diff --git a/.changeset/README.md b/.changeset/README.md index e5b6d8d6a6..4f3b76b096 100644 --- a/.changeset/README.md +++ b/.changeset/README.md @@ -5,4 +5,4 @@ with multi-package repos, or single-package repos to help you version and publis find the full documentation for it [in our repository](https://github.com/changesets/changesets) We have a quick list of common questions to get you started engaging with this project in -[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) +[our documentation](https://github.com/changesets/changesets/blob/master/docs/common-questions.md) diff --git a/.changeset/config.json b/.changeset/config.json index 4f8345f464..6b372552ca 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -5,7 +5,7 @@ "fixed": [], "linked": [], "access": "restricted", - "baseBranch": "master", + "baseBranch": "main", "updateInternalDependencies": "patch", - "ignore": ["@0xsequence/wallet-primitives-cli", "docs", "web"] + "ignore": [] } diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000000..ad53a8e498 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,26 @@ +# Use the latest 2.1 version of CircleCI pipeline process engine. +# See: https://circleci.com/docs/configuration-reference + +version: 2.1 +executors: + my-custom-executor: + docker: + - image: cimg/base:stable + auth: + # ensure you have first added these secrets + # visit app.circleci.com/settings/project/github/Dargon789/foundry/environment-variables + username: $DOCKER_HUB_USER + password: $DOCKER_HUB_PASSWORD +jobs: + web3-defi-game-project-: + + executor: my-custom-executor + steps: + - checkout + - run: | + # echo Hello, World! + +workflows: + my-custom-workflow: + jobs: + - web3-defi-game-project- diff --git a/.codesandbox/.github/workflows/build.yml b/.codesandbox/.github/workflows/build.yml new file mode 100644 index 0000000000..fe104fb809 --- /dev/null +++ b/.codesandbox/.github/workflows/build.yml @@ -0,0 +1,32 @@ +name: build app + +on: + push: + branches: + - master + +jobs: + build: + runs-on: ubuntu-latest + name: Build and Push + steps: + - name: git-checkout + uses: actions/checkout@v3 + + - name: Setup PNPM + uses: pnpm/action-setup@v2 + with: + version: 8 + run_install: true + + - name: Build + run: pnpm dist + + - name: Push + uses: s0/git-publish-subdir-action@develop + env: + REPO: self + BRANCH: build + FOLDER: dist + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + MESSAGE: 'Build: ({sha}) {msg}' diff --git a/.codesandbox/.gitignore b/.codesandbox/.gitignore new file mode 100644 index 0000000000..e4db0232ce --- /dev/null +++ b/.codesandbox/.gitignore @@ -0,0 +1,19 @@ +.env + +#dependencies +node_modules/ + +# production +dist/ + +# misc +.DS_Store +.vscode +.idea/ +*.iml +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +.env.local diff --git a/.codesandbox/.prettierrc b/.codesandbox/.prettierrc new file mode 100644 index 0000000000..421afa9791 --- /dev/null +++ b/.codesandbox/.prettierrc @@ -0,0 +1,9 @@ +{ + "tabWidth": 2, + "useTabs": false, + "semi": false, + "singleQuote": true, + "trailingComma": "none", + "arrowParens": "avoid", + "printWidth": 130 +} diff --git a/.codesandbox/README.md b/.codesandbox/README.md new file mode 100644 index 0000000000..130d32d21e --- /dev/null +++ b/.codesandbox/README.md @@ -0,0 +1,45 @@ +# Demo Dapp + +Dapp example on how to use Sequence Wallet. Covers how to connect, sign messages and send transctions. + +Try this dapp at: [https://0xsequence.github.io/demo-dapp](https://0xsequence.github.io/demo-dapp) + +For complete documentation on Sequence, please see: [https://docs.sequence.build](https://docs.sequence.build) + +## Usage + +1. pnpm install +2. pnpm start +3. Open browser to http://localhost:4000 to access the demo dapp +4. Open browser inspector to see responses from the remote Sequence Wallet + +## Development + +See [src/App.tsx](./src/App.tsx) for the source +usage for a variety of functions. Be sure to open your browser's dev inspector to see output. +Think of these functions as a "cookbook" for how you can perform these functions in your dapps. + +Also note, sequence.js is built on top of ethers.js, and is API-compatible. + +## Screenshots + +**Opening wallet from dapp:** + +![Open Sequence Wallet From Dapp](./screenshots/screen-open.png) + +**Send transaction from dapp:** + +Sequence Wallet is an Ethereum wallet supporting Ethereum mainnet, Polygon and more. Sequence will work +with any blockchain which is EVM compatible and supports Ethereum's node JSON-RPC interface. + +Here you can see in this screenshot the call to "Send DAI" from demo-dapp +(https://github.com/0xsequence/demo-dapp/blob/master/src/routes/HomeRoute.tsx#L420). This function demonstrates +how you can transfer an ERC-20 token like DAI on any Ethereum network. + +Notice how you can pay gas fees for a transaction in either MATIC token or USDC for price of $0.01. + +![Transfer ERC-20 token on Polygon](./screenshots/screen-txn.png) + +## LICENSE + +Apache 2.0 or MIT (your choice) diff --git a/.codesandbox/index.html b/.codesandbox/index.html new file mode 100644 index 0000000000..7a355ef15c --- /dev/null +++ b/.codesandbox/index.html @@ -0,0 +1,35 @@ + + + + + + + + + + + + + Sequence | Demo Dapp + + + + +
+ + + diff --git a/.codesandbox/package.json b/.codesandbox/package.json new file mode 100644 index 0000000000..067c84b8d1 --- /dev/null +++ b/.codesandbox/package.json @@ -0,0 +1,60 @@ +{ + "name": "demo-dapp", + "description": "Ethereum Demo Dapp built on Sequence stack", + "version": "0.1.0", + "private": true, + "homepage": "demo-dapp", + "scripts": { + "dev": "BROWSER=none pnpm start", + "start": "vite", + "build": "tsc && vite build", + "typecheck": "tsc --noEmit", + "serve": "Vite preview", + "dist": "pnpm build", + "link-sequence": "pnpm run clear:vite:cache && ../sequence.js/scripts/pnpm-link.sh link", + "unlink-sequence": "pnpm run clear:vite:cache && ../sequence.js/scripts/pnpm-link.sh unlink", + "clear:vite:cache": "rimraf node_modules/.vite/" + }, + "dependencies": { + "0xsequence": "2.2.13", + "@0xsequence/abi": "2.2.13", + "@0xsequence/design-system": "^1.8.1", + "@0xsequence/ethauth": "^1.0.0", + "@0xsequence/network": "2.2.13", + "@0xsequence/provider": "2.2.13", + "@0xsequence/utils": "2.2.13", + "@types/node": "^20.11.30", + "@types/react": "^18.3.7", + "@types/react-dom": "^18.3.0", + "@vanilla-extract/css": "^1.14.1", + "ethers": "^6.13.4", + "framer-motion": "^9.0.1", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "typescript": "^4.5.5" + }, + "devDependencies": { + "@vanilla-extract/vite-plugin": "^4.0.6", + "@vitejs/plugin-react": "^4.2.1", + "vite": "^5.2.6", + "vite-plugin-svgr": "^4.2.0", + "vite-tsconfig-paths": "^4.3.2" + }, + "eslintConfig": { + "extends": [ + "react-app" + ] + }, + "browsers list": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + } +} diff --git a/.codesandbox/pnpm-lock.yaml b/.codesandbox/pnpm-lock.yaml new file mode 100644 index 0000000000..14abf5d34d --- /dev/null +++ b/.codesandbox/pnpm-lock.yaml @@ -0,0 +1,4111 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + 0xsequence: + specifier: 2.2.3 + version: 2.2.3(ethers@6.13.4) + '@0xsequence/abi': + specifier: 2.2.13 + version: 2.2.13 + '@0xsequence/design-system': + specifier: ^1.8.1 + version: 1.8.1(@types/react-dom@18.3.0)(@types/react@18.3.7)(framer-motion@9.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@0xsequence/ethauth': + specifier: ^1.0.0 + version: 1.0.0(ethers@6.13.4) + '@0xsequence/network': + specifier: 2.2.13 + version: 2.2.13(ethers@6.13.4) + '@0xsequence/provider': + specifier: 2.2.13 + version: 2.2.13(ethers@6.13.4) + '@0xsequence/utils': + specifier: 2.2.13 + version: 2.2.13(ethers@6.13.4) + '@types/node': + specifier: ^20.11.30 + version: 20.11.30 + '@types/react': + specifier: ^18.3.7 + version: 18.3.7 + '@types/react-dom': + specifier: ^18.3.0 + version: 18.3.0 + '@vanilla-extract/css': + specifier: ^1.14.1 + version: 1.14.1 + ethers: + specifier: ^6.13.4 + version: 6.13.4 + framer-motion: + specifier: ^9.0.1 + version: 9.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: + specifier: ^18.3.1 + version: 18.3.1 + react-dom: + specifier: ^18.3.1 + version: 18.3.1(react@18.3.1) + typescript: + specifier: ^4.5.5 + version: 4.5.5 + devDependencies: + '@vanilla-extract/vite-plugin': + specifier: ^4.0.6 + version: 4.0.6(@types/node@20.11.30)(vite@5.2.6(@types/node@20.11.30)) + '@vitejs/plugin-react': + specifier: ^4.2.1 + version: 4.2.1(vite@5.2.6(@types/node@20.11.30)) + vite: + specifier: ^5.2.6 + version: 5.2.6(@types/node@20.11.30) + vite-plugin-svgr: + specifier: ^4.2.0 + version: 4.2.0(rollup@4.21.3)(typescript@4.5.5)(vite@5.2.6(@types/node@20.11.30)) + vite-tsconfig-paths: + specifier: ^4.3.2 + version: 4.3.2(typescript@4.5.5)(vite@5.2.6(@types/node@20.11.30)) + +packages: + + 0xsequence@2.2.3: + resolution: {integrity: sha512-1P/U1oEu51vCA6VgrzCt1pPjEx6iKd44NLLjHTEmmUxEKcesEFHtzhfA9H6tY/O2liqVT8SpS5NoHnQqtoyEAg==} + peerDependencies: + ethers: '>=6' + + '@0xsequence/abi@2.2.13': + resolution: {integrity: sha512-cZDR83SNxpXTD9vZoJAtmn6/YgvttN0gmeB8feQ5cpo8yd+AeJvQpUGMPR6Ud1MQGsvcPTLnTwKkL432Pc6UGQ==} + + '@0xsequence/abi@2.2.3': + resolution: {integrity: sha512-y0JxKXHKqkJh2i2d8F+Ql7P5jyGujJ2P28pN4YTcYacqmpDZqYi3d0Bf+uMgroWfncKBZDBETGxjWNvUYmhivg==} + + '@0xsequence/account@2.2.13': + resolution: {integrity: sha512-+kGyDsLEYOQUMhahtJps1N2j0jLXl0hAl2ilGA4NiALck7JP1Q/IO0RtkOlfSgjqFdyaipGvhYYyJuok2ARF5w==} + peerDependencies: + ethers: '>=6' + + '@0xsequence/account@2.2.3': + resolution: {integrity: sha512-Q0czXuoNpwwECwMS4GGkmoh0xIEfQrATi5gcyLlhA5kDu4Idsws3dy95D4fkTXTY2kt7JUNuG79XEmq5L2GciQ==} + peerDependencies: + ethers: '>=6' + + '@0xsequence/api@2.2.13': + resolution: {integrity: sha512-UmFMdLRCOfUGT2WqXzHE91sm+XU7eossdoKZ74W/F1ZTBU8XRa4DldQ0alKjff5x4Hxe/wIjppBPE9pQUzGYxA==} + + '@0xsequence/api@2.2.3': + resolution: {integrity: sha512-qwNcAWb4LbewZqn/39WHU/te1Wi+h7JJ2kuu9RRcV+rore3Z3zc7SqxHqtxoVMUOKlubmDEv/Y4BsL00m6XLmQ==} + + '@0xsequence/auth@2.2.13': + resolution: {integrity: sha512-3UQ6/zDhrNO5BVsgiLwCfQq4Nmbd1W0Ync/FNug8Yum1i9r2il54bUZRtauct6uMUaotAqNG4l/nzy105v93QQ==} + peerDependencies: + ethers: '>=6' + + '@0xsequence/auth@2.2.3': + resolution: {integrity: sha512-Ct5ECn5qigaSMDZ6j9vvGX3eaeSO9P9bAoknImhFURH4dsC7Dz03Z3oYbP/78oKX2RqV3uu8c8NxAWzYjBLuNg==} + peerDependencies: + ethers: '>=6' + + '@0xsequence/core@2.2.13': + resolution: {integrity: sha512-tu6OEGbDLg1KfMb+YOn0Z5BsYbK3UFBjuPVHRx7SpmCsZPEApJqqRKHpTYah2T3bmYIJy9tRBtqstfTsniSgng==} + peerDependencies: + ethers: '>=6' + + '@0xsequence/core@2.2.3': + resolution: {integrity: sha512-Bt2PsAIDSOjRx82uTqDYmOdin1DYVtwlt/TYb27Q/oNSY8MA1GG5NqEHefssi/ohXAsPRNeLMaspfmX0/BUTWw==} + peerDependencies: + ethers: '>=6' + + '@0xsequence/design-system@1.8.1': + resolution: {integrity: sha512-VsYBYR8d2UXnte5MvysyWtrdYpyvTYpQFbpNW8nOseAB6lWc8q9miTwYzeUy0fq90BQQ1YfE95EbJ4BjGTYInw==} + peerDependencies: + framer-motion: '>=6' + react: '>=17' + react-dom: '>=17' + + '@0xsequence/ethauth@1.0.0': + resolution: {integrity: sha512-piihXzbS8Sq7P670a+GyTm3igTJL3Ts6pqjJcC0Sv86yqeK6QD0pzJP4APP+/IQa5k+0s2l1SeZwMjR7gSPtCA==} + peerDependencies: + ethers: '>=6' + + '@0xsequence/guard@2.2.3': + resolution: {integrity: sha512-B9FRVJauAs/Asispe0p6wk3zAQubL9c6laC3xsCnFq3Qkv5t4VsGudTBe6ewx0xTeyQwEnVkneVgnUcnUP9xwA==} + peerDependencies: + ethers: '>=6' + + '@0xsequence/indexer@2.2.13': + resolution: {integrity: sha512-RFjjjckuAhM0vgYFO1RgYyBqsUrU54l2N/Isr5DPSLCCczp+qcopNuFMB0e0FuvzUP1buunxTjHRVjFH75kQEA==} + + '@0xsequence/indexer@2.2.3': + resolution: {integrity: sha512-bt74b5+SV5aGM+ZZfUmSU7rkttmc8I7OsQovQZBDw5YRVWPVEeVPZeX4ws4bZwiuYifD954A2Z/2MX1brH76Sw==} + + '@0xsequence/metadata@2.2.13': + resolution: {integrity: sha512-RpkIXSYKEt/W6zCoY99Q44OMjjLf//Pi8yImitXNh8IqTZqio54L9Xo4L+5ryz6rjPmaY3Mce1J1D5YJam0h4g==} + + '@0xsequence/metadata@2.2.3': + resolution: {integrity: sha512-Y7/Prw0CVxTuw59B0DnE0WnjbhJaPATibThWb13Y6W99M4NvQi5NlfS2KagfsMo5MHb5iFRjJHrCFovbv+MiuA==} + + '@0xsequence/migration@2.2.13': + resolution: {integrity: sha512-YcdjW7BRrQiOvhmSuvTM3GqklZVfO3dpbwSNqT0bMqwx/9YzE0CsVZVSMYrqVq5njyNFZjs42zazLdcrqqA2Ag==} + peerDependencies: + ethers: '>=6' + + '@0xsequence/migration@2.2.3': + resolution: {integrity: sha512-Q1+YePKzfPnCF9Rk0Tc9EqYtD1BdLym8ZEjco6b5BtyAGyIF7UefWql57IVEXBB/H1DtF+M7JHoZusvmS6atTw==} + peerDependencies: + ethers: '>=6' + + '@0xsequence/network@2.2.13': + resolution: {integrity: sha512-U8sVC2nWokPtQzIXwNKOP/mgkkuvjxYmQrgITkc8YDTAQOYPu6n/4lIqQ2//jjSfloniMK00tDpfUd5fCFbsUA==} + peerDependencies: + ethers: '>=6' + + '@0xsequence/network@2.2.3': + resolution: {integrity: sha512-oOw4oB/Y6EqTvFHYzMX9bjpizj8DQxkUGdQLBcs3R1ZLipbbwhMKWfBf9BoXAl1YUthyFKI5rl9v0MJMxaq3Bg==} + peerDependencies: + ethers: '>=6' + + '@0xsequence/provider@2.2.13': + resolution: {integrity: sha512-p5DlA2eHWhgfyCK7JQL3k7qT+aNiNxFkiAMbO2Q/eRnBnmrKcN0dK9HjuK1lWvWH3eZniEgK/M9Kec6nfixbcw==} + peerDependencies: + ethers: '>=6' + + '@0xsequence/provider@2.2.3': + resolution: {integrity: sha512-QxHBbgLGGpVsnEiFI5uvpuEUdl7JfxQ/i2T28aUK4vtUtiYLTiOnNwQy9RiK/bGPtqx9vh3Xh05G8c1KKWRqyw==} + peerDependencies: + ethers: '>=6' + + '@0xsequence/relayer@2.2.13': + resolution: {integrity: sha512-fnt4AJ1u9CPwx7JJwpZ7UbJ3eN2LOG0Wuwe4FS9OSfxCOhbokELRSWegToEyH6ew6FRPvsuRMN/im3Bu3Og0QQ==} + peerDependencies: + ethers: '>=6' + + '@0xsequence/relayer@2.2.3': + resolution: {integrity: sha512-baFGhIQIXhYcRNWV2mzFss+EXYkSlsnMI0+G3ZOUAfTkPR5Tv8iL/srvM0d+/ByhCsGwe8fqNfEbFTGIDOVviA==} + peerDependencies: + ethers: '>=6' + + '@0xsequence/replacer@2.2.13': + resolution: {integrity: sha512-+cTsda4HKzLpCzERrcPSEn5ei/lj4vPIs6kAS9aqO1XOWqeyslPWcPbfMgMbMbn+/vmbnVuqUXDOgRZqkZ2FEA==} + peerDependencies: + ethers: '>=6' + + '@0xsequence/replacer@2.2.3': + resolution: {integrity: sha512-onYf/GjYUkah1GTqimBliQQzCF9ksfb53ugJKibN1Q1uT2mKJvO1NMxXviuduXan2A+Rdr8/tTkfZwMnbVoX+A==} + peerDependencies: + ethers: '>=6' + + '@0xsequence/sessions@2.2.13': + resolution: {integrity: sha512-duClp86VeyaMuyKItByK2rIbsDQHDiMP22yLQeCN+Si+bk0T7Jta9rHP+PoAOncKpbRDJZSqSX1hmzYgB4LD5g==} + peerDependencies: + ethers: '>=6' + + '@0xsequence/sessions@2.2.3': + resolution: {integrity: sha512-MJgOZkG3fZFc0sidYY1OzFGte2HVRjmkrxDukuwlEsxvN2M+HikgrpFwVcG5u1n2uiJGA0Uzq85UL7jvF5QozQ==} + peerDependencies: + ethers: '>=6' + + '@0xsequence/signhub@2.2.13': + resolution: {integrity: sha512-yCo3l3a4nYNy5LOxcH4xEoGmQqMfWq9BxkUF+Y8xDd001L7cynaGzAS7s+5Fs4B+HD9obC7NxwSOeoJ6qqk4xw==} + peerDependencies: + ethers: '>=6' + + '@0xsequence/signhub@2.2.3': + resolution: {integrity: sha512-Gk0DitT/Su+gMDAa/r6mNOBX+RcWQfd75CnuOmJxBZT/jH6uxrbtlz/DDTR/P1gjf1EyYJ7NjibszMvr9sawzA==} + peerDependencies: + ethers: '>=6' + + '@0xsequence/utils@2.2.13': + resolution: {integrity: sha512-V4uip1fCZAzp5O2S+nkKnwrqmzzC7em1Mc4HJvUX+fqT0jzw20BZt0CNlX34DgW6E6MzBvWnrX+DTfz/+alBWQ==} + peerDependencies: + ethers: '>=6' + + '@0xsequence/utils@2.2.3': + resolution: {integrity: sha512-2F9dMqlgsoPdXk8xfOc7VuTrEtsNukadI5HSUYpLF+J1HZBamkCa/shgiHoKIZULiDt+scZ/3amVXvQUk0Zj1w==} + peerDependencies: + ethers: '>=6' + + '@0xsequence/wallet@2.2.13': + resolution: {integrity: sha512-lCD+Z6E4bpZCkwAttFy4P1iAM1ZkaiN9zo8dw4+unSVqzVslPPKoWNCX+b16Qg1pZEqe0yPjbqqon0eH/iHGyw==} + peerDependencies: + ethers: '>=6' + + '@0xsequence/wallet@2.2.3': + resolution: {integrity: sha512-lS/eVCQtjm4TAL4Xc+Hec7YZAoAZJ5XLRd3eo7oV8Seakwa2GagT3MeGnpMgRUTpySf4i9k3iDcL6fkpxWVvMg==} + peerDependencies: + ethers: '>=6' + + '@adraffy/ens-normalize@1.10.1': + resolution: {integrity: sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==} + + '@ampproject/remapping@2.2.1': + resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} + engines: {node: '>=6.0.0'} + + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + + '@babel/code-frame@7.23.5': + resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==} + engines: {node: '>=6.9.0'} + + '@babel/code-frame@7.24.2': + resolution: {integrity: sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.23.5': + resolution: {integrity: sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.23.7': + resolution: {integrity: sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.24.3': + resolution: {integrity: sha512-5FcvN1JHw2sHJChotgx8Ek0lyuh4kCKelgMTTqhYJJtloNvUfpAFMeNQUtdlIaktwrSV9LtCdqwk48wL2wBacQ==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.23.6': + resolution: {integrity: sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.24.1': + resolution: {integrity: sha512-DfCRfZsBcrPEHUfuBMgbJ1Ut01Y/itOs+hY2nFLgqsqXd52/iSiVq5TITtUasIUgm+IIKdY2/1I7auiQOEeC9A==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.23.6': + resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-environment-visitor@7.22.20': + resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-function-name@7.23.0': + resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-hoist-variables@7.22.5': + resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.22.15': + resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.23.3': + resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-plugin-utils@7.22.5': + resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-plugin-utils@7.24.0': + resolution: {integrity: sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-simple-access@7.22.5': + resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-split-export-declaration@7.22.6': + resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.22.5': + resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.23.4': + resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.24.1': + resolution: {integrity: sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.22.20': + resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.22.5': + resolution: {integrity: sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.23.5': + resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.23.8': + resolution: {integrity: sha512-KDqYz4PiOWvDFrdHLPhKtCThtIcKVy6avWD2oG4GEvyQ+XDZwHD4YQd+H2vNMnq2rkdxsDkU82T+Vk8U/WXHRQ==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.24.1': + resolution: {integrity: sha512-BpU09QqEe6ZCHuIHFphEFgvNSrubve1FtyMton26ekZ85gRGi6LrTF7zArARp2YvyFxloeiRmtSCq5sjh1WqIg==} + engines: {node: '>=6.9.0'} + + '@babel/highlight@7.23.4': + resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==} + engines: {node: '>=6.9.0'} + + '@babel/highlight@7.24.2': + resolution: {integrity: sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.23.6': + resolution: {integrity: sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/parser@7.24.1': + resolution: {integrity: sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-syntax-typescript@7.24.1': + resolution: {integrity: sha512-Yhnmvy5HZEnHUty6i++gcfH1/l68AHnItFHnaCv6hn9dNh0hQvvQJsxpi4BMBFN5DLeHBuucT/0DgzXif/OyRw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-self@7.23.3': + resolution: {integrity: sha512-qXRvbeKDSfwnlJnanVRp0SfuWE5DQhwQr5xtLBzp56Wabyo+4CMosF6Kfp+eOD/4FYpql64XVJ2W0pVLlJZxOQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-source@7.23.3': + resolution: {integrity: sha512-91RS0MDnAWDNvGC6Wio5XYkyWI39FMFO+JK9+4AlgaTH+yWwVTsw7/sn6LK0lH7c5F+TFkpv/3LfCJ1Ydwof/g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/runtime@7.24.1': + resolution: {integrity: sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.22.15': + resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.24.0': + resolution: {integrity: sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.23.7': + resolution: {integrity: sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.24.1': + resolution: {integrity: sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.22.5': + resolution: {integrity: sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.23.6': + resolution: {integrity: sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.24.0': + resolution: {integrity: sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==} + engines: {node: '>=6.9.0'} + + '@databeat/tracker@0.9.3': + resolution: {integrity: sha512-eGsiNU/CRFujcNtUUqvBiqveCs6S6SiAhalXPDodbk74d3FzvLqHDn5k6WfOEJIhrP3CbYgfMXL0nk51s/rQsg==} + + '@emotion/hash@0.9.1': + resolution: {integrity: sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==} + + '@emotion/is-prop-valid@0.8.8': + resolution: {integrity: sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==} + + '@emotion/memoize@0.7.4': + resolution: {integrity: sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==} + + '@esbuild/aix-ppc64@0.19.12': + resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/aix-ppc64@0.20.2': + resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.19.12': + resolution: {integrity: sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm64@0.20.2': + resolution: {integrity: sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.19.12': + resolution: {integrity: sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-arm@0.20.2': + resolution: {integrity: sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.19.12': + resolution: {integrity: sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/android-x64@0.20.2': + resolution: {integrity: sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.19.12': + resolution: {integrity: sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-arm64@0.20.2': + resolution: {integrity: sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.19.12': + resolution: {integrity: sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/darwin-x64@0.20.2': + resolution: {integrity: sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.19.12': + resolution: {integrity: sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-arm64@0.20.2': + resolution: {integrity: sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.19.12': + resolution: {integrity: sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.20.2': + resolution: {integrity: sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.19.12': + resolution: {integrity: sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm64@0.20.2': + resolution: {integrity: sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.19.12': + resolution: {integrity: sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-arm@0.20.2': + resolution: {integrity: sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.19.12': + resolution: {integrity: sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-ia32@0.20.2': + resolution: {integrity: sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.19.12': + resolution: {integrity: sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-loong64@0.20.2': + resolution: {integrity: sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.19.12': + resolution: {integrity: sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-mips64el@0.20.2': + resolution: {integrity: sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.19.12': + resolution: {integrity: sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-ppc64@0.20.2': + resolution: {integrity: sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.19.12': + resolution: {integrity: sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-riscv64@0.20.2': + resolution: {integrity: sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.19.12': + resolution: {integrity: sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-s390x@0.20.2': + resolution: {integrity: sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.19.12': + resolution: {integrity: sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/linux-x64@0.20.2': + resolution: {integrity: sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.19.12': + resolution: {integrity: sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.20.2': + resolution: {integrity: sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-x64@0.19.12': + resolution: {integrity: sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.20.2': + resolution: {integrity: sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.19.12': + resolution: {integrity: sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/sunos-x64@0.20.2': + resolution: {integrity: sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.19.12': + resolution: {integrity: sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-arm64@0.20.2': + resolution: {integrity: sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.19.12': + resolution: {integrity: sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-ia32@0.20.2': + resolution: {integrity: sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.19.12': + resolution: {integrity: sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@esbuild/win32-x64@0.20.2': + resolution: {integrity: sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@floating-ui/core@1.6.0': + resolution: {integrity: sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==} + + '@floating-ui/dom@1.6.3': + resolution: {integrity: sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==} + + '@floating-ui/react-dom@2.0.8': + resolution: {integrity: sha512-HOdqOt3R3OGeTKidaLvJKcgg75S6tibQ3Tif4eyd91QnIJWr0NLvoXFpJA/j8HqkFSL68GDca9AuyWEHlhyClw==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@floating-ui/utils@0.2.1': + resolution: {integrity: sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==} + + '@jridgewell/gen-mapping@0.3.3': + resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} + engines: {node: '>=6.0.0'} + + '@jridgewell/gen-mapping@0.3.5': + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.0': + resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.1': + resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.1.2': + resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.4.14': + resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} + + '@jridgewell/sourcemap-codec@1.4.15': + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + + '@jridgewell/trace-mapping@0.3.18': + resolution: {integrity: sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==} + + '@jridgewell/trace-mapping@0.3.21': + resolution: {integrity: sha512-SRfKmRe1KvYnxjEMtxEr+J4HIeMX5YBg/qhRHpxEIGjhX1rshcHlnFUE9K0GazhVKWM7B+nARSkV8LuvJdJ5/g==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@motionone/animation@10.15.1': + resolution: {integrity: sha512-mZcJxLjHor+bhcPuIFErMDNyrdb2vJur8lSfMCsuCB4UyV8ILZLvK+t+pg56erv8ud9xQGK/1OGPt10agPrCyQ==} + + '@motionone/dom@10.16.2': + resolution: {integrity: sha512-bnuHdNbge1FutZXv+k7xub9oPWcF0hsu8y1HTH/qg6av58YI0VufZ3ngfC7p2xhMJMnoh0LXFma2EGTgPeCkeg==} + + '@motionone/easing@10.15.1': + resolution: {integrity: sha512-6hIHBSV+ZVehf9dcKZLT7p5PEKHGhDwky2k8RKkmOvUoYP3S+dXsKupyZpqx5apjd9f+php4vXk4LuS+ADsrWw==} + + '@motionone/generators@10.15.1': + resolution: {integrity: sha512-67HLsvHJbw6cIbLA/o+gsm7h+6D4Sn7AUrB/GPxvujse1cGZ38F5H7DzoH7PhX+sjvtDnt2IhFYF2Zp1QTMKWQ==} + + '@motionone/types@10.15.1': + resolution: {integrity: sha512-iIUd/EgUsRZGrvW0jqdst8st7zKTzS9EsKkP+6c6n4MPZoQHwiHuVtTQLD6Kp0bsBLhNzKIBlHXponn/SDT4hA==} + + '@motionone/utils@10.15.1': + resolution: {integrity: sha512-p0YncgU+iklvYr/Dq4NobTRdAPv9PveRDUXabPEeOjBLSO/1FNB2phNTZxOxpi1/GZwYpAoECEa0Wam+nsmhSw==} + + '@noble/curves@1.2.0': + resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==} + + '@noble/hashes@1.3.2': + resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} + engines: {node: '>= 16'} + + '@noble/hashes@1.6.1': + resolution: {integrity: sha512-pq5D8h10hHBjyqX+cfBm0i8JUXJ0UhczFc4r74zbuT9XgewFo2E3J1cOaGtdZynILNmQ685YWGzGE1Zv6io50w==} + engines: {node: ^14.21.3 || >=16} + + '@radix-ui/number@1.1.0': + resolution: {integrity: sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==} + + '@radix-ui/primitive@1.1.0': + resolution: {integrity: sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==} + + '@radix-ui/react-arrow@1.1.0': + resolution: {integrity: sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-aspect-ratio@1.1.0': + resolution: {integrity: sha512-dP87DM/Y7jFlPgUZTlhx6FF5CEzOiaxp2rBCKlaXlpH5Ip/9Fg5zZ9lDOQ5o/MOfUlf36eak14zoWYpgcgGoOg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-checkbox@1.1.1': + resolution: {integrity: sha512-0i/EKJ222Afa1FE0C6pNJxDq1itzcl3HChE9DwskA4th4KRse8ojx8a1nVcOjwJdbpDLcz7uol77yYnQNMHdKw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-collapsible@1.1.0': + resolution: {integrity: sha512-zQY7Epa8sTL0mq4ajSJpjgn2YmCgyrG7RsQgLp3C0LQVkG7+Tf6Pv1CeNWZLyqMjhdPkBa5Lx7wYBeSu7uCSTA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-collection@1.1.0': + resolution: {integrity: sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-compose-refs@1.1.0': + resolution: {integrity: sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-context@1.1.0': + resolution: {integrity: sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-dialog@1.1.1': + resolution: {integrity: sha512-zysS+iU4YP3STKNS6USvFVqI4qqx8EpiwmT5TuCApVEBca+eRCbONi4EgzfNSuVnOXvC5UPHHMjs8RXO6DH9Bg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-direction@1.1.0': + resolution: {integrity: sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-dismissable-layer@1.1.0': + resolution: {integrity: sha512-/UovfmmXGptwGcBQawLzvn2jOfM0t4z3/uKffoBlj724+n3FvBbZ7M0aaBOmkp6pqFYpO4yx8tSVJjx3Fl2jig==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-dropdown-menu@2.1.1': + resolution: {integrity: sha512-y8E+x9fBq9qvteD2Zwa4397pUVhYsh9iq44b5RD5qu1GMJWBCBuVg1hMyItbc6+zH00TxGRqd9Iot4wzf3OoBQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-focus-guards@1.1.0': + resolution: {integrity: sha512-w6XZNUPVv6xCpZUqb/yN9DL6auvpGX3C/ee6Hdi16v2UUy25HV2Q5bcflsiDyT/g5RwbPQ/GIT1vLkeRb+ITBw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-focus-scope@1.1.0': + resolution: {integrity: sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-id@1.1.0': + resolution: {integrity: sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-menu@2.1.1': + resolution: {integrity: sha512-oa3mXRRVjHi6DZu/ghuzdylyjaMXLymx83irM7hTxutQbD+7IhPKdMdRHD26Rm+kHRrWcrUkkRPv5pd47a2xFQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-popper@1.2.0': + resolution: {integrity: sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-portal@1.1.1': + resolution: {integrity: sha512-A3UtLk85UtqhzFqtoC8Q0KvR2GbXF3mtPgACSazajqq6A41mEQgo53iPzY4i6BwDxlIFqWIhiQ2G729n+2aw/g==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-presence@1.1.0': + resolution: {integrity: sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-primitive@2.0.0': + resolution: {integrity: sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-progress@1.1.0': + resolution: {integrity: sha512-aSzvnYpP725CROcxAOEBVZZSIQVQdHgBr2QQFKySsaD14u8dNT0batuXI+AAGDdAHfXH8rbnHmjYFqVJ21KkRg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-radio-group@1.2.0': + resolution: {integrity: sha512-yv+oiLaicYMBpqgfpSPw6q+RyXlLdIpQWDHZbUKURxe+nEh53hFXPPlfhfQQtYkS5MMK/5IWIa76SksleQZSzw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-roving-focus@1.1.0': + resolution: {integrity: sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-select@2.1.1': + resolution: {integrity: sha512-8iRDfyLtzxlprOo9IicnzvpsO1wNCkuwzzCM+Z5Rb5tNOpCdMvcc2AkzX0Fz+Tz9v6NJ5B/7EEgyZveo4FBRfQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-slot@1.1.0': + resolution: {integrity: sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-switch@1.1.0': + resolution: {integrity: sha512-OBzy5WAj641k0AOSpKQtreDMe+isX0MQJ1IVyF03ucdF3DunOnROVrjWs8zsXUxC3zfZ6JL9HFVCUlMghz9dJw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-tabs@1.1.0': + resolution: {integrity: sha512-bZgOKB/LtZIij75FSuPzyEti/XBhJH52ExgtdVqjCIh+Nx/FW+LhnbXtbCzIi34ccyMsyOja8T0thCzoHFXNKA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-toast@1.2.1': + resolution: {integrity: sha512-5trl7piMXcZiCq7MW6r8YYmu0bK5qDpTWz+FdEPdKyft2UixkspheYbjbrLXVN5NGKHFbOP7lm8eD0biiSqZqg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-tooltip@1.1.2': + resolution: {integrity: sha512-9XRsLwe6Yb9B/tlnYCPVUd/TFS4J7HuOZW345DCeC6vKIxQGMZdx21RK4VoZauPD5frgkXTYVS5y90L+3YBn4w==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-use-callback-ref@1.1.0': + resolution: {integrity: sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-controllable-state@1.1.0': + resolution: {integrity: sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-escape-keydown@1.1.0': + resolution: {integrity: sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-layout-effect@1.1.0': + resolution: {integrity: sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-previous@1.1.0': + resolution: {integrity: sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-rect@1.1.0': + resolution: {integrity: sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-size@1.1.0': + resolution: {integrity: sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-visually-hidden@1.1.0': + resolution: {integrity: sha512-N8MDZqtgCgG5S3aV60INAB475osJousYpZ4cTJ2cFbMpdHS5Y6loLTH8LPtkj2QN0x93J30HT/M3qJXM0+lyeQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/rect@1.1.0': + resolution: {integrity: sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==} + + '@rollup/pluginutils@5.1.0': + resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/rollup-android-arm-eabi@4.13.1': + resolution: {integrity: sha512-4C4UERETjXpC4WpBXDbkgNVgHyWfG3B/NKY46e7w5H134UDOFqUJKpsLm0UYmuupW+aJmRgeScrDNfvZ5WV80A==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm-eabi@4.21.3': + resolution: {integrity: sha512-MmKSfaB9GX+zXl6E8z4koOr/xU63AMVleLEa64v7R0QF/ZloMs5vcD1sHgM64GXXS1csaJutG+ddtzcueI/BLg==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.13.1': + resolution: {integrity: sha512-TrTaFJ9pXgfXEiJKQ3yQRelpQFqgRzVR9it8DbeRzG0RX7mKUy0bqhCFsgevwXLJepQKTnLl95TnPGf9T9AMOA==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-android-arm64@4.21.3': + resolution: {integrity: sha512-zrt8ecH07PE3sB4jPOggweBjJMzI1JG5xI2DIsUbkA+7K+Gkjys6eV7i9pOenNSDJH3eOr/jLb/PzqtmdwDq5g==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.13.1': + resolution: {integrity: sha512-fz7jN6ahTI3cKzDO2otQuybts5cyu0feymg0bjvYCBrZQ8tSgE8pc0sSNEuGvifrQJWiwx9F05BowihmLxeQKw==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-arm64@4.21.3': + resolution: {integrity: sha512-P0UxIOrKNBFTQaXTxOH4RxuEBVCgEA5UTNV6Yz7z9QHnUJ7eLX9reOd/NYMO3+XZO2cco19mXTxDMXxit4R/eQ==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.13.1': + resolution: {integrity: sha512-WTvdz7SLMlJpektdrnWRUN9C0N2qNHwNbWpNo0a3Tod3gb9leX+yrYdCeB7VV36OtoyiPAivl7/xZ3G1z5h20g==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.21.3': + resolution: {integrity: sha512-L1M0vKGO5ASKntqtsFEjTq/fD91vAqnzeaF6sfNAy55aD+Hi2pBI5DKwCO+UNDQHWsDViJLqshxOahXyLSh3EA==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-linux-arm-gnueabihf@4.13.1': + resolution: {integrity: sha512-dBHQl+7wZzBYcIF6o4k2XkAfwP2ks1mYW2q/Gzv9n39uDcDiAGDqEyml08OdY0BIct0yLSPkDTqn4i6czpBLLw==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-gnueabihf@4.21.3': + resolution: {integrity: sha512-btVgIsCjuYFKUjopPoWiDqmoUXQDiW2A4C3Mtmp5vACm7/GnyuprqIDPNczeyR5W8rTXEbkmrJux7cJmD99D2g==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.21.3': + resolution: {integrity: sha512-zmjbSphplZlau6ZTkxd3+NMtE4UKVy7U4aVFMmHcgO5CUbw17ZP6QCgyxhzGaU/wFFdTfiojjbLG3/0p9HhAqA==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.13.1': + resolution: {integrity: sha512-bur4JOxvYxfrAmocRJIW0SADs3QdEYK6TQ7dTNz6Z4/lySeu3Z1H/+tl0a4qDYv0bCdBpUYM0sYa/X+9ZqgfSQ==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.21.3': + resolution: {integrity: sha512-nSZfcZtAnQPRZmUkUQwZq2OjQciR6tEoJaZVFvLHsj0MF6QhNMg0fQ6mUOsiCUpTqxTx0/O6gX0V/nYc7LrgPw==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.13.1': + resolution: {integrity: sha512-ssp77SjcDIUSoUyj7DU7/5iwM4ZEluY+N8umtCT9nBRs3u045t0KkW02LTyHouHDomnMXaXSZcCSr2bdMK63kA==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.21.3': + resolution: {integrity: sha512-MnvSPGO8KJXIMGlQDYfvYS3IosFN2rKsvxRpPO2l2cum+Z3exiExLwVU+GExL96pn8IP+GdH8Tz70EpBhO0sIQ==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.21.3': + resolution: {integrity: sha512-+W+p/9QNDr2vE2AXU0qIy0qQE75E8RTwTwgqS2G5CRQ11vzq0tbnfBd6brWhS9bCRjAjepJe2fvvkvS3dno+iw==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.13.1': + resolution: {integrity: sha512-Jv1DkIvwEPAb+v25/Unrnnq9BO3F5cbFPT821n3S5litkz+O5NuXuNhqtPx5KtcwOTtaqkTsO+IVzJOsxd11aQ==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.21.3': + resolution: {integrity: sha512-yXH6K6KfqGXaxHrtr+Uoy+JpNlUlI46BKVyonGiaD74ravdnF9BUNC+vV+SIuB96hUMGShhKV693rF9QDfO6nQ==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.13.1': + resolution: {integrity: sha512-U564BrhEfaNChdATQaEODtquCC7Ez+8Hxz1h5MAdMYj0AqD0GA9rHCpElajb/sQcaFL6NXmHc5O+7FXpWMa73Q==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.21.3': + resolution: {integrity: sha512-R8cwY9wcnApN/KDYWTH4gV/ypvy9yZUHlbJvfaiXSB48JO3KpwSpjOGqO4jnGkLDSk1hgjYkTbTt6Q7uvPf8eg==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.13.1': + resolution: {integrity: sha512-zGRDulLTeDemR8DFYyFIQ8kMP02xpUsX4IBikc7lwL9PrwR3gWmX2NopqiGlI2ZVWMl15qZeUjumTwpv18N7sQ==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.21.3': + resolution: {integrity: sha512-kZPbX/NOPh0vhS5sI+dR8L1bU2cSO9FgxwM8r7wHzGydzfSjLRCFAT87GR5U9scj2rhzN3JPYVC7NoBbl4FZ0g==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.13.1': + resolution: {integrity: sha512-VTk/MveyPdMFkYJJPCkYBw07KcTkGU2hLEyqYMsU4NjiOfzoaDTW9PWGRsNwiOA3qI0k/JQPjkl/4FCK1smskQ==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.21.3': + resolution: {integrity: sha512-S0Yq+xA1VEH66uiMNhijsWAafffydd2X5b77eLHfRmfLsRSpbiAWiRHV6DEpz6aOToPsgid7TI9rGd6zB1rhbg==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.13.1': + resolution: {integrity: sha512-L+hX8Dtibb02r/OYCsp4sQQIi3ldZkFI0EUkMTDwRfFykXBPptoz/tuuGqEd3bThBSLRWPR6wsixDSgOx/U3Zw==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-arm64-msvc@4.21.3': + resolution: {integrity: sha512-9isNzeL34yquCPyerog+IMCNxKR8XYmGd0tHSV+OVx0TmE0aJOo9uw4fZfUuk2qxobP5sug6vNdZR6u7Mw7Q+Q==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.13.1': + resolution: {integrity: sha512-+dI2jVPfM5A8zme8riEoNC7UKk0Lzc7jCj/U89cQIrOjrZTCWZl/+IXUeRT2rEZ5j25lnSA9G9H1Ob9azaF/KQ==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.21.3': + resolution: {integrity: sha512-nMIdKnfZfzn1Vsk+RuOvl43ONTZXoAPUUxgcU0tXooqg4YrAqzfKzVenqqk2g5efWh46/D28cKFrOzDSW28gTA==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.13.1': + resolution: {integrity: sha512-YY1Exxo2viZ/O2dMHuwQvimJ0SqvL+OAWQLLY6rvXavgQKjhQUzn7nc1Dd29gjB5Fqi00nrBWctJBOyfVMIVxw==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.21.3': + resolution: {integrity: sha512-fOvu7PCQjAj4eWDEuD8Xz5gpzFqXzGlxHZozHP4b9Jxv9APtdxL6STqztDzMLuRXEc4UpXGGhx029Xgm91QBeA==} + cpu: [x64] + os: [win32] + + '@svgr/babel-plugin-add-jsx-attribute@8.0.0': + resolution: {integrity: sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-remove-jsx-attribute@8.0.0': + resolution: {integrity: sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0': + resolution: {integrity: sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0': + resolution: {integrity: sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-svg-dynamic-title@8.0.0': + resolution: {integrity: sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-svg-em-dimensions@8.0.0': + resolution: {integrity: sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-transform-react-native-svg@8.1.0': + resolution: {integrity: sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-transform-svg-component@8.0.0': + resolution: {integrity: sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==} + engines: {node: '>=12'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-preset@8.1.0': + resolution: {integrity: sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/core@8.1.0': + resolution: {integrity: sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==} + engines: {node: '>=14'} + + '@svgr/hast-util-to-babel-ast@8.0.0': + resolution: {integrity: sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==} + engines: {node: '>=14'} + + '@svgr/plugin-jsx@8.1.0': + resolution: {integrity: sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==} + engines: {node: '>=14'} + peerDependencies: + '@svgr/core': '*' + + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.6.8': + resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.20.5': + resolution: {integrity: sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==} + + '@types/estree@1.0.5': + resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + + '@types/node@20.11.30': + resolution: {integrity: sha512-dHM6ZxwlmuZaRmUPfv1p+KrdD1Dci04FbdEm/9wEMouFqxYoFl5aMkt0VMAUtYRQDyYvD41WJLukhq/ha3YuTw==} + + '@types/node@22.7.5': + resolution: {integrity: sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==} + + '@types/prop-types@15.7.13': + resolution: {integrity: sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==} + + '@types/react-dom@18.3.0': + resolution: {integrity: sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==} + + '@types/react@18.3.7': + resolution: {integrity: sha512-KUnDCJF5+AiZd8owLIeVHqmW9yM4sqmDVf2JRJiBMFkGvkoZ4/WyV2lL4zVsoinmRS/W3FeEdZLEWFRofnT2FQ==} + + '@vanilla-extract/babel-plugin-debug-ids@1.0.5': + resolution: {integrity: sha512-Rc9A6ylsw7EBErmpgqCMvc/Z/eEZxI5k1xfLQHw7f5HHh3oc5YfzsAsYU/PdmSNjF1dp3sGEViBdDltvwnfVaA==} + + '@vanilla-extract/css@1.14.1': + resolution: {integrity: sha512-V4JUuHNjZgl64NGfkDJePqizkNgiSpphODtZEs4cCPuxLAzwOUJYATGpejwimJr1n529kq4DEKWexW22LMBokw==} + + '@vanilla-extract/integration@7.1.1': + resolution: {integrity: sha512-2JjDKL2HDTazis4oTkUFsQFUyw61k8oym9r0NOLSJC0JB0W25W1ryVZvDx74d3deIyB5AWbCselyzl3gja30kQ==} + + '@vanilla-extract/private@1.0.3': + resolution: {integrity: sha512-17kVyLq3ePTKOkveHxXuIJZtGYs+cSoev7BlP+Lf4916qfDhk/HBjvlYDe8egrea7LNPHKwSZJK/bzZC+Q6AwQ==} + + '@vanilla-extract/vite-plugin@4.0.6': + resolution: {integrity: sha512-uT2AhzxEC8qdn7SFxD/MHF7pxyFMb2e7HY3+isyPDzkTyIdiA/ZXk7qwWhcigFMNCJ6YuyxFQJmiDhP9U9oOmg==} + peerDependencies: + vite: ^4.0.3 || ^5.0.0 + + '@vitejs/plugin-react@4.2.1': + resolution: {integrity: sha512-oojO9IDc4nCUUi8qIR11KoQm0XFFLIwsRBwHRR4d/88IWghn1y6ckz/bJ8GHDCsYEJee8mDzqtJxh15/cisJNQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.2.0 || ^5.0.0 + + acorn@8.11.3: + resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} + engines: {node: '>=0.4.0'} + hasBin: true + + aes-js@4.0.0-beta.5: + resolution: {integrity: sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==} + + ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aria-hidden@1.2.4: + resolution: {integrity: sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==} + engines: {node: '>=10'} + + browserslist@4.22.2: + resolution: {integrity: sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + + caniuse-lite@1.0.30001579: + resolution: {integrity: sha512-u5AUVkixruKHJjw/pj9wISlcMpgFWzSrczLZbrqBSxukQixmg0SJ5sZTpvaFvxU0HoQKd4yoyAogyrAz9pzJnA==} + + chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cosmiconfig@8.3.6: + resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + + css-what@6.1.0: + resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} + engines: {node: '>= 6'} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-object-diff@1.1.9: + resolution: {integrity: sha512-Rn+RuwkmkDwCi2/oXOFS9Gsr5lJZu/yTGpK7wAaAIE75CC+LCGEZHpY6VQJa/RoJcrmaA/docWJZvYohlNkWPA==} + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + detect-node-es@1.1.0: + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + + dot-case@3.0.4: + resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} + + electron-to-chromium@1.4.638: + resolution: {integrity: sha512-gpmbAG2LbfPKcDaL5m9IKutKjUx4ZRkvGNkgL/8nKqxkXsBVYykVULboWlqCrHsh3razucgDJDuKoWJmGPdItA==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + + esbuild@0.19.12: + resolution: {integrity: sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==} + engines: {node: '>=12'} + hasBin: true + + esbuild@0.20.2: + resolution: {integrity: sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==} + engines: {node: '>=12'} + hasBin: true + + escalade@3.1.1: + resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} + engines: {node: '>=6'} + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + ethers@6.13.4: + resolution: {integrity: sha512-21YtnZVg4/zKkCQPjrDj38B1r4nQvTZLopUGMLQ1ePU2zV/joCfDC3t3iKQjWRzjjjbzR+mdAIoikeBRNkdllA==} + engines: {node: '>=14.0.0'} + + eval@0.1.8: + resolution: {integrity: sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw==} + engines: {node: '>= 0.8'} + + eventemitter2@6.4.9: + resolution: {integrity: sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + framer-motion@9.0.1: + resolution: {integrity: sha512-0EP7+b/hnsbrFOum9zU+23Fq2cJJrLOqv/yJ26fIzK4CC33ZAjXZGi1/XyblbgnUF0cxZ/SEDj5IYHeQo42qNg==} + peerDependencies: + react: ^18.0.0 + react-dom: ^18.0.0 + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-nonce@1.0.1: + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} + engines: {node: '>=6'} + + globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + + globrex@0.1.2: + resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} + + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + hey-listen@1.0.8: + resolution: {integrity: sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==} + + idb@7.1.1: + resolution: {integrity: sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==} + + import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + + invariant@2.2.4: + resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + javascript-stringify@2.1.0: + resolution: {integrity: sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==} + + js-base64@3.7.7: + resolution: {integrity: sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + jsesc@2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonc-parser@3.2.1: + resolution: {integrity: sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + lower-case@2.0.2: + resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + media-query-parser@2.0.2: + resolution: {integrity: sha512-1N4qp+jE0pL5Xv4uEcwVUhIkwdUO3S/9gML90nqKA7v7FcOS5vUtatfzok9S9U1EJU8dHWlcv95WLnKmmxZI9w==} + + mlly@1.6.1: + resolution: {integrity: sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA==} + + modern-ahocorasick@1.0.1: + resolution: {integrity: sha512-yoe+JbhTClckZ67b2itRtistFKf8yPYelHLc7e5xAwtNAXxM6wJTUx2C7QeVSJFDzKT7bCIFyBVybPMKvmB9AA==} + + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + no-case@3.0.4: + resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + + node-releases@2.0.14: + resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} + + outdent@0.8.0: + resolution: {integrity: sha512-KiOAIsdpUTcAXuykya5fnVVT+/5uS0Q1mrkRHcF89tpieSmY33O/tmc54CqwA+bfhbtEfZUNLHaPUiB9X3jt1A==} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + + picocolors@1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + pkg-types@1.0.3: + resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==} + + postcss@8.4.38: + resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} + engines: {node: ^10 || ^12 || >=14} + + react-dom@18.3.1: + resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} + peerDependencies: + react: ^18.3.1 + + react-hook-form@7.53.0: + resolution: {integrity: sha512-M1n3HhqCww6S2hxLxciEXy2oISPnAzxY7gvwVPrtlczTM/1dDadXgUxDpHMrMTblDOcm/AXtXxHwZ3jpg1mqKQ==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^16.8.0 || ^17 || ^18 || ^19 + + react-refresh@0.14.0: + resolution: {integrity: sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==} + engines: {node: '>=0.10.0'} + + react-remove-scroll-bar@2.3.6: + resolution: {integrity: sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + react-remove-scroll@2.5.7: + resolution: {integrity: sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + react-style-singleton@2.2.1: + resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + react@18.3.1: + resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + engines: {node: '>=0.10.0'} + + regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + + require-like@0.1.2: + resolution: {integrity: sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + rollup@4.13.1: + resolution: {integrity: sha512-hFi+fU132IvJ2ZuihN56dwgpltpmLZHZWsx27rMCTZ2sYwrqlgL5sECGy1eeV2lAihD8EzChBVVhsXci0wD4Tg==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + rollup@4.21.3: + resolution: {integrity: sha512-7sqRtBNnEbcBtMeRVc6VRsJMmpI+JU1z9VTvW8D4gXIYQFz0aLcsE6rRkyghZkLfEgUZgVvOG7A5CVz/VW5GIA==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + scheduler@0.23.2: + resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + snake-case@3.0.4: + resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} + + source-map-js@1.2.0: + resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + engines: {node: '>=0.10.0'} + + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + svg-parser@2.0.4: + resolution: {integrity: sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==} + + to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + + tsconfck@3.0.3: + resolution: {integrity: sha512-4t0noZX9t6GcPTfBAbIbbIU4pfpCwh0ueq3S4O/5qXI1VwK1outmxhe9dOiEWqMz3MW2LKgDTpqWV+37IWuVbA==} + engines: {node: ^18 || >=20} + hasBin: true + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + + tslib@2.6.1: + resolution: {integrity: sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==} + + tslib@2.6.2: + resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + + tslib@2.7.0: + resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} + + typescript@4.5.5: + resolution: {integrity: sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==} + engines: {node: '>=4.2.0'} + hasBin: true + + ufo@1.5.3: + resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==} + + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + + undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + + update-browserslist-db@1.0.13: + resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + use-callback-ref@1.3.2: + resolution: {integrity: sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + use-sidecar@1.1.2: + resolution: {integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.9.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + vite-node@1.4.0: + resolution: {integrity: sha512-VZDAseqjrHgNd4Kh8icYHWzTKSCZMhia7GyHfhtzLW33fZlG9SwsB6CEhgyVOWkJfJ2pFLrp/Gj1FSfAiqH9Lw==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + + vite-plugin-svgr@4.2.0: + resolution: {integrity: sha512-SC7+FfVtNQk7So0XMjrrtLAbEC8qjFPifyD7+fs/E6aaNdVde6umlVVh0QuwDLdOMu7vp5RiGFsB70nj5yo0XA==} + peerDependencies: + vite: ^2.6.0 || 3 || 4 || 5 + + vite-tsconfig-paths@4.3.2: + resolution: {integrity: sha512-0Vd/a6po6Q+86rPlntHye7F31zA2URZMbH8M3saAZ/xR9QoGN/L21bxEGfXdWmFdNkqPpRdxFT7nmNe12e9/uA==} + peerDependencies: + vite: '*' + peerDependenciesMeta: + vite: + optional: true + + vite@5.2.6: + resolution: {integrity: sha512-FPtnxFlSIKYjZ2eosBQamz4CbyrTizbZ3hnGJlh/wMtCrlp1Hah6AzBLjGI5I2urTfNnpovpHdrL6YRuBOPnCA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + webextension-polyfill@0.10.0: + resolution: {integrity: sha512-c5s35LgVa5tFaHhrZDnr3FpQpjj1BB+RXhLTYUxGqBVN460HkbM8TBtEqdXWbpTKfzwCcjAZVF7zXCYSKtcp9g==} + + ws@8.17.1: + resolution: {integrity: sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + +snapshots: + + 0xsequence@2.2.3(ethers@6.13.4): + dependencies: + '@0xsequence/abi': 2.2.3 + '@0xsequence/account': 2.2.3(ethers@6.13.4) + '@0xsequence/api': 2.2.3 + '@0xsequence/auth': 2.2.3(ethers@6.13.4) + '@0xsequence/core': 2.2.3(ethers@6.13.4) + '@0xsequence/guard': 2.2.3(ethers@6.13.4) + '@0xsequence/indexer': 2.2.3 + '@0xsequence/metadata': 2.2.3 + '@0xsequence/migration': 2.2.3(ethers@6.13.4) + '@0xsequence/network': 2.2.3(ethers@6.13.4) + '@0xsequence/provider': 2.2.3(ethers@6.13.4) + '@0xsequence/relayer': 2.2.3(ethers@6.13.4) + '@0xsequence/sessions': 2.2.3(ethers@6.13.4) + '@0xsequence/signhub': 2.2.3(ethers@6.13.4) + '@0xsequence/utils': 2.2.3(ethers@6.13.4) + '@0xsequence/wallet': 2.2.3(ethers@6.13.4) + ethers: 6.13.4 + + '@0xsequence/abi@2.2.13': {} + + '@0xsequence/abi@2.2.3': {} + + '@0xsequence/account@2.2.13(ethers@6.13.4)': + dependencies: + '@0xsequence/abi': 2.2.13 + '@0xsequence/core': 2.2.13(ethers@6.13.4) + '@0xsequence/migration': 2.2.13(ethers@6.13.4) + '@0xsequence/network': 2.2.13(ethers@6.13.4) + '@0xsequence/relayer': 2.2.13(ethers@6.13.4) + '@0xsequence/sessions': 2.2.13(ethers@6.13.4) + '@0xsequence/utils': 2.2.13(ethers@6.13.4) + '@0xsequence/wallet': 2.2.13(ethers@6.13.4) + ethers: 6.13.4 + + '@0xsequence/account@2.2.3(ethers@6.13.4)': + dependencies: + '@0xsequence/abi': 2.2.3 + '@0xsequence/core': 2.2.3(ethers@6.13.4) + '@0xsequence/migration': 2.2.3(ethers@6.13.4) + '@0xsequence/network': 2.2.3(ethers@6.13.4) + '@0xsequence/relayer': 2.2.3(ethers@6.13.4) + '@0xsequence/sessions': 2.2.3(ethers@6.13.4) + '@0xsequence/utils': 2.2.3(ethers@6.13.4) + '@0xsequence/wallet': 2.2.3(ethers@6.13.4) + ethers: 6.13.4 + + '@0xsequence/api@2.2.13': {} + + '@0xsequence/api@2.2.3': {} + + '@0xsequence/auth@2.2.13(ethers@6.13.4)': + dependencies: + '@0xsequence/abi': 2.2.13 + '@0xsequence/account': 2.2.13(ethers@6.13.4) + '@0xsequence/api': 2.2.13 + '@0xsequence/core': 2.2.13(ethers@6.13.4) + '@0xsequence/ethauth': 1.0.0(ethers@6.13.4) + '@0xsequence/indexer': 2.2.13 + '@0xsequence/metadata': 2.2.13 + '@0xsequence/migration': 2.2.13(ethers@6.13.4) + '@0xsequence/network': 2.2.13(ethers@6.13.4) + '@0xsequence/sessions': 2.2.13(ethers@6.13.4) + '@0xsequence/signhub': 2.2.13(ethers@6.13.4) + '@0xsequence/utils': 2.2.13(ethers@6.13.4) + '@0xsequence/wallet': 2.2.13(ethers@6.13.4) + ethers: 6.13.4 + + '@0xsequence/auth@2.2.3(ethers@6.13.4)': + dependencies: + '@0xsequence/abi': 2.2.3 + '@0xsequence/account': 2.2.3(ethers@6.13.4) + '@0xsequence/api': 2.2.3 + '@0xsequence/core': 2.2.3(ethers@6.13.4) + '@0xsequence/ethauth': 1.0.0(ethers@6.13.4) + '@0xsequence/indexer': 2.2.3 + '@0xsequence/metadata': 2.2.3 + '@0xsequence/migration': 2.2.3(ethers@6.13.4) + '@0xsequence/network': 2.2.3(ethers@6.13.4) + '@0xsequence/sessions': 2.2.3(ethers@6.13.4) + '@0xsequence/signhub': 2.2.3(ethers@6.13.4) + '@0xsequence/utils': 2.2.3(ethers@6.13.4) + '@0xsequence/wallet': 2.2.3(ethers@6.13.4) + ethers: 6.13.4 + + '@0xsequence/core@2.2.13(ethers@6.13.4)': + dependencies: + '@0xsequence/abi': 2.2.13 + '@0xsequence/utils': 2.2.13(ethers@6.13.4) + ethers: 6.13.4 + + '@0xsequence/core@2.2.3(ethers@6.13.4)': + dependencies: + '@0xsequence/abi': 2.2.3 + '@0xsequence/utils': 2.2.3(ethers@6.13.4) + ethers: 6.13.4 + + '@0xsequence/design-system@1.8.1(@types/react-dom@18.3.0)(@types/react@18.3.7)(framer-motion@9.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-aspect-ratio': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-checkbox': 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-collapsible': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-dialog': 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-dropdown-menu': 2.1.1(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-progress': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-radio-group': 1.2.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-select': 2.1.1(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-switch': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-tabs': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-toast': 1.2.1(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-tooltip': 1.1.2(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + framer-motion: 9.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-hook-form: 7.53.0(react@18.3.1) + transitivePeerDependencies: + - '@types/react' + - '@types/react-dom' + + '@0xsequence/ethauth@1.0.0(ethers@6.13.4)': + dependencies: + ethers: 6.13.4 + js-base64: 3.7.7 + + '@0xsequence/guard@2.2.3(ethers@6.13.4)': + dependencies: + '@0xsequence/account': 2.2.3(ethers@6.13.4) + '@0xsequence/core': 2.2.3(ethers@6.13.4) + '@0xsequence/signhub': 2.2.3(ethers@6.13.4) + '@0xsequence/utils': 2.2.3(ethers@6.13.4) + ethers: 6.13.4 + + '@0xsequence/indexer@2.2.13': {} + + '@0xsequence/indexer@2.2.3': {} + + '@0xsequence/metadata@2.2.13': {} + + '@0xsequence/metadata@2.2.3': {} + + '@0xsequence/migration@2.2.13(ethers@6.13.4)': + dependencies: + '@0xsequence/abi': 2.2.13 + '@0xsequence/core': 2.2.13(ethers@6.13.4) + '@0xsequence/wallet': 2.2.13(ethers@6.13.4) + ethers: 6.13.4 + + '@0xsequence/migration@2.2.3(ethers@6.13.4)': + dependencies: + '@0xsequence/abi': 2.2.3 + '@0xsequence/core': 2.2.3(ethers@6.13.4) + '@0xsequence/wallet': 2.2.3(ethers@6.13.4) + ethers: 6.13.4 + + '@0xsequence/network@2.2.13(ethers@6.13.4)': + dependencies: + '@0xsequence/core': 2.2.13(ethers@6.13.4) + '@0xsequence/indexer': 2.2.13 + '@0xsequence/relayer': 2.2.13(ethers@6.13.4) + '@0xsequence/utils': 2.2.13(ethers@6.13.4) + ethers: 6.13.4 + + '@0xsequence/network@2.2.3(ethers@6.13.4)': + dependencies: + '@0xsequence/core': 2.2.3(ethers@6.13.4) + '@0xsequence/indexer': 2.2.3 + '@0xsequence/relayer': 2.2.3(ethers@6.13.4) + '@0xsequence/utils': 2.2.3(ethers@6.13.4) + ethers: 6.13.4 + + '@0xsequence/provider@2.2.13(ethers@6.13.4)': + dependencies: + '@0xsequence/abi': 2.2.13 + '@0xsequence/account': 2.2.13(ethers@6.13.4) + '@0xsequence/auth': 2.2.13(ethers@6.13.4) + '@0xsequence/core': 2.2.13(ethers@6.13.4) + '@0xsequence/migration': 2.2.13(ethers@6.13.4) + '@0xsequence/network': 2.2.13(ethers@6.13.4) + '@0xsequence/relayer': 2.2.13(ethers@6.13.4) + '@0xsequence/utils': 2.2.13(ethers@6.13.4) + '@0xsequence/wallet': 2.2.13(ethers@6.13.4) + '@databeat/tracker': 0.9.3 + ethers: 6.13.4 + eventemitter2: 6.4.9 + webextension-polyfill: 0.10.0 + + '@0xsequence/provider@2.2.3(ethers@6.13.4)': + dependencies: + '@0xsequence/abi': 2.2.3 + '@0xsequence/account': 2.2.3(ethers@6.13.4) + '@0xsequence/auth': 2.2.3(ethers@6.13.4) + '@0xsequence/core': 2.2.3(ethers@6.13.4) + '@0xsequence/migration': 2.2.3(ethers@6.13.4) + '@0xsequence/network': 2.2.3(ethers@6.13.4) + '@0xsequence/relayer': 2.2.3(ethers@6.13.4) + '@0xsequence/utils': 2.2.3(ethers@6.13.4) + '@0xsequence/wallet': 2.2.3(ethers@6.13.4) + '@databeat/tracker': 0.9.3 + ethers: 6.13.4 + eventemitter2: 6.4.9 + webextension-polyfill: 0.10.0 + + '@0xsequence/relayer@2.2.13(ethers@6.13.4)': + dependencies: + '@0xsequence/abi': 2.2.13 + '@0xsequence/core': 2.2.13(ethers@6.13.4) + '@0xsequence/utils': 2.2.13(ethers@6.13.4) + ethers: 6.13.4 + + '@0xsequence/relayer@2.2.3(ethers@6.13.4)': + dependencies: + '@0xsequence/abi': 2.2.3 + '@0xsequence/core': 2.2.3(ethers@6.13.4) + '@0xsequence/utils': 2.2.3(ethers@6.13.4) + ethers: 6.13.4 + + '@0xsequence/replacer@2.2.13(ethers@6.13.4)': + dependencies: + '@0xsequence/abi': 2.2.13 + '@0xsequence/core': 2.2.13(ethers@6.13.4) + ethers: 6.13.4 + + '@0xsequence/replacer@2.2.3(ethers@6.13.4)': + dependencies: + '@0xsequence/abi': 2.2.3 + '@0xsequence/core': 2.2.3(ethers@6.13.4) + ethers: 6.13.4 + + '@0xsequence/sessions@2.2.13(ethers@6.13.4)': + dependencies: + '@0xsequence/core': 2.2.13(ethers@6.13.4) + '@0xsequence/migration': 2.2.13(ethers@6.13.4) + '@0xsequence/replacer': 2.2.13(ethers@6.13.4) + '@0xsequence/utils': 2.2.13(ethers@6.13.4) + ethers: 6.13.4 + idb: 7.1.1 + + '@0xsequence/sessions@2.2.3(ethers@6.13.4)': + dependencies: + '@0xsequence/core': 2.2.3(ethers@6.13.4) + '@0xsequence/migration': 2.2.3(ethers@6.13.4) + '@0xsequence/replacer': 2.2.3(ethers@6.13.4) + '@0xsequence/utils': 2.2.3(ethers@6.13.4) + ethers: 6.13.4 + idb: 7.1.1 + + '@0xsequence/signhub@2.2.13(ethers@6.13.4)': + dependencies: + '@0xsequence/core': 2.2.13(ethers@6.13.4) + ethers: 6.13.4 + + '@0xsequence/signhub@2.2.3(ethers@6.13.4)': + dependencies: + '@0xsequence/core': 2.2.3(ethers@6.13.4) + ethers: 6.13.4 + + '@0xsequence/utils@2.2.13(ethers@6.13.4)': + dependencies: + ethers: 6.13.4 + js-base64: 3.7.7 + + '@0xsequence/utils@2.2.3(ethers@6.13.4)': + dependencies: + ethers: 6.13.4 + js-base64: 3.7.7 + + '@0xsequence/wallet@2.2.13(ethers@6.13.4)': + dependencies: + '@0xsequence/abi': 2.2.13 + '@0xsequence/core': 2.2.13(ethers@6.13.4) + '@0xsequence/network': 2.2.13(ethers@6.13.4) + '@0xsequence/relayer': 2.2.13(ethers@6.13.4) + '@0xsequence/signhub': 2.2.13(ethers@6.13.4) + '@0xsequence/utils': 2.2.13(ethers@6.13.4) + ethers: 6.13.4 + + '@0xsequence/wallet@2.2.3(ethers@6.13.4)': + dependencies: + '@0xsequence/abi': 2.2.3 + '@0xsequence/core': 2.2.3(ethers@6.13.4) + '@0xsequence/network': 2.2.3(ethers@6.13.4) + '@0xsequence/relayer': 2.2.3(ethers@6.13.4) + '@0xsequence/signhub': 2.2.3(ethers@6.13.4) + '@0xsequence/utils': 2.2.3(ethers@6.13.4) + ethers: 6.13.4 + + '@adraffy/ens-normalize@1.10.1': {} + + '@ampproject/remapping@2.2.1': + dependencies: + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.18 + + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + + '@babel/code-frame@7.23.5': + dependencies: + '@babel/highlight': 7.23.4 + chalk: 2.4.2 + + '@babel/code-frame@7.24.2': + dependencies: + '@babel/highlight': 7.24.2 + picocolors: 1.0.0 + + '@babel/compat-data@7.23.5': {} + + '@babel/core@7.23.7': + dependencies: + '@ampproject/remapping': 2.2.1 + '@babel/code-frame': 7.23.5 + '@babel/generator': 7.23.6 + '@babel/helper-compilation-targets': 7.23.6 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.7) + '@babel/helpers': 7.23.8 + '@babel/parser': 7.23.6 + '@babel/template': 7.22.15 + '@babel/traverse': 7.23.7 + '@babel/types': 7.23.6 + convert-source-map: 2.0.0 + debug: 4.3.4 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/core@7.24.3': + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.24.2 + '@babel/generator': 7.24.1 + '@babel/helper-compilation-targets': 7.23.6 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.3) + '@babel/helpers': 7.24.1 + '@babel/parser': 7.24.1 + '@babel/template': 7.24.0 + '@babel/traverse': 7.24.1 + '@babel/types': 7.24.0 + convert-source-map: 2.0.0 + debug: 4.3.4 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.23.6': + dependencies: + '@babel/types': 7.23.6 + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.21 + jsesc: 2.5.2 + + '@babel/generator@7.24.1': + dependencies: + '@babel/types': 7.24.0 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 2.5.2 + + '@babel/helper-compilation-targets@7.23.6': + dependencies: + '@babel/compat-data': 7.23.5 + '@babel/helper-validator-option': 7.23.5 + browserslist: 4.22.2 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-environment-visitor@7.22.20': {} + + '@babel/helper-function-name@7.23.0': + dependencies: + '@babel/template': 7.22.15 + '@babel/types': 7.23.6 + + '@babel/helper-hoist-variables@7.22.5': + dependencies: + '@babel/types': 7.22.5 + + '@babel/helper-module-imports@7.22.15': + dependencies: + '@babel/types': 7.23.6 + + '@babel/helper-module-transforms@7.23.3(@babel/core@7.23.7)': + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-module-imports': 7.22.15 + '@babel/helper-simple-access': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/helper-validator-identifier': 7.22.20 + + '@babel/helper-module-transforms@7.23.3(@babel/core@7.24.3)': + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-module-imports': 7.22.15 + '@babel/helper-simple-access': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/helper-validator-identifier': 7.22.20 + + '@babel/helper-plugin-utils@7.22.5': {} + + '@babel/helper-plugin-utils@7.24.0': {} + + '@babel/helper-simple-access@7.22.5': + dependencies: + '@babel/types': 7.22.5 + + '@babel/helper-split-export-declaration@7.22.6': + dependencies: + '@babel/types': 7.22.5 + + '@babel/helper-string-parser@7.22.5': {} + + '@babel/helper-string-parser@7.23.4': {} + + '@babel/helper-string-parser@7.24.1': {} + + '@babel/helper-validator-identifier@7.22.20': {} + + '@babel/helper-validator-identifier@7.22.5': {} + + '@babel/helper-validator-option@7.23.5': {} + + '@babel/helpers@7.23.8': + dependencies: + '@babel/template': 7.22.15 + '@babel/traverse': 7.23.7 + '@babel/types': 7.23.6 + transitivePeerDependencies: + - supports-color + + '@babel/helpers@7.24.1': + dependencies: + '@babel/template': 7.24.0 + '@babel/traverse': 7.24.1 + '@babel/types': 7.24.0 + transitivePeerDependencies: + - supports-color + + '@babel/highlight@7.23.4': + dependencies: + '@babel/helper-validator-identifier': 7.22.20 + chalk: 2.4.2 + js-tokens: 4.0.0 + + '@babel/highlight@7.24.2': + dependencies: + '@babel/helper-validator-identifier': 7.22.20 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.0.0 + + '@babel/parser@7.23.6': + dependencies: + '@babel/types': 7.23.6 + + '@babel/parser@7.24.1': + dependencies: + '@babel/types': 7.24.0 + + '@babel/plugin-syntax-typescript@7.24.1(@babel/core@7.24.3)': + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 + + '@babel/plugin-transform-react-jsx-self@7.23.3(@babel/core@7.23.7)': + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + + '@babel/plugin-transform-react-jsx-source@7.23.3(@babel/core@7.23.7)': + dependencies: + '@babel/core': 7.23.7 + '@babel/helper-plugin-utils': 7.22.5 + + '@babel/runtime@7.24.1': + dependencies: + regenerator-runtime: 0.14.1 + + '@babel/template@7.22.15': + dependencies: + '@babel/code-frame': 7.23.5 + '@babel/parser': 7.23.6 + '@babel/types': 7.23.6 + + '@babel/template@7.24.0': + dependencies: + '@babel/code-frame': 7.24.2 + '@babel/parser': 7.24.1 + '@babel/types': 7.24.0 + + '@babel/traverse@7.23.7': + dependencies: + '@babel/code-frame': 7.23.5 + '@babel/generator': 7.23.6 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/parser': 7.23.6 + '@babel/types': 7.23.6 + debug: 4.3.4 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/traverse@7.24.1': + dependencies: + '@babel/code-frame': 7.24.2 + '@babel/generator': 7.24.1 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/parser': 7.24.1 + '@babel/types': 7.24.0 + debug: 4.3.4 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.22.5': + dependencies: + '@babel/helper-string-parser': 7.22.5 + '@babel/helper-validator-identifier': 7.22.5 + to-fast-properties: 2.0.0 + + '@babel/types@7.23.6': + dependencies: + '@babel/helper-string-parser': 7.23.4 + '@babel/helper-validator-identifier': 7.22.20 + to-fast-properties: 2.0.0 + + '@babel/types@7.24.0': + dependencies: + '@babel/helper-string-parser': 7.24.1 + '@babel/helper-validator-identifier': 7.22.20 + to-fast-properties: 2.0.0 + + '@databeat/tracker@0.9.3': + dependencies: + '@noble/hashes': 1.6.1 + + '@emotion/hash@0.9.1': {} + + '@emotion/is-prop-valid@0.8.8': + dependencies: + '@emotion/memoize': 0.7.4 + optional: true + + '@emotion/memoize@0.7.4': + optional: true + + '@esbuild/aix-ppc64@0.19.12': + optional: true + + '@esbuild/aix-ppc64@0.20.2': + optional: true + + '@esbuild/android-arm64@0.19.12': + optional: true + + '@esbuild/android-arm64@0.20.2': + optional: true + + '@esbuild/android-arm@0.19.12': + optional: true + + '@esbuild/android-arm@0.20.2': + optional: true + + '@esbuild/android-x64@0.19.12': + optional: true + + '@esbuild/android-x64@0.20.2': + optional: true + + '@esbuild/darwin-arm64@0.19.12': + optional: true + + '@esbuild/darwin-arm64@0.20.2': + optional: true + + '@esbuild/darwin-x64@0.19.12': + optional: true + + '@esbuild/darwin-x64@0.20.2': + optional: true + + '@esbuild/freebsd-arm64@0.19.12': + optional: true + + '@esbuild/freebsd-arm64@0.20.2': + optional: true + + '@esbuild/freebsd-x64@0.19.12': + optional: true + + '@esbuild/freebsd-x64@0.20.2': + optional: true + + '@esbuild/linux-arm64@0.19.12': + optional: true + + '@esbuild/linux-arm64@0.20.2': + optional: true + + '@esbuild/linux-arm@0.19.12': + optional: true + + '@esbuild/linux-arm@0.20.2': + optional: true + + '@esbuild/linux-ia32@0.19.12': + optional: true + + '@esbuild/linux-ia32@0.20.2': + optional: true + + '@esbuild/linux-loong64@0.19.12': + optional: true + + '@esbuild/linux-loong64@0.20.2': + optional: true + + '@esbuild/linux-mips64el@0.19.12': + optional: true + + '@esbuild/linux-mips64el@0.20.2': + optional: true + + '@esbuild/linux-ppc64@0.19.12': + optional: true + + '@esbuild/linux-ppc64@0.20.2': + optional: true + + '@esbuild/linux-riscv64@0.19.12': + optional: true + + '@esbuild/linux-riscv64@0.20.2': + optional: true + + '@esbuild/linux-s390x@0.19.12': + optional: true + + '@esbuild/linux-s390x@0.20.2': + optional: true + + '@esbuild/linux-x64@0.19.12': + optional: true + + '@esbuild/linux-x64@0.20.2': + optional: true + + '@esbuild/netbsd-x64@0.19.12': + optional: true + + '@esbuild/netbsd-x64@0.20.2': + optional: true + + '@esbuild/openbsd-x64@0.19.12': + optional: true + + '@esbuild/openbsd-x64@0.20.2': + optional: true + + '@esbuild/sunos-x64@0.19.12': + optional: true + + '@esbuild/sunos-x64@0.20.2': + optional: true + + '@esbuild/win32-arm64@0.19.12': + optional: true + + '@esbuild/win32-arm64@0.20.2': + optional: true + + '@esbuild/win32-ia32@0.19.12': + optional: true + + '@esbuild/win32-ia32@0.20.2': + optional: true + + '@esbuild/win32-x64@0.19.12': + optional: true + + '@esbuild/win32-x64@0.20.2': + optional: true + + '@floating-ui/core@1.6.0': + dependencies: + '@floating-ui/utils': 0.2.1 + + '@floating-ui/dom@1.6.3': + dependencies: + '@floating-ui/core': 1.6.0 + '@floating-ui/utils': 0.2.1 + + '@floating-ui/react-dom@2.0.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@floating-ui/dom': 1.6.3 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@floating-ui/utils@0.2.1': {} + + '@jridgewell/gen-mapping@0.3.3': + dependencies: + '@jridgewell/set-array': 1.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping': 0.3.18 + + '@jridgewell/gen-mapping@0.3.5': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.0': {} + + '@jridgewell/resolve-uri@3.1.1': {} + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/sourcemap-codec@1.4.14': {} + + '@jridgewell/sourcemap-codec@1.4.15': {} + + '@jridgewell/trace-mapping@0.3.18': + dependencies: + '@jridgewell/resolve-uri': 3.1.0 + '@jridgewell/sourcemap-codec': 1.4.14 + + '@jridgewell/trace-mapping@0.3.21': + dependencies: + '@jridgewell/resolve-uri': 3.1.1 + '@jridgewell/sourcemap-codec': 1.4.15 + + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + + '@motionone/animation@10.15.1': + dependencies: + '@motionone/easing': 10.15.1 + '@motionone/types': 10.15.1 + '@motionone/utils': 10.15.1 + tslib: 2.6.2 + + '@motionone/dom@10.16.2': + dependencies: + '@motionone/animation': 10.15.1 + '@motionone/generators': 10.15.1 + '@motionone/types': 10.15.1 + '@motionone/utils': 10.15.1 + hey-listen: 1.0.8 + tslib: 2.6.2 + + '@motionone/easing@10.15.1': + dependencies: + '@motionone/utils': 10.15.1 + tslib: 2.6.2 + + '@motionone/generators@10.15.1': + dependencies: + '@motionone/types': 10.15.1 + '@motionone/utils': 10.15.1 + tslib: 2.6.2 + + '@motionone/types@10.15.1': {} + + '@motionone/utils@10.15.1': + dependencies: + '@motionone/types': 10.15.1 + hey-listen: 1.0.8 + tslib: 2.6.2 + + '@noble/curves@1.2.0': + dependencies: + '@noble/hashes': 1.3.2 + + '@noble/hashes@1.3.2': {} + + '@noble/hashes@1.6.1': {} + + '@radix-ui/number@1.1.0': {} + + '@radix-ui/primitive@1.1.0': {} + + '@radix-ui/react-arrow@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.7 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-aspect-ratio@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.7 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-checkbox@1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-context': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-presence': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.7)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.7 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-collapsible@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-context': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-presence': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.7)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.7 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-collection@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-context': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.1.0(@types/react@18.3.7)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.7 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-compose-refs@1.1.0(@types/react@18.3.7)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.7 + + '@radix-ui/react-context@1.1.0(@types/react@18.3.7)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.7 + + '@radix-ui/react-dialog@1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-context': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-portal': 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.7)(react@18.3.1) + aria-hidden: 1.2.4 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.5.7(@types/react@18.3.7)(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.7 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-direction@1.1.0(@types/react@18.3.7)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.7 + + '@radix-ui/react-dismissable-layer@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-use-escape-keydown': 1.1.0(@types/react@18.3.7)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.7 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-dropdown-menu@2.1.1(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-context': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-menu': 2.1.1(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.7)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.7 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-focus-guards@1.1.0(@types/react@18.3.7)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.7 + + '@radix-ui/react-focus-scope@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.7)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.7 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-id@1.1.0(@types/react@18.3.7)(react@18.3.1)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.7)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.7 + + '@radix-ui/react-menu@2.1.1(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-collection': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-context': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-popper': 1.2.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.7)(react@18.3.1) + aria-hidden: 1.2.4 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.5.7(@types/react@18.3.7)(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.7 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-popper@1.2.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@floating-ui/react-dom': 2.0.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-arrow': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-context': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-use-rect': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/rect': 1.1.0 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.7 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-portal@1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.7)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.7 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-presence@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.7)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.7 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-primitive@2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-slot': 1.1.0(@types/react@18.3.7)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.7 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-progress@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-context': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.7 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-radio-group@1.2.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-context': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-presence': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.7)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.7 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-roving-focus@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-collection': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-context': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.7)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.7 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-select@2.1.1(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/number': 1.1.0 + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-collection': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-context': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-popper': 1.2.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + aria-hidden: 1.2.4 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.5.7(@types/react@18.3.7)(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.7 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-slot@1.1.0(@types/react@18.3.7)(react@18.3.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.7)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.7 + + '@radix-ui/react-switch@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-context': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.7)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.7 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-tabs@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-context': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-presence': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.7)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.7 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-toast@1.2.1(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-collection': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-context': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.7 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-tooltip@1.1.2(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-context': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-popper': 1.2.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.7)(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.7 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-use-callback-ref@1.1.0(@types/react@18.3.7)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.7 + + '@radix-ui/react-use-controllable-state@1.1.0(@types/react@18.3.7)(react@18.3.1)': + dependencies: + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.7)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.7 + + '@radix-ui/react-use-escape-keydown@1.1.0(@types/react@18.3.7)(react@18.3.1)': + dependencies: + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.7)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.7 + + '@radix-ui/react-use-layout-effect@1.1.0(@types/react@18.3.7)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.7 + + '@radix-ui/react-use-previous@1.1.0(@types/react@18.3.7)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.7 + + '@radix-ui/react-use-rect@1.1.0(@types/react@18.3.7)(react@18.3.1)': + dependencies: + '@radix-ui/rect': 1.1.0 + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.7 + + '@radix-ui/react-use-size@1.1.0(@types/react@18.3.7)(react@18.3.1)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.7)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.7 + + '@radix-ui/react-visually-hidden@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.7)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.7 + '@types/react-dom': 18.3.0 + + '@radix-ui/rect@1.1.0': {} + + '@rollup/pluginutils@5.1.0(rollup@4.21.3)': + dependencies: + '@types/estree': 1.0.5 + estree-walker: 2.0.2 + picomatch: 2.3.1 + optionalDependencies: + rollup: 4.21.3 + + '@rollup/rollup-android-arm-eabi@4.13.1': + optional: true + + '@rollup/rollup-android-arm-eabi@4.21.3': + optional: true + + '@rollup/rollup-android-arm64@4.13.1': + optional: true + + '@rollup/rollup-android-arm64@4.21.3': + optional: true + + '@rollup/rollup-darwin-arm64@4.13.1': + optional: true + + '@rollup/rollup-darwin-arm64@4.21.3': + optional: true + + '@rollup/rollup-darwin-x64@4.13.1': + optional: true + + '@rollup/rollup-darwin-x64@4.21.3': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.13.1': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.21.3': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.21.3': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.13.1': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.21.3': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.13.1': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.21.3': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.21.3': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.13.1': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.21.3': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.13.1': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.21.3': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.13.1': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.21.3': + optional: true + + '@rollup/rollup-linux-x64-musl@4.13.1': + optional: true + + '@rollup/rollup-linux-x64-musl@4.21.3': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.13.1': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.21.3': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.13.1': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.21.3': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.13.1': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.21.3': + optional: true + + '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.23.7)': + dependencies: + '@babel/core': 7.23.7 + + '@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.23.7)': + dependencies: + '@babel/core': 7.23.7 + + '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.23.7)': + dependencies: + '@babel/core': 7.23.7 + + '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.23.7)': + dependencies: + '@babel/core': 7.23.7 + + '@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.23.7)': + dependencies: + '@babel/core': 7.23.7 + + '@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.23.7)': + dependencies: + '@babel/core': 7.23.7 + + '@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.23.7)': + dependencies: + '@babel/core': 7.23.7 + + '@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.23.7)': + dependencies: + '@babel/core': 7.23.7 + + '@svgr/babel-preset@8.1.0(@babel/core@7.23.7)': + dependencies: + '@babel/core': 7.23.7 + '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.23.7) + '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.23.7) + '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.23.7) + '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.23.7) + '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.23.7) + '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.23.7) + '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.23.7) + '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.23.7) + + '@svgr/core@8.1.0(typescript@4.5.5)': + dependencies: + '@babel/core': 7.23.7 + '@svgr/babel-preset': 8.1.0(@babel/core@7.23.7) + camelcase: 6.3.0 + cosmiconfig: 8.3.6(typescript@4.5.5) + snake-case: 3.0.4 + transitivePeerDependencies: + - supports-color + - typescript + + '@svgr/hast-util-to-babel-ast@8.0.0': + dependencies: + '@babel/types': 7.23.6 + entities: 4.5.0 + + '@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@4.5.5))': + dependencies: + '@babel/core': 7.23.7 + '@svgr/babel-preset': 8.1.0(@babel/core@7.23.7) + '@svgr/core': 8.1.0(typescript@4.5.5) + '@svgr/hast-util-to-babel-ast': 8.0.0 + svg-parser: 2.0.4 + transitivePeerDependencies: + - supports-color + + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.23.6 + '@babel/types': 7.23.6 + '@types/babel__generator': 7.6.8 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.20.5 + + '@types/babel__generator@7.6.8': + dependencies: + '@babel/types': 7.23.6 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.23.6 + '@babel/types': 7.23.6 + + '@types/babel__traverse@7.20.5': + dependencies: + '@babel/types': 7.23.6 + + '@types/estree@1.0.5': {} + + '@types/node@20.11.30': + dependencies: + undici-types: 5.26.5 + + '@types/node@22.7.5': + dependencies: + undici-types: 6.19.8 + + '@types/prop-types@15.7.13': {} + + '@types/react-dom@18.3.0': + dependencies: + '@types/react': 18.3.7 + + '@types/react@18.3.7': + dependencies: + '@types/prop-types': 15.7.13 + csstype: 3.1.3 + + '@vanilla-extract/babel-plugin-debug-ids@1.0.5': + dependencies: + '@babel/core': 7.24.3 + transitivePeerDependencies: + - supports-color + + '@vanilla-extract/css@1.14.1': + dependencies: + '@emotion/hash': 0.9.1 + '@vanilla-extract/private': 1.0.3 + chalk: 4.1.2 + css-what: 6.1.0 + cssesc: 3.0.0 + csstype: 3.1.3 + deep-object-diff: 1.1.9 + deepmerge: 4.3.1 + media-query-parser: 2.0.2 + modern-ahocorasick: 1.0.1 + outdent: 0.8.0 + + '@vanilla-extract/integration@7.1.1(@types/node@20.11.30)': + dependencies: + '@babel/core': 7.24.3 + '@babel/plugin-syntax-typescript': 7.24.1(@babel/core@7.24.3) + '@vanilla-extract/babel-plugin-debug-ids': 1.0.5 + '@vanilla-extract/css': 1.14.1 + esbuild: 0.19.12 + eval: 0.1.8 + find-up: 5.0.0 + javascript-stringify: 2.1.0 + lodash: 4.17.21 + mlly: 1.6.1 + outdent: 0.8.0 + vite: 5.2.6(@types/node@20.11.30) + vite-node: 1.4.0(@types/node@20.11.30) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + + '@vanilla-extract/private@1.0.3': {} + + '@vanilla-extract/vite-plugin@4.0.6(@types/node@20.11.30)(vite@5.2.6(@types/node@20.11.30))': + dependencies: + '@vanilla-extract/integration': 7.1.1(@types/node@20.11.30) + vite: 5.2.6(@types/node@20.11.30) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + + '@vitejs/plugin-react@4.2.1(vite@5.2.6(@types/node@20.11.30))': + dependencies: + '@babel/core': 7.23.7 + '@babel/plugin-transform-react-jsx-self': 7.23.3(@babel/core@7.23.7) + '@babel/plugin-transform-react-jsx-source': 7.23.3(@babel/core@7.23.7) + '@types/babel__core': 7.20.5 + react-refresh: 0.14.0 + vite: 5.2.6(@types/node@20.11.30) + transitivePeerDependencies: + - supports-color + + acorn@8.11.3: {} + + aes-js@4.0.0-beta.5: {} + + ansi-styles@3.2.1: + dependencies: + color-convert: 1.9.3 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + argparse@2.0.1: {} + + aria-hidden@1.2.4: + dependencies: + tslib: 2.6.2 + + browserslist@4.22.2: + dependencies: + caniuse-lite: 1.0.30001579 + electron-to-chromium: 1.4.638 + node-releases: 2.0.14 + update-browserslist-db: 1.0.13(browserslist@4.22.2) + + cac@6.7.14: {} + + callsites@3.1.0: {} + + camelcase@6.3.0: {} + + caniuse-lite@1.0.30001579: {} + + chalk@2.4.2: + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.3: {} + + color-name@1.1.4: {} + + convert-source-map@2.0.0: {} + + cosmiconfig@8.3.6(typescript@4.5.5): + dependencies: + import-fresh: 3.3.0 + js-yaml: 4.1.0 + parse-json: 5.2.0 + path-type: 4.0.0 + optionalDependencies: + typescript: 4.5.5 + + css-what@6.1.0: {} + + cssesc@3.0.0: {} + + csstype@3.1.3: {} + + debug@4.3.4: + dependencies: + ms: 2.1.2 + + deep-object-diff@1.1.9: {} + + deepmerge@4.3.1: {} + + detect-node-es@1.1.0: {} + + dot-case@3.0.4: + dependencies: + no-case: 3.0.4 + tslib: 2.6.2 + + electron-to-chromium@1.4.638: {} + + entities@4.5.0: {} + + error-ex@1.3.2: + dependencies: + is-arrayish: 0.2.1 + + esbuild@0.19.12: + optionalDependencies: + '@esbuild/aix-ppc64': 0.19.12 + '@esbuild/android-arm': 0.19.12 + '@esbuild/android-arm64': 0.19.12 + '@esbuild/android-x64': 0.19.12 + '@esbuild/darwin-arm64': 0.19.12 + '@esbuild/darwin-x64': 0.19.12 + '@esbuild/freebsd-arm64': 0.19.12 + '@esbuild/freebsd-x64': 0.19.12 + '@esbuild/linux-arm': 0.19.12 + '@esbuild/linux-arm64': 0.19.12 + '@esbuild/linux-ia32': 0.19.12 + '@esbuild/linux-loong64': 0.19.12 + '@esbuild/linux-mips64el': 0.19.12 + '@esbuild/linux-ppc64': 0.19.12 + '@esbuild/linux-riscv64': 0.19.12 + '@esbuild/linux-s390x': 0.19.12 + '@esbuild/linux-x64': 0.19.12 + '@esbuild/netbsd-x64': 0.19.12 + '@esbuild/openbsd-x64': 0.19.12 + '@esbuild/sunos-x64': 0.19.12 + '@esbuild/win32-arm64': 0.19.12 + '@esbuild/win32-ia32': 0.19.12 + '@esbuild/win32-x64': 0.19.12 + + esbuild@0.20.2: + optionalDependencies: + '@esbuild/aix-ppc64': 0.20.2 + '@esbuild/android-arm': 0.20.2 + '@esbuild/android-arm64': 0.20.2 + '@esbuild/android-x64': 0.20.2 + '@esbuild/darwin-arm64': 0.20.2 + '@esbuild/darwin-x64': 0.20.2 + '@esbuild/freebsd-arm64': 0.20.2 + '@esbuild/freebsd-x64': 0.20.2 + '@esbuild/linux-arm': 0.20.2 + '@esbuild/linux-arm64': 0.20.2 + '@esbuild/linux-ia32': 0.20.2 + '@esbuild/linux-loong64': 0.20.2 + '@esbuild/linux-mips64el': 0.20.2 + '@esbuild/linux-ppc64': 0.20.2 + '@esbuild/linux-riscv64': 0.20.2 + '@esbuild/linux-s390x': 0.20.2 + '@esbuild/linux-x64': 0.20.2 + '@esbuild/netbsd-x64': 0.20.2 + '@esbuild/openbsd-x64': 0.20.2 + '@esbuild/sunos-x64': 0.20.2 + '@esbuild/win32-arm64': 0.20.2 + '@esbuild/win32-ia32': 0.20.2 + '@esbuild/win32-x64': 0.20.2 + + escalade@3.1.1: {} + + escape-string-regexp@1.0.5: {} + + estree-walker@2.0.2: {} + + ethers@6.13.4: + dependencies: + '@adraffy/ens-normalize': 1.10.1 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@types/node': 22.7.5 + aes-js: 4.0.0-beta.5 + tslib: 2.7.0 + ws: 8.17.1 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + eval@0.1.8: + dependencies: + '@types/node': 20.11.30 + require-like: 0.1.2 + + eventemitter2@6.4.9: {} + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + framer-motion@9.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@motionone/dom': 10.16.2 + hey-listen: 1.0.8 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + tslib: 2.6.1 + optionalDependencies: + '@emotion/is-prop-valid': 0.8.8 + + fsevents@2.3.3: + optional: true + + gensync@1.0.0-beta.2: {} + + get-nonce@1.0.1: {} + + globals@11.12.0: {} + + globrex@0.1.2: {} + + has-flag@3.0.0: {} + + has-flag@4.0.0: {} + + hey-listen@1.0.8: {} + + idb@7.1.1: {} + + import-fresh@3.3.0: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + invariant@2.2.4: + dependencies: + loose-envify: 1.4.0 + + is-arrayish@0.2.1: {} + + javascript-stringify@2.1.0: {} + + js-base64@3.7.7: {} + + js-tokens@4.0.0: {} + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + jsesc@2.5.2: {} + + json-parse-even-better-errors@2.3.1: {} + + json5@2.2.3: {} + + jsonc-parser@3.2.1: {} + + lines-and-columns@1.2.4: {} + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash@4.17.21: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + lower-case@2.0.2: + dependencies: + tslib: 2.6.2 + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + media-query-parser@2.0.2: + dependencies: + '@babel/runtime': 7.24.1 + + mlly@1.6.1: + dependencies: + acorn: 8.11.3 + pathe: 1.1.2 + pkg-types: 1.0.3 + ufo: 1.5.3 + + modern-ahocorasick@1.0.1: {} + + ms@2.1.2: {} + + nanoid@3.3.7: {} + + no-case@3.0.4: + dependencies: + lower-case: 2.0.2 + tslib: 2.6.2 + + node-releases@2.0.14: {} + + outdent@0.8.0: {} + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse-json@5.2.0: + dependencies: + '@babel/code-frame': 7.23.5 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + + path-exists@4.0.0: {} + + path-type@4.0.0: {} + + pathe@1.1.2: {} + + picocolors@1.0.0: {} + + picomatch@2.3.1: {} + + pkg-types@1.0.3: + dependencies: + jsonc-parser: 3.2.1 + mlly: 1.6.1 + pathe: 1.1.2 + + postcss@8.4.38: + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.0 + source-map-js: 1.2.0 + + react-dom@18.3.1(react@18.3.1): + dependencies: + loose-envify: 1.4.0 + react: 18.3.1 + scheduler: 0.23.2 + + react-hook-form@7.53.0(react@18.3.1): + dependencies: + react: 18.3.1 + + react-refresh@0.14.0: {} + + react-remove-scroll-bar@2.3.6(@types/react@18.3.7)(react@18.3.1): + dependencies: + react: 18.3.1 + react-style-singleton: 2.2.1(@types/react@18.3.7)(react@18.3.1) + tslib: 2.6.2 + optionalDependencies: + '@types/react': 18.3.7 + + react-remove-scroll@2.5.7(@types/react@18.3.7)(react@18.3.1): + dependencies: + react: 18.3.1 + react-remove-scroll-bar: 2.3.6(@types/react@18.3.7)(react@18.3.1) + react-style-singleton: 2.2.1(@types/react@18.3.7)(react@18.3.1) + tslib: 2.6.2 + use-callback-ref: 1.3.2(@types/react@18.3.7)(react@18.3.1) + use-sidecar: 1.1.2(@types/react@18.3.7)(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.7 + + react-style-singleton@2.2.1(@types/react@18.3.7)(react@18.3.1): + dependencies: + get-nonce: 1.0.1 + invariant: 2.2.4 + react: 18.3.1 + tslib: 2.6.2 + optionalDependencies: + '@types/react': 18.3.7 + + react@18.3.1: + dependencies: + loose-envify: 1.4.0 + + regenerator-runtime@0.14.1: {} + + require-like@0.1.2: {} + + resolve-from@4.0.0: {} + + rollup@4.13.1: + dependencies: + '@types/estree': 1.0.5 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.13.1 + '@rollup/rollup-android-arm64': 4.13.1 + '@rollup/rollup-darwin-arm64': 4.13.1 + '@rollup/rollup-darwin-x64': 4.13.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.13.1 + '@rollup/rollup-linux-arm64-gnu': 4.13.1 + '@rollup/rollup-linux-arm64-musl': 4.13.1 + '@rollup/rollup-linux-riscv64-gnu': 4.13.1 + '@rollup/rollup-linux-s390x-gnu': 4.13.1 + '@rollup/rollup-linux-x64-gnu': 4.13.1 + '@rollup/rollup-linux-x64-musl': 4.13.1 + '@rollup/rollup-win32-arm64-msvc': 4.13.1 + '@rollup/rollup-win32-ia32-msvc': 4.13.1 + '@rollup/rollup-win32-x64-msvc': 4.13.1 + fsevents: 2.3.3 + + rollup@4.21.3: + dependencies: + '@types/estree': 1.0.5 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.21.3 + '@rollup/rollup-android-arm64': 4.21.3 + '@rollup/rollup-darwin-arm64': 4.21.3 + '@rollup/rollup-darwin-x64': 4.21.3 + '@rollup/rollup-linux-arm-gnueabihf': 4.21.3 + '@rollup/rollup-linux-arm-musleabihf': 4.21.3 + '@rollup/rollup-linux-arm64-gnu': 4.21.3 + '@rollup/rollup-linux-arm64-musl': 4.21.3 + '@rollup/rollup-linux-powerpc64le-gnu': 4.21.3 + '@rollup/rollup-linux-riscv64-gnu': 4.21.3 + '@rollup/rollup-linux-s390x-gnu': 4.21.3 + '@rollup/rollup-linux-x64-gnu': 4.21.3 + '@rollup/rollup-linux-x64-musl': 4.21.3 + '@rollup/rollup-win32-arm64-msvc': 4.21.3 + '@rollup/rollup-win32-ia32-msvc': 4.21.3 + '@rollup/rollup-win32-x64-msvc': 4.21.3 + fsevents: 2.3.3 + optional: true + + scheduler@0.23.2: + dependencies: + loose-envify: 1.4.0 + + semver@6.3.1: {} + + snake-case@3.0.4: + dependencies: + dot-case: 3.0.4 + tslib: 2.6.2 + + source-map-js@1.2.0: {} + + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + svg-parser@2.0.4: {} + + to-fast-properties@2.0.0: {} + + tsconfck@3.0.3(typescript@4.5.5): + optionalDependencies: + typescript: 4.5.5 + + tslib@2.6.1: {} + + tslib@2.6.2: {} + + tslib@2.7.0: {} + + typescript@4.5.5: {} + + ufo@1.5.3: {} + + undici-types@5.26.5: {} + + undici-types@6.19.8: {} + + update-browserslist-db@1.0.13(browserslist@4.22.2): + dependencies: + browserslist: 4.22.2 + escalade: 3.1.1 + picocolors: 1.0.0 + + use-callback-ref@1.3.2(@types/react@18.3.7)(react@18.3.1): + dependencies: + react: 18.3.1 + tslib: 2.6.2 + optionalDependencies: + '@types/react': 18.3.7 + + use-sidecar@1.1.2(@types/react@18.3.7)(react@18.3.1): + dependencies: + detect-node-es: 1.1.0 + react: 18.3.1 + tslib: 2.6.2 + optionalDependencies: + '@types/react': 18.3.7 + + vite-node@1.4.0(@types/node@20.11.30): + dependencies: + cac: 6.7.14 + debug: 4.3.4 + pathe: 1.1.2 + picocolors: 1.0.0 + vite: 5.2.6(@types/node@20.11.30) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + + vite-plugin-svgr@4.2.0(rollup@4.21.3)(typescript@4.5.5)(vite@5.2.6(@types/node@20.11.30)): + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@4.21.3) + '@svgr/core': 8.1.0(typescript@4.5.5) + '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@4.5.5)) + vite: 5.2.6(@types/node@20.11.30) + transitivePeerDependencies: + - rollup + - supports-color + - typescript + + vite-tsconfig-paths@4.3.2(typescript@4.5.5)(vite@5.2.6(@types/node@20.11.30)): + dependencies: + debug: 4.3.4 + globrex: 0.1.2 + tsconfck: 3.0.3(typescript@4.5.5) + optionalDependencies: + vite: 5.2.6(@types/node@20.11.30) + transitivePeerDependencies: + - supports-color + - typescript + + vite@5.2.6(@types/node@20.11.30): + dependencies: + esbuild: 0.20.2 + postcss: 8.4.38 + rollup: 4.13.1 + optionalDependencies: + '@types/node': 20.11.30 + fsevents: 2.3.3 + + webextension-polyfill@0.10.0: {} + + ws@8.17.1: {} + + yallist@3.1.1: {} + + yocto-queue@0.1.0: {} diff --git a/.codesandbox/public/favicon.ico b/.codesandbox/public/favicon.ico new file mode 100644 index 0000000000..bf5da566d2 Binary files /dev/null and b/.codesandbox/public/favicon.ico differ diff --git a/.codesandbox/public/logo192.png b/.codesandbox/public/logo192.png new file mode 100644 index 0000000000..f90c48a287 Binary files /dev/null and b/.codesandbox/public/logo192.png differ diff --git a/.codesandbox/public/logo512.png b/.codesandbox/public/logo512.png new file mode 100644 index 0000000000..36aff8456a Binary files /dev/null and b/.codesandbox/public/logo512.png differ diff --git a/.codesandbox/public/manifest.json b/.codesandbox/public/manifest.json new file mode 100644 index 0000000000..9db53285e9 --- /dev/null +++ b/.codesandbox/public/manifest.json @@ -0,0 +1,25 @@ +{ + "short_name": "Sequence Demo Dapp", + "name": "Ethereum Demo Dapp built on Sequence stack", + "icons": [ + { + "src": "favicon.ico", + "sizes": "64x64 32x32 24x24 16x16", + "type": "image/x-icon" + }, + { + "src": "logo192.png", + "type": "image/png", + "sizes": "192x192" + }, + { + "src": "logo512.png", + "type": "image/png", + "sizes": "512x512" + } + ], + "start_url": ".", + "display": "standalone", + "theme_color": "#000000", + "background_color": "#ffffff" +} diff --git a/.codesandbox/public/robots.txt b/.codesandbox/public/robots.txt new file mode 100644 index 0000000000..e9e57dc4d4 --- /dev/null +++ b/.codesandbox/public/robots.txt @@ -0,0 +1,3 @@ +# https://www.robotstxt.org/robotstxt.html +User-agent: * +Disallow: diff --git a/.codesandbox/screenshots/screen-open.png b/.codesandbox/screenshots/screen-open.png new file mode 100644 index 0000000000..17fa83ccc1 Binary files /dev/null and b/.codesandbox/screenshots/screen-open.png differ diff --git a/.codesandbox/screenshots/screen-txn.png b/.codesandbox/screenshots/screen-txn.png new file mode 100644 index 0000000000..3ed768960e Binary files /dev/null and b/.codesandbox/screenshots/screen-txn.png differ diff --git a/.codesandbox/src/App.tsx b/.codesandbox/src/App.tsx new file mode 100644 index 0000000000..73eec67f40 --- /dev/null +++ b/.codesandbox/src/App.tsx @@ -0,0 +1,1348 @@ +import { AnimatePresence } from 'framer-motion' +import React, { useState, useEffect, useMemo, SetStateAction } from 'react' +import { ethers } from 'ethers' +import { sequence } from '0xsequence' +import { walletContracts } from '@0xsequence/abi' +import { + Box, + Image, + Text, + Button, + ExternalLinkIcon, + Divider, + Card, + TransactionIcon, + Select, + TokenImage, + TextInput, + Modal +} from '@0xsequence/design-system' +import { ETHAuth } from '@0xsequence/ethane' +import { configureLogger } from '@0xsequence/utils' +import { ConnectOptions, OpenWalletIntent, Settings } from '@0xsequence/provider' +import { ChainId, NetworkType } from '@0xsequence/network' + +import { ERC_20_ABI } from './constants/abi' +import { Console } from './components/Console' +import { Group } from './components/Group' +import { getDefaultChainId, toHexString } from './helpers' +import logoUrl from './images/logo.svg' +import skyweaverBannerUrl from './images/sky weaver-banner.png' +import skyweaverBannerLargeUrl from './images/sky weaver-banner-large.png' + +configureLogger({ logLevel: 'DEBUG' }) + +interface Environment { + name: string + walletUrl: string + projectAccessKey: string +} + +const environments: Environment[] = [ + { + name: 'production', + walletUrl: 'https://sequence.app', + projectAccessKey: 'AQAAAAAAAAbvrgpWEC2Aefg5qYStQmwjBpA' + }, + { + name: 'development', + walletUrl: 'https://dev.sequence.app', + //projectAccessKey: 'AQAAAAAAAAVBNfoB30kz7Ph4I_Qs5mkYuDc', + projectAccessKey: 'AQAAAAAAAAVCXiQ9f_57R44MjorZ4SmGdhA' + }, + { + name: 'local', + walletUrl: 'http://localhost:3333', + projectAccessKey: 'AQAAAAAAAAVCXiQ9f_57R44MjorZ4SmGdhA' + }, + { + name: 'custom', + walletUrl: '', + projectAccessKey: '' + } +] + +const DEFAULT_API_URL = 'https://api.sequence.app' + +// Specify your desired default chain id. NOTE: you can communicate to multiple +// chains at the same time without even having to switch the network, but a default +// chain is required. +const defaultChainId = getDefaultChainId() || ChainId.MAINNET +// const defaultChainId = ChainId.POLYGON +// const defaultChainId = ChainId.GURLI +// const defaultChainId = ChainId.ARBITRUM +// const defaultChainId = ChainId.AVALANCHE +// etc.. see the full list here: https://docs.sequence.xyz/multi-chain-support + +// For Sequence core dev team -- app developers can ignore +// a custom wallet app url can specified in the query string +const urlParams = new URLSearchParams(window.location.search) + +const env = urlParams.get('env') ?? 'production' +const envConfig = environments.find(x => x.name === env) +const walletAppURL = urlParams.get('walletAppURL') ?? envConfig.walletUrl +const projectAccessKey = urlParams.get('projectAccessKey') ?? envConfig.projectAccessKey +const showProhibitedActions = urlParams.has('showProhibitedActions') + +const isCustom = walletAppURL !== envConfig.walletUrl || projectAccessKey !== envConfig.projectAccessKey + +if (walletAppURL && walletAppURL.length > 0) { + // Wallet can point to a custom wallet app url + // NOTICE: this is not needed, unless testing an alpha version of the wallet + sequence.initWallet(projectAccessKey, { defaultNetwork: defaultChainId, transports: { walletAppURL } }) +} else { + // Init the sequence wallet library at the top-level of your project with + // your designed default chain id + sequence.initWallet(projectAccessKey, { defaultNetwork: defaultChainId, transports: { walletAppURL } }) +} + +// App component +const App = () => { + const [consoleMsg, setConsoleMsg] = useState(null) + const [email, setEmail] = useState(null) + const [consoleLoading, setConsoleLoading] = useState(false) + const [isWalletConnected, setIsWalletConnected] = useState(false) + + const wallet = sequence.getWallet().getProvider() + + const [showChainId, setShowChainId] = useState(wallet.getChainId()) + const [isOpen, toggleModal] = useState(false) + const [warning, setWarning] = useState(false) + + useMemo(() => { + wallet.on('chainChanged', (chainId: string) => { + setShowChainId(Number(BigInt(chainId))) + }) + }, []) + + useEffect(() => { + setIsWalletConnected(wallet.isConnected()) + }, [wallet]) + + useEffect(() => { + consoleWelcomeMessage() + // eslint-disable-next-line + }, [isWalletConnected]) + + useEffect(() => { + // Wallet events + wallet.client.onOpen(() => { + console.log('wallet window opened') + }) + + wallet.client.onClose(() => { + console.log('wallet window closed') + }) + }, [wallet]) + + const defaultConnectOptions: ConnectOptions = { + app: 'Demo Dapp', + askForEmail: true + // keepWalletOpened: true, + } + + // Methods + const connect = async (connectOptions: ConnectOptions = { app: 'Demo dapp' }) => { + if (isWalletConnected) { + resetConsole() + appendConsoleLine('Wallet already connected!') + setConsoleLoading(false) + return + } + + connectOptions = { + ...defaultConnectOptions, + ...connectOptions, + settings: { + ...defaultConnectOptions.settings, + ...connectOptions.settings + } + } + + try { + resetConsole() + appendConsoleLine('Connecting') + const wallet = sequence.getWallet() + + const connectDetails = await wallet.connect(connectOptions) + + // Example of how to verify using ETHAuth via Sequence API + if (connectOptions.authorize && connectDetails.connected) { + let apiUrl = urlParams.get('apiUrl') + + if (!apiUrl || apiUrl.length === 0) { + apiUrl = DEFAULT_API_URL + } + + const api = new sequence.api.SequenceAPIClient(apiUrl) + // or just + // const api = new sequence.api.SequenceAPIClient('https://api.sequence.app') + + const { isValid } = await api.isValidETHAuthProof({ + chainId: connectDetails.chainId, + walletAddress: connectDetails.session.accountAddress, + ethAuthProofString: connectDetails.proof!.proofString + }) + + appendConsoleLine(`isValid (API)?: ${isValid}`) + } + + // Example of how to verify using ETHAuth directl on the client + if (connectOptions.authorize) { + const ethAuth = new ETHAuth() + + if (connectDetails.proof) { + const decodedProof = await ethAuth.decodeProof(connectDetails.proof.proofString, true) + + const isValid = await wallet.utils.isValidTypedDataSignature( + wallet.getAddress(), + connectDetails.proof.typedData, + decodedProof.signature, + Number(BigInt(connectDetails.chainId)) + ) + + appendConsoleLine(`connected using chainId: ${BigInt(connectDetails.chainId).toString()}`) + appendConsoleLine(`isValid (client)?: ${isValid}`) + } + } + + setConsoleLoading(false) + if (connectDetails.connected) { + appendConsoleLine('Wallet connected!') + appendConsoleLine(`shared email: ${connectDetails.email}`) + setIsWalletConnected(true) + } else { + appendConsoleLine('Failed to connect wallet - ' + connectDetails.error) + } + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const disconnect = () => { + const wallet = sequence.getWallet() + wallet.disconnect() + consoleWelcomeMessage() + setIsWalletConnected(false) + } + + const openWallet = () => { + const wallet = sequence.getWallet() + wallet.openWallet() + } + + const openWalletWithSettings = () => { + const wallet = sequence.getWallet() + + const settings: Settings = { + theme: 'light', + includedPaymentProviders: ['moonpay', 'ramp'], + defaultFundingCurrency: 'eth', + defaultPurchaseAmount: 400, + lockFundingCurrencyToDefault: false + } + + const intent: OpenWalletIntent = { + type: 'openWithOptions', + options: { + app: 'Demo Dapp', + settings + } + } + + const path = 'wallet/add-funds' + wallet.openWallet(path, intent) + } + + const closeWallet = () => { + const wallet = sequence.getWallet() + wallet.closeWallet() + } + + const isConnected = async () => { + resetConsole() + const wallet = sequence.getWallet() + appendConsoleLine(`isConnected?: ${wallet.isConnected()}`) + setConsoleLoading(false) + } + + const isOpened = async () => { + resetConsole() + const wallet = sequence.getWallet() + appendConsoleLine(`isOpened?: ${wallet.isOpened()}`) + setConsoleLoading(false) + } + + const getChainID = async () => { + try { + resetConsole() + + const topChainId = wallet.getChainId() + appendConsoleLine(`top chainId: ${topChainId}`) + + const provider = wallet.getProvider() + const providerChainId = provider!.getChainId() + appendConsoleLine(`provider.getChainId(): ${providerChainId}`) + + const signer = wallet.getSigner() + const signerChainId = await signer.getChainId() + appendConsoleLine(`signer.getChainId(): ${signerChainId}`) + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const getAccounts = async () => { + try { + resetConsole() + + const wallet = sequence.getWallet() + const address = wallet.getAddress() + appendConsoleLine(`getAddress(): ${address}`) + + const provider = wallet.getProvider() + const accountList = provider.listAccounts() + appendConsoleLine(`accounts: ${JSON.stringify(accountList)}`) + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const getBalance = async () => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + const provider = wallet.getProvider() + const account = wallet.getAddress() + const balanceChk1 = await provider!.getBalance(account) + appendConsoleLine(`balance check 1: ${balanceChk1.toString()}`) + + const signer = wallet.getSigner() + const balanceChk2 = await signer.getBalance() + appendConsoleLine(`balance check 2: ${balanceChk2.toString()}`) + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const getNetworks = async () => { + try { + resetConsole() + + const wallet = sequence.getWallet() + const networks = await wallet.getNetworks() + + appendConsoleLine(`networks: ${JSON.stringify(networks, null, 2)}`) + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const signMessageString = async () => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + appendConsoleLine('signing message...') + const signer = wallet.getSigner() + + const message = `1915 Robert Frost +The Road Not Taken + +Two roads diverged in a yellow wood, +And sorry I could not travel both +And be one traveler, long I stood +And looked down one as far as I could +To where it bent in the undergrowth + +Then took the other, as just as fair, +And having perhaps the better claim, +Because it was grassy and wanted wear +Though as for that the passing there +Had worn them really about the same, + +And both that morning equally lay +In leaves no step had trodden black. +Oh, I kept the first for another day! +Yet knowing how way leads on to way, +I doubted if I should ever come back. + +I shall be telling this with a sigh +Somewhere ages and ages hence: +Two roads diverged in a wood, and I— +I took the one less traveled by, +And that has made all the difference. + +\u2601 \u2600 \u2602` + + // sign + const sig = await signer.signMessage(message) + appendConsoleLine(`signature: ${sig}`) + + const isValid = await wallet.utils.isValidMessageSignature(wallet.getAddress(), message, sig, await signer.getChainId()) + appendConsoleLine(`isValid?: ${isValid}`) + if (!isValid) throw new Error('sig invalid') + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const signMessageHex = async () => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + appendConsoleLine('signing message...') + const signer = wallet.getSigner() + + // Message in hex + const message = ethers.hexlify(ethers.toUtf8Bytes('Hello, world!')) + + // sign + const sig = await signer.signMessage(message) + appendConsoleLine(`signature: ${sig}`) + + const isValid = await wallet.utils.isValidMessageSignature(wallet.getAddress(), message, sig, await signer.getChainId()) + appendConsoleLine(`isValid?: ${isValid}`) + if (!isValid) throw new Error('sig invalid') + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const signMessageBytes = async () => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + appendConsoleLine('signing message...') + const signer = wallet.getSigner() + + // Message in hex + const message = ethers.toUtf8Bytes('Hello, world!') + + // sign + const sig = await signer.signMessage(message) + appendConsoleLine(`signature: ${sig}`) + + const isValid = await wallet.utils.isValidMessageSignature(wallet.getAddress(), message, sig, await signer.getChainId()) + appendConsoleLine(`isValid?: ${isValid}`) + if (!isValid) throw new Error('sig invalid') + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const signTypedData = async () => { + try { + resetConsole() + const wallet = sequence.getWallet() + + appendConsoleLine('signing typedData...') + + const typedData: sequence.utils.TypedData = { + types: { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' } + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'cc', type: 'Person[]' }, + { name: 'contents', type: 'string' }, + { name: 'attachements', type: 'string[]' } + ] + }, + primaryType: 'Mail', + domain: { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC' + }, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826' + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB' + }, + cc: [ + { name: 'Dev Team', wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB' }, + { name: 'Accounting', wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB' } + ], + contents: 'Hello, Bob!', + attachements: ['cat.png', 'dog.png'] + } + } + + const signer = wallet.getSigner() + + const sig = await signer.signTypedData(typedData.domain, typedData.types, typedData.message) + appendConsoleLine(`signature: ${sig}`) + + // validate + const isValid = await wallet.utils.isValidTypedDataSignature(wallet.getAddress(), typedData, sig, await signer.getChainId()) + appendConsoleLine(`isValid?: ${isValid}`) + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const estimateUnwrapGas = async () => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + const wmaticContractAddress = '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270' + const wmaticInterface = new ethers.Interface(['function withdraw(uint256 amount)']) + + const tx: sequence.transactions.Transaction = { + to: wmaticContractAddress, + data: wmaticInterface.encodeFunctionData('withdraw', ['1000000000000000000']) + } + + const provider = wallet.getProvider() + const estimate = await provider.estimateGas(tx) + + appendConsoleLine(`estimated gas needed for wmatic withdrawal : ${estimate.toString()}`) + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const sendETH = async (signer?: sequence.provider.SequenceSigner) => { + try { + resetConsole() + const wallet = sequence.getWallet() + + signer = signer || wallet.getSigner() + + appendConsoleLine(`Transfer txn on ${signer.getChainId()} chainId`) + + // NOTE: on mainnet, the balance will be of ETH value + // and on matic, the balance will be of MATIC value + + // Sending the funds to the wallet itself + // so we don't lose any funds ;-) + // (of course, you can send anywhere) + const toAddress = await signer.getAddress() + + const tx1: sequence.transactions.Transaction = { + delegateCall: false, + revertOnError: false, + gasLimit: '0x55555', + to: toAddress, + value: ethers.parseEther('1.234'), + data: '0x' + } + + const tx2: sequence.transactions.Transaction = { + delegateCall: false, + revertOnError: false, + gasLimit: '0x55555', + to: toAddress, + value: ethers.parseEther('0.4242'), + data: '0x' + } + + const provider = signer.provider + + const balance1 = await provider.getBalance(toAddress) + appendConsoleLine(`balance of ${toAddress}, before: ${balance1}`) + + const txnResp = await signer.sendTransaction([tx1, tx2]) + appendConsoleLine(`txnResponse: ${JSON.stringify(txnResp)}`) + + const balance2 = await provider.getBalance(toAddress) + appendConsoleLine(`balance of ${toAddress}, after: ${balance2}`) + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const sendSepoliaUSDC = async (signer?: sequence.provider.SequenceSigner) => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + signer = signer || wallet.getSigner() // select DefaultChain signer by default + + // Sending the funds to the wallet itself + // so we don't lose any funds ;-) + // (of course, you can send anywhere) + const toAddress = await signer.getAddress() + + const amount = ethers.parseUnits('1', 1) + + // (USDC address on Sepolia) + const usdcAddress = '0x07865c6e87b9f70255377e024ace6630c1eaa37f' + + const tx: sequence.transactions.Transaction = { + delegateCall: false, + revertOnError: false, + gasLimit: '0x55555', + to: usdcAddress, + value: 0, + data: new ethers.Interface(ERC_20_ABI).encodeFunctionData('transfer', [toAddress, toHexString(amount)]) + } + + const txnResp = await signer.sendTransaction([tx], { chainId: ChainId.SEPOLIA }) + appendConsoleLine(`txnResponse: ${JSON.stringify(txnResp)}`) + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const sendDAI = async (signer?: sequence.provider.SequenceSigner) => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + signer = signer || wallet.getSigner() // select DefaultChain signer by default + + // Sending the funds to the wallet itself + // so we don't lose any funds ;-) + // (of course, you can send anywhere) + const toAddress = await signer.getAddress() + + const amount = ethers.parseUnits('0.05', 18) + const daiContractAddress = '0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063' // (DAI address on Polygon) + + const tx: sequence.transactions.Transaction = { + delegateCall: false, + revertOnError: false, + gasLimit: '0x55555', + to: daiContractAddress, + value: 0, + data: new ethers.Interface(ERC_20_ABI).encodeFunctionData('transfer', [toAddress, toHexString(amount)]) + } + + const txnResp = await signer.sendTransaction([tx]) + appendConsoleLine(`txnResponse: ${JSON.stringify(txnResp)}`) + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const sendETHSidechain = async () => { + try { + const wallet = sequence.getWallet() + + // Send either to Arbitrum or Optimism + // just pick one that is not the current chainId + const pick = wallet.getChainId() === ChainId.ARBITRUM ? ChainId.OPTIMISM : ChainId.ARBITRUM + sendETH(wallet.getSigner(pick)) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const send1155Tokens = async () => { + try { + resetConsole() + appendConsoleLine('TODO') + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const contractExample = async (signer?: sequence.provider.SequenceSigner) => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + signer = signer || wallet.getSigner() + + const abi = [ + 'function balanceOf(address owner) view returns (uint256)', + 'function decimals() view returns (uint8)', + 'function symbol() view returns (string)', + 'function transfer(address to, uint amount) returns (bool)', + 'event Transfer(address indexed from, address indexed to, uint amount)' + ] + + // USD Coin (PoS) on Polygon + const address = '0x2791bca1f2de4661ed88a30c99a7a9449aa84174' + + const usdc = new ethers.Contract(address, abi) + + const usdSymbol = await usdc.symbol() + appendConsoleLine(`Token symbol: ${usdSymbol}`) + + const balance = await usdc.balanceOf(await signer.getAddress()) + appendConsoleLine(`Token Balance: ${balance.toString()}`) + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const fetchTokenBalances = async () => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + const signer = wallet.getSigner() + const accountAddress = await signer.getAddress() + const networks = await wallet.getNetworks() + const network = networks.find(network => network.chainId === ChainId.POLYGON) + + if (!network) { + throw new Error(`Could not find Polygon network in networks list`) + } + + const indexer = new sequence.indexer.SequenceIndexer(network.indexerUrl) + + const tokenBalances = await indexer.getTokenBalances({ + accountAddress: accountAddress, + includeMetadata: true + }) + + appendConsoleLine(`tokens in your account: ${JSON.stringify(tokenBalances)}`) + + // NOTE: you can put any NFT/collectible address in the `contractAddress` field and it will return all of the balances + metadata. + // We use the Skyweaver production contract address here for demo purposes, but try another one :) + const skyweaverCollectibles = await indexer.getTokenBalances({ + accountAddress: accountAddress, + includeMetadata: true, + contractAddress: '0x631998e91476DA5B870D741192fc5Cbc55F5a52E' + }) + appendConsoleLine(`skyweaver collectibles in your account: ${JSON.stringify(skyweaverCollectibles)}`) + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const updateImplementation = async (signer?: sequence.provider.SequenceSigner) => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + signer = signer || wallet.getSigner() // select DefaultChain signer by default + + const transaction: sequence.transactions.Transaction = { + to: wallet.getAddress(), + data: new ethers.Interface(walletContracts.mainModule.abi).encodeFunctionData('updateImplementation', [ + ethers.ZeroAddress + ]) + } + + const response = await signer.sendTransaction(transaction) + appendConsoleLine(`response: ${JSON.stringify(response)}`) + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const updateImageHash = async (signer?: sequence.provider.SequenceSigner) => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + signer = signer || wallet.getSigner() // select DefaultChain signer by default + + const transaction: sequence.transactions.Transaction = { + to: wallet.getAddress(), + data: new ethers.Interface(walletContracts.mainModuleUpgradable.abi).encodeFunctionData('updateImageHash', [ + ethers.ZeroHash + ]) + } + + const response = await signer.sendTransaction(transaction) + appendConsoleLine(`response: ${JSON.stringify(response)}`) + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const delegateCall = async (signer?: sequence.provider.SequenceSigner) => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + signer = signer || wallet.getSigner() // select DefaultChain signer by default + + const transaction: sequence.transactions.Transaction = { + to: wallet.getAddress(), + delegateCall: true + } + + const response = await signer.sendTransaction(transaction) + appendConsoleLine(`response: ${JSON.stringify(response)}`) + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const addHook = async (signer?: sequence.provider.SequenceSigner) => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + signer = signer || wallet.getSigner() // select DefaultChain signer by default + + const transaction: sequence.transactions.Transaction = { + to: wallet.getAddress(), + data: new ethers.Interface(['function addHook(bytes4 _signature, address _implementation)']).encodeFunctionData( + 'addHook', + ['0x01234567', ethers.ZeroAddress] + ) + } + + const response = await signer.sendTransaction(transaction) + appendConsoleLine(`response: ${JSON.stringify(response)}`) + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const setExtraImageHash = async (signer?: sequence.provider.SequenceSigner) => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + signer = signer || wallet.getSigner() // select DefaultChain signer by default + + const transaction: sequence.transactions.Transaction = { + to: wallet.getAddress(), + data: new ethers.Interface(['function setExtraImageHash(bytes32 _imageHash, uint256 _expiration)']).encodeFunctionData( + 'setExtraImageHash', + [ethers.ZeroHash, ethers.MaxUint256] + ) + } + + const response = await signer.sendTransaction(transaction) + appendConsoleLine(`response: ${JSON.stringify(response)}`) + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const appendConsoleLine = (message: string, clear = false) => { + console.log(message) + + if (clear) { + return setConsoleMsg(message) + } + + return setConsoleMsg(prevState => { + return `${prevState}\n\n${message}` + }) + } + + const resetConsole = () => { + setConsoleLoading(true) + } + + const consoleWelcomeMessage = () => { + setConsoleLoading(false) + + if (isWalletConnected) { + setConsoleMsg('Status: Wallet is connected :)') + } else { + setConsoleMsg('Status: Wallet not connected. Please connect wallet first.') + } + } + + const consoleErrorMessage = () => { + setConsoleLoading(false) + setConsoleMsg('An error occurred') + } + + // networks list, filtered and sorted + const omitNetworks = [ + ChainId.RINKEBY, + ChainId.HARDHAT, + ChainId.HARDHAT_2, + ChainId.KOVAN, + ChainId.ROPSTEN, + ChainId.HOMEVERSE_TESTNET, + ChainId.BASE_GOERLI + ] + + const mainnets = Object.values(sequence.network.networks) + .filter(network => network.type === NetworkType.MAINNET) + .sort((a, b) => a.chainId - b.chainId) + const testnets = Object.values(sequence.network.networks) + .filter(network => network.type === NetworkType.TESTNET) + .sort((a, b) => a.chainId - b.chainId) + const networks = [...mainnets, ...testnets].filter(network => !network.deprecated && !omitNetworks.includes(network.chainId)) + + useEffect(() => { + if (email && !isOpen) { + console.log(email) + connect({ + app: 'Demo Dapp', + authorize: true, + settings: { + // Specify signInWithEmail with an email address to allow user automatically sign in with the email option. + signInWithEmail: email, + theme: 'dark', + bannerUrl: `${window.location.origin}${skyweaverBannerUrl}` + } + }) + setEmail(null) + } + }, [email, isOpen]) + + const sanitizeEmail = (email: string) => { + // Trim unnecessary spaces + email = email.trim() + + // Check if the email matches the pattern of a typical email + const emailRegex = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/ + if (emailRegex.test(email)) { + return true + } + + return false + } + + return ( + + + + logo + + + + + + Demo Dapp + + + + + + A dapp example on how to use the Sequence Wallet. This covers how to connect, sign messages and send transctions. + + + + + + + Please open your browser dev inspector to view output of functions below. + + + + + + {!isCustom && ( + + wallet.setDefaultChainId(Number(value))} + value={String(showChainId)} + options={[ + ...Object.values(networks).map(network => ({ + label: ( + + + {network.title!} + + ), + value: String(network.chainId) + })) + ]} + /> + + + + + + + + + + + +` + +const entry = resolveEntry() + +module.exports = { + mode: 'none', + context: process.cwd(), + entry: entry, + output: { + library: 'lib', + libraryTarget: 'umd' + }, + watch: false, + plugins: [...resolveHtmlPlugins(entry)], + module: { + rules: [ + { + test: /\.(js|mjs|ts)$/, + include: [...resolvePackages(), resolveCwd('./tests'), ...resolveExtras], + loader: require.resolve('babel-loader'), + options: { + presets: ['@babel/preset-typescript'], + plugins: [ + [require.resolve('@babel/plugin-transform-class-properties'), { loose: true }] + ], + cacheCompression: false, + compact: false, + }, + }, + { + test: /\.(jpe?g|png|gif|svg)$/i, + use: [ + { + loader: 'url-loader', + options: { + limit: 8192000 + } + } + ] + } + ] + }, + resolve: { + modules: ['node_modules', resolveCwd('node_modules')], + extensions: ['.ts', '.js', '.png', '.jpg', '.d.ts'], + alias: {}, + fallback: { + fs: false, + stream: false, + readline: false, + assert: false + } + }, + devServer: { + clientLogLevel: 'silent', + open: false, + host: '0.0.0.0', + port: port, + historyApiFallback: true, + stats: 'errors-only', + disableHostCheck: true, + contentBase: path.resolve(process.cwd(), 'tests/browser'), + publicPath: '/', + inline: false, + hot: false + } +} diff --git a/packages/0xsequence/tests/window-transport.spec.ts b/packages/0xsequence/tests/window-transport.spec.ts new file mode 100644 index 0000000000..d56374379b --- /dev/null +++ b/packages/0xsequence/tests/window-transport.spec.ts @@ -0,0 +1,3 @@ +import { runBrowserTests } from './utils/browser-test-runner' + +runBrowserTests('window-transport', 'window-transport/dapp.test.html') diff --git a/packages/abi/CHANGELOG.md b/packages/abi/CHANGELOG.md new file mode 100644 index 0000000000..15772c27df --- /dev/null +++ b/packages/abi/CHANGELOG.md @@ -0,0 +1,2085 @@ +# @0xsequence/abi + +## 2.3.8 + +### Patch Changes + +- indexer: update clients + +## 2.3.7 + +### Patch Changes + +- Metadata updates + +## 2.3.6 + +### Patch Changes + +- New chains + +## 2.3.5 + +### Patch Changes + +- Add Frequency Testnet + +## 2.3.4 + +### Patch Changes + +- metadata: exclude deprecated methods on rpc client + +## 2.3.3 + +### Patch Changes + +- metadata: client update + +## 2.3.2 + +### Patch Changes + +- metadata: update rpc client + +## 2.3.1 + +### Patch Changes + +- indexer: update rpc client + +## 2.3.0 + +### Minor Changes + +- update metadata rpc client + +## 2.2.15 + +### Patch Changes + +- API updates + +## 2.2.14 + +### Patch Changes + +- Somnia Testnet and Monad Testnet + +## 2.2.13 + +### Patch Changes + +- Add XR1 to all networks + +## 2.2.12 + +### Patch Changes + +- Add XR1 + +## 2.2.11 + +### Patch Changes + +- Relayer updates + +## 2.2.10 + +### Patch Changes + +- Etherlink support + +## 2.2.9 + +### Patch Changes + +- Indexer gateway native token balances + +## 2.2.8 + +### Patch Changes + +- Add Moonbeam and Moonbase Alpha + +## 2.2.7 + +### Patch Changes + +- Update Builder package + +## 2.2.6 + +### Patch Changes + +- Update relayer package + +## 2.2.5 + +### Patch Changes + +- auth: fix sequence indexer gateway url +- account: immutable wallet proxy hook + +## 2.2.4 + +### Patch Changes + +- network: update soneium mainnet block explorer url +- waas: signTypedData intent support + +## 2.2.3 + +### Patch Changes + +- provider: updating initWallet to use connected network configs if they exist + +## 2.2.2 + +### Patch Changes + +- pass projectAccessKey to relayer at all times + +## 2.2.1 + +### Patch Changes + +- waas-ethers: sign typed data + +## 2.2.0 + +### Minor Changes + +- indexer: gateway client +- @0xsequence/builder +- upgrade puppeteer to v23.10.3 + +## 2.1.8 + +### Patch Changes + +- Add Soneium Mainnet + +## 2.1.7 + +### Patch Changes + +- guard: pass project access key to guard requests + +## 2.1.6 + +### Patch Changes + +- Add LAOS and Telos Testnet chains + +## 2.1.5 + +### Patch Changes + +- account: save presigned configuration with reference chain id 1 + +## 2.1.4 + +### Patch Changes + +- provider: pass projectAccessKey into MuxMessageProvider + +## 2.1.3 + +### Patch Changes + +- waas: time drift date fix due to strange browser quirk + +## 2.1.2 + +### Patch Changes + +- provider: export analytics correctly + +## 2.1.1 + +### Patch Changes + +- Add LAOS chain support + +## 2.1.0 + +### Minor Changes + +- account: forward project access key when estimating fees and sending transactions + +### Patch Changes + +- sessions: save signatures with reference chain id + +## 2.0.26 + +### Patch Changes + +- account: fix chain id comparison + +## 2.0.25 + +### Patch Changes + +- skale-nebula: deploy gas limit = 10m + +## 2.0.24 + +### Patch Changes + +- sessions: arweave: configurable gateway url +- waas: use /status to get time drift before sending any intents + +## 2.0.23 + +### Patch Changes + +- Add The Root Network support + +## 2.0.22 + +### Patch Changes + +- Add SKALE Nebula Mainnet support + +## 2.0.21 + +### Patch Changes + +- account: add publishWitnessFor + +## 2.0.20 + +### Patch Changes + +- upgrade deps, and improve waas session status handling + +## 2.0.19 + +### Patch Changes + +- Add Immutable zkEVM support + +## 2.0.18 + +### Patch Changes + +- waas: new contractCall transaction type +- sessions: add arweave owner + +## 2.0.17 + +### Patch Changes + +- update waas auth to clear session before signIn + +## 2.0.16 + +### Patch Changes + +- Removed Astar chains + +## 2.0.15 + +### Patch Changes + +- indexer: update bindings with token balance additions + +## 2.0.14 + +### Patch Changes + +- sessions: arweave config reader +- network: add b3 and apechain mainnet configs + +## 2.0.13 + +### Patch Changes + +- network: toy-testnet + +## 2.0.12 + +### Patch Changes + +- api: update bindings + +## 2.0.11 + +### Patch Changes + +- waas: intents test fix +- api: update bindings + +## 2.0.10 + +### Patch Changes + +- network: soneium minato testnet + +## 2.0.9 + +### Patch Changes + +- network: fix SKALE network name + +## 2.0.8 + +### Patch Changes + +- metadata: update bindings + +## 2.0.7 + +### Patch Changes + +- wallet request handler fix + +## 2.0.6 + +### Patch Changes + +- network: matic -> pol + +## 2.0.5 + +### Patch Changes + +- provider: update databeat to 0.9.2 + +## 2.0.4 + +### Patch Changes + +- network: add skale-nebula-testnet + +## 2.0.3 + +### Patch Changes + +- waas: check session status in SequenceWaaS.isSignedIn() + +## 2.0.2 + +### Patch Changes + +- sessions: property convert serialized bignumber hex value to bigint + +## 2.0.1 + +### Patch Changes + +- waas: http signature check for authenticator requests +- provider: unwrap legacy json rpc responses +- use json replacer and reviver for bigints + +## 2.0.0 + +### Major Changes + +- ethers v6 + +## 1.10.15 + +### Patch Changes + +- utils: extractProjectIdFromAccessKey + +## 1.10.14 + +### Patch Changes + +- network: add borne-testnet to allNetworks + +## 1.10.13 + +### Patch Changes + +- network: add borne testnet + +## 1.10.12 + +### Patch Changes + +- api: update bindings +- global/window -> globalThis + +## 1.10.11 + +### Patch Changes + +- waas: updated intent.gen without webrpc types, errors exported from authenticator.gen + +## 1.10.10 + +### Patch Changes + +- metadata: update bindings with new contract collections api + +## 1.10.9 + +### Patch Changes + +- waas minor update + +## 1.10.8 + +### Patch Changes + +- update metadata bindings + +## 1.10.7 + +### Patch Changes + +- minor fixes to waas client + +## 1.10.6 + +### Patch Changes + +- metadata: update bindings + +## 1.10.5 + +### Patch Changes + +- network: ape-chain-testnet -> apechain-testnet + +## 1.10.4 + +### Patch Changes + +- network: add b3-sepolia, ape-chain-testnet, blast, blast-sepolia + +## 1.10.3 + +### Patch Changes + +- typing fix + +## 1.10.2 + +### Patch Changes + +- - waas: add getIdToken method + - indexer: update api client + +## 1.10.1 + +### Patch Changes + +- metadata: update bindings + +## 1.10.0 + +### Minor Changes + +- waas release v1.3.0 + +## 1.9.37 + +### Patch Changes + +- network: adds nativeToken data to NetworkMetadata constants + +## 1.9.36 + +### Patch Changes + +- guard: export client + +## 1.9.35 + +### Patch Changes + +- guard: update bindings + +## 1.9.34 + +### Patch Changes + +- waas: always use lowercase email + +## 1.9.33 + +### Patch Changes + +- waas: umd build + +## 1.9.32 + +### Patch Changes + +- indexer: update bindings + +## 1.9.31 + +### Patch Changes + +- metadata: token directory changes + +## 1.9.30 + +### Patch Changes + +- update + +## 1.9.29 + +### Patch Changes + +- disable gnosis chain + +## 1.9.28 + +### Patch Changes + +- add utils/merkletree + +## 1.9.27 + +### Patch Changes + +- network: optimistic -> optimism +- waas: remove defaults +- api, sessions: update bindings + +## 1.9.26 + +### Patch Changes + +- - add backend interfaces for pluggable interfaces + - introduce @0xsequence/react-native + - update pnpm to lockfile v9 + +## 1.9.25 + +### Patch Changes + +- update webrpc clients with new error types + +## 1.9.24 + +### Patch Changes + +- waas: add memoryStore backend to localStore + +## 1.9.23 + +### Patch Changes + +- update api client bindings + +## 1.9.22 + +### Patch Changes + +- update metadata client bindings + +## 1.9.21 + +### Patch Changes + +- api client bindings + +## 1.9.20 + +### Patch Changes + +- api client bindings update + +## 1.9.19 + +### Patch Changes + +- waas update + +## 1.9.18 + +### Patch Changes + +- provider: prohibit dangerous functions + +## 1.9.17 + +### Patch Changes + +- network: add xr-sepolia + +## 1.9.16 + +### Patch Changes + +- waas: sequence.feeOptions + +## 1.9.15 + +### Patch Changes + +- metadata: collection external_link field name fix + +## 1.9.14 + +### Patch Changes + +- network: astar-zkatana -> astar-zkyoto +- network: deprecate polygon mumbai network +- network: add xai and polygon amoy + +## 1.9.13 + +### Patch Changes + +- waas: fix @0xsequence/network dependency + +## 1.9.12 + +### Patch Changes + +- indexer: update rpc bindings +- provider: signMessage: Serialize the BytesLike or string message into hexstring before sending +- waas: SessionAuthProof + +## 1.9.11 + +### Patch Changes + +- metdata, update rpc bindings + +## 1.9.10 + +### Patch Changes + +- update metadata rpc bindings + +## 1.9.9 + +### Patch Changes + +- metadata, add SequenceCollections rpc client + +## 1.9.8 + +### Patch Changes + +- waas client update + +## 1.9.7 + +### Patch Changes + +- update rpc client bindings for api, metadata and relayer + +## 1.9.6 + +### Patch Changes + +- waas package update + +## 1.9.5 + +### Patch Changes + +- RpcRelayer prioritize project access key + +## 1.9.4 + +### Patch Changes + +- waas: fix network dependency + +## 1.9.3 + +### Patch Changes + +- provider: don't append access key to RPC url if user has already provided it + +## 1.9.2 + +### Patch Changes + +- network: add xai-sepolia + +## 1.9.1 + +### Patch Changes + +- analytics fix + +## 1.9.0 + +### Minor Changes + +- waas release + +## 1.8.8 + +### Patch Changes + +- update metadata bindings + +## 1.8.7 + +### Patch Changes + +- provider: update databeat to 0.9.1 + +## 1.8.6 + +### Patch Changes + +- guard: SignedOwnershipProof + +## 1.8.5 + +### Patch Changes + +- guard: signOwnershipProof and isSignedOwnershipProof + +## 1.8.4 + +### Patch Changes + +- network: add homeverse to networks list + +## 1.8.3 + +### Patch Changes + +- api: introduce basic linked wallet support + +## 1.8.2 + +### Patch Changes + +- provider: don't initialize analytics unless explicitly requested + +## 1.8.1 + +### Patch Changes + +- update to analytics provider + +## 1.8.0 + +### Minor Changes + +- provider: project analytics + +## 1.7.2 + +### Patch Changes + +- 0xsequence: ChainId should not be exported as a type +- account, wallet: fix nonce selection + +## 1.7.1 + +### Patch Changes + +- network: add missing avalanche logoURI + +## 1.7.0 + +### Minor Changes + +- provider: projectAccessKey is now required + +### Patch Changes + +- network: add NetworkMetadata.logoURI property for all networks + +## 1.6.3 + +### Patch Changes + +- network list update + +## 1.6.2 + +### Patch Changes + +- auth: projectAccessKey option +- wallet: use 12 bytes for random space + +## 1.6.1 + +### Patch Changes + +- core: add simple config from subdigest support +- core: fix encode tree with subdigest +- account: implement buildOnChainSignature on Account + +## 1.6.0 + +### Minor Changes + +- account, wallet: parallel transactions by default + +### Patch Changes + +- provider: emit disconnect on sign out + +## 1.5.0 + +### Minor Changes + +- signhub: add 'signing' signer status + +### Patch Changes + +- auth: Session.open: onAccountAddress callback +- account: allow empty transaction bundles + +## 1.4.9 + +### Patch Changes + +- rename SequenceMetadataClient to SequenceMetadata + +## 1.4.8 + +### Patch Changes + +- account: Account.getSigners + +## 1.4.7 + +### Patch Changes + +- update indexer client bindings + +## 1.4.6 + +### Patch Changes + +- - add sepolia networks, mark goerli as deprecated + - update indexer client bindings + +## 1.4.5 + +### Patch Changes + +- indexer/metadata: update client bindings +- auth: selectWallet with new address + +## 1.4.4 + +### Patch Changes + +- indexer: update bindings +- auth: handle jwt expiry + +## 1.4.3 + +### Patch Changes + +- guard: return active status from GuardSigner.getAuthMethods + +## 1.4.2 + +### Patch Changes + +- guard: update bindings + +## 1.4.1 + +### Patch Changes + +- network: remove unused networks +- signhub: orchestrator interface +- guard: auth methods interface +- guard: update bindings for pin and totp +- guard: no more retry logic + +## 1.4.0 + +### Minor Changes + +- project access key support + +## 1.3.0 + +### Minor Changes + +- signhub: account children + +### Patch Changes + +- guard: do not throw when building deploy transaction +- network: snowtrace.io -> subnets.avax.network/c-chain + +## 1.2.9 + +### Patch Changes + +- account: AccountSigner.sendTransaction simulateForFeeOptions +- relayer: update bindings + +## 1.2.8 + +### Patch Changes + +- rename X-Sequence-Token-Key header to X-Access-Key + +## 1.2.7 + +### Patch Changes + +- add x-sequence-token-key to clients + +## 1.2.6 + +### Patch Changes + +- Fix bind multicall provider + +## 1.2.5 + +### Patch Changes + +- Multicall default configuration fixes + +## 1.2.4 + +### Patch Changes + +- provider: Adding missing payment provider types to PaymentProviderOption +- provider: WalletRequestHandler.notifyChainChanged + +## 1.2.3 + +### Patch Changes + +- auth, provider: connect to accept optional authorizeNonce + +## 1.2.2 + +### Patch Changes + +- provider: allow createContract calls +- core: check for explicit zero address in contract deployments + +## 1.2.1 + +### Patch Changes + +- auth: use sequence api chain id as reference chain id if available + +## 1.2.0 + +### Minor Changes + +- split services from session, better local support + +## 1.1.15 + +### Patch Changes + +- guard: remove error filtering + +## 1.1.14 + +### Patch Changes + +- guard: add GuardSigner.onError + +## 1.1.13 + +### Patch Changes + +- provider: pass client version with connect options +- provider: removing large from BannerSize + +## 1.1.12 + +### Patch Changes + +- provider: adding bannerSize to ConnectOptions + +## 1.1.11 + +### Patch Changes + +- add homeverse configs + +## 1.1.10 + +### Patch Changes + +- handle default EIP6492 on send + +## 1.1.9 + +### Patch Changes + +- Custom default EIP6492 on client + +## 1.1.8 + +### Patch Changes + +- metadata: searchMetadata: add types filter + +## 1.1.7 + +### Patch Changes + +- adding signInWith connect settings option to allow dapps to automatically login their users with a certain provider optimizing the normal authentication flow + +## 1.1.6 + +### Patch Changes + +- metadata: searchMetadata: add chainID and excludeTokenMetadata filters + +## 1.1.5 + +### Patch Changes + +- account: re-compute meta-transaction id for wallet deployment transactions + +## 1.1.4 + +### Patch Changes + +- network: rename base-mainnet to base +- provider: override isDefaultChain with ConnectOptions.networkId if provided + +## 1.1.3 + +### Patch Changes + +- provider: use network id from transport session +- provider: sign authorization using ConnectOptions.networkId if provided + +## 1.1.2 + +### Patch Changes + +- provider: jsonrpc chain id fixes + +## 1.1.1 + +### Patch Changes + +- network: add base mainnet and sepolia +- provider: reject toxic transaction requests + +## 1.1.0 + +### Minor Changes + +- Refactor dapp facing provider + +## 1.0.5 + +### Patch Changes + +- network: export network constants +- guard: use the correct global for fetch +- network: nova-explorer.arbitrum.io -> nova.arbiscan.io + +## 1.0.4 + +### Patch Changes + +- provider: accept name or number for networkId + +## 1.0.3 + +### Patch Changes + +- Simpler isValidSignature helpers + +## 1.0.2 + +### Patch Changes + +- add extra signature validation utils methods + +## 1.0.1 + +### Patch Changes + +- add homeverse testnet + +## 1.0.0 + +### Major Changes + +- https://sequence.xyz/blog/sequence-wallet-light-state-sync-full-merkle-wallets + +## 0.43.34 + +### Patch Changes + +- auth: no jwt for indexer + +## 0.43.33 + +### Patch Changes + +- Adding onConnectOptionsChange handler to WalletRequestHandler + +## 0.43.32 + +### Patch Changes + +- add Base Goerli network + +## 0.43.31 + +### Patch Changes + +- remove AuxDataProvider, add promptSignInConnect + +## 0.43.30 + +### Patch Changes + +- add arbitrum goerli testnet + +## 0.43.29 + +### Patch Changes + +- provider: check availability of window object + +## 0.43.28 + +### Patch Changes + +- update api bindings + +## 0.43.27 + +### Patch Changes + +- Add rpc is sequence method + +## 0.43.26 + +### Patch Changes + +- add zkevm url to enum + +## 0.43.25 + +### Patch Changes + +- added polygon zkevm to mainnet networks + +## 0.43.24 + +### Patch Changes + +- name change from zkevm to polygon-zkevm + +## 0.43.23 + +### Patch Changes + +- update zkEVM name to Polygon zkEVM + +## 0.43.22 + +### Patch Changes + +- add zkevm chain + +## 0.43.21 + +### Patch Changes + +- api: update client bindings + +## 0.43.20 + +### Patch Changes + +- indexer: update bindings + +## 0.43.19 + +### Patch Changes + +- session proof update + +## 0.43.18 + +### Patch Changes + +- rpc client global check, hardening + +## 0.43.17 + +### Patch Changes + +- rpc clients, check of 'global' is defined + +## 0.43.16 + +### Patch Changes + +- ethers peerDep to v5, update rpc client global use + +## 0.43.15 + +### Patch Changes + +- - provider: expand receiver type on some util methods + +## 0.43.14 + +### Patch Changes + +- bump + +## 0.43.13 + +### Patch Changes + +- update rpc bindings + +## 0.43.12 + +### Patch Changes + +- provider: single wallet init, and add new unregisterWallet() method + +## 0.43.11 + +### Patch Changes + +- fix lockfiles +- re-add mocha type deleter + +## 0.43.10 + +### Patch Changes + +- various improvements + +## 0.43.9 + +### Patch Changes + +- update deps + +## 0.43.8 + +### Patch Changes + +- network: JsonRpcProvider with caching + +## 0.43.7 + +### Patch Changes + +- provider: fix wallet network init + +## 0.43.6 + +### Patch Changes + +- metadatata: update rpc bindings + +## 0.43.5 + +### Patch Changes + +- provider: do not set default network for connect messages +- provider: forward missing error message + +## 0.43.4 + +### Patch Changes + +- no-change version bump to fix incorrectly tagged snapshot build + +## 0.43.3 + +### Patch Changes + +- metadata: update bindings + +## 0.43.2 + +### Patch Changes + +- provider: implement connectUnchecked + +## 0.43.1 + +### Patch Changes + +- update to latest ethauth dep + +## 0.43.0 + +### Minor Changes + +- move ethers to a peer dependency + +## 0.42.10 + +### Patch Changes + +- add auxDataProvider + +## 0.42.9 + +### Patch Changes + +- provider: add eip-191 exceptions + +## 0.42.8 + +### Patch Changes + +- provider: skip setting intent origin if we're unity plugin + +## 0.42.7 + +### Patch Changes + +- Add sign in options to connection settings + +## 0.42.6 + +### Patch Changes + +- api bindings update + +## 0.42.5 + +### Patch Changes + +- relayer: don't treat missing receipt as hard failure + +## 0.42.4 + +### Patch Changes + +- provider: add custom app protocol to connect options + +## 0.42.3 + +### Patch Changes + +- update api bindings + +## 0.42.2 + +### Patch Changes + +- disable rinkeby network + +## 0.42.1 + +### Patch Changes + +- wallet: optional waitForReceipt parameter + +## 0.42.0 + +### Minor Changes + +- relayer: estimateGasLimits -> simulate +- add simulator package + +### Patch Changes + +- transactions: fix flattenAuxTransactions +- provider: only filter nullish values +- provider: re-map transaction 'gas' back to 'gasLimit' + +## 0.41.3 + +### Patch Changes + +- api bindings update + +## 0.41.2 + +### Patch Changes + +- api bindings update + +## 0.41.1 + +### Patch Changes + +- update default networks + +## 0.41.0 + +### Minor Changes + +- relayer: fix Relayer.wait() interface + + The interface for calling Relayer.wait() has changed. Instead of a single optional ill-defined timeout/delay parameter, there are three optional parameters, in order: + - timeout: the maximum time to wait for the transaction receipt + - delay: the polling interval, i.e. the time to wait between requests + - maxFails: the maximum number of hard failures to tolerate before giving up + + Please update your codebase accordingly. + +- relayer: add optional waitForReceipt parameter to Relayer.relay + + The behaviour of Relayer.relay() was not well-defined with respect to whether or not it waited for a receipt. + This change allows the caller to specify whether to wait or not, with the default behaviour being to wait. + +### Patch Changes + +- relayer: wait receipt retry logic +- fix wrapped object error +- provider: forward delegateCall and revertOnError transaction fields + +## 0.40.6 + +### Patch Changes + +- add arbitrum-nova chain + +## 0.40.5 + +### Patch Changes + +- api: update bindings + +## 0.40.4 + +### Patch Changes + +- add unreal transport + +## 0.40.3 + +### Patch Changes + +- provider: fix MessageToSign message type + +## 0.40.2 + +### Patch Changes + +- Wallet provider, loadSession method + +## 0.40.1 + +### Patch Changes + +- export sequence.initWallet and sequence.getWallet + +## 0.40.0 + +### Minor Changes + +- add sequence.initWallet(network, config) and sequence.getWallet() helper methods + +## 0.39.6 + +### Patch Changes + +- indexer: update client bindings + +## 0.39.5 + +### Patch Changes + +- provider: fix networkRpcUrl config option + +## 0.39.4 + +### Patch Changes + +- api: update client bindings + +## 0.39.3 + +### Patch Changes + +- add request method on Web3Provider + +## 0.39.2 + +### Patch Changes + +- update umd name + +## 0.39.1 + +### Patch Changes + +- add Aurora network +- add origin info for accountsChanged event to handle it per dapp + +## 0.39.0 + +### Minor Changes + +- abstract window.localStorage to interface type + +## 0.38.2 + +### Patch Changes + +- provider: add Settings.defaultPurchaseAmount + +## 0.38.1 + +### Patch Changes + +- update api and metadata rpc bindings + +## 0.38.0 + +### Minor Changes + +- api: update bindings, change TokenPrice interface +- bridge: remove @0xsequence/bridge package +- api: update bindings, rename ContractCallArg to TupleComponent + +## 0.37.1 + +### Patch Changes + +- Add back sortNetworks - Removing sorting was a breaking change for dapps on older versions which directly integrate sequence. + +## 0.37.0 + +### Minor Changes + +- network related fixes and improvements +- api: bindings: exchange rate lookups + +## 0.36.13 + +### Patch Changes + +- api: update bindings with new price endpoints + +## 0.36.12 + +### Patch Changes + +- wallet: skip remote signers if not needed +- auth: check that signature meets threshold before requesting auth token + +## 0.36.11 + +### Patch Changes + +- Prefix EIP191 message on wallet-request-handler + +## 0.36.10 + +### Patch Changes + +- support bannerUrl on connect + +## 0.36.9 + +### Patch Changes + +- minor dev xp improvements + +## 0.36.8 + +### Patch Changes + +- more connect options (theme, payment providers, funding currencies) + +## 0.36.7 + +### Patch Changes + +- fix missing break + +## 0.36.6 + +### Patch Changes + +- wallet_switchEthereumChain support + +## 0.36.5 + +### Patch Changes + +- auth: bump ethauth to 0.7.0 + network, wallet: don't assume position of auth network in list + api/indexer/metadata: trim trailing slash on hostname, and add endpoint urls + relayer: Allow to specify local relayer transaction parameters like gas price or gas limit + +## 0.36.4 + +### Patch Changes + +- Updating list of chain ids to include other ethereum compatible chains + +## 0.36.3 + +### Patch Changes + +- provider: pass connect options to prompter methods + +## 0.36.2 + +### Patch Changes + +- transactions: Setting target to 0x0 when empty to during SequenceTxAbiEncode + +## 0.36.1 + +### Patch Changes + +- metadata: update client with more fields + +## 0.36.0 + +### Minor Changes + +- relayer, wallet: fee quote support + +## 0.35.12 + +### Patch Changes + +- provider: rename wallet.commands to wallet.utils + +## 0.35.11 + +### Patch Changes + +- provider/utils: smoother message validation + +## 0.35.10 + +### Patch Changes + +- upgrade deps + +## 0.35.9 + +### Patch Changes + +- provider: window-transport override event handlers with new wallet instance + +## 0.35.8 + +### Patch Changes + +- provider: async wallet sign in improvements + +## 0.35.7 + +### Patch Changes + +- config: cache wallet configs + +## 0.35.6 + +### Patch Changes + +- provider: support async signin of wallet request handler + +## 0.35.5 + +### Patch Changes + +- wallet: skip threshold check during fee estimation + +## 0.35.4 + +### Patch Changes + +- - browser extension mode, center window + +## 0.35.3 + +### Patch Changes + +- - update window position when in browser extension mode + +## 0.35.2 + +### Patch Changes + +- - provider: WindowMessageHandler accept optional windowHref + +## 0.35.1 + +### Patch Changes + +- wallet: update config on undeployed too + +## 0.35.0 + +### Minor Changes + +- - config: add buildStubSignature + - provider: add checks to signing cases for wallet deployment and config statuses + - provider: add prompt for wallet deployment + - relayer: add BaseRelayer.prependWalletDeploy + - relayer: add Relayer.feeOptions + - relayer: account for wallet deployment in fee estimation + - transactions: add fromTransactionish + - wallet: add Account.prependConfigUpdate + - wallet: add Account.getFeeOptions + +## 0.34.0 + +### Minor Changes + +- - upgrade deps + +## 0.31.0 + +### Minor Changes + +- - upgrading to ethers v5.5 + +## 0.30.0 + +### Minor Changes + +- - upgrade most deps + +## 0.29.8 + +### Patch Changes + +- update api + +## 0.29.0 + +### Minor Changes + +- major architectural changes in Sequence design + - only one API instance, API is no longer a per-chain service + - separate per-chain indexer service, API no longer handles indexing + - single contract metadata service, API no longer serves metadata + + chaind package has been removed, indexer and metadata packages have been added + + stronger typing with new explicit ChainId type + + multicall fixes and improvements + + forbid "wait" transactions in sendTransactionBatch calls + +## 0.28.0 + +### Minor Changes + +- extension provider + +## 0.27.0 + +### Minor Changes + +- Add requireFreshSigner lib to sessions + +## 0.25.1 + +### Patch Changes + +- Fix build typescrypt issue + +## 0.25.0 + +### Minor Changes + +- 10c8af8: Add estimator package + Fix multicall few calls bug + +## 0.23.0 + +### Minor Changes + +- - relayer: offer variety of gas fee options from the relayer service" + +## 0.22.2 + +### Patch Changes + +- e1c109e: Fix authProof on expired sessions + +## 0.22.1 + +### Patch Changes + +- transport session cache + +## 0.22.0 + +### Minor Changes + +- e667b65: Expose all relayer options on networks + +## 0.21.5 + +### Patch Changes + +- Give priority to metaTxnId returned by relayer + +## 0.21.4 + +### Patch Changes + +- Add has enough signers method + +## 0.21.3 + +### Patch Changes + +- add window session cache + +## 0.21.2 + +### Patch Changes + +- exception handlind in relayer + +## 0.21.0 + +### Minor Changes + +- - fix gas estimation on wallets with large number of signers + - update to session handling and wallet config construction upon auth + +## 0.19.3 + +### Patch Changes + +- jwtAuth visibility, package version sync + +## 0.19.2 + +### Patch Changes + +- - api: change jwtAuth visibility + +## 0.19.0 + +### Minor Changes + +- - provider, improve dapp / wallet transport io + +## 0.18.0 + +### Minor Changes + +- relayer improvements and pending transaction handling + +## 0.16.0 + +### Minor Changes + +- relayer as its own service separate from chaind + +## 0.15.1 + +### Patch Changes + +- update api clients + +## 0.14.3 + +### Patch Changes + +- Fix 0xSequence relayer dependencies + +## 0.14.2 + +### Patch Changes + +- Add debug logs to rpc-relayer + +## 0.14.0 + +### Minor Changes + +- update sequence utils finder which includes optimization + +## 0.13.0 + +### Minor Changes + +- Update SequenceUtils deployed contract + +## 0.12.1 + +### Patch Changes + +- npm bump + +## 0.12.0 + +### Minor Changes + +- provider: improvements to window transport + +## 0.11.4 + +### Patch Changes + +- update api client + +## 0.11.3 + +### Patch Changes + +- improve openWindow state options handling + +## 0.11.2 + +### Patch Changes + +- Fix multicall proxy scopes + +## 0.11.1 + +### Patch Changes + +- Add support for dynamic and nested signatures + +## 0.11.0 + +### Minor Changes + +- Update wallet context to 1.7 contracts + +## 0.10.9 + +### Patch Changes + +- add support for public addresses as signers in session.open + +## 0.10.8 + +### Patch Changes + +- Multicall production configuration + +## 0.10.7 + +### Patch Changes + +- allow provider transport to force disconnect + +## 0.10.6 + +### Patch Changes + +- - fix getWalletState method + +## 0.10.5 + +### Patch Changes + +- update relayer gas refund options + +## 0.10.4 + +### Patch Changes + +- Update api proto + +## 0.10.3 + +### Patch Changes + +- Fix loading config cross-chain + +## 0.10.2 + +### Patch Changes + +- - message digest fix + +## 0.10.1 + +### Patch Changes + +- upgrade deps + +## 0.10.0 + +### Minor Changes + +- Deployed new contracts with ERC1271 signer support + +## 0.9.6 + +### Patch Changes + +- Update ABIs for latest sequence contracts + +## 0.9.3 + +### Patch Changes + +- - minor improvements + +## 0.9.1 + +### Patch Changes + +- - patch bump + +## 0.9.0 + +### Minor Changes + +- - provider transport hardening + +## 0.8.5 + +### Patch Changes + +- - use latest wallet-contracts + +## 0.8.4 + +### Patch Changes + +- - minor improvements, name updates and comments + +## 0.8.3 + +### Patch Changes + +- - refinements + + - normalize signer address in config + + - provider: getWalletState() method to WalletProvider + +## 0.8.2 + +### Patch Changes + +- - field rename and ethauth dependency bump + +## 0.8.1 + +### Patch Changes + +- - variety of optimizations + +## 0.8.0 + +### Minor Changes + +- - changeset fix + +## 0.7.0 + +### Patch Changes + +- 6f11ed7: sequence.js, init release diff --git a/packages/abi/README.md b/packages/abi/README.md new file mode 100644 index 0000000000..e0bbc2309a --- /dev/null +++ b/packages/abi/README.md @@ -0,0 +1,4 @@ +@0xsequence/abi +=============== + +See [0xsequence project page](https://github.com/0xsequence/sequence.js). diff --git a/packages/abi/package.json b/packages/abi/package.json new file mode 100644 index 0000000000..c0305eccc1 --- /dev/null +++ b/packages/abi/package.json @@ -0,0 +1,22 @@ +{ + "name": "@0xsequence/abi", + "version": "2.0.0", + "description": "abi sub-package for Sequence", + "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/abi", + "source": "src/index.ts", + "main": "dist/0xsequence-abi.cjs.js", + "module": "dist/0xsequence-abi.esm.js", + "author": "Horizon Blockchain Games", + "license": "Apache-2.0", + "scripts": { + "test": "echo", + "typecheck": "tsc --noEmit" + }, + "dependencies": {}, + "peerDependencies": {}, + "devDependencies": {}, + "files": [ + "src", + "dist" + ] +} diff --git a/packages/abi/src/index.ts b/packages/abi/src/index.ts new file mode 100644 index 0000000000..6537ee23d2 --- /dev/null +++ b/packages/abi/src/index.ts @@ -0,0 +1 @@ +export { walletContracts } from './wallet' diff --git a/packages/abi/src/tokens/erc1155.ts b/packages/abi/src/tokens/erc1155.ts new file mode 100644 index 0000000000..1e20ce4050 --- /dev/null +++ b/packages/abi/src/tokens/erc1155.ts @@ -0,0 +1,3 @@ +export const abi = [] + +export const returns = {} diff --git a/packages/abi/src/tokens/erc20.ts b/packages/abi/src/tokens/erc20.ts new file mode 100644 index 0000000000..1e20ce4050 --- /dev/null +++ b/packages/abi/src/tokens/erc20.ts @@ -0,0 +1,3 @@ +export const abi = [] + +export const returns = {} diff --git a/packages/abi/src/tokens/erc721.ts b/packages/abi/src/tokens/erc721.ts new file mode 100644 index 0000000000..1e20ce4050 --- /dev/null +++ b/packages/abi/src/tokens/erc721.ts @@ -0,0 +1,3 @@ +export const abi = [] + +export const returns = {} diff --git a/packages/abi/src/wallet/erc1271.ts b/packages/abi/src/wallet/erc1271.ts new file mode 100644 index 0000000000..14e0576117 --- /dev/null +++ b/packages/abi/src/wallet/erc1271.ts @@ -0,0 +1,26 @@ +export const abi = [ + { + type: 'function', + name: 'isValidSignature', + constant: true, + inputs: [ + { + type: 'bytes32' + }, + { + type: 'bytes' + } + ], + outputs: [ + { + type: 'bytes4' + } + ], + payable: false, + stateMutability: 'view' + } +] + +export const returns = { + isValidSignatureBytes32: '0x1626ba7e' +} diff --git a/packages/abi/src/wallet/erc5719.ts b/packages/abi/src/wallet/erc5719.ts new file mode 100644 index 0000000000..2f9b43b6ab --- /dev/null +++ b/packages/abi/src/wallet/erc5719.ts @@ -0,0 +1,19 @@ +export const abi = [ + { + inputs: [ + { + internalType: 'bytes32', + type: 'bytes32' + } + ], + name: 'getAlternativeSignature', + outputs: [ + { + internalType: 'string', + type: 'string' + } + ], + stateMutability: 'view', + type: 'function' + } +] diff --git a/packages/abi/src/wallet/erc6492.ts b/packages/abi/src/wallet/erc6492.ts new file mode 100644 index 0000000000..dcaf022a50 --- /dev/null +++ b/packages/abi/src/wallet/erc6492.ts @@ -0,0 +1,61 @@ +export const abi = [ + { inputs: [{ internalType: 'bytes', name: 'error', type: 'bytes' }], name: 'ERC1271Revert', type: 'error' }, + { inputs: [{ internalType: 'bytes', name: 'error', type: 'bytes' }], name: 'ERC6492DeployFailed', type: 'error' }, + { + inputs: [ + { internalType: 'address', name: '_signer', type: 'address' }, + { internalType: 'bytes32', name: '_hash', type: 'bytes32' }, + { internalType: 'bytes', name: '_signature', type: 'bytes' } + ], + name: 'isValidSig', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { internalType: 'address', name: '_signer', type: 'address' }, + { internalType: 'bytes32', name: '_hash', type: 'bytes32' }, + { internalType: 'bytes', name: '_signature', type: 'bytes' }, + { internalType: 'bool', name: 'allowSideEffects', type: 'bool' }, + { internalType: 'bool', name: 'deployAlreadyDeployed', type: 'bool' } + ], + name: 'isValidSigImpl', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { internalType: 'address', name: '_signer', type: 'address' }, + { internalType: 'bytes32', name: '_hash', type: 'bytes32' }, + { internalType: 'bytes', name: '_signature', type: 'bytes' } + ], + name: 'isValidSigNoThrow', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { internalType: 'address', name: '_signer', type: 'address' }, + { internalType: 'bytes32', name: '_hash', type: 'bytes32' }, + { internalType: 'bytes', name: '_signature', type: 'bytes' } + ], + name: 'isValidSigWithSideEffects', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { internalType: 'address', name: '_signer', type: 'address' }, + { internalType: 'bytes32', name: '_hash', type: 'bytes32' }, + { internalType: 'bytes', name: '_signature', type: 'bytes' } + ], + name: 'isValidSigWithSideEffectsNoThrow', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'nonpayable', + type: 'function' + } +] diff --git a/packages/abi/src/wallet/factory.ts b/packages/abi/src/wallet/factory.ts new file mode 100644 index 0000000000..df5ef5fc66 --- /dev/null +++ b/packages/abi/src/wallet/factory.ts @@ -0,0 +1,18 @@ +export const abi = [ + { + type: 'function', + name: 'deploy', + constant: false, + inputs: [ + { + type: 'address' + }, + { + type: 'bytes32' + } + ], + outputs: [], + payable: true, + stateMutability: 'payable' + } +] diff --git a/packages/abi/src/wallet/index.ts b/packages/abi/src/wallet/index.ts new file mode 100644 index 0000000000..cb9bdf867c --- /dev/null +++ b/packages/abi/src/wallet/index.ts @@ -0,0 +1,19 @@ +import * as erc5719 from './erc5719' +import * as erc1271 from './erc1271' +import * as erc6492 from './erc6492' +import * as factory from './factory' +import * as mainModule from './mainModule' +import * as mainModuleUpgradable from './mainModuleUpgradable' +import * as sequenceUtils from './sequenceUtils' +import * as requireFreshSigner from './libs/requireFreshSigners' + +export const walletContracts = { + erc6492, + erc5719, + erc1271, + factory, + mainModule, + mainModuleUpgradable, + sequenceUtils, + requireFreshSigner +} diff --git a/packages/abi/src/wallet/libs/requireFreshSigners.ts b/packages/abi/src/wallet/libs/requireFreshSigners.ts new file mode 100644 index 0000000000..ef8f78657c --- /dev/null +++ b/packages/abi/src/wallet/libs/requireFreshSigners.ts @@ -0,0 +1,15 @@ +export const abi = [ + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + } + ], + name: 'requireFreshSigner', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + } +] diff --git a/packages/abi/src/wallet/mainModule.ts b/packages/abi/src/wallet/mainModule.ts new file mode 100644 index 0000000000..e92fde8f1d --- /dev/null +++ b/packages/abi/src/wallet/mainModule.ts @@ -0,0 +1,158 @@ +export const abi = [ + { + type: 'function', + name: 'nonce', + constant: true, + inputs: [], + outputs: [ + { + type: 'uint256' + } + ], + payable: false, + stateMutability: 'view' + }, + { + type: 'function', + name: 'readNonce', + constant: true, + inputs: [ + { + type: 'uint256' + } + ], + outputs: [ + { + type: 'uint256' + } + ], + payable: false, + stateMutability: 'view' + }, + { + type: 'function', + name: 'updateImplementation', + constant: false, + inputs: [ + { + type: 'address' + } + ], + outputs: [], + payable: false, + stateMutability: 'nonpayable' + }, + { + type: 'function', + name: 'selfExecute', + constant: false, + inputs: [ + { + components: [ + { + type: 'bool', + name: 'delegateCall' + }, + { + type: 'bool', + name: 'revertOnError' + }, + { + type: 'uint256', + name: 'gasLimit' + }, + { + type: 'address', + name: 'target' + }, + { + type: 'uint256', + name: 'value' + }, + { + type: 'bytes', + name: 'data' + } + ], + type: 'tuple[]' + } + ], + outputs: [], + payable: false, + stateMutability: 'nonpayable' + }, + { + type: 'function', + name: 'execute', + constant: false, + inputs: [ + { + components: [ + { + type: 'bool', + name: 'delegateCall' + }, + { + type: 'bool', + name: 'revertOnError' + }, + { + type: 'uint256', + name: 'gasLimit' + }, + { + type: 'address', + name: 'target' + }, + { + type: 'uint256', + name: 'value' + }, + { + type: 'bytes', + name: 'data' + } + ], + type: 'tuple[]' + }, + { + type: 'uint256' + }, + { + type: 'bytes' + } + ], + outputs: [], + payable: false, + stateMutability: 'nonpayable' + }, + { + type: 'function', + name: 'createContract', + inputs: [ + { + type: 'bytes' + } + ], + payable: true, + stateMutability: 'payable' + }, + { + type: 'function', + name: 'setExtraImageHash', + constant: false, + inputs: [ + { + type: 'bytes32', + name: 'imageHash' + }, + { + type: 'uint256', + name: 'expiration' + } + ], + outputs: [], + payable: false, + stateMutability: 'nonpayable' + } +] diff --git a/packages/abi/src/wallet/mainModuleUpgradable.ts b/packages/abi/src/wallet/mainModuleUpgradable.ts new file mode 100644 index 0000000000..e49298a38f --- /dev/null +++ b/packages/abi/src/wallet/mainModuleUpgradable.ts @@ -0,0 +1,28 @@ +export const abi = [ + { + type: 'function', + name: 'updateImageHash', + constant: true, + inputs: [ + { + type: 'bytes32' + } + ], + outputs: [], + payable: false, + stateMutability: 'view' + }, + { + type: 'function', + name: 'imageHash', + constant: true, + inputs: [], + outputs: [ + { + type: 'bytes32' + } + ], + payable: false, + stateMutability: 'view' + } +] diff --git a/packages/abi/src/wallet/sequenceUtils.ts b/packages/abi/src/wallet/sequenceUtils.ts new file mode 100644 index 0000000000..7b52c69c8a --- /dev/null +++ b/packages/abi/src/wallet/sequenceUtils.ts @@ -0,0 +1,516 @@ +export const abi = [ + { + inputs: [ + { + internalType: 'address', + name: '_factory', + type: 'address' + }, + { + internalType: 'address', + name: '_mainModule', + type: 'address' + } + ], + stateMutability: 'nonpayable', + type: 'constructor' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: '_wallet', + type: 'address' + }, + { + indexed: true, + internalType: 'bytes32', + name: '_imageHash', + type: 'bytes32' + }, + { + indexed: false, + internalType: 'uint256', + name: '_threshold', + type: 'uint256' + }, + { + indexed: false, + internalType: 'bytes', + name: '_signers', + type: 'bytes' + } + ], + name: 'RequiredConfig', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: '_wallet', + type: 'address' + }, + { + indexed: true, + internalType: 'address', + name: '_signer', + type: 'address' + } + ], + name: 'RequiredSigner', + type: 'event' + }, + { + inputs: [ + { + internalType: 'address', + name: '_addr', + type: 'address' + } + ], + name: 'callBalanceOf', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'callBlockNumber', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_i', + type: 'uint256' + } + ], + name: 'callBlockhash', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'callChainId', + outputs: [ + { + internalType: 'uint256', + name: 'id', + type: 'uint256' + } + ], + stateMutability: 'pure', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '_addr', + type: 'address' + } + ], + name: 'callCode', + outputs: [ + { + internalType: 'bytes', + name: 'code', + type: 'bytes' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '_addr', + type: 'address' + } + ], + name: 'callCodeHash', + outputs: [ + { + internalType: 'bytes32', + name: 'codeHash', + type: 'bytes32' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '_addr', + type: 'address' + } + ], + name: 'callCodeSize', + outputs: [ + { + internalType: 'uint256', + name: 'size', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'callCoinbase', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'callDifficulty', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'callGasLeft', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'callGasLimit', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'callGasPrice', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'callOrigin', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'callTimestamp', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + } + ], + name: 'knownImageHashes', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + name: 'lastImageHashUpdate', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + } + ], + name: 'lastSignerUpdate', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + } + ], + name: 'lastWalletUpdate', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + components: [ + { + internalType: 'bool', + name: 'delegateCall', + type: 'bool' + }, + { + internalType: 'bool', + name: 'revertOnError', + type: 'bool' + }, + { + internalType: 'uint256', + name: 'gasLimit', + type: 'uint256' + }, + { + internalType: 'address', + name: 'target', + type: 'address' + }, + { + internalType: 'uint256', + name: 'value', + type: 'uint256' + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes' + } + ], + internalType: 'struct IModuleCalls.Transaction[]', + name: '_txs', + type: 'tuple[]' + } + ], + name: 'multiCall', + outputs: [ + { + internalType: 'bool[]', + name: '_successes', + type: 'bool[]' + }, + { + internalType: 'bytes[]', + name: '_results', + type: 'bytes[]' + } + ], + stateMutability: 'payable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '_wallet', + type: 'address' + }, + { + internalType: 'uint256', + name: '_threshold', + type: 'uint256' + }, + { + components: [ + { + internalType: 'uint256', + name: 'weight', + type: 'uint256' + }, + { + internalType: 'address', + name: 'signer', + type: 'address' + } + ], + internalType: 'struct RequireUtils.Member[]', + name: '_members', + type: 'tuple[]' + }, + { + internalType: 'bool', + name: '_index', + type: 'bool' + } + ], + name: 'publishConfig', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '_wallet', + type: 'address' + }, + { + internalType: 'bytes32', + name: '_hash', + type: 'bytes32' + }, + { + internalType: 'uint256', + name: '_sizeMembers', + type: 'uint256' + }, + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + }, + { + internalType: 'bool', + name: '_index', + type: 'bool' + } + ], + name: 'publishInitialSigners', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '_wallet', + type: 'address' + }, + { + internalType: 'uint256', + name: '_nonce', + type: 'uint256' + } + ], + name: 'requireMinNonce', + outputs: [], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_expiration', + type: 'uint256' + } + ], + name: 'requireNonExpired', + outputs: [], + stateMutability: 'view', + type: 'function' + } +] diff --git a/packages/account/CHANGELOG.md b/packages/account/CHANGELOG.md new file mode 100644 index 0000000000..c506f50538 --- /dev/null +++ b/packages/account/CHANGELOG.md @@ -0,0 +1,1770 @@ +# @0xsequence/account + +## 2.0.0 + +### Major Changes + +- changeset + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@2.0.0 + - @0xsequence/core@2.0.0 + - @0xsequence/migration@2.0.0 + - @0xsequence/network@2.0.0 + - @0xsequence/relayer@2.0.0 + - @0xsequence/sessions@2.0.0 + - @0xsequence/utils@2.0.0 + - @0xsequence/wallet@2.0.0 + +## 1.10.14 + +### Patch Changes + +- network: add borne-testnet to allNetworks +- Updated dependencies + - @0xsequence/abi@1.10.14 + - @0xsequence/core@1.10.14 + - @0xsequence/migration@1.10.14 + - @0xsequence/network@1.10.14 + - @0xsequence/relayer@1.10.14 + - @0xsequence/sessions@1.10.14 + - @0xsequence/utils@1.10.14 + - @0xsequence/wallet@1.10.14 + +## 1.10.13 + +### Patch Changes + +- network: add borne testnet +- Updated dependencies + - @0xsequence/abi@1.10.13 + - @0xsequence/core@1.10.13 + - @0xsequence/migration@1.10.13 + - @0xsequence/network@1.10.13 + - @0xsequence/relayer@1.10.13 + - @0xsequence/sessions@1.10.13 + - @0xsequence/utils@1.10.13 + - @0xsequence/wallet@1.10.13 + +## 1.10.12 + +### Patch Changes + +- api: update bindings +- global/window -> globalThis +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.10.12 + - @0xsequence/core@1.10.12 + - @0xsequence/migration@1.10.12 + - @0xsequence/network@1.10.12 + - @0xsequence/relayer@1.10.12 + - @0xsequence/sessions@1.10.12 + - @0xsequence/utils@1.10.12 + - @0xsequence/wallet@1.10.12 + +## 1.10.11 + +### Patch Changes + +- waas: updated intent.gen without webrpc types, errors exported from authenticator.gen +- Updated dependencies + - @0xsequence/abi@1.10.11 + - @0xsequence/core@1.10.11 + - @0xsequence/migration@1.10.11 + - @0xsequence/network@1.10.11 + - @0xsequence/relayer@1.10.11 + - @0xsequence/sessions@1.10.11 + - @0xsequence/utils@1.10.11 + - @0xsequence/wallet@1.10.11 + +## 1.10.10 + +### Patch Changes + +- metadata: update bindings with new contract collections api +- Updated dependencies + - @0xsequence/abi@1.10.10 + - @0xsequence/core@1.10.10 + - @0xsequence/migration@1.10.10 + - @0xsequence/network@1.10.10 + - @0xsequence/relayer@1.10.10 + - @0xsequence/sessions@1.10.10 + - @0xsequence/utils@1.10.10 + - @0xsequence/wallet@1.10.10 + +## 1.10.9 + +### Patch Changes + +- waas minor update +- Updated dependencies + - @0xsequence/abi@1.10.9 + - @0xsequence/core@1.10.9 + - @0xsequence/migration@1.10.9 + - @0xsequence/network@1.10.9 + - @0xsequence/relayer@1.10.9 + - @0xsequence/sessions@1.10.9 + - @0xsequence/utils@1.10.9 + - @0xsequence/wallet@1.10.9 + +## 1.10.8 + +### Patch Changes + +- update metadata bindings +- Updated dependencies + - @0xsequence/abi@1.10.8 + - @0xsequence/core@1.10.8 + - @0xsequence/migration@1.10.8 + - @0xsequence/network@1.10.8 + - @0xsequence/relayer@1.10.8 + - @0xsequence/sessions@1.10.8 + - @0xsequence/utils@1.10.8 + - @0xsequence/wallet@1.10.8 + +## 1.10.7 + +### Patch Changes + +- minor fixes to waas client +- Updated dependencies + - @0xsequence/abi@1.10.7 + - @0xsequence/core@1.10.7 + - @0xsequence/migration@1.10.7 + - @0xsequence/network@1.10.7 + - @0xsequence/relayer@1.10.7 + - @0xsequence/sessions@1.10.7 + - @0xsequence/utils@1.10.7 + - @0xsequence/wallet@1.10.7 + +## 1.10.6 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/abi@1.10.6 + - @0xsequence/core@1.10.6 + - @0xsequence/migration@1.10.6 + - @0xsequence/network@1.10.6 + - @0xsequence/relayer@1.10.6 + - @0xsequence/sessions@1.10.6 + - @0xsequence/utils@1.10.6 + - @0xsequence/wallet@1.10.6 + +## 1.10.5 + +### Patch Changes + +- network: ape-chain-testnet -> apechain-testnet +- Updated dependencies + - @0xsequence/abi@1.10.5 + - @0xsequence/core@1.10.5 + - @0xsequence/migration@1.10.5 + - @0xsequence/network@1.10.5 + - @0xsequence/relayer@1.10.5 + - @0xsequence/sessions@1.10.5 + - @0xsequence/utils@1.10.5 + - @0xsequence/wallet@1.10.5 + +## 1.10.4 + +### Patch Changes + +- network: add b3-sepolia, ape-chain-testnet, blast, blast-sepolia +- Updated dependencies + - @0xsequence/abi@1.10.4 + - @0xsequence/core@1.10.4 + - @0xsequence/migration@1.10.4 + - @0xsequence/network@1.10.4 + - @0xsequence/relayer@1.10.4 + - @0xsequence/sessions@1.10.4 + - @0xsequence/utils@1.10.4 + - @0xsequence/wallet@1.10.4 + +## 1.10.3 + +### Patch Changes + +- typing fix +- Updated dependencies + - @0xsequence/abi@1.10.3 + - @0xsequence/core@1.10.3 + - @0xsequence/migration@1.10.3 + - @0xsequence/network@1.10.3 + - @0xsequence/relayer@1.10.3 + - @0xsequence/sessions@1.10.3 + - @0xsequence/utils@1.10.3 + - @0xsequence/wallet@1.10.3 + +## 1.10.2 + +### Patch Changes + +- - waas: add getIdToken method + - indexer: update api client +- Updated dependencies + - @0xsequence/abi@1.10.2 + - @0xsequence/core@1.10.2 + - @0xsequence/migration@1.10.2 + - @0xsequence/network@1.10.2 + - @0xsequence/relayer@1.10.2 + - @0xsequence/sessions@1.10.2 + - @0xsequence/utils@1.10.2 + - @0xsequence/wallet@1.10.2 + +## 1.10.1 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/abi@1.10.1 + - @0xsequence/core@1.10.1 + - @0xsequence/migration@1.10.1 + - @0xsequence/network@1.10.1 + - @0xsequence/relayer@1.10.1 + - @0xsequence/sessions@1.10.1 + - @0xsequence/utils@1.10.1 + - @0xsequence/wallet@1.10.1 + +## 1.10.0 + +### Minor Changes + +- waas release v1.3.0 + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.10.0 + - @0xsequence/core@1.10.0 + - @0xsequence/migration@1.10.0 + - @0xsequence/network@1.10.0 + - @0xsequence/relayer@1.10.0 + - @0xsequence/sessions@1.10.0 + - @0xsequence/utils@1.10.0 + - @0xsequence/wallet@1.10.0 + +## 1.9.37 + +### Patch Changes + +- network: adds nativeToken data to NetworkMetadata constants +- Updated dependencies + - @0xsequence/abi@1.9.37 + - @0xsequence/core@1.9.37 + - @0xsequence/migration@1.9.37 + - @0xsequence/network@1.9.37 + - @0xsequence/relayer@1.9.37 + - @0xsequence/sessions@1.9.37 + - @0xsequence/utils@1.9.37 + - @0xsequence/wallet@1.9.37 + +## 1.9.36 + +### Patch Changes + +- guard: export client +- Updated dependencies + - @0xsequence/abi@1.9.36 + - @0xsequence/core@1.9.36 + - @0xsequence/migration@1.9.36 + - @0xsequence/network@1.9.36 + - @0xsequence/relayer@1.9.36 + - @0xsequence/sessions@1.9.36 + - @0xsequence/utils@1.9.36 + - @0xsequence/wallet@1.9.36 + +## 1.9.35 + +### Patch Changes + +- guard: update bindings +- Updated dependencies + - @0xsequence/abi@1.9.35 + - @0xsequence/core@1.9.35 + - @0xsequence/migration@1.9.35 + - @0xsequence/network@1.9.35 + - @0xsequence/relayer@1.9.35 + - @0xsequence/sessions@1.9.35 + - @0xsequence/utils@1.9.35 + - @0xsequence/wallet@1.9.35 + +## 1.9.34 + +### Patch Changes + +- waas: always use lowercase email +- Updated dependencies + - @0xsequence/abi@1.9.34 + - @0xsequence/core@1.9.34 + - @0xsequence/migration@1.9.34 + - @0xsequence/network@1.9.34 + - @0xsequence/relayer@1.9.34 + - @0xsequence/sessions@1.9.34 + - @0xsequence/utils@1.9.34 + - @0xsequence/wallet@1.9.34 + +## 1.9.33 + +### Patch Changes + +- waas: umd build +- Updated dependencies + - @0xsequence/abi@1.9.33 + - @0xsequence/core@1.9.33 + - @0xsequence/migration@1.9.33 + - @0xsequence/network@1.9.33 + - @0xsequence/relayer@1.9.33 + - @0xsequence/sessions@1.9.33 + - @0xsequence/utils@1.9.33 + - @0xsequence/wallet@1.9.33 + +## 1.9.32 + +### Patch Changes + +- indexer: update bindings +- Updated dependencies + - @0xsequence/abi@1.9.32 + - @0xsequence/core@1.9.32 + - @0xsequence/migration@1.9.32 + - @0xsequence/network@1.9.32 + - @0xsequence/relayer@1.9.32 + - @0xsequence/sessions@1.9.32 + - @0xsequence/utils@1.9.32 + - @0xsequence/wallet@1.9.32 + +## 1.9.31 + +### Patch Changes + +- metadata: token directory changes +- Updated dependencies + - @0xsequence/abi@1.9.31 + - @0xsequence/core@1.9.31 + - @0xsequence/migration@1.9.31 + - @0xsequence/network@1.9.31 + - @0xsequence/relayer@1.9.31 + - @0xsequence/sessions@1.9.31 + - @0xsequence/utils@1.9.31 + - @0xsequence/wallet@1.9.31 + +## 1.9.30 + +### Patch Changes + +- update +- Updated dependencies + - @0xsequence/abi@1.9.30 + - @0xsequence/core@1.9.30 + - @0xsequence/migration@1.9.30 + - @0xsequence/network@1.9.30 + - @0xsequence/relayer@1.9.30 + - @0xsequence/sessions@1.9.30 + - @0xsequence/utils@1.9.30 + - @0xsequence/wallet@1.9.30 + +## 1.9.29 + +### Patch Changes + +- disable gnosis chain +- Updated dependencies + - @0xsequence/abi@1.9.29 + - @0xsequence/core@1.9.29 + - @0xsequence/migration@1.9.29 + - @0xsequence/network@1.9.29 + - @0xsequence/relayer@1.9.29 + - @0xsequence/sessions@1.9.29 + - @0xsequence/utils@1.9.29 + - @0xsequence/wallet@1.9.29 + +## 1.9.28 + +### Patch Changes + +- add utils/merkletree +- Updated dependencies + - @0xsequence/abi@1.9.28 + - @0xsequence/core@1.9.28 + - @0xsequence/migration@1.9.28 + - @0xsequence/network@1.9.28 + - @0xsequence/relayer@1.9.28 + - @0xsequence/sessions@1.9.28 + - @0xsequence/utils@1.9.28 + - @0xsequence/wallet@1.9.28 + +## 1.9.27 + +### Patch Changes + +- network: optimistic -> optimism +- waas: remove defaults +- api, sessions: update bindings +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.9.27 + - @0xsequence/core@1.9.27 + - @0xsequence/migration@1.9.27 + - @0xsequence/network@1.9.27 + - @0xsequence/relayer@1.9.27 + - @0xsequence/sessions@1.9.27 + - @0xsequence/utils@1.9.27 + - @0xsequence/wallet@1.9.27 + +## 1.9.26 + +### Patch Changes + +- - add backend interfaces for pluggable interfaces + - introduce @0xsequence/react-native + - update pnpm to lockfile v9 +- Updated dependencies + - @0xsequence/abi@1.9.26 + - @0xsequence/core@1.9.26 + - @0xsequence/migration@1.9.26 + - @0xsequence/network@1.9.26 + - @0xsequence/relayer@1.9.26 + - @0xsequence/sessions@1.9.26 + - @0xsequence/utils@1.9.26 + - @0xsequence/wallet@1.9.26 + +## 1.9.25 + +### Patch Changes + +- update webrpc clients with new error types +- Updated dependencies + - @0xsequence/abi@1.9.25 + - @0xsequence/core@1.9.25 + - @0xsequence/migration@1.9.25 + - @0xsequence/network@1.9.25 + - @0xsequence/relayer@1.9.25 + - @0xsequence/sessions@1.9.25 + - @0xsequence/utils@1.9.25 + - @0xsequence/wallet@1.9.25 + +## 1.9.24 + +### Patch Changes + +- waas: add memoryStore backend to localStore +- Updated dependencies + - @0xsequence/abi@1.9.24 + - @0xsequence/core@1.9.24 + - @0xsequence/migration@1.9.24 + - @0xsequence/network@1.9.24 + - @0xsequence/relayer@1.9.24 + - @0xsequence/sessions@1.9.24 + - @0xsequence/utils@1.9.24 + - @0xsequence/wallet@1.9.24 + +## 1.9.23 + +### Patch Changes + +- update api client bindings +- Updated dependencies + - @0xsequence/abi@1.9.23 + - @0xsequence/core@1.9.23 + - @0xsequence/migration@1.9.23 + - @0xsequence/network@1.9.23 + - @0xsequence/relayer@1.9.23 + - @0xsequence/sessions@1.9.23 + - @0xsequence/utils@1.9.23 + - @0xsequence/wallet@1.9.23 + +## 1.9.22 + +### Patch Changes + +- update metadata client bindings +- Updated dependencies + - @0xsequence/abi@1.9.22 + - @0xsequence/core@1.9.22 + - @0xsequence/migration@1.9.22 + - @0xsequence/network@1.9.22 + - @0xsequence/relayer@1.9.22 + - @0xsequence/sessions@1.9.22 + - @0xsequence/utils@1.9.22 + - @0xsequence/wallet@1.9.22 + +## 1.9.21 + +### Patch Changes + +- api client bindings +- Updated dependencies + - @0xsequence/abi@1.9.21 + - @0xsequence/core@1.9.21 + - @0xsequence/migration@1.9.21 + - @0xsequence/network@1.9.21 + - @0xsequence/relayer@1.9.21 + - @0xsequence/sessions@1.9.21 + - @0xsequence/utils@1.9.21 + - @0xsequence/wallet@1.9.21 + +## 1.9.20 + +### Patch Changes + +- api client bindings update +- Updated dependencies + - @0xsequence/abi@1.9.20 + - @0xsequence/core@1.9.20 + - @0xsequence/migration@1.9.20 + - @0xsequence/network@1.9.20 + - @0xsequence/relayer@1.9.20 + - @0xsequence/sessions@1.9.20 + - @0xsequence/utils@1.9.20 + - @0xsequence/wallet@1.9.20 + +## 1.9.19 + +### Patch Changes + +- waas update +- Updated dependencies + - @0xsequence/abi@1.9.19 + - @0xsequence/core@1.9.19 + - @0xsequence/migration@1.9.19 + - @0xsequence/network@1.9.19 + - @0xsequence/relayer@1.9.19 + - @0xsequence/sessions@1.9.19 + - @0xsequence/utils@1.9.19 + - @0xsequence/wallet@1.9.19 + +## 1.9.18 + +### Patch Changes + +- provider: prohibit dangerous functions +- Updated dependencies + - @0xsequence/abi@1.9.18 + - @0xsequence/core@1.9.18 + - @0xsequence/migration@1.9.18 + - @0xsequence/network@1.9.18 + - @0xsequence/relayer@1.9.18 + - @0xsequence/sessions@1.9.18 + - @0xsequence/utils@1.9.18 + - @0xsequence/wallet@1.9.18 + +## 1.9.17 + +### Patch Changes + +- network: add xr-sepolia +- Updated dependencies + - @0xsequence/network@1.9.17 + - @0xsequence/abi@1.9.17 + - @0xsequence/core@1.9.17 + - @0xsequence/migration@1.9.17 + - @0xsequence/relayer@1.9.17 + - @0xsequence/sessions@1.9.17 + - @0xsequence/utils@1.9.17 + - @0xsequence/wallet@1.9.17 + +## 1.9.16 + +### Patch Changes + +- waas: sequence.feeOptions +- Updated dependencies + - @0xsequence/abi@1.9.16 + - @0xsequence/core@1.9.16 + - @0xsequence/migration@1.9.16 + - @0xsequence/network@1.9.16 + - @0xsequence/relayer@1.9.16 + - @0xsequence/sessions@1.9.16 + - @0xsequence/utils@1.9.16 + - @0xsequence/wallet@1.9.16 + +## 1.9.15 + +### Patch Changes + +- metadata: collection external_link field name fix +- Updated dependencies + - @0xsequence/abi@1.9.15 + - @0xsequence/core@1.9.15 + - @0xsequence/migration@1.9.15 + - @0xsequence/network@1.9.15 + - @0xsequence/relayer@1.9.15 + - @0xsequence/sessions@1.9.15 + - @0xsequence/utils@1.9.15 + - @0xsequence/wallet@1.9.15 + +## 1.9.14 + +### Patch Changes + +- network: astar-zkatana -> astar-zkyoto +- network: deprecate polygon mumbai network +- network: add xai and polygon amoy +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.9.14 + - @0xsequence/core@1.9.14 + - @0xsequence/migration@1.9.14 + - @0xsequence/network@1.9.14 + - @0xsequence/relayer@1.9.14 + - @0xsequence/sessions@1.9.14 + - @0xsequence/utils@1.9.14 + - @0xsequence/wallet@1.9.14 + +## 1.9.13 + +### Patch Changes + +- waas: fix @0xsequence/network dependency +- Updated dependencies + - @0xsequence/abi@1.9.13 + - @0xsequence/core@1.9.13 + - @0xsequence/migration@1.9.13 + - @0xsequence/network@1.9.13 + - @0xsequence/relayer@1.9.13 + - @0xsequence/sessions@1.9.13 + - @0xsequence/utils@1.9.13 + - @0xsequence/wallet@1.9.13 + +## 1.9.12 + +### Patch Changes + +- indexer: update rpc bindings +- provider: signMessage: Serialize the BytesLike or string message into hexstring before sending +- waas: SessionAuthProof +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.9.12 + - @0xsequence/core@1.9.12 + - @0xsequence/migration@1.9.12 + - @0xsequence/network@1.9.12 + - @0xsequence/relayer@1.9.12 + - @0xsequence/sessions@1.9.12 + - @0xsequence/utils@1.9.12 + - @0xsequence/wallet@1.9.12 + +## 1.9.11 + +### Patch Changes + +- metdata, update rpc bindings +- Updated dependencies + - @0xsequence/abi@1.9.11 + - @0xsequence/core@1.9.11 + - @0xsequence/migration@1.9.11 + - @0xsequence/network@1.9.11 + - @0xsequence/relayer@1.9.11 + - @0xsequence/sessions@1.9.11 + - @0xsequence/utils@1.9.11 + - @0xsequence/wallet@1.9.11 + +## 1.9.10 + +### Patch Changes + +- update metadata rpc bindings +- Updated dependencies + - @0xsequence/abi@1.9.10 + - @0xsequence/core@1.9.10 + - @0xsequence/migration@1.9.10 + - @0xsequence/network@1.9.10 + - @0xsequence/relayer@1.9.10 + - @0xsequence/sessions@1.9.10 + - @0xsequence/utils@1.9.10 + - @0xsequence/wallet@1.9.10 + +## 1.9.9 + +### Patch Changes + +- metadata, add SequenceCollections rpc client +- Updated dependencies + - @0xsequence/abi@1.9.9 + - @0xsequence/core@1.9.9 + - @0xsequence/migration@1.9.9 + - @0xsequence/network@1.9.9 + - @0xsequence/relayer@1.9.9 + - @0xsequence/sessions@1.9.9 + - @0xsequence/utils@1.9.9 + - @0xsequence/wallet@1.9.9 + +## 1.9.8 + +### Patch Changes + +- waas client update +- Updated dependencies + - @0xsequence/abi@1.9.8 + - @0xsequence/core@1.9.8 + - @0xsequence/migration@1.9.8 + - @0xsequence/network@1.9.8 + - @0xsequence/relayer@1.9.8 + - @0xsequence/sessions@1.9.8 + - @0xsequence/utils@1.9.8 + - @0xsequence/wallet@1.9.8 + +## 1.9.7 + +### Patch Changes + +- update rpc client bindings for api, metadata and relayer +- Updated dependencies + - @0xsequence/abi@1.9.7 + - @0xsequence/core@1.9.7 + - @0xsequence/migration@1.9.7 + - @0xsequence/network@1.9.7 + - @0xsequence/relayer@1.9.7 + - @0xsequence/sessions@1.9.7 + - @0xsequence/utils@1.9.7 + - @0xsequence/wallet@1.9.7 + +## 1.9.6 + +### Patch Changes + +- waas package update +- Updated dependencies + - @0xsequence/abi@1.9.6 + - @0xsequence/core@1.9.6 + - @0xsequence/migration@1.9.6 + - @0xsequence/network@1.9.6 + - @0xsequence/relayer@1.9.6 + - @0xsequence/sessions@1.9.6 + - @0xsequence/utils@1.9.6 + - @0xsequence/wallet@1.9.6 + +## 1.9.5 + +### Patch Changes + +- RpcRelayer prioritize project access key +- Updated dependencies + - @0xsequence/abi@1.9.5 + - @0xsequence/core@1.9.5 + - @0xsequence/migration@1.9.5 + - @0xsequence/network@1.9.5 + - @0xsequence/relayer@1.9.5 + - @0xsequence/sessions@1.9.5 + - @0xsequence/utils@1.9.5 + - @0xsequence/wallet@1.9.5 + +## 1.9.4 + +### Patch Changes + +- waas: fix network dependency +- Updated dependencies + - @0xsequence/abi@1.9.4 + - @0xsequence/core@1.9.4 + - @0xsequence/migration@1.9.4 + - @0xsequence/network@1.9.4 + - @0xsequence/relayer@1.9.4 + - @0xsequence/sessions@1.9.4 + - @0xsequence/utils@1.9.4 + - @0xsequence/wallet@1.9.4 + +## 1.9.3 + +### Patch Changes + +- provider: don't append access key to RPC url if user has already provided it +- Updated dependencies + - @0xsequence/abi@1.9.3 + - @0xsequence/core@1.9.3 + - @0xsequence/migration@1.9.3 + - @0xsequence/network@1.9.3 + - @0xsequence/relayer@1.9.3 + - @0xsequence/sessions@1.9.3 + - @0xsequence/utils@1.9.3 + - @0xsequence/wallet@1.9.3 + +## 1.9.2 + +### Patch Changes + +- network: add xai-sepolia +- Updated dependencies + - @0xsequence/abi@1.9.2 + - @0xsequence/core@1.9.2 + - @0xsequence/migration@1.9.2 + - @0xsequence/network@1.9.2 + - @0xsequence/relayer@1.9.2 + - @0xsequence/sessions@1.9.2 + - @0xsequence/utils@1.9.2 + - @0xsequence/wallet@1.9.2 + +## 1.9.1 + +### Patch Changes + +- analytics fix +- Updated dependencies + - @0xsequence/abi@1.9.1 + - @0xsequence/core@1.9.1 + - @0xsequence/migration@1.9.1 + - @0xsequence/network@1.9.1 + - @0xsequence/relayer@1.9.1 + - @0xsequence/sessions@1.9.1 + - @0xsequence/utils@1.9.1 + - @0xsequence/wallet@1.9.1 + +## 1.9.0 + +### Minor Changes + +- waas release + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.9.0 + - @0xsequence/core@1.9.0 + - @0xsequence/migration@1.9.0 + - @0xsequence/network@1.9.0 + - @0xsequence/relayer@1.9.0 + - @0xsequence/sessions@1.9.0 + - @0xsequence/utils@1.9.0 + - @0xsequence/wallet@1.9.0 + +## 1.8.8 + +### Patch Changes + +- update metadata bindings +- Updated dependencies + - @0xsequence/abi@1.8.8 + - @0xsequence/core@1.8.8 + - @0xsequence/migration@1.8.8 + - @0xsequence/network@1.8.8 + - @0xsequence/relayer@1.8.8 + - @0xsequence/sessions@1.8.8 + - @0xsequence/utils@1.8.8 + - @0xsequence/wallet@1.8.8 + +## 1.8.7 + +### Patch Changes + +- provider: update databeat to 0.9.1 +- Updated dependencies + - @0xsequence/abi@1.8.7 + - @0xsequence/core@1.8.7 + - @0xsequence/migration@1.8.7 + - @0xsequence/network@1.8.7 + - @0xsequence/relayer@1.8.7 + - @0xsequence/sessions@1.8.7 + - @0xsequence/utils@1.8.7 + - @0xsequence/wallet@1.8.7 + +## 1.8.6 + +### Patch Changes + +- guard: SignedOwnershipProof +- Updated dependencies + - @0xsequence/abi@1.8.6 + - @0xsequence/core@1.8.6 + - @0xsequence/migration@1.8.6 + - @0xsequence/network@1.8.6 + - @0xsequence/relayer@1.8.6 + - @0xsequence/sessions@1.8.6 + - @0xsequence/utils@1.8.6 + - @0xsequence/wallet@1.8.6 + +## 1.8.5 + +### Patch Changes + +- guard: signOwnershipProof and isSignedOwnershipProof +- Updated dependencies + - @0xsequence/abi@1.8.5 + - @0xsequence/core@1.8.5 + - @0xsequence/migration@1.8.5 + - @0xsequence/network@1.8.5 + - @0xsequence/relayer@1.8.5 + - @0xsequence/sessions@1.8.5 + - @0xsequence/utils@1.8.5 + - @0xsequence/wallet@1.8.5 + +## 1.8.4 + +### Patch Changes + +- network: add homeverse to networks list +- Updated dependencies + - @0xsequence/abi@1.8.4 + - @0xsequence/core@1.8.4 + - @0xsequence/migration@1.8.4 + - @0xsequence/network@1.8.4 + - @0xsequence/relayer@1.8.4 + - @0xsequence/sessions@1.8.4 + - @0xsequence/utils@1.8.4 + - @0xsequence/wallet@1.8.4 + +## 1.8.3 + +### Patch Changes + +- api: introduce basic linked wallet support +- Updated dependencies + - @0xsequence/abi@1.8.3 + - @0xsequence/core@1.8.3 + - @0xsequence/migration@1.8.3 + - @0xsequence/network@1.8.3 + - @0xsequence/relayer@1.8.3 + - @0xsequence/sessions@1.8.3 + - @0xsequence/utils@1.8.3 + - @0xsequence/wallet@1.8.3 + +## 1.8.2 + +### Patch Changes + +- provider: don't initialize analytics unless explicitly requested +- Updated dependencies + - @0xsequence/abi@1.8.2 + - @0xsequence/core@1.8.2 + - @0xsequence/migration@1.8.2 + - @0xsequence/network@1.8.2 + - @0xsequence/relayer@1.8.2 + - @0xsequence/sessions@1.8.2 + - @0xsequence/utils@1.8.2 + - @0xsequence/wallet@1.8.2 + +## 1.8.1 + +### Patch Changes + +- update to analytics provider +- Updated dependencies + - @0xsequence/abi@1.8.1 + - @0xsequence/core@1.8.1 + - @0xsequence/migration@1.8.1 + - @0xsequence/network@1.8.1 + - @0xsequence/relayer@1.8.1 + - @0xsequence/sessions@1.8.1 + - @0xsequence/utils@1.8.1 + - @0xsequence/wallet@1.8.1 + +## 1.8.0 + +### Minor Changes + +- provider: project analytics + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.8.0 + - @0xsequence/core@1.8.0 + - @0xsequence/migration@1.8.0 + - @0xsequence/network@1.8.0 + - @0xsequence/relayer@1.8.0 + - @0xsequence/sessions@1.8.0 + - @0xsequence/utils@1.8.0 + - @0xsequence/wallet@1.8.0 + +## 1.7.2 + +### Patch Changes + +- 0xsequence: ChainId should not be exported as a type +- account, wallet: fix nonce selection +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.7.2 + - @0xsequence/core@1.7.2 + - @0xsequence/migration@1.7.2 + - @0xsequence/network@1.7.2 + - @0xsequence/relayer@1.7.2 + - @0xsequence/sessions@1.7.2 + - @0xsequence/utils@1.7.2 + - @0xsequence/wallet@1.7.2 + +## 1.7.1 + +### Patch Changes + +- network: add missing avalanche logoURI +- Updated dependencies + - @0xsequence/abi@1.7.1 + - @0xsequence/core@1.7.1 + - @0xsequence/migration@1.7.1 + - @0xsequence/network@1.7.1 + - @0xsequence/relayer@1.7.1 + - @0xsequence/sessions@1.7.1 + - @0xsequence/utils@1.7.1 + - @0xsequence/wallet@1.7.1 + +## 1.7.0 + +### Minor Changes + +- provider: projectAccessKey is now required + +### Patch Changes + +- network: add NetworkMetadata.logoURI property for all networks +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.7.0 + - @0xsequence/core@1.7.0 + - @0xsequence/migration@1.7.0 + - @0xsequence/network@1.7.0 + - @0xsequence/relayer@1.7.0 + - @0xsequence/sessions@1.7.0 + - @0xsequence/utils@1.7.0 + - @0xsequence/wallet@1.7.0 + +## 1.6.3 + +### Patch Changes + +- network list update +- Updated dependencies + - @0xsequence/abi@1.6.3 + - @0xsequence/core@1.6.3 + - @0xsequence/migration@1.6.3 + - @0xsequence/network@1.6.3 + - @0xsequence/relayer@1.6.3 + - @0xsequence/sessions@1.6.3 + - @0xsequence/utils@1.6.3 + - @0xsequence/wallet@1.6.3 + +## 1.6.2 + +### Patch Changes + +- auth: projectAccessKey option +- wallet: use 12 bytes for random space +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.6.2 + - @0xsequence/core@1.6.2 + - @0xsequence/migration@1.6.2 + - @0xsequence/network@1.6.2 + - @0xsequence/relayer@1.6.2 + - @0xsequence/sessions@1.6.2 + - @0xsequence/utils@1.6.2 + - @0xsequence/wallet@1.6.2 + +## 1.6.1 + +### Patch Changes + +- core: add simple config from subdigest support +- core: fix encode tree with subdigest +- account: implement buildOnChainSignature on Account +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.6.1 + - @0xsequence/core@1.6.1 + - @0xsequence/migration@1.6.1 + - @0xsequence/network@1.6.1 + - @0xsequence/relayer@1.6.1 + - @0xsequence/sessions@1.6.1 + - @0xsequence/utils@1.6.1 + - @0xsequence/wallet@1.6.1 + +## 1.6.0 + +### Minor Changes + +- account, wallet: parallel transactions by default + +### Patch Changes + +- provider: emit disconnect on sign out +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.6.0 + - @0xsequence/migration@1.6.0 + - @0xsequence/network@1.6.0 + - @0xsequence/relayer@1.6.0 + - @0xsequence/sessions@1.6.0 + - @0xsequence/utils@1.6.0 + - @0xsequence/wallet@1.6.0 + +## 1.5.0 + +### Minor Changes + +- signhub: add 'signing' signer status + +### Patch Changes + +- auth: Session.open: onAccountAddress callback +- account: allow empty transaction bundles +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.5.0 + - @0xsequence/migration@1.5.0 + - @0xsequence/network@1.5.0 + - @0xsequence/relayer@1.5.0 + - @0xsequence/sessions@1.5.0 + - @0xsequence/utils@1.5.0 + - @0xsequence/wallet@1.5.0 + +## 1.4.9 + +### Patch Changes + +- rename SequenceMetadataClient to SequenceMetadata +- Updated dependencies + - @0xsequence/core@1.4.9 + - @0xsequence/migration@1.4.9 + - @0xsequence/network@1.4.9 + - @0xsequence/relayer@1.4.9 + - @0xsequence/sessions@1.4.9 + - @0xsequence/utils@1.4.9 + - @0xsequence/wallet@1.4.9 + +## 1.4.8 + +### Patch Changes + +- account: Account.getSigners +- Updated dependencies + - @0xsequence/core@1.4.8 + - @0xsequence/migration@1.4.8 + - @0xsequence/network@1.4.8 + - @0xsequence/relayer@1.4.8 + - @0xsequence/sessions@1.4.8 + - @0xsequence/utils@1.4.8 + - @0xsequence/wallet@1.4.8 + +## 1.4.7 + +### Patch Changes + +- update indexer client bindings +- Updated dependencies + - @0xsequence/core@1.4.7 + - @0xsequence/migration@1.4.7 + - @0xsequence/network@1.4.7 + - @0xsequence/relayer@1.4.7 + - @0xsequence/sessions@1.4.7 + - @0xsequence/utils@1.4.7 + - @0xsequence/wallet@1.4.7 + +## 1.4.6 + +### Patch Changes + +- - add sepolia networks, mark goerli as deprecated + - update indexer client bindings +- Updated dependencies + - @0xsequence/core@1.4.6 + - @0xsequence/migration@1.4.6 + - @0xsequence/network@1.4.6 + - @0xsequence/relayer@1.4.6 + - @0xsequence/sessions@1.4.6 + - @0xsequence/utils@1.4.6 + - @0xsequence/wallet@1.4.6 + +## 1.4.5 + +### Patch Changes + +- indexer/metadata: update client bindings +- auth: selectWallet with new address +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.4.5 + - @0xsequence/migration@1.4.5 + - @0xsequence/network@1.4.5 + - @0xsequence/relayer@1.4.5 + - @0xsequence/sessions@1.4.5 + - @0xsequence/utils@1.4.5 + - @0xsequence/wallet@1.4.5 + +## 1.4.4 + +### Patch Changes + +- indexer: update bindings +- auth: handle jwt expiry +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.4.4 + - @0xsequence/migration@1.4.4 + - @0xsequence/network@1.4.4 + - @0xsequence/relayer@1.4.4 + - @0xsequence/sessions@1.4.4 + - @0xsequence/utils@1.4.4 + - @0xsequence/wallet@1.4.4 + +## 1.4.3 + +### Patch Changes + +- guard: return active status from GuardSigner.getAuthMethods +- Updated dependencies + - @0xsequence/core@1.4.3 + - @0xsequence/migration@1.4.3 + - @0xsequence/network@1.4.3 + - @0xsequence/relayer@1.4.3 + - @0xsequence/sessions@1.4.3 + - @0xsequence/utils@1.4.3 + - @0xsequence/wallet@1.4.3 + +## 1.4.2 + +### Patch Changes + +- guard: update bindings +- Updated dependencies + - @0xsequence/core@1.4.2 + - @0xsequence/migration@1.4.2 + - @0xsequence/network@1.4.2 + - @0xsequence/relayer@1.4.2 + - @0xsequence/sessions@1.4.2 + - @0xsequence/utils@1.4.2 + - @0xsequence/wallet@1.4.2 + +## 1.4.1 + +### Patch Changes + +- network: remove unused networks +- signhub: orchestrator interface +- guard: auth methods interface +- guard: update bindings for pin and totp +- guard: no more retry logic +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.4.1 + - @0xsequence/migration@1.4.1 + - @0xsequence/network@1.4.1 + - @0xsequence/relayer@1.4.1 + - @0xsequence/sessions@1.4.1 + - @0xsequence/utils@1.4.1 + - @0xsequence/wallet@1.4.1 + +## 1.4.0 + +### Minor Changes + +- project access key support + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.4.0 + - @0xsequence/migration@1.4.0 + - @0xsequence/network@1.4.0 + - @0xsequence/relayer@1.4.0 + - @0xsequence/sessions@1.4.0 + - @0xsequence/utils@1.4.0 + - @0xsequence/wallet@1.4.0 + +## 1.3.0 + +### Minor Changes + +- signhub: account children + +### Patch Changes + +- guard: do not throw when building deploy transaction +- network: snowtrace.io -> subnets.avax.network/c-chain +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.3.0 + - @0xsequence/migration@1.3.0 + - @0xsequence/network@1.3.0 + - @0xsequence/relayer@1.3.0 + - @0xsequence/sessions@1.3.0 + - @0xsequence/utils@1.3.0 + - @0xsequence/wallet@1.3.0 + +## 1.2.9 + +### Patch Changes + +- account: AccountSigner.sendTransaction simulateForFeeOptions +- relayer: update bindings +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.2.9 + - @0xsequence/migration@1.2.9 + - @0xsequence/network@1.2.9 + - @0xsequence/relayer@1.2.9 + - @0xsequence/sessions@1.2.9 + - @0xsequence/utils@1.2.9 + - @0xsequence/wallet@1.2.9 + +## 1.2.8 + +### Patch Changes + +- rename X-Sequence-Token-Key header to X-Access-Key +- Updated dependencies + - @0xsequence/core@1.2.8 + - @0xsequence/migration@1.2.8 + - @0xsequence/network@1.2.8 + - @0xsequence/relayer@1.2.8 + - @0xsequence/sessions@1.2.8 + - @0xsequence/utils@1.2.8 + - @0xsequence/wallet@1.2.8 + +## 1.2.7 + +### Patch Changes + +- add x-sequence-token-key to clients +- Updated dependencies + - @0xsequence/core@1.2.7 + - @0xsequence/migration@1.2.7 + - @0xsequence/network@1.2.7 + - @0xsequence/relayer@1.2.7 + - @0xsequence/sessions@1.2.7 + - @0xsequence/utils@1.2.7 + - @0xsequence/wallet@1.2.7 + +## 1.2.6 + +### Patch Changes + +- Fix bind multicall provider +- Updated dependencies + - @0xsequence/core@1.2.6 + - @0xsequence/migration@1.2.6 + - @0xsequence/network@1.2.6 + - @0xsequence/relayer@1.2.6 + - @0xsequence/sessions@1.2.6 + - @0xsequence/utils@1.2.6 + - @0xsequence/wallet@1.2.6 + +## 1.2.5 + +### Patch Changes + +- Multicall default configuration fixes +- Updated dependencies + - @0xsequence/core@1.2.5 + - @0xsequence/migration@1.2.5 + - @0xsequence/network@1.2.5 + - @0xsequence/relayer@1.2.5 + - @0xsequence/sessions@1.2.5 + - @0xsequence/utils@1.2.5 + - @0xsequence/wallet@1.2.5 + +## 1.2.4 + +### Patch Changes + +- provider: Adding missing payment provider types to PaymentProviderOption +- provider: WalletRequestHandler.notifyChainChanged +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.2.4 + - @0xsequence/migration@1.2.4 + - @0xsequence/network@1.2.4 + - @0xsequence/relayer@1.2.4 + - @0xsequence/sessions@1.2.4 + - @0xsequence/utils@1.2.4 + - @0xsequence/wallet@1.2.4 + +## 1.2.3 + +### Patch Changes + +- auth, provider: connect to accept optional authorizeNonce +- Updated dependencies + - @0xsequence/core@1.2.3 + - @0xsequence/migration@1.2.3 + - @0xsequence/network@1.2.3 + - @0xsequence/relayer@1.2.3 + - @0xsequence/sessions@1.2.3 + - @0xsequence/utils@1.2.3 + - @0xsequence/wallet@1.2.3 + +## 1.2.2 + +### Patch Changes + +- provider: allow createContract calls +- core: check for explicit zero address in contract deployments +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.2.2 + - @0xsequence/migration@1.2.2 + - @0xsequence/network@1.2.2 + - @0xsequence/relayer@1.2.2 + - @0xsequence/sessions@1.2.2 + - @0xsequence/utils@1.2.2 + - @0xsequence/wallet@1.2.2 + +## 1.2.1 + +### Patch Changes + +- auth: use sequence api chain id as reference chain id if available +- Updated dependencies + - @0xsequence/core@1.2.1 + - @0xsequence/migration@1.2.1 + - @0xsequence/network@1.2.1 + - @0xsequence/relayer@1.2.1 + - @0xsequence/sessions@1.2.1 + - @0xsequence/utils@1.2.1 + - @0xsequence/wallet@1.2.1 + +## 1.2.0 + +### Minor Changes + +- split services from session, better local support + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.2.0 + - @0xsequence/migration@1.2.0 + - @0xsequence/network@1.2.0 + - @0xsequence/relayer@1.2.0 + - @0xsequence/sessions@1.2.0 + - @0xsequence/utils@1.2.0 + - @0xsequence/wallet@1.2.0 + +## 1.1.15 + +### Patch Changes + +- guard: remove error filtering +- Updated dependencies + - @0xsequence/core@1.1.15 + - @0xsequence/migration@1.1.15 + - @0xsequence/network@1.1.15 + - @0xsequence/relayer@1.1.15 + - @0xsequence/sessions@1.1.15 + - @0xsequence/utils@1.1.15 + - @0xsequence/wallet@1.1.15 + +## 1.1.14 + +### Patch Changes + +- guard: add GuardSigner.onError +- Updated dependencies + - @0xsequence/core@1.1.14 + - @0xsequence/migration@1.1.14 + - @0xsequence/network@1.1.14 + - @0xsequence/relayer@1.1.14 + - @0xsequence/sessions@1.1.14 + - @0xsequence/utils@1.1.14 + - @0xsequence/wallet@1.1.14 + +## 1.1.13 + +### Patch Changes + +- provider: pass client version with connect options +- provider: removing large from BannerSize +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.1.13 + - @0xsequence/migration@1.1.13 + - @0xsequence/network@1.1.13 + - @0xsequence/relayer@1.1.13 + - @0xsequence/sessions@1.1.13 + - @0xsequence/utils@1.1.13 + - @0xsequence/wallet@1.1.13 + +## 1.1.12 + +### Patch Changes + +- provider: adding bannerSize to ConnectOptions +- Updated dependencies + - @0xsequence/core@1.1.12 + - @0xsequence/migration@1.1.12 + - @0xsequence/network@1.1.12 + - @0xsequence/relayer@1.1.12 + - @0xsequence/sessions@1.1.12 + - @0xsequence/utils@1.1.12 + - @0xsequence/wallet@1.1.12 + +## 1.1.11 + +### Patch Changes + +- add homeverse configs +- Updated dependencies + - @0xsequence/core@1.1.11 + - @0xsequence/migration@1.1.11 + - @0xsequence/network@1.1.11 + - @0xsequence/relayer@1.1.11 + - @0xsequence/sessions@1.1.11 + - @0xsequence/utils@1.1.11 + - @0xsequence/wallet@1.1.11 + +## 1.1.10 + +### Patch Changes + +- handle default EIP6492 on send +- Updated dependencies + - @0xsequence/core@1.1.10 + - @0xsequence/migration@1.1.10 + - @0xsequence/network@1.1.10 + - @0xsequence/relayer@1.1.10 + - @0xsequence/sessions@1.1.10 + - @0xsequence/utils@1.1.10 + - @0xsequence/wallet@1.1.10 + +## 1.1.9 + +### Patch Changes + +- Custom default EIP6492 on client +- Updated dependencies + - @0xsequence/core@1.1.9 + - @0xsequence/migration@1.1.9 + - @0xsequence/network@1.1.9 + - @0xsequence/relayer@1.1.9 + - @0xsequence/sessions@1.1.9 + - @0xsequence/utils@1.1.9 + - @0xsequence/wallet@1.1.9 + +## 1.1.8 + +### Patch Changes + +- metadata: searchMetadata: add types filter +- Updated dependencies + - @0xsequence/core@1.1.8 + - @0xsequence/migration@1.1.8 + - @0xsequence/network@1.1.8 + - @0xsequence/relayer@1.1.8 + - @0xsequence/sessions@1.1.8 + - @0xsequence/utils@1.1.8 + - @0xsequence/wallet@1.1.8 + +## 1.1.7 + +### Patch Changes + +- adding signInWith connect settings option to allow dapps to automatically login their users with a certain provider optimizing the normal authentication flow +- Updated dependencies + - @0xsequence/core@1.1.7 + - @0xsequence/migration@1.1.7 + - @0xsequence/network@1.1.7 + - @0xsequence/relayer@1.1.7 + - @0xsequence/sessions@1.1.7 + - @0xsequence/utils@1.1.7 + - @0xsequence/wallet@1.1.7 + +## 1.1.6 + +### Patch Changes + +- metadata: searchMetadata: add chainID and excludeTokenMetadata filters +- Updated dependencies + - @0xsequence/core@1.1.6 + - @0xsequence/migration@1.1.6 + - @0xsequence/network@1.1.6 + - @0xsequence/relayer@1.1.6 + - @0xsequence/sessions@1.1.6 + - @0xsequence/utils@1.1.6 + - @0xsequence/wallet@1.1.6 + +## 1.1.5 + +### Patch Changes + +- account: re-compute meta-transaction id for wallet deployment transactions +- Updated dependencies + - @0xsequence/core@1.1.5 + - @0xsequence/migration@1.1.5 + - @0xsequence/network@1.1.5 + - @0xsequence/relayer@1.1.5 + - @0xsequence/sessions@1.1.5 + - @0xsequence/utils@1.1.5 + - @0xsequence/wallet@1.1.5 + +## 1.1.4 + +### Patch Changes + +- network: rename base-mainnet to base +- provider: override isDefaultChain with ConnectOptions.networkId if provided +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.1.4 + - @0xsequence/migration@1.1.4 + - @0xsequence/network@1.1.4 + - @0xsequence/relayer@1.1.4 + - @0xsequence/sessions@1.1.4 + - @0xsequence/utils@1.1.4 + - @0xsequence/wallet@1.1.4 + +## 1.1.3 + +### Patch Changes + +- provider: use network id from transport session +- provider: sign authorization using ConnectOptions.networkId if provided +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.1.3 + - @0xsequence/migration@1.1.3 + - @0xsequence/network@1.1.3 + - @0xsequence/relayer@1.1.3 + - @0xsequence/sessions@1.1.3 + - @0xsequence/utils@1.1.3 + - @0xsequence/wallet@1.1.3 + +## 1.1.2 + +### Patch Changes + +- provider: jsonrpc chain id fixes +- Updated dependencies + - @0xsequence/core@1.1.2 + - @0xsequence/migration@1.1.2 + - @0xsequence/network@1.1.2 + - @0xsequence/relayer@1.1.2 + - @0xsequence/sessions@1.1.2 + - @0xsequence/utils@1.1.2 + - @0xsequence/wallet@1.1.2 + +## 1.1.1 + +### Patch Changes + +- network: add base mainnet and sepolia +- provider: reject toxic transaction requests +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.1.1 + - @0xsequence/migration@1.1.1 + - @0xsequence/network@1.1.1 + - @0xsequence/relayer@1.1.1 + - @0xsequence/sessions@1.1.1 + - @0xsequence/utils@1.1.1 + - @0xsequence/wallet@1.1.1 + +## 1.1.0 + +### Minor Changes + +- Refactor dapp facing provider + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.1.0 + - @0xsequence/migration@1.1.0 + - @0xsequence/network@1.1.0 + - @0xsequence/relayer@1.1.0 + - @0xsequence/sessions@1.1.0 + - @0xsequence/utils@1.1.0 + - @0xsequence/wallet@1.1.0 + +## 1.0.5 + +### Patch Changes + +- network: export network constants +- guard: use the correct global for fetch +- network: nova-explorer.arbitrum.io -> nova.arbiscan.io +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.0.5 + - @0xsequence/migration@1.0.5 + - @0xsequence/network@1.0.5 + - @0xsequence/relayer@1.0.5 + - @0xsequence/sessions@1.0.5 + - @0xsequence/utils@1.0.5 + - @0xsequence/wallet@1.0.5 + +## 1.0.4 + +### Patch Changes + +- provider: accept name or number for networkId +- Updated dependencies + - @0xsequence/core@1.0.4 + - @0xsequence/migration@1.0.4 + - @0xsequence/network@1.0.4 + - @0xsequence/relayer@1.0.4 + - @0xsequence/sessions@1.0.4 + - @0xsequence/utils@1.0.4 + - @0xsequence/wallet@1.0.4 + +## 1.0.3 + +### Patch Changes + +- Simpler isValidSignature helpers +- Updated dependencies + - @0xsequence/core@1.0.3 + - @0xsequence/migration@1.0.3 + - @0xsequence/network@1.0.3 + - @0xsequence/relayer@1.0.3 + - @0xsequence/sessions@1.0.3 + - @0xsequence/utils@1.0.3 + - @0xsequence/wallet@1.0.3 + +## 1.0.2 + +### Patch Changes + +- add extra signature validation utils methods +- Updated dependencies + - @0xsequence/core@1.0.2 + - @0xsequence/migration@1.0.2 + - @0xsequence/network@1.0.2 + - @0xsequence/relayer@1.0.2 + - @0xsequence/sessions@1.0.2 + - @0xsequence/utils@1.0.2 + - @0xsequence/wallet@1.0.2 + +## 1.0.1 + +### Patch Changes + +- add homeverse testnet +- Updated dependencies + - @0xsequence/core@1.0.1 + - @0xsequence/migration@1.0.1 + - @0xsequence/network@1.0.1 + - @0xsequence/relayer@1.0.1 + - @0xsequence/sessions@1.0.1 + - @0xsequence/utils@1.0.1 + - @0xsequence/wallet@1.0.1 + +## 1.0.0 + +### Major Changes + +- https://sequence.xyz/blog/sequence-wallet-light-state-sync-full-merkle-wallets + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.0.0 + - @0xsequence/migration@1.0.0 + - @0xsequence/network@1.0.0 + - @0xsequence/relayer@1.0.0 + - @0xsequence/sessions@1.0.0 + - @0xsequence/utils@1.0.0 + - @0xsequence/wallet@1.0.0 diff --git a/packages/account/hardhat.config.js b/packages/account/hardhat.config.js new file mode 100644 index 0000000000..9e73336b07 --- /dev/null +++ b/packages/account/hardhat.config.js @@ -0,0 +1,12 @@ + +module.exports = { + networks: { + hardhat: { + chainId: 31337, + port: 7146, + accounts: { + mnemonic: 'ripple axis someone ridge uniform wrist prosper there frog rate olympic knee' + }, + }, + } +} diff --git a/packages/account/hardhat2.config.js b/packages/account/hardhat2.config.js new file mode 100644 index 0000000000..e984fc2e79 --- /dev/null +++ b/packages/account/hardhat2.config.js @@ -0,0 +1,11 @@ + +module.exports = { + networks: { + hardhat: { + chainId: 31338, + accounts: { + mnemonic: 'ripple axis someone ridge uniform wrist prosper there frog rate olympic knee' + } + } + } +} diff --git a/packages/account/package.json b/packages/account/package.json new file mode 100644 index 0000000000..ddaefabe13 --- /dev/null +++ b/packages/account/package.json @@ -0,0 +1,40 @@ +{ + "name": "@0xsequence/account", + "version": "2.0.0", + "description": "tools for migrating sequence wallets to new versions", + "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/account", + "source": "src/index.ts", + "main": "dist/0xsequence-account.cjs.js", + "module": "dist/0xsequence-account.esm.js", + "author": "Horizon Blockchain Games", + "license": "Apache-2.0", + "scripts": { + "test": "pnpm test:concurrently 'pnpm test:run'", + "test:run": "pnpm test:file tests/**/*.spec.ts", + "test:file": "TS_NODE_PROJECT=../../tsconfig.test.json mocha -r ts-node/register --timeout 120000", + "test:concurrently": "concurrently -k --success first 'pnpm start:hardhat2 > /dev/null'", + "start:hardhat2": "hardhat node --hostname 0.0.0.0 --port 7048 --config ./hardhat2.config.js", + "test:coverage": "nyc pnpm test" + }, + "dependencies": { + "@0xsequence/abi": "workspace:*", + "@0xsequence/core": "workspace:*", + "@0xsequence/migration": "workspace:*", + "@0xsequence/network": "workspace:*", + "@0xsequence/relayer": "workspace:*", + "@0xsequence/sessions": "workspace:*", + "@0xsequence/utils": "workspace:*", + "@0xsequence/wallet": "workspace:*", + "ethers": "^5.5.2" + }, + "devDependencies": { + "@0xsequence/signhub": "workspace:*", + "@0xsequence/tests": "workspace:*", + "@istanbuljs/nyc-config-typescript": "^1.0.2", + "nyc": "^15.1.0" + }, + "files": [ + "src", + "dist" + ] +} diff --git a/packages/account/src/account.ts b/packages/account/src/account.ts new file mode 100644 index 0000000000..3243842eb8 --- /dev/null +++ b/packages/account/src/account.ts @@ -0,0 +1,1085 @@ +import { walletContracts } from '@0xsequence/abi' +import { commons, universal } from '@0xsequence/core' +import { WalletSignRequestMetadata } from '@0xsequence/core/src/commons' +import { migrator, defaults, version } from '@0xsequence/migration' +import { ChainId, NetworkConfig } from '@0xsequence/network' +import { FeeOption, FeeQuote, isRelayer, Relayer, RpcRelayer } from '@0xsequence/relayer' +import { tracker } from '@0xsequence/sessions' +import { SignatureOrchestrator } from '@0xsequence/signhub' +import { encodeTypedDataDigest, getEthersConnectionInfo } from '@0xsequence/utils' +import { Wallet } from '@0xsequence/wallet' +import { ethers, TypedDataDomain, TypedDataField } from 'ethers' +import { AccountSigner, AccountSignerOptions } from './signer' + +export type AccountStatus = { + original: { + version: number + imageHash: string + context: commons.context.WalletContext + } + onChain: { + imageHash: string + config: commons.config.Config + version: number + deployed: boolean + } + fullyMigrated: boolean + signedMigrations: migrator.SignedMigration[] + version: number + presignedConfigurations: tracker.PresignedConfigLink[] + imageHash: string + config: commons.config.Config + checkpoint: ethers.BigNumberish + canOnchainValidate: boolean +} + +export type AccountOptions = { + // The only unique identifier for a wallet is the address + address: string + + // The config tracker keeps track of chained configs, + // counterfactual addresses and reverse lookups for configurations + // it must implement both the ConfigTracker and MigrationTracker + tracker: tracker.ConfigTracker & migrator.PresignedMigrationTracker + + // Versioned contexts contains the context information for each Sequence version + contexts: commons.context.VersionedContext + + // Optional list of migrations, if not provided, the default migrations will be used + // NOTICE: the last vestion is considered the "current" version for the account + migrations?: migrator.Migrations + + // Orchestrator manages signing messages and transactions + orchestrator: SignatureOrchestrator + + // Networks information and providers + networks: NetworkConfig[] + + // Jwt + jwt?: string + + // Project access key + projectAccessKey?: string +} + +export interface PreparedTransactions { + transactions: commons.transaction.SimulatedTransaction[] + flatDecorated: commons.transaction.Transaction[] + feeOptions: FeeOption[] + feeQuote?: FeeQuote +} + +class Chain0Reader implements commons.reader.Reader { + async isDeployed(_wallet: string): Promise { + return false + } + + async implementation(_wallet: string): Promise { + return undefined + } + + async imageHash(_wallet: string): Promise { + return undefined + } + + async nonce(_wallet: string, _space: ethers.BigNumberish): Promise { + return ethers.constants.Zero + } + + async isValidSignature(_wallet: string, _digest: ethers.utils.BytesLike, _signature: ethers.utils.BytesLike): Promise { + throw new Error('Method not supported.') + } +} + +export class Account { + public readonly address: string + + public readonly networks: NetworkConfig[] + public readonly tracker: tracker.ConfigTracker & migrator.PresignedMigrationTracker + public readonly contexts: commons.context.VersionedContext + + public readonly migrator: migrator.Migrator + public readonly migrations: migrator.Migrations + + private orchestrator: SignatureOrchestrator + + private jwt?: string + + private projectAccessKey?: string + + constructor(options: AccountOptions) { + this.address = ethers.utils.getAddress(options.address) + + this.contexts = options.contexts + this.tracker = options.tracker + this.networks = options.networks + this.orchestrator = options.orchestrator + this.jwt = options.jwt + this.projectAccessKey = options.projectAccessKey + + this.migrations = options.migrations || defaults.DefaultMigrations + this.migrator = new migrator.Migrator(options.tracker, this.migrations, this.contexts) + } + + getSigner(chainId: ChainId, options?: AccountSignerOptions): AccountSigner { + return new AccountSigner(this, chainId, options) + } + + static async new(options: { + config: commons.config.SimpleConfig + tracker: tracker.ConfigTracker & migrator.PresignedMigrationTracker + contexts: commons.context.VersionedContext + orchestrator: SignatureOrchestrator + networks: NetworkConfig[] + migrations?: migrator.Migrations + projectAccessKey?: string + }): Promise { + const mig = new migrator.Migrator(options.tracker, options.migrations ?? defaults.DefaultMigrations, options.contexts) + + const lastMigration = mig.lastMigration() + const lastCoder = lastMigration.configCoder + + const config = lastCoder.fromSimple(options.config) + const imageHash = lastCoder.imageHashOf(config) + const context = options.contexts[lastMigration.version] + const address = commons.context.addressOf(context, imageHash) + + await options.tracker.saveCounterfactualWallet({ config, context: Object.values(options.contexts) }) + + return new Account({ + address, + tracker: options.tracker, + contexts: options.contexts, + networks: options.networks, + orchestrator: options.orchestrator, + migrations: options.migrations, + projectAccessKey: options.projectAccessKey + }) + } + + getAddress(): Promise { + return Promise.resolve(this.address) + } + + get version(): number { + return this.migrator.lastMigration().version + } + + get coders(): { + signature: commons.signature.SignatureCoder + config: commons.config.ConfigCoder + } { + const lastMigration = this.migrator.lastMigration() + + return { + signature: lastMigration.signatureCoder, + config: lastMigration.configCoder + } + } + + network(chainId: ethers.BigNumberish): NetworkConfig { + const tcid = ethers.BigNumber.from(chainId) + const found = this.networks.find(n => tcid.eq(n.chainId)) + if (!found) throw new Error(`Network not found for chainId ${chainId}`) + return found + } + + providerFor(chainId: ethers.BigNumberish): ethers.providers.Provider { + const found = this.network(chainId) + if (!found.provider && !found.rpcUrl) throw new Error(`Provider not found for chainId ${chainId}`) + return ( + found.provider || + new ethers.providers.StaticJsonRpcProvider(getEthersConnectionInfo(found.rpcUrl, this.projectAccessKey, this.jwt), { + name: '', + chainId: ethers.BigNumber.from(chainId).toNumber() + }) + ) + } + + reader(chainId: ethers.BigNumberish): commons.reader.Reader { + if (ethers.constants.Zero.eq(chainId)) return new Chain0Reader() + + // TODO: Networks should be able to provide a reader directly + // and we should default to the on-chain reader + return new commons.reader.OnChainReader(this.providerFor(chainId)) + } + + relayer(chainId: ethers.BigNumberish): Relayer { + const found = this.network(chainId) + if (!found.relayer) throw new Error(`Relayer not found for chainId ${chainId}`) + if (isRelayer(found.relayer)) return found.relayer + return new RpcRelayer({ + ...found.relayer, + // If there's an access key, we don't pass the JWT, because browser-side usage of this code mandates an access key + // and passing a JWT causes a CORS error. + ...(this.projectAccessKey ? { projectAccessKey: this.projectAccessKey } : { jwtAuth: this.jwt }) + }) + } + + setOrchestrator(orchestrator: SignatureOrchestrator) { + this.orchestrator = orchestrator + } + + setJwt(jwt: string) { + this.jwt = jwt + } + + contextFor(version: number): commons.context.WalletContext { + const ctx = this.contexts[version] + if (!ctx) throw new Error(`Context not found for version ${version}`) + return ctx + } + + walletForStatus(chainId: ethers.BigNumberish, status: Pick & Pick): Wallet { + const coder = universal.coderFor(status.version) + return this.walletFor(chainId, this.contextFor(status.version), status.config, coder) + } + + walletFor( + chainId: ethers.BigNumberish, + context: commons.context.WalletContext, + config: commons.config.Config, + coders: typeof this.coders + ): Wallet { + const isNetworkZero = ethers.constants.Zero.eq(chainId) + return new Wallet({ + config, + context, + chainId, + coders, + relayer: isNetworkZero ? undefined : this.relayer(chainId), + address: this.address, + orchestrator: this.orchestrator, + reader: this.reader(chainId) + }) + } + + // Get the status of the account on a given network + // this does the following process: + // 1. Get the current on-chain status of the wallet (version + imageHash) + // 2. Get any pending migrations that have been signed by the wallet + // 3. Get any pending configuration updates that have been signed by the wallet + // 4. Fetch reverse lookups for both on-chain and pending configurations + async status(chainId: ethers.BigNumberish, longestPath: boolean = false): Promise { + const isDeployedPromise = this.reader(chainId).isDeployed(this.address) + + const counterfactualImageHashPromise = this.tracker + .imageHashOfCounterfactualWallet({ + wallet: this.address + }) + .then(r => { + if (!r) throw new Error(`Counterfactual imageHash not found for wallet ${this.address}`) + return r + }) + + const counterFactualVersionPromise = counterfactualImageHashPromise.then(r => { + return version.counterfactualVersion(this.address, r.imageHash, Object.values(this.contexts)) + }) + + const onChainVersionPromise = (async () => { + const isDeployed = await isDeployedPromise + if (!isDeployed) return counterFactualVersionPromise + + const implementation = await this.reader(chainId).implementation(this.address) + if (!implementation) throw new Error(`Implementation not found for wallet ${this.address}`) + + const versions = Object.values(this.contexts) + for (let i = 0; i < versions.length; i++) { + if (versions[i].mainModule === implementation || versions[i].mainModuleUpgradable === implementation) { + return versions[i].version + } + } + + throw new Error(`Version not found for implementation ${implementation}`) + })() + + const onChainImageHashPromise = (async () => { + const deployedImageHash = await this.reader(chainId).imageHash(this.address) + if (deployedImageHash) return deployedImageHash + const counterfactualImageHash = await counterfactualImageHashPromise + if (counterfactualImageHash) return counterfactualImageHash.imageHash + throw new Error(`On-chain imageHash not found for wallet ${this.address}`) + })() + + const onChainConfigPromise = (async () => { + const onChainImageHash = await onChainImageHashPromise + const onChainConfig = await this.tracker.configOfImageHash({ imageHash: onChainImageHash }) + if (onChainConfig) return onChainConfig + throw new Error(`On-chain config not found for imageHash ${onChainImageHash}`) + })() + + const onChainVersion = await onChainVersionPromise + const onChainImageHash = await onChainImageHashPromise + + let fromImageHash = onChainImageHash + let lastVersion = onChainVersion + let signedMigrations: migrator.SignedMigration[] = [] + + if (onChainVersion !== this.version) { + // We either need to use the presigned configuration updates, or we haven't performed + // any updates yet, so we can only use the on-chain imageHash as-is + const presignedMigrate = await this.migrator.getAllMigratePresignedTransaction({ + address: this.address, + fromImageHash: onChainImageHash, + fromVersion: onChainVersion, + chainId + }) + + // The migrator returns the original version and imageHash + // if no presigned migration is found, so no need to check here + fromImageHash = presignedMigrate.lastImageHash + lastVersion = presignedMigrate.lastVersion + + signedMigrations = presignedMigrate.signedMigrations + } + + const presigned = await this.tracker.loadPresignedConfiguration({ + wallet: this.address, + fromImageHash: fromImageHash, + longestPath + }) + + const imageHash = presigned && presigned.length > 0 ? presigned[presigned.length - 1].nextImageHash : fromImageHash + const config = await this.tracker.configOfImageHash({ imageHash }) + if (!config) { + throw new Error(`Config not found for imageHash ${imageHash}`) + } + + const isDeployed = await isDeployedPromise + const counterfactualImageHash = await counterfactualImageHashPromise + const checkpoint = universal.coderFor(lastVersion).config.checkpointOf(config as any) + + return { + original: { + ...counterfactualImageHash, + version: await counterFactualVersionPromise + }, + onChain: { + imageHash: onChainImageHash, + config: await onChainConfigPromise, + version: onChainVersion, + deployed: isDeployed + }, + fullyMigrated: lastVersion === this.version, + signedMigrations, + version: lastVersion, + presignedConfigurations: presigned, + imageHash, + config, + checkpoint, + canOnchainValidate: onChainVersion === this.version && isDeployed + } + } + + private mustBeFullyMigrated(status: AccountStatus) { + if (!status.fullyMigrated) { + throw new Error(`Wallet ${this.address} is not fully migrated`) + } + } + + async predecorateSignedTransactions( + status: AccountStatus, + chainId: ethers.BigNumberish + ): Promise { + // Request signed predecorate transactions from child wallets + const bundles = await this.orchestrator.predecorateSignedTransactions({ chainId }) + // Get signed predecorate transaction + const predecorated = await this.predecorateTransactions([], status, chainId) + if (commons.transaction.fromTransactionish(this.address, predecorated).length > 0) { + // Sign it + bundles.push(await this.signTransactions(predecorated, chainId)) + } + return bundles + } + + async predecorateTransactions( + txs: commons.transaction.Transactionish, + status: AccountStatus, + chainId: ethers.BigNumberish + ): Promise { + // if onchain wallet config is not up to date + // then we should append an extra transaction that updates it + // to the latest "lazy" state + if (status.onChain.imageHash !== status.imageHash) { + const wallet = this.walletForStatus(chainId, status) + const updateConfig = await wallet.buildUpdateConfigurationTransaction(status.config) + return [Array.isArray(txs) ? txs : [txs], updateConfig.transactions].flat() + } + + return txs + } + + async decorateTransactions( + bundles: commons.transaction.IntendedTransactionBundle | commons.transaction.IntendedTransactionBundle[], + status: AccountStatus, + chainId?: ethers.BigNumberish + ): Promise { + if (!Array.isArray(bundles)) { + // Recurse with array + return this.decorateTransactions([bundles], status, chainId) + } + + // Default to chainId of first bundle when not supplied + chainId = chainId ?? bundles[0].chainId + + const bootstrapBundle = await this.buildBootstrapTransactions(status, chainId) + const hasBootstrapTxs = bootstrapBundle.transactions.length > 0 + + if (!hasBootstrapTxs && bundles.length === 1) { + return bundles[0] + } + + // Intent defaults to first bundle when no bootstrap transaction + const { entrypoint } = hasBootstrapTxs ? bootstrapBundle : bundles[0] + + const decoratedBundle = { + entrypoint, + chainId, + // Intent of the first bundle is used + intent: bundles[0]?.intent, + transactions: [ + ...bootstrapBundle.transactions, + ...bundles.map( + (bundle): commons.transaction.Transaction => ({ + to: bundle.entrypoint, + data: commons.transaction.encodeBundleExecData(bundle), + gasLimit: 0, + delegateCall: false, + revertOnError: true, + value: 0 + }) + ) + ] + } + + // Re-compute the meta-transaction id to use the guest module subdigest + if (!status.onChain.deployed) { + const id = commons.transaction.subdigestOfGuestModuleTransactions( + this.contexts[this.version].guestModule, + chainId, + decoratedBundle.transactions + ) + + if (decoratedBundle.intent === undefined) { + decoratedBundle.intent = { id, wallet: this.address } + } else { + decoratedBundle.intent.id = id + } + } + + return decoratedBundle + } + + async decorateSignature( + signature: T, + status: Partial> + ): Promise { + if (!status.presignedConfigurations || status.presignedConfigurations.length === 0) { + return signature + } + + const coder = this.coders.signature + + const chain = status.presignedConfigurations.map(c => c.signature) + const chainedSignature = coder.chainSignatures(signature, chain) + return coder.trim(chainedSignature) + } + + async publishWitness(): Promise { + const digest = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(`This is a Sequence account woo! ${Date.now()}`)) + const signature = await this.signDigest(digest, 0, false) + const decoded = this.coders.signature.decode(signature) + const signatures = this.coders.signature.signaturesOfDecoded(decoded) + return this.tracker.saveWitnesses({ wallet: this.address, digest, chainId: 0, signatures }) + } + + async signDigest( + digest: ethers.BytesLike, + chainId: ethers.BigNumberish, + decorate: boolean = true, + cantValidateBehavior: 'ignore' | 'eip6492' | 'throw' = 'ignore', + metadata?: object + ): Promise { + // If we are signing a digest for chainId zero then we can never be fully migrated + // because Sequence v1 doesn't allow for signing a message on "all chains" + + // So we ignore the state on "chain zero" and instead use one of the states of the networks + // wallet-webapp should ensure the wallet is as migrated as possible, trying to mimic + // the behaviour of being migrated on all chains + const chainRef = ethers.constants.Zero.eq(chainId) ? this.networks[0].chainId : chainId + const status = await this.status(chainRef) + this.mustBeFullyMigrated(status) + + // Check if we can validate onchain and what to do if we can't + // revert early, since there is no point in signing a digest now + if (!status.canOnchainValidate && cantValidateBehavior === 'throw') { + throw new Error('Wallet cannot validate onchain') + } + + const wallet = this.walletForStatus(chainId, status) + const signature = await wallet.signDigest(digest, metadata) + + const decorated = decorate ? this.decorateSignature(signature, status) : signature + + // If the wallet can't validate onchain then we + // need to prefix the decorated signature with all deployments and migrations + // aka doing a bootstrap using EIP-6492 + if (!status.canOnchainValidate) { + switch (cantValidateBehavior) { + // NOTICE: We covered this case before signing the digest + // case 'throw': + // throw new Error('Wallet cannot validate on-chain') + case 'ignore': + return decorated + + case 'eip6492': + return this.buildEIP6492Signature(await decorated, status, chainId) + } + } + + return decorated + } + + buildOnChainSignature(digest: ethers.BytesLike): { bundle: commons.transaction.TransactionBundle; signature: string } { + const subdigest = commons.signature.subdigestOf({ digest: ethers.utils.hexlify(digest), chainId: 0, address: this.address }) + const hexSubdigest = ethers.utils.hexlify(subdigest) + const config = this.coders.config.fromSimple({ + // Threshold *only* needs to be > 0, this is not a magic number + // we only use 2 ** 15 because it may lead to lower gas costs in some chains + threshold: 32768, + checkpoint: 0, + signers: [], + subdigests: [hexSubdigest] + }) + + const walletInterface = new ethers.utils.Interface(walletContracts.mainModule.abi) + const bundle: commons.transaction.TransactionBundle = { + entrypoint: this.address, + transactions: [ + { + to: this.address, + data: walletInterface.encodeFunctionData( + // *NEVER* use updateImageHash here, as it would effectively destroy the wallet + // setExtraImageHash sets an additional imageHash, without changing the current one + 'setExtraImageHash', + [ + this.coders.config.imageHashOf(config), + // 2 ** 255 instead of max uint256, to have more zeros in the calldata + '57896044618658097711785492504343953926634992332820282019728792003956564819968' + ] + ), + // Conservative gas limit, used because the current relayer + // has trouble estimating gas for this transaction + gasLimit: 250000 + } + ] + } + + // Fire and forget request to save the config + this.tracker.saveWalletConfig({ config }) + + // Encode a signature proof for the given subdigest + // use `chainId = 0` to make it simpler, as this signature is only a proof + const signature = this.coders.signature.encodeSigners(config, new Map(), [hexSubdigest], 0).encoded + return { bundle, signature } + } + + private async buildEIP6492Signature(signature: string, status: AccountStatus, chainId: ethers.BigNumberish): Promise { + const bootstrapBundle = await this.buildBootstrapTransactions(status, chainId) + if (bootstrapBundle.transactions.length === 0) { + throw new Error('Cannot build EIP-6492 signature without bootstrap transactions') + } + + const encoded = ethers.utils.defaultAbiCoder.encode( + ['address', 'bytes', 'bytes'], + [bootstrapBundle.entrypoint, commons.transaction.encodeBundleExecData(bootstrapBundle), signature] + ) + + return ethers.utils.solidityPack(['bytes', 'bytes32'], [encoded, commons.EIP6492.EIP_6492_SUFFIX]) + } + + async editConfig(changes: { + add?: commons.config.SimpleSigner[] + remove?: string[] + threshold?: ethers.BigNumberish + }): Promise { + const currentConfig = await this.status(0).then(s => s.config) + const newConfig = this.coders.config.editConfig(currentConfig, { + ...changes, + checkpoint: this.coders.config.checkpointOf(currentConfig).add(1) + }) + + return this.updateConfig(newConfig) + } + + async updateConfig(config: commons.config.Config): Promise { + // config should be for the current version of the wallet + if (!this.coders.config.isWalletConfig(config)) { + throw new Error(`Invalid config for wallet ${this.address}`) + } + + const nextImageHash = this.coders.config.imageHashOf(config) + + // sign an update config struct + const updateStruct = this.coders.signature.hashSetImageHash(nextImageHash) + + // sign the update struct, using chain id 0 + const signature = await this.signDigest(updateStruct, 0, false) + + // save the presigned transaction to the sessions tracker + await this.tracker.savePresignedConfiguration({ + wallet: this.address, + nextConfig: config, + signature + }) + + // safety check, tracker should have a reverse lookup for the imageHash + // outside of the local cache + const reverseConfig = await this.tracker.configOfImageHash({ + imageHash: nextImageHash, + noCache: true + }) + + if (!reverseConfig || this.coders.config.imageHashOf(reverseConfig) !== nextImageHash) { + throw Error(`Reverse lookup failed for imageHash ${nextImageHash}`) + } + } + + /** + * This method is used to bootstrap the wallet on a given chain. + * this deploys the wallets and executes all the necessary transactions + * for that wallet to start working with the given version. + * + * This usually involves: (a) deploying the wallet, (b) executing migrations + * + * Notice: It should NOT explicitly include chained signatures. Unless internally used + * by any of the migrations. + * + */ + async buildBootstrapTransactions( + status: AccountStatus, + chainId: ethers.BigNumberish + ): Promise { + const bundle = await this.orchestrator.buildDeployTransaction({ chainId }) + const transactions: commons.transaction.Transaction[] = bundle?.transactions ?? [] + + // Add wallet deployment if needed + if (!status.onChain.deployed) { + // Wallet deployment will vary depending on the version + // so we need to use the context to get the correct deployment + const deployTransaction = Wallet.buildDeployTransaction(status.original.context, status.original.imageHash) + + transactions.push(...deployTransaction.transactions) + } + const len = transactions.length + + // Get pending migrations + transactions.push( + ...status.signedMigrations.map(m => ({ + to: m.tx.entrypoint, + data: commons.transaction.encodeBundleExecData(m.tx), + value: 0, + gasLimit: 0, + revertOnError: true, + delegateCall: false + })) + ) + + // Build the transaction intent, if the transaction has migrations + // then we should use one of the intents of the migrations (anyone will do) + // if it doesn't, then the only intent we could use if the GuestModule one + // ... but this may fail if the relayer uses a different GuestModule + const id = + status.signedMigrations.length > 0 + ? status.signedMigrations[0].tx.intent.id + : commons.transaction.subdigestOfGuestModuleTransactions(this.contexts[this.version].guestModule, chainId, transactions) + + // Everything is encoded as a bundle + // using the GuestModule of the account version + const { guestModule } = this.contextFor(status.version) + return { entrypoint: guestModule, transactions, chainId, intent: { id, wallet: this.address } } + } + + async bootstrapTransactions( + chainId: ethers.BigNumberish, + prestatus?: AccountStatus + ): Promise> { + const status = prestatus || (await this.status(chainId)) + return this.buildBootstrapTransactions(status, chainId) + } + + async doBootstrap(chainId: ethers.BigNumberish, feeQuote?: FeeQuote, prestatus?: AccountStatus) { + const bootstrapTxs = await this.bootstrapTransactions(chainId, prestatus) + return this.relayer(chainId).relay({ ...bootstrapTxs, chainId }, feeQuote) + } + + signMessage( + message: ethers.BytesLike, + chainId: ethers.BigNumberish, + cantValidateBehavior: 'ignore' | 'eip6492' | 'throw' = 'ignore' + ): Promise { + return this.signDigest(ethers.utils.keccak256(message), chainId, true, cantValidateBehavior) + } + + async signTransactions( + txs: commons.transaction.Transactionish, + chainId: ethers.BigNumberish, + pstatus?: AccountStatus, + options?: { + nonceSpace?: ethers.BigNumberish + serial?: boolean + } + ): Promise { + const status = pstatus || (await this.status(chainId)) + this.mustBeFullyMigrated(status) + + const wallet = this.walletForStatus(chainId, status) + + const metadata: WalletSignRequestMetadata = { + address: this.address, + digest: '', // Set in wallet.signTransactions + chainId, + config: { version: this.version }, + decorate: true, + cantValidateBehavior: 'ignore' + } + + const nonceOptions = options?.serial + ? { serial: true } + : options?.nonceSpace !== undefined + ? { space: options.nonceSpace } + : undefined + + const signed = await wallet.signTransactions(txs, nonceOptions, metadata) + + return { + ...signed, + signature: await this.decorateSignature(signed.signature, status) + } + } + + async signMigrations( + chainId: ethers.BigNumberish, + editConfig: (prevConfig: commons.config.Config) => commons.config.Config + ): Promise { + const status = await this.status(chainId) + if (status.fullyMigrated) return false + + const wallet = this.walletForStatus(chainId, status) + const nextConfig = editConfig(wallet.config) + const signed = await this.migrator.signNextMigration(this.address, status.version, wallet, nextConfig) + if (!signed) return false + + // Make sure the tracker has a copy of the config + // before attempting to save the migration + // otherwise if this second step fails the tracker could end up + // with a migration to an unknown config + await this.tracker.saveWalletConfig({ config: nextConfig }) + const nextCoder = universal.coderFor(nextConfig.version).config + const nextImageHash = nextCoder.imageHashOf(nextConfig as any) + const reverseConfig = await this.tracker.configOfImageHash({ imageHash: nextImageHash, noCache: true }) + if (!reverseConfig || nextCoder.imageHashOf(reverseConfig as any) !== nextImageHash) { + throw Error(`Reverse lookup failed for imageHash ${nextImageHash}`) + } + + await this.tracker.saveMigration(this.address, signed, this.contexts) + + return true + } + + async signAllMigrations( + editConfig: (prevConfig: commons.config.Config) => commons.config.Config + ): Promise<{ signedMigrations: Array; failedChains: number[] }> { + const failedChains: number[] = [] + const signedMigrations = await Promise.all( + this.networks.map(async n => { + try { + // Signing migrations for each chain + return await this.signMigrations(n.chainId, editConfig) + } catch (error) { + console.warn(`Failed to sign migrations for chain ${n.chainId}`, error) + + // Adding failed chainId to the failedChains array + failedChains.push(n.chainId) + // Using null as a placeholder for failed chains + return null + } + }) + ) + + // Filter out null values to get only the successful signed migrations + const successfulSignedMigrations = signedMigrations.filter(migration => migration !== null) + + return { signedMigrations: successfulSignedMigrations, failedChains } + } + + async isMigratedAllChains(): Promise<{ migratedAllChains: boolean; failedChains: number[] }> { + const failedChains: number[] = [] + const statuses = await Promise.all( + this.networks.map(async n => { + try { + return await this.status(n.chainId) + } catch (error) { + failedChains.push(n.chainId) + + console.warn(`Failed to get status for chain ${n.chainId}`, error) + + // default to true for failed chains + return { fullyMigrated: true } + } + }) + ) + + const migratedAllChains = statuses.every(s => s.fullyMigrated) + return { migratedAllChains, failedChains } + } + + async sendSignedTransactions( + signedBundle: commons.transaction.IntendedTransactionBundle | commons.transaction.IntendedTransactionBundle[], + chainId: ethers.BigNumberish, + quote?: FeeQuote, + pstatus?: AccountStatus, + callback?: (bundle: commons.transaction.IntendedTransactionBundle) => void + ): Promise { + if (!Array.isArray(signedBundle)) { + return this.sendSignedTransactions([signedBundle], chainId, quote, pstatus, callback) + } + const status = pstatus || (await this.status(chainId)) + this.mustBeFullyMigrated(status) + + const decoratedBundle = await this.decorateTransactions(signedBundle, status, chainId) + callback?.(decoratedBundle) + + return this.relayer(chainId).relay(decoratedBundle, quote) + } + + async fillGasLimits( + txs: commons.transaction.Transactionish, + chainId: ethers.BigNumberish, + status?: AccountStatus + ): Promise { + const wallet = this.walletForStatus(chainId, status || (await this.status(chainId))) + return wallet.fillGasLimits(txs) + } + + async gasRefundQuotes( + txs: commons.transaction.Transactionish, + chainId: ethers.BigNumberish, + stubSignatureOverrides: Map, + status?: AccountStatus, + options?: { + simulate?: boolean + } + ): Promise<{ + options: FeeOption[] + quote?: FeeQuote + decorated: commons.transaction.IntendedTransactionBundle + }> { + const wstatus = status || (await this.status(chainId)) + const wallet = this.walletForStatus(chainId, wstatus) + + const predecorated = await this.predecorateTransactions(txs, wstatus, chainId) + const transactions = commons.transaction.fromTransactionish(this.address, predecorated) + + // We can't sign the transactions (because we don't want to bother the user) + // so we use the latest configuration to build a "stub" signature, the relayer + // knows to ignore the wallet signatures + const stubSignature = wallet.coders.config.buildStubSignature(wallet.config, stubSignatureOverrides) + + // Now we can decorate the transactions as always, but we need to manually build the signed bundle + const intentId = ethers.utils.hexlify(ethers.utils.randomBytes(32)) + const signedBundle: commons.transaction.SignedTransactionBundle = { + chainId, + intent: { + id: intentId, + wallet: this.address + }, + signature: stubSignature, + transactions, + entrypoint: this.address, + nonce: 0 // The relayer also ignored the nonce + } + + const decoratedBundle = await this.decorateTransactions(signedBundle, wstatus) + const data = commons.transaction.encodeBundleExecData(decoratedBundle) + const res = await this.relayer(chainId).getFeeOptionsRaw(decoratedBundle.entrypoint, data, options) + return { ...res, decorated: decoratedBundle } + } + + async prepareTransactions(args: { + txs: commons.transaction.Transactionish + chainId: ethers.BigNumberish + stubSignatureOverrides: Map + simulateForFeeOptions?: boolean + }): Promise { + const status = await this.status(args.chainId) + + const transactions = await this.fillGasLimits(args.txs, args.chainId, status) + const gasRefundQuote = await this.gasRefundQuotes(transactions, args.chainId, args.stubSignatureOverrides, status, { + simulate: args.simulateForFeeOptions + }) + const flatDecorated = commons.transaction.unwind(this.address, gasRefundQuote.decorated.transactions) + + return { + transactions, + flatDecorated, + feeOptions: gasRefundQuote.options, + feeQuote: gasRefundQuote.quote + } + } + + async sendTransaction( + txs: commons.transaction.Transactionish, + chainId: ethers.BigNumberish, + quote?: FeeQuote, + skipPreDecorate: boolean = false, + callback?: (bundle: commons.transaction.IntendedTransactionBundle) => void, + options?: { + nonceSpace?: ethers.BigNumberish + serial?: boolean + } + ): Promise { + const status = await this.status(chainId) + + const predecorated = skipPreDecorate ? txs : await this.predecorateTransactions(txs, status, chainId) + const hasTxs = commons.transaction.fromTransactionish(this.address, predecorated).length > 0 + const signed = hasTxs ? await this.signTransactions(predecorated, chainId, undefined, options) : undefined + + const childBundles = await this.orchestrator.predecorateSignedTransactions({ chainId }) + + const bundles: commons.transaction.SignedTransactionBundle[] = [] + if (signed !== undefined && signed.transactions.length > 0) { + bundles.push(signed) + } + bundles.push(...childBundles.filter(b => b.transactions.length > 0)) + + return this.sendSignedTransactions(bundles, chainId, quote, undefined, callback) + } + + async signTypedData( + domain: TypedDataDomain, + types: Record>, + message: Record, + chainId: ethers.BigNumberish, + cantValidateBehavior: 'ignore' | 'eip6492' | 'throw' = 'ignore' + ): Promise { + const digest = encodeTypedDataDigest({ domain, types, message }) + return this.signDigest(digest, chainId, true, cantValidateBehavior) + } + + async getSigners(): Promise> { + const last = (ts: T[]): T | undefined => (ts.length ? ts[ts.length - 1] : undefined) + + return ( + await Promise.all( + this.networks.map(async ({ chainId, name }) => { + try { + const status = await this.status(chainId) + + let latestImageHash = last(status.presignedConfigurations)?.nextImageHash + if (!latestImageHash) { + if (status.onChain.version !== status.version) { + const migration = last(status.signedMigrations) + if (migration) { + const { toVersion, toConfig } = migration + const coder = universal.genericCoderFor(toVersion) + latestImageHash = coder.config.imageHashOf(toConfig) + } + } + } + if (!latestImageHash) { + latestImageHash = status.onChain.imageHash + } + + const latestConfig = await this.tracker.configOfImageHash({ imageHash: latestImageHash }) + if (!latestConfig) { + throw new Error(`unable to find config for image hash ${latestImageHash}`) + } + + const coder = universal.genericCoderFor(latestConfig.version) + const signers = coder.config.signersOf(latestConfig) + + return signers.map(signer => ({ ...signer, network: chainId })) + } catch (error) { + console.warn(`unable to get signers on network ${chainId} ${name}`, error) + return [] + } + }) + ) + ).flat() + } + + async getAllSigners(): Promise< + { + address: string + weight: number + network: number + flaggedForRemoval: boolean + }[] + > { + const allSigners: { + address: string + weight: number + network: number + flaggedForRemoval: boolean + }[] = [] + + // We need to get the signers for each status + await Promise.all( + this.networks.map(async network => { + const chainId = network.chainId + + // Getting the status with `longestPath` set to true will give us all the possible configurations + // between the current onChain config and the latest config, including the ones "flagged for removal" + const status = await this.status(chainId, true) + + const fullChain = [ + status.onChain.imageHash, + ...(status.onChain.version !== status.version + ? status.signedMigrations.map(m => universal.coderFor(m.toVersion).config.imageHashOf(m.toConfig as any)) + : []), + ...status.presignedConfigurations.map(update => update.nextImageHash) + ] + + return Promise.all( + fullChain.map(async (nextImageHash, iconf) => { + const isLast = iconf === fullChain.length - 1 + const config = await this.tracker.configOfImageHash({ imageHash: nextImageHash }) + + if (!config) { + console.warn(`AllSigners may be incomplete, config not found for imageHash ${nextImageHash}`) + return + } + + const coder = universal.genericCoderFor(config.version) + const signers = coder.config.signersOf(config) + + signers.forEach(signer => { + const exists = allSigners.find(s => s.address === signer.address && s.network === chainId) + + if (exists && isLast && exists.flaggedForRemoval) { + exists.flaggedForRemoval = false + return + } + + if (exists) return + + allSigners.push({ + address: signer.address, + weight: signer.weight, + network: chainId, + flaggedForRemoval: !isLast + }) + }) + }) + ) + }) + ) + + return allSigners + } +} + +export function isAccount(value: any): value is Account { + return value instanceof Account +} diff --git a/packages/account/src/index.ts b/packages/account/src/index.ts new file mode 100644 index 0000000000..8a695b2e25 --- /dev/null +++ b/packages/account/src/index.ts @@ -0,0 +1 @@ +export * from './account' diff --git a/packages/account/src/orchestrator/wrapper.ts b/packages/account/src/orchestrator/wrapper.ts new file mode 100644 index 0000000000..ab9e16c3fd --- /dev/null +++ b/packages/account/src/orchestrator/wrapper.ts @@ -0,0 +1,69 @@ +import { commons } from '@0xsequence/core' +import { signers, Status } from '@0xsequence/signhub' +import { ethers } from 'ethers' +import { Account } from '../account' + +export type MetadataWithChainId = { + chainId: ethers.BigNumberish +} + +// Implements a wrapper for using Sequence accounts as nested signers in the signhub orchestrator. +export class AccountOrchestratorWrapper implements signers.SapientSigner { + constructor(public account: Account) {} + + async getAddress(): Promise { + return this.account.address + } + + getChainIdFromMetadata(metadata: object): ethers.BigNumber { + try { + const { chainId } = metadata as MetadataWithChainId + return ethers.BigNumber.from(chainId) + } catch (err) { + // Invalid metadata object + throw new Error('AccountOrchestratorWrapper only supports metadata with chain id') + } + } + + async buildDeployTransaction(metadata: object): Promise { + const chainId = this.getChainIdFromMetadata(metadata) + const status = await this.account.status(chainId) + return this.account.buildBootstrapTransactions(status, chainId) + } + + async predecorateSignedTransactions(metadata: object): Promise { + const chainId = this.getChainIdFromMetadata(metadata) + const status = await this.account.status(chainId) + return this.account.predecorateSignedTransactions(status, chainId) + } + + async decorateTransactions( + bundle: commons.transaction.IntendedTransactionBundle, + metadata: object + ): Promise { + const chainId = this.getChainIdFromMetadata(metadata) + const status = await this.account.status(chainId) + return this.account.decorateTransactions(bundle, status) + } + + sign(message: ethers.utils.BytesLike, metadata: object): Promise { + if (!commons.isWalletSignRequestMetadata(metadata)) { + throw new Error('AccountOrchestratorWrapper only supports wallet metadata requests') + } + + const { chainId, decorate } = metadata + // EIP-6492 not supported on nested signatures + // Default to throw instead of ignore. Ignoring should be explicit + const cantValidateBehavior = metadata.cantValidateBehavior ?? 'throw' + + // For Sequence nested signatures we must use `signDigest` and not `signMessage` + // otherwise the account will hash the digest and the signature will be invalid. + return this.account.signDigest(message, chainId, decorate, cantValidateBehavior, metadata) + } + + notifyStatusChange(_i: string, _s: Status, _m: object): void {} + + suffix(): ethers.utils.BytesLike { + return [3] + } +} diff --git a/packages/account/src/signer.ts b/packages/account/src/signer.ts new file mode 100644 index 0000000000..1ffd1f4fd3 --- /dev/null +++ b/packages/account/src/signer.ts @@ -0,0 +1,223 @@ +import { ChainId } from '@0xsequence/network' +import { Account } from './account' +import { ethers } from 'ethers' +import { commons } from '@0xsequence/core' +import { FeeOption, proto } from '@0xsequence/relayer' +import { isDeferrable } from './utils' + +export type AccountSignerOptions = { + nonceSpace?: ethers.BigNumberish + cantValidateBehavior?: 'ignore' | 'eip6492' | 'throw' + stubSignatureOverrides?: Map + selectFee?: ( + txs: ethers.utils.Deferrable | commons.transaction.Transactionish, + options: FeeOption[] + ) => Promise +} + +function encodeGasRefundTransaction(option?: FeeOption) { + if (!option) return [] + + const value = ethers.BigNumber.from(option.value) + + switch (option.token.type) { + case proto.FeeTokenType.UNKNOWN: + return [ + { + delegateCall: false, + revertOnError: true, + gasLimit: option.gasLimit, + to: option.to, + value: value.toHexString(), + data: '0x' + } + ] + + case proto.FeeTokenType.ERC20_TOKEN: + if (!option.token.contractAddress) { + throw new Error(`No contract address for ERC-20 fee option`) + } + + return [ + { + delegateCall: false, + revertOnError: true, + gasLimit: option.gasLimit, + to: option.token.contractAddress, + value: 0, + data: new ethers.utils.Interface([ + { + constant: false, + inputs: [{ type: 'address' }, { type: 'uint256' }], + name: 'transfer', + outputs: [], + type: 'function' + } + ]).encodeFunctionData('transfer', [option.to, value.toHexString()]) + } + ] + + default: + throw new Error(`Unhandled fee token type ${option.token.type}`) + } +} + +export class AccountSigner implements ethers.Signer { + public readonly _isSigner = true + + constructor( + public account: Account, + public chainId: ChainId, + public readonly options?: AccountSignerOptions + ) {} + + get provider() { + return this.account.providerFor(this.chainId) + } + + async getAddress(): Promise { + return this.account.address + } + + signMessage(message: string | ethers.utils.Bytes): Promise { + return this.account.signMessage(message, this.chainId, this.options?.cantValidateBehavior ?? 'throw') + } + + private async defaultSelectFee( + _txs: ethers.utils.Deferrable | commons.transaction.Transactionish, + options: FeeOption[] + ): Promise { + // If no options, return undefined + if (options.length === 0) return undefined + + // If there are multiple options, try them one by one + // until we find one that satisfies the balance requirement + const balanceOfAbi = [ + { + constant: true, + inputs: [{ type: 'address' }], + name: 'balanceOf', + outputs: [{ type: 'uint256' }], + type: 'function' + } + ] + + for (const option of options) { + if (option.token.type === proto.FeeTokenType.UNKNOWN) { + // Native token + const balance = await this.getBalance() + if (balance.gte(ethers.BigNumber.from(option.value))) { + return option + } + } else if (option.token.contractAddress && option.token.type === proto.FeeTokenType.ERC20_TOKEN) { + // ERC20 token + const token = new ethers.Contract(option.token.contractAddress, balanceOfAbi, this.provider) + const balance = await token.balanceOf(this.account.address) + if (balance.gte(ethers.BigNumber.from(option.value))) { + return option + } + } else { + // Unsupported token type + } + } + + throw new Error('No fee option available - not enough balance') + } + + async sendTransaction( + txsPromise: ethers.utils.Deferrable | commons.transaction.Transactionish, + options?: { + simulateForFeeOptions?: boolean + } + ): Promise { + const txs = isDeferrable(txsPromise) + ? await ethers.utils.resolveProperties(txsPromise as ethers.utils.Deferrable) + : txsPromise + + const prepare = await this.account.prepareTransactions({ + txs, + chainId: this.chainId, + stubSignatureOverrides: this.options?.stubSignatureOverrides ?? new Map(), + simulateForFeeOptions: options?.simulateForFeeOptions + }) + + const selectMethod = this.options?.selectFee ?? this.defaultSelectFee.bind(this) + const feeOption = await selectMethod(txs, prepare.feeOptions) + + const finalTransactions = [...prepare.transactions, ...encodeGasRefundTransaction(feeOption)] + + return this.account.sendTransaction( + finalTransactions, + this.chainId, + prepare.feeQuote, + undefined, + undefined, + this.options?.nonceSpace !== undefined + ? { + nonceSpace: this.options.nonceSpace + } + : undefined + ) as Promise // Will always have a transaction response + } + + getBalance(blockTag?: ethers.providers.BlockTag | undefined): Promise { + return this.provider.getBalance(this.account.address, blockTag) + } + + call( + transaction: ethers.utils.Deferrable, + blockTag?: ethers.providers.BlockTag | undefined + ): Promise { + return this.provider.call(transaction, blockTag) + } + + async resolveName(name: string): Promise { + const res = await this.provider.resolveName(name) + if (!res) throw new Error(`Could not resolve name ${name}`) + return res + } + + connect(_provider: ethers.providers.Provider): ethers.Signer { + throw new Error('Method not implemented.') + } + + signTransaction(transaction: ethers.utils.Deferrable): Promise { + throw new Error('Method not implemented.') + } + + getTransactionCount(blockTag?: ethers.providers.BlockTag | undefined): Promise { + throw new Error('Method not implemented.') + } + + estimateGas(transaction: ethers.utils.Deferrable): Promise { + throw new Error('Method not implemented.') + } + + getChainId(): Promise { + return Promise.resolve(ethers.BigNumber.from(this.chainId).toNumber()) + } + + getGasPrice(): Promise { + throw new Error('Method not implemented.') + } + + getFeeData(): Promise { + throw new Error('Method not implemented.') + } + + checkTransaction( + transaction: ethers.utils.Deferrable + ): ethers.utils.Deferrable { + throw new Error('Method not implemented.') + } + + populateTransaction( + transaction: ethers.utils.Deferrable + ): Promise { + throw new Error('Method not implemented.') + } + + _checkProvider(operation?: string | undefined): void { + throw new Error('Method not implemented.') + } +} diff --git a/packages/account/src/utils.ts b/packages/account/src/utils.ts new file mode 100644 index 0000000000..b8d715ec6c --- /dev/null +++ b/packages/account/src/utils.ts @@ -0,0 +1,14 @@ +import { ethers } from 'ethers' + +function isPromise(value: any): value is Promise { + return !!value && typeof value.then === 'function' +} + +export function isDeferrable(value: any): value is ethers.utils.Deferrable { + // The value is deferrable if any of the properties is a Promises + if (typeof value === 'object') { + return Object.keys(value).some(key => isPromise(value[key])) + } + + return false +} diff --git a/packages/account/tests/account.spec.ts b/packages/account/tests/account.spec.ts new file mode 100644 index 0000000000..056e226861 --- /dev/null +++ b/packages/account/tests/account.spec.ts @@ -0,0 +1,1536 @@ +import { walletContracts } from '@0xsequence/abi' +import { commons, v1, v2 } from '@0xsequence/core' +import { migrator } from '@0xsequence/migration' +import { NetworkConfig } from '@0xsequence/network' +import { LocalRelayer, Relayer } from '@0xsequence/relayer' +import { tracker, trackers } from '@0xsequence/sessions' +import { Orchestrator } from '@0xsequence/signhub' +import * as utils from '@0xsequence/tests' +import { Wallet } from '@0xsequence/wallet' +import * as chai from 'chai' +import chaiAsPromised from 'chai-as-promised' +import { ethers } from 'ethers' +import hardhat from 'hardhat' + +import { Account } from '../src/account' +import { AccountOrchestratorWrapper } from '../src/orchestrator/wrapper' + +const { expect } = chai.use(chaiAsPromised) + +const deterministic = false + +describe('Account', () => { + let provider1: ethers.providers.JsonRpcProvider + let provider2: ethers.providers.JsonRpcProvider + + let signer1: ethers.Signer + let signer2: ethers.Signer + + let contexts: commons.context.VersionedContext + let networks: NetworkConfig[] + + let tracker: tracker.ConfigTracker & migrator.PresignedMigrationTracker + + let defaultArgs: { + contexts: commons.context.VersionedContext + networks: NetworkConfig[] + tracker: tracker.ConfigTracker & migrator.PresignedMigrationTracker + } + + let defaultTx: commons.transaction.Transaction + + const createNestedAccount = async (entropy: string, bootstrapInner = true, bootstrapOuter = true) => { + const signer = randomWallet(entropy) + + const configInner = { + threshold: 1, + checkpoint: Math.floor(now() / 1000), + signers: [{ address: signer.address, weight: 1 }] + } + const accountInner = await Account.new({ + ...defaultArgs, + config: configInner, + orchestrator: new Orchestrator([signer]) + }) + if (bootstrapInner) { + await accountInner.doBootstrap(networks[0].chainId) + } + + const configOuter = { + threshold: 1, + checkpoint: Math.floor(now() / 1000), + signers: [{ address: accountInner.address, weight: 1 }] + } + const accountOuter = await Account.new({ + ...defaultArgs, + config: configOuter, + orchestrator: new Orchestrator([new AccountOrchestratorWrapper(accountInner)]) + }) + if (bootstrapOuter) { + await accountOuter.doBootstrap(networks[0].chainId) + } + + return { signer, accountInner, accountOuter } + } + + const getEth = async (address: string, signer?: ethers.Signer) => { + if (signer === undefined) { + // Do both networks + await getEth(address, signer1) + await getEth(address, signer2) + return + } + // Signer sends the address some ETH for defaultTx use + const tx = await signer.sendTransaction({ + to: address, + value: 10 // Should be plenty + }) + await tx.wait() + } + + before(async () => { + provider1 = new ethers.providers.Web3Provider(hardhat.network.provider as any) + provider2 = new ethers.providers.JsonRpcProvider('http://127.0.0.1:7048') + + // TODO: Implement migrations on local config tracker + tracker = new trackers.local.LocalConfigTracker(provider1) + + signer1 = provider1.getSigner() + signer2 = provider2.getSigner() + + networks = [ + { + chainId: 31337, + name: 'hardhat', + provider: provider1, + rpcUrl: '', + relayer: new LocalRelayer(signer1), + nativeToken: { + symbol: 'ETH', + name: 'Ether', + decimals: 18 + } + }, + { + chainId: 31338, + name: 'hardhat2', + provider: provider2, + rpcUrl: 'http://127.0.0.1:7048', + relayer: new LocalRelayer(signer2), + nativeToken: { + symbol: 'ETH', + name: 'Ether', + decimals: 18 + } + } + ] + + const context1 = utils.context.deploySequenceContexts(signer1) + const context2 = utils.context.deploySequenceContexts(signer2) + expect(await context1).to.deep.equal(await context2) + contexts = await context1 + + defaultArgs = { + contexts, + networks, + tracker + } + + defaultTx = { + to: await signer1.getAddress(), + value: 1 + } + }) + + describe('New account', () => { + it('Should create a new account', async () => { + const signer = randomWallet('Should create a new account') + const config = { + threshold: 1, + checkpoint: Math.floor(now() / 1000), + signers: [{ address: signer.address, weight: 1 }] + } + + const account = await Account.new({ + ...defaultArgs, + config, + orchestrator: new Orchestrator([signer]) + }) + + expect(account).to.be.instanceOf(Account) + expect(account.address).to.not.be.undefined + + await getEth(account.address) + const tx = await account.sendTransaction([defaultTx], networks[0].chainId) + expect(tx).to.not.be.undefined + + const status = await account.status(networks[0].chainId) + expect(status.fullyMigrated).to.be.true + expect(status.onChain.deployed).to.be.true + expect(status.onChain.version).to.equal(2) + }) + + it('Should create new nested accounts', async () => { + const { accountInner, accountOuter } = await createNestedAccount('create new nested accounts', false, false) + + await getEth(accountOuter.address) + await accountOuter.sendTransaction([defaultTx], networks[0].chainId) + + const statusOuter = await accountOuter.status(networks[0].chainId) + + expect(statusOuter.fullyMigrated).to.be.true + expect(statusOuter.onChain.deployed).to.be.true + expect(statusOuter.onChain.version).to.equal(2) + + const statusInner = await accountInner.status(networks[0].chainId) + expect(statusInner.fullyMigrated).to.be.true + expect(statusInner.onChain.deployed).to.be.true + expect(statusInner.onChain.version).to.equal(2) + }) + + it('Should send tx on nested accounts', async () => { + const { accountInner, accountOuter } = await createNestedAccount('sent tx on nested accounts', true, true) + + await getEth(accountOuter.address) + await accountOuter.sendTransaction([defaultTx], networks[0].chainId) + + const statusOuter = await accountOuter.status(networks[0].chainId) + + expect(statusOuter.fullyMigrated).to.be.true + expect(statusOuter.onChain.deployed).to.be.true + expect(statusOuter.onChain.version).to.equal(2) + + const statusInner = await accountInner.status(networks[0].chainId) + expect(statusInner.fullyMigrated).to.be.true + expect(statusInner.onChain.deployed).to.be.true + expect(statusInner.onChain.version).to.equal(2) + }) + + it('Should send transactions on multiple networks', async () => { + const signer = randomWallet('Should send transactions on multiple networks') + const config = { + threshold: 1, + checkpoint: Math.floor(now() / 1000), + signers: [{ address: signer.address, weight: 1 }] + } + + const account = await Account.new({ + ...defaultArgs, + config, + orchestrator: new Orchestrator([signer]) + }) + + await getEth(account.address) + await account.sendTransaction([defaultTx], networks[0].chainId) + await account.sendTransaction([defaultTx], networks[1].chainId) + + const status1 = await account.status(networks[0].chainId) + const status2 = await account.status(networks[1].chainId) + + expect(status1.fullyMigrated).to.be.true + expect(status1.onChain.deployed).to.be.true + expect(status1.onChain.version).to.equal(2) + + expect(status2.fullyMigrated).to.be.true + expect(status2.onChain.deployed).to.be.true + expect(status2.onChain.version).to.equal(2) + }) + + it('Should create a new account with many signers', async () => { + const signers = new Array(24).fill(0).map(() => randomWallet('Should create a new account with many signers')) + const config = { + threshold: 3, + checkpoint: Math.floor(now() / 1000), + signers: signers.map(signer => ({ + address: signer.address, + weight: 1 + })) + } + + const rsigners = signers.sort(() => randomFraction('Should create a new account with many signers 2') - 0.5) + const account = await Account.new({ + ...defaultArgs, + config, + orchestrator: new Orchestrator(rsigners.slice(0, 4)) + }) + + await getEth(account.address) + await account.sendTransaction([defaultTx], networks[0].chainId) + + const status = await account.status(networks[0].chainId) + expect(status.fullyMigrated).to.be.true + expect(status.onChain.deployed).to.be.true + expect(status.onChain.version).to.equal(2) + }) + + it('Should sign and validate a message', async () => { + const signer = randomWallet('Should sign and validate a message') + const config = { + threshold: 1, + checkpoint: Math.floor(now() / 1000), + signers: [{ address: signer.address, weight: 1 }] + } + + const account = await Account.new({ + ...defaultArgs, + config, + orchestrator: new Orchestrator([signer]) + }) + + await account.doBootstrap(networks[0].chainId) + + const msg = ethers.utils.toUtf8Bytes('Hello World') + const sig = await account.signMessage(msg, networks[0].chainId) + + const valid = await commons.EIP1271.isValidEIP1271Signature( + account.address, + ethers.utils.keccak256(msg), + sig, + networks[0].provider! + ) + + expect(valid).to.be.true + }) + + it('Should sign and validate a message with nested account', async () => { + const { accountOuter } = await createNestedAccount('sign and validate nested') + + const msg = ethers.utils.toUtf8Bytes('Hello World') + const sig = await accountOuter.signMessage(msg, networks[0].chainId) + + const valid = await commons.EIP1271.isValidEIP1271Signature( + accountOuter.address, + ethers.utils.keccak256(msg), + sig, + networks[0].provider! + ) + + expect(valid).to.be.true + }) + + it('Should update account to new configuration', async () => { + const signer = randomWallet('Should update account to new configuration') + const simpleConfig1 = { + threshold: 1, + checkpoint: Math.floor(now() / 1000), + signers: [{ address: signer.address, weight: 1 }] + } + const config1 = v2.config.ConfigCoder.fromSimple(simpleConfig1) + + const account = await Account.new({ + ...defaultArgs, + config: simpleConfig1, + orchestrator: new Orchestrator([signer]) + }) + + const signer2a = randomWallet('Should update account to new configuration 2') + const signer2b = randomWallet('Should update account to new configuration 3') + + const simpleConfig2 = { + threshold: 4, + checkpoint: Math.floor(now() / 1000) + 1, + signers: [ + { + address: signer2a.address, + weight: 2 + }, + { + address: signer2b.address, + weight: 2 + } + ] + } + + const config2 = v2.config.ConfigCoder.fromSimple(simpleConfig2) + await account.updateConfig(config2) + + const status2 = await account.status(networks[0].chainId) + expect(status2.fullyMigrated).to.be.true + expect(status2.onChain.deployed).to.be.false + expect(status2.onChain.version).to.equal(2) + expect(status2.onChain.imageHash).to.deep.equal(v2.config.ConfigCoder.imageHashOf(config1)) + expect(status2.imageHash).to.deep.equal(v2.config.ConfigCoder.imageHashOf(config2)) + }) + + it('Should sign and validate a message without being deployed', async () => { + const signer = randomWallet('Should sign and validate a message without being deployed') + const config = { + threshold: 1, + checkpoint: Math.floor(now() / 1000), + signers: [{ address: signer.address, weight: 1 }] + } + + const account = await Account.new({ + ...defaultArgs, + config, + orchestrator: new Orchestrator([signer]) + }) + + const msg = ethers.utils.toUtf8Bytes('Hello World') + const sig = await account.signMessage(msg, networks[0].chainId, 'eip6492') + + const valid = await account.reader(networks[0].chainId).isValidSignature(account.address, ethers.utils.keccak256(msg), sig) + + expect(valid).to.be.true + }) + + it('Should sign and validate a message without being deployed with nested account', async () => { + const { accountOuter } = await createNestedAccount('sign and validate nested undeployed', true, false) + + const msg = ethers.utils.toUtf8Bytes('Hello World') + const sig = await accountOuter.signMessage(msg, networks[0].chainId, 'eip6492') + + const valid = await accountOuter + .reader(networks[0].chainId) + .isValidSignature(accountOuter.address, ethers.utils.keccak256(msg), sig) + + expect(valid).to.be.true + }) + + it('Should sign and validate a message with undeployed nested account and signer', async () => { + // Testing that an undeployed account doesn't error as other signer can satisfy threshold + const signerA = randomWallet('Nested account signer A') + const signerB = randomWallet('Nested account signer B') + + const configInner = { + threshold: 1, + checkpoint: Math.floor(now() / 1000), + signers: [{ address: signerA.address, weight: 1 }] + } + const accountInner = await Account.new({ + ...defaultArgs, + config: configInner, + orchestrator: new Orchestrator([signerA]) + }) // Undeployed + + const configOuter = { + threshold: 1, + checkpoint: Math.floor(now() / 1000), + signers: [ + { address: accountInner.address, weight: 1 }, + { address: signerB.address, weight: 1 } + ] + } + const accountOuter = await Account.new({ + ...defaultArgs, + config: configOuter, + orchestrator: new Orchestrator([new AccountOrchestratorWrapper(accountInner), signerB]) + }) + await accountOuter.doBootstrap(networks[0].chainId) + + const msg = ethers.utils.toUtf8Bytes('Hello World') + const sig = await accountOuter.signMessage(msg, networks[0].chainId) + + const valid = await accountOuter + .reader(networks[0].chainId) + .isValidSignature(accountOuter.address, ethers.utils.keccak256(msg), sig) + + expect(valid).to.be.true + }) + + it('Should refuse to sign when not deployed', async () => { + const signer = randomWallet('Should refuse to sign when not deployed') + const config = { + threshold: 1, + checkpoint: Math.floor(now() / 1000), + signers: [{ address: signer.address, weight: 1 }] + } + + const account = await Account.new({ + ...defaultArgs, + config, + orchestrator: new Orchestrator([signer]) + }) + + const msg = ethers.utils.toUtf8Bytes('Hello World') + const sig = account.signMessage(msg, networks[0].chainId, 'throw') + + expect(sig).to.be.rejected + }) + + it('Should refuse to sign when not deployed (nested)', async () => { + const { accountOuter } = await createNestedAccount('refuse to sign undeployed', false, false) + + const msg = ethers.utils.toUtf8Bytes('Hello World') + const sig = accountOuter.signMessage(msg, networks[0].chainId, 'eip6492') // Note EIP-6492 throws when nested not deployed + + expect(sig).to.be.rejected + }) + + describe('After upgrading', () => { + let account: Account + + let signer1: ethers.Wallet + let signer2a: ethers.Wallet + let signer2b: ethers.Wallet + let signerIndex = 1 + + beforeEach(async () => { + signer1 = randomWallet(`After upgrading ${signerIndex++}`) + const simpleConfig1 = { + threshold: 1, + checkpoint: Math.floor(now() / 1000) + 1, + signers: [{ address: signer1.address, weight: 1 }] + } + + account = await Account.new({ + ...defaultArgs, + config: simpleConfig1, + orchestrator: new Orchestrator([signer1]) + }) + await getEth(account.address) + + signer2a = randomWallet(`After upgrading ${signerIndex++}`) + signer2b = randomWallet(`After upgrading ${signerIndex++}`) + + const simpleConfig2 = { + threshold: 4, + checkpoint: await account.status(0).then(s => ethers.BigNumber.from(s.checkpoint).add(1)), + signers: [ + { + address: signer2a.address, + weight: 2 + }, + { + address: signer2b.address, + weight: 2 + } + ] + } + + const config2 = v2.config.ConfigCoder.fromSimple(simpleConfig2) + await account.updateConfig(config2) + account.setOrchestrator(new Orchestrator([signer2a, signer2b])) + }) + + it('Should send a transaction', async () => { + const tx = await account.sendTransaction([defaultTx], networks[0].chainId) + expect(tx).to.not.be.undefined + + const status = await account.status(networks[0].chainId) + expect(status.fullyMigrated).to.be.true + expect(status.onChain.deployed).to.be.true + expect(status.onChain.imageHash).to.equal(status.imageHash) + }) + + it('Should send a transaction on nested account', async () => { + const configOuter = { + threshold: 1, + checkpoint: Math.floor(now() / 1000), + signers: [{ address: account.address, weight: 1 }] + } + const accountOuter = await Account.new({ + ...defaultArgs, + config: configOuter, + orchestrator: new Orchestrator([new AccountOrchestratorWrapper(account)]) + }) + + await accountOuter.doBootstrap(networks[0].chainId) + + const tx = await accountOuter.sendTransaction([], networks[0].chainId) + expect(tx).to.not.be.undefined + + const statusOuter = await accountOuter.status(networks[0].chainId) + expect(statusOuter.fullyMigrated).to.be.true + expect(statusOuter.onChain.deployed).to.be.true + expect(statusOuter.onChain.imageHash).to.equal(statusOuter.imageHash) + + const status = await account.status(networks[0].chainId) + expect(status.fullyMigrated).to.be.true + expect(status.onChain.deployed).to.be.true + expect(status.onChain.imageHash).to.equal(status.imageHash) + }) + + it('Should send a transaction on undeployed nested account', async () => { + const configOuter = { + threshold: 1, + checkpoint: Math.floor(now() / 1000), + signers: [{ address: account.address, weight: 1 }] + } + const accountOuter = await Account.new({ + ...defaultArgs, + config: configOuter, + orchestrator: new Orchestrator([new AccountOrchestratorWrapper(account)]) + }) + + await getEth(accountOuter.address) + const tx = await accountOuter.sendTransaction([defaultTx], networks[0].chainId) + expect(tx).to.not.be.undefined + + const status = await account.status(networks[0].chainId) + expect(status.fullyMigrated).to.be.true + expect(status.onChain.deployed).to.be.true + expect(status.onChain.imageHash).to.equal(status.imageHash) + }) + + it('Should sign a message', async () => { + const msg = ethers.utils.toUtf8Bytes('Hello World') + const sig = await account.signMessage(msg, networks[0].chainId) + + const canOnchainValidate = await account.status(networks[0].chainId).then(s => s.canOnchainValidate) + expect(canOnchainValidate).to.be.false + await account.doBootstrap(networks[0].chainId) + + const valid = await commons.EIP1271.isValidEIP1271Signature( + account.address, + ethers.utils.keccak256(msg), + sig, + networks[0].provider! + ) + + expect(valid).to.be.true + }) + + it('Should fail to use old signer', async () => { + account.setOrchestrator(new Orchestrator([signer1])) + const tx = account.sendTransaction([defaultTx], networks[0].chainId) + await expect(tx).to.be.rejected + }) + + it('Should send a transaction on a different network', async () => { + const tx = await account.sendTransaction([defaultTx], networks[1].chainId) + expect(tx).to.not.be.undefined + + const status = await account.status(networks[1].chainId) + expect(status.fullyMigrated).to.be.true + expect(status.onChain.deployed).to.be.true + expect(status.onChain.imageHash).to.equal(status.imageHash) + }) + + describe('After reloading the account', () => { + beforeEach(async () => { + account = new Account({ + ...defaultArgs, + address: account.address, + orchestrator: new Orchestrator([signer2a, signer2b]) + }) + await getEth(account.address) + }) + + it('Should send a transaction', async () => { + const tx = await account.sendTransaction([defaultTx], networks[0].chainId) + expect(tx).to.not.be.undefined + + const status = await account.status(networks[0].chainId) + expect(status.fullyMigrated).to.be.true + expect(status.onChain.deployed).to.be.true + expect(status.onChain.imageHash).to.equal(status.imageHash) + }) + + it('Should sign a message', async () => { + const msg = ethers.utils.toUtf8Bytes('Hello World') + const sig = await account.signMessage(msg, networks[0].chainId) + + const canOnchainValidate = await account.status(networks[0].chainId).then(s => s.canOnchainValidate) + expect(canOnchainValidate).to.be.false + await account.doBootstrap(networks[0].chainId) + + const valid = await commons.EIP1271.isValidEIP1271Signature( + account.address, + ethers.utils.keccak256(msg), + sig, + networks[0].provider! + ) + + expect(valid).to.be.true + }) + }) + + describe('After updating the config again', () => { + let signer3a: ethers.Wallet + let signer3b: ethers.Wallet + let signer3c: ethers.Wallet + let signerIndex = 1 + + let config3: v2.config.WalletConfig + + beforeEach(async () => { + signer3a = randomWallet(`After updating the config again ${signerIndex++}`) + signer3b = randomWallet(`After updating the config again ${signerIndex++}`) + signer3c = randomWallet(`After updating the config again ${signerIndex++}`) + + const simpleConfig3 = { + threshold: 5, + checkpoint: await account.status(0).then(s => ethers.BigNumber.from(s.checkpoint).add(1)), + signers: [ + { + address: signer3a.address, + weight: 2 + }, + { + address: signer3b.address, + weight: 2 + }, + { + address: signer3c.address, + weight: 1 + } + ] + } + + config3 = v2.config.ConfigCoder.fromSimple(simpleConfig3) + + await account.updateConfig(config3) + account.setOrchestrator(new Orchestrator([signer3a, signer3b, signer3c])) + }) + + it('Should update account status', async () => { + const status = await account.status(networks[0].chainId) + expect(status.fullyMigrated).to.be.true + expect(status.onChain.deployed).to.be.false + expect(status.imageHash).to.equal(v2.config.ConfigCoder.imageHashOf(config3)) + expect(status.presignedConfigurations.length).to.equal(2) + }) + + it('Should send a transaction', async () => { + const tx = await account.sendTransaction([defaultTx], networks[0].chainId) + expect(tx).to.not.be.undefined + + const status = await account.status(networks[0].chainId) + expect(status.fullyMigrated).to.be.true + expect(status.onChain.deployed).to.be.true + expect(status.onChain.imageHash).to.equal(status.imageHash) + }) + + it('Should sign a message', async () => { + const msg = ethers.utils.toUtf8Bytes('Hello World') + const sig = await account.signMessage(msg, networks[0].chainId) + + const canOnchainValidate = await account.status(networks[0].chainId).then(s => s.canOnchainValidate) + expect(canOnchainValidate).to.be.false + await account.doBootstrap(networks[0].chainId) + + const status = await account.status(networks[0].chainId) + expect(status.onChain.imageHash).to.not.equal(status.imageHash) + + const valid = await commons.EIP1271.isValidEIP1271Signature( + account.address, + ethers.utils.keccak256(msg), + sig, + networks[0].provider! + ) + + expect(valid).to.be.true + }) + }) + + describe('After sending a transaction', () => { + beforeEach(async () => { + await account.sendTransaction([defaultTx], networks[0].chainId) + }) + + it('Should send a transaction in a different network', async () => { + const tx = await account.sendTransaction([defaultTx], networks[1].chainId) + expect(tx).to.not.be.undefined + + const status = await account.status(networks[1].chainId) + expect(status.fullyMigrated).to.be.true + expect(status.onChain.deployed).to.be.true + expect(status.onChain.imageHash).to.equal(status.imageHash) + }) + + it('Should send a second transaction', async () => { + const tx = await account.sendTransaction([defaultTx], networks[0].chainId) + expect(tx).to.not.be.undefined + }) + + let signerIndex = 1 + it('Should update the configuration again', async () => { + const signer2a = randomWallet(`Should update the configuration again ${signerIndex++}`) + const signer2b = randomWallet(`Should update the configuration again ${signerIndex++}`) + const signer2c = randomWallet(`Should update the configuration again ${signerIndex++}`) + + const simpleConfig2 = { + threshold: 6, + checkpoint: await account.status(0).then(s => ethers.BigNumber.from(s.checkpoint).add(1)), + signers: [ + { + address: signer2a.address, + weight: 3 + }, + { + address: signer2b.address, + weight: 3 + }, + { + address: signer2c.address, + weight: 3 + } + ] + } + + const ogOnchainImageHash = await account.status(0).then(s => s.onChain.imageHash) + const imageHash1 = await account.status(0).then(s => s.imageHash) + + const config2 = v2.config.ConfigCoder.fromSimple(simpleConfig2) + await account.updateConfig(config2) + + const status1 = await account.status(networks[0].chainId) + const status2 = await account.status(networks[1].chainId) + + expect(status1.fullyMigrated).to.be.true + expect(status1.onChain.deployed).to.be.true + expect(status1.onChain.imageHash).to.equal(imageHash1) + expect(status1.imageHash).to.equal(v2.config.ConfigCoder.imageHashOf(config2)) + expect(status1.presignedConfigurations.length).to.equal(1) + + expect(status2.fullyMigrated).to.be.true + expect(status2.onChain.deployed).to.be.false + expect(status2.onChain.imageHash).to.equal(ogOnchainImageHash) + expect(status2.imageHash).to.equal(v2.config.ConfigCoder.imageHashOf(config2)) + expect(status2.presignedConfigurations.length).to.equal(2) + }) + }) + }) + }) + + describe('Migrated wallet', () => { + it('Should migrate undeployed account', async () => { + // Old account may be an address that's not even deployed + const signer1 = randomWallet('Should migrate undeployed account') + + const simpleConfig = { + threshold: 1, + checkpoint: 0, + signers: [ + { + address: signer1.address, + weight: 1 + } + ] + } + + const config = v1.config.ConfigCoder.fromSimple(simpleConfig) + const configv2 = v2.config.ConfigCoder.fromSimple(simpleConfig) + + const imageHash = v1.config.ConfigCoder.imageHashOf(config) + const address = commons.context.addressOf(contexts[1], imageHash) + + // Sessions server MUST have information about the old wallet + // in production this is retrieved from SequenceUtils contract + await tracker.saveCounterfactualWallet({ config, context: [contexts[1]] }) + + // Importing the account should work! + const account = new Account({ ...defaultArgs, address, orchestrator: new Orchestrator([signer1]) }) + + const status = await account.status(0) + expect(status.fullyMigrated).to.be.false + expect(status.onChain.deployed).to.be.false + expect(status.onChain.imageHash).to.equal(imageHash) + expect(status.imageHash).to.equal(imageHash) + expect(status.version).to.equal(1) + + // Sending a transaction should fail (not fully migrated) + await getEth(account.address) + await expect(account.sendTransaction([defaultTx], networks[0].chainId)).to.be.rejected + + // Should sign migration using the account + await account.signAllMigrations(c => c) + + const status2 = await account.status(networks[0].chainId) + expect(status2.fullyMigrated).to.be.true + expect(status2.onChain.deployed).to.be.false + expect(status2.onChain.imageHash).to.equal(imageHash) + expect(status2.onChain.version).to.equal(1) + expect(status2.imageHash).to.equal(v2.config.ConfigCoder.imageHashOf(configv2)) + expect(status2.version).to.equal(2) + + // Send a transaction + const tx = await account.sendTransaction([defaultTx], networks[0].chainId) + expect(tx).to.not.be.undefined + + const status3 = await account.status(networks[0].chainId) + expect(status3.fullyMigrated).to.be.true + expect(status3.onChain.deployed).to.be.true + expect(status3.onChain.imageHash).to.equal(v2.config.ConfigCoder.imageHashOf(configv2)) + expect(status3.onChain.version).to.equal(2) + expect(status3.imageHash).to.equal(v2.config.ConfigCoder.imageHashOf(configv2)) + expect(status3.version).to.equal(2) + + // Send another transaction on another chain + const tx2 = await account.sendTransaction([defaultTx], networks[1].chainId) + expect(tx2).to.not.be.undefined + + const status4 = await account.status(networks[1].chainId) + expect(status4.fullyMigrated).to.be.true + expect(status4.onChain.deployed).to.be.true + expect(status4.onChain.imageHash).to.equal(v2.config.ConfigCoder.imageHashOf(configv2)) + expect(status4.onChain.version).to.equal(2) + expect(status4.imageHash).to.equal(v2.config.ConfigCoder.imageHashOf(configv2)) + expect(status4.version).to.equal(2) + }) + + it('Should migrate a half-deployed account', async () => { + // Old account created with 3 signers, and already deployed + // in one of the chains + const signer1 = randomWallet('Should migrate a half-deployed account') + const signer2 = randomWallet('Should migrate a half-deployed account 2') + const signer3 = randomWallet('Should migrate a half-deployed account 3') + + const simpleConfig = { + threshold: 2, + checkpoint: 0, + signers: [ + { + address: signer1.address, + weight: 1 + }, + { + address: signer2.address, + weight: 1 + }, + { + address: signer3.address, + weight: 1 + } + ] + } + + const config = v1.config.ConfigCoder.fromSimple(simpleConfig) + const imageHash = v1.config.ConfigCoder.imageHashOf(config) + const address = commons.context.addressOf(contexts[1], imageHash) + + // Deploy the wallet on network 0 + const deployTx = Wallet.buildDeployTransaction(contexts[1], imageHash) + await (networks[0].relayer! as Relayer).relay({ + ...deployTx, + chainId: networks[0].chainId, + intent: { + id: '0x00', + wallet: address + } + }) + + // Feed all information to sequence-sessions + // (on prod this would be imported from SequenceUtils) + await tracker.saveCounterfactualWallet({ config, context: Object.values(contexts) }) + + // Importing the account should work! + const account = new Account({ + ...defaultArgs, + address, + orchestrator: new Orchestrator([signer1, signer3]) + }) + + // Status on network 0 should be deployed, network 1 not + // both should not be migrated, and use the original imageHash + const status1 = await account.status(networks[0].chainId) + expect(status1.fullyMigrated).to.be.false + expect(status1.onChain.deployed).to.be.true + expect(status1.onChain.imageHash).to.equal(imageHash) + expect(status1.onChain.version).to.equal(1) + expect(status1.imageHash).to.equal(imageHash) + expect(status1.version).to.equal(1) + + const status2 = await account.status(networks[1].chainId) + expect(status2.fullyMigrated).to.be.false + expect(status2.onChain.deployed).to.be.false + expect(status2.onChain.imageHash).to.equal(imageHash) + expect(status2.onChain.version).to.equal(1) + expect(status2.imageHash).to.equal(imageHash) + expect(status2.version).to.equal(1) + + // Signing transactions (on both networks) and signing messages should fail + await getEth(account.address) + await expect(account.sendTransaction([defaultTx], networks[0].chainId)).to.be.rejected + await expect(account.sendTransaction([defaultTx], networks[1].chainId)).to.be.rejected + await expect(account.signMessage('0x00', networks[0].chainId)).to.be.rejected + await expect(account.signMessage('0x00', networks[1].chainId)).to.be.rejected + + await account.signAllMigrations(c => c) + + // Sign a transaction on network 0 and network 1, both should work + // and should take the wallet on-chain up to speed + const configv2 = v2.config.ConfigCoder.fromSimple(simpleConfig) + + const tx1 = await account.sendTransaction([defaultTx], networks[0].chainId) + expect(tx1).to.not.be.undefined + + const status1b = await account.status(networks[0].chainId) + expect(status1b.fullyMigrated).to.be.true + expect(status1b.onChain.deployed).to.be.true + expect(status1b.onChain.imageHash).to.equal(v2.config.ConfigCoder.imageHashOf(configv2)) + expect(status1b.onChain.version).to.equal(2) + expect(status1b.imageHash).to.equal(v2.config.ConfigCoder.imageHashOf(configv2)) + expect(status1b.version).to.equal(2) + + const tx2 = await account.sendTransaction([defaultTx], networks[1].chainId) + expect(tx2).to.not.be.undefined + + const status2b = await account.status(networks[1].chainId) + expect(status2b).to.be.deep.equal(status1b) + }) + + it('Should migrate an upgraded wallet', async () => { + const signer1 = randomWallet('Should migrate an upgraded wallet') + const signer2 = randomWallet('Should migrate an upgraded wallet 2') + const signer3 = randomWallet('Should migrate an upgraded wallet 3') + const signer4 = randomWallet('Should migrate an upgraded wallet 4') + + const simpleConfig1a = { + threshold: 3, + checkpoint: 0, + signers: [ + { + address: signer1.address, + weight: 2 + }, + { + address: signer2.address, + weight: 2 + }, + { + address: signer3.address, + weight: 2 + } + ] + } + + const config1a = v1.config.ConfigCoder.fromSimple(simpleConfig1a) + const imageHash1a = v1.config.ConfigCoder.imageHashOf(config1a) + const address = commons.context.addressOf(contexts[1], imageHash1a) + + const simpleConfig1b = { + threshold: 3, + checkpoint: 0, + signers: [ + { + address: signer1.address, + weight: 2 + }, + { + address: signer2.address, + weight: 2 + }, + { + address: signer4.address, + weight: 2 + } + ] + } + + const config1b = v1.config.ConfigCoder.fromSimple(simpleConfig1b) + const imageHash1b = v1.config.ConfigCoder.imageHashOf(config1b) + + // Update wallet to config 1b (on network 0) + const wallet = new Wallet({ + coders: { + signature: v1.signature.SignatureCoder, + config: v1.config.ConfigCoder + }, + context: contexts[1], + config: config1a, + chainId: networks[0].chainId, + address, + orchestrator: new Orchestrator([signer1, signer3]), + relayer: (networks[0].relayer as Relayer)!, + provider: networks[0].provider! + }) + + const utx = await wallet.buildUpdateConfigurationTransaction(config1b) + const signed = await wallet.signTransactionBundle(utx) + const decorated = await wallet.decorateTransactions(signed) + await (networks[0].relayer as Relayer).relay(decorated) + + // Importing the account should work! + const account = new Account({ + ...defaultArgs, + address, + orchestrator: new Orchestrator([signer1, signer3]) + }) + + // Feed the tracker with all the data + await tracker.saveCounterfactualWallet({ config: config1a, context: [contexts[1]] }) + await tracker.saveWalletConfig({ config: config1b }) + + // Status on network 0 should be deployed, network 1 not + // and the configuration on network 0 should be the B one + const status1 = await account.status(networks[0].chainId) + expect(status1.fullyMigrated).to.be.false + expect(status1.onChain.deployed).to.be.true + expect(status1.onChain.imageHash).to.equal(imageHash1b) + expect(status1.onChain.version).to.equal(1) + expect(status1.imageHash).to.equal(imageHash1b) + + const status2 = await account.status(networks[1].chainId) + expect(status2.fullyMigrated).to.be.false + expect(status2.onChain.deployed).to.be.false + expect(status2.onChain.imageHash).to.equal(imageHash1a) + expect(status2.onChain.version).to.equal(1) + expect(status2.imageHash).to.equal(imageHash1a) + + // Signing transactions (on both networks) and signing messages should fail + await getEth(account.address) + await expect(account.sendTransaction([defaultTx], networks[0].chainId)).to.be.rejected + await expect(account.sendTransaction([defaultTx], networks[1].chainId)).to.be.rejected + await expect(account.signMessage('0x00', networks[0].chainId)).to.be.rejected + await expect(account.signMessage('0x00', networks[1].chainId)).to.be.rejected + + // Sign all migrations should only have signers1 and 2 + // so the migration should only be available on network 1 (the one not updated) + await account.signAllMigrations(c => c) + + const config2a = v2.config.ConfigCoder.fromSimple(simpleConfig1a) + const config2b = v2.config.ConfigCoder.fromSimple(simpleConfig1b) + const imageHash2a = v2.config.ConfigCoder.imageHashOf(config2a) + + const status1b = await account.status(networks[0].chainId) + expect(status1b.fullyMigrated).to.be.false + expect(status1b.onChain.deployed).to.be.true + expect(status1b.onChain.imageHash).to.equal(imageHash1b) + expect(status1b.onChain.version).to.equal(1) + expect(status1b.imageHash).to.equal(imageHash1b) + expect(status1b.version).to.equal(1) + + const status2b = await account.status(networks[1].chainId) + expect(status2b.fullyMigrated).to.be.true + expect(status2b.onChain.deployed).to.be.false + expect(status2b.onChain.imageHash).to.equal(imageHash1a) + expect(status2b.onChain.version).to.equal(1) + expect(status2b.imageHash).to.equal(imageHash2a) + expect(status2b.version).to.equal(2) + + // Sending a transaction should work for network 1 + // but fail for network 0, same with signing messages + await expect(account.sendTransaction([defaultTx], networks[0].chainId)).to.be.rejected + await expect(account.sendTransaction([defaultTx], networks[1].chainId)).to.be.fulfilled + + await expect(account.signMessage('0x00', networks[0].chainId)).to.be.rejected + await expect(account.signMessage('0x00', networks[1].chainId)).to.be.fulfilled + + // Signing another migration with signers1 and 2 should put both in sync + account.setOrchestrator(new Orchestrator([signer1, signer2])) + await account.signAllMigrations(c => c) + + await expect(account.sendTransaction([defaultTx], networks[0].chainId)).to.be.fulfilled + await expect(account.sendTransaction([defaultTx], networks[1].chainId)).to.be.fulfilled + + await expect(account.signMessage('0x00', networks[0].chainId)).to.be.fulfilled + await expect(account.signMessage('0x00', networks[1].chainId)).to.be.fulfilled + + const status1c = await account.status(networks[0].chainId) + const status2c = await account.status(networks[1].chainId) + + expect(status1c.fullyMigrated).to.be.true + expect(status2c.fullyMigrated).to.be.true + + // Configs are still different! + expect(status1c.imageHash).to.not.equal(status2c.imageHash) + + const simpleConfig4 = { + threshold: 2, + checkpoint: 1, + signers: [ + { + address: signer1.address, + weight: 1 + }, + { + address: signer2.address, + weight: 1 + }, + { + address: signer4.address, + weight: 1 + } + ] + } + + const config4 = v2.config.ConfigCoder.fromSimple(simpleConfig4) + + await account.updateConfig(config4) + + const status1d = await account.status(networks[0].chainId) + const status2d = await account.status(networks[1].chainId) + + // Configs are now the same! + expect(status1d.imageHash).to.be.equal(status2d.imageHash) + }) + + it('Should edit the configuration during the migration', async () => { + // Old account may be an address that's not even deployed + const signer1 = randomWallet('Should edit the configuration during the migration') + const signer2 = randomWallet('Should edit the configuration during the migration 2') + + const simpleConfig1 = { + threshold: 1, + checkpoint: 0, + signers: [ + { + address: signer1.address, + weight: 1 + } + ] + } + + const simpleConfig2 = { + threshold: 1, + checkpoint: 0, + signers: [ + { + address: signer2.address, + weight: 1 + } + ] + } + + const config = v1.config.ConfigCoder.fromSimple(simpleConfig1) + const configv2 = v2.config.ConfigCoder.fromSimple(simpleConfig2) + + const imageHash = v1.config.ConfigCoder.imageHashOf(config) + const address = commons.context.addressOf(contexts[1], imageHash) + + // Sessions server MUST have information about the old wallet + // in production this is retrieved from SequenceUtils contract + await tracker.saveCounterfactualWallet({ config, context: [contexts[1]] }) + + // Importing the account should work! + const orchestrator = new Orchestrator([signer1]) + const account = new Account({ ...defaultArgs, address, orchestrator: orchestrator }) + + const status = await account.status(0) + expect(status.fullyMigrated).to.be.false + expect(status.onChain.deployed).to.be.false + expect(status.onChain.imageHash).to.equal(imageHash) + expect(status.imageHash).to.equal(imageHash) + expect(status.version).to.equal(1) + + // Sending a transaction should fail (not fully migrated) + await getEth(account.address) + await expect(account.sendTransaction([defaultTx], networks[0].chainId)).to.be.rejected + + // Should sign migration using the account + await account.signAllMigrations(c => { + expect(v1.config.ConfigCoder.imageHashOf(c as any)).to.equal(v1.config.ConfigCoder.imageHashOf(config)) + return configv2 + }) + + const status2 = await account.status(networks[0].chainId) + expect(status2.fullyMigrated).to.be.true + expect(status2.onChain.deployed).to.be.false + expect(status2.onChain.imageHash).to.equal(imageHash) + expect(status2.onChain.version).to.equal(1) + expect(status2.imageHash).to.equal(v2.config.ConfigCoder.imageHashOf(configv2)) + expect(status2.version).to.equal(2) + + // Send a transaction + orchestrator.setSigners([signer2]) + const tx = await account.sendTransaction([defaultTx], networks[0].chainId) + expect(tx).to.not.be.undefined + + const status3 = await account.status(networks[0].chainId) + expect(status3.fullyMigrated).to.be.true + expect(status3.onChain.deployed).to.be.true + expect(status3.onChain.imageHash).to.equal(v2.config.ConfigCoder.imageHashOf(configv2)) + expect(status3.onChain.version).to.equal(2) + expect(status3.imageHash).to.equal(v2.config.ConfigCoder.imageHashOf(configv2)) + expect(status3.version).to.equal(2) + + // Send another transaction on another chain + const tx2 = await account.sendTransaction([defaultTx], networks[1].chainId) + expect(tx2).to.not.be.undefined + + const status4 = await account.status(networks[1].chainId) + expect(status4.fullyMigrated).to.be.true + expect(status4.onChain.deployed).to.be.true + expect(status4.onChain.imageHash).to.equal(v2.config.ConfigCoder.imageHashOf(configv2)) + expect(status4.onChain.version).to.equal(2) + expect(status4.imageHash).to.equal(v2.config.ConfigCoder.imageHashOf(configv2)) + expect(status4.version).to.equal(2) + }) + + context('Signing messages', async () => { + context('After migrating', async () => { + let account: Account + let imageHash: string + + beforeEach(async () => { + // Old account may be an address that's not even deployed + const signer1 = randomWallet( + 'Signing messages - After migrating' + account?.address ?? '' // Append prev address to entropy to avoid collisions + ) + + const simpleConfig = { + threshold: 1, + checkpoint: 0, + signers: [ + { + address: signer1.address, + weight: 1 + } + ] + } + + const config = v1.config.ConfigCoder.fromSimple(simpleConfig) + imageHash = v1.config.ConfigCoder.imageHashOf(config) + const address = commons.context.addressOf(contexts[1], imageHash) + + // Sessions server MUST have information about the old wallet + // in production this is retrieved from SequenceUtils contract + await tracker.saveCounterfactualWallet({ config, context: [contexts[1]] }) + + account = new Account({ ...defaultArgs, address, orchestrator: new Orchestrator([signer1]) }) + + // Should sign migration using the account + await account.signAllMigrations(c => c) + }) + + it('Should validate a message signed by undeployed migrated wallet', async () => { + const msg = ethers.utils.toUtf8Bytes('I like that you are reading our tests') + const sig = await account.signMessage(msg, networks[0].chainId, 'eip6492') + + const valid = await account + .reader(networks[0].chainId) + .isValidSignature(account.address, ethers.utils.keccak256(msg), sig) + + expect(valid).to.be.true + }) + + it('Should reject a message signed by undeployed migrated wallet (if set the throw)', async () => { + const msg = ethers.utils.toUtf8Bytes('I do not know what to write here anymore') + const sig = account.signMessage(msg, networks[0].chainId, 'throw') + + await expect(sig).to.be.rejected + }) + + it('Should return an invalid signature by undeployed migrated wallet (if set to ignore)', async () => { + const msg = ethers.utils.toUtf8Bytes('Sending a hug') + const sig = await account.signMessage(msg, networks[0].chainId, 'ignore') + + const valid = await account + .reader(networks[0].chainId) + .isValidSignature(account.address, ethers.utils.keccak256(msg), sig) + + expect(valid).to.be.false + }) + + it('Should validate a message signed by deployed migrated wallet (deployed with v1)', async () => { + const deployTx = Wallet.buildDeployTransaction(contexts[1], imageHash) + await signer1.sendTransaction({ + to: deployTx.entrypoint, + data: commons.transaction.encodeBundleExecData(deployTx) + }) + + expect(await networks[0].provider!.getCode(account.address).then(c => ethers.utils.arrayify(c).length)).to.not.equal(0) + + const msg = ethers.utils.toUtf8Bytes('Everything seems to be working fine so far') + const sig = await account.signMessage(msg, networks[0].chainId, 'eip6492') + + const valid = await account + .reader(networks[0].chainId) + .isValidSignature(account.address, ethers.utils.keccak256(msg), sig) + + expect(valid).to.be.true + }) + + it('Should fail to sign a message signed by deployed migrated wallet (deployed with v1) if throw', async () => { + const deployTx = Wallet.buildDeployTransaction(contexts[1], imageHash) + await signer1.sendTransaction({ + to: deployTx.entrypoint, + data: commons.transaction.encodeBundleExecData(deployTx) + }) + + expect(await networks[0].provider!.getCode(account.address).then(c => ethers.utils.arrayify(c).length)).to.not.equal(0) + + const msg = ethers.utils.toUtf8Bytes('Everything seems to be working fine so far') + const sig = account.signMessage(msg, networks[0].chainId, 'throw') + expect(sig).to.be.rejected + }) + + it('Should return an invalid signature by deployed migrated wallet (deployed with v1) if ignore', async () => { + const deployTx = Wallet.buildDeployTransaction(contexts[1], imageHash) + await signer1.sendTransaction({ + to: deployTx.entrypoint, + data: commons.transaction.encodeBundleExecData(deployTx) + }) + + expect(await networks[0].provider!.getCode(account.address).then(c => ethers.utils.arrayify(c).length)).to.not.equal(0) + + const msg = ethers.utils.toUtf8Bytes('Everything seems to be working fine so far') + const sig = await account.signMessage(msg, networks[0].chainId, 'ignore') + const valid = await account + .reader(networks[0].chainId) + .isValidSignature(account.address, ethers.utils.keccak256(msg), sig) + + expect(valid).to.be.false + }) + }) + }) + }) + + describe('Nonce selection', async () => { + let signer: ethers.Wallet + let account: Account + + let getNonce: (response: ethers.providers.TransactionResponse) => { space: ethers.BigNumber; nonce: ethers.BigNumber } + + before(async () => { + const mainModule = new ethers.utils.Interface(walletContracts.mainModule.abi) + + getNonce = ({ data }) => { + const [_, encoded] = mainModule.decodeFunctionData('execute', data) + const [space, nonce] = commons.transaction.decodeNonce(encoded) + return { space, nonce } + } + + signer = randomWallet('Nonce selection') + + const config = { + threshold: 1, + checkpoint: Math.floor(now() / 1000), + signers: [{ address: signer.address, weight: 1 }] + } + + account = await Account.new({ + ...defaultArgs, + config, + orchestrator: new Orchestrator([signer]) + }) + + // use a deployed account, otherwise we end up testing the decorated bundle nonce + const response = await account.sendTransaction([], networks[0].chainId) + await response?.wait() + + await getEth(account.address, signer1) + await getEth(account.address, signer2) + }) + + it('Should use explicitly set nonces', async () => { + let response = await account.sendTransaction( + { to: await signer1.getAddress(), value: 1 }, + networks[0].chainId, + undefined, + undefined, + undefined, + { nonceSpace: 6492 } + ) + if (!response) { + throw new Error('expected response') + } + + let { space, nonce } = getNonce(response) + + expect(space.eq(6492)).to.be.true + expect(nonce.eq(0)).to.be.true + + await response.wait() + + response = await account.sendTransaction( + { to: await signer1.getAddress(), value: 1 }, + networks[0].chainId, + undefined, + undefined, + undefined, + { nonceSpace: 6492 } + ) + if (!response) { + throw new Error('expected response') + } + + const encoded = getNonce(response) + space = encoded.space + nonce = encoded.nonce + + expect(space.eq(6492)).to.be.true + expect(nonce.eq(1)).to.be.true + }) + + it('Should select random nonces by default', async () => { + let response = await account.sendTransaction({ to: await signer1.getAddress(), value: 1 }, networks[0].chainId) + if (!response) { + throw new Error('expected response') + } + + const { space: firstSpace, nonce: firstNonce } = getNonce(response) + + expect(firstSpace.eq(0)).to.be.false + expect(firstNonce.eq(0)).to.be.true + + // not necessary, parallel execution is ok: + // await response.wait() + + response = await account.sendTransaction({ to: await signer1.getAddress(), value: 1 }, networks[0].chainId) + if (!response) { + throw new Error('expected response') + } + + const { space: secondSpace, nonce: secondNonce } = getNonce(response) + + expect(secondSpace.eq(0)).to.be.false + expect(secondNonce.eq(0)).to.be.true + + expect(secondSpace.eq(firstSpace)).to.be.false + }) + + it('Should respect the serial option', async () => { + let response = await account.sendTransaction( + { to: await signer1.getAddress(), value: 1 }, + networks[0].chainId, + undefined, + undefined, + undefined, + { serial: true } + ) + if (!response) { + throw new Error('expected response') + } + + let { space, nonce } = getNonce(response) + + expect(space.eq(0)).to.be.true + expect(nonce.eq(0)).to.be.true + + await response.wait() + + response = await account.sendTransaction( + { to: await signer1.getAddress(), value: 1 }, + networks[0].chainId, + undefined, + undefined, + undefined, + { serial: true } + ) + if (!response) { + throw new Error('expected response') + } + + const encoded = getNonce(response) + space = encoded.space + nonce = encoded.nonce + + expect(space.eq(0)).to.be.true + expect(nonce.eq(1)).to.be.true + }) + }) +}) + +let nowCalls = 0 +export function now(): number { + if (deterministic) { + return Date.parse('2023-02-14T00:00:00.000Z') + 1000 * nowCalls++ + } else { + return Date.now() + } +} + +export function randomWallet(entropy: number | string): ethers.Wallet { + return new ethers.Wallet(randomBytes(32, entropy)) +} + +export function randomFraction(entropy: number | string): number { + const bytes = randomBytes(7, entropy) + bytes[0] &= 0x1f + return bytes.reduce((sum, byte) => 256 * sum + byte) / Number.MAX_SAFE_INTEGER +} + +export function randomBytes(length: number, entropy: number | string): Uint8Array { + if (deterministic) { + let bytes = '' + while (bytes.length < 2 * length) { + bytes += ethers.utils.id(`${bytes}${entropy}`).slice(2) + } + return ethers.utils.arrayify(`0x${bytes.slice(0, 2 * length)}`) + } else { + return ethers.utils.randomBytes(length) + } +} diff --git a/packages/account/tests/signer.spec.ts b/packages/account/tests/signer.spec.ts new file mode 100644 index 0000000000..cdc8aede44 --- /dev/null +++ b/packages/account/tests/signer.spec.ts @@ -0,0 +1,896 @@ +import { commons, v1, v2 } from '@0xsequence/core' +import { migrator } from '@0xsequence/migration' +import { NetworkConfig } from '@0xsequence/network' +import { FeeOption, FeeQuote, LocalRelayer, LocalRelayerOptions, Relayer, proto } from '@0xsequence/relayer' +import { tracker, trackers } from '@0xsequence/sessions' +import { Orchestrator } from '@0xsequence/signhub' +import * as utils from '@0xsequence/tests' +import { Wallet } from '@0xsequence/wallet' +import * as chai from 'chai' +import chaiAsPromised from 'chai-as-promised' +import { ethers } from 'ethers' +import hardhat from 'hardhat' + +import { Account } from '../src/account' +import { now, randomWallet } from './account.spec' +import { createERC20 } from '@0xsequence/tests/src/tokens/erc20' + +const { expect } = chai.use(chaiAsPromised) + +describe('Account signer', () => { + let provider1: ethers.providers.JsonRpcProvider + let provider2: ethers.providers.JsonRpcProvider + + let signer1: ethers.Signer + let signer2: ethers.Signer + + let contexts: commons.context.VersionedContext + let networks: NetworkConfig[] + + let tracker: tracker.ConfigTracker & migrator.PresignedMigrationTracker + + let defaultArgs: { + contexts: commons.context.VersionedContext + networks: NetworkConfig[] + tracker: tracker.ConfigTracker & migrator.PresignedMigrationTracker + } + + before(async () => { + provider1 = new ethers.providers.Web3Provider(hardhat.network.provider as any) + provider2 = new ethers.providers.JsonRpcProvider('http://127.0.0.1:7048') + + // TODO: Implement migrations on local config tracker + tracker = new trackers.local.LocalConfigTracker(provider1) as any + + networks = [ + { + chainId: 31337, + name: 'hardhat', + provider: provider1, + rpcUrl: '', + relayer: new LocalRelayer(provider1.getSigner()), + nativeToken: { + symbol: 'ETH', + name: 'Ether', + decimals: 18 + } + }, + { + chainId: 31338, + name: 'hardhat2', + provider: provider2, + rpcUrl: 'http://127.0.0.1:7048', + relayer: new LocalRelayer(provider2.getSigner()), + nativeToken: { + symbol: 'ETH', + name: 'Ether', + decimals: 18 + } + } + ] + + signer1 = provider1.getSigner() + signer2 = provider2.getSigner() + + contexts = await utils.context.deploySequenceContexts(signer1) + const context2 = await utils.context.deploySequenceContexts(signer2) + + expect(contexts).to.deep.equal(context2) + + defaultArgs = { + contexts, + networks, + tracker + } + }) + + describe('with new account', () => { + var account: Account + var config: any + var accountSigner: ethers.Wallet + + beforeEach(async () => { + accountSigner = randomWallet('Should create a new account') + config = { + threshold: 1, + checkpoint: Math.floor(now() / 1000), + signers: [{ address: accountSigner.address, weight: 1 }] + } + + account = await Account.new({ + ...defaultArgs, + config, + orchestrator: new Orchestrator([accountSigner]) + }) + }) + ;[31337, 31338].map((chainId: number) => { + context(`for chain ${chainId}`, () => { + it('should send transaction', async () => { + const signer = account.getSigner(chainId) + + const res = await signer.sendTransaction({ + to: ethers.Wallet.createRandom().address + }) + + expect(res).to.exist + expect(res.hash).to.exist + + expect(await signer.provider.getTransaction(res.hash)).to.exist + }) + + it('should send batch transaction', async () => { + const signer = account.getSigner(chainId) + + const res = await signer.sendTransaction([ + { + to: ethers.Wallet.createRandom().address + }, + { + to: ethers.Wallet.createRandom().address + } + ]) + + expect(res).to.exist + expect(res.hash).to.exist + + expect(await signer.provider.getTransaction(res.hash)).to.exist + }) + + it('should send two transactions (one has deploy)', async () => { + const signer = account.getSigner(chainId) + + expect(await signer.provider.getCode(account.address)).to.equal('0x') + + await signer.sendTransaction({ + to: ethers.Wallet.createRandom().address + }) + + expect(await signer.provider.getCode(account.address)).to.not.equal('0x') + + const res = await signer.sendTransaction({ + to: ethers.Wallet.createRandom().address + }) + + expect(res).to.exist + expect(res.hash).to.exist + + expect(await signer.provider.getTransaction(res.hash)).to.exist + }) + + it('should fail to sign message because not deployed', async () => { + const signer = account.getSigner(chainId) + + await expect(signer.signMessage(ethers.utils.randomBytes(32))).to.be.rejectedWith('Wallet cannot validate onchain') + }) + + it('should sign message after deployment', async () => { + const signer = account.getSigner(chainId) + + await signer.sendTransaction({ + to: ethers.Wallet.createRandom().address + }) + + expect(await signer.provider.getCode(account.address)).to.not.equal('0x') + + const signature = await signer.signMessage(ethers.utils.randomBytes(32)) + expect(signature).to.exist + expect(signature).to.not.equal('0x') + }) + + it('should sign a message (undeployed) when using EIP6492', async () => { + const signer = account.getSigner(chainId, { cantValidateBehavior: 'eip6492' }) + + const signature = await signer.signMessage(ethers.utils.randomBytes(32)) + expect(signature).to.exist + expect(signature).to.not.equal('0x') + }) + + it('should return account address', async () => { + expect(account.address).to.equal(await account.getSigner(chainId).getAddress()) + }) + + it('should return chainId', async () => { + expect(chainId).to.equal(await account.getSigner(chainId).getChainId()) + }) + + it('should call select fee even if there is no fee', async () => { + let callsToSelectFee = 0 + + const tx = { + to: ethers.Wallet.createRandom().address + } + + const signer = account.getSigner(chainId, { + selectFee: async (txs: any, options: FeeOption[]) => { + callsToSelectFee++ + expect(txs).to.deep.equal(tx) + expect(options).to.deep.equal([]) + return undefined + } + }) + + const res = await signer.sendTransaction(tx) + + expect(callsToSelectFee).to.equal(1) + + expect(res).to.exist + expect(res.hash).to.exist + + expect(await signer.provider.getTransaction(res.hash)).to.exist + }) + + describe('select fee', () => { + var account: never + var getAccount: (feeOptions: FeeOption[], feeQuote: FeeQuote) => Promise + + beforeEach(async () => { + class LocalRelayerWithFee extends LocalRelayer { + constructor( + options: LocalRelayerOptions | ethers.Signer, + public feeOptions: FeeOption[], + public quote: FeeQuote + ) { + super(options) + } + + async getFeeOptions( + _address: string, + ..._transactions: commons.transaction.Transaction[] + ): Promise<{ options: FeeOption[] }> { + return { options: this.feeOptions, quote: this.quote } as any + } + + async getFeeOptionsRaw( + _entrypoint: string, + _data: ethers.utils.BytesLike, + _options?: { simulate?: boolean } + ): Promise<{ options: FeeOption[] }> { + return { options: this.feeOptions, quote: this.quote } as any + } + + async gasRefundOptions( + _address: string, + ..._transactions: commons.transaction.Transaction[] + ): Promise { + return this.feeOptions + } + + async relay( + signedTxs: commons.transaction.IntendedTransactionBundle, + quote?: FeeQuote | undefined, + waitForReceipt?: boolean | undefined + ): Promise> { + expect(quote).to.equal(this.quote) + return super.relay(signedTxs, quote, waitForReceipt) + } + } + + getAccount = async (feeOptions: FeeOption[], feeQuote: FeeQuote) => { + return Account.new({ + ...defaultArgs, + networks: defaultArgs.networks.map(n => { + return { + ...n, + relayer: new LocalRelayerWithFee(chainId === 31337 ? signer1 : signer2, feeOptions, feeQuote) + } + }), + config, + orchestrator: new Orchestrator([accountSigner]) + }) + } + }) + + it('should automatically select native fee', async () => { + const feeOptions: FeeOption[] = [ + { + token: { + chainId, + name: 'native', + symbol: 'ETH', + type: proto.FeeTokenType.UNKNOWN, + logoURL: '' + }, + to: ethers.Wallet.createRandom().address, + value: '12', + gasLimit: 100000 + } + ] + + const feeQuote: FeeQuote = { + _tag: 'FeeQuote', + _quote: ethers.utils.randomBytes(99) + } + + const account = await getAccount(feeOptions, feeQuote) + const signer = account.getSigner(chainId) + + await (chainId === 31337 ? signer1 : signer2).sendTransaction({ + to: account.address, + value: 12 + }) + + const res = await signer.sendTransaction({ + to: ethers.Wallet.createRandom().address + }) + + expect(res).to.exist + expect(res.hash).to.exist + + expect(await signer.provider.getTransaction(res.hash)).to.exist + }) + + it('should reject if balance is not enough', async () => { + const feeOptions: FeeOption[] = [ + { + token: { + chainId, + name: 'native', + symbol: 'ETH', + type: proto.FeeTokenType.UNKNOWN, + logoURL: '' + }, + to: ethers.Wallet.createRandom().address, + value: ethers.utils.parseEther('12').toString(), + gasLimit: 100000 + } + ] + + const feeQuote: FeeQuote = { + _tag: 'FeeQuote', + _quote: ethers.utils.randomBytes(99) + } + + const account = await getAccount(feeOptions, feeQuote) + const signer = account.getSigner(chainId) + + await (chainId === 31337 ? signer1 : signer2).sendTransaction({ + to: account.address, + value: 11 + }) + + const res = signer.sendTransaction({ + to: ethers.Wallet.createRandom().address + }) + + expect(res).to.be.rejectedWith('No fee option available - not enough balance') + }) + + it('should automatically select ERC20 fee', async () => { + const token = await createERC20(chainId === 31337 ? signer1 : signer2, 'Test Token', 'TEST', 18) + + const recipient = ethers.Wallet.createRandom().address + const feeOptions: FeeOption[] = [ + { + token: { + chainId, + name: 'TEST', + symbol: 'TEST', + type: proto.FeeTokenType.ERC20_TOKEN, + logoURL: '', + contractAddress: token.address + }, + to: recipient, + value: ethers.utils.parseEther('250').toString(), + gasLimit: 400000 + } + ] + + const feeQuote: FeeQuote = { + _tag: 'FeeQuote', + _quote: ethers.utils.randomBytes(99) + } + + const account = await getAccount(feeOptions, feeQuote) + const signer = account.getSigner(chainId) + + await token.mint(account.address, ethers.utils.parseEther('6000')) + + const res = await signer.sendTransaction({ + to: ethers.Wallet.createRandom().address + }) + + expect(res).to.exist + expect(res.hash).to.exist + + expect(await signer.provider.getTransaction(res.hash)).to.exist + expect(await token.balanceOf(recipient)).to.deep.equal(ethers.utils.parseEther('250')) + }) + + it('should reject ERC20 fee if not enough balance', async () => { + const token = await createERC20(chainId === 31337 ? signer1 : signer2, 'Test Token', 'TEST', 18) + + const recipient = ethers.Wallet.createRandom().address + const feeOptions: FeeOption[] = [ + { + token: { + chainId, + name: 'TEST', + symbol: 'TEST', + type: proto.FeeTokenType.ERC20_TOKEN, + logoURL: '', + contractAddress: token.address + }, + to: recipient, + value: ethers.utils.parseEther('250').toString(), + gasLimit: 400000 + } + ] + + const feeQuote: FeeQuote = { + _tag: 'FeeQuote', + _quote: ethers.utils.randomBytes(99) + } + + const account = await getAccount(feeOptions, feeQuote) + const signer = account.getSigner(chainId) + + const res = signer.sendTransaction({ + to: ethers.Wallet.createRandom().address + }) + + expect(res).to.be.rejectedWith('No fee option available - not enough balance') + }) + + it('should automatically select ERC20 fee if user has no ETH', async () => { + const token = await createERC20(chainId === 31337 ? signer1 : signer2, 'Test Token', 'TEST', 18) + + const recipient = ethers.Wallet.createRandom().address + const feeOptions: FeeOption[] = [ + { + token: { + chainId, + name: 'native', + symbol: 'ETH', + type: proto.FeeTokenType.UNKNOWN, + logoURL: '' + }, + to: recipient, + value: ethers.utils.parseEther('12').toString(), + gasLimit: 100000 + }, + { + token: { + chainId, + name: 'TEST', + symbol: 'TEST', + type: proto.FeeTokenType.ERC20_TOKEN, + logoURL: '', + contractAddress: token.address + }, + to: recipient, + value: ethers.utils.parseEther('11').toString(), + gasLimit: 400000 + } + ] + + const feeQuote: FeeQuote = { + _tag: 'FeeQuote', + _quote: ethers.utils.randomBytes(99) + } + + const account = await getAccount(feeOptions, feeQuote) + const signer = account.getSigner(chainId) + + await token.mint(account.address, ethers.utils.parseEther('11')) + + const res = await signer.sendTransaction({ + to: ethers.Wallet.createRandom().address + }) + + expect(res).to.exist + expect(res.hash).to.exist + + expect(await signer.provider.getTransaction(res.hash)).to.exist + expect(await token.balanceOf(recipient)).to.deep.equal(ethers.utils.parseEther('11')) + }) + + it('should select fee using callback (first option)', async () => { + const recipient = ethers.Wallet.createRandom().address + + const token = await createERC20(chainId === 31337 ? signer1 : signer2, 'Test Token', 'TEST', 18) + + const feeOptions: FeeOption[] = [ + { + token: { + chainId, + name: 'native', + symbol: 'ETH', + type: proto.FeeTokenType.UNKNOWN, + logoURL: '' + }, + to: recipient, + value: '5', + gasLimit: 100000 + }, + { + token: { + chainId, + name: 'TEST', + symbol: 'TEST', + type: proto.FeeTokenType.ERC20_TOKEN, + logoURL: '', + contractAddress: token.address + }, + to: recipient, + value: ethers.utils.parseEther('11').toString(), + gasLimit: 400000 + } + ] + + const feeQuote: FeeQuote = { + _tag: 'FeeQuote', + _quote: ethers.utils.randomBytes(99) + } + + const account = await getAccount(feeOptions, feeQuote) + const signer = account.getSigner(chainId, { + selectFee: async (_txs: any, options: FeeOption[]) => { + expect(options).to.deep.equal(feeOptions) + return options[0] + } + }) + + await (chainId === 31337 ? signer1 : signer2).sendTransaction({ + to: account.address, + value: 5 + }) + + const res = await signer.sendTransaction({ + to: ethers.Wallet.createRandom().address + }) + + expect(res).to.exist + expect(res.hash).to.exist + + expect(await signer.provider.getTransaction(res.hash)).to.exist + expect(await signer.provider.getBalance(recipient)).to.deep.equal(ethers.BigNumber.from('5')) + expect(await token.balanceOf(recipient)).to.deep.equal(ethers.utils.parseEther('0')) + }) + + it('should select fee using callback (second option)', async () => { + const recipient = ethers.Wallet.createRandom().address + + const token = await createERC20(chainId === 31337 ? signer1 : signer2, 'Test Token', 'TEST', 18) + + const feeOptions: FeeOption[] = [ + { + token: { + chainId, + name: 'native', + symbol: 'ETH', + type: proto.FeeTokenType.UNKNOWN, + logoURL: '' + }, + to: recipient, + value: '5', + gasLimit: 100000 + }, + { + token: { + chainId, + name: 'TEST', + symbol: 'TEST', + type: proto.FeeTokenType.ERC20_TOKEN, + logoURL: '', + contractAddress: token.address + }, + to: recipient, + value: ethers.utils.parseEther('11').toString(), + gasLimit: 400000 + } + ] + + const feeQuote: FeeQuote = { + _tag: 'FeeQuote', + _quote: ethers.utils.randomBytes(99) + } + + const account = await getAccount(feeOptions, feeQuote) + const signer = account.getSigner(chainId, { + selectFee: async (_txs: any, options: FeeOption[]) => { + expect(options).to.deep.equal(feeOptions) + return options[1] + } + }) + + await token.mint(account.address, ethers.utils.parseEther('11')) + + const res = await signer.sendTransaction({ + to: ethers.Wallet.createRandom().address + }) + + expect(res).to.exist + expect(res.hash).to.exist + + expect(await signer.provider.getTransaction(res.hash)).to.exist + expect(await signer.provider.getBalance(recipient)).to.deep.equal(ethers.BigNumber.from('0')) + expect(await token.balanceOf(recipient)).to.deep.equal(ethers.utils.parseEther('11')) + }) + }) + }) + + it('should send transactions on multiple nonce spaces one by one', async () => { + const signer1 = account.getSigner(chainId, { nonceSpace: '0x01' }) + const signer2 = account.getSigner(chainId, { nonceSpace: 2 }) + const randomSpace = ethers.BigNumber.from(ethers.utils.hexlify(ethers.utils.randomBytes(12))) + const signer3 = account.getSigner(chainId, { + nonceSpace: randomSpace + }) + const signer4 = account.getSigner(chainId, { nonceSpace: '0x04' }) + const signer5 = account.getSigner(chainId, { nonceSpace: '0xffffffffffffffffffffffffffffffffffffffff' }) + + await signer1.sendTransaction({ + to: ethers.Wallet.createRandom().address + }) + + await signer2.sendTransaction({ + to: ethers.Wallet.createRandom().address + }) + + await signer3.sendTransaction({ + to: ethers.Wallet.createRandom().address + }) + + await signer4.sendTransaction({ + to: ethers.Wallet.createRandom().address + }) + + await signer5.sendTransaction({ + to: ethers.Wallet.createRandom().address + }) + + // Should have used all spaces + const wallet = account.walletForStatus(chainId, await account.status(chainId)) + + const nonceSpace1 = await wallet.getNonce('0x01').then(r => ethers.BigNumber.from(r)) + expect(nonceSpace1.toString()).to.equal('1') + + const nonceSpace2 = await wallet.getNonce(2).then(r => ethers.BigNumber.from(r)) + expect(nonceSpace2.toString()).to.equal('1') + + const nonceSpace3 = await wallet.getNonce(randomSpace).then(r => ethers.BigNumber.from(r)) + expect(nonceSpace3.toString()).to.equal('1') + + const nonceSpace4 = await wallet.getNonce('0x04').then(r => ethers.BigNumber.from(r)) + expect(nonceSpace4.toString()).to.equal('1') + + const nonceSpace5 = await wallet + .getNonce('0xffffffffffffffffffffffffffffffffffffffff') + .then(r => ethers.BigNumber.from(r)) + expect(nonceSpace5.toString()).to.equal('1') + + // Unused space should have nonce 0 + const nonceSpace6 = await wallet.getNonce('0x06').then(r => ethers.BigNumber.from(r)) + expect(nonceSpace6.toString()).to.equal('0') + + // Using a space should consume it + await signer1.sendTransaction({ + to: ethers.Wallet.createRandom().address + }) + + const nonceSpace1b = await wallet.getNonce('0x01').then(r => ethers.BigNumber.from(r)) + expect(nonceSpace1b.toString()).to.equal('2') + }) + + // Skip if using external network (chainId 31338) + // it randomly fails using node 20, it does not seem to be a bug + // on sequence.js, instead the external node returns empty data when calling + // `getNonce()`, when it should return a value + ;(chainId === 31338 ? describe.skip : describe)('multiple nonce spaces', async () => { + it('should send transactions on multiple nonce spaces at once', async () => { + const signer1 = account.getSigner(chainId, { nonceSpace: '0x01' }) + const signer2 = account.getSigner(chainId, { nonceSpace: 2 }) + const randomSpace = ethers.BigNumber.from(ethers.utils.hexlify(ethers.utils.randomBytes(12))) + const signer3 = account.getSigner(chainId, { + nonceSpace: randomSpace + }) + const signer4 = account.getSigner(chainId, { nonceSpace: '0x04' }) + const signer5 = account.getSigner(chainId, { nonceSpace: '0xffffffffffffffffffffffffffffffffffffffff' }) + + const results = await Promise.all([ + signer1.sendTransaction({ + to: ethers.Wallet.createRandom().address + }), + signer2.sendTransaction({ + to: ethers.Wallet.createRandom().address + }), + signer3.sendTransaction({ + to: ethers.Wallet.createRandom().address + }), + signer4.sendTransaction({ + to: ethers.Wallet.createRandom().address + }), + signer5.sendTransaction({ + to: ethers.Wallet.createRandom().address + }) + ]) + + expect(results).to.have.lengthOf(5) + expect(results[0]).to.exist + expect(results[0].hash).to.exist + expect(results[1]).to.exist + expect(results[1].hash).to.exist + expect(results[2]).to.exist + expect(results[2].hash).to.exist + expect(results[3]).to.exist + expect(results[3].hash).to.exist + expect(results[4]).to.exist + expect(results[4].hash).to.exist + + // hashes should be different + for (let i = 0; i < results.length; i++) { + for (let j = i + 1; j < results.length; j++) { + expect(results[i].hash).to.not.equal(results[j].hash) + } + } + + // Should have used all spaces + const wallet = account.walletForStatus(chainId, await account.status(chainId)) + + const nonceSpace1 = await wallet.getNonce('0x01').then(r => ethers.BigNumber.from(r)) + expect(nonceSpace1.toString()).to.equal('1') + + const nonceSpace2 = await wallet.getNonce(2).then(r => ethers.BigNumber.from(r)) + expect(nonceSpace2.toString()).to.equal('1') + + const nonceSpace3 = await wallet.getNonce(randomSpace).then(r => ethers.BigNumber.from(r)) + expect(nonceSpace3.toString()).to.equal('1') + + const nonceSpace4 = await wallet.getNonce('0x04').then(r => ethers.BigNumber.from(r)) + expect(nonceSpace4.toString()).to.equal('1') + + const nonceSpace5 = await wallet + .getNonce('0xffffffffffffffffffffffffffffffffffffffff') + .then(r => ethers.BigNumber.from(r)) + expect(nonceSpace5.toString()).to.equal('1') + + // Unused space should have nonce 0 + const nonceSpace6 = await wallet.getNonce('0x06').then(r => ethers.BigNumber.from(r)) + expect(nonceSpace6.toString()).to.equal('0') + + // Using a space should consume it + await signer1.sendTransaction({ + to: ethers.Wallet.createRandom().address + }) + + const nonceSpace1b = await wallet.getNonce('0x01').then(r => ethers.BigNumber.from(r)) + expect(nonceSpace1b.toString()).to.equal('2') + }) + + it('should send 100 parallel transactions using different spaces', async () => { + const signers = new Array(100).fill(0).map(() => + account.getSigner(chainId, { + nonceSpace: ethers.BigNumber.from(ethers.utils.hexlify(ethers.utils.randomBytes(12))) + }) + ) + + // Send a random transaction on each one of them + await Promise.all( + signers.map(signer => + signer.sendTransaction({ + to: ethers.Wallet.createRandom().address + }) + ) + ) + + // Send another + await Promise.all( + signers.map(signer => + signer.sendTransaction({ + to: ethers.Wallet.createRandom().address + }) + ) + ) + + /// ... and another + await Promise.all( + signers.map(signer => + signer.sendTransaction({ + to: ethers.Wallet.createRandom().address + }) + ) + ) + }) + + it('should send multiple transactions on multiple nonce spaces at once', async () => { + const signer1 = account.getSigner(chainId, { nonceSpace: '0x01' }) + const signer2 = account.getSigner(chainId, { nonceSpace: 2 }) + const randomSpace = ethers.BigNumber.from(ethers.utils.hexlify(ethers.utils.randomBytes(12))) + + const signer3 = account.getSigner(chainId, { + nonceSpace: randomSpace + }) + const signer4 = account.getSigner(chainId, { nonceSpace: '0x04' }) + const signer5 = account.getSigner(chainId, { nonceSpace: '0xffffffffffffffffffffffffffffffffffffffff' }) + + await Promise.all([ + signer1.sendTransaction({ + to: ethers.Wallet.createRandom().address + }), + signer2.sendTransaction({ + to: ethers.Wallet.createRandom().address + }), + signer3.sendTransaction({ + to: ethers.Wallet.createRandom().address + }), + signer4.sendTransaction({ + to: ethers.Wallet.createRandom().address + }), + signer5.sendTransaction({ + to: ethers.Wallet.createRandom().address + }) + ]) + + const results = await Promise.all([ + signer1.sendTransaction({ + to: ethers.Wallet.createRandom().address + }), + signer2.sendTransaction({ + to: ethers.Wallet.createRandom().address + }), + signer3.sendTransaction({ + to: ethers.Wallet.createRandom().address + }), + signer4.sendTransaction({ + to: ethers.Wallet.createRandom().address + }), + signer5.sendTransaction({ + to: ethers.Wallet.createRandom().address + }) + ]) + + expect(results).to.have.lengthOf(5) + expect(results[0]).to.exist + expect(results[0].hash).to.exist + expect(results[1]).to.exist + expect(results[1].hash).to.exist + expect(results[2]).to.exist + expect(results[2].hash).to.exist + expect(results[3]).to.exist + expect(results[3].hash).to.exist + expect(results[4]).to.exist + expect(results[4].hash).to.exist + + // hashes should be different + for (let i = 0; i < results.length; i++) { + for (let j = i + 1; j < results.length; j++) { + expect(results[i].hash).to.not.equal(results[j].hash) + } + } + + // Should have used all spaces + const wallet = account.walletForStatus(chainId, await account.status(chainId)) + + const nonceSpace2 = await wallet.getNonce(2).then(r => ethers.BigNumber.from(r)) + expect(nonceSpace2.toString()).to.equal('2') + + const nonceSpace1 = await wallet.getNonce('0x01').then(r => ethers.BigNumber.from(r)) + expect(nonceSpace1.toString()).to.equal('2') + + const nonceSpace3 = await wallet.getNonce(randomSpace).then(r => ethers.BigNumber.from(r)) + expect(nonceSpace3.toString()).to.equal('2') + + const nonceSpace4 = await wallet.getNonce('0x04').then(r => ethers.BigNumber.from(r)) + expect(nonceSpace4.toString()).to.equal('2') + + const nonceSpace5 = await wallet + .getNonce('0xffffffffffffffffffffffffffffffffffffffff') + .then(r => ethers.BigNumber.from(r)) + expect(nonceSpace5.toString()).to.equal('2') + + // Unused space should have nonce 0 + const nonceSpace6 = await wallet.getNonce('0x06').then(r => ethers.BigNumber.from(r)) + expect(nonceSpace6.toString()).to.equal('0') + + // Using a space should consume it + await signer1.sendTransaction({ + to: ethers.Wallet.createRandom().address + }) + + const nonceSpace1b = await wallet.getNonce('0x01').then(r => ethers.BigNumber.from(r)) + expect(nonceSpace1b.toString()).to.equal('3') + }) + }) + }) + }) +}) diff --git a/packages/api/CHANGELOG.md b/packages/api/CHANGELOG.md new file mode 100644 index 0000000000..abd71e7933 --- /dev/null +++ b/packages/api/CHANGELOG.md @@ -0,0 +1,1733 @@ +# @0xsequence/api + +## 1.10.8 + +### Patch Changes + +- update metadata bindings + +## 1.10.7 + +### Patch Changes + +- minor fixes to waas client + +## 1.10.6 + +### Patch Changes + +- metadata: update bindings + +## 1.10.5 + +### Patch Changes + +- network: ape-chain-testnet -> apechain-testnet + +## 1.10.4 + +### Patch Changes + +- network: add b3-sepolia, ape-chain-testnet, blast, blast-sepolia + +## 1.10.3 + +### Patch Changes + +- typing fix + +## 1.10.2 + +### Patch Changes + +- - waas: add getIdToken method + - indexer: update api client + +## 1.10.1 + +### Patch Changes + +- metadata: update bindings + +## 1.10.0 + +### Minor Changes + +- waas release v1.3.0 + +## 1.9.37 + +### Patch Changes + +- network: adds nativeToken data to NetworkMetadata constants + +## 1.9.36 + +### Patch Changes + +- guard: export client + +## 1.9.35 + +### Patch Changes + +- guard: update bindings + +## 1.9.34 + +### Patch Changes + +- waas: always use lowercase email + +## 1.9.33 + +### Patch Changes + +- waas: umd build + +## 1.9.32 + +### Patch Changes + +- indexer: update bindings + +## 1.9.31 + +### Patch Changes + +- metadata: token directory changes + +## 1.9.30 + +### Patch Changes + +- update + +## 1.9.29 + +### Patch Changes + +- disable gnosis chain + +## 1.9.28 + +### Patch Changes + +- add utils/merkletree + +## 1.9.27 + +### Patch Changes + +- network: optimistic -> optimism +- waas: remove defaults +- api, sessions: update bindings + +## 1.9.26 + +### Patch Changes + +- - add backend interfaces for pluggable interfaces + - introduce @0xsequence/react-native + - update pnpm to lockfile v9 + +## 1.9.25 + +### Patch Changes + +- update webrpc clients with new error types + +## 1.9.24 + +### Patch Changes + +- waas: add memoryStore backend to localStore + +## 1.9.23 + +### Patch Changes + +- update api client bindings + +## 1.9.22 + +### Patch Changes + +- update metadata client bindings + +## 1.9.21 + +### Patch Changes + +- api client bindings + +## 1.9.20 + +### Patch Changes + +- api client bindings update + +## 1.9.19 + +### Patch Changes + +- waas update + +## 1.9.18 + +### Patch Changes + +- provider: prohibit dangerous functions + +## 1.9.17 + +### Patch Changes + +- network: add xr-sepolia + +## 1.9.16 + +### Patch Changes + +- waas: sequence.feeOptions + +## 1.9.15 + +### Patch Changes + +- metadata: collection external_link field name fix + +## 1.9.14 + +### Patch Changes + +- network: astar-zkatana -> astar-zkyoto +- network: deprecate polygon mumbai network +- network: add xai and polygon amoy + +## 1.9.13 + +### Patch Changes + +- waas: fix @0xsequence/network dependency + +## 1.9.12 + +### Patch Changes + +- indexer: update rpc bindings +- provider: signMessage: Serialize the BytesLike or string message into hexstring before sending +- waas: SessionAuthProof + +## 1.9.11 + +### Patch Changes + +- metdata, update rpc bindings + +## 1.9.10 + +### Patch Changes + +- update metadata rpc bindings + +## 1.9.9 + +### Patch Changes + +- metadata, add SequenceCollections rpc client + +## 1.9.8 + +### Patch Changes + +- waas client update + +## 1.9.7 + +### Patch Changes + +- update rpc client bindings for api, metadata and relayer + +## 1.9.6 + +### Patch Changes + +- waas package update + +## 1.9.5 + +### Patch Changes + +- RpcRelayer prioritize project access key + +## 1.9.4 + +### Patch Changes + +- waas: fix network dependency + +## 1.9.3 + +### Patch Changes + +- provider: don't append access key to RPC url if user has already provided it + +## 1.9.2 + +### Patch Changes + +- network: add xai-sepolia + +## 1.9.1 + +### Patch Changes + +- analytics fix + +## 1.9.0 + +### Minor Changes + +- waas release + +## 1.8.8 + +### Patch Changes + +- update metadata bindings + +## 1.8.7 + +### Patch Changes + +- provider: update databeat to 0.9.1 + +## 1.8.6 + +### Patch Changes + +- guard: SignedOwnershipProof + +## 1.8.5 + +### Patch Changes + +- guard: signOwnershipProof and isSignedOwnershipProof + +## 1.8.4 + +### Patch Changes + +- network: add homeverse to networks list + +## 1.8.3 + +### Patch Changes + +- api: introduce basic linked wallet support + +## 1.8.2 + +### Patch Changes + +- provider: don't initialize analytics unless explicitly requested + +## 1.8.1 + +### Patch Changes + +- update to analytics provider + +## 1.8.0 + +### Minor Changes + +- provider: project analytics + +## 1.7.2 + +### Patch Changes + +- 0xsequence: ChainId should not be exported as a type +- account, wallet: fix nonce selection + +## 1.7.1 + +### Patch Changes + +- network: add missing avalanche logoURI + +## 1.7.0 + +### Minor Changes + +- provider: projectAccessKey is now required + +### Patch Changes + +- network: add NetworkMetadata.logoURI property for all networks + +## 1.6.3 + +### Patch Changes + +- network list update + +## 1.6.2 + +### Patch Changes + +- auth: projectAccessKey option +- wallet: use 12 bytes for random space + +## 1.6.1 + +### Patch Changes + +- core: add simple config from subdigest support +- core: fix encode tree with subdigest +- account: implement buildOnChainSignature on Account + +## 1.6.0 + +### Minor Changes + +- account, wallet: parallel transactions by default + +### Patch Changes + +- provider: emit disconnect on sign out + +## 1.5.0 + +### Minor Changes + +- signhub: add 'signing' signer status + +### Patch Changes + +- auth: Session.open: onAccountAddress callback +- account: allow empty transaction bundles + +## 1.4.9 + +### Patch Changes + +- rename SequenceMetadataClient to SequenceMetadata + +## 1.4.8 + +### Patch Changes + +- account: Account.getSigners + +## 1.4.7 + +### Patch Changes + +- update indexer client bindings + +## 1.4.6 + +### Patch Changes + +- - add sepolia networks, mark goerli as deprecated + - update indexer client bindings + +## 1.4.5 + +### Patch Changes + +- indexer/metadata: update client bindings +- auth: selectWallet with new address + +## 1.4.4 + +### Patch Changes + +- indexer: update bindings +- auth: handle jwt expiry + +## 1.4.3 + +### Patch Changes + +- guard: return active status from GuardSigner.getAuthMethods + +## 1.4.2 + +### Patch Changes + +- guard: update bindings + +## 1.4.1 + +### Patch Changes + +- network: remove unused networks +- signhub: orchestrator interface +- guard: auth methods interface +- guard: update bindings for pin and totp +- guard: no more retry logic + +## 1.4.0 + +### Minor Changes + +- project access key support + +## 1.3.0 + +### Minor Changes + +- signhub: account children + +### Patch Changes + +- guard: do not throw when building deploy transaction +- network: snowtrace.io -> subnets.avax.network/c-chain + +## 1.2.9 + +### Patch Changes + +- account: AccountSigner.sendTransaction simulateForFeeOptions +- relayer: update bindings + +## 1.2.8 + +### Patch Changes + +- rename X-Sequence-Token-Key header to X-Access-Key + +## 1.2.7 + +### Patch Changes + +- add x-sequence-token-key to clients + +## 1.2.6 + +### Patch Changes + +- Fix bind multicall provider + +## 1.2.5 + +### Patch Changes + +- Multicall default configuration fixes + +## 1.2.4 + +### Patch Changes + +- provider: Adding missing payment provider types to PaymentProviderOption +- provider: WalletRequestHandler.notifyChainChanged + +## 1.2.3 + +### Patch Changes + +- auth, provider: connect to accept optional authorizeNonce + +## 1.2.2 + +### Patch Changes + +- provider: allow createContract calls +- core: check for explicit zero address in contract deployments + +## 1.2.1 + +### Patch Changes + +- auth: use sequence api chain id as reference chain id if available + +## 1.2.0 + +### Minor Changes + +- split services from session, better local support + +## 1.1.15 + +### Patch Changes + +- guard: remove error filtering + +## 1.1.14 + +### Patch Changes + +- guard: add GuardSigner.onError + +## 1.1.13 + +### Patch Changes + +- provider: pass client version with connect options +- provider: removing large from BannerSize + +## 1.1.12 + +### Patch Changes + +- provider: adding bannerSize to ConnectOptions + +## 1.1.11 + +### Patch Changes + +- add homeverse configs + +## 1.1.10 + +### Patch Changes + +- handle default EIP6492 on send + +## 1.1.9 + +### Patch Changes + +- Custom default EIP6492 on client + +## 1.1.8 + +### Patch Changes + +- metadata: searchMetadata: add types filter + +## 1.1.7 + +### Patch Changes + +- adding signInWith connect settings option to allow dapps to automatically login their users with a certain provider optimizing the normal authentication flow + +## 1.1.6 + +### Patch Changes + +- metadata: searchMetadata: add chainID and excludeTokenMetadata filters + +## 1.1.5 + +### Patch Changes + +- account: re-compute meta-transaction id for wallet deployment transactions + +## 1.1.4 + +### Patch Changes + +- network: rename base-mainnet to base +- provider: override isDefaultChain with ConnectOptions.networkId if provided + +## 1.1.3 + +### Patch Changes + +- provider: use network id from transport session +- provider: sign authorization using ConnectOptions.networkId if provided + +## 1.1.2 + +### Patch Changes + +- provider: jsonrpc chain id fixes + +## 1.1.1 + +### Patch Changes + +- network: add base mainnet and sepolia +- provider: reject toxic transaction requests + +## 1.1.0 + +### Minor Changes + +- Refactor dapp facing provider + +## 1.0.5 + +### Patch Changes + +- network: export network constants +- guard: use the correct global for fetch +- network: nova-explorer.arbitrum.io -> nova.arbiscan.io + +## 1.0.4 + +### Patch Changes + +- provider: accept name or number for networkId + +## 1.0.3 + +### Patch Changes + +- Simpler isValidSignature helpers + +## 1.0.2 + +### Patch Changes + +- add extra signature validation utils methods + +## 1.0.1 + +### Patch Changes + +- add homeverse testnet + +## 1.0.0 + +### Major Changes + +- https://sequence.xyz/blog/sequence-wallet-light-state-sync-full-merkle-wallets + +## 0.43.34 + +### Patch Changes + +- auth: no jwt for indexer + +## 0.43.33 + +### Patch Changes + +- Adding onConnectOptionsChange handler to WalletRequestHandler + +## 0.43.32 + +### Patch Changes + +- add Base Goerli network + +## 0.43.31 + +### Patch Changes + +- remove AuxDataProvider, add promptSignInConnect + +## 0.43.30 + +### Patch Changes + +- add arbitrum goerli testnet + +## 0.43.29 + +### Patch Changes + +- provider: check availability of window object + +## 0.43.28 + +### Patch Changes + +- update api bindings + +## 0.43.27 + +### Patch Changes + +- Add rpc is sequence method + +## 0.43.26 + +### Patch Changes + +- add zkevm url to enum + +## 0.43.25 + +### Patch Changes + +- added polygon zkevm to mainnet networks + +## 0.43.24 + +### Patch Changes + +- name change from zkevm to polygon-zkevm + +## 0.43.23 + +### Patch Changes + +- update zkEVM name to Polygon zkEVM + +## 0.43.22 + +### Patch Changes + +- add zkevm chain + +## 0.43.21 + +### Patch Changes + +- api: update client bindings + +## 0.43.20 + +### Patch Changes + +- indexer: update bindings + +## 0.43.19 + +### Patch Changes + +- session proof update + +## 0.43.18 + +### Patch Changes + +- rpc client global check, hardening + +## 0.43.17 + +### Patch Changes + +- rpc clients, check of 'global' is defined + +## 0.43.16 + +### Patch Changes + +- ethers peerDep to v5, update rpc client global use + +## 0.43.15 + +### Patch Changes + +- - provider: expand receiver type on some util methods + +## 0.43.14 + +### Patch Changes + +- bump + +## 0.43.13 + +### Patch Changes + +- update rpc bindings + +## 0.43.12 + +### Patch Changes + +- provider: single wallet init, and add new unregisterWallet() method + +## 0.43.11 + +### Patch Changes + +- fix lockfiles +- re-add mocha type deleter + +## 0.43.10 + +### Patch Changes + +- various improvements + +## 0.43.9 + +### Patch Changes + +- update deps + +## 0.43.8 + +### Patch Changes + +- network: JsonRpcProvider with caching + +## 0.43.7 + +### Patch Changes + +- provider: fix wallet network init + +## 0.43.6 + +### Patch Changes + +- metadatata: update rpc bindings + +## 0.43.5 + +### Patch Changes + +- provider: do not set default network for connect messages +- provider: forward missing error message + +## 0.43.4 + +### Patch Changes + +- no-change version bump to fix incorrectly tagged snapshot build + +## 0.43.3 + +### Patch Changes + +- metadata: update bindings + +## 0.43.2 + +### Patch Changes + +- provider: implement connectUnchecked + +## 0.43.1 + +### Patch Changes + +- update to latest ethauth dep + +## 0.43.0 + +### Minor Changes + +- move ethers to a peer dependency + +## 0.42.10 + +### Patch Changes + +- add auxDataProvider + +## 0.42.9 + +### Patch Changes + +- provider: add eip-191 exceptions + +## 0.42.8 + +### Patch Changes + +- provider: skip setting intent origin if we're unity plugin + +## 0.42.7 + +### Patch Changes + +- Add sign in options to connection settings + +## 0.42.6 + +### Patch Changes + +- api bindings update + +## 0.42.5 + +### Patch Changes + +- relayer: don't treat missing receipt as hard failure + +## 0.42.4 + +### Patch Changes + +- provider: add custom app protocol to connect options + +## 0.42.3 + +### Patch Changes + +- update api bindings + +## 0.42.2 + +### Patch Changes + +- disable rinkeby network + +## 0.42.1 + +### Patch Changes + +- wallet: optional waitForReceipt parameter + +## 0.42.0 + +### Minor Changes + +- relayer: estimateGasLimits -> simulate +- add simulator package + +### Patch Changes + +- transactions: fix flattenAuxTransactions +- provider: only filter nullish values +- provider: re-map transaction 'gas' back to 'gasLimit' + +## 0.41.3 + +### Patch Changes + +- api bindings update + +## 0.41.2 + +### Patch Changes + +- api bindings update + +## 0.41.1 + +### Patch Changes + +- update default networks + +## 0.41.0 + +### Minor Changes + +- relayer: fix Relayer.wait() interface + + The interface for calling Relayer.wait() has changed. Instead of a single optional ill-defined timeout/delay parameter, there are three optional parameters, in order: + + - timeout: the maximum time to wait for the transaction receipt + - delay: the polling interval, i.e. the time to wait between requests + - maxFails: the maximum number of hard failures to tolerate before giving up + + Please update your codebase accordingly. + +- relayer: add optional waitForReceipt parameter to Relayer.relay + + The behaviour of Relayer.relay() was not well-defined with respect to whether or not it waited for a receipt. + This change allows the caller to specify whether to wait or not, with the default behaviour being to wait. + +### Patch Changes + +- relayer: wait receipt retry logic +- fix wrapped object error +- provider: forward delegateCall and revertOnError transaction fields + +## 0.40.6 + +### Patch Changes + +- add arbitrum-nova chain + +## 0.40.5 + +### Patch Changes + +- api: update bindings + +## 0.40.4 + +### Patch Changes + +- add unreal transport + +## 0.40.3 + +### Patch Changes + +- provider: fix MessageToSign message type + +## 0.40.2 + +### Patch Changes + +- Wallet provider, loadSession method + +## 0.40.1 + +### Patch Changes + +- export sequence.initWallet and sequence.getWallet + +## 0.40.0 + +### Minor Changes + +- add sequence.initWallet(network, config) and sequence.getWallet() helper methods + +## 0.39.6 + +### Patch Changes + +- indexer: update client bindings + +## 0.39.5 + +### Patch Changes + +- provider: fix networkRpcUrl config option + +## 0.39.4 + +### Patch Changes + +- api: update client bindings + +## 0.39.3 + +### Patch Changes + +- add request method on Web3Provider + +## 0.39.2 + +### Patch Changes + +- update umd name + +## 0.39.1 + +### Patch Changes + +- add Aurora network +- add origin info for accountsChanged event to handle it per dapp + +## 0.39.0 + +### Minor Changes + +- abstract window.localStorage to interface type + +## 0.38.2 + +### Patch Changes + +- provider: add Settings.defaultPurchaseAmount + +## 0.38.1 + +### Patch Changes + +- update api and metadata rpc bindings + +## 0.38.0 + +### Minor Changes + +- api: update bindings, change TokenPrice interface +- bridge: remove @0xsequence/bridge package +- api: update bindings, rename ContractCallArg to TupleComponent + +## 0.37.1 + +### Patch Changes + +- Add back sortNetworks - Removing sorting was a breaking change for dapps on older versions which directly integrate sequence. + +## 0.37.0 + +### Minor Changes + +- network related fixes and improvements +- api: bindings: exchange rate lookups + +## 0.36.13 + +### Patch Changes + +- api: update bindings with new price endpoints + +## 0.36.12 + +### Patch Changes + +- wallet: skip remote signers if not needed +- auth: check that signature meets threshold before requesting auth token + +## 0.36.11 + +### Patch Changes + +- Prefix EIP191 message on wallet-request-handler + +## 0.36.10 + +### Patch Changes + +- support bannerUrl on connect + +## 0.36.9 + +### Patch Changes + +- minor dev xp improvements + +## 0.36.8 + +### Patch Changes + +- more connect options (theme, payment providers, funding currencies) + +## 0.36.7 + +### Patch Changes + +- fix missing break + +## 0.36.6 + +### Patch Changes + +- wallet_switchEthereumChain support + +## 0.36.5 + +### Patch Changes + +- auth: bump ethauth to 0.7.0 + network, wallet: don't assume position of auth network in list + api/indexer/metadata: trim trailing slash on hostname, and add endpoint urls + relayer: Allow to specify local relayer transaction parameters like gas price or gas limit + +## 0.36.4 + +### Patch Changes + +- Updating list of chain ids to include other ethereum compatible chains + +## 0.36.3 + +### Patch Changes + +- provider: pass connect options to prompter methods + +## 0.36.2 + +### Patch Changes + +- transactions: Setting target to 0x0 when empty to during SequenceTxAbiEncode + +## 0.36.1 + +### Patch Changes + +- metadata: update client with more fields + +## 0.36.0 + +### Minor Changes + +- relayer, wallet: fee quote support + +## 0.35.12 + +### Patch Changes + +- provider: rename wallet.commands to wallet.utils + +## 0.35.11 + +### Patch Changes + +- provider/utils: smoother message validation + +## 0.35.10 + +### Patch Changes + +- upgrade deps + +## 0.35.9 + +### Patch Changes + +- provider: window-transport override event handlers with new wallet instance + +## 0.35.8 + +### Patch Changes + +- provider: async wallet sign in improvements + +## 0.35.7 + +### Patch Changes + +- config: cache wallet configs + +## 0.35.6 + +### Patch Changes + +- provider: support async signin of wallet request handler + +## 0.35.5 + +### Patch Changes + +- wallet: skip threshold check during fee estimation + +## 0.35.4 + +### Patch Changes + +- - browser extension mode, center window + +## 0.35.3 + +### Patch Changes + +- - update window position when in browser extension mode + +## 0.35.2 + +### Patch Changes + +- - provider: WindowMessageHandler accept optional windowHref + +## 0.35.1 + +### Patch Changes + +- wallet: update config on undeployed too + +## 0.35.0 + +### Minor Changes + +- - config: add buildStubSignature + - provider: add checks to signing cases for wallet deployment and config statuses + - provider: add prompt for wallet deployment + - relayer: add BaseRelayer.prependWalletDeploy + - relayer: add Relayer.feeOptions + - relayer: account for wallet deployment in fee estimation + - transactions: add fromTransactionish + - wallet: add Account.prependConfigUpdate + - wallet: add Account.getFeeOptions + +## 0.34.0 + +### Minor Changes + +- - upgrade deps + +## 0.33.1 + +### Patch Changes + +- update bindings + +## 0.31.0 + +### Minor Changes + +- - upgrading to ethers v5.5 + +## 0.30.0 + +### Minor Changes + +- - upgrade most deps + +## 0.29.9 + +### Patch Changes + +- update client + +## 0.29.8 + +### Patch Changes + +- update api + +## 0.29.4 + +### Patch Changes + +- api: update rpc bindings + +## 0.29.1 + +### Patch Changes + +- metadata: ContractInfo.decimals is now optional, i.e. may be undefined + + api: new APIs for user storage and isUsingGoogleMail + +## 0.29.0 + +### Minor Changes + +- major architectural changes in Sequence design + + - only one API instance, API is no longer a per-chain service + - separate per-chain indexer service, API no longer handles indexing + - single contract metadata service, API no longer serves metadata + + chaind package has been removed, indexer and metadata packages have been added + + stronger typing with new explicit ChainId type + + multicall fixes and improvements + + forbid "wait" transactions in sendTransactionBatch calls + +## 0.28.0 + +### Minor Changes + +- extension provider + +## 0.27.0 + +### Minor Changes + +- Add requireFreshSigner lib to sessions + +## 0.25.1 + +### Patch Changes + +- Fix build typescrypt issue + +## 0.25.0 + +### Minor Changes + +- 10c8af8: Add estimator package + Fix multicall few calls bug + +## 0.24.0 + +### Minor Changes + +- pass wallet config and nonce to GetMetaTxnNetworkFeeOptions + +## 0.23.0 + +### Minor Changes + +- - relayer: offer variety of gas fee options from the relayer service" + +## 0.22.2 + +### Patch Changes + +- e1c109e: Fix authProof on expired sessions + +## 0.22.1 + +### Patch Changes + +- transport session cache + +## 0.22.0 + +### Minor Changes + +- e667b65: Expose all relayer options on networks + +## 0.21.5 + +### Patch Changes + +- Give priority to metaTxnId returned by relayer + +## 0.21.4 + +### Patch Changes + +- Add has enough signers method + +## 0.21.3 + +### Patch Changes + +- add window session cache + +## 0.21.2 + +### Patch Changes + +- exception handlind in relayer + +## 0.21.0 + +### Minor Changes + +- - fix gas estimation on wallets with large number of signers + - update to session handling and wallet config construction upon auth + +## 0.20.0 + +### Minor Changes + +- revert JWT request piggybacking + +## 0.19.3 + +### Patch Changes + +- jwtAuth visibility, package version sync + +## 0.19.0 + +### Minor Changes + +- - provider, improve dapp / wallet transport io + +## 0.18.0 + +### Minor Changes + +- relayer improvements and pending transaction handling + +## 0.17.0 + +### Minor Changes + +- ArcadeumAPIClient no longer exposes jwtAuth + +## 0.16.1 + +### Patch Changes + +- api: add legacy types for bw compat + +## 0.16.0 + +### Minor Changes + +- relayer as its own service separate from chaind + +## 0.15.1 + +### Patch Changes + +- update api clients + +## 0.15.0 + +### Patch Changes + +- - update chaind and api bindings + - replace EstimateMetaTxnGasReceipt with UpdateMetaTxnGasLimits and GetMetaTxnNetworkFeeOptions + +## 0.14.3 + +### Patch Changes + +- Fix 0xSequence relayer dependencies + +## 0.14.2 + +### Patch Changes + +- Add debug logs to rpc-relayer + +## 0.14.1 + +### Patch Changes + +- update api client + +## 0.14.0 + +### Minor Changes + +- update sequence utils finder which includes optimization + +## 0.13.0 + +### Minor Changes + +- Update SequenceUtils deployed contract + +## 0.12.1 + +### Patch Changes + +- npm bump + +## 0.12.0 + +### Minor Changes + +- provider: improvements to window transport + +## 0.11.4 + +### Patch Changes + +- update api client + +## 0.11.3 + +### Patch Changes + +- improve openWindow state options handling + +## 0.11.2 + +### Patch Changes + +- Fix multicall proxy scopes + +## 0.11.1 + +### Patch Changes + +- Add support for dynamic and nested signatures + +## 0.11.0 + +### Minor Changes + +- Update wallet context to 1.7 contracts + +## 0.10.9 + +### Patch Changes + +- add support for public addresses as signers in session.open + +## 0.10.8 + +### Patch Changes + +- Multicall production configuration + +## 0.10.7 + +### Patch Changes + +- allow provider transport to force disconnect + +## 0.10.6 + +### Patch Changes + +- - fix getWalletState method + +## 0.10.5 + +### Patch Changes + +- update relayer gas refund options + +## 0.10.4 + +### Patch Changes + +- Update api proto + +## 0.10.3 + +### Patch Changes + +- Fix loading config cross-chain + +## 0.10.2 + +### Patch Changes + +- - message digest fix + +## 0.10.1 + +### Patch Changes + +- upgrade deps + +## 0.10.0 + +### Minor Changes + +- Deployed new contracts with ERC1271 signer support + +## 0.9.6 + +### Patch Changes + +- Update ABIs for latest sequence contracts + +## 0.9.5 + +### Patch Changes + +- Implemented session class + +## 0.9.3 + +### Patch Changes + +- - minor improvements + +## 0.9.2 + +### Patch Changes + +- - Update api client + +## 0.9.1 + +### Patch Changes + +- - patch bump + +## 0.9.0 + +### Minor Changes + +- - provider transport hardening + +## 0.8.5 + +### Patch Changes + +- - use latest wallet-contracts + +## 0.8.4 + +### Patch Changes + +- - minor improvements, name updates and comments + +## 0.8.3 + +### Patch Changes + +- - refinements + + - normalize signer address in config + + - provider: getWalletState() method to WalletProvider + +## 0.8.2 + +### Patch Changes + +- - field rename and ethauth dependency bump + +## 0.8.1 + +### Patch Changes + +- - variety of optimizations + +## 0.8.0 + +### Minor Changes + +- - changeset fix + +## 0.7.0 + +### Patch Changes + +- 6f11ed7: sequence.js, init release diff --git a/packages/api/README.md b/packages/api/README.md new file mode 100644 index 0000000000..6ac423e4d9 --- /dev/null +++ b/packages/api/README.md @@ -0,0 +1,4 @@ +@0xsequence/api +=============== + +See [0xsequence project page](https://github.com/0xsequence/sequence.js). diff --git a/packages/services/userdata/eslint.config.js b/packages/api/eslint.config.js similarity index 100% rename from packages/services/userdata/eslint.config.js rename to packages/api/eslint.config.js diff --git a/packages/api/package.json b/packages/api/package.json new file mode 100644 index 0000000000..e46e1fe230 --- /dev/null +++ b/packages/api/package.json @@ -0,0 +1,22 @@ +{ + "name": "@0xsequence/api", + "version": "2.0.0", + "description": "api sub-package for Sequence", + "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/api", + "source": "src/index.ts", + "main": "dist/0xsequence-api.cjs.js", + "module": "dist/0xsequence-api.esm.js", + "author": "Horizon Blockchain Games", + "license": "Apache-2.0", + "scripts": { + "test": "echo", + "typecheck": "tsc --noEmit" + }, + "dependencies": {}, + "peerDependencies": {}, + "devDependencies": {}, + "files": [ + "src", + "dist" + ] +} diff --git a/packages/api/src/api.gen.ts b/packages/api/src/api.gen.ts new file mode 100644 index 0000000000..09dc0423b6 --- /dev/null +++ b/packages/api/src/api.gen.ts @@ -0,0 +1,1745 @@ +/* eslint-disable */ +// sequence-api v0.4.0 da72de09959c34a964bb84662ed6bd510f78f5cb +// -- +// Code generated by webrpc-gen@v0.18.6 with typescript generator. DO NOT EDIT. +// +// webrpc-gen -schema=api.ridl -target=typescript -client -out=./clients/api.gen.ts + +// WebRPC description and code-gen version +export const WebRPCVersion = 'v1' + +// Schema version of your RIDL schema +export const WebRPCSchemaVersion = 'v0.4.0' + +// Schema hash generated from your RIDL schema +export const WebRPCSchemaHash = 'da72de09959c34a964bb84662ed6bd510f78f5cb' + +// +// Types +// + +export enum SortOrder { + DESC = 'DESC', + ASC = 'ASC' +} + +export interface Version { + webrpcVersion: string + schemaVersion: string + schemaHash: string + appVersion: string +} + +export interface RuntimeStatus { + healthOK: boolean + startTime: string + uptime: number + ver: string + branch: string + commitHash: string + checks: RuntimeChecks + numTxnsRelayed: { [key: string]: NumTxnsRelayed } +} + +export interface NumTxnsRelayed { + chainID: number + prev: number + current: number + period: number +} + +export interface RuntimeChecks {} + +export interface SequenceContext { + factory: string + mainModule: string + mainModuleUpgradable: string + guestModule: string + utils: string +} + +export interface User { + address: string + username: string + avatar: string + bio: string + location: string + locale: string + backup?: boolean + backupConfirmed?: boolean + maxInvites?: number + updatedAt?: string + createdAt?: string +} + +export interface WalletBackup { + accountAddress: string + secretHash: string + encryptedWallet: string + userConfirmed: boolean + updatedAt?: string + createdAt?: string +} + +export interface Friend { + id: number + userAddress: string + friendAddress: string + nickname: string + user?: User + createdAt?: string +} + +export interface InviteCode { + usesLeft: number + ownerAccount: string + email?: string + url: string + createdAt?: string + expiresAt?: string +} + +export interface InviteCodeAccount { + claimedByUserAddress: string + claimedAt?: string +} + +export interface InviteInfo { + expiryInHours: number + max: number + invites: Array +} + +export interface ContractCall { + signature: string + function: string + args: Array +} + +export interface TupleComponent { + name?: string + type: string + value: any +} + +export interface Transaction { + delegateCall: boolean + revertOnError: boolean + gasLimit: string + target: string + value: string + data: string + call?: ContractCall +} + +export interface UserStorage { + userAddress: string + key: string + value: any +} + +export interface Token { + chainId: number + contractAddress: string + tokenId?: string +} + +export interface Price { + value: number + currency: string +} + +export interface TokenPrice { + token: Token + price?: Price + price24hChange?: Price + floorPrice: Price + buyPrice: Price + sellPrice: Price + updatedAt: string +} + +export interface ExchangeRate { + name: string + symbol: string + value: number + vsCurrency: string + currencyType: string +} + +export interface LinkedWallet { + id: number + walletAddress: string + linkedWalletAddress: string + createdAt?: string +} + +export interface Page { + pageSize?: number + page?: number + totalRecords?: number + column?: string + before?: any + after?: any + sort?: Array + more?: boolean +} + +export interface SortBy { + column: string + order: SortOrder +} + +export interface NftCheckoutParams { + name: string + imageUrl: string + network: string + recipientAddress: string + blockchainNftId: string + contractAddress: string + quantity: number + decimals?: number +} + +export interface NftCheckout { + token: string + expiresAt: string + orderId: string +} + +export interface SardineOrder { + id: string + createdAt?: string + referenceId: string + status: string + fiatCurrency: string + fiatExchangeRateUSD: number + transactionId: string + expiresAt?: string + total: number + subTotal: number + transactionFee: number + networkFee: number + paymentCurrency?: string + paymentMethodType?: string + transactionType: string + name: string + price: number + imageUrl: string + contractAddress?: string + transactionHash?: string + recipientAddress: string +} + +export interface API { + ping(headers?: object, signal?: AbortSignal): Promise + version(headers?: object, signal?: AbortSignal): Promise + runtimeStatus(headers?: object, signal?: AbortSignal): Promise + clock(headers?: object, signal?: AbortSignal): Promise + getSequenceContext(headers?: object, signal?: AbortSignal): Promise + getAuthToken(args: GetAuthTokenArgs, headers?: object, signal?: AbortSignal): Promise + getAuthToken2(args: GetAuthToken2Args, headers?: object, signal?: AbortSignal): Promise + sendPasswordlessLink( + args: SendPasswordlessLinkArgs, + headers?: object, + signal?: AbortSignal + ): Promise + friendList(args: FriendListArgs, headers?: object, signal?: AbortSignal): Promise + getFriendByAddress(args: GetFriendByAddressArgs, headers?: object, signal?: AbortSignal): Promise + searchFriends(args: SearchFriendsArgs, headers?: object, signal?: AbortSignal): Promise + addFriend(args: AddFriendArgs, headers?: object, signal?: AbortSignal): Promise + updateFriendNickname( + args: UpdateFriendNicknameArgs, + headers?: object, + signal?: AbortSignal + ): Promise + removeFriend(args: RemoveFriendArgs, headers?: object, signal?: AbortSignal): Promise + contractCall(args: ContractCallArgs, headers?: object, signal?: AbortSignal): Promise + decodeContractCall(args: DecodeContractCallArgs, headers?: object, signal?: AbortSignal): Promise + lookupContractCallSelectors( + args: LookupContractCallSelectorsArgs, + headers?: object, + signal?: AbortSignal + ): Promise + userStorageFetch(args: UserStorageFetchArgs, headers?: object, signal?: AbortSignal): Promise + userStorageSave(args: UserStorageSaveArgs, headers?: object, signal?: AbortSignal): Promise + userStorageDelete(args: UserStorageDeleteArgs, headers?: object, signal?: AbortSignal): Promise + userStorageFetchAll(args: UserStorageFetchAllArgs, headers?: object, signal?: AbortSignal): Promise + getMoonpayLink(args: GetMoonpayLinkArgs, headers?: object, signal?: AbortSignal): Promise + getSardineClientToken(headers?: object, signal?: AbortSignal): Promise + getSardineNFTCheckoutToken( + args: GetSardineNFTCheckoutTokenArgs, + headers?: object, + signal?: AbortSignal + ): Promise + getSardineNFTCheckoutOrderStatus( + args: GetSardineNFTCheckoutOrderStatusArgs, + headers?: object, + signal?: AbortSignal + ): Promise + resolveENSAddress(args: ResolveENSAddressArgs, headers?: object, signal?: AbortSignal): Promise + isValidSignature(args: IsValidSignatureArgs, headers?: object, signal?: AbortSignal): Promise + isValidMessageSignature( + args: IsValidMessageSignatureArgs, + headers?: object, + signal?: AbortSignal + ): Promise + isValidTypedDataSignature( + args: IsValidTypedDataSignatureArgs, + headers?: object, + signal?: AbortSignal + ): Promise + isValidETHAuthProof(args: IsValidETHAuthProofArgs, headers?: object, signal?: AbortSignal): Promise + getCoinPrices(args: GetCoinPricesArgs, headers?: object, signal?: AbortSignal): Promise + getCollectiblePrices( + args: GetCollectiblePricesArgs, + headers?: object, + signal?: AbortSignal + ): Promise + getExchangeRate(args: GetExchangeRateArgs, headers?: object, signal?: AbortSignal): Promise + memoryStore(args: MemoryStoreArgs, headers?: object, signal?: AbortSignal): Promise + memoryLoad(args: MemoryLoadArgs, headers?: object, signal?: AbortSignal): Promise + getInviteInfo(headers?: object, signal?: AbortSignal): Promise + isValidAccessCode(args: IsValidAccessCodeArgs, headers?: object, signal?: AbortSignal): Promise + internalClaimAccessCode( + args: InternalClaimAccessCodeArgs, + headers?: object, + signal?: AbortSignal + ): Promise + blockNumberAtTime(args: BlockNumberAtTimeArgs, headers?: object, signal?: AbortSignal): Promise + paperSessionSecret(args: PaperSessionSecretArgs, headers?: object, signal?: AbortSignal): Promise + paperSessionSecret2(args: PaperSessionSecret2Args, headers?: object, signal?: AbortSignal): Promise + linkWallet(args: LinkWalletArgs, headers?: object, signal?: AbortSignal): Promise + getLinkedWallets(args: GetLinkedWalletsArgs, headers?: object, signal?: AbortSignal): Promise +} + +export interface PingArgs {} + +export interface PingReturn { + status: boolean +} +export interface VersionArgs {} + +export interface VersionReturn { + version: Version +} +export interface RuntimeStatusArgs {} + +export interface RuntimeStatusReturn { + status: RuntimeStatus +} +export interface ClockArgs {} + +export interface ClockReturn { + serverTime: string +} +export interface GetSequenceContextArgs {} + +export interface GetSequenceContextReturn { + data: SequenceContext +} +export interface GetAuthTokenArgs { + ewtString: string + testnetMode?: boolean +} + +export interface GetAuthTokenReturn { + status: boolean + jwtToken: string + address: string + user?: User +} +export interface GetAuthToken2Args { + ewtString: string + chainID: string +} + +export interface GetAuthToken2Return { + status: boolean + jwtToken: string + address: string + user?: User +} +export interface SendPasswordlessLinkArgs { + email: string + redirectUri: string + intent: string +} + +export interface SendPasswordlessLinkReturn { + status: boolean +} +export interface FriendListArgs { + nickname?: string + page?: Page +} + +export interface FriendListReturn { + page: Page + friends: Array +} +export interface GetFriendByAddressArgs { + friendAddress: string +} + +export interface GetFriendByAddressReturn { + status: boolean + friend: Friend +} +export interface SearchFriendsArgs { + filterUsername: string + page?: Page +} + +export interface SearchFriendsReturn { + friends: Array +} +export interface AddFriendArgs { + friendAddress: string + optionalNickname?: string +} + +export interface AddFriendReturn { + status: boolean + friend?: Friend +} +export interface UpdateFriendNicknameArgs { + friendAddress: string + nickname: string +} + +export interface UpdateFriendNicknameReturn { + status: boolean + friend?: Friend +} +export interface RemoveFriendArgs { + friendAddress: string +} + +export interface RemoveFriendReturn { + status: boolean +} +export interface ContractCallArgs { + chainID: string + contract: string + inputExpr: string + outputExpr: string + args: Array +} + +export interface ContractCallReturn { + returns: Array +} +export interface DecodeContractCallArgs { + callData: string +} + +export interface DecodeContractCallReturn { + call: ContractCall +} +export interface LookupContractCallSelectorsArgs { + selectors: Array +} + +export interface LookupContractCallSelectorsReturn { + signatures: Array> +} +export interface UserStorageFetchArgs { + key: string +} + +export interface UserStorageFetchReturn { + object: any +} +export interface UserStorageSaveArgs { + key: string + object: any +} + +export interface UserStorageSaveReturn { + ok: boolean +} +export interface UserStorageDeleteArgs { + key: string +} + +export interface UserStorageDeleteReturn { + ok: boolean +} +export interface UserStorageFetchAllArgs { + keys?: Array +} + +export interface UserStorageFetchAllReturn { + objects: { [key: string]: any } +} +export interface GetMoonpayLinkArgs { + url: string +} + +export interface GetMoonpayLinkReturn { + signedUrl: string +} +export interface GetSardineClientTokenArgs {} + +export interface GetSardineClientTokenReturn { + token: string +} +export interface GetSardineNFTCheckoutTokenArgs { + params: NftCheckoutParams +} + +export interface GetSardineNFTCheckoutTokenReturn { + resp: NftCheckout +} +export interface GetSardineNFTCheckoutOrderStatusArgs { + orderId: string +} + +export interface GetSardineNFTCheckoutOrderStatusReturn { + resp: SardineOrder +} +export interface ResolveENSAddressArgs { + ens: string +} + +export interface ResolveENSAddressReturn { + address: string + ok: boolean +} +export interface IsValidSignatureArgs { + chainId: string + walletAddress: string + digest: string + signature: string +} + +export interface IsValidSignatureReturn { + isValid: boolean +} +export interface IsValidMessageSignatureArgs { + chainId: string + walletAddress: string + message: string + signature: string +} + +export interface IsValidMessageSignatureReturn { + isValid: boolean +} +export interface IsValidTypedDataSignatureArgs { + chainId: string + walletAddress: string + typedData: any + signature: string +} + +export interface IsValidTypedDataSignatureReturn { + isValid: boolean +} +export interface IsValidETHAuthProofArgs { + chainId: string + walletAddress: string + ethAuthProofString: string +} + +export interface IsValidETHAuthProofReturn { + isValid: boolean +} +export interface GetCoinPricesArgs { + tokens: Array +} + +export interface GetCoinPricesReturn { + tokenPrices: Array +} +export interface GetCollectiblePricesArgs { + tokens: Array +} + +export interface GetCollectiblePricesReturn { + tokenPrices: Array +} +export interface GetExchangeRateArgs { + toCurrency: string +} + +export interface GetExchangeRateReturn { + exchangeRate: ExchangeRate +} +export interface MemoryStoreArgs { + key: string + value: string +} + +export interface MemoryStoreReturn { + ok: boolean +} +export interface MemoryLoadArgs { + key: string +} + +export interface MemoryLoadReturn { + value: string +} +export interface GetInviteInfoArgs {} + +export interface GetInviteInfoReturn { + inviteInfo: InviteInfo +} +export interface IsValidAccessCodeArgs { + accessCode: string +} + +export interface IsValidAccessCodeReturn { + status: boolean +} +export interface InternalClaimAccessCodeArgs { + address: string + accessCode: string +} + +export interface InternalClaimAccessCodeReturn { + status: boolean +} +export interface BlockNumberAtTimeArgs { + chainId: number + timestamps: Array +} + +export interface BlockNumberAtTimeReturn { + blocks: Array +} +export interface PaperSessionSecretArgs { + chainName: string + contractAddress: string + paramsJson: string + contractType: string +} + +export interface PaperSessionSecretReturn { + secret: string +} +export interface PaperSessionSecret2Args { + chainName: string + contractAddress: string + paramsJson: string + abi: string +} + +export interface PaperSessionSecret2Return { + secret: string +} +export interface LinkWalletArgs { + chainId: string + walletAddress: string + ethAuthProofString: string + linkedWalletMessage: string + linkedWalletSignature: string +} + +export interface LinkWalletReturn { + status: boolean + linkedWalletAddress: string +} +export interface GetLinkedWalletsArgs { + walletAddress: string +} + +export interface GetLinkedWalletsReturn { + linkedWallets: Array +} + +// +// Client +// +export class API implements API { + protected hostname: string + protected fetch: Fetch + protected path = '/rpc/API/' + + constructor(hostname: string, fetch: Fetch) { + this.hostname = hostname + this.fetch = (input: RequestInfo, init?: RequestInit) => fetch(input, init) + } + + private url(name: string): string { + return this.hostname + this.path + name + } + + ping = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('Ping'), createHTTPRequest({}, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + status: _data.status + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + version = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('Version'), createHTTPRequest({}, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + version: _data.version + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + runtimeStatus = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('RuntimeStatus'), createHTTPRequest({}, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + status: _data.status + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + clock = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('Clock'), createHTTPRequest({}, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + serverTime: _data.serverTime + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + getSequenceContext = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetSequenceContext'), createHTTPRequest({}, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + data: _data.data + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + getAuthToken = (args: GetAuthTokenArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetAuthToken'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + status: _data.status, + jwtToken: _data.jwtToken, + address: _data.address, + user: _data.user + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + getAuthToken2 = (args: GetAuthToken2Args, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetAuthToken2'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + status: _data.status, + jwtToken: _data.jwtToken, + address: _data.address, + user: _data.user + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + sendPasswordlessLink = ( + args: SendPasswordlessLinkArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('SendPasswordlessLink'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + status: _data.status + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + friendList = (args: FriendListArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('FriendList'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + page: _data.page, + friends: >_data.friends + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + getFriendByAddress = ( + args: GetFriendByAddressArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetFriendByAddress'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + status: _data.status, + friend: _data.friend + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + searchFriends = (args: SearchFriendsArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('SearchFriends'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + friends: >_data.friends + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + addFriend = (args: AddFriendArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('AddFriend'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + status: _data.status, + friend: _data.friend + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + updateFriendNickname = ( + args: UpdateFriendNicknameArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('UpdateFriendNickname'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + status: _data.status, + friend: _data.friend + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + removeFriend = (args: RemoveFriendArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('RemoveFriend'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + status: _data.status + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + contractCall = (args: ContractCallArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('ContractCall'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + returns: >_data.returns + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + decodeContractCall = ( + args: DecodeContractCallArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('DecodeContractCall'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + call: _data.call + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + lookupContractCallSelectors = ( + args: LookupContractCallSelectorsArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('LookupContractCallSelectors'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + signatures: >>_data.signatures + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + userStorageFetch = (args: UserStorageFetchArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('UserStorageFetch'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + object: _data.object + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + userStorageSave = (args: UserStorageSaveArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('UserStorageSave'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + ok: _data.ok + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + userStorageDelete = (args: UserStorageDeleteArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('UserStorageDelete'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + ok: _data.ok + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + userStorageFetchAll = ( + args: UserStorageFetchAllArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('UserStorageFetchAll'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + objects: <{ [key: string]: any }>_data.objects + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + getMoonpayLink = (args: GetMoonpayLinkArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetMoonpayLink'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + signedUrl: _data.signedUrl + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + getSardineClientToken = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetSardineClientToken'), createHTTPRequest({}, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + token: _data.token + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + getSardineNFTCheckoutToken = ( + args: GetSardineNFTCheckoutTokenArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetSardineNFTCheckoutToken'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + resp: _data.resp + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + getSardineNFTCheckoutOrderStatus = ( + args: GetSardineNFTCheckoutOrderStatusArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetSardineNFTCheckoutOrderStatus'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + resp: _data.resp + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + resolveENSAddress = (args: ResolveENSAddressArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('ResolveENSAddress'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + address: _data.address, + ok: _data.ok + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + isValidSignature = (args: IsValidSignatureArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('IsValidSignature'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + isValid: _data.isValid + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + isValidMessageSignature = ( + args: IsValidMessageSignatureArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('IsValidMessageSignature'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + isValid: _data.isValid + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + isValidTypedDataSignature = ( + args: IsValidTypedDataSignatureArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('IsValidTypedDataSignature'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + isValid: _data.isValid + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + isValidETHAuthProof = ( + args: IsValidETHAuthProofArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('IsValidETHAuthProof'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + isValid: _data.isValid + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + getCoinPrices = (args: GetCoinPricesArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetCoinPrices'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + tokenPrices: >_data.tokenPrices + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + getCollectiblePrices = ( + args: GetCollectiblePricesArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetCollectiblePrices'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + tokenPrices: >_data.tokenPrices + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + getExchangeRate = (args: GetExchangeRateArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetExchangeRate'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + exchangeRate: _data.exchangeRate + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + memoryStore = (args: MemoryStoreArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('MemoryStore'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + ok: _data.ok + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + memoryLoad = (args: MemoryLoadArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('MemoryLoad'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + value: _data.value + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + getInviteInfo = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetInviteInfo'), createHTTPRequest({}, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + inviteInfo: _data.inviteInfo + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + isValidAccessCode = (args: IsValidAccessCodeArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('IsValidAccessCode'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + status: _data.status + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + internalClaimAccessCode = ( + args: InternalClaimAccessCodeArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('InternalClaimAccessCode'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + status: _data.status + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + blockNumberAtTime = (args: BlockNumberAtTimeArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('BlockNumberAtTime'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + blocks: >_data.blocks + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + paperSessionSecret = ( + args: PaperSessionSecretArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('PaperSessionSecret'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + secret: _data.secret + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + paperSessionSecret2 = ( + args: PaperSessionSecret2Args, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('PaperSessionSecret2'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + secret: _data.secret + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + linkWallet = (args: LinkWalletArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('LinkWallet'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + status: _data.status, + linkedWalletAddress: _data.linkedWalletAddress + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + getLinkedWallets = (args: GetLinkedWalletsArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetLinkedWallets'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + linkedWallets: >_data.linkedWallets + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } +} + +const createHTTPRequest = (body: object = {}, headers: object = {}, signal: AbortSignal | null = null): object => { + return { + method: 'POST', + headers: { ...headers, 'Content-Type': 'application/json' }, + body: JSON.stringify(body || {}), + signal + } +} + +const buildResponse = (res: Response): Promise => { + return res.text().then(text => { + let data + try { + data = JSON.parse(text) + } catch (error) { + let message = '' + if (error instanceof Error) { + message = error.message + } + throw WebrpcBadResponseError.new({ + status: res.status, + cause: `JSON.parse(): ${message}: response text: ${text}` + }) + } + if (!res.ok) { + const code: number = typeof data.code === 'number' ? data.code : 0 + throw (webrpcErrorByCode[code] || WebrpcError).new(data) + } + return data + }) +} + +// +// Errors +// + +export class WebrpcError extends Error { + name: string + code: number + message: string + status: number + cause?: string + + /** @deprecated Use message instead of msg. Deprecated in webrpc v0.11.0. */ + msg: string + + constructor(name: string, code: number, message: string, status: number, cause?: string) { + super(message) + this.name = name || 'WebrpcError' + this.code = typeof code === 'number' ? code : 0 + this.message = message || `endpoint error ${this.code}` + this.msg = this.message + this.status = typeof status === 'number' ? status : 0 + this.cause = cause + Object.setPrototypeOf(this, WebrpcError.prototype) + } + + static new(payload: any): WebrpcError { + return new this(payload.error, payload.code, payload.message || payload.msg, payload.status, payload.cause) + } +} + +// Webrpc errors + +export class WebrpcEndpointError extends WebrpcError { + constructor( + name: string = 'WebrpcEndpoint', + code: number = 0, + message: string = 'endpoint error', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcEndpointError.prototype) + } +} + +export class WebrpcRequestFailedError extends WebrpcError { + constructor( + name: string = 'WebrpcRequestFailed', + code: number = -1, + message: string = 'request failed', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcRequestFailedError.prototype) + } +} + +export class WebrpcBadRouteError extends WebrpcError { + constructor( + name: string = 'WebrpcBadRoute', + code: number = -2, + message: string = 'bad route', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadRouteError.prototype) + } +} + +export class WebrpcBadMethodError extends WebrpcError { + constructor( + name: string = 'WebrpcBadMethod', + code: number = -3, + message: string = 'bad method', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadMethodError.prototype) + } +} + +export class WebrpcBadRequestError extends WebrpcError { + constructor( + name: string = 'WebrpcBadRequest', + code: number = -4, + message: string = 'bad request', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadRequestError.prototype) + } +} + +export class WebrpcBadResponseError extends WebrpcError { + constructor( + name: string = 'WebrpcBadResponse', + code: number = -5, + message: string = 'bad response', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadResponseError.prototype) + } +} + +export class WebrpcServerPanicError extends WebrpcError { + constructor( + name: string = 'WebrpcServerPanic', + code: number = -6, + message: string = 'server panic', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcServerPanicError.prototype) + } +} + +export class WebrpcInternalErrorError extends WebrpcError { + constructor( + name: string = 'WebrpcInternalError', + code: number = -7, + message: string = 'internal error', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcInternalErrorError.prototype) + } +} + +export class WebrpcClientDisconnectedError extends WebrpcError { + constructor( + name: string = 'WebrpcClientDisconnected', + code: number = -8, + message: string = 'client disconnected', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcClientDisconnectedError.prototype) + } +} + +export class WebrpcStreamLostError extends WebrpcError { + constructor( + name: string = 'WebrpcStreamLost', + code: number = -9, + message: string = 'stream lost', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcStreamLostError.prototype) + } +} + +export class WebrpcStreamFinishedError extends WebrpcError { + constructor( + name: string = 'WebrpcStreamFinished', + code: number = -10, + message: string = 'stream finished', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcStreamFinishedError.prototype) + } +} + +// Schema errors + +export class UnauthorizedError extends WebrpcError { + constructor( + name: string = 'Unauthorized', + code: number = 1000, + message: string = 'Unauthorized access', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, UnauthorizedError.prototype) + } +} + +export class PermissionDeniedError extends WebrpcError { + constructor( + name: string = 'PermissionDenied', + code: number = 1001, + message: string = 'Permission denied', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, PermissionDeniedError.prototype) + } +} + +export class SessionExpiredError extends WebrpcError { + constructor( + name: string = 'SessionExpired', + code: number = 1002, + message: string = 'Session expired', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, SessionExpiredError.prototype) + } +} + +export class AbortedError extends WebrpcError { + constructor( + name: string = 'Aborted', + code: number = 1005, + message: string = 'Request aborted', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, AbortedError.prototype) + } +} + +export class InvalidArgumentError extends WebrpcError { + constructor( + name: string = 'InvalidArgument', + code: number = 2000, + message: string = 'Invalid argument', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, InvalidArgumentError.prototype) + } +} + +export class UnavailableError extends WebrpcError { + constructor( + name: string = 'Unavailable', + code: number = 2002, + message: string = 'Unavailable resource', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, UnavailableError.prototype) + } +} + +export class QueryFailedError extends WebrpcError { + constructor( + name: string = 'QueryFailed', + code: number = 2003, + message: string = 'Query failed', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, QueryFailedError.prototype) + } +} + +export class NotFoundError extends WebrpcError { + constructor( + name: string = 'NotFound', + code: number = 3000, + message: string = 'Resource not found', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, NotFoundError.prototype) + } +} + +export enum errors { + WebrpcEndpoint = 'WebrpcEndpoint', + WebrpcRequestFailed = 'WebrpcRequestFailed', + WebrpcBadRoute = 'WebrpcBadRoute', + WebrpcBadMethod = 'WebrpcBadMethod', + WebrpcBadRequest = 'WebrpcBadRequest', + WebrpcBadResponse = 'WebrpcBadResponse', + WebrpcServerPanic = 'WebrpcServerPanic', + WebrpcInternalError = 'WebrpcInternalError', + WebrpcClientDisconnected = 'WebrpcClientDisconnected', + WebrpcStreamLost = 'WebrpcStreamLost', + WebrpcStreamFinished = 'WebrpcStreamFinished', + Unauthorized = 'Unauthorized', + PermissionDenied = 'PermissionDenied', + SessionExpired = 'SessionExpired', + Aborted = 'Aborted', + InvalidArgument = 'InvalidArgument', + Unavailable = 'Unavailable', + QueryFailed = 'QueryFailed', + NotFound = 'NotFound' +} + +const webrpcErrorByCode: { [code: number]: any } = { + [0]: WebrpcEndpointError, + [-1]: WebrpcRequestFailedError, + [-2]: WebrpcBadRouteError, + [-3]: WebrpcBadMethodError, + [-4]: WebrpcBadRequestError, + [-5]: WebrpcBadResponseError, + [-6]: WebrpcServerPanicError, + [-7]: WebrpcInternalErrorError, + [-8]: WebrpcClientDisconnectedError, + [-9]: WebrpcStreamLostError, + [-10]: WebrpcStreamFinishedError, + [1000]: UnauthorizedError, + [1001]: PermissionDeniedError, + [1002]: SessionExpiredError, + [1005]: AbortedError, + [2000]: InvalidArgumentError, + [2002]: UnavailableError, + [2003]: QueryFailedError, + [3000]: NotFoundError +} + +export type Fetch = (input: RequestInfo, init?: RequestInit) => Promise diff --git a/packages/api/src/index.ts b/packages/api/src/index.ts new file mode 100644 index 0000000000..63b8559678 --- /dev/null +++ b/packages/api/src/index.ts @@ -0,0 +1,36 @@ +export * from './userdata.gen.js' + +import { UserData as UserdataRpc } from './userdata.gen.js' + +export class SequenceUserdataClient extends UserdataRpc { + constructor( + hostname: string, + public projectAccessKey?: string, + public jwtAuth?: string, + ) { + super(hostname.endsWith('/') ? hostname.slice(0, -1) : hostname, fetch) + this.fetch = this._fetch + } + + _fetch = (input: RequestInfo, init?: RequestInit): Promise => { + // automatically include jwt and access key auth header to requests + // if its been set on the api client + const headers: Record = {} + + const jwtAuth = this.jwtAuth + const projectAccessKey = this.projectAccessKey + + if (jwtAuth && jwtAuth.length > 0) { + headers['Authorization'] = `BEARER ${jwtAuth}` + } + + if (projectAccessKey && projectAccessKey.length > 0) { + headers['X-Access-Key'] = projectAccessKey + } + + // before the request is made + init!.headers = { ...init!.headers, ...headers } + + return fetch(input, init) + } +} diff --git a/packages/auth/CHANGELOG.md b/packages/auth/CHANGELOG.md new file mode 100644 index 0000000000..37751e73a0 --- /dev/null +++ b/packages/auth/CHANGELOG.md @@ -0,0 +1,4782 @@ +# @0xsequence/auth + +## 2.0.0 + +### Major Changes + +- changeset + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@2.0.0 + - @0xsequence/account@2.0.0 + - @0xsequence/api@2.0.0 + - @0xsequence/core@2.0.0 + - @0xsequence/indexer@2.0.0 + - @0xsequence/metadata@2.0.0 + - @0xsequence/migration@2.0.0 + - @0xsequence/network@2.0.0 + - @0xsequence/sessions@2.0.0 + - @0xsequence/signhub@2.0.0 + - @0xsequence/utils@2.0.0 + - @0xsequence/wallet@2.0.0 + +## 1.10.14 + +### Patch Changes + +- network: add borne-testnet to allNetworks +- Updated dependencies + - @0xsequence/abi@1.10.14 + - @0xsequence/account@1.10.14 + - @0xsequence/api@1.10.14 + - @0xsequence/core@1.10.14 + - @0xsequence/indexer@1.10.14 + - @0xsequence/metadata@1.10.14 + - @0xsequence/migration@1.10.14 + - @0xsequence/network@1.10.14 + - @0xsequence/sessions@1.10.14 + - @0xsequence/signhub@1.10.14 + - @0xsequence/utils@1.10.14 + - @0xsequence/wallet@1.10.14 + +## 1.10.13 + +### Patch Changes + +- network: add borne testnet +- Updated dependencies + - @0xsequence/abi@1.10.13 + - @0xsequence/account@1.10.13 + - @0xsequence/api@1.10.13 + - @0xsequence/core@1.10.13 + - @0xsequence/indexer@1.10.13 + - @0xsequence/metadata@1.10.13 + - @0xsequence/migration@1.10.13 + - @0xsequence/network@1.10.13 + - @0xsequence/sessions@1.10.13 + - @0xsequence/signhub@1.10.13 + - @0xsequence/utils@1.10.13 + - @0xsequence/wallet@1.10.13 + +## 1.10.12 + +### Patch Changes + +- api: update bindings +- global/window -> globalThis +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.10.12 + - @0xsequence/account@1.10.12 + - @0xsequence/api@1.10.12 + - @0xsequence/core@1.10.12 + - @0xsequence/indexer@1.10.12 + - @0xsequence/metadata@1.10.12 + - @0xsequence/migration@1.10.12 + - @0xsequence/network@1.10.12 + - @0xsequence/sessions@1.10.12 + - @0xsequence/signhub@1.10.12 + - @0xsequence/utils@1.10.12 + - @0xsequence/wallet@1.10.12 + +## 1.10.11 + +### Patch Changes + +- waas: updated intent.gen without webrpc types, errors exported from authenticator.gen +- Updated dependencies + - @0xsequence/abi@1.10.11 + - @0xsequence/account@1.10.11 + - @0xsequence/api@1.10.11 + - @0xsequence/core@1.10.11 + - @0xsequence/indexer@1.10.11 + - @0xsequence/metadata@1.10.11 + - @0xsequence/migration@1.10.11 + - @0xsequence/network@1.10.11 + - @0xsequence/sessions@1.10.11 + - @0xsequence/signhub@1.10.11 + - @0xsequence/utils@1.10.11 + - @0xsequence/wallet@1.10.11 + +## 1.10.10 + +### Patch Changes + +- metadata: update bindings with new contract collections api +- Updated dependencies + - @0xsequence/abi@1.10.10 + - @0xsequence/account@1.10.10 + - @0xsequence/api@1.10.10 + - @0xsequence/core@1.10.10 + - @0xsequence/indexer@1.10.10 + - @0xsequence/metadata@1.10.10 + - @0xsequence/migration@1.10.10 + - @0xsequence/network@1.10.10 + - @0xsequence/sessions@1.10.10 + - @0xsequence/signhub@1.10.10 + - @0xsequence/utils@1.10.10 + - @0xsequence/wallet@1.10.10 + +## 1.10.9 + +### Patch Changes + +- waas minor update +- Updated dependencies + - @0xsequence/abi@1.10.9 + - @0xsequence/account@1.10.9 + - @0xsequence/api@1.10.9 + - @0xsequence/core@1.10.9 + - @0xsequence/indexer@1.10.9 + - @0xsequence/metadata@1.10.9 + - @0xsequence/migration@1.10.9 + - @0xsequence/network@1.10.9 + - @0xsequence/sessions@1.10.9 + - @0xsequence/signhub@1.10.9 + - @0xsequence/utils@1.10.9 + - @0xsequence/wallet@1.10.9 + +## 1.10.8 + +### Patch Changes + +- update metadata bindings +- Updated dependencies + - @0xsequence/abi@1.10.8 + - @0xsequence/account@1.10.8 + - @0xsequence/api@1.10.8 + - @0xsequence/core@1.10.8 + - @0xsequence/indexer@1.10.8 + - @0xsequence/metadata@1.10.8 + - @0xsequence/migration@1.10.8 + - @0xsequence/network@1.10.8 + - @0xsequence/sessions@1.10.8 + - @0xsequence/signhub@1.10.8 + - @0xsequence/utils@1.10.8 + - @0xsequence/wallet@1.10.8 + +## 1.10.7 + +### Patch Changes + +- minor fixes to waas client +- Updated dependencies + - @0xsequence/abi@1.10.7 + - @0xsequence/account@1.10.7 + - @0xsequence/api@1.10.7 + - @0xsequence/core@1.10.7 + - @0xsequence/indexer@1.10.7 + - @0xsequence/metadata@1.10.7 + - @0xsequence/migration@1.10.7 + - @0xsequence/network@1.10.7 + - @0xsequence/sessions@1.10.7 + - @0xsequence/signhub@1.10.7 + - @0xsequence/utils@1.10.7 + - @0xsequence/wallet@1.10.7 + +## 1.10.6 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/abi@1.10.6 + - @0xsequence/account@1.10.6 + - @0xsequence/api@1.10.6 + - @0xsequence/core@1.10.6 + - @0xsequence/indexer@1.10.6 + - @0xsequence/metadata@1.10.6 + - @0xsequence/migration@1.10.6 + - @0xsequence/network@1.10.6 + - @0xsequence/sessions@1.10.6 + - @0xsequence/signhub@1.10.6 + - @0xsequence/utils@1.10.6 + - @0xsequence/wallet@1.10.6 + +## 1.10.5 + +### Patch Changes + +- network: ape-chain-testnet -> apechain-testnet +- Updated dependencies + - @0xsequence/abi@1.10.5 + - @0xsequence/account@1.10.5 + - @0xsequence/api@1.10.5 + - @0xsequence/core@1.10.5 + - @0xsequence/indexer@1.10.5 + - @0xsequence/metadata@1.10.5 + - @0xsequence/migration@1.10.5 + - @0xsequence/network@1.10.5 + - @0xsequence/sessions@1.10.5 + - @0xsequence/signhub@1.10.5 + - @0xsequence/utils@1.10.5 + - @0xsequence/wallet@1.10.5 + +## 1.10.4 + +### Patch Changes + +- network: add b3-sepolia, ape-chain-testnet, blast, blast-sepolia +- Updated dependencies + - @0xsequence/abi@1.10.4 + - @0xsequence/account@1.10.4 + - @0xsequence/api@1.10.4 + - @0xsequence/core@1.10.4 + - @0xsequence/indexer@1.10.4 + - @0xsequence/metadata@1.10.4 + - @0xsequence/migration@1.10.4 + - @0xsequence/network@1.10.4 + - @0xsequence/sessions@1.10.4 + - @0xsequence/signhub@1.10.4 + - @0xsequence/utils@1.10.4 + - @0xsequence/wallet@1.10.4 + +## 1.10.3 + +### Patch Changes + +- typing fix +- Updated dependencies + - @0xsequence/abi@1.10.3 + - @0xsequence/account@1.10.3 + - @0xsequence/api@1.10.3 + - @0xsequence/core@1.10.3 + - @0xsequence/indexer@1.10.3 + - @0xsequence/metadata@1.10.3 + - @0xsequence/migration@1.10.3 + - @0xsequence/network@1.10.3 + - @0xsequence/sessions@1.10.3 + - @0xsequence/signhub@1.10.3 + - @0xsequence/utils@1.10.3 + - @0xsequence/wallet@1.10.3 + +## 1.10.2 + +### Patch Changes + +- - waas: add getIdToken method + - indexer: update api client +- Updated dependencies + - @0xsequence/abi@1.10.2 + - @0xsequence/account@1.10.2 + - @0xsequence/api@1.10.2 + - @0xsequence/core@1.10.2 + - @0xsequence/indexer@1.10.2 + - @0xsequence/metadata@1.10.2 + - @0xsequence/migration@1.10.2 + - @0xsequence/network@1.10.2 + - @0xsequence/sessions@1.10.2 + - @0xsequence/signhub@1.10.2 + - @0xsequence/utils@1.10.2 + - @0xsequence/wallet@1.10.2 + +## 1.10.1 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/abi@1.10.1 + - @0xsequence/account@1.10.1 + - @0xsequence/api@1.10.1 + - @0xsequence/core@1.10.1 + - @0xsequence/indexer@1.10.1 + - @0xsequence/metadata@1.10.1 + - @0xsequence/migration@1.10.1 + - @0xsequence/network@1.10.1 + - @0xsequence/sessions@1.10.1 + - @0xsequence/signhub@1.10.1 + - @0xsequence/utils@1.10.1 + - @0xsequence/wallet@1.10.1 + +## 1.10.0 + +### Minor Changes + +- waas release v1.3.0 + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.10.0 + - @0xsequence/account@1.10.0 + - @0xsequence/api@1.10.0 + - @0xsequence/core@1.10.0 + - @0xsequence/indexer@1.10.0 + - @0xsequence/metadata@1.10.0 + - @0xsequence/migration@1.10.0 + - @0xsequence/network@1.10.0 + - @0xsequence/sessions@1.10.0 + - @0xsequence/signhub@1.10.0 + - @0xsequence/utils@1.10.0 + - @0xsequence/wallet@1.10.0 + +## 1.9.37 + +### Patch Changes + +- network: adds nativeToken data to NetworkMetadata constants +- Updated dependencies + - @0xsequence/abi@1.9.37 + - @0xsequence/account@1.9.37 + - @0xsequence/api@1.9.37 + - @0xsequence/core@1.9.37 + - @0xsequence/indexer@1.9.37 + - @0xsequence/metadata@1.9.37 + - @0xsequence/migration@1.9.37 + - @0xsequence/network@1.9.37 + - @0xsequence/sessions@1.9.37 + - @0xsequence/signhub@1.9.37 + - @0xsequence/utils@1.9.37 + - @0xsequence/wallet@1.9.37 + +## 1.9.36 + +### Patch Changes + +- guard: export client +- Updated dependencies + - @0xsequence/abi@1.9.36 + - @0xsequence/account@1.9.36 + - @0xsequence/api@1.9.36 + - @0xsequence/core@1.9.36 + - @0xsequence/indexer@1.9.36 + - @0xsequence/metadata@1.9.36 + - @0xsequence/migration@1.9.36 + - @0xsequence/network@1.9.36 + - @0xsequence/sessions@1.9.36 + - @0xsequence/signhub@1.9.36 + - @0xsequence/utils@1.9.36 + - @0xsequence/wallet@1.9.36 + +## 1.9.35 + +### Patch Changes + +- guard: update bindings +- Updated dependencies + - @0xsequence/abi@1.9.35 + - @0xsequence/account@1.9.35 + - @0xsequence/api@1.9.35 + - @0xsequence/core@1.9.35 + - @0xsequence/indexer@1.9.35 + - @0xsequence/metadata@1.9.35 + - @0xsequence/migration@1.9.35 + - @0xsequence/network@1.9.35 + - @0xsequence/sessions@1.9.35 + - @0xsequence/signhub@1.9.35 + - @0xsequence/utils@1.9.35 + - @0xsequence/wallet@1.9.35 + +## 1.9.34 + +### Patch Changes + +- waas: always use lowercase email +- Updated dependencies + - @0xsequence/abi@1.9.34 + - @0xsequence/account@1.9.34 + - @0xsequence/api@1.9.34 + - @0xsequence/core@1.9.34 + - @0xsequence/indexer@1.9.34 + - @0xsequence/metadata@1.9.34 + - @0xsequence/migration@1.9.34 + - @0xsequence/network@1.9.34 + - @0xsequence/sessions@1.9.34 + - @0xsequence/signhub@1.9.34 + - @0xsequence/utils@1.9.34 + - @0xsequence/wallet@1.9.34 + +## 1.9.33 + +### Patch Changes + +- waas: umd build +- Updated dependencies + - @0xsequence/abi@1.9.33 + - @0xsequence/account@1.9.33 + - @0xsequence/api@1.9.33 + - @0xsequence/core@1.9.33 + - @0xsequence/indexer@1.9.33 + - @0xsequence/metadata@1.9.33 + - @0xsequence/migration@1.9.33 + - @0xsequence/network@1.9.33 + - @0xsequence/sessions@1.9.33 + - @0xsequence/signhub@1.9.33 + - @0xsequence/utils@1.9.33 + - @0xsequence/wallet@1.9.33 + +## 1.9.32 + +### Patch Changes + +- indexer: update bindings +- Updated dependencies + - @0xsequence/abi@1.9.32 + - @0xsequence/account@1.9.32 + - @0xsequence/api@1.9.32 + - @0xsequence/core@1.9.32 + - @0xsequence/indexer@1.9.32 + - @0xsequence/metadata@1.9.32 + - @0xsequence/migration@1.9.32 + - @0xsequence/network@1.9.32 + - @0xsequence/sessions@1.9.32 + - @0xsequence/signhub@1.9.32 + - @0xsequence/utils@1.9.32 + - @0xsequence/wallet@1.9.32 + +## 1.9.31 + +### Patch Changes + +- metadata: token directory changes +- Updated dependencies + - @0xsequence/abi@1.9.31 + - @0xsequence/account@1.9.31 + - @0xsequence/api@1.9.31 + - @0xsequence/core@1.9.31 + - @0xsequence/indexer@1.9.31 + - @0xsequence/metadata@1.9.31 + - @0xsequence/migration@1.9.31 + - @0xsequence/network@1.9.31 + - @0xsequence/sessions@1.9.31 + - @0xsequence/signhub@1.9.31 + - @0xsequence/utils@1.9.31 + - @0xsequence/wallet@1.9.31 + +## 1.9.30 + +### Patch Changes + +- update +- Updated dependencies + - @0xsequence/abi@1.9.30 + - @0xsequence/account@1.9.30 + - @0xsequence/api@1.9.30 + - @0xsequence/core@1.9.30 + - @0xsequence/indexer@1.9.30 + - @0xsequence/metadata@1.9.30 + - @0xsequence/migration@1.9.30 + - @0xsequence/network@1.9.30 + - @0xsequence/sessions@1.9.30 + - @0xsequence/signhub@1.9.30 + - @0xsequence/utils@1.9.30 + - @0xsequence/wallet@1.9.30 + +## 1.9.29 + +### Patch Changes + +- disable gnosis chain +- Updated dependencies + - @0xsequence/abi@1.9.29 + - @0xsequence/account@1.9.29 + - @0xsequence/api@1.9.29 + - @0xsequence/core@1.9.29 + - @0xsequence/indexer@1.9.29 + - @0xsequence/metadata@1.9.29 + - @0xsequence/migration@1.9.29 + - @0xsequence/network@1.9.29 + - @0xsequence/sessions@1.9.29 + - @0xsequence/signhub@1.9.29 + - @0xsequence/utils@1.9.29 + - @0xsequence/wallet@1.9.29 + +## 1.9.28 + +### Patch Changes + +- add utils/merkletree +- Updated dependencies + - @0xsequence/abi@1.9.28 + - @0xsequence/account@1.9.28 + - @0xsequence/api@1.9.28 + - @0xsequence/core@1.9.28 + - @0xsequence/indexer@1.9.28 + - @0xsequence/metadata@1.9.28 + - @0xsequence/migration@1.9.28 + - @0xsequence/network@1.9.28 + - @0xsequence/sessions@1.9.28 + - @0xsequence/signhub@1.9.28 + - @0xsequence/utils@1.9.28 + - @0xsequence/wallet@1.9.28 + +## 1.9.27 + +### Patch Changes + +- network: optimistic -> optimism +- waas: remove defaults +- api, sessions: update bindings +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.9.27 + - @0xsequence/account@1.9.27 + - @0xsequence/api@1.9.27 + - @0xsequence/core@1.9.27 + - @0xsequence/indexer@1.9.27 + - @0xsequence/metadata@1.9.27 + - @0xsequence/migration@1.9.27 + - @0xsequence/network@1.9.27 + - @0xsequence/sessions@1.9.27 + - @0xsequence/signhub@1.9.27 + - @0xsequence/utils@1.9.27 + - @0xsequence/wallet@1.9.27 + +## 1.9.26 + +### Patch Changes + +- - add backend interfaces for pluggable interfaces + - introduce @0xsequence/react-native + - update pnpm to lockfile v9 +- Updated dependencies + - @0xsequence/abi@1.9.26 + - @0xsequence/account@1.9.26 + - @0xsequence/api@1.9.26 + - @0xsequence/core@1.9.26 + - @0xsequence/indexer@1.9.26 + - @0xsequence/metadata@1.9.26 + - @0xsequence/migration@1.9.26 + - @0xsequence/network@1.9.26 + - @0xsequence/sessions@1.9.26 + - @0xsequence/signhub@1.9.26 + - @0xsequence/utils@1.9.26 + - @0xsequence/wallet@1.9.26 + +## 1.9.25 + +### Patch Changes + +- update webrpc clients with new error types +- Updated dependencies + - @0xsequence/abi@1.9.25 + - @0xsequence/account@1.9.25 + - @0xsequence/api@1.9.25 + - @0xsequence/core@1.9.25 + - @0xsequence/indexer@1.9.25 + - @0xsequence/metadata@1.9.25 + - @0xsequence/migration@1.9.25 + - @0xsequence/network@1.9.25 + - @0xsequence/sessions@1.9.25 + - @0xsequence/signhub@1.9.25 + - @0xsequence/utils@1.9.25 + - @0xsequence/wallet@1.9.25 + +## 1.9.24 + +### Patch Changes + +- waas: add memoryStore backend to localStore +- Updated dependencies + - @0xsequence/abi@1.9.24 + - @0xsequence/account@1.9.24 + - @0xsequence/api@1.9.24 + - @0xsequence/core@1.9.24 + - @0xsequence/indexer@1.9.24 + - @0xsequence/metadata@1.9.24 + - @0xsequence/migration@1.9.24 + - @0xsequence/network@1.9.24 + - @0xsequence/sessions@1.9.24 + - @0xsequence/signhub@1.9.24 + - @0xsequence/utils@1.9.24 + - @0xsequence/wallet@1.9.24 + +## 1.9.23 + +### Patch Changes + +- update api client bindings +- Updated dependencies + - @0xsequence/abi@1.9.23 + - @0xsequence/account@1.9.23 + - @0xsequence/api@1.9.23 + - @0xsequence/core@1.9.23 + - @0xsequence/indexer@1.9.23 + - @0xsequence/metadata@1.9.23 + - @0xsequence/migration@1.9.23 + - @0xsequence/network@1.9.23 + - @0xsequence/sessions@1.9.23 + - @0xsequence/signhub@1.9.23 + - @0xsequence/utils@1.9.23 + - @0xsequence/wallet@1.9.23 + +## 1.9.22 + +### Patch Changes + +- update metadata client bindings +- Updated dependencies + - @0xsequence/abi@1.9.22 + - @0xsequence/account@1.9.22 + - @0xsequence/api@1.9.22 + - @0xsequence/core@1.9.22 + - @0xsequence/indexer@1.9.22 + - @0xsequence/metadata@1.9.22 + - @0xsequence/migration@1.9.22 + - @0xsequence/network@1.9.22 + - @0xsequence/sessions@1.9.22 + - @0xsequence/signhub@1.9.22 + - @0xsequence/utils@1.9.22 + - @0xsequence/wallet@1.9.22 + +## 1.9.21 + +### Patch Changes + +- api client bindings +- Updated dependencies + - @0xsequence/abi@1.9.21 + - @0xsequence/account@1.9.21 + - @0xsequence/api@1.9.21 + - @0xsequence/core@1.9.21 + - @0xsequence/indexer@1.9.21 + - @0xsequence/metadata@1.9.21 + - @0xsequence/migration@1.9.21 + - @0xsequence/network@1.9.21 + - @0xsequence/sessions@1.9.21 + - @0xsequence/signhub@1.9.21 + - @0xsequence/utils@1.9.21 + - @0xsequence/wallet@1.9.21 + +## 1.9.20 + +### Patch Changes + +- api client bindings update +- Updated dependencies + - @0xsequence/abi@1.9.20 + - @0xsequence/account@1.9.20 + - @0xsequence/api@1.9.20 + - @0xsequence/core@1.9.20 + - @0xsequence/indexer@1.9.20 + - @0xsequence/metadata@1.9.20 + - @0xsequence/migration@1.9.20 + - @0xsequence/network@1.9.20 + - @0xsequence/sessions@1.9.20 + - @0xsequence/signhub@1.9.20 + - @0xsequence/utils@1.9.20 + - @0xsequence/wallet@1.9.20 + +## 1.9.19 + +### Patch Changes + +- waas update +- Updated dependencies + - @0xsequence/abi@1.9.19 + - @0xsequence/account@1.9.19 + - @0xsequence/api@1.9.19 + - @0xsequence/core@1.9.19 + - @0xsequence/indexer@1.9.19 + - @0xsequence/metadata@1.9.19 + - @0xsequence/migration@1.9.19 + - @0xsequence/network@1.9.19 + - @0xsequence/sessions@1.9.19 + - @0xsequence/signhub@1.9.19 + - @0xsequence/utils@1.9.19 + - @0xsequence/wallet@1.9.19 + +## 1.9.18 + +### Patch Changes + +- provider: prohibit dangerous functions +- Updated dependencies + - @0xsequence/abi@1.9.18 + - @0xsequence/account@1.9.18 + - @0xsequence/api@1.9.18 + - @0xsequence/core@1.9.18 + - @0xsequence/indexer@1.9.18 + - @0xsequence/metadata@1.9.18 + - @0xsequence/migration@1.9.18 + - @0xsequence/network@1.9.18 + - @0xsequence/sessions@1.9.18 + - @0xsequence/signhub@1.9.18 + - @0xsequence/utils@1.9.18 + - @0xsequence/wallet@1.9.18 + +## 1.9.17 + +### Patch Changes + +- network: add xr-sepolia +- Updated dependencies + - @0xsequence/network@1.9.17 + - @0xsequence/abi@1.9.17 + - @0xsequence/account@1.9.17 + - @0xsequence/api@1.9.17 + - @0xsequence/core@1.9.17 + - @0xsequence/indexer@1.9.17 + - @0xsequence/metadata@1.9.17 + - @0xsequence/migration@1.9.17 + - @0xsequence/sessions@1.9.17 + - @0xsequence/signhub@1.9.17 + - @0xsequence/utils@1.9.17 + - @0xsequence/wallet@1.9.17 + +## 1.9.16 + +### Patch Changes + +- waas: sequence.feeOptions +- Updated dependencies + - @0xsequence/abi@1.9.16 + - @0xsequence/account@1.9.16 + - @0xsequence/api@1.9.16 + - @0xsequence/core@1.9.16 + - @0xsequence/indexer@1.9.16 + - @0xsequence/metadata@1.9.16 + - @0xsequence/migration@1.9.16 + - @0xsequence/network@1.9.16 + - @0xsequence/sessions@1.9.16 + - @0xsequence/signhub@1.9.16 + - @0xsequence/utils@1.9.16 + - @0xsequence/wallet@1.9.16 + +## 1.9.15 + +### Patch Changes + +- metadata: collection external_link field name fix +- Updated dependencies + - @0xsequence/abi@1.9.15 + - @0xsequence/account@1.9.15 + - @0xsequence/api@1.9.15 + - @0xsequence/core@1.9.15 + - @0xsequence/indexer@1.9.15 + - @0xsequence/metadata@1.9.15 + - @0xsequence/migration@1.9.15 + - @0xsequence/network@1.9.15 + - @0xsequence/sessions@1.9.15 + - @0xsequence/signhub@1.9.15 + - @0xsequence/utils@1.9.15 + - @0xsequence/wallet@1.9.15 + +## 1.9.14 + +### Patch Changes + +- network: astar-zkatana -> astar-zkyoto +- network: deprecate polygon mumbai network +- network: add xai and polygon amoy +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.9.14 + - @0xsequence/account@1.9.14 + - @0xsequence/api@1.9.14 + - @0xsequence/core@1.9.14 + - @0xsequence/indexer@1.9.14 + - @0xsequence/metadata@1.9.14 + - @0xsequence/migration@1.9.14 + - @0xsequence/network@1.9.14 + - @0xsequence/sessions@1.9.14 + - @0xsequence/signhub@1.9.14 + - @0xsequence/utils@1.9.14 + - @0xsequence/wallet@1.9.14 + +## 1.9.13 + +### Patch Changes + +- waas: fix @0xsequence/network dependency +- Updated dependencies + - @0xsequence/abi@1.9.13 + - @0xsequence/account@1.9.13 + - @0xsequence/api@1.9.13 + - @0xsequence/core@1.9.13 + - @0xsequence/indexer@1.9.13 + - @0xsequence/metadata@1.9.13 + - @0xsequence/migration@1.9.13 + - @0xsequence/network@1.9.13 + - @0xsequence/sessions@1.9.13 + - @0xsequence/signhub@1.9.13 + - @0xsequence/utils@1.9.13 + - @0xsequence/wallet@1.9.13 + +## 1.9.12 + +### Patch Changes + +- indexer: update rpc bindings +- provider: signMessage: Serialize the BytesLike or string message into hexstring before sending +- waas: SessionAuthProof +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.9.12 + - @0xsequence/account@1.9.12 + - @0xsequence/api@1.9.12 + - @0xsequence/core@1.9.12 + - @0xsequence/indexer@1.9.12 + - @0xsequence/metadata@1.9.12 + - @0xsequence/migration@1.9.12 + - @0xsequence/network@1.9.12 + - @0xsequence/sessions@1.9.12 + - @0xsequence/signhub@1.9.12 + - @0xsequence/utils@1.9.12 + - @0xsequence/wallet@1.9.12 + +## 1.9.11 + +### Patch Changes + +- metdata, update rpc bindings +- Updated dependencies + - @0xsequence/abi@1.9.11 + - @0xsequence/account@1.9.11 + - @0xsequence/api@1.9.11 + - @0xsequence/core@1.9.11 + - @0xsequence/indexer@1.9.11 + - @0xsequence/metadata@1.9.11 + - @0xsequence/migration@1.9.11 + - @0xsequence/network@1.9.11 + - @0xsequence/sessions@1.9.11 + - @0xsequence/signhub@1.9.11 + - @0xsequence/utils@1.9.11 + - @0xsequence/wallet@1.9.11 + +## 1.9.10 + +### Patch Changes + +- update metadata rpc bindings +- Updated dependencies + - @0xsequence/abi@1.9.10 + - @0xsequence/account@1.9.10 + - @0xsequence/api@1.9.10 + - @0xsequence/core@1.9.10 + - @0xsequence/indexer@1.9.10 + - @0xsequence/metadata@1.9.10 + - @0xsequence/migration@1.9.10 + - @0xsequence/network@1.9.10 + - @0xsequence/sessions@1.9.10 + - @0xsequence/signhub@1.9.10 + - @0xsequence/utils@1.9.10 + - @0xsequence/wallet@1.9.10 + +## 1.9.9 + +### Patch Changes + +- metadata, add SequenceCollections rpc client +- Updated dependencies + - @0xsequence/abi@1.9.9 + - @0xsequence/account@1.9.9 + - @0xsequence/api@1.9.9 + - @0xsequence/core@1.9.9 + - @0xsequence/indexer@1.9.9 + - @0xsequence/metadata@1.9.9 + - @0xsequence/migration@1.9.9 + - @0xsequence/network@1.9.9 + - @0xsequence/sessions@1.9.9 + - @0xsequence/signhub@1.9.9 + - @0xsequence/utils@1.9.9 + - @0xsequence/wallet@1.9.9 + +## 1.9.8 + +### Patch Changes + +- waas client update +- Updated dependencies + - @0xsequence/abi@1.9.8 + - @0xsequence/account@1.9.8 + - @0xsequence/api@1.9.8 + - @0xsequence/core@1.9.8 + - @0xsequence/indexer@1.9.8 + - @0xsequence/metadata@1.9.8 + - @0xsequence/migration@1.9.8 + - @0xsequence/network@1.9.8 + - @0xsequence/sessions@1.9.8 + - @0xsequence/signhub@1.9.8 + - @0xsequence/utils@1.9.8 + - @0xsequence/wallet@1.9.8 + +## 1.9.7 + +### Patch Changes + +- update rpc client bindings for api, metadata and relayer +- Updated dependencies + - @0xsequence/abi@1.9.7 + - @0xsequence/account@1.9.7 + - @0xsequence/api@1.9.7 + - @0xsequence/core@1.9.7 + - @0xsequence/indexer@1.9.7 + - @0xsequence/metadata@1.9.7 + - @0xsequence/migration@1.9.7 + - @0xsequence/network@1.9.7 + - @0xsequence/sessions@1.9.7 + - @0xsequence/signhub@1.9.7 + - @0xsequence/utils@1.9.7 + - @0xsequence/wallet@1.9.7 + +## 1.9.6 + +### Patch Changes + +- waas package update +- Updated dependencies + - @0xsequence/abi@1.9.6 + - @0xsequence/account@1.9.6 + - @0xsequence/api@1.9.6 + - @0xsequence/core@1.9.6 + - @0xsequence/indexer@1.9.6 + - @0xsequence/metadata@1.9.6 + - @0xsequence/migration@1.9.6 + - @0xsequence/network@1.9.6 + - @0xsequence/sessions@1.9.6 + - @0xsequence/signhub@1.9.6 + - @0xsequence/utils@1.9.6 + - @0xsequence/wallet@1.9.6 + +## 1.9.5 + +### Patch Changes + +- RpcRelayer prioritize project access key +- Updated dependencies + - @0xsequence/abi@1.9.5 + - @0xsequence/account@1.9.5 + - @0xsequence/api@1.9.5 + - @0xsequence/core@1.9.5 + - @0xsequence/indexer@1.9.5 + - @0xsequence/metadata@1.9.5 + - @0xsequence/migration@1.9.5 + - @0xsequence/network@1.9.5 + - @0xsequence/sessions@1.9.5 + - @0xsequence/signhub@1.9.5 + - @0xsequence/utils@1.9.5 + - @0xsequence/wallet@1.9.5 + +## 1.9.4 + +### Patch Changes + +- waas: fix network dependency +- Updated dependencies + - @0xsequence/abi@1.9.4 + - @0xsequence/account@1.9.4 + - @0xsequence/api@1.9.4 + - @0xsequence/core@1.9.4 + - @0xsequence/indexer@1.9.4 + - @0xsequence/metadata@1.9.4 + - @0xsequence/migration@1.9.4 + - @0xsequence/network@1.9.4 + - @0xsequence/sessions@1.9.4 + - @0xsequence/signhub@1.9.4 + - @0xsequence/utils@1.9.4 + - @0xsequence/wallet@1.9.4 + +## 1.9.3 + +### Patch Changes + +- provider: don't append access key to RPC url if user has already provided it +- Updated dependencies + - @0xsequence/abi@1.9.3 + - @0xsequence/account@1.9.3 + - @0xsequence/api@1.9.3 + - @0xsequence/core@1.9.3 + - @0xsequence/indexer@1.9.3 + - @0xsequence/metadata@1.9.3 + - @0xsequence/migration@1.9.3 + - @0xsequence/network@1.9.3 + - @0xsequence/sessions@1.9.3 + - @0xsequence/signhub@1.9.3 + - @0xsequence/utils@1.9.3 + - @0xsequence/wallet@1.9.3 + +## 1.9.2 + +### Patch Changes + +- network: add xai-sepolia +- Updated dependencies + - @0xsequence/abi@1.9.2 + - @0xsequence/account@1.9.2 + - @0xsequence/api@1.9.2 + - @0xsequence/core@1.9.2 + - @0xsequence/indexer@1.9.2 + - @0xsequence/metadata@1.9.2 + - @0xsequence/migration@1.9.2 + - @0xsequence/network@1.9.2 + - @0xsequence/sessions@1.9.2 + - @0xsequence/signhub@1.9.2 + - @0xsequence/utils@1.9.2 + - @0xsequence/wallet@1.9.2 + +## 1.9.1 + +### Patch Changes + +- analytics fix +- Updated dependencies + - @0xsequence/abi@1.9.1 + - @0xsequence/account@1.9.1 + - @0xsequence/api@1.9.1 + - @0xsequence/core@1.9.1 + - @0xsequence/indexer@1.9.1 + - @0xsequence/metadata@1.9.1 + - @0xsequence/migration@1.9.1 + - @0xsequence/network@1.9.1 + - @0xsequence/sessions@1.9.1 + - @0xsequence/signhub@1.9.1 + - @0xsequence/utils@1.9.1 + - @0xsequence/wallet@1.9.1 + +## 1.9.0 + +### Minor Changes + +- waas release + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.9.0 + - @0xsequence/account@1.9.0 + - @0xsequence/api@1.9.0 + - @0xsequence/core@1.9.0 + - @0xsequence/indexer@1.9.0 + - @0xsequence/metadata@1.9.0 + - @0xsequence/migration@1.9.0 + - @0xsequence/network@1.9.0 + - @0xsequence/sessions@1.9.0 + - @0xsequence/signhub@1.9.0 + - @0xsequence/utils@1.9.0 + - @0xsequence/wallet@1.9.0 + +## 1.8.8 + +### Patch Changes + +- update metadata bindings +- Updated dependencies + - @0xsequence/abi@1.8.8 + - @0xsequence/account@1.8.8 + - @0xsequence/api@1.8.8 + - @0xsequence/core@1.8.8 + - @0xsequence/indexer@1.8.8 + - @0xsequence/metadata@1.8.8 + - @0xsequence/migration@1.8.8 + - @0xsequence/network@1.8.8 + - @0xsequence/sessions@1.8.8 + - @0xsequence/signhub@1.8.8 + - @0xsequence/utils@1.8.8 + - @0xsequence/wallet@1.8.8 + +## 1.8.7 + +### Patch Changes + +- provider: update databeat to 0.9.1 +- Updated dependencies + - @0xsequence/abi@1.8.7 + - @0xsequence/account@1.8.7 + - @0xsequence/api@1.8.7 + - @0xsequence/core@1.8.7 + - @0xsequence/indexer@1.8.7 + - @0xsequence/metadata@1.8.7 + - @0xsequence/migration@1.8.7 + - @0xsequence/network@1.8.7 + - @0xsequence/sessions@1.8.7 + - @0xsequence/signhub@1.8.7 + - @0xsequence/utils@1.8.7 + - @0xsequence/wallet@1.8.7 + +## 1.8.6 + +### Patch Changes + +- guard: SignedOwnershipProof +- Updated dependencies + - @0xsequence/abi@1.8.6 + - @0xsequence/account@1.8.6 + - @0xsequence/api@1.8.6 + - @0xsequence/core@1.8.6 + - @0xsequence/indexer@1.8.6 + - @0xsequence/metadata@1.8.6 + - @0xsequence/migration@1.8.6 + - @0xsequence/network@1.8.6 + - @0xsequence/sessions@1.8.6 + - @0xsequence/signhub@1.8.6 + - @0xsequence/utils@1.8.6 + - @0xsequence/wallet@1.8.6 + +## 1.8.5 + +### Patch Changes + +- guard: signOwnershipProof and isSignedOwnershipProof +- Updated dependencies + - @0xsequence/abi@1.8.5 + - @0xsequence/account@1.8.5 + - @0xsequence/api@1.8.5 + - @0xsequence/core@1.8.5 + - @0xsequence/indexer@1.8.5 + - @0xsequence/metadata@1.8.5 + - @0xsequence/migration@1.8.5 + - @0xsequence/network@1.8.5 + - @0xsequence/sessions@1.8.5 + - @0xsequence/signhub@1.8.5 + - @0xsequence/utils@1.8.5 + - @0xsequence/wallet@1.8.5 + +## 1.8.4 + +### Patch Changes + +- network: add homeverse to networks list +- Updated dependencies + - @0xsequence/abi@1.8.4 + - @0xsequence/account@1.8.4 + - @0xsequence/api@1.8.4 + - @0xsequence/core@1.8.4 + - @0xsequence/indexer@1.8.4 + - @0xsequence/metadata@1.8.4 + - @0xsequence/migration@1.8.4 + - @0xsequence/network@1.8.4 + - @0xsequence/sessions@1.8.4 + - @0xsequence/signhub@1.8.4 + - @0xsequence/utils@1.8.4 + - @0xsequence/wallet@1.8.4 + +## 1.8.3 + +### Patch Changes + +- api: introduce basic linked wallet support +- Updated dependencies + - @0xsequence/abi@1.8.3 + - @0xsequence/account@1.8.3 + - @0xsequence/api@1.8.3 + - @0xsequence/core@1.8.3 + - @0xsequence/indexer@1.8.3 + - @0xsequence/metadata@1.8.3 + - @0xsequence/migration@1.8.3 + - @0xsequence/network@1.8.3 + - @0xsequence/sessions@1.8.3 + - @0xsequence/signhub@1.8.3 + - @0xsequence/utils@1.8.3 + - @0xsequence/wallet@1.8.3 + +## 1.8.2 + +### Patch Changes + +- provider: don't initialize analytics unless explicitly requested +- Updated dependencies + - @0xsequence/abi@1.8.2 + - @0xsequence/account@1.8.2 + - @0xsequence/api@1.8.2 + - @0xsequence/core@1.8.2 + - @0xsequence/indexer@1.8.2 + - @0xsequence/metadata@1.8.2 + - @0xsequence/migration@1.8.2 + - @0xsequence/network@1.8.2 + - @0xsequence/sessions@1.8.2 + - @0xsequence/signhub@1.8.2 + - @0xsequence/utils@1.8.2 + - @0xsequence/wallet@1.8.2 + +## 1.8.1 + +### Patch Changes + +- update to analytics provider +- Updated dependencies + - @0xsequence/abi@1.8.1 + - @0xsequence/account@1.8.1 + - @0xsequence/api@1.8.1 + - @0xsequence/core@1.8.1 + - @0xsequence/indexer@1.8.1 + - @0xsequence/metadata@1.8.1 + - @0xsequence/migration@1.8.1 + - @0xsequence/network@1.8.1 + - @0xsequence/sessions@1.8.1 + - @0xsequence/signhub@1.8.1 + - @0xsequence/utils@1.8.1 + - @0xsequence/wallet@1.8.1 + +## 1.8.0 + +### Minor Changes + +- provider: project analytics + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.8.0 + - @0xsequence/account@1.8.0 + - @0xsequence/api@1.8.0 + - @0xsequence/core@1.8.0 + - @0xsequence/indexer@1.8.0 + - @0xsequence/metadata@1.8.0 + - @0xsequence/migration@1.8.0 + - @0xsequence/network@1.8.0 + - @0xsequence/sessions@1.8.0 + - @0xsequence/signhub@1.8.0 + - @0xsequence/utils@1.8.0 + - @0xsequence/wallet@1.8.0 + +## 1.7.2 + +### Patch Changes + +- 0xsequence: ChainId should not be exported as a type +- account, wallet: fix nonce selection +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.7.2 + - @0xsequence/account@1.7.2 + - @0xsequence/api@1.7.2 + - @0xsequence/core@1.7.2 + - @0xsequence/indexer@1.7.2 + - @0xsequence/metadata@1.7.2 + - @0xsequence/migration@1.7.2 + - @0xsequence/network@1.7.2 + - @0xsequence/sessions@1.7.2 + - @0xsequence/signhub@1.7.2 + - @0xsequence/utils@1.7.2 + - @0xsequence/wallet@1.7.2 + +## 1.7.1 + +### Patch Changes + +- network: add missing avalanche logoURI +- Updated dependencies + - @0xsequence/abi@1.7.1 + - @0xsequence/account@1.7.1 + - @0xsequence/api@1.7.1 + - @0xsequence/core@1.7.1 + - @0xsequence/indexer@1.7.1 + - @0xsequence/metadata@1.7.1 + - @0xsequence/migration@1.7.1 + - @0xsequence/network@1.7.1 + - @0xsequence/sessions@1.7.1 + - @0xsequence/signhub@1.7.1 + - @0xsequence/utils@1.7.1 + - @0xsequence/wallet@1.7.1 + +## 1.7.0 + +### Minor Changes + +- provider: projectAccessKey is now required + +### Patch Changes + +- network: add NetworkMetadata.logoURI property for all networks +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.7.0 + - @0xsequence/account@1.7.0 + - @0xsequence/api@1.7.0 + - @0xsequence/core@1.7.0 + - @0xsequence/indexer@1.7.0 + - @0xsequence/metadata@1.7.0 + - @0xsequence/migration@1.7.0 + - @0xsequence/network@1.7.0 + - @0xsequence/sessions@1.7.0 + - @0xsequence/signhub@1.7.0 + - @0xsequence/utils@1.7.0 + - @0xsequence/wallet@1.7.0 + +## 1.6.3 + +### Patch Changes + +- network list update +- Updated dependencies + - @0xsequence/abi@1.6.3 + - @0xsequence/account@1.6.3 + - @0xsequence/api@1.6.3 + - @0xsequence/core@1.6.3 + - @0xsequence/indexer@1.6.3 + - @0xsequence/metadata@1.6.3 + - @0xsequence/migration@1.6.3 + - @0xsequence/network@1.6.3 + - @0xsequence/sessions@1.6.3 + - @0xsequence/signhub@1.6.3 + - @0xsequence/utils@1.6.3 + - @0xsequence/wallet@1.6.3 + +## 1.6.2 + +### Patch Changes + +- auth: projectAccessKey option +- wallet: use 12 bytes for random space +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.6.2 + - @0xsequence/account@1.6.2 + - @0xsequence/api@1.6.2 + - @0xsequence/core@1.6.2 + - @0xsequence/indexer@1.6.2 + - @0xsequence/metadata@1.6.2 + - @0xsequence/migration@1.6.2 + - @0xsequence/network@1.6.2 + - @0xsequence/sessions@1.6.2 + - @0xsequence/signhub@1.6.2 + - @0xsequence/utils@1.6.2 + - @0xsequence/wallet@1.6.2 + +## 1.6.1 + +### Patch Changes + +- core: add simple config from subdigest support +- core: fix encode tree with subdigest +- account: implement buildOnChainSignature on Account +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.6.1 + - @0xsequence/account@1.6.1 + - @0xsequence/api@1.6.1 + - @0xsequence/core@1.6.1 + - @0xsequence/indexer@1.6.1 + - @0xsequence/metadata@1.6.1 + - @0xsequence/migration@1.6.1 + - @0xsequence/network@1.6.1 + - @0xsequence/sessions@1.6.1 + - @0xsequence/signhub@1.6.1 + - @0xsequence/utils@1.6.1 + - @0xsequence/wallet@1.6.1 + +## 1.6.0 + +### Minor Changes + +- account, wallet: parallel transactions by default + +### Patch Changes + +- provider: emit disconnect on sign out +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.6.0 + - @0xsequence/account@1.6.0 + - @0xsequence/api@1.6.0 + - @0xsequence/core@1.6.0 + - @0xsequence/indexer@1.6.0 + - @0xsequence/metadata@1.6.0 + - @0xsequence/migration@1.6.0 + - @0xsequence/network@1.6.0 + - @0xsequence/sessions@1.6.0 + - @0xsequence/signhub@1.6.0 + - @0xsequence/utils@1.6.0 + - @0xsequence/wallet@1.6.0 + +## 1.5.0 + +### Minor Changes + +- signhub: add 'signing' signer status + +### Patch Changes + +- auth: Session.open: onAccountAddress callback +- account: allow empty transaction bundles +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.5.0 + - @0xsequence/account@1.5.0 + - @0xsequence/api@1.5.0 + - @0xsequence/core@1.5.0 + - @0xsequence/indexer@1.5.0 + - @0xsequence/metadata@1.5.0 + - @0xsequence/migration@1.5.0 + - @0xsequence/network@1.5.0 + - @0xsequence/sessions@1.5.0 + - @0xsequence/signhub@1.5.0 + - @0xsequence/utils@1.5.0 + - @0xsequence/wallet@1.5.0 + +## 1.4.9 + +### Patch Changes + +- rename SequenceMetadataClient to SequenceMetadata +- Updated dependencies + - @0xsequence/abi@1.4.9 + - @0xsequence/account@1.4.9 + - @0xsequence/api@1.4.9 + - @0xsequence/core@1.4.9 + - @0xsequence/indexer@1.4.9 + - @0xsequence/metadata@1.4.9 + - @0xsequence/migration@1.4.9 + - @0xsequence/network@1.4.9 + - @0xsequence/sessions@1.4.9 + - @0xsequence/signhub@1.4.9 + - @0xsequence/utils@1.4.9 + - @0xsequence/wallet@1.4.9 + +## 1.4.8 + +### Patch Changes + +- account: Account.getSigners +- Updated dependencies + - @0xsequence/abi@1.4.8 + - @0xsequence/account@1.4.8 + - @0xsequence/api@1.4.8 + - @0xsequence/core@1.4.8 + - @0xsequence/indexer@1.4.8 + - @0xsequence/metadata@1.4.8 + - @0xsequence/migration@1.4.8 + - @0xsequence/network@1.4.8 + - @0xsequence/sessions@1.4.8 + - @0xsequence/signhub@1.4.8 + - @0xsequence/utils@1.4.8 + - @0xsequence/wallet@1.4.8 + +## 1.4.7 + +### Patch Changes + +- update indexer client bindings +- Updated dependencies + - @0xsequence/abi@1.4.7 + - @0xsequence/account@1.4.7 + - @0xsequence/api@1.4.7 + - @0xsequence/core@1.4.7 + - @0xsequence/indexer@1.4.7 + - @0xsequence/metadata@1.4.7 + - @0xsequence/migration@1.4.7 + - @0xsequence/network@1.4.7 + - @0xsequence/sessions@1.4.7 + - @0xsequence/signhub@1.4.7 + - @0xsequence/utils@1.4.7 + - @0xsequence/wallet@1.4.7 + +## 1.4.6 + +### Patch Changes + +- - add sepolia networks, mark goerli as deprecated + - update indexer client bindings +- Updated dependencies + - @0xsequence/abi@1.4.6 + - @0xsequence/account@1.4.6 + - @0xsequence/api@1.4.6 + - @0xsequence/core@1.4.6 + - @0xsequence/indexer@1.4.6 + - @0xsequence/metadata@1.4.6 + - @0xsequence/migration@1.4.6 + - @0xsequence/network@1.4.6 + - @0xsequence/sessions@1.4.6 + - @0xsequence/signhub@1.4.6 + - @0xsequence/utils@1.4.6 + - @0xsequence/wallet@1.4.6 + +## 1.4.5 + +### Patch Changes + +- indexer/metadata: update client bindings +- auth: selectWallet with new address +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.4.5 + - @0xsequence/account@1.4.5 + - @0xsequence/api@1.4.5 + - @0xsequence/core@1.4.5 + - @0xsequence/indexer@1.4.5 + - @0xsequence/metadata@1.4.5 + - @0xsequence/migration@1.4.5 + - @0xsequence/network@1.4.5 + - @0xsequence/sessions@1.4.5 + - @0xsequence/signhub@1.4.5 + - @0xsequence/utils@1.4.5 + - @0xsequence/wallet@1.4.5 + +## 1.4.4 + +### Patch Changes + +- indexer: update bindings +- auth: handle jwt expiry +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.4.4 + - @0xsequence/account@1.4.4 + - @0xsequence/api@1.4.4 + - @0xsequence/core@1.4.4 + - @0xsequence/indexer@1.4.4 + - @0xsequence/metadata@1.4.4 + - @0xsequence/migration@1.4.4 + - @0xsequence/network@1.4.4 + - @0xsequence/sessions@1.4.4 + - @0xsequence/signhub@1.4.4 + - @0xsequence/utils@1.4.4 + - @0xsequence/wallet@1.4.4 + +## 1.4.3 + +### Patch Changes + +- guard: return active status from GuardSigner.getAuthMethods +- Updated dependencies + - @0xsequence/abi@1.4.3 + - @0xsequence/account@1.4.3 + - @0xsequence/api@1.4.3 + - @0xsequence/core@1.4.3 + - @0xsequence/indexer@1.4.3 + - @0xsequence/metadata@1.4.3 + - @0xsequence/migration@1.4.3 + - @0xsequence/network@1.4.3 + - @0xsequence/sessions@1.4.3 + - @0xsequence/signhub@1.4.3 + - @0xsequence/utils@1.4.3 + - @0xsequence/wallet@1.4.3 + +## 1.4.2 + +### Patch Changes + +- guard: update bindings +- Updated dependencies + - @0xsequence/abi@1.4.2 + - @0xsequence/account@1.4.2 + - @0xsequence/api@1.4.2 + - @0xsequence/core@1.4.2 + - @0xsequence/indexer@1.4.2 + - @0xsequence/metadata@1.4.2 + - @0xsequence/migration@1.4.2 + - @0xsequence/network@1.4.2 + - @0xsequence/sessions@1.4.2 + - @0xsequence/signhub@1.4.2 + - @0xsequence/utils@1.4.2 + - @0xsequence/wallet@1.4.2 + +## 1.4.1 + +### Patch Changes + +- network: remove unused networks +- signhub: orchestrator interface +- guard: auth methods interface +- guard: update bindings for pin and totp +- guard: no more retry logic +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.4.1 + - @0xsequence/account@1.4.1 + - @0xsequence/api@1.4.1 + - @0xsequence/core@1.4.1 + - @0xsequence/indexer@1.4.1 + - @0xsequence/metadata@1.4.1 + - @0xsequence/migration@1.4.1 + - @0xsequence/network@1.4.1 + - @0xsequence/sessions@1.4.1 + - @0xsequence/signhub@1.4.1 + - @0xsequence/utils@1.4.1 + - @0xsequence/wallet@1.4.1 + +## 1.4.0 + +### Minor Changes + +- project access key support + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.4.0 + - @0xsequence/account@1.4.0 + - @0xsequence/api@1.4.0 + - @0xsequence/core@1.4.0 + - @0xsequence/indexer@1.4.0 + - @0xsequence/metadata@1.4.0 + - @0xsequence/migration@1.4.0 + - @0xsequence/network@1.4.0 + - @0xsequence/sessions@1.4.0 + - @0xsequence/signhub@1.4.0 + - @0xsequence/utils@1.4.0 + - @0xsequence/wallet@1.4.0 + +## 1.3.0 + +### Minor Changes + +- signhub: account children + +### Patch Changes + +- guard: do not throw when building deploy transaction +- network: snowtrace.io -> subnets.avax.network/c-chain +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.3.0 + - @0xsequence/account@1.3.0 + - @0xsequence/api@1.3.0 + - @0xsequence/core@1.3.0 + - @0xsequence/indexer@1.3.0 + - @0xsequence/metadata@1.3.0 + - @0xsequence/migration@1.3.0 + - @0xsequence/network@1.3.0 + - @0xsequence/sessions@1.3.0 + - @0xsequence/signhub@1.3.0 + - @0xsequence/utils@1.3.0 + - @0xsequence/wallet@1.3.0 + +## 1.2.9 + +### Patch Changes + +- account: AccountSigner.sendTransaction simulateForFeeOptions +- relayer: update bindings +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.2.9 + - @0xsequence/account@1.2.9 + - @0xsequence/api@1.2.9 + - @0xsequence/core@1.2.9 + - @0xsequence/indexer@1.2.9 + - @0xsequence/metadata@1.2.9 + - @0xsequence/migration@1.2.9 + - @0xsequence/network@1.2.9 + - @0xsequence/sessions@1.2.9 + - @0xsequence/signhub@1.2.9 + - @0xsequence/utils@1.2.9 + - @0xsequence/wallet@1.2.9 + +## 1.2.8 + +### Patch Changes + +- rename X-Sequence-Token-Key header to X-Access-Key +- Updated dependencies + - @0xsequence/abi@1.2.8 + - @0xsequence/account@1.2.8 + - @0xsequence/api@1.2.8 + - @0xsequence/core@1.2.8 + - @0xsequence/indexer@1.2.8 + - @0xsequence/metadata@1.2.8 + - @0xsequence/migration@1.2.8 + - @0xsequence/network@1.2.8 + - @0xsequence/sessions@1.2.8 + - @0xsequence/signhub@1.2.8 + - @0xsequence/utils@1.2.8 + - @0xsequence/wallet@1.2.8 + +## 1.2.7 + +### Patch Changes + +- add x-sequence-token-key to clients +- Updated dependencies + - @0xsequence/abi@1.2.7 + - @0xsequence/account@1.2.7 + - @0xsequence/api@1.2.7 + - @0xsequence/core@1.2.7 + - @0xsequence/indexer@1.2.7 + - @0xsequence/metadata@1.2.7 + - @0xsequence/migration@1.2.7 + - @0xsequence/network@1.2.7 + - @0xsequence/sessions@1.2.7 + - @0xsequence/signhub@1.2.7 + - @0xsequence/utils@1.2.7 + - @0xsequence/wallet@1.2.7 + +## 1.2.6 + +### Patch Changes + +- Fix bind multicall provider +- Updated dependencies + - @0xsequence/abi@1.2.6 + - @0xsequence/account@1.2.6 + - @0xsequence/api@1.2.6 + - @0xsequence/core@1.2.6 + - @0xsequence/indexer@1.2.6 + - @0xsequence/metadata@1.2.6 + - @0xsequence/migration@1.2.6 + - @0xsequence/network@1.2.6 + - @0xsequence/sessions@1.2.6 + - @0xsequence/signhub@1.2.6 + - @0xsequence/utils@1.2.6 + - @0xsequence/wallet@1.2.6 + +## 1.2.5 + +### Patch Changes + +- Multicall default configuration fixes +- Updated dependencies + - @0xsequence/abi@1.2.5 + - @0xsequence/account@1.2.5 + - @0xsequence/api@1.2.5 + - @0xsequence/core@1.2.5 + - @0xsequence/indexer@1.2.5 + - @0xsequence/metadata@1.2.5 + - @0xsequence/migration@1.2.5 + - @0xsequence/network@1.2.5 + - @0xsequence/sessions@1.2.5 + - @0xsequence/signhub@1.2.5 + - @0xsequence/utils@1.2.5 + - @0xsequence/wallet@1.2.5 + +## 1.2.4 + +### Patch Changes + +- provider: Adding missing payment provider types to PaymentProviderOption +- provider: WalletRequestHandler.notifyChainChanged +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.2.4 + - @0xsequence/account@1.2.4 + - @0xsequence/api@1.2.4 + - @0xsequence/core@1.2.4 + - @0xsequence/indexer@1.2.4 + - @0xsequence/metadata@1.2.4 + - @0xsequence/migration@1.2.4 + - @0xsequence/network@1.2.4 + - @0xsequence/sessions@1.2.4 + - @0xsequence/signhub@1.2.4 + - @0xsequence/utils@1.2.4 + - @0xsequence/wallet@1.2.4 + +## 1.2.3 + +### Patch Changes + +- auth, provider: connect to accept optional authorizeNonce +- Updated dependencies + - @0xsequence/abi@1.2.3 + - @0xsequence/account@1.2.3 + - @0xsequence/api@1.2.3 + - @0xsequence/core@1.2.3 + - @0xsequence/indexer@1.2.3 + - @0xsequence/metadata@1.2.3 + - @0xsequence/migration@1.2.3 + - @0xsequence/network@1.2.3 + - @0xsequence/sessions@1.2.3 + - @0xsequence/signhub@1.2.3 + - @0xsequence/utils@1.2.3 + - @0xsequence/wallet@1.2.3 + +## 1.2.2 + +### Patch Changes + +- provider: allow createContract calls +- core: check for explicit zero address in contract deployments +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.2.2 + - @0xsequence/account@1.2.2 + - @0xsequence/api@1.2.2 + - @0xsequence/core@1.2.2 + - @0xsequence/indexer@1.2.2 + - @0xsequence/metadata@1.2.2 + - @0xsequence/migration@1.2.2 + - @0xsequence/network@1.2.2 + - @0xsequence/sessions@1.2.2 + - @0xsequence/signhub@1.2.2 + - @0xsequence/utils@1.2.2 + - @0xsequence/wallet@1.2.2 + +## 1.2.1 + +### Patch Changes + +- auth: use sequence api chain id as reference chain id if available +- Updated dependencies + - @0xsequence/abi@1.2.1 + - @0xsequence/account@1.2.1 + - @0xsequence/api@1.2.1 + - @0xsequence/core@1.2.1 + - @0xsequence/indexer@1.2.1 + - @0xsequence/metadata@1.2.1 + - @0xsequence/migration@1.2.1 + - @0xsequence/network@1.2.1 + - @0xsequence/sessions@1.2.1 + - @0xsequence/signhub@1.2.1 + - @0xsequence/utils@1.2.1 + - @0xsequence/wallet@1.2.1 + +## 1.2.0 + +### Minor Changes + +- split services from session, better local support + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.2.0 + - @0xsequence/account@1.2.0 + - @0xsequence/api@1.2.0 + - @0xsequence/core@1.2.0 + - @0xsequence/indexer@1.2.0 + - @0xsequence/metadata@1.2.0 + - @0xsequence/migration@1.2.0 + - @0xsequence/network@1.2.0 + - @0xsequence/sessions@1.2.0 + - @0xsequence/signhub@1.2.0 + - @0xsequence/utils@1.2.0 + - @0xsequence/wallet@1.2.0 + +## 1.1.15 + +### Patch Changes + +- guard: remove error filtering +- Updated dependencies + - @0xsequence/abi@1.1.15 + - @0xsequence/account@1.1.15 + - @0xsequence/api@1.1.15 + - @0xsequence/core@1.1.15 + - @0xsequence/indexer@1.1.15 + - @0xsequence/metadata@1.1.15 + - @0xsequence/migration@1.1.15 + - @0xsequence/network@1.1.15 + - @0xsequence/sessions@1.1.15 + - @0xsequence/signhub@1.1.15 + - @0xsequence/utils@1.1.15 + - @0xsequence/wallet@1.1.15 + +## 1.1.14 + +### Patch Changes + +- guard: add GuardSigner.onError +- Updated dependencies + - @0xsequence/abi@1.1.14 + - @0xsequence/account@1.1.14 + - @0xsequence/api@1.1.14 + - @0xsequence/core@1.1.14 + - @0xsequence/indexer@1.1.14 + - @0xsequence/metadata@1.1.14 + - @0xsequence/migration@1.1.14 + - @0xsequence/network@1.1.14 + - @0xsequence/sessions@1.1.14 + - @0xsequence/signhub@1.1.14 + - @0xsequence/utils@1.1.14 + - @0xsequence/wallet@1.1.14 + +## 1.1.13 + +### Patch Changes + +- provider: pass client version with connect options +- provider: removing large from BannerSize +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.1.13 + - @0xsequence/account@1.1.13 + - @0xsequence/api@1.1.13 + - @0xsequence/core@1.1.13 + - @0xsequence/indexer@1.1.13 + - @0xsequence/metadata@1.1.13 + - @0xsequence/migration@1.1.13 + - @0xsequence/network@1.1.13 + - @0xsequence/sessions@1.1.13 + - @0xsequence/signhub@1.1.13 + - @0xsequence/utils@1.1.13 + - @0xsequence/wallet@1.1.13 + +## 1.1.12 + +### Patch Changes + +- provider: adding bannerSize to ConnectOptions +- Updated dependencies + - @0xsequence/abi@1.1.12 + - @0xsequence/account@1.1.12 + - @0xsequence/api@1.1.12 + - @0xsequence/core@1.1.12 + - @0xsequence/indexer@1.1.12 + - @0xsequence/metadata@1.1.12 + - @0xsequence/migration@1.1.12 + - @0xsequence/network@1.1.12 + - @0xsequence/sessions@1.1.12 + - @0xsequence/signhub@1.1.12 + - @0xsequence/utils@1.1.12 + - @0xsequence/wallet@1.1.12 + +## 1.1.11 + +### Patch Changes + +- add homeverse configs +- Updated dependencies + - @0xsequence/abi@1.1.11 + - @0xsequence/account@1.1.11 + - @0xsequence/api@1.1.11 + - @0xsequence/core@1.1.11 + - @0xsequence/indexer@1.1.11 + - @0xsequence/metadata@1.1.11 + - @0xsequence/migration@1.1.11 + - @0xsequence/network@1.1.11 + - @0xsequence/sessions@1.1.11 + - @0xsequence/signhub@1.1.11 + - @0xsequence/utils@1.1.11 + - @0xsequence/wallet@1.1.11 + +## 1.1.10 + +### Patch Changes + +- handle default EIP6492 on send +- Updated dependencies + - @0xsequence/abi@1.1.10 + - @0xsequence/account@1.1.10 + - @0xsequence/api@1.1.10 + - @0xsequence/core@1.1.10 + - @0xsequence/indexer@1.1.10 + - @0xsequence/metadata@1.1.10 + - @0xsequence/migration@1.1.10 + - @0xsequence/network@1.1.10 + - @0xsequence/sessions@1.1.10 + - @0xsequence/signhub@1.1.10 + - @0xsequence/utils@1.1.10 + - @0xsequence/wallet@1.1.10 + +## 1.1.9 + +### Patch Changes + +- Custom default EIP6492 on client +- Updated dependencies + - @0xsequence/abi@1.1.9 + - @0xsequence/account@1.1.9 + - @0xsequence/api@1.1.9 + - @0xsequence/core@1.1.9 + - @0xsequence/indexer@1.1.9 + - @0xsequence/metadata@1.1.9 + - @0xsequence/migration@1.1.9 + - @0xsequence/network@1.1.9 + - @0xsequence/sessions@1.1.9 + - @0xsequence/signhub@1.1.9 + - @0xsequence/utils@1.1.9 + - @0xsequence/wallet@1.1.9 + +## 1.1.8 + +### Patch Changes + +- metadata: searchMetadata: add types filter +- Updated dependencies + - @0xsequence/abi@1.1.8 + - @0xsequence/account@1.1.8 + - @0xsequence/api@1.1.8 + - @0xsequence/core@1.1.8 + - @0xsequence/indexer@1.1.8 + - @0xsequence/metadata@1.1.8 + - @0xsequence/migration@1.1.8 + - @0xsequence/network@1.1.8 + - @0xsequence/sessions@1.1.8 + - @0xsequence/signhub@1.1.8 + - @0xsequence/utils@1.1.8 + - @0xsequence/wallet@1.1.8 + +## 1.1.7 + +### Patch Changes + +- adding signInWith connect settings option to allow dapps to automatically login their users with a certain provider optimizing the normal authentication flow +- Updated dependencies + - @0xsequence/abi@1.1.7 + - @0xsequence/account@1.1.7 + - @0xsequence/api@1.1.7 + - @0xsequence/core@1.1.7 + - @0xsequence/indexer@1.1.7 + - @0xsequence/metadata@1.1.7 + - @0xsequence/migration@1.1.7 + - @0xsequence/network@1.1.7 + - @0xsequence/sessions@1.1.7 + - @0xsequence/signhub@1.1.7 + - @0xsequence/utils@1.1.7 + - @0xsequence/wallet@1.1.7 + +## 1.1.6 + +### Patch Changes + +- metadata: searchMetadata: add chainID and excludeTokenMetadata filters +- Updated dependencies + - @0xsequence/abi@1.1.6 + - @0xsequence/account@1.1.6 + - @0xsequence/api@1.1.6 + - @0xsequence/core@1.1.6 + - @0xsequence/indexer@1.1.6 + - @0xsequence/metadata@1.1.6 + - @0xsequence/migration@1.1.6 + - @0xsequence/network@1.1.6 + - @0xsequence/sessions@1.1.6 + - @0xsequence/signhub@1.1.6 + - @0xsequence/utils@1.1.6 + - @0xsequence/wallet@1.1.6 + +## 1.1.5 + +### Patch Changes + +- account: re-compute meta-transaction id for wallet deployment transactions +- Updated dependencies + - @0xsequence/abi@1.1.5 + - @0xsequence/account@1.1.5 + - @0xsequence/api@1.1.5 + - @0xsequence/core@1.1.5 + - @0xsequence/indexer@1.1.5 + - @0xsequence/metadata@1.1.5 + - @0xsequence/migration@1.1.5 + - @0xsequence/network@1.1.5 + - @0xsequence/sessions@1.1.5 + - @0xsequence/signhub@1.1.5 + - @0xsequence/utils@1.1.5 + - @0xsequence/wallet@1.1.5 + +## 1.1.4 + +### Patch Changes + +- network: rename base-mainnet to base +- provider: override isDefaultChain with ConnectOptions.networkId if provided +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.1.4 + - @0xsequence/account@1.1.4 + - @0xsequence/api@1.1.4 + - @0xsequence/core@1.1.4 + - @0xsequence/indexer@1.1.4 + - @0xsequence/metadata@1.1.4 + - @0xsequence/migration@1.1.4 + - @0xsequence/network@1.1.4 + - @0xsequence/sessions@1.1.4 + - @0xsequence/signhub@1.1.4 + - @0xsequence/utils@1.1.4 + - @0xsequence/wallet@1.1.4 + +## 1.1.3 + +### Patch Changes + +- provider: use network id from transport session +- provider: sign authorization using ConnectOptions.networkId if provided +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.1.3 + - @0xsequence/account@1.1.3 + - @0xsequence/api@1.1.3 + - @0xsequence/core@1.1.3 + - @0xsequence/indexer@1.1.3 + - @0xsequence/metadata@1.1.3 + - @0xsequence/migration@1.1.3 + - @0xsequence/network@1.1.3 + - @0xsequence/sessions@1.1.3 + - @0xsequence/signhub@1.1.3 + - @0xsequence/utils@1.1.3 + - @0xsequence/wallet@1.1.3 + +## 1.1.2 + +### Patch Changes + +- provider: jsonrpc chain id fixes +- Updated dependencies + - @0xsequence/abi@1.1.2 + - @0xsequence/account@1.1.2 + - @0xsequence/api@1.1.2 + - @0xsequence/core@1.1.2 + - @0xsequence/indexer@1.1.2 + - @0xsequence/metadata@1.1.2 + - @0xsequence/migration@1.1.2 + - @0xsequence/network@1.1.2 + - @0xsequence/sessions@1.1.2 + - @0xsequence/signhub@1.1.2 + - @0xsequence/utils@1.1.2 + - @0xsequence/wallet@1.1.2 + +## 1.1.1 + +### Patch Changes + +- network: add base mainnet and sepolia +- provider: reject toxic transaction requests +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.1.1 + - @0xsequence/account@1.1.1 + - @0xsequence/api@1.1.1 + - @0xsequence/core@1.1.1 + - @0xsequence/indexer@1.1.1 + - @0xsequence/metadata@1.1.1 + - @0xsequence/migration@1.1.1 + - @0xsequence/network@1.1.1 + - @0xsequence/sessions@1.1.1 + - @0xsequence/signhub@1.1.1 + - @0xsequence/utils@1.1.1 + - @0xsequence/wallet@1.1.1 + +## 1.1.0 + +### Minor Changes + +- Refactor dapp facing provider + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.1.0 + - @0xsequence/account@1.1.0 + - @0xsequence/api@1.1.0 + - @0xsequence/core@1.1.0 + - @0xsequence/indexer@1.1.0 + - @0xsequence/metadata@1.1.0 + - @0xsequence/migration@1.1.0 + - @0xsequence/network@1.1.0 + - @0xsequence/sessions@1.1.0 + - @0xsequence/signhub@1.1.0 + - @0xsequence/utils@1.1.0 + - @0xsequence/wallet@1.1.0 + +## 1.0.5 + +### Patch Changes + +- network: export network constants +- guard: use the correct global for fetch +- network: nova-explorer.arbitrum.io -> nova.arbiscan.io +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.0.5 + - @0xsequence/account@1.0.5 + - @0xsequence/api@1.0.5 + - @0xsequence/core@1.0.5 + - @0xsequence/indexer@1.0.5 + - @0xsequence/metadata@1.0.5 + - @0xsequence/migration@1.0.5 + - @0xsequence/network@1.0.5 + - @0xsequence/sessions@1.0.5 + - @0xsequence/signhub@1.0.5 + - @0xsequence/utils@1.0.5 + - @0xsequence/wallet@1.0.5 + +## 1.0.4 + +### Patch Changes + +- provider: accept name or number for networkId +- Updated dependencies + - @0xsequence/abi@1.0.4 + - @0xsequence/account@1.0.4 + - @0xsequence/api@1.0.4 + - @0xsequence/core@1.0.4 + - @0xsequence/indexer@1.0.4 + - @0xsequence/metadata@1.0.4 + - @0xsequence/migration@1.0.4 + - @0xsequence/network@1.0.4 + - @0xsequence/sessions@1.0.4 + - @0xsequence/signhub@1.0.4 + - @0xsequence/utils@1.0.4 + - @0xsequence/wallet@1.0.4 + +## 1.0.3 + +### Patch Changes + +- Simpler isValidSignature helpers +- Updated dependencies + - @0xsequence/abi@1.0.3 + - @0xsequence/account@1.0.3 + - @0xsequence/api@1.0.3 + - @0xsequence/core@1.0.3 + - @0xsequence/indexer@1.0.3 + - @0xsequence/metadata@1.0.3 + - @0xsequence/migration@1.0.3 + - @0xsequence/network@1.0.3 + - @0xsequence/sessions@1.0.3 + - @0xsequence/signhub@1.0.3 + - @0xsequence/utils@1.0.3 + - @0xsequence/wallet@1.0.3 + +## 1.0.2 + +### Patch Changes + +- add extra signature validation utils methods +- Updated dependencies + - @0xsequence/abi@1.0.2 + - @0xsequence/account@1.0.2 + - @0xsequence/api@1.0.2 + - @0xsequence/core@1.0.2 + - @0xsequence/indexer@1.0.2 + - @0xsequence/metadata@1.0.2 + - @0xsequence/migration@1.0.2 + - @0xsequence/network@1.0.2 + - @0xsequence/sessions@1.0.2 + - @0xsequence/signhub@1.0.2 + - @0xsequence/utils@1.0.2 + - @0xsequence/wallet@1.0.2 + +## 1.0.1 + +### Patch Changes + +- add homeverse testnet +- Updated dependencies + - @0xsequence/abi@1.0.1 + - @0xsequence/account@1.0.1 + - @0xsequence/api@1.0.1 + - @0xsequence/core@1.0.1 + - @0xsequence/indexer@1.0.1 + - @0xsequence/metadata@1.0.1 + - @0xsequence/migration@1.0.1 + - @0xsequence/network@1.0.1 + - @0xsequence/sessions@1.0.1 + - @0xsequence/signhub@1.0.1 + - @0xsequence/utils@1.0.1 + - @0xsequence/wallet@1.0.1 + +## 1.0.0 + +### Major Changes + +- https://sequence.xyz/blog/sequence-wallet-light-state-sync-full-merkle-wallets + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.0.0 + - @0xsequence/account@1.0.0 + - @0xsequence/api@1.0.0 + - @0xsequence/core@1.0.0 + - @0xsequence/indexer@1.0.0 + - @0xsequence/metadata@1.0.0 + - @0xsequence/migration@1.0.0 + - @0xsequence/network@1.0.0 + - @0xsequence/sessions@1.0.0 + - @0xsequence/signhub@1.0.0 + - @0xsequence/utils@1.0.0 + - @0xsequence/wallet@1.0.0 + +## 0.43.34 + +### Patch Changes + +- auth: no jwt for indexer +- Updated dependencies + - @0xsequence/abi@0.43.34 + - @0xsequence/api@0.43.34 + - @0xsequence/config@0.43.34 + - @0xsequence/indexer@0.43.34 + - @0xsequence/metadata@0.43.34 + - @0xsequence/network@0.43.34 + - @0xsequence/provider@0.43.34 + - @0xsequence/utils@0.43.34 + - @0xsequence/wallet@0.43.34 + +## 0.43.33 + +### Patch Changes + +- Adding onConnectOptionsChange handler to WalletRequestHandler +- Updated dependencies + - @0xsequence/abi@0.43.33 + - @0xsequence/api@0.43.33 + - @0xsequence/config@0.43.33 + - @0xsequence/indexer@0.43.33 + - @0xsequence/metadata@0.43.33 + - @0xsequence/network@0.43.33 + - @0xsequence/provider@0.43.33 + - @0xsequence/utils@0.43.33 + - @0xsequence/wallet@0.43.33 + +## 0.43.32 + +### Patch Changes + +- add Base Goerli network +- Updated dependencies + - @0xsequence/abi@0.43.32 + - @0xsequence/api@0.43.32 + - @0xsequence/config@0.43.32 + - @0xsequence/indexer@0.43.32 + - @0xsequence/metadata@0.43.32 + - @0xsequence/network@0.43.32 + - @0xsequence/provider@0.43.32 + - @0xsequence/utils@0.43.32 + - @0xsequence/wallet@0.43.32 + +## 0.43.31 + +### Patch Changes + +- remove AuxDataProvider, add promptSignInConnect +- Updated dependencies + - @0xsequence/abi@0.43.31 + - @0xsequence/api@0.43.31 + - @0xsequence/config@0.43.31 + - @0xsequence/indexer@0.43.31 + - @0xsequence/metadata@0.43.31 + - @0xsequence/network@0.43.31 + - @0xsequence/provider@0.43.31 + - @0xsequence/utils@0.43.31 + - @0xsequence/wallet@0.43.31 + +## 0.43.30 + +### Patch Changes + +- add arbitrum goerli testnet +- Updated dependencies + - @0xsequence/abi@0.43.30 + - @0xsequence/api@0.43.30 + - @0xsequence/config@0.43.30 + - @0xsequence/indexer@0.43.30 + - @0xsequence/metadata@0.43.30 + - @0xsequence/network@0.43.30 + - @0xsequence/provider@0.43.30 + - @0xsequence/utils@0.43.30 + - @0xsequence/wallet@0.43.30 + +## 0.43.29 + +### Patch Changes + +- provider: check availability of window object +- Updated dependencies + - @0xsequence/abi@0.43.29 + - @0xsequence/api@0.43.29 + - @0xsequence/config@0.43.29 + - @0xsequence/indexer@0.43.29 + - @0xsequence/metadata@0.43.29 + - @0xsequence/network@0.43.29 + - @0xsequence/provider@0.43.29 + - @0xsequence/utils@0.43.29 + - @0xsequence/wallet@0.43.29 + +## 0.43.28 + +### Patch Changes + +- update api bindings +- Updated dependencies + - @0xsequence/abi@0.43.28 + - @0xsequence/api@0.43.28 + - @0xsequence/config@0.43.28 + - @0xsequence/indexer@0.43.28 + - @0xsequence/metadata@0.43.28 + - @0xsequence/network@0.43.28 + - @0xsequence/provider@0.43.28 + - @0xsequence/utils@0.43.28 + - @0xsequence/wallet@0.43.28 + +## 0.43.27 + +### Patch Changes + +- Add rpc is sequence method +- Updated dependencies + - @0xsequence/abi@0.43.27 + - @0xsequence/api@0.43.27 + - @0xsequence/config@0.43.27 + - @0xsequence/indexer@0.43.27 + - @0xsequence/metadata@0.43.27 + - @0xsequence/network@0.43.27 + - @0xsequence/provider@0.43.27 + - @0xsequence/utils@0.43.27 + - @0xsequence/wallet@0.43.27 + +## 0.43.26 + +### Patch Changes + +- add zkevm url to enum +- Updated dependencies + - @0xsequence/abi@0.43.26 + - @0xsequence/api@0.43.26 + - @0xsequence/config@0.43.26 + - @0xsequence/indexer@0.43.26 + - @0xsequence/metadata@0.43.26 + - @0xsequence/network@0.43.26 + - @0xsequence/provider@0.43.26 + - @0xsequence/utils@0.43.26 + - @0xsequence/wallet@0.43.26 + +## 0.43.25 + +### Patch Changes + +- added polygon zkevm to mainnet networks +- Updated dependencies + - @0xsequence/abi@0.43.25 + - @0xsequence/api@0.43.25 + - @0xsequence/config@0.43.25 + - @0xsequence/indexer@0.43.25 + - @0xsequence/metadata@0.43.25 + - @0xsequence/network@0.43.25 + - @0xsequence/provider@0.43.25 + - @0xsequence/utils@0.43.25 + - @0xsequence/wallet@0.43.25 + +## 0.43.24 + +### Patch Changes + +- name change from zkevm to polygon-zkevm +- Updated dependencies + - @0xsequence/abi@0.43.24 + - @0xsequence/api@0.43.24 + - @0xsequence/config@0.43.24 + - @0xsequence/indexer@0.43.24 + - @0xsequence/metadata@0.43.24 + - @0xsequence/network@0.43.24 + - @0xsequence/provider@0.43.24 + - @0xsequence/utils@0.43.24 + - @0xsequence/wallet@0.43.24 + +## 0.43.23 + +### Patch Changes + +- update zkEVM name to Polygon zkEVM +- Updated dependencies + - @0xsequence/abi@0.43.23 + - @0xsequence/api@0.43.23 + - @0xsequence/config@0.43.23 + - @0xsequence/indexer@0.43.23 + - @0xsequence/metadata@0.43.23 + - @0xsequence/network@0.43.23 + - @0xsequence/provider@0.43.23 + - @0xsequence/utils@0.43.23 + - @0xsequence/wallet@0.43.23 + +## 0.43.22 + +### Patch Changes + +- add zkevm chain +- Updated dependencies + - @0xsequence/abi@0.43.22 + - @0xsequence/api@0.43.22 + - @0xsequence/config@0.43.22 + - @0xsequence/indexer@0.43.22 + - @0xsequence/metadata@0.43.22 + - @0xsequence/network@0.43.22 + - @0xsequence/provider@0.43.22 + - @0xsequence/utils@0.43.22 + - @0xsequence/wallet@0.43.22 + +## 0.43.21 + +### Patch Changes + +- api: update client bindings +- Updated dependencies + - @0xsequence/abi@0.43.21 + - @0xsequence/api@0.43.21 + - @0xsequence/config@0.43.21 + - @0xsequence/indexer@0.43.21 + - @0xsequence/metadata@0.43.21 + - @0xsequence/network@0.43.21 + - @0xsequence/provider@0.43.21 + - @0xsequence/utils@0.43.21 + - @0xsequence/wallet@0.43.21 + +## 0.43.20 + +### Patch Changes + +- indexer: update bindings +- Updated dependencies + - @0xsequence/abi@0.43.20 + - @0xsequence/api@0.43.20 + - @0xsequence/config@0.43.20 + - @0xsequence/indexer@0.43.20 + - @0xsequence/metadata@0.43.20 + - @0xsequence/network@0.43.20 + - @0xsequence/provider@0.43.20 + - @0xsequence/utils@0.43.20 + - @0xsequence/wallet@0.43.20 + +## 0.43.19 + +### Patch Changes + +- session proof update +- Updated dependencies + - @0xsequence/abi@0.43.19 + - @0xsequence/api@0.43.19 + - @0xsequence/config@0.43.19 + - @0xsequence/indexer@0.43.19 + - @0xsequence/metadata@0.43.19 + - @0xsequence/network@0.43.19 + - @0xsequence/provider@0.43.19 + - @0xsequence/utils@0.43.19 + - @0xsequence/wallet@0.43.19 + +## 0.43.18 + +### Patch Changes + +- rpc client global check, hardening +- Updated dependencies + - @0xsequence/abi@0.43.18 + - @0xsequence/api@0.43.18 + - @0xsequence/config@0.43.18 + - @0xsequence/indexer@0.43.18 + - @0xsequence/metadata@0.43.18 + - @0xsequence/network@0.43.18 + - @0xsequence/provider@0.43.18 + - @0xsequence/utils@0.43.18 + - @0xsequence/wallet@0.43.18 + +## 0.43.17 + +### Patch Changes + +- rpc clients, check of 'global' is defined +- Updated dependencies + - @0xsequence/abi@0.43.17 + - @0xsequence/api@0.43.17 + - @0xsequence/config@0.43.17 + - @0xsequence/indexer@0.43.17 + - @0xsequence/metadata@0.43.17 + - @0xsequence/network@0.43.17 + - @0xsequence/provider@0.43.17 + - @0xsequence/utils@0.43.17 + - @0xsequence/wallet@0.43.17 + +## 0.43.16 + +### Patch Changes + +- ethers peerDep to v5, update rpc client global use +- Updated dependencies + - @0xsequence/abi@0.43.16 + - @0xsequence/api@0.43.16 + - @0xsequence/config@0.43.16 + - @0xsequence/indexer@0.43.16 + - @0xsequence/metadata@0.43.16 + - @0xsequence/network@0.43.16 + - @0xsequence/provider@0.43.16 + - @0xsequence/utils@0.43.16 + - @0xsequence/wallet@0.43.16 + +## 0.43.15 + +### Patch Changes + +- - provider: expand receiver type on some util methods +- Updated dependencies + - @0xsequence/abi@0.43.15 + - @0xsequence/api@0.43.15 + - @0xsequence/config@0.43.15 + - @0xsequence/indexer@0.43.15 + - @0xsequence/metadata@0.43.15 + - @0xsequence/network@0.43.15 + - @0xsequence/provider@0.43.15 + - @0xsequence/utils@0.43.15 + - @0xsequence/wallet@0.43.15 + +## 0.43.14 + +### Patch Changes + +- bump +- Updated dependencies + - @0xsequence/abi@0.43.14 + - @0xsequence/api@0.43.14 + - @0xsequence/config@0.43.14 + - @0xsequence/indexer@0.43.14 + - @0xsequence/metadata@0.43.14 + - @0xsequence/network@0.43.14 + - @0xsequence/provider@0.43.14 + - @0xsequence/utils@0.43.14 + - @0xsequence/wallet@0.43.14 + +## 0.43.13 + +### Patch Changes + +- update rpc bindings +- Updated dependencies + - @0xsequence/abi@0.43.13 + - @0xsequence/api@0.43.13 + - @0xsequence/config@0.43.13 + - @0xsequence/indexer@0.43.13 + - @0xsequence/metadata@0.43.13 + - @0xsequence/network@0.43.13 + - @0xsequence/provider@0.43.13 + - @0xsequence/utils@0.43.13 + - @0xsequence/wallet@0.43.13 + +## 0.43.12 + +### Patch Changes + +- provider: single wallet init, and add new unregisterWallet() method +- Updated dependencies + - @0xsequence/abi@0.43.12 + - @0xsequence/api@0.43.12 + - @0xsequence/config@0.43.12 + - @0xsequence/indexer@0.43.12 + - @0xsequence/metadata@0.43.12 + - @0xsequence/network@0.43.12 + - @0xsequence/provider@0.43.12 + - @0xsequence/utils@0.43.12 + - @0xsequence/wallet@0.43.12 + +## 0.43.11 + +### Patch Changes + +- fix lockfiles +- re-add mocha type deleter +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.43.11 + - @0xsequence/api@0.43.11 + - @0xsequence/config@0.43.11 + - @0xsequence/indexer@0.43.11 + - @0xsequence/metadata@0.43.11 + - @0xsequence/network@0.43.11 + - @0xsequence/provider@0.43.11 + - @0xsequence/utils@0.43.11 + - @0xsequence/wallet@0.43.11 + +## 0.43.10 + +### Patch Changes + +- various improvements +- Updated dependencies + - @0xsequence/abi@0.43.10 + - @0xsequence/api@0.43.10 + - @0xsequence/config@0.43.10 + - @0xsequence/indexer@0.43.10 + - @0xsequence/metadata@0.43.10 + - @0xsequence/network@0.43.10 + - @0xsequence/provider@0.43.10 + - @0xsequence/utils@0.43.10 + - @0xsequence/wallet@0.43.10 + +## 0.43.9 + +### Patch Changes + +- update deps +- Updated dependencies + - @0xsequence/abi@0.43.9 + - @0xsequence/api@0.43.9 + - @0xsequence/config@0.43.9 + - @0xsequence/indexer@0.43.9 + - @0xsequence/metadata@0.43.9 + - @0xsequence/network@0.43.9 + - @0xsequence/provider@0.43.9 + - @0xsequence/utils@0.43.9 + - @0xsequence/wallet@0.43.9 + +## 0.43.8 + +### Patch Changes + +- network: JsonRpcProvider with caching +- Updated dependencies + - @0xsequence/abi@0.43.8 + - @0xsequence/api@0.43.8 + - @0xsequence/config@0.43.8 + - @0xsequence/indexer@0.43.8 + - @0xsequence/metadata@0.43.8 + - @0xsequence/network@0.43.8 + - @0xsequence/provider@0.43.8 + - @0xsequence/utils@0.43.8 + - @0xsequence/wallet@0.43.8 + +## 0.43.7 + +### Patch Changes + +- provider: fix wallet network init +- Updated dependencies + - @0xsequence/abi@0.43.7 + - @0xsequence/api@0.43.7 + - @0xsequence/config@0.43.7 + - @0xsequence/indexer@0.43.7 + - @0xsequence/metadata@0.43.7 + - @0xsequence/network@0.43.7 + - @0xsequence/utils@0.43.7 + - @0xsequence/wallet@0.43.7 + +## 0.43.6 + +### Patch Changes + +- metadatata: update rpc bindings +- Updated dependencies + - @0xsequence/abi@0.43.6 + - @0xsequence/api@0.43.6 + - @0xsequence/config@0.43.6 + - @0xsequence/indexer@0.43.6 + - @0xsequence/metadata@0.43.6 + - @0xsequence/network@0.43.6 + - @0xsequence/utils@0.43.6 + - @0xsequence/wallet@0.43.6 + +## 0.43.5 + +### Patch Changes + +- provider: do not set default network for connect messages +- provider: forward missing error message +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.43.5 + - @0xsequence/api@0.43.5 + - @0xsequence/config@0.43.5 + - @0xsequence/indexer@0.43.5 + - @0xsequence/metadata@0.43.5 + - @0xsequence/network@0.43.5 + - @0xsequence/utils@0.43.5 + - @0xsequence/wallet@0.43.5 + +## 0.43.4 + +### Patch Changes + +- no-change version bump to fix incorrectly tagged snapshot build +- Updated dependencies + - @0xsequence/abi@0.43.4 + - @0xsequence/api@0.43.4 + - @0xsequence/config@0.43.4 + - @0xsequence/indexer@0.43.4 + - @0xsequence/metadata@0.43.4 + - @0xsequence/network@0.43.4 + - @0xsequence/utils@0.43.4 + - @0xsequence/wallet@0.43.4 + +## 0.43.3 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/abi@0.43.3 + - @0xsequence/api@0.43.3 + - @0xsequence/config@0.43.3 + - @0xsequence/indexer@0.43.3 + - @0xsequence/metadata@0.43.3 + - @0xsequence/network@0.43.3 + - @0xsequence/utils@0.43.3 + - @0xsequence/wallet@0.43.3 + +## 0.43.2 + +### Patch Changes + +- provider: implement connectUnchecked +- Updated dependencies + - @0xsequence/abi@0.43.2 + - @0xsequence/api@0.43.2 + - @0xsequence/config@0.43.2 + - @0xsequence/indexer@0.43.2 + - @0xsequence/metadata@0.43.2 + - @0xsequence/network@0.43.2 + - @0xsequence/utils@0.43.2 + - @0xsequence/wallet@0.43.2 + +## 0.43.1 + +### Patch Changes + +- update to latest ethauth dep +- Updated dependencies + - @0xsequence/abi@0.43.1 + - @0xsequence/api@0.43.1 + - @0xsequence/config@0.43.1 + - @0xsequence/indexer@0.43.1 + - @0xsequence/metadata@0.43.1 + - @0xsequence/network@0.43.1 + - @0xsequence/utils@0.43.1 + - @0xsequence/wallet@0.43.1 + +## 0.43.0 + +### Minor Changes + +- move ethers to a peer dependency + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.43.0 + - @0xsequence/api@0.43.0 + - @0xsequence/config@0.43.0 + - @0xsequence/indexer@0.43.0 + - @0xsequence/metadata@0.43.0 + - @0xsequence/network@0.43.0 + - @0xsequence/utils@0.43.0 + - @0xsequence/wallet@0.43.0 + +## 0.42.10 + +### Patch Changes + +- add auxDataProvider +- Updated dependencies + - @0xsequence/abi@0.42.10 + - @0xsequence/api@0.42.10 + - @0xsequence/config@0.42.10 + - @0xsequence/indexer@0.42.10 + - @0xsequence/metadata@0.42.10 + - @0xsequence/network@0.42.10 + - @0xsequence/utils@0.42.10 + - @0xsequence/wallet@0.42.10 + +## 0.42.9 + +### Patch Changes + +- provider: add eip-191 exceptions +- Updated dependencies + - @0xsequence/abi@0.42.9 + - @0xsequence/api@0.42.9 + - @0xsequence/config@0.42.9 + - @0xsequence/indexer@0.42.9 + - @0xsequence/metadata@0.42.9 + - @0xsequence/network@0.42.9 + - @0xsequence/utils@0.42.9 + - @0xsequence/wallet@0.42.9 + +## 0.42.8 + +### Patch Changes + +- provider: skip setting intent origin if we're unity plugin +- Updated dependencies + - @0xsequence/abi@0.42.8 + - @0xsequence/api@0.42.8 + - @0xsequence/config@0.42.8 + - @0xsequence/indexer@0.42.8 + - @0xsequence/metadata@0.42.8 + - @0xsequence/network@0.42.8 + - @0xsequence/utils@0.42.8 + - @0xsequence/wallet@0.42.8 + +## 0.42.7 + +### Patch Changes + +- Add sign in options to connection settings +- Updated dependencies + - @0xsequence/abi@0.42.7 + - @0xsequence/api@0.42.7 + - @0xsequence/config@0.42.7 + - @0xsequence/indexer@0.42.7 + - @0xsequence/metadata@0.42.7 + - @0xsequence/network@0.42.7 + - @0xsequence/utils@0.42.7 + - @0xsequence/wallet@0.42.7 + +## 0.42.6 + +### Patch Changes + +- api bindings update +- Updated dependencies + - @0xsequence/abi@0.42.6 + - @0xsequence/api@0.42.6 + - @0xsequence/config@0.42.6 + - @0xsequence/indexer@0.42.6 + - @0xsequence/metadata@0.42.6 + - @0xsequence/network@0.42.6 + - @0xsequence/utils@0.42.6 + - @0xsequence/wallet@0.42.6 + +## 0.42.5 + +### Patch Changes + +- relayer: don't treat missing receipt as hard failure +- Updated dependencies + - @0xsequence/abi@0.42.5 + - @0xsequence/api@0.42.5 + - @0xsequence/config@0.42.5 + - @0xsequence/indexer@0.42.5 + - @0xsequence/metadata@0.42.5 + - @0xsequence/network@0.42.5 + - @0xsequence/utils@0.42.5 + - @0xsequence/wallet@0.42.5 + +## 0.42.4 + +### Patch Changes + +- provider: add custom app protocol to connect options +- Updated dependencies + - @0xsequence/abi@0.42.4 + - @0xsequence/api@0.42.4 + - @0xsequence/config@0.42.4 + - @0xsequence/indexer@0.42.4 + - @0xsequence/metadata@0.42.4 + - @0xsequence/network@0.42.4 + - @0xsequence/utils@0.42.4 + - @0xsequence/wallet@0.42.4 + +## 0.42.3 + +### Patch Changes + +- update api bindings +- Updated dependencies + - @0xsequence/abi@0.42.3 + - @0xsequence/api@0.42.3 + - @0xsequence/config@0.42.3 + - @0xsequence/indexer@0.42.3 + - @0xsequence/metadata@0.42.3 + - @0xsequence/network@0.42.3 + - @0xsequence/utils@0.42.3 + - @0xsequence/wallet@0.42.3 + +## 0.42.2 + +### Patch Changes + +- disable rinkeby network +- Updated dependencies + - @0xsequence/abi@0.42.2 + - @0xsequence/api@0.42.2 + - @0xsequence/config@0.42.2 + - @0xsequence/indexer@0.42.2 + - @0xsequence/metadata@0.42.2 + - @0xsequence/network@0.42.2 + - @0xsequence/utils@0.42.2 + - @0xsequence/wallet@0.42.2 + +## 0.42.1 + +### Patch Changes + +- wallet: optional waitForReceipt parameter +- Updated dependencies + - @0xsequence/abi@0.42.1 + - @0xsequence/api@0.42.1 + - @0xsequence/config@0.42.1 + - @0xsequence/indexer@0.42.1 + - @0xsequence/metadata@0.42.1 + - @0xsequence/network@0.42.1 + - @0xsequence/utils@0.42.1 + - @0xsequence/wallet@0.42.1 + +## 0.42.0 + +### Minor Changes + +- relayer: estimateGasLimits -> simulate +- add simulator package + +### Patch Changes + +- transactions: fix flattenAuxTransactions +- provider: only filter nullish values +- provider: re-map transaction 'gas' back to 'gasLimit' +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.42.0 + - @0xsequence/api@0.42.0 + - @0xsequence/config@0.42.0 + - @0xsequence/indexer@0.42.0 + - @0xsequence/metadata@0.42.0 + - @0xsequence/network@0.42.0 + - @0xsequence/utils@0.42.0 + - @0xsequence/wallet@0.42.0 + +## 0.41.3 + +### Patch Changes + +- api bindings update +- Updated dependencies + - @0xsequence/abi@0.41.3 + - @0xsequence/api@0.41.3 + - @0xsequence/config@0.41.3 + - @0xsequence/indexer@0.41.3 + - @0xsequence/metadata@0.41.3 + - @0xsequence/network@0.41.3 + - @0xsequence/utils@0.41.3 + - @0xsequence/wallet@0.41.3 + +## 0.41.2 + +### Patch Changes + +- api bindings update +- Updated dependencies + - @0xsequence/abi@0.41.2 + - @0xsequence/api@0.41.2 + - @0xsequence/config@0.41.2 + - @0xsequence/indexer@0.41.2 + - @0xsequence/metadata@0.41.2 + - @0xsequence/network@0.41.2 + - @0xsequence/utils@0.41.2 + - @0xsequence/wallet@0.41.2 + +## 0.41.1 + +### Patch Changes + +- update default networks +- Updated dependencies + - @0xsequence/abi@0.41.1 + - @0xsequence/api@0.41.1 + - @0xsequence/config@0.41.1 + - @0xsequence/indexer@0.41.1 + - @0xsequence/metadata@0.41.1 + - @0xsequence/network@0.41.1 + - @0xsequence/utils@0.41.1 + - @0xsequence/wallet@0.41.1 + +## 0.41.0 + +### Minor Changes + +- relayer: fix Relayer.wait() interface + + The interface for calling Relayer.wait() has changed. Instead of a single optional ill-defined timeout/delay parameter, there are three optional parameters, in order: + + - timeout: the maximum time to wait for the transaction receipt + - delay: the polling interval, i.e. the time to wait between requests + - maxFails: the maximum number of hard failures to tolerate before giving up + + Please update your codebase accordingly. + +- relayer: add optional waitForReceipt parameter to Relayer.relay + + The behaviour of Relayer.relay() was not well-defined with respect to whether or not it waited for a receipt. + This change allows the caller to specify whether to wait or not, with the default behaviour being to wait. + +### Patch Changes + +- relayer: wait receipt retry logic +- fix wrapped object error +- provider: forward delegateCall and revertOnError transaction fields +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.41.0 + - @0xsequence/api@0.41.0 + - @0xsequence/config@0.41.0 + - @0xsequence/indexer@0.41.0 + - @0xsequence/metadata@0.41.0 + - @0xsequence/network@0.41.0 + - @0xsequence/utils@0.41.0 + - @0xsequence/wallet@0.41.0 + +## 0.40.6 + +### Patch Changes + +- add arbitrum-nova chain +- Updated dependencies + - @0xsequence/abi@0.40.6 + - @0xsequence/api@0.40.6 + - @0xsequence/config@0.40.6 + - @0xsequence/indexer@0.40.6 + - @0xsequence/metadata@0.40.6 + - @0xsequence/network@0.40.6 + - @0xsequence/utils@0.40.6 + - @0xsequence/wallet@0.40.6 + +## 0.40.5 + +### Patch Changes + +- api: update bindings +- Updated dependencies + - @0xsequence/abi@0.40.5 + - @0xsequence/api@0.40.5 + - @0xsequence/config@0.40.5 + - @0xsequence/indexer@0.40.5 + - @0xsequence/metadata@0.40.5 + - @0xsequence/network@0.40.5 + - @0xsequence/utils@0.40.5 + - @0xsequence/wallet@0.40.5 + +## 0.40.4 + +### Patch Changes + +- add unreal transport +- Updated dependencies + - @0xsequence/abi@0.40.4 + - @0xsequence/api@0.40.4 + - @0xsequence/config@0.40.4 + - @0xsequence/indexer@0.40.4 + - @0xsequence/metadata@0.40.4 + - @0xsequence/network@0.40.4 + - @0xsequence/utils@0.40.4 + - @0xsequence/wallet@0.40.4 + +## 0.40.3 + +### Patch Changes + +- provider: fix MessageToSign message type +- Updated dependencies + - @0xsequence/abi@0.40.3 + - @0xsequence/api@0.40.3 + - @0xsequence/config@0.40.3 + - @0xsequence/indexer@0.40.3 + - @0xsequence/metadata@0.40.3 + - @0xsequence/network@0.40.3 + - @0xsequence/utils@0.40.3 + - @0xsequence/wallet@0.40.3 + +## 0.40.2 + +### Patch Changes + +- Wallet provider, loadSession method +- Updated dependencies + - @0xsequence/abi@0.40.2 + - @0xsequence/api@0.40.2 + - @0xsequence/config@0.40.2 + - @0xsequence/indexer@0.40.2 + - @0xsequence/metadata@0.40.2 + - @0xsequence/network@0.40.2 + - @0xsequence/utils@0.40.2 + - @0xsequence/wallet@0.40.2 + +## 0.40.1 + +### Patch Changes + +- export sequence.initWallet and sequence.getWallet +- Updated dependencies + - @0xsequence/abi@0.40.1 + - @0xsequence/api@0.40.1 + - @0xsequence/config@0.40.1 + - @0xsequence/indexer@0.40.1 + - @0xsequence/metadata@0.40.1 + - @0xsequence/network@0.40.1 + - @0xsequence/utils@0.40.1 + - @0xsequence/wallet@0.40.1 + +## 0.40.0 + +### Minor Changes + +- add sequence.initWallet(network, config) and sequence.getWallet() helper methods + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.40.0 + - @0xsequence/api@0.40.0 + - @0xsequence/config@0.40.0 + - @0xsequence/indexer@0.40.0 + - @0xsequence/metadata@0.40.0 + - @0xsequence/network@0.40.0 + - @0xsequence/utils@0.40.0 + - @0xsequence/wallet@0.40.0 + +## 0.39.6 + +### Patch Changes + +- indexer: update client bindings +- Updated dependencies + - @0xsequence/abi@0.39.6 + - @0xsequence/api@0.39.6 + - @0xsequence/config@0.39.6 + - @0xsequence/indexer@0.39.6 + - @0xsequence/metadata@0.39.6 + - @0xsequence/network@0.39.6 + - @0xsequence/utils@0.39.6 + - @0xsequence/wallet@0.39.6 + +## 0.39.5 + +### Patch Changes + +- provider: fix networkRpcUrl config option +- Updated dependencies + - @0xsequence/abi@0.39.5 + - @0xsequence/api@0.39.5 + - @0xsequence/config@0.39.5 + - @0xsequence/indexer@0.39.5 + - @0xsequence/metadata@0.39.5 + - @0xsequence/network@0.39.5 + - @0xsequence/utils@0.39.5 + - @0xsequence/wallet@0.39.5 + +## 0.39.4 + +### Patch Changes + +- api: update client bindings +- Updated dependencies + - @0xsequence/abi@0.39.4 + - @0xsequence/api@0.39.4 + - @0xsequence/config@0.39.4 + - @0xsequence/indexer@0.39.4 + - @0xsequence/metadata@0.39.4 + - @0xsequence/network@0.39.4 + - @0xsequence/utils@0.39.4 + - @0xsequence/wallet@0.39.4 + +## 0.39.3 + +### Patch Changes + +- add request method on Web3Provider +- Updated dependencies + - @0xsequence/abi@0.39.3 + - @0xsequence/api@0.39.3 + - @0xsequence/config@0.39.3 + - @0xsequence/indexer@0.39.3 + - @0xsequence/metadata@0.39.3 + - @0xsequence/network@0.39.3 + - @0xsequence/utils@0.39.3 + - @0xsequence/wallet@0.39.3 + +## 0.39.2 + +### Patch Changes + +- update umd name +- Updated dependencies + - @0xsequence/abi@0.39.2 + - @0xsequence/api@0.39.2 + - @0xsequence/config@0.39.2 + - @0xsequence/indexer@0.39.2 + - @0xsequence/metadata@0.39.2 + - @0xsequence/network@0.39.2 + - @0xsequence/utils@0.39.2 + - @0xsequence/wallet@0.39.2 + +## 0.39.1 + +### Patch Changes + +- add Aurora network +- add origin info for accountsChanged event to handle it per dapp +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.39.1 + - @0xsequence/api@0.39.1 + - @0xsequence/config@0.39.1 + - @0xsequence/indexer@0.39.1 + - @0xsequence/metadata@0.39.1 + - @0xsequence/network@0.39.1 + - @0xsequence/utils@0.39.1 + - @0xsequence/wallet@0.39.1 + +## 0.39.0 + +### Minor Changes + +- abstract window.localStorage to interface type + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.39.0 + - @0xsequence/api@0.39.0 + - @0xsequence/config@0.39.0 + - @0xsequence/indexer@0.39.0 + - @0xsequence/metadata@0.39.0 + - @0xsequence/network@0.39.0 + - @0xsequence/utils@0.39.0 + - @0xsequence/wallet@0.39.0 + +## 0.38.2 + +### Patch Changes + +- provider: add Settings.defaultPurchaseAmount +- Updated dependencies + - @0xsequence/abi@0.38.2 + - @0xsequence/api@0.38.2 + - @0xsequence/config@0.38.2 + - @0xsequence/indexer@0.38.2 + - @0xsequence/metadata@0.38.2 + - @0xsequence/network@0.38.2 + - @0xsequence/utils@0.38.2 + - @0xsequence/wallet@0.38.2 + +## 0.38.1 + +### Patch Changes + +- update api and metadata rpc bindings +- Updated dependencies + - @0xsequence/abi@0.38.1 + - @0xsequence/api@0.38.1 + - @0xsequence/config@0.38.1 + - @0xsequence/indexer@0.38.1 + - @0xsequence/metadata@0.38.1 + - @0xsequence/network@0.38.1 + - @0xsequence/utils@0.38.1 + - @0xsequence/wallet@0.38.1 + +## 0.38.0 + +### Minor Changes + +- api: update bindings, change TokenPrice interface +- bridge: remove @0xsequence/bridge package +- api: update bindings, rename ContractCallArg to TupleComponent + +### Patch Changes + +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.38.0 + - @0xsequence/api@0.38.0 + - @0xsequence/config@0.38.0 + - @0xsequence/indexer@0.38.0 + - @0xsequence/metadata@0.38.0 + - @0xsequence/network@0.38.0 + - @0xsequence/utils@0.38.0 + - @0xsequence/wallet@0.38.0 + +## 0.37.1 + +### Patch Changes + +- Add back sortNetworks - Removing sorting was a breaking change for dapps on older versions which directly integrate sequence. +- Updated dependencies + - @0xsequence/abi@0.37.1 + - @0xsequence/api@0.37.1 + - @0xsequence/config@0.37.1 + - @0xsequence/indexer@0.37.1 + - @0xsequence/metadata@0.37.1 + - @0xsequence/network@0.37.1 + - @0xsequence/utils@0.37.1 + - @0xsequence/wallet@0.37.1 + +## 0.37.0 + +### Minor Changes + +- network related fixes and improvements +- api: bindings: exchange rate lookups + +### Patch Changes + +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.37.0 + - @0xsequence/api@0.37.0 + - @0xsequence/config@0.37.0 + - @0xsequence/indexer@0.37.0 + - @0xsequence/metadata@0.37.0 + - @0xsequence/network@0.37.0 + - @0xsequence/utils@0.37.0 + - @0xsequence/wallet@0.37.0 + +## 0.36.13 + +### Patch Changes + +- api: update bindings with new price endpoints +- Updated dependencies + - @0xsequence/abi@0.36.13 + - @0xsequence/api@0.36.13 + - @0xsequence/config@0.36.13 + - @0xsequence/indexer@0.36.13 + - @0xsequence/metadata@0.36.13 + - @0xsequence/network@0.36.13 + - @0xsequence/utils@0.36.13 + - @0xsequence/wallet@0.36.13 + +## 0.36.12 + +### Patch Changes + +- wallet: skip remote signers if not needed +- auth: check that signature meets threshold before requesting auth token +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.36.12 + - @0xsequence/api@0.36.12 + - @0xsequence/config@0.36.12 + - @0xsequence/indexer@0.36.12 + - @0xsequence/metadata@0.36.12 + - @0xsequence/network@0.36.12 + - @0xsequence/utils@0.36.12 + - @0xsequence/wallet@0.36.12 + +## 0.36.11 + +### Patch Changes + +- Prefix EIP191 message on wallet-request-handler +- Updated dependencies + - @0xsequence/abi@0.36.11 + - @0xsequence/api@0.36.11 + - @0xsequence/config@0.36.11 + - @0xsequence/indexer@0.36.11 + - @0xsequence/metadata@0.36.11 + - @0xsequence/network@0.36.11 + - @0xsequence/utils@0.36.11 + - @0xsequence/wallet@0.36.11 + +## 0.36.10 + +### Patch Changes + +- support bannerUrl on connect +- Updated dependencies + - @0xsequence/abi@0.36.10 + - @0xsequence/api@0.36.10 + - @0xsequence/config@0.36.10 + - @0xsequence/indexer@0.36.10 + - @0xsequence/metadata@0.36.10 + - @0xsequence/network@0.36.10 + - @0xsequence/utils@0.36.10 + - @0xsequence/wallet@0.36.10 + +## 0.36.9 + +### Patch Changes + +- minor dev xp improvements +- Updated dependencies + - @0xsequence/abi@0.36.9 + - @0xsequence/api@0.36.9 + - @0xsequence/config@0.36.9 + - @0xsequence/indexer@0.36.9 + - @0xsequence/metadata@0.36.9 + - @0xsequence/network@0.36.9 + - @0xsequence/utils@0.36.9 + - @0xsequence/wallet@0.36.9 + +## 0.36.8 + +### Patch Changes + +- more connect options (theme, payment providers, funding currencies) +- Updated dependencies + - @0xsequence/abi@0.36.8 + - @0xsequence/api@0.36.8 + - @0xsequence/config@0.36.8 + - @0xsequence/indexer@0.36.8 + - @0xsequence/metadata@0.36.8 + - @0xsequence/network@0.36.8 + - @0xsequence/utils@0.36.8 + - @0xsequence/wallet@0.36.8 + +## 0.36.7 + +### Patch Changes + +- fix missing break +- Updated dependencies + - @0xsequence/abi@0.36.7 + - @0xsequence/api@0.36.7 + - @0xsequence/config@0.36.7 + - @0xsequence/indexer@0.36.7 + - @0xsequence/metadata@0.36.7 + - @0xsequence/network@0.36.7 + - @0xsequence/utils@0.36.7 + - @0xsequence/wallet@0.36.7 + +## 0.36.6 + +### Patch Changes + +- wallet_switchEthereumChain support +- Updated dependencies + - @0xsequence/abi@0.36.6 + - @0xsequence/api@0.36.6 + - @0xsequence/config@0.36.6 + - @0xsequence/indexer@0.36.6 + - @0xsequence/metadata@0.36.6 + - @0xsequence/network@0.36.6 + - @0xsequence/utils@0.36.6 + - @0xsequence/wallet@0.36.6 + +## 0.36.5 + +### Patch Changes + +- auth: bump ethauth to 0.7.0 + network, wallet: don't assume position of auth network in list + api/indexer/metadata: trim trailing slash on hostname, and add endpoint urls + relayer: Allow to specify local relayer transaction parameters like gas price or gas limit +- Updated dependencies + - @0xsequence/abi@0.36.5 + - @0xsequence/api@0.36.5 + - @0xsequence/config@0.36.5 + - @0xsequence/indexer@0.36.5 + - @0xsequence/metadata@0.36.5 + - @0xsequence/network@0.36.5 + - @0xsequence/utils@0.36.5 + - @0xsequence/wallet@0.36.5 + +## 0.36.4 + +### Patch Changes + +- Updating list of chain ids to include other ethereum compatible chains +- Updated dependencies + - @0xsequence/abi@0.36.4 + - @0xsequence/api@0.36.4 + - @0xsequence/config@0.36.4 + - @0xsequence/indexer@0.36.4 + - @0xsequence/metadata@0.36.4 + - @0xsequence/network@0.36.4 + - @0xsequence/utils@0.36.4 + - @0xsequence/wallet@0.36.4 + +## 0.36.3 + +### Patch Changes + +- provider: pass connect options to prompter methods +- Updated dependencies + - @0xsequence/abi@0.36.3 + - @0xsequence/api@0.36.3 + - @0xsequence/config@0.36.3 + - @0xsequence/indexer@0.36.3 + - @0xsequence/metadata@0.36.3 + - @0xsequence/network@0.36.3 + - @0xsequence/utils@0.36.3 + - @0xsequence/wallet@0.36.3 + +## 0.36.2 + +### Patch Changes + +- transactions: Setting target to 0x0 when empty to during SequenceTxAbiEncode +- Updated dependencies + - @0xsequence/abi@0.36.2 + - @0xsequence/api@0.36.2 + - @0xsequence/config@0.36.2 + - @0xsequence/indexer@0.36.2 + - @0xsequence/metadata@0.36.2 + - @0xsequence/network@0.36.2 + - @0xsequence/utils@0.36.2 + - @0xsequence/wallet@0.36.2 + +## 0.36.1 + +### Patch Changes + +- metadata: update client with more fields +- Updated dependencies + - @0xsequence/abi@0.36.1 + - @0xsequence/api@0.36.1 + - @0xsequence/config@0.36.1 + - @0xsequence/indexer@0.36.1 + - @0xsequence/metadata@0.36.1 + - @0xsequence/network@0.36.1 + - @0xsequence/utils@0.36.1 + - @0xsequence/wallet@0.36.1 + +## 0.36.0 + +### Minor Changes + +- relayer, wallet: fee quote support + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.36.0 + - @0xsequence/api@0.36.0 + - @0xsequence/config@0.36.0 + - @0xsequence/indexer@0.36.0 + - @0xsequence/metadata@0.36.0 + - @0xsequence/network@0.36.0 + - @0xsequence/utils@0.36.0 + - @0xsequence/wallet@0.36.0 + +## 0.35.12 + +### Patch Changes + +- provider: rename wallet.commands to wallet.utils +- Updated dependencies + - @0xsequence/abi@0.35.12 + - @0xsequence/api@0.35.12 + - @0xsequence/config@0.35.12 + - @0xsequence/indexer@0.35.12 + - @0xsequence/metadata@0.35.12 + - @0xsequence/network@0.35.12 + - @0xsequence/utils@0.35.12 + - @0xsequence/wallet@0.35.12 + +## 0.35.11 + +### Patch Changes + +- provider/utils: smoother message validation +- Updated dependencies + - @0xsequence/abi@0.35.11 + - @0xsequence/api@0.35.11 + - @0xsequence/config@0.35.11 + - @0xsequence/indexer@0.35.11 + - @0xsequence/metadata@0.35.11 + - @0xsequence/network@0.35.11 + - @0xsequence/utils@0.35.11 + - @0xsequence/wallet@0.35.11 + +## 0.35.10 + +### Patch Changes + +- upgrade deps +- Updated dependencies + - @0xsequence/abi@0.35.10 + - @0xsequence/api@0.35.10 + - @0xsequence/config@0.35.10 + - @0xsequence/indexer@0.35.10 + - @0xsequence/metadata@0.35.10 + - @0xsequence/network@0.35.10 + - @0xsequence/utils@0.35.10 + - @0xsequence/wallet@0.35.10 + +## 0.35.9 + +### Patch Changes + +- provider: window-transport override event handlers with new wallet instance +- Updated dependencies + - @0xsequence/abi@0.35.9 + - @0xsequence/api@0.35.9 + - @0xsequence/config@0.35.9 + - @0xsequence/indexer@0.35.9 + - @0xsequence/metadata@0.35.9 + - @0xsequence/network@0.35.9 + - @0xsequence/utils@0.35.9 + - @0xsequence/wallet@0.35.9 + +## 0.35.8 + +### Patch Changes + +- provider: async wallet sign in improvements +- Updated dependencies + - @0xsequence/abi@0.35.8 + - @0xsequence/api@0.35.8 + - @0xsequence/config@0.35.8 + - @0xsequence/indexer@0.35.8 + - @0xsequence/metadata@0.35.8 + - @0xsequence/network@0.35.8 + - @0xsequence/utils@0.35.8 + - @0xsequence/wallet@0.35.8 + +## 0.35.7 + +### Patch Changes + +- config: cache wallet configs +- Updated dependencies + - @0xsequence/abi@0.35.7 + - @0xsequence/api@0.35.7 + - @0xsequence/config@0.35.7 + - @0xsequence/indexer@0.35.7 + - @0xsequence/metadata@0.35.7 + - @0xsequence/network@0.35.7 + - @0xsequence/utils@0.35.7 + - @0xsequence/wallet@0.35.7 + +## 0.35.6 + +### Patch Changes + +- provider: support async signin of wallet request handler +- Updated dependencies + - @0xsequence/abi@0.35.6 + - @0xsequence/api@0.35.6 + - @0xsequence/config@0.35.6 + - @0xsequence/indexer@0.35.6 + - @0xsequence/metadata@0.35.6 + - @0xsequence/network@0.35.6 + - @0xsequence/utils@0.35.6 + - @0xsequence/wallet@0.35.6 + +## 0.35.5 + +### Patch Changes + +- wallet: skip threshold check during fee estimation +- Updated dependencies + - @0xsequence/abi@0.35.5 + - @0xsequence/api@0.35.5 + - @0xsequence/config@0.35.5 + - @0xsequence/indexer@0.35.5 + - @0xsequence/metadata@0.35.5 + - @0xsequence/network@0.35.5 + - @0xsequence/utils@0.35.5 + - @0xsequence/wallet@0.35.5 + +## 0.35.4 + +### Patch Changes + +- - browser extension mode, center window +- Updated dependencies + - @0xsequence/abi@0.35.4 + - @0xsequence/api@0.35.4 + - @0xsequence/config@0.35.4 + - @0xsequence/indexer@0.35.4 + - @0xsequence/metadata@0.35.4 + - @0xsequence/network@0.35.4 + - @0xsequence/utils@0.35.4 + - @0xsequence/wallet@0.35.4 + +## 0.35.3 + +### Patch Changes + +- - update window position when in browser extension mode +- Updated dependencies + - @0xsequence/abi@0.35.3 + - @0xsequence/api@0.35.3 + - @0xsequence/config@0.35.3 + - @0xsequence/indexer@0.35.3 + - @0xsequence/metadata@0.35.3 + - @0xsequence/network@0.35.3 + - @0xsequence/utils@0.35.3 + - @0xsequence/wallet@0.35.3 + +## 0.35.2 + +### Patch Changes + +- - provider: WindowMessageHandler accept optional windowHref +- Updated dependencies + - @0xsequence/abi@0.35.2 + - @0xsequence/api@0.35.2 + - @0xsequence/config@0.35.2 + - @0xsequence/indexer@0.35.2 + - @0xsequence/metadata@0.35.2 + - @0xsequence/network@0.35.2 + - @0xsequence/utils@0.35.2 + - @0xsequence/wallet@0.35.2 + +## 0.35.1 + +### Patch Changes + +- wallet: update config on undeployed too +- Updated dependencies + - @0xsequence/abi@0.35.1 + - @0xsequence/api@0.35.1 + - @0xsequence/config@0.35.1 + - @0xsequence/indexer@0.35.1 + - @0xsequence/metadata@0.35.1 + - @0xsequence/network@0.35.1 + - @0xsequence/utils@0.35.1 + - @0xsequence/wallet@0.35.1 + +## 0.35.0 + +### Minor Changes + +- - config: add buildStubSignature + - provider: add checks to signing cases for wallet deployment and config statuses + - provider: add prompt for wallet deployment + - relayer: add BaseRelayer.prependWalletDeploy + - relayer: add Relayer.feeOptions + - relayer: account for wallet deployment in fee estimation + - transactions: add fromTransactionish + - wallet: add Account.prependConfigUpdate + - wallet: add Account.getFeeOptions + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.35.0 + - @0xsequence/api@0.35.0 + - @0xsequence/config@0.35.0 + - @0xsequence/indexer@0.35.0 + - @0xsequence/metadata@0.35.0 + - @0xsequence/network@0.35.0 + - @0xsequence/utils@0.35.0 + - @0xsequence/wallet@0.35.0 + +## 0.34.1 + +### Patch Changes + +- upgrade ethauth dep + +## 0.34.0 + +### Minor Changes + +- - upgrade deps + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.34.0 + - @0xsequence/api@0.34.0 + - @0xsequence/config@0.34.0 + - @0xsequence/indexer@0.34.0 + - @0xsequence/metadata@0.34.0 + - @0xsequence/network@0.34.0 + - @0xsequence/utils@0.34.0 + - @0xsequence/wallet@0.34.0 + +## 0.33.3 + +### Patch Changes + +- Updated dependencies + - @0xsequence/wallet@0.33.3 + +## 0.33.2 + +### Patch Changes + +- @0xsequence/wallet@0.33.2 + +## 0.33.1 + +### Patch Changes + +- Updated dependencies + - @0xsequence/api@0.33.1 + +## 0.33.0 + +### Minor Changes + +- auth: fix spelling of 'thershold' to 'threshold' + +## 0.31.3 + +### Patch Changes + +- Updated dependencies + - @0xsequence/metadata@0.31.3 + +## 0.31.1 + +### Patch Changes + +- @0xsequence/wallet@0.31.1 + +## 0.31.0 + +### Minor Changes + +- - upgrading to ethers v5.5 + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.31.0 + - @0xsequence/api@0.31.0 + - @0xsequence/config@0.31.0 + - @0xsequence/indexer@0.31.0 + - @0xsequence/metadata@0.31.0 + - @0xsequence/network@0.31.0 + - @0xsequence/utils@0.31.0 + - @0xsequence/wallet@0.31.0 + +## 0.30.0 + +### Minor Changes + +- - upgrade most deps + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.30.0 + - @0xsequence/api@0.30.0 + - @0xsequence/config@0.30.0 + - @0xsequence/indexer@0.30.0 + - @0xsequence/metadata@0.30.0 + - @0xsequence/network@0.30.0 + - @0xsequence/utils@0.30.0 + - @0xsequence/wallet@0.30.0 + +## 0.29.9 + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/api@0.29.9 + +## 0.29.8 + +### Patch Changes + +- update api +- Updated dependencies [undefined] + - @0xsequence/abi@0.29.8 + - @0xsequence/api@0.29.8 + - @0xsequence/config@0.29.8 + - @0xsequence/indexer@0.29.8 + - @0xsequence/metadata@0.29.8 + - @0xsequence/network@0.29.8 + - @0xsequence/utils@0.29.8 + - @0xsequence/wallet@0.29.8 + +## 0.29.7 + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/wallet@0.29.7 + +## 0.29.6 + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/network@0.29.6 + - @0xsequence/config@0.29.6 + - @0xsequence/wallet@0.29.6 + +## 0.29.5 + +### Patch Changes + +- auth: pass testnetMode flag depending on network +- Updated dependencies [undefined] + - @0xsequence/config@0.29.5 + - @0xsequence/wallet@0.29.5 + +## 0.29.4 + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/api@0.29.4 + +## 0.29.3 + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/indexer@0.29.3 + +## 0.29.2 + +### Patch Changes + +- @0xsequence/wallet@0.29.2 + +## 0.29.1 + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/api@0.29.1 + - @0xsequence/metadata@0.29.1 + +## 0.29.0 + +### Minor Changes + +- major architectural changes in Sequence design + + - only one API instance, API is no longer a per-chain service + - separate per-chain indexer service, API no longer handles indexing + - single contract metadata service, API no longer serves metadata + + chaind package has been removed, indexer and metadata packages have been added + + stronger typing with new explicit ChainId type + + multicall fixes and improvements + + forbid "wait" transactions in sendTransactionBatch calls + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/api@0.29.0 + - @0xsequence/config@0.29.0 + - @0xsequence/indexer@0.29.0 + - @0xsequence/metadata@0.29.0 + - @0xsequence/network@0.29.0 + - @0xsequence/abi@0.29.0 + - @0xsequence/utils@0.29.0 + - @0xsequence/wallet@0.29.0 + +## 0.28.0 + +### Minor Changes + +- extension provider + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.28.0 + - @0xsequence/api@0.28.0 + - @0xsequence/config@0.28.0 + - @0xsequence/network@0.28.0 + - @0xsequence/utils@0.28.0 + - @0xsequence/wallet@0.28.0 + +## 0.27.2 + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/wallet@0.27.2 + +## 0.27.1 + +### Patch Changes + +- @0xsequence/wallet@0.27.1 + +## 0.27.0 + +### Minor Changes + +- Add requireFreshSigner lib to sessions + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.27.0 + - @0xsequence/api@0.27.0 + - @0xsequence/config@0.27.0 + - @0xsequence/network@0.27.0 + - @0xsequence/utils@0.27.0 + - @0xsequence/wallet@0.27.0 + +## 0.26.0 + +### Minor Changes + +- update relayer client bindings + provide the wallet's address for calls to SendMetaTxn + modify the semantics of Relayer.getNonce() to allow relayers to select nonce spaces for clients + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/wallet@0.26.0 + +## 0.25.1 + +### Patch Changes + +- Fix build typescrypt issue +- Updated dependencies [undefined] + - @0xsequence/abi@0.25.1 + - @0xsequence/api@0.25.1 + - @0xsequence/config@0.25.1 + - @0xsequence/network@0.25.1 + - @0xsequence/utils@0.25.1 + - @0xsequence/wallet@0.25.1 + +## 0.25.0 + +### Minor Changes + +- 10c8af8: Add estimator package + Fix multicall few calls bug + +### Patch Changes + +- Updated dependencies [10c8af8] + - @0xsequence/abi@0.25.0 + - @0xsequence/api@0.25.0 + - @0xsequence/config@0.25.0 + - @0xsequence/network@0.25.0 + - @0xsequence/utils@0.25.0 + - @0xsequence/wallet@0.25.0 + +## 0.24.1 + +### Patch Changes + +- @0xsequence/wallet@0.24.1 + +## 0.24.0 + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/api@0.24.0 + - @0xsequence/wallet@0.24.0 + +## 0.23.0 + +### Minor Changes + +- - relayer: offer variety of gas fee options from the relayer service" + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.23.0 + - @0xsequence/api@0.23.0 + - @0xsequence/config@0.23.0 + - @0xsequence/network@0.23.0 + - @0xsequence/utils@0.23.0 + - @0xsequence/wallet@0.23.0 + +## 0.22.2 + +### Patch Changes + +- e1c109e: Fix authProof on expired sessions +- Updated dependencies [e1c109e] + - @0xsequence/abi@0.22.2 + - @0xsequence/api@0.22.2 + - @0xsequence/config@0.22.2 + - @0xsequence/network@0.22.2 + - @0xsequence/utils@0.22.2 + - @0xsequence/wallet@0.22.2 + +## 0.22.1 + +### Patch Changes + +- transport session cache +- Updated dependencies [undefined] + - @0xsequence/abi@0.22.1 + - @0xsequence/api@0.22.1 + - @0xsequence/config@0.22.1 + - @0xsequence/network@0.22.1 + - @0xsequence/utils@0.22.1 + - @0xsequence/wallet@0.22.1 + +## 0.22.0 + +### Minor Changes + +- e667b65: Expose all relayer options on networks + +### Patch Changes + +- Updated dependencies [e667b65] + - @0xsequence/abi@0.22.0 + - @0xsequence/network@0.22.0 + - @0xsequence/utils@0.22.0 + - @0xsequence/wallet@0.22.0 + - @0xsequence/api@0.22.0 + - @0xsequence/config@0.22.0 + +## 0.21.5 + +### Patch Changes + +- Give priority to metaTxnId returned by relayer +- Updated dependencies [undefined] + - @0xsequence/abi@0.21.5 + - @0xsequence/api@0.21.5 + - @0xsequence/config@0.21.5 + - @0xsequence/network@0.21.5 + - @0xsequence/utils@0.21.5 + - @0xsequence/wallet@0.21.5 + +## 0.21.4 + +### Patch Changes + +- Add has enough signers method +- Updated dependencies [undefined] + - @0xsequence/abi@0.21.4 + - @0xsequence/api@0.21.4 + - @0xsequence/config@0.21.4 + - @0xsequence/network@0.21.4 + - @0xsequence/utils@0.21.4 + - @0xsequence/wallet@0.21.4 + +## 0.21.3 + +### Patch Changes + +- add window session cache +- Updated dependencies [undefined] + - @0xsequence/abi@0.21.3 + - @0xsequence/api@0.21.3 + - @0xsequence/config@0.21.3 + - @0xsequence/network@0.21.3 + - @0xsequence/utils@0.21.3 + - @0xsequence/wallet@0.21.3 + +## 0.21.2 + +### Patch Changes + +- exception handlind in relayer +- Updated dependencies [undefined] + - @0xsequence/abi@0.21.2 + - @0xsequence/api@0.21.2 + - @0xsequence/config@0.21.2 + - @0xsequence/network@0.21.2 + - @0xsequence/utils@0.21.2 + - @0xsequence/wallet@0.21.2 + +## 0.21.1 + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/wallet@0.21.1 + +## 0.21.0 + +### Minor Changes + +- - fix gas estimation on wallets with large number of signers + - update to session handling and wallet config construction upon auth + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.21.0 + - @0xsequence/api@0.21.0 + - @0xsequence/config@0.21.0 + - @0xsequence/network@0.21.0 + - @0xsequence/utils@0.21.0 + - @0xsequence/wallet@0.21.0 + +## 0.20.0 + +### Minor Changes + +- revert JWT request piggybacking + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/api@0.20.0 + +## 0.19.3 + +### Patch Changes + +- jwtAuth visibility, package version sync +- Updated dependencies [undefined] + - @0xsequence/abi@0.19.3 + - @0xsequence/api@0.19.3 + - @0xsequence/config@0.19.3 + - @0xsequence/network@0.19.3 + - @0xsequence/utils@0.19.3 + - @0xsequence/wallet@0.19.3 + +## 0.19.2 + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.19.2 + - @0xsequence/config@0.19.2 + - @0xsequence/wallet@0.19.2 + +## 0.19.0 + +### Minor Changes + +- - provider, improve dapp / wallet transport io + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.19.0 + - @0xsequence/api@0.19.0 + - @0xsequence/config@0.19.0 + - @0xsequence/network@0.19.0 + - @0xsequence/utils@0.19.0 + - @0xsequence/wallet@0.19.0 + +## 0.18.0 + +### Minor Changes + +- relayer improvements and pending transaction handling + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.18.0 + - @0xsequence/api@0.18.0 + - @0xsequence/config@0.18.0 + - @0xsequence/network@0.18.0 + - @0xsequence/wallet@0.18.0 + +## 0.17.0 + +### Minor Changes + +- piggyback on already pending JWT and signing requests + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/api@0.17.0 + +## 0.16.1 + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/api@0.16.1 + +## 0.16.0 + +### Minor Changes + +- relayer as its own service separate from chaind + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.16.0 + - @0xsequence/api@0.16.0 + - @0xsequence/config@0.16.0 + - @0xsequence/network@0.16.0 + - @0xsequence/wallet@0.16.0 + +## 0.15.1 + +### Patch Changes + +- update api clients +- Updated dependencies [undefined] + - @0xsequence/abi@0.15.1 + - @0xsequence/api@0.15.1 + - @0xsequence/config@0.15.1 + - @0xsequence/network@0.15.1 + - @0xsequence/wallet@0.15.1 + +## 0.15.0 + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/api@0.15.0 + - @0xsequence/wallet@0.15.0 + +## 0.14.3 + +### Patch Changes + +- Fix 0xSequence relayer dependencies +- Updated dependencies [undefined] + - @0xsequence/abi@0.14.3 + - @0xsequence/api@0.14.3 + - @0xsequence/config@0.14.3 + - @0xsequence/network@0.14.3 + - @0xsequence/wallet@0.14.3 + +## 0.14.2 + +### Patch Changes + +- Add debug logs to rpc-relayer +- Updated dependencies [undefined] + - @0xsequence/abi@0.14.2 + - @0xsequence/api@0.14.2 + - @0xsequence/config@0.14.2 + - @0xsequence/network@0.14.2 + - @0xsequence/wallet@0.14.2 + +## 0.14.0 + +### Minor Changes + +- update sequence utils finder which includes optimization + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.14.0 + - @0xsequence/api@0.14.0 + - @0xsequence/config@0.14.0 + - @0xsequence/network@0.14.0 + - @0xsequence/wallet@0.14.0 + +## 0.13.0 + +### Minor Changes + +- Update SequenceUtils deployed contract + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.13.0 + - @0xsequence/api@0.13.0 + - @0xsequence/config@0.13.0 + - @0xsequence/network@0.13.0 + - @0xsequence/wallet@0.13.0 + +## 0.12.1 + +### Patch Changes + +- npm bump +- Updated dependencies [undefined] + - @0xsequence/abi@0.12.1 + - @0xsequence/api@0.12.1 + - @0xsequence/config@0.12.1 + - @0xsequence/network@0.12.1 + - @0xsequence/wallet@0.12.1 + +## 0.12.0 + +### Minor Changes + +- provider: improvements to window transport + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.12.0 + - @0xsequence/api@0.12.0 + - @0xsequence/config@0.12.0 + - @0xsequence/network@0.12.0 + - @0xsequence/wallet@0.12.0 + +## 0.11.4 + +### Patch Changes + +- update api client +- Updated dependencies [undefined] + - @0xsequence/api@0.11.4 + - @0xsequence/abi@0.11.4 + - @0xsequence/config@0.11.4 + - @0xsequence/network@0.11.4 + - @0xsequence/wallet@0.11.4 + +## 0.11.3 + +### Patch Changes + +- improve openWindow state options handling +- Updated dependencies [undefined] + - @0xsequence/abi@0.11.3 + - @0xsequence/api@0.11.3 + - @0xsequence/config@0.11.3 + - @0xsequence/network@0.11.3 + - @0xsequence/wallet@0.11.3 + +## 0.11.2 + +### Patch Changes + +- Fix multicall proxy scopes +- Updated dependencies [undefined] + - @0xsequence/abi@0.11.2 + - @0xsequence/api@0.11.2 + - @0xsequence/config@0.11.2 + - @0xsequence/network@0.11.2 + - @0xsequence/wallet@0.11.2 + +## 0.11.1 + +### Patch Changes + +- Add support for dynamic and nested signatures +- Updated dependencies [undefined] + - @0xsequence/abi@0.11.1 + - @0xsequence/api@0.11.1 + - @0xsequence/config@0.11.1 + - @0xsequence/network@0.11.1 + - @0xsequence/wallet@0.11.1 + +## 0.11.0 + +### Minor Changes + +- Update wallet context to 1.7 contracts + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.11.0 + - @0xsequence/api@0.11.0 + - @0xsequence/config@0.11.0 + - @0xsequence/network@0.11.0 + - @0xsequence/wallet@0.11.0 + +## 0.10.9 + +### Patch Changes + +- add support for public addresses as signers in session.open +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.9 + - @0xsequence/api@0.10.9 + - @0xsequence/config@0.10.9 + - @0xsequence/network@0.10.9 + - @0xsequence/wallet@0.10.9 + +## 0.10.8 + +### Patch Changes + +- Multicall production configuration +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.8 + - @0xsequence/api@0.10.8 + - @0xsequence/config@0.10.8 + - @0xsequence/network@0.10.8 + - @0xsequence/wallet@0.10.8 + +## 0.10.7 + +### Patch Changes + +- allow provider transport to force disconnect +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.7 + - @0xsequence/api@0.10.7 + - @0xsequence/config@0.10.7 + - @0xsequence/network@0.10.7 + - @0xsequence/wallet@0.10.7 + +## 0.10.6 + +### Patch Changes + +- - fix getWalletState method +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.6 + - @0xsequence/api@0.10.6 + - @0xsequence/config@0.10.6 + - @0xsequence/network@0.10.6 + - @0xsequence/wallet@0.10.6 + +## 0.10.5 + +### Patch Changes + +- update relayer gas refund options +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.5 + - @0xsequence/api@0.10.5 + - @0xsequence/config@0.10.5 + - @0xsequence/network@0.10.5 + - @0xsequence/wallet@0.10.5 + +## 0.10.4 + +### Patch Changes + +- Update api proto +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.4 + - @0xsequence/api@0.10.4 + - @0xsequence/config@0.10.4 + - @0xsequence/network@0.10.4 + - @0xsequence/wallet@0.10.4 + +## 0.10.3 + +### Patch Changes + +- Fix loading config cross-chain +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.3 + - @0xsequence/api@0.10.3 + - @0xsequence/config@0.10.3 + - @0xsequence/network@0.10.3 + - @0xsequence/wallet@0.10.3 + +## 0.10.2 + +### Patch Changes + +- - message digest fix +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.2 + - @0xsequence/api@0.10.2 + - @0xsequence/config@0.10.2 + - @0xsequence/network@0.10.2 + - @0xsequence/wallet@0.10.2 + +## 0.10.1 + +### Patch Changes + +- upgrade deps +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.1 + - @0xsequence/api@0.10.1 + - @0xsequence/config@0.10.1 + - @0xsequence/network@0.10.1 + - @0xsequence/wallet@0.10.1 + +## 0.10.0 + +### Minor Changes + +- Deployed new contracts with ERC1271 signer support + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.0 + - @0xsequence/api@0.10.0 + - @0xsequence/config@0.10.0 + - @0xsequence/network@0.10.0 + - @0xsequence/wallet@0.10.0 + +## 0.9.6 + +### Patch Changes + +- Update ABIs for latest sequence contracts +- Updated dependencies [undefined] + - @0xsequence/api@0.9.6 + - @0xsequence/config@0.9.6 + - @0xsequence/network@0.9.6 + - @0xsequence/wallet@0.9.6 + - @0xsequence/abi@0.9.6 + +## 0.9.5 + +### Patch Changes + +- Implemented session class +- Updated dependencies [undefined] + - @0xsequence/api@0.9.5 + - @0xsequence/config@0.9.5 + - @0xsequence/network@0.9.5 + - @0xsequence/wallet@0.9.5 + +## 0.9.3 + +### Patch Changes + +- - minor improvements +- Updated dependencies [undefined] + - @0xsequence/abi@0.9.3 + - @0xsequence/network@0.9.3 + - @0xsequence/wallet@0.9.3 + +## 0.9.1 + +### Patch Changes + +- - patch bump +- Updated dependencies [undefined] + - @0xsequence/abi@0.9.1 + - @0xsequence/network@0.9.1 + - @0xsequence/wallet@0.9.1 + +## 0.9.0 + +### Minor Changes + +- - provider transport hardening + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.9.0 + - @0xsequence/network@0.9.0 + - @0xsequence/wallet@0.9.0 + +## 0.8.5 + +### Patch Changes + +- - use latest wallet-contracts +- Updated dependencies [undefined] + - @0xsequence/abi@0.8.5 + - @0xsequence/network@0.8.5 + - @0xsequence/wallet@0.8.5 + +## 0.8.4 + +### Patch Changes + +- - minor improvements, name updates and comments +- Updated dependencies [undefined] + - @0xsequence/abi@0.8.4 + - @0xsequence/network@0.8.4 + - @0xsequence/wallet@0.8.4 + +## 0.8.3 + +### Patch Changes + +- - refinements + + - normalize signer address in config + + - provider: getWalletState() method to WalletProvider + +- Updated dependencies [undefined] + - @0xsequence/abi@0.8.3 + - @0xsequence/network@0.8.3 + - @0xsequence/wallet@0.8.3 + +## 0.8.2 + +### Patch Changes + +- - field rename and ethauth dependency bump +- Updated dependencies [undefined] + - @0xsequence/abi@0.8.2 + - @0xsequence/network@0.8.2 + - @0xsequence/wallet@0.8.2 + +## 0.8.1 + +### Patch Changes + +- - variety of optimizations +- Updated dependencies [undefined] + - @0xsequence/abi@0.8.1 + - @0xsequence/network@0.8.1 + - @0xsequence/wallet@0.8.1 + +## 0.8.0 + +### Minor Changes + +- - changeset fix + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.8.0 + - @0xsequence/network@0.8.0 + - @0xsequence/wallet@0.8.0 + +## 0.7.2 + +### Patch Changes + +- package.json fix + +## 0.7.0 + +### Patch Changes + +- 6f11ed7: sequence.js, init release +- Updated dependencies [6f11ed7] + - @0xsequence/abi@0.7.0 + - @0xsequence/network@0.7.0 + - @0xsequence/wallet@0.7.0 diff --git a/packages/auth/README.md b/packages/auth/README.md new file mode 100644 index 0000000000..33f7072359 --- /dev/null +++ b/packages/auth/README.md @@ -0,0 +1,4 @@ +@0xsequence/auth +================ + +See [0xsequence project page](https://github.com/0xsequence/sequence.js). diff --git a/packages/auth/hardhat.config.js b/packages/auth/hardhat.config.js new file mode 100644 index 0000000000..eaca505314 --- /dev/null +++ b/packages/auth/hardhat.config.js @@ -0,0 +1,15 @@ +/** + * @type import('hardhat/config').HardhatUserConfig + */ +module.exports = { + solidity: '0.7.6', + + networks: { + hardhat: { + chainId: 31337, + accounts: { + mnemonic: 'ripple axis someone ridge uniform wrist prosper there frog rate olympic knee' + } + } + } +} diff --git a/packages/auth/package.json b/packages/auth/package.json new file mode 100644 index 0000000000..945ca4f2d8 --- /dev/null +++ b/packages/auth/package.json @@ -0,0 +1,49 @@ +{ + "name": "@0xsequence/auth", + "version": "2.0.0", + "description": "auth sub-package for Sequence", + "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/auth", + "source": "src/index.ts", + "main": "dist/0xsequence-auth.cjs.js", + "module": "dist/0xsequence-auth.esm.js", + "author": "Horizon Blockchain Games", + "license": "Apache-2.0", + "scripts": { + "test": "pnpm test:concurrently 'pnpm test:run'", + "test:run": "pnpm test:file tests/**/*.spec.ts", + "test:file": "NODE_OPTIONS='--import tsx' mocha --timeout 30000", + "test:concurrently": "concurrently -k --success first 'pnpm start:hardhat > /dev/null' ", + "start:hardhat": "hardhat node --port 9546", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@0xsequence/abi": "workspace:*", + "@0xsequence/account": "workspace:*", + "@0xsequence/api": "workspace:*", + "@0xsequence/core": "workspace:*", + "@0xsequence/ethauth": "^0.8.1", + "@0xsequence/indexer": "workspace:*", + "@0xsequence/metadata": "workspace:*", + "@0xsequence/migration": "workspace:*", + "@0xsequence/network": "workspace:*", + "@0xsequence/sessions": "workspace:*", + "@0xsequence/signhub": "workspace:*", + "@0xsequence/wallet": "workspace:*", + "@0xsequence/utils": "workspace:*" + }, + "peerDependencies": { + "ethers": ">=5.5 < 6" + }, + "devDependencies": { + "@0xsequence/tests": "workspace:*", + "@0xsequence/wallet-contracts": "^1.10.0", + "concurrently": "^7.5.0", + "ethers": "^5.7.2", + "hardhat": "^2.20.1", + "mockttp": "^3.6.0" + }, + "files": [ + "src", + "dist" + ] +} diff --git a/packages/auth/src/authorization.ts b/packages/auth/src/authorization.ts new file mode 100644 index 0000000000..103c2b2a79 --- /dev/null +++ b/packages/auth/src/authorization.ts @@ -0,0 +1,81 @@ +import { ethers } from 'ethers' +import { ETHAuth, Proof } from '@0xsequence/ethauth' +import { ChainIdLike, toChainIdNumber } from '@0xsequence/network' +import { TypedData } from '@0xsequence/utils' +import { Signer } from '@0xsequence/wallet' +import { Account } from '@0xsequence/account' +import { DEFAULT_SESSION_EXPIRATION } from './services' + +export interface AuthorizationOptions { + // app name string, ie 'Skyweaver' + app?: string + + // origin hostname of encoded in the message, ie. 'play.skyweaver.net' + origin?: string + + // expiry in seconds encoded in the message + expiry?: number + + // nonce for the authorization request + nonce?: number +} + +export interface ETHAuthProof { + // eip712 typed-data payload for ETHAuth domain as input + typedData: TypedData + + // signature encoded in an ETHAuth proof string + proofString: string +} + +// signAuthorization will perform an EIP712 typed-data message signing of ETHAuth domain via the provided +// Signer and authorization options. +export const signAuthorization = async ( + signer: Signer | Account, + chainId: ChainIdLike, + options: AuthorizationOptions +): Promise => { + const address = ethers.utils.getAddress(await signer.getAddress()) + if (!address || address === '' || address === '0x') { + throw ErrAccountIsRequired + } + + const proof = new Proof() + proof.address = address + + if (!options || !options.app || options.app === '') { + throw new AuthError('authorization options requires app to be set') + } + proof.claims.app = options.app + proof.claims.ogn = options.origin + proof.claims.n = options.nonce + + proof.setExpiryIn(options.expiry ? Math.max(options.expiry, 200) : DEFAULT_SESSION_EXPIRATION) + + const typedData = proof.messageTypedData() + + const chainIdNumber = toChainIdNumber(chainId) + + proof.signature = await (signer instanceof Account + ? // Account can sign EIP-6492 signatures, so it doesn't require deploying the wallet + signer.signTypedData(typedData.domain, typedData.types, typedData.message, chainIdNumber, 'eip6492') + : signer.signTypedData(typedData.domain, typedData.types, typedData.message, chainIdNumber)) + + const ethAuth = new ETHAuth() + const proofString = await ethAuth.encodeProof(proof, true) + + return { + typedData, + proofString + } +} + +// TODO: review...... +export class AuthError extends Error { + constructor(message?: string) { + super(message) + this.name = 'AuthError' + } +} + +export const ErrAccountIsRequired = new AuthError('auth error: account address is empty') diff --git a/packages/auth/src/index.ts b/packages/auth/src/index.ts new file mode 100644 index 0000000000..af64af8df0 --- /dev/null +++ b/packages/auth/src/index.ts @@ -0,0 +1,3 @@ +export * from './authorization' +export * from './session' +export * from './proof' diff --git a/packages/auth/src/proof.ts b/packages/auth/src/proof.ts new file mode 100644 index 0000000000..23051fde69 --- /dev/null +++ b/packages/auth/src/proof.ts @@ -0,0 +1,16 @@ +import { commons } from '@0xsequence/core' +import { Proof, ValidatorFunc } from '@0xsequence/ethauth' +import { tracker } from '@0xsequence/sessions' +import { ethers } from 'ethers' + +export const ValidateSequenceWalletProof = ( + readerFor: (chainId: number) => commons.reader.Reader, + tracker: tracker.ConfigTracker, + context: commons.context.WalletContext +): ValidatorFunc => { + return async (_provider: ethers.providers.JsonRpcProvider, chainId: number, proof: Proof): Promise<{ isValid: boolean }> => { + const digest = proof.messageDigest() + const isValid = await readerFor(chainId).isValidSignature(proof.address, digest, proof.signature) + return { isValid } + } +} diff --git a/packages/auth/src/services.ts b/packages/auth/src/services.ts new file mode 100644 index 0000000000..6db53a216d --- /dev/null +++ b/packages/auth/src/services.ts @@ -0,0 +1,337 @@ +import { Account } from '@0xsequence/account' +import { SequenceAPIClient } from '@0xsequence/api' +import { ETHAuth, Proof } from '@0xsequence/ethauth' +import { Indexer, SequenceIndexer } from '@0xsequence/indexer' +import { SequenceMetadata } from '@0xsequence/metadata' +import { ChainIdLike, findNetworkConfig } from '@0xsequence/network' +import { getEthersConnectionInfo } from '@0xsequence/utils' +import { ethers } from 'ethers' + +export type SessionMeta = { + // name of the app requesting the session, used with ETHAuth + name: string + + // expiration in seconds for a session before it expires, used with ETHAuth + expiration?: number +} + +export type ServicesSettings = { + metadata: SessionMeta + sequenceApiUrl: string + sequenceApiChainId: ethers.BigNumberish + sequenceMetadataUrl: string +} + +export type SessionJWT = { + token: string + expiration: number +} + +export type SessionJWTPromise = { + token: Promise + expiration: number +} + +export type ProofStringPromise = { + proofString: Promise + expiration: number +} + +// Default session expiration of ETHAuth token (1 week) +export const DEFAULT_SESSION_EXPIRATION = 60 * 60 * 24 * 7 + +// Long session expiration of ETHAuth token (~1 year) +export const LONG_SESSION_EXPIRATION = 3e7 + +const EXPIRATION_JWT_MARGIN = 60 // seconds + +export class Services { + _initialAuthRequest: Promise + + // proof strings are indexed by account address and app name, see getProofStringKey() + private readonly proofStrings: Map = new Map() + + private onAuthCallbacks: ((result: PromiseSettledResult) => void)[] = [] + + private apiClient: SequenceAPIClient | undefined + private metadataClient: SequenceMetadata | undefined + private indexerClients: Map = new Map() + + private projectAccessKey?: string + + constructor( + public readonly account: Account, + public readonly settings: ServicesSettings, + public readonly status: { + jwt?: SessionJWTPromise + metadata?: SessionMeta + } = {}, + projectAccessKey?: string + ) { + this.projectAccessKey = projectAccessKey + } + + private now(): number { + return Math.floor(Date.now() / 1000) + } + + get expiration(): number { + return Math.max(this.settings.metadata.expiration ?? DEFAULT_SESSION_EXPIRATION, 120) + } + + onAuth(cb: (result: PromiseSettledResult) => void) { + this.onAuthCallbacks.push(cb) + return () => (this.onAuthCallbacks = this.onAuthCallbacks.filter(c => c !== cb)) + } + + async dump(): Promise<{ + jwt?: SessionJWT + metadata?: SessionMeta + }> { + if (!this.status.jwt) return { metadata: this.settings.metadata } + + return { + jwt: { + token: await this.status.jwt.token, + expiration: this.status.jwt.expiration + }, + metadata: this.status.metadata + } + } + + auth(maxTries: number = 5): Promise { + if (this._initialAuthRequest) return this._initialAuthRequest + + this._initialAuthRequest = (async () => { + const url = this.settings.sequenceApiUrl + if (!url) throw Error('No sequence api url') + + let jwtAuth: string | undefined + for (let i = 1; ; i++) { + try { + jwtAuth = (await this.getJWT(true)).token + break + } catch (error) { + if (i === maxTries) { + console.error(`couldn't authenticate after ${maxTries} attempts`, error) + throw error + } + } + } + + return new SequenceAPIClient(url, undefined, jwtAuth) + })() + + return this._initialAuthRequest + } + + private async getJWT(tryAuth: boolean): Promise { + const url = this.settings.sequenceApiUrl + if (!url) throw Error('No sequence api url') + + // check if we already have or are waiting for a token + if (this.status.jwt) { + const jwt = this.status.jwt + const token = await jwt.token + + if (this.now() < jwt.expiration) { + return { token, expiration: jwt.expiration } + } + + // token expired, delete it and get a new one + this.status.jwt = undefined + } + + if (!tryAuth) { + throw new Error('no auth token in memory') + } + + const proofStringKey = this.getProofStringKey() + const { proofString, expiration } = this.getProofString(proofStringKey) + + const jwt = { + token: proofString + .then(async proofString => { + const api = new SequenceAPIClient(url) + + const authResp = await api.getAuthToken({ ewtString: proofString }) + + if (authResp?.status === true && authResp.jwtToken.length !== 0) { + return authResp.jwtToken + } else { + if (!(await this.isProofStringValid(proofString))) { + this.proofStrings.delete(proofStringKey) + } + throw new Error('no auth token from server') + } + }) + .catch(reason => { + this.status.jwt = undefined + throw reason + }), + expiration + } + + this.status.jwt = jwt + + jwt.token + .then(token => { + this.onAuthCallbacks.forEach(cb => { + try { + cb({ status: 'fulfilled', value: token }) + } catch {} + }) + }) + .catch((reason: any) => { + this.onAuthCallbacks.forEach(cb => { + try { + cb({ status: 'rejected', reason }) + } catch {} + }) + }) + + const token = await jwt.token + return { token, expiration } + } + + private getProofStringKey(): string { + return `${this.account.address} - ${this.settings.metadata.name}` + } + + private async isProofStringValid(proofString: string): Promise { + try { + const ethAuth = new ETHAuth() + const chainId = ethers.BigNumber.from(this.settings.sequenceApiChainId) + const network = findNetworkConfig(this.account.networks, chainId) + if (!network) throw Error('No network found') + ethAuth.chainId = chainId.toNumber() + + // TODO: Modify ETHAuth so it can take a provider instead of a url + // ----- + // Can't pass jwt here since this is used for getting the jwt + ethAuth.provider = new ethers.providers.StaticJsonRpcProvider( + getEthersConnectionInfo(network.rpcUrl, this.projectAccessKey), + { + name: '', + chainId: chainId.toNumber() + } + ) + + await ethAuth.decodeProof(proofString) + + return true + } catch { + return false + } + } + + async getAPIClient(tryAuth: boolean = true): Promise { + if (!this.apiClient) { + const url = this.settings.sequenceApiUrl + if (!url) throw Error('No sequence api url') + + const jwtAuth = (await this.getJWT(tryAuth)).token + this.apiClient = new SequenceAPIClient(url, undefined, jwtAuth) + } + + return this.apiClient + } + + async getMetadataClient(tryAuth: boolean = true): Promise { + if (!this.metadataClient) { + const jwtAuth = (await this.getJWT(tryAuth)).token + this.metadataClient = new SequenceMetadata(this.settings.sequenceMetadataUrl, undefined, jwtAuth) + } + + return this.metadataClient + } + + async getIndexerClient(chainId: ChainIdLike, tryAuth: boolean = true): Promise { + const network = findNetworkConfig(this.account.networks, chainId) + if (!network) { + throw Error(`No network for chain ${chainId}`) + } + + if (!this.indexerClients.has(network.chainId)) { + if (network.indexer) { + this.indexerClients.set(network.chainId, network.indexer) + } else if (network.indexerUrl) { + const jwtAuth = (await this.getJWT(tryAuth)).token + this.indexerClients.set(network.chainId, new SequenceIndexer(network.indexerUrl, undefined, jwtAuth)) + } else { + throw Error(`No indexer url for chain ${chainId}`) + } + } + + return this.indexerClients.get(network.chainId)! + } + + private getProofString(key: string): ProofStringPromise { + // check if we already have or are waiting for a proof string + if (this.proofStrings.has(key)) { + const proofString = this.proofStrings.get(key)! + + if (this.now() < proofString.expiration) { + return proofString + } + + // proof string expired, delete it and make a new one + this.proofStrings.delete(key) + } + + const proof = new Proof({ + address: this.account.address + }) + + proof.claims.app = this.settings.metadata.name + if (typeof window === 'object') { + proof.claims.ogn = window.location.origin + } + proof.setExpiryIn(this.expiration) + + const ethAuth = new ETHAuth() + const chainId = ethers.BigNumber.from(this.settings.sequenceApiChainId) + const network = findNetworkConfig(this.account.networks, chainId) + if (!network) throw Error('No network found') + ethAuth.chainId = chainId.toNumber() + // TODO: Modify ETHAuth so it can take a provider instead of a url + // ----- + // Can't pass jwt here since this is used for getting the jwt + ethAuth.provider = new ethers.providers.StaticJsonRpcProvider( + getEthersConnectionInfo(network.rpcUrl, this.projectAccessKey), + { + name: '', + chainId: chainId.toNumber() + } + ) + + const expiration = this.now() + this.expiration - EXPIRATION_JWT_MARGIN + + const proofString = { + proofString: Promise.resolve( + // NOTICE: TODO: Here we ask the account to sign the message + // using whatever configuration we have ON-CHAIN, this means + // that the account will still use the v1 wallet, even if the migration + // was signed. + // + // This works for Sequence webapp v1 -> v2 because all v1 configurations share the same formula + // (torus + guard), but if we ever decide to allow cross-device login, then it will not work, because + // those other signers may not be part of the configuration. + // + this.account.signDigest(proof.messageDigest(), this.settings.sequenceApiChainId, true, 'eip6492') + ) + .then(s => { + proof.signature = s + return ethAuth.encodeProof(proof, true) + }) + .catch(reason => { + this.proofStrings.delete(key) + throw reason + }), + expiration + } + + this.proofStrings.set(key, proofString) + return proofString + } +} diff --git a/packages/auth/src/session.ts b/packages/auth/src/session.ts new file mode 100644 index 0000000000..84820df9a1 --- /dev/null +++ b/packages/auth/src/session.ts @@ -0,0 +1,397 @@ +import { ChainId, NetworkConfig, allNetworks, findNetworkConfig } from '@0xsequence/network' +import { jwtDecodeClaims } from '@0xsequence/utils' +import { Account } from '@0xsequence/account' +import { ethers } from 'ethers' +import { tracker, trackers } from '@0xsequence/sessions' +import { Orchestrator, SignatureOrchestrator, signers } from '@0xsequence/signhub' +import { migrator } from '@0xsequence/migration' +import { commons, universal, v1 } from '@0xsequence/core' +import { Services, ServicesSettings, SessionJWT, SessionMeta } from './services' + +export interface SessionDumpV1 { + config: Omit & { address?: string } + jwt?: SessionJWT + metadata: SessionMeta +} + +export interface SessionDumpV2 { + version: 2 + address: string + jwt?: SessionJWT + metadata?: SessionMeta +} + +export function isSessionDumpV1(obj: any): obj is SessionDumpV1 { + return obj.config && obj.metadata && obj.version === undefined +} + +export function isSessionDumpV2(obj: any): obj is SessionDumpV2 { + return obj.version === 2 && obj.address +} + +// These chains are always validated for migrations +// if they are not available, the login will fail +export const CRITICAL_CHAINS = [1, 137] + +export type SessionSettings = { + services?: ServicesSettings + contexts: commons.context.VersionedContext + networks: NetworkConfig[] + tracker: tracker.ConfigTracker & migrator.PresignedMigrationTracker +} + +export const SessionSettingsDefault: SessionSettings = { + contexts: commons.context.defaultContexts, + networks: allNetworks, + tracker: new trackers.remote.RemoteConfigTracker('https://sessions.sequence.app') +} + +export class Session { + constructor( + public networks: NetworkConfig[], + public contexts: commons.context.VersionedContext, + public account: Account, + public services?: Services + ) {} + + async dump(): Promise { + const base = { + version: 2 as const, + address: this.account.address + } + + if (this.services) { + return { + ...base, + ...(await this.services.dump()) + } + } + + return base + } + + static async singleSigner(args: { + settings?: Partial + signer: ethers.Signer | signers.SapientSigner | string + selectWallet?: (wallets: string[]) => Promise + onAccountAddress?: (address: string) => void + onMigration?: (account: Account) => Promise + editConfigOnMigration?: (config: commons.config.Config) => commons.config.Config + projectAccessKey: string + }): Promise { + let { signer } = args + + if (typeof signer === 'string') { + signer = new ethers.Wallet(signer) + } + + const orchestrator = new Orchestrator([signer]) + const referenceSigner = await signer.getAddress() + const threshold = 1 + const addSigners = [ + { + weight: 1, + address: referenceSigner + } + ] + + const selectWallet = + args.selectWallet || + (async (wallets: string[]) => { + if (wallets.length === 0) return undefined + + // Find a wallet that was originally created + // as a 1/1 of the reference signer + const tracker = args.settings?.tracker ?? SessionSettingsDefault.tracker + + const configs = await Promise.all( + wallets.map(async wallet => { + const imageHash = await tracker.imageHashOfCounterfactualWallet({ wallet }) + + return { + wallet, + config: imageHash && (await tracker.configOfImageHash({ imageHash: imageHash.imageHash })) + } + }) + ) + + for (const config of configs) { + if (!config.config) { + continue + } + + const coder = universal.genericCoderFor(config.config.version) + const signers = coder.config.signersOf(config.config) + + if (signers.length === 1 && signers[0].address === referenceSigner) { + return config.wallet + } + } + + return undefined + }) + + return Session.open({ + ...args, + orchestrator, + referenceSigner, + threshold, + addSigners, + selectWallet + }) + } + + static async open(args: { + settings?: Partial + orchestrator: SignatureOrchestrator + addSigners?: commons.config.SimpleSigner[] + referenceSigner: string + threshold?: ethers.BigNumberish + selectWallet: (wallets: string[]) => Promise + onAccountAddress?: (address: string) => void + editConfigOnMigration?: (config: commons.config.Config) => commons.config.Config + onMigration?: (account: Account) => Promise + projectAccessKey?: string + }): Promise { + const { + referenceSigner, + threshold, + addSigners, + selectWallet, + onAccountAddress, + settings, + editConfigOnMigration, + onMigration, + orchestrator, + projectAccessKey + } = args + + const { contexts, networks, tracker, services } = { ...SessionSettingsDefault, ...settings } + + // The reference network is mainnet, if mainnet is not available, we use the first network + const referenceChainId = + findNetworkConfig(networks, settings?.services?.sequenceApiChainId ?? ChainId.MAINNET)?.chainId ?? networks[0]?.chainId + if (!referenceChainId) throw Error('No reference chain found') + + const foundWallets = await tracker.walletsOfSigner({ signer: referenceSigner }) + const selectedWallet = await selectWallet(foundWallets.map(w => w.wallet)) + + let account: Account + + if (selectedWallet) { + onAccountAddress?.(selectedWallet) + + // existing account, lets update it + account = new Account({ + address: selectedWallet, + tracker, + networks, + contexts, + orchestrator, + projectAccessKey + }) + + // Get the latest configuration of the wallet (on the reference chain) + // now this configuration should be of the latest version, so we can start + // manipulating it. + + // NOTICE: We are performing the wallet update on a single chain, assuming that + // all other networks have the same configuration. This is not always true. + if (addSigners && addSigners.length > 0) { + // New wallets never need migrations + // (because we create them on the latest version) + let status = await account.status(referenceChainId) + + // If the wallet was created originally on v2, then we can skip + // the migration checks all together. + if (status.original.version !== status.version || account.version !== status.version) { + // Account may not have been migrated yet, so we need to check + // if it has been migrated and if not, migrate it (in all chains) + const { migratedAllChains: isFullyMigrated, failedChains } = await account.isMigratedAllChains() + + // Failed chains must not contain mainnet or polygon, otherwise we cannot proceed. + if (failedChains.some(c => CRITICAL_CHAINS.includes(c))) { + throw Error(`Failed to fetch account status on ${failedChains.join(', ')}`) + } + + if (!isFullyMigrated) { + // This is an oportunity for whoever is opening the session to + // feed the orchestrator with more signers, so that the migration + // can be completed. + if (onMigration && !(await onMigration(account))) { + throw Error('Migration cancelled, cannot open session') + } + + const { failedChains } = await account.signAllMigrations(editConfigOnMigration || (c => c)) + if (failedChains.some(c => CRITICAL_CHAINS.includes(c))) { + throw Error(`Failed to sign migrations on ${failedChains.join(', ')}`) + } + + // If we are using a dedupped tracker we need to invalidate the cache + // otherwise we run the risk of not seeing the signed migrations reflected. + if (trackers.isDedupedTracker(tracker)) { + tracker.invalidateCache() + } + + let isFullyMigrated2: boolean + ;[isFullyMigrated2, status] = await Promise.all([ + account.isMigratedAllChains().then(r => r.migratedAllChains), + account.status(referenceChainId) + ]) + + if (!isFullyMigrated2) throw Error('Failed to migrate account') + } + } + + // NOTICE: We only need to do this because the API will not be able to + // validate the v2 signature (if the account has an onchain version of 1) + // we could speed this up by sending the migration alongside the jwt request + // and letting the API validate it offchain. + if (status.onChain.version !== status.version) { + await account.doBootstrap(referenceChainId, undefined, status) + } + + const prevConfig = status.config + const nextConfig = account.coders.config.editConfig(prevConfig, { + add: addSigners, + threshold + }) + + // Only update the onchain config if the imageHash has changed + if (account.coders.config.imageHashOf(prevConfig) !== account.coders.config.imageHashOf(nextConfig)) { + const newConfig = account.coders.config.editConfig(nextConfig, { + checkpoint: account.coders.config.checkpointOf(prevConfig).add(1) + }) + + await account.updateConfig(newConfig) + } + } + } else { + if (!addSigners || addSigners.length === 0) { + throw Error('Cannot create new account without signers') + } + + if (!threshold) { + throw Error('Cannot create new account without threshold') + } + + // fresh account + account = await Account.new({ + config: { threshold, checkpoint: 0, signers: addSigners }, + tracker, + contexts, + orchestrator, + networks, + projectAccessKey + }) + + onAccountAddress?.(account.address) + + // sign a digest and send it to the tracker + // otherwise the tracker will not know about this account + await account.publishWitness() + + // safety check, the remove tracker should be able to find + // this account for the reference signer + const foundWallets = await tracker.walletsOfSigner({ signer: referenceSigner, noCache: true }) + if (!foundWallets.some(w => w.wallet === account.address)) { + throw Error('Account not found on tracker') + } + } + + let servicesObj: Services | undefined + + if (services) { + servicesObj = new Services(account, services) + servicesObj.auth() // fire and forget + + servicesObj.onAuth(result => { + if (result.status === 'fulfilled') { + account.setJwt(result.value) + } + }) + } + + return new Session(networks, contexts, account, servicesObj) + } + + static async load(args: { + settings?: Partial + orchestrator: SignatureOrchestrator + dump: SessionDumpV1 | SessionDumpV2 + editConfigOnMigration: (config: commons.config.Config) => commons.config.Config + onMigration?: (account: Account) => Promise + }): Promise { + const { dump, settings, editConfigOnMigration, onMigration, orchestrator } = args + const { contexts, networks, tracker, services } = { ...SessionSettingsDefault, ...settings } + + let account: Account + + if (isSessionDumpV1(dump)) { + // Old configuration format used to also contain an "address" field + // but if it doesn't, it means that it was a "counterfactual" account + // not yet updated, so we need to compute the address + const oldAddress = + dump.config.address || + commons.context.addressOf(contexts[1], v1.config.ConfigCoder.imageHashOf({ ...dump.config, version: 1 })) + + const jwtExpired = (dump.jwt?.expiration ?? 0) < Math.floor(Date.now() / 1000) + + account = new Account({ + address: oldAddress, + tracker, + networks, + contexts, + orchestrator, + jwt: jwtExpired ? undefined : dump.jwt?.token + }) + + // TODO: This property may not hold if the user adds a new network + if (!(await account.isMigratedAllChains().then(r => r.migratedAllChains))) { + // This is an oportunity for whoever is opening the session to + // feed the orchestrator with more signers, so that the migration + // can be completed. + if (onMigration && !(await onMigration(account))) { + throw Error('Migration cancelled, cannot open session') + } + + console.log('Migrating account...') + await account.signAllMigrations(editConfigOnMigration) + if (!(await account.isMigratedAllChains().then(r => r.migratedAllChains))) throw Error('Failed to migrate account') + } + + // We may need to update the JWT if the account has been migrated + } else if (isSessionDumpV2(dump)) { + const jwtExpired = (dump.jwt?.expiration ?? 0) < Math.floor(Date.now() / 1000) + + account = new Account({ + address: dump.address, + tracker, + networks, + contexts, + orchestrator, + jwt: jwtExpired ? undefined : dump.jwt?.token + }) + } else { + throw Error('Invalid dump format') + } + + let servicesObj: Services | undefined + + if (services) { + servicesObj = new Services( + account, + services, + dump.jwt && { + jwt: { + token: Promise.resolve(dump.jwt.token), + expiration: dump.jwt.expiration ?? jwtDecodeClaims(dump.jwt.token).exp + }, + metadata: dump.metadata + } + ) + } + + return new Session(networks, contexts, account, servicesObj) + } +} diff --git a/packages/auth/tests/session.spec.ts b/packages/auth/tests/session.spec.ts new file mode 100644 index 0000000000..8e0c4091dd --- /dev/null +++ b/packages/auth/tests/session.spec.ts @@ -0,0 +1,1424 @@ +import { Account } from '@0xsequence/account' +import { commons, v1, v2 } from '@0xsequence/core' +import { ETHAuth, Proof } from '@0xsequence/ethauth' +import { migrator } from '@0xsequence/migration' +import { NetworkConfig } from '@0xsequence/network' +import { LocalRelayer } from '@0xsequence/relayer' +import { tracker, trackers } from '@0xsequence/sessions' +import { Orchestrator, SignatureOrchestrator } from '@0xsequence/signhub' +import * as utils from '@0xsequence/tests' +import { CallReceiverMock, HookCallerMock } from '@0xsequence/wallet-contracts' +import * as chai from 'chai' +import chaiAsPromised from 'chai-as-promised' +import { ethers, Signer as AbstractSigner } from 'ethers' +import * as mockServer from 'mockttp' +import { Session, SessionDumpV1, SessionSettings, ValidateSequenceWalletProof } from '../src' +import { delay, mockDate } from './utils' + +const CallReceiverMockArtifact = require('@0xsequence/wallet-contracts/artifacts/contracts/mocks/CallReceiverMock.sol/CallReceiverMock.json') +const HookCallerMockArtifact = require('@0xsequence/wallet-contracts/artifacts/contracts/mocks/HookCallerMock.sol/HookCallerMock.json') + +const { expect } = chai.use(chaiAsPromised) + +const deterministic = false + +type EthereumInstance = { + chainId?: number + providerUrl?: string + provider?: ethers.providers.JsonRpcProvider + signer?: AbstractSigner +} + +class CountingSigner extends AbstractSigner { + private _signingRequests: number = 0 + + constructor(private readonly signer: AbstractSigner) { + super() + } + + get signingRequests(): number { + return this._signingRequests + } + + getAddress(): Promise { + return this.signer.getAddress() + } + + signMessage(message: ethers.Bytes | string): Promise { + this._signingRequests++ + return this.signer.signMessage(message) + } + + signTransaction(transaction: ethers.utils.Deferrable): Promise { + this._signingRequests++ + return this.signer.signTransaction(transaction) + } + + connect(provider: ethers.providers.Provider): ethers.Signer { + return this.signer.connect(provider) + } +} + +describe('Wallet integration', function () { + const ethnode: EthereumInstance = {} + + let relayer: LocalRelayer + let callReceiver: CallReceiverMock + let hookCaller: HookCallerMock + + let contexts: commons.context.VersionedContext + let networks: NetworkConfig[] + + let tracker: tracker.ConfigTracker & migrator.PresignedMigrationTracker + let orchestrator: SignatureOrchestrator + let simpleSettings: SessionSettings + + before(async () => { + // Provider from hardhat without a server instance + ethnode.providerUrl = `http://127.0.0.1:9546/` + ethnode.provider = new ethers.providers.JsonRpcProvider(ethnode.providerUrl) + + const chainId = (await ethnode.provider.getNetwork()).chainId + ethnode.signer = ethnode.provider.getSigner() + ethnode.chainId = chainId + + // Deploy local relayer + relayer = new LocalRelayer(ethnode.signer) + + networks = [ + { + name: 'local', + chainId, + provider: ethnode.provider, + isDefaultChain: true, + relayer, + rpcUrl: '', + nativeToken: { + symbol: 'ETH', + name: 'Ether', + decimals: 18 + } + } + ] as NetworkConfig[] + + contexts = await utils.context.deploySequenceContexts(ethnode.signer) + + // Deploy call receiver mock + callReceiver = (await new ethers.ContractFactory( + CallReceiverMockArtifact.abi, + CallReceiverMockArtifact.bytecode, + ethnode.signer + ).deploy()) as CallReceiverMock + + // Deploy hook caller mock + hookCaller = (await new ethers.ContractFactory( + HookCallerMockArtifact.abi, + HookCallerMockArtifact.bytecode, + ethnode.signer + ).deploy()) as HookCallerMock + + tracker = new trackers.local.LocalConfigTracker(ethnode.provider!) + orchestrator = new Orchestrator([]) + + simpleSettings = { + contexts, + networks, + tracker, + services: { + metadata: { + name: 'test' + }, + sequenceApiUrl: '', + sequenceApiChainId: chainId, + sequenceMetadataUrl: '' + } + } + }) + + it('Should open a new session', async () => { + const referenceSigner = randomWallet('Should open a new session') + orchestrator.setSigners([referenceSigner]) + + const session = await Session.open({ + orchestrator, + settings: simpleSettings, + referenceSigner: referenceSigner.address, + addSigners: [{ address: referenceSigner.address, weight: 1 }], + threshold: 1, + selectWallet: async ws => { + expect(ws.length).to.equal(0) + return undefined + }, + editConfigOnMigration: config => config + }) + + expect(session.account.address).to.not.equal(ethers.constants.AddressZero) + + const status = await session.account.status(networks[0].chainId) + + expect(v2.config.isWalletConfig(status.config)).to.equal(true) + const configv2 = status.config as v2.config.WalletConfig + + expect(ethers.BigNumber.from(configv2.threshold)).to.deep.equal(ethers.BigNumber.from(1)) + expect(v2.config.isSignerLeaf(configv2.tree)).to.equal(true) + + const leaf = configv2.tree as v2.config.SignerLeaf + expect(leaf.address).to.equal(referenceSigner.address) + expect(ethers.BigNumber.from(leaf.weight)).to.deep.equal(ethers.BigNumber.from(1)) + + await session.account.sendTransaction({ to: referenceSigner.address }, networks[0].chainId) + }) + + it('Should dump and load a session', async () => { + const referenceSigner = randomWallet('Should dump and load a session') + orchestrator.setSigners([referenceSigner]) + + const session = await Session.open({ + settings: simpleSettings, + orchestrator, + referenceSigner: referenceSigner.address, + addSigners: [{ address: referenceSigner.address, weight: 1 }], + threshold: 1, + selectWallet: async ws => { + expect(ws.length).to.equal(0) + return undefined + }, + editConfigOnMigration: config => config + }) + + const dump = await session.dump() + + const session2 = await Session.load({ + settings: simpleSettings, + orchestrator, + dump, + editConfigOnMigration: config => config + }) + + await session.account.sendTransaction({ to: referenceSigner.address }, networks[0].chainId) + + expect(session.account.address).to.equal(session2.account.address) + }) + + it('Should open an existing session', async () => { + const referenceSigner = randomWallet('Should open an existing session') + orchestrator.setSigners([referenceSigner]) + + const session = await Session.open({ + settings: simpleSettings, + orchestrator, + referenceSigner: referenceSigner.address, + addSigners: [{ address: referenceSigner.address, weight: 1 }], + threshold: 1, + selectWallet: async ws => ws[0] ?? undefined, + editConfigOnMigration: config => config + }) + + const newSigner = randomWallet('Should open an existing session 2') + const session2 = await Session.open({ + settings: simpleSettings, + orchestrator, + referenceSigner: referenceSigner.address, + addSigners: [{ address: newSigner.address, weight: 1 }], + threshold: 2, + selectWallet: async ws => { + expect(ws.length).to.equal(1) + return ws[0] + }, + editConfigOnMigration: config => config + }) + + const newConfig = (await session2.account.status(networks[0].chainId).then(s => s.config)) as v2.config.WalletConfig + + expect(session2.account.address).to.equal(session.account.address) + expect(ethers.BigNumber.from(newConfig.threshold)).to.deep.equal(ethers.BigNumber.from(2)) + + const newSigners = v2.config.signersOf(newConfig.tree).map(s => s.address) + expect(newSigners.length).to.equal(2) + expect(newSigners).to.include(newSigner.address) + expect(newSigners).to.include(referenceSigner.address) + expect(ethers.BigNumber.from((newConfig.tree as any).left.weight)).to.deep.equal(ethers.BigNumber.from(1)) + expect(ethers.BigNumber.from((newConfig.tree as any).right.weight)).to.deep.equal(ethers.BigNumber.from(1)) + }) + + it('Should create a new account if selectWallet returns undefined', async () => { + const referenceSigner = randomWallet('Should create a new account if selectWallet returns undefined') + orchestrator.setSigners([referenceSigner]) + + const oldSession = await Session.open({ + settings: simpleSettings, + orchestrator, + referenceSigner: referenceSigner.address, + addSigners: [{ address: referenceSigner.address, weight: 1 }], + threshold: 1, + selectWallet: async () => undefined, + editConfigOnMigration: config => config + }) + + const newSigner = randomWallet('Should create a new account if selectWallet returns undefined 2') + const newSession = await Session.open({ + settings: simpleSettings, + orchestrator, + referenceSigner: referenceSigner.address, + addSigners: [ + { address: referenceSigner.address, weight: 1 }, + { address: newSigner.address, weight: 1 } + ], + threshold: 1, + selectWallet: async wallets => { + expect(wallets.length).to.equal(1) + return undefined + }, + editConfigOnMigration: config => config + }) + + expect(newSession.account.address).to.not.equal(oldSession.account.address) + }) + + it('Should select between two wallets using selectWallet', async () => { + const referenceSigner = randomWallet('Should select between two wallets using selectWallet') + orchestrator.setSigners([referenceSigner]) + + const oldSession1 = await Session.open({ + settings: simpleSettings, + orchestrator, + referenceSigner: referenceSigner.address, + addSigners: [{ address: referenceSigner.address, weight: 1 }], + threshold: 1, + selectWallet: async () => undefined, + editConfigOnMigration: config => config + }) + + const oldSession2 = await Session.open({ + settings: simpleSettings, + orchestrator, + referenceSigner: referenceSigner.address, + addSigners: [{ address: referenceSigner.address, weight: 2 }], + threshold: 2, + selectWallet: async () => undefined, + editConfigOnMigration: config => config + }) + + const newSigner = randomWallet('Should select between two wallets using selectWallet 2') + const newSession1 = await Session.open({ + settings: simpleSettings, + orchestrator, + referenceSigner: referenceSigner.address, + addSigners: [{ address: newSigner.address, weight: 1 }], + threshold: 1, + selectWallet: async wallets => { + expect(wallets.length).to.equal(2) + expect(wallets).to.include(oldSession1.account.address) + expect(wallets).to.include(oldSession2.account.address) + return oldSession1.account.address + }, + editConfigOnMigration: config => config + }) + + expect(newSession1.account.address).to.equal(oldSession1.account.address) + + const newSession2 = await Session.open({ + settings: simpleSettings, + orchestrator, + referenceSigner: referenceSigner.address, + addSigners: [{ address: newSigner.address, weight: 1 }], + threshold: 1, + selectWallet: async wallets => { + expect(wallets.length).to.equal(2) + expect(wallets).to.include(oldSession1.account.address) + expect(wallets).to.include(oldSession2.account.address) + return oldSession2.account.address + }, + editConfigOnMigration: config => config + }) + + expect(newSession2.account.address).to.equal(oldSession2.account.address) + + await newSession1.account.sendTransaction([], networks[0].chainId) + await newSession2.account.sendTransaction([], networks[0].chainId) + }) + + it('Should re-open a session after sending a transaction', async () => { + const referenceSigner = randomWallet('Should re-open a session after sending a transaction') + const signer1 = randomWallet('Should re-open a session after sending a transaction 2') + orchestrator.setSigners([referenceSigner, signer1]) + + const session = await Session.open({ + settings: simpleSettings, + orchestrator, + referenceSigner: referenceSigner.address, + addSigners: [ + { + address: referenceSigner.address, + weight: 1 + }, + { + address: signer1.address, + weight: 1 + } + ], + threshold: 2, + selectWallet: async () => undefined, + editConfigOnMigration: config => config + }) + + await session.account.sendTransaction([], networks[0].chainId) + + const signer2 = randomWallet('Should re-open a session after sending a transaction 3') + + const newSession = await Session.open({ + settings: simpleSettings, + orchestrator, + referenceSigner: referenceSigner.address, + addSigners: [{ address: signer2.address, weight: 1 }], + threshold: 2, + selectWallet: async wallets => { + expect(wallets.length).to.equal(1) + return wallets[0] + }, + editConfigOnMigration: config => config + }) + + expect(newSession.account.address).to.equal(session.account.address) + + await newSession.account.sendTransaction([], networks[0].chainId) + }) + + describe('Migrate sessions', () => { + let ogAccount: Account + let referenceSigner: ethers.Wallet + let referenceSignerIndex = 1 + let v1SessionDump: SessionDumpV1 + + beforeEach(async () => { + // Create a wallet using v1 + referenceSigner = randomWallet(`Migrate sessions ${referenceSignerIndex++}`) + orchestrator.setSigners([referenceSigner]) + + ogAccount = await Account.new({ + config: { threshold: 1, checkpoint: 0, signers: [{ address: referenceSigner.address, weight: 1 }] }, + tracker, + contexts: { 1: contexts[1] }, + orchestrator, + networks, + migrations: { + 0: { + version: 1, + configCoder: v1.config.ConfigCoder, + signatureCoder: v1.signature.SignatureCoder + } as any + } + }) + + await ogAccount.publishWitness() + + v1SessionDump = { + config: { + threshold: 1, + signers: [{ address: referenceSigner.address, weight: 1 }] + }, + metadata: { + name: 'Test' + } + } + }) + + it('Should open and migrate old session, without dump', async () => { + const newSigner = randomWallet('Should open and migrate old session, without dump') + orchestrator.setSigners([referenceSigner, newSigner]) + + const newSession = await Session.open({ + settings: simpleSettings, + orchestrator, + referenceSigner: referenceSigner.address, + addSigners: [{ address: newSigner.address, weight: 1 }], + threshold: 1, + selectWallet: async wallets => { + expect(wallets.length).to.equal(1) + return wallets[0] + }, + editConfigOnMigration: config => config + }) + + expect(newSession.account.address).to.equal(ogAccount.address) + const status = await newSession.account.status(networks[0].chainId) + expect(status.version).to.equal(2) + expect(status.fullyMigrated).to.be.true + + await newSession.account.sendTransaction([], networks[0].chainId) + }) + + it('Should open and migrate dump', async () => { + const newSession = await Session.load({ + settings: simpleSettings, + orchestrator, + dump: v1SessionDump, + editConfigOnMigration: config => config + }) + + expect(newSession.account.address).to.equal(ogAccount.address) + + const status = await newSession.account.status(networks[0].chainId) + expect(status.version).to.equal(2) + expect(status.fullyMigrated).to.be.true + + await newSession.account.sendTransaction([], networks[0].chainId) + }) + + describe('After updating old wallet', () => { + let newSignerIndex = 1 + + beforeEach(async () => { + const status = await ogAccount.status(networks[0].chainId) + const wallet = ogAccount.walletForStatus(networks[0].chainId, status) + + const newSigner = randomWallet(`After updating old wallet ${newSignerIndex++}`) + orchestrator.setSigners([referenceSigner, newSigner]) + + const uptx = await wallet.buildUpdateConfigurationTransaction({ + threshold: 2, + signers: [ + { address: referenceSigner.address, weight: 1 }, + { address: newSigner.address, weight: 1 } + ] + } as v1.config.WalletConfig) + + const suptx = await wallet.signTransactionBundle(uptx) + await wallet.relayer?.relay(suptx) + + v1SessionDump = { + ...v1SessionDump, + config: { + ...v1SessionDump.config, + address: wallet.address + } + } + }) + + it('Should open and migrate old session', async () => { + const newSigner2 = randomWallet('Should open and migrate old session') + + const newSession = await Session.open({ + settings: simpleSettings, + orchestrator, + referenceSigner: referenceSigner.address, + addSigners: [{ address: newSigner2.address, weight: 1 }], + threshold: 2, + selectWallet: async wallets => { + expect(wallets.length).to.equal(1) + return wallets[0] + }, + editConfigOnMigration: config => config + }) + + expect(newSession.account.address).to.equal(ogAccount.address) + const status = await newSession.account.status(networks[0].chainId) + expect(status.version).to.equal(2) + expect(status.fullyMigrated).to.be.true + + orchestrator.setSigners([referenceSigner, newSigner2]) + await newSession.account.sendTransaction([], networks[0].chainId) + }) + + it('Should open and migrate dump', async () => { + const newSession = await Session.load({ + settings: simpleSettings, + orchestrator, + dump: v1SessionDump, + editConfigOnMigration: config => config + }) + + expect(newSession.account.address).to.equal(ogAccount.address) + + const status = await newSession.account.status(networks[0].chainId) + expect(status.version).to.equal(2) + expect(status.fullyMigrated).to.be.true + + await newSession.account.sendTransaction([], networks[0].chainId) + }) + }) + }) + + describe('JWT Auth', () => { + let server: mockServer.Mockttp + let fakeJwt: string + let fakeJwtIndex = 1 + let proofAddress: string + + let delayMs: number = 0 + let totalCount: number = 0 + let recoverCount: { [address: string]: number } = {} + + let alwaysFail: boolean = false + + const sequenceApiUrl = 'http://127.0.0.1:8099' + let settings: SessionSettings + + beforeEach(() => { + settings = { + ...simpleSettings, + services: { + ...simpleSettings.services!, + sequenceApiUrl + } + } + + fakeJwt = ethers.utils.hexlify(randomBytes(64, `JWT Auth ${fakeJwtIndex++}`)) + + server = mockServer.getLocal() + server.start(8099) + server.forPost('/rpc/API/GetAuthToken').thenCallback(async request => { + if (delayMs !== 0) await delay(delayMs) + + const validator = ValidateSequenceWalletProof( + () => new commons.reader.OnChainReader(networks[0].provider!), + tracker, + contexts[2] + ) + + const ethauth = new ETHAuth(validator) + + ethauth.chainId = ethnode.chainId! + ethauth.configJsonRpcProvider(ethnode.providerUrl!) + + totalCount++ + + if (alwaysFail) return { statusCode: 400 } + + try { + const proof = await ethauth.decodeProof((await request.body.getJson())!['ewtString']) + proofAddress = ethers.utils.getAddress(proof.address) + + if (recoverCount[proofAddress]) { + recoverCount[proofAddress]++ + } else { + recoverCount[proofAddress] = 1 + } + + return { + statusCode: 200, + body: JSON.stringify({ + status: true, + jwtToken: fakeJwt + }) + } + } catch { + if (recoverCount['error']) { + recoverCount['error']++ + } else { + recoverCount['error'] = 1 + } + + return { + statusCode: 401 + } + } + }) + }) + + afterEach(() => { + server.stop() + delayMs = 0 + totalCount = 0 + recoverCount = {} + alwaysFail = false + }) + + it('Should get JWT token', async () => { + const referenceSigner = randomWallet('Should get JWT token') + orchestrator.setSigners([referenceSigner]) + + const session = await Session.open({ + settings, + orchestrator, + referenceSigner: referenceSigner.address, + addSigners: [{ address: referenceSigner.address, weight: 1 }], + threshold: 1, + selectWallet: async () => undefined, + editConfigOnMigration: config => config + }) + + await session.services?.auth() + expect(totalCount).to.equal(1) + expect(await session.services?.status.jwt?.token).to.equal(fakeJwt) + expect(proofAddress).to.equal(session.account.address) + }) + + it('Should get JWT after updating session', async () => { + const referenceSigner = randomWallet('Should get JWT after updating session') + orchestrator.setSigners([referenceSigner]) + + await Session.open({ + settings: simpleSettings, + orchestrator, + referenceSigner: referenceSigner.address, + addSigners: [{ address: referenceSigner.address, weight: 1 }], + threshold: 1, + selectWallet: async () => undefined, + editConfigOnMigration: config => config + }) + + const newSigner = randomWallet('Should get JWT after updating session 2') + const session = await Session.open({ + settings, + orchestrator, + referenceSigner: referenceSigner.address, + addSigners: [{ address: newSigner.address, weight: 1 }], + threshold: 1, + selectWallet: async ws => ws[0], + editConfigOnMigration: config => config + }) + + await session.services?.auth() + + expect(totalCount).to.equal(1) + expect(await session.services?.status.jwt?.token).to.equal(fakeJwt) + expect(proofAddress).to.equal(session.account.address) + }) + + it('Should get JWT during first session creation', async () => { + const referenceSigner = randomWallet('Should get JWT during first session creation') + orchestrator.setSigners([referenceSigner]) + + const session = await Session.open({ + settings, + orchestrator, + referenceSigner: referenceSigner.address, + addSigners: [{ address: referenceSigner.address, weight: 1 }], + threshold: 1, + selectWallet: async () => undefined, + editConfigOnMigration: config => config + }) + + await session.services?._initialAuthRequest + + expect(totalCount).to.equal(1) + expect(recoverCount[session.account.address]).to.equal(1) + + expect(await session.services?.status.jwt?.token).to.equal(fakeJwt) + }) + + it('Should get JWT during session opening', async () => { + delayMs = 500 + + const referenceSigner = randomWallet('Should get JWT during session opening - 1') + orchestrator.setSigners([referenceSigner]) + + let session = await Session.open({ + settings: simpleSettings, + orchestrator, + referenceSigner: referenceSigner.address, + addSigners: [{ address: referenceSigner.address, weight: 1 }], + threshold: 1, + selectWallet: async () => undefined, + editConfigOnMigration: config => config + }) + + await expect(session.services?._initialAuthRequest).to.be.rejected + + const newSigner = randomWallet('Should get JWT during session opening 2') + orchestrator.setSigners([referenceSigner, newSigner]) + + session = await Session.open({ + settings, + orchestrator, + referenceSigner: referenceSigner.address, + addSigners: [{ address: newSigner.address, weight: 1 }], + threshold: 2, + selectWallet: async ws => { + expect(ws.length).to.equal(1) + return ws[0] + }, + editConfigOnMigration: config => config + }) + + await session.services?._initialAuthRequest + + expect(totalCount).to.equal(1) + expect(recoverCount[session.account.address]).to.equal(1) + + expect(await session.services?.status.jwt?.token).to.equal(fakeJwt) + }) + + it('Should get API with lazy JWT during first session creation', async () => { + const referenceSigner = randomWallet('Should get API with lazy JWT during first session creation') + orchestrator.setSigners([referenceSigner]) + + const session = await Session.open({ + settings, + orchestrator, + referenceSigner: referenceSigner.address, + addSigners: [{ address: referenceSigner.address, weight: 1 }], + threshold: 1, + selectWallet: async () => undefined, + editConfigOnMigration: config => config + }) + + const api = await session.services?.getAPIClient() + + expect(totalCount).to.equal(1) + expect(recoverCount[session.account.address]).to.equal(1) + + expect(await session.services?.status.jwt?.token).to.equal(fakeJwt) + + server.forPost('/rpc/API/FriendList').thenCallback(async request => { + const hasToken = request.headers['authorization']!.includes(fakeJwt) + return { statusCode: hasToken ? 200 : 401, body: JSON.stringify({}) } + }) + + await api!.friendList({ page: {} }) + }) + + it('Should get API with lazy JWT during session opening', async () => { + delayMs = 500 + const referenceSigner = randomWallet('Should get API with lazy JWT during session opening') + orchestrator.setSigners([referenceSigner]) + + await Session.open({ + settings: simpleSettings, + orchestrator, + referenceSigner: referenceSigner.address, + addSigners: [{ address: referenceSigner.address, weight: 1 }], + threshold: 1, + selectWallet: async () => undefined, + editConfigOnMigration: config => config + }) + + const newSigner = randomWallet('Should get API with lazy JWT during session opening 2') + orchestrator.setSigners([referenceSigner, newSigner]) + + const session = await Session.open({ + settings, + orchestrator, + referenceSigner: referenceSigner.address, + addSigners: [{ address: newSigner.address, weight: 1 }], + threshold: 2, + selectWallet: async ws => ws[0], + editConfigOnMigration: config => config + }) + + const api = await session.services?.getAPIClient() + + expect(totalCount).to.equal(1) + expect(recoverCount[session.account.address]).to.equal(1) + + expect(await session.services?.status.jwt?.token).to.equal(fakeJwt) + + server.forPost('/rpc/API/FriendList').thenCallback(async request => { + const hasToken = request.headers['authorization']!.includes(fakeJwt) + return { statusCode: hasToken ? 200 : 401, body: JSON.stringify({}) } + }) + + await api!.friendList({ page: {} }) + }) + + it('Should call callbacks on JWT token', async () => { + const referenceSigner = randomWallet('Should call callbacks on JWT token') + orchestrator.setSigners([referenceSigner]) + + const session = await Session.open({ + settings, + orchestrator, + referenceSigner: referenceSigner.address, + addSigners: [{ address: referenceSigner.address, weight: 1 }], + threshold: 1, + selectWallet: async () => undefined, + editConfigOnMigration: config => config + }) + + let calledCallback = 0 + session.services?.onAuth(() => calledCallback++) + + await session.services?._initialAuthRequest + + expect(calledCallback).to.equal(1) + }) + + it('Should call callbacks on JWT token (on open only once)', async () => { + delayMs = 500 + + const referenceSigner = randomWallet('Should call callbacks on JWT token (on open only once)') + orchestrator.setSigners([referenceSigner]) + + await Session.open({ + settings: simpleSettings, + orchestrator, + referenceSigner: referenceSigner.address, + addSigners: [{ address: referenceSigner.address, weight: 1 }], + threshold: 1, + selectWallet: async () => undefined, + editConfigOnMigration: config => config + }) + + const newSigner = randomWallet('Should call callbacks on JWT token (on open only once) 2') + orchestrator.setSigners([referenceSigner, newSigner]) + + const session = await Session.open({ + settings, + orchestrator, + referenceSigner: referenceSigner.address, + addSigners: [ + { address: referenceSigner.address, weight: 1 }, + { address: newSigner.address, weight: 1 } + ], + threshold: 2, + selectWallet: async ws => ws[0], + editConfigOnMigration: config => config + }) + + let calledCallback = 0 + session.services?.onAuth(() => calledCallback++) + + await session.services?._initialAuthRequest + + expect(calledCallback).to.equal(1) + }) + + it('Should retry 5 times retrieving the JWT token', async () => { + delayMs = 1000 + const referenceSigner = randomWallet('Should retry 5 times retrieving the JWT token') + orchestrator.setSigners([referenceSigner]) + + const session = await Session.open({ + settings, + orchestrator, + referenceSigner: referenceSigner.address, + addSigners: [{ address: referenceSigner.address, weight: 1 }], + threshold: 1, + selectWallet: async () => undefined, + editConfigOnMigration: config => config + }) + + alwaysFail = true + await expect(session.services?.auth()).to.be.rejected + expect(totalCount).to.equal(5) + expect(session.services?.status.jwt).to.be.undefined + }) + + it('Should get API with JWT already present', async () => { + delayMs = 500 + + const referenceSigner = randomWallet('Should get API with JWT already present') + orchestrator.setSigners([referenceSigner]) + + await Session.open({ + settings: simpleSettings, + orchestrator, + referenceSigner: referenceSigner.address, + addSigners: [{ address: referenceSigner.address, weight: 1 }], + threshold: 1, + selectWallet: async () => undefined, + editConfigOnMigration: config => config + }) + + const newSigner = randomWallet('Should get API with JWT already present 2') + orchestrator.setSigners([referenceSigner, newSigner]) + + const session = await Session.open({ + settings, + orchestrator, + referenceSigner: referenceSigner.address, + addSigners: [{ address: newSigner.address, weight: 1 }], + threshold: 2, + selectWallet: async ws => ws[0], + editConfigOnMigration: config => config + }) + + await session.services?._initialAuthRequest + const totalCountBefore = totalCount + + // This should use the already existing JWT + const api = await session.services?.getAPIClient() + + expect(totalCount).to.equal(totalCountBefore) + expect(recoverCount[session.account.address]).to.equal(1) + expect(await session.services?.status.jwt?.token).to.equal(fakeJwt) + + server.forPost('/rpc/API/FriendList').thenCallback(async request => { + const hasToken = request.headers['authorization']!.includes(fakeJwt) + return { statusCode: hasToken ? 200 : 401, body: JSON.stringify({}) } + }) + + await api!.friendList({ page: {} }) + }) + + it('Should fail to get API with false tryAuth and no JWT', async () => { + const referenceSigner = randomWallet('Should fail to get API with false tryAuth and no JWT') + orchestrator.setSigners([referenceSigner]) + + alwaysFail = true + + const session = await Session.open({ + settings: simpleSettings, + orchestrator, + referenceSigner: referenceSigner.address, + addSigners: [{ address: referenceSigner.address, weight: 1 }], + threshold: 1, + selectWallet: async () => undefined, + editConfigOnMigration: config => config + }) + + await expect(session.services?._initialAuthRequest).to.be.rejected + + alwaysFail = false + + const apiPromise = session.services?.getAPIClient(false) + + await expect(apiPromise).to.be.rejected + + expect(totalCount).to.equal(0) + expect(session.services?.status.jwt).to.be.undefined + }) + + it('Should fail to get API without api url', async () => { + const referenceSigner = randomWallet('Should fail to get API without api url') + orchestrator.setSigners([referenceSigner]) + + const session = await Session.open({ + settings: simpleSettings, + orchestrator, + referenceSigner: referenceSigner.address, + addSigners: [{ address: referenceSigner.address, weight: 1 }], + threshold: 1, + selectWallet: async () => undefined, + editConfigOnMigration: config => config + }) + + const apiPromise = session.services?.getAPIClient() + + await expect(apiPromise).to.be.rejected + + expect(totalCount).to.equal(0) + expect(session.services?.status.jwt?.token).to.be.undefined + }) + + it('Should fail to get JWT with no api configured', async () => { + const referenceSigner = randomWallet('Should fail to get JWT with no api configured') + orchestrator.setSigners([referenceSigner]) + + const session = await Session.open({ + settings: simpleSettings, + orchestrator, + referenceSigner: referenceSigner.address, + addSigners: [{ address: referenceSigner.address, weight: 1 }], + threshold: 1, + selectWallet: async () => undefined, + editConfigOnMigration: config => config + }) + + await expect(session.services?.auth()).to.be.rejected + + expect(totalCount).to.equal(0) + expect(session.services?.status.jwt?.token).to.be.undefined + }) + + it('Should reuse outstanding JWT requests', async () => { + const referenceSigner = new CountingSigner(randomWallet('Should reuse outstanding JWT requests')) + orchestrator.setSigners([referenceSigner]) + + alwaysFail = true + + const session = await Session.open({ + settings, + orchestrator, + referenceSigner: await referenceSigner.getAddress(), + addSigners: [{ address: await referenceSigner.getAddress(), weight: 1 }], + threshold: 1, + selectWallet: async () => undefined, + editConfigOnMigration: config => config + }) + + // 1 signing request is made to publish signers + expect(referenceSigner.signingRequests).to.equal(1) + + const signingRequestsBefore = referenceSigner.signingRequests + + await expect(session.services?._initialAuthRequest).to.be.rejected + + alwaysFail = false + totalCount = 0 + + // Create a bunch of API clients concurrently + const requests: any[] = [] + while (requests.length < 10) { + requests.push(session.services?.getAPIClient()) + } + await expect(Promise.all(requests)).to.be.fulfilled + + expect(totalCount).to.equal(1) + expect(referenceSigner.signingRequests).to.equal(signingRequestsBefore + 1) + }) + + it('Should reuse existing proof signatures', async () => { + const referenceSigner = new CountingSigner(randomWallet('Should reuse existing proof signatures')) + orchestrator.setSigners([referenceSigner]) + + alwaysFail = true + + const session = await Session.open({ + settings, + orchestrator, + referenceSigner: await referenceSigner.getAddress(), + addSigners: [{ address: await referenceSigner.getAddress(), weight: 1 }], + threshold: 1, + selectWallet: async () => undefined, + editConfigOnMigration: config => config + }) + + // 1 signing request is made to publish signers + expect(referenceSigner.signingRequests).to.equal(1) + + const signingRequestsBefore = referenceSigner.signingRequests + + await expect(session.services?._initialAuthRequest).to.be.rejected + + totalCount = 0 + + // Create a bunch of API clients sequentially + for (let i = 0; i < 10; i++) { + await expect(session.services?.getAPIClient()).to.be.rejected + } + + expect(totalCount).to.equal(10) + expect(referenceSigner.signingRequests).to.equal(signingRequestsBefore + 1) + }) + + it('Should neither re-authenticate nor retry if request succeeds', async () => { + const referenceSigner = new CountingSigner(randomWallet('Should neither re-authenticate nor retry if request succeeds')) + orchestrator.setSigners([referenceSigner]) + + const session = await Session.open({ + settings, + orchestrator, + referenceSigner: await referenceSigner.getAddress(), + addSigners: [{ address: await referenceSigner.getAddress(), weight: 1 }], + threshold: 1, + selectWallet: async () => undefined, + editConfigOnMigration: config => config + }) + + await session.services?._initialAuthRequest + + const api = await session.services?.getAPIClient() + + const okResponses = [true] + server.forPost('/rpc/API/FriendList').thenCallback(async () => { + return { statusCode: okResponses.shift() ? 200 : 401, body: JSON.stringify({}) } + }) + + totalCount = 0 + + await expect(api!.friendList({ page: {} })).to.be.fulfilled + + // no re-authentication since it succeeded + expect(totalCount).to.equal(0) + }) + + describe('With expiration', () => { + let resetDateMock: Function | undefined + + const setDate = (seconds: number) => { + if (resetDateMock) resetDateMock() + const newMockDate = new Date() + newMockDate.setTime(seconds * 1000) + resetDateMock = mockDate(newMockDate) + } + + afterEach(() => { + if (resetDateMock) resetDateMock() + }) + + it('Should request a new JWT after expiration', async () => { + const baseTime = 1613579057 + setDate(baseTime) + + const referenceSigner = randomWallet('Should request a new JWT after expiration') + orchestrator.setSigners([referenceSigner]) + + const session = await Session.open({ + settings: { + ...settings, + services: { + ...settings.services!, + metadata: { + name: 'Test', + expiration: 240 + } + } + }, + orchestrator, + referenceSigner: referenceSigner.address, + addSigners: [{ address: referenceSigner.address, weight: 1 }], + threshold: 1, + selectWallet: async () => undefined, + editConfigOnMigration: config => config + }) + + await session.services?._initialAuthRequest + + expect(totalCount).to.equal(1) + expect(await session.services?.status.jwt?.token).to.equal(fakeJwt) + expect(session.services?.status.jwt?.expiration).to.equal(baseTime + 240 - 60) + + // Force expire (1 hour) + const newBaseTime = baseTime + 60 * 60 + setDate(newBaseTime) + + fakeJwt = ethers.utils.hexlify(randomBytes(96, 'Should request a new JWT after expiration 2')) + + await session.services?.getAPIClient() + + expect(totalCount).to.equal(2) + expect(await session.services?.status.jwt?.token).to.equal(fakeJwt) + expect(session.services?.status.jwt?.expiration).to.equal(newBaseTime + 240 - 60) + }) + + it('Should force min expiration time', async () => { + const baseTime = 1613579057 + setDate(baseTime) + + const referenceSigner = randomWallet('Should force min expiration time') + orchestrator.setSigners([referenceSigner]) + + const session = await Session.open({ + settings: { + ...settings, + services: { + ...settings.services!, + metadata: { + name: 'Test', + expiration: 1 + } + } + }, + orchestrator, + referenceSigner: referenceSigner.address, + addSigners: [{ address: referenceSigner.address, weight: 1 }], + threshold: 1, + selectWallet: async () => undefined, + editConfigOnMigration: config => config + }) + + await session.services?._initialAuthRequest + + expect(totalCount).to.equal(1) + expect(await session.services?.status.jwt?.token).to.equal(fakeJwt) + expect(session.services?.status.jwt?.expiration).to.equal(baseTime + 120 - 60) + }) + }) + }) + + describe('ETHAuth proof validation', () => { + it('Should validate an ETHAuth signature by an undeployed wallet', async () => { + const signer = randomWallet('Should validate an ETHAuth signature by an undeployed wallet') + const config = { + threshold: 1, + checkpoint: Math.floor(now() / 1000), + signers: [{ address: signer.address, weight: 1 }] + } + const account = await Account.new({ + config, + tracker, + contexts, + orchestrator: new Orchestrator([signer]), + networks + }) + + // begin by setting the parameters of the ETHAuth proof + const proof = new Proof({ address: account.address }) + proof.claims.app = 'Should validate an ETHAuth signature by an undeployed wallet' + proof.claims.iat = Math.floor(now() / 1000) // seconds since epoch, or better yet, proof.setIssuedAtNow() + proof.claims.exp = proof.claims.iat + 3600 // seconds since epoch, or better yet, proof.setExpiryIn(3600) + + // create an EIP-6492-compatible ETHAuth proof signature of the proof's message digest + proof.signature = await account.signDigest(proof.messageDigest(), ethnode.chainId!, true, 'eip6492') + // an EIP-6492 signature for an undeployed wallet always ends with the EIP-6492 suffix + expect(proof.signature.endsWith(commons.EIP6492.EIP_6492_SUFFIX.slice(2))).to.be.true + + // create an EIP-6492-aware ETHAuth proof validator + const validator = ValidateSequenceWalletProof( + () => new commons.reader.OnChainReader(ethnode.provider!), + tracker, + contexts[2] + ) + const ethauth = new ETHAuth(validator) + await ethauth.configJsonRpcProvider(ethnode.providerUrl!) + + // proofs can be encoded to and decoded from strings like so + const proofString = await ethauth.encodeProof(proof) + const decodedProof = await ethauth.decodeProof(proofString) + + // decoded proofs can be validated like so + expect(ethauth.validateProof(decodedProof)).to.eventually.be.true + }) + }) + describe('session without services', () => { + let noServiceSettings: SessionSettings + + before(() => { + noServiceSettings = { + ...simpleSettings, + services: undefined + } + }) + + it('should open a session without services', async () => { + const referenceSigner = randomWallet('should open a session without services') + orchestrator.setSigners([referenceSigner]) + + const session = await Session.open({ + settings: noServiceSettings, + orchestrator, + referenceSigner: referenceSigner.address, + addSigners: [{ address: referenceSigner.address, weight: 1 }], + threshold: 1, + selectWallet: async () => { + return undefined + }, + editConfigOnMigration: config => config + }) + + expect(session.services).to.be.undefined + }) + + it('should dump a session without services', async () => { + const referenceSigner = randomWallet('should dump a session without services') + orchestrator.setSigners([referenceSigner]) + + const session = await Session.open({ + settings: noServiceSettings, + orchestrator, + referenceSigner: referenceSigner.address, + addSigners: [{ address: referenceSigner.address, weight: 1 }], + threshold: 1, + selectWallet: async () => { + return undefined + }, + editConfigOnMigration: config => config + }) + + const dump = await session.dump() + expect(dump).to.not.be.undefined + expect(dump.jwt).to.be.undefined + expect(dump.metadata).to.be.undefined + }) + + it('should load dump without services', async () => { + const referenceSigner = randomWallet('should load dump without services') + orchestrator.setSigners([referenceSigner]) + + const session = await Session.open({ + settings: noServiceSettings, + orchestrator, + referenceSigner: referenceSigner.address, + addSigners: [{ address: referenceSigner.address, weight: 1 }], + threshold: 1, + selectWallet: async () => { + return undefined + }, + editConfigOnMigration: config => config + }) + + const dump = await session.dump() + const newSession = await Session.load({ + orchestrator, + settings: noServiceSettings, + dump: dump, + editConfigOnMigration: config => config + }) + + expect(newSession.services).to.be.undefined + }) + }) + + describe('single signer session', () => { + it('should create a new single signer session', async () => { + const signer = randomWallet('should create a new single signer session') + + const session = await Session.singleSigner({ + settings: simpleSettings, + signer: signer + }) + + expect(session.account.address).to.not.be.undefined + + const status = await session.account.status(networks[0].chainId) + const config = status.config as v2.config.WalletConfig + + expect(config.threshold).to.equal(1) + expect(v2.config.isSignerLeaf(config.tree)).to.be.true + expect(config.tree as v2.config.SignerLeaf).to.deep.equal({ + weight: 1, + address: signer.address + }) + }) + + it('should open same single signer session twice', async () => { + const signer = randomWallet('should open same single signer session twice') + + const session1 = await Session.singleSigner({ + settings: simpleSettings, + signer: signer + }) + + const address1 = session1.account.address + const status1 = await session1.account.status(networks[0].chainId) + + const session2 = await Session.singleSigner({ + settings: simpleSettings, + signer: signer + }) + + const address2 = session2.account.address + const status2 = await session2.account.status(networks[0].chainId) + + expect(address1).to.equal(address2) + + // should not change the config! + expect(status1.config).to.deep.equal(status2.config) + }) + + it('should send a transaction from a single signer session', async () => { + const signer = randomWallet('should send a transaction from a single signer session') + + const session = await Session.singleSigner({ + settings: simpleSettings, + signer: signer + }) + + const receipt = await session.account.sendTransaction( + { + to: ethers.Wallet.createRandom().address + }, + networks[0].chainId + ) + + expect(receipt.hash).to.not.be.undefined + }) + }) +}) + +let nowCalls = 0 +function now(): number { + if (deterministic) { + return Date.parse('2023-02-14T00:00:00.000Z') + 1000 * nowCalls++ + } else { + return Date.now() + } +} + +function randomWallet(entropy: number | string): ethers.Wallet { + return new ethers.Wallet(randomBytes(32, entropy)) +} + +function randomBytes(length: number, entropy: number | string): Uint8Array { + if (deterministic) { + let bytes = '' + while (bytes.length < 2 * length) { + bytes += ethers.utils.id(`${bytes}${entropy}`).slice(2) + } + return ethers.utils.arrayify(`0x${bytes.slice(0, 2 * length)}`) + } else { + return ethers.utils.randomBytes(length) + } +} diff --git a/packages/auth/tests/utils/index.ts b/packages/auth/tests/utils/index.ts new file mode 100644 index 0000000000..8c4c6f9990 --- /dev/null +++ b/packages/auth/tests/utils/index.ts @@ -0,0 +1,33 @@ +export function delay(time: number): Promise { + return new Promise(solve => setTimeout(solve, time)) +} + +/** + * @param {Date} expected The date to which we want to freeze time + * @returns {Function} Call to remove Date mocking + */ +export const mockDate = (expected: Date): (() => void) => { + const _Date = Date + + // If any Date or number is passed to the constructor + // use that instead of our mocked date + function MockDate(mockOverride?: Date | number) { + return new _Date(mockOverride || expected) + } + + MockDate.UTC = _Date.UTC + MockDate.parse = _Date.parse + MockDate.now = () => expected.getTime() + // Give our mock Date has the same prototype as Date + // Some libraries rely on this to identify Date objects + MockDate.prototype = _Date.prototype + + // Our mock is not a full implementation of Date + // Types will not match but it's good enough for our tests + global.Date = MockDate as any + + // Callback function to remove the Date mock + return () => { + global.Date = _Date + } +} diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md new file mode 100644 index 0000000000..6d7d0e8357 --- /dev/null +++ b/packages/core/CHANGELOG.md @@ -0,0 +1,1017 @@ +# @0xsequence/core + +## 2.0.0 + +### Major Changes + +- changeset + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@2.0.0 + +## 1.10.14 + +### Patch Changes + +- network: add borne-testnet to allNetworks +- Updated dependencies + - @0xsequence/abi@1.10.14 + +## 1.10.13 + +### Patch Changes + +- network: add borne testnet +- Updated dependencies + - @0xsequence/abi@1.10.13 + +## 1.10.12 + +### Patch Changes + +- api: update bindings +- global/window -> globalThis +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.10.12 + +## 1.10.11 + +### Patch Changes + +- waas: updated intent.gen without webrpc types, errors exported from authenticator.gen +- Updated dependencies + - @0xsequence/abi@1.10.11 + +## 1.10.10 + +### Patch Changes + +- metadata: update bindings with new contract collections api +- Updated dependencies + - @0xsequence/abi@1.10.10 + +## 1.10.9 + +### Patch Changes + +- waas minor update +- Updated dependencies + - @0xsequence/abi@1.10.9 + +## 1.10.8 + +### Patch Changes + +- update metadata bindings +- Updated dependencies + - @0xsequence/abi@1.10.8 + +## 1.10.7 + +### Patch Changes + +- minor fixes to waas client +- Updated dependencies + - @0xsequence/abi@1.10.7 + +## 1.10.6 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/abi@1.10.6 + +## 1.10.5 + +### Patch Changes + +- network: ape-chain-testnet -> apechain-testnet +- Updated dependencies + - @0xsequence/abi@1.10.5 + +## 1.10.4 + +### Patch Changes + +- network: add b3-sepolia, ape-chain-testnet, blast, blast-sepolia +- Updated dependencies + - @0xsequence/abi@1.10.4 + +## 1.10.3 + +### Patch Changes + +- typing fix +- Updated dependencies + - @0xsequence/abi@1.10.3 + +## 1.10.2 + +### Patch Changes + +- - waas: add getIdToken method + - indexer: update api client +- Updated dependencies + - @0xsequence/abi@1.10.2 + +## 1.10.1 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/abi@1.10.1 + +## 1.10.0 + +### Minor Changes + +- waas release v1.3.0 + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.10.0 + +## 1.9.37 + +### Patch Changes + +- network: adds nativeToken data to NetworkMetadata constants +- Updated dependencies + - @0xsequence/abi@1.9.37 + +## 1.9.36 + +### Patch Changes + +- guard: export client +- Updated dependencies + - @0xsequence/abi@1.9.36 + +## 1.9.35 + +### Patch Changes + +- guard: update bindings +- Updated dependencies + - @0xsequence/abi@1.9.35 + +## 1.9.34 + +### Patch Changes + +- waas: always use lowercase email +- Updated dependencies + - @0xsequence/abi@1.9.34 + +## 1.9.33 + +### Patch Changes + +- waas: umd build +- Updated dependencies + - @0xsequence/abi@1.9.33 + +## 1.9.32 + +### Patch Changes + +- indexer: update bindings +- Updated dependencies + - @0xsequence/abi@1.9.32 + +## 1.9.31 + +### Patch Changes + +- metadata: token directory changes +- Updated dependencies + - @0xsequence/abi@1.9.31 + +## 1.9.30 + +### Patch Changes + +- update +- Updated dependencies + - @0xsequence/abi@1.9.30 + +## 1.9.29 + +### Patch Changes + +- disable gnosis chain +- Updated dependencies + - @0xsequence/abi@1.9.29 + +## 1.9.28 + +### Patch Changes + +- add utils/merkletree +- Updated dependencies + - @0xsequence/abi@1.9.28 + +## 1.9.27 + +### Patch Changes + +- network: optimistic -> optimism +- waas: remove defaults +- api, sessions: update bindings +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.9.27 + +## 1.9.26 + +### Patch Changes + +- - add backend interfaces for pluggable interfaces + - introduce @0xsequence/react-native + - update pnpm to lockfile v9 +- Updated dependencies + - @0xsequence/abi@1.9.26 + +## 1.9.25 + +### Patch Changes + +- update webrpc clients with new error types +- Updated dependencies + - @0xsequence/abi@1.9.25 + +## 1.9.24 + +### Patch Changes + +- waas: add memoryStore backend to localStore +- Updated dependencies + - @0xsequence/abi@1.9.24 + +## 1.9.23 + +### Patch Changes + +- update api client bindings +- Updated dependencies + - @0xsequence/abi@1.9.23 + +## 1.9.22 + +### Patch Changes + +- update metadata client bindings +- Updated dependencies + - @0xsequence/abi@1.9.22 + +## 1.9.21 + +### Patch Changes + +- api client bindings +- Updated dependencies + - @0xsequence/abi@1.9.21 + +## 1.9.20 + +### Patch Changes + +- api client bindings update +- Updated dependencies + - @0xsequence/abi@1.9.20 + +## 1.9.19 + +### Patch Changes + +- waas update +- Updated dependencies + - @0xsequence/abi@1.9.19 + +## 1.9.18 + +### Patch Changes + +- provider: prohibit dangerous functions +- Updated dependencies + - @0xsequence/abi@1.9.18 + +## 1.9.17 + +### Patch Changes + +- network: add xr-sepolia +- Updated dependencies + - @0xsequence/abi@1.9.17 + +## 1.9.16 + +### Patch Changes + +- waas: sequence.feeOptions +- Updated dependencies + - @0xsequence/abi@1.9.16 + +## 1.9.15 + +### Patch Changes + +- metadata: collection external_link field name fix +- Updated dependencies + - @0xsequence/abi@1.9.15 + +## 1.9.14 + +### Patch Changes + +- network: astar-zkatana -> astar-zkyoto +- network: deprecate polygon mumbai network +- network: add xai and polygon amoy +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.9.14 + +## 1.9.13 + +### Patch Changes + +- waas: fix @0xsequence/network dependency +- Updated dependencies + - @0xsequence/abi@1.9.13 + +## 1.9.12 + +### Patch Changes + +- indexer: update rpc bindings +- provider: signMessage: Serialize the BytesLike or string message into hexstring before sending +- waas: SessionAuthProof +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.9.12 + +## 1.9.11 + +### Patch Changes + +- metdata, update rpc bindings +- Updated dependencies + - @0xsequence/abi@1.9.11 + +## 1.9.10 + +### Patch Changes + +- update metadata rpc bindings +- Updated dependencies + - @0xsequence/abi@1.9.10 + +## 1.9.9 + +### Patch Changes + +- metadata, add SequenceCollections rpc client +- Updated dependencies + - @0xsequence/abi@1.9.9 + +## 1.9.8 + +### Patch Changes + +- waas client update +- Updated dependencies + - @0xsequence/abi@1.9.8 + +## 1.9.7 + +### Patch Changes + +- update rpc client bindings for api, metadata and relayer +- Updated dependencies + - @0xsequence/abi@1.9.7 + +## 1.9.6 + +### Patch Changes + +- waas package update +- Updated dependencies + - @0xsequence/abi@1.9.6 + +## 1.9.5 + +### Patch Changes + +- RpcRelayer prioritize project access key +- Updated dependencies + - @0xsequence/abi@1.9.5 + +## 1.9.4 + +### Patch Changes + +- waas: fix network dependency +- Updated dependencies + - @0xsequence/abi@1.9.4 + +## 1.9.3 + +### Patch Changes + +- provider: don't append access key to RPC url if user has already provided it +- Updated dependencies + - @0xsequence/abi@1.9.3 + +## 1.9.2 + +### Patch Changes + +- network: add xai-sepolia +- Updated dependencies + - @0xsequence/abi@1.9.2 + +## 1.9.1 + +### Patch Changes + +- analytics fix +- Updated dependencies + - @0xsequence/abi@1.9.1 + +## 1.9.0 + +### Minor Changes + +- waas release + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.9.0 + +## 1.8.8 + +### Patch Changes + +- update metadata bindings +- Updated dependencies + - @0xsequence/abi@1.8.8 + +## 1.8.7 + +### Patch Changes + +- provider: update databeat to 0.9.1 +- Updated dependencies + - @0xsequence/abi@1.8.7 + +## 1.8.6 + +### Patch Changes + +- guard: SignedOwnershipProof +- Updated dependencies + - @0xsequence/abi@1.8.6 + +## 1.8.5 + +### Patch Changes + +- guard: signOwnershipProof and isSignedOwnershipProof +- Updated dependencies + - @0xsequence/abi@1.8.5 + +## 1.8.4 + +### Patch Changes + +- network: add homeverse to networks list +- Updated dependencies + - @0xsequence/abi@1.8.4 + +## 1.8.3 + +### Patch Changes + +- api: introduce basic linked wallet support +- Updated dependencies + - @0xsequence/abi@1.8.3 + +## 1.8.2 + +### Patch Changes + +- provider: don't initialize analytics unless explicitly requested +- Updated dependencies + - @0xsequence/abi@1.8.2 + +## 1.8.1 + +### Patch Changes + +- update to analytics provider +- Updated dependencies + - @0xsequence/abi@1.8.1 + +## 1.8.0 + +### Minor Changes + +- provider: project analytics + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.8.0 + +## 1.7.2 + +### Patch Changes + +- 0xsequence: ChainId should not be exported as a type +- account, wallet: fix nonce selection +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.7.2 + +## 1.7.1 + +### Patch Changes + +- network: add missing avalanche logoURI +- Updated dependencies + - @0xsequence/abi@1.7.1 + +## 1.7.0 + +### Minor Changes + +- provider: projectAccessKey is now required + +### Patch Changes + +- network: add NetworkMetadata.logoURI property for all networks +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.7.0 + +## 1.6.3 + +### Patch Changes + +- network list update +- Updated dependencies + - @0xsequence/abi@1.6.3 + +## 1.6.2 + +### Patch Changes + +- auth: projectAccessKey option +- wallet: use 12 bytes for random space +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.6.2 + +## 1.6.1 + +### Patch Changes + +- core: add simple config from subdigest support +- core: fix encode tree with subdigest +- account: implement buildOnChainSignature on Account +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.6.1 + +## 1.6.0 + +### Minor Changes + +- account, wallet: parallel transactions by default + +### Patch Changes + +- provider: emit disconnect on sign out +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.6.0 + +## 1.5.0 + +### Minor Changes + +- signhub: add 'signing' signer status + +### Patch Changes + +- auth: Session.open: onAccountAddress callback +- account: allow empty transaction bundles +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.5.0 + +## 1.4.9 + +### Patch Changes + +- rename SequenceMetadataClient to SequenceMetadata +- Updated dependencies + - @0xsequence/abi@1.4.9 + +## 1.4.8 + +### Patch Changes + +- account: Account.getSigners +- Updated dependencies + - @0xsequence/abi@1.4.8 + +## 1.4.7 + +### Patch Changes + +- update indexer client bindings +- Updated dependencies + - @0xsequence/abi@1.4.7 + +## 1.4.6 + +### Patch Changes + +- - add sepolia networks, mark goerli as deprecated + - update indexer client bindings +- Updated dependencies + - @0xsequence/abi@1.4.6 + +## 1.4.5 + +### Patch Changes + +- indexer/metadata: update client bindings +- auth: selectWallet with new address +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.4.5 + +## 1.4.4 + +### Patch Changes + +- indexer: update bindings +- auth: handle jwt expiry +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.4.4 + +## 1.4.3 + +### Patch Changes + +- guard: return active status from GuardSigner.getAuthMethods +- Updated dependencies + - @0xsequence/abi@1.4.3 + +## 1.4.2 + +### Patch Changes + +- guard: update bindings +- Updated dependencies + - @0xsequence/abi@1.4.2 + +## 1.4.1 + +### Patch Changes + +- network: remove unused networks +- signhub: orchestrator interface +- guard: auth methods interface +- guard: update bindings for pin and totp +- guard: no more retry logic +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.4.1 + +## 1.4.0 + +### Minor Changes + +- project access key support + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.4.0 + +## 1.3.0 + +### Minor Changes + +- signhub: account children + +### Patch Changes + +- guard: do not throw when building deploy transaction +- network: snowtrace.io -> subnets.avax.network/c-chain +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.3.0 + +## 1.2.9 + +### Patch Changes + +- account: AccountSigner.sendTransaction simulateForFeeOptions +- relayer: update bindings +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.2.9 + +## 1.2.8 + +### Patch Changes + +- rename X-Sequence-Token-Key header to X-Access-Key +- Updated dependencies + - @0xsequence/abi@1.2.8 + +## 1.2.7 + +### Patch Changes + +- add x-sequence-token-key to clients +- Updated dependencies + - @0xsequence/abi@1.2.7 + +## 1.2.6 + +### Patch Changes + +- Fix bind multicall provider +- Updated dependencies + - @0xsequence/abi@1.2.6 + +## 1.2.5 + +### Patch Changes + +- Multicall default configuration fixes +- Updated dependencies + - @0xsequence/abi@1.2.5 + +## 1.2.4 + +### Patch Changes + +- provider: Adding missing payment provider types to PaymentProviderOption +- provider: WalletRequestHandler.notifyChainChanged +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.2.4 + +## 1.2.3 + +### Patch Changes + +- auth, provider: connect to accept optional authorizeNonce +- Updated dependencies + - @0xsequence/abi@1.2.3 + +## 1.2.2 + +### Patch Changes + +- provider: allow createContract calls +- core: check for explicit zero address in contract deployments +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.2.2 + +## 1.2.1 + +### Patch Changes + +- auth: use sequence api chain id as reference chain id if available +- Updated dependencies + - @0xsequence/abi@1.2.1 + +## 1.2.0 + +### Minor Changes + +- split services from session, better local support + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.2.0 + +## 1.1.15 + +### Patch Changes + +- guard: remove error filtering +- Updated dependencies + - @0xsequence/abi@1.1.15 + +## 1.1.14 + +### Patch Changes + +- guard: add GuardSigner.onError +- Updated dependencies + - @0xsequence/abi@1.1.14 + +## 1.1.13 + +### Patch Changes + +- provider: pass client version with connect options +- provider: removing large from BannerSize +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.1.13 + +## 1.1.12 + +### Patch Changes + +- provider: adding bannerSize to ConnectOptions +- Updated dependencies + - @0xsequence/abi@1.1.12 + +## 1.1.11 + +### Patch Changes + +- add homeverse configs +- Updated dependencies + - @0xsequence/abi@1.1.11 + +## 1.1.10 + +### Patch Changes + +- handle default EIP6492 on send +- Updated dependencies + - @0xsequence/abi@1.1.10 + +## 1.1.9 + +### Patch Changes + +- Custom default EIP6492 on client +- Updated dependencies + - @0xsequence/abi@1.1.9 + +## 1.1.8 + +### Patch Changes + +- metadata: searchMetadata: add types filter +- Updated dependencies + - @0xsequence/abi@1.1.8 + +## 1.1.7 + +### Patch Changes + +- adding signInWith connect settings option to allow dapps to automatically login their users with a certain provider optimizing the normal authentication flow +- Updated dependencies + - @0xsequence/abi@1.1.7 + +## 1.1.6 + +### Patch Changes + +- metadata: searchMetadata: add chainID and excludeTokenMetadata filters +- Updated dependencies + - @0xsequence/abi@1.1.6 + +## 1.1.5 + +### Patch Changes + +- account: re-compute meta-transaction id for wallet deployment transactions +- Updated dependencies + - @0xsequence/abi@1.1.5 + +## 1.1.4 + +### Patch Changes + +- network: rename base-mainnet to base +- provider: override isDefaultChain with ConnectOptions.networkId if provided +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.1.4 + +## 1.1.3 + +### Patch Changes + +- provider: use network id from transport session +- provider: sign authorization using ConnectOptions.networkId if provided +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.1.3 + +## 1.1.2 + +### Patch Changes + +- provider: jsonrpc chain id fixes +- Updated dependencies + - @0xsequence/abi@1.1.2 + +## 1.1.1 + +### Patch Changes + +- network: add base mainnet and sepolia +- provider: reject toxic transaction requests +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.1.1 + +## 1.1.0 + +### Minor Changes + +- Refactor dapp facing provider + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.1.0 + +## 1.0.5 + +### Patch Changes + +- network: export network constants +- guard: use the correct global for fetch +- network: nova-explorer.arbitrum.io -> nova.arbiscan.io +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.0.5 + +## 1.0.4 + +### Patch Changes + +- provider: accept name or number for networkId +- Updated dependencies + - @0xsequence/abi@1.0.4 + +## 1.0.3 + +### Patch Changes + +- Simpler isValidSignature helpers +- Updated dependencies + - @0xsequence/abi@1.0.3 + +## 1.0.2 + +### Patch Changes + +- add extra signature validation utils methods +- Updated dependencies + - @0xsequence/abi@1.0.2 + +## 1.0.1 + +### Patch Changes + +- add homeverse testnet +- Updated dependencies + - @0xsequence/abi@1.0.1 + +## 1.0.0 + +### Major Changes + +- https://sequence.xyz/blog/sequence-wallet-light-state-sync-full-merkle-wallets + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.0.0 diff --git a/packages/core/package.json b/packages/core/package.json new file mode 100644 index 0000000000..9f79c70b6d --- /dev/null +++ b/packages/core/package.json @@ -0,0 +1,30 @@ +{ + "name": "@0xsequence/core", + "version": "2.0.0", + "description": "core primitives for interacting with the sequence wallet contracts", + "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/core", + "source": "src/index.ts", + "main": "dist/0xsequence-core.cjs.js", + "module": "dist/0xsequence-core.esm.js", + "author": "Horizon Blockchain Games", + "license": "Apache-2.0", + "scripts": { + "test": "pnpm test:file tests/**/*.spec.ts", + "test:file": "TS_NODE_PROJECT=../../tsconfig.test.json mocha -r ts-node/register --timeout 30000", + "test:coverage": "nyc yarn test" + }, + "peerDependencies": { + "ethers": ">=5.5" + }, + "devDependencies": { + "@istanbuljs/nyc-config-typescript": "^1.0.2", + "nyc": "^15.1.0" + }, + "files": [ + "src", + "dist" + ], + "dependencies": { + "@0xsequence/abi": "workspace:*" + } +} diff --git a/packages/core/src/commons/config.ts b/packages/core/src/commons/config.ts new file mode 100644 index 0000000000..2529b8f827 --- /dev/null +++ b/packages/core/src/commons/config.ts @@ -0,0 +1,67 @@ +import { ethers } from 'ethers' +import { WalletContext } from './context' +import * as transaction from './transaction' + +export type Config = { + version: number +} + +export type SimpleSigner = { address: string; weight: ethers.BigNumberish } + +export type SimpleConfig = { + threshold: ethers.BigNumberish + checkpoint: ethers.BigNumberish + signers: SimpleSigner[] + subdigests?: string[] +} + +export interface ConfigCoder { + imageHashOf: (config: T) => string + hasSubdigest: (config: T, subdigest: string) => boolean + + isWalletConfig: (config: Config) => config is T + + checkpointOf: (config: T) => ethers.BigNumber + + fromSimple: (config: SimpleConfig) => T + + signersOf: (config: T) => { address: string; weight: number }[] + + toJSON: (config: T) => string + fromJSON: (json: string) => T + + isComplete: (config: T) => boolean + + editConfig: ( + config: T, + action: { + add?: SimpleSigner[] + remove?: string[] + threshold?: ethers.BigNumberish + checkpoint?: ethers.BigNumberish + } + ) => T + + buildStubSignature: (config: T, overrides: Map) => string + + // isValid: (config: T) => boolean + + // TODO: This may not be the best place for this + // maybe it could go in the migration classes? + update: { + isKindUsed: boolean + + buildTransaction: ( + address: string, + config: T, + context: WalletContext, + kind?: 'first' | 'later' | undefined + ) => transaction.TransactionBundle + + decodeTransaction: (tx: transaction.TransactionBundle) => { + address: string + newImageHash: string + kind: 'first' | 'later' | undefined + } + } +} diff --git a/packages/core/src/commons/context.ts b/packages/core/src/commons/context.ts new file mode 100644 index 0000000000..9868e42a3d --- /dev/null +++ b/packages/core/src/commons/context.ts @@ -0,0 +1,112 @@ +import { ethers } from 'ethers' +import { allVersions } from '..' + +import { DeployedWalletContext as context1 } from '../v1' +import { DeployedWalletContext as context2 } from '../v2' + +export type WalletContext = { + version: number + factory: string + mainModule: string + mainModuleUpgradable: string + guestModule: string + + walletCreationCode: string +} + +export function addressOf(context: WalletContext, imageHash: ethers.BytesLike) { + const codeHash = ethers.utils.keccak256( + ethers.utils.solidityPack(['bytes', 'bytes32'], [context.walletCreationCode, ethers.utils.hexZeroPad(context.mainModule, 32)]) + ) + + const hash = ethers.utils.keccak256( + ethers.utils.solidityPack(['bytes1', 'address', 'bytes32', 'bytes32'], ['0xff', context.factory, imageHash, codeHash]) + ) + + return ethers.utils.getAddress(ethers.utils.hexDataSlice(hash, 12)) +} + +export async function isValidCounterfactual( + wallet: string, + digest: ethers.BytesLike, + signature: ethers.BytesLike, + chainId: ethers.BigNumberish, + provider: ethers.providers.Provider, + contexts: { [key: number]: WalletContext } +) { + // We don't know the version of the signature + // so we need to try all of them + const res = await Promise.all( + allVersions.map(async version => { + try { + const decoded = version.signature.SignatureCoder.decode(ethers.utils.hexlify(signature)) + + const recovered1 = await version.signature.SignatureCoder.recover( + decoded as any, + { + address: wallet, + digest: ethers.utils.hexlify(digest), + chainId + }, + provider + ) + + const imageHash = version.config.ConfigCoder.imageHashOf(recovered1.config as any) + const counterfactualAddress = addressOf(contexts[version.version], imageHash) + + if (counterfactualAddress.toLowerCase() === wallet.toLowerCase()) { + return true + } + + // chainId=0 means no chainId, so the signature is valid for all chains + // we need to check that case too + const recovered2 = await version.signature.SignatureCoder.recover( + decoded as any, + { + address: wallet, + digest: ethers.utils.hexlify(digest), + chainId + }, + provider + ) + + const imageHash2 = version.config.ConfigCoder.imageHashOf(recovered2.config as any) + const counterfactualAddress2 = addressOf(contexts[version.version], imageHash2) + + return counterfactualAddress2.toLowerCase() === wallet.toLowerCase() + } catch {} + + // We most likely failed to decode the signature + return false + }) + ) + + return res.some(r => r) +} + +export type VersionedContext = { [key: number]: WalletContext } + +export function isValidVersionedContext(contexts: VersionedContext): boolean { + // number of keys is the number of versions + const versions = Object.keys(contexts).length + + // check that all versions exist and are valid + for (let i = 1; i <= versions; i++) { + const context = contexts[i] + if (!context || context.version !== i) { + return false + } + } + + return true +} + +export function latestContext(contexts: VersionedContext): WalletContext { + const versions = Object.keys(contexts).length + return contexts[versions] +} + +export const defaultContexts: VersionedContext = { + 1: context1, + 2: context2 +} diff --git a/packages/core/src/commons/index.ts b/packages/core/src/commons/index.ts new file mode 100644 index 0000000000..7bc6db71be --- /dev/null +++ b/packages/core/src/commons/index.ts @@ -0,0 +1,10 @@ +export * as config from './config' +export * as signature from './signature' +export * as context from './context' +export * as signer from './signer' +export * as EIP1271 from './validateEIP1271' +export * as transaction from './transaction' +export * as reader from './reader' +export * as EIP6492 from './validateEIP6492' + +export * from './orchestrator' diff --git a/packages/core/src/commons/orchestrator.ts b/packages/core/src/commons/orchestrator.ts new file mode 100644 index 0000000000..cb0d731659 --- /dev/null +++ b/packages/core/src/commons/orchestrator.ts @@ -0,0 +1,42 @@ +import { ethers } from 'ethers' +import { commons } from '..' +import { Config } from './config' + +/** + * Request metadata, used by the wallet to pass additional information through the orchestrator. + */ +export type WalletSignRequestMetadata = { + address: string + digest: ethers.utils.BytesLike + chainId: ethers.BigNumberish + + config: Config + + parts?: Map + + // TODO: We can add a "percentage" field to the orchestrator to indicate + // how close are we to the threshold. This can be used to display + // a progress bar or something similar. + + message?: ethers.utils.BytesLike + transactions?: commons.transaction.Transaction[] + + // This is used only when a Sequence wallet is nested in another Sequence wallet + // it contains the original metadata of the parent wallet. + parent?: WalletSignRequestMetadata + + decorate?: boolean + cantValidateBehavior?: 'ignore' | 'eip6492' | 'throw' +} + +export function isWalletSignRequestMetadata(obj: any): obj is WalletSignRequestMetadata { + return obj && obj.address && obj.digest && obj.chainId !== undefined && obj.config +} + +/** + * Request metadata, used by the wallet to pass additional information through the orchestrator. + */ +export type WalletDeployMetadata = { + includeChildren?: boolean // Whether to include children in deployment, default false + ignoreDeployed?: boolean // Whether to ignore already deployed wallets, default false +} diff --git a/packages/core/src/commons/reader.ts b/packages/core/src/commons/reader.ts new file mode 100644 index 0000000000..99af855bc6 --- /dev/null +++ b/packages/core/src/commons/reader.ts @@ -0,0 +1,93 @@ +import { walletContracts } from '@0xsequence/abi' +import { ethers } from 'ethers' +import { commons } from '..' +import { validateEIP6492Offchain } from './validateEIP6492' + +/** + * Provides stateful information about the wallet. + */ +export interface Reader { + isDeployed(wallet: string): Promise + implementation(wallet: string): Promise + imageHash(wallet: string): Promise + nonce(wallet: string, space: ethers.BigNumberish): Promise + isValidSignature(wallet: string, digest: ethers.BytesLike, signature: ethers.BytesLike): Promise +} + +/** + * The OnChainReader class fetches on-chain data from a wallet. + * It is used to understand the "real" state of the wallet contract on-chain. + */ +export class OnChainReader implements Reader { + // Simple cache to avoid re-fetching the same data + private isDeployedCache: Set = new Set() + + constructor(public readonly provider: ethers.providers.Provider) {} + + private module(address: string) { + return new ethers.Contract( + address, + [...walletContracts.mainModuleUpgradable.abi, ...walletContracts.mainModule.abi, ...walletContracts.erc1271.abi], + this.provider + ) + } + + async isDeployed(wallet: string): Promise { + // This is safe to cache because the wallet cannot be undeployed once deployed + if (this.isDeployedCache.has(wallet)) { + return true + } + + const code = await this.provider.getCode(wallet).then(c => ethers.utils.arrayify(c)) + const isDeployed = code.length !== 0 + if (isDeployed) { + this.isDeployedCache.add(wallet) + } + + return isDeployed + } + + async implementation(wallet: string): Promise { + const position = ethers.utils.defaultAbiCoder.encode(['address'], [wallet]) + const val = await this.provider.getStorageAt(wallet, position).then(c => ethers.utils.arrayify(c)) + + if (val.length === 20) { + return ethers.utils.getAddress(ethers.utils.hexlify(val)) + } + + if (val.length === 32) { + return ethers.utils.defaultAbiCoder.decode(['address'], val)[0] + } + + return undefined + } + + async imageHash(wallet: string): Promise { + try { + const imageHash = await this.module(wallet).imageHash() + return imageHash + } catch {} + + return undefined + } + + async nonce(wallet: string, space: ethers.BigNumberish = 0): Promise { + try { + const nonce = await this.module(wallet).readNonce(space) + return nonce + } catch (e) { + if (!(await this.isDeployed(wallet))) { + return 0 + } + + throw e + } + } + + // We use the EIP-6492 validator contract to check the signature + // this means that if the wallet is not deployed, then the signature + // must be prefixed with a transaction that deploys the wallet + async isValidSignature(wallet: string, digest: ethers.BytesLike, signature: ethers.BytesLike): Promise { + return validateEIP6492Offchain(this.provider, wallet, digest, signature) + } +} diff --git a/packages/core/src/commons/signature.ts b/packages/core/src/commons/signature.ts new file mode 100644 index 0000000000..e54dc4167f --- /dev/null +++ b/packages/core/src/commons/signature.ts @@ -0,0 +1,71 @@ +import { ethers } from 'ethers' +import * as config from './config' + +export type SignaturePart = { + signature: string + isDynamic: boolean +} + +export type Signature = { + version: number + config: T + subdigest: string + payload?: SignedPayload +} + +export type UnrecoveredSignature = { + version: number +} + +export type SignedPayload = { + message?: ethers.BytesLike + digest: string + chainId: ethers.BigNumberish + address: string +} + +export interface SignatureCoder< + Y extends config.Config = config.Config, + T extends Signature = Signature, + Z extends UnrecoveredSignature = UnrecoveredSignature +> { + decode: (data: string) => Z + encode: (data: T | Z | ethers.BytesLike) => string + + trim: (data: string) => Promise + + recover: (data: Z, payload: SignedPayload, provider: ethers.providers.Provider) => Promise + + supportsNoChainId: boolean + + encodeSigners: ( + config: Y, + signatures: Map, + subdigests: string[], + chainId: ethers.BigNumberish + ) => { + encoded: string + weight: ethers.BigNumber + } + + hasEnoughSigningPower: (config: Y, signatures: Map) => boolean + + chainSignatures: (main: T | Z | ethers.BytesLike, suffixes: (T | Z | ethers.BytesLike)[]) => string + + hashSetImageHash: (imageHash: string) => string + + signaturesOf: (config: Y) => { address: string; signature: string }[] + + signaturesOfDecoded: (decoded: Z) => string[] +} + +export function subdigestOf(payload: SignedPayload) { + return ethers.utils.solidityKeccak256( + ['bytes', 'uint256', 'address', 'bytes32'], + ['0x1901', payload.chainId, payload.address, payload.digest] + ) +} + +export function isSignedPayload(payload: any): payload is SignedPayload { + return payload.digest !== undefined && payload.chainId !== undefined && payload.address !== undefined +} diff --git a/packages/core/src/commons/signer.ts b/packages/core/src/commons/signer.ts new file mode 100644 index 0000000000..4e146c7a03 --- /dev/null +++ b/packages/core/src/commons/signer.ts @@ -0,0 +1,73 @@ +import { ethers } from 'ethers' +import { isValidEIP1271Signature } from './validateEIP1271' + +export enum SigType { + EIP712 = 1, + ETH_SIGN = 2, + WALLET_BYTES32 = 3 +} + +export function canRecover(signature: ethers.BytesLike) { + const bytes = ethers.utils.arrayify(signature) + const type = bytes[bytes.length - 1] + + return type === SigType.EIP712 || type === SigType.ETH_SIGN +} + +export function recoverSigner(digest: ethers.BytesLike, signature: ethers.BytesLike) { + const bytes = ethers.utils.arrayify(signature) + const digestBytes = ethers.utils.arrayify(digest) + + // type is last byte + const type = bytes[bytes.length - 1] + + // Split r:s:v + const r = ethers.utils.hexlify(bytes.slice(0, 32)) + const s = ethers.utils.hexlify(bytes.slice(32, 64)) + const v = ethers.BigNumber.from(bytes.slice(64, 65)).toNumber() + + const splitSignature = { r, s, v } + + if (type === SigType.EIP712) { + return ethers.utils.recoverAddress(digestBytes, splitSignature) + } + + if (type === SigType.ETH_SIGN) { + return ethers.utils.recoverAddress(ethers.utils.hashMessage(digestBytes), splitSignature) + } + + throw new Error(`Unsupported signature type: ${type}`) +} + +export function isValidSignature( + address: string, + digest: ethers.BytesLike, + signature: ethers.BytesLike, + provider: ethers.providers.Provider +) { + const bytes = ethers.utils.arrayify(signature) + + // type is last byte + const type = bytes[bytes.length - 1] + + if (type === SigType.EIP712 || type === SigType.ETH_SIGN) { + return address === recoverSigner(digest, signature) + } + + if (type === SigType.WALLET_BYTES32) { + return isValidEIP1271Signature(address, ethers.utils.hexlify(digest), bytes.slice(0, -1), provider) + } + + throw new Error(`Unsupported signature type: ${type}`) +} + +export function tryRecoverSigner(digest: ethers.BytesLike, signature: ethers.BytesLike): string | undefined { + const bytes = ethers.utils.arrayify(signature) + if (bytes.length !== 66) return undefined + + try { + return recoverSigner(digest, bytes) + } catch {} + + return undefined +} diff --git a/packages/core/src/commons/transaction.ts b/packages/core/src/commons/transaction.ts new file mode 100644 index 0000000000..a8495dab02 --- /dev/null +++ b/packages/core/src/commons/transaction.ts @@ -0,0 +1,322 @@ +import { BigNumberish, BytesLike, ethers } from 'ethers' +import { subdigestOf } from './signature' +import { walletContracts } from '@0xsequence/abi' + +export interface Transaction { + to: string + value?: BigNumberish + data?: BytesLike + gasLimit?: BigNumberish + delegateCall?: boolean + revertOnError?: boolean +} + +export interface SimulatedTransaction extends Transaction { + succeeded: boolean + executed: boolean + gasUsed: number + gasLimit: number + result?: string + reason?: string +} + +export interface TransactionEncoded { + delegateCall: boolean + revertOnError: boolean + gasLimit: BigNumberish + target: string + value: BigNumberish + data: BytesLike +} + +export type Transactionish = + | ethers.providers.TransactionRequest + | ethers.providers.TransactionRequest[] + | Transaction + | Transaction[] + +export interface TransactionResponse extends ethers.providers.TransactionResponse { + receipt?: R +} + +export type TransactionBundle = { + entrypoint: string + transactions: Transaction[] + nonce?: BigNumberish +} + +export type IntendedTransactionBundle = TransactionBundle & { + chainId: BigNumberish + intent: { + id: string + wallet: string + } +} + +export type SignedTransactionBundle = IntendedTransactionBundle & { + signature: string + nonce: BigNumberish +} + +export type RelayReadyTransactionBundle = SignedTransactionBundle | IntendedTransactionBundle + +export const MetaTransactionsType = `tuple( + bool delegateCall, + bool revertOnError, + uint256 gasLimit, + address target, + uint256 value, + bytes data +)[]` + +export function intendTransactionBundle( + bundle: TransactionBundle, + wallet: string, + chainId: BigNumberish, + id: string +): IntendedTransactionBundle { + return { + ...bundle, + chainId, + intent: { id: id, wallet } + } +} + +export function intendedTransactionID(bundle: IntendedTransactionBundle) { + return ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode( + ['address', 'uint256', 'bytes32'], + [bundle.intent.wallet, bundle.chainId, bundle.intent.id] + ) + ) +} + +export function unpackMetaTransactionsData(data: BytesLike): [ethers.BigNumber, TransactionEncoded[]] { + const res = ethers.utils.defaultAbiCoder.decode(['uint256', MetaTransactionsType], data) + if (res.length !== 2 || !res[0] || !res[1]) throw new Error('Invalid meta transaction data') + return [res[0], res[1]] +} + +export function packMetaTransactionsData(nonce: ethers.BigNumberish, txs: Transaction[]): string { + return ethers.utils.defaultAbiCoder.encode(['uint256', MetaTransactionsType], [nonce, sequenceTxAbiEncode(txs)]) +} + +export function digestOfTransactions(nonce: BigNumberish, txs: Transaction[]) { + return ethers.utils.keccak256(packMetaTransactionsData(nonce, txs)) +} + +export function subdigestOfTransactions( + address: string, + chainId: BigNumberish, + nonce: ethers.BigNumberish, + txs: Transaction[] +): string { + return subdigestOf({ address, chainId, digest: digestOfTransactions(nonce, txs) }) +} + +export function subdigestOfGuestModuleTransactions(guestModule: string, chainId: BigNumberish, txs: Transaction[]): string { + return subdigestOf({ + address: guestModule, + chainId, + digest: ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode(['string', MetaTransactionsType], ['guest:', sequenceTxAbiEncode(txs)]) + ) + }) +} + +export function toSequenceTransactions( + wallet: string, + txs: (Transaction | ethers.providers.TransactionRequest)[] +): { nonce?: ethers.BigNumberish; transaction: Transaction }[] { + return txs.map(tx => toSequenceTransaction(wallet, tx)) +} + +export function toSequenceTransaction( + wallet: string, + tx: ethers.providers.TransactionRequest +): { nonce?: ethers.BigNumberish; transaction: Transaction } { + if (tx.to && tx.to !== ethers.constants.AddressZero) { + return { + nonce: tx.nonce, + transaction: { + delegateCall: false, + revertOnError: false, + gasLimit: tx.gasLimit || 0, + to: tx.to, + value: tx.value || 0, + data: tx.data || '0x' + } + } + } else { + const walletInterface = new ethers.utils.Interface(walletContracts.mainModule.abi) + const data = walletInterface.encodeFunctionData(walletInterface.getFunction('createContract'), [tx.data]) + + return { + nonce: tx.nonce, + transaction: { + delegateCall: false, + revertOnError: false, + gasLimit: tx.gasLimit, + to: wallet, + value: tx.value || 0, + data: data + } + } + } +} + +export function isSequenceTransaction(tx: any): tx is Transaction { + return tx.delegateCall !== undefined || tx.revertOnError !== undefined +} + +export function hasSequenceTransactions(txs: any[]): txs is Transaction[] { + return txs.every(isSequenceTransaction) +} + +// TODO: We may be able to remove this if we make Transaction === TransactionEncoded +export function sequenceTxAbiEncode(txs: Transaction[]): TransactionEncoded[] { + return txs.map(t => ({ + delegateCall: t.delegateCall === true, + revertOnError: t.revertOnError === true, + gasLimit: t.gasLimit !== undefined ? t.gasLimit : ethers.constants.Zero, + target: t.to ?? ethers.constants.AddressZero, + value: t.value !== undefined ? t.value : ethers.constants.Zero, + data: t.data !== undefined ? t.data : [] + })) +} + +export function fromTxAbiEncode(txs: TransactionEncoded[]): Transaction[] { + return txs.map(t => ({ + delegateCall: t.delegateCall, + revertOnError: t.revertOnError, + gasLimit: t.gasLimit, + to: t.target, + value: t.value, + data: t.data + })) +} + +// export function appendNonce(txs: Transaction[], nonce: BigNumberish): Transaction[] { +// return txs.map((t: Transaction) => ({ ...t, nonce })) +// } + +export function encodeNonce(space: BigNumberish, nonce: BigNumberish): ethers.BigNumber { + const bspace = ethers.BigNumber.from(space) + const bnonce = ethers.BigNumber.from(nonce) + + const shl = ethers.constants.Two.pow(ethers.BigNumber.from(96)) + + if (!bnonce.div(shl).eq(ethers.constants.Zero)) { + throw new Error('Space already encoded') + } + + return bnonce.add(bspace.mul(shl)) +} + +export function decodeNonce(nonce: BigNumberish): [ethers.BigNumber, ethers.BigNumber] { + const bnonce = ethers.BigNumber.from(nonce) + const shr = ethers.constants.Two.pow(ethers.BigNumber.from(96)) + + return [bnonce.div(shr), bnonce.mod(shr)] +} + +export function fromTransactionish(wallet: string, transaction: Transactionish): Transaction[] { + if (Array.isArray(transaction)) { + if (hasSequenceTransactions(transaction)) { + return transaction + } else { + const stx = toSequenceTransactions(wallet, transaction) + return stx.map(t => t.transaction) + } + } else if (isSequenceTransaction(transaction)) { + return [transaction] + } else { + return [toSequenceTransaction(wallet, transaction).transaction] + } +} + +export function isTransactionBundle(cand: any): cand is TransactionBundle { + return ( + cand !== undefined && + cand.entrypoint !== undefined && + cand.chainId !== undefined && + cand.transactions !== undefined && + cand.nonce !== undefined && + cand.intent !== undefined && + cand.intent.id !== undefined && + cand.intent.wallet !== undefined && + Array.isArray(cand.transactions) && + (cand).transactions.reduce((p, c) => p && isSequenceTransaction(c), true) + ) +} + +export function isSignedTransactionBundle(cand: any): cand is SignedTransactionBundle { + return cand !== undefined && cand.signature !== undefined && cand.signature !== '' && isTransactionBundle(cand) +} + +export function encodeBundleExecData(bundle: TransactionBundle): string { + const walletInterface = new ethers.utils.Interface(walletContracts.mainModule.abi) + return walletInterface.encodeFunctionData( + walletInterface.getFunction('execute'), + isSignedTransactionBundle(bundle) + ? [ + // Signed transaction bundle has all 3 parameters + sequenceTxAbiEncode(bundle.transactions), + bundle.nonce, + bundle.signature + ] + : [ + // Unsigned bundle may be a GuestModule call, so signature and nonce are missing + sequenceTxAbiEncode(bundle.transactions), + 0, + [] + ] + ) +} + +// TODO: Use Sequence ABI package +export const selfExecuteSelector = '0x61c2926c' +export const selfExecuteAbi = `tuple( + bool delegateCall, + bool revertOnError, + uint256 gasLimit, + address target, + uint256 value, + bytes data +)[]` + +// Splits Sequence batch transactions into individual parts +export const unwind = (wallet: string, transactions: Transaction[]): Transaction[] => { + const unwound: Transaction[] = [] + + const walletInterface = new ethers.utils.Interface(walletContracts.mainModule.abi) + + for (const tx of transactions) { + const txData = ethers.utils.arrayify(tx.data || '0x') + + if (tx.to === wallet && ethers.utils.hexlify(txData.slice(0, 4)) === selfExecuteSelector) { + // Decode as selfExecute call + const data = txData.slice(4) + const decoded = ethers.utils.defaultAbiCoder.decode([selfExecuteAbi], data)[0] + unwound.push( + ...unwind( + tx.to, + decoded.map((d: TransactionEncoded) => ({ ...d, to: d.target })) + ) + ) + } else { + try { + const innerTransactions = walletInterface.decodeFunctionData('execute', txData)[0] + const unwoundTransactions = unwind( + wallet, + innerTransactions.map((tx: TransactionEncoded) => ({ ...tx, to: tx.target })) + ) + unwound.push(...unwoundTransactions) + } catch { + unwound.push(tx) + } + } + } + + return unwound +} diff --git a/packages/core/src/commons/validateEIP1271.ts b/packages/core/src/commons/validateEIP1271.ts new file mode 100644 index 0000000000..d71049182b --- /dev/null +++ b/packages/core/src/commons/validateEIP1271.ts @@ -0,0 +1,38 @@ +import { ethers } from 'ethers' + +const EIP1271_MAGIC_VALUE = '0x1626ba7e' + +const EIP1271_ABI = [ + { + inputs: [ + { + internalType: 'bytes32', + type: 'bytes32' + }, + { + internalType: 'bytes', + type: 'bytes' + } + ], + name: 'isValidSignature', + outputs: [ + { + internalType: 'bytes4', + type: 'bytes4' + } + ], + stateMutability: 'view', + type: 'function' + } +] + +export async function isValidEIP1271Signature( + address: string, + digest: string, + signature: ethers.BytesLike, + provider: ethers.providers.Provider +): Promise { + const contract = new ethers.Contract(address, EIP1271_ABI, provider) + const result = await contract.isValidSignature(digest, signature) + return result === EIP1271_MAGIC_VALUE +} diff --git a/packages/core/src/commons/validateEIP6492.ts b/packages/core/src/commons/validateEIP6492.ts new file mode 100644 index 0000000000..478c5786d2 --- /dev/null +++ b/packages/core/src/commons/validateEIP6492.ts @@ -0,0 +1,197 @@ +import { ethers } from 'ethers' + +/* Source of Offchain EIP-6492 validation: + +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + + +// As per ERC-1271 +interface IERC1271Wallet { + function isValidSignature(bytes32 hash, bytes calldata signature) external view returns (bytes4 magicValue); +} + +error ERC1271Revert(bytes error); +error ERC6492DeployFailed(bytes error); + +contract UniversalSigValidator { + bytes32 private constant ERC6492_DETECTION_SUFFIX = 0x6492649264926492649264926492649264926492649264926492649264926492; + bytes4 private constant ERC1271_SUCCESS = 0x1626ba7e; + + function isValidSigImpl( + address _signer, + bytes32 _hash, + bytes calldata _signature, + bool allowSideEffects, + bool deployAlreadyDeployed + ) public returns (bool) { + uint contractCodeLen = address(_signer).code.length; + bytes memory sigToValidate; + // The order here is striclty defined in https://eips.ethereum.org/EIPS/eip-6492 + // - ERC-6492 suffix check and verification first, while being permissive in case the contract is already deployed; if the contract is deployed we will check the sig against the deployed version, this allows 6492 signatures to still be validated while taking into account potential key rotation + // - ERC-1271 verification if there's contract code + // - finally, ecrecover + bool isCounterfactual = bytes32(_signature[_signature.length-32:_signature.length]) == ERC6492_DETECTION_SUFFIX; + if (isCounterfactual) { + address create2Factory; + bytes memory factoryCalldata; + (create2Factory, factoryCalldata, sigToValidate) = abi.decode(_signature[0:_signature.length-32], (address, bytes, bytes)); + + if (contractCodeLen == 0 || deployAlreadyDeployed) { + (bool success, bytes memory err) = create2Factory.call(factoryCalldata); + if (!success) revert ERC6492DeployFailed(err); + } + } else { + sigToValidate = _signature; + } + + // Try ERC-1271 verification + if (isCounterfactual || contractCodeLen > 0) { + try IERC1271Wallet(_signer).isValidSignature(_hash, sigToValidate) returns (bytes4 magicValue) { + bool isValid = magicValue == ERC1271_SUCCESS; + + // EXPERIMENTAL: This is not part of the EIP-6492 spec *yet* + // but it may be useful to retry the call making the factory call + // even if the wallet is already deployed, in case the wallet + // needs to perform some sort of migration or onchain key rotation + if (!isValid && !deployAlreadyDeployed && contractCodeLen > 0) { + return isValidSigImpl(_signer, _hash, _signature, allowSideEffects, true); + } + + if (contractCodeLen == 0 && isCounterfactual && !allowSideEffects) { + // if the call had side effects we need to return the + // result using a `revert` (to undo the state changes) + assembly { + mstore(0, isValid) + revert(31, 1) + } + } + + return isValid; + } catch (bytes memory err) { + // EXPERIMENTAL: This is not part of the EIP-6492 spec *yet* + // but it may be useful to retry the call making the factory call + // even if the wallet is already deployed, in case the wallet + // needs to perform some sort of migration or onchain key rotation + if (!deployAlreadyDeployed && contractCodeLen > 0) { + return isValidSigImpl(_signer, _hash, _signature, allowSideEffects, true); + } + + revert ERC1271Revert(err); + } + } + + // ecrecover verification + require(_signature.length == 65, 'SignatureValidator#recoverSigner: invalid signature length'); + bytes32 r = bytes32(_signature[0:32]); + bytes32 s = bytes32(_signature[32:64]); + uint8 v = uint8(_signature[64]); + + if (v != 27 && v != 28) { + revert('SignatureValidator: invalid signature v value'); + } + + return ecrecover(_hash, v, r, s) == _signer; + } + + function isValidSigWithSideEffects( + address _signer, + bytes32 _hash, + bytes calldata _signature + ) external returns (bool) { + return this.isValidSigImpl(_signer, _hash, _signature, true, false); + } + + function isValidSig( + address _signer, + bytes32 _hash, + bytes calldata _signature + ) external returns (bool) { + try this.isValidSigImpl(_signer, _hash, _signature, false, false) returns (bool isValid) { + return isValid; + } catch (bytes memory error) { + // in order to avoid side effects from the contract getting deployed, the entire call will revert with a single byte result + uint len = error.length; + if (len == 1) { + return error[0] == 0x01; + // all other errors are simply forwarded, but in custom formats so that nothing else can revert with a single byte in the call + } else { + assembly { revert(error, len) } + } + } + } + + // NOTICE: These functions aren't part of the standard + // they are helpers that behave like the above functions + // but they don't revert on failure, instead they return false + + function isValidSigNoThrow( + address _signer, + bytes32 _hash, + bytes calldata _signature + ) external returns (bool) { + try this.isValidSigImpl(_signer, _hash, _signature, false, false) returns (bool isValid) { + return isValid; + } catch (bytes memory error) { + // in order to avoid side effects from the contract getting deployed, the entire call will revert with a single byte result + uint len = error.length; + if (len == 1) { + return error[0] == 0x01; + // all other errors are simply forwarded, but in custom formats so that nothing else can revert with a single byte in the call + } else { + // Ignore all other errors and return false + return false; + } + } + } + + function isValidSigWithSideEffectsNoThrow( + address _signer, + bytes32 _hash, + bytes calldata _signature + ) external returns (bool) { + try this.isValidSigImpl(_signer, _hash, _signature, true, false) returns (bool isValid) { + return isValid; + } catch (bytes memory error) { + // Ignore all errors and return false + return false; + } + } +} + +// this is a helper so we can perform validation in a single eth_call without pre-deploying a singleton +contract ValidateSigOffchain { + constructor (address _signer, bytes32 _hash, bytes memory _signature) { + UniversalSigValidator validator = new UniversalSigValidator(); + bool isValidSig = validator.isValidSigWithSideEffects(_signer, _hash, _signature); + assembly { + mstore(0, isValidSig) + return(31, 1) + } + } +} +*/ + +export const EIP_6492_OFFCHAIN_DEPLOY_CODE = + '0x608060405234801561001057600080fd5b5060405161124a38038061124a83398101604081905261002f91610124565b600060405161003d906100dd565b604051809103906000f080158015610059573d6000803e3d6000fd5b5090506000816001600160a01b0316638f0684308686866040518463ffffffff1660e01b815260040161008e939291906101fb565b6020604051808303816000875af11580156100ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100d19190610244565b9050806000526001601ff35b610fdc8061026e83390190565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561011b578181015183820152602001610103565b50506000910152565b60008060006060848603121561013957600080fd5b83516001600160a01b038116811461015057600080fd5b6020850151604086015191945092506001600160401b038082111561017457600080fd5b818601915086601f83011261018857600080fd5b81518181111561019a5761019a6100ea565b604051601f8201601f19908116603f011681019083821181831017156101c2576101c26100ea565b816040528281528960208487010111156101db57600080fd5b6101ec836020830160208801610100565b80955050505050509250925092565b60018060a01b0384168152826020820152606060408201526000825180606084015261022e816080850160208701610100565b601f01601f191691909101608001949350505050565b60006020828403121561025657600080fd5b8151801515811461026657600080fd5b939250505056fe608060405234801561001057600080fd5b50610fbc806100206000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c806376be4cea1161005057806376be4cea146100a65780638f068430146100b957806398ef1ed8146100cc57600080fd5b80631c6453271461006c5780633d787b6314610093575b600080fd5b61007f61007a366004610ad4565b6100df565b604051901515815260200160405180910390f35b61007f6100a1366004610ad4565b61023d565b61007f6100b4366004610b3e565b61031e565b61007f6100c7366004610ad4565b6108e1565b61007f6100da366004610ad4565b61096e565b6040517f76be4cea00000000000000000000000000000000000000000000000000000000815260009030906376be4cea9061012890889088908890889088908190600401610bc3565b6020604051808303816000875af1925050508015610181575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261017e91810190610c45565b60015b610232573d8080156101af576040519150601f19603f3d011682016040523d82523d6000602084013e6101b4565b606091505b508051600181900361022757816000815181106101d3576101d3610c69565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0100000000000000000000000000000000000000000000000000000000000000149250610235915050565b600092505050610235565b90505b949350505050565b6040517f76be4cea00000000000000000000000000000000000000000000000000000000815260009030906376be4cea906102879088908890889088906001908990600401610bc3565b6020604051808303816000875af19250505080156102e0575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526102dd91810190610c45565b60015b610232573d80801561030e576040519150601f19603f3d011682016040523d82523d6000602084013e610313565b606091505b506000915050610235565b600073ffffffffffffffffffffffffffffffffffffffff87163b6060827f64926492649264926492649264926492649264926492649264926492649264928888610369602082610c98565b610375928b9290610cd8565b61037e91610d02565b1490508015610484576000606089828a610399602082610c98565b926103a693929190610cd8565b8101906103b39190610e18565b955090925090508415806103c45750865b1561047d576000808373ffffffffffffffffffffffffffffffffffffffff16836040516103f19190610eb2565b6000604051808303816000865af19150503d806000811461042e576040519150601f19603f3d011682016040523d82523d6000602084013e610433565b606091505b50915091508161047a57806040517f9d0d6e2d0000000000000000000000000000000000000000000000000000000081526004016104719190610f18565b60405180910390fd5b50505b50506104be565b87878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509294505050505b80806104ca5750600083115b156106bb576040517f1626ba7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8b1690631626ba7e90610523908c908690600401610f2b565b602060405180830381865afa92505050801561057a575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261057791810190610f44565b60015b61060f573d8080156105a8576040519150601f19603f3d011682016040523d82523d6000602084013e6105ad565b606091505b50851580156105bc5750600084115b156105db576105d08b8b8b8b8b600161031e565b9450505050506108d7565b806040517f6f2a95990000000000000000000000000000000000000000000000000000000081526004016104719190610f18565b7fffffffff0000000000000000000000000000000000000000000000000000000081167f1626ba7e000000000000000000000000000000000000000000000000000000001480158161065f575086155b801561066b5750600085115b1561068b5761067f8c8c8c8c8c600161031e565b955050505050506108d7565b841580156106965750825b80156106a0575087155b156106af57806000526001601ffd5b94506108d79350505050565b6041871461074b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5369676e617475726556616c696461746f72237265636f7665725369676e657260448201527f3a20696e76616c6964207369676e6174757265206c656e6774680000000000006064820152608401610471565b600061075a6020828a8c610cd8565b61076391610d02565b90506000610775604060208b8d610cd8565b61077e91610d02565b905060008a8a604081811061079557610795610c69565b919091013560f81c915050601b81148015906107b557508060ff16601c14155b15610842576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f5369676e617475726556616c696461746f723a20696e76616c6964207369676e60448201527f617475726520762076616c7565000000000000000000000000000000000000006064820152608401610471565b6040805160008152602081018083528e905260ff831691810191909152606081018490526080810183905273ffffffffffffffffffffffffffffffffffffffff8e169060019060a0016020604051602081039080840390855afa1580156108ad573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff161496505050505050505b9695505050505050565b6040517f76be4cea00000000000000000000000000000000000000000000000000000000815260009030906376be4cea9061092b9088908890889088906001908990600401610bc3565b6020604051808303816000875af115801561094a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102329190610c45565b6040517f76be4cea00000000000000000000000000000000000000000000000000000000815260009030906376be4cea906109b790889088908890889088908190600401610bc3565b6020604051808303816000875af1925050508015610a10575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252610a0d91810190610c45565b60015b610232573d808015610a3e576040519150601f19603f3d011682016040523d82523d6000602084013e610a43565b606091505b5080516001819003610a6257816000815181106101d3576101d3610c69565b8082fd5b73ffffffffffffffffffffffffffffffffffffffff81168114610a8857600080fd5b50565b60008083601f840112610a9d57600080fd5b50813567ffffffffffffffff811115610ab557600080fd5b602083019150836020828501011115610acd57600080fd5b9250929050565b60008060008060608587031215610aea57600080fd5b8435610af581610a66565b935060208501359250604085013567ffffffffffffffff811115610b1857600080fd5b610b2487828801610a8b565b95989497509550505050565b8015158114610a8857600080fd5b60008060008060008060a08789031215610b5757600080fd5b8635610b6281610a66565b955060208701359450604087013567ffffffffffffffff811115610b8557600080fd5b610b9189828a01610a8b565b9095509350506060870135610ba581610b30565b91506080870135610bb581610b30565b809150509295509295509295565b73ffffffffffffffffffffffffffffffffffffffff8716815285602082015260a060408201528360a0820152838560c0830137600060c085830181019190915292151560608201529015156080820152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101019392505050565b600060208284031215610c5757600080fd5b8151610c6281610b30565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b81810381811115610cd2577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b92915050565b60008085851115610ce857600080fd5b83861115610cf557600080fd5b5050820193919092039150565b80356020831015610cd2577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112610d7e57600080fd5b813567ffffffffffffffff80821115610d9957610d99610d3e565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610ddf57610ddf610d3e565b81604052838152866020858801011115610df857600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600060608486031215610e2d57600080fd5b8335610e3881610a66565b9250602084013567ffffffffffffffff80821115610e5557600080fd5b610e6187838801610d6d565b93506040860135915080821115610e7757600080fd5b50610e8486828701610d6d565b9150509250925092565b60005b83811015610ea9578181015183820152602001610e91565b50506000910152565b60008251610ec4818460208701610e8e565b9190910192915050565b60008151808452610ee6816020860160208601610e8e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610c626020830184610ece565b8281526040602082015260006102356040830184610ece565b600060208284031215610f5657600080fd5b81517fffffffff0000000000000000000000000000000000000000000000000000000081168114610c6257600080fdfea26469706673582212201a72aed4b15ffb05b6502997a9bb655992e06590bd26b336dfbb153d7ff6f34b64736f6c63430008120033' +export const EIP_6492_SUFFIX = '0x6492649264926492649264926492649264926492649264926492649264926492' + +// TODO: This is a length payload, we can lower the load by deploying +// the contract on some of the popular chains, and calling the contract +// if the provider is one of those chains +export async function validateEIP6492Offchain( + provider: ethers.providers.Provider, + signer: string, + hash: ethers.utils.BytesLike, + signature: ethers.utils.BytesLike +): Promise { + return ( + '0x01' === + (await provider.call({ + data: ethers.utils.concat([ + EIP_6492_OFFCHAIN_DEPLOY_CODE, + new ethers.utils.AbiCoder().encode(['address', 'bytes32', 'bytes'], [signer, hash, signature]) + ]) + })) + ) +} diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts new file mode 100644 index 0000000000..3d153a1ceb --- /dev/null +++ b/packages/core/src/index.ts @@ -0,0 +1,11 @@ +export * as v1 from './v1' +export * as v2 from './v2' +export * as commons from './commons' +export * as universal from './universal' + +import * as v1 from './v1' +import * as v2 from './v2' + +export { VERSION } from './version' + +export const allVersions = [v1, v2] diff --git a/packages/core/src/universal/index.ts b/packages/core/src/universal/index.ts new file mode 100644 index 0000000000..54e70287c4 --- /dev/null +++ b/packages/core/src/universal/index.ts @@ -0,0 +1,25 @@ +import { commons, v1, v2 } from '..' + +export const ALL_CODERS = [ + { config: v1.config.ConfigCoder, signature: v1.signature.SignatureCoder }, + { config: v2.config.ConfigCoder, signature: v2.signature.SignatureCoder } +] + +export function coderFor(version: number) { + const index = version - 1 + if (index < 0 || index >= ALL_CODERS.length) { + throw new Error(`No coder for version: ${version}`) + } + + return ALL_CODERS[index] +} + +/** + * Same as `coderFor` but returns `generic` coders without versioned types. + */ +export function genericCoderFor(version: number): { + config: commons.config.ConfigCoder + signature: commons.signature.SignatureCoder +} { + return coderFor(version) +} diff --git a/packages/core/src/v1/config.ts b/packages/core/src/v1/config.ts new file mode 100644 index 0000000000..859474b278 --- /dev/null +++ b/packages/core/src/v1/config.ts @@ -0,0 +1,221 @@ +import { ethers } from 'ethers' +import { walletContracts } from '@0xsequence/abi' +import { commons } from '..' +import { encodeSigners } from './signature' +import { SimpleConfig } from '../commons/config' + +export type AddressMember = { + weight: ethers.BigNumberish + address: string + signature?: string +} + +export type WalletConfig = commons.config.Config & { + threshold: ethers.BigNumberish + signers: AddressMember[] +} + +export const ConfigCoder: commons.config.ConfigCoder = { + isWalletConfig: (config: commons.config.Config): config is WalletConfig => { + return ( + config.version === 1 && (config as WalletConfig).threshold !== undefined && (config as WalletConfig).signers !== undefined + ) + }, + + imageHashOf: (config: WalletConfig): string => { + return config.signers.reduce( + (imageHash, signer) => + ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode(['bytes32', 'uint8', 'address'], [imageHash, signer.weight, signer.address]) + ), + ethers.utils.solidityPack(['uint256'], [config.threshold]) + ) + }, + + hasSubdigest: (_walletConfig: WalletConfig, _subdigest: string): boolean => { + // v1 does not support explicit subdigests + return false + }, + + isComplete: (_config: WalletConfig): boolean => { + // v1 does not support incomplete configs + return true + }, + + checkpointOf: (_config: WalletConfig): ethers.BigNumber => { + return ethers.BigNumber.from(0) + }, + + signersOf: (config: WalletConfig): { address: string; weight: number }[] => { + return config.signers.map(s => ({ address: s.address, weight: ethers.BigNumber.from(s.weight).toNumber() })) + }, + + fromSimple: (config: SimpleConfig): WalletConfig => { + if (!ethers.constants.Zero.eq(config.checkpoint)) { + throw new Error('v1 wallet config does not support checkpoint') + } + + if (config.subdigests && config.subdigests.length > 0) { + throw new Error('v1 wallet config does not support subdigests') + } + + return { + version: 1, + threshold: config.threshold, + signers: config.signers + } + }, + + update: { + isKindUsed: true, + + buildTransaction: ( + wallet: string, + config: WalletConfig, + context: commons.context.WalletContext, + kind?: 'first' | 'later' | undefined + ): commons.transaction.TransactionBundle => { + const module = new ethers.utils.Interface([...walletContracts.mainModule.abi, ...walletContracts.mainModuleUpgradable.abi]) + + const transactions: commons.transaction.Transaction[] = [] + + if (!kind || kind === 'first') { + transactions.push({ + to: wallet, + data: module.encodeFunctionData(module.getFunction('updateImplementation'), [context.mainModuleUpgradable]), + gasLimit: 0, + delegateCall: false, + revertOnError: true, + value: 0 + }) + } + + transactions.push({ + to: wallet, + data: module.encodeFunctionData(module.getFunction('updateImageHash'), [ConfigCoder.imageHashOf(config)]), + gasLimit: 0, + delegateCall: false, + revertOnError: true, + value: 0 + }) + + return { + entrypoint: wallet, + transactions + } + }, + decodeTransaction: function (tx: commons.transaction.TransactionBundle): { + address: string + newImageHash: string + kind: 'first' | 'later' | undefined + } { + throw new Error('Function not implemented.') + } + }, + + toJSON: function (config: WalletConfig): string { + const plainMembers = config.signers.map(signer => { + return { + weight: ethers.BigNumber.from(signer.weight).toString(), + address: signer.address + } + }) + + return JSON.stringify({ + version: config.version, + threshold: ethers.BigNumber.from(config.threshold).toString(), + signers: plainMembers + }) + }, + + fromJSON: function (json: string): WalletConfig { + const parsed = JSON.parse(json) + + const signers = parsed.signers.map((signer: any) => { + return { + weight: ethers.BigNumber.from(signer.weight), + address: signer.address + } + }) + + return { + version: parsed.version, + threshold: ethers.BigNumber.from(parsed.threshold), + signers + } + }, + + editConfig: function ( + config: WalletConfig, + action: { + add?: commons.config.SimpleSigner[] + remove?: string[] + threshold?: ethers.BigNumberish + checkpoint?: ethers.BigNumberish + } + ): WalletConfig { + const newSigners = config.signers.slice() + + if (action.checkpoint && !ethers.constants.Zero.eq(action.checkpoint)) { + throw new Error('v1 wallet config does not support checkpoint') + } + + if (action.add) { + for (const signer of action.add) { + if (newSigners.find(s => s.address === signer.address)) { + continue + } + + newSigners.push({ + weight: signer.weight, + address: signer.address + }) + } + } + + if (action.remove) { + for (const address of action.remove) { + const index = newSigners.findIndex(signer => signer.address === address) + if (index >= 0) { + newSigners.splice(index, 1) + } + } + } + + return { + version: config.version, + threshold: action.threshold ?? config.threshold, + signers: newSigners + } + }, + + buildStubSignature: function (config: WalletConfig, overrides: Map) { + const parts = new Map() + + for (const [signer, signature] of overrides.entries()) { + parts.set(signer, { signature, isDynamic: true }) + + const { encoded, weight } = encodeSigners(config, parts, [], 0) + + if (weight.gte(config.threshold)) { + return encoded + } + } + + const signers = config.signers + + for (const { address } of signers.sort(({ weight: a }, { weight: b }) => ethers.BigNumber.from(a).sub(b).toNumber())) { + const signature = + '0x4e82f02f388a12b5f9d29eaf2452dd040c0ee5804b4e504b4dd64e396c6c781f2c7624195acba242dd825bfd25a290912e3c230841fd55c9a734c4de8d9899451b02' + parts.set(address, { signature, isDynamic: false }) + + const { encoded, weight } = encodeSigners(config, parts, [], 0) + + if (weight.gte(config.threshold)) { + return encoded + } + } + + return encodeSigners(config, parts, [], 0).encoded + } +} diff --git a/packages/core/src/v1/index.ts b/packages/core/src/v1/index.ts new file mode 100644 index 0000000000..57ae48ed82 --- /dev/null +++ b/packages/core/src/v1/index.ts @@ -0,0 +1,15 @@ +import { WalletContext } from '../commons/context' + +export * as config from './config' +export * as signature from './signature' + +export const version = 1 + +export const DeployedWalletContext: WalletContext = { + version: version, + factory: '0xf9D09D634Fb818b05149329C1dcCFAeA53639d96', + guestModule: '0x02390F3E6E5FD1C6786CB78FD3027C117a9955A7', + mainModule: '0xd01F11855bCcb95f88D7A48492F66410d4637313', + mainModuleUpgradable: '0x7EFE6cE415956c5f80C6530cC6cc81b4808F6118', + walletCreationCode: '0x603a600e3d39601a805130553df3363d3d373d3d3d363d30545af43d82803e903d91601857fd5bf3' +} diff --git a/packages/core/src/v1/signature.ts b/packages/core/src/v1/signature.ts new file mode 100644 index 0000000000..628b0c2e6b --- /dev/null +++ b/packages/core/src/v1/signature.ts @@ -0,0 +1,256 @@ +import { ethers } from 'ethers' +import * as base from '../commons/signature' +import { AddressMember, WalletConfig } from './config' +import { isValidSignature, recoverSigner } from '../commons/signer' + +export enum SignaturePartType { + EOASignature = 0, + Address = 1, + DynamicSignature = 2 +} + +export type Signature = base.Signature + +export type UnrecoveredSignatureMember = { + unrecovered: true + weight: ethers.BigNumberish + signature: string + address?: string + isDynamic: boolean +} + +export type UnrecoveredMember = AddressMember | UnrecoveredSignatureMember + +export type UnrecoveredSignature = base.UnrecoveredSignature & { + threshold: ethers.BigNumberish + signers: UnrecoveredMember[] +} + +export function isAddressMember(member: any): member is AddressMember { + return (member as AddressMember).address !== undefined && !isUnrecoveredSignatureMember(member) +} + +export function isUnrecoveredSignatureMember(member: any): member is UnrecoveredSignatureMember { + return ( + (member as UnrecoveredSignatureMember).signature !== undefined && + (member as UnrecoveredSignatureMember).weight !== undefined && + (member as UnrecoveredSignatureMember).isDynamic !== undefined + ) +} + +export function isUnrecoveredSignature(signature: Signature | UnrecoveredSignature): signature is UnrecoveredSignature { + return (signature as UnrecoveredSignature).threshold !== undefined && (signature as UnrecoveredSignature).signers !== undefined +} + +export function decodeSignature(signature: ethers.BytesLike): UnrecoveredSignature { + const bytes = ethers.utils.arrayify(signature) + + const threshold = (bytes[0] << 8) | bytes[1] + const signers: UnrecoveredMember[] = [] + + for (let i = 2; i < bytes.length; ) { + const type = bytes[i++] + const weight = bytes[i++] + + switch (type) { + case SignaturePartType.EOASignature: + signers.push({ + unrecovered: true, + weight, + signature: ethers.utils.hexlify(bytes.slice(i, i + 66)), + isDynamic: false + }) + i += 66 + break + + case SignaturePartType.Address: + signers.push({ + weight, + address: ethers.utils.getAddress(ethers.utils.hexlify(bytes.slice(i, i + 20))) + }) + i += 20 + break + + case SignaturePartType.DynamicSignature: + const address = ethers.utils.getAddress(ethers.utils.hexlify(bytes.slice(i, i + 20))) + i += 20 + + const size = (bytes[i] << 8) | bytes[i + 1] + i += 2 + + signers.push({ + unrecovered: true, + weight, + signature: ethers.utils.hexlify(bytes.slice(i, i + size)), + address, + isDynamic: true + }) + i += size + break + + default: + throw new Error(`Unknown signature part type: ${type}`) + } + } + + return { version: 1, threshold, signers } +} + +export function encodeSignature(signature: Signature | UnrecoveredSignature | ethers.BytesLike): string { + if (ethers.utils.isBytesLike(signature)) return ethers.utils.hexlify(signature) + + const { signers, threshold } = isUnrecoveredSignature(signature) ? signature : signature.config + + const encodedSigners = signers.map(s => { + if (isAddressMember(s)) { + return ethers.utils.solidityPack(['uint8', 'uint8', 'address'], [SignaturePartType.Address, s.weight, s.address]) + } + + if (s.isDynamic) { + const bytes = ethers.utils.arrayify(s.signature) + return ethers.utils.solidityPack( + ['uint8', 'uint8', 'address', 'uint16', 'bytes'], + [SignaturePartType.DynamicSignature, s.weight, s.address, bytes.length, bytes] + ) + } + + return ethers.utils.solidityPack(['uint8', 'uint8', 'bytes'], [SignaturePartType.EOASignature, s.weight, s.signature]) + }) + + return ethers.utils.solidityPack(['uint16', ...new Array(encodedSigners.length).fill('bytes')], [threshold, ...encodedSigners]) +} + +export async function recoverSignature( + data: UnrecoveredSignature, + payload: base.SignedPayload, + provider: ethers.providers.Provider +): Promise { + const subdigest = base.subdigestOf(payload) + const signers = await Promise.all( + data.signers.map(async s => { + if (isAddressMember(s)) { + return s + } + + if (s.isDynamic) { + if (!s.address) throw new Error('Dynamic signature part must have address') + if (!isValidSignature(s.address, subdigest, s.signature, provider)) { + throw new Error(`Invalid dynamic signature part ${s.address}`) + } + + return { address: s.address, weight: s.weight, signature: s.signature } + } else { + const address = recoverSigner(subdigest, s.signature) + return { address, weight: s.weight, signature: s.signature } + } + }) + ) + + return { + version: 1, + payload, + subdigest, + config: { + version: 1, + threshold: data.threshold, + signers + } + } +} + +export function encodeSigners( + config: WalletConfig, + signatures: Map, + subdigests: string[], + _: ethers.BigNumberish +): { encoded: string; weight: ethers.BigNumber } { + if (subdigests.length !== 0) { + throw new Error('Explicit subdigests not supported on v1') + } + + let weight = ethers.BigNumber.from(0) + const parts = config.signers.map(s => { + if (!signatures.has(s.address)) { + return s + } + + const signature = signatures.get(s.address)! + const bytes = ethers.utils.arrayify(signature.signature) + + weight = weight.add(s.weight) + + if (signature.isDynamic || bytes.length !== 66) { + return { + ...s, + isDynamic: true, + signature: signature.signature, + address: s.address + } + } + + return { + ...s, + isDynamic: false, + signature: signature.signature + } + }) + + const encoded = encodeSignature({ version: 1, threshold: config.threshold, signers: parts }) + return { encoded, weight } +} + +export const SignatureCoder: base.SignatureCoder = { + decode: (data: string): UnrecoveredSignature => { + return decodeSignature(data) + }, + + encode: (data: Signature | UnrecoveredSignature | ethers.BytesLike): string => { + return encodeSignature(data) + }, + + trim: async (data: string): Promise => { + return data + }, + + supportsNoChainId: true, + + recover: (data: UnrecoveredSignature, payload: base.SignedPayload, provider: ethers.providers.Provider): Promise => { + return recoverSignature(data, payload, provider) + }, + + encodeSigners: ( + config: WalletConfig, + signatures: Map, + subdigests: string[], + chainId: ethers.BigNumberish + ): { + encoded: string + weight: ethers.BigNumber + } => { + return encodeSigners(config, signatures, subdigests, chainId) + }, + + hasEnoughSigningPower: (config: WalletConfig, signatures: Map): boolean => { + const { weight } = SignatureCoder.encodeSigners(config, signatures, [], 0) + return weight.gte(config.threshold) + }, + + chainSignatures: ( + _main: Signature | UnrecoveredSignature | ethers.BytesLike, + _suffix: (Signature | UnrecoveredSignature | ethers.BytesLike)[] + ): string => { + throw new Error('Signature chaining not supported on v1') + }, + + hashSetImageHash: function (_imageHash: string): string { + throw new Error('Image hash not supported on v1') + }, + + signaturesOf(config: WalletConfig): { address: string; signature: string }[] { + return config.signers.filter(s => s.signature !== undefined).map(s => ({ address: s.address, signature: s.signature! })) + }, + + signaturesOfDecoded: function (data: UnrecoveredSignature): string[] { + return data.signers.map(s => s.signature).filter(s => s !== undefined) as string[] + } +} diff --git a/packages/core/src/v2/chained.ts b/packages/core/src/v2/chained.ts new file mode 100644 index 0000000000..9240aee75d --- /dev/null +++ b/packages/core/src/v2/chained.ts @@ -0,0 +1,23 @@ +import { ethers } from 'ethers' + +// = keccak256("SetImageHash(bytes32 imageHash)") +export const SetImageHashPrefix = '0x8713a7c4465f6fbee2b6e9d6646d1d9f83fec929edfc4baf661f3c865bdd04d1' + +export function hashSetImageHash(imageHash: string): string { + return ethers.utils.keccak256(messageSetImageHash(imageHash)) +} + +export function messageSetImageHash(imageHash: string) { + return ethers.utils.solidityPack(['bytes32', 'bytes32'], [SetImageHashPrefix, imageHash]) +} + +export function decodeMessageSetImageHash(message: ethers.BytesLike): string | undefined { + const arr = ethers.utils.arrayify(message) + if (arr.length !== 64) return undefined + if (ethers.utils.hexlify(arr.slice(0, 32)) !== SetImageHashPrefix) return undefined + return ethers.utils.hexlify(arr.slice(32, 64)) +} + +export function isMessageSetImageHash(message: ethers.BytesLike): boolean { + return decodeMessageSetImageHash(message) !== undefined +} diff --git a/packages/core/src/v2/config.ts b/packages/core/src/v2/config.ts new file mode 100644 index 0000000000..968e265eaf --- /dev/null +++ b/packages/core/src/v2/config.ts @@ -0,0 +1,620 @@ +import { ethers } from 'ethers' +import { walletContracts } from '@0xsequence/abi' +import { commons } from '..' +import { encodeSigners } from './signature' +import { SimpleConfig } from '../commons/config' + +// +// Tree typings - leaves +// + +export type SignerLeaf = { + address: string + weight: ethers.BigNumberish + signature?: string +} + +export type SubdigestLeaf = { + subdigest: string +} + +export type NestedLeaf = { + tree: Topology + weight: ethers.BigNumberish + threshold: ethers.BigNumberish +} + +// This is an unknown node +// it means the tree has a branch +// but we don't know what the content +export type NodeLeaf = { + nodeHash: string +} + +export type Leaf = SignerLeaf | SubdigestLeaf | NestedLeaf | NodeLeaf + +export function isSignerLeaf(leaf: any): leaf is SignerLeaf { + return (leaf as SignerLeaf).address !== undefined && (leaf as SignerLeaf).weight !== undefined +} + +export function isSubdigestLeaf(leaf: any): leaf is SubdigestLeaf { + return (leaf as SubdigestLeaf).subdigest !== undefined && (leaf as SignerLeaf).address === undefined +} + +export function topologyToJSON(tree: Topology): string { + if (isNode(tree)) { + return JSON.stringify({ + left: topologyToJSON(tree.left), + right: topologyToJSON(tree.right) + }) + } + + if (isNestedLeaf(tree)) { + return JSON.stringify({ + weight: ethers.BigNumber.from(tree.weight).toString(), + threshold: ethers.BigNumber.from(tree.threshold).toString(), + tree: topologyToJSON(tree.tree) + }) + } + + if (isSignerLeaf(tree)) { + return JSON.stringify({ + address: tree.address, + weight: ethers.BigNumber.from(tree.weight).toString() + }) + } + + return JSON.stringify(tree) +} + +export function topologyFromJSON(json: string | object): Topology { + const parsed = typeof json === 'string' ? JSON.parse(json) : json + + if (parsed.left !== undefined && parsed.right !== undefined) { + return { + left: topologyFromJSON(parsed.left), + right: topologyFromJSON(parsed.right) + } + } + + if (parsed.weight !== undefined && parsed.threshold !== undefined && parsed.tree !== undefined) { + return { + weight: ethers.BigNumber.from(parsed.weight), + threshold: ethers.BigNumber.from(parsed.threshold), + tree: topologyFromJSON(parsed.tree) + } + } + + if (parsed.address !== undefined && parsed.weight !== undefined) { + return { + address: parsed.address, + weight: ethers.BigNumber.from(parsed.weight) + } + } + + return parsed +} + +export function isNestedLeaf(leaf: any): leaf is NestedLeaf { + return ( + (leaf as NestedLeaf).tree !== undefined && + (leaf as NestedLeaf).weight !== undefined && + (leaf as NestedLeaf).threshold !== undefined + ) +} + +export function isNodeLeaf(leaf: any): leaf is NodeLeaf { + return (leaf as NodeLeaf).nodeHash !== undefined +} + +export function isLeaf(leaf: any): leaf is Leaf { + return isSignerLeaf(leaf) || isSubdigestLeaf(leaf) || isNestedLeaf(leaf) || isNodeLeaf(leaf) +} + +// +// Tree typings - nodes +// + +export type Node = { + left: Node | Leaf + right: Node | Leaf +} + +export type Topology = Node | Leaf + +export function isNode(node: any): node is Node { + return (node as Node).left !== undefined && (node as Node).right !== undefined +} + +export function isTopology(topology: any): topology is Topology { + return isNode(topology) || isLeaf(topology) +} + +export function encodeSignerLeaf(leaf: SignerLeaf): string { + return ethers.utils.solidityPack(['uint96', 'address'], [leaf.weight, leaf.address]) +} + +export function decodeSignerLeaf(encoded: string): SignerLeaf { + const bytes = ethers.utils.arrayify(encoded) + + if (bytes.length !== 32) { + throw new Error('Invalid encoded string length') + } + + const weight = ethers.BigNumber.from(bytes.slice(0, 12)) + const address = ethers.utils.getAddress(ethers.utils.hexlify(bytes.slice(12))) + + return { weight, address } +} + +export function isEncodedSignerLeaf(encoded: string): boolean { + const bytes = ethers.utils.arrayify(encoded) + + if (bytes.length !== 32) { + return false + } + + const prefix = bytes.slice(0, 11) + return prefix.every(byte => byte === 0) +} + +export function hashNode(node: Node | Leaf): string { + if (isSignerLeaf(node)) { + return encodeSignerLeaf(node) + } + + if (isSubdigestLeaf(node)) { + return ethers.utils.solidityKeccak256(['string', 'bytes32'], ['Sequence static digest:\n', node.subdigest]) + } + + if (isNestedLeaf(node)) { + const nested = hashNode(node.tree) + return ethers.utils.solidityKeccak256( + ['string', 'bytes32', 'uint256', 'uint256'], + ['Sequence nested config:\n', nested, node.threshold, node.weight] + ) + } + + if (isNodeLeaf(node)) { + return node.nodeHash + } + + return ethers.utils.solidityKeccak256(['bytes32', 'bytes32'], [hashNode(node.left), hashNode(node.right)]) +} + +export function leftFace(topology: Topology): Topology[] { + const stack: Topology[] = [] + + let prev = topology + while (!isLeaf(prev)) { + stack.unshift(prev.right) + prev = prev.left + } + + stack.unshift(prev) + + return stack +} + +// +// Wallet config types +// + +export type WalletConfig = commons.config.Config & { + threshold: ethers.BigNumberish + checkpoint: ethers.BigNumberish + tree: Topology +} + +export function isWalletConfig(config: any): config is WalletConfig { + return ( + (config as WalletConfig).threshold !== undefined && + (config as WalletConfig).checkpoint !== undefined && + (config as WalletConfig).tree !== undefined && + (config as WalletConfig).version !== undefined && + (config as WalletConfig).version === 2 + ) +} + +export function imageHash(config: WalletConfig): string { + return ethers.utils.solidityKeccak256( + ['bytes32', 'uint256'], + [ethers.utils.solidityKeccak256(['bytes32', 'uint256'], [hashNode(config.tree), config.threshold]), config.checkpoint] + ) +} + +// +// Simple wallet config types +// (used for building and reading merkle configs) +// +// dev: `members` is a flat representation of the tree +// it keeps relevant structure like 'nested trees' but +// it ignores the tree structure +// +// + +export type SimpleNestedMember = { + threshold: ethers.BigNumberish + weight: ethers.BigNumberish + members: SimpleConfigMember[] +} + +export type SimpleConfigMember = SubdigestLeaf | SignerLeaf | SimpleNestedMember + +export type SimpleWalletConfig = { + threshold: ethers.BigNumberish + checkpoint: ethers.BigNumberish + members: SimpleConfigMember[] +} + +export function isSimpleNestedMember(member: any): member is SimpleNestedMember { + return ( + (member as SimpleNestedMember).threshold !== undefined && + (member as SimpleNestedMember).weight !== undefined && + (member as SimpleNestedMember).members !== undefined + ) +} + +export function topologyToMembers(tree: Topology): SimpleConfigMember[] { + if (isSignerLeaf(tree) || isSubdigestLeaf(tree)) { + return [tree] + } + + if (isNestedLeaf(tree)) { + return [ + { + threshold: tree.threshold, + weight: tree.weight, + members: topologyToMembers(tree.tree) + } + ] + } + + if (isNodeLeaf(tree)) { + // we don't know the content of this node + // so we omit it + return [] + } + + return [...topologyToMembers(tree.left), ...topologyToMembers(tree.right)] +} + +export function hasUnknownNodes(tree: Topology): boolean { + if (isNodeLeaf(tree)) { + return true + } + + if (isNode(tree)) { + return hasUnknownNodes(tree.left) || hasUnknownNodes(tree.right) + } + + return false +} + +export function toSimpleWalletConfig(config: WalletConfig): SimpleWalletConfig { + return { + threshold: config.threshold, + checkpoint: config.checkpoint, + members: topologyToMembers(config.tree) + } +} + +export type TopologyBuilder = (members: SimpleConfigMember[]) => Topology + +const membersAsTopologies = (members: SimpleConfigMember[], builder: TopologyBuilder): Topology[] => { + return members.map(member => { + if (isSimpleNestedMember(member)) { + return { + tree: builder(member.members), + threshold: member.threshold, + weight: member.weight + } + } + + return member + }) +} + +export function legacyTopologyBuilder(members: SimpleConfigMember[]): Topology { + if (members.length === 0) { + throw new Error('Empty members array') + } + + const asTopologies = membersAsTopologies(members, legacyTopologyBuilder) + return asTopologies.reduce((acc, member) => { + return { + left: acc, + right: member + } + }) +} + +export function merkleTopologyBuilder(members: SimpleConfigMember[]): Topology { + if (members.length === 0) { + throw new Error('Empty members array') + } + + const leaves = membersAsTopologies(members, merkleTopologyBuilder) + for (let s = leaves.length; s > 1; s = s / 2) { + for (let i = 0; i < s / 2; i++) { + const j1 = i * 2 + const j2 = j1 + 1 + + if (j2 >= s) { + leaves[i] = leaves[j1] + } else { + leaves[i] = { + left: leaves[j1], + right: leaves[j2] + } + } + } + } + + return leaves[0] +} + +export function optimized2SignersTopologyBuilder(members: SimpleConfigMember[]): Topology { + if (members.length > 8) { + return merkleTopologyBuilder(members) + } + + return legacyTopologyBuilder(members) +} + +export function toWalletConfig( + simpleWalletConfig: SimpleWalletConfig, + builder: TopologyBuilder = optimized2SignersTopologyBuilder +): WalletConfig { + return { + version: 2, + threshold: simpleWalletConfig.threshold, + checkpoint: simpleWalletConfig.checkpoint, + tree: builder(simpleWalletConfig.members) + } +} + +export function hasSubdigest(tree: Topology, subdigest: string): boolean { + if (isSubdigestLeaf(tree)) { + return tree.subdigest === subdigest + } + + if (isNode(tree)) { + return hasSubdigest(tree.left, subdigest) || hasSubdigest(tree.right, subdigest) + } + + return false +} + +export function signersOf(tree: Topology): { address: string; weight: number }[] { + const stack: Topology[] = [tree] + const signers = new Set<{ address: string; weight: number }>() + + while (stack.length > 0) { + const node = stack.pop() + + if (isNestedLeaf(node)) { + stack.push(node.tree) + } else if (isNode(node)) { + stack.push(node.left) + stack.push(node.right) + } else if (isSignerLeaf(node)) { + signers.add({ address: node.address, weight: ethers.BigNumber.from(node.weight).toNumber() }) + } + } + + return Array.from(signers) +} + +export function isComplete(tree: Topology): boolean { + if (isNode(tree)) { + return isComplete(tree.left) && isComplete(tree.right) + } + + return !isNodeLeaf(tree) +} + +export const ConfigCoder: commons.config.ConfigCoder = { + isWalletConfig: (config: commons.config.Config): config is WalletConfig => { + return config.version === 2 && (config as WalletConfig).threshold !== undefined && (config as WalletConfig).tree !== undefined + }, + + imageHashOf: (config: WalletConfig): string => { + return imageHash(config) + }, + + hasSubdigest: (config: WalletConfig, subdigest: string): boolean => { + return hasSubdigest(config.tree, subdigest) + }, + + checkpointOf: (config: WalletConfig): ethers.BigNumber => { + return ethers.BigNumber.from(config.checkpoint) + }, + + signersOf: (config: WalletConfig): { address: string; weight: number }[] => { + return signersOf(config.tree) + }, + + fromSimple: (config: SimpleConfig): WalletConfig => { + return toWalletConfig({ + ...config, + members: [...config.signers, ...(config.subdigests ?? []).map(subdigest => ({ subdigest }))] + }) + }, + + isComplete: (config: WalletConfig): boolean => { + return isComplete(config.tree) + }, + + // isValid = (config: WalletConfig): boolean {} + /** + * + * Notice: context and kind are ignored because v2 + * doesn't need to manually update the implementation before + * a configuration update, it's automatically done by the contract. + * + */ + update: { + isKindUsed: true, + + buildTransaction: ( + wallet: string, + config: WalletConfig, + _context: commons.context.WalletContext, + _kind?: 'first' | 'later' | undefined + ): commons.transaction.TransactionBundle => { + const module = new ethers.utils.Interface(walletContracts.mainModuleUpgradable.abi) + + return { + entrypoint: wallet, + transactions: [ + { + to: wallet, + data: module.encodeFunctionData(module.getFunction('updateImageHash'), [ConfigCoder.imageHashOf(config)]), + gasLimit: 0, + delegateCall: false, + revertOnError: true, + value: 0 + } + ] + } + }, + decodeTransaction: function (tx: commons.transaction.TransactionBundle): { + address: string + newImageHash: string + kind: 'first' | 'later' | undefined + } { + const module = new ethers.utils.Interface(walletContracts.mainModuleUpgradable.abi) + + if (tx.transactions.length !== 1) { + throw new Error('Invalid transaction bundle, expected 1 transaction') + } + + const data = tx.transactions[0].data + if (!data) { + throw new Error('Invalid transaction bundle, expected data') + } + + const decoded = module.decodeFunctionData(module.getFunction('updateImageHash'), data) + if (!decoded) { + throw new Error('Invalid transaction bundle, expected valid data') + } + + if (tx.transactions[0].to !== tx.entrypoint) { + throw new Error('Invalid transaction bundle, expected to be sent to entrypoint') + } + + if (tx.transactions[0].delegateCall) { + throw new Error('Invalid transaction bundle, expected not to be a delegateCall') + } + + if (!tx.transactions[0].revertOnError) { + throw new Error('Invalid transaction bundle, expected revertOnError') + } + + if (!ethers.constants.Zero.eq(tx.transactions[0]?.value ?? 0)) { + throw new Error('Invalid transaction bundle, expected value to be 0') + } + + if (!ethers.constants.Zero.eq(tx.transactions[0]?.gasLimit ?? 0)) { + throw new Error('Invalid transaction bundle, expected value to be 0') + } + + return { + address: tx.entrypoint, + newImageHash: decoded[0], + kind: undefined + } + } + }, + + toJSON: function (config: WalletConfig): string { + return JSON.stringify({ + version: config.version, + threshold: ethers.BigNumber.from(config.threshold).toString(), + checkpoint: ethers.BigNumber.from(config.checkpoint).toString(), + tree: topologyToJSON(config.tree) + }) + }, + + fromJSON: function (json: string): WalletConfig { + const config = JSON.parse(json) + return { + version: config.version, + threshold: ethers.BigNumber.from(config.threshold), + checkpoint: ethers.BigNumber.from(config.checkpoint), + tree: topologyFromJSON(config.tree) + } + }, + + editConfig: function ( + config: WalletConfig, + action: { + add?: commons.config.SimpleSigner[] + remove?: string[] + threshold?: ethers.BigNumberish + checkpoint?: ethers.BigNumberish + } + ): WalletConfig { + const members = topologyToMembers(config.tree) + + if (action.add) { + for (const signer of action.add) { + if (members.find(s => isSignerLeaf(s) && s.address === signer.address)) { + continue + } + + members.push({ + address: signer.address, + weight: signer.weight + }) + } + } + + if (action.remove) { + for (const address of action.remove) { + const index = members.findIndex(s => isSignerLeaf(s) && s.address === address) + if (index >= 0) { + members.splice(index, 1) + } + } + } + + return { + version: config.version, + threshold: action.threshold ?? config.threshold, + checkpoint: action.checkpoint ?? config.checkpoint, + tree: optimized2SignersTopologyBuilder(members) + } + }, + + buildStubSignature: function (config: WalletConfig, overrides: Map) { + const parts = new Map() + + for (const [signer, signature] of overrides.entries()) { + parts.set(signer, { signature, isDynamic: true }) + + const { encoded, weight } = encodeSigners(config, parts, [], 0) + + if (weight.gte(config.threshold)) { + return encoded + } + } + + const signers = signersOf(config.tree) + + for (const { address } of signers.sort(({ weight: a }, { weight: b }) => a - b)) { + const signature = + '0x4e82f02f388a12b5f9d29eaf2452dd040c0ee5804b4e504b4dd64e396c6c781f2c7624195acba242dd825bfd25a290912e3c230841fd55c9a734c4de8d9899451b02' + parts.set(address, { signature, isDynamic: false }) + + const { encoded, weight } = encodeSigners(config, parts, [], 0) + + if (weight.gte(config.threshold)) { + return encoded + } + } + + return encodeSigners(config, parts, [], 0).encoded + } +} diff --git a/packages/core/src/v2/context.ts b/packages/core/src/v2/context.ts new file mode 100644 index 0000000000..6092201d1b --- /dev/null +++ b/packages/core/src/v2/context.ts @@ -0,0 +1,5 @@ +import { WalletContext as BaseContext } from '../commons/context' + +export type WalletContext = BaseContext & { + version: 2 +} diff --git a/packages/core/src/v2/index.ts b/packages/core/src/v2/index.ts new file mode 100644 index 0000000000..f921265a42 --- /dev/null +++ b/packages/core/src/v2/index.ts @@ -0,0 +1,25 @@ +import { WalletContext } from '../commons/context' + +export * as config from './config' +export * as signature from './signature' +export * as context from './context' +export * as chained from './chained' + +import { ConfigCoder } from './config' +import { SignatureCoder } from './signature' + +export const coders = { + config: ConfigCoder, + signature: SignatureCoder +} + +export const version = 2 + +export const DeployedWalletContext: WalletContext = { + version: version, + factory: '0xFaA5c0b14d1bED5C888Ca655B9a8A5911F78eF4A', + guestModule: '0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE', + mainModule: '0xfBf8f1A5E00034762D928f46d438B947f5d4065d', + mainModuleUpgradable: '0x4222dcA3974E39A8b41c411FeDDE9b09Ae14b911', + walletCreationCode: '0x603a600e3d39601a805130553df3363d3d373d3d3d363d30545af43d82803e903d91601857fd5bf3' +} diff --git a/packages/core/src/v2/signature.ts b/packages/core/src/v2/signature.ts new file mode 100644 index 0000000000..2fa5415e5c --- /dev/null +++ b/packages/core/src/v2/signature.ts @@ -0,0 +1,977 @@ +import { BigNumberish, ethers } from 'ethers' +import { isValidSignature, recoverSigner, tryRecoverSigner } from '../commons/signer' +import { + hashNode, + isNestedLeaf, + isNode, + isNodeLeaf, + isSignerLeaf, + isSubdigestLeaf, + Leaf, + WalletConfig, + SignerLeaf, + Topology, + imageHash, + NodeLeaf, + decodeSignerLeaf, + isEncodedSignerLeaf +} from './config' +import * as base from '../commons/signature' +import { hashSetImageHash } from './chained' + +export enum SignatureType { + Legacy = 0, + Dynamic = 1, + NoChainIdDynamic = 2, + Chained = 3 +} + +export enum SignaturePartType { + Signature = 0, + Address = 1, + DynamicSignature = 2, + Node = 3, + Branch = 4, + Subdigest = 5, + Nested = 6 +} + +export const SignaturePartTypeLength = 66 + +export type SignatureLeaf = SignerLeaf & { + signature: string + isDynamic: boolean +} + +export type UnrecoveredSignatureLeaf = Omit & + Pick, 'address'> & { + unrecovered: true + } + +export type UnrecoveredNestedLeaf = { + tree: UnrecoveredTopology + weight: BigNumberish + threshold: BigNumberish +} + +export type UnrecoveredLeaf = UnrecoveredNestedLeaf | UnrecoveredSignatureLeaf | Leaf + +export type UnrecoveredNode = { + left: UnrecoveredNode | UnrecoveredLeaf + right: UnrecoveredNode | UnrecoveredLeaf +} + +export type UnrecoveredTopology = UnrecoveredNode | UnrecoveredLeaf + +export function isUnrecoveredNode(node: UnrecoveredTopology): node is UnrecoveredNode { + return (node as UnrecoveredNode).left !== undefined && (node as UnrecoveredNode).right !== undefined +} + +export function isUnrecoveredNestedLeaf(leaf: UnrecoveredTopology): leaf is UnrecoveredNestedLeaf { + return (leaf as UnrecoveredNestedLeaf).tree !== undefined +} + +export function isUnrecoveredSignatureLeaf(leaf: UnrecoveredTopology): leaf is UnrecoveredSignatureLeaf { + return ( + (leaf as UnrecoveredSignatureLeaf).unrecovered && + (leaf as UnrecoveredSignatureLeaf).signature !== undefined && + (leaf as UnrecoveredSignatureLeaf).isDynamic !== undefined + ) +} + +export function decodeSignatureTree(body: ethers.BytesLike): UnrecoveredTopology { + let arr = ethers.utils.arrayify(body) + + let pointer: undefined | (Omit & Pick, 'right'>) + + const append = (prevPointer: typeof pointer, node: UnrecoveredNode | UnrecoveredLeaf): typeof pointer => { + if (!prevPointer) { + return { + left: node + } + } + + if (!prevPointer.right) { + return { + left: prevPointer.left, + right: node + } + } + + return { + left: prevPointer as Required, + right: node + } + } + + while (arr.length > 0) { + const type = arr[0] as SignaturePartType + arr = arr.slice(1) + + switch (type) { + case SignaturePartType.Signature: + { + const weight = arr[0] + const signature = ethers.utils.hexlify(arr.slice(1, SignaturePartTypeLength + 1)) + + pointer = append(pointer, { + signature, + weight, + unrecovered: true, + isDynamic: false + }) + arr = arr.slice(SignaturePartTypeLength + 1) + } + break + + case SignaturePartType.Address: + { + const weight = arr[0] + const address = ethers.utils.getAddress(ethers.utils.hexlify(arr.slice(1, 21))) + + pointer = append(pointer, { + address, + weight + }) + arr = arr.slice(21) + } + break + + case SignaturePartType.DynamicSignature: + { + const weight = arr[0] + const address = ethers.utils.getAddress(ethers.utils.hexlify(arr.slice(1, 21))) + const size = (arr[21] << 16) | (arr[22] << 8) | arr[23] + const signature = ethers.utils.hexlify(arr.slice(24, 24 + size)) + + pointer = append(pointer, { + address, + signature, + weight, + unrecovered: true, + isDynamic: true + }) + arr = arr.slice(24 + size) + } + break + + case SignaturePartType.Node: + { + const nodeHash = ethers.utils.hexlify(arr.slice(0, 32)) + + pointer = append(pointer, { nodeHash }) + arr = arr.slice(32) + } + break + + case SignaturePartType.Branch: + { + const size = (arr[0] << 16) | (arr[1] << 8) | arr[2] + const branch = decodeSignatureTree(arr.slice(3, 3 + size)) + + pointer = append(pointer, branch) + arr = arr.slice(3 + size) + } + break + + case SignaturePartType.Subdigest: + { + const subdigest = ethers.utils.hexlify(arr.slice(0, 32)) + + pointer = append(pointer, { subdigest }) + arr = arr.slice(32) + } + break + + case SignaturePartType.Nested: + { + const weight = arr[0] + const threshold = (arr[1] << 8) | arr[2] + const size = (arr[3] << 16) | (arr[4] << 8) | arr[5] + + const tree = decodeSignatureTree(arr.slice(6, 6 + size)) + + pointer = append(pointer, { + weight, + threshold, + tree + }) + arr = arr.slice(6 + size) + } + break + + default: + throw new Error(`Unknown signature part type: ${type}: ${ethers.utils.hexlify(arr)}`) + } + } + + if (!pointer) { + throw new Error('Empty signature tree') + } + + if (pointer.right) { + return pointer as Required + } + + return pointer.left +} + +export class InvalidSignatureLeafError extends Error { + constructor(public leaf: UnrecoveredLeaf) { + super(`Invalid signature leaf: ${JSON.stringify(leaf)}`) + } +} + +export async function recoverTopology( + unrecovered: UnrecoveredTopology, + subdigest: string, + provider: ethers.providers.Provider +): Promise { + if (isUnrecoveredNode(unrecovered)) { + const [left, right] = await Promise.all([ + recoverTopology(unrecovered.left, subdigest, provider), + recoverTopology(unrecovered.right, subdigest, provider) + ]) + + return { left, right } + } + + if (isUnrecoveredNestedLeaf(unrecovered)) { + return { + weight: unrecovered.weight, + threshold: unrecovered.threshold, + tree: await recoverTopology(unrecovered.tree, subdigest, provider) + } + } + + if (isUnrecoveredSignatureLeaf(unrecovered)) { + if (unrecovered.isDynamic) { + if (!unrecovered.address) { + throw new Error('Dynamic signature leaf without address') + } + + const isValid = await isValidSignature(unrecovered.address, subdigest, unrecovered.signature, provider) + if (!isValid) { + throw new InvalidSignatureLeafError(unrecovered) + } + + return { + weight: unrecovered.weight, + address: unrecovered.address!, + signature: unrecovered.signature, + subdigest + } + } else { + return { + weight: unrecovered.weight, + address: recoverSigner(subdigest, unrecovered.signature), + signature: unrecovered.signature, + subdigest + } + } + } + + return unrecovered +} + +// TODO: It should be possible to re-use encodeSignatureTree +// and avoid duplicating this logic +export const partEncoder = { + concat: (a: ethers.BytesLike, b: ethers.BytesLike) => { + return ethers.utils.solidityPack(['bytes', 'bytes'], [a, b]) + }, + node: (nodeHash: ethers.BytesLike): string => { + return ethers.utils.solidityPack(['uint8', 'bytes32'], [SignaturePartType.Node, nodeHash]) + }, + branch: (tree: ethers.BytesLike): string => { + const arr = ethers.utils.arrayify(tree) + return ethers.utils.solidityPack(['uint8', 'uint24', 'bytes'], [SignaturePartType.Branch, arr.length, arr]) + }, + nested: (weight: ethers.BigNumberish, threshold: ethers.BigNumberish, tree: ethers.BytesLike): string => { + const arr = ethers.utils.arrayify(tree) + return ethers.utils.solidityPack( + ['uint8', 'uint8', 'uint16', 'uint24', 'bytes'], + [SignaturePartType.Nested, weight, threshold, arr.length, arr] + ) + }, + subdigest: (subdigest: ethers.BytesLike): string => { + return ethers.utils.solidityPack(['uint8', 'bytes32'], [SignaturePartType.Subdigest, subdigest]) + }, + signature: (weight: ethers.BigNumberish, signature: ethers.BytesLike): string => { + return ethers.utils.solidityPack(['uint8', 'uint8', 'bytes'], [SignaturePartType.Signature, weight, signature]) + }, + dynamicSignature: (weight: ethers.BigNumberish, address: ethers.BytesLike, signature: ethers.BytesLike): string => { + const arrSignature = ethers.utils.arrayify(signature) + return ethers.utils.solidityPack( + ['uint8', 'uint8', 'address', 'uint24', 'bytes'], + [SignaturePartType.DynamicSignature, weight, address, arrSignature.length, arrSignature] + ) + }, + address: (weight: ethers.BigNumberish, address: ethers.BytesLike): string => { + return ethers.utils.solidityPack(['uint8', 'uint8', 'address'], [SignaturePartType.Address, weight, address]) + } +} + +export type EncodingOptions = { + forceDynamicEncoding?: boolean + disableTrim?: boolean +} + +export function encodeSigners( + config: WalletConfig, + parts: Map, + subdigests: string[], + chainId: ethers.BigNumberish, + options: EncodingOptions = {} +): { + encoded: string + weight: ethers.BigNumber +} { + const tree = encodeTree(config.tree, parts, subdigests, options) + + if (ethers.BigNumber.from(chainId).isZero()) { + return { + encoded: ethers.utils.solidityPack( + ['uint8', 'uint16', 'uint32', 'bytes'], + [SignatureType.NoChainIdDynamic, config.threshold, config.checkpoint, tree.encoded] + ), + weight: tree.weight + } + } + + if (ethers.BigNumber.from(config.threshold).gt(255)) { + return { + encoded: ethers.utils.solidityPack( + ['uint8', 'uint16', 'uint32', 'bytes'], + [SignatureType.Dynamic, config.threshold, config.checkpoint, tree.encoded] + ), + weight: tree.weight + } + } + + return { + encoded: ethers.utils.solidityPack( + ['uint8', 'uint8', 'uint32', 'bytes'], + [SignatureType.Legacy, config.threshold, config.checkpoint, tree.encoded] + ), + weight: tree.weight + } +} + +export function encodeTree( + topology: Topology, + parts: Map, + subdigests: string[], + options: EncodingOptions = {} +): { + encoded: string + weight: ethers.BigNumber +} { + const trim = !options.disableTrim + + if (isNode(topology)) { + const left = encodeTree(topology.left, parts, subdigests) + const right = encodeTree(topology.right, parts, subdigests) + + const isLeftSigner = isSignerLeaf(topology.left) + const isRightSigner = isSignerLeaf(topology.right) + + if (trim && left.weight.eq(0) && right.weight.eq(0) && !isLeftSigner && !isRightSigner) { + return { + // We don't need to include anything for this node + // just the hash will be enough + encoded: partEncoder.node(hashNode(topology)), + weight: ethers.constants.Zero + } + } + + if (trim && right.weight.eq(0) && !isRightSigner) { + return { + // The right node doesn't have any weight + // but we still need to include the left node encoded + encoded: partEncoder.concat(left.encoded, partEncoder.node(hashNode(topology.right))), + weight: left.weight + } + } + + if (trim && left.weight.eq(0) && !isLeftSigner) { + return { + // The left node doesn't have any weight + // we can just append its hash, but for the right node + // we need to create a new "branch" + encoded: partEncoder.concat(partEncoder.node(hashNode(topology.left)), partEncoder.branch(right.encoded)), + weight: right.weight + } + } + + return { + // Both nodes have weight, we need to include both + // the right one must be a branch + encoded: partEncoder.concat(left.encoded, partEncoder.branch(right.encoded)), + weight: left.weight.add(right.weight) + } + } + + if (isNestedLeaf(topology)) { + const tree = encodeTree(topology.tree, parts, subdigests) + + if (trim && tree.weight.eq(0)) { + return { + encoded: partEncoder.node(hashNode(topology)), + weight: ethers.constants.Zero + } + } + + return { + encoded: partEncoder.nested(topology.weight, topology.threshold, tree.encoded), + weight: tree.weight + } + } + + if (isNodeLeaf(topology)) { + return { + encoded: partEncoder.node(hashNode(topology)), + weight: ethers.constants.Zero + } + } + + if (isSubdigestLeaf(topology)) { + const include = subdigests.includes(topology.subdigest) + return { + encoded: partEncoder.subdigest(topology.subdigest), + weight: include ? ethers.constants.MaxUint256 : ethers.constants.Zero + } + } + + if (isSignerLeaf(topology)) { + const include = parts.has(topology.address) + + if (include) { + const part = parts.get(topology.address)! + const signature = part.signature + + if (options.forceDynamicEncoding || part.isDynamic) { + return { + encoded: partEncoder.dynamicSignature(topology.weight, topology.address, signature), + weight: ethers.BigNumber.from(topology.weight) + } + } else { + return { + encoded: partEncoder.signature(topology.weight, signature), + weight: ethers.BigNumber.from(topology.weight) + } + } + } else { + return { + encoded: partEncoder.address(topology.weight, topology.address), + weight: ethers.constants.Zero + } + } + } + + throw new Error(`Invalid topology - unknown error: ${JSON.stringify(topology)}`) +} + +export type UnrecoveredConfig = { + tree: UnrecoveredTopology + threshold: ethers.BigNumberish + checkpoint: ethers.BigNumberish +} + +export type UnrecoveredSignature = base.UnrecoveredSignature & { + type: SignatureType + decoded: UnrecoveredConfig +} + +export type Signature = base.Signature & { + type: SignatureType +} + +export type UnrecoveredChainedSignature = UnrecoveredSignature & { + suffix: (UnrecoveredSignature | UnrecoveredChainedSignature)[] +} + +export type ChainedSignature = Signature & { + suffix: (Signature | ChainedSignature)[] +} + +export function deepestConfigOfSignature(signature: Signature | ChainedSignature): WalletConfig { + return isChainedSignature(signature) + ? deepestConfigOfSignature(signature.suffix[signature.suffix.length - 1]) + : signature.config +} + +export function isUnrecoveredSignature(sig: any): sig is UnrecoveredSignature { + return sig.type !== undefined && sig.decoded !== undefined && sig.version !== undefined && sig.version === 2 +} + +export function isUnrecoveredChainedSignature(sig: any): sig is UnrecoveredChainedSignature { + return sig.suffix !== undefined && Array.isArray(sig.suffix) && sig.suffix.every(isUnrecoveredSignature) +} + +export function isSignature(sig: any): sig is Signature { + return ( + sig.type !== undefined && + sig.config !== undefined && + sig.digest !== undefined && + sig.version !== undefined && + sig.version === 2 + ) +} + +export function isChainedSignature(sig: any): sig is ChainedSignature { + return sig.chain !== undefined && Array.isArray(sig.chain) && sig.chain.every(isSignature) +} + +export function decodeSignature(signature: ethers.BytesLike): UnrecoveredSignature | UnrecoveredChainedSignature { + const bytes = ethers.utils.arrayify(signature) + const type = bytes[0] + + switch (type) { + case SignatureType.Legacy: + return { version: 2, type: SignatureType.Legacy, decoded: decodeSignatureBody(bytes) } + + case SignatureType.Dynamic: + return { version: 2, type: SignatureType.Dynamic, decoded: decodeSignatureBody(bytes.slice(1)) } + + case SignatureType.NoChainIdDynamic: + return { version: 2, type: SignatureType.NoChainIdDynamic, decoded: decodeSignatureBody(bytes.slice(1)) } + + case SignatureType.Chained: + return decodeChainedSignature(bytes) + + default: + throw new Error(`Invalid signature type: ${type}`) + } +} + +export function decodeSignatureBody(signature: ethers.BytesLike): UnrecoveredConfig { + const bytes = ethers.utils.arrayify(signature) + + const threshold = (bytes[0] << 8) | bytes[1] + const checkpoint = (bytes[2] << 24) | (bytes[3] << 16) | (bytes[4] << 8) | bytes[5] + + const tree = decodeSignatureTree(bytes.slice(6)) + + return { threshold, checkpoint, tree } +} + +export function decodeChainedSignature(signature: ethers.BytesLike): UnrecoveredChainedSignature { + const arr = ethers.utils.arrayify(signature) + const type = arr[0] + + if (type !== SignatureType.Chained) { + throw new Error(`Expected chained signature type: ${type}`) + } + + const chain: (UnrecoveredSignature | UnrecoveredChainedSignature)[] = [] + let index = 1 + + while (index < arr.length) { + const size = (arr[index] << 16) | (arr[index + 1] << 8) | arr[index + 2] + index += 3 + + const sig = decodeSignature(arr.slice(index, index + size)) + chain.push(sig) + + index += size + } + + const main = chain[0] + if (isUnrecoveredChainedSignature(main)) { + throw new Error(`Expected first link of chained signature to be a simple signature (not chained)`) + } + + const suffix = chain.slice(1) + + return { ...main, suffix } +} + +export function setImageHashStruct(imageHash: string) { + return ethers.utils.solidityPack( + ['bytes32', 'bytes32'], + [ethers.utils.solidityKeccak256(['string'], ['SetImageHash(bytes32 imageHash)']), imageHash] + ) +} + +export async function recoverSignature( + signature: UnrecoveredSignature | UnrecoveredChainedSignature, + payload: base.SignedPayload | { subdigest: string }, + provider: ethers.providers.Provider +): Promise { + const signedPayload = (payload as { subdigest: string }).subdigest === undefined ? (payload as base.SignedPayload) : undefined + + const isNoChainId = signature.type === SignatureType.NoChainIdDynamic + if (isNoChainId && signedPayload) { + signedPayload.chainId = 0 + } + + const subdigest = signedPayload ? base.subdigestOf(signedPayload) : (payload as { subdigest: string }).subdigest + + if (!isUnrecoveredChainedSignature(signature)) { + const tree = await recoverTopology(signature.decoded.tree, subdigest, provider) + return { version: 2, type: signature.type, subdigest, config: { version: 2, ...signature.decoded, tree } } + } + + if (!base.isSignedPayload(signedPayload)) { + throw new Error(`Chained signature recovery requires detailed signed payload, subdigest is not enough`) + } + + const result: (Signature | ChainedSignature)[] = [] + let mutatedPayload = signedPayload + + // Recover the chain of signatures + // NOTICE: Remove the suffix from the "first" siganture + // otherwise we recurse infinitely + for (const sig of [{ ...signature, suffix: undefined }, ...signature.suffix]) { + const recovered = await recoverSignature(sig, mutatedPayload, provider) + result.unshift(recovered) + + const nextMessage = setImageHashStruct(imageHash(deepestConfigOfSignature(recovered))) + + mutatedPayload = { + ...mutatedPayload, + message: nextMessage, + digest: ethers.utils.keccak256(nextMessage) + } + } + + const main = result[0] + const suffix = result.slice(1) + + return { ...main, suffix } +} + +export function encodeChain(main: ethers.BytesLike, suffix: ethers.BytesLike[]): string { + const allSignatures = [main, ...(suffix || [])] + const encodedMap = allSignatures.map(s => ethers.utils.arrayify(encodeSignature(s))) + + const body = ethers.utils.solidityPack( + encodedMap.map(() => ['uint24', 'bytes']).flat(), + encodedMap.map(s => [s.length, s]).flat() + ) + + return ethers.utils.solidityPack(['uint8', 'bytes'], [SignatureType.Chained, body]) +} + +export function encodeSignature( + decoded: UnrecoveredChainedSignature | ChainedSignature | UnrecoveredSignature | Signature | ethers.BytesLike +): string { + if (ethers.utils.isBytesLike(decoded)) return ethers.utils.hexlify(decoded) + + if (isUnrecoveredChainedSignature(decoded) || isChainedSignature(decoded)) { + return encodeChain(encodeSignature(decoded), (decoded.suffix || []).map(encodeSignature)) + } + + const body = isUnrecoveredSignature(decoded) ? decoded.decoded : decoded.config + + switch (decoded.type) { + case SignatureType.Legacy: + if (ethers.BigNumber.from(body.threshold).gt(255)) { + throw new Error(`Legacy signature threshold is too large: ${body.threshold} (max 255)`) + } + + return encodeSignatureBody(body) + + case SignatureType.NoChainIdDynamic: + case SignatureType.Dynamic: + return ethers.utils.solidityPack(['uint8', 'bytes'], [decoded.type, encodeSignatureBody(body)]) + + case SignatureType.Chained: + throw new Error(`Unreachable code: Chained signature should be handled above`) + + default: + throw new Error(`Invalid signature type: ${decoded.type}`) + } +} + +export function encodeSignatureBody(decoded: WalletConfig | UnrecoveredConfig): string { + return ethers.utils.solidityPack( + ['uint16', 'uint32', 'bytes'], + [decoded.threshold, decoded.checkpoint, encodeSignatureTree(decoded.tree)] + ) +} + +export function encodeSignatureTree(tree: UnrecoveredTopology | Topology): string { + if (isNode(tree) || isUnrecoveredNode(tree)) { + const encodedRight = ethers.utils.arrayify(encodeSignatureTree(tree.right)) + const encodedLeft = ethers.utils.arrayify(encodeSignatureTree(tree.left)) + const isBranching = isNode(tree.right) || isUnrecoveredNode(tree.right) + + if (isBranching) { + return ethers.utils.solidityPack( + ['bytes', 'uint8', 'uint24', 'bytes'], + [encodedLeft, SignaturePartType.Branch, encodedRight.length, encodedRight] + ) + } else { + return ethers.utils.solidityPack(['bytes', 'bytes'], [encodedLeft, encodedRight]) + } + } + + if (isNestedLeaf(tree) || isUnrecoveredNestedLeaf(tree)) { + const nested = ethers.utils.arrayify(encodeSignatureTree(tree.tree)) + + return ethers.utils.solidityPack( + ['uint8', 'uint8', 'uint16', 'uint24', 'bytes'], + [SignaturePartType.Nested, tree.weight, tree.threshold, nested.length, nested] + ) + } + + if (isUnrecoveredSignatureLeaf(tree) || (isSignerLeaf(tree) && tree.signature !== undefined)) { + const signature = ethers.utils.arrayify(tree.signature!) + + if ((tree as { isDynamic?: boolean }).isDynamic || signature.length !== SignaturePartTypeLength) { + if (!tree.address) throw new Error(`Dynamic signature leaf must have address`) + return ethers.utils.solidityPack( + ['uint8', 'uint8', 'address', 'uint24', 'bytes'], + [SignaturePartType.DynamicSignature, tree.weight, tree.address, signature.length, signature] + ) + } else { + return ethers.utils.solidityPack(['uint8', 'uint8', 'bytes'], [SignaturePartType.Signature, tree.weight, signature]) + } + } + + if (isSignerLeaf(tree)) { + return ethers.utils.solidityPack(['uint8', 'uint8', 'address'], [SignaturePartType.Address, tree.weight, tree.address]) + } + + if (isNodeLeaf(tree)) { + return ethers.utils.solidityPack(['uint8', 'bytes32'], [SignaturePartType.Node, tree.nodeHash]) + } + + if (isSubdigestLeaf(tree)) { + return ethers.utils.solidityPack(['uint8', 'bytes32'], [SignaturePartType.Subdigest, tree.subdigest]) + } + + throw new Error(`Unknown signature tree type: ${tree}`) +} + +export function signaturesOf(topology: Topology): { address: string; signature: string }[] { + if (isNode(topology)) { + return [...signaturesOf(topology.left), ...signaturesOf(topology.right)] + } + + if (isNestedLeaf(topology)) { + return signaturesOf(topology.tree) + } + + if (isSignerLeaf(topology) && topology.signature) { + return [{ address: topology.address, signature: topology.signature }] + } + + return [] +} + +export function signaturesOfDecoded(utopology: UnrecoveredTopology): string[] { + if (isUnrecoveredNode(utopology)) { + return [...signaturesOfDecoded(utopology.left), ...signaturesOfDecoded(utopology.right)] + } + + if (isUnrecoveredNestedLeaf(utopology)) { + return signaturesOfDecoded(utopology.tree) + } + + if (isUnrecoveredSignatureLeaf(utopology)) { + return [utopology.signature] + } + + return [] +} + +export function subdigestsOfDecoded(utopology: UnrecoveredTopology): string[] { + if (isUnrecoveredNode(utopology)) { + return [...subdigestsOfDecoded(utopology.left), ...subdigestsOfDecoded(utopology.right)] + } + + if (isUnrecoveredNestedLeaf(utopology)) { + return subdigestsOfDecoded(utopology.tree) + } + + if (isSubdigestLeaf(utopology)) { + return [utopology.subdigest] + } + + return [] +} + +export async function trimSignature(signature: string | UnrecoveredSignature): Promise { + const decoded = typeof signature === 'string' ? decodeSignature(signature) : signature + + if (isUnrecoveredChainedSignature(decoded)) { + // We need to trim every suffix AND the main signature + const trimmed = await Promise.all([ + trimSignature({ ...decoded, suffix: undefined } as UnrecoveredSignature), + ...decoded.suffix.map(s => trimSignature(s)) + ]) + + return encodeChain(trimmed[0], trimmed.slice(1)) + } + + const { trimmed } = await trimUnrecoveredTree(decoded.decoded.tree) + return encodeSignature({ ...decoded, decoded: { ...decoded.decoded, tree: trimmed } }) +} + +export async function trimUnrecoveredTree( + tree: UnrecoveredTopology, + trimStaticDigest: boolean = true +): Promise<{ + weight: number + trimmed: UnrecoveredTopology +}> { + if (isUnrecoveredNode(tree)) { + const [left, right] = await Promise.all([trimUnrecoveredTree(tree.left), trimUnrecoveredTree(tree.right)]) + + if (left.weight === 0 && right.weight === 0) { + try { + // If both weights are 0 then it means we don't have any signatures yet + // because of that, we should be able to "recover" the tree with any subdigest + // and still get the valid node hash (there shouldn't be any signatures to verify) + const recovered = await recoverTopology(tree, ethers.constants.HashZero, undefined as any) + + return { + weight: 0, + trimmed: { + nodeHash: hashNode(recovered) + } as NodeLeaf + } + } catch { + // If something fails it's more likely because some signatures have sneaked in + // in that case we should keep this node + } + } else { + return { + weight: left.weight + right.weight, + trimmed: { + left: left.trimmed, + right: right.trimmed + } as UnrecoveredNode + } + } + } + + if (isUnrecoveredNestedLeaf(tree)) { + const trimmed = await trimUnrecoveredTree(tree.tree) + + if (trimmed.weight === 0) { + try { + // If the nested leaf is empty, we can recover it with any subdigest + // and still get the valid node hash (there shouldn't be any signatures to verify) + const recovered = await recoverTopology(tree, ethers.constants.HashZero, undefined as any) + + return { + weight: 0, + trimmed: { + nodeHash: hashNode(recovered) + } as NodeLeaf + } + } catch { + // If something fails it's more likely because some signatures have sneaked in + // in that case we should keep this node + } + } + + return { + weight: trimmed.weight, + trimmed: { + weight: tree.weight, + threshold: tree.threshold, + tree: trimmed.trimmed + } as UnrecoveredNestedLeaf + } + } + + // Hash nodes can be encoded as signer leaves if they have a weight below + // 256, most likely the are signer leaves wrongly encoded + if (isNodeLeaf(tree) && isEncodedSignerLeaf(tree.nodeHash)) { + return { + weight: 0, + trimmed: { + ...decodeSignerLeaf(tree.nodeHash) + } as SignerLeaf + } + } + + if (isUnrecoveredSignatureLeaf(tree) || (isSignerLeaf(tree) && tree.signature !== undefined)) { + return { + weight: ethers.BigNumber.from(tree.weight).toNumber(), + trimmed: tree + } + } + + if (!trimStaticDigest && isSubdigestLeaf(tree)) { + return { + weight: +Infinity, + trimmed: tree + } + } + + return { + weight: 0, + trimmed: tree + } +} + +export const SignatureCoder: base.SignatureCoder = { + decode: (data: string): UnrecoveredSignature => { + return decodeSignature(data) + }, + + encode: (data: Signature | UnrecoveredSignature): string => { + return encodeSignature(data) + }, + + trim: (data: string): Promise => { + return trimSignature(data) + }, + + supportsNoChainId: true, + + recover: ( + data: UnrecoveredSignature | UnrecoveredChainedSignature, + payload: base.SignedPayload, + provider: ethers.providers.Provider + ): Promise => { + return recoverSignature(data, payload, provider) + }, + + encodeSigners: ( + config: WalletConfig, + signatures: Map, + subdigests: string[], + chainId: ethers.BigNumberish + ): { + encoded: string + weight: ethers.BigNumber + } => { + return encodeSigners(config, signatures, subdigests, chainId) + }, + + hasEnoughSigningPower: (config: WalletConfig, signatures: Map): boolean => { + const { weight } = SignatureCoder.encodeSigners(config, signatures, [], 0) + return weight.gte(config.threshold) + }, + + chainSignatures: ( + main: Signature | UnrecoveredSignature | UnrecoveredChainedSignature | ethers.BytesLike, + suffix: (Signature | UnrecoveredSignature | UnrecoveredChainedSignature | ethers.BytesLike)[] + ): string => { + // Notice: v2 expects suffix to be reversed + // that being: from signed to current imageHash + const reversed = suffix.reverse() + const mraw = ethers.utils.isBytesLike(main) ? main : encodeSignature(main) + const sraw = reversed.map(s => (ethers.utils.isBytesLike(s) ? s : encodeSignature(s))) + return encodeChain(mraw, sraw) + }, + + hashSetImageHash: function (imageHash: string): string { + return hashSetImageHash(imageHash) + }, + + signaturesOf(config: WalletConfig): { address: string; signature: string }[] { + return signaturesOf(config.tree) + }, + + signaturesOfDecoded: function (data: UnrecoveredSignature): string[] { + return signaturesOfDecoded(data.decoded.tree) + } +} diff --git a/packages/core/src/version.ts b/packages/core/src/version.ts new file mode 100644 index 0000000000..bb4c7f26f5 --- /dev/null +++ b/packages/core/src/version.ts @@ -0,0 +1 @@ +export const VERSION = '2.0.0' diff --git a/packages/core/tests/v2/config.spec.ts b/packages/core/tests/v2/config.spec.ts new file mode 100644 index 0000000000..c9f88535c7 --- /dev/null +++ b/packages/core/tests/v2/config.spec.ts @@ -0,0 +1,512 @@ +import { expect } from 'chai' +import { config } from '../../src/v2' + +const sampleTree1: config.Topology = { + left: { + address: '0x07ab71Fe97F9122a2dBE3797aa441623f5a59DB1', + weight: 2 + }, + right: { + left: { + left: { + subdigest: '0xb374baf809e388014912ca7020c8ef51ad68591db3f010f9e35a77c15d4d6bed' + }, + right: { + subdigest: '0x787c83a19321fc70f8653f8faa39cce60bf26cac51c25df1b0634eb7ddbe0c60' + } + }, + right: { + address: '0xdafea492d9c6733ae3d56b7ed1adb60692c98bc5', + weight: 1 + } + } +} + +const sampleTree2: config.Topology = { + left: { + left: { + left: { + subdigest: '0x0000000000000000000000000000000000000000000000000000000000000000' + }, + right: { + subdigest: '0x0000000000000000000000000000000000000000000000000000000000000001' + } + }, + right: { + left: { + subdigest: '0x0000000000000000000000000000000000000000000000000000000000000002' + }, + right: { + subdigest: '0x0000000000000000000000000000000000000000000000000000000000000003' + } + } + }, + right: { + left: { + left: { + subdigest: '0x0000000000000000000000000000000000000000000000000000000000000004' + }, + right: { + subdigest: '0x0000000000000000000000000000000000000000000000000000000000000005' + } + }, + right: { + left: { + subdigest: '0x0000000000000000000000000000000000000000000000000000000000000006' + }, + right: { + subdigest: '0x0000000000000000000000000000000000000000000000000000000000000007' + } + } + } +} + +const sampleTree3: config.Topology = { + left: { + tree: { + left: { + address: '0x07ab71Fe97F9122a2dBE3797aa441623f5a59DB1', + weight: 2 + }, + right: { + left: { + subdigest: '0x0000000000000000000000000000000000000000000000000000000000000006' + }, + right: { + subdigest: '0x787c83a19321fc70f8653f8faa39cce60bf26cac51c25df10000000000000000' + } + } + }, + weight: 90, + threshold: 2 + }, + right: { + left: { + left: { + subdigest: '0xb374baf809e388014912ca7020c8ef51ad68591db3f010f9e35a77c15d4d6bed' + }, + right: { + subdigest: '0x787c83a19321fc70f8653f8faa39cce60bf26cac51c25df1b0634eb7ddbe0c60' + } + }, + right: { + address: '0xdafea492d9c6733ae3d56b7ed1adb60692c98bc5', + weight: 1 + } + } +} + +describe('v2 config utils', () => { + describe('Detect different leaves', () => { + it('Should detect signer leaf', () => { + const leaf: config.Leaf = { + address: '0x07ab71Fe97F9122a2dBE3797aa441623f5a59DB1', + weight: 2 + } + + expect(config.isLeaf(leaf)).to.be.true + expect(config.isSignerLeaf(leaf)).to.be.true + expect(config.isTopology(leaf)).to.be.true + expect(config.isNode(leaf)).to.be.false + expect(config.isSubdigestLeaf(leaf)).to.be.false + expect(config.isNestedLeaf(leaf)).to.be.false + }) + + it('Should detect subdigest leaf', () => { + const leaf: config.Leaf = { + subdigest: '0x787c83a19321fc70f8653f8faa39cce60bf26cac51c25df1b0634eb7ddbe0c60' + } + + expect(config.isLeaf(leaf)).to.be.true + expect(config.isSubdigestLeaf(leaf)).to.be.true + expect(config.isTopology(leaf)).to.be.true + expect(config.isNode(leaf)).to.be.false + expect(config.isSignerLeaf(leaf)).to.be.false + expect(config.isNestedLeaf(leaf)).to.be.false + }) + + it('Should detect nested leaf', () => { + const leaf: config.Leaf = { + tree: sampleTree1, + weight: 90, + threshold: 2 + } + + expect(config.isLeaf(leaf)).to.be.true + expect(config.isNestedLeaf(leaf)).to.be.true + expect(config.isTopology(leaf)).to.be.true + expect(config.isNode(leaf)).to.be.false + expect(config.isSignerLeaf(leaf)).to.be.false + expect(config.isSubdigestLeaf(leaf)).to.be.false + }) + + it('Should detect node', () => { + expect(config.isTopology(sampleTree1)).to.be.true + expect(config.isNode(sampleTree1)).to.be.true + expect(config.isLeaf(sampleTree1)).to.be.false + expect(config.isNestedLeaf(sampleTree1)).to.be.false + expect(config.isSignerLeaf(sampleTree1)).to.be.false + expect(config.isSubdigestLeaf(sampleTree1)).to.be.false + }) + }) + + describe('Hash leaves', () => { + it('Hash signer leaf', () => { + const hash = config.hashNode({ + address: '0x07ab71Fe97F9122a2dBE3797aa441623f5a59DB1', + weight: 129 + }) + + expect(hash).to.equal(`0x00000000000000000000008107ab71fe97f9122a2dbe3797aa441623f5a59db1`) + }) + + it('Hash subdigest', () => { + const hash = config.hashNode({ + subdigest: '0xb38b3da0ef56c3094675167fed4a263c3346b325dddb6e56a3eb9a10ed7539ed' + }) + + expect(hash).to.equal(`0x7cf15e50f6d44f71912ca6575b7fd911a5c6f19d0195692c7d35a102ad5ae98b`) + }) + + it('Hash nested leaf', () => { + const hash = config.hashNode({ + tree: sampleTree1, + weight: 90, + threshold: 211 + }) + + expect(hash).to.equal(`0x6cca65d12b31379a7b429e43443969524821e57d2c6a7fafae8e30bd31a5295b`) + }) + + it('Hash node', () => { + const tree = { + left: { + address: '0x07ab71Fe97F9122a2dBE3797aa441623f5a59DB1', + weight: 129 + }, + right: { + subdigest: '0x787c83a19321fc70f8653f8faa39cce60bf26cac51c25df1b0634eb7ddbe0c60' + } + } + + const hash = config.hashNode(tree) + expect(hash).to.equal(`0x47dcfac6c5622054a0ac762baa1a5eb10705484ea1e000869bbc11a093bec97e`) + }) + }) + + it('Read left face of tree', () => { + const leftFace1 = config.leftFace(sampleTree1) + expect(leftFace1.length).to.equal(2) + expect(leftFace1[0]).to.deep.equal(sampleTree1['left']) + expect(leftFace1[1]).to.deep.equal(sampleTree1['right']) + + const leftFace2 = config.leftFace(sampleTree2) + expect(leftFace2.length).to.equal(4) + expect(leftFace2[0]).to.deep.equal(sampleTree2['left']['left']['left']) + expect(leftFace2[1]).to.deep.equal(sampleTree2['left']['left']['right']) + expect(leftFace2[2]).to.deep.equal(sampleTree2['left']['right']) + expect(leftFace2[3]).to.deep.equal(sampleTree2['right']) + + const leftFace3 = config.leftFace(sampleTree3) + expect(leftFace3.length).to.equal(2) + expect(leftFace3[0]).to.deep.equal(sampleTree3['left']) + expect(leftFace3[1]).to.deep.equal(sampleTree3['right']) + }) + + describe('Simplify configurations', () => { + it('Should simplify configuration', () => { + const simplifiedConfig1 = config.toSimpleWalletConfig({ + version: 2, + tree: sampleTree1, + threshold: 11, + checkpoint: 999999 + }) + + expect(simplifiedConfig1).to.deep.equal({ + checkpoint: 999999, + threshold: 11, + members: [ + sampleTree1['left'], + sampleTree1['right']['left']['left'], + sampleTree1['right']['left']['right'], + sampleTree1['right']['right'] + ] + }) + + const simplifiedConfig2 = config.toSimpleWalletConfig({ + version: 2, + tree: sampleTree2, + threshold: 1, + checkpoint: 2 + }) + + expect(simplifiedConfig2).to.deep.equal({ + checkpoint: 2, + threshold: 1, + members: [ + sampleTree2['left']['left']['left'], + sampleTree2['left']['left']['right'], + sampleTree2['left']['right']['left'], + sampleTree2['left']['right']['right'], + sampleTree2['right']['left']['left'], + sampleTree2['right']['left']['right'], + sampleTree2['right']['right']['left'], + sampleTree2['right']['right']['right'] + ] + }) + + const simplifiedConfig3 = config.toSimpleWalletConfig({ + version: 2, + tree: sampleTree3, + threshold: 2, + checkpoint: 3 + }) + + expect(simplifiedConfig3).to.deep.equal({ + checkpoint: 3, + threshold: 2, + members: [ + { + threshold: sampleTree3['left']['threshold'], + weight: sampleTree3['left']['weight'], + members: [ + sampleTree3['left']['tree']['left'], + sampleTree3['left']['tree']['right']['left'], + sampleTree3['left']['tree']['right']['right'] + ] + }, + sampleTree3['right']['left']['left'], + sampleTree3['right']['left']['right'], + sampleTree3['right']['right'] + ] + }) + }) + }) + + describe('Build configurations', async () => { + it('Build legacy configuration', () => { + const legacyConfig1 = config.toWalletConfig( + { + members: [ + sampleTree1['left'], + sampleTree1['right']['left']['left'], + sampleTree1['right']['left']['right'], + sampleTree1['right']['right'] + ], + threshold: 11, + checkpoint: 999999 + }, + config.legacyTopologyBuilder + ) + + expect(legacyConfig1).to.deep.equal({ + version: 2, + checkpoint: 999999, + threshold: 11, + tree: { + left: { + left: { + left: sampleTree1['left'], + right: sampleTree1['right']['left']['left'] + }, + right: sampleTree1['right']['left']['right'] + }, + right: sampleTree1['right']['right'] + } + }) + + const legacyConfig2 = config.toWalletConfig({ + members: [ + sampleTree2['left']['left']['left'], + sampleTree2['left']['left']['right'], + sampleTree2['left']['right']['left'], + sampleTree2['left']['right']['right'], + sampleTree2['right']['left']['left'], + sampleTree2['right']['left']['right'], + sampleTree2['right']['right']['left'], + sampleTree2['right']['right']['right'] + ], + threshold: 1, + checkpoint: 2 + }) + + expect(legacyConfig2).to.deep.equal({ + version: 2, + checkpoint: 2, + threshold: 1, + tree: { + left: { + left: { + left: { + left: { + left: { + left: { + left: sampleTree2['left']['left']['left'], + right: sampleTree2['left']['left']['right'] + }, + right: sampleTree2['left']['right']['left'] + }, + right: sampleTree2['left']['right']['right'] + }, + right: sampleTree2['right']['left']['left'] + }, + right: sampleTree2['right']['left']['right'] + }, + right: sampleTree2['right']['right']['left'] + }, + right: sampleTree2['right']['right']['right'] + } + }) + + const legacyConfig3 = config.toWalletConfig({ + members: [ + { + threshold: sampleTree3['left']['threshold'], + weight: sampleTree3['left']['weight'], + members: [ + sampleTree3['left']['tree']['left'], + sampleTree3['left']['tree']['right']['left'], + sampleTree3['left']['tree']['right']['right'] + ] + }, + sampleTree3['right']['left']['left'], + sampleTree3['right']['left']['right'], + sampleTree3['right']['right'] + ], + threshold: 2, + checkpoint: 3 + }) + + expect(legacyConfig3).to.deep.equal({ + version: 2, + checkpoint: 3, + threshold: 2, + tree: { + left: { + left: { + left: { + weight: sampleTree3['left']['weight'], + threshold: sampleTree3['left']['threshold'], + tree: { + left: { + left: sampleTree3['left']['tree']['left'], + right: sampleTree3['left']['tree']['right']['left'] + }, + right: sampleTree3['left']['tree']['right']['right'] + } + }, + right: sampleTree3['right']['left']['left'] + }, + right: sampleTree3['right']['left']['right'] + }, + right: sampleTree3['right']['right'] + } + }) + }) + + it('Build merkle configuration', () => { + const merkleConfig1 = config.toWalletConfig( + { + members: [ + sampleTree1['left'], + sampleTree1['right']['left']['left'], + sampleTree1['right']['left']['right'], + sampleTree1['right']['right'] + ], + threshold: 11, + checkpoint: 999999 + }, + config.merkleTopologyBuilder + ) + + expect(merkleConfig1).to.deep.equal({ + version: 2, + checkpoint: 999999, + threshold: 11, + tree: { + left: { + left: sampleTree1['left'], + right: sampleTree1['right']['left']['left'] + }, + right: { + left: sampleTree1['right']['left']['right'], + right: sampleTree1['right']['right'] + } + } + }) + + const merkleConfig2 = config.toWalletConfig( + { + members: [ + sampleTree2['left']['left']['left'], + sampleTree2['left']['left']['right'], + sampleTree2['left']['right']['left'], + sampleTree2['left']['right']['right'], + sampleTree2['right']['left']['left'], + sampleTree2['right']['left']['right'], + sampleTree2['right']['right']['left'], + sampleTree2['right']['right']['right'] + ], + threshold: 1, + checkpoint: 2 + }, + config.merkleTopologyBuilder + ) + + expect(merkleConfig2).to.deep.equal({ + version: 2, + checkpoint: 2, + threshold: 1, + tree: sampleTree2 + }) + + const merkleConfig3 = config.toWalletConfig( + { + members: [ + { + threshold: sampleTree3['left']['threshold'], + weight: sampleTree3['left']['weight'], + members: [ + sampleTree3['left']['tree']['left'], + sampleTree3['left']['tree']['right']['left'], + sampleTree3['left']['tree']['right']['right'] + ] + }, + sampleTree3['right']['left']['left'], + sampleTree3['right']['left']['right'], + sampleTree3['right']['right'] + ], + threshold: 2, + checkpoint: 3 + }, + config.merkleTopologyBuilder + ) + + expect(merkleConfig3).to.deep.equal({ + version: 2, + checkpoint: 3, + threshold: 2, + tree: { + left: { + left: { + weight: sampleTree3['left']['weight'], + threshold: sampleTree3['left']['threshold'], + tree: { + left: { + left: sampleTree3['left']['tree']['left'], + right: sampleTree3['left']['tree']['right']['left'] + }, + right: sampleTree3['left']['tree']['right']['right'] + } + }, + right: sampleTree3['right']['left']['left'] + }, + right: { + left: sampleTree3['right']['left']['right'], + right: sampleTree3['right']['right'] + } + } + }) + }) + }) +}) diff --git a/packages/core/tests/v2/signature.spec.ts b/packages/core/tests/v2/signature.spec.ts new file mode 100644 index 0000000000..1c4ac2d52e --- /dev/null +++ b/packages/core/tests/v2/signature.spec.ts @@ -0,0 +1,603 @@ +import { expect } from 'chai' +import { ethers } from 'ethers' +import { decodeSignature, encodeSignature, SignaturePartType, SignatureType } from '../../src/v2/signature' + +const sampleSignature1 = + '0x0001636911b800019fa7b7e8ed25088c413074818ac10ab3bbcddb120bbec85083f3ba254e5547d953fe615a6474fd365326244dedd7afa3911ad39c956ca096d721064d6b29055d1b02' +const sampleSignature2 = + '0x000263691389034a062f86183c9d46e129f0331f2a42f6ba22a3525a46ecd197fa23d177d75f2d040000a0033fce59919d0a4ee44a8066a3b1d0083760d89a06ae89edadf8a58e0e5c5ac5040400007b01016ffeccf6f31e0a469d55dede5651d34a6ecd9fc500017052a0438a13da22242bcd20c219630d839c364cd2b6042add1bee32774c37d72ba2ace8b7a79c95a536d4c0fed3fe05883c6e1188a4191a91623a903e4ec21c1b0203ad5831467806b6edd059ff5ac9809f2bb6e80512ceb5d466a67251ffb842fae1040000c50314b729622595218cdbef06c630daeea028e25e8ca048d97bc170d75feb9066ad0400007f030c8c0bb7e8c5ec8eed444ae25f3a1796597bcfacf5f6b758ae4fadd6fc416f560400005a0001e7618f1b7b012d7fc48f518f498bb6823dc2a8308984287501873cb535b6d5bf526fb91a220297f461ac5a2434d0e8e768c3bf166c329366ddc885bf2e1676271c0201014ef7ec718f66ae3920ea119b9d7ddf39337601f703fdea4c5fb23fb3cc2b2360057abef1ff7e7195acbdc4db555c27cc588a4585a6' +const sampleSignature3 = + '0x0003636916740101a653f5900ef5c538142cd8aef1ce750390b29a3e0101a54e174d851bcffe8c1332c00e23156b4982204d0400002c0101ddfba5791de0b8da80d46b43915ae34c4876c4f80101f50834aa68dec4d9d151b1ff1c509c81431ddc450400008a0101e8e7c96af0d472a8d0e60e86009a97290fbc0f6d010188a175d23b41252823e7fd88297754f5c580c4ff0400005a0101653ca45307922091337376cb305485c0d889a7a10001d9b2a3142267255c50581c8023648916a3e8c3ae7ca50f6752b6874a20e76e496b30c4e1b653691b3ae9fea40a66966f3d1f2a35cedb52fbf07ae09269fb3c8e1b02040001180101a18522682c76e7e4083fcef379839347a533f782010159d7eb9085272adb317893df26e7f39dcfdda1ba0400002c0101c31ee68141cb47d2b260fe5a6e48b37d021d8f190101947ee7254d4de72f7a1b2e70ed3f8e8ae6510d77040000b8000147f646e6d13434b2df65fc1ab9086264bed1030e485e3513ed01686d03d127df510efc468bbeedde677c3af1fda7b0dbffc7186e07203eb09718cc256cf6b5d11b020101ce1977029e9398ec9f45327c81cf7a557f5d30b80400005a01010b6a69349728615d6e1c8d4fd133e49aafd5b91b0001aaac151a6ad4bf7f966db203164551a7c3c3969d15666dd2c75202231623f5ee2059711c84d2f216126bf3dc6cc63223eba079262e73c58da4f97583747c790b1c02' +const sampleSignature4 = + '0x00010000000203f6dc189f16bb65c588ccd5c63aa805bcbeb6e90dd8a049cfba0936050f299087060400020000c3037c989a96925302993812c1ec3924bce3ba2ca0e8f7e3655e30f5b24d965aa18b040000880001a73ce16a9cc7075c18bd2b4fd2649812fecb51460353a55bf62f821bf884443a169e0d0e04113d7ef2c2d15f1ecf46531f291259542065c556f0e721a82b3c581b02000193f1f388009f68763df43632153155960ea6604723bb517e90788822ff21e38722be4387e8f67c0db677b74d9a0c2a804183e6a3eebd2ba53dbfc54432f1a10f1b020101907c144d2490f49838c6499507ee5914f4a22b5b' +const sampleSignature5 = + '0x020001636a2c7d032b4c067647ee1f154214b4ad83bbbe7e57a528ca0df587e34ded382ca7348c100400006703c702696d354063d18d750cc686a1f356e503f85516c54375ef5878250a22758704000042054cd7065b01927d3429db64e0a7ec956fa5506dab23fa37c767eb4375fab7898b032acf6636e813600f741841733e57a7e0cb4131f3c68db7ba7014fb94525f5de20302c10a9634e89b4293346a7408364eeece764491bd465d043f7c826518c2bc9501011a9bd9f98e2c0c81bcf51da26c3a7cfcc18c43b4030c389524f715de03757bcbc7a084f52c5d54def431bb8080a18d0075e26b859c0101379b2a7a384376b420d3d19c5c5717abaad3a969' +const sampleSignature6 = + '0x010002636a33a501012093ec341be249baa0c8afa35fef368a90a483900201cd907cf455a1a00a4ebe37ef5f4bb7abc3770a6900004228230cc5c4ee221c093054fef22c12d534f4d63782bc94a160c2f781cef142e019b84d82070b67cb750ec9ba46ae49e6687591810099f6e58811fbe35ea3db451c0202014bffabff5819087514d8db622543c3d0d89cd64d000042844e002b27098ba6144bc9eb7950cd20a4062d265bdd042bffbb7ec8405caf7f60f1c5bdcd8ea4f4acee17d5ac9eac6bcdb40a20a41796d40a153278ab062b211c020101e8c4a6eb40ece266c7a58670493ee0727be4d20a' + +describe('v2 signature utils', () => { + describe('Decode signatures', () => { + it('Decode simple signature', () => { + const decoded = decodeSignature(sampleSignature1) + + expect(decoded).to.deep.equal({ + version: 2, + type: SignatureType.Legacy, + decoded: { + threshold: 1, + checkpoint: 1667830200, + tree: { + isDynamic: false, + signature: + '0x9fa7b7e8ed25088c413074818ac10ab3bbcddb120bbec85083f3ba254e5547d953fe615a6474fd365326244dedd7afa3911ad39c956ca096d721064d6b29055d1b02', + unrecovered: true, + weight: 1 + } + } + }) + }) + + it('Decode trimmed 2/N with 31 signers', () => { + /** + 0x9ce037be2c62dfec86f2cf5339f773b8fc22da992b9e33ee8ee050676a1fef48', + ā”œā”€ 0xcc049b7ee4891eb306511fb4019c104766fb97c73097a6ddd73858c1ba200292', + │ ā”œā”€ 0x4a062f86183c9d46e129f0331f2a42f6ba22a3525a46ecd197fa23d177d75f2d', + │ │ ā”œā”€ 0xe66f95b2257d7765d2af2a44f85bf9c9ecd220c686943595f4c7b87f42214b78', + │ │ │ ā”œā”€ 0xfccac93b8e71891c0647977a42447b037574deaa9d4cf7a6a6e6fd9275b75a5d', + │ │ │ │ ā”œā”€ weight: 1 - address: 0x39bc8F324dB1d2356E084b8c504F972f4A774fB2', + │ │ │ │ └─ weight: 1 - address: 0xb2C7368fA82d1Fd633f79FA9BcBE923cB1b84e4f', + │ │ │ └─ 0x85dab8bdc832396fb5f6f3dc3d86e589a6358edde9d5dfb567199ba81328f429', + │ │ │ ā”œā”€ weight: 1 - address: 0xAc9a3035638E36300DCd6e89cf7D3861bbb8dd1F', + │ │ │ └─ weight: 1 - address: 0x7Fb579CE8378EbcB953c6b1159cFF1d2DEEb6f74', + │ │ └─ 0xc0a464e50c14c3c9be84fcf19726f39298b1101b62da1ea093d058f574dc4075', + │ │ ā”œā”€ 0xa2ba648e377ddd25ccc5d55db2eaf2031d713ea63456cf60dbd88acb4fb9b826', + │ │ │ ā”œā”€ weight: 1 - address: 0x5dfc6cA7841DF26872BeF07C68fc18031908480c', + │ │ │ └─ weight: 1 - address: 0xA3B58D5778F59cF331693618f5E11b901029C3DE', + │ │ └─ 0x6ec7200199b3dad7a17e09b5a04df6518bc3eefecd59b6509f47bc478325384b', + │ │ ā”œā”€ weight: 1 - address: 0xAD4d6101f2fFda7C39D039d4c496B9005AaDBFaA', + │ │ └─ weight: 1 - address: 0x204De2Fa1FF302345CFd53bE37a5234c606783d8', + │ └─ 0x326e14238f8038db10e675efdf0c7648f8066c6a064738b73ec1db63a904c26c', + │ ā”œā”€ 0x3fce59919d0a4ee44a8066a3b1d0083760d89a06ae89edadf8a58e0e5c5ac504', + │ │ ā”œā”€ 0xa13a367336b680c598ffcc7738b9b18135000db5be559f35262b28e1701bb9a3', + │ │ │ ā”œā”€ weight: 1 - address: 0xD6BE598eD22A999f51BDCFD484454319CCe32b92', + │ │ │ └─ weight: 1 - address: 0x3347821222470CD136bAac735bf59A1734A80B83', + │ │ └─ 0x14b13f254e58655bf2d4dce5c7e3ec0566a4e025a70d1fc0d41a08e675c86358', + │ │ ā”œā”€ weight: 1 - address: 0x0aE2D84a35Eb1fD2B78dF00940A84c6a4954B4A6', + │ │ └─ weight: 1 - address: 0x598fD5791971eb873FA8147B1BdF3207068F7E56', + │ └─ 0xa507ba934d99995d74786ac057b7c2cd9e22ac9d4c3aee6739e0cc0d308065db', + │ ā”œā”€ 0x1df893b2ba851550922f4c3c6f60608f6c70fbe1f47670eaf9f5c3a6edbcd400', + │ │ ā”œā”€ weight: 1 - address: 0x6FFEcCF6F31e0a469D55DEdE5651D34A6ECd9FC5', + │ │ └─ weight: 1 - address: 0xE8D34A3999375ef56CD8eB41AC678f5332F7F223', + │ └─ 0xad5831467806b6edd059ff5ac9809f2bb6e80512ceb5d466a67251ffb842fae1', + │ ā”œā”€ weight: 1 - address: 0x103dD4E217C422839F3D4b1897C3b1100184d962', + │ └─ weight: 1 - address: 0x5adDAfA4498f9F54af54B8CD8a86728818Df911f', + └─ 0xb7a09a95298cc9bbeeb3c8fbe1f46d158976de898ca42470d0da75cea7be9b43', + ā”œā”€ 0x2ac4cc831b29dd447dc2d95a203a7b146ffbb8b9cf3fd0022d15bd0a490bc557', + │ ā”œā”€ 0x14b729622595218cdbef06c630daeea028e25e8ca048d97bc170d75feb9066ad', + │ │ ā”œā”€ 0xd08870ce28971831b6320b00d017b4351c75ca68432721c6e50145fc320bd900', + │ │ │ ā”œā”€ weight: 1 - address: 0x8881DFDBb650d55A440e7F40c3Fc890D327cE35C', + │ │ │ └─ weight: 1 - address: 0x133BC159421310c81E1045ba1e1f8fac34e2c5bB', + │ │ └─ 0x99a7e698bb471ec55f01f14f21a20d23b2f3c142fabe99b3294c526b50207a13', + │ │ ā”œā”€ weight: 1 - address: 0xCA9Ed033CB7E9D905942866cD2E593aEB2e05731', + │ │ └─ weight: 1 - address: 0x96613Fda8926dB718719c3c1CE9DaeeddbC520F1', + │ └─ 0xd508a67420b9138396432c9d6a89735a4f1bddf3800ce175fe54f5f80eea6fc7', + │ ā”œā”€ 0x0c8c0bb7e8c5ec8eed444ae25f3a1796597bcfacf5f6b758ae4fadd6fc416f56', + │ │ ā”œā”€ weight: 1 - address: 0x6d0fDa7520Bb48B6948f77214EE7411636853f30', + │ │ └─ weight: 1 - address: 0x1252c641DC898449490C7F145598b5A70c6738de', + │ └─ 0xc6eb96ebf4f10c3073d6b680efcb57d636b83fe5bc92912ae7c300d9e9cb232a', + │ ā”œā”€ weight: 1 - address: 0x3B69bC115e6D79E8adBD011020676750B169bEDd', + │ └─ weight: 1 - address: 0x4ef7Ec718f66ae3920ea119b9d7DDF39337601f7', + └─ 0xfdea4c5fb23fb3cc2b2360057abef1ff7e7195acbdc4db555c27cc588a4585a6', + ā”œā”€ 0x33b6f5aa2e0cc8d120a1ec31e74095d978b88fce7c34030579c1ea1ef372c4ad', + │ ā”œā”€ 0x5885c583c79ef1fe29477fcb82c7053518a99bedf73ebbf1948a160bdb8e2c0f', + │ │ ā”œā”€ weight: 1 - address: 0x89eD176B654F09024a8EFb0F9576D05f614E6f77', + │ │ └─ weight: 1 - address: 0xe8a3eb4CbEFF970eBd44e862f788C4CDB64009c1', + │ └─ 0x367a80d6704d73c6777aae2c7ed880a0536520df2d3a3f3a3a17d22925842833', + │ ā”œā”€ weight: 1 - address: 0x2C170AfE2D6c8489e4A272370DA494856E39BBDb', + │ └─ weight: 1 - address: 0x6c32dd456D1DD14d91739f777D37378D243AfF93', + └─ 0x6b8ac6478e09f9c92bed9532e1bdb2a2eefcfad542a6d5573bb16df0e50f7bdb', + ā”œā”€ 0x7206ea506e442d2a7ca309d52e4ebe6f0b8982261dbd45e87490bd86cfe77a2a', + │ ā”œā”€ weight: 1 - address: 0x72D0f36D4a0f18E22E7Ffd955C69C55D632d13Ae', + │ └─ weight: 1 - address: 0xfa79D7198d04b384735b8a24dE92014ECD59f777', + └─ weight: 1 - address: 0xFE3de6DF80c5890bAdBC24c1b4256A6c6E311933' + */ + + const decoded = decodeSignature(sampleSignature2) + + expect(decoded).to.deep.equal({ + version: 2, + type: SignatureType.Legacy, + decoded: { + threshold: 2, + checkpoint: 1667830665, + tree: { + left: { + left: { + nodeHash: '0x4a062f86183c9d46e129f0331f2a42f6ba22a3525a46ecd197fa23d177d75f2d' + }, + right: { + left: { + nodeHash: '0x3fce59919d0a4ee44a8066a3b1d0083760d89a06ae89edadf8a58e0e5c5ac504' + }, + right: { + left: { + left: { + address: '0x6FFEcCF6F31e0a469D55DEdE5651D34A6ECd9FC5', + weight: 1 + }, + right: { + // signature for: 0xE8D34A3999375ef56CD8eB41AC678f5332F7F223 + signature: + '0x7052a0438a13da22242bcd20c219630d839c364cd2b6042add1bee32774c37d72ba2ace8b7a79c95a536d4c0fed3fe05883c6e1188a4191a91623a903e4ec21c1b02', + weight: 1, + unrecovered: true, + isDynamic: false + } + }, + right: { + nodeHash: '0xad5831467806b6edd059ff5ac9809f2bb6e80512ceb5d466a67251ffb842fae1' + } + } + } + }, + right: { + left: { + left: { + nodeHash: '0x14b729622595218cdbef06c630daeea028e25e8ca048d97bc170d75feb9066ad' + }, + right: { + left: { + nodeHash: '0x0c8c0bb7e8c5ec8eed444ae25f3a1796597bcfacf5f6b758ae4fadd6fc416f56' + }, + right: { + left: { + // signature for: 0x3B69bC115e6D79E8adBD011020676750B169bEDd + signature: + '0xe7618f1b7b012d7fc48f518f498bb6823dc2a8308984287501873cb535b6d5bf526fb91a220297f461ac5a2434d0e8e768c3bf166c329366ddc885bf2e1676271c02', + weight: 1, + unrecovered: true, + isDynamic: false + }, + right: { + address: '0x4ef7Ec718f66ae3920ea119b9d7DDF39337601f7', + weight: 1 + } + } + } + }, + right: { + nodeHash: '0xfdea4c5fb23fb3cc2b2360057abef1ff7e7195acbdc4db555c27cc588a4585a6' + } + } + } + } + }) + }) + + it('Decode non-trimmed 3/N with 16 signers', () => { + /** + 0x0bd27b4a9a6a160ae92f5dc27a5d20156e81b049e451cc226db03be9454a9dbe', + ā”œā”€ 0xa9b9bb8f341ef4cba67d42b2c588d99f700a451f208d1d7ecb23d017ab23c3c5', + │ ā”œā”€ 0x24ac1effef0566192cd4ad878bc135c7d649b4989507f284fe5c66dae01117d3', + │ │ ā”œā”€ 0x67dff26d956ede906bbd0692a0cd573a78c7e345d54ccc93e2383337b4a46660', + │ │ │ ā”œā”€ weight: 1 - address: 0xA653F5900Ef5c538142Cd8Aef1CE750390B29a3E', + │ │ │ └─ weight: 1 - address: 0xA54e174d851bCFFE8C1332C00e23156B4982204D', + │ │ └─ 0x211bbe1253185da2e1f353cfb210c48378521ebfb3e103e18459e6aa9143848f', + │ │ ā”œā”€ weight: 1 - address: 0xDdfbA5791dE0b8Da80d46B43915Ae34C4876C4F8', + │ │ └─ weight: 1 - address: 0xF50834aa68DEc4D9D151b1ff1c509C81431DDC45', + │ └─ 0x0888e3e8bb7be34c21de30730e8f9cd91d03222bfea229eeabab03f3aa2183e0', + │ ā”œā”€ 0x360fe86d2a78344c383256a5509dac30c5046dd38cf6bfc54a880ac4f7e604ed', + │ │ ā”œā”€ weight: 1 - address: 0xe8e7C96aF0D472a8D0E60E86009a97290Fbc0F6d', + │ │ └─ weight: 1 - address: 0x88a175d23b41252823e7fD88297754f5C580c4Ff', + │ └─ 0x1235b94db1f48cebb5ebec7d345033d92801312f13086c1a79d032e703525bea', + │ ā”œā”€ weight: 1 - address: 0x653cA45307922091337376Cb305485c0D889A7A1', + │ └─ weight: 1 - address: 0xCf8BF768E2b69953577e1FF16b147c773faEc959', + └─ 0x86c8fbddf975589fecf3e2a5a543a916dedcf80aeb12f32abc26586110449059', + ā”œā”€ 0xcb4f6042dd1421bc59313c5a8e806514c2fbad361e706e6ec36a4dd6b815e03a', + │ ā”œā”€ 0x63fa3b020293428bfee299769b520e08641c66299922077cc91abd2ff31920f6', + │ │ ā”œā”€ weight: 1 - address: 0xa18522682c76e7e4083fCEF379839347a533f782', + │ │ └─ weight: 1 - address: 0x59d7eb9085272AdB317893Df26E7F39dCfdDa1bA', + │ └─ 0x4dc9c2311b9bfddc117ef646088b22d4a9548d9651a93c8246f7ad33acdf9431', + │ ā”œā”€ weight: 1 - address: 0xC31Ee68141cB47d2B260fE5A6e48b37d021D8F19', + │ └─ weight: 1 - address: 0x947EE7254D4dE72F7A1B2e70ed3f8E8aE6510D77', + └─ 0x7fe1e93c3a299dd8f6ebc06d4c94e5df6423b4ce919367f83f8c672e5e17cba8', + ā”œā”€ 0x8d0659c89c7f8de17801cf0178f4d32550b095187afac0d6b733797af881b41b', + │ ā”œā”€ weight: 1 - address: 0xb92E451800D78AA8f8492fFEA1a5afc77774f880', + │ └─ weight: 1 - address: 0xCE1977029e9398Ec9F45327c81cf7a557F5D30b8', + └─ 0xe4eaf15623516afc250692b6f8888be93638077ae5c78d95b01b7bf99b56cb67', + ā”œā”€ weight: 1 - address: 0x0b6a69349728615d6e1C8d4FD133e49AafD5b91b', + └─ weight: 1 - address: 0x8245B0c0C4319523c2D2616F86EBd02DaDA2FBD3' + */ + + const decoded = decodeSignature(sampleSignature3) + + expect(decoded).to.deep.equal({ + version: 2, + type: SignatureType.Legacy, + decoded: { + checkpoint: 1667831412, + threshold: 3, + tree: { + left: { + left: { + left: { + left: { + address: '0xA653F5900Ef5c538142Cd8Aef1CE750390B29a3E', + weight: 1 + }, + right: { + address: '0xA54e174d851bCFFE8C1332C00e23156B4982204D', + weight: 1 + } + }, + right: { + left: { + address: '0xDdfbA5791dE0b8Da80d46B43915Ae34C4876C4F8', + weight: 1 + }, + right: { + address: '0xF50834aa68DEc4D9D151b1ff1c509C81431DDC45', + weight: 1 + } + } + }, + right: { + left: { + left: { + address: '0xe8e7C96aF0D472a8D0E60E86009a97290Fbc0F6d', + weight: 1 + }, + right: { + address: '0x88a175d23b41252823e7fD88297754f5C580c4Ff', + weight: 1 + } + }, + right: { + left: { + address: '0x653cA45307922091337376Cb305485c0D889A7A1', + weight: 1 + }, + right: { + // address: '0xCf8BF768E2b69953577e1FF16b147c773faEc959', + signature: + '0xd9b2a3142267255c50581c8023648916a3e8c3ae7ca50f6752b6874a20e76e496b30c4e1b653691b3ae9fea40a66966f3d1f2a35cedb52fbf07ae09269fb3c8e1b02', + isDynamic: false, + unrecovered: true, + weight: 1 + } + } + } + }, + right: { + left: { + left: { + left: { + address: '0xa18522682c76e7e4083fCEF379839347a533f782', + weight: 1 + }, + right: { + address: '0x59d7eb9085272AdB317893Df26E7F39dCfdDa1bA', + weight: 1 + } + }, + right: { + left: { + address: '0xC31Ee68141cB47d2B260fE5A6e48b37d021D8F19', + weight: 1 + }, + right: { + address: '0x947EE7254D4dE72F7A1B2e70ed3f8E8aE6510D77', + weight: 1 + } + } + }, + right: { + left: { + left: { + // address: '0xb92E451800D78AA8f8492fFEA1a5afc77774f880', + signature: + '0x47f646e6d13434b2df65fc1ab9086264bed1030e485e3513ed01686d03d127df510efc468bbeedde677c3af1fda7b0dbffc7186e07203eb09718cc256cf6b5d11b02', + unrecovered: true, + isDynamic: false, + weight: 1 + }, + right: { + address: '0xCE1977029e9398Ec9F45327c81cf7a557F5D30b8', + weight: 1 + } + }, + right: { + left: { + address: '0x0b6a69349728615d6e1C8d4FD133e49AafD5b91b', + weight: 1 + }, + right: { + // address: '0x8245B0c0C4319523c2D2616F86EBd02DaDA2FBD3', + signature: + '0xaaac151a6ad4bf7f966db203164551a7c3c3969d15666dd2c75202231623f5ee2059711c84d2f216126bf3dc6cc63223eba079262e73c58da4f97583747c790b1c02', + unrecovered: true, + isDynamic: false, + weight: 1 + } + } + } + } + } + } + }) + }) + + it('Decode signature with nested trees', () => { + /** + 0xc62c3d8ab0422ccbab7339f13b987179c2583743b8af4728cd49b146c710c5c6', + ā”œā”€ 0xf6dc189f16bb65c588ccd5c63aa805bcbeb6e90dd8a049cfba0936050f299087', + │ ā”œā”€ 0x59276a9b2f7b735fd033d13fdfcf01391f6c112dc48418107c47faa292cda138', + │ │ ā”œā”€ 0x52b68b273da79cbad184ab5dc8e89825b373ab9af6ee97e0c556d3829126ba7c', + │ │ │ ā”œā”€ weight: 1 - address: 0xb159d82f98490c5Db1dB71b76bbb2C3a86DEce0C', + │ │ │ └─ weight: 1 - address: 0x29Fc57a0eb82688ad558A572C9E23e94243dB4d3', + │ │ └─ weight: 1 - address: 0x0B2b3abA8538639E6D9c1B1200942FA00148ABCB', + │ └─ weight: 1 - address: 0x3314715F5EE607A8988EC4c43351910CD6c76AE5', + └─ 0xd9b2fcc7c63fceaea59b7423cfda5e01307139ac078c2a1695fef1f9a4d9f50a', + └─ threshold: 2 - weight: 4', + ā”œā”€ 0x3c8cb8e47389edeee921bdb2efa8a8e664ef38790cfb4230ee51d5314e3a37d3', + │ ā”œā”€ 0x7c989a96925302993812c1ec3924bce3ba2ca0e8f7e3655e30f5b24d965aa18b', + │ │ ā”œā”€ weight: 1 - address: 0x711dD9c6D02010ABEfd5a4587298CB6a230d3877', + │ │ └─ weight: 1 - address: 0x05ead11721299d471d4e83b51ebfeB87F24A96c5', + │ └─ 0xfeac20f352af0c03f48d1eaeeacbde8e86b391bf97dd83665c218271da447be2', + │ ā”œā”€ weight: 1 - address: 0x4Faade320BBE1B9E31803A8A104305c3B5D5cC7E', + │ └─ weight: 1 - address: 0xE403b05AA84848604B40aFDbfE4977e9Be4ECCa9', + └─ weight: 1 - address: 0x907c144D2490f49838c6499507EE5914f4A22b5B' + */ + + const decoded = decodeSignature(sampleSignature4) + + expect(decoded).to.deep.equal({ + version: 2, + type: SignatureType.Legacy, + decoded: { + threshold: 1, + checkpoint: 2, + tree: { + left: { + nodeHash: '0xf6dc189f16bb65c588ccd5c63aa805bcbeb6e90dd8a049cfba0936050f299087' + }, + right: { + weight: 4, + threshold: 2, + tree: { + left: { + left: { + nodeHash: '0x7c989a96925302993812c1ec3924bce3ba2ca0e8f7e3655e30f5b24d965aa18b' + }, + right: { + left: { + signature: + '0xa73ce16a9cc7075c18bd2b4fd2649812fecb51460353a55bf62f821bf884443a169e0d0e04113d7ef2c2d15f1ecf46531f291259542065c556f0e721a82b3c581b02', + weight: 1, + unrecovered: true, + isDynamic: false + }, + right: { + signature: + '0x93f1f388009f68763df43632153155960ea6604723bb517e90788822ff21e38722be4387e8f67c0db677b74d9a0c2a804183e6a3eebd2ba53dbfc54432f1a10f1b02', + weight: 1, + unrecovered: true, + isDynamic: false + } + } + }, + right: { + address: '0x907c144D2490f49838c6499507EE5914f4A22b5B', + weight: 1 + } + } + } + } + } + }) + }) + + it('Decode static subdigests signature', () => { + /* + 0xd039f8f363eec6e6580c04fba1dfa1a7586827d884cb4d98ed667e131a01c268', + ā”œā”€ 0x73c9ee2e965c95b829c86ef4849dbf2f0410f4ac4380d2fc58f9246f9d84d0d0', + │ ā”œā”€ 0x73b96511a817fcf95200cd76af547a767c2faea2d52aa9e759f2a8ced75c7c67', + │ │ ā”œā”€ 0x9be568b9b969ab8d1012696c56ff89db394dcac9881bef5e361a4ffed446d6f6', + │ │ │ ā”œā”€ 0x1915fb45c54b103485bf50f1afb0fa6a70c1546211c48d15480ecc991765ba7f', + │ │ │ │ ā”œā”€ X 0x2b4c067647ee1f154214b4ad83bbbe7e57a528ca0df587e34ded382ca7348c10', + │ │ │ │ │ ā”œā”€ 0xd82efd7c2419e1ce6ec9de6f51051f6376773cd727c032cd15823755f19e4356', + │ │ │ │ │ │ ā”œā”€ subDigest: 0xd151a051d91288c5c5f4688ec5c6f0977f41535747293bcdc6859885e2e3c8f9', + │ │ │ │ │ │ └─ subDigest: 0x746fba99dcf684e2b9eb7dceace9d00b1988c5ad13fb46bb7c6272b8dac15821', + │ │ │ │ │ └─ 0xbff3206ad6a9cb35896c77f154b2aa4f72b709c9f4ec756d0da521163b3bcb61', + │ │ │ │ │ ā”œā”€ subDigest: 0xd5f94f3099a2c78c8687c81e7e29a2193a7003383989be621ab864efead521dc', + │ │ │ │ │ └─ subDigest: 0x6f5f1a3fb35d99dbf84a5f23713fd168231dddf6589a990378b83cf03f02d9f0', + │ │ │ │ └─ 0x798573e5ebb023632eafafce765fe8227f302a6db5e4c123a5a997c593471749', + │ │ │ │ ā”œā”€ X 0xc702696d354063d18d750cc686a1f356e503f85516c54375ef5878250a227587', + │ │ │ │ │ ā”œā”€ subDigest: 0xced8ceaa611754f0824a3066c4e53a1e78113dad5d8c63985b076eba2912bf09', + │ │ │ │ │ └─ subDigest: 0x00b43843c7c77215b123e3471be7532c64180d872e2dd68cd739bb7f1bcca725', + │ │ │ │ └─ 0x47344ce248ff726cf13c68d1e4bb7f2ab3a0b52d0668e240ed0925877ac62a88', + │ │ │ │ ā”œā”€ -> subDigest: 0x4cd7065b01927d3429db64e0a7ec956fa5506dab23fa37c767eb4375fab7898b', + │ │ │ │ └─ X (hashed) subDigest: 0xc0b21c4464a6acf6d8451d3a077bb3ebaa3953bd2e01609dec557af47239c012', + │ │ │ └─ X 0x02c10a9634e89b4293346a7408364eeece764491bd465d043f7c826518c2bc95', + │ │ │ ā”œā”€ subDigest: 0xae6b3762bab90dcc5eccbb3a8d1f5f8d9d974b2458403779ff998636c99ec15e', + │ │ │ └─ subDigest: 0x5c9de17d821a60f691929cd6d475d155a27e4d3ce0c79b4412a8e5e50c0e4f1e', + │ │ └─ X weight: 1 - address: 0x1A9bD9f98E2C0C81BcF51DA26c3a7CFcC18c43B4', + │ └─ X 0x0c389524f715de03757bcbc7a084f52c5d54def431bb8080a18d0075e26b859c', + │ ā”œā”€ weight: 1 - address: 0xEdAE5e1bF8D80e20C9008479A07400e84BC1af9D', + │ └─ weight: 1 - address: 0xBf31A9f466Fc2844CDE7F12c87dc3e6676c8D0b2', + └─ X weight: 1 - address: 0x379b2A7A384376B420D3D19c5c5717ABAaD3a969' + */ + const decoded = decodeSignature(sampleSignature5) + + expect(decoded).to.deep.equal({ + version: 2, + type: SignatureType.NoChainIdDynamic, + decoded: { + threshold: 1, + checkpoint: 1667902589, + tree: { + left: { + left: { + left: { + left: { + left: { + nodeHash: '0x2b4c067647ee1f154214b4ad83bbbe7e57a528ca0df587e34ded382ca7348c10' + }, + right: { + left: { + nodeHash: '0xc702696d354063d18d750cc686a1f356e503f85516c54375ef5878250a227587' + }, + right: { + left: { + subdigest: '0x4cd7065b01927d3429db64e0a7ec956fa5506dab23fa37c767eb4375fab7898b' + }, + right: { + nodeHash: '0x2acf6636e813600f741841733e57a7e0cb4131f3c68db7ba7014fb94525f5de2' + } + } + } + }, + right: { + nodeHash: '0x02c10a9634e89b4293346a7408364eeece764491bd465d043f7c826518c2bc95' + } + }, + right: { + address: '0x1A9bD9f98E2C0C81BcF51DA26c3a7CFcC18c43B4', + weight: 1 + } + }, + right: { + nodeHash: '0x0c389524f715de03757bcbc7a084f52c5d54def431bb8080a18d0075e26b859c' + } + }, + right: { + address: '0x379b2A7A384376B420D3D19c5c5717ABAaD3a969', + weight: 1 + } + } + } + }) + }) + + it('Decode dynamic signatures', () => { + /* + 0xe916ef5f1e4c38acd77f793ab9fe6696272541dce1fc84ffb712e2faccd4be07', + ā”œā”€ 0x8554edff027c3cb80d02e3e233a778c85165fbc2c813e8b4148339f8cda1cfd1', + │ ā”œā”€ 0xd871650a4a126ee8112934486f91f28f4da3e64474d66c778d1f2bd84b6f9ec7', + │ │ ā”œā”€ weight: 1 - address: 0x2093ec341be249BAA0c8aFA35fEF368a90a48390', + │ │ └─ weight: 1 - address: 0xCd907CF455A1A00a4ebE37Ef5F4BB7aBc3770A69', + │ └─ weight: 1 - address: 0x4bfFABff5819087514d8dB622543c3d0d89cD64D', + └─ weight: 1 - address: 0xe8C4a6EB40EcE266C7a58670493eE0727be4D20A' + */ + + const decoded = decodeSignature(sampleSignature6) + + expect(decoded).to.deep.equal({ + version: 2, + type: SignatureType.Dynamic, + decoded: { + threshold: 2, + checkpoint: 1667904421, + tree: { + left: { + left: { + left: { + address: '0x2093ec341be249BAA0c8aFA35fEF368a90a48390', + weight: 1 + }, + right: { + address: '0xCd907CF455A1A00a4ebE37Ef5F4BB7aBc3770A69', + signature: + '0x28230cc5c4ee221c093054fef22c12d534f4d63782bc94a160c2f781cef142e019b84d82070b67cb750ec9ba46ae49e6687591810099f6e58811fbe35ea3db451c02', + weight: 1, + isDynamic: true, + unrecovered: true + } + }, + right: { + address: '0x4bfFABff5819087514d8dB622543c3d0d89cD64D', + signature: + '0x844e002b27098ba6144bc9eb7950cd20a4062d265bdd042bffbb7ec8405caf7f60f1c5bdcd8ea4f4acee17d5ac9eac6bcdb40a20a41796d40a153278ab062b211c02', + weight: 1, + isDynamic: true, + unrecovered: true + } + }, + right: { + address: '0xe8C4a6EB40EcE266C7a58670493eE0727be4D20A', + weight: 1 + } + } + } + }) + }) + + it('Fail to decode invalid signature part type', () => { + const invalidSignature = ethers.utils.solidityPack( + ['bytes', 'uint8'], + ['0x0001ffffffff', Object.keys(SignaturePartType).length / 2] + ) + + expect(() => decodeSignature(invalidSignature)).to.throw( + `Unknown signature part type: ${Object.keys(SignaturePartType).length / 2}: 0x` + ) + }) + + it('Fail to decode empty tree signature', () => { + const invalidSignature = '0x0001ffffffff' + + expect(() => decodeSignature(invalidSignature)).to.throw('Empty signature tree') + }) + }) + + describe('Encode signatures', () => { + describe('Encode decoded signatures', () => { + it('Re-encode simple signature', () => { + const decoded = decodeSignature(sampleSignature1) + const reEncoded = encodeSignature(decoded) + expect(reEncoded).to.equal(sampleSignature1) + expect(decoded).to.deep.equal(decodeSignature(reEncoded)) + }) + + it('Re-encode trimmed 2/N with 31 signers', () => { + const decoded = decodeSignature(sampleSignature2) + const reEncoded = encodeSignature(decoded) + + expect(decoded).to.deep.equal(decodeSignature(reEncoded)) + expect(reEncoded).to.equal(sampleSignature2) + }) + + it('Re-encode non-trimmed 3/N with 16 signers', () => { + const decoded = decodeSignature(sampleSignature3) + const reEncoded = encodeSignature(decoded) + + expect(decoded).to.deep.equal(decodeSignature(reEncoded)) + expect(reEncoded).to.equal(sampleSignature3) + }) + + it('Re-encode signature with nested trees', () => { + const decoded = decodeSignature(sampleSignature4) + const reEncoded = encodeSignature(decoded) + + expect(decoded).to.deep.equal(decodeSignature(reEncoded)) + expect(reEncoded).to.equal(sampleSignature4) + }) + + it('Re-encode static subdigests signature', () => { + const decoded = decodeSignature(sampleSignature5) + const reEncoded = encodeSignature(decoded) + + expect(decoded).to.deep.equal(decodeSignature(reEncoded)) + expect(reEncoded).to.equal(sampleSignature5) + }) + + it('Re-encode dynamic signatures', () => { + const decoded = decodeSignature(sampleSignature6) + const reEncoded = encodeSignature(decoded) + + expect(decoded).to.deep.equal(decodeSignature(reEncoded)) + expect(reEncoded).to.equal(sampleSignature6) + }) + }) + }) +}) diff --git a/packages/deployer/.gitignore b/packages/deployer/.gitignore new file mode 100644 index 0000000000..b8e5877ec0 --- /dev/null +++ b/packages/deployer/.gitignore @@ -0,0 +1,4 @@ +config/PROD.env +cache +artifacts/build-info +artifacts/**/*.dbg.json diff --git a/packages/deployer/CHANGELOG.md b/packages/deployer/CHANGELOG.md new file mode 100644 index 0000000000..c1d715ed6c --- /dev/null +++ b/packages/deployer/CHANGELOG.md @@ -0,0 +1,2404 @@ +# @0xsequence/deployer + +## 2.0.0 + +### Major Changes + +- changeset + +### Patch Changes + +- Updated dependencies + - @0xsequence/utils@2.0.0 + +## 1.10.14 + +### Patch Changes + +- network: add borne-testnet to allNetworks +- Updated dependencies + - @0xsequence/utils@1.10.14 + +## 1.10.13 + +### Patch Changes + +- network: add borne testnet +- Updated dependencies + - @0xsequence/utils@1.10.13 + +## 1.10.12 + +### Patch Changes + +- api: update bindings +- global/window -> globalThis +- Updated dependencies +- Updated dependencies + - @0xsequence/utils@1.10.12 + +## 1.10.11 + +### Patch Changes + +- waas: updated intent.gen without webrpc types, errors exported from authenticator.gen +- Updated dependencies + - @0xsequence/utils@1.10.11 + +## 1.10.10 + +### Patch Changes + +- metadata: update bindings with new contract collections api +- Updated dependencies + - @0xsequence/utils@1.10.10 + +## 1.10.9 + +### Patch Changes + +- waas minor update +- Updated dependencies + - @0xsequence/utils@1.10.9 + +## 1.10.8 + +### Patch Changes + +- update metadata bindings +- Updated dependencies + - @0xsequence/utils@1.10.8 + +## 1.10.7 + +### Patch Changes + +- minor fixes to waas client +- Updated dependencies + - @0xsequence/utils@1.10.7 + +## 1.10.6 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/utils@1.10.6 + +## 1.10.5 + +### Patch Changes + +- network: ape-chain-testnet -> apechain-testnet +- Updated dependencies + - @0xsequence/utils@1.10.5 + +## 1.10.4 + +### Patch Changes + +- network: add b3-sepolia, ape-chain-testnet, blast, blast-sepolia +- Updated dependencies + - @0xsequence/utils@1.10.4 + +## 1.10.3 + +### Patch Changes + +- typing fix +- Updated dependencies + - @0xsequence/utils@1.10.3 + +## 1.10.2 + +### Patch Changes + +- - waas: add getIdToken method + - indexer: update api client +- Updated dependencies + - @0xsequence/utils@1.10.2 + +## 1.10.1 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/utils@1.10.1 + +## 1.10.0 + +### Minor Changes + +- waas release v1.3.0 + +### Patch Changes + +- Updated dependencies + - @0xsequence/utils@1.10.0 + +## 1.9.37 + +### Patch Changes + +- network: adds nativeToken data to NetworkMetadata constants +- Updated dependencies + - @0xsequence/utils@1.9.37 + +## 1.9.36 + +### Patch Changes + +- guard: export client +- Updated dependencies + - @0xsequence/utils@1.9.36 + +## 1.9.35 + +### Patch Changes + +- guard: update bindings +- Updated dependencies + - @0xsequence/utils@1.9.35 + +## 1.9.34 + +### Patch Changes + +- waas: always use lowercase email +- Updated dependencies + - @0xsequence/utils@1.9.34 + +## 1.9.33 + +### Patch Changes + +- waas: umd build +- Updated dependencies + - @0xsequence/utils@1.9.33 + +## 1.9.32 + +### Patch Changes + +- indexer: update bindings +- Updated dependencies + - @0xsequence/utils@1.9.32 + +## 1.9.31 + +### Patch Changes + +- metadata: token directory changes +- Updated dependencies + - @0xsequence/utils@1.9.31 + +## 1.9.30 + +### Patch Changes + +- update +- Updated dependencies + - @0xsequence/utils@1.9.30 + +## 1.9.29 + +### Patch Changes + +- disable gnosis chain +- Updated dependencies + - @0xsequence/utils@1.9.29 + +## 1.9.28 + +### Patch Changes + +- add utils/merkletree +- Updated dependencies + - @0xsequence/utils@1.9.28 + +## 1.9.27 + +### Patch Changes + +- network: optimistic -> optimism +- waas: remove defaults +- api, sessions: update bindings +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/utils@1.9.27 + +## 1.9.26 + +### Patch Changes + +- - add backend interfaces for pluggable interfaces + - introduce @0xsequence/react-native + - update pnpm to lockfile v9 +- Updated dependencies + - @0xsequence/utils@1.9.26 + +## 1.9.25 + +### Patch Changes + +- update webrpc clients with new error types +- Updated dependencies + - @0xsequence/utils@1.9.25 + +## 1.9.24 + +### Patch Changes + +- waas: add memoryStore backend to localStore +- Updated dependencies + - @0xsequence/utils@1.9.24 + +## 1.9.23 + +### Patch Changes + +- update api client bindings +- Updated dependencies + - @0xsequence/utils@1.9.23 + +## 1.9.22 + +### Patch Changes + +- update metadata client bindings +- Updated dependencies + - @0xsequence/utils@1.9.22 + +## 1.9.21 + +### Patch Changes + +- api client bindings +- Updated dependencies + - @0xsequence/utils@1.9.21 + +## 1.9.20 + +### Patch Changes + +- api client bindings update +- Updated dependencies + - @0xsequence/utils@1.9.20 + +## 1.9.19 + +### Patch Changes + +- waas update +- Updated dependencies + - @0xsequence/utils@1.9.19 + +## 1.9.18 + +### Patch Changes + +- provider: prohibit dangerous functions +- Updated dependencies + - @0xsequence/utils@1.9.18 + +## 1.9.17 + +### Patch Changes + +- network: add xr-sepolia +- Updated dependencies + - @0xsequence/utils@1.9.17 + +## 1.9.16 + +### Patch Changes + +- waas: sequence.feeOptions +- Updated dependencies + - @0xsequence/utils@1.9.16 + +## 1.9.15 + +### Patch Changes + +- metadata: collection external_link field name fix +- Updated dependencies + - @0xsequence/utils@1.9.15 + +## 1.9.14 + +### Patch Changes + +- network: astar-zkatana -> astar-zkyoto +- network: deprecate polygon mumbai network +- network: add xai and polygon amoy +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/utils@1.9.14 + +## 1.9.13 + +### Patch Changes + +- waas: fix @0xsequence/network dependency +- Updated dependencies + - @0xsequence/utils@1.9.13 + +## 1.9.12 + +### Patch Changes + +- indexer: update rpc bindings +- provider: signMessage: Serialize the BytesLike or string message into hexstring before sending +- waas: SessionAuthProof +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/utils@1.9.12 + +## 1.9.11 + +### Patch Changes + +- metdata, update rpc bindings +- Updated dependencies + - @0xsequence/utils@1.9.11 + +## 1.9.10 + +### Patch Changes + +- update metadata rpc bindings +- Updated dependencies + - @0xsequence/utils@1.9.10 + +## 1.9.9 + +### Patch Changes + +- metadata, add SequenceCollections rpc client +- Updated dependencies + - @0xsequence/utils@1.9.9 + +## 1.9.8 + +### Patch Changes + +- waas client update +- Updated dependencies + - @0xsequence/utils@1.9.8 + +## 1.9.7 + +### Patch Changes + +- update rpc client bindings for api, metadata and relayer +- Updated dependencies + - @0xsequence/utils@1.9.7 + +## 1.9.6 + +### Patch Changes + +- waas package update +- Updated dependencies + - @0xsequence/utils@1.9.6 + +## 1.9.5 + +### Patch Changes + +- RpcRelayer prioritize project access key +- Updated dependencies + - @0xsequence/utils@1.9.5 + +## 1.9.4 + +### Patch Changes + +- waas: fix network dependency +- Updated dependencies + - @0xsequence/utils@1.9.4 + +## 1.9.3 + +### Patch Changes + +- provider: don't append access key to RPC url if user has already provided it +- Updated dependencies + - @0xsequence/utils@1.9.3 + +## 1.9.2 + +### Patch Changes + +- network: add xai-sepolia +- Updated dependencies + - @0xsequence/utils@1.9.2 + +## 1.9.1 + +### Patch Changes + +- analytics fix +- Updated dependencies + - @0xsequence/utils@1.9.1 + +## 1.9.0 + +### Minor Changes + +- waas release + +### Patch Changes + +- Updated dependencies + - @0xsequence/utils@1.9.0 + +## 1.8.8 + +### Patch Changes + +- update metadata bindings +- Updated dependencies + - @0xsequence/utils@1.8.8 + +## 1.8.7 + +### Patch Changes + +- provider: update databeat to 0.9.1 +- Updated dependencies + - @0xsequence/utils@1.8.7 + +## 1.8.6 + +### Patch Changes + +- guard: SignedOwnershipProof +- Updated dependencies + - @0xsequence/utils@1.8.6 + +## 1.8.5 + +### Patch Changes + +- guard: signOwnershipProof and isSignedOwnershipProof +- Updated dependencies + - @0xsequence/utils@1.8.5 + +## 1.8.4 + +### Patch Changes + +- network: add homeverse to networks list +- Updated dependencies + - @0xsequence/utils@1.8.4 + +## 1.8.3 + +### Patch Changes + +- api: introduce basic linked wallet support +- Updated dependencies + - @0xsequence/utils@1.8.3 + +## 1.8.2 + +### Patch Changes + +- provider: don't initialize analytics unless explicitly requested +- Updated dependencies + - @0xsequence/utils@1.8.2 + +## 1.8.1 + +### Patch Changes + +- update to analytics provider +- Updated dependencies + - @0xsequence/utils@1.8.1 + +## 1.8.0 + +### Minor Changes + +- provider: project analytics + +### Patch Changes + +- Updated dependencies + - @0xsequence/utils@1.8.0 + +## 1.7.2 + +### Patch Changes + +- 0xsequence: ChainId should not be exported as a type +- account, wallet: fix nonce selection +- Updated dependencies +- Updated dependencies + - @0xsequence/utils@1.7.2 + +## 1.7.1 + +### Patch Changes + +- network: add missing avalanche logoURI +- Updated dependencies + - @0xsequence/utils@1.7.1 + +## 1.7.0 + +### Minor Changes + +- provider: projectAccessKey is now required + +### Patch Changes + +- network: add NetworkMetadata.logoURI property for all networks +- Updated dependencies +- Updated dependencies + - @0xsequence/utils@1.7.0 + +## 1.6.3 + +### Patch Changes + +- network list update +- Updated dependencies + - @0xsequence/utils@1.6.3 + +## 1.6.2 + +### Patch Changes + +- auth: projectAccessKey option +- wallet: use 12 bytes for random space +- Updated dependencies +- Updated dependencies + - @0xsequence/utils@1.6.2 + +## 1.6.1 + +### Patch Changes + +- core: add simple config from subdigest support +- core: fix encode tree with subdigest +- account: implement buildOnChainSignature on Account +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/utils@1.6.1 + +## 1.6.0 + +### Minor Changes + +- account, wallet: parallel transactions by default + +### Patch Changes + +- provider: emit disconnect on sign out +- Updated dependencies +- Updated dependencies + - @0xsequence/utils@1.6.0 + +## 1.5.0 + +### Minor Changes + +- signhub: add 'signing' signer status + +### Patch Changes + +- auth: Session.open: onAccountAddress callback +- account: allow empty transaction bundles +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/utils@1.5.0 + +## 1.4.9 + +### Patch Changes + +- rename SequenceMetadataClient to SequenceMetadata +- Updated dependencies + - @0xsequence/utils@1.4.9 + +## 1.4.8 + +### Patch Changes + +- account: Account.getSigners +- Updated dependencies + - @0xsequence/utils@1.4.8 + +## 1.4.7 + +### Patch Changes + +- update indexer client bindings +- Updated dependencies + - @0xsequence/utils@1.4.7 + +## 1.4.6 + +### Patch Changes + +- - add sepolia networks, mark goerli as deprecated + - update indexer client bindings +- Updated dependencies + - @0xsequence/utils@1.4.6 + +## 1.4.5 + +### Patch Changes + +- indexer/metadata: update client bindings +- auth: selectWallet with new address +- Updated dependencies +- Updated dependencies + - @0xsequence/utils@1.4.5 + +## 1.4.4 + +### Patch Changes + +- indexer: update bindings +- auth: handle jwt expiry +- Updated dependencies +- Updated dependencies + - @0xsequence/utils@1.4.4 + +## 1.4.3 + +### Patch Changes + +- guard: return active status from GuardSigner.getAuthMethods +- Updated dependencies + - @0xsequence/utils@1.4.3 + +## 1.4.2 + +### Patch Changes + +- guard: update bindings +- Updated dependencies + - @0xsequence/utils@1.4.2 + +## 1.4.1 + +### Patch Changes + +- network: remove unused networks +- signhub: orchestrator interface +- guard: auth methods interface +- guard: update bindings for pin and totp +- guard: no more retry logic +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/utils@1.4.1 + +## 1.4.0 + +### Minor Changes + +- project access key support + +### Patch Changes + +- Updated dependencies + - @0xsequence/utils@1.4.0 + +## 1.3.0 + +### Minor Changes + +- signhub: account children + +### Patch Changes + +- guard: do not throw when building deploy transaction +- network: snowtrace.io -> subnets.avax.network/c-chain +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/utils@1.3.0 + +## 1.2.9 + +### Patch Changes + +- account: AccountSigner.sendTransaction simulateForFeeOptions +- relayer: update bindings +- Updated dependencies +- Updated dependencies + - @0xsequence/utils@1.2.9 + +## 1.2.8 + +### Patch Changes + +- rename X-Sequence-Token-Key header to X-Access-Key +- Updated dependencies + - @0xsequence/utils@1.2.8 + +## 1.2.7 + +### Patch Changes + +- add x-sequence-token-key to clients +- Updated dependencies + - @0xsequence/utils@1.2.7 + +## 1.2.6 + +### Patch Changes + +- Fix bind multicall provider +- Updated dependencies + - @0xsequence/utils@1.2.6 + +## 1.2.5 + +### Patch Changes + +- Multicall default configuration fixes +- Updated dependencies + - @0xsequence/utils@1.2.5 + +## 1.2.4 + +### Patch Changes + +- provider: Adding missing payment provider types to PaymentProviderOption +- provider: WalletRequestHandler.notifyChainChanged +- Updated dependencies +- Updated dependencies + - @0xsequence/utils@1.2.4 + +## 1.2.3 + +### Patch Changes + +- auth, provider: connect to accept optional authorizeNonce +- Updated dependencies + - @0xsequence/utils@1.2.3 + +## 1.2.2 + +### Patch Changes + +- provider: allow createContract calls +- core: check for explicit zero address in contract deployments +- Updated dependencies +- Updated dependencies + - @0xsequence/utils@1.2.2 + +## 1.2.1 + +### Patch Changes + +- auth: use sequence api chain id as reference chain id if available +- Updated dependencies + - @0xsequence/utils@1.2.1 + +## 1.2.0 + +### Minor Changes + +- split services from session, better local support + +### Patch Changes + +- Updated dependencies + - @0xsequence/utils@1.2.0 + +## 1.1.15 + +### Patch Changes + +- guard: remove error filtering +- Updated dependencies + - @0xsequence/utils@1.1.15 + +## 1.1.14 + +### Patch Changes + +- guard: add GuardSigner.onError +- Updated dependencies + - @0xsequence/utils@1.1.14 + +## 1.1.13 + +### Patch Changes + +- provider: pass client version with connect options +- provider: removing large from BannerSize +- Updated dependencies +- Updated dependencies + - @0xsequence/utils@1.1.13 + +## 1.1.12 + +### Patch Changes + +- provider: adding bannerSize to ConnectOptions +- Updated dependencies + - @0xsequence/utils@1.1.12 + +## 1.1.11 + +### Patch Changes + +- add homeverse configs +- Updated dependencies + - @0xsequence/utils@1.1.11 + +## 1.1.10 + +### Patch Changes + +- handle default EIP6492 on send +- Updated dependencies + - @0xsequence/utils@1.1.10 + +## 1.1.9 + +### Patch Changes + +- Custom default EIP6492 on client +- Updated dependencies + - @0xsequence/utils@1.1.9 + +## 1.1.8 + +### Patch Changes + +- metadata: searchMetadata: add types filter +- Updated dependencies + - @0xsequence/utils@1.1.8 + +## 1.1.7 + +### Patch Changes + +- adding signInWith connect settings option to allow dapps to automatically login their users with a certain provider optimizing the normal authentication flow +- Updated dependencies + - @0xsequence/utils@1.1.7 + +## 1.1.6 + +### Patch Changes + +- metadata: searchMetadata: add chainID and excludeTokenMetadata filters +- Updated dependencies + - @0xsequence/utils@1.1.6 + +## 1.1.5 + +### Patch Changes + +- account: re-compute meta-transaction id for wallet deployment transactions +- Updated dependencies + - @0xsequence/utils@1.1.5 + +## 1.1.4 + +### Patch Changes + +- network: rename base-mainnet to base +- provider: override isDefaultChain with ConnectOptions.networkId if provided +- Updated dependencies +- Updated dependencies + - @0xsequence/utils@1.1.4 + +## 1.1.3 + +### Patch Changes + +- provider: use network id from transport session +- provider: sign authorization using ConnectOptions.networkId if provided +- Updated dependencies +- Updated dependencies + - @0xsequence/utils@1.1.3 + +## 1.1.2 + +### Patch Changes + +- provider: jsonrpc chain id fixes +- Updated dependencies + - @0xsequence/utils@1.1.2 + +## 1.1.1 + +### Patch Changes + +- network: add base mainnet and sepolia +- provider: reject toxic transaction requests +- Updated dependencies +- Updated dependencies + - @0xsequence/utils@1.1.1 + +## 1.1.0 + +### Minor Changes + +- Refactor dapp facing provider + +### Patch Changes + +- Updated dependencies + - @0xsequence/utils@1.1.0 + +## 1.0.5 + +### Patch Changes + +- network: export network constants +- guard: use the correct global for fetch +- network: nova-explorer.arbitrum.io -> nova.arbiscan.io +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/utils@1.0.5 + +## 1.0.4 + +### Patch Changes + +- provider: accept name or number for networkId +- Updated dependencies + - @0xsequence/utils@1.0.4 + +## 1.0.3 + +### Patch Changes + +- Simpler isValidSignature helpers +- Updated dependencies + - @0xsequence/utils@1.0.3 + +## 1.0.2 + +### Patch Changes + +- add extra signature validation utils methods +- Updated dependencies + - @0xsequence/utils@1.0.2 + +## 1.0.1 + +### Patch Changes + +- add homeverse testnet +- Updated dependencies + - @0xsequence/utils@1.0.1 + +## 1.0.0 + +### Major Changes + +- https://sequence.xyz/blog/sequence-wallet-light-state-sync-full-merkle-wallets + +### Patch Changes + +- Updated dependencies + - @0xsequence/utils@1.0.0 + +## 0.43.34 + +### Patch Changes + +- auth: no jwt for indexer +- Updated dependencies + - @0xsequence/utils@0.43.34 + +## 0.43.33 + +### Patch Changes + +- Adding onConnectOptionsChange handler to WalletRequestHandler +- Updated dependencies + - @0xsequence/utils@0.43.33 + +## 0.43.32 + +### Patch Changes + +- add Base Goerli network +- Updated dependencies + - @0xsequence/utils@0.43.32 + +## 0.43.31 + +### Patch Changes + +- remove AuxDataProvider, add promptSignInConnect +- Updated dependencies + - @0xsequence/utils@0.43.31 + +## 0.43.30 + +### Patch Changes + +- add arbitrum goerli testnet +- Updated dependencies + - @0xsequence/utils@0.43.30 + +## 0.43.29 + +### Patch Changes + +- provider: check availability of window object +- Updated dependencies + - @0xsequence/utils@0.43.29 + +## 0.43.28 + +### Patch Changes + +- update api bindings +- Updated dependencies + - @0xsequence/utils@0.43.28 + +## 0.43.27 + +### Patch Changes + +- Add rpc is sequence method +- Updated dependencies + - @0xsequence/utils@0.43.27 + +## 0.43.26 + +### Patch Changes + +- add zkevm url to enum +- Updated dependencies + - @0xsequence/utils@0.43.26 + +## 0.43.25 + +### Patch Changes + +- added polygon zkevm to mainnet networks +- Updated dependencies + - @0xsequence/utils@0.43.25 + +## 0.43.24 + +### Patch Changes + +- name change from zkevm to polygon-zkevm +- Updated dependencies + - @0xsequence/utils@0.43.24 + +## 0.43.23 + +### Patch Changes + +- update zkEVM name to Polygon zkEVM +- Updated dependencies + - @0xsequence/utils@0.43.23 + +## 0.43.22 + +### Patch Changes + +- add zkevm chain +- Updated dependencies + - @0xsequence/utils@0.43.22 + +## 0.43.21 + +### Patch Changes + +- api: update client bindings +- Updated dependencies + - @0xsequence/utils@0.43.21 + +## 0.43.20 + +### Patch Changes + +- indexer: update bindings +- Updated dependencies + - @0xsequence/utils@0.43.20 + +## 0.43.19 + +### Patch Changes + +- session proof update +- Updated dependencies + - @0xsequence/utils@0.43.19 + +## 0.43.18 + +### Patch Changes + +- rpc client global check, hardening +- Updated dependencies + - @0xsequence/utils@0.43.18 + +## 0.43.17 + +### Patch Changes + +- rpc clients, check of 'global' is defined +- Updated dependencies + - @0xsequence/utils@0.43.17 + +## 0.43.16 + +### Patch Changes + +- ethers peerDep to v5, update rpc client global use +- Updated dependencies + - @0xsequence/utils@0.43.16 + +## 0.43.15 + +### Patch Changes + +- - provider: expand receiver type on some util methods +- Updated dependencies + - @0xsequence/utils@0.43.15 + +## 0.43.14 + +### Patch Changes + +- bump +- Updated dependencies + - @0xsequence/utils@0.43.14 + +## 0.43.13 + +### Patch Changes + +- update rpc bindings +- Updated dependencies + - @0xsequence/utils@0.43.13 + +## 0.43.12 + +### Patch Changes + +- provider: single wallet init, and add new unregisterWallet() method +- Updated dependencies + - @0xsequence/utils@0.43.12 + +## 0.43.11 + +### Patch Changes + +- fix lockfiles +- re-add mocha type deleter +- Updated dependencies +- Updated dependencies + - @0xsequence/utils@0.43.11 + +## 0.43.10 + +### Patch Changes + +- various improvements +- Updated dependencies + - @0xsequence/utils@0.43.10 + +## 0.43.9 + +### Patch Changes + +- update deps +- Updated dependencies + - @0xsequence/utils@0.43.9 + +## 0.43.8 + +### Patch Changes + +- network: JsonRpcProvider with caching +- Updated dependencies + - @0xsequence/utils@0.43.8 + +## 0.43.7 + +### Patch Changes + +- provider: fix wallet network init +- Updated dependencies + - @0xsequence/utils@0.43.7 + +## 0.43.6 + +### Patch Changes + +- metadatata: update rpc bindings +- Updated dependencies + - @0xsequence/utils@0.43.6 + +## 0.43.5 + +### Patch Changes + +- provider: do not set default network for connect messages +- provider: forward missing error message +- Updated dependencies +- Updated dependencies + - @0xsequence/utils@0.43.5 + +## 0.43.4 + +### Patch Changes + +- no-change version bump to fix incorrectly tagged snapshot build +- Updated dependencies + - @0xsequence/utils@0.43.4 + +## 0.43.3 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/utils@0.43.3 + +## 0.43.2 + +### Patch Changes + +- provider: implement connectUnchecked +- Updated dependencies + - @0xsequence/utils@0.43.2 + +## 0.43.1 + +### Patch Changes + +- update to latest ethauth dep +- Updated dependencies + - @0xsequence/utils@0.43.1 + +## 0.43.0 + +### Minor Changes + +- move ethers to a peer dependency + +### Patch Changes + +- Updated dependencies + - @0xsequence/utils@0.43.0 + +## 0.42.10 + +### Patch Changes + +- add auxDataProvider +- Updated dependencies + - @0xsequence/utils@0.42.10 + +## 0.42.9 + +### Patch Changes + +- provider: add eip-191 exceptions +- Updated dependencies + - @0xsequence/utils@0.42.9 + +## 0.42.8 + +### Patch Changes + +- provider: skip setting intent origin if we're unity plugin +- Updated dependencies + - @0xsequence/utils@0.42.8 + +## 0.42.7 + +### Patch Changes + +- Add sign in options to connection settings +- Updated dependencies + - @0xsequence/utils@0.42.7 + +## 0.42.6 + +### Patch Changes + +- api bindings update +- Updated dependencies + - @0xsequence/utils@0.42.6 + +## 0.42.5 + +### Patch Changes + +- relayer: don't treat missing receipt as hard failure +- Updated dependencies + - @0xsequence/utils@0.42.5 + +## 0.42.4 + +### Patch Changes + +- provider: add custom app protocol to connect options +- Updated dependencies + - @0xsequence/utils@0.42.4 + +## 0.42.3 + +### Patch Changes + +- update api bindings +- Updated dependencies + - @0xsequence/utils@0.42.3 + +## 0.42.2 + +### Patch Changes + +- disable rinkeby network +- Updated dependencies + - @0xsequence/utils@0.42.2 + +## 0.42.1 + +### Patch Changes + +- wallet: optional waitForReceipt parameter +- Updated dependencies + - @0xsequence/utils@0.42.1 + +## 0.42.0 + +### Minor Changes + +- relayer: estimateGasLimits -> simulate +- add simulator package + +### Patch Changes + +- transactions: fix flattenAuxTransactions +- provider: only filter nullish values +- provider: re-map transaction 'gas' back to 'gasLimit' +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/utils@0.42.0 + +## 0.41.3 + +### Patch Changes + +- api bindings update +- Updated dependencies + - @0xsequence/utils@0.41.3 + +## 0.41.2 + +### Patch Changes + +- api bindings update +- Updated dependencies + - @0xsequence/utils@0.41.2 + +## 0.41.1 + +### Patch Changes + +- update default networks +- Updated dependencies + - @0xsequence/utils@0.41.1 + +## 0.41.0 + +### Minor Changes + +- relayer: fix Relayer.wait() interface + + The interface for calling Relayer.wait() has changed. Instead of a single optional ill-defined timeout/delay parameter, there are three optional parameters, in order: + + - timeout: the maximum time to wait for the transaction receipt + - delay: the polling interval, i.e. the time to wait between requests + - maxFails: the maximum number of hard failures to tolerate before giving up + + Please update your codebase accordingly. + +- relayer: add optional waitForReceipt parameter to Relayer.relay + + The behaviour of Relayer.relay() was not well-defined with respect to whether or not it waited for a receipt. + This change allows the caller to specify whether to wait or not, with the default behaviour being to wait. + +### Patch Changes + +- relayer: wait receipt retry logic +- fix wrapped object error +- provider: forward delegateCall and revertOnError transaction fields +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/utils@0.41.0 + +## 0.40.6 + +### Patch Changes + +- add arbitrum-nova chain +- Updated dependencies + - @0xsequence/utils@0.40.6 + +## 0.40.5 + +### Patch Changes + +- api: update bindings +- Updated dependencies + - @0xsequence/utils@0.40.5 + +## 0.40.4 + +### Patch Changes + +- add unreal transport +- Updated dependencies + - @0xsequence/utils@0.40.4 + +## 0.40.3 + +### Patch Changes + +- provider: fix MessageToSign message type +- Updated dependencies + - @0xsequence/utils@0.40.3 + +## 0.40.2 + +### Patch Changes + +- Wallet provider, loadSession method +- Updated dependencies + - @0xsequence/utils@0.40.2 + +## 0.40.1 + +### Patch Changes + +- export sequence.initWallet and sequence.getWallet +- Updated dependencies + - @0xsequence/utils@0.40.1 + +## 0.40.0 + +### Minor Changes + +- add sequence.initWallet(network, config) and sequence.getWallet() helper methods + +### Patch Changes + +- Updated dependencies + - @0xsequence/utils@0.40.0 + +## 0.39.6 + +### Patch Changes + +- indexer: update client bindings +- Updated dependencies + - @0xsequence/utils@0.39.6 + +## 0.39.5 + +### Patch Changes + +- provider: fix networkRpcUrl config option +- Updated dependencies + - @0xsequence/utils@0.39.5 + +## 0.39.4 + +### Patch Changes + +- api: update client bindings +- Updated dependencies + - @0xsequence/utils@0.39.4 + +## 0.39.3 + +### Patch Changes + +- add request method on Web3Provider +- Updated dependencies + - @0xsequence/utils@0.39.3 + +## 0.39.2 + +### Patch Changes + +- update umd name +- Updated dependencies + - @0xsequence/utils@0.39.2 + +## 0.39.1 + +### Patch Changes + +- add Aurora network +- add origin info for accountsChanged event to handle it per dapp +- Updated dependencies +- Updated dependencies + - @0xsequence/utils@0.39.1 + +## 0.39.0 + +### Minor Changes + +- abstract window.localStorage to interface type + +### Patch Changes + +- Updated dependencies + - @0xsequence/utils@0.39.0 + +## 0.38.2 + +### Patch Changes + +- provider: add Settings.defaultPurchaseAmount +- Updated dependencies + - @0xsequence/utils@0.38.2 + +## 0.38.1 + +### Patch Changes + +- update api and metadata rpc bindings +- Updated dependencies + - @0xsequence/utils@0.38.1 + +## 0.38.0 + +### Minor Changes + +- api: update bindings, change TokenPrice interface +- bridge: remove @0xsequence/bridge package +- api: update bindings, rename ContractCallArg to TupleComponent + +### Patch Changes + +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/utils@0.38.0 + +## 0.37.1 + +### Patch Changes + +- Add back sortNetworks - Removing sorting was a breaking change for dapps on older versions which directly integrate sequence. +- Updated dependencies + - @0xsequence/utils@0.37.1 + +## 0.37.0 + +### Minor Changes + +- network related fixes and improvements +- api: bindings: exchange rate lookups + +### Patch Changes + +- Updated dependencies +- Updated dependencies + - @0xsequence/utils@0.37.0 + +## 0.36.13 + +### Patch Changes + +- api: update bindings with new price endpoints +- Updated dependencies + - @0xsequence/utils@0.36.13 + +## 0.36.12 + +### Patch Changes + +- wallet: skip remote signers if not needed +- auth: check that signature meets threshold before requesting auth token +- Updated dependencies +- Updated dependencies + - @0xsequence/utils@0.36.12 + +## 0.36.11 + +### Patch Changes + +- Prefix EIP191 message on wallet-request-handler +- Updated dependencies + - @0xsequence/utils@0.36.11 + +## 0.36.10 + +### Patch Changes + +- support bannerUrl on connect +- Updated dependencies + - @0xsequence/utils@0.36.10 + +## 0.36.9 + +### Patch Changes + +- minor dev xp improvements +- Updated dependencies + - @0xsequence/utils@0.36.9 + +## 0.36.8 + +### Patch Changes + +- more connect options (theme, payment providers, funding currencies) +- Updated dependencies + - @0xsequence/utils@0.36.8 + +## 0.36.7 + +### Patch Changes + +- fix missing break +- Updated dependencies + - @0xsequence/utils@0.36.7 + +## 0.36.6 + +### Patch Changes + +- wallet_switchEthereumChain support +- Updated dependencies + - @0xsequence/utils@0.36.6 + +## 0.36.5 + +### Patch Changes + +- auth: bump ethauth to 0.7.0 + network, wallet: don't assume position of auth network in list + api/indexer/metadata: trim trailing slash on hostname, and add endpoint urls + relayer: Allow to specify local relayer transaction parameters like gas price or gas limit +- Updated dependencies + - @0xsequence/utils@0.36.5 + +## 0.36.4 + +### Patch Changes + +- Updating list of chain ids to include other ethereum compatible chains +- Updated dependencies + - @0xsequence/utils@0.36.4 + +## 0.36.3 + +### Patch Changes + +- provider: pass connect options to prompter methods +- Updated dependencies + - @0xsequence/utils@0.36.3 + +## 0.36.2 + +### Patch Changes + +- transactions: Setting target to 0x0 when empty to during SequenceTxAbiEncode +- Updated dependencies + - @0xsequence/utils@0.36.2 + +## 0.36.1 + +### Patch Changes + +- metadata: update client with more fields +- Updated dependencies + - @0xsequence/utils@0.36.1 + +## 0.36.0 + +### Minor Changes + +- relayer, wallet: fee quote support + +### Patch Changes + +- Updated dependencies + - @0xsequence/utils@0.36.0 + +## 0.35.12 + +### Patch Changes + +- provider: rename wallet.commands to wallet.utils +- Updated dependencies + - @0xsequence/utils@0.35.12 + +## 0.35.11 + +### Patch Changes + +- provider/utils: smoother message validation +- Updated dependencies + - @0xsequence/utils@0.35.11 + +## 0.35.10 + +### Patch Changes + +- upgrade deps +- Updated dependencies + - @0xsequence/utils@0.35.10 + +## 0.35.9 + +### Patch Changes + +- provider: window-transport override event handlers with new wallet instance +- Updated dependencies + - @0xsequence/utils@0.35.9 + +## 0.35.8 + +### Patch Changes + +- provider: async wallet sign in improvements +- Updated dependencies + - @0xsequence/utils@0.35.8 + +## 0.35.7 + +### Patch Changes + +- config: cache wallet configs +- Updated dependencies + - @0xsequence/utils@0.35.7 + +## 0.35.6 + +### Patch Changes + +- provider: support async signin of wallet request handler +- Updated dependencies + - @0xsequence/utils@0.35.6 + +## 0.35.5 + +### Patch Changes + +- wallet: skip threshold check during fee estimation +- Updated dependencies + - @0xsequence/utils@0.35.5 + +## 0.35.4 + +### Patch Changes + +- - browser extension mode, center window +- Updated dependencies + - @0xsequence/utils@0.35.4 + +## 0.35.3 + +### Patch Changes + +- - update window position when in browser extension mode +- Updated dependencies + - @0xsequence/utils@0.35.3 + +## 0.35.2 + +### Patch Changes + +- - provider: WindowMessageHandler accept optional windowHref +- Updated dependencies + - @0xsequence/utils@0.35.2 + +## 0.35.1 + +### Patch Changes + +- wallet: update config on undeployed too +- Updated dependencies + - @0xsequence/utils@0.35.1 + +## 0.35.0 + +### Minor Changes + +- - config: add buildStubSignature + - provider: add checks to signing cases for wallet deployment and config statuses + - provider: add prompt for wallet deployment + - relayer: add BaseRelayer.prependWalletDeploy + - relayer: add Relayer.feeOptions + - relayer: account for wallet deployment in fee estimation + - transactions: add fromTransactionish + - wallet: add Account.prependConfigUpdate + - wallet: add Account.getFeeOptions + +### Patch Changes + +- Updated dependencies + - @0xsequence/utils@0.35.0 + +## 0.34.0 + +### Minor Changes + +- - upgrade deps + +### Patch Changes + +- Updated dependencies + - @0xsequence/utils@0.34.0 + +## 0.31.2 + +### Patch Changes + +- remove ora + +## 0.31.0 + +### Minor Changes + +- - upgrading to ethers v5.5 + +### Patch Changes + +- Updated dependencies + - @0xsequence/utils@0.31.0 + +## 0.30.0 + +### Minor Changes + +- - upgrade most deps + +### Patch Changes + +- Updated dependencies + - @0xsequence/utils@0.30.0 + +## 0.29.8 + +### Patch Changes + +- update api +- Updated dependencies [undefined] + - @0xsequence/utils@0.29.8 + +## 0.29.0 + +### Minor Changes + +- major architectural changes in Sequence design + + - only one API instance, API is no longer a per-chain service + - separate per-chain indexer service, API no longer handles indexing + - single contract metadata service, API no longer serves metadata + + chaind package has been removed, indexer and metadata packages have been added + + stronger typing with new explicit ChainId type + + multicall fixes and improvements + + forbid "wait" transactions in sendTransactionBatch calls + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/utils@0.29.0 + +## 0.28.0 + +### Minor Changes + +- extension provider + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/utils@0.28.0 + +## 0.27.0 + +### Minor Changes + +- Add requireFreshSigner lib to sessions + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/utils@0.27.0 + +## 0.25.1 + +### Patch Changes + +- Fix build typescrypt issue +- Updated dependencies [undefined] + - @0xsequence/utils@0.25.1 + +## 0.25.0 + +### Minor Changes + +- 10c8af8: Add estimator package + Fix multicall few calls bug + +### Patch Changes + +- Updated dependencies [10c8af8] + - @0xsequence/utils@0.25.0 + +## 0.23.0 + +### Minor Changes + +- - relayer: offer variety of gas fee options from the relayer service" + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/utils@0.23.0 + +## 0.22.2 + +### Patch Changes + +- e1c109e: Fix authProof on expired sessions +- Updated dependencies [e1c109e] + - @0xsequence/utils@0.22.2 + +## 0.22.1 + +### Patch Changes + +- transport session cache +- Updated dependencies [undefined] + - @0xsequence/utils@0.22.1 + +## 0.22.0 + +### Minor Changes + +- e667b65: Expose all relayer options on networks + +### Patch Changes + +- Updated dependencies [e667b65] + - @0xsequence/utils@0.22.0 + +## 0.21.5 + +### Patch Changes + +- Give priority to metaTxnId returned by relayer +- Updated dependencies [undefined] + - @0xsequence/utils@0.21.5 + +## 0.21.4 + +### Patch Changes + +- Add has enough signers method +- Updated dependencies [undefined] + - @0xsequence/utils@0.21.4 + +## 0.21.3 + +### Patch Changes + +- add window session cache +- Updated dependencies [undefined] + - @0xsequence/utils@0.21.3 + +## 0.21.2 + +### Patch Changes + +- exception handlind in relayer +- Updated dependencies [undefined] + - @0xsequence/utils@0.21.2 + +## 0.21.0 + +### Minor Changes + +- - fix gas estimation on wallets with large number of signers + - update to session handling and wallet config construction upon auth + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/utils@0.21.0 + +## 0.19.3 + +### Patch Changes + +- jwtAuth visibility, package version sync +- Updated dependencies [undefined] + - @0xsequence/utils@0.19.3 + +## 0.19.0 + +### Minor Changes + +- - provider, improve dapp / wallet transport io + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/utils@0.19.0 + +## 0.18.0 + +### Minor Changes + +- relayer improvements and pending transaction handling + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/utils@0.18.0 + +## 0.16.0 + +### Minor Changes + +- relayer as its own service separate from chaind + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/utils@0.16.0 + +## 0.15.1 + +### Patch Changes + +- update api clients +- Updated dependencies [undefined] + - @0xsequence/utils@0.15.1 + +## 0.14.3 + +### Patch Changes + +- Fix 0xSequence relayer dependencies +- Updated dependencies [undefined] + - @0xsequence/utils@0.14.3 + +## 0.14.2 + +### Patch Changes + +- Add debug logs to rpc-relayer +- Updated dependencies [undefined] + - @0xsequence/utils@0.14.2 + +## 0.14.0 + +### Minor Changes + +- update sequence utils finder which includes optimization + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/utils@0.14.0 + +## 0.13.0 + +### Minor Changes + +- Update SequenceUtils deployed contract + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/utils@0.13.0 + +## 0.12.1 + +### Patch Changes + +- npm bump +- Updated dependencies [undefined] + - @0xsequence/utils@0.12.1 + +## 0.12.0 + +### Minor Changes + +- provider: improvements to window transport + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/utils@0.12.0 + +## 0.11.4 + +### Patch Changes + +- update api client +- Updated dependencies [undefined] + - @0xsequence/utils@0.11.4 + +## 0.11.3 + +### Patch Changes + +- improve openWindow state options handling +- Updated dependencies [undefined] + - @0xsequence/utils@0.11.3 + +## 0.11.2 + +### Patch Changes + +- Fix multicall proxy scopes +- Updated dependencies [undefined] + - @0xsequence/utils@0.11.2 + +## 0.11.1 + +### Patch Changes + +- Add support for dynamic and nested signatures +- Updated dependencies [undefined] + - @0xsequence/utils@0.11.1 + +## 0.11.0 + +### Minor Changes + +- Update wallet context to 1.7 contracts + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/utils@0.11.0 + +## 0.10.9 + +### Patch Changes + +- add support for public addresses as signers in session.open +- Updated dependencies [undefined] + - @0xsequence/utils@0.10.9 + +## 0.10.8 + +### Patch Changes + +- Multicall production configuration +- Updated dependencies [undefined] + - @0xsequence/utils@0.10.8 + +## 0.10.7 + +### Patch Changes + +- allow provider transport to force disconnect +- Updated dependencies [undefined] + - @0xsequence/utils@0.10.7 + +## 0.10.6 + +### Patch Changes + +- - fix getWalletState method +- Updated dependencies [undefined] + - @0xsequence/utils@0.10.6 + +## 0.10.5 + +### Patch Changes + +- update relayer gas refund options +- Updated dependencies [undefined] + - @0xsequence/utils@0.10.5 + +## 0.10.4 + +### Patch Changes + +- Update api proto +- Updated dependencies [undefined] + - @0xsequence/utils@0.10.4 + +## 0.10.3 + +### Patch Changes + +- Fix loading config cross-chain +- Updated dependencies [undefined] + - @0xsequence/utils@0.10.3 + +## 0.10.2 + +### Patch Changes + +- - message digest fix +- Updated dependencies [undefined] + - @0xsequence/utils@0.10.2 + +## 0.10.1 + +### Patch Changes + +- upgrade deps +- Updated dependencies [undefined] + - @0xsequence/utils@0.10.1 + +## 0.10.0 + +### Minor Changes + +- Deployed new contracts with ERC1271 signer support + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/utils@0.10.0 + +## 0.9.6 + +### Patch Changes + +- Update ABIs for latest sequence contracts +- Updated dependencies [undefined] + - @0xsequence/utils@0.9.6 + +## 0.9.5 + +### Patch Changes + +- Implemented session class +- Updated dependencies [undefined] + - @0xsequence/utils@0.9.5 + +## 0.9.3 + +### Patch Changes + +- - minor improvements +- Updated dependencies [undefined] + - @0xsequence/utils@0.9.3 + +## 0.9.1 + +### Patch Changes + +- - patch bump +- Updated dependencies [undefined] + - @0xsequence/utils@0.9.1 + +## 0.9.0 + +### Minor Changes + +- - provider transport hardening + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/utils@0.9.0 + +## 0.8.5 + +### Patch Changes + +- - use latest wallet-contracts +- Updated dependencies [undefined] + - @0xsequence/utils@0.8.5 + +## 0.8.4 + +### Patch Changes + +- - minor improvements, name updates and comments +- Updated dependencies [undefined] + - @0xsequence/utils@0.8.4 + +## 0.8.3 + +### Patch Changes + +- - refinements + + - normalize signer address in config + + - provider: getWalletState() method to WalletProvider + +- Updated dependencies [undefined] + - @0xsequence/utils@0.8.3 + +## 0.8.2 + +### Patch Changes + +- - field rename and ethauth dependency bump +- Updated dependencies [undefined] + - @0xsequence/utils@0.8.2 + +## 0.8.1 + +### Patch Changes + +- - variety of optimizations +- Updated dependencies [undefined] + - @0xsequence/utils@0.8.1 + +## 0.8.0 + +### Minor Changes + +- - changeset fix + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/utils@0.8.0 + +## 0.7.2 + +### Patch Changes + +- package.json fix + +## 0.7.0 + +### Patch Changes + +- 6f11ed7: sequence.js, init release +- Updated dependencies [6f11ed7] + - @0xsequence/utils@0.7.0 diff --git a/packages/deployer/README.md b/packages/deployer/README.md new file mode 100644 index 0000000000..1c58d69d4d --- /dev/null +++ b/packages/deployer/README.md @@ -0,0 +1,60 @@ +@0xsequence/deployer +==================== + +Deploy contracts using a universal deployer via CREATE2, allowing contracts to have the same address on any EVM chain. + +UniversalDeployer works in both Web Browsers and Nodejs. + +For more info, see [0xsequence project page](https://github.com/0xsequence/sequence.js). + +# How to use + +1. `yarn add @0xsequence/deployer` +1. Import UniversalDeployer into script +2. Create UniversalDeployer instance +3. Deploy contracts + +An `instance` number can be passed if multiple instance of the same contract need to be deployed on the same chain. The default instance number is 0, if none is passed. + +```typescript +... +import { UniversalDeployer } from '@0xsequence/deployer' + +const provider = new Web3Provider(web3.currentProvider) +const universalDeployer = new UniversalDeployer(network.name, provider) + +const main = async () => { + await universalDeployer.deploy('Factory', FactoryFactory) + await universalDeployer.deploy('MainModuleUpgradable', MainModuleUpgradableFactory) + await universalDeployer.deploy('GuestModule', GuestModuleFactory) + + prompt.start(`writing deployment information to ${network.name}.json`) + await universalDeployer.registerDeployment() + + // or, await universalDeployer.getDeployment() + + prompt.succeed() +} + +main() +``` + +You can also pass transaction parameters explicitly : + +```typescript +... + +const main = async () => { + await universalDeployer.deploy('WalletFactory', FactoryFactory, {gasLimit: 1000000} ) + await universalDeployer.deploy('MainModuleUpgradable', MainModuleUpgradableFactory, {gasPrice: new BigNumber(10).pow(9)}) +} + +``` + +--- + +## License + +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) + +Copyright (c) 2018-present Horizon Blockchain Games Inc. diff --git a/packages/deployer/artifacts/contracts/NanoUniversalDeployer.sol/NanoUniversalDeployer.json b/packages/deployer/artifacts/contracts/NanoUniversalDeployer.sol/NanoUniversalDeployer.json new file mode 100644 index 0000000000..3c7fe11b13 --- /dev/null +++ b/packages/deployer/artifacts/contracts/NanoUniversalDeployer.sol/NanoUniversalDeployer.json @@ -0,0 +1,28 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "NanoUniversalDeployer", + "sourceName": "contracts/NanoUniversalDeployer.sol", + "abi": [ + { + "anonymous": true, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_addr", + "type": "address" + } + ], + "name": "Deploy", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + } + ], + "bytecode": "0x6080604052348015600f57600080fd5b5060a580601d6000396000f3fe60a06020601f3690810182900490910282016040526080818152600092839283918190838280828437600092018290525084519495509392505060208401905034f56040805173ffffffffffffffffffffffffffffffffffffffff83168152905191935081900360200190a0505000fea26469706673582212207457f4b6f392e3ba295b33e363360d55f06ead85ec96165a406e7b0231ab668464736f6c63430007060033", + "deployedBytecode": "0x60a06020601f3690810182900490910282016040526080818152600092839283918190838280828437600092018290525084519495509392505060208401905034f56040805173ffffffffffffffffffffffffffffffffffffffff83168152905191935081900360200190a0505000fea26469706673582212207457f4b6f392e3ba295b33e363360d55f06ead85ec96165a406e7b0231ab668464736f6c63430007060033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/packages/deployer/artifacts/contracts/UniversalDeployer2.sol/UniversalDeployer2.json b/packages/deployer/artifacts/contracts/UniversalDeployer2.sol/UniversalDeployer2.json new file mode 100644 index 0000000000..b56022dc0f --- /dev/null +++ b/packages/deployer/artifacts/contracts/UniversalDeployer2.sol/UniversalDeployer2.json @@ -0,0 +1,42 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "UniversalDeployer2", + "sourceName": "contracts/UniversalDeployer2.sol", + "abi": [ + { + "anonymous": true, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_addr", + "type": "address" + } + ], + "name": "Deploy", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_creationCode", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_instance", + "type": "uint256" + } + ], + "name": "deploy", + "outputs": [], + "stateMutability": "payable", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b5061013d806100206000396000f3fe60806040526004361061001e5760003560e01c80639c4ae2d014610023575b600080fd5b6100cb6004803603604081101561003957600080fd5b81019060208101813564010000000081111561005457600080fd5b82018360208201111561006657600080fd5b8035906020019184600183028401116401000000008311171561008857600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955050913592506100cd915050565b005b60008183516020850134f56040805173ffffffffffffffffffffffffffffffffffffffff83168152905191925081900360200190a050505056fea264697066735822122033609f614f03931b92d88c309d698449bb77efcd517328d341fa4f923c5d8c7964736f6c63430007060033", + "deployedBytecode": "0x60806040526004361061001e5760003560e01c80639c4ae2d014610023575b600080fd5b6100cb6004803603604081101561003957600080fd5b81019060208101813564010000000081111561005457600080fd5b82018360208201111561006657600080fd5b8035906020019184600183028401116401000000008311171561008857600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955050913592506100cd915050565b005b60008183516020850134f56040805173ffffffffffffffffffffffffffffffffffffffff83168152905191925081900360200190a050505056fea264697066735822122033609f614f03931b92d88c309d698449bb77efcd517328d341fa4f923c5d8c7964736f6c63430007060033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/packages/deployer/config/PROD.env.sample b/packages/deployer/config/PROD.env.sample new file mode 100644 index 0000000000..f7afe8cd99 --- /dev/null +++ b/packages/deployer/config/PROD.env.sample @@ -0,0 +1,2 @@ +ETH_MNEMONIC="" +INFURA_API_KEY="" diff --git a/packages/deployer/contracts/NanoUniversalDeployer.sol b/packages/deployer/contracts/NanoUniversalDeployer.sol new file mode 100644 index 0000000000..6419b91683 --- /dev/null +++ b/packages/deployer/contracts/NanoUniversalDeployer.sol @@ -0,0 +1,12 @@ +pragma solidity ^0.7.6; + +contract NanoUniversalDeployer { + event Deploy(address _addr) anonymous; + + fallback() external payable { + address addr; + bytes memory code = msg.data; + assembly { addr := create2(callvalue(), add(code, 32), mload(code), 0) } + emit Deploy(addr); + } +} \ No newline at end of file diff --git a/packages/deployer/contracts/UniversalDeployer2.sol b/packages/deployer/contracts/UniversalDeployer2.sol new file mode 100644 index 0000000000..a25edfeeb5 --- /dev/null +++ b/packages/deployer/contracts/UniversalDeployer2.sol @@ -0,0 +1,16 @@ +pragma solidity ^0.7.6; + +contract UniversalDeployer2 { + event Deploy(address _addr) anonymous; + + /** + * @notice will deploy a contract via create2 + * @param _creationCode Creation code of contract to deploy + * @param _instance Instance number of contract to deploy + */ + function deploy(bytes memory _creationCode, uint256 _instance) public payable { + address addr; + assembly { addr := create2(callvalue(), add(_creationCode, 32), mload(_creationCode), _instance) } + emit Deploy(addr); + } +} \ No newline at end of file diff --git a/packages/deployer/hardhat.config.ts b/packages/deployer/hardhat.config.ts new file mode 100644 index 0000000000..13afd38348 --- /dev/null +++ b/packages/deployer/hardhat.config.ts @@ -0,0 +1,31 @@ +// import '@nomiclabs/hardhat-truffle5' +import { networkConfig } from './src/utils/configLoader' + +const ganacheNetwork = { + url: 'http://127.0.0.1:8545', + blockGasLimit: 6000000000 +} + +module.exports = { + solidity: { + version: '0.7.6', + settings: { + optimizer: { + enabled: true, + runs: 100000, + details: { + yul: true + } + } + } + }, + paths: { + tests: './src/tests' + }, + networks: { + goerli: networkConfig('goerli'), + mumbai: networkConfig('mumbai'), + matic: networkConfig('matic'), + ganache: ganacheNetwork + } +} diff --git a/packages/deployer/package.json b/packages/deployer/package.json new file mode 100644 index 0000000000..dd0fa7a81e --- /dev/null +++ b/packages/deployer/package.json @@ -0,0 +1,41 @@ +{ + "name": "@0xsequence/deployer", + "version": "2.0.0", + "description": "deployer sub-package for Sequence", + "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/deployer", + "source": "src/index.ts", + "main": "dist/0xsequence-deployer.cjs.js", + "module": "dist/0xsequence-deployer.esm.js", + "author": "Horizon Blockchain Games", + "license": "Apache-2.0", + "scripts": { + "test": "pnpm test:file tests/**/*.spec.ts", + "test:file": "NODE_OPTIONS='--import tsx' mocha --timeout 30000", + "typecheck": "tsc --noEmit", + "build": "rm -rf src/typings && TS_NODE_PROJECT=../../tsconfig.test.json hardhat clean && pnpm compile-contracts && pnpm gen:typings", + "compile-contracts": "TS_NODE_PROJECT=../../tsconfig.test.json hardhat --max-memory 4096 compile", + "gen:typings": "rm -rf ./src/typings/contracts/* && typechain --target ethers-v5 --out-dir src/typings/contracts './artifacts/contracts/!(build-info)/**/*[^dbg].json'" + }, + "dependencies": { + "@0xsequence/utils": "workspace:*" + }, + "peerDependencies": { + "ethers": ">=5.5 < 6", + "@ethersproject/abi": ">= 5.5", + "@ethersproject/providers": ">= 5.5" + }, + "devDependencies": { + "@ethersproject/abi": "^5.7.0", + "@ethersproject/providers": "^5.7.2", + "@nomiclabs/hardhat-ethers": "^2.2.1", + "@nomiclabs/hardhat-web3": "^2.0.0", + "@typechain/ethers-v5": "^10.1.1", + "dotenv": "^16.0.3", + "ethers": "^5.7.2", + "typechain": "^8.1.1" + }, + "files": [ + "src", + "dist" + ] +} diff --git a/packages/deployer/src/UniversalDeployer.ts b/packages/deployer/src/UniversalDeployer.ts new file mode 100644 index 0000000000..598bc46113 --- /dev/null +++ b/packages/deployer/src/UniversalDeployer.ts @@ -0,0 +1,207 @@ +import * as fs from 'fs' +import { ethers, ContractFactory, ContractTransaction } from 'ethers' +import { promisify, isNode } from '@0xsequence/utils' +import { UniversalDeployer2__factory } from './typings/contracts' +import { + EOA_UNIVERSAL_DEPLOYER_ADDRESS, + UNIVERSAL_DEPLOYER_ADDRESS, + UNIVERSAL_DEPLOYER_2_ADDRESS, + UNIVERSAL_DEPLOYER_FUNDING, + UNIVERSAL_DEPLOYER_TX, + UNIVERSAL_DEPLOYER_2_BYTECODE +} from './constants' +import { ContractInstance } from './types' +import { createLogger, Logger } from './utils/logger' + +let prompt: Logger +createLogger().then(logger => (prompt = logger)) + +ethers.utils.Logger.setLogLevel(ethers.utils.Logger.levels.OFF) + +export class UniversalDeployer { + private deployedInstances: ContractInstance[] = [] + private signer: ethers.Signer + + constructor( + public networkName: string, + public provider: ethers.providers.JsonRpcProvider, + public signerOverride?: ethers.Signer + ) { + this.signer = signerOverride || provider.getSigner() + } + + deploy = async ( + contractAlias: string, + contractFactory: new (signer: ethers.Signer) => T, + txParams?: ethers.providers.TransactionRequest, + instance?: number | ethers.BigNumber, + ...args: Parameters + ): Promise => { + try { + // Deploy universal deployer 2 if not yet deployed on chain_id + const universalDeployer2Code = await this.provider.getCode(UNIVERSAL_DEPLOYER_2_ADDRESS) + if (universalDeployer2Code === '0x') await this.deployUniversalDeployer2(txParams) + + // Deploying contract + prompt.start(`Deploying ${contractAlias}`) + const factory = new contractFactory(this.signer) + const deployTx = await factory.getDeployTransaction(...args) + + // Make sure instance number is specified + const instanceNumber = instance !== undefined ? instance : 0 + + // Verify if contract already deployed + const contractAddress = await this.addressOf(contractFactory, instanceNumber, ...args) + const contractCode = await this.provider.getCode(contractAddress) + + const deployer = UniversalDeployer2__factory.connect(UNIVERSAL_DEPLOYER_2_ADDRESS, this.signer) + + if (contractCode === '0x') { + // Deploy contract if not already deployed + const tx = (await deployer.functions.deploy(deployTx.data!, instanceNumber, txParams)) as ContractTransaction + await tx.wait() + + // Verify that the deployment was successful since tx won't revert + const postDeployCode = await this.provider.getCode(contractAddress) + postDeployCode === '0x' ? prompt.fail(contractAddress) : prompt.succeed() + } else { + prompt.warn(`ALREADY DEPLOYED: ${contractAlias}`) + } + + const contract = factory.attach(contractAddress) + this.deployedInstances.push({ contractAlias, contract }) + + return contract + } catch (error) { + throw new Error(`CONTRACT DEPLOY FAILED: ${error}`) + } + } + + deployUniversalDeployer = async (txParams?: ethers.providers.TransactionRequest) => { + if ((await this.provider.getBalance(EOA_UNIVERSAL_DEPLOYER_ADDRESS)) < UNIVERSAL_DEPLOYER_FUNDING) { + prompt.start("Funding universal deployer's EOA") + const tx = await this.signer.sendTransaction({ + to: EOA_UNIVERSAL_DEPLOYER_ADDRESS, + value: UNIVERSAL_DEPLOYER_FUNDING, + ...txParams + }) + const receipt = await tx.wait() + if (receipt.status !== 1) { + prompt.fail('txn receipt status failed') + } else { + prompt.succeed() + } + } + + prompt.start('Deploying universal deployer contract') + const tx2 = await this.provider.sendTransaction(UNIVERSAL_DEPLOYER_TX) + // await tx2.wait() + + // const universalDeployerCodeCheck = await this.provider.getCode(UNIVERSAL_DEPLOYER_ADDRESS) + // if (universalDeployerCodeCheck === '0x') { + // prompt.fail(UNIVERSAL_DEPLOYER_ADDRESS) + // } else { + // prompt.succeed() + // } + prompt.succeed() + } + + // Deploy universal deployer via universal deployer 1 + deployUniversalDeployer2 = async (txParams?: ethers.providers.TransactionRequest) => { + const universalDeployerCode = await this.provider.getCode(UNIVERSAL_DEPLOYER_ADDRESS) + if (universalDeployerCode === '0x') { + await this.deployUniversalDeployer(txParams) + } else { + ;('ALREADY DEPLOYED') + } + + // NOTE: in case the getCode below fails, double check the UNIVERSAL_DEPLOYER_2_ADDRESS address + // which is emitted from the deployer 1 contract creation logs. This address may change if + // the UNIVERSAL_DEPLOYER_2_BYTECODE changes of the deployer -- which should never really happen. + + prompt.start('Deploying universal deployer 2 contract') + const tx = (await this.signer.sendTransaction({ + to: UNIVERSAL_DEPLOYER_ADDRESS, + data: UNIVERSAL_DEPLOYER_2_BYTECODE, + ...txParams + })) as ContractTransaction + await tx.wait() + + // const universalDeployer2CodeCheck = await this.provider.getCode(UNIVERSAL_DEPLOYER_2_ADDRESS) + // if (universalDeployer2CodeCheck === '0x') { + // prompt.fail(UNIVERSAL_DEPLOYER_2_ADDRESS) + // } else { + // prompt.succeed() + // } + prompt.succeed() + } + + getDeployment = () => { + return this.deployedInstances.reduce( + (list, instance) => { + const { contract, contractAlias } = instance + list[contractAlias] = contract + return list + }, + {} as { [key: string]: ethers.Contract | { address: string } } + ) + } + + getDeploymentList = () => + this.deployedInstances.map(({ contract, contractAlias }) => { + if (contract as ethers.Contract) { + return { + contractName: contractAlias, + address: contract.address + // abi: contract.interface.abi + } + } else { + return { + contractName: contractAlias, + address: contract.address + } + } + }) + + registerDeployment = async (filePath?: string) => { + if (!isNode()) { + throw new Error('registerDeployment cannot be run in a browser. Node is required. Try the getDeployment() method.') + } + + return promisify(fs.writeFile)( + filePath ? filePath : `./networks/${this.networkName}.json`, + JSON.stringify(this.getDeployment(), null, 2), + { flag: 'w+' } + ) + } + + manualDeploymentRegistration = (contractAlias: string, address: string) => { + this.deployedInstances.push({ + contractAlias, + contract: { address: address } + }) + } + + addressOf = async ( + contractFactory: new (signer: ethers.Signer) => T, + contractInstance: number | ethers.BigNumber, + ...args: Parameters + ): Promise => { + const factory = new contractFactory(this.signer) + const deployTx = await factory.getDeployTransaction(...args) + const deployData = deployTx.data + + const codeHash = ethers.utils.keccak256(ethers.utils.solidityPack(['bytes'], [deployData])) + + const salt = ethers.utils.solidityPack(['uint256'], [contractInstance]) + + const hash = ethers.utils.keccak256( + ethers.utils.solidityPack( + ['bytes1', 'address', 'bytes32', 'bytes32'], + ['0xff', UNIVERSAL_DEPLOYER_2_ADDRESS, salt, codeHash] + ) + ) + + return ethers.utils.getAddress(ethers.utils.hexDataSlice(hash, 12)) + } +} diff --git a/packages/deployer/src/constants.ts b/packages/deployer/src/constants.ts new file mode 100644 index 0000000000..9fded9dcdc --- /dev/null +++ b/packages/deployer/src/constants.ts @@ -0,0 +1,18 @@ +import { BigNumber } from 'ethers' + +export const EOA_UNIVERSAL_DEPLOYER_ADDRESS: string = '0x9c5a87452d4FAC0cbd53BDCA580b20A45526B3AB' +export const UNIVERSAL_DEPLOYER_ADDRESS: string = '0x1b926fbb24a9f78dcdd3272f2d86f5d0660e59c0' +export const UNIVERSAL_DEPLOYER_2_ADDRESS: string = '0x8a5bc19e22d6ad55a2c763b93a75d09f321fe764' +export const UNIVERSAL_DEPLOYER_FUNDING: BigNumber = BigNumber.from(300).mul(BigNumber.from(10).pow(14)) +export const UNIVERSAL_DEPLOYER_TX: string = + '0xf9010880852416b84e01830222e08080b8b66080604052348015600f57600080fd5b50609980601d6000396000f3fe60a06020601f369081018290049091028201604052608081815260009260609284918190838280828437600092018290525084519495509392505060208401905034f5604080516001600160a01b0383168152905191935081900360200190a0505000fea26469706673582212205a310755225e3c740b2f013fb6343f4c205e7141fcdf15947f5f0e0e818727fb64736f6c634300060a00331ca01820182018201820182018201820182018201820182018201820182018201820a01820182018201820182018201820182018201820182018201820182018201820' + +// expected bytecode for the universal deployer 2. If this changes for whatever reason then the universal +// deployer's addresses of contracts it's deployed will change, and so will UNIVERSAL_DEPLOYER_2_ADDRESS. +// +// do not change this value. it is here to integrity check within the UniversalDeployer. if you do change +// it however, then make sure to also update UNIVERSAL_DEPLOYER_2_ADDRESS. +// +// this value was originally copied from typings/contracts/factories/UniversalDeployer2__factory.ts +export const UNIVERSAL_DEPLOYER_2_BYTECODE = + '0x608060405234801561001057600080fd5b5061013d806100206000396000f3fe60806040526004361061001e5760003560e01c80639c4ae2d014610023575b600080fd5b6100cb6004803603604081101561003957600080fd5b81019060208101813564010000000081111561005457600080fd5b82018360208201111561006657600080fd5b8035906020019184600183028401116401000000008311171561008857600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955050913592506100cd915050565b005b60008183516020850134f56040805173ffffffffffffffffffffffffffffffffffffffff83168152905191925081900360200190a050505056fea264697066735822122033609f614f03931b92d88c309d698449bb77efcd517328d341fa4f923c5d8c7964736f6c63430007060033' diff --git a/packages/deployer/src/index.ts b/packages/deployer/src/index.ts new file mode 100644 index 0000000000..155d24c683 --- /dev/null +++ b/packages/deployer/src/index.ts @@ -0,0 +1,3 @@ +export { UniversalDeployer } from './UniversalDeployer' +export * from './constants' +export * from './types' diff --git a/packages/deployer/src/types.ts b/packages/deployer/src/types.ts new file mode 100644 index 0000000000..69b31aec42 --- /dev/null +++ b/packages/deployer/src/types.ts @@ -0,0 +1,15 @@ +import { Contract } from 'ethers' + +export interface FactoryDeployedContract { + address: string +} + +export interface ContractInstance { + contractAlias: string + contract: Contract | { address: string } +} + +export interface ContractInfo { + contractName: string + contractAlias?: string +} diff --git a/packages/deployer/src/typings/contracts/NanoUniversalDeployer.ts b/packages/deployer/src/typings/contracts/NanoUniversalDeployer.ts new file mode 100644 index 0000000000..9f85040284 --- /dev/null +++ b/packages/deployer/src/typings/contracts/NanoUniversalDeployer.ts @@ -0,0 +1,60 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import type { BaseContract, Signer, utils } from 'ethers' +import type { EventFragment } from '@ethersproject/abi' +import type { Listener, Provider } from '@ethersproject/providers' +import type { TypedEventFilter, TypedEvent, TypedListener, OnEvent, PromiseOrValue } from './common' + +export interface NanoUniversalDeployerInterface extends utils.Interface { + functions: {} + + events: { + 'Deploy(address)': EventFragment + } + + getEvent(nameOrSignatureOrTopic: 'Deploy'): EventFragment +} + +export interface DeployEventObject { + _addr: string +} +export type DeployEvent = TypedEvent<[string], DeployEventObject> + +export type DeployEventFilter = TypedEventFilter + +export interface NanoUniversalDeployer extends BaseContract { + connect(signerOrProvider: Signer | Provider | string): this + attach(addressOrName: string): this + deployed(): Promise + + interface: NanoUniversalDeployerInterface + + queryFilter( + event: TypedEventFilter, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise> + + listeners(eventFilter?: TypedEventFilter): Array> + listeners(eventName?: string): Array + removeAllListeners(eventFilter: TypedEventFilter): this + removeAllListeners(eventName?: string): this + off: OnEvent + on: OnEvent + once: OnEvent + removeListener: OnEvent + + functions: {} + + callStatic: {} + + filters: { + 'Deploy(address)'(_addr?: null): DeployEventFilter + Deploy(_addr?: null): DeployEventFilter + } + + estimateGas: {} + + populateTransaction: {} +} diff --git a/packages/deployer/src/typings/contracts/UniversalDeployer2.ts b/packages/deployer/src/typings/contracts/UniversalDeployer2.ts new file mode 100644 index 0000000000..cf2db74cec --- /dev/null +++ b/packages/deployer/src/typings/contracts/UniversalDeployer2.ts @@ -0,0 +1,109 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import type { + BaseContract, + BigNumber, + BigNumberish, + BytesLike, + CallOverrides, + ContractTransaction, + PayableOverrides, + PopulatedTransaction, + Signer, + utils +} from 'ethers' +import type { FunctionFragment, Result, EventFragment } from '@ethersproject/abi' +import type { Listener, Provider } from '@ethersproject/providers' +import type { TypedEventFilter, TypedEvent, TypedListener, OnEvent, PromiseOrValue } from './common' + +export interface UniversalDeployer2Interface extends utils.Interface { + functions: { + 'deploy(bytes,uint256)': FunctionFragment + } + + getFunction(nameOrSignatureOrTopic: 'deploy'): FunctionFragment + + encodeFunctionData(functionFragment: 'deploy', values: [PromiseOrValue, PromiseOrValue]): string + + decodeFunctionResult(functionFragment: 'deploy', data: BytesLike): Result + + events: { + 'Deploy(address)': EventFragment + } + + getEvent(nameOrSignatureOrTopic: 'Deploy'): EventFragment +} + +export interface DeployEventObject { + _addr: string +} +export type DeployEvent = TypedEvent<[string], DeployEventObject> + +export type DeployEventFilter = TypedEventFilter + +export interface UniversalDeployer2 extends BaseContract { + connect(signerOrProvider: Signer | Provider | string): this + attach(addressOrName: string): this + deployed(): Promise + + interface: UniversalDeployer2Interface + + queryFilter( + event: TypedEventFilter, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise> + + listeners(eventFilter?: TypedEventFilter): Array> + listeners(eventName?: string): Array + removeAllListeners(eventFilter: TypedEventFilter): this + removeAllListeners(eventName?: string): this + off: OnEvent + on: OnEvent + once: OnEvent + removeListener: OnEvent + + functions: { + deploy( + _creationCode: PromiseOrValue, + _instance: PromiseOrValue, + overrides?: PayableOverrides & { from?: PromiseOrValue } + ): Promise + } + + deploy( + _creationCode: PromiseOrValue, + _instance: PromiseOrValue, + overrides?: PayableOverrides & { from?: PromiseOrValue } + ): Promise + + callStatic: { + deploy( + _creationCode: PromiseOrValue, + _instance: PromiseOrValue, + overrides?: CallOverrides + ): Promise + } + + filters: { + 'Deploy(address)'(_addr?: null): DeployEventFilter + Deploy(_addr?: null): DeployEventFilter + } + + estimateGas: { + deploy( + _creationCode: PromiseOrValue, + _instance: PromiseOrValue, + overrides?: PayableOverrides & { from?: PromiseOrValue } + ): Promise + } + + populateTransaction: { + deploy( + _creationCode: PromiseOrValue, + _instance: PromiseOrValue, + overrides?: PayableOverrides & { from?: PromiseOrValue } + ): Promise + } +} diff --git a/packages/deployer/src/typings/contracts/common.ts b/packages/deployer/src/typings/contracts/common.ts new file mode 100644 index 0000000000..5d37e711b7 --- /dev/null +++ b/packages/deployer/src/typings/contracts/common.ts @@ -0,0 +1,32 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import type { Listener } from '@ethersproject/providers' +import type { Event, EventFilter } from 'ethers' + +export interface TypedEvent = any, TArgsObject = any> extends Event { + args: TArgsArray & TArgsObject +} + +export interface TypedEventFilter<_TEvent extends TypedEvent> extends EventFilter {} + +export interface TypedListener { + (...listenerArg: [...__TypechainArgsArray, TEvent]): void +} + +type __TypechainArgsArray = T extends TypedEvent ? U : never + +export interface OnEvent { + (eventFilter: TypedEventFilter, listener: TypedListener): TRes + (eventName: string, listener: Listener): TRes +} + +export type MinEthersFactory = { + deploy(...a: ARGS[]): Promise +} + +export type GetContractTypeFromFactory = F extends MinEthersFactory ? C : never + +export type GetARGsTypeFromFactory = F extends MinEthersFactory ? Parameters : never + +export type PromiseOrValue = T | Promise diff --git a/packages/deployer/src/typings/contracts/factories/NanoUniversalDeployer__factory.ts b/packages/deployer/src/typings/contracts/factories/NanoUniversalDeployer__factory.ts new file mode 100644 index 0000000000..bcecf70016 --- /dev/null +++ b/packages/deployer/src/typings/contracts/factories/NanoUniversalDeployer__factory.ts @@ -0,0 +1,67 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import { Signer, utils, Contract, ContractFactory, Overrides } from 'ethers' +import type { Provider, TransactionRequest } from '@ethersproject/providers' +import type { PromiseOrValue } from '../common' +import type { NanoUniversalDeployer, NanoUniversalDeployerInterface } from '../NanoUniversalDeployer' + +const _abi = [ + { + anonymous: true, + inputs: [ + { + indexed: false, + internalType: 'address', + name: '_addr', + type: 'address' + } + ], + name: 'Deploy', + type: 'event' + }, + { + stateMutability: 'payable', + type: 'fallback' + } +] + +const _bytecode = + '0x6080604052348015600f57600080fd5b5060a580601d6000396000f3fe60a06020601f3690810182900490910282016040526080818152600092839283918190838280828437600092018290525084519495509392505060208401905034f56040805173ffffffffffffffffffffffffffffffffffffffff83168152905191935081900360200190a0505000fea26469706673582212207457f4b6f392e3ba295b33e363360d55f06ead85ec96165a406e7b0231ab668464736f6c63430007060033' + +type NanoUniversalDeployerConstructorParams = [signer?: Signer] | ConstructorParameters + +const isSuperArgs = (xs: NanoUniversalDeployerConstructorParams): xs is ConstructorParameters => + xs.length > 1 + +export class NanoUniversalDeployer__factory extends ContractFactory { + constructor(...args: NanoUniversalDeployerConstructorParams) { + if (isSuperArgs(args)) { + super(...args) + } else { + super(_abi, _bytecode, args[0]) + } + } + + override deploy(overrides?: Overrides & { from?: PromiseOrValue }): Promise { + return super.deploy(overrides || {}) as Promise + } + override getDeployTransaction(overrides?: Overrides & { from?: PromiseOrValue }): TransactionRequest { + return super.getDeployTransaction(overrides || {}) + } + override attach(address: string): NanoUniversalDeployer { + return super.attach(address) as NanoUniversalDeployer + } + override connect(signer: Signer): NanoUniversalDeployer__factory { + return super.connect(signer) as NanoUniversalDeployer__factory + } + + static readonly bytecode = _bytecode + static readonly abi = _abi + static createInterface(): NanoUniversalDeployerInterface { + return new utils.Interface(_abi) as NanoUniversalDeployerInterface + } + static connect(address: string, signerOrProvider: Signer | Provider): NanoUniversalDeployer { + return new Contract(address, _abi, signerOrProvider) as NanoUniversalDeployer + } +} diff --git a/packages/deployer/src/typings/contracts/factories/UniversalDeployer2__factory.ts b/packages/deployer/src/typings/contracts/factories/UniversalDeployer2__factory.ts new file mode 100644 index 0000000000..67cf2eb000 --- /dev/null +++ b/packages/deployer/src/typings/contracts/factories/UniversalDeployer2__factory.ts @@ -0,0 +1,81 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import { Signer, utils, Contract, ContractFactory, Overrides } from 'ethers' +import type { Provider, TransactionRequest } from '@ethersproject/providers' +import type { PromiseOrValue } from '../common' +import type { UniversalDeployer2, UniversalDeployer2Interface } from '../UniversalDeployer2' + +const _abi = [ + { + anonymous: true, + inputs: [ + { + indexed: false, + internalType: 'address', + name: '_addr', + type: 'address' + } + ], + name: 'Deploy', + type: 'event' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_creationCode', + type: 'bytes' + }, + { + internalType: 'uint256', + name: '_instance', + type: 'uint256' + } + ], + name: 'deploy', + outputs: [], + stateMutability: 'payable', + type: 'function' + } +] + +const _bytecode = + '0x608060405234801561001057600080fd5b5061013d806100206000396000f3fe60806040526004361061001e5760003560e01c80639c4ae2d014610023575b600080fd5b6100cb6004803603604081101561003957600080fd5b81019060208101813564010000000081111561005457600080fd5b82018360208201111561006657600080fd5b8035906020019184600183028401116401000000008311171561008857600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955050913592506100cd915050565b005b60008183516020850134f56040805173ffffffffffffffffffffffffffffffffffffffff83168152905191925081900360200190a050505056fea264697066735822122033609f614f03931b92d88c309d698449bb77efcd517328d341fa4f923c5d8c7964736f6c63430007060033' + +type UniversalDeployer2ConstructorParams = [signer?: Signer] | ConstructorParameters + +const isSuperArgs = (xs: UniversalDeployer2ConstructorParams): xs is ConstructorParameters => + xs.length > 1 + +export class UniversalDeployer2__factory extends ContractFactory { + constructor(...args: UniversalDeployer2ConstructorParams) { + if (isSuperArgs(args)) { + super(...args) + } else { + super(_abi, _bytecode, args[0]) + } + } + + override deploy(overrides?: Overrides & { from?: PromiseOrValue }): Promise { + return super.deploy(overrides || {}) as Promise + } + override getDeployTransaction(overrides?: Overrides & { from?: PromiseOrValue }): TransactionRequest { + return super.getDeployTransaction(overrides || {}) + } + override attach(address: string): UniversalDeployer2 { + return super.attach(address) as UniversalDeployer2 + } + override connect(signer: Signer): UniversalDeployer2__factory { + return super.connect(signer) as UniversalDeployer2__factory + } + + static readonly bytecode = _bytecode + static readonly abi = _abi + static createInterface(): UniversalDeployer2Interface { + return new utils.Interface(_abi) as UniversalDeployer2Interface + } + static connect(address: string, signerOrProvider: Signer | Provider): UniversalDeployer2 { + return new Contract(address, _abi, signerOrProvider) as UniversalDeployer2 + } +} diff --git a/packages/deployer/src/typings/contracts/factories/index.ts b/packages/deployer/src/typings/contracts/factories/index.ts new file mode 100644 index 0000000000..e460629dd8 --- /dev/null +++ b/packages/deployer/src/typings/contracts/factories/index.ts @@ -0,0 +1,5 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +export { NanoUniversalDeployer__factory } from './NanoUniversalDeployer__factory' +export { UniversalDeployer2__factory } from './UniversalDeployer2__factory' diff --git a/packages/deployer/src/typings/contracts/index.ts b/packages/deployer/src/typings/contracts/index.ts new file mode 100644 index 0000000000..087a970c94 --- /dev/null +++ b/packages/deployer/src/typings/contracts/index.ts @@ -0,0 +1,8 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +export type { NanoUniversalDeployer } from './NanoUniversalDeployer' +export type { UniversalDeployer2 } from './UniversalDeployer2' +export * as factories from './factories' +export { NanoUniversalDeployer__factory } from './factories/NanoUniversalDeployer__factory' +export { UniversalDeployer2__factory } from './factories/UniversalDeployer2__factory' diff --git a/packages/deployer/src/utils/configLoader.ts b/packages/deployer/src/utils/configLoader.ts new file mode 100644 index 0000000000..35f67c524c --- /dev/null +++ b/packages/deployer/src/utils/configLoader.ts @@ -0,0 +1,49 @@ +import * as dotenv from 'dotenv' +import * as path from 'path' +import { HttpNetworkConfig, HttpNetworkHDAccountsConfig } from 'hardhat/types/config' +import { ethers } from 'ethers' + +type EthereumNetworksTypes = 'rinkeby' | 'ropsten' | 'kovan' | 'goerli' | 'mainnet' | 'mumbai' | 'matic' + +export const getEnvConfig = (env: string) => { + const envFile = path.resolve(__dirname, `../../config/${env}.env`) + const envLoad = dotenv.config({ path: envFile }) + + if (envLoad.error) { + console.warn('No config found, using default') + return { ETH_MNEMONIC: ethers.Wallet.createRandom().mnemonic.phrase } + } + + return envLoad.parsed || {} +} + +export const networkConfig = (network: EthereumNetworksTypes): HttpNetworkConfig => { + const config = getEnvConfig('PROD') + const networkConfig: HttpNetworkConfig = { + url: (function (network) { + switch (network) { + case 'mumbai': + return 'https://rpc-mumbai.matic.today/' + + case 'matic': + return 'https://rpc-mainnet.matic.network' + + default: + return `https://${network}.infura.io/v3/${config['INFURA_API_KEY']}` + } + })(network), + accounts: { + mnemonic: config['ETH_MNEMONIC'], + initialIndex: 0, + count: 10, + path: `m/44'/60'/0'/0` + } as HttpNetworkHDAccountsConfig, + gas: 'auto', + gasPrice: 'auto', + gasMultiplier: 1, + timeout: 20000, + httpHeaders: {} + } + + return networkConfig +} diff --git a/packages/deployer/src/utils/logger.ts b/packages/deployer/src/utils/logger.ts new file mode 100644 index 0000000000..17f7f3fd15 --- /dev/null +++ b/packages/deployer/src/utils/logger.ts @@ -0,0 +1,34 @@ +export interface Logger { + start(text?: string): void + stop(): void + succeed(text?: string): void + fail(text?: string): void + warn(text?: string): void + info(text?: string): void +} + +export const createLogger = async (): Promise => { + let startText = '' + return { + start: function (text: string = '') { + startText = text + console.warn(`[start] ${text}`) + }, + stop: function () { + console.warn(`[stop] ${startText}`) + startText = '' + }, + succeed: function (text: string = '') { + console.warn(`[success] ${startText} ${text}`) + }, + fail: function (text: string = '') { + console.warn(`[fail] ${startText} ${text}`) + }, + warn: function (text: string = '') { + console.warn(`[warn] ${startText} ${text}`) + }, + info: function (text: string = '') { + console.warn(`[info] ${startText} ${text}`) + } + } +} diff --git a/packages/deployer/tests/mock.spec.ts b/packages/deployer/tests/mock.spec.ts new file mode 100644 index 0000000000..9ddc326c89 --- /dev/null +++ b/packages/deployer/tests/mock.spec.ts @@ -0,0 +1,3 @@ +describe('deployer', function () { + it('todo', () => {}) +}) diff --git a/packages/estimator/CHANGELOG.md b/packages/estimator/CHANGELOG.md new file mode 100644 index 0000000000..b955ee686b --- /dev/null +++ b/packages/estimator/CHANGELOG.md @@ -0,0 +1,2626 @@ +# @0xsequence/estimator + +## 2.0.0 + +### Major Changes + +- changeset + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@2.0.0 + - @0xsequence/core@2.0.0 + - @0xsequence/utils@2.0.0 + +## 1.10.14 + +### Patch Changes + +- network: add borne-testnet to allNetworks +- Updated dependencies + - @0xsequence/abi@1.10.14 + - @0xsequence/core@1.10.14 + - @0xsequence/utils@1.10.14 + +## 1.10.13 + +### Patch Changes + +- network: add borne testnet +- Updated dependencies + - @0xsequence/abi@1.10.13 + - @0xsequence/core@1.10.13 + - @0xsequence/utils@1.10.13 + +## 1.10.12 + +### Patch Changes + +- api: update bindings +- global/window -> globalThis +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.10.12 + - @0xsequence/core@1.10.12 + - @0xsequence/utils@1.10.12 + +## 1.10.11 + +### Patch Changes + +- waas: updated intent.gen without webrpc types, errors exported from authenticator.gen +- Updated dependencies + - @0xsequence/abi@1.10.11 + - @0xsequence/core@1.10.11 + - @0xsequence/utils@1.10.11 + +## 1.10.10 + +### Patch Changes + +- metadata: update bindings with new contract collections api +- Updated dependencies + - @0xsequence/abi@1.10.10 + - @0xsequence/core@1.10.10 + - @0xsequence/utils@1.10.10 + +## 1.10.9 + +### Patch Changes + +- waas minor update +- Updated dependencies + - @0xsequence/abi@1.10.9 + - @0xsequence/core@1.10.9 + - @0xsequence/utils@1.10.9 + +## 1.10.8 + +### Patch Changes + +- update metadata bindings +- Updated dependencies + - @0xsequence/abi@1.10.8 + - @0xsequence/core@1.10.8 + - @0xsequence/utils@1.10.8 + +## 1.10.7 + +### Patch Changes + +- minor fixes to waas client +- Updated dependencies + - @0xsequence/abi@1.10.7 + - @0xsequence/core@1.10.7 + - @0xsequence/utils@1.10.7 + +## 1.10.6 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/abi@1.10.6 + - @0xsequence/core@1.10.6 + - @0xsequence/utils@1.10.6 + +## 1.10.5 + +### Patch Changes + +- network: ape-chain-testnet -> apechain-testnet +- Updated dependencies + - @0xsequence/abi@1.10.5 + - @0xsequence/core@1.10.5 + - @0xsequence/utils@1.10.5 + +## 1.10.4 + +### Patch Changes + +- network: add b3-sepolia, ape-chain-testnet, blast, blast-sepolia +- Updated dependencies + - @0xsequence/abi@1.10.4 + - @0xsequence/core@1.10.4 + - @0xsequence/utils@1.10.4 + +## 1.10.3 + +### Patch Changes + +- typing fix +- Updated dependencies + - @0xsequence/abi@1.10.3 + - @0xsequence/core@1.10.3 + - @0xsequence/utils@1.10.3 + +## 1.10.2 + +### Patch Changes + +- - waas: add getIdToken method + - indexer: update api client +- Updated dependencies + - @0xsequence/abi@1.10.2 + - @0xsequence/core@1.10.2 + - @0xsequence/utils@1.10.2 + +## 1.10.1 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/abi@1.10.1 + - @0xsequence/core@1.10.1 + - @0xsequence/utils@1.10.1 + +## 1.10.0 + +### Minor Changes + +- waas release v1.3.0 + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.10.0 + - @0xsequence/core@1.10.0 + - @0xsequence/utils@1.10.0 + +## 1.9.37 + +### Patch Changes + +- network: adds nativeToken data to NetworkMetadata constants +- Updated dependencies + - @0xsequence/abi@1.9.37 + - @0xsequence/core@1.9.37 + - @0xsequence/utils@1.9.37 + +## 1.9.36 + +### Patch Changes + +- guard: export client +- Updated dependencies + - @0xsequence/abi@1.9.36 + - @0xsequence/core@1.9.36 + - @0xsequence/utils@1.9.36 + +## 1.9.35 + +### Patch Changes + +- guard: update bindings +- Updated dependencies + - @0xsequence/abi@1.9.35 + - @0xsequence/core@1.9.35 + - @0xsequence/utils@1.9.35 + +## 1.9.34 + +### Patch Changes + +- waas: always use lowercase email +- Updated dependencies + - @0xsequence/abi@1.9.34 + - @0xsequence/core@1.9.34 + - @0xsequence/utils@1.9.34 + +## 1.9.33 + +### Patch Changes + +- waas: umd build +- Updated dependencies + - @0xsequence/abi@1.9.33 + - @0xsequence/core@1.9.33 + - @0xsequence/utils@1.9.33 + +## 1.9.32 + +### Patch Changes + +- indexer: update bindings +- Updated dependencies + - @0xsequence/abi@1.9.32 + - @0xsequence/core@1.9.32 + - @0xsequence/utils@1.9.32 + +## 1.9.31 + +### Patch Changes + +- metadata: token directory changes +- Updated dependencies + - @0xsequence/abi@1.9.31 + - @0xsequence/core@1.9.31 + - @0xsequence/utils@1.9.31 + +## 1.9.30 + +### Patch Changes + +- update +- Updated dependencies + - @0xsequence/abi@1.9.30 + - @0xsequence/core@1.9.30 + - @0xsequence/utils@1.9.30 + +## 1.9.29 + +### Patch Changes + +- disable gnosis chain +- Updated dependencies + - @0xsequence/abi@1.9.29 + - @0xsequence/core@1.9.29 + - @0xsequence/utils@1.9.29 + +## 1.9.28 + +### Patch Changes + +- add utils/merkletree +- Updated dependencies + - @0xsequence/abi@1.9.28 + - @0xsequence/core@1.9.28 + - @0xsequence/utils@1.9.28 + +## 1.9.27 + +### Patch Changes + +- network: optimistic -> optimism +- waas: remove defaults +- api, sessions: update bindings +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.9.27 + - @0xsequence/core@1.9.27 + - @0xsequence/utils@1.9.27 + +## 1.9.26 + +### Patch Changes + +- - add backend interfaces for pluggable interfaces + - introduce @0xsequence/react-native + - update pnpm to lockfile v9 +- Updated dependencies + - @0xsequence/abi@1.9.26 + - @0xsequence/core@1.9.26 + - @0xsequence/utils@1.9.26 + +## 1.9.25 + +### Patch Changes + +- update webrpc clients with new error types +- Updated dependencies + - @0xsequence/abi@1.9.25 + - @0xsequence/core@1.9.25 + - @0xsequence/utils@1.9.25 + +## 1.9.24 + +### Patch Changes + +- waas: add memoryStore backend to localStore +- Updated dependencies + - @0xsequence/abi@1.9.24 + - @0xsequence/core@1.9.24 + - @0xsequence/utils@1.9.24 + +## 1.9.23 + +### Patch Changes + +- update api client bindings +- Updated dependencies + - @0xsequence/abi@1.9.23 + - @0xsequence/core@1.9.23 + - @0xsequence/utils@1.9.23 + +## 1.9.22 + +### Patch Changes + +- update metadata client bindings +- Updated dependencies + - @0xsequence/abi@1.9.22 + - @0xsequence/core@1.9.22 + - @0xsequence/utils@1.9.22 + +## 1.9.21 + +### Patch Changes + +- api client bindings +- Updated dependencies + - @0xsequence/abi@1.9.21 + - @0xsequence/core@1.9.21 + - @0xsequence/utils@1.9.21 + +## 1.9.20 + +### Patch Changes + +- api client bindings update +- Updated dependencies + - @0xsequence/abi@1.9.20 + - @0xsequence/core@1.9.20 + - @0xsequence/utils@1.9.20 + +## 1.9.19 + +### Patch Changes + +- waas update +- Updated dependencies + - @0xsequence/abi@1.9.19 + - @0xsequence/core@1.9.19 + - @0xsequence/utils@1.9.19 + +## 1.9.18 + +### Patch Changes + +- provider: prohibit dangerous functions +- Updated dependencies + - @0xsequence/abi@1.9.18 + - @0xsequence/core@1.9.18 + - @0xsequence/utils@1.9.18 + +## 1.9.17 + +### Patch Changes + +- network: add xr-sepolia +- Updated dependencies + - @0xsequence/abi@1.9.17 + - @0xsequence/core@1.9.17 + - @0xsequence/utils@1.9.17 + +## 1.9.16 + +### Patch Changes + +- waas: sequence.feeOptions +- Updated dependencies + - @0xsequence/abi@1.9.16 + - @0xsequence/core@1.9.16 + - @0xsequence/utils@1.9.16 + +## 1.9.15 + +### Patch Changes + +- metadata: collection external_link field name fix +- Updated dependencies + - @0xsequence/abi@1.9.15 + - @0xsequence/core@1.9.15 + - @0xsequence/utils@1.9.15 + +## 1.9.14 + +### Patch Changes + +- network: astar-zkatana -> astar-zkyoto +- network: deprecate polygon mumbai network +- network: add xai and polygon amoy +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.9.14 + - @0xsequence/core@1.9.14 + - @0xsequence/utils@1.9.14 + +## 1.9.13 + +### Patch Changes + +- waas: fix @0xsequence/network dependency +- Updated dependencies + - @0xsequence/abi@1.9.13 + - @0xsequence/core@1.9.13 + - @0xsequence/utils@1.9.13 + +## 1.9.12 + +### Patch Changes + +- indexer: update rpc bindings +- provider: signMessage: Serialize the BytesLike or string message into hexstring before sending +- waas: SessionAuthProof +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.9.12 + - @0xsequence/core@1.9.12 + - @0xsequence/utils@1.9.12 + +## 1.9.11 + +### Patch Changes + +- metdata, update rpc bindings +- Updated dependencies + - @0xsequence/abi@1.9.11 + - @0xsequence/core@1.9.11 + - @0xsequence/utils@1.9.11 + +## 1.9.10 + +### Patch Changes + +- update metadata rpc bindings +- Updated dependencies + - @0xsequence/abi@1.9.10 + - @0xsequence/core@1.9.10 + - @0xsequence/utils@1.9.10 + +## 1.9.9 + +### Patch Changes + +- metadata, add SequenceCollections rpc client +- Updated dependencies + - @0xsequence/abi@1.9.9 + - @0xsequence/core@1.9.9 + - @0xsequence/utils@1.9.9 + +## 1.9.8 + +### Patch Changes + +- waas client update +- Updated dependencies + - @0xsequence/abi@1.9.8 + - @0xsequence/core@1.9.8 + - @0xsequence/utils@1.9.8 + +## 1.9.7 + +### Patch Changes + +- update rpc client bindings for api, metadata and relayer +- Updated dependencies + - @0xsequence/abi@1.9.7 + - @0xsequence/core@1.9.7 + - @0xsequence/utils@1.9.7 + +## 1.9.6 + +### Patch Changes + +- waas package update +- Updated dependencies + - @0xsequence/abi@1.9.6 + - @0xsequence/core@1.9.6 + - @0xsequence/utils@1.9.6 + +## 1.9.5 + +### Patch Changes + +- RpcRelayer prioritize project access key +- Updated dependencies + - @0xsequence/abi@1.9.5 + - @0xsequence/core@1.9.5 + - @0xsequence/utils@1.9.5 + +## 1.9.4 + +### Patch Changes + +- waas: fix network dependency +- Updated dependencies + - @0xsequence/abi@1.9.4 + - @0xsequence/core@1.9.4 + - @0xsequence/utils@1.9.4 + +## 1.9.3 + +### Patch Changes + +- provider: don't append access key to RPC url if user has already provided it +- Updated dependencies + - @0xsequence/abi@1.9.3 + - @0xsequence/core@1.9.3 + - @0xsequence/utils@1.9.3 + +## 1.9.2 + +### Patch Changes + +- network: add xai-sepolia +- Updated dependencies + - @0xsequence/abi@1.9.2 + - @0xsequence/core@1.9.2 + - @0xsequence/utils@1.9.2 + +## 1.9.1 + +### Patch Changes + +- analytics fix +- Updated dependencies + - @0xsequence/abi@1.9.1 + - @0xsequence/core@1.9.1 + - @0xsequence/utils@1.9.1 + +## 1.9.0 + +### Minor Changes + +- waas release + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.9.0 + - @0xsequence/core@1.9.0 + - @0xsequence/utils@1.9.0 + +## 1.8.8 + +### Patch Changes + +- update metadata bindings +- Updated dependencies + - @0xsequence/abi@1.8.8 + - @0xsequence/core@1.8.8 + - @0xsequence/utils@1.8.8 + +## 1.8.7 + +### Patch Changes + +- provider: update databeat to 0.9.1 +- Updated dependencies + - @0xsequence/abi@1.8.7 + - @0xsequence/core@1.8.7 + - @0xsequence/utils@1.8.7 + +## 1.8.6 + +### Patch Changes + +- guard: SignedOwnershipProof +- Updated dependencies + - @0xsequence/abi@1.8.6 + - @0xsequence/core@1.8.6 + - @0xsequence/utils@1.8.6 + +## 1.8.5 + +### Patch Changes + +- guard: signOwnershipProof and isSignedOwnershipProof +- Updated dependencies + - @0xsequence/abi@1.8.5 + - @0xsequence/core@1.8.5 + - @0xsequence/utils@1.8.5 + +## 1.8.4 + +### Patch Changes + +- network: add homeverse to networks list +- Updated dependencies + - @0xsequence/abi@1.8.4 + - @0xsequence/core@1.8.4 + - @0xsequence/utils@1.8.4 + +## 1.8.3 + +### Patch Changes + +- api: introduce basic linked wallet support +- Updated dependencies + - @0xsequence/abi@1.8.3 + - @0xsequence/core@1.8.3 + - @0xsequence/utils@1.8.3 + +## 1.8.2 + +### Patch Changes + +- provider: don't initialize analytics unless explicitly requested +- Updated dependencies + - @0xsequence/abi@1.8.2 + - @0xsequence/core@1.8.2 + - @0xsequence/utils@1.8.2 + +## 1.8.1 + +### Patch Changes + +- update to analytics provider +- Updated dependencies + - @0xsequence/abi@1.8.1 + - @0xsequence/core@1.8.1 + - @0xsequence/utils@1.8.1 + +## 1.8.0 + +### Minor Changes + +- provider: project analytics + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.8.0 + - @0xsequence/core@1.8.0 + - @0xsequence/utils@1.8.0 + +## 1.7.2 + +### Patch Changes + +- 0xsequence: ChainId should not be exported as a type +- account, wallet: fix nonce selection +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.7.2 + - @0xsequence/core@1.7.2 + - @0xsequence/utils@1.7.2 + +## 1.7.1 + +### Patch Changes + +- network: add missing avalanche logoURI +- Updated dependencies + - @0xsequence/abi@1.7.1 + - @0xsequence/core@1.7.1 + - @0xsequence/utils@1.7.1 + +## 1.7.0 + +### Minor Changes + +- provider: projectAccessKey is now required + +### Patch Changes + +- network: add NetworkMetadata.logoURI property for all networks +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.7.0 + - @0xsequence/core@1.7.0 + - @0xsequence/utils@1.7.0 + +## 1.6.3 + +### Patch Changes + +- network list update +- Updated dependencies + - @0xsequence/abi@1.6.3 + - @0xsequence/core@1.6.3 + - @0xsequence/utils@1.6.3 + +## 1.6.2 + +### Patch Changes + +- auth: projectAccessKey option +- wallet: use 12 bytes for random space +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.6.2 + - @0xsequence/core@1.6.2 + - @0xsequence/utils@1.6.2 + +## 1.6.1 + +### Patch Changes + +- core: add simple config from subdigest support +- core: fix encode tree with subdigest +- account: implement buildOnChainSignature on Account +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.6.1 + - @0xsequence/core@1.6.1 + - @0xsequence/utils@1.6.1 + +## 1.6.0 + +### Minor Changes + +- account, wallet: parallel transactions by default + +### Patch Changes + +- provider: emit disconnect on sign out +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.6.0 + - @0xsequence/core@1.6.0 + - @0xsequence/utils@1.6.0 + +## 1.5.0 + +### Minor Changes + +- signhub: add 'signing' signer status + +### Patch Changes + +- auth: Session.open: onAccountAddress callback +- account: allow empty transaction bundles +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.5.0 + - @0xsequence/core@1.5.0 + - @0xsequence/utils@1.5.0 + +## 1.4.9 + +### Patch Changes + +- rename SequenceMetadataClient to SequenceMetadata +- Updated dependencies + - @0xsequence/abi@1.4.9 + - @0xsequence/core@1.4.9 + - @0xsequence/utils@1.4.9 + +## 1.4.8 + +### Patch Changes + +- account: Account.getSigners +- Updated dependencies + - @0xsequence/abi@1.4.8 + - @0xsequence/core@1.4.8 + - @0xsequence/utils@1.4.8 + +## 1.4.7 + +### Patch Changes + +- update indexer client bindings +- Updated dependencies + - @0xsequence/abi@1.4.7 + - @0xsequence/core@1.4.7 + - @0xsequence/utils@1.4.7 + +## 1.4.6 + +### Patch Changes + +- - add sepolia networks, mark goerli as deprecated + - update indexer client bindings +- Updated dependencies + - @0xsequence/abi@1.4.6 + - @0xsequence/core@1.4.6 + - @0xsequence/utils@1.4.6 + +## 1.4.5 + +### Patch Changes + +- indexer/metadata: update client bindings +- auth: selectWallet with new address +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.4.5 + - @0xsequence/core@1.4.5 + - @0xsequence/utils@1.4.5 + +## 1.4.4 + +### Patch Changes + +- indexer: update bindings +- auth: handle jwt expiry +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.4.4 + - @0xsequence/core@1.4.4 + - @0xsequence/utils@1.4.4 + +## 1.4.3 + +### Patch Changes + +- guard: return active status from GuardSigner.getAuthMethods +- Updated dependencies + - @0xsequence/abi@1.4.3 + - @0xsequence/core@1.4.3 + - @0xsequence/utils@1.4.3 + +## 1.4.2 + +### Patch Changes + +- guard: update bindings +- Updated dependencies + - @0xsequence/abi@1.4.2 + - @0xsequence/core@1.4.2 + - @0xsequence/utils@1.4.2 + +## 1.4.1 + +### Patch Changes + +- network: remove unused networks +- signhub: orchestrator interface +- guard: auth methods interface +- guard: update bindings for pin and totp +- guard: no more retry logic +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.4.1 + - @0xsequence/core@1.4.1 + - @0xsequence/utils@1.4.1 + +## 1.4.0 + +### Minor Changes + +- project access key support + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.4.0 + - @0xsequence/core@1.4.0 + - @0xsequence/utils@1.4.0 + +## 1.3.0 + +### Minor Changes + +- signhub: account children + +### Patch Changes + +- guard: do not throw when building deploy transaction +- network: snowtrace.io -> subnets.avax.network/c-chain +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.3.0 + - @0xsequence/core@1.3.0 + - @0xsequence/utils@1.3.0 + +## 1.2.9 + +### Patch Changes + +- account: AccountSigner.sendTransaction simulateForFeeOptions +- relayer: update bindings +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.2.9 + - @0xsequence/core@1.2.9 + - @0xsequence/utils@1.2.9 + +## 1.2.8 + +### Patch Changes + +- rename X-Sequence-Token-Key header to X-Access-Key +- Updated dependencies + - @0xsequence/abi@1.2.8 + - @0xsequence/core@1.2.8 + - @0xsequence/utils@1.2.8 + +## 1.2.7 + +### Patch Changes + +- add x-sequence-token-key to clients +- Updated dependencies + - @0xsequence/abi@1.2.7 + - @0xsequence/core@1.2.7 + - @0xsequence/utils@1.2.7 + +## 1.2.6 + +### Patch Changes + +- Fix bind multicall provider +- Updated dependencies + - @0xsequence/abi@1.2.6 + - @0xsequence/core@1.2.6 + - @0xsequence/utils@1.2.6 + +## 1.2.5 + +### Patch Changes + +- Multicall default configuration fixes +- Updated dependencies + - @0xsequence/abi@1.2.5 + - @0xsequence/core@1.2.5 + - @0xsequence/utils@1.2.5 + +## 1.2.4 + +### Patch Changes + +- provider: Adding missing payment provider types to PaymentProviderOption +- provider: WalletRequestHandler.notifyChainChanged +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.2.4 + - @0xsequence/core@1.2.4 + - @0xsequence/utils@1.2.4 + +## 1.2.3 + +### Patch Changes + +- auth, provider: connect to accept optional authorizeNonce +- Updated dependencies + - @0xsequence/abi@1.2.3 + - @0xsequence/core@1.2.3 + - @0xsequence/utils@1.2.3 + +## 1.2.2 + +### Patch Changes + +- provider: allow createContract calls +- core: check for explicit zero address in contract deployments +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.2.2 + - @0xsequence/core@1.2.2 + - @0xsequence/utils@1.2.2 + +## 1.2.1 + +### Patch Changes + +- auth: use sequence api chain id as reference chain id if available +- Updated dependencies + - @0xsequence/abi@1.2.1 + - @0xsequence/core@1.2.1 + - @0xsequence/utils@1.2.1 + +## 1.2.0 + +### Minor Changes + +- split services from session, better local support + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.2.0 + - @0xsequence/core@1.2.0 + - @0xsequence/utils@1.2.0 + +## 1.1.15 + +### Patch Changes + +- guard: remove error filtering +- Updated dependencies + - @0xsequence/abi@1.1.15 + - @0xsequence/core@1.1.15 + - @0xsequence/utils@1.1.15 + +## 1.1.14 + +### Patch Changes + +- guard: add GuardSigner.onError +- Updated dependencies + - @0xsequence/abi@1.1.14 + - @0xsequence/core@1.1.14 + - @0xsequence/utils@1.1.14 + +## 1.1.13 + +### Patch Changes + +- provider: pass client version with connect options +- provider: removing large from BannerSize +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.1.13 + - @0xsequence/core@1.1.13 + - @0xsequence/utils@1.1.13 + +## 1.1.12 + +### Patch Changes + +- provider: adding bannerSize to ConnectOptions +- Updated dependencies + - @0xsequence/abi@1.1.12 + - @0xsequence/core@1.1.12 + - @0xsequence/utils@1.1.12 + +## 1.1.11 + +### Patch Changes + +- add homeverse configs +- Updated dependencies + - @0xsequence/abi@1.1.11 + - @0xsequence/core@1.1.11 + - @0xsequence/utils@1.1.11 + +## 1.1.10 + +### Patch Changes + +- handle default EIP6492 on send +- Updated dependencies + - @0xsequence/abi@1.1.10 + - @0xsequence/core@1.1.10 + - @0xsequence/utils@1.1.10 + +## 1.1.9 + +### Patch Changes + +- Custom default EIP6492 on client +- Updated dependencies + - @0xsequence/abi@1.1.9 + - @0xsequence/core@1.1.9 + - @0xsequence/utils@1.1.9 + +## 1.1.8 + +### Patch Changes + +- metadata: searchMetadata: add types filter +- Updated dependencies + - @0xsequence/abi@1.1.8 + - @0xsequence/core@1.1.8 + - @0xsequence/utils@1.1.8 + +## 1.1.7 + +### Patch Changes + +- adding signInWith connect settings option to allow dapps to automatically login their users with a certain provider optimizing the normal authentication flow +- Updated dependencies + - @0xsequence/abi@1.1.7 + - @0xsequence/core@1.1.7 + - @0xsequence/utils@1.1.7 + +## 1.1.6 + +### Patch Changes + +- metadata: searchMetadata: add chainID and excludeTokenMetadata filters +- Updated dependencies + - @0xsequence/abi@1.1.6 + - @0xsequence/core@1.1.6 + - @0xsequence/utils@1.1.6 + +## 1.1.5 + +### Patch Changes + +- account: re-compute meta-transaction id for wallet deployment transactions +- Updated dependencies + - @0xsequence/abi@1.1.5 + - @0xsequence/core@1.1.5 + - @0xsequence/utils@1.1.5 + +## 1.1.4 + +### Patch Changes + +- network: rename base-mainnet to base +- provider: override isDefaultChain with ConnectOptions.networkId if provided +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.1.4 + - @0xsequence/core@1.1.4 + - @0xsequence/utils@1.1.4 + +## 1.1.3 + +### Patch Changes + +- provider: use network id from transport session +- provider: sign authorization using ConnectOptions.networkId if provided +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.1.3 + - @0xsequence/core@1.1.3 + - @0xsequence/utils@1.1.3 + +## 1.1.2 + +### Patch Changes + +- provider: jsonrpc chain id fixes +- Updated dependencies + - @0xsequence/abi@1.1.2 + - @0xsequence/core@1.1.2 + - @0xsequence/utils@1.1.2 + +## 1.1.1 + +### Patch Changes + +- network: add base mainnet and sepolia +- provider: reject toxic transaction requests +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.1.1 + - @0xsequence/core@1.1.1 + - @0xsequence/utils@1.1.1 + +## 1.1.0 + +### Minor Changes + +- Refactor dapp facing provider + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.1.0 + - @0xsequence/core@1.1.0 + - @0xsequence/utils@1.1.0 + +## 1.0.5 + +### Patch Changes + +- network: export network constants +- guard: use the correct global for fetch +- network: nova-explorer.arbitrum.io -> nova.arbiscan.io +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.0.5 + - @0xsequence/core@1.0.5 + - @0xsequence/utils@1.0.5 + +## 1.0.4 + +### Patch Changes + +- provider: accept name or number for networkId +- Updated dependencies + - @0xsequence/abi@1.0.4 + - @0xsequence/core@1.0.4 + - @0xsequence/utils@1.0.4 + +## 1.0.3 + +### Patch Changes + +- Simpler isValidSignature helpers +- Updated dependencies + - @0xsequence/abi@1.0.3 + - @0xsequence/core@1.0.3 + - @0xsequence/utils@1.0.3 + +## 1.0.2 + +### Patch Changes + +- add extra signature validation utils methods +- Updated dependencies + - @0xsequence/abi@1.0.2 + - @0xsequence/core@1.0.2 + - @0xsequence/utils@1.0.2 + +## 1.0.1 + +### Patch Changes + +- add homeverse testnet +- Updated dependencies + - @0xsequence/abi@1.0.1 + - @0xsequence/core@1.0.1 + - @0xsequence/utils@1.0.1 + +## 1.0.0 + +### Major Changes + +- https://sequence.xyz/blog/sequence-wallet-light-state-sync-full-merkle-wallets + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.0.0 + - @0xsequence/core@1.0.0 + - @0xsequence/utils@1.0.0 + +## 0.43.34 + +### Patch Changes + +- auth: no jwt for indexer +- Updated dependencies + - @0xsequence/abi@0.43.34 + - @0xsequence/config@0.43.34 + - @0xsequence/network@0.43.34 + - @0xsequence/transactions@0.43.34 + - @0xsequence/utils@0.43.34 + +## 0.43.33 + +### Patch Changes + +- Adding onConnectOptionsChange handler to WalletRequestHandler +- Updated dependencies + - @0xsequence/abi@0.43.33 + - @0xsequence/config@0.43.33 + - @0xsequence/network@0.43.33 + - @0xsequence/transactions@0.43.33 + - @0xsequence/utils@0.43.33 + +## 0.43.32 + +### Patch Changes + +- add Base Goerli network +- Updated dependencies + - @0xsequence/abi@0.43.32 + - @0xsequence/config@0.43.32 + - @0xsequence/network@0.43.32 + - @0xsequence/transactions@0.43.32 + - @0xsequence/utils@0.43.32 + +## 0.43.31 + +### Patch Changes + +- remove AuxDataProvider, add promptSignInConnect +- Updated dependencies + - @0xsequence/abi@0.43.31 + - @0xsequence/config@0.43.31 + - @0xsequence/network@0.43.31 + - @0xsequence/transactions@0.43.31 + - @0xsequence/utils@0.43.31 + +## 0.43.30 + +### Patch Changes + +- add arbitrum goerli testnet +- Updated dependencies + - @0xsequence/abi@0.43.30 + - @0xsequence/config@0.43.30 + - @0xsequence/network@0.43.30 + - @0xsequence/transactions@0.43.30 + - @0xsequence/utils@0.43.30 + +## 0.43.29 + +### Patch Changes + +- provider: check availability of window object +- Updated dependencies + - @0xsequence/abi@0.43.29 + - @0xsequence/config@0.43.29 + - @0xsequence/network@0.43.29 + - @0xsequence/transactions@0.43.29 + - @0xsequence/utils@0.43.29 + +## 0.43.28 + +### Patch Changes + +- update api bindings +- Updated dependencies + - @0xsequence/abi@0.43.28 + - @0xsequence/config@0.43.28 + - @0xsequence/network@0.43.28 + - @0xsequence/transactions@0.43.28 + - @0xsequence/utils@0.43.28 + +## 0.43.27 + +### Patch Changes + +- Add rpc is sequence method +- Updated dependencies + - @0xsequence/abi@0.43.27 + - @0xsequence/config@0.43.27 + - @0xsequence/network@0.43.27 + - @0xsequence/transactions@0.43.27 + - @0xsequence/utils@0.43.27 + +## 0.43.26 + +### Patch Changes + +- add zkevm url to enum +- Updated dependencies + - @0xsequence/abi@0.43.26 + - @0xsequence/config@0.43.26 + - @0xsequence/network@0.43.26 + - @0xsequence/transactions@0.43.26 + - @0xsequence/utils@0.43.26 + +## 0.43.25 + +### Patch Changes + +- added polygon zkevm to mainnet networks +- Updated dependencies + - @0xsequence/abi@0.43.25 + - @0xsequence/config@0.43.25 + - @0xsequence/network@0.43.25 + - @0xsequence/transactions@0.43.25 + - @0xsequence/utils@0.43.25 + +## 0.43.24 + +### Patch Changes + +- name change from zkevm to polygon-zkevm +- Updated dependencies + - @0xsequence/abi@0.43.24 + - @0xsequence/config@0.43.24 + - @0xsequence/network@0.43.24 + - @0xsequence/transactions@0.43.24 + - @0xsequence/utils@0.43.24 + +## 0.43.23 + +### Patch Changes + +- update zkEVM name to Polygon zkEVM +- Updated dependencies + - @0xsequence/abi@0.43.23 + - @0xsequence/config@0.43.23 + - @0xsequence/network@0.43.23 + - @0xsequence/transactions@0.43.23 + - @0xsequence/utils@0.43.23 + +## 0.43.22 + +### Patch Changes + +- add zkevm chain +- Updated dependencies + - @0xsequence/abi@0.43.22 + - @0xsequence/config@0.43.22 + - @0xsequence/network@0.43.22 + - @0xsequence/transactions@0.43.22 + - @0xsequence/utils@0.43.22 + +## 0.43.21 + +### Patch Changes + +- api: update client bindings +- Updated dependencies + - @0xsequence/abi@0.43.21 + - @0xsequence/config@0.43.21 + - @0xsequence/network@0.43.21 + - @0xsequence/transactions@0.43.21 + - @0xsequence/utils@0.43.21 + +## 0.43.20 + +### Patch Changes + +- indexer: update bindings +- Updated dependencies + - @0xsequence/abi@0.43.20 + - @0xsequence/config@0.43.20 + - @0xsequence/network@0.43.20 + - @0xsequence/transactions@0.43.20 + - @0xsequence/utils@0.43.20 + +## 0.43.19 + +### Patch Changes + +- session proof update +- Updated dependencies + - @0xsequence/abi@0.43.19 + - @0xsequence/config@0.43.19 + - @0xsequence/network@0.43.19 + - @0xsequence/transactions@0.43.19 + - @0xsequence/utils@0.43.19 + +## 0.43.18 + +### Patch Changes + +- rpc client global check, hardening +- Updated dependencies + - @0xsequence/abi@0.43.18 + - @0xsequence/config@0.43.18 + - @0xsequence/network@0.43.18 + - @0xsequence/transactions@0.43.18 + - @0xsequence/utils@0.43.18 + +## 0.43.17 + +### Patch Changes + +- rpc clients, check of 'global' is defined +- Updated dependencies + - @0xsequence/abi@0.43.17 + - @0xsequence/config@0.43.17 + - @0xsequence/network@0.43.17 + - @0xsequence/transactions@0.43.17 + - @0xsequence/utils@0.43.17 + +## 0.43.16 + +### Patch Changes + +- ethers peerDep to v5, update rpc client global use +- Updated dependencies + - @0xsequence/abi@0.43.16 + - @0xsequence/config@0.43.16 + - @0xsequence/network@0.43.16 + - @0xsequence/transactions@0.43.16 + - @0xsequence/utils@0.43.16 + +## 0.43.15 + +### Patch Changes + +- - provider: expand receiver type on some util methods +- Updated dependencies + - @0xsequence/abi@0.43.15 + - @0xsequence/config@0.43.15 + - @0xsequence/network@0.43.15 + - @0xsequence/transactions@0.43.15 + - @0xsequence/utils@0.43.15 + +## 0.43.14 + +### Patch Changes + +- bump +- Updated dependencies + - @0xsequence/abi@0.43.14 + - @0xsequence/config@0.43.14 + - @0xsequence/network@0.43.14 + - @0xsequence/transactions@0.43.14 + - @0xsequence/utils@0.43.14 + +## 0.43.13 + +### Patch Changes + +- update rpc bindings +- Updated dependencies + - @0xsequence/abi@0.43.13 + - @0xsequence/config@0.43.13 + - @0xsequence/network@0.43.13 + - @0xsequence/transactions@0.43.13 + - @0xsequence/utils@0.43.13 + +## 0.43.12 + +### Patch Changes + +- provider: single wallet init, and add new unregisterWallet() method +- Updated dependencies + - @0xsequence/abi@0.43.12 + - @0xsequence/config@0.43.12 + - @0xsequence/network@0.43.12 + - @0xsequence/transactions@0.43.12 + - @0xsequence/utils@0.43.12 + +## 0.43.11 + +### Patch Changes + +- fix lockfiles +- re-add mocha type deleter +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.43.11 + - @0xsequence/config@0.43.11 + - @0xsequence/network@0.43.11 + - @0xsequence/transactions@0.43.11 + - @0xsequence/utils@0.43.11 + +## 0.43.10 + +### Patch Changes + +- various improvements +- Updated dependencies + - @0xsequence/abi@0.43.10 + - @0xsequence/config@0.43.10 + - @0xsequence/network@0.43.10 + - @0xsequence/transactions@0.43.10 + - @0xsequence/utils@0.43.10 + +## 0.43.9 + +### Patch Changes + +- update deps +- Updated dependencies + - @0xsequence/abi@0.43.9 + - @0xsequence/config@0.43.9 + - @0xsequence/network@0.43.9 + - @0xsequence/transactions@0.43.9 + - @0xsequence/utils@0.43.9 + +## 0.43.8 + +### Patch Changes + +- network: JsonRpcProvider with caching +- Updated dependencies + - @0xsequence/abi@0.43.8 + - @0xsequence/config@0.43.8 + - @0xsequence/network@0.43.8 + - @0xsequence/transactions@0.43.8 + - @0xsequence/utils@0.43.8 + +## 0.43.7 + +### Patch Changes + +- provider: fix wallet network init +- Updated dependencies + - @0xsequence/abi@0.43.7 + - @0xsequence/config@0.43.7 + - @0xsequence/network@0.43.7 + - @0xsequence/transactions@0.43.7 + - @0xsequence/utils@0.43.7 + +## 0.43.6 + +### Patch Changes + +- metadatata: update rpc bindings +- Updated dependencies + - @0xsequence/abi@0.43.6 + - @0xsequence/config@0.43.6 + - @0xsequence/network@0.43.6 + - @0xsequence/transactions@0.43.6 + - @0xsequence/utils@0.43.6 + +## 0.43.5 + +### Patch Changes + +- provider: do not set default network for connect messages +- provider: forward missing error message +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.43.5 + - @0xsequence/config@0.43.5 + - @0xsequence/network@0.43.5 + - @0xsequence/transactions@0.43.5 + - @0xsequence/utils@0.43.5 + +## 0.43.4 + +### Patch Changes + +- no-change version bump to fix incorrectly tagged snapshot build +- Updated dependencies + - @0xsequence/abi@0.43.4 + - @0xsequence/config@0.43.4 + - @0xsequence/network@0.43.4 + - @0xsequence/transactions@0.43.4 + - @0xsequence/utils@0.43.4 + +## 0.43.3 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/abi@0.43.3 + - @0xsequence/config@0.43.3 + - @0xsequence/network@0.43.3 + - @0xsequence/transactions@0.43.3 + - @0xsequence/utils@0.43.3 + +## 0.43.2 + +### Patch Changes + +- provider: implement connectUnchecked +- Updated dependencies + - @0xsequence/abi@0.43.2 + - @0xsequence/config@0.43.2 + - @0xsequence/network@0.43.2 + - @0xsequence/transactions@0.43.2 + - @0xsequence/utils@0.43.2 + +## 0.43.1 + +### Patch Changes + +- update to latest ethauth dep +- Updated dependencies + - @0xsequence/abi@0.43.1 + - @0xsequence/config@0.43.1 + - @0xsequence/network@0.43.1 + - @0xsequence/transactions@0.43.1 + - @0xsequence/utils@0.43.1 + +## 0.43.0 + +### Minor Changes + +- move ethers to a peer dependency + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.43.0 + - @0xsequence/config@0.43.0 + - @0xsequence/network@0.43.0 + - @0xsequence/transactions@0.43.0 + - @0xsequence/utils@0.43.0 + +## 0.42.10 + +### Patch Changes + +- add auxDataProvider +- Updated dependencies + - @0xsequence/abi@0.42.10 + - @0xsequence/config@0.42.10 + - @0xsequence/network@0.42.10 + - @0xsequence/transactions@0.42.10 + - @0xsequence/utils@0.42.10 + +## 0.42.9 + +### Patch Changes + +- provider: add eip-191 exceptions +- Updated dependencies + - @0xsequence/abi@0.42.9 + - @0xsequence/config@0.42.9 + - @0xsequence/network@0.42.9 + - @0xsequence/transactions@0.42.9 + - @0xsequence/utils@0.42.9 + +## 0.42.8 + +### Patch Changes + +- provider: skip setting intent origin if we're unity plugin +- Updated dependencies + - @0xsequence/abi@0.42.8 + - @0xsequence/config@0.42.8 + - @0xsequence/network@0.42.8 + - @0xsequence/transactions@0.42.8 + - @0xsequence/utils@0.42.8 + +## 0.42.7 + +### Patch Changes + +- Add sign in options to connection settings +- Updated dependencies + - @0xsequence/abi@0.42.7 + - @0xsequence/config@0.42.7 + - @0xsequence/network@0.42.7 + - @0xsequence/transactions@0.42.7 + - @0xsequence/utils@0.42.7 + +## 0.42.6 + +### Patch Changes + +- api bindings update +- Updated dependencies + - @0xsequence/abi@0.42.6 + - @0xsequence/config@0.42.6 + - @0xsequence/network@0.42.6 + - @0xsequence/transactions@0.42.6 + - @0xsequence/utils@0.42.6 + +## 0.42.5 + +### Patch Changes + +- relayer: don't treat missing receipt as hard failure +- Updated dependencies + - @0xsequence/abi@0.42.5 + - @0xsequence/config@0.42.5 + - @0xsequence/network@0.42.5 + - @0xsequence/transactions@0.42.5 + - @0xsequence/utils@0.42.5 + +## 0.42.4 + +### Patch Changes + +- provider: add custom app protocol to connect options +- Updated dependencies + - @0xsequence/abi@0.42.4 + - @0xsequence/config@0.42.4 + - @0xsequence/network@0.42.4 + - @0xsequence/transactions@0.42.4 + - @0xsequence/utils@0.42.4 + +## 0.42.3 + +### Patch Changes + +- update api bindings +- Updated dependencies + - @0xsequence/abi@0.42.3 + - @0xsequence/config@0.42.3 + - @0xsequence/network@0.42.3 + - @0xsequence/transactions@0.42.3 + - @0xsequence/utils@0.42.3 + +## 0.42.2 + +### Patch Changes + +- disable rinkeby network +- Updated dependencies + - @0xsequence/abi@0.42.2 + - @0xsequence/config@0.42.2 + - @0xsequence/network@0.42.2 + - @0xsequence/transactions@0.42.2 + - @0xsequence/utils@0.42.2 + +## 0.42.1 + +### Patch Changes + +- wallet: optional waitForReceipt parameter +- Updated dependencies + - @0xsequence/abi@0.42.1 + - @0xsequence/config@0.42.1 + - @0xsequence/network@0.42.1 + - @0xsequence/transactions@0.42.1 + - @0xsequence/utils@0.42.1 + +## 0.42.0 + +### Minor Changes + +- relayer: estimateGasLimits -> simulate +- add simulator package + +### Patch Changes + +- transactions: fix flattenAuxTransactions +- provider: only filter nullish values +- provider: re-map transaction 'gas' back to 'gasLimit' +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.42.0 + - @0xsequence/config@0.42.0 + - @0xsequence/network@0.42.0 + - @0xsequence/transactions@0.42.0 + - @0xsequence/utils@0.42.0 + +## 0.41.3 + +### Patch Changes + +- api bindings update +- Updated dependencies + - @0xsequence/abi@0.41.3 + - @0xsequence/config@0.41.3 + - @0xsequence/network@0.41.3 + - @0xsequence/transactions@0.41.3 + - @0xsequence/utils@0.41.3 + +## 0.41.2 + +### Patch Changes + +- api bindings update +- Updated dependencies + - @0xsequence/abi@0.41.2 + - @0xsequence/config@0.41.2 + - @0xsequence/network@0.41.2 + - @0xsequence/transactions@0.41.2 + - @0xsequence/utils@0.41.2 + +## 0.41.1 + +### Patch Changes + +- update default networks +- Updated dependencies + - @0xsequence/abi@0.41.1 + - @0xsequence/config@0.41.1 + - @0xsequence/network@0.41.1 + - @0xsequence/transactions@0.41.1 + - @0xsequence/utils@0.41.1 + +## 0.41.0 + +### Minor Changes + +- relayer: fix Relayer.wait() interface + + The interface for calling Relayer.wait() has changed. Instead of a single optional ill-defined timeout/delay parameter, there are three optional parameters, in order: + + - timeout: the maximum time to wait for the transaction receipt + - delay: the polling interval, i.e. the time to wait between requests + - maxFails: the maximum number of hard failures to tolerate before giving up + + Please update your codebase accordingly. + +- relayer: add optional waitForReceipt parameter to Relayer.relay + + The behaviour of Relayer.relay() was not well-defined with respect to whether or not it waited for a receipt. + This change allows the caller to specify whether to wait or not, with the default behaviour being to wait. + +### Patch Changes + +- relayer: wait receipt retry logic +- fix wrapped object error +- provider: forward delegateCall and revertOnError transaction fields +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.41.0 + - @0xsequence/config@0.41.0 + - @0xsequence/network@0.41.0 + - @0xsequence/transactions@0.41.0 + - @0xsequence/utils@0.41.0 + +## 0.40.6 + +### Patch Changes + +- add arbitrum-nova chain +- Updated dependencies + - @0xsequence/abi@0.40.6 + - @0xsequence/config@0.40.6 + - @0xsequence/network@0.40.6 + - @0xsequence/transactions@0.40.6 + - @0xsequence/utils@0.40.6 + +## 0.40.5 + +### Patch Changes + +- api: update bindings +- Updated dependencies + - @0xsequence/abi@0.40.5 + - @0xsequence/config@0.40.5 + - @0xsequence/network@0.40.5 + - @0xsequence/transactions@0.40.5 + - @0xsequence/utils@0.40.5 + +## 0.40.4 + +### Patch Changes + +- add unreal transport +- Updated dependencies + - @0xsequence/abi@0.40.4 + - @0xsequence/config@0.40.4 + - @0xsequence/network@0.40.4 + - @0xsequence/transactions@0.40.4 + - @0xsequence/utils@0.40.4 + +## 0.40.3 + +### Patch Changes + +- provider: fix MessageToSign message type +- Updated dependencies + - @0xsequence/abi@0.40.3 + - @0xsequence/config@0.40.3 + - @0xsequence/network@0.40.3 + - @0xsequence/transactions@0.40.3 + - @0xsequence/utils@0.40.3 + +## 0.40.2 + +### Patch Changes + +- Wallet provider, loadSession method +- Updated dependencies + - @0xsequence/abi@0.40.2 + - @0xsequence/config@0.40.2 + - @0xsequence/network@0.40.2 + - @0xsequence/transactions@0.40.2 + - @0xsequence/utils@0.40.2 + +## 0.40.1 + +### Patch Changes + +- export sequence.initWallet and sequence.getWallet +- Updated dependencies + - @0xsequence/abi@0.40.1 + - @0xsequence/config@0.40.1 + - @0xsequence/network@0.40.1 + - @0xsequence/transactions@0.40.1 + - @0xsequence/utils@0.40.1 + +## 0.40.0 + +### Minor Changes + +- add sequence.initWallet(network, config) and sequence.getWallet() helper methods + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.40.0 + - @0xsequence/config@0.40.0 + - @0xsequence/network@0.40.0 + - @0xsequence/transactions@0.40.0 + - @0xsequence/utils@0.40.0 + +## 0.39.6 + +### Patch Changes + +- indexer: update client bindings +- Updated dependencies + - @0xsequence/abi@0.39.6 + - @0xsequence/config@0.39.6 + - @0xsequence/network@0.39.6 + - @0xsequence/transactions@0.39.6 + - @0xsequence/utils@0.39.6 + +## 0.39.5 + +### Patch Changes + +- provider: fix networkRpcUrl config option +- Updated dependencies + - @0xsequence/abi@0.39.5 + - @0xsequence/config@0.39.5 + - @0xsequence/network@0.39.5 + - @0xsequence/transactions@0.39.5 + - @0xsequence/utils@0.39.5 + +## 0.39.4 + +### Patch Changes + +- api: update client bindings +- Updated dependencies + - @0xsequence/abi@0.39.4 + - @0xsequence/config@0.39.4 + - @0xsequence/network@0.39.4 + - @0xsequence/transactions@0.39.4 + - @0xsequence/utils@0.39.4 + +## 0.39.3 + +### Patch Changes + +- add request method on Web3Provider +- Updated dependencies + - @0xsequence/abi@0.39.3 + - @0xsequence/config@0.39.3 + - @0xsequence/network@0.39.3 + - @0xsequence/transactions@0.39.3 + - @0xsequence/utils@0.39.3 + +## 0.39.2 + +### Patch Changes + +- update umd name +- Updated dependencies + - @0xsequence/abi@0.39.2 + - @0xsequence/config@0.39.2 + - @0xsequence/network@0.39.2 + - @0xsequence/transactions@0.39.2 + - @0xsequence/utils@0.39.2 + +## 0.39.1 + +### Patch Changes + +- add Aurora network +- add origin info for accountsChanged event to handle it per dapp +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.39.1 + - @0xsequence/config@0.39.1 + - @0xsequence/network@0.39.1 + - @0xsequence/transactions@0.39.1 + - @0xsequence/utils@0.39.1 + +## 0.39.0 + +### Minor Changes + +- abstract window.localStorage to interface type + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.39.0 + - @0xsequence/config@0.39.0 + - @0xsequence/network@0.39.0 + - @0xsequence/transactions@0.39.0 + - @0xsequence/utils@0.39.0 + +## 0.38.2 + +### Patch Changes + +- provider: add Settings.defaultPurchaseAmount +- Updated dependencies + - @0xsequence/abi@0.38.2 + - @0xsequence/config@0.38.2 + - @0xsequence/network@0.38.2 + - @0xsequence/transactions@0.38.2 + - @0xsequence/utils@0.38.2 + +## 0.38.1 + +### Patch Changes + +- update api and metadata rpc bindings +- Updated dependencies + - @0xsequence/abi@0.38.1 + - @0xsequence/config@0.38.1 + - @0xsequence/network@0.38.1 + - @0xsequence/transactions@0.38.1 + - @0xsequence/utils@0.38.1 + +## 0.38.0 + +### Minor Changes + +- api: update bindings, change TokenPrice interface +- bridge: remove @0xsequence/bridge package +- api: update bindings, rename ContractCallArg to TupleComponent + +### Patch Changes + +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.38.0 + - @0xsequence/config@0.38.0 + - @0xsequence/network@0.38.0 + - @0xsequence/transactions@0.38.0 + - @0xsequence/utils@0.38.0 + +## 0.37.1 + +### Patch Changes + +- Add back sortNetworks - Removing sorting was a breaking change for dapps on older versions which directly integrate sequence. +- Updated dependencies + - @0xsequence/abi@0.37.1 + - @0xsequence/config@0.37.1 + - @0xsequence/network@0.37.1 + - @0xsequence/transactions@0.37.1 + - @0xsequence/utils@0.37.1 + +## 0.37.0 + +### Minor Changes + +- network related fixes and improvements +- api: bindings: exchange rate lookups + +### Patch Changes + +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.37.0 + - @0xsequence/config@0.37.0 + - @0xsequence/network@0.37.0 + - @0xsequence/transactions@0.37.0 + - @0xsequence/utils@0.37.0 + +## 0.36.13 + +### Patch Changes + +- api: update bindings with new price endpoints +- Updated dependencies + - @0xsequence/abi@0.36.13 + - @0xsequence/config@0.36.13 + - @0xsequence/network@0.36.13 + - @0xsequence/transactions@0.36.13 + - @0xsequence/utils@0.36.13 + +## 0.36.12 + +### Patch Changes + +- wallet: skip remote signers if not needed +- auth: check that signature meets threshold before requesting auth token +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.36.12 + - @0xsequence/config@0.36.12 + - @0xsequence/network@0.36.12 + - @0xsequence/transactions@0.36.12 + - @0xsequence/utils@0.36.12 + +## 0.36.11 + +### Patch Changes + +- Prefix EIP191 message on wallet-request-handler +- Updated dependencies + - @0xsequence/abi@0.36.11 + - @0xsequence/config@0.36.11 + - @0xsequence/network@0.36.11 + - @0xsequence/transactions@0.36.11 + - @0xsequence/utils@0.36.11 + +## 0.36.10 + +### Patch Changes + +- support bannerUrl on connect +- Updated dependencies + - @0xsequence/abi@0.36.10 + - @0xsequence/config@0.36.10 + - @0xsequence/network@0.36.10 + - @0xsequence/transactions@0.36.10 + - @0xsequence/utils@0.36.10 + +## 0.36.9 + +### Patch Changes + +- minor dev xp improvements +- Updated dependencies + - @0xsequence/abi@0.36.9 + - @0xsequence/config@0.36.9 + - @0xsequence/network@0.36.9 + - @0xsequence/transactions@0.36.9 + - @0xsequence/utils@0.36.9 + +## 0.36.8 + +### Patch Changes + +- more connect options (theme, payment providers, funding currencies) +- Updated dependencies + - @0xsequence/abi@0.36.8 + - @0xsequence/config@0.36.8 + - @0xsequence/network@0.36.8 + - @0xsequence/transactions@0.36.8 + - @0xsequence/utils@0.36.8 + +## 0.36.7 + +### Patch Changes + +- fix missing break +- Updated dependencies + - @0xsequence/abi@0.36.7 + - @0xsequence/config@0.36.7 + - @0xsequence/network@0.36.7 + - @0xsequence/transactions@0.36.7 + - @0xsequence/utils@0.36.7 + +## 0.36.6 + +### Patch Changes + +- wallet_switchEthereumChain support +- Updated dependencies + - @0xsequence/abi@0.36.6 + - @0xsequence/config@0.36.6 + - @0xsequence/network@0.36.6 + - @0xsequence/transactions@0.36.6 + - @0xsequence/utils@0.36.6 + +## 0.36.5 + +### Patch Changes + +- auth: bump ethauth to 0.7.0 + network, wallet: don't assume position of auth network in list + api/indexer/metadata: trim trailing slash on hostname, and add endpoint urls + relayer: Allow to specify local relayer transaction parameters like gas price or gas limit +- Updated dependencies + - @0xsequence/abi@0.36.5 + - @0xsequence/config@0.36.5 + - @0xsequence/network@0.36.5 + - @0xsequence/transactions@0.36.5 + - @0xsequence/utils@0.36.5 + +## 0.36.4 + +### Patch Changes + +- Updating list of chain ids to include other ethereum compatible chains +- Updated dependencies + - @0xsequence/abi@0.36.4 + - @0xsequence/config@0.36.4 + - @0xsequence/network@0.36.4 + - @0xsequence/transactions@0.36.4 + - @0xsequence/utils@0.36.4 + +## 0.36.3 + +### Patch Changes + +- provider: pass connect options to prompter methods +- Updated dependencies + - @0xsequence/abi@0.36.3 + - @0xsequence/config@0.36.3 + - @0xsequence/network@0.36.3 + - @0xsequence/transactions@0.36.3 + - @0xsequence/utils@0.36.3 + +## 0.36.2 + +### Patch Changes + +- transactions: Setting target to 0x0 when empty to during SequenceTxAbiEncode +- Updated dependencies + - @0xsequence/abi@0.36.2 + - @0xsequence/config@0.36.2 + - @0xsequence/network@0.36.2 + - @0xsequence/transactions@0.36.2 + - @0xsequence/utils@0.36.2 + +## 0.36.1 + +### Patch Changes + +- metadata: update client with more fields +- Updated dependencies + - @0xsequence/abi@0.36.1 + - @0xsequence/config@0.36.1 + - @0xsequence/network@0.36.1 + - @0xsequence/transactions@0.36.1 + - @0xsequence/utils@0.36.1 + +## 0.36.0 + +### Minor Changes + +- relayer, wallet: fee quote support + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.36.0 + - @0xsequence/config@0.36.0 + - @0xsequence/network@0.36.0 + - @0xsequence/transactions@0.36.0 + - @0xsequence/utils@0.36.0 + +## 0.35.12 + +### Patch Changes + +- provider: rename wallet.commands to wallet.utils +- Updated dependencies + - @0xsequence/abi@0.35.12 + - @0xsequence/config@0.35.12 + - @0xsequence/network@0.35.12 + - @0xsequence/transactions@0.35.12 + - @0xsequence/utils@0.35.12 + +## 0.35.11 + +### Patch Changes + +- provider/utils: smoother message validation +- Updated dependencies + - @0xsequence/abi@0.35.11 + - @0xsequence/config@0.35.11 + - @0xsequence/network@0.35.11 + - @0xsequence/transactions@0.35.11 + - @0xsequence/utils@0.35.11 + +## 0.35.10 + +### Patch Changes + +- upgrade deps +- Updated dependencies + - @0xsequence/abi@0.35.10 + - @0xsequence/config@0.35.10 + - @0xsequence/network@0.35.10 + - @0xsequence/transactions@0.35.10 + - @0xsequence/utils@0.35.10 + +## 0.35.9 + +### Patch Changes + +- provider: window-transport override event handlers with new wallet instance +- Updated dependencies + - @0xsequence/abi@0.35.9 + - @0xsequence/config@0.35.9 + - @0xsequence/network@0.35.9 + - @0xsequence/transactions@0.35.9 + - @0xsequence/utils@0.35.9 + +## 0.35.8 + +### Patch Changes + +- provider: async wallet sign in improvements +- Updated dependencies + - @0xsequence/abi@0.35.8 + - @0xsequence/config@0.35.8 + - @0xsequence/network@0.35.8 + - @0xsequence/transactions@0.35.8 + - @0xsequence/utils@0.35.8 + +## 0.35.7 + +### Patch Changes + +- config: cache wallet configs +- Updated dependencies + - @0xsequence/abi@0.35.7 + - @0xsequence/config@0.35.7 + - @0xsequence/network@0.35.7 + - @0xsequence/transactions@0.35.7 + - @0xsequence/utils@0.35.7 + +## 0.35.6 + +### Patch Changes + +- provider: support async signin of wallet request handler +- Updated dependencies + - @0xsequence/abi@0.35.6 + - @0xsequence/config@0.35.6 + - @0xsequence/network@0.35.6 + - @0xsequence/transactions@0.35.6 + - @0xsequence/utils@0.35.6 + +## 0.35.5 + +### Patch Changes + +- wallet: skip threshold check during fee estimation +- Updated dependencies + - @0xsequence/abi@0.35.5 + - @0xsequence/config@0.35.5 + - @0xsequence/network@0.35.5 + - @0xsequence/transactions@0.35.5 + - @0xsequence/utils@0.35.5 + +## 0.35.4 + +### Patch Changes + +- - browser extension mode, center window +- Updated dependencies + - @0xsequence/abi@0.35.4 + - @0xsequence/config@0.35.4 + - @0xsequence/network@0.35.4 + - @0xsequence/transactions@0.35.4 + - @0xsequence/utils@0.35.4 + +## 0.35.3 + +### Patch Changes + +- - update window position when in browser extension mode +- Updated dependencies + - @0xsequence/abi@0.35.3 + - @0xsequence/config@0.35.3 + - @0xsequence/network@0.35.3 + - @0xsequence/transactions@0.35.3 + - @0xsequence/utils@0.35.3 + +## 0.35.2 + +### Patch Changes + +- - provider: WindowMessageHandler accept optional windowHref +- Updated dependencies + - @0xsequence/abi@0.35.2 + - @0xsequence/config@0.35.2 + - @0xsequence/network@0.35.2 + - @0xsequence/transactions@0.35.2 + - @0xsequence/utils@0.35.2 + +## 0.35.1 + +### Patch Changes + +- wallet: update config on undeployed too +- Updated dependencies + - @0xsequence/abi@0.35.1 + - @0xsequence/config@0.35.1 + - @0xsequence/network@0.35.1 + - @0xsequence/transactions@0.35.1 + - @0xsequence/utils@0.35.1 + +## 0.35.0 + +### Minor Changes + +- - config: add buildStubSignature + - provider: add checks to signing cases for wallet deployment and config statuses + - provider: add prompt for wallet deployment + - relayer: add BaseRelayer.prependWalletDeploy + - relayer: add Relayer.feeOptions + - relayer: account for wallet deployment in fee estimation + - transactions: add fromTransactionish + - wallet: add Account.prependConfigUpdate + - wallet: add Account.getFeeOptions + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.35.0 + - @0xsequence/config@0.35.0 + - @0xsequence/network@0.35.0 + - @0xsequence/transactions@0.35.0 + - @0xsequence/utils@0.35.0 + +## 0.34.0 + +### Minor Changes + +- - upgrade deps + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.34.0 + - @0xsequence/config@0.34.0 + - @0xsequence/network@0.34.0 + - @0xsequence/transactions@0.34.0 + - @0xsequence/utils@0.34.0 + +## 0.33.2 + +### Patch Changes + +- Updated dependencies + - @0xsequence/transactions@0.33.2 + +## 0.31.0 + +### Minor Changes + +- - upgrading to ethers v5.5 + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.31.0 + - @0xsequence/config@0.31.0 + - @0xsequence/network@0.31.0 + - @0xsequence/transactions@0.31.0 + - @0xsequence/utils@0.31.0 + +## 0.30.0 + +### Minor Changes + +- - upgrade most deps + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.30.0 + - @0xsequence/config@0.30.0 + - @0xsequence/network@0.30.0 + - @0xsequence/transactions@0.30.0 + - @0xsequence/utils@0.30.0 + +## 0.29.8 + +### Patch Changes + +- update api +- Updated dependencies [undefined] + - @0xsequence/abi@0.29.8 + - @0xsequence/config@0.29.8 + - @0xsequence/network@0.29.8 + - @0xsequence/transactions@0.29.8 + - @0xsequence/utils@0.29.8 + +## 0.29.6 + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/network@0.29.6 + - @0xsequence/config@0.29.6 + - @0xsequence/transactions@0.29.6 + +## 0.29.5 + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/config@0.29.5 + +## 0.29.0 + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/config@0.29.0 + - @0xsequence/network@0.29.0 + - @0xsequence/transactions@0.29.0 + - @0xsequence/abi@0.29.0 + - @0xsequence/utils@0.29.0 + +## 0.28.0 + +### Minor Changes + +- extension provider + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.28.0 + - @0xsequence/config@0.28.0 + - @0xsequence/network@0.28.0 + - @0xsequence/transactions@0.28.0 + - @0xsequence/utils@0.28.0 + +## 0.27.0 + +### Minor Changes + +- Add requireFreshSigner lib to sessions + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.27.0 + - @0xsequence/config@0.27.0 + - @0xsequence/network@0.27.0 + - @0xsequence/transactions@0.27.0 + - @0xsequence/utils@0.27.0 + +## 0.25.1 + +### Patch Changes + +- Fix build typescrypt issue +- Updated dependencies [undefined] + - @0xsequence/abi@0.25.1 + - @0xsequence/config@0.25.1 + - @0xsequence/network@0.25.1 + - @0xsequence/transactions@0.25.1 + - @0xsequence/utils@0.25.1 + +## 0.25.0 + +### Minor Changes + +- 10c8af8: Add estimator package + Fix multicall few calls bug + +### Patch Changes + +- Updated dependencies [10c8af8] + - @0xsequence/abi@0.25.0 + - @0xsequence/config@0.25.0 + - @0xsequence/network@0.25.0 + - @0xsequence/transactions@0.25.0 + - @0xsequence/utils@0.25.0 diff --git a/packages/estimator/package.json b/packages/estimator/package.json new file mode 100644 index 0000000000..5c03955558 --- /dev/null +++ b/packages/estimator/package.json @@ -0,0 +1,39 @@ +{ + "name": "@0xsequence/estimator", + "version": "2.0.0", + "description": "estimator sub-package for Sequence", + "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/estimator", + "source": "src/index.ts", + "main": "dist/0xsequence-estimator.cjs.js", + "module": "dist/0xsequence-estimator.esm.js", + "author": "Horizon Blockchain Games", + "license": "Apache-2.0", + "scripts": { + "test": "pnpm test:concurrently 'pnpm test:run'", + "test:run": "wait-on -t 120000 http-get://127.0.0.1:10045/ && pnpm test:file tests/**/*.spec.ts", + "test:file": "NODE_OPTIONS='--import tsx' mocha --timeout 30000", + "test:concurrently": "concurrently -k --success first 'pnpm start:geth > /dev/null'", + "start:geth": "docker run --rm -t -p 10045:10045 ethereum/client-go:v1.10.16 --http --http.addr 0.0.0.0 --http.port 10045 --datadir test_chain --dev --rpc.allow-unprotected-txs", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@0xsequence/abi": "workspace:*", + "@0xsequence/core": "workspace:*", + "@0xsequence/utils": "workspace:*", + "@0xsequence/wallet-contracts": "^1.10.0" + }, + "peerDependencies": { + "ethers": ">=5.5 < 6" + }, + "devDependencies": { + "@0xsequence/signhub": "workspace:*", + "@0xsequence/tests": "workspace:*", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "ethers": "^5.7.2" + }, + "files": [ + "src", + "dist" + ] +} diff --git a/packages/estimator/src/builds/MainModuleGasEstimation.ts b/packages/estimator/src/builds/MainModuleGasEstimation.ts new file mode 100644 index 0000000000..63e4b2fc4b --- /dev/null +++ b/packages/estimator/src/builds/MainModuleGasEstimation.ts @@ -0,0 +1,854 @@ +export const mainModuleGasEstimation = { + _format: 'hh-sol-artifact-1', + contractName: 'MainModuleGasEstimation', + sourceName: 'contracts/modules/MainModuleGasEstimation.sol', + abi: [ + { + inputs: [ + { + internalType: 'uint256', + name: '_space', + type: 'uint256' + }, + { + internalType: 'uint256', + name: '_provided', + type: 'uint256' + }, + { + internalType: 'uint256', + name: '_current', + type: 'uint256' + } + ], + name: 'BadNonce', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes4', + name: '_signature', + type: 'bytes4' + } + ], + name: 'HookAlreadyExists', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes4', + name: '_signature', + type: 'bytes4' + } + ], + name: 'HookDoesNotExist', + type: 'error' + }, + { + inputs: [], + name: 'ImageHashIsZero', + type: 'error' + }, + { + inputs: [ + { + internalType: 'address', + name: '_implementation', + type: 'address' + } + ], + name: 'InvalidImplementation', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_hash', + type: 'bytes32' + }, + { + internalType: 'address', + name: '_addr', + type: 'address' + }, + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + } + ], + name: 'InvalidNestedSignature', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + }, + { + internalType: 'bytes32', + name: '_s', + type: 'bytes32' + } + ], + name: 'InvalidSValue', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_hash', + type: 'bytes32' + }, + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + } + ], + name: 'InvalidSignature', + type: 'error' + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_flag', + type: 'uint256' + } + ], + name: 'InvalidSignatureFlag', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + } + ], + name: 'InvalidSignatureLength', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes1', + name: '_type', + type: 'bytes1' + } + ], + name: 'InvalidSignatureType', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + }, + { + internalType: 'uint256', + name: '_v', + type: 'uint256' + } + ], + name: 'InvalidVValue', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + }, + { + internalType: 'uint256', + name: 'threshold', + type: 'uint256' + }, + { + internalType: 'uint256', + name: '_weight', + type: 'uint256' + } + ], + name: 'LowWeightChainedSignature', + type: 'error' + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_index', + type: 'uint256' + }, + { + internalType: 'uint256', + name: '_requested', + type: 'uint256' + }, + { + internalType: 'uint256', + name: '_available', + type: 'uint256' + } + ], + name: 'NotEnoughGas', + type: 'error' + }, + { + inputs: [ + { + internalType: 'address', + name: '_sender', + type: 'address' + }, + { + internalType: 'address', + name: '_self', + type: 'address' + } + ], + name: 'OnlySelfAuth', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + } + ], + name: 'SignerIsAddress0', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + }, + { + internalType: 'uint256', + name: '_type', + type: 'uint256' + }, + { + internalType: 'bool', + name: '_recoverMode', + type: 'bool' + } + ], + name: 'UnsupportedSignatureType', + type: 'error' + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_current', + type: 'uint256' + }, + { + internalType: 'uint256', + name: '_prev', + type: 'uint256' + } + ], + name: 'WrongChainedCheckpointOrder', + type: 'error' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: '_contract', + type: 'address' + } + ], + name: 'CreatedContract', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'bytes32', + name: 'newImageHash', + type: 'bytes32' + } + ], + name: 'ImageHashUpdated', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'newImplementation', + type: 'address' + } + ], + name: 'ImplementationUpdated', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: '_space', + type: 'uint256' + }, + { + indexed: false, + internalType: 'uint256', + name: '_newNonce', + type: 'uint256' + } + ], + name: 'NonceChange', + type: 'event' + }, + { + anonymous: true, + inputs: [ + { + indexed: false, + internalType: 'bytes32', + name: '_tx', + type: 'bytes32' + } + ], + name: 'TxExecuted', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'bytes32', + name: '_tx', + type: 'bytes32' + }, + { + indexed: false, + internalType: 'bytes', + name: '_reason', + type: 'bytes' + } + ], + name: 'TxFailed', + type: 'event' + }, + { + stateMutability: 'payable', + type: 'fallback' + }, + { + inputs: [], + name: 'SET_IMAGE_HASH_TYPE_HASH', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes4', + name: '_signature', + type: 'bytes4' + }, + { + internalType: 'address', + name: '_implementation', + type: 'address' + } + ], + name: 'addHook', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_code', + type: 'bytes' + } + ], + name: 'createContract', + outputs: [ + { + internalType: 'address', + name: 'addr', + type: 'address' + } + ], + stateMutability: 'payable', + type: 'function' + }, + { + inputs: [ + { + components: [ + { + internalType: 'bool', + name: 'delegateCall', + type: 'bool' + }, + { + internalType: 'bool', + name: 'revertOnError', + type: 'bool' + }, + { + internalType: 'uint256', + name: 'gasLimit', + type: 'uint256' + }, + { + internalType: 'address', + name: 'target', + type: 'address' + }, + { + internalType: 'uint256', + name: 'value', + type: 'uint256' + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes' + } + ], + internalType: 'struct IModuleCalls.Transaction[]', + name: '_txs', + type: 'tuple[]' + }, + { + internalType: 'uint256', + name: '_nonce', + type: 'uint256' + }, + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + } + ], + name: 'execute', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [], + name: 'imageHash', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_hash', + type: 'bytes32' + }, + { + internalType: 'bytes', + name: '_signatures', + type: 'bytes' + } + ], + name: 'isValidSignature', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_data', + type: 'bytes' + }, + { + internalType: 'bytes', + name: '_signatures', + type: 'bytes' + } + ], + name: 'isValidSignature', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'nonce', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]' + }, + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]' + }, + { + internalType: 'bytes', + name: '', + type: 'bytes' + } + ], + name: 'onERC1155BatchReceived', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'uint256', + name: '', + type: 'uint256' + }, + { + internalType: 'uint256', + name: '', + type: 'uint256' + }, + { + internalType: 'bytes', + name: '', + type: 'bytes' + } + ], + name: 'onERC1155Received', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'uint256', + name: '', + type: 'uint256' + }, + { + internalType: 'bytes', + name: '', + type: 'bytes' + } + ], + name: 'onERC721Received', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes4', + name: '_signature', + type: 'bytes4' + } + ], + name: 'readHook', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_space', + type: 'uint256' + } + ], + name: 'readNonce', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes4', + name: '_signature', + type: 'bytes4' + } + ], + name: 'removeHook', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + components: [ + { + internalType: 'bool', + name: 'delegateCall', + type: 'bool' + }, + { + internalType: 'bool', + name: 'revertOnError', + type: 'bool' + }, + { + internalType: 'uint256', + name: 'gasLimit', + type: 'uint256' + }, + { + internalType: 'address', + name: 'target', + type: 'address' + }, + { + internalType: 'uint256', + name: 'value', + type: 'uint256' + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes' + } + ], + internalType: 'struct IModuleCalls.Transaction[]', + name: '_txs', + type: 'tuple[]' + } + ], + name: 'selfExecute', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_digest', + type: 'bytes32' + }, + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + } + ], + name: 'signatureRecovery', + outputs: [ + { + internalType: 'uint256', + name: 'threshold', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'weight', + type: 'uint256' + }, + { + internalType: 'bytes32', + name: 'imageHash', + type: 'bytes32' + }, + { + internalType: 'bytes32', + name: 'subDigest', + type: 'bytes32' + }, + { + internalType: 'uint256', + name: 'checkpoint', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes4', + name: '_interfaceID', + type: 'bytes4' + } + ], + name: 'supportsInterface', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool' + } + ], + stateMutability: 'pure', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_imageHash', + type: 'bytes32' + } + ], + name: 'updateImageHash', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '_implementation', + type: 'address' + } + ], + name: 'updateImplementation', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + stateMutability: 'payable', + type: 'receive' + } + ], + bytecode: + '0x608060405234801561001057600080fd5b50612daa806100206000396000f3fe6080604052600436106101485760003560e01c806357c56d6b116100c057806390042baf11610074578063b93ea7ad11610059578063b93ea7ad146104da578063bc197c81146104fa578063f23a6e61146105425761014f565b806390042baf146104b2578063affed0e0146104c55761014f565b80637a9a1628116100a55780637a9a16281461042a578063853c50681461044a5780638c3f5563146104925761014f565b806357c56d6b146103d657806361c2926c1461040a5761014f565b80631a9b23371161011757806329561426116100fc57806329561426146103735780634fcf3eca1461039357806351605d80146103b35761014f565b80631a9b23371461030e57806320c13b0b146103535761014f565b806301ffc9a714610223578063025b22bc14610258578063150b7a02146102785780631626ba7e146102ee5761014f565b3661014f57005b600061017e6000357fffffffff0000000000000000000000000000000000000000000000000000000016610588565b905073ffffffffffffffffffffffffffffffffffffffff811615610221576000808273ffffffffffffffffffffffffffffffffffffffff166000366040516101c79291906122da565b600060405180830381855af49150503d8060008114610202576040519150601f19603f3d011682016040523d82523d6000602084013e610207565b606091505b50915091508161021957805160208201fd5b805160208201f35b005b34801561022f57600080fd5b5061024361023e366004612318565b6105dc565b60405190151581526020015b60405180910390f35b34801561026457600080fd5b5061022161027336600461235e565b6105e7565b34801561028457600080fd5b506102bd6102933660046123c2565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff00000000000000000000000000000000000000000000000000000000909116815260200161024f565b3480156102fa57600080fd5b506102bd610309366004612431565b610639565b34801561031a57600080fd5b5061032e610329366004612318565b610686565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161024f565b34801561035f57600080fd5b506102bd61036e36600461247d565b610691565b34801561037f57600080fd5b5061022161038e3660046124e9565b6106f6565b34801561039f57600080fd5b506102216103ae366004612318565b610740565b3480156103bf57600080fd5b506103c861086f565b60405190815260200161024f565b3480156103e257600080fd5b506103c87f8713a7c4465f6fbee2b6e9d6646d1d9f83fec929edfc4baf661f3c865bdd04d181565b34801561041657600080fd5b50610221610425366004612547565b61089e565b34801561043657600080fd5b50610221610445366004612589565b610924565b34801561045657600080fd5b5061046a610465366004612431565b6109ba565b604080519586526020860194909452928401919091526060830152608082015260a00161024f565b34801561049e57600080fd5b506103c86104ad3660046124e9565b610b82565b61032e6104c0366004612621565b610bae565b3480156104d157600080fd5b506103c8610c4a565b3480156104e657600080fd5b506102216104f53660046126f0565b610c56565b34801561050657600080fd5b506102bd610515366004612725565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b34801561054e57600080fd5b506102bd61055d3660046127e0565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b60006105d67fbe27a319efc8734e89e26ba4bc95f5c788584163b959f03fa04e2d7ab4b9a1207fffffffff000000000000000000000000000000000000000000000000000000008416610d9b565b92915050565b60006105d682610df9565b33301461062d576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044015b60405180910390fd5b61063681610e55565b50565b600080610647858585610f10565b509050801561067957507f1626ba7e00000000000000000000000000000000000000000000000000000000905061067f565b50600090505b9392505050565b60006105d682610588565b6000806106b686866040516106a79291906122da565b60405180910390208585610f10565b50905080156106e857507f20c13b0b0000000000000000000000000000000000000000000000000000000090506106ee565b50600090505b949350505050565b333014610737576040517fe1258894000000000000000000000000000000000000000000000000000000008152336004820152306024820152604401610624565b61063681610f4e565b333014610781576040517fe1258894000000000000000000000000000000000000000000000000000000008152336004820152306024820152604401610624565b600061078c82610588565b73ffffffffffffffffffffffffffffffffffffffff16036107fd576040517f1c3812cc0000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000082166004820152602401610624565b604080517fbe27a319efc8734e89e26ba4bc95f5c788584163b959f03fa04e2d7ab4b9a1206020808301919091527fffffffff00000000000000000000000000000000000000000000000000000000841682840152825180830384018152606090920190925280519101206000905550565b60006108997fea7157fa25e3aa17d0ae2d5280fa4e24d421c61842aa85e45194e1145aa72bf85490565b905090565b3330146108df576040517fe1258894000000000000000000000000000000000000000000000000000000008152336004820152306024820152604401610624565b600061091283836040516020016108f7929190612a00565b60405160208183030381529060405280519060200120610fde565b905061091f818484611063565b505050565b61092d836111c1565b60008061096585888860405160200161094893929190612a48565b604051602081830303815290604052805190602001208585610f10565b91509150816109a6578084846040517f8f4a234f00000000000000000000000000000000000000000000000000000000815260040161062493929190612a6b565b6109b1818888611063565b50505050505050565b600080600080600080878760008181106109d6576109d6612a85565b909101357fff00000000000000000000000000000000000000000000000000000000000000169150819050610a2c57610a0e89610fde565b9250610a1b8389896112ca565b92985090965094509150610b779050565b7fff0000000000000000000000000000000000000000000000000000000000000081811601610a6b57610a5e89610fde565b9250610a1b83898961131b565b7ffe000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821601610abd57610a5e89611347565b7ffd000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821601610b2157610b118989896113b4565b9550955095509550955050610b77565b6040517f6085cd820000000000000000000000000000000000000000000000000000000081527fff0000000000000000000000000000000000000000000000000000000000000082166004820152602401610624565b939792965093509350565b60006105d67f8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e83610d9b565b6000333014610bf1576040517fe1258894000000000000000000000000000000000000000000000000000000008152336004820152306024820152604401610624565b81516020830134f060405173ffffffffffffffffffffffffffffffffffffffff821681529091507fa506ad4e7f05eceba62a023c3219e5bd98a615f4fa87e2afb08a2da5cf62bf0c9060200160405180910390a1919050565b60006108996000610b82565b333014610c97576040517fe1258894000000000000000000000000000000000000000000000000000000008152336004820152306024820152604401610624565b6000610ca283610588565b73ffffffffffffffffffffffffffffffffffffffff1614610d13576040517f5b4d6d6a0000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000083166004820152602401610624565b604080517fbe27a319efc8734e89e26ba4bc95f5c788584163b959f03fa04e2d7ab4b9a1206020808301919091527fffffffff000000000000000000000000000000000000000000000000000000008516828401528251808303840181526060909201909252805191012073ffffffffffffffffffffffffffffffffffffffff821690555050565b6000808383604051602001610dba929190918252602082015260400190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052805160209091012054949350505050565b60007f6ffbd451000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831601610e4c57506001919050565b6105d682611531565b73ffffffffffffffffffffffffffffffffffffffff81163b610ebb576040517f0c76093700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610624565b610ec3813055565b60405173ffffffffffffffffffffffffffffffffffffffff821681527f310ba5f1d2ed074b51e2eccd052a47ae9ab7c6b800d1fca3db3999d6a592ca03906020015b60405180910390a150565b6000806000806000610f238888886109ba565b50965091945092509050828210801590610f415750610f4181611672565b9450505050935093915050565b80610f85576040517f4294d12700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610fae7fea7157fa25e3aa17d0ae2d5280fa4e24d421c61842aa85e45194e1145aa72bf8829055565b6040518181527f307ed6bd941ee9fc80f369c94af5fa11e25bab5102a6140191756c5474a30bfa90602001610f05565b6040517f190100000000000000000000000000000000000000000000000000000000000060208201524660228201527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b166042820152605681018290526000906076015b604051602081830303815290604052805190602001209050919050565b8060005b818110156111ba573684848381811061108257611082612a85565b90506020028101906110949190612ab4565b90506040810135805a10156110e95782815a6040517f2bb3e3ba000000000000000000000000000000000000000000000000000000008152600481019390935260248301919091526044820152606401610624565b60006110f86020840184612af2565b1561113757611130611110608085016060860161235e565b831561111c578361111e565b5a5b61112b60a0870187612b0d565b61167d565b9050611172565b61116f61114a608085016060860161235e565b6080850135841561115b578461115d565b5a5b61116a60a0880188612b0d565b611698565b90505b801561118e5760405188815260200160405180910390a06111af565b6111af6111a16040850160208601612af2565b896111aa6116b5565b6116d4565b505050600101611067565b5050505050565b606081901c6bffffffffffffffffffffffff821660006111e083610b82565b90508181141580156111f0575060005b15611238576040517f9b6514f4000000000000000000000000000000000000000000000000000000008152600481018490526024810183905260448101829052606401610624565b604080517f8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e60208083019190915281830186905282518083038401815260609092019092528051910120600183019081905560408051858152602081018390527f1f180c27086c7a39ea2a7b25239d1ab92348f07ca7bb59d1438fcf527568f881910160405180910390a15050505050565b60008080806112e5876112e0876006818b612b72565b611720565b6000908152873560f01c6020818152604080842084526002909a013560e01c908190529890912090999198509695509350505050565b600080808061133687611331876001818b612b72565b6112ca565b935093509350935093509350935093565b6040517f190100000000000000000000000000000000000000000000000000000000000060208201526000602282018190527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b1660428301526056820183905290607601611046565b6000808080806004600188013560e81c826113cf8383612bcb565b90506113e18b61046583868d8f612b72565b939b50919950975095509350878710156114395761140181848b8d612b72565b89896040517fb006aba00000000000000000000000000000000000000000000000000000000081526004016106249493929190612bde565b8092505b888310156115235760038301928a013560e81c915061145c8383612bcb565b9050600061147e61146c88611bb6565b8c8c8790869261046593929190612b72565b939c50919a50985090915050888810156114d65761149e82858c8e612b72565b8a8a6040517fb006aba00000000000000000000000000000000000000000000000000000000081526004016106249493929190612bde565b848110611519576040517f37daf62b0000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610624565b935091508161143d565b505050939792965093509350565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fec6aba500000000000000000000000000000000000000000000000000000000014806115c457507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b8061161057507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b8061165c57507fffffffff0000000000000000000000000000000000000000000000000000000082167fc0ee0b8a00000000000000000000000000000000000000000000000000000000145b1561166957506001919050565b6105d682611bea565b60006105d682611c46565b60006040518284823760008084838989f49695505050505050565b6000604051828482376000808483898b8af1979650505050505050565b60603d604051915060208201818101604052818352816000823e505090565b82156116e257805160208201fd5b7f3dbd1590ea96dd3253a91f24e64e3a502e1225d602a5731357bc12643070ccd78282604051611713929190612c05565b60405180910390a1505050565b60008060005b83811015611bad57600181019085013560f81c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81016117c757601582019186013560f881901c9060581c73ffffffffffffffffffffffffffffffffffffffff81169074ff0000000000000000000000000000000000000000168117856117ad57806117bc565b60008681526020829052604090205b955050505050611726565b8061185d5760018201918681013560f81c9060430160006117f38a6117ee84888c8e612b72565b611c5f565b60ff841697909701969194508491905060a083901b74ff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff821617866118425780611851565b60008781526020829052604090205b96505050505050611726565b60028103611985576000808784013560f881901c9060581c73ffffffffffffffffffffffffffffffffffffffff16601586019550909250905060008885013560e81c600386018162ffffff1691508096508192505050600081860190506118d68b848c8c8a9086926118d193929190612b72565b611f22565b61191e578a836118e883898d8f612b72565b6040517f9a9462320000000000000000000000000000000000000000000000000000000081526004016106249493929190612c79565b60ff8416979097019694508460a084901b74ff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff841617876119695780611978565b60008881526020829052604090205b9750505050505050611726565b600381036119b8576020820191860135836119a057806119af565b60008481526020829052604090205b93505050611726565b60048103611a04576003808301928781013560e81c91908201016000806119e58b6112e085898d8f612b72565b6000988952602052604090972096909701965090935061172692505050565b60068103611b0c5760008287013560f81c60018401935060ff16905060008784013560f01c60028501945061ffff16905060008885013560e81c600386018162ffffff169150809650819250505060008186019050600080611a728d8d8d8b9087926112e093929190612b72565b93985088939092509050848210611a8857988501985b604080517f53657175656e6365206e657374656420636f6e6669673a0a0000000000000000602080830191909152603882018490526058820188905260788083018a9052835180840390910181526098909201909252805191012089611aee5780611afd565b60008a81526020829052604090205b99505050505050505050611726565b60058103611b78576020820191860135878103611b47577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff94505b6000611b52826120cf565b905084611b5f5780611b6e565b60008581526020829052604090205b9450505050611726565b6040517fb2505f7c00000000000000000000000000000000000000000000000000000000815260048101829052602401610624565b50935093915050565b7f8713a7c4465f6fbee2b6e9d6646d1d9f83fec929edfc4baf661f3c865bdd04d160009081526020829052604081206105d6565b60007ffda4dd44000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831601611c3d57506001919050565b6105d68261210a565b6000611c5182612166565b806105d65750600192915050565b600060428214611c9f5782826040517f2ee17a3d000000000000000000000000000000000000000000000000000000008152600401610624929190612cb9565b6000611cb8611caf600185612ccd565b85013560f81c90565b60ff169050604084013560f81c843560208601357f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0811115611d2c578686826040517fad4aac7600000000000000000000000000000000000000000000000000000000815260040161062493929190612ce0565b8260ff16601b14158015611d4457508260ff16601c14155b15611d81578686846040517fe578897e00000000000000000000000000000000000000000000000000000000815260040161062493929190612d04565b60018403611dee576040805160008152602081018083528a905260ff851691810191909152606081018390526080810182905260019060a0015b6020604051602081039080840390855afa158015611ddd573d6000803e3d6000fd5b505050602060405103519450611ec6565b60028403611e8b576040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101899052600190605c01604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600084529083018083525260ff861690820152606081018490526080810183905260a001611dbb565b86868560016040517f9dfba8520000000000000000000000000000000000000000000000000000000081526004016106249493929190612d2b565b73ffffffffffffffffffffffffffffffffffffffff8516611f175786866040517f6c1719d2000000000000000000000000000000000000000000000000000000008152600401610624929190612cb9565b505050509392505050565b6000808383611f32600182612ccd565b818110611f4157611f41612a85565b919091013560f81c9150506001811480611f5b5750600281145b15611fa0578473ffffffffffffffffffffffffffffffffffffffff16611f82878686611c5f565b73ffffffffffffffffffffffffffffffffffffffff161491506120c6565b6003810361208b5773ffffffffffffffffffffffffffffffffffffffff8516631626ba7e8786600087611fd4600182612ccd565b92611fe193929190612b72565b6040518463ffffffff1660e01b8152600401611fff93929190612a6b565b602060405180830381865afa15801561201c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120409190612d57565b7fffffffff00000000000000000000000000000000000000000000000000000000167f1626ba7e000000000000000000000000000000000000000000000000000000001491506120c6565b83838260006040517f9dfba8520000000000000000000000000000000000000000000000000000000081526004016106249493929190612d2b565b50949350505050565b6040517f53657175656e636520737461746963206469676573743a0a0000000000000000602082015260388101829052600090605801611046565b60007fe4a77bbc000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083160161215d57506001919050565b6105d682612199565b600081158015906105d65750507fea7157fa25e3aa17d0ae2d5280fa4e24d421c61842aa85e45194e1145aa72bf8541490565b60007fae9fa280000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316016121ec57506001919050565b6105d68260007fffffffff0000000000000000000000000000000000000000000000000000000082167fac6a444e00000000000000000000000000000000000000000000000000000000148061228357507fffffffff0000000000000000000000000000000000000000000000000000000082167f36e7817500000000000000000000000000000000000000000000000000000000145b1561229057506001919050565b7f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316146105d6565b8183823760009101908152919050565b7fffffffff000000000000000000000000000000000000000000000000000000008116811461063657600080fd5b60006020828403121561232a57600080fd5b813561067f816122ea565b803573ffffffffffffffffffffffffffffffffffffffff8116811461235957600080fd5b919050565b60006020828403121561237057600080fd5b61067f82612335565b60008083601f84011261238b57600080fd5b50813567ffffffffffffffff8111156123a357600080fd5b6020830191508360208285010111156123bb57600080fd5b9250929050565b6000806000806000608086880312156123da57600080fd5b6123e386612335565b94506123f160208701612335565b935060408601359250606086013567ffffffffffffffff81111561241457600080fd5b61242088828901612379565b969995985093965092949392505050565b60008060006040848603121561244657600080fd5b83359250602084013567ffffffffffffffff81111561246457600080fd5b61247086828701612379565b9497909650939450505050565b6000806000806040858703121561249357600080fd5b843567ffffffffffffffff808211156124ab57600080fd5b6124b788838901612379565b909650945060208701359150808211156124d057600080fd5b506124dd87828801612379565b95989497509550505050565b6000602082840312156124fb57600080fd5b5035919050565b60008083601f84011261251457600080fd5b50813567ffffffffffffffff81111561252c57600080fd5b6020830191508360208260051b85010111156123bb57600080fd5b6000806020838503121561255a57600080fd5b823567ffffffffffffffff81111561257157600080fd5b61257d85828601612502565b90969095509350505050565b6000806000806000606086880312156125a157600080fd5b853567ffffffffffffffff808211156125b957600080fd5b6125c589838a01612502565b90975095506020880135945060408801359150808211156125e557600080fd5b5061242088828901612379565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561263357600080fd5b813567ffffffffffffffff8082111561264b57600080fd5b818401915084601f83011261265f57600080fd5b813581811115612671576126716125f2565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156126b7576126b76125f2565b816040528281528760208487010111156126d057600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000806040838503121561270357600080fd5b823561270e816122ea565b915061271c60208401612335565b90509250929050565b60008060008060008060008060a0898b03121561274157600080fd5b61274a89612335565b975061275860208a01612335565b9650604089013567ffffffffffffffff8082111561277557600080fd5b6127818c838d01612502565b909850965060608b013591508082111561279a57600080fd5b6127a68c838d01612502565b909650945060808b01359150808211156127bf57600080fd5b506127cc8b828c01612379565b999c989b5096995094979396929594505050565b60008060008060008060a087890312156127f957600080fd5b61280287612335565b955061281060208801612335565b94506040870135935060608701359250608087013567ffffffffffffffff81111561283a57600080fd5b61284689828a01612379565b979a9699509497509295939492505050565b8035801515811461235957600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b81835260006020808501808196508560051b810191508460005b878110156129f357828403895281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4188360301811261290a57600080fd5b870160c061291782612858565b15158652612926878301612858565b15158688015260408281013590870152606073ffffffffffffffffffffffffffffffffffffffff612958828501612335565b16908701526080828101359087015260a080830135368490037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe101811261299e57600080fd5b90920187810192903567ffffffffffffffff8111156129bc57600080fd5b8036038413156129cb57600080fd5b82828901526129dd8389018286612868565b9c89019c975050509286019250506001016128cb565b5091979650505050505050565b60408152600560408201527f73656c663a00000000000000000000000000000000000000000000000000000060608201526080602082015260006106ee6080830184866128b1565b838152604060208201526000612a626040830184866128b1565b95945050505050565b838152604060208201526000612a62604083018486612868565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff41833603018112612ae857600080fd5b9190910192915050565b600060208284031215612b0457600080fd5b61067f82612858565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612b4257600080fd5b83018035915067ffffffffffffffff821115612b5d57600080fd5b6020019150368190038213156123bb57600080fd5b60008085851115612b8257600080fd5b83861115612b8f57600080fd5b5050820193919092039150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156105d6576105d6612b9c565b606081526000612bf2606083018688612868565b6020830194909452506040015292915050565b82815260006020604081840152835180604085015260005b81811015612c3957858101830151858201606001528201612c1d565b5060006060828601015260607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f830116850101925050509392505050565b84815273ffffffffffffffffffffffffffffffffffffffff84166020820152606060408201526000612caf606083018486612868565b9695505050505050565b6020815260006106ee602083018486612868565b818103818111156105d6576105d6612b9c565b604081526000612cf4604083018587612868565b9050826020830152949350505050565b604081526000612d18604083018587612868565b905060ff83166020830152949350505050565b606081526000612d3f606083018688612868565b60208301949094525090151560409091015292915050565b600060208284031215612d6957600080fd5b815161067f816122ea56fea2646970667358221220d1c64e83cb54c2e1824f98a6e0664734329329620cf112737055416b4d68ea6a64736f6c63430008110033', + deployedBytecode: + '0x6080604052600436106101485760003560e01c806357c56d6b116100c057806390042baf11610074578063b93ea7ad11610059578063b93ea7ad146104da578063bc197c81146104fa578063f23a6e61146105425761014f565b806390042baf146104b2578063affed0e0146104c55761014f565b80637a9a1628116100a55780637a9a16281461042a578063853c50681461044a5780638c3f5563146104925761014f565b806357c56d6b146103d657806361c2926c1461040a5761014f565b80631a9b23371161011757806329561426116100fc57806329561426146103735780634fcf3eca1461039357806351605d80146103b35761014f565b80631a9b23371461030e57806320c13b0b146103535761014f565b806301ffc9a714610223578063025b22bc14610258578063150b7a02146102785780631626ba7e146102ee5761014f565b3661014f57005b600061017e6000357fffffffff0000000000000000000000000000000000000000000000000000000016610588565b905073ffffffffffffffffffffffffffffffffffffffff811615610221576000808273ffffffffffffffffffffffffffffffffffffffff166000366040516101c79291906122da565b600060405180830381855af49150503d8060008114610202576040519150601f19603f3d011682016040523d82523d6000602084013e610207565b606091505b50915091508161021957805160208201fd5b805160208201f35b005b34801561022f57600080fd5b5061024361023e366004612318565b6105dc565b60405190151581526020015b60405180910390f35b34801561026457600080fd5b5061022161027336600461235e565b6105e7565b34801561028457600080fd5b506102bd6102933660046123c2565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff00000000000000000000000000000000000000000000000000000000909116815260200161024f565b3480156102fa57600080fd5b506102bd610309366004612431565b610639565b34801561031a57600080fd5b5061032e610329366004612318565b610686565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161024f565b34801561035f57600080fd5b506102bd61036e36600461247d565b610691565b34801561037f57600080fd5b5061022161038e3660046124e9565b6106f6565b34801561039f57600080fd5b506102216103ae366004612318565b610740565b3480156103bf57600080fd5b506103c861086f565b60405190815260200161024f565b3480156103e257600080fd5b506103c87f8713a7c4465f6fbee2b6e9d6646d1d9f83fec929edfc4baf661f3c865bdd04d181565b34801561041657600080fd5b50610221610425366004612547565b61089e565b34801561043657600080fd5b50610221610445366004612589565b610924565b34801561045657600080fd5b5061046a610465366004612431565b6109ba565b604080519586526020860194909452928401919091526060830152608082015260a00161024f565b34801561049e57600080fd5b506103c86104ad3660046124e9565b610b82565b61032e6104c0366004612621565b610bae565b3480156104d157600080fd5b506103c8610c4a565b3480156104e657600080fd5b506102216104f53660046126f0565b610c56565b34801561050657600080fd5b506102bd610515366004612725565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b34801561054e57600080fd5b506102bd61055d3660046127e0565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b60006105d67fbe27a319efc8734e89e26ba4bc95f5c788584163b959f03fa04e2d7ab4b9a1207fffffffff000000000000000000000000000000000000000000000000000000008416610d9b565b92915050565b60006105d682610df9565b33301461062d576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044015b60405180910390fd5b61063681610e55565b50565b600080610647858585610f10565b509050801561067957507f1626ba7e00000000000000000000000000000000000000000000000000000000905061067f565b50600090505b9392505050565b60006105d682610588565b6000806106b686866040516106a79291906122da565b60405180910390208585610f10565b50905080156106e857507f20c13b0b0000000000000000000000000000000000000000000000000000000090506106ee565b50600090505b949350505050565b333014610737576040517fe1258894000000000000000000000000000000000000000000000000000000008152336004820152306024820152604401610624565b61063681610f4e565b333014610781576040517fe1258894000000000000000000000000000000000000000000000000000000008152336004820152306024820152604401610624565b600061078c82610588565b73ffffffffffffffffffffffffffffffffffffffff16036107fd576040517f1c3812cc0000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000082166004820152602401610624565b604080517fbe27a319efc8734e89e26ba4bc95f5c788584163b959f03fa04e2d7ab4b9a1206020808301919091527fffffffff00000000000000000000000000000000000000000000000000000000841682840152825180830384018152606090920190925280519101206000905550565b60006108997fea7157fa25e3aa17d0ae2d5280fa4e24d421c61842aa85e45194e1145aa72bf85490565b905090565b3330146108df576040517fe1258894000000000000000000000000000000000000000000000000000000008152336004820152306024820152604401610624565b600061091283836040516020016108f7929190612a00565b60405160208183030381529060405280519060200120610fde565b905061091f818484611063565b505050565b61092d836111c1565b60008061096585888860405160200161094893929190612a48565b604051602081830303815290604052805190602001208585610f10565b91509150816109a6578084846040517f8f4a234f00000000000000000000000000000000000000000000000000000000815260040161062493929190612a6b565b6109b1818888611063565b50505050505050565b600080600080600080878760008181106109d6576109d6612a85565b909101357fff00000000000000000000000000000000000000000000000000000000000000169150819050610a2c57610a0e89610fde565b9250610a1b8389896112ca565b92985090965094509150610b779050565b7fff0000000000000000000000000000000000000000000000000000000000000081811601610a6b57610a5e89610fde565b9250610a1b83898961131b565b7ffe000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821601610abd57610a5e89611347565b7ffd000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821601610b2157610b118989896113b4565b9550955095509550955050610b77565b6040517f6085cd820000000000000000000000000000000000000000000000000000000081527fff0000000000000000000000000000000000000000000000000000000000000082166004820152602401610624565b939792965093509350565b60006105d67f8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e83610d9b565b6000333014610bf1576040517fe1258894000000000000000000000000000000000000000000000000000000008152336004820152306024820152604401610624565b81516020830134f060405173ffffffffffffffffffffffffffffffffffffffff821681529091507fa506ad4e7f05eceba62a023c3219e5bd98a615f4fa87e2afb08a2da5cf62bf0c9060200160405180910390a1919050565b60006108996000610b82565b333014610c97576040517fe1258894000000000000000000000000000000000000000000000000000000008152336004820152306024820152604401610624565b6000610ca283610588565b73ffffffffffffffffffffffffffffffffffffffff1614610d13576040517f5b4d6d6a0000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000083166004820152602401610624565b604080517fbe27a319efc8734e89e26ba4bc95f5c788584163b959f03fa04e2d7ab4b9a1206020808301919091527fffffffff000000000000000000000000000000000000000000000000000000008516828401528251808303840181526060909201909252805191012073ffffffffffffffffffffffffffffffffffffffff821690555050565b6000808383604051602001610dba929190918252602082015260400190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052805160209091012054949350505050565b60007f6ffbd451000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831601610e4c57506001919050565b6105d682611531565b73ffffffffffffffffffffffffffffffffffffffff81163b610ebb576040517f0c76093700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610624565b610ec3813055565b60405173ffffffffffffffffffffffffffffffffffffffff821681527f310ba5f1d2ed074b51e2eccd052a47ae9ab7c6b800d1fca3db3999d6a592ca03906020015b60405180910390a150565b6000806000806000610f238888886109ba565b50965091945092509050828210801590610f415750610f4181611672565b9450505050935093915050565b80610f85576040517f4294d12700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610fae7fea7157fa25e3aa17d0ae2d5280fa4e24d421c61842aa85e45194e1145aa72bf8829055565b6040518181527f307ed6bd941ee9fc80f369c94af5fa11e25bab5102a6140191756c5474a30bfa90602001610f05565b6040517f190100000000000000000000000000000000000000000000000000000000000060208201524660228201527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b166042820152605681018290526000906076015b604051602081830303815290604052805190602001209050919050565b8060005b818110156111ba573684848381811061108257611082612a85565b90506020028101906110949190612ab4565b90506040810135805a10156110e95782815a6040517f2bb3e3ba000000000000000000000000000000000000000000000000000000008152600481019390935260248301919091526044820152606401610624565b60006110f86020840184612af2565b1561113757611130611110608085016060860161235e565b831561111c578361111e565b5a5b61112b60a0870187612b0d565b61167d565b9050611172565b61116f61114a608085016060860161235e565b6080850135841561115b578461115d565b5a5b61116a60a0880188612b0d565b611698565b90505b801561118e5760405188815260200160405180910390a06111af565b6111af6111a16040850160208601612af2565b896111aa6116b5565b6116d4565b505050600101611067565b5050505050565b606081901c6bffffffffffffffffffffffff821660006111e083610b82565b90508181141580156111f0575060005b15611238576040517f9b6514f4000000000000000000000000000000000000000000000000000000008152600481018490526024810183905260448101829052606401610624565b604080517f8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e60208083019190915281830186905282518083038401815260609092019092528051910120600183019081905560408051858152602081018390527f1f180c27086c7a39ea2a7b25239d1ab92348f07ca7bb59d1438fcf527568f881910160405180910390a15050505050565b60008080806112e5876112e0876006818b612b72565b611720565b6000908152873560f01c6020818152604080842084526002909a013560e01c908190529890912090999198509695509350505050565b600080808061133687611331876001818b612b72565b6112ca565b935093509350935093509350935093565b6040517f190100000000000000000000000000000000000000000000000000000000000060208201526000602282018190527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b1660428301526056820183905290607601611046565b6000808080806004600188013560e81c826113cf8383612bcb565b90506113e18b61046583868d8f612b72565b939b50919950975095509350878710156114395761140181848b8d612b72565b89896040517fb006aba00000000000000000000000000000000000000000000000000000000081526004016106249493929190612bde565b8092505b888310156115235760038301928a013560e81c915061145c8383612bcb565b9050600061147e61146c88611bb6565b8c8c8790869261046593929190612b72565b939c50919a50985090915050888810156114d65761149e82858c8e612b72565b8a8a6040517fb006aba00000000000000000000000000000000000000000000000000000000081526004016106249493929190612bde565b848110611519576040517f37daf62b0000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610624565b935091508161143d565b505050939792965093509350565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fec6aba500000000000000000000000000000000000000000000000000000000014806115c457507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b8061161057507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b8061165c57507fffffffff0000000000000000000000000000000000000000000000000000000082167fc0ee0b8a00000000000000000000000000000000000000000000000000000000145b1561166957506001919050565b6105d682611bea565b60006105d682611c46565b60006040518284823760008084838989f49695505050505050565b6000604051828482376000808483898b8af1979650505050505050565b60603d604051915060208201818101604052818352816000823e505090565b82156116e257805160208201fd5b7f3dbd1590ea96dd3253a91f24e64e3a502e1225d602a5731357bc12643070ccd78282604051611713929190612c05565b60405180910390a1505050565b60008060005b83811015611bad57600181019085013560f81c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81016117c757601582019186013560f881901c9060581c73ffffffffffffffffffffffffffffffffffffffff81169074ff0000000000000000000000000000000000000000168117856117ad57806117bc565b60008681526020829052604090205b955050505050611726565b8061185d5760018201918681013560f81c9060430160006117f38a6117ee84888c8e612b72565b611c5f565b60ff841697909701969194508491905060a083901b74ff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff821617866118425780611851565b60008781526020829052604090205b96505050505050611726565b60028103611985576000808784013560f881901c9060581c73ffffffffffffffffffffffffffffffffffffffff16601586019550909250905060008885013560e81c600386018162ffffff1691508096508192505050600081860190506118d68b848c8c8a9086926118d193929190612b72565b611f22565b61191e578a836118e883898d8f612b72565b6040517f9a9462320000000000000000000000000000000000000000000000000000000081526004016106249493929190612c79565b60ff8416979097019694508460a084901b74ff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff841617876119695780611978565b60008881526020829052604090205b9750505050505050611726565b600381036119b8576020820191860135836119a057806119af565b60008481526020829052604090205b93505050611726565b60048103611a04576003808301928781013560e81c91908201016000806119e58b6112e085898d8f612b72565b6000988952602052604090972096909701965090935061172692505050565b60068103611b0c5760008287013560f81c60018401935060ff16905060008784013560f01c60028501945061ffff16905060008885013560e81c600386018162ffffff169150809650819250505060008186019050600080611a728d8d8d8b9087926112e093929190612b72565b93985088939092509050848210611a8857988501985b604080517f53657175656e6365206e657374656420636f6e6669673a0a0000000000000000602080830191909152603882018490526058820188905260788083018a9052835180840390910181526098909201909252805191012089611aee5780611afd565b60008a81526020829052604090205b99505050505050505050611726565b60058103611b78576020820191860135878103611b47577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff94505b6000611b52826120cf565b905084611b5f5780611b6e565b60008581526020829052604090205b9450505050611726565b6040517fb2505f7c00000000000000000000000000000000000000000000000000000000815260048101829052602401610624565b50935093915050565b7f8713a7c4465f6fbee2b6e9d6646d1d9f83fec929edfc4baf661f3c865bdd04d160009081526020829052604081206105d6565b60007ffda4dd44000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831601611c3d57506001919050565b6105d68261210a565b6000611c5182612166565b806105d65750600192915050565b600060428214611c9f5782826040517f2ee17a3d000000000000000000000000000000000000000000000000000000008152600401610624929190612cb9565b6000611cb8611caf600185612ccd565b85013560f81c90565b60ff169050604084013560f81c843560208601357f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0811115611d2c578686826040517fad4aac7600000000000000000000000000000000000000000000000000000000815260040161062493929190612ce0565b8260ff16601b14158015611d4457508260ff16601c14155b15611d81578686846040517fe578897e00000000000000000000000000000000000000000000000000000000815260040161062493929190612d04565b60018403611dee576040805160008152602081018083528a905260ff851691810191909152606081018390526080810182905260019060a0015b6020604051602081039080840390855afa158015611ddd573d6000803e3d6000fd5b505050602060405103519450611ec6565b60028403611e8b576040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101899052600190605c01604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600084529083018083525260ff861690820152606081018490526080810183905260a001611dbb565b86868560016040517f9dfba8520000000000000000000000000000000000000000000000000000000081526004016106249493929190612d2b565b73ffffffffffffffffffffffffffffffffffffffff8516611f175786866040517f6c1719d2000000000000000000000000000000000000000000000000000000008152600401610624929190612cb9565b505050509392505050565b6000808383611f32600182612ccd565b818110611f4157611f41612a85565b919091013560f81c9150506001811480611f5b5750600281145b15611fa0578473ffffffffffffffffffffffffffffffffffffffff16611f82878686611c5f565b73ffffffffffffffffffffffffffffffffffffffff161491506120c6565b6003810361208b5773ffffffffffffffffffffffffffffffffffffffff8516631626ba7e8786600087611fd4600182612ccd565b92611fe193929190612b72565b6040518463ffffffff1660e01b8152600401611fff93929190612a6b565b602060405180830381865afa15801561201c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120409190612d57565b7fffffffff00000000000000000000000000000000000000000000000000000000167f1626ba7e000000000000000000000000000000000000000000000000000000001491506120c6565b83838260006040517f9dfba8520000000000000000000000000000000000000000000000000000000081526004016106249493929190612d2b565b50949350505050565b6040517f53657175656e636520737461746963206469676573743a0a0000000000000000602082015260388101829052600090605801611046565b60007fe4a77bbc000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083160161215d57506001919050565b6105d682612199565b600081158015906105d65750507fea7157fa25e3aa17d0ae2d5280fa4e24d421c61842aa85e45194e1145aa72bf8541490565b60007fae9fa280000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316016121ec57506001919050565b6105d68260007fffffffff0000000000000000000000000000000000000000000000000000000082167fac6a444e00000000000000000000000000000000000000000000000000000000148061228357507fffffffff0000000000000000000000000000000000000000000000000000000082167f36e7817500000000000000000000000000000000000000000000000000000000145b1561229057506001919050565b7f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316146105d6565b8183823760009101908152919050565b7fffffffff000000000000000000000000000000000000000000000000000000008116811461063657600080fd5b60006020828403121561232a57600080fd5b813561067f816122ea565b803573ffffffffffffffffffffffffffffffffffffffff8116811461235957600080fd5b919050565b60006020828403121561237057600080fd5b61067f82612335565b60008083601f84011261238b57600080fd5b50813567ffffffffffffffff8111156123a357600080fd5b6020830191508360208285010111156123bb57600080fd5b9250929050565b6000806000806000608086880312156123da57600080fd5b6123e386612335565b94506123f160208701612335565b935060408601359250606086013567ffffffffffffffff81111561241457600080fd5b61242088828901612379565b969995985093965092949392505050565b60008060006040848603121561244657600080fd5b83359250602084013567ffffffffffffffff81111561246457600080fd5b61247086828701612379565b9497909650939450505050565b6000806000806040858703121561249357600080fd5b843567ffffffffffffffff808211156124ab57600080fd5b6124b788838901612379565b909650945060208701359150808211156124d057600080fd5b506124dd87828801612379565b95989497509550505050565b6000602082840312156124fb57600080fd5b5035919050565b60008083601f84011261251457600080fd5b50813567ffffffffffffffff81111561252c57600080fd5b6020830191508360208260051b85010111156123bb57600080fd5b6000806020838503121561255a57600080fd5b823567ffffffffffffffff81111561257157600080fd5b61257d85828601612502565b90969095509350505050565b6000806000806000606086880312156125a157600080fd5b853567ffffffffffffffff808211156125b957600080fd5b6125c589838a01612502565b90975095506020880135945060408801359150808211156125e557600080fd5b5061242088828901612379565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561263357600080fd5b813567ffffffffffffffff8082111561264b57600080fd5b818401915084601f83011261265f57600080fd5b813581811115612671576126716125f2565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156126b7576126b76125f2565b816040528281528760208487010111156126d057600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000806040838503121561270357600080fd5b823561270e816122ea565b915061271c60208401612335565b90509250929050565b60008060008060008060008060a0898b03121561274157600080fd5b61274a89612335565b975061275860208a01612335565b9650604089013567ffffffffffffffff8082111561277557600080fd5b6127818c838d01612502565b909850965060608b013591508082111561279a57600080fd5b6127a68c838d01612502565b909650945060808b01359150808211156127bf57600080fd5b506127cc8b828c01612379565b999c989b5096995094979396929594505050565b60008060008060008060a087890312156127f957600080fd5b61280287612335565b955061281060208801612335565b94506040870135935060608701359250608087013567ffffffffffffffff81111561283a57600080fd5b61284689828a01612379565b979a9699509497509295939492505050565b8035801515811461235957600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b81835260006020808501808196508560051b810191508460005b878110156129f357828403895281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4188360301811261290a57600080fd5b870160c061291782612858565b15158652612926878301612858565b15158688015260408281013590870152606073ffffffffffffffffffffffffffffffffffffffff612958828501612335565b16908701526080828101359087015260a080830135368490037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe101811261299e57600080fd5b90920187810192903567ffffffffffffffff8111156129bc57600080fd5b8036038413156129cb57600080fd5b82828901526129dd8389018286612868565b9c89019c975050509286019250506001016128cb565b5091979650505050505050565b60408152600560408201527f73656c663a00000000000000000000000000000000000000000000000000000060608201526080602082015260006106ee6080830184866128b1565b838152604060208201526000612a626040830184866128b1565b95945050505050565b838152604060208201526000612a62604083018486612868565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff41833603018112612ae857600080fd5b9190910192915050565b600060208284031215612b0457600080fd5b61067f82612858565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612b4257600080fd5b83018035915067ffffffffffffffff821115612b5d57600080fd5b6020019150368190038213156123bb57600080fd5b60008085851115612b8257600080fd5b83861115612b8f57600080fd5b5050820193919092039150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156105d6576105d6612b9c565b606081526000612bf2606083018688612868565b6020830194909452506040015292915050565b82815260006020604081840152835180604085015260005b81811015612c3957858101830151858201606001528201612c1d565b5060006060828601015260607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f830116850101925050509392505050565b84815273ffffffffffffffffffffffffffffffffffffffff84166020820152606060408201526000612caf606083018486612868565b9695505050505050565b6020815260006106ee602083018486612868565b818103818111156105d6576105d6612b9c565b604081526000612cf4604083018587612868565b9050826020830152949350505050565b604081526000612d18604083018587612868565b905060ff83166020830152949350505050565b606081526000612d3f606083018688612868565b60208301949094525090151560409091015292915050565b600060208284031215612d6957600080fd5b815161067f816122ea56fea2646970667358221220d1c64e83cb54c2e1824f98a6e0664734329329620cf112737055416b4d68ea6a64736f6c63430008110033', + linkReferences: {}, + deployedLinkReferences: {} +} diff --git a/packages/estimator/src/builds/index.ts b/packages/estimator/src/builds/index.ts new file mode 100644 index 0000000000..630bef12cd --- /dev/null +++ b/packages/estimator/src/builds/index.ts @@ -0,0 +1 @@ +export * from './MainModuleGasEstimation' diff --git a/packages/estimator/src/estimator.ts b/packages/estimator/src/estimator.ts new file mode 100644 index 0000000000..0705cea53e --- /dev/null +++ b/packages/estimator/src/estimator.ts @@ -0,0 +1,15 @@ +import { ethers } from 'ethers' +import { commons, v2 } from '@0xsequence/core' + +export interface Estimator { + estimateGasLimits( + address: string, + config: v2.config.WalletConfig, + context: commons.context.WalletContext, + nonce: ethers.BigNumberish, + ...transactions: commons.transaction.Transaction[] + ): Promise<{ + transactions: commons.transaction.Transaction[] + total: ethers.BigNumber + }> +} diff --git a/packages/estimator/src/index.ts b/packages/estimator/src/index.ts new file mode 100644 index 0000000000..690fbfbe0b --- /dev/null +++ b/packages/estimator/src/index.ts @@ -0,0 +1,3 @@ +export * from './overwriter-estimator' +export * from './overwriter-sequence-estimator' +export * from './estimator' diff --git a/packages/estimator/src/overwriter-estimator.ts b/packages/estimator/src/overwriter-estimator.ts new file mode 100644 index 0000000000..e442ffe833 --- /dev/null +++ b/packages/estimator/src/overwriter-estimator.ts @@ -0,0 +1,137 @@ +import { ethers } from 'ethers' +import { getEthersConnectionInfo, isBigNumberish, Optionals } from '@0xsequence/utils' + +const GasEstimator = require('@0xsequence/wallet-contracts/artifacts/contracts/modules/utils/GasEstimator.sol/GasEstimator.json') + +function toQuantity(number: ethers.BigNumberish | string): string { + if (isBigNumberish(number)) { + return ethers.BigNumber.from(number).toHexString() + } + + return number +} + +function tryDecodeError(bytes: ethers.BytesLike): string { + try { + return ethers.utils.toUtf8String('0x' + ethers.utils.hexlify(bytes).substr(138)) + } catch (e) { + return 'UNKNOWN_ERROR' + } +} + +function toHexNumber(number: ethers.BigNumberish): string { + return ethers.BigNumber.from(number).toHexString() +} + +export type OverwriterEstimatorOptions = { + rpc: string | ethers.providers.JsonRpcProvider + dataZeroCost?: number + dataOneCost?: number + baseCost?: number +} + +export const OverwriterEstimatorDefaults: Required> = { + dataZeroCost: 4, + dataOneCost: 16, + baseCost: 21000 +} + +export class OverwriterEstimator { + public provider: ethers.providers.JsonRpcProvider + public options: Required + + constructor(options: OverwriterEstimatorOptions) { + this.provider = + typeof options.rpc === 'string' + ? new ethers.providers.StaticJsonRpcProvider(getEthersConnectionInfo(options.rpc)) + : options.rpc + this.options = { ...OverwriterEstimatorDefaults, ...options } + } + + txBaseCost(data: ethers.BytesLike): number { + const bytes = ethers.utils.arrayify(data) + return bytes + .reduce((p, c) => (c == 0 ? p.add(this.options.dataZeroCost) : p.add(this.options.dataOneCost)), ethers.constants.Zero) + .add(this.options.baseCost) + .toNumber() + } + + async estimate(args: { + to: string + from?: string + data?: ethers.BytesLike + gasPrice?: ethers.BigNumberish + gas?: ethers.BigNumberish + overwrites?: { + [address: string]: { + code?: string + balance?: ethers.BigNumberish + nonce?: ethers.BigNumberish + stateDiff?: { + key: string + value: string + }[] + state?: { + key: string + value: string + }[] + } + } + blockTag?: string | ethers.BigNumberish + }): Promise { + const blockTag = args.blockTag ? toQuantity(args.blockTag) : 'latest' + const data = args.data ? args.data : [] + const from = args.from ? ethers.utils.getAddress(args.from) : ethers.Wallet.createRandom().address + + const gasEstimatorInterface = new ethers.utils.Interface(GasEstimator.abi) + const encodedEstimate = gasEstimatorInterface.encodeFunctionData('estimate', [args.to, data]) + + const providedOverwrites = args.overwrites + ? Object.keys(args.overwrites).reduce((p, a) => { + const address = ethers.utils.getAddress(a) + const o = args.overwrites![a] + + if (address === from) { + throw Error("Can't overwrite from address values") + } + + return { + ...p, + [address]: { + code: o.code ? ethers.utils.hexlify(o.code) : undefined, + nonce: o.nonce ? toHexNumber(o.nonce) : undefined, + balance: o.balance ? toHexNumber(o.balance) : undefined, + state: o.state ? o.state : undefined, + stateDiff: o.stateDiff ? o.stateDiff : undefined + } + } + }, {}) + : {} + + const overwrites = { + ...providedOverwrites, + [from]: { + code: GasEstimator.deployedBytecode + } + } + + const response = await this.provider.send('eth_call', [ + { + to: from, + data: encodedEstimate, + gasPrice: args.gasPrice, + gas: args.gas + }, + blockTag, + overwrites + ]) + + const decoded = gasEstimatorInterface.decodeFunctionResult('estimate', response) + + if (!decoded.success) { + throw Error(`Failed gas estimation with ${tryDecodeError(decoded.result)}`) + } + + return ethers.BigNumber.from(decoded.gas).add(this.txBaseCost(data)) + } +} diff --git a/packages/estimator/src/overwriter-sequence-estimator.ts b/packages/estimator/src/overwriter-sequence-estimator.ts new file mode 100644 index 0000000000..7404de1918 --- /dev/null +++ b/packages/estimator/src/overwriter-sequence-estimator.ts @@ -0,0 +1,139 @@ +import { OverwriterEstimator } from './overwriter-estimator' +import { walletContracts } from '@0xsequence/abi' +import { ethers, utils } from 'ethers' +import { Estimator } from './estimator' +import { commons, v2 } from '@0xsequence/core' +import { mainModuleGasEstimation } from './builds' + +export class OverwriterSequenceEstimator implements Estimator { + constructor(public estimator: OverwriterEstimator) {} + + async estimateGasLimits( + address: string, + config: v2.config.WalletConfig, + context: commons.context.WalletContext, + nonce: ethers.BigNumberish, + ...transactions: commons.transaction.Transaction[] + ): Promise<{ transactions: commons.transaction.Transaction[]; total: ethers.BigNumber }> { + const walletInterface = new utils.Interface(walletContracts.mainModule.abi) + + const allSigners = await Promise.all( + v2.config.signersOf(config.tree).map(async (s, i) => ({ + index: i, + address: s.address, + weight: ethers.BigNumber.from(s.weight), + isEOA: await this.estimator.provider.getCode(s.address).then(c => ethers.utils.arrayify(c).length === 0) + })) + ) + + let totalWeight = 0 + + // Pick NOT EOA signers until we reach the threshold + // if we can't reach the threshold, then we'll use the lowest weight EOA signers + // TODO: if EOAs have the same weight, then we should pick the ones further apart from each other (in the tree) + const designatedSigners = allSigners + .sort((a, b) => { + if (a.isEOA && !b.isEOA) return 1 + if (!a.isEOA && b.isEOA) return -1 + if (a.weight.eq(b.weight)) return a.index - b.index + return a.weight.sub(b.weight).toNumber() + }) + .filter(s => { + if (totalWeight >= (config.threshold as number)) { + return false + } else { + totalWeight += s.weight.toNumber() + return true + } + }) + + // Generate a fake signature, meant to resemble the final signature of the transaction + // this "fake" signature is provided to compute a more accurate gas estimation + const fakeSignatures = new Map() + for (const s of designatedSigners) { + if (s.isEOA) { + fakeSignatures.set(s.address, { + signature: (await ethers.Wallet.createRandom().signMessage('')) + '02', + isDynamic: false + }) + } else { + // Assume a 2/3 nested contract signature + const signer1 = ethers.Wallet.createRandom() + const signer2 = ethers.Wallet.createRandom() + const signer3 = ethers.Wallet.createRandom() + + const nestedSignature = v2.signature.encodeSigners( + v2.config.ConfigCoder.fromSimple({ + threshold: 2, + checkpoint: 0, + signers: [ + { + address: signer1.address, + weight: 1 + }, + { + address: signer2.address, + weight: 1 + }, + { + address: signer3.address, + weight: 1 + } + ] + }), + new Map([ + [signer1.address, { signature: (await signer1.signMessage('')) + '02', isDynamic: false }], + [signer2.address, { signature: (await signer2.signMessage('')) + '02', isDynamic: false }] + ]), + [], + 0 + ) + + fakeSignatures.set(s.address, { + signature: nestedSignature.encoded + '03', + isDynamic: true + }) + } + } + + const stubSignature = v2.signature.encodeSigners(config, fakeSignatures, [], 0).encoded + + // Use the provided nonce + // TODO: Maybe ignore if this fails on the MainModuleGasEstimation + // it could help reduce the edge cases for when the gas estimation fails + const encoded = commons.transaction.sequenceTxAbiEncode(transactions) + + const sequenceOverwrites = { + [context.mainModule]: { + code: mainModuleGasEstimation.deployedBytecode + }, + [context.mainModuleUpgradable]: { + code: mainModuleGasEstimation.deployedBytecode + } + } + + const estimates = await Promise.all([ + ...encoded.map(async (_, i) => { + return this.estimator.estimate({ + to: address, + data: walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [ + encoded.slice(0, i), + nonce, + stubSignature + ]), + overwrites: sequenceOverwrites + }) + }), + this.estimator.estimate({ + to: address, // Compute full gas estimation with all transaction + data: walletInterface.encodeFunctionData(walletInterface.getFunction('execute'), [encoded, nonce, stubSignature]), + overwrites: sequenceOverwrites + }) + ]) + + return { + transactions: transactions.map((t, i) => ({ ...t, gasLimit: estimates[i + 1].sub(estimates[i]) })), + total: estimates[estimates.length - 1] + } + } +} diff --git a/packages/estimator/tests/estimator.spec.ts b/packages/estimator/tests/estimator.spec.ts new file mode 100644 index 0000000000..f9095991d3 --- /dev/null +++ b/packages/estimator/tests/estimator.spec.ts @@ -0,0 +1,44 @@ +import { ethers } from 'ethers' + +import { CallReceiverMock } from '@0xsequence/wallet-contracts' +import { OverwriterEstimator } from '@0xsequence/estimator' +import { encodeData } from '@0xsequence/wallet/tests/utils' +import { expect } from 'chai' + +const CallReceiverMockArtifact = require('@0xsequence/wallet-contracts/artifacts/contracts/mocks/CallReceiverMock.sol/CallReceiverMock.json') + +describe('estimator', function () { + let url: string + let provider: ethers.providers.JsonRpcProvider + let callReceiver: CallReceiverMock + + let estimator: OverwriterEstimator + + before(async () => { + url = 'http://127.0.0.1:10045/' + provider = new ethers.providers.JsonRpcProvider(url) + + callReceiver = (await new ethers.ContractFactory( + CallReceiverMockArtifact.abi, + CallReceiverMockArtifact.bytecode, + provider.getSigner() + ).deploy()) as unknown as CallReceiverMock + + estimator = new OverwriterEstimator({ rpc: url }) + }) + + beforeEach(async () => { + await callReceiver.setRevertFlag(false) + await callReceiver.testCall(0, []) + }) + + it('should estimate the gas of a single call', async () => { + const gas = await estimator.estimate({ + to: callReceiver.address, + data: await encodeData(callReceiver, 'testCall', 1, '0x112233') + }) + const tx = await (await callReceiver.testCall(1, '0x112233')).wait() + expect(gas.toNumber()).to.be.above(tx.gasUsed.toNumber()) + expect(gas.toNumber()).to.be.approximately(tx.gasUsed.toNumber(), 5000) + }) +}) diff --git a/packages/estimator/tests/sequence-estimator.spec.ts b/packages/estimator/tests/sequence-estimator.spec.ts new file mode 100644 index 0000000000..5d447d44c3 --- /dev/null +++ b/packages/estimator/tests/sequence-estimator.spec.ts @@ -0,0 +1,319 @@ +import { CallReceiverMock, HookCallerMock } from '@0xsequence/wallet-contracts' + +import { LocalRelayer } from '@0xsequence/relayer' +import { ethers } from 'ethers' + +import { configureLogger } from '@0xsequence/utils' +import { commons, v2 } from '@0xsequence/core' + +import chaiAsPromised from 'chai-as-promised' +import * as chai from 'chai' + +import { SequenceOrchestratorWrapper, Wallet, WalletV2 } from '@0xsequence/wallet' +import { OverwriterSequenceEstimator } from '../src' +import { OverwriterEstimator } from '../dist/0xsequence-estimator.cjs' +import { encodeData } from '@0xsequence/wallet/tests/utils' +import { context } from '@0xsequence/tests' +import { Orchestrator } from '@0xsequence/signhub' + +const CallReceiverMockArtifact = require('@0xsequence/wallet-contracts/artifacts/contracts/mocks/CallReceiverMock.sol/CallReceiverMock.json') +const HookCallerMockArtifact = require('@0xsequence/wallet-contracts/artifacts/contracts/mocks/HookCallerMock.sol/HookCallerMock.json') + +const { expect } = chai.use(chaiAsPromised) + +configureLogger({ logLevel: 'DEBUG', silence: false }) + +describe('Wallet integration', function () { + let relayer: LocalRelayer + let callReceiver: CallReceiverMock + let hookCaller: HookCallerMock + + let contexts: Awaited> + let provider: ethers.providers.JsonRpcProvider + let signers: ethers.Signer[] + + let estimator: OverwriterSequenceEstimator + + before(async () => { + const url = 'http://127.0.0.1:10045/' + provider = new ethers.providers.JsonRpcProvider(url) + + signers = new Array(8).fill(0).map((_, i) => provider.getSigner(i)) + + contexts = await context.deploySequenceContexts(signers[0]) + relayer = new LocalRelayer(signers[0]) + + // Deploy call receiver mock + callReceiver = (await new ethers.ContractFactory( + CallReceiverMockArtifact.abi, + CallReceiverMockArtifact.bytecode, + signers[0] + ).deploy({ gasLimit: 1000000 })) as CallReceiverMock + + // Deploy hook caller mock + hookCaller = (await new ethers.ContractFactory( + HookCallerMockArtifact.abi, + HookCallerMockArtifact.bytecode, + signers[0] + ).deploy({ gasLimit: 1000000 })) as HookCallerMock + + // Deploy local relayer + relayer = new LocalRelayer({ signer: signers[0] }) + + // Create gas estimator + estimator = new OverwriterSequenceEstimator(new OverwriterEstimator({ rpc: provider })) + }) + + beforeEach(async () => { + await callReceiver.setRevertFlag(false) + await callReceiver.testCall(0, []) + }) + + describe('estimate gas of transactions', () => { + const options = [ + { + name: 'single signer wallet', + getWallet: async () => { + // const pk = ethers.utils.randomBytes(32) + // const wallet = await Wallet.singleOwner(pk, context) + // return wallet.connect(ethnode.provider, relayer) + const signer = ethers.Wallet.createRandom() + const config = v2.config.ConfigCoder.fromSimple({ + threshold: 1, + checkpoint: 0, + signers: [{ weight: 1, address: signer.address }] + }) + + return Wallet.newWallet({ + context: contexts[2], + coders: v2.coders, + config, + provider, + relayer, + orchestrator: new Orchestrator([signer]), + chainId: provider.network.chainId + }) + } + }, + { + name: 'multiple signers wallet', + getWallet: async () => { + const signers = new Array(4).fill(0).map(() => ethers.Wallet.createRandom()) + + const config = v2.config.ConfigCoder.fromSimple({ + threshold: 3, + checkpoint: 100, + signers: signers.map(s => ({ weight: 1, address: s.address })) + }) + + return Wallet.newWallet({ + context: contexts[2], + coders: v2.coders, + config, + provider, + relayer, + orchestrator: new Orchestrator([signers[0], signers[1], signers[2]]), + chainId: provider.network.chainId + }) + } + }, + // TODO: This test fails because the gas estimation uses signers that are packed together + // in the tree, we need to modify the estimator so it picks a sparse set of signers + // { + // name: 'many multiple signers wallet', + // getWallet: async () => { + // const signers = new Array(111).fill(0).map(() => ethers.Wallet.createRandom()) + + // const config = v2.config.ConfigCoder.fromSimple({ + // threshold: 11, + // checkpoint: 100, + // signers: signers.map(s => ({ weight: 1, address: s.address })) + // }) + + // console.log(JSON.stringify(config, null, 2)) + + // return Wallet.newWallet({ + // context: contexts[2], + // coders: v2.coders, + // config, + // provider, + // relayer, + // orchestrator: new Orchestrator(signers.slice(0, 12)), + // chainId: provider.network.chainId + // }) + // } + // }, + { + name: 'nested wallet', + getWallet: async () => { + const EOAsigners = new Array(3).fill(0).map(() => ethers.Wallet.createRandom()) + + const nestedSigners = new Array(3).fill(0).map(() => ethers.Wallet.createRandom()) + const nestedConfig = v2.config.ConfigCoder.fromSimple({ + threshold: 2, + checkpoint: 0, + signers: nestedSigners.map(s => ({ weight: 1, address: s.address })) + }) + + const nestedWallet = Wallet.newWallet({ + context: contexts[2], + coders: v2.coders, + config: nestedConfig, + provider, + relayer, + orchestrator: new Orchestrator([nestedSigners[0], nestedSigners[1]]), + chainId: provider.network.chainId + }) + + await nestedWallet.deploy() + + const signers = [nestedWallet, ...EOAsigners] + + const config = v2.config.ConfigCoder.fromSimple({ + threshold: 3, + checkpoint: 0, + signers: signers.map(s => ({ weight: 1, address: s.address })) + }) + + return Wallet.newWallet({ + context: contexts[2], + coders: v2.coders, + config, + provider, + relayer, + orchestrator: new Orchestrator([new SequenceOrchestratorWrapper(nestedWallet), EOAsigners[0], EOAsigners[1]]), + chainId: provider.network.chainId + }) + } + }, + { + name: 'asymetrical signers wallet', + getWallet: async () => { + const signersA = new Array(5).fill(0).map(() => ethers.Wallet.createRandom()) + const signersB = new Array(6).fill(0).map(() => ethers.Wallet.createRandom()) + + const signers = [...signersA, ...signersB] + + const config = v2.config.ConfigCoder.fromSimple({ + threshold: 5, + checkpoint: 0, + signers: signers.map((s, i) => ({ weight: i <= signersA.length ? 1 : 10, address: s.address })) + }) + + return Wallet.newWallet({ + context: contexts[2], + coders: v2.coders, + config, + provider, + relayer, + orchestrator: new Orchestrator(signersA), + chainId: provider.network.chainId + }) + } + } + ] + + options.map(o => { + describe(`with ${o.name}`, () => { + let wallet: WalletV2 + + beforeEach(async () => { + wallet = await o.getWallet() + }) + + describe('with deployed wallet', () => { + let txs: commons.transaction.Transaction[] + + beforeEach(async () => { + await callReceiver.testCall(0, []) + await wallet.deploy() + }) + + describe('a single transaction', () => { + beforeEach(async () => { + txs = [ + { + delegateCall: false, + revertOnError: false, + gasLimit: 0, + to: callReceiver.address, + value: ethers.constants.Zero, + data: await encodeData(callReceiver, 'testCall', 14442, '0x112233') + } + ] + }) + + it('should use estimated gas for a single transaction', async () => { + const estimation = await estimator.estimateGasLimits(wallet.address, wallet.config, wallet.context, 0, ...txs) + const realTx = await (await wallet.sendTransaction(estimation.transactions)).wait(1) + + expect(realTx.gasUsed.toNumber()).to.be.approximately(estimation.total.toNumber(), 10000) + expect(realTx.gasUsed.toNumber()).to.be.below(estimation.total.toNumber()) + + expect((await callReceiver.lastValA()).toNumber()).to.equal(14442) + }) + + it('should predict gas usage for a single transaction', async () => { + const estimation = await estimator.estimateGasLimits(wallet.address, wallet.config, wallet.context, 0, ...txs) + const realTx = await (await wallet.sendTransaction(txs)).wait(1) + + expect(realTx.gasUsed.toNumber()).to.be.approximately(estimation.total.toNumber(), 10000) + expect(realTx.gasUsed.toNumber()).to.be.below(estimation.total.toNumber()) + + expect((await callReceiver.lastValA()).toNumber()).to.equal(14442) + }) + + it('should use estimated gas for a single failing transaction', async () => { + await callReceiver.setRevertFlag(true) + const estimation = await estimator.estimateGasLimits(wallet.address, wallet.config, wallet.context, 0, ...txs) + const realTx = await (await wallet.sendTransaction(estimation.transactions)).wait(1) + + expect(realTx.gasUsed.toNumber()).to.be.approximately(estimation.total.toNumber(), 10000) + expect(realTx.gasUsed.toNumber()).to.be.below(estimation.total.toNumber()) + + expect((await callReceiver.lastValA()).toNumber()).to.equal(0) + }) + }) + + describe('a batch of transactions', () => { + let valB: Uint8Array + + beforeEach(async () => { + await callReceiver.setRevertFlag(true) + valB = ethers.utils.randomBytes(99) + + txs = [ + { + delegateCall: false, + revertOnError: false, + gasLimit: 0, + to: callReceiver.address, + value: ethers.constants.Zero, + data: await encodeData(callReceiver, 'setRevertFlag', false) + }, + { + delegateCall: false, + revertOnError: true, + gasLimit: 0, + to: callReceiver.address, + value: ethers.constants.Zero, + data: await encodeData(callReceiver, 'testCall', 2, valB) + } + ] + }) + + it('should use estimated gas for a batch of transactions', async () => { + const estimation = await estimator.estimateGasLimits(wallet.address, wallet.config, wallet.context, 0, ...txs) + const realTx = await (await wallet.sendTransaction(estimation.transactions)).wait(1) + + expect(realTx.gasUsed.toNumber()).to.be.approximately(estimation.total.toNumber(), 30000) + expect(realTx.gasUsed.toNumber()).to.be.below(estimation.total.toNumber()) + + expect(ethers.utils.hexlify(await callReceiver.lastValB())).to.equal(ethers.utils.hexlify(valB)) + }) + }) + }) + }) + }) + }) +}) diff --git a/packages/guard/CHANGELOG.md b/packages/guard/CHANGELOG.md new file mode 100644 index 0000000000..7f3a52142d --- /dev/null +++ b/packages/guard/CHANGELOG.md @@ -0,0 +1,2159 @@ +# @0xsequence/guard + +## 1.10.8 + +### Patch Changes + +- update metadata bindings +- Updated dependencies + - @0xsequence/account@1.10.8 + - @0xsequence/core@1.10.8 + - @0xsequence/signhub@1.10.8 + - @0xsequence/utils@1.10.8 + +## 1.10.7 + +### Patch Changes + +- minor fixes to waas client +- Updated dependencies + - @0xsequence/account@1.10.7 + - @0xsequence/core@1.10.7 + - @0xsequence/signhub@1.10.7 + - @0xsequence/utils@1.10.7 + +## 1.10.6 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/account@1.10.6 + - @0xsequence/core@1.10.6 + - @0xsequence/signhub@1.10.6 + - @0xsequence/utils@1.10.6 + +## 1.10.5 + +### Patch Changes + +- network: ape-chain-testnet -> apechain-testnet +- Updated dependencies + - @0xsequence/account@1.10.5 + - @0xsequence/core@1.10.5 + - @0xsequence/signhub@1.10.5 + - @0xsequence/utils@1.10.5 + +## 1.10.4 + +### Patch Changes + +- network: add b3-sepolia, ape-chain-testnet, blast, blast-sepolia +- Updated dependencies + - @0xsequence/account@1.10.4 + - @0xsequence/core@1.10.4 + - @0xsequence/signhub@1.10.4 + - @0xsequence/utils@1.10.4 + +## 1.10.3 + +### Patch Changes + +- typing fix +- Updated dependencies + - @0xsequence/account@1.10.3 + - @0xsequence/core@1.10.3 + - @0xsequence/signhub@1.10.3 + - @0xsequence/utils@1.10.3 + +## 1.10.2 + +### Patch Changes + +- - waas: add getIdToken method + - indexer: update api client +- Updated dependencies + - @0xsequence/account@1.10.2 + - @0xsequence/core@1.10.2 + - @0xsequence/signhub@1.10.2 + - @0xsequence/utils@1.10.2 + +## 1.10.1 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/account@1.10.1 + - @0xsequence/core@1.10.1 + - @0xsequence/signhub@1.10.1 + - @0xsequence/utils@1.10.1 + +## 1.10.0 + +### Minor Changes + +- waas release v1.3.0 + +### Patch Changes + +- Updated dependencies + - @0xsequence/account@1.10.0 + - @0xsequence/core@1.10.0 + - @0xsequence/signhub@1.10.0 + - @0xsequence/utils@1.10.0 + +## 1.9.37 + +### Patch Changes + +- network: adds nativeToken data to NetworkMetadata constants +- Updated dependencies + - @0xsequence/account@1.9.37 + - @0xsequence/core@1.9.37 + - @0xsequence/signhub@1.9.37 + - @0xsequence/utils@1.9.37 + +## 1.9.36 + +### Patch Changes + +- guard: export client +- Updated dependencies + - @0xsequence/account@1.9.36 + - @0xsequence/core@1.9.36 + - @0xsequence/signhub@1.9.36 + - @0xsequence/utils@1.9.36 + +## 1.9.35 + +### Patch Changes + +- guard: update bindings +- Updated dependencies + - @0xsequence/account@1.9.35 + - @0xsequence/core@1.9.35 + - @0xsequence/signhub@1.9.35 + - @0xsequence/utils@1.9.35 + +## 1.9.34 + +### Patch Changes + +- waas: always use lowercase email +- Updated dependencies + - @0xsequence/account@1.9.34 + - @0xsequence/core@1.9.34 + - @0xsequence/signhub@1.9.34 + - @0xsequence/utils@1.9.34 + +## 1.9.33 + +### Patch Changes + +- waas: umd build +- Updated dependencies + - @0xsequence/account@1.9.33 + - @0xsequence/core@1.9.33 + - @0xsequence/signhub@1.9.33 + - @0xsequence/utils@1.9.33 + +## 1.9.32 + +### Patch Changes + +- indexer: update bindings +- Updated dependencies + - @0xsequence/account@1.9.32 + - @0xsequence/core@1.9.32 + - @0xsequence/signhub@1.9.32 + - @0xsequence/utils@1.9.32 + +## 1.9.31 + +### Patch Changes + +- metadata: token directory changes +- Updated dependencies + - @0xsequence/account@1.9.31 + - @0xsequence/core@1.9.31 + - @0xsequence/signhub@1.9.31 + - @0xsequence/utils@1.9.31 + +## 1.9.30 + +### Patch Changes + +- update +- Updated dependencies + - @0xsequence/account@1.9.30 + - @0xsequence/core@1.9.30 + - @0xsequence/signhub@1.9.30 + - @0xsequence/utils@1.9.30 + +## 1.9.29 + +### Patch Changes + +- disable gnosis chain +- Updated dependencies + - @0xsequence/account@1.9.29 + - @0xsequence/core@1.9.29 + - @0xsequence/signhub@1.9.29 + - @0xsequence/utils@1.9.29 + +## 1.9.28 + +### Patch Changes + +- add utils/merkletree +- Updated dependencies + - @0xsequence/account@1.9.28 + - @0xsequence/core@1.9.28 + - @0xsequence/signhub@1.9.28 + - @0xsequence/utils@1.9.28 + +## 1.9.27 + +### Patch Changes + +- network: optimistic -> optimism +- waas: remove defaults +- api, sessions: update bindings +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/account@1.9.27 + - @0xsequence/core@1.9.27 + - @0xsequence/signhub@1.9.27 + - @0xsequence/utils@1.9.27 + +## 1.9.26 + +### Patch Changes + +- - add backend interfaces for pluggable interfaces + - introduce @0xsequence/react-native + - update pnpm to lockfile v9 +- Updated dependencies + - @0xsequence/account@1.9.26 + - @0xsequence/core@1.9.26 + - @0xsequence/signhub@1.9.26 + - @0xsequence/utils@1.9.26 + +## 1.9.25 + +### Patch Changes + +- update webrpc clients with new error types +- Updated dependencies + - @0xsequence/account@1.9.25 + - @0xsequence/core@1.9.25 + - @0xsequence/signhub@1.9.25 + - @0xsequence/utils@1.9.25 + +## 1.9.24 + +### Patch Changes + +- waas: add memoryStore backend to localStore +- Updated dependencies + - @0xsequence/account@1.9.24 + - @0xsequence/core@1.9.24 + - @0xsequence/signhub@1.9.24 + - @0xsequence/utils@1.9.24 + +## 1.9.23 + +### Patch Changes + +- update api client bindings +- Updated dependencies + - @0xsequence/account@1.9.23 + - @0xsequence/core@1.9.23 + - @0xsequence/signhub@1.9.23 + - @0xsequence/utils@1.9.23 + +## 1.9.22 + +### Patch Changes + +- update metadata client bindings +- Updated dependencies + - @0xsequence/account@1.9.22 + - @0xsequence/core@1.9.22 + - @0xsequence/signhub@1.9.22 + - @0xsequence/utils@1.9.22 + +## 1.9.21 + +### Patch Changes + +- api client bindings +- Updated dependencies + - @0xsequence/account@1.9.21 + - @0xsequence/core@1.9.21 + - @0xsequence/signhub@1.9.21 + - @0xsequence/utils@1.9.21 + +## 1.9.20 + +### Patch Changes + +- api client bindings update +- Updated dependencies + - @0xsequence/account@1.9.20 + - @0xsequence/core@1.9.20 + - @0xsequence/signhub@1.9.20 + - @0xsequence/utils@1.9.20 + +## 1.9.19 + +### Patch Changes + +- waas update +- Updated dependencies + - @0xsequence/account@1.9.19 + - @0xsequence/core@1.9.19 + - @0xsequence/signhub@1.9.19 + - @0xsequence/utils@1.9.19 + +## 1.9.18 + +### Patch Changes + +- provider: prohibit dangerous functions +- Updated dependencies + - @0xsequence/account@1.9.18 + - @0xsequence/core@1.9.18 + - @0xsequence/signhub@1.9.18 + - @0xsequence/utils@1.9.18 + +## 1.9.17 + +### Patch Changes + +- network: add xr-sepolia +- Updated dependencies + - @0xsequence/account@1.9.17 + - @0xsequence/core@1.9.17 + - @0xsequence/signhub@1.9.17 + - @0xsequence/utils@1.9.17 + +## 1.9.16 + +### Patch Changes + +- waas: sequence.feeOptions +- Updated dependencies + - @0xsequence/account@1.9.16 + - @0xsequence/core@1.9.16 + - @0xsequence/signhub@1.9.16 + - @0xsequence/utils@1.9.16 + +## 1.9.15 + +### Patch Changes + +- metadata: collection external_link field name fix +- Updated dependencies + - @0xsequence/account@1.9.15 + - @0xsequence/core@1.9.15 + - @0xsequence/signhub@1.9.15 + - @0xsequence/utils@1.9.15 + +## 1.9.14 + +### Patch Changes + +- network: astar-zkatana -> astar-zkyoto +- network: deprecate polygon mumbai network +- network: add xai and polygon amoy +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/account@1.9.14 + - @0xsequence/core@1.9.14 + - @0xsequence/signhub@1.9.14 + - @0xsequence/utils@1.9.14 + +## 1.9.13 + +### Patch Changes + +- waas: fix @0xsequence/network dependency +- Updated dependencies + - @0xsequence/account@1.9.13 + - @0xsequence/core@1.9.13 + - @0xsequence/signhub@1.9.13 + - @0xsequence/utils@1.9.13 + +## 1.9.12 + +### Patch Changes + +- indexer: update rpc bindings +- provider: signMessage: Serialize the BytesLike or string message into hexstring before sending +- waas: SessionAuthProof +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/account@1.9.12 + - @0xsequence/core@1.9.12 + - @0xsequence/signhub@1.9.12 + - @0xsequence/utils@1.9.12 + +## 1.9.11 + +### Patch Changes + +- metdata, update rpc bindings +- Updated dependencies + - @0xsequence/account@1.9.11 + - @0xsequence/core@1.9.11 + - @0xsequence/signhub@1.9.11 + - @0xsequence/utils@1.9.11 + +## 1.9.10 + +### Patch Changes + +- update metadata rpc bindings +- Updated dependencies + - @0xsequence/account@1.9.10 + - @0xsequence/core@1.9.10 + - @0xsequence/signhub@1.9.10 + - @0xsequence/utils@1.9.10 + +## 1.9.9 + +### Patch Changes + +- metadata, add SequenceCollections rpc client +- Updated dependencies + - @0xsequence/account@1.9.9 + - @0xsequence/core@1.9.9 + - @0xsequence/signhub@1.9.9 + - @0xsequence/utils@1.9.9 + +## 1.9.8 + +### Patch Changes + +- waas client update +- Updated dependencies + - @0xsequence/account@1.9.8 + - @0xsequence/core@1.9.8 + - @0xsequence/signhub@1.9.8 + - @0xsequence/utils@1.9.8 + +## 1.9.7 + +### Patch Changes + +- update rpc client bindings for api, metadata and relayer +- Updated dependencies + - @0xsequence/account@1.9.7 + - @0xsequence/core@1.9.7 + - @0xsequence/signhub@1.9.7 + - @0xsequence/utils@1.9.7 + +## 1.9.6 + +### Patch Changes + +- waas package update +- Updated dependencies + - @0xsequence/account@1.9.6 + - @0xsequence/core@1.9.6 + - @0xsequence/signhub@1.9.6 + - @0xsequence/utils@1.9.6 + +## 1.9.5 + +### Patch Changes + +- RpcRelayer prioritize project access key +- Updated dependencies + - @0xsequence/account@1.9.5 + - @0xsequence/core@1.9.5 + - @0xsequence/signhub@1.9.5 + - @0xsequence/utils@1.9.5 + +## 1.9.4 + +### Patch Changes + +- waas: fix network dependency +- Updated dependencies + - @0xsequence/account@1.9.4 + - @0xsequence/core@1.9.4 + - @0xsequence/signhub@1.9.4 + - @0xsequence/utils@1.9.4 + +## 1.9.3 + +### Patch Changes + +- provider: don't append access key to RPC url if user has already provided it +- Updated dependencies + - @0xsequence/account@1.9.3 + - @0xsequence/core@1.9.3 + - @0xsequence/signhub@1.9.3 + - @0xsequence/utils@1.9.3 + +## 1.9.2 + +### Patch Changes + +- network: add xai-sepolia +- Updated dependencies + - @0xsequence/account@1.9.2 + - @0xsequence/core@1.9.2 + - @0xsequence/signhub@1.9.2 + - @0xsequence/utils@1.9.2 + +## 1.9.1 + +### Patch Changes + +- analytics fix +- Updated dependencies + - @0xsequence/account@1.9.1 + - @0xsequence/core@1.9.1 + - @0xsequence/signhub@1.9.1 + - @0xsequence/utils@1.9.1 + +## 1.9.0 + +### Minor Changes + +- waas release + +### Patch Changes + +- Updated dependencies + - @0xsequence/account@1.9.0 + - @0xsequence/core@1.9.0 + - @0xsequence/signhub@1.9.0 + - @0xsequence/utils@1.9.0 + +## 1.8.8 + +### Patch Changes + +- update metadata bindings +- Updated dependencies + - @0xsequence/account@1.8.8 + - @0xsequence/core@1.8.8 + - @0xsequence/signhub@1.8.8 + - @0xsequence/utils@1.8.8 + +## 1.8.7 + +### Patch Changes + +- provider: update databeat to 0.9.1 +- Updated dependencies + - @0xsequence/account@1.8.7 + - @0xsequence/core@1.8.7 + - @0xsequence/signhub@1.8.7 + - @0xsequence/utils@1.8.7 + +## 1.8.6 + +### Patch Changes + +- guard: SignedOwnershipProof +- Updated dependencies + - @0xsequence/account@1.8.6 + - @0xsequence/core@1.8.6 + - @0xsequence/signhub@1.8.6 + - @0xsequence/utils@1.8.6 + +## 1.8.5 + +### Patch Changes + +- guard: signOwnershipProof and isSignedOwnershipProof +- Updated dependencies + - @0xsequence/account@1.8.5 + - @0xsequence/core@1.8.5 + - @0xsequence/signhub@1.8.5 + - @0xsequence/utils@1.8.5 + +## 1.8.4 + +### Patch Changes + +- network: add homeverse to networks list +- Updated dependencies + - @0xsequence/account@1.8.4 + - @0xsequence/core@1.8.4 + - @0xsequence/signhub@1.8.4 + - @0xsequence/utils@1.8.4 + +## 1.8.3 + +### Patch Changes + +- api: introduce basic linked wallet support +- Updated dependencies + - @0xsequence/account@1.8.3 + - @0xsequence/core@1.8.3 + - @0xsequence/signhub@1.8.3 + - @0xsequence/utils@1.8.3 + +## 1.8.2 + +### Patch Changes + +- provider: don't initialize analytics unless explicitly requested +- Updated dependencies + - @0xsequence/account@1.8.2 + - @0xsequence/core@1.8.2 + - @0xsequence/signhub@1.8.2 + - @0xsequence/utils@1.8.2 + +## 1.8.1 + +### Patch Changes + +- update to analytics provider +- Updated dependencies + - @0xsequence/account@1.8.1 + - @0xsequence/core@1.8.1 + - @0xsequence/signhub@1.8.1 + - @0xsequence/utils@1.8.1 + +## 1.8.0 + +### Minor Changes + +- provider: project analytics + +### Patch Changes + +- Updated dependencies + - @0xsequence/account@1.8.0 + - @0xsequence/core@1.8.0 + - @0xsequence/signhub@1.8.0 + - @0xsequence/utils@1.8.0 + +## 1.7.2 + +### Patch Changes + +- 0xsequence: ChainId should not be exported as a type +- account, wallet: fix nonce selection +- Updated dependencies +- Updated dependencies + - @0xsequence/account@1.7.2 + - @0xsequence/core@1.7.2 + - @0xsequence/signhub@1.7.2 + - @0xsequence/utils@1.7.2 + +## 1.7.1 + +### Patch Changes + +- network: add missing avalanche logoURI +- Updated dependencies + - @0xsequence/account@1.7.1 + - @0xsequence/core@1.7.1 + - @0xsequence/signhub@1.7.1 + - @0xsequence/utils@1.7.1 + +## 1.7.0 + +### Minor Changes + +- provider: projectAccessKey is now required + +### Patch Changes + +- network: add NetworkMetadata.logoURI property for all networks +- Updated dependencies +- Updated dependencies + - @0xsequence/account@1.7.0 + - @0xsequence/core@1.7.0 + - @0xsequence/signhub@1.7.0 + - @0xsequence/utils@1.7.0 + +## 1.6.3 + +### Patch Changes + +- network list update +- Updated dependencies + - @0xsequence/account@1.6.3 + - @0xsequence/core@1.6.3 + - @0xsequence/signhub@1.6.3 + - @0xsequence/utils@1.6.3 + +## 1.6.2 + +### Patch Changes + +- auth: projectAccessKey option +- wallet: use 12 bytes for random space +- Updated dependencies +- Updated dependencies + - @0xsequence/account@1.6.2 + - @0xsequence/core@1.6.2 + - @0xsequence/signhub@1.6.2 + - @0xsequence/utils@1.6.2 + +## 1.6.1 + +### Patch Changes + +- core: add simple config from subdigest support +- core: fix encode tree with subdigest +- account: implement buildOnChainSignature on Account +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/account@1.6.1 + - @0xsequence/core@1.6.1 + - @0xsequence/signhub@1.6.1 + - @0xsequence/utils@1.6.1 + +## 1.6.0 + +### Minor Changes + +- account, wallet: parallel transactions by default + +### Patch Changes + +- provider: emit disconnect on sign out +- Updated dependencies +- Updated dependencies + - @0xsequence/account@1.6.0 + - @0xsequence/core@1.6.0 + - @0xsequence/signhub@1.6.0 + - @0xsequence/utils@1.6.0 + +## 1.5.0 + +### Minor Changes + +- signhub: add 'signing' signer status + +### Patch Changes + +- auth: Session.open: onAccountAddress callback +- account: allow empty transaction bundles +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/account@1.5.0 + - @0xsequence/core@1.5.0 + - @0xsequence/signhub@1.5.0 + - @0xsequence/utils@1.5.0 + +## 1.4.9 + +### Patch Changes + +- rename SequenceMetadataClient to SequenceMetadata +- Updated dependencies + - @0xsequence/account@1.4.9 + - @0xsequence/core@1.4.9 + - @0xsequence/signhub@1.4.9 + - @0xsequence/utils@1.4.9 + +## 1.4.8 + +### Patch Changes + +- account: Account.getSigners +- Updated dependencies + - @0xsequence/account@1.4.8 + - @0xsequence/core@1.4.8 + - @0xsequence/signhub@1.4.8 + - @0xsequence/utils@1.4.8 + +## 1.4.7 + +### Patch Changes + +- update indexer client bindings +- Updated dependencies + - @0xsequence/account@1.4.7 + - @0xsequence/core@1.4.7 + - @0xsequence/signhub@1.4.7 + - @0xsequence/utils@1.4.7 + +## 1.4.6 + +### Patch Changes + +- - add sepolia networks, mark goerli as deprecated + - update indexer client bindings +- Updated dependencies + - @0xsequence/account@1.4.6 + - @0xsequence/core@1.4.6 + - @0xsequence/signhub@1.4.6 + - @0xsequence/utils@1.4.6 + +## 1.4.5 + +### Patch Changes + +- indexer/metadata: update client bindings +- auth: selectWallet with new address +- Updated dependencies +- Updated dependencies + - @0xsequence/account@1.4.5 + - @0xsequence/core@1.4.5 + - @0xsequence/signhub@1.4.5 + - @0xsequence/utils@1.4.5 + +## 1.4.4 + +### Patch Changes + +- indexer: update bindings +- auth: handle jwt expiry +- Updated dependencies +- Updated dependencies + - @0xsequence/account@1.4.4 + - @0xsequence/core@1.4.4 + - @0xsequence/signhub@1.4.4 + - @0xsequence/utils@1.4.4 + +## 1.4.3 + +### Patch Changes + +- guard: return active status from GuardSigner.getAuthMethods +- Updated dependencies + - @0xsequence/account@1.4.3 + - @0xsequence/core@1.4.3 + - @0xsequence/signhub@1.4.3 + - @0xsequence/utils@1.4.3 + +## 1.4.2 + +### Patch Changes + +- guard: update bindings +- Updated dependencies + - @0xsequence/account@1.4.2 + - @0xsequence/core@1.4.2 + - @0xsequence/signhub@1.4.2 + - @0xsequence/utils@1.4.2 + +## 1.4.1 + +### Patch Changes + +- network: remove unused networks +- signhub: orchestrator interface +- guard: auth methods interface +- guard: update bindings for pin and totp +- guard: no more retry logic +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/account@1.4.1 + - @0xsequence/core@1.4.1 + - @0xsequence/signhub@1.4.1 + - @0xsequence/utils@1.4.1 + +## 1.4.0 + +### Minor Changes + +- project access key support + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.4.0 + - @0xsequence/signhub@1.4.0 + +## 1.3.0 + +### Minor Changes + +- signhub: account children + +### Patch Changes + +- guard: do not throw when building deploy transaction +- network: snowtrace.io -> subnets.avax.network/c-chain +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.3.0 + - @0xsequence/signhub@1.3.0 + +## 1.2.9 + +### Patch Changes + +- account: AccountSigner.sendTransaction simulateForFeeOptions +- relayer: update bindings +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.2.9 + - @0xsequence/signhub@1.2.9 + +## 1.2.8 + +### Patch Changes + +- rename X-Sequence-Token-Key header to X-Access-Key +- Updated dependencies + - @0xsequence/core@1.2.8 + - @0xsequence/signhub@1.2.8 + +## 1.2.7 + +### Patch Changes + +- add x-sequence-token-key to clients +- Updated dependencies + - @0xsequence/core@1.2.7 + - @0xsequence/signhub@1.2.7 + +## 1.2.6 + +### Patch Changes + +- Fix bind multicall provider +- Updated dependencies + - @0xsequence/core@1.2.6 + - @0xsequence/signhub@1.2.6 + +## 1.2.5 + +### Patch Changes + +- Multicall default configuration fixes +- Updated dependencies + - @0xsequence/core@1.2.5 + - @0xsequence/signhub@1.2.5 + +## 1.2.4 + +### Patch Changes + +- provider: Adding missing payment provider types to PaymentProviderOption +- provider: WalletRequestHandler.notifyChainChanged +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.2.4 + - @0xsequence/signhub@1.2.4 + +## 1.2.3 + +### Patch Changes + +- auth, provider: connect to accept optional authorizeNonce +- Updated dependencies + - @0xsequence/core@1.2.3 + - @0xsequence/signhub@1.2.3 + +## 1.2.2 + +### Patch Changes + +- provider: allow createContract calls +- core: check for explicit zero address in contract deployments +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.2.2 + - @0xsequence/signhub@1.2.2 + +## 1.2.1 + +### Patch Changes + +- auth: use sequence api chain id as reference chain id if available +- Updated dependencies + - @0xsequence/core@1.2.1 + - @0xsequence/signhub@1.2.1 + +## 1.2.0 + +### Minor Changes + +- split services from session, better local support + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.2.0 + - @0xsequence/signhub@1.2.0 + +## 1.1.15 + +### Patch Changes + +- guard: remove error filtering +- Updated dependencies + - @0xsequence/core@1.1.15 + - @0xsequence/signhub@1.1.15 + +## 1.1.14 + +### Patch Changes + +- guard: add GuardSigner.onError +- Updated dependencies + - @0xsequence/core@1.1.14 + - @0xsequence/signhub@1.1.14 + +## 1.1.13 + +### Patch Changes + +- provider: pass client version with connect options +- provider: removing large from BannerSize +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.1.13 + - @0xsequence/signhub@1.1.13 + +## 1.1.12 + +### Patch Changes + +- provider: adding bannerSize to ConnectOptions +- Updated dependencies + - @0xsequence/core@1.1.12 + - @0xsequence/signhub@1.1.12 + +## 1.1.11 + +### Patch Changes + +- add homeverse configs +- Updated dependencies + - @0xsequence/core@1.1.11 + - @0xsequence/signhub@1.1.11 + +## 1.1.10 + +### Patch Changes + +- handle default EIP6492 on send +- Updated dependencies + - @0xsequence/core@1.1.10 + - @0xsequence/signhub@1.1.10 + +## 1.1.9 + +### Patch Changes + +- Custom default EIP6492 on client +- Updated dependencies + - @0xsequence/core@1.1.9 + - @0xsequence/signhub@1.1.9 + +## 1.1.8 + +### Patch Changes + +- metadata: searchMetadata: add types filter +- Updated dependencies + - @0xsequence/core@1.1.8 + - @0xsequence/signhub@1.1.8 + +## 1.1.7 + +### Patch Changes + +- adding signInWith connect settings option to allow dapps to automatically login their users with a certain provider optimizing the normal authentication flow +- Updated dependencies + - @0xsequence/core@1.1.7 + - @0xsequence/signhub@1.1.7 + +## 1.1.6 + +### Patch Changes + +- metadata: searchMetadata: add chainID and excludeTokenMetadata filters +- Updated dependencies + - @0xsequence/core@1.1.6 + - @0xsequence/signhub@1.1.6 + +## 1.1.5 + +### Patch Changes + +- account: re-compute meta-transaction id for wallet deployment transactions +- Updated dependencies + - @0xsequence/core@1.1.5 + - @0xsequence/signhub@1.1.5 + +## 1.1.4 + +### Patch Changes + +- network: rename base-mainnet to base +- provider: override isDefaultChain with ConnectOptions.networkId if provided +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.1.4 + - @0xsequence/signhub@1.1.4 + +## 1.1.3 + +### Patch Changes + +- provider: use network id from transport session +- provider: sign authorization using ConnectOptions.networkId if provided +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.1.3 + - @0xsequence/signhub@1.1.3 + +## 1.1.2 + +### Patch Changes + +- provider: jsonrpc chain id fixes +- Updated dependencies + - @0xsequence/core@1.1.2 + - @0xsequence/signhub@1.1.2 + +## 1.1.1 + +### Patch Changes + +- network: add base mainnet and sepolia +- provider: reject toxic transaction requests +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.1.1 + - @0xsequence/signhub@1.1.1 + +## 1.1.0 + +### Minor Changes + +- Refactor dapp facing provider + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.1.0 + - @0xsequence/signhub@1.1.0 + +## 1.0.5 + +### Patch Changes + +- network: export network constants +- guard: use the correct global for fetch +- network: nova-explorer.arbitrum.io -> nova.arbiscan.io +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.0.5 + - @0xsequence/signhub@1.0.5 + +## 1.0.4 + +### Patch Changes + +- provider: accept name or number for networkId +- Updated dependencies + - @0xsequence/core@1.0.4 + - @0xsequence/signhub@1.0.4 + +## 1.0.3 + +### Patch Changes + +- Simpler isValidSignature helpers +- Updated dependencies + - @0xsequence/core@1.0.3 + - @0xsequence/signhub@1.0.3 + +## 1.0.2 + +### Patch Changes + +- add extra signature validation utils methods +- Updated dependencies + - @0xsequence/core@1.0.2 + - @0xsequence/signhub@1.0.2 + +## 1.0.1 + +### Patch Changes + +- add homeverse testnet +- Updated dependencies + - @0xsequence/core@1.0.1 + - @0xsequence/signhub@1.0.1 + +## 1.0.0 + +### Major Changes + +- https://sequence.xyz/blog/sequence-wallet-light-state-sync-full-merkle-wallets + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.0.0 + - @0xsequence/signhub@1.0.0 + +## 0.43.34 + +### Patch Changes + +- auth: no jwt for indexer + +## 0.43.33 + +### Patch Changes + +- Adding onConnectOptionsChange handler to WalletRequestHandler + +## 0.43.32 + +### Patch Changes + +- add Base Goerli network + +## 0.43.31 + +### Patch Changes + +- remove AuxDataProvider, add promptSignInConnect + +## 0.43.30 + +### Patch Changes + +- add arbitrum goerli testnet + +## 0.43.29 + +### Patch Changes + +- provider: check availability of window object + +## 0.43.28 + +### Patch Changes + +- update api bindings + +## 0.43.27 + +### Patch Changes + +- Add rpc is sequence method + +## 0.43.26 + +### Patch Changes + +- add zkevm url to enum + +## 0.43.25 + +### Patch Changes + +- added polygon zkevm to mainnet networks + +## 0.43.24 + +### Patch Changes + +- name change from zkevm to polygon-zkevm + +## 0.43.23 + +### Patch Changes + +- update zkEVM name to Polygon zkEVM + +## 0.43.22 + +### Patch Changes + +- add zkevm chain + +## 0.43.21 + +### Patch Changes + +- api: update client bindings + +## 0.43.20 + +### Patch Changes + +- indexer: update bindings + +## 0.43.19 + +### Patch Changes + +- session proof update + +## 0.43.18 + +### Patch Changes + +- rpc client global check, hardening + +## 0.43.17 + +### Patch Changes + +- rpc clients, check of 'global' is defined + +## 0.43.16 + +### Patch Changes + +- ethers peerDep to v5, update rpc client global use + +## 0.43.15 + +### Patch Changes + +- - provider: expand receiver type on some util methods + +## 0.43.14 + +### Patch Changes + +- bump + +## 0.43.13 + +### Patch Changes + +- update rpc bindings + +## 0.43.12 + +### Patch Changes + +- provider: single wallet init, and add new unregisterWallet() method + +## 0.43.11 + +### Patch Changes + +- fix lockfiles +- re-add mocha type deleter + +## 0.43.10 + +### Patch Changes + +- various improvements + +## 0.43.9 + +### Patch Changes + +- update deps + +## 0.43.8 + +### Patch Changes + +- network: JsonRpcProvider with caching + +## 0.43.7 + +### Patch Changes + +- provider: fix wallet network init + +## 0.43.6 + +### Patch Changes + +- metadatata: update rpc bindings + +## 0.43.5 + +### Patch Changes + +- provider: do not set default network for connect messages +- provider: forward missing error message + +## 0.43.4 + +### Patch Changes + +- no-change version bump to fix incorrectly tagged snapshot build + +## 0.43.3 + +### Patch Changes + +- metadata: update bindings + +## 0.43.2 + +### Patch Changes + +- provider: implement connectUnchecked + +## 0.43.1 + +### Patch Changes + +- update to latest ethauth dep + +## 0.43.0 + +### Minor Changes + +- move ethers to a peer dependency + +## 0.42.10 + +### Patch Changes + +- add auxDataProvider + +## 0.42.9 + +### Patch Changes + +- provider: add eip-191 exceptions + +## 0.42.8 + +### Patch Changes + +- provider: skip setting intent origin if we're unity plugin + +## 0.42.7 + +### Patch Changes + +- Add sign in options to connection settings + +## 0.42.6 + +### Patch Changes + +- api bindings update + +## 0.42.5 + +### Patch Changes + +- relayer: don't treat missing receipt as hard failure + +## 0.42.4 + +### Patch Changes + +- provider: add custom app protocol to connect options + +## 0.42.3 + +### Patch Changes + +- update api bindings + +## 0.42.2 + +### Patch Changes + +- disable rinkeby network + +## 0.42.1 + +### Patch Changes + +- wallet: optional waitForReceipt parameter + +## 0.42.0 + +### Minor Changes + +- relayer: estimateGasLimits -> simulate +- add simulator package + +### Patch Changes + +- transactions: fix flattenAuxTransactions +- provider: only filter nullish values +- provider: re-map transaction 'gas' back to 'gasLimit' + +## 0.41.3 + +### Patch Changes + +- api bindings update + +## 0.41.2 + +### Patch Changes + +- api bindings update + +## 0.41.1 + +### Patch Changes + +- update default networks + +## 0.41.0 + +### Minor Changes + +- relayer: fix Relayer.wait() interface + + The interface for calling Relayer.wait() has changed. Instead of a single optional ill-defined timeout/delay parameter, there are three optional parameters, in order: + + - timeout: the maximum time to wait for the transaction receipt + - delay: the polling interval, i.e. the time to wait between requests + - maxFails: the maximum number of hard failures to tolerate before giving up + + Please update your codebase accordingly. + +- relayer: add optional waitForReceipt parameter to Relayer.relay + + The behaviour of Relayer.relay() was not well-defined with respect to whether or not it waited for a receipt. + This change allows the caller to specify whether to wait or not, with the default behaviour being to wait. + +### Patch Changes + +- relayer: wait receipt retry logic +- fix wrapped object error +- provider: forward delegateCall and revertOnError transaction fields + +## 0.40.6 + +### Patch Changes + +- add arbitrum-nova chain + +## 0.40.5 + +### Patch Changes + +- api: update bindings + +## 0.40.4 + +### Patch Changes + +- add unreal transport + +## 0.40.3 + +### Patch Changes + +- provider: fix MessageToSign message type + +## 0.40.2 + +### Patch Changes + +- Wallet provider, loadSession method + +## 0.40.1 + +### Patch Changes + +- export sequence.initWallet and sequence.getWallet + +## 0.40.0 + +### Minor Changes + +- add sequence.initWallet(network, config) and sequence.getWallet() helper methods + +## 0.39.6 + +### Patch Changes + +- indexer: update client bindings + +## 0.39.5 + +### Patch Changes + +- provider: fix networkRpcUrl config option + +## 0.39.4 + +### Patch Changes + +- api: update client bindings + +## 0.39.3 + +### Patch Changes + +- add request method on Web3Provider + +## 0.39.2 + +### Patch Changes + +- update umd name + +## 0.39.1 + +### Patch Changes + +- add Aurora network +- add origin info for accountsChanged event to handle it per dapp + +## 0.39.0 + +### Minor Changes + +- abstract window.localStorage to interface type + +## 0.38.2 + +### Patch Changes + +- provider: add Settings.defaultPurchaseAmount + +## 0.38.1 + +### Patch Changes + +- update api and metadata rpc bindings + +## 0.38.0 + +### Minor Changes + +- api: update bindings, change TokenPrice interface +- bridge: remove @0xsequence/bridge package +- api: update bindings, rename ContractCallArg to TupleComponent + +## 0.37.1 + +### Patch Changes + +- Add back sortNetworks - Removing sorting was a breaking change for dapps on older versions which directly integrate sequence. + +## 0.37.0 + +### Minor Changes + +- network related fixes and improvements +- api: bindings: exchange rate lookups + +## 0.36.13 + +### Patch Changes + +- api: update bindings with new price endpoints + +## 0.36.12 + +### Patch Changes + +- wallet: skip remote signers if not needed +- auth: check that signature meets threshold before requesting auth token + +## 0.36.11 + +### Patch Changes + +- Prefix EIP191 message on wallet-request-handler + +## 0.36.10 + +### Patch Changes + +- support bannerUrl on connect + +## 0.36.9 + +### Patch Changes + +- minor dev xp improvements + +## 0.36.8 + +### Patch Changes + +- more connect options (theme, payment providers, funding currencies) + +## 0.36.7 + +### Patch Changes + +- fix missing break + +## 0.36.6 + +### Patch Changes + +- wallet_switchEthereumChain support + +## 0.36.5 + +### Patch Changes + +- auth: bump ethauth to 0.7.0 + network, wallet: don't assume position of auth network in list + api/indexer/metadata: trim trailing slash on hostname, and add endpoint urls + relayer: Allow to specify local relayer transaction parameters like gas price or gas limit + +## 0.36.4 + +### Patch Changes + +- Updating list of chain ids to include other ethereum compatible chains + +## 0.36.3 + +### Patch Changes + +- provider: pass connect options to prompter methods + +## 0.36.2 + +### Patch Changes + +- transactions: Setting target to 0x0 when empty to during SequenceTxAbiEncode + +## 0.36.1 + +### Patch Changes + +- metadata: update client with more fields + +## 0.36.0 + +### Minor Changes + +- relayer, wallet: fee quote support + +## 0.35.12 + +### Patch Changes + +- provider: rename wallet.commands to wallet.utils + +## 0.35.11 + +### Patch Changes + +- provider/utils: smoother message validation + +## 0.35.10 + +### Patch Changes + +- upgrade deps + +## 0.35.9 + +### Patch Changes + +- provider: window-transport override event handlers with new wallet instance + +## 0.35.8 + +### Patch Changes + +- provider: async wallet sign in improvements + +## 0.35.7 + +### Patch Changes + +- config: cache wallet configs + +## 0.35.6 + +### Patch Changes + +- provider: support async signin of wallet request handler + +## 0.35.5 + +### Patch Changes + +- wallet: skip threshold check during fee estimation + +## 0.35.4 + +### Patch Changes + +- - browser extension mode, center window + +## 0.35.3 + +### Patch Changes + +- - update window position when in browser extension mode + +## 0.35.2 + +### Patch Changes + +- - provider: WindowMessageHandler accept optional windowHref + +## 0.35.1 + +### Patch Changes + +- wallet: update config on undeployed too + +## 0.35.0 + +### Minor Changes + +- - config: add buildStubSignature + - provider: add checks to signing cases for wallet deployment and config statuses + - provider: add prompt for wallet deployment + - relayer: add BaseRelayer.prependWalletDeploy + - relayer: add Relayer.feeOptions + - relayer: account for wallet deployment in fee estimation + - transactions: add fromTransactionish + - wallet: add Account.prependConfigUpdate + - wallet: add Account.getFeeOptions + +## 0.34.0 + +### Minor Changes + +- - upgrade deps + +## 0.31.0 + +### Minor Changes + +- - upgrading to ethers v5.5 + +## 0.30.0 + +### Minor Changes + +- - upgrade most deps + +## 0.29.8 + +### Patch Changes + +- update api + +## 0.28.0 + +### Minor Changes + +- extension provider + +## 0.27.0 + +### Minor Changes + +- Add requireFreshSigner lib to sessions + +## 0.25.1 + +### Patch Changes + +- Fix build typescrypt issue + +## 0.25.0 + +### Minor Changes + +- 10c8af8: Add estimator package + Fix multicall few calls bug + +## 0.23.0 + +### Minor Changes + +- - relayer: offer variety of gas fee options from the relayer service" + +## 0.22.2 + +### Patch Changes + +- e1c109e: Fix authProof on expired sessions + +## 0.22.1 + +### Patch Changes + +- transport session cache + +## 0.22.0 + +### Minor Changes + +- e667b65: Expose all relayer options on networks + +## 0.21.5 + +### Patch Changes + +- Give priority to metaTxnId returned by relayer + +## 0.21.4 + +### Patch Changes + +- Add has enough signers method + +## 0.21.3 + +### Patch Changes + +- add window session cache + +## 0.21.2 + +### Patch Changes + +- exception handlind in relayer + +## 0.21.0 + +### Minor Changes + +- - fix gas estimation on wallets with large number of signers + - update to session handling and wallet config construction upon auth + +## 0.19.3 + +### Patch Changes + +- jwtAuth visibility, package version sync + +## 0.19.0 + +### Minor Changes + +- - provider, improve dapp / wallet transport io + +## 0.18.0 + +### Minor Changes + +- relayer improvements and pending transaction handling + +## 0.16.0 + +### Minor Changes + +- relayer as its own service separate from chaind + +## 0.15.1 + +### Patch Changes + +- update api clients + +## 0.14.3 + +### Patch Changes + +- Fix 0xSequence relayer dependencies + +## 0.14.2 + +### Patch Changes + +- Add debug logs to rpc-relayer + +## 0.14.0 + +### Minor Changes + +- update sequence utils finder which includes optimization + +## 0.13.0 + +### Minor Changes + +- Update SequenceUtils deployed contract + +## 0.12.1 + +### Patch Changes + +- npm bump + +## 0.12.0 + +### Minor Changes + +- provider: improvements to window transport + +## 0.11.4 + +### Patch Changes + +- update api client + +## 0.11.3 + +### Patch Changes + +- improve openWindow state options handling + +## 0.11.2 + +### Patch Changes + +- Fix multicall proxy scopes + +## 0.11.1 + +### Patch Changes + +- Add support for dynamic and nested signatures + +## 0.11.0 + +### Minor Changes + +- Update wallet context to 1.7 contracts + +## 0.10.9 + +### Patch Changes + +- add support for public addresses as signers in session.open + +## 0.10.8 + +### Patch Changes + +- Multicall production configuration + +## 0.10.7 + +### Patch Changes + +- allow provider transport to force disconnect + +## 0.10.6 + +### Patch Changes + +- - fix getWalletState method + +## 0.10.5 + +### Patch Changes + +- update relayer gas refund options + +## 0.10.4 + +### Patch Changes + +- Update api proto + +## 0.10.3 + +### Patch Changes + +- Fix loading config cross-chain + +## 0.10.2 + +### Patch Changes + +- - message digest fix + +## 0.10.1 + +### Patch Changes + +- upgrade deps + +## 0.10.0 + +### Minor Changes + +- Deployed new contracts with ERC1271 signer support + +## 0.9.6 + +### Patch Changes + +- Update ABIs for latest sequence contracts + +## 0.9.3 + +### Patch Changes + +- - minor improvements + +## 0.9.1 + +### Patch Changes + +- - patch bump + +## 0.9.0 + +### Minor Changes + +- - provider transport hardening + +## 0.8.5 + +### Patch Changes + +- - use latest wallet-contracts + +## 0.8.4 + +### Patch Changes + +- - minor improvements, name updates and comments + +## 0.8.3 + +### Patch Changes + +- - refinements + + - normalize signer address in config + + - provider: getWalletState() method to WalletProvider + +## 0.8.2 + +### Patch Changes + +- - field rename and ethauth dependency bump + +## 0.8.1 + +### Patch Changes + +- - variety of optimizations + +## 0.8.0 + +### Minor Changes + +- - changeset fix + +## 0.7.0 + +### Patch Changes + +- 6f11ed7: sequence.js, init release diff --git a/packages/guard/README.md b/packages/guard/README.md new file mode 100644 index 0000000000..9da6b41be3 --- /dev/null +++ b/packages/guard/README.md @@ -0,0 +1,4 @@ +@0xsequence/guard +================= + +See [0xsequence project page](https://github.com/0xsequence/sequence.js). diff --git a/packages/guard/package.json b/packages/guard/package.json new file mode 100644 index 0000000000..7f8afc9b03 --- /dev/null +++ b/packages/guard/package.json @@ -0,0 +1,26 @@ +{ + "name": "@0xsequence/guard", + "version": "2.0.0", + "description": "guard sub-package for Sequence", + "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/guard", + "source": "src/index.ts", + "main": "dist/0xsequence-guard.cjs.js", + "module": "dist/0xsequence-guard.esm.js", + "author": "Horizon Blockchain Games", + "license": "Apache-2.0", + "scripts": { + "test": "echo", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@0xsequence/account": "workspace:*", + "@0xsequence/core": "workspace:*", + "@0xsequence/signhub": "workspace:*", + "@0xsequence/utils": "workspace:*", + "ethers": "^5.7.2" + }, + "files": [ + "src", + "dist" + ] +} diff --git a/packages/guard/src/guard.gen.ts b/packages/guard/src/guard.gen.ts new file mode 100644 index 0000000000..519740c299 --- /dev/null +++ b/packages/guard/src/guard.gen.ts @@ -0,0 +1,814 @@ +/* eslint-disable */ +// sequence-guard v0.4.0 5b203e30a5c79b2b9a37483ce17500a51b94ebe1 +// -- +// Code generated by webrpc-gen@v0.18.6 with typescript generator. DO NOT EDIT. +// +// webrpc-gen -schema=guard.ridl -target=typescript -client -out=./clients/guard.gen.ts + +// WebRPC description and code-gen version +export const WebRPCVersion = 'v1' + +// Schema version of your RIDL schema +export const WebRPCSchemaVersion = 'v0.4.0' + +// Schema hash generated from your RIDL schema +export const WebRPCSchemaHash = '5b203e30a5c79b2b9a37483ce17500a51b94ebe1' + +// +// Types +// + +export interface Version { + webrpcVersion: string + schemaVersion: string + schemaHash: string + appVersion: string +} + +export interface RuntimeStatus { + healthOK: boolean + startTime: string + uptime: number + ver: string + branch: string + commitHash: string +} + +export interface WalletConfig { + address: string + content: string +} + +export interface WalletSigner { + address: string + weight: number +} + +export interface SignRequest { + chainId: number + msg: string + auxData: string +} + +export interface OwnershipProof { + wallet: string + timestamp: number + signer: string + signature: string +} + +export interface AuthToken { + id: string + token: string +} + +export interface RecoveryCode { + code: string + used: boolean +} + +export interface Guard { + ping(headers?: object, signal?: AbortSignal): Promise + version(headers?: object, signal?: AbortSignal): Promise + runtimeStatus(headers?: object, signal?: AbortSignal): Promise + getSignerConfig(args: GetSignerConfigArgs, headers?: object, signal?: AbortSignal): Promise + sign(args: SignArgs, headers?: object, signal?: AbortSignal): Promise + signWith(args: SignWithArgs, headers?: object, signal?: AbortSignal): Promise + patch(args: PatchArgs, headers?: object, signal?: AbortSignal): Promise + authMethods(args: AuthMethodsArgs, headers?: object, signal?: AbortSignal): Promise + setPIN(args: SetPINArgs, headers?: object, signal?: AbortSignal): Promise + resetPIN(args: ResetPINArgs, headers?: object, signal?: AbortSignal): Promise + createTOTP(args: CreateTOTPArgs, headers?: object, signal?: AbortSignal): Promise + commitTOTP(args: CommitTOTPArgs, headers?: object, signal?: AbortSignal): Promise + resetTOTP(args: ResetTOTPArgs, headers?: object, signal?: AbortSignal): Promise + reset2FA(args: Reset2FAArgs, headers?: object, signal?: AbortSignal): Promise + recoveryCodes(args: RecoveryCodesArgs, headers?: object, signal?: AbortSignal): Promise + resetRecoveryCodes(args: ResetRecoveryCodesArgs, headers?: object, signal?: AbortSignal): Promise +} + +export interface PingArgs {} + +export interface PingReturn { + status: boolean +} +export interface VersionArgs {} + +export interface VersionReturn { + version: Version +} +export interface RuntimeStatusArgs {} + +export interface RuntimeStatusReturn { + status: RuntimeStatus +} +export interface GetSignerConfigArgs { + signer: string +} + +export interface GetSignerConfigReturn { + signerConfig: WalletConfig +} +export interface SignArgs { + request: SignRequest + token?: AuthToken +} + +export interface SignReturn { + sig: string +} +export interface SignWithArgs { + signer: string + request: SignRequest + token?: AuthToken +} + +export interface SignWithReturn { + sig: string +} +export interface PatchArgs { + signer: string + chainId: number + secret: string +} + +export interface PatchReturn { + txs: any +} +export interface AuthMethodsArgs { + proof?: OwnershipProof +} + +export interface AuthMethodsReturn { + methods: Array + active: boolean +} +export interface SetPINArgs { + pin: string + timestamp: number + signature: string +} + +export interface SetPINReturn {} +export interface ResetPINArgs { + timestamp: number + signature: string +} + +export interface ResetPINReturn {} +export interface CreateTOTPArgs { + timestamp: number + signature: string +} + +export interface CreateTOTPReturn { + uri: string +} +export interface CommitTOTPArgs { + token: string +} + +export interface CommitTOTPReturn { + codes: Array +} +export interface ResetTOTPArgs { + timestamp: number + signature: string +} + +export interface ResetTOTPReturn {} +export interface Reset2FAArgs { + code: string + proof?: OwnershipProof +} + +export interface Reset2FAReturn {} +export interface RecoveryCodesArgs { + timestamp: number + signature: string +} + +export interface RecoveryCodesReturn { + codes: Array +} +export interface ResetRecoveryCodesArgs { + timestamp: number + signature: string +} + +export interface ResetRecoveryCodesReturn { + codes: Array +} + +// +// Client +// +export class Guard implements Guard { + protected hostname: string + protected fetch: Fetch + protected path = '/rpc/Guard/' + + constructor(hostname: string, fetch: Fetch) { + this.hostname = hostname + this.fetch = (input: RequestInfo, init?: RequestInit) => fetch(input, init) + } + + private url(name: string): string { + return this.hostname + this.path + name + } + + ping = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('Ping'), createHTTPRequest({}, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + status: _data.status + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + version = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('Version'), createHTTPRequest({}, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + version: _data.version + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + runtimeStatus = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('RuntimeStatus'), createHTTPRequest({}, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + status: _data.status + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + getSignerConfig = (args: GetSignerConfigArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetSignerConfig'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + signerConfig: _data.signerConfig + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + sign = (args: SignArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('Sign'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + sig: _data.sig + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + signWith = (args: SignWithArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('SignWith'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + sig: _data.sig + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + patch = (args: PatchArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('Patch'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + txs: _data.txs + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + authMethods = (args: AuthMethodsArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('AuthMethods'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + methods: >_data.methods, + active: _data.active + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + setPIN = (args: SetPINArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('SetPIN'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return {} + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + resetPIN = (args: ResetPINArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('ResetPIN'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return {} + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + createTOTP = (args: CreateTOTPArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('CreateTOTP'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + uri: _data.uri + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + commitTOTP = (args: CommitTOTPArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('CommitTOTP'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + codes: >_data.codes + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + resetTOTP = (args: ResetTOTPArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('ResetTOTP'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return {} + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + reset2FA = (args: Reset2FAArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('Reset2FA'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return {} + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + recoveryCodes = (args: RecoveryCodesArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('RecoveryCodes'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + codes: >_data.codes + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + resetRecoveryCodes = ( + args: ResetRecoveryCodesArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('ResetRecoveryCodes'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + codes: >_data.codes + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } +} + +const createHTTPRequest = (body: object = {}, headers: object = {}, signal: AbortSignal | null = null): object => { + return { + method: 'POST', + headers: { ...headers, 'Content-Type': 'application/json' }, + body: JSON.stringify(body || {}), + signal + } +} + +const buildResponse = (res: Response): Promise => { + return res.text().then(text => { + let data + try { + data = JSON.parse(text) + } catch (error) { + let message = '' + if (error instanceof Error) { + message = error.message + } + throw WebrpcBadResponseError.new({ + status: res.status, + cause: `JSON.parse(): ${message}: response text: ${text}` + }) + } + if (!res.ok) { + const code: number = typeof data.code === 'number' ? data.code : 0 + throw (webrpcErrorByCode[code] || WebrpcError).new(data) + } + return data + }) +} + +// +// Errors +// + +export class WebrpcError extends Error { + name: string + code: number + message: string + status: number + cause?: string + + /** @deprecated Use message instead of msg. Deprecated in webrpc v0.11.0. */ + msg: string + + constructor(name: string, code: number, message: string, status: number, cause?: string) { + super(message) + this.name = name || 'WebrpcError' + this.code = typeof code === 'number' ? code : 0 + this.message = message || `endpoint error ${this.code}` + this.msg = this.message + this.status = typeof status === 'number' ? status : 0 + this.cause = cause + Object.setPrototypeOf(this, WebrpcError.prototype) + } + + static new(payload: any): WebrpcError { + return new this(payload.error, payload.code, payload.message || payload.msg, payload.status, payload.cause) + } +} + +// Webrpc errors + +export class WebrpcEndpointError extends WebrpcError { + constructor( + name: string = 'WebrpcEndpoint', + code: number = 0, + message: string = 'endpoint error', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcEndpointError.prototype) + } +} + +export class WebrpcRequestFailedError extends WebrpcError { + constructor( + name: string = 'WebrpcRequestFailed', + code: number = -1, + message: string = 'request failed', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcRequestFailedError.prototype) + } +} + +export class WebrpcBadRouteError extends WebrpcError { + constructor( + name: string = 'WebrpcBadRoute', + code: number = -2, + message: string = 'bad route', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadRouteError.prototype) + } +} + +export class WebrpcBadMethodError extends WebrpcError { + constructor( + name: string = 'WebrpcBadMethod', + code: number = -3, + message: string = 'bad method', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadMethodError.prototype) + } +} + +export class WebrpcBadRequestError extends WebrpcError { + constructor( + name: string = 'WebrpcBadRequest', + code: number = -4, + message: string = 'bad request', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadRequestError.prototype) + } +} + +export class WebrpcBadResponseError extends WebrpcError { + constructor( + name: string = 'WebrpcBadResponse', + code: number = -5, + message: string = 'bad response', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadResponseError.prototype) + } +} + +export class WebrpcServerPanicError extends WebrpcError { + constructor( + name: string = 'WebrpcServerPanic', + code: number = -6, + message: string = 'server panic', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcServerPanicError.prototype) + } +} + +export class WebrpcInternalErrorError extends WebrpcError { + constructor( + name: string = 'WebrpcInternalError', + code: number = -7, + message: string = 'internal error', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcInternalErrorError.prototype) + } +} + +export class WebrpcClientDisconnectedError extends WebrpcError { + constructor( + name: string = 'WebrpcClientDisconnected', + code: number = -8, + message: string = 'client disconnected', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcClientDisconnectedError.prototype) + } +} + +export class WebrpcStreamLostError extends WebrpcError { + constructor( + name: string = 'WebrpcStreamLost', + code: number = -9, + message: string = 'stream lost', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcStreamLostError.prototype) + } +} + +export class WebrpcStreamFinishedError extends WebrpcError { + constructor( + name: string = 'WebrpcStreamFinished', + code: number = -10, + message: string = 'stream finished', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcStreamFinishedError.prototype) + } +} + +// Schema errors + +export class UnauthorizedError extends WebrpcError { + constructor( + name: string = 'Unauthorized', + code: number = 1000, + message: string = 'Unauthorized access', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, UnauthorizedError.prototype) + } +} + +export class SessionExpiredError extends WebrpcError { + constructor( + name: string = 'SessionExpired', + code: number = 1002, + message: string = 'Session expired', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, SessionExpiredError.prototype) + } +} + +export class AbortedError extends WebrpcError { + constructor( + name: string = 'Aborted', + code: number = 1005, + message: string = 'Request aborted', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, AbortedError.prototype) + } +} + +export class InvalidArgumentError extends WebrpcError { + constructor( + name: string = 'InvalidArgument', + code: number = 2001, + message: string = 'Invalid argument', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, InvalidArgumentError.prototype) + } +} + +export class UnavailableError extends WebrpcError { + constructor( + name: string = 'Unavailable', + code: number = 2002, + message: string = 'Unavailable resource', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, UnavailableError.prototype) + } +} + +export class QueryFailedError extends WebrpcError { + constructor( + name: string = 'QueryFailed', + code: number = 2003, + message: string = 'Query failed', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, QueryFailedError.prototype) + } +} + +export class ValidationFailedError extends WebrpcError { + constructor( + name: string = 'ValidationFailed', + code: number = 2004, + message: string = 'Validation Failed', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, ValidationFailedError.prototype) + } +} + +export class NotFoundError extends WebrpcError { + constructor( + name: string = 'NotFound', + code: number = 3000, + message: string = 'Resource not found', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, NotFoundError.prototype) + } +} + +export enum errors { + WebrpcEndpoint = 'WebrpcEndpoint', + WebrpcRequestFailed = 'WebrpcRequestFailed', + WebrpcBadRoute = 'WebrpcBadRoute', + WebrpcBadMethod = 'WebrpcBadMethod', + WebrpcBadRequest = 'WebrpcBadRequest', + WebrpcBadResponse = 'WebrpcBadResponse', + WebrpcServerPanic = 'WebrpcServerPanic', + WebrpcInternalError = 'WebrpcInternalError', + WebrpcClientDisconnected = 'WebrpcClientDisconnected', + WebrpcStreamLost = 'WebrpcStreamLost', + WebrpcStreamFinished = 'WebrpcStreamFinished', + Unauthorized = 'Unauthorized', + SessionExpired = 'SessionExpired', + Aborted = 'Aborted', + InvalidArgument = 'InvalidArgument', + Unavailable = 'Unavailable', + QueryFailed = 'QueryFailed', + ValidationFailed = 'ValidationFailed', + NotFound = 'NotFound' +} + +const webrpcErrorByCode: { [code: number]: any } = { + [0]: WebrpcEndpointError, + [-1]: WebrpcRequestFailedError, + [-2]: WebrpcBadRouteError, + [-3]: WebrpcBadMethodError, + [-4]: WebrpcBadRequestError, + [-5]: WebrpcBadResponseError, + [-6]: WebrpcServerPanicError, + [-7]: WebrpcInternalErrorError, + [-8]: WebrpcClientDisconnectedError, + [-9]: WebrpcStreamLostError, + [-10]: WebrpcStreamFinishedError, + [1000]: UnauthorizedError, + [1002]: SessionExpiredError, + [1005]: AbortedError, + [2001]: InvalidArgumentError, + [2002]: UnavailableError, + [2003]: QueryFailedError, + [2004]: ValidationFailedError, + [3000]: NotFoundError +} + +export type Fetch = (input: RequestInfo, init?: RequestInit) => Promise diff --git a/packages/guard/src/index.ts b/packages/guard/src/index.ts new file mode 100644 index 0000000000..d4a9b72a02 --- /dev/null +++ b/packages/guard/src/index.ts @@ -0,0 +1,2 @@ +export { Guard } from './guard.gen' +export * from './signer' diff --git a/packages/guard/src/signer.ts b/packages/guard/src/signer.ts new file mode 100644 index 0000000000..ba0c5288a3 --- /dev/null +++ b/packages/guard/src/signer.ts @@ -0,0 +1,294 @@ +import { Account } from '@0xsequence/account' +import { commons, universal } from '@0xsequence/core' +import { signers, Status } from '@0xsequence/signhub' +import { encodeTypedDataDigest, TypedData } from '@0xsequence/utils' +import { BytesLike, ethers, TypedDataDomain } from 'ethers' +import { AuthMethodsReturn, Guard, RecoveryCode as GuardRecoveryCode } from './guard.gen' + +const fetch = typeof global === 'object' ? global.fetch : window.fetch + +export class GuardSigner implements signers.SapientSigner { + private guard: Guard + + constructor( + public readonly address: string, + public readonly url: string, + public readonly appendSuffix: boolean = false + ) { + this.guard = new Guard(url, fetch) + } + + async getAddress(): Promise { + return this.address + } + + async buildDeployTransaction(_metadata: object): Promise { + return undefined + } + + async predecorateSignedTransactions(_metadata: object): Promise { + return [] + } + + async decorateTransactions( + bundle: commons.transaction.IntendedTransactionBundle, + _metadata: object + ): Promise { + return bundle + } + + async sign(message: BytesLike, metadata: object): Promise { + if (!commons.isWalletSignRequestMetadata(metadata)) { + throw new Error('expected sequence signature request metadata') + } + + const guardTotpCode = (metadata as { guardTotpCode?: string }).guardTotpCode + + // Building auxData, notice: this uses the old v1 format + // TODO: We should update the guard API so we can pass the metadata directly + const coder = universal.genericCoderFor(metadata.config.version) + const { encoded } = coder.signature.encodeSigners(metadata.config, metadata.parts ?? new Map(), [], metadata.chainId) + + return ( + await this.guard.signWith({ + signer: this.address, + request: { + msg: ethers.utils.hexlify(message), + auxData: this.packMsgAndSig(metadata.address, metadata.digest, encoded, metadata.chainId), + chainId: ethers.BigNumber.from(metadata.chainId).toNumber() + }, + token: guardTotpCode ? { id: AuthMethod.TOTP, token: guardTotpCode } : undefined + }) + ).sig + } + + notifyStatusChange(_id: string, _status: Status, _metadata: object): void {} + + async getAuthMethods(proof: OwnershipProof): Promise<{ methods: AuthMethod[]; active: boolean }> { + let response: AuthMethodsReturn + + if ('jwt' in proof) { + response = await this.guard.authMethods({}, { Authorization: `BEARER ${proof.jwt}` }) + } else { + const signedProof = await signOwnershipProof(proof) + + response = await this.guard.authMethods({ + proof: { + wallet: signedProof.walletAddress, + timestamp: signedProof.timestamp.getTime(), + signer: signedProof.signerAddress, + signature: signedProof.signature + } + }) + } + + return { ...response, methods: response.methods.map(parseAuthMethod) } + } + + async setPin(pin: string | undefined, proof: AuthUpdateProof): Promise { + const signedProof = await signAuthUpdateProof(proof) + + if (pin === undefined) { + await this.guard.resetPIN( + { timestamp: signedProof.timestamp.getTime(), signature: signedProof.signature }, + { Authorization: `BEARER ${proof.jwt}` } + ) + } else { + await this.guard.setPIN( + { pin, timestamp: signedProof.timestamp.getTime(), signature: signedProof.signature }, + { Authorization: `BEARER ${proof.jwt}` } + ) + } + } + + resetPin(proof: AuthUpdateProof): Promise { + return this.setPin(undefined, proof) + } + + async createTotp(proof: AuthUpdateProof): Promise { + const signedProof = await signAuthUpdateProof(proof) + + const { uri } = await this.guard.createTOTP( + { timestamp: signedProof.timestamp.getTime(), signature: signedProof.signature }, + { Authorization: `BEARER ${proof.jwt}` } + ) + + return new URL(uri) + } + + async commitTotp(token: string, jwt: string): Promise { + const { codes } = await this.guard.commitTOTP({ token }, { Authorization: `BEARER ${jwt}` }) + return codes + } + + async resetTotp(proof: AuthUpdateProof): Promise { + const signedProof = await signAuthUpdateProof(proof) + + await this.guard.resetTOTP( + { timestamp: signedProof.timestamp.getTime(), signature: signedProof.signature }, + { Authorization: `BEARER ${proof.jwt}` } + ) + } + + async reset2fa(recoveryCode: string, proof: OwnershipProof): Promise { + if ('jwt' in proof) { + await this.guard.reset2FA({ code: recoveryCode }, { Authorization: `BEARER ${proof.jwt}` }) + } else { + const signedProof = await signOwnershipProof(proof) + + await this.guard.reset2FA({ + code: recoveryCode, + proof: { + wallet: signedProof.walletAddress, + timestamp: signedProof.timestamp.getTime(), + signer: signedProof.signerAddress, + signature: signedProof.signature + } + }) + } + } + + async getRecoveryCodes(proof: AuthUpdateProof): Promise { + const signedProof = await signAuthUpdateProof(proof) + + const { codes } = await this.guard.recoveryCodes( + { timestamp: signedProof.timestamp.getTime(), signature: signedProof.signature }, + { Authorization: `BEARER ${proof.jwt}` } + ) + + return codes + } + + async resetRecoveryCodes(proof: AuthUpdateProof): Promise { + const signedProof = await signAuthUpdateProof(proof) + + const { codes } = await this.guard.resetRecoveryCodes( + { timestamp: signedProof.timestamp.getTime(), signature: signedProof.signature }, + { Authorization: `BEARER ${proof.jwt}` } + ) + + return codes + } + + private packMsgAndSig(address: string, msg: BytesLike, sig: BytesLike, chainId: ethers.BigNumberish): string { + return ethers.utils.defaultAbiCoder.encode(['address', 'uint256', 'bytes', 'bytes'], [address, chainId, msg, sig]) + } + + suffix(): BytesLike { + return this.appendSuffix ? [3] : [] + } +} + +export type RecoveryCode = GuardRecoveryCode + +export enum AuthMethod { + PIN = 'PIN', + TOTP = 'TOTP' +} + +function parseAuthMethod(method: string): AuthMethod { + switch (method) { + case AuthMethod.PIN: + case AuthMethod.TOTP: + return method + default: + throw new Error(`unknown auth method '${method}'`) + } +} + +export type SignedOwnershipProof = { + walletAddress: string + timestamp: Date + signerAddress: string + signature: string +} + +export type OwnershipProof = + | SignedOwnershipProof + | { jwt: string } + | { + walletAddress: string + signer: ethers.Signer | signers.SapientSigner + } + +export function isSignedOwnershipProof(proof: OwnershipProof): proof is SignedOwnershipProof { + return 'signerAddress' in proof && typeof proof.signerAddress === 'string' +} + +export async function signOwnershipProof(proof: Exclude): Promise { + if (isSignedOwnershipProof(proof)) { + return proof + } else { + const signer = signers.isSapientSigner(proof.signer) ? proof.signer : new signers.SignerWrapper(proof.signer) + const signerAddress = await signer.getAddress() + const timestamp = new Date() + const typedData = getOwnershipProofTypedData(proof.walletAddress, timestamp) + const digest = encodeTypedDataDigest(typedData) + + return { + walletAddress: proof.walletAddress, + timestamp, + signerAddress, + signature: ethers.utils.hexlify(await signer.sign(digest, {})) + } + } +} + +export type AuthUpdateProof = { jwt: string } & ({ timestamp: Date; signature: string } | { wallet: Account }) + +async function signAuthUpdateProof(proof: AuthUpdateProof): Promise<{ jwt: string; timestamp: Date; signature: string }> { + if ('wallet' in proof) { + const timestamp = new Date() + const typedData = getAuthUpdateProofTypedData(timestamp) + + const signature = await proof.wallet.signTypedData( + typedData.domain, + typedData.types, + typedData.message, + typedData.domain.chainId ?? 1, + 'eip6492' + ) + + return { jwt: proof.jwt, timestamp, signature } + } else { + return proof + } +} + +export function getOwnershipProofTypedData(wallet: string, timestamp: Date): TypedData { + return { + domain, + types: { + AuthMethods: [ + { name: 'wallet', type: 'address' }, + { name: 'timestamp', type: 'string' } + ] + }, + message: { + wallet: ethers.utils.getAddress(wallet), + timestamp: toUTCString(timestamp) + } + } +} + +export function getAuthUpdateProofTypedData(timestamp: Date): TypedData { + return { + domain, + types: { + AuthUpdate: [{ name: 'timestamp', type: 'string' }] + }, + message: { + timestamp: toUTCString(timestamp) + } + } +} + +const domain: TypedDataDomain = { + name: 'Sequence Guard', + version: '1', + chainId: 1 +} + +function toUTCString(date: Date): string { + return date.toUTCString().replace('GMT', 'UTC') +} diff --git a/packages/indexer/CHANGELOG.md b/packages/indexer/CHANGELOG.md new file mode 100644 index 0000000000..5eac945aaf --- /dev/null +++ b/packages/indexer/CHANGELOG.md @@ -0,0 +1,1358 @@ +# @0xsequence/indexer + +## 1.10.8 + +### Patch Changes + +- update metadata bindings + +## 1.10.7 + +### Patch Changes + +- minor fixes to waas client + +## 1.10.6 + +### Patch Changes + +- metadata: update bindings + +## 1.10.5 + +### Patch Changes + +- network: ape-chain-testnet -> apechain-testnet + +## 1.10.4 + +### Patch Changes + +- network: add b3-sepolia, ape-chain-testnet, blast, blast-sepolia + +## 1.10.3 + +### Patch Changes + +- typing fix + +## 1.10.2 + +### Patch Changes + +- - waas: add getIdToken method + - indexer: update api client + +## 1.10.1 + +### Patch Changes + +- metadata: update bindings + +## 1.10.0 + +### Minor Changes + +- waas release v1.3.0 + +## 1.9.37 + +### Patch Changes + +- network: adds nativeToken data to NetworkMetadata constants + +## 1.9.36 + +### Patch Changes + +- guard: export client + +## 1.9.35 + +### Patch Changes + +- guard: update bindings + +## 1.9.34 + +### Patch Changes + +- waas: always use lowercase email + +## 1.9.33 + +### Patch Changes + +- waas: umd build + +## 1.9.32 + +### Patch Changes + +- indexer: update bindings + +## 1.9.31 + +### Patch Changes + +- metadata: token directory changes + +## 1.9.30 + +### Patch Changes + +- update + +## 1.9.29 + +### Patch Changes + +- disable gnosis chain + +## 1.9.28 + +### Patch Changes + +- add utils/merkletree + +## 1.9.27 + +### Patch Changes + +- network: optimistic -> optimism +- waas: remove defaults +- api, sessions: update bindings + +## 1.9.26 + +### Patch Changes + +- - add backend interfaces for pluggable interfaces + - introduce @0xsequence/react-native + - update pnpm to lockfile v9 + +## 1.9.25 + +### Patch Changes + +- update webrpc clients with new error types + +## 1.9.24 + +### Patch Changes + +- waas: add memoryStore backend to localStore + +## 1.9.23 + +### Patch Changes + +- update api client bindings + +## 1.9.22 + +### Patch Changes + +- update metadata client bindings + +## 1.9.21 + +### Patch Changes + +- api client bindings + +## 1.9.20 + +### Patch Changes + +- api client bindings update + +## 1.9.19 + +### Patch Changes + +- waas update + +## 1.9.18 + +### Patch Changes + +- provider: prohibit dangerous functions + +## 1.9.17 + +### Patch Changes + +- network: add xr-sepolia + +## 1.9.16 + +### Patch Changes + +- waas: sequence.feeOptions + +## 1.9.15 + +### Patch Changes + +- metadata: collection external_link field name fix + +## 1.9.14 + +### Patch Changes + +- network: astar-zkatana -> astar-zkyoto +- network: deprecate polygon mumbai network +- network: add xai and polygon amoy + +## 1.9.13 + +### Patch Changes + +- waas: fix @0xsequence/network dependency + +## 1.9.12 + +### Patch Changes + +- indexer: update rpc bindings +- provider: signMessage: Serialize the BytesLike or string message into hexstring before sending +- waas: SessionAuthProof + +## 1.9.11 + +### Patch Changes + +- metdata, update rpc bindings + +## 1.9.10 + +### Patch Changes + +- update metadata rpc bindings + +## 1.9.9 + +### Patch Changes + +- metadata, add SequenceCollections rpc client + +## 1.9.8 + +### Patch Changes + +- waas client update + +## 1.9.7 + +### Patch Changes + +- update rpc client bindings for api, metadata and relayer + +## 1.9.6 + +### Patch Changes + +- waas package update + +## 1.9.5 + +### Patch Changes + +- RpcRelayer prioritize project access key + +## 1.9.4 + +### Patch Changes + +- waas: fix network dependency + +## 1.9.3 + +### Patch Changes + +- provider: don't append access key to RPC url if user has already provided it + +## 1.9.2 + +### Patch Changes + +- network: add xai-sepolia + +## 1.9.1 + +### Patch Changes + +- analytics fix + +## 1.9.0 + +### Minor Changes + +- waas release + +## 1.8.8 + +### Patch Changes + +- update metadata bindings + +## 1.8.7 + +### Patch Changes + +- provider: update databeat to 0.9.1 + +## 1.8.6 + +### Patch Changes + +- guard: SignedOwnershipProof + +## 1.8.5 + +### Patch Changes + +- guard: signOwnershipProof and isSignedOwnershipProof + +## 1.8.4 + +### Patch Changes + +- network: add homeverse to networks list + +## 1.8.3 + +### Patch Changes + +- api: introduce basic linked wallet support + +## 1.8.2 + +### Patch Changes + +- provider: don't initialize analytics unless explicitly requested + +## 1.8.1 + +### Patch Changes + +- update to analytics provider + +## 1.8.0 + +### Minor Changes + +- provider: project analytics + +## 1.7.2 + +### Patch Changes + +- 0xsequence: ChainId should not be exported as a type +- account, wallet: fix nonce selection + +## 1.7.1 + +### Patch Changes + +- network: add missing avalanche logoURI + +## 1.7.0 + +### Minor Changes + +- provider: projectAccessKey is now required + +### Patch Changes + +- network: add NetworkMetadata.logoURI property for all networks + +## 1.6.3 + +### Patch Changes + +- network list update + +## 1.6.2 + +### Patch Changes + +- auth: projectAccessKey option +- wallet: use 12 bytes for random space + +## 1.6.1 + +### Patch Changes + +- core: add simple config from subdigest support +- core: fix encode tree with subdigest +- account: implement buildOnChainSignature on Account + +## 1.6.0 + +### Minor Changes + +- account, wallet: parallel transactions by default + +### Patch Changes + +- provider: emit disconnect on sign out + +## 1.5.0 + +### Minor Changes + +- signhub: add 'signing' signer status + +### Patch Changes + +- auth: Session.open: onAccountAddress callback +- account: allow empty transaction bundles + +## 1.4.9 + +### Patch Changes + +- rename SequenceMetadataClient to SequenceMetadata + +## 1.4.8 + +### Patch Changes + +- account: Account.getSigners + +## 1.4.7 + +### Patch Changes + +- update indexer client bindings + +## 1.4.6 + +### Patch Changes + +- - add sepolia networks, mark goerli as deprecated + - update indexer client bindings + +## 1.4.5 + +### Patch Changes + +- indexer/metadata: update client bindings +- auth: selectWallet with new address + +## 1.4.4 + +### Patch Changes + +- indexer: update bindings +- auth: handle jwt expiry + +## 1.4.3 + +### Patch Changes + +- guard: return active status from GuardSigner.getAuthMethods + +## 1.4.2 + +### Patch Changes + +- guard: update bindings + +## 1.4.1 + +### Patch Changes + +- network: remove unused networks +- signhub: orchestrator interface +- guard: auth methods interface +- guard: update bindings for pin and totp +- guard: no more retry logic + +## 1.4.0 + +### Minor Changes + +- project access key support + +## 1.3.0 + +### Minor Changes + +- signhub: account children + +### Patch Changes + +- guard: do not throw when building deploy transaction +- network: snowtrace.io -> subnets.avax.network/c-chain + +## 1.2.9 + +### Patch Changes + +- account: AccountSigner.sendTransaction simulateForFeeOptions +- relayer: update bindings + +## 1.2.8 + +### Patch Changes + +- rename X-Sequence-Token-Key header to X-Access-Key + +## 1.2.7 + +### Patch Changes + +- add x-sequence-token-key to clients + +## 1.2.6 + +### Patch Changes + +- Fix bind multicall provider + +## 1.2.5 + +### Patch Changes + +- Multicall default configuration fixes + +## 1.2.4 + +### Patch Changes + +- provider: Adding missing payment provider types to PaymentProviderOption +- provider: WalletRequestHandler.notifyChainChanged + +## 1.2.3 + +### Patch Changes + +- auth, provider: connect to accept optional authorizeNonce + +## 1.2.2 + +### Patch Changes + +- provider: allow createContract calls +- core: check for explicit zero address in contract deployments + +## 1.2.1 + +### Patch Changes + +- auth: use sequence api chain id as reference chain id if available + +## 1.2.0 + +### Minor Changes + +- split services from session, better local support + +## 1.1.15 + +### Patch Changes + +- guard: remove error filtering + +## 1.1.14 + +### Patch Changes + +- guard: add GuardSigner.onError + +## 1.1.13 + +### Patch Changes + +- provider: pass client version with connect options +- provider: removing large from BannerSize + +## 1.1.12 + +### Patch Changes + +- provider: adding bannerSize to ConnectOptions + +## 1.1.11 + +### Patch Changes + +- add homeverse configs + +## 1.1.10 + +### Patch Changes + +- handle default EIP6492 on send + +## 1.1.9 + +### Patch Changes + +- Custom default EIP6492 on client + +## 1.1.8 + +### Patch Changes + +- metadata: searchMetadata: add types filter + +## 1.1.7 + +### Patch Changes + +- adding signInWith connect settings option to allow dapps to automatically login their users with a certain provider optimizing the normal authentication flow + +## 1.1.6 + +### Patch Changes + +- metadata: searchMetadata: add chainID and excludeTokenMetadata filters + +## 1.1.5 + +### Patch Changes + +- account: re-compute meta-transaction id for wallet deployment transactions + +## 1.1.4 + +### Patch Changes + +- network: rename base-mainnet to base +- provider: override isDefaultChain with ConnectOptions.networkId if provided + +## 1.1.3 + +### Patch Changes + +- provider: use network id from transport session +- provider: sign authorization using ConnectOptions.networkId if provided + +## 1.1.2 + +### Patch Changes + +- provider: jsonrpc chain id fixes + +## 1.1.1 + +### Patch Changes + +- network: add base mainnet and sepolia +- provider: reject toxic transaction requests + +## 1.1.0 + +### Minor Changes + +- Refactor dapp facing provider + +## 1.0.5 + +### Patch Changes + +- network: export network constants +- guard: use the correct global for fetch +- network: nova-explorer.arbitrum.io -> nova.arbiscan.io + +## 1.0.4 + +### Patch Changes + +- provider: accept name or number for networkId + +## 1.0.3 + +### Patch Changes + +- Simpler isValidSignature helpers + +## 1.0.2 + +### Patch Changes + +- add extra signature validation utils methods + +## 1.0.1 + +### Patch Changes + +- add homeverse testnet + +## 1.0.0 + +### Major Changes + +- https://sequence.xyz/blog/sequence-wallet-light-state-sync-full-merkle-wallets + +## 0.43.34 + +### Patch Changes + +- auth: no jwt for indexer + +## 0.43.33 + +### Patch Changes + +- Adding onConnectOptionsChange handler to WalletRequestHandler + +## 0.43.32 + +### Patch Changes + +- add Base Goerli network + +## 0.43.31 + +### Patch Changes + +- remove AuxDataProvider, add promptSignInConnect + +## 0.43.30 + +### Patch Changes + +- add arbitrum goerli testnet + +## 0.43.29 + +### Patch Changes + +- provider: check availability of window object + +## 0.43.28 + +### Patch Changes + +- update api bindings + +## 0.43.27 + +### Patch Changes + +- Add rpc is sequence method + +## 0.43.26 + +### Patch Changes + +- add zkevm url to enum + +## 0.43.25 + +### Patch Changes + +- added polygon zkevm to mainnet networks + +## 0.43.24 + +### Patch Changes + +- name change from zkevm to polygon-zkevm + +## 0.43.23 + +### Patch Changes + +- update zkEVM name to Polygon zkEVM + +## 0.43.22 + +### Patch Changes + +- add zkevm chain + +## 0.43.21 + +### Patch Changes + +- api: update client bindings + +## 0.43.20 + +### Patch Changes + +- indexer: update bindings + +## 0.43.19 + +### Patch Changes + +- session proof update + +## 0.43.18 + +### Patch Changes + +- rpc client global check, hardening + +## 0.43.17 + +### Patch Changes + +- rpc clients, check of 'global' is defined + +## 0.43.16 + +### Patch Changes + +- ethers peerDep to v5, update rpc client global use + +## 0.43.15 + +### Patch Changes + +- - provider: expand receiver type on some util methods + +## 0.43.14 + +### Patch Changes + +- bump + +## 0.43.13 + +### Patch Changes + +- update rpc bindings + +## 0.43.12 + +### Patch Changes + +- provider: single wallet init, and add new unregisterWallet() method + +## 0.43.11 + +### Patch Changes + +- fix lockfiles +- re-add mocha type deleter + +## 0.43.10 + +### Patch Changes + +- various improvements + +## 0.43.9 + +### Patch Changes + +- update deps + +## 0.43.8 + +### Patch Changes + +- network: JsonRpcProvider with caching + +## 0.43.7 + +### Patch Changes + +- provider: fix wallet network init + +## 0.43.6 + +### Patch Changes + +- metadatata: update rpc bindings + +## 0.43.5 + +### Patch Changes + +- provider: do not set default network for connect messages +- provider: forward missing error message + +## 0.43.4 + +### Patch Changes + +- no-change version bump to fix incorrectly tagged snapshot build + +## 0.43.3 + +### Patch Changes + +- metadata: update bindings + +## 0.43.2 + +### Patch Changes + +- provider: implement connectUnchecked + +## 0.43.1 + +### Patch Changes + +- update to latest ethauth dep + +## 0.43.0 + +### Minor Changes + +- move ethers to a peer dependency + +## 0.42.10 + +### Patch Changes + +- add auxDataProvider + +## 0.42.9 + +### Patch Changes + +- provider: add eip-191 exceptions + +## 0.42.8 + +### Patch Changes + +- provider: skip setting intent origin if we're unity plugin + +## 0.42.7 + +### Patch Changes + +- Add sign in options to connection settings + +## 0.42.6 + +### Patch Changes + +- api bindings update + +## 0.42.5 + +### Patch Changes + +- relayer: don't treat missing receipt as hard failure + +## 0.42.4 + +### Patch Changes + +- provider: add custom app protocol to connect options + +## 0.42.3 + +### Patch Changes + +- update api bindings + +## 0.42.2 + +### Patch Changes + +- disable rinkeby network + +## 0.42.1 + +### Patch Changes + +- wallet: optional waitForReceipt parameter + +## 0.42.0 + +### Minor Changes + +- relayer: estimateGasLimits -> simulate +- add simulator package + +### Patch Changes + +- transactions: fix flattenAuxTransactions +- provider: only filter nullish values +- provider: re-map transaction 'gas' back to 'gasLimit' + +## 0.41.3 + +### Patch Changes + +- api bindings update + +## 0.41.2 + +### Patch Changes + +- api bindings update + +## 0.41.1 + +### Patch Changes + +- update default networks + +## 0.41.0 + +### Minor Changes + +- relayer: fix Relayer.wait() interface + + The interface for calling Relayer.wait() has changed. Instead of a single optional ill-defined timeout/delay parameter, there are three optional parameters, in order: + + - timeout: the maximum time to wait for the transaction receipt + - delay: the polling interval, i.e. the time to wait between requests + - maxFails: the maximum number of hard failures to tolerate before giving up + + Please update your codebase accordingly. + +- relayer: add optional waitForReceipt parameter to Relayer.relay + + The behaviour of Relayer.relay() was not well-defined with respect to whether or not it waited for a receipt. + This change allows the caller to specify whether to wait or not, with the default behaviour being to wait. + +### Patch Changes + +- relayer: wait receipt retry logic +- fix wrapped object error +- provider: forward delegateCall and revertOnError transaction fields + +## 0.40.6 + +### Patch Changes + +- add arbitrum-nova chain + +## 0.40.5 + +### Patch Changes + +- api: update bindings + +## 0.40.4 + +### Patch Changes + +- add unreal transport + +## 0.40.3 + +### Patch Changes + +- provider: fix MessageToSign message type + +## 0.40.2 + +### Patch Changes + +- Wallet provider, loadSession method + +## 0.40.1 + +### Patch Changes + +- export sequence.initWallet and sequence.getWallet + +## 0.40.0 + +### Minor Changes + +- add sequence.initWallet(network, config) and sequence.getWallet() helper methods + +## 0.39.6 + +### Patch Changes + +- indexer: update client bindings + +## 0.39.5 + +### Patch Changes + +- provider: fix networkRpcUrl config option + +## 0.39.4 + +### Patch Changes + +- api: update client bindings + +## 0.39.3 + +### Patch Changes + +- add request method on Web3Provider + +## 0.39.2 + +### Patch Changes + +- update umd name + +## 0.39.1 + +### Patch Changes + +- add Aurora network +- add origin info for accountsChanged event to handle it per dapp + +## 0.39.0 + +### Minor Changes + +- abstract window.localStorage to interface type + +## 0.38.2 + +### Patch Changes + +- provider: add Settings.defaultPurchaseAmount + +## 0.38.1 + +### Patch Changes + +- update api and metadata rpc bindings + +## 0.38.0 + +### Minor Changes + +- api: update bindings, change TokenPrice interface +- bridge: remove @0xsequence/bridge package +- api: update bindings, rename ContractCallArg to TupleComponent + +## 0.37.1 + +### Patch Changes + +- Add back sortNetworks - Removing sorting was a breaking change for dapps on older versions which directly integrate sequence. + +## 0.37.0 + +### Minor Changes + +- network related fixes and improvements +- api: bindings: exchange rate lookups + +## 0.36.13 + +### Patch Changes + +- api: update bindings with new price endpoints + +## 0.36.12 + +### Patch Changes + +- wallet: skip remote signers if not needed +- auth: check that signature meets threshold before requesting auth token + +## 0.36.11 + +### Patch Changes + +- Prefix EIP191 message on wallet-request-handler + +## 0.36.10 + +### Patch Changes + +- support bannerUrl on connect + +## 0.36.9 + +### Patch Changes + +- minor dev xp improvements + +## 0.36.8 + +### Patch Changes + +- more connect options (theme, payment providers, funding currencies) + +## 0.36.7 + +### Patch Changes + +- fix missing break + +## 0.36.6 + +### Patch Changes + +- wallet_switchEthereumChain support + +## 0.36.5 + +### Patch Changes + +- auth: bump ethauth to 0.7.0 + network, wallet: don't assume position of auth network in list + api/indexer/metadata: trim trailing slash on hostname, and add endpoint urls + relayer: Allow to specify local relayer transaction parameters like gas price or gas limit + +## 0.36.4 + +### Patch Changes + +- Updating list of chain ids to include other ethereum compatible chains + +## 0.36.3 + +### Patch Changes + +- provider: pass connect options to prompter methods + +## 0.36.2 + +### Patch Changes + +- transactions: Setting target to 0x0 when empty to during SequenceTxAbiEncode + +## 0.36.1 + +### Patch Changes + +- metadata: update client with more fields + +## 0.36.0 + +### Minor Changes + +- relayer, wallet: fee quote support + +## 0.35.12 + +### Patch Changes + +- provider: rename wallet.commands to wallet.utils + +## 0.35.11 + +### Patch Changes + +- provider/utils: smoother message validation + +## 0.35.10 + +### Patch Changes + +- upgrade deps + +## 0.35.9 + +### Patch Changes + +- provider: window-transport override event handlers with new wallet instance + +## 0.35.8 + +### Patch Changes + +- provider: async wallet sign in improvements + +## 0.35.7 + +### Patch Changes + +- config: cache wallet configs + +## 0.35.6 + +### Patch Changes + +- provider: support async signin of wallet request handler + +## 0.35.5 + +### Patch Changes + +- wallet: skip threshold check during fee estimation + +## 0.35.4 + +### Patch Changes + +- - browser extension mode, center window + +## 0.35.3 + +### Patch Changes + +- - update window position when in browser extension mode + +## 0.35.2 + +### Patch Changes + +- - provider: WindowMessageHandler accept optional windowHref + +## 0.35.1 + +### Patch Changes + +- wallet: update config on undeployed too + +## 0.35.0 + +### Minor Changes + +- - config: add buildStubSignature + - provider: add checks to signing cases for wallet deployment and config statuses + - provider: add prompt for wallet deployment + - relayer: add BaseRelayer.prependWalletDeploy + - relayer: add Relayer.feeOptions + - relayer: account for wallet deployment in fee estimation + - transactions: add fromTransactionish + - wallet: add Account.prependConfigUpdate + - wallet: add Account.getFeeOptions + +## 0.34.0 + +### Minor Changes + +- - upgrade deps + +## 0.31.0 + +### Minor Changes + +- - upgrading to ethers v5.5 + +## 0.30.0 + +### Minor Changes + +- - upgrade most deps + +## 0.29.8 + +### Patch Changes + +- update api + +## 0.29.3 + +### Patch Changes + +- indexer: add bridge contract types + +## 0.29.0 + +### Minor Changes + +- major architectural changes in Sequence design + + - only one API instance, API is no longer a per-chain service + - separate per-chain indexer service, API no longer handles indexing + - single contract metadata service, API no longer serves metadata + + chaind package has been removed, indexer and metadata packages have been added + + stronger typing with new explicit ChainId type + + multicall fixes and improvements + + forbid "wait" transactions in sendTransactionBatch calls diff --git a/packages/indexer/README.md b/packages/indexer/README.md new file mode 100644 index 0000000000..dfffc4c7a5 --- /dev/null +++ b/packages/indexer/README.md @@ -0,0 +1,4 @@ +@0xsequence/indexer +=================== + +See [0xsequence project page](https://github.com/0xsequence/sequence.js). diff --git a/packages/indexer/package.json b/packages/indexer/package.json new file mode 100644 index 0000000000..c38233a323 --- /dev/null +++ b/packages/indexer/package.json @@ -0,0 +1,22 @@ +{ + "name": "@0xsequence/indexer", + "version": "2.0.0", + "description": "indexer sub-package for Sequence", + "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/indexer", + "source": "src/index.ts", + "main": "dist/0xsequence-indexer.cjs.js", + "module": "dist/0xsequence-indexer.esm.js", + "author": "Horizon Blockchain Games", + "license": "Apache-2.0", + "scripts": { + "test": "echo", + "typecheck": "tsc --noEmit" + }, + "dependencies": {}, + "peerDependencies": {}, + "devDependencies": {}, + "files": [ + "src", + "dist" + ] +} diff --git a/packages/indexer/src/index.ts b/packages/indexer/src/index.ts new file mode 100644 index 0000000000..544c2ce4ba --- /dev/null +++ b/packages/indexer/src/index.ts @@ -0,0 +1,38 @@ +export * from './indexer.gen' + +import { Indexer as IndexerRpc } from './indexer.gen' + +const fetch = typeof global === 'object' ? global.fetch : window.fetch + +export class SequenceIndexer extends IndexerRpc { + constructor( + hostname: string, + public projectAccessKey?: string, + public jwtAuth?: string + ) { + super(hostname.endsWith('/') ? hostname.slice(0, -1) : hostname, fetch) + this.fetch = this._fetch + } + + _fetch = (input: RequestInfo, init?: RequestInit): Promise => { + // automatically include jwt and access key auth header to requests + // if its been set on the api client + const headers: { [key: string]: any } = {} + + const jwtAuth = this.jwtAuth + const projectAccessKey = this.projectAccessKey + + if (jwtAuth && jwtAuth.length > 0) { + headers['Authorization'] = `BEARER ${jwtAuth}` + } + + if (projectAccessKey && projectAccessKey.length > 0) { + headers['X-Access-Key'] = projectAccessKey + } + + // before the request is made + init!.headers = { ...init!.headers, ...headers } + + return fetch(input, init) + } +} diff --git a/packages/indexer/src/indexer.gen.ts b/packages/indexer/src/indexer.gen.ts new file mode 100644 index 0000000000..0fc4a52a15 --- /dev/null +++ b/packages/indexer/src/indexer.gen.ts @@ -0,0 +1,2763 @@ +/* eslint-disable */ +// sequence-indexer v0.4.0 cfbb0160fed6f7e2208a73cad454f3cddace9c7a +// -- +// Code generated by Webrpc-gen@v0.31.2 with typescript generator. DO NOT EDIT. +// +// webrpc-gen -schema=merged.gen.json -service=Indexer -target=typescript -client -out=./clients/indexer.gen.ts + +// Webrpc description and code-gen version +export const WebrpcVersion = 'v1' + +// Schema version of your RIDL schema +export const WebrpcSchemaVersion = 'v0.4.0' + +// Schema hash generated from your RIDL schema +export const WebrpcSchemaHash = 'cfbb0160fed6f7e2208a73cad454f3cddace9c7a' + +// +// Client interface +// + +export interface IndexerClient { + addWebhookListener(req: AddWebhookListenerRequest, headers?: object, signal?: AbortSignal): Promise + + /** + * Fetches a single receipt and then will stop the subscription + */ + fetchTransactionReceipt( + req: FetchTransactionReceiptRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + /** + * Fetches a single receipt with filter and then will stop the subscription + */ + fetchTransactionReceiptWithFilter( + req: FetchTransactionReceiptWithFilterRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + /** + * Webhooks + */ + getAllWebhookListeners( + req: GetAllWebhookListenersRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + /** + * Get balance update aggregate values -- useful for syncing balance details of a contract, ie. from Skyweaver. + * Also consider using SubscribeBalanceUpdates or SubscribeEvents as other alternatives. + */ + getBalanceUpdates(req: GetBalanceUpdatesRequest, headers?: object, signal?: AbortSignal): Promise + + /** + * Get the chain ID of the indexer + */ + getChainID(headers?: object, signal?: AbortSignal): Promise + + /** + * Queries an ethereum node for the latest and confirm ETH balances + * DEPRECATED: use GetNativeTokenBalance instead + * + * @deprecated GetNativeTokenBalance + */ + getEtherBalance(req: GetEtherBalanceRequest, headers?: object, signal?: AbortSignal): Promise + + /** + * GetMarketplaceOrders queries marketplace orders with filtering and pagination. + * + * Retrieves buy orders (offers) and sell orders (listings) from a specific marketplace + * and collection with comprehensive filtering options. + * + * Parameters: + * marketplaceContractAddress: Target marketplace contract (required) + * collectionAddress: NFT collection contract (required) + * filter: MarketplaceOrderFilter with options: + * - isListing: true=listings, false=offers, omit=both + * - userAddresses: Include specific users + * - currencyAddresses: Filter by currencies (empty=all) + * - orderIds: Filter by specific order ids (empty=all) + * - tokenIds: Filter by specific tokens (empty=all) + * - excludeUserAddresses: Exclude specific users + * - blockNumberGt: Orders greater than block number + * - createdAtAfter: Orders after timestamp + * - orderStatuses: Filter by status (OPEN, CLOSED, CANCELLED) + * - returnExpired: Include expired orders + * page: Pagination control (optional) + * + * Returns: Updated pagination info and array of matching orders + */ + getMarketplaceOrders( + req: GetMarketplaceOrdersRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + /** + * GetMarketplaceTopOrders finds the most competitive orders for specific tokens. + * + * Optimized for price discovery, returns the best available orders for each token. + * Useful for displaying current market prices and finding trading opportunities. + * + * Parameters: + * marketplaceContractAddress: Target marketplace contract (required) + * collectionAddress: NFT collection contract (required) + * filter: MarketplaceTopOrdersFilter with options: + * - currencyAddresses: Consider specific currencies (empty=all) + * - tokenIds: Target token IDs (required, non-empty) + * - isListing: true=listings/sell orders, false=offers/buy orders + * - priceSort: ASC=lowest first, DESC=highest first + * - excludeUser: Hide orders from specific user + * + * Returns: Array of top-priced active orders, sorted by priceSort preference + */ + getMarketplaceTopOrders( + req: GetMarketplaceTopOrdersRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + /** + * GetNativeTokenBalance queries an ethereum node for the latest native token account balance. + * The native token is the token of the chain the indexer is connected to, for example, ETH on Ethereum + * and POL on Polygon. + */ + getNativeTokenBalance( + req: GetNativeTokenBalanceRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + /** + * GetTokenBalances returns a balance summary/details for a specific account. By default + * if accountAddress is left empty, it will use the account from the jwt session. + * + * Also, if contractAddress is undefined, then it will list all current user coins/collectibles. + * But, if contractAddress is provided, then it will return the token balances for the contract, this is + * only useful for 1155, but for other tokens, it can act as a filter for the single balance. + * + * DEPRECATED: use GetTokenBalancesSummary / GetTokenBalancesDetails + * + * @deprecated GetTokenBalancesSummary + */ + getTokenBalances(req: GetTokenBalancesRequest, headers?: object, signal?: AbortSignal): Promise + + /** + * GetTokenBalancesByContract returns a balances for a specific accounts and + * contracts. The collection ERC721 & ERC1155 tokens are represented as + * individual balances. + * + * If `filter` is not provided, it will error out as it requires at least + * contract address. + * + * If `filter.contractStatus` is not provided, it will include verified only + * tokens. + */ + getTokenBalancesByContract( + req: GetTokenBalancesByContractRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + /** + * GetTokenBalancesDetails returns a detailed balance summary for a specific + * accounts. The collection ERC721 & ERC1155 tokens are represented as + * individual balances. + * + * If `filter` is not provided, it will use the filter with account from the + * jwt session. + * + * If `filter.contractStatus` is not provided, it will include verified only + * tokens. + */ + getTokenBalancesDetails( + req: GetTokenBalancesDetailsRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + /** + * GetTokenBalancesSummary returns a summary of token balances for a specific + * accounts. The collection ERC721 & ERC1155 tokens are represented as a + * single aggregated balance. + * + * If `filter` is not provided, it will use the filter with account from the + * jwt session. + * + * If `filter.contractStatus` is not provided, it will include verified only + * tokens. + */ + getTokenBalancesSummary( + req: GetTokenBalancesSummaryRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + /** + * GetTokenIDRanges returns the range of tokenIDs for a token collection contract. + * This is useful for ERC-721 and ERC-1155 contracts to get the range of valid tokenIDs. It is similar to + * GetTokenIDs, but returns the range of tokenIDs instead of the list of tokenIDs, which is more efficient + * for large collections and very easy to the caller to expand the range into a list of tokenIDs. + * + * NOTE: this method will only return up to 15,000 ranges, if there are more ranges, it will return + * a boolean to indicate there are more ranges beyond the first 15,000. Therefore, if `moreRanges` is + * false then you have all the ranges, but if true, you need to make a follow up call to fetch the next + * page of ranges. + * + * As an example, if a NFT collection of 100,000 tokens uses ids from 1,2,3,...,100_000 then this endpoint + * will return just a single range from [1,100_000], but if there are gaps between the sequence, then + * those will be broken into separate range entries. + */ + getTokenIDRanges(req: GetTokenIDRangesRequest, headers?: object, signal?: AbortSignal): Promise + + /** + * GetTokenIDs returns the list of each individual token id for a token collection contract. + * This is useful for ERC-721 and ERC-1155 contracts to get the list of valid tokenIDs. + */ + getTokenIDs(req: GetTokenIDsRequest, headers?: object, signal?: AbortSignal): Promise + + getTokenPrice(req: GetTokenPriceRequest, headers?: object, signal?: AbortSignal): Promise + + getTokenPrices(req: GetTokenPricesRequest, headers?: object, signal?: AbortSignal): Promise + + /** + * GetTokenSupplies returns the set of tokenIDs used by a contract address, supporting ERC-20, ERC-721, and ERC-1155 + * contracts, and their respective supply as well. + */ + getTokenSupplies(req: GetTokenSuppliesRequest, headers?: object, signal?: AbortSignal): Promise + + /** + * GetTokenSuppliesMap returns the token supplies of ERC-20 and ERC-1155 tokens as requested in the `tokenMap` + * represented as a map of contractAddress :: []tokenIDs. + * + * For an ERC-20 specify tokenIDs as an empty array or [0], for example, { '0xdef': [] } or { '0xdef': [0] } + * For ERC-1155 pass the array of tokens are strings, ie. { '0xabc': ['1', '2', '3'] } + */ + getTokenSuppliesMap( + req: GetTokenSuppliesMapRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + /** + * History of mined transactions for the account which includes a list of token transfers (sent/recieved) + * and sent transactions from a Sequence wallet + */ + getTransactionHistory( + req: GetTransactionHistoryRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + getWebhookListener(req: GetWebhookListenerRequest, headers?: object, signal?: AbortSignal): Promise + + listTokenPrices(req: ListTokenPricesRequest, headers?: object, signal?: AbortSignal): Promise + + pauseAllWebhookListeners( + req: PauseAllWebhookListenersRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + /** + * Ping the indexer + */ + ping(headers?: object, signal?: AbortSignal): Promise + + removeAllWebhookListeners( + req: RemoveAllWebhookListenersRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + removeWebhookListener( + req: RemoveWebhookListenerRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + resumeAllWebhookListeners( + req: ResumeAllWebhookListenersRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + /** + * Get the current runtime health status of the indexer + */ + runtimeStatus(headers?: object, signal?: AbortSignal): Promise + + /** + * SubscribeBalanceUpdates listens to balance updates for a specific contract address + */ + subscribeBalanceUpdates( + req: SubscribeBalanceUpdatesRequest, + options: WebrpcStreamOptions + ): WebrpcStreamController + + /** + * SubscribeEvents listens to events on-chain based on the filter criteria + * + * TODO: some additional options can be passed such as block, reorg true, etc. + * or stay behind, etc. + */ + subscribeEvents(req: SubscribeEventsRequest, options: WebrpcStreamOptions): WebrpcStreamController + + /** + * Listen to transaction receipts on-chain based on the filter criteria + */ + subscribeReceipts( + req: SubscribeReceiptsRequest, + options: WebrpcStreamOptions + ): WebrpcStreamController + + /** + * Re-sync an incorrect token balance with the correct on-chain balance + * NOTE: this method is almost never used, but we've marked it internal in case + * we ever want to use it again. This method was written a very long time ago in + * scenarios when the indexer had little bugs, but now its solid. + */ + syncBalance(req: SyncBalanceRequest, headers?: object, signal?: AbortSignal): Promise + + toggleWebhookListener( + req: ToggleWebhookListenerRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + updateWebhookListener( + req: UpdateWebhookListenerRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + /** + * Get the current version of the indexer + */ + version(headers?: object, signal?: AbortSignal): Promise +} + +// +// Schema types +// + +export interface Asset { + id: number + collectionId: number + tokenId?: string + url?: string + metadataField: string + name?: string + filesize?: number + mimeType?: string + width?: number + height?: number + updatedAt?: string +} + +export interface BloomStats { + hitRatio: string + falsePositivesPercent: string + hitCount: number + missCount: number + falsePositives: number +} + +export interface BloomStatus { + enabled: boolean + initialized: boolean + bloomInitElapsedTime: string + stats: BloomStats +} + +export interface Bond { + pebble: PebbleMetrics + estimatedDiskUsagePerTable: any + estimatedDiskUsageTotal: string +} + +export interface ChainInfo { + chainId: number + chainName: string +} + +export interface ContractInfo { + chainId: number + address: string + source: string + name: string + type: string + symbol: string + decimals?: number + logoURI: string + deployed: boolean + bytecodeHash: string + extensions: ContractInfoExtensions + updatedAt: string + queuedAt?: string + status: ResourceStatus +} + +export interface ContractInfoExtensionBridgeInfo { + tokenAddress: string +} + +export interface ContractInfoExtensionIndexingInfo { + useOnChainBalance: boolean +} + +export interface ContractInfoExtensions { + link?: string + description?: string + categories?: Array + bridgeInfo?: { [key: string]: ContractInfoExtensionBridgeInfo } + indexingInfo?: ContractInfoExtensionIndexingInfo + ogImage?: string + ogName?: string + originChainId?: number + originAddress?: string + blacklist?: boolean + verified?: boolean + verifiedBy?: string + featured?: boolean + featureIndex?: number +} + +export enum ContractType { + UNKNOWN = 'UNKNOWN', + NATIVE = 'NATIVE', + ERC20 = 'ERC20', + ERC721 = 'ERC721', + ERC1155 = 'ERC1155', + SEQUENCE_WALLET = 'SEQUENCE_WALLET', + ERC20_BRIDGE = 'ERC20_BRIDGE', + ERC721_BRIDGE = 'ERC721_BRIDGE', + ERC1155_BRIDGE = 'ERC1155_BRIDGE', + SEQ_MARKETPLACE = 'SEQ_MARKETPLACE', + ERC6909 = 'ERC6909' +} + +export enum ContractVerificationStatus { + VERIFIED = 'VERIFIED', + UNVERIFIED = 'UNVERIFIED', + ALL = 'ALL' +} + +export interface DiskUsage { + humanReadable: string + used: number + size: number + percent: number + dirs: { [key: string]: string } +} + +export interface EtherBalance { + accountAddress: string + balanceWei: string +} + +export interface EventDecoded { + topicHash: string + eventSig: string + types: Array + names: Array + values: Array +} + +export interface EventFilter { + events?: Array + contractAddresses?: Array + accounts?: Array + tokenIDs?: Array +} + +export interface EventLog { + id: number + uid: string + type: EventLogType + blockNumber: number + blockHash: string + parentBlockHash: string + contractAddress: string + contractType: ContractType + txnHash: string + txnIndex: number + txnLogIndex: number + logDataType: EventLogDataType + ts: string + txnInfo?: TxnInfo + rawLog?: { [key: string]: any } + event?: EventDecoded +} + +export enum EventLogDataType { + EVENT = 'EVENT', + TOKEN_TRANSFER = 'TOKEN_TRANSFER', + NATIVE_TOKEN_TRANSFER = 'NATIVE_TOKEN_TRANSFER', + SEQUENCE_TXN = 'SEQUENCE_TXN' +} + +export enum EventLogType { + UNKNOWN = 'UNKNOWN', + BLOCK_ADDED = 'BLOCK_ADDED', + BLOCK_REMOVED = 'BLOCK_REMOVED' +} + +export interface GatewayBackendResponseTime { + percentiles: { [key: string]: number } + average: number +} + +export interface GatewayBackendRuntimeStatus { + name: string + chainId: number + responseTime: GatewayBackendResponseTime +} + +export interface GatewayEtherBalance { + chainId: number + errorReason?: string + result: EtherBalance +} + +export interface GatewayNativeTokenBalance { + chainId: number + errorReason?: string + result: NativeTokenBalance +} + +export interface GatewayNativeTokenBalances { + chainId: number + errorReason?: string + results: Array +} + +export interface GatewayPrice { + chainID: number + errorReason?: string + results: Array +} + +export interface GatewayRuntimeStatus { + healthOK: boolean + startTime: string + uptime: number + ver: string + branch: string + commitHash: string + backends: Array +} + +export interface GatewayTokenBalance { + chainId: number + errorReason?: string + results: Array +} + +export interface GatewayTokenPriceQuery { + chainID: number + queries: Array +} + +export interface GatewayTransaction { + chainId: number + errorReason?: string + results: Array +} + +export interface IndexState { + chainId: string + lastBlockNum: number + lastBlockHash: string +} + +export interface IndexedBlock { + blockNumber: number + blockShortHash: string +} + +export interface IndexerMetrics { + blocksPerSecond: number + eventsPerSecond: number +} + +export interface MarketplaceOrder { + orderId: string + tokenContract: string + tokenId: string + isListing: boolean + quantity: string + quantityRemaining: string + currencyAddress: string + pricePerToken: string + expiry: string + orderStatus: OrderStatus + createdBy: string + blockNumber: number + orderbookContractAddress: string + createdAt: number +} + +export interface MarketplaceOrderFilter { + isListing?: boolean + userAddresses?: Array + currencyAddresses: Array + orderIds: Array + tokenIds: Array + excludeUserAddresses?: Array + blockNumberGt: number + createdAtAfter: number + orderStatuses: Array + returnExpired: boolean +} + +export interface MarketplaceTopOrdersFilter { + currencyAddresses: Array + tokenIds: Array + isListing: boolean + priceSort: SortOrder + excludeUser?: string +} + +export interface MetadataOptions { + verifiedOnly?: boolean + unverifiedOnly?: boolean + includeContracts?: Array +} + +export interface NativeTokenBalance { + accountAddress: string + chainId: number + name: string + symbol: string + balance: string + balanceUSD: string + priceUSD: string + priceUpdatedAt?: string + errorReason?: string +} + +export enum NetworkType { + MAINNETS = 'MAINNETS', + TESTNETS = 'TESTNETS', + ALL = 'ALL' +} + +export enum OrderStatus { + OPEN = 'OPEN', + CLOSED = 'CLOSED', + CANCELLED = 'CANCELLED' +} + +export interface Page { + page?: number + column?: string + before?: any + after?: any + sort?: Array + pageSize?: number + more?: boolean +} + +export interface PebbleMetrics { + compactionCount: number + compactionEstimatedDebt: number + compactionInProgressBytes: number + compactionNumInProgress: number + compactionMarkedFiles: number +} + +export interface Price { + contractAddress: string + tokenID?: string + priceUSD: string + updatedAt?: string +} + +export enum ResourceStatus { + NOT_AVAILABLE = 'NOT_AVAILABLE', + REFRESHING = 'REFRESHING', + AVAILABLE = 'AVAILABLE' +} + +export interface RuntimeChecks { + running: boolean + runnables: any + cgoEnabled: boolean + quotaControlEnabled: boolean + syncMode: string + percentIndexed: number + lastBlockNum: number + lastBlockNumWithState: number + bloomStatus: BloomStatus + bond: Bond + diskUsage: DiskUsage + metrics: IndexerMetrics +} + +export interface RuntimeStatus { + healthOK: boolean + indexerEnabled: boolean + startTime: string + uptime: number + ver: string + branch: string + commitHash: string + chainID: number + checks: RuntimeChecks +} + +export interface SortBy { + column: string + order: SortOrder +} + +export enum SortOrder { + DESC = 'DESC', + ASC = 'ASC' +} + +export interface TokenBalance { + contractType: ContractType + contractAddress: string + accountAddress: string + tokenID?: string + balance: string + balanceUSD: string + priceUSD: string + priceUpdatedAt?: string + blockHash: string + blockNumber: number + chainId: number + uniqueCollectibles: string + isSummary: boolean + contractInfo?: ContractInfo + tokenMetadata?: TokenMetadata +} + +export interface TokenBalanceFilter { + contractAddress: string + sinceBlockNumber: number +} + +export interface TokenBalancesByContractFilter { + contractAddresses: Array + accountAddresses?: Array + contractStatus?: ContractVerificationStatus +} + +export interface TokenBalancesFilter { + accountAddresses: Array + contractStatus?: ContractVerificationStatus + contractTypes?: Array + contractWhitelist?: Array + contractBlacklist?: Array + omitNativeBalances: boolean + omitPrices?: boolean +} + +export interface TokenHistory { + blockNumber: number + blockHash: string + contractAddress: string + contractType: ContractType + fromAddress: string + toAddress: string + txnHash: string + txnIndex: number + txnLogIndex: number + tokenIDs: string + amounts: string + ts: string +} + +export interface TokenIDRange { + start: string + end: string +} + +export interface TokenMetadata { + chainId?: number + contractAddress?: string + tokenId: string + source: string + name: string + description?: string + image?: string + video?: string + audio?: string + properties?: { [key: string]: any } + attributes: Array<{ [key: string]: any }> + image_data?: string + external_url?: string + background_color?: string + animation_url?: string + decimals?: number + updatedAt?: string + assets?: Array + status: ResourceStatus + queuedAt?: string + lastFetched?: string +} + +export interface TokenPriceQuery { + contractAddress: string + tokenID?: string +} + +export interface TokenSupply { + tokenID: string + supply: string + chainId: number + contractInfo?: ContractInfo + tokenMetadata?: TokenMetadata +} + +export interface Transaction { + txnHash: string + blockNumber: number + blockHash: string + chainId: number + metaTxnID?: string + transfers?: Array + timestamp: string +} + +export interface TransactionFilter { + txnHash?: string + from?: string + to?: string + contractAddress?: string + event?: string +} + +export interface TransactionHistoryFilter { + accountAddress?: string + contractAddress?: string + accountAddresses?: Array + contractAddresses?: Array + transactionHashes?: Array + metaTransactionIDs?: Array + fromBlock?: number + toBlock?: number + tokenID?: string + omitPrices?: boolean +} + +export interface TransactionLog { + contractAddress: string + topics: Array + data: string + index: number +} + +export interface TransactionReceipt { + txnHash: string + txnStatus: TransactionStatus + txnIndex: number + txnType: TransactionType + blockHash: string + blockNumber: number + gasUsed: number + effectiveGasPrice: string + from: string + to: string + logs: Array + final: boolean + reorged: boolean +} + +export enum TransactionStatus { + FAILED = 'FAILED', + SUCCESSFUL = 'SUCCESSFUL' +} + +export enum TransactionType { + LegacyTxnType = 'LegacyTxnType', + AccessListTxnType = 'AccessListTxnType', + DynamicFeeTxnType = 'DynamicFeeTxnType' +} + +export interface TxnInfo { + from: string + to: string + value: string +} + +export interface TxnTransfer { + transferType: TxnTransferType + contractAddress: string + contractType: ContractType + from: string + to: string + tokenIds?: Array + amounts: Array + logIndex: number + amountsUSD?: Array + pricesUSD?: Array + contractInfo?: ContractInfo + tokenMetadata?: { [key: string]: TokenMetadata } +} + +export enum TxnTransferType { + UNKNOWN = 'UNKNOWN', + SEND = 'SEND', + RECEIVE = 'RECEIVE' +} + +export interface Version { + webrpcVersion: string + schemaVersion: string + schemaHash: string + appVersion: string +} + +export interface WALWriterRuntimeStatus { + healthOK: boolean + startTime: string + uptime: number + ver: string + branch: string + commitHash: string + chainID: number + percentWALWritten: number +} + +export interface WebhookListener { + id: number + projectID: number + url: string + filters: EventFilter + name: string + updatedAt: string + active: boolean +} + +export interface AddWebhookListenerRequest { + url: string + filters: EventFilter + projectId?: number +} + +export interface AddWebhookListenerResponse { + status: boolean + listener: WebhookListener +} + +export interface FetchTransactionReceiptRequest { + txnHash: string + maxBlockWait?: number +} + +export interface FetchTransactionReceiptResponse { + receipt: TransactionReceipt +} + +export interface FetchTransactionReceiptWithFilterRequest { + filter: TransactionFilter + maxBlockWait?: number +} + +export interface FetchTransactionReceiptWithFilterResponse { + receipt: TransactionReceipt +} + +export interface GetAllWebhookListenersRequest { + projectId?: number +} + +export interface GetAllWebhookListenersResponse { + listeners: Array +} + +export interface GetBalanceUpdatesRequest { + contractAddress: string + lastBlockNumber: number + lastBlockHash?: string + page?: Page +} + +export interface GetBalanceUpdatesResponse { + page: Page + balances: Array +} + +export interface GetChainIDRequest {} + +export interface GetChainIDResponse { + chainID: number +} + +export interface GetEtherBalanceRequest { + accountAddress?: string +} + +export interface GetEtherBalanceResponse { + balance: EtherBalance +} + +export interface GetMarketplaceOrdersRequest { + marketplaceContractAddress: string + collectionAddress: string + filter?: MarketplaceOrderFilter + page?: Page +} + +export interface GetMarketplaceOrdersResponse { + page?: Page + orders: Array +} + +export interface GetMarketplaceTopOrdersRequest { + marketplaceContractAddress: string + collectionAddress: string + filter: MarketplaceTopOrdersFilter +} + +export interface GetMarketplaceTopOrdersResponse { + orders: Array +} + +export interface GetNativeTokenBalanceRequest { + accountAddress?: string + omitPrices?: boolean +} + +export interface GetNativeTokenBalanceResponse { + balance: NativeTokenBalance +} + +export interface GetTokenBalancesRequest { + accountAddress?: string + contractAddress?: string + tokenID?: string + includeMetadata?: boolean + metadataOptions?: MetadataOptions + includeCollectionTokens?: boolean + page?: Page +} + +export interface GetTokenBalancesResponse { + page: Page + balances: Array +} + +export interface GetTokenBalancesByContractRequest { + filter: TokenBalancesByContractFilter + omitMetadata?: boolean + page?: Page +} + +export interface GetTokenBalancesByContractResponse { + page: Page + balances: Array +} + +export interface GetTokenBalancesDetailsRequest { + filter: TokenBalancesFilter + omitMetadata?: boolean + page?: Page +} + +export interface GetTokenBalancesDetailsResponse { + page: Page + nativeBalances: Array + balances: Array +} + +export interface GetTokenBalancesSummaryRequest { + filter: TokenBalancesFilter + omitMetadata?: boolean + page?: Page +} + +export interface GetTokenBalancesSummaryResponse { + page: Page + nativeBalances: Array + balances: Array +} + +export interface GetTokenIDRangesRequest { + contractAddress: string + lastTokenID?: string +} + +export interface GetTokenIDRangesResponse { + contractType: ContractType + tokenIDRanges: Array + moreRanges: boolean +} + +export interface GetTokenIDsRequest { + contractAddress: string + page?: Page +} + +export interface GetTokenIDsResponse { + page: Page + contractType: ContractType + tokenIDs: Array +} + +export interface GetTokenPriceRequest { + q: TokenPriceQuery +} + +export interface GetTokenPriceResponse { + price: Price +} + +export interface GetTokenPricesRequest { + q: Array +} + +export interface GetTokenPricesResponse { + prices: Array +} + +export interface GetTokenSuppliesRequest { + contractAddress: string + includeMetadata?: boolean + page?: Page +} + +export interface GetTokenSuppliesResponse { + page: Page + contractType: ContractType + tokenIDs: Array +} + +export interface GetTokenSuppliesMapRequest { + tokenMap: { [key: string]: Array } + includeMetadata?: boolean +} + +export interface GetTokenSuppliesMapResponse { + supplies: { [key: string]: Array } +} + +export interface GetTransactionHistoryRequest { + filter: TransactionHistoryFilter + page?: Page + includeMetadata?: boolean + metadataOptions?: MetadataOptions +} + +export interface GetTransactionHistoryResponse { + page: Page + transactions: Array +} + +export interface GetWebhookListenerRequest { + id: number + projectId?: number +} + +export interface GetWebhookListenerResponse { + listener: WebhookListener +} + +export interface ListTokenPricesRequest { + page?: Page +} + +export interface ListTokenPricesResponse { + page: Page + prices: Array +} + +export interface PauseAllWebhookListenersRequest { + projectId?: number +} + +export interface PauseAllWebhookListenersResponse { + status: boolean +} + +export interface PingRequest {} + +export interface PingResponse { + status: boolean +} + +export interface RemoveAllWebhookListenersRequest { + projectId?: number +} + +export interface RemoveAllWebhookListenersResponse { + status: boolean +} + +export interface RemoveWebhookListenerRequest { + id: number + projectId?: number +} + +export interface RemoveWebhookListenerResponse { + status: boolean +} + +export interface ResumeAllWebhookListenersRequest { + projectId?: number +} + +export interface ResumeAllWebhookListenersResponse { + status: boolean +} + +export interface RuntimeStatusRequest {} + +export interface RuntimeStatusResponse { + status: RuntimeStatus +} + +export interface SubscribeBalanceUpdatesRequest { + contractAddress: string +} + +export interface SubscribeBalanceUpdatesResponse { + balance: TokenBalance +} + +export interface SubscribeEventsRequest { + filter: EventFilter +} + +export interface SubscribeEventsResponse { + log: EventLog +} + +export interface SubscribeReceiptsRequest { + filter: TransactionFilter +} + +export interface SubscribeReceiptsResponse { + receipt: TransactionReceipt +} + +export interface SyncBalanceRequest { + accountAddress: string + contractAddress: string + tokenID?: string +} + +export interface SyncBalanceResponse {} + +export interface ToggleWebhookListenerRequest { + id: number + projectId?: number +} + +export interface ToggleWebhookListenerResponse { + webhookListener: WebhookListener +} + +export interface UpdateWebhookListenerRequest { + listener: WebhookListener + projectId?: number +} + +export interface UpdateWebhookListenerResponse { + status: boolean +} + +export interface VersionRequest {} + +export interface VersionResponse { + version: Version +} + +// +// Client +// + +export class Indexer implements IndexerClient { + protected hostname: string + protected fetch: Fetch + protected path = '/rpc/Indexer/' + + constructor(hostname: string, fetch: Fetch) { + this.hostname = hostname.replace(/\/*$/, '') + this.fetch = (input: RequestInfo, init?: RequestInit) => fetch(input, init) + } + + private url(name: string): string { + return this.hostname + this.path + name + } + + queryKey = { + addWebhookListener: (req: AddWebhookListenerRequest) => ['Indexer', 'addWebhookListener', req] as const, + fetchTransactionReceipt: (req: FetchTransactionReceiptRequest) => ['Indexer', 'fetchTransactionReceipt', req] as const, + fetchTransactionReceiptWithFilter: (req: FetchTransactionReceiptWithFilterRequest) => + ['Indexer', 'fetchTransactionReceiptWithFilter', req] as const, + getAllWebhookListeners: (req: GetAllWebhookListenersRequest) => ['Indexer', 'getAllWebhookListeners', req] as const, + getBalanceUpdates: (req: GetBalanceUpdatesRequest) => ['Indexer', 'getBalanceUpdates', req] as const, + getChainID: () => ['Indexer', 'getChainID'] as const, + getEtherBalance: (req: GetEtherBalanceRequest) => ['Indexer', 'getEtherBalance', req] as const, + getMarketplaceOrders: (req: GetMarketplaceOrdersRequest) => ['Indexer', 'getMarketplaceOrders', req] as const, + getMarketplaceTopOrders: (req: GetMarketplaceTopOrdersRequest) => ['Indexer', 'getMarketplaceTopOrders', req] as const, + getNativeTokenBalance: (req: GetNativeTokenBalanceRequest) => ['Indexer', 'getNativeTokenBalance', req] as const, + getTokenBalances: (req: GetTokenBalancesRequest) => ['Indexer', 'getTokenBalances', req] as const, + getTokenBalancesByContract: (req: GetTokenBalancesByContractRequest) => + ['Indexer', 'getTokenBalancesByContract', req] as const, + getTokenBalancesDetails: (req: GetTokenBalancesDetailsRequest) => ['Indexer', 'getTokenBalancesDetails', req] as const, + getTokenBalancesSummary: (req: GetTokenBalancesSummaryRequest) => ['Indexer', 'getTokenBalancesSummary', req] as const, + getTokenIDRanges: (req: GetTokenIDRangesRequest) => ['Indexer', 'getTokenIDRanges', req] as const, + getTokenIDs: (req: GetTokenIDsRequest) => ['Indexer', 'getTokenIDs', req] as const, + getTokenPrice: (req: GetTokenPriceRequest) => ['Indexer', 'getTokenPrice', req] as const, + getTokenPrices: (req: GetTokenPricesRequest) => ['Indexer', 'getTokenPrices', req] as const, + getTokenSupplies: (req: GetTokenSuppliesRequest) => ['Indexer', 'getTokenSupplies', req] as const, + getTokenSuppliesMap: (req: GetTokenSuppliesMapRequest) => ['Indexer', 'getTokenSuppliesMap', req] as const, + getTransactionHistory: (req: GetTransactionHistoryRequest) => ['Indexer', 'getTransactionHistory', req] as const, + getWebhookListener: (req: GetWebhookListenerRequest) => ['Indexer', 'getWebhookListener', req] as const, + listTokenPrices: (req: ListTokenPricesRequest) => ['Indexer', 'listTokenPrices', req] as const, + pauseAllWebhookListeners: (req: PauseAllWebhookListenersRequest) => ['Indexer', 'pauseAllWebhookListeners', req] as const, + ping: () => ['Indexer', 'ping'] as const, + removeAllWebhookListeners: (req: RemoveAllWebhookListenersRequest) => ['Indexer', 'removeAllWebhookListeners', req] as const, + removeWebhookListener: (req: RemoveWebhookListenerRequest) => ['Indexer', 'removeWebhookListener', req] as const, + resumeAllWebhookListeners: (req: ResumeAllWebhookListenersRequest) => ['Indexer', 'resumeAllWebhookListeners', req] as const, + runtimeStatus: () => ['Indexer', 'runtimeStatus'] as const, + subscribeBalanceUpdates: (req: SubscribeBalanceUpdatesRequest) => ['Indexer', 'subscribeBalanceUpdates', req] as const, + subscribeEvents: (req: SubscribeEventsRequest) => ['Indexer', 'subscribeEvents', req] as const, + subscribeReceipts: (req: SubscribeReceiptsRequest) => ['Indexer', 'subscribeReceipts', req] as const, + syncBalance: (req: SyncBalanceRequest) => ['Indexer', 'syncBalance', req] as const, + toggleWebhookListener: (req: ToggleWebhookListenerRequest) => ['Indexer', 'toggleWebhookListener', req] as const, + updateWebhookListener: (req: UpdateWebhookListenerRequest) => ['Indexer', 'updateWebhookListener', req] as const, + version: () => ['Indexer', 'version'] as const + } + + addWebhookListener = ( + req: AddWebhookListenerRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('AddWebhookListener'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'AddWebhookListenerResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + fetchTransactionReceipt = ( + req: FetchTransactionReceiptRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('FetchTransactionReceipt'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'FetchTransactionReceiptResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + fetchTransactionReceiptWithFilter = ( + req: FetchTransactionReceiptWithFilterRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('FetchTransactionReceiptWithFilter'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'FetchTransactionReceiptWithFilterResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + getAllWebhookListeners = ( + req: GetAllWebhookListenersRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetAllWebhookListeners'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetAllWebhookListenersResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + getBalanceUpdates = ( + req: GetBalanceUpdatesRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetBalanceUpdates'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetBalanceUpdatesResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + getChainID = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetChainID'), createHttpRequest('{}', headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetChainIDResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + getEtherBalance = (req: GetEtherBalanceRequest, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetEtherBalance'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetEtherBalanceResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + getMarketplaceOrders = ( + req: GetMarketplaceOrdersRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetMarketplaceOrders'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetMarketplaceOrdersResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + getMarketplaceTopOrders = ( + req: GetMarketplaceTopOrdersRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetMarketplaceTopOrders'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetMarketplaceTopOrdersResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + getNativeTokenBalance = ( + req: GetNativeTokenBalanceRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetNativeTokenBalance'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetNativeTokenBalanceResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + getTokenBalances = ( + req: GetTokenBalancesRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetTokenBalances'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetTokenBalancesResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + getTokenBalancesByContract = ( + req: GetTokenBalancesByContractRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetTokenBalancesByContract'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetTokenBalancesByContractResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + getTokenBalancesDetails = ( + req: GetTokenBalancesDetailsRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetTokenBalancesDetails'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetTokenBalancesDetailsResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + getTokenBalancesSummary = ( + req: GetTokenBalancesSummaryRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetTokenBalancesSummary'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetTokenBalancesSummaryResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + getTokenIDRanges = ( + req: GetTokenIDRangesRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetTokenIDRanges'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetTokenIDRangesResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + getTokenIDs = (req: GetTokenIDsRequest, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetTokenIDs'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetTokenIDsResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + getTokenPrice = (req: GetTokenPriceRequest, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetTokenPrice'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetTokenPriceResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + getTokenPrices = (req: GetTokenPricesRequest, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetTokenPrices'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetTokenPricesResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + getTokenSupplies = ( + req: GetTokenSuppliesRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetTokenSupplies'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetTokenSuppliesResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + getTokenSuppliesMap = ( + req: GetTokenSuppliesMapRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetTokenSuppliesMap'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetTokenSuppliesMapResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + getTransactionHistory = ( + req: GetTransactionHistoryRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetTransactionHistory'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetTransactionHistoryResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + getWebhookListener = ( + req: GetWebhookListenerRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetWebhookListener'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetWebhookListenerResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + listTokenPrices = (req: ListTokenPricesRequest, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('ListTokenPrices'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'ListTokenPricesResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + pauseAllWebhookListeners = ( + req: PauseAllWebhookListenersRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('PauseAllWebhookListeners'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'PauseAllWebhookListenersResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + ping = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('Ping'), createHttpRequest('{}', headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'PingResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + removeAllWebhookListeners = ( + req: RemoveAllWebhookListenersRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('RemoveAllWebhookListeners'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'RemoveAllWebhookListenersResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + removeWebhookListener = ( + req: RemoveWebhookListenerRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('RemoveWebhookListener'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'RemoveWebhookListenerResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + resumeAllWebhookListeners = ( + req: ResumeAllWebhookListenersRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('ResumeAllWebhookListeners'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'ResumeAllWebhookListenersResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + runtimeStatus = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('RuntimeStatus'), createHttpRequest('{}', headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'RuntimeStatusResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + subscribeBalanceUpdates = ( + req: SubscribeBalanceUpdatesRequest, + options: WebrpcStreamOptions + ): WebrpcStreamController => { + const abortController = new AbortController() + const abortSignal = abortController.signal + + if (options.signal) { + abortSignal.addEventListener('abort', () => abortController.abort(options.signal?.reason), { + signal: options.signal + }) + } + + const _fetch = () => + this.fetch(this.url('SubscribeBalanceUpdates'), createHttpRequest(JsonEncode(req), options.headers, abortSignal)).then( + async res => { + await sseResponse(res, options, _fetch) + }, + error => { + options.onError(error, _fetch) + } + ) + + const resp = _fetch() + return { + abort: abortController.abort.bind(abortController), + closed: resp + } + } + subscribeEvents = ( + req: SubscribeEventsRequest, + options: WebrpcStreamOptions + ): WebrpcStreamController => { + const abortController = new AbortController() + const abortSignal = abortController.signal + + if (options.signal) { + abortSignal.addEventListener('abort', () => abortController.abort(options.signal?.reason), { + signal: options.signal + }) + } + + const _fetch = () => + this.fetch(this.url('SubscribeEvents'), createHttpRequest(JsonEncode(req), options.headers, abortSignal)).then( + async res => { + await sseResponse(res, options, _fetch) + }, + error => { + options.onError(error, _fetch) + } + ) + + const resp = _fetch() + return { + abort: abortController.abort.bind(abortController), + closed: resp + } + } + subscribeReceipts = ( + req: SubscribeReceiptsRequest, + options: WebrpcStreamOptions + ): WebrpcStreamController => { + const abortController = new AbortController() + const abortSignal = abortController.signal + + if (options.signal) { + abortSignal.addEventListener('abort', () => abortController.abort(options.signal?.reason), { + signal: options.signal + }) + } + + const _fetch = () => + this.fetch(this.url('SubscribeReceipts'), createHttpRequest(JsonEncode(req), options.headers, abortSignal)).then( + async res => { + await sseResponse(res, options, _fetch) + }, + error => { + options.onError(error, _fetch) + } + ) + + const resp = _fetch() + return { + abort: abortController.abort.bind(abortController), + closed: resp + } + } + syncBalance = (req: SyncBalanceRequest, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('SyncBalance'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'SyncBalanceResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + toggleWebhookListener = ( + req: ToggleWebhookListenerRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('ToggleWebhookListener'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'ToggleWebhookListenerResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + updateWebhookListener = ( + req: UpdateWebhookListenerRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('UpdateWebhookListener'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'UpdateWebhookListenerResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + version = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('Version'), createHttpRequest('{}', headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'VersionResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } +} + +const sseResponse = async (res: Response, options: WebrpcStreamOptions, retryFetch: () => Promise) => { + const { onMessage, onOpen, onClose, onError } = options + + if (!res.ok) { + try { + await buildResponse(res) + } catch (error) { + // @ts-ignore + onError(error, retryFetch) + } + return + } + + if (!res.body) { + onError( + WebrpcBadResponseError.new({ + status: res.status, + cause: 'Invalid response, missing body' + }), + retryFetch + ) + return + } + + onOpen && onOpen() + + const reader = res.body.getReader() + const decoder = new TextDecoder() + let buffer = '' + let lastReadTime = Date.now() + const timeout = (10 + 1) * 1000 + let timeoutError = false + const intervalId = setInterval(() => { + if (Date.now() - lastReadTime > timeout) { + timeoutError = true + clearInterval(intervalId) + reader.releaseLock() + } + }, timeout) + + while (true) { + let value + let done + try { + ;({ value, done } = await reader.read()) + if (timeoutError) throw new Error('Timeout, no data or heartbeat received') + lastReadTime = Date.now() + buffer += decoder.decode(value, { stream: true }) + } catch (error) { + if (error instanceof DOMException && error.name === 'AbortError') { + onError( + WebrpcClientAbortedError.new({ + message: 'AbortError', + cause: `AbortError: ${error instanceof Error ? error.message : String(error)}` + }), + () => { + throw new Error('Abort signal cannot be used to reconnect') + } + ) + } else { + onError( + WebrpcStreamLostError.new({ + cause: `reader.read(): ${error instanceof Error ? error.message : String(error)}` + }), + retryFetch + ) + } + return + } + + let lines = buffer.split('\n') + for (let i = 0; i < lines.length - 1; i++) { + const line = lines[i] + if (line?.length === 0) { + continue + } + let data: any + try { + data = JSON.parse(line) + if (data.hasOwnProperty('webrpcError')) { + const error = data.webrpcError + const code: number = typeof error.code === 'number' ? error.code : 0 + onError((webrpcErrorByCode[code] || WebrpcError).new(error), retryFetch) + return + } + } catch (error) { + if (error instanceof Error && error.message === 'Abort signal cannot be used to reconnect') { + throw error + } + onError( + WebrpcBadResponseError.new({ + status: res.status, + cause: `JSON.parse(): ${error instanceof Error ? error.message : String(error)}` + }), + retryFetch + ) + } + onMessage(data) + } + + if (!done) { + const lastLine = lines[lines.length - 1] + buffer = lastLine || '' + continue + } + + onClose && onClose() + return + } +} + +const createHttpRequest = (body: string = '{}', headers: object = {}, signal: AbortSignal | null = null): object => { + const reqHeaders: { [key: string]: string } = { + ...headers, + 'Content-Type': 'application/json', + [WebrpcHeader]: WebrpcHeaderValue + } + return { method: 'POST', headers: reqHeaders, body, signal } +} + +const buildResponse = (res: Response): Promise => { + return res.text().then(text => { + let data + try { + data = JSON.parse(text) + } catch (error) { + throw WebrpcBadResponseError.new({ + status: res.status, + cause: `JSON.parse(): ${error instanceof Error ? error.message : String(error)}: response text: ${text}` + }) + } + if (!res.ok) { + const code: number = typeof data.code === 'number' ? data.code : 0 + throw (webrpcErrorByCode[code] || WebrpcError).new(data) + } + return data + }) +} + +export type Fetch = (input: RequestInfo, init?: RequestInit) => Promise + +export interface WebrpcStreamOptions extends WebrpcOptions { + onMessage: (message: T) => void + onError: (error: WebrpcError, reconnect: () => void) => void + onOpen?: () => void + onClose?: () => void +} + +export interface WebrpcOptions { + headers?: HeadersInit + signal?: AbortSignal +} + +export interface WebrpcStreamController { + abort: (reason?: any) => void + closed: Promise +} + +export const JsonEncode = (obj: T): string => { + return JSON.stringify(obj) +} + +export const JsonDecode = (data: string | any, _typ: string = ''): T => { + let parsed: any = data + if (typeof data === 'string') { + try { + parsed = JSON.parse(data) + } catch (err) { + throw WebrpcBadResponseError.new({ cause: `JsonDecode: JSON.parse failed: ${(err as Error).message}` }) + } + } + return parsed as T +} + +// +// Errors +// + +type WebrpcErrorParams = { name?: string; code?: number; message?: string; status?: number; cause?: string } + +export class WebrpcError extends Error { + code: number + status: number + + constructor(error: WebrpcErrorParams = {}) { + super(error.message) + this.name = error.name || 'WebrpcEndpointError' + this.code = typeof error.code === 'number' ? error.code : 0 + this.message = error.message || `endpoint error` + this.status = typeof error.status === 'number' ? error.status : 400 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, WebrpcError.prototype) + } + + static new(payload: any): WebrpcError { + return new this({ message: payload.message, code: payload.code, status: payload.status, cause: payload.cause }) + } +} + +export class WebrpcEndpointError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'WebrpcEndpoint' + this.code = typeof error.code === 'number' ? error.code : 0 + this.message = error.message || `endpoint error` + this.status = typeof error.status === 'number' ? error.status : 400 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, WebrpcEndpointError.prototype) + } +} + +export class WebrpcRequestFailedError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'WebrpcRequestFailed' + this.code = typeof error.code === 'number' ? error.code : -1 + this.message = error.message || `request failed` + this.status = typeof error.status === 'number' ? error.status : 400 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, WebrpcRequestFailedError.prototype) + } +} + +export class WebrpcBadRouteError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'WebrpcBadRoute' + this.code = typeof error.code === 'number' ? error.code : -2 + this.message = error.message || `bad route` + this.status = typeof error.status === 'number' ? error.status : 404 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, WebrpcBadRouteError.prototype) + } +} + +export class WebrpcBadMethodError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'WebrpcBadMethod' + this.code = typeof error.code === 'number' ? error.code : -3 + this.message = error.message || `bad method` + this.status = typeof error.status === 'number' ? error.status : 405 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, WebrpcBadMethodError.prototype) + } +} + +export class WebrpcBadRequestError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'WebrpcBadRequest' + this.code = typeof error.code === 'number' ? error.code : -4 + this.message = error.message || `bad request` + this.status = typeof error.status === 'number' ? error.status : 400 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, WebrpcBadRequestError.prototype) + } +} + +export class WebrpcBadResponseError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'WebrpcBadResponse' + this.code = typeof error.code === 'number' ? error.code : -5 + this.message = error.message || `bad response` + this.status = typeof error.status === 'number' ? error.status : 500 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, WebrpcBadResponseError.prototype) + } +} + +export class WebrpcServerPanicError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'WebrpcServerPanic' + this.code = typeof error.code === 'number' ? error.code : -6 + this.message = error.message || `server panic` + this.status = typeof error.status === 'number' ? error.status : 500 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, WebrpcServerPanicError.prototype) + } +} + +export class WebrpcInternalErrorError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'WebrpcInternalError' + this.code = typeof error.code === 'number' ? error.code : -7 + this.message = error.message || `internal error` + this.status = typeof error.status === 'number' ? error.status : 500 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, WebrpcInternalErrorError.prototype) + } +} + +export class WebrpcClientAbortedError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'WebrpcClientAborted' + this.code = typeof error.code === 'number' ? error.code : -8 + this.message = error.message || `request aborted by client` + this.status = typeof error.status === 'number' ? error.status : 400 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, WebrpcClientAbortedError.prototype) + } +} + +export class WebrpcStreamLostError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'WebrpcStreamLost' + this.code = typeof error.code === 'number' ? error.code : -9 + this.message = error.message || `stream lost` + this.status = typeof error.status === 'number' ? error.status : 400 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, WebrpcStreamLostError.prototype) + } +} + +export class WebrpcStreamFinishedError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'WebrpcStreamFinished' + this.code = typeof error.code === 'number' ? error.code : -10 + this.message = error.message || `stream finished` + this.status = typeof error.status === 'number' ? error.status : 200 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, WebrpcStreamFinishedError.prototype) + } +} + +// +// Schema errors +// + +export class AbortedError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'Aborted' + this.code = typeof error.code === 'number' ? error.code : 1005 + this.message = error.message || `Request aborted` + this.status = typeof error.status === 'number' ? error.status : 400 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, AbortedError.prototype) + } +} + +export class AccessKeyMismatchError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'AccessKeyMismatch' + this.code = typeof error.code === 'number' ? error.code : 1102 + this.message = error.message || `Access key mismatch` + this.status = typeof error.status === 'number' ? error.status : 409 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, AccessKeyMismatchError.prototype) + } +} + +export class AccessKeyNotFoundError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'AccessKeyNotFound' + this.code = typeof error.code === 'number' ? error.code : 1101 + this.message = error.message || `Access key not found` + this.status = typeof error.status === 'number' ? error.status : 401 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, AccessKeyNotFoundError.prototype) + } +} + +export class AtLeastOneKeyError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'AtLeastOneKey' + this.code = typeof error.code === 'number' ? error.code : 1302 + this.message = error.message || `You need at least one Access Key` + this.status = typeof error.status === 'number' ? error.status : 403 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, AtLeastOneKeyError.prototype) + } +} + +export class GeoblockedError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'Geoblocked' + this.code = typeof error.code === 'number' ? error.code : 1006 + this.message = error.message || `Geoblocked region` + this.status = typeof error.status === 'number' ? error.status : 451 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, GeoblockedError.prototype) + } +} + +export class InvalidArgumentError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'InvalidArgument' + this.code = typeof error.code === 'number' ? error.code : 2001 + this.message = error.message || `Invalid argument` + this.status = typeof error.status === 'number' ? error.status : 400 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, InvalidArgumentError.prototype) + } +} + +export class InvalidOriginError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'InvalidOrigin' + this.code = typeof error.code === 'number' ? error.code : 1103 + this.message = error.message || `Invalid origin for Access Key` + this.status = typeof error.status === 'number' ? error.status : 403 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, InvalidOriginError.prototype) + } +} + +export class InvalidServiceError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'InvalidService' + this.code = typeof error.code === 'number' ? error.code : 1104 + this.message = error.message || `Service not enabled for Access key` + this.status = typeof error.status === 'number' ? error.status : 403 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, InvalidServiceError.prototype) + } +} + +export class MaxAccessKeysError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'MaxAccessKeys' + this.code = typeof error.code === 'number' ? error.code : 1301 + this.message = error.message || `Access keys limit reached` + this.status = typeof error.status === 'number' ? error.status : 403 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, MaxAccessKeysError.prototype) + } +} + +export class MetadataCallFailedError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'MetadataCallFailed' + this.code = typeof error.code === 'number' ? error.code : 3003 + this.message = error.message || `Metadata service call failed` + this.status = typeof error.status === 'number' ? error.status : 400 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, MetadataCallFailedError.prototype) + } +} + +export class MethodNotFoundError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'MethodNotFound' + this.code = typeof error.code === 'number' ? error.code : 1003 + this.message = error.message || `Method not found` + this.status = typeof error.status === 'number' ? error.status : 404 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, MethodNotFoundError.prototype) + } +} + +export class NoDefaultKeyError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'NoDefaultKey' + this.code = typeof error.code === 'number' ? error.code : 1300 + this.message = error.message || `No default access key found` + this.status = typeof error.status === 'number' ? error.status : 403 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, NoDefaultKeyError.prototype) + } +} + +export class NotFoundError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'NotFound' + this.code = typeof error.code === 'number' ? error.code : 3000 + this.message = error.message || `Resource not found` + this.status = typeof error.status === 'number' ? error.status : 400 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, NotFoundError.prototype) + } +} + +export class PermissionDeniedError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'PermissionDenied' + this.code = typeof error.code === 'number' ? error.code : 1001 + this.message = error.message || `Permission denied` + this.status = typeof error.status === 'number' ? error.status : 403 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, PermissionDeniedError.prototype) + } +} + +export class ProjectNotFoundError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'ProjectNotFound' + this.code = typeof error.code === 'number' ? error.code : 1100 + this.message = error.message || `Project not found` + this.status = typeof error.status === 'number' ? error.status : 401 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, ProjectNotFoundError.prototype) + } +} + +export class QueryFailedError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'QueryFailed' + this.code = typeof error.code === 'number' ? error.code : 2003 + this.message = error.message || `Query failed` + this.status = typeof error.status === 'number' ? error.status : 400 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, QueryFailedError.prototype) + } +} + +export class QuotaExceededError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'QuotaExceeded' + this.code = typeof error.code === 'number' ? error.code : 1200 + this.message = error.message || `Quota exceeded` + this.status = typeof error.status === 'number' ? error.status : 429 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, QuotaExceededError.prototype) + } +} + +export class RateLimitError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'RateLimit' + this.code = typeof error.code === 'number' ? error.code : 1201 + this.message = error.message || `Rate limit exceeded` + this.status = typeof error.status === 'number' ? error.status : 429 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, RateLimitError.prototype) + } +} + +export class RateLimitedError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'RateLimited' + this.code = typeof error.code === 'number' ? error.code : 1007 + this.message = error.message || `Rate-limited. Please slow down.` + this.status = typeof error.status === 'number' ? error.status : 429 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, RateLimitedError.prototype) + } +} + +export class RequestConflictError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'RequestConflict' + this.code = typeof error.code === 'number' ? error.code : 1004 + this.message = error.message || `Conflict with target resource` + this.status = typeof error.status === 'number' ? error.status : 409 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, RequestConflictError.prototype) + } +} + +export class ResourceExhaustedError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'ResourceExhausted' + this.code = typeof error.code === 'number' ? error.code : 2004 + this.message = error.message || `Resource exhausted` + this.status = typeof error.status === 'number' ? error.status : 400 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, ResourceExhaustedError.prototype) + } +} + +export class SessionExpiredError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'SessionExpired' + this.code = typeof error.code === 'number' ? error.code : 1002 + this.message = error.message || `Session expired` + this.status = typeof error.status === 'number' ? error.status : 403 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, SessionExpiredError.prototype) + } +} + +export class TimeoutError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'Timeout' + this.code = typeof error.code === 'number' ? error.code : 1900 + this.message = error.message || `Request timed out` + this.status = typeof error.status === 'number' ? error.status : 408 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, TimeoutError.prototype) + } +} + +export class UnauthorizedError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'Unauthorized' + this.code = typeof error.code === 'number' ? error.code : 1000 + this.message = error.message || `Unauthorized access` + this.status = typeof error.status === 'number' ? error.status : 401 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, UnauthorizedError.prototype) + } +} + +export class UnauthorizedUserError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'UnauthorizedUser' + this.code = typeof error.code === 'number' ? error.code : 1105 + this.message = error.message || `Unauthorized user` + this.status = typeof error.status === 'number' ? error.status : 403 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, UnauthorizedUserError.prototype) + } +} + +export class UnavailableError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'Unavailable' + this.code = typeof error.code === 'number' ? error.code : 2002 + this.message = error.message || `Unavailable resource` + this.status = typeof error.status === 'number' ? error.status : 400 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, UnavailableError.prototype) + } +} + +export enum errors { + WebrpcEndpoint = 'WebrpcEndpoint', + WebrpcRequestFailed = 'WebrpcRequestFailed', + WebrpcBadRoute = 'WebrpcBadRoute', + WebrpcBadMethod = 'WebrpcBadMethod', + WebrpcBadRequest = 'WebrpcBadRequest', + WebrpcBadResponse = 'WebrpcBadResponse', + WebrpcServerPanic = 'WebrpcServerPanic', + WebrpcInternalError = 'WebrpcInternalError', + WebrpcClientAborted = 'WebrpcClientAborted', + WebrpcStreamLost = 'WebrpcStreamLost', + WebrpcStreamFinished = 'WebrpcStreamFinished', + Aborted = 'Aborted', + AccessKeyMismatch = 'AccessKeyMismatch', + AccessKeyNotFound = 'AccessKeyNotFound', + AtLeastOneKey = 'AtLeastOneKey', + Geoblocked = 'Geoblocked', + InvalidArgument = 'InvalidArgument', + InvalidOrigin = 'InvalidOrigin', + InvalidService = 'InvalidService', + MaxAccessKeys = 'MaxAccessKeys', + MetadataCallFailed = 'MetadataCallFailed', + MethodNotFound = 'MethodNotFound', + NoDefaultKey = 'NoDefaultKey', + NotFound = 'NotFound', + PermissionDenied = 'PermissionDenied', + ProjectNotFound = 'ProjectNotFound', + QueryFailed = 'QueryFailed', + QuotaExceeded = 'QuotaExceeded', + RateLimit = 'RateLimit', + RateLimited = 'RateLimited', + RequestConflict = 'RequestConflict', + ResourceExhausted = 'ResourceExhausted', + SessionExpired = 'SessionExpired', + Timeout = 'Timeout', + Unauthorized = 'Unauthorized', + UnauthorizedUser = 'UnauthorizedUser', + Unavailable = 'Unavailable' +} + +export enum WebrpcErrorCodes { + WebrpcEndpoint = 0, + WebrpcRequestFailed = -1, + WebrpcBadRoute = -2, + WebrpcBadMethod = -3, + WebrpcBadRequest = -4, + WebrpcBadResponse = -5, + WebrpcServerPanic = -6, + WebrpcInternalError = -7, + WebrpcClientAborted = -8, + WebrpcStreamLost = -9, + WebrpcStreamFinished = -10, + Aborted = 1005, + AccessKeyMismatch = 1102, + AccessKeyNotFound = 1101, + AtLeastOneKey = 1302, + Geoblocked = 1006, + InvalidArgument = 2001, + InvalidOrigin = 1103, + InvalidService = 1104, + MaxAccessKeys = 1301, + MetadataCallFailed = 3003, + MethodNotFound = 1003, + NoDefaultKey = 1300, + NotFound = 3000, + PermissionDenied = 1001, + ProjectNotFound = 1100, + QueryFailed = 2003, + QuotaExceeded = 1200, + RateLimit = 1201, + RateLimited = 1007, + RequestConflict = 1004, + ResourceExhausted = 2004, + SessionExpired = 1002, + Timeout = 1900, + Unauthorized = 1000, + UnauthorizedUser = 1105, + Unavailable = 2002 +} + +export const webrpcErrorByCode: { [code: number]: any } = { + [0]: WebrpcEndpointError, + [-1]: WebrpcRequestFailedError, + [-2]: WebrpcBadRouteError, + [-3]: WebrpcBadMethodError, + [-4]: WebrpcBadRequestError, + [-5]: WebrpcBadResponseError, + [-6]: WebrpcServerPanicError, + [-7]: WebrpcInternalErrorError, + [-8]: WebrpcClientAbortedError, + [-9]: WebrpcStreamLostError, + [-10]: WebrpcStreamFinishedError, + [1005]: AbortedError, + [1102]: AccessKeyMismatchError, + [1101]: AccessKeyNotFoundError, + [1302]: AtLeastOneKeyError, + [1006]: GeoblockedError, + [2001]: InvalidArgumentError, + [1103]: InvalidOriginError, + [1104]: InvalidServiceError, + [1301]: MaxAccessKeysError, + [3003]: MetadataCallFailedError, + [1003]: MethodNotFoundError, + [1300]: NoDefaultKeyError, + [3000]: NotFoundError, + [1001]: PermissionDeniedError, + [1100]: ProjectNotFoundError, + [2003]: QueryFailedError, + [1200]: QuotaExceededError, + [1201]: RateLimitError, + [1007]: RateLimitedError, + [1004]: RequestConflictError, + [2004]: ResourceExhaustedError, + [1002]: SessionExpiredError, + [1900]: TimeoutError, + [1000]: UnauthorizedError, + [1105]: UnauthorizedUserError, + [2002]: UnavailableError +} + +// +// Webrpc +// + +export const WebrpcHeader = 'Webrpc' + +export const WebrpcHeaderValue = 'webrpc@v0.31.2;gen-typescript@v0.23.1;sequence-indexer@v0.4.0' + +type WebrpcGenVersions = { + WebrpcGenVersion: string + codeGenName: string + codeGenVersion: string + schemaName: string + schemaVersion: string +} + +export function VersionFromHeader(headers: Headers): WebrpcGenVersions { + const headerValue = headers.get(WebrpcHeader) + if (!headerValue) { + return { + WebrpcGenVersion: '', + codeGenName: '', + codeGenVersion: '', + schemaName: '', + schemaVersion: '' + } + } + + return parseWebrpcGenVersions(headerValue) +} + +function parseWebrpcGenVersions(header: string): WebrpcGenVersions { + const versions = header.split(';') + if (versions.length < 3) { + return { + WebrpcGenVersion: '', + codeGenName: '', + codeGenVersion: '', + schemaName: '', + schemaVersion: '' + } + } + + const [_, WebrpcGenVersion] = versions[0]!.split('@') + const [codeGenName, codeGenVersion] = versions[1]!.split('@') + const [schemaName, schemaVersion] = versions[2]!.split('@') + + return { + WebrpcGenVersion: WebrpcGenVersion ?? '', + codeGenName: codeGenName ?? '', + codeGenVersion: codeGenVersion ?? '', + schemaName: schemaName ?? '', + schemaVersion: schemaVersion ?? '' + } +} diff --git a/packages/indexer/src/indexergw.gen.ts b/packages/indexer/src/indexergw.gen.ts new file mode 100644 index 0000000000..ce59f412a8 --- /dev/null +++ b/packages/indexer/src/indexergw.gen.ts @@ -0,0 +1,1785 @@ +/* eslint-disable */ +// sequence-indexer v0.4.0 3309c3d48de1790b7d12c5769c1e6bc59eb9831c +// -- +// Code generated by Webrpc-gen@v0.31.2 with typescript generator. DO NOT EDIT. +// +// webrpc-gen -schema=merged.gen.json -service=IndexerGateway -target=typescript -client -out=./clients/indexergw.gen.ts + +// Webrpc description and code-gen version +export const WebrpcVersion = 'v1' + +// Schema version of your RIDL schema +export const WebrpcSchemaVersion = 'v0.4.0' + +// Schema hash generated from your RIDL schema +export const WebrpcSchemaHash = '3309c3d48de1790b7d12c5769c1e6bc59eb9831c' + +// +// Client interface +// + +export interface IndexerGatewayClient { + /** + * GetTokenBalances returns a balance summary/details for an specific account + * on all indexer nodes. By default if accountAddress is left empty, it will + * use the account from the jwt session. + */ + getBalanceUpdates(req: GetBalanceUpdatesRequest, headers?: object, signal?: AbortSignal): Promise + + /** + * GetChains returns a list of chains with their ID and name + */ + getChains(req: GetChainsRequest, headers?: object, signal?: AbortSignal): Promise + + /** + * GetNativeTokenBalance queries indexer nodes for the latest native token + * account balance. + */ + getNativeTokenBalance( + req: GetNativeTokenBalanceRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + /** + * GetTokenBalances returns a balance summary/details for a specific account + * on all indexer nodes. By default if accountAddress is left empty, it will + * use the account from the jwt session. + * + * @deprecated Use GetTokenBalancesSummary or GetTokenBalancesDetails instead. + */ + getTokenBalances(req: GetTokenBalancesRequest, headers?: object, signal?: AbortSignal): Promise + + /** + * GetTokenBalancesByContract returns a balances for specific accounts and + * contracts on all indexer nodes. The collection ERC721 & ERC1155 tokens are + * represented as individual balances. + */ + getTokenBalancesByContract( + req: GetTokenBalancesByContractRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + /** + * GetTokenBalancesDetails returns a detailed balance summary for the given + * accounts on all indexer nodes. The collection ERC721 & ERC1155 tokens are + * represented as individual balances. + */ + getTokenBalancesDetails( + req: GetTokenBalancesDetailsRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + /** + * GetTokenBalancesSummary returns a summary of token balances for the given + * accounts on all indexer nodes. The collection ERC721 & ERC1155 tokens are + * represented as a single aggregated balance. + */ + getTokenBalancesSummary( + req: GetTokenBalancesSummaryRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + getTokenPrice(req: GetTokenPriceRequest, headers?: object, signal?: AbortSignal): Promise + + getTokenPrices(req: GetTokenPricesRequest, headers?: object, signal?: AbortSignal): Promise + + /** + * GetTransactionHistory returns the history of mined transactions for the + * given account on all indexer nodes, which includes a list of token transfer + * (sent/received) , and sent transactions from a Sequence wallet. + */ + getTransactionHistory( + req: GetTransactionHistoryRequest, + headers?: object, + signal?: AbortSignal + ): Promise + + /** + * Ping the indexer + */ + ping(headers?: object, signal?: AbortSignal): Promise + + /** + * Get the current runtime health status of the indexer gatewya + */ + runtimeStatus(headers?: object, signal?: AbortSignal): Promise + + /** + * Get the current version of the indexer + */ + version(headers?: object, signal?: AbortSignal): Promise +} + +// +// Schema types +// + +export interface Asset { + id: number + collectionId: number + tokenId?: string + url?: string + metadataField: string + name?: string + filesize?: number + mimeType?: string + width?: number + height?: number + updatedAt?: string +} + +export interface BloomStats { + hitRatio: string + falsePositivesPercent: string + hitCount: number + missCount: number + falsePositives: number +} + +export interface BloomStatus { + enabled: boolean + initialized: boolean + bloomInitElapsedTime: string + stats: BloomStats +} + +export interface Bond { + pebble: PebbleMetrics + estimatedDiskUsagePerTable: any + estimatedDiskUsageTotal: string +} + +export interface ChainInfo { + chainId: number + chainName: string +} + +export interface ContractInfo { + chainId: number + address: string + source: string + name: string + type: string + symbol: string + decimals?: number + logoURI: string + deployed: boolean + bytecodeHash: string + extensions: ContractInfoExtensions + updatedAt: string + queuedAt?: string + status: ResourceStatus +} + +export interface ContractInfoExtensionBridgeInfo { + tokenAddress: string +} + +export interface ContractInfoExtensionIndexingInfo { + useOnChainBalance: boolean +} + +export interface ContractInfoExtensions { + link?: string + description?: string + categories?: Array + bridgeInfo?: { [key: string]: ContractInfoExtensionBridgeInfo } + indexingInfo?: ContractInfoExtensionIndexingInfo + ogImage?: string + ogName?: string + originChainId?: number + originAddress?: string + blacklist?: boolean + verified?: boolean + verifiedBy?: string + featured?: boolean + featureIndex?: number +} + +export enum ContractType { + UNKNOWN = 'UNKNOWN', + NATIVE = 'NATIVE', + ERC20 = 'ERC20', + ERC721 = 'ERC721', + ERC1155 = 'ERC1155', + SEQUENCE_WALLET = 'SEQUENCE_WALLET', + ERC20_BRIDGE = 'ERC20_BRIDGE', + ERC721_BRIDGE = 'ERC721_BRIDGE', + ERC1155_BRIDGE = 'ERC1155_BRIDGE', + SEQ_MARKETPLACE = 'SEQ_MARKETPLACE', + ERC6909 = 'ERC6909' +} + +export enum ContractVerificationStatus { + VERIFIED = 'VERIFIED', + UNVERIFIED = 'UNVERIFIED', + ALL = 'ALL' +} + +export interface DiskUsage { + humanReadable: string + used: number + size: number + percent: number + dirs: { [key: string]: string } +} + +export interface EtherBalance { + accountAddress: string + balanceWei: string +} + +export interface EventDecoded { + topicHash: string + eventSig: string + types: Array + names: Array + values: Array +} + +export interface EventFilter { + events?: Array + contractAddresses?: Array + accounts?: Array + tokenIDs?: Array +} + +export interface EventLog { + id: number + uid: string + type: EventLogType + blockNumber: number + blockHash: string + parentBlockHash: string + contractAddress: string + contractType: ContractType + txnHash: string + txnIndex: number + txnLogIndex: number + logDataType: EventLogDataType + ts: string + txnInfo?: TxnInfo + rawLog?: { [key: string]: any } + event?: EventDecoded +} + +export enum EventLogDataType { + EVENT = 'EVENT', + TOKEN_TRANSFER = 'TOKEN_TRANSFER', + NATIVE_TOKEN_TRANSFER = 'NATIVE_TOKEN_TRANSFER', + SEQUENCE_TXN = 'SEQUENCE_TXN' +} + +export enum EventLogType { + UNKNOWN = 'UNKNOWN', + BLOCK_ADDED = 'BLOCK_ADDED', + BLOCK_REMOVED = 'BLOCK_REMOVED' +} + +export interface GatewayBackendResponseTime { + percentiles: { [key: string]: number } + average: number +} + +export interface GatewayBackendRuntimeStatus { + name: string + chainId: number + responseTime: GatewayBackendResponseTime +} + +export interface GatewayEtherBalance { + chainId: number + errorReason?: string + result: EtherBalance +} + +export interface GatewayNativeTokenBalance { + chainId: number + errorReason?: string + result: NativeTokenBalance +} + +export interface GatewayNativeTokenBalances { + chainId: number + errorReason?: string + results: Array +} + +export interface GatewayPrice { + chainID: number + errorReason?: string + results: Array +} + +export interface GatewayRuntimeStatus { + healthOK: boolean + startTime: string + uptime: number + ver: string + branch: string + commitHash: string + backends: Array +} + +export interface GatewayTokenBalance { + chainId: number + errorReason?: string + results: Array +} + +export interface GatewayTokenPriceQuery { + chainID: number + queries: Array +} + +export interface GatewayTransaction { + chainId: number + errorReason?: string + results: Array +} + +export interface IndexState { + chainId: string + lastBlockNum: number + lastBlockHash: string +} + +export interface IndexedBlock { + blockNumber: number + blockShortHash: string +} + +export interface IndexerMetrics { + blocksPerSecond: number + eventsPerSecond: number +} + +export interface MarketplaceOrder { + orderId: string + tokenContract: string + tokenId: string + isListing: boolean + quantity: string + quantityRemaining: string + currencyAddress: string + pricePerToken: string + expiry: string + orderStatus: OrderStatus + createdBy: string + blockNumber: number + orderbookContractAddress: string + createdAt: number +} + +export interface MarketplaceOrderFilter { + isListing?: boolean + userAddresses?: Array + currencyAddresses: Array + orderIds: Array + tokenIds: Array + excludeUserAddresses?: Array + blockNumberGt: number + createdAtAfter: number + orderStatuses: Array + returnExpired: boolean +} + +export interface MarketplaceTopOrdersFilter { + currencyAddresses: Array + tokenIds: Array + isListing: boolean + priceSort: SortOrder + excludeUser?: string +} + +export interface MetadataOptions { + verifiedOnly?: boolean + unverifiedOnly?: boolean + includeContracts?: Array +} + +export interface NativeTokenBalance { + accountAddress: string + chainId: number + name: string + symbol: string + balance: string + balanceUSD: string + priceUSD: string + priceUpdatedAt?: string + errorReason?: string +} + +export enum NetworkType { + MAINNETS = 'MAINNETS', + TESTNETS = 'TESTNETS', + ALL = 'ALL' +} + +export enum OrderStatus { + OPEN = 'OPEN', + CLOSED = 'CLOSED', + CANCELLED = 'CANCELLED' +} + +export interface Page { + page?: number + column?: string + before?: any + after?: any + sort?: Array + pageSize?: number + more?: boolean +} + +export interface PebbleMetrics { + compactionCount: number + compactionEstimatedDebt: number + compactionInProgressBytes: number + compactionNumInProgress: number + compactionMarkedFiles: number +} + +export interface Price { + contractAddress: string + tokenID?: string + priceUSD: string + updatedAt?: string +} + +export enum ResourceStatus { + NOT_AVAILABLE = 'NOT_AVAILABLE', + REFRESHING = 'REFRESHING', + AVAILABLE = 'AVAILABLE' +} + +export interface RuntimeChecks { + running: boolean + runnables: any + cgoEnabled: boolean + quotaControlEnabled: boolean + syncMode: string + percentIndexed: number + lastBlockNum: number + lastBlockNumWithState: number + bloomStatus: BloomStatus + bond: Bond + diskUsage: DiskUsage + metrics: IndexerMetrics +} + +export interface RuntimeStatus { + healthOK: boolean + indexerEnabled: boolean + startTime: string + uptime: number + ver: string + branch: string + commitHash: string + chainID: number + checks: RuntimeChecks +} + +export interface SortBy { + column: string + order: SortOrder +} + +export enum SortOrder { + DESC = 'DESC', + ASC = 'ASC' +} + +export interface TokenBalance { + contractType: ContractType + contractAddress: string + accountAddress: string + tokenID?: string + balance: string + balanceUSD: string + priceUSD: string + priceUpdatedAt?: string + blockHash: string + blockNumber: number + chainId: number + uniqueCollectibles: string + isSummary: boolean + contractInfo?: ContractInfo + tokenMetadata?: TokenMetadata +} + +export interface TokenBalanceFilter { + contractAddress: string + sinceBlockNumber: number +} + +export interface TokenBalancesByContractFilter { + contractAddresses: Array + accountAddresses?: Array + contractStatus?: ContractVerificationStatus +} + +export interface TokenBalancesFilter { + accountAddresses: Array + contractStatus?: ContractVerificationStatus + contractTypes?: Array + contractWhitelist?: Array + contractBlacklist?: Array + omitNativeBalances: boolean + omitPrices?: boolean +} + +export interface TokenHistory { + blockNumber: number + blockHash: string + contractAddress: string + contractType: ContractType + fromAddress: string + toAddress: string + txnHash: string + txnIndex: number + txnLogIndex: number + tokenIDs: string + amounts: string + ts: string +} + +export interface TokenIDRange { + start: string + end: string +} + +export interface TokenMetadata { + chainId?: number + contractAddress?: string + tokenId: string + source: string + name: string + description?: string + image?: string + video?: string + audio?: string + properties?: { [key: string]: any } + attributes: Array<{ [key: string]: any }> + image_data?: string + external_url?: string + background_color?: string + animation_url?: string + decimals?: number + updatedAt?: string + assets?: Array + status: ResourceStatus + queuedAt?: string + lastFetched?: string +} + +export interface TokenPriceQuery { + contractAddress: string + tokenID?: string +} + +export interface TokenSupply { + tokenID: string + supply: string + chainId: number + contractInfo?: ContractInfo + tokenMetadata?: TokenMetadata +} + +export interface Transaction { + txnHash: string + blockNumber: number + blockHash: string + chainId: number + metaTxnID?: string + transfers?: Array + timestamp: string +} + +export interface TransactionFilter { + txnHash?: string + from?: string + to?: string + contractAddress?: string + event?: string +} + +export interface TransactionHistoryFilter { + accountAddress?: string + contractAddress?: string + accountAddresses?: Array + contractAddresses?: Array + transactionHashes?: Array + metaTransactionIDs?: Array + fromBlock?: number + toBlock?: number + tokenID?: string + omitPrices?: boolean +} + +export interface TransactionLog { + contractAddress: string + topics: Array + data: string + index: number +} + +export interface TransactionReceipt { + txnHash: string + txnStatus: TransactionStatus + txnIndex: number + txnType: TransactionType + blockHash: string + blockNumber: number + gasUsed: number + effectiveGasPrice: string + from: string + to: string + logs: Array + final: boolean + reorged: boolean +} + +export enum TransactionStatus { + FAILED = 'FAILED', + SUCCESSFUL = 'SUCCESSFUL' +} + +export enum TransactionType { + LegacyTxnType = 'LegacyTxnType', + AccessListTxnType = 'AccessListTxnType', + DynamicFeeTxnType = 'DynamicFeeTxnType' +} + +export interface TxnInfo { + from: string + to: string + value: string +} + +export interface TxnTransfer { + transferType: TxnTransferType + contractAddress: string + contractType: ContractType + from: string + to: string + tokenIds?: Array + amounts: Array + logIndex: number + amountsUSD?: Array + pricesUSD?: Array + contractInfo?: ContractInfo + tokenMetadata?: { [key: string]: TokenMetadata } +} + +export enum TxnTransferType { + UNKNOWN = 'UNKNOWN', + SEND = 'SEND', + RECEIVE = 'RECEIVE' +} + +export interface Version { + webrpcVersion: string + schemaVersion: string + schemaHash: string + appVersion: string +} + +export interface WALWriterRuntimeStatus { + healthOK: boolean + startTime: string + uptime: number + ver: string + branch: string + commitHash: string + chainID: number + percentWALWritten: number +} + +export interface WebhookListener { + id: number + projectID: number + url: string + filters: EventFilter + name: string + updatedAt: string + active: boolean +} + +export interface GetBalanceUpdatesRequest { + chainIds?: Array + networks?: Array + networkType?: NetworkType + contractAddress: string + lastBlockNumber: number + lastBlockHash?: string + page?: Page +} + +export interface GetBalanceUpdatesResponse { + page: Page + balances: Array +} + +export interface GetChainsRequest { + networkType?: NetworkType +} + +export interface GetChainsResponse { + chains: Array +} + +export interface GetNativeTokenBalanceRequest { + chainIds?: Array + networks?: Array + networkType?: NetworkType + accountAddress?: string + omitPrices?: boolean +} + +export interface GetNativeTokenBalanceResponse { + balances: Array +} + +export interface GetTokenBalancesRequest { + chainIds?: Array + networks?: Array + networkType?: NetworkType + accountAddress?: string + contractAddress?: string + tokenID?: string + includeMetadata?: boolean + metadataOptions?: MetadataOptions + includeCollectionTokens?: boolean + page?: Page +} + +export interface GetTokenBalancesResponse { + page: Page + balances: Array +} + +export interface GetTokenBalancesByContractRequest { + chainIds?: Array + networks?: Array + networkType?: NetworkType + filter: TokenBalancesByContractFilter + omitMetadata?: boolean + page?: Page +} + +export interface GetTokenBalancesByContractResponse { + page: Page + balances: Array +} + +export interface GetTokenBalancesDetailsRequest { + chainIds?: Array + networks?: Array + networkType?: NetworkType + filter: TokenBalancesFilter + omitMetadata?: boolean + page?: Page +} + +export interface GetTokenBalancesDetailsResponse { + page: Page + nativeBalances: Array + balances: Array +} + +export interface GetTokenBalancesSummaryRequest { + chainIds?: Array + networks?: Array + networkType?: NetworkType + filter: TokenBalancesFilter + omitMetadata?: boolean + page?: Page +} + +export interface GetTokenBalancesSummaryResponse { + page: Page + nativeBalances: Array + balances: Array +} + +export interface GetTokenPriceRequest { + q: GatewayTokenPriceQuery +} + +export interface GetTokenPriceResponse { + price: GatewayPrice +} + +export interface GetTokenPricesRequest { + q: Array +} + +export interface GetTokenPricesResponse { + prices: Array +} + +export interface GetTransactionHistoryRequest { + chainIds?: Array + networks?: Array + networkType?: NetworkType + filter: TransactionHistoryFilter + includeMetadata?: boolean + metadataOptions?: MetadataOptions + page?: Page +} + +export interface GetTransactionHistoryResponse { + page: Page + transactions: Array +} + +export interface PingRequest {} + +export interface PingResponse { + status: boolean +} + +export interface RuntimeStatusRequest {} + +export interface RuntimeStatusResponse { + status: GatewayRuntimeStatus +} + +export interface VersionRequest {} + +export interface VersionResponse { + version: Version +} + +// +// Client +// + +export class IndexerGateway implements IndexerGatewayClient { + protected hostname: string + protected fetch: Fetch + protected path = '/rpc/IndexerGateway/' + + constructor(hostname: string, fetch: Fetch) { + this.hostname = hostname.replace(/\/*$/, '') + this.fetch = (input: RequestInfo, init?: RequestInit) => fetch(input, init) + } + + private url(name: string): string { + return this.hostname + this.path + name + } + + queryKey = { + getBalanceUpdates: (req: GetBalanceUpdatesRequest) => ['IndexerGateway', 'getBalanceUpdates', req] as const, + getChains: (req: GetChainsRequest) => ['IndexerGateway', 'getChains', req] as const, + getNativeTokenBalance: (req: GetNativeTokenBalanceRequest) => ['IndexerGateway', 'getNativeTokenBalance', req] as const, + getTokenBalances: (req: GetTokenBalancesRequest) => ['IndexerGateway', 'getTokenBalances', req] as const, + getTokenBalancesByContract: (req: GetTokenBalancesByContractRequest) => + ['IndexerGateway', 'getTokenBalancesByContract', req] as const, + getTokenBalancesDetails: (req: GetTokenBalancesDetailsRequest) => ['IndexerGateway', 'getTokenBalancesDetails', req] as const, + getTokenBalancesSummary: (req: GetTokenBalancesSummaryRequest) => ['IndexerGateway', 'getTokenBalancesSummary', req] as const, + getTokenPrice: (req: GetTokenPriceRequest) => ['IndexerGateway', 'getTokenPrice', req] as const, + getTokenPrices: (req: GetTokenPricesRequest) => ['IndexerGateway', 'getTokenPrices', req] as const, + getTransactionHistory: (req: GetTransactionHistoryRequest) => ['IndexerGateway', 'getTransactionHistory', req] as const, + ping: () => ['IndexerGateway', 'ping'] as const, + runtimeStatus: () => ['IndexerGateway', 'runtimeStatus'] as const, + version: () => ['IndexerGateway', 'version'] as const + } + + getBalanceUpdates = ( + req: GetBalanceUpdatesRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetBalanceUpdates'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetBalanceUpdatesResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + getChains = (req: GetChainsRequest, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetChains'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetChainsResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + getNativeTokenBalance = ( + req: GetNativeTokenBalanceRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetNativeTokenBalance'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetNativeTokenBalanceResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + getTokenBalances = ( + req: GetTokenBalancesRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetTokenBalances'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetTokenBalancesResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + getTokenBalancesByContract = ( + req: GetTokenBalancesByContractRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetTokenBalancesByContract'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetTokenBalancesByContractResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + getTokenBalancesDetails = ( + req: GetTokenBalancesDetailsRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetTokenBalancesDetails'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetTokenBalancesDetailsResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + getTokenBalancesSummary = ( + req: GetTokenBalancesSummaryRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetTokenBalancesSummary'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetTokenBalancesSummaryResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + getTokenPrice = (req: GetTokenPriceRequest, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetTokenPrice'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetTokenPriceResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + getTokenPrices = (req: GetTokenPricesRequest, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetTokenPrices'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetTokenPricesResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + getTransactionHistory = ( + req: GetTransactionHistoryRequest, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetTransactionHistory'), createHttpRequest(JsonEncode(req), headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'GetTransactionHistoryResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + ping = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('Ping'), createHttpRequest('{}', headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'PingResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + runtimeStatus = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('RuntimeStatus'), createHttpRequest('{}', headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'RuntimeStatusResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } + + version = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('Version'), createHttpRequest('{}', headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return JsonDecode(_data, 'VersionResponse') + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error instanceof Error ? error.message : String(error)}` }) + } + ) + } +} + +const createHttpRequest = (body: string = '{}', headers: object = {}, signal: AbortSignal | null = null): object => { + const reqHeaders: { [key: string]: string } = { + ...headers, + 'Content-Type': 'application/json', + [WebrpcHeader]: WebrpcHeaderValue + } + return { method: 'POST', headers: reqHeaders, body, signal } +} + +const buildResponse = (res: Response): Promise => { + return res.text().then(text => { + let data + try { + data = JSON.parse(text) + } catch (error) { + throw WebrpcBadResponseError.new({ + status: res.status, + cause: `JSON.parse(): ${error instanceof Error ? error.message : String(error)}: response text: ${text}` + }) + } + if (!res.ok) { + const code: number = typeof data.code === 'number' ? data.code : 0 + throw (webrpcErrorByCode[code] || WebrpcError).new(data) + } + return data + }) +} + +export type Fetch = (input: RequestInfo, init?: RequestInit) => Promise + +export const JsonEncode = (obj: T): string => { + return JSON.stringify(obj) +} + +export const JsonDecode = (data: string | any, _typ: string = ''): T => { + let parsed: any = data + if (typeof data === 'string') { + try { + parsed = JSON.parse(data) + } catch (err) { + throw WebrpcBadResponseError.new({ cause: `JsonDecode: JSON.parse failed: ${(err as Error).message}` }) + } + } + return parsed as T +} + +// +// Errors +// + +type WebrpcErrorParams = { name?: string; code?: number; message?: string; status?: number; cause?: string } + +export class WebrpcError extends Error { + code: number + status: number + + constructor(error: WebrpcErrorParams = {}) { + super(error.message) + this.name = error.name || 'WebrpcEndpointError' + this.code = typeof error.code === 'number' ? error.code : 0 + this.message = error.message || `endpoint error` + this.status = typeof error.status === 'number' ? error.status : 400 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, WebrpcError.prototype) + } + + static new(payload: any): WebrpcError { + return new this({ message: payload.message, code: payload.code, status: payload.status, cause: payload.cause }) + } +} + +export class WebrpcEndpointError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'WebrpcEndpoint' + this.code = typeof error.code === 'number' ? error.code : 0 + this.message = error.message || `endpoint error` + this.status = typeof error.status === 'number' ? error.status : 400 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, WebrpcEndpointError.prototype) + } +} + +export class WebrpcRequestFailedError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'WebrpcRequestFailed' + this.code = typeof error.code === 'number' ? error.code : -1 + this.message = error.message || `request failed` + this.status = typeof error.status === 'number' ? error.status : 400 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, WebrpcRequestFailedError.prototype) + } +} + +export class WebrpcBadRouteError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'WebrpcBadRoute' + this.code = typeof error.code === 'number' ? error.code : -2 + this.message = error.message || `bad route` + this.status = typeof error.status === 'number' ? error.status : 404 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, WebrpcBadRouteError.prototype) + } +} + +export class WebrpcBadMethodError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'WebrpcBadMethod' + this.code = typeof error.code === 'number' ? error.code : -3 + this.message = error.message || `bad method` + this.status = typeof error.status === 'number' ? error.status : 405 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, WebrpcBadMethodError.prototype) + } +} + +export class WebrpcBadRequestError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'WebrpcBadRequest' + this.code = typeof error.code === 'number' ? error.code : -4 + this.message = error.message || `bad request` + this.status = typeof error.status === 'number' ? error.status : 400 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, WebrpcBadRequestError.prototype) + } +} + +export class WebrpcBadResponseError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'WebrpcBadResponse' + this.code = typeof error.code === 'number' ? error.code : -5 + this.message = error.message || `bad response` + this.status = typeof error.status === 'number' ? error.status : 500 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, WebrpcBadResponseError.prototype) + } +} + +export class WebrpcServerPanicError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'WebrpcServerPanic' + this.code = typeof error.code === 'number' ? error.code : -6 + this.message = error.message || `server panic` + this.status = typeof error.status === 'number' ? error.status : 500 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, WebrpcServerPanicError.prototype) + } +} + +export class WebrpcInternalErrorError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'WebrpcInternalError' + this.code = typeof error.code === 'number' ? error.code : -7 + this.message = error.message || `internal error` + this.status = typeof error.status === 'number' ? error.status : 500 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, WebrpcInternalErrorError.prototype) + } +} + +export class WebrpcClientAbortedError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'WebrpcClientAborted' + this.code = typeof error.code === 'number' ? error.code : -8 + this.message = error.message || `request aborted by client` + this.status = typeof error.status === 'number' ? error.status : 400 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, WebrpcClientAbortedError.prototype) + } +} + +export class WebrpcStreamLostError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'WebrpcStreamLost' + this.code = typeof error.code === 'number' ? error.code : -9 + this.message = error.message || `stream lost` + this.status = typeof error.status === 'number' ? error.status : 400 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, WebrpcStreamLostError.prototype) + } +} + +export class WebrpcStreamFinishedError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'WebrpcStreamFinished' + this.code = typeof error.code === 'number' ? error.code : -10 + this.message = error.message || `stream finished` + this.status = typeof error.status === 'number' ? error.status : 200 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, WebrpcStreamFinishedError.prototype) + } +} + +// +// Schema errors +// + +export class AbortedError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'Aborted' + this.code = typeof error.code === 'number' ? error.code : 1005 + this.message = error.message || `Request aborted` + this.status = typeof error.status === 'number' ? error.status : 400 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, AbortedError.prototype) + } +} + +export class AccessKeyMismatchError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'AccessKeyMismatch' + this.code = typeof error.code === 'number' ? error.code : 1102 + this.message = error.message || `Access key mismatch` + this.status = typeof error.status === 'number' ? error.status : 409 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, AccessKeyMismatchError.prototype) + } +} + +export class AccessKeyNotFoundError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'AccessKeyNotFound' + this.code = typeof error.code === 'number' ? error.code : 1101 + this.message = error.message || `Access key not found` + this.status = typeof error.status === 'number' ? error.status : 401 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, AccessKeyNotFoundError.prototype) + } +} + +export class AtLeastOneKeyError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'AtLeastOneKey' + this.code = typeof error.code === 'number' ? error.code : 1302 + this.message = error.message || `You need at least one Access Key` + this.status = typeof error.status === 'number' ? error.status : 403 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, AtLeastOneKeyError.prototype) + } +} + +export class GeoblockedError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'Geoblocked' + this.code = typeof error.code === 'number' ? error.code : 1006 + this.message = error.message || `Geoblocked region` + this.status = typeof error.status === 'number' ? error.status : 451 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, GeoblockedError.prototype) + } +} + +export class InvalidArgumentError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'InvalidArgument' + this.code = typeof error.code === 'number' ? error.code : 2001 + this.message = error.message || `Invalid argument` + this.status = typeof error.status === 'number' ? error.status : 400 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, InvalidArgumentError.prototype) + } +} + +export class InvalidOriginError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'InvalidOrigin' + this.code = typeof error.code === 'number' ? error.code : 1103 + this.message = error.message || `Invalid origin for Access Key` + this.status = typeof error.status === 'number' ? error.status : 403 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, InvalidOriginError.prototype) + } +} + +export class InvalidServiceError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'InvalidService' + this.code = typeof error.code === 'number' ? error.code : 1104 + this.message = error.message || `Service not enabled for Access key` + this.status = typeof error.status === 'number' ? error.status : 403 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, InvalidServiceError.prototype) + } +} + +export class MaxAccessKeysError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'MaxAccessKeys' + this.code = typeof error.code === 'number' ? error.code : 1301 + this.message = error.message || `Access keys limit reached` + this.status = typeof error.status === 'number' ? error.status : 403 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, MaxAccessKeysError.prototype) + } +} + +export class MetadataCallFailedError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'MetadataCallFailed' + this.code = typeof error.code === 'number' ? error.code : 3003 + this.message = error.message || `Metadata service call failed` + this.status = typeof error.status === 'number' ? error.status : 400 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, MetadataCallFailedError.prototype) + } +} + +export class MethodNotFoundError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'MethodNotFound' + this.code = typeof error.code === 'number' ? error.code : 1003 + this.message = error.message || `Method not found` + this.status = typeof error.status === 'number' ? error.status : 404 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, MethodNotFoundError.prototype) + } +} + +export class NoDefaultKeyError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'NoDefaultKey' + this.code = typeof error.code === 'number' ? error.code : 1300 + this.message = error.message || `No default access key found` + this.status = typeof error.status === 'number' ? error.status : 403 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, NoDefaultKeyError.prototype) + } +} + +export class NotFoundError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'NotFound' + this.code = typeof error.code === 'number' ? error.code : 3000 + this.message = error.message || `Resource not found` + this.status = typeof error.status === 'number' ? error.status : 400 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, NotFoundError.prototype) + } +} + +export class PermissionDeniedError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'PermissionDenied' + this.code = typeof error.code === 'number' ? error.code : 1001 + this.message = error.message || `Permission denied` + this.status = typeof error.status === 'number' ? error.status : 403 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, PermissionDeniedError.prototype) + } +} + +export class ProjectNotFoundError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'ProjectNotFound' + this.code = typeof error.code === 'number' ? error.code : 1100 + this.message = error.message || `Project not found` + this.status = typeof error.status === 'number' ? error.status : 401 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, ProjectNotFoundError.prototype) + } +} + +export class QueryFailedError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'QueryFailed' + this.code = typeof error.code === 'number' ? error.code : 2003 + this.message = error.message || `Query failed` + this.status = typeof error.status === 'number' ? error.status : 400 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, QueryFailedError.prototype) + } +} + +export class QuotaExceededError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'QuotaExceeded' + this.code = typeof error.code === 'number' ? error.code : 1200 + this.message = error.message || `Quota exceeded` + this.status = typeof error.status === 'number' ? error.status : 429 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, QuotaExceededError.prototype) + } +} + +export class RateLimitError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'RateLimit' + this.code = typeof error.code === 'number' ? error.code : 1201 + this.message = error.message || `Rate limit exceeded` + this.status = typeof error.status === 'number' ? error.status : 429 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, RateLimitError.prototype) + } +} + +export class RateLimitedError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'RateLimited' + this.code = typeof error.code === 'number' ? error.code : 1007 + this.message = error.message || `Rate-limited. Please slow down.` + this.status = typeof error.status === 'number' ? error.status : 429 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, RateLimitedError.prototype) + } +} + +export class RequestConflictError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'RequestConflict' + this.code = typeof error.code === 'number' ? error.code : 1004 + this.message = error.message || `Conflict with target resource` + this.status = typeof error.status === 'number' ? error.status : 409 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, RequestConflictError.prototype) + } +} + +export class ResourceExhaustedError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'ResourceExhausted' + this.code = typeof error.code === 'number' ? error.code : 2004 + this.message = error.message || `Resource exhausted` + this.status = typeof error.status === 'number' ? error.status : 400 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, ResourceExhaustedError.prototype) + } +} + +export class SessionExpiredError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'SessionExpired' + this.code = typeof error.code === 'number' ? error.code : 1002 + this.message = error.message || `Session expired` + this.status = typeof error.status === 'number' ? error.status : 403 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, SessionExpiredError.prototype) + } +} + +export class TimeoutError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'Timeout' + this.code = typeof error.code === 'number' ? error.code : 1900 + this.message = error.message || `Request timed out` + this.status = typeof error.status === 'number' ? error.status : 408 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, TimeoutError.prototype) + } +} + +export class UnauthorizedError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'Unauthorized' + this.code = typeof error.code === 'number' ? error.code : 1000 + this.message = error.message || `Unauthorized access` + this.status = typeof error.status === 'number' ? error.status : 401 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, UnauthorizedError.prototype) + } +} + +export class UnauthorizedUserError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'UnauthorizedUser' + this.code = typeof error.code === 'number' ? error.code : 1105 + this.message = error.message || `Unauthorized user` + this.status = typeof error.status === 'number' ? error.status : 403 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, UnauthorizedUserError.prototype) + } +} + +export class UnavailableError extends WebrpcError { + constructor(error: WebrpcErrorParams = {}) { + super(error) + this.name = error.name || 'Unavailable' + this.code = typeof error.code === 'number' ? error.code : 2002 + this.message = error.message || `Unavailable resource` + this.status = typeof error.status === 'number' ? error.status : 400 + if (error.cause !== undefined) this.cause = error.cause + Object.setPrototypeOf(this, UnavailableError.prototype) + } +} + +export enum errors { + WebrpcEndpoint = 'WebrpcEndpoint', + WebrpcRequestFailed = 'WebrpcRequestFailed', + WebrpcBadRoute = 'WebrpcBadRoute', + WebrpcBadMethod = 'WebrpcBadMethod', + WebrpcBadRequest = 'WebrpcBadRequest', + WebrpcBadResponse = 'WebrpcBadResponse', + WebrpcServerPanic = 'WebrpcServerPanic', + WebrpcInternalError = 'WebrpcInternalError', + WebrpcClientAborted = 'WebrpcClientAborted', + WebrpcStreamLost = 'WebrpcStreamLost', + WebrpcStreamFinished = 'WebrpcStreamFinished', + Aborted = 'Aborted', + AccessKeyMismatch = 'AccessKeyMismatch', + AccessKeyNotFound = 'AccessKeyNotFound', + AtLeastOneKey = 'AtLeastOneKey', + Geoblocked = 'Geoblocked', + InvalidArgument = 'InvalidArgument', + InvalidOrigin = 'InvalidOrigin', + InvalidService = 'InvalidService', + MaxAccessKeys = 'MaxAccessKeys', + MetadataCallFailed = 'MetadataCallFailed', + MethodNotFound = 'MethodNotFound', + NoDefaultKey = 'NoDefaultKey', + NotFound = 'NotFound', + PermissionDenied = 'PermissionDenied', + ProjectNotFound = 'ProjectNotFound', + QueryFailed = 'QueryFailed', + QuotaExceeded = 'QuotaExceeded', + RateLimit = 'RateLimit', + RateLimited = 'RateLimited', + RequestConflict = 'RequestConflict', + ResourceExhausted = 'ResourceExhausted', + SessionExpired = 'SessionExpired', + Timeout = 'Timeout', + Unauthorized = 'Unauthorized', + UnauthorizedUser = 'UnauthorizedUser', + Unavailable = 'Unavailable' +} + +export enum WebrpcErrorCodes { + WebrpcEndpoint = 0, + WebrpcRequestFailed = -1, + WebrpcBadRoute = -2, + WebrpcBadMethod = -3, + WebrpcBadRequest = -4, + WebrpcBadResponse = -5, + WebrpcServerPanic = -6, + WebrpcInternalError = -7, + WebrpcClientAborted = -8, + WebrpcStreamLost = -9, + WebrpcStreamFinished = -10, + Aborted = 1005, + AccessKeyMismatch = 1102, + AccessKeyNotFound = 1101, + AtLeastOneKey = 1302, + Geoblocked = 1006, + InvalidArgument = 2001, + InvalidOrigin = 1103, + InvalidService = 1104, + MaxAccessKeys = 1301, + MetadataCallFailed = 3003, + MethodNotFound = 1003, + NoDefaultKey = 1300, + NotFound = 3000, + PermissionDenied = 1001, + ProjectNotFound = 1100, + QueryFailed = 2003, + QuotaExceeded = 1200, + RateLimit = 1201, + RateLimited = 1007, + RequestConflict = 1004, + ResourceExhausted = 2004, + SessionExpired = 1002, + Timeout = 1900, + Unauthorized = 1000, + UnauthorizedUser = 1105, + Unavailable = 2002 +} + +export const webrpcErrorByCode: { [code: number]: any } = { + [0]: WebrpcEndpointError, + [-1]: WebrpcRequestFailedError, + [-2]: WebrpcBadRouteError, + [-3]: WebrpcBadMethodError, + [-4]: WebrpcBadRequestError, + [-5]: WebrpcBadResponseError, + [-6]: WebrpcServerPanicError, + [-7]: WebrpcInternalErrorError, + [-8]: WebrpcClientAbortedError, + [-9]: WebrpcStreamLostError, + [-10]: WebrpcStreamFinishedError, + [1005]: AbortedError, + [1102]: AccessKeyMismatchError, + [1101]: AccessKeyNotFoundError, + [1302]: AtLeastOneKeyError, + [1006]: GeoblockedError, + [2001]: InvalidArgumentError, + [1103]: InvalidOriginError, + [1104]: InvalidServiceError, + [1301]: MaxAccessKeysError, + [3003]: MetadataCallFailedError, + [1003]: MethodNotFoundError, + [1300]: NoDefaultKeyError, + [3000]: NotFoundError, + [1001]: PermissionDeniedError, + [1100]: ProjectNotFoundError, + [2003]: QueryFailedError, + [1200]: QuotaExceededError, + [1201]: RateLimitError, + [1007]: RateLimitedError, + [1004]: RequestConflictError, + [2004]: ResourceExhaustedError, + [1002]: SessionExpiredError, + [1900]: TimeoutError, + [1000]: UnauthorizedError, + [1105]: UnauthorizedUserError, + [2002]: UnavailableError +} + +// +// Webrpc +// + +export const WebrpcHeader = 'Webrpc' + +export const WebrpcHeaderValue = 'webrpc@v0.31.2;gen-typescript@v0.23.1;sequence-indexer@v0.4.0' + +type WebrpcGenVersions = { + WebrpcGenVersion: string + codeGenName: string + codeGenVersion: string + schemaName: string + schemaVersion: string +} + +export function VersionFromHeader(headers: Headers): WebrpcGenVersions { + const headerValue = headers.get(WebrpcHeader) + if (!headerValue) { + return { + WebrpcGenVersion: '', + codeGenName: '', + codeGenVersion: '', + schemaName: '', + schemaVersion: '' + } + } + + return parseWebrpcGenVersions(headerValue) +} + +function parseWebrpcGenVersions(header: string): WebrpcGenVersions { + const versions = header.split(';') + if (versions.length < 3) { + return { + WebrpcGenVersion: '', + codeGenName: '', + codeGenVersion: '', + schemaName: '', + schemaVersion: '' + } + } + + const [_, WebrpcGenVersion] = versions[0]!.split('@') + const [codeGenName, codeGenVersion] = versions[1]!.split('@') + const [schemaName, schemaVersion] = versions[2]!.split('@') + + return { + WebrpcGenVersion: WebrpcGenVersion ?? '', + codeGenName: codeGenName ?? '', + codeGenVersion: codeGenVersion ?? '', + schemaName: schemaName ?? '', + schemaVersion: schemaVersion ?? '' + } +} diff --git a/packages/metadata/CHANGELOG.md b/packages/metadata/CHANGELOG.md new file mode 100644 index 0000000000..8ae80f3bc1 --- /dev/null +++ b/packages/metadata/CHANGELOG.md @@ -0,0 +1,1366 @@ +# @0xsequence/metadata + +## 1.10.8 + +### Patch Changes + +- update metadata bindings + +## 1.10.7 + +### Patch Changes + +- minor fixes to waas client + +## 1.10.6 + +### Patch Changes + +- metadata: update bindings + +## 1.10.5 + +### Patch Changes + +- network: ape-chain-testnet -> apechain-testnet + +## 1.10.4 + +### Patch Changes + +- network: add b3-sepolia, ape-chain-testnet, blast, blast-sepolia + +## 1.10.3 + +### Patch Changes + +- typing fix + +## 1.10.2 + +### Patch Changes + +- - waas: add getIdToken method + - indexer: update api client + +## 1.10.1 + +### Patch Changes + +- metadata: update bindings + +## 1.10.0 + +### Minor Changes + +- waas release v1.3.0 + +## 1.9.37 + +### Patch Changes + +- network: adds nativeToken data to NetworkMetadata constants + +## 1.9.36 + +### Patch Changes + +- guard: export client + +## 1.9.35 + +### Patch Changes + +- guard: update bindings + +## 1.9.34 + +### Patch Changes + +- waas: always use lowercase email + +## 1.9.33 + +### Patch Changes + +- waas: umd build + +## 1.9.32 + +### Patch Changes + +- indexer: update bindings + +## 1.9.31 + +### Patch Changes + +- metadata: token directory changes + +## 1.9.30 + +### Patch Changes + +- update + +## 1.9.29 + +### Patch Changes + +- disable gnosis chain + +## 1.9.28 + +### Patch Changes + +- add utils/merkletree + +## 1.9.27 + +### Patch Changes + +- network: optimistic -> optimism +- waas: remove defaults +- api, sessions: update bindings + +## 1.9.26 + +### Patch Changes + +- - add backend interfaces for pluggable interfaces + - introduce @0xsequence/react-native + - update pnpm to lockfile v9 + +## 1.9.25 + +### Patch Changes + +- update webrpc clients with new error types + +## 1.9.24 + +### Patch Changes + +- waas: add memoryStore backend to localStore + +## 1.9.23 + +### Patch Changes + +- update api client bindings + +## 1.9.22 + +### Patch Changes + +- update metadata client bindings + +## 1.9.21 + +### Patch Changes + +- api client bindings + +## 1.9.20 + +### Patch Changes + +- api client bindings update + +## 1.9.19 + +### Patch Changes + +- waas update + +## 1.9.18 + +### Patch Changes + +- provider: prohibit dangerous functions + +## 1.9.17 + +### Patch Changes + +- network: add xr-sepolia + +## 1.9.16 + +### Patch Changes + +- waas: sequence.feeOptions + +## 1.9.15 + +### Patch Changes + +- metadata: collection external_link field name fix + +## 1.9.14 + +### Patch Changes + +- network: astar-zkatana -> astar-zkyoto +- network: deprecate polygon mumbai network +- network: add xai and polygon amoy + +## 1.9.13 + +### Patch Changes + +- waas: fix @0xsequence/network dependency + +## 1.9.12 + +### Patch Changes + +- indexer: update rpc bindings +- provider: signMessage: Serialize the BytesLike or string message into hexstring before sending +- waas: SessionAuthProof + +## 1.9.11 + +### Patch Changes + +- metdata, update rpc bindings + +## 1.9.10 + +### Patch Changes + +- update metadata rpc bindings + +## 1.9.9 + +### Patch Changes + +- metadata, add SequenceCollections rpc client + +## 1.9.8 + +### Patch Changes + +- waas client update + +## 1.9.7 + +### Patch Changes + +- update rpc client bindings for api, metadata and relayer + +## 1.9.6 + +### Patch Changes + +- waas package update + +## 1.9.5 + +### Patch Changes + +- RpcRelayer prioritize project access key + +## 1.9.4 + +### Patch Changes + +- waas: fix network dependency + +## 1.9.3 + +### Patch Changes + +- provider: don't append access key to RPC url if user has already provided it + +## 1.9.2 + +### Patch Changes + +- network: add xai-sepolia + +## 1.9.1 + +### Patch Changes + +- analytics fix + +## 1.9.0 + +### Minor Changes + +- waas release + +## 1.8.8 + +### Patch Changes + +- update metadata bindings + +## 1.8.7 + +### Patch Changes + +- provider: update databeat to 0.9.1 + +## 1.8.6 + +### Patch Changes + +- guard: SignedOwnershipProof + +## 1.8.5 + +### Patch Changes + +- guard: signOwnershipProof and isSignedOwnershipProof + +## 1.8.4 + +### Patch Changes + +- network: add homeverse to networks list + +## 1.8.3 + +### Patch Changes + +- api: introduce basic linked wallet support + +## 1.8.2 + +### Patch Changes + +- provider: don't initialize analytics unless explicitly requested + +## 1.8.1 + +### Patch Changes + +- update to analytics provider + +## 1.8.0 + +### Minor Changes + +- provider: project analytics + +## 1.7.2 + +### Patch Changes + +- 0xsequence: ChainId should not be exported as a type +- account, wallet: fix nonce selection + +## 1.7.1 + +### Patch Changes + +- network: add missing avalanche logoURI + +## 1.7.0 + +### Minor Changes + +- provider: projectAccessKey is now required + +### Patch Changes + +- network: add NetworkMetadata.logoURI property for all networks + +## 1.6.3 + +### Patch Changes + +- network list update + +## 1.6.2 + +### Patch Changes + +- auth: projectAccessKey option +- wallet: use 12 bytes for random space + +## 1.6.1 + +### Patch Changes + +- core: add simple config from subdigest support +- core: fix encode tree with subdigest +- account: implement buildOnChainSignature on Account + +## 1.6.0 + +### Minor Changes + +- account, wallet: parallel transactions by default + +### Patch Changes + +- provider: emit disconnect on sign out + +## 1.5.0 + +### Minor Changes + +- signhub: add 'signing' signer status + +### Patch Changes + +- auth: Session.open: onAccountAddress callback +- account: allow empty transaction bundles + +## 1.4.9 + +### Patch Changes + +- rename SequenceMetadataClient to SequenceMetadata + +## 1.4.8 + +### Patch Changes + +- account: Account.getSigners + +## 1.4.7 + +### Patch Changes + +- update indexer client bindings + +## 1.4.6 + +### Patch Changes + +- - add sepolia networks, mark goerli as deprecated + - update indexer client bindings + +## 1.4.5 + +### Patch Changes + +- indexer/metadata: update client bindings +- auth: selectWallet with new address + +## 1.4.4 + +### Patch Changes + +- indexer: update bindings +- auth: handle jwt expiry + +## 1.4.3 + +### Patch Changes + +- guard: return active status from GuardSigner.getAuthMethods + +## 1.4.2 + +### Patch Changes + +- guard: update bindings + +## 1.4.1 + +### Patch Changes + +- network: remove unused networks +- signhub: orchestrator interface +- guard: auth methods interface +- guard: update bindings for pin and totp +- guard: no more retry logic + +## 1.4.0 + +### Minor Changes + +- project access key support + +## 1.3.0 + +### Minor Changes + +- signhub: account children + +### Patch Changes + +- guard: do not throw when building deploy transaction +- network: snowtrace.io -> subnets.avax.network/c-chain + +## 1.2.9 + +### Patch Changes + +- account: AccountSigner.sendTransaction simulateForFeeOptions +- relayer: update bindings + +## 1.2.8 + +### Patch Changes + +- rename X-Sequence-Token-Key header to X-Access-Key + +## 1.2.7 + +### Patch Changes + +- add x-sequence-token-key to clients + +## 1.2.6 + +### Patch Changes + +- Fix bind multicall provider + +## 1.2.5 + +### Patch Changes + +- Multicall default configuration fixes + +## 1.2.4 + +### Patch Changes + +- provider: Adding missing payment provider types to PaymentProviderOption +- provider: WalletRequestHandler.notifyChainChanged + +## 1.2.3 + +### Patch Changes + +- auth, provider: connect to accept optional authorizeNonce + +## 1.2.2 + +### Patch Changes + +- provider: allow createContract calls +- core: check for explicit zero address in contract deployments + +## 1.2.1 + +### Patch Changes + +- auth: use sequence api chain id as reference chain id if available + +## 1.2.0 + +### Minor Changes + +- split services from session, better local support + +## 1.1.15 + +### Patch Changes + +- guard: remove error filtering + +## 1.1.14 + +### Patch Changes + +- guard: add GuardSigner.onError + +## 1.1.13 + +### Patch Changes + +- provider: pass client version with connect options +- provider: removing large from BannerSize + +## 1.1.12 + +### Patch Changes + +- provider: adding bannerSize to ConnectOptions + +## 1.1.11 + +### Patch Changes + +- add homeverse configs + +## 1.1.10 + +### Patch Changes + +- handle default EIP6492 on send + +## 1.1.9 + +### Patch Changes + +- Custom default EIP6492 on client + +## 1.1.8 + +### Patch Changes + +- metadata: searchMetadata: add types filter + +## 1.1.7 + +### Patch Changes + +- adding signInWith connect settings option to allow dapps to automatically login their users with a certain provider optimizing the normal authentication flow + +## 1.1.6 + +### Patch Changes + +- metadata: searchMetadata: add chainID and excludeTokenMetadata filters + +## 1.1.5 + +### Patch Changes + +- account: re-compute meta-transaction id for wallet deployment transactions + +## 1.1.4 + +### Patch Changes + +- network: rename base-mainnet to base +- provider: override isDefaultChain with ConnectOptions.networkId if provided + +## 1.1.3 + +### Patch Changes + +- provider: use network id from transport session +- provider: sign authorization using ConnectOptions.networkId if provided + +## 1.1.2 + +### Patch Changes + +- provider: jsonrpc chain id fixes + +## 1.1.1 + +### Patch Changes + +- network: add base mainnet and sepolia +- provider: reject toxic transaction requests + +## 1.1.0 + +### Minor Changes + +- Refactor dapp facing provider + +## 1.0.5 + +### Patch Changes + +- network: export network constants +- guard: use the correct global for fetch +- network: nova-explorer.arbitrum.io -> nova.arbiscan.io + +## 1.0.4 + +### Patch Changes + +- provider: accept name or number for networkId + +## 1.0.3 + +### Patch Changes + +- Simpler isValidSignature helpers + +## 1.0.2 + +### Patch Changes + +- add extra signature validation utils methods + +## 1.0.1 + +### Patch Changes + +- add homeverse testnet + +## 1.0.0 + +### Major Changes + +- https://sequence.xyz/blog/sequence-wallet-light-state-sync-full-merkle-wallets + +## 0.43.34 + +### Patch Changes + +- auth: no jwt for indexer + +## 0.43.33 + +### Patch Changes + +- Adding onConnectOptionsChange handler to WalletRequestHandler + +## 0.43.32 + +### Patch Changes + +- add Base Goerli network + +## 0.43.31 + +### Patch Changes + +- remove AuxDataProvider, add promptSignInConnect + +## 0.43.30 + +### Patch Changes + +- add arbitrum goerli testnet + +## 0.43.29 + +### Patch Changes + +- provider: check availability of window object + +## 0.43.28 + +### Patch Changes + +- update api bindings + +## 0.43.27 + +### Patch Changes + +- Add rpc is sequence method + +## 0.43.26 + +### Patch Changes + +- add zkevm url to enum + +## 0.43.25 + +### Patch Changes + +- added polygon zkevm to mainnet networks + +## 0.43.24 + +### Patch Changes + +- name change from zkevm to polygon-zkevm + +## 0.43.23 + +### Patch Changes + +- update zkEVM name to Polygon zkEVM + +## 0.43.22 + +### Patch Changes + +- add zkevm chain + +## 0.43.21 + +### Patch Changes + +- api: update client bindings + +## 0.43.20 + +### Patch Changes + +- indexer: update bindings + +## 0.43.19 + +### Patch Changes + +- session proof update + +## 0.43.18 + +### Patch Changes + +- rpc client global check, hardening + +## 0.43.17 + +### Patch Changes + +- rpc clients, check of 'global' is defined + +## 0.43.16 + +### Patch Changes + +- ethers peerDep to v5, update rpc client global use + +## 0.43.15 + +### Patch Changes + +- - provider: expand receiver type on some util methods + +## 0.43.14 + +### Patch Changes + +- bump + +## 0.43.13 + +### Patch Changes + +- update rpc bindings + +## 0.43.12 + +### Patch Changes + +- provider: single wallet init, and add new unregisterWallet() method + +## 0.43.11 + +### Patch Changes + +- fix lockfiles +- re-add mocha type deleter + +## 0.43.10 + +### Patch Changes + +- various improvements + +## 0.43.9 + +### Patch Changes + +- update deps + +## 0.43.8 + +### Patch Changes + +- network: JsonRpcProvider with caching + +## 0.43.7 + +### Patch Changes + +- provider: fix wallet network init + +## 0.43.6 + +### Patch Changes + +- metadatata: update rpc bindings + +## 0.43.5 + +### Patch Changes + +- provider: do not set default network for connect messages +- provider: forward missing error message + +## 0.43.4 + +### Patch Changes + +- no-change version bump to fix incorrectly tagged snapshot build + +## 0.43.3 + +### Patch Changes + +- metadata: update bindings + +## 0.43.2 + +### Patch Changes + +- provider: implement connectUnchecked + +## 0.43.1 + +### Patch Changes + +- update to latest ethauth dep + +## 0.43.0 + +### Minor Changes + +- move ethers to a peer dependency + +## 0.42.10 + +### Patch Changes + +- add auxDataProvider + +## 0.42.9 + +### Patch Changes + +- provider: add eip-191 exceptions + +## 0.42.8 + +### Patch Changes + +- provider: skip setting intent origin if we're unity plugin + +## 0.42.7 + +### Patch Changes + +- Add sign in options to connection settings + +## 0.42.6 + +### Patch Changes + +- api bindings update + +## 0.42.5 + +### Patch Changes + +- relayer: don't treat missing receipt as hard failure + +## 0.42.4 + +### Patch Changes + +- provider: add custom app protocol to connect options + +## 0.42.3 + +### Patch Changes + +- update api bindings + +## 0.42.2 + +### Patch Changes + +- disable rinkeby network + +## 0.42.1 + +### Patch Changes + +- wallet: optional waitForReceipt parameter + +## 0.42.0 + +### Minor Changes + +- relayer: estimateGasLimits -> simulate +- add simulator package + +### Patch Changes + +- transactions: fix flattenAuxTransactions +- provider: only filter nullish values +- provider: re-map transaction 'gas' back to 'gasLimit' + +## 0.41.3 + +### Patch Changes + +- api bindings update + +## 0.41.2 + +### Patch Changes + +- api bindings update + +## 0.41.1 + +### Patch Changes + +- update default networks + +## 0.41.0 + +### Minor Changes + +- relayer: fix Relayer.wait() interface + + The interface for calling Relayer.wait() has changed. Instead of a single optional ill-defined timeout/delay parameter, there are three optional parameters, in order: + + - timeout: the maximum time to wait for the transaction receipt + - delay: the polling interval, i.e. the time to wait between requests + - maxFails: the maximum number of hard failures to tolerate before giving up + + Please update your codebase accordingly. + +- relayer: add optional waitForReceipt parameter to Relayer.relay + + The behaviour of Relayer.relay() was not well-defined with respect to whether or not it waited for a receipt. + This change allows the caller to specify whether to wait or not, with the default behaviour being to wait. + +### Patch Changes + +- relayer: wait receipt retry logic +- fix wrapped object error +- provider: forward delegateCall and revertOnError transaction fields + +## 0.40.6 + +### Patch Changes + +- add arbitrum-nova chain + +## 0.40.5 + +### Patch Changes + +- api: update bindings + +## 0.40.4 + +### Patch Changes + +- add unreal transport + +## 0.40.3 + +### Patch Changes + +- provider: fix MessageToSign message type + +## 0.40.2 + +### Patch Changes + +- Wallet provider, loadSession method + +## 0.40.1 + +### Patch Changes + +- export sequence.initWallet and sequence.getWallet + +## 0.40.0 + +### Minor Changes + +- add sequence.initWallet(network, config) and sequence.getWallet() helper methods + +## 0.39.6 + +### Patch Changes + +- indexer: update client bindings + +## 0.39.5 + +### Patch Changes + +- provider: fix networkRpcUrl config option + +## 0.39.4 + +### Patch Changes + +- api: update client bindings + +## 0.39.3 + +### Patch Changes + +- add request method on Web3Provider + +## 0.39.2 + +### Patch Changes + +- update umd name + +## 0.39.1 + +### Patch Changes + +- add Aurora network +- add origin info for accountsChanged event to handle it per dapp + +## 0.39.0 + +### Minor Changes + +- abstract window.localStorage to interface type + +## 0.38.2 + +### Patch Changes + +- provider: add Settings.defaultPurchaseAmount + +## 0.38.1 + +### Patch Changes + +- update api and metadata rpc bindings + +## 0.38.0 + +### Minor Changes + +- api: update bindings, change TokenPrice interface +- bridge: remove @0xsequence/bridge package +- api: update bindings, rename ContractCallArg to TupleComponent + +## 0.37.1 + +### Patch Changes + +- Add back sortNetworks - Removing sorting was a breaking change for dapps on older versions which directly integrate sequence. + +## 0.37.0 + +### Minor Changes + +- network related fixes and improvements +- api: bindings: exchange rate lookups + +## 0.36.13 + +### Patch Changes + +- api: update bindings with new price endpoints + +## 0.36.12 + +### Patch Changes + +- wallet: skip remote signers if not needed +- auth: check that signature meets threshold before requesting auth token + +## 0.36.11 + +### Patch Changes + +- Prefix EIP191 message on wallet-request-handler + +## 0.36.10 + +### Patch Changes + +- support bannerUrl on connect + +## 0.36.9 + +### Patch Changes + +- minor dev xp improvements + +## 0.36.8 + +### Patch Changes + +- more connect options (theme, payment providers, funding currencies) + +## 0.36.7 + +### Patch Changes + +- fix missing break + +## 0.36.6 + +### Patch Changes + +- wallet_switchEthereumChain support + +## 0.36.5 + +### Patch Changes + +- auth: bump ethauth to 0.7.0 + network, wallet: don't assume position of auth network in list + api/indexer/metadata: trim trailing slash on hostname, and add endpoint urls + relayer: Allow to specify local relayer transaction parameters like gas price or gas limit + +## 0.36.4 + +### Patch Changes + +- Updating list of chain ids to include other ethereum compatible chains + +## 0.36.3 + +### Patch Changes + +- provider: pass connect options to prompter methods + +## 0.36.2 + +### Patch Changes + +- transactions: Setting target to 0x0 when empty to during SequenceTxAbiEncode + +## 0.36.1 + +### Patch Changes + +- metadata: update client with more fields + +## 0.36.0 + +### Minor Changes + +- relayer, wallet: fee quote support + +## 0.35.12 + +### Patch Changes + +- provider: rename wallet.commands to wallet.utils + +## 0.35.11 + +### Patch Changes + +- provider/utils: smoother message validation + +## 0.35.10 + +### Patch Changes + +- upgrade deps + +## 0.35.9 + +### Patch Changes + +- provider: window-transport override event handlers with new wallet instance + +## 0.35.8 + +### Patch Changes + +- provider: async wallet sign in improvements + +## 0.35.7 + +### Patch Changes + +- config: cache wallet configs + +## 0.35.6 + +### Patch Changes + +- provider: support async signin of wallet request handler + +## 0.35.5 + +### Patch Changes + +- wallet: skip threshold check during fee estimation + +## 0.35.4 + +### Patch Changes + +- - browser extension mode, center window + +## 0.35.3 + +### Patch Changes + +- - update window position when in browser extension mode + +## 0.35.2 + +### Patch Changes + +- - provider: WindowMessageHandler accept optional windowHref + +## 0.35.1 + +### Patch Changes + +- wallet: update config on undeployed too + +## 0.35.0 + +### Minor Changes + +- - config: add buildStubSignature + - provider: add checks to signing cases for wallet deployment and config statuses + - provider: add prompt for wallet deployment + - relayer: add BaseRelayer.prependWalletDeploy + - relayer: add Relayer.feeOptions + - relayer: account for wallet deployment in fee estimation + - transactions: add fromTransactionish + - wallet: add Account.prependConfigUpdate + - wallet: add Account.getFeeOptions + +## 0.34.0 + +### Minor Changes + +- - upgrade deps + +## 0.31.3 + +### Patch Changes + +- update metadata bindings + +## 0.31.0 + +### Minor Changes + +- - upgrading to ethers v5.5 + +## 0.30.0 + +### Minor Changes + +- - upgrade most deps + +## 0.29.8 + +### Patch Changes + +- update api + +## 0.29.1 + +### Patch Changes + +- metadata: ContractInfo.decimals is now optional, i.e. may be undefined + + api: new APIs for user storage and isUsingGoogleMail + +## 0.29.0 + +### Minor Changes + +- major architectural changes in Sequence design + + - only one API instance, API is no longer a per-chain service + - separate per-chain indexer service, API no longer handles indexing + - single contract metadata service, API no longer serves metadata + + chaind package has been removed, indexer and metadata packages have been added + + stronger typing with new explicit ChainId type + + multicall fixes and improvements + + forbid "wait" transactions in sendTransactionBatch calls diff --git a/packages/metadata/README.md b/packages/metadata/README.md new file mode 100644 index 0000000000..9939fb8b12 --- /dev/null +++ b/packages/metadata/README.md @@ -0,0 +1,4 @@ +@0xsequence/metadata +==================== + +See [0xsequence project page](https://github.com/0xsequence/sequence.js). diff --git a/packages/metadata/package.json b/packages/metadata/package.json new file mode 100644 index 0000000000..d8a67d03fe --- /dev/null +++ b/packages/metadata/package.json @@ -0,0 +1,22 @@ +{ + "name": "@0xsequence/metadata", + "version": "2.0.0", + "description": "metadata sub-package for Sequence", + "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/metadata", + "source": "src/index.ts", + "main": "dist/0xsequence-metadata.cjs.js", + "module": "dist/0xsequence-metadata.esm.js", + "author": "Horizon Blockchain Games", + "license": "Apache-2.0", + "scripts": { + "test": "echo", + "typecheck": "tsc --noEmit" + }, + "dependencies": {}, + "peerDependencies": {}, + "devDependencies": {}, + "files": [ + "src", + "dist" + ] +} diff --git a/packages/metadata/src/index.ts b/packages/metadata/src/index.ts new file mode 100644 index 0000000000..383ee39206 --- /dev/null +++ b/packages/metadata/src/index.ts @@ -0,0 +1,68 @@ +export * from './metadata.gen' + +import { Metadata as MetadataRpc, Collections as CollectionsRpc } from './metadata.gen' + +const fetch = typeof global === 'object' ? global.fetch : window.fetch + +export class SequenceMetadata extends MetadataRpc { + constructor( + hostname: string = 'https://metadata.sequence.app', + public projectAccessKey?: string, + public jwtAuth?: string + ) { + super(hostname.endsWith('/') ? hostname.slice(0, -1) : hostname, fetch) + this.fetch = this._fetch + } + + _fetch = (input: RequestInfo, init?: RequestInit): Promise => { + // automatically include jwt and access key auth header to requests + // if its been set on the client + const headers: { [key: string]: any } = {} + + const jwtAuth = this.jwtAuth + const projectAccessKey = this.projectAccessKey + + if (jwtAuth && jwtAuth.length > 0) { + headers['Authorization'] = `BEARER ${jwtAuth}` + } + + if (projectAccessKey && projectAccessKey.length > 0) { + headers['X-Access-Key'] = projectAccessKey + } + + // before the request is made + init!.headers = { ...init!.headers, ...headers } + + return fetch(input, init) + } +} + +export class SequenceCollections extends CollectionsRpc { + constructor( + hostname: string = 'https://metadata.sequence.app', + public jwtAuth?: string + ) { + super(hostname.endsWith('/') ? hostname.slice(0, -1) : hostname, fetch) + this.fetch = this._fetch + } + + _fetch = (input: RequestInfo, init?: RequestInit): Promise => { + // automatically include jwt auth header to requests + // if its been set on the client + const headers: { [key: string]: any } = {} + + const jwtAuth = this.jwtAuth + + if (jwtAuth && jwtAuth.length > 0) { + headers['Authorization'] = `BEARER ${jwtAuth}` + } + + // before the request is made + init!.headers = { ...init!.headers, ...headers } + + return fetch(input, init) + } + + // TODO: add uploadAsset() method similar to, + // https://github.com/0xsequence/go-sequence/blob/master/metadata/collections.go#L52 +} diff --git a/packages/metadata/src/metadata.gen.ts b/packages/metadata/src/metadata.gen.ts new file mode 100644 index 0000000000..a827de36b2 --- /dev/null +++ b/packages/metadata/src/metadata.gen.ts @@ -0,0 +1,2384 @@ +/* eslint-disable */ +// sequence-metadata v0.4.0 d5ad7dcea438ee205efb2a08dcfde61c2226625d +// -- +// Code generated by webrpc-gen@v0.18.6 with typescript generator. DO NOT EDIT. +// +// webrpc-gen -schema=metadata.ridl -target=typescript -client -out=./clients/metadata.gen.ts + +// WebRPC description and code-gen version +export const WebRPCVersion = 'v1' + +// Schema version of your RIDL schema +export const WebRPCSchemaVersion = 'v0.4.0' + +// Schema hash generated from your RIDL schema +export const WebRPCSchemaHash = 'd5ad7dcea438ee205efb2a08dcfde61c2226625d' + +// +// Types +// + +export enum ContractType { + UNKNOWN = 'UNKNOWN', + ERC20 = 'ERC20', + ERC721 = 'ERC721', + ERC1155 = 'ERC1155' +} + +export enum PropertyType { + INT = 'INT', + STRING = 'STRING', + ARRAY = 'ARRAY', + GENERIC = 'GENERIC' +} + +export enum SwapType { + UNKNOWN = 'UNKNOWN', + BUY = 'BUY', + SELL = 'SELL' +} + +export enum TaskStatus { + PENDING = 'PENDING', + PAUSED = 'PAUSED', + FAILED = 'FAILED', + COMPLETED = 'COMPLETED', + DISABLED = 'DISABLED' +} + +export interface Version { + webrpcVersion: string + schemaVersion: string + schemaHash: string + appVersion: string +} + +export interface RuntimeStatus { + healthOK: boolean + startTime: string + uptime: number + ver: string + branch: string + commitHash: string + checks: RuntimeChecks +} + +export interface RuntimeChecks {} + +export interface ContractIndex { + collectionId?: number + chainId: number + address: string + type: ContractType + metadata: { [key: string]: any } + contentHash: number + deployed: boolean + bytecodeHash: string + notFound: boolean + updatedAt: string +} + +export interface TokenIndex { + key: string + chainId: number + contractAddress: string + tokenId: string + metadata: { [key: string]: any } + notFound?: boolean + lastFetched?: string + fetchCount?: number + updatedAt: string +} + +export interface ContractInfo { + chainId: number + address: string + name: string + type: string + symbol: string + decimals?: number + logoURI: string + deployed: boolean + bytecodeHash: string + extensions: ContractInfoExtensions + updatedAt: string +} + +export interface ContractInfoExtensions { + link: string + description: string + ogImage: string + originChainId: number + originAddress: string + blacklist: boolean + verified: boolean + verifiedBy: string + featured: boolean +} + +export interface TokenMetadata { + tokenId: string + name: string + description?: string + image?: string + video?: string + audio?: string + properties?: { [key: string]: any } + attributes: Array<{ [key: string]: any }> + image_data?: string + external_url?: string + background_color?: string + animation_url?: string + decimals?: number + updatedAt?: string + assets?: Array +} + +export interface PropertyFilter { + name: string + type: PropertyType + min?: number + max?: number + values?: Array +} + +export interface Filter { + text?: string + properties?: Array +} + +export interface Collection { + id: number + projectId: number + metadata: CollectionMetadata + private: boolean + revealKey?: string + createdAt?: string + updatedAt?: string + deletedAt?: string + baseURIs?: CollectionBaseURIs + assets?: Array +} + +export interface CollectionMetadata { + name: string + description?: string + image?: string + external_link?: string + properties?: { [key: string]: any } + attributes?: Array<{ [key: string]: any }> +} + +export interface CollectionBaseURIs { + contractMetadataURI: string + tokenMetadataURI: string +} + +export interface Asset { + id: number + collectionId: number + tokenId?: string + url?: string + metadataField: string + name?: string + filesize?: number + mimeType?: string + width?: number + height?: number + updatedAt?: string +} + +export interface Token { + collectionId: number + tokenId: string + metadata: TokenMetadata + private: boolean + updatedAt?: string +} + +export interface GetNiftyswapUnitPricesRequest { + swapType: SwapType + ids: Array + amounts: Array +} + +export interface GetNiftyswapUnitPricesResponse { + unitPrice: string + unitAmount: string + availableAmount: string +} + +export interface Page { + page?: number + column?: string + before?: any + after?: any + pageSize?: number + more?: boolean +} + +export interface TaskRunner { + id: number + workGroup: string + runAt: string +} + +export interface Task { + id: number + queue: string + status?: TaskStatus + try: number + runAt?: string + lastRanAt?: string + createdAt?: string + payload: Array + hash?: string +} + +export interface Metadata { + ping(headers?: object, signal?: AbortSignal): Promise + version(headers?: object, signal?: AbortSignal): Promise + runtimeStatus(headers?: object, signal?: AbortSignal): Promise + getTokenMetadata(args: GetTokenMetadataArgs, headers?: object, signal?: AbortSignal): Promise + refreshTokenMetadata( + args: RefreshTokenMetadataArgs, + headers?: object, + signal?: AbortSignal + ): Promise + enqueueTokensForRefresh( + args: EnqueueTokensForRefreshArgs, + headers?: object, + signal?: AbortSignal + ): Promise + getTokenRefreshStatus( + args: GetTokenRefreshStatusArgs, + headers?: object, + signal?: AbortSignal + ): Promise + getTokenRefreshResult( + args: GetTokenRefreshResultArgs, + headers?: object, + signal?: AbortSignal + ): Promise + cancelRefreshJob(args: CancelRefreshJobArgs, headers?: object, signal?: AbortSignal): Promise + getTokenMetadataBatch( + args: GetTokenMetadataBatchArgs, + headers?: object, + signal?: AbortSignal + ): Promise + searchTokenMetadata(args: SearchTokenMetadataArgs, headers?: object, signal?: AbortSignal): Promise + searchTokenIDs(args: SearchTokenIDsArgs, headers?: object, signal?: AbortSignal): Promise + tokenCollectionFilters( + args: TokenCollectionFiltersArgs, + headers?: object, + signal?: AbortSignal + ): Promise + getContractInfo(args: GetContractInfoArgs, headers?: object, signal?: AbortSignal): Promise + getContractInfoBatch( + args: GetContractInfoBatchArgs, + headers?: object, + signal?: AbortSignal + ): Promise + searchContractInfo(args: SearchContractInfoArgs, headers?: object, signal?: AbortSignal): Promise + searchContractInfoBatch( + args: SearchContractInfoBatchArgs, + headers?: object, + signal?: AbortSignal + ): Promise + searchMetadata(args: SearchMetadataArgs, headers?: object, signal?: AbortSignal): Promise + searchTokens(args: SearchTokensArgs, headers?: object, signal?: AbortSignal): Promise + searchContracts(args: SearchContractsArgs, headers?: object, signal?: AbortSignal): Promise + getNiftyswapTokenQuantity( + args: GetNiftyswapTokenQuantityArgs, + headers?: object, + signal?: AbortSignal + ): Promise + getNiftyswapUnitPrices( + args: GetNiftyswapUnitPricesArgs, + headers?: object, + signal?: AbortSignal + ): Promise + getNiftyswapUnitPricesWithQuantities( + args: GetNiftyswapUnitPricesWithQuantitiesArgs, + headers?: object, + signal?: AbortSignal + ): Promise + addContractToMintMonitor( + args: AddContractToMintMonitorArgs, + headers?: object, + signal?: AbortSignal + ): Promise + removeContractFromMintMonitor( + args: RemoveContractFromMintMonitorArgs, + headers?: object, + signal?: AbortSignal + ): Promise + mintMonitorJobStatus( + args: MintMonitorJobStatusArgs, + headers?: object, + signal?: AbortSignal + ): Promise + mintMonitorTriggerJob( + args: MintMonitorTriggerJobArgs, + headers?: object, + signal?: AbortSignal + ): Promise + syncContractTokens(args: SyncContractTokensArgs, headers?: object, signal?: AbortSignal): Promise + abortContractSync(args: AbortContractSyncArgs, headers?: object, signal?: AbortSignal): Promise + contractSyncJobStatus( + args: ContractSyncJobStatusArgs, + headers?: object, + signal?: AbortSignal + ): Promise + directoryGetNetworks( + args: DirectoryGetNetworksArgs, + headers?: object, + signal?: AbortSignal + ): Promise + directoryGetCollections( + args: DirectoryGetCollectionsArgs, + headers?: object, + signal?: AbortSignal + ): Promise + directorySearchCollections( + args: DirectorySearchCollectionsArgs, + headers?: object, + signal?: AbortSignal + ): Promise +} + +export interface PingArgs {} + +export interface PingReturn { + status: boolean +} +export interface VersionArgs {} + +export interface VersionReturn { + version: Version +} +export interface RuntimeStatusArgs {} + +export interface RuntimeStatusReturn { + status: RuntimeStatus +} +export interface GetTokenMetadataArgs { + chainID: string + contractAddress: string + tokenIDs: Array +} + +export interface GetTokenMetadataReturn { + tokenMetadata: Array +} +export interface RefreshTokenMetadataArgs { + chainID: string + contractAddress: string + tokenIDs?: Array + refreshAll?: boolean +} + +export interface RefreshTokenMetadataReturn { + taskId: number +} +export interface EnqueueTokensForRefreshArgs { + chainID: string + contractAddress: string + tokenIDs?: Array + refreshAll?: boolean +} + +export interface EnqueueTokensForRefreshReturn { + taskId: number +} +export interface GetTokenRefreshStatusArgs { + taskId: number +} + +export interface GetTokenRefreshStatusReturn { + status?: TaskStatus +} +export interface GetTokenRefreshResultArgs { + taskId: number +} + +export interface GetTokenRefreshResultReturn { + status?: TaskStatus + tokens: { [key: string]: boolean } + failureReasons: { [key: string]: string } +} +export interface CancelRefreshJobArgs { + taskId: number +} + +export interface CancelRefreshJobReturn { + ok: boolean +} +export interface GetTokenMetadataBatchArgs { + chainID: string + contractTokenMap: { [key: string]: Array } +} + +export interface GetTokenMetadataBatchReturn { + contractTokenMetadata: { [key: string]: Array } +} +export interface SearchTokenMetadataArgs { + chainID: string + contractAddress: string + filter: Filter + page?: Page +} + +export interface SearchTokenMetadataReturn { + page: Page + tokenMetadata: Array +} +export interface SearchTokenIDsArgs { + chainID: string + contractAddress: string + filter: Filter + page?: Page +} + +export interface SearchTokenIDsReturn { + page: Page + tokenIds: Array +} +export interface TokenCollectionFiltersArgs { + chainID: string + contractAddress: string +} + +export interface TokenCollectionFiltersReturn { + filters: Array +} +export interface GetContractInfoArgs { + chainID: string + contractAddress: string +} + +export interface GetContractInfoReturn { + contractInfo: ContractInfo +} +export interface GetContractInfoBatchArgs { + chainID: string + contractAddresses: Array +} + +export interface GetContractInfoBatchReturn { + contractInfoMap: { [key: string]: ContractInfo } +} +export interface SearchContractInfoArgs { + contractAddress: string +} + +export interface SearchContractInfoReturn { + contractInfoList: Array +} +export interface SearchContractInfoBatchArgs { + contractAddresses: Array +} + +export interface SearchContractInfoBatchReturn { + contractInfoByChain: { [key: string]: Array } +} +export interface SearchMetadataArgs { + filter: string + chainID?: string + types?: Array + excludeTokenMetadata?: boolean +} + +export interface SearchMetadataReturn { + tokenMetadata: Array + contractInfo: Array +} +export interface SearchTokensArgs { + q: string + chainID?: string + page?: Page +} + +export interface SearchTokensReturn { + tokenMetadata: Array + nextPage: Page +} +export interface SearchContractsArgs { + q: string + chainID?: string + chainIDs?: Array + types?: Array + page?: Page +} + +export interface SearchContractsReturn { + contractInfo: Array + nextPage: Page +} +export interface GetNiftyswapTokenQuantityArgs { + chainID: string + contractAddress: string + tokenIDs: Array +} + +export interface GetNiftyswapTokenQuantityReturn { + quantity: { [key: string]: string } +} +export interface GetNiftyswapUnitPricesArgs { + chainID: string + contractAddress: string + req: GetNiftyswapUnitPricesRequest + fresh: boolean +} + +export interface GetNiftyswapUnitPricesReturn { + prices: { [key: string]: string } +} +export interface GetNiftyswapUnitPricesWithQuantitiesArgs { + chainID: string + contractAddress: string + req: GetNiftyswapUnitPricesRequest + fresh: boolean +} + +export interface GetNiftyswapUnitPricesWithQuantitiesReturn { + prices: { [key: string]: GetNiftyswapUnitPricesResponse } +} +export interface AddContractToMintMonitorArgs { + chainID: string + contractAddress: string +} + +export interface AddContractToMintMonitorReturn { + ok: boolean +} +export interface RemoveContractFromMintMonitorArgs { + chainID: string + contractAddress: string +} + +export interface RemoveContractFromMintMonitorReturn { + ok: boolean +} +export interface MintMonitorJobStatusArgs { + chainID: string + contractAddress: string +} + +export interface MintMonitorJobStatusReturn { + task: Task +} +export interface MintMonitorTriggerJobArgs { + chainID: string + contractAddress: string +} + +export interface MintMonitorTriggerJobReturn { + ok: boolean +} +export interface SyncContractTokensArgs { + chainID: string + contractAddress: string +} + +export interface SyncContractTokensReturn { + taskID: number +} +export interface AbortContractSyncArgs { + taskID: number +} + +export interface AbortContractSyncReturn { + ok: boolean +} +export interface ContractSyncJobStatusArgs { + taskID: number +} + +export interface ContractSyncJobStatusReturn { + refreshTask: Task + syncTask: Task +} +export interface DirectoryGetNetworksArgs { + includeTestnets?: boolean + onlyFeatured?: boolean +} + +export interface DirectoryGetNetworksReturn { + networks: Array +} +export interface DirectoryGetCollectionsArgs { + chainId?: number + includeTestnets?: boolean + onlyFeatured?: boolean + page?: Page +} + +export interface DirectoryGetCollectionsReturn { + collections: Array + page: Page +} +export interface DirectorySearchCollectionsArgs { + query: string + chainId?: number + includeTestnets?: boolean + onlyFeatured?: boolean + page?: Page +} + +export interface DirectorySearchCollectionsReturn { + collections: Array + page: Page +} + +export interface Collections { + createCollection(args: CreateCollectionArgs, headers?: object, signal?: AbortSignal): Promise + getCollection(args: GetCollectionArgs, headers?: object, signal?: AbortSignal): Promise + listCollections(args: ListCollectionsArgs, headers?: object, signal?: AbortSignal): Promise + updateCollection(args: UpdateCollectionArgs, headers?: object, signal?: AbortSignal): Promise + deleteCollection(args: DeleteCollectionArgs, headers?: object, signal?: AbortSignal): Promise + publishCollection(args: PublishCollectionArgs, headers?: object, signal?: AbortSignal): Promise + unpublishCollection(args: UnpublishCollectionArgs, headers?: object, signal?: AbortSignal): Promise + createToken(args: CreateTokenArgs, headers?: object, signal?: AbortSignal): Promise + getToken(args: GetTokenArgs, headers?: object, signal?: AbortSignal): Promise + listTokens(args: ListTokensArgs, headers?: object, signal?: AbortSignal): Promise + updateToken(args: UpdateTokenArgs, headers?: object, signal?: AbortSignal): Promise + deleteToken(args: DeleteTokenArgs, headers?: object, signal?: AbortSignal): Promise + createAsset(args: CreateAssetArgs, headers?: object, signal?: AbortSignal): Promise + getAsset(args: GetAssetArgs, headers?: object, signal?: AbortSignal): Promise + updateAsset(args: UpdateAssetArgs, headers?: object, signal?: AbortSignal): Promise + deleteAsset(args: DeleteAssetArgs, headers?: object, signal?: AbortSignal): Promise +} + +export interface CreateCollectionArgs { + projectId?: number + collection: Collection +} + +export interface CreateCollectionReturn { + collection: Collection +} +export interface GetCollectionArgs { + projectId?: number + collectionId: number +} + +export interface GetCollectionReturn { + collection: Collection +} +export interface ListCollectionsArgs { + projectId?: number + page?: Page +} + +export interface ListCollectionsReturn { + page: Page + collections: Array +} +export interface UpdateCollectionArgs { + projectId?: number + collection: Collection +} + +export interface UpdateCollectionReturn { + collection: Collection +} +export interface DeleteCollectionArgs { + projectId?: number + collectionId: number +} + +export interface DeleteCollectionReturn { + status: boolean +} +export interface PublishCollectionArgs { + projectId?: number + collectionId: number + recursive?: boolean +} + +export interface PublishCollectionReturn { + collection: Collection +} +export interface UnpublishCollectionArgs { + projectId?: number + collectionId: number +} + +export interface UnpublishCollectionReturn { + collection: Collection +} +export interface CreateTokenArgs { + projectId?: number + collectionId: number + token: TokenMetadata + private?: boolean +} + +export interface CreateTokenReturn { + token: TokenMetadata + assets: Array +} +export interface GetTokenArgs { + projectId?: number + collectionId: number + tokenId: string +} + +export interface GetTokenReturn { + token: TokenMetadata + assets: Array +} +export interface ListTokensArgs { + projectId?: number + collectionId: number + page?: Page +} + +export interface ListTokensReturn { + page: Page + tokens: Array +} +export interface UpdateTokenArgs { + projectId?: number + collectionId: number + tokenId: string + token: TokenMetadata + private?: boolean +} + +export interface UpdateTokenReturn { + token: TokenMetadata +} +export interface DeleteTokenArgs { + projectId?: number + collectionId: number + tokenId: string +} + +export interface DeleteTokenReturn { + status: boolean +} +export interface CreateAssetArgs { + projectId?: number + asset: Asset +} + +export interface CreateAssetReturn { + asset: Asset +} +export interface GetAssetArgs { + projectId?: number + assetId: number +} + +export interface GetAssetReturn { + asset: Asset +} +export interface UpdateAssetArgs { + projectId?: number + asset: Asset +} + +export interface UpdateAssetReturn { + asset: Asset +} +export interface DeleteAssetArgs { + projectId?: number + assetId: number +} + +export interface DeleteAssetReturn { + status: boolean +} + +export interface Admin { + addContractsToTokenDirectory( + args: AddContractsToTokenDirectoryArgs, + headers?: object, + signal?: AbortSignal + ): Promise + removeContractsFromTokenDirectory( + args: RemoveContractsFromTokenDirectoryArgs, + headers?: object, + signal?: AbortSignal + ): Promise + modifyFeatureIndex(args: ModifyFeatureIndexArgs, headers?: object, signal?: AbortSignal): Promise + getFeatureIndex(args: GetFeatureIndexArgs, headers?: object, signal?: AbortSignal): Promise + listTokenDirectory(args: ListTokenDirectoryArgs, headers?: object, signal?: AbortSignal): Promise + linkCollection(args: LinkCollectionArgs, headers?: object, signal?: AbortSignal): Promise + listLinkedContracts(args: ListLinkedContractsArgs, headers?: object, signal?: AbortSignal): Promise +} + +export interface AddContractsToTokenDirectoryArgs { + contracts: Array + featureIndexes: Array +} + +export interface AddContractsToTokenDirectoryReturn { + ok: boolean +} +export interface RemoveContractsFromTokenDirectoryArgs { + chainHandle: string + contracts: Array +} + +export interface RemoveContractsFromTokenDirectoryReturn { + ok: boolean +} +export interface ModifyFeatureIndexArgs { + chainHandle: string + contractAddress: string + featured: number +} + +export interface ModifyFeatureIndexReturn { + ok: boolean +} +export interface GetFeatureIndexArgs { + chainHandle: string + contractAddress: string +} + +export interface GetFeatureIndexReturn { + featured: number +} +export interface ListTokenDirectoryArgs { + chainID?: number + includeTestnets?: boolean + onlyFeatured?: boolean + page?: Page +} + +export interface ListTokenDirectoryReturn { + page: Page + collections: Array +} +export interface LinkCollectionArgs { + projectId: number + chainID: number + contractAddress: string + collectionId?: number +} + +export interface LinkCollectionReturn { + ok: boolean +} +export interface ListLinkedContractsArgs { + projectId: number + collectionId?: number + page?: Page +} + +export interface ListLinkedContractsReturn { + collections: Array + page: Page +} + +// +// Client +// +export class Metadata implements Metadata { + protected hostname: string + protected fetch: Fetch + protected path = '/rpc/Metadata/' + + constructor(hostname: string, fetch: Fetch) { + this.hostname = hostname + this.fetch = (input: RequestInfo, init?: RequestInit) => fetch(input, init) + } + + private url(name: string): string { + return this.hostname + this.path + name + } + + ping = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('Ping'), createHTTPRequest({}, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + status: _data.status + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + version = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('Version'), createHTTPRequest({}, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + version: _data.version + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + runtimeStatus = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('RuntimeStatus'), createHTTPRequest({}, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + status: _data.status + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + getTokenMetadata = (args: GetTokenMetadataArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetTokenMetadata'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + tokenMetadata: >_data.tokenMetadata + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + refreshTokenMetadata = ( + args: RefreshTokenMetadataArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('RefreshTokenMetadata'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + taskId: _data.taskId + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + enqueueTokensForRefresh = ( + args: EnqueueTokensForRefreshArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('EnqueueTokensForRefresh'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + taskId: _data.taskId + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + getTokenRefreshStatus = ( + args: GetTokenRefreshStatusArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetTokenRefreshStatus'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + status: _data.status + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + getTokenRefreshResult = ( + args: GetTokenRefreshResultArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetTokenRefreshResult'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + status: _data.status, + tokens: <{ [key: string]: boolean }>_data.tokens, + failureReasons: <{ [key: string]: string }>_data.failureReasons + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + cancelRefreshJob = (args: CancelRefreshJobArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('CancelRefreshJob'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + ok: _data.ok + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + getTokenMetadataBatch = ( + args: GetTokenMetadataBatchArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetTokenMetadataBatch'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + contractTokenMetadata: <{ [key: string]: Array }>_data.contractTokenMetadata + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + searchTokenMetadata = ( + args: SearchTokenMetadataArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('SearchTokenMetadata'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + page: _data.page, + tokenMetadata: >_data.tokenMetadata + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + searchTokenIDs = (args: SearchTokenIDsArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('SearchTokenIDs'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + page: _data.page, + tokenIds: >_data.tokenIds + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + tokenCollectionFilters = ( + args: TokenCollectionFiltersArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('TokenCollectionFilters'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + filters: >_data.filters + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + getContractInfo = (args: GetContractInfoArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetContractInfo'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + contractInfo: _data.contractInfo + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + getContractInfoBatch = ( + args: GetContractInfoBatchArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetContractInfoBatch'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + contractInfoMap: <{ [key: string]: ContractInfo }>_data.contractInfoMap + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + searchContractInfo = ( + args: SearchContractInfoArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('SearchContractInfo'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + contractInfoList: >_data.contractInfoList + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + searchContractInfoBatch = ( + args: SearchContractInfoBatchArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('SearchContractInfoBatch'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + contractInfoByChain: <{ [key: string]: Array }>_data.contractInfoByChain + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + searchMetadata = (args: SearchMetadataArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('SearchMetadata'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + tokenMetadata: >_data.tokenMetadata, + contractInfo: >_data.contractInfo + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + searchTokens = (args: SearchTokensArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('SearchTokens'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + tokenMetadata: >_data.tokenMetadata, + nextPage: _data.nextPage + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + searchContracts = (args: SearchContractsArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('SearchContracts'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + contractInfo: >_data.contractInfo, + nextPage: _data.nextPage + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + getNiftyswapTokenQuantity = ( + args: GetNiftyswapTokenQuantityArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetNiftyswapTokenQuantity'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + quantity: <{ [key: string]: string }>_data.quantity + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + getNiftyswapUnitPrices = ( + args: GetNiftyswapUnitPricesArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetNiftyswapUnitPrices'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + prices: <{ [key: string]: string }>_data.prices + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + getNiftyswapUnitPricesWithQuantities = ( + args: GetNiftyswapUnitPricesWithQuantitiesArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetNiftyswapUnitPricesWithQuantities'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + prices: <{ [key: string]: GetNiftyswapUnitPricesResponse }>_data.prices + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + addContractToMintMonitor = ( + args: AddContractToMintMonitorArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('AddContractToMintMonitor'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + ok: _data.ok + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + removeContractFromMintMonitor = ( + args: RemoveContractFromMintMonitorArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('RemoveContractFromMintMonitor'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + ok: _data.ok + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + mintMonitorJobStatus = ( + args: MintMonitorJobStatusArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('MintMonitorJobStatus'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + task: _data.task + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + mintMonitorTriggerJob = ( + args: MintMonitorTriggerJobArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('MintMonitorTriggerJob'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + ok: _data.ok + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + syncContractTokens = ( + args: SyncContractTokensArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('SyncContractTokens'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + taskID: _data.taskID + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + abortContractSync = (args: AbortContractSyncArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('AbortContractSync'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + ok: _data.ok + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + contractSyncJobStatus = ( + args: ContractSyncJobStatusArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('ContractSyncJobStatus'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + refreshTask: _data.refreshTask, + syncTask: _data.syncTask + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + directoryGetNetworks = ( + args: DirectoryGetNetworksArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('DirectoryGetNetworks'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + networks: >_data.networks + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + directoryGetCollections = ( + args: DirectoryGetCollectionsArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('DirectoryGetCollections'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + collections: >_data.collections, + page: _data.page + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + directorySearchCollections = ( + args: DirectorySearchCollectionsArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('DirectorySearchCollections'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + collections: >_data.collections, + page: _data.page + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } +} +export class Collections implements Collections { + protected hostname: string + protected fetch: Fetch + protected path = '/rpc/Collections/' + + constructor(hostname: string, fetch: Fetch) { + this.hostname = hostname + this.fetch = (input: RequestInfo, init?: RequestInit) => fetch(input, init) + } + + private url(name: string): string { + return this.hostname + this.path + name + } + + createCollection = (args: CreateCollectionArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('CreateCollection'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + collection: _data.collection + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + getCollection = (args: GetCollectionArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetCollection'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + collection: _data.collection + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + listCollections = (args: ListCollectionsArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('ListCollections'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + page: _data.page, + collections: >_data.collections + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + updateCollection = (args: UpdateCollectionArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('UpdateCollection'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + collection: _data.collection + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + deleteCollection = (args: DeleteCollectionArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('DeleteCollection'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + status: _data.status + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + publishCollection = (args: PublishCollectionArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('PublishCollection'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + collection: _data.collection + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + unpublishCollection = ( + args: UnpublishCollectionArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('UnpublishCollection'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + collection: _data.collection + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + createToken = (args: CreateTokenArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('CreateToken'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + token: _data.token, + assets: >_data.assets + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + getToken = (args: GetTokenArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetToken'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + token: _data.token, + assets: >_data.assets + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + listTokens = (args: ListTokensArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('ListTokens'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + page: _data.page, + tokens: >_data.tokens + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + updateToken = (args: UpdateTokenArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('UpdateToken'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + token: _data.token + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + deleteToken = (args: DeleteTokenArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('DeleteToken'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + status: _data.status + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + createAsset = (args: CreateAssetArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('CreateAsset'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + asset: _data.asset + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + getAsset = (args: GetAssetArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetAsset'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + asset: _data.asset + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + updateAsset = (args: UpdateAssetArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('UpdateAsset'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + asset: _data.asset + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + deleteAsset = (args: DeleteAssetArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('DeleteAsset'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + status: _data.status + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } +} +export class Admin implements Admin { + protected hostname: string + protected fetch: Fetch + protected path = '/rpc/Admin/' + + constructor(hostname: string, fetch: Fetch) { + this.hostname = hostname + this.fetch = (input: RequestInfo, init?: RequestInit) => fetch(input, init) + } + + private url(name: string): string { + return this.hostname + this.path + name + } + + addContractsToTokenDirectory = ( + args: AddContractsToTokenDirectoryArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('AddContractsToTokenDirectory'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + ok: _data.ok + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + removeContractsFromTokenDirectory = ( + args: RemoveContractsFromTokenDirectoryArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('RemoveContractsFromTokenDirectory'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + ok: _data.ok + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + modifyFeatureIndex = ( + args: ModifyFeatureIndexArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('ModifyFeatureIndex'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + ok: _data.ok + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + getFeatureIndex = (args: GetFeatureIndexArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetFeatureIndex'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + featured: _data.featured + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + listTokenDirectory = ( + args: ListTokenDirectoryArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('ListTokenDirectory'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + page: _data.page, + collections: >_data.collections + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + linkCollection = (args: LinkCollectionArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('LinkCollection'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + ok: _data.ok + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + listLinkedContracts = ( + args: ListLinkedContractsArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('ListLinkedContracts'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + collections: >_data.collections, + page: _data.page + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } +} + +const createHTTPRequest = (body: object = {}, headers: object = {}, signal: AbortSignal | null = null): object => { + return { + method: 'POST', + headers: { ...headers, 'Content-Type': 'application/json' }, + body: JSON.stringify(body || {}), + signal + } +} + +const buildResponse = (res: Response): Promise => { + return res.text().then(text => { + let data + try { + data = JSON.parse(text) + } catch (error) { + let message = '' + if (error instanceof Error) { + message = error.message + } + throw WebrpcBadResponseError.new({ + status: res.status, + cause: `JSON.parse(): ${message}: response text: ${text}` + }) + } + if (!res.ok) { + const code: number = typeof data.code === 'number' ? data.code : 0 + throw (webrpcErrorByCode[code] || WebrpcError).new(data) + } + return data + }) +} + +// +// Errors +// + +export class WebrpcError extends Error { + name: string + code: number + message: string + status: number + cause?: string + + /** @deprecated Use message instead of msg. Deprecated in webrpc v0.11.0. */ + msg: string + + constructor(name: string, code: number, message: string, status: number, cause?: string) { + super(message) + this.name = name || 'WebrpcError' + this.code = typeof code === 'number' ? code : 0 + this.message = message || `endpoint error ${this.code}` + this.msg = this.message + this.status = typeof status === 'number' ? status : 0 + this.cause = cause + Object.setPrototypeOf(this, WebrpcError.prototype) + } + + static new(payload: any): WebrpcError { + return new this(payload.error, payload.code, payload.message || payload.msg, payload.status, payload.cause) + } +} + +// Webrpc errors + +export class WebrpcEndpointError extends WebrpcError { + constructor( + name: string = 'WebrpcEndpoint', + code: number = 0, + message: string = 'endpoint error', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcEndpointError.prototype) + } +} + +export class WebrpcRequestFailedError extends WebrpcError { + constructor( + name: string = 'WebrpcRequestFailed', + code: number = -1, + message: string = 'request failed', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcRequestFailedError.prototype) + } +} + +export class WebrpcBadRouteError extends WebrpcError { + constructor( + name: string = 'WebrpcBadRoute', + code: number = -2, + message: string = 'bad route', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadRouteError.prototype) + } +} + +export class WebrpcBadMethodError extends WebrpcError { + constructor( + name: string = 'WebrpcBadMethod', + code: number = -3, + message: string = 'bad method', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadMethodError.prototype) + } +} + +export class WebrpcBadRequestError extends WebrpcError { + constructor( + name: string = 'WebrpcBadRequest', + code: number = -4, + message: string = 'bad request', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadRequestError.prototype) + } +} + +export class WebrpcBadResponseError extends WebrpcError { + constructor( + name: string = 'WebrpcBadResponse', + code: number = -5, + message: string = 'bad response', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadResponseError.prototype) + } +} + +export class WebrpcServerPanicError extends WebrpcError { + constructor( + name: string = 'WebrpcServerPanic', + code: number = -6, + message: string = 'server panic', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcServerPanicError.prototype) + } +} + +export class WebrpcInternalErrorError extends WebrpcError { + constructor( + name: string = 'WebrpcInternalError', + code: number = -7, + message: string = 'internal error', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcInternalErrorError.prototype) + } +} + +export class WebrpcClientDisconnectedError extends WebrpcError { + constructor( + name: string = 'WebrpcClientDisconnected', + code: number = -8, + message: string = 'client disconnected', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcClientDisconnectedError.prototype) + } +} + +export class WebrpcStreamLostError extends WebrpcError { + constructor( + name: string = 'WebrpcStreamLost', + code: number = -9, + message: string = 'stream lost', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcStreamLostError.prototype) + } +} + +export class WebrpcStreamFinishedError extends WebrpcError { + constructor( + name: string = 'WebrpcStreamFinished', + code: number = -10, + message: string = 'stream finished', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcStreamFinishedError.prototype) + } +} + +// Schema errors + +export class UnauthorizedError extends WebrpcError { + constructor( + name: string = 'Unauthorized', + code: number = 1000, + message: string = 'Unauthorized access', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, UnauthorizedError.prototype) + } +} + +export class PermissionDeniedError extends WebrpcError { + constructor( + name: string = 'PermissionDenied', + code: number = 1001, + message: string = 'Permission denied', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, PermissionDeniedError.prototype) + } +} + +export class SessionExpiredError extends WebrpcError { + constructor( + name: string = 'SessionExpired', + code: number = 1002, + message: string = 'Session expired', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, SessionExpiredError.prototype) + } +} + +export class MethodNotFoundError extends WebrpcError { + constructor( + name: string = 'MethodNotFound', + code: number = 1003, + message: string = 'Method not found', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, MethodNotFoundError.prototype) + } +} + +export class RequestConflictError extends WebrpcError { + constructor( + name: string = 'RequestConflict', + code: number = 1004, + message: string = 'Conflict with target resource', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, RequestConflictError.prototype) + } +} + +export class FailError extends WebrpcError { + constructor( + name: string = 'Fail', + code: number = 1005, + message: string = 'Request Failed', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, FailError.prototype) + } +} + +export class GeoblockedError extends WebrpcError { + constructor( + name: string = 'Geoblocked', + code: number = 1006, + message: string = 'Geoblocked region', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, GeoblockedError.prototype) + } +} + +export class TimeoutError extends WebrpcError { + constructor( + name: string = 'Timeout', + code: number = 2000, + message: string = 'Request timed out', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, TimeoutError.prototype) + } +} + +export class InvalidArgumentError extends WebrpcError { + constructor( + name: string = 'InvalidArgument', + code: number = 2001, + message: string = 'Invalid argument', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, InvalidArgumentError.prototype) + } +} + +export class RequiredArgumentError extends WebrpcError { + constructor( + name: string = 'RequiredArgument', + code: number = 2002, + message: string = 'Required argument missing', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, RequiredArgumentError.prototype) + } +} + +export class QueryFailedError extends WebrpcError { + constructor( + name: string = 'QueryFailed', + code: number = 2003, + message: string = 'Query failed', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, QueryFailedError.prototype) + } +} + +export class ValidationFailedError extends WebrpcError { + constructor( + name: string = 'ValidationFailed', + code: number = 2004, + message: string = 'Validation failed', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, ValidationFailedError.prototype) + } +} + +export class RateLimitedError extends WebrpcError { + constructor( + name: string = 'RateLimited', + code: number = 2005, + message: string = 'Rate limited', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, RateLimitedError.prototype) + } +} + +export class NotFoundError extends WebrpcError { + constructor( + name: string = 'NotFound', + code: number = 3000, + message: string = 'Resource not found', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, NotFoundError.prototype) + } +} + +export class ProjectNotFoundError extends WebrpcError { + constructor( + name: string = 'ProjectNotFound', + code: number = 3002, + message: string = 'Project not found', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, ProjectNotFoundError.prototype) + } +} + +export class ChainNotFoundError extends WebrpcError { + constructor( + name: string = 'ChainNotFound', + code: number = 3003, + message: string = 'Chain not found', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, ChainNotFoundError.prototype) + } +} + +export class TokenDirectoryDisabledError extends WebrpcError { + constructor( + name: string = 'TokenDirectoryDisabled', + code: number = 4001, + message: string = 'Token Directory is disabled', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, TokenDirectoryDisabledError.prototype) + } +} + +export enum errors { + WebrpcEndpoint = 'WebrpcEndpoint', + WebrpcRequestFailed = 'WebrpcRequestFailed', + WebrpcBadRoute = 'WebrpcBadRoute', + WebrpcBadMethod = 'WebrpcBadMethod', + WebrpcBadRequest = 'WebrpcBadRequest', + WebrpcBadResponse = 'WebrpcBadResponse', + WebrpcServerPanic = 'WebrpcServerPanic', + WebrpcInternalError = 'WebrpcInternalError', + WebrpcClientDisconnected = 'WebrpcClientDisconnected', + WebrpcStreamLost = 'WebrpcStreamLost', + WebrpcStreamFinished = 'WebrpcStreamFinished', + Unauthorized = 'Unauthorized', + PermissionDenied = 'PermissionDenied', + SessionExpired = 'SessionExpired', + MethodNotFound = 'MethodNotFound', + RequestConflict = 'RequestConflict', + Fail = 'Fail', + Geoblocked = 'Geoblocked', + Timeout = 'Timeout', + InvalidArgument = 'InvalidArgument', + RequiredArgument = 'RequiredArgument', + QueryFailed = 'QueryFailed', + ValidationFailed = 'ValidationFailed', + RateLimited = 'RateLimited', + NotFound = 'NotFound', + ProjectNotFound = 'ProjectNotFound', + ChainNotFound = 'ChainNotFound', + TokenDirectoryDisabled = 'TokenDirectoryDisabled' +} + +const webrpcErrorByCode: { [code: number]: any } = { + [0]: WebrpcEndpointError, + [-1]: WebrpcRequestFailedError, + [-2]: WebrpcBadRouteError, + [-3]: WebrpcBadMethodError, + [-4]: WebrpcBadRequestError, + [-5]: WebrpcBadResponseError, + [-6]: WebrpcServerPanicError, + [-7]: WebrpcInternalErrorError, + [-8]: WebrpcClientDisconnectedError, + [-9]: WebrpcStreamLostError, + [-10]: WebrpcStreamFinishedError, + [1000]: UnauthorizedError, + [1001]: PermissionDeniedError, + [1002]: SessionExpiredError, + [1003]: MethodNotFoundError, + [1004]: RequestConflictError, + [1005]: FailError, + [1006]: GeoblockedError, + [2000]: TimeoutError, + [2001]: InvalidArgumentError, + [2002]: RequiredArgumentError, + [2003]: QueryFailedError, + [2004]: ValidationFailedError, + [2005]: RateLimitedError, + [3000]: NotFoundError, + [3002]: ProjectNotFoundError, + [3003]: ChainNotFoundError, + [4001]: TokenDirectoryDisabledError +} + +export type Fetch = (input: RequestInfo, init?: RequestInit) => Promise diff --git a/packages/migration/CHANGELOG.md b/packages/migration/CHANGELOG.md new file mode 100644 index 0000000000..ad3279aba2 --- /dev/null +++ b/packages/migration/CHANGELOG.md @@ -0,0 +1,1245 @@ +# @0xsequence/migration + +## 2.0.0 + +### Major Changes + +- changeset + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@2.0.0 + - @0xsequence/core@2.0.0 + - @0xsequence/wallet@2.0.0 + +## 1.10.14 + +### Patch Changes + +- network: add borne-testnet to allNetworks +- Updated dependencies + - @0xsequence/abi@1.10.14 + - @0xsequence/core@1.10.14 + - @0xsequence/wallet@1.10.14 + +## 1.10.13 + +### Patch Changes + +- network: add borne testnet +- Updated dependencies + - @0xsequence/abi@1.10.13 + - @0xsequence/core@1.10.13 + - @0xsequence/wallet@1.10.13 + +## 1.10.12 + +### Patch Changes + +- api: update bindings +- global/window -> globalThis +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.10.12 + - @0xsequence/core@1.10.12 + - @0xsequence/wallet@1.10.12 + +## 1.10.11 + +### Patch Changes + +- waas: updated intent.gen without webrpc types, errors exported from authenticator.gen +- Updated dependencies + - @0xsequence/abi@1.10.11 + - @0xsequence/core@1.10.11 + - @0xsequence/wallet@1.10.11 + +## 1.10.10 + +### Patch Changes + +- metadata: update bindings with new contract collections api +- Updated dependencies + - @0xsequence/abi@1.10.10 + - @0xsequence/core@1.10.10 + - @0xsequence/wallet@1.10.10 + +## 1.10.9 + +### Patch Changes + +- waas minor update +- Updated dependencies + - @0xsequence/abi@1.10.9 + - @0xsequence/core@1.10.9 + - @0xsequence/wallet@1.10.9 + +## 1.10.8 + +### Patch Changes + +- update metadata bindings +- Updated dependencies + - @0xsequence/abi@1.10.8 + - @0xsequence/core@1.10.8 + - @0xsequence/wallet@1.10.8 + +## 1.10.7 + +### Patch Changes + +- minor fixes to waas client +- Updated dependencies + - @0xsequence/abi@1.10.7 + - @0xsequence/core@1.10.7 + - @0xsequence/wallet@1.10.7 + +## 1.10.6 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/abi@1.10.6 + - @0xsequence/core@1.10.6 + - @0xsequence/wallet@1.10.6 + +## 1.10.5 + +### Patch Changes + +- network: ape-chain-testnet -> apechain-testnet +- Updated dependencies + - @0xsequence/abi@1.10.5 + - @0xsequence/core@1.10.5 + - @0xsequence/wallet@1.10.5 + +## 1.10.4 + +### Patch Changes + +- network: add b3-sepolia, ape-chain-testnet, blast, blast-sepolia +- Updated dependencies + - @0xsequence/abi@1.10.4 + - @0xsequence/core@1.10.4 + - @0xsequence/wallet@1.10.4 + +## 1.10.3 + +### Patch Changes + +- typing fix +- Updated dependencies + - @0xsequence/abi@1.10.3 + - @0xsequence/core@1.10.3 + - @0xsequence/wallet@1.10.3 + +## 1.10.2 + +### Patch Changes + +- - waas: add getIdToken method + - indexer: update api client +- Updated dependencies + - @0xsequence/abi@1.10.2 + - @0xsequence/core@1.10.2 + - @0xsequence/wallet@1.10.2 + +## 1.10.1 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/abi@1.10.1 + - @0xsequence/core@1.10.1 + - @0xsequence/wallet@1.10.1 + +## 1.10.0 + +### Minor Changes + +- waas release v1.3.0 + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.10.0 + - @0xsequence/core@1.10.0 + - @0xsequence/wallet@1.10.0 + +## 1.9.37 + +### Patch Changes + +- network: adds nativeToken data to NetworkMetadata constants +- Updated dependencies + - @0xsequence/abi@1.9.37 + - @0xsequence/core@1.9.37 + - @0xsequence/wallet@1.9.37 + +## 1.9.36 + +### Patch Changes + +- guard: export client +- Updated dependencies + - @0xsequence/abi@1.9.36 + - @0xsequence/core@1.9.36 + - @0xsequence/wallet@1.9.36 + +## 1.9.35 + +### Patch Changes + +- guard: update bindings +- Updated dependencies + - @0xsequence/abi@1.9.35 + - @0xsequence/core@1.9.35 + - @0xsequence/wallet@1.9.35 + +## 1.9.34 + +### Patch Changes + +- waas: always use lowercase email +- Updated dependencies + - @0xsequence/abi@1.9.34 + - @0xsequence/core@1.9.34 + - @0xsequence/wallet@1.9.34 + +## 1.9.33 + +### Patch Changes + +- waas: umd build +- Updated dependencies + - @0xsequence/abi@1.9.33 + - @0xsequence/core@1.9.33 + - @0xsequence/wallet@1.9.33 + +## 1.9.32 + +### Patch Changes + +- indexer: update bindings +- Updated dependencies + - @0xsequence/abi@1.9.32 + - @0xsequence/core@1.9.32 + - @0xsequence/wallet@1.9.32 + +## 1.9.31 + +### Patch Changes + +- metadata: token directory changes +- Updated dependencies + - @0xsequence/abi@1.9.31 + - @0xsequence/core@1.9.31 + - @0xsequence/wallet@1.9.31 + +## 1.9.30 + +### Patch Changes + +- update +- Updated dependencies + - @0xsequence/abi@1.9.30 + - @0xsequence/core@1.9.30 + - @0xsequence/wallet@1.9.30 + +## 1.9.29 + +### Patch Changes + +- disable gnosis chain +- Updated dependencies + - @0xsequence/abi@1.9.29 + - @0xsequence/core@1.9.29 + - @0xsequence/wallet@1.9.29 + +## 1.9.28 + +### Patch Changes + +- add utils/merkletree +- Updated dependencies + - @0xsequence/abi@1.9.28 + - @0xsequence/core@1.9.28 + - @0xsequence/wallet@1.9.28 + +## 1.9.27 + +### Patch Changes + +- network: optimistic -> optimism +- waas: remove defaults +- api, sessions: update bindings +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.9.27 + - @0xsequence/core@1.9.27 + - @0xsequence/wallet@1.9.27 + +## 1.9.26 + +### Patch Changes + +- - add backend interfaces for pluggable interfaces + - introduce @0xsequence/react-native + - update pnpm to lockfile v9 +- Updated dependencies + - @0xsequence/abi@1.9.26 + - @0xsequence/core@1.9.26 + - @0xsequence/wallet@1.9.26 + +## 1.9.25 + +### Patch Changes + +- update webrpc clients with new error types +- Updated dependencies + - @0xsequence/abi@1.9.25 + - @0xsequence/core@1.9.25 + - @0xsequence/wallet@1.9.25 + +## 1.9.24 + +### Patch Changes + +- waas: add memoryStore backend to localStore +- Updated dependencies + - @0xsequence/abi@1.9.24 + - @0xsequence/core@1.9.24 + - @0xsequence/wallet@1.9.24 + +## 1.9.23 + +### Patch Changes + +- update api client bindings +- Updated dependencies + - @0xsequence/abi@1.9.23 + - @0xsequence/core@1.9.23 + - @0xsequence/wallet@1.9.23 + +## 1.9.22 + +### Patch Changes + +- update metadata client bindings +- Updated dependencies + - @0xsequence/abi@1.9.22 + - @0xsequence/core@1.9.22 + - @0xsequence/wallet@1.9.22 + +## 1.9.21 + +### Patch Changes + +- api client bindings +- Updated dependencies + - @0xsequence/abi@1.9.21 + - @0xsequence/core@1.9.21 + - @0xsequence/wallet@1.9.21 + +## 1.9.20 + +### Patch Changes + +- api client bindings update +- Updated dependencies + - @0xsequence/abi@1.9.20 + - @0xsequence/core@1.9.20 + - @0xsequence/wallet@1.9.20 + +## 1.9.19 + +### Patch Changes + +- waas update +- Updated dependencies + - @0xsequence/abi@1.9.19 + - @0xsequence/core@1.9.19 + - @0xsequence/wallet@1.9.19 + +## 1.9.18 + +### Patch Changes + +- provider: prohibit dangerous functions +- Updated dependencies + - @0xsequence/abi@1.9.18 + - @0xsequence/core@1.9.18 + - @0xsequence/wallet@1.9.18 + +## 1.9.17 + +### Patch Changes + +- network: add xr-sepolia +- Updated dependencies + - @0xsequence/abi@1.9.17 + - @0xsequence/core@1.9.17 + - @0xsequence/wallet@1.9.17 + +## 1.9.16 + +### Patch Changes + +- waas: sequence.feeOptions +- Updated dependencies + - @0xsequence/abi@1.9.16 + - @0xsequence/core@1.9.16 + - @0xsequence/wallet@1.9.16 + +## 1.9.15 + +### Patch Changes + +- metadata: collection external_link field name fix +- Updated dependencies + - @0xsequence/abi@1.9.15 + - @0xsequence/core@1.9.15 + - @0xsequence/wallet@1.9.15 + +## 1.9.14 + +### Patch Changes + +- network: astar-zkatana -> astar-zkyoto +- network: deprecate polygon mumbai network +- network: add xai and polygon amoy +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.9.14 + - @0xsequence/core@1.9.14 + - @0xsequence/wallet@1.9.14 + +## 1.9.13 + +### Patch Changes + +- waas: fix @0xsequence/network dependency +- Updated dependencies + - @0xsequence/abi@1.9.13 + - @0xsequence/core@1.9.13 + - @0xsequence/wallet@1.9.13 + +## 1.9.12 + +### Patch Changes + +- indexer: update rpc bindings +- provider: signMessage: Serialize the BytesLike or string message into hexstring before sending +- waas: SessionAuthProof +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.9.12 + - @0xsequence/core@1.9.12 + - @0xsequence/wallet@1.9.12 + +## 1.9.11 + +### Patch Changes + +- metdata, update rpc bindings +- Updated dependencies + - @0xsequence/abi@1.9.11 + - @0xsequence/core@1.9.11 + - @0xsequence/wallet@1.9.11 + +## 1.9.10 + +### Patch Changes + +- update metadata rpc bindings +- Updated dependencies + - @0xsequence/abi@1.9.10 + - @0xsequence/core@1.9.10 + - @0xsequence/wallet@1.9.10 + +## 1.9.9 + +### Patch Changes + +- metadata, add SequenceCollections rpc client +- Updated dependencies + - @0xsequence/abi@1.9.9 + - @0xsequence/core@1.9.9 + - @0xsequence/wallet@1.9.9 + +## 1.9.8 + +### Patch Changes + +- waas client update +- Updated dependencies + - @0xsequence/abi@1.9.8 + - @0xsequence/core@1.9.8 + - @0xsequence/wallet@1.9.8 + +## 1.9.7 + +### Patch Changes + +- update rpc client bindings for api, metadata and relayer +- Updated dependencies + - @0xsequence/abi@1.9.7 + - @0xsequence/core@1.9.7 + - @0xsequence/wallet@1.9.7 + +## 1.9.6 + +### Patch Changes + +- waas package update +- Updated dependencies + - @0xsequence/abi@1.9.6 + - @0xsequence/core@1.9.6 + - @0xsequence/wallet@1.9.6 + +## 1.9.5 + +### Patch Changes + +- RpcRelayer prioritize project access key +- Updated dependencies + - @0xsequence/abi@1.9.5 + - @0xsequence/core@1.9.5 + - @0xsequence/wallet@1.9.5 + +## 1.9.4 + +### Patch Changes + +- waas: fix network dependency +- Updated dependencies + - @0xsequence/abi@1.9.4 + - @0xsequence/core@1.9.4 + - @0xsequence/wallet@1.9.4 + +## 1.9.3 + +### Patch Changes + +- provider: don't append access key to RPC url if user has already provided it +- Updated dependencies + - @0xsequence/abi@1.9.3 + - @0xsequence/core@1.9.3 + - @0xsequence/wallet@1.9.3 + +## 1.9.2 + +### Patch Changes + +- network: add xai-sepolia +- Updated dependencies + - @0xsequence/abi@1.9.2 + - @0xsequence/core@1.9.2 + - @0xsequence/wallet@1.9.2 + +## 1.9.1 + +### Patch Changes + +- analytics fix +- Updated dependencies + - @0xsequence/abi@1.9.1 + - @0xsequence/core@1.9.1 + - @0xsequence/wallet@1.9.1 + +## 1.9.0 + +### Minor Changes + +- waas release + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.9.0 + - @0xsequence/core@1.9.0 + - @0xsequence/wallet@1.9.0 + +## 1.8.8 + +### Patch Changes + +- update metadata bindings +- Updated dependencies + - @0xsequence/abi@1.8.8 + - @0xsequence/core@1.8.8 + - @0xsequence/wallet@1.8.8 + +## 1.8.7 + +### Patch Changes + +- provider: update databeat to 0.9.1 +- Updated dependencies + - @0xsequence/abi@1.8.7 + - @0xsequence/core@1.8.7 + - @0xsequence/wallet@1.8.7 + +## 1.8.6 + +### Patch Changes + +- guard: SignedOwnershipProof +- Updated dependencies + - @0xsequence/abi@1.8.6 + - @0xsequence/core@1.8.6 + - @0xsequence/wallet@1.8.6 + +## 1.8.5 + +### Patch Changes + +- guard: signOwnershipProof and isSignedOwnershipProof +- Updated dependencies + - @0xsequence/abi@1.8.5 + - @0xsequence/core@1.8.5 + - @0xsequence/wallet@1.8.5 + +## 1.8.4 + +### Patch Changes + +- network: add homeverse to networks list +- Updated dependencies + - @0xsequence/abi@1.8.4 + - @0xsequence/core@1.8.4 + - @0xsequence/wallet@1.8.4 + +## 1.8.3 + +### Patch Changes + +- api: introduce basic linked wallet support +- Updated dependencies + - @0xsequence/abi@1.8.3 + - @0xsequence/core@1.8.3 + - @0xsequence/wallet@1.8.3 + +## 1.8.2 + +### Patch Changes + +- provider: don't initialize analytics unless explicitly requested +- Updated dependencies + - @0xsequence/abi@1.8.2 + - @0xsequence/core@1.8.2 + - @0xsequence/wallet@1.8.2 + +## 1.8.1 + +### Patch Changes + +- update to analytics provider +- Updated dependencies + - @0xsequence/abi@1.8.1 + - @0xsequence/core@1.8.1 + - @0xsequence/wallet@1.8.1 + +## 1.8.0 + +### Minor Changes + +- provider: project analytics + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.8.0 + - @0xsequence/core@1.8.0 + - @0xsequence/wallet@1.8.0 + +## 1.7.2 + +### Patch Changes + +- 0xsequence: ChainId should not be exported as a type +- account, wallet: fix nonce selection +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.7.2 + - @0xsequence/core@1.7.2 + - @0xsequence/wallet@1.7.2 + +## 1.7.1 + +### Patch Changes + +- network: add missing avalanche logoURI +- Updated dependencies + - @0xsequence/abi@1.7.1 + - @0xsequence/core@1.7.1 + - @0xsequence/wallet@1.7.1 + +## 1.7.0 + +### Minor Changes + +- provider: projectAccessKey is now required + +### Patch Changes + +- network: add NetworkMetadata.logoURI property for all networks +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.7.0 + - @0xsequence/core@1.7.0 + - @0xsequence/wallet@1.7.0 + +## 1.6.3 + +### Patch Changes + +- network list update +- Updated dependencies + - @0xsequence/abi@1.6.3 + - @0xsequence/core@1.6.3 + - @0xsequence/wallet@1.6.3 + +## 1.6.2 + +### Patch Changes + +- auth: projectAccessKey option +- wallet: use 12 bytes for random space +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.6.2 + - @0xsequence/core@1.6.2 + - @0xsequence/wallet@1.6.2 + +## 1.6.1 + +### Patch Changes + +- core: add simple config from subdigest support +- core: fix encode tree with subdigest +- account: implement buildOnChainSignature on Account +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.6.1 + - @0xsequence/core@1.6.1 + - @0xsequence/wallet@1.6.1 + +## 1.6.0 + +### Minor Changes + +- account, wallet: parallel transactions by default + +### Patch Changes + +- provider: emit disconnect on sign out +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.6.0 + - @0xsequence/core@1.6.0 + - @0xsequence/wallet@1.6.0 + +## 1.5.0 + +### Minor Changes + +- signhub: add 'signing' signer status + +### Patch Changes + +- auth: Session.open: onAccountAddress callback +- account: allow empty transaction bundles +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.5.0 + - @0xsequence/core@1.5.0 + - @0xsequence/wallet@1.5.0 + +## 1.4.9 + +### Patch Changes + +- rename SequenceMetadataClient to SequenceMetadata +- Updated dependencies + - @0xsequence/abi@1.4.9 + - @0xsequence/core@1.4.9 + - @0xsequence/wallet@1.4.9 + +## 1.4.8 + +### Patch Changes + +- account: Account.getSigners +- Updated dependencies + - @0xsequence/abi@1.4.8 + - @0xsequence/core@1.4.8 + - @0xsequence/wallet@1.4.8 + +## 1.4.7 + +### Patch Changes + +- update indexer client bindings +- Updated dependencies + - @0xsequence/abi@1.4.7 + - @0xsequence/core@1.4.7 + - @0xsequence/wallet@1.4.7 + +## 1.4.6 + +### Patch Changes + +- - add sepolia networks, mark goerli as deprecated + - update indexer client bindings +- Updated dependencies + - @0xsequence/abi@1.4.6 + - @0xsequence/core@1.4.6 + - @0xsequence/wallet@1.4.6 + +## 1.4.5 + +### Patch Changes + +- indexer/metadata: update client bindings +- auth: selectWallet with new address +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.4.5 + - @0xsequence/core@1.4.5 + - @0xsequence/wallet@1.4.5 + +## 1.4.4 + +### Patch Changes + +- indexer: update bindings +- auth: handle jwt expiry +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.4.4 + - @0xsequence/core@1.4.4 + - @0xsequence/wallet@1.4.4 + +## 1.4.3 + +### Patch Changes + +- guard: return active status from GuardSigner.getAuthMethods +- Updated dependencies + - @0xsequence/abi@1.4.3 + - @0xsequence/core@1.4.3 + - @0xsequence/wallet@1.4.3 + +## 1.4.2 + +### Patch Changes + +- guard: update bindings +- Updated dependencies + - @0xsequence/abi@1.4.2 + - @0xsequence/core@1.4.2 + - @0xsequence/wallet@1.4.2 + +## 1.4.1 + +### Patch Changes + +- network: remove unused networks +- signhub: orchestrator interface +- guard: auth methods interface +- guard: update bindings for pin and totp +- guard: no more retry logic +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.4.1 + - @0xsequence/core@1.4.1 + - @0xsequence/wallet@1.4.1 + +## 1.4.0 + +### Minor Changes + +- project access key support + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.4.0 + - @0xsequence/core@1.4.0 + - @0xsequence/wallet@1.4.0 + +## 1.3.0 + +### Minor Changes + +- signhub: account children + +### Patch Changes + +- guard: do not throw when building deploy transaction +- network: snowtrace.io -> subnets.avax.network/c-chain +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.3.0 + - @0xsequence/core@1.3.0 + - @0xsequence/wallet@1.3.0 + +## 1.2.9 + +### Patch Changes + +- account: AccountSigner.sendTransaction simulateForFeeOptions +- relayer: update bindings +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.2.9 + - @0xsequence/core@1.2.9 + - @0xsequence/wallet@1.2.9 + +## 1.2.8 + +### Patch Changes + +- rename X-Sequence-Token-Key header to X-Access-Key +- Updated dependencies + - @0xsequence/abi@1.2.8 + - @0xsequence/core@1.2.8 + - @0xsequence/wallet@1.2.8 + +## 1.2.7 + +### Patch Changes + +- add x-sequence-token-key to clients +- Updated dependencies + - @0xsequence/abi@1.2.7 + - @0xsequence/core@1.2.7 + - @0xsequence/wallet@1.2.7 + +## 1.2.6 + +### Patch Changes + +- Fix bind multicall provider +- Updated dependencies + - @0xsequence/abi@1.2.6 + - @0xsequence/core@1.2.6 + - @0xsequence/wallet@1.2.6 + +## 1.2.5 + +### Patch Changes + +- Multicall default configuration fixes +- Updated dependencies + - @0xsequence/abi@1.2.5 + - @0xsequence/core@1.2.5 + - @0xsequence/wallet@1.2.5 + +## 1.2.4 + +### Patch Changes + +- provider: Adding missing payment provider types to PaymentProviderOption +- provider: WalletRequestHandler.notifyChainChanged +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.2.4 + - @0xsequence/core@1.2.4 + - @0xsequence/wallet@1.2.4 + +## 1.2.3 + +### Patch Changes + +- auth, provider: connect to accept optional authorizeNonce +- Updated dependencies + - @0xsequence/abi@1.2.3 + - @0xsequence/core@1.2.3 + - @0xsequence/wallet@1.2.3 + +## 1.2.2 + +### Patch Changes + +- provider: allow createContract calls +- core: check for explicit zero address in contract deployments +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.2.2 + - @0xsequence/core@1.2.2 + - @0xsequence/wallet@1.2.2 + +## 1.2.1 + +### Patch Changes + +- auth: use sequence api chain id as reference chain id if available +- Updated dependencies + - @0xsequence/abi@1.2.1 + - @0xsequence/core@1.2.1 + - @0xsequence/wallet@1.2.1 + +## 1.2.0 + +### Minor Changes + +- split services from session, better local support + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.2.0 + - @0xsequence/core@1.2.0 + - @0xsequence/wallet@1.2.0 + +## 1.1.15 + +### Patch Changes + +- guard: remove error filtering +- Updated dependencies + - @0xsequence/abi@1.1.15 + - @0xsequence/core@1.1.15 + - @0xsequence/wallet@1.1.15 + +## 1.1.14 + +### Patch Changes + +- guard: add GuardSigner.onError +- Updated dependencies + - @0xsequence/abi@1.1.14 + - @0xsequence/core@1.1.14 + - @0xsequence/wallet@1.1.14 + +## 1.1.13 + +### Patch Changes + +- provider: pass client version with connect options +- provider: removing large from BannerSize +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.1.13 + - @0xsequence/core@1.1.13 + - @0xsequence/wallet@1.1.13 + +## 1.1.12 + +### Patch Changes + +- provider: adding bannerSize to ConnectOptions +- Updated dependencies + - @0xsequence/abi@1.1.12 + - @0xsequence/core@1.1.12 + - @0xsequence/wallet@1.1.12 + +## 1.1.11 + +### Patch Changes + +- add homeverse configs +- Updated dependencies + - @0xsequence/abi@1.1.11 + - @0xsequence/core@1.1.11 + - @0xsequence/wallet@1.1.11 + +## 1.1.10 + +### Patch Changes + +- handle default EIP6492 on send +- Updated dependencies + - @0xsequence/abi@1.1.10 + - @0xsequence/core@1.1.10 + - @0xsequence/wallet@1.1.10 + +## 1.1.9 + +### Patch Changes + +- Custom default EIP6492 on client +- Updated dependencies + - @0xsequence/abi@1.1.9 + - @0xsequence/core@1.1.9 + - @0xsequence/wallet@1.1.9 + +## 1.1.8 + +### Patch Changes + +- metadata: searchMetadata: add types filter +- Updated dependencies + - @0xsequence/abi@1.1.8 + - @0xsequence/core@1.1.8 + - @0xsequence/wallet@1.1.8 + +## 1.1.7 + +### Patch Changes + +- adding signInWith connect settings option to allow dapps to automatically login their users with a certain provider optimizing the normal authentication flow +- Updated dependencies + - @0xsequence/abi@1.1.7 + - @0xsequence/core@1.1.7 + - @0xsequence/wallet@1.1.7 + +## 1.1.6 + +### Patch Changes + +- metadata: searchMetadata: add chainID and excludeTokenMetadata filters +- Updated dependencies + - @0xsequence/abi@1.1.6 + - @0xsequence/core@1.1.6 + - @0xsequence/wallet@1.1.6 + +## 1.1.5 + +### Patch Changes + +- account: re-compute meta-transaction id for wallet deployment transactions +- Updated dependencies + - @0xsequence/abi@1.1.5 + - @0xsequence/core@1.1.5 + - @0xsequence/wallet@1.1.5 + +## 1.1.4 + +### Patch Changes + +- network: rename base-mainnet to base +- provider: override isDefaultChain with ConnectOptions.networkId if provided +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.1.4 + - @0xsequence/core@1.1.4 + - @0xsequence/wallet@1.1.4 + +## 1.1.3 + +### Patch Changes + +- provider: use network id from transport session +- provider: sign authorization using ConnectOptions.networkId if provided +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.1.3 + - @0xsequence/core@1.1.3 + - @0xsequence/wallet@1.1.3 + +## 1.1.2 + +### Patch Changes + +- provider: jsonrpc chain id fixes +- Updated dependencies + - @0xsequence/abi@1.1.2 + - @0xsequence/core@1.1.2 + - @0xsequence/wallet@1.1.2 + +## 1.1.1 + +### Patch Changes + +- network: add base mainnet and sepolia +- provider: reject toxic transaction requests +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.1.1 + - @0xsequence/core@1.1.1 + - @0xsequence/wallet@1.1.1 + +## 1.1.0 + +### Minor Changes + +- Refactor dapp facing provider + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.1.0 + - @0xsequence/core@1.1.0 + - @0xsequence/wallet@1.1.0 + +## 1.0.5 + +### Patch Changes + +- network: export network constants +- guard: use the correct global for fetch +- network: nova-explorer.arbitrum.io -> nova.arbiscan.io +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.0.5 + - @0xsequence/core@1.0.5 + - @0xsequence/wallet@1.0.5 + +## 1.0.4 + +### Patch Changes + +- provider: accept name or number for networkId +- Updated dependencies + - @0xsequence/abi@1.0.4 + - @0xsequence/core@1.0.4 + - @0xsequence/wallet@1.0.4 + +## 1.0.3 + +### Patch Changes + +- Simpler isValidSignature helpers +- Updated dependencies + - @0xsequence/abi@1.0.3 + - @0xsequence/core@1.0.3 + - @0xsequence/wallet@1.0.3 + +## 1.0.2 + +### Patch Changes + +- add extra signature validation utils methods +- Updated dependencies + - @0xsequence/abi@1.0.2 + - @0xsequence/core@1.0.2 + - @0xsequence/wallet@1.0.2 + +## 1.0.1 + +### Patch Changes + +- add homeverse testnet +- Updated dependencies + - @0xsequence/abi@1.0.1 + - @0xsequence/core@1.0.1 + - @0xsequence/wallet@1.0.1 + +## 1.0.0 + +### Major Changes + +- https://sequence.xyz/blog/sequence-wallet-light-state-sync-full-merkle-wallets + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.0.0 + - @0xsequence/core@1.0.0 + - @0xsequence/wallet@1.0.0 diff --git a/packages/migration/package.json b/packages/migration/package.json new file mode 100644 index 0000000000..1aefbd7ca5 --- /dev/null +++ b/packages/migration/package.json @@ -0,0 +1,28 @@ +{ + "name": "@0xsequence/migration", + "version": "2.0.0", + "description": "tools for migrating sequence wallets to new versions", + "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/migration", + "source": "src/index.ts", + "main": "dist/0xsequence-migration.cjs.js", + "module": "dist/0xsequence-migration.esm.js", + "author": "Horizon Blockchain Games", + "license": "Apache-2.0", + "scripts": { + "test": "echo 'TODO: Migration tests'" + }, + "dependencies": { + "@0xsequence/abi": "workspace:*", + "@0xsequence/core": "workspace:*", + "@0xsequence/wallet": "workspace:*", + "ethers": "^5.5.2" + }, + "devDependencies": { + "@istanbuljs/nyc-config-typescript": "^1.0.2", + "nyc": "^15.1.0" + }, + "files": [ + "src", + "dist" + ] +} diff --git a/packages/migration/src/defaults.ts b/packages/migration/src/defaults.ts new file mode 100644 index 0000000000..ad2078e239 --- /dev/null +++ b/packages/migration/src/defaults.ts @@ -0,0 +1,6 @@ +import { v1v2 } from './migrations' +import { Migrations } from './migrator' + +export const DefaultMigrations: Migrations = { + 1: v1v2 +} diff --git a/packages/migration/src/index.ts b/packages/migration/src/index.ts new file mode 100644 index 0000000000..6f0c97c5fb --- /dev/null +++ b/packages/migration/src/index.ts @@ -0,0 +1,4 @@ +export * as version from './version' +export * as migration from './migrations' +export * as migrator from './migrator' +export * as defaults from './defaults' diff --git a/packages/migration/src/migrations/index.ts b/packages/migration/src/migrations/index.ts new file mode 100644 index 0000000000..97b91e6012 --- /dev/null +++ b/packages/migration/src/migrations/index.ts @@ -0,0 +1,25 @@ +import { commons } from '@0xsequence/core' +import { UnsignedMigration } from '../migrator' +import { Migration_v1v2 } from './migration_01_02' + +// = uint160(keccak256("org.sequence.sdk.migration.space.nonce")) +export const MIGRATION_NONCE_SPACE = '0xa04263acf755e8bd19c0d7e20eea39a9ff3729eb' + +export interface Migration

{ + version: number + + buildTransaction: (address: string, contexts: commons.context.VersionedContext, newConfig: P | C) => UnsignedMigration + + decodeTransaction: ( + tx: commons.transaction.TransactionBundle, + contexts: commons.context.VersionedContext + ) => { + address: string + newImageHash: string + } + + configCoder: commons.config.ConfigCoder + signatureCoder: commons.signature.SignatureCoder, commons.signature.UnrecoveredSignature> +} + +export const v1v2 = new Migration_v1v2() diff --git a/packages/migration/src/migrations/migration_01_02.ts b/packages/migration/src/migrations/migration_01_02.ts new file mode 100644 index 0000000000..cbd7a07016 --- /dev/null +++ b/packages/migration/src/migrations/migration_01_02.ts @@ -0,0 +1,113 @@ +import { commons, v1, v2 } from '@0xsequence/core' +import { ethers } from 'ethers' + +import { Migration, MIGRATION_NONCE_SPACE } from '.' +import { walletContracts } from '@0xsequence/abi' +import { UnsignedMigration } from '../migrator' + +export class Migration_v1v2 implements Migration { + version = 2 + + configCoder = v2.config.ConfigCoder + signatureCoder = v2.signature.SignatureCoder + + buildTransaction( + address: string, + contexts: commons.context.VersionedContext, + newConfig: v1.config.WalletConfig | v2.config.WalletConfig + ): UnsignedMigration { + // If new config is not v2, then we need to convert it to v2 + if (!v2.config.ConfigCoder.isWalletConfig(newConfig)) { + const v2Config = v2.config.toWalletConfig({ + threshold: newConfig.threshold, + members: newConfig.signers, + checkpoint: 0 + }) + + return this.buildTransaction(address, contexts, v2Config) + } + + const context = contexts[2] + const contract = new ethers.utils.Interface(walletContracts.mainModule.abi) + + // WARNING: v1 wallets CAN NOT use v2 configurations so we ALWAYS need to update + // both the implementation and the configuration at the same time + + const updateBundle = v2.config.ConfigCoder.update.buildTransaction(address, newConfig, context, 'first') + + const tx = { + entrypoint: address, + nonce: commons.transaction.encodeNonce(MIGRATION_NONCE_SPACE, 0), + transactions: [ + { + to: address, + value: 0, + gasLimit: 0, + revertOnError: true, + delegateCall: false, + data: contract.encodeFunctionData(contract.getFunction('updateImplementation'), [context.mainModuleUpgradable]) + }, + ...updateBundle.transactions + ] + } + + return { + tx, + fromVersion: this.version - 1, + toVersion: this.version, + toConfig: newConfig + } + } + + decodeTransaction( + tx: commons.transaction.TransactionBundle, + contexts: commons.context.VersionedContext + ): { + address: string + newImageHash: string + } { + const address = tx.entrypoint + + if (tx.transactions.length < 2) { + throw new Error('Invalid transaction bundle size') + } + + if (!tx.nonce || !commons.transaction.encodeNonce(MIGRATION_NONCE_SPACE, 0).eq(tx.nonce)) { + throw new Error('Invalid transaction bundle nonce') + } + + if ( + tx.transactions[0].to !== address || + tx.transactions[1].to !== address || + tx.transactions[0].delegateCall || + tx.transactions[1].delegateCall || + !tx.transactions[0].revertOnError || + !tx.transactions[1].revertOnError || + (tx.transactions[0].value && !ethers.constants.Zero.eq(tx.transactions[0].value)) || + (tx.transactions[1].value && !ethers.constants.Zero.eq(tx.transactions[1].value)) || + (tx.transactions[0].gasLimit && !ethers.constants.Zero.eq(tx.transactions[0].gasLimit)) || + (tx.transactions[1].gasLimit && !ethers.constants.Zero.eq(tx.transactions[1].gasLimit)) + ) { + throw new Error('Invalid transaction bundle format') + } + + const context = contexts[2] + const contract = new ethers.utils.Interface(walletContracts.mainModule.abi) + + const data1 = ethers.utils.hexlify(tx.transactions[0].data || []) + const expectData1 = ethers.utils.hexlify( + contract.encodeFunctionData(contract.getFunction('updateImplementation'), [context.mainModuleUpgradable]) + ) + + if (data1 !== expectData1) { + throw new Error('Invalid new implementation on transaction') + } + + const decoded2 = v2.config.ConfigCoder.update.decodeTransaction({ entrypoint: address, transactions: [tx.transactions[1]] }) + if (decoded2.address !== address) { + throw new Error('Invalid transaction bundle address') + } + + return decoded2 + } +} diff --git a/packages/migration/src/migrator.ts b/packages/migration/src/migrator.ts new file mode 100644 index 0000000000..379197f255 --- /dev/null +++ b/packages/migration/src/migrator.ts @@ -0,0 +1,123 @@ +import { commons } from '@0xsequence/core' +import { Wallet } from '@0xsequence/wallet' +import { ethers } from 'ethers' + +import { Migration } from './migrations' + +export type UnsignedMigration = { + tx: commons.transaction.TransactionBundle + fromVersion: number + toVersion: number + toConfig: commons.config.Config +} + +export type SignedMigration = Omit & { + tx: commons.transaction.SignedTransactionBundle +} + +export interface PresignedMigrationTracker { + getMigration( + address: string, + fromImageHash: string, + fromVersion: number, + chainId: ethers.BigNumberish + ): Promise + + saveMigration(address: string, signed: SignedMigration, contexts: commons.context.VersionedContext): Promise +} + +export type Migrations = { [version: number]: Migration } + +function validateMigrations(migrations: Migrations) { + for (const [version, migration] of Object.entries(migrations)) { + if (version !== String(migration.version - 1)) { + throw new Error(`Migration with key ${version} has version ${migration.version}, expected version to be key + 1`) + } + } +} + +export class Migrator { + constructor( + public readonly tracker: PresignedMigrationTracker, + public readonly migrations: Migrations, + public readonly contexts: commons.context.VersionedContext + ) { + validateMigrations(migrations) + } + + lastMigration(): Migration { + let last: Migration | undefined + for (const migration of Object.values(this.migrations)) { + if (last === undefined || migration.version > last.version) { + last = migration + } + } + if (last === undefined) { + throw new Error('No migrations') + } + return last + } + + async getAllMigratePresignedTransaction(args: { + address: string + fromImageHash: string + fromVersion: number + chainId: ethers.BigNumberish + }): Promise<{ + lastVersion: number + lastImageHash: string + signedMigrations: SignedMigration[] + missing: boolean + }> { + const { address, fromImageHash, fromVersion, chainId } = args + + let fih = fromImageHash + let fversion = fromVersion + + const versions = Object.values(this.contexts) + const migs: SignedMigration[] = [] + + for (let i = 1; i < versions.length; i++) { + const mig = await this.tracker.getMigration(address, fih, fversion, chainId) + if (!mig) return { signedMigrations: migs, missing: true, lastImageHash: fih, lastVersion: fversion } + + migs.push(mig) + + const migration = this.migrations[fversion] + if (!migration) { + throw new Error(`No migration found for version ${fversion}`) + } + + const decoded = migration.decodeTransaction(mig.tx, this.contexts) + if (decoded.address !== address) { + throw new Error(`Migration transaction address does not match expected address`) + } + + fih = decoded.newImageHash + fversion += 1 + } + + return { signedMigrations: migs, missing: false, lastImageHash: fih, lastVersion: fversion } + } + + async signNextMigration( + address: string, + fromVersion: number, + wallet: Wallet, + nextConfig: commons.config.Config + ): Promise { + const migration = this.migrations[fromVersion] + + if (!migration) { + return undefined + } + + const unsignedMigration = migration.buildTransaction(address, this.contexts, nextConfig) + const signedBundle = await wallet.signTransactionBundle(unsignedMigration.tx) + + return { + ...unsignedMigration, + tx: signedBundle + } + } +} diff --git a/packages/migration/src/version.ts b/packages/migration/src/version.ts new file mode 100644 index 0000000000..d67a0fdebf --- /dev/null +++ b/packages/migration/src/version.ts @@ -0,0 +1,30 @@ +import { ethers } from 'ethers' +import { commons } from '@0xsequence/core' + +export function counterfactualVersion( + address: string, + firstImageHash: string, + versions: commons.context.WalletContext[] +): number { + for (let i = 0; i < versions.length; i++) { + if (commons.context.addressOf(versions[i], firstImageHash) === address) { + return versions[i].version + } + } + + // if we can't find the version then either the address is invalid, + // the version is not in VersionedContext, or the firstImageHash is not correct + throw new Error('Could not find version for counterfactual address') +} + +export interface Version< + C extends commons.config.Config, + S extends commons.signature.Signature, + U extends commons.signature.UnrecoveredSignature +> { + version: number + coders: { + config: commons.config.ConfigCoder + signature: commons.signature.SignatureCoder + } +} diff --git a/packages/multicall/CHANGELOG.md b/packages/multicall/CHANGELOG.md new file mode 100644 index 0000000000..2cc02fb15b --- /dev/null +++ b/packages/multicall/CHANGELOG.md @@ -0,0 +1,2943 @@ +# @0xsequence/multicall + +## 2.0.0 + +### Major Changes + +- changeset + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@2.0.0 + - @0xsequence/network@2.0.0 + - @0xsequence/utils@2.0.0 + +## 1.10.14 + +### Patch Changes + +- network: add borne-testnet to allNetworks +- Updated dependencies + - @0xsequence/abi@1.10.14 + - @0xsequence/network@1.10.14 + - @0xsequence/utils@1.10.14 + +## 1.10.13 + +### Patch Changes + +- network: add borne testnet +- Updated dependencies + - @0xsequence/abi@1.10.13 + - @0xsequence/network@1.10.13 + - @0xsequence/utils@1.10.13 + +## 1.10.12 + +### Patch Changes + +- api: update bindings +- global/window -> globalThis +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.10.12 + - @0xsequence/network@1.10.12 + - @0xsequence/utils@1.10.12 + +## 1.10.11 + +### Patch Changes + +- waas: updated intent.gen without webrpc types, errors exported from authenticator.gen +- Updated dependencies + - @0xsequence/abi@1.10.11 + - @0xsequence/network@1.10.11 + - @0xsequence/utils@1.10.11 + +## 1.10.10 + +### Patch Changes + +- metadata: update bindings with new contract collections api +- Updated dependencies + - @0xsequence/abi@1.10.10 + - @0xsequence/network@1.10.10 + - @0xsequence/utils@1.10.10 + +## 1.10.9 + +### Patch Changes + +- waas minor update +- Updated dependencies + - @0xsequence/abi@1.10.9 + - @0xsequence/network@1.10.9 + - @0xsequence/utils@1.10.9 + +## 1.10.8 + +### Patch Changes + +- update metadata bindings +- Updated dependencies + - @0xsequence/abi@1.10.8 + - @0xsequence/network@1.10.8 + - @0xsequence/utils@1.10.8 + +## 1.10.7 + +### Patch Changes + +- minor fixes to waas client +- Updated dependencies + - @0xsequence/abi@1.10.7 + - @0xsequence/network@1.10.7 + - @0xsequence/utils@1.10.7 + +## 1.10.6 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/abi@1.10.6 + - @0xsequence/network@1.10.6 + - @0xsequence/utils@1.10.6 + +## 1.10.5 + +### Patch Changes + +- network: ape-chain-testnet -> apechain-testnet +- Updated dependencies + - @0xsequence/abi@1.10.5 + - @0xsequence/network@1.10.5 + - @0xsequence/utils@1.10.5 + +## 1.10.4 + +### Patch Changes + +- network: add b3-sepolia, ape-chain-testnet, blast, blast-sepolia +- Updated dependencies + - @0xsequence/abi@1.10.4 + - @0xsequence/network@1.10.4 + - @0xsequence/utils@1.10.4 + +## 1.10.3 + +### Patch Changes + +- typing fix +- Updated dependencies + - @0xsequence/abi@1.10.3 + - @0xsequence/network@1.10.3 + - @0xsequence/utils@1.10.3 + +## 1.10.2 + +### Patch Changes + +- - waas: add getIdToken method + - indexer: update api client +- Updated dependencies + - @0xsequence/abi@1.10.2 + - @0xsequence/network@1.10.2 + - @0xsequence/utils@1.10.2 + +## 1.10.1 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/abi@1.10.1 + - @0xsequence/network@1.10.1 + - @0xsequence/utils@1.10.1 + +## 1.10.0 + +### Minor Changes + +- waas release v1.3.0 + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.10.0 + - @0xsequence/network@1.10.0 + - @0xsequence/utils@1.10.0 + +## 1.9.37 + +### Patch Changes + +- network: adds nativeToken data to NetworkMetadata constants +- Updated dependencies + - @0xsequence/abi@1.9.37 + - @0xsequence/network@1.9.37 + - @0xsequence/utils@1.9.37 + +## 1.9.36 + +### Patch Changes + +- guard: export client +- Updated dependencies + - @0xsequence/abi@1.9.36 + - @0xsequence/network@1.9.36 + - @0xsequence/utils@1.9.36 + +## 1.9.35 + +### Patch Changes + +- guard: update bindings +- Updated dependencies + - @0xsequence/abi@1.9.35 + - @0xsequence/network@1.9.35 + - @0xsequence/utils@1.9.35 + +## 1.9.34 + +### Patch Changes + +- waas: always use lowercase email +- Updated dependencies + - @0xsequence/abi@1.9.34 + - @0xsequence/network@1.9.34 + - @0xsequence/utils@1.9.34 + +## 1.9.33 + +### Patch Changes + +- waas: umd build +- Updated dependencies + - @0xsequence/abi@1.9.33 + - @0xsequence/network@1.9.33 + - @0xsequence/utils@1.9.33 + +## 1.9.32 + +### Patch Changes + +- indexer: update bindings +- Updated dependencies + - @0xsequence/abi@1.9.32 + - @0xsequence/network@1.9.32 + - @0xsequence/utils@1.9.32 + +## 1.9.31 + +### Patch Changes + +- metadata: token directory changes +- Updated dependencies + - @0xsequence/abi@1.9.31 + - @0xsequence/network@1.9.31 + - @0xsequence/utils@1.9.31 + +## 1.9.30 + +### Patch Changes + +- update +- Updated dependencies + - @0xsequence/abi@1.9.30 + - @0xsequence/network@1.9.30 + - @0xsequence/utils@1.9.30 + +## 1.9.29 + +### Patch Changes + +- disable gnosis chain +- Updated dependencies + - @0xsequence/abi@1.9.29 + - @0xsequence/network@1.9.29 + - @0xsequence/utils@1.9.29 + +## 1.9.28 + +### Patch Changes + +- add utils/merkletree +- Updated dependencies + - @0xsequence/abi@1.9.28 + - @0xsequence/network@1.9.28 + - @0xsequence/utils@1.9.28 + +## 1.9.27 + +### Patch Changes + +- network: optimistic -> optimism +- waas: remove defaults +- api, sessions: update bindings +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.9.27 + - @0xsequence/network@1.9.27 + - @0xsequence/utils@1.9.27 + +## 1.9.26 + +### Patch Changes + +- - add backend interfaces for pluggable interfaces + - introduce @0xsequence/react-native + - update pnpm to lockfile v9 +- Updated dependencies + - @0xsequence/abi@1.9.26 + - @0xsequence/network@1.9.26 + - @0xsequence/utils@1.9.26 + +## 1.9.25 + +### Patch Changes + +- update webrpc clients with new error types +- Updated dependencies + - @0xsequence/abi@1.9.25 + - @0xsequence/network@1.9.25 + - @0xsequence/utils@1.9.25 + +## 1.9.24 + +### Patch Changes + +- waas: add memoryStore backend to localStore +- Updated dependencies + - @0xsequence/abi@1.9.24 + - @0xsequence/network@1.9.24 + - @0xsequence/utils@1.9.24 + +## 1.9.23 + +### Patch Changes + +- update api client bindings +- Updated dependencies + - @0xsequence/abi@1.9.23 + - @0xsequence/network@1.9.23 + - @0xsequence/utils@1.9.23 + +## 1.9.22 + +### Patch Changes + +- update metadata client bindings +- Updated dependencies + - @0xsequence/abi@1.9.22 + - @0xsequence/network@1.9.22 + - @0xsequence/utils@1.9.22 + +## 1.9.21 + +### Patch Changes + +- api client bindings +- Updated dependencies + - @0xsequence/abi@1.9.21 + - @0xsequence/network@1.9.21 + - @0xsequence/utils@1.9.21 + +## 1.9.20 + +### Patch Changes + +- api client bindings update +- Updated dependencies + - @0xsequence/abi@1.9.20 + - @0xsequence/network@1.9.20 + - @0xsequence/utils@1.9.20 + +## 1.9.19 + +### Patch Changes + +- waas update +- Updated dependencies + - @0xsequence/abi@1.9.19 + - @0xsequence/network@1.9.19 + - @0xsequence/utils@1.9.19 + +## 1.9.18 + +### Patch Changes + +- provider: prohibit dangerous functions +- Updated dependencies + - @0xsequence/abi@1.9.18 + - @0xsequence/network@1.9.18 + - @0xsequence/utils@1.9.18 + +## 1.9.17 + +### Patch Changes + +- network: add xr-sepolia +- Updated dependencies + - @0xsequence/network@1.9.17 + - @0xsequence/abi@1.9.17 + - @0xsequence/utils@1.9.17 + +## 1.9.16 + +### Patch Changes + +- waas: sequence.feeOptions +- Updated dependencies + - @0xsequence/abi@1.9.16 + - @0xsequence/network@1.9.16 + - @0xsequence/utils@1.9.16 + +## 1.9.15 + +### Patch Changes + +- metadata: collection external_link field name fix +- Updated dependencies + - @0xsequence/abi@1.9.15 + - @0xsequence/network@1.9.15 + - @0xsequence/utils@1.9.15 + +## 1.9.14 + +### Patch Changes + +- network: astar-zkatana -> astar-zkyoto +- network: deprecate polygon mumbai network +- network: add xai and polygon amoy +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.9.14 + - @0xsequence/network@1.9.14 + - @0xsequence/utils@1.9.14 + +## 1.9.13 + +### Patch Changes + +- waas: fix @0xsequence/network dependency +- Updated dependencies + - @0xsequence/abi@1.9.13 + - @0xsequence/network@1.9.13 + - @0xsequence/utils@1.9.13 + +## 1.9.12 + +### Patch Changes + +- indexer: update rpc bindings +- provider: signMessage: Serialize the BytesLike or string message into hexstring before sending +- waas: SessionAuthProof +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.9.12 + - @0xsequence/network@1.9.12 + - @0xsequence/utils@1.9.12 + +## 1.9.11 + +### Patch Changes + +- metdata, update rpc bindings +- Updated dependencies + - @0xsequence/abi@1.9.11 + - @0xsequence/network@1.9.11 + - @0xsequence/utils@1.9.11 + +## 1.9.10 + +### Patch Changes + +- update metadata rpc bindings +- Updated dependencies + - @0xsequence/abi@1.9.10 + - @0xsequence/network@1.9.10 + - @0xsequence/utils@1.9.10 + +## 1.9.9 + +### Patch Changes + +- metadata, add SequenceCollections rpc client +- Updated dependencies + - @0xsequence/abi@1.9.9 + - @0xsequence/network@1.9.9 + - @0xsequence/utils@1.9.9 + +## 1.9.8 + +### Patch Changes + +- waas client update +- Updated dependencies + - @0xsequence/abi@1.9.8 + - @0xsequence/network@1.9.8 + - @0xsequence/utils@1.9.8 + +## 1.9.7 + +### Patch Changes + +- update rpc client bindings for api, metadata and relayer +- Updated dependencies + - @0xsequence/abi@1.9.7 + - @0xsequence/network@1.9.7 + - @0xsequence/utils@1.9.7 + +## 1.9.6 + +### Patch Changes + +- waas package update +- Updated dependencies + - @0xsequence/abi@1.9.6 + - @0xsequence/network@1.9.6 + - @0xsequence/utils@1.9.6 + +## 1.9.5 + +### Patch Changes + +- RpcRelayer prioritize project access key +- Updated dependencies + - @0xsequence/abi@1.9.5 + - @0xsequence/network@1.9.5 + - @0xsequence/utils@1.9.5 + +## 1.9.4 + +### Patch Changes + +- waas: fix network dependency +- Updated dependencies + - @0xsequence/abi@1.9.4 + - @0xsequence/network@1.9.4 + - @0xsequence/utils@1.9.4 + +## 1.9.3 + +### Patch Changes + +- provider: don't append access key to RPC url if user has already provided it +- Updated dependencies + - @0xsequence/abi@1.9.3 + - @0xsequence/network@1.9.3 + - @0xsequence/utils@1.9.3 + +## 1.9.2 + +### Patch Changes + +- network: add xai-sepolia +- Updated dependencies + - @0xsequence/abi@1.9.2 + - @0xsequence/network@1.9.2 + - @0xsequence/utils@1.9.2 + +## 1.9.1 + +### Patch Changes + +- analytics fix +- Updated dependencies + - @0xsequence/abi@1.9.1 + - @0xsequence/network@1.9.1 + - @0xsequence/utils@1.9.1 + +## 1.9.0 + +### Minor Changes + +- waas release + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.9.0 + - @0xsequence/network@1.9.0 + - @0xsequence/utils@1.9.0 + +## 1.8.8 + +### Patch Changes + +- update metadata bindings +- Updated dependencies + - @0xsequence/abi@1.8.8 + - @0xsequence/network@1.8.8 + - @0xsequence/utils@1.8.8 + +## 1.8.7 + +### Patch Changes + +- provider: update databeat to 0.9.1 +- Updated dependencies + - @0xsequence/abi@1.8.7 + - @0xsequence/network@1.8.7 + - @0xsequence/utils@1.8.7 + +## 1.8.6 + +### Patch Changes + +- guard: SignedOwnershipProof +- Updated dependencies + - @0xsequence/abi@1.8.6 + - @0xsequence/network@1.8.6 + - @0xsequence/utils@1.8.6 + +## 1.8.5 + +### Patch Changes + +- guard: signOwnershipProof and isSignedOwnershipProof +- Updated dependencies + - @0xsequence/abi@1.8.5 + - @0xsequence/network@1.8.5 + - @0xsequence/utils@1.8.5 + +## 1.8.4 + +### Patch Changes + +- network: add homeverse to networks list +- Updated dependencies + - @0xsequence/abi@1.8.4 + - @0xsequence/network@1.8.4 + - @0xsequence/utils@1.8.4 + +## 1.8.3 + +### Patch Changes + +- api: introduce basic linked wallet support +- Updated dependencies + - @0xsequence/abi@1.8.3 + - @0xsequence/network@1.8.3 + - @0xsequence/utils@1.8.3 + +## 1.8.2 + +### Patch Changes + +- provider: don't initialize analytics unless explicitly requested +- Updated dependencies + - @0xsequence/abi@1.8.2 + - @0xsequence/network@1.8.2 + - @0xsequence/utils@1.8.2 + +## 1.8.1 + +### Patch Changes + +- update to analytics provider +- Updated dependencies + - @0xsequence/abi@1.8.1 + - @0xsequence/network@1.8.1 + - @0xsequence/utils@1.8.1 + +## 1.8.0 + +### Minor Changes + +- provider: project analytics + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.8.0 + - @0xsequence/network@1.8.0 + - @0xsequence/utils@1.8.0 + +## 1.7.2 + +### Patch Changes + +- 0xsequence: ChainId should not be exported as a type +- account, wallet: fix nonce selection +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.7.2 + - @0xsequence/network@1.7.2 + - @0xsequence/utils@1.7.2 + +## 1.7.1 + +### Patch Changes + +- network: add missing avalanche logoURI +- Updated dependencies + - @0xsequence/abi@1.7.1 + - @0xsequence/network@1.7.1 + - @0xsequence/utils@1.7.1 + +## 1.7.0 + +### Minor Changes + +- provider: projectAccessKey is now required + +### Patch Changes + +- network: add NetworkMetadata.logoURI property for all networks +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.7.0 + - @0xsequence/network@1.7.0 + - @0xsequence/utils@1.7.0 + +## 1.6.3 + +### Patch Changes + +- network list update +- Updated dependencies + - @0xsequence/abi@1.6.3 + - @0xsequence/network@1.6.3 + - @0xsequence/utils@1.6.3 + +## 1.6.2 + +### Patch Changes + +- auth: projectAccessKey option +- wallet: use 12 bytes for random space +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.6.2 + - @0xsequence/network@1.6.2 + - @0xsequence/utils@1.6.2 + +## 1.6.1 + +### Patch Changes + +- core: add simple config from subdigest support +- core: fix encode tree with subdigest +- account: implement buildOnChainSignature on Account +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.6.1 + - @0xsequence/network@1.6.1 + - @0xsequence/utils@1.6.1 + +## 1.6.0 + +### Minor Changes + +- account, wallet: parallel transactions by default + +### Patch Changes + +- provider: emit disconnect on sign out +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.6.0 + - @0xsequence/network@1.6.0 + - @0xsequence/utils@1.6.0 + +## 1.5.0 + +### Minor Changes + +- signhub: add 'signing' signer status + +### Patch Changes + +- auth: Session.open: onAccountAddress callback +- account: allow empty transaction bundles +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.5.0 + - @0xsequence/network@1.5.0 + - @0xsequence/utils@1.5.0 + +## 1.4.9 + +### Patch Changes + +- rename SequenceMetadataClient to SequenceMetadata +- Updated dependencies + - @0xsequence/abi@1.4.9 + - @0xsequence/network@1.4.9 + - @0xsequence/utils@1.4.9 + +## 1.4.8 + +### Patch Changes + +- account: Account.getSigners +- Updated dependencies + - @0xsequence/abi@1.4.8 + - @0xsequence/network@1.4.8 + - @0xsequence/utils@1.4.8 + +## 1.4.7 + +### Patch Changes + +- update indexer client bindings +- Updated dependencies + - @0xsequence/abi@1.4.7 + - @0xsequence/network@1.4.7 + - @0xsequence/utils@1.4.7 + +## 1.4.6 + +### Patch Changes + +- - add sepolia networks, mark goerli as deprecated + - update indexer client bindings +- Updated dependencies + - @0xsequence/abi@1.4.6 + - @0xsequence/network@1.4.6 + - @0xsequence/utils@1.4.6 + +## 1.4.5 + +### Patch Changes + +- indexer/metadata: update client bindings +- auth: selectWallet with new address +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.4.5 + - @0xsequence/network@1.4.5 + - @0xsequence/utils@1.4.5 + +## 1.4.4 + +### Patch Changes + +- indexer: update bindings +- auth: handle jwt expiry +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.4.4 + - @0xsequence/network@1.4.4 + - @0xsequence/utils@1.4.4 + +## 1.4.3 + +### Patch Changes + +- guard: return active status from GuardSigner.getAuthMethods +- Updated dependencies + - @0xsequence/abi@1.4.3 + - @0xsequence/network@1.4.3 + - @0xsequence/utils@1.4.3 + +## 1.4.2 + +### Patch Changes + +- guard: update bindings +- Updated dependencies + - @0xsequence/abi@1.4.2 + - @0xsequence/network@1.4.2 + - @0xsequence/utils@1.4.2 + +## 1.4.1 + +### Patch Changes + +- network: remove unused networks +- signhub: orchestrator interface +- guard: auth methods interface +- guard: update bindings for pin and totp +- guard: no more retry logic +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.4.1 + - @0xsequence/network@1.4.1 + - @0xsequence/utils@1.4.1 + +## 1.4.0 + +### Minor Changes + +- project access key support + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.4.0 + - @0xsequence/network@1.4.0 + - @0xsequence/utils@1.4.0 + +## 1.3.0 + +### Minor Changes + +- signhub: account children + +### Patch Changes + +- guard: do not throw when building deploy transaction +- network: snowtrace.io -> subnets.avax.network/c-chain +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.3.0 + - @0xsequence/network@1.3.0 + - @0xsequence/utils@1.3.0 + +## 1.2.9 + +### Patch Changes + +- account: AccountSigner.sendTransaction simulateForFeeOptions +- relayer: update bindings +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.2.9 + - @0xsequence/network@1.2.9 + - @0xsequence/utils@1.2.9 + +## 1.2.8 + +### Patch Changes + +- rename X-Sequence-Token-Key header to X-Access-Key +- Updated dependencies + - @0xsequence/abi@1.2.8 + - @0xsequence/network@1.2.8 + - @0xsequence/utils@1.2.8 + +## 1.2.7 + +### Patch Changes + +- add x-sequence-token-key to clients +- Updated dependencies + - @0xsequence/abi@1.2.7 + - @0xsequence/network@1.2.7 + - @0xsequence/utils@1.2.7 + +## 1.2.6 + +### Patch Changes + +- Fix bind multicall provider +- Updated dependencies + - @0xsequence/abi@1.2.6 + - @0xsequence/network@1.2.6 + - @0xsequence/utils@1.2.6 + +## 1.2.5 + +### Patch Changes + +- Multicall default configuration fixes +- Updated dependencies + - @0xsequence/abi@1.2.5 + - @0xsequence/network@1.2.5 + - @0xsequence/utils@1.2.5 + +## 1.2.4 + +### Patch Changes + +- provider: Adding missing payment provider types to PaymentProviderOption +- provider: WalletRequestHandler.notifyChainChanged +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.2.4 + - @0xsequence/network@1.2.4 + - @0xsequence/utils@1.2.4 + +## 1.2.3 + +### Patch Changes + +- auth, provider: connect to accept optional authorizeNonce +- Updated dependencies + - @0xsequence/abi@1.2.3 + - @0xsequence/network@1.2.3 + - @0xsequence/utils@1.2.3 + +## 1.2.2 + +### Patch Changes + +- provider: allow createContract calls +- core: check for explicit zero address in contract deployments +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.2.2 + - @0xsequence/network@1.2.2 + - @0xsequence/utils@1.2.2 + +## 1.2.1 + +### Patch Changes + +- auth: use sequence api chain id as reference chain id if available +- Updated dependencies + - @0xsequence/abi@1.2.1 + - @0xsequence/network@1.2.1 + - @0xsequence/utils@1.2.1 + +## 1.2.0 + +### Minor Changes + +- split services from session, better local support + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.2.0 + - @0xsequence/network@1.2.0 + - @0xsequence/utils@1.2.0 + +## 1.1.15 + +### Patch Changes + +- guard: remove error filtering +- Updated dependencies + - @0xsequence/abi@1.1.15 + - @0xsequence/network@1.1.15 + - @0xsequence/utils@1.1.15 + +## 1.1.14 + +### Patch Changes + +- guard: add GuardSigner.onError +- Updated dependencies + - @0xsequence/abi@1.1.14 + - @0xsequence/network@1.1.14 + - @0xsequence/utils@1.1.14 + +## 1.1.13 + +### Patch Changes + +- provider: pass client version with connect options +- provider: removing large from BannerSize +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.1.13 + - @0xsequence/network@1.1.13 + - @0xsequence/utils@1.1.13 + +## 1.1.12 + +### Patch Changes + +- provider: adding bannerSize to ConnectOptions +- Updated dependencies + - @0xsequence/abi@1.1.12 + - @0xsequence/network@1.1.12 + - @0xsequence/utils@1.1.12 + +## 1.1.11 + +### Patch Changes + +- add homeverse configs +- Updated dependencies + - @0xsequence/abi@1.1.11 + - @0xsequence/network@1.1.11 + - @0xsequence/utils@1.1.11 + +## 1.1.10 + +### Patch Changes + +- handle default EIP6492 on send +- Updated dependencies + - @0xsequence/abi@1.1.10 + - @0xsequence/network@1.1.10 + - @0xsequence/utils@1.1.10 + +## 1.1.9 + +### Patch Changes + +- Custom default EIP6492 on client +- Updated dependencies + - @0xsequence/abi@1.1.9 + - @0xsequence/network@1.1.9 + - @0xsequence/utils@1.1.9 + +## 1.1.8 + +### Patch Changes + +- metadata: searchMetadata: add types filter +- Updated dependencies + - @0xsequence/abi@1.1.8 + - @0xsequence/network@1.1.8 + - @0xsequence/utils@1.1.8 + +## 1.1.7 + +### Patch Changes + +- adding signInWith connect settings option to allow dapps to automatically login their users with a certain provider optimizing the normal authentication flow +- Updated dependencies + - @0xsequence/abi@1.1.7 + - @0xsequence/network@1.1.7 + - @0xsequence/utils@1.1.7 + +## 1.1.6 + +### Patch Changes + +- metadata: searchMetadata: add chainID and excludeTokenMetadata filters +- Updated dependencies + - @0xsequence/abi@1.1.6 + - @0xsequence/network@1.1.6 + - @0xsequence/utils@1.1.6 + +## 1.1.5 + +### Patch Changes + +- account: re-compute meta-transaction id for wallet deployment transactions +- Updated dependencies + - @0xsequence/abi@1.1.5 + - @0xsequence/network@1.1.5 + - @0xsequence/utils@1.1.5 + +## 1.1.4 + +### Patch Changes + +- network: rename base-mainnet to base +- provider: override isDefaultChain with ConnectOptions.networkId if provided +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.1.4 + - @0xsequence/network@1.1.4 + - @0xsequence/utils@1.1.4 + +## 1.1.3 + +### Patch Changes + +- provider: use network id from transport session +- provider: sign authorization using ConnectOptions.networkId if provided +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.1.3 + - @0xsequence/network@1.1.3 + - @0xsequence/utils@1.1.3 + +## 1.1.2 + +### Patch Changes + +- provider: jsonrpc chain id fixes +- Updated dependencies + - @0xsequence/abi@1.1.2 + - @0xsequence/network@1.1.2 + - @0xsequence/utils@1.1.2 + +## 1.1.1 + +### Patch Changes + +- network: add base mainnet and sepolia +- provider: reject toxic transaction requests +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.1.1 + - @0xsequence/network@1.1.1 + - @0xsequence/utils@1.1.1 + +## 1.1.0 + +### Minor Changes + +- Refactor dapp facing provider + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.1.0 + - @0xsequence/network@1.1.0 + - @0xsequence/utils@1.1.0 + +## 1.0.5 + +### Patch Changes + +- network: export network constants +- guard: use the correct global for fetch +- network: nova-explorer.arbitrum.io -> nova.arbiscan.io +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.0.5 + - @0xsequence/network@1.0.5 + - @0xsequence/utils@1.0.5 + +## 1.0.4 + +### Patch Changes + +- provider: accept name or number for networkId +- Updated dependencies + - @0xsequence/abi@1.0.4 + - @0xsequence/network@1.0.4 + - @0xsequence/utils@1.0.4 + +## 1.0.3 + +### Patch Changes + +- Simpler isValidSignature helpers +- Updated dependencies + - @0xsequence/abi@1.0.3 + - @0xsequence/network@1.0.3 + - @0xsequence/utils@1.0.3 + +## 1.0.2 + +### Patch Changes + +- add extra signature validation utils methods +- Updated dependencies + - @0xsequence/abi@1.0.2 + - @0xsequence/network@1.0.2 + - @0xsequence/utils@1.0.2 + +## 1.0.1 + +### Patch Changes + +- add homeverse testnet +- Updated dependencies + - @0xsequence/abi@1.0.1 + - @0xsequence/network@1.0.1 + - @0xsequence/utils@1.0.1 + +## 1.0.0 + +### Major Changes + +- https://sequence.xyz/blog/sequence-wallet-light-state-sync-full-merkle-wallets + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.0.0 + - @0xsequence/network@1.0.0 + - @0xsequence/utils@1.0.0 + +## 0.43.34 + +### Patch Changes + +- auth: no jwt for indexer +- Updated dependencies + - @0xsequence/abi@0.43.34 + - @0xsequence/network@0.43.34 + - @0xsequence/utils@0.43.34 + +## 0.43.33 + +### Patch Changes + +- Adding onConnectOptionsChange handler to WalletRequestHandler +- Updated dependencies + - @0xsequence/abi@0.43.33 + - @0xsequence/network@0.43.33 + - @0xsequence/utils@0.43.33 + +## 0.43.32 + +### Patch Changes + +- add Base Goerli network +- Updated dependencies + - @0xsequence/abi@0.43.32 + - @0xsequence/network@0.43.32 + - @0xsequence/utils@0.43.32 + +## 0.43.31 + +### Patch Changes + +- remove AuxDataProvider, add promptSignInConnect +- Updated dependencies + - @0xsequence/abi@0.43.31 + - @0xsequence/network@0.43.31 + - @0xsequence/utils@0.43.31 + +## 0.43.30 + +### Patch Changes + +- add arbitrum goerli testnet +- Updated dependencies + - @0xsequence/abi@0.43.30 + - @0xsequence/network@0.43.30 + - @0xsequence/utils@0.43.30 + +## 0.43.29 + +### Patch Changes + +- provider: check availability of window object +- Updated dependencies + - @0xsequence/abi@0.43.29 + - @0xsequence/network@0.43.29 + - @0xsequence/utils@0.43.29 + +## 0.43.28 + +### Patch Changes + +- update api bindings +- Updated dependencies + - @0xsequence/abi@0.43.28 + - @0xsequence/network@0.43.28 + - @0xsequence/utils@0.43.28 + +## 0.43.27 + +### Patch Changes + +- Add rpc is sequence method +- Updated dependencies + - @0xsequence/abi@0.43.27 + - @0xsequence/network@0.43.27 + - @0xsequence/utils@0.43.27 + +## 0.43.26 + +### Patch Changes + +- add zkevm url to enum +- Updated dependencies + - @0xsequence/abi@0.43.26 + - @0xsequence/network@0.43.26 + - @0xsequence/utils@0.43.26 + +## 0.43.25 + +### Patch Changes + +- added polygon zkevm to mainnet networks +- Updated dependencies + - @0xsequence/abi@0.43.25 + - @0xsequence/network@0.43.25 + - @0xsequence/utils@0.43.25 + +## 0.43.24 + +### Patch Changes + +- name change from zkevm to polygon-zkevm +- Updated dependencies + - @0xsequence/abi@0.43.24 + - @0xsequence/network@0.43.24 + - @0xsequence/utils@0.43.24 + +## 0.43.23 + +### Patch Changes + +- update zkEVM name to Polygon zkEVM +- Updated dependencies + - @0xsequence/abi@0.43.23 + - @0xsequence/network@0.43.23 + - @0xsequence/utils@0.43.23 + +## 0.43.22 + +### Patch Changes + +- add zkevm chain +- Updated dependencies + - @0xsequence/abi@0.43.22 + - @0xsequence/network@0.43.22 + - @0xsequence/utils@0.43.22 + +## 0.43.21 + +### Patch Changes + +- api: update client bindings +- Updated dependencies + - @0xsequence/abi@0.43.21 + - @0xsequence/network@0.43.21 + - @0xsequence/utils@0.43.21 + +## 0.43.20 + +### Patch Changes + +- indexer: update bindings +- Updated dependencies + - @0xsequence/abi@0.43.20 + - @0xsequence/network@0.43.20 + - @0xsequence/utils@0.43.20 + +## 0.43.19 + +### Patch Changes + +- session proof update +- Updated dependencies + - @0xsequence/abi@0.43.19 + - @0xsequence/network@0.43.19 + - @0xsequence/utils@0.43.19 + +## 0.43.18 + +### Patch Changes + +- rpc client global check, hardening +- Updated dependencies + - @0xsequence/abi@0.43.18 + - @0xsequence/network@0.43.18 + - @0xsequence/utils@0.43.18 + +## 0.43.17 + +### Patch Changes + +- rpc clients, check of 'global' is defined +- Updated dependencies + - @0xsequence/abi@0.43.17 + - @0xsequence/network@0.43.17 + - @0xsequence/utils@0.43.17 + +## 0.43.16 + +### Patch Changes + +- ethers peerDep to v5, update rpc client global use +- Updated dependencies + - @0xsequence/abi@0.43.16 + - @0xsequence/network@0.43.16 + - @0xsequence/utils@0.43.16 + +## 0.43.15 + +### Patch Changes + +- - provider: expand receiver type on some util methods +- Updated dependencies + - @0xsequence/abi@0.43.15 + - @0xsequence/network@0.43.15 + - @0xsequence/utils@0.43.15 + +## 0.43.14 + +### Patch Changes + +- bump +- Updated dependencies + - @0xsequence/abi@0.43.14 + - @0xsequence/network@0.43.14 + - @0xsequence/utils@0.43.14 + +## 0.43.13 + +### Patch Changes + +- update rpc bindings +- Updated dependencies + - @0xsequence/abi@0.43.13 + - @0xsequence/network@0.43.13 + - @0xsequence/utils@0.43.13 + +## 0.43.12 + +### Patch Changes + +- provider: single wallet init, and add new unregisterWallet() method +- Updated dependencies + - @0xsequence/abi@0.43.12 + - @0xsequence/network@0.43.12 + - @0xsequence/utils@0.43.12 + +## 0.43.11 + +### Patch Changes + +- fix lockfiles +- re-add mocha type deleter +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.43.11 + - @0xsequence/network@0.43.11 + - @0xsequence/utils@0.43.11 + +## 0.43.10 + +### Patch Changes + +- various improvements +- Updated dependencies + - @0xsequence/abi@0.43.10 + - @0xsequence/network@0.43.10 + - @0xsequence/utils@0.43.10 + +## 0.43.9 + +### Patch Changes + +- update deps +- Updated dependencies + - @0xsequence/abi@0.43.9 + - @0xsequence/network@0.43.9 + - @0xsequence/utils@0.43.9 + +## 0.43.8 + +### Patch Changes + +- network: JsonRpcProvider with caching +- Updated dependencies + - @0xsequence/abi@0.43.8 + - @0xsequence/network@0.43.8 + - @0xsequence/utils@0.43.8 + +## 0.43.7 + +### Patch Changes + +- provider: fix wallet network init +- Updated dependencies + - @0xsequence/abi@0.43.7 + - @0xsequence/network@0.43.7 + - @0xsequence/utils@0.43.7 + +## 0.43.6 + +### Patch Changes + +- metadatata: update rpc bindings +- Updated dependencies + - @0xsequence/abi@0.43.6 + - @0xsequence/network@0.43.6 + - @0xsequence/utils@0.43.6 + +## 0.43.5 + +### Patch Changes + +- provider: do not set default network for connect messages +- provider: forward missing error message +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.43.5 + - @0xsequence/network@0.43.5 + - @0xsequence/utils@0.43.5 + +## 0.43.4 + +### Patch Changes + +- no-change version bump to fix incorrectly tagged snapshot build +- Updated dependencies + - @0xsequence/abi@0.43.4 + - @0xsequence/network@0.43.4 + - @0xsequence/utils@0.43.4 + +## 0.43.3 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/abi@0.43.3 + - @0xsequence/network@0.43.3 + - @0xsequence/utils@0.43.3 + +## 0.43.2 + +### Patch Changes + +- provider: implement connectUnchecked +- Updated dependencies + - @0xsequence/abi@0.43.2 + - @0xsequence/network@0.43.2 + - @0xsequence/utils@0.43.2 + +## 0.43.1 + +### Patch Changes + +- update to latest ethauth dep +- Updated dependencies + - @0xsequence/abi@0.43.1 + - @0xsequence/network@0.43.1 + - @0xsequence/utils@0.43.1 + +## 0.43.0 + +### Minor Changes + +- move ethers to a peer dependency + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.43.0 + - @0xsequence/network@0.43.0 + - @0xsequence/utils@0.43.0 + +## 0.42.10 + +### Patch Changes + +- add auxDataProvider +- Updated dependencies + - @0xsequence/abi@0.42.10 + - @0xsequence/network@0.42.10 + - @0xsequence/utils@0.42.10 + +## 0.42.9 + +### Patch Changes + +- provider: add eip-191 exceptions +- Updated dependencies + - @0xsequence/abi@0.42.9 + - @0xsequence/network@0.42.9 + - @0xsequence/utils@0.42.9 + +## 0.42.8 + +### Patch Changes + +- provider: skip setting intent origin if we're unity plugin +- Updated dependencies + - @0xsequence/abi@0.42.8 + - @0xsequence/network@0.42.8 + - @0xsequence/utils@0.42.8 + +## 0.42.7 + +### Patch Changes + +- Add sign in options to connection settings +- Updated dependencies + - @0xsequence/abi@0.42.7 + - @0xsequence/network@0.42.7 + - @0xsequence/utils@0.42.7 + +## 0.42.6 + +### Patch Changes + +- api bindings update +- Updated dependencies + - @0xsequence/abi@0.42.6 + - @0xsequence/network@0.42.6 + - @0xsequence/utils@0.42.6 + +## 0.42.5 + +### Patch Changes + +- relayer: don't treat missing receipt as hard failure +- Updated dependencies + - @0xsequence/abi@0.42.5 + - @0xsequence/network@0.42.5 + - @0xsequence/utils@0.42.5 + +## 0.42.4 + +### Patch Changes + +- provider: add custom app protocol to connect options +- Updated dependencies + - @0xsequence/abi@0.42.4 + - @0xsequence/network@0.42.4 + - @0xsequence/utils@0.42.4 + +## 0.42.3 + +### Patch Changes + +- update api bindings +- Updated dependencies + - @0xsequence/abi@0.42.3 + - @0xsequence/network@0.42.3 + - @0xsequence/utils@0.42.3 + +## 0.42.2 + +### Patch Changes + +- disable rinkeby network +- Updated dependencies + - @0xsequence/abi@0.42.2 + - @0xsequence/network@0.42.2 + - @0xsequence/utils@0.42.2 + +## 0.42.1 + +### Patch Changes + +- wallet: optional waitForReceipt parameter +- Updated dependencies + - @0xsequence/abi@0.42.1 + - @0xsequence/network@0.42.1 + - @0xsequence/utils@0.42.1 + +## 0.42.0 + +### Minor Changes + +- relayer: estimateGasLimits -> simulate +- add simulator package + +### Patch Changes + +- transactions: fix flattenAuxTransactions +- provider: only filter nullish values +- provider: re-map transaction 'gas' back to 'gasLimit' +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.42.0 + - @0xsequence/network@0.42.0 + - @0xsequence/utils@0.42.0 + +## 0.41.3 + +### Patch Changes + +- api bindings update +- Updated dependencies + - @0xsequence/abi@0.41.3 + - @0xsequence/network@0.41.3 + - @0xsequence/utils@0.41.3 + +## 0.41.2 + +### Patch Changes + +- api bindings update +- Updated dependencies + - @0xsequence/abi@0.41.2 + - @0xsequence/network@0.41.2 + - @0xsequence/utils@0.41.2 + +## 0.41.1 + +### Patch Changes + +- update default networks +- Updated dependencies + - @0xsequence/abi@0.41.1 + - @0xsequence/network@0.41.1 + - @0xsequence/utils@0.41.1 + +## 0.41.0 + +### Minor Changes + +- relayer: fix Relayer.wait() interface + + The interface for calling Relayer.wait() has changed. Instead of a single optional ill-defined timeout/delay parameter, there are three optional parameters, in order: + + - timeout: the maximum time to wait for the transaction receipt + - delay: the polling interval, i.e. the time to wait between requests + - maxFails: the maximum number of hard failures to tolerate before giving up + + Please update your codebase accordingly. + +- relayer: add optional waitForReceipt parameter to Relayer.relay + + The behaviour of Relayer.relay() was not well-defined with respect to whether or not it waited for a receipt. + This change allows the caller to specify whether to wait or not, with the default behaviour being to wait. + +### Patch Changes + +- relayer: wait receipt retry logic +- fix wrapped object error +- provider: forward delegateCall and revertOnError transaction fields +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.41.0 + - @0xsequence/network@0.41.0 + - @0xsequence/utils@0.41.0 + +## 0.40.6 + +### Patch Changes + +- add arbitrum-nova chain +- Updated dependencies + - @0xsequence/abi@0.40.6 + - @0xsequence/network@0.40.6 + - @0xsequence/utils@0.40.6 + +## 0.40.5 + +### Patch Changes + +- api: update bindings +- Updated dependencies + - @0xsequence/abi@0.40.5 + - @0xsequence/network@0.40.5 + - @0xsequence/utils@0.40.5 + +## 0.40.4 + +### Patch Changes + +- add unreal transport +- Updated dependencies + - @0xsequence/abi@0.40.4 + - @0xsequence/network@0.40.4 + - @0xsequence/utils@0.40.4 + +## 0.40.3 + +### Patch Changes + +- provider: fix MessageToSign message type +- Updated dependencies + - @0xsequence/abi@0.40.3 + - @0xsequence/network@0.40.3 + - @0xsequence/utils@0.40.3 + +## 0.40.2 + +### Patch Changes + +- Wallet provider, loadSession method +- Updated dependencies + - @0xsequence/abi@0.40.2 + - @0xsequence/network@0.40.2 + - @0xsequence/utils@0.40.2 + +## 0.40.1 + +### Patch Changes + +- export sequence.initWallet and sequence.getWallet +- Updated dependencies + - @0xsequence/abi@0.40.1 + - @0xsequence/network@0.40.1 + - @0xsequence/utils@0.40.1 + +## 0.40.0 + +### Minor Changes + +- add sequence.initWallet(network, config) and sequence.getWallet() helper methods + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.40.0 + - @0xsequence/network@0.40.0 + - @0xsequence/utils@0.40.0 + +## 0.39.6 + +### Patch Changes + +- indexer: update client bindings +- Updated dependencies + - @0xsequence/abi@0.39.6 + - @0xsequence/network@0.39.6 + - @0xsequence/utils@0.39.6 + +## 0.39.5 + +### Patch Changes + +- provider: fix networkRpcUrl config option +- Updated dependencies + - @0xsequence/abi@0.39.5 + - @0xsequence/network@0.39.5 + - @0xsequence/utils@0.39.5 + +## 0.39.4 + +### Patch Changes + +- api: update client bindings +- Updated dependencies + - @0xsequence/abi@0.39.4 + - @0xsequence/network@0.39.4 + - @0xsequence/utils@0.39.4 + +## 0.39.3 + +### Patch Changes + +- add request method on Web3Provider +- Updated dependencies + - @0xsequence/abi@0.39.3 + - @0xsequence/network@0.39.3 + - @0xsequence/utils@0.39.3 + +## 0.39.2 + +### Patch Changes + +- update umd name +- Updated dependencies + - @0xsequence/abi@0.39.2 + - @0xsequence/network@0.39.2 + - @0xsequence/utils@0.39.2 + +## 0.39.1 + +### Patch Changes + +- add Aurora network +- add origin info for accountsChanged event to handle it per dapp +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.39.1 + - @0xsequence/network@0.39.1 + - @0xsequence/utils@0.39.1 + +## 0.39.0 + +### Minor Changes + +- abstract window.localStorage to interface type + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.39.0 + - @0xsequence/network@0.39.0 + - @0xsequence/utils@0.39.0 + +## 0.38.2 + +### Patch Changes + +- provider: add Settings.defaultPurchaseAmount +- Updated dependencies + - @0xsequence/abi@0.38.2 + - @0xsequence/network@0.38.2 + - @0xsequence/utils@0.38.2 + +## 0.38.1 + +### Patch Changes + +- update api and metadata rpc bindings +- Updated dependencies + - @0xsequence/abi@0.38.1 + - @0xsequence/network@0.38.1 + - @0xsequence/utils@0.38.1 + +## 0.38.0 + +### Minor Changes + +- api: update bindings, change TokenPrice interface +- bridge: remove @0xsequence/bridge package +- api: update bindings, rename ContractCallArg to TupleComponent + +### Patch Changes + +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.38.0 + - @0xsequence/network@0.38.0 + - @0xsequence/utils@0.38.0 + +## 0.37.1 + +### Patch Changes + +- Add back sortNetworks - Removing sorting was a breaking change for dapps on older versions which directly integrate sequence. +- Updated dependencies + - @0xsequence/abi@0.37.1 + - @0xsequence/network@0.37.1 + - @0xsequence/utils@0.37.1 + +## 0.37.0 + +### Minor Changes + +- network related fixes and improvements +- api: bindings: exchange rate lookups + +### Patch Changes + +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.37.0 + - @0xsequence/network@0.37.0 + - @0xsequence/utils@0.37.0 + +## 0.36.13 + +### Patch Changes + +- api: update bindings with new price endpoints +- Updated dependencies + - @0xsequence/abi@0.36.13 + - @0xsequence/network@0.36.13 + - @0xsequence/utils@0.36.13 + +## 0.36.12 + +### Patch Changes + +- wallet: skip remote signers if not needed +- auth: check that signature meets threshold before requesting auth token +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.36.12 + - @0xsequence/network@0.36.12 + - @0xsequence/utils@0.36.12 + +## 0.36.11 + +### Patch Changes + +- Prefix EIP191 message on wallet-request-handler +- Updated dependencies + - @0xsequence/abi@0.36.11 + - @0xsequence/network@0.36.11 + - @0xsequence/utils@0.36.11 + +## 0.36.10 + +### Patch Changes + +- support bannerUrl on connect +- Updated dependencies + - @0xsequence/abi@0.36.10 + - @0xsequence/network@0.36.10 + - @0xsequence/utils@0.36.10 + +## 0.36.9 + +### Patch Changes + +- minor dev xp improvements +- Updated dependencies + - @0xsequence/abi@0.36.9 + - @0xsequence/network@0.36.9 + - @0xsequence/utils@0.36.9 + +## 0.36.8 + +### Patch Changes + +- more connect options (theme, payment providers, funding currencies) +- Updated dependencies + - @0xsequence/abi@0.36.8 + - @0xsequence/network@0.36.8 + - @0xsequence/utils@0.36.8 + +## 0.36.7 + +### Patch Changes + +- fix missing break +- Updated dependencies + - @0xsequence/abi@0.36.7 + - @0xsequence/network@0.36.7 + - @0xsequence/utils@0.36.7 + +## 0.36.6 + +### Patch Changes + +- wallet_switchEthereumChain support +- Updated dependencies + - @0xsequence/abi@0.36.6 + - @0xsequence/network@0.36.6 + - @0xsequence/utils@0.36.6 + +## 0.36.5 + +### Patch Changes + +- auth: bump ethauth to 0.7.0 + network, wallet: don't assume position of auth network in list + api/indexer/metadata: trim trailing slash on hostname, and add endpoint urls + relayer: Allow to specify local relayer transaction parameters like gas price or gas limit +- Updated dependencies + - @0xsequence/abi@0.36.5 + - @0xsequence/network@0.36.5 + - @0xsequence/utils@0.36.5 + +## 0.36.4 + +### Patch Changes + +- Updating list of chain ids to include other ethereum compatible chains +- Updated dependencies + - @0xsequence/abi@0.36.4 + - @0xsequence/network@0.36.4 + - @0xsequence/utils@0.36.4 + +## 0.36.3 + +### Patch Changes + +- provider: pass connect options to prompter methods +- Updated dependencies + - @0xsequence/abi@0.36.3 + - @0xsequence/network@0.36.3 + - @0xsequence/utils@0.36.3 + +## 0.36.2 + +### Patch Changes + +- transactions: Setting target to 0x0 when empty to during SequenceTxAbiEncode +- Updated dependencies + - @0xsequence/abi@0.36.2 + - @0xsequence/network@0.36.2 + - @0xsequence/utils@0.36.2 + +## 0.36.1 + +### Patch Changes + +- metadata: update client with more fields +- Updated dependencies + - @0xsequence/abi@0.36.1 + - @0xsequence/network@0.36.1 + - @0xsequence/utils@0.36.1 + +## 0.36.0 + +### Minor Changes + +- relayer, wallet: fee quote support + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.36.0 + - @0xsequence/network@0.36.0 + - @0xsequence/utils@0.36.0 + +## 0.35.12 + +### Patch Changes + +- provider: rename wallet.commands to wallet.utils +- Updated dependencies + - @0xsequence/abi@0.35.12 + - @0xsequence/network@0.35.12 + - @0xsequence/utils@0.35.12 + +## 0.35.11 + +### Patch Changes + +- provider/utils: smoother message validation +- Updated dependencies + - @0xsequence/abi@0.35.11 + - @0xsequence/network@0.35.11 + - @0xsequence/utils@0.35.11 + +## 0.35.10 + +### Patch Changes + +- upgrade deps +- Updated dependencies + - @0xsequence/abi@0.35.10 + - @0xsequence/network@0.35.10 + - @0xsequence/utils@0.35.10 + +## 0.35.9 + +### Patch Changes + +- provider: window-transport override event handlers with new wallet instance +- Updated dependencies + - @0xsequence/abi@0.35.9 + - @0xsequence/network@0.35.9 + - @0xsequence/utils@0.35.9 + +## 0.35.8 + +### Patch Changes + +- provider: async wallet sign in improvements +- Updated dependencies + - @0xsequence/abi@0.35.8 + - @0xsequence/network@0.35.8 + - @0xsequence/utils@0.35.8 + +## 0.35.7 + +### Patch Changes + +- config: cache wallet configs +- Updated dependencies + - @0xsequence/abi@0.35.7 + - @0xsequence/network@0.35.7 + - @0xsequence/utils@0.35.7 + +## 0.35.6 + +### Patch Changes + +- provider: support async signin of wallet request handler +- Updated dependencies + - @0xsequence/abi@0.35.6 + - @0xsequence/network@0.35.6 + - @0xsequence/utils@0.35.6 + +## 0.35.5 + +### Patch Changes + +- wallet: skip threshold check during fee estimation +- Updated dependencies + - @0xsequence/abi@0.35.5 + - @0xsequence/network@0.35.5 + - @0xsequence/utils@0.35.5 + +## 0.35.4 + +### Patch Changes + +- - browser extension mode, center window +- Updated dependencies + - @0xsequence/abi@0.35.4 + - @0xsequence/network@0.35.4 + - @0xsequence/utils@0.35.4 + +## 0.35.3 + +### Patch Changes + +- - update window position when in browser extension mode +- Updated dependencies + - @0xsequence/abi@0.35.3 + - @0xsequence/network@0.35.3 + - @0xsequence/utils@0.35.3 + +## 0.35.2 + +### Patch Changes + +- - provider: WindowMessageHandler accept optional windowHref +- Updated dependencies + - @0xsequence/abi@0.35.2 + - @0xsequence/network@0.35.2 + - @0xsequence/utils@0.35.2 + +## 0.35.1 + +### Patch Changes + +- wallet: update config on undeployed too +- Updated dependencies + - @0xsequence/abi@0.35.1 + - @0xsequence/network@0.35.1 + - @0xsequence/utils@0.35.1 + +## 0.35.0 + +### Minor Changes + +- - config: add buildStubSignature + - provider: add checks to signing cases for wallet deployment and config statuses + - provider: add prompt for wallet deployment + - relayer: add BaseRelayer.prependWalletDeploy + - relayer: add Relayer.feeOptions + - relayer: account for wallet deployment in fee estimation + - transactions: add fromTransactionish + - wallet: add Account.prependConfigUpdate + - wallet: add Account.getFeeOptions + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.35.0 + - @0xsequence/network@0.35.0 + - @0xsequence/utils@0.35.0 + +## 0.34.0 + +### Minor Changes + +- - upgrade deps + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.34.0 + - @0xsequence/network@0.34.0 + - @0xsequence/utils@0.34.0 + +## 0.31.0 + +### Minor Changes + +- - upgrading to ethers v5.5 + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.31.0 + - @0xsequence/network@0.31.0 + - @0xsequence/utils@0.31.0 + +## 0.30.0 + +### Minor Changes + +- - upgrade most deps + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.30.0 + - @0xsequence/network@0.30.0 + - @0xsequence/utils@0.30.0 + +## 0.29.8 + +### Patch Changes + +- update api +- Updated dependencies [undefined] + - @0xsequence/abi@0.29.8 + - @0xsequence/network@0.29.8 + - @0xsequence/utils@0.29.8 + +## 0.29.6 + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/network@0.29.6 + +## 0.29.0 + +### Minor Changes + +- major architectural changes in Sequence design + + - only one API instance, API is no longer a per-chain service + - separate per-chain indexer service, API no longer handles indexing + - single contract metadata service, API no longer serves metadata + + chaind package has been removed, indexer and metadata packages have been added + + stronger typing with new explicit ChainId type + + multicall fixes and improvements + + forbid "wait" transactions in sendTransactionBatch calls + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/network@0.29.0 + - @0xsequence/abi@0.29.0 + - @0xsequence/utils@0.29.0 + +## 0.28.0 + +### Minor Changes + +- extension provider + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.28.0 + - @0xsequence/network@0.28.0 + - @0xsequence/utils@0.28.0 + +## 0.27.0 + +### Minor Changes + +- Add requireFreshSigner lib to sessions + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.27.0 + - @0xsequence/network@0.27.0 + - @0xsequence/utils@0.27.0 + +## 0.25.1 + +### Patch Changes + +- Fix build typescrypt issue +- Updated dependencies [undefined] + - @0xsequence/abi@0.25.1 + - @0xsequence/network@0.25.1 + - @0xsequence/utils@0.25.1 + +## 0.25.0 + +### Minor Changes + +- 10c8af8: Add estimator package + Fix multicall few calls bug + +### Patch Changes + +- Updated dependencies [10c8af8] + - @0xsequence/abi@0.25.0 + - @0xsequence/network@0.25.0 + - @0xsequence/utils@0.25.0 + +## 0.23.0 + +### Minor Changes + +- - relayer: offer variety of gas fee options from the relayer service" + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.23.0 + - @0xsequence/network@0.23.0 + - @0xsequence/utils@0.23.0 + +## 0.22.2 + +### Patch Changes + +- e1c109e: Fix authProof on expired sessions +- Updated dependencies [e1c109e] + - @0xsequence/abi@0.22.2 + - @0xsequence/network@0.22.2 + - @0xsequence/utils@0.22.2 + +## 0.22.1 + +### Patch Changes + +- transport session cache +- Updated dependencies [undefined] + - @0xsequence/abi@0.22.1 + - @0xsequence/network@0.22.1 + - @0xsequence/utils@0.22.1 + +## 0.22.0 + +### Minor Changes + +- e667b65: Expose all relayer options on networks + +### Patch Changes + +- Updated dependencies [e667b65] + - @0xsequence/abi@0.22.0 + - @0xsequence/network@0.22.0 + - @0xsequence/utils@0.22.0 + +## 0.21.5 + +### Patch Changes + +- Give priority to metaTxnId returned by relayer +- Updated dependencies [undefined] + - @0xsequence/abi@0.21.5 + - @0xsequence/network@0.21.5 + - @0xsequence/utils@0.21.5 + +## 0.21.4 + +### Patch Changes + +- Add has enough signers method +- Updated dependencies [undefined] + - @0xsequence/abi@0.21.4 + - @0xsequence/network@0.21.4 + - @0xsequence/utils@0.21.4 + +## 0.21.3 + +### Patch Changes + +- add window session cache +- Updated dependencies [undefined] + - @0xsequence/abi@0.21.3 + - @0xsequence/network@0.21.3 + - @0xsequence/utils@0.21.3 + +## 0.21.2 + +### Patch Changes + +- exception handlind in relayer +- Updated dependencies [undefined] + - @0xsequence/abi@0.21.2 + - @0xsequence/network@0.21.2 + - @0xsequence/utils@0.21.2 + +## 0.21.0 + +### Minor Changes + +- - fix gas estimation on wallets with large number of signers + - update to session handling and wallet config construction upon auth + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.21.0 + - @0xsequence/network@0.21.0 + - @0xsequence/utils@0.21.0 + +## 0.19.3 + +### Patch Changes + +- jwtAuth visibility, package version sync +- Updated dependencies [undefined] + - @0xsequence/abi@0.19.3 + - @0xsequence/network@0.19.3 + - @0xsequence/utils@0.19.3 + +## 0.19.2 + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.19.2 + +## 0.19.0 + +### Minor Changes + +- - provider, improve dapp / wallet transport io + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.19.0 + - @0xsequence/network@0.19.0 + - @0xsequence/utils@0.19.0 + +## 0.18.0 + +### Minor Changes + +- relayer improvements and pending transaction handling + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.18.0 + - @0xsequence/network@0.18.0 + - @0xsequence/utils@0.18.0 + +## 0.16.0 + +### Minor Changes + +- relayer as its own service separate from chaind + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.16.0 + - @0xsequence/network@0.16.0 + - @0xsequence/utils@0.16.0 + +## 0.15.1 + +### Patch Changes + +- update api clients +- Updated dependencies [undefined] + - @0xsequence/abi@0.15.1 + - @0xsequence/network@0.15.1 + - @0xsequence/utils@0.15.1 + +## 0.14.3 + +### Patch Changes + +- Fix 0xSequence relayer dependencies +- Updated dependencies [undefined] + - @0xsequence/abi@0.14.3 + - @0xsequence/network@0.14.3 + - @0xsequence/utils@0.14.3 + +## 0.14.2 + +### Patch Changes + +- Add debug logs to rpc-relayer +- Updated dependencies [undefined] + - @0xsequence/abi@0.14.2 + - @0xsequence/network@0.14.2 + - @0xsequence/utils@0.14.2 + +## 0.14.0 + +### Minor Changes + +- update sequence utils finder which includes optimization + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.14.0 + - @0xsequence/network@0.14.0 + - @0xsequence/utils@0.14.0 + +## 0.13.0 + +### Minor Changes + +- Update SequenceUtils deployed contract + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.13.0 + - @0xsequence/network@0.13.0 + - @0xsequence/utils@0.13.0 + +## 0.12.1 + +### Patch Changes + +- npm bump +- Updated dependencies [undefined] + - @0xsequence/abi@0.12.1 + - @0xsequence/network@0.12.1 + - @0xsequence/utils@0.12.1 + +## 0.12.0 + +### Minor Changes + +- provider: improvements to window transport + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.12.0 + - @0xsequence/network@0.12.0 + - @0xsequence/utils@0.12.0 + +## 0.11.4 + +### Patch Changes + +- update api client +- Updated dependencies [undefined] + - @0xsequence/abi@0.11.4 + - @0xsequence/network@0.11.4 + - @0xsequence/utils@0.11.4 + +## 0.11.3 + +### Patch Changes + +- improve openWindow state options handling +- Updated dependencies [undefined] + - @0xsequence/abi@0.11.3 + - @0xsequence/network@0.11.3 + - @0xsequence/utils@0.11.3 + +## 0.11.2 + +### Patch Changes + +- Fix multicall proxy scopes +- Updated dependencies [undefined] + - @0xsequence/abi@0.11.2 + - @0xsequence/network@0.11.2 + - @0xsequence/utils@0.11.2 + +## 0.11.1 + +### Patch Changes + +- Add support for dynamic and nested signatures +- Updated dependencies [undefined] + - @0xsequence/abi@0.11.1 + - @0xsequence/network@0.11.1 + - @0xsequence/utils@0.11.1 + +## 0.11.0 + +### Minor Changes + +- Update wallet context to 1.7 contracts + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.11.0 + - @0xsequence/network@0.11.0 + - @0xsequence/utils@0.11.0 + +## 0.10.9 + +### Patch Changes + +- add support for public addresses as signers in session.open +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.9 + - @0xsequence/network@0.10.9 + - @0xsequence/utils@0.10.9 + +## 0.10.8 + +### Patch Changes + +- Multicall production configuration +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.8 + - @0xsequence/network@0.10.8 + - @0xsequence/utils@0.10.8 + +## 0.10.7 + +### Patch Changes + +- allow provider transport to force disconnect +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.7 + - @0xsequence/network@0.10.7 + - @0xsequence/utils@0.10.7 + +## 0.10.6 + +### Patch Changes + +- - fix getWalletState method +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.6 + - @0xsequence/network@0.10.6 + - @0xsequence/utils@0.10.6 + +## 0.10.5 + +### Patch Changes + +- update relayer gas refund options +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.5 + - @0xsequence/network@0.10.5 + - @0xsequence/utils@0.10.5 + +## 0.10.4 + +### Patch Changes + +- Update api proto +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.4 + - @0xsequence/network@0.10.4 + - @0xsequence/utils@0.10.4 + +## 0.10.3 + +### Patch Changes + +- Fix loading config cross-chain +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.3 + - @0xsequence/network@0.10.3 + - @0xsequence/utils@0.10.3 + +## 0.10.2 + +### Patch Changes + +- - message digest fix +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.2 + - @0xsequence/network@0.10.2 + - @0xsequence/utils@0.10.2 + +## 0.10.1 + +### Patch Changes + +- upgrade deps +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.1 + - @0xsequence/network@0.10.1 + - @0xsequence/utils@0.10.1 + +## 0.10.0 + +### Minor Changes + +- Deployed new contracts with ERC1271 signer support + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.0 + - @0xsequence/network@0.10.0 + - @0xsequence/utils@0.10.0 + +## 0.9.6 + +### Patch Changes + +- Update ABIs for latest sequence contracts +- Updated dependencies [undefined] + - @0xsequence/network@0.9.6 + - @0xsequence/utils@0.9.6 + - @0xsequence/abi@0.9.6 + +## 0.9.5 + +### Patch Changes + +- Implemented session class +- Updated dependencies [undefined] + - @0xsequence/network@0.9.5 + - @0xsequence/utils@0.9.5 + +## 0.9.3 + +### Patch Changes + +- - minor improvements +- Updated dependencies [undefined] + - @0xsequence/abi@0.9.3 + - @0xsequence/network@0.9.3 + - @0xsequence/utils@0.9.3 + +## 0.9.1 + +### Patch Changes + +- - patch bump +- Updated dependencies [undefined] + - @0xsequence/abi@0.9.1 + - @0xsequence/network@0.9.1 + - @0xsequence/utils@0.9.1 + +## 0.9.0 + +### Minor Changes + +- - provider transport hardening + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.9.0 + - @0xsequence/network@0.9.0 + - @0xsequence/utils@0.9.0 + +## 0.8.5 + +### Patch Changes + +- - use latest wallet-contracts +- Updated dependencies [undefined] + - @0xsequence/abi@0.8.5 + - @0xsequence/network@0.8.5 + - @0xsequence/utils@0.8.5 + +## 0.8.4 + +### Patch Changes + +- - minor improvements, name updates and comments +- Updated dependencies [undefined] + - @0xsequence/abi@0.8.4 + - @0xsequence/network@0.8.4 + - @0xsequence/utils@0.8.4 + +## 0.8.3 + +### Patch Changes + +- - refinements + + - normalize signer address in config + + - provider: getWalletState() method to WalletProvider + +- Updated dependencies [undefined] + - @0xsequence/abi@0.8.3 + - @0xsequence/network@0.8.3 + - @0xsequence/utils@0.8.3 + +## 0.8.2 + +### Patch Changes + +- - field rename and ethauth dependency bump +- Updated dependencies [undefined] + - @0xsequence/abi@0.8.2 + - @0xsequence/network@0.8.2 + - @0xsequence/utils@0.8.2 + +## 0.8.1 + +### Patch Changes + +- - variety of optimizations +- Updated dependencies [undefined] + - @0xsequence/abi@0.8.1 + - @0xsequence/network@0.8.1 + - @0xsequence/utils@0.8.1 + +## 0.8.0 + +### Minor Changes + +- - changeset fix + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.8.0 + - @0xsequence/network@0.8.0 + - @0xsequence/utils@0.8.0 + +## 0.7.2 + +### Patch Changes + +- package.json fix + +## 0.7.0 + +### Patch Changes + +- 6f11ed7: sequence.js, init release +- Updated dependencies [6f11ed7] + - @0xsequence/abi@0.7.0 + - @0xsequence/network@0.7.0 + - @0xsequence/utils@0.7.0 diff --git a/packages/multicall/README.md b/packages/multicall/README.md new file mode 100644 index 0000000000..7a16973da1 --- /dev/null +++ b/packages/multicall/README.md @@ -0,0 +1,169 @@ +@0xsequence/multicall +===================== + +An Ethereum provider wrapper that aggregates multiple operations in one, reducing the network load +on clients and servers. The project aims to be plug-and-play with existing ether.js integrations. + +For more info see [0xsequence project page](https://github.com/0xsequence/sequence.js). + +Inspired by MakerDAO [Multicall.js](https://github.com/makerdao/multicall.js). + +## Installation + +`yarn add @0xsequence/multicall` + +or + +`npm install --save @0xsequence/multicall` + +## Usage + +Sequence Multicall works by implementing `ethers.Provider` and wrapping an existing `ethers.Provider`; this +wrapped provider can transparently aggregate supported JSON-RPC calls. + +```ts +import { providers } from '@0xsequence/multicall' +import { providers as ethersProviders } from 'ethers' + +// MulticallProvider can wrap and extend with multicall functionality +// any ethers.js provider, it's not limited to JsonRpcProvider +const provider = new providers.MulticallProvider(new ethersProviders.JsonRpcProvider("https://cloudflare-eth.com/")) +``` + +### Making aggregated calls + +Multicall leverages RPC calls' asynchronous nature to perform the aggregation; it implements a buffer +with a configurable 50ms delay and aggregates all operations received within that window. + +Explicit usage of the functionality can be forced by making multiple calls using `Promise.all`. + +```ts +// Both requests are aggregated into a single RPC call +const [balance, supply] = await Promise.all([ + provider.getBalance("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"), + dai.totalSupply() +]) +``` + +Methods can also be aggregated without using `Promise.all`, as long as there are no `await` in between calls. + +```ts +// DON'T +const balance = await provider.getBalance("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2") +const supply = await dai.totalSupply() + +// DO +const balancePromise = provider.getBalance("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2") +const supplyPromise = dai.totalSupply() + +const balance = await balancePromise +const supply = await supplyPromise +``` + +## Using the provider + +The `MulticallProvider` instance can be used in any context where an ethers.Provider is expected, including +contract interfaces, middlewares, or libraries; all calls to the same provider are candidates for aggregation. + +```ts +// Uses a single JSON-RPC call + +const abi = [ + "function balanceOf(address owner) view returns (uint256)", + "function totalSupply() view returns (uint256)", + "function symbol() view returns (string)", +] + +const uni = new ethers.Contract("0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984", abi, provider) +const dai = new ethers.Contract("0x6B175474E89094C44Da98b954EedeAC495271d0F", abi, provider) + +const uniTotalSupplyPromise = uni.totalSupply() + +const [totalSupply, balance, daiSymbol, uniSymbol] = await Promise.all([ + dai.totalSupply(), + dai.balanceOf("0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B"), + dai.symbol(), + uni.symbol() +]) + +const uniTotalSupply = await uniTotalSupplyPromise +``` + + +### Supported methods + +The following JSON-RPC methods are supported for call aggregation: + +-------------------------------------------------------------------------------------------------------------------- +| Method | Supported | Implemented | Notes | +|-----------------|-----------|-------------|----------------------------------------------------------------------| +| eth_call | Yes | Yes | Requests containing `from`, `gasPrice` or `value` aren't aggregated. | +| eth_getBalance | Yes | Yes | | +| eth_getCode | Yes | Yes | | +| eth_blockNumber | Yes | No | | +-------------------------------------------------------------------------------------------------------------------- + +All other RPC methods that are part of the standard are forwarded to the parent provider without any modifications. + +> āš ļø Using mixed blocktags will make some calls skip aggregation. + + +### Error handling + +The multicall wrapper is designed to work with any exiting ether.js integration transparently; this includes error +handling for cases when multicall fails, is wrongly configured, or the contract does not support it. + +JSON-RPC Calls are forwarded to the parent provider on any of the following cases: +- Multicall contract is not deployed on the given network +- Individual call fails (only failed calls are forwarded) +- Batch call fails (all calls are forwarded) +- Invalid RPC Call (invalid address, etc.) +- Mixed blocktags within a batch +- Unsupported special parameters (see supported methods) +- Unsupported method + + +## Configuration + +The MulticallProvider comes with a pre-defined configuration; it's ready to work out-of-the-box on +the networks: Mainnet, Ropsten, Kovan, Rinkeby, Gƶrli, and Matic (Mainnet). + +```ts +DEFAULT_CONF = { + batchSize: 50, + timeWindow: 50, // ms + contract: "0xd130B43062D875a4B7aF3f8fc036Bc6e9D3E1B3E" +} +``` +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +| Parameter | Required | Description | +|------------|----------|------------------------------------------------------------------------------------------------------------------------------------------------------| +| batchSize | Yes | Defines the maximum number of calls to batch into a single JSON-RPC call. | +| timeWindow | Yes | Defines the time each call is held on buffer waiting for subsequent calls before aggregation, use 0 for "next js tick". | +| contract | Yes | Instance of MultiCallUtils contract, see: https://github.com/0xsequence/wallet-contracts/blob/master/src/contracts/modules/utils/MultiCallUtils.sol | +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + + +### Supported networks + +The utility contract is `0xd130B43062D875a4B7aF3f8fc036Bc6e9D3E1B3E`, it has been deployed using an [Universal Deployer](https://gist.github.com/Agusx1211/de05dabf918d448d315aa018e2572031) and it uses the same address on all networks. It can be used on any of these chains without configuration changes. + +------------------------------------------------------------------------------------ +| Network | Address | Deployed | +|:-------------------------|:-------------------------------------------|:---------| +| Mainnet | 0xd130B43062D875a4B7aF3f8fc036Bc6e9D3E1B3E | Yes | +| Gƶrli | 0xd130B43062D875a4B7aF3f8fc036Bc6e9D3E1B3E | Yes | +| Ropsten | 0xd130B43062D875a4B7aF3f8fc036Bc6e9D3E1B3E | Yes | +| Rinkeby | 0xd130B43062D875a4B7aF3f8fc036Bc6e9D3E1B3E | Yes | +| Kovan | 0xd130B43062D875a4B7aF3f8fc036Bc6e9D3E1B3E | Yes | +| Polygon | 0xd130B43062D875a4B7aF3f8fc036Bc6e9D3E1B3E | Yes | +| Mumbai (Polygon testnet) | 0xd130B43062D875a4B7aF3f8fc036Bc6e9D3E1B3E | Yes | +| Arbitrum One | 0xd130B43062D875a4B7aF3f8fc036Bc6e9D3E1B3E | Yes | +| Arbitrum testnet | 0xd130B43062D875a4B7aF3f8fc036Bc6e9D3E1B3E | Yes | +| Arbitrum Gƶrli testnet | 0xd130B43062D875a4B7aF3f8fc036Bc6e9D3E1B3E | Yes | +| Avalanche | 0xd130B43062D875a4B7aF3f8fc036Bc6e9D3E1B3E | Yes | +| BSC | 0xd130B43062D875a4B7aF3f8fc036Bc6e9D3E1B3E | Yes | +------------------------------------------------------------------------------------ + +It can be deployed on any network that supports the `CREATE2` opcode. See https://blockscan.com/address/0xd130B43062D875a4B7aF3f8fc036Bc6e9D3E1B3E for live list. + diff --git a/packages/multicall/package.json b/packages/multicall/package.json new file mode 100644 index 0000000000..5aa4eadb9d --- /dev/null +++ b/packages/multicall/package.json @@ -0,0 +1,39 @@ +{ + "name": "@0xsequence/multicall", + "version": "2.0.0", + "description": "multicall sub-package for Sequence", + "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/multicall", + "source": "src/index.ts", + "main": "dist/0xsequence-multicall.cjs.js", + "module": "dist/0xsequence-multicall.esm.js", + "author": "Horizon Blockchain Games", + "license": "Apache-2.0", + "scripts": { + "test": "echo 'note, run local-test script instead, as test command is flakey'", + "local-test": "NODE_OPTIONS='--import tsx' mocha --timeout 10000 tests/**/*.spec.ts", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@0xsequence/abi": "workspace:*", + "@0xsequence/network": "workspace:*", + "@0xsequence/utils": "workspace:*" + }, + "peerDependencies": { + "ethers": ">=5.5 < 6" + }, + "devDependencies": { + "@0xsequence/wallet-contracts": "^2.0.0", + "@ethersproject/providers": "^5.7.2", + "@types/web3-provider-engine": "^14.0.1", + "eth-json-rpc-middleware": "^9.0.1", + "ethers": "^5.7.2", + "ganache": "^7.5.0", + "json-rpc-engine": "^6.1.0", + "web3": "^1.8.1", + "web3-provider-engine": "^16.0.4" + }, + "files": [ + "src", + "dist" + ] +} diff --git a/packages/multicall/src/constants.ts b/packages/multicall/src/constants.ts new file mode 100644 index 0000000000..624c345edc --- /dev/null +++ b/packages/multicall/src/constants.ts @@ -0,0 +1,5 @@ +export enum JsonRpcMethod { + ethCall = 'eth_call', + ethGetBalance = 'eth_getBalance', + ethGetCode = 'eth_getCode' +} diff --git a/packages/multicall/src/index.ts b/packages/multicall/src/index.ts new file mode 100644 index 0000000000..a8b96096cc --- /dev/null +++ b/packages/multicall/src/index.ts @@ -0,0 +1,2 @@ +export { Multicall } from './multicall' +export * as providers from './providers' diff --git a/packages/multicall/src/multicall.ts b/packages/multicall/src/multicall.ts new file mode 100644 index 0000000000..be217f950a --- /dev/null +++ b/packages/multicall/src/multicall.ts @@ -0,0 +1,321 @@ +import { BigNumber, ethers } from 'ethers' +import { walletContracts } from '@0xsequence/abi' +import { JsonRpcMethod } from './constants' +import { BlockTag, eqBlockTag, parseBlockTag, partition, safeSolve } from './utils' +import { promisify, getRandomInt } from '@0xsequence/utils' +import { JsonRpcVersion, JsonRpcRequest, JsonRpcResponseCallback, JsonRpcHandlerFunc } from '@0xsequence/network' + +export type MulticallOptions = { + // number of calls to enqueue before calling. + batchSize: number + + // number of calls to batch within a time window (in milliseconds). If 0, will disable timeWindow. + timeWindow: number + + // contract is the address of the Sequence MultiCallUtils smart contract where + // the batched multicall is sent to an Ethereum node. + contract: string + + // logs details about aggregated calls + verbose: boolean +} + +type QueueEntry = { + request: JsonRpcRequest + callback: JsonRpcResponseCallback + next: JsonRpcHandlerFunc + error?: boolean + result?: JsonRpcResponseCallback +} + +const DefaultMulticallOptions = { + batchSize: 50, + timeWindow: 50, + // SequenceUtils: v2 + contract: '0xdbbFa3cB3B087B64F4ef5E3D20Dda2488AA244e6', + verbose: false +} + +export class Multicall { + public static DefaultOptions = { ...DefaultMulticallOptions } + + readonly batchableJsonRpcMethods = [JsonRpcMethod.ethCall, JsonRpcMethod.ethGetCode, JsonRpcMethod.ethGetBalance] + + readonly multicallInterface = new ethers.utils.Interface(walletContracts.sequenceUtils.abi) + + public options: MulticallOptions + + constructor(options?: Partial) { + this.options = options ? { ...Multicall.DefaultOptions, ...options } : Multicall.DefaultOptions + if (this.options.batchSize <= 0) throw new Error(`Invalid batch size of ${this.options.batchSize}`) + } + + private timeout: NodeJS.Timeout | undefined + private queue = [] as QueueEntry[] + + scheduleExecution = () => { + if (this.queue.length > 0) { + if (this.timeout) clearTimeout(this.timeout) + this.timeout = setTimeout(this.run, this.options.timeWindow) + } + } + + handle = (next: JsonRpcHandlerFunc, request: JsonRpcRequest, callback: JsonRpcResponseCallback) => { + // Schedule for batching and return + if (this.batchableJsonRpcMethods.find(m => m === request.method)) { + this.queue.push({ + request: request, + callback: callback, + next: next + }) + if (this.options.verbose) console.log('Scheduling call', request.method) + this.scheduleExecution() + return + } + + if (this.options.verbose) console.log('Forwarded call', request.method) + + // Move to next handler + return next(request, callback) + } + + run = async () => { + /* eslint-disable no-var */ + if (this.options.verbose) console.log('Processing multicall') + + // Read items from queue + const limit = Math.min(this.options.batchSize, this.queue.length) + if (limit === 0) { + if (this.options.verbose) console.log('Skip multicall, empty queue') + return + } + + // Skip multicall on single item + if (limit === 1) { + this.forward(this.queue[0]) + this.queue = [] + if (this.options.verbose) console.log('Skip multicall, single item') + return + } + + if (this.options.verbose) console.log('Resolving', limit) + + // Get batch from queue + var items = this.queue.slice(0, limit) + + // Update queue + this.queue = limit === this.queue.length ? [] : this.queue.slice(limit) + if (this.options.verbose) console.log('Updated queue', this.queue.length) + + if (this.queue.length !== 0) { + if (this.options.verbose) console.log('Scheduling next batch') + this.scheduleExecution() + } + + // Get next candidate + const next = items[0].next as JsonRpcHandlerFunc + let blockTag: BlockTag | undefined + + // Partition incompatible calls + var [items, discartItems] = partition(items, item => { + try { + // Mixed next callbacks + if (item.next !== next) return false + + switch (item.request.method) { + case JsonRpcMethod.ethCall: + // Unsupported eth_call parameters + if (item.request.params![0].from || item.request.params![0].gasPrice || item.request.params![0].value) { + return false + } + case JsonRpcMethod.ethGetBalance: + case JsonRpcMethod.ethGetCode: + // Mixed blockTags + const itemBlockTag = parseBlockTag(item.request.params![1]) + if (blockTag === undefined) blockTag = itemBlockTag + if (!eqBlockTag(itemBlockTag, blockTag)) return false + } + + return true + } catch { + return false + } + }) + + // Forward discarted items + // end execution if no items remain + if (discartItems.length !== 0) { + if (this.options.verbose) console.log('Forwarding incompatible calls', discartItems.length) + this.forward(discartItems) + if (items.length === 0) { + if (this.options.verbose) console.log('Skip multicall, all calls are incompatible') + return + } + } + + // Aggregate all calls + let callParams = items.map(v => { + try { + switch (v.request.method) { + case JsonRpcMethod.ethCall: + return { + delegateCall: false, + revertOnError: false, + target: v.request.params![0].to, + data: v.request.params![0].data, + gasLimit: v.request.params![0].gas ? v.request.params![0].gas : 0, + value: 0 + } + case JsonRpcMethod.ethGetCode: + return { + delegateCall: false, + revertOnError: false, + target: this.options.contract, + gasLimit: 0, + value: 0, + data: this.multicallInterface.encodeFunctionData(this.multicallInterface.getFunction('callCode'), [ + v.request.params![0] + ]) + } + case JsonRpcMethod.ethGetBalance: + return { + delegateCall: false, + revertOnError: false, + target: this.options.contract, + gasLimit: 0, + value: 0, + data: this.multicallInterface.encodeFunctionData(this.multicallInterface.getFunction('callBalanceOf'), [ + v.request.params![0] + ]) + } + default: + return null + } + } catch { + return null + } + }) + + // Filter calls with enconding errors and forward items + var [items, discartItems] = partition(items, (_, i: number) => callParams[i] !== undefined) + callParams = callParams.filter(c => c) + + if (discartItems.length !== 0) { + if (this.options.verbose) console.log('Forwarding calls on error', discartItems.length) + this.forward(discartItems) + if (items.length === 0) { + if (this.options.verbose) console.log('Skip multicall, all calls had encoding errors') + return + } + } + + // Encode multicall + let encodedCall: string + try { + if (this.options.verbose) console.log('Encoding multicall') + encodedCall = this.multicallInterface.encodeFunctionData(this.multicallInterface.getFunction('multiCall'), [callParams]) + } catch (err) { + if (this.options.verbose) console.warn('Error encoding multicall, forwarding one by one', err) + this.forward(items) + return + } + + // Forward single multicall rpc call + const reqId = getRandomInt() + + // TODO: fix types below.. + + const res = await safeSolve( + // @ts-ignore + promisify(next)({ + id: reqId!, + jsonrpc: JsonRpcVersion!, + method: JsonRpcMethod.ethCall!, + params: [ + { + to: this.options.contract!, + value: 0, + data: encodedCall! + }, + BigNumber.isBigNumber(blockTag) ? blockTag.toNumber() : blockTag + ] + // @ts-ignore + }), + e => ({ + jsonrpc: JsonRpcVersion!, + id: reqId!, + result: undefined, + error: e! + }) + ) + + // Error calling multicall + // Forward all calls to middleware + // @ts-ignore + if (res.error) { + if (this.options.verbose) console.warn('Error calling multicall, forwarding one by one', res.error) + return this.forward(items) + } + + // Decode result from multicall + let decoded: ethers.utils.Result + try { + // @ts-ignore + decoded = this.multicallInterface.decodeFunctionResult(this.multicallInterface.getFunction('multiCall'), res.result) + } catch (err) { + if (this.options.verbose) console.warn('Error decoding multicall result, forwarding one by one', err) + this.forward(items) + return + } + + // Send results for each request + // errors fallback through the middleware + if (this.options.verbose) console.log('Got response for', items.length) + items.forEach((item, index) => { + if (!decoded[0][index]) { + if (this.options.verbose) console.warn(`Multicall error for ${item.request.method} not found`) + this.forward(item) + } else { + switch (item.request.method) { + case JsonRpcMethod.ethCall: + item.callback(undefined, { + jsonrpc: item.request.jsonrpc!, + id: item.request.id!, + result: decoded[1][index] + }) + break + case JsonRpcMethod.ethGetCode: + item.callback(undefined, { + jsonrpc: item.request.jsonrpc!, + id: item.request.id!, + result: ethers.utils.defaultAbiCoder.decode(['bytes'], decoded[1][index])[0] + }) + break + case JsonRpcMethod.ethGetBalance: + item.callback(undefined, { + jsonrpc: item.request.jsonrpc!, + id: item.request.id!, + result: ethers.utils.defaultAbiCoder.decode(['uint256'], decoded[1][index])[0] + }) + break + } + } + }) + } + + private forward(entries: QueueEntry[] | QueueEntry) { + if (Array.isArray(entries)) { + entries.forEach(e => e.next(e.request, e.callback)) + } else { + entries.next(entries.request, entries.callback) + } + } + + static isMulticall(cand: any): cand is Multicall { + return cand && cand.handle !== undefined && cand.conf !== undefined && Multicall.isMulticallOptions(cand.options) + } + + static isMulticallOptions(cand: any): cand is MulticallOptions { + return cand !== undefined && cand.batchSize !== undefined && cand.timeWindow !== undefined && cand.contract !== undefined + } +} diff --git a/packages/multicall/src/providers/external-provider.ts b/packages/multicall/src/providers/external-provider.ts new file mode 100644 index 0000000000..e9390369d3 --- /dev/null +++ b/packages/multicall/src/providers/external-provider.ts @@ -0,0 +1,44 @@ +import { providers } from 'ethers' +import { Multicall, MulticallOptions } from '../multicall' +import { JsonRpcRequest, JsonRpcResponseCallback } from '@0xsequence/network' + +type ExternalProvider = providers.ExternalProvider + +export class MulticallExternalProvider implements ExternalProvider { + private multicall: Multicall + + constructor( + private provider: providers.ExternalProvider, + multicall?: Multicall | Partial + ) { + this.multicall = Multicall.isMulticall(multicall) ? multicall : new Multicall(multicall!) + + if (provider.send) { + const next = async (req: JsonRpcRequest, callback: JsonRpcResponseCallback) => { + provider.send!(req, callback) + } + + ;(this as any).send = (request: JsonRpcRequest, callback: JsonRpcResponseCallback) => { + this.multicall.handle(next, request, callback) + } + } + + if (provider.sendAsync) { + const next = async (req: JsonRpcRequest, callback: JsonRpcResponseCallback) => { + provider.sendAsync!(req, callback) + } + + ;(this as any).sendAsync = (request: JsonRpcRequest, callback: JsonRpcResponseCallback) => { + this.multicall.handle(next, request, callback) + } + } + } + + public get isMetaMask() { + return this.provider.isMetaMask + } + + public get isStatus() { + return this.provider.isStatus + } +} diff --git a/packages/multicall/src/providers/index.ts b/packages/multicall/src/providers/index.ts new file mode 100644 index 0000000000..45ab3938e8 --- /dev/null +++ b/packages/multicall/src/providers/index.ts @@ -0,0 +1,3 @@ +export * from './provider' +export * from './external-provider' +export * from './provider-middleware' diff --git a/packages/multicall/src/providers/provider-middleware.ts b/packages/multicall/src/providers/provider-middleware.ts new file mode 100644 index 0000000000..0bda937aa5 --- /dev/null +++ b/packages/multicall/src/providers/provider-middleware.ts @@ -0,0 +1,11 @@ +import { Multicall, MulticallOptions } from '../multicall' +import { JsonRpcRequest, JsonRpcResponseCallback, JsonRpcHandlerFunc, JsonRpcMiddleware } from '@0xsequence/network' + +export const multicallMiddleware = + (multicall?: Multicall | Partial): JsonRpcMiddleware => + (next: JsonRpcHandlerFunc) => { + const lib = Multicall.isMulticall(multicall) ? multicall : new Multicall(multicall!) + return (request: JsonRpcRequest, callback: JsonRpcResponseCallback) => { + return lib.handle(next, request, callback) + } + } diff --git a/packages/multicall/src/providers/provider.ts b/packages/multicall/src/providers/provider.ts new file mode 100644 index 0000000000..199ddf5d42 --- /dev/null +++ b/packages/multicall/src/providers/provider.ts @@ -0,0 +1,119 @@ +import { ethers, BigNumber, utils } from 'ethers' +import { promisify, getRandomInt } from '@0xsequence/utils' +import { Multicall, MulticallOptions } from '../multicall' +import { JsonRpcMethod } from '../constants' +import { JsonRpcVersion, JsonRpcRequest, JsonRpcResponseCallback } from '@0xsequence/network' + +export const ProxyMethods = [ + 'getNetwork', + 'getBlockNumber', + 'getGasPrice', + 'getTransactionCount', + 'getStorageAt', + 'sendTransaction', + 'estimateGas', + 'getBlock', + 'getTransaction', + 'getTransactionReceipt', + 'getLogs', + 'emit', + 'litenerCount', + 'addListener', + 'removeListener', + 'waitForTransaction', + 'detectNetwork', + 'getBlockWithTransactions' +] + +export class MulticallProvider extends ethers.providers.BaseProvider { + private multicall: Multicall + + constructor( + private provider: ethers.providers.Provider, + multicall?: Multicall | Partial + ) { + super(provider.getNetwork()) + + this.listenerCount = provider.listenerCount.bind(provider) + this.multicall = Multicall.isMulticall(multicall) ? multicall : new Multicall(multicall) + + ProxyMethods.forEach(m => { + if ((provider as any)[m] !== undefined) { + ;(this as any)[m] = (...args: any) => (provider as any)[m](...args) + } + }) + } + + getResolver = async (name: string | Promise) => { + const provider = this.provider as ethers.providers.BaseProvider + + if (provider.getResolver) { + const ogResolver = await provider.getResolver(await name) + if (!ogResolver) return null + return new ethers.providers.Resolver(this as any, ogResolver.address, ogResolver.name) + } + + return provider.getResolver(await name) + } + + next = async (req: JsonRpcRequest, callback: JsonRpcResponseCallback) => { + try { + switch (req.method) { + case JsonRpcMethod.ethCall: + this.callback(req, callback, await this.provider.call(req.params![0], req.params![1])) + break + + case JsonRpcMethod.ethGetCode: + this.callback(req, callback, await this.provider.getCode(req.params![0], req.params![1])) + break + + case JsonRpcMethod.ethGetBalance: + this.callback(req, callback, await this.provider.getBalance(req.params![0], req.params![1])) + break + } + } catch (e) { + this.callback(req, callback, undefined, e) + } + } + + private callback(req: JsonRpcRequest, callback: JsonRpcResponseCallback, resp: any, err?: any) { + callback(err, { + jsonrpc: JsonRpcVersion, + id: req.id!, + result: resp, + error: err + }) + } + + async call( + transaction: utils.Deferrable, + blockTag?: string | number | Promise + ): Promise { + return this.rpcCall(JsonRpcMethod.ethCall, transaction, blockTag) + } + + async getCode( + addressOrName: string | Promise, + blockTag?: string | number | Promise + ): Promise { + return this.rpcCall(JsonRpcMethod.ethGetCode, addressOrName, blockTag) + } + + async getBalance( + addressOrName: string | Promise, + blockTag?: string | number | Promise + ): Promise { + return this.rpcCall(JsonRpcMethod.ethGetBalance, addressOrName, blockTag) + } + + async rpcCall(method: string, ...params: any[]): Promise { + const reqId = getRandomInt() + const resp = await promisify(this.multicall.handle)(this.next, { + jsonrpc: JsonRpcVersion, + id: reqId, + method: method, + params: params + }) + return resp!.result + } +} diff --git a/packages/multicall/src/types.ts b/packages/multicall/src/types.ts new file mode 100644 index 0000000000..7d665bb125 --- /dev/null +++ b/packages/multicall/src/types.ts @@ -0,0 +1,8 @@ +export type Call = () => Promise + +export type CallResult = { + call: Call + success: boolean + result: Array + outputs?: Array +} diff --git a/packages/multicall/src/utils.ts b/packages/multicall/src/utils.ts new file mode 100644 index 0000000000..48557bbc54 --- /dev/null +++ b/packages/multicall/src/utils.ts @@ -0,0 +1,47 @@ +import { BigNumber, BigNumberish } from 'ethers' + +export async function safeSolve(promise: Promise, def: T | ((e: any) => T)): Promise { + try { + return await promise + } catch (e) { + const d = def instanceof Function ? def(e) : def + return d + } +} + +export function partition(array: T[], callback: (v: T, i: number) => boolean): [T[], T[]] { + return array.reduce( + function (result, element, i) { + callback(element, i) ? result[0].push(element) : result[1].push(element) + return result + }, + [[] as any[], [] as any[]] + ) +} + +export type BlockTag = 'earliest' | 'latest' | 'pending' | BigNumber + +export function parseBlockTag(cand: string | BigNumberish | undefined): BlockTag { + if (cand === undefined) return 'latest' + + switch (cand) { + case 'earliest': + case 'latest': + case 'pending': + return cand + } + + return BigNumber.from(cand) +} + +export function eqBlockTag(a: BlockTag, b: BlockTag): boolean { + if (a === b) return true + + if (BigNumber.isBigNumber(a)) { + if (BigNumber.isBigNumber(b)) return a.eq(b) + return false + } + + if (BigNumber.isBigNumber(b)) return false + return a === b +} diff --git a/packages/multicall/tests/multicall.spec.ts b/packages/multicall/tests/multicall.spec.ts new file mode 100644 index 0000000000..0a00f97675 --- /dev/null +++ b/packages/multicall/tests/multicall.spec.ts @@ -0,0 +1,600 @@ +import { ethers, providers, Signer } from 'ethers' +import * as Ganache from 'ganache' +import { CallReceiverMock } from '@0xsequence/wallet-contracts' +import { JsonRpcRouter, JsonRpcExternalProvider } from '@0xsequence/network' + +import chaiAsPromised from 'chai-as-promised' +import * as chai from 'chai' +import { MulticallExternalProvider, multicallMiddleware, MulticallProvider } from '../src/providers' +import { SpyProxy } from './utils' +import { getRandomInt } from '@0xsequence/utils' +import { JsonRpcMethod } from '../src/constants' +import { MulticallOptions, Multicall } from '../src/multicall' + +const { JsonRpcEngine } = require('json-rpc-engine') + +const { providerAsMiddleware, providerFromEngine } = require('eth-json-rpc-middleware') + +const CallReceiverMockArtifact = require('@0xsequence/wallet-contracts/artifacts/contracts/mocks/CallReceiverMock.sol/CallReceiverMock.json') +const SequenceUtilsArtifact = require('@0xsequence/wallet-contracts/artifacts/contracts/modules/utils/SequenceUtils.sol/SequenceUtils.json') + +import Web3 from 'web3' +const { expect } = chai.use(chaiAsPromised) + +const GANACHE_PORT = 38546 + +type GanacheInstance = { + server?: any + serverUri?: string + provider?: providers.JsonRpcProvider + spyProxy?: providers.JsonRpcProvider + signer?: Signer + chainId?: number +} + +describe('Multicall integration', function () { + const ganache: GanacheInstance = {} + let provider: ethers.providers.Provider + let brokenProvider: ethers.providers.Provider + + let callMock: CallReceiverMock + + let utilsContract: ethers.Contract + + let callCounter = 0 + let accounts: { account: ethers.Wallet; secretKey: string; balance: string }[] + + before(async () => { + accounts = Array(5) + .fill(0) + .map(() => { + const account = ethers.Wallet.createRandom() + return { + account: account, + secretKey: account.privateKey, + balance: ethers.utils.hexlify(ethers.utils.randomBytes(9)) + } + }) + + // Deploy Ganache test env + ganache.chainId = 1337 + ganache.server = Ganache.server({ + chain: { + chainId: ganache.chainId, + networkId: ganache.chainId + }, + mnemonic: 'ripple axis someone ridge uniform wrist prosper there frog rate olympic knee', + accounts: accounts, + logging: { + verbose: false, + debug: false, + logger: undefined + } + }) + + // TODO: use hardhat instead like in wallet/wallet.spec.ts + + await ganache.server.listen(GANACHE_PORT) + ganache.serverUri = `http://127.0.0.1:${GANACHE_PORT}/` + ganache.provider = new providers.JsonRpcProvider(ganache.serverUri) + ganache.signer = ganache.provider.getSigner() + + utilsContract = await new ethers.ContractFactory( + SequenceUtilsArtifact.abi, + SequenceUtilsArtifact.bytecode, + ganache.signer + ).deploy(ethers.constants.AddressZero, ethers.constants.AddressZero) + + // Create provider + ganache.spyProxy = SpyProxy( + ganache.provider, + { + prop: 'call', + func: ganache.provider.call, + callback: () => { + callCounter++ + } + }, + { + prop: 'getCode', + func: ganache.provider.getCode, + callback: () => { + callCounter++ + } + }, + { + prop: 'getBalance', + func: ganache.provider.getBalance, + callback: () => { + callCounter++ + } + }, + { + prop: 'send', + func: ganache.provider.send, + callback: (method: string, _: any[]) => { + switch (method) { + case JsonRpcMethod.ethCall: + case JsonRpcMethod.ethGetCode: + case JsonRpcMethod.ethGetBalance: + callCounter++ + } + } + } + ) + + callMock = await createCallMock() + }) + + async function createCallMock() { + return (await new ethers.ContractFactory( + CallReceiverMockArtifact.abi, + CallReceiverMockArtifact.bytecode, + ganache.signer + ).deploy()) as unknown as CallReceiverMock + } + + const options = [ + { + name: 'Ether.js provider wrapper', + provider: (options?: Partial) => new MulticallProvider(ganache.spyProxy!, options) + }, + { + name: 'Json Rpc Router (Sequence)', + provider: (options?: Partial) => + new providers.Web3Provider( + new JsonRpcRouter([multicallMiddleware(options)], new JsonRpcExternalProvider(ganache.spyProxy!)) + ) + }, + { + name: 'Ether.js external provider wrapper', + provider: (conf?: Partial) => + new providers.Web3Provider(new MulticallExternalProvider(new JsonRpcExternalProvider(ganache.spyProxy!), conf)) + }, + { + name: 'Provider Engine (json-rpc-engine)', + provider: (conf?: Partial) => { + const engine = new JsonRpcEngine() + + engine.push(providerAsMiddleware(new MulticallExternalProvider(new JsonRpcExternalProvider(ganache.spyProxy!), conf))) + + return new ethers.providers.Web3Provider(providerFromEngine(engine)) + } + }, + { + name: 'Web3 external provider wrapper', + provider: (conf?: Partial) => { + const web3HttpProvider = new Web3.providers.HttpProvider(ganache.serverUri!) + const spyHttpProvider = SpyProxy(web3HttpProvider, { + prop: 'send', + func: web3HttpProvider.send, + callback: (p: any) => { + switch (p.method) { + case JsonRpcMethod.ethCall: + case JsonRpcMethod.ethGetCode: + case JsonRpcMethod.ethGetBalance: + callCounter++ + } + } + }) + return new providers.Web3Provider(new MulticallExternalProvider(spyHttpProvider as any, conf)) + } + }, + { + name: 'Ether.js provider wrapper (without proxy)', + provider: (options?: Partial) => new MulticallProvider(ganache.provider!, options), + ignoreCount: true + }, + { + name: 'Json Rpc Router (Sequence) (without proxy)', + provider: (options?: Partial) => + new providers.Web3Provider( + new JsonRpcRouter([multicallMiddleware(options)], new JsonRpcExternalProvider(ganache.provider!)) + ), + ignoreCount: true + }, + { + name: 'Ether.js external provider wrapper (without proxy)', + provider: (conf?: Partial) => + new providers.Web3Provider(new MulticallExternalProvider(new JsonRpcExternalProvider(ganache.provider!), conf)), + ignoreCount: true + }, + { + name: 'Provider Engine (json-rpc-engine) (without proxy)', + provider: (conf?: Partial) => { + const engine = new JsonRpcEngine() + + engine.push(providerAsMiddleware(new MulticallExternalProvider(new JsonRpcExternalProvider(ganache.provider!), conf))) + + return new ethers.providers.Web3Provider(providerFromEngine(engine)) + }, + ignoreCount: true + }, + { + name: 'Web3 external provider wrapper (without proxy)', + provider: (conf?: Partial) => { + const web3HttpProvider = new Web3.providers.HttpProvider(ganache.serverUri!) + const spyHttpProvider = SpyProxy(web3HttpProvider, { + prop: 'send', + func: web3HttpProvider.send, + callback: (p: any) => { + switch (p.method) { + case JsonRpcMethod.ethCall: + case JsonRpcMethod.ethGetCode: + case JsonRpcMethod.ethGetBalance: + callCounter++ + } + } + }) + return new providers.Web3Provider(new MulticallExternalProvider(web3HttpProvider as any, conf)) + }, + ignoreCount: true + } + ] + + beforeEach(() => { + callCounter = 0 + }) + + after(async () => { + ganache.server.close() + }) + + options.map(option => { + context(option.name, () => { + beforeEach(() => { + provider = option.provider({ contract: utilsContract.address, timeWindow: 500 }) + }) + + describe('Aggregate calls', async () => { + it('Should aggregate two calls', async () => { + await callMock.testCall(848487868126387, '0x001122') + + const multiCallMock = callMock.connect(provider) + const promiseA = multiCallMock.lastValA() + const promiseB = multiCallMock.lastValB() + + expect((await promiseA).toString()).to.equal('848487868126387') + expect(await promiseB).to.equal('0x001122') + + if (option.ignoreCount) return + expect(callCounter).to.equal(1) + }) + it('Should aggregate three calls', async () => { + const callMockB = await createCallMock() + + const randomData1 = ethers.utils.hexlify(ethers.utils.randomBytes(33)) + const randomData2 = ethers.utils.hexlify(ethers.utils.randomBytes(42)) + + await callMock.testCall(55122, randomData1) + await callMockB.testCall(2, randomData2) + + const multiCallMock = callMock.connect(provider) + const multiCallMockB = callMockB.connect(provider) + + const promiseA = multiCallMock.lastValA() + + const [valB, valC] = await Promise.all([multiCallMock.lastValB(), multiCallMockB.lastValB()]) + + expect((await promiseA).toString()).to.equal('55122') + expect(valB).to.equal(randomData1) + expect(valC).to.equal(randomData2) + + if (option.ignoreCount) return + expect(callCounter).to.equal(1) + }) + it('Should aggregate 62 calls in two batches', async () => { + const callMocks = await Promise.all( + Array(62) + .fill(0) + .map(() => createCallMock()) + ) + + const randomValues = Array(62) + .fill(0) + .map(() => ethers.utils.hexlify(ethers.utils.randomBytes(getRandomInt(0, 41)))) + await Promise.all(randomValues.map((v, i) => callMocks[i].testCall(0, v))) + + const values = await Promise.all(callMocks.map(c => c.connect(provider).lastValB())) + values.forEach((v, i) => expect(v).to.equal(randomValues[i])) + + if (option.ignoreCount) return + expect(callCounter).to.equal(2) + }) + it('Should aggregate in three batches :: queue > batch after first run', async () => { + const numberOfCalls = Multicall.DefaultOptions.batchSize * 2 + 2 + const mid = numberOfCalls / 2 // Split Promise.all to not break RPC calls + + let callMocks = await Promise.all( + Array(mid) + .fill(0) + .map(() => createCallMock()) + ) + callMocks = [ + ...callMocks, + ...(await Promise.all( + Array(mid) + .fill(0) + .map(() => createCallMock()) + )) + ] + + const randomValues = Array(numberOfCalls) + .fill(0) + .map(() => ethers.utils.hexlify(ethers.utils.randomBytes(getRandomInt(0, 41)))) + await Promise.all(randomValues.slice(0, mid).map((v, i) => callMocks[i].testCall(0, v))) + await Promise.all(randomValues.slice(mid).map((v, i) => callMocks[i + mid].testCall(0, v))) + + const values = await Promise.all(callMocks.map(c => c.connect(provider).lastValB())) + values.forEach((v, i) => expect(v).to.equal(randomValues[i])) + + if (option.ignoreCount) return + expect(callCounter).to.equal(3) + }) + it('Should call eth_getCode', async () => { + const code = await Promise.all([provider.getCode(callMock.address), provider.getCode(utilsContract.address)]) + + if (!option.ignoreCount) expect(callCounter).to.equal(1) + + const rawCode = await Promise.all([ + ganache.provider!.getCode(callMock.address), + ganache.provider!.getCode(utilsContract.address) + ]) + + expect(rawCode[0]).to.equal(code[0]) + expect(rawCode[1]).to.equal(code[1]) + }) + it('Should mix eth_getCode and eth_call', async () => { + await callMock.testCall(0, '0x9952') + + const multiCallMock = callMock.connect(provider) + const promiseA = provider.getCode(callMock.address) + const promiseB = multiCallMock.lastValB() + + expect(await promiseA).to.equal(await ganache.provider!.getCode(callMock.address)) + expect(await promiseB).to.equal('0x9952') + + if (option.ignoreCount) return + expect(callCounter).to.equal(1) + }) + it('Should call eth_getBalance', async () => { + const randomAddress = ethers.Wallet.createRandom().address + + const balances = await Promise.all([ + provider.getBalance(accounts[2].account.address), + provider.getBalance(accounts[1].account.address), + provider.getBalance(accounts[2].account.address), + provider.getBalance(randomAddress) + ]) + + if (!option.ignoreCount) expect(callCounter).to.equal(1) + + // expect(callCounter).to.equal(1) + const rawBalances = await Promise.all([ + ganache.provider!.getBalance(accounts[2].account.address), + ganache.provider!.getBalance(accounts[1].account.address), + ganache.provider!.getBalance(accounts[2].account.address), + ganache.provider!.getBalance(randomAddress) + ]) + + rawBalances.forEach((bal, i) => { + expect(balances[i].toHexString()).to.equal(bal.toHexString()) + }) + }) + it('Should call eth_getBalance and eth_getCode', async () => { + const promiseA = provider.getCode(callMock.address) + const promiseB = await provider.getBalance(accounts[3].account.address) + + expect(await promiseA).to.equal(await ganache.provider!.getCode(callMock.address)) + expect(promiseB.toHexString()).to.equal((await ganache.provider!.getBalance(accounts[3].account.address)).toHexString()) + + if (option.ignoreCount) return + expect(callCounter).to.equal(1) + }) + }) + describe('Handle errors', async () => { + it('Should not retry after failing to execute single call (not multicalled)', async () => { + const callMockB = await createCallMock() + + await callMockB.setRevertFlag(true) + + const multiCallMockB = callMockB.connect(provider) + + // await expect(multiCallMockB.callStatic.testCall(1, "0x1122")).to.be.rejectedWith('VM Exception while processing transaction: revert CallReceiverMock#testCall: REVERT_FLAG') + await expect(multiCallMockB.callStatic.testCall(1, '0x1122')).to.be.rejectedWith(/Transaction reverted/) + + if (option.ignoreCount) return + expect(callCounter).to.equal(1) + }) + it('Should retry after failing to execute using batch', async () => { + const callMockB = await createCallMock() + + await callMockB.setRevertFlag(true) + + const multiCallMockB = callMockB.connect(provider) + + // await expect(Promise.all([ + // multiCallMockB.callStatic.testCall(1, "0x1122"), + // multiCallMockB.callStatic.testCall(2, "0x1122") + // ])).to.be.rejectedWith('VM Exception while processing transaction: revert CallReceiverMock#testCall: REVERT_FLAG') + await expect( + Promise.all([multiCallMockB.callStatic.testCall(1, '0x1122'), multiCallMockB.callStatic.testCall(2, '0x1122')]) + ).to.be.rejectedWith(/Transaction reverted/) + + if (option.ignoreCount) return + expect(callCounter).to.equal(3) + }) + + it('Should call getStorageAt', async () => { + const random = ethers.utils.hexlify(ethers.utils.randomBytes(32)) + await callMock.testCall(random, '0x00') + const storageAt = ethers.utils.hexZeroPad(await provider.getStorageAt(callMock.address, 0), 32) + expect(storageAt).to.equal(ethers.utils.defaultAbiCoder.encode(['bytes32'], [random])) + }) + + it('Should call getStorageAt with padding', async () => { + const val = '0x001a6077bf4f6eae0b4d9158b68bc770c97e5ef19efffcfa28aec2bce13cae24' + await callMock.testCall(val, '0x00') + const storageAt = ethers.utils.hexZeroPad(await provider.getStorageAt(callMock.address, 0), 32) + expect(storageAt).to.equal(ethers.utils.defaultAbiCoder.encode(['bytes32'], [val])) + }) + + it('Should detect network', async () => { + const net = await (provider as ethers.providers.BaseProvider).detectNetwork() + expect(net.chainId).to.equal(1337) + }) + + // TODO: fix this test, its breaking on macOS node v15.12.0 + /*it("Should execute batch with errors on it", async () => { + const callMockB = await createCallMock() + + callMockB.testCall(1, "0x1122") + + await callMockB.setRevertFlag(true) + + const multiCallMockB = callMockB.connect(provider) + + const errorPromise = multiCallMockB.callStatic.testCall(1, "0x1122") + + const res = await Promise.all([ + provider.getCode(multiCallMockB.address), + multiCallMockB.lastValB() + ]) + + await expect(errorPromise).to.be.rejected + + expect(res[0].length).to.not.equal(0) + expect(res[1]).to.equal("0x1122") + expect(callCounter).to.equal(2) + })*/ + + const brokenProviderOptions = [ + { + name: 'non-deployed util contract', + overhead: 0, + brokenProvider: (getProvider: (options?: Partial) => providers.Provider) => + getProvider({ + contract: '' + }) + }, + { + name: 'EOA address as util contract', + overhead: 1, + brokenProvider: (getProvider: (options?: Partial) => providers.Provider) => + getProvider({ + contract: ethers.Wallet.createRandom().address + }) + }, + { + name: 'Broken contract as util contract', + overhead: 1, + brokenProvider: (getProvider: (options?: Partial) => providers.Provider) => + getProvider({ + contract: callMock.address + }) + }, + { + name: 'invalid address as util contract', + overhead: 0, + brokenProvider: (getProvider: (options?: Partial) => providers.Provider) => + getProvider({ + contract: 'This is not a valid address' + }) + } + ] + + brokenProviderOptions.map(brokenOption => + context(brokenOption.name, () => { + beforeEach(() => { + brokenProvider = brokenOption.brokenProvider(option.provider) + }) + + it('Should fallback to provider if multicall fails eth_getCode', async () => { + const code = await Promise.all([ + brokenProvider.getCode(callMock.address), + brokenProvider.getCode(utilsContract.address) + ]) + + if (!option.ignoreCount) expect(callCounter).to.equal(2 + brokenOption.overhead) + const rawCode = await Promise.all([ + ganache.provider!.getCode(callMock.address), + ganache.provider!.getCode(utilsContract.address) + ]) + + expect(rawCode[0]).to.equal(code[0]) + expect(rawCode[1]).to.equal(code[1]) + }) + + it('Should fallback to provider if multicall fails eth_call', async () => { + await callMock.testCall(848487868126387, '0x001122') + + const multiCallMock = callMock.connect(brokenProvider) + const promiseA = multiCallMock.lastValA() + const promiseB = multiCallMock.lastValB() + + expect((await promiseA).toString()).to.equal('848487868126387') + expect(await promiseB).to.equal('0x001122') + + if (option.ignoreCount) return + expect(callCounter).to.equal(3) + }) + + it('Should fallback to provider if multicall fails eth_call and eth_getCode', async () => { + await callMock.testCall(848487868126387, '0x001122') + + const multiCallMock = callMock.connect(brokenProvider) + const promiseA = multiCallMock.lastValA() + const promiseB = multiCallMock.lastValB() + const promiseC = brokenProvider.getCode(callMock.address) + + expect((await promiseA).toString()).to.equal('848487868126387') + expect(await promiseB).to.equal('0x001122') + expect(await promiseC).to.equal(await provider.getCode(callMock.address)) + + if (option.ignoreCount) return + expect(callCounter).to.equal(4 + brokenOption.overhead) + }) + + it('Should fallback to provider if multicall fails eth_getBalance', async () => { + const randomAddress = ethers.Wallet.createRandom().address + + const balances = await Promise.all([ + brokenProvider.getBalance(accounts[2].account.address), + brokenProvider.getBalance(accounts[1].account.address), + brokenProvider.getBalance(accounts[2].account.address), + brokenProvider.getBalance(randomAddress) + ]) + + if (!option.ignoreCount) expect(callCounter).to.equal(4 + brokenOption.overhead) + + // expect(callCounter).to.equal(1) + const rawBalances = await Promise.all([ + ganache.provider!.getBalance(accounts[2].account.address), + ganache.provider!.getBalance(accounts[1].account.address), + ganache.provider!.getBalance(accounts[2].account.address), + ganache.provider!.getBalance(randomAddress) + ]) + + rawBalances.forEach((bal, i) => { + expect(balances[i].toHexString()).to.equal(bal.toHexString()) + }) + }) + + it('Should fallback to provider if multicall fails eth_getBalance and eth_getCode', async () => { + const promiseA = brokenProvider.getCode(callMock.address) + const promiseB = await brokenProvider.getBalance(accounts[3].account.address) + + expect(await promiseA).to.equal(await ganache.provider!.getCode(callMock.address)) + expect(promiseB.toHexString()).to.equal( + (await ganache.provider!.getBalance(accounts[3].account.address)).toHexString() + ) + + if (option.ignoreCount) return + expect(callCounter).to.equal(2 + brokenOption.overhead) + }) + }) + ) + }) + }) + }) +}) diff --git a/packages/multicall/tests/utils/index.ts b/packages/multicall/tests/utils/index.ts new file mode 100644 index 0000000000..be4c722d7f --- /dev/null +++ b/packages/multicall/tests/utils/index.ts @@ -0,0 +1,33 @@ +export type SpyProxyHooks any> = { + prop: keyof K + func: T + callback: (...params: Parameters) => boolean | void +} + +export const SpyProxy = (obj: T, ...hooks: SpyProxyHooks any>[]): T => { + const handler = { + get: function (target: T, prop: keyof T, receiver: any) { + if (target[prop] instanceof Function) { + return (...p: any): any => { + if ( + !hooks + .filter(h => h.prop === prop) + .map(f => f.callback(...p)) + .reduce((p, c) => p || c, false) + ) { + return (obj[prop] as unknown as Function)(...p) + } + } + } + + if (Object.getPrototypeOf(obj)[prop] !== null) { + return obj[prop] + } + + return Reflect.get(target, prop, receiver) + } + } + + // @ts-ignore + return new Proxy(obj, handler) +} diff --git a/packages/network/CHANGELOG.md b/packages/network/CHANGELOG.md new file mode 100644 index 0000000000..5e924927ee --- /dev/null +++ b/packages/network/CHANGELOG.md @@ -0,0 +1,2749 @@ +# @0xsequence/network + +## 1.10.8 + +### Patch Changes + +- update metadata bindings +- Updated dependencies + - @0xsequence/core@1.10.8 + - @0xsequence/indexer@1.10.8 + - @0xsequence/relayer@1.10.8 + - @0xsequence/utils@1.10.8 + +## 1.10.7 + +### Patch Changes + +- minor fixes to waas client +- Updated dependencies + - @0xsequence/core@1.10.7 + - @0xsequence/indexer@1.10.7 + - @0xsequence/relayer@1.10.7 + - @0xsequence/utils@1.10.7 + +## 1.10.6 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/core@1.10.6 + - @0xsequence/indexer@1.10.6 + - @0xsequence/relayer@1.10.6 + - @0xsequence/utils@1.10.6 + +## 1.10.5 + +### Patch Changes + +- network: ape-chain-testnet -> apechain-testnet +- Updated dependencies + - @0xsequence/core@1.10.5 + - @0xsequence/indexer@1.10.5 + - @0xsequence/relayer@1.10.5 + - @0xsequence/utils@1.10.5 + +## 1.10.4 + +### Patch Changes + +- network: add b3-sepolia, ape-chain-testnet, blast, blast-sepolia +- Updated dependencies + - @0xsequence/core@1.10.4 + - @0xsequence/indexer@1.10.4 + - @0xsequence/relayer@1.10.4 + - @0xsequence/utils@1.10.4 + +## 1.10.3 + +### Patch Changes + +- typing fix +- Updated dependencies + - @0xsequence/core@1.10.3 + - @0xsequence/indexer@1.10.3 + - @0xsequence/relayer@1.10.3 + - @0xsequence/utils@1.10.3 + +## 1.10.2 + +### Patch Changes + +- - waas: add getIdToken method + - indexer: update api client +- Updated dependencies + - @0xsequence/core@1.10.2 + - @0xsequence/indexer@1.10.2 + - @0xsequence/relayer@1.10.2 + - @0xsequence/utils@1.10.2 + +## 1.10.1 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/core@1.10.1 + - @0xsequence/indexer@1.10.1 + - @0xsequence/relayer@1.10.1 + - @0xsequence/utils@1.10.1 + +## 1.10.0 + +### Minor Changes + +- waas release v1.3.0 + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.10.0 + - @0xsequence/indexer@1.10.0 + - @0xsequence/relayer@1.10.0 + - @0xsequence/utils@1.10.0 + +## 1.9.37 + +### Patch Changes + +- network: adds nativeToken data to NetworkMetadata constants +- Updated dependencies + - @0xsequence/core@1.9.37 + - @0xsequence/indexer@1.9.37 + - @0xsequence/relayer@1.9.37 + - @0xsequence/utils@1.9.37 + +## 1.9.36 + +### Patch Changes + +- guard: export client +- Updated dependencies + - @0xsequence/core@1.9.36 + - @0xsequence/indexer@1.9.36 + - @0xsequence/relayer@1.9.36 + - @0xsequence/utils@1.9.36 + +## 1.9.35 + +### Patch Changes + +- guard: update bindings +- Updated dependencies + - @0xsequence/core@1.9.35 + - @0xsequence/indexer@1.9.35 + - @0xsequence/relayer@1.9.35 + - @0xsequence/utils@1.9.35 + +## 1.9.34 + +### Patch Changes + +- waas: always use lowercase email +- Updated dependencies + - @0xsequence/core@1.9.34 + - @0xsequence/indexer@1.9.34 + - @0xsequence/relayer@1.9.34 + - @0xsequence/utils@1.9.34 + +## 1.9.33 + +### Patch Changes + +- waas: umd build +- Updated dependencies + - @0xsequence/core@1.9.33 + - @0xsequence/indexer@1.9.33 + - @0xsequence/relayer@1.9.33 + - @0xsequence/utils@1.9.33 + +## 1.9.32 + +### Patch Changes + +- indexer: update bindings +- Updated dependencies + - @0xsequence/core@1.9.32 + - @0xsequence/indexer@1.9.32 + - @0xsequence/relayer@1.9.32 + - @0xsequence/utils@1.9.32 + +## 1.9.31 + +### Patch Changes + +- metadata: token directory changes +- Updated dependencies + - @0xsequence/core@1.9.31 + - @0xsequence/indexer@1.9.31 + - @0xsequence/relayer@1.9.31 + - @0xsequence/utils@1.9.31 + +## 1.9.30 + +### Patch Changes + +- update +- Updated dependencies + - @0xsequence/core@1.9.30 + - @0xsequence/indexer@1.9.30 + - @0xsequence/relayer@1.9.30 + - @0xsequence/utils@1.9.30 + +## 1.9.29 + +### Patch Changes + +- disable gnosis chain +- Updated dependencies + - @0xsequence/core@1.9.29 + - @0xsequence/indexer@1.9.29 + - @0xsequence/relayer@1.9.29 + - @0xsequence/utils@1.9.29 + +## 1.9.28 + +### Patch Changes + +- add utils/merkletree +- Updated dependencies + - @0xsequence/core@1.9.28 + - @0xsequence/indexer@1.9.28 + - @0xsequence/relayer@1.9.28 + - @0xsequence/utils@1.9.28 + +## 1.9.27 + +### Patch Changes + +- network: optimistic -> optimism +- waas: remove defaults +- api, sessions: update bindings +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.9.27 + - @0xsequence/indexer@1.9.27 + - @0xsequence/relayer@1.9.27 + - @0xsequence/utils@1.9.27 + +## 1.9.26 + +### Patch Changes + +- - add backend interfaces for pluggable interfaces + - introduce @0xsequence/react-native + - update pnpm to lockfile v9 +- Updated dependencies + - @0xsequence/core@1.9.26 + - @0xsequence/indexer@1.9.26 + - @0xsequence/relayer@1.9.26 + - @0xsequence/utils@1.9.26 + +## 1.9.25 + +### Patch Changes + +- update webrpc clients with new error types +- Updated dependencies + - @0xsequence/core@1.9.25 + - @0xsequence/indexer@1.9.25 + - @0xsequence/relayer@1.9.25 + - @0xsequence/utils@1.9.25 + +## 1.9.24 + +### Patch Changes + +- waas: add memoryStore backend to localStore +- Updated dependencies + - @0xsequence/core@1.9.24 + - @0xsequence/indexer@1.9.24 + - @0xsequence/relayer@1.9.24 + - @0xsequence/utils@1.9.24 + +## 1.9.23 + +### Patch Changes + +- update api client bindings +- Updated dependencies + - @0xsequence/core@1.9.23 + - @0xsequence/indexer@1.9.23 + - @0xsequence/relayer@1.9.23 + - @0xsequence/utils@1.9.23 + +## 1.9.22 + +### Patch Changes + +- update metadata client bindings +- Updated dependencies + - @0xsequence/core@1.9.22 + - @0xsequence/indexer@1.9.22 + - @0xsequence/relayer@1.9.22 + - @0xsequence/utils@1.9.22 + +## 1.9.21 + +### Patch Changes + +- api client bindings +- Updated dependencies + - @0xsequence/core@1.9.21 + - @0xsequence/indexer@1.9.21 + - @0xsequence/relayer@1.9.21 + - @0xsequence/utils@1.9.21 + +## 1.9.20 + +### Patch Changes + +- api client bindings update +- Updated dependencies + - @0xsequence/core@1.9.20 + - @0xsequence/indexer@1.9.20 + - @0xsequence/relayer@1.9.20 + - @0xsequence/utils@1.9.20 + +## 1.9.19 + +### Patch Changes + +- waas update +- Updated dependencies + - @0xsequence/core@1.9.19 + - @0xsequence/indexer@1.9.19 + - @0xsequence/relayer@1.9.19 + - @0xsequence/utils@1.9.19 + +## 1.9.18 + +### Patch Changes + +- provider: prohibit dangerous functions +- Updated dependencies + - @0xsequence/core@1.9.18 + - @0xsequence/indexer@1.9.18 + - @0xsequence/relayer@1.9.18 + - @0xsequence/utils@1.9.18 + +## 1.9.17 + +### Patch Changes + +- network: add xr-sepolia +- Updated dependencies + - @0xsequence/core@1.9.17 + - @0xsequence/indexer@1.9.17 + - @0xsequence/relayer@1.9.17 + - @0xsequence/utils@1.9.17 + +## 1.9.16 + +### Patch Changes + +- waas: sequence.feeOptions +- Updated dependencies + - @0xsequence/core@1.9.16 + - @0xsequence/indexer@1.9.16 + - @0xsequence/relayer@1.9.16 + - @0xsequence/utils@1.9.16 + +## 1.9.15 + +### Patch Changes + +- metadata: collection external_link field name fix +- Updated dependencies + - @0xsequence/core@1.9.15 + - @0xsequence/indexer@1.9.15 + - @0xsequence/relayer@1.9.15 + - @0xsequence/utils@1.9.15 + +## 1.9.14 + +### Patch Changes + +- network: astar-zkatana -> astar-zkyoto +- network: deprecate polygon mumbai network +- network: add xai and polygon amoy +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.9.14 + - @0xsequence/indexer@1.9.14 + - @0xsequence/relayer@1.9.14 + - @0xsequence/utils@1.9.14 + +## 1.9.13 + +### Patch Changes + +- waas: fix @0xsequence/network dependency +- Updated dependencies + - @0xsequence/core@1.9.13 + - @0xsequence/indexer@1.9.13 + - @0xsequence/relayer@1.9.13 + - @0xsequence/utils@1.9.13 + +## 1.9.12 + +### Patch Changes + +- indexer: update rpc bindings +- provider: signMessage: Serialize the BytesLike or string message into hexstring before sending +- waas: SessionAuthProof +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.9.12 + - @0xsequence/indexer@1.9.12 + - @0xsequence/relayer@1.9.12 + - @0xsequence/utils@1.9.12 + +## 1.9.11 + +### Patch Changes + +- metdata, update rpc bindings +- Updated dependencies + - @0xsequence/core@1.9.11 + - @0xsequence/indexer@1.9.11 + - @0xsequence/relayer@1.9.11 + - @0xsequence/utils@1.9.11 + +## 1.9.10 + +### Patch Changes + +- update metadata rpc bindings +- Updated dependencies + - @0xsequence/core@1.9.10 + - @0xsequence/indexer@1.9.10 + - @0xsequence/relayer@1.9.10 + - @0xsequence/utils@1.9.10 + +## 1.9.9 + +### Patch Changes + +- metadata, add SequenceCollections rpc client +- Updated dependencies + - @0xsequence/core@1.9.9 + - @0xsequence/indexer@1.9.9 + - @0xsequence/relayer@1.9.9 + - @0xsequence/utils@1.9.9 + +## 1.9.8 + +### Patch Changes + +- waas client update +- Updated dependencies + - @0xsequence/core@1.9.8 + - @0xsequence/indexer@1.9.8 + - @0xsequence/relayer@1.9.8 + - @0xsequence/utils@1.9.8 + +## 1.9.7 + +### Patch Changes + +- update rpc client bindings for api, metadata and relayer +- Updated dependencies + - @0xsequence/core@1.9.7 + - @0xsequence/indexer@1.9.7 + - @0xsequence/relayer@1.9.7 + - @0xsequence/utils@1.9.7 + +## 1.9.6 + +### Patch Changes + +- waas package update +- Updated dependencies + - @0xsequence/core@1.9.6 + - @0xsequence/indexer@1.9.6 + - @0xsequence/relayer@1.9.6 + - @0xsequence/utils@1.9.6 + +## 1.9.5 + +### Patch Changes + +- RpcRelayer prioritize project access key +- Updated dependencies + - @0xsequence/core@1.9.5 + - @0xsequence/indexer@1.9.5 + - @0xsequence/relayer@1.9.5 + - @0xsequence/utils@1.9.5 + +## 1.9.4 + +### Patch Changes + +- waas: fix network dependency +- Updated dependencies + - @0xsequence/core@1.9.4 + - @0xsequence/indexer@1.9.4 + - @0xsequence/relayer@1.9.4 + - @0xsequence/utils@1.9.4 + +## 1.9.3 + +### Patch Changes + +- provider: don't append access key to RPC url if user has already provided it +- Updated dependencies + - @0xsequence/core@1.9.3 + - @0xsequence/indexer@1.9.3 + - @0xsequence/relayer@1.9.3 + - @0xsequence/utils@1.9.3 + +## 1.9.2 + +### Patch Changes + +- network: add xai-sepolia +- Updated dependencies + - @0xsequence/core@1.9.2 + - @0xsequence/indexer@1.9.2 + - @0xsequence/relayer@1.9.2 + - @0xsequence/utils@1.9.2 + +## 1.9.1 + +### Patch Changes + +- analytics fix +- Updated dependencies + - @0xsequence/core@1.9.1 + - @0xsequence/indexer@1.9.1 + - @0xsequence/relayer@1.9.1 + - @0xsequence/utils@1.9.1 + +## 1.9.0 + +### Minor Changes + +- waas release + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.9.0 + - @0xsequence/indexer@1.9.0 + - @0xsequence/relayer@1.9.0 + - @0xsequence/utils@1.9.0 + +## 1.8.8 + +### Patch Changes + +- update metadata bindings +- Updated dependencies + - @0xsequence/core@1.8.8 + - @0xsequence/indexer@1.8.8 + - @0xsequence/relayer@1.8.8 + - @0xsequence/utils@1.8.8 + +## 1.8.7 + +### Patch Changes + +- provider: update databeat to 0.9.1 +- Updated dependencies + - @0xsequence/core@1.8.7 + - @0xsequence/indexer@1.8.7 + - @0xsequence/relayer@1.8.7 + - @0xsequence/utils@1.8.7 + +## 1.8.6 + +### Patch Changes + +- guard: SignedOwnershipProof +- Updated dependencies + - @0xsequence/core@1.8.6 + - @0xsequence/indexer@1.8.6 + - @0xsequence/relayer@1.8.6 + - @0xsequence/utils@1.8.6 + +## 1.8.5 + +### Patch Changes + +- guard: signOwnershipProof and isSignedOwnershipProof +- Updated dependencies + - @0xsequence/core@1.8.5 + - @0xsequence/indexer@1.8.5 + - @0xsequence/relayer@1.8.5 + - @0xsequence/utils@1.8.5 + +## 1.8.4 + +### Patch Changes + +- network: add homeverse to networks list +- Updated dependencies + - @0xsequence/core@1.8.4 + - @0xsequence/indexer@1.8.4 + - @0xsequence/relayer@1.8.4 + - @0xsequence/utils@1.8.4 + +## 1.8.3 + +### Patch Changes + +- api: introduce basic linked wallet support +- Updated dependencies + - @0xsequence/core@1.8.3 + - @0xsequence/indexer@1.8.3 + - @0xsequence/relayer@1.8.3 + - @0xsequence/utils@1.8.3 + +## 1.8.2 + +### Patch Changes + +- provider: don't initialize analytics unless explicitly requested +- Updated dependencies + - @0xsequence/core@1.8.2 + - @0xsequence/indexer@1.8.2 + - @0xsequence/relayer@1.8.2 + - @0xsequence/utils@1.8.2 + +## 1.8.1 + +### Patch Changes + +- update to analytics provider +- Updated dependencies + - @0xsequence/core@1.8.1 + - @0xsequence/indexer@1.8.1 + - @0xsequence/relayer@1.8.1 + - @0xsequence/utils@1.8.1 + +## 1.8.0 + +### Minor Changes + +- provider: project analytics + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.8.0 + - @0xsequence/indexer@1.8.0 + - @0xsequence/relayer@1.8.0 + - @0xsequence/utils@1.8.0 + +## 1.7.2 + +### Patch Changes + +- 0xsequence: ChainId should not be exported as a type +- account, wallet: fix nonce selection +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.7.2 + - @0xsequence/indexer@1.7.2 + - @0xsequence/relayer@1.7.2 + - @0xsequence/utils@1.7.2 + +## 1.7.1 + +### Patch Changes + +- network: add missing avalanche logoURI +- Updated dependencies + - @0xsequence/core@1.7.1 + - @0xsequence/indexer@1.7.1 + - @0xsequence/relayer@1.7.1 + - @0xsequence/utils@1.7.1 + +## 1.7.0 + +### Minor Changes + +- provider: projectAccessKey is now required + +### Patch Changes + +- network: add NetworkMetadata.logoURI property for all networks +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.7.0 + - @0xsequence/indexer@1.7.0 + - @0xsequence/relayer@1.7.0 + - @0xsequence/utils@1.7.0 + +## 1.6.3 + +### Patch Changes + +- network list update +- Updated dependencies + - @0xsequence/core@1.6.3 + - @0xsequence/indexer@1.6.3 + - @0xsequence/relayer@1.6.3 + - @0xsequence/utils@1.6.3 + +## 1.6.2 + +### Patch Changes + +- auth: projectAccessKey option +- wallet: use 12 bytes for random space +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.6.2 + - @0xsequence/indexer@1.6.2 + - @0xsequence/relayer@1.6.2 + - @0xsequence/utils@1.6.2 + +## 1.6.1 + +### Patch Changes + +- core: add simple config from subdigest support +- core: fix encode tree with subdigest +- account: implement buildOnChainSignature on Account +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.6.1 + - @0xsequence/indexer@1.6.1 + - @0xsequence/relayer@1.6.1 + - @0xsequence/utils@1.6.1 + +## 1.6.0 + +### Minor Changes + +- account, wallet: parallel transactions by default + +### Patch Changes + +- provider: emit disconnect on sign out +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.6.0 + - @0xsequence/indexer@1.6.0 + - @0xsequence/relayer@1.6.0 + - @0xsequence/utils@1.6.0 + +## 1.5.0 + +### Minor Changes + +- signhub: add 'signing' signer status + +### Patch Changes + +- auth: Session.open: onAccountAddress callback +- account: allow empty transaction bundles +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.5.0 + - @0xsequence/indexer@1.5.0 + - @0xsequence/relayer@1.5.0 + - @0xsequence/utils@1.5.0 + +## 1.4.9 + +### Patch Changes + +- rename SequenceMetadataClient to SequenceMetadata +- Updated dependencies + - @0xsequence/core@1.4.9 + - @0xsequence/indexer@1.4.9 + - @0xsequence/relayer@1.4.9 + - @0xsequence/utils@1.4.9 + +## 1.4.8 + +### Patch Changes + +- account: Account.getSigners +- Updated dependencies + - @0xsequence/core@1.4.8 + - @0xsequence/indexer@1.4.8 + - @0xsequence/relayer@1.4.8 + - @0xsequence/utils@1.4.8 + +## 1.4.7 + +### Patch Changes + +- update indexer client bindings +- Updated dependencies + - @0xsequence/core@1.4.7 + - @0xsequence/indexer@1.4.7 + - @0xsequence/relayer@1.4.7 + - @0xsequence/utils@1.4.7 + +## 1.4.6 + +### Patch Changes + +- - add sepolia networks, mark goerli as deprecated + - update indexer client bindings +- Updated dependencies + - @0xsequence/core@1.4.6 + - @0xsequence/indexer@1.4.6 + - @0xsequence/relayer@1.4.6 + - @0xsequence/utils@1.4.6 + +## 1.4.5 + +### Patch Changes + +- indexer/metadata: update client bindings +- auth: selectWallet with new address +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.4.5 + - @0xsequence/indexer@1.4.5 + - @0xsequence/relayer@1.4.5 + - @0xsequence/utils@1.4.5 + +## 1.4.4 + +### Patch Changes + +- indexer: update bindings +- auth: handle jwt expiry +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.4.4 + - @0xsequence/indexer@1.4.4 + - @0xsequence/relayer@1.4.4 + - @0xsequence/utils@1.4.4 + +## 1.4.3 + +### Patch Changes + +- guard: return active status from GuardSigner.getAuthMethods +- Updated dependencies + - @0xsequence/core@1.4.3 + - @0xsequence/indexer@1.4.3 + - @0xsequence/relayer@1.4.3 + - @0xsequence/utils@1.4.3 + +## 1.4.2 + +### Patch Changes + +- guard: update bindings +- Updated dependencies + - @0xsequence/core@1.4.2 + - @0xsequence/indexer@1.4.2 + - @0xsequence/relayer@1.4.2 + - @0xsequence/utils@1.4.2 + +## 1.4.1 + +### Patch Changes + +- network: remove unused networks +- signhub: orchestrator interface +- guard: auth methods interface +- guard: update bindings for pin and totp +- guard: no more retry logic +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.4.1 + - @0xsequence/indexer@1.4.1 + - @0xsequence/relayer@1.4.1 + - @0xsequence/utils@1.4.1 + +## 1.4.0 + +### Minor Changes + +- project access key support + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.4.0 + - @0xsequence/indexer@1.4.0 + - @0xsequence/relayer@1.4.0 + - @0xsequence/utils@1.4.0 + +## 1.3.0 + +### Minor Changes + +- signhub: account children + +### Patch Changes + +- guard: do not throw when building deploy transaction +- network: snowtrace.io -> subnets.avax.network/c-chain +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.3.0 + - @0xsequence/indexer@1.3.0 + - @0xsequence/relayer@1.3.0 + - @0xsequence/utils@1.3.0 + +## 1.2.9 + +### Patch Changes + +- account: AccountSigner.sendTransaction simulateForFeeOptions +- relayer: update bindings +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.2.9 + - @0xsequence/indexer@1.2.9 + - @0xsequence/relayer@1.2.9 + - @0xsequence/utils@1.2.9 + +## 1.2.8 + +### Patch Changes + +- rename X-Sequence-Token-Key header to X-Access-Key +- Updated dependencies + - @0xsequence/core@1.2.8 + - @0xsequence/indexer@1.2.8 + - @0xsequence/relayer@1.2.8 + - @0xsequence/utils@1.2.8 + +## 1.2.7 + +### Patch Changes + +- add x-sequence-token-key to clients +- Updated dependencies + - @0xsequence/core@1.2.7 + - @0xsequence/indexer@1.2.7 + - @0xsequence/relayer@1.2.7 + - @0xsequence/utils@1.2.7 + +## 1.2.6 + +### Patch Changes + +- Fix bind multicall provider +- Updated dependencies + - @0xsequence/core@1.2.6 + - @0xsequence/indexer@1.2.6 + - @0xsequence/relayer@1.2.6 + - @0xsequence/utils@1.2.6 + +## 1.2.5 + +### Patch Changes + +- Multicall default configuration fixes +- Updated dependencies + - @0xsequence/core@1.2.5 + - @0xsequence/indexer@1.2.5 + - @0xsequence/relayer@1.2.5 + - @0xsequence/utils@1.2.5 + +## 1.2.4 + +### Patch Changes + +- provider: Adding missing payment provider types to PaymentProviderOption +- provider: WalletRequestHandler.notifyChainChanged +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.2.4 + - @0xsequence/indexer@1.2.4 + - @0xsequence/relayer@1.2.4 + - @0xsequence/utils@1.2.4 + +## 1.2.3 + +### Patch Changes + +- auth, provider: connect to accept optional authorizeNonce +- Updated dependencies + - @0xsequence/core@1.2.3 + - @0xsequence/indexer@1.2.3 + - @0xsequence/relayer@1.2.3 + - @0xsequence/utils@1.2.3 + +## 1.2.2 + +### Patch Changes + +- provider: allow createContract calls +- core: check for explicit zero address in contract deployments +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.2.2 + - @0xsequence/indexer@1.2.2 + - @0xsequence/relayer@1.2.2 + - @0xsequence/utils@1.2.2 + +## 1.2.1 + +### Patch Changes + +- auth: use sequence api chain id as reference chain id if available +- Updated dependencies + - @0xsequence/core@1.2.1 + - @0xsequence/indexer@1.2.1 + - @0xsequence/relayer@1.2.1 + - @0xsequence/utils@1.2.1 + +## 1.2.0 + +### Minor Changes + +- split services from session, better local support + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.2.0 + - @0xsequence/indexer@1.2.0 + - @0xsequence/relayer@1.2.0 + - @0xsequence/utils@1.2.0 + +## 1.1.15 + +### Patch Changes + +- guard: remove error filtering +- Updated dependencies + - @0xsequence/core@1.1.15 + - @0xsequence/indexer@1.1.15 + - @0xsequence/relayer@1.1.15 + - @0xsequence/utils@1.1.15 + +## 1.1.14 + +### Patch Changes + +- guard: add GuardSigner.onError +- Updated dependencies + - @0xsequence/core@1.1.14 + - @0xsequence/indexer@1.1.14 + - @0xsequence/relayer@1.1.14 + - @0xsequence/utils@1.1.14 + +## 1.1.13 + +### Patch Changes + +- provider: pass client version with connect options +- provider: removing large from BannerSize +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.1.13 + - @0xsequence/indexer@1.1.13 + - @0xsequence/relayer@1.1.13 + - @0xsequence/utils@1.1.13 + +## 1.1.12 + +### Patch Changes + +- provider: adding bannerSize to ConnectOptions +- Updated dependencies + - @0xsequence/core@1.1.12 + - @0xsequence/indexer@1.1.12 + - @0xsequence/relayer@1.1.12 + - @0xsequence/utils@1.1.12 + +## 1.1.11 + +### Patch Changes + +- add homeverse configs +- Updated dependencies + - @0xsequence/core@1.1.11 + - @0xsequence/indexer@1.1.11 + - @0xsequence/relayer@1.1.11 + - @0xsequence/utils@1.1.11 + +## 1.1.10 + +### Patch Changes + +- handle default EIP6492 on send +- Updated dependencies + - @0xsequence/core@1.1.10 + - @0xsequence/indexer@1.1.10 + - @0xsequence/relayer@1.1.10 + - @0xsequence/utils@1.1.10 + +## 1.1.9 + +### Patch Changes + +- Custom default EIP6492 on client +- Updated dependencies + - @0xsequence/core@1.1.9 + - @0xsequence/indexer@1.1.9 + - @0xsequence/relayer@1.1.9 + - @0xsequence/utils@1.1.9 + +## 1.1.8 + +### Patch Changes + +- metadata: searchMetadata: add types filter +- Updated dependencies + - @0xsequence/core@1.1.8 + - @0xsequence/indexer@1.1.8 + - @0xsequence/relayer@1.1.8 + - @0xsequence/utils@1.1.8 + +## 1.1.7 + +### Patch Changes + +- adding signInWith connect settings option to allow dapps to automatically login their users with a certain provider optimizing the normal authentication flow +- Updated dependencies + - @0xsequence/core@1.1.7 + - @0xsequence/indexer@1.1.7 + - @0xsequence/relayer@1.1.7 + - @0xsequence/utils@1.1.7 + +## 1.1.6 + +### Patch Changes + +- metadata: searchMetadata: add chainID and excludeTokenMetadata filters +- Updated dependencies + - @0xsequence/core@1.1.6 + - @0xsequence/indexer@1.1.6 + - @0xsequence/relayer@1.1.6 + - @0xsequence/utils@1.1.6 + +## 1.1.5 + +### Patch Changes + +- account: re-compute meta-transaction id for wallet deployment transactions +- Updated dependencies + - @0xsequence/core@1.1.5 + - @0xsequence/indexer@1.1.5 + - @0xsequence/relayer@1.1.5 + - @0xsequence/utils@1.1.5 + +## 1.1.4 + +### Patch Changes + +- network: rename base-mainnet to base +- provider: override isDefaultChain with ConnectOptions.networkId if provided +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.1.4 + - @0xsequence/indexer@1.1.4 + - @0xsequence/relayer@1.1.4 + - @0xsequence/utils@1.1.4 + +## 1.1.3 + +### Patch Changes + +- provider: use network id from transport session +- provider: sign authorization using ConnectOptions.networkId if provided +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.1.3 + - @0xsequence/indexer@1.1.3 + - @0xsequence/relayer@1.1.3 + - @0xsequence/utils@1.1.3 + +## 1.1.2 + +### Patch Changes + +- provider: jsonrpc chain id fixes +- Updated dependencies + - @0xsequence/core@1.1.2 + - @0xsequence/indexer@1.1.2 + - @0xsequence/relayer@1.1.2 + - @0xsequence/utils@1.1.2 + +## 1.1.1 + +### Patch Changes + +- network: add base mainnet and sepolia +- provider: reject toxic transaction requests +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.1.1 + - @0xsequence/indexer@1.1.1 + - @0xsequence/relayer@1.1.1 + - @0xsequence/utils@1.1.1 + +## 1.1.0 + +### Minor Changes + +- Refactor dapp facing provider + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.1.0 + - @0xsequence/indexer@1.1.0 + - @0xsequence/relayer@1.1.0 + - @0xsequence/utils@1.1.0 + +## 1.0.5 + +### Patch Changes + +- network: export network constants +- guard: use the correct global for fetch +- network: nova-explorer.arbitrum.io -> nova.arbiscan.io +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.0.5 + - @0xsequence/indexer@1.0.5 + - @0xsequence/relayer@1.0.5 + - @0xsequence/utils@1.0.5 + +## 1.0.4 + +### Patch Changes + +- provider: accept name or number for networkId +- Updated dependencies + - @0xsequence/core@1.0.4 + - @0xsequence/indexer@1.0.4 + - @0xsequence/relayer@1.0.4 + - @0xsequence/utils@1.0.4 + +## 1.0.3 + +### Patch Changes + +- Simpler isValidSignature helpers +- Updated dependencies + - @0xsequence/core@1.0.3 + - @0xsequence/indexer@1.0.3 + - @0xsequence/relayer@1.0.3 + - @0xsequence/utils@1.0.3 + +## 1.0.2 + +### Patch Changes + +- add extra signature validation utils methods +- Updated dependencies + - @0xsequence/core@1.0.2 + - @0xsequence/indexer@1.0.2 + - @0xsequence/relayer@1.0.2 + - @0xsequence/utils@1.0.2 + +## 1.0.1 + +### Patch Changes + +- add homeverse testnet +- Updated dependencies + - @0xsequence/core@1.0.1 + - @0xsequence/indexer@1.0.1 + - @0xsequence/relayer@1.0.1 + - @0xsequence/utils@1.0.1 + +## 1.0.0 + +### Major Changes + +- https://sequence.xyz/blog/sequence-wallet-light-state-sync-full-merkle-wallets + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.0.0 + - @0xsequence/indexer@1.0.0 + - @0xsequence/relayer@1.0.0 + - @0xsequence/utils@1.0.0 + +## 0.43.34 + +### Patch Changes + +- auth: no jwt for indexer +- Updated dependencies + - @0xsequence/indexer@0.43.34 + - @0xsequence/provider@0.43.34 + - @0xsequence/relayer@0.43.34 + - @0xsequence/utils@0.43.34 + +## 0.43.33 + +### Patch Changes + +- Adding onConnectOptionsChange handler to WalletRequestHandler +- Updated dependencies + - @0xsequence/indexer@0.43.33 + - @0xsequence/provider@0.43.33 + - @0xsequence/relayer@0.43.33 + - @0xsequence/utils@0.43.33 + +## 0.43.32 + +### Patch Changes + +- add Base Goerli network +- Updated dependencies + - @0xsequence/indexer@0.43.32 + - @0xsequence/provider@0.43.32 + - @0xsequence/relayer@0.43.32 + - @0xsequence/utils@0.43.32 + +## 0.43.31 + +### Patch Changes + +- remove AuxDataProvider, add promptSignInConnect +- Updated dependencies + - @0xsequence/indexer@0.43.31 + - @0xsequence/provider@0.43.31 + - @0xsequence/relayer@0.43.31 + - @0xsequence/utils@0.43.31 + +## 0.43.30 + +### Patch Changes + +- add arbitrum goerli testnet +- Updated dependencies + - @0xsequence/indexer@0.43.30 + - @0xsequence/provider@0.43.30 + - @0xsequence/relayer@0.43.30 + - @0xsequence/utils@0.43.30 + +## 0.43.29 + +### Patch Changes + +- provider: check availability of window object +- Updated dependencies + - @0xsequence/indexer@0.43.29 + - @0xsequence/provider@0.43.29 + - @0xsequence/relayer@0.43.29 + - @0xsequence/utils@0.43.29 + +## 0.43.28 + +### Patch Changes + +- update api bindings +- Updated dependencies + - @0xsequence/indexer@0.43.28 + - @0xsequence/provider@0.43.28 + - @0xsequence/relayer@0.43.28 + - @0xsequence/utils@0.43.28 + +## 0.43.27 + +### Patch Changes + +- Add rpc is sequence method +- Updated dependencies + - @0xsequence/indexer@0.43.27 + - @0xsequence/provider@0.43.27 + - @0xsequence/relayer@0.43.27 + - @0xsequence/utils@0.43.27 + +## 0.43.26 + +### Patch Changes + +- add zkevm url to enum +- Updated dependencies + - @0xsequence/indexer@0.43.26 + - @0xsequence/provider@0.43.26 + - @0xsequence/relayer@0.43.26 + - @0xsequence/utils@0.43.26 + +## 0.43.25 + +### Patch Changes + +- added polygon zkevm to mainnet networks +- Updated dependencies + - @0xsequence/indexer@0.43.25 + - @0xsequence/provider@0.43.25 + - @0xsequence/relayer@0.43.25 + - @0xsequence/utils@0.43.25 + +## 0.43.24 + +### Patch Changes + +- name change from zkevm to polygon-zkevm +- Updated dependencies + - @0xsequence/indexer@0.43.24 + - @0xsequence/provider@0.43.24 + - @0xsequence/relayer@0.43.24 + - @0xsequence/utils@0.43.24 + +## 0.43.23 + +### Patch Changes + +- update zkEVM name to Polygon zkEVM +- Updated dependencies + - @0xsequence/indexer@0.43.23 + - @0xsequence/provider@0.43.23 + - @0xsequence/relayer@0.43.23 + - @0xsequence/utils@0.43.23 + +## 0.43.22 + +### Patch Changes + +- add zkevm chain +- Updated dependencies + - @0xsequence/indexer@0.43.22 + - @0xsequence/provider@0.43.22 + - @0xsequence/relayer@0.43.22 + - @0xsequence/utils@0.43.22 + +## 0.43.21 + +### Patch Changes + +- api: update client bindings +- Updated dependencies + - @0xsequence/indexer@0.43.21 + - @0xsequence/provider@0.43.21 + - @0xsequence/relayer@0.43.21 + - @0xsequence/utils@0.43.21 + +## 0.43.20 + +### Patch Changes + +- indexer: update bindings +- Updated dependencies + - @0xsequence/indexer@0.43.20 + - @0xsequence/provider@0.43.20 + - @0xsequence/relayer@0.43.20 + - @0xsequence/utils@0.43.20 + +## 0.43.19 + +### Patch Changes + +- session proof update +- Updated dependencies + - @0xsequence/indexer@0.43.19 + - @0xsequence/provider@0.43.19 + - @0xsequence/relayer@0.43.19 + - @0xsequence/utils@0.43.19 + +## 0.43.18 + +### Patch Changes + +- rpc client global check, hardening +- Updated dependencies + - @0xsequence/indexer@0.43.18 + - @0xsequence/provider@0.43.18 + - @0xsequence/relayer@0.43.18 + - @0xsequence/utils@0.43.18 + +## 0.43.17 + +### Patch Changes + +- rpc clients, check of 'global' is defined +- Updated dependencies + - @0xsequence/indexer@0.43.17 + - @0xsequence/provider@0.43.17 + - @0xsequence/relayer@0.43.17 + - @0xsequence/utils@0.43.17 + +## 0.43.16 + +### Patch Changes + +- ethers peerDep to v5, update rpc client global use +- Updated dependencies + - @0xsequence/indexer@0.43.16 + - @0xsequence/provider@0.43.16 + - @0xsequence/relayer@0.43.16 + - @0xsequence/utils@0.43.16 + +## 0.43.15 + +### Patch Changes + +- - provider: expand receiver type on some util methods +- Updated dependencies + - @0xsequence/indexer@0.43.15 + - @0xsequence/provider@0.43.15 + - @0xsequence/relayer@0.43.15 + - @0xsequence/utils@0.43.15 + +## 0.43.14 + +### Patch Changes + +- bump +- Updated dependencies + - @0xsequence/indexer@0.43.14 + - @0xsequence/provider@0.43.14 + - @0xsequence/relayer@0.43.14 + - @0xsequence/utils@0.43.14 + +## 0.43.13 + +### Patch Changes + +- update rpc bindings +- Updated dependencies + - @0xsequence/indexer@0.43.13 + - @0xsequence/provider@0.43.13 + - @0xsequence/relayer@0.43.13 + - @0xsequence/utils@0.43.13 + +## 0.43.12 + +### Patch Changes + +- provider: single wallet init, and add new unregisterWallet() method +- Updated dependencies + - @0xsequence/indexer@0.43.12 + - @0xsequence/provider@0.43.12 + - @0xsequence/relayer@0.43.12 + - @0xsequence/utils@0.43.12 + +## 0.43.11 + +### Patch Changes + +- fix lockfiles +- re-add mocha type deleter +- Updated dependencies +- Updated dependencies + - @0xsequence/indexer@0.43.11 + - @0xsequence/provider@0.43.11 + - @0xsequence/relayer@0.43.11 + - @0xsequence/utils@0.43.11 + +## 0.43.10 + +### Patch Changes + +- various improvements +- Updated dependencies + - @0xsequence/indexer@0.43.10 + - @0xsequence/provider@0.43.10 + - @0xsequence/relayer@0.43.10 + - @0xsequence/utils@0.43.10 + +## 0.43.9 + +### Patch Changes + +- update deps +- Updated dependencies + - @0xsequence/indexer@0.43.9 + - @0xsequence/provider@0.43.9 + - @0xsequence/relayer@0.43.9 + - @0xsequence/utils@0.43.9 + +## 0.43.8 + +### Patch Changes + +- network: JsonRpcProvider with caching +- Updated dependencies + - @0xsequence/indexer@0.43.8 + - @0xsequence/provider@0.43.8 + - @0xsequence/relayer@0.43.8 + - @0xsequence/utils@0.43.8 + +## 0.43.7 + +### Patch Changes + +- provider: fix wallet network init +- Updated dependencies + - @0xsequence/utils@0.43.7 + +## 0.43.6 + +### Patch Changes + +- metadatata: update rpc bindings +- Updated dependencies + - @0xsequence/utils@0.43.6 + +## 0.43.5 + +### Patch Changes + +- provider: do not set default network for connect messages +- provider: forward missing error message +- Updated dependencies +- Updated dependencies + - @0xsequence/utils@0.43.5 + +## 0.43.4 + +### Patch Changes + +- no-change version bump to fix incorrectly tagged snapshot build +- Updated dependencies + - @0xsequence/utils@0.43.4 + +## 0.43.3 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/utils@0.43.3 + +## 0.43.2 + +### Patch Changes + +- provider: implement connectUnchecked +- Updated dependencies + - @0xsequence/utils@0.43.2 + +## 0.43.1 + +### Patch Changes + +- update to latest ethauth dep +- Updated dependencies + - @0xsequence/utils@0.43.1 + +## 0.43.0 + +### Minor Changes + +- move ethers to a peer dependency + +### Patch Changes + +- Updated dependencies + - @0xsequence/utils@0.43.0 + +## 0.42.10 + +### Patch Changes + +- add auxDataProvider +- Updated dependencies + - @0xsequence/utils@0.42.10 + +## 0.42.9 + +### Patch Changes + +- provider: add eip-191 exceptions +- Updated dependencies + - @0xsequence/utils@0.42.9 + +## 0.42.8 + +### Patch Changes + +- provider: skip setting intent origin if we're unity plugin +- Updated dependencies + - @0xsequence/utils@0.42.8 + +## 0.42.7 + +### Patch Changes + +- Add sign in options to connection settings +- Updated dependencies + - @0xsequence/utils@0.42.7 + +## 0.42.6 + +### Patch Changes + +- api bindings update +- Updated dependencies + - @0xsequence/utils@0.42.6 + +## 0.42.5 + +### Patch Changes + +- relayer: don't treat missing receipt as hard failure +- Updated dependencies + - @0xsequence/utils@0.42.5 + +## 0.42.4 + +### Patch Changes + +- provider: add custom app protocol to connect options +- Updated dependencies + - @0xsequence/utils@0.42.4 + +## 0.42.3 + +### Patch Changes + +- update api bindings +- Updated dependencies + - @0xsequence/utils@0.42.3 + +## 0.42.2 + +### Patch Changes + +- disable rinkeby network +- Updated dependencies + - @0xsequence/utils@0.42.2 + +## 0.42.1 + +### Patch Changes + +- wallet: optional waitForReceipt parameter +- Updated dependencies + - @0xsequence/utils@0.42.1 + +## 0.42.0 + +### Minor Changes + +- relayer: estimateGasLimits -> simulate +- add simulator package + +### Patch Changes + +- transactions: fix flattenAuxTransactions +- provider: only filter nullish values +- provider: re-map transaction 'gas' back to 'gasLimit' +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/utils@0.42.0 + +## 0.41.3 + +### Patch Changes + +- api bindings update +- Updated dependencies + - @0xsequence/utils@0.41.3 + +## 0.41.2 + +### Patch Changes + +- api bindings update +- Updated dependencies + - @0xsequence/utils@0.41.2 + +## 0.41.1 + +### Patch Changes + +- update default networks +- Updated dependencies + - @0xsequence/utils@0.41.1 + +## 0.41.0 + +### Minor Changes + +- relayer: fix Relayer.wait() interface + + The interface for calling Relayer.wait() has changed. Instead of a single optional ill-defined timeout/delay parameter, there are three optional parameters, in order: + + - timeout: the maximum time to wait for the transaction receipt + - delay: the polling interval, i.e. the time to wait between requests + - maxFails: the maximum number of hard failures to tolerate before giving up + + Please update your codebase accordingly. + +- relayer: add optional waitForReceipt parameter to Relayer.relay + + The behaviour of Relayer.relay() was not well-defined with respect to whether or not it waited for a receipt. + This change allows the caller to specify whether to wait or not, with the default behaviour being to wait. + +### Patch Changes + +- relayer: wait receipt retry logic +- fix wrapped object error +- provider: forward delegateCall and revertOnError transaction fields +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/utils@0.41.0 + +## 0.40.6 + +### Patch Changes + +- add arbitrum-nova chain +- Updated dependencies + - @0xsequence/utils@0.40.6 + +## 0.40.5 + +### Patch Changes + +- api: update bindings +- Updated dependencies + - @0xsequence/utils@0.40.5 + +## 0.40.4 + +### Patch Changes + +- add unreal transport +- Updated dependencies + - @0xsequence/utils@0.40.4 + +## 0.40.3 + +### Patch Changes + +- provider: fix MessageToSign message type +- Updated dependencies + - @0xsequence/utils@0.40.3 + +## 0.40.2 + +### Patch Changes + +- Wallet provider, loadSession method +- Updated dependencies + - @0xsequence/utils@0.40.2 + +## 0.40.1 + +### Patch Changes + +- export sequence.initWallet and sequence.getWallet +- Updated dependencies + - @0xsequence/utils@0.40.1 + +## 0.40.0 + +### Minor Changes + +- add sequence.initWallet(network, config) and sequence.getWallet() helper methods + +### Patch Changes + +- Updated dependencies + - @0xsequence/utils@0.40.0 + +## 0.39.6 + +### Patch Changes + +- indexer: update client bindings +- Updated dependencies + - @0xsequence/utils@0.39.6 + +## 0.39.5 + +### Patch Changes + +- provider: fix networkRpcUrl config option +- Updated dependencies + - @0xsequence/utils@0.39.5 + +## 0.39.4 + +### Patch Changes + +- api: update client bindings +- Updated dependencies + - @0xsequence/utils@0.39.4 + +## 0.39.3 + +### Patch Changes + +- add request method on Web3Provider +- Updated dependencies + - @0xsequence/utils@0.39.3 + +## 0.39.2 + +### Patch Changes + +- update umd name +- Updated dependencies + - @0xsequence/utils@0.39.2 + +## 0.39.1 + +### Patch Changes + +- add Aurora network +- add origin info for accountsChanged event to handle it per dapp +- Updated dependencies +- Updated dependencies + - @0xsequence/utils@0.39.1 + +## 0.39.0 + +### Minor Changes + +- abstract window.localStorage to interface type + +### Patch Changes + +- Updated dependencies + - @0xsequence/utils@0.39.0 + +## 0.38.2 + +### Patch Changes + +- provider: add Settings.defaultPurchaseAmount +- Updated dependencies + - @0xsequence/utils@0.38.2 + +## 0.38.1 + +### Patch Changes + +- update api and metadata rpc bindings +- Updated dependencies + - @0xsequence/utils@0.38.1 + +## 0.38.0 + +### Minor Changes + +- api: update bindings, change TokenPrice interface +- bridge: remove @0xsequence/bridge package +- api: update bindings, rename ContractCallArg to TupleComponent + +### Patch Changes + +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/utils@0.38.0 + +## 0.37.1 + +### Patch Changes + +- Add back sortNetworks - Removing sorting was a breaking change for dapps on older versions which directly integrate sequence. +- Updated dependencies + - @0xsequence/utils@0.37.1 + +## 0.37.0 + +### Minor Changes + +- network related fixes and improvements +- api: bindings: exchange rate lookups + +### Patch Changes + +- Updated dependencies +- Updated dependencies + - @0xsequence/utils@0.37.0 + +## 0.36.13 + +### Patch Changes + +- api: update bindings with new price endpoints +- Updated dependencies + - @0xsequence/utils@0.36.13 + +## 0.36.12 + +### Patch Changes + +- wallet: skip remote signers if not needed +- auth: check that signature meets threshold before requesting auth token +- Updated dependencies +- Updated dependencies + - @0xsequence/utils@0.36.12 + +## 0.36.11 + +### Patch Changes + +- Prefix EIP191 message on wallet-request-handler +- Updated dependencies + - @0xsequence/utils@0.36.11 + +## 0.36.10 + +### Patch Changes + +- support bannerUrl on connect +- Updated dependencies + - @0xsequence/utils@0.36.10 + +## 0.36.9 + +### Patch Changes + +- minor dev xp improvements +- Updated dependencies + - @0xsequence/utils@0.36.9 + +## 0.36.8 + +### Patch Changes + +- more connect options (theme, payment providers, funding currencies) +- Updated dependencies + - @0xsequence/utils@0.36.8 + +## 0.36.7 + +### Patch Changes + +- fix missing break +- Updated dependencies + - @0xsequence/utils@0.36.7 + +## 0.36.6 + +### Patch Changes + +- wallet_switchEthereumChain support +- Updated dependencies + - @0xsequence/utils@0.36.6 + +## 0.36.5 + +### Patch Changes + +- auth: bump ethauth to 0.7.0 + network, wallet: don't assume position of auth network in list + api/indexer/metadata: trim trailing slash on hostname, and add endpoint urls + relayer: Allow to specify local relayer transaction parameters like gas price or gas limit +- Updated dependencies + - @0xsequence/utils@0.36.5 + +## 0.36.4 + +### Patch Changes + +- Updating list of chain ids to include other ethereum compatible chains +- Updated dependencies + - @0xsequence/utils@0.36.4 + +## 0.36.3 + +### Patch Changes + +- provider: pass connect options to prompter methods +- Updated dependencies + - @0xsequence/utils@0.36.3 + +## 0.36.2 + +### Patch Changes + +- transactions: Setting target to 0x0 when empty to during SequenceTxAbiEncode +- Updated dependencies + - @0xsequence/utils@0.36.2 + +## 0.36.1 + +### Patch Changes + +- metadata: update client with more fields +- Updated dependencies + - @0xsequence/utils@0.36.1 + +## 0.36.0 + +### Minor Changes + +- relayer, wallet: fee quote support + +### Patch Changes + +- Updated dependencies + - @0xsequence/utils@0.36.0 + +## 0.35.12 + +### Patch Changes + +- provider: rename wallet.commands to wallet.utils +- Updated dependencies + - @0xsequence/utils@0.35.12 + +## 0.35.11 + +### Patch Changes + +- provider/utils: smoother message validation +- Updated dependencies + - @0xsequence/utils@0.35.11 + +## 0.35.10 + +### Patch Changes + +- upgrade deps +- Updated dependencies + - @0xsequence/utils@0.35.10 + +## 0.35.9 + +### Patch Changes + +- provider: window-transport override event handlers with new wallet instance +- Updated dependencies + - @0xsequence/utils@0.35.9 + +## 0.35.8 + +### Patch Changes + +- provider: async wallet sign in improvements +- Updated dependencies + - @0xsequence/utils@0.35.8 + +## 0.35.7 + +### Patch Changes + +- config: cache wallet configs +- Updated dependencies + - @0xsequence/utils@0.35.7 + +## 0.35.6 + +### Patch Changes + +- provider: support async signin of wallet request handler +- Updated dependencies + - @0xsequence/utils@0.35.6 + +## 0.35.5 + +### Patch Changes + +- wallet: skip threshold check during fee estimation +- Updated dependencies + - @0xsequence/utils@0.35.5 + +## 0.35.4 + +### Patch Changes + +- - browser extension mode, center window +- Updated dependencies + - @0xsequence/utils@0.35.4 + +## 0.35.3 + +### Patch Changes + +- - update window position when in browser extension mode +- Updated dependencies + - @0xsequence/utils@0.35.3 + +## 0.35.2 + +### Patch Changes + +- - provider: WindowMessageHandler accept optional windowHref +- Updated dependencies + - @0xsequence/utils@0.35.2 + +## 0.35.1 + +### Patch Changes + +- wallet: update config on undeployed too +- Updated dependencies + - @0xsequence/utils@0.35.1 + +## 0.35.0 + +### Minor Changes + +- - config: add buildStubSignature + - provider: add checks to signing cases for wallet deployment and config statuses + - provider: add prompt for wallet deployment + - relayer: add BaseRelayer.prependWalletDeploy + - relayer: add Relayer.feeOptions + - relayer: account for wallet deployment in fee estimation + - transactions: add fromTransactionish + - wallet: add Account.prependConfigUpdate + - wallet: add Account.getFeeOptions + +### Patch Changes + +- Updated dependencies + - @0xsequence/utils@0.35.0 + +## 0.34.0 + +### Minor Changes + +- - upgrade deps + +### Patch Changes + +- Updated dependencies + - @0xsequence/utils@0.34.0 + +## 0.31.0 + +### Minor Changes + +- - upgrading to ethers v5.5 + +### Patch Changes + +- Updated dependencies + - @0xsequence/utils@0.31.0 + +## 0.30.0 + +### Minor Changes + +- - upgrade most deps + +### Patch Changes + +- Updated dependencies + - @0xsequence/utils@0.30.0 + +## 0.29.8 + +### Patch Changes + +- update api +- Updated dependencies [undefined] + - @0xsequence/utils@0.29.8 + +## 0.29.6 + +### Patch Changes + +- auth: pass testnetMode flag depending on network + +## 0.29.0 + +### Minor Changes + +- major architectural changes in Sequence design + + - only one API instance, API is no longer a per-chain service + - separate per-chain indexer service, API no longer handles indexing + - single contract metadata service, API no longer serves metadata + + chaind package has been removed, indexer and metadata packages have been added + + stronger typing with new explicit ChainId type + + multicall fixes and improvements + + forbid "wait" transactions in sendTransactionBatch calls + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/utils@0.29.0 + +## 0.28.0 + +### Minor Changes + +- extension provider + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/utils@0.28.0 + +## 0.27.0 + +### Minor Changes + +- Add requireFreshSigner lib to sessions + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/utils@0.27.0 + +## 0.25.1 + +### Patch Changes + +- Fix build typescrypt issue +- Updated dependencies [undefined] + - @0xsequence/utils@0.25.1 + +## 0.25.0 + +### Minor Changes + +- 10c8af8: Add estimator package + Fix multicall few calls bug + +### Patch Changes + +- Updated dependencies [10c8af8] + - @0xsequence/utils@0.25.0 + +## 0.23.0 + +### Minor Changes + +- - relayer: offer variety of gas fee options from the relayer service" + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/utils@0.23.0 + +## 0.22.2 + +### Patch Changes + +- e1c109e: Fix authProof on expired sessions +- Updated dependencies [e1c109e] + - @0xsequence/utils@0.22.2 + +## 0.22.1 + +### Patch Changes + +- transport session cache +- Updated dependencies [undefined] + - @0xsequence/utils@0.22.1 + +## 0.22.0 + +### Minor Changes + +- e667b65: Expose all relayer options on networks + +### Patch Changes + +- Updated dependencies [e667b65] + - @0xsequence/utils@0.22.0 + +## 0.21.5 + +### Patch Changes + +- Give priority to metaTxnId returned by relayer +- Updated dependencies [undefined] + - @0xsequence/utils@0.21.5 + +## 0.21.4 + +### Patch Changes + +- Add has enough signers method +- Updated dependencies [undefined] + - @0xsequence/utils@0.21.4 + +## 0.21.3 + +### Patch Changes + +- add window session cache +- Updated dependencies [undefined] + - @0xsequence/utils@0.21.3 + +## 0.21.2 + +### Patch Changes + +- exception handlind in relayer +- Updated dependencies [undefined] + - @0xsequence/utils@0.21.2 + +## 0.21.0 + +### Minor Changes + +- - fix gas estimation on wallets with large number of signers + - update to session handling and wallet config construction upon auth + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/utils@0.21.0 + +## 0.19.3 + +### Patch Changes + +- jwtAuth visibility, package version sync +- Updated dependencies [undefined] + - @0xsequence/utils@0.19.3 + +## 0.19.0 + +### Minor Changes + +- - provider, improve dapp / wallet transport io + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/utils@0.19.0 + +## 0.18.0 + +### Minor Changes + +- relayer improvements and pending transaction handling + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/utils@0.18.0 + +## 0.16.0 + +### Minor Changes + +- relayer as its own service separate from chaind + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/utils@0.16.0 + +## 0.15.1 + +### Patch Changes + +- update api clients +- Updated dependencies [undefined] + - @0xsequence/utils@0.15.1 + +## 0.14.3 + +### Patch Changes + +- Fix 0xSequence relayer dependencies +- Updated dependencies [undefined] + - @0xsequence/utils@0.14.3 + +## 0.14.2 + +### Patch Changes + +- Add debug logs to rpc-relayer +- Updated dependencies [undefined] + - @0xsequence/utils@0.14.2 + +## 0.14.0 + +### Minor Changes + +- update sequence utils finder which includes optimization + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/utils@0.14.0 + +## 0.13.0 + +### Minor Changes + +- Update SequenceUtils deployed contract + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/utils@0.13.0 + +## 0.12.1 + +### Patch Changes + +- npm bump +- Updated dependencies [undefined] + - @0xsequence/utils@0.12.1 + +## 0.12.0 + +### Minor Changes + +- provider: improvements to window transport + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/utils@0.12.0 + +## 0.11.4 + +### Patch Changes + +- update api client +- Updated dependencies [undefined] + - @0xsequence/utils@0.11.4 + +## 0.11.3 + +### Patch Changes + +- improve openWindow state options handling +- Updated dependencies [undefined] + - @0xsequence/utils@0.11.3 + +## 0.11.2 + +### Patch Changes + +- Fix multicall proxy scopes +- Updated dependencies [undefined] + - @0xsequence/utils@0.11.2 + +## 0.11.1 + +### Patch Changes + +- Add support for dynamic and nested signatures +- Updated dependencies [undefined] + - @0xsequence/utils@0.11.1 + +## 0.11.0 + +### Minor Changes + +- Update wallet context to 1.7 contracts + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/utils@0.11.0 + +## 0.10.9 + +### Patch Changes + +- add support for public addresses as signers in session.open +- Updated dependencies [undefined] + - @0xsequence/utils@0.10.9 + +## 0.10.8 + +### Patch Changes + +- Multicall production configuration +- Updated dependencies [undefined] + - @0xsequence/utils@0.10.8 + +## 0.10.7 + +### Patch Changes + +- allow provider transport to force disconnect +- Updated dependencies [undefined] + - @0xsequence/utils@0.10.7 + +## 0.10.6 + +### Patch Changes + +- - fix getWalletState method +- Updated dependencies [undefined] + - @0xsequence/utils@0.10.6 + +## 0.10.5 + +### Patch Changes + +- update relayer gas refund options +- Updated dependencies [undefined] + - @0xsequence/utils@0.10.5 + +## 0.10.4 + +### Patch Changes + +- Update api proto +- Updated dependencies [undefined] + - @0xsequence/utils@0.10.4 + +## 0.10.3 + +### Patch Changes + +- Fix loading config cross-chain +- Updated dependencies [undefined] + - @0xsequence/utils@0.10.3 + +## 0.10.2 + +### Patch Changes + +- - message digest fix +- Updated dependencies [undefined] + - @0xsequence/utils@0.10.2 + +## 0.10.1 + +### Patch Changes + +- upgrade deps +- Updated dependencies [undefined] + - @0xsequence/utils@0.10.1 + +## 0.10.0 + +### Minor Changes + +- Deployed new contracts with ERC1271 signer support + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/utils@0.10.0 + +## 0.9.6 + +### Patch Changes + +- Update ABIs for latest sequence contracts +- Updated dependencies [undefined] + - @0xsequence/utils@0.9.6 + +## 0.9.5 + +### Patch Changes + +- Implemented session class +- Updated dependencies [undefined] + - @0xsequence/utils@0.9.5 + +## 0.9.3 + +### Patch Changes + +- - minor improvements +- Updated dependencies [undefined] + - @0xsequence/utils@0.9.3 + +## 0.9.1 + +### Patch Changes + +- - patch bump +- Updated dependencies [undefined] + - @0xsequence/utils@0.9.1 + +## 0.9.0 + +### Minor Changes + +- - provider transport hardening + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/utils@0.9.0 + +## 0.8.5 + +### Patch Changes + +- - use latest wallet-contracts +- Updated dependencies [undefined] + - @0xsequence/utils@0.8.5 + +## 0.8.4 + +### Patch Changes + +- - minor improvements, name updates and comments +- Updated dependencies [undefined] + - @0xsequence/utils@0.8.4 + +## 0.8.3 + +### Patch Changes + +- - refinements + + - normalize signer address in config + + - provider: getWalletState() method to WalletProvider + +- Updated dependencies [undefined] + - @0xsequence/utils@0.8.3 + +## 0.8.2 + +### Patch Changes + +- - field rename and ethauth dependency bump +- Updated dependencies [undefined] + - @0xsequence/utils@0.8.2 + +## 0.8.1 + +### Patch Changes + +- - variety of optimizations +- Updated dependencies [undefined] + - @0xsequence/utils@0.8.1 + +## 0.8.0 + +### Minor Changes + +- - changeset fix + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/utils@0.8.0 + +## 0.7.1 + +### Patch Changes + +- 02377ab: Minor improvements +- 1fe4379: \* explicitly export types in 0xsequence meta-package + - introduce new `networksIndex` method in network package +- Updated dependencies [02377ab] + - @0xsequence/utils@0.7.1 + +## 0.7.0 + +### Patch Changes + +- 6f11ed7: sequence.js, init release +- Updated dependencies [6f11ed7] + - @0xsequence/utils@0.7.0 diff --git a/packages/network/README.md b/packages/network/README.md new file mode 100644 index 0000000000..d0f9f960ae --- /dev/null +++ b/packages/network/README.md @@ -0,0 +1,4 @@ +@0xsequence/network +=================== + +See [0xsequence project page](https://github.com/0xsequence/sequence.js). diff --git a/packages/network/constants/package.json b/packages/network/constants/package.json new file mode 100644 index 0000000000..9cbfa6612c --- /dev/null +++ b/packages/network/constants/package.json @@ -0,0 +1,4 @@ +{ + "main": "dist/0xsequence-network-constants.cjs.js", + "module": "dist/0xsequence-network-constants.esm.js" +} diff --git a/packages/network/package.json b/packages/network/package.json new file mode 100644 index 0000000000..5d39ec194a --- /dev/null +++ b/packages/network/package.json @@ -0,0 +1,38 @@ +{ + "name": "@0xsequence/network", + "version": "2.0.0", + "description": "network sub-package for Sequence", + "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/network", + "source": "src/index.ts", + "main": "dist/0xsequence-network.cjs.js", + "module": "dist/0xsequence-network.esm.js", + "author": "Horizon Blockchain Games", + "license": "Apache-2.0", + "scripts": { + "test": "echo", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@0xsequence/core": "workspace:*", + "@0xsequence/indexer": "workspace:*", + "@0xsequence/relayer": "workspace:*", + "@0xsequence/utils": "workspace:*" + }, + "peerDependencies": { + "ethers": ">=5.5 < 6" + }, + "devDependencies": { + "ethers": "^5.7.2" + }, + "files": [ + "src", + "dist", + "constants" + ], + "preconstruct": { + "entrypoints": [ + "index.ts", + "constants.ts" + ] + } +} diff --git a/packages/network/src/config.ts b/packages/network/src/config.ts new file mode 100644 index 0000000000..e81b0740db --- /dev/null +++ b/packages/network/src/config.ts @@ -0,0 +1,128 @@ +import { BigNumberish, ethers, providers } from 'ethers' +import { Indexer } from '@0xsequence/indexer' +import { Relayer, RpcRelayerOptions } from '@0xsequence/relayer' +import { findNetworkConfig, stringTemplate, validateAndSortNetworks } from './utils' +import { isBigNumberish } from '@0xsequence/utils' +import { ChainId, NetworkMetadata, networks } from './constants' + +export type NetworkConfig = NetworkMetadata & { + rpcUrl: string + provider?: providers.Provider + indexerUrl?: string + indexer?: Indexer + relayer?: Relayer | RpcRelayerOptions + + // isDefaultChain identifies the default network. For example, a dapp may run on the Polygon + // network and may configure the wallet to use it as its main/default chain. + isDefaultChain?: boolean + + // Disabled / deprecated chain + disabled?: boolean +} + +type LegacyNetworkConfig = NetworkConfig & { isAuthChain?: boolean } + +export const indexerURL = (network: string) => stringTemplate('https://${network}-indexer.sequence.app', { network }) +export const relayerURL = (network: string) => stringTemplate('https://${network}-relayer.sequence.app', { network }) +export const nodesURL = (network: string) => stringTemplate('https://nodes.sequence.app/${network}', { network }) + +export function findSupportedNetwork(chainIdOrName: string | ChainIdLike): NetworkConfig | undefined { + return findNetworkConfig(allNetworks, chainIdOrName) +} + +export type ChainIdLike = NetworkConfig | BigNumberish + +export function toChainIdNumber(chainIdLike: ChainIdLike): ethers.BigNumber { + if (ethers.BigNumber.isBigNumber(chainIdLike)) { + return chainIdLike + } + + if (isBigNumberish(chainIdLike)) { + return ethers.BigNumber.from(chainIdLike) + } + + return ethers.BigNumber.from(chainIdLike.chainId) +} + +const createNetworkConfig = (chainId: ChainId, options?: { disabled?: boolean }): NetworkConfig => { + const network = networks[chainId] + + if (!network) { + throw new Error(`Network with chainId ${chainId} not found`) + } + + const rpcUrl = nodesURL(network.name) + + return { + ...network, + rpcUrl, + indexerUrl: indexerURL(network.name), + relayer: { + url: relayerURL(network.name), + provider: { + url: rpcUrl + } + }, + ...options + } +} + +export const hardhatNetworks = [ + { + ...networks[ChainId.HARDHAT], + rpcUrl: 'http://localhost:8545', + relayer: { + url: 'http://localhost:3000', + provider: { + url: 'http://localhost:8545' + } + } + }, + { + ...networks[ChainId.HARDHAT_2], + rpcUrl: 'http://localhost:9545', + relayer: { + url: 'http://localhost:3000', + provider: { + url: 'http://localhost:9545' + } + } + } +] + +export const allNetworks = validateAndSortNetworks([ + { ...createNetworkConfig(ChainId.POLYGON), isDefaultChain: true, isAuthChain: true } as LegacyNetworkConfig, + createNetworkConfig(ChainId.MAINNET), + createNetworkConfig(ChainId.BSC), + createNetworkConfig(ChainId.AVALANCHE), + createNetworkConfig(ChainId.ARBITRUM), + createNetworkConfig(ChainId.ARBITRUM_NOVA), + createNetworkConfig(ChainId.OPTIMISM), + createNetworkConfig(ChainId.OPTIMISM_SEPOLIA), + createNetworkConfig(ChainId.POLYGON_ZKEVM), + createNetworkConfig(ChainId.GNOSIS), + createNetworkConfig(ChainId.RINKEBY, { disabled: true }), + createNetworkConfig(ChainId.GOERLI, { disabled: true }), + createNetworkConfig(ChainId.SEPOLIA), + createNetworkConfig(ChainId.POLYGON_MUMBAI, { disabled: true }), + createNetworkConfig(ChainId.POLYGON_AMOY), + createNetworkConfig(ChainId.BSC_TESTNET), + createNetworkConfig(ChainId.ARBITRUM_SEPOLIA), + createNetworkConfig(ChainId.BASE), + createNetworkConfig(ChainId.BASE_SEPOLIA), + createNetworkConfig(ChainId.HOMEVERSE), + createNetworkConfig(ChainId.HOMEVERSE_TESTNET), + createNetworkConfig(ChainId.XAI), + createNetworkConfig(ChainId.XAI_SEPOLIA), + createNetworkConfig(ChainId.AVALANCHE_TESTNET), + createNetworkConfig(ChainId.ASTAR_ZKEVM), + createNetworkConfig(ChainId.ASTAR_ZKYOTO), + createNetworkConfig(ChainId.XR_SEPOLIA), + createNetworkConfig(ChainId.B3_SEPOLIA), + createNetworkConfig(ChainId.APECHAIN_TESTNET), + createNetworkConfig(ChainId.BLAST), + createNetworkConfig(ChainId.BLAST_SEPOLIA), + createNetworkConfig(ChainId.TELOS), + + ...hardhatNetworks +]) diff --git a/packages/network/src/constants.ts b/packages/network/src/constants.ts new file mode 100644 index 0000000000..e1582836cb --- /dev/null +++ b/packages/network/src/constants.ts @@ -0,0 +1,774 @@ +export enum ChainId { + // Ethereum + MAINNET = 1, + ROPSTEN = 3, // network is deprecated + RINKEBY = 4, // network is deprecated + GOERLI = 5, // network is deprecated + KOVAN = 42, // network is deprecated + SEPOLIA = 11155111, + + // Polygon + POLYGON = 137, + POLYGON_MUMBAI = 80001, // network is deprecated + POLYGON_ZKEVM = 1101, + POLYGON_AMOY = 80002, + + // BSC + BSC = 56, + BSC_TESTNET = 97, + + // Optimism + OPTIMISM = 10, + OPTIMISM_KOVAN = 69, // network is deprecated + OPTIMISM_GOERLI = 420, // network is deprecated + OPTIMISM_SEPOLIA = 11155420, + + // Arbitrum One + ARBITRUM = 42161, + ARBITRUM_GOERLI = 421613, // network is deprecated + ARBITRUM_SEPOLIA = 421614, + + // Arbitrum Nova + ARBITRUM_NOVA = 42170, + + // Avalanche + AVALANCHE = 43114, + AVALANCHE_TESTNET = 43113, + + // Gnosis Chain (XDAI) + GNOSIS = 100, + + // BASE + BASE = 8453, + BASE_GOERLI = 84531, // network is deprecated + BASE_SEPOLIA = 84532, + + // HOMEVERSE + HOMEVERSE_TESTNET = 40875, + HOMEVERSE = 19011, + + // Xai + XAI = 660279, + XAI_SEPOLIA = 37714555429, + + // Astar + ASTAR_ZKEVM = 3776, + ASTAR_ZKYOTO = 6038361, + + // XR + XR_SEPOLIA = 2730, + + // TELOS + TELOS = 40, + + // B3 Sepolia + B3_SEPOLIA = 1993, + + // APE Chain + APECHAIN_TESTNET = 33111, + + // Blast + BLAST = 81457, + BLAST_SEPOLIA = 168587773, + + // HARDHAT TESTNETS + HARDHAT = 31337, + HARDHAT_2 = 31338 +} + +export enum NetworkType { + MAINNET = 'mainnet', + TESTNET = 'testnet' +} + +export type BlockExplorerConfig = { + name?: string + rootUrl: string + addressUrl?: string + txnHashUrl?: string +} + +export interface NetworkMetadata { + chainId: ChainId + type?: NetworkType + name: string + title?: string + logoURI?: string + blockExplorer?: BlockExplorerConfig + ensAddress?: string + testnet?: boolean // Deprecated field, use type instead + deprecated?: boolean // The actual network is deprecated + nativeToken: { + symbol: string + name: string + decimals: number + } +} + +export const networks: Record = { + [ChainId.MAINNET]: { + chainId: ChainId.MAINNET, + type: NetworkType.MAINNET, + name: 'mainnet', + title: 'Ethereum', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.MAINNET}.webp`, + blockExplorer: { + name: 'Etherscan', + rootUrl: 'https://etherscan.io/' + }, + nativeToken: { + symbol: 'ETH', + name: 'Ether', + decimals: 18 + }, + ensAddress: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e' + }, + [ChainId.ROPSTEN]: { + chainId: ChainId.ROPSTEN, + type: NetworkType.TESTNET, + name: 'ropsten', + title: 'Ropsten', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.ROPSTEN}.webp`, + testnet: true, + blockExplorer: { + name: 'Etherscan (Ropsten)', + rootUrl: 'https://ropsten.etherscan.io/' + }, + nativeToken: { + symbol: 'roETH', + name: 'Ropsten Ether', + decimals: 18 + }, + ensAddress: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e', + deprecated: true + }, + [ChainId.RINKEBY]: { + chainId: ChainId.RINKEBY, + type: NetworkType.TESTNET, + name: 'rinkeby', + title: 'Rinkeby', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.RINKEBY}.webp`, + testnet: true, + blockExplorer: { + name: 'Etherscan (Rinkeby)', + rootUrl: 'https://rinkeby.etherscan.io/' + }, + nativeToken: { + symbol: 'rETH', + name: 'Rinkeby Ether', + decimals: 18 + }, + ensAddress: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e', + deprecated: true + }, + [ChainId.GOERLI]: { + chainId: ChainId.GOERLI, + type: NetworkType.TESTNET, + name: 'goerli', + title: 'Goerli', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.GOERLI}.webp`, + testnet: true, + blockExplorer: { + name: 'Etherscan (Goerli)', + rootUrl: 'https://goerli.etherscan.io/' + }, + nativeToken: { + symbol: 'gETH', + name: 'Goerli Ether', + decimals: 18 + }, + ensAddress: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e', + deprecated: true + }, + [ChainId.KOVAN]: { + chainId: ChainId.KOVAN, + type: NetworkType.TESTNET, + name: 'kovan', + title: 'Kovan', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.KOVAN}.webp`, + testnet: true, + blockExplorer: { + name: 'Etherscan (Kovan)', + rootUrl: 'https://kovan.etherscan.io/' + }, + nativeToken: { + symbol: 'kETH', + name: 'Kovan Ether', + decimals: 18 + }, + deprecated: true + }, + [ChainId.SEPOLIA]: { + chainId: ChainId.SEPOLIA, + type: NetworkType.TESTNET, + name: 'sepolia', + title: 'Sepolia', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.SEPOLIA}.webp`, + testnet: true, + blockExplorer: { + name: 'Etherscan (Sepolia)', + rootUrl: 'https://sepolia.etherscan.io/' + }, + nativeToken: { + symbol: 'sETH', + name: 'Sepolia Ether', + decimals: 18 + } + }, + [ChainId.POLYGON]: { + chainId: ChainId.POLYGON, + type: NetworkType.MAINNET, + name: 'polygon', + title: 'Polygon', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.POLYGON}.webp`, + blockExplorer: { + name: 'Polygonscan', + rootUrl: 'https://polygonscan.com/' + }, + nativeToken: { + symbol: 'MATIC', + name: 'Polygon', + decimals: 18 + } + }, + [ChainId.POLYGON_MUMBAI]: { + chainId: ChainId.POLYGON_MUMBAI, + type: NetworkType.TESTNET, + name: 'mumbai', + title: 'Polygon Mumbai', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.POLYGON_MUMBAI}.webp`, + testnet: true, + blockExplorer: { + name: 'Polygonscan (Mumbai)', + rootUrl: 'https://mumbai.polygonscan.com/' + }, + nativeToken: { + symbol: 'mMATIC', + name: 'Mumbai Polygon', + decimals: 18 + }, + deprecated: true + }, + [ChainId.POLYGON_AMOY]: { + chainId: ChainId.POLYGON_AMOY, + type: NetworkType.TESTNET, + name: 'amoy', + title: 'Polygon Amoy', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.POLYGON_AMOY}.webp`, + testnet: true, + blockExplorer: { + name: 'OKLink (Amoy)', + rootUrl: 'https://www.oklink.com/amoy/' + }, + nativeToken: { + symbol: 'aMATIC', + name: 'Amoy Polygon', + decimals: 18 + } + }, + [ChainId.POLYGON_ZKEVM]: { + chainId: ChainId.POLYGON_ZKEVM, + type: NetworkType.MAINNET, + name: 'polygon-zkevm', + title: 'Polygon zkEVM', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.POLYGON_ZKEVM}.webp`, + blockExplorer: { + name: 'Polygonscan (zkEVM)', + rootUrl: 'https://zkevm.polygonscan.com/' + }, + nativeToken: { + symbol: 'ETH', + name: 'Ether', + decimals: 18 + } + }, + [ChainId.BSC]: { + chainId: ChainId.BSC, + type: NetworkType.MAINNET, + name: 'bsc', + title: 'BNB Smart Chain', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.BSC}.webp`, + blockExplorer: { + name: 'BSCScan', + rootUrl: 'https://bscscan.com/' + }, + nativeToken: { + symbol: 'BNB', + name: 'BNB', + decimals: 18 + } + }, + [ChainId.BSC_TESTNET]: { + chainId: ChainId.BSC_TESTNET, + type: NetworkType.TESTNET, + name: 'bsc-testnet', + title: 'BNB Smart Chain Testnet', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.BSC_TESTNET}.webp`, + testnet: true, + blockExplorer: { + name: 'BSCScan (Testnet)', + rootUrl: 'https://testnet.bscscan.com/' + }, + nativeToken: { + symbol: 'tBNB', + name: 'Testnet BNB', + decimals: 18 + } + }, + [ChainId.OPTIMISM]: { + chainId: ChainId.OPTIMISM, + type: NetworkType.MAINNET, + name: 'optimism', + title: 'Optimism', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.OPTIMISM}.webp`, + blockExplorer: { + name: 'Etherscan (Optimism)', + rootUrl: 'https://optimistic.etherscan.io/' + }, + nativeToken: { + symbol: 'ETH', + name: 'Ether', + decimals: 18 + } + }, + [ChainId.OPTIMISM_KOVAN]: { + chainId: ChainId.OPTIMISM_KOVAN, + type: NetworkType.TESTNET, + name: 'optimism-kovan', + title: 'Optimism Kovan', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.OPTIMISM_KOVAN}.webp`, + testnet: true, + blockExplorer: { + name: 'Etherscan (Optimism Kovan)', + rootUrl: 'https://kovan-optimistic.etherscan.io/' + }, + nativeToken: { + symbol: 'kETH', + name: 'Kovan Ether', + decimals: 18 + }, + deprecated: true + }, + [ChainId.OPTIMISM_GOERLI]: { + chainId: ChainId.OPTIMISM_GOERLI, + type: NetworkType.TESTNET, + name: 'optimism-goerli', + title: 'Optimism Goerli', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.OPTIMISM_GOERLI}.webp`, + testnet: true, + blockExplorer: { + name: 'Etherscan (Optimism Goerli)', + rootUrl: 'https://goerli-optimistic.etherscan.io/' + }, + nativeToken: { + symbol: 'gETH', + name: 'Goerli Ether', + decimals: 18 + }, + deprecated: true + }, + [ChainId.OPTIMISM_SEPOLIA]: { + chainId: ChainId.OPTIMISM_SEPOLIA, + type: NetworkType.TESTNET, + name: 'optimism-sepolia', + title: 'Optimism Sepolia', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.OPTIMISM_SEPOLIA}.webp`, + testnet: true, + blockExplorer: { + name: 'Etherscan (Optimism Sepolia)', + rootUrl: 'https://sepolia-optimistic.etherscan.io/' + }, + nativeToken: { + symbol: 'sETH', + name: 'Sepolia Ether', + decimals: 18 + } + }, + [ChainId.ARBITRUM]: { + chainId: ChainId.ARBITRUM, + type: NetworkType.MAINNET, + name: 'arbitrum', + title: 'Arbitrum One', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.ARBITRUM}.webp`, + blockExplorer: { + name: 'Arbiscan', + rootUrl: 'https://arbiscan.io/' + }, + nativeToken: { + symbol: 'ETH', + name: 'Ether', + decimals: 18 + } + }, + [ChainId.ARBITRUM_GOERLI]: { + chainId: ChainId.ARBITRUM_GOERLI, + type: NetworkType.TESTNET, + name: 'arbitrum-goerli', + title: 'Arbitrum Goerli', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.ARBITRUM_GOERLI}.webp`, + testnet: true, + blockExplorer: { + name: 'Arbiscan (Goerli Testnet)', + rootUrl: 'https://testnet.arbiscan.io/' + }, + nativeToken: { + symbol: 'gETH', + name: 'Goerli Ether', + decimals: 18 + }, + deprecated: true + }, + [ChainId.ARBITRUM_SEPOLIA]: { + chainId: ChainId.ARBITRUM_SEPOLIA, + type: NetworkType.TESTNET, + name: 'arbitrum-sepolia', + title: 'Arbitrum Sepolia', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.ARBITRUM_SEPOLIA}.webp`, + testnet: true, + blockExplorer: { + name: 'Arbiscan (Sepolia Testnet)', + rootUrl: 'https://sepolia.arbiscan.io/' + }, + nativeToken: { + symbol: 'sETH', + name: 'Sepolia Ether', + decimals: 18 + } + }, + [ChainId.ARBITRUM_NOVA]: { + chainId: ChainId.ARBITRUM_NOVA, + type: NetworkType.MAINNET, + name: 'arbitrum-nova', + title: 'Arbitrum Nova', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.ARBITRUM_NOVA}.webp`, + blockExplorer: { + name: 'Arbiscan Nova', + rootUrl: 'https://nova.arbiscan.io/' + }, + nativeToken: { + symbol: 'ETH', + name: 'Ether', + decimals: 18 + } + }, + [ChainId.AVALANCHE]: { + chainId: ChainId.AVALANCHE, + type: NetworkType.MAINNET, + name: 'avalanche', + title: 'Avalanche', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.AVALANCHE}.webp`, + blockExplorer: { + name: 'Snowtrace', + rootUrl: 'https://subnets.avax.network/c-chain/' + }, + nativeToken: { + symbol: 'AVAX', + name: 'AVAX', + decimals: 18 + } + }, + [ChainId.AVALANCHE_TESTNET]: { + chainId: ChainId.AVALANCHE_TESTNET, + type: NetworkType.TESTNET, + name: 'avalanche-testnet', + title: 'Avalanche Testnet', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.AVALANCHE_TESTNET}.webp`, + testnet: true, + blockExplorer: { + name: 'Snowtrace (Testnet)', + rootUrl: 'https://subnets-test.avax.network/c-chain/' + }, + nativeToken: { + symbol: 'tAVAX', + name: 'Testnet AVAX', + decimals: 18 + } + }, + [ChainId.GNOSIS]: { + chainId: ChainId.GNOSIS, + type: NetworkType.MAINNET, + name: 'gnosis', + title: 'Gnosis Chain', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.GNOSIS}.webp`, + blockExplorer: { + name: 'Gnosis Chain Explorer', + rootUrl: 'https://blockscout.com/xdai/mainnet/' + }, + nativeToken: { + symbol: 'XDAI', + name: 'XDAI', + decimals: 18 + } + }, + [ChainId.BASE]: { + chainId: ChainId.BASE, + type: NetworkType.MAINNET, + name: 'base', + title: 'Base (Coinbase)', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.BASE}.webp`, + blockExplorer: { + name: 'Base Explorer', + rootUrl: 'https://basescan.org/' + }, + nativeToken: { + symbol: 'ETH', + name: 'Ether', + decimals: 18 + } + }, + [ChainId.BASE_GOERLI]: { + chainId: ChainId.BASE_GOERLI, + type: NetworkType.TESTNET, + name: 'base-goerli', + title: 'Base Goerli', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.BASE_GOERLI}.webp`, + testnet: true, + blockExplorer: { + name: 'Base Goerli Explorer', + rootUrl: 'https://goerli.basescan.org/' + }, + nativeToken: { + symbol: 'gETH', + name: 'Goerli Ether', + decimals: 18 + }, + deprecated: true + }, + [ChainId.BASE_SEPOLIA]: { + chainId: ChainId.BASE_SEPOLIA, + type: NetworkType.TESTNET, + name: 'base-sepolia', + title: 'Base Sepolia', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.BASE_SEPOLIA}.webp`, + testnet: true, + blockExplorer: { + name: 'Base Sepolia Explorer', + rootUrl: 'https://base-sepolia.blockscout.com/' + }, + nativeToken: { + symbol: 'sETH', + name: 'Sepolia Ether', + decimals: 18 + } + }, + [ChainId.HOMEVERSE]: { + chainId: ChainId.HOMEVERSE, + type: NetworkType.MAINNET, + name: 'homeverse', + title: 'Oasys Homeverse', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.HOMEVERSE}.webp`, + blockExplorer: { + name: 'Oasys Homeverse Explorer', + rootUrl: 'https://explorer.oasys.homeverse.games/' + }, + nativeToken: { + symbol: 'OAS', + name: 'OAS', + decimals: 18 + } + }, + [ChainId.HOMEVERSE_TESTNET]: { + chainId: ChainId.HOMEVERSE_TESTNET, + type: NetworkType.TESTNET, + name: 'homeverse-testnet', + title: 'Oasys Homeverse Testnet', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.HOMEVERSE_TESTNET}.webp`, + testnet: true, + blockExplorer: { + name: 'Oasys Homeverse Explorer (Testnet)', + rootUrl: 'https://explorer.testnet.oasys.homeverse.games/' + }, + nativeToken: { + symbol: 'tOAS', + name: 'Testnet OAS', + decimals: 18 + } + }, + [ChainId.XAI]: { + chainId: ChainId.XAI, + type: NetworkType.MAINNET, + name: 'xai', + title: 'Xai', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.XAI}.webp`, + blockExplorer: { + name: 'Xai Explorer', + rootUrl: 'https://explorer.xai-chain.net/' + }, + nativeToken: { + symbol: 'XAI', + name: 'XAI', + decimals: 18 + } + }, + [ChainId.XAI_SEPOLIA]: { + chainId: ChainId.XAI_SEPOLIA, + type: NetworkType.TESTNET, + name: 'xai-sepolia', + title: 'Xai Sepolia', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.XAI_SEPOLIA}.webp`, + testnet: true, + blockExplorer: { + name: 'Xai Sepolia Explorer', + rootUrl: 'https://testnet-explorer-v2.xai-chain.net/' + }, + nativeToken: { + symbol: 'sXAI', + name: 'Sepolia XAI', + decimals: 18 + } + }, + [ChainId.ASTAR_ZKEVM]: { + chainId: ChainId.ASTAR_ZKEVM, + type: NetworkType.MAINNET, + name: 'astar-zkevm', + title: 'Astar zkEVM', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.ASTAR_ZKEVM}.webp`, + blockExplorer: { + name: 'Astar zkEVM Explorer', + rootUrl: 'https://astar-zkevm.explorer.startale.com/' + }, + nativeToken: { + symbol: 'ETH', + name: 'Ether', + decimals: 18 + } + }, + [ChainId.ASTAR_ZKYOTO]: { + chainId: ChainId.ASTAR_ZKYOTO, + type: NetworkType.TESTNET, + name: 'astar-zkyoto', + title: 'Astar zKyoto Testnet', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.ASTAR_ZKYOTO}.webp`, + testnet: true, + blockExplorer: { + name: 'Astar zKyoto Explorer', + rootUrl: 'https://astar-zkyoto.blockscout.com/' + }, + nativeToken: { + symbol: 'ETH', + name: 'Ether', + decimals: 18 + } + }, + [ChainId.XR_SEPOLIA]: { + chainId: ChainId.XR_SEPOLIA, + type: NetworkType.TESTNET, + name: 'xr-sepolia', + title: 'XR Sepolia', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.XR_SEPOLIA}.webp`, + testnet: true, + blockExplorer: { + name: 'XR Sepolia Explorer', + rootUrl: 'https://xr-sepolia-testnet.explorer.caldera.xyz/' + }, + nativeToken: { + symbol: 'tXR', + name: 'Sepolia XR', + decimals: 18 + } + }, + [ChainId.B3_SEPOLIA]: { + chainId: ChainId.B3_SEPOLIA, + type: NetworkType.TESTNET, + name: 'b3-sepolia', + title: 'B3 Sepolia', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.B3_SEPOLIA}.webp`, + testnet: true, + blockExplorer: { + name: 'B3 Sepolia Explorer', + rootUrl: 'https://sepolia.explorer.b3.fun/' + }, + nativeToken: { + symbol: 'ETH', + name: 'Ether', + decimals: 18 + } + }, + [ChainId.APECHAIN_TESTNET]: { + chainId: ChainId.APECHAIN_TESTNET, + type: NetworkType.TESTNET, + name: 'apechain-testnet', + title: 'APE Chain Testnet', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.APECHAIN_TESTNET}.webp`, + testnet: true, + blockExplorer: { + name: 'APE Chain Explorer', + rootUrl: 'https://curtis.explorer.caldera.xyz/' + }, + nativeToken: { + symbol: 'APE', + name: 'ApeCoin', + decimals: 18 + } + }, + [ChainId.BLAST]: { + chainId: ChainId.BLAST, + type: NetworkType.MAINNET, + name: 'blast', + title: 'Blast', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.BLAST}.webp`, + blockExplorer: { + name: 'Blast Explorer', + rootUrl: 'https://blastscan.io/' + }, + nativeToken: { + symbol: 'ETH', + name: 'Ether', + decimals: 18 + } + }, + [ChainId.BLAST_SEPOLIA]: { + chainId: ChainId.BLAST_SEPOLIA, + type: NetworkType.TESTNET, + name: 'blast-sepolia', + title: 'Blast Sepolia', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.BLAST_SEPOLIA}.webp`, + testnet: true, + blockExplorer: { + name: 'Blast Sepolia Explorer', + rootUrl: 'https://sepolia.blastexplorer.io/' + }, + nativeToken: { + symbol: 'ETH', + name: 'Ether', + decimals: 18 + } + }, + [ChainId.TELOS]: { + chainId: ChainId.TELOS, + type: NetworkType.MAINNET, + name: 'telos', + title: 'Telos', + logoURI: `https://assets.sequence.info/images/networks/medium/${ChainId.TELOS}.webp`, + blockExplorer: { + name: 'Telos Explorer', + rootUrl: 'https://explorer.telos.net/network/' + }, + nativeToken: { + symbol: 'TLOS', + name: 'TLOS', + decimals: 18 + } + }, + + [ChainId.HARDHAT]: { + chainId: ChainId.HARDHAT, + name: 'hardhat', + title: 'Hardhat (local testnet)', + nativeToken: { + symbol: 'ETH', + name: 'Ether', + decimals: 18 + } + }, + [ChainId.HARDHAT_2]: { + chainId: ChainId.HARDHAT_2, + name: 'hardhat2', + title: 'Hardhat (local testnet)', + nativeToken: { + symbol: 'ETH', + name: 'Ether', + decimals: 18 + } + } +} diff --git a/packages/network/src/index.ts b/packages/network/src/index.ts new file mode 100644 index 0000000000..c042b0908c --- /dev/null +++ b/packages/network/src/index.ts @@ -0,0 +1,5 @@ +export * from './constants' +export * from './config' +export * from './json-rpc' +export * from './json-rpc-provider' +export * from './utils' diff --git a/packages/network/src/json-rpc-provider.ts b/packages/network/src/json-rpc-provider.ts new file mode 100644 index 0000000000..4c2404af04 --- /dev/null +++ b/packages/network/src/json-rpc-provider.ts @@ -0,0 +1,108 @@ +import { ethers } from 'ethers' +import { + JsonRpcRouter, + JsonRpcSender, + loggingProviderMiddleware, + EagerProvider, + SingleflightMiddleware, + CachedProvider, + JsonRpcMiddleware, + JsonRpcMiddlewareHandler +} from './json-rpc' +import { ChainId, networks } from './constants' + +export interface JsonRpcProviderOptions { + // .. + chainId?: number + + // .. + middlewares?: Array + + // .. + blockCache?: boolean | string[] +} + +// JsonRpcProvider with a middleware stack. By default it will use a simple caching middleware. +export class JsonRpcProvider extends ethers.providers.JsonRpcProvider { + private _chainId?: number + private _sender: JsonRpcSender + + constructor(url: ethers.utils.ConnectionInfo | string, options?: JsonRpcProviderOptions) { + super(url, options?.chainId) + + const chainId = options?.chainId + const middlewares = options?.middlewares + const blockCache = options?.blockCache + + this._chainId = chainId + + // NOTE: it will either use the middleware stack passed to the constructor + // or it will use the default caching middleware provider. It does not concat them, + // so if you set middlewares, make sure you set the caching middleware yourself if you'd + // like to keep using it. + const router = new JsonRpcRouter( + middlewares ?? [ + // loggingProviderMiddleware, + new EagerProvider({ chainId }), + new SingleflightMiddleware(), + new CachedProvider({ defaultChainId: chainId, blockCache: blockCache }) + ], + new JsonRpcSender(this.fetch, chainId) + ) + + this._sender = new JsonRpcSender(router, chainId) + } + + async getNetwork(): Promise { + const chainId = this._chainId + if (chainId) { + const network = networks[chainId as ChainId] + const name = network?.name || '' + const ensAddress = network?.ensAddress + return { + name: name, + chainId: chainId, + ensAddress: ensAddress + } + } else { + const chainIdHex = await this.send('eth_chainId', []) + this._chainId = ethers.BigNumber.from(chainIdHex).toNumber() + return this.getNetwork() + } + } + + send = (method: string, params: Array): Promise => { + return this._sender.send(method, params) + } + + private fetch = (method: string, params: Array): Promise => { + const request = { + method: method, + params: params, + id: this._nextId++, + jsonrpc: '2.0' + } + + const result = ethers.utils.fetchJson(this.connection, JSON.stringify(request), getResult).then( + result => { + return result + }, + error => { + throw error + } + ) + + return result + } +} + +function getResult(payload: { error?: { code?: number; data?: any; message?: string }; result?: any }): any { + if (payload.error) { + // @TODO: not any + const error: any = new Error(payload.error.message) + error.code = payload.error.code + error.data = payload.error.data + throw error + } + return payload.result +} diff --git a/packages/network/src/json-rpc/index.ts b/packages/network/src/json-rpc/index.ts new file mode 100644 index 0000000000..6eceac084c --- /dev/null +++ b/packages/network/src/json-rpc/index.ts @@ -0,0 +1,5 @@ +export * from './types' +export * from './router' +export * from './sender' +export * from './middleware' +export * from './utils' diff --git a/packages/network/src/json-rpc/middleware/allow-provider.ts b/packages/network/src/json-rpc/middleware/allow-provider.ts new file mode 100644 index 0000000000..5d5c624a6f --- /dev/null +++ b/packages/network/src/json-rpc/middleware/allow-provider.ts @@ -0,0 +1,42 @@ +import { + JsonRpcHandlerFunc, + JsonRpcRequest, + JsonRpcResponseCallback, + JsonRpcMiddleware, + JsonRpcMiddlewareHandler +} from '../types' + +export class AllowProvider implements JsonRpcMiddlewareHandler { + sendAsyncMiddleware: JsonRpcMiddleware + + private isAllowedFunc: (request: JsonRpcRequest) => boolean + + constructor(isAllowedFunc?: (request: JsonRpcRequest) => boolean) { + if (isAllowedFunc) { + this.isAllowedFunc = isAllowedFunc + } else { + this.isAllowedFunc = (request: JsonRpcRequest): boolean => true + } + + this.sendAsyncMiddleware = allowProviderMiddleware(this.isAllowedFunc) + } + + setIsAllowedFunc(fn: (request: JsonRpcRequest) => boolean) { + this.isAllowedFunc = fn + this.sendAsyncMiddleware = allowProviderMiddleware(this.isAllowedFunc) + } +} + +export const allowProviderMiddleware = + (isAllowed: (request: JsonRpcRequest) => boolean): JsonRpcMiddleware => + (next: JsonRpcHandlerFunc) => { + return (request: JsonRpcRequest, callback: JsonRpcResponseCallback, chainId?: number) => { + // ensure precondition is met or do not allow the request to continue + if (!isAllowed(request)) { + throw new Error('allowProvider middleware precondition is unmet.') + } + + // request is allowed. keep going.. + next(request, callback, chainId) + } + } diff --git a/packages/network/src/json-rpc/middleware/cached-provider.ts b/packages/network/src/json-rpc/middleware/cached-provider.ts new file mode 100644 index 0000000000..7ede68530f --- /dev/null +++ b/packages/network/src/json-rpc/middleware/cached-provider.ts @@ -0,0 +1,175 @@ +import { JsonRpcHandlerFunc, JsonRpcRequest, JsonRpcResponse, JsonRpcResponseCallback, JsonRpcMiddlewareHandler } from '../types' + +export interface CachedProviderOptions { + // defaultChainId passes a chainId to provider handler if one isn't passed. + // This is used in multi-chain mode + defaultChainId?: number + + // blockCache toggle, with option to pass specific set of methods to use with + // the block cache. + blockCache?: boolean | string[] +} + +export class CachedProvider implements JsonRpcMiddlewareHandler { + // cachableJsonRpcMethods which can be permanently cached for lifetime + // of the provider. + private cachableJsonRpcMethods = [ + 'net_version', + 'eth_chainId', + 'eth_accounts', + 'sequence_getWalletContext', + 'sequence_getNetworks' + ] + + // cachableJsonRpcMethodsByBlock which can be temporarily cached for a short + // period of time, essentially by block time. As we support chains fast blocks, + // we keep the values here cachable only for 1.5 seconds. This is still useful to + // memoize the calls within app-code that calls out to fetch these values within + // a short period of time. + private cachableJsonRpcMethodsByBlock: string[] = ['eth_call', 'eth_getCode'] + + // cache for life-time of provider (unless explicitly cleared) + private cache: { [key: string]: any } + + // cache by block, simulated by using a 1 second life-time + private cacheByBlock: { [key: string]: any } + private cacheByBlockResetLock: boolean = false + + // onUpdateCallback callback to be notified when cache values are set. + private onUpdateCallback?: (key?: string, value?: any) => void + + // defaultChainId is used for default chain select with used with multi-chain provider + readonly defaultChainId?: number + + constructor(options?: CachedProviderOptions) { + this.cache = {} + this.cacheByBlock = {} + this.defaultChainId = options?.defaultChainId + if (!options?.blockCache) { + this.cachableJsonRpcMethodsByBlock = [] + } else if (options?.blockCache !== true) { + this.cachableJsonRpcMethodsByBlock = options?.blockCache + } + } + + sendAsyncMiddleware = (next: JsonRpcHandlerFunc) => { + return (request: JsonRpcRequest, callback: JsonRpcResponseCallback, chainId?: number) => { + // Respond early with cached result + if (this.cachableJsonRpcMethods.includes(request.method) || this.cachableJsonRpcMethodsByBlock.includes(request.method)) { + const key = this.cacheKey(request.method, request.params!, chainId || this.defaultChainId) + const result = this.getCacheValue(key) + if (result && result !== '') { + callback(undefined, { + jsonrpc: '2.0', + id: request.id!, + result: result + }) + return + } + } + + // Continue down the handler chain + next( + request, + (error: any, response?: JsonRpcResponse, chainId?: number) => { + // Store result in cache and continue + if ( + this.cachableJsonRpcMethods.includes(request.method) || + this.cachableJsonRpcMethodsByBlock.includes(request.method) + ) { + if (response && response.result && this.shouldCacheResponse(request, response)) { + // cache the value + const key = this.cacheKey(request.method, request.params!, chainId || this.defaultChainId) + + if (this.cachableJsonRpcMethods.includes(request.method)) { + this.setCacheValue(key, response.result) + } else { + this.setCacheByBlockValue(key, response.result) + } + } + } + + // Exec next handler + callback(error, response) + }, + chainId || this.defaultChainId + ) + } + } + + cacheKey = (method: string, params: any[], chainId?: number) => { + let key = '' + if (chainId) { + key = `${chainId}:${method}:` + } else { + key = `:${method}:` + } + if (!params || params.length === 0) { + return key + '[]' + } + return key + JSON.stringify(params) + } + + getCache = () => this.cache + + setCache = (cache: { [key: string]: any }) => { + this.cache = cache + if (this.onUpdateCallback) { + this.onUpdateCallback() + } + } + + getCacheValue = (key: string): any => { + if (this.cache[key]) { + return this.cache[key] + } + if (this.cacheByBlock[key]) { + return this.cacheByBlock[key] + } + return undefined + } + + setCacheValue = (key: string, value: any) => { + this.cache[key] = value + if (this.onUpdateCallback) { + this.onUpdateCallback(key, value) + } + } + + setCacheByBlockValue = (key: string, value: any) => { + this.cacheByBlock[key] = value + + // clear the cacheByBlock once every X period of time + if (!this.cacheByBlockResetLock) { + this.cacheByBlockResetLock = true + setTimeout(() => { + this.cacheByBlockResetLock = false + this.cacheByBlock = {} + }, 1500) // 1.5 second cache lifetime + } + } + + shouldCacheResponse = (request: JsonRpcRequest, response?: JsonRpcResponse): boolean => { + // skip if we do not have response result + if (!response || !response.result) { + return false + } + + // skip caching eth_getCode where resposne value is '0x' or empty + if (request.method === 'eth_getCode' && response.result.length <= 2) { + return false + } + + // all good -- signal to cache the result + return true + } + + onUpdate(callback: (key?: string, value?: any) => void) { + this.onUpdateCallback = callback + } + + clearCache = () => { + this.cache = {} + this.cacheByBlock = {} + } +} diff --git a/packages/network/src/json-rpc/middleware/eager-provider.ts b/packages/network/src/json-rpc/middleware/eager-provider.ts new file mode 100644 index 0000000000..df85adc445 --- /dev/null +++ b/packages/network/src/json-rpc/middleware/eager-provider.ts @@ -0,0 +1,62 @@ +import { commons } from '@0xsequence/core' +import { ethers } from 'ethers' +import { JsonRpcHandlerFunc, JsonRpcRequest, JsonRpcResponseCallback, JsonRpcResponse, JsonRpcMiddlewareHandler } from '../types' + +// EagerProvider will eagerly respond to a provider request from pre-initialized data values. +// +// This is useful for saving a few remote calls for responses we're already expecting when +// communicating to a specific network provider. + +export type EagerProviderOptions = { + accountAddress?: string + chainId?: number + walletContext?: commons.context.VersionedContext +} + +export class EagerProvider implements JsonRpcMiddlewareHandler { + readonly options: EagerProviderOptions + + constructor(options: EagerProviderOptions) { + this.options = options + } + + sendAsyncMiddleware = (next: JsonRpcHandlerFunc) => { + return (request: JsonRpcRequest, callback: JsonRpcResponseCallback, chainId?: number) => { + const { id, method } = request + + switch (method) { + case 'net_version': + if (this.options.chainId) { + callback(undefined, { jsonrpc: '2.0', id: id!, result: `${this.options.chainId}` }) + return + } + break + + case 'eth_chainId': + if (this.options.chainId) { + callback(undefined, { jsonrpc: '2.0', id: id!, result: ethers.utils.hexlify(this.options.chainId) }) + return + } + break + + case 'eth_accounts': + if (this.options.accountAddress) { + callback(undefined, { jsonrpc: '2.0', id: id!, result: [ethers.utils.getAddress(this.options.accountAddress)] }) + return + } + break + + case 'sequence_getWalletContext': + if (this.options.walletContext) { + callback(undefined, { jsonrpc: '2.0', id: id!, result: this.options.walletContext }) + return + } + break + + default: + } + + next(request, callback, chainId) + } + } +} diff --git a/packages/network/src/json-rpc/middleware/exception-provider.ts b/packages/network/src/json-rpc/middleware/exception-provider.ts new file mode 100644 index 0000000000..570051a076 --- /dev/null +++ b/packages/network/src/json-rpc/middleware/exception-provider.ts @@ -0,0 +1,21 @@ +import { JsonRpcHandlerFunc, JsonRpcRequest, JsonRpcResponse, JsonRpcResponseCallback, JsonRpcMiddleware } from '../types' + +export const exceptionProviderMiddleware: JsonRpcMiddleware = (next: JsonRpcHandlerFunc) => { + return (request: JsonRpcRequest, callback: JsonRpcResponseCallback, chainId?: number) => { + next( + request, + (error: any, response?: JsonRpcResponse) => { + if (!error && response && response.error) { + if (typeof response.error === 'string') { + throw new Error(response.error) + } else { + throw new Error(response.error.message) + } + } + + callback(error, response) + }, + chainId + ) + } +} diff --git a/packages/network/src/json-rpc/middleware/index.ts b/packages/network/src/json-rpc/middleware/index.ts new file mode 100644 index 0000000000..2f292adabd --- /dev/null +++ b/packages/network/src/json-rpc/middleware/index.ts @@ -0,0 +1,9 @@ +export { AllowProvider, allowProviderMiddleware } from './allow-provider' +export { CachedProvider } from './cached-provider' +export { EagerProvider } from './eager-provider' +export { exceptionProviderMiddleware } from './exception-provider' +export { loggingProviderMiddleware } from './logging-provider' +export { networkProviderMiddleware } from './network-provider' +export { PublicProvider } from './public-provider' +export { SigningProvider } from './signing-provider' +export { SingleflightMiddleware } from './singleflight' diff --git a/packages/network/src/json-rpc/middleware/logging-provider.ts b/packages/network/src/json-rpc/middleware/logging-provider.ts new file mode 100644 index 0000000000..a64e787635 --- /dev/null +++ b/packages/network/src/json-rpc/middleware/logging-provider.ts @@ -0,0 +1,33 @@ +import { JsonRpcHandlerFunc, JsonRpcRequest, JsonRpcResponse, JsonRpcResponseCallback, JsonRpcMiddleware } from '../types' +import { logger } from '@0xsequence/utils' + +// TODO: rename to loggerMiddleware +export const loggingProviderMiddleware: JsonRpcMiddleware = (next: JsonRpcHandlerFunc) => { + return (request: JsonRpcRequest, callback: JsonRpcResponseCallback, chainId?: number) => { + const chainIdLabel = chainId ? ` chainId:${chainId}` : '' + logger.info(`[provider request]${chainIdLabel} id:${request.id} method:${request.method} params:`, request.params) + + next( + request, + (error: any, response?: JsonRpcResponse) => { + if (error) { + logger.warn( + `[provider response]${chainIdLabel} id:${request.id} method:${request.method} params:`, + request.params, + `error:`, + error + ) + } else { + logger.info( + `[provider response]${chainIdLabel} id:${request.id} method:${request.method} params:`, + request.params, + `response:`, + response + ) + } + callback(error, response) + }, + chainId + ) + } +} diff --git a/packages/network/src/json-rpc/middleware/network-provider.ts b/packages/network/src/json-rpc/middleware/network-provider.ts new file mode 100644 index 0000000000..75bba1007d --- /dev/null +++ b/packages/network/src/json-rpc/middleware/network-provider.ts @@ -0,0 +1,33 @@ +import { ethers } from 'ethers' +import { + JsonRpcHandlerFunc, + JsonRpcRequest, + JsonRpcResponseCallback, + JsonRpcMiddleware, + JsonRpcMiddlewareHandler +} from '../types' + +export const networkProviderMiddleware = + (getChainId: (request: JsonRpcRequest) => number): JsonRpcMiddleware => + (next: JsonRpcHandlerFunc) => { + return (request: JsonRpcRequest, callback: JsonRpcResponseCallback, chainId?: number) => { + const networkChainId = getChainId(request) + + const { id, method } = request + + switch (method) { + case 'net_version': + callback(undefined, { jsonrpc: '2.0', id: id!, result: `${networkChainId}` }) + return + + case 'eth_chainId': + callback(undefined, { jsonrpc: '2.0', id: id!, result: ethers.utils.hexlify(networkChainId) }) + return + + default: + } + + // request is allowed. keep going.. + next(request, callback, chainId) + } + } diff --git a/packages/network/src/json-rpc/middleware/public-provider.ts b/packages/network/src/json-rpc/middleware/public-provider.ts new file mode 100644 index 0000000000..7b0b1042ed --- /dev/null +++ b/packages/network/src/json-rpc/middleware/public-provider.ts @@ -0,0 +1,56 @@ +import { providers } from 'ethers' +import { JsonRpcHandlerFunc, JsonRpcRequest, JsonRpcResponseCallback, JsonRpcMiddlewareHandler } from '../types' +import { SignerJsonRpcMethods } from './signing-provider' +import { logger } from '@0xsequence/utils' + +export class PublicProvider implements JsonRpcMiddlewareHandler { + private privateJsonRpcMethods = ['net_version', 'eth_chainId', 'eth_accounts', ...SignerJsonRpcMethods] + + private provider?: providers.JsonRpcProvider + private rpcUrl?: string + + constructor(rpcUrl?: string) { + if (rpcUrl) { + this.setRpcUrl(rpcUrl) + } + } + + sendAsyncMiddleware = (next: JsonRpcHandlerFunc) => { + return (request: JsonRpcRequest, callback: JsonRpcResponseCallback) => { + // When provider is configured, send non-private methods to our local public provider + if (this.provider && !this.privateJsonRpcMethods.includes(request.method)) { + this.provider + .send(request.method, request.params!) + .then(r => { + callback(undefined, { + jsonrpc: '2.0', + id: request.id!, + result: r + }) + }) + .catch(e => callback(e)) + return + } + + // Continue to next handler + logger.debug('[public-provider] sending request to signer window', request.method) + next(request, callback) + } + } + + getRpcUrl() { + return this.rpcUrl + } + + setRpcUrl(rpcUrl: string) { + if (!rpcUrl || rpcUrl === '') { + this.rpcUrl = undefined + this.provider = undefined + } else { + this.rpcUrl = rpcUrl + // TODO: maybe use @0xsequence/network JsonRpcProvider here instead, + // which supports better caching. + this.provider = new providers.JsonRpcProvider(rpcUrl) + } + } +} diff --git a/packages/network/src/json-rpc/middleware/signing-provider.ts b/packages/network/src/json-rpc/middleware/signing-provider.ts new file mode 100644 index 0000000000..fab1bcccfb --- /dev/null +++ b/packages/network/src/json-rpc/middleware/signing-provider.ts @@ -0,0 +1,51 @@ +import { JsonRpcHandlerFunc, JsonRpcRequest, JsonRpcResponseCallback, JsonRpcMiddlewareHandler, JsonRpcHandler } from '../types' + +export const SignerJsonRpcMethods = [ + 'personal_sign', + 'eth_sign', + 'eth_signTypedData', + 'eth_signTypedData_v4', + 'eth_sendTransaction', + 'eth_sendRawTransaction', + 'sequence_sign', // sequence-aware personal_sign + 'sequence_signTypedData_v4', // sequence-aware eth_signTypedData_v4 + + 'sequence_getWalletContext', + 'sequence_getWalletConfig', + 'sequence_getWalletState', + 'sequence_getNetworks', + 'sequence_updateConfig', + 'sequence_publishConfig', + 'sequence_gasRefundOptions', + 'sequence_getNonce', + 'sequence_relay', + + 'eth_decrypt', + 'eth_getEncryptionPublicKey', + 'wallet_addEthereumChain', + 'wallet_switchEthereumChain', + 'wallet_registerOnboarding', + 'wallet_watchAsset', + 'wallet_scanQRCode' +] + +export class SigningProvider implements JsonRpcMiddlewareHandler { + private provider: JsonRpcHandler + + constructor(provider: JsonRpcHandler) { + this.provider = provider + } + + sendAsyncMiddleware = (next: JsonRpcHandlerFunc) => { + return (request: JsonRpcRequest, callback: JsonRpcResponseCallback, chainId?: number) => { + // Forward signing requests to the signing provider + if (SignerJsonRpcMethods.includes(request.method)) { + this.provider.sendAsync(request, callback, chainId) + return + } + + // Continue to next handler + next(request, callback, chainId) + } + } +} diff --git a/packages/network/src/json-rpc/middleware/singleflight.ts b/packages/network/src/json-rpc/middleware/singleflight.ts new file mode 100644 index 0000000000..324a478fa0 --- /dev/null +++ b/packages/network/src/json-rpc/middleware/singleflight.ts @@ -0,0 +1,95 @@ +import { JsonRpcHandlerFunc, JsonRpcRequest, JsonRpcResponse, JsonRpcResponseCallback, JsonRpcMiddlewareHandler } from '../types' + +export class SingleflightMiddleware implements JsonRpcMiddlewareHandler { + private singleflightJsonRpcMethods = [ + 'eth_chainId', + 'net_version', + 'eth_call', + 'eth_getCode', + 'eth_blockNumber', + 'eth_getBalance', + 'eth_getStorageAt', + 'eth_getTransactionCount', + 'eth_getBlockTransactionCountByHash', + 'eth_getBlockTransactionCountByNumber', + 'eth_getUncleCountByBlockHash', + 'eth_getUncleCountByBlockNumber', + 'eth_getBlockByHash', + 'eth_getBlockByNumber', + 'eth_getTransactionByHash', + 'eth_getTransactionByBlockHashAndIndex', + 'eth_getTransactionByBlockNumberAndIndex', + 'eth_getTransactionReceipt', + 'eth_getUncleByBlockHashAndIndex', + 'eth_getUncleByBlockNumberAndIndex', + 'eth_getLogs' + ] + + inflight: { [key: string]: { id: number; callback: JsonRpcResponseCallback }[] } + + constructor() { + this.inflight = {} + } + + sendAsyncMiddleware = (next: JsonRpcHandlerFunc) => { + return (request: JsonRpcRequest, callback: JsonRpcResponseCallback, chainId?: number) => { + // continue to next handler if method isn't part of methods list + if (!this.singleflightJsonRpcMethods.includes(request.method)) { + next(request, callback, chainId) + return + } + + const key = this.requestKey(request.method, request.params || [], chainId) + + if (!this.inflight[key]) { + // first request -- init the empty list + this.inflight[key] = [] + } else { + // already in-flight, add the callback to the list and return + this.inflight[key].push({ id: request.id!, callback }) + return + } + + // Continue down the handler chain + next( + request, + (error: any, response?: JsonRpcResponse, chainId?: number) => { + // callback the original request + callback(error, response) + + // callback all other requests of the same kind in queue, with the + // same response result as from the first response. + for (let i = 0; i < this.inflight[key].length; i++) { + const sub = this.inflight[key][i] + if (error) { + sub.callback(error, response) + } else if (response) { + sub.callback(undefined, { + jsonrpc: '2.0', + id: sub.id, + result: response!.result + }) + } + } + + // clear request key + delete this.inflight[key] + }, + chainId + ) + } + } + + requestKey = (method: string, params: any[], chainId?: number) => { + let key = '' + if (chainId) { + key = `${chainId}:${method}:` + } else { + key = `:${method}:` + } + if (!params || params.length === 0) { + return key + '[]' + } + return key + JSON.stringify(params) + } +} diff --git a/packages/network/src/json-rpc/router.ts b/packages/network/src/json-rpc/router.ts new file mode 100644 index 0000000000..26e8a1fa8c --- /dev/null +++ b/packages/network/src/json-rpc/router.ts @@ -0,0 +1,54 @@ +import { + JsonRpcHandlerFunc, + JsonRpcRequest, + JsonRpcResponseCallback, + JsonRpcHandler, + JsonRpcMiddleware, + JsonRpcMiddlewareHandler +} from './types' + +export class JsonRpcRouter implements JsonRpcHandler { + private sender: JsonRpcHandler + private handler: JsonRpcHandlerFunc + + constructor(middlewares: Array, sender: JsonRpcHandler) { + this.sender = sender + if (middlewares) { + this.setMiddleware(middlewares) + } + } + + setMiddleware(middlewares: Array) { + this.handler = createJsonRpcMiddlewareStack(middlewares, this.sender.sendAsync) + } + + sendAsync(request: JsonRpcRequest, callback: JsonRpcResponseCallback, chainId?: number) { + try { + this.handler(request, callback, chainId) + } catch (err) { + callback(err, undefined) + } + } +} + +export const createJsonRpcMiddlewareStack = ( + middlewares: Array, + handler: JsonRpcHandlerFunc +): JsonRpcHandlerFunc => { + if (middlewares.length === 0) return handler + + const toMiddleware = (v: any): JsonRpcMiddleware => { + if (v.sendAsyncMiddleware) { + return (v as JsonRpcMiddlewareHandler).sendAsyncMiddleware + } else { + return v + } + } + + let chain: JsonRpcHandlerFunc + chain = toMiddleware(middlewares[middlewares.length - 1])(handler) + for (let i = middlewares.length - 2; i >= 0; i--) { + chain = toMiddleware(middlewares[i])(chain) + } + return chain +} diff --git a/packages/network/src/json-rpc/sender.ts b/packages/network/src/json-rpc/sender.ts new file mode 100644 index 0000000000..28ad94a054 --- /dev/null +++ b/packages/network/src/json-rpc/sender.ts @@ -0,0 +1,99 @@ +import { providers } from 'ethers' +import { + JsonRpcRequest, + JsonRpcResponse, + JsonRpcResponseCallback, + JsonRpcHandler, + JsonRpcFetchFunc, + JsonRpcRequestFunc, + JsonRpcVersion +} from './types' +import { isJsonRpcProvider, isJsonRpcHandler } from './utils' + +type ExternalProvider = providers.ExternalProvider + +let _nextId = 0 + +export class JsonRpcSender implements JsonRpcHandler { + readonly send: JsonRpcFetchFunc + readonly request: JsonRpcRequestFunc + readonly defaultChainId?: number + + constructor(provider: providers.JsonRpcProvider | JsonRpcHandler | JsonRpcFetchFunc, defaultChainId?: number) { + this.defaultChainId = defaultChainId + + if (isJsonRpcProvider(provider)) { + // we can ignore defaultChainId for JsonRpcProviders as they are already chain-bound + this.send = provider.send.bind(provider) + } else if (isJsonRpcHandler(provider)) { + this.send = (method: string, params?: Array, chainId?: number): Promise => { + return new Promise((resolve, reject) => { + provider.sendAsync( + { + // TODO: really shouldn't have to set these here? + jsonrpc: JsonRpcVersion, + id: ++_nextId, + method, + params + }, + (error: any, response?: JsonRpcResponse) => { + if (error) { + reject(error) + } else if (response) { + resolve(response.result) + } else { + resolve(undefined) + } + }, + chainId || this.defaultChainId + ) + }) + } + } else { + this.send = provider + } + + this.request = (request: { method: string; params?: any[] }, chainId?: number): Promise => { + return this.send(request.method, request.params, chainId) + } + } + + sendAsync = ( + request: JsonRpcRequest, + callback: JsonRpcResponseCallback | ((error: any, response: any) => void), + chainId?: number + ) => { + this.send(request.method, request.params, chainId || this.defaultChainId) + .then(r => { + callback(undefined, { + jsonrpc: '2.0', + id: request.id, + result: r + }) + }) + .catch(e => { + callback(e, undefined) + }) + } +} + +export class JsonRpcExternalProvider implements ExternalProvider, JsonRpcHandler { + constructor(private provider: providers.JsonRpcProvider) {} + + sendAsync = (request: JsonRpcRequest, callback: JsonRpcResponseCallback | ((error: any, response: any) => void)) => { + this.provider + .send(request.method, request.params!) + .then(r => { + callback(undefined, { + jsonrpc: '2.0', + id: request.id, + result: r + }) + }) + .catch(e => { + callback(e, undefined) + }) + } + + send = this.sendAsync +} diff --git a/packages/network/src/json-rpc/types.ts b/packages/network/src/json-rpc/types.ts new file mode 100644 index 0000000000..cfe45f8fbe --- /dev/null +++ b/packages/network/src/json-rpc/types.ts @@ -0,0 +1,39 @@ +export const JsonRpcVersion = '2.0' + +export interface JsonRpcRequest { + jsonrpc?: string + id?: number + method: string + params?: any[] +} + +export interface JsonRpcResponse { + jsonrpc: string + id: number + result: any + error?: ProviderRpcError +} + +export type JsonRpcResponseCallback = (error?: ProviderRpcError, response?: JsonRpcResponse) => void + +export type JsonRpcHandlerFunc = (request: JsonRpcRequest, callback: JsonRpcResponseCallback, chainId?: number) => void + +export interface JsonRpcHandler { + sendAsync: JsonRpcHandlerFunc +} + +export type JsonRpcFetchFunc = (method: string, params?: any[], chainId?: number) => Promise + +// EIP-1193 function signature +export type JsonRpcRequestFunc = (request: { method: string; params?: any[] }, chainId?: number) => Promise + +export type JsonRpcMiddleware = (next: JsonRpcHandlerFunc) => JsonRpcHandlerFunc + +export interface JsonRpcMiddlewareHandler { + sendAsyncMiddleware: JsonRpcMiddleware +} + +export interface ProviderRpcError extends Error { + code?: number + data?: { [key: string]: any } +} diff --git a/packages/network/src/json-rpc/utils.ts b/packages/network/src/json-rpc/utils.ts new file mode 100644 index 0000000000..7d03f965f1 --- /dev/null +++ b/packages/network/src/json-rpc/utils.ts @@ -0,0 +1,17 @@ +import { providers } from 'ethers' +import { JsonRpcHandler } from './types' + +export function isJsonRpcProvider(cand: any): cand is providers.JsonRpcProvider { + return ( + cand !== undefined && + cand.send !== undefined && + cand.constructor.defaultUrl !== undefined && + cand.detectNetwork !== undefined && + cand.getSigner !== undefined && + cand.perform !== undefined + ) +} + +export function isJsonRpcHandler(cand: any): cand is JsonRpcHandler { + return cand !== undefined && cand.sendAsync !== undefined +} diff --git a/packages/network/src/utils.ts b/packages/network/src/utils.ts new file mode 100644 index 0000000000..648eb9a699 --- /dev/null +++ b/packages/network/src/utils.ts @@ -0,0 +1,210 @@ +import { ethers, BigNumberish } from 'ethers' +import { ChainIdLike } from '.' +import { NetworkConfig } from './config' + +export function isNetworkConfig(cand: any): cand is NetworkConfig { + return cand && cand.chainId !== undefined && cand.name !== undefined && cand.rpcUrl !== undefined && cand.relayer !== undefined +} + +export const getChainId = (chainId: ChainIdLike): number => { + if (typeof chainId === 'number') { + return chainId + } + if ((chainId).chainId) { + return (chainId).chainId + } + return ethers.BigNumber.from(chainId as BigNumberish).toNumber() +} + +export const maybeChainId = (chainId?: ChainIdLike): number | undefined => { + if (!chainId) return undefined + return getChainId(chainId) +} + +export const isValidNetworkConfig = ( + networkConfig: NetworkConfig | NetworkConfig[], + raise: boolean = false, + skipRelayerCheck: boolean = false +): boolean => { + if (!networkConfig) throw new Error(`invalid network config: empty config`) + + const configs: NetworkConfig[] = [] + if (Array.isArray(networkConfig)) { + configs.push(...networkConfig) + } else { + configs.push(networkConfig) + } + + if (configs.length === 0) { + if (raise) throw new Error(`invalid network config: empty config`) + return false + } + + // Ensure distinct chainId configs + const chainIds = configs.map(c => c.chainId).sort() + const dupes = chainIds.filter((c, i) => chainIds.indexOf(c) !== i) + if (dupes.length > 0) { + if (raise) throw new Error(`invalid network config: duplicate chainIds ${dupes}`) + return false + } + + // Downcase all network names + configs.forEach(c => (c.name = c.name.toLowerCase())) + + // Ensure distinct network names + const names = configs.map(c => c.name).sort() + const nameDupes = names.filter((c, i) => names.indexOf(c) !== i) + if (nameDupes.length > 0) { + if (raise) throw new Error(`invalid network config: duplicate network names ${nameDupes}`) + return false + } + + // Ensure rpcUrl or provider is specified + // Ensure relayerUrl or relayer is specified + // Ensure one default chain + // Ensure one auth chain + let defaultChain = false + for (let i = 0; i < configs.length; i++) { + const c = configs[i] + if ((!c.rpcUrl || c.rpcUrl === '') && !c.provider) { + if (raise) throw new Error(`invalid network config for chainId ${c.chainId}: rpcUrl or provider must be provided`) + return false + } + if (!skipRelayerCheck) { + if (!c.relayer) { + if (raise) throw new Error(`invalid network config for chainId ${c.chainId}: relayer must be provided`) + return false + } + } + if (c.isDefaultChain) { + if (defaultChain) { + if (raise) + throw new Error(`invalid network config for chainId ${c.chainId}: DefaultChain is already set by another config`) + return false + } + defaultChain = true + } + } + + if (!defaultChain) { + if (raise) throw new Error(`invalid network config: DefaultChain must be set`) + return false + } + + return true +} + +export const ensureValidNetworks = (networks: NetworkConfig[], skipRelayerCheck: boolean = false): NetworkConfig[] => { + isValidNetworkConfig(networks, true, skipRelayerCheck) + return networks +} + +export const ensureUniqueNetworks = (networks: NetworkConfig[], raise: boolean = true): boolean => { + const chainIds = networks.map(c => c.chainId).sort() + const dupes = chainIds.filter((c, i) => chainIds.indexOf(c) !== i) + if (dupes.length > 0) { + if (raise) throw new Error(`invalid network config: duplicate chainIds ${dupes}`) + return false + } + return true +} + +export const updateNetworkConfig = (src: Partial, dest: NetworkConfig) => { + if (!src || !dest) return + + if (!src.chainId && !src.name) { + throw new Error('failed to update network config: source config is missing chainId or name') + } + if (src.chainId !== dest.chainId && src.name !== dest.name) { + throw new Error('failed to update network config: one of chainId or name must match') + } + + if (src.rpcUrl) { + dest.rpcUrl = src.rpcUrl + dest.provider = undefined + } + if (src.provider) { + dest.provider = src.provider + } + if (src.relayer) { + dest.relayer = src.relayer + } +} + +export const validateAndSortNetworks = (networks: NetworkConfig[]) => { + return ensureValidNetworks(sortNetworks(networks)) +} + +export const findNetworkConfig = (networks: NetworkConfig[], chainId: ChainIdLike): NetworkConfig | undefined => { + if (typeof chainId === 'string') { + if (chainId.startsWith('0x')) { + const id = ethers.BigNumber.from(chainId).toNumber() + return networks.find(n => n.chainId === id) + } else { + return networks.find(n => n.name === chainId || `${n.chainId}` === chainId) + } + } else if (typeof chainId === 'number') { + return networks.find(n => n.chainId === chainId) + } else if ((chainId).chainId) { + return networks.find(n => n.chainId === (chainId).chainId) + } else if (ethers.BigNumber.isBigNumber(chainId)) { + const id = chainId.toNumber() + return networks.find(n => n.chainId === id) + } else { + return undefined + } +} + +export const checkNetworkConfig = (network: NetworkConfig, chainId: string | number): boolean => { + if (!network) return false + if (network.name === chainId) return true + if (network.chainId === chainId) return true + return false +} + +export const networksIndex = (networks: NetworkConfig[]): { [key: string]: NetworkConfig } => { + const index: { [key: string]: NetworkConfig } = {} + for (let i = 0; i < networks.length; i++) { + index[networks[i].name] = networks[i] + } + return index +} + +// TODO: we should remove sortNetworks in the future but this is a breaking change for dapp integrations on older versions <-> wallet +// sortNetworks orders the network config list by: defaultChain, authChain, ..rest by chainId ascending numbers +export const sortNetworks = (networks: NetworkConfig[]): NetworkConfig[] => { + if (!networks) { + return [] + } + + const config = networks.sort((a, b) => { + if (a.chainId === b.chainId) return 0 + return a.chainId < b.chainId ? -1 : 1 + }) + + // DefaultChain goes first + const defaultConfigIdx = config.findIndex(c => c.isDefaultChain) + if (defaultConfigIdx > 0) config.splice(0, 0, config.splice(defaultConfigIdx, 1)[0]) + + return config +} + +export const stringTemplate = (sTemplate: string, mData: any) => { + if (typeof sTemplate === 'string') { + mData = mData ? mData : {} + return sTemplate.replace(/\$\{\s*([$#@\-\d\w]+)\s*\}/gim, function (fullMath, grp) { + let val = mData[grp] + if (typeof val === 'function') { + val = val() + } else if (val === null || val === undefined) { + val = '' + } else if (typeof val === 'object' || typeof val === 'symbol') { + val = val.toString() + } else { + val = val.valueOf() + } + return val + }) + } + return '' +} diff --git a/packages/provider/CHANGELOG.md b/packages/provider/CHANGELOG.md new file mode 100644 index 0000000000..a3e6100d7f --- /dev/null +++ b/packages/provider/CHANGELOG.md @@ -0,0 +1,4480 @@ +# @0xsequence/provider + +## 2.0.0 + +### Major Changes + +- changeset + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@2.0.0 + - @0xsequence/account@2.0.0 + - @0xsequence/auth@2.0.0 + - @0xsequence/core@2.0.0 + - @0xsequence/migration@2.0.0 + - @0xsequence/network@2.0.0 + - @0xsequence/relayer@2.0.0 + - @0xsequence/utils@2.0.0 + - @0xsequence/wallet@2.0.0 + +## 1.10.14 + +### Patch Changes + +- network: add borne-testnet to allNetworks +- Updated dependencies + - @0xsequence/abi@1.10.14 + - @0xsequence/account@1.10.14 + - @0xsequence/auth@1.10.14 + - @0xsequence/core@1.10.14 + - @0xsequence/migration@1.10.14 + - @0xsequence/network@1.10.14 + - @0xsequence/relayer@1.10.14 + - @0xsequence/utils@1.10.14 + - @0xsequence/wallet@1.10.14 + +## 1.10.13 + +### Patch Changes + +- network: add borne testnet +- Updated dependencies + - @0xsequence/abi@1.10.13 + - @0xsequence/account@1.10.13 + - @0xsequence/auth@1.10.13 + - @0xsequence/core@1.10.13 + - @0xsequence/migration@1.10.13 + - @0xsequence/network@1.10.13 + - @0xsequence/relayer@1.10.13 + - @0xsequence/utils@1.10.13 + - @0xsequence/wallet@1.10.13 + +## 1.10.12 + +### Patch Changes + +- api: update bindings +- global/window -> globalThis +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.10.12 + - @0xsequence/account@1.10.12 + - @0xsequence/auth@1.10.12 + - @0xsequence/core@1.10.12 + - @0xsequence/migration@1.10.12 + - @0xsequence/network@1.10.12 + - @0xsequence/relayer@1.10.12 + - @0xsequence/utils@1.10.12 + - @0xsequence/wallet@1.10.12 + +## 1.10.11 + +### Patch Changes + +- waas: updated intent.gen without webrpc types, errors exported from authenticator.gen +- Updated dependencies + - @0xsequence/abi@1.10.11 + - @0xsequence/account@1.10.11 + - @0xsequence/auth@1.10.11 + - @0xsequence/core@1.10.11 + - @0xsequence/migration@1.10.11 + - @0xsequence/network@1.10.11 + - @0xsequence/relayer@1.10.11 + - @0xsequence/utils@1.10.11 + - @0xsequence/wallet@1.10.11 + +## 1.10.10 + +### Patch Changes + +- metadata: update bindings with new contract collections api +- Updated dependencies + - @0xsequence/abi@1.10.10 + - @0xsequence/account@1.10.10 + - @0xsequence/auth@1.10.10 + - @0xsequence/core@1.10.10 + - @0xsequence/migration@1.10.10 + - @0xsequence/network@1.10.10 + - @0xsequence/relayer@1.10.10 + - @0xsequence/utils@1.10.10 + - @0xsequence/wallet@1.10.10 + +## 1.10.9 + +### Patch Changes + +- waas minor update +- Updated dependencies + - @0xsequence/abi@1.10.9 + - @0xsequence/account@1.10.9 + - @0xsequence/auth@1.10.9 + - @0xsequence/core@1.10.9 + - @0xsequence/migration@1.10.9 + - @0xsequence/network@1.10.9 + - @0xsequence/relayer@1.10.9 + - @0xsequence/utils@1.10.9 + - @0xsequence/wallet@1.10.9 + +## 1.10.8 + +### Patch Changes + +- update metadata bindings +- Updated dependencies + - @0xsequence/abi@1.10.8 + - @0xsequence/account@1.10.8 + - @0xsequence/auth@1.10.8 + - @0xsequence/core@1.10.8 + - @0xsequence/migration@1.10.8 + - @0xsequence/network@1.10.8 + - @0xsequence/relayer@1.10.8 + - @0xsequence/utils@1.10.8 + - @0xsequence/wallet@1.10.8 + +## 1.10.7 + +### Patch Changes + +- minor fixes to waas client +- Updated dependencies + - @0xsequence/abi@1.10.7 + - @0xsequence/account@1.10.7 + - @0xsequence/auth@1.10.7 + - @0xsequence/core@1.10.7 + - @0xsequence/migration@1.10.7 + - @0xsequence/network@1.10.7 + - @0xsequence/relayer@1.10.7 + - @0xsequence/utils@1.10.7 + - @0xsequence/wallet@1.10.7 + +## 1.10.6 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/abi@1.10.6 + - @0xsequence/account@1.10.6 + - @0xsequence/auth@1.10.6 + - @0xsequence/core@1.10.6 + - @0xsequence/migration@1.10.6 + - @0xsequence/network@1.10.6 + - @0xsequence/relayer@1.10.6 + - @0xsequence/utils@1.10.6 + - @0xsequence/wallet@1.10.6 + +## 1.10.5 + +### Patch Changes + +- network: ape-chain-testnet -> apechain-testnet +- Updated dependencies + - @0xsequence/abi@1.10.5 + - @0xsequence/account@1.10.5 + - @0xsequence/auth@1.10.5 + - @0xsequence/core@1.10.5 + - @0xsequence/migration@1.10.5 + - @0xsequence/network@1.10.5 + - @0xsequence/relayer@1.10.5 + - @0xsequence/utils@1.10.5 + - @0xsequence/wallet@1.10.5 + +## 1.10.4 + +### Patch Changes + +- network: add b3-sepolia, ape-chain-testnet, blast, blast-sepolia +- Updated dependencies + - @0xsequence/abi@1.10.4 + - @0xsequence/account@1.10.4 + - @0xsequence/auth@1.10.4 + - @0xsequence/core@1.10.4 + - @0xsequence/migration@1.10.4 + - @0xsequence/network@1.10.4 + - @0xsequence/relayer@1.10.4 + - @0xsequence/utils@1.10.4 + - @0xsequence/wallet@1.10.4 + +## 1.10.3 + +### Patch Changes + +- typing fix +- Updated dependencies + - @0xsequence/abi@1.10.3 + - @0xsequence/account@1.10.3 + - @0xsequence/auth@1.10.3 + - @0xsequence/core@1.10.3 + - @0xsequence/migration@1.10.3 + - @0xsequence/network@1.10.3 + - @0xsequence/relayer@1.10.3 + - @0xsequence/utils@1.10.3 + - @0xsequence/wallet@1.10.3 + +## 1.10.2 + +### Patch Changes + +- - waas: add getIdToken method + - indexer: update api client +- Updated dependencies + - @0xsequence/abi@1.10.2 + - @0xsequence/account@1.10.2 + - @0xsequence/auth@1.10.2 + - @0xsequence/core@1.10.2 + - @0xsequence/migration@1.10.2 + - @0xsequence/network@1.10.2 + - @0xsequence/relayer@1.10.2 + - @0xsequence/utils@1.10.2 + - @0xsequence/wallet@1.10.2 + +## 1.10.1 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/abi@1.10.1 + - @0xsequence/account@1.10.1 + - @0xsequence/auth@1.10.1 + - @0xsequence/core@1.10.1 + - @0xsequence/migration@1.10.1 + - @0xsequence/network@1.10.1 + - @0xsequence/relayer@1.10.1 + - @0xsequence/utils@1.10.1 + - @0xsequence/wallet@1.10.1 + +## 1.10.0 + +### Minor Changes + +- waas release v1.3.0 + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.10.0 + - @0xsequence/account@1.10.0 + - @0xsequence/auth@1.10.0 + - @0xsequence/core@1.10.0 + - @0xsequence/migration@1.10.0 + - @0xsequence/network@1.10.0 + - @0xsequence/relayer@1.10.0 + - @0xsequence/utils@1.10.0 + - @0xsequence/wallet@1.10.0 + +## 1.9.37 + +### Patch Changes + +- network: adds nativeToken data to NetworkMetadata constants +- Updated dependencies + - @0xsequence/abi@1.9.37 + - @0xsequence/account@1.9.37 + - @0xsequence/auth@1.9.37 + - @0xsequence/core@1.9.37 + - @0xsequence/migration@1.9.37 + - @0xsequence/network@1.9.37 + - @0xsequence/relayer@1.9.37 + - @0xsequence/utils@1.9.37 + - @0xsequence/wallet@1.9.37 + +## 1.9.36 + +### Patch Changes + +- guard: export client +- Updated dependencies + - @0xsequence/abi@1.9.36 + - @0xsequence/account@1.9.36 + - @0xsequence/auth@1.9.36 + - @0xsequence/core@1.9.36 + - @0xsequence/migration@1.9.36 + - @0xsequence/network@1.9.36 + - @0xsequence/relayer@1.9.36 + - @0xsequence/utils@1.9.36 + - @0xsequence/wallet@1.9.36 + +## 1.9.35 + +### Patch Changes + +- guard: update bindings +- Updated dependencies + - @0xsequence/abi@1.9.35 + - @0xsequence/account@1.9.35 + - @0xsequence/auth@1.9.35 + - @0xsequence/core@1.9.35 + - @0xsequence/migration@1.9.35 + - @0xsequence/network@1.9.35 + - @0xsequence/relayer@1.9.35 + - @0xsequence/utils@1.9.35 + - @0xsequence/wallet@1.9.35 + +## 1.9.34 + +### Patch Changes + +- waas: always use lowercase email +- Updated dependencies + - @0xsequence/abi@1.9.34 + - @0xsequence/account@1.9.34 + - @0xsequence/auth@1.9.34 + - @0xsequence/core@1.9.34 + - @0xsequence/migration@1.9.34 + - @0xsequence/network@1.9.34 + - @0xsequence/relayer@1.9.34 + - @0xsequence/utils@1.9.34 + - @0xsequence/wallet@1.9.34 + +## 1.9.33 + +### Patch Changes + +- waas: umd build +- Updated dependencies + - @0xsequence/abi@1.9.33 + - @0xsequence/account@1.9.33 + - @0xsequence/auth@1.9.33 + - @0xsequence/core@1.9.33 + - @0xsequence/migration@1.9.33 + - @0xsequence/network@1.9.33 + - @0xsequence/relayer@1.9.33 + - @0xsequence/utils@1.9.33 + - @0xsequence/wallet@1.9.33 + +## 1.9.32 + +### Patch Changes + +- indexer: update bindings +- Updated dependencies + - @0xsequence/abi@1.9.32 + - @0xsequence/account@1.9.32 + - @0xsequence/auth@1.9.32 + - @0xsequence/core@1.9.32 + - @0xsequence/migration@1.9.32 + - @0xsequence/network@1.9.32 + - @0xsequence/relayer@1.9.32 + - @0xsequence/utils@1.9.32 + - @0xsequence/wallet@1.9.32 + +## 1.9.31 + +### Patch Changes + +- metadata: token directory changes +- Updated dependencies + - @0xsequence/abi@1.9.31 + - @0xsequence/account@1.9.31 + - @0xsequence/auth@1.9.31 + - @0xsequence/core@1.9.31 + - @0xsequence/migration@1.9.31 + - @0xsequence/network@1.9.31 + - @0xsequence/relayer@1.9.31 + - @0xsequence/utils@1.9.31 + - @0xsequence/wallet@1.9.31 + +## 1.9.30 + +### Patch Changes + +- update +- Updated dependencies + - @0xsequence/abi@1.9.30 + - @0xsequence/account@1.9.30 + - @0xsequence/auth@1.9.30 + - @0xsequence/core@1.9.30 + - @0xsequence/migration@1.9.30 + - @0xsequence/network@1.9.30 + - @0xsequence/relayer@1.9.30 + - @0xsequence/utils@1.9.30 + - @0xsequence/wallet@1.9.30 + +## 1.9.29 + +### Patch Changes + +- disable gnosis chain +- Updated dependencies + - @0xsequence/abi@1.9.29 + - @0xsequence/account@1.9.29 + - @0xsequence/auth@1.9.29 + - @0xsequence/core@1.9.29 + - @0xsequence/migration@1.9.29 + - @0xsequence/network@1.9.29 + - @0xsequence/relayer@1.9.29 + - @0xsequence/utils@1.9.29 + - @0xsequence/wallet@1.9.29 + +## 1.9.28 + +### Patch Changes + +- add utils/merkletree +- Updated dependencies + - @0xsequence/abi@1.9.28 + - @0xsequence/account@1.9.28 + - @0xsequence/auth@1.9.28 + - @0xsequence/core@1.9.28 + - @0xsequence/migration@1.9.28 + - @0xsequence/network@1.9.28 + - @0xsequence/relayer@1.9.28 + - @0xsequence/utils@1.9.28 + - @0xsequence/wallet@1.9.28 + +## 1.9.27 + +### Patch Changes + +- network: optimistic -> optimism +- waas: remove defaults +- api, sessions: update bindings +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.9.27 + - @0xsequence/account@1.9.27 + - @0xsequence/auth@1.9.27 + - @0xsequence/core@1.9.27 + - @0xsequence/migration@1.9.27 + - @0xsequence/network@1.9.27 + - @0xsequence/relayer@1.9.27 + - @0xsequence/utils@1.9.27 + - @0xsequence/wallet@1.9.27 + +## 1.9.26 + +### Patch Changes + +- - add backend interfaces for pluggable interfaces + - introduce @0xsequence/react-native + - update pnpm to lockfile v9 +- Updated dependencies + - @0xsequence/abi@1.9.26 + - @0xsequence/account@1.9.26 + - @0xsequence/auth@1.9.26 + - @0xsequence/core@1.9.26 + - @0xsequence/migration@1.9.26 + - @0xsequence/network@1.9.26 + - @0xsequence/relayer@1.9.26 + - @0xsequence/utils@1.9.26 + - @0xsequence/wallet@1.9.26 + +## 1.9.25 + +### Patch Changes + +- update webrpc clients with new error types +- Updated dependencies + - @0xsequence/abi@1.9.25 + - @0xsequence/account@1.9.25 + - @0xsequence/auth@1.9.25 + - @0xsequence/core@1.9.25 + - @0xsequence/migration@1.9.25 + - @0xsequence/network@1.9.25 + - @0xsequence/relayer@1.9.25 + - @0xsequence/utils@1.9.25 + - @0xsequence/wallet@1.9.25 + +## 1.9.24 + +### Patch Changes + +- waas: add memoryStore backend to localStore +- Updated dependencies + - @0xsequence/abi@1.9.24 + - @0xsequence/account@1.9.24 + - @0xsequence/auth@1.9.24 + - @0xsequence/core@1.9.24 + - @0xsequence/migration@1.9.24 + - @0xsequence/network@1.9.24 + - @0xsequence/relayer@1.9.24 + - @0xsequence/utils@1.9.24 + - @0xsequence/wallet@1.9.24 + +## 1.9.23 + +### Patch Changes + +- update api client bindings +- Updated dependencies + - @0xsequence/abi@1.9.23 + - @0xsequence/account@1.9.23 + - @0xsequence/auth@1.9.23 + - @0xsequence/core@1.9.23 + - @0xsequence/migration@1.9.23 + - @0xsequence/network@1.9.23 + - @0xsequence/relayer@1.9.23 + - @0xsequence/utils@1.9.23 + - @0xsequence/wallet@1.9.23 + +## 1.9.22 + +### Patch Changes + +- update metadata client bindings +- Updated dependencies + - @0xsequence/abi@1.9.22 + - @0xsequence/account@1.9.22 + - @0xsequence/auth@1.9.22 + - @0xsequence/core@1.9.22 + - @0xsequence/migration@1.9.22 + - @0xsequence/network@1.9.22 + - @0xsequence/relayer@1.9.22 + - @0xsequence/utils@1.9.22 + - @0xsequence/wallet@1.9.22 + +## 1.9.21 + +### Patch Changes + +- api client bindings +- Updated dependencies + - @0xsequence/abi@1.9.21 + - @0xsequence/account@1.9.21 + - @0xsequence/auth@1.9.21 + - @0xsequence/core@1.9.21 + - @0xsequence/migration@1.9.21 + - @0xsequence/network@1.9.21 + - @0xsequence/relayer@1.9.21 + - @0xsequence/utils@1.9.21 + - @0xsequence/wallet@1.9.21 + +## 1.9.20 + +### Patch Changes + +- api client bindings update +- Updated dependencies + - @0xsequence/abi@1.9.20 + - @0xsequence/account@1.9.20 + - @0xsequence/auth@1.9.20 + - @0xsequence/core@1.9.20 + - @0xsequence/migration@1.9.20 + - @0xsequence/network@1.9.20 + - @0xsequence/relayer@1.9.20 + - @0xsequence/utils@1.9.20 + - @0xsequence/wallet@1.9.20 + +## 1.9.19 + +### Patch Changes + +- waas update +- Updated dependencies + - @0xsequence/abi@1.9.19 + - @0xsequence/account@1.9.19 + - @0xsequence/auth@1.9.19 + - @0xsequence/core@1.9.19 + - @0xsequence/migration@1.9.19 + - @0xsequence/network@1.9.19 + - @0xsequence/relayer@1.9.19 + - @0xsequence/utils@1.9.19 + - @0xsequence/wallet@1.9.19 + +## 1.9.18 + +### Patch Changes + +- provider: prohibit dangerous functions +- Updated dependencies + - @0xsequence/abi@1.9.18 + - @0xsequence/account@1.9.18 + - @0xsequence/auth@1.9.18 + - @0xsequence/core@1.9.18 + - @0xsequence/migration@1.9.18 + - @0xsequence/network@1.9.18 + - @0xsequence/relayer@1.9.18 + - @0xsequence/utils@1.9.18 + - @0xsequence/wallet@1.9.18 + +## 1.9.17 + +### Patch Changes + +- network: add xr-sepolia +- Updated dependencies + - @0xsequence/network@1.9.17 + - @0xsequence/abi@1.9.17 + - @0xsequence/account@1.9.17 + - @0xsequence/auth@1.9.17 + - @0xsequence/core@1.9.17 + - @0xsequence/migration@1.9.17 + - @0xsequence/relayer@1.9.17 + - @0xsequence/utils@1.9.17 + - @0xsequence/wallet@1.9.17 + +## 1.9.16 + +### Patch Changes + +- waas: sequence.feeOptions +- Updated dependencies + - @0xsequence/abi@1.9.16 + - @0xsequence/account@1.9.16 + - @0xsequence/auth@1.9.16 + - @0xsequence/core@1.9.16 + - @0xsequence/migration@1.9.16 + - @0xsequence/network@1.9.16 + - @0xsequence/relayer@1.9.16 + - @0xsequence/utils@1.9.16 + - @0xsequence/wallet@1.9.16 + +## 1.9.15 + +### Patch Changes + +- metadata: collection external_link field name fix +- Updated dependencies + - @0xsequence/abi@1.9.15 + - @0xsequence/account@1.9.15 + - @0xsequence/auth@1.9.15 + - @0xsequence/core@1.9.15 + - @0xsequence/migration@1.9.15 + - @0xsequence/network@1.9.15 + - @0xsequence/relayer@1.9.15 + - @0xsequence/utils@1.9.15 + - @0xsequence/wallet@1.9.15 + +## 1.9.14 + +### Patch Changes + +- network: astar-zkatana -> astar-zkyoto +- network: deprecate polygon mumbai network +- network: add xai and polygon amoy +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.9.14 + - @0xsequence/account@1.9.14 + - @0xsequence/auth@1.9.14 + - @0xsequence/core@1.9.14 + - @0xsequence/migration@1.9.14 + - @0xsequence/network@1.9.14 + - @0xsequence/relayer@1.9.14 + - @0xsequence/utils@1.9.14 + - @0xsequence/wallet@1.9.14 + +## 1.9.13 + +### Patch Changes + +- waas: fix @0xsequence/network dependency +- Updated dependencies + - @0xsequence/abi@1.9.13 + - @0xsequence/account@1.9.13 + - @0xsequence/auth@1.9.13 + - @0xsequence/core@1.9.13 + - @0xsequence/migration@1.9.13 + - @0xsequence/network@1.9.13 + - @0xsequence/relayer@1.9.13 + - @0xsequence/utils@1.9.13 + - @0xsequence/wallet@1.9.13 + +## 1.9.12 + +### Patch Changes + +- indexer: update rpc bindings +- provider: signMessage: Serialize the BytesLike or string message into hexstring before sending +- waas: SessionAuthProof +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.9.12 + - @0xsequence/account@1.9.12 + - @0xsequence/auth@1.9.12 + - @0xsequence/core@1.9.12 + - @0xsequence/migration@1.9.12 + - @0xsequence/network@1.9.12 + - @0xsequence/relayer@1.9.12 + - @0xsequence/utils@1.9.12 + - @0xsequence/wallet@1.9.12 + +## 1.9.11 + +### Patch Changes + +- metdata, update rpc bindings +- Updated dependencies + - @0xsequence/abi@1.9.11 + - @0xsequence/account@1.9.11 + - @0xsequence/auth@1.9.11 + - @0xsequence/core@1.9.11 + - @0xsequence/migration@1.9.11 + - @0xsequence/network@1.9.11 + - @0xsequence/relayer@1.9.11 + - @0xsequence/utils@1.9.11 + - @0xsequence/wallet@1.9.11 + +## 1.9.10 + +### Patch Changes + +- update metadata rpc bindings +- Updated dependencies + - @0xsequence/abi@1.9.10 + - @0xsequence/account@1.9.10 + - @0xsequence/auth@1.9.10 + - @0xsequence/core@1.9.10 + - @0xsequence/migration@1.9.10 + - @0xsequence/network@1.9.10 + - @0xsequence/relayer@1.9.10 + - @0xsequence/utils@1.9.10 + - @0xsequence/wallet@1.9.10 + +## 1.9.9 + +### Patch Changes + +- metadata, add SequenceCollections rpc client +- Updated dependencies + - @0xsequence/abi@1.9.9 + - @0xsequence/account@1.9.9 + - @0xsequence/auth@1.9.9 + - @0xsequence/core@1.9.9 + - @0xsequence/migration@1.9.9 + - @0xsequence/network@1.9.9 + - @0xsequence/relayer@1.9.9 + - @0xsequence/utils@1.9.9 + - @0xsequence/wallet@1.9.9 + +## 1.9.8 + +### Patch Changes + +- waas client update +- Updated dependencies + - @0xsequence/abi@1.9.8 + - @0xsequence/account@1.9.8 + - @0xsequence/auth@1.9.8 + - @0xsequence/core@1.9.8 + - @0xsequence/migration@1.9.8 + - @0xsequence/network@1.9.8 + - @0xsequence/relayer@1.9.8 + - @0xsequence/utils@1.9.8 + - @0xsequence/wallet@1.9.8 + +## 1.9.7 + +### Patch Changes + +- update rpc client bindings for api, metadata and relayer +- Updated dependencies + - @0xsequence/abi@1.9.7 + - @0xsequence/account@1.9.7 + - @0xsequence/auth@1.9.7 + - @0xsequence/core@1.9.7 + - @0xsequence/migration@1.9.7 + - @0xsequence/network@1.9.7 + - @0xsequence/relayer@1.9.7 + - @0xsequence/utils@1.9.7 + - @0xsequence/wallet@1.9.7 + +## 1.9.6 + +### Patch Changes + +- waas package update +- Updated dependencies + - @0xsequence/abi@1.9.6 + - @0xsequence/account@1.9.6 + - @0xsequence/auth@1.9.6 + - @0xsequence/core@1.9.6 + - @0xsequence/migration@1.9.6 + - @0xsequence/network@1.9.6 + - @0xsequence/relayer@1.9.6 + - @0xsequence/utils@1.9.6 + - @0xsequence/wallet@1.9.6 + +## 1.9.5 + +### Patch Changes + +- RpcRelayer prioritize project access key +- Updated dependencies + - @0xsequence/abi@1.9.5 + - @0xsequence/account@1.9.5 + - @0xsequence/auth@1.9.5 + - @0xsequence/core@1.9.5 + - @0xsequence/migration@1.9.5 + - @0xsequence/network@1.9.5 + - @0xsequence/relayer@1.9.5 + - @0xsequence/utils@1.9.5 + - @0xsequence/wallet@1.9.5 + +## 1.9.4 + +### Patch Changes + +- waas: fix network dependency +- Updated dependencies + - @0xsequence/abi@1.9.4 + - @0xsequence/account@1.9.4 + - @0xsequence/auth@1.9.4 + - @0xsequence/core@1.9.4 + - @0xsequence/migration@1.9.4 + - @0xsequence/network@1.9.4 + - @0xsequence/relayer@1.9.4 + - @0xsequence/utils@1.9.4 + - @0xsequence/wallet@1.9.4 + +## 1.9.3 + +### Patch Changes + +- provider: don't append access key to RPC url if user has already provided it +- Updated dependencies + - @0xsequence/abi@1.9.3 + - @0xsequence/account@1.9.3 + - @0xsequence/auth@1.9.3 + - @0xsequence/core@1.9.3 + - @0xsequence/migration@1.9.3 + - @0xsequence/network@1.9.3 + - @0xsequence/relayer@1.9.3 + - @0xsequence/utils@1.9.3 + - @0xsequence/wallet@1.9.3 + +## 1.9.2 + +### Patch Changes + +- network: add xai-sepolia +- Updated dependencies + - @0xsequence/abi@1.9.2 + - @0xsequence/account@1.9.2 + - @0xsequence/auth@1.9.2 + - @0xsequence/core@1.9.2 + - @0xsequence/migration@1.9.2 + - @0xsequence/network@1.9.2 + - @0xsequence/relayer@1.9.2 + - @0xsequence/utils@1.9.2 + - @0xsequence/wallet@1.9.2 + +## 1.9.1 + +### Patch Changes + +- analytics fix +- Updated dependencies + - @0xsequence/abi@1.9.1 + - @0xsequence/account@1.9.1 + - @0xsequence/auth@1.9.1 + - @0xsequence/core@1.9.1 + - @0xsequence/migration@1.9.1 + - @0xsequence/network@1.9.1 + - @0xsequence/relayer@1.9.1 + - @0xsequence/utils@1.9.1 + - @0xsequence/wallet@1.9.1 + +## 1.9.0 + +### Minor Changes + +- waas release + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.9.0 + - @0xsequence/account@1.9.0 + - @0xsequence/auth@1.9.0 + - @0xsequence/core@1.9.0 + - @0xsequence/migration@1.9.0 + - @0xsequence/network@1.9.0 + - @0xsequence/relayer@1.9.0 + - @0xsequence/utils@1.9.0 + - @0xsequence/wallet@1.9.0 + +## 1.8.8 + +### Patch Changes + +- update metadata bindings +- Updated dependencies + - @0xsequence/abi@1.8.8 + - @0xsequence/account@1.8.8 + - @0xsequence/auth@1.8.8 + - @0xsequence/core@1.8.8 + - @0xsequence/migration@1.8.8 + - @0xsequence/network@1.8.8 + - @0xsequence/relayer@1.8.8 + - @0xsequence/utils@1.8.8 + - @0xsequence/wallet@1.8.8 + +## 1.8.7 + +### Patch Changes + +- provider: update databeat to 0.9.1 +- Updated dependencies + - @0xsequence/abi@1.8.7 + - @0xsequence/account@1.8.7 + - @0xsequence/auth@1.8.7 + - @0xsequence/core@1.8.7 + - @0xsequence/migration@1.8.7 + - @0xsequence/network@1.8.7 + - @0xsequence/relayer@1.8.7 + - @0xsequence/utils@1.8.7 + - @0xsequence/wallet@1.8.7 + +## 1.8.6 + +### Patch Changes + +- guard: SignedOwnershipProof +- Updated dependencies + - @0xsequence/abi@1.8.6 + - @0xsequence/account@1.8.6 + - @0xsequence/auth@1.8.6 + - @0xsequence/core@1.8.6 + - @0xsequence/migration@1.8.6 + - @0xsequence/network@1.8.6 + - @0xsequence/relayer@1.8.6 + - @0xsequence/utils@1.8.6 + - @0xsequence/wallet@1.8.6 + +## 1.8.5 + +### Patch Changes + +- guard: signOwnershipProof and isSignedOwnershipProof +- Updated dependencies + - @0xsequence/abi@1.8.5 + - @0xsequence/account@1.8.5 + - @0xsequence/auth@1.8.5 + - @0xsequence/core@1.8.5 + - @0xsequence/migration@1.8.5 + - @0xsequence/network@1.8.5 + - @0xsequence/relayer@1.8.5 + - @0xsequence/utils@1.8.5 + - @0xsequence/wallet@1.8.5 + +## 1.8.4 + +### Patch Changes + +- network: add homeverse to networks list +- Updated dependencies + - @0xsequence/abi@1.8.4 + - @0xsequence/account@1.8.4 + - @0xsequence/auth@1.8.4 + - @0xsequence/core@1.8.4 + - @0xsequence/migration@1.8.4 + - @0xsequence/network@1.8.4 + - @0xsequence/relayer@1.8.4 + - @0xsequence/utils@1.8.4 + - @0xsequence/wallet@1.8.4 + +## 1.8.3 + +### Patch Changes + +- api: introduce basic linked wallet support +- Updated dependencies + - @0xsequence/abi@1.8.3 + - @0xsequence/account@1.8.3 + - @0xsequence/auth@1.8.3 + - @0xsequence/core@1.8.3 + - @0xsequence/migration@1.8.3 + - @0xsequence/network@1.8.3 + - @0xsequence/relayer@1.8.3 + - @0xsequence/utils@1.8.3 + - @0xsequence/wallet@1.8.3 + +## 1.8.2 + +### Patch Changes + +- provider: don't initialize analytics unless explicitly requested +- Updated dependencies + - @0xsequence/abi@1.8.2 + - @0xsequence/account@1.8.2 + - @0xsequence/auth@1.8.2 + - @0xsequence/core@1.8.2 + - @0xsequence/migration@1.8.2 + - @0xsequence/network@1.8.2 + - @0xsequence/relayer@1.8.2 + - @0xsequence/utils@1.8.2 + - @0xsequence/wallet@1.8.2 + +## 1.8.1 + +### Patch Changes + +- update to analytics provider +- Updated dependencies + - @0xsequence/abi@1.8.1 + - @0xsequence/account@1.8.1 + - @0xsequence/auth@1.8.1 + - @0xsequence/core@1.8.1 + - @0xsequence/migration@1.8.1 + - @0xsequence/network@1.8.1 + - @0xsequence/relayer@1.8.1 + - @0xsequence/utils@1.8.1 + - @0xsequence/wallet@1.8.1 + +## 1.8.0 + +### Minor Changes + +- provider: project analytics + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.8.0 + - @0xsequence/account@1.8.0 + - @0xsequence/auth@1.8.0 + - @0xsequence/core@1.8.0 + - @0xsequence/migration@1.8.0 + - @0xsequence/network@1.8.0 + - @0xsequence/relayer@1.8.0 + - @0xsequence/utils@1.8.0 + - @0xsequence/wallet@1.8.0 + +## 1.7.2 + +### Patch Changes + +- 0xsequence: ChainId should not be exported as a type +- account, wallet: fix nonce selection +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.7.2 + - @0xsequence/account@1.7.2 + - @0xsequence/auth@1.7.2 + - @0xsequence/core@1.7.2 + - @0xsequence/migration@1.7.2 + - @0xsequence/network@1.7.2 + - @0xsequence/relayer@1.7.2 + - @0xsequence/utils@1.7.2 + - @0xsequence/wallet@1.7.2 + +## 1.7.1 + +### Patch Changes + +- network: add missing avalanche logoURI +- Updated dependencies + - @0xsequence/abi@1.7.1 + - @0xsequence/account@1.7.1 + - @0xsequence/auth@1.7.1 + - @0xsequence/core@1.7.1 + - @0xsequence/migration@1.7.1 + - @0xsequence/network@1.7.1 + - @0xsequence/relayer@1.7.1 + - @0xsequence/utils@1.7.1 + - @0xsequence/wallet@1.7.1 + +## 1.7.0 + +### Minor Changes + +- provider: projectAccessKey is now required + +### Patch Changes + +- network: add NetworkMetadata.logoURI property for all networks +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.7.0 + - @0xsequence/account@1.7.0 + - @0xsequence/auth@1.7.0 + - @0xsequence/core@1.7.0 + - @0xsequence/migration@1.7.0 + - @0xsequence/network@1.7.0 + - @0xsequence/relayer@1.7.0 + - @0xsequence/utils@1.7.0 + - @0xsequence/wallet@1.7.0 + +## 1.6.3 + +### Patch Changes + +- network list update +- Updated dependencies + - @0xsequence/abi@1.6.3 + - @0xsequence/account@1.6.3 + - @0xsequence/auth@1.6.3 + - @0xsequence/core@1.6.3 + - @0xsequence/migration@1.6.3 + - @0xsequence/network@1.6.3 + - @0xsequence/relayer@1.6.3 + - @0xsequence/utils@1.6.3 + - @0xsequence/wallet@1.6.3 + +## 1.6.2 + +### Patch Changes + +- auth: projectAccessKey option +- wallet: use 12 bytes for random space +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.6.2 + - @0xsequence/account@1.6.2 + - @0xsequence/auth@1.6.2 + - @0xsequence/core@1.6.2 + - @0xsequence/migration@1.6.2 + - @0xsequence/network@1.6.2 + - @0xsequence/relayer@1.6.2 + - @0xsequence/utils@1.6.2 + - @0xsequence/wallet@1.6.2 + +## 1.6.1 + +### Patch Changes + +- core: add simple config from subdigest support +- core: fix encode tree with subdigest +- account: implement buildOnChainSignature on Account +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.6.1 + - @0xsequence/account@1.6.1 + - @0xsequence/auth@1.6.1 + - @0xsequence/core@1.6.1 + - @0xsequence/migration@1.6.1 + - @0xsequence/network@1.6.1 + - @0xsequence/relayer@1.6.1 + - @0xsequence/utils@1.6.1 + - @0xsequence/wallet@1.6.1 + +## 1.6.0 + +### Minor Changes + +- account, wallet: parallel transactions by default + +### Patch Changes + +- provider: emit disconnect on sign out +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.6.0 + - @0xsequence/account@1.6.0 + - @0xsequence/auth@1.6.0 + - @0xsequence/core@1.6.0 + - @0xsequence/migration@1.6.0 + - @0xsequence/network@1.6.0 + - @0xsequence/relayer@1.6.0 + - @0xsequence/utils@1.6.0 + - @0xsequence/wallet@1.6.0 + +## 1.5.0 + +### Minor Changes + +- signhub: add 'signing' signer status + +### Patch Changes + +- auth: Session.open: onAccountAddress callback +- account: allow empty transaction bundles +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.5.0 + - @0xsequence/account@1.5.0 + - @0xsequence/auth@1.5.0 + - @0xsequence/core@1.5.0 + - @0xsequence/migration@1.5.0 + - @0xsequence/network@1.5.0 + - @0xsequence/relayer@1.5.0 + - @0xsequence/utils@1.5.0 + - @0xsequence/wallet@1.5.0 + +## 1.4.9 + +### Patch Changes + +- rename SequenceMetadataClient to SequenceMetadata +- Updated dependencies + - @0xsequence/abi@1.4.9 + - @0xsequence/account@1.4.9 + - @0xsequence/auth@1.4.9 + - @0xsequence/core@1.4.9 + - @0xsequence/migration@1.4.9 + - @0xsequence/network@1.4.9 + - @0xsequence/relayer@1.4.9 + - @0xsequence/utils@1.4.9 + - @0xsequence/wallet@1.4.9 + +## 1.4.8 + +### Patch Changes + +- account: Account.getSigners +- Updated dependencies + - @0xsequence/abi@1.4.8 + - @0xsequence/account@1.4.8 + - @0xsequence/auth@1.4.8 + - @0xsequence/core@1.4.8 + - @0xsequence/migration@1.4.8 + - @0xsequence/network@1.4.8 + - @0xsequence/relayer@1.4.8 + - @0xsequence/utils@1.4.8 + - @0xsequence/wallet@1.4.8 + +## 1.4.7 + +### Patch Changes + +- update indexer client bindings +- Updated dependencies + - @0xsequence/abi@1.4.7 + - @0xsequence/account@1.4.7 + - @0xsequence/auth@1.4.7 + - @0xsequence/core@1.4.7 + - @0xsequence/migration@1.4.7 + - @0xsequence/network@1.4.7 + - @0xsequence/relayer@1.4.7 + - @0xsequence/utils@1.4.7 + - @0xsequence/wallet@1.4.7 + +## 1.4.6 + +### Patch Changes + +- - add sepolia networks, mark goerli as deprecated + - update indexer client bindings +- Updated dependencies + - @0xsequence/abi@1.4.6 + - @0xsequence/account@1.4.6 + - @0xsequence/auth@1.4.6 + - @0xsequence/core@1.4.6 + - @0xsequence/migration@1.4.6 + - @0xsequence/network@1.4.6 + - @0xsequence/relayer@1.4.6 + - @0xsequence/utils@1.4.6 + - @0xsequence/wallet@1.4.6 + +## 1.4.5 + +### Patch Changes + +- indexer/metadata: update client bindings +- auth: selectWallet with new address +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.4.5 + - @0xsequence/account@1.4.5 + - @0xsequence/auth@1.4.5 + - @0xsequence/core@1.4.5 + - @0xsequence/migration@1.4.5 + - @0xsequence/network@1.4.5 + - @0xsequence/relayer@1.4.5 + - @0xsequence/utils@1.4.5 + - @0xsequence/wallet@1.4.5 + +## 1.4.4 + +### Patch Changes + +- indexer: update bindings +- auth: handle jwt expiry +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.4.4 + - @0xsequence/account@1.4.4 + - @0xsequence/auth@1.4.4 + - @0xsequence/core@1.4.4 + - @0xsequence/migration@1.4.4 + - @0xsequence/network@1.4.4 + - @0xsequence/relayer@1.4.4 + - @0xsequence/utils@1.4.4 + - @0xsequence/wallet@1.4.4 + +## 1.4.3 + +### Patch Changes + +- guard: return active status from GuardSigner.getAuthMethods +- Updated dependencies + - @0xsequence/abi@1.4.3 + - @0xsequence/account@1.4.3 + - @0xsequence/auth@1.4.3 + - @0xsequence/core@1.4.3 + - @0xsequence/migration@1.4.3 + - @0xsequence/network@1.4.3 + - @0xsequence/relayer@1.4.3 + - @0xsequence/utils@1.4.3 + - @0xsequence/wallet@1.4.3 + +## 1.4.2 + +### Patch Changes + +- guard: update bindings +- Updated dependencies + - @0xsequence/abi@1.4.2 + - @0xsequence/account@1.4.2 + - @0xsequence/auth@1.4.2 + - @0xsequence/core@1.4.2 + - @0xsequence/migration@1.4.2 + - @0xsequence/network@1.4.2 + - @0xsequence/relayer@1.4.2 + - @0xsequence/utils@1.4.2 + - @0xsequence/wallet@1.4.2 + +## 1.4.1 + +### Patch Changes + +- network: remove unused networks +- signhub: orchestrator interface +- guard: auth methods interface +- guard: update bindings for pin and totp +- guard: no more retry logic +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.4.1 + - @0xsequence/account@1.4.1 + - @0xsequence/auth@1.4.1 + - @0xsequence/core@1.4.1 + - @0xsequence/migration@1.4.1 + - @0xsequence/network@1.4.1 + - @0xsequence/relayer@1.4.1 + - @0xsequence/utils@1.4.1 + - @0xsequence/wallet@1.4.1 + +## 1.4.0 + +### Minor Changes + +- project access key support + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.4.0 + - @0xsequence/account@1.4.0 + - @0xsequence/auth@1.4.0 + - @0xsequence/core@1.4.0 + - @0xsequence/migration@1.4.0 + - @0xsequence/network@1.4.0 + - @0xsequence/relayer@1.4.0 + - @0xsequence/utils@1.4.0 + - @0xsequence/wallet@1.4.0 + +## 1.3.0 + +### Minor Changes + +- signhub: account children + +### Patch Changes + +- guard: do not throw when building deploy transaction +- network: snowtrace.io -> subnets.avax.network/c-chain +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.3.0 + - @0xsequence/account@1.3.0 + - @0xsequence/auth@1.3.0 + - @0xsequence/core@1.3.0 + - @0xsequence/migration@1.3.0 + - @0xsequence/network@1.3.0 + - @0xsequence/relayer@1.3.0 + - @0xsequence/utils@1.3.0 + - @0xsequence/wallet@1.3.0 + +## 1.2.9 + +### Patch Changes + +- account: AccountSigner.sendTransaction simulateForFeeOptions +- relayer: update bindings +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.2.9 + - @0xsequence/account@1.2.9 + - @0xsequence/auth@1.2.9 + - @0xsequence/core@1.2.9 + - @0xsequence/migration@1.2.9 + - @0xsequence/network@1.2.9 + - @0xsequence/relayer@1.2.9 + - @0xsequence/utils@1.2.9 + - @0xsequence/wallet@1.2.9 + +## 1.2.8 + +### Patch Changes + +- rename X-Sequence-Token-Key header to X-Access-Key +- Updated dependencies + - @0xsequence/abi@1.2.8 + - @0xsequence/account@1.2.8 + - @0xsequence/auth@1.2.8 + - @0xsequence/core@1.2.8 + - @0xsequence/migration@1.2.8 + - @0xsequence/network@1.2.8 + - @0xsequence/relayer@1.2.8 + - @0xsequence/utils@1.2.8 + - @0xsequence/wallet@1.2.8 + +## 1.2.7 + +### Patch Changes + +- add x-sequence-token-key to clients +- Updated dependencies + - @0xsequence/abi@1.2.7 + - @0xsequence/account@1.2.7 + - @0xsequence/auth@1.2.7 + - @0xsequence/core@1.2.7 + - @0xsequence/migration@1.2.7 + - @0xsequence/network@1.2.7 + - @0xsequence/relayer@1.2.7 + - @0xsequence/utils@1.2.7 + - @0xsequence/wallet@1.2.7 + +## 1.2.6 + +### Patch Changes + +- Fix bind multicall provider +- Updated dependencies + - @0xsequence/abi@1.2.6 + - @0xsequence/account@1.2.6 + - @0xsequence/auth@1.2.6 + - @0xsequence/core@1.2.6 + - @0xsequence/migration@1.2.6 + - @0xsequence/network@1.2.6 + - @0xsequence/relayer@1.2.6 + - @0xsequence/utils@1.2.6 + - @0xsequence/wallet@1.2.6 + +## 1.2.5 + +### Patch Changes + +- Multicall default configuration fixes +- Updated dependencies + - @0xsequence/abi@1.2.5 + - @0xsequence/account@1.2.5 + - @0xsequence/auth@1.2.5 + - @0xsequence/core@1.2.5 + - @0xsequence/migration@1.2.5 + - @0xsequence/network@1.2.5 + - @0xsequence/relayer@1.2.5 + - @0xsequence/utils@1.2.5 + - @0xsequence/wallet@1.2.5 + +## 1.2.4 + +### Patch Changes + +- provider: Adding missing payment provider types to PaymentProviderOption +- provider: WalletRequestHandler.notifyChainChanged +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.2.4 + - @0xsequence/account@1.2.4 + - @0xsequence/auth@1.2.4 + - @0xsequence/core@1.2.4 + - @0xsequence/migration@1.2.4 + - @0xsequence/network@1.2.4 + - @0xsequence/relayer@1.2.4 + - @0xsequence/utils@1.2.4 + - @0xsequence/wallet@1.2.4 + +## 1.2.3 + +### Patch Changes + +- auth, provider: connect to accept optional authorizeNonce +- Updated dependencies + - @0xsequence/abi@1.2.3 + - @0xsequence/account@1.2.3 + - @0xsequence/auth@1.2.3 + - @0xsequence/core@1.2.3 + - @0xsequence/migration@1.2.3 + - @0xsequence/network@1.2.3 + - @0xsequence/relayer@1.2.3 + - @0xsequence/utils@1.2.3 + - @0xsequence/wallet@1.2.3 + +## 1.2.2 + +### Patch Changes + +- provider: allow createContract calls +- core: check for explicit zero address in contract deployments +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.2.2 + - @0xsequence/account@1.2.2 + - @0xsequence/auth@1.2.2 + - @0xsequence/core@1.2.2 + - @0xsequence/migration@1.2.2 + - @0xsequence/network@1.2.2 + - @0xsequence/relayer@1.2.2 + - @0xsequence/utils@1.2.2 + - @0xsequence/wallet@1.2.2 + +## 1.2.1 + +### Patch Changes + +- auth: use sequence api chain id as reference chain id if available +- Updated dependencies + - @0xsequence/abi@1.2.1 + - @0xsequence/account@1.2.1 + - @0xsequence/auth@1.2.1 + - @0xsequence/core@1.2.1 + - @0xsequence/migration@1.2.1 + - @0xsequence/network@1.2.1 + - @0xsequence/relayer@1.2.1 + - @0xsequence/utils@1.2.1 + - @0xsequence/wallet@1.2.1 + +## 1.2.0 + +### Minor Changes + +- split services from session, better local support + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.2.0 + - @0xsequence/account@1.2.0 + - @0xsequence/auth@1.2.0 + - @0xsequence/core@1.2.0 + - @0xsequence/migration@1.2.0 + - @0xsequence/network@1.2.0 + - @0xsequence/relayer@1.2.0 + - @0xsequence/utils@1.2.0 + - @0xsequence/wallet@1.2.0 + +## 1.1.15 + +### Patch Changes + +- guard: remove error filtering +- Updated dependencies + - @0xsequence/abi@1.1.15 + - @0xsequence/account@1.1.15 + - @0xsequence/auth@1.1.15 + - @0xsequence/core@1.1.15 + - @0xsequence/migration@1.1.15 + - @0xsequence/network@1.1.15 + - @0xsequence/relayer@1.1.15 + - @0xsequence/utils@1.1.15 + - @0xsequence/wallet@1.1.15 + +## 1.1.14 + +### Patch Changes + +- guard: add GuardSigner.onError +- Updated dependencies + - @0xsequence/abi@1.1.14 + - @0xsequence/account@1.1.14 + - @0xsequence/auth@1.1.14 + - @0xsequence/core@1.1.14 + - @0xsequence/migration@1.1.14 + - @0xsequence/network@1.1.14 + - @0xsequence/relayer@1.1.14 + - @0xsequence/utils@1.1.14 + - @0xsequence/wallet@1.1.14 + +## 1.1.13 + +### Patch Changes + +- provider: pass client version with connect options +- provider: removing large from BannerSize +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.1.13 + - @0xsequence/account@1.1.13 + - @0xsequence/auth@1.1.13 + - @0xsequence/core@1.1.13 + - @0xsequence/migration@1.1.13 + - @0xsequence/network@1.1.13 + - @0xsequence/relayer@1.1.13 + - @0xsequence/utils@1.1.13 + - @0xsequence/wallet@1.1.13 + +## 1.1.12 + +### Patch Changes + +- provider: adding bannerSize to ConnectOptions +- Updated dependencies + - @0xsequence/abi@1.1.12 + - @0xsequence/account@1.1.12 + - @0xsequence/auth@1.1.12 + - @0xsequence/core@1.1.12 + - @0xsequence/migration@1.1.12 + - @0xsequence/network@1.1.12 + - @0xsequence/relayer@1.1.12 + - @0xsequence/utils@1.1.12 + - @0xsequence/wallet@1.1.12 + +## 1.1.11 + +### Patch Changes + +- add homeverse configs +- Updated dependencies + - @0xsequence/abi@1.1.11 + - @0xsequence/account@1.1.11 + - @0xsequence/auth@1.1.11 + - @0xsequence/core@1.1.11 + - @0xsequence/migration@1.1.11 + - @0xsequence/network@1.1.11 + - @0xsequence/relayer@1.1.11 + - @0xsequence/utils@1.1.11 + - @0xsequence/wallet@1.1.11 + +## 1.1.10 + +### Patch Changes + +- handle default EIP6492 on send +- Updated dependencies + - @0xsequence/abi@1.1.10 + - @0xsequence/account@1.1.10 + - @0xsequence/auth@1.1.10 + - @0xsequence/core@1.1.10 + - @0xsequence/migration@1.1.10 + - @0xsequence/network@1.1.10 + - @0xsequence/relayer@1.1.10 + - @0xsequence/utils@1.1.10 + - @0xsequence/wallet@1.1.10 + +## 1.1.9 + +### Patch Changes + +- Custom default EIP6492 on client +- Updated dependencies + - @0xsequence/abi@1.1.9 + - @0xsequence/account@1.1.9 + - @0xsequence/auth@1.1.9 + - @0xsequence/core@1.1.9 + - @0xsequence/migration@1.1.9 + - @0xsequence/network@1.1.9 + - @0xsequence/relayer@1.1.9 + - @0xsequence/utils@1.1.9 + - @0xsequence/wallet@1.1.9 + +## 1.1.8 + +### Patch Changes + +- metadata: searchMetadata: add types filter +- Updated dependencies + - @0xsequence/abi@1.1.8 + - @0xsequence/account@1.1.8 + - @0xsequence/auth@1.1.8 + - @0xsequence/core@1.1.8 + - @0xsequence/migration@1.1.8 + - @0xsequence/network@1.1.8 + - @0xsequence/relayer@1.1.8 + - @0xsequence/utils@1.1.8 + - @0xsequence/wallet@1.1.8 + +## 1.1.7 + +### Patch Changes + +- adding signInWith connect settings option to allow dapps to automatically login their users with a certain provider optimizing the normal authentication flow +- Updated dependencies + - @0xsequence/abi@1.1.7 + - @0xsequence/account@1.1.7 + - @0xsequence/auth@1.1.7 + - @0xsequence/core@1.1.7 + - @0xsequence/migration@1.1.7 + - @0xsequence/network@1.1.7 + - @0xsequence/relayer@1.1.7 + - @0xsequence/utils@1.1.7 + - @0xsequence/wallet@1.1.7 + +## 1.1.6 + +### Patch Changes + +- metadata: searchMetadata: add chainID and excludeTokenMetadata filters +- Updated dependencies + - @0xsequence/abi@1.1.6 + - @0xsequence/account@1.1.6 + - @0xsequence/auth@1.1.6 + - @0xsequence/core@1.1.6 + - @0xsequence/migration@1.1.6 + - @0xsequence/network@1.1.6 + - @0xsequence/relayer@1.1.6 + - @0xsequence/utils@1.1.6 + - @0xsequence/wallet@1.1.6 + +## 1.1.5 + +### Patch Changes + +- account: re-compute meta-transaction id for wallet deployment transactions +- Updated dependencies + - @0xsequence/abi@1.1.5 + - @0xsequence/account@1.1.5 + - @0xsequence/auth@1.1.5 + - @0xsequence/core@1.1.5 + - @0xsequence/migration@1.1.5 + - @0xsequence/network@1.1.5 + - @0xsequence/relayer@1.1.5 + - @0xsequence/utils@1.1.5 + - @0xsequence/wallet@1.1.5 + +## 1.1.4 + +### Patch Changes + +- network: rename base-mainnet to base +- provider: override isDefaultChain with ConnectOptions.networkId if provided +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.1.4 + - @0xsequence/account@1.1.4 + - @0xsequence/auth@1.1.4 + - @0xsequence/core@1.1.4 + - @0xsequence/migration@1.1.4 + - @0xsequence/network@1.1.4 + - @0xsequence/relayer@1.1.4 + - @0xsequence/utils@1.1.4 + - @0xsequence/wallet@1.1.4 + +## 1.1.3 + +### Patch Changes + +- provider: use network id from transport session +- provider: sign authorization using ConnectOptions.networkId if provided +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.1.3 + - @0xsequence/account@1.1.3 + - @0xsequence/auth@1.1.3 + - @0xsequence/core@1.1.3 + - @0xsequence/migration@1.1.3 + - @0xsequence/network@1.1.3 + - @0xsequence/relayer@1.1.3 + - @0xsequence/utils@1.1.3 + - @0xsequence/wallet@1.1.3 + +## 1.1.2 + +### Patch Changes + +- provider: jsonrpc chain id fixes +- Updated dependencies + - @0xsequence/abi@1.1.2 + - @0xsequence/account@1.1.2 + - @0xsequence/auth@1.1.2 + - @0xsequence/core@1.1.2 + - @0xsequence/migration@1.1.2 + - @0xsequence/network@1.1.2 + - @0xsequence/relayer@1.1.2 + - @0xsequence/utils@1.1.2 + - @0xsequence/wallet@1.1.2 + +## 1.1.1 + +### Patch Changes + +- network: add base mainnet and sepolia +- provider: reject toxic transaction requests +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.1.1 + - @0xsequence/account@1.1.1 + - @0xsequence/auth@1.1.1 + - @0xsequence/core@1.1.1 + - @0xsequence/migration@1.1.1 + - @0xsequence/network@1.1.1 + - @0xsequence/relayer@1.1.1 + - @0xsequence/utils@1.1.1 + - @0xsequence/wallet@1.1.1 + +## 1.1.0 + +### Minor Changes + +- Refactor dapp facing provider + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.1.0 + - @0xsequence/account@1.1.0 + - @0xsequence/auth@1.1.0 + - @0xsequence/core@1.1.0 + - @0xsequence/migration@1.1.0 + - @0xsequence/network@1.1.0 + - @0xsequence/relayer@1.1.0 + - @0xsequence/utils@1.1.0 + - @0xsequence/wallet@1.1.0 + +## 1.0.5 + +### Patch Changes + +- network: export network constants +- guard: use the correct global for fetch +- network: nova-explorer.arbitrum.io -> nova.arbiscan.io +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.0.5 + - @0xsequence/account@1.0.5 + - @0xsequence/auth@1.0.5 + - @0xsequence/core@1.0.5 + - @0xsequence/migration@1.0.5 + - @0xsequence/network@1.0.5 + - @0xsequence/relayer@1.0.5 + - @0xsequence/utils@1.0.5 + - @0xsequence/wallet@1.0.5 + +## 1.0.4 + +### Patch Changes + +- provider: accept name or number for networkId +- Updated dependencies + - @0xsequence/abi@1.0.4 + - @0xsequence/account@1.0.4 + - @0xsequence/auth@1.0.4 + - @0xsequence/core@1.0.4 + - @0xsequence/migration@1.0.4 + - @0xsequence/network@1.0.4 + - @0xsequence/relayer@1.0.4 + - @0xsequence/utils@1.0.4 + - @0xsequence/wallet@1.0.4 + +## 1.0.3 + +### Patch Changes + +- Simpler isValidSignature helpers +- Updated dependencies + - @0xsequence/abi@1.0.3 + - @0xsequence/account@1.0.3 + - @0xsequence/auth@1.0.3 + - @0xsequence/core@1.0.3 + - @0xsequence/migration@1.0.3 + - @0xsequence/network@1.0.3 + - @0xsequence/relayer@1.0.3 + - @0xsequence/utils@1.0.3 + - @0xsequence/wallet@1.0.3 + +## 1.0.2 + +### Patch Changes + +- add extra signature validation utils methods +- Updated dependencies + - @0xsequence/abi@1.0.2 + - @0xsequence/account@1.0.2 + - @0xsequence/auth@1.0.2 + - @0xsequence/core@1.0.2 + - @0xsequence/migration@1.0.2 + - @0xsequence/network@1.0.2 + - @0xsequence/relayer@1.0.2 + - @0xsequence/utils@1.0.2 + - @0xsequence/wallet@1.0.2 + +## 1.0.1 + +### Patch Changes + +- add homeverse testnet +- Updated dependencies + - @0xsequence/abi@1.0.1 + - @0xsequence/account@1.0.1 + - @0xsequence/auth@1.0.1 + - @0xsequence/core@1.0.1 + - @0xsequence/migration@1.0.1 + - @0xsequence/network@1.0.1 + - @0xsequence/relayer@1.0.1 + - @0xsequence/utils@1.0.1 + - @0xsequence/wallet@1.0.1 + +## 1.0.0 + +### Major Changes + +- https://sequence.xyz/blog/sequence-wallet-light-state-sync-full-merkle-wallets + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.0.0 + - @0xsequence/account@1.0.0 + - @0xsequence/auth@1.0.0 + - @0xsequence/core@1.0.0 + - @0xsequence/migration@1.0.0 + - @0xsequence/network@1.0.0 + - @0xsequence/relayer@1.0.0 + - @0xsequence/utils@1.0.0 + - @0xsequence/wallet@1.0.0 + +## 0.43.34 + +### Patch Changes + +- auth: no jwt for indexer +- Updated dependencies + - @0xsequence/abi@0.43.34 + - @0xsequence/auth@0.43.34 + - @0xsequence/config@0.43.34 + - @0xsequence/network@0.43.34 + - @0xsequence/relayer@0.43.34 + - @0xsequence/transactions@0.43.34 + - @0xsequence/utils@0.43.34 + - @0xsequence/wallet@0.43.34 + +## 0.43.33 + +### Patch Changes + +- Adding onConnectOptionsChange handler to WalletRequestHandler +- Updated dependencies + - @0xsequence/abi@0.43.33 + - @0xsequence/auth@0.43.33 + - @0xsequence/config@0.43.33 + - @0xsequence/network@0.43.33 + - @0xsequence/relayer@0.43.33 + - @0xsequence/transactions@0.43.33 + - @0xsequence/utils@0.43.33 + - @0xsequence/wallet@0.43.33 + +## 0.43.32 + +### Patch Changes + +- add Base Goerli network +- Updated dependencies + - @0xsequence/abi@0.43.32 + - @0xsequence/auth@0.43.32 + - @0xsequence/config@0.43.32 + - @0xsequence/network@0.43.32 + - @0xsequence/relayer@0.43.32 + - @0xsequence/transactions@0.43.32 + - @0xsequence/utils@0.43.32 + - @0xsequence/wallet@0.43.32 + +## 0.43.31 + +### Patch Changes + +- remove AuxDataProvider, add promptSignInConnect +- Updated dependencies + - @0xsequence/abi@0.43.31 + - @0xsequence/auth@0.43.31 + - @0xsequence/config@0.43.31 + - @0xsequence/network@0.43.31 + - @0xsequence/relayer@0.43.31 + - @0xsequence/transactions@0.43.31 + - @0xsequence/utils@0.43.31 + - @0xsequence/wallet@0.43.31 + +## 0.43.30 + +### Patch Changes + +- add arbitrum goerli testnet +- Updated dependencies + - @0xsequence/abi@0.43.30 + - @0xsequence/auth@0.43.30 + - @0xsequence/config@0.43.30 + - @0xsequence/network@0.43.30 + - @0xsequence/relayer@0.43.30 + - @0xsequence/transactions@0.43.30 + - @0xsequence/utils@0.43.30 + - @0xsequence/wallet@0.43.30 + +## 0.43.29 + +### Patch Changes + +- provider: check availability of window object +- Updated dependencies + - @0xsequence/abi@0.43.29 + - @0xsequence/auth@0.43.29 + - @0xsequence/config@0.43.29 + - @0xsequence/network@0.43.29 + - @0xsequence/relayer@0.43.29 + - @0xsequence/transactions@0.43.29 + - @0xsequence/utils@0.43.29 + - @0xsequence/wallet@0.43.29 + +## 0.43.28 + +### Patch Changes + +- update api bindings +- Updated dependencies + - @0xsequence/abi@0.43.28 + - @0xsequence/auth@0.43.28 + - @0xsequence/config@0.43.28 + - @0xsequence/network@0.43.28 + - @0xsequence/relayer@0.43.28 + - @0xsequence/transactions@0.43.28 + - @0xsequence/utils@0.43.28 + - @0xsequence/wallet@0.43.28 + +## 0.43.27 + +### Patch Changes + +- Add rpc is sequence method +- Updated dependencies + - @0xsequence/abi@0.43.27 + - @0xsequence/auth@0.43.27 + - @0xsequence/config@0.43.27 + - @0xsequence/network@0.43.27 + - @0xsequence/relayer@0.43.27 + - @0xsequence/transactions@0.43.27 + - @0xsequence/utils@0.43.27 + - @0xsequence/wallet@0.43.27 + +## 0.43.26 + +### Patch Changes + +- add zkevm url to enum +- Updated dependencies + - @0xsequence/abi@0.43.26 + - @0xsequence/auth@0.43.26 + - @0xsequence/config@0.43.26 + - @0xsequence/network@0.43.26 + - @0xsequence/relayer@0.43.26 + - @0xsequence/transactions@0.43.26 + - @0xsequence/utils@0.43.26 + - @0xsequence/wallet@0.43.26 + +## 0.43.25 + +### Patch Changes + +- added polygon zkevm to mainnet networks +- Updated dependencies + - @0xsequence/abi@0.43.25 + - @0xsequence/auth@0.43.25 + - @0xsequence/config@0.43.25 + - @0xsequence/network@0.43.25 + - @0xsequence/relayer@0.43.25 + - @0xsequence/transactions@0.43.25 + - @0xsequence/utils@0.43.25 + - @0xsequence/wallet@0.43.25 + +## 0.43.24 + +### Patch Changes + +- name change from zkevm to polygon-zkevm +- Updated dependencies + - @0xsequence/abi@0.43.24 + - @0xsequence/auth@0.43.24 + - @0xsequence/config@0.43.24 + - @0xsequence/network@0.43.24 + - @0xsequence/relayer@0.43.24 + - @0xsequence/transactions@0.43.24 + - @0xsequence/utils@0.43.24 + - @0xsequence/wallet@0.43.24 + +## 0.43.23 + +### Patch Changes + +- update zkEVM name to Polygon zkEVM +- Updated dependencies + - @0xsequence/abi@0.43.23 + - @0xsequence/auth@0.43.23 + - @0xsequence/config@0.43.23 + - @0xsequence/network@0.43.23 + - @0xsequence/relayer@0.43.23 + - @0xsequence/transactions@0.43.23 + - @0xsequence/utils@0.43.23 + - @0xsequence/wallet@0.43.23 + +## 0.43.22 + +### Patch Changes + +- add zkevm chain +- Updated dependencies + - @0xsequence/abi@0.43.22 + - @0xsequence/auth@0.43.22 + - @0xsequence/config@0.43.22 + - @0xsequence/network@0.43.22 + - @0xsequence/relayer@0.43.22 + - @0xsequence/transactions@0.43.22 + - @0xsequence/utils@0.43.22 + - @0xsequence/wallet@0.43.22 + +## 0.43.21 + +### Patch Changes + +- api: update client bindings +- Updated dependencies + - @0xsequence/abi@0.43.21 + - @0xsequence/auth@0.43.21 + - @0xsequence/config@0.43.21 + - @0xsequence/network@0.43.21 + - @0xsequence/relayer@0.43.21 + - @0xsequence/transactions@0.43.21 + - @0xsequence/utils@0.43.21 + - @0xsequence/wallet@0.43.21 + +## 0.43.20 + +### Patch Changes + +- indexer: update bindings +- Updated dependencies + - @0xsequence/abi@0.43.20 + - @0xsequence/auth@0.43.20 + - @0xsequence/config@0.43.20 + - @0xsequence/network@0.43.20 + - @0xsequence/relayer@0.43.20 + - @0xsequence/transactions@0.43.20 + - @0xsequence/utils@0.43.20 + - @0xsequence/wallet@0.43.20 + +## 0.43.19 + +### Patch Changes + +- session proof update +- Updated dependencies + - @0xsequence/abi@0.43.19 + - @0xsequence/auth@0.43.19 + - @0xsequence/config@0.43.19 + - @0xsequence/network@0.43.19 + - @0xsequence/relayer@0.43.19 + - @0xsequence/transactions@0.43.19 + - @0xsequence/utils@0.43.19 + - @0xsequence/wallet@0.43.19 + +## 0.43.18 + +### Patch Changes + +- rpc client global check, hardening +- Updated dependencies + - @0xsequence/abi@0.43.18 + - @0xsequence/auth@0.43.18 + - @0xsequence/config@0.43.18 + - @0xsequence/network@0.43.18 + - @0xsequence/relayer@0.43.18 + - @0xsequence/transactions@0.43.18 + - @0xsequence/utils@0.43.18 + - @0xsequence/wallet@0.43.18 + +## 0.43.17 + +### Patch Changes + +- rpc clients, check of 'global' is defined +- Updated dependencies + - @0xsequence/abi@0.43.17 + - @0xsequence/auth@0.43.17 + - @0xsequence/config@0.43.17 + - @0xsequence/network@0.43.17 + - @0xsequence/relayer@0.43.17 + - @0xsequence/transactions@0.43.17 + - @0xsequence/utils@0.43.17 + - @0xsequence/wallet@0.43.17 + +## 0.43.16 + +### Patch Changes + +- ethers peerDep to v5, update rpc client global use +- Updated dependencies + - @0xsequence/abi@0.43.16 + - @0xsequence/auth@0.43.16 + - @0xsequence/config@0.43.16 + - @0xsequence/network@0.43.16 + - @0xsequence/relayer@0.43.16 + - @0xsequence/transactions@0.43.16 + - @0xsequence/utils@0.43.16 + - @0xsequence/wallet@0.43.16 + +## 0.43.15 + +### Patch Changes + +- - provider: expand receiver type on some util methods +- Updated dependencies + - @0xsequence/abi@0.43.15 + - @0xsequence/auth@0.43.15 + - @0xsequence/config@0.43.15 + - @0xsequence/network@0.43.15 + - @0xsequence/relayer@0.43.15 + - @0xsequence/transactions@0.43.15 + - @0xsequence/utils@0.43.15 + - @0xsequence/wallet@0.43.15 + +## 0.43.14 + +### Patch Changes + +- bump +- Updated dependencies + - @0xsequence/abi@0.43.14 + - @0xsequence/auth@0.43.14 + - @0xsequence/config@0.43.14 + - @0xsequence/network@0.43.14 + - @0xsequence/relayer@0.43.14 + - @0xsequence/transactions@0.43.14 + - @0xsequence/utils@0.43.14 + - @0xsequence/wallet@0.43.14 + +## 0.43.13 + +### Patch Changes + +- update rpc bindings +- Updated dependencies + - @0xsequence/abi@0.43.13 + - @0xsequence/auth@0.43.13 + - @0xsequence/config@0.43.13 + - @0xsequence/network@0.43.13 + - @0xsequence/relayer@0.43.13 + - @0xsequence/transactions@0.43.13 + - @0xsequence/utils@0.43.13 + - @0xsequence/wallet@0.43.13 + +## 0.43.12 + +### Patch Changes + +- provider: single wallet init, and add new unregisterWallet() method +- Updated dependencies + - @0xsequence/abi@0.43.12 + - @0xsequence/auth@0.43.12 + - @0xsequence/config@0.43.12 + - @0xsequence/network@0.43.12 + - @0xsequence/relayer@0.43.12 + - @0xsequence/transactions@0.43.12 + - @0xsequence/utils@0.43.12 + - @0xsequence/wallet@0.43.12 + +## 0.43.11 + +### Patch Changes + +- fix lockfiles +- re-add mocha type deleter +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.43.11 + - @0xsequence/auth@0.43.11 + - @0xsequence/config@0.43.11 + - @0xsequence/network@0.43.11 + - @0xsequence/relayer@0.43.11 + - @0xsequence/transactions@0.43.11 + - @0xsequence/utils@0.43.11 + - @0xsequence/wallet@0.43.11 + +## 0.43.10 + +### Patch Changes + +- various improvements +- Updated dependencies + - @0xsequence/abi@0.43.10 + - @0xsequence/auth@0.43.10 + - @0xsequence/config@0.43.10 + - @0xsequence/network@0.43.10 + - @0xsequence/relayer@0.43.10 + - @0xsequence/transactions@0.43.10 + - @0xsequence/utils@0.43.10 + - @0xsequence/wallet@0.43.10 + +## 0.43.9 + +### Patch Changes + +- update deps +- Updated dependencies + - @0xsequence/abi@0.43.9 + - @0xsequence/auth@0.43.9 + - @0xsequence/config@0.43.9 + - @0xsequence/network@0.43.9 + - @0xsequence/relayer@0.43.9 + - @0xsequence/transactions@0.43.9 + - @0xsequence/utils@0.43.9 + - @0xsequence/wallet@0.43.9 + +## 0.43.8 + +### Patch Changes + +- network: JsonRpcProvider with caching +- Updated dependencies + - @0xsequence/abi@0.43.8 + - @0xsequence/auth@0.43.8 + - @0xsequence/config@0.43.8 + - @0xsequence/network@0.43.8 + - @0xsequence/relayer@0.43.8 + - @0xsequence/transactions@0.43.8 + - @0xsequence/utils@0.43.8 + - @0xsequence/wallet@0.43.8 + +## 0.43.7 + +### Patch Changes + +- provider: fix wallet network init +- Updated dependencies + - @0xsequence/abi@0.43.7 + - @0xsequence/auth@0.43.7 + - @0xsequence/config@0.43.7 + - @0xsequence/network@0.43.7 + - @0xsequence/transactions@0.43.7 + - @0xsequence/utils@0.43.7 + - @0xsequence/wallet@0.43.7 + +## 0.43.6 + +### Patch Changes + +- metadatata: update rpc bindings +- Updated dependencies + - @0xsequence/abi@0.43.6 + - @0xsequence/auth@0.43.6 + - @0xsequence/config@0.43.6 + - @0xsequence/network@0.43.6 + - @0xsequence/transactions@0.43.6 + - @0xsequence/utils@0.43.6 + - @0xsequence/wallet@0.43.6 + +## 0.43.5 + +### Patch Changes + +- provider: do not set default network for connect messages +- provider: forward missing error message +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.43.5 + - @0xsequence/auth@0.43.5 + - @0xsequence/config@0.43.5 + - @0xsequence/network@0.43.5 + - @0xsequence/transactions@0.43.5 + - @0xsequence/utils@0.43.5 + - @0xsequence/wallet@0.43.5 + +## 0.43.4 + +### Patch Changes + +- no-change version bump to fix incorrectly tagged snapshot build +- Updated dependencies + - @0xsequence/abi@0.43.4 + - @0xsequence/auth@0.43.4 + - @0xsequence/config@0.43.4 + - @0xsequence/network@0.43.4 + - @0xsequence/transactions@0.43.4 + - @0xsequence/utils@0.43.4 + - @0xsequence/wallet@0.43.4 + +## 0.43.3 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/abi@0.43.3 + - @0xsequence/auth@0.43.3 + - @0xsequence/config@0.43.3 + - @0xsequence/network@0.43.3 + - @0xsequence/transactions@0.43.3 + - @0xsequence/utils@0.43.3 + - @0xsequence/wallet@0.43.3 + +## 0.43.2 + +### Patch Changes + +- provider: implement connectUnchecked +- Updated dependencies + - @0xsequence/abi@0.43.2 + - @0xsequence/auth@0.43.2 + - @0xsequence/config@0.43.2 + - @0xsequence/network@0.43.2 + - @0xsequence/transactions@0.43.2 + - @0xsequence/utils@0.43.2 + - @0xsequence/wallet@0.43.2 + +## 0.43.1 + +### Patch Changes + +- update to latest ethauth dep +- Updated dependencies + - @0xsequence/abi@0.43.1 + - @0xsequence/auth@0.43.1 + - @0xsequence/config@0.43.1 + - @0xsequence/network@0.43.1 + - @0xsequence/transactions@0.43.1 + - @0xsequence/utils@0.43.1 + - @0xsequence/wallet@0.43.1 + +## 0.43.0 + +### Minor Changes + +- move ethers to a peer dependency + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.43.0 + - @0xsequence/auth@0.43.0 + - @0xsequence/config@0.43.0 + - @0xsequence/network@0.43.0 + - @0xsequence/transactions@0.43.0 + - @0xsequence/utils@0.43.0 + - @0xsequence/wallet@0.43.0 + +## 0.42.10 + +### Patch Changes + +- add auxDataProvider +- Updated dependencies + - @0xsequence/abi@0.42.10 + - @0xsequence/auth@0.42.10 + - @0xsequence/config@0.42.10 + - @0xsequence/network@0.42.10 + - @0xsequence/transactions@0.42.10 + - @0xsequence/utils@0.42.10 + - @0xsequence/wallet@0.42.10 + +## 0.42.9 + +### Patch Changes + +- provider: add eip-191 exceptions +- Updated dependencies + - @0xsequence/abi@0.42.9 + - @0xsequence/auth@0.42.9 + - @0xsequence/config@0.42.9 + - @0xsequence/network@0.42.9 + - @0xsequence/transactions@0.42.9 + - @0xsequence/utils@0.42.9 + - @0xsequence/wallet@0.42.9 + +## 0.42.8 + +### Patch Changes + +- provider: skip setting intent origin if we're unity plugin +- Updated dependencies + - @0xsequence/abi@0.42.8 + - @0xsequence/auth@0.42.8 + - @0xsequence/config@0.42.8 + - @0xsequence/network@0.42.8 + - @0xsequence/transactions@0.42.8 + - @0xsequence/utils@0.42.8 + - @0xsequence/wallet@0.42.8 + +## 0.42.7 + +### Patch Changes + +- Add sign in options to connection settings +- Updated dependencies + - @0xsequence/abi@0.42.7 + - @0xsequence/auth@0.42.7 + - @0xsequence/config@0.42.7 + - @0xsequence/network@0.42.7 + - @0xsequence/transactions@0.42.7 + - @0xsequence/utils@0.42.7 + - @0xsequence/wallet@0.42.7 + +## 0.42.6 + +### Patch Changes + +- api bindings update +- Updated dependencies + - @0xsequence/abi@0.42.6 + - @0xsequence/auth@0.42.6 + - @0xsequence/config@0.42.6 + - @0xsequence/network@0.42.6 + - @0xsequence/transactions@0.42.6 + - @0xsequence/utils@0.42.6 + - @0xsequence/wallet@0.42.6 + +## 0.42.5 + +### Patch Changes + +- relayer: don't treat missing receipt as hard failure +- Updated dependencies + - @0xsequence/abi@0.42.5 + - @0xsequence/auth@0.42.5 + - @0xsequence/config@0.42.5 + - @0xsequence/network@0.42.5 + - @0xsequence/transactions@0.42.5 + - @0xsequence/utils@0.42.5 + - @0xsequence/wallet@0.42.5 + +## 0.42.4 + +### Patch Changes + +- provider: add custom app protocol to connect options +- Updated dependencies + - @0xsequence/abi@0.42.4 + - @0xsequence/auth@0.42.4 + - @0xsequence/config@0.42.4 + - @0xsequence/network@0.42.4 + - @0xsequence/transactions@0.42.4 + - @0xsequence/utils@0.42.4 + - @0xsequence/wallet@0.42.4 + +## 0.42.3 + +### Patch Changes + +- update api bindings +- Updated dependencies + - @0xsequence/abi@0.42.3 + - @0xsequence/auth@0.42.3 + - @0xsequence/config@0.42.3 + - @0xsequence/network@0.42.3 + - @0xsequence/transactions@0.42.3 + - @0xsequence/utils@0.42.3 + - @0xsequence/wallet@0.42.3 + +## 0.42.2 + +### Patch Changes + +- disable rinkeby network +- Updated dependencies + - @0xsequence/abi@0.42.2 + - @0xsequence/auth@0.42.2 + - @0xsequence/config@0.42.2 + - @0xsequence/network@0.42.2 + - @0xsequence/transactions@0.42.2 + - @0xsequence/utils@0.42.2 + - @0xsequence/wallet@0.42.2 + +## 0.42.1 + +### Patch Changes + +- wallet: optional waitForReceipt parameter +- Updated dependencies + - @0xsequence/abi@0.42.1 + - @0xsequence/auth@0.42.1 + - @0xsequence/config@0.42.1 + - @0xsequence/network@0.42.1 + - @0xsequence/transactions@0.42.1 + - @0xsequence/utils@0.42.1 + - @0xsequence/wallet@0.42.1 + +## 0.42.0 + +### Minor Changes + +- relayer: estimateGasLimits -> simulate +- add simulator package + +### Patch Changes + +- transactions: fix flattenAuxTransactions +- provider: only filter nullish values +- provider: re-map transaction 'gas' back to 'gasLimit' +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.42.0 + - @0xsequence/auth@0.42.0 + - @0xsequence/config@0.42.0 + - @0xsequence/network@0.42.0 + - @0xsequence/transactions@0.42.0 + - @0xsequence/utils@0.42.0 + - @0xsequence/wallet@0.42.0 + +## 0.41.3 + +### Patch Changes + +- api bindings update +- Updated dependencies + - @0xsequence/abi@0.41.3 + - @0xsequence/auth@0.41.3 + - @0xsequence/config@0.41.3 + - @0xsequence/network@0.41.3 + - @0xsequence/transactions@0.41.3 + - @0xsequence/utils@0.41.3 + - @0xsequence/wallet@0.41.3 + +## 0.41.2 + +### Patch Changes + +- api bindings update +- Updated dependencies + - @0xsequence/abi@0.41.2 + - @0xsequence/auth@0.41.2 + - @0xsequence/config@0.41.2 + - @0xsequence/network@0.41.2 + - @0xsequence/transactions@0.41.2 + - @0xsequence/utils@0.41.2 + - @0xsequence/wallet@0.41.2 + +## 0.41.1 + +### Patch Changes + +- update default networks +- Updated dependencies + - @0xsequence/abi@0.41.1 + - @0xsequence/auth@0.41.1 + - @0xsequence/config@0.41.1 + - @0xsequence/network@0.41.1 + - @0xsequence/transactions@0.41.1 + - @0xsequence/utils@0.41.1 + - @0xsequence/wallet@0.41.1 + +## 0.41.0 + +### Minor Changes + +- relayer: fix Relayer.wait() interface + + The interface for calling Relayer.wait() has changed. Instead of a single optional ill-defined timeout/delay parameter, there are three optional parameters, in order: + + - timeout: the maximum time to wait for the transaction receipt + - delay: the polling interval, i.e. the time to wait between requests + - maxFails: the maximum number of hard failures to tolerate before giving up + + Please update your codebase accordingly. + +- relayer: add optional waitForReceipt parameter to Relayer.relay + + The behaviour of Relayer.relay() was not well-defined with respect to whether or not it waited for a receipt. + This change allows the caller to specify whether to wait or not, with the default behaviour being to wait. + +### Patch Changes + +- relayer: wait receipt retry logic +- fix wrapped object error +- provider: forward delegateCall and revertOnError transaction fields +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.41.0 + - @0xsequence/auth@0.41.0 + - @0xsequence/config@0.41.0 + - @0xsequence/network@0.41.0 + - @0xsequence/transactions@0.41.0 + - @0xsequence/utils@0.41.0 + - @0xsequence/wallet@0.41.0 + +## 0.40.6 + +### Patch Changes + +- add arbitrum-nova chain +- Updated dependencies + - @0xsequence/abi@0.40.6 + - @0xsequence/auth@0.40.6 + - @0xsequence/config@0.40.6 + - @0xsequence/network@0.40.6 + - @0xsequence/transactions@0.40.6 + - @0xsequence/utils@0.40.6 + - @0xsequence/wallet@0.40.6 + +## 0.40.5 + +### Patch Changes + +- api: update bindings +- Updated dependencies + - @0xsequence/abi@0.40.5 + - @0xsequence/auth@0.40.5 + - @0xsequence/config@0.40.5 + - @0xsequence/network@0.40.5 + - @0xsequence/transactions@0.40.5 + - @0xsequence/utils@0.40.5 + - @0xsequence/wallet@0.40.5 + +## 0.40.4 + +### Patch Changes + +- add unreal transport +- Updated dependencies + - @0xsequence/abi@0.40.4 + - @0xsequence/auth@0.40.4 + - @0xsequence/config@0.40.4 + - @0xsequence/network@0.40.4 + - @0xsequence/transactions@0.40.4 + - @0xsequence/utils@0.40.4 + - @0xsequence/wallet@0.40.4 + +## 0.40.3 + +### Patch Changes + +- provider: fix MessageToSign message type +- Updated dependencies + - @0xsequence/abi@0.40.3 + - @0xsequence/auth@0.40.3 + - @0xsequence/config@0.40.3 + - @0xsequence/network@0.40.3 + - @0xsequence/transactions@0.40.3 + - @0xsequence/utils@0.40.3 + - @0xsequence/wallet@0.40.3 + +## 0.40.2 + +### Patch Changes + +- Wallet provider, loadSession method +- Updated dependencies + - @0xsequence/abi@0.40.2 + - @0xsequence/auth@0.40.2 + - @0xsequence/config@0.40.2 + - @0xsequence/network@0.40.2 + - @0xsequence/transactions@0.40.2 + - @0xsequence/utils@0.40.2 + - @0xsequence/wallet@0.40.2 + +## 0.40.1 + +### Patch Changes + +- export sequence.initWallet and sequence.getWallet +- Updated dependencies + - @0xsequence/abi@0.40.1 + - @0xsequence/auth@0.40.1 + - @0xsequence/config@0.40.1 + - @0xsequence/network@0.40.1 + - @0xsequence/transactions@0.40.1 + - @0xsequence/utils@0.40.1 + - @0xsequence/wallet@0.40.1 + +## 0.40.0 + +### Minor Changes + +- add sequence.initWallet(network, config) and sequence.getWallet() helper methods + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.40.0 + - @0xsequence/auth@0.40.0 + - @0xsequence/config@0.40.0 + - @0xsequence/network@0.40.0 + - @0xsequence/transactions@0.40.0 + - @0xsequence/utils@0.40.0 + - @0xsequence/wallet@0.40.0 + +## 0.39.6 + +### Patch Changes + +- indexer: update client bindings +- Updated dependencies + - @0xsequence/abi@0.39.6 + - @0xsequence/auth@0.39.6 + - @0xsequence/config@0.39.6 + - @0xsequence/network@0.39.6 + - @0xsequence/transactions@0.39.6 + - @0xsequence/utils@0.39.6 + - @0xsequence/wallet@0.39.6 + +## 0.39.5 + +### Patch Changes + +- provider: fix networkRpcUrl config option +- Updated dependencies + - @0xsequence/abi@0.39.5 + - @0xsequence/auth@0.39.5 + - @0xsequence/config@0.39.5 + - @0xsequence/network@0.39.5 + - @0xsequence/transactions@0.39.5 + - @0xsequence/utils@0.39.5 + - @0xsequence/wallet@0.39.5 + +## 0.39.4 + +### Patch Changes + +- api: update client bindings +- Updated dependencies + - @0xsequence/abi@0.39.4 + - @0xsequence/auth@0.39.4 + - @0xsequence/config@0.39.4 + - @0xsequence/network@0.39.4 + - @0xsequence/transactions@0.39.4 + - @0xsequence/utils@0.39.4 + - @0xsequence/wallet@0.39.4 + +## 0.39.3 + +### Patch Changes + +- add request method on Web3Provider +- Updated dependencies + - @0xsequence/abi@0.39.3 + - @0xsequence/auth@0.39.3 + - @0xsequence/config@0.39.3 + - @0xsequence/network@0.39.3 + - @0xsequence/transactions@0.39.3 + - @0xsequence/utils@0.39.3 + - @0xsequence/wallet@0.39.3 + +## 0.39.2 + +### Patch Changes + +- update umd name +- Updated dependencies + - @0xsequence/abi@0.39.2 + - @0xsequence/auth@0.39.2 + - @0xsequence/config@0.39.2 + - @0xsequence/network@0.39.2 + - @0xsequence/transactions@0.39.2 + - @0xsequence/utils@0.39.2 + - @0xsequence/wallet@0.39.2 + +## 0.39.1 + +### Patch Changes + +- add Aurora network +- add origin info for accountsChanged event to handle it per dapp +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.39.1 + - @0xsequence/auth@0.39.1 + - @0xsequence/config@0.39.1 + - @0xsequence/network@0.39.1 + - @0xsequence/transactions@0.39.1 + - @0xsequence/utils@0.39.1 + - @0xsequence/wallet@0.39.1 + +## 0.39.0 + +### Minor Changes + +- abstract window.localStorage to interface type + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.39.0 + - @0xsequence/auth@0.39.0 + - @0xsequence/config@0.39.0 + - @0xsequence/network@0.39.0 + - @0xsequence/transactions@0.39.0 + - @0xsequence/utils@0.39.0 + - @0xsequence/wallet@0.39.0 + +## 0.38.2 + +### Patch Changes + +- provider: add Settings.defaultPurchaseAmount +- Updated dependencies + - @0xsequence/abi@0.38.2 + - @0xsequence/auth@0.38.2 + - @0xsequence/config@0.38.2 + - @0xsequence/network@0.38.2 + - @0xsequence/transactions@0.38.2 + - @0xsequence/utils@0.38.2 + - @0xsequence/wallet@0.38.2 + +## 0.38.1 + +### Patch Changes + +- update api and metadata rpc bindings +- Updated dependencies + - @0xsequence/abi@0.38.1 + - @0xsequence/auth@0.38.1 + - @0xsequence/config@0.38.1 + - @0xsequence/network@0.38.1 + - @0xsequence/transactions@0.38.1 + - @0xsequence/utils@0.38.1 + - @0xsequence/wallet@0.38.1 + +## 0.38.0 + +### Minor Changes + +- api: update bindings, change TokenPrice interface +- bridge: remove @0xsequence/bridge package +- api: update bindings, rename ContractCallArg to TupleComponent + +### Patch Changes + +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.38.0 + - @0xsequence/auth@0.38.0 + - @0xsequence/config@0.38.0 + - @0xsequence/network@0.38.0 + - @0xsequence/transactions@0.38.0 + - @0xsequence/utils@0.38.0 + - @0xsequence/wallet@0.38.0 + +## 0.37.1 + +### Patch Changes + +- Add back sortNetworks - Removing sorting was a breaking change for dapps on older versions which directly integrate sequence. +- Updated dependencies + - @0xsequence/abi@0.37.1 + - @0xsequence/auth@0.37.1 + - @0xsequence/config@0.37.1 + - @0xsequence/network@0.37.1 + - @0xsequence/transactions@0.37.1 + - @0xsequence/utils@0.37.1 + - @0xsequence/wallet@0.37.1 + +## 0.37.0 + +### Minor Changes + +- network related fixes and improvements +- api: bindings: exchange rate lookups + +### Patch Changes + +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.37.0 + - @0xsequence/auth@0.37.0 + - @0xsequence/config@0.37.0 + - @0xsequence/network@0.37.0 + - @0xsequence/transactions@0.37.0 + - @0xsequence/utils@0.37.0 + - @0xsequence/wallet@0.37.0 + +## 0.36.13 + +### Patch Changes + +- api: update bindings with new price endpoints +- Updated dependencies + - @0xsequence/abi@0.36.13 + - @0xsequence/auth@0.36.13 + - @0xsequence/config@0.36.13 + - @0xsequence/network@0.36.13 + - @0xsequence/transactions@0.36.13 + - @0xsequence/utils@0.36.13 + - @0xsequence/wallet@0.36.13 + +## 0.36.12 + +### Patch Changes + +- wallet: skip remote signers if not needed +- auth: check that signature meets threshold before requesting auth token +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.36.12 + - @0xsequence/auth@0.36.12 + - @0xsequence/config@0.36.12 + - @0xsequence/network@0.36.12 + - @0xsequence/transactions@0.36.12 + - @0xsequence/utils@0.36.12 + - @0xsequence/wallet@0.36.12 + +## 0.36.11 + +### Patch Changes + +- Prefix EIP191 message on wallet-request-handler +- Updated dependencies + - @0xsequence/abi@0.36.11 + - @0xsequence/auth@0.36.11 + - @0xsequence/config@0.36.11 + - @0xsequence/network@0.36.11 + - @0xsequence/transactions@0.36.11 + - @0xsequence/utils@0.36.11 + - @0xsequence/wallet@0.36.11 + +## 0.36.10 + +### Patch Changes + +- support bannerUrl on connect +- Updated dependencies + - @0xsequence/abi@0.36.10 + - @0xsequence/auth@0.36.10 + - @0xsequence/config@0.36.10 + - @0xsequence/network@0.36.10 + - @0xsequence/transactions@0.36.10 + - @0xsequence/utils@0.36.10 + - @0xsequence/wallet@0.36.10 + +## 0.36.9 + +### Patch Changes + +- minor dev xp improvements +- Updated dependencies + - @0xsequence/abi@0.36.9 + - @0xsequence/auth@0.36.9 + - @0xsequence/config@0.36.9 + - @0xsequence/network@0.36.9 + - @0xsequence/transactions@0.36.9 + - @0xsequence/utils@0.36.9 + - @0xsequence/wallet@0.36.9 + +## 0.36.8 + +### Patch Changes + +- more connect options (theme, payment providers, funding currencies) +- Updated dependencies + - @0xsequence/abi@0.36.8 + - @0xsequence/auth@0.36.8 + - @0xsequence/config@0.36.8 + - @0xsequence/network@0.36.8 + - @0xsequence/transactions@0.36.8 + - @0xsequence/utils@0.36.8 + - @0xsequence/wallet@0.36.8 + +## 0.36.7 + +### Patch Changes + +- fix missing break +- Updated dependencies + - @0xsequence/abi@0.36.7 + - @0xsequence/auth@0.36.7 + - @0xsequence/config@0.36.7 + - @0xsequence/network@0.36.7 + - @0xsequence/transactions@0.36.7 + - @0xsequence/utils@0.36.7 + - @0xsequence/wallet@0.36.7 + +## 0.36.6 + +### Patch Changes + +- wallet_switchEthereumChain support +- Updated dependencies + - @0xsequence/abi@0.36.6 + - @0xsequence/auth@0.36.6 + - @0xsequence/config@0.36.6 + - @0xsequence/network@0.36.6 + - @0xsequence/transactions@0.36.6 + - @0xsequence/utils@0.36.6 + - @0xsequence/wallet@0.36.6 + +## 0.36.5 + +### Patch Changes + +- auth: bump ethauth to 0.7.0 + network, wallet: don't assume position of auth network in list + api/indexer/metadata: trim trailing slash on hostname, and add endpoint urls + relayer: Allow to specify local relayer transaction parameters like gas price or gas limit +- Updated dependencies + - @0xsequence/abi@0.36.5 + - @0xsequence/auth@0.36.5 + - @0xsequence/config@0.36.5 + - @0xsequence/network@0.36.5 + - @0xsequence/transactions@0.36.5 + - @0xsequence/utils@0.36.5 + - @0xsequence/wallet@0.36.5 + +## 0.36.4 + +### Patch Changes + +- Updating list of chain ids to include other ethereum compatible chains +- Updated dependencies + - @0xsequence/abi@0.36.4 + - @0xsequence/auth@0.36.4 + - @0xsequence/config@0.36.4 + - @0xsequence/network@0.36.4 + - @0xsequence/transactions@0.36.4 + - @0xsequence/utils@0.36.4 + - @0xsequence/wallet@0.36.4 + +## 0.36.3 + +### Patch Changes + +- provider: pass connect options to prompter methods +- Updated dependencies + - @0xsequence/abi@0.36.3 + - @0xsequence/auth@0.36.3 + - @0xsequence/config@0.36.3 + - @0xsequence/network@0.36.3 + - @0xsequence/transactions@0.36.3 + - @0xsequence/utils@0.36.3 + - @0xsequence/wallet@0.36.3 + +## 0.36.2 + +### Patch Changes + +- transactions: Setting target to 0x0 when empty to during SequenceTxAbiEncode +- Updated dependencies + - @0xsequence/abi@0.36.2 + - @0xsequence/auth@0.36.2 + - @0xsequence/config@0.36.2 + - @0xsequence/network@0.36.2 + - @0xsequence/transactions@0.36.2 + - @0xsequence/utils@0.36.2 + - @0xsequence/wallet@0.36.2 + +## 0.36.1 + +### Patch Changes + +- metadata: update client with more fields +- Updated dependencies + - @0xsequence/abi@0.36.1 + - @0xsequence/auth@0.36.1 + - @0xsequence/config@0.36.1 + - @0xsequence/network@0.36.1 + - @0xsequence/transactions@0.36.1 + - @0xsequence/utils@0.36.1 + - @0xsequence/wallet@0.36.1 + +## 0.36.0 + +### Minor Changes + +- relayer, wallet: fee quote support + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.36.0 + - @0xsequence/auth@0.36.0 + - @0xsequence/config@0.36.0 + - @0xsequence/network@0.36.0 + - @0xsequence/transactions@0.36.0 + - @0xsequence/utils@0.36.0 + - @0xsequence/wallet@0.36.0 + +## 0.35.12 + +### Patch Changes + +- provider: rename wallet.commands to wallet.utils +- Updated dependencies + - @0xsequence/abi@0.35.12 + - @0xsequence/auth@0.35.12 + - @0xsequence/config@0.35.12 + - @0xsequence/network@0.35.12 + - @0xsequence/transactions@0.35.12 + - @0xsequence/utils@0.35.12 + - @0xsequence/wallet@0.35.12 + +## 0.35.11 + +### Patch Changes + +- provider/utils: smoother message validation +- Updated dependencies + - @0xsequence/abi@0.35.11 + - @0xsequence/auth@0.35.11 + - @0xsequence/config@0.35.11 + - @0xsequence/network@0.35.11 + - @0xsequence/transactions@0.35.11 + - @0xsequence/utils@0.35.11 + - @0xsequence/wallet@0.35.11 + +## 0.35.10 + +### Patch Changes + +- upgrade deps +- Updated dependencies + - @0xsequence/abi@0.35.10 + - @0xsequence/auth@0.35.10 + - @0xsequence/config@0.35.10 + - @0xsequence/network@0.35.10 + - @0xsequence/transactions@0.35.10 + - @0xsequence/utils@0.35.10 + - @0xsequence/wallet@0.35.10 + +## 0.35.9 + +### Patch Changes + +- provider: window-transport override event handlers with new wallet instance +- Updated dependencies + - @0xsequence/abi@0.35.9 + - @0xsequence/auth@0.35.9 + - @0xsequence/config@0.35.9 + - @0xsequence/network@0.35.9 + - @0xsequence/transactions@0.35.9 + - @0xsequence/utils@0.35.9 + - @0xsequence/wallet@0.35.9 + +## 0.35.8 + +### Patch Changes + +- provider: async wallet sign in improvements +- Updated dependencies + - @0xsequence/abi@0.35.8 + - @0xsequence/auth@0.35.8 + - @0xsequence/config@0.35.8 + - @0xsequence/network@0.35.8 + - @0xsequence/transactions@0.35.8 + - @0xsequence/utils@0.35.8 + - @0xsequence/wallet@0.35.8 + +## 0.35.7 + +### Patch Changes + +- config: cache wallet configs +- Updated dependencies + - @0xsequence/abi@0.35.7 + - @0xsequence/auth@0.35.7 + - @0xsequence/config@0.35.7 + - @0xsequence/network@0.35.7 + - @0xsequence/transactions@0.35.7 + - @0xsequence/utils@0.35.7 + - @0xsequence/wallet@0.35.7 + +## 0.35.6 + +### Patch Changes + +- provider: support async signin of wallet request handler +- Updated dependencies + - @0xsequence/abi@0.35.6 + - @0xsequence/auth@0.35.6 + - @0xsequence/config@0.35.6 + - @0xsequence/network@0.35.6 + - @0xsequence/transactions@0.35.6 + - @0xsequence/utils@0.35.6 + - @0xsequence/wallet@0.35.6 + +## 0.35.5 + +### Patch Changes + +- wallet: skip threshold check during fee estimation +- Updated dependencies + - @0xsequence/abi@0.35.5 + - @0xsequence/auth@0.35.5 + - @0xsequence/config@0.35.5 + - @0xsequence/network@0.35.5 + - @0xsequence/transactions@0.35.5 + - @0xsequence/utils@0.35.5 + - @0xsequence/wallet@0.35.5 + +## 0.35.4 + +### Patch Changes + +- - browser extension mode, center window +- Updated dependencies + - @0xsequence/abi@0.35.4 + - @0xsequence/auth@0.35.4 + - @0xsequence/config@0.35.4 + - @0xsequence/network@0.35.4 + - @0xsequence/transactions@0.35.4 + - @0xsequence/utils@0.35.4 + - @0xsequence/wallet@0.35.4 + +## 0.35.3 + +### Patch Changes + +- - update window position when in browser extension mode +- Updated dependencies + - @0xsequence/abi@0.35.3 + - @0xsequence/auth@0.35.3 + - @0xsequence/config@0.35.3 + - @0xsequence/network@0.35.3 + - @0xsequence/transactions@0.35.3 + - @0xsequence/utils@0.35.3 + - @0xsequence/wallet@0.35.3 + +## 0.35.2 + +### Patch Changes + +- - provider: WindowMessageHandler accept optional windowHref +- Updated dependencies + - @0xsequence/abi@0.35.2 + - @0xsequence/auth@0.35.2 + - @0xsequence/config@0.35.2 + - @0xsequence/network@0.35.2 + - @0xsequence/transactions@0.35.2 + - @0xsequence/utils@0.35.2 + - @0xsequence/wallet@0.35.2 + +## 0.35.1 + +### Patch Changes + +- wallet: update config on undeployed too +- Updated dependencies + - @0xsequence/abi@0.35.1 + - @0xsequence/auth@0.35.1 + - @0xsequence/config@0.35.1 + - @0xsequence/network@0.35.1 + - @0xsequence/transactions@0.35.1 + - @0xsequence/utils@0.35.1 + - @0xsequence/wallet@0.35.1 + +## 0.35.0 + +### Minor Changes + +- - config: add buildStubSignature + - provider: add checks to signing cases for wallet deployment and config statuses + - provider: add prompt for wallet deployment + - relayer: add BaseRelayer.prependWalletDeploy + - relayer: add Relayer.feeOptions + - relayer: account for wallet deployment in fee estimation + - transactions: add fromTransactionish + - wallet: add Account.prependConfigUpdate + - wallet: add Account.getFeeOptions + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.35.0 + - @0xsequence/auth@0.35.0 + - @0xsequence/config@0.35.0 + - @0xsequence/network@0.35.0 + - @0xsequence/transactions@0.35.0 + - @0xsequence/utils@0.35.0 + - @0xsequence/wallet@0.35.0 + +## 0.34.1 + +### Patch Changes + +- Updated dependencies + - @0xsequence/auth@0.34.1 + +## 0.34.0 + +### Minor Changes + +- - upgrade deps + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.34.0 + - @0xsequence/auth@0.34.0 + - @0xsequence/config@0.34.0 + - @0xsequence/network@0.34.0 + - @0xsequence/transactions@0.34.0 + - @0xsequence/utils@0.34.0 + - @0xsequence/wallet@0.34.0 + +## 0.33.3 + +### Patch Changes + +- Updated dependencies + - @0xsequence/wallet@0.33.3 + - @0xsequence/auth@0.33.3 + +## 0.33.2 + +### Patch Changes + +- Updated dependencies + - @0xsequence/transactions@0.33.2 + - @0xsequence/wallet@0.33.2 + - @0xsequence/auth@0.33.2 + +## 0.33.1 + +### Patch Changes + +- @0xsequence/auth@0.33.1 + +## 0.33.0 + +### Patch Changes + +- Updated dependencies + - @0xsequence/auth@0.33.0 + +## 0.31.3 + +### Patch Changes + +- @0xsequence/auth@0.31.3 + +## 0.31.1 + +### Patch Changes + +- @0xsequence/wallet@0.31.1 +- @0xsequence/auth@0.31.1 + +## 0.31.0 + +### Minor Changes + +- - upgrading to ethers v5.5 + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.31.0 + - @0xsequence/auth@0.31.0 + - @0xsequence/config@0.31.0 + - @0xsequence/network@0.31.0 + - @0xsequence/transactions@0.31.0 + - @0xsequence/utils@0.31.0 + - @0xsequence/wallet@0.31.0 + +## 0.30.0 + +### Minor Changes + +- - upgrade most deps + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.30.0 + - @0xsequence/auth@0.30.0 + - @0xsequence/config@0.30.0 + - @0xsequence/network@0.30.0 + - @0xsequence/transactions@0.30.0 + - @0xsequence/utils@0.30.0 + - @0xsequence/wallet@0.30.0 + +## 0.29.9 + +### Patch Changes + +- @0xsequence/auth@0.29.9 + +## 0.29.8 + +### Patch Changes + +- update api +- Updated dependencies [undefined] + - @0xsequence/abi@0.29.8 + - @0xsequence/auth@0.29.8 + - @0xsequence/config@0.29.8 + - @0xsequence/network@0.29.8 + - @0xsequence/transactions@0.29.8 + - @0xsequence/utils@0.29.8 + - @0xsequence/wallet@0.29.8 + +## 0.29.7 + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/wallet@0.29.7 + - @0xsequence/auth@0.29.7 + +## 0.29.6 + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/network@0.29.6 + - @0xsequence/auth@0.29.6 + - @0xsequence/config@0.29.6 + - @0xsequence/transactions@0.29.6 + - @0xsequence/wallet@0.29.6 + +## 0.29.5 + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/auth@0.29.5 + - @0xsequence/config@0.29.5 + - @0xsequence/wallet@0.29.5 + +## 0.29.4 + +### Patch Changes + +- @0xsequence/auth@0.29.4 + +## 0.29.3 + +### Patch Changes + +- @0xsequence/auth@0.29.3 + +## 0.29.2 + +### Patch Changes + +- @0xsequence/wallet@0.29.2 +- @0xsequence/auth@0.29.2 + +## 0.29.1 + +### Patch Changes + +- @0xsequence/auth@0.29.1 + +## 0.29.0 + +### Minor Changes + +- major architectural changes in Sequence design + + - only one API instance, API is no longer a per-chain service + - separate per-chain indexer service, API no longer handles indexing + - single contract metadata service, API no longer serves metadata + + chaind package has been removed, indexer and metadata packages have been added + + stronger typing with new explicit ChainId type + + multicall fixes and improvements + + forbid "wait" transactions in sendTransactionBatch calls + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/auth@0.29.0 + - @0xsequence/config@0.29.0 + - @0xsequence/network@0.29.0 + - @0xsequence/transactions@0.29.0 + - @0xsequence/abi@0.29.0 + - @0xsequence/utils@0.29.0 + - @0xsequence/wallet@0.29.0 + +## 0.28.0 + +### Minor Changes + +- extension provider + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.28.0 + - @0xsequence/auth@0.28.0 + - @0xsequence/config@0.28.0 + - @0xsequence/network@0.28.0 + - @0xsequence/transactions@0.28.0 + - @0xsequence/utils@0.28.0 + - @0xsequence/wallet@0.28.0 + +## 0.27.2 + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/wallet@0.27.2 + - @0xsequence/auth@0.27.2 + +## 0.27.1 + +### Patch Changes + +- @0xsequence/wallet@0.27.1 +- @0xsequence/auth@0.27.1 + +## 0.27.0 + +### Minor Changes + +- Add requireFreshSigner lib to sessions + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.27.0 + - @0xsequence/auth@0.27.0 + - @0xsequence/config@0.27.0 + - @0xsequence/network@0.27.0 + - @0xsequence/transactions@0.27.0 + - @0xsequence/utils@0.27.0 + - @0xsequence/wallet@0.27.0 + +## 0.26.0 + +### Minor Changes + +- update relayer client bindings + provide the wallet's address for calls to SendMetaTxn + modify the semantics of Relayer.getNonce() to allow relayers to select nonce spaces for clients + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/wallet@0.26.0 + - @0xsequence/auth@0.26.0 + +## 0.25.1 + +### Patch Changes + +- Fix build typescrypt issue +- Updated dependencies [undefined] + - @0xsequence/abi@0.25.1 + - @0xsequence/auth@0.25.1 + - @0xsequence/config@0.25.1 + - @0xsequence/network@0.25.1 + - @0xsequence/transactions@0.25.1 + - @0xsequence/utils@0.25.1 + - @0xsequence/wallet@0.25.1 + +## 0.25.0 + +### Minor Changes + +- 10c8af8: Add estimator package + Fix multicall few calls bug + +### Patch Changes + +- Updated dependencies [10c8af8] + - @0xsequence/abi@0.25.0 + - @0xsequence/auth@0.25.0 + - @0xsequence/config@0.25.0 + - @0xsequence/network@0.25.0 + - @0xsequence/transactions@0.25.0 + - @0xsequence/utils@0.25.0 + - @0xsequence/wallet@0.25.0 + +## 0.24.1 + +### Patch Changes + +- @0xsequence/wallet@0.24.1 +- @0xsequence/auth@0.24.1 + +## 0.24.0 + +### Patch Changes + +- @0xsequence/auth@0.24.0 +- @0xsequence/wallet@0.24.0 + +## 0.23.0 + +### Minor Changes + +- - relayer: offer variety of gas fee options from the relayer service" + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.23.0 + - @0xsequence/auth@0.23.0 + - @0xsequence/config@0.23.0 + - @0xsequence/network@0.23.0 + - @0xsequence/transactions@0.23.0 + - @0xsequence/utils@0.23.0 + - @0xsequence/wallet@0.23.0 + +## 0.22.2 + +### Patch Changes + +- e1c109e: Fix authProof on expired sessions +- Updated dependencies [e1c109e] + - @0xsequence/auth@0.22.2 + - @0xsequence/abi@0.22.2 + - @0xsequence/config@0.22.2 + - @0xsequence/network@0.22.2 + - @0xsequence/transactions@0.22.2 + - @0xsequence/utils@0.22.2 + - @0xsequence/wallet@0.22.2 + +## 0.22.1 + +### Patch Changes + +- transport session cache +- Updated dependencies [undefined] + - @0xsequence/abi@0.22.1 + - @0xsequence/auth@0.22.1 + - @0xsequence/config@0.22.1 + - @0xsequence/network@0.22.1 + - @0xsequence/transactions@0.22.1 + - @0xsequence/utils@0.22.1 + - @0xsequence/wallet@0.22.1 + +## 0.22.0 + +### Minor Changes + +- e667b65: Expose all relayer options on networks + +### Patch Changes + +- Updated dependencies [e667b65] + - @0xsequence/abi@0.22.0 + - @0xsequence/network@0.22.0 + - @0xsequence/utils@0.22.0 + - @0xsequence/wallet@0.22.0 + - @0xsequence/auth@0.22.0 + - @0xsequence/config@0.22.0 + - @0xsequence/transactions@0.22.0 + +## 0.21.5 + +### Patch Changes + +- Give priority to metaTxnId returned by relayer +- Updated dependencies [undefined] + - @0xsequence/abi@0.21.5 + - @0xsequence/auth@0.21.5 + - @0xsequence/config@0.21.5 + - @0xsequence/network@0.21.5 + - @0xsequence/transactions@0.21.5 + - @0xsequence/utils@0.21.5 + - @0xsequence/wallet@0.21.5 + +## 0.21.4 + +### Patch Changes + +- Add has enough signers method +- Updated dependencies [undefined] + - @0xsequence/abi@0.21.4 + - @0xsequence/auth@0.21.4 + - @0xsequence/config@0.21.4 + - @0xsequence/network@0.21.4 + - @0xsequence/transactions@0.21.4 + - @0xsequence/utils@0.21.4 + - @0xsequence/wallet@0.21.4 + +## 0.21.3 + +### Patch Changes + +- add window session cache +- Updated dependencies [undefined] + - @0xsequence/abi@0.21.3 + - @0xsequence/auth@0.21.3 + - @0xsequence/config@0.21.3 + - @0xsequence/network@0.21.3 + - @0xsequence/transactions@0.21.3 + - @0xsequence/utils@0.21.3 + - @0xsequence/wallet@0.21.3 + +## 0.21.2 + +### Patch Changes + +- exception handlind in relayer +- Updated dependencies [undefined] + - @0xsequence/abi@0.21.2 + - @0xsequence/auth@0.21.2 + - @0xsequence/config@0.21.2 + - @0xsequence/network@0.21.2 + - @0xsequence/transactions@0.21.2 + - @0xsequence/utils@0.21.2 + - @0xsequence/wallet@0.21.2 + +## 0.21.1 + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/wallet@0.21.1 + - @0xsequence/auth@0.21.1 + +## 0.21.0 + +### Minor Changes + +- - fix gas estimation on wallets with large number of signers + - update to session handling and wallet config construction upon auth + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.21.0 + - @0xsequence/auth@0.21.0 + - @0xsequence/config@0.21.0 + - @0xsequence/network@0.21.0 + - @0xsequence/transactions@0.21.0 + - @0xsequence/utils@0.21.0 + - @0xsequence/wallet@0.21.0 + +## 0.20.0 + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/auth@0.20.0 + +## 0.19.3 + +### Patch Changes + +- jwtAuth visibility, package version sync +- Updated dependencies [undefined] + - @0xsequence/abi@0.19.3 + - @0xsequence/auth@0.19.3 + - @0xsequence/config@0.19.3 + - @0xsequence/network@0.19.3 + - @0xsequence/transactions@0.19.3 + - @0xsequence/utils@0.19.3 + - @0xsequence/wallet@0.19.3 + +## 0.19.2 + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.19.2 + - @0xsequence/auth@0.19.2 + - @0xsequence/config@0.19.2 + - @0xsequence/transactions@0.19.2 + - @0xsequence/wallet@0.19.2 + +## 0.19.1 + +### Patch Changes + +- add open intent in history state + +## 0.19.0 + +### Minor Changes + +- - provider, improve dapp / wallet transport io + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.19.0 + - @0xsequence/auth@0.19.0 + - @0xsequence/config@0.19.0 + - @0xsequence/network@0.19.0 + - @0xsequence/transactions@0.19.0 + - @0xsequence/utils@0.19.0 + - @0xsequence/wallet@0.19.0 + +## 0.18.0 + +### Minor Changes + +- relayer improvements and pending transaction handling + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.18.0 + - @0xsequence/auth@0.18.0 + - @0xsequence/config@0.18.0 + - @0xsequence/network@0.18.0 + - @0xsequence/transactions@0.18.0 + - @0xsequence/utils@0.18.0 + - @0xsequence/wallet@0.18.0 + +## 0.17.0 + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/auth@0.17.0 + +## 0.16.1 + +### Patch Changes + +- @0xsequence/auth@0.16.1 + +## 0.16.0 + +### Minor Changes + +- relayer as its own service separate from chaind + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.16.0 + - @0xsequence/auth@0.16.0 + - @0xsequence/config@0.16.0 + - @0xsequence/network@0.16.0 + - @0xsequence/transactions@0.16.0 + - @0xsequence/utils@0.16.0 + - @0xsequence/wallet@0.16.0 + +## 0.15.1 + +### Patch Changes + +- update api clients +- Updated dependencies [undefined] + - @0xsequence/abi@0.15.1 + - @0xsequence/auth@0.15.1 + - @0xsequence/config@0.15.1 + - @0xsequence/network@0.15.1 + - @0xsequence/transactions@0.15.1 + - @0xsequence/utils@0.15.1 + - @0xsequence/wallet@0.15.1 + +## 0.15.0 + +### Patch Changes + +- @0xsequence/wallet@0.15.0 +- @0xsequence/auth@0.15.0 +- @0xsequence/transactions@0.15.0 + +## 0.14.3 + +### Patch Changes + +- Fix 0xSequence relayer dependencies +- Updated dependencies [undefined] + - @0xsequence/abi@0.14.3 + - @0xsequence/auth@0.14.3 + - @0xsequence/config@0.14.3 + - @0xsequence/network@0.14.3 + - @0xsequence/transactions@0.14.3 + - @0xsequence/utils@0.14.3 + - @0xsequence/wallet@0.14.3 + +## 0.14.2 + +### Patch Changes + +- Add debug logs to rpc-relayer +- Updated dependencies [undefined] + - @0xsequence/abi@0.14.2 + - @0xsequence/auth@0.14.2 + - @0xsequence/config@0.14.2 + - @0xsequence/network@0.14.2 + - @0xsequence/transactions@0.14.2 + - @0xsequence/utils@0.14.2 + - @0xsequence/wallet@0.14.2 + +## 0.14.0 + +### Minor Changes + +- update sequence utils finder which includes optimization + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.14.0 + - @0xsequence/auth@0.14.0 + - @0xsequence/config@0.14.0 + - @0xsequence/network@0.14.0 + - @0xsequence/transactions@0.14.0 + - @0xsequence/utils@0.14.0 + - @0xsequence/wallet@0.14.0 + +## 0.13.0 + +### Minor Changes + +- Update SequenceUtils deployed contract + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.13.0 + - @0xsequence/auth@0.13.0 + - @0xsequence/config@0.13.0 + - @0xsequence/network@0.13.0 + - @0xsequence/transactions@0.13.0 + - @0xsequence/utils@0.13.0 + - @0xsequence/wallet@0.13.0 + +## 0.12.4 + +### Patch Changes + +- provider: set timeout to open wallet to 30s + +## 0.12.3 + +### Patch Changes + +- provider: proxy message event support + +## 0.12.2 + +### Patch Changes + +- proxy transport improvements + +## 0.12.1 + +### Patch Changes + +- npm bump +- Updated dependencies [undefined] + - @0xsequence/abi@0.12.1 + - @0xsequence/auth@0.12.1 + - @0xsequence/config@0.12.1 + - @0xsequence/network@0.12.1 + - @0xsequence/transactions@0.12.1 + - @0xsequence/utils@0.12.1 + - @0xsequence/wallet@0.12.1 + +## 0.12.0 + +### Minor Changes + +- provider: improvements to window transport + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.12.0 + - @0xsequence/auth@0.12.0 + - @0xsequence/config@0.12.0 + - @0xsequence/network@0.12.0 + - @0xsequence/transactions@0.12.0 + - @0xsequence/utils@0.12.0 + - @0xsequence/wallet@0.12.0 + +## 0.11.4 + +### Patch Changes + +- update api client +- Updated dependencies [undefined] + - @0xsequence/abi@0.11.4 + - @0xsequence/auth@0.11.4 + - @0xsequence/config@0.11.4 + - @0xsequence/network@0.11.4 + - @0xsequence/transactions@0.11.4 + - @0xsequence/utils@0.11.4 + - @0xsequence/wallet@0.11.4 + +## 0.11.3 + +### Patch Changes + +- improve openWindow state options handling +- Updated dependencies [undefined] + - @0xsequence/abi@0.11.3 + - @0xsequence/auth@0.11.3 + - @0xsequence/config@0.11.3 + - @0xsequence/network@0.11.3 + - @0xsequence/transactions@0.11.3 + - @0xsequence/utils@0.11.3 + - @0xsequence/wallet@0.11.3 + +## 0.11.2 + +### Patch Changes + +- Fix multicall proxy scopes +- Updated dependencies [undefined] + - @0xsequence/abi@0.11.2 + - @0xsequence/auth@0.11.2 + - @0xsequence/config@0.11.2 + - @0xsequence/network@0.11.2 + - @0xsequence/transactions@0.11.2 + - @0xsequence/utils@0.11.2 + - @0xsequence/wallet@0.11.2 + +## 0.11.1 + +### Patch Changes + +- Add support for dynamic and nested signatures +- Updated dependencies [undefined] + - @0xsequence/abi@0.11.1 + - @0xsequence/auth@0.11.1 + - @0xsequence/config@0.11.1 + - @0xsequence/network@0.11.1 + - @0xsequence/transactions@0.11.1 + - @0xsequence/utils@0.11.1 + - @0xsequence/wallet@0.11.1 + +## 0.11.0 + +### Minor Changes + +- Update wallet context to 1.7 contracts + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.11.0 + - @0xsequence/auth@0.11.0 + - @0xsequence/config@0.11.0 + - @0xsequence/network@0.11.0 + - @0xsequence/transactions@0.11.0 + - @0xsequence/utils@0.11.0 + - @0xsequence/wallet@0.11.0 + +## 0.10.9 + +### Patch Changes + +- add support for public addresses as signers in session.open +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.9 + - @0xsequence/auth@0.10.9 + - @0xsequence/config@0.10.9 + - @0xsequence/network@0.10.9 + - @0xsequence/transactions@0.10.9 + - @0xsequence/utils@0.10.9 + - @0xsequence/wallet@0.10.9 + +## 0.10.8 + +### Patch Changes + +- Multicall production configuration +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.8 + - @0xsequence/auth@0.10.8 + - @0xsequence/config@0.10.8 + - @0xsequence/network@0.10.8 + - @0xsequence/transactions@0.10.8 + - @0xsequence/utils@0.10.8 + - @0xsequence/wallet@0.10.8 + +## 0.10.7 + +### Patch Changes + +- allow provider transport to force disconnect +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.7 + - @0xsequence/auth@0.10.7 + - @0xsequence/config@0.10.7 + - @0xsequence/network@0.10.7 + - @0xsequence/transactions@0.10.7 + - @0xsequence/utils@0.10.7 + - @0xsequence/wallet@0.10.7 + +## 0.10.6 + +### Patch Changes + +- - fix getWalletState method +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.6 + - @0xsequence/auth@0.10.6 + - @0xsequence/config@0.10.6 + - @0xsequence/network@0.10.6 + - @0xsequence/transactions@0.10.6 + - @0xsequence/utils@0.10.6 + - @0xsequence/wallet@0.10.6 + +## 0.10.5 + +### Patch Changes + +- update relayer gas refund options +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.5 + - @0xsequence/auth@0.10.5 + - @0xsequence/config@0.10.5 + - @0xsequence/network@0.10.5 + - @0xsequence/transactions@0.10.5 + - @0xsequence/utils@0.10.5 + - @0xsequence/wallet@0.10.5 + +## 0.10.4 + +### Patch Changes + +- Update api proto +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.4 + - @0xsequence/auth@0.10.4 + - @0xsequence/config@0.10.4 + - @0xsequence/network@0.10.4 + - @0xsequence/transactions@0.10.4 + - @0xsequence/utils@0.10.4 + - @0xsequence/wallet@0.10.4 + +## 0.10.3 + +### Patch Changes + +- Fix loading config cross-chain +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.3 + - @0xsequence/auth@0.10.3 + - @0xsequence/config@0.10.3 + - @0xsequence/network@0.10.3 + - @0xsequence/transactions@0.10.3 + - @0xsequence/utils@0.10.3 + - @0xsequence/wallet@0.10.3 + +## 0.10.2 + +### Patch Changes + +- - message digest fix +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.2 + - @0xsequence/auth@0.10.2 + - @0xsequence/config@0.10.2 + - @0xsequence/network@0.10.2 + - @0xsequence/transactions@0.10.2 + - @0xsequence/utils@0.10.2 + - @0xsequence/wallet@0.10.2 + +## 0.10.1 + +### Patch Changes + +- upgrade deps +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.1 + - @0xsequence/auth@0.10.1 + - @0xsequence/config@0.10.1 + - @0xsequence/network@0.10.1 + - @0xsequence/transactions@0.10.1 + - @0xsequence/utils@0.10.1 + - @0xsequence/wallet@0.10.1 + +## 0.10.0 + +### Minor Changes + +- Deployed new contracts with ERC1271 signer support + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.0 + - @0xsequence/auth@0.10.0 + - @0xsequence/config@0.10.0 + - @0xsequence/network@0.10.0 + - @0xsequence/transactions@0.10.0 + - @0xsequence/utils@0.10.0 + - @0xsequence/wallet@0.10.0 + +## 0.9.6 + +### Patch Changes + +- Update ABIs for latest sequence contracts +- Updated dependencies [undefined] + - @0xsequence/auth@0.9.6 + - @0xsequence/config@0.9.6 + - @0xsequence/network@0.9.6 + - @0xsequence/transactions@0.9.6 + - @0xsequence/utils@0.9.6 + - @0xsequence/wallet@0.9.6 + - @0xsequence/abi@0.9.6 + +## 0.9.5 + +### Patch Changes + +- Implemented session class +- Updated dependencies [undefined] + - @0xsequence/auth@0.9.5 + - @0xsequence/config@0.9.5 + - @0xsequence/network@0.9.5 + - @0xsequence/transactions@0.9.5 + - @0xsequence/utils@0.9.5 + - @0xsequence/wallet@0.9.5 + +## 0.9.4 + +### Patch Changes + +- - session improvements + +## 0.9.3 + +### Patch Changes + +- - minor improvements +- Updated dependencies [undefined] + - @0xsequence/abi@0.9.3 + - @0xsequence/auth@0.9.3 + - @0xsequence/config@0.9.3 + - @0xsequence/network@0.9.3 + - @0xsequence/transactions@0.9.3 + - @0xsequence/utils@0.9.3 + - @0xsequence/wallet@0.9.3 + +## 0.9.1 + +### Patch Changes + +- - patch bump +- Updated dependencies [undefined] + - @0xsequence/abi@0.9.1 + - @0xsequence/auth@0.9.1 + - @0xsequence/config@0.9.1 + - @0xsequence/network@0.9.1 + - @0xsequence/transactions@0.9.1 + - @0xsequence/utils@0.9.1 + - @0xsequence/wallet@0.9.1 + +## 0.9.0 + +### Minor Changes + +- - provider transport hardening + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.9.0 + - @0xsequence/auth@0.9.0 + - @0xsequence/config@0.9.0 + - @0xsequence/network@0.9.0 + - @0xsequence/transactions@0.9.0 + - @0xsequence/utils@0.9.0 + - @0xsequence/wallet@0.9.0 + +## 0.8.5 + +### Patch Changes + +- - use latest wallet-contracts +- Updated dependencies [undefined] + - @0xsequence/abi@0.8.5 + - @0xsequence/auth@0.8.5 + - @0xsequence/config@0.8.5 + - @0xsequence/network@0.8.5 + - @0xsequence/transactions@0.8.5 + - @0xsequence/utils@0.8.5 + - @0xsequence/wallet@0.8.5 + +## 0.8.4 + +### Patch Changes + +- - minor improvements, name updates and comments +- Updated dependencies [undefined] + - @0xsequence/abi@0.8.4 + - @0xsequence/auth@0.8.4 + - @0xsequence/config@0.8.4 + - @0xsequence/network@0.8.4 + - @0xsequence/transactions@0.8.4 + - @0xsequence/utils@0.8.4 + - @0xsequence/wallet@0.8.4 + +## 0.8.3 + +### Patch Changes + +- - refinements + + - normalize signer address in config + + - provider: getWalletState() method to WalletProvider + +- Updated dependencies [undefined] + - @0xsequence/abi@0.8.3 + - @0xsequence/auth@0.8.3 + - @0xsequence/config@0.8.3 + - @0xsequence/network@0.8.3 + - @0xsequence/transactions@0.8.3 + - @0xsequence/utils@0.8.3 + - @0xsequence/wallet@0.8.3 + +## 0.8.2 + +### Patch Changes + +- - field rename and ethauth dependency bump +- Updated dependencies [undefined] + - @0xsequence/abi@0.8.2 + - @0xsequence/auth@0.8.2 + - @0xsequence/config@0.8.2 + - @0xsequence/network@0.8.2 + - @0xsequence/transactions@0.8.2 + - @0xsequence/utils@0.8.2 + - @0xsequence/wallet@0.8.2 + +## 0.8.1 + +### Patch Changes + +- - variety of optimizations +- Updated dependencies [undefined] + - @0xsequence/abi@0.8.1 + - @0xsequence/auth@0.8.1 + - @0xsequence/config@0.8.1 + - @0xsequence/network@0.8.1 + - @0xsequence/transactions@0.8.1 + - @0xsequence/utils@0.8.1 + - @0xsequence/wallet@0.8.1 + +## 0.8.0 + +### Minor Changes + +- - changeset fix + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.8.0 + - @0xsequence/auth@0.8.0 + - @0xsequence/network@0.8.0 + - @0xsequence/transactions@0.8.0 + - @0xsequence/utils@0.8.0 + - @0xsequence/wallet@0.8.0 + +## 0.7.1 + +### Patch Changes + +- 02377ab: Minor improvements +- Updated dependencies [02377ab] +- Updated dependencies [1fe4379] + - @0xsequence/network@0.7.1 + - @0xsequence/utils@0.7.1 + - @0xsequence/wallet@0.7.1 + +## 0.7.0 + +### Patch Changes + +- 6f11ed7: sequence.js, init release +- Updated dependencies [6f11ed7] + - @0xsequence/abi@0.7.0 + - @0xsequence/auth@0.7.0 + - @0xsequence/network@0.7.0 + - @0xsequence/transactions@0.7.0 + - @0xsequence/utils@0.7.0 + - @0xsequence/wallet@0.7.0 diff --git a/packages/provider/README.md b/packages/provider/README.md new file mode 100644 index 0000000000..1145018ae3 --- /dev/null +++ b/packages/provider/README.md @@ -0,0 +1,4 @@ +@0xsequence/provider +==================== + +See [0xsequence project page](https://github.com/0xsequence/sequence.js). diff --git a/packages/provider/hardhat1.config.js b/packages/provider/hardhat1.config.js new file mode 100644 index 0000000000..e88cf69acf --- /dev/null +++ b/packages/provider/hardhat1.config.js @@ -0,0 +1,16 @@ +/** + * @type import('hardhat/config').HardhatUserConfig + */ +module.exports = { + solidity: '0.7.6', + + networks: { + hardhat: { + initialBaseFeePerGas: 1, + chainId: 31337, + accounts: { + mnemonic: 'ripple axis someone ridge uniform wrist prosper there frog rate olympic knee' + }, + }, + } +} diff --git a/packages/provider/hardhat2.config.js b/packages/provider/hardhat2.config.js new file mode 100644 index 0000000000..981cb7ce01 --- /dev/null +++ b/packages/provider/hardhat2.config.js @@ -0,0 +1,16 @@ +/** + * @type import('hardhat/config').HardhatUserConfig + */ +module.exports = { + solidity: '0.7.6', + + networks: { + hardhat: { + initialBaseFeePerGas: 1, + chainId: 31338, + accounts: { + mnemonic: 'ripple axis someone ridge uniform wrist prosper there frog rate olympic knee' + }, + }, + } +} diff --git a/packages/provider/package.json b/packages/provider/package.json new file mode 100644 index 0000000000..22bb01a9b0 --- /dev/null +++ b/packages/provider/package.json @@ -0,0 +1,48 @@ +{ + "name": "@0xsequence/provider", + "version": "2.0.0", + "description": "provider sub-package for Sequence", + "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/provider", + "source": "src/index.ts", + "main": "dist/0xsequence-provider.cjs.js", + "module": "dist/0xsequence-provider.esm.js", + "author": "Horizon Blockchain Games", + "license": "Apache-2.0", + "scripts": { + "test": "pnpm test:concurrently 'pnpm test:run'", + "test:run": "pnpm test:file tests/**/*.spec.ts", + "test:file": "NODE_OPTIONS='--import tsx' mocha --timeout 30000", + "typecheck": "tsc --noEmit", + "test:concurrently": "concurrently -k --success first 'pnpm start:hardhat1' 'pnpm start:hardhat2'", + "start:hardhat1": "pnpm start:hardhat1:verbose > /dev/null 2>&1", + "start:hardhat2": "pnpm start:hardhat2:verbose > /dev/null 2>&1", + "start:hardhat1:verbose": "hardhat node --config hardhat1.config.js --hostname 0.0.0.0 --port 9595", + "start:hardhat2:verbose": "hardhat node --config hardhat2.config.js --hostname 0.0.0.0 --port 8595" + }, + "dependencies": { + "@0xsequence/abi": "workspace:*", + "@0xsequence/account": "workspace:*", + "@0xsequence/auth": "workspace:*", + "@0xsequence/core": "workspace:*", + "@0xsequence/migration": "workspace:*", + "@0xsequence/network": "workspace:*", + "@0xsequence/relayer": "workspace:*", + "@0xsequence/utils": "workspace:*", + "@0xsequence/wallet": "workspace:*", + "@databeat/tracker": "^0.9.1", + "eventemitter2": "^6.4.5", + "webextension-polyfill": "^0.10.0" + }, + "peerDependencies": { + "ethers": ">=5.5 < 6" + }, + "devDependencies": { + "@types/webextension-polyfill": "^0.10.0", + "ethers": "^5.7.2", + "hardhat": "^2.20.1" + }, + "files": [ + "src", + "dist" + ] +} diff --git a/packages/provider/src/analytics.ts b/packages/provider/src/analytics.ts new file mode 100644 index 0000000000..54cb2832ee --- /dev/null +++ b/packages/provider/src/analytics.ts @@ -0,0 +1,47 @@ +import { Databeat, Event as DatabeatEvent, Auth, isBrowser } from '@databeat/tracker' + +export enum EventType { + // Core types part of Databeat + INIT, + VIEW, + + // Provider specific + SIGN_MESSAGE_REQUEST, + SIGN_TYPED_DATA_REQUEST, + SEND_TRANSACTION_REQUEST +} + +export type EventTypes = keyof typeof EventType +export type Event = DatabeatEvent + +// Analytics sub-class to add some custom helper methods +export class Analytics extends Databeat {} + +// Setup analytics tracker +export const setupAnalytics = (projectAccessKey: string, server?: string) => { + if (!server) { + server = 'https://nodes.sequence.app' + } + + // disable tracking if projectAccessKey is not set + const noop = !projectAccessKey + + // auth + const auth: Auth = {} + if (projectAccessKey) { + auth.headers = { 'X-Access-Key': projectAccessKey } + } + + return new Analytics(server, auth, { + noop: noop, + defaultEnabled: true, + privacy: { userIdHash: true, userAgentSalt: false }, + initProps: () => { + if (!isBrowser()) { + return {} + } else { + return { origin: window.location.origin } + } + } + }) +} diff --git a/packages/provider/src/client.ts b/packages/provider/src/client.ts new file mode 100644 index 0000000000..ea280f6419 --- /dev/null +++ b/packages/provider/src/client.ts @@ -0,0 +1,535 @@ +import { JsonRpcRequest, JsonRpcResponse, NetworkConfig } from '@0xsequence/network' +import { + ConnectDetails, + ConnectOptions, + ItemStore, + MuxMessageProvider, + MuxTransportTemplate, + OpenWalletIntent, + OptionalChainId, + OptionalEIP6492, + ProviderTransport, + WalletEventTypes, + WalletSession, + isMuxTransportTemplate, + isProviderTransport, + messageToBytes +} from '.' +import { commons } from '@0xsequence/core' +import { TypedData } from '@0xsequence/utils' +import { toExtended } from './extended' +import { Analytics, setupAnalytics } from './analytics' +import { ethers } from 'ethers' + +import packageJson from '../package.json' + +/** + * This session class is meant to persist the state of the wallet connection + * whitin the dapp. This enables the client to retain the wallet address (and some more) + * even if the user refreshes the page. Otherwise we would have to open the popup again. + */ +export class SequenceClientSession { + static readonly SESSION_LOCALSTORE_KEY = '@sequence.session' + + constructor(private store: ItemStore) {} + + connectedSession(): Required { + const session = this.getSession() + + if (session && session.accountAddress && session.walletContext && session.networks) { + return { + accountAddress: session.accountAddress!, + walletContext: session.walletContext!, + networks: session.networks! + } + } + + throw new Error('Sequence session not connected') + } + + hasSession(): boolean { + return this.getSession()?.accountAddress !== undefined + } + + setSession(session: WalletSession) { + return this.store.setItem(SequenceClientSession.SESSION_LOCALSTORE_KEY, JSON.stringify(session)) + } + + getSession(): WalletSession | undefined { + const session = this.store.getItem(SequenceClientSession.SESSION_LOCALSTORE_KEY) + + if (session) { + return JSON.parse(session) + } + + return undefined + } + + async clearSession() { + return this.store.removeItem(SequenceClientSession.SESSION_LOCALSTORE_KEY) + } +} + +/** + * The wallet webapp doesn't really care what's the "default chain" for the user. + * so we don't even bother to send this information to the wallet. Instead, we + * track it locally using storage, that way the data stays always in sync. + */ +export class DefaultChainIdTracker { + static readonly SESSION_CHAIN_ID_KEY = '@sequence.session.defaultChainId' + + callbacks: ((chainId: number) => void)[] = [] + + constructor( + private store: ItemStore, + private startingChainId: number = 1 + ) { + store.onItemChange(DefaultChainIdTracker.SESSION_CHAIN_ID_KEY, (value: string | null) => { + if (value) { + const chainId = parseInt(value) + this.callbacks.forEach(cb => cb(chainId)) + } + }) + } + + onDefaultChainIdChanged(callback: (chainId: number) => void) { + this.callbacks.push(callback) + return () => { + this.callbacks = this.callbacks.filter(cb => cb !== callback) + } + } + + setDefaultChainId(chainId: number) { + if (chainId !== this.getDefaultChainId()) { + this.store.setItem(DefaultChainIdTracker.SESSION_CHAIN_ID_KEY, chainId.toString()) + } + } + + getDefaultChainId(): number { + const read = this.store.getItem(DefaultChainIdTracker.SESSION_CHAIN_ID_KEY) + + if (!read || read.length === 0) { + return this.startingChainId + } + + return parseInt(read) + } +} + +export type SequenceClientOptions = { + defaultChainId?: number + defaultEIP6492?: boolean + projectAccessKey?: string + analytics?: boolean +} + +/** + * This is a wallet client for sequence wallet-webapp. It connects using *some* transport + * and it allows to perform all sequence specific (or write) operations related to the wallet. + *s + * It doesn't implement a full ethereum Provider, it doesn't include read-only methods. + */ + +// TODO: rename Client to transport.. or something.. like SequenceTransport .. +export class SequenceClient { + private readonly session: SequenceClientSession + private readonly defaultChainId: DefaultChainIdTracker + private readonly callbacks: { [K in keyof WalletEventTypes]?: WalletEventTypes[K][] } = {} + + public readonly transport: ProviderTransport + + public readonly defaultEIP6492: boolean + public readonly projectAccessKey?: string + public readonly analytics?: Analytics + + constructor(transport: ProviderTransport | MuxTransportTemplate, store: ItemStore, options?: SequenceClientOptions) { + if (isMuxTransportTemplate(transport)) { + this.transport = MuxMessageProvider.new(transport) + } else if (isProviderTransport(transport)) { + this.transport = transport + } else { + throw new Error('Invalid transport') + } + + const defaultChainId = options?.defaultChainId + this.defaultEIP6492 = options?.defaultEIP6492 ?? false + + this.session = new SequenceClientSession(store) + this.defaultChainId = new DefaultChainIdTracker(store, defaultChainId) + + this.transport.on('accountsChanged', (accounts: string[]) => { + if (accounts.length > 1) { + console.warn('SequenceClient: wallet-webapp returned more than one account') + } + + this.callbacks.accountsChanged?.forEach(cb => cb(accounts)) + }) + + this.transport.on('connect', (response: ConnectDetails) => { + const chainIdHex = ethers.utils.hexValue(this.getChainId()) + this.callbacks.connect?.forEach(cb => + cb({ + ...response, + // Ignore the full connect response + // use the chainId defined locally + chainId: chainIdHex + }) + ) + }) + + this.transport.on('disconnect', (error, origin) => { + this.callbacks.disconnect?.forEach(cb => cb(error, origin)) + }) + + this.transport.on('networks', networks => { + this.callbacks.networks?.forEach(cb => cb(networks)) + }) + + this.transport.on('walletContext', context => { + this.callbacks.walletContext?.forEach(cb => cb(context)) + }) + + this.transport.on('open', info => { + this.callbacks.open?.forEach(cb => cb(info)) + }) + + this.transport.on('close', () => { + this.callbacks.close?.forEach(cb => cb()) + }) + + this.transport.on('chainChanged', (chainIdHex, origin) => { + this.callbacks.chainChanged?.forEach(cb => cb(chainIdHex, origin)) + }) + + // We don't listen for the transport chainChanged event + // instead we handle it locally, so we listen for changes in the store + this.defaultChainId.onDefaultChainIdChanged((chainId: number) => { + const chainIdHex = ethers.utils.hexValue(chainId) + this.callbacks.chainChanged?.forEach(cb => cb(chainIdHex)) + }) + + if (options?.projectAccessKey) { + this.projectAccessKey = options.projectAccessKey + } + if (this.projectAccessKey && options?.analytics) { + this.analytics = setupAnalytics(this.projectAccessKey) + } + + if (this.session.getSession()?.accountAddress) { + this.analytics?.identify(this.session.getSession()?.accountAddress?.toLowerCase()) + } + } + + // Callbacks + + registerCallback(eventName: K, callback: WalletEventTypes[K]) { + if (!this.callbacks[eventName]) { + this.callbacks[eventName] = [] + } + + this.callbacks[eventName]!.push(callback) + + return () => { + this.callbacks[eventName] = this.callbacks[eventName]!.filter(c => c !== callback) as any + } + } + + // Individual callbacks lead to more idiomatic code + + onOpen(callback: WalletEventTypes['open']) { + return this.registerCallback('open', callback) + } + + onClose(callback: WalletEventTypes['close']) { + return this.registerCallback('close', callback) + } + + onConnect(callback: WalletEventTypes['connect']) { + return this.registerCallback('connect', callback) + } + + onDisconnect(callback: WalletEventTypes['disconnect']) { + return this.registerCallback('disconnect', callback) + } + + onNetworks(callback: WalletEventTypes['networks']) { + return this.registerCallback('networks', callback) + } + + onAccountsChanged(callback: WalletEventTypes['accountsChanged']) { + return this.registerCallback('accountsChanged', callback) + } + + // @deprecated + onWalletContext(callback: WalletEventTypes['walletContext']) { + return this.registerCallback('walletContext', callback) + } + + onChainChanged(callback: WalletEventTypes['chainChanged']) { + return this.registerCallback('chainChanged', callback) + } + + onDefaultChainIdChanged(callback: WalletEventTypes['chainChanged']) { + return this.registerCallback('chainChanged', callback) + } + + getChainId(): number { + return this.defaultChainId.getDefaultChainId() + } + + setDefaultChainId(chainId: number) { + return this.defaultChainId.setDefaultChainId(chainId) + } + + // Proxy transport methods + + async openWallet(path?: string, intent?: OpenWalletIntent) { + this.transport.openWallet(path, intent, this.getChainId()) + await this.transport.waitUntilOpened() + return this.isOpened() + } + + closeWallet() { + return this.transport.closeWallet() + } + + isOpened(): boolean { + return this.transport.isOpened() + } + + isConnected(): boolean { + return this.session.hasSession() + } + + getSession(): WalletSession | undefined { + return this.session.getSession() + } + + // Basic API + getAddress(): string { + const session = this.session.connectedSession() + return session.accountAddress + } + + async connect(options: ConnectOptions): Promise { + if (options?.authorizeVersion === undefined) { + // Populate default authorize version if not provided + options.authorizeVersion = 2 + } + + if (options?.refresh === true) { + this.disconnect() + } + + options.projectAccessKey = this.projectAccessKey + + if (options) { + if (options.authorize) { + if (!options.app) { + throw new Error(`connecting with 'authorize' option also requires 'app' to be set`) + } + + if (options.authorizeVersion === undefined) { + options.authorizeVersion = 2 + } + } + } + + await this.openWallet(undefined, { + type: 'connect', + options: { ...options, networkId: this.getChainId(), clientVersion: packageJson.version } + }) + + const connectDetails = await this.transport.waitUntilConnected().catch((error): ConnectDetails => { + if (error instanceof Error) { + return { connected: false, error: error.message } + } else { + return { connected: false, error: JSON.stringify(error) } + } + }) + + // Normalize chainId into a decimal string + // TODO: Remove this once wallet-webapp returns chainId as a string + if (connectDetails.chainId) { + connectDetails.chainId = ethers.BigNumber.from(connectDetails.chainId).toString() + } + + if (connectDetails.connected) { + if (!connectDetails.session) { + throw new Error('impossible state, connect response is missing session') + } + + this.session.setSession(connectDetails.session) + + if (connectDetails.session?.accountAddress) { + this.analytics?.identify(connectDetails.session.accountAddress.toLowerCase()) + } + } + + return connectDetails + } + + disconnect() { + if (this.isOpened()) { + this.closeWallet() + } + + this.analytics?.reset() + + return this.session.clearSession() + } + + // Higher level API + + // Working with sendAsync is less idiomatic + // but transport uses it instead of send, so we wrap it + send(request: JsonRpcRequest, chainId?: number): Promise { + // Internally when sending requests we use `legacy_sign` + // to avoid the default EIP6492 behavior overriding an explicit + // "legacy sign" request, so we map the method here. + request.method = this.mapSignMethod(request.method) + + return new Promise((resolve, reject) => { + this.transport.sendAsync( + request, + (error, response) => { + if (error) { + reject(error) + } else if (response === undefined) { + reject(new Error(`Got undefined response for request: ${request}`)) + } else if (typeof response === 'object' && response.error) { + reject(response.error) + } else if (typeof response === 'object' && response.result) { + resolve(response.result) + } else { + reject(new Error(`Got invalid response for request: ${request}`)) + } + }, + chainId || this.getChainId() + ) + }) + } + + async getNetworks(pull?: boolean): Promise { + const connectedSession = this.session.connectedSession() + + if (pull) { + connectedSession.networks = await this.send({ method: 'sequence_getNetworks' }) + this.session.setSession(connectedSession) + } + + return connectedSession.networks + } + + // NOTICE: `legacy_sign` will get overriden by `send` + // it is done this way to ensure that: + // - `send` handles `personal_sign` as a request for the default sign method + // - explicit `personal_sign` is not replaced by `sequence_sign` (if default is EI6492) + private signMethod(options?: OptionalEIP6492) { + if (options?.eip6492 === undefined) { + return 'personal_sign' + } + + return options.eip6492 ? 'sequence_sign' : 'legacy_sign' + } + + private signTypedDataMethod(options?: OptionalEIP6492) { + if (options?.eip6492 === undefined) { + return 'eth_signTypedData_v4' + } + + return options.eip6492 ? 'sequence_signTypedData_v4' : 'legacy_signTypedData_v4' + } + + private mapSignMethod(method: string): string { + if (method === 'personal_sign') { + if (this.defaultEIP6492) { + return 'sequence_sign' + } else { + return 'personal_sign' + } + } + + if (method === 'eth_signTypedData_v4') { + if (this.defaultEIP6492) { + return 'sequence_signTypedData_v4' + } else { + return 'eth_signTypedData_v4' + } + } + + if (method === 'legacy_sign') { + return 'personal_sign' + } + + if (method === 'legacy_signTypedData_v4') { + return 'eth_signTypedData_v4' + } + + return method + } + + async signMessage(message: ethers.BytesLike, options?: OptionalEIP6492 & OptionalChainId): Promise { + const method = this.signMethod(options) + + this.analytics?.track({ event: 'SIGN_MESSAGE_REQUEST', props: { chainId: `${options?.chainId || this.getChainId()}` } }) + + // Serialize a BytesLike or string message into a hex string before sending + message = ethers.utils.hexlify(messageToBytes(message)) + + // Address is ignored by the wallet webapp + return this.send({ method, params: [message, this.getAddress()] }, options?.chainId) + } + + async signTypedData(typedData: TypedData, options?: OptionalEIP6492 & OptionalChainId): Promise { + const method = this.signTypedDataMethod(options) + + // TODO: Stop using ethers for this, this is the only place where we use it + // and it makes the client depend on ethers. + const encoded = ethers.utils._TypedDataEncoder.getPayload(typedData.domain, typedData.types, typedData.message) + + // The sign typed data will use one of the following chainIds, in order: + // - The one provided in the options + // - The one provided in the typedData.domain.chainId + // - The default chainId + + this.analytics?.track({ event: 'SIGN_TYPED_DATA_REQUEST', props: { chainId: `${options?.chainId || this.getChainId()}` } }) + + return this.send( + { method, params: [this.getAddress(), encoded] }, + options?.chainId || + (typedData.domain.chainId && ethers.BigNumber.from(typedData.domain.chainId).toNumber()) || + this.getChainId() + ) + } + + async sendTransaction( + tx: ethers.providers.TransactionRequest[] | ethers.providers.TransactionRequest, + options?: OptionalChainId + ): Promise { + const sequenceTxs = Array.isArray(tx) ? tx : [tx] + const extendedTxs = toExtended(sequenceTxs) + + this.analytics?.track({ event: 'SEND_TRANSACTION_REQUEST', props: { chainId: `${options?.chainId || this.getChainId()}` } }) + + return this.send({ method: 'eth_sendTransaction', params: [extendedTxs] }, options?.chainId) + } + + async getWalletContext(): Promise { + return this.send({ method: 'sequence_getWalletContext' }) + } + + async getOnchainWalletConfig(options?: OptionalChainId): Promise { + // NOTICE: sequence_getWalletConfig sends the chainId as a param + const res = await this.send( + { method: 'sequence_getWalletConfig', params: [options?.chainId || this.getChainId()] }, + options?.chainId + ) + return Array.isArray(res) ? res[0] : res + } + + // NOTICE: We are leaving out all the "regular" methods os a tipical + // JSON RPC Provider (eth_getBlockByNumber, eth_call, etc) + // wallet-webapp does implement them, but this client is meant to be + // exclusively used for Sequence specific methods +} diff --git a/packages/provider/src/eip191exceptions.ts b/packages/provider/src/eip191exceptions.ts new file mode 100644 index 0000000000..af24a53157 --- /dev/null +++ b/packages/provider/src/eip191exceptions.ts @@ -0,0 +1,137 @@ +import { ethers } from 'ethers' + +export function messageIsExemptFromEIP191Prefix(message: Uint8Array): boolean { + return EIP_191_PREFIX_EXCEPTIONS.some(e => e.predicate(message)) +} + +const EIP_191_PREFIX_EXCEPTIONS: Array<{ + name: string + predicate: (message: Uint8Array) => boolean +}> = [ + // NOTE: Decentraland does not support 191 correctly. + { + name: 'Decentraland Exception', + predicate: isDecentralandLoginMessage + }, + + // NOTE: 0x v3 does not support 191 correctly. + // See https://gov.0x.org/t/zeip-proposal-fix-v3-eip-191-non-compliance-when-validating-eip-1271-signatures/3396 for more info. + { name: '0x v3 Exception', predicate: isZeroExV3Order } +] + +const DCL_REGEX = + /^Decentraland Login\nEphemeral address: 0x[a-fA-F0-9]{40}\nExpiration: (\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)((-(\d{2}):(\d{2})|Z)?)$/ +export function isDecentralandLoginMessage(bytes: Uint8Array): boolean { + try { + const stringified = ethers.utils.toUtf8String(bytes) + return DCL_REGEX.test(stringified) + } catch { + return false + } +} + +// try to interpret bytes as abi-encoded 0x v3 OrderWithHash - +// see https://github.com/0xProject/0x-protocol-specification/blob/master/v3/v3-specification.md +export function isZeroExV3Order(bytes: Uint8Array): boolean { + const abi = new ethers.utils.Interface(ZeroXV3EIP1271OrderWithHashAbi) + try { + abi.decodeFunctionData('OrderWithHash', bytes) + return true + } catch (err) { + // failed to decode ABI, so it's not a v3 order. + return false + } +} + +const ZeroXV3EIP1271OrderWithHashAbi = [ + { + inputs: [ + { + components: [ + { + internalType: 'address', + name: 'makerAddress', + type: 'address' + }, + { + internalType: 'address', + name: 'takerAddress', + type: 'address' + }, + { + internalType: 'address', + name: 'feeRecipientAddress', + type: 'address' + }, + { + internalType: 'address', + name: 'senderAddress', + type: 'address' + }, + { + internalType: 'uint256', + name: 'makerAssetAmount', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'takerAssetAmount', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'makerFee', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'takerFee', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'expirationTimeSeconds', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'salt', + type: 'uint256' + }, + { + internalType: 'bytes', + name: 'makerAssetData', + type: 'bytes' + }, + { + internalType: 'bytes', + name: 'takerAssetData', + type: 'bytes' + }, + { + internalType: 'bytes', + name: 'makerFeeAssetData', + type: 'bytes' + }, + { + internalType: 'bytes', + name: 'takerFeeAssetData', + type: 'bytes' + } + ], + internalType: 'struct IEIP1271Data.Order', + name: 'order', + type: 'tuple' + }, + { + internalType: 'bytes32', + name: 'orderHash', + type: 'bytes32' + } + ], + name: 'OrderWithHash', + outputs: [], + stateMutability: 'pure', + type: 'function' + } +] diff --git a/packages/provider/src/extended.ts b/packages/provider/src/extended.ts new file mode 100644 index 0000000000..b8e15a5fcf --- /dev/null +++ b/packages/provider/src/extended.ts @@ -0,0 +1,26 @@ +import { ethers } from 'ethers' + +export type ExtendedTransactionRequest = ethers.providers.TransactionRequest & { + auxiliary?: ethers.providers.TransactionRequest[] +} + +export function toExtended(transactions: ethers.providers.TransactionRequest[]): ExtendedTransactionRequest { + if (transactions.length === 0) { + throw new Error('No transaction provided') + } + + const [first, ...rest] = transactions + + return { + ...first, + auxiliary: rest + } +} + +export function fromExtended(transaction: ExtendedTransactionRequest): ethers.providers.TransactionRequest[] { + return [transaction, ...(transaction.auxiliary || [])] +} + +export function isExtended(transaction: ethers.providers.TransactionRequest): transaction is ExtendedTransactionRequest { + return (transaction as any).auxiliary !== undefined +} diff --git a/packages/provider/src/index.ts b/packages/provider/src/index.ts new file mode 100644 index 0000000000..50e99d811e --- /dev/null +++ b/packages/provider/src/index.ts @@ -0,0 +1,8 @@ +export * from './transactions' +export * from './transports' +export * from './types' +export * from './provider' +export * from './utils' +export * from './client' +export * from './signer' +export * from './init' diff --git a/packages/provider/src/init.ts b/packages/provider/src/init.ts new file mode 100644 index 0000000000..371acae3fd --- /dev/null +++ b/packages/provider/src/init.ts @@ -0,0 +1,170 @@ +import { + CachedProvider, + ChainIdLike, + JsonRpcRouter, + JsonRpcSender, + NetworkConfig, + allNetworks, + exceptionProviderMiddleware, + findNetworkConfig, + loggingProviderMiddleware +} from '@0xsequence/network' +import { MuxTransportTemplate } from './transports' +import { ItemStore, useBestStore } from './utils' +import { ethers } from 'ethers' +import { SequenceClient } from './client' +import { SequenceProvider } from './provider' + +export interface ProviderConfig { + // The local storage dependency for the wallet provider, defaults to window.localStorage. + // For example, this option should be used when using React Native since window.localStorage is not available. + localStorage?: ItemStore + + // defaultNetwork is the primary network of a dapp and the default network a + // provider will communicate. Note: this setting is also configurable from the + // Wallet constructor's first argument. If both are specified, then they + // need to match + defaultNetwork?: ChainIdLike + + // defaultEIP6492 defines if EIP-6492 is enabled by default when signing messages. + defaultEIP6492?: boolean + + // networks is a configuration list of networks used by the wallet. This list + // is combined with the network list specified by sequence.js. + // notice that this can only replace the rpc urls on the dapp side, + // the networks on wallet-webapp side remain the same. + // + // NOTICE: It's not possible to define networks that aren't already + // defined in sequence.js. + networks?: Partial[] + + // transports for dapp to wallet jron-rpc communication + transports?: MuxTransportTemplate + + // analytics .... (default: true) + analytics?: boolean +} + +export const DefaultProviderConfig = { + transports: { + walletAppURL: 'https://sequence.app', + windowTransport: { enabled: true }, + proxyTransport: { enabled: false } + }, + + defaultNetwork: 1, + analytics: true +} + +let sequenceWalletProvider: SequenceProvider | undefined + +/** + * Initializes a wallet with the provided project access key and optional configuration. + * + * @param projectAccessKey - Access key for the project that can be obtained from Sequence Builder on sequence.build + * @param partialConfig - Optional partial configuration for the wallet. + * @returns The initialized wallet provider. + * @throws Error if projectAccessKey is not provided, empty string or is not string. + */ +export const initWallet = (projectAccessKey: string, partialConfig?: Partial) => { + if (!projectAccessKey || typeof projectAccessKey !== 'string') { + throw new Error('Please pass a projectAccessKey in initWallet.') + } + + if (sequenceWalletProvider) { + return sequenceWalletProvider + } + + // Combine both the provided config and the default config + const config = { + ...DefaultProviderConfig, + ...partialConfig, + transports: { + ...DefaultProviderConfig.transports, + ...partialConfig?.transports + } + } + + const rpcProviders: Record = {} + + // Find any new networks that aren't already defined in sequence.js + // and add them to the list of networks, (they must have a rpcUrl and chainId) + const newNetworks = (config.networks?.filter(n => { + n.rpcUrl !== undefined && n.chainId !== undefined && !allNetworks.find(an => an.chainId === n.chainId) + }) ?? []) as NetworkConfig[] + + // Override any information about the networks using the config + const combinedNetworks = allNetworks + .map(n => { + const network = config.networks?.find(cn => cn.chainId === n.chainId) + return network ? { ...n, ...network } : n + }) + .concat(newNetworks) + .map(network => { + // don't double-append in the case the user has already included their access key in the rpc URL + if (network.rpcUrl.includes(projectAccessKey)) { + return network + } + + // this will probably break non-sequence RPC provider URLs. + network.rpcUrl = network.rpcUrl + `/${projectAccessKey}` + return network + }) + + // This builds a "public rpc" on demand, we build them on demand because we don't want to + // generate a bunch of providers for networks that aren't used. + const providerForChainId = (chainId: number) => { + if (!rpcProviders[chainId]) { + const rpcUrl = combinedNetworks.find(n => n.chainId === chainId)?.rpcUrl + if (!rpcUrl) { + throw new Error(`no rpcUrl found for chainId: ${chainId}`) + } + + const baseProvider = new ethers.providers.JsonRpcProvider(rpcUrl) + const router = new JsonRpcRouter( + [loggingProviderMiddleware, exceptionProviderMiddleware, new CachedProvider()], + new JsonRpcSender(baseProvider) + ) + + rpcProviders[chainId] = new ethers.providers.Web3Provider(router, chainId) + } + + return rpcProviders[chainId] + } + + // This is the starting default network (as defined by the config) + // it can be later be changed using `wallet_switchEthereumChain` or some + // of the other methods on the provider. + const defaultNetwork = config.defaultNetwork ? findNetworkConfig(combinedNetworks, config.defaultNetwork)?.chainId : undefined + if (!defaultNetwork && config.defaultNetwork) { + throw new Error(`defaultNetwork not found for chainId: ${config.defaultNetwork}`) + } + + // Generate ItemStore + const itemStore = config.localStorage || useBestStore() + + // Create client, provider and return signer + const client = new SequenceClient(config.transports, itemStore, { + defaultChainId: defaultNetwork, + defaultEIP6492: config.defaultEIP6492, + projectAccessKey: projectAccessKey, + analytics: config.analytics + }) + + sequenceWalletProvider = new SequenceProvider(client, providerForChainId) + return sequenceWalletProvider +} + +export const unregisterWallet = () => { + if (!sequenceWalletProvider) return + sequenceWalletProvider.client.closeWallet() + sequenceWalletProvider.client.transport.unregister() + sequenceWalletProvider = undefined +} + +export const getWallet = () => { + if (!sequenceWalletProvider) { + throw new Error('Wallet has not been initialized, call sequence.initWallet(config) first.') + } + return sequenceWalletProvider +} diff --git a/packages/provider/src/provider.ts b/packages/provider/src/provider.ts new file mode 100644 index 0000000000..0ebeb1bd61 --- /dev/null +++ b/packages/provider/src/provider.ts @@ -0,0 +1,524 @@ +import { ethers } from 'ethers' +import { SequenceClient } from './client' +import { ChainIdLike, NetworkConfig, allNetworks, findNetworkConfig } from '@0xsequence/network' +import { ConnectDetails, ConnectOptions, EIP1193Provider, OpenWalletIntent, OptionalChainIdLike, WalletSession } from './types' +import { commons } from '@0xsequence/core' +import { WalletUtils } from './utils/index' +import { SequenceSigner, SingleNetworkSequenceSigner } from './signer' + +export interface ISequenceProvider { + readonly _isSequenceProvider: true + + connect(options?: ConnectOptions): Promise + disconnect(): void + + isConnected(): boolean + getSession(): WalletSession | undefined + + listAccounts(): string[] + + // @deprecated use getSigner().getAddress() instead + getAddress(): string + + getNetworks(): Promise + getChainId(): number + + setDefaultChainId(chainId: ChainIdLike): void + + isOpened(): boolean + openWallet(path?: string, intent?: OpenWalletIntent): Promise + closeWallet(): void + + getProvider(): SequenceProvider + getProvider(chainId: ChainIdLike): SingleNetworkSequenceProvider + getProvider(chainId?: ChainIdLike): SequenceProvider | SingleNetworkSequenceProvider + + getSigner(): SequenceSigner + getSigner(chainId: ChainIdLike): SingleNetworkSequenceSigner + getSigner(chainId?: ChainIdLike): SequenceSigner | SingleNetworkSequenceSigner + + // @deprecated use getSigner().getWalletContext() instead + getWalletContext(): Promise + + // @deprecated use getSigner().getWalletConfig() instead + getWalletConfig(chainId?: ChainIdLike): Promise + + utils: WalletUtils +} + +export class SequenceProvider extends ethers.providers.BaseProvider implements ISequenceProvider, EIP1193Provider { + private readonly singleNetworkProviders: { [chainId: number]: SingleNetworkSequenceProvider } = {} + + readonly _isSequenceProvider = true + readonly utils: WalletUtils + + readonly signer: SequenceSigner + + constructor( + public readonly client: SequenceClient, + private readonly providerFor: (networkId: number) => ethers.providers.JsonRpcProvider, + public readonly networks: NetworkConfig[] = allNetworks + ) { + // We support a lot of networks + // but we start with the default one + super(client.getChainId()) + + // Emit events as defined by EIP-1193 + client.onConnect(details => { + this.emit('connect', details) + }) + + client.onDisconnect(error => { + this.emit('disconnect', error) + }) + + client.onDefaultChainIdChanged(chainId => { + this.emit('chainChanged', chainId) + }) + + client.onAccountsChanged(accounts => { + this.emit('accountsChanged', accounts) + }) + + // NOTICE: We don't emit 'open' and 'close' events + // because these are handled by the library, and they + // are not part of EIP-1193 + + // devs can still access them using + // client.onOpen() + // client.onClose() + + // Create a Sequence signer too + this.signer = new SequenceSigner(this.client, this) + + // Create a utils instance + this.utils = new WalletUtils(this.signer) + } + + getSigner(): SequenceSigner + getSigner(chainId: ChainIdLike): SingleNetworkSequenceSigner + getSigner(chainId?: ChainIdLike): SequenceSigner | SingleNetworkSequenceSigner + + getSigner(chainId?: ChainIdLike) { + return this.signer.getSigner(chainId) + } + + connect(options: ConnectOptions) { + return this.client.connect(options) + } + + disconnect() { + return this.client.disconnect() + } + + isConnected() { + return this.client.isConnected() + } + + getSession() { + return this.client.getSession() + } + + listAccounts(): string[] { + return [this.client.getAddress()] + } + + // @deprecated use getSigner() instead + getAddress() { + return this.client.getAddress() + } + + getNetworks(): Promise { + return this.client.getNetworks() + } + + getChainId(): number { + return this.client.getChainId() + } + + setDefaultChainId(chainId: ChainIdLike) { + return this.client.setDefaultChainId(this.toChainId(chainId)) + } + + isOpened(): boolean { + return this.client.isOpened() + } + + closeWallet(): void { + return this.client.closeWallet() + } + + getWalletContext(): Promise { + return this.client.getWalletContext() + } + + // @deprecated use getSigner() instead + async getWalletConfig(chainId?: ChainIdLike): Promise { + const useChainId = await this.useChainId(chainId) + return this.client.getOnchainWalletConfig({ chainId: useChainId }) + } + + authorize(options: ConnectOptions) { + // Just an alias for connect with authorize: true + return this.client.connect({ ...options, authorize: true }) + } + + async openWallet(path?: string, intent?: OpenWalletIntent) { + await this.client.openWallet(path, intent) + return true + } + + toChainId(chainId: ChainIdLike): number + toChainId(chainId?: ChainIdLike): number | undefined + + toChainId(chainId?: ChainIdLike) { + if (chainId === undefined) { + return undefined + } + + const resolved = findNetworkConfig(this.networks, chainId as ChainIdLike) + + if (!resolved) { + throw new Error(`Unsupported network ${chainId}`) + } + + return resolved.chainId + } + + /** + * Resolves the chainId to use for the given request. If no chainId is provided, + * it uses the chainId defined by the client (default chainId). This can be + * overriden to build a single-network SequenceProvider. + */ + protected async useChainId(chainId?: ChainIdLike): Promise { + return this.toChainId(chainId) || this.client.getChainId() + } + + /** + * This generates a provider that ONLY works for the given chainId. + * the generated provider can't switch networks, and can't handle requests + * for other networks. + */ + getProvider(): SequenceProvider + getProvider(chainId: ChainIdLike): SingleNetworkSequenceProvider + getProvider(chainId?: ChainIdLike): SequenceProvider | SingleNetworkSequenceProvider + + getProvider(chainId?: ChainIdLike) { + // The provider without a chainId is... this one + if (!chainId) { + return this + } + + const useChainId = this.toChainId(chainId) + + if (!this.singleNetworkProviders[useChainId]) { + this.singleNetworkProviders[useChainId] = new SingleNetworkSequenceProvider(this.client, this.providerFor, useChainId) + } + + return this.singleNetworkProviders[useChainId] + } + + /** + * This returns a subprovider, this is a regular non-sequence provider that + * can be used to fulfill read only requests on a given network. + */ + async _getSubprovider(chainId?: ChainIdLike): Promise { + const useChainId = await this.useChainId(chainId) + + // Whoever implements providerFrom should memoize the generated provider + // otherwise every instance of SequenceProvider will create a new subprovider + const provider = this.providerFor(useChainId) + + if (!provider) { + throw new Error(`Unsupported network ${useChainId}`) + } + + return provider + } + + async perform(method: string, params: any): Promise { + // First we check if the method should be handled by the client + if (method === 'eth_chainId') { + return ethers.utils.hexValue(await this.useChainId()) + } + + if (method === 'eth_accounts') { + return [this.client.getAddress()] + } + + if (method === 'wallet_switchEthereumChain') { + const args = params[0] as { chainId: string } | number | string + const chainId = normalizeChainId(args) + return this.setDefaultChainId(chainId) + } + + // Usually these methods aren't used by calling the provider + // but to maximize compatibility we support them too. + // The correct way of accessing these methods is by using .getSigner() + if ( + method === 'eth_sendTransaction' || + method === 'eth_sign' || + method === 'eth_signTypedData' || + method === 'eth_signTypedData_v4' || + method === 'personal_sign' || + // These methods will use EIP-6492 + // but this is handled directly by the wallet + method === 'sequence_sign' || + method === 'sequence_signTypedData_v4' + ) { + // We pass the chainId to the client, if we don't pass one + // the client will use its own default chainId + return this.client.send({ method, params }, this.getChainId()) + } + + // Forward call to the corresponding provider + // we use the provided chainId, or the default one provided by the client + const provider = await this._getSubprovider() + const prepared = provider.prepareRequest(method, params) ?? [method, params] + return provider.send(prepared[0], prepared[1]) + } + + send(method: string, params: any): Promise { + return this.perform(method, params) + } + + request(request: { method: string; params?: any[] | undefined }) { + return this.perform(request.method, request.params) + } + + async detectNetwork(): Promise { + const chainId = this.client.getChainId() + const network = findNetworkConfig(this.networks, chainId) + + if (!network) { + throw new Error(`Unknown network ${chainId}`) + } + + return network + } + + // Override most of the methods, so we add support for an optional chainId + // argument, which is used to select the provider to use. + // + // NOTICE: We could use generics to avoid repeating the same code + // but this would make the code harder to read, and it's not worth it + // since we only have a few methods to override. + + async waitForTransaction(transactionHash: string, confirmations?: number, timeout?: number, optionals?: OptionalChainIdLike) { + const provider = await this._getSubprovider(optionals?.chainId) + return provider.waitForTransaction(transactionHash, confirmations, timeout) + } + + async getBlockNumber(optionals?: OptionalChainIdLike) { + const provider = await this._getSubprovider(optionals?.chainId) + return provider.getBlockNumber() + } + + async getGasPrice(optionals?: OptionalChainIdLike) { + const provider = await this._getSubprovider(optionals?.chainId) + return provider.getGasPrice() + } + + async getBalance( + addressOrName: string | Promise, + blockTag?: ethers.providers.BlockTag | Promise, + optionals?: OptionalChainIdLike + ) { + const provider = await this._getSubprovider(optionals?.chainId) + return provider.getBalance(addressOrName, blockTag) + } + + async getTransactionCount( + addressOrName: string | Promise, + blockTag?: ethers.providers.BlockTag | Promise, + optionals?: OptionalChainIdLike + ) { + const provider = await this._getSubprovider(optionals?.chainId) + return provider.getTransactionCount(addressOrName, blockTag) + } + + async getCode( + addressOrName: string | Promise, + blockTag?: ethers.providers.BlockTag | Promise, + optionals?: OptionalChainIdLike + ) { + const provider = await this._getSubprovider(optionals?.chainId) + return provider.getCode(addressOrName, blockTag) + } + + async getStorageAt( + addressOrName: string | Promise, + position: ethers.BigNumberish | Promise, + blockTag?: ethers.providers.BlockTag | Promise, + optionals?: OptionalChainIdLike + ) { + const provider = await this._getSubprovider(optionals?.chainId) + return provider.getStorageAt(addressOrName, position, blockTag) + } + + async call( + transaction: ethers.utils.Deferrable, + blockTag?: ethers.providers.BlockTag | Promise, + optionals?: OptionalChainIdLike + ) { + const provider = await this._getSubprovider(optionals?.chainId) + return provider.call(transaction, blockTag) + } + + async estimateGas(transaction: ethers.utils.Deferrable, optionals?: OptionalChainIdLike) { + const provider = await this._getSubprovider(optionals?.chainId) + return provider.estimateGas(transaction) + } + + async getBlock( + blockHashOrBlockTag: ethers.providers.BlockTag | string | Promise, + optionals?: OptionalChainIdLike + ) { + const provider = await this._getSubprovider(optionals?.chainId) + return provider.getBlock(blockHashOrBlockTag) + } + + async getTransaction(transactionHash: string | Promise, optionals?: OptionalChainIdLike) { + const provider = await this._getSubprovider(optionals?.chainId) + return provider.getTransaction(transactionHash) + } + + async getLogs(filter: ethers.providers.Filter | Promise, optionals?: OptionalChainIdLike) { + const provider = await this._getSubprovider(optionals?.chainId) + return provider.getLogs(filter) + } + + // ENS methods + + async supportsENS(): Promise { + const networks = await this.getNetworks() + return networks.some(n => n.chainId === 1) + } + + async getResolver(name: string) { + if (!(await this.supportsENS())) { + return null + } + + // Resolver is always on the chainId 1 + const provider = await this._getSubprovider(1) + return provider.getResolver(name) + } + + async resolveName(name: string | Promise) { + if (ethers.utils.isAddress(await name)) { + return name + } + + if (!(await this.supportsENS())) { + return null + } + + // Resolver is always on the chainId 1 + const provider = await this._getSubprovider(1) + return provider.resolveName(name) + } + + async lookupAddress(address: string | Promise) { + if (!(await this.supportsENS())) { + return null + } + + // Resolver is always on the chainId 1 + const provider = await this._getSubprovider(1) + return provider.lookupAddress(address) + } + + async getAvatar(nameOrAddress: string) { + if (!(await this.supportsENS())) { + return null + } + + const provider = await this._getSubprovider(1) + return provider.getAvatar(nameOrAddress) + } + + static is = (provider: any): provider is SequenceProvider => { + return provider && typeof provider === 'object' && provider._isSequenceProvider === true + } +} + +function normalizeChainId(chainId: string | number | bigint | { chainId: string }): number { + if (typeof chainId === 'object') return normalizeChainId(chainId.chainId) + return ethers.BigNumber.from(chainId).toNumber() +} + +/** + * This is the same provider, but it only allows a single network at a time. + * the network defined by the constructor is the only one that can be used. + * + * Attempting to call any method with a different network will throw an error. + * Attempting to change the network of this provider will throw an error. + * + * NOTICE: These networks won't support ENS unless they are the mainnet. + */ +export class SingleNetworkSequenceProvider extends SequenceProvider { + readonly _isSingleNetworkSequenceProvider = true + + constructor( + client: SequenceClient, + providerFor: (networkId: number) => ethers.providers.JsonRpcProvider, + public readonly chainId: ChainIdLike + ) { + super(client, providerFor) + } + + private _useChainId(chainId?: ChainIdLike): number { + const provided = this.toChainId(chainId) + + if (provided && provided !== this.chainId) { + throw new Error(`This provider only supports the network ${this.chainId}, but ${provided} was requested.`) + } + + return provided || super.toChainId(this.chainId) + } + + protected useChainId(chainId?: ChainIdLike): Promise { + return Promise.resolve(this._useChainId(chainId)) + } + + getChainId(): number { + return super.toChainId(this.chainId) + } + + async getNetwork(): Promise { + const networks = await this.client.getNetworks() + const res = findNetworkConfig(networks, this.chainId) + + if (!res) { + throw new Error(`Unsupported network ${this.chainId}`) + } + + return res + } + + /** + * Override getProvider and getSigner so they always use `useChainId` + * this way they can't return providers and signers that can switch networks, + * or that don't match the chainId of this signer. + */ + getProvider(chainId?: ChainIdLike): SingleNetworkSequenceProvider { + if (this._useChainId(chainId) !== this.chainId) { + throw new Error(`Unreachable code`) + } + + return this + } + + getSigner(chainId?: ChainIdLike): SingleNetworkSequenceSigner { + return super.getSigner(this._useChainId(chainId)) + } + + setDefaultChainId(_chainId: ChainIdLike): void { + throw new Error(`This provider only supports the network ${this.chainId}; use the parent provider to switch networks.`) + } + + static is(cand: any): cand is SingleNetworkSequenceProvider { + return cand && typeof cand === 'object' && cand._isSingleNetworkSequenceProvider === true + } +} diff --git a/packages/provider/src/signer.ts b/packages/provider/src/signer.ts new file mode 100644 index 0000000000..5e15dbb0c4 --- /dev/null +++ b/packages/provider/src/signer.ts @@ -0,0 +1,300 @@ +import { ethers } from 'ethers' + +import { SequenceProvider, SingleNetworkSequenceProvider } from './provider' +import { SequenceClient } from './client' +import { commons } from '@0xsequence/core' +import { ChainIdLike, NetworkConfig } from '@0xsequence/network' +import { resolveArrayProperties } from './utils' +import { WalletUtils } from './utils/index' +import { OptionalChainIdLike, OptionalEIP6492 } from './types' + +export interface ISequenceSigner extends ethers.Signer { + getProvider(): SequenceProvider + getProvider(chainId: ChainIdLike): SingleNetworkSequenceProvider + getProvider(chainId?: ChainIdLike): SequenceProvider | SingleNetworkSequenceProvider + + getSigner(): SequenceSigner + getSigner(chainId: ChainIdLike): SingleNetworkSequenceSigner + getSigner(chainId?: ChainIdLike): SequenceSigner | SingleNetworkSequenceSigner + + getWalletConfig(chainId?: ChainIdLike): Promise + getNetworks(): Promise + + signMessage(message: ethers.BytesLike, options?: OptionalChainIdLike & OptionalEIP6492): Promise + + signTypedData( + domain: ethers.TypedDataDomain, + types: Record>, + message: Record, + options?: OptionalChainIdLike & OptionalEIP6492 + ): Promise + + // sendTransaction takes an unsigned transaction, or list of unsigned transactions, and then has it signed by + // the signer, and finally sends it to the relayer for submission to an Ethereum network. + // It supports any kind of transaction, including regular ethers transactions, and Sequence transactions. + sendTransaction( + transaction: + | ethers.utils.Deferrable[] + | ethers.utils.Deferrable, + options?: OptionalChainIdLike + ): Promise + + utils: WalletUtils +} + +export class SequenceSigner implements ISequenceSigner { + private readonly singleNetworkSigners: { [chainId: number]: SingleNetworkSequenceSigner } = {} + + readonly _isSigner: boolean = true + readonly _isSequenceSigner: boolean = true + + get utils(): WalletUtils { + return this.provider.utils + } + + constructor( + public client: SequenceClient, + public provider: SequenceProvider + ) {} + + async getAddress(): Promise { + return this.client.getAddress() + } + + // This method shouldn't be used directly + // it exists to maintain compatibility with ethers.Signer + connect(provider: ethers.providers.Provider): SequenceSigner { + if (!SequenceProvider.is(provider)) { + throw new Error('SequenceSigner can only be connected to a SequenceProvider') + } + + return new SequenceSigner(this.client, provider) + } + + getSigner(): SequenceSigner + getSigner(chainId: ChainIdLike): SingleNetworkSequenceSigner + getSigner(chainId?: ChainIdLike): SingleNetworkSequenceSigner | SequenceSigner + + getSigner(chainId?: ChainIdLike): SingleNetworkSequenceSigner | SequenceSigner { + // The signer for the default network is this signer + if (!chainId) { + return this + } + + const useChainId = this.provider.toChainId(chainId) + + if (!this.singleNetworkSigners[useChainId]) { + this.singleNetworkSigners[useChainId] = new SingleNetworkSequenceSigner(this.client, this.provider, useChainId) + } + + return this.singleNetworkSigners[useChainId] + } + + /** + * Resolves the chainId to use for the given request. If no chainId is provided, + * it uses the chainId defined by the client (default chainId). This can be + * overriden to build a single-network SequenceProvider. + */ + protected useChainId(chainId?: ChainIdLike): number { + return this.provider.toChainId(chainId) || this.client.getChainId() + } + + async signMessage(message: ethers.BytesLike, options?: OptionalChainIdLike & OptionalEIP6492): Promise { + const { eip6492 = true } = options || {} + const chainId = this.useChainId(options?.chainId) + return this.client.signMessage(message, { eip6492, chainId }) + } + + async signTypedData( + domain: ethers.TypedDataDomain, + types: Record>, + message: Record, + options?: OptionalChainIdLike & OptionalEIP6492 + ): Promise { + const { eip6492 = true } = options || {} + const chainId = this.useChainId(options?.chainId) + return this.client.signTypedData({ domain, types, message }, { eip6492, chainId }) + } + + getProvider(): SequenceProvider + getProvider(chainId: ChainIdLike): SingleNetworkSequenceProvider + getProvider(chainId?: ChainIdLike): SingleNetworkSequenceProvider | SequenceProvider + + getProvider(chainId?: ChainIdLike): SingleNetworkSequenceProvider | SequenceProvider { + return this.provider.getProvider(chainId) + } + + async sendTransaction( + transaction: + | ethers.utils.Deferrable[] + | ethers.utils.Deferrable, + options?: OptionalChainIdLike + ) { + const chainId = this.useChainId(options?.chainId) + const resolved = await resolveArrayProperties(transaction) + const txHash = await this.client.sendTransaction(resolved, { chainId }) + const provider = this.getProvider(chainId) + + try { + return (await ethers.utils.poll( + async () => { + const tx = await provider.getTransaction(txHash) + return tx ? provider._wrapTransaction(tx, txHash) : undefined + }, + { onceBlock: provider } + )) as ethers.providers.TransactionResponse + } catch (err) { + err.transactionHash = txHash + throw err + } + } + + async getWalletConfig(chainId?: ChainIdLike | undefined): Promise { + const useChainId = this.useChainId(chainId) + return this.client.getOnchainWalletConfig({ chainId: useChainId }) + } + + getNetworks(): Promise { + return this.client.getNetworks() + } + + async getBalance(blockTag?: ethers.providers.BlockTag | undefined, optionals?: OptionalChainIdLike): Promise { + const provider = this.getProvider(optionals?.chainId) + return provider.getBalance(this.getAddress(), blockTag) + } + + async estimateGas( + transaction: ethers.utils.Deferrable, + optionals?: OptionalChainIdLike + ): Promise { + return this.getProvider(optionals?.chainId).estimateGas(transaction) + } + + async call( + transaction: ethers.utils.Deferrable, + blockTag?: ethers.providers.BlockTag | undefined, + optionals?: OptionalChainIdLike + ): Promise { + return this.getProvider(optionals?.chainId).call(transaction, blockTag) + } + + getChainId(): Promise { + return Promise.resolve(this.client.getChainId()) + } + + async getGasPrice(optionals?: OptionalChainIdLike): Promise { + return this.getProvider(optionals?.chainId).getGasPrice() + } + + async getFeeData(optionals?: OptionalChainIdLike): Promise { + return this.getProvider(optionals?.chainId).getFeeData() + } + + async resolveName(name: string): Promise { + const res = await this.provider.resolveName(name) + + // For some reason ethers.Signer expects this to return `string` + // but ethers.providers.Provider expects this to return `string | null`. + // The signer doesn't have any other source of information, so we'll + // fail if the provider doesn't return a result. + if (res === null) { + throw new Error(`ENS name not found: ${name}`) + } + + return res + } + + _checkProvider(_operation?: string | undefined): void { + // We always have a provider, so this is a noop + } + + populateTransaction( + _transaction: ethers.utils.Deferrable + ): Promise { + throw new Error('SequenceSigner does not support populateTransaction') + } + + checkTransaction( + _transaction: ethers.utils.Deferrable + ): ethers.utils.Deferrable { + throw new Error('SequenceSigner does not support checkTransaction') + } + + getTransactionCount(_blockTag?: ethers.providers.BlockTag | undefined): Promise { + // We could try returning the sequence nonce here + // but we aren't sure how ethers will use this nonce + throw new Error('SequenceSigner does not support getTransactionCount') + } + + signTransaction(_transaction: ethers.utils.Deferrable): Promise { + // We could implement signTransaction/sendTransaction here + // but first we need a way of serializing these signed transactions + // and it could lead to more trouble, because the dapp could try to send this transaction + // using a different provider, which would fail. + throw new Error('SequenceWallet does not support signTransaction, use sendTransaction instead.') + } + + static is(cand: any): cand is SequenceSigner { + return cand && typeof cand === 'object' && cand._isSequenceSigner === true + } +} + +/** + * This is the same provider, but it only allows a single network at a time. + * the network defined by the constructor is the only one that can be used. + * + * Attempting to call any method with a different network will throw an error. + * Attempting to change the network of this provider will throw an error. + * + * NOTICE: These networks won't support ENS unless they are the mainnet. + */ +export class SingleNetworkSequenceSigner extends SequenceSigner { + readonly _isSingleNetworkSequenceSigner = true + + constructor( + client: SequenceClient, + provider: SequenceProvider, + public readonly chainId: ChainIdLike + ) { + super(client, provider.getProvider(chainId)) + } + + private _useChainId(chainId?: ChainIdLike): number { + const provided = this.provider.toChainId(chainId) + + if (provided && provided !== this.chainId) { + throw new Error(`This signer only supports the network ${this.chainId}, but ${provided} was requested.`) + } + + return provided || this.provider.toChainId(this.chainId) + } + + protected useChainId(chainId?: ChainIdLike): number { + return this._useChainId(chainId) + } + + getChainId(): Promise { + return Promise.resolve(this.provider.toChainId(this.chainId)) + } + + /** + * Override getProvider and getSigner so they always use `useChainId` + * this way they can't return providers and signers that can switch networks, + * or that don't match the chainId of this signer. + */ + getProvider(chainId?: ChainIdLike): SingleNetworkSequenceProvider { + return super.getProvider(this._useChainId(chainId)) + } + + getSigner(chainId?: ChainIdLike | undefined): SingleNetworkSequenceSigner { + if (this._useChainId(chainId) !== this.chainId) { + throw new Error(`Unreachable code`) + } + + return this + } + + static is(cand: any): cand is SingleNetworkSequenceSigner { + return cand && typeof cand === 'object' && cand._isSingleNetworkSequenceSigner === true + } +} diff --git a/packages/provider/src/transactions.ts b/packages/provider/src/transactions.ts new file mode 100644 index 0000000000..3b95b9017e --- /dev/null +++ b/packages/provider/src/transactions.ts @@ -0,0 +1,57 @@ +import { walletContracts } from '@0xsequence/abi' +import { commons } from '@0xsequence/core' +import { ethers } from 'ethers' + +const PROHIBITED_FUNCTIONS = new Map( + [ + 'addHook(bytes4,address)', + 'clearExtraImageHashes(bytes32[])', + 'removeHook(bytes4)', + 'setExtraImageHash(bytes32,uint256)', + 'updateIPFSRoot(bytes32)', + 'updateImageHash(bytes32)', + 'updateImageHashAndIPFS(bytes32,bytes32)', + 'updateImplementation(address)' + ].map(signature => [ethers.utils.keccak256(ethers.utils.toUtf8Bytes(signature)).slice(0, 10), signature]) +) + +export function validateTransactionRequest(wallet: string, transaction: commons.transaction.Transactionish) { + const transactions = commons.transaction.fromTransactionish(wallet, transaction) + const unwound = commons.transaction.unwind(wallet, transactions) + unwound.forEach(transaction => validateTransaction(wallet, transaction)) +} + +function validateTransaction(wallet: string, transaction: commons.transaction.Transaction) { + if (transaction.to.toLowerCase() === wallet.toLowerCase()) { + if (transaction.data) { + const data = ethers.utils.arrayify(transaction.data) + if (data.length >= 4 && !isCreateContractCall(data)) { + throw new Error('self calls are forbidden') + } + } + } + + if (transaction.delegateCall) { + throw new Error('delegate calls are forbidden') + } + + if (transaction.data) { + const data = ethers.utils.hexlify(transaction.data) + const selector = data.slice(0, 10) + const signature = PROHIBITED_FUNCTIONS.get(selector) + if (signature) { + const name = signature.slice(0, signature.indexOf('(')) + throw new Error(`${name} calls are forbidden`) + } + } +} + +function isCreateContractCall(data: ethers.BytesLike): boolean { + const walletInterface = new ethers.utils.Interface(walletContracts.mainModule.abi) + try { + walletInterface.decodeFunctionData('createContract', data) + return true + } catch { + return false + } +} diff --git a/packages/provider/src/transports/base-provider-transport.ts b/packages/provider/src/transports/base-provider-transport.ts new file mode 100644 index 0000000000..0338395355 --- /dev/null +++ b/packages/provider/src/transports/base-provider-transport.ts @@ -0,0 +1,415 @@ +import { EventEmitter2 as EventEmitter } from 'eventemitter2' + +import { + ProviderTransport, + ProviderMessage, + ProviderMessageRequest, + EventType, + ProviderEventTypes, + ProviderMessageResponse, + ProviderMessageResponseCallback, + OpenState, + OpenWalletIntent, + ConnectDetails, + WalletSession, + ProviderRpcError, + InitState, + TypedEventEmitter +} from '../types' + +import { NetworkConfig, JsonRpcRequest, JsonRpcResponseCallback } from '@0xsequence/network' +import { logger } from '@0xsequence/utils' +import { ethers } from 'ethers' +import { commons } from '@0xsequence/core' + +export const PROVIDER_OPEN_TIMEOUT = 30000 // in ms + +let _messageIdx = 0 + +export const nextMessageIdx = () => ++_messageIdx + +export abstract class BaseProviderTransport implements ProviderTransport { + protected pendingMessageRequests: ProviderMessageRequest[] = [] + protected responseCallbacks = new Map() + + protected state: OpenState + protected confirmationOnly: boolean = false + protected events: TypedEventEmitter = new EventEmitter() as TypedEventEmitter + + protected openPayload: { sessionId?: string; session?: WalletSession } | undefined + protected connectPayload: ConnectDetails | undefined + protected accountsChangedPayload: { accounts: string[]; origin?: string } | undefined + protected networksPayload: NetworkConfig[] | undefined + protected walletContextPayload: commons.context.VersionedContext | undefined + + protected _sessionId?: string + protected _init: InitState + protected _registered: boolean + + constructor() { + this.state = OpenState.CLOSED + this._registered = false + this._init = InitState.NIL + } + + get registered(): boolean { + return this._registered + } + + register() { + throw new Error('abstract method') + } + + unregister() { + throw new Error('abstract method') + } + + openWallet(path?: string, intent?: OpenWalletIntent, networkId?: string | number) { + throw new Error('abstract method') + } + + closeWallet() { + throw new Error('abstract method') + } + + isOpened(): boolean { + return this.registered && this.state === OpenState.OPENED + } + + isConnected(): boolean { + // if we're registered, and we have the account details, then we are connected + const session = this.openPayload?.session + return ( + this.registered && + session !== undefined && + !!session.accountAddress && + session.accountAddress.length === 42 && + !!session.networks && + session.networks.length > 0 + ) + } + + sendAsync = async (request: JsonRpcRequest, callback: JsonRpcResponseCallback, chainId?: number) => { + // here, we receive the message from the dapp provider call + + if (this.state === OpenState.CLOSED) { + // flag the wallet to auto-close once user submits input. ie. + // prompting to sign a message or transaction + this.confirmationOnly = true + } + + // open/focus the wallet. + // automatically open the wallet when a provider request makes it here. + // + // NOTE: if we're not signed in, then the provider will fail, users must first connect+sign in. + // + // TODO: how does this behave with a session has expired? + this.openWallet(undefined, { type: 'jsonRpcRequest', method: request.method }, chainId) + + // send message request, await, and then execute callback after receiving the response + try { + if (!this.isOpened()) { + await this.waitUntilOpened() // will throw on timeout + } + + const response = await this.sendMessageRequest({ + idx: nextMessageIdx(), + type: EventType.MESSAGE, + data: request, + chainId: chainId + }) + callback(undefined, response.data) + } catch (err) { + callback(err) + } + } + + // handleMessage will handle message received from the remote wallet + handleMessage(message: ProviderMessage) { + // init incoming for initial handshake with transport. + // always respond to INIT messages, e.g. on popup window reload + if (message.type === EventType.INIT) { + logger.debug('MessageProvider, received INIT message', message) + const { nonce } = message.data as { nonce: string } + if (!nonce || nonce.length == 0) { + logger.error('invalid init nonce') + return + } + this._init = InitState.OK + this.sendMessage({ + idx: -1, + type: EventType.INIT, + data: { + sessionId: this._sessionId, + nonce: nonce + } + }) + } + + if (this._init !== InitState.OK) { + // if provider is not init'd, then we drop any received messages. the only + // message we will process is of event type 'init', as our acknowledgement + return + } + + // message is either a notification, or its a ProviderMessageResponse + logger.debug('RECEIVED MESSAGE FROM WALLET', message.idx, message) + + const requestIdx = message.idx + const responseCallback = this.responseCallbacks.get(requestIdx) + if (requestIdx) { + this.responseCallbacks.delete(requestIdx) + } + + // OPEN response + // + // Flip opened flag, and flush the pending queue + if (message.type === EventType.OPEN && !this.isOpened()) { + if (this._sessionId && this._sessionId !== message.data?.sessionId) { + logger.debug('open event received from wallet, but does not match sessionId', this._sessionId) + return + } + + // check if open error occured due to invalid defaultNetworkId + if (message.data?.error) { + const err = new Error(`opening wallet failed: received ${message.data?.error}`) + logger.error(err) + this.close() + throw err + } + + // success! + this.state = OpenState.OPENED + this.openPayload = message.data + this.events.emit('open', this.openPayload!) + + // flush pending requests when connected + if (this.pendingMessageRequests.length !== 0) { + const pendingMessageRequests = this.pendingMessageRequests.splice(0, this.pendingMessageRequests.length) + + pendingMessageRequests.forEach(async pendingMessageRequest => { + this.sendMessage(pendingMessageRequest) + }) + } + + return + } + + // MESSAGE resposne + if (message.type === EventType.MESSAGE) { + // Require user confirmation, bring up wallet to prompt for input then close + // TODO: perhaps apply technique like in multicall to queue messages within + // a period of time, then close the window if responseCallbacks is empty, this is better. + if (this.confirmationOnly) { + setTimeout(() => { + if (this.responseCallbacks.size === 0) { + this.closeWallet() + } + }, 500) // TODO: be smarter about timer as we're processing the response callbacks.. + } + + if (!responseCallback) { + // NOTE: this would occur if 'idx' isn't set, which should never happen + // or when we register two handler, or duplicate messages with the same idx are sent, + // all of which should be prevented prior to getting to this point + throw new Error('impossible state') + } + + // Callback to original caller + if (responseCallback) { + this.events.emit('message', message) + responseCallback((message as ProviderMessageResponse).data.error, message) + return + } + } + + // ACCOUNTS_CHANGED -- when a user logs in or out + if (message.type === EventType.ACCOUNTS_CHANGED) { + this.accountsChangedPayload = { accounts: [] } + if (message.data && message.data.length > 0) { + this.accountsChangedPayload = { + accounts: [ethers.utils.getAddress(message.data[0])], + origin: message.origin + } + this.events.emit('accountsChanged', this.accountsChangedPayload.accounts, this.accountsChangedPayload.origin) + } else { + this.events.emit('accountsChanged', [], message.origin) + } + return + } + + // CHAIN_CHANGED -- when a user changes their default chain + if (message.type === EventType.CHAIN_CHANGED) { + this.events.emit('chainChanged', message.data, message.origin) + return + } + + // NOTIFY NETWORKS -- when a user connects or logs in + if (message.type === EventType.NETWORKS) { + this.networksPayload = message.data + this.events.emit('networks', this.networksPayload!) + return + } + + // NOTIFY WALLET_CONTEXT -- when a user connects or logs in + if (message.type === EventType.WALLET_CONTEXT) { + this.walletContextPayload = message.data + this.events.emit('walletContext', this.walletContextPayload!) + return + } + + // NOTIFY CLOSE -- when wallet instructs to close + if (message.type === EventType.CLOSE) { + if (this.state !== OpenState.CLOSED) { + this.close(message.data) + } + } + + // NOTIFY CONNECT -- when wallet instructs we've connected + if (message.type === EventType.CONNECT) { + this.connectPayload = message.data + this.events.emit('connect', this.connectPayload!) + } + + // NOTIFY DISCONNECT -- when wallet instructs to disconnect + if (message.type === EventType.DISCONNECT) { + if (this.isConnected()) { + this.events.emit('disconnect', message.data, message.origin) + this.close() + } + } + } + + // sendMessageRequest sends a ProviderMessageRequest over the wire to the wallet + sendMessageRequest = async (message: ProviderMessageRequest): Promise => { + return new Promise((resolve, reject) => { + if ((!message.idx || message.idx <= 0) && message.type !== 'init') { + reject(new Error('message idx not set')) + } + + const responseCallback: ProviderMessageResponseCallback = (error: ProviderRpcError, response?: ProviderMessageResponse) => { + if (error) { + reject(error) + } else if (response) { + resolve(response) + } else { + throw new Error('no valid response to return') + } + } + + const idx = message.idx + if (!this.responseCallbacks.get(idx)) { + this.responseCallbacks.set(idx, responseCallback) + } else { + reject(new Error('duplicate message idx, should never happen')) + } + + if (!this.isOpened()) { + logger.debug('pushing to pending requests', message) + this.pendingMessageRequests.push(message) + } else { + this.sendMessage(message) + } + }) + } + + sendMessage(message: ProviderMessage) { + throw new Error('abstract method') + } + + on(event: K, fn: ProviderEventTypes[K]) { + this.events.on(event, fn as any) + } + + once(event: K, fn: ProviderEventTypes[K]) { + this.events.once(event, fn as any) + } + + emit(event: K, ...args: Parameters): boolean { + return this.events.emit(event, ...(args as any)) + } + + waitUntilOpened = async (openTimeout = PROVIDER_OPEN_TIMEOUT): Promise => { + let opened = false + return Promise.race([ + new Promise((_, reject) => { + const timeout = setTimeout(() => { + clearTimeout(timeout) + // only emit close if the timeout wins the race + if (!opened) { + this.state = OpenState.CLOSED + this.events.emit('close', { code: 1005, message: 'opening wallet timed out' } as ProviderRpcError) + } + reject(new Error('opening wallet timed out')) + }, openTimeout) + }), + new Promise(resolve => { + if (this.isOpened()) { + opened = true + resolve(this.openPayload?.session) + return + } + this.events.once('open', (openInfo: { session?: WalletSession }) => { + this.openPayload = openInfo + opened = true + resolve(openInfo.session) + }) + }) + ]) + } + + waitUntilConnected = async (): Promise => { + await this.waitUntilOpened() + + const connect = new Promise(resolve => { + if (this.connectPayload) { + resolve(this.connectPayload) + return + } + + this.events.once('connect', connectDetails => { + this.connectPayload = connectDetails + resolve(connectDetails) + }) + }) + + const closeWallet = new Promise((_, reject) => { + this.events.once('close', error => { + if (error) { + reject(new Error(`wallet closed due to ${JSON.stringify(error)}`)) + } else { + reject(new Error(`user closed the wallet`)) + } + }) + }) + + return Promise.race([connect, closeWallet]) + } + + protected close(error?: ProviderRpcError) { + if (this.state === OpenState.CLOSED) return + + this.state = OpenState.CLOSED + this.confirmationOnly = false + this._sessionId = undefined + logger.info('closing wallet and flushing!') + + // flush pending requests and return error to all callbacks + this.pendingMessageRequests.length = 0 + this.responseCallbacks.forEach(responseCallback => { + responseCallback({ + ...new Error('wallet closed'), + code: 4001 + }) + }) + this.responseCallbacks.clear() + + this.connectPayload = undefined + this.openPayload = undefined + this.accountsChangedPayload = undefined + this.networksPayload = undefined + this.walletContextPayload = undefined + + this.events.emit('close', error) + } +} diff --git a/packages/provider/src/transports/base-wallet-transport.ts b/packages/provider/src/transports/base-wallet-transport.ts new file mode 100644 index 0000000000..b3a15d46c0 --- /dev/null +++ b/packages/provider/src/transports/base-wallet-transport.ts @@ -0,0 +1,475 @@ +import { ethers } from 'ethers' +import { + WalletTransport, + ProviderMessage, + ProviderMessageRequest, + EventType, + ProviderMessageResponse, + ProviderRpcError, + InitState, + ConnectDetails, + WalletSession, + TransportSession +} from '../types' + +import { WalletRequestHandler } from './wallet-request-handler' + +import { NetworkConfig, JsonRpcRequest, JsonRpcResponseCallback, findSupportedNetwork } from '@0xsequence/network' +import { logger, sanitizeAlphanumeric, sanitizeHost, sanitizeNumberString } from '@0xsequence/utils' +import { AuthorizationOptions } from '@0xsequence/auth' + +import { PROVIDER_OPEN_TIMEOUT } from './base-provider-transport' +import { isBrowserExtension, useBestStore } from '../utils' +import { commons } from '@0xsequence/core' + +const TRANSPORT_SESSION_LS_KEY = '@sequence.transportSession' + +export abstract class BaseWalletTransport implements WalletTransport { + protected walletRequestHandler: WalletRequestHandler + protected _sessionId: string + protected _registered: boolean + + protected _init: InitState + protected _initNonce: string + protected _initCallback?: (error?: string) => void + + // appOrigin identifies the dapp's origin which opened the app. A transport + // will auto-detect and set this value if it can. This is determined + // as the parent app/window which opened the wallet. + protected appOrigin?: string + + constructor(walletRequestHandler: WalletRequestHandler) { + this.walletRequestHandler = walletRequestHandler + this._init = InitState.NIL + + this.walletRequestHandler.on('connect', (connectDetails: ConnectDetails) => { + if (!this.registered) return + // means user has logged in and wallet is connected to the app + this.notifyConnect(connectDetails) + }) + + this.walletRequestHandler.on('disconnect', (error?: ProviderRpcError, origin?: string) => { + if (!this.registered) return + // means user has logged out the app / disconnected wallet from the app + this.notifyDisconnect(error, origin) + }) + + this.walletRequestHandler.on('accountsChanged', (accounts: string[], origin?: string) => { + if (!this.registered) return + this.notifyAccountsChanged(accounts, origin) + }) + + this.walletRequestHandler.on('networks', (networks: NetworkConfig[]) => { + if (!this.registered) return + this.notifyNetworks(networks) + if (!networks || networks.length === 0) { + this.notifyChainChanged('0x0') + } else { + this.notifyChainChanged(ethers.utils.hexValue(networks.find(network => network.isDefaultChain)!.chainId)) + } + }) + + this.walletRequestHandler.on('chainChanged', (chainIdHex: string, origin?: string) => { + this.notifyChainChanged(chainIdHex, origin) + }) + + this.walletRequestHandler.on('walletContext', (walletContext: commons.context.VersionedContext) => { + if (!this.registered || !walletContext) return + this.notifyWalletContext(walletContext) + }) + + this.walletRequestHandler.on('close', (error?: ProviderRpcError) => { + if (!this.registered) return + this.notifyClose(error) + }) + } + + get registered(): boolean { + return this._registered + } + + register() { + throw new Error('abstract method') + } + + unregister() { + throw new Error('abstract method') + } + + sendAsync = async (request: JsonRpcRequest, callback: JsonRpcResponseCallback, chainId?: number) => { + throw new Error('abstract method') + } + + handleMessage = async (message: ProviderMessage) => { + const request = message + + // ensure initial handshake is complete before accepting + // other kinds of messages. + if (this._init !== InitState.OK) { + if (request.type === EventType.INIT) { + if (this.isValidInitAck(message)) { + // successful init + if (this._initCallback) this._initCallback() + } else { + // failed init + if (this._initCallback) this._initCallback('invalid init') + return + } + } else { + // we expect init message first. do nothing here. + } + return + } + + // ensure signer is ready to handle requests + // if (this.walletRequestHandler.getSigner() === undefined) { + // await this.walletRequestHandler.signerReady() + // } + + // handle request + switch (request.type) { + case EventType.OPEN: { + if (this._init !== InitState.OK) return + const session: TransportSession = { + sessionId: request.data.sessionId, + intent: request.data.intent, + networkId: request.data.networkId + } + await this.open(session) + return + } + + case EventType.CLOSE: { + if (this._init !== InitState.OK) return + // noop. just here to capture the message so event emitters may be notified + return + } + + case EventType.MESSAGE: { + const response = await this.walletRequestHandler.sendMessageRequest(request) + this.sendMessage(response) + + if (response.data.error) { + // TODO: for certain errors, whenever we want to render something to the UI + // we should throw + } + return + } + + default: { + logger.error(`unexpected payload type ${request.type}`) + } + } + } + + // sendMessageRequest sends a ProviderMessageRequest to the wallet post-message transport + sendMessageRequest = async (message: ProviderMessageRequest): Promise => { + return this.walletRequestHandler.sendMessageRequest(message) + } + + sendMessage(message: ProviderMessage) { + throw new Error('abstract method') + } + + notifyOpen(openInfo: { chainId?: string; sessionId?: string; session?: WalletSession; error?: string }) { + const { chainId, sessionId, session, error } = openInfo + this.sendMessage({ + idx: -1, + type: EventType.OPEN, + data: { + chainId, + sessionId, + session, + error + } + }) + } + + notifyClose(error?: ProviderRpcError) { + this.sendMessage({ + idx: -1, + type: EventType.CLOSE, + data: error ? { error } : null + }) + } + + notifyConnect(connectDetails: ConnectDetails) { + this.sendMessage({ + idx: -1, + type: EventType.CONNECT, + data: connectDetails + }) + } + + notifyDisconnect(error?: ProviderRpcError, origin?: string) { + this.sendMessage({ + idx: -1, + type: EventType.DISCONNECT, + data: error ? { error } : null, + origin + }) + } + + notifyAccountsChanged(accounts: string[], origin?: string) { + this.sendMessage({ + idx: -1, + type: EventType.ACCOUNTS_CHANGED, + data: accounts, + origin + }) + } + + notifyChainChanged(chainIdHex: string, origin?: string) { + this.sendMessage({ + idx: -1, + type: EventType.CHAIN_CHANGED, + data: chainIdHex, + origin + }) + } + + notifyNetworks(networks: NetworkConfig[]) { + this.sendMessage({ + idx: -1, + type: EventType.NETWORKS, + data: networks + }) + } + + notifyWalletContext(walletContext: commons.context.VersionedContext) { + this.sendMessage({ + idx: -1, + type: EventType.WALLET_CONTEXT, + data: walletContext + }) + } + + protected isValidInitAck(message: ProviderMessage): boolean { + if (this._init === InitState.OK) { + // we're already in init state, we shouldn't handle this message + logger.warn("isValidInitAck, already in init'd state, so inquiry is invalid.") + return false + } + if (message.type !== EventType.INIT) { + logger.warn('isValidInitAck, invalid message type, expecting init') + return false + } + + const { sessionId, nonce } = message.data as any as { sessionId: string; nonce: string } + if (!sessionId || sessionId.length === 0 || !nonce || nonce.length === 0) { + logger.error('invalid init ack') + return false + } + if (sessionId !== this._sessionId || nonce !== this._initNonce) { + logger.error('invalid init ack match') + return false + } + + // all checks pass, its true + return true + } + + private init(): Promise { + return new Promise((resolve, reject) => { + // avoid re-init`ing, or if there is a transport which doesn't require + // it, then it may set this._init to OK in its constructor. + if (this._init === InitState.OK) { + resolve() + return + } + if (this._init !== InitState.NIL || this._initCallback) { + reject('transport init is in progress') + return + } + + // start init timeout, if we don't receive confirmation + // from provider within this amount of time, then we timeout + const initTimeout = setTimeout(() => { + logger.warn('transport init timed out') + if (this._initCallback) { + this._initCallback('transport init timed out') + } + }, PROVIDER_OPEN_TIMEOUT / 2) + + // setup callback as we receive the init message async in the handleMessage function + this._initCallback = (error?: string) => { + this._initCallback = undefined // reset + clearTimeout(initTimeout) + if (error) { + reject(error) + } else { + this._init = InitState.OK + resolve() + } + } + + // send init request with random nonce to the provider, where we expect + // for the provider to echo it back to us as complete handshake + this._initNonce = `${performance.now()}` + this.sendMessage({ + idx: -1, + type: EventType.INIT, + data: { nonce: this._initNonce } + }) + this._init = InitState.SENT_NONCE + + // NOTE: the promise will resolve in the _initCallback method + // which will be called from either handleMessage or the initTimeout + }) + } + + protected open = async ({ sessionId, intent, networkId }: TransportSession): Promise => { + if (sessionId) { + this._sessionId = sanitizeNumberString(sessionId) + // persist transport session in localstorage for restoring after redirect/reload + this.saveTransportSession({ sessionId, intent, networkId }) + } + + this.walletRequestHandler.setOpenIntent(intent) + + // init handshake for certain transports, before we can open the communication. + // + // for example, with the window-transport, we have to exchange messages to determine the + // origin host of the dapp. + await this.init() + + // determine chainId from networkId (string or number) + let chainId: number | undefined = undefined + try { + if (networkId) { + const network = findSupportedNetwork(networkId) + if (network) { + chainId = network.chainId + } else { + throw new Error(`unknown network ${networkId}`) + } + } else { + // if not provided, use defaultChainId + chainId = this.walletRequestHandler.defaultChainId() + } + } catch (err) { + console.error(err) + } + + // Prepare connect options from intent + if (intent && intent.type === 'connect' && intent.options) { + const connectOptions = intent.options + const authorizeOptions: AuthorizationOptions = connectOptions // overlapping types + + // Sanity/integrity check the intent payload, and set authorization origin + // if its been determined as part of the init handshake from earlier. + if (this.appOrigin && authorizeOptions?.origin) { + if (!isBrowserExtension()) { + if (authorizeOptions.origin !== this.appOrigin) { + throw new Error('origin is invalid') + } else { + // request origin and derived origins match, lets carry on + } + } + } else if (!this.appOrigin && authorizeOptions?.origin) { + // ie. when we can't determine the origin in our transport, but dapp provides it to us. + // we just sanitize the origin host. + connectOptions.origin = sanitizeHost(authorizeOptions.origin) + } else if (this.appOrigin) { + // ie. when we auto-determine the origin such as in window-transport + connectOptions.origin = this.appOrigin + } + if (connectOptions.app) { + connectOptions.app = sanitizeAlphanumeric(connectOptions.app) + } + + if (connectOptions.networkId) { + networkId = connectOptions.networkId + } else if (networkId) { + connectOptions.networkId = networkId + } + + // Set connect options on the walletRequestHandler as our primary + // wallet controller, and fall back to networkId if necessary + this.walletRequestHandler.setConnectOptions(connectOptions) + } else { + this.walletRequestHandler.setConnectOptions(undefined) + } + + // ensure signer is ready + await this.walletRequestHandler.getAccount() + + // Notify open and proceed to prompt for connection if intended + if (!(await this.walletRequestHandler.isSignedIn())) { + // open wallet without a specific connected chainId, as the user is not signed in + this.notifyOpen({ + sessionId: this._sessionId + }) + return true + } else { + // prompt user with a connect request. the options will be used as previously set above. + // upon success, the walletRequestHandler will notify the dapp with the ConnectDetails. + // upon cancellation by user, the walletRequestHandler will throw an error + + if (intent && intent.type === 'connect') { + // Failed to set default network on open + // Fail silently here so we can continue with connect flow and ask + // user to connect on a different network if necessary + if (!chainId || chainId <= 0) { + console.log('Failed to set default network on open') + } + + // notify wallet is opened, without session details + this.notifyOpen({ + sessionId: this._sessionId + }) + + try { + const connectDetails = await this.walletRequestHandler.promptConnect(intent.options) + if (connectDetails.connected) { + this.walletRequestHandler.notifyConnect(connectDetails) + } + } catch (err) { + logger.warn('promptConnect not connected:', err) + } finally { + // auto-close by default, unless intent is to keep open + if (!intent.options || intent.options.keepWalletOpened !== true) { + this.notifyClose() + } + } + } else { + // Using default network + + // Failed to set default network on open -- quit + close + if (!chainId || chainId <= 0) { + this.notifyOpen({ + sessionId: this._sessionId, + error: `failed to open wallet on network ${networkId}` + }) + return false + } + + // user is already connected, notify session details. + // TODO: in future, keep list if 'connected' dapps / sessions in the session + // controller, and only sync with allowed apps + this.notifyOpen({ + sessionId: this._sessionId, + chainId: `${chainId}`, + session: await this.walletRequestHandler.walletSession(chainId) + }) + } + } + + return true + } + + private saveTransportSession = (session: TransportSession) => { + useBestStore().setItem(TRANSPORT_SESSION_LS_KEY, JSON.stringify(session)) + } + + protected getCachedTransportSession = async (): Promise => { + const session = useBestStore().getItem(TRANSPORT_SESSION_LS_KEY) + + try { + return session ? (JSON.parse(session) as TransportSession) : null + } catch (err) { + console.error(`unable to parse transport session: ${session}`) + return null + } + } +} diff --git a/packages/provider/src/transports/extension-transport/base-injected-transport.ts b/packages/provider/src/transports/extension-transport/base-injected-transport.ts new file mode 100644 index 0000000000..94d734dbb5 --- /dev/null +++ b/packages/provider/src/transports/extension-transport/base-injected-transport.ts @@ -0,0 +1,101 @@ +import { JsonRpcRequest, JsonRpcResponse } from '@0xsequence/network' +import { logger } from '@0xsequence/utils' +import { EventEmitter2 as EventEmitter } from 'eventemitter2' +import { + ProviderMessageResponseCallback, + ProviderMessage, + EventType, + ProviderMessageRequest, + ProviderMessageResponse +} from '../../types' + +export interface Stream { + on(ev: string | symbol, fn: (...args: any[]) => void): void + writable: boolean + write(chunk: any, cb?: (error: Error | null | undefined) => void): boolean +} + +// to be used on injected window.ethereum EIP1193 proxy +export abstract class BaseInjectedTransport extends EventEmitter { + protected responseCallbacks = new Map() + + private _messageIdx = 0 + protected nextMessageIdx = () => ++this._messageIdx + + constructor(private stream: Stream) { + super() + + this.stream.on('data', this.handleMessage) + } + + private handleMessage = (message: ProviderMessage) => { + if (!message.type || !message.data) { + return + } + + logger.info('[received message]', message) + + const requestIdx = message.idx + const responseCallback = this.responseCallbacks.get(requestIdx) + if (requestIdx) { + this.responseCallbacks.delete(requestIdx) + } + + switch (message.type) { + case EventType.MESSAGE: + if (responseCallback) { + this.emit(EventType.MESSAGE, message) + responseCallback(message.data.error, message) + } else { + // NOTE: this would occur if 'idx' isn't set, which should never happen + // or when we register two handler, or duplicate messages with the same idx are sent, + // all of which should be prevented prior to getting to this point + throw new Error('impossible state') + } + break + case EventType.DISCONNECT: + case EventType.ACCOUNTS_CHANGED: + case EventType.CHAIN_CHANGED: + this.emit(message.type, message.data) + break + default: + console.error('unknown message type', message) + break + } + } + + protected sendMessageRequest = async (message: ProviderMessageRequest): Promise => { + return new Promise((resolve, reject) => { + if (!message.idx || message.idx <= 0) { + reject(new Error('message idx not set')) + } + + const responseCallback: ProviderMessageResponseCallback = (error: any, response?: ProviderMessageResponse) => { + if (error) { + reject(error) + } else if (response) { + resolve(response) + } else { + throw new Error('no valid response to return') + } + } + + const { idx } = message + if (!this.responseCallbacks.get(idx)) { + this.responseCallbacks.set(idx, responseCallback) + } else { + reject(new Error('duplicate message idx, should never happen')) + } + + this.sendMessage(message) + }) + } + + private sendMessage(message: ProviderMessage) { + if (!this.stream.writable) { + console.error('window post message stream is not writable') + } + + this.stream.write(message) + } +} diff --git a/packages/provider/src/transports/extension-transport/extension-message-handler.ts b/packages/provider/src/transports/extension-transport/extension-message-handler.ts new file mode 100644 index 0000000000..88449b564b --- /dev/null +++ b/packages/provider/src/transports/extension-transport/extension-message-handler.ts @@ -0,0 +1,29 @@ +import { WalletRequestHandler } from '../wallet-request-handler' +import { BaseWalletTransport } from '../base-wallet-transport' +import { InitState, ProviderMessage } from '../../types' +import { Runtime } from 'webextension-polyfill' +import { logger } from '@0xsequence/utils' + +export const CHANNEL_ID = 'sequence-extension-message-handler' + +export class ExtensionMessageHandler extends BaseWalletTransport { + private port: any + + constructor( + walletRequestHandler: WalletRequestHandler, + public runtime: Runtime.Static + ) { + super(walletRequestHandler) + this._init = InitState.OK + } + + register() { + this._registered = true + this.port = this.runtime.connect({ name: CHANNEL_ID }) + } + + sendMessage(message: ProviderMessage) { + logger.info('[ExtensionMessageHandler send]', message) + this.port.postMessage(message) + } +} diff --git a/packages/provider/src/transports/extension-transport/extension-message-provider.ts b/packages/provider/src/transports/extension-transport/extension-message-provider.ts new file mode 100644 index 0000000000..a65f214b0a --- /dev/null +++ b/packages/provider/src/transports/extension-transport/extension-message-provider.ts @@ -0,0 +1,41 @@ +import { InitState, OpenWalletIntent, ProviderMessage } from '../../types' +import { BaseProviderTransport } from '../base-provider-transport' +import { CHANNEL_ID } from './extension-message-handler' + +import { Runtime } from 'webextension-polyfill' + +export class ExtensionMessageProvider extends BaseProviderTransport { + constructor(runtime: Runtime.Static) { + super() + + runtime.onConnect.addListener(port => { + if (port.name === CHANNEL_ID) { + this._init = InitState.OK + + port.onMessage.addListener((message: ProviderMessage) => { + this.handleMessage(message) + }) + } + }) + } + + register = () => { + this._registered = true + } + + sendMessage(message: ProviderMessage) { + //noop + } + + unregister() { + //noop + } + + openWallet(path?: string, intent?: OpenWalletIntent, networkId?: string | number) { + //noop + } + + closeWallet() { + //noop + } +} diff --git a/packages/provider/src/transports/extension-transport/index.ts b/packages/provider/src/transports/extension-transport/index.ts new file mode 100644 index 0000000000..af015cdc0b --- /dev/null +++ b/packages/provider/src/transports/extension-transport/index.ts @@ -0,0 +1,3 @@ +export * from './extension-message-handler' +export * from './extension-message-provider' +export * from './base-injected-transport' diff --git a/packages/provider/src/transports/index.ts b/packages/provider/src/transports/index.ts new file mode 100644 index 0000000000..35f06a3af8 --- /dev/null +++ b/packages/provider/src/transports/index.ts @@ -0,0 +1,8 @@ +export * from './base-provider-transport' +export * from './base-wallet-transport' +export * from './proxy-transport' +export * from './mux-transport' +export * from './window-transport' +export * from './wallet-request-handler' +export * from './extension-transport' +export * from './unreal-transport' diff --git a/packages/provider/src/transports/mux-transport/index.ts b/packages/provider/src/transports/mux-transport/index.ts new file mode 100644 index 0000000000..6a69b9e8d0 --- /dev/null +++ b/packages/provider/src/transports/mux-transport/index.ts @@ -0,0 +1 @@ +export * from './mux-message-provider' diff --git a/packages/provider/src/transports/mux-transport/mux-message-provider.ts b/packages/provider/src/transports/mux-transport/mux-message-provider.ts new file mode 100644 index 0000000000..109181aba9 --- /dev/null +++ b/packages/provider/src/transports/mux-transport/mux-message-provider.ts @@ -0,0 +1,249 @@ +import { + ProviderMessage, + ProviderTransport, + ProviderEventTypes, + ProviderMessageRequest, + ProviderMessageResponse, + WalletSession, + OpenWalletIntent, + ConnectDetails +} from '../../types' + +import { JsonRpcRequest, JsonRpcResponseCallback } from '@0xsequence/network' +import { ProxyMessageChannelPort, ProxyMessageProvider } from '../proxy-transport' +import { Runtime } from 'webextension-polyfill' +import { UnrealMessageProvider } from '../unreal-transport' +import { ExtensionMessageProvider } from '../extension-transport' +import { WindowMessageProvider } from '../window-transport' + +export type MuxTransportTemplate = { + walletAppURL?: string + + // WindowMessage transport (optional) + windowTransport?: { + enabled: boolean + } + + // ProxyMessage transport (optional) + proxyTransport?: { + enabled: boolean + appPort?: ProxyMessageChannelPort + } + + // Extension transport (optional) + extensionTransport?: { + enabled: boolean + runtime: Runtime.Static + } + + // Unreal Engine transport (optional) + unrealTransport?: { + enabled: boolean + } +} + +export function isMuxTransportTemplate(obj: any): obj is MuxTransportTemplate { + return ( + obj && + typeof obj === 'object' && + ((obj.windowTransport && typeof obj.windowTransport === 'object') || + (obj.proxyTransport && typeof obj.proxyTransport === 'object') || + (obj.extensionTransport && typeof obj.extensionTransport === 'object') || + (obj.unrealTransport && typeof obj.unrealTransport === 'object')) && + // One of the transports must be enabled + ((obj.windowTransport && obj.windowTransport.enabled) || + (obj.proxyTransport && obj.proxyTransport.enabled) || + (obj.extensionTransport && obj.extensionTransport.enabled) || + (obj.unrealTransport && obj.unrealTransport.enabled)) + ) +} + +export class MuxMessageProvider implements ProviderTransport { + private messageProviders: ProviderTransport[] + private provider: ProviderTransport | undefined + + constructor(...messageProviders: ProviderTransport[]) { + this.messageProviders = messageProviders + this.provider = undefined + } + + static new(template: MuxTransportTemplate): MuxMessageProvider { + const muxMessageProvider = new MuxMessageProvider() + + if (template.windowTransport?.enabled && typeof window === 'object' && template.walletAppURL) { + const windowMessageProvider = new WindowMessageProvider(template.walletAppURL) + muxMessageProvider.add(windowMessageProvider) + } + + if (template.proxyTransport?.enabled) { + const proxyMessageProvider = new ProxyMessageProvider(template.proxyTransport.appPort!) + muxMessageProvider.add(proxyMessageProvider) + } + + if (template.extensionTransport?.enabled) { + const extensionMessageProvider = new ExtensionMessageProvider(template.extensionTransport.runtime) + muxMessageProvider.add(extensionMessageProvider) + + // NOTE/REVIEW: see note in mux-message-provider + // + // We don't add the extensionMessageProvider here because we don't send requests to it anyways, we seem to + // send all requests to the WindowMessageProvider anyways. By allowing it, if browser restarts, it will break + // the entire extension because messageProvider.provider will be undefined. So this is a hack to fix it. + } + + if (template.unrealTransport?.enabled && template.windowTransport && template.walletAppURL) { + const unrealMessageProvider = new UnrealMessageProvider(template.walletAppURL) + muxMessageProvider.add(unrealMessageProvider) + } + + muxMessageProvider.register() + + return muxMessageProvider + } + + add(...messageProviders: ProviderTransport[]) { + this.messageProviders.push(...messageProviders) + } + + register = () => { + if (this.messageProviders.length === 1) { + this.provider = this.messageProviders[0] + this.provider.register() + return + } + + // REVIEW/NOTE: ........ this method does not work for the chrome-extension. The issue becomes + // when the browser quits or restarts, the "open" event is never triggered. Perhaps the code here is fine, + // or maybe its not. What should happen is when a dapp makes a request, it will call openWallet + // below, in which case one of the events will register. So perhaps this is fine. + this.messageProviders.forEach(m => { + m.register() + + m.once('open', () => { + // the first one to open is the winner, and others will be unregistered + if (!this.provider) { + this.provider = m + + // unregister other providers + this.messageProviders.forEach(m => { + if (this.provider !== m) { + m.unregister() + } + }) + } + }) + }) + } + + unregister = () => { + this.messageProviders.forEach(m => m.unregister()) + this.provider = undefined + } + + openWallet = (path?: string, intent?: OpenWalletIntent, networkId?: string | number): void => { + if (this.provider) { + this.provider.openWallet(path, intent, networkId) + return + } + this.messageProviders.forEach(m => m.openWallet(path, intent, networkId)) + } + + closeWallet() { + if (this.provider) { + this.provider.closeWallet() + } + } + + isOpened(): boolean { + if (this.provider) { + return this.provider.isOpened() + } + return false + } + + isConnected(): boolean { + if (this.provider) { + return this.provider.isConnected() + } + return false + } + + on(event: K, fn: ProviderEventTypes[K]) { + if (this.provider) { + this.provider.on(event, fn) + return + } + this.messageProviders.forEach(m => { + m.on(event, fn) + }) + } + + once(event: K, fn: ProviderEventTypes[K]) { + if (this.provider) { + this.provider.once(event, fn) + return + } + this.messageProviders.forEach(m => { + m.once(event, fn) + }) + } + + emit(event: K, ...args: Parameters): boolean { + if (this.provider) { + return this.provider.emit(event, ...args) + } + for (let i = 0; i < this.messageProviders.length; i++) { + this.messageProviders[i].emit(event, ...args) + } + return true + } + + sendAsync = async (request: JsonRpcRequest, callback: JsonRpcResponseCallback, chainId?: number) => { + if (this.provider) { + this.provider.sendAsync(request, callback, chainId) + return + } + throw new Error('impossible state, wallet must be opened first') + } + + sendMessage(message: ProviderMessage) { + if (!message.idx || message.idx <= 0) { + throw new Error('message idx is empty') + } + + if (this.provider) { + this.provider.sendMessage(message) + } else { + throw new Error('impossible state, wallet must be opened first') + } + } + + sendMessageRequest = async (message: ProviderMessageRequest): Promise => { + if (this.provider) { + return this.provider.sendMessageRequest(message) + } + throw new Error('impossible state, wallet must be opened first') + } + + handleMessage(message: ProviderMessage): void { + if (this.provider) { + this.provider.handleMessage(message) + return + } + throw new Error('impossible state, wallet must be opened first') + } + + waitUntilOpened = async (): Promise => { + if (this.provider) { + return this.provider.waitUntilOpened() + } + return Promise.race(this.messageProviders.map(p => p.waitUntilOpened())) + } + + waitUntilConnected = async (): Promise => { + if (this.provider) { + return this.provider.waitUntilConnected() + } + throw new Error('impossible state, wallet must be opened first') + } +} diff --git a/packages/provider/src/transports/proxy-transport/index.ts b/packages/provider/src/transports/proxy-transport/index.ts new file mode 100644 index 0000000000..dd0a693325 --- /dev/null +++ b/packages/provider/src/transports/proxy-transport/index.ts @@ -0,0 +1,3 @@ +export * from './proxy-message-channel' +export * from './proxy-message-provider' +export * from './proxy-message-handler' diff --git a/packages/provider/src/transports/proxy-transport/proxy-message-channel.ts b/packages/provider/src/transports/proxy-transport/proxy-message-channel.ts new file mode 100644 index 0000000000..33f585797e --- /dev/null +++ b/packages/provider/src/transports/proxy-transport/proxy-message-channel.ts @@ -0,0 +1,57 @@ +import { EventEmitter2 as EventEmitter } from 'eventemitter2' +import { ProviderMessage, ProviderMessageTransport, ProviderEventTypes, TypedEventEmitter } from '../../types' + +export class ProxyMessageChannel { + app: ProxyMessageChannelPort + wallet: ProxyMessageChannelPort + + constructor() { + const port1 = new ProxyMessageChannelPort() + const port2 = new ProxyMessageChannelPort() + + port1.conn = port2 + port2.conn = port1 + + this.app = port1 + this.wallet = port2 + } +} + +export class ProxyMessageChannelPort implements ProviderMessageTransport { + conn: ProviderMessageTransport + events: TypedEventEmitter = new EventEmitter() as TypedEventEmitter + + // handle messages which hit this port + handleMessage = (message: ProviderMessage): void => { + throw new Error('ProxyMessageChannelPort is not registered') + } + + // send messages to the connected port + sendMessage = (message: ProviderMessage): void => { + this.conn.handleMessage(message) + + // trigger events + if (message.type === 'open') { + this.events.emit('open', message as any) + } + if (message.type === 'close') { + this.events.emit('close', message as any) + } + if (message.type === 'connect') { + this.events.emit('connect', message as any) + } + if (message.type === 'disconnect') { + this.events.emit('disconnect', message as any) + } + } + + on(event: K, fn: ProxyEventTypes[K]) { + this.events.on(event, fn as any) + } + + once(event: K, fn: ProxyEventTypes[K]) { + this.events.once(event, fn as any) + } +} + +export type ProxyEventTypes = Pick diff --git a/packages/provider/src/transports/proxy-transport/proxy-message-handler.ts b/packages/provider/src/transports/proxy-transport/proxy-message-handler.ts new file mode 100644 index 0000000000..68d2e39824 --- /dev/null +++ b/packages/provider/src/transports/proxy-transport/proxy-message-handler.ts @@ -0,0 +1,44 @@ +import { BaseWalletTransport } from '../base-wallet-transport' +import { WalletRequestHandler } from '../wallet-request-handler' +import { InitState, ProviderMessage } from '../../types' +import { ProxyMessageChannelPort } from './proxy-message-channel' + +export class ProxyMessageHandler extends BaseWalletTransport { + private port: ProxyMessageChannelPort + + constructor(walletRequestHandler: WalletRequestHandler, port: ProxyMessageChannelPort) { + super(walletRequestHandler) + this.port = port + this._init = InitState.OK + } + + register() { + this.port.handleMessage = (message: ProviderMessage): void => { + this.handleMessage(message) + } + this._registered = true + } + + // note: we can't decide whether to restore the session within register(), because session info is + // received asyncronously via EventType.OPEN after register() is executed. + // And in the case of a redirect/reload, EventType.OPEN is not sent at all, + // because the wallet is already open. + // + // call this method from wallet redirect hander when a session restore is needed + async restoreSession() { + const cachedSession = await this.getCachedTransportSession() + if (cachedSession) { + this.open(cachedSession) + } + } + + unregister() { + // @ts-ignore + this.port.handleMessage = undefined + this._registered = false + } + + sendMessage(message: ProviderMessage) { + this.port.sendMessage(message) + } +} diff --git a/packages/provider/src/transports/proxy-transport/proxy-message-provider.ts b/packages/provider/src/transports/proxy-transport/proxy-message-provider.ts new file mode 100644 index 0000000000..b5d817c789 --- /dev/null +++ b/packages/provider/src/transports/proxy-transport/proxy-message-provider.ts @@ -0,0 +1,85 @@ +import { BaseProviderTransport } from '../base-provider-transport' + +import { ProviderMessage, OpenState, OpenWalletIntent, EventType, InitState } from '../../types' + +import { ProxyMessageChannelPort, ProxyEventTypes } from './proxy-message-channel' + +export class ProxyMessageProvider extends BaseProviderTransport { + private port: ProxyMessageChannelPort + + constructor(port: ProxyMessageChannelPort) { + super() + this.state = OpenState.CLOSED + this.port = port + if (!port) { + throw new Error('port argument cannot be empty') + } + + // disable init handshake for proxy-transport, we set it to OK, to + // consider it in completed state. + this._init = InitState.OK + } + + register = () => { + this.port.handleMessage = (message: ProviderMessage): void => { + this.handleMessage(message) + } + + this.on('open', (...args: Parameters) => { + this.port.events.emit('open', ...args) + }) + this.on('close', (...args: Parameters) => { + this.port.events.emit('close', ...args) + }) + this.on('connect', (...args: Parameters) => { + this.port.events.emit('connect', ...args) + }) + this.on('disconnect', (...args: Parameters) => { + this.port.events.emit('disconnect', ...args) + }) + + this._registered = true + } + + unregister = () => { + this._registered = false + this.closeWallet() + this.events.removeAllListeners() + // @ts-ignore + this.port.handleMessage = undefined + } + + openWallet = (path?: string, intent?: OpenWalletIntent, networkId?: string | number): void => { + if (this.state === OpenState.CLOSED) { + this.state = OpenState.OPENING + const sessionId = `${performance.now()}` + this._sessionId = sessionId + this.sendMessage({ + idx: -1, + type: EventType.OPEN, + data: { + path, + intent, + networkId, + sessionId + } + }) + } + } + + closeWallet() { + this.sendMessage({ + idx: -1, + type: EventType.CLOSE, + data: null + }) + this.close() + } + + sendMessage(message: ProviderMessage) { + if (!message.idx) { + throw new Error('message idx is empty') + } + this.port.sendMessage(message) + } +} diff --git a/packages/provider/src/transports/unreal-transport/index.ts b/packages/provider/src/transports/unreal-transport/index.ts new file mode 100644 index 0000000000..460b0a9f08 --- /dev/null +++ b/packages/provider/src/transports/unreal-transport/index.ts @@ -0,0 +1,2 @@ +export * from './unreal-message-provider' +export * from './unreal-message-handler' diff --git a/packages/provider/src/transports/unreal-transport/overridelogs.ts b/packages/provider/src/transports/unreal-transport/overridelogs.ts new file mode 100644 index 0000000000..5148d93890 --- /dev/null +++ b/packages/provider/src/transports/unreal-transport/overridelogs.ts @@ -0,0 +1,34 @@ +interface UnrealInjectedWindow { + ue?: { + sequencewallettransport?: { + logfromjs: (message: string) => void + warnfromjs: (message: string) => void + errorfromjs: (message: string) => void + } + } + logsOverriddenForUnreal?: boolean +} +declare const window: Window & typeof globalThis & UnrealInjectedWindow + +/** + * This will redirect console logs from Sequence.js & the wallet to the Unreal console, for debugging purposes. + */ +export function overrideLogs(side: 'dapp' | 'wallet') { + if (window.ue?.sequencewallettransport && !window.logsOverriddenForUnreal) { + const t = window.ue?.sequencewallettransport + console.log = (...args: unknown[]) => { + t.logfromjs(`${side}: ${stringify(args)}`) + } + console.warn = (...args: unknown[]) => { + t.warnfromjs(`${side}: ${stringify(args)}`) + } + console.error = (...args: unknown[]) => { + t.errorfromjs(`${side}: ${stringify(args)}`) + } + window.logsOverriddenForUnreal = true + } +} + +function stringify(things: unknown[]): string { + return things.map(a => (typeof a === 'object' ? (a instanceof Error ? a.message : JSON.stringify(a)) : String(a))).join(' ') +} diff --git a/packages/provider/src/transports/unreal-transport/unreal-message-handler.ts b/packages/provider/src/transports/unreal-transport/unreal-message-handler.ts new file mode 100644 index 0000000000..8358d6c6c4 --- /dev/null +++ b/packages/provider/src/transports/unreal-transport/unreal-message-handler.ts @@ -0,0 +1,121 @@ +import { + ProviderMessageRequest, + ProviderMessage, + EventType, + InitState, + WindowSessionParams, + OpenWalletIntent, + ProviderRpcError, + TransportSession +} from '../../types' +import { WalletRequestHandler } from '../wallet-request-handler' +import { BaseWalletTransport } from '../base-wallet-transport' +import { logger, base64DecodeObject } from '@0xsequence/utils' +import { overrideLogs } from './overridelogs' + +// all lowercase is an annoying limitation of Unreal CEF BindUObject +interface UnrealInjectedWalletWindow { + ue?: { + sequencewallettransport?: { + onmessagefromsequencejs?: (message: ProviderMessageRequest) => void + sendmessagetosequencejs: (message: string) => void + } + } +} +declare const window: Window & typeof globalThis & UnrealInjectedWalletWindow + +/** + * Initialized on Wallet side + */ +export class UnrealMessageHandler extends BaseWalletTransport { + constructor(walletRequestHandler: WalletRequestHandler) { + super(walletRequestHandler) + this._init = InitState.NIL + } + + async register(windowHref?: string | URL) { + if (window.ue?.sequencewallettransport === undefined) { + return + } + overrideLogs('wallet') + + // record open details (sessionId + default network) from the window url + const { search: rawParams } = new URL(windowHref || window.location.href) + + let session: TransportSession | null = this.getUnrealTransportSession(rawParams) + + // provider should always include sid when opening a new window + const isNewWindowSession = !!session.sessionId + + // attempt to restore previous session in the case of a redirect or window reload + if (!isNewWindowSession) { + session = await this.getCachedTransportSession() + } + + if (!session) { + logger.error('unreal session is undefined') + return + } + + // listen for window-transport requests + window.ue.sequencewallettransport.onmessagefromsequencejs = this.onMessageFromUnreal + this._registered = true + + // send open event to the app which opened us + this.open(session) + .then(opened => { + if (!opened) { + const err = `failed to open to network ${session?.networkId}` + logger.error(err) + this.notifyClose({ message: err } as ProviderRpcError) + window.close() + } + }) + .catch(e => { + const err = `failed to open to network ${session?.networkId}, due to: ${e}` + logger.error(err) + this.notifyClose({ message: err } as ProviderRpcError) + window.close() + }) + } + + unregister() { + if (window.ue?.sequencewallettransport?.onmessagefromsequencejs === this.onMessageFromUnreal) { + delete window.ue.sequencewallettransport.onmessagefromsequencejs + } + this._registered = false + } + + // onmessage is called when (the wallet) receives request messages from the dapp + // over the unreal json-messaging transport + private onMessageFromUnreal = (request: ProviderMessageRequest) => { + // Wallet always expects json-rpc request messages from a dapp + + logger.debug('RECEIVED MESSAGE', request) + + // Handle message via the base transport + this.handleMessage(request) + } + + // sendMessage sends message to the dapp window + sendMessage(message: ProviderMessage) { + if (message.type !== EventType.INIT && this._init !== InitState.OK) { + logger.error('impossible state, should not be calling postMessage until inited') + return + } + // prepare payload + const payload = JSON.stringify(message) + + // post-message to app. + window.ue?.sequencewallettransport?.sendmessagetosequencejs(payload) + } + + private getUnrealTransportSession = (windowParams: string | undefined): TransportSession => { + const params = new WindowSessionParams(windowParams) + return { + sessionId: params.get('sid'), + networkId: params.get('net'), + intent: base64DecodeObject(params.get('intent')) + } + } +} diff --git a/packages/provider/src/transports/unreal-transport/unreal-message-provider.ts b/packages/provider/src/transports/unreal-transport/unreal-message-provider.ts new file mode 100644 index 0000000000..8b1908589d --- /dev/null +++ b/packages/provider/src/transports/unreal-transport/unreal-message-provider.ts @@ -0,0 +1,121 @@ +import { OpenWalletIntent, ProviderMessage, InitState, WindowSessionParams } from '../../types' +import { BaseProviderTransport } from '../base-provider-transport' +import { base64EncodeObject } from '@0xsequence/utils' +import { overrideLogs } from './overridelogs' + +let registeredUnrealMessageProvider: UnrealMessageProvider | undefined + +// all lowercase is an annoying limitation of Unreal CEF BindUObject +interface UnrealInjectedSequenceJSWindow { + ue?: { + sequencewallettransport?: { + onmessagefromwallet?: (message: ProviderMessage) => void + sendmessagetowallet: (message: string) => void + } + } +} + +declare const window: Window & typeof globalThis & UnrealInjectedSequenceJSWindow + +/** + * Initialized on dApp side + */ +export class UnrealMessageProvider extends BaseProviderTransport { + private walletURL: URL + + constructor(walletAppURL: string) { + super() + this.walletURL = new URL(walletAppURL) + } + + register = () => { + overrideLogs('dapp') + if (registeredUnrealMessageProvider) { + // overriding the registered message provider + registeredUnrealMessageProvider.unregister() + registeredUnrealMessageProvider = this + } + + // listen for incoming messages from wallet + if (window.ue?.sequencewallettransport) { + window.ue.sequencewallettransport.onmessagefromwallet = this.onUnrealCallback + } + registeredUnrealMessageProvider = this + + this._registered = true + console.log('registering transport!') + } + + unregister = () => { + this._registered = false + this.closeWallet() + + // disable message listener + if (registeredUnrealMessageProvider === this) { + registeredUnrealMessageProvider = undefined + } + if (window.ue?.sequencewallettransport?.onmessagefromwallet === this.onUnrealCallback) { + delete window.ue.sequencewallettransport.onmessagefromwallet + } + + // clear event listeners + this.events.removeAllListeners() + } + + openWallet = (path?: string, intent?: OpenWalletIntent, networkId?: string | number): void => { + if (this.isOpened()) { + // TODO focus wallet + console.log('wallet already open!') + return + } + + console.log('opening wallet!') + // Instantiate new walletURL for this call + const walletURL = new URL(this.walletURL.href) + const windowSessionParams = new WindowSessionParams() + + if (path) { + walletURL.pathname = path.toLowerCase() + } + + // Set session, intent and network id on walletURL + this._init = InitState.NIL + this._sessionId = `${performance.now()}` + windowSessionParams.set('sid', this._sessionId) + + if (intent) { + // encode intent as base64 url-encoded param + windowSessionParams.set('intent', base64EncodeObject(intent)) + } + if (networkId) { + windowSessionParams.set('net', `${networkId}`) + } + // serialize params + walletURL.search = windowSessionParams.toString() + + console.log('opening wallet to', walletURL.href) + + window.open(walletURL.href) + } + + closeWallet() { + this.close() + } + + // onmessage, receives ProviderMessageResponse from the wallet unreal transport + private onUnrealCallback = (message: ProviderMessage) => { + if (!message) { + throw new Error('ProviderMessage object is empty') + } + + // handle message with base message provider + this.handleMessage(message) + } + + // all lowercase is an annoying limitation of Unreal CEF BindUObject + sendMessage(message: ProviderMessage) { + const postedMessage = typeof message !== 'string' ? JSON.stringify(message) : message + console.log('Sending message to wallet:', postedMessage) + window.ue?.sequencewallettransport?.sendmessagetowallet(postedMessage) + } +} diff --git a/packages/provider/src/transports/wallet-request-handler.ts b/packages/provider/src/transports/wallet-request-handler.ts new file mode 100644 index 0000000000..98dbf3cf3c --- /dev/null +++ b/packages/provider/src/transports/wallet-request-handler.ts @@ -0,0 +1,940 @@ +import { Account, AccountStatus } from '@0xsequence/account' +import { signAuthorization, AuthorizationOptions } from '@0xsequence/auth' +import { commons } from '@0xsequence/core' +import { + ChainId, + ChainIdLike, + findNetworkConfig, + findSupportedNetwork, + JsonRpcHandler, + JsonRpcRequest, + JsonRpcResponse, + JsonRpcResponseCallback, + NetworkConfig +} from '@0xsequence/network' +import { logger, TypedData } from '@0xsequence/utils' +import { BigNumber, ethers, providers } from 'ethers' +import { EventEmitter2 as EventEmitter } from 'eventemitter2' + +import { fromExtended } from '../extended' +import { validateTransactionRequest } from '../transactions' +import { + ConnectDetails, + ConnectOptions, + ErrSignedInRequired, + MessageToSign, + NetworkedConnectOptions, + OpenWalletIntent, + PromptConnectDetails, + ProviderEventTypes, + ProviderMessageRequest, + ProviderMessageRequestHandler, + ProviderMessageResponse, + ProviderRpcError, + TypedEventEmitter, + WalletSession +} from '../types' +import { prefixEIP191Message } from '../utils' + +type ExternalProvider = providers.ExternalProvider + +const SIGNER_READY_TIMEOUT = 10000 + +export interface WalletSignInOptions { + connect?: boolean + defaultNetworkId?: number +} + +export class WalletRequestHandler implements ExternalProvider, JsonRpcHandler, ProviderMessageRequestHandler { + // signer interface of the wallet. A null value means there is no signer (ie. user not signed in). An undefined + // value means the signer state is unknown, usually meaning the wallet app is booting up and initializing. Of course + // a Signer value is the actually interface to a signed-in account + private account: Account | null | undefined + private signerReadyCallbacks: Array<() => void> = [] + + private prompter: WalletUserPrompter | null + private networks: NetworkConfig[] + + private _openIntent?: OpenWalletIntent + private _connectOptions?: ConnectOptions + + private events: TypedEventEmitter = new EventEmitter() as TypedEventEmitter + + onConnectOptionsChange: ((connectOptions: ConnectOptions | undefined) => void) | undefined = undefined + + constructor(account: Account | null | undefined, prompter: WalletUserPrompter | null, networks: NetworkConfig[]) { + this.account = account + this.prompter = prompter + this.networks = networks + } + + defaultChainId(): number { + return this.prompter?.getDefaultChainId() ?? this.networks[0].chainId + } + + async signIn(account: Account | null, options: WalletSignInOptions = {}) { + this.setAccount(account) + + const { connect, defaultNetworkId } = options + + // Optionally, connect the dapp and wallet. In case connectOptions are provided, we will perform + // necessary auth request, and then notify the dapp of the 'connect' details. + // + // NOTE: if a user is signing into a dapp from a fresh state, and and auth request is made + // we don't trigger the promptConnect flow, as we consider the user just authenticated + // for this dapp, so its safe to authorize in the promptSignInConnect() which will directly + // connect after signing in. + // + // NOTE: signIn can optionally connect and notify dapp at this time for new signIn flows + if (connect) { + const connectOptions = this._connectOptions + + let connectDetails: ConnectDetails | PromptConnectDetails + + if (this.prompter !== null) { + connectDetails = await this.prompter?.promptSignInConnect(connectOptions) + } else { + connectDetails = await this.connect(connectOptions) + } + + this.notifyConnect(connectDetails) + + if (!connectOptions || connectOptions.keepWalletOpened !== true) { + this.notifyClose() + } + } + + if (defaultNetworkId && this.defaultChainId() !== defaultNetworkId) { + await this.prompter?.promptChangeNetwork(defaultNetworkId) + } + } + + signOut() { + if (this.account) { + this.notifyDisconnect() + } + + // signed out state + this.setAccount(null) + } + + signerReset() { + // resetting signer puts the wallet in an uninitialized state, which requires the app to + // re-initiatize and set the signer either as "null" (ie. no signer) or "Signer" (ie. signed in). + this.account = undefined + } + + signerReady(timeout: number = SIGNER_READY_TIMEOUT): Promise { + return new Promise((resolve, reject) => { + if (this.account !== undefined) { + resolve() + } else { + setTimeout(() => { + if (this.account === undefined) { + this.signerReadyCallbacks = [] + reject(`signerReady timed out`) + } + }, timeout) + this.signerReadyCallbacks.push(resolve) + } + }) + } + + async connect(options?: NetworkedConnectOptions): Promise { + if (!this.account) { + return { + connected: false, + chainId: '0x0', + error: 'unable to connect without signed in account' + } + } + + const networkId = options?.networkId ?? this.defaultChainId() ?? ChainId.MAINNET + const chainId = findSupportedNetwork(networkId)!.chainId + + const connectDetails: ConnectDetails = { + connected: true, + chainId: ethers.utils.hexValue(chainId) + } + + if (options && options.authorize) { + // Perform ethauth eip712 request and construct the ConnectDetails response + // including the auth proof + const authOptions: AuthorizationOptions = { + app: options.app, + origin: options.origin, + expiry: options.expiry, + nonce: options.authorizeNonce + } + // if (typeof(options.authorize) === 'object') { + // authOptions = { ...authOptions, ...options.authorize } + // } + + try { + // TODO: Either implement account as a signer, or change signAuthorization to accept an account + connectDetails.proof = await signAuthorization(this.account, chainId, authOptions) + } catch (err) { + logger.warn(`connect, signAuthorization failed for options: ${JSON.stringify(options)}, due to: ${err.message}`) + return { + connected: false, + chainId: '0x0', + error: `signAuthorization failed: ${err.message}` + } + } + } + + // Build session response for connect details + connectDetails.session = this.walletSession(chainId) + + return connectDetails + } + + promptConnect = async (options?: NetworkedConnectOptions): Promise => { + if (!options && !this._connectOptions) { + // this is an unexpected state and should not happen + throw new Error('prompter connect options are empty') + } + + if (!this.prompter) { + // if prompter is null, we'll auto connect + return this.connect(options) + } + + const promptConnectDetails = await this.prompter.promptConnect(options || this._connectOptions).catch(_ => { + return { connected: false } as ConnectDetails + }) + + const connectDetails: ConnectDetails = promptConnectDetails + if (connectDetails.connected && !connectDetails.session) { + connectDetails.session = await this.walletSession(options?.networkId) + } + + return promptConnectDetails + } + + // sendMessageRequest will unwrap the ProviderMessageRequest and send it to the JsonRpcHandler + // (aka, the signer in this instance) and then responds with a wrapped response of + // ProviderMessageResponse to be sent over the transport + sendMessageRequest(message: ProviderMessageRequest): Promise { + return new Promise(resolve => { + this.sendAsync( + message.data, + (error: any, response?: JsonRpcResponse) => { + // TODO: if response includes data.error, why do we need a separate error argument here? + + const responseMessage: ProviderMessageResponse = { + ...message, + data: response! + } + + // NOTE: we always resolve here, are the sendAsync call will wrap any exceptions + // in the error field of the response to ensure we send back to the user + resolve(responseMessage) + }, + message.chainId + ) + }) + } + + // sendAsync implements the JsonRpcHandler interface for sending JsonRpcRequests to the wallet + sendAsync = async (request: JsonRpcRequest, callback: JsonRpcResponseCallback, chainId?: number) => { + const response: JsonRpcResponse = { + jsonrpc: '2.0', + id: request.id!, + result: null + } + + await this.getAccount() + + try { + // only allow public json rpc method to the provider when user is not logged in, aka signer is not set + if ((!this.account || this.account === null) && !permittedJsonRpcMethods.includes(request.method)) { + // throw new Error(`not logged in. ${request.method} is unavailable`) + throw ErrSignedInRequired + } + + // wallet account + const account = this.account + if (!account) throw new Error('WalletRequestHandler: wallet account is not configured') + + // fetch the provider for the specific chain, or undefined will select defaultChain + const provider = this.account?.providerFor(chainId ?? this.defaultChainId()) + if (!provider) throw new Error(`WalletRequestHandler: wallet provider is not configured for chainId ${chainId}`) + const jsonRpcProvider = provider instanceof ethers.providers.JsonRpcProvider ? provider : undefined + + switch (request.method) { + case 'net_version': { + if (!jsonRpcProvider) { + throw new Error(`Account provider doesn't support send method`) + } + + const result = await jsonRpcProvider.send('net_version', []) + response.result = result + break + } + + case 'eth_chainId': { + if (!jsonRpcProvider) { + throw new Error(`Account provider doesn't support send method`) + } + + const result = await jsonRpcProvider.send('eth_chainId', []) + response.result = result + break + } + + case 'eth_accounts': { + const walletAddress = account.address + response.result = [walletAddress] + break + } + + case 'eth_getBalance': { + const [accountAddress, blockTag] = request.params! + const walletBalance = await provider.getBalance(accountAddress, blockTag) + response.result = walletBalance.toHexString() + break + } + + case 'sequence_sign': + case 'personal_sign': + case 'eth_sign': { + // note: message from json-rpc input is in hex format + let message: any + + // there is a difference in the order of the params: + // sequence_sign, personal_sign: [data, address] + // eth_sign: [address, data] + switch (request.method) { + case 'sequence_sign': + case 'personal_sign': { + const [data, _address] = request.params! + message = data + break + } + case 'eth_sign': { + const [_address, data] = request.params! + message = data + break + } + } + + let sig = '' + + // Message must be prefixed with "\x19Ethereum Signed Message:\n" + // as defined by EIP-191 + const prefixedMessage = prefixEIP191Message(message) + + // TODO: + // if (process.env.TEST_MODE === 'true' && this.prompter === null) { + const sequenceVerified = request.method === 'sequence_sign' + if (this.prompter === null) { + // prompter is null, so we'll sign from here + sig = await account.signMessage( + prefixedMessage, + chainId ?? this.defaultChainId(), + sequenceVerified ? 'eip6492' : 'ignore' + ) + } else { + sig = await this.prompter.promptSignMessage( + { + chainId: chainId, + message: prefixedMessage, + eip6492: sequenceVerified + }, + this.connectOptions + ) + } + + if (sig && sig.length > 0) { + response.result = sig + } else { + // The user has declined the request when value is null + throw new Error('declined by user') + } + break + } + + case 'sequence_signTypedData_v4': + case 'eth_signTypedData': + case 'eth_signTypedData_v4': { + // note: signingAddress from json-rpc input is in hex format, and typedDataObject + // should be an object, but in some instances may be double string encoded + const [signingAddress, typedDataObject] = request.params! + + let typedData: TypedData | undefined = undefined + if (typeof typedDataObject === 'string') { + try { + typedData = JSON.parse(typedDataObject) + } catch (e) { + console.warn('walletRequestHandler: error parsing typedData', e) + } + } else { + typedData = typedDataObject + } + + if (!typedData || !typedData.domain || !typedData.types || !typedData.message) { + throw new Error('invalid typedData object') + } + + let sig = '' + + const sequenceVerified = request.method === 'sequence_signTypedData_v4' + if (this.prompter === null) { + // prompter is null, so we'll sign from here + sig = await account.signTypedData( + typedData.domain, + typedData.types, + typedData.message, + chainId ?? this.defaultChainId(), + sequenceVerified ? 'eip6492' : 'ignore' + ) + } else { + sig = await this.prompter.promptSignMessage( + { + chainId: chainId, + typedData: typedData, + eip6492: sequenceVerified + }, + this.connectOptions + ) + } + + if (sig && sig.length > 0) { + response.result = sig + } else { + // The user has declined the request when value is null + throw new Error('declined by user') + } + break + } + + case 'eth_sendTransaction': { + // https://eth.wiki/json-rpc/API#eth_sendtransaction + const transactionParams = fromExtended(request.params![0]).map(tx => { + // eth_sendTransaction uses 'gas' + // ethers and sequence use 'gasLimit' + if ('gas' in tx && tx.gasLimit === undefined) { + tx.gasLimit = tx.gas as any + delete tx.gas + } + + return tx + }) + + validateTransactionRequest(account.address, transactionParams) + + let txnHash = '' + if (this.prompter === null) { + // prompter is null, so we'll send from here + const txnResponse = await account.sendTransaction(transactionParams, chainId ?? this.defaultChainId()) + txnHash = txnResponse?.hash ?? '' + } else { + // prompt user to provide the response + txnHash = await this.prompter.promptSendTransaction(transactionParams, chainId, this.connectOptions) + } + + if (txnHash) { + response.result = txnHash + } else { + // The user has declined the request when value is null + throw new Error('declined by user') + } + break + } + + case 'eth_signTransaction': { + // https://eth.wiki/json-rpc/API#eth_signTransaction + const [transaction] = request.params! + const sender = ethers.utils.getAddress(transaction.from) + + if (sender !== account.address) { + throw new Error('sender address does not match wallet') + } + + validateTransactionRequest(account.address, transaction) + + if (this.prompter === null) { + // The eth_signTransaction method expects a `string` return value we instead return a `SignedTransactions` object, + // this can only be broadcasted using an RPC provider with support for signed Sequence transactions, like this one. + // + // TODO: verify serializing / transporting the SignedTransaction object works as expected, most likely however + // we will want to resolveProperties the big number values to hex strings + response.result = await account.signTransactions(transaction, chainId ?? this.defaultChainId()) + } else { + response.result = await this.prompter.promptSignTransaction(transaction, chainId, this.connectOptions) + } + + break + } + + case 'eth_sendRawTransaction': { + // NOTE: we're not using a prompter here as the transaction is already signed + // and would have prompted the user upon signing. + + // https://eth.wiki/json-rpc/API#eth_sendRawTransaction + if (commons.transaction.isSignedTransactionBundle(request.params![0])) { + const txChainId = BigNumber.from(request.params![0].chainId).toNumber() + const tx = await account.relayer(txChainId)!.relay(request.params![0]) + response.result = tx.hash + } else { + const tx = await provider.sendTransaction(request.params![0]) + response.result = tx.hash + } + break + } + + case 'eth_getTransactionCount': { + const address = ethers.utils.getAddress(request.params![0] as string) + const tag = request.params![1] + + // TODO: Maybe we should fetch this data from the relayer or from the reader + // but for now we keep it simple and just use the provider + + const count = await provider.getTransactionCount(address, tag) + response.result = ethers.BigNumber.from(count).toHexString() + + break + } + + case 'eth_blockNumber': { + response.result = await provider.getBlockNumber() + break + } + + case 'eth_getBlockByNumber': { + response.result = await provider.getBlock(request.params![0] /* , jsonRpcRequest.params[1] */) + break + } + + case 'eth_getBlockByHash': { + response.result = await provider.getBlock(request.params![0] /* , jsonRpcRequest.params[1] */) + break + } + + case 'eth_getTransactionByHash': { + response.result = await provider.getTransaction(request.params![0]) + break + } + + case 'eth_call': { + const [transactionObject, blockTag] = request.params! + response.result = await provider.call(transactionObject, blockTag) + break + } + + case 'eth_getCode': { + const [contractAddress, blockTag] = request.params! + response.result = await provider.getCode(contractAddress, blockTag) + break + } + + case 'eth_estimateGas': { + const [transactionObject] = request.params! + response.result = await provider.estimateGas(transactionObject) + break + } + + case 'eth_gasPrice': { + const gasPrice = await provider.getGasPrice() + response.result = gasPrice.toHexString() + break + } + + case 'wallet_switchEthereumChain': { + const [switchParams] = request.params! + if (!switchParams.chainId || switchParams.chainId.length === 0) { + throw new Error('invalid chainId') + } + + const chainId = ethers.BigNumber.from(switchParams.chainId) + + this.setDefaultChainId(chainId.toNumber()) + + response.result = null // success + break + } + + // smart wallet method + case 'sequence_getWalletContext': { + response.result = account.contexts + break + } + + // smart wallet method + case 'sequence_getWalletConfig': { + const [chainId] = request.params! + if (chainId) { + response.result = [(await account.status(chainId)).onChain.config] + } else { + response.result = await Promise.all( + account.networks.map(async network => { + const status = await account.status(network.chainId) + return status.onChain.config + }) + ) + } + break + } + + // smart wallet method + case 'sequence_getWalletState': { + const [chainId] = request.params! + // TODO: Add getWalletState to the Signer interface + if (chainId) { + response.result = [getLegacyWalletState(chainId, await account.status(chainId))] + } else { + response.result = await Promise.all( + account.networks.map(async network => { + const status = await account.status(network.chainId) + return getLegacyWalletState(network.chainId, status) + }) + ) + } + break + } + + // smart wallet method + case 'sequence_getNetworks': { + // NOTE: must ensure that the response result below returns clean serialized data, which is to omit + // the provider and relayer objects and only return the urls so can be reinstantiated on dapp side. + // This is handled by this.getNetworks() but noted here for future readers. + response.result = await this.getNetworks(true) + break + } + + case 'sequence_isSequence': { + response.result = true + break + } + + // smart wallet method + case 'sequence_updateConfig': { + throw new Error('sequence_updateConfig method is not allowed from a dapp') + // NOTE: method is disabled as we don't need a dapp to request to update a config. + // However, if we ever want this, we can enable it but must also use the prompter + // for confirmation. + // + // const [newConfig] = request.params + // response.result = await signer.updateConfig(newConfig) + break + } + + // smart wallet method + case 'sequence_publishConfig': { + throw new Error('sequence_publishConfig method is not allowed from a dapp') + break + } + + // relayer method + case 'sequence_gasRefundOptions': { + // TODO + break + } + + // relayer method + case 'sequence_getNonce': { + // TODO + break + } + + // relayer method + case 'sequence_relay': { + // TODO + break + } + + // set default network of wallet + case 'sequence_setDefaultNetwork': { + const [defaultChainId] = request.params! + + if (!defaultChainId) { + throw new Error('invalid request, method argument defaultChainId cannot be empty') + } + + this.setDefaultChainId(defaultChainId) + response.result = await this.getNetworks(true) + break + } + + default: { + if (!jsonRpcProvider) { + throw new Error(`Account provider doesn't support send method`) + } + + // NOTE: provider here will be chain-bound if chainId is provided + const providerResponse = await jsonRpcProvider.send(request.method, request.params!) + response.result = providerResponse + } + } + } catch (err) { + logger.error(err) + + // See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1193.md#rpc-errors + response.result = null + response.error = { + ...new Error(err), + code: 4001 + } + } + + callback(undefined, response) + } + + on(event: K, fn: ProviderEventTypes[K]) { + this.events.on(event, fn as any) + } + + once(event: K, fn: ProviderEventTypes[K]) { + this.events.once(event, fn as any) + } + + async getAddress(): Promise { + return this.account?.address ?? '' + } + + get openIntent(): OpenWalletIntent | undefined { + return this._openIntent + } + + setOpenIntent(intent: OpenWalletIntent | undefined) { + this._openIntent = intent + } + + get connectOptions(): ConnectOptions | undefined { + return this._connectOptions + } + + setConnectOptions(options: ConnectOptions | undefined) { + this._connectOptions = options + + this.onConnectOptionsChange?.(options) + } + + async setDefaultChainId(chainId: number): Promise { + await this.prompter?.promptChangeNetwork(chainId) + return this.defaultChainId() + } + + async getNetworks(jsonRpcResponse?: boolean): Promise { + if (!this.account) { + logger.warn('signer not set: getNetworks is returning an empty list') + return [] + } + + if (jsonRpcResponse) { + // omit provider and relayer objects as they are not serializable + return this.account.networks.map(n => { + const network: NetworkConfig = { ...n } + network.provider = undefined + network.relayer = undefined + return network + }) + } else { + return this.account.networks + } + } + + walletSession(networkId?: ChainIdLike): WalletSession | undefined { + if (!this.account) { + return undefined + } + + const session = { + walletContext: this.account.contexts, + accountAddress: this.account.address, + // The dapp shouldn't access the relayer directly, and the provider (as an object) is not serializable. + networks: this.account.networks.map(n => ({ ...n, provider: undefined, relayer: undefined })) + } + + if (networkId) { + const network = findNetworkConfig(session.networks, networkId) + + if (network) { + // Delete the isDefaultChain property from the session network + session.networks?.forEach(n => delete n.isDefaultChain) + + // Add the isDefaultChain property to the network with the given networkId + network.isDefaultChain = true + } + } + + return session + } + + notifyConnect(connectDetails: ConnectDetails, origin?: string) { + console.log('emit connect', connectDetails) + this.events.emit('connect', connectDetails) + if (connectDetails.session?.accountAddress) { + this.events.emit('accountsChanged', [connectDetails.session?.accountAddress], origin) + } + } + + notifyDisconnect(origin?: string) { + this.events.emit('accountsChanged', [], origin) + this.events.emit('disconnect', undefined, origin) + } + + notifyChainChanged(chainId: number, origin?: string) { + this.events.emit('chainChanged', ethers.utils.hexValue(chainId), origin) + } + + async notifyNetworks(networks?: NetworkConfig[]) { + const n = networks || (await this.getNetworks(true)) + this.events.emit('networks', n) + if (n.length > 0) { + const defaultNetwork = n.find(network => network.chainId === this.defaultChainId()) + if (defaultNetwork) { + this.events.emit('chainChanged', ethers.utils.hexValue(defaultNetwork.chainId)) + } + } else { + this.events.emit('chainChanged', '0x0') + } + } + + async notifyWalletContext() { + if (!this.account) { + logger.warn('signer not set: skipping to notify wallet context') + return + } + const walletContext = this.account.contexts + this.events.emit('walletContext', walletContext) + } + + notifyClose(error?: ProviderRpcError) { + this.events.emit('close', error) + } + + isSignedIn = async (): Promise => { + await this.signerReady() + return !!this.account + } + + getAccount = async (): Promise => { + await this.signerReady() + if (this.account === undefined) { + throw new Error('signerReady failed resolve') + } + return this.account + } + + setAccount(account: Account | null | undefined) { + this.account = account + + if (account !== undefined) { + for (let i = 0; i < this.signerReadyCallbacks.length; i++) { + this.signerReadyCallbacks[i]() + } + this.signerReadyCallbacks = [] + } + } + + private async handleConfirmWalletDeployPrompt( + prompter: WalletUserPrompter, + account: Account, + sequenceVerified: boolean, + chainId?: number + ): Promise { + // check if wallet is deployed and up to date, if not, prompt user to deploy + // if no chainId is provided, we'll assume the wallet is auth chain wallet and is up to date + if (!chainId) { + return true + } + + const skipsDeploy = (status: AccountStatus) => { + return status.canOnchainValidate || (status.original.version === 2 && sequenceVerified) + } + + const status = await account.status(chainId) + if (skipsDeploy(status)) { + return true + } + + const promptResult = await prompter.promptConfirmWalletDeploy(chainId, this.connectOptions) + + // if client returned true, check again to make sure wallet is deployed and up to date + if (promptResult) { + const status2 = await account.status(chainId) + + if (skipsDeploy(status2)) { + return true + } else { + logger.error('WalletRequestHandler: result for promptConfirmWalletDeploy is not correct') + return false + } + } + + return false + } +} + +export interface WalletUserPrompter { + getDefaultChainId(): number + + promptConnect(options?: ConnectOptions): Promise + promptSignInConnect(options?: ConnectOptions): Promise + + promptSignMessage(message: MessageToSign, options?: ConnectOptions): Promise + promptSignTransaction(txn: commons.transaction.Transactionish, chainId?: number, options?: ConnectOptions): Promise + promptSendTransaction(txn: commons.transaction.Transactionish, chainId?: number, options?: ConnectOptions): Promise + promptConfirmWalletDeploy(chainId: number, options?: ConnectOptions): Promise + + promptChangeNetwork(chainId: number): Promise +} + +interface LegacyWalletState { + context: commons.context.WalletContext + config?: commons.config.Config + + // the wallet address + address: string + + // the chainId of the network + chainId: number + + // whether the wallet has been ever deployed + deployed: boolean + + // the imageHash of the `config` WalletConfig + imageHash: string + + // the last imageHash of a WalletConfig, stored on-chain + lastImageHash?: string + + // whether the WalletConfig object itself has been published to logs + published?: boolean + + status: AccountStatus +} + +function getLegacyWalletState(chainId: number, status: AccountStatus): LegacyWalletState { + return { + context: status.original.context, + config: status.onChain.config, + address: commons.context.addressOf(status.original.context, status.original.imageHash), + chainId, + deployed: status.onChain.deployed, + imageHash: status.imageHash, + lastImageHash: status.onChain.imageHash, + published: true, + status + } +} + +const permittedJsonRpcMethods = [ + 'net_version', + 'eth_chainId', + 'eth_getBalance', + 'eth_getTransactionCount', + 'eth_blockNumber', + 'eth_getBlockByNumber', + 'eth_getBlockByHash', + 'eth_getTransactionByHash', + 'eth_getCode', + 'eth_estimateGas', + 'eth_gasPrice', + + 'sequence_getWalletContext', + 'sequence_getNetworks', + 'sequence_setDefaultNetwork' +] diff --git a/packages/provider/src/transports/window-transport/index.ts b/packages/provider/src/transports/window-transport/index.ts new file mode 100644 index 0000000000..c286e86a5f --- /dev/null +++ b/packages/provider/src/transports/window-transport/index.ts @@ -0,0 +1,2 @@ +export * from './window-message-provider' +export * from './window-message-handler' diff --git a/packages/provider/src/transports/window-transport/window-message-handler.ts b/packages/provider/src/transports/window-transport/window-message-handler.ts new file mode 100644 index 0000000000..4336547b72 --- /dev/null +++ b/packages/provider/src/transports/window-transport/window-message-handler.ts @@ -0,0 +1,168 @@ +import { + ProviderMessageRequest, + ProviderMessage, + EventType, + InitState, + WindowSessionParams, + OpenWalletIntent, + ProviderRpcError, + TransportSession +} from '../../types' +import { WalletRequestHandler } from '../wallet-request-handler' +import { BaseWalletTransport } from '../base-wallet-transport' +import { logger, sanitizeNumberString, base64DecodeObject } from '@0xsequence/utils' + +export class WindowMessageHandler extends BaseWalletTransport { + protected parentWindow: Window + + private _isPopup: boolean = false + + constructor(walletRequestHandler: WalletRequestHandler) { + super(walletRequestHandler) + this._init = InitState.NIL + } + + async register(windowHref?: any) { + const isPopup = parent.window.opener !== null + this._isPopup = isPopup + if (isPopup !== true) { + return + } + + // record open details (sessionId + default network) from the window url + const { pathname, search: rawParams } = new URL(windowHref || window.location.href) + + let session: TransportSession | null = this.getWindowTransportSession(rawParams) + + // provider should always include sid when opening a new window + const isNewWindowSession = !!session.sessionId + + // attempt to restore previous session in the case of a redirect or window reload + if (!isNewWindowSession) { + session = await this.getCachedTransportSession() + } + + if (!session) { + logger.error('window session is undefined') + return + } + + // record parent window instance for communication + this.parentWindow = parent.window.opener + + // listen for window-transport requests + window.addEventListener('message', this.onWindowEvent, false) + this._registered = true + + // send open event to the app which opened us + this.open(session) + .then(opened => { + if (!opened) { + const err = `failed to open to network ${session?.networkId}` + logger.error(err) + this.notifyClose({ message: err } as ProviderRpcError) + window.close() + } + }) + .catch(e => { + const err = `failed to open to network ${session?.networkId}, due to: ${e}` + logger.error(err) + this.notifyClose({ message: err } as ProviderRpcError) + window.close() + }) + } + + unregister() { + window.removeEventListener('message', this.onWindowEvent) + this._registered = false + } + + // onmessage is called when (the wallet) receives request messages from the dapp + // over the window post-messaging transport + private onWindowEvent = async (event: MessageEvent) => { + if (!event.origin || event.origin === '') { + // skip same-origin or when event.origin is empty/undefined + return + } + if (this.appOrigin && event.origin !== this.appOrigin) { + // skip message as not from expected app origin + return + } + + // Wallet always expects json-rpc request messages from a dapp + let request: ProviderMessageRequest + try { + request = JSON.parse(event.data) + } catch (err) { + // event is not a ProviderMessage JSON object, skip + return + } + + logger.debug('RECEIVED MESSAGE', request) + + // Record event origin for valid init ack + if (this._init !== InitState.OK && this.isValidInitAck(request)) { + this.appOrigin = event.origin + } + if (this._init === InitState.OK && (!this.appOrigin || this.appOrigin.length < 8)) { + // impossible state + logger.error('impossible state, init.OK and appOrigin required') + return + } + + // Handle message via the base transport + this.handleMessage(request) + } + + // postMessage sends message to the dapp window + sendMessage(message: ProviderMessage) { + // prepare payload + const payload = JSON.stringify(message) + + // post-message to app. + // only for init requests, we send to '*' origin + if (message.type === EventType.INIT) { + this.postMessage(payload, true) + } else { + this.postMessage(payload) + } + } + + get isPopup(): boolean { + return this._isPopup + } + + private postMessage(message: any, init = false) { + if (init !== true && this._init !== InitState.OK) { + logger.error('impossible state, should not be calling postMessage until inited') + return + } + + if (init) { + // init message transmission. If we already know the app origin, restrict to it; + // do not fall back to a global target, to avoid leaking sensitive data. + if (this.appOrigin && this.appOrigin.length > 4) { + this.parentWindow.postMessage(message, this.appOrigin) + } else { + logger.error('unable to postMessage init message as appOrigin is invalid or unavailable') + } + } else { + // open message transmission + if (this.appOrigin && this.appOrigin.length > 4) { + // just above '.com' + this.parentWindow.postMessage(message, this.appOrigin) + } else { + logger.error('unable to postMessage as parentOrigin is invalid') + } + } + } + + private getWindowTransportSession = (windowParams: string | undefined): TransportSession => { + const params = new WindowSessionParams(windowParams) + return { + sessionId: params.get('sid'), + networkId: params.get('net'), + intent: base64DecodeObject(params.get('intent')) + } + } +} diff --git a/packages/provider/src/transports/window-transport/window-message-provider.ts b/packages/provider/src/transports/window-transport/window-message-provider.ts new file mode 100644 index 0000000000..5256214d13 --- /dev/null +++ b/packages/provider/src/transports/window-transport/window-message-provider.ts @@ -0,0 +1,197 @@ +import { OpenWalletIntent, ProviderMessage, InitState, EventType, WindowSessionParams } from '../../types' +import { BaseProviderTransport } from '../base-provider-transport' +import { logger, base64EncodeObject } from '@0xsequence/utils' +import { isBrowserExtension, isUnityPlugin } from '../../utils' + +// .. +let registeredWindowMessageProvider: WindowMessageProvider | undefined + +export class WindowMessageProvider extends BaseProviderTransport { + private walletURL: URL + private walletWindow: Window | null + + constructor(walletAppURL: string) { + super() + this.walletURL = new URL(walletAppURL) + } + + register = () => { + if (registeredWindowMessageProvider) { + // overriding the registered message provider + registeredWindowMessageProvider.unregister() + registeredWindowMessageProvider = this + } + + // listen for incoming messages from wallet + window.addEventListener('message', this.onWindowEvent) + registeredWindowMessageProvider = this + + // open heartbeat + this.on('open', () => { + // Heartbeat to track if window closed + const popup = this.walletWindow + const interval = setInterval(() => { + if (popup && popup.closed) { + clearInterval(interval) + this.close() + } + }, 500) + }) + + // close clean up + this.on('close', () => { + if (this.walletWindow) { + this.walletWindow.close() + this.walletWindow = null + } + }) + + this._registered = true + } + + unregister = () => { + this._registered = false + this.closeWallet() + + // disable message listener + if (registeredWindowMessageProvider === this) { + registeredWindowMessageProvider = undefined + } + window.removeEventListener('message', this.onWindowEvent) + + // clear event listeners + this.events.removeAllListeners() + } + + openWallet = (path?: string, intent?: OpenWalletIntent, networkId?: string | number): void => { + if (this.walletWindow && this.isOpened()) { + // TODO: update the location of window to path + this.walletWindow.focus() + return + } + + // Instantiate new walletURL for this call + const walletURL = new URL(this.walletURL.href) + const windowSessionParams = new WindowSessionParams() + + if (path && path !== '') { + walletURL.pathname = path.toLowerCase() + } + + // Set session, intent and network id on walletURL + this._init = InitState.NIL + this._sessionId = `${performance.now()}` + windowSessionParams.set('sid', this._sessionId) + + if (intent) { + // for the window-transport, we eagerly/optimistically set the origin host + // when connecting to the wallet, however, this will be verified and enforced + // on the wallet-side, so if a dapp provides the wrong origin, it will be dropped. + if (intent.type === 'connect') { + if (!intent.options) + intent.options = { + app: window.location.origin + } + + // skip setting origin host if we're in an browser extension execution context + // allow origin that is passed in + if (!isBrowserExtension() && !isUnityPlugin() && intent.options) { + intent.options.origin = window.location.origin + } + } + // encode intent as base64 url-encoded param + windowSessionParams.set('intent', base64EncodeObject(intent)) + } + if (networkId) { + windowSessionParams.set('net', `${networkId}`) + } + + // Open popup window on center of the app window + let windowSize: number[] + let windowPos: number[] + + if (isBrowserExtension()) { + windowSize = [450, 750] + windowPos = [Math.abs(window.screen.width / 2 - windowSize[0] / 2), Math.abs(window.screen.height / 2 - windowSize[1] / 2)] + } else { + windowSize = [450, 750] + windowPos = [ + Math.abs(window.screenX + window.innerWidth / 2 - windowSize[0] / 2), + Math.abs(window.screenY + window.innerHeight / 2 - windowSize[1] / 2) + ] + } + + const windowFeatures = + `toolbar=0,location=0,menubar=0,scrollbars=yes,status=yes` + + `,width=${windowSize[0]},height=${windowSize[1]}` + + `,left=${windowPos[0]},top=${windowPos[1]}` + + // serialize params + walletURL.search = windowSessionParams.toString() + + this.walletWindow = window.open(walletURL.href, 'sequence.app', windowFeatures) + + // TODO: move this somewhere else + // TODO: perhaps we trigger a .on('openTimeout') event..? maybe.. could help. + + // Popup blocking detection and notice + // let warned = false + // const warnPopupBlocked = () => { + // if (warned) return + // warned = true + // // alert('popup is blocked! hey yo') // NOTE: for debug purposes only + // throw new Error('popup is blocked') + // } + + // const popupCheck = setTimeout(() => { + // if (!popup || popup.closed || typeof popup.closed === 'undefined') { + // // popup is definitely blocked if we reach here. + // warnPopupBlocked() + // } + // }, 1000) + + // const popupBlocked = popup === null || popup === undefined + // if (popupBlocked) { + // warnPopupBlocked() + // return + // } + } + + closeWallet() { + this.close() + this.walletWindow?.close() + } + + // onmessage, receives ProviderMessageResponse from the wallet post-message transport + private onWindowEvent = (event: MessageEvent) => { + // Security check, ensure message is coming from wallet origin url + if (event.origin !== this.walletURL.origin) { + // Safetly can skip events not from the wallet + return + } + + let message: ProviderMessage + try { + message = JSON.parse(event.data) + } catch (err) { + // event is not a ProviderMessage JSON object, skip + return + } + + if (!message) { + throw new Error('ProviderMessage object is empty') + } + + // handle message with base message provider + this.handleMessage(message) + } + + sendMessage(message: ProviderMessage) { + if (!this.walletWindow) { + logger.warn('WindowMessageProvider: sendMessage failed as walletWindow is unavailable') + return + } + const postedMessage = typeof message !== 'string' ? JSON.stringify(message) : message + this.walletWindow.postMessage(postedMessage, this.walletURL.origin) + } +} diff --git a/packages/provider/src/types.ts b/packages/provider/src/types.ts new file mode 100644 index 0000000000..60bfb26da9 --- /dev/null +++ b/packages/provider/src/types.ts @@ -0,0 +1,380 @@ +import { ETHAuthProof as AuthETHAuthProof } from '@0xsequence/auth' +import { commons } from '@0xsequence/core' +import { + ChainIdLike, + JsonRpcHandler, + JsonRpcRequest, + JsonRpcResponse, + NetworkConfig, + ProviderRpcError as NetworkProviderRpcError +} from '@0xsequence/network' +import { TypedData } from '@0xsequence/utils' + +export interface ProviderTransport extends JsonRpcHandler, ProviderMessageTransport, ProviderMessageRequestHandler { + register(): void + unregister(): void + + openWallet(path?: string, intent?: OpenWalletIntent, networkId?: string | number): void + closeWallet(): void + + isOpened(): boolean + isConnected(): boolean + + on(event: K, fn: ProviderEventTypes[K]): void + once(event: K, fn: ProviderEventTypes[K]): void + emit(event: K, ...args: Parameters): boolean + + waitUntilOpened(): Promise + waitUntilConnected(): Promise +} + +export function isProviderTransport(transport: any): transport is ProviderTransport { + return ( + transport && + typeof transport === 'object' && + typeof transport.register === 'function' && + typeof transport.unregister === 'function' && + typeof transport.openWallet === 'function' && + typeof transport.closeWallet === 'function' && + typeof transport.isOpened === 'function' && + typeof transport.isConnected === 'function' && + typeof transport.on === 'function' + ) +} + +export interface WalletTransport extends JsonRpcHandler, ProviderMessageTransport, ProviderMessageRequestHandler { + register(): void + unregister(): void + + notifyOpen(openInfo: { chainId?: string; sessionId?: string; session?: WalletSession; error?: string }): void + notifyClose(error?: ProviderRpcError): void + + notifyConnect(connectDetails: ConnectDetails): void + notifyAccountsChanged(accounts: string[]): void + notifyChainChanged(chainIdHex: string): void + notifyNetworks(networks: NetworkConfig[]): void +} + +export interface ProviderMessage { + idx: number // message id number + type: string // message type + data: T // the ethereum json-rpc payload + chainId?: number // chain id which the message is intended + origin?: string // origin of the message +} + +export type ProviderMessageRequest = ProviderMessage + +export type ProviderMessageResponse = ProviderMessage + +// ProviderMessageCallback is used to respond to ProviderMessage requests. The error +// argument is for exceptions during the execution, and response is the response payload +// which may contain the result or an error payload from the wallet. +export type ProviderMessageResponseCallback = (error?: ProviderRpcError, response?: ProviderMessageResponse) => void + +export type ProviderRpcError = NetworkProviderRpcError + +export interface ProviderMessageRequestHandler { + // sendMessageRequest sends a ProviderMessageRequest over the wire to the wallet. + // This method is similar to `sendMessage`, but it expects a response to this message. + sendMessageRequest(message: ProviderMessageRequest): Promise +} + +export interface ProviderMessageTransport { + // handleMessage will handle a message received from the remote wallet + handleMessage(message: ProviderMessage): void + + // sendMessage will send the provider message over the wire + sendMessage(message: ProviderMessage): void +} + +export type WindowSessionParam = 'sid' | 'net' | 'intent' + +// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging +export interface WindowSessionParams extends URLSearchParams { + get(name: WindowSessionParam): string | null + set(name: WindowSessionParam, value: string): void +} + +// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging +export class WindowSessionParams extends URLSearchParams { + static new(init?: Record | string) { + return new URLSearchParams(init) as WindowSessionParams + } +} + +export interface TransportSession { + sessionId?: string | null + networkId?: string | number | null + intent?: OpenWalletIntent +} + +export enum EventType { + OPEN = 'open', + CLOSE = 'close', + + MESSAGE = 'message', + CONNECT = 'connect', + DISCONNECT = 'disconnect', + ACCOUNTS_CHANGED = 'accountsChanged', + CHAIN_CHANGED = 'chainChanged', + + NETWORKS = 'networks', + WALLET_CONTEXT = 'walletContext', + + INIT = 'init', + DEBUG = '_debug' +} + +export interface WalletEventTypes { + open: (openInfo: { chainId?: string; sessionId?: string; session?: WalletSession; error?: string }) => void + close: (error?: ProviderRpcError) => void + + connect: (connectDetails: ConnectDetails) => void + disconnect: (error?: ProviderRpcError, origin?: string) => void + + accountsChanged: (accounts: string[], origin?: string) => void + chainChanged: (chainIdHex: string, origin?: string) => void + + networks: (networks: NetworkConfig[]) => void + walletContext: (walletContext: commons.context.VersionedContext) => void +} + +export interface ProviderEventTypes extends WalletEventTypes { + message: (message: ProviderMessageResponse) => void +} + +export enum OpenState { + CLOSED = 0, + OPENING = 1, + OPENED = 2 +} + +export enum InitState { + NIL = 0, + SENT_NONCE = 1, + OK = 2 +} + +export interface ConnectOptions { + /** app name of the dapp which will be announced to user on connect screen */ + app: string + + /** custom protocol for auth redirect (unity/unreal) */ + appProtocol?: string + + /** origin hint of the dapp's host opening the wallet. This value will automatically + * be determined and verified for integrity, and can be omitted. */ + origin?: string + + /** access key for the project that can be obtained from Sequence Builder on sequence.build. + * This value will be automatically populated using the key passed in initWallet. */ + projectAccessKey?: string + + /** expiry number (in seconds) that is used for ETHAuth proof. Default is 1 week in seconds. */ + expiry?: number + + /** authorize will perform an ETHAuth eip712 signing and return the proof to the dapp. */ + authorize?: boolean + + /** authorizeNonce is an optional number to be passed as ETHAuth's nonce claim for replay protection. **/ + authorizeNonce?: number + + /** authorizeVersion is the version of the SDK that will validate the ETHAuth proof. */ + authorizeVersion?: number + + /** askForEmail will prompt to give permission to the dapp to access email address */ + askForEmail?: boolean + + /** refresh flag will force a full re-connect (ie. disconnect then connect again) */ + refresh?: boolean + + /** keepWalletOpened will keep the wallet window opened after connecting. The default + * is to automatically close the wallet after connecting. */ + keepWalletOpened?: boolean + + /** clientVersion is the sequence.js version of the dapp client. */ + clientVersion?: string + + /** Options to further customize the wallet experience. */ + settings?: Settings +} + +export interface NetworkedConnectOptions extends ConnectOptions { + /** chainId is the chainId to connect to. If not specified, the default chainId + * will be used. This does not define a default chain id, it is only used for the connect + * authorization signature. */ + networkId?: string | number +} + +/** Options to further customize the wallet experience. */ +export interface Settings { + /** Specify a wallet theme. `light` and `dark` are the main themes, to use other available + * themes, you can use the camel case version of the theme names in the wallet settings. + * For example: "Blue Dark" on wallet UI can be passed as "blueDark". + * Note that this setting will not be persisted, use wallet.open with 'openWithOptions' intent + * to set when you open the wallet for user. */ + theme?: ThemeOption + + /** Specify a banner image. This image, if provided, will be displayed on the wallet during + * the connect/authorize process */ + bannerUrl?: string + + bannerSize?: BannerSize + + /** Specify payment providers to use. If not specified, + * all available payment providers will be enabled. + * Note that this setting will not be persisted, use wallet.open with 'openWithOptions' intent + * to set when you open the wallet for user. */ + includedPaymentProviders?: PaymentProviderOption[] + + /** Specify a default currency to use with payment providers. + * If not specified, the default is USDC. + * Note that this setting will not be persisted, use wallet.open with 'openWithOptions' intent + * to set when you open the wallet for user. */ + defaultFundingCurrency?: CurrencyOption + + /** Specify default purchase amount as an integer, for prefilling the funding amount. + * If not specified, the default is 100. + * Note that this setting will not be persisted, use wallet.open with 'openWithOptions' intent + * to set when you open the wallet for user. */ + defaultPurchaseAmount?: number + + /** If true, lockFundingCurrencyToDefault disables picking any currency provided by payment + * providers other than the defaultFundingCurrency. + * If false, it allows picking any currency provided by payment providers. + * The default is true. + * Note that this setting will not be persisted, use wallet.open with 'openWithOptions' intent + * to set when you open the wallet for user. */ + lockFundingCurrencyToDefault?: boolean + + /** Specify an auth provider to allow dapp to specify ahead of time which auth method to redirect to. + * Will be ignored if user is already signed in. + */ + signInWith?: SignInOption + + /** Specify an email address to allow user automatically sign in with the email option. + * Will be ignored if user is already signed in. + */ + signInWithEmail?: string + + /** Specify which sign in options are allowed. + * Will be ignored if user is already signed in. + */ + signInOptions?: SignInOption[] + + /** Specify auxiliary data + */ + aux?: any +} + +/** light and dark are the main themes, to use other themes in wallet settings, + * you can use the camel case version of the name in the wallet settings. + * For example: "Blue Dark" on wallet UI can be passed as "blueDark" */ +export type ThemeOption = 'light' | 'dark' | string +export type PaymentProviderOption = 'ramp' | 'moonpay' | 'transak' | 'onmeta' | 'paytrie' | 'sardine' +export type CurrencyOption = 'usdc' | 'eth' | 'matic' +export type SignInOption = 'email' | 'google' | 'apple' | 'facebook' | 'discord' | 'twitch' +export type BannerSize = 'small' | 'medium' // | 'large' + +export interface ConnectDetails { + // chainId (in hex) and error are defined by EIP-1193 expected fields + chainId?: string + error?: string + + // connected flag denotes user-accepted the connect request + connected: boolean + + // session include account and network information needed by the dapp wallet provider. + session?: WalletSession + + // proof is a signed typedData (EIP-712) payload using ETHAuth domain. + // NOTE: the proof is signed to the `authChainId`, as the canonical auth chain. + proof?: ETHAuthProof + + // email address provided from wallet to the dapp, as request + accepted + // by a user during a connect request + email?: string +} + +export type PromptConnectDetails = Pick + +export type OpenWalletIntent = + | { type: 'connect'; options?: NetworkedConnectOptions } + | { type: 'openWithOptions'; options?: ConnectOptions } + | { type: 'jsonRpcRequest'; method: string } + +export interface MessageToSign { + message?: Uint8Array + typedData?: TypedData + chainId?: number + + eip6492?: boolean +} + +export type ETHAuthProof = AuthETHAuthProof + +export interface WalletSession { + // Wallet context + walletContext?: commons.context.VersionedContext + + // Account address of the wallet + accountAddress?: string + + // Networks in use for the session. The default/dapp network will show + // up as the first one in the list as the "main chain" + networks?: NetworkConfig[] +} + +export class ProviderError extends Error { + constructor(message?: string) { + super(message) + this.name = 'ProviderError' + } +} + +export const ErrSignedInRequired = new ProviderError('Wallet is not signed in. Connect a wallet and try again.') + +// TODO: lets build some nice error handling tools, prob in /utils ... + +export interface TypedEventEmitter { + addListener(event: E, listener: Events[E]): this + on(event: E, listener: Events[E]): this + once(event: E, listener: Events[E]): this + prependListener(event: E, listener: Events[E]): this + prependOnceListener(event: E, listener: Events[E]): this + + off(event: E, listener: Events[E]): this + removeAllListeners(event?: E): this + removeListener(event: E, listener: Events[E]): this + + emit(event: E, ...args: Arguments): boolean + eventNames(): (keyof Events | string | symbol)[] + listeners(event: E): Function[] + listenerCount(event: E): number +} + +type Arguments = [T] extends [(...args: infer U) => any] ? U : [T] extends [void] ? [] : [T] + +export type OptionalChainIdLike = + | { + chainId?: ChainIdLike + } + | undefined + +export type OptionalChainId = + | { + chainId?: number + } + | undefined + +export type OptionalEIP6492 = + | { + eip6492?: boolean + } + | undefined + +// This is required by viem, it expects a provider to have an EIP-1193 compliant `request` attribute. +export interface EIP1193Provider { + request: (request: { method: string; params?: Array }) => Promise +} diff --git a/packages/provider/src/utils.ts b/packages/provider/src/utils.ts new file mode 100644 index 0000000000..615ba0215d --- /dev/null +++ b/packages/provider/src/utils.ts @@ -0,0 +1,212 @@ +import { ethers, BytesLike } from 'ethers' +import { messageIsExemptFromEIP191Prefix } from './eip191exceptions' +import { AccountStatus } from '@0xsequence/account' +import { commons } from '@0xsequence/core' +import { encodeMessageDigest, TypedData, encodeTypedDataDigest } from '@0xsequence/utils' + +const eip191prefix = ethers.utils.toUtf8Bytes('\x19Ethereum Signed Message:\n') + +export const messageToBytes = (message: BytesLike): Uint8Array => { + if (ethers.utils.isBytesLike(message)) { + return ethers.utils.arrayify(message) + } + + return ethers.utils.toUtf8Bytes(message) +} + +export const prefixEIP191Message = (message: BytesLike): Uint8Array => { + const messageBytes = messageToBytes(message) + if (messageIsExemptFromEIP191Prefix(messageBytes)) { + return messageBytes + } else { + return ethers.utils.concat([eip191prefix, ethers.utils.toUtf8Bytes(String(messageBytes.length)), messageBytes]) + } +} + +export const trimEIP191Prefix = (prefixedMessage: Uint8Array): Uint8Array => { + // If the message is not prefixed, we return the message as is. + if (JSON.stringify(prefixedMessage.slice(0, eip191prefix.length)) !== JSON.stringify(eip191prefix)) { + return prefixedMessage + } + + // We have two parts to remove. + // First is the EIP-191 prefix. + const ethereumSignedMessagePartSlicedArray = prefixedMessage.slice(eip191prefix.length) + + // Second is the digits added which represent length of the message without the prefix + // and we need to find the prefix that will match this. + // Here first we take the max prefix char length, and check if as a number it is bigger + // than the length of the message (since prefix is added to represent length of original message), + // if it is we remove 1 from char length, if not we keep the max prefix char length. + // As an example for the case where , if the message is 123456789, the expected prefix char is 9, with starting value 9123456789 + // the char length of the total message with the prefix is 10, so the max prefix char length we start is 2 from [1,0], and as a number 10, it is longer + // than the length of the message after removing prefix (10 - 2 = 8), so we slice 1 char less, which is 9, and we get the correct prefix. + const maxPrefixCharLength = String(ethereumSignedMessagePartSlicedArray.length).length + + let prefixCharLenght: number + let prefixAsNumber: number + + try { + prefixAsNumber = Number(ethers.utils.toUtf8String(ethereumSignedMessagePartSlicedArray.slice(0, maxPrefixCharLength))) + } catch { + prefixAsNumber = Number(ethers.utils.hexlify(ethereumSignedMessagePartSlicedArray.slice(0, maxPrefixCharLength))) + } + + if (prefixAsNumber > ethereumSignedMessagePartSlicedArray.length || !Number.isInteger(prefixAsNumber)) { + prefixCharLenght = maxPrefixCharLength - 1 + } else { + prefixCharLenght = maxPrefixCharLength + } + + const prefixRevertedMessage = ethereumSignedMessagePartSlicedArray.slice(prefixCharLenght) + + return prefixRevertedMessage +} + +export const isValidSignature = async ( + address: string, + digest: Uint8Array, + sig: string, + provider: ethers.providers.Provider +): Promise => { + const reader = new commons.reader.OnChainReader(provider) + return reader.isValidSignature(address, digest, sig) +} + +// Verify message signature +export const isValidMessageSignature = async ( + address: string, + message: string | Uint8Array, + signature: string, + provider: ethers.providers.Provider +): Promise => { + const prefixed = prefixEIP191Message(message) + const digest = encodeMessageDigest(prefixed) + return isValidSignature(address, digest, signature, provider) +} + +// Verify typedData signature +export const isValidTypedDataSignature = ( + address: string, + typedData: TypedData, + signature: string, + provider: ethers.providers.Provider +): Promise => { + return isValidSignature(address, encodeTypedDataDigest(typedData), signature, provider) +} + +export const isBrowserExtension = (): boolean => + window.location.protocol === 'chrome-extension:' || window.location.protocol === 'moz-extension:' + +export const isUnityPlugin = (): boolean => !!navigator.userAgent.match(/UnitySequence/i) + +// /** +// * Returns the status of a signer's wallet on given chain by checking wallet deployment and config status +// * +// * @param {Status} of the wallet +// */ +export const isWalletUpToDate = (status: AccountStatus): boolean => { + return status.onChain.deployed && status.fullyMigrated +} + +export interface ItemStore { + getItem(key: string): string | null + setItem(key: string, value: string): void + + removeItem(key: string): void + + onItemChange(key: string, cb: (value: string | null) => void): () => void +} + +export class MemoryItemStore implements ItemStore { + private callbacks: { key: string; cb: (value: string | null) => void }[] = [] + private store: Record = {} + + getItem(key: string): string | null { + return this.store[key] || null + } + + setItem(key: string, value: string): void { + this.store[key] = value + this.callbacks.filter(c => c.key === key).forEach(c => c.cb(value)) + } + + removeItem(key: string): void { + delete this.store[key] + } + + onItemChange(key: string, cb: (value: string | null) => void): () => void { + this.callbacks.push({ key, cb }) + + return () => { + this.callbacks = this.callbacks.filter(c => c.cb !== cb) + } + } +} + +export class LocalStorage implements ItemStore { + private callbacks: { key: string; cb: (value: string | null) => void }[] = [] + + static isAvailable(): boolean { + return typeof window === 'object' && typeof window.localStorage === 'object' + } + + constructor() { + if (!LocalStorage.isAvailable()) { + throw new Error('LocalStorage is not available') + } + + window.addEventListener('storage', e => { + const { key } = e + const cb = this.callbacks.filter(c => c.key === key) + cb.forEach(c => c.cb(this.getItem(key!))) + }) + } + + getItem(key: string): string | null { + return window.localStorage.getItem(key) + } + + setItem(key: string, value: string): void { + window.localStorage.setItem(key, value) + + // Trigger callbacks + // NOTICE: the event is not triggered on the same window + this.callbacks.filter(c => c.key === key).forEach(c => c.cb(value)) + } + + removeItem(key: string): void { + window.localStorage.removeItem(key) + + // Trigger callbacks + // NOTICE: the event is not triggered on the same window + this.callbacks.filter(c => c.key === key).forEach(c => c.cb(null)) + } + + onItemChange(key: string, cb: (value: string | null) => void): () => void { + this.callbacks.push({ key, cb }) + + return () => { + this.callbacks = this.callbacks.filter(c => c.cb !== cb) + } + } +} + +export function useBestStore(): ItemStore { + if (LocalStorage.isAvailable()) { + return new LocalStorage() + } + + return new MemoryItemStore() +} + +export async function resolveArrayProperties( + object: Readonly> | Readonly>[] +): Promise { + if (Array.isArray(object)) { + // T must include array type + return Promise.all(object.map(o => ethers.utils.resolveProperties(o))) as any + } + + return ethers.utils.resolveProperties(object) +} diff --git a/packages/provider/src/utils/index.ts b/packages/provider/src/utils/index.ts new file mode 100644 index 0000000000..73105a5d32 --- /dev/null +++ b/packages/provider/src/utils/index.ts @@ -0,0 +1,75 @@ +import { BytesLike, TypedDataDomain, TypedDataField } from 'ethers' +import { ChainIdLike } from '@0xsequence/network' +import { encodeMessageDigest, TypedData, encodeTypedDataDigest } from '@0xsequence/utils' +import { isValidSignature, prefixEIP191Message } from '../utils' +import { SequenceSigner, SingleNetworkSequenceSigner } from '../signer' + +/** + * This class is redundant with the SequenceSigner class, but it is here for now to + * maintain compatibility with the old wallet API. Eventually we should move these + * methods to the SequenceSigner class and deprecate this class. + */ +export class WalletUtils { + constructor(public signer: SequenceSigner) { + if (SingleNetworkSequenceSigner.is(signer)) { + throw new Error('WalletUtils does not support SingleNetworkSequenceSigner') + } + } + + // Sign message on a specified chain, or DefaultChain by default + signMessage(message: BytesLike, chainId?: ChainIdLike, eip6492?: boolean): Promise { + return this.signer.signMessage(message, { chainId, eip6492 }) + } + + // Sign EIP-712 TypedData on a specified chain, or DefaultChain by default + signTypedData( + domain: TypedDataDomain, + types: Record>, + message: Record, + chainId?: ChainIdLike, + eip6492?: boolean + ): Promise { + return this.signer.signTypedData(domain, types, message, { chainId, eip6492 }) + } + + // Verify signature of a digest, one of a message, typedData or other + async isValidSignature(address: string, digest: Uint8Array, signature: string, chainId: number): Promise { + return isValidSignature(address, digest, signature, this.signer.getProvider(chainId)) + } + + // Verify message signature + async isValidMessageSignature( + address: string, + message: string | Uint8Array, + signature: string, + chainId: number + ): Promise { + const provider = this.signer.getProvider(chainId) + const prefixed = prefixEIP191Message(message) + const digest = encodeMessageDigest(prefixed) + return isValidSignature(address, digest, signature, provider) + } + + // Verify typedData signature + isValidTypedDataSignature(address: string, typedData: TypedData, signature: string, chainId: number): Promise { + return this.isValidSignature(address, encodeTypedDataDigest(typedData), signature, chainId) + } + + // sendTransaction() + // sendTransactions() + + // sendETH() + // sendToken() + // sendCoin() -- sugar for sendToken() + // sendCollectible() -- sugar for sendToken() + // callContract() + + // transactionHistory() + // getReceipt() + // getLogs() + // // .. + + // validateSignature() + // recoverWalletConfig() + // recoverAddress() +} diff --git a/packages/provider/tests/client.spec.ts b/packages/provider/tests/client.spec.ts new file mode 100644 index 0000000000..7f223f62bf --- /dev/null +++ b/packages/provider/tests/client.spec.ts @@ -0,0 +1,1637 @@ +import { expect } from 'chai' +import { + OpenWalletIntent, + ProviderEventTypes, + ProviderTransport, + SequenceClient, + TypedEventEmitter, + messageToBytes, + useBestStore +} from '../src' +import { JsonRpcRequest, JsonRpcResponse, JsonRpcResponseCallback, allNetworks } from '@0xsequence/network' +import EventEmitter from 'events' +import { commons, v1, v2 } from '@0xsequence/core' +import { ethers } from 'ethers' +import { TypedData } from '@0xsequence/utils' +import { ExtendedTransactionRequest } from '../src/extended' +import packageJson from '../package.json' + +const basicMockTransport = { + on: () => {}, + register: () => {}, + unregister: () => {}, + openWallet: () => {}, + closeWallet: () => {}, + isOpened: () => false, + isConnected: () => false +} as unknown as ProviderTransport + +const sampleContext = { + [1]: { + version: 1, + factory: '0x1234', + mainModule: '0x5678', + mainModuleUpgradable: '0x213123', + guestModule: '0x634123', + + walletCreationCode: '0x112233' + }, + [4]: { + version: 4, + factory: '0x99283', + mainModule: '0x1234', + mainModuleUpgradable: '0x5678', + guestModule: '0x213123', + + walletCreationCode: '0x112233' + } +} as commons.context.VersionedContext + +describe('SequenceClient', () => { + describe('callbacks', () => { + const callbacks: TypedEventEmitter = new EventEmitter() as TypedEventEmitter + let client: SequenceClient + + beforeEach(() => { + const mockTransport = { + ...basicMockTransport, + on(event: K, fn: ProviderEventTypes[K]): void { + callbacks.on(event, fn) + } + } + + client = new SequenceClient(mockTransport as unknown as ProviderTransport, useBestStore(), 1) + }) + + it('shoud emit open event', async () => { + let called = false + + client.onOpen(() => { + called = true + }) + + callbacks.emit('open', {}) + expect(called).to.be.true + }) + + it('should emit networks event', async () => { + let called = false + + client.onNetworks(networks => { + expect(networks).to.deep.equal(allNetworks) + called = true + }) + + callbacks.emit('networks', JSON.parse(JSON.stringify(allNetworks))) + expect(called).to.be.true + }) + + it('should emit accounts changed event', async () => { + let called = false + + client.onAccountsChanged(accounts => { + expect(accounts).to.deep.equal(['0x1234', '0x5678']) + called = true + }) + + callbacks.emit('accountsChanged', ['0x1234', '0x5678']) + expect(called).to.be.true + }) + + it('should emit wallet context event', async () => { + let called = false + + client.onWalletContext(context => { + expect(context).to.deep.equal(sampleContext) + called = true + }) + + callbacks.emit('walletContext', sampleContext) + expect(called).to.be.true + }) + + it('should emit default chain id changed event', async () => { + // NOTICE: This is not handled by the transport + // this is because network switching is done client-side + // and transport is never aware of it. + let calls = 0 + + client.onDefaultChainIdChanged(chainId => { + expect(chainId).to.equal(calls === 0 ? '0x2' : '0x1') + calls++ + }) + + client.setDefaultChainId(2) + client.setDefaultChainId(1) + // Second call should not trigger event + client.setDefaultChainId(1) + + expect(calls).to.equal(2) + }) + + it('should emit close event', async () => { + let called = false + + client.onClose(() => { + called = true + }) + + callbacks.emit('close') + expect(called).to.be.true + }) + + it('should unregister callback', async () => { + let called = false + + const unregister = client.onClose(() => { + called = true + }) + + unregister() + + callbacks.emit('close') + expect(called).to.be.false + }) + + it('should emit connect event', async () => { + let callsToConnect = 0 + + client.onConnect(details => { + callsToConnect++ + expect(details).to.deep.equal({ + connected: true, + chainId: '0x1', + session: { + accountAddress: '0x1234' + }, + email: 'test@sequence.app' + }) + }) + + callbacks.emit('connect', { + connected: true, + chainId: '0x1', + session: { + accountAddress: '0x1234' + }, + email: 'test@sequence.app' + }) + + expect(callsToConnect).to.equal(1) + }) + + it('should use default chain id during connect event', async () => { + let callsToConnect = 0 + + client.onConnect(details => { + callsToConnect++ + expect(details).to.deep.equal({ + connected: true, + chainId: '0x2', + session: { + accountAddress: '0x1234' + }, + email: 'test@sequence.app' + }) + }) + + client.setDefaultChainId(2) + + callbacks.emit('connect', { + connected: true, + // This should be ignored + chainId: '0xa', + session: { + accountAddress: '0x1234' + }, + email: 'test@sequence.app' + }) + + expect(callsToConnect).to.equal(1) + }) + + it('should emit disconnect event', async () => { + let callsToDisconnect = 0 + + client.onDisconnect(details => { + callsToDisconnect++ + expect(details).to.deep.equal({ + code: 9999 + }) + }) + + callbacks.emit('disconnect', { + code: 9999 + } as any) + + expect(callsToDisconnect).to.equal(1) + }) + }) + + it('should open wallet', async () => { + let calledOpenWallet = 0 + let calledWaitUntilOpened = 0 + let calledIsOpened = 0 + + const path = 'this/is/a/test/path' + const intent = { + type: 'connect' + } as OpenWalletIntent + + const client = new SequenceClient( + { + ...basicMockTransport, + openWallet: (path: string, intent: OpenWalletIntent, chainId?: number) => { + calledOpenWallet++ + expect(path).to.equal(path) + expect(intent).to.equal(intent) + expect(chainId).to.equal(2) + return Promise.resolve(true) + }, + waitUntilOpened: async () => { + calledWaitUntilOpened++ + // delay a bit + await new Promise(resolve => setTimeout(resolve, 500)) + return { + accountAddress: ethers.Wallet.createRandom().address + } + }, + isOpened: () => { + calledIsOpened++ + return false + } + }, + useBestStore(), + { + defaultChainId: 2 + } + ) + + const result = await client.openWallet(path, intent) + expect(result).to.equal(false) + expect(calledOpenWallet).to.equal(1) + expect(calledWaitUntilOpened).to.equal(1) + expect(calledIsOpened).to.equal(1) + }) + + it('should open wallet on default chain id', async () => { + let calledOpenWallet = 0 + let calledWaitUntilOpened = 0 + let calledIsOpened = 0 + + const path = 'this/is/a/test/path' + const intent = { + type: 'connect' + } as OpenWalletIntent + + const client = new SequenceClient( + { + ...basicMockTransport, + openWallet: (path: string, intent: OpenWalletIntent, chainId?: number) => { + calledOpenWallet++ + expect(path).to.equal(path) + expect(intent).to.equal(intent) + expect(chainId).to.equal(3) + return Promise.resolve(true) + }, + waitUntilOpened: async () => { + calledWaitUntilOpened++ + // delay a bit + await new Promise(resolve => setTimeout(resolve, 500)) + return { + accountAddress: ethers.Wallet.createRandom().address + } + }, + isOpened: () => { + calledIsOpened++ + return false + } + }, + useBestStore(), + { + defaultChainId: 2 + } + ) + + client.setDefaultChainId(3) + const result = await client.openWallet(path, intent) + expect(result).to.equal(false) + expect(calledOpenWallet).to.equal(1) + expect(calledWaitUntilOpened).to.equal(1) + expect(calledIsOpened).to.equal(1) + }) + + it('should close wallet', async () => { + let calledCloseWallet = 0 + + const client = new SequenceClient( + { + ...basicMockTransport, + closeWallet: () => { + calledCloseWallet++ + } + }, + useBestStore(), + { + defaultChainId: 2 + } + ) + + client.closeWallet() + expect(calledCloseWallet).to.equal(1) + }) + + it('should handle isOpened', async () => { + let calledIsOpened = 0 + + const client = new SequenceClient( + { + ...basicMockTransport, + isOpened: () => { + calledIsOpened++ + return calledIsOpened === 1 + } + }, + useBestStore(), + { + defaultChainId: 2 + } + ) + + const result1 = client.isOpened() + expect(result1).to.equal(true) + expect(calledIsOpened).to.equal(1) + + const result2 = client.isOpened() + expect(result2).to.equal(false) + expect(calledIsOpened).to.equal(2) + }) + + it('should handle connect, isConnected and disconnect', async () => { + let calledIsOpened = 0 + let calledOpenWallet = 0 + let calledCloseWallet = 0 + let calledWaitUntilOpened = 0 + let calledWaitUntilConnected = 0 + + const session = { + accountAddress: ethers.Wallet.createRandom().address + } + + const client = new SequenceClient( + { + ...basicMockTransport, + openWallet: (path?: string, intent?: OpenWalletIntent) => { + expect(path).to.equal(undefined) + expect(intent).to.deep.equal({ + type: 'connect', + options: { + app: 'This is a test', + authorizeVersion: 2, + networkId: 2, + clientVersion: packageJson.version, + projectAccessKey: undefined + } + }) + + calledOpenWallet++ + return Promise.resolve(true) + }, + waitUntilOpened: async () => { + calledWaitUntilOpened++ + return session + }, + waitUntilConnected: async () => { + calledWaitUntilConnected++ + return { connected: true, chainId: '0xa', session } + }, + isOpened: () => { + calledIsOpened++ + return true + }, + closeWallet: () => { + calledCloseWallet++ + } + }, + useBestStore(), + { + defaultChainId: 2 + } + ) + + const result1 = client.isConnected() + expect(result1).to.equal(false) + + const result2 = await client.connect({ app: 'This is a test' }) + expect(result2.chainId).to.equal('10') + expect(result2.connected).to.equal(true) + expect(result2.session).to.equal(session) + + const result3 = client.isConnected() + expect(result3).to.equal(true) + + await client.disconnect() + + const result4 = client.isConnected() + expect(result4).to.equal(false) + + expect(calledIsOpened).to.equal(2, 'isOpened') + expect(calledOpenWallet).to.equal(1, 'openWallet') + expect(calledWaitUntilOpened).to.equal(1, 'waitUntilOpened') + expect(calledWaitUntilConnected).to.equal(1, 'waitUntilConnected') + expect(calledCloseWallet).to.equal(1, 'closeWallet') + }) + + it('should handle fail to connect', async () => { + const client = new SequenceClient( + { + ...basicMockTransport, + openWallet: () => Promise.resolve(true), + waitUntilOpened: async () => { + return { + accountAddress: ethers.Wallet.createRandom().address + } + }, + waitUntilConnected: async () => { + throw new Error('Failed to connect') + }, + isOpened: () => true + }, + useBestStore(), + { + defaultChainId: 2 + } + ) + + const result = await client.connect({ app: 'This is a test' }) + expect(result.connected).to.equal(false) + expect(result.session).to.equal(undefined) + expect(result.error).to.equal('Failed to connect') + expect(client.isConnected()).to.equal(false) + }) + + it('should handle reject connect', async () => { + const client = new SequenceClient( + { + ...basicMockTransport, + openWallet: () => Promise.resolve(true), + waitUntilOpened: async () => { + return { + accountAddress: ethers.Wallet.createRandom().address + } + }, + waitUntilConnected: async () => { + return { connected: false } + }, + isOpened: () => true + }, + useBestStore(), + { + defaultChainId: 2 + } + ) + + const result = await client.connect({ app: 'This is a test' }) + expect(result.connected).to.equal(false) + expect(result.session).to.equal(undefined) + expect(result.error).to.equal(undefined) + expect(client.isConnected()).to.equal(false) + }) + + it('should handle arbitrary send', async () => { + let calledSendAsync = 0 + + const commands = [ + { chainId: 2, req: { method: 'eth_chainId', params: [] }, res: { result: '0x1' } }, + { chainId: 2, req: { method: 'eth_accounts', params: [] }, res: { result: '0x12345' } }, + { chainId: 5, req: { method: 'eth_sendTransaction', params: [{ to: '0x1234' }] }, res: { result: '0x000' } }, + { chainId: 9, req: { method: 'non-standard', params: [{ a: 23123, b: true }] }, res: { result: '0x99' } } + ] as { chainId: number; req: JsonRpcRequest; res: JsonRpcResponse }[] + + const client = new SequenceClient( + { + ...basicMockTransport, + sendAsync: (request: JsonRpcRequest, callback: JsonRpcResponseCallback, chainId?: number) => { + calledSendAsync++ + const command = commands.shift() + expect(request).to.deep.equal(command?.req) + expect(chainId).to.equal(command?.chainId) + callback(undefined, command?.res) + } + }, + useBestStore(), + { + defaultChainId: 2 + } + ) + + expect(calledSendAsync).to.equal(0) + + const result1 = await client.send({ method: 'eth_chainId', params: [] }) + expect(result1).to.deep.equal('0x1') + expect(calledSendAsync).to.equal(1) + + const result2 = await client.send({ method: 'eth_accounts', params: [] }, 2) + expect(result2).to.deep.equal('0x12345') + expect(calledSendAsync).to.equal(2) + + const result3 = await client.send({ method: 'eth_sendTransaction', params: [{ to: '0x1234' }] }, 5) + expect(result3).to.deep.equal('0x000') + expect(calledSendAsync).to.equal(3) + + // Changing the default chainId + // should change the chainId of the request + client.setDefaultChainId(9) + + const result4 = await client.send({ method: 'non-standard', params: [{ a: 23123, b: true }] }) + expect(result4).to.deep.equal('0x99') + expect(calledSendAsync).to.equal(4) + }) + + it('should handle error during arbitrary send', async () => { + const client = new SequenceClient( + { + ...basicMockTransport, + sendAsync: (request: JsonRpcRequest, callback: JsonRpcResponseCallback, chainId?: number) => { + callback(new Error('Failed to send')) + } + }, + useBestStore(), + { + defaultChainId: 2 + } + ) + + const result = client.send({ method: 'eth_chainId', params: [] }) + await expect(result).to.be.rejectedWith('Failed to send') + }) + + it('should fail is response is empty', async () => { + const client = new SequenceClient( + { + ...basicMockTransport, + sendAsync: (request: JsonRpcRequest, callback: JsonRpcResponseCallback, chainId?: number) => { + callback(undefined, undefined) + } + }, + useBestStore(), + { + defaultChainId: 2 + } + ) + + const request = { method: 'eth_chainId', params: [] } + const result = client.send(request) + await expect(result).to.be.rejectedWith(`Got undefined response for request: ${request}`) + }) + + it('shound handle getNetworks', async () => { + // Networks are fetched once (during connect) and cached + let calledSendAsync = 0 + + const session = { + accountAddress: ethers.Wallet.createRandom().address, + networks: allNetworks, + walletContext: sampleContext + } + + const client = new SequenceClient( + { + ...basicMockTransport, + sendAsync: (request: JsonRpcRequest, callback: JsonRpcResponseCallback) => { + calledSendAsync++ + expect(request).to.deep.equal({ method: 'sequence_getNetworks' }) + callback(undefined, { + result: [ + { + chainId: 5, + name: 'test' + } + ] + } as any) + }, + openWallet: () => { + return Promise.resolve(true) + }, + waitUntilOpened: async () => { + return session + }, + waitUntilConnected: async () => { + return { connected: true, session } + }, + isOpened: () => { + return true + } + }, + useBestStore(), + { + defaultChainId: 2 + } + ) + + const result1 = client.getNetworks() + await expect(result1).to.be.rejectedWith('Sequence session not connected') + + await client.connect({ app: 'This is a test' }) + + const result2 = await client.getNetworks() + expect(result2).to.deep.equal(allNetworks) + // We fetched this data on the connect call + expect(calledSendAsync).to.equal(0) + + const result3 = await client.getNetworks() + expect(result3).to.deep.equal(allNetworks) + // We cached the data + expect(calledSendAsync).to.equal(0) + + const result4 = await client.getNetworks(true) + expect(result4).to.deep.equal([ + { + chainId: 5, + name: 'test' + } + ]) + // We forced a fetch + expect(calledSendAsync).to.equal(1) + }) + + it('should return address and accounts', async () => { + const session = { + accountAddress: ethers.Wallet.createRandom().address, + networks: allNetworks, + walletContext: sampleContext + } + + const client = new SequenceClient( + { + ...basicMockTransport, + openWallet: () => { + return Promise.resolve(true) + }, + waitUntilOpened: async () => { + return session + }, + waitUntilConnected: async () => { + return { connected: true, session } + }, + isOpened: () => { + return true + }, + closeWallet: () => {} + }, + useBestStore(), + { + defaultChainId: 2 + } + ) + + const result1 = new Promise(() => client.getAddress()) + await expect(result1).to.be.rejectedWith('Sequence session not connected') + + await client.connect({ app: 'This is a test' }) + + const result3 = client.getAddress() + expect(result3).to.equal(session.accountAddress) + + await client.disconnect() + + const result5 = new Promise(() => client.getAddress()) + await expect(result5).to.be.rejectedWith('Sequence session not connected') + }) + + it('should call sign message', async () => { + const session = { + accountAddress: ethers.Wallet.createRandom().address, + networks: allNetworks, + walletContext: sampleContext + } + + let calledSendAsync = 0 + + const requests = [ + { eip6492: false, chainId: 2, message: '0x1234', result: '0x0000' }, + { eip6492: true, chainId: 2, message: [4, 2, 9, 1], result: '0x1111' }, + { eip6492: false, chainId: 5, message: '0x9993212', result: '0x2222' }, + { eip6492: true, chainId: 6, message: [4, 2, 9, 1], result: '0x3333' } + ] as { eip6492: boolean; chainId: number; message: ethers.BytesLike; result: string }[] + + const client = new SequenceClient( + { + ...basicMockTransport, + sendAsync: (request: JsonRpcRequest, callback: JsonRpcResponseCallback, chainId?: number) => { + calledSendAsync++ + const req = requests.shift() + + if (!req) { + throw new Error('No more requests to handle') + } + + const message = ethers.utils.hexlify(messageToBytes(req.message)) + + expect(request).to.deep.equal( + { + method: req.eip6492 ? 'sequence_sign' : 'personal_sign', + params: [message, session.accountAddress] + }, + 'sendAsync request mismatch' + ) + expect(chainId).to.equal(req.chainId) + callback(undefined, { result: req.result } as any) + }, + openWallet: () => { + return Promise.resolve(true) + }, + waitUntilOpened: async () => { + return session + }, + waitUntilConnected: async () => { + return { connected: true, session } + }, + isOpened: () => { + return true + }, + closeWallet: () => {} + }, + useBestStore(), + { + defaultChainId: 2 + } + ) + + const result1 = client.signMessage('0x1234') + await expect(result1).to.be.rejectedWith('Sequence session not connected') + + await client.connect({ app: 'This is a test' }) + + const result2 = await client.signMessage('0x1234') + expect(result2).to.equal('0x0000') + + const result3 = await client.signMessage([4, 2, 9, 1], { eip6492: true, chainId: 2 }) + expect(result3).to.equal('0x1111') + + client.setDefaultChainId(5) + + const result4 = await client.signMessage('0x9993212') + expect(result4).to.equal('0x2222') + + const result5 = await client.signMessage([4, 2, 9, 1], { eip6492: true, chainId: 6 }) + expect(result5).to.equal('0x3333') + + expect(calledSendAsync).to.equal(4) + }) + + it('should call sign typed message', async () => { + const session = { + accountAddress: ethers.Wallet.createRandom().address, + networks: allNetworks, + walletContext: sampleContext + } + + let calledSendAsync = 0 + + const requests = [ + { + eip6492: false, + chainId: 2, + data: { + domain: { + name: 'App1', + version: '1', + chainId: 2, + verifyingContract: ethers.Wallet.createRandom().address + }, + types: { + Person: [ + { name: 'name', type: 'string' }, + { name: 'age', type: 'uint256' } + ] + }, + message: { + name: 'Alice', + age: '28' + } + }, + result: '0x0000' + }, + { + eip6492: true, + chainId: 2, + data: { + domain: { + name: 'App2', + version: '1.1', + chainId: 2, + verifyingContract: ethers.Wallet.createRandom().address + }, + types: { + Payment: [ + { name: 'receiver', type: 'address' }, + { name: 'amount', type: 'uint256' } + ] + }, + message: { + receiver: ethers.Wallet.createRandom().address, + amount: '100' + } + }, + result: '0x1111' + }, + { + eip6492: false, + chainId: 5, + data: { + domain: { + name: 'App3', + version: '2', + chainId: 5, + verifyingContract: ethers.Wallet.createRandom().address + }, + types: { + Agreement: [ + { name: 'firstParty', type: 'address' }, + { name: 'secondParty', type: 'address' }, + { name: 'terms', type: 'string' } + ] + }, + message: { + firstParty: ethers.Wallet.createRandom().address, + secondParty: ethers.Wallet.createRandom().address, + terms: 'Terms of the agreement here.' + } + }, + result: '0x2222' + }, + { + eip6492: true, + chainId: 6, + data: { + domain: { + name: 'App4', + version: '2.1', + chainId: 7, // This is ignored because option takes precedence + verifyingContract: ethers.Wallet.createRandom().address + }, + types: { + Sale: [ + { name: 'item', type: 'string' }, + { name: 'price', type: 'uint256' } + ] + }, + message: { + item: 'Laptop', + price: '1500' + } + }, + result: '0x3333' + }, + { + eip6492: true, + chainId: 99, + data: { + domain: { + name: 'App4', + version: '2.1', + chainId: 99, + verifyingContract: ethers.Wallet.createRandom().address + }, + types: { + Sale: [ + { name: 'item', type: 'string' }, + { name: 'price', type: 'uint256' } + ] + }, + message: { + item: 'Laptop', + price: '1500' + } + }, + result: '0x5555' + } + ] as { eip6492: boolean; chainId: number; data: TypedData; result: string }[] + + const client = new SequenceClient( + { + ...basicMockTransport, + sendAsync: (request: JsonRpcRequest, callback: JsonRpcResponseCallback, chainId?: number) => { + const req = requests[calledSendAsync] + calledSendAsync++ + + const encoded = ethers.utils._TypedDataEncoder.getPayload(req!.data.domain, req!.data.types, req!.data.message) + + expect(request).to.deep.equal({ + method: req?.eip6492 ? 'sequence_signTypedData_v4' : 'eth_signTypedData_v4', + params: [session.accountAddress, encoded] + }) + + expect(chainId).to.equal(req?.chainId) + callback(undefined, { result: req?.result } as any) + }, + openWallet: () => { + return Promise.resolve(true) + }, + waitUntilOpened: async () => { + return session + }, + waitUntilConnected: async () => { + return { connected: true, session } + }, + isOpened: () => { + return true + }, + closeWallet: () => {} + }, + useBestStore(), + { + defaultChainId: 2 + } + ) + + const result1 = client.signTypedData(requests[0].data) + await expect(result1).to.be.rejectedWith('Sequence session not connected') + + await client.connect({ app: 'This is a test' }) + + const result2 = await client.signTypedData(requests[0].data) + expect(result2).to.equal('0x0000') + + const result3 = await client.signTypedData(requests[1].data, { eip6492: true, chainId: 2 }) + expect(result3).to.equal('0x1111') + + client.setDefaultChainId(5) + + const result4 = await client.signTypedData(requests[2].data) + expect(result4).to.equal('0x2222') + + const result5 = await client.signTypedData(requests[3].data, { eip6492: true, chainId: 6 }) + expect(result5).to.equal('0x3333') + + expect(calledSendAsync).to.equal(4) + + // Should use chainId provided by typed data + const result6 = await client.signTypedData(requests[4].data, { eip6492: true }) + expect(result6).to.equal('0x5555') + }) + + it('should call send transaction', async () => { + let calledSendAsync = 0 + + const requests = [ + { + chainId: 2, + tx: { + to: '0x88E1627e95071d140Abaec34574ee4AC991295fC', + value: ethers.utils.parseEther('1.0'), + auxiliary: [] + }, + result: '0x0000' + }, + { + chainId: 2, + tx: { + to: '0xD20bC67fD6feFad616Ed6B29d6d15884E08b6D86', + value: 0, + gasLimit: 90000, + data: '0x8fe62083b9bc53178597a5a6bf55a565f1889b177607a3713bd1299aa2d4eac5458b279c87b7f85eb4e8', + auxiliary: [] + }, + result: '0x1111' + }, + { + chainId: 5, + tx: { + to: '0xf0B654137245894CAb26e56230403651B053D2Dd', + auxiliary: [] + }, + result: '0x2222' + }, + { + chainId: 6, + tx: { + to: '0x88E1627e95071d140Abaec34574ee4AC991295fC', + value: ethers.utils.parseEther('1.0'), + auxiliary: [ + { + to: '0xD20bC67fD6feFad616Ed6B29d6d15884E08b6D86', + data: '0xefc57b05025168af33d34948ddbad8bd32a2eb8857468aa492ef94de07451c4b3423080f028edebab979' + }, + { + to: '0xf0B654137245894CAb26e56230403651B053D2Dd', + value: 1 + } + ] + }, + result: '0x3333' + } + ] as { chainId: number; tx: ExtendedTransactionRequest; result: string }[] + + const client = new SequenceClient( + { + ...basicMockTransport, + sendAsync: (request: JsonRpcRequest, callback: JsonRpcResponseCallback, chainId?: number) => { + calledSendAsync++ + const req = requests.shift() + expect(request).to.deep.equal({ + method: 'eth_sendTransaction', + params: [req?.tx] + }) + expect(chainId).to.equal(req?.chainId) + callback(undefined, { result: req?.result } as any) + } + }, + useBestStore(), + { + defaultChainId: 2 + } + ) + + // NOTICE: eth_sendTransaction doesn't require the address, so we don't attempt + // to get the address, thus we don't need to connect to the wallet + // we could add an extra check, but better to avoid client-side access control + // and let the wallet handle it, so we don't have a false sense of security. + // + // const result1 = client.sendTransaction({ + // to: '0x88E1627e95071d140Abaec34574ee4AC991295fC', + // value: ethers.utils.parseEther('1.0'), + // }) + + // await expect(result1).to.be.rejectedWith('Sequence session not connected') + // await client.connect({ app: 'This is a test' }) + + const result2 = await client.sendTransaction({ + to: '0x88E1627e95071d140Abaec34574ee4AC991295fC', + value: ethers.utils.parseEther('1.0') + }) + + expect(result2).to.equal('0x0000') + + const result3 = await client.sendTransaction( + { + to: '0xD20bC67fD6feFad616Ed6B29d6d15884E08b6D86', + value: 0, + data: '0x8fe62083b9bc53178597a5a6bf55a565f1889b177607a3713bd1299aa2d4eac5458b279c87b7f85eb4e8', + gasLimit: 90000 + }, + { chainId: 2 } + ) + + expect(result3).to.equal('0x1111') + + client.setDefaultChainId(5) + + const result4 = await client.sendTransaction({ + to: '0xf0B654137245894CAb26e56230403651B053D2Dd' + }) + + expect(result4).to.equal('0x2222') + + const result5 = await client.sendTransaction( + [ + { + to: '0x88E1627e95071d140Abaec34574ee4AC991295fC', + value: ethers.utils.parseEther('1.0') + }, + { + to: '0xD20bC67fD6feFad616Ed6B29d6d15884E08b6D86', + data: '0xefc57b05025168af33d34948ddbad8bd32a2eb8857468aa492ef94de07451c4b3423080f028edebab979' + }, + { + to: '0xf0B654137245894CAb26e56230403651B053D2Dd', + value: 1 + } + ], + { chainId: 6 } + ) + + expect(result5).to.equal('0x3333') + + expect(calledSendAsync).to.equal(4) + }) + + it('should call getWalletContext', async () => { + let calledSendAsync = 0 + + const client = new SequenceClient( + { + ...basicMockTransport, + sendAsync: (request: JsonRpcRequest, callback: JsonRpcResponseCallback, chainId?: number) => { + calledSendAsync++ + expect(request).to.deep.equal({ + method: 'sequence_getWalletContext' + }) + callback(undefined, { result: sampleContext } as any) + } + }, + useBestStore(), + { + defaultChainId: 2 + } + ) + + const result = await client.getWalletContext() + expect(result).to.deep.equal(sampleContext) + expect(calledSendAsync).to.equal(1) + }) + + it('should call getOnchainWalletConfig', async () => { + let calledSendAsync = 0 + + const results = [ + { + chainId: 2, + result: v2.config.ConfigCoder.fromSimple({ + threshold: 2, + checkpoint: 0, + signers: [ + { weight: 1, address: ethers.Wallet.createRandom().address }, + { weight: 1, address: ethers.Wallet.createRandom().address } + ] + }) + }, + { + chainId: 2, + result: v2.config.ConfigCoder.fromSimple({ + threshold: 1, + checkpoint: 10, + signers: [{ weight: 1, address: ethers.Wallet.createRandom().address }] + }) + }, + { + chainId: 5, + result: v1.config.ConfigCoder.fromSimple({ + threshold: 1, + checkpoint: 0, + signers: [ + { weight: 3, address: ethers.Wallet.createRandom().address }, + { weight: 2, address: ethers.Wallet.createRandom().address }, + { weight: 3, address: ethers.Wallet.createRandom().address } + ] + }) + }, + { + chainId: 6, + result: v1.config.ConfigCoder.fromSimple({ + threshold: 1, + checkpoint: 0, + signers: [{ weight: 1, address: ethers.Wallet.createRandom().address }] + }) + } + ] as { chainId: number; result: commons.config.Config }[] + + const client = new SequenceClient( + { + ...basicMockTransport, + sendAsync: (request: JsonRpcRequest, callback: JsonRpcResponseCallback, chainId?: number) => { + const req = results[calledSendAsync] + calledSendAsync++ + expect(request).to.deep.equal({ + method: 'sequence_getWalletConfig', + params: [req?.chainId] + }) + expect(chainId).to.be.equal(req?.chainId) + callback(undefined, { result: req?.result } as any) + } + }, + useBestStore(), + { + defaultChainId: 2 + } + ) + + // NOTICE: sequence_getWalletConfig doesn't require the address, so we don't attempt + // to get the address, thus we don't need to connect to the wallet + // we could add an extra check, but better to avoid client-side access control + // and let the wallet handle it, so we don't have a false sense of security. + + const result1 = await client.getOnchainWalletConfig() + expect(result1).to.deep.equal(results[0].result) + + const result2 = await client.getOnchainWalletConfig({ chainId: 2 }) + expect(result2).to.deep.equal(results[1].result) + + client.setDefaultChainId(5) + + const result3 = await client.getOnchainWalletConfig() + expect(result3).to.deep.equal(results[2].result) + + const result4 = await client.getOnchainWalletConfig({ chainId: 6 }) + expect(result4).to.deep.equal(results[3].result) + }) + + describe('Network changes', async () => { + it('should react to default chainId change', async () => { + const store = useBestStore() + + const client1 = new SequenceClient(basicMockTransport, store, { defaultChainId: 2 }) + const client2 = new SequenceClient(basicMockTransport, store, { defaultChainId: 2 }) + + expect(client1.getChainId()).to.equal(2) + expect(client2.getChainId()).to.equal(2) + + client1.setDefaultChainId(5) + + expect(client1.getChainId()).to.equal(5) + expect(client2.getChainId()).to.equal(5) + }) + + it('should converge after default chainId change (different initial chain ids)', async () => { + const store = useBestStore() + + const client1 = new SequenceClient(basicMockTransport, store, { defaultChainId: 2 }) + const client2 = new SequenceClient(basicMockTransport, store, { defaultChainId: 5 }) + + expect(client1.getChainId()).to.equal(2) + expect(client2.getChainId()).to.equal(5) + + client1.setDefaultChainId(10) + + expect(client1.getChainId()).to.equal(10) + expect(client2.getChainId()).to.equal(10) + }) + + it('should emit an event when default chainId changes', async () => { + const store = useBestStore() + + const client1 = new SequenceClient(basicMockTransport, store, { defaultChainId: 2 }) + const client2 = new SequenceClient(basicMockTransport, store, { defaultChainId: 2 }) + + let called1 = 0 + client1.onDefaultChainIdChanged(chainId => { + called1++ + expect(chainId).to.equal('0xa') + }) + + let called2 = 0 + client2.onDefaultChainIdChanged(chainId => { + called2++ + expect(chainId).to.equal('0xa') + }) + + client1.setDefaultChainId(10) + + expect(called1).to.equal(1) + expect(called2).to.equal(1) + }) + }) + + describe('Default EIP6492', () => { + it('should default to legacy signatures', async () => { + let requests: number = 0 + + const data = { + domain: { + name: 'App1', + version: '1', + chainId: 2, + verifyingContract: ethers.Wallet.createRandom().address + }, + types: { + Person: [ + { name: 'name', type: 'string' }, + { name: 'age', type: 'uint256' } + ] + }, + message: { + name: 'Alice', + age: '28' + } + } + + const session = { + accountAddress: ethers.Wallet.createRandom().address, + networks: allNetworks, + walletContext: sampleContext + } + + const client = new SequenceClient( + { + ...basicMockTransport, + sendAsync: (request: JsonRpcRequest, callback: JsonRpcResponseCallback, chainId?: number) => { + if (requests === 0) { + expect(request.method).to.equal('personal_sign') + requests++ + callback(undefined, { result: '0x445566' } as any) + } else if (requests === 1) { + expect(request.method).to.equal('eth_signTypedData_v4') + requests++ + callback(undefined, { result: '0x112233' } as any) + } else { + expect.fail('Should not have called sendAsync') + } + }, + openWallet: () => { + return Promise.resolve(true) + }, + waitUntilOpened: async () => { + return session + }, + waitUntilConnected: async () => { + return { connected: true, session } + }, + isOpened: () => { + return true + }, + closeWallet: () => {} + }, + useBestStore() + ) + + await client.connect({ app: 'This is a test' }) + + expect(client.defaultEIP6492).to.be.false + + const result1 = await client.signMessage('0x112233') + expect(result1).to.equal('0x445566') + + const result2 = await client.signTypedData(data) + expect(result2).to.equal('0x112233') + }) + + it('should default to EIP6492 signatures', async () => { + let requests: number = 0 + + const data = { + domain: { + name: 'App1', + version: '1', + chainId: 2, + verifyingContract: ethers.Wallet.createRandom().address + }, + types: { + Person: [ + { name: 'name', type: 'string' }, + { name: 'age', type: 'uint256' } + ] + }, + message: { + name: 'Alice', + age: '28' + } + } + + const session = { + accountAddress: ethers.Wallet.createRandom().address, + networks: allNetworks, + walletContext: sampleContext + } + + const client = new SequenceClient( + { + ...basicMockTransport, + sendAsync: (request: JsonRpcRequest, callback: JsonRpcResponseCallback, chainId?: number) => { + if (requests === 0) { + expect(request.method).to.equal('sequence_sign') + requests++ + callback(undefined, { result: '0x445566' } as any) + } else if (requests === 1) { + expect(request.method).to.equal('sequence_signTypedData_v4') + requests++ + callback(undefined, { result: '0x112233' } as any) + } else { + expect.fail('Should not have called sendAsync') + } + }, + openWallet: () => { + return Promise.resolve(true) + }, + waitUntilOpened: async () => { + return session + }, + waitUntilConnected: async () => { + return { connected: true, session } + }, + isOpened: () => { + return true + }, + closeWallet: () => {} + }, + useBestStore(), + { defaultEIP6492: true } + ) + + await client.connect({ app: 'This is a test' }) + + expect(client.defaultEIP6492).to.be.true + + const result1 = await client.signMessage('0x112233') + expect(result1).to.equal('0x445566') + + const result2 = await client.signTypedData(data) + expect(result2).to.equal('0x112233') + }) + + it('should default to legacy when calling send', async () => { + let requests: number = 0 + + const data = { + domain: { + name: 'App1', + version: '1', + chainId: 2, + verifyingContract: ethers.Wallet.createRandom().address + }, + types: { + Person: [ + { name: 'name', type: 'string' }, + { name: 'age', type: 'uint256' } + ] + }, + message: { + name: 'Alice', + age: '28' + } + } + + const session = { + accountAddress: ethers.Wallet.createRandom().address, + networks: allNetworks, + walletContext: sampleContext + } + + const client = new SequenceClient( + { + ...basicMockTransport, + sendAsync: (request: JsonRpcRequest, callback: JsonRpcResponseCallback, chainId?: number) => { + if (requests === 0) { + expect(request.method).to.equal('personal_sign') + requests++ + callback(undefined, { result: '0x445566' } as any) + } else if (requests === 1) { + expect(request.method).to.equal('eth_signTypedData_v4') + requests++ + callback(undefined, { result: '0x112233' } as any) + } else { + expect.fail('Should not have called sendAsync') + } + }, + openWallet: () => { + return Promise.resolve(true) + }, + waitUntilOpened: async () => { + return session + }, + waitUntilConnected: async () => { + return { connected: true, session } + }, + isOpened: () => { + return true + }, + closeWallet: () => {} + }, + useBestStore() + ) + + await client.connect({ app: 'This is a test' }) + + expect(client.defaultEIP6492).to.be.false + + const result1 = await client.send({ method: 'personal_sign', params: ['0x112233'] }) + expect(result1).to.equal('0x445566') + + const result2 = await client.send({ method: 'eth_signTypedData_v4', params: [data] }) + expect(result2).to.equal('0x112233') + }) + + it('should default to EIP6492 when calling send', async () => { + let requests: number = 0 + + const data = { + domain: { + name: 'App1', + version: '1', + chainId: 2, + verifyingContract: ethers.Wallet.createRandom().address + }, + types: { + Person: [ + { name: 'name', type: 'string' }, + { name: 'age', type: 'uint256' } + ] + }, + message: { + name: 'Alice', + age: '28' + } + } + + const session = { + accountAddress: ethers.Wallet.createRandom().address, + networks: allNetworks, + walletContext: sampleContext + } + + const client = new SequenceClient( + { + ...basicMockTransport, + sendAsync: (request: JsonRpcRequest, callback: JsonRpcResponseCallback, chainId?: number) => { + if (requests === 0) { + expect(request.method).to.equal('sequence_sign') + requests++ + callback(undefined, { result: '0x445566' } as any) + } else if (requests === 1) { + expect(request.method).to.equal('sequence_signTypedData_v4') + requests++ + callback(undefined, { result: '0x112233' } as any) + } else { + expect.fail('Should not have called sendAsync') + } + }, + openWallet: () => { + return Promise.resolve(true) + }, + waitUntilOpened: async () => { + return session + }, + waitUntilConnected: async () => { + return { connected: true, session } + }, + isOpened: () => { + return true + }, + closeWallet: () => {} + }, + useBestStore(), + { defaultEIP6492: true } + ) + + await client.connect({ app: 'This is a test' }) + + expect(client.defaultEIP6492).to.be.true + + const result1 = await client.send({ method: 'personal_sign', params: ['0x112233'] }) + expect(result1).to.equal('0x445566') + + const result2 = await client.send({ method: 'eth_signTypedData_v4', params: [data] }) + expect(result2).to.equal('0x112233') + }) + + it('should not override method if default is not set', async () => { + let requests: number = 0 + + const data = { + domain: { + name: 'App1', + version: '1', + chainId: 2, + verifyingContract: ethers.Wallet.createRandom().address + }, + types: { + Person: [ + { name: 'name', type: 'string' }, + { name: 'age', type: 'uint256' } + ] + }, + message: { + name: 'Alice', + age: '28' + } + } + + const session = { + accountAddress: ethers.Wallet.createRandom().address, + networks: allNetworks, + walletContext: sampleContext + } + + const client = new SequenceClient( + { + ...basicMockTransport, + sendAsync: (request: JsonRpcRequest, callback: JsonRpcResponseCallback, chainId?: number) => { + if (requests === 0) { + expect(request.method).to.equal('sequence_sign') + requests++ + callback(undefined, { result: '0x445566' } as any) + } else if (requests === 1) { + expect(request.method).to.equal('sequence_signTypedData_v4') + requests++ + callback(undefined, { result: '0x112233' } as any) + } else { + expect.fail('Should not have called sendAsync') + } + }, + openWallet: () => { + return Promise.resolve(true) + }, + waitUntilOpened: async () => { + return session + }, + waitUntilConnected: async () => { + return { connected: true, session } + }, + isOpened: () => { + return true + }, + closeWallet: () => {} + }, + useBestStore() + ) + + await client.connect({ app: 'This is a test' }) + + const result1 = await client.send({ method: 'sequence_sign', params: ['0x112233'] }) + expect(result1).to.equal('0x445566') + + const result2 = await client.send({ method: 'sequence_signTypedData_v4', params: [data] }) + expect(result2).to.equal('0x112233') + }) + }) +}) diff --git a/packages/provider/tests/eip191prefix.spec.ts b/packages/provider/tests/eip191prefix.spec.ts new file mode 100644 index 0000000000..c8434bd68f --- /dev/null +++ b/packages/provider/tests/eip191prefix.spec.ts @@ -0,0 +1,22 @@ +import chaiAsPromised from 'chai-as-promised' +import * as chai from 'chai' + +import { messageIsExemptFromEIP191Prefix } from '../src/eip191exceptions' +import { dclLogin, message1, zeroExV3Order } from './messages' +const { expect } = chai.use(chaiAsPromised) + +describe('191 prefix exceptions', () => { + it('decentraland is exempt', () => { + expect(messageIsExemptFromEIP191Prefix(dclLogin)).equal(true) + }) + + it('should strip 191 prefix from 0x v3 orders', () => { + expect(messageIsExemptFromEIP191Prefix(zeroExV3Order)).equal(true) + }) + + it('should not strip 191 prefix from other messages', () => { + expect(messageIsExemptFromEIP191Prefix(message1)).equal(false) + expect(messageIsExemptFromEIP191Prefix(zeroExV3Order.slice(0, -10))).equal(false) + expect(messageIsExemptFromEIP191Prefix(dclLogin.slice(0, -10))).equal(false) + }) +}) diff --git a/packages/provider/tests/messages.ts b/packages/provider/tests/messages.ts new file mode 100644 index 0000000000..48f17a5765 --- /dev/null +++ b/packages/provider/tests/messages.ts @@ -0,0 +1,93 @@ +import { ethers } from 'ethers' +import { prefixEIP191Message } from '../src/utils' + +// Ethereum personal sign: Hello, World! +export const message1 = new Uint8Array([ + 25, 69, 116, 104, 101, 114, 101, 117, 109, 32, 83, 105, 103, 110, 101, 100, 32, 77, 101, 115, 115, 97, 103, 101, 58, 10, 49, 51, + 72, 101, 108, 108, 111, 44, 32, 87, 111, 114, 108, 100, 33 +]) + +const dclText = `Decentraland Login +Ephemeral address: 0xe1bCF3CAc83534a055f7254C1FD88B21159fCc67 +Expiration: 2022-10-27T16:03:29.191Z` + +export const dclLogin = ethers.utils.toUtf8Bytes(dclText) + +// Ethereum personal sign 0x v3 order +export const zeroExV3Order = new Uint8Array([ + 62, 254, 80, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 3, 153, 144, + 71, 27, 241, 205, 119, 186, 5, 60, 99, 148, 99, 19, 201, 174, 101, 93, 86, 211, 104, 110, 31, 232, 176, 9, 52, 53, 122, 24, 41, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191, 3, 19, 123, 56, 230, 5, 28, 73, 127, 92, 7, 29, 45, 29, 189, 8, 190, 24, 26, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 55, 18, 71, 48, 244, 210, 213, 18, 72, 210, 192, 93, 42, 229, 203, 210, 136, 237, 103, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 188, 192, 42, 21, 92, 55, 66, 99, 50, 17, 85, 85, 92, 207, 65, 7, 0, 23, 100, 158, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 122, 103, 240, 255, 23, 36, 169, 85, 88, 7, 31, 44, 217, 97, 21, 252, 202, 109, 69, 32, 114, + 145, 27, 10, 160, 236, 62, 181, 81, 143, 220, 202, 36, 172, 69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, + 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 36, 148, 207, 205, 215, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 224, 182, 179, 167, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 244, 114, 97, 176, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 190, 65, 193, 52, 252, 53, 23, 203, 14, 201, 75, 110, 234, 251, 102, 207, 153, 152, 120, 47, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 36, 148, 207, 205, 215, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 13, 224, 182, 179, 167, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 244, 114, 97, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 170, 165, 185, 230, 197, 137, 100, 47, 152, 161, 205, 169, 155, 157, 2, 75, 132, 7, 40, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +]) + +// Messages for testing trim-eip191prefix + +export const trimEIP191Prefix_test1_raw = `1915 Robert Frost +The Road Not Taken + +Two roads diverged in a yellow wood, +And sorry I could not travel both +And be one traveler, long I stood +And looked down one as far as I could +To where it bent in the undergrowth + +Then took the other, as just as fair, +And having perhaps the better claim, +Because it was grassy and wanted wear +Though as for that the passing there +Had worn them really about the same, + +And both that morning equally lay +In leaves no step had trodden black. +Oh, I kept the first for another day! +Yet knowing how way leads on to way, +I doubted if I should ever come back. + +I shall be telling this with a sigh +Somewhere ages and ages hence: +Two roads diverged in a wood, and I— +I took the one less traveled by, +And that has made all the difference. + +\u2601 \u2600 \u2602` +export const trimEIP191Prefix_test2_raw = dclText +export const trimEIP191Prefix_test3_raw = '1915 Robe' // 9 chars +export const trimEIP191Prefix_test4_raw = + '123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789' // 99 chars +export const trimEIP191Prefix_test5_raw = 'Robe 1915' + +export const trimEIP191Prefix_test1_prefixed = prefixEIP191Message(trimEIP191Prefix_test1_raw) +export const trimEIP191Prefix_test2_prefixed = prefixEIP191Message(dclText) +export const trimEIP191Prefix_test3_prefixed = prefixEIP191Message(trimEIP191Prefix_test3_raw) +export const trimEIP191Prefix_test4_prefixed = prefixEIP191Message(trimEIP191Prefix_test4_raw) +export const trimEIP191Prefix_test5_prefixed = prefixEIP191Message(trimEIP191Prefix_test5_raw) diff --git a/packages/provider/tests/provider.spec.ts b/packages/provider/tests/provider.spec.ts new file mode 100644 index 0000000000..2025f62647 --- /dev/null +++ b/packages/provider/tests/provider.spec.ts @@ -0,0 +1,1743 @@ +import { ethers } from 'ethers' +import { + ConnectOptions, + OpenWalletIntent, + OptionalChainId, + SequenceClient, + SequenceProvider, + SingleNetworkSequenceProvider +} from '../src' +import { expect } from 'chai' +import { JsonRpcRequest, JsonRpcResponse, allNetworks } from '@0xsequence/network' +import { ExtendedTransactionRequest } from '../src/extended' + +const hardhat1Provider = new ethers.providers.JsonRpcProvider('http://127.0.0.1:9595') +const hardhat2Provider = new ethers.providers.JsonRpcProvider('http://127.0.0.1:8595') + +const providerFor = (chainId: number) => { + if (chainId === 31337) { + return hardhat1Provider + } + + if (chainId === 31338) { + return hardhat2Provider + } + + throw new Error(`No provider for chainId ${chainId}`) +} + +let defaultChainId: number + +let callback: (chainId: number) => void + +const onDefaultChainIdChanged = (cb: (chainId: number) => void) => { + callback = cb +} + +const setDefaultChainId = (chainId: number) => { + defaultChainId = chainId + callback(chainId) +} + +const basicMockClient = { + getChainId: () => defaultChainId, + onDefaultChainIdChanged, + setDefaultChainId, + // EIP-1193 + onConnect: () => {}, + onDisconnect: () => {}, + onAccountsChanged: () => {} +} as unknown as SequenceClient + +async function waitUntilNoFail(provider: ethers.providers.Provider, timeout = 20000): Promise { + const start = Date.now() + while (Date.now() - start < timeout) { + try { + await provider.getBlockNumber() + return + } catch (e) { + await new Promise(resolve => setTimeout(resolve, 100)) + } + } + console.warn('waitUntilNoFail timed out') +} + +describe('SequenceProvider', () => { + before(async () => { + // Wait for both providers to be ready + await Promise.all([waitUntilNoFail(hardhat1Provider), waitUntilNoFail(hardhat2Provider)]) + }) + + beforeEach(() => { + defaultChainId = 31337 + }) + + describe('client proxy methods', () => { + it('should call connect', async () => { + let callsToConnect = 0 + + const provider = new SequenceProvider( + { + ...basicMockClient, + connect: async (transport: ConnectOptions) => { + expect(transport).to.deep.equal({ app: 'test' }) + callsToConnect++ + return { connected: true } + } + } as unknown as SequenceClient, + providerFor + ) + + const res = await provider.connect({ app: 'test' }) + expect(res).to.deep.equal({ connected: true }) + expect(callsToConnect).to.equal(1) + }) + + it('should call disconnect', async () => { + let callsToDisconnect = 0 + + const provider = new SequenceProvider( + { + ...basicMockClient, + disconnect: async () => { + callsToDisconnect++ + } + } as unknown as SequenceClient, + providerFor + ) + + await provider.disconnect() + expect(callsToDisconnect).to.equal(1) + }) + + it('should call isConnected', async () => { + let callsToIsConnected = 0 + + const provider = new SequenceProvider( + { + ...basicMockClient, + isConnected: () => { + callsToIsConnected++ + return true + } + } as unknown as SequenceClient, + providerFor + ) + + const res = provider.isConnected() + expect(res).to.equal(true) + expect(callsToIsConnected).to.equal(1) + }) + + it('should call getSession', async () => { + let callsToGetSession = 0 + + const provider = new SequenceProvider( + { + ...basicMockClient, + getSession: () => { + callsToGetSession++ + return { session: 'test' } + } + } as unknown as SequenceClient, + providerFor + ) + + const res = provider.getSession() + expect(res).to.deep.equal({ session: 'test' }) + expect(callsToGetSession).to.equal(1) + }) + + it('should call getAddress', async () => { + let callsToGetAddress = 0 + + const provider = new SequenceProvider( + { + ...basicMockClient, + getAddress: () => { + callsToGetAddress++ + return '0x123' + } + } as unknown as SequenceClient, + providerFor + ) + + const res = provider.getAddress() + expect(res).to.equal('0x123') + expect(callsToGetAddress).to.equal(1) + }) + + it('should call getNetworks', async () => { + let callsToGetNetworks = 0 + + const provider = new SequenceProvider( + { + ...basicMockClient, + getNetworks: async () => { + callsToGetNetworks++ + return [{ chainId: 31337 }, { chainId: 31338 }] + } + } as unknown as SequenceClient, + providerFor + ) + + const res = await provider.getNetworks() + expect(res).to.deep.equal([{ chainId: 31337 }, { chainId: 31338 }]) + expect(callsToGetNetworks).to.equal(1) + }) + + it('should call getChainId', async () => { + let callsToGetChainId = 0 + + const provider = new SequenceProvider( + { + ...basicMockClient, + getChainId: () => { + callsToGetChainId++ + return 31337 + } + } as unknown as SequenceClient, + providerFor + ) + + const res = provider.getChainId() + expect(res).to.equal(31337) + + // This method is also called by the constructor + expect(callsToGetChainId).to.equal(2) + }) + + it('should call setDefaultChainId', async () => { + let callsToSetDefaultChainId = 0 + + const provider = new SequenceProvider( + { + ...basicMockClient, + setDefaultChainId: (chainId: number) => { + callsToSetDefaultChainId++ + expect(chainId).to.equal(31338) + } + } as unknown as SequenceClient, + providerFor + ) + + provider.setDefaultChainId(31338) + expect(callsToSetDefaultChainId).to.equal(1) + }) + + it('should call isOpened', async () => { + let callsToIsOpened = 0 + + const provider = new SequenceProvider( + { + ...basicMockClient, + isOpened: () => { + callsToIsOpened++ + return true + } + } as unknown as SequenceClient, + providerFor + ) + + const res = provider.isOpened() + expect(res).to.equal(true) + expect(callsToIsOpened).to.equal(1) + }) + + it('should call closeWallet', async () => { + let callsToCloseWallet = 0 + + const provider = new SequenceProvider( + { + ...basicMockClient, + closeWallet: async () => { + callsToCloseWallet++ + } + } as unknown as SequenceClient, + providerFor + ) + + provider.closeWallet() + expect(callsToCloseWallet).to.equal(1) + }) + + it('should call getWalletContext', async () => { + let callsToGetWalletContext = 0 + + const provider = new SequenceProvider( + { + ...basicMockClient, + getWalletContext: async () => { + callsToGetWalletContext++ + return { walletContext: 'test' } + } + } as unknown as SequenceClient, + providerFor + ) + + const res = await provider.getWalletContext() + expect(res).to.deep.equal({ walletContext: 'test' }) + expect(callsToGetWalletContext).to.equal(1) + }) + + it('should call getWalletConfig', async () => { + let callsToGetWalletConfig = 0 + + const provider = new SequenceProvider( + { + ...basicMockClient, + getOnchainWalletConfig: async (options?: OptionalChainId) => { + expect(options).to.deep.equal({ chainId: 31338 }) + callsToGetWalletConfig++ + return { walletConfig: 'test' } + } + } as unknown as SequenceClient, + providerFor + ) + + const res = await provider.getWalletConfig('hardhat2') + expect(res).to.deep.equal({ walletConfig: 'test' }) + expect(callsToGetWalletConfig).to.equal(1) + }) + + it('should call connect + authorize', async () => { + let callsToConnect = 0 + + const provider = new SequenceProvider( + { + ...basicMockClient, + connect: async (transport: ConnectOptions) => { + expect(transport).to.deep.equal({ app: 'test', authorize: true }) + callsToConnect++ + return { connected: true } + } + } as unknown as SequenceClient, + providerFor + ) + + const res = await provider.authorize({ app: 'test' }) + expect(res).to.deep.equal({ connected: true }) + expect(callsToConnect).to.equal(1) + }) + + it('should call openWallet', async () => { + let callsToOpenWallet = 0 + + const provider = new SequenceProvider( + { + ...basicMockClient, + openWallet: (path: string, intent: OpenWalletIntent) => { + expect(path).to.equal('/test') + expect(intent).to.deep.equal({ type: 'connect' }) + callsToOpenWallet++ + } + } as unknown as SequenceClient, + providerFor + ) + + await provider.openWallet('/test', { type: 'connect' }) + expect(callsToOpenWallet).to.equal(1) + }) + }) + + describe('provider events', () => { + let provider: SequenceProvider + + const callbacks: { [event: string]: (data: any) => void } = {} + + beforeEach(() => { + const usecb = (name: string, cb: (data: any) => any) => { + callbacks[name] = cb + return () => {} + } + + provider = new SequenceProvider( + { + ...basicMockClient, + onConnect: (c: any) => usecb('connect', c), + onDisconnect: (c: any) => usecb('disconnect', c), + onDefaultChainIdChanged: (c: any) => usecb('chainChanged', c), + onAccountsChanged: (c: any) => usecb('accountsChanged', c) + } as unknown as SequenceClient, + providerFor + ) + }) + + it('should call onConnect', async () => { + let callsToOnConnect = 0 + + provider.on('connect', (data: any) => { + callsToOnConnect++ + expect(data).to.deep.equal({ + connected: true, + chainId: '0x112233' + }) + }) + + callbacks['connect']({ + connected: true, + chainId: '0x112233' + }) + + await new Promise(resolve => setTimeout(resolve, 100)) + expect(callsToOnConnect).to.equal(1) + }) + + it('should call onDisconnect', async () => { + let callsToOnDisconnect = 0 + + provider.on('disconnect', (data: any) => { + callsToOnDisconnect++ + expect(data).to.deep.equal({ + connected: false, + error: 1000 + }) + }) + + callbacks['disconnect']({ + connected: false, + error: 1000 + }) + + await new Promise(resolve => setTimeout(resolve, 100)) + expect(callsToOnDisconnect).to.equal(1) + }) + + it('should call onDefaultChainIdChanged', async () => { + let callsToOnDefaultChainIdChanged = 0 + + provider.on('chainChanged', (data: any) => { + callsToOnDefaultChainIdChanged++ + expect(data).to.equal(31338) + }) + + callbacks['chainChanged'](31338) + + await new Promise(resolve => setTimeout(resolve, 100)) + expect(callsToOnDefaultChainIdChanged).to.equal(1) + }) + + it('should call onAccountsChanged', async () => { + let callsToOnAccountsChanged = 0 + + provider.on('accountsChanged', (data: any) => { + callsToOnAccountsChanged++ + expect(data).to.deep.equal(['0x123']) + }) + + callbacks['accountsChanged'](['0x123']) + + await new Promise(resolve => setTimeout(resolve, 100)) + expect(callsToOnAccountsChanged).to.equal(1) + }) + }) + + // This converts from "any kind" of chainId to a number + describe('toChainId', () => { + let provider: SequenceProvider + + const defaultChainId: number = 31337 + + beforeEach(() => { + provider = new SequenceProvider( + { + ...basicMockClient, + onDefaultChainIdChanged, + getChainId: () => defaultChainId + } as unknown as SequenceClient, + providerFor + ) + }) + + it('should work for numbers', () => { + expect(provider.toChainId(1)).to.equal(1) + expect(provider.toChainId(31337)).to.equal(31337) + expect(provider.toChainId(31338)).to.equal(31338) + }) + + it('should fail if network is not supported', () => { + expect(() => provider.toChainId(99999)).to.throw('Unsupported network 99999') + }) + + it('should work for number strings', () => { + expect(provider.toChainId('1')).to.equal(1) + expect(provider.toChainId('31337')).to.equal(31337) + expect(provider.toChainId('31338')).to.equal(31338) + }) + + it('should work for hex strings', () => { + expect(provider.toChainId('0x1')).to.equal(1) + expect(provider.toChainId('0x7a69')).to.equal(31337) + expect(provider.toChainId('0x7a6a')).to.equal(31338) + }) + + it('should fail if network is not supported - number string', () => { + expect(() => provider.toChainId('99999')).to.throw('Unsupported network 99999') + }) + + it('should fail if network is not supported - hex string', () => { + expect(() => provider.toChainId('0x99999')).to.throw('Unsupported network 0x99999') + }) + + it('should work for network names', () => { + expect(provider.toChainId('mainnet')).to.equal(1) + expect(provider.toChainId('rinkeby')).to.equal(4) + expect(provider.toChainId('goerli')).to.equal(5) + expect(provider.toChainId('polygon')).to.equal(137) + expect(provider.toChainId('mumbai')).to.equal(80001) + expect(provider.toChainId('polygon-zkevm')).to.equal(1101) + expect(provider.toChainId('bsc')).to.equal(56) + expect(provider.toChainId('bsc-testnet')).to.equal(97) + expect(provider.toChainId('optimism')).to.equal(10) + expect(provider.toChainId('arbitrum')).to.equal(42161) + expect(provider.toChainId('arbitrum-sepolia')).to.equal(421614) + expect(provider.toChainId('arbitrum-nova')).to.equal(42170) + expect(provider.toChainId('avalanche')).to.equal(43114) + }) + + it('should fail if network is not supported - network name', () => { + expect(() => provider.toChainId('notreallyachain')).to.throw('Unsupported network notreallyachain') + }) + + it('should work when passing a full network config', () => { + expect(provider.toChainId(allNetworks.find(n => n.chainId === 1))).to.equal(1) + expect(provider.toChainId(allNetworks.find(n => n.chainId === 31337))).to.equal(31337) + }) + + it('should fail if the passed network config doesnt exist on the provider', () => { + const fakeNetwork = { chainId: 99999, name: 'fake', rpcUrl: 'http://127.0.0.1:99999' } + expect(() => provider.toChainId(fakeNetwork)).to.throw(`Unsupported network ${fakeNetwork}`) + }) + + it('should work when passing a BigNumber', () => { + expect(provider.toChainId(ethers.BigNumber.from(1))).to.equal(1) + expect(provider.toChainId(ethers.BigNumber.from(31337))).to.equal(31337) + expect(provider.toChainId(ethers.BigNumber.from(31338))).to.equal(31338) + }) + + it('should fail if network is not supported - BigNumber', () => { + expect(() => provider.toChainId(ethers.BigNumber.from(99999))).to.throw( + `Unsupported network ${ethers.BigNumber.from(99999)}` + ) + }) + + it('should return undefined if passed undefined', () => { + expect(provider.toChainId(undefined)).to.equal(undefined) + }) + }) + + describe('getProvider (single network)', () => { + let provider: SequenceProvider + + beforeEach(() => { + provider = new SequenceProvider(basicMockClient, providerFor) + }) + + it('should return self if asked for no specific chain', () => { + expect(provider.getProvider()).to.equal(provider) + }) + + it('should not return self if asked for the current default chain', () => { + expect(provider.getProvider(provider.getChainId())).to.not.equal(provider) + }) + + it('should return specific provider if asked for a specific chain', () => { + expect(provider.getProvider(31337).getChainId()).to.equal(31337) + expect(provider.getProvider(31338).getChainId()).to.equal(31338) + }) + + it('specific provider should not be parent provider', () => { + expect(provider.getProvider(31337)).to.not.equal(provider) + }) + + it('should return same provider if asked for specific chain twice', () => { + const provider1 = provider.getProvider(31337) + const provider2 = provider.getProvider(31337) + expect(provider1).to.equal(provider2) + + const provider3 = provider.getProvider(31338) + const provider4 = provider.getProvider(31338) + expect(provider3).to.equal(provider4) + + expect(provider1).to.not.equal(provider3) + }) + + it('should fail to return provider for different chain from a specific provider', () => { + const provider1 = provider.getProvider(31337) + expect(() => provider1.getProvider(31338)).to.throw( + 'This provider only supports the network 31337, but 31338 was requested.' + ) + + const provider2 = provider.getProvider(31338) + expect(() => provider2.getProvider(31337)).to.throw( + 'This provider only supports the network 31338, but 31337 was requested.' + ) + }) + + it('specific provider should return self if asked for no specific chain', () => { + const provider1 = provider.getProvider(31337) + expect(provider1.getProvider()).to.equal(provider1) + expect(provider1).to.not.equal(provider) + expect(provider1.getProvider()).to.not.equal(provider) + }) + + it('specific provider should return self if asked for the provider of its own chain', () => { + const provider1 = provider.getProvider(31338) + expect(provider1.getProvider(31338)).to.equal(provider1) + }) + + it('should return isSingleNetworkSequenceProvider', async () => { + const main = provider.getProvider() + const single = provider.getProvider(31337) + + expect(SequenceProvider.is(main)).to.equal(true) + expect(SequenceProvider.is(single)).to.equal(true) + expect(SingleNetworkSequenceProvider.is(main)).to.equal(false) + expect(SingleNetworkSequenceProvider.is(single)).to.equal(true) + }) + }) + + describe('getSigner (single network)', () => { + let provider: SequenceProvider + + beforeEach(() => { + provider = new SequenceProvider(basicMockClient, providerFor) + }) + + it('should get signer for default chain', async () => { + const signer = provider.getSigner() + expect(await signer.getChainId()).to.equal(31337) + }) + + it('should not get same signer for default and specific chain', async () => { + const signer1 = provider.getSigner() + const signer2 = provider.getSigner(31337) + expect(signer1).to.not.equal(signer2) + }) + + it('should get signer for specific chain', async () => { + const signer = provider.getSigner(31338) + expect(await signer.getChainId()).to.equal(31338) + }) + + it('should get signer for specific chain from specific provider', async () => { + const signer = provider.getProvider(31338).getSigner() + expect(await signer.getChainId()).to.equal(31338) + }) + + it('should get signer for specific chain from specific provider (using chainid(', async () => { + const signer = provider.getProvider(31338).getSigner(31338) + expect(await signer.getChainId()).to.equal(31338) + }) + + it('should fail to get signer for different chain from a specific provider', async () => { + expect(() => provider.getProvider(31338).getSigner(31337)).to.throw( + 'This provider only supports the network 31338, but 31337 was requested.' + ) + }) + }) + + describe('subproviders (public rpc methods)', () => { + let provider: SequenceProvider + + beforeEach(() => { + provider = new SequenceProvider(basicMockClient, providerFor) + }) + + it('should return hardhat1 subprovider for chain 31337', async () => { + expect(await provider._getSubprovider('hardhat')).to.equal(hardhat1Provider) + }) + + it('should return hardhat2 subprovider for chain 31338', async () => { + expect(await provider._getSubprovider('hardhat2')).to.equal(hardhat2Provider) + }) + + it('should fail to return subprovider if providerFor doesnt return a provider', async () => { + await expect(provider._getSubprovider(1)).to.be.rejectedWith('No provider for chainId 1') + }) + + it('should return hardhat1 subprovider for default chain', async () => { + expect(await provider._getSubprovider()).to.equal(hardhat1Provider) + }) + + it('should return hardat2 if default chain is changed', async () => { + provider.setDefaultChainId(31338) + expect(await provider._getSubprovider()).to.equal(hardhat2Provider) + }) + + describe('forward methods to subprovider', () => { + const testAccounts = [ + new ethers.Wallet('0xcd0434442164a4a6ef9bb677da8dc326fddf412cad4df65e1a3f2555aee5e2b3').connect(hardhat1Provider), + new ethers.Wallet('0xcd0434442164a4a6ef9bb677da8dc326fddf412cad4df65e1a3f2555aee5e2b3').connect(hardhat2Provider) + ] + + describe('forward getBlockNumber', () => { + let bn1: number + let bn2: number + + beforeEach(async () => { + bn1 = await hardhat1Provider.getBlockNumber() + bn2 = await hardhat2Provider.getBlockNumber() + + if (bn1 === bn2) { + await hardhat2Provider.send('evm_mine', []) + bn2 = await hardhat2Provider.getBlockNumber() + } + + expect(bn1).to.not.equal(bn2) + }) + + it('forward getBlockNumber - default', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.getBlockNumber()).to.equal(bn1, 'default chain') + + provider.setDefaultChainId(31338) + expect(await provider.getBlockNumber()).to.equal(bn2, 'new default chain') + }) + + it('forward getBlockNumber - specific chain', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.getBlockNumber({ chainId: 31337 })).to.equal(bn1) + expect(await provider.getBlockNumber({ chainId: 31338 })).to.equal(bn2) + }) + + it('forward getBlockNumber - static network provider', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.getProvider('hardhat').getBlockNumber()).to.equal(bn1) + expect(await provider.getProvider('hardhat2').getBlockNumber()).to.equal(bn2) + }) + + it('fail to forward getBlockNumber - static network provider for different chain', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + await expect(provider.getProvider('hardhat2').getBlockNumber({ chainId: 31337 })).to.be.rejectedWith( + 'This provider only supports the network 31338, but 31337 was requested.' + ) + }) + }) + + describe('forward getGasPrice', () => { + let provider: SequenceProvider + + beforeEach(() => { + // NOTICE: We need to path the hardhat providers so they return different gas prices + provider = new SequenceProvider(basicMockClient, (chainId: number) => { + if (chainId === 31337) { + return { + ...hardhat1Provider, + getGasPrice: async () => ethers.BigNumber.from(1) + } as unknown as ethers.providers.JsonRpcProvider + } + + if (chainId === 31338) { + return { + ...hardhat2Provider, + getGasPrice: async () => ethers.BigNumber.from(2) + } as unknown as ethers.providers.JsonRpcProvider + } + + throw new Error(`No provider for chainId ${chainId}`) + }) + }) + + it('forward getGasPrice - default', async () => { + expect(await provider.getGasPrice()).to.deep.equal(ethers.BigNumber.from(1)) + + provider.setDefaultChainId(31338) + expect(await provider.getGasPrice()).to.deep.equal(ethers.BigNumber.from(2)) + }) + + it('forward getGasPrice - specific chain', async () => { + expect(await provider.getGasPrice({ chainId: 31337 })).to.deep.equal(ethers.BigNumber.from(1)) + expect(await provider.getGasPrice({ chainId: 31338 })).to.deep.equal(ethers.BigNumber.from(2)) + }) + + it('forward getGasPrice - static network provider', async () => { + expect(await provider.getProvider('hardhat').getGasPrice()).to.deep.equal(ethers.BigNumber.from(1)) + expect(await provider.getProvider(31338).getGasPrice()).to.deep.equal(ethers.BigNumber.from(2)) + }) + + it('fail to forward getGasPrice - static network provider for different chain', async () => { + await expect(provider.getProvider('hardhat').getGasPrice({ chainId: 31338 })).to.be.rejectedWith( + 'This provider only supports the network 31337, but 31338 was requested.' + ) + }) + }) + + describe('forward getBalance', () => { + let b1: ethers.BigNumber + let b2: ethers.BigNumber + + beforeEach(async () => { + b1 = await hardhat1Provider.getBalance(testAccounts[0].address) + b2 = await hardhat2Provider.getBalance(testAccounts[1].address) + + if (b1.eq(b2)) { + await testAccounts[1].sendTransaction({ + to: ethers.Wallet.createRandom().address, + value: 1 + }) + + b2 = await hardhat2Provider.getBalance(testAccounts[1].address) + } + + expect(b1).to.not.deep.equal(b2) + }) + + it('forward getBalance - default', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.getBalance(testAccounts[0].address)).to.deep.equal(b1) + + provider.setDefaultChainId(31338) + expect(await provider.getBalance(testAccounts[1].address)).to.deep.equal(b2) + }) + + it('forward getBalance - specific chain', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.getBalance(testAccounts[0].address, undefined, { chainId: 31337 })).to.deep.equal(b1) + expect(await provider.getBalance(testAccounts[1].address, undefined, { chainId: 31338 })).to.deep.equal(b2) + }) + + it('forward getBalance - static network provider', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.getProvider('hardhat').getBalance(testAccounts[0].address)).to.deep.equal(b1) + expect(await provider.getProvider('hardhat2').getBalance(testAccounts[1].address)).to.deep.equal(b2) + }) + + it('fail to forward getBalance - static network provider for different chain', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + await expect( + provider.getProvider('hardhat2').getBalance(testAccounts[0].address, undefined, { chainId: 31337 }) + ).to.be.rejectedWith('This provider only supports the network 31338, but 31337 was requested.') + }) + }) + + describe('forward getTransactionCount', () => { + let txc1: number + let txc2: number + + beforeEach(async () => { + txc1 = await hardhat1Provider.getTransactionCount(testAccounts[0].address) + txc2 = await hardhat2Provider.getTransactionCount(testAccounts[1].address) + + if (txc1 === txc2) { + await testAccounts[1].sendTransaction({ + to: testAccounts[0].address + }) + + txc2 = await hardhat2Provider.getTransactionCount(testAccounts[1].address) + } + + expect(txc1).to.not.equal(txc2) + }) + + it('forward getTransactionCount - default', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.getTransactionCount(testAccounts[0].address)).to.equal(txc1) + + provider.setDefaultChainId(31338) + expect(await provider.getTransactionCount(testAccounts[1].address)).to.equal(txc2) + }) + + it('forward getTransactionCount - specific chain', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.getTransactionCount(testAccounts[0].address, undefined, { chainId: 31337 })).to.equal(txc1) + expect(await provider.getTransactionCount(testAccounts[1].address, undefined, { chainId: 31338 })).to.equal(txc2) + }) + + it('forward getTransactionCount - static network provider', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.getProvider('hardhat').getTransactionCount(testAccounts[0].address)).to.equal(txc1) + expect(await provider.getProvider('hardhat2').getTransactionCount(testAccounts[1].address)).to.equal(txc2) + }) + + it('fail to forward getTransactionCount - static network provider for different chain', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + await expect( + provider.getProvider('hardhat2').getTransactionCount(testAccounts[0].address, undefined, { chainId: 31337 }) + ).to.be.rejectedWith('This provider only supports the network 31338, but 31337 was requested.') + }) + }) + + describe('forward getCode', () => { + let addr: string + + beforeEach(async () => { + // deploy a "contract" with code 0x112233 + const res = await testAccounts[0] + .sendTransaction({ + data: '0x621122336000526003601df3' + }) + .then(r => r.wait()) + + addr = res.contractAddress + + expect(await hardhat1Provider.getCode(addr)).to.equal('0x112233') + expect(await hardhat2Provider.getCode(addr)).to.equal('0x') + }) + + it('forward getCode - default', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.getCode(addr)).to.equal('0x112233') + + provider.setDefaultChainId(31338) + expect(await provider.getCode(addr)).to.equal('0x') + }) + + it('forward getCode - specific chain', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.getCode(addr, undefined, { chainId: 31337 })).to.equal('0x112233') + expect(await provider.getCode(addr, undefined, { chainId: 31338 })).to.equal('0x') + }) + + it('forward getCode - static network provider', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.getProvider('hardhat').getCode(addr)).to.equal('0x112233') + expect(await provider.getProvider('hardhat2').getCode(addr)).to.equal('0x') + }) + + it('fail to forward getCode - static network provider for different chain', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + await expect(provider.getProvider('hardhat2').getCode(addr, undefined, { chainId: 31337 })).to.be.rejectedWith( + 'This provider only supports the network 31338, but 31337 was requested.' + ) + }) + }) + + describe('forward getStorageAt', () => { + const expected = '0x0000000000000000000000000000000000000000000000000000000000112233' + const empty = '0x0000000000000000000000000000000000000000000000000000000000000000' + + let addr: string + + beforeEach(async () => { + // deploy a "contract" that writes 0x112233 to storage slot 0x445566 + const res = await testAccounts[0] + .sendTransaction({ + data: '0x621122336244556655' + }) + .then(r => r.wait()) + + addr = res.contractAddress + + expect(await hardhat1Provider.getStorageAt(addr, '0x445566')).to.equal(expected) + expect(await hardhat2Provider.getStorageAt(addr, '0x445566')).to.equal(empty) + }) + + it('forward getStorageAt - default', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.getStorageAt(addr, '0x445566')).to.equal(expected) + + provider.setDefaultChainId(31338) + expect(await provider.getStorageAt(addr, '0x445566')).to.equal(empty) + }) + + it('forward getStorageAt - specific chain', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.getStorageAt(addr, '0x445566', undefined, { chainId: 31337 })).to.equal(expected) + expect(await provider.getStorageAt(addr, '0x445566', undefined, { chainId: 31338 })).to.equal(empty) + }) + + it('forward getStorageAt - static network provider', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.getProvider('hardhat').getStorageAt(addr, '0x445566')).to.equal(expected) + expect(await provider.getProvider('hardhat2').getStorageAt(addr, '0x445566')).to.equal(empty) + }) + + it('fail to forward getStorageAt - static network provider for different chain', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + await expect( + provider.getProvider('hardhat2').getStorageAt(addr, '0x445566', undefined, { chainId: 31337 }) + ).to.be.rejectedWith('This provider only supports the network 31338, but 31337 was requested.') + }) + }) + + describe('forward call', () => { + let addr: string + + beforeEach(async () => { + // deploy a "contract" that when called returns 0x112233 + const res = await testAccounts[0] + .sendTransaction({ + data: '0x6b621122336000526003601df3600052600c6014f3' + }) + .then(r => r.wait()) + + addr = res.contractAddress + + expect(await hardhat1Provider.call({ to: addr })).to.equal('0x112233') + expect(await hardhat2Provider.call({ to: addr })).to.equal('0x') + }) + + it('forward call - default', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.call({ to: addr })).to.equal('0x112233') + + provider.setDefaultChainId(31338) + expect(await provider.call({ to: addr })).to.equal('0x') + }) + + it('forward call - specific chain', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.call({ to: addr }, undefined, { chainId: 31337 })).to.equal('0x112233') + expect(await provider.call({ to: addr }, undefined, { chainId: 31338 })).to.equal('0x') + }) + + it('forward call - static network provider', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.getProvider('hardhat').call({ to: addr })).to.equal('0x112233') + expect(await provider.getProvider('hardhat2').call({ to: addr })).to.equal('0x') + }) + + it('fail to forward call - static network provider for different chain', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + await expect(provider.getProvider('hardhat2').call({ to: addr }, undefined, { chainId: 31337 })).to.be.rejectedWith( + 'This provider only supports the network 31338, but 31337 was requested.' + ) + }) + }) + + describe('forward estimateGas', () => { + let eg1: ethers.BigNumber + let eg2: ethers.BigNumber + + let addr: string + + beforeEach(async () => { + // deploy a "contract" that when called returns 0x112233 + // (this uses a bit of gas that we can measure) + const res = await testAccounts[0] + .sendTransaction({ + data: '0x6b621122336000526003601df3600052600c6014f3' + }) + .then(r => r.wait()) + + addr = res.contractAddress + + eg1 = await hardhat1Provider.estimateGas({ to: addr }) + eg2 = await hardhat2Provider.estimateGas({ to: addr }) + + expect(eg1).to.not.deep.equal(eg2) + }) + + it('forward estimateGas - default', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.estimateGas({ to: addr })).to.deep.equal(eg1) + + provider.setDefaultChainId(31338) + expect(await provider.estimateGas({ to: addr })).to.deep.equal(eg2) + }) + + it('forward estimateGas - specific chain', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.estimateGas({ to: addr }, { chainId: 31337 })).to.deep.equal(eg1) + expect(await provider.estimateGas({ to: addr }, { chainId: 31338 })).to.deep.equal(eg2) + }) + + it('forward estimateGas - static network provider', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.getProvider('hardhat').estimateGas({ to: addr })).to.deep.equal(eg1) + expect(await provider.getProvider('hardhat2').estimateGas({ to: addr })).to.deep.equal(eg2) + }) + + it('fail to forward estimateGas - static network provider for different chain', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + await expect(provider.getProvider('hardhat2').estimateGas({ to: addr }, { chainId: 31337 })).to.be.rejectedWith( + 'This provider only supports the network 31338, but 31337 was requested.' + ) + }) + }) + + describe('forward getBlock', () => { + let b1: ethers.providers.Block + let b2: ethers.providers.Block + + beforeEach(async () => { + b1 = await hardhat1Provider.getBlock(1) + b2 = await hardhat2Provider.getBlock(1) + + expect(b1).to.not.deep.equal(b2) + }) + + it('forward getBlock - default', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.getBlock(1)).to.deep.equal(b1) + + provider.setDefaultChainId(31338) + expect(await provider.getBlock(1)).to.deep.equal(b2) + }) + + it('forward getBlock - specific chain', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.getBlock(1, { chainId: 31337 })).to.deep.equal(b1) + expect(await provider.getBlock(1, { chainId: 31338 })).to.deep.equal(b2) + }) + + it('forward getBlock - static network provider', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.getProvider('hardhat').getBlock(1)).to.deep.equal(b1) + expect(await provider.getProvider('hardhat2').getBlock(1)).to.deep.equal(b2) + }) + + it('fail to forward getBlock - static network provider for different chain', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + await expect(provider.getProvider('hardhat2').getBlock(0, { chainId: 31337 })).to.be.rejectedWith( + 'This provider only supports the network 31338, but 31337 was requested.' + ) + }) + }) + + describe('forward getTransaction', () => { + let t1: string + + beforeEach(async () => { + // We can't create a transaction that exists on both chains + const res = await testAccounts[0].sendTransaction({ + to: ethers.Wallet.createRandom().address + }) + + t1 = res.hash + await res.wait() + }) + + it('forward getTransaction - default', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.getTransaction(t1).then(r => r.hash)).to.equal(t1) + + provider.setDefaultChainId(31338) + expect(await provider.getTransaction(t1)).to.be.null + }) + + it('forward getTransaction - specific chain', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.getTransaction(t1, { chainId: 31337 }).then(r => r.hash)).to.equal(t1) + expect(await provider.getTransaction(t1, { chainId: 31338 })).to.be.null + }) + + it('forward getTransaction - static network provider', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect( + await provider + .getProvider('hardhat') + .getTransaction(t1) + .then(r => r.hash) + ).to.equal(t1) + expect(await provider.getProvider('hardhat2').getTransaction(t1)).to.be.null + }) + + it('fail to forward getTransaction - static network provider for different chain', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + await expect(provider.getProvider('hardhat2').getTransaction(t1, { chainId: 31337 })).to.be.rejectedWith( + 'This provider only supports the network 31338, but 31337 was requested.' + ) + }) + }) + + describe('forward getLogs', () => { + let t1: string + + let r1: Array + let r2: Array + + beforeEach(async () => { + // Deploy a contract that emits a single LOG0 event (during deployment) + const res = await testAccounts[0] + .sendTransaction({ + data: '0x60006000a0' + }) + .then(r => r.wait()) + + t1 = res.contractAddress + + r1 = await hardhat1Provider.getLogs({ address: t1 }) + r2 = await hardhat2Provider.getLogs({ address: t1 }) + + expect(r1).to.not.deep.equal(r2) + }) + + it('forward getLogs - default', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.getLogs({ address: t1 })).to.deep.equal(r1) + + provider.setDefaultChainId(31338) + expect(await provider.getLogs({ address: t1 })).to.deep.equal(r2) + }) + + it('forward getLogs - specific chain', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.getLogs({ address: t1 }, { chainId: 31337 })).to.deep.equal(r1) + expect(await provider.getLogs({ address: t1 }, { chainId: 31338 })).to.deep.equal(r2) + }) + + it('forward getLogs - static network provider', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.getProvider('hardhat').getLogs({ address: t1 })).to.deep.equal(r1) + expect(await provider.getProvider('hardhat2').getLogs({ address: t1 })).to.deep.equal(r2) + }) + + it('fail to forward getLogs - static network provider for different chain', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + await expect(provider.getProvider('hardhat2').getLogs({ address: t1 }, { chainId: 31337 })).to.be.rejectedWith( + 'This provider only supports the network 31338, but 31337 was requested.' + ) + }) + }) + + describe('forward waitForTransaction', () => { + let t1: string + + beforeEach(async () => { + t1 = await testAccounts[0] + .sendTransaction({ + to: ethers.Wallet.createRandom().address + }) + .then(r => r.hash) + }) + + it('forward waitForTransaction - default', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.waitForTransaction(t1, undefined, 250).then(r => r.transactionHash)).to.equal(t1) + + provider.setDefaultChainId(31338) + await expect(provider.waitForTransaction(t1, undefined, 250)).to.be.rejected + }) + + it('forward waitForTransaction - specific chain', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.waitForTransaction(t1, undefined, 250, { chainId: 31337 }).then(r => r.transactionHash)).to.equal( + t1 + ) + await expect(provider.waitForTransaction(t1, undefined, 250, { chainId: 31338 })).to.be.rejected + }) + + it('forward waitForTransaction - static network provider', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect( + await provider + .getProvider('hardhat') + .waitForTransaction(t1, undefined, 250) + .then(r => r.transactionHash) + ).to.equal(t1) + await expect(provider.getProvider('hardhat2').waitForTransaction(t1, undefined, 250)).to.be.rejected + }) + + it('fail to forward waitForTransaction - static network provider for different chain', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + await expect( + provider.getProvider('hardhat2').waitForTransaction(t1, undefined, 250, { chainId: 31337 }) + ).to.be.rejectedWith('This provider only supports the network 31338, but 31337 was requested.') + }) + }) + + // NOTICE: These tests may be a bit fragile, as they rely + // on using the sequence mainnet provider + describe('forward ENS methods', () => { + let provider: SequenceProvider + let mainnetProvider: ethers.providers.JsonRpcProvider + + let vitalikAddr: string | null + + before(async () => { + mainnetProvider = new ethers.providers.JsonRpcProvider('https://nodes.sequence.app/mainnet') + vitalikAddr = await mainnetProvider.resolveName('vitalik.eth') + }) + + beforeEach(() => { + provider = new SequenceProvider( + { + ...basicMockClient, + getNetworks: async () => allNetworks + } as unknown as SequenceClient, + (chainId: number) => { + if (chainId === 1) { + return mainnetProvider + } + + return providerFor(chainId) + } + ) + }) + + it('resolve normal address', async () => { + const addr = ethers.Wallet.createRandom().address + expect(await provider.resolveName(addr)).to.equal(addr) + }) + + it('forward resolveName on primary provider', async () => { + expect(await provider.resolveName('vitalik.eth')).to.equal(vitalikAddr) + }) + + it('forward resolveName on single network (mainnet) provider', async () => { + expect(await provider.getProvider('mainnet').resolveName('vitalik.eth')).to.equal(vitalikAddr) + }) + + it('fail to forward resolveName on single network (hardhat) provider', async () => { + await expect(provider.getProvider('hardhat').resolveName('vitalik.eth')).to.be.rejectedWith( + 'This provider only supports the network 31337, but 1 was requested.' + ) + }) + }) + }) + + describe('perform implementation', () => { + describe('perform eth_chainId', async () => { + it('should return initial default chainId', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.perform('eth_chainId', [])).to.equal(ethers.utils.hexValue(31337)) + }) + + it('should return new default chainId', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + provider.setDefaultChainId(31338) + expect(await provider.perform('eth_chainId', [])).to.equal(ethers.utils.hexValue(31338)) + }) + + it('should return static chainId', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.getProvider(31337).perform('eth_chainId', [])).to.equal(ethers.utils.hexValue(31337)) + expect(await provider.getProvider(31338).perform('eth_chainId', [])).to.equal(ethers.utils.hexValue(31338)) + }) + + it('should return chainId using request', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.request({ method: 'eth_chainId' })).to.equal(ethers.utils.hexValue(31337)) + }) + }) + + describe('perform eth_accounts', async () => { + let provider: SequenceProvider + let address: string + + beforeEach(async () => { + address = ethers.Wallet.createRandom().address + provider = new SequenceProvider( + { + ...basicMockClient, + getAddress: () => address + } as unknown as SequenceClient, + providerFor + ) + }) + + it('should return accounts on main provider', async () => { + expect(await provider.perform('eth_accounts', [])).to.deep.equal([address]) + }) + + it('should return accounts on single network provider', async () => { + expect(await provider.getProvider(31337).perform('eth_accounts', [])).to.deep.equal([address]) + expect(await provider.getProvider(31338).perform('eth_accounts', [])).to.deep.equal([address]) + }) + + it('should return accounts using request', async () => { + expect(await provider.request({ method: 'eth_accounts' })).to.deep.equal([address]) + }) + }) + + describe('perform wallet_switchEthereumChain', async () => { + it('should switch default chainId using request', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.request({ method: 'eth_chainId' })).to.equal(ethers.utils.hexValue(31337)) + + await provider.request({ method: 'wallet_switchEthereumChain', params: [{ chainId: '0x7a6a' }] }) + expect(defaultChainId).to.equal(31338) + }) + + it('should switch default chainId using object', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.perform('eth_chainId', [])).to.equal(ethers.utils.hexValue(31337)) + + await provider.perform('wallet_switchEthereumChain', [{ chainId: '0x7a6a' }]) + expect(defaultChainId).to.equal(31338) + expect(await provider.perform('eth_chainId', [])).to.equal(ethers.utils.hexValue(31338)) + }) + + it('should switch default chainId using hex string', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.perform('eth_chainId', [])).to.equal(ethers.utils.hexValue(31337)) + + await provider.perform('wallet_switchEthereumChain', ['0x7a6a']) + expect(defaultChainId).to.equal(31338) + expect(await provider.perform('eth_chainId', [])).to.equal(ethers.utils.hexValue(31338)) + }) + + it('should switch default chainId using number', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.perform('eth_chainId', [])).to.equal(ethers.utils.hexValue(31337)) + + await provider.perform('wallet_switchEthereumChain', [31338]) + expect(defaultChainId).to.equal(31338) + expect(await provider.perform('eth_chainId', [])).to.equal(ethers.utils.hexValue(31338)) + }) + + it('should switch default chainId using string', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.perform('eth_chainId', [])).to.equal(ethers.utils.hexValue(31337)) + + await provider.perform('wallet_switchEthereumChain', ['31338']) + expect(defaultChainId).to.equal(31338) + expect(await provider.perform('eth_chainId', [])).to.equal(ethers.utils.hexValue(31338)) + }) + + it('should fail to switch default chainId on static network provider', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + await expect(provider.getProvider(31337).perform('wallet_switchEthereumChain', ['31337'])).to.be.rejectedWith( + 'This provider only supports the network 31337; use the parent provider to switch networks.' + ) + }) + + describe('using the setDefaultChainId method', async () => { + it('should switch default chainId using name', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.perform('eth_chainId', [])).to.equal(ethers.utils.hexValue(31337)) + + provider.setDefaultChainId('hardhat2') + expect(defaultChainId).to.equal(31338) + expect(await provider.perform('eth_chainId', [])).to.equal(ethers.utils.hexValue(31338)) + }) + + it('should switch default chainId using number', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.perform('eth_chainId', [])).to.equal(ethers.utils.hexValue(31337)) + + provider.setDefaultChainId(31338) + expect(defaultChainId).to.equal(31338) + expect(await provider.perform('eth_chainId', [])).to.equal(ethers.utils.hexValue(31338)) + }) + + it('should switch default chainId using string', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.perform('eth_chainId', [])).to.equal(ethers.utils.hexValue(31337)) + + provider.setDefaultChainId('31338') + expect(defaultChainId).to.equal(31338) + expect(await provider.perform('eth_chainId', [])).to.equal(ethers.utils.hexValue(31338)) + }) + + it('should switch default chainId using hex string', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(await provider.perform('eth_chainId', [])).to.equal(ethers.utils.hexValue(31337)) + + provider.setDefaultChainId('0x7a6a') + expect(defaultChainId).to.equal(31338) + expect(await provider.perform('eth_chainId', [])).to.equal(ethers.utils.hexValue(31338)) + }) + + it('should fail to switch default chainId on static network provider', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(() => provider.getProvider(31337).setDefaultChainId(31338)).to.throw( + 'This provider only supports the network 31337; use the parent provider to switch networks.' + ) + }) + + it('should fail to switch default chainId (to same chainId) on static network provider', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(() => provider.getProvider(31337).setDefaultChainId(31337)).to.throw( + 'This provider only supports the network 31337; use the parent provider to switch networks.' + ) + }) + }) + }) + + describe('sequence client methods', () => { + describe('perform eth_sendTransaction', async () => { + const expectedResult = ethers.utils.hexlify(ethers.utils.randomBytes(32)) + + let provider: SequenceProvider + let calledCount: number + + let expectedChainId: number + let expectedTx: ethers.providers.TransactionRequest + + beforeEach(async () => { + calledCount = 0 + provider = new SequenceProvider( + { + ...basicMockClient, + send: async (request: JsonRpcRequest, chainId?: number) => { + expect(chainId).to.equal(expectedChainId) + expect(request.method).to.equal('eth_sendTransaction') + expect(request.params).to.deep.equal([expectedTx]) + calledCount++ + return expectedResult + } + } as unknown as SequenceClient, + providerFor + ) + + expectedTx = { + to: ethers.Wallet.createRandom().address, + value: '9000', + data: ethers.utils.hexlify(ethers.utils.randomBytes(66)) + } + }) + + it('should call sendTransaction on main provider', async () => { + expectedChainId = 31337 + const res = await provider.perform('eth_sendTransaction', [expectedTx]) + expect(calledCount).to.equal(1) + expect(res).to.equal(expectedResult) + }) + + it('should call sendTransaction after switching default chainId', async () => { + expectedChainId = 31338 + provider.setDefaultChainId(31338) + const res = await provider.perform('eth_sendTransaction', [expectedTx]) + expect(calledCount).to.equal(1) + expect(res).to.equal(expectedResult) + }) + + it('should call sendTransaction on single network provider', async () => { + expectedChainId = 31338 + const res = await provider.getProvider(31338).perform('eth_sendTransaction', [expectedTx]) + expect(calledCount).to.equal(1) + expect(res).to.equal(expectedResult) + }) + + it('should call sendTransaction with aux data', async () => { + expectedTx = { + ...expectedTx, + auxiliary: [{ to: ethers.Wallet.createRandom().address }] + } as ExtendedTransactionRequest + expectedChainId = 31338 + const res = await provider.getProvider(31338).perform('eth_sendTransaction', [expectedTx]) + expect(calledCount).to.equal(1) + expect(res).to.equal(expectedResult) + }) + + it('should call sendTransaction using request', async () => { + expectedChainId = 31337 + const res = await provider.request({ method: 'eth_sendTransaction', params: [expectedTx] }) + expect(calledCount).to.equal(1) + expect(res).to.equal(expectedResult) + }) + }) + ;['eth_sign', 'personal_sign', 'sequence_sign'].forEach(method => { + describe(`perform ${method}`, async () => { + const expectedResult = ethers.utils.hexlify(ethers.utils.randomBytes(120)) + + let provider: SequenceProvider + let calledCount: number + + let expectedChainId: number + let expectedAddress: string + let expectedMessage: string + + beforeEach(async () => { + calledCount = 0 + provider = new SequenceProvider( + { + ...basicMockClient, + send: async (request: JsonRpcRequest, chainId?: number) => { + expect(chainId).to.equal(expectedChainId) + expect(request.method).to.equal(method) + expect(request.params).to.deep.equal([expectedAddress, expectedMessage]) + calledCount++ + return expectedResult + } + } as unknown as SequenceClient, + providerFor + ) + + expectedAddress = ethers.Wallet.createRandom().address + expectedMessage = ethers.utils.hexlify(ethers.utils.randomBytes(66)) + }) + + it('should call sign on main provider', async () => { + expectedChainId = 31337 + const res = await provider.perform(method, [expectedAddress, expectedMessage]) + expect(calledCount).to.equal(1) + expect(res).to.equal(expectedResult) + }) + + it('should call sign after switching default chainId', async () => { + expectedChainId = 31338 + provider.setDefaultChainId(31338) + const res = await provider.perform(method, [expectedAddress, expectedMessage]) + expect(calledCount).to.equal(1) + expect(res).to.equal(expectedResult) + }) + + it('should call sign on single network provider', async () => { + expectedChainId = 31338 + const res = await provider.getProvider(31338).perform(method, [expectedAddress, expectedMessage]) + expect(calledCount).to.equal(1) + expect(res).to.equal(expectedResult) + }) + + it('should call sign using request', async () => { + expectedChainId = 31337 + const res = await provider.request({ method, params: [expectedAddress, expectedMessage] }) + expect(calledCount).to.equal(1) + expect(res).to.equal(expectedResult) + }) + }) + }) + ;['eth_signTypedData', 'eth_signTypedData_v4', 'sequence_signTypedData_v4'].forEach(method => { + describe(`perform ${method}`, async () => { + const expectedResult = ethers.utils.hexlify(ethers.utils.randomBytes(121)) + + let provider: SequenceProvider + let calledCount: number + + let expectedChainId: number + let expectedAddress: string + let expectedMessage: Array + + beforeEach(async () => { + calledCount = 0 + provider = new SequenceProvider( + { + ...basicMockClient, + send: async (request: JsonRpcRequest, chainId?: number) => { + expect(chainId).to.equal(expectedChainId) + expect(request.method).to.equal(method) + expect(request.params).to.deep.equal([expectedAddress, expectedMessage]) + calledCount++ + return expectedResult + } + } as unknown as SequenceClient, + providerFor + ) + + expectedAddress = ethers.Wallet.createRandom().address + expectedMessage = [{ thisisjustdata: ethers.utils.hexlify(ethers.utils.randomBytes(66)), sure: 'yes' }] + }) + + it('should call sign on main provider', async () => { + expectedChainId = 31337 + const res = await provider.perform(method, [expectedAddress, expectedMessage]) + expect(calledCount).to.equal(1) + expect(res).to.equal(expectedResult) + }) + + it('should call sign after switching default chainId', async () => { + expectedChainId = 31338 + provider.setDefaultChainId(31338) + const res = await provider.perform(method, [expectedAddress, expectedMessage]) + expect(calledCount).to.equal(1) + expect(res).to.equal(expectedResult) + }) + + it('should call sign on single network provider', async () => { + expectedChainId = 31338 + const res = await provider.getProvider(31338).perform(method, [expectedAddress, expectedMessage]) + expect(calledCount).to.equal(1) + expect(res).to.equal(expectedResult) + }) + + it('should call sign using request', async () => { + expectedChainId = 31337 + const res = await provider.request({ method, params: [expectedAddress, expectedMessage] }) + expect(calledCount).to.equal(1) + expect(res).to.equal(expectedResult) + }) + }) + }) + }) + + describe('misc public rpc methods', () => { + let provider: SequenceProvider + let b1: number + let b2: number + + beforeEach(async () => { + provider = new SequenceProvider(basicMockClient, providerFor) + b1 = await hardhat1Provider.getBlockNumber() + b2 = await hardhat2Provider.getBlockNumber() + }) + + it('should forward random method to main provider', async () => { + await provider.perform('evm_mine', []) + expect(await hardhat1Provider.getBlockNumber()).to.equal(b1 + 1) + expect(await hardhat2Provider.getBlockNumber()).to.equal(b2) + }) + + it('should forward random method after switching default chain', async () => { + provider.setDefaultChainId(31338) + await provider.perform('evm_mine', []) + expect(await hardhat1Provider.getBlockNumber()).to.equal(b1) + expect(await hardhat2Provider.getBlockNumber()).to.equal(b2 + 1) + }) + + it('should forward random method to single network provider', async () => { + await provider.getProvider(31338).perform('evm_mine', []) + expect(await hardhat1Provider.getBlockNumber()).to.equal(b1) + expect(await hardhat2Provider.getBlockNumber()).to.equal(b2 + 1) + }) + + it('should forward method with parameters', async () => { + await provider.perform('evm_mine', []) + await provider.perform('evm_mine', []) + const block1 = await hardhat1Provider.getBlock(2).then(t => t.hash) + expect(await provider.perform('eth_getBlockByNumber', ['0x2', false]).then(t => t.hash)).to.equal(block1) + }) + + it('should forward method using request', async () => { + await provider.request({ method: 'evm_mine', params: [] }) + await provider.request({ method: 'evm_mine', params: [] }) + const block1 = await hardhat1Provider.getBlock(2).then(t => t.hash) + expect(await provider.request({ method: 'eth_getBlockByNumber', params: ['0x2', false] }).then(t => t.hash)).to.equal( + block1 + ) + }) + }) + }) + }) + + it('should return true to isSequenceProvider', () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + expect(SequenceProvider.is(provider)).to.equal(true) + }) + + describe('network switching', () => { + it('should emit chainChanged when default chain is changed', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + + let emittedCount = 0 + provider.on('chainChanged', chainId => { + expect(chainId).to.equal(31338) + emittedCount++ + }) + + provider.setDefaultChainId(31338) + + await new Promise(resolve => setTimeout(resolve, 100)) + expect(emittedCount).to.equal(1) + }) + + it('should detect network', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + const initialNetwork = await provider.detectNetwork() + + expect(initialNetwork.chainId).to.equal(31337, 'initial network') + + provider.setDefaultChainId(31338) + + await new Promise(resolve => setTimeout(resolve, 100)) + const newNetwork = await provider.detectNetwork() + expect(newNetwork.chainId).to.equal(31338, '2nd network') + }) + + it('should update polling block number', async () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + + const b1 = await hardhat1Provider.getBlockNumber() + const b2 = await hardhat2Provider.getBlockNumber() + + if (b1 === b2) { + await hardhat2Provider.send('evm_mine', []) + } + + expect(b1).to.not.equal(b2) + + await new Promise(resolve => setTimeout(resolve, 250)) + const initialBlockNumber = provider.blockNumber + + provider.setDefaultChainId(31338) + + await new Promise(resolve => setTimeout(resolve, 250)) + const newBlockNumber = await provider.getBlockNumber() + + expect(initialBlockNumber).to.not.equal(newBlockNumber) + }) + }) +}) diff --git a/packages/provider/tests/remove-eip191prefix.spec.ts b/packages/provider/tests/remove-eip191prefix.spec.ts new file mode 100644 index 0000000000..1a4c31f7c3 --- /dev/null +++ b/packages/provider/tests/remove-eip191prefix.spec.ts @@ -0,0 +1,34 @@ +import chaiAsPromised from 'chai-as-promised' +import * as chai from 'chai' + +import { + trimEIP191Prefix_test1_prefixed, + trimEIP191Prefix_test1_raw, + trimEIP191Prefix_test2_prefixed, + trimEIP191Prefix_test2_raw, + trimEIP191Prefix_test3_prefixed, + trimEIP191Prefix_test3_raw, + trimEIP191Prefix_test4_prefixed, + trimEIP191Prefix_test4_raw, + trimEIP191Prefix_test5_prefixed, + trimEIP191Prefix_test5_raw +} from './messages' +import { trimEIP191Prefix } from '../src/utils' +import { ethers } from 'ethers' +const { expect } = chai.use(chaiAsPromised) + +describe('trimming eip191prefix', () => { + it('should trim prefix', () => { + expect(ethers.utils.toUtf8String(trimEIP191Prefix(trimEIP191Prefix_test1_prefixed))).equal(trimEIP191Prefix_test1_raw) + }) + + it('should handle eip191 exempt messages (by returning early)', () => { + expect(ethers.utils.toUtf8String(trimEIP191Prefix(trimEIP191Prefix_test2_prefixed))).equal(trimEIP191Prefix_test2_raw) + }) + + it('should trim prefix for case where max prefix char as number is bigger than the length of the message', () => { + expect(ethers.utils.toUtf8String(trimEIP191Prefix(trimEIP191Prefix_test3_prefixed))).equal(trimEIP191Prefix_test3_raw) + expect(ethers.utils.toUtf8String(trimEIP191Prefix(trimEIP191Prefix_test4_prefixed))).equal(trimEIP191Prefix_test4_raw) + expect(ethers.utils.toUtf8String(trimEIP191Prefix(trimEIP191Prefix_test5_prefixed))).equal(trimEIP191Prefix_test5_raw) + }) +}) diff --git a/packages/provider/tests/signer.spec.ts b/packages/provider/tests/signer.spec.ts new file mode 100644 index 0000000000..36044d9a98 --- /dev/null +++ b/packages/provider/tests/signer.spec.ts @@ -0,0 +1,1091 @@ +import { ethers } from 'ethers' +import { + ConnectOptions, + OpenWalletIntent, + OptionalChainId, + OptionalChainIdLike, + OptionalEIP6492, + SequenceClient, + SequenceProvider, + SequenceSigner, + SingleNetworkSequenceProvider, + SingleNetworkSequenceSigner +} from '../src' +import { expect } from 'chai' +import { JsonRpcRequest, JsonRpcResponse, allNetworks } from '@0xsequence/network' +import { ExtendedTransactionRequest } from '../src/extended' +import { TypedData } from '@0xsequence/utils' + +const hardhat1Provider = new ethers.providers.JsonRpcProvider('http://127.0.0.1:9595') +const hardhat2Provider = new ethers.providers.JsonRpcProvider('http://127.0.0.1:8595') + +const testAccounts = [ + new ethers.Wallet('0xcd0434442164a4a6ef9bb677da8dc326fddf412cad4df65e1a3f2555aee5e2b3').connect(hardhat1Provider), + new ethers.Wallet('0xcd0434442164a4a6ef9bb677da8dc326fddf412cad4df65e1a3f2555aee5e2b3').connect(hardhat2Provider) +] + +const providerFor = (chainId: number) => { + if (chainId === 31337) { + return hardhat1Provider + } + + if (chainId === 31338) { + return hardhat2Provider + } + + throw new Error(`No provider for chainId ${chainId}`) +} + +let defaultChainId: number + +let callback: (chainId: number) => void + +const onDefaultChainIdChanged = (cb: (chainId: number) => void) => { + callback = cb +} + +const setDefaultChainId = (chainId: number) => { + defaultChainId = chainId + callback(chainId) +} + +const basicMockClient = { + getChainId: () => defaultChainId, + onDefaultChainIdChanged, + setDefaultChainId, + // EIP-1193 + onConnect: () => {}, + onDisconnect: () => {}, + onAccountsChanged: () => {} +} as unknown as SequenceClient + +async function waitUntilNoFail(provider: ethers.providers.Provider, timeout = 20000): Promise { + const start = Date.now() + while (Date.now() - start < timeout) { + try { + await provider.getBlockNumber() + return + } catch (e) { + await new Promise(resolve => setTimeout(resolve, 100)) + } + } + console.warn('waitUntilNoFail timed out') +} + +describe('SequenceSigner', () => { + before(async () => { + // Wait for both providers to be ready + await Promise.all([waitUntilNoFail(hardhat1Provider), waitUntilNoFail(hardhat2Provider)]) + }) + + beforeEach(() => { + defaultChainId = 31337 + }) + + describe('client proxy methods', () => { + describe('getWalletConfig', () => { + const returnWalletConfig = { + version: 1, + threshold: 5, + signers: [ + { + weight: 1, + addr: ethers.Wallet.createRandom().address + } + ] + } + + let expectedChainId: number + let signer: SequenceSigner + let callsToGetWalletConfig: number + + beforeEach(() => { + callsToGetWalletConfig = 0 + signer = new SequenceProvider( + { + ...basicMockClient, + getOnchainWalletConfig: async (args: { chainId: number }) => { + expect(args.chainId).to.equal(expectedChainId) + callsToGetWalletConfig++ + return returnWalletConfig + } + } as unknown as SequenceClient, + providerFor + ).getSigner() + }) + + it('should return the wallet config', async () => { + expectedChainId = 31337 + const walletConfig = await signer.getWalletConfig() + expect(walletConfig).to.deep.equal(returnWalletConfig) + expect(callsToGetWalletConfig).to.equal(1) + }) + + it('should return the wallet config for a different chainId', async () => { + expectedChainId = 31338 + signer.provider.setDefaultChainId(31338) + const walletConfig = await signer.getWalletConfig() + expect(walletConfig).to.deep.equal(returnWalletConfig) + expect(callsToGetWalletConfig).to.equal(1) + }) + + it('should return the wallet config on a specific network signer', async () => { + const signer1 = signer.getSigner(31337) + const signer2 = signer.getSigner(31338) + + expectedChainId = 31337 + const walletConfig1 = await signer1.getWalletConfig() + expect(walletConfig1).to.deep.equal(returnWalletConfig) + expect(callsToGetWalletConfig).to.equal(1) + + expectedChainId = 31338 + const walletConfig2 = await signer2.getWalletConfig() + expect(walletConfig2).to.deep.equal(returnWalletConfig) + expect(callsToGetWalletConfig).to.equal(2) + }) + }) + + it('getNetworks', async () => { + let callsToGetNetworks = 0 + const signer = new SequenceProvider( + { + ...basicMockClient, + getNetworks: async () => { + callsToGetNetworks++ + return allNetworks + } + } as unknown as SequenceClient, + providerFor + ).getSigner() + + expect(await signer.getNetworks()).to.deep.equal(allNetworks) + expect(callsToGetNetworks).to.equal(1) + + expect(await signer.getSigner(31337).getNetworks()).to.deep.equal(allNetworks) + expect(callsToGetNetworks).to.equal(2) + + expect(await signer.getSigner('hardhat2').getNetworks()).to.deep.equal(allNetworks) + expect(callsToGetNetworks).to.equal(3) + }) + + describe('getChainId', () => { + it('should return the default chainId', async () => { + const signer = new SequenceProvider(basicMockClient, providerFor).getSigner() + expect(await signer.getChainId()).to.equal(31337) + }) + + it('should return the chainId for a specific signer', async () => { + const signer = new SequenceProvider(basicMockClient, providerFor).getSigner() + expect(await signer.getSigner(31338).getChainId()).to.equal(31338) + }) + + it('should return the chainId for a specific signer by name', async () => { + const signer = new SequenceProvider(basicMockClient, providerFor).getSigner() + expect(await signer.getSigner('hardhat2').getChainId()).to.equal(31338) + }) + + it('should return the chainId after the default chainId changes', async () => { + const signer = new SequenceProvider(basicMockClient, providerFor).getSigner() + expect(await signer.getChainId()).to.equal(31337) + signer.provider.setDefaultChainId(31338) + expect(await signer.getChainId()).to.equal(31338) + }) + }) + + describe('getAddress', () => { + let callsToGetAddress: number + let signer: SequenceSigner + let address: string + + beforeEach(() => { + callsToGetAddress = 0 + address = ethers.Wallet.createRandom().address + signer = new SequenceProvider( + { + ...basicMockClient, + getAddress: () => { + callsToGetAddress++ + return address + } + } as unknown as SequenceClient, + providerFor + ).getSigner() + }) + + it('should return the address', async () => { + expect(await signer.getAddress()).to.equal(address) + expect(callsToGetAddress).to.equal(1) + }) + + it('should return the address for a specific signer', async () => { + expect(await signer.getSigner(31338).getAddress()).to.equal(address) + expect(callsToGetAddress).to.equal(1) + }) + + it('getAddress should not be memoized', async () => { + expect(await signer.getAddress()).to.equal(address) + expect(callsToGetAddress).to.equal(1) + expect(await signer.getAddress()).to.equal(address) + expect(callsToGetAddress).to.equal(2) + }) + }) + }) + + describe('provider proxy methods', () => { + describe('getBalance', () => { + let signer: SequenceSigner + let address: string + + beforeEach(async () => { + address = ethers.Wallet.createRandom().address + + signer = new SequenceProvider( + { + ...basicMockClient, + getAddress: () => address + } as unknown as SequenceClient, + providerFor + ).getSigner() + + // Send 10 wei in hardhat1 and 20 wei in hardhat2 + await testAccounts[0].sendTransaction({ + to: address, + value: 10 + }) + + await testAccounts[1].sendTransaction({ + to: address, + value: 20 + }) + }) + + it('should return the balance on default chain', async () => { + expect(await signer.getBalance().then(b => b.toNumber())).to.equal(10) + }) + + it('should return the balance on default chain after switching networks', async () => { + signer.provider.setDefaultChainId(31338) + expect(await signer.getBalance().then(b => b.toNumber())).to.equal(20) + }) + + it('should return the balance on specific chain', async () => { + expect(await signer.getBalance(undefined, { chainId: 31337 }).then(b => b.toNumber())).to.equal(10) + expect(await signer.getBalance(undefined, { chainId: 31338 }).then(b => b.toNumber())).to.equal(20) + }) + + it('should return the balance on specific chain using string network name', async () => { + expect(await signer.getBalance(undefined, { chainId: 'hardhat' }).then(b => b.toNumber())).to.equal(10) + expect(await signer.getBalance(undefined, { chainId: 'hardhat2' }).then(b => b.toNumber())).to.equal(20) + }) + + it('should return the balance on static network signer', async () => { + expect( + await signer + .getSigner(31337) + .getBalance() + .then(b => b.toNumber()) + ).to.equal(10) + expect( + await signer + .getSigner(31338) + .getBalance() + .then(b => b.toNumber()) + ).to.equal(20) + }) + + it('should return the balance on static network signer using string network name', async () => { + expect( + await signer + .getSigner('hardhat') + .getBalance() + .then(b => b.toNumber()) + ).to.equal(10) + expect( + await signer + .getSigner('hardhat2') + .getBalance() + .then(b => b.toNumber()) + ).to.equal(20) + }) + + it('should return balance on specific chain when passing chainId', async () => { + expect( + await signer + .getSigner('hardhat') + .getBalance(undefined, { chainId: 31337 }) + .then(b => b.toNumber()) + ).to.equal(10) + expect( + await signer + .getSigner('hardhat2') + .getBalance(undefined, { chainId: 31338 }) + .then(b => b.toNumber()) + ).to.equal(20) + }) + + it('should fail to return balance on specific chain when passing different chainId', async () => { + await expect(signer.getSigner('hardhat').getBalance(undefined, { chainId: 31338 })).to.be.rejectedWith( + 'This signer only supports the network 31337, but 31338 was requested.' + ) + }) + }) + + describe('estimate gas', () => { + let signer: SequenceSigner + + let eg1: ethers.BigNumber + let eg2: ethers.BigNumber + + let addr: string + + beforeEach(async () => { + // deploy a "contract" that when called returns 0x112233 + // (this uses a bit of gas that we can measure) + const res = await testAccounts[0] + .sendTransaction({ + data: '0x6b621122336000526003601df3600052600c6014f3' + }) + .then(r => r.wait()) + + addr = res.contractAddress + + eg1 = await hardhat1Provider.estimateGas({ to: addr }) + eg2 = await hardhat2Provider.estimateGas({ to: addr }) + + expect(eg1).to.not.deep.equal(eg2) + + signer = new SequenceProvider(basicMockClient, providerFor).getSigner() + }) + + it('forward estimateGas - default', async () => { + expect(await signer.estimateGas({ to: addr })).to.deep.equal(eg1) + + signer.provider.setDefaultChainId(31338) + expect(await signer.estimateGas({ to: addr })).to.deep.equal(eg2) + }) + + it('forward estimateGas - specific chain', async () => { + expect(await signer.estimateGas({ to: addr }, { chainId: 31337 })).to.deep.equal(eg1) + expect(await signer.estimateGas({ to: addr }, { chainId: 31338 })).to.deep.equal(eg2) + }) + + it('forward estimateGas - static network provider', async () => { + expect(await signer.getSigner('hardhat').estimateGas({ to: addr })).to.deep.equal(eg1) + expect(await signer.getSigner('hardhat2').estimateGas({ to: addr })).to.deep.equal(eg2) + }) + + it('fail to forward estimateGas - static network provider for different chain', async () => { + await expect(signer.getSigner('hardhat2').estimateGas({ to: addr }, { chainId: 31337 })).to.be.rejectedWith( + 'This signer only supports the network 31338, but 31337 was requested.' + ) + }) + }) + + describe('call', () => { + let signer: SequenceSigner + let addr: string + + beforeEach(async () => { + // deploy a "contract" that when called returns 0x112233 + const res = await testAccounts[0] + .sendTransaction({ + data: '0x6b621122336000526003601df3600052600c6014f3' + }) + .then(r => r.wait()) + + addr = res.contractAddress + + expect(await hardhat1Provider.call({ to: addr })).to.equal('0x112233') + expect(await hardhat2Provider.call({ to: addr })).to.equal('0x') + signer = new SequenceProvider(basicMockClient, providerFor).getSigner() + }) + + it('forward call - default', async () => { + expect(await signer.call({ to: addr })).to.equal('0x112233') + + signer.provider.setDefaultChainId(31338) + expect(await signer.call({ to: addr })).to.equal('0x') + }) + + it('forward call - specific chain', async () => { + expect(await signer.call({ to: addr }, undefined, { chainId: 31337 })).to.equal('0x112233') + expect(await signer.call({ to: addr }, undefined, { chainId: 31338 })).to.equal('0x') + }) + + it('forward call - static network provider', async () => { + expect(await signer.getSigner(31337).call({ to: addr })).to.equal('0x112233') + expect(await signer.getSigner(31338).call({ to: addr })).to.equal('0x') + }) + + it('fail to forward call - static network provider for different chain', async () => { + await expect(signer.getSigner('hardhat2').call({ to: addr }, undefined, { chainId: 31337 })).to.be.rejectedWith( + 'This signer only supports the network 31338, but 31337 was requested.' + ) + }) + }) + + describe('getGasPrice', () => { + let signer: SequenceSigner + + beforeEach(() => { + // NOTICE: We need to path the hardhat providers so they return different gas prices + signer = new SequenceProvider(basicMockClient, (chainId: number) => { + if (chainId === 31337) { + return { + ...hardhat1Provider, + getGasPrice: async () => ethers.BigNumber.from(1) + } as unknown as ethers.providers.JsonRpcProvider + } + + if (chainId === 31338) { + return { + ...hardhat2Provider, + getGasPrice: async () => ethers.BigNumber.from(2) + } as unknown as ethers.providers.JsonRpcProvider + } + + throw new Error(`No provider for chainId ${chainId}`) + }).getSigner() + }) + + it('forward getGasPrice - default', async () => { + expect(await signer.getGasPrice()).to.deep.equal(ethers.BigNumber.from(1)) + + signer.provider.setDefaultChainId(31338) + expect(await signer.getGasPrice()).to.deep.equal(ethers.BigNumber.from(2)) + }) + + it('forward getGasPrice - specific chain', async () => { + expect(await signer.getGasPrice({ chainId: 31337 })).to.deep.equal(ethers.BigNumber.from(1)) + expect(await signer.getGasPrice({ chainId: 31338 })).to.deep.equal(ethers.BigNumber.from(2)) + }) + + it('forward getGasPrice - static network provider', async () => { + expect(await signer.getSigner('hardhat').getGasPrice()).to.deep.equal(ethers.BigNumber.from(1)) + expect(await signer.getSigner(31338).getGasPrice()).to.deep.equal(ethers.BigNumber.from(2)) + }) + + it('fail to forward getGasPrice - static network provider for different chain', async () => { + await expect(signer.getSigner('hardhat').getGasPrice({ chainId: 31338 })).to.be.rejectedWith( + 'This signer only supports the network 31337, but 31338 was requested.' + ) + }) + }) + + describe('ENS', () => { + let signer: SequenceSigner + let mainnetProvider: ethers.providers.JsonRpcProvider + + let vitalikAddr: string | null + + before(async () => { + mainnetProvider = new ethers.providers.JsonRpcProvider('https://nodes.sequence.app/mainnet') + vitalikAddr = await mainnetProvider.resolveName('vitalik.eth') + }) + + beforeEach(() => { + signer = new SequenceProvider( + { + ...basicMockClient, + getNetworks: async () => allNetworks + } as unknown as SequenceClient, + (chainId: number) => { + if (chainId === 1) { + return mainnetProvider + } + + return providerFor(chainId) + } + ).getSigner() + }) + + it('resolve normal address', async () => { + const addr = ethers.Wallet.createRandom().address + expect(await signer.resolveName(addr)).to.equal(addr) + }) + + it('forward resolveName on primary provider', async () => { + expect(await signer.resolveName('vitalik.eth')).to.equal(vitalikAddr) + }) + + it('forward resolveName on single network (mainnet) provider', async () => { + expect(await signer.getSigner('mainnet').resolveName('vitalik.eth')).to.equal(vitalikAddr) + }) + + it('fail to forward resolveName on single network (hardhat) provider', async () => { + await expect(signer.getSigner('hardhat').resolveName('vitalik.eth')).to.be.rejectedWith( + 'This provider only supports the network 31337, but 1 was requested.' + ) + }) + + it('shuld fail if the name is not resolved', async () => { + await expect(signer.resolveName('pleasedontregisterthisorelsethistestwillfail.eth')).to.be.rejectedWith( + 'ENS name not found: pleasedontregisterthisorelsethistestwillfail.eth' + ) + }) + }) + }) + + describe('connect', () => { + it('should connect to new sequence provider', () => { + const signer = new SequenceProvider(basicMockClient, providerFor).getSigner() + const newProvider = new SequenceProvider(basicMockClient, providerFor) + + expect(signer.provider).to.not.equal(newProvider) + const newSigner = signer.connect(newProvider) + + expect(signer).to.not.equal(newSigner) + expect(newSigner.provider).to.equal(newProvider) + }) + + it('should fail to connect to non-sequence provider', () => { + const signer = new SequenceProvider(basicMockClient, providerFor).getSigner() + expect(() => signer.connect(hardhat1Provider)).to.throw('SequenceSigner can only be connected to a SequenceProvider') + }) + }) + + describe('single networks signer', () => { + it('default chainId signer should return this', () => { + const signer = new SequenceProvider(basicMockClient, providerFor).getSigner() + expect(signer.getSigner()).to.equal(signer) + }) + + it('static network matching default chainId should not return this', () => { + const signer = new SequenceProvider(basicMockClient, providerFor).getSigner() + expect(signer.getSigner(31337)).to.not.equal(signer) + }) + + it('static network should be memoized', () => { + const signer = new SequenceProvider(basicMockClient, providerFor).getSigner() + expect(signer.getSigner(31337)).to.equal(signer.getSigner('hardhat')) + }) + + it('static network should math the one provided by the provider', () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + const signer = provider.getSigner() + expect(signer.getSigner(31337).provider).to.equal(provider.getSigner(31337).provider) + }) + + it('static network provider should return static network signer', () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + const staticProvider = provider.getProvider(31337) + const signer = staticProvider.getSigner() + expect(SingleNetworkSequenceSigner.is(signer)).to.be.true + }) + + it('static network provider should return static network signer when asking for the same chainId', () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + const staticProvider = provider.getProvider(31337) + const signer = staticProvider.getSigner(31337) + expect(SingleNetworkSequenceSigner.is(signer)).to.be.true + expect(signer).to.equal(staticProvider.getSigner()) + }) + + it('static network provider should fail to return signer for different chainId', () => { + const provider = new SequenceProvider(basicMockClient, providerFor) + const staticProvider = provider.getProvider(31337) + expect(() => staticProvider.getSigner(31338)).to.throw( + 'This provider only supports the network 31337, but 31338 was requested.' + ) + }) + + it('static network signer should return static chainId', async () => { + const signer = new SequenceProvider(basicMockClient, providerFor).getSigner(31337) + expect(await signer.getChainId()).to.equal(31337) + }) + + it('static network signer should return self when asking for the same chainId', () => { + const signer = new SequenceProvider(basicMockClient, providerFor).getSigner() + const snetwork = signer.getSigner(31337) + expect(snetwork.getSigner(31337)).to.equal(snetwork) + }) + + it('static network signer should return self when asked for a signer without chainId', () => { + const signer = new SequenceProvider(basicMockClient, providerFor).getSigner() + const snetwork = signer.getSigner(31337) + expect(snetwork.getSigner()).to.equal(snetwork) + }) + + it('static network signer should fail to return signer for a different chainId', () => { + const signer = new SequenceProvider(basicMockClient, providerFor).getSigner(31337) + expect(() => signer.getSigner(31338)).to.throw('This signer only supports the network 31337, but 31338 was requested.') + }) + + it('static network signer should return static network provider', () => { + const signer = new SequenceProvider(basicMockClient, providerFor).getSigner(31337) + const provider = signer.getProvider() + expect(SingleNetworkSequenceProvider.is(provider)).to.be.true + }) + + it('static network signer should return static network provider when asked for same chainId', () => { + const signer = new SequenceProvider(basicMockClient, providerFor).getSigner(31337) + const provider = signer.getProvider(31337) + expect(SingleNetworkSequenceProvider.is(provider)).to.be.true + expect(provider).to.equal(signer.getProvider()) + }) + + it('static network signer should fail to return provider for different chainId', () => { + const signer = new SequenceProvider(basicMockClient, providerFor).getSigner(31337) + expect(() => signer.getProvider(31338)).to.throw('This signer only supports the network 31337, but 31338 was requested.') + }) + + it('signer getProvider should return main provider', () => { + const signer = new SequenceProvider(basicMockClient, providerFor).getSigner(31337) + expect(signer.getProvider()).to.equal(signer.provider) + }) + }) + + describe('signMessage', () => { + let signer: SequenceSigner + + let callsToSignMessage: number + let expectedSignMessage: ethers.utils.BytesLike + let expectedOptions: OptionalEIP6492 & OptionalChainId + let returnValue: string + + beforeEach(() => { + callsToSignMessage = 0 + expectedSignMessage = ethers.utils.hexlify(ethers.utils.randomBytes(64)) + expectedOptions = {} + returnValue = ethers.utils.hexlify(ethers.utils.randomBytes(99)) + + signer = new SequenceProvider( + { + ...basicMockClient, + signMessage: async (message: string, options: OptionalEIP6492 & OptionalChainId) => { + expect(message).to.equal(expectedSignMessage) + expect(options).to.deep.equal(expectedOptions) + callsToSignMessage++ + return returnValue + } + } as unknown as SequenceClient, + providerFor + ).getSigner() + }) + + it('should sign message on default chain', async () => { + expectedOptions = { chainId: 31337, eip6492: true } + expect(await signer.signMessage(expectedSignMessage)).to.equal(returnValue) + expect(callsToSignMessage).to.equal(1) + }) + + it('should sign message on default chain without using eip6492', async () => { + expectedOptions = { chainId: 31337, eip6492: false } + expect(await signer.signMessage(expectedSignMessage, { eip6492: false })).to.equal(returnValue) + expect(callsToSignMessage).to.equal(1) + }) + + it('should sign message on default chain after switching networks', async () => { + expectedOptions = { chainId: 31338, eip6492: true } + signer.provider.setDefaultChainId(31338) + expect(await signer.signMessage(expectedSignMessage)).to.equal(returnValue) + expect(callsToSignMessage).to.equal(1) + }) + + it('should sign message on default chain after switching networks without using eip6492', async () => { + expectedOptions = { chainId: 31338, eip6492: false } + signer.provider.setDefaultChainId(31338) + expect(await signer.signMessage(expectedSignMessage, { eip6492: false })).to.equal(returnValue) + expect(callsToSignMessage).to.equal(1) + }) + + it('should sign message on specific chain', async () => { + expectedOptions = { chainId: 31338, eip6492: true } + expect(await signer.signMessage(expectedSignMessage, { chainId: 31338 })).to.equal(returnValue) + expect(callsToSignMessage).to.equal(1) + }) + + it('should sign message on specific chain without using eip6492', async () => { + expectedOptions = { chainId: 31338, eip6492: false } + expect(await signer.signMessage(expectedSignMessage, { chainId: 31338, eip6492: false })).to.equal(returnValue) + expect(callsToSignMessage).to.equal(1) + }) + + it('should sign message on specific chain using string network name', async () => { + expectedOptions = { chainId: 31338, eip6492: true } + expect(await signer.signMessage(expectedSignMessage, { chainId: 'hardhat2' })).to.equal(returnValue) + expect(callsToSignMessage).to.equal(1) + }) + + it('should sign message on specific chain using string network name without using eip6492', async () => { + expectedOptions = { chainId: 31338, eip6492: false } + expect(await signer.signMessage(expectedSignMessage, { chainId: 'hardhat2', eip6492: false })).to.equal(returnValue) + expect(callsToSignMessage).to.equal(1) + }) + + it('should sign message on static network signer', async () => { + expectedOptions = { chainId: 31338, eip6492: true } + expect(await signer.getSigner(31338).signMessage(expectedSignMessage)).to.equal(returnValue) + expect(callsToSignMessage).to.equal(1) + }) + + it('should sign message on static network signer without using eip6492', async () => { + expectedOptions = { chainId: 31338, eip6492: false } + expect(await signer.getSigner(31338).signMessage(expectedSignMessage, { eip6492: false })).to.equal(returnValue) + expect(callsToSignMessage).to.equal(1) + }) + + it('should sign message on static network signer if passing chainId', async () => { + expectedOptions = { chainId: 31338, eip6492: true } + expect(await signer.getSigner(31338).signMessage(expectedSignMessage, { chainId: 31338 })).to.equal(returnValue) + expect(callsToSignMessage).to.equal(1) + }) + + it('should fail to sign message on static network signer if passing different chainId', async () => { + await expect(signer.getSigner(31338).signMessage(expectedSignMessage, { chainId: 31337 })).to.be.rejectedWith( + 'This signer only supports the network 31338, but 31337 was requested.' + ) + }) + + it('should pass array instead of string', async () => { + expectedSignMessage = ethers.utils.arrayify(ethers.utils.randomBytes(199)) + expectedOptions = { chainId: 31337, eip6492: true } + expect(await signer.signMessage(expectedSignMessage)).to.equal(returnValue) + }) + }) + + describe('signTypedData', () => { + let signer: SequenceSigner + + let callsToSignTypedData: number + let expectedDomain: ethers.TypedDataDomain + let expectedTypes: Record> + let expectedMessage: Record + let expectedOptions: OptionalEIP6492 & OptionalChainId + let returnValue: string + + beforeEach(() => { + callsToSignTypedData = 0 + expectedDomain = { + name: 'Sequence', + version: '1', + chainId: 31337, + verifyingContract: ethers.utils.hexlify(ethers.utils.randomBytes(12)) + } + expectedTypes = { + EIP712Domain: [ + { name: 'name', type: 'string' }, + { name: 'version', type: 'string' }, + { name: 'chainId', type: 'uint256' }, + { name: 'verifyingContract', type: 'address' } + ], + MetaTransaction: [ + { name: 'nonce', type: 'uint256' }, + { name: 'from', type: 'address' }, + { name: 'to', type: 'address' }, + { name: 'data', type: 'bytes' } + ] + } + expectedMessage = { + nonce: 1, + from: ethers.utils.hexlify(ethers.utils.randomBytes(12)), + to: ethers.utils.hexlify(ethers.utils.randomBytes(20)), + data: ethers.utils.hexlify(ethers.utils.randomBytes(32)) + } + expectedOptions = {} + returnValue = ethers.utils.hexlify(ethers.utils.randomBytes(99)) + + signer = new SequenceProvider( + { + ...basicMockClient, + signTypedData: async (typedData: TypedData, options: OptionalEIP6492 & OptionalChainId) => { + expect(typedData.domain).to.deep.equal(expectedDomain) + expect(typedData.types).to.deep.equal(expectedTypes) + expect(typedData.message).to.deep.equal(expectedMessage) + expect(options).to.deep.equal(expectedOptions) + callsToSignTypedData++ + return returnValue + } + } as unknown as SequenceClient, + providerFor + ).getSigner() + }) + + it('should sign typed data on default chain', async () => { + expectedOptions = { chainId: 31337, eip6492: true } + expect(await signer.signTypedData(expectedDomain, expectedTypes, expectedMessage)).to.equal(returnValue) + expect(callsToSignTypedData).to.equal(1) + }) + + it('should sign typed data on default chain without using eip6492', async () => { + expectedOptions = { chainId: 31337, eip6492: false } + expect(await signer.signTypedData(expectedDomain, expectedTypes, expectedMessage, { eip6492: false })).to.equal(returnValue) + expect(callsToSignTypedData).to.equal(1) + }) + + it('should sign typed data on default chain after switching networks', async () => { + expectedOptions = { chainId: 31338, eip6492: true } + signer.provider.setDefaultChainId(31338) + expect(await signer.signTypedData(expectedDomain, expectedTypes, expectedMessage)).to.equal(returnValue) + expect(callsToSignTypedData).to.equal(1) + }) + + it('should sign typed data on default chain after switching networks without using eip6492', async () => { + expectedOptions = { chainId: 31338, eip6492: false } + signer.provider.setDefaultChainId(31338) + expect(await signer.signTypedData(expectedDomain, expectedTypes, expectedMessage, { eip6492: false })).to.equal(returnValue) + expect(callsToSignTypedData).to.equal(1) + }) + + it('should sign typed data on specific chain', async () => { + expectedOptions = { chainId: 31338, eip6492: true } + expect(await signer.signTypedData(expectedDomain, expectedTypes, expectedMessage, { chainId: 31338 })).to.equal(returnValue) + expect(callsToSignTypedData).to.equal(1) + }) + + it('should sign typed data on specific chain without using eip6492', async () => { + expectedOptions = { chainId: 31338, eip6492: false } + expect( + await signer.signTypedData(expectedDomain, expectedTypes, expectedMessage, { chainId: 31338, eip6492: false }) + ).to.equal(returnValue) + expect(callsToSignTypedData).to.equal(1) + }) + + it('should sign typed data on specific chain using string network name', async () => { + expectedOptions = { chainId: 31338, eip6492: true } + expect( + await signer.signTypedData(expectedDomain, expectedTypes, expectedMessage, { + chainId: 'hardhat2' + }) + ).to.equal(returnValue) + expect(callsToSignTypedData).to.equal(1) + }) + + it('should sign typed data on specific chain using string network name without using eip6492', async () => { + expectedOptions = { chainId: 31338, eip6492: false } + expect( + await signer.signTypedData(expectedDomain, expectedTypes, expectedMessage, { + chainId: 'hardhat2', + eip6492: false + }) + ).to.equal(returnValue) + expect(callsToSignTypedData).to.equal(1) + }) + + it('should sign typed data on static network signer', async () => { + expectedOptions = { chainId: 31338, eip6492: true } + expect(await signer.getSigner(31338).signTypedData(expectedDomain, expectedTypes, expectedMessage)).to.equal(returnValue) + expect(callsToSignTypedData).to.equal(1) + }) + + it('should sign typed data on static network signer without using eip6492', async () => { + expectedOptions = { chainId: 31338, eip6492: false } + expect( + await signer.getSigner(31338).signTypedData(expectedDomain, expectedTypes, expectedMessage, { eip6492: false }) + ).to.equal(returnValue) + expect(callsToSignTypedData).to.equal(1) + }) + + it('should sign typed data on static network signer if passing chainId', async () => { + expectedOptions = { chainId: 31338, eip6492: true } + expect( + await signer.getSigner(31338).signTypedData(expectedDomain, expectedTypes, expectedMessage, { chainId: 31338 }) + ).to.equal(returnValue) + expect(callsToSignTypedData).to.equal(1) + }) + + it('should fail to sign typed data on static network signer if passing different chainId', async () => { + await expect( + signer.getSigner(31338).signTypedData(expectedDomain, expectedTypes, expectedMessage, { chainId: 31337 }) + ).to.be.rejectedWith('This signer only supports the network 31338, but 31337 was requested.') + }) + }) + + describe('sendTransaction', () => { + let callsToSendTransaction: number + let expectedTransactionRequest: + | ethers.utils.Deferrable[] + | ethers.utils.Deferrable + + let expectedOptions: OptionalChainIdLike + + let signer: SequenceSigner + + beforeEach(() => { + callsToSendTransaction = 0 + + expectedTransactionRequest = { + to: ethers.utils.hexlify(ethers.utils.randomBytes(12)), + value: ethers.utils.parseEther('1.0'), + data: ethers.utils.hexlify(ethers.utils.randomBytes(55)), + gasLimit: 40000 + } + + expectedOptions = {} + + signer = new SequenceProvider( + { + ...basicMockClient, + sendTransaction: async ( + transactionRequest: + | ethers.utils.Deferrable[] + | ethers.utils.Deferrable, + options: OptionalChainIdLike + ) => { + expect(transactionRequest).to.deep.equal(expectedTransactionRequest) + expect(options).to.deep.equal(expectedOptions) + callsToSendTransaction++ + + // Send a random transaction on the expected chainId + // so we can return some "hash", otherwise the provider + // will throw an error + const subsig = testAccounts[(options?.chainId ?? 31337) === 31337 ? 0 : 1] + const tx = await subsig.sendTransaction({ + to: ethers.Wallet.createRandom().address + }) + + return tx.hash + } + } as unknown as SequenceClient, + providerFor + ).getSigner() + }) + + it('should send transaction on default chain', async () => { + expectedOptions = { chainId: 31337 } + const tx = await signer.sendTransaction(expectedTransactionRequest) + expect(tx.wait()).to.be.fulfilled + expect(ethers.utils.arrayify(tx.hash)).to.have.lengthOf(32) + expect(callsToSendTransaction).to.equal(1) + }) + + it('should send transaction on default chain after switching networks', async () => { + expectedOptions = { chainId: 31338 } + signer.provider.setDefaultChainId(31338) + const tx = await signer.sendTransaction(expectedTransactionRequest) + expect(tx.wait()).to.be.fulfilled + expect(ethers.utils.arrayify(tx.hash)).to.have.lengthOf(32) + expect(callsToSendTransaction).to.equal(1) + }) + + it('should send transaction on specific chain', async () => { + expectedOptions = { chainId: 31338 } + const tx = await signer.sendTransaction(expectedTransactionRequest, { chainId: 31338 }) + expect(tx.wait()).to.be.fulfilled + expect(ethers.utils.arrayify(tx.hash)).to.have.lengthOf(32) + expect(callsToSendTransaction).to.equal(1) + }) + + it('should send transaction on specific chain using string network name', async () => { + expectedOptions = { chainId: 31338 } + const tx = await signer.sendTransaction(expectedTransactionRequest, { chainId: 'hardhat2' }) + expect(tx.wait()).to.be.fulfilled + expect(ethers.utils.arrayify(tx.hash)).to.have.lengthOf(32) + expect(callsToSendTransaction).to.equal(1) + }) + + it('should send transaction on static network signer', async () => { + expectedOptions = { chainId: 31338 } + const tx = await signer.getSigner(31338).sendTransaction(expectedTransactionRequest) + expect(tx.wait()).to.be.fulfilled + expect(ethers.utils.arrayify(tx.hash)).to.have.lengthOf(32) + expect(callsToSendTransaction).to.equal(1) + }) + + it('should send transaction on static network signer if passing chainId', async () => { + expectedOptions = { chainId: 31338 } + const tx = await signer.getSigner(31338).sendTransaction(expectedTransactionRequest, { chainId: 'hardhat2' }) + expect(tx.wait()).to.be.fulfilled + expect(ethers.utils.arrayify(tx.hash)).to.have.lengthOf(32) + expect(callsToSendTransaction).to.equal(1) + }) + + it('should fail to send transaction on static network signer if passing different chainId', async () => { + await expect(signer.getSigner(31338).sendTransaction(expectedTransactionRequest, { chainId: 31337 })).to.be.rejectedWith( + 'This signer only supports the network 31338, but 31337 was requested.' + ) + }) + + it('should send batch transaction', async () => { + expectedOptions = { chainId: 31338 } + expectedTransactionRequest = [ + { + to: ethers.utils.hexlify(ethers.utils.randomBytes(12)), + value: ethers.utils.parseEther('1.0'), + data: ethers.utils.hexlify(ethers.utils.randomBytes(55)) + }, + { + to: ethers.utils.hexlify(ethers.utils.randomBytes(12)), + data: ethers.utils.hexlify(ethers.utils.randomBytes(1)) + }, + { + to: ethers.utils.hexlify(ethers.utils.randomBytes(12)), + value: 2 + } + ] + + const tx = await signer.sendTransaction(expectedTransactionRequest, { chainId: 31338 }) + expect(tx.wait()).to.be.fulfilled + expect(ethers.utils.arrayify(tx.hash)).to.have.lengthOf(32) + expect(callsToSendTransaction).to.equal(1) + }) + + it('shoud send deffered transaction', async () => { + expectedOptions = { chainId: 31338 } + const expected = { + to: ethers.utils.hexlify(ethers.utils.randomBytes(12)), + value: ethers.utils.parseEther('1.0').toString() + } + + expectedTransactionRequest = JSON.parse(JSON.stringify(expected)) + + const derrered = { + to: new Promise(async r => { + await new Promise(d => setTimeout(d, 1000)) + return r(expected.to) + }), + value: new Promise(async r => { + await new Promise(d => setTimeout(d, 600)) + return r(expected.value) + }) + } + + const tx = await signer.sendTransaction(derrered, { chainId: 31338 }) + expect(tx.wait()).to.be.fulfilled + expect(ethers.utils.arrayify(tx.hash)).to.have.lengthOf(32) + }) + + it('shoud send array of deffered transactions', async () => { + expectedOptions = { chainId: 31338 } + const expected = [ + { + to: ethers.utils.hexlify(ethers.utils.randomBytes(12)), + value: ethers.utils.parseEther('1.0').toString() + }, + { + to: ethers.utils.hexlify(ethers.utils.randomBytes(12)), + data: ethers.utils.hexlify(ethers.utils.randomBytes(111)) + } + ] + + expectedTransactionRequest = JSON.parse(JSON.stringify(expected)) + + const derrered = [ + { + to: new Promise(async r => { + await new Promise(d => setTimeout(d, 1000)) + return r(expected[0].to) + }), + value: new Promise(async r => { + await new Promise(d => setTimeout(d, 600)) + return r(expected[0].value!) + }) + }, + { + to: new Promise(async r => { + await new Promise(d => setTimeout(d, 412)) + return r(expected[1].to) + }), + data: new Promise(async r => { + await new Promise(d => setTimeout(d, 1001)) + return r(expected[1].data!) + }) + } + ] + + const tx = await signer.sendTransaction(derrered, { chainId: 31338 }) + expect(tx.wait()).to.be.fulfilled + expect(ethers.utils.arrayify(tx.hash)).to.have.lengthOf(32) + }) + }) +}) diff --git a/packages/provider/tests/transactions.spec.ts b/packages/provider/tests/transactions.spec.ts new file mode 100644 index 0000000000..ad89d9f814 --- /dev/null +++ b/packages/provider/tests/transactions.spec.ts @@ -0,0 +1,109 @@ +import { commons } from '@0xsequence/core' +import { expect } from 'chai' +import { validateTransactionRequest } from '../src/transactions' + +const self = '0x5e1f5e1f5e1f5e1f5e1f5e1f5e1f5e1f5e1f5e1f' +const to = '0x0123456789012345678901234567890123456789' + +describe('validating transaction requests', () => { + it('should throw an error when a transaction does a self call', () => { + const transaction = { + to, + data: commons.transaction.encodeBundleExecData({ + entrypoint: to, + transactions: [ + { + to: self, + data: '0x12345678' + } + ] + }) + } + + expect(() => validateTransactionRequest(self, transaction)).to.throw() + }) + + it('should throw an error when a transaction does a deep self call', () => { + const transaction = { + to, + data: commons.transaction.encodeBundleExecData({ + entrypoint: to, + transactions: [ + { + to: self, + data: commons.transaction.encodeBundleExecData({ + entrypoint: self, + transactions: [ + { + to: self, + data: '0x12345678' + } + ] + }) + } + ] + }) + } + + expect(() => validateTransactionRequest(self, transaction)).to.throw() + }) + + it('should throw an error when a transaction does a delegate call', () => { + const transaction = { + to, + data: commons.transaction.encodeBundleExecData({ + entrypoint: to, + transactions: [ + { + to, + delegateCall: true + } + ] + }) + } + + expect(() => validateTransactionRequest(self, transaction)).to.throw() + }) + + it('should throw an error when a transaction does a deep delegate call', () => { + const transaction = { + to, + data: commons.transaction.encodeBundleExecData({ + entrypoint: to, + transactions: [ + { + to: self, + data: commons.transaction.encodeBundleExecData({ + entrypoint: self, + transactions: [ + { + to: self, + delegateCall: true + } + ] + }) + } + ] + }) + } + + expect(() => validateTransactionRequest(self, transaction)).to.throw() + }) + + it('should not throw an error in general', () => { + const transaction = { + to, + data: commons.transaction.encodeBundleExecData({ + entrypoint: to, + transactions: [ + { + to: self, // self without data is ok + value: '1000000000000000000' + } + ] + }) + } + + expect(() => validateTransactionRequest(self, transaction)).to.not.throw() + }) +}) diff --git a/packages/provider/tests/zeroxv3.spec.ts b/packages/provider/tests/zeroxv3.spec.ts new file mode 100644 index 0000000000..ee65442e2a --- /dev/null +++ b/packages/provider/tests/zeroxv3.spec.ts @@ -0,0 +1,14 @@ +import chaiAsPromised from 'chai-as-promised' +import * as chai from 'chai' + +import { isZeroExV3Order } from '../src/eip191exceptions' +import { message1, zeroExV3Order } from './messages' +const { expect } = chai.use(chaiAsPromised) + +describe('Utils / 0xv3', () => { + it('should detect 0x v3 order', () => { + expect(isZeroExV3Order(message1)).equals(false) + expect(isZeroExV3Order(zeroExV3Order.slice(0, -1))).equals(false) + expect(isZeroExV3Order(zeroExV3Order)).equals(true) + }) +}) diff --git a/packages/react-native/CHANGELOG.md b/packages/react-native/CHANGELOG.md new file mode 100644 index 0000000000..8025a00947 --- /dev/null +++ b/packages/react-native/CHANGELOG.md @@ -0,0 +1,240 @@ +# @0xsequence/react-native + +## 2.0.0 + +### Major Changes + +- changeset + +### Patch Changes + +- Updated dependencies + - @0xsequence/waas@2.0.0 + +## 1.10.14 + +### Patch Changes + +- network: add borne-testnet to allNetworks +- Updated dependencies + - @0xsequence/waas@1.10.14 + +## 1.10.13 + +### Patch Changes + +- network: add borne testnet +- Updated dependencies + - @0xsequence/waas@1.10.13 + +## 1.10.12 + +### Patch Changes + +- api: update bindings +- global/window -> globalThis +- Updated dependencies +- Updated dependencies + - @0xsequence/waas@1.10.12 + +## 1.10.11 + +### Patch Changes + +- waas: updated intent.gen without webrpc types, errors exported from authenticator.gen +- Updated dependencies + - @0xsequence/waas@1.10.11 + +## 1.10.10 + +### Patch Changes + +- metadata: update bindings with new contract collections api +- Updated dependencies + - @0xsequence/waas@1.10.10 + +## 1.10.9 + +### Patch Changes + +- waas minor update +- Updated dependencies + - @0xsequence/waas@1.10.9 + +## 1.10.8 + +### Patch Changes + +- update metadata bindings +- Updated dependencies + - @0xsequence/waas@1.10.8 + +## 1.10.7 + +### Patch Changes + +- minor fixes to waas client +- Updated dependencies + - @0xsequence/waas@1.10.7 + +## 1.10.6 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/waas@1.10.6 + +## 1.10.5 + +### Patch Changes + +- network: ape-chain-testnet -> apechain-testnet +- Updated dependencies + - @0xsequence/waas@1.10.5 + +## 1.10.4 + +### Patch Changes + +- network: add b3-sepolia, ape-chain-testnet, blast, blast-sepolia +- Updated dependencies + - @0xsequence/waas@1.10.4 + +## 1.10.3 + +### Patch Changes + +- typing fix +- Updated dependencies + - @0xsequence/waas@1.10.3 + +## 1.10.2 + +### Patch Changes + +- - waas: add getIdToken method + - indexer: update api client +- Updated dependencies + - @0xsequence/waas@1.10.2 + +## 1.10.1 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/waas@1.10.1 + +## 1.10.0 + +### Minor Changes + +- waas release v1.3.0 + +### Patch Changes + +- Updated dependencies + - @0xsequence/waas@1.10.0 + +## 1.9.37 + +### Patch Changes + +- network: adds nativeToken data to NetworkMetadata constants +- Updated dependencies + - @0xsequence/waas@1.9.37 + +## 1.9.36 + +### Patch Changes + +- guard: export client +- Updated dependencies + - @0xsequence/waas@1.9.36 + +## 1.9.35 + +### Patch Changes + +- guard: update bindings +- Updated dependencies + - @0xsequence/waas@1.9.35 + +## 1.9.34 + +### Patch Changes + +- waas: always use lowercase email +- Updated dependencies + - @0xsequence/waas@1.9.34 + +## 1.9.33 + +### Patch Changes + +- waas: umd build +- Updated dependencies + - @0xsequence/waas@1.9.33 + +## 1.9.32 + +### Patch Changes + +- indexer: update bindings +- Updated dependencies + - @0xsequence/waas@1.9.32 + +## 1.9.31 + +### Patch Changes + +- metadata: token directory changes +- Updated dependencies + - @0xsequence/waas@1.9.31 + +## 1.9.30 + +### Patch Changes + +- update +- Updated dependencies + - @0xsequence/waas@1.9.30 + +## 1.9.29 + +### Patch Changes + +- disable gnosis chain +- Updated dependencies + - @0xsequence/waas@1.9.29 + +## 1.9.28 + +### Patch Changes + +- add utils/merkletree +- Updated dependencies + - @0xsequence/waas@1.9.28 + +## 1.9.27 + +### Patch Changes + +- network: optimistic -> optimism +- waas: remove defaults +- api, sessions: update bindings +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/waas@1.9.27 + +## 1.9.26 + +### Patch Changes + +- - add backend interfaces for pluggable interfaces + - introduce @0xsequence/react-native + - update pnpm to lockfile v9 +- Updated dependencies + - @0xsequence/waas@1.9.26 diff --git a/packages/react-native/package.json b/packages/react-native/package.json new file mode 100644 index 0000000000..690c15fa56 --- /dev/null +++ b/packages/react-native/package.json @@ -0,0 +1,25 @@ +{ + "name": "@0xsequence/react-native", + "version": "2.0.0", + "description": "react-native compat-lib sub-package for Sequence", + "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/react-native", + "source": "src/index.ts", + "main": "dist/0xsequence-react-native.cjs.js", + "module": "dist/0xsequence-react-native.esm.js", + "author": "Horizon Blockchain Games", + "license": "Apache-2.0", + "scripts": { + "test": "echo", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@0xsequence/waas": "workspace:*", + "react-native-keychain": "^8.2.0" + }, + "peerDependencies": {}, + "devDependencies": {}, + "files": [ + "src", + "dist" + ] +} diff --git a/packages/react-native/src/index.ts b/packages/react-native/src/index.ts new file mode 100644 index 0000000000..c05c347fe4 --- /dev/null +++ b/packages/react-native/src/index.ts @@ -0,0 +1 @@ +export * from './keychain-store' diff --git a/packages/react-native/src/keychain-store.ts b/packages/react-native/src/keychain-store.ts new file mode 100644 index 0000000000..9a5a5bbfcd --- /dev/null +++ b/packages/react-native/src/keychain-store.ts @@ -0,0 +1,30 @@ +import { SecureStoreBackend } from '@0xsequence/waas' + +import { getGenericPassword, setGenericPassword, resetGenericPassword } from 'react-native-keychain' + +export class KeychainSecureStoreBackend implements SecureStoreBackend { + constructor() { + // no-op + } + + async get(dbName: string, dbStoreName: string, key: string): Promise { + const credentials = await getGenericPassword({ service: dbStoreName }) + if (credentials) { + return credentials.password + } else { + return null + } + } + + async set(dbName: string, dbStoreName: string, key: string, value: any): Promise { + if (typeof value !== 'string') { + throw new Error('Value must be a string') + } + await setGenericPassword(key, value, { service: dbStoreName }) + return true + } + + async delete(dbName: string, dbStoreName: string, key: string): Promise { + return resetGenericPassword({ service: dbStoreName }) + } +} diff --git a/packages/relayer/CHANGELOG.md b/packages/relayer/CHANGELOG.md new file mode 100644 index 0000000000..cb132caec1 --- /dev/null +++ b/packages/relayer/CHANGELOG.md @@ -0,0 +1,3132 @@ +# @0xsequence/relayer + +## 1.10.8 + +### Patch Changes + +- update metadata bindings +- Updated dependencies + - @0xsequence/abi@1.10.8 + - @0xsequence/core@1.10.8 + - @0xsequence/utils@1.10.8 + +## 1.10.7 + +### Patch Changes + +- minor fixes to waas client +- Updated dependencies + - @0xsequence/abi@1.10.7 + - @0xsequence/core@1.10.7 + - @0xsequence/utils@1.10.7 + +## 1.10.6 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/abi@1.10.6 + - @0xsequence/core@1.10.6 + - @0xsequence/utils@1.10.6 + +## 1.10.5 + +### Patch Changes + +- network: ape-chain-testnet -> apechain-testnet +- Updated dependencies + - @0xsequence/abi@1.10.5 + - @0xsequence/core@1.10.5 + - @0xsequence/utils@1.10.5 + +## 1.10.4 + +### Patch Changes + +- network: add b3-sepolia, ape-chain-testnet, blast, blast-sepolia +- Updated dependencies + - @0xsequence/abi@1.10.4 + - @0xsequence/core@1.10.4 + - @0xsequence/utils@1.10.4 + +## 1.10.3 + +### Patch Changes + +- typing fix +- Updated dependencies + - @0xsequence/abi@1.10.3 + - @0xsequence/core@1.10.3 + - @0xsequence/utils@1.10.3 + +## 1.10.2 + +### Patch Changes + +- - waas: add getIdToken method + - indexer: update api client +- Updated dependencies + - @0xsequence/abi@1.10.2 + - @0xsequence/core@1.10.2 + - @0xsequence/utils@1.10.2 + +## 1.10.1 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/abi@1.10.1 + - @0xsequence/core@1.10.1 + - @0xsequence/utils@1.10.1 + +## 1.10.0 + +### Minor Changes + +- waas release v1.3.0 + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.10.0 + - @0xsequence/core@1.10.0 + - @0xsequence/utils@1.10.0 + +## 1.9.37 + +### Patch Changes + +- network: adds nativeToken data to NetworkMetadata constants +- Updated dependencies + - @0xsequence/abi@1.9.37 + - @0xsequence/core@1.9.37 + - @0xsequence/utils@1.9.37 + +## 1.9.36 + +### Patch Changes + +- guard: export client +- Updated dependencies + - @0xsequence/abi@1.9.36 + - @0xsequence/core@1.9.36 + - @0xsequence/utils@1.9.36 + +## 1.9.35 + +### Patch Changes + +- guard: update bindings +- Updated dependencies + - @0xsequence/abi@1.9.35 + - @0xsequence/core@1.9.35 + - @0xsequence/utils@1.9.35 + +## 1.9.34 + +### Patch Changes + +- waas: always use lowercase email +- Updated dependencies + - @0xsequence/abi@1.9.34 + - @0xsequence/core@1.9.34 + - @0xsequence/utils@1.9.34 + +## 1.9.33 + +### Patch Changes + +- waas: umd build +- Updated dependencies + - @0xsequence/abi@1.9.33 + - @0xsequence/core@1.9.33 + - @0xsequence/utils@1.9.33 + +## 1.9.32 + +### Patch Changes + +- indexer: update bindings +- Updated dependencies + - @0xsequence/abi@1.9.32 + - @0xsequence/core@1.9.32 + - @0xsequence/utils@1.9.32 + +## 1.9.31 + +### Patch Changes + +- metadata: token directory changes +- Updated dependencies + - @0xsequence/abi@1.9.31 + - @0xsequence/core@1.9.31 + - @0xsequence/utils@1.9.31 + +## 1.9.30 + +### Patch Changes + +- update +- Updated dependencies + - @0xsequence/abi@1.9.30 + - @0xsequence/core@1.9.30 + - @0xsequence/utils@1.9.30 + +## 1.9.29 + +### Patch Changes + +- disable gnosis chain +- Updated dependencies + - @0xsequence/abi@1.9.29 + - @0xsequence/core@1.9.29 + - @0xsequence/utils@1.9.29 + +## 1.9.28 + +### Patch Changes + +- add utils/merkletree +- Updated dependencies + - @0xsequence/abi@1.9.28 + - @0xsequence/core@1.9.28 + - @0xsequence/utils@1.9.28 + +## 1.9.27 + +### Patch Changes + +- network: optimistic -> optimism +- waas: remove defaults +- api, sessions: update bindings +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.9.27 + - @0xsequence/core@1.9.27 + - @0xsequence/utils@1.9.27 + +## 1.9.26 + +### Patch Changes + +- - add backend interfaces for pluggable interfaces + - introduce @0xsequence/react-native + - update pnpm to lockfile v9 +- Updated dependencies + - @0xsequence/abi@1.9.26 + - @0xsequence/core@1.9.26 + - @0xsequence/utils@1.9.26 + +## 1.9.25 + +### Patch Changes + +- update webrpc clients with new error types +- Updated dependencies + - @0xsequence/abi@1.9.25 + - @0xsequence/core@1.9.25 + - @0xsequence/utils@1.9.25 + +## 1.9.24 + +### Patch Changes + +- waas: add memoryStore backend to localStore +- Updated dependencies + - @0xsequence/abi@1.9.24 + - @0xsequence/core@1.9.24 + - @0xsequence/utils@1.9.24 + +## 1.9.23 + +### Patch Changes + +- update api client bindings +- Updated dependencies + - @0xsequence/abi@1.9.23 + - @0xsequence/core@1.9.23 + - @0xsequence/utils@1.9.23 + +## 1.9.22 + +### Patch Changes + +- update metadata client bindings +- Updated dependencies + - @0xsequence/abi@1.9.22 + - @0xsequence/core@1.9.22 + - @0xsequence/utils@1.9.22 + +## 1.9.21 + +### Patch Changes + +- api client bindings +- Updated dependencies + - @0xsequence/abi@1.9.21 + - @0xsequence/core@1.9.21 + - @0xsequence/utils@1.9.21 + +## 1.9.20 + +### Patch Changes + +- api client bindings update +- Updated dependencies + - @0xsequence/abi@1.9.20 + - @0xsequence/core@1.9.20 + - @0xsequence/utils@1.9.20 + +## 1.9.19 + +### Patch Changes + +- waas update +- Updated dependencies + - @0xsequence/abi@1.9.19 + - @0xsequence/core@1.9.19 + - @0xsequence/utils@1.9.19 + +## 1.9.18 + +### Patch Changes + +- provider: prohibit dangerous functions +- Updated dependencies + - @0xsequence/abi@1.9.18 + - @0xsequence/core@1.9.18 + - @0xsequence/utils@1.9.18 + +## 1.9.17 + +### Patch Changes + +- network: add xr-sepolia +- Updated dependencies + - @0xsequence/abi@1.9.17 + - @0xsequence/core@1.9.17 + - @0xsequence/utils@1.9.17 + +## 1.9.16 + +### Patch Changes + +- waas: sequence.feeOptions +- Updated dependencies + - @0xsequence/abi@1.9.16 + - @0xsequence/core@1.9.16 + - @0xsequence/utils@1.9.16 + +## 1.9.15 + +### Patch Changes + +- metadata: collection external_link field name fix +- Updated dependencies + - @0xsequence/abi@1.9.15 + - @0xsequence/core@1.9.15 + - @0xsequence/utils@1.9.15 + +## 1.9.14 + +### Patch Changes + +- network: astar-zkatana -> astar-zkyoto +- network: deprecate polygon mumbai network +- network: add xai and polygon amoy +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.9.14 + - @0xsequence/core@1.9.14 + - @0xsequence/utils@1.9.14 + +## 1.9.13 + +### Patch Changes + +- waas: fix @0xsequence/network dependency +- Updated dependencies + - @0xsequence/abi@1.9.13 + - @0xsequence/core@1.9.13 + - @0xsequence/utils@1.9.13 + +## 1.9.12 + +### Patch Changes + +- indexer: update rpc bindings +- provider: signMessage: Serialize the BytesLike or string message into hexstring before sending +- waas: SessionAuthProof +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.9.12 + - @0xsequence/core@1.9.12 + - @0xsequence/utils@1.9.12 + +## 1.9.11 + +### Patch Changes + +- metdata, update rpc bindings +- Updated dependencies + - @0xsequence/abi@1.9.11 + - @0xsequence/core@1.9.11 + - @0xsequence/utils@1.9.11 + +## 1.9.10 + +### Patch Changes + +- update metadata rpc bindings +- Updated dependencies + - @0xsequence/abi@1.9.10 + - @0xsequence/core@1.9.10 + - @0xsequence/utils@1.9.10 + +## 1.9.9 + +### Patch Changes + +- metadata, add SequenceCollections rpc client +- Updated dependencies + - @0xsequence/abi@1.9.9 + - @0xsequence/core@1.9.9 + - @0xsequence/utils@1.9.9 + +## 1.9.8 + +### Patch Changes + +- waas client update +- Updated dependencies + - @0xsequence/abi@1.9.8 + - @0xsequence/core@1.9.8 + - @0xsequence/utils@1.9.8 + +## 1.9.7 + +### Patch Changes + +- update rpc client bindings for api, metadata and relayer +- Updated dependencies + - @0xsequence/abi@1.9.7 + - @0xsequence/core@1.9.7 + - @0xsequence/utils@1.9.7 + +## 1.9.6 + +### Patch Changes + +- waas package update +- Updated dependencies + - @0xsequence/abi@1.9.6 + - @0xsequence/core@1.9.6 + - @0xsequence/utils@1.9.6 + +## 1.9.5 + +### Patch Changes + +- RpcRelayer prioritize project access key +- Updated dependencies + - @0xsequence/abi@1.9.5 + - @0xsequence/core@1.9.5 + - @0xsequence/utils@1.9.5 + +## 1.9.4 + +### Patch Changes + +- waas: fix network dependency +- Updated dependencies + - @0xsequence/abi@1.9.4 + - @0xsequence/core@1.9.4 + - @0xsequence/utils@1.9.4 + +## 1.9.3 + +### Patch Changes + +- provider: don't append access key to RPC url if user has already provided it +- Updated dependencies + - @0xsequence/abi@1.9.3 + - @0xsequence/core@1.9.3 + - @0xsequence/utils@1.9.3 + +## 1.9.2 + +### Patch Changes + +- network: add xai-sepolia +- Updated dependencies + - @0xsequence/abi@1.9.2 + - @0xsequence/core@1.9.2 + - @0xsequence/utils@1.9.2 + +## 1.9.1 + +### Patch Changes + +- analytics fix +- Updated dependencies + - @0xsequence/abi@1.9.1 + - @0xsequence/core@1.9.1 + - @0xsequence/utils@1.9.1 + +## 1.9.0 + +### Minor Changes + +- waas release + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.9.0 + - @0xsequence/core@1.9.0 + - @0xsequence/utils@1.9.0 + +## 1.8.8 + +### Patch Changes + +- update metadata bindings +- Updated dependencies + - @0xsequence/abi@1.8.8 + - @0xsequence/core@1.8.8 + - @0xsequence/utils@1.8.8 + +## 1.8.7 + +### Patch Changes + +- provider: update databeat to 0.9.1 +- Updated dependencies + - @0xsequence/abi@1.8.7 + - @0xsequence/core@1.8.7 + - @0xsequence/utils@1.8.7 + +## 1.8.6 + +### Patch Changes + +- guard: SignedOwnershipProof +- Updated dependencies + - @0xsequence/abi@1.8.6 + - @0xsequence/core@1.8.6 + - @0xsequence/utils@1.8.6 + +## 1.8.5 + +### Patch Changes + +- guard: signOwnershipProof and isSignedOwnershipProof +- Updated dependencies + - @0xsequence/abi@1.8.5 + - @0xsequence/core@1.8.5 + - @0xsequence/utils@1.8.5 + +## 1.8.4 + +### Patch Changes + +- network: add homeverse to networks list +- Updated dependencies + - @0xsequence/abi@1.8.4 + - @0xsequence/core@1.8.4 + - @0xsequence/utils@1.8.4 + +## 1.8.3 + +### Patch Changes + +- api: introduce basic linked wallet support +- Updated dependencies + - @0xsequence/abi@1.8.3 + - @0xsequence/core@1.8.3 + - @0xsequence/utils@1.8.3 + +## 1.8.2 + +### Patch Changes + +- provider: don't initialize analytics unless explicitly requested +- Updated dependencies + - @0xsequence/abi@1.8.2 + - @0xsequence/core@1.8.2 + - @0xsequence/utils@1.8.2 + +## 1.8.1 + +### Patch Changes + +- update to analytics provider +- Updated dependencies + - @0xsequence/abi@1.8.1 + - @0xsequence/core@1.8.1 + - @0xsequence/utils@1.8.1 + +## 1.8.0 + +### Minor Changes + +- provider: project analytics + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.8.0 + - @0xsequence/core@1.8.0 + - @0xsequence/utils@1.8.0 + +## 1.7.2 + +### Patch Changes + +- 0xsequence: ChainId should not be exported as a type +- account, wallet: fix nonce selection +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.7.2 + - @0xsequence/core@1.7.2 + - @0xsequence/utils@1.7.2 + +## 1.7.1 + +### Patch Changes + +- network: add missing avalanche logoURI +- Updated dependencies + - @0xsequence/abi@1.7.1 + - @0xsequence/core@1.7.1 + - @0xsequence/utils@1.7.1 + +## 1.7.0 + +### Minor Changes + +- provider: projectAccessKey is now required + +### Patch Changes + +- network: add NetworkMetadata.logoURI property for all networks +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.7.0 + - @0xsequence/core@1.7.0 + - @0xsequence/utils@1.7.0 + +## 1.6.3 + +### Patch Changes + +- network list update +- Updated dependencies + - @0xsequence/abi@1.6.3 + - @0xsequence/core@1.6.3 + - @0xsequence/utils@1.6.3 + +## 1.6.2 + +### Patch Changes + +- auth: projectAccessKey option +- wallet: use 12 bytes for random space +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.6.2 + - @0xsequence/core@1.6.2 + - @0xsequence/utils@1.6.2 + +## 1.6.1 + +### Patch Changes + +- core: add simple config from subdigest support +- core: fix encode tree with subdigest +- account: implement buildOnChainSignature on Account +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.6.1 + - @0xsequence/core@1.6.1 + - @0xsequence/utils@1.6.1 + +## 1.6.0 + +### Minor Changes + +- account, wallet: parallel transactions by default + +### Patch Changes + +- provider: emit disconnect on sign out +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.6.0 + - @0xsequence/core@1.6.0 + - @0xsequence/utils@1.6.0 + +## 1.5.0 + +### Minor Changes + +- signhub: add 'signing' signer status + +### Patch Changes + +- auth: Session.open: onAccountAddress callback +- account: allow empty transaction bundles +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.5.0 + - @0xsequence/core@1.5.0 + - @0xsequence/utils@1.5.0 + +## 1.4.9 + +### Patch Changes + +- rename SequenceMetadataClient to SequenceMetadata +- Updated dependencies + - @0xsequence/abi@1.4.9 + - @0xsequence/core@1.4.9 + - @0xsequence/utils@1.4.9 + +## 1.4.8 + +### Patch Changes + +- account: Account.getSigners +- Updated dependencies + - @0xsequence/abi@1.4.8 + - @0xsequence/core@1.4.8 + - @0xsequence/utils@1.4.8 + +## 1.4.7 + +### Patch Changes + +- update indexer client bindings +- Updated dependencies + - @0xsequence/abi@1.4.7 + - @0xsequence/core@1.4.7 + - @0xsequence/utils@1.4.7 + +## 1.4.6 + +### Patch Changes + +- - add sepolia networks, mark goerli as deprecated + - update indexer client bindings +- Updated dependencies + - @0xsequence/abi@1.4.6 + - @0xsequence/core@1.4.6 + - @0xsequence/utils@1.4.6 + +## 1.4.5 + +### Patch Changes + +- indexer/metadata: update client bindings +- auth: selectWallet with new address +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.4.5 + - @0xsequence/core@1.4.5 + - @0xsequence/utils@1.4.5 + +## 1.4.4 + +### Patch Changes + +- indexer: update bindings +- auth: handle jwt expiry +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.4.4 + - @0xsequence/core@1.4.4 + - @0xsequence/utils@1.4.4 + +## 1.4.3 + +### Patch Changes + +- guard: return active status from GuardSigner.getAuthMethods +- Updated dependencies + - @0xsequence/abi@1.4.3 + - @0xsequence/core@1.4.3 + - @0xsequence/utils@1.4.3 + +## 1.4.2 + +### Patch Changes + +- guard: update bindings +- Updated dependencies + - @0xsequence/abi@1.4.2 + - @0xsequence/core@1.4.2 + - @0xsequence/utils@1.4.2 + +## 1.4.1 + +### Patch Changes + +- network: remove unused networks +- signhub: orchestrator interface +- guard: auth methods interface +- guard: update bindings for pin and totp +- guard: no more retry logic +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.4.1 + - @0xsequence/core@1.4.1 + - @0xsequence/utils@1.4.1 + +## 1.4.0 + +### Minor Changes + +- project access key support + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.4.0 + - @0xsequence/core@1.4.0 + - @0xsequence/utils@1.4.0 + +## 1.3.0 + +### Minor Changes + +- signhub: account children + +### Patch Changes + +- guard: do not throw when building deploy transaction +- network: snowtrace.io -> subnets.avax.network/c-chain +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.3.0 + - @0xsequence/core@1.3.0 + - @0xsequence/utils@1.3.0 + +## 1.2.9 + +### Patch Changes + +- account: AccountSigner.sendTransaction simulateForFeeOptions +- relayer: update bindings +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.2.9 + - @0xsequence/core@1.2.9 + - @0xsequence/utils@1.2.9 + +## 1.2.8 + +### Patch Changes + +- rename X-Sequence-Token-Key header to X-Access-Key +- Updated dependencies + - @0xsequence/abi@1.2.8 + - @0xsequence/core@1.2.8 + - @0xsequence/utils@1.2.8 + +## 1.2.7 + +### Patch Changes + +- add x-sequence-token-key to clients +- Updated dependencies + - @0xsequence/abi@1.2.7 + - @0xsequence/core@1.2.7 + - @0xsequence/utils@1.2.7 + +## 1.2.6 + +### Patch Changes + +- Fix bind multicall provider +- Updated dependencies + - @0xsequence/abi@1.2.6 + - @0xsequence/core@1.2.6 + - @0xsequence/utils@1.2.6 + +## 1.2.5 + +### Patch Changes + +- Multicall default configuration fixes +- Updated dependencies + - @0xsequence/abi@1.2.5 + - @0xsequence/core@1.2.5 + - @0xsequence/utils@1.2.5 + +## 1.2.4 + +### Patch Changes + +- provider: Adding missing payment provider types to PaymentProviderOption +- provider: WalletRequestHandler.notifyChainChanged +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.2.4 + - @0xsequence/core@1.2.4 + - @0xsequence/utils@1.2.4 + +## 1.2.3 + +### Patch Changes + +- auth, provider: connect to accept optional authorizeNonce +- Updated dependencies + - @0xsequence/abi@1.2.3 + - @0xsequence/core@1.2.3 + - @0xsequence/utils@1.2.3 + +## 1.2.2 + +### Patch Changes + +- provider: allow createContract calls +- core: check for explicit zero address in contract deployments +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.2.2 + - @0xsequence/core@1.2.2 + - @0xsequence/utils@1.2.2 + +## 1.2.1 + +### Patch Changes + +- auth: use sequence api chain id as reference chain id if available +- Updated dependencies + - @0xsequence/abi@1.2.1 + - @0xsequence/core@1.2.1 + - @0xsequence/utils@1.2.1 + +## 1.2.0 + +### Minor Changes + +- split services from session, better local support + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.2.0 + - @0xsequence/core@1.2.0 + - @0xsequence/utils@1.2.0 + +## 1.1.15 + +### Patch Changes + +- guard: remove error filtering +- Updated dependencies + - @0xsequence/abi@1.1.15 + - @0xsequence/core@1.1.15 + - @0xsequence/utils@1.1.15 + +## 1.1.14 + +### Patch Changes + +- guard: add GuardSigner.onError +- Updated dependencies + - @0xsequence/abi@1.1.14 + - @0xsequence/core@1.1.14 + - @0xsequence/utils@1.1.14 + +## 1.1.13 + +### Patch Changes + +- provider: pass client version with connect options +- provider: removing large from BannerSize +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.1.13 + - @0xsequence/core@1.1.13 + - @0xsequence/utils@1.1.13 + +## 1.1.12 + +### Patch Changes + +- provider: adding bannerSize to ConnectOptions +- Updated dependencies + - @0xsequence/abi@1.1.12 + - @0xsequence/core@1.1.12 + - @0xsequence/utils@1.1.12 + +## 1.1.11 + +### Patch Changes + +- add homeverse configs +- Updated dependencies + - @0xsequence/abi@1.1.11 + - @0xsequence/core@1.1.11 + - @0xsequence/utils@1.1.11 + +## 1.1.10 + +### Patch Changes + +- handle default EIP6492 on send +- Updated dependencies + - @0xsequence/abi@1.1.10 + - @0xsequence/core@1.1.10 + - @0xsequence/utils@1.1.10 + +## 1.1.9 + +### Patch Changes + +- Custom default EIP6492 on client +- Updated dependencies + - @0xsequence/abi@1.1.9 + - @0xsequence/core@1.1.9 + - @0xsequence/utils@1.1.9 + +## 1.1.8 + +### Patch Changes + +- metadata: searchMetadata: add types filter +- Updated dependencies + - @0xsequence/abi@1.1.8 + - @0xsequence/core@1.1.8 + - @0xsequence/utils@1.1.8 + +## 1.1.7 + +### Patch Changes + +- adding signInWith connect settings option to allow dapps to automatically login their users with a certain provider optimizing the normal authentication flow +- Updated dependencies + - @0xsequence/abi@1.1.7 + - @0xsequence/core@1.1.7 + - @0xsequence/utils@1.1.7 + +## 1.1.6 + +### Patch Changes + +- metadata: searchMetadata: add chainID and excludeTokenMetadata filters +- Updated dependencies + - @0xsequence/abi@1.1.6 + - @0xsequence/core@1.1.6 + - @0xsequence/utils@1.1.6 + +## 1.1.5 + +### Patch Changes + +- account: re-compute meta-transaction id for wallet deployment transactions +- Updated dependencies + - @0xsequence/abi@1.1.5 + - @0xsequence/core@1.1.5 + - @0xsequence/utils@1.1.5 + +## 1.1.4 + +### Patch Changes + +- network: rename base-mainnet to base +- provider: override isDefaultChain with ConnectOptions.networkId if provided +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.1.4 + - @0xsequence/core@1.1.4 + - @0xsequence/utils@1.1.4 + +## 1.1.3 + +### Patch Changes + +- provider: use network id from transport session +- provider: sign authorization using ConnectOptions.networkId if provided +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.1.3 + - @0xsequence/core@1.1.3 + - @0xsequence/utils@1.1.3 + +## 1.1.2 + +### Patch Changes + +- provider: jsonrpc chain id fixes +- Updated dependencies + - @0xsequence/abi@1.1.2 + - @0xsequence/core@1.1.2 + - @0xsequence/utils@1.1.2 + +## 1.1.1 + +### Patch Changes + +- network: add base mainnet and sepolia +- provider: reject toxic transaction requests +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.1.1 + - @0xsequence/core@1.1.1 + - @0xsequence/utils@1.1.1 + +## 1.1.0 + +### Minor Changes + +- Refactor dapp facing provider + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.1.0 + - @0xsequence/core@1.1.0 + - @0xsequence/utils@1.1.0 + +## 1.0.5 + +### Patch Changes + +- network: export network constants +- guard: use the correct global for fetch +- network: nova-explorer.arbitrum.io -> nova.arbiscan.io +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.0.5 + - @0xsequence/core@1.0.5 + - @0xsequence/utils@1.0.5 + +## 1.0.4 + +### Patch Changes + +- provider: accept name or number for networkId +- Updated dependencies + - @0xsequence/abi@1.0.4 + - @0xsequence/core@1.0.4 + - @0xsequence/utils@1.0.4 + +## 1.0.3 + +### Patch Changes + +- Simpler isValidSignature helpers +- Updated dependencies + - @0xsequence/abi@1.0.3 + - @0xsequence/core@1.0.3 + - @0xsequence/utils@1.0.3 + +## 1.0.2 + +### Patch Changes + +- add extra signature validation utils methods +- Updated dependencies + - @0xsequence/abi@1.0.2 + - @0xsequence/core@1.0.2 + - @0xsequence/utils@1.0.2 + +## 1.0.1 + +### Patch Changes + +- add homeverse testnet +- Updated dependencies + - @0xsequence/abi@1.0.1 + - @0xsequence/core@1.0.1 + - @0xsequence/utils@1.0.1 + +## 1.0.0 + +### Major Changes + +- https://sequence.xyz/blog/sequence-wallet-light-state-sync-full-merkle-wallets + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.0.0 + - @0xsequence/core@1.0.0 + - @0xsequence/utils@1.0.0 + +## 0.43.34 + +### Patch Changes + +- auth: no jwt for indexer +- Updated dependencies + - @0xsequence/abi@0.43.34 + - @0xsequence/config@0.43.34 + - @0xsequence/network@0.43.34 + - @0xsequence/transactions@0.43.34 + - @0xsequence/utils@0.43.34 + +## 0.43.33 + +### Patch Changes + +- Adding onConnectOptionsChange handler to WalletRequestHandler +- Updated dependencies + - @0xsequence/abi@0.43.33 + - @0xsequence/config@0.43.33 + - @0xsequence/network@0.43.33 + - @0xsequence/transactions@0.43.33 + - @0xsequence/utils@0.43.33 + +## 0.43.32 + +### Patch Changes + +- add Base Goerli network +- Updated dependencies + - @0xsequence/abi@0.43.32 + - @0xsequence/config@0.43.32 + - @0xsequence/network@0.43.32 + - @0xsequence/transactions@0.43.32 + - @0xsequence/utils@0.43.32 + +## 0.43.31 + +### Patch Changes + +- remove AuxDataProvider, add promptSignInConnect +- Updated dependencies + - @0xsequence/abi@0.43.31 + - @0xsequence/config@0.43.31 + - @0xsequence/network@0.43.31 + - @0xsequence/transactions@0.43.31 + - @0xsequence/utils@0.43.31 + +## 0.43.30 + +### Patch Changes + +- add arbitrum goerli testnet +- Updated dependencies + - @0xsequence/abi@0.43.30 + - @0xsequence/config@0.43.30 + - @0xsequence/network@0.43.30 + - @0xsequence/transactions@0.43.30 + - @0xsequence/utils@0.43.30 + +## 0.43.29 + +### Patch Changes + +- provider: check availability of window object +- Updated dependencies + - @0xsequence/abi@0.43.29 + - @0xsequence/config@0.43.29 + - @0xsequence/network@0.43.29 + - @0xsequence/transactions@0.43.29 + - @0xsequence/utils@0.43.29 + +## 0.43.28 + +### Patch Changes + +- update api bindings +- Updated dependencies + - @0xsequence/abi@0.43.28 + - @0xsequence/config@0.43.28 + - @0xsequence/network@0.43.28 + - @0xsequence/transactions@0.43.28 + - @0xsequence/utils@0.43.28 + +## 0.43.27 + +### Patch Changes + +- Add rpc is sequence method +- Updated dependencies + - @0xsequence/abi@0.43.27 + - @0xsequence/config@0.43.27 + - @0xsequence/network@0.43.27 + - @0xsequence/transactions@0.43.27 + - @0xsequence/utils@0.43.27 + +## 0.43.26 + +### Patch Changes + +- add zkevm url to enum +- Updated dependencies + - @0xsequence/abi@0.43.26 + - @0xsequence/config@0.43.26 + - @0xsequence/network@0.43.26 + - @0xsequence/transactions@0.43.26 + - @0xsequence/utils@0.43.26 + +## 0.43.25 + +### Patch Changes + +- added polygon zkevm to mainnet networks +- Updated dependencies + - @0xsequence/abi@0.43.25 + - @0xsequence/config@0.43.25 + - @0xsequence/network@0.43.25 + - @0xsequence/transactions@0.43.25 + - @0xsequence/utils@0.43.25 + +## 0.43.24 + +### Patch Changes + +- name change from zkevm to polygon-zkevm +- Updated dependencies + - @0xsequence/abi@0.43.24 + - @0xsequence/config@0.43.24 + - @0xsequence/network@0.43.24 + - @0xsequence/transactions@0.43.24 + - @0xsequence/utils@0.43.24 + +## 0.43.23 + +### Patch Changes + +- update zkEVM name to Polygon zkEVM +- Updated dependencies + - @0xsequence/abi@0.43.23 + - @0xsequence/config@0.43.23 + - @0xsequence/network@0.43.23 + - @0xsequence/transactions@0.43.23 + - @0xsequence/utils@0.43.23 + +## 0.43.22 + +### Patch Changes + +- add zkevm chain +- Updated dependencies + - @0xsequence/abi@0.43.22 + - @0xsequence/config@0.43.22 + - @0xsequence/network@0.43.22 + - @0xsequence/transactions@0.43.22 + - @0xsequence/utils@0.43.22 + +## 0.43.21 + +### Patch Changes + +- api: update client bindings +- Updated dependencies + - @0xsequence/abi@0.43.21 + - @0xsequence/config@0.43.21 + - @0xsequence/network@0.43.21 + - @0xsequence/transactions@0.43.21 + - @0xsequence/utils@0.43.21 + +## 0.43.20 + +### Patch Changes + +- indexer: update bindings +- Updated dependencies + - @0xsequence/abi@0.43.20 + - @0xsequence/config@0.43.20 + - @0xsequence/network@0.43.20 + - @0xsequence/transactions@0.43.20 + - @0xsequence/utils@0.43.20 + +## 0.43.19 + +### Patch Changes + +- session proof update +- Updated dependencies + - @0xsequence/abi@0.43.19 + - @0xsequence/config@0.43.19 + - @0xsequence/network@0.43.19 + - @0xsequence/transactions@0.43.19 + - @0xsequence/utils@0.43.19 + +## 0.43.18 + +### Patch Changes + +- rpc client global check, hardening +- Updated dependencies + - @0xsequence/abi@0.43.18 + - @0xsequence/config@0.43.18 + - @0xsequence/network@0.43.18 + - @0xsequence/transactions@0.43.18 + - @0xsequence/utils@0.43.18 + +## 0.43.17 + +### Patch Changes + +- rpc clients, check of 'global' is defined +- Updated dependencies + - @0xsequence/abi@0.43.17 + - @0xsequence/config@0.43.17 + - @0xsequence/network@0.43.17 + - @0xsequence/transactions@0.43.17 + - @0xsequence/utils@0.43.17 + +## 0.43.16 + +### Patch Changes + +- ethers peerDep to v5, update rpc client global use +- Updated dependencies + - @0xsequence/abi@0.43.16 + - @0xsequence/config@0.43.16 + - @0xsequence/network@0.43.16 + - @0xsequence/transactions@0.43.16 + - @0xsequence/utils@0.43.16 + +## 0.43.15 + +### Patch Changes + +- - provider: expand receiver type on some util methods +- Updated dependencies + - @0xsequence/abi@0.43.15 + - @0xsequence/config@0.43.15 + - @0xsequence/network@0.43.15 + - @0xsequence/transactions@0.43.15 + - @0xsequence/utils@0.43.15 + +## 0.43.14 + +### Patch Changes + +- bump +- Updated dependencies + - @0xsequence/abi@0.43.14 + - @0xsequence/config@0.43.14 + - @0xsequence/network@0.43.14 + - @0xsequence/transactions@0.43.14 + - @0xsequence/utils@0.43.14 + +## 0.43.13 + +### Patch Changes + +- update rpc bindings +- Updated dependencies + - @0xsequence/abi@0.43.13 + - @0xsequence/config@0.43.13 + - @0xsequence/network@0.43.13 + - @0xsequence/transactions@0.43.13 + - @0xsequence/utils@0.43.13 + +## 0.43.12 + +### Patch Changes + +- provider: single wallet init, and add new unregisterWallet() method +- Updated dependencies + - @0xsequence/abi@0.43.12 + - @0xsequence/config@0.43.12 + - @0xsequence/network@0.43.12 + - @0xsequence/transactions@0.43.12 + - @0xsequence/utils@0.43.12 + +## 0.43.11 + +### Patch Changes + +- fix lockfiles +- re-add mocha type deleter +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.43.11 + - @0xsequence/config@0.43.11 + - @0xsequence/network@0.43.11 + - @0xsequence/transactions@0.43.11 + - @0xsequence/utils@0.43.11 + +## 0.43.10 + +### Patch Changes + +- various improvements +- Updated dependencies + - @0xsequence/abi@0.43.10 + - @0xsequence/config@0.43.10 + - @0xsequence/network@0.43.10 + - @0xsequence/transactions@0.43.10 + - @0xsequence/utils@0.43.10 + +## 0.43.9 + +### Patch Changes + +- update deps +- Updated dependencies + - @0xsequence/abi@0.43.9 + - @0xsequence/config@0.43.9 + - @0xsequence/network@0.43.9 + - @0xsequence/transactions@0.43.9 + - @0xsequence/utils@0.43.9 + +## 0.43.8 + +### Patch Changes + +- network: JsonRpcProvider with caching +- Updated dependencies + - @0xsequence/abi@0.43.8 + - @0xsequence/config@0.43.8 + - @0xsequence/network@0.43.8 + - @0xsequence/transactions@0.43.8 + - @0xsequence/utils@0.43.8 + +## 0.43.7 + +### Patch Changes + +- provider: fix wallet network init +- Updated dependencies + - @0xsequence/abi@0.43.7 + - @0xsequence/config@0.43.7 + - @0xsequence/transactions@0.43.7 + - @0xsequence/utils@0.43.7 + +## 0.43.6 + +### Patch Changes + +- metadatata: update rpc bindings +- Updated dependencies + - @0xsequence/abi@0.43.6 + - @0xsequence/config@0.43.6 + - @0xsequence/transactions@0.43.6 + - @0xsequence/utils@0.43.6 + +## 0.43.5 + +### Patch Changes + +- provider: do not set default network for connect messages +- provider: forward missing error message +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.43.5 + - @0xsequence/config@0.43.5 + - @0xsequence/transactions@0.43.5 + - @0xsequence/utils@0.43.5 + +## 0.43.4 + +### Patch Changes + +- no-change version bump to fix incorrectly tagged snapshot build +- Updated dependencies + - @0xsequence/abi@0.43.4 + - @0xsequence/config@0.43.4 + - @0xsequence/transactions@0.43.4 + - @0xsequence/utils@0.43.4 + +## 0.43.3 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/abi@0.43.3 + - @0xsequence/config@0.43.3 + - @0xsequence/transactions@0.43.3 + - @0xsequence/utils@0.43.3 + +## 0.43.2 + +### Patch Changes + +- provider: implement connectUnchecked +- Updated dependencies + - @0xsequence/abi@0.43.2 + - @0xsequence/config@0.43.2 + - @0xsequence/transactions@0.43.2 + - @0xsequence/utils@0.43.2 + +## 0.43.1 + +### Patch Changes + +- update to latest ethauth dep +- Updated dependencies + - @0xsequence/abi@0.43.1 + - @0xsequence/config@0.43.1 + - @0xsequence/transactions@0.43.1 + - @0xsequence/utils@0.43.1 + +## 0.43.0 + +### Minor Changes + +- move ethers to a peer dependency + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.43.0 + - @0xsequence/config@0.43.0 + - @0xsequence/transactions@0.43.0 + - @0xsequence/utils@0.43.0 + +## 0.42.10 + +### Patch Changes + +- add auxDataProvider +- Updated dependencies + - @0xsequence/abi@0.42.10 + - @0xsequence/config@0.42.10 + - @0xsequence/transactions@0.42.10 + - @0xsequence/utils@0.42.10 + +## 0.42.9 + +### Patch Changes + +- provider: add eip-191 exceptions +- Updated dependencies + - @0xsequence/abi@0.42.9 + - @0xsequence/config@0.42.9 + - @0xsequence/transactions@0.42.9 + - @0xsequence/utils@0.42.9 + +## 0.42.8 + +### Patch Changes + +- provider: skip setting intent origin if we're unity plugin +- Updated dependencies + - @0xsequence/abi@0.42.8 + - @0xsequence/config@0.42.8 + - @0xsequence/transactions@0.42.8 + - @0xsequence/utils@0.42.8 + +## 0.42.7 + +### Patch Changes + +- Add sign in options to connection settings +- Updated dependencies + - @0xsequence/abi@0.42.7 + - @0xsequence/config@0.42.7 + - @0xsequence/transactions@0.42.7 + - @0xsequence/utils@0.42.7 + +## 0.42.6 + +### Patch Changes + +- api bindings update +- Updated dependencies + - @0xsequence/abi@0.42.6 + - @0xsequence/config@0.42.6 + - @0xsequence/transactions@0.42.6 + - @0xsequence/utils@0.42.6 + +## 0.42.5 + +### Patch Changes + +- relayer: don't treat missing receipt as hard failure +- Updated dependencies + - @0xsequence/abi@0.42.5 + - @0xsequence/config@0.42.5 + - @0xsequence/transactions@0.42.5 + - @0xsequence/utils@0.42.5 + +## 0.42.4 + +### Patch Changes + +- provider: add custom app protocol to connect options +- Updated dependencies + - @0xsequence/abi@0.42.4 + - @0xsequence/config@0.42.4 + - @0xsequence/transactions@0.42.4 + - @0xsequence/utils@0.42.4 + +## 0.42.3 + +### Patch Changes + +- update api bindings +- Updated dependencies + - @0xsequence/abi@0.42.3 + - @0xsequence/config@0.42.3 + - @0xsequence/transactions@0.42.3 + - @0xsequence/utils@0.42.3 + +## 0.42.2 + +### Patch Changes + +- disable rinkeby network +- Updated dependencies + - @0xsequence/abi@0.42.2 + - @0xsequence/config@0.42.2 + - @0xsequence/transactions@0.42.2 + - @0xsequence/utils@0.42.2 + +## 0.42.1 + +### Patch Changes + +- wallet: optional waitForReceipt parameter +- Updated dependencies + - @0xsequence/abi@0.42.1 + - @0xsequence/config@0.42.1 + - @0xsequence/transactions@0.42.1 + - @0xsequence/utils@0.42.1 + +## 0.42.0 + +### Minor Changes + +- relayer: estimateGasLimits -> simulate +- add simulator package + +### Patch Changes + +- transactions: fix flattenAuxTransactions +- provider: only filter nullish values +- provider: re-map transaction 'gas' back to 'gasLimit' +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.42.0 + - @0xsequence/config@0.42.0 + - @0xsequence/transactions@0.42.0 + - @0xsequence/utils@0.42.0 + +## 0.41.3 + +### Patch Changes + +- api bindings update +- Updated dependencies + - @0xsequence/abi@0.41.3 + - @0xsequence/config@0.41.3 + - @0xsequence/transactions@0.41.3 + - @0xsequence/utils@0.41.3 + +## 0.41.2 + +### Patch Changes + +- api bindings update +- Updated dependencies + - @0xsequence/abi@0.41.2 + - @0xsequence/config@0.41.2 + - @0xsequence/transactions@0.41.2 + - @0xsequence/utils@0.41.2 + +## 0.41.1 + +### Patch Changes + +- update default networks +- Updated dependencies + - @0xsequence/abi@0.41.1 + - @0xsequence/config@0.41.1 + - @0xsequence/transactions@0.41.1 + - @0xsequence/utils@0.41.1 + +## 0.41.0 + +### Minor Changes + +- relayer: fix Relayer.wait() interface + + The interface for calling Relayer.wait() has changed. Instead of a single optional ill-defined timeout/delay parameter, there are three optional parameters, in order: + + - timeout: the maximum time to wait for the transaction receipt + - delay: the polling interval, i.e. the time to wait between requests + - maxFails: the maximum number of hard failures to tolerate before giving up + + Please update your codebase accordingly. + +- relayer: add optional waitForReceipt parameter to Relayer.relay + + The behaviour of Relayer.relay() was not well-defined with respect to whether or not it waited for a receipt. + This change allows the caller to specify whether to wait or not, with the default behaviour being to wait. + +### Patch Changes + +- relayer: wait receipt retry logic +- fix wrapped object error +- provider: forward delegateCall and revertOnError transaction fields +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.41.0 + - @0xsequence/config@0.41.0 + - @0xsequence/transactions@0.41.0 + - @0xsequence/utils@0.41.0 + +## 0.40.6 + +### Patch Changes + +- add arbitrum-nova chain +- Updated dependencies + - @0xsequence/abi@0.40.6 + - @0xsequence/config@0.40.6 + - @0xsequence/transactions@0.40.6 + - @0xsequence/utils@0.40.6 + +## 0.40.5 + +### Patch Changes + +- api: update bindings +- Updated dependencies + - @0xsequence/abi@0.40.5 + - @0xsequence/config@0.40.5 + - @0xsequence/transactions@0.40.5 + - @0xsequence/utils@0.40.5 + +## 0.40.4 + +### Patch Changes + +- add unreal transport +- Updated dependencies + - @0xsequence/abi@0.40.4 + - @0xsequence/config@0.40.4 + - @0xsequence/transactions@0.40.4 + - @0xsequence/utils@0.40.4 + +## 0.40.3 + +### Patch Changes + +- provider: fix MessageToSign message type +- Updated dependencies + - @0xsequence/abi@0.40.3 + - @0xsequence/config@0.40.3 + - @0xsequence/transactions@0.40.3 + - @0xsequence/utils@0.40.3 + +## 0.40.2 + +### Patch Changes + +- Wallet provider, loadSession method +- Updated dependencies + - @0xsequence/abi@0.40.2 + - @0xsequence/config@0.40.2 + - @0xsequence/transactions@0.40.2 + - @0xsequence/utils@0.40.2 + +## 0.40.1 + +### Patch Changes + +- export sequence.initWallet and sequence.getWallet +- Updated dependencies + - @0xsequence/abi@0.40.1 + - @0xsequence/config@0.40.1 + - @0xsequence/transactions@0.40.1 + - @0xsequence/utils@0.40.1 + +## 0.40.0 + +### Minor Changes + +- add sequence.initWallet(network, config) and sequence.getWallet() helper methods + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.40.0 + - @0xsequence/config@0.40.0 + - @0xsequence/transactions@0.40.0 + - @0xsequence/utils@0.40.0 + +## 0.39.6 + +### Patch Changes + +- indexer: update client bindings +- Updated dependencies + - @0xsequence/abi@0.39.6 + - @0xsequence/config@0.39.6 + - @0xsequence/transactions@0.39.6 + - @0xsequence/utils@0.39.6 + +## 0.39.5 + +### Patch Changes + +- provider: fix networkRpcUrl config option +- Updated dependencies + - @0xsequence/abi@0.39.5 + - @0xsequence/config@0.39.5 + - @0xsequence/transactions@0.39.5 + - @0xsequence/utils@0.39.5 + +## 0.39.4 + +### Patch Changes + +- api: update client bindings +- Updated dependencies + - @0xsequence/abi@0.39.4 + - @0xsequence/config@0.39.4 + - @0xsequence/transactions@0.39.4 + - @0xsequence/utils@0.39.4 + +## 0.39.3 + +### Patch Changes + +- add request method on Web3Provider +- Updated dependencies + - @0xsequence/abi@0.39.3 + - @0xsequence/config@0.39.3 + - @0xsequence/transactions@0.39.3 + - @0xsequence/utils@0.39.3 + +## 0.39.2 + +### Patch Changes + +- update umd name +- Updated dependencies + - @0xsequence/abi@0.39.2 + - @0xsequence/config@0.39.2 + - @0xsequence/transactions@0.39.2 + - @0xsequence/utils@0.39.2 + +## 0.39.1 + +### Patch Changes + +- add Aurora network +- add origin info for accountsChanged event to handle it per dapp +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.39.1 + - @0xsequence/config@0.39.1 + - @0xsequence/transactions@0.39.1 + - @0xsequence/utils@0.39.1 + +## 0.39.0 + +### Minor Changes + +- abstract window.localStorage to interface type + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.39.0 + - @0xsequence/config@0.39.0 + - @0xsequence/transactions@0.39.0 + - @0xsequence/utils@0.39.0 + +## 0.38.2 + +### Patch Changes + +- provider: add Settings.defaultPurchaseAmount +- Updated dependencies + - @0xsequence/abi@0.38.2 + - @0xsequence/config@0.38.2 + - @0xsequence/transactions@0.38.2 + - @0xsequence/utils@0.38.2 + +## 0.38.1 + +### Patch Changes + +- update api and metadata rpc bindings +- Updated dependencies + - @0xsequence/abi@0.38.1 + - @0xsequence/config@0.38.1 + - @0xsequence/transactions@0.38.1 + - @0xsequence/utils@0.38.1 + +## 0.38.0 + +### Minor Changes + +- api: update bindings, change TokenPrice interface +- bridge: remove @0xsequence/bridge package +- api: update bindings, rename ContractCallArg to TupleComponent + +### Patch Changes + +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.38.0 + - @0xsequence/config@0.38.0 + - @0xsequence/transactions@0.38.0 + - @0xsequence/utils@0.38.0 + +## 0.37.1 + +### Patch Changes + +- Add back sortNetworks - Removing sorting was a breaking change for dapps on older versions which directly integrate sequence. +- Updated dependencies + - @0xsequence/abi@0.37.1 + - @0xsequence/config@0.37.1 + - @0xsequence/transactions@0.37.1 + - @0xsequence/utils@0.37.1 + +## 0.37.0 + +### Minor Changes + +- network related fixes and improvements +- api: bindings: exchange rate lookups + +### Patch Changes + +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.37.0 + - @0xsequence/config@0.37.0 + - @0xsequence/transactions@0.37.0 + - @0xsequence/utils@0.37.0 + +## 0.36.13 + +### Patch Changes + +- api: update bindings with new price endpoints +- Updated dependencies + - @0xsequence/abi@0.36.13 + - @0xsequence/config@0.36.13 + - @0xsequence/transactions@0.36.13 + - @0xsequence/utils@0.36.13 + +## 0.36.12 + +### Patch Changes + +- wallet: skip remote signers if not needed +- auth: check that signature meets threshold before requesting auth token +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.36.12 + - @0xsequence/config@0.36.12 + - @0xsequence/transactions@0.36.12 + - @0xsequence/utils@0.36.12 + +## 0.36.11 + +### Patch Changes + +- Prefix EIP191 message on wallet-request-handler +- Updated dependencies + - @0xsequence/abi@0.36.11 + - @0xsequence/config@0.36.11 + - @0xsequence/transactions@0.36.11 + - @0xsequence/utils@0.36.11 + +## 0.36.10 + +### Patch Changes + +- support bannerUrl on connect +- Updated dependencies + - @0xsequence/abi@0.36.10 + - @0xsequence/config@0.36.10 + - @0xsequence/transactions@0.36.10 + - @0xsequence/utils@0.36.10 + +## 0.36.9 + +### Patch Changes + +- minor dev xp improvements +- Updated dependencies + - @0xsequence/abi@0.36.9 + - @0xsequence/config@0.36.9 + - @0xsequence/transactions@0.36.9 + - @0xsequence/utils@0.36.9 + +## 0.36.8 + +### Patch Changes + +- more connect options (theme, payment providers, funding currencies) +- Updated dependencies + - @0xsequence/abi@0.36.8 + - @0xsequence/config@0.36.8 + - @0xsequence/transactions@0.36.8 + - @0xsequence/utils@0.36.8 + +## 0.36.7 + +### Patch Changes + +- fix missing break +- Updated dependencies + - @0xsequence/abi@0.36.7 + - @0xsequence/config@0.36.7 + - @0xsequence/transactions@0.36.7 + - @0xsequence/utils@0.36.7 + +## 0.36.6 + +### Patch Changes + +- wallet_switchEthereumChain support +- Updated dependencies + - @0xsequence/abi@0.36.6 + - @0xsequence/config@0.36.6 + - @0xsequence/transactions@0.36.6 + - @0xsequence/utils@0.36.6 + +## 0.36.5 + +### Patch Changes + +- auth: bump ethauth to 0.7.0 + network, wallet: don't assume position of auth network in list + api/indexer/metadata: trim trailing slash on hostname, and add endpoint urls + relayer: Allow to specify local relayer transaction parameters like gas price or gas limit +- Updated dependencies + - @0xsequence/abi@0.36.5 + - @0xsequence/config@0.36.5 + - @0xsequence/transactions@0.36.5 + - @0xsequence/utils@0.36.5 + +## 0.36.4 + +### Patch Changes + +- Updating list of chain ids to include other ethereum compatible chains +- Updated dependencies + - @0xsequence/abi@0.36.4 + - @0xsequence/config@0.36.4 + - @0xsequence/transactions@0.36.4 + - @0xsequence/utils@0.36.4 + +## 0.36.3 + +### Patch Changes + +- provider: pass connect options to prompter methods +- Updated dependencies + - @0xsequence/abi@0.36.3 + - @0xsequence/config@0.36.3 + - @0xsequence/transactions@0.36.3 + - @0xsequence/utils@0.36.3 + +## 0.36.2 + +### Patch Changes + +- transactions: Setting target to 0x0 when empty to during SequenceTxAbiEncode +- Updated dependencies + - @0xsequence/abi@0.36.2 + - @0xsequence/config@0.36.2 + - @0xsequence/transactions@0.36.2 + - @0xsequence/utils@0.36.2 + +## 0.36.1 + +### Patch Changes + +- metadata: update client with more fields +- Updated dependencies + - @0xsequence/abi@0.36.1 + - @0xsequence/config@0.36.1 + - @0xsequence/transactions@0.36.1 + - @0xsequence/utils@0.36.1 + +## 0.36.0 + +### Minor Changes + +- relayer, wallet: fee quote support + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.36.0 + - @0xsequence/config@0.36.0 + - @0xsequence/transactions@0.36.0 + - @0xsequence/utils@0.36.0 + +## 0.35.12 + +### Patch Changes + +- provider: rename wallet.commands to wallet.utils +- Updated dependencies + - @0xsequence/abi@0.35.12 + - @0xsequence/config@0.35.12 + - @0xsequence/transactions@0.35.12 + - @0xsequence/utils@0.35.12 + +## 0.35.11 + +### Patch Changes + +- provider/utils: smoother message validation +- Updated dependencies + - @0xsequence/abi@0.35.11 + - @0xsequence/config@0.35.11 + - @0xsequence/transactions@0.35.11 + - @0xsequence/utils@0.35.11 + +## 0.35.10 + +### Patch Changes + +- upgrade deps +- Updated dependencies + - @0xsequence/abi@0.35.10 + - @0xsequence/config@0.35.10 + - @0xsequence/transactions@0.35.10 + - @0xsequence/utils@0.35.10 + +## 0.35.9 + +### Patch Changes + +- provider: window-transport override event handlers with new wallet instance +- Updated dependencies + - @0xsequence/abi@0.35.9 + - @0xsequence/config@0.35.9 + - @0xsequence/transactions@0.35.9 + - @0xsequence/utils@0.35.9 + +## 0.35.8 + +### Patch Changes + +- provider: async wallet sign in improvements +- Updated dependencies + - @0xsequence/abi@0.35.8 + - @0xsequence/config@0.35.8 + - @0xsequence/transactions@0.35.8 + - @0xsequence/utils@0.35.8 + +## 0.35.7 + +### Patch Changes + +- config: cache wallet configs +- Updated dependencies + - @0xsequence/abi@0.35.7 + - @0xsequence/config@0.35.7 + - @0xsequence/transactions@0.35.7 + - @0xsequence/utils@0.35.7 + +## 0.35.6 + +### Patch Changes + +- provider: support async signin of wallet request handler +- Updated dependencies + - @0xsequence/abi@0.35.6 + - @0xsequence/config@0.35.6 + - @0xsequence/transactions@0.35.6 + - @0xsequence/utils@0.35.6 + +## 0.35.5 + +### Patch Changes + +- wallet: skip threshold check during fee estimation +- Updated dependencies + - @0xsequence/abi@0.35.5 + - @0xsequence/config@0.35.5 + - @0xsequence/transactions@0.35.5 + - @0xsequence/utils@0.35.5 + +## 0.35.4 + +### Patch Changes + +- - browser extension mode, center window +- Updated dependencies + - @0xsequence/abi@0.35.4 + - @0xsequence/config@0.35.4 + - @0xsequence/transactions@0.35.4 + - @0xsequence/utils@0.35.4 + +## 0.35.3 + +### Patch Changes + +- - update window position when in browser extension mode +- Updated dependencies + - @0xsequence/abi@0.35.3 + - @0xsequence/config@0.35.3 + - @0xsequence/transactions@0.35.3 + - @0xsequence/utils@0.35.3 + +## 0.35.2 + +### Patch Changes + +- - provider: WindowMessageHandler accept optional windowHref +- Updated dependencies + - @0xsequence/abi@0.35.2 + - @0xsequence/config@0.35.2 + - @0xsequence/transactions@0.35.2 + - @0xsequence/utils@0.35.2 + +## 0.35.1 + +### Patch Changes + +- wallet: update config on undeployed too +- Updated dependencies + - @0xsequence/abi@0.35.1 + - @0xsequence/config@0.35.1 + - @0xsequence/transactions@0.35.1 + - @0xsequence/utils@0.35.1 + +## 0.35.0 + +### Minor Changes + +- - config: add buildStubSignature + - provider: add checks to signing cases for wallet deployment and config statuses + - provider: add prompt for wallet deployment + - relayer: add BaseRelayer.prependWalletDeploy + - relayer: add Relayer.feeOptions + - relayer: account for wallet deployment in fee estimation + - transactions: add fromTransactionish + - wallet: add Account.prependConfigUpdate + - wallet: add Account.getFeeOptions + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.35.0 + - @0xsequence/config@0.35.0 + - @0xsequence/transactions@0.35.0 + - @0xsequence/utils@0.35.0 + +## 0.34.0 + +### Minor Changes + +- - upgrade deps + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.34.0 + - @0xsequence/config@0.34.0 + - @0xsequence/transactions@0.34.0 + - @0xsequence/utils@0.34.0 + +## 0.33.2 + +### Patch Changes + +- Updated dependencies + - @0xsequence/transactions@0.33.2 + +## 0.31.1 + +### Patch Changes + +- relayer: add Relayer.simulate + +## 0.31.0 + +### Minor Changes + +- - upgrading to ethers v5.5 + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.31.0 + - @0xsequence/config@0.31.0 + - @0xsequence/transactions@0.31.0 + - @0xsequence/utils@0.31.0 + +## 0.30.0 + +### Minor Changes + +- - upgrade most deps + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.30.0 + - @0xsequence/config@0.30.0 + - @0xsequence/transactions@0.30.0 + - @0xsequence/utils@0.30.0 + +## 0.29.8 + +### Patch Changes + +- update api +- Updated dependencies [undefined] + - @0xsequence/abi@0.29.8 + - @0xsequence/config@0.29.8 + - @0xsequence/transactions@0.29.8 + - @0xsequence/utils@0.29.8 + +## 0.29.6 + +### Patch Changes + +- @0xsequence/config@0.29.6 +- @0xsequence/transactions@0.29.6 + +## 0.29.5 + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/config@0.29.5 + +## 0.29.2 + +### Patch Changes + +- relayer: don't pass nonce to GetMetaTxnNetworkFeeOptions + +## 0.29.0 + +### Minor Changes + +- major architectural changes in Sequence design + + - only one API instance, API is no longer a per-chain service + - separate per-chain indexer service, API no longer handles indexing + - single contract metadata service, API no longer serves metadata + + chaind package has been removed, indexer and metadata packages have been added + + stronger typing with new explicit ChainId type + + multicall fixes and improvements + + forbid "wait" transactions in sendTransactionBatch calls + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/config@0.29.0 + - @0xsequence/transactions@0.29.0 + - @0xsequence/abi@0.29.0 + - @0xsequence/utils@0.29.0 + +## 0.28.0 + +### Minor Changes + +- extension provider + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.28.0 + - @0xsequence/chaind@0.28.0 + - @0xsequence/config@0.28.0 + - @0xsequence/transactions@0.28.0 + - @0xsequence/utils@0.28.0 + +## 0.27.1 + +### Patch Changes + +- fix waitReceipt polling logic + +## 0.27.0 + +### Minor Changes + +- Add requireFreshSigner lib to sessions + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.27.0 + - @0xsequence/chaind@0.27.0 + - @0xsequence/config@0.27.0 + - @0xsequence/transactions@0.27.0 + - @0xsequence/utils@0.27.0 + +## 0.26.0 + +### Minor Changes + +- update relayer client bindings + provide the wallet's address for calls to SendMetaTxn + modify the semantics of Relayer.getNonce() to allow relayers to select nonce spaces for clients + +## 0.25.1 + +### Patch Changes + +- Fix build typescrypt issue +- Updated dependencies [undefined] + - @0xsequence/abi@0.25.1 + - @0xsequence/chaind@0.25.1 + - @0xsequence/config@0.25.1 + - @0xsequence/transactions@0.25.1 + - @0xsequence/utils@0.25.1 + +## 0.25.0 + +### Minor Changes + +- 10c8af8: Add estimator package + Fix multicall few calls bug + +### Patch Changes + +- Updated dependencies [10c8af8] + - @0xsequence/abi@0.25.0 + - @0xsequence/chaind@0.25.0 + - @0xsequence/config@0.25.0 + - @0xsequence/transactions@0.25.0 + - @0xsequence/utils@0.25.0 + +## 0.24.1 + +### Patch Changes + +- relayer: wait for queued status instead of unknown + +## 0.24.0 + +### Minor Changes + +- pass wallet config and nonce to GetMetaTxnNetworkFeeOptions + +## 0.23.0 + +### Minor Changes + +- - relayer: offer variety of gas fee options from the relayer service" + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.23.0 + - @0xsequence/chaind@0.23.0 + - @0xsequence/config@0.23.0 + - @0xsequence/transactions@0.23.0 + - @0xsequence/utils@0.23.0 + +## 0.22.2 + +### Patch Changes + +- e1c109e: Fix authProof on expired sessions +- Updated dependencies [e1c109e] + - @0xsequence/abi@0.22.2 + - @0xsequence/chaind@0.22.2 + - @0xsequence/config@0.22.2 + - @0xsequence/transactions@0.22.2 + - @0xsequence/utils@0.22.2 + +## 0.22.1 + +### Patch Changes + +- transport session cache +- Updated dependencies [undefined] + - @0xsequence/abi@0.22.1 + - @0xsequence/chaind@0.22.1 + - @0xsequence/config@0.22.1 + - @0xsequence/transactions@0.22.1 + - @0xsequence/utils@0.22.1 + +## 0.22.0 + +### Minor Changes + +- e667b65: Expose all relayer options on networks + +### Patch Changes + +- Updated dependencies [e667b65] + - @0xsequence/abi@0.22.0 + - @0xsequence/utils@0.22.0 + - @0xsequence/chaind@0.22.0 + - @0xsequence/config@0.22.0 + - @0xsequence/transactions@0.22.0 + +## 0.21.5 + +### Patch Changes + +- Give priority to metaTxnId returned by relayer +- Updated dependencies [undefined] + - @0xsequence/abi@0.21.5 + - @0xsequence/chaind@0.21.5 + - @0xsequence/config@0.21.5 + - @0xsequence/transactions@0.21.5 + - @0xsequence/utils@0.21.5 + +## 0.21.4 + +### Patch Changes + +- Add has enough signers method +- Updated dependencies [undefined] + - @0xsequence/abi@0.21.4 + - @0xsequence/chaind@0.21.4 + - @0xsequence/config@0.21.4 + - @0xsequence/transactions@0.21.4 + - @0xsequence/utils@0.21.4 + +## 0.21.3 + +### Patch Changes + +- add window session cache +- Updated dependencies [undefined] + - @0xsequence/abi@0.21.3 + - @0xsequence/chaind@0.21.3 + - @0xsequence/config@0.21.3 + - @0xsequence/transactions@0.21.3 + - @0xsequence/utils@0.21.3 + +## 0.21.2 + +### Patch Changes + +- exception handlind in relayer +- Updated dependencies [undefined] + - @0xsequence/abi@0.21.2 + - @0xsequence/chaind@0.21.2 + - @0xsequence/config@0.21.2 + - @0xsequence/transactions@0.21.2 + - @0xsequence/utils@0.21.2 + +## 0.21.0 + +### Minor Changes + +- - fix gas estimation on wallets with large number of signers + - update to session handling and wallet config construction upon auth + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.21.0 + - @0xsequence/chaind@0.21.0 + - @0xsequence/config@0.21.0 + - @0xsequence/transactions@0.21.0 + - @0xsequence/utils@0.21.0 + +## 0.19.3 + +### Patch Changes + +- jwtAuth visibility, package version sync +- Updated dependencies [undefined] + - @0xsequence/abi@0.19.3 + - @0xsequence/chaind@0.19.3 + - @0xsequence/config@0.19.3 + - @0xsequence/transactions@0.19.3 + - @0xsequence/utils@0.19.3 + +## 0.19.2 + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.19.2 + - @0xsequence/config@0.19.2 + - @0xsequence/transactions@0.19.2 + +## 0.19.0 + +### Minor Changes + +- - provider, improve dapp / wallet transport io + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.19.0 + - @0xsequence/chaind@0.19.0 + - @0xsequence/config@0.19.0 + - @0xsequence/transactions@0.19.0 + - @0xsequence/utils@0.19.0 + +## 0.18.0 + +### Minor Changes + +- relayer improvements and pending transaction handling + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.18.0 + - @0xsequence/chaind@0.18.0 + - @0xsequence/config@0.18.0 + - @0xsequence/transactions@0.18.0 + - @0xsequence/utils@0.18.0 + +## 0.16.0 + +### Minor Changes + +- relayer as its own service separate from chaind + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.16.0 + - @0xsequence/chaind@0.16.0 + - @0xsequence/config@0.16.0 + - @0xsequence/transactions@0.16.0 + - @0xsequence/utils@0.16.0 + +## 0.15.1 + +### Patch Changes + +- update api clients +- Updated dependencies [undefined] + - @0xsequence/abi@0.15.1 + - @0xsequence/chaind@0.15.1 + - @0xsequence/config@0.15.1 + - @0xsequence/transactions@0.15.1 + - @0xsequence/utils@0.15.1 + +## 0.15.0 + +### Minor Changes + +- - update chaind and api bindings + - replace EstimateMetaTxnGasReceipt with UpdateMetaTxnGasLimits and GetMetaTxnNetworkFeeOptions + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/chaind@0.15.0 + - @0xsequence/transactions@0.15.0 + +## 0.14.3 + +### Patch Changes + +- Fix 0xSequence relayer dependencies +- Updated dependencies [undefined] + - @0xsequence/abi@0.14.3 + - @0xsequence/chaind@0.14.3 + - @0xsequence/config@0.14.3 + - @0xsequence/transactions@0.14.3 + - @0xsequence/utils@0.14.3 + +## 0.14.2 + +### Patch Changes + +- Add debug logs to rpc-relayer +- Updated dependencies [undefined] + - @0xsequence/abi@0.14.2 + - @0xsequence/chaind@0.14.2 + - @0xsequence/config@0.14.2 + - @0xsequence/transactions@0.14.2 + +## 0.14.0 + +### Minor Changes + +- update sequence utils finder which includes optimization + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.14.0 + - @0xsequence/chaind@0.14.0 + - @0xsequence/config@0.14.0 + - @0xsequence/transactions@0.14.0 + +## 0.13.0 + +### Minor Changes + +- Update SequenceUtils deployed contract + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.13.0 + - @0xsequence/chaind@0.13.0 + - @0xsequence/config@0.13.0 + - @0xsequence/transactions@0.13.0 + +## 0.12.1 + +### Patch Changes + +- npm bump +- Updated dependencies [undefined] + - @0xsequence/abi@0.12.1 + - @0xsequence/chaind@0.12.1 + - @0xsequence/config@0.12.1 + - @0xsequence/transactions@0.12.1 + +## 0.12.0 + +### Minor Changes + +- provider: improvements to window transport + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.12.0 + - @0xsequence/chaind@0.12.0 + - @0xsequence/config@0.12.0 + - @0xsequence/transactions@0.12.0 + +## 0.11.4 + +### Patch Changes + +- update api client +- Updated dependencies [undefined] + - @0xsequence/abi@0.11.4 + - @0xsequence/chaind@0.11.4 + - @0xsequence/config@0.11.4 + - @0xsequence/transactions@0.11.4 + +## 0.11.3 + +### Patch Changes + +- improve openWindow state options handling +- Updated dependencies [undefined] + - @0xsequence/abi@0.11.3 + - @0xsequence/chaind@0.11.3 + - @0xsequence/config@0.11.3 + - @0xsequence/transactions@0.11.3 + +## 0.11.2 + +### Patch Changes + +- Fix multicall proxy scopes +- Updated dependencies [undefined] + - @0xsequence/abi@0.11.2 + - @0xsequence/chaind@0.11.2 + - @0xsequence/config@0.11.2 + - @0xsequence/transactions@0.11.2 + +## 0.11.1 + +### Patch Changes + +- Add support for dynamic and nested signatures +- Updated dependencies [undefined] + - @0xsequence/abi@0.11.1 + - @0xsequence/chaind@0.11.1 + - @0xsequence/config@0.11.1 + - @0xsequence/transactions@0.11.1 + +## 0.11.0 + +### Minor Changes + +- Update wallet context to 1.7 contracts + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.11.0 + - @0xsequence/chaind@0.11.0 + - @0xsequence/config@0.11.0 + - @0xsequence/transactions@0.11.0 + +## 0.10.9 + +### Patch Changes + +- add support for public addresses as signers in session.open +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.9 + - @0xsequence/chaind@0.10.9 + - @0xsequence/config@0.10.9 + - @0xsequence/transactions@0.10.9 + +## 0.10.8 + +### Patch Changes + +- Multicall production configuration +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.8 + - @0xsequence/chaind@0.10.8 + - @0xsequence/config@0.10.8 + - @0xsequence/transactions@0.10.8 + +## 0.10.7 + +### Patch Changes + +- allow provider transport to force disconnect +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.7 + - @0xsequence/chaind@0.10.7 + - @0xsequence/config@0.10.7 + - @0xsequence/transactions@0.10.7 + +## 0.10.6 + +### Patch Changes + +- - fix getWalletState method +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.6 + - @0xsequence/chaind@0.10.6 + - @0xsequence/config@0.10.6 + - @0xsequence/transactions@0.10.6 + +## 0.10.5 + +### Patch Changes + +- update relayer gas refund options +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.5 + - @0xsequence/chaind@0.10.5 + - @0xsequence/config@0.10.5 + - @0xsequence/transactions@0.10.5 + +## 0.10.4 + +### Patch Changes + +- Update api proto +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.4 + - @0xsequence/chaind@0.10.4 + - @0xsequence/config@0.10.4 + - @0xsequence/transactions@0.10.4 + +## 0.10.3 + +### Patch Changes + +- Fix loading config cross-chain +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.3 + - @0xsequence/chaind@0.10.3 + - @0xsequence/config@0.10.3 + - @0xsequence/transactions@0.10.3 + +## 0.10.2 + +### Patch Changes + +- - message digest fix +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.2 + - @0xsequence/chaind@0.10.2 + - @0xsequence/config@0.10.2 + - @0xsequence/transactions@0.10.2 + +## 0.10.1 + +### Patch Changes + +- upgrade deps +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.1 + - @0xsequence/chaind@0.10.1 + - @0xsequence/config@0.10.1 + - @0xsequence/transactions@0.10.1 + +## 0.10.0 + +### Minor Changes + +- Deployed new contracts with ERC1271 signer support + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.0 + - @0xsequence/chaind@0.10.0 + - @0xsequence/config@0.10.0 + - @0xsequence/transactions@0.10.0 + +## 0.9.6 + +### Patch Changes + +- Update ABIs for latest sequence contracts +- Updated dependencies [undefined] + - @0xsequence/config@0.9.6 + - @0xsequence/transactions@0.9.6 + - @0xsequence/abi@0.9.6 + - @0xsequence/chaind@0.9.6 + +## 0.9.5 + +### Patch Changes + +- Implemented session class +- Updated dependencies [undefined] + - @0xsequence/config@0.9.5 + - @0xsequence/transactions@0.9.5 + +## 0.9.3 + +### Patch Changes + +- - minor improvements +- Updated dependencies [undefined] + - @0xsequence/abi@0.9.3 + - @0xsequence/chaind@0.9.3 + - @0xsequence/config@0.9.3 + - @0xsequence/transactions@0.9.3 + +## 0.9.1 + +### Patch Changes + +- - patch bump +- Updated dependencies [undefined] + - @0xsequence/abi@0.9.1 + - @0xsequence/chaind@0.9.1 + - @0xsequence/config@0.9.1 + - @0xsequence/transactions@0.9.1 + +## 0.9.0 + +### Minor Changes + +- - provider transport hardening + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.9.0 + - @0xsequence/chaind@0.9.0 + - @0xsequence/config@0.9.0 + - @0xsequence/transactions@0.9.0 + +## 0.8.5 + +### Patch Changes + +- - use latest wallet-contracts +- Updated dependencies [undefined] + - @0xsequence/abi@0.8.5 + - @0xsequence/chaind@0.8.5 + - @0xsequence/config@0.8.5 + - @0xsequence/transactions@0.8.5 + +## 0.8.4 + +### Patch Changes + +- - minor improvements, name updates and comments +- Updated dependencies [undefined] + - @0xsequence/abi@0.8.4 + - @0xsequence/chaind@0.8.4 + - @0xsequence/config@0.8.4 + - @0xsequence/transactions@0.8.4 + +## 0.8.3 + +### Patch Changes + +- - refinements + + - normalize signer address in config + + - provider: getWalletState() method to WalletProvider + +- Updated dependencies [undefined] + - @0xsequence/abi@0.8.3 + - @0xsequence/chaind@0.8.3 + - @0xsequence/config@0.8.3 + - @0xsequence/transactions@0.8.3 + +## 0.8.2 + +### Patch Changes + +- - field rename and ethauth dependency bump +- Updated dependencies [undefined] + - @0xsequence/abi@0.8.2 + - @0xsequence/chaind@0.8.2 + - @0xsequence/config@0.8.2 + - @0xsequence/transactions@0.8.2 + +## 0.8.1 + +### Patch Changes + +- - variety of optimizations +- Updated dependencies [undefined] + - @0xsequence/abi@0.8.1 + - @0xsequence/chaind@0.8.1 + - @0xsequence/config@0.8.1 + - @0xsequence/transactions@0.8.1 + +## 0.8.0 + +### Minor Changes + +- - changeset fix + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.8.0 + - @0xsequence/chaind@0.8.0 + - @0xsequence/config@0.8.0 + - @0xsequence/transactions@0.8.0 + +## 0.7.1 + +### Patch Changes + +- 02377ab: Minor improvements + +## 0.7.0 + +### Patch Changes + +- 6f11ed7: sequence.js, init release +- Updated dependencies [6f11ed7] + - @0xsequence/abi@0.7.0 + - @0xsequence/chaind@0.7.0 + - @0xsequence/config@0.7.0 + - @0xsequence/transactions@0.7.0 diff --git a/packages/relayer/README.md b/packages/relayer/README.md new file mode 100644 index 0000000000..71c808fd0e --- /dev/null +++ b/packages/relayer/README.md @@ -0,0 +1,4 @@ +@0xsequence/relayer +=================== + +See [0xsequence project page](https://github.com/0xsequence/sequence.js). diff --git a/packages/relayer/hardhat.config.js b/packages/relayer/hardhat.config.js new file mode 100644 index 0000000000..eaca505314 --- /dev/null +++ b/packages/relayer/hardhat.config.js @@ -0,0 +1,15 @@ +/** + * @type import('hardhat/config').HardhatUserConfig + */ +module.exports = { + solidity: '0.7.6', + + networks: { + hardhat: { + chainId: 31337, + accounts: { + mnemonic: 'ripple axis someone ridge uniform wrist prosper there frog rate olympic knee' + } + } + } +} diff --git a/packages/relayer/package.json b/packages/relayer/package.json new file mode 100644 index 0000000000..12921bc680 --- /dev/null +++ b/packages/relayer/package.json @@ -0,0 +1,37 @@ +{ + "name": "@0xsequence/relayer", + "version": "2.0.0", + "description": "relayer sub-package for Sequence", + "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/relayer", + "source": "src/index.ts", + "main": "dist/0xsequence-relayer.cjs.js", + "module": "dist/0xsequence-relayer.esm.js", + "author": "Horizon Blockchain Games", + "license": "Apache-2.0", + "scripts": { + "test": "pnpm test:concurrently 'pnpm test:run'", + "test:run": "pnpm test:file tests/**/*.spec.ts", + "test:file": "NODE_OPTIONS='--import tsx' mocha --timeout 30000", + "test:concurrently": "concurrently -k --success first 'pnpm start:hardhat > /dev/null' ", + "start:hardhat": "pnpm hardhat node --port 9547", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@0xsequence/abi": "workspace:*", + "@0xsequence/core": "workspace:*", + "@0xsequence/utils": "workspace:*" + }, + "peerDependencies": { + "ethers": ">=5.5 < 6" + }, + "devDependencies": { + "@0xsequence/signhub": "workspace:*", + "@0xsequence/tests": "workspace:*", + "@0xsequence/wallet-contracts": "^1.10.0", + "ethers": "^5.7.2" + }, + "files": [ + "src", + "dist" + ] +} diff --git a/packages/relayer/src/index.ts b/packages/relayer/src/index.ts new file mode 100644 index 0000000000..f771369bb5 --- /dev/null +++ b/packages/relayer/src/index.ts @@ -0,0 +1,86 @@ +import { ethers, providers } from 'ethers' +import { proto } from './rpc-relayer' + +import { commons } from '@0xsequence/core' + +export interface Relayer { + // simulate returns the execution results for a list of transactions. + simulate(wallet: string, ...transactions: commons.transaction.Transaction[]): Promise + + // getFeeOptions returns the fee options that the relayer will accept as payment. + // If a quote is returned, it may be passed back to the relayer for dispatch. + getFeeOptions( + address: string, + ...transactions: commons.transaction.Transaction[] + ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> + + // getFeeOptionsRaw returns the fee options that the relayer will accept as payment. + // If a quote is returned, it may be passed back to the relayer for dispatch. + // It doesn't make any assumptions about the transaction format. + getFeeOptionsRaw( + entrypoint: string, + data: ethers.utils.BytesLike, + options?: { + simulate?: boolean + } + ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> + + // gasRefundOptions returns the transactions which can be included to refund a + // relayer for submitting your transaction to a network. + gasRefundOptions(address: string, ...transactions: commons.transaction.Transaction[]): Promise + + // getNonce returns the transaction count/nonce for a wallet, encoded with nonce space. + // If space is undefined, the relayer can choose a nonce space to encode the result with. + // Otherwise, the relayer must return a nonce encoded for the given nonce space. + getNonce(address: string, space?: ethers.BigNumberish, blockTag?: providers.BlockTag): Promise + + // relayer will submit the transaction(s) to the network and return the transaction response. + // The quote should be the one returned from getFeeOptions, if any. + // waitForReceipt must default to true. + relay( + signedTxs: commons.transaction.IntendedTransactionBundle, + quote?: FeeQuote, + waitForReceipt?: boolean + ): Promise + + // wait for transaction confirmation + // timeout is the maximum time to wait for the transaction response + // delay is the polling interval, i.e. the time to wait between requests + // maxFails is the maximum number of hard failures to tolerate before giving up + wait( + metaTxnId: string | commons.transaction.SignedTransactionBundle, + timeout?: number, + delay?: number, + maxFails?: number + ): Promise +} + +export * from './local-relayer' +export * from './provider-relayer' +export * from './rpc-relayer' +export { proto as RpcRelayerProto } from './rpc-relayer' +export type SimulateResult = proto.SimulateResult +export type FeeOption = proto.FeeOption + +// A fee quote is simply an opaque value that can be obtained via Relayer.getFeeOptions(), and +// returned back to the same relayer via Relayer.relay(). Fee quotes should be treated as an +// implementation detail of the relayer that produces them. +// +// This interface exists for type-safety purposes to protect against passing non-FeeQuotes to +// Relayer.relay(), or any other functions that call it indirectly (e.g. Account.sendTransaction). +export interface FeeQuote { + _tag: 'FeeQuote' + _quote: unknown +} + +export function isRelayer(cand: any): cand is Relayer { + return ( + typeof cand === 'object' && + typeof cand.simulate === 'function' && + typeof cand.getFeeOptions === 'function' && + typeof cand.gasRefundOptions === 'function' && + typeof cand.getNonce === 'function' && + typeof cand.relay === 'function' && + typeof cand.wait === 'function' + ) +} diff --git a/packages/relayer/src/local-relayer.ts b/packages/relayer/src/local-relayer.ts new file mode 100644 index 0000000000..19712ce120 --- /dev/null +++ b/packages/relayer/src/local-relayer.ts @@ -0,0 +1,79 @@ +import { Signer as AbstractSigner, providers, BytesLike } from 'ethers' +import { logger } from '@0xsequence/utils' +import { FeeOption, FeeQuote, Relayer } from '.' +import { ProviderRelayer, ProviderRelayerOptions } from './provider-relayer' +import { commons } from '@0xsequence/core' + +export type LocalRelayerOptions = Omit & { + signer: AbstractSigner +} + +export function isLocalRelayerOptions(obj: any): obj is LocalRelayerOptions { + return obj.signer !== undefined && AbstractSigner.isSigner(obj.signer) +} + +export class LocalRelayer extends ProviderRelayer implements Relayer { + private signer: AbstractSigner + private txnOptions: providers.TransactionRequest + + constructor(options: LocalRelayerOptions | AbstractSigner) { + super(AbstractSigner.isSigner(options) ? { provider: options.provider! } : { ...options, provider: options.signer.provider! }) + this.signer = AbstractSigner.isSigner(options) ? options : options.signer + if (!this.signer.provider) throw new Error('Signer must have a provider') + } + + async getFeeOptions(_address: string, ..._transactions: commons.transaction.Transaction[]): Promise<{ options: FeeOption[] }> { + return { options: [] } + } + + async getFeeOptionsRaw( + _entrypoint: string, + _data: BytesLike, + _options?: { + simulate?: boolean + } + ): Promise<{ options: FeeOption[] }> { + return { options: [] } + } + + async gasRefundOptions(address: string, ...transactions: commons.transaction.Transaction[]): Promise { + const { options } = await this.getFeeOptions(address, ...transactions) + return options + } + + setTransactionOptions(transactionRequest: providers.TransactionRequest) { + this.txnOptions = transactionRequest + } + + async relay( + signedTxs: commons.transaction.IntendedTransactionBundle, + quote?: FeeQuote, + waitForReceipt: boolean = true + ): Promise> { + if (quote !== undefined) { + logger.warn(`LocalRelayer doesn't accept fee quotes`) + } + + const data = commons.transaction.encodeBundleExecData(signedTxs) + + // TODO: think about computing gas limit individually, summing together and passing across + // NOTE: we expect that all txns have set their gasLimit ahead of time through proper estimation + // const gasLimit = signedTxs.transactions.reduce((sum, tx) => sum.add(tx.gasLimit), ethers.BigNumber.from(0)) + // txRequest.gasLimit = gasLimit + + const responsePromise = this.signer.sendTransaction({ + to: signedTxs.entrypoint, + data, + ...this.txnOptions, + gasLimit: 9000000 + }) + + if (waitForReceipt) { + const response: commons.transaction.TransactionResponse = await responsePromise + response.receipt = await response.wait() + return response + } else { + return responsePromise + } + } +} diff --git a/packages/relayer/src/provider-relayer.ts b/packages/relayer/src/provider-relayer.ts new file mode 100644 index 0000000000..9135c7acf0 --- /dev/null +++ b/packages/relayer/src/provider-relayer.ts @@ -0,0 +1,247 @@ +import { ethers, providers } from 'ethers' +import { walletContracts } from '@0xsequence/abi' +import { FeeOption, FeeQuote, Relayer, SimulateResult } from '.' +import { logger, Optionals } from '@0xsequence/utils' +import { commons } from '@0xsequence/core' + +const DEFAULT_GAS_LIMIT = ethers.BigNumber.from(800000) + +export interface ProviderRelayerOptions { + provider: providers.Provider + waitPollRate?: number + deltaBlocksLog?: number + fromBlockLog?: number +} + +export const ProviderRelayerDefaults: Required> = { + waitPollRate: 1000, + deltaBlocksLog: 12, + fromBlockLog: -1024 +} + +export function isProviderRelayerOptions(obj: any): obj is ProviderRelayerOptions { + return obj.provider !== undefined && providers.Provider.isProvider(obj.provider) +} + +export abstract class ProviderRelayer implements Relayer { + public provider: providers.Provider + public waitPollRate: number + public deltaBlocksLog: number + public fromBlockLog: number + + constructor(options: ProviderRelayerOptions) { + const opts = { ...ProviderRelayerDefaults, ...options } + + this.provider = opts.provider + this.waitPollRate = opts.waitPollRate + this.deltaBlocksLog = opts.deltaBlocksLog + this.fromBlockLog = opts.fromBlockLog + } + + abstract getFeeOptions( + address: string, + ...transactions: commons.transaction.Transaction[] + ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> + + abstract getFeeOptionsRaw( + entrypoint: string, + data: ethers.utils.BytesLike, + options?: { + simulate?: boolean + } + ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> + + abstract gasRefundOptions(address: string, ...transactions: commons.transaction.Transaction[]): Promise + + abstract relay( + signedTxs: commons.transaction.IntendedTransactionBundle, + quote?: FeeQuote, + waitForReceipt?: boolean + ): Promise + + async simulate(wallet: string, ...transactions: commons.transaction.Transaction[]): Promise { + return ( + await Promise.all( + transactions.map(async tx => { + // Respect gasLimit request of the transaction (as long as its not 0) + if (tx.gasLimit && !ethers.BigNumber.from(tx.gasLimit || 0).eq(ethers.constants.Zero)) { + return tx.gasLimit + } + + // Fee can't be estimated locally for delegateCalls + if (tx.delegateCall) { + return DEFAULT_GAS_LIMIT + } + + // Fee can't be estimated for self-called if wallet hasn't been deployed + if (tx.to === wallet && (await this.provider.getCode(wallet).then(code => ethers.utils.arrayify(code).length === 0))) { + return DEFAULT_GAS_LIMIT + } + + if (!this.provider) { + throw new Error('signer.provider is not set, but is required') + } + + // TODO: If the wallet address has been deployed, gas limits can be + // estimated with more accurately by using self-calls with the batch transactions one by one + return this.provider.estimateGas({ + from: wallet, + to: tx.to, + data: tx.data, + value: tx.value + }) + }) + ) + ).map(gasLimit => ({ + executed: true, + succeeded: true, + gasUsed: ethers.BigNumber.from(gasLimit).toNumber(), + gasLimit: ethers.BigNumber.from(gasLimit).toNumber() + })) + } + + async getNonce(address: string, space?: ethers.BigNumberish, blockTag?: providers.BlockTag): Promise { + if (!this.provider) { + throw new Error('provider is not set') + } + + if ((await this.provider.getCode(address)) === '0x') { + return 0 + } + + if (space === undefined) { + space = 0 + } + + const module = new ethers.Contract(address, walletContracts.mainModule.abi, this.provider) + const nonce = await module.readNonce(space, { blockTag: blockTag }) + return commons.transaction.encodeNonce(space, nonce) + } + + async wait( + metaTxnId: string | commons.transaction.SignedTransactionBundle, + timeoutDuration?: number, + delay: number = this.waitPollRate, + maxFails: number = 5 + ): Promise { + if (typeof metaTxnId !== 'string') { + metaTxnId = commons.transaction.intendedTransactionID(metaTxnId) + } + + let timedOut = false + + const retry = async (f: () => Promise, errorMessage: string): Promise => { + let fails = 0 + + while (!timedOut) { + try { + return await f() + } catch (error) { + fails++ + + if (maxFails !== undefined && fails >= maxFails) { + logger.error(`giving up after ${fails} failed attempts${errorMessage ? `: ${errorMessage}` : ''}`, error) + throw error + } else { + logger.warn(`attempt #${fails} failed${errorMessage ? `: ${errorMessage}` : ''}`, error) + } + } + + if (delay > 0) { + await new Promise(resolve => setTimeout(resolve, delay)) + } + } + + throw new Error(`timed out after ${fails} failed attempts${errorMessage ? `: ${errorMessage}` : ''}`) + } + + const waitReceipt = async (): Promise => { + // Transactions can only get executed on nonce change + // get all nonce changes and look for metaTxnIds in between logs + let lastBlock: number = this.fromBlockLog + + if (lastBlock < 0) { + const block = await retry(() => this.provider.getBlockNumber(), 'unable to get latest block number') + lastBlock = block + lastBlock + } + + if (typeof metaTxnId !== 'string') { + throw new Error('impossible') + } + + const normalMetaTxnId = metaTxnId.replace('0x', '') + + while (!timedOut) { + const block = await retry(() => this.provider.getBlockNumber(), 'unable to get latest block number') + + const logs = await retry( + () => + this.provider.getLogs({ + fromBlock: Math.max(0, lastBlock - this.deltaBlocksLog), + toBlock: block, + // Nonce change event topic + topics: ['0x1f180c27086c7a39ea2a7b25239d1ab92348f07ca7bb59d1438fcf527568f881'] + }), + `unable to get NonceChange logs for blocks ${Math.max(0, lastBlock - this.deltaBlocksLog)} to ${block}` + ) + + lastBlock = block + + // Get receipts of all transactions + const txs = await Promise.all( + logs.map(l => + retry( + () => this.provider.getTransactionReceipt(l.transactionHash), + `unable to get receipt for transaction ${l.transactionHash}` + ) + ) + ) + + // Find a transaction with a TxExecuted log + const found = txs.find(tx => + tx.logs.find( + l => + (l.topics.length === 0 && l.data.replace('0x', '') === normalMetaTxnId) || + (l.topics.length === 1 && + // TxFailed event topic + l.topics[0] === '0x3dbd1590ea96dd3253a91f24e64e3a502e1225d602a5731357bc12643070ccd7' && + l.data.length >= 64 && + l.data.replace('0x', '').startsWith(normalMetaTxnId)) + ) + ) + + // If found return that + if (found) { + return { + receipt: found, + ...(await retry( + () => this.provider.getTransaction(found.transactionHash), + `unable to get transaction ${found.transactionHash}` + )) + } + } + + // Otherwise wait and try again + if (!timedOut) { + await new Promise(r => setTimeout(r, delay)) + } + } + + throw new Error(`Timeout waiting for transaction receipt ${metaTxnId}`) + } + + if (timeoutDuration !== undefined) { + return Promise.race([ + waitReceipt(), + new Promise((_, reject) => + setTimeout(() => { + timedOut = true + reject(`Timeout waiting for transaction receipt ${metaTxnId}`) + }, timeoutDuration) + ) + ]) + } else { + return waitReceipt() + } + } +} diff --git a/packages/relayer/src/rpc-relayer/index.ts b/packages/relayer/src/rpc-relayer/index.ts new file mode 100644 index 0000000000..728035b7e6 --- /dev/null +++ b/packages/relayer/src/rpc-relayer/index.ts @@ -0,0 +1,328 @@ +import { ethers } from 'ethers' +import { FeeOption, FeeQuote, Relayer, SimulateResult } from '..' +import * as proto from './relayer.gen' +import { commons } from '@0xsequence/core' +import { getEthersConnectionInfo, logger } from '@0xsequence/utils' + +export { proto } + +const FINAL_STATUSES = [ + proto.ETHTxnStatus.DROPPED, + proto.ETHTxnStatus.SUCCEEDED, + proto.ETHTxnStatus.PARTIALLY_FAILED, + proto.ETHTxnStatus.FAILED +] + +const FAILED_STATUSES = [proto.ETHTxnStatus.DROPPED, proto.ETHTxnStatus.PARTIALLY_FAILED, proto.ETHTxnStatus.FAILED] + +export interface RpcRelayerOptions { + provider: ethers.providers.Provider | { url: string } + url: string + projectAccessKey?: string + jwtAuth?: string +} + +export function isRpcRelayerOptions(obj: any): obj is RpcRelayerOptions { + return ( + obj.url !== undefined && + typeof obj.url === 'string' && + obj.provider !== undefined && + ethers.providers.Provider.isProvider(obj.provider) + ) +} + +const fetch = typeof global === 'object' ? global.fetch : window.fetch + +// TODO: rename to SequenceRelayer +export class RpcRelayer implements Relayer { + private readonly service: proto.Relayer + public readonly provider: ethers.providers.Provider + + constructor(public options: RpcRelayerOptions) { + this.service = new proto.Relayer(options.url, this._fetch) + + if (ethers.providers.Provider.isProvider(options.provider)) { + this.provider = options.provider + } else { + const { jwtAuth, projectAccessKey } = this.options + const providerConnectionInfo = getEthersConnectionInfo(options.provider.url, projectAccessKey, jwtAuth) + this.provider = new ethers.providers.StaticJsonRpcProvider(providerConnectionInfo) + } + } + + _fetch = (input: RequestInfo, init?: RequestInit): Promise => { + // automatically include jwt and access key auth header to requests + // if its been set on the api client + const headers: { [key: string]: any } = {} + + const { jwtAuth, projectAccessKey } = this.options + + if (jwtAuth && jwtAuth.length > 0) { + headers['Authorization'] = `BEARER ${jwtAuth}` + } + + if (projectAccessKey && projectAccessKey.length > 0) { + headers['X-Access-Key'] = projectAccessKey + } + + // before the request is made + init!.headers = { ...init!.headers, ...headers } + + return fetch(input, init) + } + + async waitReceipt( + metaTxnId: string | commons.transaction.SignedTransactionBundle, + delay: number = 1000, + maxFails: number = 5, + isCancelled?: () => boolean + ): Promise { + if (typeof metaTxnId !== 'string') { + metaTxnId = commons.transaction.intendedTransactionID(metaTxnId) + } + + logger.info(`[rpc-relayer/waitReceipt] waiting for ${metaTxnId}`) + + let fails = 0 + + while (isCancelled === undefined || !isCancelled()) { + try { + const { receipt } = await this.service.getMetaTxnReceipt({ metaTxID: metaTxnId }) + + if ( + receipt && + receipt.txnReceipt && + receipt.txnReceipt !== 'null' && + FINAL_STATUSES.includes(receipt.status as proto.ETHTxnStatus) + ) { + return { receipt } + } + } catch (e) { + fails++ + + if (fails === maxFails) { + throw e + } + } + + if (isCancelled === undefined || !isCancelled()) { + await new Promise(resolve => setTimeout(resolve, delay)) + } + } + + throw new Error(`Cancelled waiting for transaction receipt ${metaTxnId}`) + } + + async simulate(wallet: string, ...transactions: commons.transaction.Transaction[]): Promise { + const coder = ethers.utils.defaultAbiCoder + const encoded = coder.encode( + [commons.transaction.MetaTransactionsType], + [commons.transaction.sequenceTxAbiEncode(transactions)] + ) + return (await this.service.simulate({ wallet, transactions: encoded })).results + } + + async getFeeOptions( + address: string, + ...transactions: commons.transaction.Transaction[] + ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> { + // NOTE/TODO: for a given `service` the feeTokens will not change between execution, so we should memoize this value + // for a short-period of time, perhaps for 1 day or in memory. Perhaps one day we can make this happen automatically + // with http cache response for this endpoint and service-worker.. lots of approaches + const feeTokens = await this.service.feeTokens() + + if (feeTokens.isFeeRequired) { + const symbols = feeTokens.tokens.map(token => token.symbol).join(', ') + logger.info(`[rpc-relayer/getFeeOptions] relayer fees are required, accepted tokens are ${symbols}`) + + const nonce = await this.getNonce(address) + + if (!this.provider) { + logger.warn(`[rpc-relayer/getFeeOptions] provider not set, needed for stub signature`) + throw new Error('provider is not set') + } + + const { options, quote } = await this.service.feeOptions({ + wallet: address, + to: address, + data: commons.transaction.encodeBundleExecData({ + entrypoint: address, + transactions, + nonce + }) + }) + + logger.info(`[rpc-relayer/getFeeOptions] got refund options ${JSON.stringify(options)}`) + return { options, quote: { _tag: 'FeeQuote', _quote: quote } } + } else { + logger.info(`[rpc-relayer/getFeeOptions] relayer fees are not required`) + return { options: [] } + } + } + + async getFeeOptionsRaw( + entrypoint: string, + data: ethers.utils.BytesLike, + options?: { + simulate?: boolean + } + ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> { + const { options: feeOptions, quote } = await this.service.feeOptions({ + wallet: entrypoint, + to: entrypoint, + data: ethers.utils.hexlify(data), + simulate: options?.simulate + }) + + return { options: feeOptions, quote: { _tag: 'FeeQuote', _quote: quote } } + } + + async gasRefundOptions(address: string, ...transactions: commons.transaction.Transaction[]): Promise { + const { options } = await this.getFeeOptions(address, ...transactions) + return options + } + + async getNonce(address: string, space?: ethers.BigNumberish): Promise { + logger.info(`[rpc-relayer/getNonce] get nonce for wallet ${address} space: ${space}`) + const encodedNonce = space !== undefined ? ethers.BigNumber.from(space).toHexString() : undefined + const resp = await this.service.getMetaTxnNonce({ walletContractAddress: address, space: encodedNonce }) + const nonce = ethers.BigNumber.from(resp.nonce) + const [decodedSpace, decodedNonce] = commons.transaction.decodeNonce(nonce) + logger.info(`[rpc-relayer/getNonce] got next nonce for wallet ${address} ${decodedNonce} space: ${decodedSpace}`) + return nonce + } + + async relay( + signedTxs: commons.transaction.IntendedTransactionBundle, + quote?: FeeQuote, + waitForReceipt: boolean = true + ): Promise> { + logger.info( + `[rpc-relayer/relay] relaying signed meta-transactions ${JSON.stringify(signedTxs)} with quote ${JSON.stringify(quote)}` + ) + + let typecheckedQuote: string | undefined + if (quote !== undefined) { + if (typeof quote._quote === 'string') { + typecheckedQuote = quote._quote + } else { + logger.warn('[rpc-relayer/relay] ignoring invalid fee quote') + } + } + + if (!this.provider) { + logger.warn(`[rpc-relayer/relay] provider not set, failed relay`) + throw new Error('provider is not set') + } + + const data = commons.transaction.encodeBundleExecData(signedTxs) + const metaTxn = await this.service.sendMetaTxn({ + call: { + walletAddress: signedTxs.intent.wallet, + contract: signedTxs.entrypoint, + input: data + }, + quote: typecheckedQuote + }) + + logger.info(`[rpc-relayer/relay] got relay result ${JSON.stringify(metaTxn)}`) + + if (waitForReceipt) { + return this.wait(signedTxs.intent.id) + } else { + const response = { + hash: signedTxs.intent.id, + confirmations: 0, + from: signedTxs.intent.wallet, + wait: (_confirmations?: number): Promise => Promise.reject(new Error('impossible')) + } + + const wait = async (confirmations?: number): Promise => { + if (!this.provider) { + throw new Error('cannot wait for receipt, relayer has no provider set') + } + + const waitResponse = await this.wait(signedTxs.intent.id) + const transactionHash = waitResponse.receipt?.transactionHash + + if (!transactionHash) { + throw new Error('cannot wait for receipt, unknown native transaction hash') + } + + Object.assign(response, waitResponse) + + return this.provider.waitForTransaction(transactionHash, confirmations) + } + + response.wait = wait + + return response as commons.transaction.TransactionResponse + } + } + + async wait( + metaTxnId: string | commons.transaction.SignedTransactionBundle, + timeout?: number, + delay: number = 1000, + maxFails: number = 5 + ): Promise> { + let timedOut = false + + const { receipt } = await (timeout !== undefined + ? Promise.race([ + this.waitReceipt(metaTxnId, delay, maxFails, () => timedOut), + new Promise((_, reject) => + setTimeout(() => { + timedOut = true + reject(`Timeout waiting for transaction receipt ${metaTxnId}`) + }, timeout) + ) + ]) + : this.waitReceipt(metaTxnId, delay, maxFails)) + + if (!receipt.txnReceipt || FAILED_STATUSES.includes(receipt.status as proto.ETHTxnStatus)) { + throw new MetaTransactionResponseException(receipt) + } + + const txReceipt = JSON.parse(receipt.txnReceipt) as RelayerTxReceipt + + return { + blockHash: txReceipt.blockHash, + blockNumber: ethers.BigNumber.from(txReceipt.blockNumber).toNumber(), + confirmations: 1, + from: typeof metaTxnId === 'string' ? undefined : metaTxnId.intent.wallet, + hash: txReceipt.transactionHash, + raw: receipt.txnReceipt, + receipt: txReceipt, // extended type which is Sequence-specific. Contains the decoded metaTxReceipt + wait: async (confirmations?: number) => this.provider!.waitForTransaction(txReceipt.transactionHash, confirmations) + } as commons.transaction.TransactionResponse + } +} + +class MetaTransactionResponseException { + constructor(public receipt: proto.MetaTxnReceipt) {} +} + +export type RelayerTxReceipt = { + blockHash: string + blockNumber: string + contractAddress: string + cumulativeGasUsed: string + gasUsed: string + logs: { + address: string + blockHash: string + blockNumber: string + data: string + logIndex: string + removed: boolean + topics: string[] + transactionHash: string + transactionIndex: string + }[] + logsBloom: string + root: string + status: string + transactionHash: string + transactionIndex: string +} diff --git a/packages/relayer/src/rpc-relayer/relayer.gen.ts b/packages/relayer/src/rpc-relayer/relayer.gen.ts new file mode 100644 index 0000000000..91ce2e9b01 --- /dev/null +++ b/packages/relayer/src/rpc-relayer/relayer.gen.ts @@ -0,0 +1,1461 @@ +/* eslint-disable */ +// sequence-relayer v0.4.1 1e27d0fd295aa5897878939595ef0c6adc54b1a3 +// -- +// Code generated by webrpc-gen@v0.18.6 with typescript generator. DO NOT EDIT. +// +// webrpc-gen -schema=relayer.ridl -target=typescript -client -out=./clients/relayer.gen.ts + +// WebRPC description and code-gen version +export const WebRPCVersion = 'v1' + +// Schema version of your RIDL schema +export const WebRPCSchemaVersion = 'v0.4.1' + +// Schema hash generated from your RIDL schema +export const WebRPCSchemaHash = '1e27d0fd295aa5897878939595ef0c6adc54b1a3' + +// +// Types +// + +export enum ETHTxnStatus { + UNKNOWN = 'UNKNOWN', + DROPPED = 'DROPPED', + QUEUED = 'QUEUED', + SENT = 'SENT', + SUCCEEDED = 'SUCCEEDED', + PARTIALLY_FAILED = 'PARTIALLY_FAILED', + FAILED = 'FAILED' +} + +export enum TransferType { + SEND = 'SEND', + RECEIVE = 'RECEIVE', + BRIDGE_DEPOSIT = 'BRIDGE_DEPOSIT', + BRIDGE_WITHDRAW = 'BRIDGE_WITHDRAW', + BURN = 'BURN', + UNKNOWN = 'UNKNOWN' +} + +export enum FeeTokenType { + UNKNOWN = 'UNKNOWN', + ERC20_TOKEN = 'ERC20_TOKEN', + ERC1155_TOKEN = 'ERC1155_TOKEN' +} + +export enum SortOrder { + DESC = 'DESC', + ASC = 'ASC' +} + +export interface Version { + webrpcVersion: string + schemaVersion: string + schemaHash: string + appVersion: string +} + +export interface RuntimeStatus { + healthOK: boolean + startTime: string + uptime: number + ver: string + branch: string + commitHash: string + useEIP1559: boolean + senders: Array + checks: RuntimeChecks + numTxnsRelayed: NumTxnsRelayed +} + +export interface SenderStatus { + index: number + address: string + etherBalance: number + active: boolean +} + +export interface RuntimeChecks {} + +export interface NumTxnsRelayed { + prev: number + current: number + period: number +} + +export interface SequenceContext { + factory: string + mainModule: string + mainModuleUpgradable: string + guestModule: string + utils: string +} + +export interface GasTank { + id: number + name: string + currentBalance: number + unlimited: boolean + feeMarkupFactor: number + updatedAt: string + createdAt: string +} + +export interface GasTankBalanceAdjustment { + gasTankId: number + nonce: number + amount: number + totalBalance: number + balanceTimestamp: string + createdAt: string +} + +export interface GasSponsor { + id: number + gasTankId: number + projectId: number + address: string + name: string + active: boolean + updatedAt: string + createdAt: string + deletedAt: string +} + +export interface GasSponsorUsage { + name: string + id: number + totalGasUsed: number + totalTxnFees: number + totalTxnFeesUsd: number + avgGasPrice: number + totalTxns: number + startTime: string + endTime: string +} + +export interface MetaTxn { + walletAddress: string + contract: string + input: string +} + +export interface MetaTxnLog { + id: number + projectId: number + txnHash: string + txnNonce: string + metaTxnID?: string + txnStatus: ETHTxnStatus + txnRevertReason: string + requeues: number + queuedAt: string + sentAt: string + minedAt: string + target: string + input: string + txnArgs: { [key: string]: any } + txnReceipt?: { [key: string]: any } + walletAddress: string + metaTxnNonce: string + gasLimit: number + gasPrice: string + gasUsed: number + gasEstimated: number + gasFeeMarkup?: number + usdRate: string + creditsUsed: number + isWhitelisted: boolean + gasSponsor?: number + gasTank?: number + updatedAt: string + createdAt: string +} + +export interface MetaTxnEntry { + id: number + metaTxnID: string + txnStatus: ETHTxnStatus + txnRevertReason: string + index: number + logs?: Array + updatedAt: string + createdAt: string +} + +export interface MetaTxnReceipt { + id: string + status: string + revertReason?: string + index: number + logs: Array + receipts: Array + txnReceipt: string +} + +export interface MetaTxnReceiptLog { + address: string + topics: Array + data: string +} + +export interface Transaction { + txnHash?: string + blockNumber: number + chainId: number + metaTxnID?: string + transfers?: Array + users?: { [key: string]: TxnLogUser } + timestamp: string +} + +export interface TxnLogUser { + username: string +} + +export interface TxnLogTransfer { + transferType: TransferType + contractAddress: string + from: string + to: string + ids: Array + amounts: Array +} + +export interface SentTransactionsFilter { + pending?: boolean + failed?: boolean +} + +export interface SimulateResult { + executed: boolean + succeeded: boolean + result?: string + reason?: string + gasUsed: number + gasLimit: number +} + +export interface FeeOption { + token: FeeToken + to: string + value: string + gasLimit: number +} + +export interface FeeToken { + chainId: number + name: string + symbol: string + type: FeeTokenType + decimals?: number + logoURL: string + contractAddress?: string + tokenID?: string +} + +export interface Page { + pageSize?: number + page?: number + more?: boolean + totalRecords?: number + column?: string + before?: any + after?: any + sort?: Array +} + +export interface SortBy { + column: string + order: SortOrder +} + +export interface Relayer { + ping(headers?: object, signal?: AbortSignal): Promise + version(headers?: object, signal?: AbortSignal): Promise + runtimeStatus(headers?: object, signal?: AbortSignal): Promise + getSequenceContext(headers?: object, signal?: AbortSignal): Promise + getChainID(headers?: object, signal?: AbortSignal): Promise + sendMetaTxn(args: SendMetaTxnArgs, headers?: object, signal?: AbortSignal): Promise + getMetaTxnNonce(args: GetMetaTxnNonceArgs, headers?: object, signal?: AbortSignal): Promise + getMetaTxnReceipt(args: GetMetaTxnReceiptArgs, headers?: object, signal?: AbortSignal): Promise + simulate(args: SimulateArgs, headers?: object, signal?: AbortSignal): Promise + updateMetaTxnGasLimits( + args: UpdateMetaTxnGasLimitsArgs, + headers?: object, + signal?: AbortSignal + ): Promise + feeTokens(headers?: object, signal?: AbortSignal): Promise + feeOptions(args: FeeOptionsArgs, headers?: object, signal?: AbortSignal): Promise + getMetaTxnNetworkFeeOptions( + args: GetMetaTxnNetworkFeeOptionsArgs, + headers?: object, + signal?: AbortSignal + ): Promise + getMetaTransactions(args: GetMetaTransactionsArgs, headers?: object, signal?: AbortSignal): Promise + sentTransactions(args: SentTransactionsArgs, headers?: object, signal?: AbortSignal): Promise + pendingTransactions(args: PendingTransactionsArgs, headers?: object, signal?: AbortSignal): Promise + getGasTank(args: GetGasTankArgs, headers?: object, signal?: AbortSignal): Promise + addGasTank(args: AddGasTankArgs, headers?: object, signal?: AbortSignal): Promise + updateGasTank(args: UpdateGasTankArgs, headers?: object, signal?: AbortSignal): Promise + getGasSponsor(args: GetGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise + addressGasSponsors(args: AddressGasSponsorsArgs, headers?: object, signal?: AbortSignal): Promise + listGasSponsors(args: ListGasSponsorsArgs, headers?: object, signal?: AbortSignal): Promise + addGasSponsor(args: AddGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise + updateGasSponsor(args: UpdateGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise + removeGasSponsor(args: RemoveGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise + reportGasSponsorUsage( + args: ReportGasSponsorUsageArgs, + headers?: object, + signal?: AbortSignal + ): Promise + nextGasTankBalanceAdjustmentNonce( + args: NextGasTankBalanceAdjustmentNonceArgs, + headers?: object, + signal?: AbortSignal + ): Promise + adjustGasTankBalance( + args: AdjustGasTankBalanceArgs, + headers?: object, + signal?: AbortSignal + ): Promise + getGasTankBalanceAdjustment( + args: GetGasTankBalanceAdjustmentArgs, + headers?: object, + signal?: AbortSignal + ): Promise + listGasTankBalanceAdjustments( + args: ListGasTankBalanceAdjustmentsArgs, + headers?: object, + signal?: AbortSignal + ): Promise +} + +export interface PingArgs {} + +export interface PingReturn { + status: boolean +} +export interface VersionArgs {} + +export interface VersionReturn { + version: Version +} +export interface RuntimeStatusArgs {} + +export interface RuntimeStatusReturn { + status: RuntimeStatus +} +export interface GetSequenceContextArgs {} + +export interface GetSequenceContextReturn { + data: SequenceContext +} +export interface GetChainIDArgs {} + +export interface GetChainIDReturn { + chainID: number +} +export interface SendMetaTxnArgs { + call: MetaTxn + quote?: string +} + +export interface SendMetaTxnReturn { + status: boolean + txnHash: string +} +export interface GetMetaTxnNonceArgs { + walletContractAddress: string + space?: string +} + +export interface GetMetaTxnNonceReturn { + nonce: string +} +export interface GetMetaTxnReceiptArgs { + metaTxID: string +} + +export interface GetMetaTxnReceiptReturn { + receipt: MetaTxnReceipt +} +export interface SimulateArgs { + wallet: string + transactions: string +} + +export interface SimulateReturn { + results: Array +} +export interface UpdateMetaTxnGasLimitsArgs { + walletAddress: string + walletConfig: any + payload: string +} + +export interface UpdateMetaTxnGasLimitsReturn { + payload: string +} +export interface FeeTokensArgs {} + +export interface FeeTokensReturn { + isFeeRequired: boolean + tokens: Array +} +export interface FeeOptionsArgs { + wallet: string + to: string + data: string + simulate?: boolean +} + +export interface FeeOptionsReturn { + options: Array + sponsored: boolean + quote?: string +} +export interface GetMetaTxnNetworkFeeOptionsArgs { + walletConfig: any + payload: string +} + +export interface GetMetaTxnNetworkFeeOptionsReturn { + options: Array +} +export interface GetMetaTransactionsArgs { + projectId: number + gasTankId: number + page?: Page +} + +export interface GetMetaTransactionsReturn { + page: Page + transactions: Array +} +export interface SentTransactionsArgs { + filter?: SentTransactionsFilter + page?: Page +} + +export interface SentTransactionsReturn { + page: Page + transactions: Array +} +export interface PendingTransactionsArgs { + page?: Page +} + +export interface PendingTransactionsReturn { + page: Page + transactions: Array +} +export interface GetGasTankArgs { + id: number +} + +export interface GetGasTankReturn { + gasTank: GasTank +} +export interface AddGasTankArgs { + name: string + feeMarkupFactor: number + unlimited?: boolean +} + +export interface AddGasTankReturn { + status: boolean + gasTank: GasTank +} +export interface UpdateGasTankArgs { + id: number + name?: string + feeMarkupFactor?: number + unlimited?: boolean +} + +export interface UpdateGasTankReturn { + status: boolean + gasTank: GasTank +} +export interface GetGasSponsorArgs { + id: number +} + +export interface GetGasSponsorReturn { + gasSponsor: GasSponsor +} +export interface AddressGasSponsorsArgs { + address: string + page?: Page +} + +export interface AddressGasSponsorsReturn { + page: Page + gasSponsors: Array +} +export interface ListGasSponsorsArgs { + projectId: number + gasTankId: number + page?: Page +} + +export interface ListGasSponsorsReturn { + page: Page + gasSponsors: Array +} +export interface AddGasSponsorArgs { + projectId: number + gasTankId: number + address: string + name?: string + active?: boolean +} + +export interface AddGasSponsorReturn { + status: boolean + gasSponsor: GasSponsor +} +export interface UpdateGasSponsorArgs { + id: number + name?: string + active?: boolean +} + +export interface UpdateGasSponsorReturn { + status: boolean + gasSponsor: GasSponsor +} +export interface RemoveGasSponsorArgs { + id: number +} + +export interface RemoveGasSponsorReturn { + status: boolean +} +export interface ReportGasSponsorUsageArgs { + projectId: number + gasTankId: number + startTime?: string + endTime?: string +} + +export interface ReportGasSponsorUsageReturn { + gasSponsorUsage: Array +} +export interface NextGasTankBalanceAdjustmentNonceArgs { + id: number +} + +export interface NextGasTankBalanceAdjustmentNonceReturn { + nonce: number +} +export interface AdjustGasTankBalanceArgs { + id: number + nonce: number + amount: number +} + +export interface AdjustGasTankBalanceReturn { + status: boolean + adjustment: GasTankBalanceAdjustment +} +export interface GetGasTankBalanceAdjustmentArgs { + id: number + nonce: number +} + +export interface GetGasTankBalanceAdjustmentReturn { + adjustment: GasTankBalanceAdjustment +} +export interface ListGasTankBalanceAdjustmentsArgs { + id: number + page?: Page +} + +export interface ListGasTankBalanceAdjustmentsReturn { + page: Page + adjustments: Array +} + +// +// Client +// +export class Relayer implements Relayer { + protected hostname: string + protected fetch: Fetch + protected path = '/rpc/Relayer/' + + constructor(hostname: string, fetch: Fetch) { + this.hostname = hostname + this.fetch = (input: RequestInfo, init?: RequestInit) => fetch(input, init) + } + + private url(name: string): string { + return this.hostname + this.path + name + } + + ping = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('Ping'), createHTTPRequest({}, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + status: _data.status + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + version = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('Version'), createHTTPRequest({}, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + version: _data.version + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + runtimeStatus = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('RuntimeStatus'), createHTTPRequest({}, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + status: _data.status + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + getSequenceContext = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetSequenceContext'), createHTTPRequest({}, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + data: _data.data + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + getChainID = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetChainID'), createHTTPRequest({}, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + chainID: _data.chainID + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + sendMetaTxn = (args: SendMetaTxnArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('SendMetaTxn'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + status: _data.status, + txnHash: _data.txnHash + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + getMetaTxnNonce = (args: GetMetaTxnNonceArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetMetaTxnNonce'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + nonce: _data.nonce + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + getMetaTxnReceipt = (args: GetMetaTxnReceiptArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetMetaTxnReceipt'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + receipt: _data.receipt + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + simulate = (args: SimulateArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('Simulate'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + results: >_data.results + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + updateMetaTxnGasLimits = ( + args: UpdateMetaTxnGasLimitsArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('UpdateMetaTxnGasLimits'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + payload: _data.payload + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + feeTokens = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('FeeTokens'), createHTTPRequest({}, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + isFeeRequired: _data.isFeeRequired, + tokens: >_data.tokens + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + feeOptions = (args: FeeOptionsArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('FeeOptions'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + options: >_data.options, + sponsored: _data.sponsored, + quote: _data.quote + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + getMetaTxnNetworkFeeOptions = ( + args: GetMetaTxnNetworkFeeOptionsArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetMetaTxnNetworkFeeOptions'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + options: >_data.options + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + getMetaTransactions = ( + args: GetMetaTransactionsArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetMetaTransactions'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + page: _data.page, + transactions: >_data.transactions + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + sentTransactions = (args: SentTransactionsArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('SentTransactions'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + page: _data.page, + transactions: >_data.transactions + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + pendingTransactions = ( + args: PendingTransactionsArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('PendingTransactions'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + page: _data.page, + transactions: >_data.transactions + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + getGasTank = (args: GetGasTankArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetGasTank'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + gasTank: _data.gasTank + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + addGasTank = (args: AddGasTankArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('AddGasTank'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + status: _data.status, + gasTank: _data.gasTank + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + updateGasTank = (args: UpdateGasTankArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('UpdateGasTank'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + status: _data.status, + gasTank: _data.gasTank + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + getGasSponsor = (args: GetGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetGasSponsor'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + gasSponsor: _data.gasSponsor + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + addressGasSponsors = ( + args: AddressGasSponsorsArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('AddressGasSponsors'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + page: _data.page, + gasSponsors: >_data.gasSponsors + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + listGasSponsors = (args: ListGasSponsorsArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('ListGasSponsors'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + page: _data.page, + gasSponsors: >_data.gasSponsors + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + addGasSponsor = (args: AddGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('AddGasSponsor'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + status: _data.status, + gasSponsor: _data.gasSponsor + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + updateGasSponsor = (args: UpdateGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('UpdateGasSponsor'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + status: _data.status, + gasSponsor: _data.gasSponsor + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + removeGasSponsor = (args: RemoveGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('RemoveGasSponsor'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + status: _data.status + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + reportGasSponsorUsage = ( + args: ReportGasSponsorUsageArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('ReportGasSponsorUsage'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + gasSponsorUsage: >_data.gasSponsorUsage + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + nextGasTankBalanceAdjustmentNonce = ( + args: NextGasTankBalanceAdjustmentNonceArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('NextGasTankBalanceAdjustmentNonce'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + nonce: _data.nonce + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + adjustGasTankBalance = ( + args: AdjustGasTankBalanceArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('AdjustGasTankBalance'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + status: _data.status, + adjustment: _data.adjustment + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + getGasTankBalanceAdjustment = ( + args: GetGasTankBalanceAdjustmentArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('GetGasTankBalanceAdjustment'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + adjustment: _data.adjustment + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + listGasTankBalanceAdjustments = ( + args: ListGasTankBalanceAdjustmentsArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('ListGasTankBalanceAdjustments'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + page: _data.page, + adjustments: >_data.adjustments + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } +} + +const createHTTPRequest = (body: object = {}, headers: object = {}, signal: AbortSignal | null = null): object => { + return { + method: 'POST', + headers: { ...headers, 'Content-Type': 'application/json' }, + body: JSON.stringify(body || {}), + signal + } +} + +const buildResponse = (res: Response): Promise => { + return res.text().then(text => { + let data + try { + data = JSON.parse(text) + } catch (error) { + let message = '' + if (error instanceof Error) { + message = error.message + } + throw WebrpcBadResponseError.new({ + status: res.status, + cause: `JSON.parse(): ${message}: response text: ${text}` + }) + } + if (!res.ok) { + const code: number = typeof data.code === 'number' ? data.code : 0 + throw (webrpcErrorByCode[code] || WebrpcError).new(data) + } + return data + }) +} + +// +// Errors +// + +export class WebrpcError extends Error { + name: string + code: number + message: string + status: number + cause?: string + + /** @deprecated Use message instead of msg. Deprecated in webrpc v0.11.0. */ + msg: string + + constructor(name: string, code: number, message: string, status: number, cause?: string) { + super(message) + this.name = name || 'WebrpcError' + this.code = typeof code === 'number' ? code : 0 + this.message = message || `endpoint error ${this.code}` + this.msg = this.message + this.status = typeof status === 'number' ? status : 0 + this.cause = cause + Object.setPrototypeOf(this, WebrpcError.prototype) + } + + static new(payload: any): WebrpcError { + return new this(payload.error, payload.code, payload.message || payload.msg, payload.status, payload.cause) + } +} + +// Webrpc errors + +export class WebrpcEndpointError extends WebrpcError { + constructor( + name: string = 'WebrpcEndpoint', + code: number = 0, + message: string = 'endpoint error', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcEndpointError.prototype) + } +} + +export class WebrpcRequestFailedError extends WebrpcError { + constructor( + name: string = 'WebrpcRequestFailed', + code: number = -1, + message: string = 'request failed', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcRequestFailedError.prototype) + } +} + +export class WebrpcBadRouteError extends WebrpcError { + constructor( + name: string = 'WebrpcBadRoute', + code: number = -2, + message: string = 'bad route', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadRouteError.prototype) + } +} + +export class WebrpcBadMethodError extends WebrpcError { + constructor( + name: string = 'WebrpcBadMethod', + code: number = -3, + message: string = 'bad method', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadMethodError.prototype) + } +} + +export class WebrpcBadRequestError extends WebrpcError { + constructor( + name: string = 'WebrpcBadRequest', + code: number = -4, + message: string = 'bad request', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadRequestError.prototype) + } +} + +export class WebrpcBadResponseError extends WebrpcError { + constructor( + name: string = 'WebrpcBadResponse', + code: number = -5, + message: string = 'bad response', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadResponseError.prototype) + } +} + +export class WebrpcServerPanicError extends WebrpcError { + constructor( + name: string = 'WebrpcServerPanic', + code: number = -6, + message: string = 'server panic', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcServerPanicError.prototype) + } +} + +export class WebrpcInternalErrorError extends WebrpcError { + constructor( + name: string = 'WebrpcInternalError', + code: number = -7, + message: string = 'internal error', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcInternalErrorError.prototype) + } +} + +export class WebrpcClientDisconnectedError extends WebrpcError { + constructor( + name: string = 'WebrpcClientDisconnected', + code: number = -8, + message: string = 'client disconnected', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcClientDisconnectedError.prototype) + } +} + +export class WebrpcStreamLostError extends WebrpcError { + constructor( + name: string = 'WebrpcStreamLost', + code: number = -9, + message: string = 'stream lost', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcStreamLostError.prototype) + } +} + +export class WebrpcStreamFinishedError extends WebrpcError { + constructor( + name: string = 'WebrpcStreamFinished', + code: number = -10, + message: string = 'stream finished', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcStreamFinishedError.prototype) + } +} + +// Schema errors + +export class UnauthorizedError extends WebrpcError { + constructor( + name: string = 'Unauthorized', + code: number = 1000, + message: string = 'Unauthorized access', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, UnauthorizedError.prototype) + } +} + +export class PermissionDeniedError extends WebrpcError { + constructor( + name: string = 'PermissionDenied', + code: number = 1001, + message: string = 'Permission denied', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, PermissionDeniedError.prototype) + } +} + +export class MethodNotFoundError extends WebrpcError { + constructor( + name: string = 'MethodNotFound', + code: number = 1003, + message: string = 'Method not found', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, MethodNotFoundError.prototype) + } +} + +export class AbortedError extends WebrpcError { + constructor( + name: string = 'Aborted', + code: number = 1005, + message: string = 'Request aborted', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, AbortedError.prototype) + } +} + +export class InvalidArgumentError extends WebrpcError { + constructor( + name: string = 'InvalidArgument', + code: number = 2001, + message: string = 'Invalid argument', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, InvalidArgumentError.prototype) + } +} + +export class UnavailableError extends WebrpcError { + constructor( + name: string = 'Unavailable', + code: number = 2002, + message: string = 'Unavailable resource', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, UnavailableError.prototype) + } +} + +export class QueryFailedError extends WebrpcError { + constructor( + name: string = 'QueryFailed', + code: number = 2003, + message: string = 'Query failed', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, QueryFailedError.prototype) + } +} + +export class NotFoundError extends WebrpcError { + constructor( + name: string = 'NotFound', + code: number = 3000, + message: string = 'Resource not found', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, NotFoundError.prototype) + } +} + +export enum errors { + WebrpcEndpoint = 'WebrpcEndpoint', + WebrpcRequestFailed = 'WebrpcRequestFailed', + WebrpcBadRoute = 'WebrpcBadRoute', + WebrpcBadMethod = 'WebrpcBadMethod', + WebrpcBadRequest = 'WebrpcBadRequest', + WebrpcBadResponse = 'WebrpcBadResponse', + WebrpcServerPanic = 'WebrpcServerPanic', + WebrpcInternalError = 'WebrpcInternalError', + WebrpcClientDisconnected = 'WebrpcClientDisconnected', + WebrpcStreamLost = 'WebrpcStreamLost', + WebrpcStreamFinished = 'WebrpcStreamFinished', + Unauthorized = 'Unauthorized', + PermissionDenied = 'PermissionDenied', + MethodNotFound = 'MethodNotFound', + Aborted = 'Aborted', + InvalidArgument = 'InvalidArgument', + Unavailable = 'Unavailable', + QueryFailed = 'QueryFailed', + NotFound = 'NotFound' +} + +const webrpcErrorByCode: { [code: number]: any } = { + [0]: WebrpcEndpointError, + [-1]: WebrpcRequestFailedError, + [-2]: WebrpcBadRouteError, + [-3]: WebrpcBadMethodError, + [-4]: WebrpcBadRequestError, + [-5]: WebrpcBadResponseError, + [-6]: WebrpcServerPanicError, + [-7]: WebrpcInternalErrorError, + [-8]: WebrpcClientDisconnectedError, + [-9]: WebrpcStreamLostError, + [-10]: WebrpcStreamFinishedError, + [1000]: UnauthorizedError, + [1001]: PermissionDeniedError, + [1003]: MethodNotFoundError, + [1005]: AbortedError, + [2001]: InvalidArgumentError, + [2002]: UnavailableError, + [2003]: QueryFailedError, + [3000]: NotFoundError +} + +export type Fetch = (input: RequestInfo, init?: RequestInit) => Promise diff --git a/packages/relayer/tests/provider-relayer.spec.ts b/packages/relayer/tests/provider-relayer.spec.ts new file mode 100644 index 0000000000..681cb59e52 --- /dev/null +++ b/packages/relayer/tests/provider-relayer.spec.ts @@ -0,0 +1,532 @@ +import { commons, v2 } from '@0xsequence/core' +import { Orchestrator } from '@0xsequence/signhub' +import { context } from '@0xsequence/tests' +import { Wallet, WalletV2 } from '@0xsequence/wallet' +import { CallReceiverMock, HookCallerMock } from '@0xsequence/wallet-contracts' +import * as chai from 'chai' +import chaiAsPromised from 'chai-as-promised' +import { ethers } from 'ethers' +import hardhat from 'hardhat' +import { LocalRelayer } from '../src' + +const CallReceiverMockArtifact = require('@0xsequence/wallet-contracts/artifacts/contracts/mocks/CallReceiverMock.sol/CallReceiverMock.json') +const HookCallerMockArtifact = require('@0xsequence/wallet-contracts/artifacts/contracts/mocks/HookCallerMock.sol/HookCallerMock.json') + +const { expect } = chai.use(chaiAsPromised) + +describe('Wallet integration', function () { + let relayer: LocalRelayer + let callReceiver: CallReceiverMock + let hookCaller: HookCallerMock + + let contexts: Awaited> + let provider: ethers.providers.Web3Provider + let signers: ethers.Signer[] + + before(async () => { + provider = new ethers.providers.Web3Provider(hardhat.network.provider as any) + signers = new Array(8).fill(0).map((_, i) => provider.getSigner(i)) + contexts = await context.deploySequenceContexts(signers[0]) + relayer = new LocalRelayer(signers[1]) + + // Deploy call receiver mock + callReceiver = (await new ethers.ContractFactory( + CallReceiverMockArtifact.abi, + CallReceiverMockArtifact.bytecode, + signers[0] + ).deploy()) as CallReceiverMock + + // Deploy hook caller mock + hookCaller = (await new ethers.ContractFactory( + HookCallerMockArtifact.abi, + HookCallerMockArtifact.bytecode, + signers[0] + ).deploy()) as HookCallerMock + }) + + describe('Waiting for receipts', () => { + ;[ + { + name: 'deployed', + deployed: true + }, + { + name: 'undeployed', + deployed: false + } + ].map(c => { + let wallet: WalletV2 + + beforeEach(async () => { + const signer = ethers.Wallet.createRandom() + const orchestrator = new Orchestrator([signer]) + + const config = v2.config.ConfigCoder.fromSimple({ + threshold: 1, + checkpoint: 0, + signers: [ + { + address: signer.address, + weight: 1 + } + ] + }) + + wallet = Wallet.newWallet({ + coders: v2.coders, + context: contexts[2], + config, + orchestrator, + chainId: provider.network.chainId, + provider, + relayer + }) + + if (c.deployed) await wallet.deploy() + + expect(await wallet.reader().isDeployed(wallet.address)).to.equal(c.deployed) + }) + + describe(`For ${c.name} wallet`, () => { + it('Should get receipt of success transaction', async () => { + const txn = { + to: ethers.Wallet.createRandom().address, + data: ethers.utils.randomBytes(43), + delegateCall: false, + revertOnError: false, + gasLimit: 140000, + value: 0 + } + + const id = commons.transaction.subdigestOfTransactions(wallet.address, provider.network.chainId, 0, [txn]) + + const receiptPromise = relayer.wait(id, 10000) + await new Promise(r => setTimeout(r, 1000)) + + const ogtx = await wallet.sendTransaction(txn, { serial: true }) + const receipt = await receiptPromise + + expect(receipt).to.not.be.undefined + expect(receipt.hash).to.equal(ogtx.hash) + }) + + it('Should get receipt of success batch transaction', async () => { + const txns = [ + { + to: ethers.Wallet.createRandom().address, + data: ethers.utils.randomBytes(43), + delegateCall: false, + revertOnError: false, + gasLimit: 140000, + value: 0, + nonce: 0 + }, + { + to: ethers.Wallet.createRandom().address, + data: ethers.utils.randomBytes(43), + delegateCall: false, + revertOnError: false, + gasLimit: 140000, + value: 0, + nonce: 0 + } + ] + + const nonce = 0 //wallet.randomNonce() + const id = commons.transaction.subdigestOfTransactions(wallet.address, provider.network.chainId, nonce, txns) + + const receiptPromise = relayer.wait(id, 10000) + await new Promise(r => setTimeout(r, 1000)) + + const ogtx = await wallet.sendTransaction(txns, { nonce }) + const receipt = await receiptPromise + + expect(receipt).to.not.be.undefined + expect(receipt.hash).to.equal(ogtx.hash) + }) + + it('Should get receipt of batch transaction with failed meta-txs', async () => { + const txns = [ + { + to: ethers.Wallet.createRandom().address, + data: ethers.utils.randomBytes(43), + delegateCall: false, + revertOnError: false, + gasLimit: 140000, + value: 0, + nonce: 0 + }, + { + to: contexts[2].factory, + // 0xff not a valid factory method + data: '0xffffffffffff', + delegateCall: false, + revertOnError: false, + gasLimit: 140000, + value: 0, + nonce: 0 + } + ] + + const nonce = wallet.randomNonce() + const id = commons.transaction.subdigestOfTransactions(wallet.address, provider.network.chainId, nonce, txns) + + const receiptPromise = relayer.wait(id, 10000) + await new Promise(r => setTimeout(r, 1000)) + + const ogtx = await wallet.sendTransaction(txns, { nonce }) + const receipt = await receiptPromise + + expect(receipt).to.not.be.undefined + expect(receipt.hash).to.equal(ogtx.hash) + }) + + it('Should get receipt of failed transaction', async () => { + const txn = { + to: contexts[1].factory, + // 0xff not a valid factory method + data: '0xffffffffffff', + delegateCall: false, + revertOnError: false, + gasLimit: 140000, + value: 0, + nonce: 0 + } + + const id = commons.transaction.subdigestOfTransactions(wallet.address, provider.network.chainId, 0, [txn]) + + const receiptPromise = relayer.wait(id, 10000) + await new Promise(r => setTimeout(r, 1000)) + + const ogtx = await wallet.sendTransaction(txn, { serial: true }) + const receipt = await receiptPromise + + expect(receipt).to.not.be.undefined + expect(receipt.hash).to.equal(ogtx.hash) + }) + + it('Find correct receipt between multiple other transactions', async () => { + const altSigner = ethers.Wallet.createRandom() + const orchestrator = new Orchestrator([altSigner]) + + const config = v2.config.ConfigCoder.fromSimple({ + threshold: 1, + checkpoint: 0, + signers: [ + { + address: altSigner.address, + weight: 1 + } + ] + }) + + const altWallet = Wallet.newWallet({ + coders: v2.coders, + context: contexts[2], + config, + provider, + relayer, + orchestrator, + chainId: provider.network.chainId + }) + + await altWallet.deploy() + + expect(await altWallet.reader().isDeployed(altWallet.address)).to.be.true + + await Promise.all( + new Array(8).fill(0).map(async (_, i) => { + await altWallet.sendTransaction( + { + to: ethers.Wallet.createRandom().address, + data: ethers.utils.randomBytes(43), + delegateCall: false, + revertOnError: false, + gasLimit: 140000, + value: 0 + }, + { nonce: commons.transaction.encodeNonce(i, 0) } + ) + }) + ) + + const txn = { + to: ethers.Wallet.createRandom().address, + data: ethers.utils.randomBytes(43), + delegateCall: false, + revertOnError: false, + gasLimit: 140000, + value: 0, + nonce: 0 + } + + const id = commons.transaction.subdigestOfTransactions(wallet.address, provider.network.chainId, 0, [txn]) + + const receiptPromise = relayer.wait(id, 10000) + await new Promise(r => setTimeout(r, 1000)) + + const ogtx = await wallet.sendTransaction(txn, { serial: true }) + + // Post-txs + await Promise.all( + new Array(8).fill(0).map(async (_, i) => { + await altWallet.sendTransaction( + { + to: ethers.Wallet.createRandom().address, + data: ethers.utils.randomBytes(43), + delegateCall: false, + revertOnError: false, + gasLimit: 140000, + value: 0 + }, + { nonce: commons.transaction.encodeNonce(i + 1000, 0) } + ) + }) + ) + + const receipt = await receiptPromise + + expect(receipt).to.not.be.undefined + expect(receipt.hash).to.equal(ogtx.hash) + }) + + it('Find correct receipt between multiple other failed transactions', async () => { + // Pre-txs + const altSigner = ethers.Wallet.createRandom() + const orchestrator = new Orchestrator([altSigner]) + + const config = v2.config.ConfigCoder.fromSimple({ + threshold: 1, + checkpoint: 0, + signers: [ + { + address: altSigner.address, + weight: 1 + } + ] + }) + + const altWallet = Wallet.newWallet({ + coders: v2.coders, + context: contexts[2], + config, + provider, + relayer, + orchestrator, + chainId: provider.network.chainId + }) + + await Promise.all( + new Array(8).fill(0).map(async (_, i) => { + await altWallet.sendTransaction( + { + to: ethers.Wallet.createRandom().address, + data: ethers.utils.randomBytes(43), + delegateCall: false, + revertOnError: false, + gasLimit: 140000, + value: 0 + }, + { nonce: commons.transaction.encodeNonce(i, 0) } + ) + }) + ) + + await Promise.all( + new Array(8).fill(0).map(async (_, i) => { + await altWallet.sendTransaction( + { + to: contexts[2].factory, + // 0xff not a valid factory method + data: '0xffffffffffff', + delegateCall: false, + revertOnError: false, + gasLimit: 140000, + value: 0 + }, + { nonce: commons.transaction.encodeNonce(i + 1000, 0) } + ) + }) + ) + + const txn = { + to: ethers.Wallet.createRandom().address, + data: ethers.utils.randomBytes(43), + delegateCall: false, + revertOnError: false, + gasLimit: 140000, + value: 0, + nonce: 0 + } + + const id = commons.transaction.subdigestOfTransactions(wallet.address, provider.network.chainId, 0, [txn]) + + const receiptPromise = relayer.wait(id, 10000) + await new Promise(r => setTimeout(r, 1000)) + + const ogtx = await wallet.sendTransaction(txn, { serial: true }) + + const receipt = await receiptPromise + + expect(receipt).to.not.be.undefined + expect(receipt.hash).to.equal(ogtx.hash) + }) + + it('Find failed tx receipt between multiple other failed transactions', async () => { + // Pre-txs + const altSigner = ethers.Wallet.createRandom() + const orchestrator = new Orchestrator([altSigner]) + + const config = v2.config.ConfigCoder.fromSimple({ + threshold: 1, + checkpoint: 0, + signers: [ + { + address: altSigner.address, + weight: 1 + } + ] + }) + + const altWallet = Wallet.newWallet({ + coders: v2.coders, + context: contexts[2], + config, + provider, + relayer, + orchestrator, + chainId: provider.network.chainId + }) + + await Promise.all( + new Array(8).fill(0).map(async (_, i) => { + await altWallet.sendTransaction( + { + to: ethers.Wallet.createRandom().address, + data: ethers.utils.randomBytes(43), + delegateCall: false, + revertOnError: false, + gasLimit: 140000 + }, + { nonce: commons.transaction.encodeNonce(i, 0) } + ) + }) + ) + + await Promise.all( + new Array(8).fill(0).map(async (_, i) => { + await altWallet.sendTransaction( + { + to: contexts[1].factory, + // 0xff not a valid factory method + data: '0xffffffffffff', + delegateCall: false, + revertOnError: false, + gasLimit: 140000 + }, + { nonce: commons.transaction.encodeNonce(i + 1000, 0) } + ) + }) + ) + + const txn = { + to: contexts[2].factory, + // 0xff not a valid factory method + data: '0xffffffffffff', + delegateCall: false, + revertOnError: false, + gasLimit: 140000, + value: 0, + nonce: 0 + } + + const id = commons.transaction.subdigestOfTransactions(wallet.address, provider.network.chainId, 0, [txn]) + + const receiptPromise = relayer.wait(id, 10000) + await new Promise(r => setTimeout(r, 1000)) + + const ogtx = await wallet.sendTransaction(txn, { serial: true }) + const receipt = await receiptPromise + + expect(receipt).to.not.be.undefined + expect(receipt.hash).to.equal(ogtx.hash) + }) + + it('Should timeout receipt if transaction is never sent', async () => { + const txn = { + to: ethers.Wallet.createRandom().address, + data: ethers.utils.randomBytes(43), + delegateCall: false, + revertOnError: false, + gasLimit: 140000, + value: 0, + nonce: 0 + } + + const id = commons.transaction.subdigestOfTransactions(wallet.address, provider.network.chainId, 0, [txn]) + const receiptPromise = relayer.wait(id, 2000) + + await expect(receiptPromise).to.be.rejectedWith(`Timeout waiting for transaction receipt ${id}`) + }) + + if (c.deployed) { + it('Find correct receipt between multiple other failed transactions of the same wallet', async () => { + // Pre-txs + await Promise.all( + new Array(8).fill(0).map(async (_, i) => { + await wallet.sendTransaction( + { + to: ethers.Wallet.createRandom().address, + data: ethers.utils.randomBytes(43), + delegateCall: false, + revertOnError: false, + gasLimit: 140000, + value: 0 + }, + { nonce: commons.transaction.encodeNonce(i + 1000, 0) } + ) + }) + ) + + await Promise.all( + new Array(8).fill(0).map(async (_, i) => { + await wallet.sendTransaction( + { + to: contexts[1].factory, + // 0xff not a valid factory method + data: '0xffffffffffff', + delegateCall: false, + revertOnError: false, + gasLimit: 140000, + value: 0 + }, + { nonce: commons.transaction.encodeNonce(i + 2000, 0) } + ) + }) + ) + + const txn = { + to: ethers.Wallet.createRandom().address, + data: ethers.utils.randomBytes(43), + delegateCall: false, + revertOnError: false, + gasLimit: 140000 + } + + const id = commons.transaction.subdigestOfTransactions(wallet.address, provider.network.chainId, 0, [txn]) + + const receiptPromise = relayer.wait(id, 10000) + await new Promise(r => setTimeout(r, 1000)) + + const ogtx = await wallet.sendTransaction(txn, { serial: true }) + + const receipt = await receiptPromise + + expect(receipt).to.not.be.undefined + expect(receipt.hash).to.equal(ogtx.hash) + }) + } + }) + }) + }) +}) diff --git a/packages/replacer/CHANGELOG.md b/packages/replacer/CHANGELOG.md new file mode 100644 index 0000000000..749d1427e0 --- /dev/null +++ b/packages/replacer/CHANGELOG.md @@ -0,0 +1,1131 @@ +# @0xsequence/replacer + +## 2.0.0 + +### Major Changes + +- changeset + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@2.0.0 + - @0xsequence/core@2.0.0 + +## 1.10.14 + +### Patch Changes + +- network: add borne-testnet to allNetworks +- Updated dependencies + - @0xsequence/abi@1.10.14 + - @0xsequence/core@1.10.14 + +## 1.10.13 + +### Patch Changes + +- network: add borne testnet +- Updated dependencies + - @0xsequence/abi@1.10.13 + - @0xsequence/core@1.10.13 + +## 1.10.12 + +### Patch Changes + +- api: update bindings +- global/window -> globalThis +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.10.12 + - @0xsequence/core@1.10.12 + +## 1.10.11 + +### Patch Changes + +- waas: updated intent.gen without webrpc types, errors exported from authenticator.gen +- Updated dependencies + - @0xsequence/abi@1.10.11 + - @0xsequence/core@1.10.11 + +## 1.10.10 + +### Patch Changes + +- metadata: update bindings with new contract collections api +- Updated dependencies + - @0xsequence/abi@1.10.10 + - @0xsequence/core@1.10.10 + +## 1.10.9 + +### Patch Changes + +- waas minor update +- Updated dependencies + - @0xsequence/abi@1.10.9 + - @0xsequence/core@1.10.9 + +## 1.10.8 + +### Patch Changes + +- update metadata bindings +- Updated dependencies + - @0xsequence/abi@1.10.8 + - @0xsequence/core@1.10.8 + +## 1.10.7 + +### Patch Changes + +- minor fixes to waas client +- Updated dependencies + - @0xsequence/abi@1.10.7 + - @0xsequence/core@1.10.7 + +## 1.10.6 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/abi@1.10.6 + - @0xsequence/core@1.10.6 + +## 1.10.5 + +### Patch Changes + +- network: ape-chain-testnet -> apechain-testnet +- Updated dependencies + - @0xsequence/abi@1.10.5 + - @0xsequence/core@1.10.5 + +## 1.10.4 + +### Patch Changes + +- network: add b3-sepolia, ape-chain-testnet, blast, blast-sepolia +- Updated dependencies + - @0xsequence/abi@1.10.4 + - @0xsequence/core@1.10.4 + +## 1.10.3 + +### Patch Changes + +- typing fix +- Updated dependencies + - @0xsequence/abi@1.10.3 + - @0xsequence/core@1.10.3 + +## 1.10.2 + +### Patch Changes + +- - waas: add getIdToken method + - indexer: update api client +- Updated dependencies + - @0xsequence/abi@1.10.2 + - @0xsequence/core@1.10.2 + +## 1.10.1 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/abi@1.10.1 + - @0xsequence/core@1.10.1 + +## 1.10.0 + +### Minor Changes + +- waas release v1.3.0 + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.10.0 + - @0xsequence/core@1.10.0 + +## 1.9.37 + +### Patch Changes + +- network: adds nativeToken data to NetworkMetadata constants +- Updated dependencies + - @0xsequence/abi@1.9.37 + - @0xsequence/core@1.9.37 + +## 1.9.36 + +### Patch Changes + +- guard: export client +- Updated dependencies + - @0xsequence/abi@1.9.36 + - @0xsequence/core@1.9.36 + +## 1.9.35 + +### Patch Changes + +- guard: update bindings +- Updated dependencies + - @0xsequence/abi@1.9.35 + - @0xsequence/core@1.9.35 + +## 1.9.34 + +### Patch Changes + +- waas: always use lowercase email +- Updated dependencies + - @0xsequence/abi@1.9.34 + - @0xsequence/core@1.9.34 + +## 1.9.33 + +### Patch Changes + +- waas: umd build +- Updated dependencies + - @0xsequence/abi@1.9.33 + - @0xsequence/core@1.9.33 + +## 1.9.32 + +### Patch Changes + +- indexer: update bindings +- Updated dependencies + - @0xsequence/abi@1.9.32 + - @0xsequence/core@1.9.32 + +## 1.9.31 + +### Patch Changes + +- metadata: token directory changes +- Updated dependencies + - @0xsequence/abi@1.9.31 + - @0xsequence/core@1.9.31 + +## 1.9.30 + +### Patch Changes + +- update +- Updated dependencies + - @0xsequence/abi@1.9.30 + - @0xsequence/core@1.9.30 + +## 1.9.29 + +### Patch Changes + +- disable gnosis chain +- Updated dependencies + - @0xsequence/abi@1.9.29 + - @0xsequence/core@1.9.29 + +## 1.9.28 + +### Patch Changes + +- add utils/merkletree +- Updated dependencies + - @0xsequence/abi@1.9.28 + - @0xsequence/core@1.9.28 + +## 1.9.27 + +### Patch Changes + +- network: optimistic -> optimism +- waas: remove defaults +- api, sessions: update bindings +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.9.27 + - @0xsequence/core@1.9.27 + +## 1.9.26 + +### Patch Changes + +- - add backend interfaces for pluggable interfaces + - introduce @0xsequence/react-native + - update pnpm to lockfile v9 +- Updated dependencies + - @0xsequence/abi@1.9.26 + - @0xsequence/core@1.9.26 + +## 1.9.25 + +### Patch Changes + +- update webrpc clients with new error types +- Updated dependencies + - @0xsequence/abi@1.9.25 + - @0xsequence/core@1.9.25 + +## 1.9.24 + +### Patch Changes + +- waas: add memoryStore backend to localStore +- Updated dependencies + - @0xsequence/abi@1.9.24 + - @0xsequence/core@1.9.24 + +## 1.9.23 + +### Patch Changes + +- update api client bindings +- Updated dependencies + - @0xsequence/abi@1.9.23 + - @0xsequence/core@1.9.23 + +## 1.9.22 + +### Patch Changes + +- update metadata client bindings +- Updated dependencies + - @0xsequence/abi@1.9.22 + - @0xsequence/core@1.9.22 + +## 1.9.21 + +### Patch Changes + +- api client bindings +- Updated dependencies + - @0xsequence/abi@1.9.21 + - @0xsequence/core@1.9.21 + +## 1.9.20 + +### Patch Changes + +- api client bindings update +- Updated dependencies + - @0xsequence/abi@1.9.20 + - @0xsequence/core@1.9.20 + +## 1.9.19 + +### Patch Changes + +- waas update +- Updated dependencies + - @0xsequence/abi@1.9.19 + - @0xsequence/core@1.9.19 + +## 1.9.18 + +### Patch Changes + +- provider: prohibit dangerous functions +- Updated dependencies + - @0xsequence/abi@1.9.18 + - @0xsequence/core@1.9.18 + +## 1.9.17 + +### Patch Changes + +- network: add xr-sepolia +- Updated dependencies + - @0xsequence/abi@1.9.17 + - @0xsequence/core@1.9.17 + +## 1.9.16 + +### Patch Changes + +- waas: sequence.feeOptions +- Updated dependencies + - @0xsequence/abi@1.9.16 + - @0xsequence/core@1.9.16 + +## 1.9.15 + +### Patch Changes + +- metadata: collection external_link field name fix +- Updated dependencies + - @0xsequence/abi@1.9.15 + - @0xsequence/core@1.9.15 + +## 1.9.14 + +### Patch Changes + +- network: astar-zkatana -> astar-zkyoto +- network: deprecate polygon mumbai network +- network: add xai and polygon amoy +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.9.14 + - @0xsequence/core@1.9.14 + +## 1.9.13 + +### Patch Changes + +- waas: fix @0xsequence/network dependency +- Updated dependencies + - @0xsequence/abi@1.9.13 + - @0xsequence/core@1.9.13 + +## 1.9.12 + +### Patch Changes + +- indexer: update rpc bindings +- provider: signMessage: Serialize the BytesLike or string message into hexstring before sending +- waas: SessionAuthProof +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.9.12 + - @0xsequence/core@1.9.12 + +## 1.9.11 + +### Patch Changes + +- metdata, update rpc bindings +- Updated dependencies + - @0xsequence/abi@1.9.11 + - @0xsequence/core@1.9.11 + +## 1.9.10 + +### Patch Changes + +- update metadata rpc bindings +- Updated dependencies + - @0xsequence/abi@1.9.10 + - @0xsequence/core@1.9.10 + +## 1.9.9 + +### Patch Changes + +- metadata, add SequenceCollections rpc client +- Updated dependencies + - @0xsequence/abi@1.9.9 + - @0xsequence/core@1.9.9 + +## 1.9.8 + +### Patch Changes + +- waas client update +- Updated dependencies + - @0xsequence/abi@1.9.8 + - @0xsequence/core@1.9.8 + +## 1.9.7 + +### Patch Changes + +- update rpc client bindings for api, metadata and relayer +- Updated dependencies + - @0xsequence/abi@1.9.7 + - @0xsequence/core@1.9.7 + +## 1.9.6 + +### Patch Changes + +- waas package update +- Updated dependencies + - @0xsequence/abi@1.9.6 + - @0xsequence/core@1.9.6 + +## 1.9.5 + +### Patch Changes + +- RpcRelayer prioritize project access key +- Updated dependencies + - @0xsequence/abi@1.9.5 + - @0xsequence/core@1.9.5 + +## 1.9.4 + +### Patch Changes + +- waas: fix network dependency +- Updated dependencies + - @0xsequence/abi@1.9.4 + - @0xsequence/core@1.9.4 + +## 1.9.3 + +### Patch Changes + +- provider: don't append access key to RPC url if user has already provided it +- Updated dependencies + - @0xsequence/abi@1.9.3 + - @0xsequence/core@1.9.3 + +## 1.9.2 + +### Patch Changes + +- network: add xai-sepolia +- Updated dependencies + - @0xsequence/abi@1.9.2 + - @0xsequence/core@1.9.2 + +## 1.9.1 + +### Patch Changes + +- analytics fix +- Updated dependencies + - @0xsequence/abi@1.9.1 + - @0xsequence/core@1.9.1 + +## 1.9.0 + +### Minor Changes + +- waas release + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.9.0 + - @0xsequence/core@1.9.0 + +## 1.8.8 + +### Patch Changes + +- update metadata bindings +- Updated dependencies + - @0xsequence/abi@1.8.8 + - @0xsequence/core@1.8.8 + +## 1.8.7 + +### Patch Changes + +- provider: update databeat to 0.9.1 +- Updated dependencies + - @0xsequence/abi@1.8.7 + - @0xsequence/core@1.8.7 + +## 1.8.6 + +### Patch Changes + +- guard: SignedOwnershipProof +- Updated dependencies + - @0xsequence/abi@1.8.6 + - @0xsequence/core@1.8.6 + +## 1.8.5 + +### Patch Changes + +- guard: signOwnershipProof and isSignedOwnershipProof +- Updated dependencies + - @0xsequence/abi@1.8.5 + - @0xsequence/core@1.8.5 + +## 1.8.4 + +### Patch Changes + +- network: add homeverse to networks list +- Updated dependencies + - @0xsequence/abi@1.8.4 + - @0xsequence/core@1.8.4 + +## 1.8.3 + +### Patch Changes + +- api: introduce basic linked wallet support +- Updated dependencies + - @0xsequence/abi@1.8.3 + - @0xsequence/core@1.8.3 + +## 1.8.2 + +### Patch Changes + +- provider: don't initialize analytics unless explicitly requested +- Updated dependencies + - @0xsequence/abi@1.8.2 + - @0xsequence/core@1.8.2 + +## 1.8.1 + +### Patch Changes + +- update to analytics provider +- Updated dependencies + - @0xsequence/abi@1.8.1 + - @0xsequence/core@1.8.1 + +## 1.8.0 + +### Minor Changes + +- provider: project analytics + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.8.0 + - @0xsequence/core@1.8.0 + +## 1.7.2 + +### Patch Changes + +- 0xsequence: ChainId should not be exported as a type +- account, wallet: fix nonce selection +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.7.2 + - @0xsequence/core@1.7.2 + +## 1.7.1 + +### Patch Changes + +- network: add missing avalanche logoURI +- Updated dependencies + - @0xsequence/abi@1.7.1 + - @0xsequence/core@1.7.1 + +## 1.7.0 + +### Minor Changes + +- provider: projectAccessKey is now required + +### Patch Changes + +- network: add NetworkMetadata.logoURI property for all networks +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.7.0 + - @0xsequence/core@1.7.0 + +## 1.6.3 + +### Patch Changes + +- network list update +- Updated dependencies + - @0xsequence/abi@1.6.3 + - @0xsequence/core@1.6.3 + +## 1.6.2 + +### Patch Changes + +- auth: projectAccessKey option +- wallet: use 12 bytes for random space +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.6.2 + - @0xsequence/core@1.6.2 + +## 1.6.1 + +### Patch Changes + +- core: add simple config from subdigest support +- core: fix encode tree with subdigest +- account: implement buildOnChainSignature on Account +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.6.1 + - @0xsequence/core@1.6.1 + +## 1.6.0 + +### Minor Changes + +- account, wallet: parallel transactions by default + +### Patch Changes + +- provider: emit disconnect on sign out +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.6.0 + - @0xsequence/core@1.6.0 + +## 1.5.0 + +### Minor Changes + +- signhub: add 'signing' signer status + +### Patch Changes + +- auth: Session.open: onAccountAddress callback +- account: allow empty transaction bundles +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.5.0 + - @0xsequence/core@1.5.0 + +## 1.4.9 + +### Patch Changes + +- rename SequenceMetadataClient to SequenceMetadata +- Updated dependencies + - @0xsequence/abi@1.4.9 + - @0xsequence/core@1.4.9 + +## 1.4.8 + +### Patch Changes + +- account: Account.getSigners +- Updated dependencies + - @0xsequence/abi@1.4.8 + - @0xsequence/core@1.4.8 + +## 1.4.7 + +### Patch Changes + +- update indexer client bindings +- Updated dependencies + - @0xsequence/abi@1.4.7 + - @0xsequence/core@1.4.7 + +## 1.4.6 + +### Patch Changes + +- - add sepolia networks, mark goerli as deprecated + - update indexer client bindings +- Updated dependencies + - @0xsequence/abi@1.4.6 + - @0xsequence/core@1.4.6 + +## 1.4.5 + +### Patch Changes + +- indexer/metadata: update client bindings +- auth: selectWallet with new address +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.4.5 + - @0xsequence/core@1.4.5 + +## 1.4.4 + +### Patch Changes + +- indexer: update bindings +- auth: handle jwt expiry +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.4.4 + - @0xsequence/core@1.4.4 + +## 1.4.3 + +### Patch Changes + +- guard: return active status from GuardSigner.getAuthMethods +- Updated dependencies + - @0xsequence/abi@1.4.3 + - @0xsequence/core@1.4.3 + +## 1.4.2 + +### Patch Changes + +- guard: update bindings +- Updated dependencies + - @0xsequence/abi@1.4.2 + - @0xsequence/core@1.4.2 + +## 1.4.1 + +### Patch Changes + +- network: remove unused networks +- signhub: orchestrator interface +- guard: auth methods interface +- guard: update bindings for pin and totp +- guard: no more retry logic +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.4.1 + - @0xsequence/core@1.4.1 + +## 1.4.0 + +### Minor Changes + +- project access key support + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.4.0 + - @0xsequence/core@1.4.0 + +## 1.3.0 + +### Minor Changes + +- signhub: account children + +### Patch Changes + +- guard: do not throw when building deploy transaction +- network: snowtrace.io -> subnets.avax.network/c-chain +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.3.0 + - @0xsequence/core@1.3.0 + +## 1.2.9 + +### Patch Changes + +- account: AccountSigner.sendTransaction simulateForFeeOptions +- relayer: update bindings +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.2.9 + - @0xsequence/core@1.2.9 + +## 1.2.8 + +### Patch Changes + +- rename X-Sequence-Token-Key header to X-Access-Key +- Updated dependencies + - @0xsequence/abi@1.2.8 + - @0xsequence/core@1.2.8 + +## 1.2.7 + +### Patch Changes + +- add x-sequence-token-key to clients +- Updated dependencies + - @0xsequence/abi@1.2.7 + - @0xsequence/core@1.2.7 + +## 1.2.6 + +### Patch Changes + +- Fix bind multicall provider +- Updated dependencies + - @0xsequence/abi@1.2.6 + - @0xsequence/core@1.2.6 + +## 1.2.5 + +### Patch Changes + +- Multicall default configuration fixes +- Updated dependencies + - @0xsequence/abi@1.2.5 + - @0xsequence/core@1.2.5 + +## 1.2.4 + +### Patch Changes + +- provider: Adding missing payment provider types to PaymentProviderOption +- provider: WalletRequestHandler.notifyChainChanged +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.2.4 + - @0xsequence/core@1.2.4 + +## 1.2.3 + +### Patch Changes + +- auth, provider: connect to accept optional authorizeNonce +- Updated dependencies + - @0xsequence/abi@1.2.3 + - @0xsequence/core@1.2.3 + +## 1.2.2 + +### Patch Changes + +- provider: allow createContract calls +- core: check for explicit zero address in contract deployments +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.2.2 + - @0xsequence/core@1.2.2 + +## 1.2.1 + +### Patch Changes + +- auth: use sequence api chain id as reference chain id if available +- Updated dependencies + - @0xsequence/abi@1.2.1 + - @0xsequence/core@1.2.1 + +## 1.2.0 + +### Minor Changes + +- split services from session, better local support + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.2.0 + - @0xsequence/core@1.2.0 + +## 1.1.15 + +### Patch Changes + +- guard: remove error filtering +- Updated dependencies + - @0xsequence/abi@1.1.15 + - @0xsequence/core@1.1.15 + +## 1.1.14 + +### Patch Changes + +- guard: add GuardSigner.onError +- Updated dependencies + - @0xsequence/abi@1.1.14 + - @0xsequence/core@1.1.14 + +## 1.1.13 + +### Patch Changes + +- provider: pass client version with connect options +- provider: removing large from BannerSize +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.1.13 + - @0xsequence/core@1.1.13 + +## 1.1.12 + +### Patch Changes + +- provider: adding bannerSize to ConnectOptions +- Updated dependencies + - @0xsequence/abi@1.1.12 + - @0xsequence/core@1.1.12 + +## 1.1.11 + +### Patch Changes + +- add homeverse configs +- Updated dependencies + - @0xsequence/abi@1.1.11 + - @0xsequence/core@1.1.11 + +## 1.1.10 + +### Patch Changes + +- handle default EIP6492 on send +- Updated dependencies + - @0xsequence/abi@1.1.10 + - @0xsequence/core@1.1.10 + +## 1.1.9 + +### Patch Changes + +- Custom default EIP6492 on client +- Updated dependencies + - @0xsequence/abi@1.1.9 + - @0xsequence/core@1.1.9 + +## 1.1.8 + +### Patch Changes + +- metadata: searchMetadata: add types filter +- Updated dependencies + - @0xsequence/abi@1.1.8 + - @0xsequence/core@1.1.8 + +## 1.1.7 + +### Patch Changes + +- adding signInWith connect settings option to allow dapps to automatically login their users with a certain provider optimizing the normal authentication flow +- Updated dependencies + - @0xsequence/abi@1.1.7 + - @0xsequence/core@1.1.7 + +## 1.1.6 + +### Patch Changes + +- metadata: searchMetadata: add chainID and excludeTokenMetadata filters +- Updated dependencies + - @0xsequence/abi@1.1.6 + - @0xsequence/core@1.1.6 + +## 1.1.5 + +### Patch Changes + +- account: re-compute meta-transaction id for wallet deployment transactions +- Updated dependencies + - @0xsequence/abi@1.1.5 + - @0xsequence/core@1.1.5 + +## 1.1.4 + +### Patch Changes + +- network: rename base-mainnet to base +- provider: override isDefaultChain with ConnectOptions.networkId if provided +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.1.4 + - @0xsequence/core@1.1.4 + +## 1.1.3 + +### Patch Changes + +- provider: use network id from transport session +- provider: sign authorization using ConnectOptions.networkId if provided +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.1.3 + - @0xsequence/core@1.1.3 + +## 1.1.2 + +### Patch Changes + +- provider: jsonrpc chain id fixes +- Updated dependencies + - @0xsequence/abi@1.1.2 + - @0xsequence/core@1.1.2 + +## 1.1.1 + +### Patch Changes + +- network: add base mainnet and sepolia +- provider: reject toxic transaction requests +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.1.1 + - @0xsequence/core@1.1.1 + +## 1.1.0 + +### Minor Changes + +- Refactor dapp facing provider + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.1.0 + - @0xsequence/core@1.1.0 + +## 1.0.5 + +### Patch Changes + +- network: export network constants +- guard: use the correct global for fetch +- network: nova-explorer.arbitrum.io -> nova.arbiscan.io +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.0.5 + - @0xsequence/core@1.0.5 + +## 1.0.4 + +### Patch Changes + +- provider: accept name or number for networkId +- Updated dependencies + - @0xsequence/abi@1.0.4 + - @0xsequence/core@1.0.4 + +## 1.0.3 + +### Patch Changes + +- Simpler isValidSignature helpers +- Updated dependencies + - @0xsequence/abi@1.0.3 + - @0xsequence/core@1.0.3 + +## 1.0.2 + +### Patch Changes + +- add extra signature validation utils methods +- Updated dependencies + - @0xsequence/abi@1.0.2 + - @0xsequence/core@1.0.2 + +## 1.0.1 + +### Patch Changes + +- add homeverse testnet +- Updated dependencies + - @0xsequence/abi@1.0.1 + - @0xsequence/core@1.0.1 + +## 1.0.0 + +### Major Changes + +- https://sequence.xyz/blog/sequence-wallet-light-state-sync-full-merkle-wallets + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.0.0 + - @0xsequence/core@1.0.0 diff --git a/packages/replacer/package.json b/packages/replacer/package.json new file mode 100644 index 0000000000..3e3141b87b --- /dev/null +++ b/packages/replacer/package.json @@ -0,0 +1,26 @@ +{ + "name": "@0xsequence/replacer", + "version": "2.0.0", + "description": "EIP-5719 client implementation", + "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/replacer", + "source": "src/index.ts", + "main": "dist/0xsequence-replacer.cjs.js", + "module": "dist/0xsequence-replacer.esm.js", + "author": "Horizon Blockchain Games", + "license": "Apache-2.0", + "scripts": { + "test": "echo 'TODO: replacer tests'" + }, + "dependencies": { + "@0xsequence/abi": "workspace:*", + "@0xsequence/core": "workspace:*" + }, + "peerDependencies": { + "ethers": ">=5.5" + }, + "devDependencies": {}, + "files": [ + "src", + "dist" + ] +} diff --git a/packages/replacer/src/cached.ts b/packages/replacer/src/cached.ts new file mode 100644 index 0000000000..28ae1e5c79 --- /dev/null +++ b/packages/replacer/src/cached.ts @@ -0,0 +1,31 @@ +import { ethers } from 'ethers' +import { runByEIP5719, URISolver } from '.' + +export class CachedEIP5719 { + constructor( + public provider: ethers.providers.Provider, + public solver?: URISolver, + public window: number = 1000 + ) {} + + private pending: Map< + string, + { + timestamp: number + promise: Promise + } + > = new Map() + + async runByEIP5719(address: string, digest: ethers.BytesLike, signature: ethers.BytesLike): Promise { + const key = `${address}-${digest}-${signature}` + const now = Date.now() + + if (this.pending.has(key) && now - this.pending.get(key)!.timestamp < this.window) { + return this.pending.get(key)!.promise + } + + const promise = runByEIP5719(address, this.provider, digest, signature, this.solver) + this.pending.set(key, { timestamp: now, promise }) + return promise + } +} diff --git a/packages/replacer/src/index.ts b/packages/replacer/src/index.ts new file mode 100644 index 0000000000..02c76da8f8 --- /dev/null +++ b/packages/replacer/src/index.ts @@ -0,0 +1,118 @@ +import { ethers } from 'ethers' +import { walletContracts } from '@0xsequence/abi' +import { isIPFS, useGateway } from './ipfs' +import { commons } from '@0xsequence/core' + +export * from './cached' + +export function eip5719Contract(address: string, provider: ethers.providers.Provider): ethers.Contract { + // TODO: for some reason walletContracts is not being loaded from local + // remove this code once fixed + const abi = [ + { + inputs: [ + { + internalType: 'bytes32', + type: 'bytes32' + } + ], + name: 'getAlternativeSignature', + outputs: [ + { + internalType: 'string', + type: 'string' + } + ], + stateMutability: 'view', + type: 'function' + } + ] + + return new ethers.Contract(address, abi, provider) +} + +export function eip1271Contract(address: string, provider: ethers.providers.Provider): ethers.Contract { + return new ethers.Contract(address, walletContracts.erc1271.abi, provider) +} + +export async function isValidSignature( + address: string, + provider: ethers.providers.Provider, + digest: ethers.BytesLike, + signature: ethers.BytesLike +): Promise { + // First we try to validate the signature using Ethers + try { + const addr = ethers.utils.recoverAddress(digest, signature) + if (addr.toLowerCase() === address.toLowerCase()) return true + } catch {} + + // Then we try to validate the signature using EIP1271 + try { + const contract = eip1271Contract(address, provider) + const value = await contract.isValidSignature(digest, signature) + if (value === walletContracts.erc1271.returns) return true + } catch {} + + // If all else fails, we return false + return false +} + +export interface URISolver { + resolve: (uri: string) => Promise +} + +async function tryAwait(promise: Promise): Promise { + try { + return await promise + } catch { + return undefined + } +} + +export async function runByEIP5719( + address: string, + provider: ethers.providers.Provider, + digest: ethers.BytesLike, + signature: ethers.BytesLike, + solver?: URISolver, + tries: number = 0 +): Promise { + if (tries > 10) throw new Error('EIP5719 - Too many tries') + + if (commons.signer.canRecover(signature)) { + const recoveredAddr = commons.signer.recoverSigner(digest, signature) + if (recoveredAddr && recoveredAddr.toLowerCase() === address.toLowerCase()) return signature + } + + try { + if (await commons.signer.isValidSignature(address, digest, signature, provider)) { + return signature + } + } catch {} + + const altUri = await tryAwait(eip5719Contract(address, provider).getAlternativeSignature(digest) as Promise) + if (!altUri || altUri === '') throw new Error('EIP5719 - Invalid signature and no alternative signature') + + const altSignature = ethers.utils.hexlify(await (solver || new URISolverIPFS()).resolve(altUri)) + if (!altSignature || altSignature === '') throw new Error('EIP5719 - Empty alternative signature') + if (altSignature === ethers.utils.hexlify(signature)) throw new Error('EIP5719 - Alternative signature is invalid or the same') + + return runByEIP5719(address, provider, digest, altSignature, solver, tries + 1) +} + +export class URISolverIPFS implements URISolver { + constructor(public gateway: string = 'https://cloudflare-ipfs.com/ipfs/') {} + + uri = (uri: string): string => { + if (isIPFS(uri)) return useGateway(uri, this.gateway) + return uri + } + + resolve = async (uri: string): Promise => { + const url = this.uri(uri) + const res = await fetch(url) + if (!res.ok) throw new Error(`URISolverIPFS - Failed to fetch ${url}`) + return await res.text() + } +} diff --git a/packages/replacer/src/ipfs.ts b/packages/replacer/src/ipfs.ts new file mode 100644 index 0000000000..2e6c64ddcb --- /dev/null +++ b/packages/replacer/src/ipfs.ts @@ -0,0 +1,9 @@ +export function useGateway(uri: string, gateway: string) { + const clean = uri.replace('ipfs://ipfs/', '').replace('ipfs://', '') + if (uri.startsWith('ipfs://')) return `${gateway}${clean}` + return uri +} + +export function isIPFS(uri: string): boolean { + return uri.startsWith('ipfs://') +} diff --git a/packages/services/api/CHANGELOG.md b/packages/services/api/CHANGELOG.md index 8d7c5dc551..37b4ea3326 100644 --- a/packages/services/api/CHANGELOG.md +++ b/packages/services/api/CHANGELOG.md @@ -1,5 +1,11 @@ # @0xsequence/api +## 3.0.10 + +### Patch Changes + +- Minor network updates, relayer interface + ## 3.0.9 ### Patch Changes diff --git a/packages/services/api/eslint.config.js b/packages/services/api/eslint.config.js index cecf89b031..19170f88ed 100644 --- a/packages/services/api/eslint.config.js +++ b/packages/services/api/eslint.config.js @@ -1,4 +1,4 @@ -import { config as baseConfig } from "@repo/eslint-config/base" +import { config } from "@repo/eslint-config/react-internal"; /** @type {import("eslint").Linter.Config} */ -export default baseConfig +export default config; diff --git a/packages/services/api/package.json b/packages/services/api/package.json index c0fe2135e0..d05f1ddbe4 100644 --- a/packages/services/api/package.json +++ b/packages/services/api/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/api", - "version": "3.0.9", + "version": "3.0.10", "description": "api sub-package for Sequence", "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/services/api", "author": "Sequence Platforms ULC", diff --git a/packages/services/builder/CHANGELOG.md b/packages/services/builder/CHANGELOG.md index 98b2661e72..1e76b7c904 100644 --- a/packages/services/builder/CHANGELOG.md +++ b/packages/services/builder/CHANGELOG.md @@ -1,5 +1,11 @@ # @0xsequence/builder +## 3.0.10 + +### Patch Changes + +- Minor network updates, relayer interface + ## 3.0.9 ### Patch Changes diff --git a/packages/services/builder/package.json b/packages/services/builder/package.json index 058fda6a51..56f014585a 100644 --- a/packages/services/builder/package.json +++ b/packages/services/builder/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/builder", - "version": "3.0.9", + "version": "3.0.10", "description": "builder sub-package for Sequence", "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/services/builder", "author": "Sequence Platforms ULC", diff --git a/packages/services/guard/CHANGELOG.md b/packages/services/guard/CHANGELOG.md index b3c436416c..d0d37458db 100644 --- a/packages/services/guard/CHANGELOG.md +++ b/packages/services/guard/CHANGELOG.md @@ -1,5 +1,11 @@ # @0xsequence/guard +## 3.0.10 + +### Patch Changes + +- Minor network updates, relayer interface + ## 3.0.9 ### Patch Changes diff --git a/packages/services/guard/eslint.config.js b/packages/services/guard/eslint.config.js index cecf89b031..19170f88ed 100644 --- a/packages/services/guard/eslint.config.js +++ b/packages/services/guard/eslint.config.js @@ -1,4 +1,4 @@ -import { config as baseConfig } from "@repo/eslint-config/base" +import { config } from "@repo/eslint-config/react-internal"; /** @type {import("eslint").Linter.Config} */ -export default baseConfig +export default config; diff --git a/packages/services/guard/package.json b/packages/services/guard/package.json index 35857bea69..3bc3e0f667 100644 --- a/packages/services/guard/package.json +++ b/packages/services/guard/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/guard", - "version": "3.0.9", + "version": "3.0.10", "description": "guard sub-package for Sequence", "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/services/guard", "author": "Sequence Platforms ULC", diff --git a/packages/services/guard/src/client/guard.gen.ts b/packages/services/guard/src/client/guard.gen.ts index 4eea436eeb..ec0af4487a 100644 --- a/packages/services/guard/src/client/guard.gen.ts +++ b/packages/services/guard/src/client/guard.gen.ts @@ -1,5 +1,5 @@ /* eslint-disable */ -// sequence-guard v0.5.0 910e01c32ffb24b42386d4ca6be119b0acc55c5f +// sequence-guard v0.4.0 b62e755c3f81d6b5a8e7462abc063a57a744cdef // -- // Code generated by webrpc-gen@v0.25.3 with typescript generator. DO NOT EDIT. // @@ -7,16 +7,16 @@ export const WebrpcHeader = 'Webrpc' -export const WebrpcHeaderValue = 'webrpc@v0.25.3;gen-typescript@v0.17.0;sequence-guard@v0.5.0' +export const WebrpcHeaderValue = 'webrpc@v0.25.3;gen-typescript@v0.17.0;sequence-guard@v0.4.0' // WebRPC description and code-gen version export const WebRPCVersion = 'v1' // Schema version of your RIDL schema -export const WebRPCSchemaVersion = 'v0.5.0' +export const WebRPCSchemaVersion = 'v0.4.0' // Schema hash generated from your RIDL schema -export const WebRPCSchemaHash = '910e01c32ffb24b42386d4ca6be119b0acc55c5f' +export const WebRPCSchemaHash = 'b62e755c3f81d6b5a8e7462abc063a57a744cdef' type WebrpcGenVersions = { webrpcGenVersion: string @@ -131,7 +131,6 @@ export interface OwnershipProof { export interface AuthToken { id: string token: string - resetAuth?: boolean } export interface RecoveryCode { diff --git a/packages/services/identity-instrument/CHANGELOG.md b/packages/services/identity-instrument/CHANGELOG.md deleted file mode 100644 index 5575cda0b9..0000000000 --- a/packages/services/identity-instrument/CHANGELOG.md +++ /dev/null @@ -1,194 +0,0 @@ -# @0xsequence/identity-instrument - -## 3.0.9 - -### Patch Changes - -- Fee options fixes - -## 3.0.8 - -### Patch Changes - -- Bug fix for relayer fee options handling - -## 3.0.7 - -### Patch Changes - -- Minor bug fixes - -## 3.0.6 - -### Patch Changes - -- userdata upgrade, arweave support - -## 3.0.5 - -### Patch Changes - -- Account federation support - -## 3.0.4 - -### Patch Changes - -- id-token login support - -## 3.0.3 - -### Patch Changes - -- 3.0.3 - -## 3.0.2 - -### Patch Changes - -- allow native self transfer - -## 3.0.1 - -### Patch Changes - -- Network and session fixes - -## 3.0.0 - -### Patch Changes - -- f68be62: ethauth support -- 49d8a2f: New chains, minor fixes -- 3411232: Beta release with dapp connector fixes -- 23cb9e9: New chains, relayer rpc fix -- f5f6a7a: dapp-client updates -- e7de3b1: Fix signer 404 error, minor fixes -- 493836f: multicall3 optimization -- 30e1f1a: 3.0.0 beta -- d5017e8: Beta release for v3 -- 24a5fab: Final RC before 3.0.0 -- e5e1a03: Apple auth fixes -- 0b63113: Apple auth fix -- a89134a: Userdata service updates -- 7c6c811: 3.0.0-beta.3 with fixes -- 3.0.0 release -- 98ce38b: 3.0.0-beta.2 with identity instrument updates -- 747e6b5: Relayer fee options fix -- 40c19ff: dapp client updates for EOA login -- 6d5de25: 3.0.0-beta.1 -- 934acd1: RC5 upgrade - -## 3.0.0-beta.19 - -### Patch Changes - -- Final RC before 3.0.0 - -## 3.0.0-beta.18 - -### Patch Changes - -- multicall3 optimization - -## 3.0.0-beta.17 - -### Patch Changes - -- New chains, relayer rpc fix - -## 3.0.0-beta.16 - -### Patch Changes - -- ethauth support - -## 3.0.0-beta.15 - -### Patch Changes - -- New chains, minor fixes - -## 3.0.0-beta.14 - -### Patch Changes - -- Relayer fee options fix - -## 3.0.0-beta.13 - -### Patch Changes - -- Userdata service updates - -## 3.0.0-beta.12 - -### Patch Changes - -- Beta release with dapp connector fixes - -## 3.0.0-beta.11 - -### Patch Changes - -- 3.0.0 beta - -## 3.0.0-beta.10 - -### Patch Changes - -- dapp-client updates - -## 3.0.0-beta.9 - -### Patch Changes - -- dapp client updates for EOA login - -## 3.0.0-beta.8 - -### Patch Changes - -- Apple auth fixes - -## 3.0.0-beta.7 - -### Patch Changes - -- Apple auth fix - -## 3.0.0-beta.6 - -### Patch Changes - -- Fix signer 404 error, minor fixes - -## 3.0.0-beta.5 - -### Patch Changes - -- Beta release for v3 - -## 3.0.0-beta.4 - -### Patch Changes - -- RC5 upgrade - -## 3.0.0-beta.3 - -### Patch Changes - -- 3.0.0-beta.3 with fixes - -## 3.0.0-beta.2 - -### Patch Changes - -- 3.0.0-beta.2 with identity instrument updates - -## 3.0.0-beta.1 - -### Patch Changes - -- 3.0.0-beta.1 diff --git a/packages/services/identity-instrument/eslint.config.js b/packages/services/identity-instrument/eslint.config.js index cecf89b031..19170f88ed 100644 --- a/packages/services/identity-instrument/eslint.config.js +++ b/packages/services/identity-instrument/eslint.config.js @@ -1,4 +1,4 @@ -import { config as baseConfig } from "@repo/eslint-config/base" +import { config } from "@repo/eslint-config/react-internal"; /** @type {import("eslint").Linter.Config} */ -export default baseConfig +export default config; diff --git a/packages/services/identity-instrument/package.json b/packages/services/identity-instrument/package.json index 856d7e3292..7c37bbcc31 100644 --- a/packages/services/identity-instrument/package.json +++ b/packages/services/identity-instrument/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/identity-instrument", - "version": "3.0.9", + "version": "3.0.10", "license": "Apache-2.0", "type": "module", "publishConfig": { diff --git a/packages/services/identity-instrument/src/index.ts b/packages/services/identity-instrument/src/index.ts index f7b477b6ce..12eb0f0ffc 100644 --- a/packages/services/identity-instrument/src/index.ts +++ b/packages/services/identity-instrument/src/index.ts @@ -65,7 +65,7 @@ export class IdentityInstrument { keyType: KeyType.Ethereum_Secp256k1, }, digest: Hex.fromBytes(digest), - nonce: Hex.fromNumber(Date.now()), + nonce: Hex.random(16), } const res = await this.rpc.sign({ params, diff --git a/packages/services/indexer/CHANGELOG.md b/packages/services/indexer/CHANGELOG.md index b3233d5c69..693670b22c 100644 --- a/packages/services/indexer/CHANGELOG.md +++ b/packages/services/indexer/CHANGELOG.md @@ -1,5 +1,11 @@ # @0xsequence/indexer +## 3.0.10 + +### Patch Changes + +- Minor network updates, relayer interface + ## 3.0.9 ### Patch Changes diff --git a/packages/services/indexer/package.json b/packages/services/indexer/package.json index 1b0d32023b..9833ffaa95 100644 --- a/packages/services/indexer/package.json +++ b/packages/services/indexer/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/indexer", - "version": "3.0.9", + "version": "3.0.10", "description": "indexer sub-package for Sequence", "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/services/indexer", "author": "Sequence Platforms ULC", diff --git a/packages/services/marketplace/CHANGELOG.md b/packages/services/marketplace/CHANGELOG.md index 4365abb88f..b99659fe6f 100644 --- a/packages/services/marketplace/CHANGELOG.md +++ b/packages/services/marketplace/CHANGELOG.md @@ -1,5 +1,11 @@ # @0xsequence/marketplace +## 3.0.10 + +### Patch Changes + +- Minor network updates, relayer interface + ## 3.0.9 ### Patch Changes diff --git a/packages/services/marketplace/package.json b/packages/services/marketplace/package.json index f2aed5ef25..1ac1889a4e 100644 --- a/packages/services/marketplace/package.json +++ b/packages/services/marketplace/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/marketplace", - "version": "3.0.9", + "version": "3.0.10", "description": "marketplace sub-package for Sequence", "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/services/marketplace", "author": "Sequence Platforms ULC", diff --git a/packages/services/marketplace/src/marketplace.gen.ts b/packages/services/marketplace/src/marketplace.gen.ts index 6a316623df..f251bce5d3 100644 --- a/packages/services/marketplace/src/marketplace.gen.ts +++ b/packages/services/marketplace/src/marketplace.gen.ts @@ -1,14 +1,14 @@ /* eslint-disable */ -// marketplace-api 652676d9951ceb12f6846907c7c4b5160c73c57a +// marketplace-api 7ab3354385f317680dd861e82a18aa351d8579d5 // -- -// Code generated by webrpc-gen@v0.30.2 with github.com/webrpc/gen-typescript@v0.19.0 generator. DO NOT EDIT. +// Code generated by webrpc-gen@v0.25.1 with typescript generator. DO NOT EDIT. // -// webrpc-gen -schema=./schema/schema.ridl -target=github.com/webrpc/gen-typescript@v0.19.0 -client -out=./clients/marketplace.gen.ts +// webrpc-gen -schema=marketplace.ridl -target=typescript -client -out=./clients/marketplace.gen.ts export const WebrpcHeader = 'Webrpc' export const WebrpcHeaderValue = - 'webrpc@v0.30.2;gen-typescript@v0.19.0;marketplace-api@v0.0.0-652676d9951ceb12f6846907c7c4b5160c73c57a' + 'webrpc@v0.25.1;gen-typescript@v0.17.0;marketplace-api@v0.0.0-7ab3354385f317680dd861e82a18aa351d8579d5' // WebRPC description and code-gen version export const WebRPCVersion = 'v1' @@ -17,7 +17,7 @@ export const WebRPCVersion = 'v1' export const WebRPCSchemaVersion = '' // Schema hash generated from your RIDL schema -export const WebRPCSchemaHash = '652676d9951ceb12f6846907c7c4b5160c73c57a' +export const WebRPCSchemaHash = '7ab3354385f317680dd861e82a18aa351d8579d5' type WebrpcGenVersions = { webrpcGenVersion: string @@ -71,9 +71,41 @@ function parseWebrpcGenVersions(header: string): WebrpcGenVersions { // Types // +export interface TokenMetadata { + tokenId: string + name: string + description?: string + image?: string + video?: string + audio?: string + properties?: { [key: string]: any } + attributes: Array<{ [key: string]: any }> + image_data?: string + external_url?: string + background_color?: string + animation_url?: string + decimals?: number + updatedAt?: string + assets?: Array +} + +export interface Asset { + id: number + collectionId: number + tokenId: string + url?: string + metadataField: string + name?: string + filesize?: number + mimeType?: string + width?: number + height?: number + updatedAt?: string +} + export enum SortOrder { - ASC = 'ASC', DESC = 'DESC', + ASC = 'ASC', } export enum PropertyType { @@ -95,7 +127,6 @@ export enum MarketplaceKind { alienswap = 'alienswap', payment_processor = 'payment_processor', mintify = 'mintify', - magic_eden = 'magic_eden', } export enum OrderbookKind { @@ -107,7 +138,6 @@ export enum OrderbookKind { looks_rare = 'looks_rare', reservoir = 'reservoir', x2y2 = 'x2y2', - magic_eden = 'magic_eden', } export enum SourceKind { @@ -115,8 +145,6 @@ export enum SourceKind { external = 'external', sequence_marketplace_v1 = 'sequence_marketplace_v1', sequence_marketplace_v2 = 'sequence_marketplace_v2', - opensea = 'opensea', - magic_eden = 'magic_eden', } export enum OrderSide { @@ -125,12 +153,6 @@ export enum OrderSide { offer = 'offer', } -export enum OfferType { - unknown = 'unknown', - item = 'item', - collection = 'collection', -} - export enum OrderStatus { unknown = 'unknown', active = 'active', @@ -158,6 +180,12 @@ export enum CollectionPriority { export enum CollectionStatus { unknown = 'unknown', created = 'created', + syncing_contract_metadata = 'syncing_contract_metadata', + synced_contract_metadata = 'synced_contract_metadata', + syncing_metadata = 'syncing_metadata', + synced_metadata = 'synced_metadata', + syncing_tokens = 'syncing_tokens', + synced_tokens = 'synced_tokens', syncing_orders = 'syncing_orders', active = 'active', failed = 'failed', @@ -171,30 +199,12 @@ export enum ProjectStatus { inactive = 'inactive', } -export enum ItemsContractStatus { - unknown = 'unknown', - created = 'created', - syncing_contract_metadata = 'syncing_contract_metadata', - synced_contract_metadata = 'synced_contract_metadata', - syncing_tokens = 'syncing_tokens', - synced_tokens = 'synced_tokens', - active = 'active', - inactive = 'inactive', - incompatible_type = 'incompatible_type', -} - export enum CollectibleStatus { unknown = 'unknown', active = 'active', inactive = 'inactive', } -export enum CollectibleSource { - unknown = 'unknown', - indexer = 'indexer', - manual = 'manual', -} - export enum CurrencyStatus { unknown = 'unknown', created = 'created', @@ -228,27 +238,24 @@ export enum TransactionCrypto { export enum TransactionNFTCheckoutProvider { unknown = 'unknown', - transak = 'transak', sardine = 'sardine', + transak = 'transak', } export enum TransactionOnRampProvider { unknown = 'unknown', - transak = 'transak', sardine = 'sardine', + transak = 'transak', } export enum TransactionSwapProvider { unknown = 'unknown', - lifi = 'lifi', + zerox = 'zerox', } export enum ExecuteType { unknown = 'unknown', order = 'order', - createListing = 'createListing', - createItemOffer = 'createItemOffer', - createTraitOffer = 'createTraitOffer', } export enum ActivityAction { @@ -262,33 +269,6 @@ export enum ActivityAction { transfer = 'transfer', } -export enum PrimarySaleContractStatus { - unknown = 'unknown', - created = 'created', - syncing_items = 'syncing_items', - active = 'active', - inactive = 'inactive', - incompatible_type = 'incompatible_type', - failed = 'failed', -} - -export enum PrimarySaleVersion { - v0 = 'v0', - v1 = 'v1', -} - -export enum PrimarySaleItemDetailType { - unknown = 'unknown', - global = 'global', - individual = 'individual', -} - -export enum MetadataStatus { - NOT_AVAILABLE = 'NOT_AVAILABLE', - REFRESHING = 'REFRESHING', - AVAILABLE = 'AVAILABLE', -} - export interface Page { page: number pageSize: number @@ -325,26 +305,6 @@ export interface CollectiblesFilter { ordersNotCreatedBy?: Array inCurrencyAddresses?: Array notInCurrencyAddresses?: Array - prices?: Array -} - -export interface OrdersFilter { - searchText?: string - properties?: Array - marketplaces?: Array - inAccounts?: Array - notInAccounts?: Array - ordersCreatedBy?: Array - ordersNotCreatedBy?: Array - inCurrencyAddresses?: Array - notInCurrencyAddresses?: Array - prices?: Array -} - -export interface PriceFilter { - contractAddress: string - min?: string - max?: string } export interface Order { @@ -354,7 +314,6 @@ export interface Order { status: OrderStatus chainId: number originName: string - slug: string collectionContractAddress: string tokenId?: string createdBy: string @@ -427,8 +386,6 @@ export interface CollectionConfig { export interface CollectionLastSynced { allOrders: string newOrders: string - names: Array - cursors: { [key: string]: string } } export interface Project { @@ -441,22 +398,12 @@ export interface Project { deletedAt?: string } -export interface ItemsContract { - status: ItemsContractStatus +export interface Collectible { chainId: number contractAddress: string - contractType: ContractType - lastSynced: string - createdAt: string - updatedAt: string - deletedAt?: string -} - -export interface Collectible { status: CollectibleStatus tokenId: string decimals: number - source: CollectibleSource createdAt: string updatedAt: string deletedAt?: string @@ -473,8 +420,6 @@ export interface Currency { exchangeRate: number defaultChainCurrency: boolean nativeCurrency: boolean - openseaListing: boolean - openseaOffer: boolean createdAt: string updatedAt: string deletedAt?: string @@ -554,16 +499,6 @@ export interface CheckoutOptions { onRamp: Array } -export interface ExecuteInput { - chainId: string - signature: string - method: string - endpoint: string - executeType: ExecuteType - body: any - slug?: string -} - export interface Activity { chainId: number contractAddress: string @@ -585,91 +520,6 @@ export interface Activity { deletedAt?: string } -export interface PrimarySaleContract { - chainId: number - contractAddress: string - collectionAddress: string - contractType: ContractType - version: PrimarySaleVersion - currencyAddress: string - priceDecimals: number - status: PrimarySaleContractStatus - lastSynced: string - createdAt: string - updatedAt: string - deletedAt?: string -} - -export interface PrimarySaleItem { - itemAddress: string - contractType: ContractType - tokenId: string - itemType: PrimarySaleItemDetailType - startDate: string - endDate: string - currencyAddress: string - priceDecimals: number - priceAmount: string - priceAmountFormatted: string - priceUsd: number - priceUsdFormatted: string - supply: string - supplyCap: string - unlimitedSupply: boolean - createdAt: string - updatedAt: string - deletedAt?: string -} - -export interface CollectiblePrimarySaleItem { - metadata: TokenMetadata - primarySaleItem: PrimarySaleItem -} - -export interface PrimarySaleItemsFilter { - includeEmpty: boolean - searchText?: string - properties?: Array - detailTypes?: Array - startDateAfter?: string - startDateBefore?: string - endDateAfter?: string - endDateBefore?: string -} - -export interface TokenMetadata { - tokenId: string - name: string - description?: string - image?: string - video?: string - audio?: string - properties?: { [key: string]: any } - attributes: Array<{ [key: string]: any }> - image_data?: string - external_url?: string - background_color?: string - animation_url?: string - decimals?: number - updatedAt?: string - assets?: Array - status: MetadataStatus -} - -export interface Asset { - id: number - collectionId: number - tokenId: string - url?: string - metadataField: string - name?: string - filesize?: number - mimeType?: string - width?: number - height?: number - updatedAt?: string -} - export interface Admin { createCollection(args: CreateCollectionArgs, headers?: object, signal?: AbortSignal): Promise getCollection(args: GetCollectionArgs, headers?: object, signal?: AbortSignal): Promise @@ -680,29 +530,14 @@ export interface Admin { * determine what should happen here */ syncCollection(args: SyncCollectionArgs, headers?: object, signal?: AbortSignal): Promise - createPrimarySaleContract( - args: CreatePrimarySaleContractArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - deletePrimarySaleContract( - args: DeletePrimarySaleContractArgs, - headers?: object, - signal?: AbortSignal, - ): Promise createCurrency(args: CreateCurrencyArgs, headers?: object, signal?: AbortSignal): Promise createCurrencies(args: CreateCurrenciesArgs, headers?: object, signal?: AbortSignal): Promise updateCurrency(args: UpdateCurrencyArgs, headers?: object, signal?: AbortSignal): Promise - listCurrencies(args: ListCurrenciesArgs, headers?: object, signal?: AbortSignal): Promise + listCurrencies(headers?: object, signal?: AbortSignal): Promise deleteCurrency(args: DeleteCurrencyArgs, headers?: object, signal?: AbortSignal): Promise - /** - * This for manual adding of non minted ERC1155 tokens, it's used for purposes of Shop. - */ - addCollectibles(args: AddCollectiblesArgs, headers?: object, signal?: AbortSignal): Promise } export interface CreateCollectionArgs { - chainId: string projectId: number contractAddress: string } @@ -711,7 +546,6 @@ export interface CreateCollectionReturn { collection: Collection } export interface GetCollectionArgs { - chainId: string projectId: number contractAddress: string } @@ -720,7 +554,6 @@ export interface GetCollectionReturn { collection: Collection } export interface UpdateCollectionArgs { - chainId: string collection: Collection } @@ -728,7 +561,6 @@ export interface UpdateCollectionReturn { collection: Collection } export interface ListCollectionsArgs { - chainId: string projectId: number page?: Page } @@ -738,7 +570,6 @@ export interface ListCollectionsReturn { page?: Page } export interface DeleteCollectionArgs { - chainId: string projectId: number contractAddress: string } @@ -747,30 +578,14 @@ export interface DeleteCollectionReturn { collection: Collection } export interface SyncCollectionArgs { - chainId: string - contractAddress: string -} - -export interface SyncCollectionReturn {} -export interface CreatePrimarySaleContractArgs { - chainId: string projectId: number - primarySaleContractAddress: string - itemsContractAddress: string + contractAddress: string } -export interface CreatePrimarySaleContractReturn { - primarySaleContract: PrimarySaleContract -} -export interface DeletePrimarySaleContractArgs { - chainId: string - projectId: number - primarySaleContractAddress: string +export interface SyncCollectionReturn { + collection: Collection } - -export interface DeletePrimarySaleContractReturn {} export interface CreateCurrencyArgs { - chainId: string currency: Currency } @@ -778,7 +593,6 @@ export interface CreateCurrencyReturn { currency: Currency } export interface CreateCurrenciesArgs { - chainId: string currencies: Array } @@ -786,53 +600,33 @@ export interface CreateCurrenciesReturn { currency: { [key: string]: Currency } } export interface UpdateCurrencyArgs { - chainId: string currency: Currency } export interface UpdateCurrencyReturn { currency: Currency } -export interface ListCurrenciesArgs { - chainId: string -} +export interface ListCurrenciesArgs {} export interface ListCurrenciesReturn { currencies: Array } export interface DeleteCurrencyArgs { - chainId: string + chainId: number contractAddress: string } export interface DeleteCurrencyReturn { currency: Currency } -export interface AddCollectiblesArgs { - chainId: string - itemsContractAddress: string - tokenIds: Array -} - -export interface AddCollectiblesReturn {} export interface Marketplace { - listCurrencies(args: ListCurrenciesArgs, headers?: object, signal?: AbortSignal): Promise + listCurrencies(headers?: object, signal?: AbortSignal): Promise getCollectionDetail( args: GetCollectionDetailArgs, headers?: object, signal?: AbortSignal, ): Promise - getCollectionActiveListingsCurrencies( - args: GetCollectionActiveListingsCurrenciesArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - getCollectionActiveOffersCurrencies( - args: GetCollectionActiveOffersCurrenciesArgs, - headers?: object, - signal?: AbortSignal, - ): Promise getCollectible(args: GetCollectibleArgs, headers?: object, signal?: AbortSignal): Promise getLowestPriceOfferForCollectible( args: GetLowestPriceOfferForCollectibleArgs, @@ -864,23 +658,6 @@ export interface Marketplace { headers?: object, signal?: AbortSignal, ): Promise - listOrdersWithCollectibles( - args: ListOrdersWithCollectiblesArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - getCountOfAllOrders( - args: GetCountOfAllOrdersArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - getCountOfFilteredOrders( - args: GetCountOfFilteredOrdersArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - listListings(args: ListListingsArgs, headers?: object, signal?: AbortSignal): Promise - listOffers(args: ListOffersArgs, headers?: object, signal?: AbortSignal): Promise getCountOfListingsForCollectible( args: GetCountOfListingsForCollectibleArgs, headers?: object, @@ -968,7 +745,7 @@ export interface Marketplace { signal?: AbortSignal, ): Promise /** - * only used in a case of external transactions ( when we create off-chain transactions ) for instance opensea market, use only ExecuteInput params and leave other root inputs empty, they are depracated and kept only for backward compatibility + * only used in a case of external transactions ( when we create off-chain transactions ) for instance opensea market */ execute(args: ExecuteArgs, headers?: object, signal?: AbortSignal): Promise /** @@ -1019,61 +796,21 @@ export interface Marketplace { headers?: object, signal?: AbortSignal, ): Promise - supportedMarketplaces( - args: SupportedMarketplacesArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - getPrimarySaleItem( - args: GetPrimarySaleItemArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - listPrimarySaleItems( - args: ListPrimarySaleItemsArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - getCountOfPrimarySaleItems( - args: GetCountOfPrimarySaleItemsArgs, - headers?: object, - signal?: AbortSignal, - ): Promise } -export interface ListCurrenciesArgs { - chainId: string -} +export interface ListCurrenciesArgs {} export interface ListCurrenciesReturn { currencies: Array } export interface GetCollectionDetailArgs { - chainId: string contractAddress: string } export interface GetCollectionDetailReturn { collection: Collection } -export interface GetCollectionActiveListingsCurrenciesArgs { - chainId: string - contractAddress: string -} - -export interface GetCollectionActiveListingsCurrenciesReturn { - currencies: Array -} -export interface GetCollectionActiveOffersCurrenciesArgs { - chainId: string - contractAddress: string -} - -export interface GetCollectionActiveOffersCurrenciesReturn { - currencies: Array -} export interface GetCollectibleArgs { - chainId: string contractAddress: string tokenId: string } @@ -1082,7 +819,6 @@ export interface GetCollectibleReturn { metadata: TokenMetadata } export interface GetLowestPriceOfferForCollectibleArgs { - chainId: string contractAddress: string tokenId: string filter?: OrderFilter @@ -1092,7 +828,6 @@ export interface GetLowestPriceOfferForCollectibleReturn { order: Order } export interface GetHighestPriceOfferForCollectibleArgs { - chainId: string contractAddress: string tokenId: string filter?: OrderFilter @@ -1102,7 +837,6 @@ export interface GetHighestPriceOfferForCollectibleReturn { order: Order } export interface GetLowestPriceListingForCollectibleArgs { - chainId: string contractAddress: string tokenId: string filter?: OrderFilter @@ -1112,7 +846,6 @@ export interface GetLowestPriceListingForCollectibleReturn { order: Order } export interface GetHighestPriceListingForCollectibleArgs { - chainId: string contractAddress: string tokenId: string filter?: OrderFilter @@ -1122,7 +855,6 @@ export interface GetHighestPriceListingForCollectibleReturn { order: Order } export interface ListListingsForCollectibleArgs { - chainId: string contractAddress: string tokenId: string filter?: OrderFilter @@ -1134,7 +866,6 @@ export interface ListListingsForCollectibleReturn { page?: Page } export interface ListOffersForCollectibleArgs { - chainId: string contractAddress: string tokenId: string filter?: OrderFilter @@ -1145,61 +876,7 @@ export interface ListOffersForCollectibleReturn { offers: Array page?: Page } -export interface ListOrdersWithCollectiblesArgs { - chainId: string - side: OrderSide - contractAddress: string - filter?: OrdersFilter - page?: Page -} - -export interface ListOrdersWithCollectiblesReturn { - collectibles: Array - page?: Page -} -export interface GetCountOfAllOrdersArgs { - chainId: string - side: OrderSide - contractAddress: string -} - -export interface GetCountOfAllOrdersReturn { - count: number -} -export interface GetCountOfFilteredOrdersArgs { - chainId: string - side: OrderSide - contractAddress: string - filter?: OrdersFilter -} - -export interface GetCountOfFilteredOrdersReturn { - count: number -} -export interface ListListingsArgs { - chainId: string - contractAddress: string - filter?: OrderFilter - page?: Page -} - -export interface ListListingsReturn { - listings: Array - page?: Page -} -export interface ListOffersArgs { - chainId: string - contractAddress: string - filter?: OrderFilter - page?: Page -} - -export interface ListOffersReturn { - offers: Array - page?: Page -} export interface GetCountOfListingsForCollectibleArgs { - chainId: string contractAddress: string tokenId: string filter?: OrderFilter @@ -1209,7 +886,6 @@ export interface GetCountOfListingsForCollectibleReturn { count: number } export interface GetCountOfOffersForCollectibleArgs { - chainId: string contractAddress: string tokenId: string filter?: OrderFilter @@ -1219,7 +895,6 @@ export interface GetCountOfOffersForCollectibleReturn { count: number } export interface GetCollectibleLowestOfferArgs { - chainId: string contractAddress: string tokenId: string filter?: OrderFilter @@ -1229,7 +904,6 @@ export interface GetCollectibleLowestOfferReturn { order?: Order } export interface GetCollectibleHighestOfferArgs { - chainId: string contractAddress: string tokenId: string filter?: OrderFilter @@ -1239,7 +913,6 @@ export interface GetCollectibleHighestOfferReturn { order?: Order } export interface GetCollectibleLowestListingArgs { - chainId: string contractAddress: string tokenId: string filter?: OrderFilter @@ -1249,7 +922,6 @@ export interface GetCollectibleLowestListingReturn { order?: Order } export interface GetCollectibleHighestListingArgs { - chainId: string contractAddress: string tokenId: string filter?: OrderFilter @@ -1259,7 +931,6 @@ export interface GetCollectibleHighestListingReturn { order?: Order } export interface ListCollectibleListingsArgs { - chainId: string contractAddress: string tokenId: string filter?: OrderFilter @@ -1271,7 +942,6 @@ export interface ListCollectibleListingsReturn { page?: Page } export interface ListCollectibleOffersArgs { - chainId: string contractAddress: string tokenId: string filter?: OrderFilter @@ -1283,7 +953,6 @@ export interface ListCollectibleOffersReturn { page?: Page } export interface GenerateBuyTransactionArgs { - chainId: string collectionAddress: string buyer: string marketplace: MarketplaceKind @@ -1296,7 +965,6 @@ export interface GenerateBuyTransactionReturn { steps: Array } export interface GenerateSellTransactionArgs { - chainId: string collectionAddress: string seller: string marketplace: MarketplaceKind @@ -1309,13 +977,11 @@ export interface GenerateSellTransactionReturn { steps: Array } export interface GenerateListingTransactionArgs { - chainId: string collectionAddress: string owner: string contractType: ContractType orderbook: OrderbookKind listing: CreateReq - additionalFees: Array walletType?: WalletKind } @@ -1323,22 +989,18 @@ export interface GenerateListingTransactionReturn { steps: Array } export interface GenerateOfferTransactionArgs { - chainId: string collectionAddress: string maker: string contractType: ContractType orderbook: OrderbookKind offer: CreateReq - additionalFees: Array walletType?: WalletKind - offerType: OfferType } export interface GenerateOfferTransactionReturn { steps: Array } export interface GenerateCancelTransactionArgs { - chainId: string collectionAddress: string maker: string marketplace: MarketplaceKind @@ -1349,20 +1011,17 @@ export interface GenerateCancelTransactionReturn { steps: Array } export interface ExecuteArgs { - params: ExecuteInput - chainId?: string - signature?: string - method?: string - endpoint?: string - executeType?: ExecuteType - body?: any -} + signature: string + method: string + endpoint: string + executeType: ExecuteType + body: any +} export interface ExecuteReturn { orderId: string } export interface ListCollectiblesArgs { - chainId: string side: OrderSide contractAddress: string filter?: CollectiblesFilter @@ -1374,7 +1033,6 @@ export interface ListCollectiblesReturn { page?: Page } export interface GetCountOfAllCollectiblesArgs { - chainId: string contractAddress: string } @@ -1382,7 +1040,6 @@ export interface GetCountOfAllCollectiblesReturn { count: number } export interface GetCountOfFilteredCollectiblesArgs { - chainId: string side: OrderSide contractAddress: string filter?: CollectiblesFilter @@ -1392,7 +1049,6 @@ export interface GetCountOfFilteredCollectiblesReturn { count: number } export interface GetFloorOrderArgs { - chainId: string contractAddress: string filter?: CollectiblesFilter } @@ -1401,7 +1057,6 @@ export interface GetFloorOrderReturn { collectible: CollectibleOrder } export interface ListCollectionActivitiesArgs { - chainId: string contractAddress: string page?: Page } @@ -1411,7 +1066,6 @@ export interface ListCollectionActivitiesReturn { page?: Page } export interface ListCollectibleActivitiesArgs { - chainId: string contractAddress: string tokenId: string page?: Page @@ -1422,7 +1076,6 @@ export interface ListCollectibleActivitiesReturn { page?: Page } export interface ListCollectiblesWithLowestListingArgs { - chainId: string contractAddress: string filter?: CollectiblesFilter page?: Page @@ -1433,7 +1086,6 @@ export interface ListCollectiblesWithLowestListingReturn { page?: Page } export interface ListCollectiblesWithHighestOfferArgs { - chainId: string contractAddress: string filter?: CollectiblesFilter page?: Page @@ -1444,19 +1096,16 @@ export interface ListCollectiblesWithHighestOfferReturn { page?: Page } export interface SyncOrderArgs { - chainId: string order: Order } export interface SyncOrderReturn {} export interface SyncOrdersArgs { - chainId: string orders: Array } export interface SyncOrdersReturn {} export interface GetOrdersArgs { - chainId: string input: Array page?: Page } @@ -1466,7 +1115,6 @@ export interface GetOrdersReturn { page?: Page } export interface CheckoutOptionsMarketplaceArgs { - chainId: string wallet: string orders: Array additionalFee: number @@ -1476,7 +1124,6 @@ export interface CheckoutOptionsMarketplaceReturn { options: CheckoutOptions } export interface CheckoutOptionsSalesContractArgs { - chainId: string wallet: string contractAddress: string collectionAddress: string @@ -1486,42 +1133,6 @@ export interface CheckoutOptionsSalesContractArgs { export interface CheckoutOptionsSalesContractReturn { options: CheckoutOptions } -export interface SupportedMarketplacesArgs { - chainId: string -} - -export interface SupportedMarketplacesReturn { - marketplaces: Array -} -export interface GetPrimarySaleItemArgs { - chainId: string - primarySaleContractAddress: string - tokenId: string -} - -export interface GetPrimarySaleItemReturn { - item: CollectiblePrimarySaleItem -} -export interface ListPrimarySaleItemsArgs { - chainId: string - primarySaleContractAddress: string - filter?: PrimarySaleItemsFilter - page?: Page -} - -export interface ListPrimarySaleItemsReturn { - primarySaleItems: Array - page?: Page -} -export interface GetCountOfPrimarySaleItemsArgs { - chainId: string - primarySaleContractAddress: string - filter?: PrimarySaleItemsFilter -} - -export interface GetCountOfPrimarySaleItemsReturn { - count: number -} // // Client @@ -1554,9 +1165,7 @@ export class Admin implements Admin { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -1571,9 +1180,7 @@ export class Admin implements Admin { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -1592,9 +1199,7 @@ export class Admin implements Admin { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -1614,9 +1219,7 @@ export class Admin implements Admin { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -1635,9 +1238,7 @@ export class Admin implements Admin { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -1648,55 +1249,15 @@ export class Admin implements Admin { signal?: AbortSignal, ): Promise => { return this.fetch(this.url('SyncCollection'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return {} - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - createPrimarySaleContract = ( - args: CreatePrimarySaleContractArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('CreatePrimarySaleContract'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { return { - primarySaleContract: _data.primarySaleContract, + collection: _data.collection, } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - deletePrimarySaleContract = ( - args: DeletePrimarySaleContractArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('DeletePrimarySaleContract'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return {} - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -1715,9 +1276,7 @@ export class Admin implements Admin { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -1736,9 +1295,7 @@ export class Admin implements Admin { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -1757,19 +1314,13 @@ export class Admin implements Admin { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } - listCurrencies = ( - args: ListCurrenciesArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('ListCurrencies'), createHTTPRequest(args, headers, signal)).then( + listCurrencies = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('ListCurrencies'), createHTTPRequest({}, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { return { @@ -1778,9 +1329,7 @@ export class Admin implements Admin { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -1799,28 +1348,7 @@ export class Admin implements Admin { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - addCollectibles = ( - args: AddCollectiblesArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('AddCollectibles'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return {} - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -1839,12 +1367,8 @@ export class Marketplace implements Marketplace { return this.hostname + this.path + name } - listCurrencies = ( - args: ListCurrenciesArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('ListCurrencies'), createHTTPRequest(args, headers, signal)).then( + listCurrencies = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('ListCurrencies'), createHTTPRequest({}, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { return { @@ -1853,9 +1377,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -1874,51 +1396,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - getCollectionActiveListingsCurrencies = ( - args: GetCollectionActiveListingsCurrenciesArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetCollectionActiveListingsCurrencies'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - currencies: >_data.currencies, - } - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - getCollectionActiveOffersCurrencies = ( - args: GetCollectionActiveOffersCurrenciesArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetCollectionActiveOffersCurrencies'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - currencies: >_data.currencies, - } - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -1937,9 +1415,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -1958,9 +1434,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -1979,9 +1453,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2000,9 +1472,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2021,9 +1491,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2043,9 +1511,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2065,109 +1531,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - listOrdersWithCollectibles = ( - args: ListOrdersWithCollectiblesArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('ListOrdersWithCollectibles'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - collectibles: >_data.collectibles, - page: _data.page, - } - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - getCountOfAllOrders = ( - args: GetCountOfAllOrdersArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetCountOfAllOrders'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - count: _data.count, - } - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - getCountOfFilteredOrders = ( - args: GetCountOfFilteredOrdersArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetCountOfFilteredOrders'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - count: _data.count, - } - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - listListings = (args: ListListingsArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('ListListings'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - listings: >_data.listings, - page: _data.page, - } - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - listOffers = (args: ListOffersArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('ListOffers'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - offers: >_data.offers, - page: _data.page, - } - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2186,9 +1550,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2207,9 +1569,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2228,9 +1588,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2249,9 +1607,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2270,9 +1626,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2291,9 +1645,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2313,9 +1665,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2335,9 +1685,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2356,9 +1704,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2377,9 +1723,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2398,9 +1742,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2419,9 +1761,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2440,9 +1780,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2457,9 +1795,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2479,9 +1815,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2500,9 +1834,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2521,9 +1853,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2538,9 +1868,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2560,9 +1888,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2582,9 +1908,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2604,9 +1928,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2626,9 +1948,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2641,9 +1961,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2656,9 +1974,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2674,9 +1990,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2695,9 +2009,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2716,94 +2028,7 @@ export class Marketplace implements Marketplace { }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - supportedMarketplaces = ( - args: SupportedMarketplacesArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('SupportedMarketplaces'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - marketplaces: >_data.marketplaces, - } - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - getPrimarySaleItem = ( - args: GetPrimarySaleItemArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetPrimarySaleItem'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - item: _data.item, - } - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - listPrimarySaleItems = ( - args: ListPrimarySaleItemsArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('ListPrimarySaleItems'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - primarySaleItems: >_data.primarySaleItems, - page: _data.page, - } - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) - }, - ) - } - - getCountOfPrimarySaleItems = ( - args: GetCountOfPrimarySaleItemsArgs, - headers?: object, - signal?: AbortSignal, - ): Promise => { - return this.fetch(this.url('GetCountOfPrimarySaleItems'), createHTTPRequest(args, headers, signal)).then( - (res) => { - return buildResponse(res).then((_data) => { - return { - count: _data.count, - } - }) - }, - (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } @@ -2827,9 +2052,13 @@ const buildResponse = (res: Response): Promise => { try { data = JSON.parse(text) } catch (error) { + let message = '' + if (error instanceof Error) { + message = error.message + } throw WebrpcBadResponseError.new({ status: res.status, - cause: `JSON.parse(): ${error instanceof Error ? error.message : String(error)}: response text: ${text}`, + cause: `JSON.parse(): ${message}: response text: ${text}`, }) } if (!res.ok) { @@ -2877,7 +2106,7 @@ export class WebrpcEndpointError extends WebrpcError { name: string = 'WebrpcEndpoint', code: number = 0, message: string = `endpoint error`, - status: number = 400, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) @@ -2890,7 +2119,7 @@ export class WebrpcRequestFailedError extends WebrpcError { name: string = 'WebrpcRequestFailed', code: number = -1, message: string = `request failed`, - status: number = 400, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) @@ -2903,7 +2132,7 @@ export class WebrpcBadRouteError extends WebrpcError { name: string = 'WebrpcBadRoute', code: number = -2, message: string = `bad route`, - status: number = 404, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) @@ -2916,7 +2145,7 @@ export class WebrpcBadMethodError extends WebrpcError { name: string = 'WebrpcBadMethod', code: number = -3, message: string = `bad method`, - status: number = 405, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) @@ -2929,7 +2158,7 @@ export class WebrpcBadRequestError extends WebrpcError { name: string = 'WebrpcBadRequest', code: number = -4, message: string = `bad request`, - status: number = 400, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) @@ -2942,7 +2171,7 @@ export class WebrpcBadResponseError extends WebrpcError { name: string = 'WebrpcBadResponse', code: number = -5, message: string = `bad response`, - status: number = 500, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) @@ -2955,7 +2184,7 @@ export class WebrpcServerPanicError extends WebrpcError { name: string = 'WebrpcServerPanic', code: number = -6, message: string = `server panic`, - status: number = 500, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) @@ -2968,7 +2197,7 @@ export class WebrpcInternalErrorError extends WebrpcError { name: string = 'WebrpcInternalError', code: number = -7, message: string = `internal error`, - status: number = 500, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) @@ -2976,16 +2205,16 @@ export class WebrpcInternalErrorError extends WebrpcError { } } -export class WebrpcClientAbortedError extends WebrpcError { +export class WebrpcClientDisconnectedError extends WebrpcError { constructor( - name: string = 'WebrpcClientAborted', + name: string = 'WebrpcClientDisconnected', code: number = -8, - message: string = `request aborted by client`, - status: number = 400, + message: string = `client disconnected`, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) - Object.setPrototypeOf(this, WebrpcClientAbortedError.prototype) + Object.setPrototypeOf(this, WebrpcClientDisconnectedError.prototype) } } @@ -2994,7 +2223,7 @@ export class WebrpcStreamLostError extends WebrpcError { name: string = 'WebrpcStreamLost', code: number = -9, message: string = `stream lost`, - status: number = 400, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) @@ -3007,7 +2236,7 @@ export class WebrpcStreamFinishedError extends WebrpcError { name: string = 'WebrpcStreamFinished', code: number = -10, message: string = `stream finished`, - status: number = 200, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) @@ -3022,7 +2251,7 @@ export class UnauthorizedError extends WebrpcError { name: string = 'Unauthorized', code: number = 1000, message: string = `Unauthorized access`, - status: number = 401, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) @@ -3035,7 +2264,7 @@ export class PermissionDeniedError extends WebrpcError { name: string = 'PermissionDenied', code: number = 1001, message: string = `Permission denied`, - status: number = 403, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) @@ -3048,7 +2277,7 @@ export class SessionExpiredError extends WebrpcError { name: string = 'SessionExpired', code: number = 1002, message: string = `Session expired`, - status: number = 403, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) @@ -3061,7 +2290,7 @@ export class MethodNotFoundError extends WebrpcError { name: string = 'MethodNotFound', code: number = 1003, message: string = `Method not found`, - status: number = 404, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) @@ -3069,64 +2298,64 @@ export class MethodNotFoundError extends WebrpcError { } } -export class RequestConflictError extends WebrpcError { +export class TimeoutError extends WebrpcError { constructor( - name: string = 'RequestConflict', - code: number = 1004, - message: string = `Conflict with target resource`, - status: number = 409, + name: string = 'Timeout', + code: number = 2000, + message: string = `Request timed out`, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) - Object.setPrototypeOf(this, RequestConflictError.prototype) + Object.setPrototypeOf(this, TimeoutError.prototype) } } -export class AbortedError extends WebrpcError { +export class InvalidArgumentError extends WebrpcError { constructor( - name: string = 'Aborted', - code: number = 1005, - message: string = `Request aborted`, - status: number = 400, + name: string = 'InvalidArgument', + code: number = 2001, + message: string = `Invalid argument`, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) - Object.setPrototypeOf(this, AbortedError.prototype) + Object.setPrototypeOf(this, InvalidArgumentError.prototype) } } -export class GeoblockedError extends WebrpcError { +export class NotFoundError extends WebrpcError { constructor( - name: string = 'Geoblocked', - code: number = 1006, - message: string = `Geoblocked region`, - status: number = 451, + name: string = 'NotFound', + code: number = 3000, + message: string = `Resource not found`, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) - Object.setPrototypeOf(this, GeoblockedError.prototype) + Object.setPrototypeOf(this, NotFoundError.prototype) } } -export class RateLimitedError extends WebrpcError { +export class UserNotFoundError extends WebrpcError { constructor( - name: string = 'RateLimited', - code: number = 1007, - message: string = `Rate-limited. Please slow down.`, - status: number = 429, + name: string = 'UserNotFound', + code: number = 3001, + message: string = `User not found`, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) - Object.setPrototypeOf(this, RateLimitedError.prototype) + Object.setPrototypeOf(this, UserNotFoundError.prototype) } } export class ProjectNotFoundError extends WebrpcError { constructor( name: string = 'ProjectNotFound', - code: number = 1008, + code: number = 3002, message: string = `Project not found`, - status: number = 401, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) @@ -3134,198 +2363,29 @@ export class ProjectNotFoundError extends WebrpcError { } } -export class SecretKeyCorsDisallowedError extends WebrpcError { - constructor( - name: string = 'SecretKeyCorsDisallowed', - code: number = 1009, - message: string = `CORS disallowed. Admin API Secret Key can't be used from a web app.`, - status: number = 403, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, SecretKeyCorsDisallowedError.prototype) - } -} - -export class AccessKeyNotFoundError extends WebrpcError { +export class InvalidTierError extends WebrpcError { constructor( - name: string = 'AccessKeyNotFound', - code: number = 1101, - message: string = `Access key not found`, - status: number = 401, + name: string = 'InvalidTier', + code: number = 3003, + message: string = `Invalid subscription tier`, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) - Object.setPrototypeOf(this, AccessKeyNotFoundError.prototype) + Object.setPrototypeOf(this, InvalidTierError.prototype) } } -export class AccessKeyMismatchError extends WebrpcError { +export class ProjectLimitReachedError extends WebrpcError { constructor( - name: string = 'AccessKeyMismatch', - code: number = 1102, - message: string = `Access key mismatch`, - status: number = 403, + name: string = 'ProjectLimitReached', + code: number = 3005, + message: string = `Project limit reached`, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) - Object.setPrototypeOf(this, AccessKeyMismatchError.prototype) - } -} - -export class InvalidOriginError extends WebrpcError { - constructor( - name: string = 'InvalidOrigin', - code: number = 1103, - message: string = `Invalid origin for Access Key`, - status: number = 403, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, InvalidOriginError.prototype) - } -} - -export class InvalidServiceError extends WebrpcError { - constructor( - name: string = 'InvalidService', - code: number = 1104, - message: string = `Service not enabled for Access key`, - status: number = 403, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, InvalidServiceError.prototype) - } -} - -export class UnauthorizedUserError extends WebrpcError { - constructor( - name: string = 'UnauthorizedUser', - code: number = 1105, - message: string = `Unauthorized user`, - status: number = 403, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, UnauthorizedUserError.prototype) - } -} - -export class InvalidChainError extends WebrpcError { - constructor( - name: string = 'InvalidChain', - code: number = 1106, - message: string = `Network not enabled for Access key`, - status: number = 403, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, InvalidChainError.prototype) - } -} - -export class QuotaExceededError extends WebrpcError { - constructor( - name: string = 'QuotaExceeded', - code: number = 1200, - message: string = `Quota request exceeded`, - status: number = 429, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, QuotaExceededError.prototype) - } -} - -export class QuotaRateLimitError extends WebrpcError { - constructor( - name: string = 'QuotaRateLimit', - code: number = 1201, - message: string = `Quota rate limit exceeded`, - status: number = 429, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, QuotaRateLimitError.prototype) - } -} - -export class NoDefaultKeyError extends WebrpcError { - constructor( - name: string = 'NoDefaultKey', - code: number = 1300, - message: string = `No default access key found`, - status: number = 403, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, NoDefaultKeyError.prototype) - } -} - -export class MaxAccessKeysError extends WebrpcError { - constructor( - name: string = 'MaxAccessKeys', - code: number = 1301, - message: string = `Access keys limit reached`, - status: number = 403, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, MaxAccessKeysError.prototype) - } -} - -export class AtLeastOneKeyError extends WebrpcError { - constructor( - name: string = 'AtLeastOneKey', - code: number = 1302, - message: string = `You need at least one Access Key`, - status: number = 403, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, AtLeastOneKeyError.prototype) - } -} - -export class TimeoutError extends WebrpcError { - constructor( - name: string = 'Timeout', - code: number = 1900, - message: string = `Request timed out`, - status: number = 408, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, TimeoutError.prototype) - } -} - -export class NotFoundError extends WebrpcError { - constructor( - name: string = 'NotFound', - code: number = 2000, - message: string = `Resource not found`, - status: number = 400, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, NotFoundError.prototype) - } -} - -export class InvalidArgumentError extends WebrpcError { - constructor( - name: string = 'InvalidArgument', - code: number = 2001, - message: string = `Invalid argument`, - status: number = 400, - cause?: string, - ) { - super(name, code, message, status, cause) - Object.setPrototypeOf(this, InvalidArgumentError.prototype) + Object.setPrototypeOf(this, ProjectLimitReachedError.prototype) } } @@ -3334,7 +2394,7 @@ export class NotImplementedError extends WebrpcError { name: string = 'NotImplemented', code: number = 9999, message: string = `Not Implemented`, - status: number = 500, + status: number = 0, cause?: string, ) { super(name, code, message, status, cause) @@ -3351,33 +2411,20 @@ export enum errors { WebrpcBadResponse = 'WebrpcBadResponse', WebrpcServerPanic = 'WebrpcServerPanic', WebrpcInternalError = 'WebrpcInternalError', - WebrpcClientAborted = 'WebrpcClientAborted', + WebrpcClientDisconnected = 'WebrpcClientDisconnected', WebrpcStreamLost = 'WebrpcStreamLost', WebrpcStreamFinished = 'WebrpcStreamFinished', Unauthorized = 'Unauthorized', PermissionDenied = 'PermissionDenied', SessionExpired = 'SessionExpired', MethodNotFound = 'MethodNotFound', - RequestConflict = 'RequestConflict', - Aborted = 'Aborted', - Geoblocked = 'Geoblocked', - RateLimited = 'RateLimited', - ProjectNotFound = 'ProjectNotFound', - SecretKeyCorsDisallowed = 'SecretKeyCorsDisallowed', - AccessKeyNotFound = 'AccessKeyNotFound', - AccessKeyMismatch = 'AccessKeyMismatch', - InvalidOrigin = 'InvalidOrigin', - InvalidService = 'InvalidService', - UnauthorizedUser = 'UnauthorizedUser', - InvalidChain = 'InvalidChain', - QuotaExceeded = 'QuotaExceeded', - QuotaRateLimit = 'QuotaRateLimit', - NoDefaultKey = 'NoDefaultKey', - MaxAccessKeys = 'MaxAccessKeys', - AtLeastOneKey = 'AtLeastOneKey', Timeout = 'Timeout', - NotFound = 'NotFound', InvalidArgument = 'InvalidArgument', + NotFound = 'NotFound', + UserNotFound = 'UserNotFound', + ProjectNotFound = 'ProjectNotFound', + InvalidTier = 'InvalidTier', + ProjectLimitReached = 'ProjectLimitReached', NotImplemented = 'NotImplemented', } @@ -3390,33 +2437,20 @@ export enum WebrpcErrorCodes { WebrpcBadResponse = -5, WebrpcServerPanic = -6, WebrpcInternalError = -7, - WebrpcClientAborted = -8, + WebrpcClientDisconnected = -8, WebrpcStreamLost = -9, WebrpcStreamFinished = -10, Unauthorized = 1000, PermissionDenied = 1001, SessionExpired = 1002, MethodNotFound = 1003, - RequestConflict = 1004, - Aborted = 1005, - Geoblocked = 1006, - RateLimited = 1007, - ProjectNotFound = 1008, - SecretKeyCorsDisallowed = 1009, - AccessKeyNotFound = 1101, - AccessKeyMismatch = 1102, - InvalidOrigin = 1103, - InvalidService = 1104, - UnauthorizedUser = 1105, - InvalidChain = 1106, - QuotaExceeded = 1200, - QuotaRateLimit = 1201, - NoDefaultKey = 1300, - MaxAccessKeys = 1301, - AtLeastOneKey = 1302, - Timeout = 1900, - NotFound = 2000, + Timeout = 2000, InvalidArgument = 2001, + NotFound = 3000, + UserNotFound = 3001, + ProjectNotFound = 3002, + InvalidTier = 3003, + ProjectLimitReached = 3005, NotImplemented = 9999, } @@ -3429,33 +2463,20 @@ export const webrpcErrorByCode: { [code: number]: any } = { [-5]: WebrpcBadResponseError, [-6]: WebrpcServerPanicError, [-7]: WebrpcInternalErrorError, - [-8]: WebrpcClientAbortedError, + [-8]: WebrpcClientDisconnectedError, [-9]: WebrpcStreamLostError, [-10]: WebrpcStreamFinishedError, [1000]: UnauthorizedError, [1001]: PermissionDeniedError, [1002]: SessionExpiredError, [1003]: MethodNotFoundError, - [1004]: RequestConflictError, - [1005]: AbortedError, - [1006]: GeoblockedError, - [1007]: RateLimitedError, - [1008]: ProjectNotFoundError, - [1009]: SecretKeyCorsDisallowedError, - [1101]: AccessKeyNotFoundError, - [1102]: AccessKeyMismatchError, - [1103]: InvalidOriginError, - [1104]: InvalidServiceError, - [1105]: UnauthorizedUserError, - [1106]: InvalidChainError, - [1200]: QuotaExceededError, - [1201]: QuotaRateLimitError, - [1300]: NoDefaultKeyError, - [1301]: MaxAccessKeysError, - [1302]: AtLeastOneKeyError, - [1900]: TimeoutError, - [2000]: NotFoundError, + [2000]: TimeoutError, [2001]: InvalidArgumentError, + [3000]: NotFoundError, + [3001]: UserNotFoundError, + [3002]: ProjectNotFoundError, + [3003]: InvalidTierError, + [3005]: ProjectLimitReachedError, [9999]: NotImplementedError, } diff --git a/packages/services/metadata/CHANGELOG.md b/packages/services/metadata/CHANGELOG.md index 19d5943a1a..c284615b66 100644 --- a/packages/services/metadata/CHANGELOG.md +++ b/packages/services/metadata/CHANGELOG.md @@ -1,5 +1,11 @@ # @0xsequence/metadata +## 3.0.10 + +### Patch Changes + +- Minor network updates, relayer interface + ## 3.0.9 ### Patch Changes diff --git a/packages/services/metadata/package.json b/packages/services/metadata/package.json index a4ea57696f..db4ec068a1 100644 --- a/packages/services/metadata/package.json +++ b/packages/services/metadata/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/metadata", - "version": "3.0.9", + "version": "3.0.10", "publishConfig": { "access": "public" }, diff --git a/packages/services/metadata/src/metadata.gen.ts b/packages/services/metadata/src/metadata.gen.ts index 9390aee762..05cdfb1943 100644 --- a/packages/services/metadata/src/metadata.gen.ts +++ b/packages/services/metadata/src/metadata.gen.ts @@ -1,357 +1,73 @@ /* eslint-disable */ -// sequence-metadata v0.4.0 673a5fa528008c7f9558810fbb24aad978ed7a84 +// sequence-metadata v0.4.0 5cb74ff169ce80c2e42e65d6bbc98b1daaa0945f // -- -// Code generated by Webrpc-gen@v0.31.0 with typescript generator. DO NOT EDIT. +// Code generated by webrpc-gen@v0.25.3 with typescript generator. DO NOT EDIT. // -// webrpc-gen -schema=metadata.ridl -target=typescript -client -ignore=@deprecated -compat -out=./clients/metadata.gen.ts +// webrpc-gen -schema=metadata.ridl -target=typescript -client -ignore=@deprecated -out=./clients/metadata.gen.ts -// Webrpc description and code-gen version -export const WebrpcVersion = 'v1' - -// Schema version of your RIDL schema -export const WebrpcSchemaVersion = 'v0.4.0' - -// Schema hash generated from your RIDL schema -export const WebrpcSchemaHash = '673a5fa528008c7f9558810fbb24aad978ed7a84' - -// -// Client interface -// - -export interface MetadataClient { - ping(headers?: object, signal?: AbortSignal): Promise - - version(headers?: object, signal?: AbortSignal): Promise - - runtimeStatus(headers?: object, signal?: AbortSignal): Promise - - getTask(req: GetTaskArgs, headers?: object, signal?: AbortSignal): Promise - - getTaskStatus(req: GetTaskStatusArgs, headers?: object, signal?: AbortSignal): Promise - - /** - * Contract Info -- returns contract meta-info for contracts found in registered chain's token-lists - */ - getContractInfo(req: GetContractInfoArgs, headers?: object, signal?: AbortSignal): Promise - - getContractInfoBatch( - req: GetContractInfoBatchArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - /** - * Find Contract Info across all chains token-lists. Similar to GetContractInfo above, - * but it will traverse all chains and results from all. - */ - findContractInfo(req: FindContractInfoArgs, headers?: object, signal?: AbortSignal): Promise - - /** - * map of contractAddress :: []ContractInfo - */ - findContractInfoBatch( - req: FindContractInfoBatchArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - /** - * Refresh Contract Info -- refresh contract meta-info - */ - refreshContractInfo( - req: RefreshContractInfoArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - refreshContractInfoBatch( - req: RefreshContractInfoBatchArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - /** - * Search for contract infos using a query string - */ - searchContractsByQuery( - req: SearchContractsByQueryArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - /** - * GetTokenMetadata - fetch token metadata for a particular contract and respective tokenIDs - */ - getTokenMetadata(req: GetTokenMetadataArgs, headers?: object, signal?: AbortSignal): Promise - - /** - * GetTokenMetadataBatch allows you to query the token metadata of a batch of contracts and respective tokenIDs - * where map is contractAddress::[]tokenID => contractAddress::[]TokenMetadata - * - * Note, we limit each request to 50 contracts max and 50 tokens max per contract. - */ - getTokenMetadataBatch( - req: GetTokenMetadataBatchArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - /** - * RefreshTokenMetadata allows you to refresh a contract metadata for contract-level and token-level metadata. - */ - refreshTokenMetadata( - req: RefreshTokenMetadataArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - /** - * Search ERC721 & ERC1155 token metadata by query string 'q' - */ - searchTokenMetadataByQuery( - req: SearchTokenMetadataByQueryArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - /** - * Search ERC721 & ERC1155 token metadata by filter object 'filter' - * which allows to search by text or properties. - */ - searchTokenMetadata( - req: SearchTokenMetadataArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - /** - * Search ERC721 & ERC1155 for token IDs by filter object 'filter' - * which allows to search by text or properties. - */ - searchTokenMetadataTokenIDs( - req: SearchTokenMetadataTokenIDsArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - /** - * Get token metadata property filters for a contract address - */ - getTokenMetadataPropertyFilters( - req: GetTokenMetadataPropertyFiltersArgs, - headers?: object, - signal?: AbortSignal, - ): Promise +export const WebrpcHeader = 'Webrpc' - /** - * Gets Token Directory supported networks - */ - getTokenDirectoryNetworks( - req: GetTokenDirectoryNetworksArgs, - headers?: object, - signal?: AbortSignal, - ): Promise +export const WebrpcHeaderValue = 'webrpc@v0.25.3;gen-typescript@v0.17.0;sequence-metadata@v0.4.0' - /** - * Gets Token Directory entries - */ - getTokenDirectory( - req: GetTokenDirectoryArgs, - headers?: object, - signal?: AbortSignal, - ): Promise +// WebRPC description and code-gen version +export const WebRPCVersion = 'v1' - /** - * Search in Token Directory - */ - searchTokenDirectory( - req: SearchTokenDirectoryArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - /** - * Niftyswap querying data - */ - getNiftyswapTokenQuantity( - req: GetNiftyswapTokenQuantityArgs, - headers?: object, - signal?: AbortSignal, - ): Promise +// Schema version of your RIDL schema +export const WebRPCSchemaVersion = 'v0.4.0' - /** - * map of tokenID :: quantity - */ - getNiftyswapUnitPrices( - req: GetNiftyswapUnitPricesArgs, - headers?: object, - signal?: AbortSignal, - ): Promise +// Schema hash generated from your RIDL schema +export const WebRPCSchemaHash = '5cb74ff169ce80c2e42e65d6bbc98b1daaa0945f' - /** - * map of tokenID :: price - */ - getNiftyswapUnitPricesWithQuantities( - req: GetNiftyswapUnitPricesWithQuantitiesArgs, - headers?: object, - signal?: AbortSignal, - ): Promise +type WebrpcGenVersions = { + webrpcGenVersion: string + codeGenName: string + codeGenVersion: string + schemaName: string + schemaVersion: string } -export interface CollectionsClient { - createCollection(req: CreateCollectionArgs, headers?: object, signal?: AbortSignal): Promise - - getCollection(req: GetCollectionArgs, headers?: object, signal?: AbortSignal): Promise - - listCollections(req: ListCollectionsArgs, headers?: object, signal?: AbortSignal): Promise - - updateCollection(req: UpdateCollectionArgs, headers?: object, signal?: AbortSignal): Promise - - deleteCollection(req: DeleteCollectionArgs, headers?: object, signal?: AbortSignal): Promise - - publishCollection( - req: PublishCollectionArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - unpublishCollection( - req: UnpublishCollectionArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - createContractCollection( - req: CreateContractCollectionArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - getContractCollection( - req: GetContractCollectionArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - listContractCollections( - req: ListContractCollectionsArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - updateContractCollection( - req: UpdateContractCollectionArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - deleteContractCollection( - req: DeleteContractCollectionArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - createToken(req: CreateTokenArgs, headers?: object, signal?: AbortSignal): Promise - - getToken(req: GetTokenArgs, headers?: object, signal?: AbortSignal): Promise - - listTokens(req: ListTokensArgs, headers?: object, signal?: AbortSignal): Promise - - updateToken(req: UpdateTokenArgs, headers?: object, signal?: AbortSignal): Promise - - deleteToken(req: DeleteTokenArgs, headers?: object, signal?: AbortSignal): Promise - - createAsset(req: CreateAssetArgs, headers?: object, signal?: AbortSignal): Promise - - getAsset(req: GetAssetArgs, headers?: object, signal?: AbortSignal): Promise - - updateAsset(req: UpdateAssetArgs, headers?: object, signal?: AbortSignal): Promise +export function VersionFromHeader(headers: Headers): WebrpcGenVersions { + const headerValue = headers.get(WebrpcHeader) + if (!headerValue) { + return { + webrpcGenVersion: '', + codeGenName: '', + codeGenVersion: '', + schemaName: '', + schemaVersion: '', + } + } - deleteAsset(req: DeleteAssetArgs, headers?: object, signal?: AbortSignal): Promise + return parseWebrpcGenVersions(headerValue) } -export interface AdminClient { - /** - * ContractInfo - */ - refreshContractInfoUpdatedBefore( - req: RefreshContractInfoUpdatedBeforeArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - /** - * TokenMetadata - */ - refreshTokenMetadataUpdatedBefore( - req: RefreshTokenMetadataUpdatedBeforeArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - /** - * Contract Info Overrides - */ - getContractInfoOverride( - req: GetContractInfoOverrideArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - getContractInfoOverrides( - req: GetContractInfoOverridesArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - addContractInfoOverride( - req: AddContractInfoOverrideArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - updateContractInfoOverride( - req: UpdateContractInfoOverrideArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - removeContractInfoOverride( - req: RemoveContractInfoOverrideArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - /** - * Token Directory - */ - isInTokenDirectory( - req: IsInTokenDirectoryArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - setTokenDirectoryFeatureIndex( - req: SetTokenDirectoryFeatureIndexArgs, - headers?: object, - signal?: AbortSignal, - ): Promise - - addContractToTokenDirectory( - req: AddContractToTokenDirectoryArgs, - headers?: object, - signal?: AbortSignal, - ): Promise +function parseWebrpcGenVersions(header: string): WebrpcGenVersions { + const versions = header.split(';') + if (versions.length < 3) { + return { + webrpcGenVersion: '', + codeGenName: '', + codeGenVersion: '', + schemaName: '', + schemaVersion: '', + } + } - removeContractFromTokenDirectory( - req: RemoveContractFromTokenDirectoryArgs, - headers?: object, - signal?: AbortSignal, - ): Promise + const [_, webrpcGenVersion] = versions[0]!.split('@') + const [codeGenName, codeGenVersion] = versions[1]!.split('@') + const [schemaName, schemaVersion] = versions[2]!.split('@') - refreshTokenDirectory(headers?: object, signal?: AbortSignal): Promise + return { + webrpcGenVersion: webrpcGenVersion ?? '', + codeGenName: codeGenName ?? '', + codeGenVersion: codeGenVersion ?? '', + schemaName: schemaName ?? '', + schemaVersion: schemaVersion ?? '', + } } // -// Schema types +// Types // export enum ContractType { @@ -650,24 +366,177 @@ export interface Task { result: Array } +export interface Metadata { + ping(headers?: object, signal?: AbortSignal): Promise + version(headers?: object, signal?: AbortSignal): Promise + runtimeStatus(headers?: object, signal?: AbortSignal): Promise + getTask(args: GetTaskArgs, headers?: object, signal?: AbortSignal): Promise + getTaskStatus(args: GetTaskStatusArgs, headers?: object, signal?: AbortSignal): Promise + /** + * Contract Info -- returns contract meta-info for contracts found in registered chain's token-lists + */ + getContractInfo(args: GetContractInfoArgs, headers?: object, signal?: AbortSignal): Promise + getContractInfoBatch( + args: GetContractInfoBatchArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Find Contract Info across all chains token-lists. Similar to GetContractInfo above, + * but it will traverse all chains and results from all. + */ + findContractInfo(args: FindContractInfoArgs, headers?: object, signal?: AbortSignal): Promise + /** + * map of contractAddress :: []ContractInfo + */ + findContractInfoBatch( + args: FindContractInfoBatchArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Refresh Contract Info -- refresh contract meta-info + */ + refreshContractInfo( + args: RefreshContractInfoArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + refreshContractInfoBatch( + args: RefreshContractInfoBatchArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Search for contract infos using a query string + */ + searchContractsByQuery( + args: SearchContractsByQueryArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * GetTokenMetadata - fetch token metadata for a particular contract and respective tokenIDs + */ + getTokenMetadata(args: GetTokenMetadataArgs, headers?: object, signal?: AbortSignal): Promise + /** + * GetTokenMetadataBatch allows you to query the token metadata of a batch of contracts and respective tokenIDs + * where map is contractAddress::[]tokenID => contractAddress::[]TokenMetadata + * + * Note, we limit each request to 50 contracts max and 50 tokens max per contract. + */ + getTokenMetadataBatch( + args: GetTokenMetadataBatchArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * RefreshTokenMetadata allows you to refresh a contract metadata for contract-level and token-level metadata. + */ + refreshTokenMetadata( + args: RefreshTokenMetadataArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Search ERC721 & ERC1155 token metadata by query string 'q' + */ + searchTokenMetadataByQuery( + args: SearchTokenMetadataByQueryArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Search ERC721 & ERC1155 token metadata by filter object 'filter' + * which allows to search by text or properties. + */ + searchTokenMetadata( + args: SearchTokenMetadataArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Search ERC721 & ERC1155 for token IDs by filter object 'filter' + * which allows to search by text or properties. + */ + searchTokenMetadataTokenIDs( + args: SearchTokenMetadataTokenIDsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Get token metadata property filters for a contract address + */ + getTokenMetadataPropertyFilters( + args: GetTokenMetadataPropertyFiltersArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Gets Token Directory supported networks + */ + getTokenDirectoryNetworks( + args: GetTokenDirectoryNetworksArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Gets Token Directory entries + */ + getTokenDirectory( + args: GetTokenDirectoryArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Search in Token Directory + */ + searchTokenDirectory( + args: SearchTokenDirectoryArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Niftyswap querying data + */ + getNiftyswapTokenQuantity( + args: GetNiftyswapTokenQuantityArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * map of tokenID :: quantity + */ + getNiftyswapUnitPrices( + args: GetNiftyswapUnitPricesArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * map of tokenID :: price + */ + getNiftyswapUnitPricesWithQuantities( + args: GetNiftyswapUnitPricesWithQuantitiesArgs, + headers?: object, + signal?: AbortSignal, + ): Promise +} + export interface PingArgs {} export interface PingReturn { status: boolean } - export interface VersionArgs {} export interface VersionReturn { version: Version } - export interface RuntimeStatusArgs {} export interface RuntimeStatusReturn { status: RuntimeStatus } - export interface GetTaskArgs { taskId: number } @@ -675,7 +544,6 @@ export interface GetTaskArgs { export interface GetTaskReturn { task: Task } - export interface GetTaskStatusArgs { taskId: number } @@ -683,7 +551,6 @@ export interface GetTaskStatusArgs { export interface GetTaskStatusReturn { status?: TaskStatus } - export interface GetContractInfoArgs { chainID: string contractAddress: string @@ -693,7 +560,6 @@ export interface GetContractInfoReturn { contractInfo: ContractInfo taskID?: number } - export interface GetContractInfoBatchArgs { chainID: string contractAddresses: Array @@ -703,7 +569,6 @@ export interface GetContractInfoBatchReturn { contractInfoMap: { [key: string]: ContractInfo } taskID?: number } - export interface FindContractInfoArgs { contractAddress: string } @@ -711,7 +576,6 @@ export interface FindContractInfoArgs { export interface FindContractInfoReturn { contractInfoList: Array } - export interface FindContractInfoBatchArgs { contractAddresses: Array } @@ -719,7 +583,6 @@ export interface FindContractInfoBatchArgs { export interface FindContractInfoBatchReturn { contractInfoByChain: { [key: string]: Array } } - export interface RefreshContractInfoArgs { chainID: string contractAddress: string @@ -728,7 +591,6 @@ export interface RefreshContractInfoArgs { export interface RefreshContractInfoReturn { taskID?: number } - export interface RefreshContractInfoBatchArgs { chainID: string contractAddresses: Array @@ -737,7 +599,6 @@ export interface RefreshContractInfoBatchArgs { export interface RefreshContractInfoBatchReturn { taskID?: number } - export interface SearchContractsByQueryArgs { q: string chainID?: string @@ -750,7 +611,6 @@ export interface SearchContractsByQueryReturn { contractInfo: Array nextPage: Page } - export interface GetTokenMetadataArgs { chainID: string contractAddress: string @@ -761,7 +621,6 @@ export interface GetTokenMetadataReturn { tokenMetadata: Array taskID?: number } - export interface GetTokenMetadataBatchArgs { chainID: string contractTokenMap: { [key: string]: Array } @@ -771,18 +630,16 @@ export interface GetTokenMetadataBatchReturn { contractTokenMetadata: { [key: string]: Array } taskID?: number } - export interface RefreshTokenMetadataArgs { chainID: string contractAddress: string tokenIDs?: Array - newMints?: boolean + refreshAll?: boolean } export interface RefreshTokenMetadataReturn { taskID: number } - export interface SearchTokenMetadataByQueryArgs { q: string chainID?: string @@ -794,7 +651,6 @@ export interface SearchTokenMetadataByQueryReturn { tokenMetadata: Array nextPage: Page } - export interface SearchTokenMetadataArgs { chainID: string contractAddress: string @@ -806,7 +662,6 @@ export interface SearchTokenMetadataReturn { page: Page tokenMetadata: Array } - export interface SearchTokenMetadataTokenIDsArgs { chainID: string contractAddress: string @@ -818,7 +673,6 @@ export interface SearchTokenMetadataTokenIDsReturn { page: Page tokenIDs: Array } - export interface GetTokenMetadataPropertyFiltersArgs { chainID: string contractAddress: string @@ -829,7 +683,6 @@ export interface GetTokenMetadataPropertyFiltersArgs { export interface GetTokenMetadataPropertyFiltersReturn { filters: Array } - export interface GetTokenDirectoryNetworksArgs { includeTestnets?: boolean onlyFeatured?: boolean @@ -839,7 +692,6 @@ export interface GetTokenDirectoryNetworksReturn { chainIDs: Array networks: Array } - export interface GetTokenDirectoryArgs { chainID?: string includeTestnets?: boolean @@ -851,7 +703,6 @@ export interface GetTokenDirectoryReturn { contracts: Array page: Page } - export interface SearchTokenDirectoryArgs { query: string chainID?: number @@ -864,7 +715,6 @@ export interface SearchTokenDirectoryReturn { contracts: Array page: Page } - export interface GetNiftyswapTokenQuantityArgs { chainID: string contractAddress: string @@ -874,7 +724,6 @@ export interface GetNiftyswapTokenQuantityArgs { export interface GetNiftyswapTokenQuantityReturn { quantity: { [key: string]: string } } - export interface GetNiftyswapUnitPricesArgs { chainID: string contractAddress: string @@ -885,7 +734,6 @@ export interface GetNiftyswapUnitPricesArgs { export interface GetNiftyswapUnitPricesReturn { prices: { [key: string]: string } } - export interface GetNiftyswapUnitPricesWithQuantitiesArgs { chainID: string contractAddress: string @@ -897,6 +745,58 @@ export interface GetNiftyswapUnitPricesWithQuantitiesReturn { prices: { [key: string]: GetNiftyswapUnitPricesResponse } } +export interface Collections { + createCollection(args: CreateCollectionArgs, headers?: object, signal?: AbortSignal): Promise + getCollection(args: GetCollectionArgs, headers?: object, signal?: AbortSignal): Promise + listCollections(args: ListCollectionsArgs, headers?: object, signal?: AbortSignal): Promise + updateCollection(args: UpdateCollectionArgs, headers?: object, signal?: AbortSignal): Promise + deleteCollection(args: DeleteCollectionArgs, headers?: object, signal?: AbortSignal): Promise + publishCollection( + args: PublishCollectionArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + unpublishCollection( + args: UnpublishCollectionArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + createContractCollection( + args: CreateContractCollectionArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + getContractCollection( + args: GetContractCollectionArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + listContractCollections( + args: ListContractCollectionsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + updateContractCollection( + args: UpdateContractCollectionArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + deleteContractCollection( + args: DeleteContractCollectionArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + createToken(args: CreateTokenArgs, headers?: object, signal?: AbortSignal): Promise + getToken(args: GetTokenArgs, headers?: object, signal?: AbortSignal): Promise + listTokens(args: ListTokensArgs, headers?: object, signal?: AbortSignal): Promise + updateToken(args: UpdateTokenArgs, headers?: object, signal?: AbortSignal): Promise + deleteToken(args: DeleteTokenArgs, headers?: object, signal?: AbortSignal): Promise + createAsset(args: CreateAssetArgs, headers?: object, signal?: AbortSignal): Promise + getAsset(args: GetAssetArgs, headers?: object, signal?: AbortSignal): Promise + updateAsset(args: UpdateAssetArgs, headers?: object, signal?: AbortSignal): Promise + deleteAsset(args: DeleteAssetArgs, headers?: object, signal?: AbortSignal): Promise +} + export interface CreateCollectionArgs { projectId?: number collection: Collection @@ -905,7 +805,6 @@ export interface CreateCollectionArgs { export interface CreateCollectionReturn { collection: Collection } - export interface GetCollectionArgs { projectId?: number collectionId: number @@ -914,7 +813,6 @@ export interface GetCollectionArgs { export interface GetCollectionReturn { collection: Collection } - export interface ListCollectionsArgs { projectId?: number page?: Page @@ -924,7 +822,6 @@ export interface ListCollectionsReturn { page: Page collections: Array } - export interface UpdateCollectionArgs { projectId?: number collection: Collection @@ -933,7 +830,6 @@ export interface UpdateCollectionArgs { export interface UpdateCollectionReturn { collection: Collection } - export interface DeleteCollectionArgs { projectId?: number collectionId: number @@ -942,7 +838,6 @@ export interface DeleteCollectionArgs { export interface DeleteCollectionReturn { status: boolean } - export interface PublishCollectionArgs { projectId?: number collectionId: number @@ -952,7 +847,6 @@ export interface PublishCollectionArgs { export interface PublishCollectionReturn { collection: Collection } - export interface UnpublishCollectionArgs { projectId?: number collectionId: number @@ -961,7 +855,6 @@ export interface UnpublishCollectionArgs { export interface UnpublishCollectionReturn { collection: Collection } - export interface CreateContractCollectionArgs { projectId: number contractCollection: ContractCollection @@ -970,7 +863,6 @@ export interface CreateContractCollectionArgs { export interface CreateContractCollectionReturn { contractCollection: ContractCollection } - export interface GetContractCollectionArgs { projectId: number chainId: number @@ -980,7 +872,6 @@ export interface GetContractCollectionArgs { export interface GetContractCollectionReturn { contractCollection: ContractCollection } - export interface ListContractCollectionsArgs { projectId: number collectionId?: number @@ -992,7 +883,6 @@ export interface ListContractCollectionsReturn { collections: Array page: Page } - export interface UpdateContractCollectionArgs { projectId: number contractCollection: ContractCollection @@ -1001,7 +891,6 @@ export interface UpdateContractCollectionArgs { export interface UpdateContractCollectionReturn { ok: boolean } - export interface DeleteContractCollectionArgs { projectId: number chainId: number @@ -1011,7 +900,6 @@ export interface DeleteContractCollectionArgs { export interface DeleteContractCollectionReturn { ok: boolean } - export interface CreateTokenArgs { projectId?: number collectionId: number @@ -1023,7 +911,6 @@ export interface CreateTokenReturn { token: TokenMetadata assets: Array } - export interface GetTokenArgs { projectId?: number collectionId: number @@ -1034,7 +921,6 @@ export interface GetTokenReturn { token: TokenMetadata assets: Array } - export interface ListTokensArgs { projectId?: number collectionId: number @@ -1045,7 +931,6 @@ export interface ListTokensReturn { page: Page tokens: Array } - export interface UpdateTokenArgs { projectId?: number collectionId: number @@ -1057,7 +942,6 @@ export interface UpdateTokenArgs { export interface UpdateTokenReturn { token: TokenMetadata } - export interface DeleteTokenArgs { projectId?: number collectionId: number @@ -1067,7 +951,6 @@ export interface DeleteTokenArgs { export interface DeleteTokenReturn { status: boolean } - export interface CreateAssetArgs { projectId?: number asset: Asset @@ -1076,7 +959,6 @@ export interface CreateAssetArgs { export interface CreateAssetReturn { asset: Asset } - export interface GetAssetArgs { projectId?: number assetId: number @@ -1085,7 +967,6 @@ export interface GetAssetArgs { export interface GetAssetReturn { asset: Asset } - export interface UpdateAssetArgs { projectId?: number asset: Asset @@ -1094,7 +975,6 @@ export interface UpdateAssetArgs { export interface UpdateAssetReturn { asset: Asset } - export interface DeleteAssetArgs { projectId?: number assetId: number @@ -1104,6 +984,77 @@ export interface DeleteAssetReturn { status: boolean } +export interface Admin { + /** + * ContractInfo + */ + refreshContractInfoUpdatedBefore( + args: RefreshContractInfoUpdatedBeforeArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * TokenMetadata + */ + refreshTokenMetadataUpdatedBefore( + args: RefreshTokenMetadataUpdatedBeforeArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Contract Info Overrides + */ + getContractInfoOverride( + args: GetContractInfoOverrideArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + getContractInfoOverrides( + args: GetContractInfoOverridesArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + addContractInfoOverride( + args: AddContractInfoOverrideArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + updateContractInfoOverride( + args: UpdateContractInfoOverrideArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + removeContractInfoOverride( + args: RemoveContractInfoOverrideArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Token Directory + */ + isInTokenDirectory( + args: IsInTokenDirectoryArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + setTokenDirectoryFeatureIndex( + args: SetTokenDirectoryFeatureIndexArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + addContractToTokenDirectory( + args: AddContractToTokenDirectoryArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + removeContractFromTokenDirectory( + args: RemoveContractFromTokenDirectoryArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + refreshTokenDirectory(headers?: object, signal?: AbortSignal): Promise +} + export interface RefreshContractInfoUpdatedBeforeArgs { before: string maxContractNumber: number @@ -1112,7 +1063,6 @@ export interface RefreshContractInfoUpdatedBeforeArgs { export interface RefreshContractInfoUpdatedBeforeReturn { taskIDs: Array } - export interface RefreshTokenMetadataUpdatedBeforeArgs { before: string maxTokenNumber: number @@ -1121,7 +1071,6 @@ export interface RefreshTokenMetadataUpdatedBeforeArgs { export interface RefreshTokenMetadataUpdatedBeforeReturn { taskIDs: Array } - export interface GetContractInfoOverrideArgs { chainID: string contractAddress: string @@ -1130,7 +1079,6 @@ export interface GetContractInfoOverrideArgs { export interface GetContractInfoOverrideReturn { contractInfoOverride: ContractInfoOverride } - export interface GetContractInfoOverridesArgs { chainID?: string page?: Page @@ -1140,7 +1088,6 @@ export interface GetContractInfoOverridesReturn { contractInfoOverrides: Array page: Page } - export interface AddContractInfoOverrideArgs { chainID: string contractAddress: string @@ -1150,7 +1097,6 @@ export interface AddContractInfoOverrideArgs { export interface AddContractInfoOverrideReturn { ok: boolean } - export interface UpdateContractInfoOverrideArgs { chainID: string contractAddress: string @@ -1160,7 +1106,6 @@ export interface UpdateContractInfoOverrideArgs { export interface UpdateContractInfoOverrideReturn { ok: boolean } - export interface RemoveContractInfoOverrideArgs { chainID: string contractAddress: string @@ -1169,7 +1114,6 @@ export interface RemoveContractInfoOverrideArgs { export interface RemoveContractInfoOverrideReturn { ok: boolean } - export interface IsInTokenDirectoryArgs { chainID: string contractAddress: string @@ -1179,7 +1123,6 @@ export interface IsInTokenDirectoryReturn { ok: boolean featureIndex: number } - export interface SetTokenDirectoryFeatureIndexArgs { chainID: string contractAddress: string @@ -1189,7 +1132,6 @@ export interface SetTokenDirectoryFeatureIndexArgs { export interface SetTokenDirectoryFeatureIndexReturn { ok: boolean } - export interface AddContractToTokenDirectoryArgs { chainID: string contractAddress: string @@ -1198,7 +1140,6 @@ export interface AddContractToTokenDirectoryArgs { export interface AddContractToTokenDirectoryReturn { ok: boolean } - export interface RemoveContractFromTokenDirectoryArgs { chainID: string contractAddress: string @@ -1207,7 +1148,6 @@ export interface RemoveContractFromTokenDirectoryArgs { export interface RemoveContractFromTokenDirectoryReturn { ok: boolean } - export interface RefreshTokenDirectoryArgs {} export interface RefreshTokenDirectoryReturn { @@ -1217,8 +1157,7 @@ export interface RefreshTokenDirectoryReturn { // // Client // - -export class Metadata implements MetadataClient { +export class Metadata implements Metadata { protected hostname: string protected fetch: Fetch protected path = '/rpc/Metadata/' @@ -1232,563 +1171,473 @@ export class Metadata implements MetadataClient { return this.hostname + this.path + name } - queryKey = { - ping: () => ['Metadata', 'ping'] as const, - version: () => ['Metadata', 'version'] as const, - runtimeStatus: () => ['Metadata', 'runtimeStatus'] as const, - getTask: (req: GetTaskArgs) => ['Metadata', 'getTask', req] as const, - getTaskStatus: (req: GetTaskStatusArgs) => ['Metadata', 'getTaskStatus', req] as const, - getContractInfo: (req: GetContractInfoArgs) => ['Metadata', 'getContractInfo', req] as const, - getContractInfoBatch: (req: GetContractInfoBatchArgs) => ['Metadata', 'getContractInfoBatch', req] as const, - findContractInfo: (req: FindContractInfoArgs) => ['Metadata', 'findContractInfo', req] as const, - findContractInfoBatch: (req: FindContractInfoBatchArgs) => ['Metadata', 'findContractInfoBatch', req] as const, - refreshContractInfo: (req: RefreshContractInfoArgs) => ['Metadata', 'refreshContractInfo', req] as const, - refreshContractInfoBatch: (req: RefreshContractInfoBatchArgs) => - ['Metadata', 'refreshContractInfoBatch', req] as const, - searchContractsByQuery: (req: SearchContractsByQueryArgs) => ['Metadata', 'searchContractsByQuery', req] as const, - getTokenMetadata: (req: GetTokenMetadataArgs) => ['Metadata', 'getTokenMetadata', req] as const, - getTokenMetadataBatch: (req: GetTokenMetadataBatchArgs) => ['Metadata', 'getTokenMetadataBatch', req] as const, - refreshTokenMetadata: (req: RefreshTokenMetadataArgs) => ['Metadata', 'refreshTokenMetadata', req] as const, - searchTokenMetadataByQuery: (req: SearchTokenMetadataByQueryArgs) => - ['Metadata', 'searchTokenMetadataByQuery', req] as const, - searchTokenMetadata: (req: SearchTokenMetadataArgs) => ['Metadata', 'searchTokenMetadata', req] as const, - searchTokenMetadataTokenIDs: (req: SearchTokenMetadataTokenIDsArgs) => - ['Metadata', 'searchTokenMetadataTokenIDs', req] as const, - getTokenMetadataPropertyFilters: (req: GetTokenMetadataPropertyFiltersArgs) => - ['Metadata', 'getTokenMetadataPropertyFilters', req] as const, - getTokenDirectoryNetworks: (req: GetTokenDirectoryNetworksArgs) => - ['Metadata', 'getTokenDirectoryNetworks', req] as const, - getTokenDirectory: (req: GetTokenDirectoryArgs) => ['Metadata', 'getTokenDirectory', req] as const, - searchTokenDirectory: (req: SearchTokenDirectoryArgs) => ['Metadata', 'searchTokenDirectory', req] as const, - getNiftyswapTokenQuantity: (req: GetNiftyswapTokenQuantityArgs) => - ['Metadata', 'getNiftyswapTokenQuantity', req] as const, - getNiftyswapUnitPrices: (req: GetNiftyswapUnitPricesArgs) => ['Metadata', 'getNiftyswapUnitPrices', req] as const, - getNiftyswapUnitPricesWithQuantities: (req: GetNiftyswapUnitPricesWithQuantitiesArgs) => - ['Metadata', 'getNiftyswapUnitPricesWithQuantities', req] as const, - } - ping = (headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('Ping'), createHttpRequest('{}', headers, signal)).then( + return this.fetch(this.url('Ping'), createHTTPRequest({}, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'PingReturn') + return { + status: _data.status, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } version = (headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('Version'), createHttpRequest('{}', headers, signal)).then( + return this.fetch(this.url('Version'), createHTTPRequest({}, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'VersionReturn') + return { + version: _data.version, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } runtimeStatus = (headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('RuntimeStatus'), createHttpRequest('{}', headers, signal)).then( + return this.fetch(this.url('RuntimeStatus'), createHTTPRequest({}, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'RuntimeStatusReturn') + return { + status: _data.status, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } - getTask = (req: GetTaskArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('GetTask'), createHttpRequest(JsonEncode(req, 'GetTaskArgs'), headers, signal)).then( + getTask = (args: GetTaskArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetTask'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetTaskReturn') + return { + task: _data.task, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } - getTaskStatus = (req: GetTaskStatusArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch( - this.url('GetTaskStatus'), - createHttpRequest(JsonEncode(req, 'GetTaskStatusArgs'), headers, signal), - ).then( + getTaskStatus = (args: GetTaskStatusArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetTaskStatus'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetTaskStatusReturn') + return { + status: _data.status, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } getContractInfo = ( - req: GetContractInfoArgs, + args: GetContractInfoArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('GetContractInfo'), - createHttpRequest(JsonEncode(req, 'GetContractInfoArgs'), headers, signal), - ).then( + return this.fetch(this.url('GetContractInfo'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetContractInfoReturn') + return { + contractInfo: _data.contractInfo, + taskID: _data.taskID, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } getContractInfoBatch = ( - req: GetContractInfoBatchArgs, + args: GetContractInfoBatchArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('GetContractInfoBatch'), - createHttpRequest(JsonEncode(req, 'GetContractInfoBatchArgs'), headers, signal), - ).then( + return this.fetch(this.url('GetContractInfoBatch'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetContractInfoBatchReturn') + return { + contractInfoMap: <{ [key: string]: ContractInfo }>_data.contractInfoMap, + taskID: _data.taskID, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } findContractInfo = ( - req: FindContractInfoArgs, + args: FindContractInfoArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('FindContractInfo'), - createHttpRequest(JsonEncode(req, 'FindContractInfoArgs'), headers, signal), - ).then( + return this.fetch(this.url('FindContractInfo'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'FindContractInfoReturn') + return { + contractInfoList: >_data.contractInfoList, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } findContractInfoBatch = ( - req: FindContractInfoBatchArgs, + args: FindContractInfoBatchArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('FindContractInfoBatch'), - createHttpRequest(JsonEncode(req, 'FindContractInfoBatchArgs'), headers, signal), - ).then( + return this.fetch(this.url('FindContractInfoBatch'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'FindContractInfoBatchReturn') + return { + contractInfoByChain: <{ [key: string]: Array }>_data.contractInfoByChain, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } refreshContractInfo = ( - req: RefreshContractInfoArgs, + args: RefreshContractInfoArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('RefreshContractInfo'), - createHttpRequest(JsonEncode(req, 'RefreshContractInfoArgs'), headers, signal), - ).then( + return this.fetch(this.url('RefreshContractInfo'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'RefreshContractInfoReturn') + return { + taskID: _data.taskID, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } refreshContractInfoBatch = ( - req: RefreshContractInfoBatchArgs, + args: RefreshContractInfoBatchArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('RefreshContractInfoBatch'), - createHttpRequest(JsonEncode(req, 'RefreshContractInfoBatchArgs'), headers, signal), - ).then( + return this.fetch(this.url('RefreshContractInfoBatch'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'RefreshContractInfoBatchReturn') + return { + taskID: _data.taskID, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } searchContractsByQuery = ( - req: SearchContractsByQueryArgs, + args: SearchContractsByQueryArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('SearchContractsByQuery'), - createHttpRequest(JsonEncode(req, 'SearchContractsByQueryArgs'), headers, signal), - ).then( + return this.fetch(this.url('SearchContractsByQuery'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'SearchContractsByQueryReturn') + return { + contractInfo: >_data.contractInfo, + nextPage: _data.nextPage, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } getTokenMetadata = ( - req: GetTokenMetadataArgs, + args: GetTokenMetadataArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('GetTokenMetadata'), - createHttpRequest(JsonEncode(req, 'GetTokenMetadataArgs'), headers, signal), - ).then( + return this.fetch(this.url('GetTokenMetadata'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetTokenMetadataReturn') + return { + tokenMetadata: >_data.tokenMetadata, + taskID: _data.taskID, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } getTokenMetadataBatch = ( - req: GetTokenMetadataBatchArgs, + args: GetTokenMetadataBatchArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('GetTokenMetadataBatch'), - createHttpRequest(JsonEncode(req, 'GetTokenMetadataBatchArgs'), headers, signal), - ).then( + return this.fetch(this.url('GetTokenMetadataBatch'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetTokenMetadataBatchReturn') + return { + contractTokenMetadata: <{ [key: string]: Array }>_data.contractTokenMetadata, + taskID: _data.taskID, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } refreshTokenMetadata = ( - req: RefreshTokenMetadataArgs, + args: RefreshTokenMetadataArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('RefreshTokenMetadata'), - createHttpRequest(JsonEncode(req, 'RefreshTokenMetadataArgs'), headers, signal), - ).then( + return this.fetch(this.url('RefreshTokenMetadata'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'RefreshTokenMetadataReturn') + return { + taskID: _data.taskID, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } searchTokenMetadataByQuery = ( - req: SearchTokenMetadataByQueryArgs, + args: SearchTokenMetadataByQueryArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('SearchTokenMetadataByQuery'), - createHttpRequest(JsonEncode(req, 'SearchTokenMetadataByQueryArgs'), headers, signal), - ).then( + return this.fetch(this.url('SearchTokenMetadataByQuery'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'SearchTokenMetadataByQueryReturn') + return { + tokenMetadata: >_data.tokenMetadata, + nextPage: _data.nextPage, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } searchTokenMetadata = ( - req: SearchTokenMetadataArgs, + args: SearchTokenMetadataArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('SearchTokenMetadata'), - createHttpRequest(JsonEncode(req, 'SearchTokenMetadataArgs'), headers, signal), - ).then( + return this.fetch(this.url('SearchTokenMetadata'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'SearchTokenMetadataReturn') + return { + page: _data.page, + tokenMetadata: >_data.tokenMetadata, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } searchTokenMetadataTokenIDs = ( - req: SearchTokenMetadataTokenIDsArgs, + args: SearchTokenMetadataTokenIDsArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('SearchTokenMetadataTokenIDs'), - createHttpRequest(JsonEncode(req, 'SearchTokenMetadataTokenIDsArgs'), headers, signal), - ).then( + return this.fetch(this.url('SearchTokenMetadataTokenIDs'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'SearchTokenMetadataTokenIDsReturn') + return { + page: _data.page, + tokenIDs: >_data.tokenIDs, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } getTokenMetadataPropertyFilters = ( - req: GetTokenMetadataPropertyFiltersArgs, + args: GetTokenMetadataPropertyFiltersArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('GetTokenMetadataPropertyFilters'), - createHttpRequest(JsonEncode(req, 'GetTokenMetadataPropertyFiltersArgs'), headers, signal), - ).then( + return this.fetch(this.url('GetTokenMetadataPropertyFilters'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetTokenMetadataPropertyFiltersReturn') + return { + filters: >_data.filters, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } getTokenDirectoryNetworks = ( - req: GetTokenDirectoryNetworksArgs, + args: GetTokenDirectoryNetworksArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('GetTokenDirectoryNetworks'), - createHttpRequest(JsonEncode(req, 'GetTokenDirectoryNetworksArgs'), headers, signal), - ).then( + return this.fetch(this.url('GetTokenDirectoryNetworks'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetTokenDirectoryNetworksReturn') + return { + chainIDs: >_data.chainIDs, + networks: >_data.networks, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } getTokenDirectory = ( - req: GetTokenDirectoryArgs, + args: GetTokenDirectoryArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('GetTokenDirectory'), - createHttpRequest(JsonEncode(req, 'GetTokenDirectoryArgs'), headers, signal), - ).then( + return this.fetch(this.url('GetTokenDirectory'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetTokenDirectoryReturn') + return { + contracts: >_data.contracts, + page: _data.page, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } searchTokenDirectory = ( - req: SearchTokenDirectoryArgs, + args: SearchTokenDirectoryArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('SearchTokenDirectory'), - createHttpRequest(JsonEncode(req, 'SearchTokenDirectoryArgs'), headers, signal), - ).then( + return this.fetch(this.url('SearchTokenDirectory'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'SearchTokenDirectoryReturn') + return { + contracts: >_data.contracts, + page: _data.page, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } getNiftyswapTokenQuantity = ( - req: GetNiftyswapTokenQuantityArgs, + args: GetNiftyswapTokenQuantityArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('GetNiftyswapTokenQuantity'), - createHttpRequest(JsonEncode(req, 'GetNiftyswapTokenQuantityArgs'), headers, signal), - ).then( + return this.fetch(this.url('GetNiftyswapTokenQuantity'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetNiftyswapTokenQuantityReturn') + return { + quantity: <{ [key: string]: string }>_data.quantity, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } getNiftyswapUnitPrices = ( - req: GetNiftyswapUnitPricesArgs, + args: GetNiftyswapUnitPricesArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('GetNiftyswapUnitPrices'), - createHttpRequest(JsonEncode(req, 'GetNiftyswapUnitPricesArgs'), headers, signal), - ).then( + return this.fetch(this.url('GetNiftyswapUnitPrices'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetNiftyswapUnitPricesReturn') + return { + prices: <{ [key: string]: string }>_data.prices, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } getNiftyswapUnitPricesWithQuantities = ( - req: GetNiftyswapUnitPricesWithQuantitiesArgs, + args: GetNiftyswapUnitPricesWithQuantitiesArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('GetNiftyswapUnitPricesWithQuantities'), - createHttpRequest(JsonEncode(req, 'GetNiftyswapUnitPricesWithQuantitiesArgs'), headers, signal), - ).then( + return this.fetch(this.url('GetNiftyswapUnitPricesWithQuantities'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode( - _data, - 'GetNiftyswapUnitPricesWithQuantitiesReturn', - ) + return { + prices: <{ [key: string]: GetNiftyswapUnitPricesResponse }>_data.prices, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } } -export class Collections implements CollectionsClient { +export class Collections implements Collections { protected hostname: string protected fetch: Fetch protected path = '/rpc/Collections/' @@ -1802,451 +1651,372 @@ export class Collections implements CollectionsClient { return this.hostname + this.path + name } - queryKey = { - createCollection: (req: CreateCollectionArgs) => ['Collections', 'createCollection', req] as const, - getCollection: (req: GetCollectionArgs) => ['Collections', 'getCollection', req] as const, - listCollections: (req: ListCollectionsArgs) => ['Collections', 'listCollections', req] as const, - updateCollection: (req: UpdateCollectionArgs) => ['Collections', 'updateCollection', req] as const, - deleteCollection: (req: DeleteCollectionArgs) => ['Collections', 'deleteCollection', req] as const, - publishCollection: (req: PublishCollectionArgs) => ['Collections', 'publishCollection', req] as const, - unpublishCollection: (req: UnpublishCollectionArgs) => ['Collections', 'unpublishCollection', req] as const, - createContractCollection: (req: CreateContractCollectionArgs) => - ['Collections', 'createContractCollection', req] as const, - getContractCollection: (req: GetContractCollectionArgs) => ['Collections', 'getContractCollection', req] as const, - listContractCollections: (req: ListContractCollectionsArgs) => - ['Collections', 'listContractCollections', req] as const, - updateContractCollection: (req: UpdateContractCollectionArgs) => - ['Collections', 'updateContractCollection', req] as const, - deleteContractCollection: (req: DeleteContractCollectionArgs) => - ['Collections', 'deleteContractCollection', req] as const, - createToken: (req: CreateTokenArgs) => ['Collections', 'createToken', req] as const, - getToken: (req: GetTokenArgs) => ['Collections', 'getToken', req] as const, - listTokens: (req: ListTokensArgs) => ['Collections', 'listTokens', req] as const, - updateToken: (req: UpdateTokenArgs) => ['Collections', 'updateToken', req] as const, - deleteToken: (req: DeleteTokenArgs) => ['Collections', 'deleteToken', req] as const, - createAsset: (req: CreateAssetArgs) => ['Collections', 'createAsset', req] as const, - getAsset: (req: GetAssetArgs) => ['Collections', 'getAsset', req] as const, - updateAsset: (req: UpdateAssetArgs) => ['Collections', 'updateAsset', req] as const, - deleteAsset: (req: DeleteAssetArgs) => ['Collections', 'deleteAsset', req] as const, - } - createCollection = ( - req: CreateCollectionArgs, + args: CreateCollectionArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('CreateCollection'), - createHttpRequest(JsonEncode(req, 'CreateCollectionArgs'), headers, signal), - ).then( + return this.fetch(this.url('CreateCollection'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'CreateCollectionReturn') + return { + collection: _data.collection, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } - getCollection = (req: GetCollectionArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch( - this.url('GetCollection'), - createHttpRequest(JsonEncode(req, 'GetCollectionArgs'), headers, signal), - ).then( + getCollection = (args: GetCollectionArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetCollection'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetCollectionReturn') + return { + collection: _data.collection, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } listCollections = ( - req: ListCollectionsArgs, + args: ListCollectionsArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('ListCollections'), - createHttpRequest(JsonEncode(req, 'ListCollectionsArgs'), headers, signal), - ).then( + return this.fetch(this.url('ListCollections'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'ListCollectionsReturn') + return { + page: _data.page, + collections: >_data.collections, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } updateCollection = ( - req: UpdateCollectionArgs, + args: UpdateCollectionArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('UpdateCollection'), - createHttpRequest(JsonEncode(req, 'UpdateCollectionArgs'), headers, signal), - ).then( + return this.fetch(this.url('UpdateCollection'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'UpdateCollectionReturn') + return { + collection: _data.collection, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } deleteCollection = ( - req: DeleteCollectionArgs, + args: DeleteCollectionArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('DeleteCollection'), - createHttpRequest(JsonEncode(req, 'DeleteCollectionArgs'), headers, signal), - ).then( + return this.fetch(this.url('DeleteCollection'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'DeleteCollectionReturn') + return { + status: _data.status, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } publishCollection = ( - req: PublishCollectionArgs, + args: PublishCollectionArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('PublishCollection'), - createHttpRequest(JsonEncode(req, 'PublishCollectionArgs'), headers, signal), - ).then( + return this.fetch(this.url('PublishCollection'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'PublishCollectionReturn') + return { + collection: _data.collection, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } unpublishCollection = ( - req: UnpublishCollectionArgs, + args: UnpublishCollectionArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('UnpublishCollection'), - createHttpRequest(JsonEncode(req, 'UnpublishCollectionArgs'), headers, signal), - ).then( + return this.fetch(this.url('UnpublishCollection'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'UnpublishCollectionReturn') + return { + collection: _data.collection, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } createContractCollection = ( - req: CreateContractCollectionArgs, + args: CreateContractCollectionArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('CreateContractCollection'), - createHttpRequest(JsonEncode(req, 'CreateContractCollectionArgs'), headers, signal), - ).then( + return this.fetch(this.url('CreateContractCollection'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'CreateContractCollectionReturn') + return { + contractCollection: _data.contractCollection, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } getContractCollection = ( - req: GetContractCollectionArgs, + args: GetContractCollectionArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('GetContractCollection'), - createHttpRequest(JsonEncode(req, 'GetContractCollectionArgs'), headers, signal), - ).then( + return this.fetch(this.url('GetContractCollection'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetContractCollectionReturn') + return { + contractCollection: _data.contractCollection, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } listContractCollections = ( - req: ListContractCollectionsArgs, + args: ListContractCollectionsArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('ListContractCollections'), - createHttpRequest(JsonEncode(req, 'ListContractCollectionsArgs'), headers, signal), - ).then( + return this.fetch(this.url('ListContractCollections'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'ListContractCollectionsReturn') + return { + contractCollections: >_data.contractCollections, + collections: >_data.collections, + page: _data.page, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } updateContractCollection = ( - req: UpdateContractCollectionArgs, + args: UpdateContractCollectionArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('UpdateContractCollection'), - createHttpRequest(JsonEncode(req, 'UpdateContractCollectionArgs'), headers, signal), - ).then( + return this.fetch(this.url('UpdateContractCollection'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'UpdateContractCollectionReturn') + return { + ok: _data.ok, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } deleteContractCollection = ( - req: DeleteContractCollectionArgs, + args: DeleteContractCollectionArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('DeleteContractCollection'), - createHttpRequest(JsonEncode(req, 'DeleteContractCollectionArgs'), headers, signal), - ).then( + return this.fetch(this.url('DeleteContractCollection'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'DeleteContractCollectionReturn') + return { + ok: _data.ok, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } - createToken = (req: CreateTokenArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch( - this.url('CreateToken'), - createHttpRequest(JsonEncode(req, 'CreateTokenArgs'), headers, signal), - ).then( + createToken = (args: CreateTokenArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('CreateToken'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'CreateTokenReturn') + return { + token: _data.token, + assets: >_data.assets, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } - getToken = (req: GetTokenArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('GetToken'), createHttpRequest(JsonEncode(req, 'GetTokenArgs'), headers, signal)).then( + getToken = (args: GetTokenArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetToken'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetTokenReturn') + return { + token: _data.token, + assets: >_data.assets, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } - listTokens = (req: ListTokensArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch( - this.url('ListTokens'), - createHttpRequest(JsonEncode(req, 'ListTokensArgs'), headers, signal), - ).then( + listTokens = (args: ListTokensArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('ListTokens'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'ListTokensReturn') + return { + page: _data.page, + tokens: >_data.tokens, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } - updateToken = (req: UpdateTokenArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch( - this.url('UpdateToken'), - createHttpRequest(JsonEncode(req, 'UpdateTokenArgs'), headers, signal), - ).then( + updateToken = (args: UpdateTokenArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('UpdateToken'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'UpdateTokenReturn') + return { + token: _data.token, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } - deleteToken = (req: DeleteTokenArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch( - this.url('DeleteToken'), - createHttpRequest(JsonEncode(req, 'DeleteTokenArgs'), headers, signal), - ).then( + deleteToken = (args: DeleteTokenArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('DeleteToken'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'DeleteTokenReturn') + return { + status: _data.status, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } - createAsset = (req: CreateAssetArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch( - this.url('CreateAsset'), - createHttpRequest(JsonEncode(req, 'CreateAssetArgs'), headers, signal), - ).then( + createAsset = (args: CreateAssetArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('CreateAsset'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'CreateAssetReturn') + return { + asset: _data.asset, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } - getAsset = (req: GetAssetArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('GetAsset'), createHttpRequest(JsonEncode(req, 'GetAssetArgs'), headers, signal)).then( + getAsset = (args: GetAssetArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetAsset'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetAssetReturn') + return { + asset: _data.asset, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } - updateAsset = (req: UpdateAssetArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch( - this.url('UpdateAsset'), - createHttpRequest(JsonEncode(req, 'UpdateAssetArgs'), headers, signal), - ).then( + updateAsset = (args: UpdateAssetArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('UpdateAsset'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'UpdateAssetReturn') + return { + asset: _data.asset, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } - deleteAsset = (req: DeleteAssetArgs, headers?: object, signal?: AbortSignal): Promise => { - return this.fetch( - this.url('DeleteAsset'), - createHttpRequest(JsonEncode(req, 'DeleteAssetArgs'), headers, signal), - ).then( + deleteAsset = (args: DeleteAssetArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('DeleteAsset'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'DeleteAssetReturn') + return { + status: _data.status, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } } -export class Admin implements AdminClient { +export class Admin implements Admin { protected hostname: string protected fetch: Fetch protected path = '/rpc/Admin/' @@ -2260,294 +2030,243 @@ export class Admin implements AdminClient { return this.hostname + this.path + name } - queryKey = { - refreshContractInfoUpdatedBefore: (req: RefreshContractInfoUpdatedBeforeArgs) => - ['Admin', 'refreshContractInfoUpdatedBefore', req] as const, - refreshTokenMetadataUpdatedBefore: (req: RefreshTokenMetadataUpdatedBeforeArgs) => - ['Admin', 'refreshTokenMetadataUpdatedBefore', req] as const, - getContractInfoOverride: (req: GetContractInfoOverrideArgs) => ['Admin', 'getContractInfoOverride', req] as const, - getContractInfoOverrides: (req: GetContractInfoOverridesArgs) => - ['Admin', 'getContractInfoOverrides', req] as const, - addContractInfoOverride: (req: AddContractInfoOverrideArgs) => ['Admin', 'addContractInfoOverride', req] as const, - updateContractInfoOverride: (req: UpdateContractInfoOverrideArgs) => - ['Admin', 'updateContractInfoOverride', req] as const, - removeContractInfoOverride: (req: RemoveContractInfoOverrideArgs) => - ['Admin', 'removeContractInfoOverride', req] as const, - isInTokenDirectory: (req: IsInTokenDirectoryArgs) => ['Admin', 'isInTokenDirectory', req] as const, - setTokenDirectoryFeatureIndex: (req: SetTokenDirectoryFeatureIndexArgs) => - ['Admin', 'setTokenDirectoryFeatureIndex', req] as const, - addContractToTokenDirectory: (req: AddContractToTokenDirectoryArgs) => - ['Admin', 'addContractToTokenDirectory', req] as const, - removeContractFromTokenDirectory: (req: RemoveContractFromTokenDirectoryArgs) => - ['Admin', 'removeContractFromTokenDirectory', req] as const, - refreshTokenDirectory: () => ['Admin', 'refreshTokenDirectory'] as const, - } - refreshContractInfoUpdatedBefore = ( - req: RefreshContractInfoUpdatedBeforeArgs, + args: RefreshContractInfoUpdatedBeforeArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('RefreshContractInfoUpdatedBefore'), - createHttpRequest(JsonEncode(req, 'RefreshContractInfoUpdatedBeforeArgs'), headers, signal), - ).then( + return this.fetch(this.url('RefreshContractInfoUpdatedBefore'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'RefreshContractInfoUpdatedBeforeReturn') + return { + taskIDs: >_data.taskIDs, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } refreshTokenMetadataUpdatedBefore = ( - req: RefreshTokenMetadataUpdatedBeforeArgs, + args: RefreshTokenMetadataUpdatedBeforeArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('RefreshTokenMetadataUpdatedBefore'), - createHttpRequest(JsonEncode(req, 'RefreshTokenMetadataUpdatedBeforeArgs'), headers, signal), - ).then( + return this.fetch(this.url('RefreshTokenMetadataUpdatedBefore'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'RefreshTokenMetadataUpdatedBeforeReturn') + return { + taskIDs: >_data.taskIDs, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } getContractInfoOverride = ( - req: GetContractInfoOverrideArgs, + args: GetContractInfoOverrideArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('GetContractInfoOverride'), - createHttpRequest(JsonEncode(req, 'GetContractInfoOverrideArgs'), headers, signal), - ).then( + return this.fetch(this.url('GetContractInfoOverride'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetContractInfoOverrideReturn') + return { + contractInfoOverride: _data.contractInfoOverride, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } getContractInfoOverrides = ( - req: GetContractInfoOverridesArgs, + args: GetContractInfoOverridesArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('GetContractInfoOverrides'), - createHttpRequest(JsonEncode(req, 'GetContractInfoOverridesArgs'), headers, signal), - ).then( + return this.fetch(this.url('GetContractInfoOverrides'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'GetContractInfoOverridesReturn') + return { + contractInfoOverrides: >_data.contractInfoOverrides, + page: _data.page, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } addContractInfoOverride = ( - req: AddContractInfoOverrideArgs, + args: AddContractInfoOverrideArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('AddContractInfoOverride'), - createHttpRequest(JsonEncode(req, 'AddContractInfoOverrideArgs'), headers, signal), - ).then( + return this.fetch(this.url('AddContractInfoOverride'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'AddContractInfoOverrideReturn') + return { + ok: _data.ok, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } updateContractInfoOverride = ( - req: UpdateContractInfoOverrideArgs, + args: UpdateContractInfoOverrideArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('UpdateContractInfoOverride'), - createHttpRequest(JsonEncode(req, 'UpdateContractInfoOverrideArgs'), headers, signal), - ).then( + return this.fetch(this.url('UpdateContractInfoOverride'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'UpdateContractInfoOverrideReturn') + return { + ok: _data.ok, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } removeContractInfoOverride = ( - req: RemoveContractInfoOverrideArgs, + args: RemoveContractInfoOverrideArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('RemoveContractInfoOverride'), - createHttpRequest(JsonEncode(req, 'RemoveContractInfoOverrideArgs'), headers, signal), - ).then( + return this.fetch(this.url('RemoveContractInfoOverride'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'RemoveContractInfoOverrideReturn') + return { + ok: _data.ok, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } isInTokenDirectory = ( - req: IsInTokenDirectoryArgs, + args: IsInTokenDirectoryArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('IsInTokenDirectory'), - createHttpRequest(JsonEncode(req, 'IsInTokenDirectoryArgs'), headers, signal), - ).then( + return this.fetch(this.url('IsInTokenDirectory'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'IsInTokenDirectoryReturn') + return { + ok: _data.ok, + featureIndex: _data.featureIndex, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } setTokenDirectoryFeatureIndex = ( - req: SetTokenDirectoryFeatureIndexArgs, + args: SetTokenDirectoryFeatureIndexArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('SetTokenDirectoryFeatureIndex'), - createHttpRequest(JsonEncode(req, 'SetTokenDirectoryFeatureIndexArgs'), headers, signal), - ).then( + return this.fetch(this.url('SetTokenDirectoryFeatureIndex'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'SetTokenDirectoryFeatureIndexReturn') + return { + ok: _data.ok, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } addContractToTokenDirectory = ( - req: AddContractToTokenDirectoryArgs, + args: AddContractToTokenDirectoryArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('AddContractToTokenDirectory'), - createHttpRequest(JsonEncode(req, 'AddContractToTokenDirectoryArgs'), headers, signal), - ).then( + return this.fetch(this.url('AddContractToTokenDirectory'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'AddContractToTokenDirectoryReturn') + return { + ok: _data.ok, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } removeContractFromTokenDirectory = ( - req: RemoveContractFromTokenDirectoryArgs, + args: RemoveContractFromTokenDirectoryArgs, headers?: object, signal?: AbortSignal, ): Promise => { - return this.fetch( - this.url('RemoveContractFromTokenDirectory'), - createHttpRequest(JsonEncode(req, 'RemoveContractFromTokenDirectoryArgs'), headers, signal), - ).then( + return this.fetch(this.url('RemoveContractFromTokenDirectory'), createHTTPRequest(args, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'RemoveContractFromTokenDirectoryReturn') + return { + ok: _data.ok, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } refreshTokenDirectory = (headers?: object, signal?: AbortSignal): Promise => { - return this.fetch(this.url('RefreshTokenDirectory'), createHttpRequest('{}', headers, signal)).then( + return this.fetch(this.url('RefreshTokenDirectory'), createHTTPRequest({}, headers, signal)).then( (res) => { return buildResponse(res).then((_data) => { - return JsonDecode(_data, 'RefreshTokenDirectoryReturn') + return { + taskID: _data.taskID, + } }) }, (error) => { - throw WebrpcRequestFailedError.new({ - cause: `fetch(): ${error instanceof Error ? error.message : String(error)}`, - }) + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) }, ) } } -const createHttpRequest = (body: string = '{}', headers: object = {}, signal: AbortSignal | null = null): object => { - const reqHeaders: { [key: string]: string } = { - ...headers, - 'Content-Type': 'application/json', - [WebrpcHeader]: WebrpcHeaderValue, +const createHTTPRequest = (body: object = {}, headers: object = {}, signal: AbortSignal | null = null): object => { + const reqHeaders: { [key: string]: string } = { ...headers, 'Content-Type': 'application/json' } + reqHeaders[WebrpcHeader] = WebrpcHeaderValue + + return { + method: 'POST', + headers: reqHeaders, + body: JSON.stringify(body || {}), + signal, } - return { method: 'POST', headers: reqHeaders, body, signal } } const buildResponse = (res: Response): Promise => { @@ -2556,9 +2275,13 @@ const buildResponse = (res: Response): Promise => { try { data = JSON.parse(text) } catch (error) { + let message = '' + if (error instanceof Error) { + message = error.message + } throw WebrpcBadResponseError.new({ status: res.status, - cause: `JSON.parse(): ${error instanceof Error ? error.message : String(error)}: response text: ${text}`, + cause: `JSON.parse(): ${message}: response text: ${text}`, }) } if (!res.ok) { @@ -2569,409 +2292,426 @@ const buildResponse = (res: Response): Promise => { }) } -export type Fetch = (input: RequestInfo, init?: RequestInit) => Promise - -export const JsonEncode = (obj: T, _typ: string = ''): string => { - return JSON.stringify(obj) -} - -export const JsonDecode = (data: string | any, _typ: string = ''): T => { - let parsed: any = data - if (typeof data === 'string') { - try { - parsed = JSON.parse(data) - } catch (err) { - throw WebrpcBadResponseError.new({ cause: `JsonDecode: JSON.parse failed: ${(err as Error).message}` }) - } - } - return parsed as T -} - // // Errors // -type WebrpcErrorParams = { name?: string; code?: number; message?: string; status?: number; cause?: string } - export class WebrpcError extends Error { + name: string code: number + message: string status: number - - constructor(error: WebrpcErrorParams = {}) { - super(error.message) - this.name = error.name || 'WebrpcEndpointError' - this.code = typeof error.code === 'number' ? error.code : 0 - this.message = error.message || `endpoint error` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause + cause?: string + + /** @deprecated Use message instead of msg. Deprecated in webrpc v0.11.0. */ + msg: string + + constructor(name: string, code: number, message: string, status: number, cause?: string) { + super(message) + this.name = name || 'WebrpcError' + this.code = typeof code === 'number' ? code : 0 + this.message = message || `endpoint error ${this.code}` + this.msg = this.message + this.status = typeof status === 'number' ? status : 0 + this.cause = cause Object.setPrototypeOf(this, WebrpcError.prototype) } static new(payload: any): WebrpcError { - return new this({ message: payload.message, code: payload.code, status: payload.status, cause: payload.cause }) + return new this(payload.error, payload.code, payload.message || payload.msg, payload.status, payload.cause) } } +// Webrpc errors + export class WebrpcEndpointError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcEndpoint' - this.code = typeof error.code === 'number' ? error.code : 0 - this.message = error.message || `endpoint error` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'WebrpcEndpoint', + code: number = 0, + message: string = `endpoint error`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, WebrpcEndpointError.prototype) } } export class WebrpcRequestFailedError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcRequestFailed' - this.code = typeof error.code === 'number' ? error.code : -1 - this.message = error.message || `request failed` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'WebrpcRequestFailed', + code: number = -1, + message: string = `request failed`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, WebrpcRequestFailedError.prototype) } } export class WebrpcBadRouteError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcBadRoute' - this.code = typeof error.code === 'number' ? error.code : -2 - this.message = error.message || `bad route` - this.status = typeof error.status === 'number' ? error.status : 404 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'WebrpcBadRoute', + code: number = -2, + message: string = `bad route`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, WebrpcBadRouteError.prototype) } } export class WebrpcBadMethodError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcBadMethod' - this.code = typeof error.code === 'number' ? error.code : -3 - this.message = error.message || `bad method` - this.status = typeof error.status === 'number' ? error.status : 405 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'WebrpcBadMethod', + code: number = -3, + message: string = `bad method`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, WebrpcBadMethodError.prototype) } } export class WebrpcBadRequestError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcBadRequest' - this.code = typeof error.code === 'number' ? error.code : -4 - this.message = error.message || `bad request` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'WebrpcBadRequest', + code: number = -4, + message: string = `bad request`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, WebrpcBadRequestError.prototype) } } export class WebrpcBadResponseError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcBadResponse' - this.code = typeof error.code === 'number' ? error.code : -5 - this.message = error.message || `bad response` - this.status = typeof error.status === 'number' ? error.status : 500 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'WebrpcBadResponse', + code: number = -5, + message: string = `bad response`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, WebrpcBadResponseError.prototype) } } export class WebrpcServerPanicError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcServerPanic' - this.code = typeof error.code === 'number' ? error.code : -6 - this.message = error.message || `server panic` - this.status = typeof error.status === 'number' ? error.status : 500 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'WebrpcServerPanic', + code: number = -6, + message: string = `server panic`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, WebrpcServerPanicError.prototype) } } export class WebrpcInternalErrorError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcInternalError' - this.code = typeof error.code === 'number' ? error.code : -7 - this.message = error.message || `internal error` - this.status = typeof error.status === 'number' ? error.status : 500 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'WebrpcInternalError', + code: number = -7, + message: string = `internal error`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, WebrpcInternalErrorError.prototype) } } -export class WebrpcClientAbortedError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcClientAborted' - this.code = typeof error.code === 'number' ? error.code : -8 - this.message = error.message || `request aborted by client` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause - Object.setPrototypeOf(this, WebrpcClientAbortedError.prototype) +export class WebrpcClientDisconnectedError extends WebrpcError { + constructor( + name: string = 'WebrpcClientDisconnected', + code: number = -8, + message: string = `client disconnected`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcClientDisconnectedError.prototype) } } export class WebrpcStreamLostError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcStreamLost' - this.code = typeof error.code === 'number' ? error.code : -9 - this.message = error.message || `stream lost` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'WebrpcStreamLost', + code: number = -9, + message: string = `stream lost`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, WebrpcStreamLostError.prototype) } } export class WebrpcStreamFinishedError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'WebrpcStreamFinished' - this.code = typeof error.code === 'number' ? error.code : -10 - this.message = error.message || `stream finished` - this.status = typeof error.status === 'number' ? error.status : 200 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'WebrpcStreamFinished', + code: number = -10, + message: string = `stream finished`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, WebrpcStreamFinishedError.prototype) } } -// // Schema errors -// export class UnauthorizedError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'Unauthorized' - this.code = typeof error.code === 'number' ? error.code : 1000 - this.message = error.message || `Unauthorized access` - this.status = typeof error.status === 'number' ? error.status : 401 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'Unauthorized', + code: number = 1000, + message: string = `Unauthorized access`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, UnauthorizedError.prototype) } } export class PermissionDeniedError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'PermissionDenied' - this.code = typeof error.code === 'number' ? error.code : 1001 - this.message = error.message || `Permission denied` - this.status = typeof error.status === 'number' ? error.status : 403 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'PermissionDenied', + code: number = 1001, + message: string = `Permission denied`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, PermissionDeniedError.prototype) } } export class SessionExpiredError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'SessionExpired' - this.code = typeof error.code === 'number' ? error.code : 1002 - this.message = error.message || `Session expired` - this.status = typeof error.status === 'number' ? error.status : 403 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'SessionExpired', + code: number = 1002, + message: string = `Session expired`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, SessionExpiredError.prototype) } } export class MethodNotFoundError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'MethodNotFound' - this.code = typeof error.code === 'number' ? error.code : 1003 - this.message = error.message || `Method not found` - this.status = typeof error.status === 'number' ? error.status : 404 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'MethodNotFound', + code: number = 1003, + message: string = `Method not found`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, MethodNotFoundError.prototype) } } export class RequestConflictError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'RequestConflict' - this.code = typeof error.code === 'number' ? error.code : 1004 - this.message = error.message || `Conflict with target resource` - this.status = typeof error.status === 'number' ? error.status : 409 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'RequestConflict', + code: number = 1004, + message: string = `Conflict with target resource`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, RequestConflictError.prototype) } } export class FailError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'Fail' - this.code = typeof error.code === 'number' ? error.code : 1005 - this.message = error.message || `Request Failed` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'Fail', + code: number = 1005, + message: string = `Request Failed`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, FailError.prototype) } } export class GeoblockedError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'Geoblocked' - this.code = typeof error.code === 'number' ? error.code : 1006 - this.message = error.message || `Geoblocked region` - this.status = typeof error.status === 'number' ? error.status : 451 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'Geoblocked', + code: number = 1006, + message: string = `Geoblocked region`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, GeoblockedError.prototype) } } export class TaskFailedError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'TaskFailed' - this.code = typeof error.code === 'number' ? error.code : 1007 - this.message = error.message || `Task failed` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'TaskFailed', + code: number = 1007, + message: string = `Task failed`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, TaskFailedError.prototype) } } export class DeprecatedError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'Deprecated' - this.code = typeof error.code === 'number' ? error.code : 1008 - this.message = error.message || `RPC method is deprecated` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'Deprecated', + code: number = 1008, + message: string = `RPC method is deprecated`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, DeprecatedError.prototype) } } export class TimeoutError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'Timeout' - this.code = typeof error.code === 'number' ? error.code : 2000 - this.message = error.message || `Request timed out` - this.status = typeof error.status === 'number' ? error.status : 408 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'Timeout', + code: number = 2000, + message: string = `Request timed out`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, TimeoutError.prototype) } } export class InvalidArgumentError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'InvalidArgument' - this.code = typeof error.code === 'number' ? error.code : 2001 - this.message = error.message || `Invalid argument` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'InvalidArgument', + code: number = 2001, + message: string = `Invalid argument`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, InvalidArgumentError.prototype) } } export class RequiredArgumentError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'RequiredArgument' - this.code = typeof error.code === 'number' ? error.code : 2002 - this.message = error.message || `Required argument missing` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'RequiredArgument', + code: number = 2002, + message: string = `Required argument missing`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, RequiredArgumentError.prototype) } } export class QueryFailedError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'QueryFailed' - this.code = typeof error.code === 'number' ? error.code : 2003 - this.message = error.message || `Query failed` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'QueryFailed', + code: number = 2003, + message: string = `Query failed`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, QueryFailedError.prototype) } } export class ValidationFailedError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'ValidationFailed' - this.code = typeof error.code === 'number' ? error.code : 2004 - this.message = error.message || `Validation failed` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'ValidationFailed', + code: number = 2004, + message: string = `Validation failed`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, ValidationFailedError.prototype) } } export class RateLimitedError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'RateLimited' - this.code = typeof error.code === 'number' ? error.code : 2005 - this.message = error.message || `Rate limited` - this.status = typeof error.status === 'number' ? error.status : 429 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'RateLimited', + code: number = 2005, + message: string = `Rate limited`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, RateLimitedError.prototype) } } export class NotFoundError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'NotFound' - this.code = typeof error.code === 'number' ? error.code : 3000 - this.message = error.message || `Resource not found` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'NotFound', + code: number = 3000, + message: string = `Resource not found`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, NotFoundError.prototype) } } export class ProjectNotFoundError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'ProjectNotFound' - this.code = typeof error.code === 'number' ? error.code : 3002 - this.message = error.message || `Project not found` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'ProjectNotFound', + code: number = 3002, + message: string = `Project not found`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, ProjectNotFoundError.prototype) } } export class ChainNotFoundError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'ChainNotFound' - this.code = typeof error.code === 'number' ? error.code : 3003 - this.message = error.message || `Chain not found` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'ChainNotFound', + code: number = 3003, + message: string = `Chain not found`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, ChainNotFoundError.prototype) } } export class TokenDirectoryDisabledError extends WebrpcError { - constructor(error: WebrpcErrorParams = {}) { - super(error) - this.name = error.name || 'TokenDirectoryDisabled' - this.code = typeof error.code === 'number' ? error.code : 4001 - this.message = error.message || `Token Directory is disabled` - this.status = typeof error.status === 'number' ? error.status : 400 - if (error.cause !== undefined) this.cause = error.cause + constructor( + name: string = 'TokenDirectoryDisabled', + code: number = 4001, + message: string = `Token Directory is disabled`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) Object.setPrototypeOf(this, TokenDirectoryDisabledError.prototype) } } @@ -2985,7 +2725,7 @@ export enum errors { WebrpcBadResponse = 'WebrpcBadResponse', WebrpcServerPanic = 'WebrpcServerPanic', WebrpcInternalError = 'WebrpcInternalError', - WebrpcClientAborted = 'WebrpcClientAborted', + WebrpcClientDisconnected = 'WebrpcClientDisconnected', WebrpcStreamLost = 'WebrpcStreamLost', WebrpcStreamFinished = 'WebrpcStreamFinished', Unauthorized = 'Unauthorized', @@ -3018,7 +2758,7 @@ export enum WebrpcErrorCodes { WebrpcBadResponse = -5, WebrpcServerPanic = -6, WebrpcInternalError = -7, - WebrpcClientAborted = -8, + WebrpcClientDisconnected = -8, WebrpcStreamLost = -9, WebrpcStreamFinished = -10, Unauthorized = 1000, @@ -3051,7 +2791,7 @@ export const webrpcErrorByCode: { [code: number]: any } = { [-5]: WebrpcBadResponseError, [-6]: WebrpcServerPanicError, [-7]: WebrpcInternalErrorError, - [-8]: WebrpcClientAbortedError, + [-8]: WebrpcClientDisconnectedError, [-9]: WebrpcStreamLostError, [-10]: WebrpcStreamFinishedError, [1000]: UnauthorizedError, @@ -3075,58 +2815,4 @@ export const webrpcErrorByCode: { [code: number]: any } = { [4001]: TokenDirectoryDisabledError, } -// -// Webrpc -// - -export const WebrpcHeader = 'Webrpc' - -export const WebrpcHeaderValue = 'webrpc@v0.31.0;gen-typescript@v0.22.5;sequence-metadata@v0.4.0' - -type WebrpcGenVersions = { - WebrpcGenVersion: string - codeGenName: string - codeGenVersion: string - schemaName: string - schemaVersion: string -} - -export function VersionFromHeader(headers: Headers): WebrpcGenVersions { - const headerValue = headers.get(WebrpcHeader) - if (!headerValue) { - return { - WebrpcGenVersion: '', - codeGenName: '', - codeGenVersion: '', - schemaName: '', - schemaVersion: '', - } - } - - return parseWebrpcGenVersions(headerValue) -} - -function parseWebrpcGenVersions(header: string): WebrpcGenVersions { - const versions = header.split(';') - if (versions.length < 3) { - return { - WebrpcGenVersion: '', - codeGenName: '', - codeGenVersion: '', - schemaName: '', - schemaVersion: '', - } - } - - const [_, WebrpcGenVersion] = versions[0]!.split('@') - const [codeGenName, codeGenVersion] = versions[1]!.split('@') - const [schemaName, schemaVersion] = versions[2]!.split('@') - - return { - WebrpcGenVersion: WebrpcGenVersion ?? '', - codeGenName: codeGenName ?? '', - codeGenVersion: codeGenVersion ?? '', - schemaName: schemaName ?? '', - schemaVersion: schemaVersion ?? '', - } -} +export type Fetch = (input: RequestInfo, init?: RequestInit) => Promise diff --git a/packages/services/relayer/CHANGELOG.md b/packages/services/relayer/CHANGELOG.md index 5e5312a893..507428d5bb 100644 --- a/packages/services/relayer/CHANGELOG.md +++ b/packages/services/relayer/CHANGELOG.md @@ -1,5 +1,13 @@ # @0xsequence/relayer +## 3.0.10 + +### Patch Changes + +- Minor network updates, relayer interface +- Updated dependencies + - @0xsequence/wallet-primitives@3.0.10 + ## 3.0.9 ### Patch Changes diff --git a/packages/services/relayer/hardhat.config.js b/packages/services/relayer/hardhat.config.js new file mode 100644 index 0000000000..fd760378b1 --- /dev/null +++ b/packages/services/relayer/hardhat.config.js @@ -0,0 +1,15 @@ +/** + * @type import('hardhat/config').HardhatUserConfig + */ +module.exports = { + solidity: '0.7.6', + + networks: { + hardhat: { + chainId: 31337, + accounts: { + mnemonic: 'ripple axis someone ridge uniform wrist prosper there frog rate olympic knee', + }, + }, + }, +} diff --git a/packages/services/relayer/package.json b/packages/services/relayer/package.json index 1ba9e2c527..ec2a8dcd9b 100644 --- a/packages/services/relayer/package.json +++ b/packages/services/relayer/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/relayer", - "version": "3.0.9", + "version": "3.0.10", "type": "module", "publishConfig": { "access": "public" diff --git a/packages/services/relayer/src/index.ts b/packages/services/relayer/src/index.ts index dc28bfc771..4859839b55 100644 --- a/packages/services/relayer/src/index.ts +++ b/packages/services/relayer/src/index.ts @@ -1,3 +1 @@ -export * as Relayer from './relayer/index.js' -export * as RpcRelayerGen from './relayer/rpc-relayer/relayer.gen.js' -export * as Preconditions from './preconditions/index.js' +export * from './rpc-relayer/index.js' diff --git a/packages/services/relayer/src/local-relayer.ts b/packages/services/relayer/src/local-relayer.ts new file mode 100644 index 0000000000..29850be344 --- /dev/null +++ b/packages/services/relayer/src/local-relayer.ts @@ -0,0 +1,125 @@ +// import { ethers } from 'ethers' +// import { logger } from '@0xsequence/utils' +// import { FeeOption, FeeQuote, proto, Relayer } from '.' +// import { ProviderRelayer, ProviderRelayerOptions } from './provider-relayer' +// import { commons } from '@0xsequence/core' + +// export type LocalRelayerOptions = Omit & { +// signer: ethers.Signer +// } + +// export function isLocalRelayerOptions(obj: any): obj is LocalRelayerOptions { +// return typeof obj === 'object' && isAbstractSigner(obj.signer) +// } + +// export class LocalRelayer extends ProviderRelayer implements Relayer { +// private signer: ethers.Signer +// private txnOptions: ethers.TransactionRequest + +// constructor(options: LocalRelayerOptions | ethers.AbstractSigner) { +// super(isAbstractSigner(options) ? { provider: options.provider! } : { ...options, provider: options.signer.provider! }) +// this.signer = isAbstractSigner(options) ? options : options.signer +// if (!this.signer.provider) throw new Error('Signer must have a provider') +// } + +// async getFeeOptions(_address: string, ..._transactions: commons.transaction.Transaction[]): Promise<{ options: FeeOption[] }> { +// return { options: [] } +// } + +// async getFeeOptionsRaw( +// _entrypoint: string, +// _data: ethers.BytesLike, +// _options?: { +// simulate?: boolean +// } +// ): Promise<{ options: FeeOption[] }> { +// return { options: [] } +// } + +// async gasRefundOptions(address: string, ...transactions: commons.transaction.Transaction[]): Promise { +// const { options } = await this.getFeeOptions(address, ...transactions) +// return options +// } + +// setTransactionOptions(transactionRequest: ethers.TransactionRequest) { +// this.txnOptions = transactionRequest +// } + +// async relay( +// signedTxs: commons.transaction.IntendedTransactionBundle, +// quote?: FeeQuote, +// waitForReceipt: boolean = true +// ): Promise> { +// if (quote !== undefined) { +// logger.warn(`LocalRelayer doesn't accept fee quotes`) +// } + +// const data = commons.transaction.encodeBundleExecData(signedTxs) + +// // TODO: think about computing gas limit individually, summing together and passing across +// // NOTE: we expect that all txns have set their gasLimit ahead of time through proper estimation +// // const gasLimit = signedTxs.transactions.reduce((sum, tx) => sum + tx.gasLimit, 0n) +// // txRequest.gasLimit = gasLimit + +// const responsePromise = this.signer.sendTransaction({ +// to: signedTxs.entrypoint, +// data, +// ...this.txnOptions, +// gasLimit: 9000000 +// }) + +// if (waitForReceipt) { +// const response: commons.transaction.TransactionResponse = await responsePromise +// response.receipt = await response.wait() +// return response +// } else { +// return responsePromise +// } +// } + +// async getMetaTransactions( +// projectId: number, +// page?: proto.Page +// ): Promise<{ +// page: proto.Page +// transactions: proto.MetaTxnLog[] +// }> { +// return { page: { page: 0, pageSize: 100 }, transactions: [] } +// } + +// async getTransactionCost( +// projectId: number, +// from: string, +// to: string +// ): Promise<{ +// cost: number +// }> { +// return { cost: 0 } +// } + +// async listGasSponsors(args: proto.ListGasSponsorsArgs): Promise { +// return { page: { page: 0, pageSize: 100 }, gasSponsors: [] } +// } + +// async addGasSponsor(args: proto.AddGasSponsorArgs): Promise { +// return { status: true, gasSponsor: {} as proto.GasSponsor } +// } + +// async updateGasSponsor(args: proto.UpdateGasSponsorArgs): Promise { +// return { status: true, gasSponsor: {} as proto.GasSponsor } +// } + +// async removeGasSponsor(args: proto.RemoveGasSponsorArgs): Promise { +// return { status: true } +// } +// } + +// function isAbstractSigner(signer: any): signer is ethers.AbstractSigner { +// return ( +// signer && +// typeof signer === 'object' && +// typeof signer.provider === 'object' && +// typeof signer.getAddress === 'function' && +// typeof signer.connect === 'function' +// ) +// } diff --git a/packages/services/relayer/src/preconditions/codec.ts b/packages/services/relayer/src/preconditions/codec.ts index b59fae6d67..74f83154be 100644 --- a/packages/services/relayer/src/preconditions/codec.ts +++ b/packages/services/relayer/src/preconditions/codec.ts @@ -36,11 +36,6 @@ export function decodePrecondition(p: TransactionPrecondition): Precondition | u return undefined } - if (typeof p.minAmount !== 'bigint') { - console.warn(`Failed to decode precondition: minAmount must be a bigint`) - return undefined - } - let precondition: Precondition | undefined try { @@ -123,92 +118,73 @@ export function decodePrecondition(p: TransactionPrecondition): Precondition | u } export function encodePrecondition(p: Precondition): string { + const data: any = {} + switch (p.type()) { case 'native-balance': { const native = p as NativeBalancePrecondition - const data = { - address: native.address.toString(), - ...(native.min !== undefined && { min: native.min.toString() }), - ...(native.max !== undefined && { max: native.max.toString() }), - } - - return JSON.stringify(data) + data.address = native.address.toString() + if (native.min !== undefined) data.min = native.min.toString() + if (native.max !== undefined) data.max = native.max.toString() + break } case 'erc20-balance': { const erc20 = p as Erc20BalancePrecondition - const data = { - address: erc20.address.toString(), - token: erc20.token.toString(), - ...(erc20.min !== undefined && { min: erc20.min.toString() }), - ...(erc20.max !== undefined && { max: erc20.max.toString() }), - } - - return JSON.stringify(data) + data.address = erc20.address.toString() + data.token = erc20.token.toString() + if (erc20.min !== undefined) data.min = erc20.min.toString() + if (erc20.max !== undefined) data.max = erc20.max.toString() + break } case 'erc20-approval': { const erc20 = p as Erc20ApprovalPrecondition - const data = { - address: erc20.address.toString(), - token: erc20.token.toString(), - operator: erc20.operator.toString(), - min: erc20.min.toString(), - } - - return JSON.stringify(data) + data.address = erc20.address.toString() + data.token = erc20.token.toString() + data.operator = erc20.operator.toString() + data.min = erc20.min.toString() + break } case 'erc721-ownership': { const erc721 = p as Erc721OwnershipPrecondition - const data = { - address: erc721.address.toString(), - token: erc721.token.toString(), - tokenId: erc721.tokenId.toString(), - ...(erc721.owned !== undefined && { owned: erc721.owned }), - } - - return JSON.stringify(data) + data.address = erc721.address.toString() + data.token = erc721.token.toString() + data.tokenId = erc721.tokenId.toString() + if (erc721.owned !== undefined) data.owned = erc721.owned + break } case 'erc721-approval': { const erc721 = p as Erc721ApprovalPrecondition - const data = { - address: erc721.address.toString(), - token: erc721.token.toString(), - tokenId: erc721.tokenId.toString(), - operator: erc721.operator.toString(), - } - - return JSON.stringify(data) + data.address = erc721.address.toString() + data.token = erc721.token.toString() + data.tokenId = erc721.tokenId.toString() + data.operator = erc721.operator.toString() + break } case 'erc1155-balance': { const erc1155 = p as Erc1155BalancePrecondition - const data = { - address: erc1155.address.toString(), - token: erc1155.token.toString(), - tokenId: erc1155.tokenId.toString(), - ...(erc1155.min !== undefined && { min: erc1155.min.toString() }), - ...(erc1155.max !== undefined && { max: erc1155.max.toString() }), - } - - return JSON.stringify(data) + data.address = erc1155.address.toString() + data.token = erc1155.token.toString() + data.tokenId = erc1155.tokenId.toString() + if (erc1155.min !== undefined) data.min = erc1155.min.toString() + if (erc1155.max !== undefined) data.max = erc1155.max.toString() + break } case 'erc1155-approval': { const erc1155 = p as Erc1155ApprovalPrecondition - const data = { - address: erc1155.address.toString(), - token: erc1155.token.toString(), - tokenId: erc1155.tokenId.toString(), - operator: erc1155.operator.toString(), - min: erc1155.min.toString(), - } - - return JSON.stringify(data) + data.address = erc1155.address.toString() + data.token = erc1155.token.toString() + data.tokenId = erc1155.tokenId.toString() + data.operator = erc1155.operator.toString() + data.min = erc1155.min.toString() + break } } - return JSON.stringify({}) + return JSON.stringify(data) } diff --git a/packages/services/relayer/src/provider-relayer.ts b/packages/services/relayer/src/provider-relayer.ts new file mode 100644 index 0000000000..85e9257f24 --- /dev/null +++ b/packages/services/relayer/src/provider-relayer.ts @@ -0,0 +1,284 @@ +// import { ethers } from 'ethers' +// import { walletContracts } from '@0xsequence/abi' +// import { FeeOption, FeeQuote, proto, Relayer, SimulateResult } from '.' +// import { logger, Optionals } from '@0xsequence/utils' +// import { commons } from '@0xsequence/core' + +// const DEFAULT_GAS_LIMIT = 800000n + +// export interface ProviderRelayerOptions { +// provider: ethers.Provider +// waitPollRate?: number +// deltaBlocksLog?: number +// fromBlockLog?: number +// } + +// export const ProviderRelayerDefaults: Required> = { +// waitPollRate: 1000, +// deltaBlocksLog: 12, +// fromBlockLog: -1024 +// } + +// export function isProviderRelayerOptions(obj: any): obj is ProviderRelayerOptions { +// return typeof obj === 'object' && isAbstractProvider(obj.provider) +// } + +// export abstract class ProviderRelayer implements Relayer { +// public provider: ethers.Provider +// public waitPollRate: number +// public deltaBlocksLog: number +// public fromBlockLog: number + +// constructor(options: ProviderRelayerOptions) { +// const opts = { ...ProviderRelayerDefaults, ...options } + +// this.provider = opts.provider +// this.waitPollRate = opts.waitPollRate +// this.deltaBlocksLog = opts.deltaBlocksLog +// this.fromBlockLog = opts.fromBlockLog +// } + +// abstract getFeeOptions( +// address: string, +// ...transactions: commons.transaction.Transaction[] +// ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> + +// abstract getFeeOptionsRaw( +// entrypoint: string, +// data: ethers.BytesLike, +// options?: { +// simulate?: boolean +// } +// ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> + +// abstract gasRefundOptions(address: string, ...transactions: commons.transaction.Transaction[]): Promise + +// abstract relay( +// signedTxs: commons.transaction.IntendedTransactionBundle, +// quote?: FeeQuote, +// waitForReceipt?: boolean +// ): Promise + +// abstract getTransactionCost( +// projectId: number, +// from: string, +// to: string +// ): Promise<{ +// cost: number +// }> + +// abstract getMetaTransactions( +// projectId: number, +// page?: proto.Page +// ): Promise<{ +// page: proto.Page +// transactions: proto.MetaTxnLog[] +// }> + +// abstract listGasSponsors(args: proto.ListGasSponsorsArgs): Promise + +// abstract addGasSponsor(args: proto.AddGasSponsorArgs): Promise + +// abstract updateGasSponsor(args: proto.UpdateGasSponsorArgs): Promise + +// abstract removeGasSponsor(args: proto.RemoveGasSponsorArgs): Promise + +// async simulate(wallet: string, ...transactions: commons.transaction.Transaction[]): Promise { +// return ( +// await Promise.all( +// transactions.map(async tx => { +// // Respect gasLimit request of the transaction (as long as its not 0) +// if (tx.gasLimit && BigInt(tx.gasLimit || 0) !== 0n) { +// return tx.gasLimit +// } + +// // Fee can't be estimated locally for delegateCalls +// if (tx.delegateCall) { +// return DEFAULT_GAS_LIMIT +// } + +// // Fee can't be estimated for self-called if wallet hasn't been deployed +// if (tx.to === wallet && (await this.provider.getCode(wallet).then(code => ethers.getBytes(code).length === 0))) { +// return DEFAULT_GAS_LIMIT +// } + +// if (!this.provider) { +// throw new Error('signer.provider is not set, but is required') +// } + +// // TODO: If the wallet address has been deployed, gas limits can be +// // estimated with more accurately by using self-calls with the batch transactions one by one +// return this.provider.estimateGas({ +// from: wallet, +// to: tx.to, +// data: tx.data, +// value: tx.value +// }) +// }) +// ) +// ).map(gasLimit => ({ +// executed: true, +// succeeded: true, +// gasUsed: Number(gasLimit), +// gasLimit: Number(gasLimit) +// })) +// } + +// async getNonce(address: string, space?: ethers.BigNumberish, blockTag?: ethers.BlockTag): Promise { +// if (!this.provider) { +// throw new Error('provider is not set') +// } + +// if ((await this.provider.getCode(address)) === '0x') { +// return 0 +// } + +// if (space === undefined) { +// space = 0 +// } + +// const module = new ethers.Contract(address, walletContracts.mainModule.abi, this.provider) +// const nonce = await module.readNonce(space, { blockTag: blockTag }) +// return commons.transaction.encodeNonce(space, nonce) +// } + +// async wait( +// metaTxnId: string | commons.transaction.SignedTransactionBundle, +// timeoutDuration?: number, +// delay: number = this.waitPollRate, +// maxFails: number = 5 +// ): Promise { +// if (typeof metaTxnId !== 'string') { +// metaTxnId = commons.transaction.intendedTransactionID(metaTxnId) +// } + +// let timedOut = false + +// const retry = async (f: () => Promise, errorMessage: string): Promise => { +// let fails = 0 + +// while (!timedOut) { +// try { +// return await f() +// } catch (error) { +// fails++ + +// if (maxFails !== undefined && fails >= maxFails) { +// logger.error(`giving up after ${fails} failed attempts${errorMessage ? `: ${errorMessage}` : ''}`, error) +// throw error +// } else { +// logger.warn(`attempt #${fails} failed${errorMessage ? `: ${errorMessage}` : ''}`, error) +// } +// } + +// if (delay > 0) { +// await new Promise(resolve => setTimeout(resolve, delay)) +// } +// } + +// throw new Error(`timed out after ${fails} failed attempts${errorMessage ? `: ${errorMessage}` : ''}`) +// } + +// const waitReceipt = async (): Promise => { +// // Transactions can only get executed on nonce change +// // get all nonce changes and look for metaTxnIds in between logs +// let lastBlock: number = this.fromBlockLog + +// if (lastBlock < 0) { +// const block = await retry(() => this.provider.getBlockNumber(), 'unable to get latest block number') +// lastBlock = block + lastBlock +// } + +// if (typeof metaTxnId !== 'string') { +// throw new Error('impossible') +// } + +// const normalMetaTxnId = metaTxnId.replace('0x', '') + +// while (!timedOut) { +// const block = await retry(() => this.provider.getBlockNumber(), 'unable to get latest block number') + +// const logs = await retry( +// () => +// this.provider.getLogs({ +// fromBlock: Math.max(0, lastBlock - this.deltaBlocksLog), +// toBlock: block, +// // Nonce change event topic +// topics: ['0x1f180c27086c7a39ea2a7b25239d1ab92348f07ca7bb59d1438fcf527568f881'] +// }), +// `unable to get NonceChange logs for blocks ${Math.max(0, lastBlock - this.deltaBlocksLog)} to ${block}` +// ) + +// lastBlock = block + +// // Get receipts of all transactions +// const txs = await Promise.all( +// logs.map(l => +// retry( +// () => this.provider.getTransactionReceipt(l.transactionHash), +// `unable to get receipt for transaction ${l.transactionHash}` +// ) +// ) +// ) + +// // Find a transaction with a TxExecuted log +// const found = txs.find(tx => +// tx?.logs.find( +// l => +// (l.topics.length === 0 && l.data.replace('0x', '') === normalMetaTxnId) || +// (l.topics.length === 1 && +// // TxFailed event topic +// l.topics[0] === '0x3dbd1590ea96dd3253a91f24e64e3a502e1225d602a5731357bc12643070ccd7' && +// l.data.length >= 64 && +// l.data.replace('0x', '').startsWith(normalMetaTxnId)) +// ) +// ) + +// // If found return that +// if (found) { +// const response = await retry(() => this.provider.getTransaction(found.hash), `unable to get transaction ${found.hash}`) +// if (!response) { +// throw new Error(`Transaction response not found for ${metaTxnId}`) +// } + +// // NOTE: we have to do this, because ethers-v6 uses private fields +// // and we can't just extend the class and override the method, so +// // we just modify the response object directly by adding the receipt to it. +// const out: any = response +// out.receipt = found +// return out +// } + +// // Otherwise wait and try again +// if (!timedOut) { +// await new Promise(r => setTimeout(r, delay)) +// } +// } + +// throw new Error(`Timeout waiting for transaction receipt ${metaTxnId}`) +// } + +// if (timeoutDuration !== undefined) { +// return Promise.race([ +// waitReceipt(), +// new Promise((_, reject) => +// setTimeout(() => { +// timedOut = true +// reject(`Timeout waiting for transaction receipt ${metaTxnId}`) +// }, timeoutDuration) +// ) +// ]) +// } else { +// return waitReceipt() +// } +// } +// } + +// function isAbstractProvider(provider: any): provider is ethers.AbstractProvider { +// return ( +// provider && +// typeof provider === 'object' && +// typeof provider.getNetwork === 'function' && +// typeof provider.getBlockNumber === 'function' +// ) +// } diff --git a/packages/services/relayer/src/relayer/relayer.ts b/packages/services/relayer/src/relayer/relayer.ts index 9f648004af..5a4fcb5c2b 100644 --- a/packages/services/relayer/src/relayer/relayer.ts +++ b/packages/services/relayer/src/relayer/relayer.ts @@ -16,7 +16,6 @@ export interface Relayer { feeOptions( wallet: Address.Address, chainId: number, - to: Address.Address, calls: Payload.Call[], data?: Hex.Hex, ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> @@ -28,10 +27,8 @@ export interface Relayer { checkPrecondition(precondition: Precondition.Precondition): Promise } -export function isRelayer(relayer: unknown): relayer is Relayer { +export function isRelayer(relayer: any): relayer is Relayer { return ( - typeof relayer === 'object' && - relayer !== null && 'isAvailable' in relayer && 'feeOptions' in relayer && 'relay' in relayer && diff --git a/packages/services/relayer/src/relayer/rpc-relayer/relayer.gen.ts b/packages/services/relayer/src/relayer/rpc-relayer/relayer.gen.ts index 8a9ff4a7b4..dd36300697 100644 --- a/packages/services/relayer/src/relayer/rpc-relayer/relayer.gen.ts +++ b/packages/services/relayer/src/relayer/rpc-relayer/relayer.gen.ts @@ -1,5 +1,5 @@ /* eslint-disable */ -// sequence-relayer v0.4.1 0a2503bc893179ba968b0015d7580aabf6a88dd4 +// sequence-relayer v0.4.1 43ed1a26ed167b22a0b0827a8725a0df6fbe6ab4 // -- // Code generated by Webrpc-gen@v0.32.2 with typescript generator. DO NOT EDIT. // @@ -12,7 +12,7 @@ export const WebrpcVersion = 'v1' export const WebrpcSchemaVersion = 'v0.4.1' // Schema hash generated from your RIDL schema -export const WebrpcSchemaHash = '0a2503bc893179ba968b0015d7580aabf6a88dd4' +export const WebrpcSchemaHash = '43ed1a26ed167b22a0b0827a8725a0df6fbe6ab4' // // Client interface @@ -390,6 +390,14 @@ export interface MetaTxn { walletAddress: string contract: string input: string + authorization?: EIP7702Authorization +} + +export interface EIP7702Authorization { + chainId: number + implementation: string + nonce: number + signature: string } export interface MetaTxnLog { @@ -586,6 +594,7 @@ export interface GetMetaTxnReceiptArgs { export interface GetMetaTxnReceiptReturn { receipt: MetaTxnReceipt + metaTxnEnqueued: boolean } export interface SimulateArgs { @@ -629,6 +638,7 @@ export interface FeeOptionsArgs { to: string data: string simulate?: boolean + authorization?: EIP7702Authorization } export interface FeeOptionsReturn { @@ -656,6 +666,7 @@ export interface FeeOptionsWithBridgeGasArgs { data: string simulate?: boolean bridgeGas: string + authorization?: EIP7702Authorization } export interface FeeOptionsWithBridgeGasReturn { @@ -696,6 +707,7 @@ export interface RepairSenderReturn {} export interface GetMetaTransactionsArgs { projectId: number page?: Page + includeNonSponsored?: boolean } export interface GetMetaTransactionsReturn { diff --git a/packages/services/relayer/src/relayer/standard/eip6963.ts b/packages/services/relayer/src/relayer/standard/eip6963.ts index a290b2c6f9..9d48613633 100644 --- a/packages/services/relayer/src/relayer/standard/eip6963.ts +++ b/packages/services/relayer/src/relayer/standard/eip6963.ts @@ -6,7 +6,7 @@ import { Payload } from '@0xsequence/wallet-primitives' import { FeeToken, TransactionPrecondition } from '../rpc-relayer/relayer.gen.js' export class EIP6963Relayer implements Relayer { - public readonly kind = 'relayer' + public readonly kind: 'relayer' = 'relayer' public readonly type = 'eip6963' public readonly id: string public readonly info: EIP6963ProviderInfo @@ -30,10 +30,9 @@ export class EIP6963Relayer implements Relayer { feeOptions( wallet: Address.Address, chainId: number, - to: Address.Address, calls: Payload.Call[], ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> { - return this.relayer.feeOptions(wallet, chainId, to, calls) + return this.relayer.feeOptions(wallet, chainId, calls) } async relay(to: Address.Address, data: Hex.Hex, chainId: number, _?: FeeQuote): Promise<{ opHash: Hex.Hex }> { @@ -59,7 +58,7 @@ export function getEIP6963Store() { return store } -const relayers: Map = new Map() +let relayers: Map = new Map() export function getRelayers(): EIP6963Relayer[] { const store = getEIP6963Store() diff --git a/packages/services/relayer/src/relayer/standard/local.ts b/packages/services/relayer/src/relayer/standard/local.ts index 4135af3b30..14d697aa23 100644 --- a/packages/services/relayer/src/relayer/standard/local.ts +++ b/packages/services/relayer/src/relayer/standard/local.ts @@ -1,18 +1,9 @@ -import { Payload } from '@0xsequence/wallet-primitives' +import { Constants, Payload } from '@0xsequence/wallet-primitives' import { EIP1193Provider } from 'mipd' -import { AbiFunction, Address, Hex, TransactionReceipt } from 'ox' +import { AbiFunction, Address, Bytes, Hex, TransactionReceipt } from 'ox' import { FeeOption, FeeQuote, OperationStatus, Relayer } from '../index.js' import { FeeToken, TransactionPrecondition } from '../rpc-relayer/relayer.gen.js' -import { - decodePrecondition, - Erc1155ApprovalPrecondition, - Erc1155BalancePrecondition, - Erc20ApprovalPrecondition, - Erc20BalancePrecondition, - Erc721ApprovalPrecondition, - Erc721OwnershipPrecondition, - NativeBalancePrecondition, -} from '../../preconditions/index.js' +import { decodePrecondition } from '../../preconditions/index.js' import { erc20BalanceOf, erc20Allowance, @@ -32,7 +23,7 @@ export interface GenericProvider { } export class LocalRelayer implements Relayer { - public readonly kind = 'relayer' + public readonly kind: 'relayer' = 'relayer' public readonly type = 'local' public readonly id = 'local' @@ -43,7 +34,7 @@ export class LocalRelayer implements Relayer { } static createFromWindow(window: Window): LocalRelayer | undefined { - const eth = (window as { ethereum?: EIP1193Provider }).ethereum + const eth = (window as any).ethereum if (!eth) { console.warn('Window.ethereum not found, skipping local relayer') return undefined @@ -63,14 +54,27 @@ export class LocalRelayer implements Relayer { } feeOptions( - _wallet: Address.Address, - _chainId: number, - _to: Address.Address, - _calls: Payload.Call[], + wallet: Address.Address, + chainId: number, + calls: Payload.Call[], ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> { return Promise.resolve({ options: [] }) } + private decodeCalls(data: Hex.Hex): Payload.Calls { + const executeSelector = AbiFunction.getSelector(Constants.EXECUTE) + + let packedPayload + if (data.startsWith(executeSelector)) { + const decode = AbiFunction.decodeData(Constants.EXECUTE, data) + packedPayload = decode[0] + } else { + packedPayload = data + } + + return Payload.decode(Bytes.fromHex(packedPayload)) + } + async relay( to: Address.Address, data: Hex.Hex, @@ -173,8 +177,8 @@ export class LocalRelayer implements Relayer { switch (decoded.type()) { case 'native-balance': { - const native = decoded as NativeBalancePrecondition - const balance = await this.provider.getBalance(native.address) + const native = decoded as any + const balance = await this.provider.getBalance(native.address.toString()) if (native.min !== undefined && balance < native.min) { return false } @@ -185,10 +189,10 @@ export class LocalRelayer implements Relayer { } case 'erc20-balance': { - const erc20 = decoded as Erc20BalancePrecondition - const data = AbiFunction.encodeData(erc20BalanceOf, [erc20.address]) + const erc20 = decoded as any + const data = AbiFunction.encodeData(erc20BalanceOf, [erc20.address.toString()]) const result = await this.provider.call({ - to: erc20.token, + to: erc20.token.toString(), data, }) const balance = BigInt(result) @@ -202,10 +206,10 @@ export class LocalRelayer implements Relayer { } case 'erc20-approval': { - const erc20 = decoded as Erc20ApprovalPrecondition - const data = AbiFunction.encodeData(erc20Allowance, [erc20.address, erc20.operator]) + const erc20 = decoded as any + const data = AbiFunction.encodeData(erc20Allowance, [erc20.address.toString(), erc20.operator.toString()]) const result = await this.provider.call({ - to: erc20.token, + to: erc20.token.toString(), data, }) const allowance = BigInt(result) @@ -213,10 +217,10 @@ export class LocalRelayer implements Relayer { } case 'erc721-ownership': { - const erc721 = decoded as Erc721OwnershipPrecondition + const erc721 = decoded as any const data = AbiFunction.encodeData(erc721OwnerOf, [erc721.tokenId]) const result = await this.provider.call({ - to: erc721.token, + to: erc721.token.toString(), data, }) const owner = '0x' + result.slice(26) @@ -225,10 +229,10 @@ export class LocalRelayer implements Relayer { } case 'erc721-approval': { - const erc721 = decoded as Erc721ApprovalPrecondition + const erc721 = decoded as any const data = AbiFunction.encodeData(erc721GetApproved, [erc721.tokenId]) const result = await this.provider.call({ - to: erc721.token, + to: erc721.token.toString(), data, }) const approved = '0x' + result.slice(26) @@ -236,10 +240,10 @@ export class LocalRelayer implements Relayer { } case 'erc1155-balance': { - const erc1155 = decoded as Erc1155BalancePrecondition - const data = AbiFunction.encodeData(erc1155BalanceOf, [erc1155.address, erc1155.tokenId]) + const erc1155 = decoded as any + const data = AbiFunction.encodeData(erc1155BalanceOf, [erc1155.address.toString(), erc1155.tokenId]) const result = await this.provider.call({ - to: erc1155.token, + to: erc1155.token.toString(), data, }) const balance = BigInt(result) @@ -253,10 +257,13 @@ export class LocalRelayer implements Relayer { } case 'erc1155-approval': { - const erc1155 = decoded as Erc1155ApprovalPrecondition - const data = AbiFunction.encodeData(erc1155IsApprovedForAll, [erc1155.address, erc1155.operator]) + const erc1155 = decoded as any + const data = AbiFunction.encodeData(erc1155IsApprovedForAll, [ + erc1155.address.toString(), + erc1155.operator.toString(), + ]) const result = await this.provider.call({ - to: erc1155.token, + to: erc1155.token.toString(), data, }) return BigInt(result) === 1n @@ -333,7 +340,7 @@ export class EIP1193ProviderAdapter implements GenericProvider { const rpcReceipt = await this.provider.request({ method: 'eth_getTransactionReceipt', params: [txHash] }) if (rpcReceipt) { - const receipt = TransactionReceipt.fromRpc(rpcReceipt as Parameters[0]) + const receipt = TransactionReceipt.fromRpc(rpcReceipt as any) if (receipt?.status === 'success') { return 'success' } else if (receipt?.status === 'reverted') { diff --git a/packages/services/relayer/src/relayer/standard/pk-relayer.ts b/packages/services/relayer/src/relayer/standard/pk-relayer.ts index b1d420a586..37b2e5a08a 100644 --- a/packages/services/relayer/src/relayer/standard/pk-relayer.ts +++ b/packages/services/relayer/src/relayer/standard/pk-relayer.ts @@ -5,7 +5,7 @@ import { FeeOption, FeeQuote, OperationStatus, Relayer } from '../index.js' import { FeeToken } from '../rpc-relayer/relayer.gen.js' export class PkRelayer implements Relayer { - public readonly kind = 'relayer' + public readonly kind: 'relayer' = 'relayer' public readonly type = 'pk' public readonly id = 'pk' private readonly relayer: LocalRelayer @@ -114,10 +114,9 @@ export class PkRelayer implements Relayer { feeOptions( wallet: Address.Address, chainId: number, - to: Address.Address, calls: Payload.Call[], ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> { - return this.relayer.feeOptions(wallet, chainId, to, calls) + return this.relayer.feeOptions(wallet, chainId, calls) } async relay(to: Address.Address, data: Hex.Hex, chainId: number, _?: FeeQuote): Promise<{ opHash: Hex.Hex }> { @@ -132,7 +131,7 @@ export class PkRelayer implements Relayer { return this.relayer.status(opHash, chainId) } - async checkPrecondition(_precondition: Precondition.Precondition): Promise { + async checkPrecondition(precondition: Precondition.Precondition): Promise { // TODO: Implement precondition check return true } diff --git a/packages/services/relayer/src/relayer/standard/sequence.ts b/packages/services/relayer/src/relayer/standard/sequence.ts index 1ae5ec69bd..2d85c929fe 100644 --- a/packages/services/relayer/src/relayer/standard/sequence.ts +++ b/packages/services/relayer/src/relayer/standard/sequence.ts @@ -3,7 +3,7 @@ import { Payload } from '@0xsequence/wallet-primitives' import { AbiFunction, Address, Bytes, Hex } from 'ox' import { FeeOption, FeeQuote, OperationStatus, Relayer } from '../index.js' export class SequenceRelayer implements Relayer { - public readonly kind = 'relayer' + public readonly kind: 'relayer' = 'relayer' public readonly type = 'sequence' readonly id = 'sequence' @@ -36,10 +36,10 @@ export class SequenceRelayer implements Relayer { async feeOptions( wallet: Address.Address, _chainId: number, - to: Address.Address, calls: Payload.Call[], transactionData?: Hex.Hex, ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> { + const to = wallet // TODO: this might be the guest module const execute = AbiFunction.from('function execute(bytes calldata _payload, bytes calldata _signature)') const payload = Payload.encode({ type: 'call', space: 0n, nonce: 0n, calls }, to) const signature = '0x0001' // TODO: use a stub signature @@ -53,7 +53,7 @@ export class SequenceRelayer implements Relayer { } } - async checkPrecondition(_precondition: TransactionPrecondition): Promise { + async checkPrecondition(precondition: TransactionPrecondition): Promise { // TODO: implement return false } diff --git a/packages/services/relayer/src/rpc-relayer/index.ts b/packages/services/relayer/src/rpc-relayer/index.ts new file mode 100644 index 0000000000..6e10f600bd --- /dev/null +++ b/packages/services/relayer/src/rpc-relayer/index.ts @@ -0,0 +1 @@ +export * from './relayer.gen.js' diff --git a/packages/services/relayer/src/rpc-relayer/relayer.gen.ts b/packages/services/relayer/src/rpc-relayer/relayer.gen.ts new file mode 100644 index 0000000000..a9e6b44405 --- /dev/null +++ b/packages/services/relayer/src/rpc-relayer/relayer.gen.ts @@ -0,0 +1,2037 @@ +/* eslint-disable */ +// sequence-relayer v0.4.1 62fe2b49d57c4a0d3960ac1176d48ecfffc7af5a +// -- +// Code generated by webrpc-gen@v0.26.0 with typescript generator. DO NOT EDIT. +// +// webrpc-gen -schema=relayer.ridl -target=typescript -client -out=./clients/relayer.gen.ts + +export const WebrpcHeader = 'Webrpc' + +export const WebrpcHeaderValue = 'webrpc@v0.26.0;gen-typescript@v0.17.0;sequence-relayer@v0.4.1' + +// WebRPC description and code-gen version +export const WebRPCVersion = 'v1' + +// Schema version of your RIDL schema +export const WebRPCSchemaVersion = 'v0.4.1' + +// Schema hash generated from your RIDL schema +export const WebRPCSchemaHash = '62fe2b49d57c4a0d3960ac1176d48ecfffc7af5a' + +type WebrpcGenVersions = { + webrpcGenVersion: string + codeGenName: string + codeGenVersion: string + schemaName: string + schemaVersion: string +} + +export function VersionFromHeader(headers: Headers): WebrpcGenVersions { + const headerValue = headers.get(WebrpcHeader) + if (!headerValue) { + return { + webrpcGenVersion: '', + codeGenName: '', + codeGenVersion: '', + schemaName: '', + schemaVersion: '', + } + } + + return parseWebrpcGenVersions(headerValue) +} + +function parseWebrpcGenVersions(header: string): WebrpcGenVersions { + const versions = header.split(';') + if (versions.length < 3) { + return { + webrpcGenVersion: '', + codeGenName: '', + codeGenVersion: '', + schemaName: '', + schemaVersion: '', + } + } + + const [_, webrpcGenVersion] = versions[0]!.split('@') + const [codeGenName, codeGenVersion] = versions[1]!.split('@') + const [schemaName, schemaVersion] = versions[2]!.split('@') + + return { + webrpcGenVersion: webrpcGenVersion ?? '', + codeGenName: codeGenName ?? '', + codeGenVersion: codeGenVersion ?? '', + schemaName: schemaName ?? '', + schemaVersion: schemaVersion ?? '', + } +} + +// +// Types +// + +export enum ETHTxnStatus { + UNKNOWN = 'UNKNOWN', + DROPPED = 'DROPPED', + QUEUED = 'QUEUED', + SENT = 'SENT', + SUCCEEDED = 'SUCCEEDED', + PARTIALLY_FAILED = 'PARTIALLY_FAILED', + FAILED = 'FAILED', + PENDING_PRECONDITION = 'PENDING_PRECONDITION', +} + +export enum TransferType { + SEND = 'SEND', + RECEIVE = 'RECEIVE', + BRIDGE_DEPOSIT = 'BRIDGE_DEPOSIT', + BRIDGE_WITHDRAW = 'BRIDGE_WITHDRAW', + BURN = 'BURN', + UNKNOWN = 'UNKNOWN', +} + +export enum SimulateStatus { + SKIPPED = 'SKIPPED', + SUCCEEDED = 'SUCCEEDED', + FAILED = 'FAILED', + ABORTED = 'ABORTED', + REVERTED = 'REVERTED', + NOT_ENOUGH_GAS = 'NOT_ENOUGH_GAS', +} + +export enum FeeTokenType { + UNKNOWN = 'UNKNOWN', + ERC20_TOKEN = 'ERC20_TOKEN', + ERC1155_TOKEN = 'ERC1155_TOKEN', +} + +export enum SortOrder { + DESC = 'DESC', + ASC = 'ASC', +} + +export interface Version { + webrpcVersion: string + schemaVersion: string + schemaHash: string + appVersion: string +} + +export interface RuntimeStatus { + healthOK: boolean + startTime: string + uptime: number + ver: string + branch: string + commitHash: string + chainID: number + useEIP1559: boolean + senders: Array + checks: RuntimeChecks +} + +export interface SenderStatus { + index: number + address: string + etherBalance: number + active: boolean +} + +export interface RuntimeChecks {} + +export interface SequenceContext { + factory: string + mainModule: string + mainModuleUpgradable: string + guestModule: string + utils: string +} + +export interface GasTank { + id: number + chainId: number + name: string + currentBalance: number + unlimited: boolean + feeMarkupFactor: number + updatedAt: string + createdAt: string +} + +export interface GasTankBalanceAdjustment { + gasTankId: number + nonce: number + amount: number + totalBalance: number + balanceTimestamp: string + createdAt: string +} + +export interface GasSponsor { + id: number + gasTankId: number + projectId: number + chainId: number + address: string + name: string + active: boolean + updatedAt: string + createdAt: string + deletedAt: string +} + +export interface GasSponsorUsage { + name: string + id: number + totalGasUsed: number + totalTxnFees: number + totalTxnFeesUsd: number + avgGasPrice: number + totalTxns: number + startTime: string + endTime: string +} + +export interface MetaTxn { + walletAddress: string + contract: string + input: string +} + +export interface MetaTxnLog { + id: number + chainId: number + projectId: number + txnHash: string + txnNonce: string + metaTxnID?: string + txnStatus: ETHTxnStatus + txnRevertReason: string + requeues: number + queuedAt: string + sentAt: string + minedAt: string + target: string + input: string + txnArgs: { [key: string]: any } + txnReceipt?: { [key: string]: any } + walletAddress: string + metaTxnNonce: string + gasLimit: number + gasPrice: string + gasUsed: number + gasEstimated: number + gasFeeMarkup?: number + usdRate: string + creditsUsed: number + cost: string + isWhitelisted: boolean + gasSponsor?: number + gasTank?: number + updatedAt: string + createdAt: string +} + +export interface MetaTxnReceipt { + id: string + status: string + revertReason?: string + index: number + logs: Array + receipts: Array + blockNumber: string + txnHash: string + txnReceipt: string +} + +export interface MetaTxnReceiptLog { + address: string + topics: Array + data: string +} + +export interface IntentPrecondition { + type: string + chainId: string + data: any +} + +export interface IntentSolution { + transactions: Array +} + +export interface Transactions { + chainID: string + transactions: Array + preconditions?: Array +} + +export interface Transaction { + delegateCall: boolean + revertOnError: boolean + gasLimit: string + target: string + value: string + data: string +} + +export interface TxnLogUser { + username: string +} + +export interface TxnLogTransfer { + transferType: TransferType + contractAddress: string + from: string + to: string + ids: Array + amounts: Array +} + +export interface SentTransactionsFilter { + pending?: boolean + failed?: boolean +} + +export interface SimulateResult { + executed: boolean + succeeded: boolean + result?: string + reason?: string + gasUsed: number + gasLimit: number +} + +export interface SimulateV3Result { + status: SimulateStatus + result?: string + error?: string + gasUsed: number + gasLimit: number +} + +export interface FeeOption { + token: FeeToken + to: string + value: string + gasLimit: number +} + +export interface FeeToken { + chainId: number + name: string + symbol: string + type: FeeTokenType + decimals?: number + logoURL: string + contractAddress?: string + tokenID?: string +} + +export interface Page { + pageSize?: number + page?: number + more?: boolean + totalRecords?: number + column?: string + before?: any + after?: any + sort?: Array +} + +export interface SortBy { + column: string + order: SortOrder +} + +export interface Relayer { + ping(headers?: object, signal?: AbortSignal): Promise + version(headers?: object, signal?: AbortSignal): Promise + runtimeStatus(headers?: object, signal?: AbortSignal): Promise + getSequenceContext(headers?: object, signal?: AbortSignal): Promise + getChainID(headers?: object, signal?: AbortSignal): Promise + /** + * + * Transactions + * + * TODO (future): rename this to just, 'SendTransaction(txn: MetaTransaction)' or 'SendTransaction(txn: SignedTransaction)', or something.. + * Project ID is only used by service and admin calls. Other clients must have projectID passed via the context + * TODO: rename return txnHash: string to metaTxnID: string + */ + sendMetaTxn(args: SendMetaTxnArgs, headers?: object, signal?: AbortSignal): Promise + getMetaTxnNonce(args: GetMetaTxnNonceArgs, headers?: object, signal?: AbortSignal): Promise + /** + * TODO: one day, make GetMetaTxnReceipt respond immediately with receipt or not + * and add WaitTransactionReceipt method, which will block and wait, similar to how GetMetaTxnReceipt + * is implemented now. + * For backwards compat, we can leave the current GetMetaTxnReceipt how it is, an deprecate it, and introduce + * new, GetTransactionReceipt and WaitTransactionReceipt methods + * we can also accept metaTxnId and txnHash .. so can take either or.. I wonder if ERC-4337 has any convention on this? + */ + getMetaTxnReceipt( + args: GetMetaTxnReceiptArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + simulate(args: SimulateArgs, headers?: object, signal?: AbortSignal): Promise + simulateV3(args: SimulateV3Args, headers?: object, signal?: AbortSignal): Promise + /** + * TODO: deprecated, to be removed by https://github.com/0xsequence/stack/pull/356 at a later date + */ + updateMetaTxnGasLimits( + args: UpdateMetaTxnGasLimitsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + feeTokens(headers?: object, signal?: AbortSignal): Promise + feeOptions(args: FeeOptionsArgs, headers?: object, signal?: AbortSignal): Promise + /** + * TODO: deprecated, to be removed by https://github.com/0xsequence/stack/pull/356 at a later date + */ + getMetaTxnNetworkFeeOptions( + args: GetMetaTxnNetworkFeeOptionsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + getMetaTransactions( + args: GetMetaTransactionsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + getTransactionCost( + args: GetTransactionCostArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Sent transactions from an account. If filter is omitted then it will return all transactions. + */ + sentTransactions(args: SentTransactionsArgs, headers?: object, signal?: AbortSignal): Promise + /** + * Pending transactions waiting to be mined for an account. This endpoint is just a sugar of `SentTransactions` + * with the filter set to pending: true. + */ + pendingTransactions( + args: PendingTransactionsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Legacy Gas Tank + */ + getGasTank(args: GetGasTankArgs, headers?: object, signal?: AbortSignal): Promise + addGasTank(args: AddGasTankArgs, headers?: object, signal?: AbortSignal): Promise + updateGasTank(args: UpdateGasTankArgs, headers?: object, signal?: AbortSignal): Promise + /** + * Legacy Gas Adjustment + */ + nextGasTankBalanceAdjustmentNonce( + args: NextGasTankBalanceAdjustmentNonceArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + adjustGasTankBalance( + args: AdjustGasTankBalanceArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + getGasTankBalanceAdjustment( + args: GetGasTankBalanceAdjustmentArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + listGasTankBalanceAdjustments( + args: ListGasTankBalanceAdjustmentsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Gas Sponsorship + */ + listGasSponsors(args: ListGasSponsorsArgs, headers?: object, signal?: AbortSignal): Promise + getGasSponsor(args: GetGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise + addGasSponsor(args: AddGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise + updateGasSponsor(args: UpdateGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise + removeGasSponsor(args: RemoveGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise + /** + * Gas Sponsor Lookup + */ + addressGasSponsors( + args: AddressGasSponsorsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Project Balance + */ + getProjectBalance( + args: GetProjectBalanceArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + adjustProjectBalance( + args: AdjustProjectBalanceArgs, + headers?: object, + signal?: AbortSignal, + ): Promise +} + +export interface PingArgs {} + +export interface PingReturn { + status: boolean +} +export interface VersionArgs {} + +export interface VersionReturn { + version: Version +} +export interface RuntimeStatusArgs {} + +export interface RuntimeStatusReturn { + status: RuntimeStatus +} +export interface GetSequenceContextArgs {} + +export interface GetSequenceContextReturn { + data: SequenceContext +} +export interface GetChainIDArgs {} + +export interface GetChainIDReturn { + chainID: number +} +export interface SendMetaTxnArgs { + call: MetaTxn + quote?: string + projectID?: number + preconditions?: Array +} + +export interface SendMetaTxnReturn { + status: boolean + txnHash: string +} +export interface GetMetaTxnNonceArgs { + walletContractAddress: string + space?: string +} + +export interface GetMetaTxnNonceReturn { + nonce: string +} +export interface GetMetaTxnReceiptArgs { + metaTxID: string +} + +export interface GetMetaTxnReceiptReturn { + receipt: MetaTxnReceipt +} +export interface SimulateArgs { + wallet: string + transactions: string +} + +export interface SimulateReturn { + results: Array +} +export interface SimulateV3Args { + wallet: string + calls: string +} + +export interface SimulateV3Return { + results: Array +} +export interface UpdateMetaTxnGasLimitsArgs { + walletAddress: string + walletConfig: any + payload: string +} + +export interface UpdateMetaTxnGasLimitsReturn { + payload: string +} +export interface FeeTokensArgs {} + +export interface FeeTokensReturn { + isFeeRequired: boolean + tokens: Array +} +export interface FeeOptionsArgs { + wallet: string + to: string + data: string + simulate?: boolean +} + +export interface FeeOptionsReturn { + options: Array + sponsored: boolean + quote?: string +} +export interface GetMetaTxnNetworkFeeOptionsArgs { + walletConfig: any + payload: string +} + +export interface GetMetaTxnNetworkFeeOptionsReturn { + options: Array +} +export interface GetMetaTransactionsArgs { + projectId: number + page?: Page +} + +export interface GetMetaTransactionsReturn { + page: Page + transactions: Array +} +export interface GetTransactionCostArgs { + projectId: number + from: string + to: string +} + +export interface GetTransactionCostReturn { + cost: number +} +export interface SentTransactionsArgs { + filter?: SentTransactionsFilter + page?: Page +} + +export interface SentTransactionsReturn { + page: Page + transactions: Array +} +export interface PendingTransactionsArgs { + page?: Page +} + +export interface PendingTransactionsReturn { + page: Page + transactions: Array +} +export interface GetGasTankArgs { + id: number +} + +export interface GetGasTankReturn { + gasTank: GasTank +} +export interface AddGasTankArgs { + name: string + feeMarkupFactor: number + unlimited?: boolean +} + +export interface AddGasTankReturn { + status: boolean + gasTank: GasTank +} +export interface UpdateGasTankArgs { + id: number + name?: string + feeMarkupFactor?: number + unlimited?: boolean +} + +export interface UpdateGasTankReturn { + status: boolean + gasTank: GasTank +} +export interface NextGasTankBalanceAdjustmentNonceArgs { + id: number +} + +export interface NextGasTankBalanceAdjustmentNonceReturn { + nonce: number +} +export interface AdjustGasTankBalanceArgs { + id: number + nonce: number + amount: number +} + +export interface AdjustGasTankBalanceReturn { + status: boolean + adjustment: GasTankBalanceAdjustment +} +export interface GetGasTankBalanceAdjustmentArgs { + id: number + nonce: number +} + +export interface GetGasTankBalanceAdjustmentReturn { + adjustment: GasTankBalanceAdjustment +} +export interface ListGasTankBalanceAdjustmentsArgs { + id: number + page?: Page +} + +export interface ListGasTankBalanceAdjustmentsReturn { + page: Page + adjustments: Array +} +export interface ListGasSponsorsArgs { + projectId: number + page?: Page +} + +export interface ListGasSponsorsReturn { + page: Page + gasSponsors: Array +} +export interface GetGasSponsorArgs { + projectId: number + id: number +} + +export interface GetGasSponsorReturn { + gasSponsor: GasSponsor +} +export interface AddGasSponsorArgs { + projectId: number + address: string + name?: string + active?: boolean +} + +export interface AddGasSponsorReturn { + status: boolean + gasSponsor: GasSponsor +} +export interface UpdateGasSponsorArgs { + projectId: number + id: number + name?: string + active?: boolean +} + +export interface UpdateGasSponsorReturn { + status: boolean + gasSponsor: GasSponsor +} +export interface RemoveGasSponsorArgs { + projectId: number + id: number +} + +export interface RemoveGasSponsorReturn { + status: boolean +} +export interface AddressGasSponsorsArgs { + address: string + page?: Page +} + +export interface AddressGasSponsorsReturn { + page: Page + gasSponsors: Array +} +export interface GetProjectBalanceArgs { + projectId: number +} + +export interface GetProjectBalanceReturn { + balance: number +} +export interface AdjustProjectBalanceArgs { + projectId: number + amount: number + identifier: string +} + +export interface AdjustProjectBalanceReturn { + balance: number +} + +// +// Client +// +export class Relayer implements Relayer { + protected hostname: string + protected fetch: Fetch + protected path = '/rpc/Relayer/' + + constructor(hostname: string, fetch: Fetch) { + this.hostname = hostname.replace(/\/*$/, '') + this.fetch = (input: RequestInfo, init?: RequestInit) => fetch(input, init) + } + + private url(name: string): string { + return this.hostname + this.path + name + } + + ping = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('Ping'), createHTTPRequest({}, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + status: _data.status, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + version = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('Version'), createHTTPRequest({}, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + version: _data.version, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + runtimeStatus = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('RuntimeStatus'), createHTTPRequest({}, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + status: _data.status, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getSequenceContext = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetSequenceContext'), createHTTPRequest({}, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + data: _data.data, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getChainID = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetChainID'), createHTTPRequest({}, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + chainID: _data.chainID, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + sendMetaTxn = (args: SendMetaTxnArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('SendMetaTxn'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + status: _data.status, + txnHash: _data.txnHash, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getMetaTxnNonce = ( + args: GetMetaTxnNonceArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('GetMetaTxnNonce'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + nonce: _data.nonce, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getMetaTxnReceipt = ( + args: GetMetaTxnReceiptArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('GetMetaTxnReceipt'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + receipt: _data.receipt, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + simulate = (args: SimulateArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('Simulate'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + results: >_data.results, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + simulateV3 = (args: SimulateV3Args, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('SimulateV3'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + results: >_data.results, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + updateMetaTxnGasLimits = ( + args: UpdateMetaTxnGasLimitsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('UpdateMetaTxnGasLimits'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + payload: _data.payload, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + feeTokens = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('FeeTokens'), createHTTPRequest({}, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + isFeeRequired: _data.isFeeRequired, + tokens: >_data.tokens, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + feeOptions = (args: FeeOptionsArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('FeeOptions'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + options: >_data.options, + sponsored: _data.sponsored, + quote: _data.quote, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getMetaTxnNetworkFeeOptions = ( + args: GetMetaTxnNetworkFeeOptionsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('GetMetaTxnNetworkFeeOptions'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + options: >_data.options, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getMetaTransactions = ( + args: GetMetaTransactionsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('GetMetaTransactions'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + page: _data.page, + transactions: >_data.transactions, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getTransactionCost = ( + args: GetTransactionCostArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('GetTransactionCost'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + cost: _data.cost, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + sentTransactions = ( + args: SentTransactionsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('SentTransactions'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + page: _data.page, + transactions: >_data.transactions, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + pendingTransactions = ( + args: PendingTransactionsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('PendingTransactions'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + page: _data.page, + transactions: >_data.transactions, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getGasTank = (args: GetGasTankArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetGasTank'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + gasTank: _data.gasTank, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + addGasTank = (args: AddGasTankArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('AddGasTank'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + status: _data.status, + gasTank: _data.gasTank, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + updateGasTank = (args: UpdateGasTankArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('UpdateGasTank'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + status: _data.status, + gasTank: _data.gasTank, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + nextGasTankBalanceAdjustmentNonce = ( + args: NextGasTankBalanceAdjustmentNonceArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('NextGasTankBalanceAdjustmentNonce'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + nonce: _data.nonce, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + adjustGasTankBalance = ( + args: AdjustGasTankBalanceArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('AdjustGasTankBalance'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + status: _data.status, + adjustment: _data.adjustment, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getGasTankBalanceAdjustment = ( + args: GetGasTankBalanceAdjustmentArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('GetGasTankBalanceAdjustment'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + adjustment: _data.adjustment, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + listGasTankBalanceAdjustments = ( + args: ListGasTankBalanceAdjustmentsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('ListGasTankBalanceAdjustments'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + page: _data.page, + adjustments: >_data.adjustments, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + listGasSponsors = ( + args: ListGasSponsorsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('ListGasSponsors'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + page: _data.page, + gasSponsors: >_data.gasSponsors, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getGasSponsor = (args: GetGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetGasSponsor'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + gasSponsor: _data.gasSponsor, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + addGasSponsor = (args: AddGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('AddGasSponsor'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + status: _data.status, + gasSponsor: _data.gasSponsor, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + updateGasSponsor = ( + args: UpdateGasSponsorArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('UpdateGasSponsor'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + status: _data.status, + gasSponsor: _data.gasSponsor, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + removeGasSponsor = ( + args: RemoveGasSponsorArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('RemoveGasSponsor'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + status: _data.status, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + addressGasSponsors = ( + args: AddressGasSponsorsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('AddressGasSponsors'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + page: _data.page, + gasSponsors: >_data.gasSponsors, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getProjectBalance = ( + args: GetProjectBalanceArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('GetProjectBalance'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + balance: _data.balance, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + adjustProjectBalance = ( + args: AdjustProjectBalanceArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('AdjustProjectBalance'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + balance: _data.balance, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } +} + +const createHTTPRequest = (body: object = {}, headers: object = {}, signal: AbortSignal | null = null): object => { + const reqHeaders: { [key: string]: string } = { ...headers, 'Content-Type': 'application/json' } + reqHeaders[WebrpcHeader] = WebrpcHeaderValue + + return { + method: 'POST', + headers: reqHeaders, + body: JSON.stringify(body || {}), + signal, + } +} + +const buildResponse = (res: Response): Promise => { + return res.text().then((text) => { + let data + try { + data = JSON.parse(text) + } catch (error) { + let message = '' + if (error instanceof Error) { + message = error.message + } + throw WebrpcBadResponseError.new({ + status: res.status, + cause: `JSON.parse(): ${message}: response text: ${text}`, + }) + } + if (!res.ok) { + const code: number = typeof data.code === 'number' ? data.code : 0 + throw (webrpcErrorByCode[code] || WebrpcError).new(data) + } + return data + }) +} + +// +// Errors +// + +export class WebrpcError extends Error { + name: string + code: number + message: string + status: number + cause?: string + + /** @deprecated Use message instead of msg. Deprecated in webrpc v0.11.0. */ + msg: string + + constructor(name: string, code: number, message: string, status: number, cause?: string) { + super(message) + this.name = name || 'WebrpcError' + this.code = typeof code === 'number' ? code : 0 + this.message = message || `endpoint error ${this.code}` + this.msg = this.message + this.status = typeof status === 'number' ? status : 0 + this.cause = cause + Object.setPrototypeOf(this, WebrpcError.prototype) + } + + static new(payload: any): WebrpcError { + return new this(payload.error, payload.code, payload.message || payload.msg, payload.status, payload.cause) + } +} + +// Webrpc errors + +export class WebrpcEndpointError extends WebrpcError { + constructor( + name: string = 'WebrpcEndpoint', + code: number = 0, + message: string = `endpoint error`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcEndpointError.prototype) + } +} + +export class WebrpcRequestFailedError extends WebrpcError { + constructor( + name: string = 'WebrpcRequestFailed', + code: number = -1, + message: string = `request failed`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcRequestFailedError.prototype) + } +} + +export class WebrpcBadRouteError extends WebrpcError { + constructor( + name: string = 'WebrpcBadRoute', + code: number = -2, + message: string = `bad route`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadRouteError.prototype) + } +} + +export class WebrpcBadMethodError extends WebrpcError { + constructor( + name: string = 'WebrpcBadMethod', + code: number = -3, + message: string = `bad method`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadMethodError.prototype) + } +} + +export class WebrpcBadRequestError extends WebrpcError { + constructor( + name: string = 'WebrpcBadRequest', + code: number = -4, + message: string = `bad request`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadRequestError.prototype) + } +} + +export class WebrpcBadResponseError extends WebrpcError { + constructor( + name: string = 'WebrpcBadResponse', + code: number = -5, + message: string = `bad response`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadResponseError.prototype) + } +} + +export class WebrpcServerPanicError extends WebrpcError { + constructor( + name: string = 'WebrpcServerPanic', + code: number = -6, + message: string = `server panic`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcServerPanicError.prototype) + } +} + +export class WebrpcInternalErrorError extends WebrpcError { + constructor( + name: string = 'WebrpcInternalError', + code: number = -7, + message: string = `internal error`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcInternalErrorError.prototype) + } +} + +export class WebrpcClientDisconnectedError extends WebrpcError { + constructor( + name: string = 'WebrpcClientDisconnected', + code: number = -8, + message: string = `client disconnected`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcClientDisconnectedError.prototype) + } +} + +export class WebrpcStreamLostError extends WebrpcError { + constructor( + name: string = 'WebrpcStreamLost', + code: number = -9, + message: string = `stream lost`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcStreamLostError.prototype) + } +} + +export class WebrpcStreamFinishedError extends WebrpcError { + constructor( + name: string = 'WebrpcStreamFinished', + code: number = -10, + message: string = `stream finished`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcStreamFinishedError.prototype) + } +} + +// Schema errors + +export class UnauthorizedError extends WebrpcError { + constructor( + name: string = 'Unauthorized', + code: number = 1000, + message: string = `Unauthorized access`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, UnauthorizedError.prototype) + } +} + +export class PermissionDeniedError extends WebrpcError { + constructor( + name: string = 'PermissionDenied', + code: number = 1001, + message: string = `Permission denied`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, PermissionDeniedError.prototype) + } +} + +export class SessionExpiredError extends WebrpcError { + constructor( + name: string = 'SessionExpired', + code: number = 1002, + message: string = `Session expired`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, SessionExpiredError.prototype) + } +} + +export class MethodNotFoundError extends WebrpcError { + constructor( + name: string = 'MethodNotFound', + code: number = 1003, + message: string = `Method not found`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, MethodNotFoundError.prototype) + } +} + +export class RequestConflictError extends WebrpcError { + constructor( + name: string = 'RequestConflict', + code: number = 1004, + message: string = `Conflict with target resource`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, RequestConflictError.prototype) + } +} + +export class AbortedError extends WebrpcError { + constructor( + name: string = 'Aborted', + code: number = 1005, + message: string = `Request aborted`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, AbortedError.prototype) + } +} + +export class GeoblockedError extends WebrpcError { + constructor( + name: string = 'Geoblocked', + code: number = 1006, + message: string = `Geoblocked region`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, GeoblockedError.prototype) + } +} + +export class RateLimitedError extends WebrpcError { + constructor( + name: string = 'RateLimited', + code: number = 1007, + message: string = `Rate-limited. Please slow down.`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, RateLimitedError.prototype) + } +} + +export class ProjectNotFoundError extends WebrpcError { + constructor( + name: string = 'ProjectNotFound', + code: number = 1008, + message: string = `Project not found`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, ProjectNotFoundError.prototype) + } +} + +export class AccessKeyNotFoundError extends WebrpcError { + constructor( + name: string = 'AccessKeyNotFound', + code: number = 1101, + message: string = `Access key not found`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, AccessKeyNotFoundError.prototype) + } +} + +export class AccessKeyMismatchError extends WebrpcError { + constructor( + name: string = 'AccessKeyMismatch', + code: number = 1102, + message: string = `Access key mismatch`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, AccessKeyMismatchError.prototype) + } +} + +export class InvalidOriginError extends WebrpcError { + constructor( + name: string = 'InvalidOrigin', + code: number = 1103, + message: string = `Invalid origin for Access Key`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, InvalidOriginError.prototype) + } +} + +export class InvalidServiceError extends WebrpcError { + constructor( + name: string = 'InvalidService', + code: number = 1104, + message: string = `Service not enabled for Access key`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, InvalidServiceError.prototype) + } +} + +export class UnauthorizedUserError extends WebrpcError { + constructor( + name: string = 'UnauthorizedUser', + code: number = 1105, + message: string = `Unauthorized user`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, UnauthorizedUserError.prototype) + } +} + +export class QuotaExceededError extends WebrpcError { + constructor( + name: string = 'QuotaExceeded', + code: number = 1200, + message: string = `Quota request exceeded`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, QuotaExceededError.prototype) + } +} + +export class QuotaRateLimitError extends WebrpcError { + constructor( + name: string = 'QuotaRateLimit', + code: number = 1201, + message: string = `Quota rate limit exceeded`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, QuotaRateLimitError.prototype) + } +} + +export class NoDefaultKeyError extends WebrpcError { + constructor( + name: string = 'NoDefaultKey', + code: number = 1300, + message: string = `No default access key found`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, NoDefaultKeyError.prototype) + } +} + +export class MaxAccessKeysError extends WebrpcError { + constructor( + name: string = 'MaxAccessKeys', + code: number = 1301, + message: string = `Access keys limit reached`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, MaxAccessKeysError.prototype) + } +} + +export class AtLeastOneKeyError extends WebrpcError { + constructor( + name: string = 'AtLeastOneKey', + code: number = 1302, + message: string = `You need at least one Access Key`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, AtLeastOneKeyError.prototype) + } +} + +export class TimeoutError extends WebrpcError { + constructor( + name: string = 'Timeout', + code: number = 1900, + message: string = `Request timed out`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, TimeoutError.prototype) + } +} + +export class InvalidArgumentError extends WebrpcError { + constructor( + name: string = 'InvalidArgument', + code: number = 2001, + message: string = `Invalid argument`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, InvalidArgumentError.prototype) + } +} + +export class UnavailableError extends WebrpcError { + constructor( + name: string = 'Unavailable', + code: number = 2002, + message: string = `Unavailable resource`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, UnavailableError.prototype) + } +} + +export class QueryFailedError extends WebrpcError { + constructor( + name: string = 'QueryFailed', + code: number = 2003, + message: string = `Query failed`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, QueryFailedError.prototype) + } +} + +export class NotFoundError extends WebrpcError { + constructor( + name: string = 'NotFound', + code: number = 3000, + message: string = `Resource not found`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, NotFoundError.prototype) + } +} + +export class InsufficientFeeError extends WebrpcError { + constructor( + name: string = 'InsufficientFee', + code: number = 3004, + message: string = `Insufficient fee`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, InsufficientFeeError.prototype) + } +} + +export class NotEnoughBalanceError extends WebrpcError { + constructor( + name: string = 'NotEnoughBalance', + code: number = 3005, + message: string = `Not enough balance`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, NotEnoughBalanceError.prototype) + } +} + +export class SimulationFailedError extends WebrpcError { + constructor( + name: string = 'SimulationFailed', + code: number = 3006, + message: string = `Simulation failed`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, SimulationFailedError.prototype) + } +} + +export enum errors { + WebrpcEndpoint = 'WebrpcEndpoint', + WebrpcRequestFailed = 'WebrpcRequestFailed', + WebrpcBadRoute = 'WebrpcBadRoute', + WebrpcBadMethod = 'WebrpcBadMethod', + WebrpcBadRequest = 'WebrpcBadRequest', + WebrpcBadResponse = 'WebrpcBadResponse', + WebrpcServerPanic = 'WebrpcServerPanic', + WebrpcInternalError = 'WebrpcInternalError', + WebrpcClientDisconnected = 'WebrpcClientDisconnected', + WebrpcStreamLost = 'WebrpcStreamLost', + WebrpcStreamFinished = 'WebrpcStreamFinished', + Unauthorized = 'Unauthorized', + PermissionDenied = 'PermissionDenied', + SessionExpired = 'SessionExpired', + MethodNotFound = 'MethodNotFound', + RequestConflict = 'RequestConflict', + Aborted = 'Aborted', + Geoblocked = 'Geoblocked', + RateLimited = 'RateLimited', + ProjectNotFound = 'ProjectNotFound', + AccessKeyNotFound = 'AccessKeyNotFound', + AccessKeyMismatch = 'AccessKeyMismatch', + InvalidOrigin = 'InvalidOrigin', + InvalidService = 'InvalidService', + UnauthorizedUser = 'UnauthorizedUser', + QuotaExceeded = 'QuotaExceeded', + QuotaRateLimit = 'QuotaRateLimit', + NoDefaultKey = 'NoDefaultKey', + MaxAccessKeys = 'MaxAccessKeys', + AtLeastOneKey = 'AtLeastOneKey', + Timeout = 'Timeout', + InvalidArgument = 'InvalidArgument', + Unavailable = 'Unavailable', + QueryFailed = 'QueryFailed', + NotFound = 'NotFound', + InsufficientFee = 'InsufficientFee', + NotEnoughBalance = 'NotEnoughBalance', + SimulationFailed = 'SimulationFailed', +} + +export enum WebrpcErrorCodes { + WebrpcEndpoint = 0, + WebrpcRequestFailed = -1, + WebrpcBadRoute = -2, + WebrpcBadMethod = -3, + WebrpcBadRequest = -4, + WebrpcBadResponse = -5, + WebrpcServerPanic = -6, + WebrpcInternalError = -7, + WebrpcClientDisconnected = -8, + WebrpcStreamLost = -9, + WebrpcStreamFinished = -10, + Unauthorized = 1000, + PermissionDenied = 1001, + SessionExpired = 1002, + MethodNotFound = 1003, + RequestConflict = 1004, + Aborted = 1005, + Geoblocked = 1006, + RateLimited = 1007, + ProjectNotFound = 1008, + AccessKeyNotFound = 1101, + AccessKeyMismatch = 1102, + InvalidOrigin = 1103, + InvalidService = 1104, + UnauthorizedUser = 1105, + QuotaExceeded = 1200, + QuotaRateLimit = 1201, + NoDefaultKey = 1300, + MaxAccessKeys = 1301, + AtLeastOneKey = 1302, + Timeout = 1900, + InvalidArgument = 2001, + Unavailable = 2002, + QueryFailed = 2003, + NotFound = 3000, + InsufficientFee = 3004, + NotEnoughBalance = 3005, + SimulationFailed = 3006, +} + +export const webrpcErrorByCode: { [code: number]: any } = { + [0]: WebrpcEndpointError, + [-1]: WebrpcRequestFailedError, + [-2]: WebrpcBadRouteError, + [-3]: WebrpcBadMethodError, + [-4]: WebrpcBadRequestError, + [-5]: WebrpcBadResponseError, + [-6]: WebrpcServerPanicError, + [-7]: WebrpcInternalErrorError, + [-8]: WebrpcClientDisconnectedError, + [-9]: WebrpcStreamLostError, + [-10]: WebrpcStreamFinishedError, + [1000]: UnauthorizedError, + [1001]: PermissionDeniedError, + [1002]: SessionExpiredError, + [1003]: MethodNotFoundError, + [1004]: RequestConflictError, + [1005]: AbortedError, + [1006]: GeoblockedError, + [1007]: RateLimitedError, + [1008]: ProjectNotFoundError, + [1101]: AccessKeyNotFoundError, + [1102]: AccessKeyMismatchError, + [1103]: InvalidOriginError, + [1104]: InvalidServiceError, + [1105]: UnauthorizedUserError, + [1200]: QuotaExceededError, + [1201]: QuotaRateLimitError, + [1300]: NoDefaultKeyError, + [1301]: MaxAccessKeysError, + [1302]: AtLeastOneKeyError, + [1900]: TimeoutError, + [2001]: InvalidArgumentError, + [2002]: UnavailableError, + [2003]: QueryFailedError, + [3000]: NotFoundError, + [3004]: InsufficientFeeError, + [3005]: NotEnoughBalanceError, + [3006]: SimulationFailedError, +} + +export type Fetch = (input: RequestInfo, init?: RequestInit) => Promise diff --git a/packages/services/relayer/test/preconditions/codec.test.ts b/packages/services/relayer/test/preconditions/codec.test.ts index a5ba279d39..88d442510a 100644 --- a/packages/services/relayer/test/preconditions/codec.test.ts +++ b/packages/services/relayer/test/preconditions/codec.test.ts @@ -36,8 +36,8 @@ describe('Preconditions Codec', () => { describe('decodePrecondition', () => { it('should return undefined for null/undefined input', () => { - expect(decodePrecondition(null as unknown as TransactionPrecondition)).toBeUndefined() - expect(decodePrecondition(undefined as unknown as TransactionPrecondition)).toBeUndefined() + expect(decodePrecondition(null as any)).toBeUndefined() + expect(decodePrecondition(undefined as any)).toBeUndefined() }) it('should decode native balance precondition with only min', () => { @@ -231,8 +231,8 @@ describe('Preconditions Codec', () => { it('should handle malformed addresses gracefully', () => { const intent: TransactionPrecondition = { type: 'native-balance', - ownerAddress: 'invalid-address', - tokenAddress: NATIVE_TOKEN_ADDRESS.toString(), + ownerAddress: 'invalid-address' as any, + tokenAddress: NATIVE_TOKEN_ADDRESS, chainId: ARBITRUM_CHAIN_ID, minAmount: BigInt('1000000000000000000'), } @@ -243,13 +243,13 @@ describe('Preconditions Codec', () => { }) it('should handle malformed BigInt values gracefully', () => { - const intent = { + const intent: TransactionPrecondition = { type: 'native-balance', - ownerAddress: TEST_ADDRESS.toString(), - tokenAddress: NATIVE_TOKEN_ADDRESS.toString(), + ownerAddress: TEST_ADDRESS, + tokenAddress: NATIVE_TOKEN_ADDRESS, chainId: ARBITRUM_CHAIN_ID, - minAmount: 'not-a-number', - } as unknown as TransactionPrecondition + minAmount: 'not-a-number' as any, + } const result = decodePrecondition(intent) expect(result).toBeUndefined() @@ -316,8 +316,8 @@ describe('Preconditions Codec', () => { }, { type: 'native-balance', - ownerAddress: 'invalid-address', - tokenAddress: NATIVE_TOKEN_ADDRESS.toString(), + ownerAddress: 'invalid-address' as any, + tokenAddress: NATIVE_TOKEN_ADDRESS, chainId: ARBITRUM_CHAIN_ID, minAmount: BigInt('1000000000000000000'), }, diff --git a/packages/services/relayer/test/preconditions/types.test.ts b/packages/services/relayer/test/preconditions/types.test.ts index a479676b58..a4ecda1d9d 100644 --- a/packages/services/relayer/test/preconditions/types.test.ts +++ b/packages/services/relayer/test/preconditions/types.test.ts @@ -179,7 +179,7 @@ describe('Preconditions Types', () => { TEST_ADDRESS, TOKEN_ADDRESS, OPERATOR_ADDRESS, - undefined as unknown as bigint, + undefined as any, ) const error = precondition.isValid() @@ -224,7 +224,7 @@ describe('Preconditions Types', () => { }) it('should validate tokenId is required', () => { - const precondition = new Erc721OwnershipPrecondition(TEST_ADDRESS, TOKEN_ADDRESS, undefined as unknown as bigint) + const precondition = new Erc721OwnershipPrecondition(TEST_ADDRESS, TOKEN_ADDRESS, undefined as any) const error = precondition.isValid() expect(error).toBeInstanceOf(Error) @@ -271,7 +271,7 @@ describe('Preconditions Types', () => { const precondition = new Erc721ApprovalPrecondition( TEST_ADDRESS, TOKEN_ADDRESS, - undefined as unknown as bigint, + undefined as any, OPERATOR_ADDRESS, ) @@ -319,7 +319,7 @@ describe('Preconditions Types', () => { }) it('should validate tokenId is required', () => { - const precondition = new Erc1155BalancePrecondition(TEST_ADDRESS, TOKEN_ADDRESS, undefined as unknown as bigint) + const precondition = new Erc1155BalancePrecondition(TEST_ADDRESS, TOKEN_ADDRESS, undefined as any) const error = precondition.isValid() expect(error).toBeInstanceOf(Error) @@ -402,7 +402,7 @@ describe('Preconditions Types', () => { const precondition = new Erc1155ApprovalPrecondition( TEST_ADDRESS, TOKEN_ADDRESS, - undefined as unknown as bigint, + undefined as any, OPERATOR_ADDRESS, 1000000n, ) @@ -432,7 +432,7 @@ describe('Preconditions Types', () => { TOKEN_ADDRESS, 123n, OPERATOR_ADDRESS, - undefined as unknown as bigint, + undefined as any, ) const error = precondition.isValid() diff --git a/packages/services/relayer/test/relayer/relayer.test.ts b/packages/services/relayer/test/relayer/relayer.test.ts index 028ccf32f0..5d4d029345 100644 --- a/packages/services/relayer/test/relayer/relayer.test.ts +++ b/packages/services/relayer/test/relayer/relayer.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it, vi, beforeEach } from 'vitest' import { Address, Hex } from 'ox' import { Network, Payload } from '@0xsequence/wallet-primitives' -import { Relayer, RpcRelayerGen } from '@0xsequence/relayer' +import { Relayer, RelayerGen } from '@0xsequence/relayer' // Test addresses and data const TEST_WALLET_ADDRESS = Address.from('0x1234567890123456789012345678901234567890') @@ -125,7 +125,7 @@ describe('Relayer', () => { symbol: 'ETH', decimals: 18, logoURL: 'https://example.com/eth.png', - type: 'NATIVE' as RpcRelayerGen.FeeTokenType, + type: 'NATIVE' as RelayerGen.FeeTokenType, contractAddress: undefined, }, to: TEST_TO_ADDRESS, @@ -308,7 +308,7 @@ describe('Relayer', () => { const isAvailable = await mockRelayer.isAvailable(TEST_WALLET_ADDRESS, TEST_CHAIN_ID) expect(isAvailable).toBe(true) - const feeOptions = await mockRelayer.feeOptions(TEST_WALLET_ADDRESS, TEST_CHAIN_ID, TEST_TO_ADDRESS, []) + const feeOptions = await mockRelayer.feeOptions(TEST_WALLET_ADDRESS, TEST_CHAIN_ID, []) expect(feeOptions.options).toEqual([]) const relayResult = await mockRelayer.relay(TEST_TO_ADDRESS, TEST_DATA, TEST_CHAIN_ID) @@ -317,7 +317,7 @@ describe('Relayer', () => { const statusResult = await mockRelayer.status(TEST_OP_HASH, TEST_CHAIN_ID) expect(statusResult.status).toBe('confirmed') - const preconditionResult = await mockRelayer.checkPrecondition({} as { type: string }) + const preconditionResult = await mockRelayer.checkPrecondition({} as any) expect(preconditionResult).toBe(true) }) }) diff --git a/packages/services/userdata/CHANGELOG.md b/packages/services/userdata/CHANGELOG.md index 9b41afaa04..139297551a 100644 --- a/packages/services/userdata/CHANGELOG.md +++ b/packages/services/userdata/CHANGELOG.md @@ -1,5 +1,11 @@ # @0xsequence/userdata +## 3.0.10 + +### Patch Changes + +- Minor network updates, relayer interface + ## 3.0.9 ### Patch Changes diff --git a/packages/services/userdata/package.json b/packages/services/userdata/package.json index bf0e184583..e546d8f223 100644 --- a/packages/services/userdata/package.json +++ b/packages/services/userdata/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/userdata", - "version": "3.0.9", + "version": "3.0.10", "description": "userdata sub-package for Sequence", "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/services/userdata", "author": "Sequence Platforms ULC", diff --git a/packages/services/userdata/src/index.ts b/packages/services/userdata/src/index.ts index 63b8559678..af76930fc8 100644 --- a/packages/services/userdata/src/index.ts +++ b/packages/services/userdata/src/index.ts @@ -1,6 +1,6 @@ -export * from './userdata.gen.js' +export * from './userdata.gen' -import { UserData as UserdataRpc } from './userdata.gen.js' +import { UserData as UserdataRpc } from './userdata.gen' export class SequenceUserdataClient extends UserdataRpc { constructor( @@ -15,7 +15,7 @@ export class SequenceUserdataClient extends UserdataRpc { _fetch = (input: RequestInfo, init?: RequestInit): Promise => { // automatically include jwt and access key auth header to requests // if its been set on the api client - const headers: Record = {} + const headers: { [key: string]: any } = {} const jwtAuth = this.jwtAuth const projectAccessKey = this.projectAccessKey diff --git a/packages/sessions/CHANGELOG.md b/packages/sessions/CHANGELOG.md new file mode 100644 index 0000000000..58cd4b18ec --- /dev/null +++ b/packages/sessions/CHANGELOG.md @@ -0,0 +1,1245 @@ +# @0xsequence/sessions + +## 2.0.0 + +### Major Changes + +- changeset + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@2.0.0 + - @0xsequence/migration@2.0.0 + - @0xsequence/replacer@2.0.0 + +## 1.10.14 + +### Patch Changes + +- network: add borne-testnet to allNetworks +- Updated dependencies + - @0xsequence/core@1.10.14 + - @0xsequence/migration@1.10.14 + - @0xsequence/replacer@1.10.14 + +## 1.10.13 + +### Patch Changes + +- network: add borne testnet +- Updated dependencies + - @0xsequence/core@1.10.13 + - @0xsequence/migration@1.10.13 + - @0xsequence/replacer@1.10.13 + +## 1.10.12 + +### Patch Changes + +- api: update bindings +- global/window -> globalThis +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.10.12 + - @0xsequence/migration@1.10.12 + - @0xsequence/replacer@1.10.12 + +## 1.10.11 + +### Patch Changes + +- waas: updated intent.gen without webrpc types, errors exported from authenticator.gen +- Updated dependencies + - @0xsequence/core@1.10.11 + - @0xsequence/migration@1.10.11 + - @0xsequence/replacer@1.10.11 + +## 1.10.10 + +### Patch Changes + +- metadata: update bindings with new contract collections api +- Updated dependencies + - @0xsequence/core@1.10.10 + - @0xsequence/migration@1.10.10 + - @0xsequence/replacer@1.10.10 + +## 1.10.9 + +### Patch Changes + +- waas minor update +- Updated dependencies + - @0xsequence/core@1.10.9 + - @0xsequence/migration@1.10.9 + - @0xsequence/replacer@1.10.9 + +## 1.10.8 + +### Patch Changes + +- update metadata bindings +- Updated dependencies + - @0xsequence/core@1.10.8 + - @0xsequence/migration@1.10.8 + - @0xsequence/replacer@1.10.8 + +## 1.10.7 + +### Patch Changes + +- minor fixes to waas client +- Updated dependencies + - @0xsequence/core@1.10.7 + - @0xsequence/migration@1.10.7 + - @0xsequence/replacer@1.10.7 + +## 1.10.6 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/core@1.10.6 + - @0xsequence/migration@1.10.6 + - @0xsequence/replacer@1.10.6 + +## 1.10.5 + +### Patch Changes + +- network: ape-chain-testnet -> apechain-testnet +- Updated dependencies + - @0xsequence/core@1.10.5 + - @0xsequence/migration@1.10.5 + - @0xsequence/replacer@1.10.5 + +## 1.10.4 + +### Patch Changes + +- network: add b3-sepolia, ape-chain-testnet, blast, blast-sepolia +- Updated dependencies + - @0xsequence/core@1.10.4 + - @0xsequence/migration@1.10.4 + - @0xsequence/replacer@1.10.4 + +## 1.10.3 + +### Patch Changes + +- typing fix +- Updated dependencies + - @0xsequence/core@1.10.3 + - @0xsequence/migration@1.10.3 + - @0xsequence/replacer@1.10.3 + +## 1.10.2 + +### Patch Changes + +- - waas: add getIdToken method + - indexer: update api client +- Updated dependencies + - @0xsequence/core@1.10.2 + - @0xsequence/migration@1.10.2 + - @0xsequence/replacer@1.10.2 + +## 1.10.1 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/core@1.10.1 + - @0xsequence/migration@1.10.1 + - @0xsequence/replacer@1.10.1 + +## 1.10.0 + +### Minor Changes + +- waas release v1.3.0 + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.10.0 + - @0xsequence/migration@1.10.0 + - @0xsequence/replacer@1.10.0 + +## 1.9.37 + +### Patch Changes + +- network: adds nativeToken data to NetworkMetadata constants +- Updated dependencies + - @0xsequence/core@1.9.37 + - @0xsequence/migration@1.9.37 + - @0xsequence/replacer@1.9.37 + +## 1.9.36 + +### Patch Changes + +- guard: export client +- Updated dependencies + - @0xsequence/core@1.9.36 + - @0xsequence/migration@1.9.36 + - @0xsequence/replacer@1.9.36 + +## 1.9.35 + +### Patch Changes + +- guard: update bindings +- Updated dependencies + - @0xsequence/core@1.9.35 + - @0xsequence/migration@1.9.35 + - @0xsequence/replacer@1.9.35 + +## 1.9.34 + +### Patch Changes + +- waas: always use lowercase email +- Updated dependencies + - @0xsequence/core@1.9.34 + - @0xsequence/migration@1.9.34 + - @0xsequence/replacer@1.9.34 + +## 1.9.33 + +### Patch Changes + +- waas: umd build +- Updated dependencies + - @0xsequence/core@1.9.33 + - @0xsequence/migration@1.9.33 + - @0xsequence/replacer@1.9.33 + +## 1.9.32 + +### Patch Changes + +- indexer: update bindings +- Updated dependencies + - @0xsequence/core@1.9.32 + - @0xsequence/migration@1.9.32 + - @0xsequence/replacer@1.9.32 + +## 1.9.31 + +### Patch Changes + +- metadata: token directory changes +- Updated dependencies + - @0xsequence/core@1.9.31 + - @0xsequence/migration@1.9.31 + - @0xsequence/replacer@1.9.31 + +## 1.9.30 + +### Patch Changes + +- update +- Updated dependencies + - @0xsequence/core@1.9.30 + - @0xsequence/migration@1.9.30 + - @0xsequence/replacer@1.9.30 + +## 1.9.29 + +### Patch Changes + +- disable gnosis chain +- Updated dependencies + - @0xsequence/core@1.9.29 + - @0xsequence/migration@1.9.29 + - @0xsequence/replacer@1.9.29 + +## 1.9.28 + +### Patch Changes + +- add utils/merkletree +- Updated dependencies + - @0xsequence/core@1.9.28 + - @0xsequence/migration@1.9.28 + - @0xsequence/replacer@1.9.28 + +## 1.9.27 + +### Patch Changes + +- network: optimistic -> optimism +- waas: remove defaults +- api, sessions: update bindings +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.9.27 + - @0xsequence/migration@1.9.27 + - @0xsequence/replacer@1.9.27 + +## 1.9.26 + +### Patch Changes + +- - add backend interfaces for pluggable interfaces + - introduce @0xsequence/react-native + - update pnpm to lockfile v9 +- Updated dependencies + - @0xsequence/core@1.9.26 + - @0xsequence/migration@1.9.26 + - @0xsequence/replacer@1.9.26 + +## 1.9.25 + +### Patch Changes + +- update webrpc clients with new error types +- Updated dependencies + - @0xsequence/core@1.9.25 + - @0xsequence/migration@1.9.25 + - @0xsequence/replacer@1.9.25 + +## 1.9.24 + +### Patch Changes + +- waas: add memoryStore backend to localStore +- Updated dependencies + - @0xsequence/core@1.9.24 + - @0xsequence/migration@1.9.24 + - @0xsequence/replacer@1.9.24 + +## 1.9.23 + +### Patch Changes + +- update api client bindings +- Updated dependencies + - @0xsequence/core@1.9.23 + - @0xsequence/migration@1.9.23 + - @0xsequence/replacer@1.9.23 + +## 1.9.22 + +### Patch Changes + +- update metadata client bindings +- Updated dependencies + - @0xsequence/core@1.9.22 + - @0xsequence/migration@1.9.22 + - @0xsequence/replacer@1.9.22 + +## 1.9.21 + +### Patch Changes + +- api client bindings +- Updated dependencies + - @0xsequence/core@1.9.21 + - @0xsequence/migration@1.9.21 + - @0xsequence/replacer@1.9.21 + +## 1.9.20 + +### Patch Changes + +- api client bindings update +- Updated dependencies + - @0xsequence/core@1.9.20 + - @0xsequence/migration@1.9.20 + - @0xsequence/replacer@1.9.20 + +## 1.9.19 + +### Patch Changes + +- waas update +- Updated dependencies + - @0xsequence/core@1.9.19 + - @0xsequence/migration@1.9.19 + - @0xsequence/replacer@1.9.19 + +## 1.9.18 + +### Patch Changes + +- provider: prohibit dangerous functions +- Updated dependencies + - @0xsequence/core@1.9.18 + - @0xsequence/migration@1.9.18 + - @0xsequence/replacer@1.9.18 + +## 1.9.17 + +### Patch Changes + +- network: add xr-sepolia +- Updated dependencies + - @0xsequence/core@1.9.17 + - @0xsequence/migration@1.9.17 + - @0xsequence/replacer@1.9.17 + +## 1.9.16 + +### Patch Changes + +- waas: sequence.feeOptions +- Updated dependencies + - @0xsequence/core@1.9.16 + - @0xsequence/migration@1.9.16 + - @0xsequence/replacer@1.9.16 + +## 1.9.15 + +### Patch Changes + +- metadata: collection external_link field name fix +- Updated dependencies + - @0xsequence/core@1.9.15 + - @0xsequence/migration@1.9.15 + - @0xsequence/replacer@1.9.15 + +## 1.9.14 + +### Patch Changes + +- network: astar-zkatana -> astar-zkyoto +- network: deprecate polygon mumbai network +- network: add xai and polygon amoy +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.9.14 + - @0xsequence/migration@1.9.14 + - @0xsequence/replacer@1.9.14 + +## 1.9.13 + +### Patch Changes + +- waas: fix @0xsequence/network dependency +- Updated dependencies + - @0xsequence/core@1.9.13 + - @0xsequence/migration@1.9.13 + - @0xsequence/replacer@1.9.13 + +## 1.9.12 + +### Patch Changes + +- indexer: update rpc bindings +- provider: signMessage: Serialize the BytesLike or string message into hexstring before sending +- waas: SessionAuthProof +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.9.12 + - @0xsequence/migration@1.9.12 + - @0xsequence/replacer@1.9.12 + +## 1.9.11 + +### Patch Changes + +- metdata, update rpc bindings +- Updated dependencies + - @0xsequence/core@1.9.11 + - @0xsequence/migration@1.9.11 + - @0xsequence/replacer@1.9.11 + +## 1.9.10 + +### Patch Changes + +- update metadata rpc bindings +- Updated dependencies + - @0xsequence/core@1.9.10 + - @0xsequence/migration@1.9.10 + - @0xsequence/replacer@1.9.10 + +## 1.9.9 + +### Patch Changes + +- metadata, add SequenceCollections rpc client +- Updated dependencies + - @0xsequence/core@1.9.9 + - @0xsequence/migration@1.9.9 + - @0xsequence/replacer@1.9.9 + +## 1.9.8 + +### Patch Changes + +- waas client update +- Updated dependencies + - @0xsequence/core@1.9.8 + - @0xsequence/migration@1.9.8 + - @0xsequence/replacer@1.9.8 + +## 1.9.7 + +### Patch Changes + +- update rpc client bindings for api, metadata and relayer +- Updated dependencies + - @0xsequence/core@1.9.7 + - @0xsequence/migration@1.9.7 + - @0xsequence/replacer@1.9.7 + +## 1.9.6 + +### Patch Changes + +- waas package update +- Updated dependencies + - @0xsequence/core@1.9.6 + - @0xsequence/migration@1.9.6 + - @0xsequence/replacer@1.9.6 + +## 1.9.5 + +### Patch Changes + +- RpcRelayer prioritize project access key +- Updated dependencies + - @0xsequence/core@1.9.5 + - @0xsequence/migration@1.9.5 + - @0xsequence/replacer@1.9.5 + +## 1.9.4 + +### Patch Changes + +- waas: fix network dependency +- Updated dependencies + - @0xsequence/core@1.9.4 + - @0xsequence/migration@1.9.4 + - @0xsequence/replacer@1.9.4 + +## 1.9.3 + +### Patch Changes + +- provider: don't append access key to RPC url if user has already provided it +- Updated dependencies + - @0xsequence/core@1.9.3 + - @0xsequence/migration@1.9.3 + - @0xsequence/replacer@1.9.3 + +## 1.9.2 + +### Patch Changes + +- network: add xai-sepolia +- Updated dependencies + - @0xsequence/core@1.9.2 + - @0xsequence/migration@1.9.2 + - @0xsequence/replacer@1.9.2 + +## 1.9.1 + +### Patch Changes + +- analytics fix +- Updated dependencies + - @0xsequence/core@1.9.1 + - @0xsequence/migration@1.9.1 + - @0xsequence/replacer@1.9.1 + +## 1.9.0 + +### Minor Changes + +- waas release + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.9.0 + - @0xsequence/migration@1.9.0 + - @0xsequence/replacer@1.9.0 + +## 1.8.8 + +### Patch Changes + +- update metadata bindings +- Updated dependencies + - @0xsequence/core@1.8.8 + - @0xsequence/migration@1.8.8 + - @0xsequence/replacer@1.8.8 + +## 1.8.7 + +### Patch Changes + +- provider: update databeat to 0.9.1 +- Updated dependencies + - @0xsequence/core@1.8.7 + - @0xsequence/migration@1.8.7 + - @0xsequence/replacer@1.8.7 + +## 1.8.6 + +### Patch Changes + +- guard: SignedOwnershipProof +- Updated dependencies + - @0xsequence/core@1.8.6 + - @0xsequence/migration@1.8.6 + - @0xsequence/replacer@1.8.6 + +## 1.8.5 + +### Patch Changes + +- guard: signOwnershipProof and isSignedOwnershipProof +- Updated dependencies + - @0xsequence/core@1.8.5 + - @0xsequence/migration@1.8.5 + - @0xsequence/replacer@1.8.5 + +## 1.8.4 + +### Patch Changes + +- network: add homeverse to networks list +- Updated dependencies + - @0xsequence/core@1.8.4 + - @0xsequence/migration@1.8.4 + - @0xsequence/replacer@1.8.4 + +## 1.8.3 + +### Patch Changes + +- api: introduce basic linked wallet support +- Updated dependencies + - @0xsequence/core@1.8.3 + - @0xsequence/migration@1.8.3 + - @0xsequence/replacer@1.8.3 + +## 1.8.2 + +### Patch Changes + +- provider: don't initialize analytics unless explicitly requested +- Updated dependencies + - @0xsequence/core@1.8.2 + - @0xsequence/migration@1.8.2 + - @0xsequence/replacer@1.8.2 + +## 1.8.1 + +### Patch Changes + +- update to analytics provider +- Updated dependencies + - @0xsequence/core@1.8.1 + - @0xsequence/migration@1.8.1 + - @0xsequence/replacer@1.8.1 + +## 1.8.0 + +### Minor Changes + +- provider: project analytics + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.8.0 + - @0xsequence/migration@1.8.0 + - @0xsequence/replacer@1.8.0 + +## 1.7.2 + +### Patch Changes + +- 0xsequence: ChainId should not be exported as a type +- account, wallet: fix nonce selection +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.7.2 + - @0xsequence/migration@1.7.2 + - @0xsequence/replacer@1.7.2 + +## 1.7.1 + +### Patch Changes + +- network: add missing avalanche logoURI +- Updated dependencies + - @0xsequence/core@1.7.1 + - @0xsequence/migration@1.7.1 + - @0xsequence/replacer@1.7.1 + +## 1.7.0 + +### Minor Changes + +- provider: projectAccessKey is now required + +### Patch Changes + +- network: add NetworkMetadata.logoURI property for all networks +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.7.0 + - @0xsequence/migration@1.7.0 + - @0xsequence/replacer@1.7.0 + +## 1.6.3 + +### Patch Changes + +- network list update +- Updated dependencies + - @0xsequence/core@1.6.3 + - @0xsequence/migration@1.6.3 + - @0xsequence/replacer@1.6.3 + +## 1.6.2 + +### Patch Changes + +- auth: projectAccessKey option +- wallet: use 12 bytes for random space +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.6.2 + - @0xsequence/migration@1.6.2 + - @0xsequence/replacer@1.6.2 + +## 1.6.1 + +### Patch Changes + +- core: add simple config from subdigest support +- core: fix encode tree with subdigest +- account: implement buildOnChainSignature on Account +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.6.1 + - @0xsequence/migration@1.6.1 + - @0xsequence/replacer@1.6.1 + +## 1.6.0 + +### Minor Changes + +- account, wallet: parallel transactions by default + +### Patch Changes + +- provider: emit disconnect on sign out +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.6.0 + - @0xsequence/migration@1.6.0 + - @0xsequence/replacer@1.6.0 + +## 1.5.0 + +### Minor Changes + +- signhub: add 'signing' signer status + +### Patch Changes + +- auth: Session.open: onAccountAddress callback +- account: allow empty transaction bundles +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.5.0 + - @0xsequence/migration@1.5.0 + - @0xsequence/replacer@1.5.0 + +## 1.4.9 + +### Patch Changes + +- rename SequenceMetadataClient to SequenceMetadata +- Updated dependencies + - @0xsequence/core@1.4.9 + - @0xsequence/migration@1.4.9 + - @0xsequence/replacer@1.4.9 + +## 1.4.8 + +### Patch Changes + +- account: Account.getSigners +- Updated dependencies + - @0xsequence/core@1.4.8 + - @0xsequence/migration@1.4.8 + - @0xsequence/replacer@1.4.8 + +## 1.4.7 + +### Patch Changes + +- update indexer client bindings +- Updated dependencies + - @0xsequence/core@1.4.7 + - @0xsequence/migration@1.4.7 + - @0xsequence/replacer@1.4.7 + +## 1.4.6 + +### Patch Changes + +- - add sepolia networks, mark goerli as deprecated + - update indexer client bindings +- Updated dependencies + - @0xsequence/core@1.4.6 + - @0xsequence/migration@1.4.6 + - @0xsequence/replacer@1.4.6 + +## 1.4.5 + +### Patch Changes + +- indexer/metadata: update client bindings +- auth: selectWallet with new address +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.4.5 + - @0xsequence/migration@1.4.5 + - @0xsequence/replacer@1.4.5 + +## 1.4.4 + +### Patch Changes + +- indexer: update bindings +- auth: handle jwt expiry +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.4.4 + - @0xsequence/migration@1.4.4 + - @0xsequence/replacer@1.4.4 + +## 1.4.3 + +### Patch Changes + +- guard: return active status from GuardSigner.getAuthMethods +- Updated dependencies + - @0xsequence/core@1.4.3 + - @0xsequence/migration@1.4.3 + - @0xsequence/replacer@1.4.3 + +## 1.4.2 + +### Patch Changes + +- guard: update bindings +- Updated dependencies + - @0xsequence/core@1.4.2 + - @0xsequence/migration@1.4.2 + - @0xsequence/replacer@1.4.2 + +## 1.4.1 + +### Patch Changes + +- network: remove unused networks +- signhub: orchestrator interface +- guard: auth methods interface +- guard: update bindings for pin and totp +- guard: no more retry logic +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.4.1 + - @0xsequence/migration@1.4.1 + - @0xsequence/replacer@1.4.1 + +## 1.4.0 + +### Minor Changes + +- project access key support + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.4.0 + - @0xsequence/migration@1.4.0 + - @0xsequence/replacer@1.4.0 + +## 1.3.0 + +### Minor Changes + +- signhub: account children + +### Patch Changes + +- guard: do not throw when building deploy transaction +- network: snowtrace.io -> subnets.avax.network/c-chain +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.3.0 + - @0xsequence/migration@1.3.0 + - @0xsequence/replacer@1.3.0 + +## 1.2.9 + +### Patch Changes + +- account: AccountSigner.sendTransaction simulateForFeeOptions +- relayer: update bindings +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.2.9 + - @0xsequence/migration@1.2.9 + - @0xsequence/replacer@1.2.9 + +## 1.2.8 + +### Patch Changes + +- rename X-Sequence-Token-Key header to X-Access-Key +- Updated dependencies + - @0xsequence/core@1.2.8 + - @0xsequence/migration@1.2.8 + - @0xsequence/replacer@1.2.8 + +## 1.2.7 + +### Patch Changes + +- add x-sequence-token-key to clients +- Updated dependencies + - @0xsequence/core@1.2.7 + - @0xsequence/migration@1.2.7 + - @0xsequence/replacer@1.2.7 + +## 1.2.6 + +### Patch Changes + +- Fix bind multicall provider +- Updated dependencies + - @0xsequence/core@1.2.6 + - @0xsequence/migration@1.2.6 + - @0xsequence/replacer@1.2.6 + +## 1.2.5 + +### Patch Changes + +- Multicall default configuration fixes +- Updated dependencies + - @0xsequence/core@1.2.5 + - @0xsequence/migration@1.2.5 + - @0xsequence/replacer@1.2.5 + +## 1.2.4 + +### Patch Changes + +- provider: Adding missing payment provider types to PaymentProviderOption +- provider: WalletRequestHandler.notifyChainChanged +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.2.4 + - @0xsequence/migration@1.2.4 + - @0xsequence/replacer@1.2.4 + +## 1.2.3 + +### Patch Changes + +- auth, provider: connect to accept optional authorizeNonce +- Updated dependencies + - @0xsequence/core@1.2.3 + - @0xsequence/migration@1.2.3 + - @0xsequence/replacer@1.2.3 + +## 1.2.2 + +### Patch Changes + +- provider: allow createContract calls +- core: check for explicit zero address in contract deployments +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.2.2 + - @0xsequence/migration@1.2.2 + - @0xsequence/replacer@1.2.2 + +## 1.2.1 + +### Patch Changes + +- auth: use sequence api chain id as reference chain id if available +- Updated dependencies + - @0xsequence/core@1.2.1 + - @0xsequence/migration@1.2.1 + - @0xsequence/replacer@1.2.1 + +## 1.2.0 + +### Minor Changes + +- split services from session, better local support + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.2.0 + - @0xsequence/migration@1.2.0 + - @0xsequence/replacer@1.2.0 + +## 1.1.15 + +### Patch Changes + +- guard: remove error filtering +- Updated dependencies + - @0xsequence/core@1.1.15 + - @0xsequence/migration@1.1.15 + - @0xsequence/replacer@1.1.15 + +## 1.1.14 + +### Patch Changes + +- guard: add GuardSigner.onError +- Updated dependencies + - @0xsequence/core@1.1.14 + - @0xsequence/migration@1.1.14 + - @0xsequence/replacer@1.1.14 + +## 1.1.13 + +### Patch Changes + +- provider: pass client version with connect options +- provider: removing large from BannerSize +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.1.13 + - @0xsequence/migration@1.1.13 + - @0xsequence/replacer@1.1.13 + +## 1.1.12 + +### Patch Changes + +- provider: adding bannerSize to ConnectOptions +- Updated dependencies + - @0xsequence/core@1.1.12 + - @0xsequence/migration@1.1.12 + - @0xsequence/replacer@1.1.12 + +## 1.1.11 + +### Patch Changes + +- add homeverse configs +- Updated dependencies + - @0xsequence/core@1.1.11 + - @0xsequence/migration@1.1.11 + - @0xsequence/replacer@1.1.11 + +## 1.1.10 + +### Patch Changes + +- handle default EIP6492 on send +- Updated dependencies + - @0xsequence/core@1.1.10 + - @0xsequence/migration@1.1.10 + - @0xsequence/replacer@1.1.10 + +## 1.1.9 + +### Patch Changes + +- Custom default EIP6492 on client +- Updated dependencies + - @0xsequence/core@1.1.9 + - @0xsequence/migration@1.1.9 + - @0xsequence/replacer@1.1.9 + +## 1.1.8 + +### Patch Changes + +- metadata: searchMetadata: add types filter +- Updated dependencies + - @0xsequence/core@1.1.8 + - @0xsequence/migration@1.1.8 + - @0xsequence/replacer@1.1.8 + +## 1.1.7 + +### Patch Changes + +- adding signInWith connect settings option to allow dapps to automatically login their users with a certain provider optimizing the normal authentication flow +- Updated dependencies + - @0xsequence/core@1.1.7 + - @0xsequence/migration@1.1.7 + - @0xsequence/replacer@1.1.7 + +## 1.1.6 + +### Patch Changes + +- metadata: searchMetadata: add chainID and excludeTokenMetadata filters +- Updated dependencies + - @0xsequence/core@1.1.6 + - @0xsequence/migration@1.1.6 + - @0xsequence/replacer@1.1.6 + +## 1.1.5 + +### Patch Changes + +- account: re-compute meta-transaction id for wallet deployment transactions +- Updated dependencies + - @0xsequence/core@1.1.5 + - @0xsequence/migration@1.1.5 + - @0xsequence/replacer@1.1.5 + +## 1.1.4 + +### Patch Changes + +- network: rename base-mainnet to base +- provider: override isDefaultChain with ConnectOptions.networkId if provided +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.1.4 + - @0xsequence/migration@1.1.4 + - @0xsequence/replacer@1.1.4 + +## 1.1.3 + +### Patch Changes + +- provider: use network id from transport session +- provider: sign authorization using ConnectOptions.networkId if provided +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.1.3 + - @0xsequence/migration@1.1.3 + - @0xsequence/replacer@1.1.3 + +## 1.1.2 + +### Patch Changes + +- provider: jsonrpc chain id fixes +- Updated dependencies + - @0xsequence/core@1.1.2 + - @0xsequence/migration@1.1.2 + - @0xsequence/replacer@1.1.2 + +## 1.1.1 + +### Patch Changes + +- network: add base mainnet and sepolia +- provider: reject toxic transaction requests +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.1.1 + - @0xsequence/migration@1.1.1 + - @0xsequence/replacer@1.1.1 + +## 1.1.0 + +### Minor Changes + +- Refactor dapp facing provider + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.1.0 + - @0xsequence/migration@1.1.0 + - @0xsequence/replacer@1.1.0 + +## 1.0.5 + +### Patch Changes + +- network: export network constants +- guard: use the correct global for fetch +- network: nova-explorer.arbitrum.io -> nova.arbiscan.io +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.0.5 + - @0xsequence/migration@1.0.5 + - @0xsequence/replacer@1.0.5 + +## 1.0.4 + +### Patch Changes + +- provider: accept name or number for networkId +- Updated dependencies + - @0xsequence/core@1.0.4 + - @0xsequence/migration@1.0.4 + - @0xsequence/replacer@1.0.4 + +## 1.0.3 + +### Patch Changes + +- Simpler isValidSignature helpers +- Updated dependencies + - @0xsequence/core@1.0.3 + - @0xsequence/migration@1.0.3 + - @0xsequence/replacer@1.0.3 + +## 1.0.2 + +### Patch Changes + +- add extra signature validation utils methods +- Updated dependencies + - @0xsequence/core@1.0.2 + - @0xsequence/migration@1.0.2 + - @0xsequence/replacer@1.0.2 + +## 1.0.1 + +### Patch Changes + +- add homeverse testnet +- Updated dependencies + - @0xsequence/core@1.0.1 + - @0xsequence/migration@1.0.1 + - @0xsequence/replacer@1.0.1 + +## 1.0.0 + +### Major Changes + +- https://sequence.xyz/blog/sequence-wallet-light-state-sync-full-merkle-wallets + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.0.0 + - @0xsequence/migration@1.0.0 + - @0xsequence/replacer@1.0.0 diff --git a/packages/sessions/hardhat.config.js b/packages/sessions/hardhat.config.js new file mode 100644 index 0000000000..51bc6d710b --- /dev/null +++ b/packages/sessions/hardhat.config.js @@ -0,0 +1,11 @@ + +module.exports = { + networks: { + hardhat: { + chainId: 31337, + accounts: { + mnemonic: 'ripple axis someone ridge uniform wrist prosper there frog rate olympic knee' + }, + }, + } +} diff --git a/packages/sessions/package.json b/packages/sessions/package.json new file mode 100644 index 0000000000..031e1f0519 --- /dev/null +++ b/packages/sessions/package.json @@ -0,0 +1,34 @@ +{ + "name": "@0xsequence/sessions", + "version": "2.0.0", + "description": "tools for migrating sequence wallets to new versions", + "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/sessions", + "source": "src/index.ts", + "main": "dist/0xsequence-sessions.cjs.js", + "module": "dist/0xsequence-sessions.esm.js", + "author": "Horizon Blockchain Games", + "license": "Apache-2.0", + "scripts": { + "test": "pnpm test:file tests/**/*.spec.ts", + "test:file": "TS_NODE_PROJECT=../../tsconfig.test.json mocha -r ts-node/register --timeout 30000", + "test:coverage": "nyc pnpm test" + }, + "dependencies": { + "@0xsequence/core": "workspace:*", + "@0xsequence/migration": "workspace:*", + "@0xsequence/replacer": "workspace:*", + "ethers": "^5.5.2", + "idb": "^7.1.1" + }, + "devDependencies": { + "@0xsequence/signhub": "workspace:*", + "@0xsequence/tests": "workspace:*", + "@istanbuljs/nyc-config-typescript": "^1.0.2", + "fake-indexeddb": "^4.0.1", + "nyc": "^15.1.0" + }, + "files": [ + "src", + "dist" + ] +} diff --git a/packages/sessions/src/index.ts b/packages/sessions/src/index.ts new file mode 100644 index 0000000000..76ee95e53a --- /dev/null +++ b/packages/sessions/src/index.ts @@ -0,0 +1,2 @@ +export * as tracker from './tracker' +export * as trackers from './trackers' diff --git a/packages/sessions/src/tracker.ts b/packages/sessions/src/tracker.ts new file mode 100644 index 0000000000..2ba3373395 --- /dev/null +++ b/packages/sessions/src/tracker.ts @@ -0,0 +1,56 @@ +import { commons } from '@0xsequence/core' +import { ethers } from 'ethers' + +export type PresignedConfig = { + wallet: string + nextConfig: commons.config.Config + signature: string +} + +export type PresignedConfigLink = Omit & { nextImageHash: string } + +export type ConfigDataDump = { + configurations: commons.config.Config[] + wallets: { + imageHash: string + context: commons.context.WalletContext + }[] + presignedTransactions: PresignedConfigLink[] +} + +export abstract class ConfigTracker { + loadPresignedConfiguration: (args: { + wallet: string + fromImageHash: string + longestPath?: boolean + }) => Promise + + savePresignedConfiguration: (args: PresignedConfig) => Promise + + saveWitnesses: (args: { wallet: string; digest: string; chainId: ethers.BigNumberish; signatures: string[] }) => Promise + + configOfImageHash: (args: { imageHash: string; noCache?: boolean }) => Promise + + saveWalletConfig: (args: { config: commons.config.Config }) => Promise + + imageHashOfCounterfactualWallet: (args: { wallet: string; noCache?: boolean }) => Promise< + | { + imageHash: string + context: commons.context.WalletContext + } + | undefined + > + + saveCounterfactualWallet: (args: { config: commons.config.Config; context: commons.context.WalletContext[] }) => Promise + + walletsOfSigner: (args: { signer: string; noCache?: boolean }) => Promise< + { + wallet: string + proof: { + digest: string + chainId: ethers.BigNumber + signature: string + } + }[] + > +} diff --git a/packages/sessions/src/trackers/cached.ts b/packages/sessions/src/trackers/cached.ts new file mode 100644 index 0000000000..e1bc447688 --- /dev/null +++ b/packages/sessions/src/trackers/cached.ts @@ -0,0 +1,186 @@ +import { commons, universal } from '@0xsequence/core' +import { migrator } from '@0xsequence/migration' +import { ethers } from 'ethers' +import { ConfigTracker, PresignedConfig, PresignedConfigLink } from '../tracker' + +export class CachedTracker implements migrator.PresignedMigrationTracker, ConfigTracker { + constructor( + private readonly tracker: migrator.PresignedMigrationTracker & ConfigTracker, + private readonly cache: migrator.PresignedMigrationTracker & ConfigTracker, + public readonly contexts: commons.context.VersionedContext + ) {} + + async loadPresignedConfiguration(args: { + wallet: string + fromImageHash: string + longestPath?: boolean | undefined + }): Promise { + // We need to check both, and return the one with the highest checkpoint + // eventually we could try to combine them, but for now we'll just return + // the one with the highest checkpoint + const results = [this.tracker.loadPresignedConfiguration(args), this.cache.loadPresignedConfiguration(args)] + + let best: PresignedConfigLink[] + + // If both results end with the same image hash, we can just return the longest/shortest one + const [result1, result2] = await Promise.all(results) + if ( + result1.length > 0 && + result2.length > 0 && + result1[result1.length - 1].nextImageHash === result2[result2.length - 1].nextImageHash + ) { + best = + args.longestPath === true + ? result1.length > result2.length + ? result1 + : result2 + : result1.length < result2.length + ? result1 + : result2 + } else { + // Otherwise we need to check the checkpoints + // this requires us to fetch the config for each image hash + const checkpoints = await Promise.all( + results.map(async result => { + const r = await result + const last = r[r.length - 1] + if (!last) return undefined + + // TODO: This will fire a lot of requests, optimize it + const config = await this.configOfImageHash({ imageHash: last.nextImageHash }) + if (!config) return undefined + + return { checkpoint: universal.genericCoderFor(config.version).config.checkpointOf(config), result: r } + }) + ) + + best = + checkpoints.reduce((acc, val) => { + if (!val) return acc + if (!acc) return val + if (val.checkpoint.gt(acc.checkpoint)) return val + return acc + })?.result ?? [] + } + + if (!best) return [] + + return best + } + + async savePresignedConfiguration(args: PresignedConfig): Promise { + await Promise.all([this.tracker.savePresignedConfiguration(args), this.cache.savePresignedConfiguration(args)]) + } + + async configOfImageHash(args: { imageHash: string; noCache?: boolean }): Promise { + // We first check the cache, if it's not there, we check the tracker + // and then we save it to the cache + if (args.noCache !== true) { + const config = await this.cache.configOfImageHash(args) + if (config) return config + } + + const config2 = await this.tracker.configOfImageHash(args) + if (config2) { + await this.cache.saveWalletConfig({ config: config2 }) + } + + return config2 + } + + async saveWalletConfig(args: { config: commons.config.Config }): Promise { + await Promise.all([this.tracker.saveWalletConfig(args), this.cache.saveWalletConfig(args)]) + } + + async imageHashOfCounterfactualWallet(args: { + wallet: string + noCache?: boolean + }): Promise<{ imageHash: string; context: commons.context.WalletContext } | undefined> { + // We first check the cache, if it's not there, we check the tracker + // and then we save it to the cache + if (args.noCache !== true) { + const result1 = await this.cache.imageHashOfCounterfactualWallet(args) + if (result1) return result1 + } + + const result2 = await this.tracker.imageHashOfCounterfactualWallet(args) + if (result2) { + // TODO: We shouldn't need to get the config to save the counterfactual wallet + const config = await this.configOfImageHash({ imageHash: result2.imageHash }) + if (config) { + await this.cache.saveCounterfactualWallet({ config, context: [result2.context] }) + } + } + + return result2 + } + + async saveCounterfactualWallet(args: { + config: commons.config.Config + context: commons.context.WalletContext[] + }): Promise { + await Promise.all([this.tracker.saveCounterfactualWallet(args), this.cache.saveCounterfactualWallet(args)]) + } + + async walletsOfSigner(args: { + signer: string + noCache?: boolean + }): Promise<{ wallet: string; proof: { digest: string; chainId: ethers.BigNumber; signature: string } }[]> { + if (args.noCache) { + return this.tracker.walletsOfSigner(args) + } + + // In this case we need to both aggregate the results from the cache and the tracker + // and then dedupe the results + const results = await Promise.all([this.tracker.walletsOfSigner(args), this.cache.walletsOfSigner(args)]) + const wallets = new Map() + + for (const result of results) { + for (const wallet of result) { + wallets.set(wallet.wallet, wallet) + } + } + + return Array.from(wallets.values()) + } + + async saveWitnesses(args: { + wallet: string + digest: string + chainId: ethers.BigNumberish + signatures: string[] + }): Promise { + await Promise.all([this.tracker.saveWitnesses(args), this.cache.saveWitnesses(args)]) + } + + async getMigration( + address: string, + fromImageHash: string, + fromVersion: number, + chainId: ethers.BigNumberish + ): Promise { + // We first check the cache, if it's not there, we check the tracker + // NOTICE: we could eventually try to combine the two, but now we just have 1 migration + // so it's not worth it. + const migration1 = await this.cache.getMigration(address, fromImageHash, fromVersion, chainId) + if (migration1) return migration1 + + const migration2 = await this.tracker.getMigration(address, fromImageHash, fromVersion, chainId) + if (migration2) { + await this.cache.saveMigration(address, migration2, this.contexts) + } + + return migration2 + } + + async saveMigration( + address: string, + signed: migrator.SignedMigration, + contexts: commons.context.VersionedContext + ): Promise { + await Promise.all([ + this.tracker.saveMigration(address, signed, contexts), + this.cache.saveMigration(address, signed, contexts) + ]) + } +} diff --git a/packages/sessions/src/trackers/debug.ts b/packages/sessions/src/trackers/debug.ts new file mode 100644 index 0000000000..3a7d8bfa96 --- /dev/null +++ b/packages/sessions/src/trackers/debug.ts @@ -0,0 +1,96 @@ +import { commons } from '@0xsequence/core' +import { migrator } from '@0xsequence/migration' +import { ethers } from 'ethers' +import { ConfigTracker, PresignedConfig, PresignedConfigLink } from '../tracker' + +export class DebugConfigTracker implements ConfigTracker, migrator.PresignedMigrationTracker { + constructor(private readonly tracker: ConfigTracker & migrator.PresignedMigrationTracker) {} + + async loadPresignedConfiguration(args: { + wallet: string + fromImageHash: string + longestPath?: boolean + }): Promise { + console.debug('? loadPresignedConfiguration') + debug(args, '? ') + return debug(await this.tracker.loadPresignedConfiguration(args), '! ') + } + + savePresignedConfiguration(args: PresignedConfig): Promise { + console.debug('? savePresignedConfiguration') + debug(args, '? ') + return this.tracker.savePresignedConfiguration(args) + } + + saveWitnesses(args: { wallet: string; digest: string; chainId: ethers.BigNumberish; signatures: string[] }): Promise { + console.debug('? saveWitnesses') + debug(args, '? ') + return this.tracker.saveWitnesses(args) + } + + async configOfImageHash(args: { imageHash: string }): Promise { + console.debug('? configOfImageHash') + debug(args, '? ') + return debug(await this.tracker.configOfImageHash(args), '! ') + } + + saveWalletConfig(args: { config: commons.config.Config }): Promise { + console.debug('? saveWalletConfig') + debug(args, '? ') + return this.tracker.saveWalletConfig(args) + } + + async imageHashOfCounterfactualWallet(args: { + wallet: string + }): Promise<{ imageHash: string; context: commons.context.WalletContext } | undefined> { + console.debug('? imageHashOfCounterfactualWallet') + debug(args, '? ') + return debug(await this.tracker.imageHashOfCounterfactualWallet(args), '! ') + } + + saveCounterfactualWallet(args: { config: commons.config.Config; context: commons.context.WalletContext[] }): Promise { + console.debug('? saveCounterfactualWallet') + debug(args, '? ') + return this.tracker.saveCounterfactualWallet(args) + } + + async walletsOfSigner(args: { + signer: string + }): Promise<{ wallet: string; proof: { digest: string; chainId: ethers.BigNumber; signature: string } }[]> { + console.debug('? walletsOfSigner') + debug(args, '? ') + return debug(await this.tracker.walletsOfSigner(args), '! ') + } + + async getMigration( + address: string, + fromImageHash: string, + fromVersion: number, + chainId: ethers.BigNumberish + ): Promise { + console.debug('? getMigration') + debug({ address, fromImageHash, fromVersion, chainId }, '? ') + return debug(await this.tracker.getMigration(address, fromImageHash, fromVersion, chainId), '! ') + } + + saveMigration(address: string, signed: migrator.SignedMigration, contexts: commons.context.VersionedContext): Promise { + console.debug('? saveMigration') + debug({ address, signed, contexts }, '? ') + return this.tracker.saveMigration(address, signed, contexts) + } +} + +function debug(value: T, prefix: string = ''): T { + switch (value) { + case undefined: + console.debug(prefix + 'undefined') + break + default: + JSON.stringify(value, undefined, 2) + .split('\n') + .map(line => prefix + line) + .forEach(line => console.debug(line)) + break + } + return value +} diff --git a/packages/sessions/src/trackers/deduped.ts b/packages/sessions/src/trackers/deduped.ts new file mode 100644 index 0000000000..c8246df85d --- /dev/null +++ b/packages/sessions/src/trackers/deduped.ts @@ -0,0 +1,99 @@ +import { commons } from '@0xsequence/core' +import { migrator } from '@0xsequence/migration' +import { BigNumber, BigNumberish, ethers } from 'ethers' +import { ConfigTracker, PresignedConfig, PresignedConfigLink } from '../tracker' +import { PromiseCache } from './promise-cache' +import { LocalConfigTracker } from './local' + +export function isDedupedTracker(tracker: any): tracker is DedupedTracker { + return tracker instanceof DedupedTracker +} + +// This tracks wraps another tracker and dedupes calls to it, so in any calls +// are sent in short succession, only the first call is forwarded to the +// underlying tracker, and the rest are ignored. +export class DedupedTracker implements migrator.PresignedMigrationTracker, ConfigTracker { + private cache: PromiseCache = new PromiseCache() + + constructor( + private readonly tracker: migrator.PresignedMigrationTracker & ConfigTracker, + public readonly window = 50, + public verbose = false + ) {} + + invalidateCache() { + this.cache = new PromiseCache() + } + + configOfImageHash(args: { imageHash: string }): Promise { + return this.cache.do('configOfImageHash', this.window, args => this.tracker.configOfImageHash(args), args) + } + + getMigration( + address: string, + fromImageHash: string, + fromVersion: number, + chainId: BigNumberish + ): Promise { + return this.cache.do( + 'getMigration', + this.window, + (...args) => this.tracker.getMigration(...args), + address, + fromImageHash, + fromVersion, + chainId + ) + } + + saveMigration(address: string, signed: migrator.SignedMigration, contexts: commons.context.VersionedContext): Promise { + return this.cache.do('saveMigration', undefined, (...args) => this.tracker.saveMigration(...args), address, signed, contexts) + } + + loadPresignedConfiguration(args: { + wallet: string + fromImageHash: string + longestPath?: boolean | undefined + }): Promise { + return this.cache.do('loadPresignedConfiguration', this.window, args => this.tracker.loadPresignedConfiguration(args), args) + } + + savePresignedConfiguration(args: PresignedConfig): Promise { + return this.cache.do('savePresignedConfiguration', undefined, args => this.tracker.savePresignedConfiguration(args), args) + } + + saveWitnesses(args: { wallet: string; digest: string; chainId: BigNumberish; signatures: string[] }): Promise { + return this.cache.do('saveWitnesses', undefined, args => this.tracker.saveWitnesses(args), args) + } + + saveWalletConfig(args: { config: commons.config.Config }): Promise { + return this.cache.do('saveWalletConfig', undefined, args => this.tracker.saveWalletConfig(args), args) + } + + imageHashOfCounterfactualWallet(args: { + wallet: string + }): Promise<{ imageHash: string; context: commons.context.WalletContext } | undefined> { + return this.cache.do( + 'imageHashOfCounterfactualWallet', + undefined, + args => this.tracker.imageHashOfCounterfactualWallet(args), + args + ) + } + + saveCounterfactualWallet(args: { config: commons.config.Config; context: commons.context.WalletContext[] }): Promise { + return this.cache.do('saveCounterfactualWallet', undefined, args => this.tracker.saveCounterfactualWallet(args), args) + } + + walletsOfSigner(args: { + signer: string + }): Promise<{ wallet: string; proof: { digest: string; chainId: BigNumber; signature: string } }[]> { + return this.cache.do('walletsOfSigner', this.window, args => this.tracker.walletsOfSigner(args), args) + } + + updateProvider(provider: ethers.providers.Provider) { + if (this.tracker instanceof LocalConfigTracker) { + this.tracker.updateProvider(provider) + } + } +} diff --git a/packages/sessions/src/trackers/index.ts b/packages/sessions/src/trackers/index.ts new file mode 100644 index 0000000000..05dddeb00f --- /dev/null +++ b/packages/sessions/src/trackers/index.ts @@ -0,0 +1,7 @@ +export * as debug from './debug' +export * as local from './local' +export * as remote from './remote' +export * as stores from './stores' +export * from './multiple' +export * from './cached' +export * from './deduped' diff --git a/packages/sessions/src/trackers/local.ts b/packages/sessions/src/trackers/local.ts new file mode 100644 index 0000000000..9d78cf47a9 --- /dev/null +++ b/packages/sessions/src/trackers/local.ts @@ -0,0 +1,594 @@ +import { commons, universal, v1, v2 } from '@0xsequence/core' +import { migration, migrator } from '@0xsequence/migration' +import { ethers } from 'ethers' +import { CachedEIP5719 } from '@0xsequence/replacer' +import { ConfigTracker, PresignedConfig, PresignedConfigLink } from '../tracker' +import { isPlainNested, isPlainNode, isPlainV2Config, MemoryTrackerStore, PlainNested, PlainNode, TrackerStore } from './stores' + +export class LocalConfigTracker implements ConfigTracker, migrator.PresignedMigrationTracker { + private cachedEIP5719: CachedEIP5719 + + constructor( + // TODO: The provider is only used to determine that EIP1271 signatures have *some* validity + // but when reconstructing a presigned transaction we should do the replacement once per chain. + // For now, it's recommended to use Mainnet as the provider. + public provider: ethers.providers.Provider, + private store: TrackerStore = new MemoryTrackerStore(), + public useEIP5719: boolean = false + ) { + this.cachedEIP5719 = new CachedEIP5719(provider) + } + + private loadTopology = async (hash: string): Promise => { + const node = await this.store.loadV2Node(hash) + if (!node) return { nodeHash: hash } + + if (isPlainNode(node)) { + const [left, right] = await Promise.all([this.loadTopology(node.left), this.loadTopology(node.right)]) + return { left, right } + } + + if (isPlainNested(node)) { + return { + weight: ethers.BigNumber.from(node.weight), + threshold: ethers.BigNumber.from(node.threshold), + tree: await this.loadTopology(node.tree) + } + } + + return node + } + + private saveTopology = async (node: v2.config.Topology): Promise => { + if (v2.config.isNodeLeaf(node)) { + return // Nothing to do, this is a dead-end + } + + const hash = v2.config.hashNode(node) + + if (v2.config.isNode(node)) { + const saveLeft = this.saveTopology(node.left) + const saveRight = this.saveTopology(node.right) + const saveThis = this.store.saveV2Node(hash, { + left: v2.config.hashNode(node.left), + right: v2.config.hashNode(node.right) + } as PlainNode) + + await Promise.all([saveLeft, saveRight, saveThis]) + + return + } + + if (v2.config.isNestedLeaf(node)) { + const saveTree = this.saveTopology(node.tree) + const saveThis = this.store.saveV2Node(hash, { + weight: ethers.BigNumber.from(node.weight).toString(), + threshold: ethers.BigNumber.from(node.threshold).toString(), + tree: v2.config.hashNode(node.tree) + } as PlainNested) + + await Promise.all([saveTree, saveThis]) + + return + } + + // If it's a normal leaf, then we just store it + if (v2.config.isSignerLeaf(node)) { + return this.store.saveV2Node(hash, { + address: node.address, + weight: node.weight + }) + } + + if (v2.config.isSubdigestLeaf(node)) { + return this.store.saveV2Node(hash, { + subdigest: node.subdigest + }) + } + + throw new Error(`Unknown topology type: ${node}`) + } + + saveWalletConfig = async (args: { config: commons.config.Config }): Promise => { + const { config } = args + if (v1.config.ConfigCoder.isWalletConfig(config)) { + // We can store the configuration as-is + const imageHash = v1.config.ConfigCoder.imageHashOf(config) + return this.store.saveConfig(imageHash, config) + } + + if (v2.config.ConfigCoder.isWalletConfig(config)) { + // We split the configuration in a list of nodes, and store them individually + // then we can reconstruct it. This also means we can combine multiple configurations + // if they share information + const imageHash = v2.config.ConfigCoder.imageHashOf(config) + + // This is an optimization, it allows us to avoid splitting the tree if it's already complete + if (v2.config.isComplete(config.tree)) { + return this.store.saveConfig(imageHash, config) + } + + // TODO: Re-enable storing partial v2 configs once + // we have more performant code to reconstructing them + // in the meantime, rely on the remote tracker + + // const storeTree = this.saveTopology(config.tree) + // const storeConfig = this.store.saveConfig(imageHash, { + // version: 2, + // threshold: ethers.BigNumber.from(config.threshold).toString(), + // checkpoint: ethers.BigNumber.from(config.checkpoint).toString(), + // tree: v2.config.hashNode(config.tree) + // }) + + // await Promise.all([storeTree, storeConfig]) + } + + return + } + + private configOfImageHashCache = {} as { [key: string]: commons.config.Config } + + configOfImageHash = async (args: { imageHash: string }): Promise => { + const { imageHash } = args + + if (this.configOfImageHashCache[args.imageHash]) { + return this.configOfImageHashCache[args.imageHash] + } + + const config = await this.store.loadConfig(imageHash) + if (!config) { + return undefined + } + + if (config.version === 1 || (config.version === 2 && !isPlainV2Config(config))) { + this.configOfImageHashCache[args.imageHash] = config + return config + } + + if (isPlainV2Config(config)) { + const fullConfig = { + version: 2, + threshold: ethers.BigNumber.from(config.threshold), + checkpoint: ethers.BigNumber.from(config.checkpoint), + tree: await this.loadTopology(config.tree) + } as v2.config.WalletConfig + this.configOfImageHashCache[args.imageHash] = fullConfig + return fullConfig + } + + throw new Error(`Unknown config type: ${config}`) + } + + saveCounterfactualWallet = async (args: { + config: commons.config.Config + context: commons.context.WalletContext[] + }): Promise => { + const { config, context } = args + const imageHash = universal.genericCoderFor(config.version).config.imageHashOf(config) + await Promise.all([ + this.saveWalletConfig({ config }), + ...context.map(ctx => { + const address = commons.context.addressOf(ctx, imageHash) + return this.store.saveCounterfactualWallet(address, imageHash, ctx) + }) + ]) + } + + imageHashOfCounterfactualWallet = async (args: { + wallet: string + }): Promise< + | { + imageHash: string + context: commons.context.WalletContext + } + | undefined + > => { + const { wallet } = args + const result = await this.store.loadCounterfactualWallet(wallet) + + if (!result) return undefined + + return { + imageHash: result.imageHash, + context: result.context + } + } + + savePayload = async (args: { payload: commons.signature.SignedPayload }): Promise => { + const { payload } = args + + const subdigest = commons.signature.subdigestOf(payload) + await this.store.savePayloadOfSubdigest(subdigest, payload) + } + + private payloadOfSubdigestCache = {} as { [key: string]: commons.signature.SignedPayload } + + payloadOfSubdigest = async (args: { subdigest: string }): Promise => { + if (this.payloadOfSubdigestCache[args.subdigest]) { + return this.payloadOfSubdigestCache[args.subdigest] + } + + const { subdigest } = args + const res = await this.store.loadPayloadOfSubdigest(subdigest) + + if (res) { + this.payloadOfSubdigestCache[subdigest] = res + } + + return res + } + + savePresignedConfiguration = async (args: PresignedConfig): Promise => { + // Presigned configurations only work with v2 (for now) + // so we can assume that the signature is for a v2 configuration + const decoded = v2.signature.SignatureCoder.decode(args.signature) + const nextImageHash = universal.genericCoderFor(args.nextConfig.version).config.imageHashOf(args.nextConfig) + const message = v2.chained.messageSetImageHash(nextImageHash) + const digest = ethers.utils.keccak256(message) + const payload = { + message, + address: args.wallet, + chainId: 0, + digest + } + + const savePayload = this.savePayload({ payload }) + const saveNextConfig = this.saveWalletConfig({ config: args.nextConfig }) + + const recovered = await v2.signature.SignatureCoder.recover(decoded, payload, this.provider) + + // Save the recovered configuration and all signature parts + const signatures = v2.signature.signaturesOf(recovered.config.tree) + await Promise.all([ + savePayload, + saveNextConfig, + this.saveWalletConfig({ config: recovered.config }), + ...signatures.map(sig => this.store.saveSignatureOfSubdigest(sig.address, recovered.subdigest, sig.signature)) + ]) + } + + loadPresignedConfiguration = async (args: { + wallet: string + fromImageHash: string + longestPath?: boolean + }): Promise => { + const { wallet, fromImageHash, longestPath } = args + + const fromConfig = await this.configOfImageHash({ imageHash: fromImageHash }) + if (!fromConfig || !v2.config.ConfigCoder.isWalletConfig(fromConfig)) { + return [] + } + + // Get all subdigests for the config members + const signers = v2.config.signersOf(fromConfig.tree).map(s => s.address) + const subdigestsOfSigner = await Promise.all(signers.map(s => this.store.loadSubdigestsOfSigner(s))) + const subdigests = [...new Set(subdigestsOfSigner.flat())] + + // Get all unique payloads + const payloads = await Promise.all( + [...new Set(subdigests)].map(async s => ({ ...(await this.payloadOfSubdigest({ subdigest: s })), subdigest: s })) + ) + + // Get all possible next imageHashes based on the payloads + const nextImageHashes = payloads + .filter(p => p?.message && p?.address && p.address === wallet) + .map(p => ({ payload: p, nextImageHash: v2.chained.decodeMessageSetImageHash(p!.message!) })) + .filter(p => p?.nextImageHash) as { + payload: commons.signature.SignedPayload & { subdigest: string } + nextImageHash: string + }[] + + // Build a signature for each next imageHash + // and filter out the ones that don't have enough weight + let bestCandidate: + | { + nextImageHash: string + checkpoint: ethers.BigNumber + signature: string + } + | undefined + + const nextConfigsAndCheckpoints = await Promise.all( + nextImageHashes.map(async ({ nextImageHash, payload }) => { + const nextConfig = await this.configOfImageHash({ imageHash: nextImageHash }) + if (!nextConfig || !v2.config.isWalletConfig(nextConfig)) return undefined + const nextCheckpoint = ethers.BigNumber.from(nextConfig.checkpoint) + return { nextConfig, nextCheckpoint, nextImageHash, payload } + }) + ) + + const sortedNextConfigsAndCheckpoints = nextConfigsAndCheckpoints + .filter(c => c !== undefined) + .filter(c => c!.nextCheckpoint.gt(fromConfig.checkpoint)) + .sort((a, b) => + // If we are looking for the longest path, sort by ascending checkpoint + // because we want to find the smalles jump, and we should start with the + // closest one. If we are not looking for the longest path, sort by + // descending checkpoint, because we want to find the largest jump. + // + // We don't have a guarantee that all "next configs" will be valid + // so worst case scenario we will need to try all of them. + // But we can try to optimize for the most common case. + a!.nextCheckpoint.gt(b!.nextCheckpoint) ? (longestPath ? 1 : -1) : longestPath ? -1 : 1 + ) + + for (const entry of sortedNextConfigsAndCheckpoints) { + const { nextConfig, nextCheckpoint, nextImageHash, payload } = entry! + + if (bestCandidate) { + const bestCheckpoint = bestCandidate.checkpoint + if (longestPath) { + // Only consider candidates earlier than our current best + if (nextCheckpoint.gte(bestCheckpoint)) continue + } else { + // Only consider candidates later than our current best + if (nextCheckpoint.lte(bestCheckpoint)) continue + } + } + + // Get all signatures (for all signers) for this subdigest + const signatures = new Map( + ( + await Promise.all( + signers.map(async signer => { + const signature = await this.store.loadSignatureOfSubdigest(signer, payload.subdigest) + if (!signature) { + return [signer, undefined] + } + + const replacedSignature = ethers.utils.hexlify( + this.useEIP5719 ? await this.cachedEIP5719.runByEIP5719(signer, payload.subdigest, signature) : signature + ) + + const isDynamic = commons.signer.tryRecoverSigner(payload.subdigest, replacedSignature) !== signer + + return [signer, { isDynamic, signature: replacedSignature }] + }) + ) + ).filter((signature): signature is [string, commons.signature.SignaturePart] => Boolean(signature[1])) + ) + + // Skip if we don't have ANY signatures (it can never reach the threshold) + if (signatures.size === 0) continue + + // Encode the full signature (to see if it has enough weight) + const encoded = v2.signature.SignatureCoder.encodeSigners(fromConfig, signatures, [], 0) + if (encoded.weight.lt(fromConfig.threshold)) continue + + // Save the new best candidate + bestCandidate = { + nextImageHash, + checkpoint: ethers.BigNumber.from(nextConfig.checkpoint), + signature: encoded.encoded + } + } + + if (!bestCandidate) { + return [] + } + + // Get the next step + const nextStep = await this.loadPresignedConfiguration({ + wallet, + fromImageHash: bestCandidate.nextImageHash, + longestPath + }) + + return [ + { + wallet, + nextImageHash: bestCandidate.nextImageHash, + signature: bestCandidate.signature + }, + ...nextStep + ] + } + + saveWitnesses = async (args: { + wallet: string + digest: string + chainId: ethers.BigNumberish + signatures: string[] + }): Promise => { + const payload = { + digest: args.digest, + address: args.wallet, + chainId: args.chainId + } + + const subdigest = commons.signature.subdigestOf(payload) + + await Promise.all([ + this.savePayload({ payload }), + ...args.signatures + .filter(signature => { + // We don't support saving witnesses for non-recoverable signatures + // we could change this eventually, but the issue is that the witness may become invalid + return commons.signer.canRecover(signature) + }) + .map(signature => { + const signer = commons.signer.recoverSigner(subdigest, signature) + return this.store.saveSignatureOfSubdigest(signer, subdigest, signature) + }) + ]) + } + + walletsOfSigner = async (args: { + signer: string + }): Promise< + { + wallet: string + proof: { + digest: string + chainId: ethers.BigNumber + signature: string + } + }[] + > => { + const subdigests = await this.store.loadSubdigestsOfSigner(args.signer) + const payloads = await Promise.all(subdigests.map(s => this.payloadOfSubdigest({ subdigest: s }))).then( + p => p.filter(p => p !== undefined) as commons.signature.SignedPayload[] + ) + + // filter unique wallets, and provide a proof for each wallet + const result: { + wallet: string + proof: { + digest: string + chainId: ethers.BigNumber + signature: string + } + }[] = [] + + for (const payload of payloads) { + const wallet = payload.address + if (result.find(r => r.wallet === wallet)) continue + + const subdigest = commons.signature.subdigestOf(payload) + const signature = await this.store.loadSignatureOfSubdigest(args.signer, subdigest) + if (!signature) continue + + result.push({ + wallet, + proof: { + digest: payload.digest, + chainId: ethers.BigNumber.from(payload.chainId), + signature: ethers.utils.hexlify(signature) + } + }) + } + + return result + } + + async saveMigration( + address: string, + signed: migrator.SignedMigration, + contexts: commons.context.VersionedContext + ): Promise { + const fromVersion = signed.fromVersion + if (fromVersion !== 1) throw new Error('Migration not supported') + if (!v2.config.isWalletConfig(signed.toConfig)) throw new Error('Invalid to config') + + // Validate migration transaction + const { newImageHash, address: decodedAddress } = migration.v1v2.decodeTransaction(signed.tx, contexts) + if (decodedAddress !== address) throw new Error('Invalid migration transaction - address') + if (v2.config.ConfigCoder.imageHashOf(signed.toConfig) != newImageHash) + throw new Error('Invalid migration transaction - config') + + // Split signature and save each part + const message = commons.transaction.packMetaTransactionsData(signed.tx.nonce, signed.tx.transactions) + const digest = ethers.utils.keccak256(message) + const payload = { chainId: signed.tx.chainId, message, address, digest } + const subdigest = commons.signature.subdigestOf(payload) + + const savePayload = this.savePayload({ payload }) + const saveToConfig = this.saveWalletConfig({ config: signed.toConfig }) + + const decoded = v1.signature.SignatureCoder.decode(signed.tx.signature) + const recovered = await v1.signature.SignatureCoder.recover(decoded, payload, this.provider) + + // Save the recovered config, the migrate transaction, and all signature parts + const signatures = v1.signature.SignatureCoder.signaturesOf(recovered.config) + + await Promise.all([ + savePayload, + saveToConfig, + this.saveWalletConfig({ config: recovered.config }), + this.store.saveMigrationsSubdigest(address, fromVersion, fromVersion + 1, subdigest, newImageHash), + ...signatures.map(sig => this.store.saveSignatureOfSubdigest(sig.address, recovered.subdigest, sig.signature)) + ]) + } + + async getMigration( + address: string, + fromImageHash: string, + fromVersion: number, + chainId: ethers.BigNumberish + ): Promise { + // Get the current config and all possible migration payloads + const [currentConfig, txs] = await Promise.all([ + this.configOfImageHash({ imageHash: fromImageHash }), + this.store.loadMigrationsSubdigest(address, fromVersion, fromVersion + 1) + ]) + + const coder = universal.coderFor(fromVersion) + if (!currentConfig) { + // We may not be able to find the config, because the migration is still not copied locally + // in that case we consider as we don't have any migration + return undefined + } + + if (!coder.config.isWalletConfig(currentConfig)) { + // throw new Error("Invalid from config - version") + // better to not fail here, some other tracker may be able to handle this migration + return undefined + } + + // We need to process every migration candidate individually + // and see which one has enough signers to be valid (for the current config) + const candidates = await Promise.all( + txs.map(async tx => { + const { subdigest, toImageHash } = tx + const payload = await this.payloadOfSubdigest({ subdigest }) + if (!payload || !payload.message) return undefined + if (!ethers.BigNumber.from(chainId).eq(payload.chainId)) return undefined + + const signers = coder.config.signersOf(currentConfig as any).map(s => s.address) + + // Get all signatures (for all signers) for this subdigest + const signatures = new Map( + ( + await Promise.all( + signers.map(async signer => { + const signature = await this.store.loadSignatureOfSubdigest(signer, subdigest) + if (!signature) { + return [signer, undefined] + } + + const replacedSignature = ethers.utils.hexlify( + this.useEIP5719 ? await this.cachedEIP5719.runByEIP5719(signer, subdigest, signature) : signature + ) + + const isDynamic = commons.signer.tryRecoverSigner(subdigest, replacedSignature) !== signer + + return [signer, { isDynamic, signature: replacedSignature }] + }) + ) + ).filter((signature): signature is [string, commons.signature.SignaturePart] => Boolean(signature[1])) + ) + + // Encode signature parts into a single signature + const encoded = coder.signature.encodeSigners(currentConfig as any, signatures, [], chainId) + if (!encoded || encoded.weight < currentConfig.threshold) return undefined + + // Unpack payload (it should have transactions) + const [nonce, transactions] = commons.transaction.unpackMetaTransactionsData(payload.message) + + return { + tx: { + entrypoint: address, + transactions: commons.transaction.fromTxAbiEncode(transactions), + chainId: chainId, + nonce: nonce, + signature: encoded.encoded, + intent: { + id: subdigest, + wallet: address + } + }, + toConfig: await this.configOfImageHash({ imageHash: toImageHash }), + fromVersion, + toVersion: fromVersion + 1 + } as migrator.SignedMigration + }) + ).then(c => c.filter(c => c !== undefined)) + + // Return the first valid candidate + return candidates[0] + } + + updateProvider(provider: ethers.providers.Provider) { + this.provider = provider + } +} diff --git a/packages/sessions/src/trackers/multiple.ts b/packages/sessions/src/trackers/multiple.ts new file mode 100644 index 0000000000..d800a257c4 --- /dev/null +++ b/packages/sessions/src/trackers/multiple.ts @@ -0,0 +1,230 @@ +import { ConfigTracker, PresignedConfig, PresignedConfigLink } from '../tracker' +import { migrator } from '@0xsequence/migration' +import { BigNumber, BigNumberish, ethers } from 'ethers' +import { commons, universal } from '@0xsequence/core' +import { LocalConfigTracker } from './local' + +export function raceUntil(promises: Promise[], fallback: T, evalRes: (val: T) => boolean): Promise { + return new Promise(resolve => { + let count = 0 + + promises.forEach(p => + p + .then((val: T) => { + if (evalRes(val)) { + resolve(val) + } else { + count++ + if (count === promises.length) { + resolve(fallback) + } + } + }) + .catch(() => { + // Ignore + count++ + if (count === promises.length) { + resolve(fallback) + } + }) + ) + }) +} + +export async function allSafe(promises: Promise[], fallback: T): Promise { + return Promise.all(promises.map(promise => promise.catch(() => fallback))) +} + +export class MultipleTracker implements migrator.PresignedMigrationTracker, ConfigTracker { + constructor(private trackers: (migrator.PresignedMigrationTracker & ConfigTracker)[]) {} + + async configOfImageHash(args: { imageHash: string }): Promise { + const requests = this.trackers.map(async (t, i) => ({ res: await t.configOfImageHash(args), i })) + + // We try to find a complete configuration, we race so that we don't wait for all trackers to respond + const result1 = await raceUntil(requests, undefined, val => { + if (val?.res === undefined) return false + return universal.genericCoderFor(val.res.version).config.isComplete(val.res) + }) + + if (result1?.res) { + // Skip saving the config to the tracker that returned the result + this.saveWalletConfig({ config: result1.res, skipTracker: result1.i }) + return result1.res + } + + // If we haven't found a complete configuration yet, it either means that the configuration is not complete + // (and thus we need to combine all results) or that the configuration is not found at all + // but we try to combine all results anyway + const tmptracker = new LocalConfigTracker(undefined as any) // TODO: Fix this, provider not needed anyway + + const results = await allSafe(requests, undefined) + + for (const r of results) { + if (r?.res) await tmptracker.saveWalletConfig({ config: r.res }) + } + + const result2 = await tmptracker.configOfImageHash(args) + if (result2) this.saveWalletConfig({ config: result2 }) + return result2 + } + + async saveWalletConfig(args: { config: commons.config.Config; skipTracker?: number }): Promise { + await Promise.all( + this.trackers.map((t, i) => { + if (i === args.skipTracker) return + return t.saveWalletConfig(args) + }) + ) + } + + async imageHashOfCounterfactualWallet(args: { + wallet: string + }): Promise<{ imageHash: string; context: commons.context.WalletContext } | undefined> { + const imageHash = await raceUntil( + this.trackers.map(t => t.imageHashOfCounterfactualWallet(args)), + undefined, + result => Boolean(result) + ) + + if (imageHash) { + this.configOfImageHash({ imageHash: imageHash.imageHash }).then(config => { + if (config) { + this.saveCounterfactualWallet({ config, context: [imageHash.context] }) + } + }) + } + + return imageHash + } + + async saveCounterfactualWallet(args: { + config: commons.config.Config + context: commons.context.WalletContext[] + skipTracker?: number + }): Promise { + await Promise.all( + this.trackers.map((t, i) => { + if (i === args.skipTracker) return + return t.saveCounterfactualWallet(args) + }) + ) + } + + async walletsOfSigner(args: { + signer: string + }): Promise<{ wallet: string; proof: { digest: string; chainId: BigNumber; signature: string } }[]> { + // We can't race here, because there is no "correct" response + // we just return the union of all results, skipping duplicates + const results = await allSafe( + this.trackers.map(t => t.walletsOfSigner(args)), + [] + ).then(r => r.flat()) + + const wallets: { [wallet: string]: { digest: string; chainId: BigNumber; signature: string } } = {} + for (const r of results) { + wallets[r.wallet] = r.proof + } + + // TODO: This will send redundant information back to the trackers + // consider optimizing this for better performance during login + + const result = Object.keys(wallets).map(w => ({ wallet: w, proof: wallets[w] })) + + const witnesses = new Map() + result.forEach(({ wallet, proof: { digest, chainId, signature } }) => { + const key = `${wallet}-${digest}-${chainId}` + let signatures = witnesses.get(key) + if (!signatures) { + signatures = { wallet, digest, chainId, signatures: [] } + witnesses.set(key, signatures) + } + signatures.signatures.push(signature) + }) + witnesses.forEach(witnesses => this.saveWitnesses(witnesses)) + + return result + } + + async saveWitnesses(args: { wallet: string; digest: string; chainId: BigNumberish; signatures: string[] }): Promise { + await Promise.all(this.trackers.map(t => t.saveWitnesses(args))) + } + + async loadPresignedConfiguration(args: { + wallet: string + fromImageHash: string + longestPath?: boolean | undefined + }): Promise { + // We can't race here, because any of the trackers could have a new "link" in the chain + const results = await allSafe( + this.trackers.map(t => t.loadPresignedConfiguration(args)), + [] + ) + + // The "best" result is the one with the highest checkpoint + const checkpoints = await allSafe( + results.map(async r => { + const last = r[r.length - 1] + + // TODO: This will fire a lot of requests, optimize it + const config = await this.configOfImageHash({ imageHash: last.nextImageHash }) + if (!config) return undefined + + return { checkpoint: universal.genericCoderFor(config.version).config.checkpointOf(config), result: r } + }), + undefined + ) + + const best = checkpoints.reduce((acc, val) => { + if (!val) return acc + if (!acc) return val + if (val.checkpoint.gt(acc.checkpoint)) return val + return acc + }) + + if (!best) return [] + + const configs = new Map>() + const config = (imageHash: string): Promise => { + if (!configs.has(imageHash)) { + configs.set(imageHash, this.configOfImageHash({ imageHash })) + } + return configs.get(imageHash)! + } + best.result.forEach(async res => { + const nextConfig = await config(res.nextImageHash) + if (nextConfig) { + this.savePresignedConfiguration({ + wallet: args.wallet, + nextConfig, + signature: res.signature + }) + } + }) + + return best.result + } + + async savePresignedConfiguration(args: PresignedConfig): Promise { + await Promise.all(this.trackers.map(t => t.savePresignedConfiguration(args))) + } + + async getMigration( + address: string, + fromImageHash: string, + fromVersion: number, + chainId: BigNumberish + ): Promise { + // TODO: Backfeed migration results to other trackers + const results = await Promise.all(this.trackers.map(t => t.getMigration(address, fromImageHash, fromVersion, chainId))) + return results.find(r => !!r) + } + + async saveMigration( + address: string, + signed: migrator.SignedMigration, + contexts: commons.context.VersionedContext + ): Promise { + await Promise.all(this.trackers.map(t => t.saveMigration(address, signed, contexts))) + } +} diff --git a/packages/sessions/src/trackers/promise-cache.ts b/packages/sessions/src/trackers/promise-cache.ts new file mode 100644 index 0000000000..0504adda88 --- /dev/null +++ b/packages/sessions/src/trackers/promise-cache.ts @@ -0,0 +1,58 @@ +import { ethers } from 'ethers' + +export class PromiseCache { + private readonly cache: Map + + constructor() { + this.cache = new Map() + } + + do, T>( + key: string, + validMilliseconds: number | undefined, + task: (...args: S) => Promise, + ...args: S + ): Promise { + key = `${key}:${ethers.utils.keccak256(ethers.utils.toUtf8Bytes(JSON.stringify(args, deterministically)))}` + + let entry = this.cache.get(key) + + if (entry) { + if (entry.expiration) { + if (new Date() >= entry.expiration) { + entry = undefined + this.cache.delete(key) + } + } + } + + if (!entry) { + const entry_: Entry = { promise: task(...args) } + + if (validMilliseconds !== undefined) { + entry_.promise = entry_.promise.then(result => { + entry_.expiration = new Date(Date.now() + validMilliseconds) + return result + }) + } + + entry = entry_ + this.cache.set(key, entry) + } + + return entry.promise as Promise + } +} + +type Entry = { + promise: Promise + expiration?: Date +} + +function deterministically(_key: string, value: any): any { + if (typeof value === 'object' && value !== null && !Array.isArray(value)) { + return Object.fromEntries(Object.entries(value).sort()) + } + + return value +} diff --git a/packages/sessions/src/trackers/remote/index.ts b/packages/sessions/src/trackers/remote/index.ts new file mode 100644 index 0000000000..1daaf05c89 --- /dev/null +++ b/packages/sessions/src/trackers/remote/index.ts @@ -0,0 +1,359 @@ +import { commons, universal, v1, v2 } from '@0xsequence/core' +import { migrator } from '@0xsequence/migration' +import { ethers } from 'ethers' +import { ConfigTracker, PresignedConfig, PresignedConfigLink } from '../../tracker' +import { Sessions, SignatureType, Transaction } from './sessions.gen' + +export class RemoteConfigTracker implements ConfigTracker, migrator.PresignedMigrationTracker { + private readonly sessions: Sessions + + constructor( + hostname: string, + public readonly onlyRecoverable: boolean = true + ) { + this.sessions = new Sessions(hostname, fetch) + } + + async loadPresignedConfiguration(args: { + wallet: string + fromImageHash: string + longestPath?: boolean + }): Promise { + try { + const { updates } = await this.sessions.configUpdates({ + wallet: args.wallet, + fromImageHash: args.fromImageHash, + allUpdates: args.longestPath + }) + + return updates.map(({ toImageHash, signature }) => ({ wallet: args.wallet, nextImageHash: toImageHash, signature })) + } catch (error) { + if (is404NotFound(error)) { + return [] + } else { + throw error + } + } + } + + async savePresignedConfiguration(args: PresignedConfig): Promise { + const config = args.nextConfig + const imageHash = universal.genericCoderFor(config.version).config.imageHashOf(config) + const message = v2.signature.setImageHashStruct(imageHash) + const digest = ethers.utils.keccak256(message) + + await this.sessions.saveSignature({ + wallet: args.wallet, + digest, + chainID: '0', + signature: args.signature, + toConfig: encodeConfig(config) + }) + } + + async saveWitnesses(args: { + wallet: string + digest: string + chainId: ethers.BigNumberish + signatures: string[] + }): Promise { + let filteredSignatures = args.signatures + if (this.onlyRecoverable) { + filteredSignatures = filteredSignatures.filter(signature => { + return commons.signer.canRecover(signature) + }) + } + + await this.sessions.saveSignerSignatures({ + wallet: args.wallet, + digest: args.digest, + chainID: numberString(args.chainId), + signatures: filteredSignatures + }) + } + + async configOfImageHash(args: { imageHash: string }): Promise { + try { + const { version, config } = await this.sessions.config(args) + return decodeConfig(version, config) + } catch (error) { + if (is404NotFound(error)) { + return + } else { + throw error + } + } + } + + async saveWalletConfig(args: { config: commons.config.Config }): Promise { + const config = encodeConfig(args.config) + await this.sessions.saveConfig({ version: args.config.version, config }) + } + + async imageHashOfCounterfactualWallet(args: { + wallet: string + }): Promise<{ imageHash: string; context: commons.context.WalletContext } | undefined> { + try { + const { deployHash, context } = await this.sessions.deployHash(args) + return { imageHash: deployHash, context } + } catch (error) { + if (is404NotFound(error)) { + return + } else { + throw error + } + } + } + + async saveCounterfactualWallet(args: { + config: commons.config.Config + context: commons.context.WalletContext[] + }): Promise { + const deployConfig = encodeConfig(args.config) + await this.sessions.saveWallet({ version: args.config.version, deployConfig }) + } + + async walletsOfSigner(args: { + signer: string + }): Promise<{ wallet: string; proof: { digest: string; chainId: ethers.BigNumber; signature: string } }[]> { + const { wallets } = await this.sessions.wallets(args) + return Object.entries(wallets).map(([wallet, { digest, chainID, type, signature }]) => { + switch (type) { + case SignatureType.EIP712: + signature += ethers.utils.hexlify(commons.signer.SigType.EIP712).slice(2) + break + case SignatureType.EthSign: + signature += ethers.utils.hexlify(commons.signer.SigType.ETH_SIGN).slice(2) + break + case SignatureType.EIP1271: + signature += ethers.utils.hexlify(commons.signer.SigType.WALLET_BYTES32).slice(2) + break + } + + return { + wallet, + proof: { + digest, + signature, + chainId: ethers.BigNumber.from(chainID) + } + } + }) + } + + async getMigration( + wallet: string, + fromImageHash: string, + fromVersion: number, + chainId: ethers.BigNumberish + ): Promise { + const chainIdString = numberString(chainId) + const { migrations } = await this.sessions.migrations({ wallet, fromVersion, fromImageHash, chainID: chainIdString }) + + const chooseMigration = async (chainId: string): Promise => { + const migrations_ = migrations[chainId] + if (migrations_) { + const toVersions = Object.keys(migrations_) + .map(Number) + .sort((a: number, b: number) => b - a) + + for (const toVersion of toVersions) { + for (const [toHash, transactions] of Object.entries(migrations_[toVersion])) { + try { + const toConfig = await this.configOfImageHash({ imageHash: toHash }) + if (toConfig) { + return { + fromVersion, + toVersion, + toConfig, + tx: { + entrypoint: transactions.executor, + transactions: transactions.transactions, + nonce: transactions.nonce, + signature: transactions.signature, + chainId, + intent: { + id: commons.transaction.subdigestOfTransactions( + wallet, + chainId, + transactions.nonce, + transactions.transactions + ), + wallet + } + } + } + } + } catch (error) { + console.error(error) + } + } + } + } + return + } + + const migration = await chooseMigration(chainIdString) + if (migration) { + return migration + } + + for (const chainId in migrations) { + if (chainId !== chainIdString) { + const migration = await chooseMigration(chainId) + if (migration) { + return migration + } + } + } + + return + } + + async saveMigration( + wallet: string, + signed: migrator.SignedMigration, + _contexts: commons.context.VersionedContext + ): Promise { + await this.sessions.saveMigration({ + wallet, + fromVersion: signed.fromVersion, + toVersion: signed.toVersion, + toConfig: encodeConfig(signed.toConfig), + executor: signed.tx.entrypoint, + transactions: signed.tx.transactions.map(encodeTransaction), + nonce: numberString(signed.tx.nonce), + signature: signed.tx.signature, + chainID: numberString(signed.tx.chainId) + }) + } +} + +type SessionsConfig = { + 1: { threshold: number; signers: Array<{ weight: number; address: string }> } + 2: { threshold: number; checkpoint: number; tree: V2SessionsConfigTree } +} + +type V2SessionsConfigTree = + | { left: V2SessionsConfigTree; right: V2SessionsConfigTree } + | { weight: number; address: string } + | { node: string } + | { weight: number; threshold: number; tree: V2SessionsConfigTree } + | { subdigest: string } + +function encodeConfig(config: commons.config.Config): SessionsConfig[1 | 2] { + switch (config.version) { + case 1: + if (v1.config.ConfigCoder.isWalletConfig(config)) { + return { + threshold: numberNumber(config.threshold), + signers: config.signers.map(({ weight, address }) => ({ weight: numberNumber(weight), address })) + } + } else { + throw new Error(`not a v${config.version} config: ${config}`) + } + + case 2: + if (v2.config.ConfigCoder.isWalletConfig(config)) { + return { + threshold: numberNumber(config.threshold), + checkpoint: numberNumber(config.checkpoint), + tree: encodeV2ConfigTree(config.tree) + } + } else { + throw new Error(`not a v${config.version} config: ${config}`) + } + + default: + throw new Error(`unknown version ${config.version}`) + } +} + +function encodeV2ConfigTree(tree: v2.config.Topology): V2SessionsConfigTree { + if (v2.config.isNode(tree)) { + return { + left: encodeV2ConfigTree(tree.left), + right: encodeV2ConfigTree(tree.right) + } + } else if (v2.config.isSignerLeaf(tree)) { + return { + weight: numberNumber(tree.weight), + address: tree.address + } + } else if (v2.config.isNestedLeaf(tree)) { + return { + weight: numberNumber(tree.weight), + threshold: numberNumber(tree.threshold), + tree: encodeV2ConfigTree(tree.tree) + } + } else if (v2.config.isNodeLeaf(tree)) { + return { node: tree.nodeHash } + } else { + return { ...tree } + } +} + +function decodeConfig(version: number, config: any): commons.config.Config { + switch (version) { + case 1: + return { ...config, version } + + case 2: + return { ...config, version, tree: decodeV2ConfigTree(config.tree) } + + default: + throw new Error(`unknown version ${version}`) + } +} + +function decodeV2ConfigTree(tree: any): v2.config.Topology { + switch (typeof tree) { + case 'object': + const tree_ = { ...tree } + + if (tree_.left !== undefined) { + tree_.left = decodeV2ConfigTree(tree_.left) + } + + if (tree_.right !== undefined) { + tree_.right = decodeV2ConfigTree(tree_.right) + } + + if (tree_.tree !== undefined) { + tree_.tree = decodeV2ConfigTree(tree_.tree) + } + + if (tree_.node !== undefined) { + tree_.nodeHash = tree_.node + delete tree_.node + } + + return tree_ + + default: + throw new Error(`v2 config tree ${tree} is not an object`) + } +} + +function encodeTransaction(transaction: commons.transaction.Transaction): Transaction { + return { + to: transaction.to, + value: transaction.value !== undefined ? numberString(transaction.value) : undefined, + data: transaction.data !== undefined ? ethers.utils.hexlify(transaction.data) : undefined, + gasLimit: transaction.gasLimit !== undefined ? numberString(transaction.gasLimit) : undefined, + delegateCall: transaction.delegateCall, + revertOnError: transaction.revertOnError + } +} + +function numberNumber(n: ethers.BigNumberish): number { + return ethers.BigNumber.from(n).toNumber() +} + +function numberString(n: ethers.BigNumberish): string { + return ethers.BigNumber.from(n).toString() +} + +function is404NotFound(error: any): boolean { + return typeof error === 'object' && error.status === 404 +} diff --git a/packages/sessions/src/trackers/remote/sessions.gen.ts b/packages/sessions/src/trackers/remote/sessions.gen.ts new file mode 100644 index 0000000000..49eb8207d5 --- /dev/null +++ b/packages/sessions/src/trackers/remote/sessions.gen.ts @@ -0,0 +1,634 @@ +/* eslint-disable */ +// sessions v0.0.1 d81ea64cbe41c1ab8b0107bce2f118817b34ebc0 +// -- +// Code generated by webrpc-gen@v0.18.6 with typescript generator. DO NOT EDIT. +// +// webrpc-gen -schema=sessions.ridl -target=typescript -client -out=./sessions.gen.ts + +// WebRPC description and code-gen version +export const WebRPCVersion = 'v1' + +// Schema version of your RIDL schema +export const WebRPCSchemaVersion = 'v0.0.1' + +// Schema hash generated from your RIDL schema +export const WebRPCSchemaHash = 'd81ea64cbe41c1ab8b0107bce2f118817b34ebc0' + +// +// Types +// + +export enum SignatureType { + EIP712 = 'EIP712', + EthSign = 'EthSign', + EIP1271 = 'EIP1271' +} + +export interface RuntimeStatus { + healthy: boolean + started: string + uptime: number + version: string + branch: string + commit: string + wallets: { [key: string]: number } + configs: { [key: string]: number } + configTrees: number + migrations: { [key: string]: number } + signatures: number + digests: number + recorder: RecorderStatus +} + +export interface RecorderStatus { + requests: number + buffer: number + lastFlush?: string + secondsSinceLastFlush?: number + endpoints: { [key: string]: number } +} + +export interface Context { + version: number + factory: string + mainModule: string + mainModuleUpgradable: string + guestModule: string + walletCreationCode: string +} + +export interface Signature { + digest: string + toImageHash?: string + chainID: string + type: SignatureType + signature: string +} + +export interface ConfigUpdate { + toImageHash: string + signature: string +} + +export interface Transaction { + to: string + value?: string + data?: string + gasLimit?: string + delegateCall?: boolean + revertOnError?: boolean +} + +export interface TransactionBundle { + executor: string + transactions: Array + nonce: string + signature: string +} + +export interface Sessions { + ping(headers?: object, signal?: AbortSignal): Promise + config(args: ConfigArgs, headers?: object, signal?: AbortSignal): Promise + wallets(args: WalletsArgs, headers?: object, signal?: AbortSignal): Promise + deployHash(args: DeployHashArgs, headers?: object, signal?: AbortSignal): Promise + configUpdates(args: ConfigUpdatesArgs, headers?: object, signal?: AbortSignal): Promise + migrations(args: MigrationsArgs, headers?: object, signal?: AbortSignal): Promise + saveConfig(args: SaveConfigArgs, headers?: object, signal?: AbortSignal): Promise + saveWallet(args: SaveWalletArgs, headers?: object, signal?: AbortSignal): Promise + saveSignature(args: SaveSignatureArgs, headers?: object, signal?: AbortSignal): Promise + saveSignerSignatures( + args: SaveSignerSignaturesArgs, + headers?: object, + signal?: AbortSignal + ): Promise + saveMigration(args: SaveMigrationArgs, headers?: object, signal?: AbortSignal): Promise +} + +export interface PingArgs {} + +export interface PingReturn {} +export interface ConfigArgs { + imageHash: string +} + +export interface ConfigReturn { + version: number + config: any +} +export interface WalletsArgs { + signer: string +} + +export interface WalletsReturn { + wallets: { [key: string]: Signature } +} +export interface DeployHashArgs { + wallet: string +} + +export interface DeployHashReturn { + deployHash: string + context: Context +} +export interface ConfigUpdatesArgs { + wallet: string + fromImageHash: string + allUpdates?: boolean +} + +export interface ConfigUpdatesReturn { + updates: Array +} +export interface MigrationsArgs { + wallet: string + fromVersion: number + fromImageHash: string + chainID?: string +} + +export interface MigrationsReturn { + migrations: { [key: string]: { [key: number]: { [key: string]: TransactionBundle } } } +} +export interface SaveConfigArgs { + version: number + config: any +} + +export interface SaveConfigReturn {} +export interface SaveWalletArgs { + version: number + deployConfig: any +} + +export interface SaveWalletReturn {} +export interface SaveSignatureArgs { + wallet: string + digest: string + chainID: string + signature: string + toConfig?: any +} + +export interface SaveSignatureReturn {} +export interface SaveSignerSignaturesArgs { + wallet: string + digest: string + chainID: string + signatures: Array + toConfig?: any +} + +export interface SaveSignerSignaturesReturn {} +export interface SaveMigrationArgs { + wallet: string + fromVersion: number + toVersion: number + toConfig: any + executor: string + transactions: Array + nonce: string + signature: string + chainID?: string +} + +export interface SaveMigrationReturn {} + +// +// Client +// +export class Sessions implements Sessions { + protected hostname: string + protected fetch: Fetch + protected path = '/rpc/Sessions/' + + constructor(hostname: string, fetch: Fetch) { + this.hostname = hostname + this.fetch = (input: RequestInfo, init?: RequestInit) => fetch(input, init) + } + + private url(name: string): string { + return this.hostname + this.path + name + } + + ping = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('Ping'), createHTTPRequest({}, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return {} + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + config = (args: ConfigArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('Config'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + version: _data.version, + config: _data.config + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + wallets = (args: WalletsArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('Wallets'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + wallets: <{ [key: string]: Signature }>_data.wallets + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + deployHash = (args: DeployHashArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('DeployHash'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + deployHash: _data.deployHash, + context: _data.context + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + configUpdates = (args: ConfigUpdatesArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('ConfigUpdates'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + updates: >_data.updates + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + migrations = (args: MigrationsArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('Migrations'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + migrations: <{ [key: string]: { [key: number]: { [key: string]: TransactionBundle } } }>_data.migrations + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + saveConfig = (args: SaveConfigArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('SaveConfig'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return {} + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + saveWallet = (args: SaveWalletArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('SaveWallet'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return {} + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + saveSignature = (args: SaveSignatureArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('SaveSignature'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return {} + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + saveSignerSignatures = ( + args: SaveSignerSignaturesArgs, + headers?: object, + signal?: AbortSignal + ): Promise => { + return this.fetch(this.url('SaveSignerSignatures'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return {} + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + saveMigration = (args: SaveMigrationArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('SaveMigration'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return {} + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } +} + +const createHTTPRequest = (body: object = {}, headers: object = {}, signal: AbortSignal | null = null): object => { + return { + method: 'POST', + headers: { ...headers, 'Content-Type': 'application/json' }, + body: JSON.stringify(body || {}), + signal + } +} + +const buildResponse = (res: Response): Promise => { + return res.text().then(text => { + let data + try { + data = JSON.parse(text) + } catch (error) { + let message = '' + if (error instanceof Error) { + message = error.message + } + throw WebrpcBadResponseError.new({ + status: res.status, + cause: `JSON.parse(): ${message}: response text: ${text}` + }) + } + if (!res.ok) { + const code: number = typeof data.code === 'number' ? data.code : 0 + throw (webrpcErrorByCode[code] || WebrpcError).new(data) + } + return data + }) +} + +// +// Errors +// + +export class WebrpcError extends Error { + name: string + code: number + message: string + status: number + cause?: string + + /** @deprecated Use message instead of msg. Deprecated in webrpc v0.11.0. */ + msg: string + + constructor(name: string, code: number, message: string, status: number, cause?: string) { + super(message) + this.name = name || 'WebrpcError' + this.code = typeof code === 'number' ? code : 0 + this.message = message || `endpoint error ${this.code}` + this.msg = this.message + this.status = typeof status === 'number' ? status : 0 + this.cause = cause + Object.setPrototypeOf(this, WebrpcError.prototype) + } + + static new(payload: any): WebrpcError { + return new this(payload.error, payload.code, payload.message || payload.msg, payload.status, payload.cause) + } +} + +// Webrpc errors + +export class WebrpcEndpointError extends WebrpcError { + constructor( + name: string = 'WebrpcEndpoint', + code: number = 0, + message: string = 'endpoint error', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcEndpointError.prototype) + } +} + +export class WebrpcRequestFailedError extends WebrpcError { + constructor( + name: string = 'WebrpcRequestFailed', + code: number = -1, + message: string = 'request failed', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcRequestFailedError.prototype) + } +} + +export class WebrpcBadRouteError extends WebrpcError { + constructor( + name: string = 'WebrpcBadRoute', + code: number = -2, + message: string = 'bad route', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadRouteError.prototype) + } +} + +export class WebrpcBadMethodError extends WebrpcError { + constructor( + name: string = 'WebrpcBadMethod', + code: number = -3, + message: string = 'bad method', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadMethodError.prototype) + } +} + +export class WebrpcBadRequestError extends WebrpcError { + constructor( + name: string = 'WebrpcBadRequest', + code: number = -4, + message: string = 'bad request', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadRequestError.prototype) + } +} + +export class WebrpcBadResponseError extends WebrpcError { + constructor( + name: string = 'WebrpcBadResponse', + code: number = -5, + message: string = 'bad response', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadResponseError.prototype) + } +} + +export class WebrpcServerPanicError extends WebrpcError { + constructor( + name: string = 'WebrpcServerPanic', + code: number = -6, + message: string = 'server panic', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcServerPanicError.prototype) + } +} + +export class WebrpcInternalErrorError extends WebrpcError { + constructor( + name: string = 'WebrpcInternalError', + code: number = -7, + message: string = 'internal error', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcInternalErrorError.prototype) + } +} + +export class WebrpcClientDisconnectedError extends WebrpcError { + constructor( + name: string = 'WebrpcClientDisconnected', + code: number = -8, + message: string = 'client disconnected', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcClientDisconnectedError.prototype) + } +} + +export class WebrpcStreamLostError extends WebrpcError { + constructor( + name: string = 'WebrpcStreamLost', + code: number = -9, + message: string = 'stream lost', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcStreamLostError.prototype) + } +} + +export class WebrpcStreamFinishedError extends WebrpcError { + constructor( + name: string = 'WebrpcStreamFinished', + code: number = -10, + message: string = 'stream finished', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcStreamFinishedError.prototype) + } +} + +// Schema errors + +export class InvalidArgumentError extends WebrpcError { + constructor( + name: string = 'InvalidArgument', + code: number = 1, + message: string = 'invalid argument', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, InvalidArgumentError.prototype) + } +} + +export class NotFoundError extends WebrpcError { + constructor(name: string = 'NotFound', code: number = 2, message: string = 'not found', status: number = 0, cause?: string) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, NotFoundError.prototype) + } +} + +export enum errors { + WebrpcEndpoint = 'WebrpcEndpoint', + WebrpcRequestFailed = 'WebrpcRequestFailed', + WebrpcBadRoute = 'WebrpcBadRoute', + WebrpcBadMethod = 'WebrpcBadMethod', + WebrpcBadRequest = 'WebrpcBadRequest', + WebrpcBadResponse = 'WebrpcBadResponse', + WebrpcServerPanic = 'WebrpcServerPanic', + WebrpcInternalError = 'WebrpcInternalError', + WebrpcClientDisconnected = 'WebrpcClientDisconnected', + WebrpcStreamLost = 'WebrpcStreamLost', + WebrpcStreamFinished = 'WebrpcStreamFinished', + InvalidArgument = 'InvalidArgument', + NotFound = 'NotFound' +} + +const webrpcErrorByCode: { [code: number]: any } = { + [0]: WebrpcEndpointError, + [-1]: WebrpcRequestFailedError, + [-2]: WebrpcBadRouteError, + [-3]: WebrpcBadMethodError, + [-4]: WebrpcBadRequestError, + [-5]: WebrpcBadResponseError, + [-6]: WebrpcServerPanicError, + [-7]: WebrpcInternalErrorError, + [-8]: WebrpcClientDisconnectedError, + [-9]: WebrpcStreamLostError, + [-10]: WebrpcStreamFinishedError, + [1]: InvalidArgumentError, + [2]: NotFoundError +} + +export type Fetch = (input: RequestInfo, init?: RequestInit) => Promise diff --git a/packages/sessions/src/trackers/stores/index.ts b/packages/sessions/src/trackers/stores/index.ts new file mode 100644 index 0000000000..b067048d03 --- /dev/null +++ b/packages/sessions/src/trackers/stores/index.ts @@ -0,0 +1,78 @@ +import { commons, v1, v2 } from '@0xsequence/core' +import { ethers } from 'ethers' + +export type PlainNode = { + left: string + right: string +} + +export type PlainNested = { + weight: string + threshold: string + tree: string +} + +export type PlainV2Config = { + version: 2 + threshold: string + checkpoint: string + tree: string +} + +export function isPlainNode(node: any): node is PlainNode { + return node.left !== undefined && node.right !== undefined +} + +export function isPlainNested(node: any): node is PlainNested { + return node.weight !== undefined && node.threshold !== undefined && node.tree !== undefined +} + +export function isPlainV2Config(config: any): config is PlainV2Config { + return ( + config.version === 2 && + config.threshold !== undefined && + config.checkpoint !== undefined && + config.tree !== undefined && + typeof config.tree === 'string' + ) +} + +export interface TrackerStore { + // top level configurations store + loadConfig: (imageHash: string) => Promise + saveConfig: (imageHash: string, config: v1.config.WalletConfig | PlainV2Config | v2.config.WalletConfig) => Promise + + // v2 configurations store + loadV2Node: (nodeHash: string) => Promise + saveV2Node: (nodeHash: string, node: PlainNode | PlainNested | v2.config.Topology) => Promise + + // counterfactual wallets + loadCounterfactualWallet: (wallet: string) => Promise<{ imageHash: string; context: commons.context.WalletContext } | undefined> + saveCounterfactualWallet: (wallet: string, imageHash: string, context: commons.context.WalletContext) => Promise + + // payloads + loadPayloadOfSubdigest: (subdigest: string) => Promise + savePayloadOfSubdigest: (subdigest: string, payload: commons.signature.SignedPayload) => Promise + + // signatures + loadSubdigestsOfSigner: (signer: string) => Promise + loadSignatureOfSubdigest: (signer: string, subdigest: string) => Promise + saveSignatureOfSubdigest: (signer: string, subdigest: string, payload: ethers.BytesLike) => Promise + + // migrations + loadMigrationsSubdigest: ( + wallet: string, + fromVersion: number, + toVersion: number + ) => Promise<{ subdigest: string; toImageHash: string }[]> + saveMigrationsSubdigest: ( + wallet: string, + fromVersion: number, + toVersion: number, + subdigest: string, + toImageHash: string + ) => Promise +} + +export * from './memoryStore' +export * from './indexedDBStore' diff --git a/packages/sessions/src/trackers/stores/indexedDBStore.ts b/packages/sessions/src/trackers/stores/indexedDBStore.ts new file mode 100644 index 0000000000..6f0f1e275a --- /dev/null +++ b/packages/sessions/src/trackers/stores/indexedDBStore.ts @@ -0,0 +1,191 @@ +import { commons, v1, v2 } from '@0xsequence/core' +import { ethers } from 'ethers' +import { PlainNested, PlainNode, PlainV2Config, TrackerStore } from '.' + +import { DBSchema, IDBPDatabase, openDB } from 'idb' + +export interface LocalTrackerDBSchema extends DBSchema { + configs: { + key: string + value: v1.config.WalletConfig | v2.config.WalletConfig | PlainV2Config + } + v2Nodes: { + key: string + value: v2.config.Topology | PlainNode | PlainNested + } + counterfactualWallets: { + key: string + value: { + imageHash: string + context: commons.context.WalletContext + } + } + payloads: { + key: string + value: commons.signature.SignedPayload + } + signatures: { + key: string // `${signer}-${subdigest}` + value: { + signature: ethers.BytesLike + signer: string + } + indexes: { + signer: string + } + } + migrations: { + key: string + value: { + wallet: string + fromVersion: number + toVersion: number + subdigest: string + toImageHash: string + } + indexes: { + jump: string // '${wallet}-${fromVersion}-${toVersion} + } + } +} + +export function recreateBigNumbers(object: T): T | undefined { + if (object === undefined) return undefined + + const result = {} as any + + for (const key of Object.keys(object)) { + const val = (object as any)[key as string] + + if (val._isBigNumber === true && val._hex !== undefined && typeof val._hex === 'string' && val._hex.length !== '') { + // Entry is a big number + result[key] = ethers.BigNumber.from(val) + } else if (Array.isArray(val)) { + // Entry is an array, recurse + result[key] = val.map(v => recreateBigNumbers(v)) + } else if (typeof val === 'object' && val !== null) { + // Entry is another object, recurse + result[key] = recreateBigNumbers(val) + } else { + // Entry is a primitive, just copy + result[key] = val + } + } + + return result +} + +export class IndexedDBStore implements TrackerStore { + private _lazyDb: IDBPDatabase | undefined + + constructor(public dbName: string) {} + + async getDb() { + if (this._lazyDb) return this._lazyDb + + const dbName = this.dbName + this._lazyDb = await openDB(dbName, 1, { + upgrade(db, oldVersion, newVersion, transaction) { + console.log(`upgrading ${dbName} from ${oldVersion} to ${newVersion} - ${transaction}`) + if (oldVersion === 0) { + db.createObjectStore('configs') + db.createObjectStore('v2Nodes') + db.createObjectStore('counterfactualWallets') + db.createObjectStore('payloads') + + const signatures = db.createObjectStore('signatures') + signatures.createIndex('signer', 'signer', { unique: false }) + + const migrations = db.createObjectStore('migrations') + migrations.createIndex('jump', ['wallet', 'fromVersion', 'toVersion']) + } + } + }) + return this._lazyDb + } + + loadConfig = async ( + imageHash: string + ): Promise => { + const db = await this.getDb() + return db.get('configs', imageHash).then(c => recreateBigNumbers(c)) + } + + saveConfig = async ( + imageHash: string, + config: v1.config.WalletConfig | v2.config.WalletConfig | PlainV2Config + ): Promise => { + const db = await this.getDb() + await db.put('configs', config, imageHash) + } + + loadV2Node = async (nodeHash: string): Promise => { + const db = await this.getDb() + return db.get('v2Nodes', nodeHash).then(c => recreateBigNumbers(c)) + } + + saveV2Node = async (nodeHash: string, node: v2.config.Topology | PlainNode | PlainNested): Promise => { + const db = await this.getDb() + await db.put('v2Nodes', node, nodeHash) + } + + loadCounterfactualWallet = async ( + wallet: string + ): Promise<{ imageHash: string; context: commons.context.WalletContext } | undefined> => { + const db = await this.getDb() + return db.get('counterfactualWallets', wallet) + } + + saveCounterfactualWallet = async (wallet: string, imageHash: string, context: commons.context.WalletContext): Promise => { + const db = await this.getDb() + await db.put('counterfactualWallets', { imageHash, context }, wallet) + } + + loadPayloadOfSubdigest = async (subdigest: string): Promise => { + const db = await this.getDb() + return db.get('payloads', subdigest).then(c => recreateBigNumbers(c)) + } + + savePayloadOfSubdigest = async (subdigest: string, payload: commons.signature.SignedPayload): Promise => { + const db = await this.getDb() + await db.put('payloads', payload, subdigest) + } + + loadSubdigestsOfSigner = async (signer: string): Promise => { + const db = await this.getDb() + const index = await db.getAllKeysFromIndex('signatures', 'signer', IDBKeyRange.only(signer)) + return index.map(key => key.split('-')[0]) + } + + loadSignatureOfSubdigest = async (signer: string, subdigest: string): Promise => { + const db = await this.getDb() + const signature = await db.get('signatures', [subdigest, signer].join('-')) + return signature?.signature + } + + saveSignatureOfSubdigest = async (signer: string, subdigest: string, payload: ethers.BytesLike): Promise => { + const db = await this.getDb() + await db.put('signatures', { signature: payload, signer }, [subdigest, signer].join('-')) + } + + loadMigrationsSubdigest = async ( + wallet: string, + fromVersion: number, + toVersion: number + ): Promise<{ subdigest: string; toImageHash: string }[]> => { + const db = await this.getDb() + const index = await db.getAllFromIndex('migrations', 'jump', IDBKeyRange.only([wallet, fromVersion, toVersion])) + return index.map(key => ({ subdigest: key.subdigest, toImageHash: key.toImageHash })) + } + + saveMigrationsSubdigest = async ( + wallet: string, + fromVersion: number, + toVersion: number, + subdigest: string, + toImageHash: string + ): Promise => { + const db = await this.getDb() + await db.put('migrations', { wallet, fromVersion, toVersion, subdigest, toImageHash }, subdigest) + } +} diff --git a/packages/sessions/src/trackers/stores/memoryStore.ts b/packages/sessions/src/trackers/stores/memoryStore.ts new file mode 100644 index 0000000000..f7a10ae235 --- /dev/null +++ b/packages/sessions/src/trackers/stores/memoryStore.ts @@ -0,0 +1,88 @@ +import { commons, v1, v2 } from '@0xsequence/core' +import { ethers } from 'ethers' +import { PlainNested, PlainNode, PlainV2Config, TrackerStore } from '.' + +export class MemoryTrackerStore implements TrackerStore { + private configs: { [imageHash: string]: v1.config.WalletConfig | v2.config.WalletConfig | PlainV2Config } = {} + private v2Nodes: { [nodeHash: string]: PlainNode | PlainNested | v2.config.Topology } = {} + private counterfactualWallets: { [wallet: string]: { imageHash: string; context: commons.context.WalletContext } } = {} + private payloads: { [subdigest: string]: commons.signature.SignedPayload } = {} + private signatures: { [signer: string]: { [subdigest: string]: ethers.BytesLike } } = {} + private migrations: { + [wallet: string]: { [fromVersion: number]: { [toVersion: number]: { subdigest: string; toImageHash: string }[] } } + } = {} + + loadConfig = (imageHash: string): Promise => { + return Promise.resolve(this.configs[imageHash]) + } + + saveConfig = (imageHash: string, config: v1.config.WalletConfig | v2.config.WalletConfig | PlainV2Config): Promise => { + this.configs[imageHash] = config + return Promise.resolve() + } + + loadV2Node = (nodeHash: string): Promise => { + return Promise.resolve(this.v2Nodes[nodeHash]) + } + + saveV2Node = (nodeHash: string, node: v2.config.Topology | PlainNode | PlainNested): Promise => { + this.v2Nodes[nodeHash] = node + return Promise.resolve() + } + + loadCounterfactualWallet = ( + wallet: string + ): Promise<{ imageHash: string; context: commons.context.WalletContext } | undefined> => { + return Promise.resolve(this.counterfactualWallets[wallet]) + } + + saveCounterfactualWallet = (wallet: string, imageHash: string, context: commons.context.WalletContext): Promise => { + this.counterfactualWallets[wallet] = { imageHash, context } + return Promise.resolve() + } + + loadPayloadOfSubdigest = (subdigest: string): Promise => { + return Promise.resolve(this.payloads[subdigest]) + } + + savePayloadOfSubdigest = (subdigest: string, payload: commons.signature.SignedPayload): Promise => { + this.payloads[subdigest] = payload + return Promise.resolve() + } + + loadSubdigestsOfSigner = (signer: string): Promise => { + return Promise.resolve(Object.keys(this.signatures[signer] || {})) + } + + loadSignatureOfSubdigest = (signer: string, subdigest: string): Promise => { + return Promise.resolve(this.signatures[signer]?.[subdigest]) + } + + saveSignatureOfSubdigest = (signer: string, subdigest: string, payload: ethers.BytesLike): Promise => { + if (!this.signatures[signer]) this.signatures[signer] = {} + this.signatures[signer][subdigest] = payload + return Promise.resolve() + } + + loadMigrationsSubdigest = ( + wallet: string, + fromVersion: number, + toVersion: number + ): Promise<{ subdigest: string; toImageHash: string }[]> => { + return Promise.resolve(this.migrations[wallet]?.[fromVersion]?.[toVersion] || []) + } + + saveMigrationsSubdigest = ( + wallet: string, + fromVersion: number, + toVersion: number, + subdigest: string, + toImageHash: string + ): Promise => { + if (!this.migrations[wallet]) this.migrations[wallet] = {} + if (!this.migrations[wallet][fromVersion]) this.migrations[wallet][fromVersion] = {} + if (!this.migrations[wallet][fromVersion][toVersion]) this.migrations[wallet][fromVersion][toVersion] = [] + this.migrations[wallet][fromVersion][toVersion].push({ subdigest, toImageHash }) + return Promise.resolve() + } +} diff --git a/packages/sessions/tests/local.spec.ts b/packages/sessions/tests/local.spec.ts new file mode 100644 index 0000000000..7dc9a349b1 --- /dev/null +++ b/packages/sessions/tests/local.spec.ts @@ -0,0 +1,1195 @@ +import hardhat from 'hardhat' +import * as chai from 'chai' +import * as utils from '@0xsequence/tests' + +import { trackers, tracker } from '../src/index' +import { commons, universal, v2 } from '@0xsequence/core' +import { ethers } from 'ethers' +import { Wallet } from '@0xsequence/wallet' +import { Orchestrator } from '@0xsequence/signhub' + +// This is a hack to get around the fact that indexedDB is not available in nodejs +import 'fake-indexeddb/auto' + +const { expect } = chai + +const ConfigCases = [ + { + name: 'v1, random', + config: () => utils.configs.random.genRandomV1Config() + }, + { + name: 'v1, no signers', + config: () => utils.configs.random.genRandomV1Config(undefined, 0) + }, + { + name: 'v1, 1 signer', + config: () => utils.configs.random.genRandomV1Config(undefined, 1) + }, + { + name: 'v1, 2 signers', + config: () => utils.configs.random.genRandomV1Config(undefined, 2) + }, + { + name: 'v1, 3 signers', + config: () => utils.configs.random.genRandomV1Config(undefined, 3) + }, + { + name: 'v1, 4 signers', + config: () => utils.configs.random.genRandomV1Config(undefined, 4) + }, + { + name: 'v1, 100 signers', + config: () => utils.configs.random.genRandomV1Config(undefined, 100) + }, + { + name: 'v1, 101 signers', + config: () => utils.configs.random.genRandomV1Config(undefined, 101) + }, + { + name: 'v2 (random)', + config: () => utils.configs.random.genRandomV2Config() + }, + { + name: 'v2, 1 signer', + config: () => utils.configs.random.genRandomV2Config(undefined, undefined, 1, 0) + }, + { + name: 'v2, 2 signers', + config: () => utils.configs.random.genRandomV2Config(undefined, undefined, 2, 0) + }, + { + name: 'v2, 3 signers', + config: () => utils.configs.random.genRandomV2Config(undefined, undefined, 3, 0) + }, + { + name: 'v2, 4 signers', + config: () => utils.configs.random.genRandomV2Config(undefined, undefined, 4, 0) + }, + { + name: 'v2, 5 signers', + config: () => utils.configs.random.genRandomV2Config(undefined, undefined, 5, 0) + }, + { + name: 'v2, 59 signers', + config: () => utils.configs.random.genRandomV2Config(undefined, undefined, 59, 0) + }, + { + name: 'v2, 5 signers (merkle)', + config: () => utils.configs.random.genRandomV2Config(undefined, undefined, 5, 0, true) + }, + { + name: 'v2, 11 signers (merkle)', + config: () => utils.configs.random.genRandomV2Config(undefined, undefined, 11, 0, true) + }, + { + name: 'v2, 101 signers (merkle)', + config: () => utils.configs.random.genRandomV2Config(undefined, undefined, 101, 0, true) + }, + { + name: 'v2, 1 subdigest', + config: () => utils.configs.random.genRandomV2Config(undefined, undefined, 0, 1) + }, + { + name: 'v2, 10 subdigest (merkle)', + config: () => utils.configs.random.genRandomV2Config(undefined, undefined, 0, 10, true) + }, + { + name: 'v2, 12 signers, 55 subdigest (merkle)', + config: () => utils.configs.random.genRandomV2Config(undefined, undefined, 12, 55, true) + }, + { + name: 'v2, random nested configs', + config: () => { + const nested1 = utils.configs.random.genRandomV2Config(undefined, undefined, 11, 10, true) + const nested2 = utils.configs.random.genRandomV2Config() + + return { + version: 2, + threshold: ethers.BigNumber.from(2), + checkpoint: ethers.BigNumber.from(392919), + tree: { + left: { + subdigest: ethers.utils.hexlify(ethers.utils.randomBytes(32)) + }, + right: { + left: { + weight: ethers.BigNumber.from(1), + threshold: ethers.BigNumber.from(99), + tree: nested1.tree + }, + right: { + weight: ethers.BigNumber.from(99), + threshold: ethers.BigNumber.from(1), + tree: nested2.tree + } + } + } + } as v2.config.WalletConfig + } + } +] + +const randomContext = () => { + return { + version: Math.floor(Math.random() * 10) + 1, + factory: ethers.Wallet.createRandom().address, + mainModule: ethers.Wallet.createRandom().address, + mainModuleUpgradable: ethers.Wallet.createRandom().address, + guestModule: ethers.Wallet.createRandom().address, + + walletCreationCode: ethers.utils.hexlify(ethers.utils.randomBytes(32)) + } +} + +const wait = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)) + +describe('Local config tracker', () => { + let provider: ethers.providers.Web3Provider + + before(async () => { + provider = new ethers.providers.Web3Provider(hardhat.network.provider as any) + }) + ;[ + { + name: 'Using memory store', + getTracker: () => new trackers.local.LocalConfigTracker(provider, new trackers.stores.MemoryTrackerStore()) + }, + { + name: 'Using IndexedDB store', + getTracker: () => new trackers.local.LocalConfigTracker(provider, new trackers.stores.IndexedDBStore('test')) + }, + { + name: 'Using multiple trackers (2)', + getTracker: () => { + const tracker1 = new trackers.local.LocalConfigTracker(provider, new trackers.stores.MemoryTrackerStore()) + const tracker2 = new trackers.local.LocalConfigTracker(provider, new trackers.stores.MemoryTrackerStore()) + + return new trackers.MultipleTracker([tracker1, tracker2]) + } + }, + { + name: 'Using multiple trackers (3)', + getTracker: () => { + const tracker1 = new trackers.local.LocalConfigTracker(provider, new trackers.stores.MemoryTrackerStore()) + const tracker2 = new trackers.local.LocalConfigTracker(provider, new trackers.stores.MemoryTrackerStore()) + const tracker3 = new trackers.local.LocalConfigTracker(provider, new trackers.stores.IndexedDBStore('test-2')) + + return new trackers.MultipleTracker([tracker1, tracker2, tracker3]) + } + }, + { + name: 'Using a cached tracker', + getTracker: () => { + const tracker = new trackers.local.LocalConfigTracker(provider, new trackers.stores.MemoryTrackerStore()) + const cache = new trackers.local.LocalConfigTracker(provider, new trackers.stores.MemoryTrackerStore()) + return new trackers.CachedTracker(tracker, cache, {}) + } + }, + { + name: 'Using a deduped tracker', + getTracker: () => { + const tracker = new trackers.local.LocalConfigTracker(provider, new trackers.stores.MemoryTrackerStore()) + return new trackers.DedupedTracker(tracker, 50) + } + } + ].map(({ name, getTracker }) => { + describe(name, () => { + let tracker: tracker.ConfigTracker + + beforeEach(() => { + tracker = getTracker() + }) + + describe('Configuration', () => { + ConfigCases.map(o => { + it(`Should be able to set and get ${o.name}`, async () => { + const config = o.config() + + await tracker.saveWalletConfig({ config }) + + const imageHash = universal.genericCoderFor(config.version).config.imageHashOf(config) + const getConfig = await tracker.configOfImageHash({ imageHash }) + + expect(normalize(getConfig)).to.deep.equal(normalize(config)) + }) + }) + + it('Should handle all cases at once', async () => { + const shuffled = ConfigCases.sort(() => Math.random() - 0.5) + const configs = shuffled.map(o => o.config()) + + for (const config of configs) { + await tracker.saveWalletConfig({ config }) + + const imageHash = universal.genericCoderFor(config.version).config.imageHashOf(config) + const getConfig = await tracker.configOfImageHash({ imageHash }) + + expect(normalize(getConfig)).to.deep.equal(normalize(config)) + } + + for (const config of configs) { + const imageHash = universal.genericCoderFor(config.version).config.imageHashOf(config) + const getConfig = await tracker.configOfImageHash({ imageHash }) + + expect(normalize(getConfig)).to.deep.equal(normalize(config)) + } + + // Adding the configs again should not change anything + for (const config of configs) { + await tracker.saveWalletConfig({ config }) + + const imageHash = universal.genericCoderFor(config.version).config.imageHashOf(config) + const getConfig = await tracker.configOfImageHash({ imageHash }) + + expect(normalize(getConfig)).to.deep.equal(normalize(config)) + } + }) + + it.skip('Should combine two different v2 configurations', async () => { + const config1 = utils.configs.random.genRandomV2Config(undefined, undefined, 25, 15, true) + const config2 = utils.configs.random.genRandomV2Config(undefined, undefined, 2, 1, false) + + const ih1 = v2.config.imageHash(config1) + const ih2 = v2.config.imageHash(config2) + + const emptyConfig = { + version: 2, + threshold: ethers.BigNumber.from(2), + checkpoint: ethers.BigNumber.from(0), + tree: { + left: { nodeHash: v2.config.hashNode(config1.tree) }, + right: { nodeHash: v2.config.hashNode(config2.tree) } + } + } + + const imageHash = v2.config.imageHash(emptyConfig) + + await tracker.saveWalletConfig({ config: emptyConfig }) + expect(normalize(await tracker.configOfImageHash({ imageHash }))).to.deep.equal(normalize(emptyConfig)) + + // Add the first config + // should reveal the left branch + await tracker.saveWalletConfig({ config: config1 }) + + // The deduped tracker may cache the result a bit, so if we see a window + // we apply a small delay + if ((tracker as any).window) { + await new Promise(resolve => setTimeout(resolve, 100)) + } + + expect(normalize(await tracker.configOfImageHash({ imageHash: ih1 }))).to.deep.equal(normalize(config1)) + expect(normalize(await tracker.configOfImageHash({ imageHash }))).to.deep.equal( + normalize({ + version: 2, + threshold: ethers.BigNumber.from(2), + checkpoint: ethers.BigNumber.from(0), + tree: { + left: config1.tree, + right: { nodeHash: v2.config.hashNode(config2.tree) } + } + }) + ) + + // Add the second config + // should reveal the whole tree + await tracker.saveWalletConfig({ config: config2 }) + + if ((tracker as any).window) { + await new Promise(resolve => setTimeout(resolve, 100)) + } + + expect(normalize(await tracker.configOfImageHash({ imageHash: ih2 }))).to.deep.equal(normalize(config2)) + expect(normalize(await tracker.configOfImageHash({ imageHash }))).to.deep.equal( + normalize({ + version: 2, + threshold: ethers.BigNumber.from(2), + checkpoint: ethers.BigNumber.from(0), + tree: { + left: config1.tree, + right: config2.tree + } + }) + ) + }) + + it('Should return undefined for unknown imageHash', async () => { + const imageHash = ethers.utils.hexlify(ethers.utils.randomBytes(32)) + expect(await tracker.configOfImageHash({ imageHash })).to.be.undefined + }) + + it('Should handle the same request multiple times', async () => { + const config = utils.configs.random.genRandomV1Config() + const imageHash = universal.genericCoderFor(config.version).config.imageHashOf(config) + + await Promise.all(new Array(10).fill(0).map(async () => tracker.saveWalletConfig({ config }))) + const results = await Promise.all(new Array(10).fill(0).map(async () => tracker.configOfImageHash({ imageHash }))) + + expect(results).to.deep.equal(new Array(10).fill(config)) + }) + }) + + describe('Counterfactual address', () => { + it('Should set and get address', async () => { + const context = randomContext() + const config = utils.configs.random.genRandomV1Config() + const imageHash = universal.genericCoderFor(config.version).config.imageHashOf(config) + + const wallet = commons.context.addressOf(context, imageHash) + await tracker.saveCounterfactualWallet({ config, context: [context] }) + const res = await tracker.imageHashOfCounterfactualWallet({ wallet }) + + expect(res).to.deep.equal({ imageHash, context }) + }) + + it('Should set address for multiple configs', async () => { + const contexts = new Array(5).fill(0).map(() => randomContext()) + const config = utils.configs.random.genRandomV1Config() + const imageHash = universal.genericCoderFor(config.version).config.imageHashOf(config) + + const wallets = contexts.map(c => commons.context.addressOf(c, imageHash)) + await tracker.saveCounterfactualWallet({ config, context: contexts }) + + for (let i = 0; i < wallets.length; i++) { + const res = await tracker.imageHashOfCounterfactualWallet({ wallet: wallets[i] }) + expect(res).to.deep.equal({ imageHash, context: contexts[i] }) + } + }) + + it('Should return undefined for unknown wallet', async () => { + const wallet = ethers.Wallet.createRandom().address + expect(await tracker.imageHashOfCounterfactualWallet({ wallet })).to.be.undefined + }) + + it('Should handle the same request multiple times', async () => { + const context = randomContext() + const config = utils.configs.random.genRandomV1Config() + const imageHash = universal.genericCoderFor(config.version).config.imageHashOf(config) + + const wallet = commons.context.addressOf(context, imageHash) + await Promise.all( + new Array(10).fill(0).map(async () => tracker.saveCounterfactualWallet({ config, context: [context] })) + ) + + const results = await Promise.all( + new Array(10).fill(0).map(async () => tracker.imageHashOfCounterfactualWallet({ wallet })) + ) + expect(results).to.deep.equal(new Array(10).fill({ imageHash, context })) + }) + }) + + describe('Chained configurations', () => { + let context: commons.context.WalletContext + + before(async () => { + context = await utils.context.deploySequenceContexts(provider.getSigner(0)).then(c => c[2]) + }) + + it('Should return return empty chained configuration if config is not known', async () => { + const imageHash = ethers.utils.hexlify(ethers.utils.randomBytes(32)) + const res = await tracker.loadPresignedConfiguration({ + wallet: ethers.Wallet.createRandom().address, + fromImageHash: imageHash + }) + expect(res).to.deep.equal([]) + }) + + it('Should return no chained configuration if no presigned transactions', async () => { + const config = utils.configs.random.genRandomV2Config() + const imageHash = v2.config.imageHash(config) + await tracker.saveWalletConfig({ config }) + const res = await tracker.loadPresignedConfiguration({ + wallet: ethers.Wallet.createRandom().address, + fromImageHash: imageHash + }) + expect(res).to.deep.equal([]) + }) + + it('Should return single presigned step', async () => { + const signer = ethers.Wallet.createRandom() + const config = { version: 2, threshold: 1, checkpoint: 0, tree: { address: signer.address, weight: 1 } } + const imageHash = v2.config.imageHash(config) + const address = commons.context.addressOf(context, imageHash) + const wallet = new Wallet({ + config, + chainId: 0, + coders: v2.coders, + address, + context, + orchestrator: new Orchestrator([signer]) + }) + + const nextConfig = utils.configs.random.genRandomV2Config() + const nextImageHash = v2.config.imageHash(nextConfig) + + const digest = v2.chained.hashSetImageHash(nextImageHash) + const signature = await wallet.signDigest(digest) + + await tracker.saveWalletConfig({ config }) + await tracker.saveWalletConfig({ config: nextConfig }) + await tracker.savePresignedConfiguration({ wallet: address, nextConfig, signature }) + + const res = await tracker.loadPresignedConfiguration({ wallet: address, fromImageHash: imageHash }) + expect(res.length).to.equal(1) + expect(res[0].nextImageHash).to.equal(nextImageHash) + expect(res[0].wallet).to.equal(wallet.address) + expect(res[0].signature).to.equal(signature) + }) + + it('Should return empty for wrong wallet', async () => { + const signer = ethers.Wallet.createRandom() + const config = { version: 2, threshold: 1, checkpoint: 0, tree: { address: signer.address, weight: 1 } } + const imageHash = v2.config.imageHash(config) + const address = commons.context.addressOf(context, imageHash) + const wallet = new Wallet({ + config, + chainId: 0, + coders: v2.coders, + address, + context, + orchestrator: new Orchestrator([signer]) + }) + + const nextConfig = utils.configs.random.genRandomV2Config() + const nextImageHash = v2.config.imageHash(nextConfig) + + const digest = v2.chained.hashSetImageHash(nextImageHash) + const signature = await wallet.signDigest(digest) + + await tracker.saveWalletConfig({ config }) + await tracker.saveWalletConfig({ config: nextConfig }) + await tracker.savePresignedConfiguration({ wallet: address, nextConfig, signature }) + + const wrongWallet = ethers.Wallet.createRandom().address + const res = await tracker.loadPresignedConfiguration({ wallet: wrongWallet, fromImageHash: imageHash }) + expect(res.length).to.equal(0) + }) + + it('Should return two steps', async () => { + // Step 1 + const signer = ethers.Wallet.createRandom() + const config = { version: 2, threshold: 1, checkpoint: 0, tree: { address: signer.address, weight: 1 } } + const imageHash = v2.config.imageHash(config) + + const address = commons.context.addressOf(context, imageHash) + const wallet1 = new Wallet({ + config, + chainId: 0, + coders: v2.coders, + address, + context, + orchestrator: new Orchestrator([signer]) + }) + + const signer2a = ethers.Wallet.createRandom() + const signer2b = ethers.Wallet.createRandom() + const nextConfig1 = { + version: 2, + threshold: 6, + checkpoint: 2, + tree: { + right: { + address: signer2a.address, + weight: 3 + }, + left: { + address: signer2b.address, + weight: 3 + } + } + } + + const nextImageHash1 = v2.config.imageHash(nextConfig1) + + const digest1 = v2.chained.hashSetImageHash(nextImageHash1) + const signature1 = await wallet1.signDigest(digest1) + + // Step 2 + const nextConfig2 = { ...utils.configs.random.genRandomV2Config(), checkpoint: 3 } + const nextImageHash2 = v2.config.imageHash(nextConfig2) + + const digest2 = v2.chained.hashSetImageHash(nextImageHash2) + const wallet2 = new Wallet({ + config: nextConfig1, + chainId: 0, + coders: v2.coders, + address, + context, + orchestrator: new Orchestrator([signer2a, signer2b]) + }) + + const signature2 = await wallet2.signDigest(digest2) + + // Saving only signature2 should lead to empty path + // because there is no route from initial config to config1 + await tracker.saveWalletConfig({ config }) + await tracker.saveWalletConfig({ config: nextConfig1 }) + await tracker.saveWalletConfig({ config: nextConfig2 }) + await tracker.savePresignedConfiguration({ + wallet: address, + nextConfig: nextConfig2, + signature: signature2 + }) + + const route0_2a = await tracker.loadPresignedConfiguration({ + wallet: address, + fromImageHash: imageHash + }) + + expect(route0_2a.length).to.equal(0) + + // But starting from imageHash1 should give us a link + const result1_2a = await tracker.loadPresignedConfiguration({ + wallet: address, + fromImageHash: nextImageHash1 + }) + + expect(result1_2a.length).to.equal(1) + expect(result1_2a[0].nextImageHash).to.equal(nextImageHash2) + expect(result1_2a[0].signature).to.equal(signature2) + expect(result1_2a[0].wallet).to.equal(address) + + // Adding the 0_1 step should give us a full chain to 2 + await tracker.savePresignedConfiguration({ + wallet: address, + nextConfig: nextConfig1, + signature: signature1 + }) + + if ((tracker as any).window) { + await new Promise(resolve => setTimeout(resolve, 100)) + } + + const result0_2b = await tracker.loadPresignedConfiguration({ + wallet: address, + fromImageHash: imageHash + }) + + expect(result0_2b.length).to.equal(2) + expect(result0_2b[0].wallet).to.equal(address) + expect(result0_2b[1].wallet).to.equal(address) + expect(result0_2b[0].nextImageHash).to.equal(nextImageHash1) + expect(result0_2b[1].nextImageHash).to.equal(nextImageHash2) + expect(result0_2b[0].signature).to.equal(signature1) + expect(result0_2b[1].signature).to.equal(signature2) + }) + + it('Should skip step if it uses the same signers', async () => { + const signer1 = ethers.Wallet.createRandom() + const config1 = { version: 2, threshold: 1, checkpoint: 0, tree: { address: signer1.address, weight: 1 } } + const imageHash1 = v2.config.imageHash(config1) + const address = commons.context.addressOf(context, imageHash1) + const wallet = new Wallet({ + config: config1, + chainId: 0, + coders: v2.coders, + address, + context, + orchestrator: new Orchestrator([signer1]) + }) + + const signer2 = ethers.Wallet.createRandom() + const config2 = { + version: 2, + threshold: 3, + checkpoint: 1, + tree: { + left: { + address: signer1.address, + weight: 3 + }, + right: { + address: signer2.address, + weight: 4 + } + } + } + + const imageHash2 = v2.config.imageHash(config2) + + const digest1 = v2.chained.hashSetImageHash(imageHash2) + const signature1 = await wallet.signDigest(digest1) + + const config3 = utils.configs.random.genRandomV2Config() + const imageHash3 = v2.config.imageHash(config3) + + const digest2 = v2.chained.hashSetImageHash(imageHash3) + const wallet2 = new Wallet({ + config: config2, + chainId: 0, + coders: v2.coders, + address, + context, + orchestrator: new Orchestrator([signer1, signer2]) + }) + + const signature2 = await wallet2.signDigest(digest2) + + await tracker.saveWalletConfig({ config: config1 }) + await tracker.saveWalletConfig({ config: config2 }) + await tracker.saveWalletConfig({ config: config3 }) + await tracker.savePresignedConfiguration({ wallet: address, nextConfig: config2, signature: signature1 }) + await tracker.savePresignedConfiguration({ wallet: address, nextConfig: config3, signature: signature2 }) + + // Going from 1 to 3 should give us 1 jump + const resa = await tracker.loadPresignedConfiguration({ + wallet: address, + fromImageHash: imageHash1 + }) + + expect(resa.length).to.equal(1) + expect(resa[0].wallet).to.equal(address) + expect(resa[0].nextImageHash).to.equal(imageHash3) + // This is equivalent to having signed the update + // with only signer1 (because that's what we have in imageHash1) + expect(resa[0].signature).to.equal(await wallet.signDigest(digest2)) + + // Unless we ask for the longest path, then we should find + // both jumps + const resb = await tracker.loadPresignedConfiguration({ + wallet: address, + fromImageHash: imageHash1, + longestPath: true + }) + + expect(resb.length).to.equal(2) + expect(resb[0].wallet).to.equal(address) + expect(resb[1].wallet).to.equal(address) + expect(resb[0].nextImageHash).to.equal(imageHash2) + expect(resb[1].nextImageHash).to.equal(imageHash3) + expect(resb[0].signature).to.equal(signature1) + expect(resb[1].signature).to.equal(signature2) + + // Should return wallets of signer1 and signer2 + const wallets1 = await tracker.walletsOfSigner({ signer: signer1.address }) + expect(wallets1.length).to.equal(1) + expect(wallets1[0].wallet).to.equal(address) + + const wallets2 = await tracker.walletsOfSigner({ signer: signer2.address }) + expect(wallets2.length).to.equal(1) + expect(wallets2[0].wallet).to.equal(address) + }) + }) + + describe('Handle witnesses', async () => { + let context: commons.context.WalletContext + + before(async () => { + context = await utils.context.deploySequenceContexts(provider.getSigner(0)).then(c => c[2]) + }) + + it('Should retrieve no witness for never used signer', async () => { + const signer = ethers.Wallet.createRandom().address + const witness = await tracker.walletsOfSigner({ signer }) + expect(witness.length).to.equal(0) + }) + + it('Should save a witness for a signer', async () => { + const signer = ethers.Wallet.createRandom() + const config = { version: 2, threshold: 1, checkpoint: 0, tree: { address: signer.address, weight: 1 } } + const imageHash = v2.config.imageHash(config) + const address = commons.context.addressOf(context, imageHash) + const wallet = new Wallet({ + config, + chainId: 1, + coders: v2.coders, + address, + context, + orchestrator: new Orchestrator([signer]) + }) + + const digest = ethers.utils.hexlify(ethers.utils.randomBytes(32)) + const signature = await wallet.signDigest(digest) + + const decoded = v2.signature.SignatureCoder.decode(signature) + await tracker.saveWitnesses({ + wallet: address, + digest, + chainId: 1, + signatures: [(decoded.decoded.tree as v2.signature.SignatureLeaf).signature] + }) + + const witness = await tracker.walletsOfSigner({ signer: signer.address }) + expect(witness.length).to.equal(1) + expect(witness[0].wallet).to.equal(address) + expect(witness[0].proof.chainId.toNumber()).to.equal(1) + expect(witness[0].proof.digest).to.equal(digest) + expect(witness[0].proof.signature).to.equal((decoded.decoded.tree as v2.signature.SignatureLeaf).signature) + + // Adding a second witness should not change anything + const digest2 = ethers.utils.hexlify(ethers.utils.randomBytes(32)) + const signature2 = await wallet.signDigest(digest2) + const decoded2 = v2.signature.SignatureCoder.decode(signature2) + await tracker.saveWitnesses({ + wallet: address, + digest: digest2, + chainId: 1, + signatures: [(decoded2.decoded.tree as v2.signature.SignatureLeaf).signature] + }) + + const witness2 = await tracker.walletsOfSigner({ signer: signer.address }) + expect(witness2.length).to.equal(1) + + // Adding a witness for a different chain should not change anything + const digest3 = ethers.utils.hexlify(ethers.utils.randomBytes(32)) + const wallet2 = new Wallet({ + config, + chainId: 2, + coders: v2.coders, + address, + context, + orchestrator: new Orchestrator([signer]) + }) + const signature3 = await wallet2.signDigest(digest3) + const decoded3 = v2.signature.SignatureCoder.decode(signature3) + await tracker.saveWitnesses({ + wallet: address, + digest: digest3, + chainId: 2, + signatures: [(decoded3.decoded.tree as v2.signature.SignatureLeaf).signature] + }) + + const witness3 = await tracker.walletsOfSigner({ signer: signer.address }) + expect(witness3.length).to.equal(1) + }) + + it('It should save witnesses for multiple wallets', async () => { + const signer = ethers.Wallet.createRandom() + const config = { version: 2, threshold: 1, checkpoint: 0, tree: { address: signer.address, weight: 1 } } + const imageHash = v2.config.imageHash(config) + const address = commons.context.addressOf(context, imageHash) + const wallet = new Wallet({ + config, + chainId: 1, + coders: v2.coders, + address, + context, + orchestrator: new Orchestrator([signer]) + }) + + const digest = ethers.utils.hexlify(ethers.utils.randomBytes(32)) + const signature = await wallet.signDigest(digest) + + const decoded = v2.signature.SignatureCoder.decode(signature) + await tracker.saveWitnesses({ + wallet: address, + digest, + chainId: 1, + signatures: [(decoded.decoded.tree as v2.signature.SignatureLeaf).signature] + }) + + const config2 = { version: 2, threshold: 2, checkpoint: 0, tree: { address: signer.address, weight: 2 } } + const imageHash2 = v2.config.imageHash(config2) + const address2 = commons.context.addressOf(context, imageHash2) + const wallet2 = new Wallet({ + config: config2, + chainId: 1, + coders: v2.coders, + address: address2, + context, + orchestrator: new Orchestrator([signer]) + }) + + const digest2 = ethers.utils.hexlify(ethers.utils.randomBytes(32)) + const signature2 = await wallet2.signDigest(digest2) + + const decoded2 = v2.signature.SignatureCoder.decode(signature2) + await tracker.saveWitnesses({ + wallet: address2, + digest: digest2, + chainId: 1, + signatures: [(decoded2.decoded.tree as v2.signature.SignatureLeaf).signature] + }) + + const witness = await tracker.walletsOfSigner({ signer: signer.address }) + expect(witness.length).to.equal(2) + + const wallet1Result = witness.find(w => w.wallet === address) + const wallet2Result = witness.find(w => w.wallet === address2) + expect(wallet1Result).to.not.be.undefined + expect(wallet2Result).to.not.be.undefined + + expect(wallet1Result?.proof.chainId.toNumber()).to.equal(1) + expect(wallet1Result?.proof.digest).to.equal(digest) + expect(wallet1Result?.proof.signature).to.equal((decoded.decoded.tree as v2.signature.SignatureLeaf).signature) + + expect(wallet2Result?.proof.chainId.toNumber()).to.equal(1) + expect(wallet2Result?.proof.digest).to.equal(digest2) + expect(wallet2Result?.proof.signature).to.equal((decoded2.decoded.tree as v2.signature.SignatureLeaf).signature) + }) + }) + }) + }) + + describe('Multiple config trackers', () => { + let tracker1: trackers.local.LocalConfigTracker + let tracker2: trackers.local.LocalConfigTracker + + let combined: trackers.MultipleTracker + + beforeEach(async () => { + tracker1 = new trackers.local.LocalConfigTracker(provider) + tracker2 = new trackers.local.LocalConfigTracker(provider) + + combined = new trackers.MultipleTracker([tracker1, tracker2]) + }) + + describe('Config', () => { + it('Storing a config should store it in both', async () => { + const config = { + version: 2, + threshold: ethers.BigNumber.from(1), + checkpoint: ethers.BigNumber.from(0), + tree: { + address: ethers.Wallet.createRandom().address, + weight: ethers.BigNumber.from(1) + } + } + + const imageHash = v2.config.imageHash(config) + + await combined.saveWalletConfig({ config }) + + const config1 = await tracker1.configOfImageHash({ imageHash }) + const config2 = await tracker2.configOfImageHash({ imageHash }) + + expect(config1).to.deep.equal(config) + expect(config2).to.deep.equal(config) + }) + + it('Retrieving a config from tracker1, should mirror to tracker2', async () => { + const config = { + version: 2, + threshold: ethers.BigNumber.from(1), + checkpoint: ethers.BigNumber.from(0), + tree: { + address: ethers.Wallet.createRandom().address, + weight: ethers.BigNumber.from(1) + } + } + + const imageHash = v2.config.imageHash(config) + + await tracker1.saveWalletConfig({ config }) + + const config1 = await combined.configOfImageHash({ imageHash }) + + await wait(500) + + const config2 = await tracker2.configOfImageHash({ imageHash }) + + expect(config1).to.deep.equal(config) + expect(config2).to.deep.equal(config) + }) + + it.skip('Should combine 2 different sources', async () => { + const node1 = { + address: ethers.Wallet.createRandom().address, + weight: ethers.BigNumber.from(1) + } + + const node2 = { + address: ethers.Wallet.createRandom().address, + weight: ethers.BigNumber.from(1) + } + + const config1 = { + version: 2, + threshold: ethers.BigNumber.from(1), + checkpoint: ethers.BigNumber.from(1234), + tree: { + left: { + nodeHash: v2.config.hashNode(node1) + }, + right: node2 + } + } + + const config2 = { + version: 2, + threshold: ethers.BigNumber.from(1), + checkpoint: ethers.BigNumber.from(1234), + tree: { + left: node1, + right: { + nodeHash: v2.config.hashNode(node2) + } + } + } + + const configAll = { + version: 2, + threshold: ethers.BigNumber.from(1), + checkpoint: ethers.BigNumber.from(1234), + tree: { + left: node1, + right: node2 + } + } + + await tracker1.saveWalletConfig({ config: config1 }) + await tracker2.saveWalletConfig({ config: config2 }) + + const imageHash = v2.config.imageHash(config2) + const res1 = await combined.configOfImageHash({ imageHash }) + const res2 = await tracker1.configOfImageHash({ imageHash }) + const res3 = await tracker2.configOfImageHash({ imageHash }) + + expect(res1).to.deep.equal(configAll) + expect(res2).to.deep.equal(configAll) + expect(res3).to.deep.equal(configAll) + }) + }) + + describe('Counterfactual addresses', () => { + it('Should store counterfactual address in both', async () => { + const context = randomContext() + const config = utils.configs.random.genRandomV1Config() + const imageHash = universal.genericCoderFor(config.version).config.imageHashOf(config) + + const wallet = commons.context.addressOf(context, imageHash) + await combined.saveCounterfactualWallet({ config, context: [context] }) + + const res1 = await combined.imageHashOfCounterfactualWallet({ wallet }) + const res2 = await tracker1.imageHashOfCounterfactualWallet({ wallet }) + const res3 = await tracker2.imageHashOfCounterfactualWallet({ wallet }) + + expect(res1).to.deep.equal({ imageHash, context }) + expect(res2).to.deep.equal({ imageHash, context }) + expect(res3).to.deep.equal({ imageHash, context }) + }) + + it('Should mirror counterfactual address from tracker1', async () => { + const context = randomContext() + const config = utils.configs.random.genRandomV1Config() + const imageHash = universal.genericCoderFor(config.version).config.imageHashOf(config) + + const wallet = commons.context.addressOf(context, imageHash) + await tracker1.saveCounterfactualWallet({ config, context: [context] }) + + const res1 = await combined.imageHashOfCounterfactualWallet({ wallet }) + + await wait(500) + + const res2 = await tracker1.imageHashOfCounterfactualWallet({ wallet }) + const res3 = await tracker2.imageHashOfCounterfactualWallet({ wallet }) + + expect(res1).to.deep.equal({ imageHash, context }) + expect(res2).to.deep.equal({ imageHash, context }) + expect(res3).to.deep.equal({ imageHash, context }) + }) + }) + + describe('Chained configurations', () => { + let context: commons.context.WalletContext + + before(async () => { + context = await utils.context.deploySequenceContexts(provider.getSigner(0)).then(c => c[2]) + }) + + it('Should store chained config in both', async () => { + const signer = ethers.Wallet.createRandom() + const config = { version: 2, threshold: 1, checkpoint: 0, tree: { address: signer.address, weight: 1 } } + const imageHash = v2.config.imageHash(config) + const address = commons.context.addressOf(context, imageHash) + const wallet = new Wallet({ + config, + chainId: 0, + coders: v2.coders, + address, + context, + orchestrator: new Orchestrator([signer]) + }) + + const nextConfig = utils.configs.random.genRandomV2Config() + const nextImageHash = v2.config.imageHash(nextConfig) + + const digest = v2.chained.hashSetImageHash(nextImageHash) + const signature = await wallet.signDigest(digest) + + await combined.saveWalletConfig({ config }) + await combined.saveWalletConfig({ config: nextConfig }) + await combined.savePresignedConfiguration({ wallet: address, nextConfig, signature }) + + const res2 = await tracker1.loadPresignedConfiguration({ wallet: address, fromImageHash: imageHash }) + const res3 = await tracker2.loadPresignedConfiguration({ wallet: address, fromImageHash: imageHash }) + const res1 = await combined.loadPresignedConfiguration({ wallet: address, fromImageHash: imageHash }) + + expect(res1.length).to.equal(1) + expect(res1[0].nextImageHash).to.equal(nextImageHash) + expect(res1[0].wallet).to.equal(wallet.address) + expect(res1[0].signature).to.equal(signature) + + expect(res2.length).to.equal(1) + expect(res2[0].nextImageHash).to.equal(nextImageHash) + expect(res2[0].wallet).to.equal(wallet.address) + expect(res2[0].signature).to.equal(signature) + + expect(res3.length).to.equal(1) + expect(res3[0].nextImageHash).to.equal(nextImageHash) + expect(res3[0].wallet).to.equal(wallet.address) + expect(res3[0].signature).to.equal(signature) + }) + + it('Should mirror chained config from tracker2', async () => { + const signer = ethers.Wallet.createRandom() + const config = { version: 2, threshold: 1, checkpoint: 0, tree: { address: signer.address, weight: 1 } } + const imageHash = v2.config.imageHash(config) + const address = commons.context.addressOf(context, imageHash) + const wallet = new Wallet({ + config, + chainId: 0, + coders: v2.coders, + address, + context, + orchestrator: new Orchestrator([signer]) + }) + + const nextConfig = utils.configs.random.genRandomV2Config() + const nextImageHash = v2.config.imageHash(nextConfig) + + const digest = v2.chained.hashSetImageHash(nextImageHash) + const signature = await wallet.signDigest(digest) + + await tracker2.saveWalletConfig({ config }) + await tracker2.saveWalletConfig({ config: nextConfig }) + await tracker2.savePresignedConfiguration({ wallet: address, nextConfig, signature }) + + const res1 = await combined.loadPresignedConfiguration({ wallet: address, fromImageHash: imageHash }) + + await wait(500) + + const res2 = await tracker1.loadPresignedConfiguration({ wallet: address, fromImageHash: imageHash }) + const res3 = await tracker2.loadPresignedConfiguration({ wallet: address, fromImageHash: imageHash }) + + expect(res1.length).to.equal(1) + expect(res1[0].nextImageHash).to.equal(nextImageHash) + expect(res1[0].wallet).to.equal(wallet.address) + expect(res1[0].signature).to.equal(signature) + + expect(res2.length).to.equal(1) + expect(res2[0].nextImageHash).to.equal(nextImageHash) + expect(res2[0].wallet).to.equal(wallet.address) + expect(res2[0].signature).to.equal(signature) + + expect(res3.length).to.equal(1) + expect(res3[0].nextImageHash).to.equal(nextImageHash) + expect(res3[0].wallet).to.equal(wallet.address) + expect(res3[0].signature).to.equal(signature) + }) + + it('Should return highest checkpoint chain (and then mirror)', async () => { + // Step 1 + const signer = ethers.Wallet.createRandom() + const config = { version: 2, threshold: 1, checkpoint: 0, tree: { address: signer.address, weight: 1 } } + const imageHash = v2.config.imageHash(config) + + const address = commons.context.addressOf(context, imageHash) + const wallet1 = new Wallet({ + config, + chainId: 0, + coders: v2.coders, + address, + context, + orchestrator: new Orchestrator([signer]) + }) + + const signer2a = ethers.Wallet.createRandom() + const signer2b = ethers.Wallet.createRandom() + const nextConfig1 = { + version: 2, + threshold: 6, + checkpoint: 2, + tree: { + right: { + address: signer2a.address, + weight: 3 + }, + left: { + address: signer2b.address, + weight: 3 + } + } + } + + const nextImageHash1 = v2.config.imageHash(nextConfig1) + + const digest1 = v2.chained.hashSetImageHash(nextImageHash1) + const signature1 = await wallet1.signDigest(digest1) + + // Step 2 + const nextConfig2 = { ...utils.configs.random.genRandomV2Config(), checkpoint: 3 } + const nextImageHash2 = v2.config.imageHash(nextConfig2) + + const digest2 = v2.chained.hashSetImageHash(nextImageHash2) + const wallet2 = new Wallet({ + config: nextConfig1, + chainId: 0, + coders: v2.coders, + address, + context, + orchestrator: new Orchestrator([signer2a, signer2b]) + }) + + const signature2 = await wallet2.signDigest(digest2) + + // Saving only signature1 on tracker 1 + await tracker1.saveWalletConfig({ config }) + await tracker1.saveWalletConfig({ config: nextConfig1 }) + await tracker1.savePresignedConfiguration({ + wallet: address, + nextConfig: nextConfig1, + signature: signature1 + }) + + // Saving both signatures on tracker 2 + await tracker2.saveWalletConfig({ config }) + await tracker2.saveWalletConfig({ config: nextConfig1 }) + await tracker2.saveWalletConfig({ config: nextConfig2 }) + await tracker2.savePresignedConfiguration({ + wallet: address, + nextConfig: nextConfig1, + signature: signature1 + }) + await tracker2.savePresignedConfiguration({ + wallet: address, + nextConfig: nextConfig2, + signature: signature2 + }) + + // Now the combined tracker should return the highest checkpoint + const res1 = await combined.loadPresignedConfiguration({ wallet: address, fromImageHash: imageHash }) + + await wait(500) + + const res2 = await tracker1.loadPresignedConfiguration({ wallet: address, fromImageHash: imageHash }) + const res3 = await tracker2.loadPresignedConfiguration({ wallet: address, fromImageHash: imageHash }) + + expect(res1.length).to.equal(2) + expect(res1[0].wallet).to.equal(address) + expect(res1[1].wallet).to.equal(address) + expect(res1[0].nextImageHash).to.equal(nextImageHash1) + expect(res1[1].nextImageHash).to.equal(nextImageHash2) + expect(res1[0].signature).to.equal(signature1) + expect(res1[1].signature).to.equal(signature2) + + expect(res2).to.deep.equal(res1) + expect(res3).to.deep.equal(res1) + }) + }) + }) +}) + +function normalize(value: any): any { + switch (typeof value) { + case 'object': + if (ethers.BigNumber.isBigNumber(value)) { + return value.toString() + } + return Object.fromEntries(Object.entries(value).map(([key, value]) => [key, normalize(value)])) + case 'number': + return `${value}` + default: + return value + } +} diff --git a/packages/signhub/CHANGELOG.md b/packages/signhub/CHANGELOG.md new file mode 100644 index 0000000000..2e1aad4fbf --- /dev/null +++ b/packages/signhub/CHANGELOG.md @@ -0,0 +1,935 @@ +# @0xsequence/signhub + +## 2.0.0 + +### Major Changes + +- changeset + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@2.0.0 + +## 1.10.14 + +### Patch Changes + +- network: add borne-testnet to allNetworks +- Updated dependencies + - @0xsequence/core@1.10.14 + +## 1.10.13 + +### Patch Changes + +- network: add borne testnet +- Updated dependencies + - @0xsequence/core@1.10.13 + +## 1.10.12 + +### Patch Changes + +- api: update bindings +- global/window -> globalThis +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.10.12 + +## 1.10.11 + +### Patch Changes + +- waas: updated intent.gen without webrpc types, errors exported from authenticator.gen +- Updated dependencies + - @0xsequence/core@1.10.11 + +## 1.10.10 + +### Patch Changes + +- metadata: update bindings with new contract collections api +- Updated dependencies + - @0xsequence/core@1.10.10 + +## 1.10.9 + +### Patch Changes + +- waas minor update +- Updated dependencies + - @0xsequence/core@1.10.9 + +## 1.10.8 + +### Patch Changes + +- update metadata bindings +- Updated dependencies + - @0xsequence/core@1.10.8 + +## 1.10.7 + +### Patch Changes + +- minor fixes to waas client +- Updated dependencies + - @0xsequence/core@1.10.7 + +## 1.10.6 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/core@1.10.6 + +## 1.10.5 + +### Patch Changes + +- network: ape-chain-testnet -> apechain-testnet +- Updated dependencies + - @0xsequence/core@1.10.5 + +## 1.10.4 + +### Patch Changes + +- network: add b3-sepolia, ape-chain-testnet, blast, blast-sepolia +- Updated dependencies + - @0xsequence/core@1.10.4 + +## 1.10.3 + +### Patch Changes + +- typing fix +- Updated dependencies + - @0xsequence/core@1.10.3 + +## 1.10.2 + +### Patch Changes + +- - waas: add getIdToken method + - indexer: update api client +- Updated dependencies + - @0xsequence/core@1.10.2 + +## 1.10.1 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/core@1.10.1 + +## 1.10.0 + +### Minor Changes + +- waas release v1.3.0 + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.10.0 + +## 1.9.37 + +### Patch Changes + +- network: adds nativeToken data to NetworkMetadata constants +- Updated dependencies + - @0xsequence/core@1.9.37 + +## 1.9.36 + +### Patch Changes + +- guard: export client +- Updated dependencies + - @0xsequence/core@1.9.36 + +## 1.9.35 + +### Patch Changes + +- guard: update bindings +- Updated dependencies + - @0xsequence/core@1.9.35 + +## 1.9.34 + +### Patch Changes + +- waas: always use lowercase email +- Updated dependencies + - @0xsequence/core@1.9.34 + +## 1.9.33 + +### Patch Changes + +- waas: umd build +- Updated dependencies + - @0xsequence/core@1.9.33 + +## 1.9.32 + +### Patch Changes + +- indexer: update bindings +- Updated dependencies + - @0xsequence/core@1.9.32 + +## 1.9.31 + +### Patch Changes + +- metadata: token directory changes +- Updated dependencies + - @0xsequence/core@1.9.31 + +## 1.9.30 + +### Patch Changes + +- update +- Updated dependencies + - @0xsequence/core@1.9.30 + +## 1.9.29 + +### Patch Changes + +- disable gnosis chain +- Updated dependencies + - @0xsequence/core@1.9.29 + +## 1.9.28 + +### Patch Changes + +- add utils/merkletree +- Updated dependencies + - @0xsequence/core@1.9.28 + +## 1.9.27 + +### Patch Changes + +- network: optimistic -> optimism +- waas: remove defaults +- api, sessions: update bindings +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.9.27 + +## 1.9.26 + +### Patch Changes + +- - add backend interfaces for pluggable interfaces + - introduce @0xsequence/react-native + - update pnpm to lockfile v9 +- Updated dependencies + - @0xsequence/core@1.9.26 + +## 1.9.25 + +### Patch Changes + +- update webrpc clients with new error types +- Updated dependencies + - @0xsequence/core@1.9.25 + +## 1.9.24 + +### Patch Changes + +- waas: add memoryStore backend to localStore +- Updated dependencies + - @0xsequence/core@1.9.24 + +## 1.9.23 + +### Patch Changes + +- update api client bindings +- Updated dependencies + - @0xsequence/core@1.9.23 + +## 1.9.22 + +### Patch Changes + +- update metadata client bindings +- Updated dependencies + - @0xsequence/core@1.9.22 + +## 1.9.21 + +### Patch Changes + +- api client bindings +- Updated dependencies + - @0xsequence/core@1.9.21 + +## 1.9.20 + +### Patch Changes + +- api client bindings update +- Updated dependencies + - @0xsequence/core@1.9.20 + +## 1.9.19 + +### Patch Changes + +- waas update +- Updated dependencies + - @0xsequence/core@1.9.19 + +## 1.9.18 + +### Patch Changes + +- provider: prohibit dangerous functions +- Updated dependencies + - @0xsequence/core@1.9.18 + +## 1.9.17 + +### Patch Changes + +- network: add xr-sepolia +- Updated dependencies + - @0xsequence/core@1.9.17 + +## 1.9.16 + +### Patch Changes + +- waas: sequence.feeOptions +- Updated dependencies + - @0xsequence/core@1.9.16 + +## 1.9.15 + +### Patch Changes + +- metadata: collection external_link field name fix +- Updated dependencies + - @0xsequence/core@1.9.15 + +## 1.9.14 + +### Patch Changes + +- network: astar-zkatana -> astar-zkyoto +- network: deprecate polygon mumbai network +- network: add xai and polygon amoy +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.9.14 + +## 1.9.13 + +### Patch Changes + +- waas: fix @0xsequence/network dependency +- Updated dependencies + - @0xsequence/core@1.9.13 + +## 1.9.12 + +### Patch Changes + +- indexer: update rpc bindings +- provider: signMessage: Serialize the BytesLike or string message into hexstring before sending +- waas: SessionAuthProof +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.9.12 + +## 1.9.11 + +### Patch Changes + +- metdata, update rpc bindings +- Updated dependencies + - @0xsequence/core@1.9.11 + +## 1.9.10 + +### Patch Changes + +- update metadata rpc bindings +- Updated dependencies + - @0xsequence/core@1.9.10 + +## 1.9.9 + +### Patch Changes + +- metadata, add SequenceCollections rpc client +- Updated dependencies + - @0xsequence/core@1.9.9 + +## 1.9.8 + +### Patch Changes + +- waas client update +- Updated dependencies + - @0xsequence/core@1.9.8 + +## 1.9.7 + +### Patch Changes + +- update rpc client bindings for api, metadata and relayer +- Updated dependencies + - @0xsequence/core@1.9.7 + +## 1.9.6 + +### Patch Changes + +- waas package update +- Updated dependencies + - @0xsequence/core@1.9.6 + +## 1.9.5 + +### Patch Changes + +- RpcRelayer prioritize project access key +- Updated dependencies + - @0xsequence/core@1.9.5 + +## 1.9.4 + +### Patch Changes + +- waas: fix network dependency +- Updated dependencies + - @0xsequence/core@1.9.4 + +## 1.9.3 + +### Patch Changes + +- provider: don't append access key to RPC url if user has already provided it +- Updated dependencies + - @0xsequence/core@1.9.3 + +## 1.9.2 + +### Patch Changes + +- network: add xai-sepolia +- Updated dependencies + - @0xsequence/core@1.9.2 + +## 1.9.1 + +### Patch Changes + +- analytics fix +- Updated dependencies + - @0xsequence/core@1.9.1 + +## 1.9.0 + +### Minor Changes + +- waas release + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.9.0 + +## 1.8.8 + +### Patch Changes + +- update metadata bindings +- Updated dependencies + - @0xsequence/core@1.8.8 + +## 1.8.7 + +### Patch Changes + +- provider: update databeat to 0.9.1 +- Updated dependencies + - @0xsequence/core@1.8.7 + +## 1.8.6 + +### Patch Changes + +- guard: SignedOwnershipProof +- Updated dependencies + - @0xsequence/core@1.8.6 + +## 1.8.5 + +### Patch Changes + +- guard: signOwnershipProof and isSignedOwnershipProof +- Updated dependencies + - @0xsequence/core@1.8.5 + +## 1.8.4 + +### Patch Changes + +- network: add homeverse to networks list +- Updated dependencies + - @0xsequence/core@1.8.4 + +## 1.8.3 + +### Patch Changes + +- api: introduce basic linked wallet support +- Updated dependencies + - @0xsequence/core@1.8.3 + +## 1.8.2 + +### Patch Changes + +- provider: don't initialize analytics unless explicitly requested +- Updated dependencies + - @0xsequence/core@1.8.2 + +## 1.8.1 + +### Patch Changes + +- update to analytics provider +- Updated dependencies + - @0xsequence/core@1.8.1 + +## 1.8.0 + +### Minor Changes + +- provider: project analytics + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.8.0 + +## 1.7.2 + +### Patch Changes + +- 0xsequence: ChainId should not be exported as a type +- account, wallet: fix nonce selection +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.7.2 + +## 1.7.1 + +### Patch Changes + +- network: add missing avalanche logoURI +- Updated dependencies + - @0xsequence/core@1.7.1 + +## 1.7.0 + +### Minor Changes + +- provider: projectAccessKey is now required + +### Patch Changes + +- network: add NetworkMetadata.logoURI property for all networks +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.7.0 + +## 1.6.3 + +### Patch Changes + +- network list update +- Updated dependencies + - @0xsequence/core@1.6.3 + +## 1.6.2 + +### Patch Changes + +- auth: projectAccessKey option +- wallet: use 12 bytes for random space +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.6.2 + +## 1.6.1 + +### Patch Changes + +- core: add simple config from subdigest support +- core: fix encode tree with subdigest +- account: implement buildOnChainSignature on Account +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.6.1 + +## 1.6.0 + +### Minor Changes + +- account, wallet: parallel transactions by default + +### Patch Changes + +- provider: emit disconnect on sign out +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.6.0 + +## 1.5.0 + +### Minor Changes + +- signhub: add 'signing' signer status + +### Patch Changes + +- auth: Session.open: onAccountAddress callback +- account: allow empty transaction bundles +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.5.0 + +## 1.4.9 + +### Patch Changes + +- rename SequenceMetadataClient to SequenceMetadata +- Updated dependencies + - @0xsequence/core@1.4.9 + +## 1.4.8 + +### Patch Changes + +- account: Account.getSigners +- Updated dependencies + - @0xsequence/core@1.4.8 + +## 1.4.7 + +### Patch Changes + +- update indexer client bindings +- Updated dependencies + - @0xsequence/core@1.4.7 + +## 1.4.6 + +### Patch Changes + +- - add sepolia networks, mark goerli as deprecated + - update indexer client bindings +- Updated dependencies + - @0xsequence/core@1.4.6 + +## 1.4.5 + +### Patch Changes + +- indexer/metadata: update client bindings +- auth: selectWallet with new address +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.4.5 + +## 1.4.4 + +### Patch Changes + +- indexer: update bindings +- auth: handle jwt expiry +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.4.4 + +## 1.4.3 + +### Patch Changes + +- guard: return active status from GuardSigner.getAuthMethods +- Updated dependencies + - @0xsequence/core@1.4.3 + +## 1.4.2 + +### Patch Changes + +- guard: update bindings +- Updated dependencies + - @0xsequence/core@1.4.2 + +## 1.4.1 + +### Patch Changes + +- network: remove unused networks +- signhub: orchestrator interface +- guard: auth methods interface +- guard: update bindings for pin and totp +- guard: no more retry logic +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.4.1 + +## 1.4.0 + +### Minor Changes + +- project access key support + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.4.0 + +## 1.3.0 + +### Minor Changes + +- signhub: account children + +### Patch Changes + +- guard: do not throw when building deploy transaction +- network: snowtrace.io -> subnets.avax.network/c-chain +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.3.0 + +## 1.2.9 + +### Patch Changes + +- account: AccountSigner.sendTransaction simulateForFeeOptions +- relayer: update bindings + +## 1.2.8 + +### Patch Changes + +- rename X-Sequence-Token-Key header to X-Access-Key + +## 1.2.7 + +### Patch Changes + +- add x-sequence-token-key to clients + +## 1.2.6 + +### Patch Changes + +- Fix bind multicall provider + +## 1.2.5 + +### Patch Changes + +- Multicall default configuration fixes + +## 1.2.4 + +### Patch Changes + +- provider: Adding missing payment provider types to PaymentProviderOption +- provider: WalletRequestHandler.notifyChainChanged + +## 1.2.3 + +### Patch Changes + +- auth, provider: connect to accept optional authorizeNonce + +## 1.2.2 + +### Patch Changes + +- provider: allow createContract calls +- core: check for explicit zero address in contract deployments + +## 1.2.1 + +### Patch Changes + +- auth: use sequence api chain id as reference chain id if available + +## 1.2.0 + +### Minor Changes + +- split services from session, better local support + +## 1.1.15 + +### Patch Changes + +- guard: remove error filtering + +## 1.1.14 + +### Patch Changes + +- guard: add GuardSigner.onError + +## 1.1.13 + +### Patch Changes + +- provider: pass client version with connect options +- provider: removing large from BannerSize + +## 1.1.12 + +### Patch Changes + +- provider: adding bannerSize to ConnectOptions + +## 1.1.11 + +### Patch Changes + +- add homeverse configs + +## 1.1.10 + +### Patch Changes + +- handle default EIP6492 on send + +## 1.1.9 + +### Patch Changes + +- Custom default EIP6492 on client + +## 1.1.8 + +### Patch Changes + +- metadata: searchMetadata: add types filter + +## 1.1.7 + +### Patch Changes + +- adding signInWith connect settings option to allow dapps to automatically login their users with a certain provider optimizing the normal authentication flow + +## 1.1.6 + +### Patch Changes + +- metadata: searchMetadata: add chainID and excludeTokenMetadata filters + +## 1.1.5 + +### Patch Changes + +- account: re-compute meta-transaction id for wallet deployment transactions + +## 1.1.4 + +### Patch Changes + +- network: rename base-mainnet to base +- provider: override isDefaultChain with ConnectOptions.networkId if provided + +## 1.1.3 + +### Patch Changes + +- provider: use network id from transport session +- provider: sign authorization using ConnectOptions.networkId if provided + +## 1.1.2 + +### Patch Changes + +- provider: jsonrpc chain id fixes + +## 1.1.1 + +### Patch Changes + +- network: add base mainnet and sepolia +- provider: reject toxic transaction requests + +## 1.1.0 + +### Minor Changes + +- Refactor dapp facing provider + +## 1.0.5 + +### Patch Changes + +- network: export network constants +- guard: use the correct global for fetch +- network: nova-explorer.arbitrum.io -> nova.arbiscan.io + +## 1.0.4 + +### Patch Changes + +- provider: accept name or number for networkId + +## 1.0.3 + +### Patch Changes + +- Simpler isValidSignature helpers + +## 1.0.2 + +### Patch Changes + +- add extra signature validation utils methods + +## 1.0.1 + +### Patch Changes + +- add homeverse testnet + +## 1.0.0 + +### Major Changes + +- https://sequence.xyz/blog/sequence-wallet-light-state-sync-full-merkle-wallets diff --git a/packages/signhub/package.json b/packages/signhub/package.json new file mode 100644 index 0000000000..048a1ba815 --- /dev/null +++ b/packages/signhub/package.json @@ -0,0 +1,29 @@ +{ + "name": "@0xsequence/signhub", + "version": "2.0.0", + "description": "orchestrates a series of signers, provides visibility into the signing process, and to the signers themselves", + "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/signhub", + "source": "src/index.ts", + "main": "dist/0xsequence-signhub.cjs.js", + "module": "dist/0xsequence-signhub.esm.js", + "author": "Horizon Blockchain Games", + "license": "Apache-2.0", + "scripts": { + "test": "yarn test:file tests/**/*.spec.ts", + "test:file": "TS_NODE_PROJECT=../../tsconfig.test.json mocha -r ts-node/register --timeout 30000", + "test:coverage": "nyc yarn test" + }, + "dependencies": { + "@0xsequence/core": "workspace:*", + "ethers": "^5.5.2" + }, + "peerDependencies": {}, + "devDependencies": { + "@istanbuljs/nyc-config-typescript": "^1.0.2", + "nyc": "^15.1.0" + }, + "files": [ + "src", + "dist" + ] +} diff --git a/packages/signhub/src/index.ts b/packages/signhub/src/index.ts new file mode 100644 index 0000000000..22f52a6440 --- /dev/null +++ b/packages/signhub/src/index.ts @@ -0,0 +1,2 @@ +export * as signers from './signers' +export * from './orchestrator' diff --git a/packages/signhub/src/orchestrator.ts b/packages/signhub/src/orchestrator.ts new file mode 100644 index 0000000000..49bf5747b2 --- /dev/null +++ b/packages/signhub/src/orchestrator.ts @@ -0,0 +1,218 @@ +import { ethers } from 'ethers' +import { commons } from '@0xsequence/core' +import { isSapientSigner, SapientSigner } from './signers/signer' +import { SignerWrapper } from './signers/wrapper' + +export type Status = { + ended: boolean + message: ethers.BytesLike + signers: { [signer: string]: SignerStatus } +} + +export enum SignerState { + INITIAL, + SIGNING, + SIGNED, + ERROR +} + +export type SignerStatus = + | { state: SignerState.INITIAL } + | { state: SignerState.SIGNING; request: Promise } + | { state: SignerState.SIGNED; signature: ethers.BytesLike; suffix: ethers.BytesLike } + | { state: SignerState.ERROR; error: any } + +export function isSignerStatusPending( + status?: SignerStatus +): status is undefined | { state: SignerState.INITIAL } | { state: SignerState.SIGNING; request: Promise } { + return status === undefined || status.state === SignerState.INITIAL || status.state === SignerState.SIGNING +} + +export interface SignatureOrchestrator { + getSigners(): Promise + + signMessage(args: { + candidates: string[] + message: ethers.BytesLike + metadata: object + callback: (status: Status, onNewMetadata: (metadata: object) => void) => boolean + }): Promise + + buildDeployTransaction(metadata: object): Promise + + predecorateSignedTransactions(metadata?: object): Promise + + decorateTransactions( + bundle: commons.transaction.IntendedTransactionBundle, + metadata?: object + ): Promise +} + +/** + * Orchestrates actions of collective signers. + * This includes the signing of a single digests and transactions by multiple signers. + * It can provide internal visibility of the signing process, and it also + * provides the internal signers with additional information about the + * message being signed. Transaction decoration can be used to ensure on-chain state + * is correctly managed during the signing process. + */ +export class Orchestrator { + private observers: ((status: Status, metadata: object) => void)[] = [] + private signers: SapientSigner[] = [] + + private count = 0 + + constructor( + signers: (ethers.Signer | SapientSigner)[], + public tag: string = Orchestrator.randomTag() + ) { + this.setSigners(signers) + } + + private static randomTag(): string { + return `default-${ethers.utils.hexlify(ethers.utils.randomBytes(8)).slice(2)}` + } + + private pullId(): string { + return `${this.tag}-${this.count++}` + } + + setSigners(signers: (ethers.Signer | SapientSigner)[]) { + this.signers = signers.map(s => (isSapientSigner(s) ? s : new SignerWrapper(s))) + } + + async getSigners(): Promise { + return Promise.all(this.signers.map(async s => s.getAddress())) + } + + subscribe(observer: (status: Status, metadata: object) => void): () => void { + this.observers.push(observer) + return () => { + this.observers = this.observers.filter(o => o !== observer) + } + } + + private async notifyObservers(id: string, status: Status, metadata: object) { + await Promise.all([ + ...this.signers.map(async signer => signer.notifyStatusChange(id, status, metadata)), + ...this.observers.map(async observer => observer(status, metadata)) + ]) + } + + async buildDeployTransaction(metadata: object): Promise { + let bundle: commons.transaction.TransactionBundle | undefined + for (const signer of this.signers) { + const newBundle = await signer.buildDeployTransaction(metadata) + if (bundle === undefined) { + // Use first bundle as base + bundle = newBundle + } else if (newBundle?.transactions) { + // Combine deploy transactions + bundle.transactions = newBundle.transactions.concat(bundle.transactions) + } + } + return bundle + } + + async predecorateSignedTransactions(metadata?: object): Promise { + const output: commons.transaction.SignedTransactionBundle[] = [] + for (const signer of this.signers) { + output.push(...(await signer.predecorateSignedTransactions(metadata ?? {}))) + } + return output + } + + async decorateTransactions( + bundle: commons.transaction.IntendedTransactionBundle, + metadata?: object + ): Promise { + for (const signer of this.signers) { + bundle = await signer.decorateTransactions(bundle, metadata ?? {}) + } + return bundle + } + + signMessage(args: { + candidates?: string[] + message: ethers.BytesLike + metadata?: object + callback?: (status: Status, onNewMetadata: (metadata: object) => void) => boolean + }): Promise { + const id = this.pullId() + + return new Promise(async resolve => { + const { message, metadata, callback, candidates } = args + const status: Status = { ended: false, message, signers: {} } + let lastMetadata = metadata ?? {} + + const onNewMetadata = (newMetadata: object) => { + lastMetadata = newMetadata + this.notifyObservers(id, status, lastMetadata) + } + + const onStatusUpdate = () => { + try { + this.notifyObservers(id, status, lastMetadata) + + const pending = Object.entries(status.signers).filter(([_, s]) => isSignerStatusPending(s)) + if ((callback && callback(status, onNewMetadata)) || pending.length === 0) { + status.ended = true + resolve(status) + this.notifyObservers(id, status, lastMetadata) + return + } + } catch (e) { + console.error('Error while notifying observers', e) + } + } + + // we only call signers that are found in `candidates` + // if `candidates` is undefined, we call all signers + let signers = this.signers + if (candidates) { + const addresses = await Promise.all(this.signers.map(async s => s.getAddress())) + signers = this.signers.filter((_, i) => candidates.includes(addresses[i])) + } + + // build callbacks object + const accepted = await Promise.allSettled( + signers.map(async s => { + const saddr = await s.getAddress() + + status.signers[saddr] = { + state: SignerState.SIGNING, + request: s + .sign(message, metadata ?? {}) + .then(signature => { + const suffix = s.suffix() + status.signers[saddr] = { state: SignerState.SIGNED, signature, suffix } + onStatusUpdate() + return signature + }) + .catch(error => { + status.signers[saddr] = { state: SignerState.ERROR, error } + onStatusUpdate() + throw error + }) + } + }) + ) + + for (let i = 0; i < accepted.length; i++) { + const signer = this.signers[i] + const promise = accepted[i] + + if (promise.status === 'rejected') { + const address = await signer.getAddress() + console.warn(`signer ${address} rejected the request: ${promise.reason}`) + status.signers[address] = { + state: SignerState.ERROR, + error: new Error(`signer ${address} rejected the request: ${promise.reason}`) + } + } + } + + onStatusUpdate() + }) + } +} diff --git a/packages/signhub/src/signers/index.ts b/packages/signhub/src/signers/index.ts new file mode 100644 index 0000000000..2ea68121ae --- /dev/null +++ b/packages/signhub/src/signers/index.ts @@ -0,0 +1,2 @@ +export * from './signer' +export * from './wrapper' diff --git a/packages/signhub/src/signers/signer.ts b/packages/signhub/src/signers/signer.ts new file mode 100644 index 0000000000..7bf3fec54f --- /dev/null +++ b/packages/signhub/src/signers/signer.ts @@ -0,0 +1,45 @@ +import { ethers } from 'ethers' +import { commons } from '@0xsequence/core' +import { Status } from '../orchestrator' + +export interface SapientSigner { + getAddress(): Promise + + buildDeployTransaction(metadata: object): Promise + + /** + * Get signed transactions to be included in the next request. + */ + predecorateSignedTransactions(metadata: object): Promise + + /** + * Modify the transaction bundle before it is sent. + */ + decorateTransactions( + bundle: commons.transaction.IntendedTransactionBundle, + metadata: object + ): Promise + + /** + * Request a signature from the signer. + */ + sign(message: ethers.BytesLike, metadata: object): Promise + + /** + * Notify the signer of a status change. + */ + notifyStatusChange(id: string, status: Status, metadata: object): void + + suffix(): ethers.BytesLike +} + +export function isSapientSigner(signer: ethers.Signer | SapientSigner): signer is SapientSigner { + return ( + (signer as SapientSigner).getAddress !== undefined && + (signer as SapientSigner).buildDeployTransaction !== undefined && + (signer as SapientSigner).predecorateSignedTransactions !== undefined && + (signer as SapientSigner).decorateTransactions !== undefined && + (signer as SapientSigner).sign !== undefined && + (signer as SapientSigner).notifyStatusChange !== undefined + ) +} diff --git a/packages/signhub/src/signers/wrapper.ts b/packages/signhub/src/signers/wrapper.ts new file mode 100644 index 0000000000..bbd2b4e806 --- /dev/null +++ b/packages/signhub/src/signers/wrapper.ts @@ -0,0 +1,41 @@ +import { ethers } from 'ethers' +import { commons } from '@0xsequence/core' +import { Status } from '../orchestrator' +import { SapientSigner } from './signer' + +export class SignerWrapper implements SapientSigner { + constructor( + public signer: ethers.Signer, + public eoa: boolean = true + ) {} + + getAddress(): Promise { + return this.signer.getAddress() + } + + async buildDeployTransaction(_metadata: object): Promise { + // Wrapped signers don't require deployment + return + } + + async predecorateSignedTransactions(_metadata: object): Promise { + return [] + } + + async decorateTransactions( + bundle: commons.transaction.IntendedTransactionBundle, + _metadata: object + ): Promise { + return bundle + } + + sign(message: ethers.utils.BytesLike, metadata: object): Promise { + return this.signer.signMessage(message) + } + + notifyStatusChange(_i: string, _s: Status, _m: object): void {} + + suffix(): ethers.BytesLike { + return [2] + } +} diff --git a/packages/signhub/tests/orchestrator.spec.ts b/packages/signhub/tests/orchestrator.spec.ts new file mode 100644 index 0000000000..1b4fad943f --- /dev/null +++ b/packages/signhub/tests/orchestrator.spec.ts @@ -0,0 +1,551 @@ +import * as chai from 'chai' +import { ethers } from 'ethers' +import { commons } from '@0xsequence/core' +import { isSignerStatusPending, Orchestrator, SignerState, Status } from '../src' +import { SapientSigner } from '../src/signers' + +const { expect } = chai + +describe('Orchestrator', () => { + describe('signMessage', () => { + it('Should call all signers', async () => { + const signers = [ethers.Wallet.createRandom(), ethers.Wallet.createRandom(), ethers.Wallet.createRandom()] + + const orchestrator = new Orchestrator(signers) + const signature = await orchestrator.signMessage({ message: '0x1234' }) + + expect(Object.keys(signature.signers)).to.have.lengthOf(signers.length) + + for (const signer of signers) { + expect(signature.signers).to.have.property(signer.address) + } + }) + + it('Should call callback with status updates', async () => { + const signers = [ethers.Wallet.createRandom(), ethers.Wallet.createRandom(), ethers.Wallet.createRandom()] + + const orchestrator = new Orchestrator(signers) + + let callbackCallsA = 0 + orchestrator.subscribe((status, metadata) => { + // Status should have all signers + let numErrors = 0 + let numSignatures = 0 + let numPending = 0 + expect(Object.keys(status.signers)).to.have.lengthOf(signers.length, 'Should have all signers') + for (const signer of signers) { + expect(status.signers).to.have.property(signer.address) + const signerStatus = status.signers[signer.address] + + if (signerStatus.state === SignerState.ERROR) { + numErrors++ + } + + if (isSignerStatusPending(signerStatus)) { + numPending++ + } + + if (signerStatus.state === SignerState.SIGNED) { + numSignatures++ + } + } + + callbackCallsA++ + + expect(numErrors).to.be.equal(0, 'No errors should be present') + expect(numSignatures).to.be.equal(Math.max(callbackCallsA, 3), 'Should have max 3 signatures') + expect(numPending).to.be.equal(Math.min(signers.length - callbackCallsA, 0), 'Should have 0 pending') + }) + + let callbackCallsB = 0 + await orchestrator.signMessage({ + message: '0x1234', + callback: () => { + callbackCallsB++ + return false + } + }) + + // 3 updates + 1 final + expect(callbackCallsA).to.be.equal(4) + + // only the 3 updates + expect(callbackCallsB).to.be.equal(3) + }) + + it('getSigners should return all signers', async () => { + const signers = new Array(10).fill(0).map(() => ethers.Wallet.createRandom()) + const orchestrator = new Orchestrator(signers) + const result = await orchestrator.getSigners() + expect(result).to.have.lengthOf(signers.length) + for (const signer of signers) { + expect(result).to.include(signer.address) + } + }) + + it('setSigners should update the signers', async () => { + const signers = new Array(10).fill(0).map(() => ethers.Wallet.createRandom()) + const orchestrator = new Orchestrator(signers) + + const newSigners = new Array(22).fill(0).map(() => ethers.Wallet.createRandom()) + orchestrator.setSigners(newSigners) + const result = await orchestrator.getSigners() + expect(result).to.have.lengthOf(newSigners.length) + for (const signer of newSigners) { + expect(result).to.include(signer.address) + } + }) + + it('exception on signer should be interpreted as error', async () => { + const brokenSignerEOA = ethers.Wallet.createRandom() + const brokenSigner: SapientSigner = { + getAddress: async function (): Promise { + return brokenSignerEOA.address + }, + buildDeployTransaction(metadata) { + throw new Error('This is a broken signer.') + }, + async predecorateSignedTransactions(_metadata: object): Promise { + throw new Error('This is a broken signer.') + }, + decorateTransactions( + bundle: commons.transaction.IntendedTransactionBundle, + metadata: object + ): Promise { + throw new Error('This is a broken signer.') + }, + sign(_message, _metadata) { + throw new Error('This is a broken signer.') + }, + notifyStatusChange: function (id: string, status: Status): void {}, + suffix: function () { + return [2] + } + } + + const signers = [ethers.Wallet.createRandom(), brokenSigner, ethers.Wallet.createRandom()] + + const orchestrator = new Orchestrator(signers) + + let callbackCallsA = 0 + orchestrator.subscribe(async status => { + // Status should have all signers + let numErrors = 0 + let numSignatures = 0 + let numPending = 0 + + expect(Object.keys(status.signers)).to.have.lengthOf(signers.length) + + for (const signer of signers) { + expect(status.signers).to.have.property(await signer.getAddress()) + const signerStatus = status.signers[await signer.getAddress()] + + if (signerStatus.state === SignerState.ERROR) { + numErrors++ + } + + if (isSignerStatusPending(signerStatus)) { + numPending++ + } + + if (signerStatus.state === SignerState.SIGNED) { + numSignatures++ + } + } + + callbackCallsA++ + + expect(numErrors).to.be.equal(1) + expect(numSignatures).to.be.equal(2) + expect(numPending).to.be.equal(0) + }) + + const signature = await orchestrator.signMessage({ message: '0x1234' }) + expect(Object.keys(signature.signers)).to.have.lengthOf(2) + + for (const signer of signers) { + const address = await signer.getAddress() + const status = signature.signers[address] + + if (address === (await brokenSigner.getAddress())) { + if (status.state === SignerState.ERROR) { + expect(status.error.message).to.contain('This is a broken signer.') + } else { + expect.fail('Signer should be rejected') + } + } else { + expect(status.state === SignerState.SIGNED).to.be.true + } + } + }) + + it('Should manually reject a request', async () => { + const rejectSignerEOA = ethers.Wallet.createRandom() + const rejectSigner: SapientSigner = { + getAddress: async function (): Promise { + return rejectSignerEOA.address + }, + buildDeployTransaction(metadata) { + throw new Error('This is a reject signer.') + }, + async predecorateSignedTransactions(_metadata: object): Promise { + throw new Error('This is a reject signer.') + }, + decorateTransactions( + bundle: commons.transaction.IntendedTransactionBundle, + metadata: object + ): Promise { + throw new Error('This is a rejected signer.') + }, + async sign(_message, _metadata) { + throw new Error('This is a rejected signer.') + }, + notifyStatusChange: function (id: string, status: Status): void {}, + suffix: function () { + return [2] + } + } + + const signers = [ethers.Wallet.createRandom(), rejectSigner] + + const orchestrator = new Orchestrator(signers) + + let callbackCallsA = 0 + orchestrator.subscribe(() => { + callbackCallsA++ + }) + + const signature = await orchestrator.signMessage({ message: '0x1234' }) + expect(Object.keys(signature.signers)).to.have.lengthOf(signers.length) + + for (const signer of signers) { + const address = await signer.getAddress() + const status = signature.signers[address] + + if (address === (await rejectSigner.getAddress())) { + if (status.state === SignerState.ERROR) { + expect(status.error.message).to.contain('This is a rejected signer.') + } else { + expect.fail('Signer should be rejected') + } + } else { + expect(status.state === SignerState.SIGNED).to.be.true + } + } + }) + + it('Should pass the correct message to the signer', async () => { + const ogMessage = ethers.utils.randomBytes(99) + const signer: SapientSigner = { + getAddress: async function (): Promise { + return '0x1234' + }, + buildDeployTransaction(metadata) { + return Promise.resolve(undefined) + }, + predecorateSignedTransactions(_metadata: object): Promise { + return Promise.resolve([]) + }, + decorateTransactions( + bundle: commons.transaction.IntendedTransactionBundle, + metadata: object + ): Promise { + return Promise.resolve(bundle) + }, + async sign(message, _metadata) { + expect(message).to.be.equal(ogMessage) + return '0x5678' + }, + notifyStatusChange: function (id: string, status: Status): void {}, + suffix: function () { + return [2] + } + } + + const orchestrator = new Orchestrator([signer]) + const signature = await orchestrator.signMessage({ message: ogMessage }) + + expect((signature.signers['0x1234'] as any).signature).to.be.equal('0x5678') + }) + + it('Should pass metadata to signer', async () => { + const ogMessage = ethers.utils.randomBytes(99) + const signer: SapientSigner = { + getAddress: async function (): Promise { + return '0x1234' + }, + buildDeployTransaction(metadata) { + return Promise.resolve(undefined) + }, + predecorateSignedTransactions(_metadata: object): Promise { + return Promise.resolve([]) + }, + decorateTransactions( + bundle: commons.transaction.IntendedTransactionBundle, + metadata: object + ): Promise { + return Promise.resolve(bundle) + }, + async sign(_message, metadata) { + expect(metadata).to.be.deep.equal({ test: 'test' }) + return '0x5678' + }, + notifyStatusChange: function (id: string, status: Status): void {}, + suffix: function () { + return [2] + } + } + + const orchestrator = new Orchestrator([signer]) + const signature = await orchestrator.signMessage({ message: ogMessage, metadata: { test: 'test' } }) + + expect((signature.signers['0x1234'] as any).signature).to.be.equal('0x5678') + }) + + it('Should pass updated metadata to signer', async () => { + const ogMessage = ethers.utils.randomBytes(99) + + let firstCall = true + let errorOnNotify: any = undefined + + const signer1: SapientSigner = { + getAddress: async function (): Promise { + return '0x1234' + }, + buildDeployTransaction(metadata) { + return Promise.resolve(undefined) + }, + predecorateSignedTransactions(_metadata: object): Promise { + return Promise.resolve([]) + }, + decorateTransactions( + bundle: commons.transaction.IntendedTransactionBundle, + metadata: object + ): Promise { + return Promise.resolve(bundle) + }, + async sign(_message, metadata) { + expect(metadata).to.be.deep.equal({ test: 'test' }) + return '0x5678' + }, + notifyStatusChange: function (id: string, status: Status, metadata: object): void { + try { + if (firstCall) { + expect(metadata).to.be.deep.equal({ test: 'test' }) + } else { + expect(metadata).to.be.deep.equal({ hello: 'world' }) + } + } catch (e) { + errorOnNotify = e + } + }, + suffix: function () { + return [2] + } + } + + const signer2: SapientSigner = { + getAddress: async function (): Promise { + return '0x5678' + }, + buildDeployTransaction(metadata) { + return Promise.resolve(undefined) + }, + predecorateSignedTransactions(_metadata: object): Promise { + return Promise.resolve([]) + }, + decorateTransactions( + bundle: commons.transaction.IntendedTransactionBundle, + metadata: object + ): Promise { + return Promise.resolve(bundle) + }, + async sign(_message, metadata) { + expect(metadata).to.be.deep.equal({ test: 'test' }) + return '0x9012' + }, + notifyStatusChange: function (id: string, status: Status, metadata: object): void { + try { + if (firstCall) { + expect(metadata).to.be.deep.equal({ test: 'test' }) + } else { + expect(metadata).to.be.deep.equal({ hello: 'world' }) + } + } catch (e) { + errorOnNotify = e + } + }, + suffix: function () { + return [2] + } + } + + const orchestrator = new Orchestrator([signer1, signer2]) + const signature = await orchestrator.signMessage({ + message: ogMessage, + metadata: { test: 'test' }, + callback: (s: Status, onNewMetadata: (metadata: object) => void) => { + if (firstCall) { + firstCall = false + onNewMetadata({ hello: 'world' }) + return false + } + + return true + } + }) + + expect((signature.signers['0x1234'] as any).signature).to.be.equal('0x5678') + expect((signature.signers['0x5678'] as any).signature).to.be.equal('0x9012') + if (errorOnNotify) throw errorOnNotify + }) + + it('Should auto-generate random tag', () => { + const orchestrator1 = new Orchestrator([]) + const orchestrator2 = new Orchestrator([]) + + expect(orchestrator1.tag).to.not.be.equal(orchestrator2.tag) + }) + + it('Should only sign with candidates', async () => { + const message = ethers.utils.randomBytes(99) + + const signer1 = ethers.Wallet.createRandom() + const signer2 = ethers.Wallet.createRandom() + const signer3 = ethers.Wallet.createRandom() + const signer4 = ethers.Wallet.createRandom() + + const orchestrator = new Orchestrator([signer1, signer2, signer3, signer4]) + + const result = await orchestrator.signMessage({ + message: message, + candidates: [signer1.address, signer3.address] + }) + + expect(result.signers[signer1.address]).to.not.be.undefined + expect(result.signers[signer2.address]).to.be.undefined + expect(result.signers[signer3.address]).to.not.be.undefined + expect(result.signers[signer4.address]).to.be.undefined + }) + }) + describe('decorateTransactions', () => { + it('Repeatedly decorate a bundle', async () => { + const signer: SapientSigner = { + getAddress: async function (): Promise { + return '0x1' + }, + async buildDeployTransaction(metadata: object) { + return undefined + }, + async predecorateSignedTransactions(_metadata: object): Promise { + return [] + }, + async decorateTransactions( + bundle: commons.transaction.IntendedTransactionBundle, + metadata: object + ): Promise { + // Add a transaction on each call + bundle.transactions.push({ + to: 'to' + }) + return bundle + }, + sign(_message, _metadata) { + throw new Error('unreachable') + }, + notifyStatusChange: function (id: string, status: Status): void {}, + suffix: function () { + return [0] + } + } + + const orchestrator = new Orchestrator([signer, signer, signer]) + const bundle: commons.transaction.IntendedTransactionBundle = { + intent: { + id: '', + wallet: '' + }, + chainId: 0, + transactions: [], + entrypoint: '' + } + + const output = await orchestrator.decorateTransactions(bundle) + + expect(output?.transactions.length).to.be.equal(3) + }) + }) + + describe('buildDeployTransaction', () => { + it('Should create a combined bundle', async () => { + const signer1: SapientSigner = { + getAddress: async function (): Promise { + return '0x1' + }, + async buildDeployTransaction(metadata: object) { + return { + entrypoint: 'entrypoint1', + transactions: [ + { + to: 'to1', + data: 'data1' + } + ] + } + }, + async predecorateSignedTransactions(_metadata: object): Promise { + return [] + }, + async decorateTransactions( + bundle: commons.transaction.IntendedTransactionBundle, + metadata: object + ): Promise { + return bundle + }, + sign(_message, _metadata) { + throw new Error('unreachable') + }, + notifyStatusChange: function (id: string, status: Status): void {}, + suffix: function () { + return [0] + } + } + const signer2: SapientSigner = { + getAddress: async function (): Promise { + return '0x2' + }, + async buildDeployTransaction(metadata: object) { + return { + entrypoint: 'entrypoint2', + transactions: [ + { + to: 'to2', + data: 'data2' + } + ] + } + }, + async predecorateSignedTransactions(_metadata: object): Promise { + return [] + }, + async decorateTransactions( + bundle: commons.transaction.IntendedTransactionBundle + ): Promise { + return bundle + }, + sign(_message, _metadata) { + throw new Error('unreachable') + }, + notifyStatusChange: function (id: string, status: Status): void {}, + suffix: function () { + return [0] + } + } + + const orchestrator = new Orchestrator([signer1, signer2]) + const bundle = await orchestrator.buildDeployTransaction({}) + + expect(bundle?.transactions.length).to.be.equal(2) + }) + }) +}) diff --git a/packages/simulator/CHANGELOG.md b/packages/simulator/CHANGELOG.md new file mode 100644 index 0000000000..6d10087f65 --- /dev/null +++ b/packages/simulator/CHANGELOG.md @@ -0,0 +1,1403 @@ +# @0xsequence/simulator + +## 2.0.0 + +### Major Changes + +- changeset + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@2.0.0 + +## 1.10.14 + +### Patch Changes + +- network: add borne-testnet to allNetworks +- Updated dependencies + - @0xsequence/core@1.10.14 + +## 1.10.13 + +### Patch Changes + +- network: add borne testnet +- Updated dependencies + - @0xsequence/core@1.10.13 + +## 1.10.12 + +### Patch Changes + +- api: update bindings +- global/window -> globalThis +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.10.12 + +## 1.10.11 + +### Patch Changes + +- waas: updated intent.gen without webrpc types, errors exported from authenticator.gen +- Updated dependencies + - @0xsequence/core@1.10.11 + +## 1.10.10 + +### Patch Changes + +- metadata: update bindings with new contract collections api +- Updated dependencies + - @0xsequence/core@1.10.10 + +## 1.10.9 + +### Patch Changes + +- waas minor update +- Updated dependencies + - @0xsequence/core@1.10.9 + +## 1.10.8 + +### Patch Changes + +- update metadata bindings +- Updated dependencies + - @0xsequence/core@1.10.8 + +## 1.10.7 + +### Patch Changes + +- minor fixes to waas client +- Updated dependencies + - @0xsequence/core@1.10.7 + +## 1.10.6 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/core@1.10.6 + +## 1.10.5 + +### Patch Changes + +- network: ape-chain-testnet -> apechain-testnet +- Updated dependencies + - @0xsequence/core@1.10.5 + +## 1.10.4 + +### Patch Changes + +- network: add b3-sepolia, ape-chain-testnet, blast, blast-sepolia +- Updated dependencies + - @0xsequence/core@1.10.4 + +## 1.10.3 + +### Patch Changes + +- typing fix +- Updated dependencies + - @0xsequence/core@1.10.3 + +## 1.10.2 + +### Patch Changes + +- - waas: add getIdToken method + - indexer: update api client +- Updated dependencies + - @0xsequence/core@1.10.2 + +## 1.10.1 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/core@1.10.1 + +## 1.10.0 + +### Minor Changes + +- waas release v1.3.0 + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.10.0 + +## 1.9.37 + +### Patch Changes + +- network: adds nativeToken data to NetworkMetadata constants +- Updated dependencies + - @0xsequence/core@1.9.37 + +## 1.9.36 + +### Patch Changes + +- guard: export client +- Updated dependencies + - @0xsequence/core@1.9.36 + +## 1.9.35 + +### Patch Changes + +- guard: update bindings +- Updated dependencies + - @0xsequence/core@1.9.35 + +## 1.9.34 + +### Patch Changes + +- waas: always use lowercase email +- Updated dependencies + - @0xsequence/core@1.9.34 + +## 1.9.33 + +### Patch Changes + +- waas: umd build +- Updated dependencies + - @0xsequence/core@1.9.33 + +## 1.9.32 + +### Patch Changes + +- indexer: update bindings +- Updated dependencies + - @0xsequence/core@1.9.32 + +## 1.9.31 + +### Patch Changes + +- metadata: token directory changes +- Updated dependencies + - @0xsequence/core@1.9.31 + +## 1.9.30 + +### Patch Changes + +- update +- Updated dependencies + - @0xsequence/core@1.9.30 + +## 1.9.29 + +### Patch Changes + +- disable gnosis chain +- Updated dependencies + - @0xsequence/core@1.9.29 + +## 1.9.28 + +### Patch Changes + +- add utils/merkletree +- Updated dependencies + - @0xsequence/core@1.9.28 + +## 1.9.27 + +### Patch Changes + +- network: optimistic -> optimism +- waas: remove defaults +- api, sessions: update bindings +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.9.27 + +## 1.9.26 + +### Patch Changes + +- - add backend interfaces for pluggable interfaces + - introduce @0xsequence/react-native + - update pnpm to lockfile v9 +- Updated dependencies + - @0xsequence/core@1.9.26 + +## 1.9.25 + +### Patch Changes + +- update webrpc clients with new error types +- Updated dependencies + - @0xsequence/core@1.9.25 + +## 1.9.24 + +### Patch Changes + +- waas: add memoryStore backend to localStore +- Updated dependencies + - @0xsequence/core@1.9.24 + +## 1.9.23 + +### Patch Changes + +- update api client bindings +- Updated dependencies + - @0xsequence/core@1.9.23 + +## 1.9.22 + +### Patch Changes + +- update metadata client bindings +- Updated dependencies + - @0xsequence/core@1.9.22 + +## 1.9.21 + +### Patch Changes + +- api client bindings +- Updated dependencies + - @0xsequence/core@1.9.21 + +## 1.9.20 + +### Patch Changes + +- api client bindings update +- Updated dependencies + - @0xsequence/core@1.9.20 + +## 1.9.19 + +### Patch Changes + +- waas update +- Updated dependencies + - @0xsequence/core@1.9.19 + +## 1.9.18 + +### Patch Changes + +- provider: prohibit dangerous functions +- Updated dependencies + - @0xsequence/core@1.9.18 + +## 1.9.17 + +### Patch Changes + +- network: add xr-sepolia +- Updated dependencies + - @0xsequence/core@1.9.17 + +## 1.9.16 + +### Patch Changes + +- waas: sequence.feeOptions +- Updated dependencies + - @0xsequence/core@1.9.16 + +## 1.9.15 + +### Patch Changes + +- metadata: collection external_link field name fix +- Updated dependencies + - @0xsequence/core@1.9.15 + +## 1.9.14 + +### Patch Changes + +- network: astar-zkatana -> astar-zkyoto +- network: deprecate polygon mumbai network +- network: add xai and polygon amoy +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.9.14 + +## 1.9.13 + +### Patch Changes + +- waas: fix @0xsequence/network dependency +- Updated dependencies + - @0xsequence/core@1.9.13 + +## 1.9.12 + +### Patch Changes + +- indexer: update rpc bindings +- provider: signMessage: Serialize the BytesLike or string message into hexstring before sending +- waas: SessionAuthProof +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.9.12 + +## 1.9.11 + +### Patch Changes + +- metdata, update rpc bindings +- Updated dependencies + - @0xsequence/core@1.9.11 + +## 1.9.10 + +### Patch Changes + +- update metadata rpc bindings +- Updated dependencies + - @0xsequence/core@1.9.10 + +## 1.9.9 + +### Patch Changes + +- metadata, add SequenceCollections rpc client +- Updated dependencies + - @0xsequence/core@1.9.9 + +## 1.9.8 + +### Patch Changes + +- waas client update +- Updated dependencies + - @0xsequence/core@1.9.8 + +## 1.9.7 + +### Patch Changes + +- update rpc client bindings for api, metadata and relayer +- Updated dependencies + - @0xsequence/core@1.9.7 + +## 1.9.6 + +### Patch Changes + +- waas package update +- Updated dependencies + - @0xsequence/core@1.9.6 + +## 1.9.5 + +### Patch Changes + +- RpcRelayer prioritize project access key +- Updated dependencies + - @0xsequence/core@1.9.5 + +## 1.9.4 + +### Patch Changes + +- waas: fix network dependency +- Updated dependencies + - @0xsequence/core@1.9.4 + +## 1.9.3 + +### Patch Changes + +- provider: don't append access key to RPC url if user has already provided it +- Updated dependencies + - @0xsequence/core@1.9.3 + +## 1.9.2 + +### Patch Changes + +- network: add xai-sepolia +- Updated dependencies + - @0xsequence/core@1.9.2 + +## 1.9.1 + +### Patch Changes + +- analytics fix +- Updated dependencies + - @0xsequence/core@1.9.1 + +## 1.9.0 + +### Minor Changes + +- waas release + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.9.0 + +## 1.8.8 + +### Patch Changes + +- update metadata bindings +- Updated dependencies + - @0xsequence/core@1.8.8 + +## 1.8.7 + +### Patch Changes + +- provider: update databeat to 0.9.1 +- Updated dependencies + - @0xsequence/core@1.8.7 + +## 1.8.6 + +### Patch Changes + +- guard: SignedOwnershipProof +- Updated dependencies + - @0xsequence/core@1.8.6 + +## 1.8.5 + +### Patch Changes + +- guard: signOwnershipProof and isSignedOwnershipProof +- Updated dependencies + - @0xsequence/core@1.8.5 + +## 1.8.4 + +### Patch Changes + +- network: add homeverse to networks list +- Updated dependencies + - @0xsequence/core@1.8.4 + +## 1.8.3 + +### Patch Changes + +- api: introduce basic linked wallet support +- Updated dependencies + - @0xsequence/core@1.8.3 + +## 1.8.2 + +### Patch Changes + +- provider: don't initialize analytics unless explicitly requested +- Updated dependencies + - @0xsequence/core@1.8.2 + +## 1.8.1 + +### Patch Changes + +- update to analytics provider +- Updated dependencies + - @0xsequence/core@1.8.1 + +## 1.8.0 + +### Minor Changes + +- provider: project analytics + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.8.0 + +## 1.7.2 + +### Patch Changes + +- 0xsequence: ChainId should not be exported as a type +- account, wallet: fix nonce selection +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.7.2 + +## 1.7.1 + +### Patch Changes + +- network: add missing avalanche logoURI +- Updated dependencies + - @0xsequence/core@1.7.1 + +## 1.7.0 + +### Minor Changes + +- provider: projectAccessKey is now required + +### Patch Changes + +- network: add NetworkMetadata.logoURI property for all networks +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.7.0 + +## 1.6.3 + +### Patch Changes + +- network list update +- Updated dependencies + - @0xsequence/core@1.6.3 + +## 1.6.2 + +### Patch Changes + +- auth: projectAccessKey option +- wallet: use 12 bytes for random space +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.6.2 + +## 1.6.1 + +### Patch Changes + +- core: add simple config from subdigest support +- core: fix encode tree with subdigest +- account: implement buildOnChainSignature on Account +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.6.1 + +## 1.6.0 + +### Minor Changes + +- account, wallet: parallel transactions by default + +### Patch Changes + +- provider: emit disconnect on sign out +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.6.0 + +## 1.5.0 + +### Minor Changes + +- signhub: add 'signing' signer status + +### Patch Changes + +- auth: Session.open: onAccountAddress callback +- account: allow empty transaction bundles +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.5.0 + +## 1.4.9 + +### Patch Changes + +- rename SequenceMetadataClient to SequenceMetadata +- Updated dependencies + - @0xsequence/core@1.4.9 + +## 1.4.8 + +### Patch Changes + +- account: Account.getSigners +- Updated dependencies + - @0xsequence/core@1.4.8 + +## 1.4.7 + +### Patch Changes + +- update indexer client bindings +- Updated dependencies + - @0xsequence/core@1.4.7 + +## 1.4.6 + +### Patch Changes + +- - add sepolia networks, mark goerli as deprecated + - update indexer client bindings +- Updated dependencies + - @0xsequence/core@1.4.6 + +## 1.4.5 + +### Patch Changes + +- indexer/metadata: update client bindings +- auth: selectWallet with new address +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.4.5 + +## 1.4.4 + +### Patch Changes + +- indexer: update bindings +- auth: handle jwt expiry +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.4.4 + +## 1.4.3 + +### Patch Changes + +- guard: return active status from GuardSigner.getAuthMethods +- Updated dependencies + - @0xsequence/core@1.4.3 + +## 1.4.2 + +### Patch Changes + +- guard: update bindings +- Updated dependencies + - @0xsequence/core@1.4.2 + +## 1.4.1 + +### Patch Changes + +- network: remove unused networks +- signhub: orchestrator interface +- guard: auth methods interface +- guard: update bindings for pin and totp +- guard: no more retry logic +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.4.1 + +## 1.4.0 + +### Minor Changes + +- project access key support + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.4.0 + +## 1.3.0 + +### Minor Changes + +- signhub: account children + +### Patch Changes + +- guard: do not throw when building deploy transaction +- network: snowtrace.io -> subnets.avax.network/c-chain +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.3.0 + +## 1.2.9 + +### Patch Changes + +- account: AccountSigner.sendTransaction simulateForFeeOptions +- relayer: update bindings +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.2.9 + +## 1.2.8 + +### Patch Changes + +- rename X-Sequence-Token-Key header to X-Access-Key +- Updated dependencies + - @0xsequence/core@1.2.8 + +## 1.2.7 + +### Patch Changes + +- add x-sequence-token-key to clients +- Updated dependencies + - @0xsequence/core@1.2.7 + +## 1.2.6 + +### Patch Changes + +- Fix bind multicall provider +- Updated dependencies + - @0xsequence/core@1.2.6 + +## 1.2.5 + +### Patch Changes + +- Multicall default configuration fixes +- Updated dependencies + - @0xsequence/core@1.2.5 + +## 1.2.4 + +### Patch Changes + +- provider: Adding missing payment provider types to PaymentProviderOption +- provider: WalletRequestHandler.notifyChainChanged +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.2.4 + +## 1.2.3 + +### Patch Changes + +- auth, provider: connect to accept optional authorizeNonce +- Updated dependencies + - @0xsequence/core@1.2.3 + +## 1.2.2 + +### Patch Changes + +- provider: allow createContract calls +- core: check for explicit zero address in contract deployments +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.2.2 + +## 1.2.1 + +### Patch Changes + +- auth: use sequence api chain id as reference chain id if available +- Updated dependencies + - @0xsequence/core@1.2.1 + +## 1.2.0 + +### Minor Changes + +- split services from session, better local support + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.2.0 + +## 1.1.15 + +### Patch Changes + +- guard: remove error filtering +- Updated dependencies + - @0xsequence/core@1.1.15 + +## 1.1.14 + +### Patch Changes + +- guard: add GuardSigner.onError +- Updated dependencies + - @0xsequence/core@1.1.14 + +## 1.1.13 + +### Patch Changes + +- provider: pass client version with connect options +- provider: removing large from BannerSize +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.1.13 + +## 1.1.12 + +### Patch Changes + +- provider: adding bannerSize to ConnectOptions +- Updated dependencies + - @0xsequence/core@1.1.12 + +## 1.1.11 + +### Patch Changes + +- add homeverse configs +- Updated dependencies + - @0xsequence/core@1.1.11 + +## 1.1.10 + +### Patch Changes + +- handle default EIP6492 on send +- Updated dependencies + - @0xsequence/core@1.1.10 + +## 1.1.9 + +### Patch Changes + +- Custom default EIP6492 on client +- Updated dependencies + - @0xsequence/core@1.1.9 + +## 1.1.8 + +### Patch Changes + +- metadata: searchMetadata: add types filter +- Updated dependencies + - @0xsequence/core@1.1.8 + +## 1.1.7 + +### Patch Changes + +- adding signInWith connect settings option to allow dapps to automatically login their users with a certain provider optimizing the normal authentication flow +- Updated dependencies + - @0xsequence/core@1.1.7 + +## 1.1.6 + +### Patch Changes + +- metadata: searchMetadata: add chainID and excludeTokenMetadata filters +- Updated dependencies + - @0xsequence/core@1.1.6 + +## 1.1.5 + +### Patch Changes + +- account: re-compute meta-transaction id for wallet deployment transactions +- Updated dependencies + - @0xsequence/core@1.1.5 + +## 1.1.4 + +### Patch Changes + +- network: rename base-mainnet to base +- provider: override isDefaultChain with ConnectOptions.networkId if provided +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.1.4 + +## 1.1.3 + +### Patch Changes + +- provider: use network id from transport session +- provider: sign authorization using ConnectOptions.networkId if provided +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.1.3 + +## 1.1.2 + +### Patch Changes + +- provider: jsonrpc chain id fixes +- Updated dependencies + - @0xsequence/core@1.1.2 + +## 1.1.1 + +### Patch Changes + +- network: add base mainnet and sepolia +- provider: reject toxic transaction requests +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.1.1 + +## 1.1.0 + +### Minor Changes + +- Refactor dapp facing provider + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.1.0 + +## 1.0.5 + +### Patch Changes + +- network: export network constants +- guard: use the correct global for fetch +- network: nova-explorer.arbitrum.io -> nova.arbiscan.io +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.0.5 + +## 1.0.4 + +### Patch Changes + +- provider: accept name or number for networkId +- Updated dependencies + - @0xsequence/core@1.0.4 + +## 1.0.3 + +### Patch Changes + +- Simpler isValidSignature helpers +- Updated dependencies + - @0xsequence/core@1.0.3 + +## 1.0.2 + +### Patch Changes + +- add extra signature validation utils methods +- Updated dependencies + - @0xsequence/core@1.0.2 + +## 1.0.1 + +### Patch Changes + +- add homeverse testnet +- Updated dependencies + - @0xsequence/core@1.0.1 + +## 1.0.0 + +### Major Changes + +- https://sequence.xyz/blog/sequence-wallet-light-state-sync-full-merkle-wallets + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.0.0 + +## 0.43.34 + +### Patch Changes + +- auth: no jwt for indexer +- Updated dependencies + - @0xsequence/transactions@0.43.34 + +## 0.43.33 + +### Patch Changes + +- Adding onConnectOptionsChange handler to WalletRequestHandler +- Updated dependencies + - @0xsequence/transactions@0.43.33 + +## 0.43.32 + +### Patch Changes + +- add Base Goerli network +- Updated dependencies + - @0xsequence/transactions@0.43.32 + +## 0.43.31 + +### Patch Changes + +- remove AuxDataProvider, add promptSignInConnect +- Updated dependencies + - @0xsequence/transactions@0.43.31 + +## 0.43.30 + +### Patch Changes + +- add arbitrum goerli testnet +- Updated dependencies + - @0xsequence/transactions@0.43.30 + +## 0.43.29 + +### Patch Changes + +- provider: check availability of window object +- Updated dependencies + - @0xsequence/transactions@0.43.29 + +## 0.43.28 + +### Patch Changes + +- update api bindings +- Updated dependencies + - @0xsequence/transactions@0.43.28 + +## 0.43.27 + +### Patch Changes + +- Add rpc is sequence method +- Updated dependencies + - @0xsequence/transactions@0.43.27 + +## 0.43.26 + +### Patch Changes + +- add zkevm url to enum +- Updated dependencies + - @0xsequence/transactions@0.43.26 + +## 0.43.25 + +### Patch Changes + +- added polygon zkevm to mainnet networks +- Updated dependencies + - @0xsequence/transactions@0.43.25 + +## 0.43.24 + +### Patch Changes + +- name change from zkevm to polygon-zkevm +- Updated dependencies + - @0xsequence/transactions@0.43.24 + +## 0.43.23 + +### Patch Changes + +- update zkEVM name to Polygon zkEVM +- Updated dependencies + - @0xsequence/transactions@0.43.23 + +## 0.43.22 + +### Patch Changes + +- add zkevm chain +- Updated dependencies + - @0xsequence/transactions@0.43.22 + +## 0.43.21 + +### Patch Changes + +- api: update client bindings +- Updated dependencies + - @0xsequence/transactions@0.43.21 + +## 0.43.20 + +### Patch Changes + +- indexer: update bindings +- Updated dependencies + - @0xsequence/transactions@0.43.20 + +## 0.43.19 + +### Patch Changes + +- session proof update +- Updated dependencies + - @0xsequence/transactions@0.43.19 + +## 0.43.18 + +### Patch Changes + +- rpc client global check, hardening +- Updated dependencies + - @0xsequence/transactions@0.43.18 + +## 0.43.17 + +### Patch Changes + +- rpc clients, check of 'global' is defined +- Updated dependencies + - @0xsequence/transactions@0.43.17 + +## 0.43.16 + +### Patch Changes + +- ethers peerDep to v5, update rpc client global use +- Updated dependencies + - @0xsequence/transactions@0.43.16 + +## 0.43.15 + +### Patch Changes + +- - provider: expand receiver type on some util methods +- Updated dependencies + - @0xsequence/transactions@0.43.15 + +## 0.43.14 + +### Patch Changes + +- bump +- Updated dependencies + - @0xsequence/transactions@0.43.14 + +## 0.43.13 + +### Patch Changes + +- update rpc bindings +- Updated dependencies + - @0xsequence/transactions@0.43.13 + +## 0.43.12 + +### Patch Changes + +- provider: single wallet init, and add new unregisterWallet() method +- Updated dependencies + - @0xsequence/transactions@0.43.12 + +## 0.43.11 + +### Patch Changes + +- fix lockfiles +- re-add mocha type deleter +- Updated dependencies +- Updated dependencies + - @0xsequence/transactions@0.43.11 + +## 0.43.10 + +### Patch Changes + +- various improvements +- Updated dependencies + - @0xsequence/transactions@0.43.10 + +## 0.43.9 + +### Patch Changes + +- update deps +- Updated dependencies + - @0xsequence/transactions@0.43.9 + +## 0.43.8 + +### Patch Changes + +- network: JsonRpcProvider with caching +- Updated dependencies + - @0xsequence/transactions@0.43.8 + +## 0.43.7 + +### Patch Changes + +- provider: fix wallet network init +- Updated dependencies + - @0xsequence/transactions@0.43.7 + +## 0.43.6 + +### Patch Changes + +- metadatata: update rpc bindings +- Updated dependencies + - @0xsequence/transactions@0.43.6 + +## 0.43.5 + +### Patch Changes + +- provider: do not set default network for connect messages +- provider: forward missing error message +- Updated dependencies +- Updated dependencies + - @0xsequence/transactions@0.43.5 + +## 0.43.4 + +### Patch Changes + +- no-change version bump to fix incorrectly tagged snapshot build +- Updated dependencies + - @0xsequence/transactions@0.43.4 + +## 0.43.3 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/transactions@0.43.3 + +## 0.43.2 + +### Patch Changes + +- provider: implement connectUnchecked +- Updated dependencies + - @0xsequence/transactions@0.43.2 + +## 0.43.1 + +### Patch Changes + +- update to latest ethauth dep +- Updated dependencies + - @0xsequence/transactions@0.43.1 + +## 0.43.0 + +### Minor Changes + +- move ethers to a peer dependency + +### Patch Changes + +- Updated dependencies + - @0xsequence/transactions@0.43.0 + +## 0.42.10 + +### Patch Changes + +- add auxDataProvider +- Updated dependencies + - @0xsequence/transactions@0.42.10 + +## 0.42.9 + +### Patch Changes + +- provider: add eip-191 exceptions +- Updated dependencies + - @0xsequence/transactions@0.42.9 + +## 0.42.8 + +### Patch Changes + +- provider: skip setting intent origin if we're unity plugin +- Updated dependencies + - @0xsequence/transactions@0.42.8 + +## 0.42.7 + +### Patch Changes + +- Add sign in options to connection settings +- Updated dependencies + - @0xsequence/transactions@0.42.7 + +## 0.42.6 + +### Patch Changes + +- api bindings update +- Updated dependencies + - @0xsequence/transactions@0.42.6 + +## 0.42.5 + +### Patch Changes + +- relayer: don't treat missing receipt as hard failure +- Updated dependencies + - @0xsequence/transactions@0.42.5 + +## 0.42.4 + +### Patch Changes + +- provider: add custom app protocol to connect options +- Updated dependencies + - @0xsequence/transactions@0.42.4 + +## 0.42.3 + +### Patch Changes + +- update api bindings +- Updated dependencies + - @0xsequence/transactions@0.42.3 + +## 0.42.2 + +### Patch Changes + +- disable rinkeby network +- Updated dependencies + - @0xsequence/transactions@0.42.2 + +## 0.42.1 + +### Patch Changes + +- wallet: optional waitForReceipt parameter +- Updated dependencies + - @0xsequence/transactions@0.42.1 + +## 0.42.0 + +### Minor Changes + +- relayer: estimateGasLimits -> simulate +- add simulator package + +### Patch Changes + +- transactions: fix flattenAuxTransactions +- provider: only filter nullish values +- provider: re-map transaction 'gas' back to 'gasLimit' +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/transactions@0.42.0 diff --git a/packages/simulator/package.json b/packages/simulator/package.json new file mode 100644 index 0000000000..503f951326 --- /dev/null +++ b/packages/simulator/package.json @@ -0,0 +1,35 @@ +{ + "name": "@0xsequence/simulator", + "version": "2.0.0", + "description": "simulator sub-package for Sequence", + "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/simulator", + "source": "src/index.ts", + "main": "dist/0xsequence-simulator.cjs.js", + "module": "dist/0xsequence-simulator.esm.js", + "author": "Horizon Blockchain Games", + "license": "Apache-2.0", + "scripts": { + "test": "pnpm test:concurrently 'pnpm test:run'", + "test:run": "wait-on -t 120000 http-get://127.0.0.1:10045/ && pnpm test:file tests/**/*.spec.ts", + "test:file": "NODE_OPTIONS='--import tsx' mocha --timeout 30000", + "test:concurrently": "concurrently -k --success first 'pnpm start:geth > /dev/null'", + "start:geth": "docker run --rm -t -p 10045:10045 ethereum/client-go:v1.10.16 --http --http.addr 0.0.0.0 --http.port 10045 --datadir test_chain --dev --rpc.allow-unprotected-txs", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@0xsequence/core": "workspace:*", + "@0xsequence/wallet-contracts": "^1.10.0" + }, + "peerDependencies": { + "ethers": ">=5.5 < 6" + }, + "devDependencies": { + "@0xsequence/signhub": "workspace:*", + "@0xsequence/tests": "workspace:*", + "ethers": "^5.7.2" + }, + "files": [ + "src", + "dist" + ] +} diff --git a/packages/simulator/src/geth-call.ts b/packages/simulator/src/geth-call.ts new file mode 100644 index 0000000000..0c72065876 --- /dev/null +++ b/packages/simulator/src/geth-call.ts @@ -0,0 +1,90 @@ +import { BigNumber, BigNumberish, BytesLike, utils, providers } from 'ethers' + +export async function gethCall( + provider: providers.JsonRpcProvider, + transaction: providers.TransactionRequest, + block?: providers.BlockTag, + overrides?: Overrides +) { + const formatter = providers.JsonRpcProvider.getFormatter() + + return provider.send('eth_call', [ + formatter.transactionRequest(transaction), + formatter.blockTag(block ?? null), + ...(overrides ? [formatOverrides(overrides)] : []) + ]) +} + +export interface Overrides { + [address: string]: { + balance?: BigNumberish + nonce?: BigNumberish + code?: BytesLike | utils.Hexable | number | bigint + state?: StorageOverrides + stateDiff?: StorageOverrides + } +} + +export interface StorageOverrides { + [hash: string]: string +} + +function formatOverrides(overrides: any): Overrides { + if (typeof overrides !== 'object') { + throw new Error('overrides must be an object') + } + + const formatted: Overrides = {} + + for (const [key, value] of Object.entries(overrides)) { + if (utils.isHexString(key, 20)) { + try { + formatted[key] = providers.Formatter.check(overridesFormat, value) + } catch {} + } + } + + return formatted +} + +const overridesFormat = { + balance: skipNullish(BigNumber.from), + nonce: skipNullish(BigNumber.from), + code: skipNullish(utils.hexlify), + state: skipNullish(formatStorageOverrides), + stateDiff: skipNullish(formatStorageOverrides) +} + +function formatStorageOverrides(overrides: any): StorageOverrides { + if (typeof overrides !== 'object') { + throw new Error('storage overrides must be an object') + } + + const formatted: StorageOverrides = {} + + for (const [key, value] of Object.entries(overrides)) { + if (utils.isHexString(key, 32)) { + try { + const hash = utils.hexlify(value as any) + if (utils.isHexString(hash, 32)) { + formatted[key] = hash + } + } catch {} + } + } + + return formatted +} + +function skipNullish(formatter: (x: X) => Y): (x?: X | null) => Y | undefined { + return x => { + switch (x) { + case null: + case undefined: + return undefined + + default: + return formatter(x) + } + } +} diff --git a/packages/simulator/src/index.ts b/packages/simulator/src/index.ts new file mode 100644 index 0000000000..2b76aac76e --- /dev/null +++ b/packages/simulator/src/index.ts @@ -0,0 +1,2 @@ +export * from './geth-call' +export * from './simulate' diff --git a/packages/simulator/src/simulate.ts b/packages/simulator/src/simulate.ts new file mode 100644 index 0000000000..e27ba54157 --- /dev/null +++ b/packages/simulator/src/simulate.ts @@ -0,0 +1,28 @@ +import { BigNumber, providers, utils } from 'ethers' +import { gethCall } from './geth-call' +import { commons } from '@0xsequence/core' + +const simulatorArtifact = require('@0xsequence/wallet-contracts/artifacts/contracts/modules/MainModuleGasEstimation.sol/MainModuleGasEstimation.json') +const simulatorInterface = new utils.Interface(simulatorArtifact.abi) +const simulatorBytecode = simulatorArtifact.deployedBytecode + +export async function simulate( + provider: providers.JsonRpcProvider, + wallet: string, + transactions: commons.transaction.Transaction[], + block?: providers.BlockTag +): Promise { + const encodedTransactions = commons.transaction.sequenceTxAbiEncode(transactions) + const data = simulatorInterface.encodeFunctionData('simulateExecute', [encodedTransactions]) + const transaction = { to: wallet, data } + const overrides = { [wallet]: { code: simulatorBytecode } } + const result = await gethCall(provider, transaction, block, overrides) + return simulatorInterface.decodeFunctionResult('simulateExecute', result)[0] +} + +export interface Result { + executed: boolean + succeeded: boolean + result: string + gasUsed: BigNumber +} diff --git a/packages/simulator/tests/sequence-simulator.spec.ts b/packages/simulator/tests/sequence-simulator.spec.ts new file mode 100644 index 0000000000..875e28c0cd --- /dev/null +++ b/packages/simulator/tests/sequence-simulator.spec.ts @@ -0,0 +1,298 @@ +import { CallReceiverMock, HookCallerMock } from '@0xsequence/wallet-contracts' +import { LocalRelayer } from '@0xsequence/relayer' +import { ethers } from 'ethers' +import { configureLogger } from '@0xsequence/utils' + +import chaiAsPromised from 'chai-as-promised' +import * as chai from 'chai' + +const CallReceiverMockArtifact = require('@0xsequence/wallet-contracts/artifacts/contracts/mocks/CallReceiverMock.sol/CallReceiverMock.json') + +const { expect } = chai.use(chaiAsPromised) + +configureLogger({ logLevel: 'DEBUG', silence: false }) + +import { SequenceOrchestratorWrapper, Wallet, WalletV2 } from '@0xsequence/wallet' +import { simulate } from '../src' +import { encodeData } from '@0xsequence/wallet/tests/utils' +import { context } from '@0xsequence/tests' +import { commons, v2 } from '@0xsequence/core' +import { Orchestrator } from '@0xsequence/signhub' + +describe('Wallet integration', function () { + let contexts: Awaited> + let provider: ethers.providers.JsonRpcProvider + let signers: ethers.Signer[] + + let relayer: LocalRelayer + let callReceiver: CallReceiverMock + + before(async () => { + const url = 'http://127.0.0.1:10045/' + provider = new ethers.providers.JsonRpcProvider(url) + + signers = new Array(8).fill(0).map((_, i) => provider.getSigner(i)) + + contexts = await context.deploySequenceContexts(signers[0]) + relayer = new LocalRelayer(signers[0]) + + // Deploy call receiver mock + callReceiver = (await new ethers.ContractFactory( + CallReceiverMockArtifact.abi, + CallReceiverMockArtifact.bytecode, + signers[0] + ).deploy({ gasLimit: 1000000 })) as CallReceiverMock + + // Deploy local relayer + relayer = new LocalRelayer({ signer: signers[0] }) + }) + + beforeEach(async () => { + await callReceiver.setRevertFlag(false) + await callReceiver.testCall(0, []) + }) + + describe('estimate gas of transactions', () => { + const options = [ + { + name: 'single signer wallet', + getWallet: async () => { + // const pk = ethers.utils.randomBytes(32) + // const wallet = await Wallet.singleOwner(pk, context) + // return wallet.connect(ethnode.provider, relayer) + const signer = ethers.Wallet.createRandom() + const config = v2.config.ConfigCoder.fromSimple({ + threshold: 1, + checkpoint: 0, + signers: [{ weight: 1, address: signer.address }] + }) + + return Wallet.newWallet({ + context: contexts[2], + coders: v2.coders, + config, + provider, + relayer, + orchestrator: new Orchestrator([signer]), + chainId: provider.network.chainId + }) + } + }, + { + name: 'multiple signers wallet', + getWallet: async () => { + const signers = new Array(4).fill(0).map(() => ethers.Wallet.createRandom()) + const config = v2.config.ConfigCoder.fromSimple({ + threshold: 3, + checkpoint: 0, + signers: signers.map(s => ({ weight: 1, address: s.address })) + }) + + return Wallet.newWallet({ + context: contexts[2], + coders: v2.coders, + config, + provider, + relayer, + orchestrator: new Orchestrator(signers.slice(0, 3)), + chainId: provider.network.chainId + }) + } + }, + { + name: 'many multiple signers wallet', + getWallet: async () => { + const signers = new Array(111).fill(0).map(() => ethers.Wallet.createRandom()) + + const config = v2.config.ConfigCoder.fromSimple({ + threshold: 77, + checkpoint: 0, + signers: signers.map(s => ({ weight: 1, address: s.address })) + }) + + return Wallet.newWallet({ + context: contexts[2], + coders: v2.coders, + config, + provider, + relayer, + orchestrator: new Orchestrator(signers.slice(0, 77)), + chainId: provider.network.chainId + }) + } + }, + { + name: 'nested wallet', + getWallet: async () => { + const EOASigners = new Array(3).fill(0).map(() => ethers.Wallet.createRandom()) + const nestedSigners = await Promise.all( + new Array(2).fill(0).map(async () => { + const signers = new Array(3).fill(0).map(() => ethers.Wallet.createRandom()) + const config = v2.config.ConfigCoder.fromSimple({ + threshold: 2, + checkpoint: 0, + signers: signers.map(s => ({ weight: 1, address: s.address })) + }) + + const wallet = Wallet.newWallet({ + context: contexts[2], + coders: v2.coders, + config, + provider, + relayer, + orchestrator: new Orchestrator(signers.slice(0, 2)), + chainId: provider.network.chainId + }) + + await wallet.deploy() + + return wallet + }) + ) + + const config = v2.config.ConfigCoder.fromSimple({ + threshold: 2, + checkpoint: 0, + signers: [ + ...EOASigners.map(s => ({ weight: 1, address: s.address })), + ...nestedSigners.map(s => ({ weight: 1, address: s.address })) + ] + }) + + return Wallet.newWallet({ + context: contexts[2], + coders: v2.coders, + config, + provider, + relayer, + orchestrator: new Orchestrator([ + ...EOASigners.slice(0, 2), + ...nestedSigners.slice(0, 1).map(s => new SequenceOrchestratorWrapper(s)) + ]), + chainId: provider.network.chainId + }) + } + }, + { + name: 'asymetrical signers wallet', + getWallet: async () => { + const signersA = new Array(5).fill(0).map(() => ethers.Wallet.createRandom()) + const signersB = new Array(6).fill(0).map(() => ethers.Wallet.createRandom()) + + const config = v2.config.ConfigCoder.fromSimple({ + threshold: 5, + checkpoint: 0, + signers: [ + ...signersA.map(s => ({ weight: 1, address: s.address })), + ...signersB.map(s => ({ weight: 10, address: s.address })) + ] + }) + + return Wallet.newWallet({ + context: contexts[2], + coders: v2.coders, + config, + provider, + relayer, + orchestrator: new Orchestrator(signersA), + chainId: provider.network.chainId + }) + } + } + ] + + options.map(o => { + describe(`with ${o.name}`, () => { + let wallet: WalletV2 + + beforeEach(async () => { + wallet = await o.getWallet() + }) + + describe('with deployed wallet', () => { + let txs: commons.transaction.Transaction[] + + beforeEach(async () => { + await callReceiver.testCall(0, []) + await wallet.deploy() + }) + + describe('a single transaction', () => { + beforeEach(async () => { + txs = [ + { + delegateCall: false, + revertOnError: false, + gasLimit: 0, + to: callReceiver.address, + value: ethers.constants.Zero, + data: await encodeData(callReceiver, 'testCall', 14442, '0x112233') + } + ] + }) + + it('should use estimated gas for a single transaction', async () => { + const results = await simulate(provider, wallet.address, txs) + + expect(results).to.have.lengthOf(txs.length) + expect(results.every(result => result.executed)).to.be.true + expect(results.every(result => result.succeeded)).to.be.true + expect(results.every(result => result.gasUsed.gt(0))).to.be.true + }) + + it('should use estimated gas for a single failing transaction', async () => { + await callReceiver.setRevertFlag(true) + + const results = await simulate(provider, wallet.address, txs) + + expect(results).to.have.lengthOf(txs.length) + expect(results.every(result => result.executed)).to.be.true + expect(results.every(result => !result.succeeded)).to.be.true + expect(results.every(result => result.gasUsed.gt(0))).to.be.true + }) + }) + + describe('a batch of transactions', () => { + let valB: Uint8Array + + beforeEach(async () => { + await callReceiver.setRevertFlag(false) + valB = ethers.utils.randomBytes(99) + + txs = [ + { + delegateCall: false, + revertOnError: false, + gasLimit: 0, + to: callReceiver.address, + value: ethers.constants.Zero, + data: await encodeData(callReceiver, 'setRevertFlag', true) + }, + { + delegateCall: false, + revertOnError: false, + gasLimit: 0, + to: callReceiver.address, + value: ethers.constants.Zero, + data: await encodeData(callReceiver, 'testCall', 2, valB) + } + ] + }) + + it('should use estimated gas for a batch of transactions', async () => { + const results = await simulate(provider, wallet.address, txs) + + expect(results).to.have.lengthOf(txs.length) + expect(results[0].executed).to.be.true + expect(results[0].succeeded).to.be.true + expect(results[0].gasUsed.gt(0)).to.be.true + expect(results[1].executed).to.be.true + expect(results[1].succeeded).to.be.false + expect(results[1].gasUsed.gt(0)).to.be.true + }) + }) + }) + }) + }) + }) +}) diff --git a/packages/tests/CHANGELOG.md b/packages/tests/CHANGELOG.md new file mode 100644 index 0000000000..265efea626 --- /dev/null +++ b/packages/tests/CHANGELOG.md @@ -0,0 +1,1017 @@ +# @0xsequence/tests + +## 2.0.0 + +### Major Changes + +- changeset + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@2.0.0 + +## 1.10.14 + +### Patch Changes + +- network: add borne-testnet to allNetworks +- Updated dependencies + - @0xsequence/core@1.10.14 + +## 1.10.13 + +### Patch Changes + +- network: add borne testnet +- Updated dependencies + - @0xsequence/core@1.10.13 + +## 1.10.12 + +### Patch Changes + +- api: update bindings +- global/window -> globalThis +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.10.12 + +## 1.10.11 + +### Patch Changes + +- waas: updated intent.gen without webrpc types, errors exported from authenticator.gen +- Updated dependencies + - @0xsequence/core@1.10.11 + +## 1.10.10 + +### Patch Changes + +- metadata: update bindings with new contract collections api +- Updated dependencies + - @0xsequence/core@1.10.10 + +## 1.10.9 + +### Patch Changes + +- waas minor update +- Updated dependencies + - @0xsequence/core@1.10.9 + +## 1.10.8 + +### Patch Changes + +- update metadata bindings +- Updated dependencies + - @0xsequence/core@1.10.8 + +## 1.10.7 + +### Patch Changes + +- minor fixes to waas client +- Updated dependencies + - @0xsequence/core@1.10.7 + +## 1.10.6 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/core@1.10.6 + +## 1.10.5 + +### Patch Changes + +- network: ape-chain-testnet -> apechain-testnet +- Updated dependencies + - @0xsequence/core@1.10.5 + +## 1.10.4 + +### Patch Changes + +- network: add b3-sepolia, ape-chain-testnet, blast, blast-sepolia +- Updated dependencies + - @0xsequence/core@1.10.4 + +## 1.10.3 + +### Patch Changes + +- typing fix +- Updated dependencies + - @0xsequence/core@1.10.3 + +## 1.10.2 + +### Patch Changes + +- - waas: add getIdToken method + - indexer: update api client +- Updated dependencies + - @0xsequence/core@1.10.2 + +## 1.10.1 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/core@1.10.1 + +## 1.10.0 + +### Minor Changes + +- waas release v1.3.0 + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.10.0 + +## 1.9.37 + +### Patch Changes + +- network: adds nativeToken data to NetworkMetadata constants +- Updated dependencies + - @0xsequence/core@1.9.37 + +## 1.9.36 + +### Patch Changes + +- guard: export client +- Updated dependencies + - @0xsequence/core@1.9.36 + +## 1.9.35 + +### Patch Changes + +- guard: update bindings +- Updated dependencies + - @0xsequence/core@1.9.35 + +## 1.9.34 + +### Patch Changes + +- waas: always use lowercase email +- Updated dependencies + - @0xsequence/core@1.9.34 + +## 1.9.33 + +### Patch Changes + +- waas: umd build +- Updated dependencies + - @0xsequence/core@1.9.33 + +## 1.9.32 + +### Patch Changes + +- indexer: update bindings +- Updated dependencies + - @0xsequence/core@1.9.32 + +## 1.9.31 + +### Patch Changes + +- metadata: token directory changes +- Updated dependencies + - @0xsequence/core@1.9.31 + +## 1.9.30 + +### Patch Changes + +- update +- Updated dependencies + - @0xsequence/core@1.9.30 + +## 1.9.29 + +### Patch Changes + +- disable gnosis chain +- Updated dependencies + - @0xsequence/core@1.9.29 + +## 1.9.28 + +### Patch Changes + +- add utils/merkletree +- Updated dependencies + - @0xsequence/core@1.9.28 + +## 1.9.27 + +### Patch Changes + +- network: optimistic -> optimism +- waas: remove defaults +- api, sessions: update bindings +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.9.27 + +## 1.9.26 + +### Patch Changes + +- - add backend interfaces for pluggable interfaces + - introduce @0xsequence/react-native + - update pnpm to lockfile v9 +- Updated dependencies + - @0xsequence/core@1.9.26 + +## 1.9.25 + +### Patch Changes + +- update webrpc clients with new error types +- Updated dependencies + - @0xsequence/core@1.9.25 + +## 1.9.24 + +### Patch Changes + +- waas: add memoryStore backend to localStore +- Updated dependencies + - @0xsequence/core@1.9.24 + +## 1.9.23 + +### Patch Changes + +- update api client bindings +- Updated dependencies + - @0xsequence/core@1.9.23 + +## 1.9.22 + +### Patch Changes + +- update metadata client bindings +- Updated dependencies + - @0xsequence/core@1.9.22 + +## 1.9.21 + +### Patch Changes + +- api client bindings +- Updated dependencies + - @0xsequence/core@1.9.21 + +## 1.9.20 + +### Patch Changes + +- api client bindings update +- Updated dependencies + - @0xsequence/core@1.9.20 + +## 1.9.19 + +### Patch Changes + +- waas update +- Updated dependencies + - @0xsequence/core@1.9.19 + +## 1.9.18 + +### Patch Changes + +- provider: prohibit dangerous functions +- Updated dependencies + - @0xsequence/core@1.9.18 + +## 1.9.17 + +### Patch Changes + +- network: add xr-sepolia +- Updated dependencies + - @0xsequence/core@1.9.17 + +## 1.9.16 + +### Patch Changes + +- waas: sequence.feeOptions +- Updated dependencies + - @0xsequence/core@1.9.16 + +## 1.9.15 + +### Patch Changes + +- metadata: collection external_link field name fix +- Updated dependencies + - @0xsequence/core@1.9.15 + +## 1.9.14 + +### Patch Changes + +- network: astar-zkatana -> astar-zkyoto +- network: deprecate polygon mumbai network +- network: add xai and polygon amoy +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.9.14 + +## 1.9.13 + +### Patch Changes + +- waas: fix @0xsequence/network dependency +- Updated dependencies + - @0xsequence/core@1.9.13 + +## 1.9.12 + +### Patch Changes + +- indexer: update rpc bindings +- provider: signMessage: Serialize the BytesLike or string message into hexstring before sending +- waas: SessionAuthProof +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.9.12 + +## 1.9.11 + +### Patch Changes + +- metdata, update rpc bindings +- Updated dependencies + - @0xsequence/core@1.9.11 + +## 1.9.10 + +### Patch Changes + +- update metadata rpc bindings +- Updated dependencies + - @0xsequence/core@1.9.10 + +## 1.9.9 + +### Patch Changes + +- metadata, add SequenceCollections rpc client +- Updated dependencies + - @0xsequence/core@1.9.9 + +## 1.9.8 + +### Patch Changes + +- waas client update +- Updated dependencies + - @0xsequence/core@1.9.8 + +## 1.9.7 + +### Patch Changes + +- update rpc client bindings for api, metadata and relayer +- Updated dependencies + - @0xsequence/core@1.9.7 + +## 1.9.6 + +### Patch Changes + +- waas package update +- Updated dependencies + - @0xsequence/core@1.9.6 + +## 1.9.5 + +### Patch Changes + +- RpcRelayer prioritize project access key +- Updated dependencies + - @0xsequence/core@1.9.5 + +## 1.9.4 + +### Patch Changes + +- waas: fix network dependency +- Updated dependencies + - @0xsequence/core@1.9.4 + +## 1.9.3 + +### Patch Changes + +- provider: don't append access key to RPC url if user has already provided it +- Updated dependencies + - @0xsequence/core@1.9.3 + +## 1.9.2 + +### Patch Changes + +- network: add xai-sepolia +- Updated dependencies + - @0xsequence/core@1.9.2 + +## 1.9.1 + +### Patch Changes + +- analytics fix +- Updated dependencies + - @0xsequence/core@1.9.1 + +## 1.9.0 + +### Minor Changes + +- waas release + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.9.0 + +## 1.8.8 + +### Patch Changes + +- update metadata bindings +- Updated dependencies + - @0xsequence/core@1.8.8 + +## 1.8.7 + +### Patch Changes + +- provider: update databeat to 0.9.1 +- Updated dependencies + - @0xsequence/core@1.8.7 + +## 1.8.6 + +### Patch Changes + +- guard: SignedOwnershipProof +- Updated dependencies + - @0xsequence/core@1.8.6 + +## 1.8.5 + +### Patch Changes + +- guard: signOwnershipProof and isSignedOwnershipProof +- Updated dependencies + - @0xsequence/core@1.8.5 + +## 1.8.4 + +### Patch Changes + +- network: add homeverse to networks list +- Updated dependencies + - @0xsequence/core@1.8.4 + +## 1.8.3 + +### Patch Changes + +- api: introduce basic linked wallet support +- Updated dependencies + - @0xsequence/core@1.8.3 + +## 1.8.2 + +### Patch Changes + +- provider: don't initialize analytics unless explicitly requested +- Updated dependencies + - @0xsequence/core@1.8.2 + +## 1.8.1 + +### Patch Changes + +- update to analytics provider +- Updated dependencies + - @0xsequence/core@1.8.1 + +## 1.8.0 + +### Minor Changes + +- provider: project analytics + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.8.0 + +## 1.7.2 + +### Patch Changes + +- 0xsequence: ChainId should not be exported as a type +- account, wallet: fix nonce selection +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.7.2 + +## 1.7.1 + +### Patch Changes + +- network: add missing avalanche logoURI +- Updated dependencies + - @0xsequence/core@1.7.1 + +## 1.7.0 + +### Minor Changes + +- provider: projectAccessKey is now required + +### Patch Changes + +- network: add NetworkMetadata.logoURI property for all networks +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.7.0 + +## 1.6.3 + +### Patch Changes + +- network list update +- Updated dependencies + - @0xsequence/core@1.6.3 + +## 1.6.2 + +### Patch Changes + +- auth: projectAccessKey option +- wallet: use 12 bytes for random space +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.6.2 + +## 1.6.1 + +### Patch Changes + +- core: add simple config from subdigest support +- core: fix encode tree with subdigest +- account: implement buildOnChainSignature on Account +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.6.1 + +## 1.6.0 + +### Minor Changes + +- account, wallet: parallel transactions by default + +### Patch Changes + +- provider: emit disconnect on sign out +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.6.0 + +## 1.5.0 + +### Minor Changes + +- signhub: add 'signing' signer status + +### Patch Changes + +- auth: Session.open: onAccountAddress callback +- account: allow empty transaction bundles +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.5.0 + +## 1.4.9 + +### Patch Changes + +- rename SequenceMetadataClient to SequenceMetadata +- Updated dependencies + - @0xsequence/core@1.4.9 + +## 1.4.8 + +### Patch Changes + +- account: Account.getSigners +- Updated dependencies + - @0xsequence/core@1.4.8 + +## 1.4.7 + +### Patch Changes + +- update indexer client bindings +- Updated dependencies + - @0xsequence/core@1.4.7 + +## 1.4.6 + +### Patch Changes + +- - add sepolia networks, mark goerli as deprecated + - update indexer client bindings +- Updated dependencies + - @0xsequence/core@1.4.6 + +## 1.4.5 + +### Patch Changes + +- indexer/metadata: update client bindings +- auth: selectWallet with new address +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.4.5 + +## 1.4.4 + +### Patch Changes + +- indexer: update bindings +- auth: handle jwt expiry +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.4.4 + +## 1.4.3 + +### Patch Changes + +- guard: return active status from GuardSigner.getAuthMethods +- Updated dependencies + - @0xsequence/core@1.4.3 + +## 1.4.2 + +### Patch Changes + +- guard: update bindings +- Updated dependencies + - @0xsequence/core@1.4.2 + +## 1.4.1 + +### Patch Changes + +- network: remove unused networks +- signhub: orchestrator interface +- guard: auth methods interface +- guard: update bindings for pin and totp +- guard: no more retry logic +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.4.1 + +## 1.4.0 + +### Minor Changes + +- project access key support + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.4.0 + +## 1.3.0 + +### Minor Changes + +- signhub: account children + +### Patch Changes + +- guard: do not throw when building deploy transaction +- network: snowtrace.io -> subnets.avax.network/c-chain +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.3.0 + +## 1.2.9 + +### Patch Changes + +- account: AccountSigner.sendTransaction simulateForFeeOptions +- relayer: update bindings +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.2.9 + +## 1.2.8 + +### Patch Changes + +- rename X-Sequence-Token-Key header to X-Access-Key +- Updated dependencies + - @0xsequence/core@1.2.8 + +## 1.2.7 + +### Patch Changes + +- add x-sequence-token-key to clients +- Updated dependencies + - @0xsequence/core@1.2.7 + +## 1.2.6 + +### Patch Changes + +- Fix bind multicall provider +- Updated dependencies + - @0xsequence/core@1.2.6 + +## 1.2.5 + +### Patch Changes + +- Multicall default configuration fixes +- Updated dependencies + - @0xsequence/core@1.2.5 + +## 1.2.4 + +### Patch Changes + +- provider: Adding missing payment provider types to PaymentProviderOption +- provider: WalletRequestHandler.notifyChainChanged +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.2.4 + +## 1.2.3 + +### Patch Changes + +- auth, provider: connect to accept optional authorizeNonce +- Updated dependencies + - @0xsequence/core@1.2.3 + +## 1.2.2 + +### Patch Changes + +- provider: allow createContract calls +- core: check for explicit zero address in contract deployments +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.2.2 + +## 1.2.1 + +### Patch Changes + +- auth: use sequence api chain id as reference chain id if available +- Updated dependencies + - @0xsequence/core@1.2.1 + +## 1.2.0 + +### Minor Changes + +- split services from session, better local support + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.2.0 + +## 1.1.15 + +### Patch Changes + +- guard: remove error filtering +- Updated dependencies + - @0xsequence/core@1.1.15 + +## 1.1.14 + +### Patch Changes + +- guard: add GuardSigner.onError +- Updated dependencies + - @0xsequence/core@1.1.14 + +## 1.1.13 + +### Patch Changes + +- provider: pass client version with connect options +- provider: removing large from BannerSize +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.1.13 + +## 1.1.12 + +### Patch Changes + +- provider: adding bannerSize to ConnectOptions +- Updated dependencies + - @0xsequence/core@1.1.12 + +## 1.1.11 + +### Patch Changes + +- add homeverse configs +- Updated dependencies + - @0xsequence/core@1.1.11 + +## 1.1.10 + +### Patch Changes + +- handle default EIP6492 on send +- Updated dependencies + - @0xsequence/core@1.1.10 + +## 1.1.9 + +### Patch Changes + +- Custom default EIP6492 on client +- Updated dependencies + - @0xsequence/core@1.1.9 + +## 1.1.8 + +### Patch Changes + +- metadata: searchMetadata: add types filter +- Updated dependencies + - @0xsequence/core@1.1.8 + +## 1.1.7 + +### Patch Changes + +- adding signInWith connect settings option to allow dapps to automatically login their users with a certain provider optimizing the normal authentication flow +- Updated dependencies + - @0xsequence/core@1.1.7 + +## 1.1.6 + +### Patch Changes + +- metadata: searchMetadata: add chainID and excludeTokenMetadata filters +- Updated dependencies + - @0xsequence/core@1.1.6 + +## 1.1.5 + +### Patch Changes + +- account: re-compute meta-transaction id for wallet deployment transactions +- Updated dependencies + - @0xsequence/core@1.1.5 + +## 1.1.4 + +### Patch Changes + +- network: rename base-mainnet to base +- provider: override isDefaultChain with ConnectOptions.networkId if provided +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.1.4 + +## 1.1.3 + +### Patch Changes + +- provider: use network id from transport session +- provider: sign authorization using ConnectOptions.networkId if provided +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.1.3 + +## 1.1.2 + +### Patch Changes + +- provider: jsonrpc chain id fixes +- Updated dependencies + - @0xsequence/core@1.1.2 + +## 1.1.1 + +### Patch Changes + +- network: add base mainnet and sepolia +- provider: reject toxic transaction requests +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.1.1 + +## 1.1.0 + +### Minor Changes + +- Refactor dapp facing provider + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.1.0 + +## 1.0.5 + +### Patch Changes + +- network: export network constants +- guard: use the correct global for fetch +- network: nova-explorer.arbitrum.io -> nova.arbiscan.io +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.0.5 + +## 1.0.4 + +### Patch Changes + +- provider: accept name or number for networkId +- Updated dependencies + - @0xsequence/core@1.0.4 + +## 1.0.3 + +### Patch Changes + +- Simpler isValidSignature helpers +- Updated dependencies + - @0xsequence/core@1.0.3 + +## 1.0.2 + +### Patch Changes + +- add extra signature validation utils methods +- Updated dependencies + - @0xsequence/core@1.0.2 + +## 1.0.1 + +### Patch Changes + +- add homeverse testnet +- Updated dependencies + - @0xsequence/core@1.0.1 + +## 1.0.0 + +### Major Changes + +- https://sequence.xyz/blog/sequence-wallet-light-state-sync-full-merkle-wallets + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.0.0 diff --git a/packages/tests/package.json b/packages/tests/package.json new file mode 100644 index 0000000000..8aeea05f74 --- /dev/null +++ b/packages/tests/package.json @@ -0,0 +1,29 @@ +{ + "name": "@0xsequence/tests", + "version": "2.0.0", + "description": "test tools for sequence.js", + "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/tests", + "source": "src/index.ts", + "main": "dist/0xsequence-tests.cjs.js", + "module": "dist/0xsequence-tests.esm.js", + "author": "Horizon Blockchain Games", + "license": "Apache-2.0", + "scripts": { + "test": "echo 'no tests for test tools'" + }, + "dependencies": { + "@0xsequence/core": "workspace:*" + }, + "peerDependencies": { + "ethers": ">=5.5" + }, + "devDependencies": { + "@istanbuljs/nyc-config-typescript": "^1.0.1", + "ethers": "^5.7.2", + "web3": "^1.8.1" + }, + "files": [ + "src", + "dist" + ] +} diff --git a/packages/tests/src/builds/artifact.ts b/packages/tests/src/builds/artifact.ts new file mode 100644 index 0000000000..b74bbb512a --- /dev/null +++ b/packages/tests/src/builds/artifact.ts @@ -0,0 +1,9 @@ +import { ethers } from 'ethers' + +export type Artifact = { + contractName: string + sourceName: string + abi: ethers.ContractInterface + bytecode: string + deployedBytecode: string +} diff --git a/packages/tests/src/builds/index.ts b/packages/tests/src/builds/index.ts new file mode 100644 index 0000000000..53e4b6eec1 --- /dev/null +++ b/packages/tests/src/builds/index.ts @@ -0,0 +1,4 @@ +export * as v1 from './v1' +export * as v2 from './v2' + +export * from './artifact' diff --git a/packages/tests/src/builds/v1/artifacts/Factory.ts b/packages/tests/src/builds/v1/artifacts/Factory.ts new file mode 100644 index 0000000000..e776e8c41a --- /dev/null +++ b/packages/tests/src/builds/v1/artifacts/Factory.ts @@ -0,0 +1,37 @@ +export const factory = { + _format: 'hh-sol-artifact-1', + contractName: 'Factory', + sourceName: 'contracts/Factory.sol', + abi: [ + { + inputs: [ + { + internalType: 'address', + name: '_mainModule', + type: 'address' + }, + { + internalType: 'bytes32', + name: '_salt', + type: 'bytes32' + } + ], + name: 'deploy', + outputs: [ + { + internalType: 'address', + name: '_contract', + type: 'address' + } + ], + stateMutability: 'payable', + type: 'function' + } + ], + bytecode: + '0x608060405234801561001057600080fd5b506101c8806100206000396000f3fe60806040526004361061001e5760003560e01c806332c02a1414610023575b600080fd5b61005c6004803603604081101561003957600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610085565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b60008060405180606001604052806028815260200161016b602891398473ffffffffffffffffffffffffffffffffffffffff166040516020018083805190602001908083835b6020831061010857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016100cb565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199092169116179052920193845250604080518085038152938201905282519294508693508401905034f594935050505056fe603a600e3d39601a805130553df3363d3d373d3d3d363d30545af43d82803e903d91601857fd5bf3a26469706673582212209b0bce93afab3297b9ebf4e58fa642ef123d74bcbd3bdb4e48b662eb12b430ca64736f6c63430007060033', + deployedBytecode: + '0x60806040526004361061001e5760003560e01c806332c02a1414610023575b600080fd5b61005c6004803603604081101561003957600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610085565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b60008060405180606001604052806028815260200161016b602891398473ffffffffffffffffffffffffffffffffffffffff166040516020018083805190602001908083835b6020831061010857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016100cb565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199092169116179052920193845250604080518085038152938201905282519294508693508401905034f594935050505056fe603a600e3d39601a805130553df3363d3d373d3d3d363d30545af43d82803e903d91601857fd5bf3a26469706673582212209b0bce93afab3297b9ebf4e58fa642ef123d74bcbd3bdb4e48b662eb12b430ca64736f6c63430007060033', + linkReferences: {}, + deployedLinkReferences: {} +} diff --git a/packages/tests/src/builds/v1/artifacts/GuestModule.ts b/packages/tests/src/builds/v1/artifacts/GuestModule.ts new file mode 100644 index 0000000000..d6bccbbe48 --- /dev/null +++ b/packages/tests/src/builds/v1/artifacts/GuestModule.ts @@ -0,0 +1,295 @@ +export const guestModule = { + _format: 'hh-sol-artifact-1', + contractName: 'GuestModule', + sourceName: 'contracts/modules/GuestModule.sol', + abi: [ + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: '_contract', + type: 'address' + } + ], + name: 'CreatedContract', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: '_space', + type: 'uint256' + }, + { + indexed: false, + internalType: 'uint256', + name: '_newNonce', + type: 'uint256' + } + ], + name: 'NonceChange', + type: 'event' + }, + { + anonymous: true, + inputs: [ + { + indexed: false, + internalType: 'bytes32', + name: '_tx', + type: 'bytes32' + } + ], + name: 'TxExecuted', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'bytes32', + name: '_tx', + type: 'bytes32' + }, + { + indexed: false, + internalType: 'bytes', + name: '_reason', + type: 'bytes' + } + ], + name: 'TxFailed', + type: 'event' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_code', + type: 'bytes' + } + ], + name: 'createContract', + outputs: [ + { + internalType: 'address', + name: 'addr', + type: 'address' + } + ], + stateMutability: 'payable', + type: 'function' + }, + { + inputs: [ + { + components: [ + { + internalType: 'bool', + name: 'delegateCall', + type: 'bool' + }, + { + internalType: 'bool', + name: 'revertOnError', + type: 'bool' + }, + { + internalType: 'uint256', + name: 'gasLimit', + type: 'uint256' + }, + { + internalType: 'address', + name: 'target', + type: 'address' + }, + { + internalType: 'uint256', + name: 'value', + type: 'uint256' + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes' + } + ], + internalType: 'struct IModuleCalls.Transaction[]', + name: '_txs', + type: 'tuple[]' + }, + { + internalType: 'uint256', + name: '', + type: 'uint256' + }, + { + internalType: 'bytes', + name: '', + type: 'bytes' + } + ], + name: 'execute', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_hash', + type: 'bytes32' + }, + { + internalType: 'bytes', + name: '_signatures', + type: 'bytes' + } + ], + name: 'isValidSignature', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_data', + type: 'bytes' + }, + { + internalType: 'bytes', + name: '_signatures', + type: 'bytes' + } + ], + name: 'isValidSignature', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'nonce', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_space', + type: 'uint256' + } + ], + name: 'readNonce', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + components: [ + { + internalType: 'bool', + name: 'delegateCall', + type: 'bool' + }, + { + internalType: 'bool', + name: 'revertOnError', + type: 'bool' + }, + { + internalType: 'uint256', + name: 'gasLimit', + type: 'uint256' + }, + { + internalType: 'address', + name: 'target', + type: 'address' + }, + { + internalType: 'uint256', + name: 'value', + type: 'uint256' + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes' + } + ], + internalType: 'struct IModuleCalls.Transaction[]', + name: '_txs', + type: 'tuple[]' + } + ], + name: 'selfExecute', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes4', + name: '_interfaceID', + type: 'bytes4' + } + ], + name: 'supportsInterface', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool' + } + ], + stateMutability: 'pure', + type: 'function' + } + ], + bytecode: + '0x608060405234801561001057600080fd5b50611ddc806100206000396000f3fe60806040526004361061007b5760003560e01c80637a9a16281161004e5780637a9a1628146101255780638c3f55631461014557806390042baf14610172578063affed0e0146101925761007b565b806301ffc9a7146100805780631626ba7e146100b657806320c13b0b146100e357806361c2926c14610103575b600080fd5b34801561008c57600080fd5b506100a061009b366004611677565b6101a7565b6040516100ad91906118be565b60405180910390f35b3480156100c257600080fd5b506100d66100d136600461162d565b6101ba565b6040516100ad91906118eb565b3480156100ef57600080fd5b506100d66100fe3660046116b7565b610233565b34801561010f57600080fd5b5061012361011e366004611590565b61028d565b005b34801561013157600080fd5b506101236101403660046115c3565b6102ce565b34801561015157600080fd5b50610165610160366004611753565b6102f6565b6040516100ad91906118c9565b610185610180366004611720565b610322565b6040516100ad919061189d565b34801561019e57600080fd5b506101656103d6565b60006101b2826103e7565b90505b919050565b60006102046101c885610444565b84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506104a492505050565b1561022c57507f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b600061025d6101c88686604051808383808284376040519201829003909120935061044492505050565b1561028557507f20c13b0b000000000000000000000000000000000000000000000000000000005b949350505050565b60006102be826040516020016102a39190611a19565b60405160208183030381529060405280519060200120610444565b90506102ca818361069c565b5050565b60006102e4846040516020016102a39190611975565b90506102f0818561069c565b50505050565b60006101b27f8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e83610817565b600033301461037c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180611d806027913960400191505060405180910390fd5b81516020830134f06040805173ffffffffffffffffffffffffffffffffffffffff8316815290519192507fa506ad4e7f05eceba62a023c3219e5bd98a615f4fa87e2afb08a2da5cf62bf0c919081900360200190a1919050565b60006103e260006102f6565b905090565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f90042baf00000000000000000000000000000000000000000000000000000000141561043b575060016101b5565b6101b282610844565b604080517f19010000000000000000000000000000000000000000000000000000000000006020808301919091524660228301523060601b6042830152605680830194909452825180830390940184526076909101909152815191012090565b60008060006104b2846108a1565b909250905061ffff821660005b855183101561067957600080806104d6898761090f565b975060ff918216945016915060018314156104fe576104f58987610990565b96509050610622565b8261052a57606061050f8a88610a08565b9750905061051d8b82610ab9565b9150828501945050610622565b60028314156105d15761053d8987610990565b96509050600061054d8a88610e43565b975061ffff16905060606105628b8984610eb4565b985090506105718c8483610fa3565b6105c6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526032815260200180611c0b6032913960400191505060405180910390fd5b505092810192610622565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180611b28602c913960400191505060405180910390fd5b848282604051602001808481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff16815260200193505050506040516020818303038152906040528051906020012094505050506104bf565b8361ffff1681101580156106915750610691826111eb565b979650505050505050565b60005b81518110156108125760008282815181106106b657fe5b6020026020010151905060006060826000015115610709576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610700906119bc565b60405180910390fd5b82604001515a1015610747576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161070090611918565b826060015173ffffffffffffffffffffffffffffffffffffffff168360800151846040015160001461077d57846040015161077f565b5a5b908560a001516040516107929190611881565b600060405180830381858888f193505050503d80600081146107d0576040519150601f19603f3d011682016040523d82523d6000602084013e6107d5565b606091505b50909250905081156107fc57856040516107ef91906118c9565b60405180910390a0610807565b6108078387836111f1565b50505060010161069f565b505050565b60408051602080820194909452808201929092528051808303820181526060909201905280519101205490565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f389901c7000000000000000000000000000000000000000000000000000000001415610898575060016101b5565b6101b282611241565b6020810151815160f09190911c9060029081111561090a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180611b776027913960400191505060405180910390fd5b915091565b8082016020015160f881901c9060f01c60ff166002830183811161092f57fe5b8451811115610989576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180611cdb6026913960400191505060405180910390fd5b9250925092565b8082016020015160601c601482018281116109a757fe5b8351811115610a01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180611b546023913960400191505060405180910390fd5b9250929050565b604080516042808252608082019092526060916000919060208201818036833701905050915082840160200180516020840152602081015160408401526022810151604284015250604283019050828111610a5f57fe5b8351811115610a01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180611c7c6023913960400191505060405180910390fd5b60008151604214610b15576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603a815260200180611aee603a913960400191505060405180910390fd5b600082600184510381518110610b2757fe5b602001015160f81c60f81b60f81c60ff169050600083604081518110610b4957fe5b016020015160f81c90506000610b5f85826112c9565b90506000610b6e8660206112c9565b90507f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0811115610be9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d815260200180611ab1603d913960400191505060405180910390fd5b8260ff16601b14158015610c0157508260ff16601c14155b15610c57576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d815260200180611b9e603d913960400191505060405180910390fd5b6001841415610ccb5760018784848460405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015610cba573d6000803e3d6000fd5b505050602060405103519450610dcd565b6002841415610d7c5760018760405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012084848460405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015610cba573d6000803e3d6000fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c815260200180611c9f603c913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516610e39576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526030815260200180611bdb6030913960400191505060405180910390fd5b5050505092915050565b8082016020015160f01c60028201828111610e5a57fe5b8351811115610a01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180611d226022913960400191505060405180910390fd5b606060008267ffffffffffffffff81118015610ecf57600080fd5b506040519080825280601f01601f191660200182016040528015610efa576020820181803683370190505b509150838501602001600060205b85811015610f2157908201518482015260208101610f08565b8486016020018051939092015190850152525082820183811015610f4157fe5b8451811115610f9b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180611d016021913960400191505060405180910390fd5b935093915050565b60008082600184510381518110610fb657fe5b016020015160f81c90506001811480610fcf5750600281145b15611013578373ffffffffffffffffffffffffffffffffffffffff16610ff58685610ab9565b73ffffffffffffffffffffffffffffffffffffffff161491506111e3565b60038114156111925782517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81018452604080517f1626ba7e000000000000000000000000000000000000000000000000000000008152600481018881526024820192835286516044830152865173ffffffffffffffffffffffffffffffffffffffff891693631626ba7e938b938a9390929160640190602085019080838360005b838110156110cd5781810151838201526020016110b5565b50505050905090810190601f1680156110fa5780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b15801561111857600080fd5b505afa15801561112c573d6000803e3d6000fd5b505050506040513d602081101561114257600080fd5b50519084527fffffffff00000000000000000000000000000000000000000000000000000000167f1626ba7e000000000000000000000000000000000000000000000000000000001491506111e3565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603f815260200180611c3d603f913960400191505060405180910390fd5b509392505050565b50600190565b82602001511561120357805160208201fd5b7f3dbd1590ea96dd3253a91f24e64e3a502e1225d602a5731357bc12643070ccd782826040516112349291906118d2565b60405180910390a1505050565b60007fffffffff00000000000000000000000000000000000000000000000000000000821615806112b357507fffffffff0000000000000000000000000000000000000000000000000000000082167f36e7817500000000000000000000000000000000000000000000000000000000145b156112c0575060016101b5565b6101b282611331565b60008160200183511015611328576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c815260200180611d44603c913960400191505060405180910390fd5b50016020015190565b7fffffffff0000000000000000000000000000000000000000000000000000000081167f01ffc9a70000000000000000000000000000000000000000000000000000000014919050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101b557600080fd5b600082601f8301126113af578081fd5b8135602067ffffffffffffffff808311156113c657fe5b6113d38283850201611a60565b83815282810190868401865b868110156114af578135890160c0807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0838e0301121561141d57898afd5b604080518281018181108a8211171561143257fe5b825261143f848b016114bd565b815261144c8285016114bd565b8a820152606080850135838301526080925061146983860161137b565b9082015260a08481013583830152928401359289841115611488578c8dfd5b6114968f8c8688010161150d565b90820152875250505092850192908501906001016113df565b509098975050505050505050565b803580151581146101b557600080fd5b60008083601f8401126114de578182fd5b50813567ffffffffffffffff8111156114f5578182fd5b602083019150836020828501011115610a0157600080fd5b600082601f83011261151d578081fd5b813567ffffffffffffffff81111561153157fe5b61156260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611a60565b818152846020838601011115611576578283fd5b816020850160208301379081016020019190915292915050565b6000602082840312156115a1578081fd5b813567ffffffffffffffff8111156115b7578182fd5b6102858482850161139f565b6000806000606084860312156115d7578182fd5b833567ffffffffffffffff808211156115ee578384fd5b6115fa8783880161139f565b9450602086013593506040860135915080821115611616578283fd5b506116238682870161150d565b9150509250925092565b600080600060408486031215611641578283fd5b83359250602084013567ffffffffffffffff81111561165e578283fd5b61166a868287016114cd565b9497909650939450505050565b600060208284031215611688578081fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461022c578182fd5b600080600080604085870312156116cc578081fd5b843567ffffffffffffffff808211156116e3578283fd5b6116ef888389016114cd565b90965094506020870135915080821115611707578283fd5b50611714878288016114cd565b95989497509550505050565b600060208284031215611731578081fd5b813567ffffffffffffffff811115611747578182fd5b6102858482850161150d565b600060208284031215611764578081fd5b5035919050565b60008282518085526020808601955080818302840101818601855b8481101561182a578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00189528151805115158452848101511515858501526040808201519085015260608082015173ffffffffffffffffffffffffffffffffffffffff16908501526080808201519085015260a09081015160c09185018290529061181681860183611837565b9a86019a9450505090830190600101611786565b5090979650505050505050565b6000815180845261184f816020860160208601611a84565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60008251611893818460208701611a84565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b901515815260200190565b90815260200190565b6000838252604060208301526102856040830184611837565b7fffffffff0000000000000000000000000000000000000000000000000000000091909116815260200190565b60208082526029908201527f47756573744d6f64756c65235f6578656375746547756573743a204e4f545f4560408201527f4e4f5547485f4741530000000000000000000000000000000000000000000000606082015260800190565b600060408252600660408301527f67756573743a000000000000000000000000000000000000000000000000000060608301526080602083015261022c608083018461176b565b60208082526033908201527f47756573744d6f64756c65235f6578656375746547756573743a2064656c656760408201527f61746543616c6c206e6f7420616c6c6f77656400000000000000000000000000606082015260800190565b600060408252600560408301527f73656c663a00000000000000000000000000000000000000000000000000000060608301526080602083015261022c608083018461176b565b60405181810167ffffffffffffffff81118282101715611a7c57fe5b604052919050565b60005b83811015611a9f578181015183820152602001611a87565b838111156102f0575050600091015256fe5369676e617475726556616c696461746f72237265636f7665725369676e65723a20696e76616c6964207369676e6174757265202773272076616c75655369676e617475726556616c696461746f72237265636f7665725369676e65723a20696e76616c6964207369676e6174757265206c656e6774684d6f64756c6541757468235f7369676e617475726556616c69646174696f6e20494e56414c49445f464c41474c696242797465732372656164416464726573733a204f55545f4f465f424f554e44534c696242797465732372656164466972737455696e7431363a204f55545f4f465f424f554e44535369676e617475726556616c696461746f72237265636f7665725369676e65723a20696e76616c6964207369676e6174757265202776272076616c75655369676e617475726556616c696461746f72237265636f7665725369676e65723a20494e56414c49445f5349474e45524d6f64756c6541757468235f7369676e617475726556616c69646174696f6e3a20494e56414c49445f5349474e41545552455369676e617475726556616c696461746f7223697356616c69645369676e61747572653a20554e535550504f525445445f5349474e41545552455f545950454c696242797465732372656164427974657336363a204f55545f4f465f424f554e44535369676e617475726556616c696461746f72237265636f7665725369676e65723a20554e535550504f525445445f5349474e41545552455f545950454c69624279746573237265616455696e743855696e74383a204f55545f4f465f424f554e44534c69624279746573237265616442797465733a204f55545f4f465f424f554e44534c69624279746573237265616455696e7431363a204f55545f4f465f424f554e44534c696242797465732372656164427974657333323a20475245415445525f4f525f455155414c5f544f5f33325f4c454e4754485f52455155495245444d6f64756c6553656c6641757468236f6e6c7953656c663a204e4f545f415554484f52495a4544a2646970667358221220f5a1de0b650baa2ee828e8766bc6dbd0c74da0cc4735a143852d24f868e4b62464736f6c63430007060033', + deployedBytecode: + '0x60806040526004361061007b5760003560e01c80637a9a16281161004e5780637a9a1628146101255780638c3f55631461014557806390042baf14610172578063affed0e0146101925761007b565b806301ffc9a7146100805780631626ba7e146100b657806320c13b0b146100e357806361c2926c14610103575b600080fd5b34801561008c57600080fd5b506100a061009b366004611677565b6101a7565b6040516100ad91906118be565b60405180910390f35b3480156100c257600080fd5b506100d66100d136600461162d565b6101ba565b6040516100ad91906118eb565b3480156100ef57600080fd5b506100d66100fe3660046116b7565b610233565b34801561010f57600080fd5b5061012361011e366004611590565b61028d565b005b34801561013157600080fd5b506101236101403660046115c3565b6102ce565b34801561015157600080fd5b50610165610160366004611753565b6102f6565b6040516100ad91906118c9565b610185610180366004611720565b610322565b6040516100ad919061189d565b34801561019e57600080fd5b506101656103d6565b60006101b2826103e7565b90505b919050565b60006102046101c885610444565b84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506104a492505050565b1561022c57507f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b600061025d6101c88686604051808383808284376040519201829003909120935061044492505050565b1561028557507f20c13b0b000000000000000000000000000000000000000000000000000000005b949350505050565b60006102be826040516020016102a39190611a19565b60405160208183030381529060405280519060200120610444565b90506102ca818361069c565b5050565b60006102e4846040516020016102a39190611975565b90506102f0818561069c565b50505050565b60006101b27f8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e83610817565b600033301461037c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180611d806027913960400191505060405180910390fd5b81516020830134f06040805173ffffffffffffffffffffffffffffffffffffffff8316815290519192507fa506ad4e7f05eceba62a023c3219e5bd98a615f4fa87e2afb08a2da5cf62bf0c919081900360200190a1919050565b60006103e260006102f6565b905090565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f90042baf00000000000000000000000000000000000000000000000000000000141561043b575060016101b5565b6101b282610844565b604080517f19010000000000000000000000000000000000000000000000000000000000006020808301919091524660228301523060601b6042830152605680830194909452825180830390940184526076909101909152815191012090565b60008060006104b2846108a1565b909250905061ffff821660005b855183101561067957600080806104d6898761090f565b975060ff918216945016915060018314156104fe576104f58987610990565b96509050610622565b8261052a57606061050f8a88610a08565b9750905061051d8b82610ab9565b9150828501945050610622565b60028314156105d15761053d8987610990565b96509050600061054d8a88610e43565b975061ffff16905060606105628b8984610eb4565b985090506105718c8483610fa3565b6105c6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526032815260200180611c0b6032913960400191505060405180910390fd5b505092810192610622565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180611b28602c913960400191505060405180910390fd5b848282604051602001808481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff16815260200193505050506040516020818303038152906040528051906020012094505050506104bf565b8361ffff1681101580156106915750610691826111eb565b979650505050505050565b60005b81518110156108125760008282815181106106b657fe5b6020026020010151905060006060826000015115610709576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610700906119bc565b60405180910390fd5b82604001515a1015610747576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161070090611918565b826060015173ffffffffffffffffffffffffffffffffffffffff168360800151846040015160001461077d57846040015161077f565b5a5b908560a001516040516107929190611881565b600060405180830381858888f193505050503d80600081146107d0576040519150601f19603f3d011682016040523d82523d6000602084013e6107d5565b606091505b50909250905081156107fc57856040516107ef91906118c9565b60405180910390a0610807565b6108078387836111f1565b50505060010161069f565b505050565b60408051602080820194909452808201929092528051808303820181526060909201905280519101205490565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f389901c7000000000000000000000000000000000000000000000000000000001415610898575060016101b5565b6101b282611241565b6020810151815160f09190911c9060029081111561090a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180611b776027913960400191505060405180910390fd5b915091565b8082016020015160f881901c9060f01c60ff166002830183811161092f57fe5b8451811115610989576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180611cdb6026913960400191505060405180910390fd5b9250925092565b8082016020015160601c601482018281116109a757fe5b8351811115610a01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180611b546023913960400191505060405180910390fd5b9250929050565b604080516042808252608082019092526060916000919060208201818036833701905050915082840160200180516020840152602081015160408401526022810151604284015250604283019050828111610a5f57fe5b8351811115610a01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180611c7c6023913960400191505060405180910390fd5b60008151604214610b15576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603a815260200180611aee603a913960400191505060405180910390fd5b600082600184510381518110610b2757fe5b602001015160f81c60f81b60f81c60ff169050600083604081518110610b4957fe5b016020015160f81c90506000610b5f85826112c9565b90506000610b6e8660206112c9565b90507f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0811115610be9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d815260200180611ab1603d913960400191505060405180910390fd5b8260ff16601b14158015610c0157508260ff16601c14155b15610c57576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d815260200180611b9e603d913960400191505060405180910390fd5b6001841415610ccb5760018784848460405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015610cba573d6000803e3d6000fd5b505050602060405103519450610dcd565b6002841415610d7c5760018760405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012084848460405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015610cba573d6000803e3d6000fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c815260200180611c9f603c913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516610e39576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526030815260200180611bdb6030913960400191505060405180910390fd5b5050505092915050565b8082016020015160f01c60028201828111610e5a57fe5b8351811115610a01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180611d226022913960400191505060405180910390fd5b606060008267ffffffffffffffff81118015610ecf57600080fd5b506040519080825280601f01601f191660200182016040528015610efa576020820181803683370190505b509150838501602001600060205b85811015610f2157908201518482015260208101610f08565b8486016020018051939092015190850152525082820183811015610f4157fe5b8451811115610f9b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180611d016021913960400191505060405180910390fd5b935093915050565b60008082600184510381518110610fb657fe5b016020015160f81c90506001811480610fcf5750600281145b15611013578373ffffffffffffffffffffffffffffffffffffffff16610ff58685610ab9565b73ffffffffffffffffffffffffffffffffffffffff161491506111e3565b60038114156111925782517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81018452604080517f1626ba7e000000000000000000000000000000000000000000000000000000008152600481018881526024820192835286516044830152865173ffffffffffffffffffffffffffffffffffffffff891693631626ba7e938b938a9390929160640190602085019080838360005b838110156110cd5781810151838201526020016110b5565b50505050905090810190601f1680156110fa5780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b15801561111857600080fd5b505afa15801561112c573d6000803e3d6000fd5b505050506040513d602081101561114257600080fd5b50519084527fffffffff00000000000000000000000000000000000000000000000000000000167f1626ba7e000000000000000000000000000000000000000000000000000000001491506111e3565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603f815260200180611c3d603f913960400191505060405180910390fd5b509392505050565b50600190565b82602001511561120357805160208201fd5b7f3dbd1590ea96dd3253a91f24e64e3a502e1225d602a5731357bc12643070ccd782826040516112349291906118d2565b60405180910390a1505050565b60007fffffffff00000000000000000000000000000000000000000000000000000000821615806112b357507fffffffff0000000000000000000000000000000000000000000000000000000082167f36e7817500000000000000000000000000000000000000000000000000000000145b156112c0575060016101b5565b6101b282611331565b60008160200183511015611328576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c815260200180611d44603c913960400191505060405180910390fd5b50016020015190565b7fffffffff0000000000000000000000000000000000000000000000000000000081167f01ffc9a70000000000000000000000000000000000000000000000000000000014919050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101b557600080fd5b600082601f8301126113af578081fd5b8135602067ffffffffffffffff808311156113c657fe5b6113d38283850201611a60565b83815282810190868401865b868110156114af578135890160c0807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0838e0301121561141d57898afd5b604080518281018181108a8211171561143257fe5b825261143f848b016114bd565b815261144c8285016114bd565b8a820152606080850135838301526080925061146983860161137b565b9082015260a08481013583830152928401359289841115611488578c8dfd5b6114968f8c8688010161150d565b90820152875250505092850192908501906001016113df565b509098975050505050505050565b803580151581146101b557600080fd5b60008083601f8401126114de578182fd5b50813567ffffffffffffffff8111156114f5578182fd5b602083019150836020828501011115610a0157600080fd5b600082601f83011261151d578081fd5b813567ffffffffffffffff81111561153157fe5b61156260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611a60565b818152846020838601011115611576578283fd5b816020850160208301379081016020019190915292915050565b6000602082840312156115a1578081fd5b813567ffffffffffffffff8111156115b7578182fd5b6102858482850161139f565b6000806000606084860312156115d7578182fd5b833567ffffffffffffffff808211156115ee578384fd5b6115fa8783880161139f565b9450602086013593506040860135915080821115611616578283fd5b506116238682870161150d565b9150509250925092565b600080600060408486031215611641578283fd5b83359250602084013567ffffffffffffffff81111561165e578283fd5b61166a868287016114cd565b9497909650939450505050565b600060208284031215611688578081fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461022c578182fd5b600080600080604085870312156116cc578081fd5b843567ffffffffffffffff808211156116e3578283fd5b6116ef888389016114cd565b90965094506020870135915080821115611707578283fd5b50611714878288016114cd565b95989497509550505050565b600060208284031215611731578081fd5b813567ffffffffffffffff811115611747578182fd5b6102858482850161150d565b600060208284031215611764578081fd5b5035919050565b60008282518085526020808601955080818302840101818601855b8481101561182a578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00189528151805115158452848101511515858501526040808201519085015260608082015173ffffffffffffffffffffffffffffffffffffffff16908501526080808201519085015260a09081015160c09185018290529061181681860183611837565b9a86019a9450505090830190600101611786565b5090979650505050505050565b6000815180845261184f816020860160208601611a84565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60008251611893818460208701611a84565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b901515815260200190565b90815260200190565b6000838252604060208301526102856040830184611837565b7fffffffff0000000000000000000000000000000000000000000000000000000091909116815260200190565b60208082526029908201527f47756573744d6f64756c65235f6578656375746547756573743a204e4f545f4560408201527f4e4f5547485f4741530000000000000000000000000000000000000000000000606082015260800190565b600060408252600660408301527f67756573743a000000000000000000000000000000000000000000000000000060608301526080602083015261022c608083018461176b565b60208082526033908201527f47756573744d6f64756c65235f6578656375746547756573743a2064656c656760408201527f61746543616c6c206e6f7420616c6c6f77656400000000000000000000000000606082015260800190565b600060408252600560408301527f73656c663a00000000000000000000000000000000000000000000000000000060608301526080602083015261022c608083018461176b565b60405181810167ffffffffffffffff81118282101715611a7c57fe5b604052919050565b60005b83811015611a9f578181015183820152602001611a87565b838111156102f0575050600091015256fe5369676e617475726556616c696461746f72237265636f7665725369676e65723a20696e76616c6964207369676e6174757265202773272076616c75655369676e617475726556616c696461746f72237265636f7665725369676e65723a20696e76616c6964207369676e6174757265206c656e6774684d6f64756c6541757468235f7369676e617475726556616c69646174696f6e20494e56414c49445f464c41474c696242797465732372656164416464726573733a204f55545f4f465f424f554e44534c696242797465732372656164466972737455696e7431363a204f55545f4f465f424f554e44535369676e617475726556616c696461746f72237265636f7665725369676e65723a20696e76616c6964207369676e6174757265202776272076616c75655369676e617475726556616c696461746f72237265636f7665725369676e65723a20494e56414c49445f5349474e45524d6f64756c6541757468235f7369676e617475726556616c69646174696f6e3a20494e56414c49445f5349474e41545552455369676e617475726556616c696461746f7223697356616c69645369676e61747572653a20554e535550504f525445445f5349474e41545552455f545950454c696242797465732372656164427974657336363a204f55545f4f465f424f554e44535369676e617475726556616c696461746f72237265636f7665725369676e65723a20554e535550504f525445445f5349474e41545552455f545950454c69624279746573237265616455696e743855696e74383a204f55545f4f465f424f554e44534c69624279746573237265616442797465733a204f55545f4f465f424f554e44534c69624279746573237265616455696e7431363a204f55545f4f465f424f554e44534c696242797465732372656164427974657333323a20475245415445525f4f525f455155414c5f544f5f33325f4c454e4754485f52455155495245444d6f64756c6553656c6641757468236f6e6c7953656c663a204e4f545f415554484f52495a4544a2646970667358221220f5a1de0b650baa2ee828e8766bc6dbd0c74da0cc4735a143852d24f868e4b62464736f6c63430007060033', + linkReferences: {}, + deployedLinkReferences: {} +} diff --git a/packages/tests/src/builds/v1/artifacts/MainModule.ts b/packages/tests/src/builds/v1/artifacts/MainModule.ts new file mode 100644 index 0000000000..89c3c4dd41 --- /dev/null +++ b/packages/tests/src/builds/v1/artifacts/MainModule.ts @@ -0,0 +1,528 @@ +export const mainModule = { + _format: 'hh-sol-artifact-1', + contractName: 'MainModule', + sourceName: 'contracts/modules/MainModule.sol', + abi: [ + { + inputs: [ + { + internalType: 'address', + name: '_factory', + type: 'address' + } + ], + stateMutability: 'nonpayable', + type: 'constructor' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: '_contract', + type: 'address' + } + ], + name: 'CreatedContract', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'newImplementation', + type: 'address' + } + ], + name: 'ImplementationUpdated', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: '_space', + type: 'uint256' + }, + { + indexed: false, + internalType: 'uint256', + name: '_newNonce', + type: 'uint256' + } + ], + name: 'NonceChange', + type: 'event' + }, + { + anonymous: true, + inputs: [ + { + indexed: false, + internalType: 'bytes32', + name: '_tx', + type: 'bytes32' + } + ], + name: 'TxExecuted', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'bytes32', + name: '_tx', + type: 'bytes32' + }, + { + indexed: false, + internalType: 'bytes', + name: '_reason', + type: 'bytes' + } + ], + name: 'TxFailed', + type: 'event' + }, + { + stateMutability: 'payable', + type: 'fallback' + }, + { + inputs: [], + name: 'FACTORY', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'INIT_CODE_HASH', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes4', + name: '_signature', + type: 'bytes4' + }, + { + internalType: 'address', + name: '_implementation', + type: 'address' + } + ], + name: 'addHook', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_code', + type: 'bytes' + } + ], + name: 'createContract', + outputs: [ + { + internalType: 'address', + name: 'addr', + type: 'address' + } + ], + stateMutability: 'payable', + type: 'function' + }, + { + inputs: [ + { + components: [ + { + internalType: 'bool', + name: 'delegateCall', + type: 'bool' + }, + { + internalType: 'bool', + name: 'revertOnError', + type: 'bool' + }, + { + internalType: 'uint256', + name: 'gasLimit', + type: 'uint256' + }, + { + internalType: 'address', + name: 'target', + type: 'address' + }, + { + internalType: 'uint256', + name: 'value', + type: 'uint256' + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes' + } + ], + internalType: 'struct IModuleCalls.Transaction[]', + name: '_txs', + type: 'tuple[]' + }, + { + internalType: 'uint256', + name: '_nonce', + type: 'uint256' + }, + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + } + ], + name: 'execute', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_hash', + type: 'bytes32' + }, + { + internalType: 'bytes', + name: '_signatures', + type: 'bytes' + } + ], + name: 'isValidSignature', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_data', + type: 'bytes' + }, + { + internalType: 'bytes', + name: '_signatures', + type: 'bytes' + } + ], + name: 'isValidSignature', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'nonce', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]' + }, + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]' + }, + { + internalType: 'bytes', + name: '', + type: 'bytes' + } + ], + name: 'onERC1155BatchReceived', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'uint256', + name: '', + type: 'uint256' + }, + { + internalType: 'uint256', + name: '', + type: 'uint256' + }, + { + internalType: 'bytes', + name: '', + type: 'bytes' + } + ], + name: 'onERC1155Received', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'uint256', + name: '', + type: 'uint256' + }, + { + internalType: 'bytes', + name: '', + type: 'bytes' + } + ], + name: 'onERC721Received', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes4', + name: '_signature', + type: 'bytes4' + } + ], + name: 'readHook', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_space', + type: 'uint256' + } + ], + name: 'readNonce', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes4', + name: '_signature', + type: 'bytes4' + } + ], + name: 'removeHook', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + components: [ + { + internalType: 'bool', + name: 'delegateCall', + type: 'bool' + }, + { + internalType: 'bool', + name: 'revertOnError', + type: 'bool' + }, + { + internalType: 'uint256', + name: 'gasLimit', + type: 'uint256' + }, + { + internalType: 'address', + name: 'target', + type: 'address' + }, + { + internalType: 'uint256', + name: 'value', + type: 'uint256' + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes' + } + ], + internalType: 'struct IModuleCalls.Transaction[]', + name: '_txs', + type: 'tuple[]' + } + ], + name: 'selfExecute', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes4', + name: '_interfaceID', + type: 'bytes4' + } + ], + name: 'supportsInterface', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool' + } + ], + stateMutability: 'pure', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '_implementation', + type: 'address' + } + ], + name: 'updateImplementation', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + stateMutability: 'payable', + type: 'receive' + } + ], + bytecode: + '0x60c06040523480156200001157600080fd5b5060405162002d6338038062002d638339810160408190526200003491620000e2565b80600060405180606001604052806028815260200162002d3b60289139306001600160a01b03166040516020018083805190602001908083835b602083106200008f5780518252601f1990920191602091820191016200006e565b51815160209384036101000a60001901801990921691161790529201938452506040805180850381529382019052825192019190912060805250505060601b6001600160601b03191660a0525062000112565b600060208284031215620000f4578081fd5b81516001600160a01b03811681146200010b578182fd5b9392505050565b60805160a05160601c612bf862000143600039806106d55280611baa5250806106b15280611bdb5250612bf86000f3fe6080604052600436106101125760003560e01c80634fcf3eca116100a557806390042baf11610074578063b93ea7ad11610059578063b93ea7ad146103c5578063bc197c81146103e5578063f23a6e611461040557610119565b806390042baf1461039d578063affed0e0146103b057610119565b80634fcf3eca1461031d57806361c2926c1461033d5780637a9a16281461035d5780638c3f55631461037d57610119565b80631a9b2337116100e15780631a9b23371461029957806320c13b0b146102c6578063257671f5146102e65780632dd310001461030857610119565b806301ffc9a7146101f4578063025b22bc1461022a578063150b7a021461024c5780631626ba7e1461027957610119565b3661011957005b60006101486000357fffffffff0000000000000000000000000000000000000000000000000000000016610425565b905073ffffffffffffffffffffffffffffffffffffffff8116156101f1576000808273ffffffffffffffffffffffffffffffffffffffff166000366040518083838082843760405192019450600093509091505080830381855af49150503d80600081146101d2576040519150601f19603f3d011682016040523d82523d6000602084013e6101d7565b606091505b5091509150816101e957805160208201fd5b805160208201f35b50005b34801561020057600080fd5b5061021461020f366004612401565b61047b565b6040516102219190612633565b60405180910390f35b34801561023657600080fd5b5061024a610245366004612166565b610486565b005b34801561025857600080fd5b5061026c610267366004612237565b6105a7565b6040516102219190612660565b34801561028557600080fd5b5061026c6102943660046123b7565b6105d1565b3480156102a557600080fd5b506102b96102b4366004612401565b61064a565b6040516102219190612612565b3480156102d257600080fd5b5061026c6102e136600461244d565b610655565b3480156102f257600080fd5b506102fb6106af565b604051610221919061263e565b34801561031457600080fd5b506102b96106d3565b34801561032957600080fd5b5061024a610338366004612401565b6106f7565b34801561034957600080fd5b5061024a61035836600461231a565b6107d5565b34801561036957600080fd5b5061024a61037836600461234d565b61086e565b34801561038957600080fd5b506102fb6103983660046124e9565b6108ea565b6102b96103ab3660046124b6565b610916565b3480156103bc57600080fd5b506102fb6109ca565b3480156103d157600080fd5b5061024a6103e036600461241b565b6109db565b3480156103f157600080fd5b5061026c610400366004612180565b610ab4565b34801561041157600080fd5b5061026c6104203660046122a4565b610ae1565b60006104737fbe27a319efc8734e89e26ba4bc95f5c788584163b959f03fa04e2d7ab4b9a1207fffffffff000000000000000000000000000000000000000000000000000000008416610b0c565b90505b919050565b600061047382610b39565b3330146104de576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180612b9c6027913960400191505060405180910390fd5b6104fd8173ffffffffffffffffffffffffffffffffffffffff16610b96565b610552576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526039815260200180612a826039913960400191505060405180910390fd5b61055b81610b9c565b6040805173ffffffffffffffffffffffffffffffffffffffff8316815290517f310ba5f1d2ed074b51e2eccd052a47ae9ab7c6b800d1fca3db3999d6a592ca039181900360200190a150565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b600061061b6105df85610ba0565b84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610c0092505050565b1561064357507f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b600061047382610425565b600061067f6105df86866040518083838082843760405192018290039091209350610ba092505050565b156106a757507f20c13b0b000000000000000000000000000000000000000000000000000000005b949350505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b33301461074f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180612b9c6027913960400191505060405180910390fd5b600061075a82610425565b73ffffffffffffffffffffffffffffffffffffffff1614156107c7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b8152602001806128e0602b913960400191505060405180910390fd5b6107d2816000610df8565b50565b33301461082d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180612b9c6027913960400191505060405180910390fd5b600061085e82604051602001610843919061277e565b60405160208183030381529060405280519060200120610ba0565b905061086a8183610e5b565b5050565b6108778261102a565b600061088f83856040516020016108439291906127c5565b905061089b8183610c00565b6108da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108d190612721565b60405180910390fd5b6108e48185610e5b565b50505050565b60006104737f8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e83610b0c565b6000333014610970576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180612b9c6027913960400191505060405180910390fd5b81516020830134f06040805173ffffffffffffffffffffffffffffffffffffffff8316815290519192507fa506ad4e7f05eceba62a023c3219e5bd98a615f4fa87e2afb08a2da5cf62bf0c919081900360200190a1919050565b60006109d660006108ea565b905090565b333014610a33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180612b9c6027913960400191505060405180910390fd5b6000610a3e83610425565b73ffffffffffffffffffffffffffffffffffffffff1614610aaa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001806129f4602c913960400191505060405180910390fd5b61086a8282610df8565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b60408051602080820194909452808201929092528051808303820181526060909201905280519101205490565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f90042baf000000000000000000000000000000000000000000000000000000001415610b8d57506001610476565b610473826110ce565b3b151590565b3055565b604080517f19010000000000000000000000000000000000000000000000000000000000006020808301919091524660228301523060601b6042830152605680830194909452825180830390940184526076909101909152815191012090565b6000806000610c0e8461120f565b909250905061ffff821660005b8551831015610dd55760008080610c32898761127d565b975060ff91821694501691506001831415610c5a57610c5189876112fe565b96509050610d7e565b82610c86576060610c6b8a88611376565b97509050610c798b82611427565b9150828501945050610d7e565b6002831415610d2d57610c9989876112fe565b965090506000610ca98a886117b1565b975061ffff1690506060610cbe8b8984611822565b98509050610ccd8c8483611911565b610d22576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001806129c26032913960400191505060405180910390fd5b505092810192610d7e565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001806128b4602c913960400191505060405180910390fd5b848282604051602001808481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019350505050604051602081830303815290604052805190602001209450505050610c1b565b8361ffff168110158015610ded5750610ded82611b59565b979650505050505050565b61086a7fbe27a319efc8734e89e26ba4bc95f5c788584163b959f03fa04e2d7ab4b9a1207fffffffff00000000000000000000000000000000000000000000000000000000841673ffffffffffffffffffffffffffffffffffffffff8416611c37565b60005b8151811015611025576000828281518110610e7557fe5b602002602001015190506000606082604001515a1015610ec1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108d1906126c4565b825115610f5957826060015173ffffffffffffffffffffffffffffffffffffffff168360400151600014610ef9578360400151610efb565b5a5b8460a00151604051610f0d91906125f6565b6000604051808303818686f4925050503d8060008114610f49576040519150601f19603f3d011682016040523d82523d6000602084013e610f4e565b606091505b509092509050610fee565b826060015173ffffffffffffffffffffffffffffffffffffffff1683608001518460400151600014610f8f578460400151610f91565b5a5b908560a00151604051610fa491906125f6565b600060405180830381858888f193505050503d8060008114610fe2576040519150601f19603f3d011682016040523d82523d6000602084013e610fe7565b606091505b5090925090505b811561100f5785604051611002919061263e565b60405180910390a061101a565b61101a838783611c65565b505050600101610e5e565b505050565b60008061103683611cb5565b915091506000611045836108ea565b9050808214611080576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108d19061268d565b6001820161108e8482611cce565b7f1f180c27086c7a39ea2a7b25239d1ab92348f07ca7bb59d1438fcf527568f88184826040516110bf9291906127de565b60405180910390a15050505050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fec6aba5000000000000000000000000000000000000000000000000000000000148061116157507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b806111ad57507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b806111f957507fffffffff0000000000000000000000000000000000000000000000000000000082167fc0ee0b8a00000000000000000000000000000000000000000000000000000000145b1561120657506001610476565b61047382611cf9565b6020810151815160f09190911c90600290811115611278576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061292e6027913960400191505060405180910390fd5b915091565b8082016020015160f881901c9060f01c60ff166002830183811161129d57fe5b84518111156112f7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180612af76026913960400191505060405180910390fd5b9250925092565b8082016020015160601c6014820182811161131557fe5b835181111561136f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602381526020018061290b6023913960400191505060405180910390fd5b9250929050565b6040805160428082526080820190925260609160009190602082018180368337019050509150828401602001805160208401526020810151604084015260228101516042840152506042830190508281116113cd57fe5b835181111561136f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180612a5f6023913960400191505060405180910390fd5b60008151604214611483576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603a81526020018061287a603a913960400191505060405180910390fd5b60008260018451038151811061149557fe5b602001015160f81c60f81b60f81c60ff1690506000836040815181106114b757fe5b016020015160f81c905060006114cd8582611d56565b905060006114dc866020611d56565b90507f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0811115611557576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d81526020018061283d603d913960400191505060405180910390fd5b8260ff16601b1415801561156f57508260ff16601c14155b156115c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d815260200180612955603d913960400191505060405180910390fd5b60018414156116395760018784848460405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015611628573d6000803e3d6000fd5b50505060206040510351945061173b565b60028414156116ea5760018760405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012084848460405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015611628573d6000803e3d6000fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c815260200180612abb603c913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff85166117a7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260308152602001806129926030913960400191505060405180910390fd5b5050505092915050565b8082016020015160f01c600282018281116117c857fe5b835181111561136f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180612b3e6022913960400191505060405180910390fd5b606060008267ffffffffffffffff8111801561183d57600080fd5b506040519080825280601f01601f191660200182016040528015611868576020820181803683370190505b509150838501602001600060205b8581101561188f57908201518482015260208101611876565b84860160200180519390920151908501525250828201838110156118af57fe5b8451811115611909576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180612b1d6021913960400191505060405180910390fd5b935093915050565b6000808260018451038151811061192457fe5b016020015160f81c9050600181148061193d5750600281145b15611981578373ffffffffffffffffffffffffffffffffffffffff166119638685611427565b73ffffffffffffffffffffffffffffffffffffffff16149150611b51565b6003811415611b005782517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81018452604080517f1626ba7e000000000000000000000000000000000000000000000000000000008152600481018881526024820192835286516044830152865173ffffffffffffffffffffffffffffffffffffffff891693631626ba7e938b938a9390929160640190602085019080838360005b83811015611a3b578181015183820152602001611a23565b50505050905090810190601f168015611a685780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b158015611a8657600080fd5b505afa158015611a9a573d6000803e3d6000fd5b505050506040513d6020811015611ab057600080fd5b50519084527fffffffff00000000000000000000000000000000000000000000000000000000167f1626ba7e00000000000000000000000000000000000000000000000000000000149150611b51565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603f815260200180612a20603f913960400191505060405180910390fd5b509392505050565b604080517fff000000000000000000000000000000000000000000000000000000000000006020808301919091527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060601b166021830152603582018490527f0000000000000000000000000000000000000000000000000000000000000000605580840191909152835180840390910181526075909201909252805191012073ffffffffffffffffffffffffffffffffffffffff163014919050565b6040805160208082019590955280820193909352805180840382018152606090930190528151919092012055565b826020015115611c7757805160208201fd5b7f3dbd1590ea96dd3253a91f24e64e3a502e1225d602a5731357bc12643070ccd78282604051611ca8929190612647565b60405180910390a1505050565b606081901c916bffffffffffffffffffffffff90911690565b61086a7f8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e8383611c37565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f025b22bc000000000000000000000000000000000000000000000000000000001415611d4d57506001610476565b61047382611dbe565b60008160200183511015611db5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c815260200180612b60603c913960400191505060405180910390fd5b50016020015190565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f389901c7000000000000000000000000000000000000000000000000000000001415611e1257506001610476565b6104738260007fffffffff0000000000000000000000000000000000000000000000000000000082161580611e8857507fffffffff0000000000000000000000000000000000000000000000000000000082167f36e7817500000000000000000000000000000000000000000000000000000000145b15611e9557506001610476565b7f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614610473565b803573ffffffffffffffffffffffffffffffffffffffff8116811461047657600080fd5b600082601f830112611f13578081fd5b8135602067ffffffffffffffff80831115611f2a57fe5b611f3782838502016127ec565b83815282810190868401865b86811015612013578135890160c0807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0838e03011215611f8157898afd5b604080518281018181108a82111715611f9657fe5b8252611fa3848b01612063565b8152611fb0828501612063565b8a8201526060808501358383015260809250611fcd838601611edf565b9082015260a08481013583830152928401359289841115611fec578c8dfd5b611ffa8f8c868801016120e3565b9082015287525050509285019290850190600101611f43565b509098975050505050505050565b60008083601f840112612032578182fd5b50813567ffffffffffffffff811115612049578182fd5b602083019150836020808302850101111561136f57600080fd5b8035801515811461047657600080fd5b80357fffffffff000000000000000000000000000000000000000000000000000000008116811461047657600080fd5b60008083601f8401126120b4578182fd5b50813567ffffffffffffffff8111156120cb578182fd5b60208301915083602082850101111561136f57600080fd5b600082601f8301126120f3578081fd5b813567ffffffffffffffff81111561210757fe5b61213860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016127ec565b81815284602083860101111561214c578283fd5b816020850160208301379081016020019190915292915050565b600060208284031215612177578081fd5b61064382611edf565b60008060008060008060008060a0898b03121561219b578384fd5b6121a489611edf565b97506121b260208a01611edf565b9650604089013567ffffffffffffffff808211156121ce578586fd5b6121da8c838d01612021565b909850965060608b01359150808211156121f2578586fd5b6121fe8c838d01612021565b909650945060808b0135915080821115612216578384fd5b506122238b828c016120a3565b999c989b5096995094979396929594505050565b60008060008060006080868803121561224e578081fd5b61225786611edf565b945061226560208701611edf565b935060408601359250606086013567ffffffffffffffff811115612287578182fd5b612293888289016120a3565b969995985093965092949392505050565b60008060008060008060a087890312156122bc578182fd5b6122c587611edf565b95506122d360208801611edf565b94506040870135935060608701359250608087013567ffffffffffffffff8111156122fc578283fd5b61230889828a016120a3565b979a9699509497509295939492505050565b60006020828403121561232b578081fd5b813567ffffffffffffffff811115612341578182fd5b6106a784828501611f03565b600080600060608486031215612361578283fd5b833567ffffffffffffffff80821115612378578485fd5b61238487838801611f03565b94506020860135935060408601359150808211156123a0578283fd5b506123ad868287016120e3565b9150509250925092565b6000806000604084860312156123cb578283fd5b83359250602084013567ffffffffffffffff8111156123e8578283fd5b6123f4868287016120a3565b9497909650939450505050565b600060208284031215612412578081fd5b61064382612073565b6000806040838503121561242d578182fd5b61243683612073565b915061244460208401611edf565b90509250929050565b60008060008060408587031215612462578182fd5b843567ffffffffffffffff80821115612479578384fd5b612485888389016120a3565b9096509450602087013591508082111561249d578384fd5b506124aa878288016120a3565b95989497509550505050565b6000602082840312156124c7578081fd5b813567ffffffffffffffff8111156124dd578182fd5b6106a7848285016120e3565b6000602082840312156124fa578081fd5b5035919050565b6000815180845260208085018081965082840281019150828601855b8581101561259f5782840389528151805115158552858101511515868601526040808201519086015260608082015173ffffffffffffffffffffffffffffffffffffffff16908601526080808201519086015260a09081015160c09186018290529061258b818701836125ac565b9a87019a955050509084019060010161251d565b5091979650505050505050565b600081518084526125c4816020860160208601612810565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60008251612608818460208701612810565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b901515815260200190565b90815260200190565b6000838252604060208301526106a760408301846125ac565b7fffffffff0000000000000000000000000000000000000000000000000000000091909116815260200190565b6020808252601f908201527f4d61696e4d6f64756c65235f617574683a20494e56414c49445f4e4f4e434500604082015260600190565b60208082526024908201527f4d6f64756c6543616c6c73235f657865637574653a204e4f545f454e4f55474860408201527f5f47415300000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526026908201527f4d6f64756c6543616c6c7323657865637574653a20494e56414c49445f53494760408201527f4e41545552450000000000000000000000000000000000000000000000000000606082015260800190565b600060408252600560408301527f73656c663a0000000000000000000000000000000000000000000000000000006060830152608060208301526106436080830184612501565b6000838252604060208301526106a76040830184612501565b918252602082015260400190565b60405181810167ffffffffffffffff8111828210171561280857fe5b604052919050565b60005b8381101561282b578181015183820152602001612813565b838111156108e4575050600091015256fe5369676e617475726556616c696461746f72237265636f7665725369676e65723a20696e76616c6964207369676e6174757265202773272076616c75655369676e617475726556616c696461746f72237265636f7665725369676e65723a20696e76616c6964207369676e6174757265206c656e6774684d6f64756c6541757468235f7369676e617475726556616c69646174696f6e20494e56414c49445f464c41474d6f64756c65486f6f6b732372656d6f7665486f6f6b3a20484f4f4b5f4e4f545f524547495354455245444c696242797465732372656164416464726573733a204f55545f4f465f424f554e44534c696242797465732372656164466972737455696e7431363a204f55545f4f465f424f554e44535369676e617475726556616c696461746f72237265636f7665725369676e65723a20696e76616c6964207369676e6174757265202776272076616c75655369676e617475726556616c696461746f72237265636f7665725369676e65723a20494e56414c49445f5349474e45524d6f64756c6541757468235f7369676e617475726556616c69646174696f6e3a20494e56414c49445f5349474e41545552454d6f64756c65486f6f6b7323616464486f6f6b3a20484f4f4b5f414c52454144595f524547495354455245445369676e617475726556616c696461746f7223697356616c69645369676e61747572653a20554e535550504f525445445f5349474e41545552455f545950454c696242797465732372656164427974657336363a204f55545f4f465f424f554e44534d6f64756c6555706461746523757064617465496d706c656d656e746174696f6e3a20494e56414c49445f494d504c454d454e544154494f4e5369676e617475726556616c696461746f72237265636f7665725369676e65723a20554e535550504f525445445f5349474e41545552455f545950454c69624279746573237265616455696e743855696e74383a204f55545f4f465f424f554e44534c69624279746573237265616442797465733a204f55545f4f465f424f554e44534c69624279746573237265616455696e7431363a204f55545f4f465f424f554e44534c696242797465732372656164427974657333323a20475245415445525f4f525f455155414c5f544f5f33325f4c454e4754485f52455155495245444d6f64756c6553656c6641757468236f6e6c7953656c663a204e4f545f415554484f52495a4544a2646970667358221220b34deca9dd75815e4ef8a9279e45750ec5554b22c673e160bdba849d80f5888564736f6c63430007060033603a600e3d39601a805130553df3363d3d373d3d3d363d30545af43d82803e903d91601857fd5bf3', + deployedBytecode: + '0x6080604052600436106101125760003560e01c80634fcf3eca116100a557806390042baf11610074578063b93ea7ad11610059578063b93ea7ad146103c5578063bc197c81146103e5578063f23a6e611461040557610119565b806390042baf1461039d578063affed0e0146103b057610119565b80634fcf3eca1461031d57806361c2926c1461033d5780637a9a16281461035d5780638c3f55631461037d57610119565b80631a9b2337116100e15780631a9b23371461029957806320c13b0b146102c6578063257671f5146102e65780632dd310001461030857610119565b806301ffc9a7146101f4578063025b22bc1461022a578063150b7a021461024c5780631626ba7e1461027957610119565b3661011957005b60006101486000357fffffffff0000000000000000000000000000000000000000000000000000000016610425565b905073ffffffffffffffffffffffffffffffffffffffff8116156101f1576000808273ffffffffffffffffffffffffffffffffffffffff166000366040518083838082843760405192019450600093509091505080830381855af49150503d80600081146101d2576040519150601f19603f3d011682016040523d82523d6000602084013e6101d7565b606091505b5091509150816101e957805160208201fd5b805160208201f35b50005b34801561020057600080fd5b5061021461020f366004612401565b61047b565b6040516102219190612633565b60405180910390f35b34801561023657600080fd5b5061024a610245366004612166565b610486565b005b34801561025857600080fd5b5061026c610267366004612237565b6105a7565b6040516102219190612660565b34801561028557600080fd5b5061026c6102943660046123b7565b6105d1565b3480156102a557600080fd5b506102b96102b4366004612401565b61064a565b6040516102219190612612565b3480156102d257600080fd5b5061026c6102e136600461244d565b610655565b3480156102f257600080fd5b506102fb6106af565b604051610221919061263e565b34801561031457600080fd5b506102b96106d3565b34801561032957600080fd5b5061024a610338366004612401565b6106f7565b34801561034957600080fd5b5061024a61035836600461231a565b6107d5565b34801561036957600080fd5b5061024a61037836600461234d565b61086e565b34801561038957600080fd5b506102fb6103983660046124e9565b6108ea565b6102b96103ab3660046124b6565b610916565b3480156103bc57600080fd5b506102fb6109ca565b3480156103d157600080fd5b5061024a6103e036600461241b565b6109db565b3480156103f157600080fd5b5061026c610400366004612180565b610ab4565b34801561041157600080fd5b5061026c6104203660046122a4565b610ae1565b60006104737fbe27a319efc8734e89e26ba4bc95f5c788584163b959f03fa04e2d7ab4b9a1207fffffffff000000000000000000000000000000000000000000000000000000008416610b0c565b90505b919050565b600061047382610b39565b3330146104de576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180612b9c6027913960400191505060405180910390fd5b6104fd8173ffffffffffffffffffffffffffffffffffffffff16610b96565b610552576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526039815260200180612a826039913960400191505060405180910390fd5b61055b81610b9c565b6040805173ffffffffffffffffffffffffffffffffffffffff8316815290517f310ba5f1d2ed074b51e2eccd052a47ae9ab7c6b800d1fca3db3999d6a592ca039181900360200190a150565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b600061061b6105df85610ba0565b84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610c0092505050565b1561064357507f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b600061047382610425565b600061067f6105df86866040518083838082843760405192018290039091209350610ba092505050565b156106a757507f20c13b0b000000000000000000000000000000000000000000000000000000005b949350505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b33301461074f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180612b9c6027913960400191505060405180910390fd5b600061075a82610425565b73ffffffffffffffffffffffffffffffffffffffff1614156107c7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b8152602001806128e0602b913960400191505060405180910390fd5b6107d2816000610df8565b50565b33301461082d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180612b9c6027913960400191505060405180910390fd5b600061085e82604051602001610843919061277e565b60405160208183030381529060405280519060200120610ba0565b905061086a8183610e5b565b5050565b6108778261102a565b600061088f83856040516020016108439291906127c5565b905061089b8183610c00565b6108da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108d190612721565b60405180910390fd5b6108e48185610e5b565b50505050565b60006104737f8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e83610b0c565b6000333014610970576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180612b9c6027913960400191505060405180910390fd5b81516020830134f06040805173ffffffffffffffffffffffffffffffffffffffff8316815290519192507fa506ad4e7f05eceba62a023c3219e5bd98a615f4fa87e2afb08a2da5cf62bf0c919081900360200190a1919050565b60006109d660006108ea565b905090565b333014610a33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180612b9c6027913960400191505060405180910390fd5b6000610a3e83610425565b73ffffffffffffffffffffffffffffffffffffffff1614610aaa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001806129f4602c913960400191505060405180910390fd5b61086a8282610df8565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b60408051602080820194909452808201929092528051808303820181526060909201905280519101205490565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f90042baf000000000000000000000000000000000000000000000000000000001415610b8d57506001610476565b610473826110ce565b3b151590565b3055565b604080517f19010000000000000000000000000000000000000000000000000000000000006020808301919091524660228301523060601b6042830152605680830194909452825180830390940184526076909101909152815191012090565b6000806000610c0e8461120f565b909250905061ffff821660005b8551831015610dd55760008080610c32898761127d565b975060ff91821694501691506001831415610c5a57610c5189876112fe565b96509050610d7e565b82610c86576060610c6b8a88611376565b97509050610c798b82611427565b9150828501945050610d7e565b6002831415610d2d57610c9989876112fe565b965090506000610ca98a886117b1565b975061ffff1690506060610cbe8b8984611822565b98509050610ccd8c8483611911565b610d22576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001806129c26032913960400191505060405180910390fd5b505092810192610d7e565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001806128b4602c913960400191505060405180910390fd5b848282604051602001808481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019350505050604051602081830303815290604052805190602001209450505050610c1b565b8361ffff168110158015610ded5750610ded82611b59565b979650505050505050565b61086a7fbe27a319efc8734e89e26ba4bc95f5c788584163b959f03fa04e2d7ab4b9a1207fffffffff00000000000000000000000000000000000000000000000000000000841673ffffffffffffffffffffffffffffffffffffffff8416611c37565b60005b8151811015611025576000828281518110610e7557fe5b602002602001015190506000606082604001515a1015610ec1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108d1906126c4565b825115610f5957826060015173ffffffffffffffffffffffffffffffffffffffff168360400151600014610ef9578360400151610efb565b5a5b8460a00151604051610f0d91906125f6565b6000604051808303818686f4925050503d8060008114610f49576040519150601f19603f3d011682016040523d82523d6000602084013e610f4e565b606091505b509092509050610fee565b826060015173ffffffffffffffffffffffffffffffffffffffff1683608001518460400151600014610f8f578460400151610f91565b5a5b908560a00151604051610fa491906125f6565b600060405180830381858888f193505050503d8060008114610fe2576040519150601f19603f3d011682016040523d82523d6000602084013e610fe7565b606091505b5090925090505b811561100f5785604051611002919061263e565b60405180910390a061101a565b61101a838783611c65565b505050600101610e5e565b505050565b60008061103683611cb5565b915091506000611045836108ea565b9050808214611080576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108d19061268d565b6001820161108e8482611cce565b7f1f180c27086c7a39ea2a7b25239d1ab92348f07ca7bb59d1438fcf527568f88184826040516110bf9291906127de565b60405180910390a15050505050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fec6aba5000000000000000000000000000000000000000000000000000000000148061116157507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b806111ad57507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b806111f957507fffffffff0000000000000000000000000000000000000000000000000000000082167fc0ee0b8a00000000000000000000000000000000000000000000000000000000145b1561120657506001610476565b61047382611cf9565b6020810151815160f09190911c90600290811115611278576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061292e6027913960400191505060405180910390fd5b915091565b8082016020015160f881901c9060f01c60ff166002830183811161129d57fe5b84518111156112f7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180612af76026913960400191505060405180910390fd5b9250925092565b8082016020015160601c6014820182811161131557fe5b835181111561136f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602381526020018061290b6023913960400191505060405180910390fd5b9250929050565b6040805160428082526080820190925260609160009190602082018180368337019050509150828401602001805160208401526020810151604084015260228101516042840152506042830190508281116113cd57fe5b835181111561136f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180612a5f6023913960400191505060405180910390fd5b60008151604214611483576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603a81526020018061287a603a913960400191505060405180910390fd5b60008260018451038151811061149557fe5b602001015160f81c60f81b60f81c60ff1690506000836040815181106114b757fe5b016020015160f81c905060006114cd8582611d56565b905060006114dc866020611d56565b90507f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0811115611557576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d81526020018061283d603d913960400191505060405180910390fd5b8260ff16601b1415801561156f57508260ff16601c14155b156115c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d815260200180612955603d913960400191505060405180910390fd5b60018414156116395760018784848460405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015611628573d6000803e3d6000fd5b50505060206040510351945061173b565b60028414156116ea5760018760405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012084848460405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015611628573d6000803e3d6000fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c815260200180612abb603c913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff85166117a7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260308152602001806129926030913960400191505060405180910390fd5b5050505092915050565b8082016020015160f01c600282018281116117c857fe5b835181111561136f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180612b3e6022913960400191505060405180910390fd5b606060008267ffffffffffffffff8111801561183d57600080fd5b506040519080825280601f01601f191660200182016040528015611868576020820181803683370190505b509150838501602001600060205b8581101561188f57908201518482015260208101611876565b84860160200180519390920151908501525250828201838110156118af57fe5b8451811115611909576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180612b1d6021913960400191505060405180910390fd5b935093915050565b6000808260018451038151811061192457fe5b016020015160f81c9050600181148061193d5750600281145b15611981578373ffffffffffffffffffffffffffffffffffffffff166119638685611427565b73ffffffffffffffffffffffffffffffffffffffff16149150611b51565b6003811415611b005782517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81018452604080517f1626ba7e000000000000000000000000000000000000000000000000000000008152600481018881526024820192835286516044830152865173ffffffffffffffffffffffffffffffffffffffff891693631626ba7e938b938a9390929160640190602085019080838360005b83811015611a3b578181015183820152602001611a23565b50505050905090810190601f168015611a685780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b158015611a8657600080fd5b505afa158015611a9a573d6000803e3d6000fd5b505050506040513d6020811015611ab057600080fd5b50519084527fffffffff00000000000000000000000000000000000000000000000000000000167f1626ba7e00000000000000000000000000000000000000000000000000000000149150611b51565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603f815260200180612a20603f913960400191505060405180910390fd5b509392505050565b604080517fff000000000000000000000000000000000000000000000000000000000000006020808301919091527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060601b166021830152603582018490527f0000000000000000000000000000000000000000000000000000000000000000605580840191909152835180840390910181526075909201909252805191012073ffffffffffffffffffffffffffffffffffffffff163014919050565b6040805160208082019590955280820193909352805180840382018152606090930190528151919092012055565b826020015115611c7757805160208201fd5b7f3dbd1590ea96dd3253a91f24e64e3a502e1225d602a5731357bc12643070ccd78282604051611ca8929190612647565b60405180910390a1505050565b606081901c916bffffffffffffffffffffffff90911690565b61086a7f8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e8383611c37565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f025b22bc000000000000000000000000000000000000000000000000000000001415611d4d57506001610476565b61047382611dbe565b60008160200183511015611db5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c815260200180612b60603c913960400191505060405180910390fd5b50016020015190565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f389901c7000000000000000000000000000000000000000000000000000000001415611e1257506001610476565b6104738260007fffffffff0000000000000000000000000000000000000000000000000000000082161580611e8857507fffffffff0000000000000000000000000000000000000000000000000000000082167f36e7817500000000000000000000000000000000000000000000000000000000145b15611e9557506001610476565b7f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614610473565b803573ffffffffffffffffffffffffffffffffffffffff8116811461047657600080fd5b600082601f830112611f13578081fd5b8135602067ffffffffffffffff80831115611f2a57fe5b611f3782838502016127ec565b83815282810190868401865b86811015612013578135890160c0807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0838e03011215611f8157898afd5b604080518281018181108a82111715611f9657fe5b8252611fa3848b01612063565b8152611fb0828501612063565b8a8201526060808501358383015260809250611fcd838601611edf565b9082015260a08481013583830152928401359289841115611fec578c8dfd5b611ffa8f8c868801016120e3565b9082015287525050509285019290850190600101611f43565b509098975050505050505050565b60008083601f840112612032578182fd5b50813567ffffffffffffffff811115612049578182fd5b602083019150836020808302850101111561136f57600080fd5b8035801515811461047657600080fd5b80357fffffffff000000000000000000000000000000000000000000000000000000008116811461047657600080fd5b60008083601f8401126120b4578182fd5b50813567ffffffffffffffff8111156120cb578182fd5b60208301915083602082850101111561136f57600080fd5b600082601f8301126120f3578081fd5b813567ffffffffffffffff81111561210757fe5b61213860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016127ec565b81815284602083860101111561214c578283fd5b816020850160208301379081016020019190915292915050565b600060208284031215612177578081fd5b61064382611edf565b60008060008060008060008060a0898b03121561219b578384fd5b6121a489611edf565b97506121b260208a01611edf565b9650604089013567ffffffffffffffff808211156121ce578586fd5b6121da8c838d01612021565b909850965060608b01359150808211156121f2578586fd5b6121fe8c838d01612021565b909650945060808b0135915080821115612216578384fd5b506122238b828c016120a3565b999c989b5096995094979396929594505050565b60008060008060006080868803121561224e578081fd5b61225786611edf565b945061226560208701611edf565b935060408601359250606086013567ffffffffffffffff811115612287578182fd5b612293888289016120a3565b969995985093965092949392505050565b60008060008060008060a087890312156122bc578182fd5b6122c587611edf565b95506122d360208801611edf565b94506040870135935060608701359250608087013567ffffffffffffffff8111156122fc578283fd5b61230889828a016120a3565b979a9699509497509295939492505050565b60006020828403121561232b578081fd5b813567ffffffffffffffff811115612341578182fd5b6106a784828501611f03565b600080600060608486031215612361578283fd5b833567ffffffffffffffff80821115612378578485fd5b61238487838801611f03565b94506020860135935060408601359150808211156123a0578283fd5b506123ad868287016120e3565b9150509250925092565b6000806000604084860312156123cb578283fd5b83359250602084013567ffffffffffffffff8111156123e8578283fd5b6123f4868287016120a3565b9497909650939450505050565b600060208284031215612412578081fd5b61064382612073565b6000806040838503121561242d578182fd5b61243683612073565b915061244460208401611edf565b90509250929050565b60008060008060408587031215612462578182fd5b843567ffffffffffffffff80821115612479578384fd5b612485888389016120a3565b9096509450602087013591508082111561249d578384fd5b506124aa878288016120a3565b95989497509550505050565b6000602082840312156124c7578081fd5b813567ffffffffffffffff8111156124dd578182fd5b6106a7848285016120e3565b6000602082840312156124fa578081fd5b5035919050565b6000815180845260208085018081965082840281019150828601855b8581101561259f5782840389528151805115158552858101511515868601526040808201519086015260608082015173ffffffffffffffffffffffffffffffffffffffff16908601526080808201519086015260a09081015160c09186018290529061258b818701836125ac565b9a87019a955050509084019060010161251d565b5091979650505050505050565b600081518084526125c4816020860160208601612810565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60008251612608818460208701612810565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b901515815260200190565b90815260200190565b6000838252604060208301526106a760408301846125ac565b7fffffffff0000000000000000000000000000000000000000000000000000000091909116815260200190565b6020808252601f908201527f4d61696e4d6f64756c65235f617574683a20494e56414c49445f4e4f4e434500604082015260600190565b60208082526024908201527f4d6f64756c6543616c6c73235f657865637574653a204e4f545f454e4f55474860408201527f5f47415300000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526026908201527f4d6f64756c6543616c6c7323657865637574653a20494e56414c49445f53494760408201527f4e41545552450000000000000000000000000000000000000000000000000000606082015260800190565b600060408252600560408301527f73656c663a0000000000000000000000000000000000000000000000000000006060830152608060208301526106436080830184612501565b6000838252604060208301526106a76040830184612501565b918252602082015260400190565b60405181810167ffffffffffffffff8111828210171561280857fe5b604052919050565b60005b8381101561282b578181015183820152602001612813565b838111156108e4575050600091015256fe5369676e617475726556616c696461746f72237265636f7665725369676e65723a20696e76616c6964207369676e6174757265202773272076616c75655369676e617475726556616c696461746f72237265636f7665725369676e65723a20696e76616c6964207369676e6174757265206c656e6774684d6f64756c6541757468235f7369676e617475726556616c69646174696f6e20494e56414c49445f464c41474d6f64756c65486f6f6b732372656d6f7665486f6f6b3a20484f4f4b5f4e4f545f524547495354455245444c696242797465732372656164416464726573733a204f55545f4f465f424f554e44534c696242797465732372656164466972737455696e7431363a204f55545f4f465f424f554e44535369676e617475726556616c696461746f72237265636f7665725369676e65723a20696e76616c6964207369676e6174757265202776272076616c75655369676e617475726556616c696461746f72237265636f7665725369676e65723a20494e56414c49445f5349474e45524d6f64756c6541757468235f7369676e617475726556616c69646174696f6e3a20494e56414c49445f5349474e41545552454d6f64756c65486f6f6b7323616464486f6f6b3a20484f4f4b5f414c52454144595f524547495354455245445369676e617475726556616c696461746f7223697356616c69645369676e61747572653a20554e535550504f525445445f5349474e41545552455f545950454c696242797465732372656164427974657336363a204f55545f4f465f424f554e44534d6f64756c6555706461746523757064617465496d706c656d656e746174696f6e3a20494e56414c49445f494d504c454d454e544154494f4e5369676e617475726556616c696461746f72237265636f7665725369676e65723a20554e535550504f525445445f5349474e41545552455f545950454c69624279746573237265616455696e743855696e74383a204f55545f4f465f424f554e44534c69624279746573237265616442797465733a204f55545f4f465f424f554e44534c69624279746573237265616455696e7431363a204f55545f4f465f424f554e44534c696242797465732372656164427974657333323a20475245415445525f4f525f455155414c5f544f5f33325f4c454e4754485f52455155495245444d6f64756c6553656c6641757468236f6e6c7953656c663a204e4f545f415554484f52495a4544a2646970667358221220b34deca9dd75815e4ef8a9279e45750ec5554b22c673e160bdba849d80f5888564736f6c63430007060033', + linkReferences: {}, + deployedLinkReferences: {} +} diff --git a/packages/tests/src/builds/v1/artifacts/MainModuleUpgradable.ts b/packages/tests/src/builds/v1/artifacts/MainModuleUpgradable.ts new file mode 100644 index 0000000000..2a9d12243c --- /dev/null +++ b/packages/tests/src/builds/v1/artifacts/MainModuleUpgradable.ts @@ -0,0 +1,530 @@ +export const mainModuleUpgradable = { + _format: 'hh-sol-artifact-1', + contractName: 'MainModuleUpgradable', + sourceName: 'contracts/modules/MainModuleUpgradable.sol', + abi: [ + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: '_contract', + type: 'address' + } + ], + name: 'CreatedContract', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'bytes32', + name: 'newImageHash', + type: 'bytes32' + } + ], + name: 'ImageHashUpdated', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'newImplementation', + type: 'address' + } + ], + name: 'ImplementationUpdated', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: '_space', + type: 'uint256' + }, + { + indexed: false, + internalType: 'uint256', + name: '_newNonce', + type: 'uint256' + } + ], + name: 'NonceChange', + type: 'event' + }, + { + anonymous: true, + inputs: [ + { + indexed: false, + internalType: 'bytes32', + name: '_tx', + type: 'bytes32' + } + ], + name: 'TxExecuted', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'bytes32', + name: '_tx', + type: 'bytes32' + }, + { + indexed: false, + internalType: 'bytes', + name: '_reason', + type: 'bytes' + } + ], + name: 'TxFailed', + type: 'event' + }, + { + stateMutability: 'payable', + type: 'fallback' + }, + { + inputs: [ + { + internalType: 'bytes4', + name: '_signature', + type: 'bytes4' + }, + { + internalType: 'address', + name: '_implementation', + type: 'address' + } + ], + name: 'addHook', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_code', + type: 'bytes' + } + ], + name: 'createContract', + outputs: [ + { + internalType: 'address', + name: 'addr', + type: 'address' + } + ], + stateMutability: 'payable', + type: 'function' + }, + { + inputs: [ + { + components: [ + { + internalType: 'bool', + name: 'delegateCall', + type: 'bool' + }, + { + internalType: 'bool', + name: 'revertOnError', + type: 'bool' + }, + { + internalType: 'uint256', + name: 'gasLimit', + type: 'uint256' + }, + { + internalType: 'address', + name: 'target', + type: 'address' + }, + { + internalType: 'uint256', + name: 'value', + type: 'uint256' + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes' + } + ], + internalType: 'struct IModuleCalls.Transaction[]', + name: '_txs', + type: 'tuple[]' + }, + { + internalType: 'uint256', + name: '_nonce', + type: 'uint256' + }, + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + } + ], + name: 'execute', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [], + name: 'imageHash', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_hash', + type: 'bytes32' + }, + { + internalType: 'bytes', + name: '_signatures', + type: 'bytes' + } + ], + name: 'isValidSignature', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_data', + type: 'bytes' + }, + { + internalType: 'bytes', + name: '_signatures', + type: 'bytes' + } + ], + name: 'isValidSignature', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'nonce', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]' + }, + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]' + }, + { + internalType: 'bytes', + name: '', + type: 'bytes' + } + ], + name: 'onERC1155BatchReceived', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'uint256', + name: '', + type: 'uint256' + }, + { + internalType: 'uint256', + name: '', + type: 'uint256' + }, + { + internalType: 'bytes', + name: '', + type: 'bytes' + } + ], + name: 'onERC1155Received', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'uint256', + name: '', + type: 'uint256' + }, + { + internalType: 'bytes', + name: '', + type: 'bytes' + } + ], + name: 'onERC721Received', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes4', + name: '_signature', + type: 'bytes4' + } + ], + name: 'readHook', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_space', + type: 'uint256' + } + ], + name: 'readNonce', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes4', + name: '_signature', + type: 'bytes4' + } + ], + name: 'removeHook', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + components: [ + { + internalType: 'bool', + name: 'delegateCall', + type: 'bool' + }, + { + internalType: 'bool', + name: 'revertOnError', + type: 'bool' + }, + { + internalType: 'uint256', + name: 'gasLimit', + type: 'uint256' + }, + { + internalType: 'address', + name: 'target', + type: 'address' + }, + { + internalType: 'uint256', + name: 'value', + type: 'uint256' + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes' + } + ], + internalType: 'struct IModuleCalls.Transaction[]', + name: '_txs', + type: 'tuple[]' + } + ], + name: 'selfExecute', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes4', + name: '_interfaceID', + type: 'bytes4' + } + ], + name: 'supportsInterface', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool' + } + ], + stateMutability: 'pure', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_imageHash', + type: 'bytes32' + } + ], + name: 'updateImageHash', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '_implementation', + type: 'address' + } + ], + name: 'updateImplementation', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + stateMutability: 'payable', + type: 'receive' + } + ], + bytecode: + '0x608060405234801561001057600080fd5b50612ce7806100206000396000f3fe6080604052600436106101125760003560e01c806351605d80116100a557806390042baf11610074578063b93ea7ad11610059578063b93ea7ad146103d0578063bc197c81146103f0578063f23a6e611461041057610119565b806390042baf146103a8578063affed0e0146103bb57610119565b806351605d801461032657806361c2926c146103485780637a9a1628146103685780638c3f55631461038857610119565b80631a9b2337116100e15780631a9b23371461029957806320c13b0b146102c657806329561426146102e65780634fcf3eca1461030657610119565b806301ffc9a7146101f4578063025b22bc1461022a578063150b7a021461024c5780631626ba7e1461027957610119565b3661011957005b60006101486000357fffffffff0000000000000000000000000000000000000000000000000000000016610430565b905073ffffffffffffffffffffffffffffffffffffffff8116156101f1576000808273ffffffffffffffffffffffffffffffffffffffff166000366040518083838082843760405192019450600093509091505080830381855af49150503d80600081146101d2576040519150601f19603f3d011682016040523d82523d6000602084013e6101d7565b606091505b5091509150816101e957805160208201fd5b805160208201f35b50005b34801561020057600080fd5b5061021461020f3660046124d4565b610486565b60405161022191906126eb565b60405180910390f35b34801561023657600080fd5b5061024a610245366004612221565b610491565b005b34801561025857600080fd5b5061026c6102673660046122f2565b6105b2565b6040516102219190612718565b34801561028557600080fd5b5061026c61029436600461248a565b6105dc565b3480156102a557600080fd5b506102b96102b43660046124d4565b610655565b60405161022191906126ca565b3480156102d257600080fd5b5061026c6102e1366004612520565b610660565b3480156102f257600080fd5b5061024a610301366004612472565b6106ba565b34801561031257600080fd5b5061024a6103213660046124d4565b6107c8565b34801561033257600080fd5b5061033b6108a6565b60405161022191906126f6565b34801561035457600080fd5b5061024a6103633660046123d5565b6108d6565b34801561037457600080fd5b5061024a610383366004612408565b61096f565b34801561039457600080fd5b5061033b6103a3366004612472565b6109eb565b6102b96103b6366004612589565b610a17565b3480156103c757600080fd5b5061033b610acb565b3480156103dc57600080fd5b5061024a6103eb3660046124ee565b610ad7565b3480156103fc57600080fd5b5061026c61040b36600461223b565b610bb0565b34801561041c57600080fd5b5061026c61042b36600461235f565b610bdd565b600061047e7fbe27a319efc8734e89e26ba4bc95f5c788584163b959f03fa04e2d7ab4b9a1207fffffffff000000000000000000000000000000000000000000000000000000008416610c08565b90505b919050565b600061047e82610c35565b3330146104e9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180612c8b6027913960400191505060405180910390fd5b6105088173ffffffffffffffffffffffffffffffffffffffff16610c92565b61055d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526039815260200180612b716039913960400191505060405180910390fd5b61056681610c98565b6040805173ffffffffffffffffffffffffffffffffffffffff8316815290517f310ba5f1d2ed074b51e2eccd052a47ae9ab7c6b800d1fca3db3999d6a592ca039181900360200190a150565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b60006106266105ea85610c9c565b84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cfc92505050565b1561064e57507f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b600061047e82610430565b600061068a6105ea86866040518083838082843760405192018290039091209350610c9c92505050565b156106b257507f20c13b0b000000000000000000000000000000000000000000000000000000005b949350505050565b333014610712576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180612c8b6027913960400191505060405180910390fd5b80610768576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260378152602001806129986037913960400191505060405180910390fd5b6107927fea7157fa25e3aa17d0ae2d5280fa4e24d421c61842aa85e45194e1145aa72bf882610ef4565b6040805182815290517f307ed6bd941ee9fc80f369c94af5fa11e25bab5102a6140191756c5474a30bfa9181900360200190a150565b333014610820576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180612c8b6027913960400191505060405180910390fd5b600061082b82610430565b73ffffffffffffffffffffffffffffffffffffffff161415610898576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b8152602001806129cf602b913960400191505060405180910390fd5b6108a3816000610ef8565b50565b60006108d17fea7157fa25e3aa17d0ae2d5280fa4e24d421c61842aa85e45194e1145aa72bf8610f5b565b905090565b33301461092e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180612c8b6027913960400191505060405180910390fd5b600061095f826040516020016109449190612836565b60405160208183030381529060405280519060200120610c9c565b905061096b8183610f5f565b5050565b6109788261112e565b6000610990838560405160200161094492919061287d565b905061099c8183610cfc565b6109db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109d2906127d9565b60405180910390fd5b6109e58185610f5f565b50505050565b600061047e7f8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e83610c08565b6000333014610a71576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180612c8b6027913960400191505060405180910390fd5b81516020830134f06040805173ffffffffffffffffffffffffffffffffffffffff8316815290519192507fa506ad4e7f05eceba62a023c3219e5bd98a615f4fa87e2afb08a2da5cf62bf0c919081900360200190a1919050565b60006108d160006109eb565b333014610b2f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180612c8b6027913960400191505060405180910390fd5b6000610b3a83610430565b73ffffffffffffffffffffffffffffffffffffffff1614610ba6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180612ae3602c913960400191505060405180910390fd5b61096b8282610ef8565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b60408051602080820194909452808201929092528051808303820181526060909201905280519101205490565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f90042baf000000000000000000000000000000000000000000000000000000001415610c8957506001610481565b61047e826111d2565b3b151590565b3055565b604080517f19010000000000000000000000000000000000000000000000000000000000006020808301919091524660228301523060601b6042830152605680830194909452825180830390940184526076909101909152815191012090565b6000806000610d0a84611313565b909250905061ffff821660005b8551831015610ed15760008080610d2e8987611381565b975060ff91821694501691506001831415610d5657610d4d8987611402565b96509050610e7a565b82610d82576060610d678a8861147a565b97509050610d758b8261152b565b9150828501945050610e7a565b6002831415610e2957610d958987611402565b965090506000610da58a886118b5565b975061ffff1690506060610dba8b8984611926565b98509050610dc98c8483611a15565b610e1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526032815260200180612ab16032913960400191505060405180910390fd5b505092810192610e7a565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c81526020018061296c602c913960400191505060405180910390fd5b848282604051602001808481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019350505050604051602081830303815290604052805190602001209450505050610d17565b8361ffff168110158015610ee95750610ee982611c5d565b979650505050505050565b9055565b61096b7fbe27a319efc8734e89e26ba4bc95f5c788584163b959f03fa04e2d7ab4b9a1207fffffffff00000000000000000000000000000000000000000000000000000000841673ffffffffffffffffffffffffffffffffffffffff8416611c9a565b5490565b60005b8151811015611129576000828281518110610f7957fe5b602002602001015190506000606082604001515a1015610fc5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109d29061277c565b82511561105d57826060015173ffffffffffffffffffffffffffffffffffffffff168360400151600014610ffd578360400151610fff565b5a5b8460a0015160405161101191906126ae565b6000604051808303818686f4925050503d806000811461104d576040519150601f19603f3d011682016040523d82523d6000602084013e611052565b606091505b5090925090506110f2565b826060015173ffffffffffffffffffffffffffffffffffffffff1683608001518460400151600014611093578460400151611095565b5a5b908560a001516040516110a891906126ae565b600060405180830381858888f193505050503d80600081146110e6576040519150601f19603f3d011682016040523d82523d6000602084013e6110eb565b606091505b5090925090505b8115611113578560405161110691906126f6565b60405180910390a061111e565b61111e838783611cc8565b505050600101610f62565b505050565b60008061113a83611d18565b915091506000611149836109eb565b9050808214611184576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109d290612745565b600182016111928482611d31565b7f1f180c27086c7a39ea2a7b25239d1ab92348f07ca7bb59d1438fcf527568f88184826040516111c3929190612896565b60405180910390a15050505050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fec6aba5000000000000000000000000000000000000000000000000000000000148061126557507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b806112b157507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b806112fd57507fffffffff0000000000000000000000000000000000000000000000000000000082167fc0ee0b8a00000000000000000000000000000000000000000000000000000000145b1561130a57506001610481565b61047e82611d5c565b6020810151815160f09190911c9060029081111561137c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180612a1d6027913960400191505060405180910390fd5b915091565b8082016020015160f881901c9060f01c60ff16600283018381116113a157fe5b84518111156113fb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180612be66026913960400191505060405180910390fd5b9250925092565b8082016020015160601c6014820182811161141957fe5b8351811115611473576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806129fa6023913960400191505060405180910390fd5b9250929050565b6040805160428082526080820190925260609160009190602082018180368337019050509150828401602001805160208401526020810151604084015260228101516042840152506042830190508281116114d157fe5b8351811115611473576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180612b4e6023913960400191505060405180910390fd5b60008151604214611587576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603a815260200180612932603a913960400191505060405180910390fd5b60008260018451038151811061159957fe5b602001015160f81c60f81b60f81c60ff1690506000836040815181106115bb57fe5b016020015160f81c905060006115d18582611db9565b905060006115e0866020611db9565b90507f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a081111561165b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d8152602001806128f5603d913960400191505060405180910390fd5b8260ff16601b1415801561167357508260ff16601c14155b156116c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d815260200180612a44603d913960400191505060405180910390fd5b600184141561173d5760018784848460405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa15801561172c573d6000803e3d6000fd5b50505060206040510351945061183f565b60028414156117ee5760018760405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012084848460405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa15801561172c573d6000803e3d6000fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c815260200180612baa603c913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff85166118ab576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526030815260200180612a816030913960400191505060405180910390fd5b5050505092915050565b8082016020015160f01c600282018281116118cc57fe5b8351811115611473576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180612c2d6022913960400191505060405180910390fd5b606060008267ffffffffffffffff8111801561194157600080fd5b506040519080825280601f01601f19166020018201604052801561196c576020820181803683370190505b509150838501602001600060205b858110156119935790820151848201526020810161197a565b84860160200180519390920151908501525250828201838110156119b357fe5b8451811115611a0d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180612c0c6021913960400191505060405180910390fd5b935093915050565b60008082600184510381518110611a2857fe5b016020015160f81c90506001811480611a415750600281145b15611a85578373ffffffffffffffffffffffffffffffffffffffff16611a67868561152b565b73ffffffffffffffffffffffffffffffffffffffff16149150611c55565b6003811415611c045782517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81018452604080517f1626ba7e000000000000000000000000000000000000000000000000000000008152600481018881526024820192835286516044830152865173ffffffffffffffffffffffffffffffffffffffff891693631626ba7e938b938a9390929160640190602085019080838360005b83811015611b3f578181015183820152602001611b27565b50505050905090810190601f168015611b6c5780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b158015611b8a57600080fd5b505afa158015611b9e573d6000803e3d6000fd5b505050506040513d6020811015611bb457600080fd5b50519084527fffffffff00000000000000000000000000000000000000000000000000000000167f1626ba7e00000000000000000000000000000000000000000000000000000000149150611c55565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603f815260200180612b0f603f913960400191505060405180910390fd5b509392505050565b6000811580159061047e5750611c927fea7157fa25e3aa17d0ae2d5280fa4e24d421c61842aa85e45194e1145aa72bf8610f5b565b909114919050565b6040805160208082019590955280820193909352805180840382018152606090930190528151919092012055565b826020015115611cda57805160208201fd5b7f3dbd1590ea96dd3253a91f24e64e3a502e1225d602a5731357bc12643070ccd78282604051611d0b9291906126ff565b60405180910390a1505050565b606081901c916bffffffffffffffffffffffff90911690565b61096b7f8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e8383611c9a565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f025b22bc000000000000000000000000000000000000000000000000000000001415611db057506001610481565b61047e82611e21565b60008160200183511015611e18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c815260200180612c4f603c913960400191505060405180910390fd5b50016020015190565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f389901c7000000000000000000000000000000000000000000000000000000001415611e7557506001610481565b61047e8260007fffffffff0000000000000000000000000000000000000000000000000000000082167f783649a6000000000000000000000000000000000000000000000000000000001415611ecd57506001610481565b61047e8260007fffffffff0000000000000000000000000000000000000000000000000000000082161580611f4357507fffffffff0000000000000000000000000000000000000000000000000000000082167f36e7817500000000000000000000000000000000000000000000000000000000145b15611f5057506001610481565b7f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083161461047e565b803573ffffffffffffffffffffffffffffffffffffffff8116811461048157600080fd5b600082601f830112611fce578081fd5b8135602067ffffffffffffffff80831115611fe557fe5b611ff282838502016128a4565b83815282810190868401865b868110156120ce578135890160c0807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0838e0301121561203c57898afd5b604080518281018181108a8211171561205157fe5b825261205e848b0161211e565b815261206b82850161211e565b8a8201526060808501358383015260809250612088838601611f9a565b9082015260a084810135838301529284013592898411156120a7578c8dfd5b6120b58f8c8688010161219e565b9082015287525050509285019290850190600101611ffe565b509098975050505050505050565b60008083601f8401126120ed578182fd5b50813567ffffffffffffffff811115612104578182fd5b602083019150836020808302850101111561147357600080fd5b8035801515811461048157600080fd5b80357fffffffff000000000000000000000000000000000000000000000000000000008116811461048157600080fd5b60008083601f84011261216f578182fd5b50813567ffffffffffffffff811115612186578182fd5b60208301915083602082850101111561147357600080fd5b600082601f8301126121ae578081fd5b813567ffffffffffffffff8111156121c257fe5b6121f360207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016128a4565b818152846020838601011115612207578283fd5b816020850160208301379081016020019190915292915050565b600060208284031215612232578081fd5b61064e82611f9a565b60008060008060008060008060a0898b031215612256578384fd5b61225f89611f9a565b975061226d60208a01611f9a565b9650604089013567ffffffffffffffff80821115612289578586fd5b6122958c838d016120dc565b909850965060608b01359150808211156122ad578586fd5b6122b98c838d016120dc565b909650945060808b01359150808211156122d1578384fd5b506122de8b828c0161215e565b999c989b5096995094979396929594505050565b600080600080600060808688031215612309578081fd5b61231286611f9a565b945061232060208701611f9a565b935060408601359250606086013567ffffffffffffffff811115612342578182fd5b61234e8882890161215e565b969995985093965092949392505050565b60008060008060008060a08789031215612377578182fd5b61238087611f9a565b955061238e60208801611f9a565b94506040870135935060608701359250608087013567ffffffffffffffff8111156123b7578283fd5b6123c389828a0161215e565b979a9699509497509295939492505050565b6000602082840312156123e6578081fd5b813567ffffffffffffffff8111156123fc578182fd5b6106b284828501611fbe565b60008060006060848603121561241c578283fd5b833567ffffffffffffffff80821115612433578485fd5b61243f87838801611fbe565b945060208601359350604086013591508082111561245b578283fd5b506124688682870161219e565b9150509250925092565b600060208284031215612483578081fd5b5035919050565b60008060006040848603121561249e578283fd5b83359250602084013567ffffffffffffffff8111156124bb578283fd5b6124c78682870161215e565b9497909650939450505050565b6000602082840312156124e5578081fd5b61064e8261212e565b60008060408385031215612500578182fd5b6125098361212e565b915061251760208401611f9a565b90509250929050565b60008060008060408587031215612535578182fd5b843567ffffffffffffffff8082111561254c578384fd5b6125588883890161215e565b90965094506020870135915080821115612570578384fd5b5061257d8782880161215e565b95989497509550505050565b60006020828403121561259a578081fd5b813567ffffffffffffffff8111156125b0578182fd5b6106b28482850161219e565b6000815180845260208085019450848183028601828601855b858110156126575783830389528151805115158452858101511515868501526040808201519085015260608082015173ffffffffffffffffffffffffffffffffffffffff16908501526080808201519085015260a09081015160c09185018290529061264381860183612664565b9a87019a94505050908401906001016125d5565b5090979650505050505050565b6000815180845261267c8160208601602086016128c8565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600082516126c08184602087016128c8565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b901515815260200190565b90815260200190565b6000838252604060208301526106b26040830184612664565b7fffffffff0000000000000000000000000000000000000000000000000000000091909116815260200190565b6020808252601f908201527f4d61696e4d6f64756c65235f617574683a20494e56414c49445f4e4f4e434500604082015260600190565b60208082526024908201527f4d6f64756c6543616c6c73235f657865637574653a204e4f545f454e4f55474860408201527f5f47415300000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526026908201527f4d6f64756c6543616c6c7323657865637574653a20494e56414c49445f53494760408201527f4e41545552450000000000000000000000000000000000000000000000000000606082015260800190565b600060408252600560408301527f73656c663a00000000000000000000000000000000000000000000000000000060608301526080602083015261064e60808301846125bc565b6000838252604060208301526106b260408301846125bc565b918252602082015260400190565b60405181810167ffffffffffffffff811182821017156128c057fe5b604052919050565b60005b838110156128e35781810151838201526020016128cb565b838111156109e5575050600091015256fe5369676e617475726556616c696461746f72237265636f7665725369676e65723a20696e76616c6964207369676e6174757265202773272076616c75655369676e617475726556616c696461746f72237265636f7665725369676e65723a20696e76616c6964207369676e6174757265206c656e6774684d6f64756c6541757468235f7369676e617475726556616c69646174696f6e20494e56414c49445f464c41474d6f64756c654175746855706772616461626c6523757064617465496d6167654861736820494e56414c49445f494d4147455f484153484d6f64756c65486f6f6b732372656d6f7665486f6f6b3a20484f4f4b5f4e4f545f524547495354455245444c696242797465732372656164416464726573733a204f55545f4f465f424f554e44534c696242797465732372656164466972737455696e7431363a204f55545f4f465f424f554e44535369676e617475726556616c696461746f72237265636f7665725369676e65723a20696e76616c6964207369676e6174757265202776272076616c75655369676e617475726556616c696461746f72237265636f7665725369676e65723a20494e56414c49445f5349474e45524d6f64756c6541757468235f7369676e617475726556616c69646174696f6e3a20494e56414c49445f5349474e41545552454d6f64756c65486f6f6b7323616464486f6f6b3a20484f4f4b5f414c52454144595f524547495354455245445369676e617475726556616c696461746f7223697356616c69645369676e61747572653a20554e535550504f525445445f5349474e41545552455f545950454c696242797465732372656164427974657336363a204f55545f4f465f424f554e44534d6f64756c6555706461746523757064617465496d706c656d656e746174696f6e3a20494e56414c49445f494d504c454d454e544154494f4e5369676e617475726556616c696461746f72237265636f7665725369676e65723a20554e535550504f525445445f5349474e41545552455f545950454c69624279746573237265616455696e743855696e74383a204f55545f4f465f424f554e44534c69624279746573237265616442797465733a204f55545f4f465f424f554e44534c69624279746573237265616455696e7431363a204f55545f4f465f424f554e44534c696242797465732372656164427974657333323a20475245415445525f4f525f455155414c5f544f5f33325f4c454e4754485f52455155495245444d6f64756c6553656c6641757468236f6e6c7953656c663a204e4f545f415554484f52495a4544a2646970667358221220aebb8d931ef86555b6441c416b208bb9fe8fe0974c5733ebbccce548296c37ce64736f6c63430007060033', + deployedBytecode: + '0x6080604052600436106101125760003560e01c806351605d80116100a557806390042baf11610074578063b93ea7ad11610059578063b93ea7ad146103d0578063bc197c81146103f0578063f23a6e611461041057610119565b806390042baf146103a8578063affed0e0146103bb57610119565b806351605d801461032657806361c2926c146103485780637a9a1628146103685780638c3f55631461038857610119565b80631a9b2337116100e15780631a9b23371461029957806320c13b0b146102c657806329561426146102e65780634fcf3eca1461030657610119565b806301ffc9a7146101f4578063025b22bc1461022a578063150b7a021461024c5780631626ba7e1461027957610119565b3661011957005b60006101486000357fffffffff0000000000000000000000000000000000000000000000000000000016610430565b905073ffffffffffffffffffffffffffffffffffffffff8116156101f1576000808273ffffffffffffffffffffffffffffffffffffffff166000366040518083838082843760405192019450600093509091505080830381855af49150503d80600081146101d2576040519150601f19603f3d011682016040523d82523d6000602084013e6101d7565b606091505b5091509150816101e957805160208201fd5b805160208201f35b50005b34801561020057600080fd5b5061021461020f3660046124d4565b610486565b60405161022191906126eb565b60405180910390f35b34801561023657600080fd5b5061024a610245366004612221565b610491565b005b34801561025857600080fd5b5061026c6102673660046122f2565b6105b2565b6040516102219190612718565b34801561028557600080fd5b5061026c61029436600461248a565b6105dc565b3480156102a557600080fd5b506102b96102b43660046124d4565b610655565b60405161022191906126ca565b3480156102d257600080fd5b5061026c6102e1366004612520565b610660565b3480156102f257600080fd5b5061024a610301366004612472565b6106ba565b34801561031257600080fd5b5061024a6103213660046124d4565b6107c8565b34801561033257600080fd5b5061033b6108a6565b60405161022191906126f6565b34801561035457600080fd5b5061024a6103633660046123d5565b6108d6565b34801561037457600080fd5b5061024a610383366004612408565b61096f565b34801561039457600080fd5b5061033b6103a3366004612472565b6109eb565b6102b96103b6366004612589565b610a17565b3480156103c757600080fd5b5061033b610acb565b3480156103dc57600080fd5b5061024a6103eb3660046124ee565b610ad7565b3480156103fc57600080fd5b5061026c61040b36600461223b565b610bb0565b34801561041c57600080fd5b5061026c61042b36600461235f565b610bdd565b600061047e7fbe27a319efc8734e89e26ba4bc95f5c788584163b959f03fa04e2d7ab4b9a1207fffffffff000000000000000000000000000000000000000000000000000000008416610c08565b90505b919050565b600061047e82610c35565b3330146104e9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180612c8b6027913960400191505060405180910390fd5b6105088173ffffffffffffffffffffffffffffffffffffffff16610c92565b61055d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526039815260200180612b716039913960400191505060405180910390fd5b61056681610c98565b6040805173ffffffffffffffffffffffffffffffffffffffff8316815290517f310ba5f1d2ed074b51e2eccd052a47ae9ab7c6b800d1fca3db3999d6a592ca039181900360200190a150565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b60006106266105ea85610c9c565b84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cfc92505050565b1561064e57507f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b600061047e82610430565b600061068a6105ea86866040518083838082843760405192018290039091209350610c9c92505050565b156106b257507f20c13b0b000000000000000000000000000000000000000000000000000000005b949350505050565b333014610712576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180612c8b6027913960400191505060405180910390fd5b80610768576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260378152602001806129986037913960400191505060405180910390fd5b6107927fea7157fa25e3aa17d0ae2d5280fa4e24d421c61842aa85e45194e1145aa72bf882610ef4565b6040805182815290517f307ed6bd941ee9fc80f369c94af5fa11e25bab5102a6140191756c5474a30bfa9181900360200190a150565b333014610820576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180612c8b6027913960400191505060405180910390fd5b600061082b82610430565b73ffffffffffffffffffffffffffffffffffffffff161415610898576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b8152602001806129cf602b913960400191505060405180910390fd5b6108a3816000610ef8565b50565b60006108d17fea7157fa25e3aa17d0ae2d5280fa4e24d421c61842aa85e45194e1145aa72bf8610f5b565b905090565b33301461092e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180612c8b6027913960400191505060405180910390fd5b600061095f826040516020016109449190612836565b60405160208183030381529060405280519060200120610c9c565b905061096b8183610f5f565b5050565b6109788261112e565b6000610990838560405160200161094492919061287d565b905061099c8183610cfc565b6109db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109d2906127d9565b60405180910390fd5b6109e58185610f5f565b50505050565b600061047e7f8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e83610c08565b6000333014610a71576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180612c8b6027913960400191505060405180910390fd5b81516020830134f06040805173ffffffffffffffffffffffffffffffffffffffff8316815290519192507fa506ad4e7f05eceba62a023c3219e5bd98a615f4fa87e2afb08a2da5cf62bf0c919081900360200190a1919050565b60006108d160006109eb565b333014610b2f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180612c8b6027913960400191505060405180910390fd5b6000610b3a83610430565b73ffffffffffffffffffffffffffffffffffffffff1614610ba6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180612ae3602c913960400191505060405180910390fd5b61096b8282610ef8565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b60408051602080820194909452808201929092528051808303820181526060909201905280519101205490565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f90042baf000000000000000000000000000000000000000000000000000000001415610c8957506001610481565b61047e826111d2565b3b151590565b3055565b604080517f19010000000000000000000000000000000000000000000000000000000000006020808301919091524660228301523060601b6042830152605680830194909452825180830390940184526076909101909152815191012090565b6000806000610d0a84611313565b909250905061ffff821660005b8551831015610ed15760008080610d2e8987611381565b975060ff91821694501691506001831415610d5657610d4d8987611402565b96509050610e7a565b82610d82576060610d678a8861147a565b97509050610d758b8261152b565b9150828501945050610e7a565b6002831415610e2957610d958987611402565b965090506000610da58a886118b5565b975061ffff1690506060610dba8b8984611926565b98509050610dc98c8483611a15565b610e1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526032815260200180612ab16032913960400191505060405180910390fd5b505092810192610e7a565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c81526020018061296c602c913960400191505060405180910390fd5b848282604051602001808481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019350505050604051602081830303815290604052805190602001209450505050610d17565b8361ffff168110158015610ee95750610ee982611c5d565b979650505050505050565b9055565b61096b7fbe27a319efc8734e89e26ba4bc95f5c788584163b959f03fa04e2d7ab4b9a1207fffffffff00000000000000000000000000000000000000000000000000000000841673ffffffffffffffffffffffffffffffffffffffff8416611c9a565b5490565b60005b8151811015611129576000828281518110610f7957fe5b602002602001015190506000606082604001515a1015610fc5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109d29061277c565b82511561105d57826060015173ffffffffffffffffffffffffffffffffffffffff168360400151600014610ffd578360400151610fff565b5a5b8460a0015160405161101191906126ae565b6000604051808303818686f4925050503d806000811461104d576040519150601f19603f3d011682016040523d82523d6000602084013e611052565b606091505b5090925090506110f2565b826060015173ffffffffffffffffffffffffffffffffffffffff1683608001518460400151600014611093578460400151611095565b5a5b908560a001516040516110a891906126ae565b600060405180830381858888f193505050503d80600081146110e6576040519150601f19603f3d011682016040523d82523d6000602084013e6110eb565b606091505b5090925090505b8115611113578560405161110691906126f6565b60405180910390a061111e565b61111e838783611cc8565b505050600101610f62565b505050565b60008061113a83611d18565b915091506000611149836109eb565b9050808214611184576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109d290612745565b600182016111928482611d31565b7f1f180c27086c7a39ea2a7b25239d1ab92348f07ca7bb59d1438fcf527568f88184826040516111c3929190612896565b60405180910390a15050505050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fec6aba5000000000000000000000000000000000000000000000000000000000148061126557507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b806112b157507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b806112fd57507fffffffff0000000000000000000000000000000000000000000000000000000082167fc0ee0b8a00000000000000000000000000000000000000000000000000000000145b1561130a57506001610481565b61047e82611d5c565b6020810151815160f09190911c9060029081111561137c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180612a1d6027913960400191505060405180910390fd5b915091565b8082016020015160f881901c9060f01c60ff16600283018381116113a157fe5b84518111156113fb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180612be66026913960400191505060405180910390fd5b9250925092565b8082016020015160601c6014820182811161141957fe5b8351811115611473576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806129fa6023913960400191505060405180910390fd5b9250929050565b6040805160428082526080820190925260609160009190602082018180368337019050509150828401602001805160208401526020810151604084015260228101516042840152506042830190508281116114d157fe5b8351811115611473576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180612b4e6023913960400191505060405180910390fd5b60008151604214611587576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603a815260200180612932603a913960400191505060405180910390fd5b60008260018451038151811061159957fe5b602001015160f81c60f81b60f81c60ff1690506000836040815181106115bb57fe5b016020015160f81c905060006115d18582611db9565b905060006115e0866020611db9565b90507f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a081111561165b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d8152602001806128f5603d913960400191505060405180910390fd5b8260ff16601b1415801561167357508260ff16601c14155b156116c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d815260200180612a44603d913960400191505060405180910390fd5b600184141561173d5760018784848460405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa15801561172c573d6000803e3d6000fd5b50505060206040510351945061183f565b60028414156117ee5760018760405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012084848460405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa15801561172c573d6000803e3d6000fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c815260200180612baa603c913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff85166118ab576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526030815260200180612a816030913960400191505060405180910390fd5b5050505092915050565b8082016020015160f01c600282018281116118cc57fe5b8351811115611473576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180612c2d6022913960400191505060405180910390fd5b606060008267ffffffffffffffff8111801561194157600080fd5b506040519080825280601f01601f19166020018201604052801561196c576020820181803683370190505b509150838501602001600060205b858110156119935790820151848201526020810161197a565b84860160200180519390920151908501525250828201838110156119b357fe5b8451811115611a0d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180612c0c6021913960400191505060405180910390fd5b935093915050565b60008082600184510381518110611a2857fe5b016020015160f81c90506001811480611a415750600281145b15611a85578373ffffffffffffffffffffffffffffffffffffffff16611a67868561152b565b73ffffffffffffffffffffffffffffffffffffffff16149150611c55565b6003811415611c045782517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81018452604080517f1626ba7e000000000000000000000000000000000000000000000000000000008152600481018881526024820192835286516044830152865173ffffffffffffffffffffffffffffffffffffffff891693631626ba7e938b938a9390929160640190602085019080838360005b83811015611b3f578181015183820152602001611b27565b50505050905090810190601f168015611b6c5780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b158015611b8a57600080fd5b505afa158015611b9e573d6000803e3d6000fd5b505050506040513d6020811015611bb457600080fd5b50519084527fffffffff00000000000000000000000000000000000000000000000000000000167f1626ba7e00000000000000000000000000000000000000000000000000000000149150611c55565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603f815260200180612b0f603f913960400191505060405180910390fd5b509392505050565b6000811580159061047e5750611c927fea7157fa25e3aa17d0ae2d5280fa4e24d421c61842aa85e45194e1145aa72bf8610f5b565b909114919050565b6040805160208082019590955280820193909352805180840382018152606090930190528151919092012055565b826020015115611cda57805160208201fd5b7f3dbd1590ea96dd3253a91f24e64e3a502e1225d602a5731357bc12643070ccd78282604051611d0b9291906126ff565b60405180910390a1505050565b606081901c916bffffffffffffffffffffffff90911690565b61096b7f8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e8383611c9a565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f025b22bc000000000000000000000000000000000000000000000000000000001415611db057506001610481565b61047e82611e21565b60008160200183511015611e18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c815260200180612c4f603c913960400191505060405180910390fd5b50016020015190565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f389901c7000000000000000000000000000000000000000000000000000000001415611e7557506001610481565b61047e8260007fffffffff0000000000000000000000000000000000000000000000000000000082167f783649a6000000000000000000000000000000000000000000000000000000001415611ecd57506001610481565b61047e8260007fffffffff0000000000000000000000000000000000000000000000000000000082161580611f4357507fffffffff0000000000000000000000000000000000000000000000000000000082167f36e7817500000000000000000000000000000000000000000000000000000000145b15611f5057506001610481565b7f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083161461047e565b803573ffffffffffffffffffffffffffffffffffffffff8116811461048157600080fd5b600082601f830112611fce578081fd5b8135602067ffffffffffffffff80831115611fe557fe5b611ff282838502016128a4565b83815282810190868401865b868110156120ce578135890160c0807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0838e0301121561203c57898afd5b604080518281018181108a8211171561205157fe5b825261205e848b0161211e565b815261206b82850161211e565b8a8201526060808501358383015260809250612088838601611f9a565b9082015260a084810135838301529284013592898411156120a7578c8dfd5b6120b58f8c8688010161219e565b9082015287525050509285019290850190600101611ffe565b509098975050505050505050565b60008083601f8401126120ed578182fd5b50813567ffffffffffffffff811115612104578182fd5b602083019150836020808302850101111561147357600080fd5b8035801515811461048157600080fd5b80357fffffffff000000000000000000000000000000000000000000000000000000008116811461048157600080fd5b60008083601f84011261216f578182fd5b50813567ffffffffffffffff811115612186578182fd5b60208301915083602082850101111561147357600080fd5b600082601f8301126121ae578081fd5b813567ffffffffffffffff8111156121c257fe5b6121f360207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016128a4565b818152846020838601011115612207578283fd5b816020850160208301379081016020019190915292915050565b600060208284031215612232578081fd5b61064e82611f9a565b60008060008060008060008060a0898b031215612256578384fd5b61225f89611f9a565b975061226d60208a01611f9a565b9650604089013567ffffffffffffffff80821115612289578586fd5b6122958c838d016120dc565b909850965060608b01359150808211156122ad578586fd5b6122b98c838d016120dc565b909650945060808b01359150808211156122d1578384fd5b506122de8b828c0161215e565b999c989b5096995094979396929594505050565b600080600080600060808688031215612309578081fd5b61231286611f9a565b945061232060208701611f9a565b935060408601359250606086013567ffffffffffffffff811115612342578182fd5b61234e8882890161215e565b969995985093965092949392505050565b60008060008060008060a08789031215612377578182fd5b61238087611f9a565b955061238e60208801611f9a565b94506040870135935060608701359250608087013567ffffffffffffffff8111156123b7578283fd5b6123c389828a0161215e565b979a9699509497509295939492505050565b6000602082840312156123e6578081fd5b813567ffffffffffffffff8111156123fc578182fd5b6106b284828501611fbe565b60008060006060848603121561241c578283fd5b833567ffffffffffffffff80821115612433578485fd5b61243f87838801611fbe565b945060208601359350604086013591508082111561245b578283fd5b506124688682870161219e565b9150509250925092565b600060208284031215612483578081fd5b5035919050565b60008060006040848603121561249e578283fd5b83359250602084013567ffffffffffffffff8111156124bb578283fd5b6124c78682870161215e565b9497909650939450505050565b6000602082840312156124e5578081fd5b61064e8261212e565b60008060408385031215612500578182fd5b6125098361212e565b915061251760208401611f9a565b90509250929050565b60008060008060408587031215612535578182fd5b843567ffffffffffffffff8082111561254c578384fd5b6125588883890161215e565b90965094506020870135915080821115612570578384fd5b5061257d8782880161215e565b95989497509550505050565b60006020828403121561259a578081fd5b813567ffffffffffffffff8111156125b0578182fd5b6106b28482850161219e565b6000815180845260208085019450848183028601828601855b858110156126575783830389528151805115158452858101511515868501526040808201519085015260608082015173ffffffffffffffffffffffffffffffffffffffff16908501526080808201519085015260a09081015160c09185018290529061264381860183612664565b9a87019a94505050908401906001016125d5565b5090979650505050505050565b6000815180845261267c8160208601602086016128c8565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600082516126c08184602087016128c8565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b901515815260200190565b90815260200190565b6000838252604060208301526106b26040830184612664565b7fffffffff0000000000000000000000000000000000000000000000000000000091909116815260200190565b6020808252601f908201527f4d61696e4d6f64756c65235f617574683a20494e56414c49445f4e4f4e434500604082015260600190565b60208082526024908201527f4d6f64756c6543616c6c73235f657865637574653a204e4f545f454e4f55474860408201527f5f47415300000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526026908201527f4d6f64756c6543616c6c7323657865637574653a20494e56414c49445f53494760408201527f4e41545552450000000000000000000000000000000000000000000000000000606082015260800190565b600060408252600560408301527f73656c663a00000000000000000000000000000000000000000000000000000060608301526080602083015261064e60808301846125bc565b6000838252604060208301526106b260408301846125bc565b918252602082015260400190565b60405181810167ffffffffffffffff811182821017156128c057fe5b604052919050565b60005b838110156128e35781810151838201526020016128cb565b838111156109e5575050600091015256fe5369676e617475726556616c696461746f72237265636f7665725369676e65723a20696e76616c6964207369676e6174757265202773272076616c75655369676e617475726556616c696461746f72237265636f7665725369676e65723a20696e76616c6964207369676e6174757265206c656e6774684d6f64756c6541757468235f7369676e617475726556616c69646174696f6e20494e56414c49445f464c41474d6f64756c654175746855706772616461626c6523757064617465496d6167654861736820494e56414c49445f494d4147455f484153484d6f64756c65486f6f6b732372656d6f7665486f6f6b3a20484f4f4b5f4e4f545f524547495354455245444c696242797465732372656164416464726573733a204f55545f4f465f424f554e44534c696242797465732372656164466972737455696e7431363a204f55545f4f465f424f554e44535369676e617475726556616c696461746f72237265636f7665725369676e65723a20696e76616c6964207369676e6174757265202776272076616c75655369676e617475726556616c696461746f72237265636f7665725369676e65723a20494e56414c49445f5349474e45524d6f64756c6541757468235f7369676e617475726556616c69646174696f6e3a20494e56414c49445f5349474e41545552454d6f64756c65486f6f6b7323616464486f6f6b3a20484f4f4b5f414c52454144595f524547495354455245445369676e617475726556616c696461746f7223697356616c69645369676e61747572653a20554e535550504f525445445f5349474e41545552455f545950454c696242797465732372656164427974657336363a204f55545f4f465f424f554e44534d6f64756c6555706461746523757064617465496d706c656d656e746174696f6e3a20494e56414c49445f494d504c454d454e544154494f4e5369676e617475726556616c696461746f72237265636f7665725369676e65723a20554e535550504f525445445f5349474e41545552455f545950454c69624279746573237265616455696e743855696e74383a204f55545f4f465f424f554e44534c69624279746573237265616442797465733a204f55545f4f465f424f554e44534c69624279746573237265616455696e7431363a204f55545f4f465f424f554e44534c696242797465732372656164427974657333323a20475245415445525f4f525f455155414c5f544f5f33325f4c454e4754485f52455155495245444d6f64756c6553656c6641757468236f6e6c7953656c663a204e4f545f415554484f52495a4544a2646970667358221220aebb8d931ef86555b6441c416b208bb9fe8fe0974c5733ebbccce548296c37ce64736f6c63430007060033', + linkReferences: {}, + deployedLinkReferences: {} +} diff --git a/packages/tests/src/builds/v1/artifacts/MultiCallUtils.ts b/packages/tests/src/builds/v1/artifacts/MultiCallUtils.ts new file mode 100644 index 0000000000..6d9f1ced30 --- /dev/null +++ b/packages/tests/src/builds/v1/artifacts/MultiCallUtils.ts @@ -0,0 +1,281 @@ +export const multiCallUtils = { + _format: 'hh-sol-artifact-1', + contractName: 'MultiCallUtils', + sourceName: 'contracts/modules/utils/MultiCallUtils.sol', + abi: [ + { + inputs: [ + { + internalType: 'address', + name: '_addr', + type: 'address' + } + ], + name: 'callBalanceOf', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'callBlockNumber', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_i', + type: 'uint256' + } + ], + name: 'callBlockhash', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'callChainId', + outputs: [ + { + internalType: 'uint256', + name: 'id', + type: 'uint256' + } + ], + stateMutability: 'pure', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '_addr', + type: 'address' + } + ], + name: 'callCode', + outputs: [ + { + internalType: 'bytes', + name: 'code', + type: 'bytes' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '_addr', + type: 'address' + } + ], + name: 'callCodeHash', + outputs: [ + { + internalType: 'bytes32', + name: 'codeHash', + type: 'bytes32' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '_addr', + type: 'address' + } + ], + name: 'callCodeSize', + outputs: [ + { + internalType: 'uint256', + name: 'size', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'callCoinbase', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'callDifficulty', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'callGasLeft', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'callGasLimit', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'callGasPrice', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'callOrigin', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'callTimestamp', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + components: [ + { + internalType: 'bool', + name: 'delegateCall', + type: 'bool' + }, + { + internalType: 'bool', + name: 'revertOnError', + type: 'bool' + }, + { + internalType: 'uint256', + name: 'gasLimit', + type: 'uint256' + }, + { + internalType: 'address', + name: 'target', + type: 'address' + }, + { + internalType: 'uint256', + name: 'value', + type: 'uint256' + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes' + } + ], + internalType: 'struct IModuleCalls.Transaction[]', + name: '_txs', + type: 'tuple[]' + } + ], + name: 'multiCall', + outputs: [ + { + internalType: 'bool[]', + name: '_successes', + type: 'bool[]' + }, + { + internalType: 'bytes[]', + name: '_results', + type: 'bytes[]' + } + ], + stateMutability: 'payable', + type: 'function' + } + ], + bytecode: + '0x608060405234801561001057600080fd5b50610aac806100206000396000f3fe6080604052600436106100e85760003560e01c8063c272d5c31161008a578063d5b5337f11610059578063d5b5337f14610230578063e90f13e71461021b578063f209883a14610250578063ffd7d74114610265576100e8565b8063c272d5c3146101b9578063c39f2d5c146101ce578063c66764e1146101ee578063d1db39071461021b576100e8565b8063543196eb116100c6578063543196eb1461014d578063984395bc1461016d57806398f9fbc41461018f578063aeea5fb5146101a4576100e8565b80630fdecfac146100ed57806343d9c9351461011857806348acd29f1461012d575b600080fd5b3480156100f957600080fd5b50610102610286565b60405161010f91906108ef565b60405180910390f35b34801561012457600080fd5b5061010261028a565b34801561013957600080fd5b50610102610148366004610649565b610292565b34801561015957600080fd5b50610102610168366004610649565b6102b0565b34801561017957600080fd5b506101826102b4565b60405161010f9190610828565b34801561019b57600080fd5b506101826102b8565b3480156101b057600080fd5b506101026102bc565b3480156101c557600080fd5b506101026102c0565b3480156101da57600080fd5b506101026101e9366004610649565b6102c4565b3480156101fa57600080fd5b5061020e610209366004610649565b6102c8565b60405161010f91906108f8565b34801561022757600080fd5b5061010261030d565b34801561023c57600080fd5b5061010261024b3660046107aa565b610311565b34801561025c57600080fd5b50610102610315565b61027861027336600461066a565b610319565b60405161010f929190610849565b4690565b60005a905090565b73ffffffffffffffffffffffffffffffffffffffff8116315b919050565b3f90565b3290565b4190565b4490565b3a90565b3b90565b60408051603f833b9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092528181529080600060208401853c50919050565b4590565b4090565b4290565b606080825167ffffffffffffffff8111801561033457600080fd5b5060405190808252806020026020018201604052801561035e578160200160208202803683370190505b509150825167ffffffffffffffff8111801561037957600080fd5b506040519080825280602002602001820160405280156103ad57816020015b60608152602001906001900390816103985790505b50905060005b835181101561058c5760008482815181106103ca57fe5b60200260200101519050806000015115610419576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610410906109c5565b60405180910390fd5b80604001515a1015610457576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041090610968565b806060015173ffffffffffffffffffffffffffffffffffffffff168160800151826040015160001461048d57826040015161048f565b5a5b908360a001516040516104a2919061080c565b600060405180830381858888f193505050503d80600081146104e0576040519150601f19603f3d011682016040523d82523d6000602084013e6104e5565b606091505b508584815181106104f257fe5b6020026020010185858151811061050557fe5b602002602001018290528215151515815250505083828151811061052557fe5b60200260200101518061054d575084828151811061053f57fe5b602002602001015160200151155b610583576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104109061090b565b506001016103b3565b50915091565b803573ffffffffffffffffffffffffffffffffffffffff811681146102ab57600080fd5b803580151581146102ab57600080fd5b600082601f8301126105d6578081fd5b813567ffffffffffffffff8111156105ea57fe5b61061b60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610a22565b81815284602083860101111561062f578283fd5b816020850160208301379081016020019190915292915050565b60006020828403121561065a578081fd5b61066382610592565b9392505050565b6000602080838503121561067c578182fd5b823567ffffffffffffffff80821115610693578384fd5b818501915085601f8301126106a6578384fd5b8135818111156106b257fe5b6106bf8485830201610a22565b81815284810190848601875b8481101561079b578135870160c0807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0838f03011215610709578a8bfd5b604080518281018181108b8211171561071e57fe5b825261072b848d016105b6565b81526107388285016105b6565b8c8201526060808501358383015260809250610755838601610592565b9082015260a084013582820152918301359189831115610773578c8dfd5b6107818f8d858701016105c6565b60a0820152875250505092870192908701906001016106cb565b50909998505050505050505050565b6000602082840312156107bb578081fd5b5035919050565b600081518084526107da816020860160208601610a46565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000825161081e818460208701610a46565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b604080825283519082018190526000906020906060840190828701845b82811015610884578151151584529284019290840190600101610866565b5050508381038285015284518082528282019080840283018401878501865b8381101561079b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08684030185526108dd8383516107c2565b948701949250908601906001016108a3565b90815260200190565b60006020825261066360208301846107c2565b60208082526027908201527f4d756c746943616c6c5574696c73236d756c746943616c6c3a2043414c4c5f5260408201527f4556455254454400000000000000000000000000000000000000000000000000606082015260800190565b60208082526028908201527f4d756c746943616c6c5574696c73236d756c746943616c6c3a204e4f545f454e60408201527f4f5547485f474153000000000000000000000000000000000000000000000000606082015260800190565b60208082526032908201527f4d756c746943616c6c5574696c73236d756c746943616c6c3a2064656c65676160408201527f746543616c6c206e6f7420616c6c6f7765640000000000000000000000000000606082015260800190565b60405181810167ffffffffffffffff81118282101715610a3e57fe5b604052919050565b60005b83811015610a61578181015183820152602001610a49565b83811115610a70576000848401525b5050505056fea26469706673582212209bcbc4408d83c4567da8d51b96a29d3d2cf56395e5ac84eee40917a48945daaf64736f6c63430007060033', + deployedBytecode: + '0x6080604052600436106100e85760003560e01c8063c272d5c31161008a578063d5b5337f11610059578063d5b5337f14610230578063e90f13e71461021b578063f209883a14610250578063ffd7d74114610265576100e8565b8063c272d5c3146101b9578063c39f2d5c146101ce578063c66764e1146101ee578063d1db39071461021b576100e8565b8063543196eb116100c6578063543196eb1461014d578063984395bc1461016d57806398f9fbc41461018f578063aeea5fb5146101a4576100e8565b80630fdecfac146100ed57806343d9c9351461011857806348acd29f1461012d575b600080fd5b3480156100f957600080fd5b50610102610286565b60405161010f91906108ef565b60405180910390f35b34801561012457600080fd5b5061010261028a565b34801561013957600080fd5b50610102610148366004610649565b610292565b34801561015957600080fd5b50610102610168366004610649565b6102b0565b34801561017957600080fd5b506101826102b4565b60405161010f9190610828565b34801561019b57600080fd5b506101826102b8565b3480156101b057600080fd5b506101026102bc565b3480156101c557600080fd5b506101026102c0565b3480156101da57600080fd5b506101026101e9366004610649565b6102c4565b3480156101fa57600080fd5b5061020e610209366004610649565b6102c8565b60405161010f91906108f8565b34801561022757600080fd5b5061010261030d565b34801561023c57600080fd5b5061010261024b3660046107aa565b610311565b34801561025c57600080fd5b50610102610315565b61027861027336600461066a565b610319565b60405161010f929190610849565b4690565b60005a905090565b73ffffffffffffffffffffffffffffffffffffffff8116315b919050565b3f90565b3290565b4190565b4490565b3a90565b3b90565b60408051603f833b9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092528181529080600060208401853c50919050565b4590565b4090565b4290565b606080825167ffffffffffffffff8111801561033457600080fd5b5060405190808252806020026020018201604052801561035e578160200160208202803683370190505b509150825167ffffffffffffffff8111801561037957600080fd5b506040519080825280602002602001820160405280156103ad57816020015b60608152602001906001900390816103985790505b50905060005b835181101561058c5760008482815181106103ca57fe5b60200260200101519050806000015115610419576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610410906109c5565b60405180910390fd5b80604001515a1015610457576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161041090610968565b806060015173ffffffffffffffffffffffffffffffffffffffff168160800151826040015160001461048d57826040015161048f565b5a5b908360a001516040516104a2919061080c565b600060405180830381858888f193505050503d80600081146104e0576040519150601f19603f3d011682016040523d82523d6000602084013e6104e5565b606091505b508584815181106104f257fe5b6020026020010185858151811061050557fe5b602002602001018290528215151515815250505083828151811061052557fe5b60200260200101518061054d575084828151811061053f57fe5b602002602001015160200151155b610583576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104109061090b565b506001016103b3565b50915091565b803573ffffffffffffffffffffffffffffffffffffffff811681146102ab57600080fd5b803580151581146102ab57600080fd5b600082601f8301126105d6578081fd5b813567ffffffffffffffff8111156105ea57fe5b61061b60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610a22565b81815284602083860101111561062f578283fd5b816020850160208301379081016020019190915292915050565b60006020828403121561065a578081fd5b61066382610592565b9392505050565b6000602080838503121561067c578182fd5b823567ffffffffffffffff80821115610693578384fd5b818501915085601f8301126106a6578384fd5b8135818111156106b257fe5b6106bf8485830201610a22565b81815284810190848601875b8481101561079b578135870160c0807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0838f03011215610709578a8bfd5b604080518281018181108b8211171561071e57fe5b825261072b848d016105b6565b81526107388285016105b6565b8c8201526060808501358383015260809250610755838601610592565b9082015260a084013582820152918301359189831115610773578c8dfd5b6107818f8d858701016105c6565b60a0820152875250505092870192908701906001016106cb565b50909998505050505050505050565b6000602082840312156107bb578081fd5b5035919050565b600081518084526107da816020860160208601610a46565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000825161081e818460208701610a46565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b604080825283519082018190526000906020906060840190828701845b82811015610884578151151584529284019290840190600101610866565b5050508381038285015284518082528282019080840283018401878501865b8381101561079b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08684030185526108dd8383516107c2565b948701949250908601906001016108a3565b90815260200190565b60006020825261066360208301846107c2565b60208082526027908201527f4d756c746943616c6c5574696c73236d756c746943616c6c3a2043414c4c5f5260408201527f4556455254454400000000000000000000000000000000000000000000000000606082015260800190565b60208082526028908201527f4d756c746943616c6c5574696c73236d756c746943616c6c3a204e4f545f454e60408201527f4f5547485f474153000000000000000000000000000000000000000000000000606082015260800190565b60208082526032908201527f4d756c746943616c6c5574696c73236d756c746943616c6c3a2064656c65676160408201527f746543616c6c206e6f7420616c6c6f7765640000000000000000000000000000606082015260800190565b60405181810167ffffffffffffffff81118282101715610a3e57fe5b604052919050565b60005b83811015610a61578181015183820152602001610a49565b83811115610a70576000848401525b5050505056fea26469706673582212209bcbc4408d83c4567da8d51b96a29d3d2cf56395e5ac84eee40917a48945daaf64736f6c63430007060033', + linkReferences: {}, + deployedLinkReferences: {} +} diff --git a/packages/tests/src/builds/v1/artifacts/SequenceUtils.ts b/packages/tests/src/builds/v1/artifacts/SequenceUtils.ts new file mode 100644 index 0000000000..dfeb067558 --- /dev/null +++ b/packages/tests/src/builds/v1/artifacts/SequenceUtils.ts @@ -0,0 +1,527 @@ +export const sequenceUtils = { + _format: 'hh-sol-artifact-1', + contractName: 'SequenceUtils', + sourceName: 'contracts/modules/utils/SequenceUtils.sol', + abi: [ + { + inputs: [ + { + internalType: 'address', + name: '_factory', + type: 'address' + }, + { + internalType: 'address', + name: '_mainModule', + type: 'address' + } + ], + stateMutability: 'nonpayable', + type: 'constructor' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: '_wallet', + type: 'address' + }, + { + indexed: true, + internalType: 'bytes32', + name: '_imageHash', + type: 'bytes32' + }, + { + indexed: false, + internalType: 'uint256', + name: '_threshold', + type: 'uint256' + }, + { + indexed: false, + internalType: 'bytes', + name: '_signers', + type: 'bytes' + } + ], + name: 'RequiredConfig', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: '_wallet', + type: 'address' + }, + { + indexed: true, + internalType: 'address', + name: '_signer', + type: 'address' + } + ], + name: 'RequiredSigner', + type: 'event' + }, + { + inputs: [ + { + internalType: 'address', + name: '_addr', + type: 'address' + } + ], + name: 'callBalanceOf', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'callBlockNumber', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_i', + type: 'uint256' + } + ], + name: 'callBlockhash', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'callChainId', + outputs: [ + { + internalType: 'uint256', + name: 'id', + type: 'uint256' + } + ], + stateMutability: 'pure', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '_addr', + type: 'address' + } + ], + name: 'callCode', + outputs: [ + { + internalType: 'bytes', + name: 'code', + type: 'bytes' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '_addr', + type: 'address' + } + ], + name: 'callCodeHash', + outputs: [ + { + internalType: 'bytes32', + name: 'codeHash', + type: 'bytes32' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '_addr', + type: 'address' + } + ], + name: 'callCodeSize', + outputs: [ + { + internalType: 'uint256', + name: 'size', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'callCoinbase', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'callDifficulty', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'callGasLeft', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'callGasLimit', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'callGasPrice', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'callOrigin', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'callTimestamp', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + } + ], + name: 'knownImageHashes', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + name: 'lastImageHashUpdate', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + } + ], + name: 'lastSignerUpdate', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + } + ], + name: 'lastWalletUpdate', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + components: [ + { + internalType: 'bool', + name: 'delegateCall', + type: 'bool' + }, + { + internalType: 'bool', + name: 'revertOnError', + type: 'bool' + }, + { + internalType: 'uint256', + name: 'gasLimit', + type: 'uint256' + }, + { + internalType: 'address', + name: 'target', + type: 'address' + }, + { + internalType: 'uint256', + name: 'value', + type: 'uint256' + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes' + } + ], + internalType: 'struct IModuleCalls.Transaction[]', + name: '_txs', + type: 'tuple[]' + } + ], + name: 'multiCall', + outputs: [ + { + internalType: 'bool[]', + name: '_successes', + type: 'bool[]' + }, + { + internalType: 'bytes[]', + name: '_results', + type: 'bytes[]' + } + ], + stateMutability: 'payable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '_wallet', + type: 'address' + }, + { + internalType: 'uint256', + name: '_threshold', + type: 'uint256' + }, + { + components: [ + { + internalType: 'uint256', + name: 'weight', + type: 'uint256' + }, + { + internalType: 'address', + name: 'signer', + type: 'address' + } + ], + internalType: 'struct RequireUtils.Member[]', + name: '_members', + type: 'tuple[]' + }, + { + internalType: 'bool', + name: '_index', + type: 'bool' + } + ], + name: 'publishConfig', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '_wallet', + type: 'address' + }, + { + internalType: 'bytes32', + name: '_hash', + type: 'bytes32' + }, + { + internalType: 'uint256', + name: '_sizeMembers', + type: 'uint256' + }, + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + }, + { + internalType: 'bool', + name: '_index', + type: 'bool' + } + ], + name: 'publishInitialSigners', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '_wallet', + type: 'address' + }, + { + internalType: 'uint256', + name: '_nonce', + type: 'uint256' + } + ], + name: 'requireMinNonce', + outputs: [], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_expiration', + type: 'uint256' + } + ], + name: 'requireNonExpired', + outputs: [], + stateMutability: 'view', + type: 'function' + } + ], + bytecode: + '0x60c06040523480156200001157600080fd5b5060405162002ad638038062002ad68339810160408190526200003491620000cd565b8181816001600160a01b031660a0816001600160a01b031660601b8152505060405180606001604052806028815260200162002aae60289139816001600160a01b03166040516020016200008a92919062000104565b60408051601f198184030181529190528051602090910120608052506200014692505050565b80516001600160a01b0381168114620000c857600080fd5b919050565b60008060408385031215620000e0578182fd5b620000eb83620000b0565b9150620000fb60208401620000b0565b90509250929050565b60008351815b818110156200012657602081870181015185830152016200010a565b81811115620001355782828501525b509190910191825250602001919050565b60805160a05160601c61293762000177600039806106515280610b1b5250806106755280610b3f52506129376000f3fe6080604052600436106101805760003560e01c806398f9fbc4116100d6578063d1db39071161007f578063e90f13e711610059578063e90f13e714610395578063f209883a146103ea578063ffd7d741146103ff57610180565b8063d1db390714610395578063d5b5337f146103aa578063e717aba9146103ca57610180565b8063c272d5c3116100b0578063c272d5c314610333578063c39f2d5c14610348578063c66764e11461036857610180565b806398f9fbc4146102e9578063aeea5fb5146102fe578063b472f0a21461031357610180565b806348acd29f116101385780637ae99638116101125780637ae99638146102875780637f29d538146102a7578063984395bc146102c757610180565b806348acd29f14610227578063543196eb146102475780637082503b1461026757610180565b80631cd05dc4116101695780631cd05dc4146101d057806343d9c935146101f057806344d466c21461020557610180565b80630fdecfac146101855780631551f0ab146101b0575b600080fd5b34801561019157600080fd5b5061019a610420565b6040516101a79190612190565b60405180910390f35b3480156101bc57600080fd5b5061019a6101cb366004611e76565b610424565b3480156101dc57600080fd5b5061019a6101eb366004611bea565b610436565b3480156101fc57600080fd5b5061019a610448565b34801561021157600080fd5b50610225610220366004611ca4565b610450565b005b34801561023357600080fd5b5061019a610242366004611bea565b61080a565b34801561025357600080fd5b5061019a610262366004611bea565b610828565b34801561027357600080fd5b50610225610282366004611c0b565b61082c565b34801561029357600080fd5b5061019a6102a2366004611bea565b610cb0565b3480156102b357600080fd5b506102256102c2366004611e76565b610cc2565b3480156102d357600080fd5b506102dc610cfe565b6040516101a79190612000565b3480156102f557600080fd5b506102dc610d02565b34801561030a57600080fd5b5061019a610d06565b34801561031f57600080fd5b5061022561032e366004611c7b565b610d0a565b34801561033f57600080fd5b5061019a610de8565b34801561035457600080fd5b5061019a610363366004611bea565b610dec565b34801561037457600080fd5b50610388610383366004611bea565b610df0565b6040516101a791906121c5565b3480156103a157600080fd5b5061019a610e35565b3480156103b657600080fd5b5061019a6103c5366004611e76565b610e39565b3480156103d657600080fd5b5061019a6103e5366004611bea565b610e3d565b3480156103f657600080fd5b5061019a610e4f565b61041261040d366004611d34565b610e53565b6040516101a7929190612021565b4690565b60036020526000908152604090205481565b60006020819052908152604090205481565b60005a905090565b8360005b838110156104e9578185858381811061046957fe5b9050604002016000013586868481811061047f57fe5b90506040020160200160208101906104979190611bea565b6040516020016104a993929190612199565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209150600101610454565b506000808773ffffffffffffffffffffffffffffffffffffffff166351605d8060e01b60405160200161051c9190611f54565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905261055491611f81565b6000604051808303816000865af19150503d8060008114610591576040519150601f19603f3d011682016040523d82523d6000602084013e610596565b606091505b50915091508180156105a9575080516020145b1561060e576000818060200190518101906105c49190611e8e565b9050838114610608576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ff90612543565b60405180910390fd5b50610732565b60405173ffffffffffffffffffffffffffffffffffffffff89169061069d907fff00000000000000000000000000000000000000000000000000000000000000907f00000000000000000000000000000000000000000000000000000000000000009087907f000000000000000000000000000000000000000000000000000000000000000090602001611ef0565b6040516020818303038152906040528051906020012060001c73ffffffffffffffffffffffffffffffffffffffff1614610703576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ff906125a0565b83156107325773ffffffffffffffffffffffffffffffffffffffff881660009081526002602052604090208390555b828873ffffffffffffffffffffffffffffffffffffffff167fb502b7446ca079086188acf3abef47c2f464f2ee9a72fcdf05ffcb74dcc17cee89898960405160200161077f9291906120c7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290526107b89291612623565b60405180910390a383156108005773ffffffffffffffffffffffffffffffffffffffff8816600090815260016020908152604080832043908190558684526003909252909120555b5050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116315b919050565b3f90565b600080610838846110c3565b9150915060008046905080898960405160200161085793929190611f9d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052805160209091012091505061ffff831660008767ffffffffffffffff811180156108ae57600080fd5b506040519080825280602002602001820160405280156108e857816020015b6108d5611b1c565b8152602001906001900390816108cd5790505b50905060005b8751851015610a9f57600080806109058b89611131565b995060ff9182169450169150600183141561092d576109248b896111b2565b98509050610a20565b8261095f57606061093e8c8a61122a565b9950905061094c88826112db565b91506109598f838d611665565b50610a20565b60028314156109ee576109728b896111b2565b9850905060006109828c8a6116f3565b995061ffff16905060606109978d8b84611764565b9a5090506109a6898483611853565b6109dc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ff9061242c565b50506109e98e828c611665565b610a20565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ff906121d8565b60405180604001604052808381526020018273ffffffffffffffffffffffffffffffffffffffff16815250858581518110610a5757fe5b60200260200101819052508380600101945050858282604051602001610a7f93929190612199565b6040516020818303038152906040528051906020012095505050506108ee565b888114610ad8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ff906124e6565b60405173ffffffffffffffffffffffffffffffffffffffff8c1690610b67907fff00000000000000000000000000000000000000000000000000000000000000907f00000000000000000000000000000000000000000000000000000000000000009087907f000000000000000000000000000000000000000000000000000000000000000090602001611ef0565b6040516020818303038152906040528051906020012060001c73ffffffffffffffffffffffffffffffffffffffff1614610bcd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ff906123a9565b828b73ffffffffffffffffffffffffffffffffffffffff167fb502b7446ca079086188acf3abef47c2f464f2ee9a72fcdf05ffcb74dcc17cee8885604051602001610c18919061212b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052610c5192916125fe565b60405180910390a38615610ca35773ffffffffffffffffffffffffffffffffffffffff8b1660008181526001602090815260408083204390819055878452600383528184205592825260029052208390555b5050505050505050505050565b60026020526000908152604090205481565b804210610cfb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ff9061234c565b50565b3290565b4190565b4490565b600080610d1683611a9b565b9150915060008473ffffffffffffffffffffffffffffffffffffffff16638c3f5563846040518263ffffffff1660e01b8152600401610d559190612190565b60206040518083038186803b158015610d6d57600080fd5b505afa158015610d81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610da59190611e8e565b905081811015610de1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ff906122ef565b5050505050565b3a90565b3b90565b60408051603f833b9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092528181529080600060208401853c50919050565b4590565b4090565b60016020526000908152604090205481565b4290565b606080825167ffffffffffffffff81118015610e6e57600080fd5b50604051908082528060200260200182016040528015610e98578160200160208202803683370190505b509150825167ffffffffffffffff81118015610eb357600080fd5b50604051908082528060200260200182016040528015610ee757816020015b6060815260200190600190039081610ed25790505b50905060005b83518110156110bd576000848281518110610f0457fe5b60200260200101519050806000015115610f4a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ff90612489565b80604001515a1015610f88576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ff90612292565b806060015173ffffffffffffffffffffffffffffffffffffffff1681608001518260400151600014610fbe578260400151610fc0565b5a5b908360a00151604051610fd39190611f81565b600060405180830381858888f193505050503d8060008114611011576040519150601f19603f3d011682016040523d82523d6000602084013e611016565b606091505b5085848151811061102357fe5b6020026020010185858151811061103657fe5b602002602001018290528215151515815250505083828151811061105657fe5b60200260200101518061107e575084828151811061107057fe5b602002602001015160200151155b6110b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ff90612235565b50600101610eed565b50915091565b6020810151815160f09190911c9060029081111561112c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061272b6027913960400191505060405180910390fd5b915091565b8082016020015160f881901c9060f01c60ff166002830183811161115157fe5b84518111156111ab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602681526020018061285d6026913960400191505060405180910390fd5b9250925092565b8082016020015160601c601482018281116111c957fe5b8351811115611223576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806127086023913960400191505060405180910390fd5b9250929050565b60408051604280825260808201909252606091600091906020820181803683370190505091508284016020018051602084015260208101516040840152602281015160428401525060428301905082811161128157fe5b8351811115611223576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806127fe6023913960400191505060405180910390fd5b60008151604214611337576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603a8152602001806126ce603a913960400191505060405180910390fd5b60008260018451038151811061134957fe5b602001015160f81c60f81b60f81c60ff16905060008360408151811061136b57fe5b016020015160f81c905060006113818582611ab4565b90506000611390866020611ab4565b90507f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a081111561140b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d815260200180612691603d913960400191505060405180910390fd5b8260ff16601b1415801561142357508260ff16601c14155b15611479576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d815260200180612752603d913960400191505060405180910390fd5b60018414156114ed5760018784848460405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156114dc573d6000803e3d6000fd5b5050506020604051035194506115ef565b600284141561159e5760018760405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012084848460405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156114dc573d6000803e3d6000fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c815260200180612821603c913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff851661165b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603081526020018061278f6030913960400191505060405180910390fd5b5050505092915050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f600ba597427f042bcd559a0d06fa1732cc104d6dd43cbe8845b5a0e804b2b39f60405160405180910390a380156116ee5773ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090204390555b505050565b8082016020015160f01c6002820182811161170a57fe5b8351811115611223576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806128a46022913960400191505060405180910390fd5b606060008267ffffffffffffffff8111801561177f57600080fd5b506040519080825280601f01601f1916602001820160405280156117aa576020820181803683370190505b509150838501602001600060205b858110156117d1579082015184820152602081016117b8565b84860160200180519390920151908501525250828201838110156117f157fe5b845181111561184b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806128836021913960400191505060405180910390fd5b935093915050565b6000808260018451038151811061186657fe5b016020015160f81c9050600181148061187f5750600281145b156118c3578373ffffffffffffffffffffffffffffffffffffffff166118a586856112db565b73ffffffffffffffffffffffffffffffffffffffff16149150611a93565b6003811415611a425782517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81018452604080517f1626ba7e000000000000000000000000000000000000000000000000000000008152600481018881526024820192835286516044830152865173ffffffffffffffffffffffffffffffffffffffff891693631626ba7e938b938a9390929160640190602085019080838360005b8381101561197d578181015183820152602001611965565b50505050905090810190601f1680156119aa5780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b1580156119c857600080fd5b505afa1580156119dc573d6000803e3d6000fd5b505050506040513d60208110156119f257600080fd5b50519084527fffffffff00000000000000000000000000000000000000000000000000000000167f1626ba7e00000000000000000000000000000000000000000000000000000000149150611a93565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603f8152602001806127bf603f913960400191505060405180910390fd5b509392505050565b606081901c916bffffffffffffffffffffffff90911690565b60008160200183511015611b13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c8152602001806128c6603c913960400191505060405180910390fd5b50016020015190565b604080518082019091526000808252602082015290565b803573ffffffffffffffffffffffffffffffffffffffff8116811461082357600080fd5b8035801515811461082357600080fd5b600082601f830112611b77578081fd5b813567ffffffffffffffff811115611b8b57fe5b611bbc60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161263c565b818152846020838601011115611bd0578283fd5b816020850160208301379081016020019190915292915050565b600060208284031215611bfb578081fd5b611c0482611b33565b9392505050565b600080600080600060a08688031215611c22578081fd5b611c2b86611b33565b94506020860135935060408601359250606086013567ffffffffffffffff811115611c54578182fd5b611c6088828901611b67565b925050611c6f60808701611b57565b90509295509295909350565b60008060408385031215611c8d578182fd5b611c9683611b33565b946020939093013593505050565b600080600080600060808688031215611cbb578081fd5b611cc486611b33565b945060208601359350604086013567ffffffffffffffff80821115611ce7578283fd5b818801915088601f830112611cfa578283fd5b813581811115611d08578384fd5b896020604083028501011115611d1c578384fd5b602083019550809450505050611c6f60608701611b57565b60006020808385031215611d46578182fd5b823567ffffffffffffffff80821115611d5d578384fd5b818501915085601f830112611d70578384fd5b813581811115611d7c57fe5b611d89848583020161263c565b81815284810190848601875b84811015611e67578135870160c0807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0838f03011215611dd3578a8bfd5b604080518281018181108b82111715611de857fe5b8252611df5848d01611b57565b8152611e02828501611b57565b8c82015260608085013583830152611e1c60808601611b33565b9082015260a08481013560808301529284013592915089831115611e3e578c8dfd5b611e4c8f8d85870101611b67565b91810191909152865250509287019290870190600101611d95565b50909998505050505050505050565b600060208284031215611e87578081fd5b5035919050565b600060208284031215611e9f578081fd5b5051919050565b60008151808452611ebe816020860160208601612660565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b7fff0000000000000000000000000000000000000000000000000000000000000094909416845260609290921b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660018401526015830152603582015260550190565b7fffffffff0000000000000000000000000000000000000000000000000000000091909116815260040190565b60008251611f93818460208701612660565b9190910192915050565b7f19010000000000000000000000000000000000000000000000000000000000008152600281019390935260609190911b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166022830152603682015260560190565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b604080825283519082018190526000906020906060840190828701845b8281101561205c57815115158452928401929084019060010161203e565b5050508381038285015284518082528282019080840283018401878501865b83811015611e67577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08684030185526120b5838351611ea6565b9487019492509086019060010161207b565b6020808252818101839052600090604080840186845b8781101561211e578135835273ffffffffffffffffffffffffffffffffffffffff612109868401611b33565b168386015291830191908301906001016120dd565b5090979650505050505050565b602080825282518282018190526000919060409081850190868401855b828110156121835781518051855286015173ffffffffffffffffffffffffffffffffffffffff16868501529284019290850190600101612148565b5091979650505050505050565b90815260200190565b928352602083019190915273ffffffffffffffffffffffffffffffffffffffff16604082015260600190565b600060208252611c046020830184611ea6565b6020808252603a908201527f526571756972655574696c73237075626c697368496e697469616c5369676e6560408201527f72733a20494e56414c49445f5349474e41545552455f464c4147000000000000606082015260800190565b60208082526027908201527f4d756c746943616c6c5574696c73236d756c746943616c6c3a2043414c4c5f5260408201527f4556455254454400000000000000000000000000000000000000000000000000606082015260800190565b60208082526028908201527f4d756c746943616c6c5574696c73236d756c746943616c6c3a204e4f545f454e60408201527f4f5547485f474153000000000000000000000000000000000000000000000000606082015260800190565b60208082526032908201527f526571756972655574696c7323726571756972654d696e4e6f6e63653a204e4f60408201527f4e43455f42454c4f575f52455155495245440000000000000000000000000000606082015260800190565b60208082526027908201527f526571756972655574696c7323726571756972654e6f6e457870697265643a2060408201527f4558504952454400000000000000000000000000000000000000000000000000606082015260800190565b60208082526048908201527f526571756972655574696c73237075626c697368496e697469616c5369676e6560408201527f72733a20554e45585045435445445f434f554e5445524641435455414c5f494d60608201527f4147455f48415348000000000000000000000000000000000000000000000000608082015260a00190565b60208082526032908201527f4d6f64756c6541757468235f7369676e617475726556616c69646174696f6e3a60408201527f20494e56414c49445f5349474e41545552450000000000000000000000000000606082015260800190565b60208082526032908201527f4d756c746943616c6c5574696c73236d756c746943616c6c3a2064656c65676160408201527f746543616c6c206e6f7420616c6c6f7765640000000000000000000000000000606082015260800190565b60208082526039908201527f526571756972655574696c73237075626c697368496e697469616c5369676e6560408201527f72733a20494e56414c49445f4d454d424552535f434f554e5400000000000000606082015260800190565b60208082526031908201527f526571756972655574696c73237075626c697368436f6e6669673a20554e455860408201527f5045435445445f494d4147455f48415348000000000000000000000000000000606082015260800190565b602080825260409082018190527f526571756972655574696c73237075626c697368436f6e6669673a20554e4558908201527f5045435445445f434f554e5445524641435455414c5f494d4147455f48415348606082015260800190565b600061ffff841682526040602083015261261b6040830184611ea6565b949350505050565b60008382526040602083015261261b6040830184611ea6565b60405181810167ffffffffffffffff8111828210171561265857fe5b604052919050565b60005b8381101561267b578181015183820152602001612663565b8381111561268a576000848401525b5050505056fe5369676e617475726556616c696461746f72237265636f7665725369676e65723a20696e76616c6964207369676e6174757265202773272076616c75655369676e617475726556616c696461746f72237265636f7665725369676e65723a20696e76616c6964207369676e6174757265206c656e6774684c696242797465732372656164416464726573733a204f55545f4f465f424f554e44534c696242797465732372656164466972737455696e7431363a204f55545f4f465f424f554e44535369676e617475726556616c696461746f72237265636f7665725369676e65723a20696e76616c6964207369676e6174757265202776272076616c75655369676e617475726556616c696461746f72237265636f7665725369676e65723a20494e56414c49445f5349474e45525369676e617475726556616c696461746f7223697356616c69645369676e61747572653a20554e535550504f525445445f5349474e41545552455f545950454c696242797465732372656164427974657336363a204f55545f4f465f424f554e44535369676e617475726556616c696461746f72237265636f7665725369676e65723a20554e535550504f525445445f5349474e41545552455f545950454c69624279746573237265616455696e743855696e74383a204f55545f4f465f424f554e44534c69624279746573237265616442797465733a204f55545f4f465f424f554e44534c69624279746573237265616455696e7431363a204f55545f4f465f424f554e44534c696242797465732372656164427974657333323a20475245415445525f4f525f455155414c5f544f5f33325f4c454e4754485f5245515549524544a26469706673582212200abb842b6eea58df953f048e3a9aa7589fd3ce15ca086e43b61cdb0c0c42723564736f6c63430007060033603a600e3d39601a805130553df3363d3d373d3d3d363d30545af43d82803e903d91601857fd5bf3', + deployedBytecode: + '0x6080604052600436106101805760003560e01c806398f9fbc4116100d6578063d1db39071161007f578063e90f13e711610059578063e90f13e714610395578063f209883a146103ea578063ffd7d741146103ff57610180565b8063d1db390714610395578063d5b5337f146103aa578063e717aba9146103ca57610180565b8063c272d5c3116100b0578063c272d5c314610333578063c39f2d5c14610348578063c66764e11461036857610180565b806398f9fbc4146102e9578063aeea5fb5146102fe578063b472f0a21461031357610180565b806348acd29f116101385780637ae99638116101125780637ae99638146102875780637f29d538146102a7578063984395bc146102c757610180565b806348acd29f14610227578063543196eb146102475780637082503b1461026757610180565b80631cd05dc4116101695780631cd05dc4146101d057806343d9c935146101f057806344d466c21461020557610180565b80630fdecfac146101855780631551f0ab146101b0575b600080fd5b34801561019157600080fd5b5061019a610420565b6040516101a79190612190565b60405180910390f35b3480156101bc57600080fd5b5061019a6101cb366004611e76565b610424565b3480156101dc57600080fd5b5061019a6101eb366004611bea565b610436565b3480156101fc57600080fd5b5061019a610448565b34801561021157600080fd5b50610225610220366004611ca4565b610450565b005b34801561023357600080fd5b5061019a610242366004611bea565b61080a565b34801561025357600080fd5b5061019a610262366004611bea565b610828565b34801561027357600080fd5b50610225610282366004611c0b565b61082c565b34801561029357600080fd5b5061019a6102a2366004611bea565b610cb0565b3480156102b357600080fd5b506102256102c2366004611e76565b610cc2565b3480156102d357600080fd5b506102dc610cfe565b6040516101a79190612000565b3480156102f557600080fd5b506102dc610d02565b34801561030a57600080fd5b5061019a610d06565b34801561031f57600080fd5b5061022561032e366004611c7b565b610d0a565b34801561033f57600080fd5b5061019a610de8565b34801561035457600080fd5b5061019a610363366004611bea565b610dec565b34801561037457600080fd5b50610388610383366004611bea565b610df0565b6040516101a791906121c5565b3480156103a157600080fd5b5061019a610e35565b3480156103b657600080fd5b5061019a6103c5366004611e76565b610e39565b3480156103d657600080fd5b5061019a6103e5366004611bea565b610e3d565b3480156103f657600080fd5b5061019a610e4f565b61041261040d366004611d34565b610e53565b6040516101a7929190612021565b4690565b60036020526000908152604090205481565b60006020819052908152604090205481565b60005a905090565b8360005b838110156104e9578185858381811061046957fe5b9050604002016000013586868481811061047f57fe5b90506040020160200160208101906104979190611bea565b6040516020016104a993929190612199565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209150600101610454565b506000808773ffffffffffffffffffffffffffffffffffffffff166351605d8060e01b60405160200161051c9190611f54565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905261055491611f81565b6000604051808303816000865af19150503d8060008114610591576040519150601f19603f3d011682016040523d82523d6000602084013e610596565b606091505b50915091508180156105a9575080516020145b1561060e576000818060200190518101906105c49190611e8e565b9050838114610608576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ff90612543565b60405180910390fd5b50610732565b60405173ffffffffffffffffffffffffffffffffffffffff89169061069d907fff00000000000000000000000000000000000000000000000000000000000000907f00000000000000000000000000000000000000000000000000000000000000009087907f000000000000000000000000000000000000000000000000000000000000000090602001611ef0565b6040516020818303038152906040528051906020012060001c73ffffffffffffffffffffffffffffffffffffffff1614610703576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ff906125a0565b83156107325773ffffffffffffffffffffffffffffffffffffffff881660009081526002602052604090208390555b828873ffffffffffffffffffffffffffffffffffffffff167fb502b7446ca079086188acf3abef47c2f464f2ee9a72fcdf05ffcb74dcc17cee89898960405160200161077f9291906120c7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290526107b89291612623565b60405180910390a383156108005773ffffffffffffffffffffffffffffffffffffffff8816600090815260016020908152604080832043908190558684526003909252909120555b5050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116315b919050565b3f90565b600080610838846110c3565b9150915060008046905080898960405160200161085793929190611f9d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052805160209091012091505061ffff831660008767ffffffffffffffff811180156108ae57600080fd5b506040519080825280602002602001820160405280156108e857816020015b6108d5611b1c565b8152602001906001900390816108cd5790505b50905060005b8751851015610a9f57600080806109058b89611131565b995060ff9182169450169150600183141561092d576109248b896111b2565b98509050610a20565b8261095f57606061093e8c8a61122a565b9950905061094c88826112db565b91506109598f838d611665565b50610a20565b60028314156109ee576109728b896111b2565b9850905060006109828c8a6116f3565b995061ffff16905060606109978d8b84611764565b9a5090506109a6898483611853565b6109dc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ff9061242c565b50506109e98e828c611665565b610a20565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ff906121d8565b60405180604001604052808381526020018273ffffffffffffffffffffffffffffffffffffffff16815250858581518110610a5757fe5b60200260200101819052508380600101945050858282604051602001610a7f93929190612199565b6040516020818303038152906040528051906020012095505050506108ee565b888114610ad8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ff906124e6565b60405173ffffffffffffffffffffffffffffffffffffffff8c1690610b67907fff00000000000000000000000000000000000000000000000000000000000000907f00000000000000000000000000000000000000000000000000000000000000009087907f000000000000000000000000000000000000000000000000000000000000000090602001611ef0565b6040516020818303038152906040528051906020012060001c73ffffffffffffffffffffffffffffffffffffffff1614610bcd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ff906123a9565b828b73ffffffffffffffffffffffffffffffffffffffff167fb502b7446ca079086188acf3abef47c2f464f2ee9a72fcdf05ffcb74dcc17cee8885604051602001610c18919061212b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052610c5192916125fe565b60405180910390a38615610ca35773ffffffffffffffffffffffffffffffffffffffff8b1660008181526001602090815260408083204390819055878452600383528184205592825260029052208390555b5050505050505050505050565b60026020526000908152604090205481565b804210610cfb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ff9061234c565b50565b3290565b4190565b4490565b600080610d1683611a9b565b9150915060008473ffffffffffffffffffffffffffffffffffffffff16638c3f5563846040518263ffffffff1660e01b8152600401610d559190612190565b60206040518083038186803b158015610d6d57600080fd5b505afa158015610d81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610da59190611e8e565b905081811015610de1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ff906122ef565b5050505050565b3a90565b3b90565b60408051603f833b9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092528181529080600060208401853c50919050565b4590565b4090565b60016020526000908152604090205481565b4290565b606080825167ffffffffffffffff81118015610e6e57600080fd5b50604051908082528060200260200182016040528015610e98578160200160208202803683370190505b509150825167ffffffffffffffff81118015610eb357600080fd5b50604051908082528060200260200182016040528015610ee757816020015b6060815260200190600190039081610ed25790505b50905060005b83518110156110bd576000848281518110610f0457fe5b60200260200101519050806000015115610f4a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ff90612489565b80604001515a1015610f88576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ff90612292565b806060015173ffffffffffffffffffffffffffffffffffffffff1681608001518260400151600014610fbe578260400151610fc0565b5a5b908360a00151604051610fd39190611f81565b600060405180830381858888f193505050503d8060008114611011576040519150601f19603f3d011682016040523d82523d6000602084013e611016565b606091505b5085848151811061102357fe5b6020026020010185858151811061103657fe5b602002602001018290528215151515815250505083828151811061105657fe5b60200260200101518061107e575084828151811061107057fe5b602002602001015160200151155b6110b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ff90612235565b50600101610eed565b50915091565b6020810151815160f09190911c9060029081111561112c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061272b6027913960400191505060405180910390fd5b915091565b8082016020015160f881901c9060f01c60ff166002830183811161115157fe5b84518111156111ab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602681526020018061285d6026913960400191505060405180910390fd5b9250925092565b8082016020015160601c601482018281116111c957fe5b8351811115611223576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806127086023913960400191505060405180910390fd5b9250929050565b60408051604280825260808201909252606091600091906020820181803683370190505091508284016020018051602084015260208101516040840152602281015160428401525060428301905082811161128157fe5b8351811115611223576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806127fe6023913960400191505060405180910390fd5b60008151604214611337576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603a8152602001806126ce603a913960400191505060405180910390fd5b60008260018451038151811061134957fe5b602001015160f81c60f81b60f81c60ff16905060008360408151811061136b57fe5b016020015160f81c905060006113818582611ab4565b90506000611390866020611ab4565b90507f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a081111561140b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d815260200180612691603d913960400191505060405180910390fd5b8260ff16601b1415801561142357508260ff16601c14155b15611479576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d815260200180612752603d913960400191505060405180910390fd5b60018414156114ed5760018784848460405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156114dc573d6000803e3d6000fd5b5050506020604051035194506115ef565b600284141561159e5760018760405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012084848460405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156114dc573d6000803e3d6000fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c815260200180612821603c913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff851661165b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603081526020018061278f6030913960400191505060405180910390fd5b5050505092915050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f600ba597427f042bcd559a0d06fa1732cc104d6dd43cbe8845b5a0e804b2b39f60405160405180910390a380156116ee5773ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090204390555b505050565b8082016020015160f01c6002820182811161170a57fe5b8351811115611223576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806128a46022913960400191505060405180910390fd5b606060008267ffffffffffffffff8111801561177f57600080fd5b506040519080825280601f01601f1916602001820160405280156117aa576020820181803683370190505b509150838501602001600060205b858110156117d1579082015184820152602081016117b8565b84860160200180519390920151908501525250828201838110156117f157fe5b845181111561184b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806128836021913960400191505060405180910390fd5b935093915050565b6000808260018451038151811061186657fe5b016020015160f81c9050600181148061187f5750600281145b156118c3578373ffffffffffffffffffffffffffffffffffffffff166118a586856112db565b73ffffffffffffffffffffffffffffffffffffffff16149150611a93565b6003811415611a425782517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81018452604080517f1626ba7e000000000000000000000000000000000000000000000000000000008152600481018881526024820192835286516044830152865173ffffffffffffffffffffffffffffffffffffffff891693631626ba7e938b938a9390929160640190602085019080838360005b8381101561197d578181015183820152602001611965565b50505050905090810190601f1680156119aa5780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b1580156119c857600080fd5b505afa1580156119dc573d6000803e3d6000fd5b505050506040513d60208110156119f257600080fd5b50519084527fffffffff00000000000000000000000000000000000000000000000000000000167f1626ba7e00000000000000000000000000000000000000000000000000000000149150611a93565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603f8152602001806127bf603f913960400191505060405180910390fd5b509392505050565b606081901c916bffffffffffffffffffffffff90911690565b60008160200183511015611b13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c8152602001806128c6603c913960400191505060405180910390fd5b50016020015190565b604080518082019091526000808252602082015290565b803573ffffffffffffffffffffffffffffffffffffffff8116811461082357600080fd5b8035801515811461082357600080fd5b600082601f830112611b77578081fd5b813567ffffffffffffffff811115611b8b57fe5b611bbc60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161263c565b818152846020838601011115611bd0578283fd5b816020850160208301379081016020019190915292915050565b600060208284031215611bfb578081fd5b611c0482611b33565b9392505050565b600080600080600060a08688031215611c22578081fd5b611c2b86611b33565b94506020860135935060408601359250606086013567ffffffffffffffff811115611c54578182fd5b611c6088828901611b67565b925050611c6f60808701611b57565b90509295509295909350565b60008060408385031215611c8d578182fd5b611c9683611b33565b946020939093013593505050565b600080600080600060808688031215611cbb578081fd5b611cc486611b33565b945060208601359350604086013567ffffffffffffffff80821115611ce7578283fd5b818801915088601f830112611cfa578283fd5b813581811115611d08578384fd5b896020604083028501011115611d1c578384fd5b602083019550809450505050611c6f60608701611b57565b60006020808385031215611d46578182fd5b823567ffffffffffffffff80821115611d5d578384fd5b818501915085601f830112611d70578384fd5b813581811115611d7c57fe5b611d89848583020161263c565b81815284810190848601875b84811015611e67578135870160c0807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0838f03011215611dd3578a8bfd5b604080518281018181108b82111715611de857fe5b8252611df5848d01611b57565b8152611e02828501611b57565b8c82015260608085013583830152611e1c60808601611b33565b9082015260a08481013560808301529284013592915089831115611e3e578c8dfd5b611e4c8f8d85870101611b67565b91810191909152865250509287019290870190600101611d95565b50909998505050505050505050565b600060208284031215611e87578081fd5b5035919050565b600060208284031215611e9f578081fd5b5051919050565b60008151808452611ebe816020860160208601612660565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b7fff0000000000000000000000000000000000000000000000000000000000000094909416845260609290921b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660018401526015830152603582015260550190565b7fffffffff0000000000000000000000000000000000000000000000000000000091909116815260040190565b60008251611f93818460208701612660565b9190910192915050565b7f19010000000000000000000000000000000000000000000000000000000000008152600281019390935260609190911b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166022830152603682015260560190565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b604080825283519082018190526000906020906060840190828701845b8281101561205c57815115158452928401929084019060010161203e565b5050508381038285015284518082528282019080840283018401878501865b83811015611e67577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08684030185526120b5838351611ea6565b9487019492509086019060010161207b565b6020808252818101839052600090604080840186845b8781101561211e578135835273ffffffffffffffffffffffffffffffffffffffff612109868401611b33565b168386015291830191908301906001016120dd565b5090979650505050505050565b602080825282518282018190526000919060409081850190868401855b828110156121835781518051855286015173ffffffffffffffffffffffffffffffffffffffff16868501529284019290850190600101612148565b5091979650505050505050565b90815260200190565b928352602083019190915273ffffffffffffffffffffffffffffffffffffffff16604082015260600190565b600060208252611c046020830184611ea6565b6020808252603a908201527f526571756972655574696c73237075626c697368496e697469616c5369676e6560408201527f72733a20494e56414c49445f5349474e41545552455f464c4147000000000000606082015260800190565b60208082526027908201527f4d756c746943616c6c5574696c73236d756c746943616c6c3a2043414c4c5f5260408201527f4556455254454400000000000000000000000000000000000000000000000000606082015260800190565b60208082526028908201527f4d756c746943616c6c5574696c73236d756c746943616c6c3a204e4f545f454e60408201527f4f5547485f474153000000000000000000000000000000000000000000000000606082015260800190565b60208082526032908201527f526571756972655574696c7323726571756972654d696e4e6f6e63653a204e4f60408201527f4e43455f42454c4f575f52455155495245440000000000000000000000000000606082015260800190565b60208082526027908201527f526571756972655574696c7323726571756972654e6f6e457870697265643a2060408201527f4558504952454400000000000000000000000000000000000000000000000000606082015260800190565b60208082526048908201527f526571756972655574696c73237075626c697368496e697469616c5369676e6560408201527f72733a20554e45585045435445445f434f554e5445524641435455414c5f494d60608201527f4147455f48415348000000000000000000000000000000000000000000000000608082015260a00190565b60208082526032908201527f4d6f64756c6541757468235f7369676e617475726556616c69646174696f6e3a60408201527f20494e56414c49445f5349474e41545552450000000000000000000000000000606082015260800190565b60208082526032908201527f4d756c746943616c6c5574696c73236d756c746943616c6c3a2064656c65676160408201527f746543616c6c206e6f7420616c6c6f7765640000000000000000000000000000606082015260800190565b60208082526039908201527f526571756972655574696c73237075626c697368496e697469616c5369676e6560408201527f72733a20494e56414c49445f4d454d424552535f434f554e5400000000000000606082015260800190565b60208082526031908201527f526571756972655574696c73237075626c697368436f6e6669673a20554e455860408201527f5045435445445f494d4147455f48415348000000000000000000000000000000606082015260800190565b602080825260409082018190527f526571756972655574696c73237075626c697368436f6e6669673a20554e4558908201527f5045435445445f434f554e5445524641435455414c5f494d4147455f48415348606082015260800190565b600061ffff841682526040602083015261261b6040830184611ea6565b949350505050565b60008382526040602083015261261b6040830184611ea6565b60405181810167ffffffffffffffff8111828210171561265857fe5b604052919050565b60005b8381101561267b578181015183820152602001612663565b8381111561268a576000848401525b5050505056fe5369676e617475726556616c696461746f72237265636f7665725369676e65723a20696e76616c6964207369676e6174757265202773272076616c75655369676e617475726556616c696461746f72237265636f7665725369676e65723a20696e76616c6964207369676e6174757265206c656e6774684c696242797465732372656164416464726573733a204f55545f4f465f424f554e44534c696242797465732372656164466972737455696e7431363a204f55545f4f465f424f554e44535369676e617475726556616c696461746f72237265636f7665725369676e65723a20696e76616c6964207369676e6174757265202776272076616c75655369676e617475726556616c696461746f72237265636f7665725369676e65723a20494e56414c49445f5349474e45525369676e617475726556616c696461746f7223697356616c69645369676e61747572653a20554e535550504f525445445f5349474e41545552455f545950454c696242797465732372656164427974657336363a204f55545f4f465f424f554e44535369676e617475726556616c696461746f72237265636f7665725369676e65723a20554e535550504f525445445f5349474e41545552455f545950454c69624279746573237265616455696e743855696e74383a204f55545f4f465f424f554e44534c69624279746573237265616442797465733a204f55545f4f465f424f554e44534c69624279746573237265616455696e7431363a204f55545f4f465f424f554e44534c696242797465732372656164427974657333323a20475245415445525f4f525f455155414c5f544f5f33325f4c454e4754485f5245515549524544a26469706673582212200abb842b6eea58df953f048e3a9aa7589fd3ce15ca086e43b61cdb0c0c42723564736f6c63430007060033', + linkReferences: {}, + deployedLinkReferences: {} +} diff --git a/packages/tests/src/builds/v1/index.ts b/packages/tests/src/builds/v1/index.ts new file mode 100644 index 0000000000..a4c3cd41a1 --- /dev/null +++ b/packages/tests/src/builds/v1/index.ts @@ -0,0 +1,6 @@ +export { factory } from './artifacts/Factory' +export { guestModule } from './artifacts/GuestModule' +export { mainModule } from './artifacts/MainModule' +export { mainModuleUpgradable } from './artifacts/MainModuleUpgradable' +export { multiCallUtils } from './artifacts/MultiCallUtils' +export { sequenceUtils } from './artifacts/SequenceUtils' diff --git a/packages/tests/src/builds/v2/artifacts/Factory.ts b/packages/tests/src/builds/v2/artifacts/Factory.ts new file mode 100644 index 0000000000..ff1a54fc2d --- /dev/null +++ b/packages/tests/src/builds/v2/artifacts/Factory.ts @@ -0,0 +1,37 @@ +export const factory = { + _format: 'hh-sol-artifact-1', + contractName: 'Factory', + sourceName: 'contracts/Factory.sol', + abi: [ + { + inputs: [ + { + internalType: 'address', + name: '_mainModule', + type: 'address' + }, + { + internalType: 'bytes32', + name: '_salt', + type: 'bytes32' + } + ], + name: 'deploy', + outputs: [ + { + internalType: 'address', + name: '_contract', + type: 'address' + } + ], + stateMutability: 'payable', + type: 'function' + } + ], + bytecode: + '0x608060405234801561001057600080fd5b5061019a806100206000396000f3fe60806040526004361061001e5760003560e01c806332c02a1414610023575b600080fd5b6100366100313660046100c5565b61005f565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b60008060405180606001604052806028815260200161013d602891398473ffffffffffffffffffffffffffffffffffffffff166040516020016100a392919061010a565b60405160208183030381529060405290508281516020830134f5949350505050565b600080604083850312156100d857600080fd5b823573ffffffffffffffffffffffffffffffffffffffff811681146100fc57600080fd5b946020939093013593505050565b6000835160005b8181101561012b5760208187018101518583015201610111565b50919091019182525060200191905056fe603a600e3d39601a805130553df3363d3d373d3d3d363d30545af43d82803e903d91601857fd5bf3a264697066735822122043a67ce1dd84e0676792a0fadb81e020ae20ed22debbddf46c2790ea0338256464736f6c63430008110033', + deployedBytecode: + '0x60806040526004361061001e5760003560e01c806332c02a1414610023575b600080fd5b6100366100313660046100c5565b61005f565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b60008060405180606001604052806028815260200161013d602891398473ffffffffffffffffffffffffffffffffffffffff166040516020016100a392919061010a565b60405160208183030381529060405290508281516020830134f5949350505050565b600080604083850312156100d857600080fd5b823573ffffffffffffffffffffffffffffffffffffffff811681146100fc57600080fd5b946020939093013593505050565b6000835160005b8181101561012b5760208187018101518583015201610111565b50919091019182525060200191905056fe603a600e3d39601a805130553df3363d3d373d3d3d363d30545af43d82803e903d91601857fd5bf3a264697066735822122043a67ce1dd84e0676792a0fadb81e020ae20ed22debbddf46c2790ea0338256464736f6c63430008110033', + linkReferences: {}, + deployedLinkReferences: {} +} diff --git a/packages/tests/src/builds/v2/artifacts/GuestModule.ts b/packages/tests/src/builds/v2/artifacts/GuestModule.ts new file mode 100644 index 0000000000..9e0e81e750 --- /dev/null +++ b/packages/tests/src/builds/v2/artifacts/GuestModule.ts @@ -0,0 +1,628 @@ +export const guestModule = { + _format: 'hh-sol-artifact-1', + contractName: 'GuestModule', + sourceName: 'contracts/modules/GuestModule.sol', + abi: [ + { + inputs: [ + { + internalType: 'uint256', + name: '_space', + type: 'uint256' + }, + { + internalType: 'uint256', + name: '_provided', + type: 'uint256' + }, + { + internalType: 'uint256', + name: '_current', + type: 'uint256' + } + ], + name: 'BadNonce', + type: 'error' + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_index', + type: 'uint256' + } + ], + name: 'DelegateCallNotAllowed', + type: 'error' + }, + { + inputs: [], + name: 'ImageHashIsZero', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_hash', + type: 'bytes32' + }, + { + internalType: 'address', + name: '_addr', + type: 'address' + }, + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + } + ], + name: 'InvalidNestedSignature', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + }, + { + internalType: 'bytes32', + name: '_s', + type: 'bytes32' + } + ], + name: 'InvalidSValue', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_hash', + type: 'bytes32' + }, + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + } + ], + name: 'InvalidSignature', + type: 'error' + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_flag', + type: 'uint256' + } + ], + name: 'InvalidSignatureFlag', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + } + ], + name: 'InvalidSignatureLength', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes1', + name: '_type', + type: 'bytes1' + } + ], + name: 'InvalidSignatureType', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + }, + { + internalType: 'uint256', + name: '_v', + type: 'uint256' + } + ], + name: 'InvalidVValue', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + }, + { + internalType: 'uint256', + name: 'threshold', + type: 'uint256' + }, + { + internalType: 'uint256', + name: '_weight', + type: 'uint256' + } + ], + name: 'LowWeightChainedSignature', + type: 'error' + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_index', + type: 'uint256' + }, + { + internalType: 'uint256', + name: '_requested', + type: 'uint256' + }, + { + internalType: 'uint256', + name: '_available', + type: 'uint256' + } + ], + name: 'NotEnoughGas', + type: 'error' + }, + { + inputs: [], + name: 'NotSupported', + type: 'error' + }, + { + inputs: [ + { + internalType: 'address', + name: '_sender', + type: 'address' + }, + { + internalType: 'address', + name: '_self', + type: 'address' + } + ], + name: 'OnlySelfAuth', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + } + ], + name: 'SignerIsAddress0', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + }, + { + internalType: 'uint256', + name: '_type', + type: 'uint256' + }, + { + internalType: 'bool', + name: '_recoverMode', + type: 'bool' + } + ], + name: 'UnsupportedSignatureType', + type: 'error' + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_current', + type: 'uint256' + }, + { + internalType: 'uint256', + name: '_prev', + type: 'uint256' + } + ], + name: 'WrongChainedCheckpointOrder', + type: 'error' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: '_contract', + type: 'address' + } + ], + name: 'CreatedContract', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'bytes32', + name: 'newImageHash', + type: 'bytes32' + } + ], + name: 'ImageHashUpdated', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: '_space', + type: 'uint256' + }, + { + indexed: false, + internalType: 'uint256', + name: '_newNonce', + type: 'uint256' + } + ], + name: 'NonceChange', + type: 'event' + }, + { + anonymous: true, + inputs: [ + { + indexed: false, + internalType: 'bytes32', + name: '_tx', + type: 'bytes32' + } + ], + name: 'TxExecuted', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'bytes32', + name: '_tx', + type: 'bytes32' + }, + { + indexed: false, + internalType: 'bytes', + name: '_reason', + type: 'bytes' + } + ], + name: 'TxFailed', + type: 'event' + }, + { + inputs: [], + name: 'SET_IMAGE_HASH_TYPE_HASH', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_code', + type: 'bytes' + } + ], + name: 'createContract', + outputs: [ + { + internalType: 'address', + name: 'addr', + type: 'address' + } + ], + stateMutability: 'payable', + type: 'function' + }, + { + inputs: [ + { + components: [ + { + internalType: 'bool', + name: 'delegateCall', + type: 'bool' + }, + { + internalType: 'bool', + name: 'revertOnError', + type: 'bool' + }, + { + internalType: 'uint256', + name: 'gasLimit', + type: 'uint256' + }, + { + internalType: 'address', + name: 'target', + type: 'address' + }, + { + internalType: 'uint256', + name: 'value', + type: 'uint256' + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes' + } + ], + internalType: 'struct IModuleCalls.Transaction[]', + name: '_txs', + type: 'tuple[]' + }, + { + internalType: 'uint256', + name: '', + type: 'uint256' + }, + { + internalType: 'bytes', + name: '', + type: 'bytes' + } + ], + name: 'execute', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_hash', + type: 'bytes32' + }, + { + internalType: 'bytes', + name: '_signatures', + type: 'bytes' + } + ], + name: 'isValidSignature', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_data', + type: 'bytes' + }, + { + internalType: 'bytes', + name: '_signatures', + type: 'bytes' + } + ], + name: 'isValidSignature', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'nonce', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_space', + type: 'uint256' + } + ], + name: 'readNonce', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + components: [ + { + internalType: 'bool', + name: 'delegateCall', + type: 'bool' + }, + { + internalType: 'bool', + name: 'revertOnError', + type: 'bool' + }, + { + internalType: 'uint256', + name: 'gasLimit', + type: 'uint256' + }, + { + internalType: 'address', + name: 'target', + type: 'address' + }, + { + internalType: 'uint256', + name: 'value', + type: 'uint256' + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes' + } + ], + internalType: 'struct IModuleCalls.Transaction[]', + name: '_txs', + type: 'tuple[]' + } + ], + name: 'selfExecute', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_digest', + type: 'bytes32' + }, + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + } + ], + name: 'signatureRecovery', + outputs: [ + { + internalType: 'uint256', + name: 'threshold', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'weight', + type: 'uint256' + }, + { + internalType: 'bytes32', + name: 'imageHash', + type: 'bytes32' + }, + { + internalType: 'bytes32', + name: 'subDigest', + type: 'bytes32' + }, + { + internalType: 'uint256', + name: 'checkpoint', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes4', + name: '_interfaceID', + type: 'bytes4' + } + ], + name: 'supportsInterface', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool' + } + ], + stateMutability: 'pure', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_imageHash', + type: 'bytes32' + } + ], + name: 'updateImageHash', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + } + ], + bytecode: + '0x608060405234801561001057600080fd5b5061210b806100206000396000f3fe6080604052600436106100bc5760003560e01c806361c2926c116100745780638c3f55631161004e5780638c3f55631461025357806390042baf14610273578063affed0e0146102ab57600080fd5b806361c2926c146101cb5780637a9a1628146101eb578063853c50681461020b57600080fd5b806320c13b0b116100a557806320c13b0b14610147578063295614261461016757806357c56d6b1461018957600080fd5b806301ffc9a7146100c15780631626ba7e146100f6575b600080fd5b3480156100cd57600080fd5b506100e16100dc3660046117cc565b6102c0565b60405190151581526020015b60405180910390f35b34801561010257600080fd5b50610116610111366004611832565b6102d1565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016100ed565b34801561015357600080fd5b5061011661016236600461187e565b61031e565b34801561017357600080fd5b506101876101823660046118ea565b610383565b005b34801561019557600080fd5b506101bd7f8713a7c4465f6fbee2b6e9d6646d1d9f83fec929edfc4baf661f3c865bdd04d181565b6040519081526020016100ed565b3480156101d757600080fd5b506101876101e6366004611948565b6103d5565b3480156101f757600080fd5b5061018761020636600461198a565b61041a565b34801561021757600080fd5b5061022b610226366004611832565b610447565b604080519586526020860194909452928401919091526060830152608082015260a0016100ed565b34801561025f57600080fd5b506101bd61026e3660046118ea565b61060f565b610286610281366004611a33565b61063b565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100ed565b3480156102b757600080fd5b506101bd6106d7565b60006102cb826106e8565b92915050565b6000806102df858585610744565b509050801561031157507f1626ba7e000000000000000000000000000000000000000000000000000000009050610317565b50600090505b9392505050565b6000806103438686604051610334929190611b02565b60405180910390208585610744565b509050801561037557507f20c13b0b00000000000000000000000000000000000000000000000000000000905061037b565b50600090505b949350505050565b3330146103c9576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044015b60405180910390fd5b6103d28161077c565b50565b600061040883836040516020016103ed929190611ce0565b604051602081830303815290604052805190602001206107ae565b9050610415818484610833565b505050565b600061043286866040516020016103ed929190611d28565b905061043f818787610833565b505050505050565b6000806000806000808787600081811061046357610463611d70565b909101357fff000000000000000000000000000000000000000000000000000000000000001691508190506104b95761049b896107ae565b92506104a8838989610996565b929850909650945091506106049050565b7fff00000000000000000000000000000000000000000000000000000000000000818116016104f8576104eb896107ae565b92506104a88389896109e7565b7ffe000000000000000000000000000000000000000000000000000000000000007fff0000000000000000000000000000000000000000000000000000000000000082160161054a576104eb89610a13565b7ffd000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216016105ae5761059e898989610a80565b9550955095509550955050610604565b6040517f6085cd820000000000000000000000000000000000000000000000000000000081527fff00000000000000000000000000000000000000000000000000000000000000821660048201526024016103c0565b939792965093509350565b60006102cb7f8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e83610bfd565b600033301461067e576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044016103c0565b81516020830134f060405173ffffffffffffffffffffffffffffffffffffffff821681529091507fa506ad4e7f05eceba62a023c3219e5bd98a615f4fa87e2afb08a2da5cf62bf0c9060200160405180910390a1919050565b60006106e3600061060f565b905090565b60007f6ffbd451000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083160161073b57506001919050565b6102cb82610c5b565b6000806000806000610757888888610447565b5096509194509250905082821080159061076f575060015b9450505050935093915050565b6040517fa038794000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f190100000000000000000000000000000000000000000000000000000000000060208201524660228201527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b166042820152605681018290526000906076015b604051602081830303815290604052805190602001209050919050565b8060005b8181101561098f573684848381811061085257610852611d70565b90506020028101906108649190611d9f565b90506108736020820182611ddd565b156108ad576040517f230d1ccc000000000000000000000000000000000000000000000000000000008152600481018390526024016103c0565b6040810135805a10156109005782815a6040517f2bb3e3ba0000000000000000000000000000000000000000000000000000000081526004810193909352602483019190915260448201526064016103c0565b600061093a6109156080850160608601611df8565b608085013584156109265784610928565b5a5b61093560a0880188611e13565b610cb7565b905080156109585760405188815260200160405180910390a0610979565b61097961096b6040850160208601611ddd565b89610974610cd4565b610cf3565b505050808061098790611ea7565b915050610837565b5050505050565b60008080806109b1876109ac876006818b611edf565b610d3f565b6000908152873560f01c6020818152604080842084526002909a013560e01c908190529890912090999198509695509350505050565b6000808080610a02876109fd876001818b611edf565b610996565b935093509350935093509350935093565b6040517f190100000000000000000000000000000000000000000000000000000000000060208201526000602282018190527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b1660428301526056820183905290607601610816565b6000808080806004600188013560e81c82610a9b8383611f09565b9050610aad8b61022683868d8f611edf565b939b5091995097509550935087871015610b0557610acd81848b8d611edf565b89896040517fb006aba00000000000000000000000000000000000000000000000000000000081526004016103c09493929190611f1c565b8092505b88831015610bef5760038301928a013560e81c9150610b288383611f09565b90506000610b4a610b38886111d5565b8c8c8790869261022693929190611edf565b939c50919a5098509091505088881015610ba257610b6a82858c8e611edf565b8a8a6040517fb006aba00000000000000000000000000000000000000000000000000000000081526004016103c09493929190611f1c565b848110610be5576040517f37daf62b00000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016103c0565b9350915081610b09565b505050939792965093509350565b6000808383604051602001610c1c929190918252602082015260400190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052805160209091012054949350505050565b60007fe4a77bbc000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831601610cae57506001919050565b6102cb82611209565b6000604051828482376000808483898b8af1979650505050505050565b60603d604051915060208201818101604052818352816000823e505090565b8215610d0157805160208201fd5b7f3dbd1590ea96dd3253a91f24e64e3a502e1225d602a5731357bc12643070ccd78282604051610d32929190611f43565b60405180910390a1505050565b60008060005b838110156111cc57600181019085013560f81c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8101610de657601582019186013560f881901c9060581c73ffffffffffffffffffffffffffffffffffffffff81169074ff000000000000000000000000000000000000000016811785610dcc5780610ddb565b60008681526020829052604090205b955050505050610d45565b80610e7c5760018201918681013560f81c906043016000610e128a610e0d84888c8e611edf565b6112f3565b60ff841697909701969194508491905060a083901b74ff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff82161786610e615780610e70565b60008781526020829052604090205b96505050505050610d45565b60028103610fa4576000808784013560f881901c9060581c73ffffffffffffffffffffffffffffffffffffffff16601586019550909250905060008885013560e81c600386018162ffffff169150809650819250505060008186019050610ef58b848c8c8a908692610ef093929190611edf565b6115b6565b610f3d578a83610f0783898d8f611edf565b6040517f9a9462320000000000000000000000000000000000000000000000000000000081526004016103c09493929190611fb7565b60ff8416979097019694508460a084901b74ff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161787610f885780610f97565b60008881526020829052604090205b9750505050505050610d45565b60038103610fd757602082019186013583610fbf5780610fce565b60008481526020829052604090205b93505050610d45565b60048103611023576003808301928781013560e81c91908201016000806110048b6109ac85898d8f611edf565b60009889526020526040909720969097019650909350610d4592505050565b6006810361112b5760008287013560f81c60018401935060ff16905060008784013560f01c60028501945061ffff16905060008885013560e81c600386018162ffffff1691508096508192505050600081860190506000806110918d8d8d8b9087926109ac93929190611edf565b939850889390925090508482106110a757988501985b604080517f53657175656e6365206e657374656420636f6e6669673a0a0000000000000000602080830191909152603882018490526058820188905260788083018a905283518084039091018152609890920190925280519101208961110d578061111c565b60008a81526020829052604090205b99505050505050505050610d45565b60058103611197576020820191860135878103611166577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff94505b600061117182611763565b90508461117e578061118d565b60008581526020829052604090205b9450505050610d45565b6040517fb2505f7c000000000000000000000000000000000000000000000000000000008152600481018290526024016103c0565b50935093915050565b7f8713a7c4465f6fbee2b6e9d6646d1d9f83fec929edfc4baf661f3c865bdd04d160009081526020829052604081206102cb565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fac6a444e00000000000000000000000000000000000000000000000000000000148061129c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f36e7817500000000000000000000000000000000000000000000000000000000145b156112a957506001919050565b7f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316146102cb565b6000604282146113335782826040517f2ee17a3d0000000000000000000000000000000000000000000000000000000081526004016103c0929190611ff7565b600061134c61134360018561200b565b85013560f81c90565b60ff169050604084013560f81c843560208601357f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08111156113c0578686826040517fad4aac760000000000000000000000000000000000000000000000000000000081526004016103c09392919061201e565b8260ff16601b141580156113d857508260ff16601c14155b15611415578686846040517fe578897e0000000000000000000000000000000000000000000000000000000081526004016103c093929190612042565b60018403611482576040805160008152602081018083528a905260ff851691810191909152606081018390526080810182905260019060a0015b6020604051602081039080840390855afa158015611471573d6000803e3d6000fd5b50505060206040510351945061155a565b6002840361151f576040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101899052600190605c01604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600084529083018083525260ff861690820152606081018490526080810183905260a00161144f565b86868560016040517f9dfba8520000000000000000000000000000000000000000000000000000000081526004016103c09493929190612069565b73ffffffffffffffffffffffffffffffffffffffff85166115ab5786866040517f6c1719d20000000000000000000000000000000000000000000000000000000081526004016103c0929190611ff7565b505050509392505050565b60008083836115c660018261200b565b8181106115d5576115d5611d70565b919091013560f81c91505060018114806115ef5750600281145b15611634578473ffffffffffffffffffffffffffffffffffffffff166116168786866112f3565b73ffffffffffffffffffffffffffffffffffffffff1614915061175a565b6003810361171f5773ffffffffffffffffffffffffffffffffffffffff8516631626ba7e878660008761166860018261200b565b9261167593929190611edf565b6040518463ffffffff1660e01b815260040161169393929190612095565b602060405180830381865afa1580156116b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116d491906120b8565b7fffffffff00000000000000000000000000000000000000000000000000000000167f1626ba7e0000000000000000000000000000000000000000000000000000000014915061175a565b83838260006040517f9dfba8520000000000000000000000000000000000000000000000000000000081526004016103c09493929190612069565b50949350505050565b6040517f53657175656e636520737461746963206469676573743a0a0000000000000000602082015260388101829052600090605801610816565b7fffffffff00000000000000000000000000000000000000000000000000000000811681146103d257600080fd5b6000602082840312156117de57600080fd5b81356103178161179e565b60008083601f8401126117fb57600080fd5b50813567ffffffffffffffff81111561181357600080fd5b60208301915083602082850101111561182b57600080fd5b9250929050565b60008060006040848603121561184757600080fd5b83359250602084013567ffffffffffffffff81111561186557600080fd5b611871868287016117e9565b9497909650939450505050565b6000806000806040858703121561189457600080fd5b843567ffffffffffffffff808211156118ac57600080fd5b6118b8888389016117e9565b909650945060208701359150808211156118d157600080fd5b506118de878288016117e9565b95989497509550505050565b6000602082840312156118fc57600080fd5b5035919050565b60008083601f84011261191557600080fd5b50813567ffffffffffffffff81111561192d57600080fd5b6020830191508360208260051b850101111561182b57600080fd5b6000806020838503121561195b57600080fd5b823567ffffffffffffffff81111561197257600080fd5b61197e85828601611903565b90969095509350505050565b6000806000806000606086880312156119a257600080fd5b853567ffffffffffffffff808211156119ba57600080fd5b6119c689838a01611903565b90975095506020880135945060408801359150808211156119e657600080fd5b506119f3888289016117e9565b969995985093965092949392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215611a4557600080fd5b813567ffffffffffffffff80821115611a5d57600080fd5b818401915084601f830112611a7157600080fd5b813581811115611a8357611a83611a04565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715611ac957611ac9611a04565b81604052828152876020848701011115611ae257600080fd5b826020860160208301376000928101602001929092525095945050505050565b8183823760009101908152919050565b80358015158114611b2257600080fd5b919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611b2257600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b818352600060208085019450848460051b86018460005b87811015611cd357838303895281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff41883603018112611bea57600080fd5b870160c0611bf782611b12565b15158552611c06878301611b12565b15158588015260408281013590860152606073ffffffffffffffffffffffffffffffffffffffff611c38828501611b27565b16908601526080828101359086015260a080830135368490037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1018112611c7e57600080fd5b90920187810192903567ffffffffffffffff811115611c9c57600080fd5b803603841315611cab57600080fd5b8282880152611cbd8388018286611b4b565b9c89019c96505050928601925050600101611bab565b5090979650505050505050565b60408152600560408201527f73656c663a000000000000000000000000000000000000000000000000000000606082015260806020820152600061037b608083018486611b94565b60408152600660408201527f67756573743a0000000000000000000000000000000000000000000000000000606082015260806020820152600061037b608083018486611b94565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff41833603018112611dd357600080fd5b9190910192915050565b600060208284031215611def57600080fd5b61031782611b12565b600060208284031215611e0a57600080fd5b61031782611b27565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611e4857600080fd5b83018035915067ffffffffffffffff821115611e6357600080fd5b60200191503681900382131561182b57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611ed857611ed8611e78565b5060010190565b60008085851115611eef57600080fd5b83861115611efc57600080fd5b5050820193919092039150565b808201808211156102cb576102cb611e78565b606081526000611f30606083018688611b4b565b6020830194909452506040015292915050565b82815260006020604081840152835180604085015260005b81811015611f7757858101830151858201606001528201611f5b565b5060006060828601015260607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f830116850101925050509392505050565b84815273ffffffffffffffffffffffffffffffffffffffff84166020820152606060408201526000611fed606083018486611b4b565b9695505050505050565b60208152600061037b602083018486611b4b565b818103818111156102cb576102cb611e78565b604081526000612032604083018587611b4b565b9050826020830152949350505050565b604081526000612056604083018587611b4b565b905060ff83166020830152949350505050565b60608152600061207d606083018688611b4b565b60208301949094525090151560409091015292915050565b8381526040602082015260006120af604083018486611b4b565b95945050505050565b6000602082840312156120ca57600080fd5b81516103178161179e56fea264697066735822122075ce1ed9c453c8c833ec89aa2911db2e9a1e07c0a29fc3ed180acba619d449be64736f6c63430008110033', + deployedBytecode: + '0x6080604052600436106100bc5760003560e01c806361c2926c116100745780638c3f55631161004e5780638c3f55631461025357806390042baf14610273578063affed0e0146102ab57600080fd5b806361c2926c146101cb5780637a9a1628146101eb578063853c50681461020b57600080fd5b806320c13b0b116100a557806320c13b0b14610147578063295614261461016757806357c56d6b1461018957600080fd5b806301ffc9a7146100c15780631626ba7e146100f6575b600080fd5b3480156100cd57600080fd5b506100e16100dc3660046117cc565b6102c0565b60405190151581526020015b60405180910390f35b34801561010257600080fd5b50610116610111366004611832565b6102d1565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016100ed565b34801561015357600080fd5b5061011661016236600461187e565b61031e565b34801561017357600080fd5b506101876101823660046118ea565b610383565b005b34801561019557600080fd5b506101bd7f8713a7c4465f6fbee2b6e9d6646d1d9f83fec929edfc4baf661f3c865bdd04d181565b6040519081526020016100ed565b3480156101d757600080fd5b506101876101e6366004611948565b6103d5565b3480156101f757600080fd5b5061018761020636600461198a565b61041a565b34801561021757600080fd5b5061022b610226366004611832565b610447565b604080519586526020860194909452928401919091526060830152608082015260a0016100ed565b34801561025f57600080fd5b506101bd61026e3660046118ea565b61060f565b610286610281366004611a33565b61063b565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100ed565b3480156102b757600080fd5b506101bd6106d7565b60006102cb826106e8565b92915050565b6000806102df858585610744565b509050801561031157507f1626ba7e000000000000000000000000000000000000000000000000000000009050610317565b50600090505b9392505050565b6000806103438686604051610334929190611b02565b60405180910390208585610744565b509050801561037557507f20c13b0b00000000000000000000000000000000000000000000000000000000905061037b565b50600090505b949350505050565b3330146103c9576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044015b60405180910390fd5b6103d28161077c565b50565b600061040883836040516020016103ed929190611ce0565b604051602081830303815290604052805190602001206107ae565b9050610415818484610833565b505050565b600061043286866040516020016103ed929190611d28565b905061043f818787610833565b505050505050565b6000806000806000808787600081811061046357610463611d70565b909101357fff000000000000000000000000000000000000000000000000000000000000001691508190506104b95761049b896107ae565b92506104a8838989610996565b929850909650945091506106049050565b7fff00000000000000000000000000000000000000000000000000000000000000818116016104f8576104eb896107ae565b92506104a88389896109e7565b7ffe000000000000000000000000000000000000000000000000000000000000007fff0000000000000000000000000000000000000000000000000000000000000082160161054a576104eb89610a13565b7ffd000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216016105ae5761059e898989610a80565b9550955095509550955050610604565b6040517f6085cd820000000000000000000000000000000000000000000000000000000081527fff00000000000000000000000000000000000000000000000000000000000000821660048201526024016103c0565b939792965093509350565b60006102cb7f8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e83610bfd565b600033301461067e576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044016103c0565b81516020830134f060405173ffffffffffffffffffffffffffffffffffffffff821681529091507fa506ad4e7f05eceba62a023c3219e5bd98a615f4fa87e2afb08a2da5cf62bf0c9060200160405180910390a1919050565b60006106e3600061060f565b905090565b60007f6ffbd451000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083160161073b57506001919050565b6102cb82610c5b565b6000806000806000610757888888610447565b5096509194509250905082821080159061076f575060015b9450505050935093915050565b6040517fa038794000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f190100000000000000000000000000000000000000000000000000000000000060208201524660228201527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b166042820152605681018290526000906076015b604051602081830303815290604052805190602001209050919050565b8060005b8181101561098f573684848381811061085257610852611d70565b90506020028101906108649190611d9f565b90506108736020820182611ddd565b156108ad576040517f230d1ccc000000000000000000000000000000000000000000000000000000008152600481018390526024016103c0565b6040810135805a10156109005782815a6040517f2bb3e3ba0000000000000000000000000000000000000000000000000000000081526004810193909352602483019190915260448201526064016103c0565b600061093a6109156080850160608601611df8565b608085013584156109265784610928565b5a5b61093560a0880188611e13565b610cb7565b905080156109585760405188815260200160405180910390a0610979565b61097961096b6040850160208601611ddd565b89610974610cd4565b610cf3565b505050808061098790611ea7565b915050610837565b5050505050565b60008080806109b1876109ac876006818b611edf565b610d3f565b6000908152873560f01c6020818152604080842084526002909a013560e01c908190529890912090999198509695509350505050565b6000808080610a02876109fd876001818b611edf565b610996565b935093509350935093509350935093565b6040517f190100000000000000000000000000000000000000000000000000000000000060208201526000602282018190527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b1660428301526056820183905290607601610816565b6000808080806004600188013560e81c82610a9b8383611f09565b9050610aad8b61022683868d8f611edf565b939b5091995097509550935087871015610b0557610acd81848b8d611edf565b89896040517fb006aba00000000000000000000000000000000000000000000000000000000081526004016103c09493929190611f1c565b8092505b88831015610bef5760038301928a013560e81c9150610b288383611f09565b90506000610b4a610b38886111d5565b8c8c8790869261022693929190611edf565b939c50919a5098509091505088881015610ba257610b6a82858c8e611edf565b8a8a6040517fb006aba00000000000000000000000000000000000000000000000000000000081526004016103c09493929190611f1c565b848110610be5576040517f37daf62b00000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016103c0565b9350915081610b09565b505050939792965093509350565b6000808383604051602001610c1c929190918252602082015260400190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052805160209091012054949350505050565b60007fe4a77bbc000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831601610cae57506001919050565b6102cb82611209565b6000604051828482376000808483898b8af1979650505050505050565b60603d604051915060208201818101604052818352816000823e505090565b8215610d0157805160208201fd5b7f3dbd1590ea96dd3253a91f24e64e3a502e1225d602a5731357bc12643070ccd78282604051610d32929190611f43565b60405180910390a1505050565b60008060005b838110156111cc57600181019085013560f81c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8101610de657601582019186013560f881901c9060581c73ffffffffffffffffffffffffffffffffffffffff81169074ff000000000000000000000000000000000000000016811785610dcc5780610ddb565b60008681526020829052604090205b955050505050610d45565b80610e7c5760018201918681013560f81c906043016000610e128a610e0d84888c8e611edf565b6112f3565b60ff841697909701969194508491905060a083901b74ff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff82161786610e615780610e70565b60008781526020829052604090205b96505050505050610d45565b60028103610fa4576000808784013560f881901c9060581c73ffffffffffffffffffffffffffffffffffffffff16601586019550909250905060008885013560e81c600386018162ffffff169150809650819250505060008186019050610ef58b848c8c8a908692610ef093929190611edf565b6115b6565b610f3d578a83610f0783898d8f611edf565b6040517f9a9462320000000000000000000000000000000000000000000000000000000081526004016103c09493929190611fb7565b60ff8416979097019694508460a084901b74ff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84161787610f885780610f97565b60008881526020829052604090205b9750505050505050610d45565b60038103610fd757602082019186013583610fbf5780610fce565b60008481526020829052604090205b93505050610d45565b60048103611023576003808301928781013560e81c91908201016000806110048b6109ac85898d8f611edf565b60009889526020526040909720969097019650909350610d4592505050565b6006810361112b5760008287013560f81c60018401935060ff16905060008784013560f01c60028501945061ffff16905060008885013560e81c600386018162ffffff1691508096508192505050600081860190506000806110918d8d8d8b9087926109ac93929190611edf565b939850889390925090508482106110a757988501985b604080517f53657175656e6365206e657374656420636f6e6669673a0a0000000000000000602080830191909152603882018490526058820188905260788083018a905283518084039091018152609890920190925280519101208961110d578061111c565b60008a81526020829052604090205b99505050505050505050610d45565b60058103611197576020820191860135878103611166577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff94505b600061117182611763565b90508461117e578061118d565b60008581526020829052604090205b9450505050610d45565b6040517fb2505f7c000000000000000000000000000000000000000000000000000000008152600481018290526024016103c0565b50935093915050565b7f8713a7c4465f6fbee2b6e9d6646d1d9f83fec929edfc4baf661f3c865bdd04d160009081526020829052604081206102cb565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fac6a444e00000000000000000000000000000000000000000000000000000000148061129c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f36e7817500000000000000000000000000000000000000000000000000000000145b156112a957506001919050565b7f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316146102cb565b6000604282146113335782826040517f2ee17a3d0000000000000000000000000000000000000000000000000000000081526004016103c0929190611ff7565b600061134c61134360018561200b565b85013560f81c90565b60ff169050604084013560f81c843560208601357f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08111156113c0578686826040517fad4aac760000000000000000000000000000000000000000000000000000000081526004016103c09392919061201e565b8260ff16601b141580156113d857508260ff16601c14155b15611415578686846040517fe578897e0000000000000000000000000000000000000000000000000000000081526004016103c093929190612042565b60018403611482576040805160008152602081018083528a905260ff851691810191909152606081018390526080810182905260019060a0015b6020604051602081039080840390855afa158015611471573d6000803e3d6000fd5b50505060206040510351945061155a565b6002840361151f576040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101899052600190605c01604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600084529083018083525260ff861690820152606081018490526080810183905260a00161144f565b86868560016040517f9dfba8520000000000000000000000000000000000000000000000000000000081526004016103c09493929190612069565b73ffffffffffffffffffffffffffffffffffffffff85166115ab5786866040517f6c1719d20000000000000000000000000000000000000000000000000000000081526004016103c0929190611ff7565b505050509392505050565b60008083836115c660018261200b565b8181106115d5576115d5611d70565b919091013560f81c91505060018114806115ef5750600281145b15611634578473ffffffffffffffffffffffffffffffffffffffff166116168786866112f3565b73ffffffffffffffffffffffffffffffffffffffff1614915061175a565b6003810361171f5773ffffffffffffffffffffffffffffffffffffffff8516631626ba7e878660008761166860018261200b565b9261167593929190611edf565b6040518463ffffffff1660e01b815260040161169393929190612095565b602060405180830381865afa1580156116b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116d491906120b8565b7fffffffff00000000000000000000000000000000000000000000000000000000167f1626ba7e0000000000000000000000000000000000000000000000000000000014915061175a565b83838260006040517f9dfba8520000000000000000000000000000000000000000000000000000000081526004016103c09493929190612069565b50949350505050565b6040517f53657175656e636520737461746963206469676573743a0a0000000000000000602082015260388101829052600090605801610816565b7fffffffff00000000000000000000000000000000000000000000000000000000811681146103d257600080fd5b6000602082840312156117de57600080fd5b81356103178161179e565b60008083601f8401126117fb57600080fd5b50813567ffffffffffffffff81111561181357600080fd5b60208301915083602082850101111561182b57600080fd5b9250929050565b60008060006040848603121561184757600080fd5b83359250602084013567ffffffffffffffff81111561186557600080fd5b611871868287016117e9565b9497909650939450505050565b6000806000806040858703121561189457600080fd5b843567ffffffffffffffff808211156118ac57600080fd5b6118b8888389016117e9565b909650945060208701359150808211156118d157600080fd5b506118de878288016117e9565b95989497509550505050565b6000602082840312156118fc57600080fd5b5035919050565b60008083601f84011261191557600080fd5b50813567ffffffffffffffff81111561192d57600080fd5b6020830191508360208260051b850101111561182b57600080fd5b6000806020838503121561195b57600080fd5b823567ffffffffffffffff81111561197257600080fd5b61197e85828601611903565b90969095509350505050565b6000806000806000606086880312156119a257600080fd5b853567ffffffffffffffff808211156119ba57600080fd5b6119c689838a01611903565b90975095506020880135945060408801359150808211156119e657600080fd5b506119f3888289016117e9565b969995985093965092949392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215611a4557600080fd5b813567ffffffffffffffff80821115611a5d57600080fd5b818401915084601f830112611a7157600080fd5b813581811115611a8357611a83611a04565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715611ac957611ac9611a04565b81604052828152876020848701011115611ae257600080fd5b826020860160208301376000928101602001929092525095945050505050565b8183823760009101908152919050565b80358015158114611b2257600080fd5b919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611b2257600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b818352600060208085019450848460051b86018460005b87811015611cd357838303895281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff41883603018112611bea57600080fd5b870160c0611bf782611b12565b15158552611c06878301611b12565b15158588015260408281013590860152606073ffffffffffffffffffffffffffffffffffffffff611c38828501611b27565b16908601526080828101359086015260a080830135368490037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1018112611c7e57600080fd5b90920187810192903567ffffffffffffffff811115611c9c57600080fd5b803603841315611cab57600080fd5b8282880152611cbd8388018286611b4b565b9c89019c96505050928601925050600101611bab565b5090979650505050505050565b60408152600560408201527f73656c663a000000000000000000000000000000000000000000000000000000606082015260806020820152600061037b608083018486611b94565b60408152600660408201527f67756573743a0000000000000000000000000000000000000000000000000000606082015260806020820152600061037b608083018486611b94565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff41833603018112611dd357600080fd5b9190910192915050565b600060208284031215611def57600080fd5b61031782611b12565b600060208284031215611e0a57600080fd5b61031782611b27565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611e4857600080fd5b83018035915067ffffffffffffffff821115611e6357600080fd5b60200191503681900382131561182b57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611ed857611ed8611e78565b5060010190565b60008085851115611eef57600080fd5b83861115611efc57600080fd5b5050820193919092039150565b808201808211156102cb576102cb611e78565b606081526000611f30606083018688611b4b565b6020830194909452506040015292915050565b82815260006020604081840152835180604085015260005b81811015611f7757858101830151858201606001528201611f5b565b5060006060828601015260607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f830116850101925050509392505050565b84815273ffffffffffffffffffffffffffffffffffffffff84166020820152606060408201526000611fed606083018486611b4b565b9695505050505050565b60208152600061037b602083018486611b4b565b818103818111156102cb576102cb611e78565b604081526000612032604083018587611b4b565b9050826020830152949350505050565b604081526000612056604083018587611b4b565b905060ff83166020830152949350505050565b60608152600061207d606083018688611b4b565b60208301949094525090151560409091015292915050565b8381526040602082015260006120af604083018486611b4b565b95945050505050565b6000602082840312156120ca57600080fd5b81516103178161179e56fea264697066735822122075ce1ed9c453c8c833ec89aa2911db2e9a1e07c0a29fc3ed180acba619d449be64736f6c63430008110033', + linkReferences: {}, + deployedLinkReferences: {} +} diff --git a/packages/tests/src/builds/v2/artifacts/MainModule.ts b/packages/tests/src/builds/v2/artifacts/MainModule.ts new file mode 100644 index 0000000000..52602897db --- /dev/null +++ b/packages/tests/src/builds/v2/artifacts/MainModule.ts @@ -0,0 +1,1104 @@ +export const mainModule = { + _format: 'hh-sol-artifact-1', + contractName: 'MainModule', + sourceName: 'contracts/modules/MainModule.sol', + abi: [ + { + inputs: [ + { + internalType: 'address', + name: '_factory', + type: 'address' + }, + { + internalType: 'address', + name: '_mainModuleUpgradable', + type: 'address' + } + ], + stateMutability: 'nonpayable', + type: 'constructor' + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_space', + type: 'uint256' + }, + { + internalType: 'uint256', + name: '_provided', + type: 'uint256' + }, + { + internalType: 'uint256', + name: '_current', + type: 'uint256' + } + ], + name: 'BadNonce', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes4', + name: '_signature', + type: 'bytes4' + } + ], + name: 'HookAlreadyExists', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes4', + name: '_signature', + type: 'bytes4' + } + ], + name: 'HookDoesNotExist', + type: 'error' + }, + { + inputs: [], + name: 'ImageHashIsZero', + type: 'error' + }, + { + inputs: [ + { + internalType: 'address', + name: '_implementation', + type: 'address' + } + ], + name: 'InvalidImplementation', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_hash', + type: 'bytes32' + }, + { + internalType: 'address', + name: '_addr', + type: 'address' + }, + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + } + ], + name: 'InvalidNestedSignature', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + }, + { + internalType: 'bytes32', + name: '_s', + type: 'bytes32' + } + ], + name: 'InvalidSValue', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_hash', + type: 'bytes32' + }, + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + } + ], + name: 'InvalidSignature', + type: 'error' + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_flag', + type: 'uint256' + } + ], + name: 'InvalidSignatureFlag', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + } + ], + name: 'InvalidSignatureLength', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes1', + name: '_type', + type: 'bytes1' + } + ], + name: 'InvalidSignatureType', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + }, + { + internalType: 'uint256', + name: '_v', + type: 'uint256' + } + ], + name: 'InvalidVValue', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + }, + { + internalType: 'uint256', + name: 'threshold', + type: 'uint256' + }, + { + internalType: 'uint256', + name: '_weight', + type: 'uint256' + } + ], + name: 'LowWeightChainedSignature', + type: 'error' + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_index', + type: 'uint256' + }, + { + internalType: 'uint256', + name: '_requested', + type: 'uint256' + }, + { + internalType: 'uint256', + name: '_available', + type: 'uint256' + } + ], + name: 'NotEnoughGas', + type: 'error' + }, + { + inputs: [ + { + internalType: 'address', + name: '_sender', + type: 'address' + }, + { + internalType: 'address', + name: '_self', + type: 'address' + } + ], + name: 'OnlySelfAuth', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + } + ], + name: 'SignerIsAddress0', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + }, + { + internalType: 'uint256', + name: '_type', + type: 'uint256' + }, + { + internalType: 'bool', + name: '_recoverMode', + type: 'bool' + } + ], + name: 'UnsupportedSignatureType', + type: 'error' + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_current', + type: 'uint256' + }, + { + internalType: 'uint256', + name: '_prev', + type: 'uint256' + } + ], + name: 'WrongChainedCheckpointOrder', + type: 'error' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: '_contract', + type: 'address' + } + ], + name: 'CreatedContract', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'bytes32', + name: '_hash', + type: 'bytes32' + } + ], + name: 'IPFSRootUpdated', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'bytes32', + name: 'newImageHash', + type: 'bytes32' + } + ], + name: 'ImageHashUpdated', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'newImplementation', + type: 'address' + } + ], + name: 'ImplementationUpdated', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: '_space', + type: 'uint256' + }, + { + indexed: false, + internalType: 'uint256', + name: '_newNonce', + type: 'uint256' + } + ], + name: 'NonceChange', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'bytes32', + name: '_imageHash', + type: 'bytes32' + }, + { + indexed: false, + internalType: 'uint256', + name: '_expiration', + type: 'uint256' + } + ], + name: 'SetExtraImageHash', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'bytes32', + name: '_digest', + type: 'bytes32' + }, + { + indexed: false, + internalType: 'uint256', + name: '_expiration', + type: 'uint256' + } + ], + name: 'SetStaticDigest', + type: 'event' + }, + { + anonymous: true, + inputs: [ + { + indexed: false, + internalType: 'bytes32', + name: '_tx', + type: 'bytes32' + } + ], + name: 'TxExecuted', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'bytes32', + name: '_tx', + type: 'bytes32' + }, + { + indexed: false, + internalType: 'bytes', + name: '_reason', + type: 'bytes' + } + ], + name: 'TxFailed', + type: 'event' + }, + { + stateMutability: 'payable', + type: 'fallback' + }, + { + inputs: [], + name: 'FACTORY', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'INIT_CODE_HASH', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'SET_IMAGE_HASH_TYPE_HASH', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'UPGRADEABLE_IMPLEMENTATION', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes4', + name: '_signature', + type: 'bytes4' + }, + { + internalType: 'address', + name: '_implementation', + type: 'address' + } + ], + name: 'addHook', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32[]', + name: '_digests', + type: 'bytes32[]' + } + ], + name: 'addStaticDigests', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32[]', + name: '_imageHashes', + type: 'bytes32[]' + } + ], + name: 'clearExtraImageHashes', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_code', + type: 'bytes' + } + ], + name: 'createContract', + outputs: [ + { + internalType: 'address', + name: 'addr', + type: 'address' + } + ], + stateMutability: 'payable', + type: 'function' + }, + { + inputs: [ + { + components: [ + { + internalType: 'bool', + name: 'delegateCall', + type: 'bool' + }, + { + internalType: 'bool', + name: 'revertOnError', + type: 'bool' + }, + { + internalType: 'uint256', + name: 'gasLimit', + type: 'uint256' + }, + { + internalType: 'address', + name: 'target', + type: 'address' + }, + { + internalType: 'uint256', + name: 'value', + type: 'uint256' + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes' + } + ], + internalType: 'struct IModuleCalls.Transaction[]', + name: '_txs', + type: 'tuple[]' + }, + { + internalType: 'uint256', + name: '_nonce', + type: 'uint256' + }, + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + } + ], + name: 'execute', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_imageHash', + type: 'bytes32' + } + ], + name: 'extraImageHash', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'ipfsRoot', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'ipfsRootBytes32', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_hash', + type: 'bytes32' + }, + { + internalType: 'bytes', + name: '_signatures', + type: 'bytes' + } + ], + name: 'isValidSignature', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_data', + type: 'bytes' + }, + { + internalType: 'bytes', + name: '_signatures', + type: 'bytes' + } + ], + name: 'isValidSignature', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'nonce', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]' + }, + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]' + }, + { + internalType: 'bytes', + name: '', + type: 'bytes' + } + ], + name: 'onERC1155BatchReceived', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'uint256', + name: '', + type: 'uint256' + }, + { + internalType: 'uint256', + name: '', + type: 'uint256' + }, + { + internalType: 'bytes', + name: '', + type: 'bytes' + } + ], + name: 'onERC1155Received', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'uint256', + name: '', + type: 'uint256' + }, + { + internalType: 'bytes', + name: '', + type: 'bytes' + } + ], + name: 'onERC721Received', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes4', + name: '_signature', + type: 'bytes4' + } + ], + name: 'readHook', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_space', + type: 'uint256' + } + ], + name: 'readNonce', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes4', + name: '_signature', + type: 'bytes4' + } + ], + name: 'removeHook', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + components: [ + { + internalType: 'bool', + name: 'delegateCall', + type: 'bool' + }, + { + internalType: 'bool', + name: 'revertOnError', + type: 'bool' + }, + { + internalType: 'uint256', + name: 'gasLimit', + type: 'uint256' + }, + { + internalType: 'address', + name: 'target', + type: 'address' + }, + { + internalType: 'uint256', + name: 'value', + type: 'uint256' + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes' + } + ], + internalType: 'struct IModuleCalls.Transaction[]', + name: '_txs', + type: 'tuple[]' + } + ], + name: 'selfExecute', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_imageHash', + type: 'bytes32' + }, + { + internalType: 'uint256', + name: '_expiration', + type: 'uint256' + } + ], + name: 'setExtraImageHash', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_digest', + type: 'bytes32' + }, + { + internalType: 'uint256', + name: '_expiration', + type: 'uint256' + } + ], + name: 'setStaticDigest', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_digest', + type: 'bytes32' + }, + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + } + ], + name: 'signatureRecovery', + outputs: [ + { + internalType: 'uint256', + name: 'threshold', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'weight', + type: 'uint256' + }, + { + internalType: 'bytes32', + name: 'imageHash', + type: 'bytes32' + }, + { + internalType: 'bytes32', + name: 'subDigest', + type: 'bytes32' + }, + { + internalType: 'uint256', + name: 'checkpoint', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_digest', + type: 'bytes32' + } + ], + name: 'staticDigest', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes4', + name: '_interfaceID', + type: 'bytes4' + } + ], + name: 'supportsInterface', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool' + } + ], + stateMutability: 'pure', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_hash', + type: 'bytes32' + } + ], + name: 'updateIPFSRoot', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_imageHash', + type: 'bytes32' + } + ], + name: 'updateImageHash', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_imageHash', + type: 'bytes32' + }, + { + internalType: 'bytes32', + name: '_ipfsRoot', + type: 'bytes32' + } + ], + name: 'updateImageHashAndIPFS', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '_implementation', + type: 'address' + } + ], + name: 'updateImplementation', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + stateMutability: 'payable', + type: 'receive' + } + ], + bytecode: + '0x60e06040523480156200001157600080fd5b5060405162003b9e38038062003b9e8339810160408190526200003491620000ba565b8181600060405180606001604052806028815260200162003b76602891396040516200006691903090602001620000f2565b60408051601f198184030181529190528051602090910120608052506001600160a01b0391821660a0521660c05250620001269050565b80516001600160a01b0381168114620000b557600080fd5b919050565b60008060408385031215620000ce57600080fd5b620000d9836200009d565b9150620000e9602084016200009d565b90509250929050565b6000835160005b81811015620001155760208187018101518583015201620000f9565b509190910191825250602001919050565b60805160a05160c051613a0b6200016b6000396000818161060b015261171f01526000818161049b0152612ca30152600081816104390152612cd40152613a0b6000f3fe6080604052600436106101dc5760003560e01c806379e472c911610102578063a4ab5f9f11610095578063c71f1f9611610064578063c71f1f961461073f578063d0748f7114610754578063d59f788514610774578063f23a6e6114610794576101e3565b8063a4ab5f9f146106a2578063affed0e0146106c2578063b93ea7ad146106d7578063bc197c81146106f7576101e3565b80638c3f5563116100d15780638c3f55631461062d5780638efa64411461064d57806390042baf1461066f578063a38cef1914610682576101e3565b806379e472c9146105715780637a9a162814610591578063853c5068146105b1578063888eeec6146105f9576101e3565b8063257671f51161017a5780634598154f116101495780634598154f146104dd5780634fcf3eca146104fd57806357c56d6b1461051d57806361c2926c14610551576101e3565b8063257671f51461042757806329561426146104695780632dd310001461048957806341ea0302146104bd576101e3565b8063150b7a02116101b6578063150b7a021461032c5780631626ba7e146103a25780631a9b2337146103c257806320c13b0b14610407576101e3565b806301ffc9a7146102b7578063025b22bc146102ec578063038dbaac1461030c576101e3565b366101e357005b60006102126000357fffffffff00000000000000000000000000000000000000000000000000000000166107da565b905073ffffffffffffffffffffffffffffffffffffffff8116156102b5576000808273ffffffffffffffffffffffffffffffffffffffff1660003660405161025b929190612e69565b600060405180830381855af49150503d8060008114610296576040519150601f19603f3d011682016040523d82523d6000602084013e61029b565b606091505b5091509150816102ad57805160208201fd5b805160208201f35b005b3480156102c357600080fd5b506102d76102d2366004612ea7565b61082e565b60405190151581526020015b60405180910390f35b3480156102f857600080fd5b506102b5610307366004612eed565b610839565b34801561031857600080fd5b506102b5610327366004612f54565b61088b565b34801561033857600080fd5b50610371610347366004612fd8565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016102e3565b3480156103ae57600080fd5b506103716103bd366004613047565b610996565b3480156103ce57600080fd5b506103e26103dd366004612ea7565b6109e3565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102e3565b34801561041357600080fd5b50610371610422366004613093565b6109ee565b34801561043357600080fd5b5061045b7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020016102e3565b34801561047557600080fd5b506102b56104843660046130ff565b610a53565b34801561049557600080fd5b506103e27f000000000000000000000000000000000000000000000000000000000000000081565b3480156104c957600080fd5b5061045b6104d83660046130ff565b610a9d565b3480156104e957600080fd5b506102b56104f8366004613118565b610aa8565b34801561050957600080fd5b506102b5610518366004612ea7565b610b6e565b34801561052957600080fd5b5061045b7f8713a7c4465f6fbee2b6e9d6646d1d9f83fec929edfc4baf661f3c865bdd04d181565b34801561055d57600080fd5b506102b561056c366004612f54565b610c9d565b34801561057d57600080fd5b506102b561058c366004613118565b610d23565b34801561059d57600080fd5b506102b56105ac36600461313a565b610de1565b3480156105bd57600080fd5b506105d16105cc366004613047565b610e77565b604080519586526020860194909452928401919091526060830152608082015260a0016102e3565b34801561060557600080fd5b506103e27f000000000000000000000000000000000000000000000000000000000000000081565b34801561063957600080fd5b5061045b6106483660046130ff565b61103f565b34801561065957600080fd5b5061066261106b565b6040516102e39190613211565b6103e261067d366004613253565b6110ec565b34801561068e57600080fd5b506102b561069d3660046130ff565b611188565b3480156106ae57600080fd5b5061045b6106bd3660046130ff565b6111d2565b3480156106ce57600080fd5b5061045b6111dd565b3480156106e357600080fd5b506102b56106f2366004613322565b6111ee565b34801561070357600080fd5b50610371610712366004613357565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b34801561074b57600080fd5b5061045b611337565b34801561076057600080fd5b506102b561076f366004613118565b611361565b34801561078057600080fd5b506102b561078f366004612f54565b6113b4565b3480156107a057600080fd5b506103716107af366004613412565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b60006108287fbe27a319efc8734e89e26ba4bc95f5c788584163b959f03fa04e2d7ab4b9a1207fffffffff0000000000000000000000000000000000000000000000000000000084166114f7565b92915050565b600061082882611555565b33301461087f576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044015b60405180910390fd5b610888816115b1565b50565b3330146108cc576040517fe1258894000000000000000000000000000000000000000000000000000000008152336004820152306024820152604401610876565b8060005b818110156109905760008484838181106108ec576108ec61348a565b90506020020135905061094c816000604080517f849e7bdc245db17e50b9f43086f1914d70eb4dab6dd89af4d541d53353ad97de602080830191909152818301859052825180830384018152606090920190925280519101208190555050565b807f804f6171d6008d9e16ee3aa0561fec328397f4ba2827a6605db388cfdefa3b0c600060405161097f91815260200190565b60405180910390a2506001016108d0565b50505050565b6000806109a485858561166c565b50905080156109d657507f1626ba7e0000000000000000000000000000000000000000000000000000000090506109dc565b50600090505b9392505050565b6000610828826107da565b600080610a138686604051610a04929190612e69565b6040518091039020858561166c565b5090508015610a4557507f20c13b0b000000000000000000000000000000000000000000000000000000009050610a4b565b50600090505b949350505050565b333014610a94576040517fe1258894000000000000000000000000000000000000000000000000000000008152336004820152306024820152604401610876565b61088881611687565b600061082882611743565b333014610ae9576040517fe1258894000000000000000000000000000000000000000000000000000000008152336004820152306024820152604401610876565b604080517f849e7bdc245db17e50b9f43086f1914d70eb4dab6dd89af4d541d53353ad97de602080830191909152818301859052825180830384018152606083019384905280519101208390559082905282907f804f6171d6008d9e16ee3aa0561fec328397f4ba2827a6605db388cfdefa3b0c906080015b60405180910390a25050565b333014610baf576040517fe1258894000000000000000000000000000000000000000000000000000000008152336004820152306024820152604401610876565b6000610bba826107da565b73ffffffffffffffffffffffffffffffffffffffff1603610c2b576040517f1c3812cc0000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000082166004820152602401610876565b604080517fbe27a319efc8734e89e26ba4bc95f5c788584163b959f03fa04e2d7ab4b9a1206020808301919091527fffffffff00000000000000000000000000000000000000000000000000000000841682840152825180830384018152606090920190925280519101206000905550565b333014610cde576040517fe1258894000000000000000000000000000000000000000000000000000000008152336004820152306024820152604401610876565b6000610d118383604051602001610cf6929190613661565b6040516020818303038152906040528051906020012061176f565b9050610d1e8184846117f4565b505050565b333014610d64576040517fe1258894000000000000000000000000000000000000000000000000000000008152336004820152306024820152604401610876565b604080517f7f25a23abc421d10864063e9a8ae5fd3fbd5116e156f148428b6a3a02ffd9454602080830191909152818301859052825180830384018152606083019384905280519101208390559082905282907f180e56184e3025975e8449fab79ff135cc5c3b3fe517a19bf8f111d69b33d2e290608001610b62565b610dea83611952565b600080610e22858888604051602001610e05939291906136a9565b60405160208183030381529060405280519060200120858561166c565b9150915081610e63578084846040517f8f4a234f000000000000000000000000000000000000000000000000000000008152600401610876939291906136cc565b610e6e8188886117f4565b50505050505050565b60008060008060008087876000818110610e9357610e9361348a565b909101357fff00000000000000000000000000000000000000000000000000000000000000169150819050610ee957610ecb8961176f565b9250610ed8838989611a4f565b929850909650945091506110349050565b7fff0000000000000000000000000000000000000000000000000000000000000081811601610f2857610f1b8961176f565b9250610ed8838989611aa0565b7ffe000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821601610f7a57610f1b89611acc565b7ffd000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821601610fde57610fce898989611b39565b9550955095509550955050611034565b6040517f6085cd820000000000000000000000000000000000000000000000000000000081527fff0000000000000000000000000000000000000000000000000000000000000082166004820152602401610876565b939792965093509350565b60006108287f8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e836114f7565b60606110c86110c361107b611337565b6040517f017012200000000000000000000000000000000000000000000000000000000060208201526024810191909152604401604051602081830303815290604052611cb6565b611ecf565b6040516020016110d891906136e6565b604051602081830303815290604052905090565b600033301461112f576040517fe1258894000000000000000000000000000000000000000000000000000000008152336004820152306024820152604401610876565b81516020830134f060405173ffffffffffffffffffffffffffffffffffffffff821681529091507fa506ad4e7f05eceba62a023c3219e5bd98a615f4fa87e2afb08a2da5cf62bf0c9060200160405180910390a1919050565b3330146111c9576040517fe1258894000000000000000000000000000000000000000000000000000000008152336004820152306024820152604401610876565b61088881611ef8565b600061082882611f51565b60006111e9600061103f565b905090565b33301461122f576040517fe1258894000000000000000000000000000000000000000000000000000000008152336004820152306024820152604401610876565b600061123a836107da565b73ffffffffffffffffffffffffffffffffffffffff16146112ab576040517f5b4d6d6a0000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000083166004820152602401610876565b604080517fbe27a319efc8734e89e26ba4bc95f5c788584163b959f03fa04e2d7ab4b9a1206020808301919091527fffffffff000000000000000000000000000000000000000000000000000000008516828401528251808303840181526060909201909252805191012073ffffffffffffffffffffffffffffffffffffffff821690555050565b5050565b60006111e97f0eecac93ced8722d209199364cda3bc33da3bc3a23daef6be49ebd780511d0335490565b3330146113a2576040517fe1258894000000000000000000000000000000000000000000000000000000008152336004820152306024820152604401610876565b6113ab82611687565b61133381611ef8565b3330146113f5576040517fe1258894000000000000000000000000000000000000000000000000000000008152336004820152306024820152604401610876565b8060005b818110156109905760008484838181106114155761141561348a565b905060200201359050611494817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff604080517f7f25a23abc421d10864063e9a8ae5fd3fbd5116e156f148428b6a3a02ffd9454602080830191909152818301859052825180830384018152606090920190925280519101208190555050565b807f180e56184e3025975e8449fab79ff135cc5c3b3fe517a19bf8f111d69b33d2e27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6040516114e691815260200190565b60405180910390a2506001016113f9565b6000808383604051602001611516929190918252602082015260400190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052805160209091012054949350505050565b60007f6ffbd451000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316016115a857506001919050565b61082882611f7d565b73ffffffffffffffffffffffffffffffffffffffff81163b611617576040517f0c76093700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610876565b61161f813055565b60405173ffffffffffffffffffffffffffffffffffffffff821681527f310ba5f1d2ed074b51e2eccd052a47ae9ab7c6b800d1fca3db3999d6a592ca03906020015b60405180910390a150565b60008061167a8585856120be565b915091505b935093915050565b806116be576040517f4294d12700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116e77fea7157fa25e3aa17d0ae2d5280fa4e24d421c61842aa85e45194e1145aa72bf8829055565b6040518181527f307ed6bd941ee9fc80f369c94af5fa11e25bab5102a6140191756c5474a30bfa9060200160405180910390a16108887f00000000000000000000000000000000000000000000000000000000000000006115b1565b60006108287f7f25a23abc421d10864063e9a8ae5fd3fbd5116e156f148428b6a3a02ffd9454836114f7565b6040517f190100000000000000000000000000000000000000000000000000000000000060208201524660228201527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b166042820152605681018290526000906076015b604051602081830303815290604052805190602001209050919050565b8060005b8181101561194b57368484838181106118135761181361348a565b9050602002810190611825919061372b565b90506040810135805a101561187a5782815a6040517f2bb3e3ba000000000000000000000000000000000000000000000000000000008152600481019390935260248301919091526044820152606401610876565b60006118896020840184613769565b156118c8576118c16118a16080850160608601612eed565b83156118ad57836118af565b5a5b6118bc60a0870187613784565b6120f2565b9050611903565b6119006118db6080850160608601612eed565b608085013584156118ec57846118ee565b5a5b6118fb60a0880188613784565b61210d565b90505b801561191f5760405188815260200160405180910390a0611940565b6119406119326040850160208601613769565b8961193b61212a565b612149565b5050506001016117f8565b5050505050565b606081901c6bffffffffffffffffffffffff821660006119718361103f565b90508181146119bd576040517f9b6514f4000000000000000000000000000000000000000000000000000000008152600481018490526024810183905260448101829052606401610876565b604080517f8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e60208083019190915281830186905282518083038401815260609092019092528051910120600183019081905560408051858152602081018390527f1f180c27086c7a39ea2a7b25239d1ab92348f07ca7bb59d1438fcf527568f881910160405180910390a15050505050565b6000808080611a6a87611a65876006818b6137e9565b612195565b6000908152873560f01c6020818152604080842084526002909a013560e01c908190529890912090999198509695509350505050565b6000808080611abb87611ab6876001818b6137e9565b611a4f565b935093509350935093509350935093565b6040517f190100000000000000000000000000000000000000000000000000000000000060208201526000602282018190527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b16604283015260568201839052906076016117d7565b6000808080806004600188013560e81c82611b548383613842565b9050611b668b6105cc83868d8f6137e9565b939b5091995097509550935087871015611bbe57611b8681848b8d6137e9565b89896040517fb006aba00000000000000000000000000000000000000000000000000000000081526004016108769493929190613855565b8092505b88831015611ca85760038301928a013560e81c9150611be18383613842565b90506000611c03611bf18861262b565b8c8c879086926105cc939291906137e9565b939c50919a5098509091505088881015611c5b57611c2382858c8e6137e9565b8a8a6040517fb006aba00000000000000000000000000000000000000000000000000000000081526004016108769493929190613855565b848110611c9e576040517f37daf62b0000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610876565b9350915081611bc2565b505050939792965093509350565b8051606090600381901b60006005600483010467ffffffffffffffff811115611ce157611ce1613224565b6040519080825280601f01601f191660200182016040528015611d0b576020820181803683370190505b5090506000806000805b86811015611e1f57888181518110611d2f57611d2f61348a565b01602001516008948501949390931b60f89390931c92909217915b60058410611e17576040805180820190915260208082527f6162636465666768696a6b6c6d6e6f707172737475767778797a323334353637818301527ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb90950194601f85871c16908110611dc057611dc061348a565b602001015160f81c60f81b858381518110611ddd57611ddd61348a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600190910190611d4a565b600101611d15565b508215611ec3576040518060400160405280602081526020017f6162636465666768696a6b6c6d6e6f707172737475767778797a3233343536378152508360050383901b601f1681518110611e7657611e7661348a565b602001015160f81c60f81b848281518110611e9357611e9361348a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505b50919695505050505050565b606081604051602001611ee2919061387c565b6040516020818303038152906040529050919050565b611f217f0eecac93ced8722d209199364cda3bc33da3bc3a23daef6be49ebd780511d033829055565b6040518181527f20d3ef1b5738a9f6d7beae515432206e7a8e2740ca6dcf46a952190ad01bcb5190602001611661565b60006108287f849e7bdc245db17e50b9f43086f1914d70eb4dab6dd89af4d541d53353ad97de836114f7565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fec6aba5000000000000000000000000000000000000000000000000000000000148061201057507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b8061205c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b806120a857507fffffffff0000000000000000000000000000000000000000000000000000000082167fc0ee0b8a00000000000000000000000000000000000000000000000000000000145b156120b557506001919050565b6108288261265f565b600080426120cb86611743565b11915081156120e757816120de866126bb565b9150915061167f565b61167a8585856126f6565b60006040518284823760008084838989f49695505050505050565b6000604051828482376000808483898b8af1979650505050505050565b60603d604051915060208201818101604052818352816000823e505090565b821561215757805160208201fd5b7f3dbd1590ea96dd3253a91f24e64e3a502e1225d602a5731357bc12643070ccd782826040516121889291906138c1565b60405180910390a1505050565b60008060005b8381101561262257600181019085013560f81c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810161223c57601582019186013560f881901c9060581c73ffffffffffffffffffffffffffffffffffffffff81169074ff0000000000000000000000000000000000000000168117856122225780612231565b60008681526020829052604090205b95505050505061219b565b806122d25760018201918681013560f81c9060430160006122688a61226384888c8e6137e9565b612734565b60ff841697909701969194508491905060a083901b74ff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff821617866122b757806122c6565b60008781526020829052604090205b9650505050505061219b565b600281036123fa576000808784013560f881901c9060581c73ffffffffffffffffffffffffffffffffffffffff16601586019550909250905060008885013560e81c600386018162ffffff16915080965081925050506000818601905061234b8b848c8c8a908692612346939291906137e9565b6129f7565b612393578a8361235d83898d8f6137e9565b6040517f9a94623200000000000000000000000000000000000000000000000000000000815260040161087694939291906138da565b60ff8416979097019694508460a084901b74ff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff841617876123de57806123ed565b60008881526020829052604090205b975050505050505061219b565b6003810361242d576020820191860135836124155780612424565b60008481526020829052604090205b9350505061219b565b60048103612479576003808301928781013560e81c919082010160008061245a8b611a6585898d8f6137e9565b6000988952602052604090972096909701965090935061219b92505050565b600681036125815760008287013560f81c60018401935060ff16905060008784013560f01c60028501945061ffff16905060008885013560e81c600386018162ffffff1691508096508192505050600081860190506000806124e78d8d8d8b908792611a65939291906137e9565b939850889390925090508482106124fd57988501985b604080517f53657175656e6365206e657374656420636f6e6669673a0a0000000000000000602080830191909152603882018490526058820188905260788083018a90528351808403909101815260989092019092528051910120896125635780612572565b60008a81526020829052604090205b9950505050505050505061219b565b600581036125ed5760208201918601358781036125bc577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff94505b60006125c782612ba4565b9050846125d457806125e3565b60008581526020829052604090205b945050505061219b565b6040517fb2505f7c00000000000000000000000000000000000000000000000000000000815260048101829052602401610876565b50935093915050565b7f8713a7c4465f6fbee2b6e9d6646d1d9f83fec929edfc4baf661f3c865bdd04d16000908152602082905260408120610828565b60007fe4a77bbc000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316016126b257506001919050565b61082882612bdf565b604080517f7f25a23abc421d10864063e9a8ae5fd3fbd5116e156f148428b6a3a02ffd945460208201529081018290526000906060016117d7565b6000806000806000612709888888610e77565b50965091945092509050828210801590612727575061272781612bea565b9450505050935093915050565b6000604282146127745782826040517f2ee17a3d00000000000000000000000000000000000000000000000000000000815260040161087692919061391a565b600061278d61278460018561392e565b85013560f81c90565b60ff169050604084013560f81c843560208601357f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0811115612801578686826040517fad4aac7600000000000000000000000000000000000000000000000000000000815260040161087693929190613941565b8260ff16601b1415801561281957508260ff16601c14155b15612856578686846040517fe578897e00000000000000000000000000000000000000000000000000000000815260040161087693929190613965565b600184036128c3576040805160008152602081018083528a905260ff851691810191909152606081018390526080810182905260019060a0015b6020604051602081039080840390855afa1580156128b2573d6000803e3d6000fd5b50505060206040510351945061299b565b60028403612960576040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101899052600190605c01604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600084529083018083525260ff861690820152606081018490526080810183905260a001612890565b86868560016040517f9dfba852000000000000000000000000000000000000000000000000000000008152600401610876949392919061398c565b73ffffffffffffffffffffffffffffffffffffffff85166129ec5786866040517f6c1719d200000000000000000000000000000000000000000000000000000000815260040161087692919061391a565b505050509392505050565b6000808383612a0760018261392e565b818110612a1657612a1661348a565b919091013560f81c9150506001811480612a305750600281145b15612a75578473ffffffffffffffffffffffffffffffffffffffff16612a57878686612734565b73ffffffffffffffffffffffffffffffffffffffff16149150612b9b565b60038103612b605773ffffffffffffffffffffffffffffffffffffffff8516631626ba7e8786600087612aa960018261392e565b92612ab6939291906137e9565b6040518463ffffffff1660e01b8152600401612ad4939291906136cc565b602060405180830381865afa158015612af1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b1591906139b8565b7fffffffff00000000000000000000000000000000000000000000000000000000167f1626ba7e00000000000000000000000000000000000000000000000000000000149150612b9b565b83838260006040517f9dfba852000000000000000000000000000000000000000000000000000000008152600401610876949392919061398c565b50949350505050565b6040517f53657175656e636520737461746963206469676573743a0a00000000000000006020820152603881018290526000906058016117d7565b600061082882612bf5565b600061082882612c51565b60007ffda4dd44000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831601612c4857506001919050565b61082882612d7f565b6000612d53826040517fff0000000000000000000000000000000000000000000000000000000000000060208201527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060601b166021820152603581018290527f000000000000000000000000000000000000000000000000000000000000000060558201526000903090607501604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052805160209091012073ffffffffffffffffffffffffffffffffffffffff161492915050565b15612d6057506001919050565b6000612d6b83611f51565b905080158015906109dc5750421092915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fac6a444e000000000000000000000000000000000000000000000000000000001480612e1257507fffffffff0000000000000000000000000000000000000000000000000000000082167f36e7817500000000000000000000000000000000000000000000000000000000145b15612e1f57506001919050565b7f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614610828565b8183823760009101908152919050565b7fffffffff000000000000000000000000000000000000000000000000000000008116811461088857600080fd5b600060208284031215612eb957600080fd5b81356109dc81612e79565b803573ffffffffffffffffffffffffffffffffffffffff81168114612ee857600080fd5b919050565b600060208284031215612eff57600080fd5b6109dc82612ec4565b60008083601f840112612f1a57600080fd5b50813567ffffffffffffffff811115612f3257600080fd5b6020830191508360208260051b8501011115612f4d57600080fd5b9250929050565b60008060208385031215612f6757600080fd5b823567ffffffffffffffff811115612f7e57600080fd5b612f8a85828601612f08565b90969095509350505050565b60008083601f840112612fa857600080fd5b50813567ffffffffffffffff811115612fc057600080fd5b602083019150836020828501011115612f4d57600080fd5b600080600080600060808688031215612ff057600080fd5b612ff986612ec4565b945061300760208701612ec4565b935060408601359250606086013567ffffffffffffffff81111561302a57600080fd5b61303688828901612f96565b969995985093965092949392505050565b60008060006040848603121561305c57600080fd5b83359250602084013567ffffffffffffffff81111561307a57600080fd5b61308686828701612f96565b9497909650939450505050565b600080600080604085870312156130a957600080fd5b843567ffffffffffffffff808211156130c157600080fd5b6130cd88838901612f96565b909650945060208701359150808211156130e657600080fd5b506130f387828801612f96565b95989497509550505050565b60006020828403121561311157600080fd5b5035919050565b6000806040838503121561312b57600080fd5b50508035926020909101359150565b60008060008060006060868803121561315257600080fd5b853567ffffffffffffffff8082111561316a57600080fd5b61317689838a01612f08565b909750955060208801359450604088013591508082111561319657600080fd5b5061303688828901612f96565b60005b838110156131be5781810151838201526020016131a6565b50506000910152565b600081518084526131df8160208601602086016131a3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006109dc60208301846131c7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561326557600080fd5b813567ffffffffffffffff8082111561327d57600080fd5b818401915084601f83011261329157600080fd5b8135818111156132a3576132a3613224565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156132e9576132e9613224565b8160405282815287602084870101111561330257600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000806040838503121561333557600080fd5b823561334081612e79565b915061334e60208401612ec4565b90509250929050565b60008060008060008060008060a0898b03121561337357600080fd5b61337c89612ec4565b975061338a60208a01612ec4565b9650604089013567ffffffffffffffff808211156133a757600080fd5b6133b38c838d01612f08565b909850965060608b01359150808211156133cc57600080fd5b6133d88c838d01612f08565b909650945060808b01359150808211156133f157600080fd5b506133fe8b828c01612f96565b999c989b5096995094979396929594505050565b60008060008060008060a0878903121561342b57600080fd5b61343487612ec4565b955061344260208801612ec4565b94506040870135935060608701359250608087013567ffffffffffffffff81111561346c57600080fd5b61347889828a01612f96565b979a9699509497509295939492505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b80358015158114612ee857600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b81835260006020808501808196508560051b810191508460005b8781101561365457828403895281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4188360301811261356b57600080fd5b870160c0613578826134b9565b151586526135878783016134b9565b15158688015260408281013590870152606073ffffffffffffffffffffffffffffffffffffffff6135b9828501612ec4565b16908701526080828101359087015260a080830135368490037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe10181126135ff57600080fd5b90920187810192903567ffffffffffffffff81111561361d57600080fd5b80360384131561362c57600080fd5b828289015261363e83890182866134c9565b9c89019c9750505092860192505060010161352c565b5091979650505050505050565b60408152600560408201527f73656c663a0000000000000000000000000000000000000000000000000000006060820152608060208201526000610a4b608083018486613512565b8381526040602082015260006136c3604083018486613512565b95945050505050565b8381526040602082015260006136c36040830184866134c9565b7f697066733a2f2f0000000000000000000000000000000000000000000000000081526000825161371e8160078501602087016131a3565b9190910160070192915050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4183360301811261375f57600080fd5b9190910192915050565b60006020828403121561377b57600080fd5b6109dc826134b9565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126137b957600080fd5b83018035915067ffffffffffffffff8211156137d457600080fd5b602001915036819003821315612f4d57600080fd5b600080858511156137f957600080fd5b8386111561380657600080fd5b5050820193919092039150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561082857610828613813565b6060815260006138696060830186886134c9565b6020830194909452506040015292915050565b7f62000000000000000000000000000000000000000000000000000000000000008152600082516138b48160018501602087016131a3565b9190910160010192915050565b828152604060208201526000610a4b60408301846131c7565b84815273ffffffffffffffffffffffffffffffffffffffff841660208201526060604082015260006139106060830184866134c9565b9695505050505050565b602081526000610a4b6020830184866134c9565b8181038181111561082857610828613813565b6040815260006139556040830185876134c9565b9050826020830152949350505050565b6040815260006139796040830185876134c9565b905060ff83166020830152949350505050565b6060815260006139a06060830186886134c9565b60208301949094525090151560409091015292915050565b6000602082840312156139ca57600080fd5b81516109dc81612e7956fea2646970667358221220e6905b82ca2ea91a0c6cc4a371ce0a85eb88794fb3bc7734ed5414f524c47c4264736f6c63430008110033603a600e3d39601a805130553df3363d3d373d3d3d363d30545af43d82803e903d91601857fd5bf3', + deployedBytecode: + '0x6080604052600436106101dc5760003560e01c806379e472c911610102578063a4ab5f9f11610095578063c71f1f9611610064578063c71f1f961461073f578063d0748f7114610754578063d59f788514610774578063f23a6e6114610794576101e3565b8063a4ab5f9f146106a2578063affed0e0146106c2578063b93ea7ad146106d7578063bc197c81146106f7576101e3565b80638c3f5563116100d15780638c3f55631461062d5780638efa64411461064d57806390042baf1461066f578063a38cef1914610682576101e3565b806379e472c9146105715780637a9a162814610591578063853c5068146105b1578063888eeec6146105f9576101e3565b8063257671f51161017a5780634598154f116101495780634598154f146104dd5780634fcf3eca146104fd57806357c56d6b1461051d57806361c2926c14610551576101e3565b8063257671f51461042757806329561426146104695780632dd310001461048957806341ea0302146104bd576101e3565b8063150b7a02116101b6578063150b7a021461032c5780631626ba7e146103a25780631a9b2337146103c257806320c13b0b14610407576101e3565b806301ffc9a7146102b7578063025b22bc146102ec578063038dbaac1461030c576101e3565b366101e357005b60006102126000357fffffffff00000000000000000000000000000000000000000000000000000000166107da565b905073ffffffffffffffffffffffffffffffffffffffff8116156102b5576000808273ffffffffffffffffffffffffffffffffffffffff1660003660405161025b929190612e69565b600060405180830381855af49150503d8060008114610296576040519150601f19603f3d011682016040523d82523d6000602084013e61029b565b606091505b5091509150816102ad57805160208201fd5b805160208201f35b005b3480156102c357600080fd5b506102d76102d2366004612ea7565b61082e565b60405190151581526020015b60405180910390f35b3480156102f857600080fd5b506102b5610307366004612eed565b610839565b34801561031857600080fd5b506102b5610327366004612f54565b61088b565b34801561033857600080fd5b50610371610347366004612fd8565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016102e3565b3480156103ae57600080fd5b506103716103bd366004613047565b610996565b3480156103ce57600080fd5b506103e26103dd366004612ea7565b6109e3565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102e3565b34801561041357600080fd5b50610371610422366004613093565b6109ee565b34801561043357600080fd5b5061045b7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020016102e3565b34801561047557600080fd5b506102b56104843660046130ff565b610a53565b34801561049557600080fd5b506103e27f000000000000000000000000000000000000000000000000000000000000000081565b3480156104c957600080fd5b5061045b6104d83660046130ff565b610a9d565b3480156104e957600080fd5b506102b56104f8366004613118565b610aa8565b34801561050957600080fd5b506102b5610518366004612ea7565b610b6e565b34801561052957600080fd5b5061045b7f8713a7c4465f6fbee2b6e9d6646d1d9f83fec929edfc4baf661f3c865bdd04d181565b34801561055d57600080fd5b506102b561056c366004612f54565b610c9d565b34801561057d57600080fd5b506102b561058c366004613118565b610d23565b34801561059d57600080fd5b506102b56105ac36600461313a565b610de1565b3480156105bd57600080fd5b506105d16105cc366004613047565b610e77565b604080519586526020860194909452928401919091526060830152608082015260a0016102e3565b34801561060557600080fd5b506103e27f000000000000000000000000000000000000000000000000000000000000000081565b34801561063957600080fd5b5061045b6106483660046130ff565b61103f565b34801561065957600080fd5b5061066261106b565b6040516102e39190613211565b6103e261067d366004613253565b6110ec565b34801561068e57600080fd5b506102b561069d3660046130ff565b611188565b3480156106ae57600080fd5b5061045b6106bd3660046130ff565b6111d2565b3480156106ce57600080fd5b5061045b6111dd565b3480156106e357600080fd5b506102b56106f2366004613322565b6111ee565b34801561070357600080fd5b50610371610712366004613357565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b34801561074b57600080fd5b5061045b611337565b34801561076057600080fd5b506102b561076f366004613118565b611361565b34801561078057600080fd5b506102b561078f366004612f54565b6113b4565b3480156107a057600080fd5b506103716107af366004613412565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b60006108287fbe27a319efc8734e89e26ba4bc95f5c788584163b959f03fa04e2d7ab4b9a1207fffffffff0000000000000000000000000000000000000000000000000000000084166114f7565b92915050565b600061082882611555565b33301461087f576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044015b60405180910390fd5b610888816115b1565b50565b3330146108cc576040517fe1258894000000000000000000000000000000000000000000000000000000008152336004820152306024820152604401610876565b8060005b818110156109905760008484838181106108ec576108ec61348a565b90506020020135905061094c816000604080517f849e7bdc245db17e50b9f43086f1914d70eb4dab6dd89af4d541d53353ad97de602080830191909152818301859052825180830384018152606090920190925280519101208190555050565b807f804f6171d6008d9e16ee3aa0561fec328397f4ba2827a6605db388cfdefa3b0c600060405161097f91815260200190565b60405180910390a2506001016108d0565b50505050565b6000806109a485858561166c565b50905080156109d657507f1626ba7e0000000000000000000000000000000000000000000000000000000090506109dc565b50600090505b9392505050565b6000610828826107da565b600080610a138686604051610a04929190612e69565b6040518091039020858561166c565b5090508015610a4557507f20c13b0b000000000000000000000000000000000000000000000000000000009050610a4b565b50600090505b949350505050565b333014610a94576040517fe1258894000000000000000000000000000000000000000000000000000000008152336004820152306024820152604401610876565b61088881611687565b600061082882611743565b333014610ae9576040517fe1258894000000000000000000000000000000000000000000000000000000008152336004820152306024820152604401610876565b604080517f849e7bdc245db17e50b9f43086f1914d70eb4dab6dd89af4d541d53353ad97de602080830191909152818301859052825180830384018152606083019384905280519101208390559082905282907f804f6171d6008d9e16ee3aa0561fec328397f4ba2827a6605db388cfdefa3b0c906080015b60405180910390a25050565b333014610baf576040517fe1258894000000000000000000000000000000000000000000000000000000008152336004820152306024820152604401610876565b6000610bba826107da565b73ffffffffffffffffffffffffffffffffffffffff1603610c2b576040517f1c3812cc0000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000082166004820152602401610876565b604080517fbe27a319efc8734e89e26ba4bc95f5c788584163b959f03fa04e2d7ab4b9a1206020808301919091527fffffffff00000000000000000000000000000000000000000000000000000000841682840152825180830384018152606090920190925280519101206000905550565b333014610cde576040517fe1258894000000000000000000000000000000000000000000000000000000008152336004820152306024820152604401610876565b6000610d118383604051602001610cf6929190613661565b6040516020818303038152906040528051906020012061176f565b9050610d1e8184846117f4565b505050565b333014610d64576040517fe1258894000000000000000000000000000000000000000000000000000000008152336004820152306024820152604401610876565b604080517f7f25a23abc421d10864063e9a8ae5fd3fbd5116e156f148428b6a3a02ffd9454602080830191909152818301859052825180830384018152606083019384905280519101208390559082905282907f180e56184e3025975e8449fab79ff135cc5c3b3fe517a19bf8f111d69b33d2e290608001610b62565b610dea83611952565b600080610e22858888604051602001610e05939291906136a9565b60405160208183030381529060405280519060200120858561166c565b9150915081610e63578084846040517f8f4a234f000000000000000000000000000000000000000000000000000000008152600401610876939291906136cc565b610e6e8188886117f4565b50505050505050565b60008060008060008087876000818110610e9357610e9361348a565b909101357fff00000000000000000000000000000000000000000000000000000000000000169150819050610ee957610ecb8961176f565b9250610ed8838989611a4f565b929850909650945091506110349050565b7fff0000000000000000000000000000000000000000000000000000000000000081811601610f2857610f1b8961176f565b9250610ed8838989611aa0565b7ffe000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821601610f7a57610f1b89611acc565b7ffd000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821601610fde57610fce898989611b39565b9550955095509550955050611034565b6040517f6085cd820000000000000000000000000000000000000000000000000000000081527fff0000000000000000000000000000000000000000000000000000000000000082166004820152602401610876565b939792965093509350565b60006108287f8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e836114f7565b60606110c86110c361107b611337565b6040517f017012200000000000000000000000000000000000000000000000000000000060208201526024810191909152604401604051602081830303815290604052611cb6565b611ecf565b6040516020016110d891906136e6565b604051602081830303815290604052905090565b600033301461112f576040517fe1258894000000000000000000000000000000000000000000000000000000008152336004820152306024820152604401610876565b81516020830134f060405173ffffffffffffffffffffffffffffffffffffffff821681529091507fa506ad4e7f05eceba62a023c3219e5bd98a615f4fa87e2afb08a2da5cf62bf0c9060200160405180910390a1919050565b3330146111c9576040517fe1258894000000000000000000000000000000000000000000000000000000008152336004820152306024820152604401610876565b61088881611ef8565b600061082882611f51565b60006111e9600061103f565b905090565b33301461122f576040517fe1258894000000000000000000000000000000000000000000000000000000008152336004820152306024820152604401610876565b600061123a836107da565b73ffffffffffffffffffffffffffffffffffffffff16146112ab576040517f5b4d6d6a0000000000000000000000000000000000000000000000000000000081527fffffffff0000000000000000000000000000000000000000000000000000000083166004820152602401610876565b604080517fbe27a319efc8734e89e26ba4bc95f5c788584163b959f03fa04e2d7ab4b9a1206020808301919091527fffffffff000000000000000000000000000000000000000000000000000000008516828401528251808303840181526060909201909252805191012073ffffffffffffffffffffffffffffffffffffffff821690555050565b5050565b60006111e97f0eecac93ced8722d209199364cda3bc33da3bc3a23daef6be49ebd780511d0335490565b3330146113a2576040517fe1258894000000000000000000000000000000000000000000000000000000008152336004820152306024820152604401610876565b6113ab82611687565b61133381611ef8565b3330146113f5576040517fe1258894000000000000000000000000000000000000000000000000000000008152336004820152306024820152604401610876565b8060005b818110156109905760008484838181106114155761141561348a565b905060200201359050611494817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff604080517f7f25a23abc421d10864063e9a8ae5fd3fbd5116e156f148428b6a3a02ffd9454602080830191909152818301859052825180830384018152606090920190925280519101208190555050565b807f180e56184e3025975e8449fab79ff135cc5c3b3fe517a19bf8f111d69b33d2e27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6040516114e691815260200190565b60405180910390a2506001016113f9565b6000808383604051602001611516929190918252602082015260400190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052805160209091012054949350505050565b60007f6ffbd451000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316016115a857506001919050565b61082882611f7d565b73ffffffffffffffffffffffffffffffffffffffff81163b611617576040517f0c76093700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610876565b61161f813055565b60405173ffffffffffffffffffffffffffffffffffffffff821681527f310ba5f1d2ed074b51e2eccd052a47ae9ab7c6b800d1fca3db3999d6a592ca03906020015b60405180910390a150565b60008061167a8585856120be565b915091505b935093915050565b806116be576040517f4294d12700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116e77fea7157fa25e3aa17d0ae2d5280fa4e24d421c61842aa85e45194e1145aa72bf8829055565b6040518181527f307ed6bd941ee9fc80f369c94af5fa11e25bab5102a6140191756c5474a30bfa9060200160405180910390a16108887f00000000000000000000000000000000000000000000000000000000000000006115b1565b60006108287f7f25a23abc421d10864063e9a8ae5fd3fbd5116e156f148428b6a3a02ffd9454836114f7565b6040517f190100000000000000000000000000000000000000000000000000000000000060208201524660228201527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b166042820152605681018290526000906076015b604051602081830303815290604052805190602001209050919050565b8060005b8181101561194b57368484838181106118135761181361348a565b9050602002810190611825919061372b565b90506040810135805a101561187a5782815a6040517f2bb3e3ba000000000000000000000000000000000000000000000000000000008152600481019390935260248301919091526044820152606401610876565b60006118896020840184613769565b156118c8576118c16118a16080850160608601612eed565b83156118ad57836118af565b5a5b6118bc60a0870187613784565b6120f2565b9050611903565b6119006118db6080850160608601612eed565b608085013584156118ec57846118ee565b5a5b6118fb60a0880188613784565b61210d565b90505b801561191f5760405188815260200160405180910390a0611940565b6119406119326040850160208601613769565b8961193b61212a565b612149565b5050506001016117f8565b5050505050565b606081901c6bffffffffffffffffffffffff821660006119718361103f565b90508181146119bd576040517f9b6514f4000000000000000000000000000000000000000000000000000000008152600481018490526024810183905260448101829052606401610876565b604080517f8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e60208083019190915281830186905282518083038401815260609092019092528051910120600183019081905560408051858152602081018390527f1f180c27086c7a39ea2a7b25239d1ab92348f07ca7bb59d1438fcf527568f881910160405180910390a15050505050565b6000808080611a6a87611a65876006818b6137e9565b612195565b6000908152873560f01c6020818152604080842084526002909a013560e01c908190529890912090999198509695509350505050565b6000808080611abb87611ab6876001818b6137e9565b611a4f565b935093509350935093509350935093565b6040517f190100000000000000000000000000000000000000000000000000000000000060208201526000602282018190527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b16604283015260568201839052906076016117d7565b6000808080806004600188013560e81c82611b548383613842565b9050611b668b6105cc83868d8f6137e9565b939b5091995097509550935087871015611bbe57611b8681848b8d6137e9565b89896040517fb006aba00000000000000000000000000000000000000000000000000000000081526004016108769493929190613855565b8092505b88831015611ca85760038301928a013560e81c9150611be18383613842565b90506000611c03611bf18861262b565b8c8c879086926105cc939291906137e9565b939c50919a5098509091505088881015611c5b57611c2382858c8e6137e9565b8a8a6040517fb006aba00000000000000000000000000000000000000000000000000000000081526004016108769493929190613855565b848110611c9e576040517f37daf62b0000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610876565b9350915081611bc2565b505050939792965093509350565b8051606090600381901b60006005600483010467ffffffffffffffff811115611ce157611ce1613224565b6040519080825280601f01601f191660200182016040528015611d0b576020820181803683370190505b5090506000806000805b86811015611e1f57888181518110611d2f57611d2f61348a565b01602001516008948501949390931b60f89390931c92909217915b60058410611e17576040805180820190915260208082527f6162636465666768696a6b6c6d6e6f707172737475767778797a323334353637818301527ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb90950194601f85871c16908110611dc057611dc061348a565b602001015160f81c60f81b858381518110611ddd57611ddd61348a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600190910190611d4a565b600101611d15565b508215611ec3576040518060400160405280602081526020017f6162636465666768696a6b6c6d6e6f707172737475767778797a3233343536378152508360050383901b601f1681518110611e7657611e7661348a565b602001015160f81c60f81b848281518110611e9357611e9361348a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505b50919695505050505050565b606081604051602001611ee2919061387c565b6040516020818303038152906040529050919050565b611f217f0eecac93ced8722d209199364cda3bc33da3bc3a23daef6be49ebd780511d033829055565b6040518181527f20d3ef1b5738a9f6d7beae515432206e7a8e2740ca6dcf46a952190ad01bcb5190602001611661565b60006108287f849e7bdc245db17e50b9f43086f1914d70eb4dab6dd89af4d541d53353ad97de836114f7565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fec6aba5000000000000000000000000000000000000000000000000000000000148061201057507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b8061205c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b806120a857507fffffffff0000000000000000000000000000000000000000000000000000000082167fc0ee0b8a00000000000000000000000000000000000000000000000000000000145b156120b557506001919050565b6108288261265f565b600080426120cb86611743565b11915081156120e757816120de866126bb565b9150915061167f565b61167a8585856126f6565b60006040518284823760008084838989f49695505050505050565b6000604051828482376000808483898b8af1979650505050505050565b60603d604051915060208201818101604052818352816000823e505090565b821561215757805160208201fd5b7f3dbd1590ea96dd3253a91f24e64e3a502e1225d602a5731357bc12643070ccd782826040516121889291906138c1565b60405180910390a1505050565b60008060005b8381101561262257600181019085013560f81c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810161223c57601582019186013560f881901c9060581c73ffffffffffffffffffffffffffffffffffffffff81169074ff0000000000000000000000000000000000000000168117856122225780612231565b60008681526020829052604090205b95505050505061219b565b806122d25760018201918681013560f81c9060430160006122688a61226384888c8e6137e9565b612734565b60ff841697909701969194508491905060a083901b74ff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff821617866122b757806122c6565b60008781526020829052604090205b9650505050505061219b565b600281036123fa576000808784013560f881901c9060581c73ffffffffffffffffffffffffffffffffffffffff16601586019550909250905060008885013560e81c600386018162ffffff16915080965081925050506000818601905061234b8b848c8c8a908692612346939291906137e9565b6129f7565b612393578a8361235d83898d8f6137e9565b6040517f9a94623200000000000000000000000000000000000000000000000000000000815260040161087694939291906138da565b60ff8416979097019694508460a084901b74ff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff841617876123de57806123ed565b60008881526020829052604090205b975050505050505061219b565b6003810361242d576020820191860135836124155780612424565b60008481526020829052604090205b9350505061219b565b60048103612479576003808301928781013560e81c919082010160008061245a8b611a6585898d8f6137e9565b6000988952602052604090972096909701965090935061219b92505050565b600681036125815760008287013560f81c60018401935060ff16905060008784013560f01c60028501945061ffff16905060008885013560e81c600386018162ffffff1691508096508192505050600081860190506000806124e78d8d8d8b908792611a65939291906137e9565b939850889390925090508482106124fd57988501985b604080517f53657175656e6365206e657374656420636f6e6669673a0a0000000000000000602080830191909152603882018490526058820188905260788083018a90528351808403909101815260989092019092528051910120896125635780612572565b60008a81526020829052604090205b9950505050505050505061219b565b600581036125ed5760208201918601358781036125bc577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff94505b60006125c782612ba4565b9050846125d457806125e3565b60008581526020829052604090205b945050505061219b565b6040517fb2505f7c00000000000000000000000000000000000000000000000000000000815260048101829052602401610876565b50935093915050565b7f8713a7c4465f6fbee2b6e9d6646d1d9f83fec929edfc4baf661f3c865bdd04d16000908152602082905260408120610828565b60007fe4a77bbc000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316016126b257506001919050565b61082882612bdf565b604080517f7f25a23abc421d10864063e9a8ae5fd3fbd5116e156f148428b6a3a02ffd945460208201529081018290526000906060016117d7565b6000806000806000612709888888610e77565b50965091945092509050828210801590612727575061272781612bea565b9450505050935093915050565b6000604282146127745782826040517f2ee17a3d00000000000000000000000000000000000000000000000000000000815260040161087692919061391a565b600061278d61278460018561392e565b85013560f81c90565b60ff169050604084013560f81c843560208601357f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0811115612801578686826040517fad4aac7600000000000000000000000000000000000000000000000000000000815260040161087693929190613941565b8260ff16601b1415801561281957508260ff16601c14155b15612856578686846040517fe578897e00000000000000000000000000000000000000000000000000000000815260040161087693929190613965565b600184036128c3576040805160008152602081018083528a905260ff851691810191909152606081018390526080810182905260019060a0015b6020604051602081039080840390855afa1580156128b2573d6000803e3d6000fd5b50505060206040510351945061299b565b60028403612960576040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101899052600190605c01604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600084529083018083525260ff861690820152606081018490526080810183905260a001612890565b86868560016040517f9dfba852000000000000000000000000000000000000000000000000000000008152600401610876949392919061398c565b73ffffffffffffffffffffffffffffffffffffffff85166129ec5786866040517f6c1719d200000000000000000000000000000000000000000000000000000000815260040161087692919061391a565b505050509392505050565b6000808383612a0760018261392e565b818110612a1657612a1661348a565b919091013560f81c9150506001811480612a305750600281145b15612a75578473ffffffffffffffffffffffffffffffffffffffff16612a57878686612734565b73ffffffffffffffffffffffffffffffffffffffff16149150612b9b565b60038103612b605773ffffffffffffffffffffffffffffffffffffffff8516631626ba7e8786600087612aa960018261392e565b92612ab6939291906137e9565b6040518463ffffffff1660e01b8152600401612ad4939291906136cc565b602060405180830381865afa158015612af1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b1591906139b8565b7fffffffff00000000000000000000000000000000000000000000000000000000167f1626ba7e00000000000000000000000000000000000000000000000000000000149150612b9b565b83838260006040517f9dfba852000000000000000000000000000000000000000000000000000000008152600401610876949392919061398c565b50949350505050565b6040517f53657175656e636520737461746963206469676573743a0a00000000000000006020820152603881018290526000906058016117d7565b600061082882612bf5565b600061082882612c51565b60007ffda4dd44000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831601612c4857506001919050565b61082882612d7f565b6000612d53826040517fff0000000000000000000000000000000000000000000000000000000000000060208201527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060601b166021820152603581018290527f000000000000000000000000000000000000000000000000000000000000000060558201526000903090607501604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052805160209091012073ffffffffffffffffffffffffffffffffffffffff161492915050565b15612d6057506001919050565b6000612d6b83611f51565b905080158015906109dc5750421092915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fac6a444e000000000000000000000000000000000000000000000000000000001480612e1257507fffffffff0000000000000000000000000000000000000000000000000000000082167f36e7817500000000000000000000000000000000000000000000000000000000145b15612e1f57506001919050565b7f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614610828565b8183823760009101908152919050565b7fffffffff000000000000000000000000000000000000000000000000000000008116811461088857600080fd5b600060208284031215612eb957600080fd5b81356109dc81612e79565b803573ffffffffffffffffffffffffffffffffffffffff81168114612ee857600080fd5b919050565b600060208284031215612eff57600080fd5b6109dc82612ec4565b60008083601f840112612f1a57600080fd5b50813567ffffffffffffffff811115612f3257600080fd5b6020830191508360208260051b8501011115612f4d57600080fd5b9250929050565b60008060208385031215612f6757600080fd5b823567ffffffffffffffff811115612f7e57600080fd5b612f8a85828601612f08565b90969095509350505050565b60008083601f840112612fa857600080fd5b50813567ffffffffffffffff811115612fc057600080fd5b602083019150836020828501011115612f4d57600080fd5b600080600080600060808688031215612ff057600080fd5b612ff986612ec4565b945061300760208701612ec4565b935060408601359250606086013567ffffffffffffffff81111561302a57600080fd5b61303688828901612f96565b969995985093965092949392505050565b60008060006040848603121561305c57600080fd5b83359250602084013567ffffffffffffffff81111561307a57600080fd5b61308686828701612f96565b9497909650939450505050565b600080600080604085870312156130a957600080fd5b843567ffffffffffffffff808211156130c157600080fd5b6130cd88838901612f96565b909650945060208701359150808211156130e657600080fd5b506130f387828801612f96565b95989497509550505050565b60006020828403121561311157600080fd5b5035919050565b6000806040838503121561312b57600080fd5b50508035926020909101359150565b60008060008060006060868803121561315257600080fd5b853567ffffffffffffffff8082111561316a57600080fd5b61317689838a01612f08565b909750955060208801359450604088013591508082111561319657600080fd5b5061303688828901612f96565b60005b838110156131be5781810151838201526020016131a6565b50506000910152565b600081518084526131df8160208601602086016131a3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006109dc60208301846131c7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561326557600080fd5b813567ffffffffffffffff8082111561327d57600080fd5b818401915084601f83011261329157600080fd5b8135818111156132a3576132a3613224565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156132e9576132e9613224565b8160405282815287602084870101111561330257600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000806040838503121561333557600080fd5b823561334081612e79565b915061334e60208401612ec4565b90509250929050565b60008060008060008060008060a0898b03121561337357600080fd5b61337c89612ec4565b975061338a60208a01612ec4565b9650604089013567ffffffffffffffff808211156133a757600080fd5b6133b38c838d01612f08565b909850965060608b01359150808211156133cc57600080fd5b6133d88c838d01612f08565b909650945060808b01359150808211156133f157600080fd5b506133fe8b828c01612f96565b999c989b5096995094979396929594505050565b60008060008060008060a0878903121561342b57600080fd5b61343487612ec4565b955061344260208801612ec4565b94506040870135935060608701359250608087013567ffffffffffffffff81111561346c57600080fd5b61347889828a01612f96565b979a9699509497509295939492505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b80358015158114612ee857600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b81835260006020808501808196508560051b810191508460005b8781101561365457828403895281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4188360301811261356b57600080fd5b870160c0613578826134b9565b151586526135878783016134b9565b15158688015260408281013590870152606073ffffffffffffffffffffffffffffffffffffffff6135b9828501612ec4565b16908701526080828101359087015260a080830135368490037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe10181126135ff57600080fd5b90920187810192903567ffffffffffffffff81111561361d57600080fd5b80360384131561362c57600080fd5b828289015261363e83890182866134c9565b9c89019c9750505092860192505060010161352c565b5091979650505050505050565b60408152600560408201527f73656c663a0000000000000000000000000000000000000000000000000000006060820152608060208201526000610a4b608083018486613512565b8381526040602082015260006136c3604083018486613512565b95945050505050565b8381526040602082015260006136c36040830184866134c9565b7f697066733a2f2f0000000000000000000000000000000000000000000000000081526000825161371e8160078501602087016131a3565b9190910160070192915050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4183360301811261375f57600080fd5b9190910192915050565b60006020828403121561377b57600080fd5b6109dc826134b9565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126137b957600080fd5b83018035915067ffffffffffffffff8211156137d457600080fd5b602001915036819003821315612f4d57600080fd5b600080858511156137f957600080fd5b8386111561380657600080fd5b5050820193919092039150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561082857610828613813565b6060815260006138696060830186886134c9565b6020830194909452506040015292915050565b7f62000000000000000000000000000000000000000000000000000000000000008152600082516138b48160018501602087016131a3565b9190910160010192915050565b828152604060208201526000610a4b60408301846131c7565b84815273ffffffffffffffffffffffffffffffffffffffff841660208201526060604082015260006139106060830184866134c9565b9695505050505050565b602081526000610a4b6020830184866134c9565b8181038181111561082857610828613813565b6040815260006139556040830185876134c9565b9050826020830152949350505050565b6040815260006139796040830185876134c9565b905060ff83166020830152949350505050565b6060815260006139a06060830186886134c9565b60208301949094525090151560409091015292915050565b6000602082840312156139ca57600080fd5b81516109dc81612e7956fea2646970667358221220e6905b82ca2ea91a0c6cc4a371ce0a85eb88794fb3bc7734ed5414f524c47c4264736f6c63430008110033', + linkReferences: {}, + deployedLinkReferences: {} +} diff --git a/packages/tests/src/builds/v2/artifacts/MainModuleUpgradable.ts b/packages/tests/src/builds/v2/artifacts/MainModuleUpgradable.ts new file mode 100644 index 0000000000..6edae5d5ee --- /dev/null +++ b/packages/tests/src/builds/v2/artifacts/MainModuleUpgradable.ts @@ -0,0 +1,1062 @@ +export const mainModuleUpgradable = { + _format: 'hh-sol-artifact-1', + contractName: 'MainModuleUpgradable', + sourceName: 'contracts/modules/MainModuleUpgradable.sol', + abi: [ + { + inputs: [ + { + internalType: 'uint256', + name: '_space', + type: 'uint256' + }, + { + internalType: 'uint256', + name: '_provided', + type: 'uint256' + }, + { + internalType: 'uint256', + name: '_current', + type: 'uint256' + } + ], + name: 'BadNonce', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes4', + name: '_signature', + type: 'bytes4' + } + ], + name: 'HookAlreadyExists', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes4', + name: '_signature', + type: 'bytes4' + } + ], + name: 'HookDoesNotExist', + type: 'error' + }, + { + inputs: [], + name: 'ImageHashIsZero', + type: 'error' + }, + { + inputs: [ + { + internalType: 'address', + name: '_implementation', + type: 'address' + } + ], + name: 'InvalidImplementation', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_hash', + type: 'bytes32' + }, + { + internalType: 'address', + name: '_addr', + type: 'address' + }, + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + } + ], + name: 'InvalidNestedSignature', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + }, + { + internalType: 'bytes32', + name: '_s', + type: 'bytes32' + } + ], + name: 'InvalidSValue', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_hash', + type: 'bytes32' + }, + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + } + ], + name: 'InvalidSignature', + type: 'error' + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_flag', + type: 'uint256' + } + ], + name: 'InvalidSignatureFlag', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + } + ], + name: 'InvalidSignatureLength', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes1', + name: '_type', + type: 'bytes1' + } + ], + name: 'InvalidSignatureType', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + }, + { + internalType: 'uint256', + name: '_v', + type: 'uint256' + } + ], + name: 'InvalidVValue', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + }, + { + internalType: 'uint256', + name: 'threshold', + type: 'uint256' + }, + { + internalType: 'uint256', + name: '_weight', + type: 'uint256' + } + ], + name: 'LowWeightChainedSignature', + type: 'error' + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_index', + type: 'uint256' + }, + { + internalType: 'uint256', + name: '_requested', + type: 'uint256' + }, + { + internalType: 'uint256', + name: '_available', + type: 'uint256' + } + ], + name: 'NotEnoughGas', + type: 'error' + }, + { + inputs: [ + { + internalType: 'address', + name: '_sender', + type: 'address' + }, + { + internalType: 'address', + name: '_self', + type: 'address' + } + ], + name: 'OnlySelfAuth', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + } + ], + name: 'SignerIsAddress0', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + }, + { + internalType: 'uint256', + name: '_type', + type: 'uint256' + }, + { + internalType: 'bool', + name: '_recoverMode', + type: 'bool' + } + ], + name: 'UnsupportedSignatureType', + type: 'error' + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_current', + type: 'uint256' + }, + { + internalType: 'uint256', + name: '_prev', + type: 'uint256' + } + ], + name: 'WrongChainedCheckpointOrder', + type: 'error' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: '_contract', + type: 'address' + } + ], + name: 'CreatedContract', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'bytes32', + name: '_hash', + type: 'bytes32' + } + ], + name: 'IPFSRootUpdated', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'bytes32', + name: 'newImageHash', + type: 'bytes32' + } + ], + name: 'ImageHashUpdated', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'newImplementation', + type: 'address' + } + ], + name: 'ImplementationUpdated', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: '_space', + type: 'uint256' + }, + { + indexed: false, + internalType: 'uint256', + name: '_newNonce', + type: 'uint256' + } + ], + name: 'NonceChange', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'bytes32', + name: '_imageHash', + type: 'bytes32' + }, + { + indexed: false, + internalType: 'uint256', + name: '_expiration', + type: 'uint256' + } + ], + name: 'SetExtraImageHash', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'bytes32', + name: '_digest', + type: 'bytes32' + }, + { + indexed: false, + internalType: 'uint256', + name: '_expiration', + type: 'uint256' + } + ], + name: 'SetStaticDigest', + type: 'event' + }, + { + anonymous: true, + inputs: [ + { + indexed: false, + internalType: 'bytes32', + name: '_tx', + type: 'bytes32' + } + ], + name: 'TxExecuted', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'bytes32', + name: '_tx', + type: 'bytes32' + }, + { + indexed: false, + internalType: 'bytes', + name: '_reason', + type: 'bytes' + } + ], + name: 'TxFailed', + type: 'event' + }, + { + stateMutability: 'payable', + type: 'fallback' + }, + { + inputs: [], + name: 'SET_IMAGE_HASH_TYPE_HASH', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes4', + name: '_signature', + type: 'bytes4' + }, + { + internalType: 'address', + name: '_implementation', + type: 'address' + } + ], + name: 'addHook', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32[]', + name: '_digests', + type: 'bytes32[]' + } + ], + name: 'addStaticDigests', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32[]', + name: '_imageHashes', + type: 'bytes32[]' + } + ], + name: 'clearExtraImageHashes', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_code', + type: 'bytes' + } + ], + name: 'createContract', + outputs: [ + { + internalType: 'address', + name: 'addr', + type: 'address' + } + ], + stateMutability: 'payable', + type: 'function' + }, + { + inputs: [ + { + components: [ + { + internalType: 'bool', + name: 'delegateCall', + type: 'bool' + }, + { + internalType: 'bool', + name: 'revertOnError', + type: 'bool' + }, + { + internalType: 'uint256', + name: 'gasLimit', + type: 'uint256' + }, + { + internalType: 'address', + name: 'target', + type: 'address' + }, + { + internalType: 'uint256', + name: 'value', + type: 'uint256' + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes' + } + ], + internalType: 'struct IModuleCalls.Transaction[]', + name: '_txs', + type: 'tuple[]' + }, + { + internalType: 'uint256', + name: '_nonce', + type: 'uint256' + }, + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + } + ], + name: 'execute', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_imageHash', + type: 'bytes32' + } + ], + name: 'extraImageHash', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'imageHash', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'ipfsRoot', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'ipfsRootBytes32', + outputs: [ + { + internalType: 'bytes32', + name: '', + type: 'bytes32' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_hash', + type: 'bytes32' + }, + { + internalType: 'bytes', + name: '_signatures', + type: 'bytes' + } + ], + name: 'isValidSignature', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes', + name: '_data', + type: 'bytes' + }, + { + internalType: 'bytes', + name: '_signatures', + type: 'bytes' + } + ], + name: 'isValidSignature', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'nonce', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]' + }, + { + internalType: 'uint256[]', + name: '', + type: 'uint256[]' + }, + { + internalType: 'bytes', + name: '', + type: 'bytes' + } + ], + name: 'onERC1155BatchReceived', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'uint256', + name: '', + type: 'uint256' + }, + { + internalType: 'uint256', + name: '', + type: 'uint256' + }, + { + internalType: 'bytes', + name: '', + type: 'bytes' + } + ], + name: 'onERC1155Received', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'uint256', + name: '', + type: 'uint256' + }, + { + internalType: 'bytes', + name: '', + type: 'bytes' + } + ], + name: 'onERC721Received', + outputs: [ + { + internalType: 'bytes4', + name: '', + type: 'bytes4' + } + ], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes4', + name: '_signature', + type: 'bytes4' + } + ], + name: 'readHook', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'uint256', + name: '_space', + type: 'uint256' + } + ], + name: 'readNonce', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes4', + name: '_signature', + type: 'bytes4' + } + ], + name: 'removeHook', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + components: [ + { + internalType: 'bool', + name: 'delegateCall', + type: 'bool' + }, + { + internalType: 'bool', + name: 'revertOnError', + type: 'bool' + }, + { + internalType: 'uint256', + name: 'gasLimit', + type: 'uint256' + }, + { + internalType: 'address', + name: 'target', + type: 'address' + }, + { + internalType: 'uint256', + name: 'value', + type: 'uint256' + }, + { + internalType: 'bytes', + name: 'data', + type: 'bytes' + } + ], + internalType: 'struct IModuleCalls.Transaction[]', + name: '_txs', + type: 'tuple[]' + } + ], + name: 'selfExecute', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_imageHash', + type: 'bytes32' + }, + { + internalType: 'uint256', + name: '_expiration', + type: 'uint256' + } + ], + name: 'setExtraImageHash', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_digest', + type: 'bytes32' + }, + { + internalType: 'uint256', + name: '_expiration', + type: 'uint256' + } + ], + name: 'setStaticDigest', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_digest', + type: 'bytes32' + }, + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + } + ], + name: 'signatureRecovery', + outputs: [ + { + internalType: 'uint256', + name: 'threshold', + type: 'uint256' + }, + { + internalType: 'uint256', + name: 'weight', + type: 'uint256' + }, + { + internalType: 'bytes32', + name: 'imageHash', + type: 'bytes32' + }, + { + internalType: 'bytes32', + name: 'subDigest', + type: 'bytes32' + }, + { + internalType: 'uint256', + name: 'checkpoint', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_digest', + type: 'bytes32' + } + ], + name: 'staticDigest', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes4', + name: '_interfaceID', + type: 'bytes4' + } + ], + name: 'supportsInterface', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool' + } + ], + stateMutability: 'pure', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_hash', + type: 'bytes32' + } + ], + name: 'updateIPFSRoot', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_imageHash', + type: 'bytes32' + } + ], + name: 'updateImageHash', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'bytes32', + name: '_imageHash', + type: 'bytes32' + }, + { + internalType: 'bytes32', + name: '_ipfsRoot', + type: 'bytes32' + } + ], + name: 'updateImageHashAndIPFS', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '_implementation', + type: 'address' + } + ], + name: 'updateImplementation', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + stateMutability: 'payable', + type: 'receive' + } + ], + bytecode: + '0x608060405234801561001057600080fd5b506138f9806100206000396000f3fe6080604052600436106101c65760003560e01c806379e472c9116100f7578063a4ab5f9f11610095578063c71f1f9611610064578063c71f1f96146106a2578063d0748f71146106b7578063d59f7885146106d7578063f23a6e61146106f7576101cd565b8063a4ab5f9f14610605578063affed0e014610625578063b93ea7ad1461063a578063bc197c811461065a576101cd565b80638c3f5563116100d15780638c3f5563146105905780638efa6441146105b057806390042baf146105d2578063a38cef19146105e5576101cd565b806379e472c9146105085780637a9a162814610528578063853c506814610548576101cd565b806329561426116101645780634fcf3eca1161013e5780634fcf3eca1461047f57806351605d801461049f57806357c56d6b146104b457806361c2926c146104e8576101cd565b8063295614261461041157806341ea0302146104315780634598154f1461045f576101cd565b8063150b7a02116101a0578063150b7a02146103165780631626ba7e1461038c5780631a9b2337146103ac57806320c13b0b146103f1576101cd565b806301ffc9a7146102a1578063025b22bc146102d6578063038dbaac146102f6576101cd565b366101cd57005b60006101fc6000357fffffffff000000000000000000000000000000000000000000000000000000001661073d565b905073ffffffffffffffffffffffffffffffffffffffff81161561029f576000808273ffffffffffffffffffffffffffffffffffffffff16600036604051610245929190612d57565b600060405180830381855af49150503d8060008114610280576040519150601f19603f3d011682016040523d82523d6000602084013e610285565b606091505b50915091508161029757805160208201fd5b805160208201f35b005b3480156102ad57600080fd5b506102c16102bc366004612d95565b610791565b60405190151581526020015b60405180910390f35b3480156102e257600080fd5b5061029f6102f1366004612ddb565b61079c565b34801561030257600080fd5b5061029f610311366004612e42565b6107ee565b34801561032257600080fd5b5061035b610331366004612ec6565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016102cd565b34801561039857600080fd5b5061035b6103a7366004612f35565b6108f9565b3480156103b857600080fd5b506103cc6103c7366004612d95565b610946565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102cd565b3480156103fd57600080fd5b5061035b61040c366004612f81565b610951565b34801561041d57600080fd5b5061029f61042c366004612fed565b6109b6565b34801561043d57600080fd5b5061045161044c366004612fed565b610a00565b6040519081526020016102cd565b34801561046b57600080fd5b5061029f61047a366004613006565b610a0b565b34801561048b57600080fd5b5061029f61049a366004612d95565b610ad1565b3480156104ab57600080fd5b50610451610c00565b3480156104c057600080fd5b506104517f8713a7c4465f6fbee2b6e9d6646d1d9f83fec929edfc4baf661f3c865bdd04d181565b3480156104f457600080fd5b5061029f610503366004612e42565b610c2f565b34801561051457600080fd5b5061029f610523366004613006565b610cb5565b34801561053457600080fd5b5061029f610543366004613028565b610d73565b34801561055457600080fd5b50610568610563366004612f35565b610e09565b604080519586526020860194909452928401919091526060830152608082015260a0016102cd565b34801561059c57600080fd5b506104516105ab366004612fed565b610fd1565b3480156105bc57600080fd5b506105c5610ffd565b6040516102cd91906130ff565b6103cc6105e0366004613141565b61107e565b3480156105f157600080fd5b5061029f610600366004612fed565b61111a565b34801561061157600080fd5b50610451610620366004612fed565b611164565b34801561063157600080fd5b5061045161116f565b34801561064657600080fd5b5061029f610655366004613210565b61117b565b34801561066657600080fd5b5061035b610675366004613245565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b3480156106ae57600080fd5b506104516112c4565b3480156106c357600080fd5b5061029f6106d2366004613006565b6112ee565b3480156106e357600080fd5b5061029f6106f2366004612e42565b611341565b34801561070357600080fd5b5061035b610712366004613300565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b600061078b7fbe27a319efc8734e89e26ba4bc95f5c788584163b959f03fa04e2d7ab4b9a1207fffffffff000000000000000000000000000000000000000000000000000000008416611484565b92915050565b600061078b826114e2565b3330146107e2576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044015b60405180910390fd5b6107eb8161153e565b50565b33301461082f576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044016107d9565b8060005b818110156108f357600084848381811061084f5761084f613378565b9050602002013590506108af816000604080517f849e7bdc245db17e50b9f43086f1914d70eb4dab6dd89af4d541d53353ad97de602080830191909152818301859052825180830384018152606090920190925280519101208190555050565b807f804f6171d6008d9e16ee3aa0561fec328397f4ba2827a6605db388cfdefa3b0c60006040516108e291815260200190565b60405180910390a250600101610833565b50505050565b6000806109078585856115f9565b509050801561093957507f1626ba7e00000000000000000000000000000000000000000000000000000000905061093f565b50600090505b9392505050565b600061078b8261073d565b6000806109768686604051610967929190612d57565b604051809103902085856115f9565b50905080156109a857507f20c13b0b0000000000000000000000000000000000000000000000000000000090506109ae565b50600090505b949350505050565b3330146109f7576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044016107d9565b6107eb81611614565b600061078b826116a4565b333014610a4c576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044016107d9565b604080517f849e7bdc245db17e50b9f43086f1914d70eb4dab6dd89af4d541d53353ad97de602080830191909152818301859052825180830384018152606083019384905280519101208390559082905282907f804f6171d6008d9e16ee3aa0561fec328397f4ba2827a6605db388cfdefa3b0c906080015b60405180910390a25050565b333014610b12576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044016107d9565b6000610b1d8261073d565b73ffffffffffffffffffffffffffffffffffffffff1603610b8e576040517f1c3812cc0000000000000000000000000000000000000000000000000000000081527fffffffff00000000000000000000000000000000000000000000000000000000821660048201526024016107d9565b604080517fbe27a319efc8734e89e26ba4bc95f5c788584163b959f03fa04e2d7ab4b9a1206020808301919091527fffffffff00000000000000000000000000000000000000000000000000000000841682840152825180830384018152606090920190925280519101206000905550565b6000610c2a7fea7157fa25e3aa17d0ae2d5280fa4e24d421c61842aa85e45194e1145aa72bf85490565b905090565b333014610c70576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044016107d9565b6000610ca38383604051602001610c8892919061354f565b604051602081830303815290604052805190602001206116d0565b9050610cb0818484611755565b505050565b333014610cf6576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044016107d9565b604080517f7f25a23abc421d10864063e9a8ae5fd3fbd5116e156f148428b6a3a02ffd9454602080830191909152818301859052825180830384018152606083019384905280519101208390559082905282907f180e56184e3025975e8449fab79ff135cc5c3b3fe517a19bf8f111d69b33d2e290608001610ac5565b610d7c836118b3565b600080610db4858888604051602001610d9793929190613597565b6040516020818303038152906040528051906020012085856115f9565b9150915081610df5578084846040517f8f4a234f0000000000000000000000000000000000000000000000000000000081526004016107d9939291906135ba565b610e00818888611755565b50505050505050565b60008060008060008087876000818110610e2557610e25613378565b909101357fff00000000000000000000000000000000000000000000000000000000000000169150819050610e7b57610e5d896116d0565b9250610e6a8389896119b0565b92985090965094509150610fc69050565b7fff0000000000000000000000000000000000000000000000000000000000000081811601610eba57610ead896116d0565b9250610e6a838989611a01565b7ffe000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821601610f0c57610ead89611a2d565b7ffd000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821601610f7057610f60898989611a9a565b9550955095509550955050610fc6565b6040517f6085cd820000000000000000000000000000000000000000000000000000000081527fff00000000000000000000000000000000000000000000000000000000000000821660048201526024016107d9565b939792965093509350565b600061078b7f8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e83611484565b606061105a61105561100d6112c4565b6040517f017012200000000000000000000000000000000000000000000000000000000060208201526024810191909152604401604051602081830303815290604052611c17565b611e30565b60405160200161106a91906135d4565b604051602081830303815290604052905090565b60003330146110c1576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044016107d9565b81516020830134f060405173ffffffffffffffffffffffffffffffffffffffff821681529091507fa506ad4e7f05eceba62a023c3219e5bd98a615f4fa87e2afb08a2da5cf62bf0c9060200160405180910390a1919050565b33301461115b576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044016107d9565b6107eb81611e59565b600061078b82611eb2565b6000610c2a6000610fd1565b3330146111bc576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044016107d9565b60006111c78361073d565b73ffffffffffffffffffffffffffffffffffffffff1614611238576040517f5b4d6d6a0000000000000000000000000000000000000000000000000000000081527fffffffff00000000000000000000000000000000000000000000000000000000831660048201526024016107d9565b604080517fbe27a319efc8734e89e26ba4bc95f5c788584163b959f03fa04e2d7ab4b9a1206020808301919091527fffffffff000000000000000000000000000000000000000000000000000000008516828401528251808303840181526060909201909252805191012073ffffffffffffffffffffffffffffffffffffffff821690555050565b5050565b6000610c2a7f0eecac93ced8722d209199364cda3bc33da3bc3a23daef6be49ebd780511d0335490565b33301461132f576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044016107d9565b61133882611614565b6112c081611e59565b333014611382576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044016107d9565b8060005b818110156108f35760008484838181106113a2576113a2613378565b905060200201359050611421817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff604080517f7f25a23abc421d10864063e9a8ae5fd3fbd5116e156f148428b6a3a02ffd9454602080830191909152818301859052825180830384018152606090920190925280519101208190555050565b807f180e56184e3025975e8449fab79ff135cc5c3b3fe517a19bf8f111d69b33d2e27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60405161147391815260200190565b60405180910390a250600101611386565b60008083836040516020016114a3929190918252602082015260400190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052805160209091012054949350505050565b60007f6ffbd451000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083160161153557506001919050565b61078b82611ede565b73ffffffffffffffffffffffffffffffffffffffff81163b6115a4576040517f0c76093700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016107d9565b6115ac813055565b60405173ffffffffffffffffffffffffffffffffffffffff821681527f310ba5f1d2ed074b51e2eccd052a47ae9ab7c6b800d1fca3db3999d6a592ca03906020015b60405180910390a150565b60008061160785858561201f565b915091505b935093915050565b8061164b576040517f4294d12700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116747fea7157fa25e3aa17d0ae2d5280fa4e24d421c61842aa85e45194e1145aa72bf8829055565b6040518181527f307ed6bd941ee9fc80f369c94af5fa11e25bab5102a6140191756c5474a30bfa906020016115ee565b600061078b7f7f25a23abc421d10864063e9a8ae5fd3fbd5116e156f148428b6a3a02ffd945483611484565b6040517f190100000000000000000000000000000000000000000000000000000000000060208201524660228201527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b166042820152605681018290526000906076015b604051602081830303815290604052805190602001209050919050565b8060005b818110156118ac573684848381811061177457611774613378565b90506020028101906117869190613619565b90506040810135805a10156117db5782815a6040517f2bb3e3ba0000000000000000000000000000000000000000000000000000000081526004810193909352602483019190915260448201526064016107d9565b60006117ea6020840184613657565b15611829576118226118026080850160608601612ddb565b831561180e5783611810565b5a5b61181d60a0870187613672565b612053565b9050611864565b61186161183c6080850160608601612ddb565b6080850135841561184d578461184f565b5a5b61185c60a0880188613672565b61206e565b90505b80156118805760405188815260200160405180910390a06118a1565b6118a16118936040850160208601613657565b8961189c61208b565b6120aa565b505050600101611759565b5050505050565b606081901c6bffffffffffffffffffffffff821660006118d283610fd1565b905081811461191e576040517f9b6514f40000000000000000000000000000000000000000000000000000000081526004810184905260248101839052604481018290526064016107d9565b604080517f8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e60208083019190915281830186905282518083038401815260609092019092528051910120600183019081905560408051858152602081018390527f1f180c27086c7a39ea2a7b25239d1ab92348f07ca7bb59d1438fcf527568f881910160405180910390a15050505050565b60008080806119cb876119c6876006818b6136d7565b6120f6565b6000908152873560f01c6020818152604080842084526002909a013560e01c908190529890912090999198509695509350505050565b6000808080611a1c87611a17876001818b6136d7565b6119b0565b935093509350935093509350935093565b6040517f190100000000000000000000000000000000000000000000000000000000000060208201526000602282018190527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b1660428301526056820183905290607601611738565b6000808080806004600188013560e81c82611ab58383613730565b9050611ac78b61056383868d8f6136d7565b939b5091995097509550935087871015611b1f57611ae781848b8d6136d7565b89896040517fb006aba00000000000000000000000000000000000000000000000000000000081526004016107d99493929190613743565b8092505b88831015611c095760038301928a013560e81c9150611b428383613730565b90506000611b64611b528861258c565b8c8c87908692610563939291906136d7565b939c50919a5098509091505088881015611bbc57611b8482858c8e6136d7565b8a8a6040517fb006aba00000000000000000000000000000000000000000000000000000000081526004016107d99493929190613743565b848110611bff576040517f37daf62b00000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016107d9565b9350915081611b23565b505050939792965093509350565b8051606090600381901b60006005600483010467ffffffffffffffff811115611c4257611c42613112565b6040519080825280601f01601f191660200182016040528015611c6c576020820181803683370190505b5090506000806000805b86811015611d8057888181518110611c9057611c90613378565b01602001516008948501949390931b60f89390931c92909217915b60058410611d78576040805180820190915260208082527f6162636465666768696a6b6c6d6e6f707172737475767778797a323334353637818301527ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb90950194601f85871c16908110611d2157611d21613378565b602001015160f81c60f81b858381518110611d3e57611d3e613378565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600190910190611cab565b600101611c76565b508215611e24576040518060400160405280602081526020017f6162636465666768696a6b6c6d6e6f707172737475767778797a3233343536378152508360050383901b601f1681518110611dd757611dd7613378565b602001015160f81c60f81b848281518110611df457611df4613378565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505b50919695505050505050565b606081604051602001611e43919061376a565b6040516020818303038152906040529050919050565b611e827f0eecac93ced8722d209199364cda3bc33da3bc3a23daef6be49ebd780511d033829055565b6040518181527f20d3ef1b5738a9f6d7beae515432206e7a8e2740ca6dcf46a952190ad01bcb51906020016115ee565b600061078b7f849e7bdc245db17e50b9f43086f1914d70eb4dab6dd89af4d541d53353ad97de83611484565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fec6aba50000000000000000000000000000000000000000000000000000000001480611f7157507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b80611fbd57507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b8061200957507fffffffff0000000000000000000000000000000000000000000000000000000082167fc0ee0b8a00000000000000000000000000000000000000000000000000000000145b1561201657506001919050565b61078b826125c0565b6000804261202c866116a4565b1191508115612048578161203f8661261c565b9150915061160c565b611607858585612657565b60006040518284823760008084838989f49695505050505050565b6000604051828482376000808483898b8af1979650505050505050565b60603d604051915060208201818101604052818352816000823e505090565b82156120b857805160208201fd5b7f3dbd1590ea96dd3253a91f24e64e3a502e1225d602a5731357bc12643070ccd782826040516120e99291906137af565b60405180910390a1505050565b60008060005b8381101561258357600181019085013560f81c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810161219d57601582019186013560f881901c9060581c73ffffffffffffffffffffffffffffffffffffffff81169074ff0000000000000000000000000000000000000000168117856121835780612192565b60008681526020829052604090205b9550505050506120fc565b806122335760018201918681013560f81c9060430160006121c98a6121c484888c8e6136d7565b612695565b60ff841697909701969194508491905060a083901b74ff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff821617866122185780612227565b60008781526020829052604090205b965050505050506120fc565b6002810361235b576000808784013560f881901c9060581c73ffffffffffffffffffffffffffffffffffffffff16601586019550909250905060008885013560e81c600386018162ffffff1691508096508192505050600081860190506122ac8b848c8c8a9086926122a7939291906136d7565b612958565b6122f4578a836122be83898d8f6136d7565b6040517f9a9462320000000000000000000000000000000000000000000000000000000081526004016107d994939291906137c8565b60ff8416979097019694508460a084901b74ff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416178761233f578061234e565b60008881526020829052604090205b97505050505050506120fc565b6003810361238e576020820191860135836123765780612385565b60008481526020829052604090205b935050506120fc565b600481036123da576003808301928781013560e81c91908201016000806123bb8b6119c685898d8f6136d7565b600098895260205260409097209690970196509093506120fc92505050565b600681036124e25760008287013560f81c60018401935060ff16905060008784013560f01c60028501945061ffff16905060008885013560e81c600386018162ffffff1691508096508192505050600081860190506000806124488d8d8d8b9087926119c6939291906136d7565b9398508893909250905084821061245e57988501985b604080517f53657175656e6365206e657374656420636f6e6669673a0a0000000000000000602080830191909152603882018490526058820188905260788083018a90528351808403909101815260989092019092528051910120896124c457806124d3565b60008a81526020829052604090205b995050505050505050506120fc565b6005810361254e57602082019186013587810361251d577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff94505b600061252882612b05565b9050846125355780612544565b60008581526020829052604090205b94505050506120fc565b6040517fb2505f7c000000000000000000000000000000000000000000000000000000008152600481018290526024016107d9565b50935093915050565b7f8713a7c4465f6fbee2b6e9d6646d1d9f83fec929edfc4baf661f3c865bdd04d1600090815260208290526040812061078b565b60007ffda4dd44000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083160161261357506001919050565b61078b82612b40565b604080517f7f25a23abc421d10864063e9a8ae5fd3fbd5116e156f148428b6a3a02ffd94546020820152908101829052600090606001611738565b600080600080600061266a888888610e09565b50965091945092509050828210801590612688575061268881612b9c565b9450505050935093915050565b6000604282146126d55782826040517f2ee17a3d0000000000000000000000000000000000000000000000000000000081526004016107d9929190613808565b60006126ee6126e560018561381c565b85013560f81c90565b60ff169050604084013560f81c843560208601357f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0811115612762578686826040517fad4aac760000000000000000000000000000000000000000000000000000000081526004016107d99392919061382f565b8260ff16601b1415801561277a57508260ff16601c14155b156127b7578686846040517fe578897e0000000000000000000000000000000000000000000000000000000081526004016107d993929190613853565b60018403612824576040805160008152602081018083528a905260ff851691810191909152606081018390526080810182905260019060a0015b6020604051602081039080840390855afa158015612813573d6000803e3d6000fd5b5050506020604051035194506128fc565b600284036128c1576040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101899052600190605c01604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600084529083018083525260ff861690820152606081018490526080810183905260a0016127f1565b86868560016040517f9dfba8520000000000000000000000000000000000000000000000000000000081526004016107d9949392919061387a565b73ffffffffffffffffffffffffffffffffffffffff851661294d5786866040517f6c1719d20000000000000000000000000000000000000000000000000000000081526004016107d9929190613808565b505050509392505050565b600080838361296860018261381c565b81811061297757612977613378565b919091013560f81c91505060018114806129915750600281145b156129d6578473ffffffffffffffffffffffffffffffffffffffff166129b8878686612695565b73ffffffffffffffffffffffffffffffffffffffff16149150612afc565b60038103612ac15773ffffffffffffffffffffffffffffffffffffffff8516631626ba7e8786600087612a0a60018261381c565b92612a17939291906136d7565b6040518463ffffffff1660e01b8152600401612a35939291906135ba565b602060405180830381865afa158015612a52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a7691906138a6565b7fffffffff00000000000000000000000000000000000000000000000000000000167f1626ba7e00000000000000000000000000000000000000000000000000000000149150612afc565b83838260006040517f9dfba8520000000000000000000000000000000000000000000000000000000081526004016107d9949392919061387a565b50949350505050565b6040517f53657175656e636520737461746963206469676573743a0a0000000000000000602082015260388101829052600090605801611738565b60007fe4a77bbc000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831601612b9357506001919050565b61078b82612ba7565b600061078b82612c03565b60007fae9fa280000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831601612bfa57506001919050565b61078b82612c3a565b6000612c0e82612d24565b15612c1b57506001919050565b6000612c2683611eb2565b9050801580159061093f5750421092915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fac6a444e000000000000000000000000000000000000000000000000000000001480612ccd57507fffffffff0000000000000000000000000000000000000000000000000000000082167f36e7817500000000000000000000000000000000000000000000000000000000145b15612cda57506001919050565b7f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083161461078b565b6000811580159061078b5750507fea7157fa25e3aa17d0ae2d5280fa4e24d421c61842aa85e45194e1145aa72bf8541490565b8183823760009101908152919050565b7fffffffff00000000000000000000000000000000000000000000000000000000811681146107eb57600080fd5b600060208284031215612da757600080fd5b813561093f81612d67565b803573ffffffffffffffffffffffffffffffffffffffff81168114612dd657600080fd5b919050565b600060208284031215612ded57600080fd5b61093f82612db2565b60008083601f840112612e0857600080fd5b50813567ffffffffffffffff811115612e2057600080fd5b6020830191508360208260051b8501011115612e3b57600080fd5b9250929050565b60008060208385031215612e5557600080fd5b823567ffffffffffffffff811115612e6c57600080fd5b612e7885828601612df6565b90969095509350505050565b60008083601f840112612e9657600080fd5b50813567ffffffffffffffff811115612eae57600080fd5b602083019150836020828501011115612e3b57600080fd5b600080600080600060808688031215612ede57600080fd5b612ee786612db2565b9450612ef560208701612db2565b935060408601359250606086013567ffffffffffffffff811115612f1857600080fd5b612f2488828901612e84565b969995985093965092949392505050565b600080600060408486031215612f4a57600080fd5b83359250602084013567ffffffffffffffff811115612f6857600080fd5b612f7486828701612e84565b9497909650939450505050565b60008060008060408587031215612f9757600080fd5b843567ffffffffffffffff80821115612faf57600080fd5b612fbb88838901612e84565b90965094506020870135915080821115612fd457600080fd5b50612fe187828801612e84565b95989497509550505050565b600060208284031215612fff57600080fd5b5035919050565b6000806040838503121561301957600080fd5b50508035926020909101359150565b60008060008060006060868803121561304057600080fd5b853567ffffffffffffffff8082111561305857600080fd5b61306489838a01612df6565b909750955060208801359450604088013591508082111561308457600080fd5b50612f2488828901612e84565b60005b838110156130ac578181015183820152602001613094565b50506000910152565b600081518084526130cd816020860160208601613091565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061093f60208301846130b5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561315357600080fd5b813567ffffffffffffffff8082111561316b57600080fd5b818401915084601f83011261317f57600080fd5b81358181111561319157613191613112565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156131d7576131d7613112565b816040528281528760208487010111156131f057600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000806040838503121561322357600080fd5b823561322e81612d67565b915061323c60208401612db2565b90509250929050565b60008060008060008060008060a0898b03121561326157600080fd5b61326a89612db2565b975061327860208a01612db2565b9650604089013567ffffffffffffffff8082111561329557600080fd5b6132a18c838d01612df6565b909850965060608b01359150808211156132ba57600080fd5b6132c68c838d01612df6565b909650945060808b01359150808211156132df57600080fd5b506132ec8b828c01612e84565b999c989b5096995094979396929594505050565b60008060008060008060a0878903121561331957600080fd5b61332287612db2565b955061333060208801612db2565b94506040870135935060608701359250608087013567ffffffffffffffff81111561335a57600080fd5b61336689828a01612e84565b979a9699509497509295939492505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b80358015158114612dd657600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b81835260006020808501808196508560051b810191508460005b8781101561354257828403895281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4188360301811261345957600080fd5b870160c0613466826133a7565b151586526134758783016133a7565b15158688015260408281013590870152606073ffffffffffffffffffffffffffffffffffffffff6134a7828501612db2565b16908701526080828101359087015260a080830135368490037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe10181126134ed57600080fd5b90920187810192903567ffffffffffffffff81111561350b57600080fd5b80360384131561351a57600080fd5b828289015261352c83890182866133b7565b9c89019c9750505092860192505060010161341a565b5091979650505050505050565b60408152600560408201527f73656c663a00000000000000000000000000000000000000000000000000000060608201526080602082015260006109ae608083018486613400565b8381526040602082015260006135b1604083018486613400565b95945050505050565b8381526040602082015260006135b16040830184866133b7565b7f697066733a2f2f0000000000000000000000000000000000000000000000000081526000825161360c816007850160208701613091565b9190910160070192915050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4183360301811261364d57600080fd5b9190910192915050565b60006020828403121561366957600080fd5b61093f826133a7565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126136a757600080fd5b83018035915067ffffffffffffffff8211156136c257600080fd5b602001915036819003821315612e3b57600080fd5b600080858511156136e757600080fd5b838611156136f457600080fd5b5050820193919092039150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561078b5761078b613701565b6060815260006137576060830186886133b7565b6020830194909452506040015292915050565b7f62000000000000000000000000000000000000000000000000000000000000008152600082516137a2816001850160208701613091565b9190910160010192915050565b8281526040602082015260006109ae60408301846130b5565b84815273ffffffffffffffffffffffffffffffffffffffff841660208201526060604082015260006137fe6060830184866133b7565b9695505050505050565b6020815260006109ae6020830184866133b7565b8181038181111561078b5761078b613701565b6040815260006138436040830185876133b7565b9050826020830152949350505050565b6040815260006138676040830185876133b7565b905060ff83166020830152949350505050565b60608152600061388e6060830186886133b7565b60208301949094525090151560409091015292915050565b6000602082840312156138b857600080fd5b815161093f81612d6756fea264697066735822122030f6a03eecf061513999472455e58728f2693e3a3541e4333a309b089861d90064736f6c63430008110033', + deployedBytecode: + '0x6080604052600436106101c65760003560e01c806379e472c9116100f7578063a4ab5f9f11610095578063c71f1f9611610064578063c71f1f96146106a2578063d0748f71146106b7578063d59f7885146106d7578063f23a6e61146106f7576101cd565b8063a4ab5f9f14610605578063affed0e014610625578063b93ea7ad1461063a578063bc197c811461065a576101cd565b80638c3f5563116100d15780638c3f5563146105905780638efa6441146105b057806390042baf146105d2578063a38cef19146105e5576101cd565b806379e472c9146105085780637a9a162814610528578063853c506814610548576101cd565b806329561426116101645780634fcf3eca1161013e5780634fcf3eca1461047f57806351605d801461049f57806357c56d6b146104b457806361c2926c146104e8576101cd565b8063295614261461041157806341ea0302146104315780634598154f1461045f576101cd565b8063150b7a02116101a0578063150b7a02146103165780631626ba7e1461038c5780631a9b2337146103ac57806320c13b0b146103f1576101cd565b806301ffc9a7146102a1578063025b22bc146102d6578063038dbaac146102f6576101cd565b366101cd57005b60006101fc6000357fffffffff000000000000000000000000000000000000000000000000000000001661073d565b905073ffffffffffffffffffffffffffffffffffffffff81161561029f576000808273ffffffffffffffffffffffffffffffffffffffff16600036604051610245929190612d57565b600060405180830381855af49150503d8060008114610280576040519150601f19603f3d011682016040523d82523d6000602084013e610285565b606091505b50915091508161029757805160208201fd5b805160208201f35b005b3480156102ad57600080fd5b506102c16102bc366004612d95565b610791565b60405190151581526020015b60405180910390f35b3480156102e257600080fd5b5061029f6102f1366004612ddb565b61079c565b34801561030257600080fd5b5061029f610311366004612e42565b6107ee565b34801561032257600080fd5b5061035b610331366004612ec6565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016102cd565b34801561039857600080fd5b5061035b6103a7366004612f35565b6108f9565b3480156103b857600080fd5b506103cc6103c7366004612d95565b610946565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102cd565b3480156103fd57600080fd5b5061035b61040c366004612f81565b610951565b34801561041d57600080fd5b5061029f61042c366004612fed565b6109b6565b34801561043d57600080fd5b5061045161044c366004612fed565b610a00565b6040519081526020016102cd565b34801561046b57600080fd5b5061029f61047a366004613006565b610a0b565b34801561048b57600080fd5b5061029f61049a366004612d95565b610ad1565b3480156104ab57600080fd5b50610451610c00565b3480156104c057600080fd5b506104517f8713a7c4465f6fbee2b6e9d6646d1d9f83fec929edfc4baf661f3c865bdd04d181565b3480156104f457600080fd5b5061029f610503366004612e42565b610c2f565b34801561051457600080fd5b5061029f610523366004613006565b610cb5565b34801561053457600080fd5b5061029f610543366004613028565b610d73565b34801561055457600080fd5b50610568610563366004612f35565b610e09565b604080519586526020860194909452928401919091526060830152608082015260a0016102cd565b34801561059c57600080fd5b506104516105ab366004612fed565b610fd1565b3480156105bc57600080fd5b506105c5610ffd565b6040516102cd91906130ff565b6103cc6105e0366004613141565b61107e565b3480156105f157600080fd5b5061029f610600366004612fed565b61111a565b34801561061157600080fd5b50610451610620366004612fed565b611164565b34801561063157600080fd5b5061045161116f565b34801561064657600080fd5b5061029f610655366004613210565b61117b565b34801561066657600080fd5b5061035b610675366004613245565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b3480156106ae57600080fd5b506104516112c4565b3480156106c357600080fd5b5061029f6106d2366004613006565b6112ee565b3480156106e357600080fd5b5061029f6106f2366004612e42565b611341565b34801561070357600080fd5b5061035b610712366004613300565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b600061078b7fbe27a319efc8734e89e26ba4bc95f5c788584163b959f03fa04e2d7ab4b9a1207fffffffff000000000000000000000000000000000000000000000000000000008416611484565b92915050565b600061078b826114e2565b3330146107e2576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044015b60405180910390fd5b6107eb8161153e565b50565b33301461082f576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044016107d9565b8060005b818110156108f357600084848381811061084f5761084f613378565b9050602002013590506108af816000604080517f849e7bdc245db17e50b9f43086f1914d70eb4dab6dd89af4d541d53353ad97de602080830191909152818301859052825180830384018152606090920190925280519101208190555050565b807f804f6171d6008d9e16ee3aa0561fec328397f4ba2827a6605db388cfdefa3b0c60006040516108e291815260200190565b60405180910390a250600101610833565b50505050565b6000806109078585856115f9565b509050801561093957507f1626ba7e00000000000000000000000000000000000000000000000000000000905061093f565b50600090505b9392505050565b600061078b8261073d565b6000806109768686604051610967929190612d57565b604051809103902085856115f9565b50905080156109a857507f20c13b0b0000000000000000000000000000000000000000000000000000000090506109ae565b50600090505b949350505050565b3330146109f7576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044016107d9565b6107eb81611614565b600061078b826116a4565b333014610a4c576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044016107d9565b604080517f849e7bdc245db17e50b9f43086f1914d70eb4dab6dd89af4d541d53353ad97de602080830191909152818301859052825180830384018152606083019384905280519101208390559082905282907f804f6171d6008d9e16ee3aa0561fec328397f4ba2827a6605db388cfdefa3b0c906080015b60405180910390a25050565b333014610b12576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044016107d9565b6000610b1d8261073d565b73ffffffffffffffffffffffffffffffffffffffff1603610b8e576040517f1c3812cc0000000000000000000000000000000000000000000000000000000081527fffffffff00000000000000000000000000000000000000000000000000000000821660048201526024016107d9565b604080517fbe27a319efc8734e89e26ba4bc95f5c788584163b959f03fa04e2d7ab4b9a1206020808301919091527fffffffff00000000000000000000000000000000000000000000000000000000841682840152825180830384018152606090920190925280519101206000905550565b6000610c2a7fea7157fa25e3aa17d0ae2d5280fa4e24d421c61842aa85e45194e1145aa72bf85490565b905090565b333014610c70576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044016107d9565b6000610ca38383604051602001610c8892919061354f565b604051602081830303815290604052805190602001206116d0565b9050610cb0818484611755565b505050565b333014610cf6576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044016107d9565b604080517f7f25a23abc421d10864063e9a8ae5fd3fbd5116e156f148428b6a3a02ffd9454602080830191909152818301859052825180830384018152606083019384905280519101208390559082905282907f180e56184e3025975e8449fab79ff135cc5c3b3fe517a19bf8f111d69b33d2e290608001610ac5565b610d7c836118b3565b600080610db4858888604051602001610d9793929190613597565b6040516020818303038152906040528051906020012085856115f9565b9150915081610df5578084846040517f8f4a234f0000000000000000000000000000000000000000000000000000000081526004016107d9939291906135ba565b610e00818888611755565b50505050505050565b60008060008060008087876000818110610e2557610e25613378565b909101357fff00000000000000000000000000000000000000000000000000000000000000169150819050610e7b57610e5d896116d0565b9250610e6a8389896119b0565b92985090965094509150610fc69050565b7fff0000000000000000000000000000000000000000000000000000000000000081811601610eba57610ead896116d0565b9250610e6a838989611a01565b7ffe000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821601610f0c57610ead89611a2d565b7ffd000000000000000000000000000000000000000000000000000000000000007fff00000000000000000000000000000000000000000000000000000000000000821601610f7057610f60898989611a9a565b9550955095509550955050610fc6565b6040517f6085cd820000000000000000000000000000000000000000000000000000000081527fff00000000000000000000000000000000000000000000000000000000000000821660048201526024016107d9565b939792965093509350565b600061078b7f8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e83611484565b606061105a61105561100d6112c4565b6040517f017012200000000000000000000000000000000000000000000000000000000060208201526024810191909152604401604051602081830303815290604052611c17565b611e30565b60405160200161106a91906135d4565b604051602081830303815290604052905090565b60003330146110c1576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044016107d9565b81516020830134f060405173ffffffffffffffffffffffffffffffffffffffff821681529091507fa506ad4e7f05eceba62a023c3219e5bd98a615f4fa87e2afb08a2da5cf62bf0c9060200160405180910390a1919050565b33301461115b576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044016107d9565b6107eb81611e59565b600061078b82611eb2565b6000610c2a6000610fd1565b3330146111bc576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044016107d9565b60006111c78361073d565b73ffffffffffffffffffffffffffffffffffffffff1614611238576040517f5b4d6d6a0000000000000000000000000000000000000000000000000000000081527fffffffff00000000000000000000000000000000000000000000000000000000831660048201526024016107d9565b604080517fbe27a319efc8734e89e26ba4bc95f5c788584163b959f03fa04e2d7ab4b9a1206020808301919091527fffffffff000000000000000000000000000000000000000000000000000000008516828401528251808303840181526060909201909252805191012073ffffffffffffffffffffffffffffffffffffffff821690555050565b5050565b6000610c2a7f0eecac93ced8722d209199364cda3bc33da3bc3a23daef6be49ebd780511d0335490565b33301461132f576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044016107d9565b61133882611614565b6112c081611e59565b333014611382576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044016107d9565b8060005b818110156108f35760008484838181106113a2576113a2613378565b905060200201359050611421817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff604080517f7f25a23abc421d10864063e9a8ae5fd3fbd5116e156f148428b6a3a02ffd9454602080830191909152818301859052825180830384018152606090920190925280519101208190555050565b807f180e56184e3025975e8449fab79ff135cc5c3b3fe517a19bf8f111d69b33d2e27fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60405161147391815260200190565b60405180910390a250600101611386565b60008083836040516020016114a3929190918252602082015260400190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052805160209091012054949350505050565b60007f6ffbd451000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083160161153557506001919050565b61078b82611ede565b73ffffffffffffffffffffffffffffffffffffffff81163b6115a4576040517f0c76093700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016107d9565b6115ac813055565b60405173ffffffffffffffffffffffffffffffffffffffff821681527f310ba5f1d2ed074b51e2eccd052a47ae9ab7c6b800d1fca3db3999d6a592ca03906020015b60405180910390a150565b60008061160785858561201f565b915091505b935093915050565b8061164b576040517f4294d12700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116747fea7157fa25e3aa17d0ae2d5280fa4e24d421c61842aa85e45194e1145aa72bf8829055565b6040518181527f307ed6bd941ee9fc80f369c94af5fa11e25bab5102a6140191756c5474a30bfa906020016115ee565b600061078b7f7f25a23abc421d10864063e9a8ae5fd3fbd5116e156f148428b6a3a02ffd945483611484565b6040517f190100000000000000000000000000000000000000000000000000000000000060208201524660228201527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b166042820152605681018290526000906076015b604051602081830303815290604052805190602001209050919050565b8060005b818110156118ac573684848381811061177457611774613378565b90506020028101906117869190613619565b90506040810135805a10156117db5782815a6040517f2bb3e3ba0000000000000000000000000000000000000000000000000000000081526004810193909352602483019190915260448201526064016107d9565b60006117ea6020840184613657565b15611829576118226118026080850160608601612ddb565b831561180e5783611810565b5a5b61181d60a0870187613672565b612053565b9050611864565b61186161183c6080850160608601612ddb565b6080850135841561184d578461184f565b5a5b61185c60a0880188613672565b61206e565b90505b80156118805760405188815260200160405180910390a06118a1565b6118a16118936040850160208601613657565b8961189c61208b565b6120aa565b505050600101611759565b5050505050565b606081901c6bffffffffffffffffffffffff821660006118d283610fd1565b905081811461191e576040517f9b6514f40000000000000000000000000000000000000000000000000000000081526004810184905260248101839052604481018290526064016107d9565b604080517f8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e60208083019190915281830186905282518083038401815260609092019092528051910120600183019081905560408051858152602081018390527f1f180c27086c7a39ea2a7b25239d1ab92348f07ca7bb59d1438fcf527568f881910160405180910390a15050505050565b60008080806119cb876119c6876006818b6136d7565b6120f6565b6000908152873560f01c6020818152604080842084526002909a013560e01c908190529890912090999198509695509350505050565b6000808080611a1c87611a17876001818b6136d7565b6119b0565b935093509350935093509350935093565b6040517f190100000000000000000000000000000000000000000000000000000000000060208201526000602282018190527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b1660428301526056820183905290607601611738565b6000808080806004600188013560e81c82611ab58383613730565b9050611ac78b61056383868d8f6136d7565b939b5091995097509550935087871015611b1f57611ae781848b8d6136d7565b89896040517fb006aba00000000000000000000000000000000000000000000000000000000081526004016107d99493929190613743565b8092505b88831015611c095760038301928a013560e81c9150611b428383613730565b90506000611b64611b528861258c565b8c8c87908692610563939291906136d7565b939c50919a5098509091505088881015611bbc57611b8482858c8e6136d7565b8a8a6040517fb006aba00000000000000000000000000000000000000000000000000000000081526004016107d99493929190613743565b848110611bff576040517f37daf62b00000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016107d9565b9350915081611b23565b505050939792965093509350565b8051606090600381901b60006005600483010467ffffffffffffffff811115611c4257611c42613112565b6040519080825280601f01601f191660200182016040528015611c6c576020820181803683370190505b5090506000806000805b86811015611d8057888181518110611c9057611c90613378565b01602001516008948501949390931b60f89390931c92909217915b60058410611d78576040805180820190915260208082527f6162636465666768696a6b6c6d6e6f707172737475767778797a323334353637818301527ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb90950194601f85871c16908110611d2157611d21613378565b602001015160f81c60f81b858381518110611d3e57611d3e613378565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600190910190611cab565b600101611c76565b508215611e24576040518060400160405280602081526020017f6162636465666768696a6b6c6d6e6f707172737475767778797a3233343536378152508360050383901b601f1681518110611dd757611dd7613378565b602001015160f81c60f81b848281518110611df457611df4613378565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505b50919695505050505050565b606081604051602001611e43919061376a565b6040516020818303038152906040529050919050565b611e827f0eecac93ced8722d209199364cda3bc33da3bc3a23daef6be49ebd780511d033829055565b6040518181527f20d3ef1b5738a9f6d7beae515432206e7a8e2740ca6dcf46a952190ad01bcb51906020016115ee565b600061078b7f849e7bdc245db17e50b9f43086f1914d70eb4dab6dd89af4d541d53353ad97de83611484565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fec6aba50000000000000000000000000000000000000000000000000000000001480611f7157507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b80611fbd57507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b8061200957507fffffffff0000000000000000000000000000000000000000000000000000000082167fc0ee0b8a00000000000000000000000000000000000000000000000000000000145b1561201657506001919050565b61078b826125c0565b6000804261202c866116a4565b1191508115612048578161203f8661261c565b9150915061160c565b611607858585612657565b60006040518284823760008084838989f49695505050505050565b6000604051828482376000808483898b8af1979650505050505050565b60603d604051915060208201818101604052818352816000823e505090565b82156120b857805160208201fd5b7f3dbd1590ea96dd3253a91f24e64e3a502e1225d602a5731357bc12643070ccd782826040516120e99291906137af565b60405180910390a1505050565b60008060005b8381101561258357600181019085013560f81c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810161219d57601582019186013560f881901c9060581c73ffffffffffffffffffffffffffffffffffffffff81169074ff0000000000000000000000000000000000000000168117856121835780612192565b60008681526020829052604090205b9550505050506120fc565b806122335760018201918681013560f81c9060430160006121c98a6121c484888c8e6136d7565b612695565b60ff841697909701969194508491905060a083901b74ff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff821617866122185780612227565b60008781526020829052604090205b965050505050506120fc565b6002810361235b576000808784013560f881901c9060581c73ffffffffffffffffffffffffffffffffffffffff16601586019550909250905060008885013560e81c600386018162ffffff1691508096508192505050600081860190506122ac8b848c8c8a9086926122a7939291906136d7565b612958565b6122f4578a836122be83898d8f6136d7565b6040517f9a9462320000000000000000000000000000000000000000000000000000000081526004016107d994939291906137c8565b60ff8416979097019694508460a084901b74ff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416178761233f578061234e565b60008881526020829052604090205b97505050505050506120fc565b6003810361238e576020820191860135836123765780612385565b60008481526020829052604090205b935050506120fc565b600481036123da576003808301928781013560e81c91908201016000806123bb8b6119c685898d8f6136d7565b600098895260205260409097209690970196509093506120fc92505050565b600681036124e25760008287013560f81c60018401935060ff16905060008784013560f01c60028501945061ffff16905060008885013560e81c600386018162ffffff1691508096508192505050600081860190506000806124488d8d8d8b9087926119c6939291906136d7565b9398508893909250905084821061245e57988501985b604080517f53657175656e6365206e657374656420636f6e6669673a0a0000000000000000602080830191909152603882018490526058820188905260788083018a90528351808403909101815260989092019092528051910120896124c457806124d3565b60008a81526020829052604090205b995050505050505050506120fc565b6005810361254e57602082019186013587810361251d577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff94505b600061252882612b05565b9050846125355780612544565b60008581526020829052604090205b94505050506120fc565b6040517fb2505f7c000000000000000000000000000000000000000000000000000000008152600481018290526024016107d9565b50935093915050565b7f8713a7c4465f6fbee2b6e9d6646d1d9f83fec929edfc4baf661f3c865bdd04d1600090815260208290526040812061078b565b60007ffda4dd44000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083160161261357506001919050565b61078b82612b40565b604080517f7f25a23abc421d10864063e9a8ae5fd3fbd5116e156f148428b6a3a02ffd94546020820152908101829052600090606001611738565b600080600080600061266a888888610e09565b50965091945092509050828210801590612688575061268881612b9c565b9450505050935093915050565b6000604282146126d55782826040517f2ee17a3d0000000000000000000000000000000000000000000000000000000081526004016107d9929190613808565b60006126ee6126e560018561381c565b85013560f81c90565b60ff169050604084013560f81c843560208601357f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0811115612762578686826040517fad4aac760000000000000000000000000000000000000000000000000000000081526004016107d99392919061382f565b8260ff16601b1415801561277a57508260ff16601c14155b156127b7578686846040517fe578897e0000000000000000000000000000000000000000000000000000000081526004016107d993929190613853565b60018403612824576040805160008152602081018083528a905260ff851691810191909152606081018390526080810182905260019060a0015b6020604051602081039080840390855afa158015612813573d6000803e3d6000fd5b5050506020604051035194506128fc565b600284036128c1576040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101899052600190605c01604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600084529083018083525260ff861690820152606081018490526080810183905260a0016127f1565b86868560016040517f9dfba8520000000000000000000000000000000000000000000000000000000081526004016107d9949392919061387a565b73ffffffffffffffffffffffffffffffffffffffff851661294d5786866040517f6c1719d20000000000000000000000000000000000000000000000000000000081526004016107d9929190613808565b505050509392505050565b600080838361296860018261381c565b81811061297757612977613378565b919091013560f81c91505060018114806129915750600281145b156129d6578473ffffffffffffffffffffffffffffffffffffffff166129b8878686612695565b73ffffffffffffffffffffffffffffffffffffffff16149150612afc565b60038103612ac15773ffffffffffffffffffffffffffffffffffffffff8516631626ba7e8786600087612a0a60018261381c565b92612a17939291906136d7565b6040518463ffffffff1660e01b8152600401612a35939291906135ba565b602060405180830381865afa158015612a52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a7691906138a6565b7fffffffff00000000000000000000000000000000000000000000000000000000167f1626ba7e00000000000000000000000000000000000000000000000000000000149150612afc565b83838260006040517f9dfba8520000000000000000000000000000000000000000000000000000000081526004016107d9949392919061387a565b50949350505050565b6040517f53657175656e636520737461746963206469676573743a0a0000000000000000602082015260388101829052600090605801611738565b60007fe4a77bbc000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831601612b9357506001919050565b61078b82612ba7565b600061078b82612c03565b60007fae9fa280000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831601612bfa57506001919050565b61078b82612c3a565b6000612c0e82612d24565b15612c1b57506001919050565b6000612c2683611eb2565b9050801580159061093f5750421092915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fac6a444e000000000000000000000000000000000000000000000000000000001480612ccd57507fffffffff0000000000000000000000000000000000000000000000000000000082167f36e7817500000000000000000000000000000000000000000000000000000000145b15612cda57506001919050565b7f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083161461078b565b6000811580159061078b5750507fea7157fa25e3aa17d0ae2d5280fa4e24d421c61842aa85e45194e1145aa72bf8541490565b8183823760009101908152919050565b7fffffffff00000000000000000000000000000000000000000000000000000000811681146107eb57600080fd5b600060208284031215612da757600080fd5b813561093f81612d67565b803573ffffffffffffffffffffffffffffffffffffffff81168114612dd657600080fd5b919050565b600060208284031215612ded57600080fd5b61093f82612db2565b60008083601f840112612e0857600080fd5b50813567ffffffffffffffff811115612e2057600080fd5b6020830191508360208260051b8501011115612e3b57600080fd5b9250929050565b60008060208385031215612e5557600080fd5b823567ffffffffffffffff811115612e6c57600080fd5b612e7885828601612df6565b90969095509350505050565b60008083601f840112612e9657600080fd5b50813567ffffffffffffffff811115612eae57600080fd5b602083019150836020828501011115612e3b57600080fd5b600080600080600060808688031215612ede57600080fd5b612ee786612db2565b9450612ef560208701612db2565b935060408601359250606086013567ffffffffffffffff811115612f1857600080fd5b612f2488828901612e84565b969995985093965092949392505050565b600080600060408486031215612f4a57600080fd5b83359250602084013567ffffffffffffffff811115612f6857600080fd5b612f7486828701612e84565b9497909650939450505050565b60008060008060408587031215612f9757600080fd5b843567ffffffffffffffff80821115612faf57600080fd5b612fbb88838901612e84565b90965094506020870135915080821115612fd457600080fd5b50612fe187828801612e84565b95989497509550505050565b600060208284031215612fff57600080fd5b5035919050565b6000806040838503121561301957600080fd5b50508035926020909101359150565b60008060008060006060868803121561304057600080fd5b853567ffffffffffffffff8082111561305857600080fd5b61306489838a01612df6565b909750955060208801359450604088013591508082111561308457600080fd5b50612f2488828901612e84565b60005b838110156130ac578181015183820152602001613094565b50506000910152565b600081518084526130cd816020860160208601613091565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061093f60208301846130b5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561315357600080fd5b813567ffffffffffffffff8082111561316b57600080fd5b818401915084601f83011261317f57600080fd5b81358181111561319157613191613112565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156131d7576131d7613112565b816040528281528760208487010111156131f057600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000806040838503121561322357600080fd5b823561322e81612d67565b915061323c60208401612db2565b90509250929050565b60008060008060008060008060a0898b03121561326157600080fd5b61326a89612db2565b975061327860208a01612db2565b9650604089013567ffffffffffffffff8082111561329557600080fd5b6132a18c838d01612df6565b909850965060608b01359150808211156132ba57600080fd5b6132c68c838d01612df6565b909650945060808b01359150808211156132df57600080fd5b506132ec8b828c01612e84565b999c989b5096995094979396929594505050565b60008060008060008060a0878903121561331957600080fd5b61332287612db2565b955061333060208801612db2565b94506040870135935060608701359250608087013567ffffffffffffffff81111561335a57600080fd5b61336689828a01612e84565b979a9699509497509295939492505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b80358015158114612dd657600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b81835260006020808501808196508560051b810191508460005b8781101561354257828403895281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4188360301811261345957600080fd5b870160c0613466826133a7565b151586526134758783016133a7565b15158688015260408281013590870152606073ffffffffffffffffffffffffffffffffffffffff6134a7828501612db2565b16908701526080828101359087015260a080830135368490037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe10181126134ed57600080fd5b90920187810192903567ffffffffffffffff81111561350b57600080fd5b80360384131561351a57600080fd5b828289015261352c83890182866133b7565b9c89019c9750505092860192505060010161341a565b5091979650505050505050565b60408152600560408201527f73656c663a00000000000000000000000000000000000000000000000000000060608201526080602082015260006109ae608083018486613400565b8381526040602082015260006135b1604083018486613400565b95945050505050565b8381526040602082015260006135b16040830184866133b7565b7f697066733a2f2f0000000000000000000000000000000000000000000000000081526000825161360c816007850160208701613091565b9190910160070192915050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4183360301811261364d57600080fd5b9190910192915050565b60006020828403121561366957600080fd5b61093f826133a7565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126136a757600080fd5b83018035915067ffffffffffffffff8211156136c257600080fd5b602001915036819003821315612e3b57600080fd5b600080858511156136e757600080fd5b838611156136f457600080fd5b5050820193919092039150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561078b5761078b613701565b6060815260006137576060830186886133b7565b6020830194909452506040015292915050565b7f62000000000000000000000000000000000000000000000000000000000000008152600082516137a2816001850160208701613091565b9190910160010192915050565b8281526040602082015260006109ae60408301846130b5565b84815273ffffffffffffffffffffffffffffffffffffffff841660208201526060604082015260006137fe6060830184866133b7565b9695505050505050565b6020815260006109ae6020830184866133b7565b8181038181111561078b5761078b613701565b6040815260006138436040830185876133b7565b9050826020830152949350505050565b6040815260006138676040830185876133b7565b905060ff83166020830152949350505050565b60608152600061388e6060830186886133b7565b60208301949094525090151560409091015292915050565b6000602082840312156138b857600080fd5b815161093f81612d6756fea264697066735822122030f6a03eecf061513999472455e58728f2693e3a3541e4333a309b089861d90064736f6c63430008110033', + linkReferences: {}, + deployedLinkReferences: {} +} diff --git a/packages/tests/src/builds/v2/artifacts/UniversalSigValidator.ts b/packages/tests/src/builds/v2/artifacts/UniversalSigValidator.ts new file mode 100644 index 0000000000..e1e10b0878 --- /dev/null +++ b/packages/tests/src/builds/v2/artifacts/UniversalSigValidator.ts @@ -0,0 +1,190 @@ +export const universalSigValidator = { + _format: 'hh-sol-artifact-1', + contractName: 'UniversalSigValidator', + sourceName: 'contracts/EIP6492.sol', + abi: [ + { + inputs: [ + { + internalType: 'bytes', + name: 'error', + type: 'bytes' + } + ], + name: 'ERC1271Revert', + type: 'error' + }, + { + inputs: [ + { + internalType: 'bytes', + name: 'error', + type: 'bytes' + } + ], + name: 'ERC6492DeployFailed', + type: 'error' + }, + { + inputs: [ + { + internalType: 'address', + name: '_signer', + type: 'address' + }, + { + internalType: 'bytes32', + name: '_hash', + type: 'bytes32' + }, + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + } + ], + name: 'isValidSig', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool' + } + ], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '_signer', + type: 'address' + }, + { + internalType: 'bytes32', + name: '_hash', + type: 'bytes32' + }, + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + }, + { + internalType: 'bool', + name: 'allowSideEffects', + type: 'bool' + }, + { + internalType: 'bool', + name: 'deployAlreadyDeployed', + type: 'bool' + } + ], + name: 'isValidSigImpl', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool' + } + ], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '_signer', + type: 'address' + }, + { + internalType: 'bytes32', + name: '_hash', + type: 'bytes32' + }, + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + } + ], + name: 'isValidSigNoThrow', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool' + } + ], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '_signer', + type: 'address' + }, + { + internalType: 'bytes32', + name: '_hash', + type: 'bytes32' + }, + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + } + ], + name: 'isValidSigWithSideEffects', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool' + } + ], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '_signer', + type: 'address' + }, + { + internalType: 'bytes32', + name: '_hash', + type: 'bytes32' + }, + { + internalType: 'bytes', + name: '_signature', + type: 'bytes' + } + ], + name: 'isValidSigWithSideEffectsNoThrow', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool' + } + ], + stateMutability: 'nonpayable', + type: 'function' + } + ], + bytecode: + '0x608060405234801561001057600080fd5b50610fbc806100206000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c806376be4cea1161005057806376be4cea146100a65780638f068430146100b957806398ef1ed8146100cc57600080fd5b80631c6453271461006c5780633d787b6314610093575b600080fd5b61007f61007a366004610ad4565b6100df565b604051901515815260200160405180910390f35b61007f6100a1366004610ad4565b61023d565b61007f6100b4366004610b3e565b61031e565b61007f6100c7366004610ad4565b6108e1565b61007f6100da366004610ad4565b61096e565b6040517f76be4cea00000000000000000000000000000000000000000000000000000000815260009030906376be4cea9061012890889088908890889088908190600401610bc3565b6020604051808303816000875af1925050508015610181575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261017e91810190610c45565b60015b610232573d8080156101af576040519150601f19603f3d011682016040523d82523d6000602084013e6101b4565b606091505b508051600181900361022757816000815181106101d3576101d3610c69565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0100000000000000000000000000000000000000000000000000000000000000149250610235915050565b600092505050610235565b90505b949350505050565b6040517f76be4cea00000000000000000000000000000000000000000000000000000000815260009030906376be4cea906102879088908890889088906001908990600401610bc3565b6020604051808303816000875af19250505080156102e0575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526102dd91810190610c45565b60015b610232573d80801561030e576040519150601f19603f3d011682016040523d82523d6000602084013e610313565b606091505b506000915050610235565b600073ffffffffffffffffffffffffffffffffffffffff87163b6060827f64926492649264926492649264926492649264926492649264926492649264928888610369602082610c98565b610375928b9290610cd8565b61037e91610d02565b1490508015610484576000606089828a610399602082610c98565b926103a693929190610cd8565b8101906103b39190610e18565b955090925090508415806103c45750865b1561047d576000808373ffffffffffffffffffffffffffffffffffffffff16836040516103f19190610eb2565b6000604051808303816000865af19150503d806000811461042e576040519150601f19603f3d011682016040523d82523d6000602084013e610433565b606091505b50915091508161047a57806040517f9d0d6e2d0000000000000000000000000000000000000000000000000000000081526004016104719190610f18565b60405180910390fd5b50505b50506104be565b87878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509294505050505b80806104ca5750600083115b156106bb576040517f1626ba7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8b1690631626ba7e90610523908c908690600401610f2b565b602060405180830381865afa92505050801561057a575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261057791810190610f44565b60015b61060f573d8080156105a8576040519150601f19603f3d011682016040523d82523d6000602084013e6105ad565b606091505b50851580156105bc5750600084115b156105db576105d08b8b8b8b8b600161031e565b9450505050506108d7565b806040517f6f2a95990000000000000000000000000000000000000000000000000000000081526004016104719190610f18565b7fffffffff0000000000000000000000000000000000000000000000000000000081167f1626ba7e000000000000000000000000000000000000000000000000000000001480158161065f575086155b801561066b5750600085115b1561068b5761067f8c8c8c8c8c600161031e565b955050505050506108d7565b841580156106965750825b80156106a0575087155b156106af57806000526001601ffd5b94506108d79350505050565b6041871461074b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5369676e617475726556616c696461746f72237265636f7665725369676e657260448201527f3a20696e76616c6964207369676e6174757265206c656e6774680000000000006064820152608401610471565b600061075a6020828a8c610cd8565b61076391610d02565b90506000610775604060208b8d610cd8565b61077e91610d02565b905060008a8a604081811061079557610795610c69565b919091013560f81c915050601b81148015906107b557508060ff16601c14155b15610842576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f5369676e617475726556616c696461746f723a20696e76616c6964207369676e60448201527f617475726520762076616c7565000000000000000000000000000000000000006064820152608401610471565b6040805160008152602081018083528e905260ff831691810191909152606081018490526080810183905273ffffffffffffffffffffffffffffffffffffffff8e169060019060a0016020604051602081039080840390855afa1580156108ad573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff161496505050505050505b9695505050505050565b6040517f76be4cea00000000000000000000000000000000000000000000000000000000815260009030906376be4cea9061092b9088908890889088906001908990600401610bc3565b6020604051808303816000875af115801561094a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102329190610c45565b6040517f76be4cea00000000000000000000000000000000000000000000000000000000815260009030906376be4cea906109b790889088908890889088908190600401610bc3565b6020604051808303816000875af1925050508015610a10575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252610a0d91810190610c45565b60015b610232573d808015610a3e576040519150601f19603f3d011682016040523d82523d6000602084013e610a43565b606091505b5080516001819003610a6257816000815181106101d3576101d3610c69565b8082fd5b73ffffffffffffffffffffffffffffffffffffffff81168114610a8857600080fd5b50565b60008083601f840112610a9d57600080fd5b50813567ffffffffffffffff811115610ab557600080fd5b602083019150836020828501011115610acd57600080fd5b9250929050565b60008060008060608587031215610aea57600080fd5b8435610af581610a66565b935060208501359250604085013567ffffffffffffffff811115610b1857600080fd5b610b2487828801610a8b565b95989497509550505050565b8015158114610a8857600080fd5b60008060008060008060a08789031215610b5757600080fd5b8635610b6281610a66565b955060208701359450604087013567ffffffffffffffff811115610b8557600080fd5b610b9189828a01610a8b565b9095509350506060870135610ba581610b30565b91506080870135610bb581610b30565b809150509295509295509295565b73ffffffffffffffffffffffffffffffffffffffff8716815285602082015260a060408201528360a0820152838560c0830137600060c085830181019190915292151560608201529015156080820152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101019392505050565b600060208284031215610c5757600080fd5b8151610c6281610b30565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b81810381811115610cd2577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b92915050565b60008085851115610ce857600080fd5b83861115610cf557600080fd5b5050820193919092039150565b80356020831015610cd2577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112610d7e57600080fd5b813567ffffffffffffffff80821115610d9957610d99610d3e565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610ddf57610ddf610d3e565b81604052838152866020858801011115610df857600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600060608486031215610e2d57600080fd5b8335610e3881610a66565b9250602084013567ffffffffffffffff80821115610e5557600080fd5b610e6187838801610d6d565b93506040860135915080821115610e7757600080fd5b50610e8486828701610d6d565b9150509250925092565b60005b83811015610ea9578181015183820152602001610e91565b50506000910152565b60008251610ec4818460208701610e8e565b9190910192915050565b60008151808452610ee6816020860160208601610e8e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610c626020830184610ece565b8281526040602082015260006102356040830184610ece565b600060208284031215610f5657600080fd5b81517fffffffff0000000000000000000000000000000000000000000000000000000081168114610c6257600080fdfea26469706673582212201a72aed4b15ffb05b6502997a9bb655992e06590bd26b336dfbb153d7ff6f34b64736f6c63430008120033', + deployedBytecode: + '0x608060405234801561001057600080fd5b50600436106100675760003560e01c806376be4cea1161005057806376be4cea146100a65780638f068430146100b957806398ef1ed8146100cc57600080fd5b80631c6453271461006c5780633d787b6314610093575b600080fd5b61007f61007a366004610ad4565b6100df565b604051901515815260200160405180910390f35b61007f6100a1366004610ad4565b61023d565b61007f6100b4366004610b3e565b61031e565b61007f6100c7366004610ad4565b6108e1565b61007f6100da366004610ad4565b61096e565b6040517f76be4cea00000000000000000000000000000000000000000000000000000000815260009030906376be4cea9061012890889088908890889088908190600401610bc3565b6020604051808303816000875af1925050508015610181575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261017e91810190610c45565b60015b610232573d8080156101af576040519150601f19603f3d011682016040523d82523d6000602084013e6101b4565b606091505b508051600181900361022757816000815181106101d3576101d3610c69565b6020910101517fff00000000000000000000000000000000000000000000000000000000000000167f0100000000000000000000000000000000000000000000000000000000000000149250610235915050565b600092505050610235565b90505b949350505050565b6040517f76be4cea00000000000000000000000000000000000000000000000000000000815260009030906376be4cea906102879088908890889088906001908990600401610bc3565b6020604051808303816000875af19250505080156102e0575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526102dd91810190610c45565b60015b610232573d80801561030e576040519150601f19603f3d011682016040523d82523d6000602084013e610313565b606091505b506000915050610235565b600073ffffffffffffffffffffffffffffffffffffffff87163b6060827f64926492649264926492649264926492649264926492649264926492649264928888610369602082610c98565b610375928b9290610cd8565b61037e91610d02565b1490508015610484576000606089828a610399602082610c98565b926103a693929190610cd8565b8101906103b39190610e18565b955090925090508415806103c45750865b1561047d576000808373ffffffffffffffffffffffffffffffffffffffff16836040516103f19190610eb2565b6000604051808303816000865af19150503d806000811461042e576040519150601f19603f3d011682016040523d82523d6000602084013e610433565b606091505b50915091508161047a57806040517f9d0d6e2d0000000000000000000000000000000000000000000000000000000081526004016104719190610f18565b60405180910390fd5b50505b50506104be565b87878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509294505050505b80806104ca5750600083115b156106bb576040517f1626ba7e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8b1690631626ba7e90610523908c908690600401610f2b565b602060405180830381865afa92505050801561057a575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261057791810190610f44565b60015b61060f573d8080156105a8576040519150601f19603f3d011682016040523d82523d6000602084013e6105ad565b606091505b50851580156105bc5750600084115b156105db576105d08b8b8b8b8b600161031e565b9450505050506108d7565b806040517f6f2a95990000000000000000000000000000000000000000000000000000000081526004016104719190610f18565b7fffffffff0000000000000000000000000000000000000000000000000000000081167f1626ba7e000000000000000000000000000000000000000000000000000000001480158161065f575086155b801561066b5750600085115b1561068b5761067f8c8c8c8c8c600161031e565b955050505050506108d7565b841580156106965750825b80156106a0575087155b156106af57806000526001601ffd5b94506108d79350505050565b6041871461074b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f5369676e617475726556616c696461746f72237265636f7665725369676e657260448201527f3a20696e76616c6964207369676e6174757265206c656e6774680000000000006064820152608401610471565b600061075a6020828a8c610cd8565b61076391610d02565b90506000610775604060208b8d610cd8565b61077e91610d02565b905060008a8a604081811061079557610795610c69565b919091013560f81c915050601b81148015906107b557508060ff16601c14155b15610842576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f5369676e617475726556616c696461746f723a20696e76616c6964207369676e60448201527f617475726520762076616c7565000000000000000000000000000000000000006064820152608401610471565b6040805160008152602081018083528e905260ff831691810191909152606081018490526080810183905273ffffffffffffffffffffffffffffffffffffffff8e169060019060a0016020604051602081039080840390855afa1580156108ad573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff161496505050505050505b9695505050505050565b6040517f76be4cea00000000000000000000000000000000000000000000000000000000815260009030906376be4cea9061092b9088908890889088906001908990600401610bc3565b6020604051808303816000875af115801561094a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102329190610c45565b6040517f76be4cea00000000000000000000000000000000000000000000000000000000815260009030906376be4cea906109b790889088908890889088908190600401610bc3565b6020604051808303816000875af1925050508015610a10575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252610a0d91810190610c45565b60015b610232573d808015610a3e576040519150601f19603f3d011682016040523d82523d6000602084013e610a43565b606091505b5080516001819003610a6257816000815181106101d3576101d3610c69565b8082fd5b73ffffffffffffffffffffffffffffffffffffffff81168114610a8857600080fd5b50565b60008083601f840112610a9d57600080fd5b50813567ffffffffffffffff811115610ab557600080fd5b602083019150836020828501011115610acd57600080fd5b9250929050565b60008060008060608587031215610aea57600080fd5b8435610af581610a66565b935060208501359250604085013567ffffffffffffffff811115610b1857600080fd5b610b2487828801610a8b565b95989497509550505050565b8015158114610a8857600080fd5b60008060008060008060a08789031215610b5757600080fd5b8635610b6281610a66565b955060208701359450604087013567ffffffffffffffff811115610b8557600080fd5b610b9189828a01610a8b565b9095509350506060870135610ba581610b30565b91506080870135610bb581610b30565b809150509295509295509295565b73ffffffffffffffffffffffffffffffffffffffff8716815285602082015260a060408201528360a0820152838560c0830137600060c085830181019190915292151560608201529015156080820152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016909101019392505050565b600060208284031215610c5757600080fd5b8151610c6281610b30565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b81810381811115610cd2577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b92915050565b60008085851115610ce857600080fd5b83861115610cf557600080fd5b5050820193919092039150565b80356020831015610cd2577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f830112610d7e57600080fd5b813567ffffffffffffffff80821115610d9957610d99610d3e565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715610ddf57610ddf610d3e565b81604052838152866020858801011115610df857600080fd5b836020870160208301376000602085830101528094505050505092915050565b600080600060608486031215610e2d57600080fd5b8335610e3881610a66565b9250602084013567ffffffffffffffff80821115610e5557600080fd5b610e6187838801610d6d565b93506040860135915080821115610e7757600080fd5b50610e8486828701610d6d565b9150509250925092565b60005b83811015610ea9578181015183820152602001610e91565b50506000910152565b60008251610ec4818460208701610e8e565b9190910192915050565b60008151808452610ee6816020860160208601610e8e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610c626020830184610ece565b8281526040602082015260006102356040830184610ece565b600060208284031215610f5657600080fd5b81517fffffffff0000000000000000000000000000000000000000000000000000000081168114610c6257600080fdfea26469706673582212201a72aed4b15ffb05b6502997a9bb655992e06590bd26b336dfbb153d7ff6f34b64736f6c63430008120033', + linkReferences: {}, + deployedLinkReferences: {} +} diff --git a/packages/tests/src/builds/v2/index.ts b/packages/tests/src/builds/v2/index.ts new file mode 100644 index 0000000000..100e9f06be --- /dev/null +++ b/packages/tests/src/builds/v2/index.ts @@ -0,0 +1,5 @@ +export { factory } from './artifacts/Factory' +export { guestModule } from './artifacts/GuestModule' +export { mainModule } from './artifacts/MainModule' +export { mainModuleUpgradable } from './artifacts/MainModuleUpgradable' +export { universalSigValidator } from './artifacts/UniversalSigValidator' diff --git a/packages/tests/src/configs/index.ts b/packages/tests/src/configs/index.ts new file mode 100644 index 0000000000..5b1f4b7f70 --- /dev/null +++ b/packages/tests/src/configs/index.ts @@ -0,0 +1 @@ +export * as random from './random' diff --git a/packages/tests/src/configs/random.ts b/packages/tests/src/configs/random.ts new file mode 100644 index 0000000000..e25d841298 --- /dev/null +++ b/packages/tests/src/configs/random.ts @@ -0,0 +1,47 @@ +import { v1, v2 } from '@0xsequence/core' +import { ethers } from 'ethers' +import { maxForBits, randomBigNumber, randomBool } from '../utils' + +export function genRandomV1Config( + threshold: ethers.BigNumberish = randomBigNumber(0, maxForBits(16)), + numSigners: ethers.BigNumberish = randomBigNumber(1, 24) +): v1.config.WalletConfig { + const signers: v1.config.AddressMember[] = [] + + for (let i = ethers.constants.Zero; i.lt(numSigners); i = i.add(1)) { + signers.push({ + address: ethers.Wallet.createRandom().address, + weight: randomBigNumber(0, maxForBits(8)) + }) + } + + return { version: 1, threshold, signers } +} + +export function genRandomV2Config( + threshold: ethers.BigNumberish = randomBigNumber(0, maxForBits(16)), + checkpoint: ethers.BigNumberish = randomBigNumber(0, maxForBits(32)), + numSigners: ethers.BigNumberish = randomBigNumber(1, 24), + numSubdigests: ethers.BigNumberish = randomBigNumber(0, 24), + useMerkleTopology: boolean = randomBool() +): v2.config.WalletConfig { + const signers: v2.config.SignerLeaf[] = [] + for (let i = ethers.constants.Zero; i.lt(numSigners); i = i.add(1)) { + signers.push({ + address: ethers.Wallet.createRandom().address, + weight: randomBigNumber(0, maxForBits(8)) + }) + } + + const subdigests: v2.config.SubdigestLeaf[] = [] + for (let i = ethers.constants.Zero; i.lt(numSubdigests); i = i.add(1)) { + subdigests.push({ + subdigest: ethers.utils.hexlify(ethers.utils.randomBytes(32)) + }) + } + + const topologyBuilder = useMerkleTopology ? v2.config.merkleTopologyBuilder : v2.config.legacyTopologyBuilder + const tree = topologyBuilder([...signers, ...subdigests]) + + return { version: 2, threshold, checkpoint, tree } +} diff --git a/packages/tests/src/context/index.ts b/packages/tests/src/context/index.ts new file mode 100644 index 0000000000..bbf4f864ee --- /dev/null +++ b/packages/tests/src/context/index.ts @@ -0,0 +1,13 @@ +import { ethers } from 'ethers' + +import { deployV1Context } from './v1' +import { deployV2Context } from './v2' + +export async function deploySequenceContexts(signer: ethers.Signer) { + const v1 = await deployV1Context(signer) + const v2 = await deployV2Context(signer) + return { 1: v1, 2: v2 } +} + +export * as v1 from './v1' +export * as v2 from './v2' diff --git a/packages/tests/src/context/v1.ts b/packages/tests/src/context/v1.ts new file mode 100644 index 0000000000..cce948bbdb --- /dev/null +++ b/packages/tests/src/context/v1.ts @@ -0,0 +1,103 @@ +import { ethers } from 'ethers' +import { isContract } from '../utils' + +// These are the Sequence v1 contracts +// we use them if they are available +const predefinedAddresses = { + factory: '0xf9D09D634Fb818b05149329C1dcCFAeA53639d96', + mainModule: '0xd01F11855bCcb95f88D7A48492F66410d4637313', + mainModuleUpgradable: '0x7EFE6cE415956c5f80C6530cC6cc81b4808F6118', + guestModule: '0x02390F3E6E5FD1C6786CB78FD3027C117a9955A7', + multiCallUtils: '0xd130B43062D875a4B7aF3f8fc036Bc6e9D3E1B3E' +} + +export async function deployV1Context(signer: ethers.Signer): Promise<{ + version: 1 + factory: string + mainModule: string + mainModuleUpgradable: string + guestModule: string + multiCallUtils: string + walletCreationCode: string +}> { + // See if signer's provider has the contracts already deployed + const provider = signer.provider + if (!provider) { + throw new Error('Signer has no provider') + } + + if ( + await Promise.all(Object.values(predefinedAddresses).map(address => isContract(provider, address))).then(r => r.every(x => x)) + ) { + console.log('Using predefined addresses for V1 contracts') + + return { + version: 1, + + factory: predefinedAddresses.factory, + mainModule: predefinedAddresses.mainModule, + mainModuleUpgradable: predefinedAddresses.mainModuleUpgradable, + guestModule: predefinedAddresses.guestModule, + multiCallUtils: predefinedAddresses.multiCallUtils, + + walletCreationCode: '0x603a600e3d39601a805130553df3363d3d373d3d3d363d30545af43d82803e903d91601857fd5bf3' + } + } + + console.log('Predefined addresses for V1 contracts not found, deploying new ones') + + // Try deploying the v1 contracts using the v1 singleton factory + await signer.sendTransaction({ + to: '0x9c5a87452d4FAC0cbd53BDCA580b20A45526B3AB', + value: ethers.utils.parseEther('0.02170000000014'), + gasLimit: 8000000 + }) + + await signer.provider?.sendTransaction( + '0xf9010880852416b84e01830222e08080b8b66080604052348015600f57600080fd5b50609980601d6000396000f3fe60a06020601f369081018290049091028201604052608081815260009260609284918190838280828437600092018290525084519495509392505060208401905034f5604080516001600160a01b0383168152905191935081900360200190a0505000fea26469706673582212205a310755225e3c740b2f013fb6343f4c205e7141fcdf15947f5f0e0e818727fb64736f6c634300060a00331ca01820182018201820182018201820182018201820182018201820182018201820a01820182018201820182018201820182018201820182018201820182018201820' + ) + + // Deploy universal deployer + await signer.sendTransaction({ + to: '0x1b926fbb24a9f78dcdd3272f2d86f5d0660e59c0', + data: '0x608060405234801561001057600080fd5b5061013d806100206000396000f3fe60806040526004361061001e5760003560e01c80639c4ae2d014610023575b600080fd5b6100cb6004803603604081101561003957600080fd5b81019060208101813564010000000081111561005457600080fd5b82018360208201111561006657600080fd5b8035906020019184600183028401116401000000008311171561008857600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955050913592506100cd915050565b005b60008183516020850134f56040805173ffffffffffffffffffffffffffffffffffffffff83168152905191925081900360200190a050505056fea264697066735822122033609f614f03931b92d88c309d698449bb77efcd517328d341fa4f923c5d8c7964736f6c63430007060033', + gasLimit: 8000000 + }) + + // Deploy factory + await signer.sendTransaction({ + to: '0x8a5bc19e22d6ad55a2c763b93a75d09f321fe764', + data: '0x9c4ae2d00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e8608060405234801561001057600080fd5b506101c8806100206000396000f3fe60806040526004361061001e5760003560e01c806332c02a1414610023575b600080fd5b61005c6004803603604081101561003957600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610085565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b60008060405180606001604052806028815260200161016b602891398473ffffffffffffffffffffffffffffffffffffffff166040516020018083805190602001908083835b6020831061010857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016100cb565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199092169116179052920193845250604080518085038152938201905282519294508693508401905034f594935050505056fe603a600e3d39601a805130553df3363d3d373d3d3d363d30545af43d82803e903d91601857fd5bf3a26469706673582212209b0bce93afab3297b9ebf4e58fa642ef123d74bcbd3bdb4e48b662eb12b430ca64736f6c63430007060033000000000000000000000000000000000000000000000000', + gasLimit: 8000000 + }) + + // Deploy mainModule + await signer.sendTransaction({ + to: '0x8a5bc19e22d6ad55a2c763b93a75d09f321fe764', + data: '0x9c4ae2d0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002d8360c06040523480156200001157600080fd5b5060405162002d6338038062002d638339810160408190526200003491620000e2565b80600060405180606001604052806028815260200162002d3b60289139306001600160a01b03166040516020018083805190602001908083835b602083106200008f5780518252601f1990920191602091820191016200006e565b51815160209384036101000a60001901801990921691161790529201938452506040805180850381529382019052825192019190912060805250505060601b6001600160601b03191660a0525062000112565b600060208284031215620000f4578081fd5b81516001600160a01b03811681146200010b578182fd5b9392505050565b60805160a05160601c612bf862000143600039806106d55280611baa5250806106b15280611bdb5250612bf86000f3fe6080604052600436106101125760003560e01c80634fcf3eca116100a557806390042baf11610074578063b93ea7ad11610059578063b93ea7ad146103c5578063bc197c81146103e5578063f23a6e611461040557610119565b806390042baf1461039d578063affed0e0146103b057610119565b80634fcf3eca1461031d57806361c2926c1461033d5780637a9a16281461035d5780638c3f55631461037d57610119565b80631a9b2337116100e15780631a9b23371461029957806320c13b0b146102c6578063257671f5146102e65780632dd310001461030857610119565b806301ffc9a7146101f4578063025b22bc1461022a578063150b7a021461024c5780631626ba7e1461027957610119565b3661011957005b60006101486000357fffffffff0000000000000000000000000000000000000000000000000000000016610425565b905073ffffffffffffffffffffffffffffffffffffffff8116156101f1576000808273ffffffffffffffffffffffffffffffffffffffff166000366040518083838082843760405192019450600093509091505080830381855af49150503d80600081146101d2576040519150601f19603f3d011682016040523d82523d6000602084013e6101d7565b606091505b5091509150816101e957805160208201fd5b805160208201f35b50005b34801561020057600080fd5b5061021461020f366004612401565b61047b565b6040516102219190612633565b60405180910390f35b34801561023657600080fd5b5061024a610245366004612166565b610486565b005b34801561025857600080fd5b5061026c610267366004612237565b6105a7565b6040516102219190612660565b34801561028557600080fd5b5061026c6102943660046123b7565b6105d1565b3480156102a557600080fd5b506102b96102b4366004612401565b61064a565b6040516102219190612612565b3480156102d257600080fd5b5061026c6102e136600461244d565b610655565b3480156102f257600080fd5b506102fb6106af565b604051610221919061263e565b34801561031457600080fd5b506102b96106d3565b34801561032957600080fd5b5061024a610338366004612401565b6106f7565b34801561034957600080fd5b5061024a61035836600461231a565b6107d5565b34801561036957600080fd5b5061024a61037836600461234d565b61086e565b34801561038957600080fd5b506102fb6103983660046124e9565b6108ea565b6102b96103ab3660046124b6565b610916565b3480156103bc57600080fd5b506102fb6109ca565b3480156103d157600080fd5b5061024a6103e036600461241b565b6109db565b3480156103f157600080fd5b5061026c610400366004612180565b610ab4565b34801561041157600080fd5b5061026c6104203660046122a4565b610ae1565b60006104737fbe27a319efc8734e89e26ba4bc95f5c788584163b959f03fa04e2d7ab4b9a1207fffffffff000000000000000000000000000000000000000000000000000000008416610b0c565b90505b919050565b600061047382610b39565b3330146104de576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180612b9c6027913960400191505060405180910390fd5b6104fd8173ffffffffffffffffffffffffffffffffffffffff16610b96565b610552576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526039815260200180612a826039913960400191505060405180910390fd5b61055b81610b9c565b6040805173ffffffffffffffffffffffffffffffffffffffff8316815290517f310ba5f1d2ed074b51e2eccd052a47ae9ab7c6b800d1fca3db3999d6a592ca039181900360200190a150565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b600061061b6105df85610ba0565b84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610c0092505050565b1561064357507f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b600061047382610425565b600061067f6105df86866040518083838082843760405192018290039091209350610ba092505050565b156106a757507f20c13b0b000000000000000000000000000000000000000000000000000000005b949350505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b33301461074f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180612b9c6027913960400191505060405180910390fd5b600061075a82610425565b73ffffffffffffffffffffffffffffffffffffffff1614156107c7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b8152602001806128e0602b913960400191505060405180910390fd5b6107d2816000610df8565b50565b33301461082d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180612b9c6027913960400191505060405180910390fd5b600061085e82604051602001610843919061277e565b60405160208183030381529060405280519060200120610ba0565b905061086a8183610e5b565b5050565b6108778261102a565b600061088f83856040516020016108439291906127c5565b905061089b8183610c00565b6108da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108d190612721565b60405180910390fd5b6108e48185610e5b565b50505050565b60006104737f8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e83610b0c565b6000333014610970576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180612b9c6027913960400191505060405180910390fd5b81516020830134f06040805173ffffffffffffffffffffffffffffffffffffffff8316815290519192507fa506ad4e7f05eceba62a023c3219e5bd98a615f4fa87e2afb08a2da5cf62bf0c919081900360200190a1919050565b60006109d660006108ea565b905090565b333014610a33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180612b9c6027913960400191505060405180910390fd5b6000610a3e83610425565b73ffffffffffffffffffffffffffffffffffffffff1614610aaa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001806129f4602c913960400191505060405180910390fd5b61086a8282610df8565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b60408051602080820194909452808201929092528051808303820181526060909201905280519101205490565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f90042baf000000000000000000000000000000000000000000000000000000001415610b8d57506001610476565b610473826110ce565b3b151590565b3055565b604080517f19010000000000000000000000000000000000000000000000000000000000006020808301919091524660228301523060601b6042830152605680830194909452825180830390940184526076909101909152815191012090565b6000806000610c0e8461120f565b909250905061ffff821660005b8551831015610dd55760008080610c32898761127d565b975060ff91821694501691506001831415610c5a57610c5189876112fe565b96509050610d7e565b82610c86576060610c6b8a88611376565b97509050610c798b82611427565b9150828501945050610d7e565b6002831415610d2d57610c9989876112fe565b965090506000610ca98a886117b1565b975061ffff1690506060610cbe8b8984611822565b98509050610ccd8c8483611911565b610d22576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001806129c26032913960400191505060405180910390fd5b505092810192610d7e565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c8152602001806128b4602c913960400191505060405180910390fd5b848282604051602001808481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019350505050604051602081830303815290604052805190602001209450505050610c1b565b8361ffff168110158015610ded5750610ded82611b59565b979650505050505050565b61086a7fbe27a319efc8734e89e26ba4bc95f5c788584163b959f03fa04e2d7ab4b9a1207fffffffff00000000000000000000000000000000000000000000000000000000841673ffffffffffffffffffffffffffffffffffffffff8416611c37565b60005b8151811015611025576000828281518110610e7557fe5b602002602001015190506000606082604001515a1015610ec1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108d1906126c4565b825115610f5957826060015173ffffffffffffffffffffffffffffffffffffffff168360400151600014610ef9578360400151610efb565b5a5b8460a00151604051610f0d91906125f6565b6000604051808303818686f4925050503d8060008114610f49576040519150601f19603f3d011682016040523d82523d6000602084013e610f4e565b606091505b509092509050610fee565b826060015173ffffffffffffffffffffffffffffffffffffffff1683608001518460400151600014610f8f578460400151610f91565b5a5b908560a00151604051610fa491906125f6565b600060405180830381858888f193505050503d8060008114610fe2576040519150601f19603f3d011682016040523d82523d6000602084013e610fe7565b606091505b5090925090505b811561100f5785604051611002919061263e565b60405180910390a061101a565b61101a838783611c65565b505050600101610e5e565b505050565b60008061103683611cb5565b915091506000611045836108ea565b9050808214611080576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108d19061268d565b6001820161108e8482611cce565b7f1f180c27086c7a39ea2a7b25239d1ab92348f07ca7bb59d1438fcf527568f88184826040516110bf9291906127de565b60405180910390a15050505050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fec6aba5000000000000000000000000000000000000000000000000000000000148061116157507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b806111ad57507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b806111f957507fffffffff0000000000000000000000000000000000000000000000000000000082167fc0ee0b8a00000000000000000000000000000000000000000000000000000000145b1561120657506001610476565b61047382611cf9565b6020810151815160f09190911c90600290811115611278576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061292e6027913960400191505060405180910390fd5b915091565b8082016020015160f881901c9060f01c60ff166002830183811161129d57fe5b84518111156112f7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180612af76026913960400191505060405180910390fd5b9250925092565b8082016020015160601c6014820182811161131557fe5b835181111561136f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602381526020018061290b6023913960400191505060405180910390fd5b9250929050565b6040805160428082526080820190925260609160009190602082018180368337019050509150828401602001805160208401526020810151604084015260228101516042840152506042830190508281116113cd57fe5b835181111561136f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180612a5f6023913960400191505060405180910390fd5b60008151604214611483576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603a81526020018061287a603a913960400191505060405180910390fd5b60008260018451038151811061149557fe5b602001015160f81c60f81b60f81c60ff1690506000836040815181106114b757fe5b016020015160f81c905060006114cd8582611d56565b905060006114dc866020611d56565b90507f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0811115611557576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d81526020018061283d603d913960400191505060405180910390fd5b8260ff16601b1415801561156f57508260ff16601c14155b156115c5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d815260200180612955603d913960400191505060405180910390fd5b60018414156116395760018784848460405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015611628573d6000803e3d6000fd5b50505060206040510351945061173b565b60028414156116ea5760018760405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012084848460405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015611628573d6000803e3d6000fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c815260200180612abb603c913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff85166117a7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260308152602001806129926030913960400191505060405180910390fd5b5050505092915050565b8082016020015160f01c600282018281116117c857fe5b835181111561136f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180612b3e6022913960400191505060405180910390fd5b606060008267ffffffffffffffff8111801561183d57600080fd5b506040519080825280601f01601f191660200182016040528015611868576020820181803683370190505b509150838501602001600060205b8581101561188f57908201518482015260208101611876565b84860160200180519390920151908501525250828201838110156118af57fe5b8451811115611909576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180612b1d6021913960400191505060405180910390fd5b935093915050565b6000808260018451038151811061192457fe5b016020015160f81c9050600181148061193d5750600281145b15611981578373ffffffffffffffffffffffffffffffffffffffff166119638685611427565b73ffffffffffffffffffffffffffffffffffffffff16149150611b51565b6003811415611b005782517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81018452604080517f1626ba7e000000000000000000000000000000000000000000000000000000008152600481018881526024820192835286516044830152865173ffffffffffffffffffffffffffffffffffffffff891693631626ba7e938b938a9390929160640190602085019080838360005b83811015611a3b578181015183820152602001611a23565b50505050905090810190601f168015611a685780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b158015611a8657600080fd5b505afa158015611a9a573d6000803e3d6000fd5b505050506040513d6020811015611ab057600080fd5b50519084527fffffffff00000000000000000000000000000000000000000000000000000000167f1626ba7e00000000000000000000000000000000000000000000000000000000149150611b51565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603f815260200180612a20603f913960400191505060405180910390fd5b509392505050565b604080517fff000000000000000000000000000000000000000000000000000000000000006020808301919091527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060601b166021830152603582018490527f0000000000000000000000000000000000000000000000000000000000000000605580840191909152835180840390910181526075909201909252805191012073ffffffffffffffffffffffffffffffffffffffff163014919050565b6040805160208082019590955280820193909352805180840382018152606090930190528151919092012055565b826020015115611c7757805160208201fd5b7f3dbd1590ea96dd3253a91f24e64e3a502e1225d602a5731357bc12643070ccd78282604051611ca8929190612647565b60405180910390a1505050565b606081901c916bffffffffffffffffffffffff90911690565b61086a7f8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e8383611c37565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f025b22bc000000000000000000000000000000000000000000000000000000001415611d4d57506001610476565b61047382611dbe565b60008160200183511015611db5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c815260200180612b60603c913960400191505060405180910390fd5b50016020015190565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f389901c7000000000000000000000000000000000000000000000000000000001415611e1257506001610476565b6104738260007fffffffff0000000000000000000000000000000000000000000000000000000082161580611e8857507fffffffff0000000000000000000000000000000000000000000000000000000082167f36e7817500000000000000000000000000000000000000000000000000000000145b15611e9557506001610476565b7f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614610473565b803573ffffffffffffffffffffffffffffffffffffffff8116811461047657600080fd5b600082601f830112611f13578081fd5b8135602067ffffffffffffffff80831115611f2a57fe5b611f3782838502016127ec565b83815282810190868401865b86811015612013578135890160c0807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0838e03011215611f8157898afd5b604080518281018181108a82111715611f9657fe5b8252611fa3848b01612063565b8152611fb0828501612063565b8a8201526060808501358383015260809250611fcd838601611edf565b9082015260a08481013583830152928401359289841115611fec578c8dfd5b611ffa8f8c868801016120e3565b9082015287525050509285019290850190600101611f43565b509098975050505050505050565b60008083601f840112612032578182fd5b50813567ffffffffffffffff811115612049578182fd5b602083019150836020808302850101111561136f57600080fd5b8035801515811461047657600080fd5b80357fffffffff000000000000000000000000000000000000000000000000000000008116811461047657600080fd5b60008083601f8401126120b4578182fd5b50813567ffffffffffffffff8111156120cb578182fd5b60208301915083602082850101111561136f57600080fd5b600082601f8301126120f3578081fd5b813567ffffffffffffffff81111561210757fe5b61213860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016127ec565b81815284602083860101111561214c578283fd5b816020850160208301379081016020019190915292915050565b600060208284031215612177578081fd5b61064382611edf565b60008060008060008060008060a0898b03121561219b578384fd5b6121a489611edf565b97506121b260208a01611edf565b9650604089013567ffffffffffffffff808211156121ce578586fd5b6121da8c838d01612021565b909850965060608b01359150808211156121f2578586fd5b6121fe8c838d01612021565b909650945060808b0135915080821115612216578384fd5b506122238b828c016120a3565b999c989b5096995094979396929594505050565b60008060008060006080868803121561224e578081fd5b61225786611edf565b945061226560208701611edf565b935060408601359250606086013567ffffffffffffffff811115612287578182fd5b612293888289016120a3565b969995985093965092949392505050565b60008060008060008060a087890312156122bc578182fd5b6122c587611edf565b95506122d360208801611edf565b94506040870135935060608701359250608087013567ffffffffffffffff8111156122fc578283fd5b61230889828a016120a3565b979a9699509497509295939492505050565b60006020828403121561232b578081fd5b813567ffffffffffffffff811115612341578182fd5b6106a784828501611f03565b600080600060608486031215612361578283fd5b833567ffffffffffffffff80821115612378578485fd5b61238487838801611f03565b94506020860135935060408601359150808211156123a0578283fd5b506123ad868287016120e3565b9150509250925092565b6000806000604084860312156123cb578283fd5b83359250602084013567ffffffffffffffff8111156123e8578283fd5b6123f4868287016120a3565b9497909650939450505050565b600060208284031215612412578081fd5b61064382612073565b6000806040838503121561242d578182fd5b61243683612073565b915061244460208401611edf565b90509250929050565b60008060008060408587031215612462578182fd5b843567ffffffffffffffff80821115612479578384fd5b612485888389016120a3565b9096509450602087013591508082111561249d578384fd5b506124aa878288016120a3565b95989497509550505050565b6000602082840312156124c7578081fd5b813567ffffffffffffffff8111156124dd578182fd5b6106a7848285016120e3565b6000602082840312156124fa578081fd5b5035919050565b6000815180845260208085018081965082840281019150828601855b8581101561259f5782840389528151805115158552858101511515868601526040808201519086015260608082015173ffffffffffffffffffffffffffffffffffffffff16908601526080808201519086015260a09081015160c09186018290529061258b818701836125ac565b9a87019a955050509084019060010161251d565b5091979650505050505050565b600081518084526125c4816020860160208601612810565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60008251612608818460208701612810565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b901515815260200190565b90815260200190565b6000838252604060208301526106a760408301846125ac565b7fffffffff0000000000000000000000000000000000000000000000000000000091909116815260200190565b6020808252601f908201527f4d61696e4d6f64756c65235f617574683a20494e56414c49445f4e4f4e434500604082015260600190565b60208082526024908201527f4d6f64756c6543616c6c73235f657865637574653a204e4f545f454e4f55474860408201527f5f47415300000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526026908201527f4d6f64756c6543616c6c7323657865637574653a20494e56414c49445f53494760408201527f4e41545552450000000000000000000000000000000000000000000000000000606082015260800190565b600060408252600560408301527f73656c663a0000000000000000000000000000000000000000000000000000006060830152608060208301526106436080830184612501565b6000838252604060208301526106a76040830184612501565b918252602082015260400190565b60405181810167ffffffffffffffff8111828210171561280857fe5b604052919050565b60005b8381101561282b578181015183820152602001612813565b838111156108e4575050600091015256fe5369676e617475726556616c696461746f72237265636f7665725369676e65723a20696e76616c6964207369676e6174757265202773272076616c75655369676e617475726556616c696461746f72237265636f7665725369676e65723a20696e76616c6964207369676e6174757265206c656e6774684d6f64756c6541757468235f7369676e617475726556616c69646174696f6e20494e56414c49445f464c41474d6f64756c65486f6f6b732372656d6f7665486f6f6b3a20484f4f4b5f4e4f545f524547495354455245444c696242797465732372656164416464726573733a204f55545f4f465f424f554e44534c696242797465732372656164466972737455696e7431363a204f55545f4f465f424f554e44535369676e617475726556616c696461746f72237265636f7665725369676e65723a20696e76616c6964207369676e6174757265202776272076616c75655369676e617475726556616c696461746f72237265636f7665725369676e65723a20494e56414c49445f5349474e45524d6f64756c6541757468235f7369676e617475726556616c69646174696f6e3a20494e56414c49445f5349474e41545552454d6f64756c65486f6f6b7323616464486f6f6b3a20484f4f4b5f414c52454144595f524547495354455245445369676e617475726556616c696461746f7223697356616c69645369676e61747572653a20554e535550504f525445445f5349474e41545552455f545950454c696242797465732372656164427974657336363a204f55545f4f465f424f554e44534d6f64756c6555706461746523757064617465496d706c656d656e746174696f6e3a20494e56414c49445f494d504c454d454e544154494f4e5369676e617475726556616c696461746f72237265636f7665725369676e65723a20554e535550504f525445445f5349474e41545552455f545950454c69624279746573237265616455696e743855696e74383a204f55545f4f465f424f554e44534c69624279746573237265616442797465733a204f55545f4f465f424f554e44534c69624279746573237265616455696e7431363a204f55545f4f465f424f554e44534c696242797465732372656164427974657333323a20475245415445525f4f525f455155414c5f544f5f33325f4c454e4754485f52455155495245444d6f64756c6553656c6641757468236f6e6c7953656c663a204e4f545f415554484f52495a4544a2646970667358221220b34deca9dd75815e4ef8a9279e45750ec5554b22c673e160bdba849d80f5888564736f6c63430007060033603a600e3d39601a805130553df3363d3d373d3d3d363d30545af43d82803e903d91601857fd5bf3000000000000000000000000f9d09d634fb818b05149329c1dccfaea53639d960000000000000000000000000000000000000000000000000000000000', + gasLimit: 8000000 + }) + + // Deploy mainModuleUpgradable + await signer.sendTransaction({ + to: '0x8A5Bc19e22D6aD55a2c763B93A75d09F321fe764', + data: '0x9c4ae2d0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002d07608060405234801561001057600080fd5b50612ce7806100206000396000f3fe6080604052600436106101125760003560e01c806351605d80116100a557806390042baf11610074578063b93ea7ad11610059578063b93ea7ad146103d0578063bc197c81146103f0578063f23a6e611461041057610119565b806390042baf146103a8578063affed0e0146103bb57610119565b806351605d801461032657806361c2926c146103485780637a9a1628146103685780638c3f55631461038857610119565b80631a9b2337116100e15780631a9b23371461029957806320c13b0b146102c657806329561426146102e65780634fcf3eca1461030657610119565b806301ffc9a7146101f4578063025b22bc1461022a578063150b7a021461024c5780631626ba7e1461027957610119565b3661011957005b60006101486000357fffffffff0000000000000000000000000000000000000000000000000000000016610430565b905073ffffffffffffffffffffffffffffffffffffffff8116156101f1576000808273ffffffffffffffffffffffffffffffffffffffff166000366040518083838082843760405192019450600093509091505080830381855af49150503d80600081146101d2576040519150601f19603f3d011682016040523d82523d6000602084013e6101d7565b606091505b5091509150816101e957805160208201fd5b805160208201f35b50005b34801561020057600080fd5b5061021461020f3660046124d4565b610486565b60405161022191906126eb565b60405180910390f35b34801561023657600080fd5b5061024a610245366004612221565b610491565b005b34801561025857600080fd5b5061026c6102673660046122f2565b6105b2565b6040516102219190612718565b34801561028557600080fd5b5061026c61029436600461248a565b6105dc565b3480156102a557600080fd5b506102b96102b43660046124d4565b610655565b60405161022191906126ca565b3480156102d257600080fd5b5061026c6102e1366004612520565b610660565b3480156102f257600080fd5b5061024a610301366004612472565b6106ba565b34801561031257600080fd5b5061024a6103213660046124d4565b6107c8565b34801561033257600080fd5b5061033b6108a6565b60405161022191906126f6565b34801561035457600080fd5b5061024a6103633660046123d5565b6108d6565b34801561037457600080fd5b5061024a610383366004612408565b61096f565b34801561039457600080fd5b5061033b6103a3366004612472565b6109eb565b6102b96103b6366004612589565b610a17565b3480156103c757600080fd5b5061033b610acb565b3480156103dc57600080fd5b5061024a6103eb3660046124ee565b610ad7565b3480156103fc57600080fd5b5061026c61040b36600461223b565b610bb0565b34801561041c57600080fd5b5061026c61042b36600461235f565b610bdd565b600061047e7fbe27a319efc8734e89e26ba4bc95f5c788584163b959f03fa04e2d7ab4b9a1207fffffffff000000000000000000000000000000000000000000000000000000008416610c08565b90505b919050565b600061047e82610c35565b3330146104e9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180612c8b6027913960400191505060405180910390fd5b6105088173ffffffffffffffffffffffffffffffffffffffff16610c92565b61055d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526039815260200180612b716039913960400191505060405180910390fd5b61056681610c98565b6040805173ffffffffffffffffffffffffffffffffffffffff8316815290517f310ba5f1d2ed074b51e2eccd052a47ae9ab7c6b800d1fca3db3999d6a592ca039181900360200190a150565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b60006106266105ea85610c9c565b84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610cfc92505050565b1561064e57507f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b600061047e82610430565b600061068a6105ea86866040518083838082843760405192018290039091209350610c9c92505050565b156106b257507f20c13b0b000000000000000000000000000000000000000000000000000000005b949350505050565b333014610712576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180612c8b6027913960400191505060405180910390fd5b80610768576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260378152602001806129986037913960400191505060405180910390fd5b6107927fea7157fa25e3aa17d0ae2d5280fa4e24d421c61842aa85e45194e1145aa72bf882610ef4565b6040805182815290517f307ed6bd941ee9fc80f369c94af5fa11e25bab5102a6140191756c5474a30bfa9181900360200190a150565b333014610820576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180612c8b6027913960400191505060405180910390fd5b600061082b82610430565b73ffffffffffffffffffffffffffffffffffffffff161415610898576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b8152602001806129cf602b913960400191505060405180910390fd5b6108a3816000610ef8565b50565b60006108d17fea7157fa25e3aa17d0ae2d5280fa4e24d421c61842aa85e45194e1145aa72bf8610f5b565b905090565b33301461092e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180612c8b6027913960400191505060405180910390fd5b600061095f826040516020016109449190612836565b60405160208183030381529060405280519060200120610c9c565b905061096b8183610f5f565b5050565b6109788261112e565b6000610990838560405160200161094492919061287d565b905061099c8183610cfc565b6109db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109d2906127d9565b60405180910390fd5b6109e58185610f5f565b50505050565b600061047e7f8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e83610c08565b6000333014610a71576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180612c8b6027913960400191505060405180910390fd5b81516020830134f06040805173ffffffffffffffffffffffffffffffffffffffff8316815290519192507fa506ad4e7f05eceba62a023c3219e5bd98a615f4fa87e2afb08a2da5cf62bf0c919081900360200190a1919050565b60006108d160006109eb565b333014610b2f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180612c8b6027913960400191505060405180910390fd5b6000610b3a83610430565b73ffffffffffffffffffffffffffffffffffffffff1614610ba6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180612ae3602c913960400191505060405180910390fd5b61096b8282610ef8565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b60408051602080820194909452808201929092528051808303820181526060909201905280519101205490565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f90042baf000000000000000000000000000000000000000000000000000000001415610c8957506001610481565b61047e826111d2565b3b151590565b3055565b604080517f19010000000000000000000000000000000000000000000000000000000000006020808301919091524660228301523060601b6042830152605680830194909452825180830390940184526076909101909152815191012090565b6000806000610d0a84611313565b909250905061ffff821660005b8551831015610ed15760008080610d2e8987611381565b975060ff91821694501691506001831415610d5657610d4d8987611402565b96509050610e7a565b82610d82576060610d678a8861147a565b97509050610d758b8261152b565b9150828501945050610e7a565b6002831415610e2957610d958987611402565b965090506000610da58a886118b5565b975061ffff1690506060610dba8b8984611926565b98509050610dc98c8483611a15565b610e1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526032815260200180612ab16032913960400191505060405180910390fd5b505092810192610e7a565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c81526020018061296c602c913960400191505060405180910390fd5b848282604051602001808481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019350505050604051602081830303815290604052805190602001209450505050610d17565b8361ffff168110158015610ee95750610ee982611c5d565b979650505050505050565b9055565b61096b7fbe27a319efc8734e89e26ba4bc95f5c788584163b959f03fa04e2d7ab4b9a1207fffffffff00000000000000000000000000000000000000000000000000000000841673ffffffffffffffffffffffffffffffffffffffff8416611c9a565b5490565b60005b8151811015611129576000828281518110610f7957fe5b602002602001015190506000606082604001515a1015610fc5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109d29061277c565b82511561105d57826060015173ffffffffffffffffffffffffffffffffffffffff168360400151600014610ffd578360400151610fff565b5a5b8460a0015160405161101191906126ae565b6000604051808303818686f4925050503d806000811461104d576040519150601f19603f3d011682016040523d82523d6000602084013e611052565b606091505b5090925090506110f2565b826060015173ffffffffffffffffffffffffffffffffffffffff1683608001518460400151600014611093578460400151611095565b5a5b908560a001516040516110a891906126ae565b600060405180830381858888f193505050503d80600081146110e6576040519150601f19603f3d011682016040523d82523d6000602084013e6110eb565b606091505b5090925090505b8115611113578560405161110691906126f6565b60405180910390a061111e565b61111e838783611cc8565b505050600101610f62565b505050565b60008061113a83611d18565b915091506000611149836109eb565b9050808214611184576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109d290612745565b600182016111928482611d31565b7f1f180c27086c7a39ea2a7b25239d1ab92348f07ca7bb59d1438fcf527568f88184826040516111c3929190612896565b60405180910390a15050505050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fec6aba5000000000000000000000000000000000000000000000000000000000148061126557507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b806112b157507fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a0200000000000000000000000000000000000000000000000000000000145b806112fd57507fffffffff0000000000000000000000000000000000000000000000000000000082167fc0ee0b8a00000000000000000000000000000000000000000000000000000000145b1561130a57506001610481565b61047e82611d5c565b6020810151815160f09190911c9060029081111561137c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180612a1d6027913960400191505060405180910390fd5b915091565b8082016020015160f881901c9060f01c60ff16600283018381116113a157fe5b84518111156113fb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180612be66026913960400191505060405180910390fd5b9250925092565b8082016020015160601c6014820182811161141957fe5b8351811115611473576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806129fa6023913960400191505060405180910390fd5b9250929050565b6040805160428082526080820190925260609160009190602082018180368337019050509150828401602001805160208401526020810151604084015260228101516042840152506042830190508281116114d157fe5b8351811115611473576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180612b4e6023913960400191505060405180910390fd5b60008151604214611587576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603a815260200180612932603a913960400191505060405180910390fd5b60008260018451038151811061159957fe5b602001015160f81c60f81b60f81c60ff1690506000836040815181106115bb57fe5b016020015160f81c905060006115d18582611db9565b905060006115e0866020611db9565b90507f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a081111561165b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d8152602001806128f5603d913960400191505060405180910390fd5b8260ff16601b1415801561167357508260ff16601c14155b156116c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d815260200180612a44603d913960400191505060405180910390fd5b600184141561173d5760018784848460405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa15801561172c573d6000803e3d6000fd5b50505060206040510351945061183f565b60028414156117ee5760018760405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012084848460405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa15801561172c573d6000803e3d6000fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c815260200180612baa603c913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff85166118ab576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526030815260200180612a816030913960400191505060405180910390fd5b5050505092915050565b8082016020015160f01c600282018281116118cc57fe5b8351811115611473576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180612c2d6022913960400191505060405180910390fd5b606060008267ffffffffffffffff8111801561194157600080fd5b506040519080825280601f01601f19166020018201604052801561196c576020820181803683370190505b509150838501602001600060205b858110156119935790820151848201526020810161197a565b84860160200180519390920151908501525250828201838110156119b357fe5b8451811115611a0d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180612c0c6021913960400191505060405180910390fd5b935093915050565b60008082600184510381518110611a2857fe5b016020015160f81c90506001811480611a415750600281145b15611a85578373ffffffffffffffffffffffffffffffffffffffff16611a67868561152b565b73ffffffffffffffffffffffffffffffffffffffff16149150611c55565b6003811415611c045782517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81018452604080517f1626ba7e000000000000000000000000000000000000000000000000000000008152600481018881526024820192835286516044830152865173ffffffffffffffffffffffffffffffffffffffff891693631626ba7e938b938a9390929160640190602085019080838360005b83811015611b3f578181015183820152602001611b27565b50505050905090810190601f168015611b6c5780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b158015611b8a57600080fd5b505afa158015611b9e573d6000803e3d6000fd5b505050506040513d6020811015611bb457600080fd5b50519084527fffffffff00000000000000000000000000000000000000000000000000000000167f1626ba7e00000000000000000000000000000000000000000000000000000000149150611c55565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603f815260200180612b0f603f913960400191505060405180910390fd5b509392505050565b6000811580159061047e5750611c927fea7157fa25e3aa17d0ae2d5280fa4e24d421c61842aa85e45194e1145aa72bf8610f5b565b909114919050565b6040805160208082019590955280820193909352805180840382018152606090930190528151919092012055565b826020015115611cda57805160208201fd5b7f3dbd1590ea96dd3253a91f24e64e3a502e1225d602a5731357bc12643070ccd78282604051611d0b9291906126ff565b60405180910390a1505050565b606081901c916bffffffffffffffffffffffff90911690565b61096b7f8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e8383611c9a565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f025b22bc000000000000000000000000000000000000000000000000000000001415611db057506001610481565b61047e82611e21565b60008160200183511015611e18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c815260200180612c4f603c913960400191505060405180910390fd5b50016020015190565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f389901c7000000000000000000000000000000000000000000000000000000001415611e7557506001610481565b61047e8260007fffffffff0000000000000000000000000000000000000000000000000000000082167f783649a6000000000000000000000000000000000000000000000000000000001415611ecd57506001610481565b61047e8260007fffffffff0000000000000000000000000000000000000000000000000000000082161580611f4357507fffffffff0000000000000000000000000000000000000000000000000000000082167f36e7817500000000000000000000000000000000000000000000000000000000145b15611f5057506001610481565b7f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083161461047e565b803573ffffffffffffffffffffffffffffffffffffffff8116811461048157600080fd5b600082601f830112611fce578081fd5b8135602067ffffffffffffffff80831115611fe557fe5b611ff282838502016128a4565b83815282810190868401865b868110156120ce578135890160c0807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0838e0301121561203c57898afd5b604080518281018181108a8211171561205157fe5b825261205e848b0161211e565b815261206b82850161211e565b8a8201526060808501358383015260809250612088838601611f9a565b9082015260a084810135838301529284013592898411156120a7578c8dfd5b6120b58f8c8688010161219e565b9082015287525050509285019290850190600101611ffe565b509098975050505050505050565b60008083601f8401126120ed578182fd5b50813567ffffffffffffffff811115612104578182fd5b602083019150836020808302850101111561147357600080fd5b8035801515811461048157600080fd5b80357fffffffff000000000000000000000000000000000000000000000000000000008116811461048157600080fd5b60008083601f84011261216f578182fd5b50813567ffffffffffffffff811115612186578182fd5b60208301915083602082850101111561147357600080fd5b600082601f8301126121ae578081fd5b813567ffffffffffffffff8111156121c257fe5b6121f360207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016128a4565b818152846020838601011115612207578283fd5b816020850160208301379081016020019190915292915050565b600060208284031215612232578081fd5b61064e82611f9a565b60008060008060008060008060a0898b031215612256578384fd5b61225f89611f9a565b975061226d60208a01611f9a565b9650604089013567ffffffffffffffff80821115612289578586fd5b6122958c838d016120dc565b909850965060608b01359150808211156122ad578586fd5b6122b98c838d016120dc565b909650945060808b01359150808211156122d1578384fd5b506122de8b828c0161215e565b999c989b5096995094979396929594505050565b600080600080600060808688031215612309578081fd5b61231286611f9a565b945061232060208701611f9a565b935060408601359250606086013567ffffffffffffffff811115612342578182fd5b61234e8882890161215e565b969995985093965092949392505050565b60008060008060008060a08789031215612377578182fd5b61238087611f9a565b955061238e60208801611f9a565b94506040870135935060608701359250608087013567ffffffffffffffff8111156123b7578283fd5b6123c389828a0161215e565b979a9699509497509295939492505050565b6000602082840312156123e6578081fd5b813567ffffffffffffffff8111156123fc578182fd5b6106b284828501611fbe565b60008060006060848603121561241c578283fd5b833567ffffffffffffffff80821115612433578485fd5b61243f87838801611fbe565b945060208601359350604086013591508082111561245b578283fd5b506124688682870161219e565b9150509250925092565b600060208284031215612483578081fd5b5035919050565b60008060006040848603121561249e578283fd5b83359250602084013567ffffffffffffffff8111156124bb578283fd5b6124c78682870161215e565b9497909650939450505050565b6000602082840312156124e5578081fd5b61064e8261212e565b60008060408385031215612500578182fd5b6125098361212e565b915061251760208401611f9a565b90509250929050565b60008060008060408587031215612535578182fd5b843567ffffffffffffffff8082111561254c578384fd5b6125588883890161215e565b90965094506020870135915080821115612570578384fd5b5061257d8782880161215e565b95989497509550505050565b60006020828403121561259a578081fd5b813567ffffffffffffffff8111156125b0578182fd5b6106b28482850161219e565b6000815180845260208085019450848183028601828601855b858110156126575783830389528151805115158452858101511515868501526040808201519085015260608082015173ffffffffffffffffffffffffffffffffffffffff16908501526080808201519085015260a09081015160c09185018290529061264381860183612664565b9a87019a94505050908401906001016125d5565b5090979650505050505050565b6000815180845261267c8160208601602086016128c8565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600082516126c08184602087016128c8565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b901515815260200190565b90815260200190565b6000838252604060208301526106b26040830184612664565b7fffffffff0000000000000000000000000000000000000000000000000000000091909116815260200190565b6020808252601f908201527f4d61696e4d6f64756c65235f617574683a20494e56414c49445f4e4f4e434500604082015260600190565b60208082526024908201527f4d6f64756c6543616c6c73235f657865637574653a204e4f545f454e4f55474860408201527f5f47415300000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526026908201527f4d6f64756c6543616c6c7323657865637574653a20494e56414c49445f53494760408201527f4e41545552450000000000000000000000000000000000000000000000000000606082015260800190565b600060408252600560408301527f73656c663a00000000000000000000000000000000000000000000000000000060608301526080602083015261064e60808301846125bc565b6000838252604060208301526106b260408301846125bc565b918252602082015260400190565b60405181810167ffffffffffffffff811182821017156128c057fe5b604052919050565b60005b838110156128e35781810151838201526020016128cb565b838111156109e5575050600091015256fe5369676e617475726556616c696461746f72237265636f7665725369676e65723a20696e76616c6964207369676e6174757265202773272076616c75655369676e617475726556616c696461746f72237265636f7665725369676e65723a20696e76616c6964207369676e6174757265206c656e6774684d6f64756c6541757468235f7369676e617475726556616c69646174696f6e20494e56414c49445f464c41474d6f64756c654175746855706772616461626c6523757064617465496d6167654861736820494e56414c49445f494d4147455f484153484d6f64756c65486f6f6b732372656d6f7665486f6f6b3a20484f4f4b5f4e4f545f524547495354455245444c696242797465732372656164416464726573733a204f55545f4f465f424f554e44534c696242797465732372656164466972737455696e7431363a204f55545f4f465f424f554e44535369676e617475726556616c696461746f72237265636f7665725369676e65723a20696e76616c6964207369676e6174757265202776272076616c75655369676e617475726556616c696461746f72237265636f7665725369676e65723a20494e56414c49445f5349474e45524d6f64756c6541757468235f7369676e617475726556616c69646174696f6e3a20494e56414c49445f5349474e41545552454d6f64756c65486f6f6b7323616464486f6f6b3a20484f4f4b5f414c52454144595f524547495354455245445369676e617475726556616c696461746f7223697356616c69645369676e61747572653a20554e535550504f525445445f5349474e41545552455f545950454c696242797465732372656164427974657336363a204f55545f4f465f424f554e44534d6f64756c6555706461746523757064617465496d706c656d656e746174696f6e3a20494e56414c49445f494d504c454d454e544154494f4e5369676e617475726556616c696461746f72237265636f7665725369676e65723a20554e535550504f525445445f5349474e41545552455f545950454c69624279746573237265616455696e743855696e74383a204f55545f4f465f424f554e44534c69624279746573237265616442797465733a204f55545f4f465f424f554e44534c69624279746573237265616455696e7431363a204f55545f4f465f424f554e44534c696242797465732372656164427974657333323a20475245415445525f4f525f455155414c5f544f5f33325f4c454e4754485f52455155495245444d6f64756c6553656c6641757468236f6e6c7953656c663a204e4f545f415554484f52495a4544a2646970667358221220aebb8d931ef86555b6441c416b208bb9fe8fe0974c5733ebbccce548296c37ce64736f6c6343000706003300000000000000000000000000000000000000000000000000', + gasLimit: 8000000 + }) + + // Deploy guestModule + await signer.sendTransaction({ + to: '0x8A5Bc19e22D6aD55a2c763B93A75d09F321fe764', + data: '0x9c4ae2d0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001dfc608060405234801561001057600080fd5b50611ddc806100206000396000f3fe60806040526004361061007b5760003560e01c80637a9a16281161004e5780637a9a1628146101255780638c3f55631461014557806390042baf14610172578063affed0e0146101925761007b565b806301ffc9a7146100805780631626ba7e146100b657806320c13b0b146100e357806361c2926c14610103575b600080fd5b34801561008c57600080fd5b506100a061009b366004611677565b6101a7565b6040516100ad91906118be565b60405180910390f35b3480156100c257600080fd5b506100d66100d136600461162d565b6101ba565b6040516100ad91906118eb565b3480156100ef57600080fd5b506100d66100fe3660046116b7565b610233565b34801561010f57600080fd5b5061012361011e366004611590565b61028d565b005b34801561013157600080fd5b506101236101403660046115c3565b6102ce565b34801561015157600080fd5b50610165610160366004611753565b6102f6565b6040516100ad91906118c9565b610185610180366004611720565b610322565b6040516100ad919061189d565b34801561019e57600080fd5b506101656103d6565b60006101b2826103e7565b90505b919050565b60006102046101c885610444565b84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506104a492505050565b1561022c57507f1626ba7e000000000000000000000000000000000000000000000000000000005b9392505050565b600061025d6101c88686604051808383808284376040519201829003909120935061044492505050565b1561028557507f20c13b0b000000000000000000000000000000000000000000000000000000005b949350505050565b60006102be826040516020016102a39190611a19565b60405160208183030381529060405280519060200120610444565b90506102ca818361069c565b5050565b60006102e4846040516020016102a39190611975565b90506102f0818561069c565b50505050565b60006101b27f8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e83610817565b600033301461037c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180611d806027913960400191505060405180910390fd5b81516020830134f06040805173ffffffffffffffffffffffffffffffffffffffff8316815290519192507fa506ad4e7f05eceba62a023c3219e5bd98a615f4fa87e2afb08a2da5cf62bf0c919081900360200190a1919050565b60006103e260006102f6565b905090565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f90042baf00000000000000000000000000000000000000000000000000000000141561043b575060016101b5565b6101b282610844565b604080517f19010000000000000000000000000000000000000000000000000000000000006020808301919091524660228301523060601b6042830152605680830194909452825180830390940184526076909101909152815191012090565b60008060006104b2846108a1565b909250905061ffff821660005b855183101561067957600080806104d6898761090f565b975060ff918216945016915060018314156104fe576104f58987610990565b96509050610622565b8261052a57606061050f8a88610a08565b9750905061051d8b82610ab9565b9150828501945050610622565b60028314156105d15761053d8987610990565b96509050600061054d8a88610e43565b975061ffff16905060606105628b8984610eb4565b985090506105718c8483610fa3565b6105c6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526032815260200180611c0b6032913960400191505060405180910390fd5b505092810192610622565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180611b28602c913960400191505060405180910390fd5b848282604051602001808481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff16815260200193505050506040516020818303038152906040528051906020012094505050506104bf565b8361ffff1681101580156106915750610691826111eb565b979650505050505050565b60005b81518110156108125760008282815181106106b657fe5b6020026020010151905060006060826000015115610709576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610700906119bc565b60405180910390fd5b82604001515a1015610747576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161070090611918565b826060015173ffffffffffffffffffffffffffffffffffffffff168360800151846040015160001461077d57846040015161077f565b5a5b908560a001516040516107929190611881565b600060405180830381858888f193505050503d80600081146107d0576040519150601f19603f3d011682016040523d82523d6000602084013e6107d5565b606091505b50909250905081156107fc57856040516107ef91906118c9565b60405180910390a0610807565b6108078387836111f1565b50505060010161069f565b505050565b60408051602080820194909452808201929092528051808303820181526060909201905280519101205490565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f389901c7000000000000000000000000000000000000000000000000000000001415610898575060016101b5565b6101b282611241565b6020810151815160f09190911c9060029081111561090a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180611b776027913960400191505060405180910390fd5b915091565b8082016020015160f881901c9060f01c60ff166002830183811161092f57fe5b8451811115610989576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180611cdb6026913960400191505060405180910390fd5b9250925092565b8082016020015160601c601482018281116109a757fe5b8351811115610a01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180611b546023913960400191505060405180910390fd5b9250929050565b604080516042808252608082019092526060916000919060208201818036833701905050915082840160200180516020840152602081015160408401526022810151604284015250604283019050828111610a5f57fe5b8351811115610a01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180611c7c6023913960400191505060405180910390fd5b60008151604214610b15576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603a815260200180611aee603a913960400191505060405180910390fd5b600082600184510381518110610b2757fe5b602001015160f81c60f81b60f81c60ff169050600083604081518110610b4957fe5b016020015160f81c90506000610b5f85826112c9565b90506000610b6e8660206112c9565b90507f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0811115610be9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d815260200180611ab1603d913960400191505060405180910390fd5b8260ff16601b14158015610c0157508260ff16601c14155b15610c57576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d815260200180611b9e603d913960400191505060405180910390fd5b6001841415610ccb5760018784848460405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015610cba573d6000803e3d6000fd5b505050602060405103519450610dcd565b6002841415610d7c5760018760405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012084848460405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015610cba573d6000803e3d6000fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c815260200180611c9f603c913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8516610e39576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526030815260200180611bdb6030913960400191505060405180910390fd5b5050505092915050565b8082016020015160f01c60028201828111610e5a57fe5b8351811115610a01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180611d226022913960400191505060405180910390fd5b606060008267ffffffffffffffff81118015610ecf57600080fd5b506040519080825280601f01601f191660200182016040528015610efa576020820181803683370190505b509150838501602001600060205b85811015610f2157908201518482015260208101610f08565b8486016020018051939092015190850152525082820183811015610f4157fe5b8451811115610f9b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180611d016021913960400191505060405180910390fd5b935093915050565b60008082600184510381518110610fb657fe5b016020015160f81c90506001811480610fcf5750600281145b15611013578373ffffffffffffffffffffffffffffffffffffffff16610ff58685610ab9565b73ffffffffffffffffffffffffffffffffffffffff161491506111e3565b60038114156111925782517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81018452604080517f1626ba7e000000000000000000000000000000000000000000000000000000008152600481018881526024820192835286516044830152865173ffffffffffffffffffffffffffffffffffffffff891693631626ba7e938b938a9390929160640190602085019080838360005b838110156110cd5781810151838201526020016110b5565b50505050905090810190601f1680156110fa5780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b15801561111857600080fd5b505afa15801561112c573d6000803e3d6000fd5b505050506040513d602081101561114257600080fd5b50519084527fffffffff00000000000000000000000000000000000000000000000000000000167f1626ba7e000000000000000000000000000000000000000000000000000000001491506111e3565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603f815260200180611c3d603f913960400191505060405180910390fd5b509392505050565b50600190565b82602001511561120357805160208201fd5b7f3dbd1590ea96dd3253a91f24e64e3a502e1225d602a5731357bc12643070ccd782826040516112349291906118d2565b60405180910390a1505050565b60007fffffffff00000000000000000000000000000000000000000000000000000000821615806112b357507fffffffff0000000000000000000000000000000000000000000000000000000082167f36e7817500000000000000000000000000000000000000000000000000000000145b156112c0575060016101b5565b6101b282611331565b60008160200183511015611328576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c815260200180611d44603c913960400191505060405180910390fd5b50016020015190565b7fffffffff0000000000000000000000000000000000000000000000000000000081167f01ffc9a70000000000000000000000000000000000000000000000000000000014919050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101b557600080fd5b600082601f8301126113af578081fd5b8135602067ffffffffffffffff808311156113c657fe5b6113d38283850201611a60565b83815282810190868401865b868110156114af578135890160c0807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0838e0301121561141d57898afd5b604080518281018181108a8211171561143257fe5b825261143f848b016114bd565b815261144c8285016114bd565b8a820152606080850135838301526080925061146983860161137b565b9082015260a08481013583830152928401359289841115611488578c8dfd5b6114968f8c8688010161150d565b90820152875250505092850192908501906001016113df565b509098975050505050505050565b803580151581146101b557600080fd5b60008083601f8401126114de578182fd5b50813567ffffffffffffffff8111156114f5578182fd5b602083019150836020828501011115610a0157600080fd5b600082601f83011261151d578081fd5b813567ffffffffffffffff81111561153157fe5b61156260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611a60565b818152846020838601011115611576578283fd5b816020850160208301379081016020019190915292915050565b6000602082840312156115a1578081fd5b813567ffffffffffffffff8111156115b7578182fd5b6102858482850161139f565b6000806000606084860312156115d7578182fd5b833567ffffffffffffffff808211156115ee578384fd5b6115fa8783880161139f565b9450602086013593506040860135915080821115611616578283fd5b506116238682870161150d565b9150509250925092565b600080600060408486031215611641578283fd5b83359250602084013567ffffffffffffffff81111561165e578283fd5b61166a868287016114cd565b9497909650939450505050565b600060208284031215611688578081fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461022c578182fd5b600080600080604085870312156116cc578081fd5b843567ffffffffffffffff808211156116e3578283fd5b6116ef888389016114cd565b90965094506020870135915080821115611707578283fd5b50611714878288016114cd565b95989497509550505050565b600060208284031215611731578081fd5b813567ffffffffffffffff811115611747578182fd5b6102858482850161150d565b600060208284031215611764578081fd5b5035919050565b60008282518085526020808601955080818302840101818601855b8481101561182a578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00189528151805115158452848101511515858501526040808201519085015260608082015173ffffffffffffffffffffffffffffffffffffffff16908501526080808201519085015260a09081015160c09185018290529061181681860183611837565b9a86019a9450505090830190600101611786565b5090979650505050505050565b6000815180845261184f816020860160208601611a84565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60008251611893818460208701611a84565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b901515815260200190565b90815260200190565b6000838252604060208301526102856040830184611837565b7fffffffff0000000000000000000000000000000000000000000000000000000091909116815260200190565b60208082526029908201527f47756573744d6f64756c65235f6578656375746547756573743a204e4f545f4560408201527f4e4f5547485f4741530000000000000000000000000000000000000000000000606082015260800190565b600060408252600660408301527f67756573743a000000000000000000000000000000000000000000000000000060608301526080602083015261022c608083018461176b565b60208082526033908201527f47756573744d6f64756c65235f6578656375746547756573743a2064656c656760408201527f61746543616c6c206e6f7420616c6c6f77656400000000000000000000000000606082015260800190565b600060408252600560408301527f73656c663a00000000000000000000000000000000000000000000000000000060608301526080602083015261022c608083018461176b565b60405181810167ffffffffffffffff81118282101715611a7c57fe5b604052919050565b60005b83811015611a9f578181015183820152602001611a87565b838111156102f0575050600091015256fe5369676e617475726556616c696461746f72237265636f7665725369676e65723a20696e76616c6964207369676e6174757265202773272076616c75655369676e617475726556616c696461746f72237265636f7665725369676e65723a20696e76616c6964207369676e6174757265206c656e6774684d6f64756c6541757468235f7369676e617475726556616c69646174696f6e20494e56414c49445f464c41474c696242797465732372656164416464726573733a204f55545f4f465f424f554e44534c696242797465732372656164466972737455696e7431363a204f55545f4f465f424f554e44535369676e617475726556616c696461746f72237265636f7665725369676e65723a20696e76616c6964207369676e6174757265202776272076616c75655369676e617475726556616c696461746f72237265636f7665725369676e65723a20494e56414c49445f5349474e45524d6f64756c6541757468235f7369676e617475726556616c69646174696f6e3a20494e56414c49445f5349474e41545552455369676e617475726556616c696461746f7223697356616c69645369676e61747572653a20554e535550504f525445445f5349474e41545552455f545950454c696242797465732372656164427974657336363a204f55545f4f465f424f554e44535369676e617475726556616c696461746f72237265636f7665725369676e65723a20554e535550504f525445445f5349474e41545552455f545950454c69624279746573237265616455696e743855696e74383a204f55545f4f465f424f554e44534c69624279746573237265616442797465733a204f55545f4f465f424f554e44534c69624279746573237265616455696e7431363a204f55545f4f465f424f554e44534c696242797465732372656164427974657333323a20475245415445525f4f525f455155414c5f544f5f33325f4c454e4754485f52455155495245444d6f64756c6553656c6641757468236f6e6c7953656c663a204e4f545f415554484f52495a4544a2646970667358221220f5a1de0b650baa2ee828e8766bc6dbd0c74da0cc4735a143852d24f868e4b62464736f6c6343000706003300000000', + gasLimit: 8000000 + }) + + // Deploy multiCallUtils + await signer.sendTransaction({ + to: '0x8A5Bc19e22D6aD55a2c763B93A75d09F321fe764', + data: '0x9c4ae2d0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002b1660c06040523480156200001157600080fd5b5060405162002ad638038062002ad68339810160408190526200003491620000cd565b8181816001600160a01b031660a0816001600160a01b031660601b8152505060405180606001604052806028815260200162002aae60289139816001600160a01b03166040516020016200008a92919062000104565b60408051601f198184030181529190528051602090910120608052506200014692505050565b80516001600160a01b0381168114620000c857600080fd5b919050565b60008060408385031215620000e0578182fd5b620000eb83620000b0565b9150620000fb60208401620000b0565b90509250929050565b60008351815b818110156200012657602081870181015185830152016200010a565b81811115620001355782828501525b509190910191825250602001919050565b60805160a05160601c61293762000177600039806106515280610b1b5250806106755280610b3f52506129376000f3fe6080604052600436106101805760003560e01c806398f9fbc4116100d6578063d1db39071161007f578063e90f13e711610059578063e90f13e714610395578063f209883a146103ea578063ffd7d741146103ff57610180565b8063d1db390714610395578063d5b5337f146103aa578063e717aba9146103ca57610180565b8063c272d5c3116100b0578063c272d5c314610333578063c39f2d5c14610348578063c66764e11461036857610180565b806398f9fbc4146102e9578063aeea5fb5146102fe578063b472f0a21461031357610180565b806348acd29f116101385780637ae99638116101125780637ae99638146102875780637f29d538146102a7578063984395bc146102c757610180565b806348acd29f14610227578063543196eb146102475780637082503b1461026757610180565b80631cd05dc4116101695780631cd05dc4146101d057806343d9c935146101f057806344d466c21461020557610180565b80630fdecfac146101855780631551f0ab146101b0575b600080fd5b34801561019157600080fd5b5061019a610420565b6040516101a79190612190565b60405180910390f35b3480156101bc57600080fd5b5061019a6101cb366004611e76565b610424565b3480156101dc57600080fd5b5061019a6101eb366004611bea565b610436565b3480156101fc57600080fd5b5061019a610448565b34801561021157600080fd5b50610225610220366004611ca4565b610450565b005b34801561023357600080fd5b5061019a610242366004611bea565b61080a565b34801561025357600080fd5b5061019a610262366004611bea565b610828565b34801561027357600080fd5b50610225610282366004611c0b565b61082c565b34801561029357600080fd5b5061019a6102a2366004611bea565b610cb0565b3480156102b357600080fd5b506102256102c2366004611e76565b610cc2565b3480156102d357600080fd5b506102dc610cfe565b6040516101a79190612000565b3480156102f557600080fd5b506102dc610d02565b34801561030a57600080fd5b5061019a610d06565b34801561031f57600080fd5b5061022561032e366004611c7b565b610d0a565b34801561033f57600080fd5b5061019a610de8565b34801561035457600080fd5b5061019a610363366004611bea565b610dec565b34801561037457600080fd5b50610388610383366004611bea565b610df0565b6040516101a791906121c5565b3480156103a157600080fd5b5061019a610e35565b3480156103b657600080fd5b5061019a6103c5366004611e76565b610e39565b3480156103d657600080fd5b5061019a6103e5366004611bea565b610e3d565b3480156103f657600080fd5b5061019a610e4f565b61041261040d366004611d34565b610e53565b6040516101a7929190612021565b4690565b60036020526000908152604090205481565b60006020819052908152604090205481565b60005a905090565b8360005b838110156104e9578185858381811061046957fe5b9050604002016000013586868481811061047f57fe5b90506040020160200160208101906104979190611bea565b6040516020016104a993929190612199565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209150600101610454565b506000808773ffffffffffffffffffffffffffffffffffffffff166351605d8060e01b60405160200161051c9190611f54565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905261055491611f81565b6000604051808303816000865af19150503d8060008114610591576040519150601f19603f3d011682016040523d82523d6000602084013e610596565b606091505b50915091508180156105a9575080516020145b1561060e576000818060200190518101906105c49190611e8e565b9050838114610608576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ff90612543565b60405180910390fd5b50610732565b60405173ffffffffffffffffffffffffffffffffffffffff89169061069d907fff00000000000000000000000000000000000000000000000000000000000000907f00000000000000000000000000000000000000000000000000000000000000009087907f000000000000000000000000000000000000000000000000000000000000000090602001611ef0565b6040516020818303038152906040528051906020012060001c73ffffffffffffffffffffffffffffffffffffffff1614610703576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ff906125a0565b83156107325773ffffffffffffffffffffffffffffffffffffffff881660009081526002602052604090208390555b828873ffffffffffffffffffffffffffffffffffffffff167fb502b7446ca079086188acf3abef47c2f464f2ee9a72fcdf05ffcb74dcc17cee89898960405160200161077f9291906120c7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290526107b89291612623565b60405180910390a383156108005773ffffffffffffffffffffffffffffffffffffffff8816600090815260016020908152604080832043908190558684526003909252909120555b5050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8116315b919050565b3f90565b600080610838846110c3565b9150915060008046905080898960405160200161085793929190611f9d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052805160209091012091505061ffff831660008767ffffffffffffffff811180156108ae57600080fd5b506040519080825280602002602001820160405280156108e857816020015b6108d5611b1c565b8152602001906001900390816108cd5790505b50905060005b8751851015610a9f57600080806109058b89611131565b995060ff9182169450169150600183141561092d576109248b896111b2565b98509050610a20565b8261095f57606061093e8c8a61122a565b9950905061094c88826112db565b91506109598f838d611665565b50610a20565b60028314156109ee576109728b896111b2565b9850905060006109828c8a6116f3565b995061ffff16905060606109978d8b84611764565b9a5090506109a6898483611853565b6109dc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ff9061242c565b50506109e98e828c611665565b610a20565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ff906121d8565b60405180604001604052808381526020018273ffffffffffffffffffffffffffffffffffffffff16815250858581518110610a5757fe5b60200260200101819052508380600101945050858282604051602001610a7f93929190612199565b6040516020818303038152906040528051906020012095505050506108ee565b888114610ad8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ff906124e6565b60405173ffffffffffffffffffffffffffffffffffffffff8c1690610b67907fff00000000000000000000000000000000000000000000000000000000000000907f00000000000000000000000000000000000000000000000000000000000000009087907f000000000000000000000000000000000000000000000000000000000000000090602001611ef0565b6040516020818303038152906040528051906020012060001c73ffffffffffffffffffffffffffffffffffffffff1614610bcd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ff906123a9565b828b73ffffffffffffffffffffffffffffffffffffffff167fb502b7446ca079086188acf3abef47c2f464f2ee9a72fcdf05ffcb74dcc17cee8885604051602001610c18919061212b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052610c5192916125fe565b60405180910390a38615610ca35773ffffffffffffffffffffffffffffffffffffffff8b1660008181526001602090815260408083204390819055878452600383528184205592825260029052208390555b5050505050505050505050565b60026020526000908152604090205481565b804210610cfb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ff9061234c565b50565b3290565b4190565b4490565b600080610d1683611a9b565b9150915060008473ffffffffffffffffffffffffffffffffffffffff16638c3f5563846040518263ffffffff1660e01b8152600401610d559190612190565b60206040518083038186803b158015610d6d57600080fd5b505afa158015610d81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610da59190611e8e565b905081811015610de1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ff906122ef565b5050505050565b3a90565b3b90565b60408051603f833b9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092528181529080600060208401853c50919050565b4590565b4090565b60016020526000908152604090205481565b4290565b606080825167ffffffffffffffff81118015610e6e57600080fd5b50604051908082528060200260200182016040528015610e98578160200160208202803683370190505b509150825167ffffffffffffffff81118015610eb357600080fd5b50604051908082528060200260200182016040528015610ee757816020015b6060815260200190600190039081610ed25790505b50905060005b83518110156110bd576000848281518110610f0457fe5b60200260200101519050806000015115610f4a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ff90612489565b80604001515a1015610f88576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ff90612292565b806060015173ffffffffffffffffffffffffffffffffffffffff1681608001518260400151600014610fbe578260400151610fc0565b5a5b908360a00151604051610fd39190611f81565b600060405180830381858888f193505050503d8060008114611011576040519150601f19603f3d011682016040523d82523d6000602084013e611016565b606091505b5085848151811061102357fe5b6020026020010185858151811061103657fe5b602002602001018290528215151515815250505083828151811061105657fe5b60200260200101518061107e575084828151811061107057fe5b602002602001015160200151155b6110b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ff90612235565b50600101610eed565b50915091565b6020810151815160f09190911c9060029081111561112c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602781526020018061272b6027913960400191505060405180910390fd5b915091565b8082016020015160f881901c9060f01c60ff166002830183811161115157fe5b84518111156111ab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602681526020018061285d6026913960400191505060405180910390fd5b9250925092565b8082016020015160601c601482018281116111c957fe5b8351811115611223576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806127086023913960400191505060405180910390fd5b9250929050565b60408051604280825260808201909252606091600091906020820181803683370190505091508284016020018051602084015260208101516040840152602281015160428401525060428301905082811161128157fe5b8351811115611223576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806127fe6023913960400191505060405180910390fd5b60008151604214611337576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603a8152602001806126ce603a913960400191505060405180910390fd5b60008260018451038151811061134957fe5b602001015160f81c60f81b60f81c60ff16905060008360408151811061136b57fe5b016020015160f81c905060006113818582611ab4565b90506000611390866020611ab4565b90507f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a081111561140b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d815260200180612691603d913960400191505060405180910390fd5b8260ff16601b1415801561142357508260ff16601c14155b15611479576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d815260200180612752603d913960400191505060405180910390fd5b60018414156114ed5760018784848460405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156114dc573d6000803e3d6000fd5b5050506020604051035194506115ef565b600284141561159e5760018760405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012084848460405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156114dc573d6000803e3d6000fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c815260200180612821603c913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff851661165b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603081526020018061278f6030913960400191505060405180910390fd5b5050505092915050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f600ba597427f042bcd559a0d06fa1732cc104d6dd43cbe8845b5a0e804b2b39f60405160405180910390a380156116ee5773ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090204390555b505050565b8082016020015160f01c6002820182811161170a57fe5b8351811115611223576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806128a46022913960400191505060405180910390fd5b606060008267ffffffffffffffff8111801561177f57600080fd5b506040519080825280601f01601f1916602001820160405280156117aa576020820181803683370190505b509150838501602001600060205b858110156117d1579082015184820152602081016117b8565b84860160200180519390920151908501525250828201838110156117f157fe5b845181111561184b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806128836021913960400191505060405180910390fd5b935093915050565b6000808260018451038151811061186657fe5b016020015160f81c9050600181148061187f5750600281145b156118c3578373ffffffffffffffffffffffffffffffffffffffff166118a586856112db565b73ffffffffffffffffffffffffffffffffffffffff16149150611a93565b6003811415611a425782517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81018452604080517f1626ba7e000000000000000000000000000000000000000000000000000000008152600481018881526024820192835286516044830152865173ffffffffffffffffffffffffffffffffffffffff891693631626ba7e938b938a9390929160640190602085019080838360005b8381101561197d578181015183820152602001611965565b50505050905090810190601f1680156119aa5780820380516001836020036101000a031916815260200191505b50935050505060206040518083038186803b1580156119c857600080fd5b505afa1580156119dc573d6000803e3d6000fd5b505050506040513d60208110156119f257600080fd5b50519084527fffffffff00000000000000000000000000000000000000000000000000000000167f1626ba7e00000000000000000000000000000000000000000000000000000000149150611a93565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603f8152602001806127bf603f913960400191505060405180910390fd5b509392505050565b606081901c916bffffffffffffffffffffffff90911690565b60008160200183511015611b13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c8152602001806128c6603c913960400191505060405180910390fd5b50016020015190565b604080518082019091526000808252602082015290565b803573ffffffffffffffffffffffffffffffffffffffff8116811461082357600080fd5b8035801515811461082357600080fd5b600082601f830112611b77578081fd5b813567ffffffffffffffff811115611b8b57fe5b611bbc60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161263c565b818152846020838601011115611bd0578283fd5b816020850160208301379081016020019190915292915050565b600060208284031215611bfb578081fd5b611c0482611b33565b9392505050565b600080600080600060a08688031215611c22578081fd5b611c2b86611b33565b94506020860135935060408601359250606086013567ffffffffffffffff811115611c54578182fd5b611c6088828901611b67565b925050611c6f60808701611b57565b90509295509295909350565b60008060408385031215611c8d578182fd5b611c9683611b33565b946020939093013593505050565b600080600080600060808688031215611cbb578081fd5b611cc486611b33565b945060208601359350604086013567ffffffffffffffff80821115611ce7578283fd5b818801915088601f830112611cfa578283fd5b813581811115611d08578384fd5b896020604083028501011115611d1c578384fd5b602083019550809450505050611c6f60608701611b57565b60006020808385031215611d46578182fd5b823567ffffffffffffffff80821115611d5d578384fd5b818501915085601f830112611d70578384fd5b813581811115611d7c57fe5b611d89848583020161263c565b81815284810190848601875b84811015611e67578135870160c0807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0838f03011215611dd3578a8bfd5b604080518281018181108b82111715611de857fe5b8252611df5848d01611b57565b8152611e02828501611b57565b8c82015260608085013583830152611e1c60808601611b33565b9082015260a08481013560808301529284013592915089831115611e3e578c8dfd5b611e4c8f8d85870101611b67565b91810191909152865250509287019290870190600101611d95565b50909998505050505050505050565b600060208284031215611e87578081fd5b5035919050565b600060208284031215611e9f578081fd5b5051919050565b60008151808452611ebe816020860160208601612660565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b7fff0000000000000000000000000000000000000000000000000000000000000094909416845260609290921b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660018401526015830152603582015260550190565b7fffffffff0000000000000000000000000000000000000000000000000000000091909116815260040190565b60008251611f93818460208701612660565b9190910192915050565b7f19010000000000000000000000000000000000000000000000000000000000008152600281019390935260609190911b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166022830152603682015260560190565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b604080825283519082018190526000906020906060840190828701845b8281101561205c57815115158452928401929084019060010161203e565b5050508381038285015284518082528282019080840283018401878501865b83811015611e67577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08684030185526120b5838351611ea6565b9487019492509086019060010161207b565b6020808252818101839052600090604080840186845b8781101561211e578135835273ffffffffffffffffffffffffffffffffffffffff612109868401611b33565b168386015291830191908301906001016120dd565b5090979650505050505050565b602080825282518282018190526000919060409081850190868401855b828110156121835781518051855286015173ffffffffffffffffffffffffffffffffffffffff16868501529284019290850190600101612148565b5091979650505050505050565b90815260200190565b928352602083019190915273ffffffffffffffffffffffffffffffffffffffff16604082015260600190565b600060208252611c046020830184611ea6565b6020808252603a908201527f526571756972655574696c73237075626c697368496e697469616c5369676e6560408201527f72733a20494e56414c49445f5349474e41545552455f464c4147000000000000606082015260800190565b60208082526027908201527f4d756c746943616c6c5574696c73236d756c746943616c6c3a2043414c4c5f5260408201527f4556455254454400000000000000000000000000000000000000000000000000606082015260800190565b60208082526028908201527f4d756c746943616c6c5574696c73236d756c746943616c6c3a204e4f545f454e60408201527f4f5547485f474153000000000000000000000000000000000000000000000000606082015260800190565b60208082526032908201527f526571756972655574696c7323726571756972654d696e4e6f6e63653a204e4f60408201527f4e43455f42454c4f575f52455155495245440000000000000000000000000000606082015260800190565b60208082526027908201527f526571756972655574696c7323726571756972654e6f6e457870697265643a2060408201527f4558504952454400000000000000000000000000000000000000000000000000606082015260800190565b60208082526048908201527f526571756972655574696c73237075626c697368496e697469616c5369676e6560408201527f72733a20554e45585045435445445f434f554e5445524641435455414c5f494d60608201527f4147455f48415348000000000000000000000000000000000000000000000000608082015260a00190565b60208082526032908201527f4d6f64756c6541757468235f7369676e617475726556616c69646174696f6e3a60408201527f20494e56414c49445f5349474e41545552450000000000000000000000000000606082015260800190565b60208082526032908201527f4d756c746943616c6c5574696c73236d756c746943616c6c3a2064656c65676160408201527f746543616c6c206e6f7420616c6c6f7765640000000000000000000000000000606082015260800190565b60208082526039908201527f526571756972655574696c73237075626c697368496e697469616c5369676e6560408201527f72733a20494e56414c49445f4d454d424552535f434f554e5400000000000000606082015260800190565b60208082526031908201527f526571756972655574696c73237075626c697368436f6e6669673a20554e455860408201527f5045435445445f494d4147455f48415348000000000000000000000000000000606082015260800190565b602080825260409082018190527f526571756972655574696c73237075626c697368436f6e6669673a20554e4558908201527f5045435445445f434f554e5445524641435455414c5f494d4147455f48415348606082015260800190565b600061ffff841682526040602083015261261b6040830184611ea6565b949350505050565b60008382526040602083015261261b6040830184611ea6565b60405181810167ffffffffffffffff8111828210171561265857fe5b604052919050565b60005b8381101561267b578181015183820152602001612663565b8381111561268a576000848401525b5050505056fe5369676e617475726556616c696461746f72237265636f7665725369676e65723a20696e76616c6964207369676e6174757265202773272076616c75655369676e617475726556616c696461746f72237265636f7665725369676e65723a20696e76616c6964207369676e6174757265206c656e6774684c696242797465732372656164416464726573733a204f55545f4f465f424f554e44534c696242797465732372656164466972737455696e7431363a204f55545f4f465f424f554e44535369676e617475726556616c696461746f72237265636f7665725369676e65723a20696e76616c6964207369676e6174757265202776272076616c75655369676e617475726556616c696461746f72237265636f7665725369676e65723a20494e56414c49445f5349474e45525369676e617475726556616c696461746f7223697356616c69645369676e61747572653a20554e535550504f525445445f5349474e41545552455f545950454c696242797465732372656164427974657336363a204f55545f4f465f424f554e44535369676e617475726556616c696461746f72237265636f7665725369676e65723a20554e535550504f525445445f5349474e41545552455f545950454c69624279746573237265616455696e743855696e74383a204f55545f4f465f424f554e44534c69624279746573237265616442797465733a204f55545f4f465f424f554e44534c69624279746573237265616455696e7431363a204f55545f4f465f424f554e44534c696242797465732372656164427974657333323a20475245415445525f4f525f455155414c5f544f5f33325f4c454e4754485f5245515549524544a26469706673582212200abb842b6eea58df953f048e3a9aa7589fd3ce15ca086e43b61cdb0c0c42723564736f6c63430007060033603a600e3d39601a805130553df3363d3d373d3d3d363d30545af43d82803e903d91601857fd5bf3000000000000000000000000f9d09d634fb818b05149329c1dccfaea53639d96000000000000000000000000d01f11855bccb95f88d7a48492f66410d463731300000000000000000000', + gasLimit: 8000000 + }) + + return deployV1Context(signer) +} diff --git a/packages/tests/src/context/v2.ts b/packages/tests/src/context/v2.ts new file mode 100644 index 0000000000..a76e97fd2d --- /dev/null +++ b/packages/tests/src/context/v2.ts @@ -0,0 +1,24 @@ +import { ethers } from 'ethers' +import { v2 } from '../builds' +import { deployContract } from '../singletonFactory' + +export async function deployV2Context(signer: ethers.Signer) { + // See if signer's provider has the contracts already deployed + const factory = await deployContract(signer, v2.factory) + const mainModuleUpgradable = await deployContract(signer, v2.mainModuleUpgradable) + const mainModule = await deployContract(signer, v2.mainModule, factory.address, mainModuleUpgradable.address) + const guestModule = await deployContract(signer, v2.guestModule) + const universalSigValidator = await deployContract(signer, v2.universalSigValidator) + + return { + version: 2, + + factory: factory.address, + mainModule: mainModule.address, + mainModuleUpgradable: mainModuleUpgradable.address, + guestModule: guestModule.address, + universalSigValidator: universalSigValidator.address, + + walletCreationCode: '0x603a600e3d39601a805130553df3363d3d373d3d3d363d30545af43d82803e903d91601857fd5bf3' + } +} diff --git a/packages/tests/src/index.ts b/packages/tests/src/index.ts new file mode 100644 index 0000000000..37c060faad --- /dev/null +++ b/packages/tests/src/index.ts @@ -0,0 +1,8 @@ +export * as context from './context' +export * as builds from './builds' + +export * as utils from './utils' + +export * as configs from './configs' +export * as singleton from './singletonFactory' +export * as erc20 from './tokens/erc20' diff --git a/packages/tests/src/singletonFactory.ts b/packages/tests/src/singletonFactory.ts new file mode 100644 index 0000000000..ff9431deea --- /dev/null +++ b/packages/tests/src/singletonFactory.ts @@ -0,0 +1,95 @@ +import { ethers } from 'ethers' +import { Artifact } from './builds' +import { isContract } from './utils' + +export const deployment = { + tx: '0xf9016c8085174876e8008303c4d88080b90154608060405234801561001057600080fd5b50610134806100206000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c80634af63f0214602d575b600080fd5b60cf60048036036040811015604157600080fd5b810190602081018135640100000000811115605b57600080fd5b820183602082011115606c57600080fd5b80359060200191846001830284011164010000000083111715608d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550509135925060eb915050565b604080516001600160a01b039092168252519081900360200190f35b6000818351602085016000f5939250505056fea26469706673582212206b44f8a82cb6b156bfcc3dc6aadd6df4eefd204bc928a4397fd15dacf6d5320564736f6c634300060200331b83247000822470', + deployer: '0xBb6e024b9cFFACB947A71991E386681B1Cd1477D', + funding: '24700000000000000' +} + +export const address = '0xce0042B868300000d44A59004Da54A005ffdcf9f' + +export const abi = [ + { + constant: false, + inputs: [ + { + internalType: 'bytes', + type: 'bytes' + }, + { + internalType: 'bytes32', + type: 'bytes32' + } + ], + name: 'deploy', + outputs: [ + { + internalType: 'address payable', + type: 'address' + } + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + } +] + +export async function mustExistEIP2470(signer: ethers.Signer): Promise { + const provider = signer.provider + if (!provider) throw new Error('signer has no provider') + + if (!(await isContract(provider, address))) { + const balanceDeployer = await provider.getBalance(deployment.deployer) + if (balanceDeployer.lt(deployment.funding)) { + await signer.sendTransaction({ + to: deployment.deployer, + value: ethers.BigNumber.from(deployment.funding).sub(balanceDeployer) + }) + } + + await provider.sendTransaction(deployment.tx) + if (!(await isContract(provider, address))) { + throw new Error('EIP2470 deployment failed') + } + } + + return new ethers.Contract(address, abi, signer) +} + +export async function deployContract(signer: ethers.Signer, artifact: Artifact, ...args: any[]): Promise { + const provider = signer.provider + if (!provider) throw new Error('signer has no provider') + + const singletonFactory = await mustExistEIP2470(signer) + + const factory = new ethers.ContractFactory(artifact.abi, artifact.bytecode) + const data = factory.getDeployTransaction(...args).data + if (!data) throw new Error('no deploy data') + + const address = ethers.utils.getAddress( + ethers.utils.hexDataSlice( + ethers.utils.keccak256( + ethers.utils.solidityPack( + ['bytes1', 'address', 'bytes32', 'bytes32'], + ['0xff', singletonFactory.address, ethers.constants.HashZero, ethers.utils.keccak256(data)] + ) + ), + 12 + ) + ) + + if (await isContract(provider, address)) { + return new ethers.Contract(address, artifact.abi, signer) + } + + const maxGasLimit = await provider.getBlock('latest').then(b => b.gasLimit.div(2)) + await singletonFactory.deploy(data, ethers.constants.HashZero, { gasLimit: maxGasLimit }).then((tx: any) => tx.wait()) + + if (!(await isContract(provider, address))) { + throw new Error('contract deployment failed') + } + + return new ethers.Contract(address, artifact.abi, signer) +} diff --git a/packages/tests/src/tokens/erc20.ts b/packages/tests/src/tokens/erc20.ts new file mode 100644 index 0000000000..5b20ebb67e --- /dev/null +++ b/packages/tests/src/tokens/erc20.ts @@ -0,0 +1,324 @@ +/* +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.3; + +contract SimpleERC20 { + mapping(address => uint256) public balanceOf; + mapping(address => mapping(address => uint256)) public allowance; + uint256 public totalSupply; + + string public name; + string public symbol; + uint8 public decimals; + + constructor(string memory _name, string memory _symbol, uint8 _decimals) { + name = _name; + symbol = _symbol; + decimals = _decimals; + } + + function mint(address to, uint256 amount) public { + totalSupply += amount; + balanceOf[to] += amount; + emit Transfer(address(0), to, amount); + } + + function transfer(address to, uint256 value) public returns (bool) { + balanceOf[msg.sender] -= value; + balanceOf[to] += value; + emit Transfer(msg.sender, to, value); + return true; + } + + function approve(address spender, uint256 value) public returns (bool) { + allowance[msg.sender][spender] = value; + emit Approval(msg.sender, spender, value); + return true; + } + + function transferFrom(address from, address to, uint256 value) public returns (bool) { + balanceOf[from] -= value; + balanceOf[to] += value; + allowance[from][msg.sender] -= value; + + emit Transfer(from, to, value); + return true; + } + + event Transfer(address indexed from, address indexed to, uint256 value); + event Approval(address indexed owner, address indexed spender, uint256 value); +} +*/ + +import { ethers } from 'ethers' + +export const TEST_ERC20_ABI = [ + { + inputs: [ + { + internalType: 'string', + name: '_name', + type: 'string' + }, + { + internalType: 'string', + name: '_symbol', + type: 'string' + }, + { + internalType: 'uint8', + name: '_decimals', + type: 'uint8' + } + ], + stateMutability: 'nonpayable', + type: 'constructor' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'owner', + type: 'address' + }, + { + indexed: true, + internalType: 'address', + name: 'spender', + type: 'address' + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256' + } + ], + name: 'Approval', + type: 'event' + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'from', + type: 'address' + }, + { + indexed: true, + internalType: 'address', + name: 'to', + type: 'address' + }, + { + indexed: false, + internalType: 'uint256', + name: 'value', + type: 'uint256' + } + ], + name: 'Transfer', + type: 'event' + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + }, + { + internalType: 'address', + name: '', + type: 'address' + } + ], + name: 'allowance', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'spender', + type: 'address' + }, + { + internalType: 'uint256', + name: 'value', + type: 'uint256' + } + ], + name: 'approve', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool' + } + ], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: '', + type: 'address' + } + ], + name: 'balanceOf', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'decimals', + outputs: [ + { + internalType: 'uint8', + name: '', + type: 'uint8' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'to', + type: 'address' + }, + { + internalType: 'uint256', + name: 'amount', + type: 'uint256' + } + ], + name: 'mint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [], + name: 'name', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'symbol', + outputs: [ + { + internalType: 'string', + name: '', + type: 'string' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [], + name: 'totalSupply', + outputs: [ + { + internalType: 'uint256', + name: '', + type: 'uint256' + } + ], + stateMutability: 'view', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'to', + type: 'address' + }, + { + internalType: 'uint256', + name: 'value', + type: 'uint256' + } + ], + name: 'transfer', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool' + } + ], + stateMutability: 'nonpayable', + type: 'function' + }, + { + inputs: [ + { + internalType: 'address', + name: 'from', + type: 'address' + }, + { + internalType: 'address', + name: 'to', + type: 'address' + }, + { + internalType: 'uint256', + name: 'value', + type: 'uint256' + } + ], + name: 'transferFrom', + outputs: [ + { + internalType: 'bool', + name: '', + type: 'bool' + } + ], + stateMutability: 'nonpayable', + type: 'function' + } +] + +export const TEST_ERC20_BYTECODE = + '0x60806040523480156200001157600080fd5b506040516200128b3803806200128b833981810160405281019062000037919062000250565b82600390816200004891906200053b565b5081600490816200005a91906200053b565b5080600560006101000a81548160ff021916908360ff16021790555050505062000622565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b620000e8826200009d565b810181811067ffffffffffffffff821117156200010a5762000109620000ae565b5b80604052505050565b60006200011f6200007f565b90506200012d8282620000dd565b919050565b600067ffffffffffffffff82111562000150576200014f620000ae565b5b6200015b826200009d565b9050602081019050919050565b60005b83811015620001885780820151818401526020810190506200016b565b60008484015250505050565b6000620001ab620001a58462000132565b62000113565b905082815260208101848484011115620001ca57620001c962000098565b5b620001d784828562000168565b509392505050565b600082601f830112620001f757620001f662000093565b5b81516200020984826020860162000194565b91505092915050565b600060ff82169050919050565b6200022a8162000212565b81146200023657600080fd5b50565b6000815190506200024a816200021f565b92915050565b6000806000606084860312156200026c576200026b62000089565b5b600084015167ffffffffffffffff8111156200028d576200028c6200008e565b5b6200029b86828701620001df565b935050602084015167ffffffffffffffff811115620002bf57620002be6200008e565b5b620002cd86828701620001df565b9250506040620002e08682870162000239565b9150509250925092565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200033d57607f821691505b602082108103620003535762000352620002f5565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b60008160020a8302905092915050565b600060088302620003c07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826200037e565b620003cc86836200037e565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b600062000419620004136200040d84620003e4565b620003ee565b620003e4565b9050919050565b6000819050919050565b6200043583620003f8565b6200044d620004448262000420565b8484546200038e565b825550505050565b600090565b6200046462000455565b620004718184846200042a565b505050565b5b8181101562000499576200048d6000826200045a565b60018101905062000477565b5050565b601f821115620004e857620004b28162000359565b620004bd846200036e565b81016020851015620004cd578190505b620004e5620004dc856200036e565b83018262000476565b50505b505050565b60008160020a8304905092915050565b60006200051060001984600802620004ed565b1980831691505092915050565b60006200052b8383620004fd565b9150826002028217905092915050565b6200054682620002ea565b67ffffffffffffffff811115620005625762000561620000ae565b5b6200056e825462000324565b6200057b8282856200049d565b600060209050601f831160018114620005b357600084156200059e578287015190505b620005aa85826200051d565b8655506200061a565b601f198416620005c38662000359565b60005b82811015620005ed57848901518255600182019150602085019450602081019050620005c6565b868310156200060d578489015162000609601f891682620004fd565b8355505b6001600288020188555050505b505050505050565b610c5980620006326000396000f3fe608060405234801561001057600080fd5b50600436106100bb576000357c01000000000000000000000000000000000000000000000000000000009004806340c10f191161008357806340c10f191461017a57806370a082311461019657806395d89b41146101c6578063a9059cbb146101e4578063dd62ed3e14610214576100bb565b806306fdde03146100c0578063095ea7b3146100de57806318160ddd1461010e57806323b872dd1461012c578063313ce5671461015c575b600080fd5b6100c8610244565b6040516100d591906108da565b60405180910390f35b6100f860048036038101906100f39190610995565b6102d2565b60405161010591906109f0565b60405180910390f35b6101166103c4565b6040516101239190610a1a565b60405180910390f35b61014660048036038101906101419190610a35565b6103ca565b60405161015391906109f0565b60405180910390f35b610164610579565b6040516101719190610aa4565b60405180910390f35b610194600480360381019061018f9190610995565b61058c565b005b6101b060048036038101906101ab9190610abf565b610664565b6040516101bd9190610a1a565b60405180910390f35b6101ce61067c565b6040516101db91906108da565b60405180910390f35b6101fe60048036038101906101f99190610995565b61070a565b60405161020b91906109f0565b60405180910390f35b61022e60048036038101906102299190610aec565b610825565b60405161023b9190610a1a565b60405180910390f35b6003805461025190610b5b565b80601f016020809104026020016040519081016040528092919081815260200182805461027d90610b5b565b80156102ca5780601f1061029f576101008083540402835291602001916102ca565b820191906000526020600020905b8154815290600101906020018083116102ad57829003601f168201915b505050505081565b600081600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516103b29190610a1a565b60405180910390a36001905092915050565b60025481565b6000816000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461041a9190610bbb565b92505081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461046f9190610bef565b9250508190555081600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546105029190610bbb565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516105669190610a1a565b60405180910390a3600190509392505050565b600560009054906101000a900460ff1681565b806002600082825461059e9190610bef565b92505081905550806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546105f39190610bef565b925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516106589190610a1a565b60405180910390a35050565b60006020528060005260406000206000915090505481565b6004805461068990610b5b565b80601f01602080910402602001604051908101604052809291908181526020018280546106b590610b5b565b80156107025780601f106106d757610100808354040283529160200191610702565b820191906000526020600020905b8154815290600101906020018083116106e557829003601f168201915b505050505081565b6000816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461075a9190610bbb565b92505081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546107af9190610bef565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516108139190610a1a565b60405180910390a36001905092915050565b6001602052816000526040600020602052806000526040600020600091509150505481565b600081519050919050565b600082825260208201905092915050565b60005b83811015610884578082015181840152602081019050610869565b60008484015250505050565b6000601f19601f8301169050919050565b60006108ac8261084a565b6108b68185610855565b93506108c6818560208601610866565b6108cf81610890565b840191505092915050565b600060208201905081810360008301526108f481846108a1565b905092915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061092c82610901565b9050919050565b61093c81610921565b811461094757600080fd5b50565b60008135905061095981610933565b92915050565b6000819050919050565b6109728161095f565b811461097d57600080fd5b50565b60008135905061098f81610969565b92915050565b600080604083850312156109ac576109ab6108fc565b5b60006109ba8582860161094a565b92505060206109cb85828601610980565b9150509250929050565b60008115159050919050565b6109ea816109d5565b82525050565b6000602082019050610a0560008301846109e1565b92915050565b610a148161095f565b82525050565b6000602082019050610a2f6000830184610a0b565b92915050565b600080600060608486031215610a4e57610a4d6108fc565b5b6000610a5c8682870161094a565b9350506020610a6d8682870161094a565b9250506040610a7e86828701610980565b9150509250925092565b600060ff82169050919050565b610a9e81610a88565b82525050565b6000602082019050610ab96000830184610a95565b92915050565b600060208284031215610ad557610ad46108fc565b5b6000610ae38482850161094a565b91505092915050565b60008060408385031215610b0357610b026108fc565b5b6000610b118582860161094a565b9250506020610b228582860161094a565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680610b7357607f821691505b602082108103610b8657610b85610b2c565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610bc68261095f565b9150610bd18361095f565b9250828203905081811115610be957610be8610b8c565b5b92915050565b6000610bfa8261095f565b9150610c058361095f565b9250828201905080821115610c1d57610c1c610b8c565b5b9291505056fea2646970667358221220129f37bd61cdb5c232d63f8cc989264602a3f614c75e0376a02d7d2d2d8910a164736f6c63430008150033' + +export function createERC20(signer: ethers.Signer, name: string, symbol: string, decimals: number) { + return new ethers.ContractFactory(TEST_ERC20_ABI, TEST_ERC20_BYTECODE, signer).deploy(name, symbol, decimals) +} diff --git a/packages/tests/src/utils.ts b/packages/tests/src/utils.ts new file mode 100644 index 0000000000..00924003a7 --- /dev/null +++ b/packages/tests/src/utils.ts @@ -0,0 +1,37 @@ +import { ethers } from 'ethers' +import { Artifact } from './builds' + +export function deployContract(signer: ethers.Signer, artifact: Artifact, ...args: any[]): Promise { + const factory = new ethers.ContractFactory(artifact.abi, artifact.bytecode, signer) + return factory.deploy(...args) +} + +export function randomBigNumber( + min: ethers.BigNumberish = 0, + max: ethers.BigNumberish = ethers.constants.MaxUint256 +): ethers.BigNumber { + const randomHex = ethers.utils.hexlify(ethers.utils.randomBytes(32)) + const randomBn = ethers.BigNumber.from(randomHex) + const minBn = ethers.BigNumber.from(min) + const maxBn = ethers.BigNumber.from(max) + const range = maxBn.sub(minBn) + + if (range.isNegative() || range.isZero()) { + throw new Error('max must be greater than min') + } + + return randomBn.mod(range).add(minBn) +} + +export function maxForBits(bits: number): ethers.BigNumber { + return ethers.BigNumber.from(2).pow(bits).sub(1) +} + +export function randomBool(): boolean { + return Math.random() >= 0.5 +} + +export async function isContract(provider: ethers.providers.Provider, address: string): Promise { + const c = await provider.getCode(address) + return ethers.utils.arrayify(c).length > 0 +} diff --git a/packages/utils/CHANGELOG.md b/packages/utils/CHANGELOG.md new file mode 100644 index 0000000000..8dfed7e18d --- /dev/null +++ b/packages/utils/CHANGELOG.md @@ -0,0 +1,1670 @@ +# @0xsequence/utils + +## 1.10.8 + +### Patch Changes + +- update metadata bindings + +## 1.10.7 + +### Patch Changes + +- minor fixes to waas client + +## 1.10.6 + +### Patch Changes + +- metadata: update bindings + +## 1.10.5 + +### Patch Changes + +- network: ape-chain-testnet -> apechain-testnet + +## 1.10.4 + +### Patch Changes + +- network: add b3-sepolia, ape-chain-testnet, blast, blast-sepolia + +## 1.10.3 + +### Patch Changes + +- typing fix + +## 1.10.2 + +### Patch Changes + +- - waas: add getIdToken method + - indexer: update api client + +## 1.10.1 + +### Patch Changes + +- metadata: update bindings + +## 1.10.0 + +### Minor Changes + +- waas release v1.3.0 + +## 1.9.37 + +### Patch Changes + +- network: adds nativeToken data to NetworkMetadata constants + +## 1.9.36 + +### Patch Changes + +- guard: export client + +## 1.9.35 + +### Patch Changes + +- guard: update bindings + +## 1.9.34 + +### Patch Changes + +- waas: always use lowercase email + +## 1.9.33 + +### Patch Changes + +- waas: umd build + +## 1.9.32 + +### Patch Changes + +- indexer: update bindings + +## 1.9.31 + +### Patch Changes + +- metadata: token directory changes + +## 1.9.30 + +### Patch Changes + +- update + +## 1.9.29 + +### Patch Changes + +- disable gnosis chain + +## 1.9.28 + +### Patch Changes + +- add utils/merkletree + +## 1.9.27 + +### Patch Changes + +- network: optimistic -> optimism +- waas: remove defaults +- api, sessions: update bindings + +## 1.9.26 + +### Patch Changes + +- - add backend interfaces for pluggable interfaces + - introduce @0xsequence/react-native + - update pnpm to lockfile v9 + +## 1.9.25 + +### Patch Changes + +- update webrpc clients with new error types + +## 1.9.24 + +### Patch Changes + +- waas: add memoryStore backend to localStore + +## 1.9.23 + +### Patch Changes + +- update api client bindings + +## 1.9.22 + +### Patch Changes + +- update metadata client bindings + +## 1.9.21 + +### Patch Changes + +- api client bindings + +## 1.9.20 + +### Patch Changes + +- api client bindings update + +## 1.9.19 + +### Patch Changes + +- waas update + +## 1.9.18 + +### Patch Changes + +- provider: prohibit dangerous functions + +## 1.9.17 + +### Patch Changes + +- network: add xr-sepolia + +## 1.9.16 + +### Patch Changes + +- waas: sequence.feeOptions + +## 1.9.15 + +### Patch Changes + +- metadata: collection external_link field name fix + +## 1.9.14 + +### Patch Changes + +- network: astar-zkatana -> astar-zkyoto +- network: deprecate polygon mumbai network +- network: add xai and polygon amoy + +## 1.9.13 + +### Patch Changes + +- waas: fix @0xsequence/network dependency + +## 1.9.12 + +### Patch Changes + +- indexer: update rpc bindings +- provider: signMessage: Serialize the BytesLike or string message into hexstring before sending +- waas: SessionAuthProof + +## 1.9.11 + +### Patch Changes + +- metdata, update rpc bindings + +## 1.9.10 + +### Patch Changes + +- update metadata rpc bindings + +## 1.9.9 + +### Patch Changes + +- metadata, add SequenceCollections rpc client + +## 1.9.8 + +### Patch Changes + +- waas client update + +## 1.9.7 + +### Patch Changes + +- update rpc client bindings for api, metadata and relayer + +## 1.9.6 + +### Patch Changes + +- waas package update + +## 1.9.5 + +### Patch Changes + +- RpcRelayer prioritize project access key + +## 1.9.4 + +### Patch Changes + +- waas: fix network dependency + +## 1.9.3 + +### Patch Changes + +- provider: don't append access key to RPC url if user has already provided it + +## 1.9.2 + +### Patch Changes + +- network: add xai-sepolia + +## 1.9.1 + +### Patch Changes + +- analytics fix + +## 1.9.0 + +### Minor Changes + +- waas release + +## 1.8.8 + +### Patch Changes + +- update metadata bindings + +## 1.8.7 + +### Patch Changes + +- provider: update databeat to 0.9.1 + +## 1.8.6 + +### Patch Changes + +- guard: SignedOwnershipProof + +## 1.8.5 + +### Patch Changes + +- guard: signOwnershipProof and isSignedOwnershipProof + +## 1.8.4 + +### Patch Changes + +- network: add homeverse to networks list + +## 1.8.3 + +### Patch Changes + +- api: introduce basic linked wallet support + +## 1.8.2 + +### Patch Changes + +- provider: don't initialize analytics unless explicitly requested + +## 1.8.1 + +### Patch Changes + +- update to analytics provider + +## 1.8.0 + +### Minor Changes + +- provider: project analytics + +## 1.7.2 + +### Patch Changes + +- 0xsequence: ChainId should not be exported as a type +- account, wallet: fix nonce selection + +## 1.7.1 + +### Patch Changes + +- network: add missing avalanche logoURI + +## 1.7.0 + +### Minor Changes + +- provider: projectAccessKey is now required + +### Patch Changes + +- network: add NetworkMetadata.logoURI property for all networks + +## 1.6.3 + +### Patch Changes + +- network list update + +## 1.6.2 + +### Patch Changes + +- auth: projectAccessKey option +- wallet: use 12 bytes for random space + +## 1.6.1 + +### Patch Changes + +- core: add simple config from subdigest support +- core: fix encode tree with subdigest +- account: implement buildOnChainSignature on Account + +## 1.6.0 + +### Minor Changes + +- account, wallet: parallel transactions by default + +### Patch Changes + +- provider: emit disconnect on sign out + +## 1.5.0 + +### Minor Changes + +- signhub: add 'signing' signer status + +### Patch Changes + +- auth: Session.open: onAccountAddress callback +- account: allow empty transaction bundles + +## 1.4.9 + +### Patch Changes + +- rename SequenceMetadataClient to SequenceMetadata + +## 1.4.8 + +### Patch Changes + +- account: Account.getSigners + +## 1.4.7 + +### Patch Changes + +- update indexer client bindings + +## 1.4.6 + +### Patch Changes + +- - add sepolia networks, mark goerli as deprecated + - update indexer client bindings + +## 1.4.5 + +### Patch Changes + +- indexer/metadata: update client bindings +- auth: selectWallet with new address + +## 1.4.4 + +### Patch Changes + +- indexer: update bindings +- auth: handle jwt expiry + +## 1.4.3 + +### Patch Changes + +- guard: return active status from GuardSigner.getAuthMethods + +## 1.4.2 + +### Patch Changes + +- guard: update bindings + +## 1.4.1 + +### Patch Changes + +- network: remove unused networks +- signhub: orchestrator interface +- guard: auth methods interface +- guard: update bindings for pin and totp +- guard: no more retry logic + +## 1.4.0 + +### Minor Changes + +- project access key support + +## 1.3.0 + +### Minor Changes + +- signhub: account children + +### Patch Changes + +- guard: do not throw when building deploy transaction +- network: snowtrace.io -> subnets.avax.network/c-chain + +## 1.2.9 + +### Patch Changes + +- account: AccountSigner.sendTransaction simulateForFeeOptions +- relayer: update bindings + +## 1.2.8 + +### Patch Changes + +- rename X-Sequence-Token-Key header to X-Access-Key + +## 1.2.7 + +### Patch Changes + +- add x-sequence-token-key to clients + +## 1.2.6 + +### Patch Changes + +- Fix bind multicall provider + +## 1.2.5 + +### Patch Changes + +- Multicall default configuration fixes + +## 1.2.4 + +### Patch Changes + +- provider: Adding missing payment provider types to PaymentProviderOption +- provider: WalletRequestHandler.notifyChainChanged + +## 1.2.3 + +### Patch Changes + +- auth, provider: connect to accept optional authorizeNonce + +## 1.2.2 + +### Patch Changes + +- provider: allow createContract calls +- core: check for explicit zero address in contract deployments + +## 1.2.1 + +### Patch Changes + +- auth: use sequence api chain id as reference chain id if available + +## 1.2.0 + +### Minor Changes + +- split services from session, better local support + +## 1.1.15 + +### Patch Changes + +- guard: remove error filtering + +## 1.1.14 + +### Patch Changes + +- guard: add GuardSigner.onError + +## 1.1.13 + +### Patch Changes + +- provider: pass client version with connect options +- provider: removing large from BannerSize + +## 1.1.12 + +### Patch Changes + +- provider: adding bannerSize to ConnectOptions + +## 1.1.11 + +### Patch Changes + +- add homeverse configs + +## 1.1.10 + +### Patch Changes + +- handle default EIP6492 on send + +## 1.1.9 + +### Patch Changes + +- Custom default EIP6492 on client + +## 1.1.8 + +### Patch Changes + +- metadata: searchMetadata: add types filter + +## 1.1.7 + +### Patch Changes + +- adding signInWith connect settings option to allow dapps to automatically login their users with a certain provider optimizing the normal authentication flow + +## 1.1.6 + +### Patch Changes + +- metadata: searchMetadata: add chainID and excludeTokenMetadata filters + +## 1.1.5 + +### Patch Changes + +- account: re-compute meta-transaction id for wallet deployment transactions + +## 1.1.4 + +### Patch Changes + +- network: rename base-mainnet to base +- provider: override isDefaultChain with ConnectOptions.networkId if provided + +## 1.1.3 + +### Patch Changes + +- provider: use network id from transport session +- provider: sign authorization using ConnectOptions.networkId if provided + +## 1.1.2 + +### Patch Changes + +- provider: jsonrpc chain id fixes + +## 1.1.1 + +### Patch Changes + +- network: add base mainnet and sepolia +- provider: reject toxic transaction requests + +## 1.1.0 + +### Minor Changes + +- Refactor dapp facing provider + +## 1.0.5 + +### Patch Changes + +- network: export network constants +- guard: use the correct global for fetch +- network: nova-explorer.arbitrum.io -> nova.arbiscan.io + +## 1.0.4 + +### Patch Changes + +- provider: accept name or number for networkId + +## 1.0.3 + +### Patch Changes + +- Simpler isValidSignature helpers + +## 1.0.2 + +### Patch Changes + +- add extra signature validation utils methods + +## 1.0.1 + +### Patch Changes + +- add homeverse testnet + +## 1.0.0 + +### Major Changes + +- https://sequence.xyz/blog/sequence-wallet-light-state-sync-full-merkle-wallets + +## 0.43.34 + +### Patch Changes + +- auth: no jwt for indexer + +## 0.43.33 + +### Patch Changes + +- Adding onConnectOptionsChange handler to WalletRequestHandler + +## 0.43.32 + +### Patch Changes + +- add Base Goerli network + +## 0.43.31 + +### Patch Changes + +- remove AuxDataProvider, add promptSignInConnect + +## 0.43.30 + +### Patch Changes + +- add arbitrum goerli testnet + +## 0.43.29 + +### Patch Changes + +- provider: check availability of window object + +## 0.43.28 + +### Patch Changes + +- update api bindings + +## 0.43.27 + +### Patch Changes + +- Add rpc is sequence method + +## 0.43.26 + +### Patch Changes + +- add zkevm url to enum + +## 0.43.25 + +### Patch Changes + +- added polygon zkevm to mainnet networks + +## 0.43.24 + +### Patch Changes + +- name change from zkevm to polygon-zkevm + +## 0.43.23 + +### Patch Changes + +- update zkEVM name to Polygon zkEVM + +## 0.43.22 + +### Patch Changes + +- add zkevm chain + +## 0.43.21 + +### Patch Changes + +- api: update client bindings + +## 0.43.20 + +### Patch Changes + +- indexer: update bindings + +## 0.43.19 + +### Patch Changes + +- session proof update + +## 0.43.18 + +### Patch Changes + +- rpc client global check, hardening + +## 0.43.17 + +### Patch Changes + +- rpc clients, check of 'global' is defined + +## 0.43.16 + +### Patch Changes + +- ethers peerDep to v5, update rpc client global use + +## 0.43.15 + +### Patch Changes + +- - provider: expand receiver type on some util methods + +## 0.43.14 + +### Patch Changes + +- bump + +## 0.43.13 + +### Patch Changes + +- update rpc bindings + +## 0.43.12 + +### Patch Changes + +- provider: single wallet init, and add new unregisterWallet() method + +## 0.43.11 + +### Patch Changes + +- fix lockfiles +- re-add mocha type deleter + +## 0.43.10 + +### Patch Changes + +- various improvements + +## 0.43.9 + +### Patch Changes + +- update deps + +## 0.43.8 + +### Patch Changes + +- network: JsonRpcProvider with caching + +## 0.43.7 + +### Patch Changes + +- provider: fix wallet network init + +## 0.43.6 + +### Patch Changes + +- metadatata: update rpc bindings + +## 0.43.5 + +### Patch Changes + +- provider: do not set default network for connect messages +- provider: forward missing error message + +## 0.43.4 + +### Patch Changes + +- no-change version bump to fix incorrectly tagged snapshot build + +## 0.43.3 + +### Patch Changes + +- metadata: update bindings + +## 0.43.2 + +### Patch Changes + +- provider: implement connectUnchecked + +## 0.43.1 + +### Patch Changes + +- update to latest ethauth dep + +## 0.43.0 + +### Minor Changes + +- move ethers to a peer dependency + +## 0.42.10 + +### Patch Changes + +- add auxDataProvider + +## 0.42.9 + +### Patch Changes + +- provider: add eip-191 exceptions + +## 0.42.8 + +### Patch Changes + +- provider: skip setting intent origin if we're unity plugin + +## 0.42.7 + +### Patch Changes + +- Add sign in options to connection settings + +## 0.42.6 + +### Patch Changes + +- api bindings update + +## 0.42.5 + +### Patch Changes + +- relayer: don't treat missing receipt as hard failure + +## 0.42.4 + +### Patch Changes + +- provider: add custom app protocol to connect options + +## 0.42.3 + +### Patch Changes + +- update api bindings + +## 0.42.2 + +### Patch Changes + +- disable rinkeby network + +## 0.42.1 + +### Patch Changes + +- wallet: optional waitForReceipt parameter + +## 0.42.0 + +### Minor Changes + +- relayer: estimateGasLimits -> simulate +- add simulator package + +### Patch Changes + +- transactions: fix flattenAuxTransactions +- provider: only filter nullish values +- provider: re-map transaction 'gas' back to 'gasLimit' + +## 0.41.3 + +### Patch Changes + +- api bindings update + +## 0.41.2 + +### Patch Changes + +- api bindings update + +## 0.41.1 + +### Patch Changes + +- update default networks + +## 0.41.0 + +### Minor Changes + +- relayer: fix Relayer.wait() interface + + The interface for calling Relayer.wait() has changed. Instead of a single optional ill-defined timeout/delay parameter, there are three optional parameters, in order: + + - timeout: the maximum time to wait for the transaction receipt + - delay: the polling interval, i.e. the time to wait between requests + - maxFails: the maximum number of hard failures to tolerate before giving up + + Please update your codebase accordingly. + +- relayer: add optional waitForReceipt parameter to Relayer.relay + + The behaviour of Relayer.relay() was not well-defined with respect to whether or not it waited for a receipt. + This change allows the caller to specify whether to wait or not, with the default behaviour being to wait. + +### Patch Changes + +- relayer: wait receipt retry logic +- fix wrapped object error +- provider: forward delegateCall and revertOnError transaction fields + +## 0.40.6 + +### Patch Changes + +- add arbitrum-nova chain + +## 0.40.5 + +### Patch Changes + +- api: update bindings + +## 0.40.4 + +### Patch Changes + +- add unreal transport + +## 0.40.3 + +### Patch Changes + +- provider: fix MessageToSign message type + +## 0.40.2 + +### Patch Changes + +- Wallet provider, loadSession method + +## 0.40.1 + +### Patch Changes + +- export sequence.initWallet and sequence.getWallet + +## 0.40.0 + +### Minor Changes + +- add sequence.initWallet(network, config) and sequence.getWallet() helper methods + +## 0.39.6 + +### Patch Changes + +- indexer: update client bindings + +## 0.39.5 + +### Patch Changes + +- provider: fix networkRpcUrl config option + +## 0.39.4 + +### Patch Changes + +- api: update client bindings + +## 0.39.3 + +### Patch Changes + +- add request method on Web3Provider + +## 0.39.2 + +### Patch Changes + +- update umd name + +## 0.39.1 + +### Patch Changes + +- add Aurora network +- add origin info for accountsChanged event to handle it per dapp + +## 0.39.0 + +### Minor Changes + +- abstract window.localStorage to interface type + +## 0.38.2 + +### Patch Changes + +- provider: add Settings.defaultPurchaseAmount + +## 0.38.1 + +### Patch Changes + +- update api and metadata rpc bindings + +## 0.38.0 + +### Minor Changes + +- api: update bindings, change TokenPrice interface +- bridge: remove @0xsequence/bridge package +- api: update bindings, rename ContractCallArg to TupleComponent + +## 0.37.1 + +### Patch Changes + +- Add back sortNetworks - Removing sorting was a breaking change for dapps on older versions which directly integrate sequence. + +## 0.37.0 + +### Minor Changes + +- network related fixes and improvements +- api: bindings: exchange rate lookups + +## 0.36.13 + +### Patch Changes + +- api: update bindings with new price endpoints + +## 0.36.12 + +### Patch Changes + +- wallet: skip remote signers if not needed +- auth: check that signature meets threshold before requesting auth token + +## 0.36.11 + +### Patch Changes + +- Prefix EIP191 message on wallet-request-handler + +## 0.36.10 + +### Patch Changes + +- support bannerUrl on connect + +## 0.36.9 + +### Patch Changes + +- minor dev xp improvements + +## 0.36.8 + +### Patch Changes + +- more connect options (theme, payment providers, funding currencies) + +## 0.36.7 + +### Patch Changes + +- fix missing break + +## 0.36.6 + +### Patch Changes + +- wallet_switchEthereumChain support + +## 0.36.5 + +### Patch Changes + +- auth: bump ethauth to 0.7.0 + network, wallet: don't assume position of auth network in list + api/indexer/metadata: trim trailing slash on hostname, and add endpoint urls + relayer: Allow to specify local relayer transaction parameters like gas price or gas limit + +## 0.36.4 + +### Patch Changes + +- Updating list of chain ids to include other ethereum compatible chains + +## 0.36.3 + +### Patch Changes + +- provider: pass connect options to prompter methods + +## 0.36.2 + +### Patch Changes + +- transactions: Setting target to 0x0 when empty to during SequenceTxAbiEncode + +## 0.36.1 + +### Patch Changes + +- metadata: update client with more fields + +## 0.36.0 + +### Minor Changes + +- relayer, wallet: fee quote support + +## 0.35.12 + +### Patch Changes + +- provider: rename wallet.commands to wallet.utils + +## 0.35.11 + +### Patch Changes + +- provider/utils: smoother message validation + +## 0.35.10 + +### Patch Changes + +- upgrade deps + +## 0.35.9 + +### Patch Changes + +- provider: window-transport override event handlers with new wallet instance + +## 0.35.8 + +### Patch Changes + +- provider: async wallet sign in improvements + +## 0.35.7 + +### Patch Changes + +- config: cache wallet configs + +## 0.35.6 + +### Patch Changes + +- provider: support async signin of wallet request handler + +## 0.35.5 + +### Patch Changes + +- wallet: skip threshold check during fee estimation + +## 0.35.4 + +### Patch Changes + +- - browser extension mode, center window + +## 0.35.3 + +### Patch Changes + +- - update window position when in browser extension mode + +## 0.35.2 + +### Patch Changes + +- - provider: WindowMessageHandler accept optional windowHref + +## 0.35.1 + +### Patch Changes + +- wallet: update config on undeployed too + +## 0.35.0 + +### Minor Changes + +- - config: add buildStubSignature + - provider: add checks to signing cases for wallet deployment and config statuses + - provider: add prompt for wallet deployment + - relayer: add BaseRelayer.prependWalletDeploy + - relayer: add Relayer.feeOptions + - relayer: account for wallet deployment in fee estimation + - transactions: add fromTransactionish + - wallet: add Account.prependConfigUpdate + - wallet: add Account.getFeeOptions + +## 0.34.0 + +### Minor Changes + +- - upgrade deps + +## 0.31.0 + +### Minor Changes + +- - upgrading to ethers v5.5 + +## 0.30.0 + +### Minor Changes + +- - upgrade most deps + +## 0.29.8 + +### Patch Changes + +- update api + +## 0.29.0 + +### Minor Changes + +- major architectural changes in Sequence design + + - only one API instance, API is no longer a per-chain service + - separate per-chain indexer service, API no longer handles indexing + - single contract metadata service, API no longer serves metadata + + chaind package has been removed, indexer and metadata packages have been added + + stronger typing with new explicit ChainId type + + multicall fixes and improvements + + forbid "wait" transactions in sendTransactionBatch calls + +## 0.28.0 + +### Minor Changes + +- extension provider + +## 0.27.0 + +### Minor Changes + +- Add requireFreshSigner lib to sessions + +## 0.25.1 + +### Patch Changes + +- Fix build typescrypt issue + +## 0.25.0 + +### Minor Changes + +- 10c8af8: Add estimator package + Fix multicall few calls bug + +## 0.23.0 + +### Minor Changes + +- - relayer: offer variety of gas fee options from the relayer service" + +## 0.22.2 + +### Patch Changes + +- e1c109e: Fix authProof on expired sessions + +## 0.22.1 + +### Patch Changes + +- transport session cache + +## 0.22.0 + +### Minor Changes + +- e667b65: Expose all relayer options on networks + +## 0.21.5 + +### Patch Changes + +- Give priority to metaTxnId returned by relayer + +## 0.21.4 + +### Patch Changes + +- Add has enough signers method + +## 0.21.3 + +### Patch Changes + +- add window session cache + +## 0.21.2 + +### Patch Changes + +- exception handlind in relayer + +## 0.21.0 + +### Minor Changes + +- - fix gas estimation on wallets with large number of signers + - update to session handling and wallet config construction upon auth + +## 0.19.3 + +### Patch Changes + +- jwtAuth visibility, package version sync + +## 0.19.0 + +### Minor Changes + +- - provider, improve dapp / wallet transport io + +## 0.18.0 + +### Minor Changes + +- relayer improvements and pending transaction handling + +## 0.16.0 + +### Minor Changes + +- relayer as its own service separate from chaind + +## 0.15.1 + +### Patch Changes + +- update api clients + +## 0.14.3 + +### Patch Changes + +- Fix 0xSequence relayer dependencies + +## 0.14.2 + +### Patch Changes + +- Add debug logs to rpc-relayer + +## 0.14.0 + +### Minor Changes + +- update sequence utils finder which includes optimization + +## 0.13.0 + +### Minor Changes + +- Update SequenceUtils deployed contract + +## 0.12.1 + +### Patch Changes + +- npm bump + +## 0.12.0 + +### Minor Changes + +- provider: improvements to window transport + +## 0.11.4 + +### Patch Changes + +- update api client + +## 0.11.3 + +### Patch Changes + +- improve openWindow state options handling + +## 0.11.2 + +### Patch Changes + +- Fix multicall proxy scopes + +## 0.11.1 + +### Patch Changes + +- Add support for dynamic and nested signatures + +## 0.11.0 + +### Minor Changes + +- Update wallet context to 1.7 contracts + +## 0.10.9 + +### Patch Changes + +- add support for public addresses as signers in session.open + +## 0.10.8 + +### Patch Changes + +- Multicall production configuration + +## 0.10.7 + +### Patch Changes + +- allow provider transport to force disconnect + +## 0.10.6 + +### Patch Changes + +- - fix getWalletState method + +## 0.10.5 + +### Patch Changes + +- update relayer gas refund options + +## 0.10.4 + +### Patch Changes + +- Update api proto + +## 0.10.3 + +### Patch Changes + +- Fix loading config cross-chain + +## 0.10.2 + +### Patch Changes + +- - message digest fix + +## 0.10.1 + +### Patch Changes + +- upgrade deps + +## 0.10.0 + +### Minor Changes + +- Deployed new contracts with ERC1271 signer support + +## 0.9.6 + +### Patch Changes + +- Update ABIs for latest sequence contracts + +## 0.9.5 + +### Patch Changes + +- Implemented session class + +## 0.9.3 + +### Patch Changes + +- - minor improvements + +## 0.9.1 + +### Patch Changes + +- - patch bump + +## 0.9.0 + +### Minor Changes + +- - provider transport hardening + +## 0.8.5 + +### Patch Changes + +- - use latest wallet-contracts + +## 0.8.4 + +### Patch Changes + +- - minor improvements, name updates and comments + +## 0.8.3 + +### Patch Changes + +- - refinements + + - normalize signer address in config + + - provider: getWalletState() method to WalletProvider + +## 0.8.2 + +### Patch Changes + +- - field rename and ethauth dependency bump + +## 0.8.1 + +### Patch Changes + +- - variety of optimizations + +## 0.8.0 + +### Minor Changes + +- - changeset fix + +## 0.7.1 + +### Patch Changes + +- 02377ab: Minor improvements + +## 0.7.0 + +### Patch Changes + +- 6f11ed7: sequence.js, init release diff --git a/packages/utils/abi/CHANGELOG.md b/packages/utils/abi/CHANGELOG.md index b66fe1270a..66866e4e33 100644 --- a/packages/utils/abi/CHANGELOG.md +++ b/packages/utils/abi/CHANGELOG.md @@ -1,5 +1,11 @@ # @0xsequence/abi +## 3.0.10 + +### Patch Changes + +- Minor network updates, relayer interface + ## 3.0.9 ### Patch Changes diff --git a/packages/utils/abi/package.json b/packages/utils/abi/package.json index a226d70fb4..34b211947d 100644 --- a/packages/utils/abi/package.json +++ b/packages/utils/abi/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/abi", - "version": "3.0.9", + "version": "3.0.10", "description": "abi sub-package for Sequence", "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/utils/abi", "author": "Sequence Platforms ULC", diff --git a/packages/utils/package.json b/packages/utils/package.json new file mode 100644 index 0000000000..672a7b3364 --- /dev/null +++ b/packages/utils/package.json @@ -0,0 +1,29 @@ +{ + "name": "@0xsequence/utils", + "version": "2.0.0", + "description": "utils sub-package for Sequence", + "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/utils", + "source": "src/index.ts", + "main": "dist/0xsequence-utils.cjs.js", + "module": "dist/0xsequence-utils.esm.js", + "author": "Horizon Blockchain Games", + "license": "Apache-2.0", + "scripts": { + "test": "pnpm test:file tests/**/*.spec.ts", + "test:file": "NODE_OPTIONS='--import tsx' mocha --timeout 30000", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "js-base64": "^3.7.2" + }, + "peerDependencies": { + "ethers": ">=5.5 < 6" + }, + "devDependencies": { + "ethers": "^5.7.2" + }, + "files": [ + "src", + "dist" + ] +} diff --git a/packages/utils/src/base64.ts b/packages/utils/src/base64.ts new file mode 100644 index 0000000000..098abf26a8 --- /dev/null +++ b/packages/utils/src/base64.ts @@ -0,0 +1,23 @@ +import { Base64 } from 'js-base64' + +export const base64Encode = (val: string): string => { + return Base64.encode(val, true) +} + +export const base64EncodeObject = (obj: any): string => { + return Base64.encode(JSON.stringify(obj), true) +} + +export const base64Decode = (encodedString: string): string | undefined => { + if (encodedString === null || encodedString === undefined) { + return undefined + } + return Base64.decode(encodedString) +} + +export const base64DecodeObject = (encodedObject: string | null): T | undefined => { + if (encodedObject === null || encodedObject === undefined) { + return undefined + } + return JSON.parse(Base64.decode(encodedObject)) as T +} diff --git a/packages/utils/src/big-number.ts b/packages/utils/src/big-number.ts new file mode 100644 index 0000000000..e5ae37e34a --- /dev/null +++ b/packages/utils/src/big-number.ts @@ -0,0 +1,14 @@ +import { BigNumber, BigNumberish, utils } from 'ethers' + +// ethers implement this method but doesn't exports it +export function isBigNumberish(value: any): value is BigNumberish { + return ( + value != null && + (BigNumber.isBigNumber(value) || + (typeof value === 'number' && value % 1 === 0) || + (typeof value === 'string' && !!value.match(/^-?[0-9]+$/)) || + utils.isHexString(value) || + typeof value === 'bigint' || + utils.isBytes(value)) + ) +} diff --git a/packages/utils/src/digest.ts b/packages/utils/src/digest.ts new file mode 100644 index 0000000000..970dd43552 --- /dev/null +++ b/packages/utils/src/digest.ts @@ -0,0 +1,18 @@ +import { ethers } from 'ethers' + +export const encodeMessageDigest = (message: string | Uint8Array) => { + if (typeof message === 'string') { + return ethers.utils.arrayify(ethers.utils.keccak256(ethers.utils.toUtf8Bytes(message))) + } else { + return ethers.utils.arrayify(ethers.utils.keccak256(message)) + } +} + +// packMessageData encodes the specified data ready for the Sequence Wallet contracts. +export const packMessageData = (walletAddress: string, chainId: ethers.BigNumberish, digest: ethers.BytesLike): string => { + return ethers.utils.solidityPack(['string', 'uint256', 'address', 'bytes32'], ['\x19\x01', chainId, walletAddress, digest]) +} + +export const subDigestOf = (address: string, chainId: ethers.BigNumberish, digest: ethers.BytesLike): string => { + return ethers.utils.keccak256(packMessageData(address, chainId, digest)) +} diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts new file mode 100644 index 0000000000..aa547dd9a0 --- /dev/null +++ b/packages/utils/src/index.ts @@ -0,0 +1,17 @@ +export * from './base64' +export * from './big-number' +export * from './digest' +export * from './is-node-or-browser' +export * from './jwt-decode' +export * from './logger' +export * from './merkle' +export * from './network' +export * from './promise-cache' +export * from './promisify' +export * from './query-string' +export * from './rand' +export * from './sanitize' +export * from './sleep' +export * from './typed-data' +export * from './types' +export * from './web' diff --git a/packages/utils/src/is-node-or-browser.ts b/packages/utils/src/is-node-or-browser.ts new file mode 100644 index 0000000000..f84032c781 --- /dev/null +++ b/packages/utils/src/is-node-or-browser.ts @@ -0,0 +1,9 @@ +export const isNode = () => { + if (typeof window === 'undefined' && typeof process === 'object') { + return true + } else { + return false + } +} + +export const isBrowser = () => !isNode() diff --git a/packages/utils/src/jwt-decode.ts b/packages/utils/src/jwt-decode.ts new file mode 100644 index 0000000000..baa862bf1c --- /dev/null +++ b/packages/utils/src/jwt-decode.ts @@ -0,0 +1,10 @@ +import { Base64 } from 'js-base64' + +export const jwtDecodeClaims = (jwt: string) => { + const parts = jwt.split('.') + if (parts.length !== 3) { + throw new Error('invalid jwt') + } + const claims = JSON.parse(Base64.decode(parts[1])) as T + return claims +} diff --git a/packages/utils/src/logger.ts b/packages/utils/src/logger.ts new file mode 100644 index 0000000000..2da1ebf1f0 --- /dev/null +++ b/packages/utils/src/logger.ts @@ -0,0 +1,98 @@ +export type LogLevel = 'DEBUG' | 'INFO' | 'WARN' | 'ERROR' | 'DISABLED' + +enum logLevel { + DEBUG = 1, + INFO = 2, + WARN = 3, + ERROR = 4, + DISABLED = 5 +} + +export interface LoggerConfig { + logLevel: LogLevel + silence?: boolean + + onwarn?: (message: any, ...optionalParams: any[]) => void + onerror?: (message: any, ...optionalParams: any[]) => void +} + +export class Logger { + logLevel: logLevel + + constructor(private config: LoggerConfig) { + this.configure(config) + } + + configure(config: Partial) { + this.config = { ...this.config, ...config } + switch (this.config.logLevel) { + case 'DEBUG': + this.logLevel = logLevel.DEBUG + break + case 'INFO': + this.logLevel = logLevel.INFO + break + case 'WARN': + this.logLevel = logLevel.WARN + break + case 'ERROR': + this.logLevel = logLevel.ERROR + break + case 'DISABLED': + this.logLevel = logLevel.DISABLED + break + default: + this.logLevel = logLevel.INFO + break + } + + // undefined silence value will disable the default silence flag + if (this.config.silence === undefined) { + this.config.silence = false + } + } + + debug(message: any, ...optionalParams: any[]) { + if (this.config.silence === true) return + if (this.logLevel === logLevel.DEBUG) { + console.log(message, ...optionalParams) + } + } + + info(message: any, ...optionalParams: any[]) { + if (this.config.silence === true) return + if (this.logLevel <= logLevel.INFO) { + console.log(message, ...optionalParams) + } + } + + warn(message: any, ...optionalParams: any[]) { + if (this.config.silence === true) return + if (this.logLevel <= logLevel.WARN) { + console.warn(message, ...optionalParams) + if (this.config.onwarn) { + this.config.onwarn(message, optionalParams) + } + } + } + + error(message: any, ...optionalParams: any[]) { + if (this.config.silence === true) return + if (this.logLevel <= logLevel.ERROR) { + console.error(message, ...optionalParams) + if (this.config.onerror) { + this.config.onerror(message, optionalParams) + } + } + } +} + +export const logger = new Logger({ + logLevel: 'INFO', + + // By default we silence the logger. In tests we should call `configureLogger` + // below to set silence: false. + silence: true +}) + +export const configureLogger = (config: Partial) => logger.configure(config) diff --git a/packages/utils/src/merkle.ts b/packages/utils/src/merkle.ts new file mode 100644 index 0000000000..6767fbc7fa --- /dev/null +++ b/packages/utils/src/merkle.ts @@ -0,0 +1,49 @@ +import { BigNumberish, utils } from 'ethers' +import { MerkleTree } from './merkletree' + +export type ToLeaf = (element: T) => string +export type Proof = string[] + +export class MerkleTreeGenerator { + private elements: T[] + private toLeaf: ToLeaf + private tree: MerkleTree + + constructor(elements: T[], toLeaf: ToLeaf) { + this.elements = elements + this.toLeaf = toLeaf + } + + generateTree(): MerkleTree { + const hashed = this.elements.map(e => this.toLeaf(e)) + return new MerkleTree(hashed, { + sortPairs: true, + sortLeaves: true + }) + } + + generateRoot(): string { + if (!this.tree) this.tree = this.generateTree() + return this.tree.getHexRoot() + } + + generateProof(element: T): Proof { + if (!this.elements.includes(element)) throw new Error('Element not found') + if (!this.tree) this.tree = this.generateTree() + return this.tree.getHexProof(this.toLeaf(element)) + } + + verifyProof(element: T, proof: Proof): boolean { + if (!this.elements.includes(element)) throw new Error('Element not found') + if (!this.tree) this.tree = this.generateTree() + return this.tree.verify(proof, this.toLeaf(element), this.generateRoot()) + } +} + +export type SaleItemsElement = { + address: string + tokenId: BigNumberish +} + +export const getSaleItemsLeaf: ToLeaf = element => + utils.solidityKeccak256(['address', 'uint256'], [element.address.toLowerCase(), element.tokenId]) diff --git a/packages/utils/src/merkletree/Base.ts b/packages/utils/src/merkletree/Base.ts new file mode 100644 index 0000000000..71dd9549e8 --- /dev/null +++ b/packages/utils/src/merkletree/Base.ts @@ -0,0 +1,109 @@ +import { ethers } from 'ethers' + +export class Base { + static bufferIndexOf(array: Uint8Array[], element: Uint8Array, isSorted: boolean = false): number { + if (isSorted) { + return Base.binarySearch(array, element, Base.compare) + } + + const eqChecker = (buffer1: Uint8Array, buffer2: Uint8Array): boolean => { + if (buffer1 === buffer2) { + return true + } + if (buffer1.length !== buffer2.length) { + return false + } + for (let i = 0; i < buffer1.length; i++) { + if (buffer1[i] !== buffer2[i]) { + return false + } + } + return true + } + + return Base.linearSearch(array, element, eqChecker) + } + + static binarySearch( + array: Uint8Array[], + element: Uint8Array, + compareFunction: (a: Uint8Array, b: Uint8Array) => number + ): number { + let start = 0 + let end = array.length - 1 + + // Iterate while start not meets end + while (start <= end) { + // Find the mid index + const mid = Math.floor((start + end) / 2) + + // Check if the mid value is greater than, equal to, or less than search element. + const ordering = compareFunction(array[mid], element) + + // If element is present at mid, start iterating for searching first appearance. + if (ordering === 0) { + // Linear reverse iteration until the first matching item index is found. + for (let i = mid - 1; i >= 0; i--) { + if (compareFunction(array[i], element) === 0) continue + return i + 1 + } + return 0 + } /* Else look in left or right half accordingly */ else if (ordering < 0) { + start = mid + 1 + } else { + end = mid - 1 + } + } + + return -1 + } + + static compare(a: Uint8Array, b: Uint8Array): number { + // Determine the minimum length to compare + const len = Math.min(a.length, b.length) + + // Compare byte by byte + for (let i = 0; i < len; i++) { + if (a[i] !== b[i]) { + return a[i] - b[i] + } + } + + // If all compared bytes are equal, compare lengths + return a.length - b.length + } + + static linearSearch(array: Uint8Array[], element: Uint8Array, eqChecker: (a: Uint8Array, b: Uint8Array) => boolean): number { + for (let i = 0; i < array.length; i++) { + if (eqChecker(array[i], element)) { + return i + } + } + + return -1 + } + + static bufferify(value: Uint8Array | string): Uint8Array { + if (typeof value === 'string') { + return ethers.utils.arrayify(value) + } + return value + } + + static isHexString(v: string): boolean { + return typeof v === 'string' && /^(0x)?[0-9A-Fa-f]*$/.test(v) + } + + static bufferToHex(value: Uint8Array, withPrefix: boolean = true): string { + const prefixed = ethers.utils.hexlify(value, { + allowMissingPrefix: true + }) + return withPrefix ? prefixed : prefixed.substring(2) + } + + static bufferifyFn(f: any): any { + return (value: any): Uint8Array => { + return Base.bufferify(f(value)) + } + } +} diff --git a/packages/utils/src/merkletree/MerkleTree.ts b/packages/utils/src/merkletree/MerkleTree.ts new file mode 100644 index 0000000000..bccea58d9a --- /dev/null +++ b/packages/utils/src/merkletree/MerkleTree.ts @@ -0,0 +1,186 @@ +import { ethers } from 'ethers' +import { Base } from './Base' + +type TValue = string +type TLeaf = Uint8Array +type TLayer = TLeaf[] +type THashFn = (value: TValue | TLeaf) => TLeaf + +export interface Options { + sortLeaves?: boolean + sortPairs?: boolean +} + +export type Proof = { position: 'left' | 'right'; data: Uint8Array }[] + +export class MerkleTree extends Base { + private hashFn: THashFn + private leaves: TLeaf[] = [] + private layers: TLayer[] = [] + private sortLeaves: boolean = false + private sortPairs: boolean = false + + constructor(leaves: any[], options: Options = {}) { + super() + + this.sortLeaves = !!options.sortLeaves + this.sortPairs = !!options.sortPairs + + this.hashFn = Base.bufferifyFn(ethers.utils.keccak256) + this.processLeaves(leaves) + } + + public getOptions() { + return { + sortLeaves: this.sortLeaves, + sortPairs: this.sortPairs + } + } + + private processLeaves(leaves: TLeaf[]) { + this.leaves = leaves.map(Base.bufferify) + if (this.sortLeaves) { + this.leaves = this.leaves.sort(Base.compare) + } + + this.createHashes(this.leaves) + } + + private createHashes(nodes: Uint8Array[]) { + this.layers = [nodes] + while (nodes.length > 1) { + const layerIndex = this.layers.length + + this.layers.push([]) + + const layerLimit = nodes.length + + for (let i = 0; i < nodes.length; i += 2) { + if (i >= layerLimit) { + this.layers[layerIndex].push(...nodes.slice(layerLimit)) + break + } else if (i + 1 === nodes.length) { + if (nodes.length % 2 === 1) { + // push copy of hash and continue iteration + this.layers[layerIndex].push(nodes[i]) + continue + } + } + + const left = nodes[i] + const right = i + 1 === nodes.length ? left : nodes[i + 1] + const combined = [left, right] + + if (this.sortPairs) { + combined.sort(Base.compare) + } + + const hash = this.hashFn(ethers.utils.concat(combined)) + this.layers[layerIndex].push(hash) + } + + nodes = this.layers[layerIndex] + } + } + + getRoot(): Uint8Array { + if (this.layers.length === 0) { + return Uint8Array.from([]) + } + + return this.layers[this.layers.length - 1][0] || Uint8Array.from([]) + } + + getHexRoot(): string { + return Base.bufferToHex(this.getRoot()) + } + + getProof(leaf: Uint8Array | string, index?: number): Proof { + if (typeof leaf === 'undefined') { + throw new Error('leaf is required') + } + leaf = Base.bufferify(leaf) + const proof: Proof = [] + + if (!Number.isInteger(index)) { + index = -1 + + for (let i = 0; i < this.leaves.length; i++) { + if (Base.compare(leaf, this.leaves[i]) === 0) { + index = i + } + } + } + + // Type fix + index = index as number + + if (index <= -1) { + return [] + } + + for (let i = 0; i < this.layers.length; i++) { + const layer = this.layers[i] + const isRightNode = index % 2 + const pairIndex = isRightNode ? index - 1 : index + 1 + + if (pairIndex < layer.length) { + proof.push({ + position: isRightNode ? 'left' : 'right', + data: layer[pairIndex] + }) + } + + // set index to parent index + index = (index / 2) | 0 + } + + return proof + } + + getHexProof(leaf: Uint8Array | string, index?: number): string[] { + return this.getProof(leaf, index).map(item => Base.bufferToHex(item.data)) + } + + verify(proof: Proof | string[], targetNode: Uint8Array | string, root: Uint8Array | string): boolean { + let hash = Base.bufferify(targetNode) + root = Base.bufferify(root) + + if (!Array.isArray(proof) || !targetNode || !root) { + return false + } + + for (let i = 0; i < proof.length; i++) { + const node = proof[i] + let data: Uint8Array + let isLeftNode: boolean + + if (typeof node === 'string') { + data = Base.bufferify(node) + isLeftNode = true + } else if (node instanceof Object) { + data = node.data + isLeftNode = node.position === 'left' + } else { + throw new Error('Expected node to be of type string or object') + } + + const buffers: Uint8Array[] = [] + + if (this.sortPairs) { + if (Base.compare(hash, data) < 0) { + buffers.push(hash, data) + } else { + buffers.push(data, hash) + } + hash = this.hashFn(ethers.utils.concat(buffers)) + } else { + buffers.push(hash) + buffers[isLeftNode ? 'unshift' : 'push'](data) + hash = this.hashFn(ethers.utils.concat(buffers)) + } + } + + return Base.compare(hash, root) === 0 + } +} diff --git a/packages/utils/src/merkletree/README.md b/packages/utils/src/merkletree/README.md new file mode 100644 index 0000000000..7ad9d73cf5 --- /dev/null +++ b/packages/utils/src/merkletree/README.md @@ -0,0 +1 @@ +This folder is a minimal fork of https://github.com/merkletreejs/merkletreejs with dependencies replaced with ethers. diff --git a/packages/utils/src/merkletree/index.ts b/packages/utils/src/merkletree/index.ts new file mode 100644 index 0000000000..136d7afdcb --- /dev/null +++ b/packages/utils/src/merkletree/index.ts @@ -0,0 +1 @@ +export { MerkleTree } from './MerkleTree' diff --git a/packages/utils/src/network.ts b/packages/utils/src/network.ts new file mode 100644 index 0000000000..a2400e3c61 --- /dev/null +++ b/packages/utils/src/network.ts @@ -0,0 +1,27 @@ +import { ethers } from 'ethers' + +export const getEthersConnectionInfo = (url: string, projectAccessKey?: string, jwt?: string): ethers.utils.ConnectionInfo => { + const headers: { + [key: string]: string | number + } = {} + + if (jwt && jwt.length > 0) { + headers['Authorization'] = `BEARER ${jwt}` + } + if (projectAccessKey && projectAccessKey.length > 0) { + headers['X-Access-Key'] = projectAccessKey + } + + return { + url, + headers, + skipFetchSetup: true, + fetchOptions: { + mode: 'cors', + cache: 'force-cache', + credentials: 'same-origin', + redirect: 'follow', + referrer: 'client' + } + } +} diff --git a/packages/utils/src/promise-cache.ts b/packages/utils/src/promise-cache.ts new file mode 100644 index 0000000000..0504adda88 --- /dev/null +++ b/packages/utils/src/promise-cache.ts @@ -0,0 +1,58 @@ +import { ethers } from 'ethers' + +export class PromiseCache { + private readonly cache: Map + + constructor() { + this.cache = new Map() + } + + do, T>( + key: string, + validMilliseconds: number | undefined, + task: (...args: S) => Promise, + ...args: S + ): Promise { + key = `${key}:${ethers.utils.keccak256(ethers.utils.toUtf8Bytes(JSON.stringify(args, deterministically)))}` + + let entry = this.cache.get(key) + + if (entry) { + if (entry.expiration) { + if (new Date() >= entry.expiration) { + entry = undefined + this.cache.delete(key) + } + } + } + + if (!entry) { + const entry_: Entry = { promise: task(...args) } + + if (validMilliseconds !== undefined) { + entry_.promise = entry_.promise.then(result => { + entry_.expiration = new Date(Date.now() + validMilliseconds) + return result + }) + } + + entry = entry_ + this.cache.set(key, entry) + } + + return entry.promise as Promise + } +} + +type Entry = { + promise: Promise + expiration?: Date +} + +function deterministically(_key: string, value: any): any { + if (typeof value === 'object' && value !== null && !Array.isArray(value)) { + return Object.fromEntries(Object.entries(value).sort()) + } + + return value +} diff --git a/packages/utils/src/promisify.ts b/packages/utils/src/promisify.ts new file mode 100644 index 0000000000..537b3e0180 --- /dev/null +++ b/packages/utils/src/promisify.ts @@ -0,0 +1,32 @@ +export function promisify(f: (cb: (err: any, res: T) => void) => void, thisContext?: any): () => Promise +export function promisify(f: (arg: A, cb: (err: any, res: T) => void) => void, thisContext?: any): (arg: A) => Promise +export function promisify( + f: (arg: A, arg2: A2, cb: (err: any, res: T) => void) => void, + thisContext?: any +): (arg: A, arg2: A2) => Promise +export function promisify( + f: (arg: A, arg2: A2, arg3: A3, cb: (err: any, res: T) => void) => void, + thisContext?: any +): (arg: A, arg2: A2, arg3: A3) => Promise +export function promisify( + f: (arg: A, arg2: A2, arg3: A3, arg4: A4, cb: (err: any, res: T) => void) => void, + thisContext?: any +): (arg: A, arg2: A2, arg3: A3, arg4: A4) => Promise +export function promisify( + f: (arg: A, arg2: A2, arg3: A3, arg4: A4, arg5: A5, cb: (err: any, res: T) => void) => void, + thisContext?: any +): (arg: A, arg2: A2, arg3: A3, arg4: A4, arg5: A5) => Promise + +export function promisify(f: any, thisContext?: any) { + return function (...a: any[]) { + const args = Array.prototype.slice.call(a) + return new Promise(async (resolve, reject) => { + try { + args.push((err: any, result: any) => (err ? reject(err) : resolve(result))) + await f.apply(thisContext, args) + } catch (e) { + reject(e) + } + }) + } +} diff --git a/packages/utils/src/query-string.ts b/packages/utils/src/query-string.ts new file mode 100644 index 0000000000..3980c0e183 --- /dev/null +++ b/packages/utils/src/query-string.ts @@ -0,0 +1,15 @@ +export function queryStringFromObject(name: string, obj: any) { + const k = encodeURIComponent(name) + const v = encodeURIComponent(JSON.stringify(obj)) + return `${k}=${v}` +} + +export function queryStringToObject(qs: string): { [key: string]: any } { + const p = qs.split('&') + const o: { [key: string]: any } = {} + for (const v of p) { + const z = v.split('=') + o[decodeURIComponent(z[0])] = JSON.parse(decodeURIComponent(z[1])) + } + return o +} diff --git a/packages/utils/src/rand.ts b/packages/utils/src/rand.ts new file mode 100644 index 0000000000..50d4ea6d5b --- /dev/null +++ b/packages/utils/src/rand.ts @@ -0,0 +1,5 @@ +export const getRandomInt = (min: number = 0, max: number = Number.MAX_SAFE_INTEGER): number => { + min = Math.ceil(min) + max = Math.floor(max) + return Math.floor(Math.random() * (max - min + 1)) + min +} diff --git a/packages/utils/src/sanitize.ts b/packages/utils/src/sanitize.ts new file mode 100644 index 0000000000..7f1044b39b --- /dev/null +++ b/packages/utils/src/sanitize.ts @@ -0,0 +1,27 @@ +// sanitizeNumberString accepts a number string and returns back a clean number string. +// For example, input '1234.5678' will return '1234.5678' but '12javascript:{}etc' will return '12' +export const sanitizeNumberString = (numString: string | null): string => { + if (!numString || typeof numString !== 'string') { + return '' + } + const v = numString.match(/[\d.]+/) + return v && v.length > 0 ? v[0].trim() : '' +} + +// sanitizeAlphanumeric accepts any string and returns alphanumeric contents only +export const sanitizeAlphanumeric = (alphanum: string): string => { + if (!alphanum || typeof alphanum !== 'string') { + return '' + } + const v = alphanum.match(/[\w\s\d]+/) + return v && v.length > 0 ? v[0].trim() : '' +} + +// sanitizeHost accepts any string and returns valid host string +export const sanitizeHost = (host: string): string => { + if (!host || typeof host !== 'string') { + return '' + } + const v = host.match(/[\w\d.\-:\/]+/) + return v && v.length > 0 ? v[0].trim() : '' +} diff --git a/packages/utils/src/sleep.ts b/packages/utils/src/sleep.ts new file mode 100644 index 0000000000..6120453e0e --- /dev/null +++ b/packages/utils/src/sleep.ts @@ -0,0 +1,8 @@ +export const sleep = (t: number) => { + return new Promise(resolve => { + const timeout = setTimeout(() => { + clearTimeout(timeout) + resolve() + }, t) + }) +} diff --git a/packages/utils/src/typed-data.ts b/packages/utils/src/typed-data.ts new file mode 100644 index 0000000000..5481cdef92 --- /dev/null +++ b/packages/utils/src/typed-data.ts @@ -0,0 +1,24 @@ +import { ethers, TypedDataDomain, TypedDataField } from 'ethers' + +export interface TypedData { + domain: TypedDataDomain + types: Record> + message: Record + primaryType?: string +} + +export type { TypedDataDomain, TypedDataField } + +export const encodeTypedDataHash = (typedData: TypedData): string => { + const types = { ...typedData.types } + + // remove EIP712Domain key from types as ethers will auto-gen it in + // the hash encoder below + delete types['EIP712Domain'] + + return ethers.utils._TypedDataEncoder.hash(typedData.domain, types, typedData.message) +} + +export const encodeTypedDataDigest = (typedData: TypedData): Uint8Array => { + return ethers.utils.arrayify(encodeTypedDataHash(typedData)) +} diff --git a/packages/utils/src/types.ts b/packages/utils/src/types.ts new file mode 100644 index 0000000000..63814fd595 --- /dev/null +++ b/packages/utils/src/types.ts @@ -0,0 +1,25 @@ +import { utils } from 'ethers' + +type Deferrable = utils.Deferrable + +const { defineReadOnly, getStatic, resolveProperties, checkProperties, shallowCopy, deepCopy } = utils + +export type { Deferrable } + +export { defineReadOnly, getStatic, resolveProperties, checkProperties, shallowCopy, deepCopy } + +export type Optionals = Omit< + T, + Exclude< + { + [K in keyof T]: T extends Record ? K : never + }[keyof T], + undefined + > +> + +export type Mask = Omit + +export type Forbid = T & { + [P in K]?: never +} diff --git a/packages/utils/src/web.ts b/packages/utils/src/web.ts new file mode 100644 index 0000000000..d8316e9782 --- /dev/null +++ b/packages/utils/src/web.ts @@ -0,0 +1,2 @@ +// urlClean removes double slashes from url path +export const urlClean = (url: string) => url.replace(/([^:]\/)\/+/g, '$1') diff --git a/packages/utils/tests/base64.spec.ts b/packages/utils/tests/base64.spec.ts new file mode 100644 index 0000000000..d56c24c831 --- /dev/null +++ b/packages/utils/tests/base64.spec.ts @@ -0,0 +1,49 @@ +import { expect } from 'chai' +import { base64EncodeObject, base64DecodeObject } from '@0xsequence/utils' + +describe('base64', function () { + it('encoding, a', () => { + const object = { + a: 1, + b: 2, + c: 'hihi', + d: '1.234' + } + + const encoded = base64EncodeObject(object) + expect(encoded).to.be.equal('eyJhIjoxLCJiIjoyLCJjIjoiaGloaSIsImQiOiIxLjIzNCJ9') + + const o = base64DecodeObject(encoded) + expect(object).to.deep.equal(o) + }) + + it('encoding, b', () => { + const object = { + a: 1, + b: 2, + c: 'hihi', + d: `how do quote's "work+out"?` + } + + const encoded = base64EncodeObject(object) + expect(encoded).to.be.equal('eyJhIjoxLCJiIjoyLCJjIjoiaGloaSIsImQiOiJob3cgZG8gcXVvdGUncyBcIndvcmsrb3V0XCI_In0') + + const o = base64DecodeObject(encoded) + expect(object).to.deep.equal(o) + }) + + it('encoding, c', () => { + const object = { + a: 1, + b: 2, + c: 'hihi', + d: { nest: '123' } + } + + const encoded = base64EncodeObject(object) + expect(encoded).to.be.equal('eyJhIjoxLCJiIjoyLCJjIjoiaGloaSIsImQiOnsibmVzdCI6IjEyMyJ9fQ') + + const o = base64DecodeObject(encoded) + expect(object).to.deep.equal(o) + }) +}) diff --git a/packages/utils/tests/jwt-decode.spec.ts b/packages/utils/tests/jwt-decode.spec.ts new file mode 100644 index 0000000000..f9af7073d5 --- /dev/null +++ b/packages/utils/tests/jwt-decode.spec.ts @@ -0,0 +1,13 @@ +import { expect } from 'chai' +import { jwtDecodeClaims } from '@0xsequence/utils' + +describe('jwt-decode', function () { + it('decode', () => { + const jwt = + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50IjoiMHg4ZTNlMzhmZTczNjdkZDNiNTJkMWUyODFlNGU4NDAwNDQ3YzhkOGI5IiwiYXBwIjoiU2VxdWVuY2UgV2FsbGV0IiwiZXhwIjoxNjIyNzY3MTcwLCJpYXQiOjE2MjAxNzUxNzB9.21AuC33BF6GR67_kixfhoRfpSfN-G98fSe1MEvrcgO0' + + const claims = jwtDecodeClaims(jwt) + expect(claims.account).to.equal('0x8e3e38fe7367dd3b52d1e281e4e8400447c8d8b9') + expect(claims.exp).to.equal(1622767170) + }) +}) diff --git a/packages/utils/tests/merkle.spec.ts b/packages/utils/tests/merkle.spec.ts new file mode 100644 index 0000000000..0713189efe --- /dev/null +++ b/packages/utils/tests/merkle.spec.ts @@ -0,0 +1,34 @@ +import { expect } from 'chai' +import { MerkleTreeGenerator, SaleItemsElement, getSaleItemsLeaf } from '@0xsequence/utils' +import { BigNumber, Wallet, constants, utils } from 'ethers' + +describe('merkle', function () { + const addrs = Array.from({ length: 10 }, () => Wallet.createRandom().address) + const elements: SaleItemsElement[] = addrs.map(addr => ({ address: addr, tokenId: BigNumber.from(1) })) + + it('generates tree, root and proof for custom elements', () => { + const getLeaf = (element: string) => utils.solidityKeccak256(['address'], [element.toLowerCase()]) + const merkleGenerator = new MerkleTreeGenerator(addrs, getLeaf) + expect(merkleGenerator.generateRoot()).to.be.a('string') + const proof = merkleGenerator.generateProof(addrs[0]) + expect(proof).to.be.an('array') + expect(merkleGenerator.verifyProof(addrs[0], proof)).to.be.true + }) + + it('generates tree, root and proof for sale items', () => { + const merkleGenerator = new MerkleTreeGenerator(elements, getSaleItemsLeaf) + expect(merkleGenerator.generateRoot()).to.be.a('string') + const proof = merkleGenerator.generateProof(elements[0]) + expect(proof).to.be.an('array') + expect(merkleGenerator.verifyProof(elements[0], proof)).to.be.true + }) + + it('errors when invalid element', () => { + const merkleGenerator = new MerkleTreeGenerator(elements, getSaleItemsLeaf) + const invalidElement: SaleItemsElement = { + address: Wallet.createRandom().address, + tokenId: constants.Zero + } + expect(() => merkleGenerator.generateProof(invalidElement)).to.throw('Element not found') + }) +}) diff --git a/packages/utils/tests/query-string.spec.ts b/packages/utils/tests/query-string.spec.ts new file mode 100644 index 0000000000..775797c003 --- /dev/null +++ b/packages/utils/tests/query-string.spec.ts @@ -0,0 +1,51 @@ +import { expect } from 'chai' +import { queryStringFromObject, queryStringToObject } from '@0xsequence/utils' + +describe('query-string', function () { + it('encoding, a', () => { + const object = { + a: 1, + b: 2, + c: 'hihi', + d: '1.234' + } + + const qs = queryStringFromObject('k', object) + expect(qs).to.be.equal('k=%7B%22a%22%3A1%2C%22b%22%3A2%2C%22c%22%3A%22hihi%22%2C%22d%22%3A%221.234%22%7D') + + const o = queryStringToObject(qs) + expect({ k: object }).to.deep.equal(o) + }) + + it('encoding, b', () => { + const object = { + a: 1, + b: 2, + c: 'hihi', + d: `how do quote's "work+out"?` + } + + const qs = queryStringFromObject('k', object) + expect(qs).to.be.equal( + "k=%7B%22a%22%3A1%2C%22b%22%3A2%2C%22c%22%3A%22hihi%22%2C%22d%22%3A%22how%20do%20quote's%20%5C%22work%2Bout%5C%22%3F%22%7D" + ) + + const o = queryStringToObject(qs) + expect({ k: object }).to.deep.equal(o) + }) + + it('encoding, c', () => { + const object = { + a: 1, + b: 2, + c: 'hihi', + d: { nest: '123' } + } + + const qs = queryStringFromObject('k', object) + expect(qs).to.be.equal('k=%7B%22a%22%3A1%2C%22b%22%3A2%2C%22c%22%3A%22hihi%22%2C%22d%22%3A%7B%22nest%22%3A%22123%22%7D%7D') + + const o = queryStringToObject(qs) + expect({ k: object }).to.deep.equal(o) + }) +}) diff --git a/packages/utils/tests/sanitize.spec.ts b/packages/utils/tests/sanitize.spec.ts new file mode 100644 index 0000000000..960113319e --- /dev/null +++ b/packages/utils/tests/sanitize.spec.ts @@ -0,0 +1,21 @@ +import { expect } from 'chai' +import { sanitizeHost } from '@0xsequence/utils' + +describe('sanitize', function () { + it('sanitize host', () => { + const a = 'http://localhost:4000' + expect(sanitizeHost(a)).to.equal('http://localhost:4000') + + const b = 'https://localhost:4000' + expect(sanitizeHost(b)).to.equal('https://localhost:4000') + + const c = 'http://play.skyweaver.net' + expect(sanitizeHost(c)).to.equal('http://play.skyweaver.net') + + const d = 'http://hello123-world4.com' + expect(sanitizeHost(d)).to.equal('http://hello123-world4.com') + + const e = 'http://hello-w(!#@%$#%^@orld.com' + expect(sanitizeHost(e)).to.equal('http://hello-w') + }) +}) diff --git a/packages/waas-ethers/CHANGELOG.md b/packages/waas-ethers/CHANGELOG.md new file mode 100644 index 0000000000..088e48963c --- /dev/null +++ b/packages/waas-ethers/CHANGELOG.md @@ -0,0 +1,467 @@ +# @0xsequence/waas-ethers + +## 2.0.0 + +### Major Changes + +- changeset + +### Patch Changes + +- Updated dependencies + - @0xsequence/waas@2.0.0 + +## 1.10.14 + +### Patch Changes + +- network: add borne-testnet to allNetworks +- Updated dependencies + - @0xsequence/waas@1.10.14 + +## 1.10.13 + +### Patch Changes + +- network: add borne testnet +- Updated dependencies + - @0xsequence/waas@1.10.13 + +## 1.10.12 + +### Patch Changes + +- api: update bindings +- global/window -> globalThis +- Updated dependencies +- Updated dependencies + - @0xsequence/waas@1.10.12 + +## 1.10.11 + +### Patch Changes + +- waas: updated intent.gen without webrpc types, errors exported from authenticator.gen +- Updated dependencies + - @0xsequence/waas@1.10.11 + +## 1.10.10 + +### Patch Changes + +- metadata: update bindings with new contract collections api +- Updated dependencies + - @0xsequence/waas@1.10.10 + +## 1.10.9 + +### Patch Changes + +- waas minor update +- Updated dependencies + - @0xsequence/waas@1.10.9 + +## 1.10.8 + +### Patch Changes + +- update metadata bindings +- Updated dependencies + - @0xsequence/waas@1.10.8 + +## 1.10.7 + +### Patch Changes + +- minor fixes to waas client +- Updated dependencies + - @0xsequence/waas@1.10.7 + +## 1.10.6 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/waas@1.10.6 + +## 1.10.5 + +### Patch Changes + +- network: ape-chain-testnet -> apechain-testnet +- Updated dependencies + - @0xsequence/waas@1.10.5 + +## 1.10.4 + +### Patch Changes + +- network: add b3-sepolia, ape-chain-testnet, blast, blast-sepolia +- Updated dependencies + - @0xsequence/waas@1.10.4 + +## 1.10.3 + +### Patch Changes + +- typing fix +- Updated dependencies + - @0xsequence/waas@1.10.3 + +## 1.10.2 + +### Patch Changes + +- - waas: add getIdToken method + - indexer: update api client +- Updated dependencies + - @0xsequence/waas@1.10.2 + +## 1.10.1 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/waas@1.10.1 + +## 1.10.0 + +### Minor Changes + +- waas release v1.3.0 + +### Patch Changes + +- Updated dependencies + - @0xsequence/waas@1.10.0 + +## 1.9.37 + +### Patch Changes + +- network: adds nativeToken data to NetworkMetadata constants +- Updated dependencies + - @0xsequence/waas@1.9.37 + +## 1.9.36 + +### Patch Changes + +- guard: export client +- Updated dependencies + - @0xsequence/waas@1.9.36 + +## 1.9.35 + +### Patch Changes + +- guard: update bindings +- Updated dependencies + - @0xsequence/waas@1.9.35 + +## 1.9.34 + +### Patch Changes + +- waas: always use lowercase email +- Updated dependencies + - @0xsequence/waas@1.9.34 + +## 1.9.33 + +### Patch Changes + +- waas: umd build +- Updated dependencies + - @0xsequence/waas@1.9.33 + +## 1.9.32 + +### Patch Changes + +- indexer: update bindings +- Updated dependencies + - @0xsequence/waas@1.9.32 + +## 1.9.31 + +### Patch Changes + +- metadata: token directory changes +- Updated dependencies + - @0xsequence/waas@1.9.31 + +## 1.9.30 + +### Patch Changes + +- update +- Updated dependencies + - @0xsequence/waas@1.9.30 + +## 1.9.29 + +### Patch Changes + +- disable gnosis chain +- Updated dependencies + - @0xsequence/waas@1.9.29 + +## 1.9.28 + +### Patch Changes + +- add utils/merkletree +- Updated dependencies + - @0xsequence/waas@1.9.28 + +## 1.9.27 + +### Patch Changes + +- network: optimistic -> optimism +- waas: remove defaults +- api, sessions: update bindings +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/waas@1.9.27 + +## 1.9.26 + +### Patch Changes + +- - add backend interfaces for pluggable interfaces + - introduce @0xsequence/react-native + - update pnpm to lockfile v9 +- Updated dependencies + - @0xsequence/waas@1.9.26 + +## 1.9.25 + +### Patch Changes + +- update webrpc clients with new error types +- Updated dependencies + - @0xsequence/waas@1.9.25 + +## 1.9.24 + +### Patch Changes + +- waas: add memoryStore backend to localStore +- Updated dependencies + - @0xsequence/waas@1.9.24 + +## 1.9.23 + +### Patch Changes + +- update api client bindings +- Updated dependencies + - @0xsequence/waas@1.9.23 + +## 1.9.22 + +### Patch Changes + +- update metadata client bindings +- Updated dependencies + - @0xsequence/waas@1.9.22 + +## 1.9.21 + +### Patch Changes + +- api client bindings +- Updated dependencies + - @0xsequence/waas@1.9.21 + +## 1.9.20 + +### Patch Changes + +- api client bindings update +- Updated dependencies + - @0xsequence/waas@1.9.20 + +## 1.9.19 + +### Patch Changes + +- waas update +- Updated dependencies + - @0xsequence/waas@1.9.19 + +## 1.9.18 + +### Patch Changes + +- provider: prohibit dangerous functions +- Updated dependencies + - @0xsequence/waas@1.9.18 + +## 1.9.17 + +### Patch Changes + +- network: add xr-sepolia +- Updated dependencies + - @0xsequence/waas@1.9.17 + +## 1.9.16 + +### Patch Changes + +- waas: sequence.feeOptions +- Updated dependencies + - @0xsequence/waas@1.9.16 + +## 1.9.15 + +### Patch Changes + +- metadata: collection external_link field name fix +- Updated dependencies + - @0xsequence/waas@1.9.15 + +## 1.9.14 + +### Patch Changes + +- network: astar-zkatana -> astar-zkyoto +- network: deprecate polygon mumbai network +- network: add xai and polygon amoy +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/waas@1.9.14 + +## 1.9.13 + +### Patch Changes + +- waas: fix @0xsequence/network dependency +- Updated dependencies + - @0xsequence/waas@1.9.13 + +## 1.9.12 + +### Patch Changes + +- indexer: update rpc bindings +- provider: signMessage: Serialize the BytesLike or string message into hexstring before sending +- waas: SessionAuthProof +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/waas@1.9.12 + +## 1.9.11 + +### Patch Changes + +- metdata, update rpc bindings +- Updated dependencies + - @0xsequence/waas@1.9.11 + +## 1.9.10 + +### Patch Changes + +- update metadata rpc bindings +- Updated dependencies + - @0xsequence/waas@1.9.10 + +## 1.9.9 + +### Patch Changes + +- metadata, add SequenceCollections rpc client +- Updated dependencies + - @0xsequence/waas@1.9.9 + +## 1.9.8 + +### Patch Changes + +- waas client update +- Updated dependencies + - @0xsequence/waas@1.9.8 + +## 1.9.7 + +### Patch Changes + +- update rpc client bindings for api, metadata and relayer +- Updated dependencies + - @0xsequence/waas@1.9.7 + +## 1.9.6 + +### Patch Changes + +- waas package update +- Updated dependencies + - @0xsequence/waas@1.9.6 + +## 1.9.5 + +### Patch Changes + +- RpcRelayer prioritize project access key +- Updated dependencies + - @0xsequence/waas@1.9.5 + +## 1.9.4 + +### Patch Changes + +- waas: fix network dependency +- Updated dependencies + - @0xsequence/waas@1.9.4 + +## 1.9.3 + +### Patch Changes + +- provider: don't append access key to RPC url if user has already provided it +- Updated dependencies + - @0xsequence/waas@1.9.3 + +## 1.9.2 + +### Patch Changes + +- network: add xai-sepolia +- Updated dependencies + - @0xsequence/waas@1.9.2 + +## 1.9.1 + +### Patch Changes + +- analytics fix +- Updated dependencies + - @0xsequence/waas@1.9.1 + +## 1.9.0 + +### Minor Changes + +- waas release + +### Patch Changes + +- Updated dependencies + - @0xsequence/waas@1.9.0 + +## 0.0.0-20231129192642 + +### Minor Changes + +- WaaS Ethers signer wrapper +- Updated dependencies + - @0xsequence/waas@0.0.0-20231129192642 diff --git a/packages/waas-ethers/README.md b/packages/waas-ethers/README.md new file mode 100644 index 0000000000..5fa1f9b1bc --- /dev/null +++ b/packages/waas-ethers/README.md @@ -0,0 +1,4 @@ +@0xsequence/waas-ethers +================= + +See [0xsequence project page](https://github.com/0xsequence/sequence.js). diff --git a/packages/waas-ethers/package.json b/packages/waas-ethers/package.json new file mode 100644 index 0000000000..ef0e9a84cb --- /dev/null +++ b/packages/waas-ethers/package.json @@ -0,0 +1,26 @@ +{ + "name": "@0xsequence/waas-ethers", + "version": "2.0.0", + "description": "waas ethers wrapper", + "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/waas", + "source": "src/index.ts", + "main": "dist/0xsequence-waas-ethers.cjs.js", + "module": "dist/0xsequence-waas-ethers.esm.js", + "author": "Horizon Blockchain Games", + "license": "Apache-2.0", + "scripts": { + "test": "echo todo", + "test:file": "NODE_OPTIONS='--import tsx' mocha -timeout 300000", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@0xsequence/waas": "workspace:*" + }, + "peerDependencies": { + "ethers": ">=5.5" + }, + "files": [ + "src", + "dist" + ] +} diff --git a/packages/waas-ethers/src/index.ts b/packages/waas-ethers/src/index.ts new file mode 100644 index 0000000000..eb0b67f6d6 --- /dev/null +++ b/packages/waas-ethers/src/index.ts @@ -0,0 +1 @@ +export * from './signer' diff --git a/packages/waas-ethers/src/signer.ts b/packages/waas-ethers/src/signer.ts new file mode 100644 index 0000000000..7afeaca8b6 --- /dev/null +++ b/packages/waas-ethers/src/signer.ts @@ -0,0 +1,135 @@ +import { BigNumber, ethers } from 'ethers' +import { CommonAuthArgs, ExtendedSequenceConfig, SequenceWaaS, SequenceConfig, networks, store } from '@0xsequence/waas' + +export class SequenceSigner extends ethers.Signer { + constructor( + private readonly sequence: SequenceWaaS, + readonly provider?: ethers.providers.BaseProvider + ) { + super() + } + + public static fromConfig( + config: SequenceConfig & Partial, + store?: store.Store, + provider?: ethers.providers.BaseProvider + ): SequenceSigner { + return new SequenceSigner(new SequenceWaaS(config, store), provider) + } + + async getAddress(): Promise { + return this.sequence.getAddress() + } + + // Ensure the provider has a sequence supported network + private async _ensureNetworkValid(providerRequired: boolean): Promise { + if (providerRequired && !this.provider) { + throw new Error('Provider is required') + } + if (this.provider && networks.isSimpleNetwork((await this.provider.getNetwork()).chainId)) { + throw new Error('Provider and WaaS configured with different networks') + } + } + + async getSimpleNetwork(): Promise { + if (this.provider) { + return this.provider.getNetwork().then(n => n.chainId) + } + return undefined + } + + async signMessage(message: ethers.utils.Bytes | string, authArgs?: CommonAuthArgs): Promise { + await this._ensureNetworkValid(false) + + const args = { + message: message.toString(), + network: await this.getSimpleNetwork(), + ...authArgs + } + return this.sequence.signMessage(args).then(response => response.data.signature) + } + + async signTransaction(_transaction: ethers.utils.Deferrable): Promise { + // Not supported. Use sendTransaction or signMessage instead. + throw new Error('SequenceSigner does not support signTransaction') + } + + async sendTransaction( + transaction: ethers.utils.Deferrable, + authArgs?: CommonAuthArgs + ): Promise { + await this._ensureNetworkValid(true) + + const args = { + transactions: [await ethers.utils.resolveProperties(transaction)], + network: await this.getSimpleNetwork(), + ...authArgs + } + const response = await this.sequence.sendTransaction(args) + + if (response.code === 'transactionFailed') { + // Failed + throw new Error(`Unable to send transaction: ${response.data.error}`) + } + + if (response.code === 'transactionReceipt') { + // Success + const { txHash } = response.data + // eslint-disable-next-line @typescript-eslint/no-extra-non-null-assertion + return this.provider!!.getTransaction(txHash) + } + + // Impossible + throw new Error('Unknown return value') + } + + connect(provider: ethers.providers.BaseProvider, sequence?: SequenceWaaS): SequenceSigner { + return new SequenceSigner(sequence ?? this.sequence, provider) + } + + // + // Provider required + // + async getBalance(blockTag?: ethers.providers.BlockTag): Promise { + await this._ensureNetworkValid(true) + return super.getBalance(blockTag) + } + + async getTransactionCount(_blockTag?: ethers.providers.BlockTag): Promise { + throw new Error('SequenceSigner does not support getTransactionCount') + } + + async estimateGas(transaction: ethers.utils.Deferrable): Promise { + await this._ensureNetworkValid(true) + //FIXME This won't be accurate + return super.estimateGas(transaction) + } + + async call( + transaction: ethers.utils.Deferrable, + blockTag?: ethers.providers.BlockTag + ): Promise { + await this._ensureNetworkValid(true) + return super.call(transaction, blockTag) + } + + async getChainId(): Promise { + await this._ensureNetworkValid(true) // Prevent mismatched configurations + return super.getChainId() + } + + async getGasPrice(): Promise { + await this._ensureNetworkValid(true) + return super.getGasPrice() + } + + async getFeeData(): Promise { + await this._ensureNetworkValid(true) + return super.getFeeData() + } + + async resolveName(name: string): Promise { + await this._ensureNetworkValid(true) + return super.resolveName(name) + } +} diff --git a/packages/waas/CHANGELOG.md b/packages/waas/CHANGELOG.md new file mode 100644 index 0000000000..7491dff83a --- /dev/null +++ b/packages/waas/CHANGELOG.md @@ -0,0 +1,487 @@ +# @0xsequence/waas + +## 2.0.0 + +### Major Changes + +- changeset + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@2.0.0 + - @0xsequence/network@2.0.0 + +## 1.10.14 + +### Patch Changes + +- network: add borne-testnet to allNetworks +- Updated dependencies + - @0xsequence/core@1.10.14 + - @0xsequence/network@1.10.14 + +## 1.10.13 + +### Patch Changes + +- network: add borne testnet +- Updated dependencies + - @0xsequence/core@1.10.13 + - @0xsequence/network@1.10.13 + +## 1.10.12 + +### Patch Changes + +- api: update bindings +- global/window -> globalThis +- Updated dependencies +- Updated dependencies + - @0xsequence/core@1.10.12 + - @0xsequence/network@1.10.12 + +## 1.10.11 + +### Patch Changes + +- waas: updated intent.gen without webrpc types, errors exported from authenticator.gen +- Updated dependencies + - @0xsequence/core@1.10.11 + - @0xsequence/network@1.10.11 + +## 1.10.10 + +### Patch Changes + +- metadata: update bindings with new contract collections api +- Updated dependencies + - @0xsequence/core@1.10.10 + - @0xsequence/network@1.10.10 + +## 1.10.9 + +### Patch Changes + +- waas minor update +- Updated dependencies + - @0xsequence/core@1.10.9 + - @0xsequence/network@1.10.9 + +## 1.10.8 + +### Patch Changes + +- update metadata bindings +- Updated dependencies + - @0xsequence/core@1.10.8 + - @0xsequence/network@1.10.8 + +## 1.10.7 + +### Patch Changes + +- minor fixes to waas client +- Updated dependencies + - @0xsequence/core@1.10.7 + - @0xsequence/network@1.10.7 + +## 1.10.6 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/core@1.10.6 + - @0xsequence/network@1.10.6 + +## 1.10.5 + +### Patch Changes + +- network: ape-chain-testnet -> apechain-testnet +- Updated dependencies + - @0xsequence/core@1.10.5 + - @0xsequence/network@1.10.5 + +## 1.10.4 + +### Patch Changes + +- network: add b3-sepolia, ape-chain-testnet, blast, blast-sepolia +- Updated dependencies + - @0xsequence/core@1.10.4 + - @0xsequence/network@1.10.4 + +## 1.10.3 + +### Patch Changes + +- typing fix +- Updated dependencies + - @0xsequence/core@1.10.3 + - @0xsequence/network@1.10.3 + +## 1.10.2 + +### Patch Changes + +- - waas: add getIdToken method + - indexer: update api client +- Updated dependencies + - @0xsequence/core@1.10.2 + - @0xsequence/network@1.10.2 + +## 1.10.1 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/core@1.10.1 + - @0xsequence/network@1.10.1 + +## 1.10.0 + +### Minor Changes + +- waas release v1.3.0 + +### Patch Changes + +- Updated dependencies + - @0xsequence/core@1.10.0 + - @0xsequence/network@1.10.0 + +## 1.9.37 + +### Patch Changes + +- network: adds nativeToken data to NetworkMetadata constants +- Updated dependencies + - @0xsequence/network@1.9.37 + +## 1.9.36 + +### Patch Changes + +- guard: export client +- Updated dependencies + - @0xsequence/network@1.9.36 + +## 1.9.35 + +### Patch Changes + +- guard: update bindings +- Updated dependencies + - @0xsequence/network@1.9.35 + +## 1.9.34 + +### Patch Changes + +- waas: always use lowercase email +- Updated dependencies + - @0xsequence/network@1.9.34 + +## 1.9.33 + +### Patch Changes + +- waas: umd build +- Updated dependencies + - @0xsequence/network@1.9.33 + +## 1.9.32 + +### Patch Changes + +- indexer: update bindings +- Updated dependencies + - @0xsequence/network@1.9.32 + +## 1.9.31 + +### Patch Changes + +- metadata: token directory changes +- Updated dependencies + - @0xsequence/network@1.9.31 + +## 1.9.30 + +### Patch Changes + +- update +- Updated dependencies + - @0xsequence/network@1.9.30 + +## 1.9.29 + +### Patch Changes + +- disable gnosis chain +- Updated dependencies + - @0xsequence/network@1.9.29 + +## 1.9.28 + +### Patch Changes + +- add utils/merkletree +- Updated dependencies + - @0xsequence/network@1.9.28 + +## 1.9.27 + +### Patch Changes + +- network: optimistic -> optimism +- waas: remove defaults +- api, sessions: update bindings +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/network@1.9.27 + +## 1.9.26 + +### Patch Changes + +- - add backend interfaces for pluggable interfaces + - introduce @0xsequence/react-native + - update pnpm to lockfile v9 +- Updated dependencies + - @0xsequence/network@1.9.26 + +## 1.9.25 + +### Patch Changes + +- update webrpc clients with new error types +- Updated dependencies + - @0xsequence/network@1.9.25 + +## 1.9.24 + +### Patch Changes + +- waas: add memoryStore backend to localStore +- Updated dependencies + - @0xsequence/network@1.9.24 + +## 1.9.23 + +### Patch Changes + +- update api client bindings +- Updated dependencies + - @0xsequence/network@1.9.23 + +## 1.9.22 + +### Patch Changes + +- update metadata client bindings +- Updated dependencies + - @0xsequence/network@1.9.22 + +## 1.9.21 + +### Patch Changes + +- api client bindings +- Updated dependencies + - @0xsequence/network@1.9.21 + +## 1.9.20 + +### Patch Changes + +- api client bindings update +- Updated dependencies + - @0xsequence/network@1.9.20 + +## 1.9.19 + +### Patch Changes + +- waas update +- Updated dependencies + - @0xsequence/network@1.9.19 + +## 1.9.18 + +### Patch Changes + +- provider: prohibit dangerous functions +- Updated dependencies + - @0xsequence/network@1.9.18 + +## 1.9.17 + +### Patch Changes + +- network: add xr-sepolia +- Updated dependencies + - @0xsequence/network@1.9.17 + +## 1.9.16 + +### Patch Changes + +- waas: sequence.feeOptions +- Updated dependencies + - @0xsequence/network@1.9.16 + +## 1.9.15 + +### Patch Changes + +- metadata: collection external_link field name fix +- Updated dependencies + - @0xsequence/network@1.9.15 + +## 1.9.14 + +### Patch Changes + +- network: astar-zkatana -> astar-zkyoto +- network: deprecate polygon mumbai network +- network: add xai and polygon amoy +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/network@1.9.14 + +## 1.9.13 + +### Patch Changes + +- waas: fix @0xsequence/network dependency +- Updated dependencies + - @0xsequence/network@1.9.13 + +## 1.9.12 + +### Patch Changes + +- indexer: update rpc bindings +- provider: signMessage: Serialize the BytesLike or string message into hexstring before sending +- waas: SessionAuthProof +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/network@1.9.12 + +## 1.9.11 + +### Patch Changes + +- metdata, update rpc bindings +- Updated dependencies + - @0xsequence/network@1.9.11 + +## 1.9.10 + +### Patch Changes + +- update metadata rpc bindings +- Updated dependencies + - @0xsequence/network@1.9.10 + +## 1.9.9 + +### Patch Changes + +- metadata, add SequenceCollections rpc client +- Updated dependencies + - @0xsequence/network@1.9.9 + +## 1.9.8 + +### Patch Changes + +- waas client update +- Updated dependencies + - @0xsequence/network@1.9.8 + +## 1.9.7 + +### Patch Changes + +- update rpc client bindings for api, metadata and relayer +- Updated dependencies + - @0xsequence/network@1.9.7 + +## 1.9.6 + +### Patch Changes + +- waas package update +- Updated dependencies + - @0xsequence/network@1.9.6 + +## 1.9.5 + +### Patch Changes + +- RpcRelayer prioritize project access key +- Updated dependencies + - @0xsequence/network@1.9.5 + +## 1.9.4 + +### Patch Changes + +- waas: fix network dependency +- Updated dependencies + - @0xsequence/network@1.9.4 + +## 1.9.3 + +### Patch Changes + +- provider: don't append access key to RPC url if user has already provided it +- Updated dependencies + - @0xsequence/network@1.9.3 + +## 1.9.2 + +### Patch Changes + +- network: add xai-sepolia +- Updated dependencies + - @0xsequence/network@1.9.2 + +## 1.9.1 + +### Patch Changes + +- analytics fix +- Updated dependencies + - @0xsequence/network@1.9.1 + +## 1.9.0 + +### Minor Changes + +- waas release + +### Patch Changes + +- Updated dependencies + - @0xsequence/network@1.9.0 + +## 0.0.0-20231129192642 + +### Minor Changes + +- WaaS Ethers signer wrapper + +## 0.0.0-20230922164806 + +### Minor Changes + +- WaaS initial implementatino diff --git a/packages/waas/README.md b/packages/waas/README.md new file mode 100644 index 0000000000..2811b84f96 --- /dev/null +++ b/packages/waas/README.md @@ -0,0 +1,4 @@ +@0xsequence/waas +================= + +See [0xsequence project page](https://github.com/0xsequence/sequence.js). diff --git a/packages/waas/package.json b/packages/waas/package.json new file mode 100644 index 0000000000..4eb1b08c4c --- /dev/null +++ b/packages/waas/package.json @@ -0,0 +1,39 @@ +{ + "name": "@0xsequence/waas", + "version": "2.0.0", + "description": "waas session client", + "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/waas", + "source": "src/index.ts", + "main": "dist/0xsequence-waas.cjs.js", + "module": "dist/0xsequence-waas.esm.js", + "umd:main": "dist/0xsequence-waas.umd.min.js", + "author": "Horizon Blockchain Games", + "license": "Apache-2.0", + "scripts": { + "test": "pnpm test:file tests/**/*.spec.ts", + "test:file": "NODE_OPTIONS='--import tsx' mocha --timeout 30000", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@0xsequence/core": "workspace:*", + "@0xsequence/network": "workspace:*", + "@aws-sdk/client-cognito-identity-provider": "^3.445.0", + "idb": "^7.1.1", + "json-canonicalize": "^1.0.6", + "jwt-decode": "^4.0.0" + }, + "files": [ + "src", + "dist" + ], + "peerDependencies": { + "ethers": ">=5.5" + }, + "devDependencies": { + "@types/jwt-decode": "^3.1.0", + "fake-indexeddb": "^4.0.1" + }, + "preconstruct": { + "umdName": "sequence-waas" + } +} diff --git a/packages/waas/src/auth.ts b/packages/waas/src/auth.ts new file mode 100644 index 0000000000..1a5136c089 --- /dev/null +++ b/packages/waas/src/auth.ts @@ -0,0 +1,712 @@ +import { Observer, SequenceWaaSBase } from './base' +import { + Account, + IdentityType, + IntentDataOpenSession, + IntentDataSendTransaction, + IntentResponseIdToken +} from './clients/intent.gen' +import { newSessionFromSessionId } from './session' +import { LocalStore, Store, StoreObj } from './store' +import { + GetTransactionReceiptArgs, + SendDelayedEncodeArgs, + SendERC1155Args, + SendERC20Args, + SendERC721Args, + SendTransactionsArgs, + SignedIntent, + SignMessageArgs +} from './intents' +import { + FeeOptionsResponse, + isCloseSessionResponse, + isFeeOptionsResponse, + isFinishValidateSessionResponse, + isGetIdTokenResponse, + isGetSessionResponse, + isInitiateAuthResponse, + isIntentTimeError, + isLinkAccountResponse, + isListAccountsResponse, + isMaySentTransactionResponse, + isSessionAuthProofResponse, + isSignedMessageResponse, + isTimedOutTransactionResponse, + isValidationRequiredResponse, + MaySentTransactionResponse, + SignedMessageResponse +} from './intents/responses' +import { WaasAuthenticator, AnswerIncorrectError, Chain, EmailAlreadyInUseError, Session } from './clients/authenticator.gen' +import { SimpleNetwork, WithSimpleNetwork } from './networks' +import { EmailAuth } from './email' +import { ethers } from 'ethers' +import { getDefaultSubtleCryptoBackend, SubtleCryptoBackend } from './subtle-crypto' +import { getDefaultSecureStoreBackend, SecureStoreBackend } from './secure-store' +import { Challenge, EmailChallenge, GuestChallenge, IdTokenChallenge, PlayFabChallenge, StytchChallenge } from './challenge' +import { jwtDecode } from 'jwt-decode' + +export type Sessions = (Session & { isThis: boolean })[] +export type { Account } +export { IdentityType } + +export type SequenceConfig = { + projectAccessKey: string + waasConfigKey: string + network?: SimpleNetwork +} + +export type ExtendedSequenceConfig = { + rpcServer: string + emailRegion?: string +} + +export type WaaSConfigKey = { + projectId: number + emailClientId?: string +} + +export type GuestIdentity = { guest: true } +export type IdTokenIdentity = { idToken: string } +export type EmailIdentity = { email: string } +export type PlayFabIdentity = { + playFabTitleId: string + playFabSessionTicket: string +} + +export type Identity = IdTokenIdentity | EmailIdentity | PlayFabIdentity | GuestIdentity + +export type SignInResponse = { + sessionId: string + wallet: string + email?: string +} + +function encodeHex(data: string | Uint8Array) { + return ( + '0x' + + Array.from(typeof data === 'string' ? new TextEncoder().encode(data) : data, byte => byte.toString(16).padStart(2, '0')).join( + '' + ) + ) +} + +function decodeHex(hex: string) { + return new Uint8Array( + hex + .substring(2) + .match(/.{1,2}/g)! + .map(byte => parseInt(byte, 16)) + ) +} + +export type ValidationArgs = { + onValidationRequired?: () => boolean +} + +export type CommonAuthArgs = { + validation?: ValidationArgs + identifier?: string +} + +export type Network = Chain + +export type NetworkList = Network[] + +export type EmailConflictInfo = { + type: IdentityType + email: string + issuer: string +} + +export function parseSequenceWaaSConfigKey(key: string): Partial { + return JSON.parse(atob(key)) +} + +export function defaultArgsOrFail( + config: SequenceConfig & Partial +): Required & Required & ExtendedSequenceConfig { + const key = (config as any).waasConfigKey + const keyOverrides = key ? parseSequenceWaaSConfigKey(key) : {} + const preconfig = { ...config, ...keyOverrides } + + if (preconfig.network === undefined) { + preconfig.network = 1 + } + + if (preconfig.projectId === undefined) { + throw new Error('Missing project id') + } + + if (preconfig.projectAccessKey === undefined) { + throw new Error('Missing access key') + } + + return preconfig as Required & Required & ExtendedSequenceConfig +} + +export class SequenceWaaS { + private waas: SequenceWaaSBase + private client: WaasAuthenticator + + private validationRequiredCallback: (() => void)[] = [] + private emailConflictCallback: ((info: EmailConflictInfo, forceCreate: () => Promise) => Promise)[] = [] + private emailAuthCodeRequiredCallback: ((respondWithCode: (code: string) => Promise) => Promise)[] = [] + private validationRequiredSalt: string + + public readonly config: Required & Required & ExtendedSequenceConfig + + private readonly deviceName: StoreObj + + private emailClient: EmailAuth | undefined + + // The last Date header value returned by the server, used for users with desynchronised clocks + private lastDate: Date | undefined + + constructor( + config: SequenceConfig & Partial, + private readonly store: Store = new LocalStore(), + private readonly cryptoBackend: SubtleCryptoBackend | null = getDefaultSubtleCryptoBackend(), + private readonly secureStoreBackend: SecureStoreBackend | null = getDefaultSecureStoreBackend() + ) { + this.config = defaultArgsOrFail(config) + this.waas = new SequenceWaaSBase({ network: 1, ...config }, this.store, this.cryptoBackend, this.secureStoreBackend) + this.client = new WaasAuthenticator(this.config.rpcServer, this.fetch.bind(this)) + this.deviceName = new StoreObj(this.store, '@0xsequence.waas.auth.deviceName', undefined) + } + + public get email() { + if (this.emailClient) { + return this.emailClient + } + + if (!this.config.emailRegion) { + throw new Error('Missing emailRegion') + } + + if (!this.config.emailClientId) { + throw new Error('Missing emailClientId') + } + + this.emailClient = new EmailAuth(this.config.emailRegion, this.config.emailClientId) + return this.emailClient + } + + async onValidationRequired(callback: () => void) { + this.validationRequiredCallback.push(callback) + return () => { + this.validationRequiredCallback = this.validationRequiredCallback.filter(c => c !== callback) + } + } + + onEmailConflict(callback: (info: EmailConflictInfo, forceCreate: () => Promise) => Promise) { + this.emailConflictCallback.push(callback) + return () => { + this.emailConflictCallback = this.emailConflictCallback.filter(c => c !== callback) + } + } + + onEmailAuthCodeRequired(callback: (respondWithCode: (code: string) => Promise) => Promise) { + this.emailAuthCodeRequiredCallback.push(callback) + return () => { + this.emailAuthCodeRequiredCallback = this.emailAuthCodeRequiredCallback.filter(c => c !== callback) + } + } + + private async handleValidationRequired({ onValidationRequired }: ValidationArgs = {}): Promise { + const proceed = onValidationRequired ? onValidationRequired() : true + if (!proceed) { + return false + } + + const intent = await this.waas.validateSession({ + deviceMetadata: (await this.deviceName.get()) ?? 'Unknown device' + }) + + const sendIntent = await this.sendIntent(intent) + this.validationRequiredSalt = sendIntent.data.salt + + for (const callback of this.validationRequiredCallback) { + callback() + } + + return this.waitForSessionValid() + } + + private headers() { + return { + 'X-Access-Key': this.config.projectAccessKey + } + } + + private async sendIntent(intent: SignedIntent) { + const sessionId = await this.waas.getSessionId() + if (!sessionId) { + throw new Error('session not open') + } + + try { + const res = await this.client.sendIntent({ intent: intent }, this.headers()) + return res.response + } catch (e) { + if (isIntentTimeError(e) && this.lastDate) { + const newIntent = await this.waas.updateIntentTime(intent, this.lastDate) + const res = await this.client.sendIntent({ intent: newIntent }, this.headers()) + return res.response + } + throw e + } + } + + async isSignedIn() { + return this.waas.isSignedIn() + } + + signIn(creds: Identity, sessionName: string): Promise { + const isEmailAuth = 'email' in creds + if (isEmailAuth && this.emailAuthCodeRequiredCallback.length == 0) { + return Promise.reject('Missing emailAuthCodeRequired callback') + } + + return new Promise(async (resolve, reject) => { + const challenge = await this.initAuth(creds) + + const respondToChallenge = async (answer: string) => { + try { + const res = await this.completeAuth(challenge.withAnswer(answer), { sessionName }) + resolve(res) + } catch (e) { + if (e instanceof AnswerIncorrectError) { + // This will NOT resolve NOR reject the top-level promise returned from signIn, it'll keep being pending + // It allows the caller to retry calling the respondToChallenge callback + throw e + } else if (e instanceof EmailAlreadyInUseError) { + const forceCreate = async () => { + try { + const res = await this.completeAuth(challenge.withAnswer(answer), { sessionName, forceCreateAccount: true }) + resolve(res) + } catch (e) { + reject(e) + } + } + const info: EmailConflictInfo = { + type: IdentityType.None, + email: '', + issuer: '' + } + if (e.cause) { + const parts = e.cause.split('|') + if (parts.length >= 2) { + info.type = parts[0] as IdentityType + info.email = parts[1] + } + if (parts.length >= 3) { + info.issuer = parts[2] + } + } + for (const callback of this.emailConflictCallback) { + callback(info, forceCreate) + } + } else { + reject(e) + } + } + } + + if (isEmailAuth) { + for (const callback of this.emailAuthCodeRequiredCallback) { + callback(respondToChallenge) + } + } else { + respondToChallenge('') + } + }) + } + + async initAuth(identity: Identity): Promise { + if ('guest' in identity && identity.guest) { + return this.initGuestAuth() + } else if ('idToken' in identity) { + return this.initIdTokenAuth(identity.idToken) + } else if ('email' in identity) { + return this.initEmailAuth(identity.email) + } else if ('playFabTitleId' in identity) { + return this.initPlayFabAuth(identity.playFabTitleId, identity.playFabSessionTicket) + } + + throw new Error('invalid identity') + } + + private async initGuestAuth() { + const sessionId = await this.waas.getSessionId() + const intent = await this.waas.initiateGuestAuth() + const res = await this.sendIntent(intent) + + if (!isInitiateAuthResponse(res)) { + throw new Error(`Invalid response: ${JSON.stringify(res)}`) + } + return new GuestChallenge(sessionId, res.data.challenge!) + } + + private async initIdTokenAuth(idToken: string) { + const decoded = jwtDecode(idToken) + const isStytch = decoded.iss?.startsWith('stytch.com/') || false + const intent = isStytch + ? await this.waas.initiateStytchAuth(idToken, decoded.exp) + : await this.waas.initiateIdTokenAuth(idToken, decoded.exp) + const res = await this.sendIntent(intent) + + if (!isInitiateAuthResponse(res)) { + throw new Error(`Invalid response: ${JSON.stringify(res)}`) + } + return isStytch ? new StytchChallenge(idToken) : new IdTokenChallenge(idToken) + } + + private async initEmailAuth(email: string) { + const sessionId = await this.waas.getSessionId() + const intent = await this.waas.initiateEmailAuth(email) + const res = await this.sendIntent(intent) + + if (!isInitiateAuthResponse(res)) { + throw new Error(`Invalid response: ${JSON.stringify(res)}`) + } + return new EmailChallenge(email, sessionId, res.data.challenge!) + } + + private async initPlayFabAuth(titleId: string, sessionTicket: string) { + const intent = await this.waas.initiatePlayFabAuth(titleId, sessionTicket) + const res = await this.sendIntent(intent) + + if (!isInitiateAuthResponse(res)) { + throw new Error(`Invalid response: ${JSON.stringify(res)}`) + } + return new PlayFabChallenge(titleId, sessionTicket) + } + + async completeAuth( + challenge: Challenge, + opts?: { sessionName?: string; forceCreateAccount?: boolean } + ): Promise { + if (!opts) { + opts = {} + } + if (!opts.sessionName) { + opts.sessionName = 'session name' + } + + const intent = await this.waas.completeAuth(challenge.getIntentParams(), { forceCreateAccount: opts.forceCreateAccount }) + try { + const res = await this.registerSession(intent, opts.sessionName) + + await this.waas.completeSignIn({ + code: 'sessionOpened', + data: { + sessionId: res.session.id, + wallet: res.response.data.wallet + } + }) + + return { + sessionId: res.session.id, + wallet: res.response.data.wallet, + email: res.session.identity.email + } + } catch (e) { + if (!(e instanceof EmailAlreadyInUseError) && !(e instanceof AnswerIncorrectError)) { + await this.waas.completeSignOut() + } + throw e + } + } + + async registerSession(intent: SignedIntent, name: string) { + try { + const res = await this.client.registerSession({ intent, friendlyName: name }, this.headers()) + return res + } catch (e) { + if (isIntentTimeError(e) && this.lastDate) { + const newIntent = await this.waas.updateIntentTime(intent, this.lastDate) + return await this.client.registerSession({ intent: newIntent, friendlyName: name }, this.headers()) + } + throw e + } + } + + private async refreshSession() { + throw new Error('Not implemented') + } + + async getSessionId() { + return this.waas.getSessionId() + } + + async getSessionHash() { + const sessionId = (await this.waas.getSessionId()).toLowerCase() + return ethers.utils.keccak256(ethers.utils.toUtf8Bytes(sessionId)) + } + + async dropSession({ sessionId, strict }: { sessionId?: string; strict?: boolean } = {}) { + const thisSessionId = await this.waas.getSessionId() + if (!thisSessionId) { + throw new Error('session not open') + } + + const closeSessionId = sessionId || thisSessionId + + try { + const intent = await this.waas.signOutSession(closeSessionId) + const result = await this.sendIntent(intent) + + if (!isCloseSessionResponse(result)) { + throw new Error(`Invalid response: ${JSON.stringify(result)}`) + } + } catch (e) { + if (strict) { + throw e + } + + console.error(e) + } + + if (closeSessionId === thisSessionId) { + if (!this.secureStoreBackend) { + throw new Error('No secure store available') + } + + const session = await newSessionFromSessionId(thisSessionId, this.cryptoBackend, this.secureStoreBackend) + session.clear() + await this.waas.completeSignOut() + await this.deviceName.set(undefined) + } + } + + async listSessions(): Promise { + const sessionId = await this.waas.getSessionId() + if (!sessionId) { + throw new Error('session not open') + } + + const intent = await this.waas.listSessions() + const res = await this.sendIntent(intent) + + return (res.data as Session[]).map(session => ({ + ...session, + isThis: session.id === sessionId + })) + } + + // WaaS specific methods + async getAddress() { + return this.waas.getAddress() + } + + async validateSession(args?: ValidationArgs) { + if (await this.isSessionValid()) { + return true + } + + return this.handleValidationRequired(args) + } + + async finishValidateSession(challenge: string): Promise { + const intent = await this.waas.finishValidateSession(this.validationRequiredSalt, challenge) + const result = await this.sendIntent(intent) + + if (!isFinishValidateSessionResponse(result)) { + throw new Error(`Invalid response: ${JSON.stringify(result)}`) + } + + this.validationRequiredSalt = '' + return result.data.isValid + } + + async isSessionValid(): Promise { + const intent = await this.waas.getSession() + const result = await this.sendIntent(intent) + + if (!isGetSessionResponse(result)) { + throw new Error(`Invalid response: ${JSON.stringify(result)}`) + } + + return result.data.validated + } + + async waitForSessionValid(timeout: number = 600000, pollRate: number = 2000) { + const start = Date.now() + + while (Date.now() - start < timeout) { + if (await this.isSessionValid()) { + return true + } + + await new Promise(resolve => setTimeout(resolve, pollRate)) + } + + return false + } + + async sessionAuthProof({ nonce, network, validation }: { nonce?: string; network?: string; validation?: ValidationArgs }) { + const intent = await this.waas.sessionAuthProof({ nonce, network }) + return await this.trySendIntent({ validation }, intent, isSessionAuthProofResponse) + } + + async listAccounts() { + const intent = await this.waas.listAccounts() + const res = await this.sendIntent(intent) + + if (!isListAccountsResponse(res)) { + throw new Error(`Invalid response: ${JSON.stringify(res)}`) + } + + return res.data + } + + async linkAccount(challenge: Challenge) { + const intent = await this.waas.linkAccount(challenge.getIntentParams()) + const res = await this.sendIntent(intent) + + if (!isLinkAccountResponse(res)) { + throw new Error(`Invalid response: ${JSON.stringify(res)}`) + } + + return res.data + } + + async removeAccount(accountId: string) { + const intent = await this.waas.removeAccount({ accountId }) + await this.sendIntent(intent) + } + + async getIdToken(args?: { nonce?: string }): Promise { + const intent = await this.waas.getIdToken({ nonce: args?.nonce }) + const res = await this.sendIntent(intent) + + if (!isGetIdTokenResponse(res)) { + throw new Error(`Invalid response: ${JSON.stringify(res)}`) + } + + return res.data + } + + async useIdentifier(args: T): Promise { + if (args.identifier) { + return args as T & { identifier: string } + } + + // Generate a new identifier + const identifier = `ts-sdk-${Date.now()}-${await this.waas.getSessionId()}` + return { ...args, identifier } as T & { identifier: string } + } + + private async trySendIntent( + args: CommonAuthArgs, + intent: SignedIntent, + isExpectedResponse: (response: any) => response is T + ): Promise { + const response = await this.sendIntent(intent) + + if (isExpectedResponse(response)) { + return response + } + + if (isValidationRequiredResponse(response)) { + const proceed = await this.handleValidationRequired(args.validation) + + if (proceed) { + const response2 = await this.sendIntent(intent) + if (isExpectedResponse(response2)) { + return response2 + } + } + } + + throw new Error(JSON.stringify(response)) + } + + async signMessage(args: WithSimpleNetwork & CommonAuthArgs): Promise { + const intent = await this.waas.signMessage(await this.useIdentifier(args)) + return this.trySendIntent(args, intent, isSignedMessageResponse) + } + + private async trySendTransactionIntent( + intent: SignedIntent, + args: CommonAuthArgs + ): Promise { + let result = await this.trySendIntent(args, intent, isMaySentTransactionResponse) + + while (isTimedOutTransactionResponse(result)) { + await new Promise(resolve => setTimeout(resolve, 1000)) + + const receiptArgs: WithSimpleNetwork & CommonAuthArgs = { + metaTxHash: result.data.metaTxHash, + network: intent.data.network, + identifier: intent.data.identifier, + validation: args.validation + } + const receiptIntent = await this.waas.getTransactionReceipt(await this.useIdentifier(receiptArgs)) + result = await this.trySendIntent(receiptArgs, receiptIntent, isMaySentTransactionResponse) + } + + return result + } + + async sendTransaction(args: WithSimpleNetwork & CommonAuthArgs): Promise { + const intent = await this.waas.sendTransaction(await this.useIdentifier(args)) + return this.trySendTransactionIntent(intent, args) + } + + async sendERC20(args: WithSimpleNetwork & CommonAuthArgs): Promise { + const intent = await this.waas.sendERC20(await this.useIdentifier(args)) + return this.trySendTransactionIntent(intent, args) + } + + async sendERC721(args: WithSimpleNetwork & CommonAuthArgs): Promise { + const intent = await this.waas.sendERC721(await this.useIdentifier(args)) + return this.trySendTransactionIntent(intent, args) + } + + async sendERC1155(args: WithSimpleNetwork & CommonAuthArgs): Promise { + const intent = await this.waas.sendERC1155(await this.useIdentifier(args)) + return this.trySendTransactionIntent(intent, args) + } + + async callContract(args: WithSimpleNetwork & CommonAuthArgs): Promise { + const intent = await this.waas.callContract(await this.useIdentifier(args)) + return this.trySendTransactionIntent(intent, args) + } + + async feeOptions(args: WithSimpleNetwork & CommonAuthArgs): Promise { + const intent = await this.waas.feeOptions(await this.useIdentifier(args)) + return this.trySendIntent(args, intent, isFeeOptionsResponse) + } + + async networkList(): Promise { + const networks: NetworkList = [] + const chainList = await this.client.chainList({ + 'X-Access-Key': this.config.projectAccessKey + }) + + for (const chain of chainList.chains) { + networks.push({ + id: chain.id, + name: chain.name, + isEnabled: chain.isEnabled + }) + } + return networks + } + + onSessionStateChanged(callback: Observer) { + return this.waas.onSessionStateChanged(callback) + } + + // Special version of fetch that keeps track of the last seen Date header + async fetch(input: RequestInfo, init?: RequestInit) { + const res = await window.fetch(input, init) + const headerValue = res.headers.get('date') + if (headerValue) { + this.lastDate = new Date(headerValue) + } + return res + } +} diff --git a/packages/waas/src/base.ts b/packages/waas/src/base.ts new file mode 100644 index 0000000000..de6fa21398 --- /dev/null +++ b/packages/waas/src/base.ts @@ -0,0 +1,605 @@ +import { + changeIntentTime, + closeSession, + combineTransactionIntents, + feeOptions, + finishValidateSession, + getIdToken, + getSession, + getTransactionReceipt, + GetTransactionReceiptArgs, + initiateAuth, + Intent, + listSessions, + openSession, + OpenSessionArgs, + sendDelayedEncode, + SendDelayedEncodeArgs, + sendERC1155, + SendERC1155Args, + sendERC20, + SendERC20Args, + sendERC721, + SendERC721Args, + sendTransactions, + SendTransactionsArgs, + sessionAuthProof, + SignedIntent, + signIntent, + signMessage, + SignMessageArgs, + validateSession +} from './intents' +import { LocalStore, Store, StoreObj } from './store' +import { newSession, newSessionFromSessionId } from './session' +import { OpenSessionResponse } from './intents/responses' +import { federateAccount, listAccounts, removeAccount } from './intents/accounts' +import { SimpleNetwork, toNetworkID, WithSimpleNetwork } from './networks' +import { + IdentityType, + IntentDataFederateAccount, + IntentDataFeeOptions, + IntentDataFinishValidateSession, + IntentDataGetSession, + IntentDataGetTransactionReceipt, + IntentDataInitiateAuth, + IntentDataListAccounts, + IntentDataOpenSession, + IntentDataSendTransaction, + IntentDataSignMessage, + IntentDataValidateSession +} from './clients/intent.gen' +import { getDefaultSubtleCryptoBackend, SubtleCryptoBackend } from './subtle-crypto' +import { getDefaultSecureStoreBackend, SecureStoreBackend } from './secure-store' +import { ethers } from 'ethers' +import { ChallengeIntentParams } from './challenge' + +type Status = 'pending' | 'signed-in' | 'signed-out' + +const SEQUENCE_WAAS_WALLET_KEY = '@0xsequence.waas.wallet' +const SEQUENCE_WAAS_SESSION_ID_KEY = '@0xsequence.waas.session_id' +const SEQUENCE_WAAS_STATUS_KEY = '@0xsequence.waas.status' + +// 5 minutes of default lifespan +const DEFAULT_LIFESPAN = 5 * 60 + +export type SessionAuthProofArgs = { + nonce?: string +} + +export type ExtraArgs = { + lifespan?: number +} + +export type ExtraTransactionArgs = ExtraArgs & { + identifier: string +} + +export type SequenceBaseConfig = { + network: SimpleNetwork +} + +export type Observer = (value: T | null) => any + +export class SequenceWaaSBase { + private readonly status: StoreObj + private readonly sessionId: StoreObj + private readonly wallet: StoreObj + + private sessionObservers: Observer[] = [] + + constructor( + public readonly config = { network: 1 } as SequenceBaseConfig, + private readonly store: Store = new LocalStore(), + private readonly cryptoBackend: SubtleCryptoBackend | null = getDefaultSubtleCryptoBackend(), + private readonly secureStoreBackend: SecureStoreBackend | null = getDefaultSecureStoreBackend() + ) { + this.status = new StoreObj(this.store, SEQUENCE_WAAS_STATUS_KEY, 'signed-out') + this.sessionId = new StoreObj(this.store, SEQUENCE_WAAS_SESSION_ID_KEY, undefined) + this.wallet = new StoreObj(this.store, SEQUENCE_WAAS_WALLET_KEY, undefined) + } + + async getAddress() { + return this.getWalletAddress() + } + + private async getWalletAddress() { + if (!(await this.isSignedIn())) { + throw new Error('Not signed in') + } + + const wallet = await this.wallet.get() + if (!wallet) { + throw new Error('No wallet') + } + + return wallet + } + + private async commonArgs( + args: T & { + identifier: string + lifespan?: number + network?: SimpleNetwork + } + ): Promise< + T & { + identifier: string + wallet: string + lifespan: number + chainId: number + } + > { + return { + ...args, + identifier: args?.identifier, + wallet: await this.getWalletAddress(), + lifespan: args?.lifespan ?? DEFAULT_LIFESPAN, + chainId: toNetworkID(args.network || this.config.network) + } + } + + /** + * Builds a payload that can be sent to the WaaS API to sign a transaction. + * It automatically signs the payload, and attaches the current wallet address. + * + * @param packet The action already packed into a packet + * @returns A payload that can be sent to the WaaS API + */ + private async signIntent(intent: Intent): Promise> { + const sessionId = await this.getSessionId() + if (sessionId === undefined) { + throw new Error('session not open') + } + + const session = await newSessionFromSessionId(sessionId, this.cryptoBackend, this.secureStoreBackend) + return signIntent(session, intent) + } + + public async signUsingSessionKey(message: string | Uint8Array) { + const sessionId = await this.getSessionId() + if (!sessionId) { + throw new Error('session not open') + } + + const signer = await newSessionFromSessionId(sessionId, this.cryptoBackend, this.secureStoreBackend) + return signer.sign(message) + } + + private gettingSessionIdPromise: Promise | undefined + + /** + * This method will return session id. + * + * @returns an id of the session + */ + public async getSessionId(): Promise { + if (this.gettingSessionIdPromise) { + return this.gettingSessionIdPromise + } + + const promiseGenerator = async () => { + let sessionId = await this.sessionId.get() + if (!sessionId) { + const session = await newSession(this.cryptoBackend, this.secureStoreBackend) + sessionId = await session.sessionId() + await this.sessionId.set(sessionId) + this.signalObservers(this.sessionObservers, sessionId) + } + this.gettingSessionIdPromise = undefined + return sessionId + } + + this.gettingSessionIdPromise = promiseGenerator() + return this.gettingSessionIdPromise + } + + /** + * This method will initiate a sign-in process with the waas API. It must be performed + * when the user wants to sign in to the app, in parallel with the authentication of the + * application's own authentication system. + * + * This method begins the sign-in process, but does not complete it. The returned payload + * must be sent to the waas API to complete the sign-in. The waas API will return a receipt + * that must be sent to the `completeSignIn` method to complete the sign-in. + * + * @param idToken Information about the user that can be used to prove their identity + * @returns a session payload that **must** be sent to the waas API to complete the sign-in + * @throws {Error} If the session is already signed in or there is a pending sign-in + */ + async signInWithIdToken(idToken: string): Promise> { + const status = await this.status.get() + if (status !== 'signed-out') { + await this.completeSignOut() + throw new Error('you are already signed in') // TODO change this awful msg + } + + const sessionId = await this.getSessionId() + const intent = await openSession({ + sessionId, + identityType: IdentityType.None, + idToken, + lifespan: DEFAULT_LIFESPAN + }) + + await this.status.set('pending') + + return this.signIntent(intent) + } + + async initiateGuestAuth(): Promise> { + const sessionId = await this.getSessionId() + const intent = await initiateAuth({ + sessionId, + identityType: IdentityType.Guest, + verifier: sessionId, + lifespan: DEFAULT_LIFESPAN + }) + + return this.signIntent(intent) + } + + async initiateEmailAuth(email: string): Promise> { + const sessionId = await this.getSessionId() + const intent = await initiateAuth({ + sessionId, + identityType: IdentityType.Email, + verifier: `${email};${sessionId}`, + lifespan: DEFAULT_LIFESPAN + }) + + return this.signIntent(intent) + } + + async initiateIdTokenAuth(idToken: string, exp?: number): Promise> { + const sessionId = await this.getSessionId() + const idTokenHash = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(idToken)) + const intent = await initiateAuth({ + sessionId, + identityType: IdentityType.OIDC, + verifier: `${idTokenHash};${exp}`, + lifespan: DEFAULT_LIFESPAN + }) + + return this.signIntent(intent) + } + + async initiateStytchAuth(idToken: string, exp?: number): Promise> { + const sessionId = await this.getSessionId() + const idTokenHash = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(idToken)) + const intent = await initiateAuth({ + sessionId, + identityType: IdentityType.Stytch, + verifier: `${idTokenHash};${exp}`, + lifespan: DEFAULT_LIFESPAN + }) + + return this.signIntent(intent) + } + + async initiatePlayFabAuth(titleId: string, sessionTicket: string): Promise> { + const sessionId = await this.getSessionId() + const ticketHash = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(sessionTicket)) + const intent = await initiateAuth({ + sessionId, + identityType: IdentityType.PlayFab, + verifier: `${titleId}|${ticketHash}`, + lifespan: DEFAULT_LIFESPAN + }) + + return this.signIntent(intent) + } + + async completeAuth(params: ChallengeIntentParams, optParams: Partial) { + const sessionId = await this.getSessionId() + const intent = await openSession({ + ...optParams, + sessionId, + lifespan: DEFAULT_LIFESPAN, + ...params + }) + + await this.status.set('pending') + + return this.signIntent(intent) + } + + onSessionStateChanged(callback: Observer): () => void { + this.sessionObservers.push(callback) + return () => { + this.sessionObservers = this.sessionObservers.filter(o => o != callback) + } + } + + async signOut({ lifespan, sessionId }: { sessionId?: string } & ExtraArgs = {}) { + sessionId = sessionId || (await this.sessionId.get()) + if (!sessionId) { + throw new Error('session not open') + } + + const intent = closeSession({ + lifespan: lifespan || DEFAULT_LIFESPAN, + sessionId: sessionId + }) + + return this.signIntent(intent) + } + + async signOutSession(sessionId: string) { + const intent = closeSession({ + lifespan: DEFAULT_LIFESPAN, + sessionId: sessionId + }) + + return this.signIntent(intent) + } + + async listSessions() { + const intent = listSessions({ + lifespan: DEFAULT_LIFESPAN, + wallet: await this.getWalletAddress() + }) + + return this.signIntent(intent) + } + + async completeSignOut() { + await Promise.all([this.status.set('signed-out'), this.wallet.set(undefined), this.sessionId.set(undefined)]) + this.signalObservers(this.sessionObservers, null) + } + + /** + * This method will complete a sign-in process with the waas API. It must be performed + * after the `signIn` method, when the waas API has returned a receipt. + * + * This method completes the sign-in process by validating the receipt's proof. + * If the proof is invalid or there is no pending sign-in, it will throw an error. + * + * After this method is called, the wallet is ready to be used to sign transactions. + * + * @param receipt The receipt returned by the waas API after the `signIn` method + * @returns The wallet address of the user that signed in + * @throws {Error} If there is no pending sign-in or the receipt is invalid + */ + async completeSignIn(receipt: OpenSessionResponse): Promise { + if ((receipt as any).result) { + return this.completeSignIn((receipt as any).result) + } + + const status = await this.status.get() + + if (receipt.code !== 'sessionOpened') { + throw new Error('Invalid receipt') + } + + if (status !== 'pending') { + throw new Error('No pending sign in') + } + + await Promise.all([this.status.set('signed-in'), this.wallet.set(receipt.data.wallet)]) + + return receipt.data.wallet + } + + async isSignedIn() { + const status = await this.status.get() + return status === 'signed-in' + } + + async sessionAuthProof(args: WithSimpleNetwork & ExtraArgs) { + const packet = sessionAuthProof({ + lifespan: args.lifespan ?? DEFAULT_LIFESPAN, + network: toNetworkID(args.network || this.config.network).toString(), + wallet: await this.getWalletAddress(), + nonce: args.nonce + }) + return this.signIntent(packet) + } + + // + // Signer methods + // + + /** + * This method can be used to sign message using waas API. It can only be used + * after successfully signing in with the `signIn` and `completeSignIn` methods. + * + * The method does not sign the message. It only returns a payload + * that must be sent to the waas API to complete the sign process. + * + * @param chainId The network on which the message will be signed + * @param message The message that will be signed + * @return a payload that must be sent to the waas API to complete sign process + */ + async signMessage(args: WithSimpleNetwork & ExtraArgs): Promise> { + const packet = signMessage({ + chainId: toNetworkID(args.network || this.config.network), + ...args, + lifespan: args.lifespan ?? DEFAULT_LIFESPAN, + wallet: await this.getWalletAddress() + }) + + return this.signIntent(packet) + } + + /** + * This method can be used to send transactions to the waas API. It can only be used + * after successfully signing in with the `signIn` and `completeSignIn` methods. + * + * The method does not send the transactions to the network. It only returns a payload + * that must be sent to the waas API to complete the transaction. + * + * @param transactions The transactions to be sent + * @param chainId The network on which the transactions will be sent + * @returns a payload that must be sent to the waas API to complete the transaction + */ + async sendTransaction( + args: WithSimpleNetwork & ExtraTransactionArgs + ): Promise> { + const intent = sendTransactions(await this.commonArgs(args)) + return this.signIntent(intent) + } + + async getTransactionReceipt( + args: WithSimpleNetwork & ExtraTransactionArgs + ): Promise> { + const intent = getTransactionReceipt(await this.commonArgs(args)) + return this.signIntent(intent) + } + + async sendERC20( + args: WithSimpleNetwork & ExtraTransactionArgs + ): Promise> { + if (args.token.toLowerCase() === args.to.toLowerCase()) { + throw new Error('Cannot burn tokens using sendERC20') + } + + const intent = sendERC20(await this.commonArgs(args)) + return this.signIntent(intent) + } + + async sendERC721( + args: WithSimpleNetwork & ExtraTransactionArgs + ): Promise> { + if (args.token.toLowerCase() === args.to.toLowerCase()) { + throw new Error('Cannot burn tokens using sendERC721') + } + + const intent = sendERC721(await this.commonArgs(args)) + return this.signIntent(intent) + } + + async sendERC1155( + args: WithSimpleNetwork & ExtraTransactionArgs + ): Promise> { + if (args.token.toLowerCase() === args.to.toLowerCase()) { + throw new Error('Cannot burn tokens using sendERC1155') + } + + const intent = sendERC1155(await this.commonArgs(args)) + return this.signIntent(intent) + } + + async callContract( + args: WithSimpleNetwork & ExtraTransactionArgs + ): Promise> { + const intent = sendDelayedEncode(await this.commonArgs(args)) + return this.signIntent(intent) + } + + async feeOptions( + args: WithSimpleNetwork & ExtraTransactionArgs + ): Promise> { + const intent = feeOptions(await this.commonArgs(args)) + return this.signIntent(intent) + } + + async validateSession({ deviceMetadata }: { deviceMetadata: string }): Promise> { + const sessionId = await this.sessionId.get() + if (!sessionId) { + throw new Error('session not open') + } + + const intent = await validateSession({ + lifespan: DEFAULT_LIFESPAN, + sessionId: sessionId, + deviceMetadata, + wallet: await this.getWalletAddress() + }) + + return this.signIntent(intent) + } + + async getSession(): Promise> { + const sessionId = await this.sessionId.get() + if (!sessionId) { + throw new Error('session not open') + } + + const intent = getSession({ + sessionId, + wallet: await this.getWalletAddress(), + lifespan: DEFAULT_LIFESPAN + }) + + return this.signIntent(intent) + } + + async finishValidateSession(salt: string, challenge: string): Promise> { + const sessionId = await this.sessionId.get() + if (!sessionId) { + throw new Error('session not open') + } + + const wallet = await this.getWalletAddress() + const intent = finishValidateSession({ + sessionId, + wallet, + lifespan: DEFAULT_LIFESPAN, + salt, + challenge + }) + return this.signIntent(intent) + } + + async listAccounts(): Promise> { + const intent = listAccounts({ + wallet: await this.getWalletAddress(), + lifespan: DEFAULT_LIFESPAN + }) + return this.signIntent(intent) + } + + async linkAccount(params: ChallengeIntentParams): Promise> { + const sessionId = await this.sessionId.get() + if (!sessionId) { + throw new Error('session not open') + } + + const intent = federateAccount({ + wallet: await this.getWalletAddress(), + lifespan: DEFAULT_LIFESPAN, + sessionId, + ...params + }) + return this.signIntent(intent) + } + + async removeAccount({ accountId }: { accountId: string }) { + const intent = removeAccount({ + wallet: await this.getWalletAddress(), + lifespan: DEFAULT_LIFESPAN, + accountId + }) + return this.signIntent(intent) + } + + async getIdToken({ nonce }: { nonce?: string }) { + const sessionId = await this.sessionId.get() + if (!sessionId) { + throw new Error('session not open') + } + + const intent = getIdToken({ + wallet: await this.getWalletAddress(), + lifespan: DEFAULT_LIFESPAN, + sessionId, + nonce + }) + return this.signIntent(intent) + } + + async batch(intents: Intent[]): Promise> { + const combined = combineTransactionIntents(intents) + return this.signIntent(combined) + } + + private signalObservers(observers: Observer[], value: T | null) { + observers.forEach(observer => observer(value)) + } + + async updateIntentTime(intent: SignedIntent, time: Date): Promise> { + const newIntent = changeIntentTime(intent, time) + return this.signIntent(newIntent) + } +} diff --git a/packages/waas/src/challenge.ts b/packages/waas/src/challenge.ts new file mode 100644 index 0000000000..9effd946fe --- /dev/null +++ b/packages/waas/src/challenge.ts @@ -0,0 +1,121 @@ +import { IdentityType } from './clients/intent.gen' +import { ethers } from 'ethers' +import { jwtDecode } from 'jwt-decode' + +export interface ChallengeIntentParams { + identityType: IdentityType + verifier: string + answer?: string +} + +export abstract class Challenge { + public abstract getIntentParams(): ChallengeIntentParams + public abstract withAnswer(answer: string): Challenge +} + +export class GuestChallenge extends Challenge { + constructor( + readonly sessionId: string, + readonly challenge: string + ) { + super() + } + + getIntentParams(): ChallengeIntentParams { + const answer = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(this.challenge + this.sessionId)) + return { + identityType: IdentityType.Guest, + verifier: this.sessionId, + answer + } + } + + withAnswer(answer: string): Challenge { + return this + } +} + +export class EmailChallenge extends Challenge { + private hashedAnswer?: string + + constructor( + readonly email: string, + readonly sessionId: string, + readonly challenge: string + ) { + super() + } + + getIntentParams(): ChallengeIntentParams { + return { + identityType: IdentityType.Email, + verifier: `${this.email};${this.sessionId}`, + answer: this.hashedAnswer + } + } + + setAnswer(answer: string): void { + this.hashedAnswer = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(this.challenge + answer)) + } + + withAnswer(answer: string) { + const challenge = new EmailChallenge(this.email, this.sessionId, this.challenge) + challenge.setAnswer(answer) + return challenge + } +} + +export class IdTokenChallenge extends Challenge { + constructor(readonly idToken: string) { + super() + } + + getIntentParams(): ChallengeIntentParams { + const decoded = jwtDecode(this.idToken) + const idTokenHash = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(this.idToken)) + return { + identityType: IdentityType.OIDC, + verifier: `${idTokenHash};${decoded.exp}`, + answer: this.idToken + } + } + + withAnswer() { + return this + } +} + +export class StytchChallenge extends IdTokenChallenge { + constructor(readonly idToken: string) { + super(idToken) + } + + getIntentParams(): ChallengeIntentParams { + return { + ...super.getIntentParams(), + identityType: IdentityType.Stytch + } + } +} + +export class PlayFabChallenge extends Challenge { + constructor( + readonly titleId: string, + readonly sessionTicket: string + ) { + super() + } + + getIntentParams(): ChallengeIntentParams { + const ticketHash = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(this.sessionTicket)) + return { + identityType: IdentityType.PlayFab, + verifier: `${this.titleId}|${ticketHash}`, + answer: this.sessionTicket + } + } + + withAnswer() { + return this + } +} diff --git a/packages/waas/src/clients/authenticator.gen.ts b/packages/waas/src/clients/authenticator.gen.ts new file mode 100644 index 0000000000..fa192f6651 --- /dev/null +++ b/packages/waas/src/clients/authenticator.gen.ts @@ -0,0 +1,823 @@ +/* eslint-disable */ +// sequence-waas-authenticator v0.1.0 35f86317a98af91896d1114ad52dd22102d9de9f +// -- +// Code generated by webrpc-gen@v0.18.8 with typescript generator. DO NOT EDIT. +// +// webrpc-gen -schema=authenticator.ridl -target=typescript -client -out=./clients/authenticator.gen.ts + +// WebRPC description and code-gen version +export const WebRPCVersion = 'v1' + +// Schema version of your RIDL schema +export const WebRPCSchemaVersion = 'v0.1.0' + +// Schema hash generated from your RIDL schema +export const WebRPCSchemaHash = '35f86317a98af91896d1114ad52dd22102d9de9f' + +// +// Types +// + +export enum IntentName { + initiateAuth = 'initiateAuth', + openSession = 'openSession', + closeSession = 'closeSession', + validateSession = 'validateSession', + finishValidateSession = 'finishValidateSession', + listSessions = 'listSessions', + getSession = 'getSession', + sessionAuthProof = 'sessionAuthProof', + feeOptions = 'feeOptions', + signMessage = 'signMessage', + sendTransaction = 'sendTransaction', + getTransactionReceipt = 'getTransactionReceipt', + federateAccount = 'federateAccount', + removeAccount = 'removeAccount', + listAccounts = 'listAccounts', + getIdToken = 'getIdToken' +} + +export enum IntentResponseCode { + authInitiated = 'authInitiated', + sessionOpened = 'sessionOpened', + sessionClosed = 'sessionClosed', + sessionList = 'sessionList', + validationRequired = 'validationRequired', + validationStarted = 'validationStarted', + validationFinished = 'validationFinished', + sessionAuthProof = 'sessionAuthProof', + signedMessage = 'signedMessage', + feeOptions = 'feeOptions', + transactionReceipt = 'transactionReceipt', + transactionFailed = 'transactionFailed', + getSessionResponse = 'getSessionResponse', + accountList = 'accountList', + accountFederated = 'accountFederated', + accountRemoved = 'accountRemoved', + idToken = 'idToken' +} + +export enum IdentityType { + None = 'None', + Guest = 'Guest', + OIDC = 'OIDC', + Email = 'Email', + PlayFab = 'PlayFab', + Stytch = 'Stytch' +} + +export interface Intent { + version: string + name: IntentName + expiresAt: number + issuedAt: number + data: any + signatures: Array +} + +export interface Signature { + sessionId: string + signature: string +} + +export interface IntentResponse { + code: IntentResponseCode + data: any +} + +export interface Version { + webrpcVersion: string + schemaVersion: string + schemaHash: string + appVersion: string +} + +export interface RuntimeStatus { + healthOK: boolean + startTime: string + uptime: number + ver: string + pcr0: string +} + +export interface Chain { + id: number + name: string + isEnabled: boolean +} + +export interface Identity { + type: IdentityType + iss: string + sub: string + email: string +} + +export interface OpenIdProvider { + iss: string + aud: Array +} + +export interface AuthEmailConfig { + enabled: boolean +} + +export interface AuthGuestConfig { + enabled: boolean +} + +export interface AuthPlayfabConfig { + enabled: boolean + titleId?: string +} + +export interface AuthStytchConfig { + enabled: boolean + projectId?: string +} + +export interface AuthConfig { + email?: AuthEmailConfig + guest?: AuthGuestConfig + playfab?: AuthPlayfabConfig + stytch?: AuthStytchConfig +} + +export interface Tenant { + projectId: number + version: number + oidcProviders: Array + allowedOrigins: Array + authConfig: AuthConfig + updatedAt: string +} + +export interface TenantData { + projectId: number + privateKey: string + parentAddress: string + userSalt: string + sequenceContext: MiniSequenceContext + upgradeCode: string + waasAccessToken: string + authConfig: AuthConfig + oidcProviders: Array + kmsKeys: Array + allowedOrigins: Array +} + +export interface MiniSequenceContext { + factory: string + mainModule: string +} + +export interface AccountData { + projectId: number + userId: string + identity: string + createdAt: string +} + +export interface Session { + id: string + projectId: number + userId: string + identity: Identity + friendlyName: string + createdAt: string + refreshedAt: string + expiresAt: string +} + +export interface SessionData { + id: string + projectId: number + userId: string + identity: string + createdAt: string + expiresAt: string +} + +export interface VerificationContext { + projectId: number + sessionId: string + identityType: IdentityType + verifier: string + challenge?: string + answer?: string + attempts: number + lastAttemptAt?: string + expiresAt: string +} + +export interface WaasAuthenticator { + registerSession(args: RegisterSessionArgs, headers?: object, signal?: AbortSignal): Promise + sendIntent(args: SendIntentArgs, headers?: object, signal?: AbortSignal): Promise + chainList(headers?: object, signal?: AbortSignal): Promise +} + +export interface RegisterSessionArgs { + intent: Intent + friendlyName: string +} + +export interface RegisterSessionReturn { + session: Session + response: IntentResponse +} +export interface SendIntentArgs { + intent: Intent +} + +export interface SendIntentReturn { + response: IntentResponse +} +export interface ChainListArgs {} + +export interface ChainListReturn { + chains: Array +} + +export interface WaasAuthenticatorAdmin { + version(headers?: object, signal?: AbortSignal): Promise + runtimeStatus(headers?: object, signal?: AbortSignal): Promise + clock(headers?: object, signal?: AbortSignal): Promise + getTenant(args: GetTenantArgs, headers?: object, signal?: AbortSignal): Promise + createTenant(args: CreateTenantArgs, headers?: object, signal?: AbortSignal): Promise + updateTenant(args: UpdateTenantArgs, headers?: object, signal?: AbortSignal): Promise +} + +export interface VersionArgs {} + +export interface VersionReturn { + version: Version +} +export interface RuntimeStatusArgs {} + +export interface RuntimeStatusReturn { + status: RuntimeStatus +} +export interface ClockArgs {} + +export interface ClockReturn { + serverTime: string +} +export interface GetTenantArgs { + projectId: number +} + +export interface GetTenantReturn { + tenant: Tenant +} +export interface CreateTenantArgs { + projectId: number + waasAccessToken: string + authConfig: AuthConfig + oidcProviders: Array + allowedOrigins: Array + password?: string +} + +export interface CreateTenantReturn { + tenant: Tenant + upgradeCode: string +} +export interface UpdateTenantArgs { + projectId: number + upgradeCode: string + authConfig: AuthConfig + oidcProviders: Array + allowedOrigins: Array +} + +export interface UpdateTenantReturn { + tenant: Tenant +} + +// +// Client +// +export class WaasAuthenticator implements WaasAuthenticator { + protected hostname: string + protected fetch: Fetch + protected path = '/rpc/WaasAuthenticator/' + + constructor(hostname: string, fetch: Fetch) { + this.hostname = hostname + this.fetch = (input: RequestInfo, init?: RequestInit) => fetch(input, init) + } + + private url(name: string): string { + return this.hostname + this.path + name + } + + registerSession = (args: RegisterSessionArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('RegisterSession'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + session: _data.session, + response: _data.response + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + sendIntent = (args: SendIntentArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('SendIntent'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + response: _data.response + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + chainList = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('ChainList'), createHTTPRequest({}, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + chains: >_data.chains + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } +} +export class WaasAuthenticatorAdmin implements WaasAuthenticatorAdmin { + protected hostname: string + protected fetch: Fetch + protected path = '/rpc/WaasAuthenticatorAdmin/' + + constructor(hostname: string, fetch: Fetch) { + this.hostname = hostname + this.fetch = (input: RequestInfo, init?: RequestInit) => fetch(input, init) + } + + private url(name: string): string { + return this.hostname + this.path + name + } + + version = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('Version'), createHTTPRequest({}, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + version: _data.version + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + runtimeStatus = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('RuntimeStatus'), createHTTPRequest({}, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + status: _data.status + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + clock = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('Clock'), createHTTPRequest({}, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + serverTime: _data.serverTime + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + getTenant = (args: GetTenantArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetTenant'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + tenant: _data.tenant + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + createTenant = (args: CreateTenantArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('CreateTenant'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + tenant: _data.tenant, + upgradeCode: _data.upgradeCode + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } + + updateTenant = (args: UpdateTenantArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('UpdateTenant'), createHTTPRequest(args, headers, signal)).then( + res => { + return buildResponse(res).then(_data => { + return { + tenant: _data.tenant + } + }) + }, + error => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + } + ) + } +} + +const createHTTPRequest = (body: object = {}, headers: object = {}, signal: AbortSignal | null = null): object => { + return { + method: 'POST', + headers: { ...headers, 'Content-Type': 'application/json' }, + body: JSON.stringify(body || {}), + signal + } +} + +const buildResponse = (res: Response): Promise => { + return res.text().then(text => { + let data + try { + data = JSON.parse(text) + } catch (error) { + let message = '' + if (error instanceof Error) { + message = error.message + } + throw WebrpcBadResponseError.new({ + status: res.status, + cause: `JSON.parse(): ${message}: response text: ${text}` + }) + } + if (!res.ok) { + const code: number = typeof data.code === 'number' ? data.code : 0 + throw (webrpcErrorByCode[code] || WebrpcError).new(data) + } + return data + }) +} + +// +// Errors +// + +export class WebrpcError extends Error { + name: string + code: number + message: string + status: number + cause?: string + + /** @deprecated Use message instead of msg. Deprecated in webrpc v0.11.0. */ + msg: string + + constructor(name: string, code: number, message: string, status: number, cause?: string) { + super(message) + this.name = name || 'WebrpcError' + this.code = typeof code === 'number' ? code : 0 + this.message = message || `endpoint error ${this.code}` + this.msg = this.message + this.status = typeof status === 'number' ? status : 0 + this.cause = cause + Object.setPrototypeOf(this, WebrpcError.prototype) + } + + static new(payload: any): WebrpcError { + return new this(payload.error, payload.code, payload.message || payload.msg, payload.status, payload.cause) + } +} + +// Webrpc errors + +export class WebrpcEndpointError extends WebrpcError { + constructor( + name: string = 'WebrpcEndpoint', + code: number = 0, + message: string = 'endpoint error', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcEndpointError.prototype) + } +} + +export class WebrpcRequestFailedError extends WebrpcError { + constructor( + name: string = 'WebrpcRequestFailed', + code: number = -1, + message: string = 'request failed', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcRequestFailedError.prototype) + } +} + +export class WebrpcBadRouteError extends WebrpcError { + constructor( + name: string = 'WebrpcBadRoute', + code: number = -2, + message: string = 'bad route', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadRouteError.prototype) + } +} + +export class WebrpcBadMethodError extends WebrpcError { + constructor( + name: string = 'WebrpcBadMethod', + code: number = -3, + message: string = 'bad method', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadMethodError.prototype) + } +} + +export class WebrpcBadRequestError extends WebrpcError { + constructor( + name: string = 'WebrpcBadRequest', + code: number = -4, + message: string = 'bad request', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadRequestError.prototype) + } +} + +export class WebrpcBadResponseError extends WebrpcError { + constructor( + name: string = 'WebrpcBadResponse', + code: number = -5, + message: string = 'bad response', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadResponseError.prototype) + } +} + +export class WebrpcServerPanicError extends WebrpcError { + constructor( + name: string = 'WebrpcServerPanic', + code: number = -6, + message: string = 'server panic', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcServerPanicError.prototype) + } +} + +export class WebrpcInternalErrorError extends WebrpcError { + constructor( + name: string = 'WebrpcInternalError', + code: number = -7, + message: string = 'internal error', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcInternalErrorError.prototype) + } +} + +export class WebrpcClientDisconnectedError extends WebrpcError { + constructor( + name: string = 'WebrpcClientDisconnected', + code: number = -8, + message: string = 'client disconnected', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcClientDisconnectedError.prototype) + } +} + +export class WebrpcStreamLostError extends WebrpcError { + constructor( + name: string = 'WebrpcStreamLost', + code: number = -9, + message: string = 'stream lost', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcStreamLostError.prototype) + } +} + +export class WebrpcStreamFinishedError extends WebrpcError { + constructor( + name: string = 'WebrpcStreamFinished', + code: number = -10, + message: string = 'stream finished', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcStreamFinishedError.prototype) + } +} + +// Schema errors + +export class UnauthorizedError extends WebrpcError { + constructor( + name: string = 'Unauthorized', + code: number = 1000, + message: string = 'Unauthorized access', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, UnauthorizedError.prototype) + } +} + +export class TenantNotFoundError extends WebrpcError { + constructor( + name: string = 'TenantNotFound', + code: number = 1001, + message: string = 'Tenant not found', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, TenantNotFoundError.prototype) + } +} + +export class EmailAlreadyInUseError extends WebrpcError { + constructor( + name: string = 'EmailAlreadyInUse', + code: number = 7000, + message: string = 'Could not create account as the email is already in use', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, EmailAlreadyInUseError.prototype) + } +} + +export class AccountAlreadyLinkedError extends WebrpcError { + constructor( + name: string = 'AccountAlreadyLinked', + code: number = 7001, + message: string = 'Could not link account as it is linked to another wallet', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, AccountAlreadyLinkedError.prototype) + } +} + +export class ProofVerificationFailedError extends WebrpcError { + constructor( + name: string = 'ProofVerificationFailed', + code: number = 7002, + message: string = 'The authentication proof could not be verified', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, ProofVerificationFailedError.prototype) + } +} + +export class AnswerIncorrectError extends WebrpcError { + constructor( + name: string = 'AnswerIncorrect', + code: number = 7003, + message: string = 'The provided answer is incorrect', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, AnswerIncorrectError.prototype) + } +} + +export class ChallengeExpiredError extends WebrpcError { + constructor( + name: string = 'ChallengeExpired', + code: number = 7004, + message: string = 'The challenge has expired', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, ChallengeExpiredError.prototype) + } +} + +export class TooManyAttemptsError extends WebrpcError { + constructor( + name: string = 'TooManyAttempts', + code: number = 7005, + message: string = 'Too many attempts', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, TooManyAttemptsError.prototype) + } +} + +export enum errors { + WebrpcEndpoint = 'WebrpcEndpoint', + WebrpcRequestFailed = 'WebrpcRequestFailed', + WebrpcBadRoute = 'WebrpcBadRoute', + WebrpcBadMethod = 'WebrpcBadMethod', + WebrpcBadRequest = 'WebrpcBadRequest', + WebrpcBadResponse = 'WebrpcBadResponse', + WebrpcServerPanic = 'WebrpcServerPanic', + WebrpcInternalError = 'WebrpcInternalError', + WebrpcClientDisconnected = 'WebrpcClientDisconnected', + WebrpcStreamLost = 'WebrpcStreamLost', + WebrpcStreamFinished = 'WebrpcStreamFinished', + Unauthorized = 'Unauthorized', + TenantNotFound = 'TenantNotFound', + EmailAlreadyInUse = 'EmailAlreadyInUse', + AccountAlreadyLinked = 'AccountAlreadyLinked', + ProofVerificationFailed = 'ProofVerificationFailed', + AnswerIncorrect = 'AnswerIncorrect', + ChallengeExpired = 'ChallengeExpired', + TooManyAttempts = 'TooManyAttempts' +} + +const webrpcErrorByCode: { [code: number]: any } = { + [0]: WebrpcEndpointError, + [-1]: WebrpcRequestFailedError, + [-2]: WebrpcBadRouteError, + [-3]: WebrpcBadMethodError, + [-4]: WebrpcBadRequestError, + [-5]: WebrpcBadResponseError, + [-6]: WebrpcServerPanicError, + [-7]: WebrpcInternalErrorError, + [-8]: WebrpcClientDisconnectedError, + [-9]: WebrpcStreamLostError, + [-10]: WebrpcStreamFinishedError, + [1000]: UnauthorizedError, + [1001]: TenantNotFoundError, + [7000]: EmailAlreadyInUseError, + [7001]: AccountAlreadyLinkedError, + [7002]: ProofVerificationFailedError, + [7003]: AnswerIncorrectError, + [7004]: ChallengeExpiredError, + [7005]: TooManyAttemptsError +} + +export type Fetch = (input: RequestInfo, init?: RequestInit) => Promise diff --git a/packages/waas/src/clients/intent.gen.ts b/packages/waas/src/clients/intent.gen.ts new file mode 100644 index 0000000000..bb8189be9b --- /dev/null +++ b/packages/waas/src/clients/intent.gen.ts @@ -0,0 +1,593 @@ +/* eslint-disable */ +// sequence-waas-intents v0.1.0 1fe0a24abef81231c54c0886157c65ef738d5ed6 +// -- +// Code generated by webrpc-gen@v0.19.3 with typescript generator. DO NOT EDIT. +// +// webrpc-gen -schema=intent.ridl -target=typescript -client -out=./intent.gen.ts + +// WebRPC description and code-gen version +export const WebRPCVersion = 'v1' + +// Schema version of your RIDL schema +export const WebRPCSchemaVersion = 'v0.1.0' + +// Schema hash generated from your RIDL schema +export const WebRPCSchemaHash = '1fe0a24abef81231c54c0886157c65ef738d5ed6' + +// +// Types +// + +export enum IntentName { + initiateAuth = 'initiateAuth', + openSession = 'openSession', + closeSession = 'closeSession', + validateSession = 'validateSession', + finishValidateSession = 'finishValidateSession', + listSessions = 'listSessions', + getSession = 'getSession', + sessionAuthProof = 'sessionAuthProof', + feeOptions = 'feeOptions', + signMessage = 'signMessage', + sendTransaction = 'sendTransaction', + getTransactionReceipt = 'getTransactionReceipt', + federateAccount = 'federateAccount', + removeAccount = 'removeAccount', + listAccounts = 'listAccounts', + getIdToken = 'getIdToken' +} + +export enum TransactionType { + transaction = 'transaction', + erc20send = 'erc20send', + erc721send = 'erc721send', + erc1155send = 'erc1155send', + delayedEncode = 'delayedEncode' +} + +export enum IntentResponseCode { + authInitiated = 'authInitiated', + sessionOpened = 'sessionOpened', + sessionClosed = 'sessionClosed', + sessionList = 'sessionList', + validationRequired = 'validationRequired', + validationStarted = 'validationStarted', + validationFinished = 'validationFinished', + sessionAuthProof = 'sessionAuthProof', + signedMessage = 'signedMessage', + feeOptions = 'feeOptions', + transactionReceipt = 'transactionReceipt', + transactionFailed = 'transactionFailed', + getSessionResponse = 'getSessionResponse', + accountList = 'accountList', + accountFederated = 'accountFederated', + accountRemoved = 'accountRemoved', + idToken = 'idToken' +} + +export enum FeeTokenType { + unknown = 'unknown', + erc20Token = 'erc20Token', + erc1155Token = 'erc1155Token' +} + +export enum IdentityType { + None = 'None', + Guest = 'Guest', + OIDC = 'OIDC', + Email = 'Email', + PlayFab = 'PlayFab', + Stytch = 'Stytch' +} + +export interface Intent { + version: string + name: IntentName + expiresAt: number + issuedAt: number + data: any + signatures: Array +} + +export interface Signature { + sessionId: string + signature: string +} + +export interface IntentDataInitiateAuth { + sessionId: string + identityType: IdentityType + verifier: string + metadata?: string +} + +export interface IntentDataOpenSession { + sessionId: string + identityType: IdentityType + verifier?: string + answer?: string + forceCreateAccount?: boolean + email?: string + idToken?: string +} + +export interface IntentDataCloseSession { + sessionId: string +} + +export interface IntentDataValidateSession { + sessionId: string + wallet: string + deviceMetadata: string +} + +export interface IntentDataFinishValidateSession { + sessionId: string + wallet: string + salt: string + challenge: string +} + +export interface IntentDataListSessions { + wallet: string +} + +export interface IntentDataGetSession { + sessionId: string + wallet: string +} + +export interface IntentDataSessionAuthProof { + network: string + wallet: string + nonce?: string +} + +export interface IntentDataSignMessage { + network: string + wallet: string + message: string +} + +export interface IntentDataFeeOptions { + network: string + wallet: string + identifier: string + transactions: Array +} + +export interface IntentDataSendTransaction { + network: string + wallet: string + identifier: string + transactions: Array + transactionsFeeQuote?: string +} + +export interface IntentDataGetTransactionReceipt { + network: string + wallet: string + metaTxHash: string +} + +export interface IntentDataFederateAccount { + sessionId: string + wallet: string + identityType: IdentityType + verifier?: string + answer?: string +} + +export interface IntentDataListAccounts { + wallet: string +} + +export interface IntentDataRemoveAccount { + wallet: string + accountId: string +} + +export interface IntentDataGetIdToken { + sessionId: string + wallet: string + nonce?: string +} + +export interface TransactionRaw { + type: string + to: string + value: string + data: string +} + +export interface TransactionERC20 { + type: string + tokenAddress: string + to: string + value: string +} + +export interface TransactionERC721 { + type: string + tokenAddress: string + to: string + id: string + safe?: boolean + data?: string +} + +export interface TransactionERC1155Value { + id: string + amount: string +} + +export interface TransactionDelayedEncode { + type: string + to: string + value: string + data: any +} + +export interface TransactionERC1155 { + type: string + tokenAddress: string + to: string + vals: Array + data?: string +} + +export interface IntentResponse { + code: IntentResponseCode + data: any +} + +export interface IntentResponseAuthInitiated { + sessionId: string + identityType: IdentityType + expiresIn: number + challenge?: string +} + +export interface IntentResponseSessionOpened { + sessionId: string + wallet: string +} + +export interface IntentResponseSessionClosed {} + +export interface IntentResponseValidateSession {} + +export interface IntentResponseValidationRequired { + sessionId: string +} + +export interface IntentResponseValidationStarted { + salt: string +} + +export interface IntentResponseValidationFinished { + isValid: boolean +} + +export interface IntentResponseListSessions { + sessions: Array +} + +export interface IntentResponseGetSession { + sessionId: string + wallet: string + validated: boolean +} + +export interface IntentResponseSessionAuthProof { + sessionId: string + network: string + wallet: string + message: string + signature: string +} + +export interface IntentResponseSignedMessage { + signature: string + message: string +} + +export interface FeeOption { + token: FeeToken + to: string + value: string + gasLimit: number +} + +export interface FeeToken { + chainId: number + name: string + symbol: string + type: FeeTokenType + decimals?: number + logoURL: string + contractAddress?: string + tokenID?: string +} + +export interface IntentResponseFeeOptions { + feeOptions: Array + feeQuote?: string +} + +export interface IntentResponseTransactionReceipt { + request: any + txHash: string + metaTxHash: string + receipt: any + nativeReceipt: any + simulations: any +} + +export interface IntentResponseTransactionFailed { + error: string + request: any + simulations: any +} + +export interface IntentResponseAccountList { + accounts: Array + currentAccountId: string +} + +export interface IntentResponseAccountFederated { + account: Account +} + +export interface IntentResponseAccountRemoved {} + +export interface IntentResponseIdToken { + idToken: string + expiresIn: number +} + +export interface Account { + id: string + type: IdentityType + issuer?: string + email?: string +} + +const createHTTPRequest = (body: object = {}, headers: object = {}, signal: AbortSignal | null = null): object => { + return { + method: 'POST', + headers: { ...headers, 'Content-Type': 'application/json' }, + body: JSON.stringify(body || {}), + signal + } +} + +const buildResponse = (res: Response): Promise => { + return res.text().then(text => { + let data + try { + data = JSON.parse(text) + } catch (error) { + let message = '' + if (error instanceof Error) { + message = error.message + } + throw WebrpcBadResponseError.new({ + status: res.status, + cause: `JSON.parse(): ${message}: response text: ${text}` + }) + } + if (!res.ok) { + const code: number = typeof data.code === 'number' ? data.code : 0 + throw (webrpcErrorByCode[code] || WebrpcError).new(data) + } + return data + }) +} + +// +// Errors +// + +export class WebrpcError extends Error { + name: string + code: number + message: string + status: number + cause?: string + + /** @deprecated Use message instead of msg. Deprecated in webrpc v0.11.0. */ + msg: string + + constructor(name: string, code: number, message: string, status: number, cause?: string) { + super(message) + this.name = name || 'WebrpcError' + this.code = typeof code === 'number' ? code : 0 + this.message = message || `endpoint error ${this.code}` + this.msg = this.message + this.status = typeof status === 'number' ? status : 0 + this.cause = cause + Object.setPrototypeOf(this, WebrpcError.prototype) + } + + static new(payload: any): WebrpcError { + return new this(payload.error, payload.code, payload.message || payload.msg, payload.status, payload.cause) + } +} + +// Webrpc errors + +export class WebrpcEndpointError extends WebrpcError { + constructor( + name: string = 'WebrpcEndpoint', + code: number = 0, + message: string = 'endpoint error', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcEndpointError.prototype) + } +} + +export class WebrpcRequestFailedError extends WebrpcError { + constructor( + name: string = 'WebrpcRequestFailed', + code: number = -1, + message: string = 'request failed', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcRequestFailedError.prototype) + } +} + +export class WebrpcBadRouteError extends WebrpcError { + constructor( + name: string = 'WebrpcBadRoute', + code: number = -2, + message: string = 'bad route', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadRouteError.prototype) + } +} + +export class WebrpcBadMethodError extends WebrpcError { + constructor( + name: string = 'WebrpcBadMethod', + code: number = -3, + message: string = 'bad method', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadMethodError.prototype) + } +} + +export class WebrpcBadRequestError extends WebrpcError { + constructor( + name: string = 'WebrpcBadRequest', + code: number = -4, + message: string = 'bad request', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadRequestError.prototype) + } +} + +export class WebrpcBadResponseError extends WebrpcError { + constructor( + name: string = 'WebrpcBadResponse', + code: number = -5, + message: string = 'bad response', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadResponseError.prototype) + } +} + +export class WebrpcServerPanicError extends WebrpcError { + constructor( + name: string = 'WebrpcServerPanic', + code: number = -6, + message: string = 'server panic', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcServerPanicError.prototype) + } +} + +export class WebrpcInternalErrorError extends WebrpcError { + constructor( + name: string = 'WebrpcInternalError', + code: number = -7, + message: string = 'internal error', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcInternalErrorError.prototype) + } +} + +export class WebrpcClientDisconnectedError extends WebrpcError { + constructor( + name: string = 'WebrpcClientDisconnected', + code: number = -8, + message: string = 'client disconnected', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcClientDisconnectedError.prototype) + } +} + +export class WebrpcStreamLostError extends WebrpcError { + constructor( + name: string = 'WebrpcStreamLost', + code: number = -9, + message: string = 'stream lost', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcStreamLostError.prototype) + } +} + +export class WebrpcStreamFinishedError extends WebrpcError { + constructor( + name: string = 'WebrpcStreamFinished', + code: number = -10, + message: string = 'stream finished', + status: number = 0, + cause?: string + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcStreamFinishedError.prototype) + } +} + +// Schema errors + +export enum errors { + WebrpcEndpoint = 'WebrpcEndpoint', + WebrpcRequestFailed = 'WebrpcRequestFailed', + WebrpcBadRoute = 'WebrpcBadRoute', + WebrpcBadMethod = 'WebrpcBadMethod', + WebrpcBadRequest = 'WebrpcBadRequest', + WebrpcBadResponse = 'WebrpcBadResponse', + WebrpcServerPanic = 'WebrpcServerPanic', + WebrpcInternalError = 'WebrpcInternalError', + WebrpcClientDisconnected = 'WebrpcClientDisconnected', + WebrpcStreamLost = 'WebrpcStreamLost', + WebrpcStreamFinished = 'WebrpcStreamFinished' +} + +const webrpcErrorByCode: { [code: number]: any } = { + [0]: WebrpcEndpointError, + [-1]: WebrpcRequestFailedError, + [-2]: WebrpcBadRouteError, + [-3]: WebrpcBadMethodError, + [-4]: WebrpcBadRequestError, + [-5]: WebrpcBadResponseError, + [-6]: WebrpcServerPanicError, + [-7]: WebrpcInternalErrorError, + [-8]: WebrpcClientDisconnectedError, + [-9]: WebrpcStreamLostError, + [-10]: WebrpcStreamFinishedError +} + +export type Fetch = (input: RequestInfo, init?: RequestInit) => Promise diff --git a/packages/waas/src/defaults.ts b/packages/waas/src/defaults.ts new file mode 100644 index 0000000000..86cf48a778 --- /dev/null +++ b/packages/waas/src/defaults.ts @@ -0,0 +1,14 @@ +// todo: add production template +/*export const PROD = { +}*/ + +// next +export const TEST = { + rpcServer: 'https://d14tu8valot5m0.cloudfront.net', + emailRegion: 'us-east-2' +} + +export const LOCAL = { + rpcServer: 'http://localhost:9123', + emailRegion: 'us-east-2' +} diff --git a/packages/waas/src/email.ts b/packages/waas/src/email.ts new file mode 100644 index 0000000000..52d970f8d9 --- /dev/null +++ b/packages/waas/src/email.ts @@ -0,0 +1,134 @@ +import { + CognitoIdentityProviderClient, + InitiateAuthCommand, + InitiateAuthCommandOutput, + RespondToAuthChallengeCommand, + SignUpCommand, + UserLambdaValidationException +} from '@aws-sdk/client-cognito-identity-provider' + +import { IdTokenIdentity } from './auth' + +export class EmailAuth { + private cognitoMemo: CognitoIdentityProviderClient + + constructor( + public readonly region: string, + public readonly clientId: string + ) {} + + private cognito() { + if (!this.cognitoMemo) { + this.cognitoMemo = new CognitoIdentityProviderClient({ + region: this.region + }) + } + + return this.cognitoMemo + } + + private signUp(email: string) { + email = email.toLowerCase().trim() + return this.cognito().send( + new SignUpCommand({ + ClientId: this.clientId, + Username: email, + Password: 'aB1%' + getRandomString(14), + UserAttributes: [{ Name: 'email', Value: email }] + }) + ) + } + + private signIn(email: string) { + email = email.toLowerCase().trim() + return this.cognito().send( + new InitiateAuthCommand({ + AuthFlow: 'CUSTOM_AUTH', + ClientId: this.clientId, + AuthParameters: { + USERNAME: email + } + }) + ) + } + + public async initiateAuth({ email }: { email: string }): Promise<{ email: string; instance: string }> { + let res: InitiateAuthCommandOutput + email = email.toLowerCase().trim() + + try { + // Try sign in directly first + res = await this.signIn(email) + } catch (e) { + if (e instanceof UserLambdaValidationException && e.message.includes('user not found')) { + // Sign up and sign in + await this.signUp(email) + res = await this.signIn(email) + } else { + throw e + } + } + + if (!res.Session) { + throw new Error('response session is empty') + } + + return { + // Notice: rename session to instance to avoid + // confusion with the native waas session + instance: res.Session, + email: email + } + } + + public async finalizeAuth({ + instance, + email, + answer, + sessionHash + }: { + instance: string + email: string + answer: string + sessionHash: string + }): Promise { + email = email.toLowerCase().trim() + + const res = await this.cognito().send( + new RespondToAuthChallengeCommand({ + ClientId: this.clientId, + Session: instance, + ChallengeName: 'CUSTOM_CHALLENGE', + ChallengeResponses: { USERNAME: email, ANSWER: answer }, + ClientMetadata: { SESSION_HASH: sessionHash } + }) + ) + + if (!res.AuthenticationResult || !res.AuthenticationResult.IdToken) { + throw new Error('AuthenticationResult.IdToken is empty') + } + + return { idToken: res.AuthenticationResult.IdToken } + } +} + +function getRandomString(len: number) { + return Array.from(getRandomValues(len)) + .map(nr => nr.toString(16).padStart(2, '0')) + .join('') +} + +function getRandomValues(len: number) { + const randomValues = new Uint8Array(len) + if (typeof window === 'object' && typeof window.crypto === 'object') { + return window.crypto.getRandomValues(randomValues) + } else { + console.warn('window.crypto.getRandomValues is not available. Falling back to less secure Math.random().') + const randomValues = new Uint8Array(len) + for (let i = 0; i < len; i++) { + const randomInteger = Math.floor(Math.random() * 256) + randomValues[i] = randomInteger + } + return randomValues + } +} diff --git a/packages/waas/src/index.ts b/packages/waas/src/index.ts new file mode 100644 index 0000000000..dae112e9e0 --- /dev/null +++ b/packages/waas/src/index.ts @@ -0,0 +1,14 @@ +export * from './base' +export * from './auth' +export * from './challenge' + +export * as store from './store' +export * as networks from './networks' + +export type { Transaction } from './intents/transactions' +export { erc20, erc721, erc1155, delayedEncode } from './intents/transactions' + +export type { SecureStoreBackend } from './secure-store' + +export * from './intents/responses' +export * from './clients/intent.gen' diff --git a/packages/waas/src/intents/accounts.ts b/packages/waas/src/intents/accounts.ts new file mode 100644 index 0000000000..e790a877e0 --- /dev/null +++ b/packages/waas/src/intents/accounts.ts @@ -0,0 +1,24 @@ +import { Intent, makeIntent } from './base' +import { IntentDataFederateAccount, IntentDataListAccounts, IntentDataRemoveAccount, IntentName } from '../clients/intent.gen' + +interface BaseArgs { + lifespan: number +} + +export type ListAccountsArgs = BaseArgs & IntentDataListAccounts + +export function listAccounts({ lifespan, ...data }: ListAccountsArgs): Intent { + return makeIntent(IntentName.listAccounts, lifespan, data) +} + +export type FederateAccountArgs = BaseArgs & IntentDataFederateAccount + +export function federateAccount({ lifespan, ...data }: FederateAccountArgs): Intent { + return makeIntent(IntentName.federateAccount, lifespan, data) +} + +export type RemoveAccountArgs = BaseArgs & IntentDataRemoveAccount + +export function removeAccount({ lifespan, ...data }: RemoveAccountArgs): Intent { + return makeIntent(IntentName.removeAccount, lifespan, data) +} diff --git a/packages/waas/src/intents/base.ts b/packages/waas/src/intents/base.ts new file mode 100644 index 0000000000..856248e388 --- /dev/null +++ b/packages/waas/src/intents/base.ts @@ -0,0 +1,54 @@ +import { VERSION as PACKAGE_VERSION } from '@0xsequence/core' +import { Intent as RawIntent, IntentName } from '../clients/intent.gen' +import { useLifespan } from './utils' +import { ethers } from 'ethers' +import { canonicalize } from 'json-canonicalize' +import { Session } from '../session' + +export type Intent = Omit & { data: T } +export type SignedIntent = Omit & { data: T } + +const INTENTS_VERSION = 1 +const VERSION = `${INTENTS_VERSION} (Web ${PACKAGE_VERSION})` + +export function makeIntent(name: IntentName, lifespan: number, data: T): Intent { + const issuedAt = Math.floor(Date.now() / 1000) + const expiresAt = issuedAt + lifespan + return { + version: VERSION, + issuedAt, + expiresAt, + name, + data + } +} + +export async function signIntent(session: Session, intent: Intent): Promise> { + const hash = hashIntent(intent) + const signature = await session.sign(new Uint8Array(hash)) + return { + ...intent, + signatures: [ + { + sessionId: await session.sessionId(), + signature + } + ] + } +} + +export function hashIntent(intent: Intent): ethers.Bytes { + // Discard all fields other than the explicitly listed + const { version, issuedAt, expiresAt, name, data } = intent + const hashableIntent = { version, issuedAt, expiresAt, name, data } + const encoded = ethers.utils.toUtf8Bytes(canonicalize(hashableIntent)) + return ethers.utils.arrayify(ethers.utils.keccak256(encoded)) +} + +export function changeIntentTime(intent: SignedIntent, now: Date): Intent { + const { signatures, ...unsignedIntent } = intent + const lifespan = intent.expiresAt - intent.issuedAt + unsignedIntent.issuedAt = Math.floor(now.getTime() / 1000) + unsignedIntent.expiresAt = unsignedIntent.issuedAt + lifespan + return unsignedIntent +} diff --git a/packages/waas/src/intents/index.ts b/packages/waas/src/intents/index.ts new file mode 100644 index 0000000000..814a601c52 --- /dev/null +++ b/packages/waas/src/intents/index.ts @@ -0,0 +1,4 @@ +export * from './base' +export * from './messages' +export * from './session' +export * from './transactions' diff --git a/packages/waas/src/intents/messages.ts b/packages/waas/src/intents/messages.ts new file mode 100644 index 0000000000..7caca8c94b --- /dev/null +++ b/packages/waas/src/intents/messages.ts @@ -0,0 +1,21 @@ +import { ethers } from 'ethers' +import { IntentDataSignMessage, IntentName } from '../clients/intent.gen' +import { Intent, makeIntent } from './base' + +interface BaseArgs { + lifespan: number + wallet: string + chainId: number +} + +export type SignMessageArgs = { + message: string +} + +export function signMessage({ wallet, chainId, message, lifespan }: SignMessageArgs & BaseArgs): Intent { + return makeIntent(IntentName.signMessage, lifespan, { + wallet, + network: chainId.toString(), + message: message.startsWith('0x') ? message : ethers.utils.hexlify(ethers.utils.toUtf8Bytes(message)) + }) +} diff --git a/packages/waas/src/intents/responses.ts b/packages/waas/src/intents/responses.ts new file mode 100644 index 0000000000..faa72f452f --- /dev/null +++ b/packages/waas/src/intents/responses.ts @@ -0,0 +1,290 @@ +import { + FeeOption, + IntentDataSendTransaction, + IntentResponseAccountFederated, + IntentResponseAccountList, + IntentResponseAuthInitiated, + IntentResponseCode, + IntentResponseGetSession, + IntentResponseIdToken, + IntentResponseValidationFinished, + IntentResponseValidationStarted +} from '../clients/intent.gen' +import { WebrpcEndpointError, WebrpcError } from '../clients/authenticator.gen' + +export type PayloadResponse = { + code: string + data: T +} + +export type ValidationRequiredResponse = { + code: 'validationRequired' + data: { + sessionId: string + } +} + +type MetaTxnReceiptLog = { + address: string + topics: string[] + data: string +} + +type MetaTxnReceipt = { + id: string + status: string + revertReason?: string | null + index: number + logs: MetaTxnReceiptLog[] + receipts: MetaTxnReceipt[] + txnReceipt: string +} + +type SimulateResult = { + executed: boolean + succeeded: boolean + result: string | null + reason: string | null + gasUsed: number + gasLimit: number +} + +export type SentTransactionResponse = { + code: 'transactionReceipt' + data: { + txHash: string + metaTxHash: string + request: IntentDataSendTransaction + receipt: MetaTxnReceipt + nativeReceipt?: any | null + simulations?: SimulateResult[] + } +} + +export type TransactionFailedResponse = { + code: 'transactionFailed' + data: { + error: string + request: IntentDataSendTransaction + simulations: SimulateResult[] + } +} + +export type MaySentTransactionResponse = SentTransactionResponse | TransactionFailedResponse + +export type FeeOptionsResponse = { + code: 'feeOptions' + data: { + feeOptions: FeeOption[] + feeQuote?: string + } +} + +export type OpenSessionResponse = { + code: 'sessionOpened' + data: { + sessionId: string + wallet: string + } +} + +export type CloseSessionResponse = { + code: 'sessionClosed' +} + +export type ListSessionsResponse = { + code: 'listSessions' + data: { + sessions: any[] + } +} + +export type SignedMessageResponse = { + code: 'signedMessage' + data: { + message: string + signature: string + } +} + +export type SessionAuthProofResponse = { + code: 'sessionAuthProof' + data: { + sessionId: string + network: string + wallet: string + message: string + signature: string + } +} + +export interface Response { + code: Code + data: Data +} + +export type InitiateAuthResponse = Response +export type ValidateSessionResponse = Response +export type FinishValidateSessionResponse = Response +export type GetSessionResponse = Response +export type LinkAccountResponse = Response +export type ListAccountsResponse = Response +export type IdTokenResponse = Response + +export function isInitiateAuthResponse(receipt: any): receipt is InitiateAuthResponse { + return ( + typeof receipt === 'object' && + receipt.code === IntentResponseCode.authInitiated && + typeof receipt.data === 'object' && + typeof receipt.data.sessionId === 'string' && + typeof receipt.data.identityType === 'string' && + typeof receipt.data.expiresIn === 'number' + ) +} + +export function isOpenSessionResponse(receipt: any): receipt is OpenSessionResponse { + return ( + typeof receipt === 'object' && + typeof receipt.code === 'string' && + receipt.code === 'sessionOpened' && + typeof receipt.data === 'object' && + typeof receipt.data.sessionId === 'string' && + typeof receipt.data.wallet === 'string' + ) +} + +export function isSentTransactionResponse(receipt: any): receipt is SentTransactionResponse { + return ( + typeof receipt === 'object' && + typeof receipt.code === 'string' && + receipt.code === 'transactionReceipt' && + typeof receipt.data === 'object' && + typeof receipt.data.txHash === 'string' && + typeof receipt.data.receipt === 'object' && + typeof receipt.data.request === 'object' + ) +} + +export function isTimedOutTransactionResponse(receipt: any): receipt is SentTransactionResponse { + return ( + typeof receipt === 'object' && + typeof receipt.code === 'string' && + receipt.code === 'transactionReceipt' && + typeof receipt.data === 'object' && + typeof receipt.data.metaTxHash === 'string' && + !receipt.data.txHash && + typeof receipt.data.request === 'object' + ) +} + +export function isFailedTransactionResponse(receipt: any): receipt is TransactionFailedResponse { + return ( + typeof receipt === 'object' && + typeof receipt.code === 'string' && + receipt.code === 'transactionFailed' && + typeof receipt.data === 'object' && + typeof receipt.data.request === 'object' && + Array.isArray(receipt.data.simulations) && + typeof receipt.data.error === 'string' + ) +} + +export function isMaySentTransactionResponse(receipt: any): receipt is MaySentTransactionResponse { + return isSentTransactionResponse(receipt) || isFailedTransactionResponse(receipt) || isTimedOutTransactionResponse(receipt) +} + +export function isSignedMessageResponse(receipt: any): receipt is SignedMessageResponse { + return ( + typeof receipt === 'object' && + typeof receipt.code === 'string' && + receipt.code === 'signedMessage' && + typeof receipt.data === 'object' && + typeof receipt.data.message === 'string' && + typeof receipt.data.signature === 'string' + ) +} + +export function isSessionAuthProofResponse(receipt: any): receipt is SessionAuthProofResponse { + return ( + typeof receipt === 'object' && + typeof receipt.code === 'string' && + receipt.code === 'sessionAuthProof' && + typeof receipt.data === 'object' && + typeof receipt.data.sessionId === 'string' && + typeof receipt.data.network === 'string' && + typeof receipt.data.wallet === 'string' && + typeof receipt.data.message === 'string' && + typeof receipt.data.signature === 'string' + ) +} + +export function isFeeOptionsResponse(receipt: any): receipt is FeeOptionsResponse { + return ( + typeof receipt === 'object' && + typeof receipt.code === 'string' && + receipt.code === 'feeOptions' && + typeof receipt.data === 'object' && + Array.isArray(receipt.data.feeOptions) + ) +} + +export function isValidationRequiredResponse(receipt: any): receipt is ValidationRequiredResponse { + return ( + typeof receipt === 'object' && + receipt.code === IntentResponseCode.validationRequired && + typeof receipt.data === 'object' && + typeof receipt.data.sessionId === 'string' + ) +} + +export function isValidateSessionResponse(receipt: any): receipt is ValidateSessionResponse { + return typeof receipt === 'object' && receipt.code === IntentResponseCode.validationStarted && typeof receipt.data === 'object' +} + +export function isFinishValidateSessionResponse(receipt: any): receipt is FinishValidateSessionResponse { + return typeof receipt === 'object' && receipt.code === IntentResponseCode.validationFinished && typeof receipt.data === 'object' +} + +export function isCloseSessionResponse(receipt: any): receipt is CloseSessionResponse { + return typeof receipt === 'object' && typeof receipt.code === 'string' && receipt.code === 'sessionClosed' +} + +export function isGetSessionResponse(receipt: any): receipt is GetSessionResponse { + return ( + typeof receipt === 'object' && + typeof receipt.code === 'string' && + receipt.code === 'getSessionResponse' && + typeof receipt.data === 'object' && + typeof receipt.data.session === 'string' && + typeof receipt.data.wallet === 'string' + ) +} + +export function isLinkAccountResponse(receipt: any): receipt is LinkAccountResponse { + return ( + typeof receipt === 'object' && + receipt.code === IntentResponseCode.accountFederated && + typeof receipt.data === 'object' && + typeof receipt.data.account === 'object' + ) +} + +export function isListAccountsResponse(receipt: any): receipt is ListAccountsResponse { + return typeof receipt === 'object' && receipt.code === IntentResponseCode.accountList && typeof receipt.data === 'object' +} +export function isIntentTimeError(error: any): error is WebrpcEndpointError { + return !!( + error instanceof WebrpcError && + (error.cause?.endsWith('intent is invalid: intent expired') || + error.cause?.endsWith('intent is invalid: intent issued in the future')) + ) +} + +export function isGetIdTokenResponse(receipt: any): receipt is IdTokenResponse { + return ( + typeof receipt === 'object' && + receipt.code === IntentResponseCode.idToken && + typeof receipt.data === 'object' && + typeof receipt.data.idToken === 'string' + ) +} diff --git a/packages/waas/src/intents/session.ts b/packages/waas/src/intents/session.ts new file mode 100644 index 0000000000..74a1145801 --- /dev/null +++ b/packages/waas/src/intents/session.ts @@ -0,0 +1,71 @@ +import { Intent, makeIntent } from './base' +import { + IntentDataCloseSession, + IntentDataFinishValidateSession, + IntentDataGetSession, + IntentDataListSessions, + IntentDataOpenSession, + IntentDataValidateSession, + IntentDataSessionAuthProof, + IntentDataInitiateAuth, + IntentDataGetIdToken, + IntentName +} from '../clients/intent.gen' + +interface BaseArgs { + lifespan: number +} + +export type InitiateAuthArgs = BaseArgs & IntentDataInitiateAuth + +export async function initiateAuth({ lifespan, ...data }: InitiateAuthArgs): Promise> { + return makeIntent(IntentName.initiateAuth, lifespan, data) +} + +export type OpenSessionArgs = BaseArgs & IntentDataOpenSession + +export async function openSession({ lifespan, ...data }: OpenSessionArgs): Promise> { + return makeIntent(IntentName.openSession, lifespan, data) +} + +export type ValidateSessionArgs = BaseArgs & IntentDataValidateSession + +export async function validateSession({ lifespan, ...data }: ValidateSessionArgs): Promise> { + return makeIntent(IntentName.validateSession, lifespan, data) +} + +export type FinishValidateSessionArgs = BaseArgs & IntentDataFinishValidateSession + +export function finishValidateSession({ lifespan, ...data }: FinishValidateSessionArgs): Intent { + return makeIntent(IntentName.finishValidateSession, lifespan, data) +} + +export type CloseSessionArgs = BaseArgs & IntentDataCloseSession + +export function closeSession({ lifespan, ...data }: CloseSessionArgs): Intent { + return makeIntent(IntentName.closeSession, lifespan, data) +} + +export type ListSessionsArgs = BaseArgs & IntentDataListSessions + +export function listSessions({ lifespan, ...data }: ListSessionsArgs): Intent { + return makeIntent(IntentName.listSessions, lifespan, data) +} + +export type GetSessionArgs = BaseArgs & IntentDataGetSession + +export function getSession({ lifespan, ...data }: GetSessionArgs): Intent { + return makeIntent(IntentName.getSession, lifespan, data) +} + +export type SessionAuthProof = BaseArgs & IntentDataSessionAuthProof + +export function sessionAuthProof({ lifespan, ...data }: SessionAuthProof): Intent { + return makeIntent(IntentName.sessionAuthProof, lifespan, data) +} + +export type GetIdTokenArgs = BaseArgs & IntentDataGetIdToken + +export function getIdToken({ lifespan, ...data }: GetIdTokenArgs): Intent { + return makeIntent(IntentName.getIdToken, lifespan, data) +} diff --git a/packages/waas/src/intents/transactions.ts b/packages/waas/src/intents/transactions.ts new file mode 100644 index 0000000000..c341f6c0ab --- /dev/null +++ b/packages/waas/src/intents/transactions.ts @@ -0,0 +1,383 @@ +import { Intent, makeIntent } from './base' +import { + IntentDataGetTransactionReceipt, + IntentDataSendTransaction, + IntentDataFeeOptions, + TransactionDelayedEncode, + TransactionERC1155, + TransactionERC20, + TransactionERC721, + TransactionRaw, + TransactionERC1155Value, + IntentName, + FeeOption, + FeeTokenType +} from '../clients/intent.gen' +import { ethers } from 'ethers' + +interface BaseArgs { + lifespan: number + wallet: string + identifier: string + chainId: number +} + +export type TransactionFeeArgs = { + transactionsFeeQuote?: string + transactionsFeeOption?: FeeOption +} + +export type SendTransactionsArgs = TransactionFeeArgs & { + transactions: Transaction[] +} + +export type SendERC20Args = TransactionFeeArgs & { + chainId: number + token: string + to: string + value: ethers.BigNumberish +} + +export type SendERC721Args = TransactionFeeArgs & { + chainId: number + token: string + to: string + id: string + safe?: boolean + data?: string +} + +export type SendERC1155Args = TransactionFeeArgs & { + chainId: number + token: string + to: string + values: { + id: string + amount: ethers.BigNumberish + }[] + data?: string +} + +export type SendDelayedEncodeArgs = TransactionFeeArgs & { + chainId: number + to: string + value: ethers.BigNumberish + abi: string + func: string + args: string[] | { [key: string]: string } +} + +export function feeOptions({ + lifespan, + wallet, + identifier, + chainId, + transactions +}: SendTransactionsArgs & BaseArgs): Intent { + return makeIntent(IntentName.feeOptions, lifespan, { + identifier, + wallet, + network: chainId.toString(), + transactions: transactions.map(tx => { + if (!tx.to || tx.to === ethers.constants.AddressZero) { + throw new Error('Contract creation not supported') + } + + if (!isEthersTx(tx)) { + return tx + } + + return { + type: 'transaction', + to: tx.to, + value: ethers.BigNumber.from(tx.value || 0).toHexString(), + data: ethers.utils.hexlify(tx.data || []) + } + }) + }) +} + +export function sendTransactions({ + lifespan, + wallet, + identifier, + chainId, + transactions, + transactionsFeeQuote, + transactionsFeeOption +}: SendTransactionsArgs & BaseArgs): Intent { + return makeIntent(IntentName.sendTransaction, lifespan, { + identifier, + wallet, + network: chainId.toString(), + transactions: withTransactionFee(transactions, transactionsFeeOption).map(tx => { + if (!tx.to || tx.to === ethers.constants.AddressZero) { + throw new Error('Contract creation not supported') + } + + if (!isEthersTx(tx)) { + return tx + } + + return { + type: 'transaction', + to: tx.to, + value: ethers.BigNumber.from(tx.value || 0).toHexString(), + data: ethers.utils.hexlify(tx.data || []) + } + }), + transactionsFeeQuote + }) +} + +function withTransactionFee(transactions: Transaction[], feeOption?: FeeOption): Transaction[] { + const extendedTransactions = [...transactions] + if (feeOption) { + switch (feeOption.token.type) { + case FeeTokenType.unknown: + extendedTransactions.push({ + to: feeOption.to, + value: feeOption.value + }) + break + case FeeTokenType.erc20Token: + if (!feeOption.token.contractAddress) { + throw new Error('contract address is required') + } + + extendedTransactions.push( + erc20({ + tokenAddress: feeOption.token.contractAddress, + to: feeOption.to, + value: feeOption.value + }) + ) + break + case FeeTokenType.erc1155Token: + if (!feeOption.token.contractAddress) { + throw new Error('contract address is required') + } + + if (!feeOption.token.tokenID) { + throw new Error('token ID is required') + } + + extendedTransactions.push( + erc1155({ + tokenAddress: feeOption.token.contractAddress, + to: feeOption.to, + vals: [{ id: feeOption.token.tokenID, amount: feeOption.value }] + }) + ) + break + } + } + + return extendedTransactions +} + +export type GetTransactionReceiptArgs = { + metaTxHash: string +} + +export function getTransactionReceipt({ + lifespan, + chainId, + wallet, + metaTxHash +}: GetTransactionReceiptArgs & BaseArgs): Intent { + return makeIntent(IntentName.getTransactionReceipt, lifespan, { + wallet, + network: chainId.toString(), + metaTxHash + }) +} + +export function sendERC20({ token, to, value, ...args }: SendERC20Args & BaseArgs): Intent { + return sendTransactions({ + transactions: [erc20({ tokenAddress: token, to, value: value.toString() })], + ...args + }) +} + +export function sendERC721({ token, to, id, safe, data, ...args }: SendERC721Args & BaseArgs): Intent { + return sendTransactions({ + transactions: [erc721({ tokenAddress: token, to, id, data, safe })], + ...args + }) +} + +export function sendERC1155({ token, to, values, data, ...args }: SendERC1155Args & BaseArgs): Intent { + const vals = values.map(v => ({ + id: v.id, + amount: ethers.BigNumber.from(v.amount).toString() + })) + + return sendTransactions({ + transactions: [erc1155({ tokenAddress: token, to, vals, data })], + ...args + }) +} + +export function sendDelayedEncode({ + to, + value, + abi, + func, + args, + ...otherArgs +}: SendDelayedEncodeArgs & BaseArgs): Intent { + return sendTransactions({ + transactions: [ + delayedEncode({ + to, + value: ethers.BigNumber.from(value).toString(), + data: { abi, func, args } + }) + ], + ...otherArgs + }) +} + +export type Transaction = + | ethers.providers.TransactionRequest + | TransactionRaw + | TransactionERC20 + | TransactionERC721 + | TransactionERC1155 + | TransactionDelayedEncode + +export function transaction(data: Omit): Transaction { + return { type: 'transaction', ...data } +} + +export function erc20(data: Omit | Omit): Transaction { + const sendERC20Args = data as Omit + const transactionERC20 = data as Omit + + if (sendERC20Args.token !== undefined) { + return { + type: 'erc20send', + tokenAddress: sendERC20Args.token, + to: sendERC20Args.to, + value: sendERC20Args.value.toString() + } + } else if (transactionERC20.tokenAddress !== undefined) { + return { type: 'erc20send', ...transactionERC20 } + } else { + throw new Error('Invalid ERC20 transaction') + } +} + +export function erc721(data: Omit | Omit): Transaction { + const sendERC721Args = data as Omit + const transactionERC721 = data as Omit + + if (sendERC721Args.token !== undefined) { + return { + type: 'erc721send', + tokenAddress: sendERC721Args.token, + to: sendERC721Args.to, + id: sendERC721Args.id, + data: sendERC721Args.data, + safe: sendERC721Args.safe + } + } else if (transactionERC721.tokenAddress !== undefined) { + return { type: 'erc721send', ...transactionERC721 } + } else { + throw new Error('Invalid ERC721 transaction') + } +} + +export function erc1155(data: Omit | Omit): Transaction { + const sendERC1155Args = data as Omit + const transactionERC1155 = data as Omit + + if (sendERC1155Args.values !== undefined) { + return { + type: 'erc1155send', + vals: sendERC1155Args.values.map(v => ({ + id: v.id, + amount: ethers.BigNumber.from(v.amount).toString() + })), + tokenAddress: sendERC1155Args.token, + to: sendERC1155Args.to, + data: sendERC1155Args.data + } + } else if (transactionERC1155.vals !== undefined) { + return { + type: 'erc1155send', + vals: transactionERC1155.vals.map(v => ({ + id: v.id, + amount: ethers.BigNumber.from(v.amount).toString() + })), + tokenAddress: transactionERC1155.tokenAddress, + to: transactionERC1155.to, + data: transactionERC1155.data + } + } else { + throw new Error('Invalid ERC1155 transaction') + } +} + +export function delayedEncode( + data: Omit | Omit +): Transaction { + const sendDelayedEncodeArgs = data as Omit + const transactionDelayedEncode = data as Omit + + if (sendDelayedEncodeArgs.abi !== undefined) { + return { + type: 'delayedEncode', + to: sendDelayedEncodeArgs.to, + value: ethers.BigNumber.from(sendDelayedEncodeArgs.value).toString(), + data: { + abi: sendDelayedEncodeArgs.abi, + func: sendDelayedEncodeArgs.func, + args: sendDelayedEncodeArgs.args + } + } + } else if (transactionDelayedEncode.data !== undefined) { + return { + type: 'delayedEncode', + to: transactionDelayedEncode.to, + value: transactionDelayedEncode.value, + data: transactionDelayedEncode.data + } + } else { + throw new Error('Invalid delayed encode transaction') + } +} + +export function combineTransactionIntents(intents: Intent[]): Intent { + if (intents.length === 0) { + throw new Error('No packets provided') + } + + // Ensure that all packets are for the same network and wallet + const network = intents[0].data.network + const wallet = intents[0].data.wallet + const lifespan = intents[0].expiresAt - intents[0].issuedAt + const identifier = intents[0].data.identifier + const transactionsFeeQuote = intents[0].data.transactionsFeeQuote + + if (!intents.every(intent => intent.data.network === network)) { + throw new Error('All packets must have the same chainId') + } + + if (!intents.every(intent => intent.data.wallet === wallet)) { + throw new Error('All packets must have the same wallet') + } + + return makeIntent(IntentName.sendTransaction, lifespan, { + network, + wallet, + identifier, + transactions: intents.flatMap(intent => intent.data.transactions), + transactionsFeeQuote + }) +} + +function isEthersTx(tx: Transaction): tx is ethers.providers.TransactionRequest { + return !['transaction', 'erc20send', 'erc721send', 'erc1155send', 'delayedEncode'].includes(tx.type as any) +} diff --git a/packages/waas/src/intents/utils.ts b/packages/waas/src/intents/utils.ts new file mode 100644 index 0000000000..7a41587a52 --- /dev/null +++ b/packages/waas/src/intents/utils.ts @@ -0,0 +1,7 @@ +export function useLifespan(lifespan: number) { + const issuedAt = Math.floor(Date.now() / 1000) + return { + issuedAt, + expiresAt: issuedAt + lifespan + } +} diff --git a/packages/waas/src/networks.ts b/packages/waas/src/networks.ts new file mode 100644 index 0000000000..058a368654 --- /dev/null +++ b/packages/waas/src/networks.ts @@ -0,0 +1,49 @@ +import { networks, ChainId } from '@0xsequence/network' + +const RPC_BASE = 'https://nodes.sequence.app/' + +const nameToId = Object.entries(networks).reduce( + (acc, [key, value]) => { + acc[value.name] = value.chainId + return acc + }, + {} as { [name: string]: (typeof networks)[ChainId.MAINNET]['chainId'] } +) + +type NameToIdType = typeof nameToId +type IdToNameType = { [K in keyof NameToIdType as NameToIdType[K]]: K } + +const idToName = Object.entries(nameToId).reduce((acc, [key, value]) => { + acc[value] = key as any + return acc +}, {} as IdToNameType) + +export type SimpleNetwork = keyof NameToIdType | keyof IdToNameType + +export function isSimpleNetwork(network: any): network is SimpleNetwork { + return toNetworkID(network) in nameToId +} + +export function toNetworkID(network: SimpleNetwork): keyof IdToNameType { + const networkNumber = typeof network === 'number' ? network : parseInt(network) + if (networkNumber in idToName) { + return networkNumber + } + + const networkLower = network.toString().toLowerCase() + if (networkLower in nameToId) { + return nameToId[networkLower as keyof NameToIdType] + } + + throw new Error(`Unknown network: ${network}`) +} + +export function nameOfNetwork(network: SimpleNetwork): keyof NameToIdType { + return idToName[toNetworkID(network)] +} + +export function rpcNode(network: SimpleNetwork): string { + return RPC_BASE + nameOfNetwork(network) +} + +export type WithSimpleNetwork = Omit & { network?: SimpleNetwork } diff --git a/packages/waas/src/secure-store.ts b/packages/waas/src/secure-store.ts new file mode 100644 index 0000000000..ace34140ec --- /dev/null +++ b/packages/waas/src/secure-store.ts @@ -0,0 +1,69 @@ +import { openDB, IDBPDatabase } from 'idb' + +export interface SecureStoreBackend { + get(dbName: string, dbStoreName: string, key: string): Promise + set(dbName: string, dbStoreName: string, key: string, value: any): Promise + delete(dbName: string, dbStoreName: string, key: string): Promise +} + +export const getDefaultSecureStoreBackend = (): SecureStoreBackend | null => { + if (isIndexedDbAvailable()) { + return new IndexedDbSecureStoreBackend() + } else { + return null + } +} + +export function isIndexedDbAvailable(): boolean { + return typeof indexedDB === 'object' +} + +export class IndexedDbSecureStoreBackend implements SecureStoreBackend { + private db: IDBPDatabase | null + + constructor() { + if (!isIndexedDbAvailable()) { + throw new Error('IndexedDB is not available') + } + + this.db = null + } + + private async openDB(dbName: string, dbStoreName: string, version: number): Promise { + if (this.db) { + return this.db + } + + this.db = await openDB(dbName, 1, { + upgrade(db) { + db.createObjectStore(dbStoreName) + } + }) + + return this.db + } + + async get(dbName: string, dbStoreName: string, key: string): Promise { + const db = await this.openDB(dbName, dbStoreName, 1) + const tx = db.transaction(dbStoreName, 'readonly') + const value = await db.get(dbStoreName, key) + await tx.done + return value + } + + async set(dbName: string, dbStoreName: string, key: string, value: any): Promise { + const db = await this.openDB(dbName, dbStoreName, 1) + const tx = db.transaction(dbStoreName, 'readwrite') + await db.put(dbStoreName, value, key) + await tx.done + return true + } + + async delete(dbName: string, dbStoreName: string, key: string): Promise { + const db = await this.openDB(dbName, dbStoreName, 1) + const tx = db.transaction(dbStoreName, 'readwrite') + await db.delete(dbStoreName, key) + await tx.done + return true + } +} diff --git a/packages/waas/src/session/index.ts b/packages/waas/src/session/index.ts new file mode 100644 index 0000000000..5e88043c39 --- /dev/null +++ b/packages/waas/src/session/index.ts @@ -0,0 +1,42 @@ +import { newSECP256K1SessionFromSessionId, newSECP256K1Session } from './secp256k1' +import { newSECP256R1SessionFromSessionId, newSECP256R1Session } from './secp256r1' +import { SubtleCryptoBackend } from '../subtle-crypto' +import { SecureStoreBackend } from '../secure-store' + +export type Session = { + sessionId(): Promise + sign(message: string | Uint8Array): Promise + clear(): void +} + +export async function newSessionFromSessionId( + sessionId: string, + cryptoBackend: SubtleCryptoBackend | null, + secureStoreBackend: SecureStoreBackend | null +): Promise { + if (!secureStoreBackend) { + throw new Error('No secure store available') + } + if (cryptoBackend) { + return newSECP256R1SessionFromSessionId(sessionId, cryptoBackend, secureStoreBackend) + } else { + return newSECP256K1SessionFromSessionId(sessionId, secureStoreBackend) + } +} + +export async function newSession( + cryptoBackend: SubtleCryptoBackend | null, + secureStoreBackend: SecureStoreBackend | null +): Promise { + if (!secureStoreBackend) { + throw new Error('No secure store available') + } + if (cryptoBackend) { + return newSECP256R1Session(cryptoBackend, secureStoreBackend) + } else { + return newSECP256K1Session(secureStoreBackend) + } +} + +export * from './secp256r1' +export * from './secp256k1' diff --git a/packages/waas/src/session/keyTypes.ts b/packages/waas/src/session/keyTypes.ts new file mode 100644 index 0000000000..d2296b980a --- /dev/null +++ b/packages/waas/src/session/keyTypes.ts @@ -0,0 +1,4 @@ +export enum KeyTypes { + ECDSAP256K1 = 0, + ECDSAP256R1 = 1 +} diff --git a/packages/waas/src/session/secp256k1.ts b/packages/waas/src/session/secp256k1.ts new file mode 100644 index 0000000000..ec76507cb4 --- /dev/null +++ b/packages/waas/src/session/secp256k1.ts @@ -0,0 +1,48 @@ +import { ethers } from 'ethers' +import { SecureStoreBackend } from '../secure-store' +import { Session } from './index' + +const idbName = 'seq-waas-session-p256k1' +const idbStoreName = 'seq-waas-session' + +export async function newSECP256K1SessionFromSessionId( + sessionId: string, + secureStoreBackend: SecureStoreBackend +): Promise { + const privateKey = await secureStoreBackend.get(idbName, idbStoreName, sessionId) + + if (!privateKey) { + throw new Error('No private key found') + } + + const wallet = new ethers.Wallet(privateKey) + + return { + sessionId(): Promise { + return wallet.getAddress() + }, + sign(message: string | Uint8Array): Promise { + return wallet.signMessage(message) + }, + clear: async () => { + await secureStoreBackend.delete(idbName, idbStoreName, sessionId) + } + } as Session +} + +export async function newSECP256K1SessionFromPrivateKey( + privateKey: string, + secureStoreBackend: SecureStoreBackend +): Promise { + const wallet = new ethers.Wallet(privateKey) + const sessionId = await wallet.getAddress() + + await secureStoreBackend.set(idbName, idbStoreName, sessionId, privateKey) + + return newSECP256K1SessionFromSessionId(sessionId, secureStoreBackend) +} + +export async function newSECP256K1Session(secureStoreBackend: SecureStoreBackend): Promise { + const wallet = ethers.Wallet.createRandom() + return newSECP256K1SessionFromPrivateKey(wallet.privateKey, secureStoreBackend) +} diff --git a/packages/waas/src/session/secp256r1.ts b/packages/waas/src/session/secp256r1.ts new file mode 100644 index 0000000000..fa95dd1e50 --- /dev/null +++ b/packages/waas/src/session/secp256r1.ts @@ -0,0 +1,92 @@ +import { ethers } from 'ethers' +import { Session } from './index' +import { KeyTypes } from './keyTypes' +import { SubtleCryptoBackend } from '../subtle-crypto' +import { SecureStoreBackend } from '../secure-store' + +const idbName = 'seq-waas-session-p256r1' +const idbStoreName = 'seq-waas-session' + +// TODO: We need to update this to use the secure store backend +// Currently it ignores the override and leverages idb +// This is because the CryptoKeyPair is a bit more complicated +// than a simple string that SecureStoreBackend can handle + +export async function newSECP256R1SessionFromSessionId( + sessionId: string, + cryptoBackend: SubtleCryptoBackend, + secureStoreBackend: SecureStoreBackend +): Promise { + const keys = await secureStoreBackend.get(idbName, idbStoreName, sessionId) + + if (!keys || !keys.privateKey) { + throw new Error('No private key found') + } + + const encoder = new TextEncoder() + return { + sessionId: async () => { + const pubKeyRaw = await cryptoBackend.exportKey('raw', keys.publicKey) + const pubKeyTypedRaw = new Uint8Array(pubKeyRaw.byteLength + 1) + + // set the first byte to the key type + pubKeyTypedRaw[0] = KeyTypes.ECDSAP256R1 + pubKeyTypedRaw.set(new Uint8Array(pubKeyRaw), 1) + + return ethers.utils.hexlify(pubKeyTypedRaw) + }, + sign: async (message: string | Uint8Array) => { + if (typeof message === 'string') { + if (message.startsWith('0x')) { + message = message.slice(2) + message = ethers.utils.arrayify(message) + } else { + message = encoder.encode(message) + } + } + const signatureBuff = await cryptoBackend.sign({ name: 'ECDSA', hash: { name: 'SHA-256' } }, keys.privateKey, message) + return ethers.utils.hexlify(new Uint8Array(signatureBuff)) + }, + clear: async () => { + await secureStoreBackend.delete(idbName, idbStoreName, sessionId) + } + } +} + +export async function newSECP256R1SessionFromKeyPair( + keyPair: CryptoKeyPair, + cryptoBackend: SubtleCryptoBackend, + secureStoreBackend: SecureStoreBackend +): Promise { + const sessionId = await pubKeyToSessionId(cryptoBackend, keyPair.publicKey) + + await secureStoreBackend.set(idbName, idbStoreName, sessionId, keyPair) + + return newSECP256R1SessionFromSessionId(sessionId, cryptoBackend, secureStoreBackend) +} + +export async function newSECP256R1Session( + cryptoBackend: SubtleCryptoBackend, + secureStoreBackend: SecureStoreBackend +): Promise { + const generatedKeys = await cryptoBackend.generateKey( + { + name: 'ECDSA', + namedCurve: 'P-256' + }, + false, + ['sign', 'verify'] + ) + return newSECP256R1SessionFromKeyPair(generatedKeys, cryptoBackend, secureStoreBackend) +} + +async function pubKeyToSessionId(cryptoBackend: SubtleCryptoBackend, pubKey: CryptoKey): Promise { + const pubKeyRaw = await cryptoBackend.exportKey('raw', pubKey) + const pubKeyTypedRaw = new Uint8Array(pubKeyRaw.byteLength + 1) + + // set the first byte to the key type + pubKeyTypedRaw[0] = KeyTypes.ECDSAP256R1 + pubKeyTypedRaw.set(new Uint8Array(pubKeyRaw), 1) + + return ethers.utils.hexlify(pubKeyTypedRaw) +} diff --git a/packages/waas/src/store.ts b/packages/waas/src/store.ts new file mode 100644 index 0000000000..a2fb99753a --- /dev/null +++ b/packages/waas/src/store.ts @@ -0,0 +1,89 @@ +export interface Store { + get(key: string): Promise + set(key: string, value: string | null): Promise +} + +export class StoreObj { + constructor( + private readonly store: Store, + private readonly key: string, + private readonly defaultValue: T + ) {} + + async get(): Promise { + const value = await this.store.get(this.key) + return value ? (value as T) : this.defaultValue + } + + async set(value: T): Promise { + if (value) { + await this.store.set(this.key, value) + } else { + await this.store.set(this.key, null) + } + } +} + +export class LocalStore implements Store { + private readonly store: Store + + constructor() { + if (WindowLocalStorage.isAvailable()) { + this.store = new WindowLocalStorage() + } else { + this.store = new MemoryStore() + } + } + + async get(key: string): Promise { + return this.store.get(key) + } + + async set(key: string, value: string | null): Promise { + return this.store.set(key, value) + } +} + +export class WindowLocalStorage implements Store { + static isAvailable(): boolean { + return typeof window === 'object' && typeof window.localStorage === 'object' + } + + constructor() { + if (!WindowLocalStorage.isAvailable()) { + throw new Error('No localStorage') + } + } + + async get(key: string): Promise { + return window.localStorage.getItem(key) + } + + async set(key: string, value: string | null): Promise { + if (!value) { + window.localStorage.removeItem(key) + } else { + window.localStorage.setItem(key, value) + } + } +} + +export class MemoryStore implements Store { + private store: Record = {} + + constructor() { + this.store = {} + } + + async get(key: string): Promise { + return this.store[key] || null + } + + async set(key: string, value: string | null): Promise { + if (value) { + this.store[key] = value + } else { + delete this.store[key] + } + } +} diff --git a/packages/waas/src/subtle-crypto.ts b/packages/waas/src/subtle-crypto.ts new file mode 100644 index 0000000000..838c743f0d --- /dev/null +++ b/packages/waas/src/subtle-crypto.ts @@ -0,0 +1,102 @@ +export interface SubtleCryptoBackend { + // generateKey is used to generate a new key pair. NOTE: its important to pass + // `false` to the extractable argument to ensure that the private key contents + // cannot be revealed. Note, that you can still use `extractable:false` and the + // `exportKey(..)` method, because the Browser is smart enough to keep the key + // opaque and only allow it to be exported in a wrapped format without revealing + // the private key contents. + generateKey( + algorithm: RsaHashedKeyGenParams | EcKeyGenParams, + extractable: boolean, + keyUsages: KeyUsage[] + ): Promise + + // exportKey is used to export a key pair. The `format` argument is used to + // specify the format of the exported key. The `key` argument is the key pair + // to export. In general we'll use `format: 'raw'` and `key: `. + // Contents will be opaque when `extractable: false` was passed to `generateKey(..)`. + exportKey(format: Exclude, key: CryptoKey): Promise + + // digest is used to hash a message. The `algorithm` argument is used to specify + // the hash algorithm to use. The `data` argument is the message to hash. + digest(algorithm: AlgorithmIdentifier, data: Uint8Array): Promise + + // sign is used to sign a message. The `algorithm` argument is used to specify + // the signing algorithm to use. The `key` argument is the private key to use + // for signing. The `data` argument is the message to sign. + // + // For our purposes we just care about ECDSA / P-256. + sign(algorithm: AlgorithmIdentifier | RsaPssParams | EcdsaParams, key: CryptoKey, data: Uint8Array): Promise + + // verify is used to verify a signature. The `algorithm` argument is used to + // specify the verification algorithm to use. The `key` argument is the public + // key to use for verification. The `signature` argument is the signature to + // verify. The `data` argument is the message to verify. + verify( + algorithm: AlgorithmIdentifier | RsaPssParams | EcdsaParams, + key: CryptoKey, + signature: Uint8Array, + data: Uint8Array + ): Promise + + // getRandomValues is used to generate random bytes. The `len` argument is the + // number of random bytes to generate. + getRandomValues(len: number): Uint8Array +} + +export const getDefaultSubtleCryptoBackend = (): SubtleCryptoBackend | null => { + if (isWindowSubtleCryptoAvailable()) { + return new WindowSubtleCryptoBackend() + } else { + return null + } +} + +export function isWindowSubtleCryptoAvailable(): boolean { + return typeof window === 'object' && typeof window.crypto === 'object' && typeof window.crypto.subtle === 'object' +} + +export class WindowSubtleCryptoBackend implements SubtleCryptoBackend { + constructor() { + if (!isWindowSubtleCryptoAvailable()) { + throw new Error('window.crypto.subtle is not available') + } + } + + async generateKey( + algorithm: RsaHashedKeyGenParams | EcKeyGenParams, + extractable: boolean, + keyUsages: KeyUsage[] + ): Promise { + return window.crypto.subtle.generateKey(algorithm, extractable, keyUsages) + } + + async exportKey(format: Exclude, key: CryptoKey): Promise { + const keyData = await window.crypto.subtle.exportKey(format, key) + return new Uint8Array(keyData) + } + + async digest(algorithm: AlgorithmIdentifier, data: Uint8Array): Promise { + const digest = await window.crypto.subtle.digest(algorithm, data) + return new Uint8Array(digest) + } + + async sign(algorithm: AlgorithmIdentifier | RsaPssParams | EcdsaParams, key: CryptoKey, data: Uint8Array): Promise { + const signature = await window.crypto.subtle.sign(algorithm, key, data) + return new Uint8Array(signature) + } + + async verify( + algorithm: AlgorithmIdentifier | RsaPssParams | EcdsaParams, + key: CryptoKey, + signature: Uint8Array, + data: Uint8Array + ): Promise { + return window.crypto.subtle.verify(algorithm, key, signature, data) + } + + getRandomValues(len: number) { + const randomValues = new Uint8Array(len) + return window.crypto.getRandomValues(randomValues) + } +} diff --git a/packages/waas/tests/intents.spec.ts b/packages/waas/tests/intents.spec.ts new file mode 100644 index 0000000000..643c8f8ea7 --- /dev/null +++ b/packages/waas/tests/intents.spec.ts @@ -0,0 +1,168 @@ +import * as chai from 'chai' +import { ethers } from 'ethers' + +import { Intent, signIntent } from '../src/intents' +import { IntentDataSendTransaction, IntentDataSignMessage } from '../src/clients/intent.gen' +import { newSECP256K1SessionFromPrivateKey } from '../src/session' +import { getDefaultSecureStoreBackend } from '../src/secure-store' + +import 'fake-indexeddb/auto' + +const { expect } = chai + +describe('Payloads', () => { + it('Should sign a payload', async () => { + const intent: Intent = { + version: '1', + name: 'sendTransactions', + issuedAt: 1600000000, + expiresAt: 1600000000 + 86400, + data: { + identifier: 'test-identifier', + wallet: '0xD67FC48b298B09Ed3D03403d930769C527186c4e', + network: '1', + transactions: [ + { + type: 'erc20send', + token: ethers.constants.AddressZero, + to: '0x0dc9603d4da53841C1C83f3B550C6143e60e0425', + value: '0' + } + ] + } + } + + const secureStoreBackend = getDefaultSecureStoreBackend() + if (!secureStoreBackend) { + throw new Error('Secure store backend not available') + } + const session = await newSECP256K1SessionFromPrivateKey( + '0xecd39e2cdadc2427255042ca7e0f86368bd7aa6e3c99470444b7d073840c1b51', + secureStoreBackend + ) + const signedIntent = await signIntent(session, intent) + + expect(signedIntent.signatures.length).to.equal(1) + expect(signedIntent.signatures[0].sessionId).to.equal(await session.sessionId()) + expect(signedIntent.signatures[0].signature).to.equal( + '0x14682ca0eb116109cdf1d0bad6a84e29787787b4a1779d2b43c28d8705ade929267474e8a7725d5e7540ded2010897d3ecaad32b27c75fbfb4f63ff1cf1a948a1c' + ) + }) + + it('Should sign a message payload', async () => { + const intent: Intent = { + version: '1', + name: 'sendTransactions', + issuedAt: 1600000000, + expiresAt: 1600000000 + 86400, + data: { + network: '1', + wallet: '0xD67FC48b298B09Ed3D03403d930769C527186c4e', + message: '0xdeadbeef' + } + } + + const secureStoreBackend = getDefaultSecureStoreBackend() + if (!secureStoreBackend) { + throw new Error('Secure store backend not available') + } + const session = await newSECP256K1SessionFromPrivateKey( + '0xecd39e2cdadc2427255042ca7e0f86368bd7aa6e3c99470444b7d073840c1b51', + secureStoreBackend + ) + const signedIntent = await signIntent(session, intent) + + expect(signedIntent.signatures.length).to.equal(1) + expect(signedIntent.signatures[0].sessionId).to.equal(await session.sessionId()) + expect(signedIntent.signatures[0].signature).to.equal( + '0x768b25315317e551ed7b540e73fdf69d8816dcc763a50c648cf2966849f089a2495103f06c876c502bfb33cb348c4b77ffe39bbd6483b932b806a5817374f9ea1c' + ) + }) + + it('Should sign transaction payload', async () => { + const intent: Intent = { + version: '1', + name: 'sendTransactions', + issuedAt: 1600000000, + expiresAt: 1600000000 + 86400, + data: { + identifier: 'test-identifier', + wallet: '0xD67FC48b298B09Ed3D03403d930769C527186c4e', + network: '1', + transactions: [ + { + type: 'transaction', + to: '0x479F6a5b0C1728947318714963a583C56A78366A', + value: '39381', + data: '0x3251ba32' + }, + { + type: 'erc20send', + token: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', + to: '0x7b1Bd3474D789e18e2E329E2c53F819B6E687b4A', + value: '1000' + }, + { + type: 'erc721send', + token: '0xF87E31492Faf9A91B02Ee0dEAAd50d51d56D5d4d', + to: '0x17fFA2d95b58228e1ECb0C6Ac25A6EfD20BA08E4', + id: '7', + safe: true, + data: '0x112233' + }, + { + type: 'erc1155send', + token: '0x631998e91476da5b870d741192fc5cbc55f5a52e', + to: '0x91E8aC543C5fEDf9F3Ef8b9dA1500dB84305681F', + vals: [ + { + id: '2', + amount: '5' + }, + { + id: '500', + amount: '1' + } + ], + data: '0x223344' + }, + { + type: 'delayedEncode', + to: '0x140d72763D1ce39Ad4E2e73EC6e8FC53E5b73B64', + value: '0', + data: { + abi: '[{"inputs":[{"internalType":"uint256","name":"_orderId","type":"uint256"},{"internalType":"uint256","name":"_maxCost","type":"uint256"},{"internalType":"address[]","name":"_fees","type":"address[]"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"fillOrKillOrder","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_val","type":"uint256"},{"internalType":"string","name":"_data","type":"string"}],"name":"notExpired","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[],"name":"otherMethods","outputs":[],"stateMutability":"nonpayable","type":"function"}]', + func: 'fillOrKillOrder', + args: [ + '48774435471364917511246724398022004900255301025912680232738918790354204737320', + '1000000000000000000', + '["0x8541D65829f98f7D71A4655cCD7B2bB8494673bF"]', + { + abi: 'notExpired(uint256,string)', + func: 'notExpired', + args: ['1600000000', 'Nov 1st, 2020'] + } + ] + } + } + ] + } + } + + const secureStoreBackend = getDefaultSecureStoreBackend() + if (!secureStoreBackend) { + throw new Error('Secure store backend not available') + } + const session = await newSECP256K1SessionFromPrivateKey( + '0xecd39e2cdadc2427255042ca7e0f86368bd7aa6e3c99470444b7d073840c1b51', + secureStoreBackend + ) + const signedIntent = await signIntent(session, intent) + + expect(signedIntent.signatures.length).to.equal(1) + expect(signedIntent.signatures[0].sessionId).to.equal(await session.sessionId()) + expect(signedIntent.signatures[0].signature).to.equal( + '0x98dd84b3d4fe077b2f55e2839609b226d8119b9b0ee10756122615a5d68746bf60596069a305a7533123f212b576d16f3f14ad06faed9fc005c32a28bf8bafb21b' + ) + }) +}) diff --git a/packages/wallet/CHANGELOG.md b/packages/wallet/CHANGELOG.md new file mode 100644 index 0000000000..1708df248d --- /dev/null +++ b/packages/wallet/CHANGELOG.md @@ -0,0 +1,3916 @@ +# @0xsequence/wallet + +## 1.10.8 + +### Patch Changes + +- update metadata bindings +- Updated dependencies + - @0xsequence/abi@1.10.8 + - @0xsequence/core@1.10.8 + - @0xsequence/network@1.10.8 + - @0xsequence/relayer@1.10.8 + - @0xsequence/signhub@1.10.8 + - @0xsequence/utils@1.10.8 + +## 1.10.7 + +### Patch Changes + +- minor fixes to waas client +- Updated dependencies + - @0xsequence/abi@1.10.7 + - @0xsequence/core@1.10.7 + - @0xsequence/network@1.10.7 + - @0xsequence/relayer@1.10.7 + - @0xsequence/signhub@1.10.7 + - @0xsequence/utils@1.10.7 + +## 1.10.6 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/abi@1.10.6 + - @0xsequence/core@1.10.6 + - @0xsequence/network@1.10.6 + - @0xsequence/relayer@1.10.6 + - @0xsequence/signhub@1.10.6 + - @0xsequence/utils@1.10.6 + +## 1.10.5 + +### Patch Changes + +- network: ape-chain-testnet -> apechain-testnet +- Updated dependencies + - @0xsequence/abi@1.10.5 + - @0xsequence/core@1.10.5 + - @0xsequence/network@1.10.5 + - @0xsequence/relayer@1.10.5 + - @0xsequence/signhub@1.10.5 + - @0xsequence/utils@1.10.5 + +## 1.10.4 + +### Patch Changes + +- network: add b3-sepolia, ape-chain-testnet, blast, blast-sepolia +- Updated dependencies + - @0xsequence/abi@1.10.4 + - @0xsequence/core@1.10.4 + - @0xsequence/network@1.10.4 + - @0xsequence/relayer@1.10.4 + - @0xsequence/signhub@1.10.4 + - @0xsequence/utils@1.10.4 + +## 1.10.3 + +### Patch Changes + +- typing fix +- Updated dependencies + - @0xsequence/abi@1.10.3 + - @0xsequence/core@1.10.3 + - @0xsequence/network@1.10.3 + - @0xsequence/relayer@1.10.3 + - @0xsequence/signhub@1.10.3 + - @0xsequence/utils@1.10.3 + +## 1.10.2 + +### Patch Changes + +- - waas: add getIdToken method + - indexer: update api client +- Updated dependencies + - @0xsequence/abi@1.10.2 + - @0xsequence/core@1.10.2 + - @0xsequence/network@1.10.2 + - @0xsequence/relayer@1.10.2 + - @0xsequence/signhub@1.10.2 + - @0xsequence/utils@1.10.2 + +## 1.10.1 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/abi@1.10.1 + - @0xsequence/core@1.10.1 + - @0xsequence/network@1.10.1 + - @0xsequence/relayer@1.10.1 + - @0xsequence/signhub@1.10.1 + - @0xsequence/utils@1.10.1 + +## 1.10.0 + +### Minor Changes + +- waas release v1.3.0 + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.10.0 + - @0xsequence/core@1.10.0 + - @0xsequence/network@1.10.0 + - @0xsequence/relayer@1.10.0 + - @0xsequence/signhub@1.10.0 + - @0xsequence/utils@1.10.0 + +## 1.9.37 + +### Patch Changes + +- network: adds nativeToken data to NetworkMetadata constants +- Updated dependencies + - @0xsequence/abi@1.9.37 + - @0xsequence/core@1.9.37 + - @0xsequence/network@1.9.37 + - @0xsequence/relayer@1.9.37 + - @0xsequence/signhub@1.9.37 + - @0xsequence/utils@1.9.37 + +## 1.9.36 + +### Patch Changes + +- guard: export client +- Updated dependencies + - @0xsequence/abi@1.9.36 + - @0xsequence/core@1.9.36 + - @0xsequence/network@1.9.36 + - @0xsequence/relayer@1.9.36 + - @0xsequence/signhub@1.9.36 + - @0xsequence/utils@1.9.36 + +## 1.9.35 + +### Patch Changes + +- guard: update bindings +- Updated dependencies + - @0xsequence/abi@1.9.35 + - @0xsequence/core@1.9.35 + - @0xsequence/network@1.9.35 + - @0xsequence/relayer@1.9.35 + - @0xsequence/signhub@1.9.35 + - @0xsequence/utils@1.9.35 + +## 1.9.34 + +### Patch Changes + +- waas: always use lowercase email +- Updated dependencies + - @0xsequence/abi@1.9.34 + - @0xsequence/core@1.9.34 + - @0xsequence/network@1.9.34 + - @0xsequence/relayer@1.9.34 + - @0xsequence/signhub@1.9.34 + - @0xsequence/utils@1.9.34 + +## 1.9.33 + +### Patch Changes + +- waas: umd build +- Updated dependencies + - @0xsequence/abi@1.9.33 + - @0xsequence/core@1.9.33 + - @0xsequence/network@1.9.33 + - @0xsequence/relayer@1.9.33 + - @0xsequence/signhub@1.9.33 + - @0xsequence/utils@1.9.33 + +## 1.9.32 + +### Patch Changes + +- indexer: update bindings +- Updated dependencies + - @0xsequence/abi@1.9.32 + - @0xsequence/core@1.9.32 + - @0xsequence/network@1.9.32 + - @0xsequence/relayer@1.9.32 + - @0xsequence/signhub@1.9.32 + - @0xsequence/utils@1.9.32 + +## 1.9.31 + +### Patch Changes + +- metadata: token directory changes +- Updated dependencies + - @0xsequence/abi@1.9.31 + - @0xsequence/core@1.9.31 + - @0xsequence/network@1.9.31 + - @0xsequence/relayer@1.9.31 + - @0xsequence/signhub@1.9.31 + - @0xsequence/utils@1.9.31 + +## 1.9.30 + +### Patch Changes + +- update +- Updated dependencies + - @0xsequence/abi@1.9.30 + - @0xsequence/core@1.9.30 + - @0xsequence/network@1.9.30 + - @0xsequence/relayer@1.9.30 + - @0xsequence/signhub@1.9.30 + - @0xsequence/utils@1.9.30 + +## 1.9.29 + +### Patch Changes + +- disable gnosis chain +- Updated dependencies + - @0xsequence/abi@1.9.29 + - @0xsequence/core@1.9.29 + - @0xsequence/network@1.9.29 + - @0xsequence/relayer@1.9.29 + - @0xsequence/signhub@1.9.29 + - @0xsequence/utils@1.9.29 + +## 1.9.28 + +### Patch Changes + +- add utils/merkletree +- Updated dependencies + - @0xsequence/abi@1.9.28 + - @0xsequence/core@1.9.28 + - @0xsequence/network@1.9.28 + - @0xsequence/relayer@1.9.28 + - @0xsequence/signhub@1.9.28 + - @0xsequence/utils@1.9.28 + +## 1.9.27 + +### Patch Changes + +- network: optimistic -> optimism +- waas: remove defaults +- api, sessions: update bindings +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.9.27 + - @0xsequence/core@1.9.27 + - @0xsequence/network@1.9.27 + - @0xsequence/relayer@1.9.27 + - @0xsequence/signhub@1.9.27 + - @0xsequence/utils@1.9.27 + +## 1.9.26 + +### Patch Changes + +- - add backend interfaces for pluggable interfaces + - introduce @0xsequence/react-native + - update pnpm to lockfile v9 +- Updated dependencies + - @0xsequence/abi@1.9.26 + - @0xsequence/core@1.9.26 + - @0xsequence/network@1.9.26 + - @0xsequence/relayer@1.9.26 + - @0xsequence/signhub@1.9.26 + - @0xsequence/utils@1.9.26 + +## 1.9.25 + +### Patch Changes + +- update webrpc clients with new error types +- Updated dependencies + - @0xsequence/abi@1.9.25 + - @0xsequence/core@1.9.25 + - @0xsequence/network@1.9.25 + - @0xsequence/relayer@1.9.25 + - @0xsequence/signhub@1.9.25 + - @0xsequence/utils@1.9.25 + +## 1.9.24 + +### Patch Changes + +- waas: add memoryStore backend to localStore +- Updated dependencies + - @0xsequence/abi@1.9.24 + - @0xsequence/core@1.9.24 + - @0xsequence/network@1.9.24 + - @0xsequence/relayer@1.9.24 + - @0xsequence/signhub@1.9.24 + - @0xsequence/utils@1.9.24 + +## 1.9.23 + +### Patch Changes + +- update api client bindings +- Updated dependencies + - @0xsequence/abi@1.9.23 + - @0xsequence/core@1.9.23 + - @0xsequence/network@1.9.23 + - @0xsequence/relayer@1.9.23 + - @0xsequence/signhub@1.9.23 + - @0xsequence/utils@1.9.23 + +## 1.9.22 + +### Patch Changes + +- update metadata client bindings +- Updated dependencies + - @0xsequence/abi@1.9.22 + - @0xsequence/core@1.9.22 + - @0xsequence/network@1.9.22 + - @0xsequence/relayer@1.9.22 + - @0xsequence/signhub@1.9.22 + - @0xsequence/utils@1.9.22 + +## 1.9.21 + +### Patch Changes + +- api client bindings +- Updated dependencies + - @0xsequence/abi@1.9.21 + - @0xsequence/core@1.9.21 + - @0xsequence/network@1.9.21 + - @0xsequence/relayer@1.9.21 + - @0xsequence/signhub@1.9.21 + - @0xsequence/utils@1.9.21 + +## 1.9.20 + +### Patch Changes + +- api client bindings update +- Updated dependencies + - @0xsequence/abi@1.9.20 + - @0xsequence/core@1.9.20 + - @0xsequence/network@1.9.20 + - @0xsequence/relayer@1.9.20 + - @0xsequence/signhub@1.9.20 + - @0xsequence/utils@1.9.20 + +## 1.9.19 + +### Patch Changes + +- waas update +- Updated dependencies + - @0xsequence/abi@1.9.19 + - @0xsequence/core@1.9.19 + - @0xsequence/network@1.9.19 + - @0xsequence/relayer@1.9.19 + - @0xsequence/signhub@1.9.19 + - @0xsequence/utils@1.9.19 + +## 1.9.18 + +### Patch Changes + +- provider: prohibit dangerous functions +- Updated dependencies + - @0xsequence/abi@1.9.18 + - @0xsequence/core@1.9.18 + - @0xsequence/network@1.9.18 + - @0xsequence/relayer@1.9.18 + - @0xsequence/signhub@1.9.18 + - @0xsequence/utils@1.9.18 + +## 1.9.17 + +### Patch Changes + +- network: add xr-sepolia +- Updated dependencies + - @0xsequence/network@1.9.17 + - @0xsequence/abi@1.9.17 + - @0xsequence/core@1.9.17 + - @0xsequence/relayer@1.9.17 + - @0xsequence/signhub@1.9.17 + - @0xsequence/utils@1.9.17 + +## 1.9.16 + +### Patch Changes + +- waas: sequence.feeOptions +- Updated dependencies + - @0xsequence/abi@1.9.16 + - @0xsequence/core@1.9.16 + - @0xsequence/network@1.9.16 + - @0xsequence/relayer@1.9.16 + - @0xsequence/signhub@1.9.16 + - @0xsequence/utils@1.9.16 + +## 1.9.15 + +### Patch Changes + +- metadata: collection external_link field name fix +- Updated dependencies + - @0xsequence/abi@1.9.15 + - @0xsequence/core@1.9.15 + - @0xsequence/network@1.9.15 + - @0xsequence/relayer@1.9.15 + - @0xsequence/signhub@1.9.15 + - @0xsequence/utils@1.9.15 + +## 1.9.14 + +### Patch Changes + +- network: astar-zkatana -> astar-zkyoto +- network: deprecate polygon mumbai network +- network: add xai and polygon amoy +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.9.14 + - @0xsequence/core@1.9.14 + - @0xsequence/network@1.9.14 + - @0xsequence/relayer@1.9.14 + - @0xsequence/signhub@1.9.14 + - @0xsequence/utils@1.9.14 + +## 1.9.13 + +### Patch Changes + +- waas: fix @0xsequence/network dependency +- Updated dependencies + - @0xsequence/abi@1.9.13 + - @0xsequence/core@1.9.13 + - @0xsequence/network@1.9.13 + - @0xsequence/relayer@1.9.13 + - @0xsequence/signhub@1.9.13 + - @0xsequence/utils@1.9.13 + +## 1.9.12 + +### Patch Changes + +- indexer: update rpc bindings +- provider: signMessage: Serialize the BytesLike or string message into hexstring before sending +- waas: SessionAuthProof +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.9.12 + - @0xsequence/core@1.9.12 + - @0xsequence/network@1.9.12 + - @0xsequence/relayer@1.9.12 + - @0xsequence/signhub@1.9.12 + - @0xsequence/utils@1.9.12 + +## 1.9.11 + +### Patch Changes + +- metdata, update rpc bindings +- Updated dependencies + - @0xsequence/abi@1.9.11 + - @0xsequence/core@1.9.11 + - @0xsequence/network@1.9.11 + - @0xsequence/relayer@1.9.11 + - @0xsequence/signhub@1.9.11 + - @0xsequence/utils@1.9.11 + +## 1.9.10 + +### Patch Changes + +- update metadata rpc bindings +- Updated dependencies + - @0xsequence/abi@1.9.10 + - @0xsequence/core@1.9.10 + - @0xsequence/network@1.9.10 + - @0xsequence/relayer@1.9.10 + - @0xsequence/signhub@1.9.10 + - @0xsequence/utils@1.9.10 + +## 1.9.9 + +### Patch Changes + +- metadata, add SequenceCollections rpc client +- Updated dependencies + - @0xsequence/abi@1.9.9 + - @0xsequence/core@1.9.9 + - @0xsequence/network@1.9.9 + - @0xsequence/relayer@1.9.9 + - @0xsequence/signhub@1.9.9 + - @0xsequence/utils@1.9.9 + +## 1.9.8 + +### Patch Changes + +- waas client update +- Updated dependencies + - @0xsequence/abi@1.9.8 + - @0xsequence/core@1.9.8 + - @0xsequence/network@1.9.8 + - @0xsequence/relayer@1.9.8 + - @0xsequence/signhub@1.9.8 + - @0xsequence/utils@1.9.8 + +## 1.9.7 + +### Patch Changes + +- update rpc client bindings for api, metadata and relayer +- Updated dependencies + - @0xsequence/abi@1.9.7 + - @0xsequence/core@1.9.7 + - @0xsequence/network@1.9.7 + - @0xsequence/relayer@1.9.7 + - @0xsequence/signhub@1.9.7 + - @0xsequence/utils@1.9.7 + +## 1.9.6 + +### Patch Changes + +- waas package update +- Updated dependencies + - @0xsequence/abi@1.9.6 + - @0xsequence/core@1.9.6 + - @0xsequence/network@1.9.6 + - @0xsequence/relayer@1.9.6 + - @0xsequence/signhub@1.9.6 + - @0xsequence/utils@1.9.6 + +## 1.9.5 + +### Patch Changes + +- RpcRelayer prioritize project access key +- Updated dependencies + - @0xsequence/abi@1.9.5 + - @0xsequence/core@1.9.5 + - @0xsequence/network@1.9.5 + - @0xsequence/relayer@1.9.5 + - @0xsequence/signhub@1.9.5 + - @0xsequence/utils@1.9.5 + +## 1.9.4 + +### Patch Changes + +- waas: fix network dependency +- Updated dependencies + - @0xsequence/abi@1.9.4 + - @0xsequence/core@1.9.4 + - @0xsequence/network@1.9.4 + - @0xsequence/relayer@1.9.4 + - @0xsequence/signhub@1.9.4 + - @0xsequence/utils@1.9.4 + +## 1.9.3 + +### Patch Changes + +- provider: don't append access key to RPC url if user has already provided it +- Updated dependencies + - @0xsequence/abi@1.9.3 + - @0xsequence/core@1.9.3 + - @0xsequence/network@1.9.3 + - @0xsequence/relayer@1.9.3 + - @0xsequence/signhub@1.9.3 + - @0xsequence/utils@1.9.3 + +## 1.9.2 + +### Patch Changes + +- network: add xai-sepolia +- Updated dependencies + - @0xsequence/abi@1.9.2 + - @0xsequence/core@1.9.2 + - @0xsequence/network@1.9.2 + - @0xsequence/relayer@1.9.2 + - @0xsequence/signhub@1.9.2 + - @0xsequence/utils@1.9.2 + +## 1.9.1 + +### Patch Changes + +- analytics fix +- Updated dependencies + - @0xsequence/abi@1.9.1 + - @0xsequence/core@1.9.1 + - @0xsequence/network@1.9.1 + - @0xsequence/relayer@1.9.1 + - @0xsequence/signhub@1.9.1 + - @0xsequence/utils@1.9.1 + +## 1.9.0 + +### Minor Changes + +- waas release + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.9.0 + - @0xsequence/core@1.9.0 + - @0xsequence/network@1.9.0 + - @0xsequence/relayer@1.9.0 + - @0xsequence/signhub@1.9.0 + - @0xsequence/utils@1.9.0 + +## 1.8.8 + +### Patch Changes + +- update metadata bindings +- Updated dependencies + - @0xsequence/abi@1.8.8 + - @0xsequence/core@1.8.8 + - @0xsequence/network@1.8.8 + - @0xsequence/relayer@1.8.8 + - @0xsequence/signhub@1.8.8 + - @0xsequence/utils@1.8.8 + +## 1.8.7 + +### Patch Changes + +- provider: update databeat to 0.9.1 +- Updated dependencies + - @0xsequence/abi@1.8.7 + - @0xsequence/core@1.8.7 + - @0xsequence/network@1.8.7 + - @0xsequence/relayer@1.8.7 + - @0xsequence/signhub@1.8.7 + - @0xsequence/utils@1.8.7 + +## 1.8.6 + +### Patch Changes + +- guard: SignedOwnershipProof +- Updated dependencies + - @0xsequence/abi@1.8.6 + - @0xsequence/core@1.8.6 + - @0xsequence/network@1.8.6 + - @0xsequence/relayer@1.8.6 + - @0xsequence/signhub@1.8.6 + - @0xsequence/utils@1.8.6 + +## 1.8.5 + +### Patch Changes + +- guard: signOwnershipProof and isSignedOwnershipProof +- Updated dependencies + - @0xsequence/abi@1.8.5 + - @0xsequence/core@1.8.5 + - @0xsequence/network@1.8.5 + - @0xsequence/relayer@1.8.5 + - @0xsequence/signhub@1.8.5 + - @0xsequence/utils@1.8.5 + +## 1.8.4 + +### Patch Changes + +- network: add homeverse to networks list +- Updated dependencies + - @0xsequence/abi@1.8.4 + - @0xsequence/core@1.8.4 + - @0xsequence/network@1.8.4 + - @0xsequence/relayer@1.8.4 + - @0xsequence/signhub@1.8.4 + - @0xsequence/utils@1.8.4 + +## 1.8.3 + +### Patch Changes + +- api: introduce basic linked wallet support +- Updated dependencies + - @0xsequence/abi@1.8.3 + - @0xsequence/core@1.8.3 + - @0xsequence/network@1.8.3 + - @0xsequence/relayer@1.8.3 + - @0xsequence/signhub@1.8.3 + - @0xsequence/utils@1.8.3 + +## 1.8.2 + +### Patch Changes + +- provider: don't initialize analytics unless explicitly requested +- Updated dependencies + - @0xsequence/abi@1.8.2 + - @0xsequence/core@1.8.2 + - @0xsequence/network@1.8.2 + - @0xsequence/relayer@1.8.2 + - @0xsequence/signhub@1.8.2 + - @0xsequence/utils@1.8.2 + +## 1.8.1 + +### Patch Changes + +- update to analytics provider +- Updated dependencies + - @0xsequence/abi@1.8.1 + - @0xsequence/core@1.8.1 + - @0xsequence/network@1.8.1 + - @0xsequence/relayer@1.8.1 + - @0xsequence/signhub@1.8.1 + - @0xsequence/utils@1.8.1 + +## 1.8.0 + +### Minor Changes + +- provider: project analytics + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.8.0 + - @0xsequence/core@1.8.0 + - @0xsequence/network@1.8.0 + - @0xsequence/relayer@1.8.0 + - @0xsequence/signhub@1.8.0 + - @0xsequence/utils@1.8.0 + +## 1.7.2 + +### Patch Changes + +- 0xsequence: ChainId should not be exported as a type +- account, wallet: fix nonce selection +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.7.2 + - @0xsequence/core@1.7.2 + - @0xsequence/network@1.7.2 + - @0xsequence/relayer@1.7.2 + - @0xsequence/signhub@1.7.2 + - @0xsequence/utils@1.7.2 + +## 1.7.1 + +### Patch Changes + +- network: add missing avalanche logoURI +- Updated dependencies + - @0xsequence/abi@1.7.1 + - @0xsequence/core@1.7.1 + - @0xsequence/network@1.7.1 + - @0xsequence/relayer@1.7.1 + - @0xsequence/signhub@1.7.1 + - @0xsequence/utils@1.7.1 + +## 1.7.0 + +### Minor Changes + +- provider: projectAccessKey is now required + +### Patch Changes + +- network: add NetworkMetadata.logoURI property for all networks +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.7.0 + - @0xsequence/core@1.7.0 + - @0xsequence/network@1.7.0 + - @0xsequence/relayer@1.7.0 + - @0xsequence/signhub@1.7.0 + - @0xsequence/utils@1.7.0 + +## 1.6.3 + +### Patch Changes + +- network list update +- Updated dependencies + - @0xsequence/abi@1.6.3 + - @0xsequence/core@1.6.3 + - @0xsequence/network@1.6.3 + - @0xsequence/relayer@1.6.3 + - @0xsequence/signhub@1.6.3 + - @0xsequence/utils@1.6.3 + +## 1.6.2 + +### Patch Changes + +- auth: projectAccessKey option +- wallet: use 12 bytes for random space +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.6.2 + - @0xsequence/core@1.6.2 + - @0xsequence/network@1.6.2 + - @0xsequence/relayer@1.6.2 + - @0xsequence/signhub@1.6.2 + - @0xsequence/utils@1.6.2 + +## 1.6.1 + +### Patch Changes + +- core: add simple config from subdigest support +- core: fix encode tree with subdigest +- account: implement buildOnChainSignature on Account +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.6.1 + - @0xsequence/core@1.6.1 + - @0xsequence/network@1.6.1 + - @0xsequence/relayer@1.6.1 + - @0xsequence/signhub@1.6.1 + - @0xsequence/utils@1.6.1 + +## 1.6.0 + +### Minor Changes + +- account, wallet: parallel transactions by default + +### Patch Changes + +- provider: emit disconnect on sign out +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.6.0 + - @0xsequence/core@1.6.0 + - @0xsequence/network@1.6.0 + - @0xsequence/relayer@1.6.0 + - @0xsequence/signhub@1.6.0 + - @0xsequence/utils@1.6.0 + +## 1.5.0 + +### Minor Changes + +- signhub: add 'signing' signer status + +### Patch Changes + +- auth: Session.open: onAccountAddress callback +- account: allow empty transaction bundles +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.5.0 + - @0xsequence/core@1.5.0 + - @0xsequence/network@1.5.0 + - @0xsequence/relayer@1.5.0 + - @0xsequence/signhub@1.5.0 + - @0xsequence/utils@1.5.0 + +## 1.4.9 + +### Patch Changes + +- rename SequenceMetadataClient to SequenceMetadata +- Updated dependencies + - @0xsequence/abi@1.4.9 + - @0xsequence/core@1.4.9 + - @0xsequence/network@1.4.9 + - @0xsequence/relayer@1.4.9 + - @0xsequence/signhub@1.4.9 + - @0xsequence/utils@1.4.9 + +## 1.4.8 + +### Patch Changes + +- account: Account.getSigners +- Updated dependencies + - @0xsequence/abi@1.4.8 + - @0xsequence/core@1.4.8 + - @0xsequence/network@1.4.8 + - @0xsequence/relayer@1.4.8 + - @0xsequence/signhub@1.4.8 + - @0xsequence/utils@1.4.8 + +## 1.4.7 + +### Patch Changes + +- update indexer client bindings +- Updated dependencies + - @0xsequence/abi@1.4.7 + - @0xsequence/core@1.4.7 + - @0xsequence/network@1.4.7 + - @0xsequence/relayer@1.4.7 + - @0xsequence/signhub@1.4.7 + - @0xsequence/utils@1.4.7 + +## 1.4.6 + +### Patch Changes + +- - add sepolia networks, mark goerli as deprecated + - update indexer client bindings +- Updated dependencies + - @0xsequence/abi@1.4.6 + - @0xsequence/core@1.4.6 + - @0xsequence/network@1.4.6 + - @0xsequence/relayer@1.4.6 + - @0xsequence/signhub@1.4.6 + - @0xsequence/utils@1.4.6 + +## 1.4.5 + +### Patch Changes + +- indexer/metadata: update client bindings +- auth: selectWallet with new address +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.4.5 + - @0xsequence/core@1.4.5 + - @0xsequence/network@1.4.5 + - @0xsequence/relayer@1.4.5 + - @0xsequence/signhub@1.4.5 + - @0xsequence/utils@1.4.5 + +## 1.4.4 + +### Patch Changes + +- indexer: update bindings +- auth: handle jwt expiry +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.4.4 + - @0xsequence/core@1.4.4 + - @0xsequence/network@1.4.4 + - @0xsequence/relayer@1.4.4 + - @0xsequence/signhub@1.4.4 + - @0xsequence/utils@1.4.4 + +## 1.4.3 + +### Patch Changes + +- guard: return active status from GuardSigner.getAuthMethods +- Updated dependencies + - @0xsequence/abi@1.4.3 + - @0xsequence/core@1.4.3 + - @0xsequence/network@1.4.3 + - @0xsequence/relayer@1.4.3 + - @0xsequence/signhub@1.4.3 + - @0xsequence/utils@1.4.3 + +## 1.4.2 + +### Patch Changes + +- guard: update bindings +- Updated dependencies + - @0xsequence/abi@1.4.2 + - @0xsequence/core@1.4.2 + - @0xsequence/network@1.4.2 + - @0xsequence/relayer@1.4.2 + - @0xsequence/signhub@1.4.2 + - @0xsequence/utils@1.4.2 + +## 1.4.1 + +### Patch Changes + +- network: remove unused networks +- signhub: orchestrator interface +- guard: auth methods interface +- guard: update bindings for pin and totp +- guard: no more retry logic +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.4.1 + - @0xsequence/core@1.4.1 + - @0xsequence/network@1.4.1 + - @0xsequence/relayer@1.4.1 + - @0xsequence/signhub@1.4.1 + - @0xsequence/utils@1.4.1 + +## 1.4.0 + +### Minor Changes + +- project access key support + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.4.0 + - @0xsequence/core@1.4.0 + - @0xsequence/network@1.4.0 + - @0xsequence/relayer@1.4.0 + - @0xsequence/signhub@1.4.0 + - @0xsequence/utils@1.4.0 + +## 1.3.0 + +### Minor Changes + +- signhub: account children + +### Patch Changes + +- guard: do not throw when building deploy transaction +- network: snowtrace.io -> subnets.avax.network/c-chain +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.3.0 + - @0xsequence/core@1.3.0 + - @0xsequence/network@1.3.0 + - @0xsequence/relayer@1.3.0 + - @0xsequence/signhub@1.3.0 + - @0xsequence/utils@1.3.0 + +## 1.2.9 + +### Patch Changes + +- account: AccountSigner.sendTransaction simulateForFeeOptions +- relayer: update bindings +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.2.9 + - @0xsequence/core@1.2.9 + - @0xsequence/network@1.2.9 + - @0xsequence/relayer@1.2.9 + - @0xsequence/signhub@1.2.9 + - @0xsequence/utils@1.2.9 + +## 1.2.8 + +### Patch Changes + +- rename X-Sequence-Token-Key header to X-Access-Key +- Updated dependencies + - @0xsequence/abi@1.2.8 + - @0xsequence/core@1.2.8 + - @0xsequence/network@1.2.8 + - @0xsequence/relayer@1.2.8 + - @0xsequence/signhub@1.2.8 + - @0xsequence/utils@1.2.8 + +## 1.2.7 + +### Patch Changes + +- add x-sequence-token-key to clients +- Updated dependencies + - @0xsequence/abi@1.2.7 + - @0xsequence/core@1.2.7 + - @0xsequence/network@1.2.7 + - @0xsequence/relayer@1.2.7 + - @0xsequence/signhub@1.2.7 + - @0xsequence/utils@1.2.7 + +## 1.2.6 + +### Patch Changes + +- Fix bind multicall provider +- Updated dependencies + - @0xsequence/abi@1.2.6 + - @0xsequence/core@1.2.6 + - @0xsequence/network@1.2.6 + - @0xsequence/relayer@1.2.6 + - @0xsequence/signhub@1.2.6 + - @0xsequence/utils@1.2.6 + +## 1.2.5 + +### Patch Changes + +- Multicall default configuration fixes +- Updated dependencies + - @0xsequence/abi@1.2.5 + - @0xsequence/core@1.2.5 + - @0xsequence/network@1.2.5 + - @0xsequence/relayer@1.2.5 + - @0xsequence/signhub@1.2.5 + - @0xsequence/utils@1.2.5 + +## 1.2.4 + +### Patch Changes + +- provider: Adding missing payment provider types to PaymentProviderOption +- provider: WalletRequestHandler.notifyChainChanged +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.2.4 + - @0xsequence/core@1.2.4 + - @0xsequence/network@1.2.4 + - @0xsequence/relayer@1.2.4 + - @0xsequence/signhub@1.2.4 + - @0xsequence/utils@1.2.4 + +## 1.2.3 + +### Patch Changes + +- auth, provider: connect to accept optional authorizeNonce +- Updated dependencies + - @0xsequence/abi@1.2.3 + - @0xsequence/core@1.2.3 + - @0xsequence/network@1.2.3 + - @0xsequence/relayer@1.2.3 + - @0xsequence/signhub@1.2.3 + - @0xsequence/utils@1.2.3 + +## 1.2.2 + +### Patch Changes + +- provider: allow createContract calls +- core: check for explicit zero address in contract deployments +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.2.2 + - @0xsequence/core@1.2.2 + - @0xsequence/network@1.2.2 + - @0xsequence/relayer@1.2.2 + - @0xsequence/signhub@1.2.2 + - @0xsequence/utils@1.2.2 + +## 1.2.1 + +### Patch Changes + +- auth: use sequence api chain id as reference chain id if available +- Updated dependencies + - @0xsequence/abi@1.2.1 + - @0xsequence/core@1.2.1 + - @0xsequence/network@1.2.1 + - @0xsequence/relayer@1.2.1 + - @0xsequence/signhub@1.2.1 + - @0xsequence/utils@1.2.1 + +## 1.2.0 + +### Minor Changes + +- split services from session, better local support + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.2.0 + - @0xsequence/core@1.2.0 + - @0xsequence/network@1.2.0 + - @0xsequence/relayer@1.2.0 + - @0xsequence/signhub@1.2.0 + - @0xsequence/utils@1.2.0 + +## 1.1.15 + +### Patch Changes + +- guard: remove error filtering +- Updated dependencies + - @0xsequence/abi@1.1.15 + - @0xsequence/core@1.1.15 + - @0xsequence/network@1.1.15 + - @0xsequence/relayer@1.1.15 + - @0xsequence/signhub@1.1.15 + - @0xsequence/utils@1.1.15 + +## 1.1.14 + +### Patch Changes + +- guard: add GuardSigner.onError +- Updated dependencies + - @0xsequence/abi@1.1.14 + - @0xsequence/core@1.1.14 + - @0xsequence/network@1.1.14 + - @0xsequence/relayer@1.1.14 + - @0xsequence/signhub@1.1.14 + - @0xsequence/utils@1.1.14 + +## 1.1.13 + +### Patch Changes + +- provider: pass client version with connect options +- provider: removing large from BannerSize +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.1.13 + - @0xsequence/core@1.1.13 + - @0xsequence/network@1.1.13 + - @0xsequence/relayer@1.1.13 + - @0xsequence/signhub@1.1.13 + - @0xsequence/utils@1.1.13 + +## 1.1.12 + +### Patch Changes + +- provider: adding bannerSize to ConnectOptions +- Updated dependencies + - @0xsequence/abi@1.1.12 + - @0xsequence/core@1.1.12 + - @0xsequence/network@1.1.12 + - @0xsequence/relayer@1.1.12 + - @0xsequence/signhub@1.1.12 + - @0xsequence/utils@1.1.12 + +## 1.1.11 + +### Patch Changes + +- add homeverse configs +- Updated dependencies + - @0xsequence/abi@1.1.11 + - @0xsequence/core@1.1.11 + - @0xsequence/network@1.1.11 + - @0xsequence/relayer@1.1.11 + - @0xsequence/signhub@1.1.11 + - @0xsequence/utils@1.1.11 + +## 1.1.10 + +### Patch Changes + +- handle default EIP6492 on send +- Updated dependencies + - @0xsequence/abi@1.1.10 + - @0xsequence/core@1.1.10 + - @0xsequence/network@1.1.10 + - @0xsequence/relayer@1.1.10 + - @0xsequence/signhub@1.1.10 + - @0xsequence/utils@1.1.10 + +## 1.1.9 + +### Patch Changes + +- Custom default EIP6492 on client +- Updated dependencies + - @0xsequence/abi@1.1.9 + - @0xsequence/core@1.1.9 + - @0xsequence/network@1.1.9 + - @0xsequence/relayer@1.1.9 + - @0xsequence/signhub@1.1.9 + - @0xsequence/utils@1.1.9 + +## 1.1.8 + +### Patch Changes + +- metadata: searchMetadata: add types filter +- Updated dependencies + - @0xsequence/abi@1.1.8 + - @0xsequence/core@1.1.8 + - @0xsequence/network@1.1.8 + - @0xsequence/relayer@1.1.8 + - @0xsequence/signhub@1.1.8 + - @0xsequence/utils@1.1.8 + +## 1.1.7 + +### Patch Changes + +- adding signInWith connect settings option to allow dapps to automatically login their users with a certain provider optimizing the normal authentication flow +- Updated dependencies + - @0xsequence/abi@1.1.7 + - @0xsequence/core@1.1.7 + - @0xsequence/network@1.1.7 + - @0xsequence/relayer@1.1.7 + - @0xsequence/signhub@1.1.7 + - @0xsequence/utils@1.1.7 + +## 1.1.6 + +### Patch Changes + +- metadata: searchMetadata: add chainID and excludeTokenMetadata filters +- Updated dependencies + - @0xsequence/abi@1.1.6 + - @0xsequence/core@1.1.6 + - @0xsequence/network@1.1.6 + - @0xsequence/relayer@1.1.6 + - @0xsequence/signhub@1.1.6 + - @0xsequence/utils@1.1.6 + +## 1.1.5 + +### Patch Changes + +- account: re-compute meta-transaction id for wallet deployment transactions +- Updated dependencies + - @0xsequence/abi@1.1.5 + - @0xsequence/core@1.1.5 + - @0xsequence/network@1.1.5 + - @0xsequence/relayer@1.1.5 + - @0xsequence/signhub@1.1.5 + - @0xsequence/utils@1.1.5 + +## 1.1.4 + +### Patch Changes + +- network: rename base-mainnet to base +- provider: override isDefaultChain with ConnectOptions.networkId if provided +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.1.4 + - @0xsequence/core@1.1.4 + - @0xsequence/network@1.1.4 + - @0xsequence/relayer@1.1.4 + - @0xsequence/signhub@1.1.4 + - @0xsequence/utils@1.1.4 + +## 1.1.3 + +### Patch Changes + +- provider: use network id from transport session +- provider: sign authorization using ConnectOptions.networkId if provided +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.1.3 + - @0xsequence/core@1.1.3 + - @0xsequence/network@1.1.3 + - @0xsequence/relayer@1.1.3 + - @0xsequence/signhub@1.1.3 + - @0xsequence/utils@1.1.3 + +## 1.1.2 + +### Patch Changes + +- provider: jsonrpc chain id fixes +- Updated dependencies + - @0xsequence/abi@1.1.2 + - @0xsequence/core@1.1.2 + - @0xsequence/network@1.1.2 + - @0xsequence/relayer@1.1.2 + - @0xsequence/signhub@1.1.2 + - @0xsequence/utils@1.1.2 + +## 1.1.1 + +### Patch Changes + +- network: add base mainnet and sepolia +- provider: reject toxic transaction requests +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.1.1 + - @0xsequence/core@1.1.1 + - @0xsequence/network@1.1.1 + - @0xsequence/relayer@1.1.1 + - @0xsequence/signhub@1.1.1 + - @0xsequence/utils@1.1.1 + +## 1.1.0 + +### Minor Changes + +- Refactor dapp facing provider + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.1.0 + - @0xsequence/core@1.1.0 + - @0xsequence/network@1.1.0 + - @0xsequence/relayer@1.1.0 + - @0xsequence/signhub@1.1.0 + - @0xsequence/utils@1.1.0 + +## 1.0.5 + +### Patch Changes + +- network: export network constants +- guard: use the correct global for fetch +- network: nova-explorer.arbitrum.io -> nova.arbiscan.io +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@1.0.5 + - @0xsequence/core@1.0.5 + - @0xsequence/network@1.0.5 + - @0xsequence/relayer@1.0.5 + - @0xsequence/signhub@1.0.5 + - @0xsequence/utils@1.0.5 + +## 1.0.4 + +### Patch Changes + +- provider: accept name or number for networkId +- Updated dependencies + - @0xsequence/abi@1.0.4 + - @0xsequence/core@1.0.4 + - @0xsequence/guard@1.0.4 + - @0xsequence/network@1.0.4 + - @0xsequence/relayer@1.0.4 + - @0xsequence/signhub@1.0.4 + - @0xsequence/utils@1.0.4 + +## 1.0.3 + +### Patch Changes + +- Simpler isValidSignature helpers +- Updated dependencies + - @0xsequence/abi@1.0.3 + - @0xsequence/core@1.0.3 + - @0xsequence/guard@1.0.3 + - @0xsequence/network@1.0.3 + - @0xsequence/relayer@1.0.3 + - @0xsequence/signhub@1.0.3 + - @0xsequence/utils@1.0.3 + +## 1.0.2 + +### Patch Changes + +- add extra signature validation utils methods +- Updated dependencies + - @0xsequence/abi@1.0.2 + - @0xsequence/core@1.0.2 + - @0xsequence/guard@1.0.2 + - @0xsequence/network@1.0.2 + - @0xsequence/relayer@1.0.2 + - @0xsequence/signhub@1.0.2 + - @0xsequence/utils@1.0.2 + +## 1.0.1 + +### Patch Changes + +- add homeverse testnet +- Updated dependencies + - @0xsequence/abi@1.0.1 + - @0xsequence/core@1.0.1 + - @0xsequence/guard@1.0.1 + - @0xsequence/network@1.0.1 + - @0xsequence/relayer@1.0.1 + - @0xsequence/signhub@1.0.1 + - @0xsequence/utils@1.0.1 + +## 1.0.0 + +### Major Changes + +- https://sequence.xyz/blog/sequence-wallet-light-state-sync-full-merkle-wallets + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@1.0.0 + - @0xsequence/core@1.0.0 + - @0xsequence/guard@1.0.0 + - @0xsequence/network@1.0.0 + - @0xsequence/relayer@1.0.0 + - @0xsequence/signhub@1.0.0 + - @0xsequence/utils@1.0.0 + +## 0.43.34 + +### Patch Changes + +- auth: no jwt for indexer +- Updated dependencies + - @0xsequence/abi@0.43.34 + - @0xsequence/config@0.43.34 + - @0xsequence/guard@0.43.34 + - @0xsequence/network@0.43.34 + - @0xsequence/relayer@0.43.34 + - @0xsequence/transactions@0.43.34 + - @0xsequence/utils@0.43.34 + +## 0.43.33 + +### Patch Changes + +- Adding onConnectOptionsChange handler to WalletRequestHandler +- Updated dependencies + - @0xsequence/abi@0.43.33 + - @0xsequence/config@0.43.33 + - @0xsequence/guard@0.43.33 + - @0xsequence/network@0.43.33 + - @0xsequence/relayer@0.43.33 + - @0xsequence/transactions@0.43.33 + - @0xsequence/utils@0.43.33 + +## 0.43.32 + +### Patch Changes + +- add Base Goerli network +- Updated dependencies + - @0xsequence/abi@0.43.32 + - @0xsequence/config@0.43.32 + - @0xsequence/guard@0.43.32 + - @0xsequence/network@0.43.32 + - @0xsequence/relayer@0.43.32 + - @0xsequence/transactions@0.43.32 + - @0xsequence/utils@0.43.32 + +## 0.43.31 + +### Patch Changes + +- remove AuxDataProvider, add promptSignInConnect +- Updated dependencies + - @0xsequence/abi@0.43.31 + - @0xsequence/config@0.43.31 + - @0xsequence/guard@0.43.31 + - @0xsequence/network@0.43.31 + - @0xsequence/relayer@0.43.31 + - @0xsequence/transactions@0.43.31 + - @0xsequence/utils@0.43.31 + +## 0.43.30 + +### Patch Changes + +- add arbitrum goerli testnet +- Updated dependencies + - @0xsequence/abi@0.43.30 + - @0xsequence/config@0.43.30 + - @0xsequence/guard@0.43.30 + - @0xsequence/network@0.43.30 + - @0xsequence/relayer@0.43.30 + - @0xsequence/transactions@0.43.30 + - @0xsequence/utils@0.43.30 + +## 0.43.29 + +### Patch Changes + +- provider: check availability of window object +- Updated dependencies + - @0xsequence/abi@0.43.29 + - @0xsequence/config@0.43.29 + - @0xsequence/guard@0.43.29 + - @0xsequence/network@0.43.29 + - @0xsequence/relayer@0.43.29 + - @0xsequence/transactions@0.43.29 + - @0xsequence/utils@0.43.29 + +## 0.43.28 + +### Patch Changes + +- update api bindings +- Updated dependencies + - @0xsequence/abi@0.43.28 + - @0xsequence/config@0.43.28 + - @0xsequence/guard@0.43.28 + - @0xsequence/network@0.43.28 + - @0xsequence/relayer@0.43.28 + - @0xsequence/transactions@0.43.28 + - @0xsequence/utils@0.43.28 + +## 0.43.27 + +### Patch Changes + +- Add rpc is sequence method +- Updated dependencies + - @0xsequence/abi@0.43.27 + - @0xsequence/config@0.43.27 + - @0xsequence/guard@0.43.27 + - @0xsequence/network@0.43.27 + - @0xsequence/relayer@0.43.27 + - @0xsequence/transactions@0.43.27 + - @0xsequence/utils@0.43.27 + +## 0.43.26 + +### Patch Changes + +- add zkevm url to enum +- Updated dependencies + - @0xsequence/abi@0.43.26 + - @0xsequence/config@0.43.26 + - @0xsequence/guard@0.43.26 + - @0xsequence/network@0.43.26 + - @0xsequence/relayer@0.43.26 + - @0xsequence/transactions@0.43.26 + - @0xsequence/utils@0.43.26 + +## 0.43.25 + +### Patch Changes + +- added polygon zkevm to mainnet networks +- Updated dependencies + - @0xsequence/abi@0.43.25 + - @0xsequence/config@0.43.25 + - @0xsequence/guard@0.43.25 + - @0xsequence/network@0.43.25 + - @0xsequence/relayer@0.43.25 + - @0xsequence/transactions@0.43.25 + - @0xsequence/utils@0.43.25 + +## 0.43.24 + +### Patch Changes + +- name change from zkevm to polygon-zkevm +- Updated dependencies + - @0xsequence/abi@0.43.24 + - @0xsequence/config@0.43.24 + - @0xsequence/guard@0.43.24 + - @0xsequence/network@0.43.24 + - @0xsequence/relayer@0.43.24 + - @0xsequence/transactions@0.43.24 + - @0xsequence/utils@0.43.24 + +## 0.43.23 + +### Patch Changes + +- update zkEVM name to Polygon zkEVM +- Updated dependencies + - @0xsequence/abi@0.43.23 + - @0xsequence/config@0.43.23 + - @0xsequence/guard@0.43.23 + - @0xsequence/network@0.43.23 + - @0xsequence/relayer@0.43.23 + - @0xsequence/transactions@0.43.23 + - @0xsequence/utils@0.43.23 + +## 0.43.22 + +### Patch Changes + +- add zkevm chain +- Updated dependencies + - @0xsequence/abi@0.43.22 + - @0xsequence/config@0.43.22 + - @0xsequence/guard@0.43.22 + - @0xsequence/network@0.43.22 + - @0xsequence/relayer@0.43.22 + - @0xsequence/transactions@0.43.22 + - @0xsequence/utils@0.43.22 + +## 0.43.21 + +### Patch Changes + +- api: update client bindings +- Updated dependencies + - @0xsequence/abi@0.43.21 + - @0xsequence/config@0.43.21 + - @0xsequence/guard@0.43.21 + - @0xsequence/network@0.43.21 + - @0xsequence/relayer@0.43.21 + - @0xsequence/transactions@0.43.21 + - @0xsequence/utils@0.43.21 + +## 0.43.20 + +### Patch Changes + +- indexer: update bindings +- Updated dependencies + - @0xsequence/abi@0.43.20 + - @0xsequence/config@0.43.20 + - @0xsequence/guard@0.43.20 + - @0xsequence/network@0.43.20 + - @0xsequence/relayer@0.43.20 + - @0xsequence/transactions@0.43.20 + - @0xsequence/utils@0.43.20 + +## 0.43.19 + +### Patch Changes + +- session proof update +- Updated dependencies + - @0xsequence/abi@0.43.19 + - @0xsequence/config@0.43.19 + - @0xsequence/guard@0.43.19 + - @0xsequence/network@0.43.19 + - @0xsequence/relayer@0.43.19 + - @0xsequence/transactions@0.43.19 + - @0xsequence/utils@0.43.19 + +## 0.43.18 + +### Patch Changes + +- rpc client global check, hardening +- Updated dependencies + - @0xsequence/abi@0.43.18 + - @0xsequence/config@0.43.18 + - @0xsequence/guard@0.43.18 + - @0xsequence/network@0.43.18 + - @0xsequence/relayer@0.43.18 + - @0xsequence/transactions@0.43.18 + - @0xsequence/utils@0.43.18 + +## 0.43.17 + +### Patch Changes + +- rpc clients, check of 'global' is defined +- Updated dependencies + - @0xsequence/abi@0.43.17 + - @0xsequence/config@0.43.17 + - @0xsequence/guard@0.43.17 + - @0xsequence/network@0.43.17 + - @0xsequence/relayer@0.43.17 + - @0xsequence/transactions@0.43.17 + - @0xsequence/utils@0.43.17 + +## 0.43.16 + +### Patch Changes + +- ethers peerDep to v5, update rpc client global use +- Updated dependencies + - @0xsequence/abi@0.43.16 + - @0xsequence/config@0.43.16 + - @0xsequence/guard@0.43.16 + - @0xsequence/network@0.43.16 + - @0xsequence/relayer@0.43.16 + - @0xsequence/transactions@0.43.16 + - @0xsequence/utils@0.43.16 + +## 0.43.15 + +### Patch Changes + +- - provider: expand receiver type on some util methods +- Updated dependencies + - @0xsequence/abi@0.43.15 + - @0xsequence/config@0.43.15 + - @0xsequence/guard@0.43.15 + - @0xsequence/network@0.43.15 + - @0xsequence/relayer@0.43.15 + - @0xsequence/transactions@0.43.15 + - @0xsequence/utils@0.43.15 + +## 0.43.14 + +### Patch Changes + +- bump +- Updated dependencies + - @0xsequence/abi@0.43.14 + - @0xsequence/config@0.43.14 + - @0xsequence/guard@0.43.14 + - @0xsequence/network@0.43.14 + - @0xsequence/relayer@0.43.14 + - @0xsequence/transactions@0.43.14 + - @0xsequence/utils@0.43.14 + +## 0.43.13 + +### Patch Changes + +- update rpc bindings +- Updated dependencies + - @0xsequence/abi@0.43.13 + - @0xsequence/config@0.43.13 + - @0xsequence/guard@0.43.13 + - @0xsequence/network@0.43.13 + - @0xsequence/relayer@0.43.13 + - @0xsequence/transactions@0.43.13 + - @0xsequence/utils@0.43.13 + +## 0.43.12 + +### Patch Changes + +- provider: single wallet init, and add new unregisterWallet() method +- Updated dependencies + - @0xsequence/abi@0.43.12 + - @0xsequence/config@0.43.12 + - @0xsequence/guard@0.43.12 + - @0xsequence/network@0.43.12 + - @0xsequence/relayer@0.43.12 + - @0xsequence/transactions@0.43.12 + - @0xsequence/utils@0.43.12 + +## 0.43.11 + +### Patch Changes + +- fix lockfiles +- re-add mocha type deleter +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.43.11 + - @0xsequence/config@0.43.11 + - @0xsequence/guard@0.43.11 + - @0xsequence/network@0.43.11 + - @0xsequence/relayer@0.43.11 + - @0xsequence/transactions@0.43.11 + - @0xsequence/utils@0.43.11 + +## 0.43.10 + +### Patch Changes + +- various improvements +- Updated dependencies + - @0xsequence/abi@0.43.10 + - @0xsequence/config@0.43.10 + - @0xsequence/guard@0.43.10 + - @0xsequence/network@0.43.10 + - @0xsequence/relayer@0.43.10 + - @0xsequence/transactions@0.43.10 + - @0xsequence/utils@0.43.10 + +## 0.43.9 + +### Patch Changes + +- update deps +- Updated dependencies + - @0xsequence/abi@0.43.9 + - @0xsequence/config@0.43.9 + - @0xsequence/guard@0.43.9 + - @0xsequence/network@0.43.9 + - @0xsequence/relayer@0.43.9 + - @0xsequence/transactions@0.43.9 + - @0xsequence/utils@0.43.9 + +## 0.43.8 + +### Patch Changes + +- network: JsonRpcProvider with caching +- Updated dependencies + - @0xsequence/abi@0.43.8 + - @0xsequence/config@0.43.8 + - @0xsequence/guard@0.43.8 + - @0xsequence/network@0.43.8 + - @0xsequence/relayer@0.43.8 + - @0xsequence/transactions@0.43.8 + - @0xsequence/utils@0.43.8 + +## 0.43.7 + +### Patch Changes + +- provider: fix wallet network init +- Updated dependencies + - @0xsequence/abi@0.43.7 + - @0xsequence/config@0.43.7 + - @0xsequence/guard@0.43.7 + - @0xsequence/network@0.43.7 + - @0xsequence/relayer@0.43.7 + - @0xsequence/transactions@0.43.7 + - @0xsequence/utils@0.43.7 + +## 0.43.6 + +### Patch Changes + +- metadatata: update rpc bindings +- Updated dependencies + - @0xsequence/abi@0.43.6 + - @0xsequence/config@0.43.6 + - @0xsequence/guard@0.43.6 + - @0xsequence/network@0.43.6 + - @0xsequence/relayer@0.43.6 + - @0xsequence/transactions@0.43.6 + - @0xsequence/utils@0.43.6 + +## 0.43.5 + +### Patch Changes + +- provider: do not set default network for connect messages +- provider: forward missing error message +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.43.5 + - @0xsequence/config@0.43.5 + - @0xsequence/guard@0.43.5 + - @0xsequence/network@0.43.5 + - @0xsequence/relayer@0.43.5 + - @0xsequence/transactions@0.43.5 + - @0xsequence/utils@0.43.5 + +## 0.43.4 + +### Patch Changes + +- no-change version bump to fix incorrectly tagged snapshot build +- Updated dependencies + - @0xsequence/abi@0.43.4 + - @0xsequence/config@0.43.4 + - @0xsequence/guard@0.43.4 + - @0xsequence/network@0.43.4 + - @0xsequence/relayer@0.43.4 + - @0xsequence/transactions@0.43.4 + - @0xsequence/utils@0.43.4 + +## 0.43.3 + +### Patch Changes + +- metadata: update bindings +- Updated dependencies + - @0xsequence/abi@0.43.3 + - @0xsequence/config@0.43.3 + - @0xsequence/guard@0.43.3 + - @0xsequence/network@0.43.3 + - @0xsequence/relayer@0.43.3 + - @0xsequence/transactions@0.43.3 + - @0xsequence/utils@0.43.3 + +## 0.43.2 + +### Patch Changes + +- provider: implement connectUnchecked +- Updated dependencies + - @0xsequence/abi@0.43.2 + - @0xsequence/config@0.43.2 + - @0xsequence/guard@0.43.2 + - @0xsequence/network@0.43.2 + - @0xsequence/relayer@0.43.2 + - @0xsequence/transactions@0.43.2 + - @0xsequence/utils@0.43.2 + +## 0.43.1 + +### Patch Changes + +- update to latest ethauth dep +- Updated dependencies + - @0xsequence/abi@0.43.1 + - @0xsequence/config@0.43.1 + - @0xsequence/guard@0.43.1 + - @0xsequence/network@0.43.1 + - @0xsequence/relayer@0.43.1 + - @0xsequence/transactions@0.43.1 + - @0xsequence/utils@0.43.1 + +## 0.43.0 + +### Minor Changes + +- move ethers to a peer dependency + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.43.0 + - @0xsequence/config@0.43.0 + - @0xsequence/guard@0.43.0 + - @0xsequence/network@0.43.0 + - @0xsequence/relayer@0.43.0 + - @0xsequence/transactions@0.43.0 + - @0xsequence/utils@0.43.0 + +## 0.42.10 + +### Patch Changes + +- add auxDataProvider +- Updated dependencies + - @0xsequence/abi@0.42.10 + - @0xsequence/config@0.42.10 + - @0xsequence/guard@0.42.10 + - @0xsequence/network@0.42.10 + - @0xsequence/relayer@0.42.10 + - @0xsequence/transactions@0.42.10 + - @0xsequence/utils@0.42.10 + +## 0.42.9 + +### Patch Changes + +- provider: add eip-191 exceptions +- Updated dependencies + - @0xsequence/abi@0.42.9 + - @0xsequence/config@0.42.9 + - @0xsequence/guard@0.42.9 + - @0xsequence/network@0.42.9 + - @0xsequence/relayer@0.42.9 + - @0xsequence/transactions@0.42.9 + - @0xsequence/utils@0.42.9 + +## 0.42.8 + +### Patch Changes + +- provider: skip setting intent origin if we're unity plugin +- Updated dependencies + - @0xsequence/abi@0.42.8 + - @0xsequence/config@0.42.8 + - @0xsequence/guard@0.42.8 + - @0xsequence/network@0.42.8 + - @0xsequence/relayer@0.42.8 + - @0xsequence/transactions@0.42.8 + - @0xsequence/utils@0.42.8 + +## 0.42.7 + +### Patch Changes + +- Add sign in options to connection settings +- Updated dependencies + - @0xsequence/abi@0.42.7 + - @0xsequence/config@0.42.7 + - @0xsequence/guard@0.42.7 + - @0xsequence/network@0.42.7 + - @0xsequence/relayer@0.42.7 + - @0xsequence/transactions@0.42.7 + - @0xsequence/utils@0.42.7 + +## 0.42.6 + +### Patch Changes + +- api bindings update +- Updated dependencies + - @0xsequence/abi@0.42.6 + - @0xsequence/config@0.42.6 + - @0xsequence/guard@0.42.6 + - @0xsequence/network@0.42.6 + - @0xsequence/relayer@0.42.6 + - @0xsequence/transactions@0.42.6 + - @0xsequence/utils@0.42.6 + +## 0.42.5 + +### Patch Changes + +- relayer: don't treat missing receipt as hard failure +- Updated dependencies + - @0xsequence/abi@0.42.5 + - @0xsequence/config@0.42.5 + - @0xsequence/guard@0.42.5 + - @0xsequence/network@0.42.5 + - @0xsequence/relayer@0.42.5 + - @0xsequence/transactions@0.42.5 + - @0xsequence/utils@0.42.5 + +## 0.42.4 + +### Patch Changes + +- provider: add custom app protocol to connect options +- Updated dependencies + - @0xsequence/abi@0.42.4 + - @0xsequence/config@0.42.4 + - @0xsequence/guard@0.42.4 + - @0xsequence/network@0.42.4 + - @0xsequence/relayer@0.42.4 + - @0xsequence/transactions@0.42.4 + - @0xsequence/utils@0.42.4 + +## 0.42.3 + +### Patch Changes + +- update api bindings +- Updated dependencies + - @0xsequence/abi@0.42.3 + - @0xsequence/config@0.42.3 + - @0xsequence/guard@0.42.3 + - @0xsequence/network@0.42.3 + - @0xsequence/relayer@0.42.3 + - @0xsequence/transactions@0.42.3 + - @0xsequence/utils@0.42.3 + +## 0.42.2 + +### Patch Changes + +- disable rinkeby network +- Updated dependencies + - @0xsequence/abi@0.42.2 + - @0xsequence/config@0.42.2 + - @0xsequence/guard@0.42.2 + - @0xsequence/network@0.42.2 + - @0xsequence/relayer@0.42.2 + - @0xsequence/transactions@0.42.2 + - @0xsequence/utils@0.42.2 + +## 0.42.1 + +### Patch Changes + +- wallet: optional waitForReceipt parameter +- Updated dependencies + - @0xsequence/abi@0.42.1 + - @0xsequence/config@0.42.1 + - @0xsequence/guard@0.42.1 + - @0xsequence/network@0.42.1 + - @0xsequence/relayer@0.42.1 + - @0xsequence/transactions@0.42.1 + - @0xsequence/utils@0.42.1 + +## 0.42.0 + +### Minor Changes + +- relayer: estimateGasLimits -> simulate +- add simulator package + +### Patch Changes + +- transactions: fix flattenAuxTransactions +- provider: only filter nullish values +- provider: re-map transaction 'gas' back to 'gasLimit' +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.42.0 + - @0xsequence/config@0.42.0 + - @0xsequence/guard@0.42.0 + - @0xsequence/network@0.42.0 + - @0xsequence/relayer@0.42.0 + - @0xsequence/transactions@0.42.0 + - @0xsequence/utils@0.42.0 + +## 0.41.3 + +### Patch Changes + +- api bindings update +- Updated dependencies + - @0xsequence/abi@0.41.3 + - @0xsequence/config@0.41.3 + - @0xsequence/guard@0.41.3 + - @0xsequence/network@0.41.3 + - @0xsequence/relayer@0.41.3 + - @0xsequence/transactions@0.41.3 + - @0xsequence/utils@0.41.3 + +## 0.41.2 + +### Patch Changes + +- api bindings update +- Updated dependencies + - @0xsequence/abi@0.41.2 + - @0xsequence/config@0.41.2 + - @0xsequence/guard@0.41.2 + - @0xsequence/network@0.41.2 + - @0xsequence/relayer@0.41.2 + - @0xsequence/transactions@0.41.2 + - @0xsequence/utils@0.41.2 + +## 0.41.1 + +### Patch Changes + +- update default networks +- Updated dependencies + - @0xsequence/abi@0.41.1 + - @0xsequence/config@0.41.1 + - @0xsequence/guard@0.41.1 + - @0xsequence/network@0.41.1 + - @0xsequence/relayer@0.41.1 + - @0xsequence/transactions@0.41.1 + - @0xsequence/utils@0.41.1 + +## 0.41.0 + +### Minor Changes + +- relayer: fix Relayer.wait() interface + + The interface for calling Relayer.wait() has changed. Instead of a single optional ill-defined timeout/delay parameter, there are three optional parameters, in order: + + - timeout: the maximum time to wait for the transaction receipt + - delay: the polling interval, i.e. the time to wait between requests + - maxFails: the maximum number of hard failures to tolerate before giving up + + Please update your codebase accordingly. + +- relayer: add optional waitForReceipt parameter to Relayer.relay + + The behaviour of Relayer.relay() was not well-defined with respect to whether or not it waited for a receipt. + This change allows the caller to specify whether to wait or not, with the default behaviour being to wait. + +### Patch Changes + +- relayer: wait receipt retry logic +- fix wrapped object error +- provider: forward delegateCall and revertOnError transaction fields +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.41.0 + - @0xsequence/config@0.41.0 + - @0xsequence/guard@0.41.0 + - @0xsequence/network@0.41.0 + - @0xsequence/relayer@0.41.0 + - @0xsequence/transactions@0.41.0 + - @0xsequence/utils@0.41.0 + +## 0.40.6 + +### Patch Changes + +- add arbitrum-nova chain +- Updated dependencies + - @0xsequence/abi@0.40.6 + - @0xsequence/config@0.40.6 + - @0xsequence/guard@0.40.6 + - @0xsequence/network@0.40.6 + - @0xsequence/relayer@0.40.6 + - @0xsequence/transactions@0.40.6 + - @0xsequence/utils@0.40.6 + +## 0.40.5 + +### Patch Changes + +- api: update bindings +- Updated dependencies + - @0xsequence/abi@0.40.5 + - @0xsequence/config@0.40.5 + - @0xsequence/guard@0.40.5 + - @0xsequence/network@0.40.5 + - @0xsequence/relayer@0.40.5 + - @0xsequence/transactions@0.40.5 + - @0xsequence/utils@0.40.5 + +## 0.40.4 + +### Patch Changes + +- add unreal transport +- Updated dependencies + - @0xsequence/abi@0.40.4 + - @0xsequence/config@0.40.4 + - @0xsequence/guard@0.40.4 + - @0xsequence/network@0.40.4 + - @0xsequence/relayer@0.40.4 + - @0xsequence/transactions@0.40.4 + - @0xsequence/utils@0.40.4 + +## 0.40.3 + +### Patch Changes + +- provider: fix MessageToSign message type +- Updated dependencies + - @0xsequence/abi@0.40.3 + - @0xsequence/config@0.40.3 + - @0xsequence/guard@0.40.3 + - @0xsequence/network@0.40.3 + - @0xsequence/relayer@0.40.3 + - @0xsequence/transactions@0.40.3 + - @0xsequence/utils@0.40.3 + +## 0.40.2 + +### Patch Changes + +- Wallet provider, loadSession method +- Updated dependencies + - @0xsequence/abi@0.40.2 + - @0xsequence/config@0.40.2 + - @0xsequence/guard@0.40.2 + - @0xsequence/network@0.40.2 + - @0xsequence/relayer@0.40.2 + - @0xsequence/transactions@0.40.2 + - @0xsequence/utils@0.40.2 + +## 0.40.1 + +### Patch Changes + +- export sequence.initWallet and sequence.getWallet +- Updated dependencies + - @0xsequence/abi@0.40.1 + - @0xsequence/config@0.40.1 + - @0xsequence/guard@0.40.1 + - @0xsequence/network@0.40.1 + - @0xsequence/relayer@0.40.1 + - @0xsequence/transactions@0.40.1 + - @0xsequence/utils@0.40.1 + +## 0.40.0 + +### Minor Changes + +- add sequence.initWallet(network, config) and sequence.getWallet() helper methods + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.40.0 + - @0xsequence/config@0.40.0 + - @0xsequence/guard@0.40.0 + - @0xsequence/network@0.40.0 + - @0xsequence/relayer@0.40.0 + - @0xsequence/transactions@0.40.0 + - @0xsequence/utils@0.40.0 + +## 0.39.6 + +### Patch Changes + +- indexer: update client bindings +- Updated dependencies + - @0xsequence/abi@0.39.6 + - @0xsequence/config@0.39.6 + - @0xsequence/guard@0.39.6 + - @0xsequence/network@0.39.6 + - @0xsequence/relayer@0.39.6 + - @0xsequence/transactions@0.39.6 + - @0xsequence/utils@0.39.6 + +## 0.39.5 + +### Patch Changes + +- provider: fix networkRpcUrl config option +- Updated dependencies + - @0xsequence/abi@0.39.5 + - @0xsequence/config@0.39.5 + - @0xsequence/guard@0.39.5 + - @0xsequence/network@0.39.5 + - @0xsequence/relayer@0.39.5 + - @0xsequence/transactions@0.39.5 + - @0xsequence/utils@0.39.5 + +## 0.39.4 + +### Patch Changes + +- api: update client bindings +- Updated dependencies + - @0xsequence/abi@0.39.4 + - @0xsequence/config@0.39.4 + - @0xsequence/guard@0.39.4 + - @0xsequence/network@0.39.4 + - @0xsequence/relayer@0.39.4 + - @0xsequence/transactions@0.39.4 + - @0xsequence/utils@0.39.4 + +## 0.39.3 + +### Patch Changes + +- add request method on Web3Provider +- Updated dependencies + - @0xsequence/abi@0.39.3 + - @0xsequence/config@0.39.3 + - @0xsequence/guard@0.39.3 + - @0xsequence/network@0.39.3 + - @0xsequence/relayer@0.39.3 + - @0xsequence/transactions@0.39.3 + - @0xsequence/utils@0.39.3 + +## 0.39.2 + +### Patch Changes + +- update umd name +- Updated dependencies + - @0xsequence/abi@0.39.2 + - @0xsequence/config@0.39.2 + - @0xsequence/guard@0.39.2 + - @0xsequence/network@0.39.2 + - @0xsequence/relayer@0.39.2 + - @0xsequence/transactions@0.39.2 + - @0xsequence/utils@0.39.2 + +## 0.39.1 + +### Patch Changes + +- add Aurora network +- add origin info for accountsChanged event to handle it per dapp +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.39.1 + - @0xsequence/config@0.39.1 + - @0xsequence/guard@0.39.1 + - @0xsequence/network@0.39.1 + - @0xsequence/relayer@0.39.1 + - @0xsequence/transactions@0.39.1 + - @0xsequence/utils@0.39.1 + +## 0.39.0 + +### Minor Changes + +- abstract window.localStorage to interface type + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.39.0 + - @0xsequence/config@0.39.0 + - @0xsequence/guard@0.39.0 + - @0xsequence/network@0.39.0 + - @0xsequence/relayer@0.39.0 + - @0xsequence/transactions@0.39.0 + - @0xsequence/utils@0.39.0 + +## 0.38.2 + +### Patch Changes + +- provider: add Settings.defaultPurchaseAmount +- Updated dependencies + - @0xsequence/abi@0.38.2 + - @0xsequence/config@0.38.2 + - @0xsequence/guard@0.38.2 + - @0xsequence/network@0.38.2 + - @0xsequence/relayer@0.38.2 + - @0xsequence/transactions@0.38.2 + - @0xsequence/utils@0.38.2 + +## 0.38.1 + +### Patch Changes + +- update api and metadata rpc bindings +- Updated dependencies + - @0xsequence/abi@0.38.1 + - @0xsequence/config@0.38.1 + - @0xsequence/guard@0.38.1 + - @0xsequence/network@0.38.1 + - @0xsequence/relayer@0.38.1 + - @0xsequence/transactions@0.38.1 + - @0xsequence/utils@0.38.1 + +## 0.38.0 + +### Minor Changes + +- api: update bindings, change TokenPrice interface +- bridge: remove @0xsequence/bridge package +- api: update bindings, rename ContractCallArg to TupleComponent + +### Patch Changes + +- Updated dependencies +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.38.0 + - @0xsequence/config@0.38.0 + - @0xsequence/guard@0.38.0 + - @0xsequence/network@0.38.0 + - @0xsequence/relayer@0.38.0 + - @0xsequence/transactions@0.38.0 + - @0xsequence/utils@0.38.0 + +## 0.37.1 + +### Patch Changes + +- Add back sortNetworks - Removing sorting was a breaking change for dapps on older versions which directly integrate sequence. +- Updated dependencies + - @0xsequence/abi@0.37.1 + - @0xsequence/config@0.37.1 + - @0xsequence/guard@0.37.1 + - @0xsequence/network@0.37.1 + - @0xsequence/relayer@0.37.1 + - @0xsequence/transactions@0.37.1 + - @0xsequence/utils@0.37.1 + +## 0.37.0 + +### Minor Changes + +- network related fixes and improvements +- api: bindings: exchange rate lookups + +### Patch Changes + +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.37.0 + - @0xsequence/config@0.37.0 + - @0xsequence/guard@0.37.0 + - @0xsequence/network@0.37.0 + - @0xsequence/relayer@0.37.0 + - @0xsequence/transactions@0.37.0 + - @0xsequence/utils@0.37.0 + +## 0.36.13 + +### Patch Changes + +- api: update bindings with new price endpoints +- Updated dependencies + - @0xsequence/abi@0.36.13 + - @0xsequence/config@0.36.13 + - @0xsequence/guard@0.36.13 + - @0xsequence/network@0.36.13 + - @0xsequence/relayer@0.36.13 + - @0xsequence/transactions@0.36.13 + - @0xsequence/utils@0.36.13 + +## 0.36.12 + +### Patch Changes + +- wallet: skip remote signers if not needed +- auth: check that signature meets threshold before requesting auth token +- Updated dependencies +- Updated dependencies + - @0xsequence/abi@0.36.12 + - @0xsequence/config@0.36.12 + - @0xsequence/guard@0.36.12 + - @0xsequence/network@0.36.12 + - @0xsequence/relayer@0.36.12 + - @0xsequence/transactions@0.36.12 + - @0xsequence/utils@0.36.12 + +## 0.36.11 + +### Patch Changes + +- Prefix EIP191 message on wallet-request-handler +- Updated dependencies + - @0xsequence/abi@0.36.11 + - @0xsequence/config@0.36.11 + - @0xsequence/guard@0.36.11 + - @0xsequence/network@0.36.11 + - @0xsequence/relayer@0.36.11 + - @0xsequence/transactions@0.36.11 + - @0xsequence/utils@0.36.11 + +## 0.36.10 + +### Patch Changes + +- support bannerUrl on connect +- Updated dependencies + - @0xsequence/abi@0.36.10 + - @0xsequence/config@0.36.10 + - @0xsequence/guard@0.36.10 + - @0xsequence/network@0.36.10 + - @0xsequence/relayer@0.36.10 + - @0xsequence/transactions@0.36.10 + - @0xsequence/utils@0.36.10 + +## 0.36.9 + +### Patch Changes + +- minor dev xp improvements +- Updated dependencies + - @0xsequence/abi@0.36.9 + - @0xsequence/config@0.36.9 + - @0xsequence/guard@0.36.9 + - @0xsequence/network@0.36.9 + - @0xsequence/relayer@0.36.9 + - @0xsequence/transactions@0.36.9 + - @0xsequence/utils@0.36.9 + +## 0.36.8 + +### Patch Changes + +- more connect options (theme, payment providers, funding currencies) +- Updated dependencies + - @0xsequence/abi@0.36.8 + - @0xsequence/config@0.36.8 + - @0xsequence/guard@0.36.8 + - @0xsequence/network@0.36.8 + - @0xsequence/relayer@0.36.8 + - @0xsequence/transactions@0.36.8 + - @0xsequence/utils@0.36.8 + +## 0.36.7 + +### Patch Changes + +- fix missing break +- Updated dependencies + - @0xsequence/abi@0.36.7 + - @0xsequence/config@0.36.7 + - @0xsequence/guard@0.36.7 + - @0xsequence/network@0.36.7 + - @0xsequence/relayer@0.36.7 + - @0xsequence/transactions@0.36.7 + - @0xsequence/utils@0.36.7 + +## 0.36.6 + +### Patch Changes + +- wallet_switchEthereumChain support +- Updated dependencies + - @0xsequence/abi@0.36.6 + - @0xsequence/config@0.36.6 + - @0xsequence/guard@0.36.6 + - @0xsequence/network@0.36.6 + - @0xsequence/relayer@0.36.6 + - @0xsequence/transactions@0.36.6 + - @0xsequence/utils@0.36.6 + +## 0.36.5 + +### Patch Changes + +- auth: bump ethauth to 0.7.0 + network, wallet: don't assume position of auth network in list + api/indexer/metadata: trim trailing slash on hostname, and add endpoint urls + relayer: Allow to specify local relayer transaction parameters like gas price or gas limit +- Updated dependencies + - @0xsequence/abi@0.36.5 + - @0xsequence/config@0.36.5 + - @0xsequence/guard@0.36.5 + - @0xsequence/network@0.36.5 + - @0xsequence/relayer@0.36.5 + - @0xsequence/transactions@0.36.5 + - @0xsequence/utils@0.36.5 + +## 0.36.4 + +### Patch Changes + +- Updating list of chain ids to include other ethereum compatible chains +- Updated dependencies + - @0xsequence/abi@0.36.4 + - @0xsequence/config@0.36.4 + - @0xsequence/guard@0.36.4 + - @0xsequence/network@0.36.4 + - @0xsequence/relayer@0.36.4 + - @0xsequence/transactions@0.36.4 + - @0xsequence/utils@0.36.4 + +## 0.36.3 + +### Patch Changes + +- provider: pass connect options to prompter methods +- Updated dependencies + - @0xsequence/abi@0.36.3 + - @0xsequence/config@0.36.3 + - @0xsequence/guard@0.36.3 + - @0xsequence/network@0.36.3 + - @0xsequence/relayer@0.36.3 + - @0xsequence/transactions@0.36.3 + - @0xsequence/utils@0.36.3 + +## 0.36.2 + +### Patch Changes + +- transactions: Setting target to 0x0 when empty to during SequenceTxAbiEncode +- Updated dependencies + - @0xsequence/abi@0.36.2 + - @0xsequence/config@0.36.2 + - @0xsequence/guard@0.36.2 + - @0xsequence/network@0.36.2 + - @0xsequence/relayer@0.36.2 + - @0xsequence/transactions@0.36.2 + - @0xsequence/utils@0.36.2 + +## 0.36.1 + +### Patch Changes + +- metadata: update client with more fields +- Updated dependencies + - @0xsequence/abi@0.36.1 + - @0xsequence/config@0.36.1 + - @0xsequence/guard@0.36.1 + - @0xsequence/network@0.36.1 + - @0xsequence/relayer@0.36.1 + - @0xsequence/transactions@0.36.1 + - @0xsequence/utils@0.36.1 + +## 0.36.0 + +### Minor Changes + +- relayer, wallet: fee quote support + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.36.0 + - @0xsequence/config@0.36.0 + - @0xsequence/guard@0.36.0 + - @0xsequence/network@0.36.0 + - @0xsequence/relayer@0.36.0 + - @0xsequence/transactions@0.36.0 + - @0xsequence/utils@0.36.0 + +## 0.35.12 + +### Patch Changes + +- provider: rename wallet.commands to wallet.utils +- Updated dependencies + - @0xsequence/abi@0.35.12 + - @0xsequence/config@0.35.12 + - @0xsequence/guard@0.35.12 + - @0xsequence/network@0.35.12 + - @0xsequence/relayer@0.35.12 + - @0xsequence/transactions@0.35.12 + - @0xsequence/utils@0.35.12 + +## 0.35.11 + +### Patch Changes + +- provider/utils: smoother message validation +- Updated dependencies + - @0xsequence/abi@0.35.11 + - @0xsequence/config@0.35.11 + - @0xsequence/guard@0.35.11 + - @0xsequence/network@0.35.11 + - @0xsequence/relayer@0.35.11 + - @0xsequence/transactions@0.35.11 + - @0xsequence/utils@0.35.11 + +## 0.35.10 + +### Patch Changes + +- upgrade deps +- Updated dependencies + - @0xsequence/abi@0.35.10 + - @0xsequence/config@0.35.10 + - @0xsequence/guard@0.35.10 + - @0xsequence/network@0.35.10 + - @0xsequence/relayer@0.35.10 + - @0xsequence/transactions@0.35.10 + - @0xsequence/utils@0.35.10 + +## 0.35.9 + +### Patch Changes + +- provider: window-transport override event handlers with new wallet instance +- Updated dependencies + - @0xsequence/abi@0.35.9 + - @0xsequence/config@0.35.9 + - @0xsequence/guard@0.35.9 + - @0xsequence/network@0.35.9 + - @0xsequence/relayer@0.35.9 + - @0xsequence/transactions@0.35.9 + - @0xsequence/utils@0.35.9 + +## 0.35.8 + +### Patch Changes + +- provider: async wallet sign in improvements +- Updated dependencies + - @0xsequence/abi@0.35.8 + - @0xsequence/config@0.35.8 + - @0xsequence/guard@0.35.8 + - @0xsequence/network@0.35.8 + - @0xsequence/relayer@0.35.8 + - @0xsequence/transactions@0.35.8 + - @0xsequence/utils@0.35.8 + +## 0.35.7 + +### Patch Changes + +- config: cache wallet configs +- Updated dependencies + - @0xsequence/abi@0.35.7 + - @0xsequence/config@0.35.7 + - @0xsequence/guard@0.35.7 + - @0xsequence/network@0.35.7 + - @0xsequence/relayer@0.35.7 + - @0xsequence/transactions@0.35.7 + - @0xsequence/utils@0.35.7 + +## 0.35.6 + +### Patch Changes + +- provider: support async signin of wallet request handler +- Updated dependencies + - @0xsequence/abi@0.35.6 + - @0xsequence/config@0.35.6 + - @0xsequence/guard@0.35.6 + - @0xsequence/network@0.35.6 + - @0xsequence/relayer@0.35.6 + - @0xsequence/transactions@0.35.6 + - @0xsequence/utils@0.35.6 + +## 0.35.5 + +### Patch Changes + +- wallet: skip threshold check during fee estimation +- Updated dependencies + - @0xsequence/abi@0.35.5 + - @0xsequence/config@0.35.5 + - @0xsequence/guard@0.35.5 + - @0xsequence/network@0.35.5 + - @0xsequence/relayer@0.35.5 + - @0xsequence/transactions@0.35.5 + - @0xsequence/utils@0.35.5 + +## 0.35.4 + +### Patch Changes + +- - browser extension mode, center window +- Updated dependencies + - @0xsequence/abi@0.35.4 + - @0xsequence/config@0.35.4 + - @0xsequence/guard@0.35.4 + - @0xsequence/network@0.35.4 + - @0xsequence/relayer@0.35.4 + - @0xsequence/transactions@0.35.4 + - @0xsequence/utils@0.35.4 + +## 0.35.3 + +### Patch Changes + +- - update window position when in browser extension mode +- Updated dependencies + - @0xsequence/abi@0.35.3 + - @0xsequence/config@0.35.3 + - @0xsequence/guard@0.35.3 + - @0xsequence/network@0.35.3 + - @0xsequence/relayer@0.35.3 + - @0xsequence/transactions@0.35.3 + - @0xsequence/utils@0.35.3 + +## 0.35.2 + +### Patch Changes + +- - provider: WindowMessageHandler accept optional windowHref +- Updated dependencies + - @0xsequence/abi@0.35.2 + - @0xsequence/config@0.35.2 + - @0xsequence/guard@0.35.2 + - @0xsequence/network@0.35.2 + - @0xsequence/relayer@0.35.2 + - @0xsequence/transactions@0.35.2 + - @0xsequence/utils@0.35.2 + +## 0.35.1 + +### Patch Changes + +- wallet: update config on undeployed too +- Updated dependencies + - @0xsequence/abi@0.35.1 + - @0xsequence/config@0.35.1 + - @0xsequence/guard@0.35.1 + - @0xsequence/network@0.35.1 + - @0xsequence/relayer@0.35.1 + - @0xsequence/transactions@0.35.1 + - @0xsequence/utils@0.35.1 + +## 0.35.0 + +### Minor Changes + +- - config: add buildStubSignature + - provider: add checks to signing cases for wallet deployment and config statuses + - provider: add prompt for wallet deployment + - relayer: add BaseRelayer.prependWalletDeploy + - relayer: add Relayer.feeOptions + - relayer: account for wallet deployment in fee estimation + - transactions: add fromTransactionish + - wallet: add Account.prependConfigUpdate + - wallet: add Account.getFeeOptions + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.35.0 + - @0xsequence/config@0.35.0 + - @0xsequence/guard@0.35.0 + - @0xsequence/network@0.35.0 + - @0xsequence/relayer@0.35.0 + - @0xsequence/transactions@0.35.0 + - @0xsequence/utils@0.35.0 + +## 0.34.0 + +### Minor Changes + +- - upgrade deps + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.34.0 + - @0xsequence/config@0.34.0 + - @0xsequence/guard@0.34.0 + - @0xsequence/network@0.34.0 + - @0xsequence/relayer@0.34.0 + - @0xsequence/transactions@0.34.0 + - @0xsequence/utils@0.34.0 + +## 0.33.3 + +### Patch Changes + +- wallet: fix Account.signTransactions + +## 0.33.2 + +### Patch Changes + +- Updated dependencies + - @0xsequence/transactions@0.33.2 + - @0xsequence/relayer@0.33.2 + +## 0.31.1 + +### Patch Changes + +- Updated dependencies + - @0xsequence/relayer@0.31.1 + +## 0.31.0 + +### Minor Changes + +- - upgrading to ethers v5.5 + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.31.0 + - @0xsequence/config@0.31.0 + - @0xsequence/guard@0.31.0 + - @0xsequence/network@0.31.0 + - @0xsequence/relayer@0.31.0 + - @0xsequence/transactions@0.31.0 + - @0xsequence/utils@0.31.0 + +## 0.30.0 + +### Minor Changes + +- - upgrade most deps + +### Patch Changes + +- Updated dependencies + - @0xsequence/abi@0.30.0 + - @0xsequence/config@0.30.0 + - @0xsequence/guard@0.30.0 + - @0xsequence/network@0.30.0 + - @0xsequence/relayer@0.30.0 + - @0xsequence/transactions@0.30.0 + - @0xsequence/utils@0.30.0 + +## 0.29.8 + +### Patch Changes + +- update api +- Updated dependencies [undefined] + - @0xsequence/abi@0.29.8 + - @0xsequence/config@0.29.8 + - @0xsequence/guard@0.29.8 + - @0xsequence/network@0.29.8 + - @0xsequence/relayer@0.29.8 + - @0xsequence/transactions@0.29.8 + - @0xsequence/utils@0.29.8 + +## 0.29.7 + +### Patch Changes + +- override ethers getChainId method + +## 0.29.6 + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/network@0.29.6 + - @0xsequence/config@0.29.6 + - @0xsequence/transactions@0.29.6 + - @0xsequence/relayer@0.29.6 + +## 0.29.5 + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/config@0.29.5 + - @0xsequence/relayer@0.29.5 + +## 0.29.2 + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/relayer@0.29.2 + +## 0.29.0 + +### Minor Changes + +- major architectural changes in Sequence design + + - only one API instance, API is no longer a per-chain service + - separate per-chain indexer service, API no longer handles indexing + - single contract metadata service, API no longer serves metadata + + chaind package has been removed, indexer and metadata packages have been added + + stronger typing with new explicit ChainId type + + multicall fixes and improvements + + forbid "wait" transactions in sendTransactionBatch calls + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/config@0.29.0 + - @0xsequence/network@0.29.0 + - @0xsequence/relayer@0.29.0 + - @0xsequence/transactions@0.29.0 + - @0xsequence/abi@0.29.0 + - @0xsequence/utils@0.29.0 + +## 0.28.0 + +### Minor Changes + +- extension provider + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.28.0 + - @0xsequence/config@0.28.0 + - @0xsequence/guard@0.28.0 + - @0xsequence/network@0.28.0 + - @0xsequence/relayer@0.28.0 + - @0xsequence/transactions@0.28.0 + - @0xsequence/utils@0.28.0 + +## 0.27.2 + +### Patch Changes + +- add SignedTransactionsCallback + +## 0.27.1 + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/relayer@0.27.1 + +## 0.27.0 + +### Minor Changes + +- Add requireFreshSigner lib to sessions + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.27.0 + - @0xsequence/config@0.27.0 + - @0xsequence/guard@0.27.0 + - @0xsequence/network@0.27.0 + - @0xsequence/relayer@0.27.0 + - @0xsequence/transactions@0.27.0 + - @0xsequence/utils@0.27.0 + +## 0.26.0 + +### Minor Changes + +- update relayer client bindings + provide the wallet's address for calls to SendMetaTxn + modify the semantics of Relayer.getNonce() to allow relayers to select nonce spaces for clients + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/relayer@0.26.0 + +## 0.25.1 + +### Patch Changes + +- Fix build typescrypt issue +- Updated dependencies [undefined] + - @0xsequence/abi@0.25.1 + - @0xsequence/config@0.25.1 + - @0xsequence/guard@0.25.1 + - @0xsequence/network@0.25.1 + - @0xsequence/relayer@0.25.1 + - @0xsequence/transactions@0.25.1 + - @0xsequence/utils@0.25.1 + +## 0.25.0 + +### Minor Changes + +- 10c8af8: Add estimator package + Fix multicall few calls bug + +### Patch Changes + +- Updated dependencies [10c8af8] + - @0xsequence/abi@0.25.0 + - @0xsequence/config@0.25.0 + - @0xsequence/guard@0.25.0 + - @0xsequence/network@0.25.0 + - @0xsequence/relayer@0.25.0 + - @0xsequence/transactions@0.25.0 + - @0xsequence/utils@0.25.0 + +## 0.24.1 + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/relayer@0.24.1 + +## 0.24.0 + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/relayer@0.24.0 + +## 0.23.0 + +### Minor Changes + +- - relayer: offer variety of gas fee options from the relayer service" + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.23.0 + - @0xsequence/config@0.23.0 + - @0xsequence/guard@0.23.0 + - @0xsequence/network@0.23.0 + - @0xsequence/relayer@0.23.0 + - @0xsequence/transactions@0.23.0 + - @0xsequence/utils@0.23.0 + +## 0.22.2 + +### Patch Changes + +- e1c109e: Fix authProof on expired sessions +- Updated dependencies [e1c109e] + - @0xsequence/abi@0.22.2 + - @0xsequence/config@0.22.2 + - @0xsequence/guard@0.22.2 + - @0xsequence/network@0.22.2 + - @0xsequence/relayer@0.22.2 + - @0xsequence/transactions@0.22.2 + - @0xsequence/utils@0.22.2 + +## 0.22.1 + +### Patch Changes + +- transport session cache +- Updated dependencies [undefined] + - @0xsequence/abi@0.22.1 + - @0xsequence/config@0.22.1 + - @0xsequence/guard@0.22.1 + - @0xsequence/network@0.22.1 + - @0xsequence/relayer@0.22.1 + - @0xsequence/transactions@0.22.1 + - @0xsequence/utils@0.22.1 + +## 0.22.0 + +### Minor Changes + +- e667b65: Expose all relayer options on networks + +### Patch Changes + +- Updated dependencies [e667b65] + - @0xsequence/abi@0.22.0 + - @0xsequence/network@0.22.0 + - @0xsequence/relayer@0.22.0 + - @0xsequence/utils@0.22.0 + - @0xsequence/config@0.22.0 + - @0xsequence/guard@0.22.0 + - @0xsequence/transactions@0.22.0 + +## 0.21.5 + +### Patch Changes + +- Give priority to metaTxnId returned by relayer +- Updated dependencies [undefined] + - @0xsequence/abi@0.21.5 + - @0xsequence/config@0.21.5 + - @0xsequence/guard@0.21.5 + - @0xsequence/network@0.21.5 + - @0xsequence/relayer@0.21.5 + - @0xsequence/transactions@0.21.5 + - @0xsequence/utils@0.21.5 + +## 0.21.4 + +### Patch Changes + +- Add has enough signers method +- Updated dependencies [undefined] + - @0xsequence/abi@0.21.4 + - @0xsequence/config@0.21.4 + - @0xsequence/guard@0.21.4 + - @0xsequence/network@0.21.4 + - @0xsequence/relayer@0.21.4 + - @0xsequence/transactions@0.21.4 + - @0xsequence/utils@0.21.4 + +## 0.21.3 + +### Patch Changes + +- add window session cache +- Updated dependencies [undefined] + - @0xsequence/abi@0.21.3 + - @0xsequence/config@0.21.3 + - @0xsequence/guard@0.21.3 + - @0xsequence/network@0.21.3 + - @0xsequence/relayer@0.21.3 + - @0xsequence/transactions@0.21.3 + - @0xsequence/utils@0.21.3 + +## 0.21.2 + +### Patch Changes + +- exception handlind in relayer +- Updated dependencies [undefined] + - @0xsequence/abi@0.21.2 + - @0xsequence/config@0.21.2 + - @0xsequence/guard@0.21.2 + - @0xsequence/network@0.21.2 + - @0xsequence/relayer@0.21.2 + - @0xsequence/transactions@0.21.2 + - @0xsequence/utils@0.21.2 + +## 0.21.1 + +### Patch Changes + +- config updates must not be revertOnError + +## 0.21.0 + +### Minor Changes + +- - fix gas estimation on wallets with large number of signers + - update to session handling and wallet config construction upon auth + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.21.0 + - @0xsequence/config@0.21.0 + - @0xsequence/guard@0.21.0 + - @0xsequence/network@0.21.0 + - @0xsequence/relayer@0.21.0 + - @0xsequence/transactions@0.21.0 + - @0xsequence/utils@0.21.0 + +## 0.19.3 + +### Patch Changes + +- jwtAuth visibility, package version sync +- Updated dependencies [undefined] + - @0xsequence/abi@0.19.3 + - @0xsequence/config@0.19.3 + - @0xsequence/guard@0.19.3 + - @0xsequence/network@0.19.3 + - @0xsequence/relayer@0.19.3 + - @0xsequence/transactions@0.19.3 + - @0xsequence/utils@0.19.3 + +## 0.19.2 + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.19.2 + - @0xsequence/config@0.19.2 + - @0xsequence/relayer@0.19.2 + - @0xsequence/transactions@0.19.2 + +## 0.19.0 + +### Minor Changes + +- - provider, improve dapp / wallet transport io + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.19.0 + - @0xsequence/config@0.19.0 + - @0xsequence/guard@0.19.0 + - @0xsequence/network@0.19.0 + - @0xsequence/relayer@0.19.0 + - @0xsequence/transactions@0.19.0 + - @0xsequence/utils@0.19.0 + +## 0.18.0 + +### Minor Changes + +- relayer improvements and pending transaction handling + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.18.0 + - @0xsequence/config@0.18.0 + - @0xsequence/guard@0.18.0 + - @0xsequence/network@0.18.0 + - @0xsequence/relayer@0.18.0 + - @0xsequence/transactions@0.18.0 + - @0xsequence/utils@0.18.0 + +## 0.16.0 + +### Minor Changes + +- relayer as its own service separate from chaind + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.16.0 + - @0xsequence/config@0.16.0 + - @0xsequence/guard@0.16.0 + - @0xsequence/network@0.16.0 + - @0xsequence/relayer@0.16.0 + - @0xsequence/transactions@0.16.0 + - @0xsequence/utils@0.16.0 + +## 0.15.1 + +### Patch Changes + +- update api clients +- Updated dependencies [undefined] + - @0xsequence/abi@0.15.1 + - @0xsequence/config@0.15.1 + - @0xsequence/guard@0.15.1 + - @0xsequence/network@0.15.1 + - @0xsequence/relayer@0.15.1 + - @0xsequence/transactions@0.15.1 + - @0xsequence/utils@0.15.1 + +## 0.15.0 + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/relayer@0.15.0 + - @0xsequence/transactions@0.15.0 + +## 0.14.3 + +### Patch Changes + +- Fix 0xSequence relayer dependencies +- Updated dependencies [undefined] + - @0xsequence/abi@0.14.3 + - @0xsequence/config@0.14.3 + - @0xsequence/guard@0.14.3 + - @0xsequence/network@0.14.3 + - @0xsequence/relayer@0.14.3 + - @0xsequence/transactions@0.14.3 + - @0xsequence/utils@0.14.3 + +## 0.14.2 + +### Patch Changes + +- Add debug logs to rpc-relayer +- Updated dependencies [undefined] + - @0xsequence/abi@0.14.2 + - @0xsequence/config@0.14.2 + - @0xsequence/guard@0.14.2 + - @0xsequence/network@0.14.2 + - @0xsequence/relayer@0.14.2 + - @0xsequence/transactions@0.14.2 + - @0xsequence/utils@0.14.2 + +## 0.14.0 + +### Minor Changes + +- update sequence utils finder which includes optimization + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.14.0 + - @0xsequence/config@0.14.0 + - @0xsequence/guard@0.14.0 + - @0xsequence/network@0.14.0 + - @0xsequence/relayer@0.14.0 + - @0xsequence/transactions@0.14.0 + - @0xsequence/utils@0.14.0 + +## 0.13.0 + +### Minor Changes + +- Update SequenceUtils deployed contract + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.13.0 + - @0xsequence/config@0.13.0 + - @0xsequence/guard@0.13.0 + - @0xsequence/network@0.13.0 + - @0xsequence/relayer@0.13.0 + - @0xsequence/transactions@0.13.0 + - @0xsequence/utils@0.13.0 + +## 0.12.1 + +### Patch Changes + +- npm bump +- Updated dependencies [undefined] + - @0xsequence/abi@0.12.1 + - @0xsequence/config@0.12.1 + - @0xsequence/guard@0.12.1 + - @0xsequence/network@0.12.1 + - @0xsequence/relayer@0.12.1 + - @0xsequence/transactions@0.12.1 + - @0xsequence/utils@0.12.1 + +## 0.12.0 + +### Minor Changes + +- provider: improvements to window transport + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.12.0 + - @0xsequence/config@0.12.0 + - @0xsequence/guard@0.12.0 + - @0xsequence/network@0.12.0 + - @0xsequence/relayer@0.12.0 + - @0xsequence/transactions@0.12.0 + - @0xsequence/utils@0.12.0 + +## 0.11.4 + +### Patch Changes + +- update api client +- Updated dependencies [undefined] + - @0xsequence/abi@0.11.4 + - @0xsequence/config@0.11.4 + - @0xsequence/guard@0.11.4 + - @0xsequence/network@0.11.4 + - @0xsequence/relayer@0.11.4 + - @0xsequence/transactions@0.11.4 + - @0xsequence/utils@0.11.4 + +## 0.11.3 + +### Patch Changes + +- improve openWindow state options handling +- Updated dependencies [undefined] + - @0xsequence/abi@0.11.3 + - @0xsequence/config@0.11.3 + - @0xsequence/guard@0.11.3 + - @0xsequence/network@0.11.3 + - @0xsequence/relayer@0.11.3 + - @0xsequence/transactions@0.11.3 + - @0xsequence/utils@0.11.3 + +## 0.11.2 + +### Patch Changes + +- Fix multicall proxy scopes +- Updated dependencies [undefined] + - @0xsequence/abi@0.11.2 + - @0xsequence/config@0.11.2 + - @0xsequence/guard@0.11.2 + - @0xsequence/network@0.11.2 + - @0xsequence/relayer@0.11.2 + - @0xsequence/transactions@0.11.2 + - @0xsequence/utils@0.11.2 + +## 0.11.1 + +### Patch Changes + +- Add support for dynamic and nested signatures +- Updated dependencies [undefined] + - @0xsequence/abi@0.11.1 + - @0xsequence/config@0.11.1 + - @0xsequence/guard@0.11.1 + - @0xsequence/network@0.11.1 + - @0xsequence/relayer@0.11.1 + - @0xsequence/transactions@0.11.1 + - @0xsequence/utils@0.11.1 + +## 0.11.0 + +### Minor Changes + +- Update wallet context to 1.7 contracts + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.11.0 + - @0xsequence/config@0.11.0 + - @0xsequence/guard@0.11.0 + - @0xsequence/network@0.11.0 + - @0xsequence/relayer@0.11.0 + - @0xsequence/transactions@0.11.0 + - @0xsequence/utils@0.11.0 + +## 0.10.9 + +### Patch Changes + +- add support for public addresses as signers in session.open +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.9 + - @0xsequence/config@0.10.9 + - @0xsequence/guard@0.10.9 + - @0xsequence/network@0.10.9 + - @0xsequence/relayer@0.10.9 + - @0xsequence/transactions@0.10.9 + - @0xsequence/utils@0.10.9 + +## 0.10.8 + +### Patch Changes + +- Multicall production configuration +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.8 + - @0xsequence/config@0.10.8 + - @0xsequence/guard@0.10.8 + - @0xsequence/network@0.10.8 + - @0xsequence/relayer@0.10.8 + - @0xsequence/transactions@0.10.8 + - @0xsequence/utils@0.10.8 + +## 0.10.7 + +### Patch Changes + +- allow provider transport to force disconnect +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.7 + - @0xsequence/config@0.10.7 + - @0xsequence/guard@0.10.7 + - @0xsequence/network@0.10.7 + - @0xsequence/relayer@0.10.7 + - @0xsequence/transactions@0.10.7 + - @0xsequence/utils@0.10.7 + +## 0.10.6 + +### Patch Changes + +- - fix getWalletState method +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.6 + - @0xsequence/config@0.10.6 + - @0xsequence/guard@0.10.6 + - @0xsequence/network@0.10.6 + - @0xsequence/relayer@0.10.6 + - @0xsequence/transactions@0.10.6 + - @0xsequence/utils@0.10.6 + +## 0.10.5 + +### Patch Changes + +- update relayer gas refund options +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.5 + - @0xsequence/config@0.10.5 + - @0xsequence/guard@0.10.5 + - @0xsequence/network@0.10.5 + - @0xsequence/relayer@0.10.5 + - @0xsequence/transactions@0.10.5 + - @0xsequence/utils@0.10.5 + +## 0.10.4 + +### Patch Changes + +- Update api proto +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.4 + - @0xsequence/config@0.10.4 + - @0xsequence/guard@0.10.4 + - @0xsequence/network@0.10.4 + - @0xsequence/relayer@0.10.4 + - @0xsequence/transactions@0.10.4 + - @0xsequence/utils@0.10.4 + +## 0.10.3 + +### Patch Changes + +- Fix loading config cross-chain +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.3 + - @0xsequence/config@0.10.3 + - @0xsequence/guard@0.10.3 + - @0xsequence/network@0.10.3 + - @0xsequence/relayer@0.10.3 + - @0xsequence/transactions@0.10.3 + - @0xsequence/utils@0.10.3 + +## 0.10.2 + +### Patch Changes + +- - message digest fix +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.2 + - @0xsequence/config@0.10.2 + - @0xsequence/guard@0.10.2 + - @0xsequence/network@0.10.2 + - @0xsequence/relayer@0.10.2 + - @0xsequence/transactions@0.10.2 + - @0xsequence/utils@0.10.2 + +## 0.10.1 + +### Patch Changes + +- upgrade deps +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.1 + - @0xsequence/config@0.10.1 + - @0xsequence/guard@0.10.1 + - @0xsequence/network@0.10.1 + - @0xsequence/relayer@0.10.1 + - @0xsequence/transactions@0.10.1 + - @0xsequence/utils@0.10.1 + +## 0.10.0 + +### Minor Changes + +- Deployed new contracts with ERC1271 signer support + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.10.0 + - @0xsequence/config@0.10.0 + - @0xsequence/guard@0.10.0 + - @0xsequence/network@0.10.0 + - @0xsequence/relayer@0.10.0 + - @0xsequence/transactions@0.10.0 + - @0xsequence/utils@0.10.0 + +## 0.9.6 + +### Patch Changes + +- Update ABIs for latest sequence contracts +- Updated dependencies [undefined] + - @0xsequence/config@0.9.6 + - @0xsequence/network@0.9.6 + - @0xsequence/relayer@0.9.6 + - @0xsequence/transactions@0.9.6 + - @0xsequence/utils@0.9.6 + - @0xsequence/abi@0.9.6 + - @0xsequence/guard@0.9.6 + +## 0.9.5 + +### Patch Changes + +- Implemented session class +- Updated dependencies [undefined] + - @0xsequence/config@0.9.5 + - @0xsequence/network@0.9.5 + - @0xsequence/relayer@0.9.5 + - @0xsequence/transactions@0.9.5 + - @0xsequence/utils@0.9.5 + +## 0.9.3 + +### Patch Changes + +- - minor improvements +- Updated dependencies [undefined] + - @0xsequence/abi@0.9.3 + - @0xsequence/config@0.9.3 + - @0xsequence/guard@0.9.3 + - @0xsequence/network@0.9.3 + - @0xsequence/relayer@0.9.3 + - @0xsequence/transactions@0.9.3 + - @0xsequence/utils@0.9.3 + +## 0.9.1 + +### Patch Changes + +- - patch bump +- Updated dependencies [undefined] + - @0xsequence/abi@0.9.1 + - @0xsequence/api@0.9.1 + - @0xsequence/config@0.9.1 + - @0xsequence/guard@0.9.1 + - @0xsequence/network@0.9.1 + - @0xsequence/relayer@0.9.1 + - @0xsequence/transactions@0.9.1 + - @0xsequence/utils@0.9.1 + +## 0.9.0 + +### Minor Changes + +- - provider transport hardening + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/api@0.9.0 + - @0xsequence/abi@0.9.0 + - @0xsequence/config@0.9.0 + - @0xsequence/guard@0.9.0 + - @0xsequence/network@0.9.0 + - @0xsequence/relayer@0.9.0 + - @0xsequence/transactions@0.9.0 + - @0xsequence/utils@0.9.0 + +## 0.8.5 + +### Patch Changes + +- - use latest wallet-contracts +- Updated dependencies [undefined] + - @0xsequence/abi@0.8.5 + - @0xsequence/api@0.8.5 + - @0xsequence/config@0.8.5 + - @0xsequence/guard@0.8.5 + - @0xsequence/network@0.8.5 + - @0xsequence/relayer@0.8.5 + - @0xsequence/transactions@0.8.5 + - @0xsequence/utils@0.8.5 + +## 0.8.4 + +### Patch Changes + +- - minor improvements, name updates and comments +- Updated dependencies [undefined] + - @0xsequence/abi@0.8.4 + - @0xsequence/api@0.8.4 + - @0xsequence/config@0.8.4 + - @0xsequence/guard@0.8.4 + - @0xsequence/network@0.8.4 + - @0xsequence/relayer@0.8.4 + - @0xsequence/transactions@0.8.4 + - @0xsequence/utils@0.8.4 + +## 0.8.3 + +### Patch Changes + +- - refinements + + - normalize signer address in config + + - provider: getWalletState() method to WalletProvider + +- Updated dependencies [undefined] + - @0xsequence/abi@0.8.3 + - @0xsequence/api@0.8.3 + - @0xsequence/config@0.8.3 + - @0xsequence/guard@0.8.3 + - @0xsequence/network@0.8.3 + - @0xsequence/relayer@0.8.3 + - @0xsequence/transactions@0.8.3 + - @0xsequence/utils@0.8.3 + +## 0.8.2 + +### Patch Changes + +- - field rename and ethauth dependency bump +- Updated dependencies [undefined] + - @0xsequence/abi@0.8.2 + - @0xsequence/api@0.8.2 + - @0xsequence/config@0.8.2 + - @0xsequence/guard@0.8.2 + - @0xsequence/network@0.8.2 + - @0xsequence/relayer@0.8.2 + - @0xsequence/transactions@0.8.2 + - @0xsequence/utils@0.8.2 + +## 0.8.1 + +### Patch Changes + +- - variety of optimizations +- Updated dependencies [undefined] + - @0xsequence/abi@0.8.1 + - @0xsequence/api@0.8.1 + - @0xsequence/config@0.8.1 + - @0xsequence/guard@0.8.1 + - @0xsequence/network@0.8.1 + - @0xsequence/relayer@0.8.1 + - @0xsequence/transactions@0.8.1 + - @0xsequence/utils@0.8.1 + +## 0.8.0 + +### Minor Changes + +- - changeset fix + +### Patch Changes + +- Updated dependencies [undefined] + - @0xsequence/abi@0.8.0 + - @0xsequence/api@0.8.0 + - @0xsequence/config@0.8.0 + - @0xsequence/guard@0.8.0 + - @0xsequence/network@0.8.0 + - @0xsequence/relayer@0.8.0 + - @0xsequence/transactions@0.8.0 + - @0xsequence/utils@0.8.0 + +## 0.7.1 + +### Patch Changes + +- 02377ab: Minor improvements +- Updated dependencies [02377ab] +- Updated dependencies [1fe4379] + - @0xsequence/network@0.7.1 + - @0xsequence/relayer@0.7.1 + - @0xsequence/utils@0.7.1 + +## 0.7.0 + +### Patch Changes + +- 6f11ed7: sequence.js, init release +- Updated dependencies [6f11ed7] + - @0xsequence/abi@0.7.0 + - @0xsequence/api@0.7.0 + - @0xsequence/config@0.7.0 + - @0xsequence/guard@0.7.0 + - @0xsequence/network@0.7.0 + - @0xsequence/relayer@0.7.0 + - @0xsequence/transactions@0.7.0 + - @0xsequence/utils@0.7.0 diff --git a/packages/wallet/README.md b/packages/wallet/README.md new file mode 100644 index 0000000000..19321e9f2a --- /dev/null +++ b/packages/wallet/README.md @@ -0,0 +1,4 @@ +@0xsequence/wallet +================== + +See [0xsequence project page](https://github.com/0xsequence/sequence.js). diff --git a/packages/wallet/core/CHANGELOG.md b/packages/wallet/core/CHANGELOG.md index 9f44040a1f..03d06db617 100644 --- a/packages/wallet/core/CHANGELOG.md +++ b/packages/wallet/core/CHANGELOG.md @@ -1,5 +1,15 @@ # @0xsequence/wallet-core +## 3.0.10 + +### Patch Changes + +- Minor network updates, relayer interface +- Updated dependencies + - @0xsequence/guard@3.0.10 + - @0xsequence/relayer@3.0.10 + - @0xsequence/wallet-primitives@3.0.10 + ## 3.0.9 ### Patch Changes diff --git a/packages/wallet/core/eslint.config.js b/packages/wallet/core/eslint.config.js index d10bbd1e97..0c24ade422 100644 --- a/packages/wallet/core/eslint.config.js +++ b/packages/wallet/core/eslint.config.js @@ -4,7 +4,7 @@ import { config as baseConfig } from '@repo/eslint-config/base' export default [ ...baseConfig, { - // files: ['**/*.{test,spec}.ts'], + files: ['**/*.{test,spec}.ts'], rules: { '@typescript-eslint/no-explicit-any': 'off', }, diff --git a/packages/wallet/core/hardhat.config.js b/packages/wallet/core/hardhat.config.js new file mode 100644 index 0000000000..fd760378b1 --- /dev/null +++ b/packages/wallet/core/hardhat.config.js @@ -0,0 +1,15 @@ +/** + * @type import('hardhat/config').HardhatUserConfig + */ +module.exports = { + solidity: '0.7.6', + + networks: { + hardhat: { + chainId: 31337, + accounts: { + mnemonic: 'ripple axis someone ridge uniform wrist prosper there frog rate olympic knee', + }, + }, + }, +} diff --git a/packages/wallet/core/package.json b/packages/wallet/core/package.json index 8cbb4eacd4..95457a5787 100644 --- a/packages/wallet/core/package.json +++ b/packages/wallet/core/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/wallet-core", - "version": "3.0.9", + "version": "3.0.10", "license": "Apache-2.0", "type": "module", "publishConfig": { diff --git a/packages/wallet/core/src/bundler/bundlers/pimlico.ts b/packages/wallet/core/src/bundler/bundlers/pimlico.ts index 4837babee0..e2d95ec331 100644 --- a/packages/wallet/core/src/bundler/bundlers/pimlico.ts +++ b/packages/wallet/core/src/bundler/bundlers/pimlico.ts @@ -16,22 +16,16 @@ type PimlicoGasPrice = { } export class PimlicoBundler implements Bundler { - public readonly kind = 'bundler' + public readonly kind: 'bundler' = 'bundler' public readonly id: string public readonly provider: Provider.Provider public readonly bundlerRpcUrl: string - private readonly fetcher: typeof fetch - constructor(bundlerRpcUrl: string, provider: Provider.Provider | string, fetcher?: typeof fetch) { + constructor(bundlerRpcUrl: string, provider: Provider.Provider | string) { this.id = `pimlico-erc4337-${bundlerRpcUrl}` this.provider = typeof provider === 'string' ? Provider.from(RpcTransport.fromHttp(provider)) : provider this.bundlerRpcUrl = bundlerRpcUrl - const resolvedFetch = fetcher ?? (globalThis as any).fetch - if (!resolvedFetch) { - throw new Error('fetch is not available') - } - this.fetcher = resolvedFetch } async isAvailable(entrypoint: Address.Address, chainId: number): Promise { @@ -119,7 +113,7 @@ export class PimlicoBundler implements Bundler { let pimlico: PimlicoStatusResp | undefined try { pimlico = await this.bundlerRpc('pimlico_getUserOperationStatus', [opHash]) - } catch { + } catch (_) { /* ignore - not Pimlico or endpoint down */ } @@ -171,7 +165,7 @@ export class PimlicoBundler implements Bundler { private async bundlerRpc(method: string, params: any[]): Promise { const body = JSON.stringify({ jsonrpc: '2.0', id: 1, method, params }) - const res = await this.fetcher(this.bundlerRpcUrl, { + const res = await fetch(this.bundlerRpcUrl, { method: 'POST', headers: { 'content-type': 'application/json' }, body, diff --git a/packages/wallet/core/src/local-relayer.ts b/packages/wallet/core/src/local-relayer.ts new file mode 100644 index 0000000000..29850be344 --- /dev/null +++ b/packages/wallet/core/src/local-relayer.ts @@ -0,0 +1,125 @@ +// import { ethers } from 'ethers' +// import { logger } from '@0xsequence/utils' +// import { FeeOption, FeeQuote, proto, Relayer } from '.' +// import { ProviderRelayer, ProviderRelayerOptions } from './provider-relayer' +// import { commons } from '@0xsequence/core' + +// export type LocalRelayerOptions = Omit & { +// signer: ethers.Signer +// } + +// export function isLocalRelayerOptions(obj: any): obj is LocalRelayerOptions { +// return typeof obj === 'object' && isAbstractSigner(obj.signer) +// } + +// export class LocalRelayer extends ProviderRelayer implements Relayer { +// private signer: ethers.Signer +// private txnOptions: ethers.TransactionRequest + +// constructor(options: LocalRelayerOptions | ethers.AbstractSigner) { +// super(isAbstractSigner(options) ? { provider: options.provider! } : { ...options, provider: options.signer.provider! }) +// this.signer = isAbstractSigner(options) ? options : options.signer +// if (!this.signer.provider) throw new Error('Signer must have a provider') +// } + +// async getFeeOptions(_address: string, ..._transactions: commons.transaction.Transaction[]): Promise<{ options: FeeOption[] }> { +// return { options: [] } +// } + +// async getFeeOptionsRaw( +// _entrypoint: string, +// _data: ethers.BytesLike, +// _options?: { +// simulate?: boolean +// } +// ): Promise<{ options: FeeOption[] }> { +// return { options: [] } +// } + +// async gasRefundOptions(address: string, ...transactions: commons.transaction.Transaction[]): Promise { +// const { options } = await this.getFeeOptions(address, ...transactions) +// return options +// } + +// setTransactionOptions(transactionRequest: ethers.TransactionRequest) { +// this.txnOptions = transactionRequest +// } + +// async relay( +// signedTxs: commons.transaction.IntendedTransactionBundle, +// quote?: FeeQuote, +// waitForReceipt: boolean = true +// ): Promise> { +// if (quote !== undefined) { +// logger.warn(`LocalRelayer doesn't accept fee quotes`) +// } + +// const data = commons.transaction.encodeBundleExecData(signedTxs) + +// // TODO: think about computing gas limit individually, summing together and passing across +// // NOTE: we expect that all txns have set their gasLimit ahead of time through proper estimation +// // const gasLimit = signedTxs.transactions.reduce((sum, tx) => sum + tx.gasLimit, 0n) +// // txRequest.gasLimit = gasLimit + +// const responsePromise = this.signer.sendTransaction({ +// to: signedTxs.entrypoint, +// data, +// ...this.txnOptions, +// gasLimit: 9000000 +// }) + +// if (waitForReceipt) { +// const response: commons.transaction.TransactionResponse = await responsePromise +// response.receipt = await response.wait() +// return response +// } else { +// return responsePromise +// } +// } + +// async getMetaTransactions( +// projectId: number, +// page?: proto.Page +// ): Promise<{ +// page: proto.Page +// transactions: proto.MetaTxnLog[] +// }> { +// return { page: { page: 0, pageSize: 100 }, transactions: [] } +// } + +// async getTransactionCost( +// projectId: number, +// from: string, +// to: string +// ): Promise<{ +// cost: number +// }> { +// return { cost: 0 } +// } + +// async listGasSponsors(args: proto.ListGasSponsorsArgs): Promise { +// return { page: { page: 0, pageSize: 100 }, gasSponsors: [] } +// } + +// async addGasSponsor(args: proto.AddGasSponsorArgs): Promise { +// return { status: true, gasSponsor: {} as proto.GasSponsor } +// } + +// async updateGasSponsor(args: proto.UpdateGasSponsorArgs): Promise { +// return { status: true, gasSponsor: {} as proto.GasSponsor } +// } + +// async removeGasSponsor(args: proto.RemoveGasSponsorArgs): Promise { +// return { status: true } +// } +// } + +// function isAbstractSigner(signer: any): signer is ethers.AbstractSigner { +// return ( +// signer && +// typeof signer === 'object' && +// typeof signer.provider === 'object' && +// typeof signer.getAddress === 'function' && +// typeof signer.connect === 'function' +// ) +// } diff --git a/packages/wallet/core/src/preconditions/codec.ts b/packages/wallet/core/src/preconditions/codec.ts new file mode 100644 index 0000000000..a50c1984f2 --- /dev/null +++ b/packages/wallet/core/src/preconditions/codec.ts @@ -0,0 +1,217 @@ +import { Address } from 'ox' +import { + Precondition, + NativeBalancePrecondition, + Erc20BalancePrecondition, + Erc20ApprovalPrecondition, + Erc721OwnershipPrecondition, + Erc721ApprovalPrecondition, + Erc1155BalancePrecondition, + Erc1155ApprovalPrecondition, +} from './types.js' + +export interface IntentPrecondition { + type: string + data: string +} + +export function decodePreconditions(preconditions: IntentPrecondition[]): Precondition[] { + const decodedPreconditions: Precondition[] = [] + + for (const p of preconditions) { + const decoded = decodePrecondition(p) + if (decoded) { + decodedPreconditions.push(decoded) + } + } + + return decodedPreconditions +} + +export function decodePrecondition(p: IntentPrecondition): Precondition | undefined { + if (!p) { + return undefined + } + + if (typeof p.minAmount !== 'bigint') { + console.warn(`Failed to decode precondition: minAmount must be a bigint`) + return undefined + } + + let precondition: Precondition | undefined + + try { + const data = JSON.parse(p.data) + + switch (p.type) { + case 'native-balance': + precondition = new NativeBalancePrecondition( + Address.from(data.address), + data.min ? BigInt(data.min) : undefined, + data.max ? BigInt(data.max) : undefined, + ) + break + + case 'erc20-balance': + precondition = new Erc20BalancePrecondition( + Address.from(data.address), + Address.from(data.token), + data.min ? BigInt(data.min) : undefined, + data.max ? BigInt(data.max) : undefined, + ) + break + + case 'erc20-approval': + precondition = new Erc20ApprovalPrecondition( + Address.from(data.address), + Address.from(data.token), + Address.from(data.operator), + BigInt(data.min), + ) + break + + case 'erc721-ownership': + precondition = new Erc721OwnershipPrecondition( + Address.from(data.address), + Address.from(data.token), + BigInt(data.tokenId), + data.owned, + ) + break + + case 'erc721-approval': + precondition = new Erc721ApprovalPrecondition( + Address.from(data.address), + Address.from(data.token), + BigInt(data.tokenId), + Address.from(data.operator), + ) + break + + case 'erc1155-balance': + precondition = new Erc1155BalancePrecondition( + Address.from(data.address), + Address.from(data.token), + BigInt(data.tokenId), + data.min ? BigInt(data.min) : undefined, + data.max ? BigInt(data.max) : undefined, + ) + break + + case 'erc1155-approval': + precondition = new Erc1155ApprovalPrecondition( + Address.from(data.address), + Address.from(data.token), + BigInt(data.tokenId), + Address.from(data.operator), + BigInt(data.min), + ) + break + + default: + return undefined + } + + const error = precondition.isValid() + if (error) { + console.warn(`Invalid precondition: ${error.message}`) + return undefined + } + + return precondition + } catch (e) { + console.warn(`Failed to decode precondition: ${e}`) + return undefined + } +} + +export function encodePrecondition(p: Precondition): string { + switch (p.type()) { + case 'native-balance': { + const native = p as NativeBalancePrecondition + const data = { + address: native.address.toString(), + ...(native.min !== undefined && { min: native.min.toString() }), + ...(native.max !== undefined && { max: native.max.toString() }), + } + + return JSON.stringify(data) + } + + case 'erc20-balance': { + const erc20 = p as Erc20BalancePrecondition + const data = { + address: erc20.address.toString(), + token: erc20.token.toString(), + ...(erc20.min !== undefined && { min: erc20.min.toString() }), + ...(erc20.max !== undefined && { max: erc20.max.toString() }), + } + + return JSON.stringify(data) + } + + case 'erc20-approval': { + const erc20 = p as Erc20ApprovalPrecondition + const data = { + address: erc20.address.toString(), + token: erc20.token.toString(), + operator: erc20.operator.toString(), + min: erc20.min.toString(), + } + + return JSON.stringify(data) + } + + case 'erc721-ownership': { + const erc721 = p as Erc721OwnershipPrecondition + const data = { + address: erc721.address.toString(), + token: erc721.token.toString(), + tokenId: erc721.tokenId.toString(), + ...(erc721.owned !== undefined && { owned: erc721.owned }), + } + + return JSON.stringify(data) + } + + case 'erc721-approval': { + const erc721 = p as Erc721ApprovalPrecondition + const data = { + address: erc721.address.toString(), + token: erc721.token.toString(), + tokenId: erc721.tokenId.toString(), + operator: erc721.operator.toString(), + } + + return JSON.stringify(data) + } + + case 'erc1155-balance': { + const erc1155 = p as Erc1155BalancePrecondition + const data = { + address: erc1155.address.toString(), + token: erc1155.token.toString(), + tokenId: erc1155.tokenId.toString(), + ...(erc1155.min !== undefined && { min: erc1155.min.toString() }), + ...(erc1155.max !== undefined && { max: erc1155.max.toString() }), + } + + return JSON.stringify(data) + } + + case 'erc1155-approval': { + const erc1155 = p as Erc1155ApprovalPrecondition + const data = { + address: erc1155.address.toString(), + token: erc1155.token.toString(), + tokenId: erc1155.tokenId.toString(), + operator: erc1155.operator.toString(), + min: erc1155.min.toString(), + } + + return JSON.stringify(data) + } + } + + return JSON.stringify({}) +} diff --git a/packages/wallet/core/src/preconditions/index.ts b/packages/wallet/core/src/preconditions/index.ts new file mode 100644 index 0000000000..6bb6376ef6 --- /dev/null +++ b/packages/wallet/core/src/preconditions/index.ts @@ -0,0 +1,3 @@ +export * from './types.js' +export * from './codec.js' +export * from './selectors.js' diff --git a/packages/wallet/core/src/preconditions/selectors.ts b/packages/wallet/core/src/preconditions/selectors.ts new file mode 100644 index 0000000000..42b8cbb3b8 --- /dev/null +++ b/packages/wallet/core/src/preconditions/selectors.ts @@ -0,0 +1,41 @@ +import { Precondition, NativeBalancePrecondition, Erc20BalancePrecondition } from './types.js' +import { IntentPrecondition, decodePreconditions } from './codec.js' + +export function extractChainID(precondition: IntentPrecondition): number | undefined { + if (!precondition) { + return undefined + } + + try { + const data = JSON.parse(precondition.data) + return data.chainID ? Number(data.chainID) : undefined + } catch (e) { + return undefined + } +} + +export function extractSupportedPreconditions(preconditions: IntentPrecondition[]): Precondition[] { + if (!preconditions || preconditions.length === 0) { + return [] + } + + return decodePreconditions(preconditions) +} + +export function extractNativeBalancePreconditions(preconditions: IntentPrecondition[]): NativeBalancePrecondition[] { + if (!preconditions || preconditions.length === 0) { + return [] + } + + const decoded = decodePreconditions(preconditions) + return decoded.filter((p): p is NativeBalancePrecondition => p.type() === 'native-balance') +} + +export function extractERC20BalancePreconditions(preconditions: IntentPrecondition[]): Erc20BalancePrecondition[] { + if (!preconditions || preconditions.length === 0) { + return [] + } + + const decoded = decodePreconditions(preconditions) + return decoded.filter((p): p is Erc20BalancePrecondition => p.type() === 'erc20-balance') +} diff --git a/packages/wallet/core/src/preconditions/types.ts b/packages/wallet/core/src/preconditions/types.ts new file mode 100644 index 0000000000..23a9db22c7 --- /dev/null +++ b/packages/wallet/core/src/preconditions/types.ts @@ -0,0 +1,201 @@ +import { Address } from 'ox' + +export interface Precondition { + type(): string + isValid(): Error | undefined +} + +export class NativeBalancePrecondition implements Precondition { + constructor( + public readonly address: Address.Address, + public readonly min?: bigint, + public readonly max?: bigint, + ) {} + + type(): string { + return 'native-balance' + } + + isValid(): Error | undefined { + if (!this.address) { + return new Error('address is required') + } + if (this.min !== undefined && this.max !== undefined && this.min > this.max) { + return new Error('min balance cannot be greater than max balance') + } + return undefined + } +} + +export class Erc20BalancePrecondition implements Precondition { + constructor( + public readonly address: Address.Address, + public readonly token: Address.Address, + public readonly min?: bigint, + public readonly max?: bigint, + ) {} + + type(): string { + return 'erc20-balance' + } + + isValid(): Error | undefined { + if (!this.address) { + return new Error('address is required') + } + if (!this.token) { + return new Error('token address is required') + } + if (this.min !== undefined && this.max !== undefined && this.min > this.max) { + return new Error('min balance cannot be greater than max balance') + } + return undefined + } +} + +export class Erc20ApprovalPrecondition implements Precondition { + constructor( + public readonly address: Address.Address, + public readonly token: Address.Address, + public readonly operator: Address.Address, + public readonly min: bigint, + ) {} + + type(): string { + return 'erc20-approval' + } + + isValid(): Error | undefined { + if (!this.address) { + return new Error('address is required') + } + if (!this.token) { + return new Error('token address is required') + } + if (!this.operator) { + return new Error('operator address is required') + } + if (this.min === undefined) { + return new Error('min approval amount is required') + } + return undefined + } +} + +export class Erc721OwnershipPrecondition implements Precondition { + constructor( + public readonly address: Address.Address, + public readonly token: Address.Address, + public readonly tokenId: bigint, + public readonly owned?: boolean, + ) {} + + type(): string { + return 'erc721-ownership' + } + + isValid(): Error | undefined { + if (!this.address) { + return new Error('address is required') + } + if (!this.token) { + return new Error('token address is required') + } + if (this.tokenId === undefined) { + return new Error('tokenId is required') + } + return undefined + } +} + +export class Erc721ApprovalPrecondition implements Precondition { + constructor( + public readonly address: Address.Address, + public readonly token: Address.Address, + public readonly tokenId: bigint, + public readonly operator: Address.Address, + ) {} + + type(): string { + return 'erc721-approval' + } + + isValid(): Error | undefined { + if (!this.address) { + return new Error('address is required') + } + if (!this.token) { + return new Error('token address is required') + } + if (this.tokenId === undefined) { + return new Error('tokenId is required') + } + if (!this.operator) { + return new Error('operator address is required') + } + return undefined + } +} + +export class Erc1155BalancePrecondition implements Precondition { + constructor( + public readonly address: Address.Address, + public readonly token: Address.Address, + public readonly tokenId: bigint, + public readonly min?: bigint, + public readonly max?: bigint, + ) {} + + type(): string { + return 'erc1155-balance' + } + + isValid(): Error | undefined { + if (!this.address) { + return new Error('address is required') + } + if (!this.token) { + return new Error('token address is required') + } + if (this.tokenId === undefined) { + return new Error('tokenId is required') + } + if (this.min !== undefined && this.max !== undefined && this.min > this.max) { + return new Error('min balance cannot be greater than max balance') + } + return undefined + } +} + +export class Erc1155ApprovalPrecondition implements Precondition { + constructor( + public readonly address: Address.Address, + public readonly token: Address.Address, + public readonly tokenId: bigint, + public readonly operator: Address.Address, + public readonly min: bigint, + ) {} + + type(): string { + return 'erc1155-approval' + } + + isValid(): Error | undefined { + if (!this.address) { + return new Error('address is required') + } + if (!this.token) { + return new Error('token address is required') + } + if (this.tokenId === undefined) { + return new Error('tokenId is required') + } + if (!this.operator) { + return new Error('operator address is required') + } + if (this.min === undefined) { + return new Error('min approval amount is required') + } + return undefined + } +} diff --git a/packages/wallet/core/src/provider-relayer.ts b/packages/wallet/core/src/provider-relayer.ts new file mode 100644 index 0000000000..85e9257f24 --- /dev/null +++ b/packages/wallet/core/src/provider-relayer.ts @@ -0,0 +1,284 @@ +// import { ethers } from 'ethers' +// import { walletContracts } from '@0xsequence/abi' +// import { FeeOption, FeeQuote, proto, Relayer, SimulateResult } from '.' +// import { logger, Optionals } from '@0xsequence/utils' +// import { commons } from '@0xsequence/core' + +// const DEFAULT_GAS_LIMIT = 800000n + +// export interface ProviderRelayerOptions { +// provider: ethers.Provider +// waitPollRate?: number +// deltaBlocksLog?: number +// fromBlockLog?: number +// } + +// export const ProviderRelayerDefaults: Required> = { +// waitPollRate: 1000, +// deltaBlocksLog: 12, +// fromBlockLog: -1024 +// } + +// export function isProviderRelayerOptions(obj: any): obj is ProviderRelayerOptions { +// return typeof obj === 'object' && isAbstractProvider(obj.provider) +// } + +// export abstract class ProviderRelayer implements Relayer { +// public provider: ethers.Provider +// public waitPollRate: number +// public deltaBlocksLog: number +// public fromBlockLog: number + +// constructor(options: ProviderRelayerOptions) { +// const opts = { ...ProviderRelayerDefaults, ...options } + +// this.provider = opts.provider +// this.waitPollRate = opts.waitPollRate +// this.deltaBlocksLog = opts.deltaBlocksLog +// this.fromBlockLog = opts.fromBlockLog +// } + +// abstract getFeeOptions( +// address: string, +// ...transactions: commons.transaction.Transaction[] +// ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> + +// abstract getFeeOptionsRaw( +// entrypoint: string, +// data: ethers.BytesLike, +// options?: { +// simulate?: boolean +// } +// ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> + +// abstract gasRefundOptions(address: string, ...transactions: commons.transaction.Transaction[]): Promise + +// abstract relay( +// signedTxs: commons.transaction.IntendedTransactionBundle, +// quote?: FeeQuote, +// waitForReceipt?: boolean +// ): Promise + +// abstract getTransactionCost( +// projectId: number, +// from: string, +// to: string +// ): Promise<{ +// cost: number +// }> + +// abstract getMetaTransactions( +// projectId: number, +// page?: proto.Page +// ): Promise<{ +// page: proto.Page +// transactions: proto.MetaTxnLog[] +// }> + +// abstract listGasSponsors(args: proto.ListGasSponsorsArgs): Promise + +// abstract addGasSponsor(args: proto.AddGasSponsorArgs): Promise + +// abstract updateGasSponsor(args: proto.UpdateGasSponsorArgs): Promise + +// abstract removeGasSponsor(args: proto.RemoveGasSponsorArgs): Promise + +// async simulate(wallet: string, ...transactions: commons.transaction.Transaction[]): Promise { +// return ( +// await Promise.all( +// transactions.map(async tx => { +// // Respect gasLimit request of the transaction (as long as its not 0) +// if (tx.gasLimit && BigInt(tx.gasLimit || 0) !== 0n) { +// return tx.gasLimit +// } + +// // Fee can't be estimated locally for delegateCalls +// if (tx.delegateCall) { +// return DEFAULT_GAS_LIMIT +// } + +// // Fee can't be estimated for self-called if wallet hasn't been deployed +// if (tx.to === wallet && (await this.provider.getCode(wallet).then(code => ethers.getBytes(code).length === 0))) { +// return DEFAULT_GAS_LIMIT +// } + +// if (!this.provider) { +// throw new Error('signer.provider is not set, but is required') +// } + +// // TODO: If the wallet address has been deployed, gas limits can be +// // estimated with more accurately by using self-calls with the batch transactions one by one +// return this.provider.estimateGas({ +// from: wallet, +// to: tx.to, +// data: tx.data, +// value: tx.value +// }) +// }) +// ) +// ).map(gasLimit => ({ +// executed: true, +// succeeded: true, +// gasUsed: Number(gasLimit), +// gasLimit: Number(gasLimit) +// })) +// } + +// async getNonce(address: string, space?: ethers.BigNumberish, blockTag?: ethers.BlockTag): Promise { +// if (!this.provider) { +// throw new Error('provider is not set') +// } + +// if ((await this.provider.getCode(address)) === '0x') { +// return 0 +// } + +// if (space === undefined) { +// space = 0 +// } + +// const module = new ethers.Contract(address, walletContracts.mainModule.abi, this.provider) +// const nonce = await module.readNonce(space, { blockTag: blockTag }) +// return commons.transaction.encodeNonce(space, nonce) +// } + +// async wait( +// metaTxnId: string | commons.transaction.SignedTransactionBundle, +// timeoutDuration?: number, +// delay: number = this.waitPollRate, +// maxFails: number = 5 +// ): Promise { +// if (typeof metaTxnId !== 'string') { +// metaTxnId = commons.transaction.intendedTransactionID(metaTxnId) +// } + +// let timedOut = false + +// const retry = async (f: () => Promise, errorMessage: string): Promise => { +// let fails = 0 + +// while (!timedOut) { +// try { +// return await f() +// } catch (error) { +// fails++ + +// if (maxFails !== undefined && fails >= maxFails) { +// logger.error(`giving up after ${fails} failed attempts${errorMessage ? `: ${errorMessage}` : ''}`, error) +// throw error +// } else { +// logger.warn(`attempt #${fails} failed${errorMessage ? `: ${errorMessage}` : ''}`, error) +// } +// } + +// if (delay > 0) { +// await new Promise(resolve => setTimeout(resolve, delay)) +// } +// } + +// throw new Error(`timed out after ${fails} failed attempts${errorMessage ? `: ${errorMessage}` : ''}`) +// } + +// const waitReceipt = async (): Promise => { +// // Transactions can only get executed on nonce change +// // get all nonce changes and look for metaTxnIds in between logs +// let lastBlock: number = this.fromBlockLog + +// if (lastBlock < 0) { +// const block = await retry(() => this.provider.getBlockNumber(), 'unable to get latest block number') +// lastBlock = block + lastBlock +// } + +// if (typeof metaTxnId !== 'string') { +// throw new Error('impossible') +// } + +// const normalMetaTxnId = metaTxnId.replace('0x', '') + +// while (!timedOut) { +// const block = await retry(() => this.provider.getBlockNumber(), 'unable to get latest block number') + +// const logs = await retry( +// () => +// this.provider.getLogs({ +// fromBlock: Math.max(0, lastBlock - this.deltaBlocksLog), +// toBlock: block, +// // Nonce change event topic +// topics: ['0x1f180c27086c7a39ea2a7b25239d1ab92348f07ca7bb59d1438fcf527568f881'] +// }), +// `unable to get NonceChange logs for blocks ${Math.max(0, lastBlock - this.deltaBlocksLog)} to ${block}` +// ) + +// lastBlock = block + +// // Get receipts of all transactions +// const txs = await Promise.all( +// logs.map(l => +// retry( +// () => this.provider.getTransactionReceipt(l.transactionHash), +// `unable to get receipt for transaction ${l.transactionHash}` +// ) +// ) +// ) + +// // Find a transaction with a TxExecuted log +// const found = txs.find(tx => +// tx?.logs.find( +// l => +// (l.topics.length === 0 && l.data.replace('0x', '') === normalMetaTxnId) || +// (l.topics.length === 1 && +// // TxFailed event topic +// l.topics[0] === '0x3dbd1590ea96dd3253a91f24e64e3a502e1225d602a5731357bc12643070ccd7' && +// l.data.length >= 64 && +// l.data.replace('0x', '').startsWith(normalMetaTxnId)) +// ) +// ) + +// // If found return that +// if (found) { +// const response = await retry(() => this.provider.getTransaction(found.hash), `unable to get transaction ${found.hash}`) +// if (!response) { +// throw new Error(`Transaction response not found for ${metaTxnId}`) +// } + +// // NOTE: we have to do this, because ethers-v6 uses private fields +// // and we can't just extend the class and override the method, so +// // we just modify the response object directly by adding the receipt to it. +// const out: any = response +// out.receipt = found +// return out +// } + +// // Otherwise wait and try again +// if (!timedOut) { +// await new Promise(r => setTimeout(r, delay)) +// } +// } + +// throw new Error(`Timeout waiting for transaction receipt ${metaTxnId}`) +// } + +// if (timeoutDuration !== undefined) { +// return Promise.race([ +// waitReceipt(), +// new Promise((_, reject) => +// setTimeout(() => { +// timedOut = true +// reject(`Timeout waiting for transaction receipt ${metaTxnId}`) +// }, timeoutDuration) +// ) +// ]) +// } else { +// return waitReceipt() +// } +// } +// } + +// function isAbstractProvider(provider: any): provider is ethers.AbstractProvider { +// return ( +// provider && +// typeof provider === 'object' && +// typeof provider.getNetwork === 'function' && +// typeof provider.getBlockNumber === 'function' +// ) +// } diff --git a/packages/wallet/core/src/relayer/bundler.ts b/packages/wallet/core/src/relayer/bundler.ts new file mode 100644 index 0000000000..4468f086de --- /dev/null +++ b/packages/wallet/core/src/relayer/bundler.ts @@ -0,0 +1,23 @@ +import { Payload } from '@0xsequence/wallet-primitives' +import { Address, Hex } from 'ox' +import { UserOperation } from 'ox/erc4337' +import { OperationStatus } from './relayer.js' + +export interface Bundler { + kind: 'bundler' + + id: string + + estimateLimits( + wallet: Address.Address, + payload: Payload.Calls4337_07, + ): Promise<{ speed?: 'slow' | 'standard' | 'fast'; payload: Payload.Calls4337_07 }[]> + relay(entrypoint: Address.Address, userOperation: UserOperation.RpcV07): Promise<{ opHash: Hex.Hex }> + status(opHash: Hex.Hex, chainId: number): Promise + + isAvailable(entrypoint: Address.Address, chainId: number): Promise +} + +export function isBundler(relayer: any): relayer is Bundler { + return 'estimateLimits' in relayer && 'relay' in relayer && 'isAvailable' in relayer +} diff --git a/packages/wallet/core/src/relayer/bundlers/index.ts b/packages/wallet/core/src/relayer/bundlers/index.ts new file mode 100644 index 0000000000..b2a53a17e2 --- /dev/null +++ b/packages/wallet/core/src/relayer/bundlers/index.ts @@ -0,0 +1 @@ +export * from './pimlico.js' diff --git a/packages/wallet/core/src/relayer/bundlers/pimlico.ts b/packages/wallet/core/src/relayer/bundlers/pimlico.ts new file mode 100644 index 0000000000..7452844e27 --- /dev/null +++ b/packages/wallet/core/src/relayer/bundlers/pimlico.ts @@ -0,0 +1,183 @@ +import { Payload } from '@0xsequence/wallet-primitives' +import { Bundler } from '../bundler.js' +import { Provider, Hex, Address, RpcTransport } from 'ox' +import { UserOperation } from 'ox/erc4337' +import { OperationStatus } from '../relayer.js' + +type FeePerGasPair = { + maxFeePerGas: Hex.Hex | bigint + maxPriorityFeePerGas: Hex.Hex | bigint +} + +type PimlicoGasPrice = { + slow: FeePerGasPair + standard: FeePerGasPair + fast: FeePerGasPair +} + +export class PimlicoBundler implements Bundler { + public readonly kind = 'bundler' + public readonly id: string + + public readonly provider: Provider.Provider + public readonly bundlerRpcUrl: string + private readonly fetcher: typeof fetch + + constructor(bundlerRpcUrl: string, provider: Provider.Provider | string, fetcher?: typeof fetch) { + this.id = `pimlico-erc4337-${bundlerRpcUrl}` + this.provider = typeof provider === 'string' ? Provider.from(RpcTransport.fromHttp(provider)) : provider + this.bundlerRpcUrl = bundlerRpcUrl + const resolvedFetch = fetcher ?? (globalThis as any).fetch + if (!resolvedFetch) { + throw new Error('fetch is not available') + } + this.fetcher = resolvedFetch + } + + async isAvailable(entrypoint: Address.Address, chainId: number): Promise { + const [bundlerChainId, supportedEntryPoints] = await Promise.all([ + this.bundlerRpc('eth_chainId', []), + this.bundlerRpc('eth_supportedEntryPoints', []), + ]) + + if (chainId !== Number(bundlerChainId)) { + return false + } + + return supportedEntryPoints.some((ep) => Address.isEqual(ep, entrypoint)) + } + + async relay(entrypoint: Address.Address, userOperation: UserOperation.RpcV07): Promise<{ opHash: Hex.Hex }> { + const status = await this.bundlerRpc('eth_sendUserOperation', [userOperation, entrypoint]) + return { opHash: status } + } + + async estimateLimits( + wallet: Address.Address, + payload: Payload.Calls4337_07, + ): Promise< + { + speed?: 'slow' | 'standard' | 'fast' + payload: Payload.Calls4337_07 + }[] + > { + const gasPrice = await this.bundlerRpc('pimlico_getUserOperationGasPrice', []) + + const dummyOp = Payload.to4337UserOperation(payload, wallet, '0x000010000000000000000000000000000000000000000000') + const rpcOp = UserOperation.toRpc(dummyOp) + const est = await this.bundlerRpc('eth_estimateUserOperationGas', [rpcOp, payload.entrypoint]) + + const estimatedFields = { + callGasLimit: BigInt(est.callGasLimit), + verificationGasLimit: BigInt(est.verificationGasLimit), + preVerificationGas: BigInt(est.preVerificationGas), + paymasterVerificationGasLimit: est.paymasterVerificationGasLimit + ? BigInt(est.paymasterVerificationGasLimit) + : payload.paymasterVerificationGasLimit, + paymasterPostOpGasLimit: est.paymasterPostOpGasLimit + ? BigInt(est.paymasterPostOpGasLimit) + : payload.paymasterPostOpGasLimit, + } + + const passthroughOptions = + payload.maxFeePerGas > 0n || payload.maxPriorityFeePerGas > 0n + ? [this.createEstimateLimitVariation(payload, estimatedFields, undefined, gasPrice.standard)] + : [] + + return [ + ...passthroughOptions, + this.createEstimateLimitVariation(payload, estimatedFields, 'slow', gasPrice.slow), + this.createEstimateLimitVariation(payload, estimatedFields, 'standard', gasPrice.standard), + this.createEstimateLimitVariation(payload, estimatedFields, 'fast', gasPrice.fast), + ] + } + + private createEstimateLimitVariation( + payload: Payload.Calls4337_07, + estimatedFields: any, + speed?: 'slow' | 'standard' | 'fast', + feePerGasPair?: FeePerGasPair, + ) { + return { + speed, + payload: { + ...payload, + ...estimatedFields, + maxFeePerGas: BigInt(feePerGasPair?.maxFeePerGas ?? payload.maxFeePerGas), + maxPriorityFeePerGas: BigInt(feePerGasPair?.maxPriorityFeePerGas ?? payload.maxPriorityFeePerGas), + }, + } + } + + async status(opHash: Hex.Hex, _chainId: number): Promise { + try { + type PimlicoStatusResp = { + status: 'not_found' | 'not_submitted' | 'submitted' | 'rejected' | 'included' | 'failed' | 'reverted' + transactionHash: Hex.Hex | null + } + + let pimlico: PimlicoStatusResp | undefined + try { + pimlico = await this.bundlerRpc('pimlico_getUserOperationStatus', [opHash]) + } catch { + /* ignore - not Pimlico or endpoint down */ + } + + if (pimlico) { + switch (pimlico.status) { + case 'not_submitted': + case 'submitted': + return { status: 'pending' } + case 'rejected': + return { status: 'failed', reason: 'rejected by bundler' } + case 'failed': + case 'reverted': + return { + status: 'failed', + transactionHash: pimlico.transactionHash ?? undefined, + reason: pimlico.status, + } + case 'included': + // fall through to receipt lookup for full info + break + case 'not_found': + default: + return { status: 'unknown' } + } + } + + // Fallback to standard method + const receipt = await this.bundlerRpc('eth_getUserOperationReceipt', [opHash]) + + if (!receipt) return { status: 'pending' } + + const txHash: Hex.Hex | undefined = + (receipt.receipt?.transactionHash as Hex.Hex) ?? (receipt.transactionHash as Hex.Hex) ?? undefined + + const ok = receipt.success === true || receipt.receipt?.status === '0x1' || receipt.receipt?.status === 1 + + return ok + ? { status: 'confirmed', transactionHash: txHash ?? opHash, data: receipt } + : { + status: 'failed', + transactionHash: txHash, + reason: receipt.revertReason ?? 'UserOp reverted', + } + } catch (err: any) { + console.error('[PimlicoBundler.status]', err) + return { status: 'unknown', reason: err?.message ?? 'status lookup failed' } + } + } + + private async bundlerRpc(method: string, params: any[]): Promise { + const body = JSON.stringify({ jsonrpc: '2.0', id: 1, method, params }) + const res = await this.fetcher(this.bundlerRpcUrl, { + method: 'POST', + headers: { 'content-type': 'application/json' }, + body, + }) + const json = await res.json() + if (json.error) throw new Error(json.error.message ?? 'bundler error') + return json.result + } +} diff --git a/packages/wallet/core/src/relayer/index.ts b/packages/wallet/core/src/relayer/index.ts new file mode 100644 index 0000000000..5fb0b67240 --- /dev/null +++ b/packages/wallet/core/src/relayer/index.ts @@ -0,0 +1,7 @@ +// Export the core interfaces and type guards +export * from './relayer.js' +export * from './bundler.js' + +// Group and export implementations +export * as Standard from './standard/index.js' +export * as Bundlers from './bundlers/index.js' diff --git a/packages/wallet/core/src/relayer/relayer.ts b/packages/wallet/core/src/relayer/relayer.ts new file mode 100644 index 0000000000..db28608fca --- /dev/null +++ b/packages/wallet/core/src/relayer/relayer.ts @@ -0,0 +1,87 @@ +import { Payload, Precondition } from '@0xsequence/wallet-primitives' +import { Address, Hex } from 'ox' +import { FeeToken, GetMetaTxnReceiptReturn } from './standard/rpc/index.js' + +export interface FeeOption { + token: FeeToken + to: string + value: string + gasLimit: number +} + +export interface FeeQuote { + _tag: 'FeeQuote' + _quote: unknown +} + +export type OperationUnknownStatus = { + status: 'unknown' + reason?: string +} + +export type OperationQueuedStatus = { + status: 'queued' + reason?: string +} + +export type OperationPendingStatus = { + status: 'pending' + reason?: string +} + +export type OperationPendingPreconditionStatus = { + status: 'pending-precondition' + reason?: string +} + +export type OperationConfirmedStatus = { + status: 'confirmed' + transactionHash: Hex.Hex + data?: GetMetaTxnReceiptReturn +} + +export type OperationFailedStatus = { + status: 'failed' + transactionHash?: Hex.Hex + reason: string + data?: GetMetaTxnReceiptReturn +} + +export type OperationStatus = + | OperationUnknownStatus + | OperationQueuedStatus + | OperationPendingStatus + | OperationPendingPreconditionStatus + | OperationConfirmedStatus + | OperationFailedStatus + +export interface Relayer { + kind: 'relayer' + + type: string + id: string + + isAvailable(wallet: Address.Address, chainId: number): Promise + + feeOptions( + wallet: Address.Address, + chainId: number, + calls: Payload.Call[], + ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> + + relay(to: Address.Address, data: Hex.Hex, chainId: number, quote?: FeeQuote): Promise<{ opHash: Hex.Hex }> + + status(opHash: Hex.Hex, chainId: number): Promise + + checkPrecondition(precondition: Precondition.Precondition): Promise +} + +export function isRelayer(relayer: any): relayer is Relayer { + return ( + 'isAvailable' in relayer && + 'feeOptions' in relayer && + 'relay' in relayer && + 'status' in relayer && + 'checkPrecondition' in relayer + ) +} diff --git a/packages/wallet/core/src/relayer/standard/abi.ts b/packages/wallet/core/src/relayer/standard/abi.ts new file mode 100644 index 0000000000..ccd965a818 --- /dev/null +++ b/packages/wallet/core/src/relayer/standard/abi.ts @@ -0,0 +1,13 @@ +import { AbiFunction } from 'ox' + +// ERC20 ABI functions +export const erc20BalanceOf = AbiFunction.from('function balanceOf(address) returns (uint256)') +export const erc20Allowance = AbiFunction.from('function allowance(address,address) returns (uint256)') + +// ERC721 ABI functions +export const erc721OwnerOf = AbiFunction.from('function ownerOf(uint256) returns (address)') +export const erc721GetApproved = AbiFunction.from('function getApproved(uint256) returns (address)') + +// ERC1155 ABI functions +export const erc1155BalanceOf = AbiFunction.from('function balanceOf(address,uint256) returns (uint256)') +export const erc1155IsApprovedForAll = AbiFunction.from('function isApprovedForAll(address,address) returns (bool)') diff --git a/packages/wallet/core/src/relayer/standard/eip6963.ts b/packages/wallet/core/src/relayer/standard/eip6963.ts new file mode 100644 index 0000000000..a9cb1d8deb --- /dev/null +++ b/packages/wallet/core/src/relayer/standard/eip6963.ts @@ -0,0 +1,71 @@ +import { createStore, EIP6963ProviderInfo, EIP6963ProviderDetail } from 'mipd' +import { EIP1193ProviderAdapter, LocalRelayer } from './local.js' +import { FeeOption, FeeQuote, OperationStatus, Relayer } from '../relayer.js' +import { Address, Hex } from 'ox' +import { Payload } from '@0xsequence/wallet-primitives' +import { IntentPrecondition } from './rpc/relayer.gen.js' + +export class EIP6963Relayer implements Relayer { + public readonly kind = 'relayer' + public readonly type = 'eip6963' + public readonly id: string + public readonly info: EIP6963ProviderInfo + private readonly relayer: LocalRelayer + + constructor(detail: EIP6963ProviderDetail) { + this.info = detail.info + this.id = detail.info.uuid + + this.relayer = new LocalRelayer(new EIP1193ProviderAdapter(detail.provider)) + } + + isAvailable(wallet: Address.Address, chainId: number): Promise { + return this.relayer.isAvailable(wallet, chainId) + } + + feeOptions( + wallet: Address.Address, + chainId: number, + to: Address.Address, + calls: Payload.Call[], + ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> { + return this.relayer.feeOptions(wallet, chainId, to, calls) + } + + async relay(to: Address.Address, data: Hex.Hex, chainId: number, _?: FeeQuote): Promise<{ opHash: Hex.Hex }> { + return this.relayer.relay(to, data, chainId) + } + + status(opHash: Hex.Hex, chainId: number): Promise { + return this.relayer.status(opHash, chainId) + } + + async checkPrecondition(precondition: IntentPrecondition): Promise { + return this.relayer.checkPrecondition(precondition) + } +} + +// Global store instance +let store: ReturnType | undefined + +export function getEIP6963Store() { + if (!store) { + store = createStore() + } + return store +} + +const relayers: Map = new Map() + +export function getRelayers(): EIP6963Relayer[] { + const store = getEIP6963Store() + const providers = store.getProviders() + + for (const detail of providers) { + if (!relayers.has(detail.info.uuid)) { + relayers.set(detail.info.uuid, new EIP6963Relayer(detail)) + } + } + + return Array.from(relayers.values()) +} diff --git a/packages/wallet/core/src/relayer/standard/index.ts b/packages/wallet/core/src/relayer/standard/index.ts new file mode 100644 index 0000000000..12260aef4a --- /dev/null +++ b/packages/wallet/core/src/relayer/standard/index.ts @@ -0,0 +1,5 @@ +export * from './local.js' +export * from './pk-relayer.js' +export * from './sequence.js' +export * as Rpc from './rpc/index.js' +export * as EIP6963 from './eip6963.js' diff --git a/packages/wallet/core/src/relayer/standard/local.ts b/packages/wallet/core/src/relayer/standard/local.ts new file mode 100644 index 0000000000..4135af3b30 --- /dev/null +++ b/packages/wallet/core/src/relayer/standard/local.ts @@ -0,0 +1,346 @@ +import { Payload } from '@0xsequence/wallet-primitives' +import { EIP1193Provider } from 'mipd' +import { AbiFunction, Address, Hex, TransactionReceipt } from 'ox' +import { FeeOption, FeeQuote, OperationStatus, Relayer } from '../index.js' +import { FeeToken, TransactionPrecondition } from '../rpc-relayer/relayer.gen.js' +import { + decodePrecondition, + Erc1155ApprovalPrecondition, + Erc1155BalancePrecondition, + Erc20ApprovalPrecondition, + Erc20BalancePrecondition, + Erc721ApprovalPrecondition, + Erc721OwnershipPrecondition, + NativeBalancePrecondition, +} from '../../preconditions/index.js' +import { + erc20BalanceOf, + erc20Allowance, + erc721OwnerOf, + erc721GetApproved, + erc1155BalanceOf, + erc1155IsApprovedForAll, +} from './abi.js' + +type GenericProviderTransactionReceipt = 'success' | 'failed' | 'unknown' + +export interface GenericProvider { + sendTransaction(args: { to: Address.Address; data: Hex.Hex }, chainId: number): Promise + getBalance(address: Address.Address): Promise + call(args: { to: Address.Address; data: Hex.Hex }): Promise + getTransactionReceipt(txHash: Hex.Hex, chainId: number): Promise +} + +export class LocalRelayer implements Relayer { + public readonly kind = 'relayer' + public readonly type = 'local' + public readonly id = 'local' + + constructor(public readonly provider: GenericProvider) {} + + isAvailable(_wallet: Address.Address, _chainId: number): Promise { + return Promise.resolve(true) + } + + static createFromWindow(window: Window): LocalRelayer | undefined { + const eth = (window as { ethereum?: EIP1193Provider }).ethereum + if (!eth) { + console.warn('Window.ethereum not found, skipping local relayer') + return undefined + } + + return new LocalRelayer(new EIP1193ProviderAdapter(eth)) + } + + static createFromProvider(provider: EIP1193Provider): LocalRelayer { + return new LocalRelayer(new EIP1193ProviderAdapter(provider)) + } + + feeTokens(): Promise<{ isFeeRequired: boolean; tokens?: FeeToken[]; paymentAddress?: Address.Address }> { + return Promise.resolve({ + isFeeRequired: false, + }) + } + + feeOptions( + _wallet: Address.Address, + _chainId: number, + _to: Address.Address, + _calls: Payload.Call[], + ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> { + return Promise.resolve({ options: [] }) + } + + async relay( + to: Address.Address, + data: Hex.Hex, + chainId: number, + quote?: FeeQuote, + preconditions?: TransactionPrecondition[], + checkInterval: number = 5000, + ): Promise<{ opHash: Hex.Hex }> { + // Helper function to check all preconditions + const checkAllPreconditions = async (): Promise => { + if (!preconditions || preconditions.length === 0) { + return true + } + + for (const precondition of preconditions) { + const isValid = await this.checkPrecondition(precondition) + if (!isValid) { + return false + } + } + return true + } + + // Check preconditions immediately + if (await checkAllPreconditions()) { + // If all preconditions are met, relay the transaction + const txHash = await this.provider.sendTransaction( + { + to, + data, + }, + chainId, + ) + + // TODO: Return the opHash instead, but solve the `status` function + // to properly fetch the receipt from an opHash instead of a txHash + return { opHash: txHash as Hex.Hex } + } + + // If not all preconditions are met, set up event listeners and polling + return new Promise((resolve, reject) => { + let timeoutId: NodeJS.Timeout + let isResolved = false + + // Function to check and relay + const checkAndRelay = async () => { + try { + if (isResolved) return + + if (await checkAllPreconditions()) { + isResolved = true + clearTimeout(timeoutId) + const txHash = await this.provider.sendTransaction( + { + to, + data, + }, + chainId, + ) + resolve({ opHash: txHash as Hex.Hex }) + } else { + // Schedule next check + timeoutId = setTimeout(checkAndRelay, checkInterval) + } + } catch (error) { + isResolved = true + clearTimeout(timeoutId) + reject(error) + } + } + + // Start checking + timeoutId = setTimeout(checkAndRelay, checkInterval) + + // Cleanup function + return () => { + isResolved = true + clearTimeout(timeoutId) + } + }) + } + + async status(opHash: Hex.Hex, chainId: number): Promise { + const receipt = await this.provider.getTransactionReceipt(opHash, chainId) + if (receipt === 'unknown') { + // Could be pending but we don't know + return { status: 'unknown' } + } + return receipt === 'success' + ? { status: 'confirmed', transactionHash: opHash } + : { status: 'failed', reason: 'failed' } + } + + async checkPrecondition(precondition: TransactionPrecondition): Promise { + const decoded = decodePrecondition(precondition) + + if (!decoded) { + return false + } + + switch (decoded.type()) { + case 'native-balance': { + const native = decoded as NativeBalancePrecondition + const balance = await this.provider.getBalance(native.address) + if (native.min !== undefined && balance < native.min) { + return false + } + if (native.max !== undefined && balance > native.max) { + return false + } + return true + } + + case 'erc20-balance': { + const erc20 = decoded as Erc20BalancePrecondition + const data = AbiFunction.encodeData(erc20BalanceOf, [erc20.address]) + const result = await this.provider.call({ + to: erc20.token, + data, + }) + const balance = BigInt(result) + if (erc20.min !== undefined && balance < erc20.min) { + return false + } + if (erc20.max !== undefined && balance > erc20.max) { + return false + } + return true + } + + case 'erc20-approval': { + const erc20 = decoded as Erc20ApprovalPrecondition + const data = AbiFunction.encodeData(erc20Allowance, [erc20.address, erc20.operator]) + const result = await this.provider.call({ + to: erc20.token, + data, + }) + const allowance = BigInt(result) + return allowance >= erc20.min + } + + case 'erc721-ownership': { + const erc721 = decoded as Erc721OwnershipPrecondition + const data = AbiFunction.encodeData(erc721OwnerOf, [erc721.tokenId]) + const result = await this.provider.call({ + to: erc721.token, + data, + }) + const owner = '0x' + result.slice(26) + const isOwner = owner.toLowerCase() === erc721.address.toString().toLowerCase() + return erc721.owned === undefined ? isOwner : erc721.owned === isOwner + } + + case 'erc721-approval': { + const erc721 = decoded as Erc721ApprovalPrecondition + const data = AbiFunction.encodeData(erc721GetApproved, [erc721.tokenId]) + const result = await this.provider.call({ + to: erc721.token, + data, + }) + const approved = '0x' + result.slice(26) + return approved.toLowerCase() === erc721.operator.toString().toLowerCase() + } + + case 'erc1155-balance': { + const erc1155 = decoded as Erc1155BalancePrecondition + const data = AbiFunction.encodeData(erc1155BalanceOf, [erc1155.address, erc1155.tokenId]) + const result = await this.provider.call({ + to: erc1155.token, + data, + }) + const balance = BigInt(result) + if (erc1155.min !== undefined && balance < erc1155.min) { + return false + } + if (erc1155.max !== undefined && balance > erc1155.max) { + return false + } + return true + } + + case 'erc1155-approval': { + const erc1155 = decoded as Erc1155ApprovalPrecondition + const data = AbiFunction.encodeData(erc1155IsApprovedForAll, [erc1155.address, erc1155.operator]) + const result = await this.provider.call({ + to: erc1155.token, + data, + }) + return BigInt(result) === 1n + } + + default: + return false + } + } +} + +export class EIP1193ProviderAdapter implements GenericProvider { + constructor(private readonly provider: EIP1193Provider) {} + + private async trySwitchChain(chainId: number) { + try { + await this.provider.request({ + method: 'wallet_switchEthereumChain', + params: [ + { + chainId: `0x${chainId.toString(16)}`, + }, + ], + }) + } catch (error) { + // Log and continue + console.error('Error switching chain', error) + } + } + + async sendTransaction(args: { to: Address.Address; data: Hex.Hex }, chainId: number) { + const accounts: Address.Address[] = await this.provider.request({ method: 'eth_requestAccounts' }) + const from = accounts[0] + + if (!from) { + console.warn('No account selected, skipping local relayer') + return undefined + } + + await this.trySwitchChain(chainId) + + const tx = await this.provider.request({ + method: 'eth_sendTransaction', + params: [ + { + from, + to: args.to, + data: args.data, + }, + ], + }) + + return tx + } + + async getBalance(address: Address.Address) { + const balance = await this.provider.request({ + method: 'eth_getBalance', + params: [address, 'latest'], + }) + return BigInt(balance) + } + + async call(args: { to: Address.Address; data: Hex.Hex }) { + return await this.provider.request({ + method: 'eth_call', + params: [args, 'latest'], + }) + } + + async getTransactionReceipt(txHash: Hex.Hex, chainId: number) { + await this.trySwitchChain(chainId) + + const rpcReceipt = await this.provider.request({ method: 'eth_getTransactionReceipt', params: [txHash] }) + + if (rpcReceipt) { + const receipt = TransactionReceipt.fromRpc(rpcReceipt as Parameters[0]) + if (receipt?.status === 'success') { + return 'success' + } else if (receipt?.status === 'reverted') { + return 'failed' + } + } + + return 'unknown' + } +} diff --git a/packages/wallet/core/src/relayer/standard/pk-relayer.ts b/packages/wallet/core/src/relayer/standard/pk-relayer.ts new file mode 100644 index 0000000000..ac591b47ed --- /dev/null +++ b/packages/wallet/core/src/relayer/standard/pk-relayer.ts @@ -0,0 +1,134 @@ +import { Payload, Precondition } from '@0xsequence/wallet-primitives' +import { Address, Hex, Provider, Secp256k1, TransactionEnvelopeEip1559, TransactionReceipt } from 'ox' +import { LocalRelayer } from './local.js' +import { FeeOption, FeeQuote, OperationStatus, Relayer } from '../relayer.js' + +export class PkRelayer implements Relayer { + public readonly kind = 'relayer' + public readonly type = 'pk' + public readonly id = 'pk' + private readonly relayer: LocalRelayer + + constructor( + privateKey: Hex.Hex, + private readonly provider: Provider.Provider, + ) { + const relayerAddress = Address.fromPublicKey(Secp256k1.getPublicKey({ privateKey })) + this.relayer = new LocalRelayer({ + sendTransaction: async (args, chainId) => { + const providerChainId = Number(await this.provider.request({ method: 'eth_chainId' })) + if (providerChainId !== chainId) { + throw new Error('Provider chain id does not match relayer chain id') + } + + const oxArgs = { ...args, to: args.to as `0x${string}`, data: args.data as `0x${string}` } + // Estimate gas with a safety buffer + const estimatedGas = BigInt(await this.provider.request({ method: 'eth_estimateGas', params: [oxArgs] })) + const safeGasLimit = estimatedGas > 21000n ? (estimatedGas * 12n) / 10n : 50000n + + // Get base fee and priority fee + const baseFee = BigInt(await this.provider.request({ method: 'eth_gasPrice' })) + const priorityFee = 100000000n // 0.1 gwei priority fee + const maxFeePerGas = baseFee + priorityFee + + // Check sender have enough balance + const senderBalance = BigInt( + await this.provider.request({ method: 'eth_getBalance', params: [relayerAddress, 'latest'] }), + ) + if (senderBalance < maxFeePerGas * safeGasLimit) { + console.log('Sender balance:', senderBalance.toString(), 'wei') + throw new Error('Sender has insufficient balance to pay for gas') + } + const nonce = BigInt( + await this.provider.request({ + method: 'eth_getTransactionCount', + params: [relayerAddress, 'latest'], + }), + ) + + // Build the relay envelope + const relayEnvelope = TransactionEnvelopeEip1559.from({ + chainId: Number(chainId), + type: 'eip1559', + from: relayerAddress, + to: oxArgs.to, + data: oxArgs.data, + gas: safeGasLimit, + maxFeePerGas: maxFeePerGas, + maxPriorityFeePerGas: priorityFee, + nonce: nonce, + value: 0n, + }) + const relayerSignature = Secp256k1.sign({ + payload: TransactionEnvelopeEip1559.getSignPayload(relayEnvelope), + privateKey: privateKey, + }) + const signedRelayEnvelope = TransactionEnvelopeEip1559.from(relayEnvelope, { + signature: relayerSignature, + }) + const tx = await this.provider.request({ + method: 'eth_sendRawTransaction', + params: [TransactionEnvelopeEip1559.serialize(signedRelayEnvelope)], + }) + return tx + }, + getBalance: async (address: string): Promise => { + const balanceHex = await this.provider.request({ + method: 'eth_getBalance', + params: [address as Address.Address, 'latest'], + }) + return BigInt(balanceHex) + }, + call: async (args: { to: string; data: string }): Promise => { + const callArgs = { to: args.to as `0x${string}`, data: args.data as `0x${string}` } + return await this.provider.request({ method: 'eth_call', params: [callArgs, 'latest'] }) + }, + getTransactionReceipt: async (txHash: string, chainId: number) => { + Hex.assert(txHash) + + const providerChainId = Number(await this.provider.request({ method: 'eth_chainId' })) + if (providerChainId !== chainId) { + throw new Error('Provider chain id does not match relayer chain id') + } + + const rpcReceipt = await this.provider.request({ method: 'eth_getTransactionReceipt', params: [txHash] }) + if (!rpcReceipt) { + return 'unknown' + } + const receipt = TransactionReceipt.fromRpc(rpcReceipt) + return receipt.status === 'success' ? 'success' : 'failed' + }, + }) + } + + async isAvailable(_wallet: Address.Address, chainId: number): Promise { + const providerChainId = Number(await this.provider.request({ method: 'eth_chainId' })) + return providerChainId === chainId + } + + feeOptions( + wallet: Address.Address, + chainId: number, + to: Address.Address, + calls: Payload.Call[], + ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> { + return this.relayer.feeOptions(wallet, chainId, to, calls) + } + + async relay(to: Address.Address, data: Hex.Hex, chainId: number, _?: FeeQuote): Promise<{ opHash: Hex.Hex }> { + const providerChainId = Number(await this.provider.request({ method: 'eth_chainId' })) + if (providerChainId !== chainId) { + throw new Error('Provider chain id does not match relayer chain id') + } + return this.relayer.relay(to, data, chainId) + } + + status(opHash: Hex.Hex, chainId: number): Promise { + return this.relayer.status(opHash, chainId) + } + + async checkPrecondition(_precondition: Precondition.Precondition): Promise { + // TODO: Implement precondition check + return true + } +} diff --git a/packages/wallet/core/src/relayer/standard/rpc/index.ts b/packages/wallet/core/src/relayer/standard/rpc/index.ts new file mode 100644 index 0000000000..e045b996e0 --- /dev/null +++ b/packages/wallet/core/src/relayer/standard/rpc/index.ts @@ -0,0 +1,466 @@ +import { + Relayer as GenRelayer, + SendMetaTxnReturn as RpcSendMetaTxnReturn, + MetaTxn as RpcMetaTxn, + FeeTokenType, + FeeToken as RpcFeeToken, + TransactionPrecondition, + ETHTxnStatus, +} from './relayer.gen.js' +import { Address, Hex, AbiFunction } from 'ox' +import { Constants, Payload, Network } from '@0xsequence/wallet-primitives' +import { FeeOption, FeeQuote, OperationStatus, Relayer } from '../index.js' +import { + decodePrecondition, + Erc1155ApprovalPrecondition, + Erc1155BalancePrecondition, + Erc20ApprovalPrecondition, + Erc20BalancePrecondition, + Erc721ApprovalPrecondition, + Erc721OwnershipPrecondition, + NativeBalancePrecondition, +} from '../../preconditions/index.js' +import { + erc20BalanceOf, + erc20Allowance, + erc721OwnerOf, + erc721GetApproved, + erc1155BalanceOf, + erc1155IsApprovedForAll, +} from '../standard/abi.js' +import { PublicClient, createPublicClient, http, Chain } from 'viem' +import * as chains from 'viem/chains' + +export type Fetch = (input: RequestInfo, init?: RequestInit) => Promise + +/** + * Convert a Sequence Network to a viem Chain + */ +const networkToChain = (network: Network.Network): Chain => { + return { + id: network.chainId, + name: network.title || network.name, + nativeCurrency: { + name: network.nativeCurrency.name, + symbol: network.nativeCurrency.symbol, + decimals: network.nativeCurrency.decimals, + }, + rpcUrls: { + default: { + http: [network.rpcUrl], + }, + }, + blockExplorers: network.blockExplorer + ? { + default: { + name: network.blockExplorer.name || 'Explorer', + url: network.blockExplorer.url, + }, + } + : undefined, + contracts: network.contracts + ? Object.entries(network.contracts).reduce( + (acc, [name, address]) => { + acc[name] = { address } + return acc + }, + {} as Record, + ) + : undefined, + } as Chain +} + +export const getChain = (chainId: number): Chain => { + // First try to get the chain from Sequence's network configurations + const sequenceNetwork = Network.getNetworkFromChainId(chainId) + if (sequenceNetwork) { + return networkToChain(sequenceNetwork) + } + + // Fall back to viem's built-in chains + const viemChain = Object.values(chains).find( + (c: unknown) => typeof c === 'object' && c !== null && 'id' in c && c.id === chainId, + ) + if (viemChain) { + return viemChain as Chain + } + + throw new Error(`Chain with id ${chainId} not found in Sequence networks or viem chains`) +} + +export class RpcRelayer implements Relayer { + public readonly kind = 'relayer' + public readonly type = 'rpc' + public readonly id: string + public readonly chainId: number + private client: GenRelayer + private fetch: Fetch + private provider: PublicClient + private readonly projectAccessKey?: string + + constructor(hostname: string, chainId: number, rpcUrl: string, fetchImpl?: Fetch, projectAccessKey?: string) { + this.id = `rpc:${hostname}` + this.chainId = chainId + this.projectAccessKey = projectAccessKey + const effectiveFetch = fetchImpl || (typeof window !== 'undefined' ? window.fetch.bind(window) : undefined) + if (!effectiveFetch) { + throw new Error('Fetch implementation is required but not available in this environment.') + } + this.fetch = effectiveFetch + this.client = new GenRelayer(hostname, this.fetch) + + // Get the chain from the chainId + const chain = getChain(chainId) + + // Create viem PublicClient with the provided RPC URL + this.provider = createPublicClient({ + chain, + transport: http(rpcUrl), + }) + } + + isAvailable(_wallet: Address.Address, chainId: number): Promise { + return Promise.resolve(this.chainId === chainId) + } + + async feeTokens(): Promise<{ isFeeRequired: boolean; tokens?: RpcFeeToken[]; paymentAddress?: Address.Address }> { + try { + const { isFeeRequired, tokens, paymentAddress } = await this.client.feeTokens() + if (isFeeRequired) { + Address.assert(paymentAddress) + return { + isFeeRequired, + tokens, + paymentAddress, + } + } + // Not required + return { + isFeeRequired, + } + } catch (e) { + console.warn('RpcRelayer.feeTokens failed:', e) + return { isFeeRequired: false } + } + } + + async feeOptions( + wallet: Address.Address, + chainId: number, + to: Address.Address, + calls: Payload.Call[], + ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> { + // IMPORTANT: + // The relayer FeeOptions endpoint simulates `eth_call(to, data)`. + // wallet-webapp-v3 requests FeeOptions with `to = wallet` and `data = Payload.encode(calls, self=wallet)`. + // This works for undeployed wallets and avoids guest-module simulation pitfalls. + const callsStruct: Payload.Calls = { type: 'call', space: 0n, nonce: 0n, calls: calls } + + const feeOptionsTo = wallet + const data = Payload.encode(callsStruct, wallet) + + try { + const result = await this.client.feeOptions( + { + wallet, + to: feeOptionsTo, + data: Hex.fromBytes(data), + }, + { ...(this.projectAccessKey ? { 'X-Access-Key': this.projectAccessKey } : undefined) }, + ) + + const quote = result.quote ? ({ _tag: 'FeeQuote', _quote: result.quote } as FeeQuote) : undefined + const options = result.options.map((option) => ({ + token: { + ...option.token, + contractAddress: this.mapRpcFeeTokenToAddress(option.token), + }, + to: option.to, + value: option.value, + gasLimit: option.gasLimit, + })) + + return { options, quote } + } catch (e) { + console.warn('RpcRelayer.feeOptions failed:', e) + return { options: [] } + } + } + + async sendMetaTxn( + walletAddress: Address.Address, + to: Address.Address, + data: Hex.Hex, + chainId: number, + quote?: FeeQuote, + preconditions?: TransactionPrecondition[], + ): Promise<{ opHash: Hex.Hex }> { + console.log('sendMetaTxn', walletAddress, to, data, chainId, quote, preconditions) + const rpcCall: RpcMetaTxn = { + walletAddress: walletAddress, + contract: to, + input: data, + } + + const result: RpcSendMetaTxnReturn = await this.client.sendMetaTxn( + { + call: rpcCall, + quote: quote ? JSON.stringify(quote._quote) : undefined, + preconditions: preconditions, + }, + { ...(this.projectAccessKey ? { 'X-Access-Key': this.projectAccessKey } : undefined) }, + ) + + if (!result.status) { + console.error('RpcRelayer.relay failed', result) + throw new Error(`Relay failed: TxnHash ${result.txnHash}`) + } + + return { opHash: Hex.fromString(result.txnHash) } + } + + async relay( + to: Address.Address, + data: Hex.Hex, + chainId: number, + quote?: FeeQuote, + preconditions?: TransactionPrecondition[], + ): Promise<{ opHash: Hex.Hex }> { + console.log('relay', to, data, chainId, quote, preconditions) + const rpcCall: RpcMetaTxn = { + walletAddress: to, + contract: to, + input: data, + } + + const result: RpcSendMetaTxnReturn = await this.client.sendMetaTxn( + { + call: rpcCall, + quote: quote ? JSON.stringify(quote._quote) : undefined, + preconditions: preconditions, + }, + { ...(this.projectAccessKey ? { 'X-Access-Key': this.projectAccessKey } : undefined) }, + ) + + if (!result.status) { + console.error('RpcRelayer.relay failed', result) + throw new Error(`Relay failed: TxnHash ${result.txnHash}`) + } + + return { opHash: `0x${result.txnHash}` } + } + + async status(opHash: Hex.Hex, _chainId: number): Promise { + try { + const cleanedOpHash = opHash.startsWith('0x') ? opHash.substring(2) : opHash + const result = await this.client.getMetaTxnReceipt({ metaTxID: cleanedOpHash }) + const receipt = result.receipt + + if (!receipt) { + console.warn(`RpcRelayer.status: receipt not found for opHash ${opHash}`) + return { status: 'unknown' } + } + + if (!receipt.status) { + console.warn(`RpcRelayer.status: receipt status not found for opHash ${opHash}`) + return { status: 'unknown' } + } + + switch (receipt.status as ETHTxnStatus) { + case ETHTxnStatus.QUEUED: + case ETHTxnStatus.PENDING_PRECONDITION: + case ETHTxnStatus.SENT: + return { status: 'pending' } + case ETHTxnStatus.SUCCEEDED: + return { status: 'confirmed', transactionHash: receipt.txnHash as Hex.Hex, data: result } + case ETHTxnStatus.FAILED: + case ETHTxnStatus.PARTIALLY_FAILED: + return { + status: 'failed', + transactionHash: receipt.txnHash ? (receipt.txnHash as Hex.Hex) : undefined, + reason: receipt.revertReason || 'Relayer reported failure', + data: result, + } + case ETHTxnStatus.DROPPED: + return { status: 'failed', reason: 'Transaction dropped' } + case ETHTxnStatus.UNKNOWN: + default: + return { status: 'unknown' } + } + } catch (error) { + console.error(`RpcRelayer.status failed for opHash ${opHash}:`, error) + return { status: 'failed', reason: 'Failed to fetch status' } + } + } + + async checkPrecondition(precondition: TransactionPrecondition): Promise { + const decoded = decodePrecondition(precondition) + + if (!decoded) { + return false + } + + switch (decoded.type()) { + case 'native-balance': { + const native = decoded as NativeBalancePrecondition + try { + const balance = await this.provider.getBalance({ address: native.address }) + const minWei = native.min !== undefined ? BigInt(native.min) : undefined + const maxWei = native.max !== undefined ? BigInt(native.max) : undefined + + if (minWei !== undefined && maxWei !== undefined) { + return balance >= minWei && balance <= maxWei + } + if (minWei !== undefined) { + return balance >= minWei + } + if (maxWei !== undefined) { + return balance <= maxWei + } + // If no min or max specified, this is an invalid precondition + console.warn('Native balance precondition has neither min nor max specified') + return false + } catch (error) { + console.error('Error checking native balance:', error) + return false + } + } + + case 'erc20-balance': { + const erc20 = decoded as Erc20BalancePrecondition + try { + const data = AbiFunction.encodeData(erc20BalanceOf, [erc20.address]) + const result = await this.provider.call({ + to: erc20.token.toString() as `0x${string}`, + data: data as `0x${string}`, + }) + const balance = BigInt(result.toString()) + const minWei = erc20.min !== undefined ? BigInt(erc20.min) : undefined + const maxWei = erc20.max !== undefined ? BigInt(erc20.max) : undefined + + if (minWei !== undefined && maxWei !== undefined) { + return balance >= minWei && balance <= maxWei + } + if (minWei !== undefined) { + return balance >= minWei + } + if (maxWei !== undefined) { + return balance <= maxWei + } + console.warn('ERC20 balance precondition has neither min nor max specified') + return false + } catch (error) { + console.error('Error checking ERC20 balance:', error) + return false + } + } + + case 'erc20-approval': { + const erc20 = decoded as Erc20ApprovalPrecondition + try { + const data = AbiFunction.encodeData(erc20Allowance, [erc20.address, erc20.operator]) + const result = await this.provider.call({ + to: erc20.token.toString() as `0x${string}`, + data: data as `0x${string}`, + }) + const allowance = BigInt(result.toString()) + const minAllowance = BigInt(erc20.min) + return allowance >= minAllowance + } catch (error) { + console.error('Error checking ERC20 approval:', error) + return false + } + } + + case 'erc721-ownership': { + const erc721 = decoded as Erc721OwnershipPrecondition + try { + const data = AbiFunction.encodeData(erc721OwnerOf, [erc721.tokenId]) + const result = await this.provider.call({ + to: erc721.token, + data: data, + }) + const resultHex = result.toString() as `0x${string}` + const owner = resultHex.slice(-40) + const isOwner = owner.toLowerCase() === erc721.address.toString().slice(2).toLowerCase() + const expectedOwnership = erc721.owned !== undefined ? erc721.owned : true + return isOwner === expectedOwnership + } catch (error) { + console.error('Error checking ERC721 ownership:', error) + return false + } + } + + case 'erc721-approval': { + const erc721 = decoded as Erc721ApprovalPrecondition + try { + const data = AbiFunction.encodeData(erc721GetApproved, [erc721.tokenId]) + const result = await this.provider.call({ + to: erc721.token.toString() as `0x${string}`, + data: data as `0x${string}`, + }) + const resultHex = result.toString() as `0x${string}` + const approved = resultHex.slice(-40) + return approved.toLowerCase() === erc721.operator.toString().slice(2).toLowerCase() + } catch (error) { + console.error('Error checking ERC721 approval:', error) + return false + } + } + + case 'erc1155-balance': { + const erc1155 = decoded as Erc1155BalancePrecondition + try { + const data = AbiFunction.encodeData(erc1155BalanceOf, [erc1155.address, erc1155.tokenId]) + const result = await this.provider.call({ + to: erc1155.token.toString() as `0x${string}`, + data: data as `0x${string}`, + }) + const balance = BigInt(result.toString()) + const minWei = erc1155.min !== undefined ? BigInt(erc1155.min) : undefined + const maxWei = erc1155.max !== undefined ? BigInt(erc1155.max) : undefined + + if (minWei !== undefined && maxWei !== undefined) { + return balance >= minWei && balance <= maxWei + } + if (minWei !== undefined) { + return balance >= minWei + } + if (maxWei !== undefined) { + return balance <= maxWei + } + console.warn('ERC1155 balance precondition has neither min nor max specified') + return false + } catch (error) { + console.error('Error checking ERC1155 balance:', error) + return false + } + } + + case 'erc1155-approval': { + const erc1155 = decoded as Erc1155ApprovalPrecondition + try { + const data = AbiFunction.encodeData(erc1155IsApprovedForAll, [erc1155.address, erc1155.operator]) + const result = await this.provider.call({ + to: erc1155.token, + data: data, + }) + return BigInt(result.toString()) === 1n + } catch (error) { + console.error('Error checking ERC1155 approval:', error) + return false + } + } + + default: + return false + } + } + + private mapRpcFeeTokenToAddress(rpcToken: RpcFeeToken): Address.Address { + if (rpcToken.type === FeeTokenType.ERC20_TOKEN && rpcToken.contractAddress) { + return Address.from(rpcToken.contractAddress) + } + return Constants.ZeroAddress // Default to zero address for native token or unsupported types + } +} diff --git a/packages/wallet/core/src/relayer/standard/rpc/relayer.gen.ts b/packages/wallet/core/src/relayer/standard/rpc/relayer.gen.ts new file mode 100644 index 0000000000..a9e6b44405 --- /dev/null +++ b/packages/wallet/core/src/relayer/standard/rpc/relayer.gen.ts @@ -0,0 +1,2037 @@ +/* eslint-disable */ +// sequence-relayer v0.4.1 62fe2b49d57c4a0d3960ac1176d48ecfffc7af5a +// -- +// Code generated by webrpc-gen@v0.26.0 with typescript generator. DO NOT EDIT. +// +// webrpc-gen -schema=relayer.ridl -target=typescript -client -out=./clients/relayer.gen.ts + +export const WebrpcHeader = 'Webrpc' + +export const WebrpcHeaderValue = 'webrpc@v0.26.0;gen-typescript@v0.17.0;sequence-relayer@v0.4.1' + +// WebRPC description and code-gen version +export const WebRPCVersion = 'v1' + +// Schema version of your RIDL schema +export const WebRPCSchemaVersion = 'v0.4.1' + +// Schema hash generated from your RIDL schema +export const WebRPCSchemaHash = '62fe2b49d57c4a0d3960ac1176d48ecfffc7af5a' + +type WebrpcGenVersions = { + webrpcGenVersion: string + codeGenName: string + codeGenVersion: string + schemaName: string + schemaVersion: string +} + +export function VersionFromHeader(headers: Headers): WebrpcGenVersions { + const headerValue = headers.get(WebrpcHeader) + if (!headerValue) { + return { + webrpcGenVersion: '', + codeGenName: '', + codeGenVersion: '', + schemaName: '', + schemaVersion: '', + } + } + + return parseWebrpcGenVersions(headerValue) +} + +function parseWebrpcGenVersions(header: string): WebrpcGenVersions { + const versions = header.split(';') + if (versions.length < 3) { + return { + webrpcGenVersion: '', + codeGenName: '', + codeGenVersion: '', + schemaName: '', + schemaVersion: '', + } + } + + const [_, webrpcGenVersion] = versions[0]!.split('@') + const [codeGenName, codeGenVersion] = versions[1]!.split('@') + const [schemaName, schemaVersion] = versions[2]!.split('@') + + return { + webrpcGenVersion: webrpcGenVersion ?? '', + codeGenName: codeGenName ?? '', + codeGenVersion: codeGenVersion ?? '', + schemaName: schemaName ?? '', + schemaVersion: schemaVersion ?? '', + } +} + +// +// Types +// + +export enum ETHTxnStatus { + UNKNOWN = 'UNKNOWN', + DROPPED = 'DROPPED', + QUEUED = 'QUEUED', + SENT = 'SENT', + SUCCEEDED = 'SUCCEEDED', + PARTIALLY_FAILED = 'PARTIALLY_FAILED', + FAILED = 'FAILED', + PENDING_PRECONDITION = 'PENDING_PRECONDITION', +} + +export enum TransferType { + SEND = 'SEND', + RECEIVE = 'RECEIVE', + BRIDGE_DEPOSIT = 'BRIDGE_DEPOSIT', + BRIDGE_WITHDRAW = 'BRIDGE_WITHDRAW', + BURN = 'BURN', + UNKNOWN = 'UNKNOWN', +} + +export enum SimulateStatus { + SKIPPED = 'SKIPPED', + SUCCEEDED = 'SUCCEEDED', + FAILED = 'FAILED', + ABORTED = 'ABORTED', + REVERTED = 'REVERTED', + NOT_ENOUGH_GAS = 'NOT_ENOUGH_GAS', +} + +export enum FeeTokenType { + UNKNOWN = 'UNKNOWN', + ERC20_TOKEN = 'ERC20_TOKEN', + ERC1155_TOKEN = 'ERC1155_TOKEN', +} + +export enum SortOrder { + DESC = 'DESC', + ASC = 'ASC', +} + +export interface Version { + webrpcVersion: string + schemaVersion: string + schemaHash: string + appVersion: string +} + +export interface RuntimeStatus { + healthOK: boolean + startTime: string + uptime: number + ver: string + branch: string + commitHash: string + chainID: number + useEIP1559: boolean + senders: Array + checks: RuntimeChecks +} + +export interface SenderStatus { + index: number + address: string + etherBalance: number + active: boolean +} + +export interface RuntimeChecks {} + +export interface SequenceContext { + factory: string + mainModule: string + mainModuleUpgradable: string + guestModule: string + utils: string +} + +export interface GasTank { + id: number + chainId: number + name: string + currentBalance: number + unlimited: boolean + feeMarkupFactor: number + updatedAt: string + createdAt: string +} + +export interface GasTankBalanceAdjustment { + gasTankId: number + nonce: number + amount: number + totalBalance: number + balanceTimestamp: string + createdAt: string +} + +export interface GasSponsor { + id: number + gasTankId: number + projectId: number + chainId: number + address: string + name: string + active: boolean + updatedAt: string + createdAt: string + deletedAt: string +} + +export interface GasSponsorUsage { + name: string + id: number + totalGasUsed: number + totalTxnFees: number + totalTxnFeesUsd: number + avgGasPrice: number + totalTxns: number + startTime: string + endTime: string +} + +export interface MetaTxn { + walletAddress: string + contract: string + input: string +} + +export interface MetaTxnLog { + id: number + chainId: number + projectId: number + txnHash: string + txnNonce: string + metaTxnID?: string + txnStatus: ETHTxnStatus + txnRevertReason: string + requeues: number + queuedAt: string + sentAt: string + minedAt: string + target: string + input: string + txnArgs: { [key: string]: any } + txnReceipt?: { [key: string]: any } + walletAddress: string + metaTxnNonce: string + gasLimit: number + gasPrice: string + gasUsed: number + gasEstimated: number + gasFeeMarkup?: number + usdRate: string + creditsUsed: number + cost: string + isWhitelisted: boolean + gasSponsor?: number + gasTank?: number + updatedAt: string + createdAt: string +} + +export interface MetaTxnReceipt { + id: string + status: string + revertReason?: string + index: number + logs: Array + receipts: Array + blockNumber: string + txnHash: string + txnReceipt: string +} + +export interface MetaTxnReceiptLog { + address: string + topics: Array + data: string +} + +export interface IntentPrecondition { + type: string + chainId: string + data: any +} + +export interface IntentSolution { + transactions: Array +} + +export interface Transactions { + chainID: string + transactions: Array + preconditions?: Array +} + +export interface Transaction { + delegateCall: boolean + revertOnError: boolean + gasLimit: string + target: string + value: string + data: string +} + +export interface TxnLogUser { + username: string +} + +export interface TxnLogTransfer { + transferType: TransferType + contractAddress: string + from: string + to: string + ids: Array + amounts: Array +} + +export interface SentTransactionsFilter { + pending?: boolean + failed?: boolean +} + +export interface SimulateResult { + executed: boolean + succeeded: boolean + result?: string + reason?: string + gasUsed: number + gasLimit: number +} + +export interface SimulateV3Result { + status: SimulateStatus + result?: string + error?: string + gasUsed: number + gasLimit: number +} + +export interface FeeOption { + token: FeeToken + to: string + value: string + gasLimit: number +} + +export interface FeeToken { + chainId: number + name: string + symbol: string + type: FeeTokenType + decimals?: number + logoURL: string + contractAddress?: string + tokenID?: string +} + +export interface Page { + pageSize?: number + page?: number + more?: boolean + totalRecords?: number + column?: string + before?: any + after?: any + sort?: Array +} + +export interface SortBy { + column: string + order: SortOrder +} + +export interface Relayer { + ping(headers?: object, signal?: AbortSignal): Promise + version(headers?: object, signal?: AbortSignal): Promise + runtimeStatus(headers?: object, signal?: AbortSignal): Promise + getSequenceContext(headers?: object, signal?: AbortSignal): Promise + getChainID(headers?: object, signal?: AbortSignal): Promise + /** + * + * Transactions + * + * TODO (future): rename this to just, 'SendTransaction(txn: MetaTransaction)' or 'SendTransaction(txn: SignedTransaction)', or something.. + * Project ID is only used by service and admin calls. Other clients must have projectID passed via the context + * TODO: rename return txnHash: string to metaTxnID: string + */ + sendMetaTxn(args: SendMetaTxnArgs, headers?: object, signal?: AbortSignal): Promise + getMetaTxnNonce(args: GetMetaTxnNonceArgs, headers?: object, signal?: AbortSignal): Promise + /** + * TODO: one day, make GetMetaTxnReceipt respond immediately with receipt or not + * and add WaitTransactionReceipt method, which will block and wait, similar to how GetMetaTxnReceipt + * is implemented now. + * For backwards compat, we can leave the current GetMetaTxnReceipt how it is, an deprecate it, and introduce + * new, GetTransactionReceipt and WaitTransactionReceipt methods + * we can also accept metaTxnId and txnHash .. so can take either or.. I wonder if ERC-4337 has any convention on this? + */ + getMetaTxnReceipt( + args: GetMetaTxnReceiptArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + simulate(args: SimulateArgs, headers?: object, signal?: AbortSignal): Promise + simulateV3(args: SimulateV3Args, headers?: object, signal?: AbortSignal): Promise + /** + * TODO: deprecated, to be removed by https://github.com/0xsequence/stack/pull/356 at a later date + */ + updateMetaTxnGasLimits( + args: UpdateMetaTxnGasLimitsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + feeTokens(headers?: object, signal?: AbortSignal): Promise + feeOptions(args: FeeOptionsArgs, headers?: object, signal?: AbortSignal): Promise + /** + * TODO: deprecated, to be removed by https://github.com/0xsequence/stack/pull/356 at a later date + */ + getMetaTxnNetworkFeeOptions( + args: GetMetaTxnNetworkFeeOptionsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + getMetaTransactions( + args: GetMetaTransactionsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + getTransactionCost( + args: GetTransactionCostArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Sent transactions from an account. If filter is omitted then it will return all transactions. + */ + sentTransactions(args: SentTransactionsArgs, headers?: object, signal?: AbortSignal): Promise + /** + * Pending transactions waiting to be mined for an account. This endpoint is just a sugar of `SentTransactions` + * with the filter set to pending: true. + */ + pendingTransactions( + args: PendingTransactionsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Legacy Gas Tank + */ + getGasTank(args: GetGasTankArgs, headers?: object, signal?: AbortSignal): Promise + addGasTank(args: AddGasTankArgs, headers?: object, signal?: AbortSignal): Promise + updateGasTank(args: UpdateGasTankArgs, headers?: object, signal?: AbortSignal): Promise + /** + * Legacy Gas Adjustment + */ + nextGasTankBalanceAdjustmentNonce( + args: NextGasTankBalanceAdjustmentNonceArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + adjustGasTankBalance( + args: AdjustGasTankBalanceArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + getGasTankBalanceAdjustment( + args: GetGasTankBalanceAdjustmentArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + listGasTankBalanceAdjustments( + args: ListGasTankBalanceAdjustmentsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Gas Sponsorship + */ + listGasSponsors(args: ListGasSponsorsArgs, headers?: object, signal?: AbortSignal): Promise + getGasSponsor(args: GetGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise + addGasSponsor(args: AddGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise + updateGasSponsor(args: UpdateGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise + removeGasSponsor(args: RemoveGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise + /** + * Gas Sponsor Lookup + */ + addressGasSponsors( + args: AddressGasSponsorsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Project Balance + */ + getProjectBalance( + args: GetProjectBalanceArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + adjustProjectBalance( + args: AdjustProjectBalanceArgs, + headers?: object, + signal?: AbortSignal, + ): Promise +} + +export interface PingArgs {} + +export interface PingReturn { + status: boolean +} +export interface VersionArgs {} + +export interface VersionReturn { + version: Version +} +export interface RuntimeStatusArgs {} + +export interface RuntimeStatusReturn { + status: RuntimeStatus +} +export interface GetSequenceContextArgs {} + +export interface GetSequenceContextReturn { + data: SequenceContext +} +export interface GetChainIDArgs {} + +export interface GetChainIDReturn { + chainID: number +} +export interface SendMetaTxnArgs { + call: MetaTxn + quote?: string + projectID?: number + preconditions?: Array +} + +export interface SendMetaTxnReturn { + status: boolean + txnHash: string +} +export interface GetMetaTxnNonceArgs { + walletContractAddress: string + space?: string +} + +export interface GetMetaTxnNonceReturn { + nonce: string +} +export interface GetMetaTxnReceiptArgs { + metaTxID: string +} + +export interface GetMetaTxnReceiptReturn { + receipt: MetaTxnReceipt +} +export interface SimulateArgs { + wallet: string + transactions: string +} + +export interface SimulateReturn { + results: Array +} +export interface SimulateV3Args { + wallet: string + calls: string +} + +export interface SimulateV3Return { + results: Array +} +export interface UpdateMetaTxnGasLimitsArgs { + walletAddress: string + walletConfig: any + payload: string +} + +export interface UpdateMetaTxnGasLimitsReturn { + payload: string +} +export interface FeeTokensArgs {} + +export interface FeeTokensReturn { + isFeeRequired: boolean + tokens: Array +} +export interface FeeOptionsArgs { + wallet: string + to: string + data: string + simulate?: boolean +} + +export interface FeeOptionsReturn { + options: Array + sponsored: boolean + quote?: string +} +export interface GetMetaTxnNetworkFeeOptionsArgs { + walletConfig: any + payload: string +} + +export interface GetMetaTxnNetworkFeeOptionsReturn { + options: Array +} +export interface GetMetaTransactionsArgs { + projectId: number + page?: Page +} + +export interface GetMetaTransactionsReturn { + page: Page + transactions: Array +} +export interface GetTransactionCostArgs { + projectId: number + from: string + to: string +} + +export interface GetTransactionCostReturn { + cost: number +} +export interface SentTransactionsArgs { + filter?: SentTransactionsFilter + page?: Page +} + +export interface SentTransactionsReturn { + page: Page + transactions: Array +} +export interface PendingTransactionsArgs { + page?: Page +} + +export interface PendingTransactionsReturn { + page: Page + transactions: Array +} +export interface GetGasTankArgs { + id: number +} + +export interface GetGasTankReturn { + gasTank: GasTank +} +export interface AddGasTankArgs { + name: string + feeMarkupFactor: number + unlimited?: boolean +} + +export interface AddGasTankReturn { + status: boolean + gasTank: GasTank +} +export interface UpdateGasTankArgs { + id: number + name?: string + feeMarkupFactor?: number + unlimited?: boolean +} + +export interface UpdateGasTankReturn { + status: boolean + gasTank: GasTank +} +export interface NextGasTankBalanceAdjustmentNonceArgs { + id: number +} + +export interface NextGasTankBalanceAdjustmentNonceReturn { + nonce: number +} +export interface AdjustGasTankBalanceArgs { + id: number + nonce: number + amount: number +} + +export interface AdjustGasTankBalanceReturn { + status: boolean + adjustment: GasTankBalanceAdjustment +} +export interface GetGasTankBalanceAdjustmentArgs { + id: number + nonce: number +} + +export interface GetGasTankBalanceAdjustmentReturn { + adjustment: GasTankBalanceAdjustment +} +export interface ListGasTankBalanceAdjustmentsArgs { + id: number + page?: Page +} + +export interface ListGasTankBalanceAdjustmentsReturn { + page: Page + adjustments: Array +} +export interface ListGasSponsorsArgs { + projectId: number + page?: Page +} + +export interface ListGasSponsorsReturn { + page: Page + gasSponsors: Array +} +export interface GetGasSponsorArgs { + projectId: number + id: number +} + +export interface GetGasSponsorReturn { + gasSponsor: GasSponsor +} +export interface AddGasSponsorArgs { + projectId: number + address: string + name?: string + active?: boolean +} + +export interface AddGasSponsorReturn { + status: boolean + gasSponsor: GasSponsor +} +export interface UpdateGasSponsorArgs { + projectId: number + id: number + name?: string + active?: boolean +} + +export interface UpdateGasSponsorReturn { + status: boolean + gasSponsor: GasSponsor +} +export interface RemoveGasSponsorArgs { + projectId: number + id: number +} + +export interface RemoveGasSponsorReturn { + status: boolean +} +export interface AddressGasSponsorsArgs { + address: string + page?: Page +} + +export interface AddressGasSponsorsReturn { + page: Page + gasSponsors: Array +} +export interface GetProjectBalanceArgs { + projectId: number +} + +export interface GetProjectBalanceReturn { + balance: number +} +export interface AdjustProjectBalanceArgs { + projectId: number + amount: number + identifier: string +} + +export interface AdjustProjectBalanceReturn { + balance: number +} + +// +// Client +// +export class Relayer implements Relayer { + protected hostname: string + protected fetch: Fetch + protected path = '/rpc/Relayer/' + + constructor(hostname: string, fetch: Fetch) { + this.hostname = hostname.replace(/\/*$/, '') + this.fetch = (input: RequestInfo, init?: RequestInit) => fetch(input, init) + } + + private url(name: string): string { + return this.hostname + this.path + name + } + + ping = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('Ping'), createHTTPRequest({}, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + status: _data.status, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + version = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('Version'), createHTTPRequest({}, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + version: _data.version, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + runtimeStatus = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('RuntimeStatus'), createHTTPRequest({}, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + status: _data.status, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getSequenceContext = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetSequenceContext'), createHTTPRequest({}, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + data: _data.data, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getChainID = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetChainID'), createHTTPRequest({}, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + chainID: _data.chainID, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + sendMetaTxn = (args: SendMetaTxnArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('SendMetaTxn'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + status: _data.status, + txnHash: _data.txnHash, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getMetaTxnNonce = ( + args: GetMetaTxnNonceArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('GetMetaTxnNonce'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + nonce: _data.nonce, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getMetaTxnReceipt = ( + args: GetMetaTxnReceiptArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('GetMetaTxnReceipt'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + receipt: _data.receipt, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + simulate = (args: SimulateArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('Simulate'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + results: >_data.results, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + simulateV3 = (args: SimulateV3Args, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('SimulateV3'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + results: >_data.results, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + updateMetaTxnGasLimits = ( + args: UpdateMetaTxnGasLimitsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('UpdateMetaTxnGasLimits'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + payload: _data.payload, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + feeTokens = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('FeeTokens'), createHTTPRequest({}, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + isFeeRequired: _data.isFeeRequired, + tokens: >_data.tokens, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + feeOptions = (args: FeeOptionsArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('FeeOptions'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + options: >_data.options, + sponsored: _data.sponsored, + quote: _data.quote, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getMetaTxnNetworkFeeOptions = ( + args: GetMetaTxnNetworkFeeOptionsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('GetMetaTxnNetworkFeeOptions'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + options: >_data.options, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getMetaTransactions = ( + args: GetMetaTransactionsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('GetMetaTransactions'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + page: _data.page, + transactions: >_data.transactions, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getTransactionCost = ( + args: GetTransactionCostArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('GetTransactionCost'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + cost: _data.cost, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + sentTransactions = ( + args: SentTransactionsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('SentTransactions'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + page: _data.page, + transactions: >_data.transactions, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + pendingTransactions = ( + args: PendingTransactionsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('PendingTransactions'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + page: _data.page, + transactions: >_data.transactions, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getGasTank = (args: GetGasTankArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetGasTank'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + gasTank: _data.gasTank, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + addGasTank = (args: AddGasTankArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('AddGasTank'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + status: _data.status, + gasTank: _data.gasTank, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + updateGasTank = (args: UpdateGasTankArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('UpdateGasTank'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + status: _data.status, + gasTank: _data.gasTank, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + nextGasTankBalanceAdjustmentNonce = ( + args: NextGasTankBalanceAdjustmentNonceArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('NextGasTankBalanceAdjustmentNonce'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + nonce: _data.nonce, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + adjustGasTankBalance = ( + args: AdjustGasTankBalanceArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('AdjustGasTankBalance'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + status: _data.status, + adjustment: _data.adjustment, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getGasTankBalanceAdjustment = ( + args: GetGasTankBalanceAdjustmentArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('GetGasTankBalanceAdjustment'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + adjustment: _data.adjustment, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + listGasTankBalanceAdjustments = ( + args: ListGasTankBalanceAdjustmentsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('ListGasTankBalanceAdjustments'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + page: _data.page, + adjustments: >_data.adjustments, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + listGasSponsors = ( + args: ListGasSponsorsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('ListGasSponsors'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + page: _data.page, + gasSponsors: >_data.gasSponsors, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getGasSponsor = (args: GetGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetGasSponsor'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + gasSponsor: _data.gasSponsor, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + addGasSponsor = (args: AddGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('AddGasSponsor'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + status: _data.status, + gasSponsor: _data.gasSponsor, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + updateGasSponsor = ( + args: UpdateGasSponsorArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('UpdateGasSponsor'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + status: _data.status, + gasSponsor: _data.gasSponsor, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + removeGasSponsor = ( + args: RemoveGasSponsorArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('RemoveGasSponsor'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + status: _data.status, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + addressGasSponsors = ( + args: AddressGasSponsorsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('AddressGasSponsors'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + page: _data.page, + gasSponsors: >_data.gasSponsors, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getProjectBalance = ( + args: GetProjectBalanceArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('GetProjectBalance'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + balance: _data.balance, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + adjustProjectBalance = ( + args: AdjustProjectBalanceArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('AdjustProjectBalance'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + balance: _data.balance, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } +} + +const createHTTPRequest = (body: object = {}, headers: object = {}, signal: AbortSignal | null = null): object => { + const reqHeaders: { [key: string]: string } = { ...headers, 'Content-Type': 'application/json' } + reqHeaders[WebrpcHeader] = WebrpcHeaderValue + + return { + method: 'POST', + headers: reqHeaders, + body: JSON.stringify(body || {}), + signal, + } +} + +const buildResponse = (res: Response): Promise => { + return res.text().then((text) => { + let data + try { + data = JSON.parse(text) + } catch (error) { + let message = '' + if (error instanceof Error) { + message = error.message + } + throw WebrpcBadResponseError.new({ + status: res.status, + cause: `JSON.parse(): ${message}: response text: ${text}`, + }) + } + if (!res.ok) { + const code: number = typeof data.code === 'number' ? data.code : 0 + throw (webrpcErrorByCode[code] || WebrpcError).new(data) + } + return data + }) +} + +// +// Errors +// + +export class WebrpcError extends Error { + name: string + code: number + message: string + status: number + cause?: string + + /** @deprecated Use message instead of msg. Deprecated in webrpc v0.11.0. */ + msg: string + + constructor(name: string, code: number, message: string, status: number, cause?: string) { + super(message) + this.name = name || 'WebrpcError' + this.code = typeof code === 'number' ? code : 0 + this.message = message || `endpoint error ${this.code}` + this.msg = this.message + this.status = typeof status === 'number' ? status : 0 + this.cause = cause + Object.setPrototypeOf(this, WebrpcError.prototype) + } + + static new(payload: any): WebrpcError { + return new this(payload.error, payload.code, payload.message || payload.msg, payload.status, payload.cause) + } +} + +// Webrpc errors + +export class WebrpcEndpointError extends WebrpcError { + constructor( + name: string = 'WebrpcEndpoint', + code: number = 0, + message: string = `endpoint error`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcEndpointError.prototype) + } +} + +export class WebrpcRequestFailedError extends WebrpcError { + constructor( + name: string = 'WebrpcRequestFailed', + code: number = -1, + message: string = `request failed`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcRequestFailedError.prototype) + } +} + +export class WebrpcBadRouteError extends WebrpcError { + constructor( + name: string = 'WebrpcBadRoute', + code: number = -2, + message: string = `bad route`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadRouteError.prototype) + } +} + +export class WebrpcBadMethodError extends WebrpcError { + constructor( + name: string = 'WebrpcBadMethod', + code: number = -3, + message: string = `bad method`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadMethodError.prototype) + } +} + +export class WebrpcBadRequestError extends WebrpcError { + constructor( + name: string = 'WebrpcBadRequest', + code: number = -4, + message: string = `bad request`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadRequestError.prototype) + } +} + +export class WebrpcBadResponseError extends WebrpcError { + constructor( + name: string = 'WebrpcBadResponse', + code: number = -5, + message: string = `bad response`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadResponseError.prototype) + } +} + +export class WebrpcServerPanicError extends WebrpcError { + constructor( + name: string = 'WebrpcServerPanic', + code: number = -6, + message: string = `server panic`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcServerPanicError.prototype) + } +} + +export class WebrpcInternalErrorError extends WebrpcError { + constructor( + name: string = 'WebrpcInternalError', + code: number = -7, + message: string = `internal error`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcInternalErrorError.prototype) + } +} + +export class WebrpcClientDisconnectedError extends WebrpcError { + constructor( + name: string = 'WebrpcClientDisconnected', + code: number = -8, + message: string = `client disconnected`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcClientDisconnectedError.prototype) + } +} + +export class WebrpcStreamLostError extends WebrpcError { + constructor( + name: string = 'WebrpcStreamLost', + code: number = -9, + message: string = `stream lost`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcStreamLostError.prototype) + } +} + +export class WebrpcStreamFinishedError extends WebrpcError { + constructor( + name: string = 'WebrpcStreamFinished', + code: number = -10, + message: string = `stream finished`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcStreamFinishedError.prototype) + } +} + +// Schema errors + +export class UnauthorizedError extends WebrpcError { + constructor( + name: string = 'Unauthorized', + code: number = 1000, + message: string = `Unauthorized access`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, UnauthorizedError.prototype) + } +} + +export class PermissionDeniedError extends WebrpcError { + constructor( + name: string = 'PermissionDenied', + code: number = 1001, + message: string = `Permission denied`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, PermissionDeniedError.prototype) + } +} + +export class SessionExpiredError extends WebrpcError { + constructor( + name: string = 'SessionExpired', + code: number = 1002, + message: string = `Session expired`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, SessionExpiredError.prototype) + } +} + +export class MethodNotFoundError extends WebrpcError { + constructor( + name: string = 'MethodNotFound', + code: number = 1003, + message: string = `Method not found`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, MethodNotFoundError.prototype) + } +} + +export class RequestConflictError extends WebrpcError { + constructor( + name: string = 'RequestConflict', + code: number = 1004, + message: string = `Conflict with target resource`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, RequestConflictError.prototype) + } +} + +export class AbortedError extends WebrpcError { + constructor( + name: string = 'Aborted', + code: number = 1005, + message: string = `Request aborted`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, AbortedError.prototype) + } +} + +export class GeoblockedError extends WebrpcError { + constructor( + name: string = 'Geoblocked', + code: number = 1006, + message: string = `Geoblocked region`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, GeoblockedError.prototype) + } +} + +export class RateLimitedError extends WebrpcError { + constructor( + name: string = 'RateLimited', + code: number = 1007, + message: string = `Rate-limited. Please slow down.`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, RateLimitedError.prototype) + } +} + +export class ProjectNotFoundError extends WebrpcError { + constructor( + name: string = 'ProjectNotFound', + code: number = 1008, + message: string = `Project not found`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, ProjectNotFoundError.prototype) + } +} + +export class AccessKeyNotFoundError extends WebrpcError { + constructor( + name: string = 'AccessKeyNotFound', + code: number = 1101, + message: string = `Access key not found`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, AccessKeyNotFoundError.prototype) + } +} + +export class AccessKeyMismatchError extends WebrpcError { + constructor( + name: string = 'AccessKeyMismatch', + code: number = 1102, + message: string = `Access key mismatch`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, AccessKeyMismatchError.prototype) + } +} + +export class InvalidOriginError extends WebrpcError { + constructor( + name: string = 'InvalidOrigin', + code: number = 1103, + message: string = `Invalid origin for Access Key`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, InvalidOriginError.prototype) + } +} + +export class InvalidServiceError extends WebrpcError { + constructor( + name: string = 'InvalidService', + code: number = 1104, + message: string = `Service not enabled for Access key`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, InvalidServiceError.prototype) + } +} + +export class UnauthorizedUserError extends WebrpcError { + constructor( + name: string = 'UnauthorizedUser', + code: number = 1105, + message: string = `Unauthorized user`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, UnauthorizedUserError.prototype) + } +} + +export class QuotaExceededError extends WebrpcError { + constructor( + name: string = 'QuotaExceeded', + code: number = 1200, + message: string = `Quota request exceeded`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, QuotaExceededError.prototype) + } +} + +export class QuotaRateLimitError extends WebrpcError { + constructor( + name: string = 'QuotaRateLimit', + code: number = 1201, + message: string = `Quota rate limit exceeded`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, QuotaRateLimitError.prototype) + } +} + +export class NoDefaultKeyError extends WebrpcError { + constructor( + name: string = 'NoDefaultKey', + code: number = 1300, + message: string = `No default access key found`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, NoDefaultKeyError.prototype) + } +} + +export class MaxAccessKeysError extends WebrpcError { + constructor( + name: string = 'MaxAccessKeys', + code: number = 1301, + message: string = `Access keys limit reached`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, MaxAccessKeysError.prototype) + } +} + +export class AtLeastOneKeyError extends WebrpcError { + constructor( + name: string = 'AtLeastOneKey', + code: number = 1302, + message: string = `You need at least one Access Key`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, AtLeastOneKeyError.prototype) + } +} + +export class TimeoutError extends WebrpcError { + constructor( + name: string = 'Timeout', + code: number = 1900, + message: string = `Request timed out`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, TimeoutError.prototype) + } +} + +export class InvalidArgumentError extends WebrpcError { + constructor( + name: string = 'InvalidArgument', + code: number = 2001, + message: string = `Invalid argument`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, InvalidArgumentError.prototype) + } +} + +export class UnavailableError extends WebrpcError { + constructor( + name: string = 'Unavailable', + code: number = 2002, + message: string = `Unavailable resource`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, UnavailableError.prototype) + } +} + +export class QueryFailedError extends WebrpcError { + constructor( + name: string = 'QueryFailed', + code: number = 2003, + message: string = `Query failed`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, QueryFailedError.prototype) + } +} + +export class NotFoundError extends WebrpcError { + constructor( + name: string = 'NotFound', + code: number = 3000, + message: string = `Resource not found`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, NotFoundError.prototype) + } +} + +export class InsufficientFeeError extends WebrpcError { + constructor( + name: string = 'InsufficientFee', + code: number = 3004, + message: string = `Insufficient fee`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, InsufficientFeeError.prototype) + } +} + +export class NotEnoughBalanceError extends WebrpcError { + constructor( + name: string = 'NotEnoughBalance', + code: number = 3005, + message: string = `Not enough balance`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, NotEnoughBalanceError.prototype) + } +} + +export class SimulationFailedError extends WebrpcError { + constructor( + name: string = 'SimulationFailed', + code: number = 3006, + message: string = `Simulation failed`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, SimulationFailedError.prototype) + } +} + +export enum errors { + WebrpcEndpoint = 'WebrpcEndpoint', + WebrpcRequestFailed = 'WebrpcRequestFailed', + WebrpcBadRoute = 'WebrpcBadRoute', + WebrpcBadMethod = 'WebrpcBadMethod', + WebrpcBadRequest = 'WebrpcBadRequest', + WebrpcBadResponse = 'WebrpcBadResponse', + WebrpcServerPanic = 'WebrpcServerPanic', + WebrpcInternalError = 'WebrpcInternalError', + WebrpcClientDisconnected = 'WebrpcClientDisconnected', + WebrpcStreamLost = 'WebrpcStreamLost', + WebrpcStreamFinished = 'WebrpcStreamFinished', + Unauthorized = 'Unauthorized', + PermissionDenied = 'PermissionDenied', + SessionExpired = 'SessionExpired', + MethodNotFound = 'MethodNotFound', + RequestConflict = 'RequestConflict', + Aborted = 'Aborted', + Geoblocked = 'Geoblocked', + RateLimited = 'RateLimited', + ProjectNotFound = 'ProjectNotFound', + AccessKeyNotFound = 'AccessKeyNotFound', + AccessKeyMismatch = 'AccessKeyMismatch', + InvalidOrigin = 'InvalidOrigin', + InvalidService = 'InvalidService', + UnauthorizedUser = 'UnauthorizedUser', + QuotaExceeded = 'QuotaExceeded', + QuotaRateLimit = 'QuotaRateLimit', + NoDefaultKey = 'NoDefaultKey', + MaxAccessKeys = 'MaxAccessKeys', + AtLeastOneKey = 'AtLeastOneKey', + Timeout = 'Timeout', + InvalidArgument = 'InvalidArgument', + Unavailable = 'Unavailable', + QueryFailed = 'QueryFailed', + NotFound = 'NotFound', + InsufficientFee = 'InsufficientFee', + NotEnoughBalance = 'NotEnoughBalance', + SimulationFailed = 'SimulationFailed', +} + +export enum WebrpcErrorCodes { + WebrpcEndpoint = 0, + WebrpcRequestFailed = -1, + WebrpcBadRoute = -2, + WebrpcBadMethod = -3, + WebrpcBadRequest = -4, + WebrpcBadResponse = -5, + WebrpcServerPanic = -6, + WebrpcInternalError = -7, + WebrpcClientDisconnected = -8, + WebrpcStreamLost = -9, + WebrpcStreamFinished = -10, + Unauthorized = 1000, + PermissionDenied = 1001, + SessionExpired = 1002, + MethodNotFound = 1003, + RequestConflict = 1004, + Aborted = 1005, + Geoblocked = 1006, + RateLimited = 1007, + ProjectNotFound = 1008, + AccessKeyNotFound = 1101, + AccessKeyMismatch = 1102, + InvalidOrigin = 1103, + InvalidService = 1104, + UnauthorizedUser = 1105, + QuotaExceeded = 1200, + QuotaRateLimit = 1201, + NoDefaultKey = 1300, + MaxAccessKeys = 1301, + AtLeastOneKey = 1302, + Timeout = 1900, + InvalidArgument = 2001, + Unavailable = 2002, + QueryFailed = 2003, + NotFound = 3000, + InsufficientFee = 3004, + NotEnoughBalance = 3005, + SimulationFailed = 3006, +} + +export const webrpcErrorByCode: { [code: number]: any } = { + [0]: WebrpcEndpointError, + [-1]: WebrpcRequestFailedError, + [-2]: WebrpcBadRouteError, + [-3]: WebrpcBadMethodError, + [-4]: WebrpcBadRequestError, + [-5]: WebrpcBadResponseError, + [-6]: WebrpcServerPanicError, + [-7]: WebrpcInternalErrorError, + [-8]: WebrpcClientDisconnectedError, + [-9]: WebrpcStreamLostError, + [-10]: WebrpcStreamFinishedError, + [1000]: UnauthorizedError, + [1001]: PermissionDeniedError, + [1002]: SessionExpiredError, + [1003]: MethodNotFoundError, + [1004]: RequestConflictError, + [1005]: AbortedError, + [1006]: GeoblockedError, + [1007]: RateLimitedError, + [1008]: ProjectNotFoundError, + [1101]: AccessKeyNotFoundError, + [1102]: AccessKeyMismatchError, + [1103]: InvalidOriginError, + [1104]: InvalidServiceError, + [1105]: UnauthorizedUserError, + [1200]: QuotaExceededError, + [1201]: QuotaRateLimitError, + [1300]: NoDefaultKeyError, + [1301]: MaxAccessKeysError, + [1302]: AtLeastOneKeyError, + [1900]: TimeoutError, + [2001]: InvalidArgumentError, + [2002]: UnavailableError, + [2003]: QueryFailedError, + [3000]: NotFoundError, + [3004]: InsufficientFeeError, + [3005]: NotEnoughBalanceError, + [3006]: SimulationFailedError, +} + +export type Fetch = (input: RequestInfo, init?: RequestInit) => Promise diff --git a/packages/wallet/core/src/relayer/standard/sequence.ts b/packages/wallet/core/src/relayer/standard/sequence.ts new file mode 100644 index 0000000000..bb55a97262 --- /dev/null +++ b/packages/wallet/core/src/relayer/standard/sequence.ts @@ -0,0 +1,110 @@ +import { ETHTxnStatus, TransactionPrecondition, Relayer as Service, FeeToken } from '../rpc-relayer/relayer.gen.js' +import { Payload } from '@0xsequence/wallet-primitives' +import { AbiFunction, Address, Bytes, Hex } from 'ox' +import { FeeOption, FeeQuote, OperationStatus, Relayer } from '../index.js' +export class SequenceRelayer implements Relayer { + public readonly kind = 'relayer' + public readonly type = 'sequence' + readonly id = 'sequence' + + private readonly service: Service + + constructor(host: string) { + this.service = new Service(host, fetch) + } + + async isAvailable(_wallet: Address.Address, _chainId: number): Promise { + return true + } + + async feeTokens(): Promise<{ isFeeRequired: boolean; tokens?: FeeToken[]; paymentAddress?: Address.Address }> { + const { isFeeRequired, tokens, paymentAddress } = await this.service.feeTokens() + if (isFeeRequired) { + Address.assert(paymentAddress) + return { + isFeeRequired, + tokens, + paymentAddress, + } + } + // Not required + return { + isFeeRequired, + } + } + + async feeOptions( + wallet: Address.Address, + _chainId: number, + to: Address.Address, + calls: Payload.Call[], + ): Promise<{ options: FeeOption[]; quote?: FeeQuote }> { + const execute = AbiFunction.from('function execute(bytes calldata _payload, bytes calldata _signature)') + const payload = Payload.encode({ type: 'call', space: 0n, nonce: 0n, calls }, to) + const signature = '0x0001' // TODO: use a stub signature + const data = AbiFunction.encodeData(execute, [Bytes.toHex(payload), signature]) + + const { options, quote } = await this.service.feeOptions({ wallet, to, data }) + + return { + options, + quote: quote ? { _tag: 'FeeQuote', _quote: quote } : undefined, + } + } + + async checkPrecondition(_precondition: TransactionPrecondition): Promise { + // TODO: implement + return false + } + + async relay(to: Address.Address, data: Hex.Hex, _chainId: number, quote?: FeeQuote): Promise<{ opHash: Hex.Hex }> { + const walletAddress = to // TODO: pass wallet address or stop requiring it + + const { txnHash } = await this.service.sendMetaTxn({ + call: { walletAddress, contract: to, input: data }, + quote: quote && (quote._quote as string), + }) + + return { opHash: `0x${txnHash}` } + } + + async status(opHash: Hex.Hex, _chainId: number): Promise { + try { + const { + receipt: { status, revertReason, txnReceipt }, + } = await this.service.getMetaTxnReceipt({ metaTxID: opHash }) + + switch (status) { + case ETHTxnStatus.UNKNOWN: + return { status: 'unknown' } + + case ETHTxnStatus.DROPPED: + return { status: 'failed', reason: revertReason ?? status } + + case ETHTxnStatus.QUEUED: + return { status: 'pending' } + + case ETHTxnStatus.SENT: + return { status: 'pending' } + + case ETHTxnStatus.SUCCEEDED: { + const receipt = JSON.parse(txnReceipt) + const transactionHash = receipt.transactionHash + Hex.assert(transactionHash) + return { status: 'confirmed', transactionHash } + } + + case ETHTxnStatus.PARTIALLY_FAILED: + return { status: 'failed', reason: revertReason ?? status } + + case ETHTxnStatus.FAILED: + return { status: 'failed', reason: revertReason ?? status } + + default: + throw new Error(`unknown transaction status '${status}'`) + } + } catch { + return { status: 'pending' } + } + } +} diff --git a/packages/wallet/core/src/rpc-relayer/index.ts b/packages/wallet/core/src/rpc-relayer/index.ts new file mode 100644 index 0000000000..6e10f600bd --- /dev/null +++ b/packages/wallet/core/src/rpc-relayer/index.ts @@ -0,0 +1 @@ +export * from './relayer.gen.js' diff --git a/packages/wallet/core/src/rpc-relayer/relayer.gen.ts b/packages/wallet/core/src/rpc-relayer/relayer.gen.ts new file mode 100644 index 0000000000..a9e6b44405 --- /dev/null +++ b/packages/wallet/core/src/rpc-relayer/relayer.gen.ts @@ -0,0 +1,2037 @@ +/* eslint-disable */ +// sequence-relayer v0.4.1 62fe2b49d57c4a0d3960ac1176d48ecfffc7af5a +// -- +// Code generated by webrpc-gen@v0.26.0 with typescript generator. DO NOT EDIT. +// +// webrpc-gen -schema=relayer.ridl -target=typescript -client -out=./clients/relayer.gen.ts + +export const WebrpcHeader = 'Webrpc' + +export const WebrpcHeaderValue = 'webrpc@v0.26.0;gen-typescript@v0.17.0;sequence-relayer@v0.4.1' + +// WebRPC description and code-gen version +export const WebRPCVersion = 'v1' + +// Schema version of your RIDL schema +export const WebRPCSchemaVersion = 'v0.4.1' + +// Schema hash generated from your RIDL schema +export const WebRPCSchemaHash = '62fe2b49d57c4a0d3960ac1176d48ecfffc7af5a' + +type WebrpcGenVersions = { + webrpcGenVersion: string + codeGenName: string + codeGenVersion: string + schemaName: string + schemaVersion: string +} + +export function VersionFromHeader(headers: Headers): WebrpcGenVersions { + const headerValue = headers.get(WebrpcHeader) + if (!headerValue) { + return { + webrpcGenVersion: '', + codeGenName: '', + codeGenVersion: '', + schemaName: '', + schemaVersion: '', + } + } + + return parseWebrpcGenVersions(headerValue) +} + +function parseWebrpcGenVersions(header: string): WebrpcGenVersions { + const versions = header.split(';') + if (versions.length < 3) { + return { + webrpcGenVersion: '', + codeGenName: '', + codeGenVersion: '', + schemaName: '', + schemaVersion: '', + } + } + + const [_, webrpcGenVersion] = versions[0]!.split('@') + const [codeGenName, codeGenVersion] = versions[1]!.split('@') + const [schemaName, schemaVersion] = versions[2]!.split('@') + + return { + webrpcGenVersion: webrpcGenVersion ?? '', + codeGenName: codeGenName ?? '', + codeGenVersion: codeGenVersion ?? '', + schemaName: schemaName ?? '', + schemaVersion: schemaVersion ?? '', + } +} + +// +// Types +// + +export enum ETHTxnStatus { + UNKNOWN = 'UNKNOWN', + DROPPED = 'DROPPED', + QUEUED = 'QUEUED', + SENT = 'SENT', + SUCCEEDED = 'SUCCEEDED', + PARTIALLY_FAILED = 'PARTIALLY_FAILED', + FAILED = 'FAILED', + PENDING_PRECONDITION = 'PENDING_PRECONDITION', +} + +export enum TransferType { + SEND = 'SEND', + RECEIVE = 'RECEIVE', + BRIDGE_DEPOSIT = 'BRIDGE_DEPOSIT', + BRIDGE_WITHDRAW = 'BRIDGE_WITHDRAW', + BURN = 'BURN', + UNKNOWN = 'UNKNOWN', +} + +export enum SimulateStatus { + SKIPPED = 'SKIPPED', + SUCCEEDED = 'SUCCEEDED', + FAILED = 'FAILED', + ABORTED = 'ABORTED', + REVERTED = 'REVERTED', + NOT_ENOUGH_GAS = 'NOT_ENOUGH_GAS', +} + +export enum FeeTokenType { + UNKNOWN = 'UNKNOWN', + ERC20_TOKEN = 'ERC20_TOKEN', + ERC1155_TOKEN = 'ERC1155_TOKEN', +} + +export enum SortOrder { + DESC = 'DESC', + ASC = 'ASC', +} + +export interface Version { + webrpcVersion: string + schemaVersion: string + schemaHash: string + appVersion: string +} + +export interface RuntimeStatus { + healthOK: boolean + startTime: string + uptime: number + ver: string + branch: string + commitHash: string + chainID: number + useEIP1559: boolean + senders: Array + checks: RuntimeChecks +} + +export interface SenderStatus { + index: number + address: string + etherBalance: number + active: boolean +} + +export interface RuntimeChecks {} + +export interface SequenceContext { + factory: string + mainModule: string + mainModuleUpgradable: string + guestModule: string + utils: string +} + +export interface GasTank { + id: number + chainId: number + name: string + currentBalance: number + unlimited: boolean + feeMarkupFactor: number + updatedAt: string + createdAt: string +} + +export interface GasTankBalanceAdjustment { + gasTankId: number + nonce: number + amount: number + totalBalance: number + balanceTimestamp: string + createdAt: string +} + +export interface GasSponsor { + id: number + gasTankId: number + projectId: number + chainId: number + address: string + name: string + active: boolean + updatedAt: string + createdAt: string + deletedAt: string +} + +export interface GasSponsorUsage { + name: string + id: number + totalGasUsed: number + totalTxnFees: number + totalTxnFeesUsd: number + avgGasPrice: number + totalTxns: number + startTime: string + endTime: string +} + +export interface MetaTxn { + walletAddress: string + contract: string + input: string +} + +export interface MetaTxnLog { + id: number + chainId: number + projectId: number + txnHash: string + txnNonce: string + metaTxnID?: string + txnStatus: ETHTxnStatus + txnRevertReason: string + requeues: number + queuedAt: string + sentAt: string + minedAt: string + target: string + input: string + txnArgs: { [key: string]: any } + txnReceipt?: { [key: string]: any } + walletAddress: string + metaTxnNonce: string + gasLimit: number + gasPrice: string + gasUsed: number + gasEstimated: number + gasFeeMarkup?: number + usdRate: string + creditsUsed: number + cost: string + isWhitelisted: boolean + gasSponsor?: number + gasTank?: number + updatedAt: string + createdAt: string +} + +export interface MetaTxnReceipt { + id: string + status: string + revertReason?: string + index: number + logs: Array + receipts: Array + blockNumber: string + txnHash: string + txnReceipt: string +} + +export interface MetaTxnReceiptLog { + address: string + topics: Array + data: string +} + +export interface IntentPrecondition { + type: string + chainId: string + data: any +} + +export interface IntentSolution { + transactions: Array +} + +export interface Transactions { + chainID: string + transactions: Array + preconditions?: Array +} + +export interface Transaction { + delegateCall: boolean + revertOnError: boolean + gasLimit: string + target: string + value: string + data: string +} + +export interface TxnLogUser { + username: string +} + +export interface TxnLogTransfer { + transferType: TransferType + contractAddress: string + from: string + to: string + ids: Array + amounts: Array +} + +export interface SentTransactionsFilter { + pending?: boolean + failed?: boolean +} + +export interface SimulateResult { + executed: boolean + succeeded: boolean + result?: string + reason?: string + gasUsed: number + gasLimit: number +} + +export interface SimulateV3Result { + status: SimulateStatus + result?: string + error?: string + gasUsed: number + gasLimit: number +} + +export interface FeeOption { + token: FeeToken + to: string + value: string + gasLimit: number +} + +export interface FeeToken { + chainId: number + name: string + symbol: string + type: FeeTokenType + decimals?: number + logoURL: string + contractAddress?: string + tokenID?: string +} + +export interface Page { + pageSize?: number + page?: number + more?: boolean + totalRecords?: number + column?: string + before?: any + after?: any + sort?: Array +} + +export interface SortBy { + column: string + order: SortOrder +} + +export interface Relayer { + ping(headers?: object, signal?: AbortSignal): Promise + version(headers?: object, signal?: AbortSignal): Promise + runtimeStatus(headers?: object, signal?: AbortSignal): Promise + getSequenceContext(headers?: object, signal?: AbortSignal): Promise + getChainID(headers?: object, signal?: AbortSignal): Promise + /** + * + * Transactions + * + * TODO (future): rename this to just, 'SendTransaction(txn: MetaTransaction)' or 'SendTransaction(txn: SignedTransaction)', or something.. + * Project ID is only used by service and admin calls. Other clients must have projectID passed via the context + * TODO: rename return txnHash: string to metaTxnID: string + */ + sendMetaTxn(args: SendMetaTxnArgs, headers?: object, signal?: AbortSignal): Promise + getMetaTxnNonce(args: GetMetaTxnNonceArgs, headers?: object, signal?: AbortSignal): Promise + /** + * TODO: one day, make GetMetaTxnReceipt respond immediately with receipt or not + * and add WaitTransactionReceipt method, which will block and wait, similar to how GetMetaTxnReceipt + * is implemented now. + * For backwards compat, we can leave the current GetMetaTxnReceipt how it is, an deprecate it, and introduce + * new, GetTransactionReceipt and WaitTransactionReceipt methods + * we can also accept metaTxnId and txnHash .. so can take either or.. I wonder if ERC-4337 has any convention on this? + */ + getMetaTxnReceipt( + args: GetMetaTxnReceiptArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + simulate(args: SimulateArgs, headers?: object, signal?: AbortSignal): Promise + simulateV3(args: SimulateV3Args, headers?: object, signal?: AbortSignal): Promise + /** + * TODO: deprecated, to be removed by https://github.com/0xsequence/stack/pull/356 at a later date + */ + updateMetaTxnGasLimits( + args: UpdateMetaTxnGasLimitsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + feeTokens(headers?: object, signal?: AbortSignal): Promise + feeOptions(args: FeeOptionsArgs, headers?: object, signal?: AbortSignal): Promise + /** + * TODO: deprecated, to be removed by https://github.com/0xsequence/stack/pull/356 at a later date + */ + getMetaTxnNetworkFeeOptions( + args: GetMetaTxnNetworkFeeOptionsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + getMetaTransactions( + args: GetMetaTransactionsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + getTransactionCost( + args: GetTransactionCostArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Sent transactions from an account. If filter is omitted then it will return all transactions. + */ + sentTransactions(args: SentTransactionsArgs, headers?: object, signal?: AbortSignal): Promise + /** + * Pending transactions waiting to be mined for an account. This endpoint is just a sugar of `SentTransactions` + * with the filter set to pending: true. + */ + pendingTransactions( + args: PendingTransactionsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Legacy Gas Tank + */ + getGasTank(args: GetGasTankArgs, headers?: object, signal?: AbortSignal): Promise + addGasTank(args: AddGasTankArgs, headers?: object, signal?: AbortSignal): Promise + updateGasTank(args: UpdateGasTankArgs, headers?: object, signal?: AbortSignal): Promise + /** + * Legacy Gas Adjustment + */ + nextGasTankBalanceAdjustmentNonce( + args: NextGasTankBalanceAdjustmentNonceArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + adjustGasTankBalance( + args: AdjustGasTankBalanceArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + getGasTankBalanceAdjustment( + args: GetGasTankBalanceAdjustmentArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + listGasTankBalanceAdjustments( + args: ListGasTankBalanceAdjustmentsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Gas Sponsorship + */ + listGasSponsors(args: ListGasSponsorsArgs, headers?: object, signal?: AbortSignal): Promise + getGasSponsor(args: GetGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise + addGasSponsor(args: AddGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise + updateGasSponsor(args: UpdateGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise + removeGasSponsor(args: RemoveGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise + /** + * Gas Sponsor Lookup + */ + addressGasSponsors( + args: AddressGasSponsorsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + /** + * Project Balance + */ + getProjectBalance( + args: GetProjectBalanceArgs, + headers?: object, + signal?: AbortSignal, + ): Promise + adjustProjectBalance( + args: AdjustProjectBalanceArgs, + headers?: object, + signal?: AbortSignal, + ): Promise +} + +export interface PingArgs {} + +export interface PingReturn { + status: boolean +} +export interface VersionArgs {} + +export interface VersionReturn { + version: Version +} +export interface RuntimeStatusArgs {} + +export interface RuntimeStatusReturn { + status: RuntimeStatus +} +export interface GetSequenceContextArgs {} + +export interface GetSequenceContextReturn { + data: SequenceContext +} +export interface GetChainIDArgs {} + +export interface GetChainIDReturn { + chainID: number +} +export interface SendMetaTxnArgs { + call: MetaTxn + quote?: string + projectID?: number + preconditions?: Array +} + +export interface SendMetaTxnReturn { + status: boolean + txnHash: string +} +export interface GetMetaTxnNonceArgs { + walletContractAddress: string + space?: string +} + +export interface GetMetaTxnNonceReturn { + nonce: string +} +export interface GetMetaTxnReceiptArgs { + metaTxID: string +} + +export interface GetMetaTxnReceiptReturn { + receipt: MetaTxnReceipt +} +export interface SimulateArgs { + wallet: string + transactions: string +} + +export interface SimulateReturn { + results: Array +} +export interface SimulateV3Args { + wallet: string + calls: string +} + +export interface SimulateV3Return { + results: Array +} +export interface UpdateMetaTxnGasLimitsArgs { + walletAddress: string + walletConfig: any + payload: string +} + +export interface UpdateMetaTxnGasLimitsReturn { + payload: string +} +export interface FeeTokensArgs {} + +export interface FeeTokensReturn { + isFeeRequired: boolean + tokens: Array +} +export interface FeeOptionsArgs { + wallet: string + to: string + data: string + simulate?: boolean +} + +export interface FeeOptionsReturn { + options: Array + sponsored: boolean + quote?: string +} +export interface GetMetaTxnNetworkFeeOptionsArgs { + walletConfig: any + payload: string +} + +export interface GetMetaTxnNetworkFeeOptionsReturn { + options: Array +} +export interface GetMetaTransactionsArgs { + projectId: number + page?: Page +} + +export interface GetMetaTransactionsReturn { + page: Page + transactions: Array +} +export interface GetTransactionCostArgs { + projectId: number + from: string + to: string +} + +export interface GetTransactionCostReturn { + cost: number +} +export interface SentTransactionsArgs { + filter?: SentTransactionsFilter + page?: Page +} + +export interface SentTransactionsReturn { + page: Page + transactions: Array +} +export interface PendingTransactionsArgs { + page?: Page +} + +export interface PendingTransactionsReturn { + page: Page + transactions: Array +} +export interface GetGasTankArgs { + id: number +} + +export interface GetGasTankReturn { + gasTank: GasTank +} +export interface AddGasTankArgs { + name: string + feeMarkupFactor: number + unlimited?: boolean +} + +export interface AddGasTankReturn { + status: boolean + gasTank: GasTank +} +export interface UpdateGasTankArgs { + id: number + name?: string + feeMarkupFactor?: number + unlimited?: boolean +} + +export interface UpdateGasTankReturn { + status: boolean + gasTank: GasTank +} +export interface NextGasTankBalanceAdjustmentNonceArgs { + id: number +} + +export interface NextGasTankBalanceAdjustmentNonceReturn { + nonce: number +} +export interface AdjustGasTankBalanceArgs { + id: number + nonce: number + amount: number +} + +export interface AdjustGasTankBalanceReturn { + status: boolean + adjustment: GasTankBalanceAdjustment +} +export interface GetGasTankBalanceAdjustmentArgs { + id: number + nonce: number +} + +export interface GetGasTankBalanceAdjustmentReturn { + adjustment: GasTankBalanceAdjustment +} +export interface ListGasTankBalanceAdjustmentsArgs { + id: number + page?: Page +} + +export interface ListGasTankBalanceAdjustmentsReturn { + page: Page + adjustments: Array +} +export interface ListGasSponsorsArgs { + projectId: number + page?: Page +} + +export interface ListGasSponsorsReturn { + page: Page + gasSponsors: Array +} +export interface GetGasSponsorArgs { + projectId: number + id: number +} + +export interface GetGasSponsorReturn { + gasSponsor: GasSponsor +} +export interface AddGasSponsorArgs { + projectId: number + address: string + name?: string + active?: boolean +} + +export interface AddGasSponsorReturn { + status: boolean + gasSponsor: GasSponsor +} +export interface UpdateGasSponsorArgs { + projectId: number + id: number + name?: string + active?: boolean +} + +export interface UpdateGasSponsorReturn { + status: boolean + gasSponsor: GasSponsor +} +export interface RemoveGasSponsorArgs { + projectId: number + id: number +} + +export interface RemoveGasSponsorReturn { + status: boolean +} +export interface AddressGasSponsorsArgs { + address: string + page?: Page +} + +export interface AddressGasSponsorsReturn { + page: Page + gasSponsors: Array +} +export interface GetProjectBalanceArgs { + projectId: number +} + +export interface GetProjectBalanceReturn { + balance: number +} +export interface AdjustProjectBalanceArgs { + projectId: number + amount: number + identifier: string +} + +export interface AdjustProjectBalanceReturn { + balance: number +} + +// +// Client +// +export class Relayer implements Relayer { + protected hostname: string + protected fetch: Fetch + protected path = '/rpc/Relayer/' + + constructor(hostname: string, fetch: Fetch) { + this.hostname = hostname.replace(/\/*$/, '') + this.fetch = (input: RequestInfo, init?: RequestInit) => fetch(input, init) + } + + private url(name: string): string { + return this.hostname + this.path + name + } + + ping = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('Ping'), createHTTPRequest({}, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + status: _data.status, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + version = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('Version'), createHTTPRequest({}, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + version: _data.version, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + runtimeStatus = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('RuntimeStatus'), createHTTPRequest({}, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + status: _data.status, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getSequenceContext = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetSequenceContext'), createHTTPRequest({}, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + data: _data.data, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getChainID = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetChainID'), createHTTPRequest({}, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + chainID: _data.chainID, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + sendMetaTxn = (args: SendMetaTxnArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('SendMetaTxn'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + status: _data.status, + txnHash: _data.txnHash, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getMetaTxnNonce = ( + args: GetMetaTxnNonceArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('GetMetaTxnNonce'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + nonce: _data.nonce, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getMetaTxnReceipt = ( + args: GetMetaTxnReceiptArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('GetMetaTxnReceipt'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + receipt: _data.receipt, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + simulate = (args: SimulateArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('Simulate'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + results: >_data.results, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + simulateV3 = (args: SimulateV3Args, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('SimulateV3'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + results: >_data.results, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + updateMetaTxnGasLimits = ( + args: UpdateMetaTxnGasLimitsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('UpdateMetaTxnGasLimits'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + payload: _data.payload, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + feeTokens = (headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('FeeTokens'), createHTTPRequest({}, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + isFeeRequired: _data.isFeeRequired, + tokens: >_data.tokens, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + feeOptions = (args: FeeOptionsArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('FeeOptions'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + options: >_data.options, + sponsored: _data.sponsored, + quote: _data.quote, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getMetaTxnNetworkFeeOptions = ( + args: GetMetaTxnNetworkFeeOptionsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('GetMetaTxnNetworkFeeOptions'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + options: >_data.options, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getMetaTransactions = ( + args: GetMetaTransactionsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('GetMetaTransactions'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + page: _data.page, + transactions: >_data.transactions, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getTransactionCost = ( + args: GetTransactionCostArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('GetTransactionCost'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + cost: _data.cost, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + sentTransactions = ( + args: SentTransactionsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('SentTransactions'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + page: _data.page, + transactions: >_data.transactions, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + pendingTransactions = ( + args: PendingTransactionsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('PendingTransactions'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + page: _data.page, + transactions: >_data.transactions, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getGasTank = (args: GetGasTankArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetGasTank'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + gasTank: _data.gasTank, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + addGasTank = (args: AddGasTankArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('AddGasTank'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + status: _data.status, + gasTank: _data.gasTank, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + updateGasTank = (args: UpdateGasTankArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('UpdateGasTank'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + status: _data.status, + gasTank: _data.gasTank, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + nextGasTankBalanceAdjustmentNonce = ( + args: NextGasTankBalanceAdjustmentNonceArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('NextGasTankBalanceAdjustmentNonce'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + nonce: _data.nonce, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + adjustGasTankBalance = ( + args: AdjustGasTankBalanceArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('AdjustGasTankBalance'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + status: _data.status, + adjustment: _data.adjustment, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getGasTankBalanceAdjustment = ( + args: GetGasTankBalanceAdjustmentArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('GetGasTankBalanceAdjustment'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + adjustment: _data.adjustment, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + listGasTankBalanceAdjustments = ( + args: ListGasTankBalanceAdjustmentsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('ListGasTankBalanceAdjustments'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + page: _data.page, + adjustments: >_data.adjustments, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + listGasSponsors = ( + args: ListGasSponsorsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('ListGasSponsors'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + page: _data.page, + gasSponsors: >_data.gasSponsors, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getGasSponsor = (args: GetGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('GetGasSponsor'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + gasSponsor: _data.gasSponsor, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + addGasSponsor = (args: AddGasSponsorArgs, headers?: object, signal?: AbortSignal): Promise => { + return this.fetch(this.url('AddGasSponsor'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + status: _data.status, + gasSponsor: _data.gasSponsor, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + updateGasSponsor = ( + args: UpdateGasSponsorArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('UpdateGasSponsor'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + status: _data.status, + gasSponsor: _data.gasSponsor, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + removeGasSponsor = ( + args: RemoveGasSponsorArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('RemoveGasSponsor'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + status: _data.status, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + addressGasSponsors = ( + args: AddressGasSponsorsArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('AddressGasSponsors'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + page: _data.page, + gasSponsors: >_data.gasSponsors, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + getProjectBalance = ( + args: GetProjectBalanceArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('GetProjectBalance'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + balance: _data.balance, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } + + adjustProjectBalance = ( + args: AdjustProjectBalanceArgs, + headers?: object, + signal?: AbortSignal, + ): Promise => { + return this.fetch(this.url('AdjustProjectBalance'), createHTTPRequest(args, headers, signal)).then( + (res) => { + return buildResponse(res).then((_data) => { + return { + balance: _data.balance, + } + }) + }, + (error) => { + throw WebrpcRequestFailedError.new({ cause: `fetch(): ${error.message || ''}` }) + }, + ) + } +} + +const createHTTPRequest = (body: object = {}, headers: object = {}, signal: AbortSignal | null = null): object => { + const reqHeaders: { [key: string]: string } = { ...headers, 'Content-Type': 'application/json' } + reqHeaders[WebrpcHeader] = WebrpcHeaderValue + + return { + method: 'POST', + headers: reqHeaders, + body: JSON.stringify(body || {}), + signal, + } +} + +const buildResponse = (res: Response): Promise => { + return res.text().then((text) => { + let data + try { + data = JSON.parse(text) + } catch (error) { + let message = '' + if (error instanceof Error) { + message = error.message + } + throw WebrpcBadResponseError.new({ + status: res.status, + cause: `JSON.parse(): ${message}: response text: ${text}`, + }) + } + if (!res.ok) { + const code: number = typeof data.code === 'number' ? data.code : 0 + throw (webrpcErrorByCode[code] || WebrpcError).new(data) + } + return data + }) +} + +// +// Errors +// + +export class WebrpcError extends Error { + name: string + code: number + message: string + status: number + cause?: string + + /** @deprecated Use message instead of msg. Deprecated in webrpc v0.11.0. */ + msg: string + + constructor(name: string, code: number, message: string, status: number, cause?: string) { + super(message) + this.name = name || 'WebrpcError' + this.code = typeof code === 'number' ? code : 0 + this.message = message || `endpoint error ${this.code}` + this.msg = this.message + this.status = typeof status === 'number' ? status : 0 + this.cause = cause + Object.setPrototypeOf(this, WebrpcError.prototype) + } + + static new(payload: any): WebrpcError { + return new this(payload.error, payload.code, payload.message || payload.msg, payload.status, payload.cause) + } +} + +// Webrpc errors + +export class WebrpcEndpointError extends WebrpcError { + constructor( + name: string = 'WebrpcEndpoint', + code: number = 0, + message: string = `endpoint error`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcEndpointError.prototype) + } +} + +export class WebrpcRequestFailedError extends WebrpcError { + constructor( + name: string = 'WebrpcRequestFailed', + code: number = -1, + message: string = `request failed`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcRequestFailedError.prototype) + } +} + +export class WebrpcBadRouteError extends WebrpcError { + constructor( + name: string = 'WebrpcBadRoute', + code: number = -2, + message: string = `bad route`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadRouteError.prototype) + } +} + +export class WebrpcBadMethodError extends WebrpcError { + constructor( + name: string = 'WebrpcBadMethod', + code: number = -3, + message: string = `bad method`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadMethodError.prototype) + } +} + +export class WebrpcBadRequestError extends WebrpcError { + constructor( + name: string = 'WebrpcBadRequest', + code: number = -4, + message: string = `bad request`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadRequestError.prototype) + } +} + +export class WebrpcBadResponseError extends WebrpcError { + constructor( + name: string = 'WebrpcBadResponse', + code: number = -5, + message: string = `bad response`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcBadResponseError.prototype) + } +} + +export class WebrpcServerPanicError extends WebrpcError { + constructor( + name: string = 'WebrpcServerPanic', + code: number = -6, + message: string = `server panic`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcServerPanicError.prototype) + } +} + +export class WebrpcInternalErrorError extends WebrpcError { + constructor( + name: string = 'WebrpcInternalError', + code: number = -7, + message: string = `internal error`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcInternalErrorError.prototype) + } +} + +export class WebrpcClientDisconnectedError extends WebrpcError { + constructor( + name: string = 'WebrpcClientDisconnected', + code: number = -8, + message: string = `client disconnected`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcClientDisconnectedError.prototype) + } +} + +export class WebrpcStreamLostError extends WebrpcError { + constructor( + name: string = 'WebrpcStreamLost', + code: number = -9, + message: string = `stream lost`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcStreamLostError.prototype) + } +} + +export class WebrpcStreamFinishedError extends WebrpcError { + constructor( + name: string = 'WebrpcStreamFinished', + code: number = -10, + message: string = `stream finished`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, WebrpcStreamFinishedError.prototype) + } +} + +// Schema errors + +export class UnauthorizedError extends WebrpcError { + constructor( + name: string = 'Unauthorized', + code: number = 1000, + message: string = `Unauthorized access`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, UnauthorizedError.prototype) + } +} + +export class PermissionDeniedError extends WebrpcError { + constructor( + name: string = 'PermissionDenied', + code: number = 1001, + message: string = `Permission denied`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, PermissionDeniedError.prototype) + } +} + +export class SessionExpiredError extends WebrpcError { + constructor( + name: string = 'SessionExpired', + code: number = 1002, + message: string = `Session expired`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, SessionExpiredError.prototype) + } +} + +export class MethodNotFoundError extends WebrpcError { + constructor( + name: string = 'MethodNotFound', + code: number = 1003, + message: string = `Method not found`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, MethodNotFoundError.prototype) + } +} + +export class RequestConflictError extends WebrpcError { + constructor( + name: string = 'RequestConflict', + code: number = 1004, + message: string = `Conflict with target resource`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, RequestConflictError.prototype) + } +} + +export class AbortedError extends WebrpcError { + constructor( + name: string = 'Aborted', + code: number = 1005, + message: string = `Request aborted`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, AbortedError.prototype) + } +} + +export class GeoblockedError extends WebrpcError { + constructor( + name: string = 'Geoblocked', + code: number = 1006, + message: string = `Geoblocked region`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, GeoblockedError.prototype) + } +} + +export class RateLimitedError extends WebrpcError { + constructor( + name: string = 'RateLimited', + code: number = 1007, + message: string = `Rate-limited. Please slow down.`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, RateLimitedError.prototype) + } +} + +export class ProjectNotFoundError extends WebrpcError { + constructor( + name: string = 'ProjectNotFound', + code: number = 1008, + message: string = `Project not found`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, ProjectNotFoundError.prototype) + } +} + +export class AccessKeyNotFoundError extends WebrpcError { + constructor( + name: string = 'AccessKeyNotFound', + code: number = 1101, + message: string = `Access key not found`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, AccessKeyNotFoundError.prototype) + } +} + +export class AccessKeyMismatchError extends WebrpcError { + constructor( + name: string = 'AccessKeyMismatch', + code: number = 1102, + message: string = `Access key mismatch`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, AccessKeyMismatchError.prototype) + } +} + +export class InvalidOriginError extends WebrpcError { + constructor( + name: string = 'InvalidOrigin', + code: number = 1103, + message: string = `Invalid origin for Access Key`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, InvalidOriginError.prototype) + } +} + +export class InvalidServiceError extends WebrpcError { + constructor( + name: string = 'InvalidService', + code: number = 1104, + message: string = `Service not enabled for Access key`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, InvalidServiceError.prototype) + } +} + +export class UnauthorizedUserError extends WebrpcError { + constructor( + name: string = 'UnauthorizedUser', + code: number = 1105, + message: string = `Unauthorized user`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, UnauthorizedUserError.prototype) + } +} + +export class QuotaExceededError extends WebrpcError { + constructor( + name: string = 'QuotaExceeded', + code: number = 1200, + message: string = `Quota request exceeded`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, QuotaExceededError.prototype) + } +} + +export class QuotaRateLimitError extends WebrpcError { + constructor( + name: string = 'QuotaRateLimit', + code: number = 1201, + message: string = `Quota rate limit exceeded`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, QuotaRateLimitError.prototype) + } +} + +export class NoDefaultKeyError extends WebrpcError { + constructor( + name: string = 'NoDefaultKey', + code: number = 1300, + message: string = `No default access key found`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, NoDefaultKeyError.prototype) + } +} + +export class MaxAccessKeysError extends WebrpcError { + constructor( + name: string = 'MaxAccessKeys', + code: number = 1301, + message: string = `Access keys limit reached`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, MaxAccessKeysError.prototype) + } +} + +export class AtLeastOneKeyError extends WebrpcError { + constructor( + name: string = 'AtLeastOneKey', + code: number = 1302, + message: string = `You need at least one Access Key`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, AtLeastOneKeyError.prototype) + } +} + +export class TimeoutError extends WebrpcError { + constructor( + name: string = 'Timeout', + code: number = 1900, + message: string = `Request timed out`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, TimeoutError.prototype) + } +} + +export class InvalidArgumentError extends WebrpcError { + constructor( + name: string = 'InvalidArgument', + code: number = 2001, + message: string = `Invalid argument`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, InvalidArgumentError.prototype) + } +} + +export class UnavailableError extends WebrpcError { + constructor( + name: string = 'Unavailable', + code: number = 2002, + message: string = `Unavailable resource`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, UnavailableError.prototype) + } +} + +export class QueryFailedError extends WebrpcError { + constructor( + name: string = 'QueryFailed', + code: number = 2003, + message: string = `Query failed`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, QueryFailedError.prototype) + } +} + +export class NotFoundError extends WebrpcError { + constructor( + name: string = 'NotFound', + code: number = 3000, + message: string = `Resource not found`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, NotFoundError.prototype) + } +} + +export class InsufficientFeeError extends WebrpcError { + constructor( + name: string = 'InsufficientFee', + code: number = 3004, + message: string = `Insufficient fee`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, InsufficientFeeError.prototype) + } +} + +export class NotEnoughBalanceError extends WebrpcError { + constructor( + name: string = 'NotEnoughBalance', + code: number = 3005, + message: string = `Not enough balance`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, NotEnoughBalanceError.prototype) + } +} + +export class SimulationFailedError extends WebrpcError { + constructor( + name: string = 'SimulationFailed', + code: number = 3006, + message: string = `Simulation failed`, + status: number = 0, + cause?: string, + ) { + super(name, code, message, status, cause) + Object.setPrototypeOf(this, SimulationFailedError.prototype) + } +} + +export enum errors { + WebrpcEndpoint = 'WebrpcEndpoint', + WebrpcRequestFailed = 'WebrpcRequestFailed', + WebrpcBadRoute = 'WebrpcBadRoute', + WebrpcBadMethod = 'WebrpcBadMethod', + WebrpcBadRequest = 'WebrpcBadRequest', + WebrpcBadResponse = 'WebrpcBadResponse', + WebrpcServerPanic = 'WebrpcServerPanic', + WebrpcInternalError = 'WebrpcInternalError', + WebrpcClientDisconnected = 'WebrpcClientDisconnected', + WebrpcStreamLost = 'WebrpcStreamLost', + WebrpcStreamFinished = 'WebrpcStreamFinished', + Unauthorized = 'Unauthorized', + PermissionDenied = 'PermissionDenied', + SessionExpired = 'SessionExpired', + MethodNotFound = 'MethodNotFound', + RequestConflict = 'RequestConflict', + Aborted = 'Aborted', + Geoblocked = 'Geoblocked', + RateLimited = 'RateLimited', + ProjectNotFound = 'ProjectNotFound', + AccessKeyNotFound = 'AccessKeyNotFound', + AccessKeyMismatch = 'AccessKeyMismatch', + InvalidOrigin = 'InvalidOrigin', + InvalidService = 'InvalidService', + UnauthorizedUser = 'UnauthorizedUser', + QuotaExceeded = 'QuotaExceeded', + QuotaRateLimit = 'QuotaRateLimit', + NoDefaultKey = 'NoDefaultKey', + MaxAccessKeys = 'MaxAccessKeys', + AtLeastOneKey = 'AtLeastOneKey', + Timeout = 'Timeout', + InvalidArgument = 'InvalidArgument', + Unavailable = 'Unavailable', + QueryFailed = 'QueryFailed', + NotFound = 'NotFound', + InsufficientFee = 'InsufficientFee', + NotEnoughBalance = 'NotEnoughBalance', + SimulationFailed = 'SimulationFailed', +} + +export enum WebrpcErrorCodes { + WebrpcEndpoint = 0, + WebrpcRequestFailed = -1, + WebrpcBadRoute = -2, + WebrpcBadMethod = -3, + WebrpcBadRequest = -4, + WebrpcBadResponse = -5, + WebrpcServerPanic = -6, + WebrpcInternalError = -7, + WebrpcClientDisconnected = -8, + WebrpcStreamLost = -9, + WebrpcStreamFinished = -10, + Unauthorized = 1000, + PermissionDenied = 1001, + SessionExpired = 1002, + MethodNotFound = 1003, + RequestConflict = 1004, + Aborted = 1005, + Geoblocked = 1006, + RateLimited = 1007, + ProjectNotFound = 1008, + AccessKeyNotFound = 1101, + AccessKeyMismatch = 1102, + InvalidOrigin = 1103, + InvalidService = 1104, + UnauthorizedUser = 1105, + QuotaExceeded = 1200, + QuotaRateLimit = 1201, + NoDefaultKey = 1300, + MaxAccessKeys = 1301, + AtLeastOneKey = 1302, + Timeout = 1900, + InvalidArgument = 2001, + Unavailable = 2002, + QueryFailed = 2003, + NotFound = 3000, + InsufficientFee = 3004, + NotEnoughBalance = 3005, + SimulationFailed = 3006, +} + +export const webrpcErrorByCode: { [code: number]: any } = { + [0]: WebrpcEndpointError, + [-1]: WebrpcRequestFailedError, + [-2]: WebrpcBadRouteError, + [-3]: WebrpcBadMethodError, + [-4]: WebrpcBadRequestError, + [-5]: WebrpcBadResponseError, + [-6]: WebrpcServerPanicError, + [-7]: WebrpcInternalErrorError, + [-8]: WebrpcClientDisconnectedError, + [-9]: WebrpcStreamLostError, + [-10]: WebrpcStreamFinishedError, + [1000]: UnauthorizedError, + [1001]: PermissionDeniedError, + [1002]: SessionExpiredError, + [1003]: MethodNotFoundError, + [1004]: RequestConflictError, + [1005]: AbortedError, + [1006]: GeoblockedError, + [1007]: RateLimitedError, + [1008]: ProjectNotFoundError, + [1101]: AccessKeyNotFoundError, + [1102]: AccessKeyMismatchError, + [1103]: InvalidOriginError, + [1104]: InvalidServiceError, + [1105]: UnauthorizedUserError, + [1200]: QuotaExceededError, + [1201]: QuotaRateLimitError, + [1300]: NoDefaultKeyError, + [1301]: MaxAccessKeysError, + [1302]: AtLeastOneKeyError, + [1900]: TimeoutError, + [2001]: InvalidArgumentError, + [2002]: UnavailableError, + [2003]: QueryFailedError, + [3000]: NotFoundError, + [3004]: InsufficientFeeError, + [3005]: NotEnoughBalanceError, + [3006]: SimulationFailedError, +} + +export type Fetch = (input: RequestInfo, init?: RequestInit) => Promise diff --git a/packages/wallet/core/src/signers/guard.ts b/packages/wallet/core/src/signers/guard.ts index 6ee2f21302..3a654edb46 100644 --- a/packages/wallet/core/src/signers/guard.ts +++ b/packages/wallet/core/src/signers/guard.ts @@ -3,10 +3,9 @@ import { Attestation, Payload } from '@0xsequence/wallet-primitives' import * as GuardService from '@0xsequence/guard' import * as Envelope from '../envelope.js' -export type GuardToken = { - id: 'TOTP' | 'PIN' | 'recovery' +type GuardToken = { + id: 'TOTP' | 'PIN' code: string - resetAuth?: boolean } export class Guard { @@ -37,7 +36,7 @@ export class Guard { digest, message, previousSignatures, - token ? { id: token.id, token: token.code, resetAuth: token.resetAuth } : undefined, + token ? { id: token.id, token: token.code } : undefined, ) return { address: this.guard.address, diff --git a/packages/wallet/core/src/signers/pk/encrypted.ts b/packages/wallet/core/src/signers/pk/encrypted.ts index dce0eb3cc7..40d26d16a5 100644 --- a/packages/wallet/core/src/signers/pk/encrypted.ts +++ b/packages/wallet/core/src/signers/pk/encrypted.ts @@ -3,8 +3,8 @@ import { resolveCoreEnv, type CoreEnv, type CryptoLike, type StorageLike, type T import { PkStore } from './index.js' export interface EncryptedData { - iv: BufferSource - data: BufferSource + iv: Uint8Array + data: ArrayBuffer keyPointer: string address: Address.Address publicKey: PublicKey.PublicKey diff --git a/packages/wallet/core/src/signers/session/explicit.ts b/packages/wallet/core/src/signers/session/explicit.ts index ef78c554a6..278027bf20 100644 --- a/packages/wallet/core/src/signers/session/explicit.ts +++ b/packages/wallet/core/src/signers/session/explicit.ts @@ -248,7 +248,10 @@ export class Explicit implements ExplicitSessionSigner { } // Sign it - const callHash = SessionSignature.hashPayloadWithCallIdx(wallet, payload, callIdx, chainId, sessionManagerAddress) + const useDeprecatedHash = + Address.isEqual(sessionManagerAddress, Extensions.Dev1.sessions) || + Address.isEqual(sessionManagerAddress, Extensions.Dev2.sessions) + const callHash = SessionSignature.hashCallWithReplayProtection(payload, callIdx, chainId, useDeprecatedHash) const sessionSignature = await this._privateKey.signDigest(Bytes.fromHex(callHash)) return { permissionIndex: BigInt(permissionIndex), diff --git a/packages/wallet/core/src/signers/session/implicit.ts b/packages/wallet/core/src/signers/session/implicit.ts index 8eb765808a..5e10439356 100644 --- a/packages/wallet/core/src/signers/session/implicit.ts +++ b/packages/wallet/core/src/signers/session/implicit.ts @@ -7,11 +7,11 @@ import { } from '@0xsequence/wallet-primitives' import { AbiFunction, Address, Bytes, Hex, Provider, Secp256k1, Signature } from 'ox' import { MemoryPkStore, PkStore } from '../pk/index.js' -import { ImplicitSessionSigner, SessionSignerValidity } from './session.js' +import { SessionSigner, SessionSignerValidity } from './session.js' export type AttestationParams = Omit -export class Implicit implements ImplicitSessionSigner { +export class Implicit implements SessionSigner { private readonly _privateKey: PkStore private readonly _identitySignature: SequenceSignature.RSY public readonly address: Address.Address @@ -42,11 +42,13 @@ export class Implicit implements ImplicitSessionSigner { } isValid(sessionTopology: SessionConfig.SessionsTopology, _chainId: number): SessionSignerValidity { - const implicitSigners = SessionConfig.getIdentitySigners(sessionTopology) - const thisIdentitySigner = this.identitySigner - if (!implicitSigners.some((s) => Address.isEqual(s, thisIdentitySigner))) { + const implicitSigner = SessionConfig.getIdentitySigner(sessionTopology) + if (!implicitSigner) { return { isValid: false, invalidReason: 'Identity signer not found' } } + if (!Address.isEqual(implicitSigner, this.identitySigner)) { + return { isValid: false, invalidReason: 'Identity signer mismatch' } + } const blacklist = SessionConfig.getImplicitBlacklist(sessionTopology) if (blacklist?.some((b) => Address.isEqual(b, this.address))) { return { isValid: false, invalidReason: 'Blacklisted' } @@ -114,7 +116,10 @@ export class Implicit implements ImplicitSessionSigner { if (!isSupported) { throw new Error('Unsupported call') } - const callHash = SessionSignature.hashPayloadWithCallIdx(wallet, payload, callIdx, chainId, sessionManagerAddress) + const useDeprecatedHash = + Address.isEqual(sessionManagerAddress, Extensions.Dev1.sessions) || + Address.isEqual(sessionManagerAddress, Extensions.Dev2.sessions) + const callHash = SessionSignature.hashCallWithReplayProtection(payload, callIdx, chainId, useDeprecatedHash) const sessionSignature = await this._privateKey.signDigest(Bytes.fromHex(callHash)) return { attestation: this._attestation, diff --git a/packages/wallet/core/src/state/local/index.ts b/packages/wallet/core/src/state/local/index.ts index 282de20e0a..d34568b878 100644 --- a/packages/wallet/core/src/state/local/index.ts +++ b/packages/wallet/core/src/state/local/index.ts @@ -66,7 +66,7 @@ export interface Store { export class Provider implements ProviderInterface { constructor( private readonly store: Store = new MemoryStore(), - public readonly extensions: Extensions.Extensions = Extensions.Rc5, + public readonly extensions: Extensions.Extensions = Extensions.Rc3, ) {} getConfiguration(imageHash: Hex.Hex): Promise { diff --git a/packages/wallet/core/src/utils/session/permission-builder.ts b/packages/wallet/core/src/utils/session/permission-builder.ts index c77580a188..08b279509a 100644 --- a/packages/wallet/core/src/utils/session/permission-builder.ts +++ b/packages/wallet/core/src/utils/session/permission-builder.ts @@ -59,8 +59,8 @@ export class PermissionBuilder { throw new Error(`cannot call exactCalldata() after calling allowAll() or adding rules`) } for (let offset = 0; offset < calldata.length; offset += 32) { - let value: Bytes.Bytes = calldata.slice(offset, offset + 32) - let mask: Bytes.Bytes = Permission.MASK.BYTES32 + let value = calldata.slice(offset, offset + 32) + let mask = Permission.MASK.BYTES32 if (value.length < 32) { mask = Bytes.fromHex(`0x${'ff'.repeat(value.length)}${'00'.repeat(32 - value.length)}`) value = Bytes.padRight(value, 32) diff --git a/packages/wallet/core/src/wallet.ts b/packages/wallet/core/src/wallet.ts index 66b0eb52b5..5aaef18094 100644 --- a/packages/wallet/core/src/wallet.ts +++ b/packages/wallet/core/src/wallet.ts @@ -447,7 +447,7 @@ export class Wallet { factory, factoryData, }, - ...(await this.prepareBlankEnvelope(Number(chainId), provider)), + ...(await this.prepareBlankEnvelope(Number(chainId))), } } @@ -535,7 +535,7 @@ export class Wallet { nonce, calls, }, - ...(await this.prepareBlankEnvelope(Number(chainId), provider)), + ...(await this.prepareBlankEnvelope(Number(chainId))), } } @@ -692,8 +692,8 @@ export class Wallet { return encoded } - private async prepareBlankEnvelope(chainId: number, provider?: Provider.Provider) { - const status = await this.getStatus(provider) + private async prepareBlankEnvelope(chainId: number) { + const status = await this.getStatus() return { wallet: this.address, diff --git a/packages/wallet/core/test/preconditions.test.ts b/packages/wallet/core/test/preconditions.test.ts new file mode 100644 index 0000000000..0fd12b7f77 --- /dev/null +++ b/packages/wallet/core/test/preconditions.test.ts @@ -0,0 +1,242 @@ +import { Address, Hex, Secp256k1 } from 'ox' +import { describe, expect, it, vi } from 'vitest' +import { + Erc1155ApprovalPrecondition, + Erc1155BalancePrecondition, + Erc20ApprovalPrecondition, + Erc20BalancePrecondition, + Erc721ApprovalPrecondition, + Erc721OwnershipPrecondition, + NativeBalancePrecondition, +} from '../../src/preconditions/types.js' +import { + LocalRelayer, + type GenericProvider, +} from '../../src/relayer/standard/local.js' +import { Network } from '@0xsequence/wallet-primitives' + +const CAN_RUN_LIVE = false +const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000' +const ERC20_IMPLICIT_MINT_CONTRACT = '0x041E0CDC028050519C8e6485B2d9840caf63773F' + +function randomAddress(): Address.Address { + return Address.fromPublicKey(Secp256k1.getPublicKey({ privateKey: Secp256k1.randomPrivateKey() })) +} + +function createMockProvider(): GenericProvider { + return { + sendTransaction: vi.fn(), + getBalance: vi.fn(), + call: vi.fn(), + getTransactionReceipt: vi.fn(), + } +} + +describe('Preconditions', () => { + const getProvider = async (): Promise<{ provider: GenericProvider; chainId: number }> => { + const chainId = Network.ChainId.MAINNET + if (CAN_RUN_LIVE) { + throw new Error('Live tests not configured: set up RPC and GenericProvider adapter') + } + const provider = createMockProvider() + return { provider, chainId } + } + + const testWalletAddress = randomAddress() + + const requireContractDeployed = async (_provider: GenericProvider, _contract: Address.Address) => { + if (CAN_RUN_LIVE) { + throw new Error('Live contract check not implemented') + } + } + + it('should create and check native balance precondition', async () => { + const { provider, chainId } = await getProvider() + const relayer = new LocalRelayer(provider) + + const precondition = new NativeBalancePrecondition( + testWalletAddress, + 1000000000000000000n, // 1 ETH min + 2000000000000000000n, // 2 ETH max + ) + + const transactionPrecondition = { + type: precondition.type(), + chainId, + ownerAddress: precondition.address.toString(), + tokenAddress: ZERO_ADDRESS, + minAmount: precondition.min ?? 0n, + } + + vi.mocked(provider.getBalance).mockResolvedValue(1500000000000000000n) // 1.5 ETH + + const isValid = await relayer.checkPrecondition(transactionPrecondition) + expect(isValid).toBe(true) + }) + + it('should create and check ERC20 balance precondition', async () => { + const { provider, chainId } = await getProvider() + const relayer = new LocalRelayer(provider) + await requireContractDeployed(provider, Address.from(ERC20_IMPLICIT_MINT_CONTRACT)) + + const precondition = new Erc20BalancePrecondition( + testWalletAddress, + Address.from(ERC20_IMPLICIT_MINT_CONTRACT), + 1000000n, // 1 token min + 2000000n, // 2 tokens max + ) + + const transactionPrecondition = { + type: precondition.type(), + chainId, + ownerAddress: precondition.address.toString(), + tokenAddress: precondition.token.toString(), + minAmount: precondition.min ?? 0n, + } + + vi.mocked(provider.call).mockResolvedValue('0x1e8480' as Hex.Hex) // 1.5 tokens in hex + + const isValid = await relayer.checkPrecondition(transactionPrecondition) + expect(isValid).toBe(true) + }) + + it('should create and check ERC20 approval precondition', async () => { + const { provider, chainId } = await getProvider() + const relayer = new LocalRelayer(provider) + await requireContractDeployed(provider, Address.from(ERC20_IMPLICIT_MINT_CONTRACT)) + + const operator = randomAddress() + const precondition = new Erc20ApprovalPrecondition( + testWalletAddress, + Address.from(ERC20_IMPLICIT_MINT_CONTRACT), + operator, + 1000000n, // 1 token min approval + ) + + const transactionPrecondition = { + type: precondition.type(), + chainId, + ownerAddress: precondition.address.toString(), + tokenAddress: precondition.token.toString(), + minAmount: precondition.min, + } + + vi.mocked(provider.call).mockResolvedValue('0x1e8480' as Hex.Hex) // 1.5 tokens in hex + + const isValid = await relayer.checkPrecondition(transactionPrecondition) + expect(isValid).toBe(true) + }) + + it('should create and check ERC721 ownership precondition', async () => { + const { provider, chainId } = await getProvider() + const relayer = new LocalRelayer(provider) + await requireContractDeployed(provider, Address.from(ERC20_IMPLICIT_MINT_CONTRACT)) + + const precondition = new Erc721OwnershipPrecondition( + testWalletAddress, + Address.from(ERC20_IMPLICIT_MINT_CONTRACT), + 1n, // tokenId + true, // must own + ) + + const transactionPrecondition = { + type: precondition.type(), + chainId, + ownerAddress: precondition.address.toString(), + tokenAddress: precondition.token.toString(), + minAmount: 0n, + } + + vi.mocked(provider.call).mockResolvedValue( + ('0x000000000000000000000000' + testWalletAddress.toString().slice(2).toLowerCase()) as Hex.Hex, + ) + + const isValid = await relayer.checkPrecondition(transactionPrecondition) + expect(isValid).toBe(true) + }) + + it('should create and check ERC721 approval precondition', async () => { + const { provider, chainId } = await getProvider() + const relayer = new LocalRelayer(provider) + await requireContractDeployed(provider, Address.from(ERC20_IMPLICIT_MINT_CONTRACT)) + + const operator = randomAddress() + const precondition = new Erc721ApprovalPrecondition( + testWalletAddress, + Address.from(ERC20_IMPLICIT_MINT_CONTRACT), + 1n, // tokenId + operator, + ) + + const transactionPrecondition = { + type: precondition.type(), + chainId, + ownerAddress: precondition.address.toString(), + tokenAddress: precondition.token.toString(), + minAmount: 0n, + } + + // getApproved returns 32-byte word: 12 zero bytes + 20-byte address. Codec uses ownerAddress as operator. + const approvedHex = + '0x' + '0'.repeat(24) + testWalletAddress.toString().slice(2).toLowerCase() + vi.mocked(provider.call).mockResolvedValue(approvedHex as Hex.Hex) + + const isValid = await relayer.checkPrecondition(transactionPrecondition) + expect(isValid).toBe(true) + }) + + it('should create and check ERC1155 balance precondition', async () => { + const { provider, chainId } = await getProvider() + const relayer = new LocalRelayer(provider) + await requireContractDeployed(provider, Address.from(ERC20_IMPLICIT_MINT_CONTRACT)) + + const precondition = new Erc1155BalancePrecondition( + testWalletAddress, + Address.from(ERC20_IMPLICIT_MINT_CONTRACT), + 1n, // tokenId + 1000000n, // 1 token min + 2000000n, // 2 tokens max + ) + + const transactionPrecondition = { + type: precondition.type(), + chainId, + ownerAddress: precondition.address.toString(), + tokenAddress: precondition.token.toString(), + minAmount: precondition.min ?? 0n, + } + + vi.mocked(provider.call).mockResolvedValue('0x1e8480' as Hex.Hex) // 1.5 tokens in hex + + const isValid = await relayer.checkPrecondition(transactionPrecondition) + expect(isValid).toBe(true) + }) + + it('should create and check ERC1155 approval precondition', async () => { + const { provider, chainId } = await getProvider() + const relayer = new LocalRelayer(provider) + await requireContractDeployed(provider, Address.from(ERC20_IMPLICIT_MINT_CONTRACT)) + + const operator = randomAddress() + const precondition = new Erc1155ApprovalPrecondition( + testWalletAddress, + Address.from(ERC20_IMPLICIT_MINT_CONTRACT), + 1n, // tokenId + operator, + 1000000n, // 1 token min approval + ) + + const transactionPrecondition = { + type: precondition.type(), + chainId, + ownerAddress: precondition.address.toString(), + tokenAddress: precondition.token.toString(), + minAmount: precondition.min, + } + + vi.mocked(provider.call).mockResolvedValue('0x1' as Hex.Hex) // true + + const isValid = await relayer.checkPrecondition(transactionPrecondition) + expect(isValid).toBe(true) + }) +}) diff --git a/packages/wallet/core/test/preconditions/codec.test.ts b/packages/wallet/core/test/preconditions/codec.test.ts new file mode 100644 index 0000000000..a5ba279d39 --- /dev/null +++ b/packages/wallet/core/test/preconditions/codec.test.ts @@ -0,0 +1,531 @@ +import { Address } from 'ox' +import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest' + +import { + decodePrecondition, + decodePreconditions, + encodePrecondition, + TransactionPrecondition, +} from '../../src/preconditions/codec.js' +import { + NativeBalancePrecondition, + Erc20BalancePrecondition, + Erc20ApprovalPrecondition, + Erc721OwnershipPrecondition, + Erc721ApprovalPrecondition, + Erc1155BalancePrecondition, + Erc1155ApprovalPrecondition, +} from '../../src/preconditions/types.js' + +// Test addresses +const TEST_ADDRESS = Address.from('0x1234567890123456789012345678901234567890') +const TOKEN_ADDRESS = Address.from('0xabcdefabcdefabcdefabcdefabcdefabcdefabcd') +const OPERATOR_ADDRESS = Address.from('0x9876543210987654321098765432109876543210') +const ARBITRUM_CHAIN_ID = 42161 +const NATIVE_TOKEN_ADDRESS = Address.from('0x0000000000000000000000000000000000000000') + +describe('Preconditions Codec', () => { + // Mock console.warn to test error logging + const originalWarn = console.warn + beforeEach(() => { + console.warn = vi.fn() + }) + afterEach(() => { + console.warn = originalWarn + }) + + describe('decodePrecondition', () => { + it('should return undefined for null/undefined input', () => { + expect(decodePrecondition(null as unknown as TransactionPrecondition)).toBeUndefined() + expect(decodePrecondition(undefined as unknown as TransactionPrecondition)).toBeUndefined() + }) + + it('should decode native balance precondition with only min', () => { + const intent: TransactionPrecondition = { + type: 'native-balance', + ownerAddress: TEST_ADDRESS, + tokenAddress: NATIVE_TOKEN_ADDRESS, + chainId: ARBITRUM_CHAIN_ID, + minAmount: BigInt('1000000000000000000'), + } + + const result = decodePrecondition(intent) + expect(result).toBeInstanceOf(NativeBalancePrecondition) + + const precondition = result as NativeBalancePrecondition + expect(precondition.min).toBe(1000000000000000000n) + expect(precondition.max).toBeUndefined() + }) + + it('should decode ERC20 balance precondition', () => { + const intent: TransactionPrecondition = { + type: 'erc20-balance', + ownerAddress: TEST_ADDRESS, + tokenAddress: TOKEN_ADDRESS, + chainId: ARBITRUM_CHAIN_ID, + minAmount: BigInt('1000000'), + } + + const result = decodePrecondition(intent) + expect(result).toBeInstanceOf(Erc20BalancePrecondition) + + const precondition = result as Erc20BalancePrecondition + expect(precondition.address).toBe(TEST_ADDRESS) + expect(precondition.token).toBe(TOKEN_ADDRESS) + expect(precondition.min).toBe(1000000n) + expect(precondition.max).toBeUndefined() + }) + + it('should decode ERC20 approval precondition', () => { + const intent: TransactionPrecondition = { + type: 'erc20-approval', + ownerAddress: TEST_ADDRESS, + tokenAddress: TOKEN_ADDRESS, + chainId: ARBITRUM_CHAIN_ID, + minAmount: BigInt('1000000'), + } + + const result = decodePrecondition(intent) + expect(result).toBeInstanceOf(Erc20ApprovalPrecondition) + + const precondition = result as Erc20ApprovalPrecondition + expect(precondition.address).toBe(TEST_ADDRESS) + expect(precondition.token).toBe(TOKEN_ADDRESS) + expect(precondition.operator).toBe(TEST_ADDRESS) + expect(precondition.min).toBe(1000000n) + }) + + it('should decode ERC721 ownership precondition', () => { + const intent: TransactionPrecondition = { + type: 'erc721-ownership', + ownerAddress: TEST_ADDRESS, + tokenAddress: TOKEN_ADDRESS, + chainId: ARBITRUM_CHAIN_ID, + minAmount: BigInt('0'), + } + + const result = decodePrecondition(intent) + expect(result).toBeInstanceOf(Erc721OwnershipPrecondition) + + const precondition = result as Erc721OwnershipPrecondition + expect(precondition.address).toBe(TEST_ADDRESS) + expect(precondition.token).toBe(TOKEN_ADDRESS) + expect(precondition.tokenId).toBe(0n) + expect(precondition.owned).toBe(true) + }) + + it('should decode ERC721 ownership precondition without owned flag', () => { + const intent: TransactionPrecondition = { + type: 'erc721-ownership', + ownerAddress: TEST_ADDRESS, + tokenAddress: TOKEN_ADDRESS, + chainId: ARBITRUM_CHAIN_ID, + minAmount: BigInt('0'), + } + + const result = decodePrecondition(intent) + expect(result).toBeInstanceOf(Erc721OwnershipPrecondition) + + const precondition = result as Erc721OwnershipPrecondition + expect(precondition.owned).toBe(true) + }) + + it('should decode ERC721 approval precondition', () => { + const intent: TransactionPrecondition = { + type: 'erc721-approval', + ownerAddress: TEST_ADDRESS, + tokenAddress: TOKEN_ADDRESS, + chainId: ARBITRUM_CHAIN_ID, + minAmount: BigInt('0'), + } + + const result = decodePrecondition(intent) + expect(result).toBeInstanceOf(Erc721ApprovalPrecondition) + + const precondition = result as Erc721ApprovalPrecondition + expect(precondition.address).toBe(TEST_ADDRESS) + expect(precondition.token).toBe(TOKEN_ADDRESS) + expect(precondition.tokenId).toBe(0n) + expect(precondition.operator).toBe(TEST_ADDRESS) + }) + + it('should decode ERC1155 balance precondition', () => { + const intent: TransactionPrecondition = { + type: 'erc1155-balance', + ownerAddress: TEST_ADDRESS, + tokenAddress: TOKEN_ADDRESS, + chainId: ARBITRUM_CHAIN_ID, + minAmount: BigInt('1000000'), + } + + const result = decodePrecondition(intent) + expect(result).toBeInstanceOf(Erc1155BalancePrecondition) + + const precondition = result as Erc1155BalancePrecondition + expect(precondition.address).toBe(TEST_ADDRESS) + expect(precondition.token).toBe(TOKEN_ADDRESS) + expect(precondition.tokenId).toBe(0n) + expect(precondition.min).toBe(1000000n) + expect(precondition.max).toBeUndefined() + }) + + it('should decode ERC1155 approval precondition', () => { + const intent: TransactionPrecondition = { + type: 'erc1155-approval', + ownerAddress: TEST_ADDRESS, + tokenAddress: TOKEN_ADDRESS, + chainId: ARBITRUM_CHAIN_ID, + minAmount: BigInt('1000000'), + } + + const result = decodePrecondition(intent) + expect(result).toBeInstanceOf(Erc1155ApprovalPrecondition) + + const precondition = result as Erc1155ApprovalPrecondition + expect(precondition.address).toBe(TEST_ADDRESS) + expect(precondition.token).toBe(TOKEN_ADDRESS) + expect(precondition.tokenId).toBe(0n) + expect(precondition.operator).toBe(TEST_ADDRESS) + expect(precondition.min).toBe(1000000n) + }) + + it('should return undefined for unknown precondition type', () => { + const intent: TransactionPrecondition = { + type: 'unknown-type', + ownerAddress: TEST_ADDRESS, + tokenAddress: NATIVE_TOKEN_ADDRESS, + chainId: ARBITRUM_CHAIN_ID, + minAmount: BigInt('0'), + } + + const result = decodePrecondition(intent) + expect(result).toBeUndefined() + }) + + it('should return undefined and log warning for invalid JSON', () => { + const intent: TransactionPrecondition = { + type: 'native-balance', + ownerAddress: TEST_ADDRESS, + tokenAddress: NATIVE_TOKEN_ADDRESS, + chainId: ARBITRUM_CHAIN_ID, + minAmount: BigInt('1000000000000000000'), + } + + const result = decodePrecondition(intent) + expect(result).toBeInstanceOf(NativeBalancePrecondition) + }) + + it('should return undefined and log warning for invalid precondition', () => { + const intent: TransactionPrecondition = { + type: 'native-balance', + ownerAddress: TEST_ADDRESS, + tokenAddress: NATIVE_TOKEN_ADDRESS, + chainId: ARBITRUM_CHAIN_ID, + minAmount: BigInt('2000000000000000000'), + } + + const result = decodePrecondition(intent) + expect(result).toBeInstanceOf(NativeBalancePrecondition) + }) + + it('should handle malformed addresses gracefully', () => { + const intent: TransactionPrecondition = { + type: 'native-balance', + ownerAddress: 'invalid-address', + tokenAddress: NATIVE_TOKEN_ADDRESS.toString(), + chainId: ARBITRUM_CHAIN_ID, + minAmount: BigInt('1000000000000000000'), + } + + const result = decodePrecondition(intent) + expect(result).toBeUndefined() + expect(console.warn).toHaveBeenCalledWith(expect.stringContaining('Failed to decode precondition')) + }) + + it('should handle malformed BigInt values gracefully', () => { + const intent = { + type: 'native-balance', + ownerAddress: TEST_ADDRESS.toString(), + tokenAddress: NATIVE_TOKEN_ADDRESS.toString(), + chainId: ARBITRUM_CHAIN_ID, + minAmount: 'not-a-number', + } as unknown as TransactionPrecondition + + const result = decodePrecondition(intent) + expect(result).toBeUndefined() + expect(console.warn).toHaveBeenCalledWith(expect.stringContaining('Failed to decode precondition')) + }) + + it('should return undefined and log warning for precondition that fails validation', () => { + // Note: NativeBalancePrecondition validation only checks min > max if both are defined + // Since TransactionPrecondition doesn't have max, this test may not trigger validation error + // But we can test with a valid precondition that should pass + const intent: TransactionPrecondition = { + type: 'native-balance', + ownerAddress: TEST_ADDRESS, + tokenAddress: NATIVE_TOKEN_ADDRESS, + chainId: ARBITRUM_CHAIN_ID, + minAmount: BigInt('1000000000000000000'), + } + + const result = decodePrecondition(intent) + expect(result).toBeInstanceOf(NativeBalancePrecondition) + }) + }) + + describe('decodePreconditions', () => { + it('should decode multiple preconditions', () => { + const intents: TransactionPrecondition[] = [ + { + type: 'native-balance', + ownerAddress: TEST_ADDRESS, + tokenAddress: NATIVE_TOKEN_ADDRESS, + chainId: ARBITRUM_CHAIN_ID, + minAmount: BigInt('1000000000000000000'), + }, + { + type: 'erc20-balance', + ownerAddress: TEST_ADDRESS, + tokenAddress: TOKEN_ADDRESS, + chainId: ARBITRUM_CHAIN_ID, + minAmount: BigInt('1000000'), + }, + ] + + const results = decodePreconditions(intents) + expect(results).toHaveLength(2) + expect(results[0]).toBeInstanceOf(NativeBalancePrecondition) + expect(results[1]).toBeInstanceOf(Erc20BalancePrecondition) + }) + + it('should filter out invalid preconditions', () => { + const intents: TransactionPrecondition[] = [ + { + type: 'native-balance', + ownerAddress: TEST_ADDRESS, + tokenAddress: NATIVE_TOKEN_ADDRESS, + chainId: ARBITRUM_CHAIN_ID, + minAmount: BigInt('1000000000000000000'), + }, + { + type: 'invalid-type', + ownerAddress: TEST_ADDRESS, + tokenAddress: NATIVE_TOKEN_ADDRESS, + chainId: ARBITRUM_CHAIN_ID, + minAmount: BigInt('0'), + }, + { + type: 'native-balance', + ownerAddress: 'invalid-address', + tokenAddress: NATIVE_TOKEN_ADDRESS.toString(), + chainId: ARBITRUM_CHAIN_ID, + minAmount: BigInt('1000000000000000000'), + }, + ] + + const results = decodePreconditions(intents) + expect(results).toHaveLength(1) + expect(results[0]).toBeInstanceOf(NativeBalancePrecondition) + }) + + it('should return empty array for empty input', () => { + const results = decodePreconditions([]) + expect(results).toEqual([]) + }) + }) + + describe('encodePrecondition', () => { + it('should encode native balance precondition with min and max', () => { + const precondition = new NativeBalancePrecondition(TEST_ADDRESS, 1000000000000000000n, 2000000000000000000n) + + const encoded = encodePrecondition(precondition) + const data = JSON.parse(encoded) + + expect(data.address).toBe(TEST_ADDRESS) + expect(data.min).toBe('1000000000000000000') + expect(data.max).toBe('2000000000000000000') + }) + + it('should encode native balance precondition with only min', () => { + const precondition = new NativeBalancePrecondition(TEST_ADDRESS, 1000000000000000000n) + + const encoded = encodePrecondition(precondition) + const data = JSON.parse(encoded) + + expect(data.address).toBe(TEST_ADDRESS) + expect(data.min).toBe('1000000000000000000') + expect(data.max).toBeUndefined() + }) + + it('should encode native balance precondition with only max', () => { + const precondition = new NativeBalancePrecondition(TEST_ADDRESS, undefined, 2000000000000000000n) + + const encoded = encodePrecondition(precondition) + const data = JSON.parse(encoded) + + expect(data.address).toBe(TEST_ADDRESS) + expect(data.min).toBeUndefined() + expect(data.max).toBe('2000000000000000000') + }) + + it('should encode ERC20 balance precondition', () => { + const precondition = new Erc20BalancePrecondition(TEST_ADDRESS, TOKEN_ADDRESS, 1000000n, 2000000n) + + const encoded = encodePrecondition(precondition) + const data = JSON.parse(encoded) + + expect(data.address).toBe(TEST_ADDRESS) + expect(data.token).toBe(TOKEN_ADDRESS) + expect(data.min).toBe('1000000') + expect(data.max).toBe('2000000') + }) + + it('should encode ERC20 approval precondition', () => { + const precondition = new Erc20ApprovalPrecondition(TEST_ADDRESS, TOKEN_ADDRESS, OPERATOR_ADDRESS, 1000000n) + + const encoded = encodePrecondition(precondition) + const data = JSON.parse(encoded) + + expect(data.address).toBe(TEST_ADDRESS) + expect(data.token).toBe(TOKEN_ADDRESS) + expect(data.operator).toBe(OPERATOR_ADDRESS) + expect(data.min).toBe('1000000') + }) + + it('should encode ERC721 ownership precondition', () => { + const precondition = new Erc721OwnershipPrecondition(TEST_ADDRESS, TOKEN_ADDRESS, 123n, true) + + const encoded = encodePrecondition(precondition) + const data = JSON.parse(encoded) + + expect(data.address).toBe(TEST_ADDRESS) + expect(data.token).toBe(TOKEN_ADDRESS) + expect(data.tokenId).toBe('123') + expect(data.owned).toBe(true) + }) + + it('should encode ERC721 ownership precondition without owned flag', () => { + const precondition = new Erc721OwnershipPrecondition(TEST_ADDRESS, TOKEN_ADDRESS, 123n) + + const encoded = encodePrecondition(precondition) + const data = JSON.parse(encoded) + + expect(data.address).toBe(TEST_ADDRESS) + expect(data.token).toBe(TOKEN_ADDRESS) + expect(data.tokenId).toBe('123') + expect(data.owned).toBeUndefined() + }) + + it('should encode ERC721 approval precondition', () => { + const precondition = new Erc721ApprovalPrecondition(TEST_ADDRESS, TOKEN_ADDRESS, 123n, OPERATOR_ADDRESS) + + const encoded = encodePrecondition(precondition) + const data = JSON.parse(encoded) + + expect(data.address).toBe(TEST_ADDRESS) + expect(data.token).toBe(TOKEN_ADDRESS) + expect(data.tokenId).toBe('123') + expect(data.operator).toBe(OPERATOR_ADDRESS) + }) + + it('should encode ERC1155 balance precondition', () => { + const precondition = new Erc1155BalancePrecondition(TEST_ADDRESS, TOKEN_ADDRESS, 123n, 1000000n, 2000000n) + + const encoded = encodePrecondition(precondition) + const data = JSON.parse(encoded) + + expect(data.address).toBe(TEST_ADDRESS) + expect(data.token).toBe(TOKEN_ADDRESS) + expect(data.tokenId).toBe('123') + expect(data.min).toBe('1000000') + expect(data.max).toBe('2000000') + }) + + it('should encode ERC1155 approval precondition', () => { + const precondition = new Erc1155ApprovalPrecondition( + TEST_ADDRESS, + TOKEN_ADDRESS, + 123n, + OPERATOR_ADDRESS, + 1000000n, + ) + + const encoded = encodePrecondition(precondition) + const data = JSON.parse(encoded) + + expect(data.address).toBe(TEST_ADDRESS) + expect(data.token).toBe(TOKEN_ADDRESS) + expect(data.tokenId).toBe('123') + expect(data.operator).toBe(OPERATOR_ADDRESS) + expect(data.min).toBe('1000000') + }) + }) + + describe('roundtrip encoding/decoding', () => { + it('should roundtrip native balance precondition', () => { + const original = new NativeBalancePrecondition(TEST_ADDRESS, 1000000000000000000n, 2000000000000000000n) + + const encoded = encodePrecondition(original) + const data = JSON.parse(encoded) + const intent: TransactionPrecondition = { + type: original.type(), + ownerAddress: data.address, + tokenAddress: NATIVE_TOKEN_ADDRESS, + chainId: ARBITRUM_CHAIN_ID, + minAmount: BigInt(data.min), + } + const decoded = decodePrecondition(intent) as NativeBalancePrecondition + + expect(decoded.address).toBe(original.address) + expect(decoded.min).toBe(original.min) + // Note: max is not preserved in TransactionPrecondition format + expect(decoded.max).toBeUndefined() + expect(decoded.type()).toBe(original.type()) + }) + + it('should roundtrip ERC20 balance precondition', () => { + const original = new Erc20BalancePrecondition(TEST_ADDRESS, TOKEN_ADDRESS, 1000000n, 2000000n) + + const encoded = encodePrecondition(original) + const data = JSON.parse(encoded) + const intent: TransactionPrecondition = { + type: original.type(), + ownerAddress: data.address, + tokenAddress: data.token, + chainId: ARBITRUM_CHAIN_ID, + minAmount: BigInt(data.min), + } + const decoded = decodePrecondition(intent) as Erc20BalancePrecondition + + expect(decoded.address).toBe(original.address) + expect(decoded.token).toBe(original.token) + expect(decoded.min).toBe(original.min) + // Note: max is not preserved in TransactionPrecondition format + expect(decoded.max).toBeUndefined() + expect(decoded.type()).toBe(original.type()) + }) + + it('should roundtrip ERC721 ownership precondition', () => { + const original = new Erc721OwnershipPrecondition(TEST_ADDRESS, TOKEN_ADDRESS, 123n, true) + + const encoded = encodePrecondition(original) + const data = JSON.parse(encoded) + const intent: TransactionPrecondition = { + type: original.type(), + ownerAddress: data.address, + tokenAddress: data.token, + chainId: ARBITRUM_CHAIN_ID, + minAmount: BigInt('0'), + } + const decoded = decodePrecondition(intent) as Erc721OwnershipPrecondition + + expect(decoded.address).toBe(original.address) + expect(decoded.token).toBe(original.token) + // Note: tokenId is not preserved in TransactionPrecondition format (defaults to 0) + expect(decoded.tokenId).toBe(0n) + // Note: owned is hardcoded to true in decoder + expect(decoded.owned).toBe(true) + expect(decoded.type()).toBe(original.type()) + }) + }) +}) diff --git a/packages/wallet/core/test/preconditions/selectors.test.ts b/packages/wallet/core/test/preconditions/selectors.test.ts new file mode 100644 index 0000000000..0cacc0e285 --- /dev/null +++ b/packages/wallet/core/test/preconditions/selectors.test.ts @@ -0,0 +1,237 @@ +import { Address } from 'ox' +import { describe, expect, it } from 'vitest' + +import { + extractChainID, + extractSupportedPreconditions, + extractNativeBalancePreconditions, + extractERC20BalancePreconditions, +} from '../../src/preconditions/selectors.js' +import { TransactionPrecondition } from '../../src/preconditions/codec.js' +import { + NativeBalancePrecondition, + Erc20BalancePrecondition, + Erc721OwnershipPrecondition, +} from '../../src/preconditions/types.js' +import { Network } from '@0xsequence/wallet-primitives' + +// Test addresses (strings for TransactionPrecondition) +const TEST_ADDRESS = '0x1234567890123456789012345678901234567890' +const TOKEN_ADDRESS = '0xabcdefabcdefabcdefabcdefabcdefabcdefabcd' +const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000' + +function nativePrecondition(overrides: Partial = {}): TransactionPrecondition { + return { + type: 'native-balance', + chainId: Network.ChainId.MAINNET, + ownerAddress: TEST_ADDRESS, + tokenAddress: ZERO_ADDRESS, + minAmount: 1000000000000000000n, + ...overrides, + } +} + +function erc20Precondition(overrides: Partial = {}): TransactionPrecondition { + return { + type: 'erc20-balance', + chainId: Network.ChainId.MAINNET, + ownerAddress: TEST_ADDRESS, + tokenAddress: TOKEN_ADDRESS, + minAmount: 1000000n, + ...overrides, + } +} + +function erc721OwnershipPrecondition(overrides: Partial = {}): TransactionPrecondition { + return { + type: 'erc721-ownership', + chainId: Network.ChainId.MAINNET, + ownerAddress: TEST_ADDRESS, + tokenAddress: TOKEN_ADDRESS, + minAmount: 0n, + ...overrides, + } +} + +describe('Preconditions Selectors', () => { + describe('extractChainID', () => { + it('should extract chainID from valid precondition data', () => { + const precondition = nativePrecondition({ chainId: Network.ChainId.MAINNET }) + const chainId = extractChainID(precondition) + expect(chainId).toBe(Network.ChainId.MAINNET) + }) + + it('should extract large chainID values', () => { + const precondition = nativePrecondition({ chainId: Network.ChainId.ARBITRUM }) + const chainId = extractChainID(precondition) + expect(chainId).toBe(Network.ChainId.ARBITRUM) + }) + + it('should return undefined when chainID is not present', () => { + const precondition = { type: 'native-balance', ownerAddress: TEST_ADDRESS, tokenAddress: ZERO_ADDRESS, minAmount: 1n } as TransactionPrecondition + const chainId = extractChainID(precondition) + expect(chainId).toBeUndefined() + }) + + it('should return undefined for null/undefined precondition', () => { + expect(extractChainID(null as unknown as TransactionPrecondition)).toBeUndefined() + expect(extractChainID(undefined as unknown as TransactionPrecondition)).toBeUndefined() + }) + + it('should handle chainID with value 0', () => { + const precondition = nativePrecondition({ chainId: 0 }) + const chainId = extractChainID(precondition) + expect(chainId).toBe(0) + }) + }) + + describe('extractSupportedPreconditions', () => { + it('should extract valid preconditions', () => { + const intents: TransactionPrecondition[] = [ + nativePrecondition(), + erc20Precondition(), + ] + + const results = extractSupportedPreconditions(intents) + expect(results).toHaveLength(2) + expect(results[0]).toBeInstanceOf(NativeBalancePrecondition) + expect(results[1]).toBeInstanceOf(Erc20BalancePrecondition) + }) + + it('should filter out invalid preconditions', () => { + const intents: TransactionPrecondition[] = [ + nativePrecondition(), + { type: 'unknown-type', chainId: 1, ownerAddress: TEST_ADDRESS, tokenAddress: ZERO_ADDRESS, minAmount: 0n } as TransactionPrecondition, + nativePrecondition({ ownerAddress: '' }), + ] + + const results = extractSupportedPreconditions(intents) + expect(results).toHaveLength(1) + expect(results[0]).toBeInstanceOf(NativeBalancePrecondition) + }) + + it('should return empty array for null/undefined input', () => { + expect(extractSupportedPreconditions(null as unknown as TransactionPrecondition[])).toEqual([]) + expect(extractSupportedPreconditions(undefined as unknown as TransactionPrecondition[])).toEqual([]) + }) + + it('should return empty array for empty input', () => { + const results = extractSupportedPreconditions([]) + expect(results).toEqual([]) + }) + + it('should handle mixed valid and invalid preconditions', () => { + const intents: TransactionPrecondition[] = [ + nativePrecondition(), + erc721OwnershipPrecondition(), + { type: 'invalid-type', chainId: 1, ownerAddress: TEST_ADDRESS, tokenAddress: ZERO_ADDRESS, minAmount: 0n } as TransactionPrecondition, + ] + + const results = extractSupportedPreconditions(intents) + expect(results).toHaveLength(2) + expect(results[0]).toBeInstanceOf(NativeBalancePrecondition) + expect(results[1]).toBeInstanceOf(Erc721OwnershipPrecondition) + }) + }) + + describe('extractNativeBalancePreconditions', () => { + it('should extract only native balance preconditions', () => { + const intents: TransactionPrecondition[] = [ + nativePrecondition({ minAmount: 1000000000000000000n }), + erc20Precondition(), + nativePrecondition({ minAmount: 2000000000000000000n }), + ] + + const results = extractNativeBalancePreconditions(intents) + expect(results).toHaveLength(2) + expect(results[0]).toBeInstanceOf(NativeBalancePrecondition) + expect(results[1]).toBeInstanceOf(NativeBalancePrecondition) + expect(results[0].min).toBe(1000000000000000000n) + expect(results[1].min).toBe(2000000000000000000n) + }) + + it('should return empty array when no native balance preconditions exist', () => { + const intents: TransactionPrecondition[] = [ + erc20Precondition(), + erc721OwnershipPrecondition(), + ] + + const results = extractNativeBalancePreconditions(intents) + expect(results).toEqual([]) + }) + + it('should return empty array for null/undefined input', () => { + expect(extractNativeBalancePreconditions(null as unknown as TransactionPrecondition[])).toEqual([]) + expect(extractNativeBalancePreconditions(undefined as unknown as TransactionPrecondition[])).toEqual([]) + }) + + it('should return empty array for empty input', () => { + const results = extractNativeBalancePreconditions([]) + expect(results).toEqual([]) + }) + + it('should filter out invalid native balance preconditions', () => { + const intents: TransactionPrecondition[] = [ + nativePrecondition({ minAmount: 1000000000000000000n }), + nativePrecondition({ ownerAddress: '' }), + ] + + const results = extractNativeBalancePreconditions(intents) + expect(results).toHaveLength(1) + expect(results[0]).toBeInstanceOf(NativeBalancePrecondition) + expect(results[0].min).toBe(1000000000000000000n) + }) + }) + + describe('extractERC20BalancePreconditions', () => { + it('should extract only ERC20 balance preconditions', () => { + const intents: TransactionPrecondition[] = [ + nativePrecondition(), + erc20Precondition({ minAmount: 1000000n }), + erc20Precondition({ minAmount: 2000000n }), + ] + + const results = extractERC20BalancePreconditions(intents) + expect(results).toHaveLength(2) + expect(results[0]).toBeInstanceOf(Erc20BalancePrecondition) + expect(results[1]).toBeInstanceOf(Erc20BalancePrecondition) + expect(results[0].min).toBe(1000000n) + expect(results[1].min).toBe(2000000n) + expect(results[0].token).toEqual(Address.from(TOKEN_ADDRESS)) + expect(results[1].token).toEqual(Address.from(TOKEN_ADDRESS)) + }) + + it('should return empty array when no ERC20 balance preconditions exist', () => { + const intents: TransactionPrecondition[] = [ + nativePrecondition(), + erc721OwnershipPrecondition(), + ] + + const results = extractERC20BalancePreconditions(intents) + expect(results).toEqual([]) + }) + + it('should return empty array for null/undefined input', () => { + expect(extractERC20BalancePreconditions(null as unknown as TransactionPrecondition[])).toEqual([]) + expect(extractERC20BalancePreconditions(undefined as unknown as TransactionPrecondition[])).toEqual([]) + }) + + it('should return empty array for empty input', () => { + const results = extractERC20BalancePreconditions([]) + expect(results).toEqual([]) + }) + + it('should filter out invalid ERC20 balance preconditions', () => { + const intents: TransactionPrecondition[] = [ + erc20Precondition({ minAmount: 1000000n }), + erc20Precondition({ tokenAddress: '' }), + ] + + const results = extractERC20BalancePreconditions(intents) + expect(results).toHaveLength(1) + expect(results[0]).toBeInstanceOf(Erc20BalancePrecondition) + expect(results[0].min).toBe(1000000n) + expect(results[0].token).toEqual(Address.from(TOKEN_ADDRESS)) + }) + }) +}) diff --git a/packages/wallet/core/test/preconditions/types.test.ts b/packages/wallet/core/test/preconditions/types.test.ts new file mode 100644 index 0000000000..a479676b58 --- /dev/null +++ b/packages/wallet/core/test/preconditions/types.test.ts @@ -0,0 +1,443 @@ +import { Address } from 'ox' +import { describe, expect, it } from 'vitest' + +import { + NativeBalancePrecondition, + Erc20BalancePrecondition, + Erc20ApprovalPrecondition, + Erc721OwnershipPrecondition, + Erc721ApprovalPrecondition, + Erc1155BalancePrecondition, + Erc1155ApprovalPrecondition, +} from '../../src/preconditions/types.js' + +// Test addresses +const TEST_ADDRESS = Address.from('0x1234567890123456789012345678901234567890') +const TOKEN_ADDRESS = Address.from('0xabcdefabcdefabcdefabcdefabcdefabcdefabcd') +const OPERATOR_ADDRESS = Address.from('0x9876543210987654321098765432109876543210') + +describe('Preconditions Types', () => { + describe('NativeBalancePrecondition', () => { + it('should create a valid native balance precondition', () => { + const precondition = new NativeBalancePrecondition(TEST_ADDRESS, 1000000000000000000n, 2000000000000000000n) + + expect(precondition.address).toBe(TEST_ADDRESS) + expect(precondition.min).toBe(1000000000000000000n) + expect(precondition.max).toBe(2000000000000000000n) + expect(precondition.type()).toBe('native-balance') + expect(precondition.isValid()).toBeUndefined() + }) + + it('should create a precondition with only min value', () => { + const precondition = new NativeBalancePrecondition(TEST_ADDRESS, 1000000000000000000n) + + expect(precondition.min).toBe(1000000000000000000n) + expect(precondition.max).toBeUndefined() + expect(precondition.isValid()).toBeUndefined() + }) + + it('should create a precondition with only max value', () => { + const precondition = new NativeBalancePrecondition(TEST_ADDRESS, undefined, 2000000000000000000n) + + expect(precondition.min).toBeUndefined() + expect(precondition.max).toBe(2000000000000000000n) + expect(precondition.isValid()).toBeUndefined() + }) + + it('should create a precondition with no min/max values', () => { + const precondition = new NativeBalancePrecondition(TEST_ADDRESS) + + expect(precondition.min).toBeUndefined() + expect(precondition.max).toBeUndefined() + expect(precondition.isValid()).toBeUndefined() + }) + + it('should validate address is required', () => { + const precondition = new NativeBalancePrecondition('' as Address.Address) + + const error = precondition.isValid() + expect(error).toBeInstanceOf(Error) + expect(error?.message).toBe('address is required') + }) + + it('should validate min cannot be greater than max', () => { + const precondition = new NativeBalancePrecondition(TEST_ADDRESS, 2000000000000000000n, 1000000000000000000n) + + const error = precondition.isValid() + expect(error).toBeInstanceOf(Error) + expect(error?.message).toBe('min balance cannot be greater than max balance') + }) + + it('should allow min equal to max', () => { + const precondition = new NativeBalancePrecondition(TEST_ADDRESS, 1000000000000000000n, 1000000000000000000n) + + expect(precondition.isValid()).toBeUndefined() + }) + }) + + describe('Erc20BalancePrecondition', () => { + it('should create a valid ERC20 balance precondition', () => { + const precondition = new Erc20BalancePrecondition(TEST_ADDRESS, TOKEN_ADDRESS, 1000000n, 2000000n) + + expect(precondition.address).toBe(TEST_ADDRESS) + expect(precondition.token).toBe(TOKEN_ADDRESS) + expect(precondition.min).toBe(1000000n) + expect(precondition.max).toBe(2000000n) + expect(precondition.type()).toBe('erc20-balance') + expect(precondition.isValid()).toBeUndefined() + }) + + it('should validate address is required', () => { + const precondition = new Erc20BalancePrecondition('' as Address.Address, TOKEN_ADDRESS) + + const error = precondition.isValid() + expect(error).toBeInstanceOf(Error) + expect(error?.message).toBe('address is required') + }) + + it('should validate token address is required', () => { + const precondition = new Erc20BalancePrecondition(TEST_ADDRESS, '' as Address.Address) + + const error = precondition.isValid() + expect(error).toBeInstanceOf(Error) + expect(error?.message).toBe('token address is required') + }) + + it('should validate min cannot be greater than max', () => { + const precondition = new Erc20BalancePrecondition(TEST_ADDRESS, TOKEN_ADDRESS, 2000000n, 1000000n) + + const error = precondition.isValid() + expect(error).toBeInstanceOf(Error) + expect(error?.message).toBe('min balance cannot be greater than max balance') + }) + + it('should create precondition with only min value', () => { + const precondition = new Erc20BalancePrecondition(TEST_ADDRESS, TOKEN_ADDRESS, 1000000n) + + expect(precondition.min).toBe(1000000n) + expect(precondition.max).toBeUndefined() + expect(precondition.isValid()).toBeUndefined() + }) + + it('should create precondition with only max value', () => { + const precondition = new Erc20BalancePrecondition(TEST_ADDRESS, TOKEN_ADDRESS, undefined, 2000000n) + + expect(precondition.min).toBeUndefined() + expect(precondition.max).toBe(2000000n) + expect(precondition.isValid()).toBeUndefined() + }) + }) + + describe('Erc20ApprovalPrecondition', () => { + it('should create a valid ERC20 approval precondition', () => { + const precondition = new Erc20ApprovalPrecondition(TEST_ADDRESS, TOKEN_ADDRESS, OPERATOR_ADDRESS, 1000000n) + + expect(precondition.address).toBe(TEST_ADDRESS) + expect(precondition.token).toBe(TOKEN_ADDRESS) + expect(precondition.operator).toBe(OPERATOR_ADDRESS) + expect(precondition.min).toBe(1000000n) + expect(precondition.type()).toBe('erc20-approval') + expect(precondition.isValid()).toBeUndefined() + }) + + it('should validate address is required', () => { + const precondition = new Erc20ApprovalPrecondition( + '' as Address.Address, + TOKEN_ADDRESS, + OPERATOR_ADDRESS, + 1000000n, + ) + + const error = precondition.isValid() + expect(error).toBeInstanceOf(Error) + expect(error?.message).toBe('address is required') + }) + + it('should validate token address is required', () => { + const precondition = new Erc20ApprovalPrecondition( + TEST_ADDRESS, + '' as Address.Address, + OPERATOR_ADDRESS, + 1000000n, + ) + + const error = precondition.isValid() + expect(error).toBeInstanceOf(Error) + expect(error?.message).toBe('token address is required') + }) + + it('should validate operator address is required', () => { + const precondition = new Erc20ApprovalPrecondition(TEST_ADDRESS, TOKEN_ADDRESS, '' as Address.Address, 1000000n) + + const error = precondition.isValid() + expect(error).toBeInstanceOf(Error) + expect(error?.message).toBe('operator address is required') + }) + + it('should validate min approval amount is required', () => { + const precondition = new Erc20ApprovalPrecondition( + TEST_ADDRESS, + TOKEN_ADDRESS, + OPERATOR_ADDRESS, + undefined as unknown as bigint, + ) + + const error = precondition.isValid() + expect(error).toBeInstanceOf(Error) + expect(error?.message).toBe('min approval amount is required') + }) + }) + + describe('Erc721OwnershipPrecondition', () => { + it('should create a valid ERC721 ownership precondition', () => { + const precondition = new Erc721OwnershipPrecondition(TEST_ADDRESS, TOKEN_ADDRESS, 123n, true) + + expect(precondition.address).toBe(TEST_ADDRESS) + expect(precondition.token).toBe(TOKEN_ADDRESS) + expect(precondition.tokenId).toBe(123n) + expect(precondition.owned).toBe(true) + expect(precondition.type()).toBe('erc721-ownership') + expect(precondition.isValid()).toBeUndefined() + }) + + it('should create precondition with default owned value', () => { + const precondition = new Erc721OwnershipPrecondition(TEST_ADDRESS, TOKEN_ADDRESS, 123n) + + expect(precondition.owned).toBeUndefined() + expect(precondition.isValid()).toBeUndefined() + }) + + it('should validate address is required', () => { + const precondition = new Erc721OwnershipPrecondition('' as Address.Address, TOKEN_ADDRESS, 123n) + + const error = precondition.isValid() + expect(error).toBeInstanceOf(Error) + expect(error?.message).toBe('address is required') + }) + + it('should validate token address is required', () => { + const precondition = new Erc721OwnershipPrecondition(TEST_ADDRESS, '' as Address.Address, 123n) + + const error = precondition.isValid() + expect(error).toBeInstanceOf(Error) + expect(error?.message).toBe('token address is required') + }) + + it('should validate tokenId is required', () => { + const precondition = new Erc721OwnershipPrecondition(TEST_ADDRESS, TOKEN_ADDRESS, undefined as unknown as bigint) + + const error = precondition.isValid() + expect(error).toBeInstanceOf(Error) + expect(error?.message).toBe('tokenId is required') + }) + + it('should handle tokenId of 0', () => { + const precondition = new Erc721OwnershipPrecondition(TEST_ADDRESS, TOKEN_ADDRESS, 0n) + + expect(precondition.tokenId).toBe(0n) + expect(precondition.isValid()).toBeUndefined() + }) + }) + + describe('Erc721ApprovalPrecondition', () => { + it('should create a valid ERC721 approval precondition', () => { + const precondition = new Erc721ApprovalPrecondition(TEST_ADDRESS, TOKEN_ADDRESS, 123n, OPERATOR_ADDRESS) + + expect(precondition.address).toBe(TEST_ADDRESS) + expect(precondition.token).toBe(TOKEN_ADDRESS) + expect(precondition.tokenId).toBe(123n) + expect(precondition.operator).toBe(OPERATOR_ADDRESS) + expect(precondition.type()).toBe('erc721-approval') + expect(precondition.isValid()).toBeUndefined() + }) + + it('should validate address is required', () => { + const precondition = new Erc721ApprovalPrecondition('' as Address.Address, TOKEN_ADDRESS, 123n, OPERATOR_ADDRESS) + + const error = precondition.isValid() + expect(error).toBeInstanceOf(Error) + expect(error?.message).toBe('address is required') + }) + + it('should validate token address is required', () => { + const precondition = new Erc721ApprovalPrecondition(TEST_ADDRESS, '' as Address.Address, 123n, OPERATOR_ADDRESS) + + const error = precondition.isValid() + expect(error).toBeInstanceOf(Error) + expect(error?.message).toBe('token address is required') + }) + + it('should validate tokenId is required', () => { + const precondition = new Erc721ApprovalPrecondition( + TEST_ADDRESS, + TOKEN_ADDRESS, + undefined as unknown as bigint, + OPERATOR_ADDRESS, + ) + + const error = precondition.isValid() + expect(error).toBeInstanceOf(Error) + expect(error?.message).toBe('tokenId is required') + }) + + it('should validate operator address is required', () => { + const precondition = new Erc721ApprovalPrecondition(TEST_ADDRESS, TOKEN_ADDRESS, 123n, '' as Address.Address) + + const error = precondition.isValid() + expect(error).toBeInstanceOf(Error) + expect(error?.message).toBe('operator address is required') + }) + }) + + describe('Erc1155BalancePrecondition', () => { + it('should create a valid ERC1155 balance precondition', () => { + const precondition = new Erc1155BalancePrecondition(TEST_ADDRESS, TOKEN_ADDRESS, 123n, 1000000n, 2000000n) + + expect(precondition.address).toBe(TEST_ADDRESS) + expect(precondition.token).toBe(TOKEN_ADDRESS) + expect(precondition.tokenId).toBe(123n) + expect(precondition.min).toBe(1000000n) + expect(precondition.max).toBe(2000000n) + expect(precondition.type()).toBe('erc1155-balance') + expect(precondition.isValid()).toBeUndefined() + }) + + it('should validate address is required', () => { + const precondition = new Erc1155BalancePrecondition('' as Address.Address, TOKEN_ADDRESS, 123n) + + const error = precondition.isValid() + expect(error).toBeInstanceOf(Error) + expect(error?.message).toBe('address is required') + }) + + it('should validate token address is required', () => { + const precondition = new Erc1155BalancePrecondition(TEST_ADDRESS, '' as Address.Address, 123n) + + const error = precondition.isValid() + expect(error).toBeInstanceOf(Error) + expect(error?.message).toBe('token address is required') + }) + + it('should validate tokenId is required', () => { + const precondition = new Erc1155BalancePrecondition(TEST_ADDRESS, TOKEN_ADDRESS, undefined as unknown as bigint) + + const error = precondition.isValid() + expect(error).toBeInstanceOf(Error) + expect(error?.message).toBe('tokenId is required') + }) + + it('should validate min cannot be greater than max', () => { + const precondition = new Erc1155BalancePrecondition(TEST_ADDRESS, TOKEN_ADDRESS, 123n, 2000000n, 1000000n) + + const error = precondition.isValid() + expect(error).toBeInstanceOf(Error) + expect(error?.message).toBe('min balance cannot be greater than max balance') + }) + + it('should create precondition with only min value', () => { + const precondition = new Erc1155BalancePrecondition(TEST_ADDRESS, TOKEN_ADDRESS, 123n, 1000000n) + + expect(precondition.min).toBe(1000000n) + expect(precondition.max).toBeUndefined() + expect(precondition.isValid()).toBeUndefined() + }) + + it('should create precondition with only max value', () => { + const precondition = new Erc1155BalancePrecondition(TEST_ADDRESS, TOKEN_ADDRESS, 123n, undefined, 2000000n) + + expect(precondition.min).toBeUndefined() + expect(precondition.max).toBe(2000000n) + expect(precondition.isValid()).toBeUndefined() + }) + }) + + describe('Erc1155ApprovalPrecondition', () => { + it('should create a valid ERC1155 approval precondition', () => { + const precondition = new Erc1155ApprovalPrecondition( + TEST_ADDRESS, + TOKEN_ADDRESS, + 123n, + OPERATOR_ADDRESS, + 1000000n, + ) + + expect(precondition.address).toBe(TEST_ADDRESS) + expect(precondition.token).toBe(TOKEN_ADDRESS) + expect(precondition.tokenId).toBe(123n) + expect(precondition.operator).toBe(OPERATOR_ADDRESS) + expect(precondition.min).toBe(1000000n) + expect(precondition.type()).toBe('erc1155-approval') + expect(precondition.isValid()).toBeUndefined() + }) + + it('should validate address is required', () => { + const precondition = new Erc1155ApprovalPrecondition( + '' as Address.Address, + TOKEN_ADDRESS, + 123n, + OPERATOR_ADDRESS, + 1000000n, + ) + + const error = precondition.isValid() + expect(error).toBeInstanceOf(Error) + expect(error?.message).toBe('address is required') + }) + + it('should validate token address is required', () => { + const precondition = new Erc1155ApprovalPrecondition( + TEST_ADDRESS, + '' as Address.Address, + 123n, + OPERATOR_ADDRESS, + 1000000n, + ) + + const error = precondition.isValid() + expect(error).toBeInstanceOf(Error) + expect(error?.message).toBe('token address is required') + }) + + it('should validate tokenId is required', () => { + const precondition = new Erc1155ApprovalPrecondition( + TEST_ADDRESS, + TOKEN_ADDRESS, + undefined as unknown as bigint, + OPERATOR_ADDRESS, + 1000000n, + ) + + const error = precondition.isValid() + expect(error).toBeInstanceOf(Error) + expect(error?.message).toBe('tokenId is required') + }) + + it('should validate operator address is required', () => { + const precondition = new Erc1155ApprovalPrecondition( + TEST_ADDRESS, + TOKEN_ADDRESS, + 123n, + '' as Address.Address, + 1000000n, + ) + + const error = precondition.isValid() + expect(error).toBeInstanceOf(Error) + expect(error?.message).toBe('operator address is required') + }) + + it('should validate min approval amount is required', () => { + const precondition = new Erc1155ApprovalPrecondition( + TEST_ADDRESS, + TOKEN_ADDRESS, + 123n, + OPERATOR_ADDRESS, + undefined as unknown as bigint, + ) + + const error = precondition.isValid() + expect(error).toBeInstanceOf(Error) + expect(error?.message).toBe('min approval amount is required') + }) + }) +}) diff --git a/packages/wallet/core/test/relayer/bundler.test.ts b/packages/wallet/core/test/relayer/bundler.test.ts index bc565e1cc3..cf5b3df469 100644 --- a/packages/wallet/core/test/relayer/bundler.test.ts +++ b/packages/wallet/core/test/relayer/bundler.test.ts @@ -2,8 +2,8 @@ import { describe, expect, it, vi, beforeEach } from 'vitest' import { Address, Hex } from 'ox' import { UserOperation } from 'ox/erc4337' import { Network, Payload } from '@0xsequence/wallet-primitives' -import { Bundler, isBundler } from '../../src/bundler/index.js' -import { Relayer } from '@0xsequence/relayer' +import { Bundler, isBundler } from '../../src/relayer/bundler.js' +import { OperationStatus } from '../../src/relayer/relayer.js' // Test addresses and data const TEST_WALLET_ADDRESS = Address.from('0x1234567890123456789012345678901234567890') @@ -220,7 +220,7 @@ describe('Bundler', () => { }) it('should handle various operation statuses', async () => { - const statuses: Relayer.OperationStatus[] = [ + const statuses: OperationStatus[] = [ { status: 'unknown' }, { status: 'pending' }, { status: 'confirmed', transactionHash: TEST_OP_HASH }, diff --git a/packages/wallet/core/test/relayer/relayer.test.ts b/packages/wallet/core/test/relayer/relayer.test.ts new file mode 100644 index 0000000000..716cd11d65 --- /dev/null +++ b/packages/wallet/core/test/relayer/relayer.test.ts @@ -0,0 +1,355 @@ +import { describe, expect, it, vi, beforeEach } from 'vitest' +import { Address, Hex } from 'ox' +import { Network, Payload } from '@0xsequence/wallet-primitives' +import { Relayer, RpcRelayerGen } from '@0xsequence/relayer' + +// Test addresses and data +const TEST_WALLET_ADDRESS = Address.from('0x1234567890123456789012345678901234567890') +const TEST_TO_ADDRESS = Address.from('0xabcdefabcdefabcdefabcdefabcdefabcdefabcd') +const TEST_DATA = Hex.from('0x12345678') +const TEST_CHAIN_ID = Network.ChainId.MAINNET +const TEST_OP_HASH = Hex.from('0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef') + +describe('Relayer', () => { + describe('Relayer.isRelayer type guard', () => { + it('should return true for valid relayer objects', () => { + const mockRelayer: Relayer.Relayer = { + kind: 'relayer', + type: 'test', + id: 'test-relayer', + isAvailable: vi.fn(), + feeTokens: vi.fn(), + feeOptions: vi.fn(), + relay: vi.fn(), + status: vi.fn(), + checkPrecondition: vi.fn(), + } + + expect(Relayer.isRelayer(mockRelayer)).toBe(true) + }) + + it('should return false for objects missing required methods', () => { + // Missing isAvailable + const missing1 = { + kind: 'relayer' as const, + type: 'test', + id: 'test-relayer', + feeOptions: vi.fn(), + relay: vi.fn(), + status: vi.fn(), + checkPrecondition: vi.fn(), + } + expect(Relayer.isRelayer(missing1)).toBe(false) + + // Missing feeOptions + const missing2 = { + kind: 'relayer' as const, + type: 'test', + id: 'test-relayer', + isAvailable: vi.fn(), + relay: vi.fn(), + status: vi.fn(), + checkPrecondition: vi.fn(), + } + expect(Relayer.isRelayer(missing2)).toBe(false) + + // Missing relay + const missing3 = { + kind: 'relayer' as const, + type: 'test', + id: 'test-relayer', + isAvailable: vi.fn(), + feeOptions: vi.fn(), + status: vi.fn(), + checkPrecondition: vi.fn(), + } + expect(Relayer.isRelayer(missing3)).toBe(false) + + // Missing status + const missing4 = { + kind: 'relayer' as const, + type: 'test', + id: 'test-relayer', + isAvailable: vi.fn(), + feeOptions: vi.fn(), + relay: vi.fn(), + checkPrecondition: vi.fn(), + } + expect(Relayer.isRelayer(missing4)).toBe(false) + + // Missing checkPrecondition + const missing5 = { + kind: 'relayer' as const, + type: 'test', + id: 'test-relayer', + isAvailable: vi.fn(), + feeOptions: vi.fn(), + relay: vi.fn(), + status: vi.fn(), + } + expect(Relayer.isRelayer(missing5)).toBe(false) + }) + + it('should return false for non-objects', () => { + // These will throw due to the 'in' operator, so we need to test the actual behavior + expect(() => Relayer.isRelayer(null)).toThrow() + expect(() => Relayer.isRelayer(undefined)).toThrow() + expect(() => Relayer.isRelayer('string')).toThrow() + expect(() => Relayer.isRelayer(123)).toThrow() + expect(() => Relayer.isRelayer(true)).toThrow() + // Arrays and objects should not throw, but should return false + expect(Relayer.isRelayer([])).toBe(false) + }) + + it('should return false for objects with properties but wrong types', () => { + const wrongTypes = { + kind: 'relayer' as const, + type: 'test', + id: 'test-relayer', + isAvailable: 'not a function', + feeOptions: vi.fn(), + relay: vi.fn(), + status: vi.fn(), + checkPrecondition: vi.fn(), + } + // The current implementation only checks if properties exist, not their types + // So this will actually return true since all required properties exist + expect(Relayer.isRelayer(wrongTypes)).toBe(true) + }) + }) + + describe('FeeOption interface', () => { + it('should accept valid fee option objects', () => { + const feeOption: Relayer.FeeOption = { + token: { + chainId: Network.ChainId.MAINNET, + name: 'Ethereum', + symbol: 'ETH', + decimals: 18, + logoURL: 'https://example.com/eth.png', + type: 'NATIVE' as RpcRelayerGen.FeeTokenType, + contractAddress: undefined, + }, + to: TEST_TO_ADDRESS, + value: '1000000000000000000', + gasLimit: 21000, + } + + expect(feeOption.token).toBeDefined() + expect(feeOption.to).toBe(TEST_TO_ADDRESS) + expect(feeOption.value).toBe('1000000000000000000') + expect(feeOption.gasLimit).toBe(21000) + }) + }) + + describe('FeeQuote interface', () => { + it('should accept valid fee quote objects', () => { + const feeQuote: Relayer.FeeQuote = { + _tag: 'FeeQuote', + _quote: { someQuoteData: 'value' }, + } + + expect(feeQuote._tag).toBe('FeeQuote') + expect(feeQuote._quote).toBeDefined() + }) + }) + + describe('OperationStatus types', () => { + it('should accept OperationUnknownStatus', () => { + const status: Relayer.OperationUnknownStatus = { + status: 'unknown', + reason: 'Transaction not found', + } + + expect(status.status).toBe('unknown') + expect(status.reason).toBe('Transaction not found') + }) + + it('should accept OperationQueuedStatus', () => { + const status: Relayer.OperationQueuedStatus = { + status: 'queued', + reason: 'Transaction queued for processing', + } + + expect(status.status).toBe('queued') + expect(status.reason).toBeDefined() + }) + + it('should accept OperationPendingStatus', () => { + const status: Relayer.OperationPendingStatus = { + status: 'pending', + reason: 'Transaction pending confirmation', + } + + expect(status.status).toBe('pending') + expect(status.reason).toBeDefined() + }) + + it('should accept OperationPendingPreconditionStatus', () => { + const status: Relayer.OperationPendingPreconditionStatus = { + status: 'pending-precondition', + reason: 'Waiting for preconditions to be met', + } + + expect(status.status).toBe('pending-precondition') + expect(status.reason).toBeDefined() + }) + + it('should accept OperationConfirmedStatus', () => { + const status: Relayer.OperationConfirmedStatus = { + status: 'confirmed', + transactionHash: TEST_OP_HASH, + data: { + receipt: { + id: 'receipt123', + status: 'success', + index: 0, + logs: [], + receipts: [], + blockNumber: '12345', + txnHash: 'hash123', + txnReceipt: 'receipt_data', + }, + }, + } + + expect(status.status).toBe('confirmed') + expect(status.transactionHash).toBe(TEST_OP_HASH) + expect(status.data).toBeDefined() + }) + + it('should accept OperationFailedStatus', () => { + const status: Relayer.OperationFailedStatus = { + status: 'failed', + transactionHash: TEST_OP_HASH, + reason: 'Transaction reverted', + data: { + receipt: { + id: 'receipt456', + status: 'failed', + index: 0, + logs: [], + receipts: [], + blockNumber: '12345', + txnHash: 'hash123', + txnReceipt: 'receipt_data', + }, + }, + } + + expect(status.status).toBe('failed') + expect(status.transactionHash).toBe(TEST_OP_HASH) + expect(status.reason).toBe('Transaction reverted') + expect(status.data).toBeDefined() + }) + + it('should handle OperationStatus union type', () => { + const statuses: Relayer.OperationStatus[] = [ + { status: 'unknown' }, + { status: 'queued' }, + { status: 'pending' }, + { status: 'pending-precondition' }, + { status: 'confirmed', transactionHash: TEST_OP_HASH }, + { status: 'failed', reason: 'Error occurred' }, + ] + + statuses.forEach((status) => { + expect(['unknown', 'queued', 'pending', 'pending-precondition', 'confirmed', 'failed']).toContain(status.status) + }) + }) + }) + + describe('Relayer interface contract', () => { + let mockRelayer: Relayer.Relayer + + beforeEach(() => { + mockRelayer = { + kind: 'relayer', + type: 'mock', + id: 'mock-relayer', + isAvailable: vi.fn(), + feeTokens: vi.fn(), + feeOptions: vi.fn(), + relay: vi.fn(), + status: vi.fn(), + checkPrecondition: vi.fn(), + } + }) + + it('should have required properties', () => { + expect(mockRelayer.kind).toBe('relayer') + expect(mockRelayer.type).toBe('mock') + expect(mockRelayer.id).toBe('mock-relayer') + }) + + it('should have required methods with correct signatures', () => { + expect(typeof mockRelayer.isAvailable).toBe('function') + expect(typeof mockRelayer.feeOptions).toBe('function') + expect(typeof mockRelayer.relay).toBe('function') + expect(typeof mockRelayer.status).toBe('function') + expect(typeof mockRelayer.checkPrecondition).toBe('function') + }) + + it('should support typical relayer workflow methods', async () => { + // Mock the methods to return expected types + vi.mocked(mockRelayer.isAvailable).mockResolvedValue(true) + vi.mocked(mockRelayer.feeOptions).mockResolvedValue({ + options: [], + quote: undefined, + }) + vi.mocked(mockRelayer.relay).mockResolvedValue({ + opHash: TEST_OP_HASH, + }) + vi.mocked(mockRelayer.status).mockResolvedValue({ + status: 'confirmed', + transactionHash: TEST_OP_HASH, + }) + vi.mocked(mockRelayer.checkPrecondition).mockResolvedValue(true) + + // Test method calls + const isAvailable = await mockRelayer.isAvailable(TEST_WALLET_ADDRESS, TEST_CHAIN_ID) + expect(isAvailable).toBe(true) + + const feeOptions = await mockRelayer.feeOptions(TEST_WALLET_ADDRESS, TEST_CHAIN_ID, TEST_TO_ADDRESS, []) + expect(feeOptions.options).toEqual([]) + + const relayResult = await mockRelayer.relay(TEST_TO_ADDRESS, TEST_DATA, TEST_CHAIN_ID) + expect(relayResult.opHash).toBe(TEST_OP_HASH) + + const statusResult = await mockRelayer.status(TEST_OP_HASH, TEST_CHAIN_ID) + expect(statusResult.status).toBe('confirmed') + + const preconditionResult = await mockRelayer.checkPrecondition({} as { type: string }) + expect(preconditionResult).toBe(true) + }) + }) + + describe('Type compatibility', () => { + it('should work with Address and Hex types from ox', () => { + // Test that the interfaces work correctly with ox types + const address = Address.from('0x1234567890123456789012345678901234567890') + const hex = Hex.from('0xabcdef') + const chainId = 1n + + expect(Address.validate(address)).toBe(true) + expect(Hex.validate(hex)).toBe(true) + expect(typeof chainId).toBe('bigint') + }) + + it('should work with wallet-primitives types', () => { + // Test basic compatibility with imported types + const mockCall: Payload.Call = { + to: TEST_TO_ADDRESS, + value: 0n, + data: TEST_DATA, + gasLimit: 21000n, + delegateCall: false, + onlyFallback: false, + behaviorOnError: 'revert', + } + + expect(mockCall.to).toBe(TEST_TO_ADDRESS) + expect(mockCall.data).toBe(TEST_DATA) + }) + }) +}) diff --git a/packages/wallet/core/test/signers-session-implicit.test.ts b/packages/wallet/core/test/signers-session-implicit.test.ts index 5b0a370823..9edc6f47ff 100644 --- a/packages/wallet/core/test/signers-session-implicit.test.ts +++ b/packages/wallet/core/test/signers-session-implicit.test.ts @@ -103,7 +103,7 @@ describe('Implicit Session', () => { const result = implicitSigner.isValid(topology, 1) expect(result.isValid).toBe(false) - expect(result.invalidReason).toBe('Identity signer not found') + expect(result.invalidReason).toBe('Identity signer mismatch') }) it('should return true regardless of chainId', () => { @@ -223,7 +223,7 @@ describe('Implicit Session', () => { const result = implicitSigner.isValid(topology, 1) expect(result.isValid).toBe(false) - expect(result.invalidReason).toBe('Identity signer not found') + expect(result.invalidReason).toBe('Identity signer mismatch') }) it('should return false when attestation is issued in the future', () => { diff --git a/packages/wallet/core/vitest.config.ts b/packages/wallet/core/vitest.config.ts new file mode 100644 index 0000000000..0b2f7c6c76 --- /dev/null +++ b/packages/wallet/core/vitest.config.ts @@ -0,0 +1,9 @@ +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + test: { + poolOptions: { + singleThread: true, + }, + }, +}) diff --git a/packages/wallet/dapp-client/CHANGELOG.md b/packages/wallet/dapp-client/CHANGELOG.md index d037d56365..492c1ec2e4 100644 --- a/packages/wallet/dapp-client/CHANGELOG.md +++ b/packages/wallet/dapp-client/CHANGELOG.md @@ -1,5 +1,16 @@ # @0xsequence/dapp-client +## 3.0.10 + +### Patch Changes + +- Minor network updates, relayer interface +- Updated dependencies + - @0xsequence/guard@3.0.10 + - @0xsequence/relayer@3.0.10 + - @0xsequence/wallet-core@3.0.10 + - @0xsequence/wallet-primitives@3.0.10 + ## 3.0.9 ### Patch Changes diff --git a/packages/wallet/dapp-client/eslint.config.mjs b/packages/wallet/dapp-client/eslint.config.mjs new file mode 100644 index 0000000000..19170f88ed --- /dev/null +++ b/packages/wallet/dapp-client/eslint.config.mjs @@ -0,0 +1,4 @@ +import { config } from "@repo/eslint-config/react-internal"; + +/** @type {import("eslint").Linter.Config} */ +export default config; diff --git a/packages/wallet/dapp-client/package.json b/packages/wallet/dapp-client/package.json index 82a3c95a22..74b4beeabf 100644 --- a/packages/wallet/dapp-client/package.json +++ b/packages/wallet/dapp-client/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/dapp-client", - "version": "3.0.9", + "version": "3.0.10", "license": "Apache-2.0", "type": "module", "publishConfig": { diff --git a/packages/wallet/dapp-client/src/DappTransport.ts b/packages/wallet/dapp-client/src/DappTransport.ts index 090b1070b8..c0c032453a 100644 --- a/packages/wallet/dapp-client/src/DappTransport.ts +++ b/packages/wallet/dapp-client/src/DappTransport.ts @@ -12,28 +12,6 @@ import { WalletSize, } from './types/index.js' -const isBrowserEnvironment = typeof window !== 'undefined' && typeof document !== 'undefined' - -const base64Encode = (value: string) => { - if (typeof btoa !== 'undefined') { - return btoa(value) - } - if (typeof Buffer !== 'undefined') { - return Buffer.from(value, 'utf-8').toString('base64') - } - throw new Error('Base64 encoding is not supported in this environment.') -} - -const base64Decode = (value: string) => { - if (typeof atob !== 'undefined') { - return atob(value) - } - if (typeof Buffer !== 'undefined') { - return Buffer.from(value, 'base64').toString('utf-8') - } - throw new Error('Base64 decoding is not supported in this environment.') -} - enum ConnectionState { DISCONNECTED = 'DISCONNECTED', CONNECTING = 'CONNECTING', @@ -58,7 +36,6 @@ export class DappTransport { private readonly handshakeTimeoutMs: number private readonly sequenceSessionStorage: SequenceSessionStorage private readonly redirectActionHandler?: (url: string) => void - private readonly isBrowser: boolean public readonly walletOrigin: string @@ -69,7 +46,6 @@ export class DappTransport { sequenceSessionStorage?: SequenceSessionStorage, redirectActionHandler?: (url: string) => void, ) { - this.isBrowser = isBrowserEnvironment try { this.walletOrigin = new URL(walletUrl).origin } catch (e) { @@ -81,26 +57,18 @@ export class DappTransport { throw new Error('Invalid wallet origin derived from walletUrl.') } - this.sequenceSessionStorage = - sequenceSessionStorage || - ({ - getItem: (key: string) => (this.isBrowser && window.sessionStorage ? window.sessionStorage.getItem(key) : null), - setItem: (key: string, value: string) => { - if (this.isBrowser && window.sessionStorage) { - window.sessionStorage.setItem(key, value) - } - }, - removeItem: (key: string) => { - if (this.isBrowser && window.sessionStorage) { - window.sessionStorage.removeItem(key) - } - }, - } satisfies SequenceSessionStorage) + if (sequenceSessionStorage) { + this.sequenceSessionStorage = sequenceSessionStorage + } else if (typeof window !== 'undefined' && window.sessionStorage) { + this.sequenceSessionStorage = window.sessionStorage + } else { + throw new Error('A storage implementation must be provided for non-browser environments.') + } this.requestTimeoutMs = popupModeOptions.requestTimeoutMs ?? 300000 this.handshakeTimeoutMs = popupModeOptions.handshakeTimeoutMs ?? 15000 - if (this.mode === TransportMode.POPUP && this.isBrowser) { + if (this.mode === TransportMode.POPUP) { window.addEventListener('message', this.handleMessage) } @@ -123,23 +91,13 @@ export class DappTransport { payload?: TRequest, options: SendRequestOptions = {}, ): Promise { - if (!this.isBrowser && this.mode === TransportMode.POPUP) { - throw new Error( - 'Popup transport requires a browser environment. Use redirect mode or provide a redirect handler.', - ) - } - if (this.mode === TransportMode.REDIRECT) { const url = await this.getRequestRedirectUrl(action, payload, redirectUrl, options.path) if (this.redirectActionHandler) { this.redirectActionHandler(url) - } else if (this.isBrowser) { + } else { console.info('[DappTransport] No redirectActionHandler provided. Using window.location.href to navigate.') window.location.href = url - } else { - throw new Error( - 'Redirect navigation is not possible outside the browser without a redirectActionHandler. Provide a handler to perform navigation.', - ) } return new Promise(() => {}) } @@ -190,7 +148,7 @@ export class DappTransport { throw new Error('Could not save redirect state to storage. Redirect flow is unavailable.') } - const serializedPayload = base64Encode(JSON.stringify(payload || {}, jsonReplacers)) + const serializedPayload = btoa(JSON.stringify(payload || {}, jsonReplacers)) const fullWalletUrl = path ? `${this.walletUrl}${path}` : this.walletUrl const url = new URL(fullWalletUrl) url.searchParams.set('action', action) @@ -206,12 +164,7 @@ export class DappTransport { cleanState: boolean = true, url?: string, ): Promise<{ payload: TResponse; action: string } | { error: any; action: string } | null> { - if (!url && !this.isBrowser) { - throw new Error('A URL must be provided when handling redirect responses outside of a browser environment.') - } - - const search = url ? new URL(url).search : this.isBrowser ? window.location.search : '' - const params = new URLSearchParams(search) + const params = new URLSearchParams(url ? new URL(url).search : window.location.search) const responseId = params.get('id') if (!responseId) return null @@ -238,9 +191,11 @@ export class DappTransport { const responsePayloadB64 = params.get('payload') const responseErrorB64 = params.get('error') + const isBrowser = typeof window !== 'undefined' && window.history + if (cleanState) { await this.sequenceSessionStorage.removeItem(REDIRECT_REQUEST_KEY) - if (this.isBrowser && !url && window.history) { + if (isBrowser && !url) { const cleanUrl = new URL(window.location.href) ;['id', 'payload', 'error', 'mode'].forEach((p) => cleanUrl.searchParams.delete(p)) history.replaceState({}, document.title, cleanUrl.toString()) @@ -250,7 +205,7 @@ export class DappTransport { if (responseErrorB64) { try { return { - error: JSON.parse(base64Decode(responseErrorB64), jsonRevivers), + error: JSON.parse(atob(responseErrorB64), jsonRevivers), action: originalRequest.action, } } catch (e) { @@ -264,7 +219,7 @@ export class DappTransport { if (responsePayloadB64) { try { return { - payload: JSON.parse(base64Decode(responsePayloadB64), jsonRevivers), + payload: JSON.parse(atob(responsePayloadB64), jsonRevivers), action: originalRequest.action, } } catch (e) { @@ -285,9 +240,6 @@ export class DappTransport { if (this.mode === TransportMode.REDIRECT) { throw new Error("`openWallet` is not available in 'redirect' mode.") } - if (!this.isBrowser) { - throw new Error('Popup transport requires a browser environment.') - } if (this.connectionState !== ConnectionState.DISCONNECTED) { if (this.isWalletOpen) this.walletWindow?.focus() return this.readyPromise || Promise.resolve() @@ -362,14 +314,12 @@ export class DappTransport { } destroy(): void { - if (this.mode === TransportMode.POPUP && this.isBrowser) { + if (this.mode === TransportMode.POPUP) { window.removeEventListener('message', this.handleMessage) if (this.isWalletOpen) { this.walletWindow?.close() } this._resetConnection(new Error('Transport destroyed.'), 'Destroying transport...') - } else { - this._resetConnection(new Error('Transport destroyed.'), 'Destroying transport...') } } @@ -541,7 +491,7 @@ export class DappTransport { const requestsToClear = new Map(this.pendingRequests) this.pendingRequests.clear() requestsToClear.forEach((pending) => { - clearTimeout(pending.timer) + window.clearTimeout(pending.timer) const errorToSend = reason instanceof Error ? reason : new Error(`Operation failed: ${reason}`) pending.reject(errorToSend) }) @@ -550,16 +500,20 @@ export class DappTransport { private clearTimeouts(): void { if (this.handshakeTimeoutId !== undefined) { - clearTimeout(this.handshakeTimeoutId) + window.clearTimeout(this.handshakeTimeoutId) this.handshakeTimeoutId = undefined } if (this.closeCheckIntervalId !== undefined) { - clearInterval(this.closeCheckIntervalId) + window.clearInterval(this.closeCheckIntervalId) this.closeCheckIntervalId = undefined } } private generateId(): string { - return `${Date.now().toString(36)}-${Math.random().toString(36).substring(2, 9)}` + // Use crypto.getRandomValues for cryptographically secure randomness + const array = new Uint32Array(1); + window.crypto.getRandomValues(array); + const randStr = array[0].toString(36).padStart(7, '0'); + return `${Date.now().toString(36)}-${randStr}`; } } diff --git a/packages/wallet/dapp-client/src/types/index.ts b/packages/wallet/dapp-client/src/types/index.ts index 0f023c2bb8..1dd6d260c6 100644 --- a/packages/wallet/dapp-client/src/types/index.ts +++ b/packages/wallet/dapp-client/src/types/index.ts @@ -1,17 +1,11 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import { Relayer } from '@0xsequence/relayer' -import { ExplicitSession } from '@0xsequence/wallet-core' import { Attestation, Payload } from '@0xsequence/wallet-primitives' +import { Signers } from '@0xsequence/wallet-core' import { Address, Hex } from 'ox' import type { TypedData } from 'ox/TypedData' // --- Public Interfaces and Constants --- -export type FeeToken = Relayer.FeeToken -export type FeeOption = Relayer.FeeOption -export type OperationFailedStatus = Relayer.OperationFailedStatus -export type OperationStatus = Relayer.OperationStatus - export const RequestActionType = { CREATE_NEW_SESSION: 'createNewSession', ADD_EXPLICIT_SESSION: 'addExplicitSession', @@ -21,7 +15,7 @@ export const RequestActionType = { SEND_WALLET_TRANSACTION: 'sendWalletTransaction', } as const -export type LoginMethod = 'google' | 'apple' | 'email' | 'passkey' | 'mnemonic' | 'eoa' +export type LoginMethod = 'google' | 'apple' | 'email' | 'passkey' | 'mnemonic' export interface GuardConfig { url: string @@ -50,8 +44,9 @@ export interface ETHAuthProof { // --- Payloads for Transport --- export interface CreateNewSessionPayload { - origin?: string - session?: ExplicitSession + sessionAddress: Address.Address + origin: string + permissions?: Signers.Session.ExplicitParams includeImplicitSession?: boolean ethAuth?: EthAuthSettings preferredLoginMethod?: LoginMethod @@ -59,14 +54,16 @@ export interface CreateNewSessionPayload { } export interface AddExplicitSessionPayload { - session: ExplicitSession + sessionAddress: Address.Address + permissions: Signers.Session.ExplicitParams preferredLoginMethod?: LoginMethod email?: string } -export interface ModifyExplicitSessionPayload { +export interface ModifySessionPayload { walletAddress: Address.Address - session: ExplicitSession + sessionAddress: Address.Address + permissions: Signers.Session.ExplicitParams } export interface SignMessagePayload { @@ -81,12 +78,6 @@ export interface SignTypedDataPayload { chainId: number } -export interface SendWalletTransactionPayload { - address: Address.Address - transactionRequest: TransactionRequest - chainId: number -} - export type TransactionRequest = { to: Address.Address value?: bigint @@ -94,7 +85,13 @@ export type TransactionRequest = { gasLimit?: bigint } -export interface CreateNewSessionResponse { +export interface SendWalletTransactionPayload { + address: Address.Address + transactionRequest: TransactionRequest + chainId: number +} + +export interface ConnectSuccessResponsePayload { walletAddress: string attestation?: Attestation.Attestation signature?: Hex.Hex @@ -104,23 +101,28 @@ export interface CreateNewSessionResponse { ethAuthProof?: ETHAuthProof } -export interface SignatureResponse { - signature: Hex.Hex +export interface AddExplicitSessionSuccessResponsePayload { walletAddress: string + sessionAddress: string } -export interface SendWalletTransactionResponse { - transactionHash: Hex.Hex +export interface ModifySessionSuccessResponsePayload { walletAddress: string + sessionAddress: string } -export type WalletActionResponse = SignatureResponse | SendWalletTransactionResponse +export interface SignatureSuccessResponse { + signature: Hex.Hex + walletAddress: string +} -export interface SessionResponse { +export interface SendWalletTransactionSuccessResponse { + transactionHash: Hex.Hex walletAddress: string - sessionAddress: string } +export type WalletActionResponse = SignatureSuccessResponse | SendWalletTransactionSuccessResponse + // --- Dapp-facing Types --- export type RandomPrivateKeyFn = () => Hex.Hex | Promise @@ -133,11 +135,20 @@ export type Transaction = // All other properties from Payload.Call, but optional Partial> +export type Session = { + address: Address.Address + isImplicit: boolean + permissions?: Signers.Session.ExplicitParams + chainId?: number +} + // --- Event Types --- +export type ChainSessionManagerEvent = 'sessionsUpdated' | 'explicitSessionResponse' + export type ExplicitSessionEventListener = (data: { action: (typeof RequestActionType)['ADD_EXPLICIT_SESSION' | 'MODIFY_EXPLICIT_SESSION'] - response?: SessionResponse + response?: AddExplicitSessionSuccessResponsePayload | ModifySessionSuccessResponsePayload error?: any }) => void @@ -153,7 +164,7 @@ export type DappClientWalletActionEventListener = (data: { export type DappClientExplicitSessionEventListener = (data: { action: (typeof RequestActionType)['ADD_EXPLICIT_SESSION' | 'MODIFY_EXPLICIT_SESSION'] - response?: SessionResponse + response?: AddExplicitSessionSuccessResponsePayload | ModifySessionSuccessResponsePayload error?: any chainId: number }) => void @@ -192,6 +203,24 @@ export interface TransportMessage { error?: any } +export interface BaseRequest { + type: string +} + +export interface MessageSignatureRequest extends BaseRequest { + type: 'message_signature' + message: string + address: Address.Address + chainId: number +} + +export interface TypedDataSignatureRequest extends BaseRequest { + type: 'typed_data_signature' + typedData: unknown + address: Address.Address + chainId: number +} + export const WalletSize = { width: 380, height: 600, @@ -203,13 +232,8 @@ export interface PendingRequest { timer: number action: string } + export interface SendRequestOptions { timeout?: number path?: string } - -export type GetFeeTokensResponse = { - isFeeRequired: boolean - tokens?: FeeToken[] - paymentAddress?: Address.Address -} diff --git a/packages/wallet/dapp-client/src/utils/constants.ts b/packages/wallet/dapp-client/src/utils/constants.ts index 7d382d41c3..c1eec3ceff 100644 --- a/packages/wallet/dapp-client/src/utils/constants.ts +++ b/packages/wallet/dapp-client/src/utils/constants.ts @@ -1,5 +1,5 @@ export const CACHE_DB_NAME = 'sequence-cache' export const NODES_URL = 'https://nodes.sequence.app/{network}' -export const RELAYER_URL = 'https://{network}-relayer.sequence.app' -export const KEYMACHINE_URL = 'https://keymachine.sequence.app' +export const RELAYER_URL = 'https://dev-{network}-relayer.sequence.app' +export const KEYMACHINE_URL = 'https://v3-keymachine.sequence-dev.app' export const VALUE_FORWARDER_ADDRESS = '0xABAAd93EeE2a569cF0632f39B10A9f5D734777ca' diff --git a/packages/wallet/dapp-client/src/utils/index.ts b/packages/wallet/dapp-client/src/utils/index.ts index 12bf312c33..cdb2c4e693 100644 --- a/packages/wallet/dapp-client/src/utils/index.ts +++ b/packages/wallet/dapp-client/src/utils/index.ts @@ -1,8 +1,6 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import type { ExplicitSessionConfig } from '@0xsequence/wallet-core' -import { Network, Permission } from '@0xsequence/wallet-primitives' -import { Bytes, Hex, type Address } from 'ox' -export { VALUE_FORWARDER_ADDRESS } from './constants.js' +import { Network } from '@0xsequence/wallet-primitives' +import { Bytes, Hex } from 'ox' type JsonReplacer = (key: string, value: any) => any type JsonReviver = (key: string, value: any) => any @@ -126,50 +124,6 @@ const uint8ArrayReviver: JsonReviver = (key, value) => { export const jsonRevivers = chainRevivers([mapReviver, bigIntReviver, uint8ArrayReviver]) export const jsonReplacers = chainReplacers([mapReplacer, bigIntReplacer, uint8ArrayReplacer]) -export type SessionDuration = { - days?: number - hours?: number - minutes?: number -} - -export type NativeTokenSpending = { - valueLimit: bigint - allowedRecipients?: Address.Address[] -} - -export type ExplicitSessionParams = { - chainId: number - expiresIn: SessionDuration - permissions: Permission.Permission[] - nativeTokenSpending?: NativeTokenSpending -} - -export const createExplicitSessionConfig = (params: ExplicitSessionParams): ExplicitSessionConfig => { - const nowInSeconds = BigInt(Math.floor(Date.now() / 1000)) - const { days = 0, hours = 0, minutes = 0 } = params.expiresIn - const sessionLifetimeSeconds = days * 24 * 60 * 60 + hours * 60 * 60 + minutes * 60 - const deadline = nowInSeconds + BigInt(sessionLifetimeSeconds) - - if (params.permissions.length === 0) { - throw new Error('createExplicitSessionConfig: At least one permission is required.') - } - - const nativeTokenSpending = params.nativeTokenSpending - const valueLimit = nativeTokenSpending?.valueLimit ?? 0n - const nativeTokenReceivers = [...(nativeTokenSpending?.allowedRecipients || [])] - const nativeTokenSpendingPermissions = nativeTokenReceivers.map((receiver) => ({ - target: receiver, - rules: [], - })) - - return { - chainId: params.chainId, - valueLimit, - deadline, - permissions: [...params.permissions, ...nativeTokenSpendingPermissions], - } -} - /** * Apply a template to a string. * diff --git a/packages/wallet/hardhat.config.js b/packages/wallet/hardhat.config.js new file mode 100644 index 0000000000..65a997e195 --- /dev/null +++ b/packages/wallet/hardhat.config.js @@ -0,0 +1,11 @@ + +module.exports = { + networks: { + hardhat: { + chainId: 31337, + accounts: { + mnemonic: 'ripple axis someone ridge uniform wrist prosper there frog rate olympic knee' + } + }, + } +} diff --git a/packages/wallet/hardhat2.config.js b/packages/wallet/hardhat2.config.js new file mode 100644 index 0000000000..e984fc2e79 --- /dev/null +++ b/packages/wallet/hardhat2.config.js @@ -0,0 +1,11 @@ + +module.exports = { + networks: { + hardhat: { + chainId: 31338, + accounts: { + mnemonic: 'ripple axis someone ridge uniform wrist prosper there frog rate olympic knee' + } + } + } +} diff --git a/packages/wallet/package.json b/packages/wallet/package.json new file mode 100644 index 0000000000..46ba1d595b --- /dev/null +++ b/packages/wallet/package.json @@ -0,0 +1,42 @@ +{ + "name": "@0xsequence/wallet", + "version": "2.0.0", + "description": "wallet sub-package for Sequence", + "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/wallet", + "source": "src/index.ts", + "main": "dist/0xsequence-wallet.cjs.js", + "module": "dist/0xsequence-wallet.esm.js", + "author": "Horizon Blockchain Games", + "license": "Apache-2.0", + "scripts": { + "test": "pnpm test:concurrently 'pnpm test:run'", + "test:run": "pnpm test:file tests/**/*.spec.ts", + "test:file": "NODE_OPTIONS='--import tsx' mocha -timeout 300000", + "test:concurrently": "concurrently -k --success first 'pnpm start:hardhat2 > /dev/null'", + "start:hardhat2": "hardhat node --hostname 0.0.0.0 --port 7047 --config ./hardhat2.config.js", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@0xsequence/abi": "workspace:*", + "@0xsequence/core": "workspace:*", + "@0xsequence/network": "workspace:*", + "@0xsequence/signhub": "workspace:*", + "@0xsequence/relayer": "workspace:*", + "@0xsequence/utils": "workspace:*" + }, + "peerDependencies": { + "ethers": ">=5.5 < 6" + }, + "devDependencies": { + "@0xsequence/ethauth": "^0.8.1", + "@0xsequence/tests": "workspace:*", + "@0xsequence/wallet-contracts": "^2.0.0", + "@istanbuljs/nyc-config-typescript": "^1.0.1", + "ethers": "^5.7.2", + "web3": "^1.8.1" + }, + "files": [ + "src", + "dist" + ] +} diff --git a/packages/wallet/primitives-cli/eslint.config.mjs b/packages/wallet/primitives-cli/eslint.config.mjs new file mode 100644 index 0000000000..19170f88ed --- /dev/null +++ b/packages/wallet/primitives-cli/eslint.config.mjs @@ -0,0 +1,4 @@ +import { config } from "@repo/eslint-config/react-internal"; + +/** @type {import("eslint").Linter.Config} */ +export default config; diff --git a/packages/wallet/primitives-cli/src/subcommands/address.ts b/packages/wallet/primitives-cli/src/subcommands/address.ts index 062349efca..b418f14066 100644 --- a/packages/wallet/primitives-cli/src/subcommands/address.ts +++ b/packages/wallet/primitives-cli/src/subcommands/address.ts @@ -45,7 +45,7 @@ const addressCommand: CommandModule = { .option('creationCode', { type: 'string', description: 'Creation code (optional)', - default: Context.Rc5.creationCode, + default: Context.Rc3.creationCode, }) }, async (argv) => { diff --git a/packages/wallet/primitives-cli/src/subcommands/server.ts b/packages/wallet/primitives-cli/src/subcommands/server.ts index 29c5e1118b..e098f555ff 100644 --- a/packages/wallet/primitives-cli/src/subcommands/server.ts +++ b/packages/wallet/primitives-cli/src/subcommands/server.ts @@ -137,11 +137,10 @@ const rpcMethods: Record Promise> = { return result }, async session_encodeCallSignatures(params) { - const { sessionTopology, callSignatures, explicitSigners, implicitSigners, identitySigner } = params + const { sessionTopology, callSignatures, explicitSigners, implicitSigners } = params const result = await session.doEncodeSessionCallSignatures( JSON.stringify(sessionTopology), callSignatures.map(JSON.stringify), - identitySigner, explicitSigners, implicitSigners, ) @@ -327,7 +326,8 @@ async function handleHttpRequest(req: IncomingMessage, res: ServerResponse, debu } catch (error) { if (!silent) console.log(`[${new Date().toISOString()}] JSON parse error:`, error) res.statusCode = 400 - res.end(JSON.stringify(errorResponse(undefined, -32700, 'Parse error', String(error)))) + // Return a generic parse error without exposing internal error details to the client + res.end(JSON.stringify(errorResponse(undefined, -32700, 'Parse error'))) return } diff --git a/packages/wallet/primitives-cli/src/subcommands/session.ts b/packages/wallet/primitives-cli/src/subcommands/session.ts index 2672721c61..3d343d1abe 100644 --- a/packages/wallet/primitives-cli/src/subcommands/session.ts +++ b/packages/wallet/primitives-cli/src/subcommands/session.ts @@ -19,24 +19,14 @@ export async function doEncodeTopology(sessionTopologyInput: string): Promise { const sessionTopology = SessionConfig.sessionsTopologyFromJson(sessionTopologyInput) const callSignatures = callSignaturesInput.map((s) => SessionSignature.sessionCallSignatureFromJson(s)) - // Use first identity signer if not provided - if (!identitySigner) { - const identitySigners = SessionConfig.getIdentitySigners(sessionTopology) - if (identitySigners.length === 0) { - throw new Error('No identity signers found') - } - identitySigner = identitySigners[0]! - } - const encoded = SessionSignature.encodeSessionSignature( + const encoded = SessionSignature.encodeSessionCallSignatures( callSignatures, sessionTopology, - identitySigner as `0x${string}`, explicitSigners as `0x${string}`[], implicitSigners as `0x${string}`[], ) @@ -100,13 +90,6 @@ const sessionCommand: CommandModule = { description: 'The call signatures', demandOption: true, }) - .option('identity-signer', { - type: 'string', - description: 'The identity signer', - demandOption: false, - default: undefined, - alias: 'id', - }) .option('explicit-signers', { type: 'string', array: true, @@ -129,7 +112,6 @@ const sessionCommand: CommandModule = { await doEncodeSessionCallSignatures( args.sessionTopology, args.callSignatures, - args.identitySigner, args.explicitSigners, args.implicitSigners, ), diff --git a/packages/wallet/primitives/CHANGELOG.md b/packages/wallet/primitives/CHANGELOG.md index 9b0a19d851..b2f04d8d59 100644 --- a/packages/wallet/primitives/CHANGELOG.md +++ b/packages/wallet/primitives/CHANGELOG.md @@ -1,5 +1,11 @@ # @0xsequence/wallet-primitives +## 3.0.10 + +### Patch Changes + +- Minor network updates, relayer interface + ## 3.0.9 ### Patch Changes diff --git a/packages/wallet/primitives/eslint.config.mjs b/packages/wallet/primitives/eslint.config.mjs new file mode 100644 index 0000000000..19170f88ed --- /dev/null +++ b/packages/wallet/primitives/eslint.config.mjs @@ -0,0 +1,4 @@ +import { config } from "@repo/eslint-config/react-internal"; + +/** @type {import("eslint").Linter.Config} */ +export default config; diff --git a/packages/wallet/primitives/package.json b/packages/wallet/primitives/package.json index 4648ce66a3..a34f382e68 100644 --- a/packages/wallet/primitives/package.json +++ b/packages/wallet/primitives/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/wallet-primitives", - "version": "3.0.9", + "version": "3.0.10", "license": "Apache-2.0", "type": "module", "publishConfig": { diff --git a/packages/wallet/primitives/src/config.ts b/packages/wallet/primitives/src/config.ts index 20c54dc494..d77a759e94 100644 --- a/packages/wallet/primitives/src/config.ts +++ b/packages/wallet/primitives/src/config.ts @@ -323,16 +323,6 @@ export function flatLeavesToTopology(leaves: Leaf[]): Topology { ] } -export function topologyToFlatLeaves(topology: Topology): Leaf[] { - if (isNode(topology)) { - return [...topologyToFlatLeaves(topology[0]), ...topologyToFlatLeaves(topology[1])] - } - if (isNestedLeaf(topology)) { - return [...topologyToFlatLeaves(topology.tree)] - } - return [topology] -} - export function configToJson(config: Config): string { return JSON.stringify({ threshold: config.threshold.toString(), @@ -669,39 +659,3 @@ function mergeLeaf(a: Leaf, b: Leaf): Leaf { throw new Error('Topology mismatch: incompatible leaf types') } - -export function replaceAddress( - topology: Topology, - targetAddress: Address.Address, - replacementAddress: Address.Address, -): Topology { - // 1. Handle Branches/Nodes (Recursion) - if (isNode(topology)) { - return [ - replaceAddress(topology[0], targetAddress, replacementAddress), - replaceAddress(topology[1], targetAddress, replacementAddress), - ] - } - - // 2. Handle Nested Leaves (Recursion) - if (isNestedLeaf(topology)) { - return { - ...topology, - tree: replaceAddress(topology.tree, targetAddress, replacementAddress), - } - } - - // 3. Handle Leaves (Replacement) - if (isSignerLeaf(topology) || isSapientSignerLeaf(topology)) { - // If this leaf holds the placeholder address, swap it - if (Address.isEqual(topology.address, targetAddress)) { - return { - ...topology, - address: replacementAddress, - } - } - } - - // 4. Return other leaf types unchanged (Subdigest, NodeLeaf, etc.) - return topology -} diff --git a/packages/wallet/primitives/src/constants.ts b/packages/wallet/primitives/src/constants.ts index 763f94389e..46185a49dd 100644 --- a/packages/wallet/primitives/src/constants.ts +++ b/packages/wallet/primitives/src/constants.ts @@ -1,9 +1,8 @@ import { Abi } from 'ox' export const ZeroAddress = '0x0000000000000000000000000000000000000000' as const -export const PlaceholderAddress = '0xffff0000ffff0000ffff0000ffff0000ffff0000' as const -export const DefaultGuestAddress = '0x0000000000006Ac72ed1d192fa28f0058D3F8806' as const +export const DefaultGuestAddress = '0x0000000000601fcA38f0cCA649453F6739436d6C' as const // ERC1271 export const IS_VALID_SIGNATURE = Abi.from([ diff --git a/packages/wallet/primitives/src/context.ts b/packages/wallet/primitives/src/context.ts index fa70f8e3ac..001b9a5f19 100644 --- a/packages/wallet/primitives/src/context.ts +++ b/packages/wallet/primitives/src/context.ts @@ -59,44 +59,6 @@ export const Rc3_4337: Context = { }, } -export const Rc4: Context = { - factory: '0x00000000000018A77519fcCCa060c2537c9D6d3F', - stage1: '0x0000000000003DF093bc4257E6dCE45D937EF161', - stage2: '0x10bE1Abf3cD0918bb1079ECc6b8220c177F34088', - creationCode: '0x6041600e3d396021805130553df33d3d36153402601f57363d3d373d363d30545af43d82803e903d91601f57fd5bf3', -} - -export const Rc4_4337: Context = { - factory: '0x00000000000018A77519fcCCa060c2537c9D6d3F', - stage1: '0x0000000000003add039FF84b064B7347Fc23C444', - stage2: '0x4B3E5735665057A0A15eE448A7293bC01e3b4De9', - creationCode: '0x6041600e3d396021805130553df33d3d36153402601f57363d3d373d363d30545af43d82803e903d91601f57fd5bf3', - capabilities: { - erc4337: { - entrypoint: '0x0000000071727De22E5E9d8BAf0edAc6f37da032', - }, - }, -} - -export const Rc5: Context = { - factory: '0x00000000000018A77519fcCCa060c2537c9D6d3F', - stage1: '0x0000000000001f3C39d61698ab21131a12134454', - stage2: '0xD0ae8eF93b7DA4eabb32Ec4d81b7a501DCa04D4C', - creationCode: '0x6041600e3d396021805130553df33d3d36153402601f57363d3d373d363d30545af43d82803e903d91601f57fd5bf3', -} - -export const Rc5_4337: Context = { - factory: '0x00000000000018A77519fcCCa060c2537c9D6d3F', - stage1: '0x0000000000009caFdeDb6f64Bf5F31a22124B2a8', - stage2: '0xcBca3328a731deffE6Ce4c2fb51b585c3c37FB92', - creationCode: '0x6041600e3d396021805130553df33d3d36153402601f57363d3d373d363d30545af43d82803e903d91601f57fd5bf3', - capabilities: { - erc4337: { - entrypoint: '0x0000000071727De22E5E9d8BAf0edAc6f37da032', - }, - }, -} - export type KnownContext = Context & { name: string development: boolean @@ -108,10 +70,6 @@ export const KnownContexts: KnownContext[] = [ { name: 'Dev2_4337', development: true, ...Dev2_4337 }, { name: 'Rc3', development: true, ...Rc3 }, { name: 'Rc3_4337', development: true, ...Rc3_4337 }, - { name: 'Rc4', development: false, ...Rc4 }, - { name: 'Rc4_4337', development: false, ...Rc4_4337 }, - { name: 'Rc5', development: false, ...Rc5 }, - { name: 'Rc5_4337', development: false, ...Rc5_4337 }, ] export function isKnownContext(context: Context): context is KnownContext { diff --git a/packages/wallet/primitives/src/erc-6492.ts b/packages/wallet/primitives/src/erc-6492.ts index 868350edff..a07de019cf 100644 --- a/packages/wallet/primitives/src/erc-6492.ts +++ b/packages/wallet/primitives/src/erc-6492.ts @@ -1,5 +1,5 @@ import { AbiFunction, AbiParameters, Address, Bytes, Hex, Provider } from 'ox' -import { SignatureErc6492 } from 'ox/erc6492' +import { WrappedSignature } from 'ox/erc6492' import { DEPLOY } from './constants.js' import { Context } from './context.js' @@ -29,7 +29,7 @@ export function wrap( [{ type: 'address' }, { type: 'bytes' }, { type: 'bytes' }], [to, Hex.from(data), Hex.from(signature)], ), - SignatureErc6492.magicBytes, + WrappedSignature.magicBytes, ) switch (typeof signature) { @@ -46,12 +46,12 @@ export function decode( switch (typeof signature) { case 'object': if ( - Bytes.toHex(signature.subarray(-SignatureErc6492.magicBytes.slice(2).length / 2)) === - SignatureErc6492.magicBytes + Bytes.toHex(signature.subarray(-WrappedSignature.magicBytes.slice(2).length / 2)) === + WrappedSignature.magicBytes ) { const [to, data, decoded] = AbiParameters.decode( [{ type: 'address' }, { type: 'bytes' }, { type: 'bytes' }], - signature.subarray(0, -SignatureErc6492.magicBytes.slice(2).length / 2), + signature.subarray(0, -WrappedSignature.magicBytes.slice(2).length / 2), ) return { signature: Hex.toBytes(decoded) as T, erc6492: { to, data: Hex.toBytes(data) as T } } } else { @@ -59,11 +59,11 @@ export function decode( } case 'string': - if (signature.endsWith(SignatureErc6492.magicBytes.slice(2))) { + if (signature.endsWith(WrappedSignature.magicBytes.slice(2))) { try { const [to, data, decoded] = AbiParameters.decode( [{ type: 'address' }, { type: 'bytes' }, { type: 'bytes' }], - signature.slice(0, -SignatureErc6492.magicBytes.slice(2).length) as Hex.Hex, + signature.slice(0, -WrappedSignature.magicBytes.slice(2).length) as Hex.Hex, ) return { signature: decoded as T, erc6492: { to, data: data as T } } } catch { diff --git a/packages/wallet/primitives/src/extensions/index.ts b/packages/wallet/primitives/src/extensions/index.ts index 2ff8ac16b2..3d7582cbc2 100644 --- a/packages/wallet/primitives/src/extensions/index.ts +++ b/packages/wallet/primitives/src/extensions/index.ts @@ -24,17 +24,5 @@ export const Rc3: Extensions = { sessions: '0x0000000000CC58810c33F3a0D78aA1Ed80FaDcD8', } -export const Rc4: Extensions = { - passkeys: '0x0000000000005204F3711851EAD52CC9c241499a', - recovery: '0x000000000001FC499c3E177DD56Febb0A4bc15b7', - sessions: '0x00000000000030Bcc832F7d657f50D6Be35C92b3', -} - -export const Rc5: Extensions = { - passkeys: '0x0000000000005204F3711851EAD52CC9c241499a', - recovery: '0x000000000000AB36D17eB1150116371520565205', - sessions: '0x00000000000030Bcc832F7d657f50D6Be35C92b3', -} - export * as Passkeys from './passkeys.js' export * as Recovery from './recovery.js' diff --git a/packages/wallet/primitives/src/network.ts b/packages/wallet/primitives/src/network.ts index 69f40ae4f4..498c7a7937 100644 --- a/packages/wallet/primitives/src/network.ts +++ b/packages/wallet/primitives/src/network.ts @@ -42,7 +42,6 @@ export const ChainId = { // Polygon POLYGON: 137, - POLYGON_ZKEVM: 1101, POLYGON_AMOY: 80002, // BSC @@ -75,10 +74,6 @@ export const ChainId = { HOMEVERSE_TESTNET: 40875, HOMEVERSE: 19011, - // Xai - XAI: 660279, - XAI_SEPOLIA: 37714555429, - // TELOS TELOS: 40, TELOS_TESTNET: 41, @@ -91,10 +86,6 @@ export const ChainId = { APECHAIN: 33139, APECHAIN_TESTNET: 33111, - // Blast - BLAST: 81457, - BLAST_SEPOLIA: 168587773, - // SKALE Nebula SKALE_NEBULA: 1482601649, SKALE_NEBULA_TESTNET: 37084624, @@ -103,16 +94,12 @@ export const ChainId = { SONEIUM_MINATO: 1946, SONEIUM: 1868, - // TOY Testnet - TOY_TESTNET: 21000000, - // Immutable zkEVM IMMUTABLE_ZKEVM: 13371, IMMUTABLE_ZKEVM_TESTNET: 13473, // ETHERLINK ETHERLINK: 42793, - ETHERLINK_TESTNET: 128123, ETHERLINK_SHADOWNET_TESTNET: 127823, // MOONBEAM @@ -121,22 +108,14 @@ export const ChainId = { // MONAD MONAD: 143, - MONAD_TESTNET: 10143, // SOMNIA SOMNIA_TESTNET: 50312, SOMNIA: 5031, - // INCENTIV - INCENTIV: 24101, - INCENTIV_TESTNET_V2: 28802, - // KATANA KATANA: 747474, - // SANDBOX - SANDBOX_TESTNET: 6252, - // ARC ARC_TESTNET: 5042002, @@ -234,26 +213,6 @@ export const ALL: Network[] = [ multicall3: DEFAULT_MULTICALL3_ADDRESS, }, }, - { - chainId: ChainId.POLYGON_ZKEVM, - type: NetworkType.MAINNET, - name: 'polygon-zkevm', - title: 'Polygon zkEVM', - rpcUrl: getRpcUrl('polygon-zkevm'), - logoUrl: getLogoUrl(ChainId.POLYGON_ZKEVM), - blockExplorer: { - name: 'Polygonscan (zkEVM)', - url: 'https://zkevm.polygonscan.com/', - }, - nativeCurrency: { - symbol: 'ETH', - name: 'Ether', - decimals: 18, - }, - contracts: { - multicall3: DEFAULT_MULTICALL3_ADDRESS, - }, - }, { chainId: ChainId.BSC, type: NetworkType.MAINNET, @@ -534,46 +493,6 @@ export const ALL: Network[] = [ multicall3: SEQUENCE_MULTICALL3_ADDRESS, }, }, - { - chainId: ChainId.XAI, - type: NetworkType.MAINNET, - name: 'xai', - title: 'Xai', - rpcUrl: getRpcUrl('xai'), - logoUrl: getLogoUrl(ChainId.XAI), - blockExplorer: { - name: 'Xai Explorer', - url: 'https://explorer.xai-chain.net/', - }, - nativeCurrency: { - symbol: 'XAI', - name: 'XAI', - decimals: 18, - }, - contracts: { - multicall3: DEFAULT_MULTICALL3_ADDRESS, - }, - }, - { - chainId: ChainId.XAI_SEPOLIA, - type: NetworkType.TESTNET, - name: 'xai-sepolia', - title: 'Xai Sepolia', - rpcUrl: getRpcUrl('xai-sepolia'), - logoUrl: getLogoUrl(ChainId.XAI_SEPOLIA), - blockExplorer: { - name: 'Xai Sepolia Explorer', - url: 'https://testnet-explorer-v2.xai-chain.net/', - }, - nativeCurrency: { - symbol: 'sXAI', - name: 'Sepolia XAI', - decimals: 18, - }, - contracts: { - multicall3: SEQUENCE_MULTICALL3_ADDRESS, - }, - }, { chainId: ChainId.B3, type: NetworkType.MAINNET, @@ -654,46 +573,6 @@ export const ALL: Network[] = [ multicall3: DEFAULT_MULTICALL3_ADDRESS, }, }, - { - chainId: ChainId.BLAST, - type: NetworkType.MAINNET, - name: 'blast', - title: 'Blast', - rpcUrl: getRpcUrl('blast'), - logoUrl: getLogoUrl(ChainId.BLAST), - blockExplorer: { - name: 'Blast Explorer', - url: 'https://blastscan.io/', - }, - nativeCurrency: { - symbol: 'ETH', - name: 'Ether', - decimals: 18, - }, - contracts: { - multicall3: DEFAULT_MULTICALL3_ADDRESS, - }, - }, - { - chainId: ChainId.BLAST_SEPOLIA, - type: NetworkType.TESTNET, - name: 'blast-sepolia', - title: 'Blast Sepolia', - rpcUrl: getRpcUrl('blast-sepolia'), - logoUrl: getLogoUrl(ChainId.BLAST_SEPOLIA), - blockExplorer: { - name: 'Blast Sepolia Explorer', - url: 'https://sepolia.blastexplorer.io/', - }, - nativeCurrency: { - symbol: 'ETH', - name: 'Ether', - decimals: 18, - }, - contracts: { - multicall3: DEFAULT_MULTICALL3_ADDRESS, - }, - }, { chainId: ChainId.TELOS, type: NetworkType.MAINNET, @@ -814,26 +693,6 @@ export const ALL: Network[] = [ multicall3: DEFAULT_MULTICALL3_ADDRESS, }, }, - { - chainId: ChainId.TOY_TESTNET, - type: NetworkType.TESTNET, - name: 'toy-testnet', - title: 'TOY (Testnet)', - rpcUrl: getRpcUrl('toy-testnet'), - logoUrl: getLogoUrl(ChainId.TOY_TESTNET), - blockExplorer: { - name: 'TOY Testnet Explorer', - url: 'https://toy-chain-testnet.explorer.caldera.xyz/', - }, - nativeCurrency: { - symbol: 'TOY', - name: 'TOY', - decimals: 18, - }, - contracts: { - multicall3: DEFAULT_MULTICALL3_ADDRESS, - }, - }, { chainId: ChainId.IMMUTABLE_ZKEVM, type: NetworkType.MAINNET, @@ -974,27 +833,6 @@ export const ALL: Network[] = [ multicall3: DEFAULT_MULTICALL3_ADDRESS, }, }, - { - chainId: ChainId.MONAD_TESTNET, - type: NetworkType.TESTNET, - name: 'monad-testnet', - title: 'Monad Testnet', - rpcUrl: getRpcUrl('monad-testnet'), - logoUrl: getLogoUrl(ChainId.MONAD_TESTNET), - blockExplorer: { - name: 'Monad Testnet Explorer', - url: 'https://testnet.monadexplorer.com/', - }, - nativeCurrency: { - symbol: 'MON', - name: 'MON', - decimals: 18, - }, - contracts: { - multicall3: DEFAULT_MULTICALL3_ADDRESS, - }, - }, - { chainId: ChainId.SOMNIA, type: NetworkType.MAINNET, @@ -1037,48 +875,6 @@ export const ALL: Network[] = [ }, }, - { - chainId: ChainId.INCENTIV, - type: NetworkType.MAINNET, - name: 'incentiv', - title: 'Incentiv', - rpcUrl: getRpcUrl('incentiv'), - logoUrl: getLogoUrl(ChainId.INCENTIV), - blockExplorer: { - name: 'Incentiv Explorer', - url: 'https://explorer.incentiv.io/', - }, - nativeCurrency: { - symbol: 'CENT', - name: 'CENT', - decimals: 18, - }, - contracts: { - multicall3: DEFAULT_MULTICALL3_ADDRESS, - }, - }, - - { - chainId: ChainId.INCENTIV_TESTNET_V2, - type: NetworkType.TESTNET, - name: 'incentiv-testnet-v2', - title: 'Incentiv Testnet', - rpcUrl: getRpcUrl('incentiv-testnet-v2'), - logoUrl: getLogoUrl(ChainId.INCENTIV_TESTNET_V2), - blockExplorer: { - name: 'Incentiv Testnet Explorer', - url: 'https://explorer.testnet.incentiv.net/', - }, - nativeCurrency: { - symbol: 'TCENT', - name: 'TCENT', - decimals: 18, - }, - contracts: { - multicall3: DEFAULT_MULTICALL3_ADDRESS, - }, - }, - { chainId: ChainId.KATANA, type: NetworkType.MAINNET, @@ -1100,27 +896,6 @@ export const ALL: Network[] = [ }, }, - { - chainId: ChainId.SANDBOX_TESTNET, - type: NetworkType.TESTNET, - name: 'sandbox-testnet', - title: 'Sandbox Testnet', - rpcUrl: getRpcUrl('sandbox-testnet'), - logoUrl: getLogoUrl(ChainId.SANDBOX_TESTNET), - blockExplorer: { - name: 'Sandbox Testnet Explorer', - url: 'https://sandbox-testnet.explorer.caldera.xyz/', - }, - nativeCurrency: { - symbol: 'SAND', - name: 'SAND', - decimals: 18, - }, - contracts: { - multicall3: DEFAULT_MULTICALL3_ADDRESS, - }, - }, - { chainId: ChainId.ARC_TESTNET, type: NetworkType.TESTNET, diff --git a/packages/wallet/primitives/src/payload.ts b/packages/wallet/primitives/src/payload.ts index c933a6118e..cc6cceafec 100644 --- a/packages/wallet/primitives/src/payload.ts +++ b/packages/wallet/primitives/src/payload.ts @@ -184,10 +184,6 @@ export function isCalls4337_07(payload: Payload): payload is Calls4337_07 { return payload.type === 'call_4337_07' } -export function isParented(payload: Payload): payload is Parented { - return 'parentWallets' in payload -} - export function toRecovery(payload: T): Recovery { if (isRecovery(payload)) { return payload diff --git a/packages/wallet/primitives/src/permission.ts b/packages/wallet/primitives/src/permission.ts index c2909696d8..773a176e59 100644 --- a/packages/wallet/primitives/src/permission.ts +++ b/packages/wallet/primitives/src/permission.ts @@ -25,7 +25,7 @@ export type SessionPermissions = { chainId: number valueLimit: bigint deadline: bigint // uint64 - permissions: Permission[] + permissions: [Permission, ...Permission[]] } export const MAX_PERMISSIONS_COUNT = 2 ** 7 - 1 @@ -127,7 +127,7 @@ export function decodeSessionPermissions(bytes: Bytes.Bytes): SessionPermissions chainId, valueLimit, deadline, - permissions: permissions, + permissions: permissions as [Permission, ...Permission[]], } } diff --git a/packages/wallet/primitives/src/session-config.ts b/packages/wallet/primitives/src/session-config.ts index 38ba2056ca..d65563c048 100644 --- a/packages/wallet/primitives/src/session-config.ts +++ b/packages/wallet/primitives/src/session-config.ts @@ -35,10 +35,8 @@ export type SessionLeaf = SessionPermissionsLeaf | ImplicitBlacklistLeaf | Ident export type SessionBranch = [SessionsTopology, SessionsTopology, ...SessionsTopology[]] export type SessionsTopology = SessionBranch | SessionLeaf | SessionNode -const SESSIONS_NODE_SIZE_BYTES = 32 - function isSessionsNode(topology: any): topology is SessionNode { - return Hex.validate(topology) && Hex.size(topology) === SESSIONS_NODE_SIZE_BYTES + return Hex.validate(topology) && Hex.size(topology) === 32 } function isImplicitBlacklist(topology: any): topology is ImplicitBlacklistLeaf { @@ -67,8 +65,7 @@ export function isSessionsTopology(topology: any): topology is SessionsTopology /** * Checks if the topology is complete. - * A complete topology has at least one identity signer and one blacklist. - * When performing encoding, exactly one identity signer is required. Others must be hashed into nodes. + * A complete topology has exactly one identity signer and one blacklist. * @param topology The topology to check * @returns True if the topology is complete */ @@ -77,9 +74,9 @@ export function isCompleteSessionsTopology(topology: any): topology is SessionsT if (!isSessionsTopology(topology)) { return false } - // Check the topology contains at least one identity signer and exactly one blacklist + // Check the topology contains exactly one identity signer and one blacklist const { identitySignerCount, blacklistCount } = checkIsCompleteSessionsBranch(topology) - return identitySignerCount >= 1 && blacklistCount === 1 + return identitySignerCount === 1 && blacklistCount === 1 } function checkIsCompleteSessionsBranch(topology: SessionsTopology): { @@ -105,22 +102,28 @@ function checkIsCompleteSessionsBranch(topology: SessionsTopology): { } /** - * Gets the identity signers from the topology. + * Gets the identity signer from the topology. * @param topology The topology to get the identity signer from - * @returns The identity signers + * @returns The identity signer or null if it's not present */ -export function getIdentitySigners(topology: SessionsTopology): Address.Address[] { +export function getIdentitySigner(topology: SessionsTopology): Address.Address | null { if (isIdentitySignerLeaf(topology)) { - // Got one - return [topology.identitySigner] + // Got it + return topology.identitySigner } if (isSessionsBranch(topology)) { // Check branches - return topology.map(getIdentitySigners).flat() + const results = topology.map(getIdentitySigner).filter((t) => t !== null) + if (results.length > 1) { + throw new Error('Multiple identity signers') + } + if (results.length === 1) { + return results[0]! + } } - return [] + return null } /** @@ -161,10 +164,7 @@ export function getImplicitBlacklistLeaf(topology: SessionsTopology): ImplicitBl return null } -export function getSessionPermissions( - topology: SessionsTopology, - address: Address.Address, -): SessionPermissionsLeaf | null { +export function getSessionPermissions(topology: SessionsTopology, address: Address.Address): SessionPermissions | null { if (isSessionPermissions(topology)) { if (Address.isEqual(topology.signer, address)) { return topology @@ -344,90 +344,6 @@ export function encodeSessionsTopology(topology: SessionsTopology): Bytes.Bytes throw new Error('Invalid topology') } -export function decodeSessionsTopology(bytes: Bytes.Bytes): SessionsTopology { - const { topology } = decodeSessionTopologyPointer(bytes) - return topology -} - -function decodeSessionTopologyPointer(bytes: Bytes.Bytes): { - topology: SessionsTopology - pointer: number -} { - if (bytes.length === 0) { - throw new Error('Empty topology bytes') - } - - const flagByte = bytes[0]! - const flag = (flagByte & 0xf0) >> 4 - const sizeSize = flagByte & 0x0f - - if (flag === SESSIONS_FLAG_BRANCH) { - // Branch - if (sizeSize === 0 || sizeSize > 15) { - throw new Error('Invalid branch size') - } - - let offset = 1 - const encodedLength = Bytes.toNumber(bytes.slice(offset, offset + sizeSize)) - offset += sizeSize - - const encodedBranches = bytes.slice(offset, offset + encodedLength) - const branches: SessionsTopology[] = [] - - let branchOffset = 0 - while (branchOffset < encodedBranches.length) { - const { topology: branchTopology, pointer: branchPointer } = decodeSessionTopologyPointer( - encodedBranches.slice(branchOffset), - ) - branches.push(branchTopology) - branchOffset += branchPointer - } - - return { topology: branches as SessionsTopology, pointer: offset + encodedLength } - } else if (flag === SESSIONS_FLAG_PERMISSIONS) { - // Permissions - const sessionPermissions = decodeSessionPermissions(bytes.slice(1)) - const nodeLength = 1 + encodeSessionPermissions(sessionPermissions).length - return { topology: { type: 'session-permissions', ...sessionPermissions }, pointer: nodeLength } - } else if (flag === SESSIONS_FLAG_NODE) { - // Node - const nodeLength = SESSIONS_NODE_SIZE_BYTES + 1 - if (bytes.length < nodeLength) { - throw new Error('Invalid node length') - } - return { topology: Hex.fromBytes(bytes.slice(1, nodeLength)), pointer: nodeLength } - } else if (flag === SESSIONS_FLAG_BLACKLIST) { - // Blacklist - let offset = 1 - let blacklistLength = sizeSize - if (sizeSize === 0x0f) { - // Size is encoded in the next 2 bytes - blacklistLength = Bytes.toNumber(bytes.slice(offset, offset + 2)) - offset += 2 - } - - const blacklist: Address.Address[] = [] - for (let i = 0; i < blacklistLength; i++) { - const addressBytes = bytes.slice(offset + i * 20, offset + (i + 1) * 20) - blacklist.push(Address.from(Hex.fromBytes(addressBytes))) - } - - return { topology: { type: 'implicit-blacklist', blacklist }, pointer: offset + blacklistLength * 20 } - } else if (flag === SESSIONS_FLAG_IDENTITY_SIGNER) { - // Identity signer - const nodeLength = 21 // Flag + address - if (bytes.length < nodeLength) { - throw new Error('Invalid identity signer length') - } - return { - topology: { type: 'identity-signer', identitySigner: Address.from(Hex.fromBytes(bytes.slice(1, nodeLength))) }, - pointer: nodeLength, - } - } else { - throw new Error(`Invalid topology flag: ${flag}`) - } -} - // JSON export function sessionsTopologyToJson(topology: SessionsTopology): string { @@ -500,39 +416,28 @@ function sessionsTopologyFromParsed(parsed: any): SessionsTopology { // Operations -function removeLeaf(topology: SessionsTopology, leaf: SessionLeaf | SessionNode): SessionsTopology | null { - if (isSessionsLeaf(topology) && isSessionsLeaf(leaf)) { - if (topology.type === leaf.type) { - if (isSessionPermissions(topology) && isSessionPermissions(leaf)) { - if (Address.isEqual(topology.signer, leaf.signer)) { - return null - } - } else if (isImplicitBlacklist(topology) && isImplicitBlacklist(leaf)) { - // Remove blacklist items in leaf from topology - const newBlacklist = topology.blacklist.filter((b) => !leaf.blacklist.includes(b)) - if (newBlacklist.length === 0) { - return null - } - return { type: 'implicit-blacklist', blacklist: newBlacklist } - } else if (isIdentitySignerLeaf(topology) && isIdentitySignerLeaf(leaf)) { - // Remove identity signer from topology - if (Address.isEqual(topology.identitySigner, leaf.identitySigner)) { - return null - } - } - } - } else if (isSessionsNode(topology) && isSessionsNode(leaf)) { - if (Hex.isEqual(topology, leaf)) { - // Match, remove the node +/** + * Removes all explicit sessions (permissions leaf nodes) that match the given signer from the topology. + * Returns the updated topology or null if it becomes empty (for nesting). + * If the signer is not found, the topology is returned unchanged. + */ +export function removeExplicitSession( + topology: SessionsTopology, + signerAddress: `0x${string}`, +): SessionsTopology | null { + if (isSessionPermissions(topology)) { + if (Address.isEqual(topology.signer, signerAddress)) { return null } + // Return the leaf unchanged + return topology } // If it's a branch, recurse on each child: if (isSessionsBranch(topology)) { const newChildren: SessionsTopology[] = [] for (const child of topology) { - const updatedChild = removeLeaf(child, leaf) + const updatedChild = removeExplicitSession(child, signerAddress) if (updatedChild != null) { newChildren.push(updatedChild) } @@ -556,29 +461,6 @@ function removeLeaf(topology: SessionsTopology, leaf: SessionLeaf | SessionNode) return topology } -/** - * Removes all explicit sessions (permissions leaf nodes) that match the given signer from the topology. - * Returns the updated topology or null if it becomes empty (for nesting). - * If the signer is not found, the topology is returned unchanged. - */ -export function removeExplicitSession( - topology: SessionsTopology, - signerAddress: `0x${string}`, -): SessionsTopology | null { - const explicitLeaf = getSessionPermissions(topology, signerAddress) - if (!explicitLeaf) { - // Not found, return unchanged - return topology - } - const removed = removeLeaf(topology, explicitLeaf) - if (!removed) { - // Empty, return null - return null - } - // Balance it - return balanceSessionsTopology(removed) -} - export function addExplicitSession( topology: SessionsTopology, sessionPermissions: SessionPermissions, @@ -592,33 +474,6 @@ export function addExplicitSession( return balanceSessionsTopology(merged) } -export function removeIdentitySigner( - topology: SessionsTopology, - identitySigner: Address.Address, -): SessionsTopology | null { - const identityLeaf: IdentitySignerLeaf = { - type: 'identity-signer', - identitySigner, - } - // Remove the old identity signer and balance - const removed = removeLeaf(topology, identityLeaf) - if (!removed) { - // Empty, return null - return null - } - return balanceSessionsTopology(removed) -} - -export function addIdentitySigner(topology: SessionsTopology, identitySigner: Address.Address): SessionsTopology { - // Find the session in the topology - if (getIdentitySigners(topology).some((s) => Address.isEqual(s, identitySigner))) { - throw new Error('Identity signer already exists') - } - // Merge and balance - const merged = mergeSessionsTopologies(topology, { type: 'identity-signer', identitySigner }) - return balanceSessionsTopology(merged) -} - /** * Merges two topologies into a new branch of [a, b]. */ @@ -666,9 +521,17 @@ function buildBalancedSessionsTopology(items: (SessionLeaf | SessionNode)[]): Se /** * Balances the topology by flattening and rebuilding as a balanced binary tree. + * This does not make a binary tree as the blacklist and identity signer are included at the top level. */ export function balanceSessionsTopology(topology: SessionsTopology): SessionsTopology { - return buildBalancedSessionsTopology(flattenSessionsTopology(topology)) + const flattened = flattenSessionsTopology(topology) + const blacklist = flattened.find((l) => isImplicitBlacklist(l)) + const identitySigner = flattened.find((l) => isIdentitySignerLeaf(l)) + const leaves = flattened.filter((l) => isSessionPermissions(l)) + if (!blacklist || !identitySigner) { + throw new Error('No blacklist or identity signer') + } + return buildBalancedSessionsTopology([blacklist, identitySigner, ...leaves]) } /** @@ -733,10 +596,9 @@ export function minimiseSessionsTopology( topology: SessionsTopology, explicitSigners: Address.Address[] = [], implicitSigners: Address.Address[] = [], - identitySigner?: Address.Address, ): SessionsTopology { if (isSessionsBranch(topology)) { - const branches = topology.map((b) => minimiseSessionsTopology(b, explicitSigners, implicitSigners, identitySigner)) + const branches = topology.map((b) => minimiseSessionsTopology(b, explicitSigners, implicitSigners)) // If all branches are nodes, the branch can be a node too if (branches.every((b) => isSessionsNode(b))) { return Hash.keccak256(Bytes.concat(...branches.map((b) => Hex.toBytes(b))), { as: 'Hex' }) @@ -759,11 +621,7 @@ export function minimiseSessionsTopology( return topology } if (isIdentitySignerLeaf(topology)) { - if (identitySigner && !Address.isEqual(topology.identitySigner, identitySigner)) { - // Not the identity signer we're looking for, so roll it up - return GenericTree.hash(encodeLeafToGeneric(topology)) - } - // Return this identity signer leaf + // Never roll up the identity signer return topology } if (isSessionsNode(topology)) { @@ -809,18 +667,15 @@ export function removeFromImplicitBlacklist(topology: SessionsTopology, address: /** * Generate an empty sessions topology with the given identity signer. No session permission and an empty blacklist */ -export function emptySessionsTopology( - identitySigner: Address.Address | [Address.Address, ...Address.Address[]], -): SessionsTopology { - if (!Array.isArray(identitySigner)) { - return emptySessionsTopology([identitySigner]) - } - const flattenedTopology: SessionLeaf[] = [ +export function emptySessionsTopology(identitySigner: Address.Address): SessionsTopology { + return [ { type: 'implicit-blacklist', blacklist: [], }, - ...identitySigner.map((signer): IdentitySignerLeaf => ({ type: 'identity-signer', identitySigner: signer })), + { + type: 'identity-signer', + identitySigner, + }, ] - return buildBalancedSessionsTopology(flattenedTopology) } diff --git a/packages/wallet/primitives/src/session-signature.ts b/packages/wallet/primitives/src/session-signature.ts index c3f67ca241..8b9306d7fc 100644 --- a/packages/wallet/primitives/src/session-signature.ts +++ b/packages/wallet/primitives/src/session-signature.ts @@ -1,19 +1,18 @@ import { Address, Bytes, Hash, Hex } from 'ox' -import { Attestation, Extensions, Payload } from './index.js' +import { Attestation, encode, encodeForJson, fromParsed, toJson } from './attestation.js' import { MAX_PERMISSIONS_COUNT } from './permission.js' import { - decodeSessionsTopology, encodeSessionsTopology, - getIdentitySigners, isCompleteSessionsTopology, minimiseSessionsTopology, SessionsTopology, } from './session-config.js' import { RSY } from './signature.js' -import { minBytesFor, packRSY, unpackRSY } from './utils.js' +import { minBytesFor, packRSY } from './utils.js' +import { Payload } from './index.js' export type ImplicitSessionCallSignature = { - attestation: Attestation.Attestation + attestation: Attestation identitySignature: RSY sessionSignature: RSY } @@ -46,7 +45,7 @@ export function sessionCallSignatureToJson(callSignature: SessionCallSignature): export function encodeSessionCallSignatureForJson(callSignature: SessionCallSignature): any { if (isImplicitSessionCallSignature(callSignature)) { return { - attestation: Attestation.encodeForJson(callSignature.attestation), + attestation: encodeForJson(callSignature.attestation), identitySignature: rsyToRsvStr(callSignature.identitySignature), sessionSignature: rsyToRsvStr(callSignature.sessionSignature), } @@ -68,7 +67,7 @@ export function sessionCallSignatureFromJson(json: string): SessionCallSignature export function sessionCallSignatureFromParsed(decoded: any): SessionCallSignature { if (decoded.attestation) { return { - attestation: Attestation.fromParsed(decoded.attestation), + attestation: fromParsed(decoded.attestation), identitySignature: rsyFromRsvStr(decoded.identitySignature), sessionSignature: rsyFromRsvStr(decoded.sessionSignature), } @@ -104,19 +103,9 @@ function rsyFromRsvStr(sigStr: string): RSY { // Usage -/** - * Encodes a list of session call signatures into a bytes array for contract validation. - * @param callSignatures The list of session call signatures to encode. - * @param topology The complete session topology. - * @param explicitSigners The list of explicit signers to encode. Others will be hashed into nodes. - * @param implicitSigners The list of implicit signers to encode. Others will be hashed into nodes. - * @param identitySigner The identity signer to encode. Others will be hashed into nodes. - * @returns The encoded session call signatures. - */ -export function encodeSessionSignature( +export function encodeSessionCallSignatures( callSignatures: SessionCallSignature[], topology: SessionsTopology, - identitySigner: Address.Address, explicitSigners: Address.Address[] = [], implicitSigners: Address.Address[] = [], ): Bytes.Bytes { @@ -128,14 +117,8 @@ export function encodeSessionSignature( throw new Error('Incomplete topology') } - // Check the topology contains the identity signer - const identitySigners = getIdentitySigners(topology) - if (!identitySigners.some((s) => Address.isEqual(s, identitySigner))) { - throw new Error('Identity signer not found') - } - // Optimise the configuration tree by rolling unused signers into nodes. - topology = minimiseSessionsTopology(topology, explicitSigners, implicitSigners, identitySigner) + topology = minimiseSessionsTopology(topology, explicitSigners, implicitSigners) // Session topology const encodedTopology = encodeSessionsTopology(topology) @@ -151,12 +134,10 @@ export function encodeSessionSignature( // Map each call signature to its attestation index callSignatures.filter(isImplicitSessionCallSignature).forEach((callSig) => { if (callSig.attestation) { - const attestationStr = Attestation.toJson(callSig.attestation) + const attestationStr = toJson(callSig.attestation) if (!attestationMap.has(attestationStr)) { attestationMap.set(attestationStr, encodedAttestations.length) - encodedAttestations.push( - Bytes.concat(Attestation.encode(callSig.attestation), packRSY(callSig.identitySignature)), - ) + encodedAttestations.push(Bytes.concat(encode(callSig.attestation), packRSY(callSig.identitySignature))) } } }) @@ -171,7 +152,7 @@ export function encodeSessionSignature( for (const callSignature of callSignatures) { if (isImplicitSessionCallSignature(callSignature)) { // Implicit - const attestationStr = Attestation.toJson(callSignature.attestation) + const attestationStr = toJson(callSignature.attestation) const attestationIndex = attestationMap.get(attestationStr) if (attestationIndex === undefined) { // Unreachable @@ -195,126 +176,24 @@ export function encodeSessionSignature( return Bytes.concat(...parts) } -export function decodeSessionSignature(encodedSignatures: Bytes.Bytes): { - topology: SessionsTopology - callSignatures: SessionCallSignature[] -} { - let offset = 0 - - // Parse session topology length (3 bytes) - const topologyLength = Bytes.toNumber(encodedSignatures.slice(offset, offset + 3)) - offset += 3 - - // Parse session topology - const topologyBytes = encodedSignatures.slice(offset, offset + topologyLength) - offset += topologyLength - const topology = decodeSessionsTopology(topologyBytes) - - // Parse attestations count (1 byte) - const attestationsCount = Bytes.toNumber(encodedSignatures.slice(offset, offset + 1)) - offset += 1 - - // Parse attestations and identity signatures - const attestations: Attestation.Attestation[] = [] - const identitySignatures: RSY[] = [] - - for (let i = 0; i < attestationsCount; i++) { - // Parse attestation - const attestation = Attestation.decode(encodedSignatures.slice(offset)) - offset += Attestation.encode(attestation).length - attestations.push(attestation) +// Helper - // Parse identity signature (64 bytes) - const identitySignature = unpackRSY(encodedSignatures.slice(offset, offset + 64)) - offset += 64 - identitySignatures.push(identitySignature) - } - - // Parse call signatures - const callSignatures: SessionCallSignature[] = [] - - while (offset < encodedSignatures.length) { - // Parse flag byte - const flagByte = encodedSignatures[offset]! - offset += 1 - - // Parse session signature (64 bytes) - const sessionSignature = unpackRSY(encodedSignatures.slice(offset, offset + 64)) - offset += 64 - - // Check if implicit (MSB set) or explicit - if ((flagByte & 0x80) !== 0) { - // Implicit call signature - const attestationIndex = flagByte & 0x7f - if (attestationIndex >= attestations.length) { - throw new Error('Invalid attestation index') - } - - callSignatures.push({ - attestation: attestations[attestationIndex]!, - identitySignature: identitySignatures[attestationIndex]!, - sessionSignature, - }) - } else { - // Explicit call signature - const permissionIndex = flagByte - callSignatures.push({ - permissionIndex: BigInt(permissionIndex), - sessionSignature, - }) - } - } - - return { - topology, - callSignatures, - } -} - -// Call encoding - -/** - * Hashes a call with replay protection parameters. - * @param payload The payload to hash. - * @param callIdx The index of the call to hash. - * @param chainId The chain ID. Use 0 when noChainId enabled. - * @param sessionManagerAddress The session manager address to compile the hash for. Only required to support deprecated hash encodings for Dev1, Dev2 and Rc3. - * @returns The hash of the call with replay protection parameters for sessions. - */ -export function hashPayloadWithCallIdx( - wallet: Address.Address, - payload: Payload.Calls & Payload.Parent, +export function hashCallWithReplayProtection( + payload: Payload.Calls, callIdx: number, chainId: number, - sessionManagerAddress?: Address.Address, + skipCallIdx: boolean = false, // Deprecated. Dev1 and Dev2 support ): Hex.Hex { - // Support deprecated hashes for Dev1, Dev2 and Rc3 - const deprecatedHashing = - sessionManagerAddress && - (Address.isEqual(sessionManagerAddress, Extensions.Dev1.sessions) || - Address.isEqual(sessionManagerAddress, Extensions.Dev2.sessions) || - Address.isEqual(sessionManagerAddress, Extensions.Rc3.sessions)) - if (deprecatedHashing) { - const call = payload.calls[callIdx]! - const ignoreCallIdx = !Address.isEqual(sessionManagerAddress, Extensions.Rc3.sessions) - return Hex.fromBytes( - Hash.keccak256( - Bytes.concat( - Bytes.fromNumber(chainId, { size: 32 }), - Bytes.fromNumber(payload.space, { size: 32 }), - Bytes.fromNumber(payload.nonce, { size: 32 }), - ignoreCallIdx ? Bytes.from([]) : Bytes.fromNumber(callIdx, { size: 32 }), - Bytes.fromHex(Payload.hashCall(call)), - ), + const call = payload.calls[callIdx]! + return Hex.fromBytes( + Hash.keccak256( + Bytes.concat( + Bytes.fromNumber(chainId, { size: 32 }), + Bytes.fromNumber(payload.space, { size: 32 }), + Bytes.fromNumber(payload.nonce, { size: 32 }), + skipCallIdx ? Bytes.from([]) : Bytes.fromNumber(callIdx, { size: 32 }), + Bytes.fromHex(Payload.hashCall(call)), ), - ) - } - // Current hashing scheme uses entire payload hash and call index (without last parent) - const parentWallets = payload.parentWallets - if (payload.parentWallets && payload.parentWallets.length > 0) { - payload.parentWallets.pop() - } - const payloadHash = Payload.hash(wallet, chainId, payload) - payload.parentWallets = parentWallets - return Hex.fromBytes(Hash.keccak256(Bytes.concat(payloadHash, Bytes.fromNumber(callIdx, { size: 32 })))) + ), + ) } diff --git a/packages/wallet/primitives/test/config.test.ts b/packages/wallet/primitives/test/config.test.ts index b4ff8e6d91..ffa7a653c4 100644 --- a/packages/wallet/primitives/test/config.test.ts +++ b/packages/wallet/primitives/test/config.test.ts @@ -33,13 +33,11 @@ import { maximumDepth, evaluateConfigurationSafety, normalizeSignerSignature, - replaceAddress, } from '../src/config.js' describe('Config', () => { const testAddress1 = '0x742d35cc6635c0532925a3b8d563a6b35b7f05f1' const testAddress2 = '0x8ba1f109551bd432803012645aac136c776056c0' - const replacementAddress = '0x1111111111111111111111111111111111111111' const testImageHash = '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef' const testDigest = '0xabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef' @@ -318,67 +316,6 @@ describe('Config', () => { }) }) - describe('replaceAddress', () => { - it('should replace signer leaf addresses', () => { - const signerLeaf: SignerLeaf = { ...sampleSignerLeaf } - - const result = replaceAddress(signerLeaf, testAddress1, replacementAddress) - - expect(result).toEqual({ ...sampleSignerLeaf, address: replacementAddress }) - expect(result).not.toBe(signerLeaf) - expect(signerLeaf.address).toBe(testAddress1) - }) - - it('should replace sapient signer leaf addresses', () => { - const sapientLeaf: SapientSignerLeaf = { ...sampleSapientSignerLeaf } - - const result = replaceAddress(sapientLeaf, testAddress2, replacementAddress) - - expect(result).toEqual({ ...sampleSapientSignerLeaf, address: replacementAddress }) - expect(result).not.toBe(sapientLeaf) - expect(sapientLeaf.address).toBe(testAddress2) - }) - - it('should recurse through nodes and nested leaves', () => { - const nestedSapient: SapientSignerLeaf = { ...sampleSapientSignerLeaf, address: testAddress1 } - const nestedLeaf: NestedLeaf = { - type: 'nested', - tree: [nestedSapient, sampleSubdigestLeaf], - weight: 5n, - threshold: 1n, - } - const topology: Topology = [{ ...sampleSignerLeaf }, nestedLeaf] - - const result = replaceAddress(topology, testAddress1, replacementAddress) - - expect(result).toEqual([ - { ...sampleSignerLeaf, address: replacementAddress }, - { - ...nestedLeaf, - tree: [{ ...nestedSapient, address: replacementAddress }, sampleSubdigestLeaf], - }, - ]) - expect(nestedSapient.address).toBe(testAddress1) - expect((nestedLeaf.tree as Node)[1]).toBe(sampleSubdigestLeaf) - }) - - it('should return the original topology when no address matches', () => { - const sapientLeaf: SapientSignerLeaf = { ...sampleSapientSignerLeaf } - - const result = replaceAddress(sapientLeaf, replacementAddress, testAddress1) - - expect(result).toBe(sapientLeaf) - }) - - it('should leave non-signer leaves unchanged', () => { - expect(replaceAddress(sampleSubdigestLeaf, testAddress1, replacementAddress)).toBe(sampleSubdigestLeaf) - expect(replaceAddress(sampleAnyAddressSubdigestLeaf, testAddress1, replacementAddress)).toBe( - sampleAnyAddressSubdigestLeaf, - ) - expect(replaceAddress(sampleNodeLeaf, testAddress1, replacementAddress)).toBe(sampleNodeLeaf) - }) - }) - describe('getWeight', () => { it('should return correct weight for signer leaf with canSign true', () => { const result = getWeight(sampleSignerLeaf, () => true) diff --git a/packages/wallet/primitives/test/erc-6492.test.ts b/packages/wallet/primitives/test/erc-6492.test.ts index 7398f58db9..dcb7688ee0 100644 --- a/packages/wallet/primitives/test/erc-6492.test.ts +++ b/packages/wallet/primitives/test/erc-6492.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it, vi } from 'vitest' import { Address, Bytes, Hex, Provider } from 'ox' -import { SignatureErc6492 } from 'ox/erc6492' +import { WrappedSignature } from 'ox/erc6492' import { deploy, wrap, decode, isValid } from '../src/erc-6492.js' import { Context } from '../src/context.js' @@ -82,7 +82,7 @@ describe('ERC-6492', () => { expect(result.startsWith('0x')).toBe(true) // Should end with the magic bytes - expect(result.endsWith(SignatureErc6492.magicBytes.slice(2))).toBe(true) + expect(result.endsWith(WrappedSignature.magicBytes.slice(2))).toBe(true) // Should contain the original signature data somewhere expect(result.length).toBeGreaterThan(testSignature.length) @@ -96,7 +96,7 @@ describe('ERC-6492', () => { // Convert to hex to check magic bytes const resultHex = Bytes.toHex(result) - expect(resultHex.endsWith(SignatureErc6492.magicBytes.slice(2))).toBe(true) + expect(resultHex.endsWith(WrappedSignature.magicBytes.slice(2))).toBe(true) }) it('should return same type as input signature', () => { @@ -133,7 +133,7 @@ describe('ERC-6492', () => { // The wrapped signature should contain encoded: address, bytes (data), bytes (signature) expect(result.length).toBeGreaterThan(testSignature.length + deployData.data.length) expect(result).toContain(testAddress.slice(2)) // Address without 0x - expect(result.endsWith(SignatureErc6492.magicBytes.slice(2))).toBe(true) + expect(result.endsWith(WrappedSignature.magicBytes.slice(2))).toBe(true) }) }) @@ -209,7 +209,7 @@ describe('ERC-6492', () => { it('should handle malformed wrapped signature gracefully', () => { // Create a signature that ends with magic bytes but has invalid encoding - const malformedSig = ('0x1234' + SignatureErc6492.magicBytes.slice(2)) as Hex.Hex + const malformedSig = ('0x1234' + WrappedSignature.magicBytes.slice(2)) as Hex.Hex const result = decode(malformedSig) // Should return original signature when decoding fails @@ -391,7 +391,7 @@ describe('ERC-6492', () => { // 2. Wrap signature with deploy data const wrappedSig = wrap(testSignature, deployCall) - expect(wrappedSig.endsWith(SignatureErc6492.magicBytes.slice(2))).toBe(true) + expect(wrappedSig.endsWith(WrappedSignature.magicBytes.slice(2))).toBe(true) // 3. Decode wrapped signature const decoded = decode(wrappedSig) @@ -457,7 +457,7 @@ describe('ERC-6492', () => { it('should handle signatures that accidentally contain magic bytes', () => { // Create a signature that contains the magic bytes but isn't wrapped - const magicInSignature = (testSignature + SignatureErc6492.magicBytes.slice(2) + '1234') as Hex.Hex + const magicInSignature = (testSignature + WrappedSignature.magicBytes.slice(2) + '1234') as Hex.Hex const result = decode(magicInSignature) // Should try to decode, but if it fails, should return original diff --git a/packages/wallet/primitives/test/session-config.test.ts b/packages/wallet/primitives/test/session-config.test.ts index 6e20d55974..7d092c15c0 100644 --- a/packages/wallet/primitives/test/session-config.test.ts +++ b/packages/wallet/primitives/test/session-config.test.ts @@ -1,60 +1,60 @@ -import { Address, Bytes } from 'ox' import { describe, expect, it } from 'vitest' +import { Address, Bytes, Hex } from 'ox' -import { ChainId } from '../src/network.js' -import { ParameterOperation, Permission, SessionPermissions } from '../src/permission.js' import { - IdentitySignerLeaf, - ImplicitBlacklistLeaf, - SESSIONS_FLAG_BLACKLIST, + SESSIONS_FLAG_PERMISSIONS, + SESSIONS_FLAG_NODE, SESSIONS_FLAG_BRANCH, + SESSIONS_FLAG_BLACKLIST, SESSIONS_FLAG_IDENTITY_SIGNER, - SESSIONS_FLAG_NODE, - SESSIONS_FLAG_PERMISSIONS, - SessionBranch, - SessionNode, + ImplicitBlacklistLeaf, + IdentitySignerLeaf, SessionPermissionsLeaf, + SessionNode, + SessionLeaf, + SessionBranch, SessionsTopology, - addExplicitSession, - addToImplicitBlacklist, - balanceSessionsTopology, - cleanSessionsTopology, - configurationTreeToSessionsTopology, - decodeLeafFromBytes, - decodeSessionsTopology, - emptySessionsTopology, - encodeLeafToGeneric, - encodeSessionsTopology, - getExplicitSigners, - getIdentitySigners, + isSessionsTopology, + isCompleteSessionsTopology, + getIdentitySigner, getImplicitBlacklist, getImplicitBlacklistLeaf, getSessionPermissions, - isCompleteSessionsTopology, - isSessionsTopology, + getExplicitSigners, + encodeLeafToGeneric, + decodeLeafFromBytes, + sessionsTopologyToConfigurationTree, + configurationTreeToSessionsTopology, + encodeSessionsTopology, + sessionsTopologyToJson, + sessionsTopologyFromJson, + removeExplicitSession, + addExplicitSession, mergeSessionsTopologies, + balanceSessionsTopology, + cleanSessionsTopology, minimiseSessionsTopology, - removeExplicitSession, + addToImplicitBlacklist, removeFromImplicitBlacklist, - sessionsTopologyFromJson, - sessionsTopologyToConfigurationTree, - sessionsTopologyToJson, + emptySessionsTopology, } from '../src/session-config.js' +import { SessionPermissions } from '../src/permission.js' +import { ChainId } from '../src/network.js' describe('Session Config', () => { // Test data - const testAddress1: Address.Address = '0x742d35cc6635c0532925a3b8d563a6b35b7f05f1' - const testAddress2: Address.Address = '0x8ba1f109551bd432803012645aac136c776056c0' - const testAddress3: Address.Address = '0xa0b86a33e6f8b5f56e64c9e1a1b8c6a9cc4b9a9e' - const testNode: SessionNode = '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef' + const testAddress1 = '0x742d35cc6635c0532925a3b8d563a6b35b7f05f1' as Address.Address + const testAddress2 = '0x8ba1f109551bd432803012645aac136c776056c0' as Address.Address + const testAddress3 = '0xa0b86a33e6f8b5f56e64c9e1a1b8c6a9cc4b9a9e' as Address.Address + const testNode = '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef' as SessionNode - const samplePermission: Permission = { + const samplePermission = { target: testAddress3, rules: [ { cumulative: false, - operation: ParameterOperation.EQUAL, - value: Bytes.fromHex('0x0000000000000000000000000000000000000000000000000000000000000000'), + operation: 0, // EQUAL + value: Bytes.fromHex('0x'), offset: 0n, mask: Bytes.fromHex('0xffffffff00000000000000000000000000000000000000000000000000000000'), }, @@ -152,9 +152,9 @@ describe('Session Config', () => { expect(isCompleteSessionsTopology(duplicateBlacklist)).toBe(false) }) - it('should return true for topology with multiple identity signers', () => { + it('should return false for topology with multiple identity signers', () => { const duplicateIdentity = [sampleBlacklistLeaf, sampleIdentitySignerLeaf, sampleIdentitySignerLeaf] - expect(isCompleteSessionsTopology(duplicateIdentity)).toBe(true) + expect(isCompleteSessionsTopology(duplicateIdentity)).toBe(false) }) it('should return false for invalid topology', () => { @@ -165,29 +165,29 @@ describe('Session Config', () => { }) describe('Topology Queries', () => { - describe('getIdentitySigners', () => { + describe('getIdentitySigner', () => { it('should return identity signer from identity signer leaf', () => { - const result = getIdentitySigners(sampleIdentitySignerLeaf) - expect(result).toEqual([testAddress1]) + const result = getIdentitySigner(sampleIdentitySignerLeaf) + expect(result).toBe(testAddress1) }) it('should return identity signer from branch', () => { - const result = getIdentitySigners(sampleCompleteTopology) - expect(result).toEqual([testAddress1]) + const result = getIdentitySigner(sampleCompleteTopology) + expect(result).toBe(testAddress1) }) - it('should return empty array when no identity signer present', () => { - const result = getIdentitySigners(sampleSessionPermissionsLeaf) - expect(result).toEqual([]) + it('should return null when no identity signer present', () => { + const result = getIdentitySigner(sampleSessionPermissionsLeaf) + expect(result).toBe(null) }) - it('should return multiple identity signers', () => { + it('should throw for multiple identity signers', () => { const multipleIdentity = [ sampleIdentitySignerLeaf, sampleIdentitySignerLeaf, sampleBlacklistLeaf, ] as SessionBranch - expect(getIdentitySigners(multipleIdentity)).toEqual([testAddress1, testAddress1]) + expect(() => getIdentitySigner(multipleIdentity)).toThrow('Multiple identity signers') }) }) @@ -400,14 +400,12 @@ describe('Session Config', () => { }) }) - describe('Sessions Topology Encoding and Decoding', () => { + describe('Sessions Topology Encoding', () => { describe('encodeSessionsTopology', () => { it('should encode session permissions leaf', () => { const result = encodeSessionsTopology(sampleSessionPermissionsLeaf) expect(result).toBeInstanceOf(Uint8Array) expect(result[0] >> 4).toBe(SESSIONS_FLAG_PERMISSIONS) - const decoded = decodeSessionsTopology(result) - expect(decoded).toEqual(sampleSessionPermissionsLeaf) }) it('should encode session node', () => { @@ -415,34 +413,12 @@ describe('Session Config', () => { expect(result).toBeInstanceOf(Uint8Array) expect(result[0] >> 4).toBe(SESSIONS_FLAG_NODE) expect(result.length).toBe(33) // 1 flag byte + 32 hash bytes - const decoded = decodeSessionsTopology(result) - expect(decoded).toEqual(testNode) }) it('should encode blacklist leaf', () => { const result = encodeSessionsTopology(sampleBlacklistLeaf) expect(result).toBeInstanceOf(Uint8Array) expect(result[0] >> 4).toBe(SESSIONS_FLAG_BLACKLIST) - const decoded = decodeSessionsTopology(result) - expect(decoded).toEqual(sampleBlacklistLeaf) - }) - - it('should encode large blacklist leaf', () => { - const blacklistCount = 1000 - const largeBlacklist: ImplicitBlacklistLeaf = { - type: 'implicit-blacklist', - blacklist: Array(blacklistCount).fill(testAddress1), - } - const result = encodeSessionsTopology(largeBlacklist) - expect(result).toBeInstanceOf(Uint8Array) - expect(result[0]).toBe((SESSIONS_FLAG_BLACKLIST << 4) | 0x0f) // Encoded large size flag - expect(Bytes.toNumber(result.slice(1, 3))).toBe(blacklistCount) - expect(result.slice(3)).toEqual( - Bytes.concat(...largeBlacklist.blacklist.map((b) => Bytes.padLeft(Bytes.fromHex(b), 20))), - ) - expect(result.length).toBe(3 + blacklistCount * 20) - const decoded = decodeSessionsTopology(result) - expect(decoded).toEqual(largeBlacklist) }) it('should encode identity signer leaf', () => { @@ -450,16 +426,12 @@ describe('Session Config', () => { expect(result).toBeInstanceOf(Uint8Array) expect(result[0] >> 4).toBe(SESSIONS_FLAG_IDENTITY_SIGNER) expect(result.length).toBe(21) // 1 flag byte + 20 address bytes - const decoded = decodeSessionsTopology(result) - expect(decoded).toEqual(sampleIdentitySignerLeaf) }) it('should encode session branch', () => { const result = encodeSessionsTopology(sampleBranch) expect(result).toBeInstanceOf(Uint8Array) expect(result[0] >> 4).toBe(SESSIONS_FLAG_BRANCH) - const decoded = decodeSessionsTopology(result) - expect(decoded).toEqual(sampleBranch) }) it('should handle large blacklist with extended encoding', () => { @@ -470,15 +442,6 @@ describe('Session Config', () => { const result = encodeSessionsTopology(largeBlacklist) expect(result).toBeInstanceOf(Uint8Array) expect(result[0] & 0x0f).toBe(0x0f) // Extended encoding flag - const decoded = decodeSessionsTopology(result) - expect(decoded).toEqual(largeBlacklist) - }) - - it('should handle complete topology', () => { - const result = encodeSessionsTopology(sampleCompleteTopology) - expect(result).toBeInstanceOf(Uint8Array) - const decoded = decodeSessionsTopology(result) - expect(decoded).toEqual(sampleCompleteTopology) }) it('should throw for blacklist too large', () => { @@ -656,9 +619,13 @@ describe('Session Config', () => { expect(isSessionsTopology(result)).toBe(true) const blacklist = getImplicitBlacklist(result) - const identitySigners = getIdentitySigners(result) + const identitySigner = getIdentitySigner(result) expect(blacklist).toBeTruthy() - expect(identitySigners).toBeTruthy() + expect(identitySigner).toBeTruthy() + }) + + it('should throw when missing blacklist or identity signer', () => { + expect(() => balanceSessionsTopology(sampleSessionPermissionsLeaf)).toThrow('No blacklist or identity signer') }) }) @@ -763,137 +730,6 @@ describe('Session Config', () => { it('should throw for invalid topology', () => { expect(() => minimiseSessionsTopology({} as any, [], [])).toThrow('Invalid topology') }) - - it('should minimize topology with multiple identity signers but keep only the specified one', () => { - // Create multiple identity signer leaves - const identitySigner1: IdentitySignerLeaf = { - type: 'identity-signer', - identitySigner: testAddress1, - } - const identitySigner2: IdentitySignerLeaf = { - type: 'identity-signer', - identitySigner: testAddress2, - } - const identitySigner3: IdentitySignerLeaf = { - type: 'identity-signer', - identitySigner: testAddress3, - } - - // Create topology with multiple identity signers - const topologyWithMultipleIdentitySigners: SessionBranch = [ - sampleBlacklistLeaf, - identitySigner1, - identitySigner2, - identitySigner3, - sampleSessionPermissionsLeaf, - ] - - // Minimize with only testAddress2 as the identity signer - const result = minimiseSessionsTopology( - topologyWithMultipleIdentitySigners, - [], // no explicit signers - [], // no implicit signers - testAddress2, // only keep this identity signer - ) - - expect(isSessionsTopology(result)).toBe(true) - - // Get all identity signers from the result - const identitySigners = getIdentitySigners(result) - - // Should only contain the specified identity signer - expect(identitySigners).toEqual([testAddress2]) - expect(identitySigners).not.toContain(testAddress1) - expect(identitySigners).not.toContain(testAddress3) - - // Verify the result is still a valid topology - expect(isSessionsTopology(result)).toBe(true) - }) - - it('should minimize deeply nested topology with multiple identity signers but keep only the specified one', () => { - // Create multiple identity signer leaves - const identitySigner1: IdentitySignerLeaf = { - type: 'identity-signer', - identitySigner: testAddress1, - } - const identitySigner2: IdentitySignerLeaf = { - type: 'identity-signer', - identitySigner: testAddress2, - } - const identitySigner3: IdentitySignerLeaf = { - type: 'identity-signer', - identitySigner: testAddress3, - } - - // Create additional session permissions for nesting - const sessionPermissions2: SessionPermissionsLeaf = { - type: 'session-permissions', - signer: testAddress2, - chainId: ChainId.MAINNET, - valueLimit: 500000000000000000n, - deadline: BigInt(Math.floor(Date.now() / 1000) + 1800), - permissions: [samplePermission], - } - - const sessionPermissions3: SessionPermissionsLeaf = { - type: 'session-permissions', - signer: testAddress3, - chainId: ChainId.MAINNET, - valueLimit: 750000000000000000n, - deadline: BigInt(Math.floor(Date.now() / 1000) + 2700), - permissions: [samplePermission], - } - - // Create a deeply nested topology structure - // Level 1: Main branch - // Level 2: Nested branches containing different combinations - const deeplyNestedTopology: SessionBranch = [ - // First nested branch: blacklist + identity signer 1 - [ - sampleBlacklistLeaf, - identitySigner1, - sampleSessionPermissionsLeaf, // testAddress1 session - ], - // Second nested branch: identity signer 2 + session permissions 2 - [ - identitySigner2, - sessionPermissions2, // testAddress2 session - ], - // Third nested branch: identity signer 3 + session permissions 3 - [ - identitySigner3, - sessionPermissions3, // testAddress3 session - ], - ] - - // Minimize with only testAddress2 as the identity signer - const result = minimiseSessionsTopology( - deeplyNestedTopology, - [], // no explicit signers - [], // no implicit signers - testAddress2, // only keep this identity signer - ) - - expect(isSessionsTopology(result)).toBe(true) - - // Get all identity signers from the result - const identitySigners = getIdentitySigners(result) - - // Should only contain the specified identity signer - expect(identitySigners).toEqual([testAddress2]) - expect(identitySigners).not.toContain(testAddress1) - expect(identitySigners).not.toContain(testAddress3) - - // Verify the result is still a valid topology - expect(isSessionsTopology(result)).toBe(true) - - // Verify that the nested structure is properly minimized - // The result should be a branch with hashed nodes and the preserved identity signer - if (Array.isArray(result)) { - // Should have some components (hashed nodes and the preserved identity signer) - expect(result.length).toBeGreaterThan(0) - } - }) }) describe('addToImplicitBlacklist', () => { @@ -960,23 +796,8 @@ describe('Session Config', () => { expect(isCompleteSessionsTopology(result)).toBe(true) - const identitySigners = getIdentitySigners(result) - expect(identitySigners).toEqual([testAddress1]) - - const blacklist = getImplicitBlacklist(result) - expect(blacklist).toEqual([]) - - const explicitSigners = getExplicitSigners(result) - expect(explicitSigners).toEqual([]) - }) - - it('should create empty topology with multiple identity signers', () => { - const result = emptySessionsTopology([testAddress1, testAddress2]) - - expect(isCompleteSessionsTopology(result)).toBe(true) - - const identitySigners = getIdentitySigners(result) - expect(identitySigners).toEqual([testAddress1, testAddress2]) + const identitySigner = getIdentitySigner(result) + expect(identitySigner).toBe(testAddress1) const blacklist = getImplicitBlacklist(result) expect(blacklist).toEqual([]) @@ -1016,8 +837,8 @@ describe('Session Config', () => { expect(isSessionsTopology(nestedTopology)).toBe(true) expect(isCompleteSessionsTopology(nestedTopology)).toBe(true) - const identitySigners = getIdentitySigners(nestedTopology) - expect(identitySigners).toEqual([testAddress1]) + const identitySigner = getIdentitySigner(nestedTopology) + expect(identitySigner).toBe(testAddress1) const blacklist = getImplicitBlacklist(nestedTopology) expect(blacklist).toContain(testAddress2) @@ -1081,7 +902,7 @@ describe('Session Config', () => { expect(isCompleteSessionsTopology(deserialized)).toBe(true) // Verify data integrity - expect(getIdentitySigners(deserialized)).toEqual([testAddress1]) + expect(getIdentitySigner(deserialized)).toBe(testAddress1) expect(getImplicitBlacklist(deserialized)).toContain(testAddress3) expect(getSessionPermissions(deserialized, testAddress2)).toBeTruthy() }) diff --git a/packages/wallet/primitives/test/session-signature.test.ts b/packages/wallet/primitives/test/session-signature.test.ts index a1fd0fe233..887ca6b047 100644 --- a/packages/wallet/primitives/test/session-signature.test.ts +++ b/packages/wallet/primitives/test/session-signature.test.ts @@ -1,32 +1,29 @@ -import { Address, Bytes, Hex } from 'ox' import { describe, expect, it } from 'vitest' +import { Address, Bytes, Hash, Hex } from 'ox' -import { Attestation } from '../src/attestation.js' -import { ChainId } from '../src/network.js' -import * as Payload from '../src/payload.js' -import { ParameterOperation } from '../src/permission.js' -import { minimiseSessionsTopology, SessionsTopology } from '../src/session-config.js' import { - decodeSessionSignature, - encodeSessionCallSignatureForJson, - encodeSessionSignature, - ExplicitSessionCallSignature, - hashPayloadWithCallIdx, ImplicitSessionCallSignature, - isExplicitSessionCallSignature, - isImplicitSessionCallSignature, + ExplicitSessionCallSignature, SessionCallSignature, + isImplicitSessionCallSignature, + isExplicitSessionCallSignature, + sessionCallSignatureToJson, + encodeSessionCallSignatureForJson, sessionCallSignatureFromJson, sessionCallSignatureFromParsed, - sessionCallSignatureToJson, + encodeSessionCallSignatures, + hashCallWithReplayProtection, } from '../src/session-signature.js' import { RSY } from '../src/signature.js' -import { Extensions } from '../src/index.js' +import { Attestation } from '../src/attestation.js' +import { SessionsTopology } from '../src/session-config.js' +import * as Payload from '../src/payload.js' +import { ChainId } from '../src/network.js' describe('Session Signature', () => { // Test data - const testAddress1: Address.Address = '0x742d35cc6635c0532925a3b8d563a6b35b7f05f1' - const testAddress2: Address.Address = '0x8ba1f109551bd432803012645aac136c776056c0' + const testAddress1 = '0x742d35cc6635c0532925a3b8d563a6b35b7f05f1' as Address.Address + const testAddress2 = '0x8ba1f109551bd432803012645aac136c776056c0' as Address.Address const testChainId = ChainId.MAINNET const testSpace = 0n const testNonce = 1n @@ -105,7 +102,7 @@ describe('Session Signature', () => { rules: [ { cumulative: false, - operation: ParameterOperation.EQUAL, + operation: 0, value: Bytes.fromHex('0x'), offset: 0n, mask: Bytes.fromHex('0xffffffff00000000000000000000000000000000000000000000000000000000'), @@ -279,50 +276,31 @@ describe('Session Signature', () => { }) }) - describe('Signature Encoding and Decoding', () => { - describe('encode / decodeSessionCallSignatures', () => { + describe('Signature Encoding', () => { + describe('encodeSessionCallSignatures', () => { it('should encode single explicit session call signature', () => { const callSignatures = [sampleExplicitSignature] - const result = encodeSessionSignature(callSignatures, completeTopology, testAddress1) + const result = encodeSessionCallSignatures(callSignatures, completeTopology) expect(result).toBeInstanceOf(Uint8Array) expect(result.length).toBeGreaterThan(0) - - const decoded = decodeSessionSignature(result) - expect(decoded.callSignatures.length).toBe(1) - const callSignature = decoded.callSignatures[0]! - if (!isExplicitSessionCallSignature(callSignature)) { - throw new Error('Call signature is not explicit') - } - expect(callSignature.permissionIndex).toBe(callSignatures[0]!.permissionIndex) - // The topology gets minimized during encoding, so we expect the minimized version - const minimizedTopology = minimiseSessionsTopology(completeTopology, [], [], testAddress1) - expect(decoded.topology).toEqual(minimizedTopology) }) // Skip implicit signature tests that cause encoding issues it.skip('should encode single implicit session call signature', () => { const callSignatures = [sampleImplicitSignature] - const result = encodeSessionSignature(callSignatures, completeTopology, testAddress1) + const result = encodeSessionCallSignatures(callSignatures, completeTopology) expect(result).toBeInstanceOf(Uint8Array) expect(result.length).toBeGreaterThan(0) - - const decoded = decodeSessionSignature(result) - expect(decoded.callSignatures).toEqual(callSignatures) - expect(decoded.topology).toEqual(completeTopology) }) it.skip('should encode multiple mixed session call signatures', () => { const callSignatures = [sampleImplicitSignature, sampleExplicitSignature] - const result = encodeSessionSignature(callSignatures, completeTopology, testAddress1) + const result = encodeSessionCallSignatures(callSignatures, completeTopology) expect(result).toBeInstanceOf(Uint8Array) expect(result.length).toBeGreaterThan(0) - - const decoded = decodeSessionSignature(result) - expect(decoded.callSignatures).toEqual(callSignatures) - expect(decoded.topology).toEqual(completeTopology) }) it.skip('should encode multiple implicit signatures with same attestation', () => { @@ -333,15 +311,10 @@ describe('Session Signature', () => { sessionSignature: sampleRSY2, // Different session signature }, ] - const result = encodeSessionSignature(callSignatures, completeTopology, testAddress1) + const result = encodeSessionCallSignatures(callSignatures, completeTopology) expect(result).toBeInstanceOf(Uint8Array) expect(result.length).toBeGreaterThan(0) - - const decoded = decodeSessionSignature(result) - expect(decoded.callSignatures).toEqual(callSignatures) - const minimizedTopology = minimiseSessionsTopology(completeTopology, [], [], testAddress1) - expect(decoded.topology).toEqual(minimizedTopology) }) it('should throw for incomplete topology', () => { @@ -362,8 +335,8 @@ describe('Session Signature', () => { rules: [ { cumulative: false, - operation: ParameterOperation.EQUAL, - value: Bytes.fromHex('0x0000000000000000000000000000000000000000000000000000000000000000'), + operation: 0, + value: Bytes.fromHex('0x'), offset: 0n, mask: Bytes.fromHex('0xffffffff00000000000000000000000000000000000000000000000000000000'), }, @@ -374,7 +347,7 @@ describe('Session Signature', () => { // Missing identity signer, but has 2 elements for valid SessionBranch ] - expect(() => encodeSessionSignature([sampleExplicitSignature], incompleteTopology, testAddress1)).toThrow( + expect(() => encodeSessionCallSignatures([sampleExplicitSignature], incompleteTopology)).toThrow( 'Incomplete topology', ) }) @@ -385,85 +358,68 @@ describe('Session Signature', () => { sessionSignature: sampleRSY, } - expect(() => encodeSessionSignature([largeIndexSignature], completeTopology, testAddress1)).toThrow( + expect(() => encodeSessionCallSignatures([largeIndexSignature], completeTopology)).toThrow( 'Permission index is too large', ) }) + it('should throw for too many attestations (simplified)', () => { + // Just test that we can create many explicit signatures instead + const callSignatures: ExplicitSessionCallSignature[] = Array(10) + .fill(null) + .map((_, i) => ({ + permissionIndex: BigInt(i), + sessionSignature: sampleRSY, + })) + + const result = encodeSessionCallSignatures(callSignatures, completeTopology) + expect(result).toBeInstanceOf(Uint8Array) + }) + it('should handle explicit signers parameter', () => { const callSignatures = [sampleExplicitSignature] - const result = encodeSessionSignature(callSignatures, completeTopology, testAddress1) + const result = encodeSessionCallSignatures(callSignatures, completeTopology, [testAddress1]) expect(result).toBeInstanceOf(Uint8Array) expect(result.length).toBeGreaterThan(0) - - const decoded = decodeSessionSignature(result) - expect(decoded.callSignatures.length).toBe(1) - const callSignature = decoded.callSignatures[0]! - if (!isExplicitSessionCallSignature(callSignature)) { - throw new Error('Call signature is not explicit') - } - expect(callSignature.permissionIndex).toBe(callSignatures[0]!.permissionIndex) - // The topology gets minimized during encoding, so we expect the minimized version - const minimizedTopology = minimiseSessionsTopology(completeTopology, [], [], testAddress1) - expect(decoded.topology).toEqual(minimizedTopology) }) it('should handle implicit signers parameter', () => { const callSignatures = [sampleExplicitSignature] - const result = encodeSessionSignature(callSignatures, completeTopology, testAddress1, [], [testAddress2]) + const result = encodeSessionCallSignatures(callSignatures, completeTopology, [], [testAddress2]) expect(result).toBeInstanceOf(Uint8Array) expect(result.length).toBeGreaterThan(0) - - const decoded = decodeSessionSignature(result) - expect(decoded.callSignatures.length).toBe(1) - const callSignature = decoded.callSignatures[0]! - if (!isExplicitSessionCallSignature(callSignature)) { - throw new Error('Call signature is not explicit') - } - expect(callSignature.permissionIndex).toBe(callSignatures[0]!.permissionIndex) - // The topology gets minimized during encoding, so we expect the minimized version - const minimizedTopology = minimiseSessionsTopology(completeTopology, [], [testAddress2], testAddress1) - expect(decoded.topology).toEqual(minimizedTopology) }) it('should throw for invalid call signature type', () => { const invalidSignature = {} as any - expect(() => encodeSessionSignature([invalidSignature], completeTopology, testAddress1)).toThrow( + expect(() => encodeSessionCallSignatures([invalidSignature], completeTopology)).toThrow( 'Invalid call signature', ) }) - - it('should throw for identity signer not found', () => { - const callSignatures = [sampleExplicitSignature] - expect(() => - encodeSessionSignature(callSignatures, completeTopology, testAddress2, [], [testAddress2]), - ).toThrow('Identity signer not found') - }) }) }) describe('Helper Functions', () => { - describe('hashPayloadWithCallIdx', () => { + describe('hashCallWithReplayProtection', () => { it('should hash call with replay protection parameters', () => { - const result = hashPayloadWithCallIdx(testAddress1, samplePayload, 0, testChainId) + const result = hashCallWithReplayProtection(samplePayload, 0, testChainId) expect(result).toMatch(/^0x[0-9a-f]{64}$/) // 32-byte hex string expect(Hex.size(result)).toBe(32) }) it('should produce different hashes for different chain IDs', () => { - const hash1 = hashPayloadWithCallIdx(testAddress1, samplePayload, 0, ChainId.MAINNET) - const hash2 = hashPayloadWithCallIdx(testAddress1, samplePayload, 0, ChainId.POLYGON) + const hash1 = hashCallWithReplayProtection(samplePayload, 0, ChainId.MAINNET) + const hash2 = hashCallWithReplayProtection(samplePayload, 0, ChainId.POLYGON) expect(hash1).not.toBe(hash2) }) it('should produce different hashes for different spaces', () => { - const hash1 = hashPayloadWithCallIdx(testAddress1, samplePayload, 0, testChainId) - const hash2 = hashPayloadWithCallIdx( - testAddress1, + const hash1 = hashCallWithReplayProtection(samplePayload, 0, testChainId) + const hash2 = hashCallWithReplayProtection( { ...samplePayload, space: samplePayload.space + 1n }, 0, testChainId, @@ -473,9 +429,8 @@ describe('Session Signature', () => { }) it('should produce different hashes for different nonces', () => { - const hash1 = hashPayloadWithCallIdx(testAddress1, samplePayload, 0, testChainId) - const hash2 = hashPayloadWithCallIdx( - testAddress1, + const hash1 = hashCallWithReplayProtection(samplePayload, 0, testChainId) + const hash2 = hashCallWithReplayProtection( { ...samplePayload, nonce: samplePayload.nonce + 1n }, 0, testChainId, @@ -491,51 +446,17 @@ describe('Session Signature', () => { } const payload2 = { ...samplePayload, calls: [call2] } - const hash1 = hashPayloadWithCallIdx(testAddress1, samplePayload, 0, testChainId) - const hash2 = hashPayloadWithCallIdx(testAddress1, payload2, 0, testChainId) - - expect(hash1).not.toBe(hash2) - }) - - it('should produce different hashes for different wallets', () => { - const payload = { ...samplePayload, calls: [sampleCall, sampleCall] } - - const hash1 = hashPayloadWithCallIdx(testAddress1, payload, 0, testChainId) - const hash2 = hashPayloadWithCallIdx(testAddress2, payload, 0, testChainId) - - expect(hash1).not.toBe(hash2) - }) - - it('should NOT produce different hashes for different wallets when using deprecated hash encoding for Dev1 and Dev2', () => { - // This is ONLY for backward compatibility with Dev1 and Dev2 - // This is exploitable and should not be used in practice - const payload = { ...samplePayload, calls: [sampleCall, sampleCall] } - - const hash1 = hashPayloadWithCallIdx(testAddress1, payload, 0, testChainId, Extensions.Dev1.sessions) - const hash2 = hashPayloadWithCallIdx(testAddress2, payload, 0, testChainId, Extensions.Dev2.sessions) - - expect(hash1).toBe(hash2) - }) - - it('should produce different hashes for different wallets when using deprecated hash encoding for Dev1/2, Rc3 and latest', () => { - // This is ONLY for backward compatibility with Rc3 - // This is exploitable and should not be used in practice - const payload = { ...samplePayload, calls: [sampleCall, sampleCall] } - - const hash1 = hashPayloadWithCallIdx(testAddress1, payload, 0, testChainId, Extensions.Dev1.sessions) - const hash2 = hashPayloadWithCallIdx(testAddress2, payload, 0, testChainId, Extensions.Rc3.sessions) - const hash3 = hashPayloadWithCallIdx(testAddress2, payload, 0, testChainId) + const hash1 = hashCallWithReplayProtection(samplePayload, 0, testChainId) + const hash2 = hashCallWithReplayProtection(payload2, 0, testChainId) expect(hash1).not.toBe(hash2) - expect(hash1).not.toBe(hash3) - expect(hash2).not.toBe(hash3) }) it('should produce different hashes for same call at different index', () => { const payload = { ...samplePayload, calls: [sampleCall, sampleCall] } - const hash1 = hashPayloadWithCallIdx(testAddress1, payload, 0, testChainId) - const hash2 = hashPayloadWithCallIdx(testAddress1, payload, 1, testChainId) + const hash1 = hashCallWithReplayProtection(payload, 0, testChainId) + const hash2 = hashCallWithReplayProtection(payload, 1, testChainId) expect(hash1).not.toBe(hash2) }) @@ -545,15 +466,15 @@ describe('Session Signature', () => { // This is exploitable and should not be used in practice const payload = { ...samplePayload, calls: [sampleCall, sampleCall] } - const hash1 = hashPayloadWithCallIdx(testAddress1, payload, 0, testChainId, Extensions.Dev1.sessions) - const hash2 = hashPayloadWithCallIdx(testAddress1, payload, 1, testChainId, Extensions.Dev1.sessions) + const hash1 = hashCallWithReplayProtection(payload, 0, testChainId, true) + const hash2 = hashCallWithReplayProtection(payload, 1, testChainId, true) expect(hash1).toBe(hash2) }) it('should be deterministic', () => { - const hash1 = hashPayloadWithCallIdx(testAddress1, samplePayload, 0, testChainId) - const hash2 = hashPayloadWithCallIdx(testAddress1, samplePayload, 0, testChainId) + const hash1 = hashCallWithReplayProtection(samplePayload, 0, testChainId) + const hash2 = hashCallWithReplayProtection(samplePayload, 0, testChainId) expect(hash1).toBe(hash2) }) @@ -563,8 +484,7 @@ describe('Session Signature', () => { const largeSpace = 2n ** 16n const largeNonce = 2n ** 24n - const result = hashPayloadWithCallIdx( - testAddress1, + const result = hashCallWithReplayProtection( { ...samplePayload, space: largeSpace, nonce: largeNonce }, 0, largeChainId, @@ -573,7 +493,7 @@ describe('Session Signature', () => { }) it('should handle zero values', () => { - const result = hashPayloadWithCallIdx(testAddress1, { ...samplePayload, space: 0n, nonce: 0n }, 0, 0) + const result = hashCallWithReplayProtection({ ...samplePayload, space: 0n, nonce: 0n }, 0, 0) expect(result).toMatch(/^0x[0-9a-f]{64}$/) }) @@ -584,7 +504,7 @@ describe('Session Signature', () => { } const payload = { ...samplePayload, calls: [callWithEmptyData] } - const result = hashPayloadWithCallIdx(testAddress1, payload, 0, testChainId) + const result = hashCallWithReplayProtection(payload, 0, testChainId) expect(result).toMatch(/^0x[0-9a-f]{64}$/) }) @@ -595,8 +515,8 @@ describe('Session Signature', () => { } const payload = { ...samplePayload, calls: [delegateCall] } - const hash1 = hashPayloadWithCallIdx(testAddress1, samplePayload, 0, testChainId) - const hash2 = hashPayloadWithCallIdx(testAddress1, payload, 0, testChainId) + const hash1 = hashCallWithReplayProtection(samplePayload, 0, testChainId) + const hash2 = hashCallWithReplayProtection(payload, 0, testChainId) expect(hash1).not.toBe(hash2) }) @@ -605,7 +525,7 @@ describe('Session Signature', () => { describe('Edge Cases and Error Handling', () => { it('should handle empty call signatures array', () => { - const result = encodeSessionSignature([], completeTopology, testAddress1) + const result = encodeSessionCallSignatures([], completeTopology) expect(result).toBeInstanceOf(Uint8Array) expect(result.length).toBeGreaterThan(0) // Should still contain topology }) @@ -616,7 +536,7 @@ describe('Session Signature', () => { sessionSignature: sampleRSY, } - const result = encodeSessionSignature([maxIndexSignature], completeTopology, testAddress1) + const result = encodeSessionCallSignatures([maxIndexSignature], completeTopology) expect(result).toBeInstanceOf(Uint8Array) }) @@ -626,7 +546,7 @@ describe('Session Signature', () => { sessionSignature: sampleRSY, } - const result = encodeSessionSignature([zeroIndexSignature], completeTopology, testAddress1) + const result = encodeSessionCallSignatures([zeroIndexSignature], completeTopology) expect(result).toBeInstanceOf(Uint8Array) }) @@ -659,9 +579,9 @@ describe('Session Signature', () => { it.skip('should handle attestation with minimal data', () => { const minimalAttestation: Attestation = { approvedSigner: testAddress1, - identityType: Bytes.fromHex('0x00000000'), - issuerHash: Bytes.fromHex('0x0000000000000000000000000000000000000000000000000000000000000000'), - audienceHash: Bytes.fromHex('0x0000000000000000000000000000000000000000000000000000000000000000'), + identityType: Bytes.fromHex('0x00'), + issuerHash: Bytes.fromHex(('0x' + '00'.repeat(32)) as Hex.Hex), + audienceHash: Bytes.fromHex(('0x' + '00'.repeat(32)) as Hex.Hex), applicationData: Bytes.fromArray([]), authData: { redirectUrl: '', @@ -675,7 +595,7 @@ describe('Session Signature', () => { sessionSignature: sampleRSY2, } - const result = encodeSessionSignature([minimalImplicitSignature], completeTopology, testAddress1) + const result = encodeSessionCallSignatures([minimalImplicitSignature], completeTopology) expect(result).toBeInstanceOf(Uint8Array) }) @@ -704,8 +624,8 @@ describe('Session Signature', () => { rules: [ { cumulative: false, - operation: ParameterOperation.EQUAL, - value: Bytes.fromHex('0x0000000000000000000000000000000000000000000000000000000000000000'), + operation: 0, + value: Bytes.fromHex('0x'), offset: 0n, mask: Bytes.fromHex('0xffffffff00000000000000000000000000000000000000000000000000000000'), }, @@ -719,7 +639,7 @@ describe('Session Signature', () => { // This test may not actually trigger the error since creating a 3-byte overflow is complex // We'll test that the function works with a large but valid topology - const result = encodeSessionSignature(callSignatures, largeTopology, testAddress1) + const result = encodeSessionCallSignatures(callSignatures, largeTopology) expect(result).toBeInstanceOf(Uint8Array) }) @@ -742,7 +662,7 @@ describe('Session Signature', () => { const callSignatures: ExplicitSessionCallSignature[] = [invalidExplicitSignature] expect(() => { - encodeSessionSignature(callSignatures, completeTopology, testAddress1) + encodeSessionCallSignatures(callSignatures, completeTopology) }).toThrow() // Should throw due to permission index validation }) }) @@ -758,7 +678,7 @@ describe('Session Signature', () => { ] // Encode - const encoded = encodeSessionSignature(callSignatures, completeTopology, testAddress1) + const encoded = encodeSessionCallSignatures(callSignatures, completeTopology, [testAddress1]) expect(encoded).toBeInstanceOf(Uint8Array) // Test encoding for each signature @@ -773,15 +693,12 @@ describe('Session Signature', () => { const calls: Payload.Call[] = [ sampleCall, { ...sampleCall, to: testAddress2 }, - { ...sampleCall, to: testAddress2 }, // Repeat call { ...sampleCall, value: 500000000000000000n }, ] const payload = { ...samplePayload, calls: calls } // Generate hashes for each call - const hashes = calls.map((call) => - hashPayloadWithCallIdx(testAddress1, payload, calls.indexOf(call), testChainId), - ) + const hashes = calls.map((call) => hashCallWithReplayProtection(payload, calls.indexOf(call), testChainId)) // All hashes should be valid and different for (let i = 0; i < hashes.length; i++) { @@ -809,7 +726,7 @@ describe('Session Signature', () => { }, ] - const result = encodeSessionSignature(callSignatures, completeTopology, testAddress1) + const result = encodeSessionCallSignatures(callSignatures, completeTopology) expect(result).toBeInstanceOf(Uint8Array) expect(result.length).toBeGreaterThan(0) }) diff --git a/packages/wallet/src/index.ts b/packages/wallet/src/index.ts new file mode 100644 index 0000000000..e40a936c00 --- /dev/null +++ b/packages/wallet/src/index.ts @@ -0,0 +1,5 @@ +export * from './signer' +export * from './utils' +export * from './wallet' + +export * from './orchestrator/wrapper' diff --git a/packages/wallet/src/orchestrator/wrapper.ts b/packages/wallet/src/orchestrator/wrapper.ts new file mode 100644 index 0000000000..04b3061220 --- /dev/null +++ b/packages/wallet/src/orchestrator/wrapper.ts @@ -0,0 +1,46 @@ +import { commons } from '@0xsequence/core' +import { signers, Status } from '@0xsequence/signhub' +import { ethers } from 'ethers' +import { Wallet } from '../wallet' + +// Implements a wrapper for using Sequence wallets as nested signers +// in the signhub orchestrator. It only works for nested signatures. +export class SequenceOrchestratorWrapper implements signers.SapientSigner { + constructor(public wallet: Wallet) {} + + async getAddress(): Promise { + return this.wallet.address + } + + async buildDeployTransaction(metadata: object): Promise { + return this.wallet.buildDeployTransaction(metadata as commons.WalletDeployMetadata | undefined) + } + + async predecorateSignedTransactions(_metadata: object): Promise { + // Wallets do not predecorate as they have no off chain knowledge + return [] + } + + async decorateTransactions( + bundle: commons.transaction.IntendedTransactionBundle, + _metadata: object + ): Promise { + return this.wallet.decorateTransactions(bundle) + } + + sign(message: ethers.utils.BytesLike, metadata: object): Promise { + if (!commons.isWalletSignRequestMetadata(metadata)) { + throw new Error('SequenceOrchestratorWrapper only supports nested Sequence signatures') + } + + // For Sequence nested signatures we must use `signDigest` and not `signMessage` + // otherwise the wallet will hash the digest and the signature will be invalid. + return this.wallet.signDigest(message, { nested: metadata }) + } + + notifyStatusChange(_i: string, _s: Status, _m: object): void {} + + suffix(): ethers.utils.BytesLike { + return [3] + } +} diff --git a/packages/wallet/src/signer.ts b/packages/wallet/src/signer.ts new file mode 100644 index 0000000000..5d8ef9b0be --- /dev/null +++ b/packages/wallet/src/signer.ts @@ -0,0 +1,96 @@ +import { BytesLike, Signer as AbstractSigner, providers, TypedDataDomain, TypedDataField, ethers } from 'ethers' +import { NetworkConfig, ChainIdLike } from '@0xsequence/network' +import { FeeQuote, Relayer } from '@0xsequence/relayer' +import { Deferrable } from '@0xsequence/utils' +import { commons } from '@0xsequence/core' + +// TODO: Move to account ? +export abstract class Signer extends AbstractSigner { + static isSequenceSigner(cand: any): cand is Signer { + return isSequenceSigner(cand) + } + + abstract getProvider(chainId?: number): Promise + abstract getRelayer(chainId?: number): Promise + + // abstract getWalletContext(): Promise + abstract getWalletConfig(chainId?: ChainIdLike): Promise + // abstract getWalletState(chainId?: ChainIdLike): Promise + + abstract getNetworks(): Promise + + // getSigners returns a list of available / attached signers to the interface. Note: you need + // enough signers in order to meet the signing threshold that satisfies a wallet config. + abstract getSigners(): Promise + + // signMessage ..... + abstract signMessage(message: BytesLike, chainId?: ChainIdLike, allSigners?: boolean, isDigest?: boolean): Promise + + // signTypedData .. + abstract signTypedData( + domain: TypedDataDomain, + types: Record>, + message: Record, + chainId: ChainIdLike, + allSigners?: boolean + ): Promise + + // sendTransaction takes an unsigned transaction, or list of unsigned transactions, and then has it signed by + // the signer, and finally sends it to the relayer for submission to an Ethereum network. + abstract sendTransaction( + transaction: Deferrable, + chainId?: ChainIdLike, + allSigners?: boolean, + quote?: FeeQuote + ): Promise + + // sendTransactionBatch provides the ability to send an array/batch of transactions as a single native on-chain transaction. + // This method works identically to sendTransaction but offers a different syntax for convience, readability and type clarity. + abstract sendTransactionBatch( + transactions: Deferrable, + chainId?: ChainIdLike, + allSigners?: boolean, + quote?: FeeQuote + ): Promise + + // Low-level methods to sign and send/relayer signed transactions separately. The combination of these methods + // is like calling just sendTransaction(..) above. Also note that sendSignedTransactions is identical + // to calling getRelayer().relay(signedTxs), but included in this interface for convenience. + abstract signTransactions( + txs: Deferrable, + chainId?: ChainIdLike, + allSigners?: boolean + ): Promise + abstract sendSignedTransactions( + signedTxs: commons.transaction.SignedTransactionBundle, + chainId?: ChainIdLike, + quote?: FeeQuote + ): Promise + + // updateConfig will update the wallet image hash on-chain, aka deploying a smart wallet config to chain. If + // newConfig argument is undefined, then it will use the existing config. Config contents will also be + // automatically published to the authChain when updating the config image hash. + abstract updateConfig( + newConfig?: commons.config.Config + ): Promise<[commons.config.Config, commons.transaction.TransactionResponse | undefined]> + + // publishConfig will store the raw WalletConfig object on-chain, note: this may be expensive, + // and is only necessary for config data-availability, in case of Account the contents are published + // to the authChain. + abstract publishConfig(): Promise + + // isDeployed .. + abstract isDeployed(chainId?: ChainIdLike): Promise +} + +export type SignedTransactionsCallback = (signedTxs: commons.transaction.SignedTransactionBundle, metaTxnHash: string) => void + +export function isSequenceSigner(signer: AbstractSigner): signer is Signer { + const cand = signer as Signer + return cand && cand.updateConfig !== undefined && cand.publishConfig !== undefined && cand.getWalletConfig !== undefined +} + +// TODO: move to error.ts, along with others.. +export class InvalidSigner extends Error {} + +export class NotEnoughSigners extends Error {} diff --git a/packages/wallet/src/utils.ts b/packages/wallet/src/utils.ts new file mode 100644 index 0000000000..52a855ed1a --- /dev/null +++ b/packages/wallet/src/utils.ts @@ -0,0 +1,31 @@ +import { ethers, utils } from 'ethers' + +export async function resolveArrayProperties( + object: Readonly> | Readonly>[] +): Promise { + if (Array.isArray(object)) { + // T must include array type + return Promise.all(object.map(o => utils.resolveProperties(o))) as any + } + + return utils.resolveProperties(object) +} + +export async function findLatestLog( + provider: ethers.providers.Provider, + filter: ethers.providers.Filter +): Promise { + const toBlock = filter.toBlock === 'latest' ? await provider.getBlockNumber() : (filter.toBlock as number) + const fromBlock = filter.fromBlock as number + + try { + const logs = await provider.getLogs({ ...filter, toBlock: toBlock }) + return logs.length === 0 ? undefined : logs[logs.length - 1] + } catch (e) { + // TODO Don't assume all errors are bad + const pivot = Math.floor((toBlock - fromBlock) / 2 + fromBlock) + const nhalf = await findLatestLog(provider, { ...filter, fromBlock: pivot, toBlock: toBlock }) + if (nhalf !== undefined) return nhalf + return findLatestLog(provider, { ...filter, fromBlock: fromBlock, toBlock: pivot }) + } +} diff --git a/packages/wallet/src/wallet.ts b/packages/wallet/src/wallet.ts new file mode 100644 index 0000000000..57c7c33bd2 --- /dev/null +++ b/packages/wallet/src/wallet.ts @@ -0,0 +1,438 @@ +import { ethers } from 'ethers' +import { commons, v1, v2 } from '@0xsequence/core' +import { SignatureOrchestrator, SignerState, Status } from '@0xsequence/signhub' +import { Deferrable, subDigestOf } from '@0xsequence/utils' +import { FeeQuote, Relayer } from '@0xsequence/relayer' +import { walletContracts } from '@0xsequence/abi' + +import { resolveArrayProperties } from './utils' + +export type WalletOptions< + T extends commons.signature.Signature, + Y extends commons.config.Config, + Z extends commons.signature.UnrecoveredSignature +> = { + // Sequence version configurator + coders: { + config: commons.config.ConfigCoder + signature: commons.signature.SignatureCoder + } + + context: commons.context.WalletContext + config: Y + + chainId: ethers.BigNumberish + address: string + + orchestrator: SignatureOrchestrator + reader?: commons.reader.Reader + + provider?: ethers.providers.Provider + relayer?: Relayer +} + +const statusToSignatureParts = (status: Status) => { + const parts = new Map() + + for (const signer of Object.keys(status.signers)) { + const value = status.signers[signer] + if (value.state === SignerState.SIGNED) { + const suffix = ethers.utils.arrayify(value.suffix) + const suffixed = ethers.utils.solidityPack(['bytes', 'bytes'], [value.signature, suffix]) + + parts.set(signer, { signature: suffixed, isDynamic: suffix.length !== 1 || suffix[0] !== 2 }) + } + } + + return parts +} + +export type WalletV2 = Wallet +export type WalletV1 = Wallet + +/** + * The wallet is the minimum interface to interact with a single Sequence wallet/contract. + * it doesn't have any knowledge of any on-chain state, instead it relies solely on the information + * provided by the user. This building block is used to create higher level abstractions. + * + * Wallet can also be used to create Sequence wallets, but it's not recommended to use it directly. + */ +export class Wallet< + Y extends commons.config.Config = commons.config.Config, + T extends commons.signature.Signature = commons.signature.Signature, + Z extends commons.signature.UnrecoveredSignature = commons.signature.UnrecoveredSignature +> extends ethers.Signer { + public context: commons.context.WalletContext + public config: Y + public address: string + public chainId: ethers.BigNumberish + + public provider?: ethers.providers.Provider + public relayer?: Relayer + + public coders: { + signature: commons.signature.SignatureCoder + config: commons.config.ConfigCoder + } + + private orchestrator: SignatureOrchestrator + private _reader?: commons.reader.Reader + + constructor(options: WalletOptions) { + if (ethers.constants.Zero.eq(options.chainId) && !options.coders.signature.supportsNoChainId) { + throw new Error(`Sequence version ${options.config.version} doesn't support chainId 0`) + } + + super() + + this.context = options.context + this.config = options.config + this.orchestrator = options.orchestrator + this.coders = options.coders + this.address = options.address + this.chainId = options.chainId + this.provider = options.provider + this.relayer = options.relayer + + this._reader = options.reader + } + + static newWallet< + Y extends commons.config.Config = commons.config.Config, + T extends commons.signature.Signature = commons.signature.Signature, + Z extends commons.signature.UnrecoveredSignature = commons.signature.UnrecoveredSignature + >(options: Omit, 'address'>): Wallet { + const address = commons.context.addressOf(options.context, options.coders.config.imageHashOf(options.config)) + return new Wallet({ ...options, address }) + } + + reader(): commons.reader.Reader { + if (this._reader) return this._reader + if (!this.provider) throw new Error('Wallet status provider requires a provider') + return new commons.reader.OnChainReader(this.provider) + } + + setConfig(config: Y) { + this.config = config + } + + setOrchestrator(orchestrator: SignatureOrchestrator) { + this.orchestrator = orchestrator + } + + setAddress(address: string) { + this.address = address + } + + getSigners(): Promise { + return this.orchestrator.getSigners() + } + + async getAddress(): Promise { + return this.address + } + + async decorateTransactions( + bundle: commons.transaction.IntendedTransactionBundle + ): Promise { + // Allow children to decorate + const decorated = await this.orchestrator.decorateTransactions(bundle) + + if (await this.reader().isDeployed(this.address)) { + // Deployed - No decorating at this level + return decorated + } + + const transactions: commons.transaction.Transaction[] = [ + { + to: decorated.entrypoint, + data: commons.transaction.encodeBundleExecData(decorated), + revertOnError: true + } + ] + + // Add deployment tx + const deployTx = await this.buildDeployTransaction() + if (deployTx) { + transactions.unshift(...deployTx.transactions) + } + + // TODO: If entrypoint is guestModule we can flatten the bundle + // and avoid calling guestModule twice + + return { + entrypoint: this.context.guestModule, + chainId: this.chainId, + intent: decorated.intent, + transactions + } + } + + async buildDeployTransaction( + metadata?: commons.WalletDeployMetadata + ): Promise { + if (metadata?.ignoreDeployed && (await this.reader().isDeployed(this.address))) { + return + } + + const imageHash = this.coders.config.imageHashOf(this.config) + + if (commons.context.addressOf(this.context, imageHash) !== this.address) { + throw new Error(`First address of config ${imageHash} doesn't match wallet address ${this.address}`) + } + + const bundle = Wallet.buildDeployTransaction(this.context, imageHash) + if (metadata?.includeChildren) { + const childBundle = await this.orchestrator.buildDeployTransaction(metadata) + if (childBundle) { + // Deploy children first + bundle.transactions = childBundle.transactions.concat(bundle.transactions) + } + } + return bundle + } + + async deploy(metadata?: commons.WalletDeployMetadata): Promise { + const deployTx = await this.buildDeployTransaction(metadata) + if (deployTx === undefined) { + // Already deployed + return + } + if (!this.relayer) throw new Error('Wallet deploy requires a relayer') + return this.relayer.relay({ + ...deployTx, + chainId: this.chainId, + intent: { + id: ethers.utils.hexlify(ethers.utils.randomBytes(32)), + wallet: this.address + } + }) + } + + static buildDeployTransaction( + context: commons.context.WalletContext, + imageHash: string + ): commons.transaction.TransactionBundle { + const factoryInterface = new ethers.utils.Interface(walletContracts.factory.abi) + + return { + entrypoint: context.guestModule, + transactions: [ + { + to: context.factory, + data: factoryInterface.encodeFunctionData(factoryInterface.getFunction('deploy'), [context.mainModule, imageHash]), + gasLimit: 100000, + delegateCall: false, + revertOnError: true, + value: 0 + } + ] + } + } + + async buildUpdateConfigurationTransaction(config: Y): Promise { + if (this.coders.config.update.isKindUsed) { + const implementation = await this.reader().implementation(this.address) + const isLaterUpdate = implementation && implementation === this.context.mainModuleUpgradable + return this.coders.config.update.buildTransaction(this.address, config, this.context, isLaterUpdate ? 'later' : 'first') + } + + return this.coders.config.update.buildTransaction(this.address, config, this.context) + } + + async getNonce(space: ethers.BigNumberish = 0): Promise { + const nonce = await this.reader().nonce(this.address, space) + if (nonce === undefined) throw new Error('Unable to determine nonce') + return nonce + } + + async signDigest(digest: ethers.utils.BytesLike, metadata?: object): Promise { + // The subdigest may be statically defined on the configuration + // in that case we just encode the proof, no need to sign anything + const subdigest = subDigestOf(this.address, this.chainId, digest) + if (this.coders.config.hasSubdigest(this.config, subdigest)) { + return this.coders.signature.encodeSigners(this.config, new Map(), [subdigest], this.chainId).encoded + } + + // We build the metadata object, this contains additional information + // that may be needed to sign the digest (by the other signers, or by the guard) + const childMetadata: commons.WalletSignRequestMetadata = { + ...metadata, // Keep other metadata fields + digest, + chainId: this.chainId, + address: this.address, + config: this.config + } + + // We ask the orchestrator to sign the digest, as soon as we have enough signature parts + // to reach the threshold we returns true, that means the orchestrator will stop asking + // and we can encode the final signature + const subdigestBytes = ethers.utils.arrayify(subdigest) + const signature = await this.orchestrator.signMessage({ + candidates: this.coders.config.signersOf(this.config).map(s => s.address), + message: subdigestBytes, + metadata: childMetadata, + callback: (status: Status, onNewMetadata: (_metadata: object) => void): boolean => { + const parts = statusToSignatureParts(status) + + const newMetadata = { ...childMetadata, parts } + onNewMetadata(newMetadata) + + return this.coders.signature.hasEnoughSigningPower(this.config, parts) + } + }) + + const parts = statusToSignatureParts(signature) + return this.coders.signature.encodeSigners(this.config, parts, [], this.chainId).encoded + } + + signMessage(message: ethers.BytesLike): Promise { + return this.signDigest(ethers.utils.keccak256(message), { message }) + } + + signTransactionBundle(bundle: commons.transaction.TransactionBundle): Promise { + if (bundle.entrypoint !== this.address) { + throw new Error(`Invalid entrypoint: ${bundle.entrypoint} !== ${this.address}`) + } + + return this.signTransactions(bundle.transactions, bundle.nonce) + } + + async fetchNonceOrSpace( + nonce?: ethers.BigNumberish | { space: ethers.BigNumberish } | { serial: boolean } + ): Promise { + let spaceValue + + if (nonce && (nonce as any).space !== undefined) { + // specified nonce "space" + spaceValue = ethers.BigNumber.from((nonce as any).space) + } else if (nonce === undefined) { + // default is random, aka parallel + return this.randomNonce() + } else if (nonce && (nonce as any).serial === true) { + // next nonce determined from the chain + spaceValue = 0 + } else { + // specific nonce is used + return nonce as ethers.BigNumberish + } + + const resultNonce = await this.reader().nonce(this.address, spaceValue) + if (resultNonce === undefined) throw new Error('Unable to determine nonce') + return commons.transaction.encodeNonce(spaceValue, resultNonce) + } + + // Generate nonce with random space + randomNonce(): ethers.BigNumberish { + const randomNonceSpace = ethers.BigNumber.from(ethers.utils.hexlify(ethers.utils.randomBytes(12))) + const randomNonce = commons.transaction.encodeNonce(randomNonceSpace, 0) + return randomNonce + } + + async signTransactions( + txs: Deferrable, + nonce?: ethers.BigNumberish | { space: ethers.BigNumberish } | { serial: boolean }, + metadata?: object + ): Promise { + const transaction = await resolveArrayProperties(txs) + const transactions = commons.transaction.fromTransactionish(this.address, transaction) + + // NOTICE: If the `transactions` list is empty, then we add a dummy transaction + // otherwise the `TxExecuted` event will not be emitted, and we won't be able to + // find the transaction hash + if (transactions.length === 0) { + transactions.push({ + to: this.address, + data: '0x', + value: 0, + gasLimit: 0, + delegateCall: false, + revertOnError: true + }) + } + + const defaultedNonce = await this.fetchNonceOrSpace(nonce) + const digest = commons.transaction.digestOfTransactions(defaultedNonce, transactions) + const meta = { + digest, + transactions, + ...metadata + } + const signature = await this.signDigest(digest, meta) + + return { + intent: { + // Maybe is better if signDigest returns the subdigest directly + id: subDigestOf(this.address, this.chainId, digest), + wallet: this.address + }, + chainId: this.chainId, + transactions, + entrypoint: this.address, + nonce: defaultedNonce, + signature + } + } + + async sendSignedTransaction( + signedBundle: commons.transaction.IntendedTransactionBundle, + quote?: FeeQuote + ): Promise { + if (!this.relayer) throw new Error('Wallet sendTransaction requires a relayer') + return this.relayer.relay(signedBundle, quote) + } + + // sendTransaction will dispatch the transaction to the relayer for submission to the network. + // This method is able to send transactions in serial or parallel (default). You can specify + // a specific nonce, or let the wallet determine the next nonce on-chain (serial:true). + // + // By default, nonces are generated randomly and assigned so transactioned can be executed + // in parallel. However, if you'd like to execute serially, pass { serial: true } as an option. + async sendTransaction( + txs: Deferrable, + options?: { + quote?: FeeQuote + nonce?: ethers.BigNumberish + serial?: boolean + } + ): Promise { + let nonce: ethers.BigNumberish | { serial: boolean } + if (options?.nonce !== undefined) { + // specific nonce is used + nonce = options.nonce + } else if (options?.serial) { + // next nonce on wallet is used and detected on-chain + nonce = { serial: true } + } else { + // default is random, aka parallel + nonce = this.randomNonce() + } + + const signed = await this.signTransactions(txs, nonce) + const decorated = await this.decorateTransactions(signed) + return this.sendSignedTransaction(decorated, options?.quote) + } + + async fillGasLimits(txs: Deferrable): Promise { + const transaction = await resolveArrayProperties(txs) + const transactions = commons.transaction.fromTransactionish(this.address, transaction) + const relayer = this.relayer + if (!relayer) throw new Error('Wallet fillGasLimits requires a relayer') + + const simulations = await relayer.simulate(this.address, ...transactions) + return transactions.map((tx, i) => { + const gasLimit = tx.gasLimit ? ethers.BigNumber.from(tx.gasLimit).toNumber() : simulations[i].gasLimit + return { ...tx, ...simulations[i], gasLimit } + }) + } + + connect(provider: ethers.providers.Provider, relayer?: Relayer): Wallet { + this.provider = provider + this.relayer = relayer + return this + } + + signTransaction(transaction: ethers.utils.Deferrable): Promise { + throw new Error('Method not implemented.') + } +} diff --git a/packages/wallet/tests/utils/deploy-wallet-context.ts b/packages/wallet/tests/utils/deploy-wallet-context.ts new file mode 100644 index 0000000000..97c5374fc0 --- /dev/null +++ b/packages/wallet/tests/utils/deploy-wallet-context.ts @@ -0,0 +1,57 @@ +import { ethers } from 'ethers' + +import { + Factory, + GuestModule, + MainModule, + MainModuleUpgradable, + SequenceUtils, + RequireFreshSigner +} from '@0xsequence/wallet-contracts' + +const FactoryArtifact = require('@0xsequence/wallet-contracts/artifacts/contracts/Factory.sol/Factory.json') +const GuestModuleArtifact = require('@0xsequence/wallet-contracts/artifacts/contracts/modules/GuestModule.sol/GuestModule.json') +const MainModuleArtifact = require('@0xsequence/wallet-contracts/artifacts/contracts/modules/MainModule.sol/MainModule.json') +const MainModuleUpgradableArtifact = require('@0xsequence/wallet-contracts/artifacts/contracts/modules/MainModuleUpgradable.sol/MainModuleUpgradable.json') +const SequenceUtilsArtifact = require('@0xsequence/wallet-contracts/artifacts/contracts/modules/utils/SequenceUtils.sol/SequenceUtils.json') +const RequireFreshSignerArtifact = require('@0xsequence/wallet-contracts/artifacts/contracts/modules/utils/libs/RequireFreshSigner.sol/RequireFreshSigner.json') + +export async function deployWalletContext( + signer: ethers.Signer +): Promise<[Factory, MainModule, MainModuleUpgradable, GuestModule, SequenceUtils, RequireFreshSigner]> { + const factory = (await new ethers.ContractFactory( + FactoryArtifact.abi, + FactoryArtifact.bytecode, + signer + ).deploy()) as unknown as Factory + + const mainModule = (await new ethers.ContractFactory(MainModuleArtifact.abi, MainModuleArtifact.bytecode, signer).deploy( + factory.address + )) as unknown as MainModule + + const mainModuleUpgradable = (await new ethers.ContractFactory( + MainModuleUpgradableArtifact.abi, + MainModuleUpgradableArtifact.bytecode, + signer + ).deploy()) as unknown as MainModuleUpgradable + + const guestModule = (await new ethers.ContractFactory( + GuestModuleArtifact.abi, + GuestModuleArtifact.bytecode, + signer + ).deploy()) as unknown as GuestModule + + const sequenceUtils = (await new ethers.ContractFactory( + SequenceUtilsArtifact.abi, + SequenceUtilsArtifact.bytecode, + signer + ).deploy(factory.address, mainModule.address)) as unknown as SequenceUtils + + const requireFreshSigner = (await new ethers.ContractFactory( + RequireFreshSignerArtifact.abi, + RequireFreshSignerArtifact.bytecode, + signer + ).deploy(sequenceUtils.address)) as unknown as RequireFreshSigner + + return [factory, mainModule, mainModuleUpgradable, guestModule, sequenceUtils, requireFreshSigner] +} diff --git a/packages/wallet/tests/utils/get-contract.ts b/packages/wallet/tests/utils/get-contract.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/wallet/tests/utils/index.ts b/packages/wallet/tests/utils/index.ts new file mode 100644 index 0000000000..6e42022cf2 --- /dev/null +++ b/packages/wallet/tests/utils/index.ts @@ -0,0 +1,5 @@ +import { ethers } from 'ethers' + +export async function encodeData(contract: ethers.Contract, method: string, ...args: any): Promise { + return (await contract.populateTransaction[method](...args)).data! +} diff --git a/packages/wallet/tests/wallet.spec.ts b/packages/wallet/tests/wallet.spec.ts new file mode 100644 index 0000000000..3c77c3a538 --- /dev/null +++ b/packages/wallet/tests/wallet.spec.ts @@ -0,0 +1,594 @@ +import hardhat from 'hardhat' +import * as chai from 'chai' + +import { walletContracts } from '@0xsequence/abi' +import { commons, v1, v2 } from '@0xsequence/core' +import { context } from '@0xsequence/tests' +import { ethers } from 'ethers' +import { SequenceOrchestratorWrapper, Wallet } from '../src/index' +import { Orchestrator, SignatureOrchestrator, signers as hubsigners } from '@0xsequence/signhub' +import { LocalRelayer } from '@0xsequence/relayer' + +const { expect } = chai + +type Coders = { + signature: commons.signature.SignatureCoder + config: commons.config.ConfigCoder +} + +describe('Wallet (primitive)', () => { + let provider: ethers.providers.JsonRpcProvider + let signers: ethers.Signer[] + + let contexts: Awaited> + let relayer: LocalRelayer + + before(async () => { + provider = new ethers.providers.Web3Provider(hardhat.network.provider as any) + signers = new Array(8).fill(0).map((_, i) => provider.getSigner(i)) + contexts = await context.deploySequenceContexts(signers[0]) + relayer = new LocalRelayer(signers[0]) + }) + ;( + [ + { + version: 1, + coders: { signature: v1.signature.SignatureCoder, config: v1.config.ConfigCoder } + }, + { + version: 2, + coders: { signature: v2.signature.SignatureCoder, config: v2.config.ConfigCoder } + } + ] as { version: number; coders: Coders }[] + ).map(({ version, coders }) => { + describe(`Using v${version} version`, () => { + it('Should deploy a new wallet', async () => { + const signer = ethers.Wallet.createRandom() + + const config = coders.config.fromSimple({ + threshold: 1, + checkpoint: 0, + signers: [{ address: signer.address, weight: 1 }] + }) + + const wallet = Wallet.newWallet({ + coders: coders, + context: contexts[version], + config, + orchestrator: new Orchestrator([new hubsigners.SignerWrapper(signer)]), + chainId: provider.network.chainId, + provider, + relayer + }) + + await wallet.deploy() + + expect(await wallet.reader().isDeployed(wallet.address)).to.be.true + }) + + it('Should deploy children', async () => { + const nestedSigner = ethers.Wallet.createRandom() + const nestedConfig = coders.config.fromSimple({ + threshold: 1, + checkpoint: 0, + signers: [{ address: nestedSigner.address, weight: 1 }] + }) + const nestedOrchestrator = new Orchestrator([nestedSigner]) + const nestedWallet = Wallet.newWallet({ + coders: coders, + context: contexts[version], + config: nestedConfig, + orchestrator: nestedOrchestrator, + chainId: provider.network.chainId, + provider, + relayer + }) + const config = coders.config.fromSimple({ + threshold: 1, + checkpoint: 0, + signers: [{ address: nestedWallet.address, weight: 1 }] + }) + const orchestrator = new Orchestrator([new SequenceOrchestratorWrapper(nestedWallet)]) + const wallet = Wallet.newWallet({ + coders: coders, + context: contexts[version], + config, + orchestrator, + chainId: provider.network.chainId, + provider, + relayer + }) + + expect(await wallet.reader().isDeployed(wallet.address)).to.be.false + expect(await nestedWallet.reader().isDeployed(nestedWallet.address)).to.be.false + await wallet.deploy({ includeChildren: true, ignoreDeployed: true }) + expect(await wallet.reader().isDeployed(wallet.address)).to.be.true + expect(await nestedWallet.reader().isDeployed(wallet.address)).to.be.true + }) + + describe('Nonce selection', async () => { + let signer: ethers.Wallet + let wallet: Wallet + + let getNonce: (response: ethers.providers.TransactionResponse) => { space: ethers.BigNumber; nonce: ethers.BigNumber } + + before(async () => { + const mainModule = new ethers.utils.Interface(walletContracts.mainModule.abi) + + getNonce = ({ data }) => { + const [_, encoded] = mainModule.decodeFunctionData('execute', data) + const [space, nonce] = commons.transaction.decodeNonce(encoded) + return { space, nonce } + } + + signer = ethers.Wallet.createRandom() + + wallet = Wallet.newWallet({ + coders, + context: contexts[version], + config: coders.config.fromSimple({ + threshold: 1, + checkpoint: 0, + signers: [{ weight: 1, address: signer.address }] + }), + chainId: provider.network.chainId, + orchestrator: new Orchestrator([signer]), + provider, + relayer + }) + + await wallet.deploy({ includeChildren: true, ignoreDeployed: true }) + + await (await signers[0].sendTransaction({ to: wallet.address, value: ethers.utils.parseEther('1') })).wait() + }) + + it('Should use explicitly set nonces', async () => { + let response = await wallet.sendTransaction( + { to: signers[0].getAddress(), value: 1 }, + { nonce: commons.transaction.encodeNonce(6492, 0) } + ) + + let { space, nonce } = getNonce(response) + + expect(space.eq(6492)).to.be.true + expect(nonce.eq(0)).to.be.true + + await response.wait() + + response = await wallet.sendTransaction( + { to: signers[0].getAddress(), value: 1 }, + { nonce: commons.transaction.encodeNonce(6492, 1) } + ) + + const encoded = getNonce(response) + space = encoded.space + nonce = encoded.nonce + + expect(space.eq(6492)).to.be.true + expect(nonce.eq(1)).to.be.true + }) + + it('Should select random nonces by default', async () => { + let response = await wallet.sendTransaction({ to: signers[0].getAddress(), value: 1 }) + + const { space: firstSpace, nonce: firstNonce } = getNonce(response) + + expect(firstSpace.eq(0)).to.be.false + expect(firstNonce.eq(0)).to.be.true + + // not necessary, parallel execution is ok: + // await response.wait() + + response = await wallet.sendTransaction({ to: signers[0].getAddress(), value: 1 }) + + const { space: secondSpace, nonce: secondNonce } = getNonce(response) + + expect(secondSpace.eq(0)).to.be.false + expect(secondNonce.eq(0)).to.be.true + + expect(secondSpace.eq(firstSpace)).to.be.false + }) + + it('Should respect the serial option', async () => { + let response = await wallet.sendTransaction({ to: signers[0].getAddress(), value: 1 }, { serial: true }) + + let { space, nonce } = getNonce(response) + + expect(space.eq(0)).to.be.true + expect(nonce.eq(0)).to.be.true + + await response.wait() + + response = await wallet.sendTransaction({ to: signers[0].getAddress(), value: 1 }, { serial: true }) + + const encoded = getNonce(response) + space = encoded.space + nonce = encoded.nonce + + expect(space.eq(0)).to.be.true + expect(nonce.eq(1)).to.be.true + }) + }) + + // + // Run tests using different combinations of signers + // + ;[ + { + name: '1/1 signer', + signers: () => { + const signer = ethers.Wallet.createRandom() + + const config = coders.config.fromSimple({ + threshold: 1, + checkpoint: 0, + signers: [{ address: signer.address, weight: 1 }] + }) + + const orchestrator = new Orchestrator([new hubsigners.SignerWrapper(signer)]) + + return { config, orchestrator } + } + }, + { + name: '1/2 signers', + signers: () => { + const signer = ethers.Wallet.createRandom() + const signers = [ + { + address: signer.address, + weight: 1 + }, + { + address: ethers.Wallet.createRandom().address, + weight: 1 + } + ].sort(() => (Math.random() > 0.5 ? 1 : -1)) + + const config = coders.config.fromSimple({ + threshold: 1, + checkpoint: 0, + signers + }) + + const orchestrator = new Orchestrator([new hubsigners.SignerWrapper(signer)]) + return { config, orchestrator } + } + }, + { + name: '2/4 signers', + signers: () => { + const members = new Array(4).fill(0).map(() => ethers.Wallet.createRandom()) + + const signers = members + .map(m => ({ + address: m.address, + weight: 2 + })) + .sort(() => (Math.random() > 0.5 ? 1 : -1)) + + const config = coders.config.fromSimple({ + threshold: 2, + checkpoint: 0, + signers + }) + + const orchestrator = new Orchestrator(members.slice(0, 2).map(m => new hubsigners.SignerWrapper(m))) + return { config, orchestrator } + } + }, + { + name: '11/90 signers', + signers: () => { + const members = new Array(90).fill(0).map(() => ethers.Wallet.createRandom()) + + const signers = members + .map(m => ({ + address: m.address, + weight: 1 + })) + .sort(() => (Math.random() > 0.5 ? 1 : -1)) + + const config = coders.config.fromSimple({ + threshold: 11, + checkpoint: 0, + signers + }) + + const orchestrator = new Orchestrator(members.slice(0, 11).map(m => new hubsigners.SignerWrapper(m))) + return { config, orchestrator } + } + }, + { + name: '1/1 signer (nested)', + signers: async () => { + const nestedSigner = ethers.Wallet.createRandom() + + const nestedConfig = coders.config.fromSimple({ + threshold: 1, + checkpoint: 0, + signers: [{ address: nestedSigner.address, weight: 1 }] + }) + + const nestedOrchestrator = new Orchestrator([nestedSigner]) + const nestedWallet = Wallet.newWallet({ + coders: coders, + context: contexts[version], + config: nestedConfig, + orchestrator: nestedOrchestrator, + chainId: provider.network.chainId, + provider, + relayer + }) + + await nestedWallet.deploy() + expect(await nestedWallet.reader().isDeployed(nestedWallet.address)).to.be.true + + const config = coders.config.fromSimple({ + threshold: 1, + checkpoint: 0, + signers: [{ address: nestedWallet.address, weight: 1 }] + }) + + const orchestrator = new Orchestrator([new SequenceOrchestratorWrapper(nestedWallet)]) + + return { config, orchestrator } + } + }, + { + name: '1/1 signer (undeployed nested)', + signers: async () => { + const nestedSigner = ethers.Wallet.createRandom() + + const nestedConfig = coders.config.fromSimple({ + threshold: 1, + checkpoint: 0, + signers: [{ address: nestedSigner.address, weight: 1 }] + }) + + const nestedOrchestrator = new Orchestrator([nestedSigner]) + const nestedWallet = Wallet.newWallet({ + coders: coders, + context: contexts[version], + config: nestedConfig, + orchestrator: nestedOrchestrator, + chainId: provider.network.chainId, + provider, + relayer + }) + + expect(await nestedWallet.reader().isDeployed(nestedWallet.address)).to.be.false + + const config = coders.config.fromSimple({ + threshold: 1, + checkpoint: 0, + signers: [{ address: nestedWallet.address, weight: 1 }] + }) + + const orchestrator = new Orchestrator([new SequenceOrchestratorWrapper(nestedWallet)]) + + return { config, orchestrator } + } + } + ].map(({ name, signers }) => { + describe(`Using ${name}`, () => { + let orchestrator: SignatureOrchestrator + let config: commons.config.Config + + beforeEach(async () => { + const { config: _config, orchestrator: _orchestrator } = await signers() + config = _config + orchestrator = _orchestrator + }) + + // Skip this as we cannot validate a message with an undeployed nested wallet + if (name !== '1/1 signer (undeployed nested)') { + it('Should sign and validate a message', async () => { + const wallet = Wallet.newWallet({ + coders: coders, + context: contexts[version], + config, + orchestrator, + chainId: provider.network.chainId, + provider, + relayer + }) + + await wallet.deploy() + expect(await wallet.reader().isDeployed(wallet.address)).to.be.true + + const message = ethers.utils.toUtf8Bytes( + `This is a random message: ${ethers.utils.hexlify(ethers.utils.randomBytes(96))}` + ) + + const signature = await wallet.signMessage(message) + const digest = ethers.utils.keccak256(message) + + expect(await wallet.reader().isValidSignature(wallet.address, digest, signature)).to.be.true + }) + } + + // + // Run tests for deployed and undeployed wallets + // transactions should be decorated automatically + // + ;[ + { + name: 'After deployment', + setup: async (wallet: Wallet) => { + await wallet.deploy() + }, + deployed: true + }, + { + name: 'Before deployment', + setup: async (_: Wallet) => {}, + deployed: false + } + ].map(({ name, setup, deployed }) => { + describe(name, () => { + let wallet: Wallet + + beforeEach(async () => { + wallet = Wallet.newWallet({ + coders: coders, + context: contexts[version], + config, + orchestrator, + chainId: provider.network.chainId, + provider, + relayer + }) + + await setup(wallet) + }) + + it('Should send an empty list of transactions', async () => { + await wallet.sendTransaction([]) + }) + + it('Should send a transaction with an empty call', async () => { + await wallet.sendTransaction([ + { + to: ethers.Wallet.createRandom().address + } + ]) + }) + + it('Should build and execute a wallet update transaction', async () => { + const newConfig = coders.config.fromSimple({ + threshold: 1, + checkpoint: 0, + signers: [ + { + address: ethers.Wallet.createRandom().address, + weight: 1 + } + ] + }) + + const updateTx = await wallet.buildUpdateConfigurationTransaction(newConfig) + + expect(updateTx.entrypoint).to.equal(wallet.address) + expect(updateTx.transactions[0].to).to.equal(wallet.address) + expect(updateTx.transactions[0].delegateCall).to.equal(false) + expect(updateTx.transactions[0].revertOnError).to.equal(true) + expect(updateTx.transactions[0].gasLimit).to.equal(0) + expect(updateTx.transactions[0].value).to.equal(0) + + if (version === 1) { + expect(updateTx.transactions.length).to.be.equal(2) + expect(updateTx.transactions[1].to).to.equal(wallet.address) + expect(updateTx.transactions[1].delegateCall).to.equal(false) + expect(updateTx.transactions[1].revertOnError).to.equal(true) + expect(updateTx.transactions[1].gasLimit).to.equal(0) + expect(updateTx.transactions[1].value).to.equal(0) + } else if (version === 2) { + expect(updateTx.transactions.length).to.be.equal(1) + } else { + throw new Error('Version not supported in test') + } + + const prevImplentation = await wallet.reader().implementation(wallet.address) + + await wallet.sendTransaction(updateTx.transactions) + + expect(await wallet.reader().imageHash(wallet.address)).to.equal(coders.config.imageHashOf(newConfig)) + expect(await wallet.reader().implementation(wallet.address)).to.not.equal(prevImplentation) + }) + + describe('parallel transactions', async () => { + let testAccount: ethers.providers.JsonRpcSigner + let testAccountAddress: string + let toBalanceBefore: ethers.BigNumber + + beforeEach(async () => { + testAccount = provider.getSigner(5) + testAccountAddress = await testAccount.getAddress() + + const ethAmount = ethers.utils.parseEther('100') + const txResp = await testAccount.sendTransaction({ + to: await wallet.getAddress(), + value: ethAmount + }) + await provider.getTransactionReceipt(txResp.hash) + toBalanceBefore = await provider.getBalance(testAccountAddress) + }) + + it('Should send an async transaction', async () => { + const ethAmount = ethers.utils.parseEther('1.0') + + const tx: ethers.providers.TransactionRequest = { + to: testAccountAddress, + value: ethAmount + } + + await wallet.sendTransaction(tx) + const toBalanceAfter = await provider.getBalance(testAccountAddress) + const sent = toBalanceAfter.sub(toBalanceBefore) + expect(sent.toString()).to.be.eq(ethAmount.toString()) + }) + + it('Should send two async transactions at once', async () => { + const ethAmount1 = ethers.utils.parseEther('1.0') + const ethAmount2 = ethers.utils.parseEther('2.0') + const ethAmount3 = ethers.utils.parseEther('5.0') + + const tx1: ethers.providers.TransactionRequest = { + to: testAccountAddress, + value: ethAmount1 + } + + const tx2: ethers.providers.TransactionRequest = { + to: testAccountAddress, + value: ethAmount2 + } + + const tx3: ethers.providers.TransactionRequest = { + to: testAccountAddress, + value: ethAmount3 + } + + // Send txns in parallel, but independently + await Promise.all([wallet.sendTransaction(tx1), wallet.sendTransaction(tx2), wallet.sendTransaction(tx3)]) + + const toBalanceAfter = await provider.getBalance(testAccountAddress) + const sent = toBalanceAfter.sub(toBalanceBefore) + expect(sent.toString()).to.be.eq(ethAmount1.add(ethAmount2).add(ethAmount3).toString()) + }) + + it('Should send multiple async transactions in one batch, async', async () => { + const ethAmount1 = ethers.utils.parseEther('1.0') + const ethAmount2 = ethers.utils.parseEther('2.0') + const ethAmount3 = ethers.utils.parseEther('5.0') + + const tx1: ethers.providers.TransactionRequest = { + to: testAccountAddress, + value: ethAmount1 + } + + const tx2: ethers.providers.TransactionRequest = { + to: testAccountAddress, + value: ethAmount2 + } + + const tx3: ethers.providers.TransactionRequest = { + to: testAccountAddress, + value: ethAmount3 + } + + // Send txns in parallel, but independently + await wallet.sendTransaction([tx1, tx2, tx3]) + + const toBalanceAfter = await provider.getBalance(testAccountAddress) + const sent = toBalanceAfter.sub(toBalanceBefore) + expect(sent.toString()).to.be.eq(ethAmount1.add(ethAmount2).add(ethAmount3).toString()) + }) + }) + }) + }) + }) + }) + }) + }) +}) diff --git a/packages/wallet/wallet-contracts/.eslintignore b/packages/wallet/wallet-contracts/.eslintignore new file mode 100644 index 0000000000..f0a62d6975 --- /dev/null +++ b/packages/wallet/wallet-contracts/.eslintignore @@ -0,0 +1,3 @@ +.eslintrc.js +node_modules +src/gen diff --git a/packages/wallet/wallet-contracts/.eslintrc.js b/packages/wallet/wallet-contracts/.eslintrc.js new file mode 100644 index 0000000000..284d5a529c --- /dev/null +++ b/packages/wallet/wallet-contracts/.eslintrc.js @@ -0,0 +1,38 @@ +const { off } = require("process") + +module.exports = { + parser: '@typescript-eslint/parser', + parserOptions: { + ecmaVersion: 2018, + sourceType: 'module' + }, + + extends: [ + 'plugin:@typescript-eslint/recommended', + 'plugin:import/errors', + 'plugin:import/warnings', + 'plugin:import/typescript', + 'prettier' + ], + + rules: { + '@typescript-eslint/no-unused-vars': 'off', + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-non-null-assertion': 'off', + '@typescript-eslint/explicit-module-boundary-types': 'off', + '@typescript-eslint/ban-types': 'off', + '@typescript-eslint/ban-ts-comment': 'off', + '@typescript-eslint/no-empty-function': 'off', + '@typescript-eslint/no-inferrable-types': 'off', + '@typescript-eslint/no-var-requires': 'off', + '@typescript-eslint/no-non-null-asserted-optional-chain': 'off', + + 'prefer-spread': 'off', + 'prefer-const': 'off', + + 'import/no-unresolved': 'off', + // 'import/no-default-export': 2, + 'import/no-named-as-default-member': 'off', + + } +} diff --git a/packages/wallet/wallet-contracts/.gitattributes b/packages/wallet/wallet-contracts/.gitattributes new file mode 100644 index 0000000000..52031de51c --- /dev/null +++ b/packages/wallet/wallet-contracts/.gitattributes @@ -0,0 +1 @@ +*.sol linguist-language=Solidity diff --git a/packages/wallet/wallet-contracts/.github/actions/install-dependencies/action.yml b/packages/wallet/wallet-contracts/.github/actions/install-dependencies/action.yml new file mode 100644 index 0000000000..2d96c7d588 --- /dev/null +++ b/packages/wallet/wallet-contracts/.github/actions/install-dependencies/action.yml @@ -0,0 +1,36 @@ +name: Setup Node and PNPM dependencies + +runs: + using: 'composite' + + steps: + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20 + + - name: Setup PNPM + uses: pnpm/action-setup@v3 + with: + version: 9 + run_install: false + + - name: Get pnpm store directory + id: pnpm-cache + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT + + - name: Setup pnpm cache + uses: actions/cache@v4 + with: + path: | + ${{ steps.pnpm-cache.outputs.STORE_PATH }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + + - name: Install dependencies + shell: bash + run: pnpm install --frozen-lockfile + if: ${{ steps.pnpm-cache.outputs.cache-hit != 'true' }} diff --git a/packages/wallet/wallet-contracts/.github/workflows/ci.yml b/packages/wallet/wallet-contracts/.github/workflows/ci.yml new file mode 100644 index 0000000000..820aa13c4c --- /dev/null +++ b/packages/wallet/wallet-contracts/.github/workflows/ci.yml @@ -0,0 +1,108 @@ +on: [push] + +name: ci + +jobs: + benchmark: + name: Benchmark + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/install-dependencies + - run: pnpm build + - run: pnpm benchmark + + lint-ts: + name: Typescript lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/install-dependencies + - run: pnpm lint:ts + + lint-sol: + name: Solidity lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/install-dependencies + - run: pnpm lint:sol + + test: + name: Test contracts + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/install-dependencies + - run: pnpm build + - run: pnpm test + + coverage: + name: Coverage + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/install-dependencies + - run: pnpm coverage || true + - name: Coveralls + uses: coverallsapp/github-action@master + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + + huff-tests: + name: Huff tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Install Huff + uses: huff-language/huff-toolchain@v3 + with: + version: nightly + + - name: Run tests + run: bash ./run_huff_tests.sh + + foundry-tests: + name: Foundry tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly + + - name: Install Huff + uses: huff-language/huff-toolchain@v3 + with: + version: nightly + + - name: Run tests + run: FOUNDRY_FUZZ_RUNS=2048 MAX_ARRAY_LEN=32 forge test -vvv + + foundry-tests-long-arrays: + name: Foundry tests (long arrays) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly + + - name: Install Huff + uses: huff-language/huff-toolchain@v3 + with: + version: nightly + + - name: Run tests + run: FOUNDRY_FUZZ_RUNS=1024 forge test -vvv diff --git a/packages/wallet/wallet-contracts/.gitmodules b/packages/wallet/wallet-contracts/.gitmodules new file mode 100644 index 0000000000..b6622fb248 --- /dev/null +++ b/packages/wallet/wallet-contracts/.gitmodules @@ -0,0 +1,6 @@ +[submodule "lib/forge-std"] + path = lib/forge-std + url = https://github.com/foundry-rs/forge-std +[submodule "lib/foundry-huff"] + path = lib/foundry-huff + url = https://github.com/huff-language/foundry-huff \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/.prettierrc b/packages/wallet/wallet-contracts/.prettierrc new file mode 100644 index 0000000000..421afa9791 --- /dev/null +++ b/packages/wallet/wallet-contracts/.prettierrc @@ -0,0 +1,9 @@ +{ + "tabWidth": 2, + "useTabs": false, + "semi": false, + "singleQuote": true, + "trailingComma": "none", + "arrowParens": "avoid", + "printWidth": 130 +} diff --git a/packages/wallet/wallet-contracts/.solcover.js b/packages/wallet/wallet-contracts/.solcover.js new file mode 100644 index 0000000000..fab8bc0e80 --- /dev/null +++ b/packages/wallet/wallet-contracts/.solcover.js @@ -0,0 +1,3 @@ +module.exports = { + skipFiles: ['mocks', 'migrations'] +} diff --git a/packages/wallet/wallet-contracts/.solhint.json b/packages/wallet/wallet-contracts/.solhint.json new file mode 100644 index 0000000000..951b9ecc0b --- /dev/null +++ b/packages/wallet/wallet-contracts/.solhint.json @@ -0,0 +1,26 @@ +{ + "extends": "solhint:recommended", + "rules": { + "quotes": "off", + "const-name-snakecase": "off", + "contract-name-camelcase": "off", + "event-name-camelcase": "off", + "func-name-mixedcase": "off", + "func-param-name-mixedcase": "off", + "modifier-name-mixedcase": "off", + "private-vars-leading-underscore": "off", + "use-forbidden-name": "off", + "var-name-mixedcase": "off", + "func-order": "off", + "imports-on-top": "off", + "ordering": "off", + "no-global-import": "off", + "no-unused-vars": "error", + "not-rely-on-time": "off", + "no-inline-assembly": "off", + "visibility-modifier-order": "off", + "compiler-version": ["error", "0.8.18"], + "func-visibility": ["warn", {"ignoreConstructors":true}], + "reason-string": ["warn", {"maxLength": 96}] + } +} diff --git a/packages/wallet/wallet-contracts/0xsequence-wallet-contracts-3.0.1.tgz b/packages/wallet/wallet-contracts/0xsequence-wallet-contracts-3.0.1.tgz new file mode 100644 index 0000000000..543d81b695 Binary files /dev/null and b/packages/wallet/wallet-contracts/0xsequence-wallet-contracts-3.0.1.tgz differ diff --git a/packages/wallet/wallet-contracts/Counter/.github/workflows/test.yml b/packages/wallet/wallet-contracts/Counter/.github/workflows/test.yml new file mode 100644 index 0000000000..b79c8d4ffd --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/.github/workflows/test.yml @@ -0,0 +1,38 @@ +name: CI + +permissions: {} + +on: + push: + pull_request: + workflow_dispatch: + +env: + FOUNDRY_PROFILE: ci + +jobs: + check: + name: Foundry project + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - uses: actions/checkout@v5 + with: + persist-credentials: false + submodules: recursive + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + + - name: Show Forge version + run: forge --version + + - name: Run Forge fmt + run: forge fmt --check + + - name: Run Forge build + run: forge build --sizes + + - name: Run Forge tests + run: forge test -vvv diff --git a/packages/wallet/wallet-contracts/Counter/.gitmodules b/packages/wallet/wallet-contracts/Counter/.gitmodules new file mode 100644 index 0000000000..888d42dcd9 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/.gitmodules @@ -0,0 +1,3 @@ +[submodule "lib/forge-std"] + path = lib/forge-std + url = https://github.com/foundry-rs/forge-std diff --git a/packages/wallet/wallet-contracts/Counter/README.md b/packages/wallet/wallet-contracts/Counter/README.md new file mode 100644 index 0000000000..8817d6ab7b --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/README.md @@ -0,0 +1,66 @@ +## Foundry + +**Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.** + +Foundry consists of: + +- **Forge**: Ethereum testing framework (like Truffle, Hardhat and DappTools). +- **Cast**: Swiss army knife for interacting with EVM smart contracts, sending transactions and getting chain data. +- **Anvil**: Local Ethereum node, akin to Ganache, Hardhat Network. +- **Chisel**: Fast, utilitarian, and verbose solidity REPL. + +## Documentation + +https://book.getfoundry.sh/ + +## Usage + +### Build + +```shell +$ forge build +``` + +### Test + +```shell +$ forge test +``` + +### Format + +```shell +$ forge fmt +``` + +### Gas Snapshots + +```shell +$ forge snapshot +``` + +### Anvil + +```shell +$ anvil +``` + +### Deploy + +```shell +$ forge script script/Counter.s.sol:CounterScript --rpc-url --private-key +``` + +### Cast + +```shell +$ cast +``` + +### Help + +```shell +$ forge --help +$ anvil --help +$ cast --help +``` diff --git a/packages/wallet/wallet-contracts/Counter/broadcast/Counter.s.sol/1/run-1763223074249.json b/packages/wallet/wallet-contracts/Counter/broadcast/Counter.s.sol/1/run-1763223074249.json new file mode 100644 index 0000000000..1a445c37f7 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/broadcast/Counter.s.sol/1/run-1763223074249.json @@ -0,0 +1,47 @@ +{ + "transactions": [ + { + "hash": "0xe967Cuba140cfd311ae7b1b1b7e3722aa342485416fa71a65724a7c61ba242ac", + "transactionType": "CREATE", + "contractName": "Counter", + "contractAddress": "0x2bc0484b5b0faff0a14b858d85e8830621fe0ca", + "function": null, + "arguments": null, + "transaction": { + "from": "0xf39fd6e51aad88f6f4ce6ab8827279coff92266", + "gas": "0x31c50", + "value": "0x0", + "input": "0x6080604052348015600e575f5ffd5b506101e18061001c5f395ff3fe608060405234801561000f575f5ffd5b506004361061003f575f3560e01c80633fb5c1cb146100435780638381f58a1461005f578063d09de08a1461007d575b5f5ffd5b61005d600480360381019061005891906100e4565b610087565b005b610067610090565b604051610074919061011e565b60405180910390f35b610085610095565b005b805f8190555050565b5f5481565b5f5f8154809291906100a690610164565b9190505550565b5f5ffd5b5f819050919050565b6100c3816100b1565b81146100cd575f5ffd5b50565b5f813590506100de816100ba565b92915050565b5f602082840312156100f9576100f86100ad565b5b5f610106848285016100d0565b91505092915050565b610118816100b1565b82525050565b5f6020820190506101315f83018461010f565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61016e826100b1565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036101a05761019f610137565b5b60018201905091905056fea2646970667358221220df4a76c68e7f061f542d26155d08ef6ac6937da6830d06a5a5c3e20d2c78b21164736f6c634300081e0033", + "nonce": "0xe6f", + "chainId": "0x1" + }, + "additionalContracts": [], + "isFixedGasLimit": false + } + ], + "receipts": [ + { + "status": "0x1", + "cumulativeGasUsed": "0x2648d", + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "type": "0x2", + "transactionHash": "0xe967cfba140cfd311ae7b1b1b7e3722aa342485416fa71a65724a7c61ba242ac", + "transactionIndex": "0x0", + "blockHash": "0x567bf85581af8ab194b098169c966fc2fa35547be5092b02ca8199f6a2fde371", + "blockNumber": "0x16b3eff", + "gasUsed": "0x2648d", + "effectiveGasPrice": "0x60f59cc", + "blobGasPrice": "0x13", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": null, + "contractAddress": "0x2bc0484b5b0fafff0a14b858d85e8830621fe0ca" + } + ], + "libraries": [], + "pending": [], + "returns": {}, + "timestamp": 1763223074249, + "chain": 1, + "commit": null +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/Counter/broadcast/Counter.s.sol/1/run-1763223530987.json b/packages/wallet/wallet-contracts/Counter/broadcast/Counter.s.sol/1/run-1763223530987.json new file mode 100644 index 0000000000..79ce8649c7 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/broadcast/Counter.s.sol/1/run-1763223530987.json @@ -0,0 +1,47 @@ +{ + "transactions": [ + { + "hash": "0x9fb638893fefbe8746ec8865245fbac0b6078c309be487fdf0e84e28ff1aaf3b", + "transactionType": "CREATE", + "contractName": "Counter", + "contractAddress": "0x1687d4bde380019748605231c956335a473fd3dc", + "function": null, + "arguments": null, + "transaction": { + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "gas": "0x31c50", + "value": "0x0", + "input": "0x6080604052348015600e575f5ffd5b506101e18061001c5f395ff3fe608060405234801561000f575f5ffd5b506004361061003f575f3560e01c80633fb5c1cb146100435780638381f58a1461005f578063d09de08a1461007d575b5f5ffd5b61005d600480360381019061005891906100e4565b610087565b005b610067610090565b604051610074919061011e565b60405180910390f35b610085610095565b005b805f8190555050565b5f5481565b5f5f8154809291906100a690610164565b9190505550565b5f5ffd5b5f819050919050565b6100c3816100b1565b81146100cd575f5ffd5b50565b5f813590506100de816100ba565b92915050565b5f602082840312156100f9576100f86100ad565b5b5f610106848285016100d0565b91505092915050565b610118816100b1565b82525050565b5f6020820190506101315f83018461010f565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61016e826100b1565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036101a05761019f610137565b5b60018201905091905056fea2646970667358221220df4a76c68e7f061f542d26155d08ef6ac6937da6830d06a5a5c3e20d2c78b21164736f6c634300081e0033", + "nonce": "0xe71", + "chainId": "0x1" + }, + "additionalContracts": [], + "isFixedGasLimit": false + } + ], + "receipts": [ + { + "status": "0x1", + "cumulativeGasUsed": "0x2648d", + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "type": "0x2", + "transactionHash": "0x9fb638893fefbe8746ec8865245fbac0b6078c309be487fdf0e84e28ff1aaf3b", + "transactionIndex": "0x0", + "blockHash": "0xedb6015df8ae2fa303919e4d754fe4ad683fa779a93b568a73205ac74c903755", + "blockNumber": "0x16b3f01", + "gasUsed": "0x2648d", + "effectiveGasPrice": "0x4a528c4", + "blobGasPrice": "0xb", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": null, + "contractAddress": "0x1687d4bde380019748605231c956335a473fd3dc" + } + ], + "libraries": [], + "pending": [], + "returns": {}, + "timestamp": 1763223530987, + "chain": 1, + "commit": null +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/Counter/broadcast/Counter.s.sol/1/run-latest.json b/packages/wallet/wallet-contracts/Counter/broadcast/Counter.s.sol/1/run-latest.json new file mode 100644 index 0000000000..79ce8649c7 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/broadcast/Counter.s.sol/1/run-latest.json @@ -0,0 +1,47 @@ +{ + "transactions": [ + { + "hash": "0x9fb638893fefbe8746ec8865245fbac0b6078c309be487fdf0e84e28ff1aaf3b", + "transactionType": "CREATE", + "contractName": "Counter", + "contractAddress": "0x1687d4bde380019748605231c956335a473fd3dc", + "function": null, + "arguments": null, + "transaction": { + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "gas": "0x31c50", + "value": "0x0", + "input": "0x6080604052348015600e575f5ffd5b506101e18061001c5f395ff3fe608060405234801561000f575f5ffd5b506004361061003f575f3560e01c80633fb5c1cb146100435780638381f58a1461005f578063d09de08a1461007d575b5f5ffd5b61005d600480360381019061005891906100e4565b610087565b005b610067610090565b604051610074919061011e565b60405180910390f35b610085610095565b005b805f8190555050565b5f5481565b5f5f8154809291906100a690610164565b9190505550565b5f5ffd5b5f819050919050565b6100c3816100b1565b81146100cd575f5ffd5b50565b5f813590506100de816100ba565b92915050565b5f602082840312156100f9576100f86100ad565b5b5f610106848285016100d0565b91505092915050565b610118816100b1565b82525050565b5f6020820190506101315f83018461010f565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61016e826100b1565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036101a05761019f610137565b5b60018201905091905056fea2646970667358221220df4a76c68e7f061f542d26155d08ef6ac6937da6830d06a5a5c3e20d2c78b21164736f6c634300081e0033", + "nonce": "0xe71", + "chainId": "0x1" + }, + "additionalContracts": [], + "isFixedGasLimit": false + } + ], + "receipts": [ + { + "status": "0x1", + "cumulativeGasUsed": "0x2648d", + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "type": "0x2", + "transactionHash": "0x9fb638893fefbe8746ec8865245fbac0b6078c309be487fdf0e84e28ff1aaf3b", + "transactionIndex": "0x0", + "blockHash": "0xedb6015df8ae2fa303919e4d754fe4ad683fa779a93b568a73205ac74c903755", + "blockNumber": "0x16b3f01", + "gasUsed": "0x2648d", + "effectiveGasPrice": "0x4a528c4", + "blobGasPrice": "0xb", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": null, + "contractAddress": "0x1687d4bde380019748605231c956335a473fd3dc" + } + ], + "libraries": [], + "pending": [], + "returns": {}, + "timestamp": 1763223530987, + "chain": 1, + "commit": null +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/Counter/foundry.lock b/packages/wallet/wallet-contracts/Counter/foundry.lock new file mode 100644 index 0000000000..fee8a95759 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/foundry.lock @@ -0,0 +1,8 @@ +{ + "lib/forge-std": { + "tag": { + "name": "v1.11.0", + "rev": "8e40513d678f392f398620b3ef2b418648b33e89" + } + } +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/Counter/foundry.toml b/packages/wallet/wallet-contracts/Counter/foundry.toml new file mode 100644 index 0000000000..25b918f9c9 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/foundry.toml @@ -0,0 +1,6 @@ +[profile.default] +src = "src" +out = "out" +libs = ["lib"] + +# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/.gitattributes b/packages/wallet/wallet-contracts/Counter/lib/forge-std/.gitattributes new file mode 100644 index 0000000000..27042d458c --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/.gitattributes @@ -0,0 +1 @@ +src/Vm.sol linguist-generated diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/.github/CODEOWNERS b/packages/wallet/wallet-contracts/Counter/lib/forge-std/.github/CODEOWNERS new file mode 100644 index 0000000000..beae7aa872 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/.github/CODEOWNERS @@ -0,0 +1 @@ +* @danipopes @klkvr @mattsse @grandizzy @yash-atreya @zerosnacks @onbjerg @0xrusowsky \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/.github/dependabot.yml b/packages/wallet/wallet-contracts/Counter/lib/forge-std/.github/dependabot.yml new file mode 100644 index 0000000000..5ace4600a1 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/.github/workflows/ci.yml b/packages/wallet/wallet-contracts/Counter/lib/forge-std/.github/workflows/ci.yml new file mode 100644 index 0000000000..cede018c79 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/.github/workflows/ci.yml @@ -0,0 +1,142 @@ +name: CI + +permissions: {} + +on: + workflow_dispatch: + pull_request: + push: + branches: + - master + +jobs: + build: + name: build +${{ matrix.toolchain }} ${{ matrix.flags }} + runs-on: ubuntu-latest + timeout-minutes: 10 + permissions: + contents: read + strategy: + fail-fast: false + matrix: + toolchain: [stable, nightly] + flags: + - "" + - --via-ir + - --use solc:0.8.17 --via-ir + - --use solc:0.8.17 + - --use solc:0.8.0 + - --use solc:0.7.6 + - --use solc:0.7.0 + - --use solc:0.6.2 + - --use solc:0.6.12 + steps: + - uses: actions/checkout@v5 + with: + persist-credentials: false + - uses: foundry-rs/foundry-toolchain@v1 + - run: forge --version + - run: | + case "${{ matrix.flags }}" in + *"solc:0.8.0"* | *"solc:0.7"* | *"solc:0.6"*) + forge build --skip test --skip Config --skip StdConfig --skip LibVariable --deny-warnings ${{ matrix.flags }} + ;; + *) + forge build --skip test --deny-warnings ${{ matrix.flags }} + ;; + esac + # via-ir compilation time checks. + - if: contains(matrix.flags, '--via-ir') + run: forge build --skip test --deny-warnings ${{ matrix.flags }} --contracts 'test/compilation/*' + + test: + runs-on: ubuntu-latest + timeout-minutes: 10 + permissions: + contents: read + strategy: + fail-fast: false + matrix: + toolchain: [stable, nightly] + steps: + - uses: actions/checkout@v5 + with: + persist-credentials: false + - uses: foundry-rs/foundry-toolchain@v1 + with: + version: ${{ matrix.toolchain }} + - run: forge --version + - run: | + if [ "${{ matrix.toolchain }}" = "stable" ]; then + forge test -vvv --no-match-path "test/Config.t.sol" + else + forge test -vvv + fi + + fmt: + runs-on: ubuntu-latest + timeout-minutes: 10 + permissions: + contents: read + steps: + - uses: actions/checkout@v5 + with: + persist-credentials: false + - uses: foundry-rs/foundry-toolchain@v1 + - run: forge --version + - run: forge fmt --check + + typos: + runs-on: ubuntu-latest + timeout-minutes: 10 + permissions: + contents: read + steps: + - uses: actions/checkout@v5 + with: + persist-credentials: false + - uses: crate-ci/typos@7436548694def3314aacd93ed06c721b1f91ea04 # v1 + + codeql: + name: Analyze (${{ matrix.language }}) + runs-on: ubuntu-latest + permissions: + security-events: write + actions: read + contents: read + strategy: + fail-fast: false + matrix: + include: + - language: actions + build-mode: none + steps: + - name: Checkout repository + uses: actions/checkout@v5 + with: + persist-credentials: false + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + build-mode: ${{ matrix.build-mode }} + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + with: + category: "/language:${{matrix.language}}" + + ci-success: + runs-on: ubuntu-latest + if: always() + needs: + - build + - test + - fmt + - typos + - codeql + timeout-minutes: 10 + steps: + - name: Decide whether the needed jobs succeeded or failed + uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe # release/v1 + with: + jobs: ${{ toJSON(needs) }} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/.github/workflows/sync.yml b/packages/wallet/wallet-contracts/Counter/lib/forge-std/.github/workflows/sync.yml new file mode 100644 index 0000000000..15731cbbf3 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/.github/workflows/sync.yml @@ -0,0 +1,36 @@ +name: Sync Release Branch + +permissions: {} + +on: + release: + types: + - created + +jobs: + sync-release-branch: + runs-on: ubuntu-latest + permissions: + contents: write + if: startsWith(github.event.release.tag_name, 'v1') + steps: + - name: Check out the repo + uses: actions/checkout@v5 + with: + persist-credentials: true + fetch-depth: 0 + ref: v1 + + # The email is derived from the bots user id, + # found here: https://api.github.com/users/github-actions%5Bbot%5D + - name: Configure Git + run: | + git config user.name github-actions[bot] + git config user.email 41898282+github-actions[bot]@users.noreply.github.com + + - name: Sync Release Branch + run: | + git fetch --tags + git checkout v1 + git reset --hard ${GITHUB_REF} + git push --force diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/CONTRIBUTING.md b/packages/wallet/wallet-contracts/Counter/lib/forge-std/CONTRIBUTING.md new file mode 100644 index 0000000000..89b75f3f78 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/CONTRIBUTING.md @@ -0,0 +1,193 @@ +## Contributing to Foundry + +Thanks for your interest in improving Foundry! + +There are multiple opportunities to contribute at any level. It doesn't matter if you are just getting started with Rust or are the most weathered expert, we can use your help. + +This document will help you get started. **Do not let the document intimidate you**. +It should be considered as a guide to help you navigate the process. + +The [dev Telegram][dev-tg] is available for any concerns you may have that are not covered in this guide. + +### Code of Conduct + +The Foundry project adheres to the [Rust Code of Conduct][rust-coc]. This code of conduct describes the _minimum_ behavior expected from all contributors. + +Instances of violations of the Code of Conduct can be reported by contacting the team at [me@gakonst.com](mailto:me@gakonst.com). + +### Ways to contribute + +There are fundamentally four ways an individual can contribute: + +1. **By opening an issue:** For example, if you believe that you have uncovered a bug + in Foundry, creating a new issue in the issue tracker is the way to report it. +2. **By adding context:** Providing additional context to existing issues, + such as screenshots and code snippets, which help resolve issues. +3. **By resolving issues:** Typically this is done in the form of either + demonstrating that the issue reported is not a problem after all, or more often, + by opening a pull request that fixes the underlying problem, in a concrete and + reviewable manner. + +**Anybody can participate in any stage of contribution**. We urge you to participate in the discussion +around bugs and participate in reviewing PRs. + +### Contributions Related to Spelling and Grammar + +At this time, we will not be accepting contributions that only fix spelling or grammatical errors in documentation, code or +elsewhere. + +### Asking for help + +If you have reviewed existing documentation and still have questions, or you are having problems, you can get help in the following ways: + +- **Asking in the support Telegram:** The [Foundry Support Telegram][support-tg] is a fast and easy way to ask questions. +- **Opening a discussion:** This repository comes with a discussions board where you can also ask for help. Click the "Discussions" tab at the top. + +As Foundry is still in heavy development, the documentation can be a bit scattered. +The [Foundry Book][foundry-book] is our current best-effort attempt at keeping up-to-date information. + +### Submitting a bug report + +When filing a new bug report in the issue tracker, you will be presented with a basic form to fill out. + +If you believe that you have uncovered a bug, please fill out the form to the best of your ability. Do not worry if you cannot answer every detail; just fill in what you can. Contributors will ask follow-up questions if something is unclear. + +The most important pieces of information we need in a bug report are: + +- The Foundry version you are on (and that it is up to date) +- The platform you are on (Windows, macOS, an M1 Mac or Linux) +- Code snippets if this is happening in relation to testing or building code +- Concrete steps to reproduce the bug + +In order to rule out the possibility of the bug being in your project, the code snippets should be as minimal +as possible. It is better if you can reproduce the bug with a small snippet as opposed to an entire project! + +See [this guide][mcve] on how to create a minimal, complete, and verifiable example. + +### Submitting a feature request + +When adding a feature request in the issue tracker, you will be presented with a basic form to fill out. + +Please include as detailed of an explanation as possible of the feature you would like, adding additional context if necessary. + +If you have examples of other tools that have the feature you are requesting, please include them as well. + +### Resolving an issue + +Pull requests are the way concrete changes are made to the code, documentation, and dependencies of Foundry. + +Even minor pull requests, such as those fixing wording, are greatly appreciated. Before making a large change, it is usually +a good idea to first open an issue describing the change to solicit feedback and guidance. This will increase +the likelihood of the PR getting merged. + +Please make sure that the following commands pass if you have changed the code: + +```sh +forge fmt --check +forge test -vvv +``` + +To make sure your changes are compatible with all compiler version targets, run the following commands: + +```sh +forge build --skip test --use solc:0.6.2 +forge build --skip test --use solc:0.6.12 +forge build --skip test --use solc:0.7.0 +forge build --skip test --use solc:0.7.6 +forge build --skip test --use solc:0.8.0 +``` + +The CI will also ensure that the code is formatted correctly and that the tests are passing across all compiler version targets. + +#### Adding cheatcodes + +Please follow the guide outlined in the [cheatcodes](https://github.com/foundry-rs/foundry/blob/master/docs/dev/cheatcodes.md#adding-a-new-cheatcode) documentation of Foundry. + +When making modifications to the native cheatcodes or adding new ones, please make sure to run [`./scripts/vm.py`](./scripts/vm.py) to update the cheatcodes in the [`src/Vm.sol`](./src/Vm.sol) file. + +By default the script will automatically generate the cheatcodes from the [`cheatcodes.json`](https://raw.githubusercontent.com/foundry-rs/foundry/master/crates/cheatcodes/assets/cheatcodes.json) file but alternatively you can provide a path to a JSON file containing the Vm interface, as generated by Foundry, with the `--from` flag. + +```sh +./scripts/vm.py --from path/to/cheatcodes.json +``` + +It is possible that the resulting [`src/Vm.sol`](./src/Vm.sol) file will have some changes that are not directly related to your changes, this is not a problem. + +#### Commits + +It is a recommended best practice to keep your changes as logically grouped as possible within individual commits. There is no limit to the number of commits any single pull request may have, and many contributors find it easier to review changes that are split across multiple commits. + +That said, if you have a number of commits that are "checkpoints" and don't represent a single logical change, please squash those together. + +#### Opening the pull request + +From within GitHub, opening a new pull request will present you with a template that should be filled out. Please try your best at filling out the details, but feel free to skip parts if you're not sure what to put. + +#### Discuss and update + +You will probably get feedback or requests for changes to your pull request. +This is a big part of the submission process, so don't be discouraged! Some contributors may sign off on the pull request right away, others may have more detailed comments or feedback. +This is a necessary part of the process in order to evaluate whether the changes are correct and necessary. + +**Any community member can review a PR, so you might get conflicting feedback**. +Keep an eye out for comments from code owners to provide guidance on conflicting feedback. + +#### Reviewing pull requests + +**Any Foundry community member is welcome to review any pull request**. + +All contributors who choose to review and provide feedback on pull requests have a responsibility to both the project and individual making the contribution. Reviews and feedback must be helpful, insightful, and geared towards improving the contribution as opposed to simply blocking it. If there are reasons why you feel the PR should not be merged, explain what those are. Do not expect to be able to block a PR from advancing simply because you say "no" without giving an explanation. Be open to having your mind changed. Be open to working _with_ the contributor to make the pull request better. + +Reviews that are dismissive or disrespectful of the contributor or any other reviewers are strictly counter to the Code of Conduct. + +When reviewing a pull request, the primary goals are for the codebase to improve and for the person submitting the request to succeed. **Even if a pull request is not merged, the submitter should come away from the experience feeling like their effort was not unappreciated**. Every PR from a new contributor is an opportunity to grow the community. + +##### Review a bit at a time + +Do not overwhelm new contributors. + +It is tempting to micro-optimize and make everything about relative performance, perfect grammar, or exact style matches. Do not succumb to that temptation.. + +Focus first on the most significant aspects of the change: + +1. Does this change make sense for Foundry? +2. Does this change make Foundry better, even if only incrementally? +3. Are there clear bugs or larger scale issues that need attending? +4. Are the commit messages readable and correct? If it contains a breaking change, is it clear enough? + +Note that only **incremental** improvement is needed to land a PR. This means that the PR does not need to be perfect, only better than the status quo. Follow-up PRs may be opened to continue iterating. + +When changes are necessary, _request_ them, do not _demand_ them, and **do not assume that the submitter already knows how to add a test or run a benchmark**. + +Specific performance optimization techniques, coding styles and conventions change over time. The first impression you give to a new contributor never does. + +Nits (requests for small changes that are not essential) are fine, but try to avoid stalling the pull request. Most nits can typically be fixed by the Foundry maintainers merging the pull request, but they can also be an opportunity for the contributor to learn a bit more about the project. + +It is always good to clearly indicate nits when you comment, e.g.: `Nit: change foo() to bar(). But this is not blocking`. + +If your comments were addressed but were not folded after new commits, or if they proved to be mistaken, please, [hide them][hiding-a-comment] with the appropriate reason to keep the conversation flow concise and relevant. + +##### Be aware of the person behind the code + +Be aware that _how_ you communicate requests and reviews in your feedback can have a significant impact on the success of the pull request. Yes, we may merge a particular change that makes Foundry better, but the individual might just not want to have anything to do with Foundry ever again. The goal is not just having good code. + +##### Abandoned or stale pull requests + +If a pull request appears to be abandoned or stalled, it is polite to first check with the contributor to see if they intend to continue the work before checking if they would mind if you took it over (especially if it just has nits left). When doing so, it is courteous to give the original contributor credit for the work they started, either by preserving their name and e-mail address in the commit log, or by using the `Author: ` or `Co-authored-by: ` metadata tag in the commits. + +_Adapted from the [ethers-rs contributing guide](https://github.com/gakonst/ethers-rs/blob/master/CONTRIBUTING.md)_. + +### Releasing + +Releases are automatically done by the release workflow when a tag is pushed, however, these steps still need to be taken: + +1. Ensure that the versions in the relevant `Cargo.toml` files are up-to-date. +2. Update documentation links +3. Perform a final audit for breaking changes. + +[rust-coc]: https://github.com/rust-lang/rust/blob/master/CODE_OF_CONDUCT.md +[dev-tg]: https://t.me/foundry_rs +[foundry-book]: https://github.com/foundry-rs/foundry-book +[support-tg]: https://t.me/foundry_support +[mcve]: https://stackoverflow.com/help/mcve +[hiding-a-comment]: https://help.github.com/articles/managing-disruptive-comments/#hiding-a-comment \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/LICENSE-APACHE b/packages/wallet/wallet-contracts/Counter/lib/forge-std/LICENSE-APACHE new file mode 100644 index 0000000000..cf01a499fb --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/LICENSE-APACHE @@ -0,0 +1,203 @@ +Copyright Contributors to Forge Standard Library + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/LICENSE-MIT b/packages/wallet/wallet-contracts/Counter/lib/forge-std/LICENSE-MIT new file mode 100644 index 0000000000..28f98304ac --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright Contributors to Forge Standard Library + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE O THE USE OR OTHER +DEALINGS IN THE SOFTWARE.R diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/README.md b/packages/wallet/wallet-contracts/Counter/lib/forge-std/README.md new file mode 100644 index 0000000000..51673e5ee9 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/README.md @@ -0,0 +1,266 @@ +# Forge Standard Library • [![CI status](https://github.com/foundry-rs/forge-std/actions/workflows/ci.yml/badge.svg)](https://github.com/foundry-rs/forge-std/actions/workflows/ci.yml) + +Forge Standard Library is a collection of helpful contracts and libraries for use with [Forge and Foundry](https://github.com/foundry-rs/foundry). It leverages Forge's cheatcodes to make writing tests easier and faster, while improving the UX of cheatcodes. + +**Learn how to use Forge-Std with the [šŸ“– Foundry Book (Forge-Std Guide)](https://getfoundry.sh/reference/forge-std/overview/).** + +## Install + +```bash +forge install foundry-rs/forge-std +``` + +## Contracts +### stdError + +This is a helper contract for errors and reverts. In Forge, this contract is particularly helpful for the `expectRevert` cheatcode, as it provides all compiler built-in errors. + +See the contract itself for all error codes. + +#### Example usage + +```solidity + +import "forge-std/Test.sol"; + +contract TestContract is Test { + ErrorsTest test; + + function setUp() public { + test = new ErrorsTest(); + } + + function testExpectArithmetic() public { + vm.expectRevert(stdError.arithmeticError); + test.arithmeticError(10); + } +} + +contract ErrorsTest { + function arithmeticError(uint256 a) public { + a = a - 100; + } +} +``` + +### stdStorage + +This is a rather large contract due to all of the overloading to make the UX decent. Primarily, it is a wrapper around the `record` and `accesses` cheatcodes. It can *always* find and write the storage slot(s) associated with a particular variable without knowing the storage layout. The one _major_ caveat to this is while a slot can be found for packed storage variables, we can't write to that variable safely. If a user tries to write to a packed slot, the execution throws an error, unless it is uninitialized (`bytes32(0)`). + +This works by recording all `SLOAD`s and `SSTORE`s during a function call. If there is a single slot read or written to, it immediately returns the slot. Otherwise, behind the scenes, we iterate through and check each one (assuming the user passed in a `depth` parameter). If the variable is a struct, you can pass in a `depth` parameter which is basically the field depth. + +I.e.: +```solidity +struct T { + // depth 0 + uint256 a; + // depth 1 + uint256 b; +} +``` + +#### Example usage + +```solidity +import "forge-std/Test.sol"; + +contract TestContract is Test { + using stdStorage for StdStorage; + + Storage test; + + function setUp() public { + test = new Storage(); + } + + function testFindExists() public { + // Lets say we want to find the slot for the public + // variable `exists`. We just pass in the function selector + // to the `find` command + uint256 slot = stdstore.target(address(test)).sig("exists()").find(); + assertEq(slot, 0); + } + + function testWriteExists() public { + // Lets say we want to write to the slot for the public + // variable `exists`. We just pass in the function selector + // to the `checked_write` command + stdstore.target(address(test)).sig("exists()").checked_write(100); + assertEq(test.exists(), 100); + } + + // It supports arbitrary storage layouts, like assembly based storage locations + function testFindHidden() public { + // `hidden` is a random hash of a bytes, iteration through slots would + // not find it. Our mechanism does + // Also, you can use the selector instead of a string + uint256 slot = stdstore.target(address(test)).sig(test.hidden.selector).find(); + assertEq(slot, uint256(keccak256("my.random.var"))); + } + + // If targeting a mapping, you have to pass in the keys necessary to perform the find + // i.e.: + function testFindMapping() public { + uint256 slot = stdstore + .target(address(test)) + .sig(test.map_addr.selector) + .with_key(address(this)) + .find(); + // in the `Storage` constructor, we wrote that this address' value was 1 in the map + // so when we load the slot, we expect it to be 1 + assertEq(uint(vm.load(address(test), bytes32(slot))), 1); + } + + // If the target is a struct, you can specify the field depth: + function testFindStruct() public { + // NOTE: see the depth parameter - 0 means 0th field, 1 means 1st field, etc. + uint256 slot_for_a_field = stdstore + .target(address(test)) + .sig(test.basicStruct.selector) + .depth(0) + .find(); + + uint256 slot_for_b_field = stdstore + .target(address(test)) + .sig(test.basicStruct.selector) + .depth(1) + .find(); + + assertEq(uint(vm.load(address(test), bytes32(slot_for_a_field))), 1); + assertEq(uint(vm.load(address(test), bytes32(slot_for_b_field))), 2); + } +} + +// A complex storage contract +contract Storage { + struct UnpackedStruct { + uint256 a; + uint256 b; + } + + constructor() { + map_addr[msg.sender] = 1; + } + + uint256 public exists = 1; + mapping(address => uint256) public map_addr; + // mapping(address => Packed) public map_packed; + mapping(address => UnpackedStruct) public map_struct; + mapping(address => mapping(address => uint256)) public deep_map; + mapping(address => mapping(address => UnpackedStruct)) public deep_map_struct; + UnpackedStruct public basicStruct = UnpackedStruct({ + a: 1, + b: 2 + }); + + function hidden() public view returns (bytes32 t) { + // an extremely hidden storage slot + bytes32 slot = keccak256("my.random.var"); + assembly { + t := sload(slot) + } + } +} +``` + +### stdCheats + +This is a wrapper over miscellaneous cheatcodes that need wrappers to be more dev friendly. Currently there are only functions related to `prank`. In general, users may expect ETH to be put into an address on `prank`, but this is not the case for safety reasons. Explicitly this `hoax` function should only be used for addresses that have expected balances as it will get overwritten. If an address already has ETH, you should just use `prank`. If you want to change that balance explicitly, just use `deal`. If you want to do both, `hoax` is also right for you. + + +#### Example usage: +```solidity + +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import "forge-std/Test.sol"; + +// Inherit the stdCheats +contract StdCheatsTest is Test { + Bar test; + function setUp() public { + test = new Bar(); + } + + function testHoax() public { + // we call `hoax`, which gives the target address + // eth and then calls `prank` + hoax(address(1337)); + test.bar{value: 100}(address(1337)); + + // overloaded to allow you to specify how much eth to + // initialize the address with + hoax(address(1337), 1); + test.bar{value: 1}(address(1337)); + } + + function testStartHoax() public { + // we call `startHoax`, which gives the target address + // eth and then calls `startPrank` + // + // it is also overloaded so that you can specify an eth amount + startHoax(address(1337)); + test.bar{value: 100}(address(1337)); + test.bar{value: 100}(address(1337)); + vm.stopPrank(); + test.bar(address(this)); + } +} + +contract Bar { + function bar(address expectedSender) public payable { + require(msg.sender == expectedSender, "!prank"); + } +} +``` + +### Std Assertions + +Contains various assertions. + +### `console.log` + +Usage follows the same format as [Hardhat](https://hardhat.org/hardhat-network/reference/#console-log). +It's recommended to use `console2.sol` as shown below, as this will show the decoded logs in Forge traces. + +```solidity +// import it indirectly via Test.sol +import "forge-std/Test.sol"; +// or directly import it +import "forge-std/console2.sol"; +... +console2.log(someValue); +``` + +If you need compatibility with Hardhat, you must use the standard `console.sol` instead. +Due to a bug in `console.sol`, logs that use `uint256` or `int256` types will not be properly decoded in Forge traces. + +```solidity +// import it indirectly via Test.sol +import "forge-std/Test.sol"; +// or directly import it +import "forge-std/console.sol"; +... +console.log(someValue); +``` + +## Contributing + +See our [contributing guidelines](./CONTRIBUTING.md). + +## Getting Help + +First, see if the answer to your question can be found in [book](https://book.getfoundry.sh). + +If the answer is not there: + +- Join the [support Telegram](https://t.me/foundry_support) to get help, or +- Open a [discussion](https://github.com/foundry-rs/foundry/discussions/new/choose) with your question, or +- Open an issue with [the bug](https://github.com/foundry-rs/foundry/issues/new/choose) + +If you want to contribute, or follow along with contributor discussion, you can use our [main telegram](https://t.me/foundry_rs) to chat with us about the development of Foundry! + +## License + +Forge Standard Library is offered under either [MIT](LICENSE-MIT) or [Apache 2.0](LICENSE-APACHE) license. diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/RELEASE_CHECKLIST.md b/packages/wallet/wallet-contracts/Counter/lib/forge-std/RELEASE_CHECKLIST.md new file mode 100644 index 0000000000..4611de4dce --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/RELEASE_CHECKLIST.md @@ -0,0 +1,12 @@ +# Release checklist + +This checklist is meant to be used as a guide for the `forge-std` release process. + +## Steps + +- [ ] Update the version number in `package.json` +- [ ] Open and merge a PR with the version bump +- [ ] Tag the merged commit with the version number: `git tag v` +- [ ] Push the tag to the repository: `git push --tags` +- [ ] Create a new GitHub release with the automatically generated changelog and with the name set to `v` +- [ ] Add `## Featured Changes` section to the top of the release notes diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/foundry.toml b/packages/wallet/wallet-contracts/Counter/lib/forge-std/foundry.toml new file mode 100644 index 0000000000..b68bd546cc --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/foundry.toml @@ -0,0 +1,27 @@ +[profile.default] +fs_permissions = [{ access = "read-write", path = "./" }] +optimizer = true +optimizer_runs = 200 + +# A list of solidity error codes to ignore. +# 3860 = init-code-size +ignored_error_codes = [3860] + +[rpc_endpoints] +# The RPC URLs are modified versions of the default for testing initialization. +mainnet = "https://eth.merkle.io" # Different API key. +optimism_sepolia = "https://sepolia.optimism.io/" # Adds a trailing slash. +arbitrum_one_sepolia = "https://sepolia-rollup.arbitrum.io/rpc/" # Adds a trailing slash. +needs_undefined_env_var = "${UNDEFINED_RPC_URL_PLACEHOLDER}" + +[fmt] +# These are all the `forge fmt` defaults. +line_length = 120 +tab_width = 4 +bracket_spacing = false +int_types = 'long' +multiline_func_header = 'attributes_first' +quote_style = 'double' +number_underscore = 'preserve' +single_line_statement_blocks = 'preserve' +ignore = ["src/console.sol", "src/console2.sol"] diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/package.json b/packages/wallet/wallet-contracts/Counter/lib/forge-std/package.json new file mode 100644 index 0000000000..09f5717329 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/package.json @@ -0,0 +1,16 @@ +{ + "name": "forge-std", + "version": "1.11.0", + "description": "Forge Standard Library is a collection of helpful contracts and libraries for use with Forge and Foundry.", + "homepage": "https://book.getfoundry.sh/forge/forge-std", + "bugs": "https://github.com/foundry-rs/forge-std/issues", + "license": "(Apache-2.0 OR MIT)", + "author": "Contributors to Forge Standard Library", + "files": [ + "src/**/*" + ], + "repository": { + "type": "git", + "url": "https://github.com/foundry-rs/forge-std.git" + } +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/scripts/vm.py b/packages/wallet/wallet-contracts/Counter/lib/forge-std/scripts/vm.py new file mode 100644 index 0000000000..3cd047d36d --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/scripts/vm.py @@ -0,0 +1,646 @@ +#!/usr/bin/env python3 + +import argparse +import copy +import json +import re +import subprocess +from enum import Enum as PyEnum +from pathlib import Path +from typing import Callable +from urllib import request + +VoidFn = Callable[[], None] + +CHEATCODES_JSON_URL = "https://raw.githubusercontent.com/foundry-rs/foundry/master/crates/cheatcodes/assets/cheatcodes.json" +OUT_PATH = "src/Vm.sol" + +VM_SAFE_DOC = """\ +/// The `VmSafe` interface does not allow manipulation of the EVM state or other actions that may +/// result in Script simulations differing from on-chain execution. It is recommended to only use +/// these cheats in scripts. +""" + +VM_DOC = """\ +/// The `Vm` interface does allow manipulation of the EVM state. These are all intended to be used +/// in tests, but it is not recommended to use these cheats in scripts. +""" + + +def main(): + parser = argparse.ArgumentParser( + description="Generate Vm.sol based on the cheatcodes json created by Foundry") + parser.add_argument( + "--from", + metavar="PATH", + dest="path", + required=False, + help="path to a json file containing the Vm interface, as generated by Foundry") + args = parser.parse_args() + json_str = request.urlopen(CHEATCODES_JSON_URL).read().decode("utf-8") if args.path is None else Path(args.path).read_text() + contract = Cheatcodes.from_json(json_str) + + ccs = contract.cheatcodes + ccs = list(filter(lambda cc: cc.status not in ["experimental", "internal"], ccs)) + ccs.sort(key=lambda cc: cc.func.id) + + safe = list(filter(lambda cc: cc.safety == "safe", ccs)) + safe.sort(key=CmpCheatcode) + unsafe = list(filter(lambda cc: cc.safety == "unsafe", ccs)) + unsafe.sort(key=CmpCheatcode) + assert len(safe) + len(unsafe) == len(ccs) + + prefix_with_group_headers(safe) + prefix_with_group_headers(unsafe) + + out = "" + + out += "// Automatically @generated by scripts/vm.py. Do not modify manually.\n\n" + + pp = CheatcodesPrinter( + spdx_identifier="MIT OR Apache-2.0", + solidity_requirement=">=0.6.2 <0.9.0", + abicoder_pragma=True, + ) + pp.p_prelude() + pp.prelude = False + out += pp.finish() + + out += "\n\n" + out += VM_SAFE_DOC + vm_safe = Cheatcodes( + # TODO: Custom errors were introduced in 0.8.4 + errors=[], # contract.errors + events=contract.events, + enums=contract.enums, + structs=contract.structs, + cheatcodes=safe, + ) + pp.p_contract(vm_safe, "VmSafe") + out += pp.finish() + + out += "\n\n" + out += VM_DOC + vm_unsafe = Cheatcodes( + errors=[], + events=[], + enums=[], + structs=[], + cheatcodes=unsafe, + ) + pp.p_contract(vm_unsafe, "Vm", "VmSafe") + out += pp.finish() + + # Compatibility with <0.8.0 + def memory_to_calldata(m: re.Match) -> str: + return " calldata " + m.group(1) + + out = re.sub(r" memory (.*returns)", memory_to_calldata, out) + + with open(OUT_PATH, "w") as f: + f.write(out) + + forge_fmt = ["forge", "fmt", OUT_PATH] + res = subprocess.run(forge_fmt) + assert res.returncode == 0, f"command failed: {forge_fmt}" + + print(f"Wrote to {OUT_PATH}") + + +class CmpCheatcode: + cheatcode: "Cheatcode" + + def __init__(self, cheatcode: "Cheatcode"): + self.cheatcode = cheatcode + + def __lt__(self, other: "CmpCheatcode") -> bool: + return cmp_cheatcode(self.cheatcode, other.cheatcode) < 0 + + def __eq__(self, other: "CmpCheatcode") -> bool: + return cmp_cheatcode(self.cheatcode, other.cheatcode) == 0 + + def __gt__(self, other: "CmpCheatcode") -> bool: + return cmp_cheatcode(self.cheatcode, other.cheatcode) > 0 + + +def cmp_cheatcode(a: "Cheatcode", b: "Cheatcode") -> int: + if a.group != b.group: + return -1 if a.group < b.group else 1 + if a.status != b.status: + return -1 if a.status < b.status else 1 + if a.safety != b.safety: + return -1 if a.safety < b.safety else 1 + if a.func.id != b.func.id: + return -1 if a.func.id < b.func.id else 1 + return 0 + + +# HACK: A way to add group header comments without having to modify printer code +def prefix_with_group_headers(cheats: list["Cheatcode"]): + s = set() + for i, cheat in enumerate(cheats): + if cheat.group in s: + continue + + s.add(cheat.group) + + c = copy.deepcopy(cheat) + c.func.description = "" + c.func.declaration = f"// ======== {group(c.group)} ========" + cheats.insert(i, c) + return cheats + + +def group(s: str) -> str: + if s == "evm": + return "EVM" + if s == "json": + return "JSON" + return s[0].upper() + s[1:] + + +class Visibility(PyEnum): + EXTERNAL: str = "external" + PUBLIC: str = "public" + INTERNAL: str = "internal" + PRIVATE: str = "private" + + def __str__(self): + return self.value + + +class Mutability(PyEnum): + PURE: str = "pure" + VIEW: str = "view" + NONE: str = "" + + def __str__(self): + return self.value + + +class Function: + id: str + description: str + declaration: str + visibility: Visibility + mutability: Mutability + signature: str + selector: str + selector_bytes: bytes + + def __init__( + self, + id: str, + description: str, + declaration: str, + visibility: Visibility, + mutability: Mutability, + signature: str, + selector: str, + selector_bytes: bytes, + ): + self.id = id + self.description = description + self.declaration = declaration + self.visibility = visibility + self.mutability = mutability + self.signature = signature + self.selector = selector + self.selector_bytes = selector_bytes + + @staticmethod + def from_dict(d: dict) -> "Function": + return Function( + d["id"], + d["description"], + d["declaration"], + Visibility(d["visibility"]), + Mutability(d["mutability"]), + d["signature"], + d["selector"], + bytes(d["selectorBytes"]), + ) + + +class Cheatcode: + func: Function + group: str + status: str + safety: str + + def __init__(self, func: Function, group: str, status: str, safety: str): + self.func = func + self.group = group + self.status = status + self.safety = safety + + @staticmethod + def from_dict(d: dict) -> "Cheatcode": + return Cheatcode( + Function.from_dict(d["func"]), + str(d["group"]), + str(d["status"]), + str(d["safety"]), + ) + + +class Error: + name: str + description: str + declaration: str + + def __init__(self, name: str, description: str, declaration: str): + self.name = name + self.description = description + self.declaration = declaration + + @staticmethod + def from_dict(d: dict) -> "Error": + return Error(**d) + + +class Event: + name: str + description: str + declaration: str + + def __init__(self, name: str, description: str, declaration: str): + self.name = name + self.description = description + self.declaration = declaration + + @staticmethod + def from_dict(d: dict) -> "Event": + return Event(**d) + + +class EnumVariant: + name: str + description: str + + def __init__(self, name: str, description: str): + self.name = name + self.description = description + + +class Enum: + name: str + description: str + variants: list[EnumVariant] + + def __init__(self, name: str, description: str, variants: list[EnumVariant]): + self.name = name + self.description = description + self.variants = variants + + @staticmethod + def from_dict(d: dict) -> "Enum": + return Enum( + d["name"], + d["description"], + list(map(lambda v: EnumVariant(**v), d["variants"])), + ) + + +class StructField: + name: str + ty: str + description: str + + def __init__(self, name: str, ty: str, description: str): + self.name = name + self.ty = ty + self.description = description + + +class Struct: + name: str + description: str + fields: list[StructField] + + def __init__(self, name: str, description: str, fields: list[StructField]): + self.name = name + self.description = description + self.fields = fields + + @staticmethod + def from_dict(d: dict) -> "Struct": + return Struct( + d["name"], + d["description"], + list(map(lambda f: StructField(**f), d["fields"])), + ) + + +class Cheatcodes: + errors: list[Error] + events: list[Event] + enums: list[Enum] + structs: list[Struct] + cheatcodes: list[Cheatcode] + + def __init__( + self, + errors: list[Error], + events: list[Event], + enums: list[Enum], + structs: list[Struct], + cheatcodes: list[Cheatcode], + ): + self.errors = errors + self.events = events + self.enums = enums + self.structs = structs + self.cheatcodes = cheatcodes + + @staticmethod + def from_dict(d: dict) -> "Cheatcodes": + return Cheatcodes( + errors=[Error.from_dict(e) for e in d["errors"]], + events=[Event.from_dict(e) for e in d["events"]], + enums=[Enum.from_dict(e) for e in d["enums"]], + structs=[Struct.from_dict(e) for e in d["structs"]], + cheatcodes=[Cheatcode.from_dict(e) for e in d["cheatcodes"]], + ) + + @staticmethod + def from_json(s) -> "Cheatcodes": + return Cheatcodes.from_dict(json.loads(s)) + + @staticmethod + def from_json_file(file_path: str) -> "Cheatcodes": + with open(file_path, "r") as f: + return Cheatcodes.from_dict(json.load(f)) + + +class Item(PyEnum): + ERROR: str = "error" + EVENT: str = "event" + ENUM: str = "enum" + STRUCT: str = "struct" + FUNCTION: str = "function" + + +class ItemOrder: + _list: list[Item] + + def __init__(self, list: list[Item]) -> None: + assert len(list) <= len(Item), "list must not contain more items than Item" + assert len(list) == len(set(list)), "list must not contain duplicates" + self._list = list + pass + + def get_list(self) -> list[Item]: + return self._list + + @staticmethod + def default() -> "ItemOrder": + return ItemOrder( + [ + Item.ERROR, + Item.EVENT, + Item.ENUM, + Item.STRUCT, + Item.FUNCTION, + ] + ) + + +class CheatcodesPrinter: + buffer: str + + prelude: bool + spdx_identifier: str + solidity_requirement: str + abicoder_v2: bool + + block_doc_style: bool + + indent_level: int + _indent_str: str + + nl_str: str + + items_order: ItemOrder + + def __init__( + self, + buffer: str = "", + prelude: bool = True, + spdx_identifier: str = "UNLICENSED", + solidity_requirement: str = "", + abicoder_pragma: bool = False, + block_doc_style: bool = False, + indent_level: int = 0, + indent_with: int | str = 4, + nl_str: str = "\n", + items_order: ItemOrder = ItemOrder.default(), + ): + self.prelude = prelude + self.spdx_identifier = spdx_identifier + self.solidity_requirement = solidity_requirement + self.abicoder_v2 = abicoder_pragma + self.block_doc_style = block_doc_style + self.buffer = buffer + self.indent_level = indent_level + self.nl_str = nl_str + + if isinstance(indent_with, int): + assert indent_with >= 0 + self._indent_str = " " * indent_with + elif isinstance(indent_with, str): + self._indent_str = indent_with + else: + assert False, "indent_with must be int or str" + + self.items_order = items_order + + def finish(self) -> str: + ret = self.buffer.rstrip() + self.buffer = "" + return ret + + def p_contract(self, contract: Cheatcodes, name: str, inherits: str = ""): + if self.prelude: + self.p_prelude(contract) + + self._p_str("interface ") + name = name.strip() + if name != "": + self._p_str(name) + self._p_str(" ") + if inherits != "": + self._p_str("is ") + self._p_str(inherits) + self._p_str(" ") + self._p_str("{") + self._p_nl() + self._with_indent(lambda: self._p_items(contract)) + self._p_str("}") + self._p_nl() + + def _p_items(self, contract: Cheatcodes): + for item in self.items_order.get_list(): + if item == Item.ERROR: + self.p_errors(contract.errors) + elif item == Item.EVENT: + self.p_events(contract.events) + elif item == Item.ENUM: + self.p_enums(contract.enums) + elif item == Item.STRUCT: + self.p_structs(contract.structs) + elif item == Item.FUNCTION: + self.p_functions(contract.cheatcodes) + else: + assert False, f"unknown item {item}" + + def p_prelude(self, contract: Cheatcodes | None = None): + self._p_str(f"// SPDX-License-Identifier: {self.spdx_identifier}") + self._p_nl() + + if self.solidity_requirement != "": + req = self.solidity_requirement + elif contract and len(contract.errors) > 0: + req = ">=0.8.4 <0.9.0" + else: + req = ">=0.6.0 <0.9.0" + self._p_str(f"pragma solidity {req};") + self._p_nl() + + if self.abicoder_v2: + self._p_str("pragma experimental ABIEncoderV2;") + self._p_nl() + + self._p_nl() + + def p_errors(self, errors: list[Error]): + for error in errors: + self._p_line(lambda: self.p_error(error)) + + def p_error(self, error: Error): + self._p_comment(error.description, doc=True) + self._p_line(lambda: self._p_str(error.declaration)) + + def p_events(self, events: list[Event]): + for event in events: + self._p_line(lambda: self.p_event(event)) + + def p_event(self, event: Event): + self._p_comment(event.description, doc=True) + self._p_line(lambda: self._p_str(event.declaration)) + + def p_enums(self, enums: list[Enum]): + for enum in enums: + self._p_line(lambda: self.p_enum(enum)) + + def p_enum(self, enum: Enum): + self._p_comment(enum.description, doc=True) + self._p_line(lambda: self._p_str(f"enum {enum.name} {{")) + self._with_indent(lambda: self.p_enum_variants(enum.variants)) + self._p_line(lambda: self._p_str("}")) + + def p_enum_variants(self, variants: list[EnumVariant]): + for i, variant in enumerate(variants): + self._p_indent() + self._p_comment(variant.description) + + self._p_indent() + self._p_str(variant.name) + if i < len(variants) - 1: + self._p_str(",") + self._p_nl() + + def p_structs(self, structs: list[Struct]): + for struct in structs: + self._p_line(lambda: self.p_struct(struct)) + + def p_struct(self, struct: Struct): + self._p_comment(struct.description, doc=True) + self._p_line(lambda: self._p_str(f"struct {struct.name} {{")) + self._with_indent(lambda: self.p_struct_fields(struct.fields)) + self._p_line(lambda: self._p_str("}")) + + def p_struct_fields(self, fields: list[StructField]): + for field in fields: + self._p_line(lambda: self.p_struct_field(field)) + + def p_struct_field(self, field: StructField): + self._p_comment(field.description) + self._p_indented(lambda: self._p_str(f"{field.ty} {field.name};")) + + def p_functions(self, cheatcodes: list[Cheatcode]): + for cheatcode in cheatcodes: + self._p_line(lambda: self.p_function(cheatcode.func)) + + def p_function(self, func: Function): + self._p_comment(func.description, doc=True) + self._p_line(lambda: self._p_str(func.declaration)) + + def _p_comment(self, s: str, doc: bool = False): + s = s.strip() + if s == "": + return + + s = map(lambda line: line.lstrip(), s.split("\n")) + if self.block_doc_style: + self._p_str("/*") + if doc: + self._p_str("*") + self._p_nl() + for line in s: + self._p_indent() + self._p_str(" ") + if doc: + self._p_str("* ") + self._p_str(line) + self._p_nl() + self._p_indent() + self._p_str(" */") + self._p_nl() + else: + first_line = True + for line in s: + if not first_line: + self._p_indent() + first_line = False + + if doc: + self._p_str("/// ") + else: + self._p_str("// ") + self._p_str(line) + self._p_nl() + + def _with_indent(self, f: VoidFn): + self._inc_indent() + f() + self._dec_indent() + + def _p_line(self, f: VoidFn): + self._p_indent() + f() + self._p_nl() + + def _p_indented(self, f: VoidFn): + self._p_indent() + f() + + def _p_indent(self): + for _ in range(self.indent_level): + self._p_str(self._indent_str) + + def _p_nl(self): + self._p_str(self.nl_str) + + def _p_str(self, txt: str): + self.buffer += txt + + def _inc_indent(self): + self.indent_level += 1 + + def _dec_indent(self): + self.indent_level -= 1 + + +if __name__ == "__main__": + main() diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/Base.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/Base.sol new file mode 100644 index 0000000000..52a508210a --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/Base.sol @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +import {StdStorage} from "./StdStorage.sol"; +import {Vm, VmSafe} from "./Vm.sol"; + +abstract contract CommonBase { + /// @dev Cheat code address. + /// Calculated as `address(uint160(uint256(keccak256("hevm cheat code"))))`. + address internal constant VM_ADDRESS = 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D; + + /// @dev console.sol and console2.sol work by executing a staticcall to this address. + /// Calculated as `address(uint160(uint88(bytes11("console.log"))))`. + address internal constant CONSOLE = 0x000000000000000000636F6e736F6c652e6c6f67; + + /// @dev Used when deploying with create2. + /// Taken from https://github.com/Arachnid/deterministic-deployment-proxy. + address internal constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C; + + /// @dev The default address for tx.origin and msg.sender. + /// Calculated as `address(uint160(uint256(keccak256("foundry default caller"))))`. + address internal constant DEFAULT_SENDER = 0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38; + + /// @dev The address of the first contract `CREATE`d by a running test contract. + /// When running tests, each test contract is `CREATE`d by `DEFAULT_SENDER` with nonce 1. + /// Calculated as `VM.computeCreateAddress(VM.computeCreateAddress(DEFAULT_SENDER, 1), 1)`. + address internal constant DEFAULT_TEST_CONTRACT = 0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f; + + /// @dev Deterministic deployment address of the Multicall3 contract. + /// Taken from https://www.multicall3.com. + address internal constant MULTICALL3_ADDRESS = 0xcA11bde05977b3631167028862bE2a173976CA11; + + /// @dev The order of the secp256k1 curve. + uint256 internal constant SECP256K1_ORDER = + 115792089237316195423570985008687907852837564279074904382605163141518161494337; + + uint256 internal constant UINT256_MAX = + 115792089237316195423570985008687907853269984665640564039457584007913129639935; + + Vm internal constant vm = Vm(VM_ADDRESS); + StdStorage internal stdstore; +} + +abstract contract TestBase is CommonBase {} + +abstract contract ScriptBase is CommonBase { + VmSafe internal constant vmSafe = VmSafe(VM_ADDRESS); +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/Config.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/Config.sol new file mode 100644 index 0000000000..1c63c8721b --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/Config.sol @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +import {console} from "./console.sol"; +import {StdConfig} from "./StdConfig.sol"; +import {CommonBase} from "./Base.sol"; + +/// @notice Boilerplate to streamline the setup of multi-chain environments. +abstract contract Config is CommonBase { + // -- STORAGE (CONFIG + CHAINS + FORKS) ------------------------------------ + + /// @dev Contract instance holding the data from the TOML config file. + StdConfig internal config; + + /// @dev Array of chain IDs for which forks have been created. + uint256[] internal chainIds; + + /// @dev A mapping from a chain ID to its initialized fork ID. + mapping(uint256 => uint256) internal forkOf; + + // -- HELPER FUNCTIONS ----------------------------------------------------- + + /// @notice Loads configuration from a file. + /// + /// @dev This function instantiates a `Config` contract, caching all its config variables. + /// + /// @param filePath: the path to the TOML configuration file. + /// @param writeToFile: whether updates are written back to the TOML file. + function _loadConfig(string memory filePath, bool writeToFile) internal { + console.log("----------"); + console.log(string.concat("Loading config from '", filePath, "'")); + config = new StdConfig(filePath, writeToFile); + vm.makePersistent(address(config)); + console.log("Config successfully loaded"); + console.log("----------"); + } + + /// @notice Loads configuration from a file and creates forks for each specified chain. + /// + /// @dev This function instantiates a `Config` contract, caching all its config variables, + /// reads the configured chain ids, and iterates through them to create a fork for each one. + /// It also creates a map `forkOf[chainId] -> forkId` to easily switch between forks. + /// + /// @param filePath: the path to the TOML configuration file. + /// @param writeToFile: whether updates are written back to the TOML file. + function _loadConfigAndForks(string memory filePath, bool writeToFile) internal { + _loadConfig(filePath, writeToFile); + + console.log("Setting up forks for the configured chains..."); + uint256[] memory chains = config.getChainIds(); + for (uint256 i = 0; i < chains.length; i++) { + uint256 chainId = chains[i]; + uint256 forkId = vm.createFork(config.getRpcUrl(chainId)); + forkOf[chainId] = forkId; + chainIds.push(chainId); + } + console.log("Forks successfully created"); + console.log("----------"); + } +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/LibVariable.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/LibVariable.sol new file mode 100644 index 0000000000..c46b15328d --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/LibVariable.sol @@ -0,0 +1,477 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +// Enable globally. +using LibVariable for Variable global; + +struct Variable { + Type ty; + bytes data; +} + +struct Type { + TypeKind kind; + bool isArray; +} + +enum TypeKind { + None, + Bool, + Address, + Bytes32, + Uint256, + Int256, + String, + Bytes +} + +/// @notice Library for type-safe coercion of the `Variable` struct to concrete types. +/// +/// @dev Ensures that when a `Variable` is cast to a concrete Solidity type, the operation is safe and the +/// underlying type matches what is expected. +/// Provides functions to check types, convert them to strings, and coerce `Variable` instances into +/// both single values and arrays of various types. +/// +/// Usage example: +/// ```solidity +/// import {LibVariable} from "./LibVariable.sol"; +/// +/// contract MyContract { +/// using LibVariable for Variable; +/// StdConfig config; // Assume 'config' is an instance of `StdConfig` and has already been loaded. +/// +/// function readValues() public { +/// // Retrieve a 'uint256' value from the config. +/// uint256 myNumber = config.get("important_number").toUint256(); +/// +/// // Would revert with `TypeMismatch` as 'important_number' isn't a `uint256` in the config file. +/// // string memory notANumber = config.get("important_number").toString(); +/// +/// // Retrieve a address array from the config. +/// string[] memory admins = config.get("whitelisted_admins").toAddressArray(); +/// } +/// } +/// ``` +library LibVariable { + error NotInitialized(); + error TypeMismatch(string expected, string actual); + error UnsafeCast(string message); + + // -- TYPE HELPERS ---------------------------------------------------- + + /// @notice Compares two Type instances for equality. + function isEqual(Type memory self, Type memory other) internal pure returns (bool) { + return self.kind == other.kind && self.isArray == other.isArray; + } + + /// @notice Compares two Type instances for equality. Reverts if they are not equal. + function assertEq(Type memory self, Type memory other) internal pure { + if (!isEqual(self, other)) { + revert TypeMismatch(toString(other), toString(self)); + } + } + + /// @notice Converts a Type struct to its full string representation (i.e. "uint256[]"). + function toString(Type memory self) internal pure returns (string memory) { + string memory tyStr = toString(self.kind); + if (!self.isArray || self.kind == TypeKind.None) { + return tyStr; + } else { + return string.concat(tyStr, "[]"); + } + } + + /// @dev Converts a `TypeKind` enum to its base string representation. + function toString(TypeKind self) internal pure returns (string memory) { + if (self == TypeKind.Bool) return "bool"; + if (self == TypeKind.Address) return "address"; + if (self == TypeKind.Bytes32) return "bytes32"; + if (self == TypeKind.Uint256) return "uint256"; + if (self == TypeKind.Int256) return "int256"; + if (self == TypeKind.String) return "string"; + if (self == TypeKind.Bytes) return "bytes"; + return "none"; + } + + /// @dev Converts a `TypeKind` enum to its base string representation. + function toTomlKey(TypeKind self) internal pure returns (string memory) { + if (self == TypeKind.Bool) return "bool"; + if (self == TypeKind.Address) return "address"; + if (self == TypeKind.Bytes32) return "bytes32"; + if (self == TypeKind.Uint256) return "uint"; + if (self == TypeKind.Int256) return "int"; + if (self == TypeKind.String) return "string"; + if (self == TypeKind.Bytes) return "bytes"; + return "none"; + } + + // -- VARIABLE HELPERS ---------------------------------------------------- + + /// @dev Checks if a `Variable` has been initialized and matches the expected type reverting if not. + modifier check(Variable memory self, Type memory expected) { + assertExists(self); + assertEq(self.ty, expected); + _; + } + + /// @dev Checks if a `Variable` has been initialized, reverting if not. + function assertExists(Variable memory self) public pure { + if (self.ty.kind == TypeKind.None) { + revert NotInitialized(); + } + } + + // -- VARIABLE COERCION FUNCTIONS (SINGLE VALUES) -------------------------- + + /// @notice Coerces a `Variable` to a `bool` value. + function toBool(Variable memory self) internal pure check(self, Type(TypeKind.Bool, false)) returns (bool) { + return abi.decode(self.data, (bool)); + } + + /// @notice Coerces a `Variable` to an `address` value. + function toAddress(Variable memory self) + internal + pure + check(self, Type(TypeKind.Address, false)) + returns (address) + { + return abi.decode(self.data, (address)); + } + + /// @notice Coerces a `Variable` to a `bytes32` value. + function toBytes32(Variable memory self) + internal + pure + check(self, Type(TypeKind.Bytes32, false)) + returns (bytes32) + { + return abi.decode(self.data, (bytes32)); + } + + /// @notice Coerces a `Variable` to a `uint256` value. + function toUint256(Variable memory self) + internal + pure + check(self, Type(TypeKind.Uint256, false)) + returns (uint256) + { + return abi.decode(self.data, (uint256)); + } + + /// @notice Coerces a `Variable` to a `uint128` value, checking for overflow. + function toUint128(Variable memory self) internal pure returns (uint128) { + uint256 value = self.toUint256(); + if (value > type(uint128).max) { + revert UnsafeCast("value does not fit in 'uint128'"); + } + return uint128(value); + } + + /// @notice Coerces a `Variable` to a `uint64` value, checking for overflow. + function toUint64(Variable memory self) internal pure returns (uint64) { + uint256 value = self.toUint256(); + if (value > type(uint64).max) { + revert UnsafeCast("value does not fit in 'uint64'"); + } + return uint64(value); + } + + /// @notice Coerces a `Variable` to a `uint32` value, checking for overflow. + function toUint32(Variable memory self) internal pure returns (uint32) { + uint256 value = self.toUint256(); + if (value > type(uint32).max) { + revert UnsafeCast("value does not fit in 'uint32'"); + } + return uint32(value); + } + + /// @notice Coerces a `Variable` to a `uint16` value, checking for overflow. + function toUint16(Variable memory self) internal pure returns (uint16) { + uint256 value = self.toUint256(); + if (value > type(uint16).max) { + revert UnsafeCast("value does not fit in 'uint16'"); + } + return uint16(value); + } + + /// @notice Coerces a `Variable` to a `uint8` value, checking for overflow. + function toUint8(Variable memory self) internal pure returns (uint8) { + uint256 value = self.toUint256(); + if (value > type(uint8).max) { + revert UnsafeCast("value does not fit in 'uint8'"); + } + return uint8(value); + } + + /// @notice Coerces a `Variable` to an `int256` value. + function toInt256(Variable memory self) internal pure check(self, Type(TypeKind.Int256, false)) returns (int256) { + return abi.decode(self.data, (int256)); + } + + /// @notice Coerces a `Variable` to an `int128` value, checking for overflow/underflow. + function toInt128(Variable memory self) internal pure returns (int128) { + int256 value = self.toInt256(); + if (value > type(int128).max || value < type(int128).min) { + revert UnsafeCast("value does not fit in 'int128'"); + } + return int128(value); + } + + /// @notice Coerces a `Variable` to an `int64` value, checking for overflow/underflow. + function toInt64(Variable memory self) internal pure returns (int64) { + int256 value = self.toInt256(); + if (value > type(int64).max || value < type(int64).min) { + revert UnsafeCast("value does not fit in 'int64'"); + } + return int64(value); + } + + /// @notice Coerces a `Variable` to an `int32` value, checking for overflow/underflow. + function toInt32(Variable memory self) internal pure returns (int32) { + int256 value = self.toInt256(); + if (value > type(int32).max || value < type(int32).min) { + revert UnsafeCast("value does not fit in 'int32'"); + } + return int32(value); + } + + /// @notice Coerces a `Variable` to an `int16` value, checking for overflow/underflow. + function toInt16(Variable memory self) internal pure returns (int16) { + int256 value = self.toInt256(); + if (value > type(int16).max || value < type(int16).min) { + revert UnsafeCast("value does not fit in 'int16'"); + } + return int16(value); + } + + /// @notice Coerces a `Variable` to an `int8` value, checking for overflow/underflow. + function toInt8(Variable memory self) internal pure returns (int8) { + int256 value = self.toInt256(); + if (value > type(int8).max || value < type(int8).min) { + revert UnsafeCast("value does not fit in 'int8'"); + } + return int8(value); + } + + /// @notice Coerces a `Variable` to a `string` value. + function toString(Variable memory self) + internal + pure + check(self, Type(TypeKind.String, false)) + returns (string memory) + { + return abi.decode(self.data, (string)); + } + + /// @notice Coerces a `Variable` to a `bytes` value. + function toBytes(Variable memory self) + internal + pure + check(self, Type(TypeKind.Bytes, false)) + returns (bytes memory) + { + return abi.decode(self.data, (bytes)); + } + + // -- VARIABLE COERCION FUNCTIONS (ARRAYS) --------------------------------- + + /// @notice Coerces a `Variable` to a `bool` array. + function toBoolArray(Variable memory self) + internal + pure + check(self, Type(TypeKind.Bool, true)) + returns (bool[] memory) + { + return abi.decode(self.data, (bool[])); + } + + /// @notice Coerces a `Variable` to an `address` array. + function toAddressArray(Variable memory self) + internal + pure + check(self, Type(TypeKind.Address, true)) + returns (address[] memory) + { + return abi.decode(self.data, (address[])); + } + + /// @notice Coerces a `Variable` to a `bytes32` array. + function toBytes32Array(Variable memory self) + internal + pure + check(self, Type(TypeKind.Bytes32, true)) + returns (bytes32[] memory) + { + return abi.decode(self.data, (bytes32[])); + } + + /// @notice Coerces a `Variable` to a `uint256` array. + function toUint256Array(Variable memory self) + internal + pure + check(self, Type(TypeKind.Uint256, true)) + returns (uint256[] memory) + { + return abi.decode(self.data, (uint256[])); + } + + /// @notice Coerces a `Variable` to a `uint128` array, checking for overflow. + function toUint128Array(Variable memory self) internal pure returns (uint128[] memory) { + uint256[] memory values = self.toUint256Array(); + uint128[] memory result = new uint128[](values.length); + for (uint256 i = 0; i < values.length; i++) { + if (values[i] > type(uint128).max) { + revert UnsafeCast("value in array does not fit in 'uint128'"); + } + result[i] = uint128(values[i]); + } + return result; + } + + /// @notice Coerces a `Variable` to a `uint64` array, checking for overflow. + function toUint64Array(Variable memory self) internal pure returns (uint64[] memory) { + uint256[] memory values = self.toUint256Array(); + uint64[] memory result = new uint64[](values.length); + for (uint256 i = 0; i < values.length; i++) { + if (values[i] > type(uint64).max) { + revert UnsafeCast("value in array does not fit in 'uint64'"); + } + result[i] = uint64(values[i]); + } + return result; + } + + /// @notice Coerces a `Variable` to a `uint32` array, checking for overflow. + function toUint32Array(Variable memory self) internal pure returns (uint32[] memory) { + uint256[] memory values = self.toUint256Array(); + uint32[] memory result = new uint32[](values.length); + for (uint256 i = 0; i < values.length; i++) { + if (values[i] > type(uint32).max) { + revert UnsafeCast("value in array does not fit in 'uint32'"); + } + result[i] = uint32(values[i]); + } + return result; + } + + /// @notice Coerces a `Variable` to a `uint16` array, checking for overflow. + function toUint16Array(Variable memory self) internal pure returns (uint16[] memory) { + uint256[] memory values = self.toUint256Array(); + uint16[] memory result = new uint16[](values.length); + for (uint256 i = 0; i < values.length; i++) { + if (values[i] > type(uint16).max) { + revert UnsafeCast("value in array does not fit in 'uint16'"); + } + result[i] = uint16(values[i]); + } + return result; + } + + /// @notice Coerces a `Variable` to a `uint8` array, checking for overflow. + function toUint8Array(Variable memory self) internal pure returns (uint8[] memory) { + uint256[] memory values = self.toUint256Array(); + uint8[] memory result = new uint8[](values.length); + for (uint256 i = 0; i < values.length; i++) { + if (values[i] > type(uint8).max) { + revert UnsafeCast("value in array does not fit in 'uint8'"); + } + result[i] = uint8(values[i]); + } + return result; + } + + /// @notice Coerces a `Variable` to an `int256` array. + function toInt256Array(Variable memory self) + internal + pure + check(self, Type(TypeKind.Int256, true)) + returns (int256[] memory) + { + return abi.decode(self.data, (int256[])); + } + + /// @notice Coerces a `Variable` to a `int128` array, checking for overflow/underflow. + function toInt128Array(Variable memory self) internal pure returns (int128[] memory) { + int256[] memory values = self.toInt256Array(); + int128[] memory result = new int128[](values.length); + for (uint256 i = 0; i < values.length; i++) { + if (values[i] > type(int128).max || values[i] < type(int128).min) { + revert UnsafeCast("value in array does not fit in 'int128'"); + } + result[i] = int128(values[i]); + } + return result; + } + + /// @notice Coerces a `Variable` to a `int64` array, checking for overflow/underflow. + function toInt64Array(Variable memory self) internal pure returns (int64[] memory) { + int256[] memory values = self.toInt256Array(); + int64[] memory result = new int64[](values.length); + for (uint256 i = 0; i < values.length; i++) { + if (values[i] > type(int64).max || values[i] < type(int64).min) { + revert UnsafeCast("value in array does not fit in 'int64'"); + } + result[i] = int64(values[i]); + } + return result; + } + + /// @notice Coerces a `Variable` to a `int32` array, checking for overflow/underflow. + function toInt32Array(Variable memory self) internal pure returns (int32[] memory) { + int256[] memory values = self.toInt256Array(); + int32[] memory result = new int32[](values.length); + for (uint256 i = 0; i < values.length; i++) { + if (values[i] > type(int32).max || values[i] < type(int32).min) { + revert UnsafeCast("value in array does not fit in 'int32'"); + } + result[i] = int32(values[i]); + } + return result; + } + + /// @notice Coerces a `Variable` to a `int16` array, checking for overflow/underflow. + function toInt16Array(Variable memory self) internal pure returns (int16[] memory) { + int256[] memory values = self.toInt256Array(); + int16[] memory result = new int16[](values.length); + for (uint256 i = 0; i < values.length; i++) { + if (values[i] > type(int16).max || values[i] < type(int16).min) { + revert UnsafeCast("value in array does not fit in 'int16'"); + } + result[i] = int16(values[i]); + } + return result; + } + + /// @notice Coerces a `Variable` to a `int8` array, checking for overflow/underflow. + function toInt8Array(Variable memory self) internal pure returns (int8[] memory) { + int256[] memory values = self.toInt256Array(); + int8[] memory result = new int8[](values.length); + for (uint256 i = 0; i < values.length; i++) { + if (values[i] > type(int8).max || values[i] < type(int8).min) { + revert UnsafeCast("value in array does not fit in 'int8'"); + } + result[i] = int8(values[i]); + } + return result; + } + + /// @notice Coerces a `Variable` to a `string` array. + function toStringArray(Variable memory self) + internal + pure + check(self, Type(TypeKind.String, true)) + returns (string[] memory) + { + return abi.decode(self.data, (string[])); + } + + /// @notice Coerces a `Variable` to a `bytes` array. + function toBytesArray(Variable memory self) + internal + pure + check(self, Type(TypeKind.Bytes, true)) + returns (bytes[] memory) + { + return abi.decode(self.data, (bytes[])); + } +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/Script.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/Script.sol new file mode 100644 index 0000000000..a2e2aa1cd0 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/Script.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +// šŸ’¬ ABOUT +// Forge Std's default Script. + +// 🧩 MODULES +import {console} from "./console.sol"; +import {console2} from "./console2.sol"; +import {safeconsole} from "./safeconsole.sol"; +import {StdChains} from "./StdChains.sol"; +import {StdCheatsSafe} from "./StdCheats.sol"; +import {StdConstants} from "./StdConstants.sol"; +import {stdJson} from "./StdJson.sol"; +import {stdMath} from "./StdMath.sol"; +import {StdStorage, stdStorageSafe} from "./StdStorage.sol"; +import {StdStyle} from "./StdStyle.sol"; +import {StdUtils} from "./StdUtils.sol"; +import {VmSafe} from "./Vm.sol"; + +// šŸ“¦ BOILERPLATE +import {ScriptBase} from "./Base.sol"; + +// ā­ļø SCRIPT +abstract contract Script is ScriptBase, StdChains, StdCheatsSafe, StdUtils { + // Note: IS_SCRIPT() must return true. + bool public IS_SCRIPT = true; +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdAssertions.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdAssertions.sol new file mode 100644 index 0000000000..4248170da0 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdAssertions.sol @@ -0,0 +1,764 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; +pragma experimental ABIEncoderV2; + +import {Vm} from "./Vm.sol"; + +abstract contract StdAssertions { + Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + + event log(string); + event logs(bytes); + + event log_address(address); + event log_bytes32(bytes32); + event log_int(int256); + event log_uint(uint256); + event log_bytes(bytes); + event log_string(string); + + event log_named_address(string key, address val); + event log_named_bytes32(string key, bytes32 val); + event log_named_decimal_int(string key, int256 val, uint256 decimals); + event log_named_decimal_uint(string key, uint256 val, uint256 decimals); + event log_named_int(string key, int256 val); + event log_named_uint(string key, uint256 val); + event log_named_bytes(string key, bytes val); + event log_named_string(string key, string val); + + event log_array(uint256[] val); + event log_array(int256[] val); + event log_array(address[] val); + event log_named_array(string key, uint256[] val); + event log_named_array(string key, int256[] val); + event log_named_array(string key, address[] val); + + bytes32 private constant FAILED_SLOT = bytes32("failed"); + + bool private _failed; + + function failed() public view returns (bool) { + if (_failed) { + return true; + } else { + return vm.load(address(vm), FAILED_SLOT) != bytes32(0); + } + } + + function fail() internal virtual { + vm.store(address(vm), FAILED_SLOT, bytes32(uint256(1))); + _failed = true; + } + + function fail(string memory message) internal virtual { + fail(); + vm.assertTrue(false, message); + } + + function assertTrue(bool data) internal pure virtual { + if (!data) { + vm.assertTrue(data); + } + } + + function assertTrue(bool data, string memory err) internal pure virtual { + if (!data) { + vm.assertTrue(data, err); + } + } + + function assertFalse(bool data) internal pure virtual { + if (data) { + vm.assertFalse(data); + } + } + + function assertFalse(bool data, string memory err) internal pure virtual { + if (data) { + vm.assertFalse(data, err); + } + } + + function assertEq(bool left, bool right) internal pure virtual { + if (left != right) { + vm.assertEq(left, right); + } + } + + function assertEq(bool left, bool right, string memory err) internal pure virtual { + if (left != right) { + vm.assertEq(left, right, err); + } + } + + function assertEq(uint256 left, uint256 right) internal pure virtual { + if (left != right) { + vm.assertEq(left, right); + } + } + + function assertEq(uint256 left, uint256 right, string memory err) internal pure virtual { + if (left != right) { + vm.assertEq(left, right, err); + } + } + + function assertEqDecimal(uint256 left, uint256 right, uint256 decimals) internal pure virtual { + vm.assertEqDecimal(left, right, decimals); + } + + function assertEqDecimal(uint256 left, uint256 right, uint256 decimals, string memory err) internal pure virtual { + vm.assertEqDecimal(left, right, decimals, err); + } + + function assertEq(int256 left, int256 right) internal pure virtual { + if (left != right) { + vm.assertEq(left, right); + } + } + + function assertEq(int256 left, int256 right, string memory err) internal pure virtual { + if (left != right) { + vm.assertEq(left, right, err); + } + } + + function assertEqDecimal(int256 left, int256 right, uint256 decimals) internal pure virtual { + vm.assertEqDecimal(left, right, decimals); + } + + function assertEqDecimal(int256 left, int256 right, uint256 decimals, string memory err) internal pure virtual { + vm.assertEqDecimal(left, right, decimals, err); + } + + function assertEq(address left, address right) internal pure virtual { + if (left != right) { + vm.assertEq(left, right); + } + } + + function assertEq(address left, address right, string memory err) internal pure virtual { + if (left != right) { + vm.assertEq(left, right, err); + } + } + + function assertEq(bytes32 left, bytes32 right) internal pure virtual { + if (left != right) { + vm.assertEq(left, right); + } + } + + function assertEq(bytes32 left, bytes32 right, string memory err) internal pure virtual { + if (left != right) { + vm.assertEq(left, right, err); + } + } + + function assertEq32(bytes32 left, bytes32 right) internal pure virtual { + if (left != right) { + vm.assertEq(left, right); + } + } + + function assertEq32(bytes32 left, bytes32 right, string memory err) internal pure virtual { + if (left != right) { + vm.assertEq(left, right, err); + } + } + + function assertEq(string memory left, string memory right) internal pure virtual { + vm.assertEq(left, right); + } + + function assertEq(string memory left, string memory right, string memory err) internal pure virtual { + vm.assertEq(left, right, err); + } + + function assertEq(bytes memory left, bytes memory right) internal pure virtual { + vm.assertEq(left, right); + } + + function assertEq(bytes memory left, bytes memory right, string memory err) internal pure virtual { + vm.assertEq(left, right, err); + } + + function assertEq(bool[] memory left, bool[] memory right) internal pure virtual { + vm.assertEq(left, right); + } + + function assertEq(bool[] memory left, bool[] memory right, string memory err) internal pure virtual { + vm.assertEq(left, right, err); + } + + function assertEq(uint256[] memory left, uint256[] memory right) internal pure virtual { + vm.assertEq(left, right); + } + + function assertEq(uint256[] memory left, uint256[] memory right, string memory err) internal pure virtual { + vm.assertEq(left, right, err); + } + + function assertEq(int256[] memory left, int256[] memory right) internal pure virtual { + vm.assertEq(left, right); + } + + function assertEq(int256[] memory left, int256[] memory right, string memory err) internal pure virtual { + vm.assertEq(left, right, err); + } + + function assertEq(address[] memory left, address[] memory right) internal pure virtual { + vm.assertEq(left, right); + } + + function assertEq(address[] memory left, address[] memory right, string memory err) internal pure virtual { + vm.assertEq(left, right, err); + } + + function assertEq(bytes32[] memory left, bytes32[] memory right) internal pure virtual { + vm.assertEq(left, right); + } + + function assertEq(bytes32[] memory left, bytes32[] memory right, string memory err) internal pure virtual { + vm.assertEq(left, right, err); + } + + function assertEq(string[] memory left, string[] memory right) internal pure virtual { + vm.assertEq(left, right); + } + + function assertEq(string[] memory left, string[] memory right, string memory err) internal pure virtual { + vm.assertEq(left, right, err); + } + + function assertEq(bytes[] memory left, bytes[] memory right) internal pure virtual { + vm.assertEq(left, right); + } + + function assertEq(bytes[] memory left, bytes[] memory right, string memory err) internal pure virtual { + vm.assertEq(left, right, err); + } + + // Legacy helper + function assertEqUint(uint256 left, uint256 right) internal pure virtual { + assertEq(left, right); + } + + function assertNotEq(bool left, bool right) internal pure virtual { + if (left == right) { + vm.assertNotEq(left, right); + } + } + + function assertNotEq(bool left, bool right, string memory err) internal pure virtual { + if (left == right) { + vm.assertNotEq(left, right, err); + } + } + + function assertNotEq(uint256 left, uint256 right) internal pure virtual { + if (left == right) { + vm.assertNotEq(left, right); + } + } + + function assertNotEq(uint256 left, uint256 right, string memory err) internal pure virtual { + if (left == right) { + vm.assertNotEq(left, right, err); + } + } + + function assertNotEqDecimal(uint256 left, uint256 right, uint256 decimals) internal pure virtual { + vm.assertNotEqDecimal(left, right, decimals); + } + + function assertNotEqDecimal(uint256 left, uint256 right, uint256 decimals, string memory err) + internal + pure + virtual + { + vm.assertNotEqDecimal(left, right, decimals, err); + } + + function assertNotEq(int256 left, int256 right) internal pure virtual { + if (left == right) { + vm.assertNotEq(left, right); + } + } + + function assertNotEq(int256 left, int256 right, string memory err) internal pure virtual { + if (left == right) { + vm.assertNotEq(left, right, err); + } + } + + function assertNotEqDecimal(int256 left, int256 right, uint256 decimals) internal pure virtual { + vm.assertNotEqDecimal(left, right, decimals); + } + + function assertNotEqDecimal(int256 left, int256 right, uint256 decimals, string memory err) internal pure virtual { + vm.assertNotEqDecimal(left, right, decimals, err); + } + + function assertNotEq(address left, address right) internal pure virtual { + if (left == right) { + vm.assertNotEq(left, right); + } + } + + function assertNotEq(address left, address right, string memory err) internal pure virtual { + if (left == right) { + vm.assertNotEq(left, right, err); + } + } + + function assertNotEq(bytes32 left, bytes32 right) internal pure virtual { + if (left == right) { + vm.assertNotEq(left, right); + } + } + + function assertNotEq(bytes32 left, bytes32 right, string memory err) internal pure virtual { + if (left == right) { + vm.assertNotEq(left, right, err); + } + } + + function assertNotEq32(bytes32 left, bytes32 right) internal pure virtual { + if (left == right) { + vm.assertNotEq(left, right); + } + } + + function assertNotEq32(bytes32 left, bytes32 right, string memory err) internal pure virtual { + if (left == right) { + vm.assertNotEq(left, right, err); + } + } + + function assertNotEq(string memory left, string memory right) internal pure virtual { + vm.assertNotEq(left, right); + } + + function assertNotEq(string memory left, string memory right, string memory err) internal pure virtual { + vm.assertNotEq(left, right, err); + } + + function assertNotEq(bytes memory left, bytes memory right) internal pure virtual { + vm.assertNotEq(left, right); + } + + function assertNotEq(bytes memory left, bytes memory right, string memory err) internal pure virtual { + vm.assertNotEq(left, right, err); + } + + function assertNotEq(bool[] memory left, bool[] memory right) internal pure virtual { + vm.assertNotEq(left, right); + } + + function assertNotEq(bool[] memory left, bool[] memory right, string memory err) internal pure virtual { + vm.assertNotEq(left, right, err); + } + + function assertNotEq(uint256[] memory left, uint256[] memory right) internal pure virtual { + vm.assertNotEq(left, right); + } + + function assertNotEq(uint256[] memory left, uint256[] memory right, string memory err) internal pure virtual { + vm.assertNotEq(left, right, err); + } + + function assertNotEq(int256[] memory left, int256[] memory right) internal pure virtual { + vm.assertNotEq(left, right); + } + + function assertNotEq(int256[] memory left, int256[] memory right, string memory err) internal pure virtual { + vm.assertNotEq(left, right, err); + } + + function assertNotEq(address[] memory left, address[] memory right) internal pure virtual { + vm.assertNotEq(left, right); + } + + function assertNotEq(address[] memory left, address[] memory right, string memory err) internal pure virtual { + vm.assertNotEq(left, right, err); + } + + function assertNotEq(bytes32[] memory left, bytes32[] memory right) internal pure virtual { + vm.assertNotEq(left, right); + } + + function assertNotEq(bytes32[] memory left, bytes32[] memory right, string memory err) internal pure virtual { + vm.assertNotEq(left, right, err); + } + + function assertNotEq(string[] memory left, string[] memory right) internal pure virtual { + vm.assertNotEq(left, right); + } + + function assertNotEq(string[] memory left, string[] memory right, string memory err) internal pure virtual { + vm.assertNotEq(left, right, err); + } + + function assertNotEq(bytes[] memory left, bytes[] memory right) internal pure virtual { + vm.assertNotEq(left, right); + } + + function assertNotEq(bytes[] memory left, bytes[] memory right, string memory err) internal pure virtual { + vm.assertNotEq(left, right, err); + } + + function assertLt(uint256 left, uint256 right) internal pure virtual { + if (left >= right) { + vm.assertLt(left, right); + } + } + + function assertLt(uint256 left, uint256 right, string memory err) internal pure virtual { + if (left >= right) { + vm.assertLt(left, right, err); + } + } + + function assertLtDecimal(uint256 left, uint256 right, uint256 decimals) internal pure virtual { + vm.assertLtDecimal(left, right, decimals); + } + + function assertLtDecimal(uint256 left, uint256 right, uint256 decimals, string memory err) internal pure virtual { + vm.assertLtDecimal(left, right, decimals, err); + } + + function assertLt(int256 left, int256 right) internal pure virtual { + if (left >= right) { + vm.assertLt(left, right); + } + } + + function assertLt(int256 left, int256 right, string memory err) internal pure virtual { + if (left >= right) { + vm.assertLt(left, right, err); + } + } + + function assertLtDecimal(int256 left, int256 right, uint256 decimals) internal pure virtual { + vm.assertLtDecimal(left, right, decimals); + } + + function assertLtDecimal(int256 left, int256 right, uint256 decimals, string memory err) internal pure virtual { + vm.assertLtDecimal(left, right, decimals, err); + } + + function assertGt(uint256 left, uint256 right) internal pure virtual { + if (left <= right) { + vm.assertGt(left, right); + } + } + + function assertGt(uint256 left, uint256 right, string memory err) internal pure virtual { + if (left <= right) { + vm.assertGt(left, right, err); + } + } + + function assertGtDecimal(uint256 left, uint256 right, uint256 decimals) internal pure virtual { + vm.assertGtDecimal(left, right, decimals); + } + + function assertGtDecimal(uint256 left, uint256 right, uint256 decimals, string memory err) internal pure virtual { + vm.assertGtDecimal(left, right, decimals, err); + } + + function assertGt(int256 left, int256 right) internal pure virtual { + if (left <= right) { + vm.assertGt(left, right); + } + } + + function assertGt(int256 left, int256 right, string memory err) internal pure virtual { + if (left <= right) { + vm.assertGt(left, right, err); + } + } + + function assertGtDecimal(int256 left, int256 right, uint256 decimals) internal pure virtual { + vm.assertGtDecimal(left, right, decimals); + } + + function assertGtDecimal(int256 left, int256 right, uint256 decimals, string memory err) internal pure virtual { + vm.assertGtDecimal(left, right, decimals, err); + } + + function assertLe(uint256 left, uint256 right) internal pure virtual { + if (left > right) { + vm.assertLe(left, right); + } + } + + function assertLe(uint256 left, uint256 right, string memory err) internal pure virtual { + if (left > right) { + vm.assertLe(left, right, err); + } + } + + function assertLeDecimal(uint256 left, uint256 right, uint256 decimals) internal pure virtual { + vm.assertLeDecimal(left, right, decimals); + } + + function assertLeDecimal(uint256 left, uint256 right, uint256 decimals, string memory err) internal pure virtual { + vm.assertLeDecimal(left, right, decimals, err); + } + + function assertLe(int256 left, int256 right) internal pure virtual { + if (left > right) { + vm.assertLe(left, right); + } + } + + function assertLe(int256 left, int256 right, string memory err) internal pure virtual { + if (left > right) { + vm.assertLe(left, right, err); + } + } + + function assertLeDecimal(int256 left, int256 right, uint256 decimals) internal pure virtual { + vm.assertLeDecimal(left, right, decimals); + } + + function assertLeDecimal(int256 left, int256 right, uint256 decimals, string memory err) internal pure virtual { + vm.assertLeDecimal(left, right, decimals, err); + } + + function assertGe(uint256 left, uint256 right) internal pure virtual { + if (left < right) { + vm.assertGe(left, right); + } + } + + function assertGe(uint256 left, uint256 right, string memory err) internal pure virtual { + if (left < right) { + vm.assertGe(left, right, err); + } + } + + function assertGeDecimal(uint256 left, uint256 right, uint256 decimals) internal pure virtual { + vm.assertGeDecimal(left, right, decimals); + } + + function assertGeDecimal(uint256 left, uint256 right, uint256 decimals, string memory err) internal pure virtual { + vm.assertGeDecimal(left, right, decimals, err); + } + + function assertGe(int256 left, int256 right) internal pure virtual { + if (left < right) { + vm.assertGe(left, right); + } + } + + function assertGe(int256 left, int256 right, string memory err) internal pure virtual { + if (left < right) { + vm.assertGe(left, right, err); + } + } + + function assertGeDecimal(int256 left, int256 right, uint256 decimals) internal pure virtual { + vm.assertGeDecimal(left, right, decimals); + } + + function assertGeDecimal(int256 left, int256 right, uint256 decimals, string memory err) internal pure virtual { + vm.assertGeDecimal(left, right, decimals, err); + } + + function assertApproxEqAbs(uint256 left, uint256 right, uint256 maxDelta) internal pure virtual { + vm.assertApproxEqAbs(left, right, maxDelta); + } + + function assertApproxEqAbs(uint256 left, uint256 right, uint256 maxDelta, string memory err) + internal + pure + virtual + { + vm.assertApproxEqAbs(left, right, maxDelta, err); + } + + function assertApproxEqAbsDecimal(uint256 left, uint256 right, uint256 maxDelta, uint256 decimals) + internal + pure + virtual + { + vm.assertApproxEqAbsDecimal(left, right, maxDelta, decimals); + } + + function assertApproxEqAbsDecimal( + uint256 left, + uint256 right, + uint256 maxDelta, + uint256 decimals, + string memory err + ) internal pure virtual { + vm.assertApproxEqAbsDecimal(left, right, maxDelta, decimals, err); + } + + function assertApproxEqAbs(int256 left, int256 right, uint256 maxDelta) internal pure virtual { + vm.assertApproxEqAbs(left, right, maxDelta); + } + + function assertApproxEqAbs(int256 left, int256 right, uint256 maxDelta, string memory err) internal pure virtual { + vm.assertApproxEqAbs(left, right, maxDelta, err); + } + + function assertApproxEqAbsDecimal(int256 left, int256 right, uint256 maxDelta, uint256 decimals) + internal + pure + virtual + { + vm.assertApproxEqAbsDecimal(left, right, maxDelta, decimals); + } + + function assertApproxEqAbsDecimal(int256 left, int256 right, uint256 maxDelta, uint256 decimals, string memory err) + internal + pure + virtual + { + vm.assertApproxEqAbsDecimal(left, right, maxDelta, decimals, err); + } + + function assertApproxEqRel( + uint256 left, + uint256 right, + uint256 maxPercentDelta // An 18 decimal fixed point number, where 1e18 == 100% + ) internal pure virtual { + vm.assertApproxEqRel(left, right, maxPercentDelta); + } + + function assertApproxEqRel( + uint256 left, + uint256 right, + uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% + string memory err + ) internal pure virtual { + vm.assertApproxEqRel(left, right, maxPercentDelta, err); + } + + function assertApproxEqRelDecimal( + uint256 left, + uint256 right, + uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% + uint256 decimals + ) internal pure virtual { + vm.assertApproxEqRelDecimal(left, right, maxPercentDelta, decimals); + } + + function assertApproxEqRelDecimal( + uint256 left, + uint256 right, + uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% + uint256 decimals, + string memory err + ) internal pure virtual { + vm.assertApproxEqRelDecimal(left, right, maxPercentDelta, decimals, err); + } + + function assertApproxEqRel(int256 left, int256 right, uint256 maxPercentDelta) internal pure virtual { + vm.assertApproxEqRel(left, right, maxPercentDelta); + } + + function assertApproxEqRel( + int256 left, + int256 right, + uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% + string memory err + ) internal pure virtual { + vm.assertApproxEqRel(left, right, maxPercentDelta, err); + } + + function assertApproxEqRelDecimal( + int256 left, + int256 right, + uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% + uint256 decimals + ) internal pure virtual { + vm.assertApproxEqRelDecimal(left, right, maxPercentDelta, decimals); + } + + function assertApproxEqRelDecimal( + int256 left, + int256 right, + uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% + uint256 decimals, + string memory err + ) internal pure virtual { + vm.assertApproxEqRelDecimal(left, right, maxPercentDelta, decimals, err); + } + + // Inherited from DSTest, not used but kept for backwards-compatibility + function checkEq0(bytes memory left, bytes memory right) internal pure returns (bool) { + return keccak256(left) == keccak256(right); + } + + function assertEq0(bytes memory left, bytes memory right) internal pure virtual { + assertEq(left, right); + } + + function assertEq0(bytes memory left, bytes memory right, string memory err) internal pure virtual { + assertEq(left, right, err); + } + + function assertNotEq0(bytes memory left, bytes memory right) internal pure virtual { + assertNotEq(left, right); + } + + function assertNotEq0(bytes memory left, bytes memory right, string memory err) internal pure virtual { + assertNotEq(left, right, err); + } + + function assertEqCall(address target, bytes memory callDataA, bytes memory callDataB) internal virtual { + assertEqCall(target, callDataA, target, callDataB, true); + } + + function assertEqCall(address targetA, bytes memory callDataA, address targetB, bytes memory callDataB) + internal + virtual + { + assertEqCall(targetA, callDataA, targetB, callDataB, true); + } + + function assertEqCall(address target, bytes memory callDataA, bytes memory callDataB, bool strictRevertData) + internal + virtual + { + assertEqCall(target, callDataA, target, callDataB, strictRevertData); + } + + function assertEqCall( + address targetA, + bytes memory callDataA, + address targetB, + bytes memory callDataB, + bool strictRevertData + ) internal virtual { + (bool successA, bytes memory returnDataA) = address(targetA).call(callDataA); + (bool successB, bytes memory returnDataB) = address(targetB).call(callDataB); + + if (successA && successB) { + assertEq(returnDataA, returnDataB, "Call return data does not match"); + } + + if (!successA && !successB && strictRevertData) { + assertEq(returnDataA, returnDataB, "Call revert data does not match"); + } + + if (!successA && successB) { + emit log("Error: Calls were not equal"); + emit log_named_bytes(" Left call revert data", returnDataA); + emit log_named_bytes(" Right call return data", returnDataB); + revert("assertion failed"); + } + + if (successA && !successB) { + emit log("Error: Calls were not equal"); + emit log_named_bytes(" Left call return data", returnDataA); + emit log_named_bytes(" Right call revert data", returnDataB); + revert("assertion failed"); + } + } +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdChains.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdChains.sol new file mode 100644 index 0000000000..3bc5f43af1 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdChains.sol @@ -0,0 +1,287 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; +pragma experimental ABIEncoderV2; + +import {VmSafe} from "./Vm.sol"; + +/** + * StdChains provides information about EVM compatible chains that can be used in scripts/tests. + * For each chain, the chain's name, chain ID, and a default RPC URL are provided. Chains are + * identified by their alias, which is the same as the alias in the `[rpc_endpoints]` section of + * the `foundry.toml` file. For best UX, ensure the alias in the `foundry.toml` file match the + * alias used in this contract, which can be found as the first argument to the + * `setChainWithDefaultRpcUrl` call in the `initializeStdChains` function. + * + * There are two main ways to use this contract: + * 1. Set a chain with `setChain(string memory chainAlias, ChainData memory chain)` or + * `setChain(string memory chainAlias, Chain memory chain)` + * 2. Get a chain with `getChain(string memory chainAlias)` or `getChain(uint256 chainId)`. + * + * The first time either of those are used, chains are initialized with the default set of RPC URLs. + * This is done in `initializeStdChains`, which uses `setChainWithDefaultRpcUrl`. Defaults are recorded in + * `defaultRpcUrls`. + * + * The `setChain` function is straightforward, and it simply saves off the given chain data. + * + * The `getChain` methods use `getChainWithUpdatedRpcUrl` to return a chain. For example, let's say + * we want to retrieve the RPC URL for `mainnet`: + * - If you have specified data with `setChain`, it will return that. + * - If you have configured a mainnet RPC URL in `foundry.toml`, it will return the URL, provided it + * is valid (e.g. a URL is specified, or an environment variable is given and exists). + * - If neither of the above conditions is met, the default data is returned. + * + * Summarizing the above, the prioritization hierarchy is `setChain` -> `foundry.toml` -> environment variable -> defaults. + */ +abstract contract StdChains { + VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); + + bool private stdChainsInitialized; + + struct ChainData { + string name; + uint256 chainId; + string rpcUrl; + } + + struct Chain { + // The chain name. + string name; + // The chain's Chain ID. + uint256 chainId; + // The chain's alias. (i.e. what gets specified in `foundry.toml`). + string chainAlias; + // A default RPC endpoint for this chain. + // NOTE: This default RPC URL is included for convenience to facilitate quick tests and + // experimentation. Do not use this RPC URL for production test suites, CI, or other heavy + // usage as you will be throttled and this is a disservice to others who need this endpoint. + string rpcUrl; + } + + // Maps from the chain's alias (matching the alias in the `foundry.toml` file) to chain data. + mapping(string => Chain) private chains; + // Maps from the chain's alias to it's default RPC URL. + mapping(string => string) private defaultRpcUrls; + // Maps from a chain ID to it's alias. + mapping(uint256 => string) private idToAlias; + + bool private fallbackToDefaultRpcUrls = true; + + // The RPC URL will be fetched from config or defaultRpcUrls if possible. + function getChain(string memory chainAlias) internal virtual returns (Chain memory chain) { + require(bytes(chainAlias).length != 0, "StdChains getChain(string): Chain alias cannot be the empty string."); + + initializeStdChains(); + chain = chains[chainAlias]; + require( + chain.chainId != 0, + string(abi.encodePacked("StdChains getChain(string): Chain with alias \"", chainAlias, "\" not found.")) + ); + + chain = getChainWithUpdatedRpcUrl(chainAlias, chain); + } + + function getChain(uint256 chainId) internal virtual returns (Chain memory chain) { + require(chainId != 0, "StdChains getChain(uint256): Chain ID cannot be 0."); + initializeStdChains(); + string memory chainAlias = idToAlias[chainId]; + + chain = chains[chainAlias]; + + require( + chain.chainId != 0, + string(abi.encodePacked("StdChains getChain(uint256): Chain with ID ", vm.toString(chainId), " not found.")) + ); + + chain = getChainWithUpdatedRpcUrl(chainAlias, chain); + } + + // set chain info, with priority to argument's rpcUrl field. + function setChain(string memory chainAlias, ChainData memory chain) internal virtual { + require( + bytes(chainAlias).length != 0, + "StdChains setChain(string,ChainData): Chain alias cannot be the empty string." + ); + + require(chain.chainId != 0, "StdChains setChain(string,ChainData): Chain ID cannot be 0."); + + initializeStdChains(); + string memory foundAlias = idToAlias[chain.chainId]; + + require( + bytes(foundAlias).length == 0 || keccak256(bytes(foundAlias)) == keccak256(bytes(chainAlias)), + string( + abi.encodePacked( + "StdChains setChain(string,ChainData): Chain ID ", + vm.toString(chain.chainId), + " already used by \"", + foundAlias, + "\"." + ) + ) + ); + + uint256 oldChainId = chains[chainAlias].chainId; + delete idToAlias[oldChainId]; + + chains[chainAlias] = + Chain({name: chain.name, chainId: chain.chainId, chainAlias: chainAlias, rpcUrl: chain.rpcUrl}); + idToAlias[chain.chainId] = chainAlias; + } + + // set chain info, with priority to argument's rpcUrl field. + function setChain(string memory chainAlias, Chain memory chain) internal virtual { + setChain(chainAlias, ChainData({name: chain.name, chainId: chain.chainId, rpcUrl: chain.rpcUrl})); + } + + function _toUpper(string memory str) private pure returns (string memory) { + bytes memory strb = bytes(str); + bytes memory copy = new bytes(strb.length); + for (uint256 i = 0; i < strb.length; i++) { + bytes1 b = strb[i]; + if (b >= 0x61 && b <= 0x7A) { + copy[i] = bytes1(uint8(b) - 32); + } else { + copy[i] = b; + } + } + return string(copy); + } + + // lookup rpcUrl, in descending order of priority: + // current -> config (foundry.toml) -> environment variable -> default + function getChainWithUpdatedRpcUrl(string memory chainAlias, Chain memory chain) + private + view + returns (Chain memory) + { + if (bytes(chain.rpcUrl).length == 0) { + try vm.rpcUrl(chainAlias) returns (string memory configRpcUrl) { + chain.rpcUrl = configRpcUrl; + } catch (bytes memory err) { + string memory envName = string(abi.encodePacked(_toUpper(chainAlias), "_RPC_URL")); + if (fallbackToDefaultRpcUrls) { + chain.rpcUrl = vm.envOr(envName, defaultRpcUrls[chainAlias]); + } else { + chain.rpcUrl = vm.envString(envName); + } + // Distinguish 'not found' from 'cannot read' + // The upstream error thrown by forge for failing cheats changed so we check both the old and new versions + bytes memory oldNotFoundError = + abi.encodeWithSignature("CheatCodeError", string(abi.encodePacked("invalid rpc url ", chainAlias))); + bytes memory newNotFoundError = abi.encodeWithSignature( + "CheatcodeError(string)", string(abi.encodePacked("invalid rpc url: ", chainAlias)) + ); + bytes32 errHash = keccak256(err); + if ( + (errHash != keccak256(oldNotFoundError) && errHash != keccak256(newNotFoundError)) + || bytes(chain.rpcUrl).length == 0 + ) { + /// @solidity memory-safe-assembly + assembly { + revert(add(32, err), mload(err)) + } + } + } + } + return chain; + } + + function setFallbackToDefaultRpcUrls(bool useDefault) internal { + fallbackToDefaultRpcUrls = useDefault; + } + + function initializeStdChains() private { + if (stdChainsInitialized) return; + + stdChainsInitialized = true; + + // If adding an RPC here, make sure to test the default RPC URL in `test_Rpcs` in `StdChains.t.sol` + setChainWithDefaultRpcUrl("anvil", ChainData("Anvil", 31337, "http://127.0.0.1:8545")); + setChainWithDefaultRpcUrl("mainnet", ChainData("Mainnet", 1, "https://eth.llamarpc.com")); + setChainWithDefaultRpcUrl( + "sepolia", ChainData("Sepolia", 11155111, "https://sepolia.infura.io/v3/b9794ad1ddf84dfb8c34d6bb5dca2001") + ); + setChainWithDefaultRpcUrl("holesky", ChainData("Holesky", 17000, "https://rpc.holesky.ethpandaops.io")); + setChainWithDefaultRpcUrl("hoodi", ChainData("Hoodi", 560048, "https://rpc.hoodi.ethpandaops.io")); + setChainWithDefaultRpcUrl("optimism", ChainData("Optimism", 10, "https://mainnet.optimism.io")); + setChainWithDefaultRpcUrl( + "optimism_sepolia", ChainData("Optimism Sepolia", 11155420, "https://sepolia.optimism.io") + ); + setChainWithDefaultRpcUrl("arbitrum_one", ChainData("Arbitrum One", 42161, "https://arb1.arbitrum.io/rpc")); + setChainWithDefaultRpcUrl( + "arbitrum_one_sepolia", ChainData("Arbitrum One Sepolia", 421614, "https://sepolia-rollup.arbitrum.io/rpc") + ); + setChainWithDefaultRpcUrl("arbitrum_nova", ChainData("Arbitrum Nova", 42170, "https://nova.arbitrum.io/rpc")); + setChainWithDefaultRpcUrl("polygon", ChainData("Polygon", 137, "https://polygon-rpc.com")); + setChainWithDefaultRpcUrl( + "polygon_amoy", ChainData("Polygon Amoy", 80002, "https://rpc-amoy.polygon.technology") + ); + setChainWithDefaultRpcUrl("avalanche", ChainData("Avalanche", 43114, "https://api.avax.network/ext/bc/C/rpc")); + setChainWithDefaultRpcUrl( + "avalanche_fuji", ChainData("Avalanche Fuji", 43113, "https://api.avax-test.network/ext/bc/C/rpc") + ); + setChainWithDefaultRpcUrl( + "bnb_smart_chain", ChainData("BNB Smart Chain", 56, "https://bsc-dataseed1.binance.org") + ); + setChainWithDefaultRpcUrl( + "bnb_smart_chain_testnet", + ChainData("BNB Smart Chain Testnet", 97, "https://rpc.ankr.com/bsc_testnet_chapel") + ); + setChainWithDefaultRpcUrl("gnosis_chain", ChainData("Gnosis Chain", 100, "https://rpc.gnosischain.com")); + setChainWithDefaultRpcUrl("moonbeam", ChainData("Moonbeam", 1284, "https://rpc.api.moonbeam.network")); + setChainWithDefaultRpcUrl( + "moonriver", ChainData("Moonriver", 1285, "https://rpc.api.moonriver.moonbeam.network") + ); + setChainWithDefaultRpcUrl("moonbase", ChainData("Moonbase", 1287, "https://rpc.testnet.moonbeam.network")); + setChainWithDefaultRpcUrl("base_sepolia", ChainData("Base Sepolia", 84532, "https://sepolia.base.org")); + setChainWithDefaultRpcUrl("base", ChainData("Base", 8453, "https://mainnet.base.org")); + setChainWithDefaultRpcUrl("blast_sepolia", ChainData("Blast Sepolia", 168587773, "https://sepolia.blast.io")); + setChainWithDefaultRpcUrl("blast", ChainData("Blast", 81457, "https://rpc.blast.io")); + setChainWithDefaultRpcUrl("fantom_opera", ChainData("Fantom Opera", 250, "https://rpc.ankr.com/fantom/")); + setChainWithDefaultRpcUrl( + "fantom_opera_testnet", ChainData("Fantom Opera Testnet", 4002, "https://rpc.ankr.com/fantom_testnet/") + ); + setChainWithDefaultRpcUrl("fraxtal", ChainData("Fraxtal", 252, "https://rpc.frax.com")); + setChainWithDefaultRpcUrl("fraxtal_testnet", ChainData("Fraxtal Testnet", 2522, "https://rpc.testnet.frax.com")); + setChainWithDefaultRpcUrl( + "berachain_bartio_testnet", ChainData("Berachain bArtio Testnet", 80084, "https://bartio.rpc.berachain.com") + ); + setChainWithDefaultRpcUrl("flare", ChainData("Flare", 14, "https://flare-api.flare.network/ext/C/rpc")); + setChainWithDefaultRpcUrl( + "flare_coston2", ChainData("Flare Coston2", 114, "https://coston2-api.flare.network/ext/C/rpc") + ); + + setChainWithDefaultRpcUrl("mode", ChainData("Mode", 34443, "https://mode.drpc.org")); + setChainWithDefaultRpcUrl("mode_sepolia", ChainData("Mode Sepolia", 919, "https://sepolia.mode.network")); + + setChainWithDefaultRpcUrl("zora", ChainData("Zora", 7777777, "https://zora.drpc.org")); + setChainWithDefaultRpcUrl( + "zora_sepolia", ChainData("Zora Sepolia", 999999999, "https://sepolia.rpc.zora.energy") + ); + + setChainWithDefaultRpcUrl("race", ChainData("Race", 6805, "https://racemainnet.io")); + setChainWithDefaultRpcUrl("race_sepolia", ChainData("Race Sepolia", 6806, "https://racemainnet.io")); + + setChainWithDefaultRpcUrl("metal", ChainData("Metal", 1750, "https://metall2.drpc.org")); + setChainWithDefaultRpcUrl("metal_sepolia", ChainData("Metal Sepolia", 1740, "https://testnet.rpc.metall2.com")); + + setChainWithDefaultRpcUrl("binary", ChainData("Binary", 624, "https://rpc.zero.thebinaryholdings.com")); + setChainWithDefaultRpcUrl( + "binary_sepolia", ChainData("Binary Sepolia", 625, "https://rpc.zero.thebinaryholdings.com") + ); + + setChainWithDefaultRpcUrl("orderly", ChainData("Orderly", 291, "https://rpc.orderly.network")); + setChainWithDefaultRpcUrl( + "orderly_sepolia", ChainData("Orderly Sepolia", 4460, "https://testnet-rpc.orderly.org") + ); + } + + // set chain info, with priority to chainAlias' rpc url in foundry.toml + function setChainWithDefaultRpcUrl(string memory chainAlias, ChainData memory chain) private { + string memory rpcUrl = chain.rpcUrl; + defaultRpcUrls[chainAlias] = rpcUrl; + chain.rpcUrl = ""; + setChain(chainAlias, chain); + chain.rpcUrl = rpcUrl; // restore argument + } +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdCheats.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdCheats.sol new file mode 100644 index 0000000000..9f360dec21 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdCheats.sol @@ -0,0 +1,829 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +import {StdStorage, stdStorage} from "./StdStorage.sol"; +import {console2} from "./console2.sol"; +import {Vm} from "./Vm.sol"; + +abstract contract StdCheatsSafe { + Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + + uint256 private constant UINT256_MAX = + 115792089237316195423570985008687907853269984665640564039457584007913129639935; + + bool private gasMeteringOff; + + // Data structures to parse Transaction objects from the broadcast artifact + // that conform to EIP1559. The Raw structs is what is parsed from the JSON + // and then converted to the one that is used by the user for better UX. + + struct RawTx1559 { + string[] arguments; + address contractAddress; + string contractName; + // json value name = function + string functionSig; + bytes32 hash; + // json value name = tx + RawTx1559Detail txDetail; + // json value name = type + string opcode; + } + + struct RawTx1559Detail { + AccessList[] accessList; + bytes data; + address from; + bytes gas; + bytes nonce; + address to; + bytes txType; + bytes value; + } + + struct Tx1559 { + string[] arguments; + address contractAddress; + string contractName; + string functionSig; + bytes32 hash; + Tx1559Detail txDetail; + string opcode; + } + + struct Tx1559Detail { + AccessList[] accessList; + bytes data; + address from; + uint256 gas; + uint256 nonce; + address to; + uint256 txType; + uint256 value; + } + + // Data structures to parse Transaction objects from the broadcast artifact + // that DO NOT conform to EIP1559. The Raw structs is what is parsed from the JSON + // and then converted to the one that is used by the user for better UX. + + struct TxLegacy { + string[] arguments; + address contractAddress; + string contractName; + string functionSig; + string hash; + string opcode; + TxDetailLegacy transaction; + } + + struct TxDetailLegacy { + AccessList[] accessList; + uint256 chainId; + bytes data; + address from; + uint256 gas; + uint256 gasPrice; + bytes32 hash; + uint256 nonce; + bytes1 opcode; + bytes32 r; + bytes32 s; + uint256 txType; + address to; + uint8 v; + uint256 value; + } + + struct AccessList { + address accessAddress; + bytes32[] storageKeys; + } + + // Data structures to parse Receipt objects from the broadcast artifact. + // The Raw structs is what is parsed from the JSON + // and then converted to the one that is used by the user for better UX. + + struct RawReceipt { + bytes32 blockHash; + bytes blockNumber; + address contractAddress; + bytes cumulativeGasUsed; + bytes effectiveGasPrice; + address from; + bytes gasUsed; + RawReceiptLog[] logs; + bytes logsBloom; + bytes status; + address to; + bytes32 transactionHash; + bytes transactionIndex; + } + + struct Receipt { + bytes32 blockHash; + uint256 blockNumber; + address contractAddress; + uint256 cumulativeGasUsed; + uint256 effectiveGasPrice; + address from; + uint256 gasUsed; + ReceiptLog[] logs; + bytes logsBloom; + uint256 status; + address to; + bytes32 transactionHash; + uint256 transactionIndex; + } + + // Data structures to parse the entire broadcast artifact, assuming the + // transactions conform to EIP1559. + + struct EIP1559ScriptArtifact { + string[] libraries; + string path; + string[] pending; + Receipt[] receipts; + uint256 timestamp; + Tx1559[] transactions; + TxReturn[] txReturns; + } + + struct RawEIP1559ScriptArtifact { + string[] libraries; + string path; + string[] pending; + RawReceipt[] receipts; + TxReturn[] txReturns; + uint256 timestamp; + RawTx1559[] transactions; + } + + struct RawReceiptLog { + // json value = address + address logAddress; + bytes32 blockHash; + bytes blockNumber; + bytes data; + bytes logIndex; + bool removed; + bytes32[] topics; + bytes32 transactionHash; + bytes transactionIndex; + bytes transactionLogIndex; + } + + struct ReceiptLog { + // json value = address + address logAddress; + bytes32 blockHash; + uint256 blockNumber; + bytes data; + uint256 logIndex; + bytes32[] topics; + uint256 transactionIndex; + uint256 transactionLogIndex; + bool removed; + } + + struct TxReturn { + string internalType; + string value; + } + + struct Account { + address addr; + uint256 key; + } + + enum AddressType { + Payable, + NonPayable, + ZeroAddress, + Precompile, + ForgeAddress + } + + // Checks that `addr` is not blacklisted by token contracts that have a blacklist. + function assumeNotBlacklisted(address token, address addr) internal view virtual { + // Nothing to check if `token` is not a contract. + uint256 tokenCodeSize; + assembly { + tokenCodeSize := extcodesize(token) + } + require(tokenCodeSize > 0, "StdCheats assumeNotBlacklisted(address,address): Token address is not a contract."); + + bool success; + bytes memory returnData; + + // 4-byte selector for `isBlacklisted(address)`, used by USDC. + (success, returnData) = token.staticcall(abi.encodeWithSelector(0xfe575a87, addr)); + vm.assume(!success || abi.decode(returnData, (bool)) == false); + + // 4-byte selector for `isBlackListed(address)`, used by USDT. + (success, returnData) = token.staticcall(abi.encodeWithSelector(0xe47d6060, addr)); + vm.assume(!success || abi.decode(returnData, (bool)) == false); + } + + // Checks that `addr` is not blacklisted by token contracts that have a blacklist. + // This is identical to `assumeNotBlacklisted(address,address)` but with a different name, for + // backwards compatibility, since this name was used in the original PR which already has + // a release. This function can be removed in a future release once we want a breaking change. + function assumeNoBlacklisted(address token, address addr) internal view virtual { + assumeNotBlacklisted(token, addr); + } + + function assumeAddressIsNot(address addr, AddressType addressType) internal virtual { + if (addressType == AddressType.Payable) { + assumeNotPayable(addr); + } else if (addressType == AddressType.NonPayable) { + assumePayable(addr); + } else if (addressType == AddressType.ZeroAddress) { + assumeNotZeroAddress(addr); + } else if (addressType == AddressType.Precompile) { + assumeNotPrecompile(addr); + } else if (addressType == AddressType.ForgeAddress) { + assumeNotForgeAddress(addr); + } + } + + function assumeAddressIsNot(address addr, AddressType addressType1, AddressType addressType2) internal virtual { + assumeAddressIsNot(addr, addressType1); + assumeAddressIsNot(addr, addressType2); + } + + function assumeAddressIsNot( + address addr, + AddressType addressType1, + AddressType addressType2, + AddressType addressType3 + ) internal virtual { + assumeAddressIsNot(addr, addressType1); + assumeAddressIsNot(addr, addressType2); + assumeAddressIsNot(addr, addressType3); + } + + function assumeAddressIsNot( + address addr, + AddressType addressType1, + AddressType addressType2, + AddressType addressType3, + AddressType addressType4 + ) internal virtual { + assumeAddressIsNot(addr, addressType1); + assumeAddressIsNot(addr, addressType2); + assumeAddressIsNot(addr, addressType3); + assumeAddressIsNot(addr, addressType4); + } + + // This function checks whether an address, `addr`, is payable. It works by sending 1 wei to + // `addr` and checking the `success` return value. + // NOTE: This function may result in state changes depending on the fallback/receive logic + // implemented by `addr`, which should be taken into account when this function is used. + function _isPayable(address addr) private returns (bool) { + require( + addr.balance < UINT256_MAX, + "StdCheats _isPayable(address): Balance equals max uint256, so it cannot receive any more funds" + ); + uint256 origBalanceTest = address(this).balance; + uint256 origBalanceAddr = address(addr).balance; + + vm.deal(address(this), 1); + (bool success,) = payable(addr).call{value: 1}(""); + + // reset balances + vm.deal(address(this), origBalanceTest); + vm.deal(addr, origBalanceAddr); + + return success; + } + + // NOTE: This function may result in state changes depending on the fallback/receive logic + // implemented by `addr`, which should be taken into account when this function is used. See the + // `_isPayable` method for more information. + function assumePayable(address addr) internal virtual { + vm.assume(_isPayable(addr)); + } + + function assumeNotPayable(address addr) internal virtual { + vm.assume(!_isPayable(addr)); + } + + function assumeNotZeroAddress(address addr) internal pure virtual { + vm.assume(addr != address(0)); + } + + function assumeNotPrecompile(address addr) internal pure virtual { + assumeNotPrecompile(addr, _pureChainId()); + } + + function assumeNotPrecompile(address addr, uint256 chainId) internal pure virtual { + // Note: For some chains like Optimism these are technically predeploys (i.e. bytecode placed at a specific + // address), but the same rationale for excluding them applies so we include those too. + + // These are reserved by Ethereum and may be on all EVM-compatible chains. + vm.assume(addr < address(0x1) || addr > address(0xff)); + + // forgefmt: disable-start + if (chainId == 10 || chainId == 420) { + // https://github.com/ethereum-optimism/optimism/blob/eaa371a0184b56b7ca6d9eb9cb0a2b78b2ccd864/op-bindings/predeploys/addresses.go#L6-L21 + vm.assume(addr < address(0x4200000000000000000000000000000000000000) || addr > address(0x4200000000000000000000000000000000000800)); + } else if (chainId == 42161 || chainId == 421613) { + // https://developer.arbitrum.io/useful-addresses#arbitrum-precompiles-l2-same-on-all-arb-chains + vm.assume(addr < address(0x0000000000000000000000000000000000000064) || addr > address(0x0000000000000000000000000000000000000068)); + } else if (chainId == 43114 || chainId == 43113) { + // https://github.com/ava-labs/subnet-evm/blob/47c03fd007ecaa6de2c52ea081596e0a88401f58/precompile/params.go#L18-L59 + vm.assume(addr < address(0x0100000000000000000000000000000000000000) || addr > address(0x01000000000000000000000000000000000000ff)); + vm.assume(addr < address(0x0200000000000000000000000000000000000000) || addr > address(0x02000000000000000000000000000000000000FF)); + vm.assume(addr < address(0x0300000000000000000000000000000000000000) || addr > address(0x03000000000000000000000000000000000000Ff)); + } + // forgefmt: disable-end + } + + function assumeNotForgeAddress(address addr) internal pure virtual { + // vm, console, and Create2Deployer addresses + vm.assume( + addr != address(vm) && addr != 0x000000000000000000636F6e736F6c652e6c6f67 + && addr != 0x4e59b44847b379578588920cA78FbF26c0B4956C + ); + } + + function assumeUnusedAddress(address addr) internal view virtual { + uint256 size; + assembly { + size := extcodesize(addr) + } + vm.assume(size == 0); + + assumeNotPrecompile(addr); + assumeNotZeroAddress(addr); + assumeNotForgeAddress(addr); + } + + function readEIP1559ScriptArtifact(string memory path) + internal + view + virtual + returns (EIP1559ScriptArtifact memory) + { + string memory data = vm.readFile(path); + bytes memory parsedData = vm.parseJson(data); + RawEIP1559ScriptArtifact memory rawArtifact = abi.decode(parsedData, (RawEIP1559ScriptArtifact)); + EIP1559ScriptArtifact memory artifact; + artifact.libraries = rawArtifact.libraries; + artifact.path = rawArtifact.path; + artifact.timestamp = rawArtifact.timestamp; + artifact.pending = rawArtifact.pending; + artifact.txReturns = rawArtifact.txReturns; + artifact.receipts = rawToConvertedReceipts(rawArtifact.receipts); + artifact.transactions = rawToConvertedEIPTx1559s(rawArtifact.transactions); + return artifact; + } + + function rawToConvertedEIPTx1559s(RawTx1559[] memory rawTxs) internal pure virtual returns (Tx1559[] memory) { + Tx1559[] memory txs = new Tx1559[](rawTxs.length); + for (uint256 i; i < rawTxs.length; i++) { + txs[i] = rawToConvertedEIPTx1559(rawTxs[i]); + } + return txs; + } + + function rawToConvertedEIPTx1559(RawTx1559 memory rawTx) internal pure virtual returns (Tx1559 memory) { + Tx1559 memory transaction; + transaction.arguments = rawTx.arguments; + transaction.contractName = rawTx.contractName; + transaction.functionSig = rawTx.functionSig; + transaction.hash = rawTx.hash; + transaction.txDetail = rawToConvertedEIP1559Detail(rawTx.txDetail); + transaction.opcode = rawTx.opcode; + return transaction; + } + + function rawToConvertedEIP1559Detail(RawTx1559Detail memory rawDetail) + internal + pure + virtual + returns (Tx1559Detail memory) + { + Tx1559Detail memory txDetail; + txDetail.data = rawDetail.data; + txDetail.from = rawDetail.from; + txDetail.to = rawDetail.to; + txDetail.nonce = _bytesToUint(rawDetail.nonce); + txDetail.txType = _bytesToUint(rawDetail.txType); + txDetail.value = _bytesToUint(rawDetail.value); + txDetail.gas = _bytesToUint(rawDetail.gas); + txDetail.accessList = rawDetail.accessList; + return txDetail; + } + + function readTx1559s(string memory path) internal view virtual returns (Tx1559[] memory) { + string memory deployData = vm.readFile(path); + bytes memory parsedDeployData = vm.parseJson(deployData, ".transactions"); + RawTx1559[] memory rawTxs = abi.decode(parsedDeployData, (RawTx1559[])); + return rawToConvertedEIPTx1559s(rawTxs); + } + + function readTx1559(string memory path, uint256 index) internal view virtual returns (Tx1559 memory) { + string memory deployData = vm.readFile(path); + string memory key = string(abi.encodePacked(".transactions[", vm.toString(index), "]")); + bytes memory parsedDeployData = vm.parseJson(deployData, key); + RawTx1559 memory rawTx = abi.decode(parsedDeployData, (RawTx1559)); + return rawToConvertedEIPTx1559(rawTx); + } + + // Analogous to readTransactions, but for receipts. + function readReceipts(string memory path) internal view virtual returns (Receipt[] memory) { + string memory deployData = vm.readFile(path); + bytes memory parsedDeployData = vm.parseJson(deployData, ".receipts"); + RawReceipt[] memory rawReceipts = abi.decode(parsedDeployData, (RawReceipt[])); + return rawToConvertedReceipts(rawReceipts); + } + + function readReceipt(string memory path, uint256 index) internal view virtual returns (Receipt memory) { + string memory deployData = vm.readFile(path); + string memory key = string(abi.encodePacked(".receipts[", vm.toString(index), "]")); + bytes memory parsedDeployData = vm.parseJson(deployData, key); + RawReceipt memory rawReceipt = abi.decode(parsedDeployData, (RawReceipt)); + return rawToConvertedReceipt(rawReceipt); + } + + function rawToConvertedReceipts(RawReceipt[] memory rawReceipts) internal pure virtual returns (Receipt[] memory) { + Receipt[] memory receipts = new Receipt[](rawReceipts.length); + for (uint256 i; i < rawReceipts.length; i++) { + receipts[i] = rawToConvertedReceipt(rawReceipts[i]); + } + return receipts; + } + + function rawToConvertedReceipt(RawReceipt memory rawReceipt) internal pure virtual returns (Receipt memory) { + Receipt memory receipt; + receipt.blockHash = rawReceipt.blockHash; + receipt.to = rawReceipt.to; + receipt.from = rawReceipt.from; + receipt.contractAddress = rawReceipt.contractAddress; + receipt.effectiveGasPrice = _bytesToUint(rawReceipt.effectiveGasPrice); + receipt.cumulativeGasUsed = _bytesToUint(rawReceipt.cumulativeGasUsed); + receipt.gasUsed = _bytesToUint(rawReceipt.gasUsed); + receipt.status = _bytesToUint(rawReceipt.status); + receipt.transactionIndex = _bytesToUint(rawReceipt.transactionIndex); + receipt.blockNumber = _bytesToUint(rawReceipt.blockNumber); + receipt.logs = rawToConvertedReceiptLogs(rawReceipt.logs); + receipt.logsBloom = rawReceipt.logsBloom; + receipt.transactionHash = rawReceipt.transactionHash; + return receipt; + } + + function rawToConvertedReceiptLogs(RawReceiptLog[] memory rawLogs) + internal + pure + virtual + returns (ReceiptLog[] memory) + { + ReceiptLog[] memory logs = new ReceiptLog[](rawLogs.length); + for (uint256 i; i < rawLogs.length; i++) { + logs[i].logAddress = rawLogs[i].logAddress; + logs[i].blockHash = rawLogs[i].blockHash; + logs[i].blockNumber = _bytesToUint(rawLogs[i].blockNumber); + logs[i].data = rawLogs[i].data; + logs[i].logIndex = _bytesToUint(rawLogs[i].logIndex); + logs[i].topics = rawLogs[i].topics; + logs[i].transactionIndex = _bytesToUint(rawLogs[i].transactionIndex); + logs[i].transactionLogIndex = _bytesToUint(rawLogs[i].transactionLogIndex); + logs[i].removed = rawLogs[i].removed; + } + return logs; + } + + // Deploy a contract by fetching the contract bytecode from + // the artifacts directory + // e.g. `deployCode(code, abi.encode(arg1,arg2,arg3))` + function deployCode(string memory what, bytes memory args) internal virtual returns (address addr) { + bytes memory bytecode = abi.encodePacked(vm.getCode(what), args); + /// @solidity memory-safe-assembly + assembly { + addr := create(0, add(bytecode, 0x20), mload(bytecode)) + } + + require(addr != address(0), "StdCheats deployCode(string,bytes): Deployment failed."); + } + + function deployCode(string memory what) internal virtual returns (address addr) { + bytes memory bytecode = vm.getCode(what); + /// @solidity memory-safe-assembly + assembly { + addr := create(0, add(bytecode, 0x20), mload(bytecode)) + } + + require(addr != address(0), "StdCheats deployCode(string): Deployment failed."); + } + + /// @dev deploy contract with value on construction + function deployCode(string memory what, bytes memory args, uint256 val) internal virtual returns (address addr) { + bytes memory bytecode = abi.encodePacked(vm.getCode(what), args); + /// @solidity memory-safe-assembly + assembly { + addr := create(val, add(bytecode, 0x20), mload(bytecode)) + } + + require(addr != address(0), "StdCheats deployCode(string,bytes,uint256): Deployment failed."); + } + + function deployCode(string memory what, uint256 val) internal virtual returns (address addr) { + bytes memory bytecode = vm.getCode(what); + /// @solidity memory-safe-assembly + assembly { + addr := create(val, add(bytecode, 0x20), mload(bytecode)) + } + + require(addr != address(0), "StdCheats deployCode(string,uint256): Deployment failed."); + } + + // creates a labeled address and the corresponding private key + function makeAddrAndKey(string memory name) internal virtual returns (address addr, uint256 privateKey) { + privateKey = uint256(keccak256(abi.encodePacked(name))); + addr = vm.addr(privateKey); + vm.label(addr, name); + } + + // creates a labeled address + function makeAddr(string memory name) internal virtual returns (address addr) { + (addr,) = makeAddrAndKey(name); + } + + // Destroys an account immediately, sending the balance to beneficiary. + // Destroying means: balance will be zero, code will be empty, and nonce will be 0 + // This is similar to selfdestruct but not identical: selfdestruct destroys code and nonce + // only after tx ends, this will run immediately. + function destroyAccount(address who, address beneficiary) internal virtual { + uint256 currBalance = who.balance; + vm.etch(who, abi.encode()); + vm.deal(who, 0); + vm.resetNonce(who); + + uint256 beneficiaryBalance = beneficiary.balance; + vm.deal(beneficiary, currBalance + beneficiaryBalance); + } + + // creates a struct containing both a labeled address and the corresponding private key + function makeAccount(string memory name) internal virtual returns (Account memory account) { + (account.addr, account.key) = makeAddrAndKey(name); + } + + function deriveRememberKey(string memory mnemonic, uint32 index) + internal + virtual + returns (address who, uint256 privateKey) + { + privateKey = vm.deriveKey(mnemonic, index); + who = vm.rememberKey(privateKey); + } + + function _bytesToUint(bytes memory b) private pure returns (uint256) { + require(b.length <= 32, "StdCheats _bytesToUint(bytes): Bytes length exceeds 32."); + return abi.decode(abi.encodePacked(new bytes(32 - b.length), b), (uint256)); + } + + function isFork() internal view virtual returns (bool status) { + try vm.activeFork() { + status = true; + } catch (bytes memory) {} + } + + modifier skipWhenForking() { + if (!isFork()) { + _; + } + } + + modifier skipWhenNotForking() { + if (isFork()) { + _; + } + } + + modifier noGasMetering() { + vm.pauseGasMetering(); + // To prevent turning gas monitoring back on with nested functions that use this modifier, + // we check if gasMetering started in the off position. If it did, we don't want to turn + // it back on until we exit the top level function that used the modifier + // + // i.e. funcA() noGasMetering { funcB() }, where funcB has noGasMetering as well. + // funcA will have `gasStartedOff` as false, funcB will have it as true, + // so we only turn metering back on at the end of the funcA + bool gasStartedOff = gasMeteringOff; + gasMeteringOff = true; + + _; + + // if gas metering was on when this modifier was called, turn it back on at the end + if (!gasStartedOff) { + gasMeteringOff = false; + vm.resumeGasMetering(); + } + } + + // We use this complex approach of `_viewChainId` and `_pureChainId` to ensure there are no + // compiler warnings when accessing chain ID in any solidity version supported by forge-std. We + // can't simply access the chain ID in a normal view or pure function because the solc View Pure + // Checker changed `chainid` from pure to view in 0.8.0. + function _viewChainId() private view returns (uint256 chainId) { + // Assembly required since `block.chainid` was introduced in 0.8.0. + assembly { + chainId := chainid() + } + + address(this); // Silence warnings in older Solc versions. + } + + function _pureChainId() private pure returns (uint256 chainId) { + function() internal view returns (uint256) fnIn = _viewChainId; + function() internal pure returns (uint256) pureChainId; + assembly { + pureChainId := fnIn + } + chainId = pureChainId(); + } +} + +// Wrappers around cheatcodes to avoid footguns +abstract contract StdCheats is StdCheatsSafe { + using stdStorage for StdStorage; + + StdStorage private stdstore; + Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + address private constant CONSOLE2_ADDRESS = 0x000000000000000000636F6e736F6c652e6c6f67; + + // Skip forward or rewind time by the specified number of seconds + function skip(uint256 time) internal virtual { + vm.warp(vm.getBlockTimestamp() + time); + } + + function rewind(uint256 time) internal virtual { + vm.warp(vm.getBlockTimestamp() - time); + } + + // Setup a prank from an address that has some ether + function hoax(address msgSender) internal virtual { + vm.deal(msgSender, 1 << 128); + vm.prank(msgSender); + } + + function hoax(address msgSender, uint256 give) internal virtual { + vm.deal(msgSender, give); + vm.prank(msgSender); + } + + function hoax(address msgSender, address origin) internal virtual { + vm.deal(msgSender, 1 << 128); + vm.prank(msgSender, origin); + } + + function hoax(address msgSender, address origin, uint256 give) internal virtual { + vm.deal(msgSender, give); + vm.prank(msgSender, origin); + } + + // Start perpetual prank from an address that has some ether + function startHoax(address msgSender) internal virtual { + vm.deal(msgSender, 1 << 128); + vm.startPrank(msgSender); + } + + function startHoax(address msgSender, uint256 give) internal virtual { + vm.deal(msgSender, give); + vm.startPrank(msgSender); + } + + // Start perpetual prank from an address that has some ether + // tx.origin is set to the origin parameter + function startHoax(address msgSender, address origin) internal virtual { + vm.deal(msgSender, 1 << 128); + vm.startPrank(msgSender, origin); + } + + function startHoax(address msgSender, address origin, uint256 give) internal virtual { + vm.deal(msgSender, give); + vm.startPrank(msgSender, origin); + } + + function changePrank(address msgSender) internal virtual { + console2_log_StdCheats("changePrank is deprecated. Please use vm.startPrank instead."); + vm.stopPrank(); + vm.startPrank(msgSender); + } + + function changePrank(address msgSender, address txOrigin) internal virtual { + vm.stopPrank(); + vm.startPrank(msgSender, txOrigin); + } + + // The same as Vm's `deal` + // Use the alternative signature for ERC20 tokens + function deal(address to, uint256 give) internal virtual { + vm.deal(to, give); + } + + // Set the balance of an account for any ERC20 token + // Use the alternative signature to update `totalSupply` + function deal(address token, address to, uint256 give) internal virtual { + deal(token, to, give, false); + } + + // Set the balance of an account for any ERC1155 token + // Use the alternative signature to update `totalSupply` + function dealERC1155(address token, address to, uint256 id, uint256 give) internal virtual { + dealERC1155(token, to, id, give, false); + } + + function deal(address token, address to, uint256 give, bool adjust) internal virtual { + // get current balance + (, bytes memory balData) = token.staticcall(abi.encodeWithSelector(0x70a08231, to)); + uint256 prevBal = abi.decode(balData, (uint256)); + + // update balance + stdstore.target(token).sig(0x70a08231).with_key(to).checked_write(give); + + // update total supply + if (adjust) { + (, bytes memory totSupData) = token.staticcall(abi.encodeWithSelector(0x18160ddd)); + uint256 totSup = abi.decode(totSupData, (uint256)); + if (give < prevBal) { + totSup -= (prevBal - give); + } else { + totSup += (give - prevBal); + } + stdstore.target(token).sig(0x18160ddd).checked_write(totSup); + } + } + + function dealERC1155(address token, address to, uint256 id, uint256 give, bool adjust) internal virtual { + // get current balance + (, bytes memory balData) = token.staticcall(abi.encodeWithSelector(0x00fdd58e, to, id)); + uint256 prevBal = abi.decode(balData, (uint256)); + + // update balance + stdstore.target(token).sig(0x00fdd58e).with_key(to).with_key(id).checked_write(give); + + // update total supply + if (adjust) { + (, bytes memory totSupData) = token.staticcall(abi.encodeWithSelector(0xbd85b039, id)); + require( + totSupData.length != 0, + "StdCheats deal(address,address,uint,uint,bool): target contract is not ERC1155Supply." + ); + uint256 totSup = abi.decode(totSupData, (uint256)); + if (give < prevBal) { + totSup -= (prevBal - give); + } else { + totSup += (give - prevBal); + } + stdstore.target(token).sig(0xbd85b039).with_key(id).checked_write(totSup); + } + } + + function dealERC721(address token, address to, uint256 id) internal virtual { + // check if token id is already minted and the actual owner. + (bool successMinted, bytes memory ownerData) = token.staticcall(abi.encodeWithSelector(0x6352211e, id)); + require(successMinted, "StdCheats deal(address,address,uint,bool): id not minted."); + + // get owner current balance + (, bytes memory fromBalData) = + token.staticcall(abi.encodeWithSelector(0x70a08231, abi.decode(ownerData, (address)))); + uint256 fromPrevBal = abi.decode(fromBalData, (uint256)); + + // get new user current balance + (, bytes memory toBalData) = token.staticcall(abi.encodeWithSelector(0x70a08231, to)); + uint256 toPrevBal = abi.decode(toBalData, (uint256)); + + // update balances + stdstore.target(token).sig(0x70a08231).with_key(abi.decode(ownerData, (address))).checked_write(--fromPrevBal); + stdstore.target(token).sig(0x70a08231).with_key(to).checked_write(++toPrevBal); + + // update owner + stdstore.target(token).sig(0x6352211e).with_key(id).checked_write(to); + } + + function deployCodeTo(string memory what, address where) internal virtual { + deployCodeTo(what, "", 0, where); + } + + function deployCodeTo(string memory what, bytes memory args, address where) internal virtual { + deployCodeTo(what, args, 0, where); + } + + function deployCodeTo(string memory what, bytes memory args, uint256 value, address where) internal virtual { + bytes memory creationCode = vm.getCode(what); + vm.etch(where, abi.encodePacked(creationCode, args)); + (bool success, bytes memory runtimeBytecode) = where.call{value: value}(""); + require(success, "StdCheats deployCodeTo(string,bytes,uint256,address): Failed to create runtime bytecode."); + vm.etch(where, runtimeBytecode); + } + + // Used to prevent the compilation of console, which shortens the compilation time when console is not used elsewhere. + function console2_log_StdCheats(string memory p0) private view { + (bool status,) = address(CONSOLE2_ADDRESS).staticcall(abi.encodeWithSignature("log(string)", p0)); + status; + } +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdConfig.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdConfig.sol new file mode 100644 index 0000000000..506ac34a58 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdConfig.sol @@ -0,0 +1,612 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +import {VmSafe} from "./Vm.sol"; +import {Variable, Type, TypeKind, LibVariable} from "./LibVariable.sol"; + +/// @notice A contract that parses a toml configuration file and load its +/// variables into storage, automatically casting them, on deployment. +/// +/// @dev This contract assumes a toml structure where top-level keys +/// represent chain ids or aliases. Under each chain key, variables are +/// organized by type in separate sub-tables like `[.]`, where +/// type must be: `bool`, `address`, `bytes32`, `uint`, `Ƭnt`, `string`, or `bytes`. +/// +/// Supported format: +/// ``` +/// [mainnet] +/// endpoint_url = "${MAINNET_RPC}" +/// +/// [mainnet.bool] +/// is_live = true +/// +/// [mainnet.address] +/// weth = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" +/// whitelisted_admins = [ +/// "${MAINNET_ADMIN}", +/// "0x00000000000000000000000000000000deadbeef", +/// "0x000000000000000000000000000000c0ffeebabe" +/// ] +/// +/// [mainnet.uint] +/// important_number = 123 +/// ``` +contract StdConfig { + using LibVariable for Type; + using LibVariable for TypeKind; + + VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); + + /// @dev Types: `bool`, `address`, `bytes32`, `uint`, `Ƭnt`, `string`, `bytes`. + uint8 private constant NUM_TYPES = 7; + + // -- ERRORS --------------------------------------------------------------- + + error AlreadyInitialized(string key); + error InvalidChainKey(string aliasOrId); + error ChainNotInitialized(uint256 chainId); + error UnableToParseVariable(string key); + error WriteToFileInForbiddenCtxt(); + + // -- STORAGE (CACHE FROM CONFIG FILE) ------------------------------------ + + /// @dev Path to the loaded TOML configuration file. + string private _filePath; + + /// @dev List of top-level keys found in the TOML file, assumed to be chain names/aliases. + string[] private _chainKeys; + + /// @dev Storage for the configured RPC URL for each chain. + mapping(uint256 => string) private _rpcOf; + + /// @dev Storage for values, organized by chain ID and variable key. + mapping(uint256 => mapping(string => bytes)) private _dataOf; + + /// @dev Type cache for runtime checking when casting. + mapping(uint256 => mapping(string => Type)) private _typeOf; + + /// @dev When enabled, `set` will always write updates back to the configuration file. + /// Can only be enabled in a scripting context to prevent file corruption from + /// concurrent I/O access, as tests run in parallel. + bool private _writeToFile; + + // -- CONSTRUCTOR ---------------------------------------------------------- + + /// @notice Reads the TOML file and iterates through each top-level key, which is + /// assumed to be a chain name or ID. For each chain, it caches its RPC + /// endpoint and all variables defined in typed sub-tables like `[.]`, + /// where type must be: `bool`, `address`, `uint`, `bytes32`, `string`, or `bytes`. + /// + /// The constructor attempts to parse each variable first as a single value, + /// and if that fails, as an array of that type. If a variable cannot be + /// parsed as either, the constructor will revert with an error. + /// + /// @param configFilePath: The local path to the TOML configuration file. + /// @param writeToFile: Whether to write updates back to the TOML file. Only for scripts. + constructor(string memory configFilePath, bool writeToFile) { + if (writeToFile && !vm.isContext(VmSafe.ForgeContext.ScriptGroup)) { + revert WriteToFileInForbiddenCtxt(); + } + + _filePath = configFilePath; + _writeToFile = writeToFile; + string memory content = vm.resolveEnv(vm.readFile(configFilePath)); + string[] memory chain_keys = vm.parseTomlKeys(content, "$"); + + // Cache the entire configuration to storage + for (uint256 i = 0; i < chain_keys.length; i++) { + string memory chain_key = chain_keys[i]; + // Ignore top-level keys that are not tables + if (vm.parseTomlKeys(content, string.concat("$.", chain_key)).length == 0) { + continue; + } + uint256 chainId = resolveChainId(chain_key); + _chainKeys.push(chain_key); + + // Cache the configure rpc endpoint for that chain. + // Falls back to `[rpc_endpoints]`. Panics if no rpc endpoint is configured. + try vm.parseTomlString(content, string.concat("$.", chain_key, ".endpoint_url")) returns (string memory url) + { + _rpcOf[chainId] = vm.resolveEnv(url); + } catch { + _rpcOf[chainId] = vm.resolveEnv(vm.rpcUrl(chain_key)); + } + + // Iterate through all the available `TypeKind`s (except `None`) to create the sub-section paths + for (uint8 t = 1; t <= NUM_TYPES; t++) { + TypeKind ty = TypeKind(t); + string memory typePath = string.concat("$.", chain_key, ".", ty.toTomlKey()); + + try vm.parseTomlKeys(content, typePath) returns (string[] memory keys) { + for (uint256 j = 0; j < keys.length; j++) { + string memory key = keys[j]; + if (_typeOf[chainId][key].kind == TypeKind.None) { + _loadAndCacheValue(content, string.concat(typePath, ".", key), chainId, key, ty); + } else { + revert AlreadyInitialized(key); + } + } + } catch {} // Section does not exist, ignore. + } + } + } + + function _loadAndCacheValue( + string memory content, + string memory path, + uint256 chainId, + string memory key, + TypeKind ty + ) private { + bool success = false; + if (ty == TypeKind.Bool) { + try vm.parseTomlBool(content, path) returns (bool val) { + _dataOf[chainId][key] = abi.encode(val); + _typeOf[chainId][key] = Type(TypeKind.Bool, false); + success = true; + } catch { + try vm.parseTomlBoolArray(content, path) returns (bool[] memory val) { + _dataOf[chainId][key] = abi.encode(val); + _typeOf[chainId][key] = Type(TypeKind.Bool, true); + success = true; + } catch {} + } + } else if (ty == TypeKind.Address) { + try vm.parseTomlAddress(content, path) returns (address val) { + _dataOf[chainId][key] = abi.encode(val); + _typeOf[chainId][key] = Type(TypeKind.Address, false); + success = true; + } catch { + try vm.parseTomlAddressArray(content, path) returns (address[] memory val) { + _dataOf[chainId][key] = abi.encode(val); + _typeOf[chainId][key] = Type(TypeKind.Address, true); + success = true; + } catch {} + } + } else if (ty == TypeKind.Bytes32) { + try vm.parseTomlBytes32(content, path) returns (bytes32 val) { + _dataOf[chainId][key] = abi.encode(val); + _typeOf[chainId][key] = Type(TypeKind.Bytes32, false); + success = true; + } catch { + try vm.parseTomlBytes32Array(content, path) returns (bytes32[] memory val) { + _dataOf[chainId][key] = abi.encode(val); + _typeOf[chainId][key] = Type(TypeKind.Bytes32, true); + success = true; + } catch {} + } + } else if (ty == TypeKind.Uint256) { + try vm.parseTomlUint(content, path) returns (uint256 val) { + _dataOf[chainId][key] = abi.encode(val); + _typeOf[chainId][key] = Type(TypeKind.Uint256, false); + success = true; + } catch { + try vm.parseTomlUintArray(content, path) returns (uint256[] memory val) { + _dataOf[chainId][key] = abi.encode(val); + _typeOf[chainId][key] = Type(TypeKind.Uint256, true); + success = true; + } catch {} + } + } else if (ty == TypeKind.Int256) { + try vm.parseTomlInt(content, path) returns (int256 val) { + _dataOf[chainId][key] = abi.encode(val); + _typeOf[chainId][key] = Type(TypeKind.Int256, false); + success = true; + } catch { + try vm.parseTomlIntArray(content, path) returns (int256[] memory val) { + _dataOf[chainId][key] = abi.encode(val); + _typeOf[chainId][key] = Type(TypeKind.Int256, true); + success = true; + } catch {} + } + } else if (ty == TypeKind.Bytes) { + try vm.parseTomlBytes(content, path) returns (bytes memory val) { + _dataOf[chainId][key] = abi.encode(val); + _typeOf[chainId][key] = Type(TypeKind.Bytes, false); + success = true; + } catch { + try vm.parseTomlBytesArray(content, path) returns (bytes[] memory val) { + _dataOf[chainId][key] = abi.encode(val); + _typeOf[chainId][key] = Type(TypeKind.Bytes, true); + success = true; + } catch {} + } + } else if (ty == TypeKind.String) { + try vm.parseTomlString(content, path) returns (string memory val) { + _dataOf[chainId][key] = abi.encode(val); + _typeOf[chainId][key] = Type(TypeKind.String, false); + success = true; + } catch { + try vm.parseTomlStringArray(content, path) returns (string[] memory val) { + _dataOf[chainId][key] = abi.encode(val); + _typeOf[chainId][key] = Type(TypeKind.String, true); + success = true; + } catch {} + } + } + + if (!success) { + revert UnableToParseVariable(key); + } + } + + // -- HELPER FUNCTIONS ----------------------------------------------------- + + /// @notice Enable or disable automatic writing to the TOML file on `set`. + /// Can only be enabled when scripting. + function writeUpdatesBackToFile(bool enabled) public { + if (enabled && !vm.isContext(VmSafe.ForgeContext.ScriptGroup)) { + revert WriteToFileInForbiddenCtxt(); + } + + _writeToFile = enabled; + } + + /// @notice Resolves a chain alias or a chain id string to its numerical chain id. + /// @param aliasOrId The string representing the chain alias (i.e. "mainnet") or a numerical ID (i.e. "1"). + /// @return The numerical chain ID. + /// @dev It first attempts to parse the input as a number. If that fails, it uses `vm.getChain` to resolve a named alias. + /// Reverts if the alias is not valid or not a number. + function resolveChainId(string memory aliasOrId) public view returns (uint256) { + try vm.parseUint(aliasOrId) returns (uint256 chainId) { + return chainId; + } catch { + try vm.getChain(aliasOrId) returns (VmSafe.Chain memory chainInfo) { + return chainInfo.chainId; + } catch { + revert InvalidChainKey(aliasOrId); + } + } + } + + /// @dev Retrieves the chain key/alias from the configuration based on the chain ID. + function _getChainKeyFromId(uint256 chainId) private view returns (string memory) { + for (uint256 i = 0; i < _chainKeys.length; i++) { + if (resolveChainId(_chainKeys[i]) == chainId) { + return _chainKeys[i]; + } + } + revert ChainNotInitialized(chainId); + } + + /// @dev Ensures type consistency when setting a value - prevents changing types unless uninitialized. + /// Updates type only when the previous type was `None`. + function _ensureTypeConsistency(uint256 chainId, string memory key, Type memory ty) private { + Type memory current = _typeOf[chainId][key]; + + if (current.kind == TypeKind.None) { + _typeOf[chainId][key] = ty; + } else { + current.assertEq(ty); + } + } + + /// @dev Wraps a string in double quotes for JSON compatibility. + function _quote(string memory s) private pure returns (string memory) { + return string.concat('"', s, '"'); + } + + /// @dev Writes a JSON-formatted value to a specific key in the TOML file. + /// @param chainId The chain id to write under. + /// @param ty The type category ('bool', 'address', 'uint', 'bytes32', 'string', or 'bytes'). + /// @param key The variable key name. + /// @param jsonValue The JSON-formatted value to write. + function _writeToToml(uint256 chainId, string memory ty, string memory key, string memory jsonValue) private { + string memory chainKey = _getChainKeyFromId(chainId); + string memory valueKey = string.concat("$.", chainKey, ".", ty, ".", key); + vm.writeToml(jsonValue, _filePath, valueKey); + } + + // -- GETTER FUNCTIONS ----------------------------------------------------- + + /// @dev Reads a variable for a given chain id and key, and returns it in a generic container. + /// The caller should use `LibVariable` to safely coerce the type. + /// Example: `uint256 myVar = config.get("my_key").toUint256();` + /// + /// @param chain_id The chain ID to read from. + /// @param key The key of the variable to retrieve. + /// @return `Variable` struct containing the type and the ABI-encoded value. + function get(uint256 chain_id, string memory key) public view returns (Variable memory) { + return Variable(_typeOf[chain_id][key], _dataOf[chain_id][key]); + } + + /// @dev Reads a variable for the current chain and a given key, and returns it in a generic container. + /// The caller should use `LibVariable` to safely coerce the type. + /// Example: `uint256 myVar = config.get("my_key").toUint256();` + /// + /// @param key The key of the variable to retrieve. + /// @return `Variable` struct containing the type and the ABI-encoded value. + function get(string memory key) public view returns (Variable memory) { + return get(vm.getChainId(), key); + } + + /// @notice Returns the numerical chain ids for all configured chains. + function getChainIds() public view returns (uint256[] memory) { + string[] memory keys = _chainKeys; + + uint256[] memory ids = new uint256[](keys.length); + for (uint256 i = 0; i < keys.length; i++) { + ids[i] = resolveChainId(keys[i]); + } + + return ids; + } + + /// @notice Reads the RPC URL for a specific chain id. + function getRpcUrl(uint256 chainId) public view returns (string memory) { + return _rpcOf[chainId]; + } + + /// @notice Reads the RPC URL for the current chain. + function getRpcUrl() public view returns (string memory) { + return _rpcOf[vm.getChainId()]; + } + + // -- SETTER FUNCTIONS (SINGLE VALUES) ------------------------------------- + + /// @notice Sets a boolean value for a given key and chain ID. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(uint256 chainId, string memory key, bool value) public { + Type memory ty = Type(TypeKind.Bool, false); + _ensureTypeConsistency(chainId, key, ty); + _dataOf[chainId][key] = abi.encode(value); + if (_writeToFile) _writeToToml(chainId, ty.kind.toTomlKey(), key, vm.toString(value)); + } + + /// @notice Sets a boolean value for a given key on the current chain. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(string memory key, bool value) public { + set(vm.getChainId(), key, value); + } + + /// @notice Sets an address value for a given key and chain ID. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(uint256 chainId, string memory key, address value) public { + Type memory ty = Type(TypeKind.Address, false); + _ensureTypeConsistency(chainId, key, ty); + _dataOf[chainId][key] = abi.encode(value); + if (_writeToFile) _writeToToml(chainId, ty.kind.toTomlKey(), key, _quote(vm.toString(value))); + } + + /// @notice Sets an address value for a given key on the current chain. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(string memory key, address value) public { + set(vm.getChainId(), key, value); + } + + /// @notice Sets a bytes32 value for a given key and chain ID. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(uint256 chainId, string memory key, bytes32 value) public { + Type memory ty = Type(TypeKind.Bytes32, false); + _ensureTypeConsistency(chainId, key, ty); + _dataOf[chainId][key] = abi.encode(value); + if (_writeToFile) _writeToToml(chainId, ty.kind.toTomlKey(), key, _quote(vm.toString(value))); + } + + /// @notice Sets a bytes32 value for a given key on the current chain. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(string memory key, bytes32 value) public { + set(vm.getChainId(), key, value); + } + + /// @notice Sets a uint256 value for a given key and chain ID. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(uint256 chainId, string memory key, uint256 value) public { + Type memory ty = Type(TypeKind.Uint256, false); + _ensureTypeConsistency(chainId, key, ty); + _dataOf[chainId][key] = abi.encode(value); + if (_writeToFile) _writeToToml(chainId, ty.kind.toTomlKey(), key, vm.toString(value)); + } + + /// @notice Sets a uint256 value for a given key on the current chain. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(string memory key, uint256 value) public { + set(vm.getChainId(), key, value); + } + + /// @notice Sets an int256 value for a given key and chain ID. + function set(uint256 chainId, string memory key, int256 value) public { + Type memory ty = Type(TypeKind.Int256, false); + _ensureTypeConsistency(chainId, key, ty); + _dataOf[chainId][key] = abi.encode(value); + if (_writeToFile) _writeToToml(chainId, ty.kind.toTomlKey(), key, vm.toString(value)); + } + + /// @notice Sets an int256 value for a given key on the current chain. + function set(string memory key, int256 value) public { + set(vm.getChainId(), key, value); + } + + /// @notice Sets a string value for a given key and chain ID. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(uint256 chainId, string memory key, string memory value) public { + Type memory ty = Type(TypeKind.String, false); + _ensureTypeConsistency(chainId, key, ty); + _dataOf[chainId][key] = abi.encode(value); + if (_writeToFile) _writeToToml(chainId, ty.kind.toTomlKey(), key, _quote(value)); + } + + /// @notice Sets a string value for a given key on the current chain. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(string memory key, string memory value) public { + set(vm.getChainId(), key, value); + } + + /// @notice Sets a bytes value for a given key and chain ID. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(uint256 chainId, string memory key, bytes memory value) public { + Type memory ty = Type(TypeKind.Bytes, false); + _ensureTypeConsistency(chainId, key, ty); + _dataOf[chainId][key] = abi.encode(value); + if (_writeToFile) _writeToToml(chainId, ty.kind.toTomlKey(), key, _quote(vm.toString(value))); + } + + /// @notice Sets a bytes value for a given key on the current chain. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(string memory key, bytes memory value) public { + set(vm.getChainId(), key, value); + } + + // -- SETTER FUNCTIONS (ARRAYS) -------------------------------------------- + + /// @notice Sets a boolean array for a given key and chain ID. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(uint256 chainId, string memory key, bool[] memory value) public { + Type memory ty = Type(TypeKind.Bool, true); + _ensureTypeConsistency(chainId, key, ty); + _dataOf[chainId][key] = abi.encode(value); + if (_writeToFile) { + string memory json = "["; + for (uint256 i = 0; i < value.length; i++) { + json = string.concat(json, vm.toString(value[i])); + if (i < value.length - 1) json = string.concat(json, ","); + } + json = string.concat(json, "]"); + _writeToToml(chainId, ty.kind.toTomlKey(), key, json); + } + } + + /// @notice Sets a boolean array for a given key on the current chain. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(string memory key, bool[] memory value) public { + set(vm.getChainId(), key, value); + } + + /// @notice Sets an address array for a given key and chain ID. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(uint256 chainId, string memory key, address[] memory value) public { + Type memory ty = Type(TypeKind.Address, true); + _ensureTypeConsistency(chainId, key, ty); + _dataOf[chainId][key] = abi.encode(value); + if (_writeToFile) { + string memory json = "["; + for (uint256 i = 0; i < value.length; i++) { + json = string.concat(json, _quote(vm.toString(value[i]))); + if (i < value.length - 1) json = string.concat(json, ","); + } + json = string.concat(json, "]"); + _writeToToml(chainId, ty.kind.toTomlKey(), key, json); + } + } + + /// @notice Sets an address array for a given key on the current chain. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(string memory key, address[] memory value) public { + set(vm.getChainId(), key, value); + } + + /// @notice Sets a bytes32 array for a given key and chain ID. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(uint256 chainId, string memory key, bytes32[] memory value) public { + Type memory ty = Type(TypeKind.Bytes32, true); + _ensureTypeConsistency(chainId, key, ty); + _dataOf[chainId][key] = abi.encode(value); + if (_writeToFile) { + string memory json = "["; + for (uint256 i = 0; i < value.length; i++) { + json = string.concat(json, _quote(vm.toString(value[i]))); + if (i < value.length - 1) json = string.concat(json, ","); + } + json = string.concat(json, "]"); + _writeToToml(chainId, ty.kind.toTomlKey(), key, json); + } + } + + /// @notice Sets a bytes32 array for a given key on the current chain. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(string memory key, bytes32[] memory value) public { + set(vm.getChainId(), key, value); + } + + /// @notice Sets a uint256 array for a given key and chain ID. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(uint256 chainId, string memory key, uint256[] memory value) public { + Type memory ty = Type(TypeKind.Uint256, true); + _ensureTypeConsistency(chainId, key, ty); + _dataOf[chainId][key] = abi.encode(value); + if (_writeToFile) { + string memory json = "["; + for (uint256 i = 0; i < value.length; i++) { + json = string.concat(json, vm.toString(value[i])); + if (i < value.length - 1) json = string.concat(json, ","); + } + json = string.concat(json, "]"); + _writeToToml(chainId, ty.kind.toTomlKey(), key, json); + } + } + + /// @notice Sets a uint256 array for a given key on the current chain. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(string memory key, uint256[] memory value) public { + set(vm.getChainId(), key, value); + } + + /// @notice Sets a int256 array for a given key and chain ID. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(uint256 chainId, string memory key, int256[] memory value) public { + Type memory ty = Type(TypeKind.Int256, true); + _ensureTypeConsistency(chainId, key, ty); + _dataOf[chainId][key] = abi.encode(value); + if (_writeToFile) { + string memory json = "["; + for (uint256 i = 0; i < value.length; i++) { + json = string.concat(json, vm.toString(value[i])); + if (i < value.length - 1) json = string.concat(json, ","); + } + json = string.concat(json, "]"); + _writeToToml(chainId, ty.kind.toTomlKey(), key, json); + } + } + + /// @notice Sets a int256 array for a given key on the current chain. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(string memory key, int256[] memory value) public { + set(vm.getChainId(), key, value); + } + + /// @notice Sets a string array for a given key and chain ID. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(uint256 chainId, string memory key, string[] memory value) public { + Type memory ty = Type(TypeKind.String, true); + _ensureTypeConsistency(chainId, key, ty); + _dataOf[chainId][key] = abi.encode(value); + if (_writeToFile) { + string memory json = "["; + for (uint256 i = 0; i < value.length; i++) { + json = string.concat(json, _quote(value[i])); + if (i < value.length - 1) json = string.concat(json, ","); + } + json = string.concat(json, "]"); + _writeToToml(chainId, ty.kind.toTomlKey(), key, json); + } + } + + /// @notice Sets a string array for a given key on the current chain. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(string memory key, string[] memory value) public { + set(vm.getChainId(), key, value); + } + + /// @notice Sets a bytes array for a given key and chain ID. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(uint256 chainId, string memory key, bytes[] memory value) public { + Type memory ty = Type(TypeKind.Bytes, true); + _ensureTypeConsistency(chainId, key, ty); + _dataOf[chainId][key] = abi.encode(value); + if (_writeToFile) { + string memory json = "["; + for (uint256 i = 0; i < value.length; i++) { + json = string.concat(json, _quote(vm.toString(value[i]))); + if (i < value.length - 1) json = string.concat(json, ","); + } + json = string.concat(json, "]"); + _writeToToml(chainId, ty.kind.toTomlKey(), key, json); + } + } + + /// @notice Sets a bytes array for a given key on the current chain. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(string memory key, bytes[] memory value) public { + set(vm.getChainId(), key, value); + } +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdConstants.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdConstants.sol new file mode 100644 index 0000000000..2047d2b33d --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdConstants.sol @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +import {IMulticall3} from "./interfaces/IMulticall3.sol"; +import {Vm} from "./Vm.sol"; + +library StdConstants { + /// @dev Cheat code address. + /// Calculated as `address(uint160(uint256(keccak256("hevm cheat code"))))`. + Vm internal constant VM = Vm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); + /// @dev console.sol and console2.sol work by executing a staticcall to this address. + /// Calculated as `address(uint160(uint88(bytes11("console.log"))))`. + address internal constant CONSOLE = 0x000000000000000000636F6e736F6c652e6c6f67; + /// @dev Used when deploying with create2. + /// Taken from https://github.com/Arachnid/deterministic-deployment-proxy. + address internal constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C; + /// @dev The default address for tx.origin and msg.sender. + /// Calculated as `address(uint160(uint256(keccak256("foundry default caller"))))`. + address internal constant DEFAULT_SENDER = 0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38; + /// @dev The address of the first contract `CREATE`d by a running test contract. + /// When running tests, each test contract is `CREATE`d by `DEFAULT_SENDER` with nonce 1. + /// Calculated as `VM.computeCreateAddress(VM.computeCreateAddress(DEFAULT_SENDER, 1), 1)`. + address internal constant DEFAULT_TEST_CONTRACT = 0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f; + /// @dev Deterministic deployment address of the Multicall3 contract. + /// Taken from https://www.multicall3.com. + IMulticall3 internal constant MULTICALL3_ADDRESS = IMulticall3(0xcA11bde05977b3631167028862bE2a173976CA11); + /// @dev The order of the secp256k1 curve. + uint256 internal constant SECP256K1_ORDER = + 115792089237316195423570985008687907852837564279074904382605163141518161494337; +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdError.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdError.sol new file mode 100644 index 0000000000..a302191faa --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdError.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: MIT +// Panics work for versions >=0.8.0, but we lowered the pragma to make this compatible with Test +pragma solidity >=0.6.2 <0.9.0; + +library stdError { + bytes public constant assertionError = abi.encodeWithSignature("Panic(uint256)", 0x01); + bytes public constant arithmeticError = abi.encodeWithSignature("Panic(uint256)", 0x11); + bytes public constant divisionError = abi.encodeWithSignature("Panic(uint256)", 0x12); + bytes public constant enumConversionError = abi.encodeWithSignature("Panic(uint256)", 0x21); + bytes public constant encodeStorageError = abi.encodeWithSignature("Panic(uint256)", 0x22); + bytes public constant popError = abi.encodeWithSignature("Panic(uint256)", 0x31); + bytes public constant indexOOBError = abi.encodeWithSignature("Panic(uint256)", 0x32); + bytes public constant memOverflowError = abi.encodeWithSignature("Panic(uint256)", 0x41); + bytes public constant zeroVarError = abi.encodeWithSignature("Panic(uint256)", 0x51); +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdInvariant.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdInvariant.sol new file mode 100644 index 0000000000..056db98fcf --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdInvariant.sol @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +abstract contract StdInvariant { + struct FuzzSelector { + address addr; + bytes4[] selectors; + } + + struct FuzzArtifactSelector { + string artifact; + bytes4[] selectors; + } + + struct FuzzInterface { + address addr; + string[] artifacts; + } + + address[] private _excludedContracts; + address[] private _excludedSenders; + address[] private _targetedContracts; + address[] private _targetedSenders; + + string[] private _excludedArtifacts; + string[] private _targetedArtifacts; + + FuzzArtifactSelector[] private _targetedArtifactSelectors; + + FuzzSelector[] private _excludedSelectors; + FuzzSelector[] private _targetedSelectors; + + FuzzInterface[] private _targetedInterfaces; + + // Functions for users: + // These are intended to be called in tests. + + function excludeContract(address newExcludedContract_) internal { + _excludedContracts.push(newExcludedContract_); + } + + function excludeSelector(FuzzSelector memory newExcludedSelector_) internal { + _excludedSelectors.push(newExcludedSelector_); + } + + function excludeSender(address newExcludedSender_) internal { + _excludedSenders.push(newExcludedSender_); + } + + function excludeArtifact(string memory newExcludedArtifact_) internal { + _excludedArtifacts.push(newExcludedArtifact_); + } + + function targetArtifact(string memory newTargetedArtifact_) internal { + _targetedArtifacts.push(newTargetedArtifact_); + } + + function targetArtifactSelector(FuzzArtifactSelector memory newTargetedArtifactSelector_) internal { + _targetedArtifactSelectors.push(newTargetedArtifactSelector_); + } + + function targetContract(address newTargetedContract_) internal { + _targetedContracts.push(newTargetedContract_); + } + + function targetSelector(FuzzSelector memory newTargetedSelector_) internal { + _targetedSelectors.push(newTargetedSelector_); + } + + function targetSender(address newTargetedSender_) internal { + _targetedSenders.push(newTargetedSender_); + } + + function targetInterface(FuzzInterface memory newTargetedInterface_) internal { + _targetedInterfaces.push(newTargetedInterface_); + } + + // Functions for forge: + // These are called by forge to run invariant tests and don't need to be called in tests. + + function excludeArtifacts() public view returns (string[] memory excludedArtifacts_) { + excludedArtifacts_ = _excludedArtifacts; + } + + function excludeContracts() public view returns (address[] memory excludedContracts_) { + excludedContracts_ = _excludedContracts; + } + + function excludeSelectors() public view returns (FuzzSelector[] memory excludedSelectors_) { + excludedSelectors_ = _excludedSelectors; + } + + function excludeSenders() public view returns (address[] memory excludedSenders_) { + excludedSenders_ = _excludedSenders; + } + + function targetArtifacts() public view returns (string[] memory targetedArtifacts_) { + targetedArtifacts_ = _targetedArtifacts; + } + + function targetArtifactSelectors() public view returns (FuzzArtifactSelector[] memory targetedArtifactSelectors_) { + targetedArtifactSelectors_ = _targetedArtifactSelectors; + } + + function targetContracts() public view returns (address[] memory targetedContracts_) { + targetedContracts_ = _targetedContracts; + } + + function targetSelectors() public view returns (FuzzSelector[] memory targetedSelectors_) { + targetedSelectors_ = _targetedSelectors; + } + + function targetSenders() public view returns (address[] memory targetedSenders_) { + targetedSenders_ = _targetedSenders; + } + + function targetInterfaces() public view returns (FuzzInterface[] memory targetedInterfaces_) { + targetedInterfaces_ = _targetedInterfaces; + } +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdJson.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdJson.sol new file mode 100644 index 0000000000..2a033c03a7 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdJson.sol @@ -0,0 +1,283 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.0 <0.9.0; + +pragma experimental ABIEncoderV2; + +import {VmSafe} from "./Vm.sol"; + +// Helpers for parsing and writing JSON files +// To parse: +// ``` +// using stdJson for string; +// string memory json = vm.readFile(""); +// json.readUint(""); +// ``` +// To write: +// ``` +// using stdJson for string; +// string memory json = "json"; +// json.serialize("a", uint256(123)); +// string memory semiFinal = json.serialize("b", string("test")); +// string memory finalJson = json.serialize("c", semiFinal); +// finalJson.write(""); +// ``` + +library stdJson { + VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); + + function keyExists(string memory json, string memory key) internal view returns (bool) { + return vm.keyExistsJson(json, key); + } + + function parseRaw(string memory json, string memory key) internal pure returns (bytes memory) { + return vm.parseJson(json, key); + } + + function readUint(string memory json, string memory key) internal pure returns (uint256) { + return vm.parseJsonUint(json, key); + } + + function readUintArray(string memory json, string memory key) internal pure returns (uint256[] memory) { + return vm.parseJsonUintArray(json, key); + } + + function readInt(string memory json, string memory key) internal pure returns (int256) { + return vm.parseJsonInt(json, key); + } + + function readIntArray(string memory json, string memory key) internal pure returns (int256[] memory) { + return vm.parseJsonIntArray(json, key); + } + + function readBytes32(string memory json, string memory key) internal pure returns (bytes32) { + return vm.parseJsonBytes32(json, key); + } + + function readBytes32Array(string memory json, string memory key) internal pure returns (bytes32[] memory) { + return vm.parseJsonBytes32Array(json, key); + } + + function readString(string memory json, string memory key) internal pure returns (string memory) { + return vm.parseJsonString(json, key); + } + + function readStringArray(string memory json, string memory key) internal pure returns (string[] memory) { + return vm.parseJsonStringArray(json, key); + } + + function readAddress(string memory json, string memory key) internal pure returns (address) { + return vm.parseJsonAddress(json, key); + } + + function readAddressArray(string memory json, string memory key) internal pure returns (address[] memory) { + return vm.parseJsonAddressArray(json, key); + } + + function readBool(string memory json, string memory key) internal pure returns (bool) { + return vm.parseJsonBool(json, key); + } + + function readBoolArray(string memory json, string memory key) internal pure returns (bool[] memory) { + return vm.parseJsonBoolArray(json, key); + } + + function readBytes(string memory json, string memory key) internal pure returns (bytes memory) { + return vm.parseJsonBytes(json, key); + } + + function readBytesArray(string memory json, string memory key) internal pure returns (bytes[] memory) { + return vm.parseJsonBytesArray(json, key); + } + + function readUintOr(string memory json, string memory key, uint256 defaultValue) internal view returns (uint256) { + return keyExists(json, key) ? readUint(json, key) : defaultValue; + } + + function readUintArrayOr(string memory json, string memory key, uint256[] memory defaultValue) + internal + view + returns (uint256[] memory) + { + return keyExists(json, key) ? readUintArray(json, key) : defaultValue; + } + + function readIntOr(string memory json, string memory key, int256 defaultValue) internal view returns (int256) { + return keyExists(json, key) ? readInt(json, key) : defaultValue; + } + + function readIntArrayOr(string memory json, string memory key, int256[] memory defaultValue) + internal + view + returns (int256[] memory) + { + return keyExists(json, key) ? readIntArray(json, key) : defaultValue; + } + + function readBytes32Or(string memory json, string memory key, bytes32 defaultValue) + internal + view + returns (bytes32) + { + return keyExists(json, key) ? readBytes32(json, key) : defaultValue; + } + + function readBytes32ArrayOr(string memory json, string memory key, bytes32[] memory defaultValue) + internal + view + returns (bytes32[] memory) + { + return keyExists(json, key) ? readBytes32Array(json, key) : defaultValue; + } + + function readStringOr(string memory json, string memory key, string memory defaultValue) + internal + view + returns (string memory) + { + return keyExists(json, key) ? readString(json, key) : defaultValue; + } + + function readStringArrayOr(string memory json, string memory key, string[] memory defaultValue) + internal + view + returns (string[] memory) + { + return keyExists(json, key) ? readStringArray(json, key) : defaultValue; + } + + function readAddressOr(string memory json, string memory key, address defaultValue) + internal + view + returns (address) + { + return keyExists(json, key) ? readAddress(json, key) : defaultValue; + } + + function readAddressArrayOr(string memory json, string memory key, address[] memory defaultValue) + internal + view + returns (address[] memory) + { + return keyExists(json, key) ? readAddressArray(json, key) : defaultValue; + } + + function readBoolOr(string memory json, string memory key, bool defaultValue) internal view returns (bool) { + return keyExists(json, key) ? readBool(json, key) : defaultValue; + } + + function readBoolArrayOr(string memory json, string memory key, bool[] memory defaultValue) + internal + view + returns (bool[] memory) + { + return keyExists(json, key) ? readBoolArray(json, key) : defaultValue; + } + + function readBytesOr(string memory json, string memory key, bytes memory defaultValue) + internal + view + returns (bytes memory) + { + return keyExists(json, key) ? readBytes(json, key) : defaultValue; + } + + function readBytesArrayOr(string memory json, string memory key, bytes[] memory defaultValue) + internal + view + returns (bytes[] memory) + { + return keyExists(json, key) ? readBytesArray(json, key) : defaultValue; + } + + function serialize(string memory jsonKey, string memory rootObject) internal returns (string memory) { + return vm.serializeJson(jsonKey, rootObject); + } + + function serialize(string memory jsonKey, string memory key, bool value) internal returns (string memory) { + return vm.serializeBool(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, bool[] memory value) + internal + returns (string memory) + { + return vm.serializeBool(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, uint256 value) internal returns (string memory) { + return vm.serializeUint(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, uint256[] memory value) + internal + returns (string memory) + { + return vm.serializeUint(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, int256 value) internal returns (string memory) { + return vm.serializeInt(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, int256[] memory value) + internal + returns (string memory) + { + return vm.serializeInt(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, address value) internal returns (string memory) { + return vm.serializeAddress(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, address[] memory value) + internal + returns (string memory) + { + return vm.serializeAddress(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, bytes32 value) internal returns (string memory) { + return vm.serializeBytes32(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, bytes32[] memory value) + internal + returns (string memory) + { + return vm.serializeBytes32(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, bytes memory value) internal returns (string memory) { + return vm.serializeBytes(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, bytes[] memory value) + internal + returns (string memory) + { + return vm.serializeBytes(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, string memory value) + internal + returns (string memory) + { + return vm.serializeString(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, string[] memory value) + internal + returns (string memory) + { + return vm.serializeString(jsonKey, key, value); + } + + function write(string memory jsonKey, string memory path) internal { + vm.writeJson(jsonKey, path); + } + + function write(string memory jsonKey, string memory path, string memory valueKey) internal { + vm.writeJson(jsonKey, path, valueKey); + } +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdMath.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdMath.sol new file mode 100644 index 0000000000..459523bdac --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdMath.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +library stdMath { + int256 private constant INT256_MIN = -57896044618658097711785492504343953926634992332820282019728792003956564819968; + + function abs(int256 a) internal pure returns (uint256) { + // Required or it will fail when `a = type(int256).min` + if (a == INT256_MIN) { + return 57896044618658097711785492504343953926634992332820282019728792003956564819968; + } + + return uint256(a > 0 ? a : -a); + } + + function delta(uint256 a, uint256 b) internal pure returns (uint256) { + return a > b ? a - b : b - a; + } + + function delta(int256 a, int256 b) internal pure returns (uint256) { + // a and b are of the same sign + // this works thanks to two's complement, the left-most bit is the sign bit + if ((a ^ b) > -1) { + return delta(abs(a), abs(b)); + } + + // a and b are of opposite signs + return abs(a) + abs(b); + } + + function percentDelta(uint256 a, uint256 b) internal pure returns (uint256) { + uint256 absDelta = delta(a, b); + + return absDelta * 1e18 / b; + } + + function percentDelta(int256 a, int256 b) internal pure returns (uint256) { + uint256 absDelta = delta(a, b); + uint256 absB = abs(b); + + return absDelta * 1e18 / absB; + } +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdStorage.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdStorage.sol new file mode 100644 index 0000000000..1627af7534 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdStorage.sol @@ -0,0 +1,473 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +import {Vm} from "./Vm.sol"; + +struct FindData { + uint256 slot; + uint256 offsetLeft; + uint256 offsetRight; + bool found; +} + +struct StdStorage { + mapping(address => mapping(bytes4 => mapping(bytes32 => FindData))) finds; + bytes32[] _keys; + bytes4 _sig; + uint256 _depth; + address _target; + bytes32 _set; + bool _enable_packed_slots; + bytes _calldata; +} + +library stdStorageSafe { + event SlotFound(address who, bytes4 fsig, bytes32 keysHash, uint256 slot); + event WARNING_UninitedSlot(address who, uint256 slot); + + Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + uint256 constant UINT256_MAX = 115792089237316195423570985008687907853269984665640564039457584007913129639935; + + function sigs(string memory sigStr) internal pure returns (bytes4) { + return bytes4(keccak256(bytes(sigStr))); + } + + function getCallParams(StdStorage storage self) internal view returns (bytes memory) { + if (self._calldata.length == 0) { + return flatten(self._keys); + } else { + return self._calldata; + } + } + + // Calls target contract with configured parameters + function callTarget(StdStorage storage self) internal view returns (bool, bytes32) { + bytes memory cd = abi.encodePacked(self._sig, getCallParams(self)); + (bool success, bytes memory rdat) = self._target.staticcall(cd); + bytes32 result = bytesToBytes32(rdat, 32 * self._depth); + + return (success, result); + } + + // Tries mutating slot value to determine if the targeted value is stored in it. + // If current value is 0, then we are setting slot value to type(uint256).max + // Otherwise, we set it to 0. That way, return value should always be affected. + function checkSlotMutatesCall(StdStorage storage self, bytes32 slot) internal returns (bool) { + bytes32 prevSlotValue = vm.load(self._target, slot); + (bool success, bytes32 prevReturnValue) = callTarget(self); + + bytes32 testVal = prevReturnValue == bytes32(0) ? bytes32(UINT256_MAX) : bytes32(0); + vm.store(self._target, slot, testVal); + + (, bytes32 newReturnValue) = callTarget(self); + + vm.store(self._target, slot, prevSlotValue); + + return (success && (prevReturnValue != newReturnValue)); + } + + // Tries setting one of the bits in slot to 1 until return value changes. + // Index of resulted bit is an offset packed slot has from left/right side + function findOffset(StdStorage storage self, bytes32 slot, bool left) internal returns (bool, uint256) { + for (uint256 offset = 0; offset < 256; offset++) { + uint256 valueToPut = left ? (1 << (255 - offset)) : (1 << offset); + vm.store(self._target, slot, bytes32(valueToPut)); + + (bool success, bytes32 data) = callTarget(self); + + if (success && (uint256(data) > 0)) { + return (true, offset); + } + } + return (false, 0); + } + + function findOffsets(StdStorage storage self, bytes32 slot) internal returns (bool, uint256, uint256) { + bytes32 prevSlotValue = vm.load(self._target, slot); + + (bool foundLeft, uint256 offsetLeft) = findOffset(self, slot, true); + (bool foundRight, uint256 offsetRight) = findOffset(self, slot, false); + + // `findOffset` may mutate slot value, so we are setting it to initial value + vm.store(self._target, slot, prevSlotValue); + return (foundLeft && foundRight, offsetLeft, offsetRight); + } + + function find(StdStorage storage self) internal returns (FindData storage) { + return find(self, true); + } + + /// @notice find an arbitrary storage slot given a function sig, input data, address of the contract and a value to check against + // slot complexity: + // if flat, will be bytes32(uint256(uint)); + // if map, will be keccak256(abi.encode(key, uint(slot))); + // if deep map, will be keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot))))); + // if map struct, will be bytes32(uint256(keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot)))))) + structFieldDepth); + function find(StdStorage storage self, bool _clear) internal returns (FindData storage) { + address who = self._target; + bytes4 fsig = self._sig; + uint256 field_depth = self._depth; + bytes memory params = getCallParams(self); + + // calldata to test against + if (self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))].found) { + if (_clear) { + clear(self); + } + return self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))]; + } + vm.record(); + (, bytes32 callResult) = callTarget(self); + (bytes32[] memory reads,) = vm.accesses(address(who)); + + if (reads.length == 0) { + revert("stdStorage find(StdStorage): No storage use detected for target."); + } else { + for (uint256 i = reads.length; --i >= 0;) { + bytes32 prev = vm.load(who, reads[i]); + if (prev == bytes32(0)) { + emit WARNING_UninitedSlot(who, uint256(reads[i])); + } + + if (!checkSlotMutatesCall(self, reads[i])) { + continue; + } + + (uint256 offsetLeft, uint256 offsetRight) = (0, 0); + + if (self._enable_packed_slots) { + bool found; + (found, offsetLeft, offsetRight) = findOffsets(self, reads[i]); + if (!found) { + continue; + } + } + + // Check that value between found offsets is equal to the current call result + uint256 curVal = (uint256(prev) & getMaskByOffsets(offsetLeft, offsetRight)) >> offsetRight; + + if (uint256(callResult) != curVal) { + continue; + } + + emit SlotFound(who, fsig, keccak256(abi.encodePacked(params, field_depth)), uint256(reads[i])); + self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))] = + FindData(uint256(reads[i]), offsetLeft, offsetRight, true); + break; + } + } + + require( + self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))].found, + "stdStorage find(StdStorage): Slot(s) not found." + ); + + if (_clear) { + clear(self); + } + return self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))]; + } + + function target(StdStorage storage self, address _target) internal returns (StdStorage storage) { + self._target = _target; + return self; + } + + function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) { + self._sig = _sig; + return self; + } + + function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) { + self._sig = sigs(_sig); + return self; + } + + function with_calldata(StdStorage storage self, bytes memory _calldata) internal returns (StdStorage storage) { + self._calldata = _calldata; + return self; + } + + function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) { + self._keys.push(bytes32(uint256(uint160(who)))); + return self; + } + + function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) { + self._keys.push(bytes32(amt)); + return self; + } + + function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) { + self._keys.push(key); + return self; + } + + function enable_packed_slots(StdStorage storage self) internal returns (StdStorage storage) { + self._enable_packed_slots = true; + return self; + } + + function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) { + self._depth = _depth; + return self; + } + + function read(StdStorage storage self) private returns (bytes memory) { + FindData storage data = find(self, false); + uint256 mask = getMaskByOffsets(data.offsetLeft, data.offsetRight); + uint256 value = (uint256(vm.load(self._target, bytes32(data.slot))) & mask) >> data.offsetRight; + clear(self); + return abi.encode(value); + } + + function read_bytes32(StdStorage storage self) internal returns (bytes32) { + return abi.decode(read(self), (bytes32)); + } + + function read_bool(StdStorage storage self) internal returns (bool) { + int256 v = read_int(self); + if (v == 0) return false; + if (v == 1) return true; + revert("stdStorage read_bool(StdStorage): Cannot decode. Make sure you are reading a bool."); + } + + function read_address(StdStorage storage self) internal returns (address) { + return abi.decode(read(self), (address)); + } + + function read_uint(StdStorage storage self) internal returns (uint256) { + return abi.decode(read(self), (uint256)); + } + + function read_int(StdStorage storage self) internal returns (int256) { + return abi.decode(read(self), (int256)); + } + + function parent(StdStorage storage self) internal returns (uint256, bytes32) { + address who = self._target; + uint256 field_depth = self._depth; + vm.startMappingRecording(); + uint256 child = find(self, true).slot - field_depth; + (bool found, bytes32 key, bytes32 parent_slot) = vm.getMappingKeyAndParentOf(who, bytes32(child)); + if (!found) { + revert( + "stdStorage read_bool(StdStorage): Cannot find parent. Make sure you give a slot and startMappingRecording() has been called." + ); + } + return (uint256(parent_slot), key); + } + + function root(StdStorage storage self) internal returns (uint256) { + address who = self._target; + uint256 field_depth = self._depth; + vm.startMappingRecording(); + uint256 child = find(self, true).slot - field_depth; + bool found; + bytes32 root_slot; + bytes32 parent_slot; + (found,, parent_slot) = vm.getMappingKeyAndParentOf(who, bytes32(child)); + if (!found) { + revert( + "stdStorage read_bool(StdStorage): Cannot find parent. Make sure you give a slot and startMappingRecording() has been called." + ); + } + while (found) { + root_slot = parent_slot; + (found,, parent_slot) = vm.getMappingKeyAndParentOf(who, bytes32(root_slot)); + } + return uint256(root_slot); + } + + function bytesToBytes32(bytes memory b, uint256 offset) private pure returns (bytes32) { + bytes32 out; + + uint256 max = b.length > 32 ? 32 : b.length; + for (uint256 i = 0; i < max; i++) { + out |= bytes32(b[offset + i] & 0xFF) >> (i * 8); + } + return out; + } + + function flatten(bytes32[] memory b) private pure returns (bytes memory) { + bytes memory result = new bytes(b.length * 32); + for (uint256 i = 0; i < b.length; i++) { + bytes32 k = b[i]; + /// @solidity memory-safe-assembly + assembly { + mstore(add(result, add(32, mul(32, i))), k) + } + } + + return result; + } + + function clear(StdStorage storage self) internal { + delete self._target; + delete self._sig; + delete self._keys; + delete self._depth; + delete self._enable_packed_slots; + delete self._calldata; + } + + // Returns mask which contains non-zero bits for values between `offsetLeft` and `offsetRight` + // (slotValue & mask) >> offsetRight will be the value of the given packed variable + function getMaskByOffsets(uint256 offsetLeft, uint256 offsetRight) internal pure returns (uint256 mask) { + // mask = ((1 << (256 - (offsetRight + offsetLeft))) - 1) << offsetRight; + // using assembly because (1 << 256) causes overflow + assembly { + mask := shl(offsetRight, sub(shl(sub(256, add(offsetRight, offsetLeft)), 1), 1)) + } + } + + // Returns slot value with updated packed variable. + function getUpdatedSlotValue(bytes32 curValue, uint256 varValue, uint256 offsetLeft, uint256 offsetRight) + internal + pure + returns (bytes32 newValue) + { + return bytes32((uint256(curValue) & ~getMaskByOffsets(offsetLeft, offsetRight)) | (varValue << offsetRight)); + } +} + +library stdStorage { + Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + + function sigs(string memory sigStr) internal pure returns (bytes4) { + return stdStorageSafe.sigs(sigStr); + } + + function find(StdStorage storage self) internal returns (uint256) { + return find(self, true); + } + + function find(StdStorage storage self, bool _clear) internal returns (uint256) { + return stdStorageSafe.find(self, _clear).slot; + } + + function target(StdStorage storage self, address _target) internal returns (StdStorage storage) { + return stdStorageSafe.target(self, _target); + } + + function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) { + return stdStorageSafe.sig(self, _sig); + } + + function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) { + return stdStorageSafe.sig(self, _sig); + } + + function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) { + return stdStorageSafe.with_key(self, who); + } + + function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) { + return stdStorageSafe.with_key(self, amt); + } + + function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) { + return stdStorageSafe.with_key(self, key); + } + + function with_calldata(StdStorage storage self, bytes memory _calldata) internal returns (StdStorage storage) { + return stdStorageSafe.with_calldata(self, _calldata); + } + + function enable_packed_slots(StdStorage storage self) internal returns (StdStorage storage) { + return stdStorageSafe.enable_packed_slots(self); + } + + function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) { + return stdStorageSafe.depth(self, _depth); + } + + function clear(StdStorage storage self) internal { + stdStorageSafe.clear(self); + } + + function checked_write(StdStorage storage self, address who) internal { + checked_write(self, bytes32(uint256(uint160(who)))); + } + + function checked_write(StdStorage storage self, uint256 amt) internal { + checked_write(self, bytes32(amt)); + } + + function checked_write_int(StdStorage storage self, int256 val) internal { + checked_write(self, bytes32(uint256(val))); + } + + function checked_write(StdStorage storage self, bool write) internal { + bytes32 t; + /// @solidity memory-safe-assembly + assembly { + t := write + } + checked_write(self, t); + } + + function checked_write(StdStorage storage self, bytes32 set) internal { + address who = self._target; + bytes4 fsig = self._sig; + uint256 field_depth = self._depth; + bytes memory params = stdStorageSafe.getCallParams(self); + + if (!self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))].found) { + find(self, false); + } + FindData storage data = self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))]; + if ((data.offsetLeft + data.offsetRight) > 0) { + uint256 maxVal = 2 ** (256 - (data.offsetLeft + data.offsetRight)); + require( + uint256(set) < maxVal, + string( + abi.encodePacked( + "stdStorage find(StdStorage): Packed slot. We can't fit value greater than ", + vm.toString(maxVal) + ) + ) + ); + } + bytes32 curVal = vm.load(who, bytes32(data.slot)); + bytes32 valToSet = stdStorageSafe.getUpdatedSlotValue(curVal, uint256(set), data.offsetLeft, data.offsetRight); + + vm.store(who, bytes32(data.slot), valToSet); + + (bool success, bytes32 callResult) = stdStorageSafe.callTarget(self); + + if (!success || callResult != set) { + vm.store(who, bytes32(data.slot), curVal); + revert("stdStorage find(StdStorage): Failed to write value."); + } + clear(self); + } + + function read_bytes32(StdStorage storage self) internal returns (bytes32) { + return stdStorageSafe.read_bytes32(self); + } + + function read_bool(StdStorage storage self) internal returns (bool) { + return stdStorageSafe.read_bool(self); + } + + function read_address(StdStorage storage self) internal returns (address) { + return stdStorageSafe.read_address(self); + } + + function read_uint(StdStorage storage self) internal returns (uint256) { + return stdStorageSafe.read_uint(self); + } + + function read_int(StdStorage storage self) internal returns (int256) { + return stdStorageSafe.read_int(self); + } + + function parent(StdStorage storage self) internal returns (uint256, bytes32) { + return stdStorageSafe.parent(self); + } + + function root(StdStorage storage self) internal returns (uint256) { + return stdStorageSafe.root(self); + } +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdStyle.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdStyle.sol new file mode 100644 index 0000000000..d371e0c60a --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdStyle.sol @@ -0,0 +1,333 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.4.22 <0.9.0; + +import {VmSafe} from "./Vm.sol"; + +library StdStyle { + VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); + + string constant RED = "\u001b[91m"; + string constant GREEN = "\u001b[92m"; + string constant YELLOW = "\u001b[93m"; + string constant BLUE = "\u001b[94m"; + string constant MAGENTA = "\u001b[95m"; + string constant CYAN = "\u001b[96m"; + string constant BOLD = "\u001b[1m"; + string constant DIM = "\u001b[2m"; + string constant ITALIC = "\u001b[3m"; + string constant UNDERLINE = "\u001b[4m"; + string constant INVERSE = "\u001b[7m"; + string constant RESET = "\u001b[0m"; + + function styleConcat(string memory style, string memory self) private pure returns (string memory) { + return string(abi.encodePacked(style, self, RESET)); + } + + function red(string memory self) internal pure returns (string memory) { + return styleConcat(RED, self); + } + + function red(uint256 self) internal pure returns (string memory) { + return red(vm.toString(self)); + } + + function red(int256 self) internal pure returns (string memory) { + return red(vm.toString(self)); + } + + function red(address self) internal pure returns (string memory) { + return red(vm.toString(self)); + } + + function red(bool self) internal pure returns (string memory) { + return red(vm.toString(self)); + } + + function redBytes(bytes memory self) internal pure returns (string memory) { + return red(vm.toString(self)); + } + + function redBytes32(bytes32 self) internal pure returns (string memory) { + return red(vm.toString(self)); + } + + function green(string memory self) internal pure returns (string memory) { + return styleConcat(GREEN, self); + } + + function green(uint256 self) internal pure returns (string memory) { + return green(vm.toString(self)); + } + + function green(int256 self) internal pure returns (string memory) { + return green(vm.toString(self)); + } + + function green(address self) internal pure returns (string memory) { + return green(vm.toString(self)); + } + + function green(bool self) internal pure returns (string memory) { + return green(vm.toString(self)); + } + + function greenBytes(bytes memory self) internal pure returns (string memory) { + return green(vm.toString(self)); + } + + function greenBytes32(bytes32 self) internal pure returns (string memory) { + return green(vm.toString(self)); + } + + function yellow(string memory self) internal pure returns (string memory) { + return styleConcat(YELLOW, self); + } + + function yellow(uint256 self) internal pure returns (string memory) { + return yellow(vm.toString(self)); + } + + function yellow(int256 self) internal pure returns (string memory) { + return yellow(vm.toString(self)); + } + + function yellow(address self) internal pure returns (string memory) { + return yellow(vm.toString(self)); + } + + function yellow(bool self) internal pure returns (string memory) { + return yellow(vm.toString(self)); + } + + function yellowBytes(bytes memory self) internal pure returns (string memory) { + return yellow(vm.toString(self)); + } + + function yellowBytes32(bytes32 self) internal pure returns (string memory) { + return yellow(vm.toString(self)); + } + + function blue(string memory self) internal pure returns (string memory) { + return styleConcat(BLUE, self); + } + + function blue(uint256 self) internal pure returns (string memory) { + return blue(vm.toString(self)); + } + + function blue(int256 self) internal pure returns (string memory) { + return blue(vm.toString(self)); + } + + function blue(address self) internal pure returns (string memory) { + return blue(vm.toString(self)); + } + + function blue(bool self) internal pure returns (string memory) { + return blue(vm.toString(self)); + } + + function blueBytes(bytes memory self) internal pure returns (string memory) { + return blue(vm.toString(self)); + } + + function blueBytes32(bytes32 self) internal pure returns (string memory) { + return blue(vm.toString(self)); + } + + function magenta(string memory self) internal pure returns (string memory) { + return styleConcat(MAGENTA, self); + } + + function magenta(uint256 self) internal pure returns (string memory) { + return magenta(vm.toString(self)); + } + + function magenta(int256 self) internal pure returns (string memory) { + return magenta(vm.toString(self)); + } + + function magenta(address self) internal pure returns (string memory) { + return magenta(vm.toString(self)); + } + + function magenta(bool self) internal pure returns (string memory) { + return magenta(vm.toString(self)); + } + + function magentaBytes(bytes memory self) internal pure returns (string memory) { + return magenta(vm.toString(self)); + } + + function magentaBytes32(bytes32 self) internal pure returns (string memory) { + return magenta(vm.toString(self)); + } + + function cyan(string memory self) internal pure returns (string memory) { + return styleConcat(CYAN, self); + } + + function cyan(uint256 self) internal pure returns (string memory) { + return cyan(vm.toString(self)); + } + + function cyan(int256 self) internal pure returns (string memory) { + return cyan(vm.toString(self)); + } + + function cyan(address self) internal pure returns (string memory) { + return cyan(vm.toString(self)); + } + + function cyan(bool self) internal pure returns (string memory) { + return cyan(vm.toString(self)); + } + + function cyanBytes(bytes memory self) internal pure returns (string memory) { + return cyan(vm.toString(self)); + } + + function cyanBytes32(bytes32 self) internal pure returns (string memory) { + return cyan(vm.toString(self)); + } + + function bold(string memory self) internal pure returns (string memory) { + return styleConcat(BOLD, self); + } + + function bold(uint256 self) internal pure returns (string memory) { + return bold(vm.toString(self)); + } + + function bold(int256 self) internal pure returns (string memory) { + return bold(vm.toString(self)); + } + + function bold(address self) internal pure returns (string memory) { + return bold(vm.toString(self)); + } + + function bold(bool self) internal pure returns (string memory) { + return bold(vm.toString(self)); + } + + function boldBytes(bytes memory self) internal pure returns (string memory) { + return bold(vm.toString(self)); + } + + function boldBytes32(bytes32 self) internal pure returns (string memory) { + return bold(vm.toString(self)); + } + + function dim(string memory self) internal pure returns (string memory) { + return styleConcat(DIM, self); + } + + function dim(uint256 self) internal pure returns (string memory) { + return dim(vm.toString(self)); + } + + function dim(int256 self) internal pure returns (string memory) { + return dim(vm.toString(self)); + } + + function dim(address self) internal pure returns (string memory) { + return dim(vm.toString(self)); + } + + function dim(bool self) internal pure returns (string memory) { + return dim(vm.toString(self)); + } + + function dimBytes(bytes memory self) internal pure returns (string memory) { + return dim(vm.toString(self)); + } + + function dimBytes32(bytes32 self) internal pure returns (string memory) { + return dim(vm.toString(self)); + } + + function italic(string memory self) internal pure returns (string memory) { + return styleConcat(ITALIC, self); + } + + function italic(uint256 self) internal pure returns (string memory) { + return italic(vm.toString(self)); + } + + function italic(int256 self) internal pure returns (string memory) { + return italic(vm.toString(self)); + } + + function italic(address self) internal pure returns (string memory) { + return italic(vm.toString(self)); + } + + function italic(bool self) internal pure returns (string memory) { + return italic(vm.toString(self)); + } + + function italicBytes(bytes memory self) internal pure returns (string memory) { + return italic(vm.toString(self)); + } + + function italicBytes32(bytes32 self) internal pure returns (string memory) { + return italic(vm.toString(self)); + } + + function underline(string memory self) internal pure returns (string memory) { + return styleConcat(UNDERLINE, self); + } + + function underline(uint256 self) internal pure returns (string memory) { + return underline(vm.toString(self)); + } + + function underline(int256 self) internal pure returns (string memory) { + return underline(vm.toString(self)); + } + + function underline(address self) internal pure returns (string memory) { + return underline(vm.toString(self)); + } + + function underline(bool self) internal pure returns (string memory) { + return underline(vm.toString(self)); + } + + function underlineBytes(bytes memory self) internal pure returns (string memory) { + return underline(vm.toString(self)); + } + + function underlineBytes32(bytes32 self) internal pure returns (string memory) { + return underline(vm.toString(self)); + } + + function inverse(string memory self) internal pure returns (string memory) { + return styleConcat(INVERSE, self); + } + + function inverse(uint256 self) internal pure returns (string memory) { + return inverse(vm.toString(self)); + } + + function inverse(int256 self) internal pure returns (string memory) { + return inverse(vm.toString(self)); + } + + function inverse(address self) internal pure returns (string memory) { + return inverse(vm.toString(self)); + } + + function inverse(bool self) internal pure returns (string memory) { + return inverse(vm.toString(self)); + } + + function inverseBytes(bytes memory self) internal pure returns (string memory) { + return inverse(vm.toString(self)); + } + + function inverseBytes32(bytes32 self) internal pure returns (string memory) { + return inverse(vm.toString(self)); + } +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdToml.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdToml.sol new file mode 100644 index 0000000000..7ad3be2f97 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdToml.sol @@ -0,0 +1,283 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.0 <0.9.0; + +pragma experimental ABIEncoderV2; + +import {VmSafe} from "./Vm.sol"; + +// Helpers for parsing and writing TOML files +// To parse: +// ``` +// using stdToml for string; +// string memory toml = vm.readFile(""); +// toml.readUint(""); +// ``` +// To write: +// ``` +// using stdToml for string; +// string memory json = "json"; +// json.serialize("a", uint256(123)); +// string memory semiFinal = json.serialize("b", string("test")); +// string memory finalJson = json.serialize("c", semiFinal); +// finalJson.write(""); +// ``` + +library stdToml { + VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); + + function keyExists(string memory toml, string memory key) internal view returns (bool) { + return vm.keyExistsToml(toml, key); + } + + function parseRaw(string memory toml, string memory key) internal pure returns (bytes memory) { + return vm.parseToml(toml, key); + } + + function readUint(string memory toml, string memory key) internal pure returns (uint256) { + return vm.parseTomlUint(toml, key); + } + + function readUintArray(string memory toml, string memory key) internal pure returns (uint256[] memory) { + return vm.parseTomlUintArray(toml, key); + } + + function readInt(string memory toml, string memory key) internal pure returns (int256) { + return vm.parseTomlInt(toml, key); + } + + function readIntArray(string memory toml, string memory key) internal pure returns (int256[] memory) { + return vm.parseTomlIntArray(toml, key); + } + + function readBytes32(string memory toml, string memory key) internal pure returns (bytes32) { + return vm.parseTomlBytes32(toml, key); + } + + function readBytes32Array(string memory toml, string memory key) internal pure returns (bytes32[] memory) { + return vm.parseTomlBytes32Array(toml, key); + } + + function readString(string memory toml, string memory key) internal pure returns (string memory) { + return vm.parseTomlString(toml, key); + } + + function readStringArray(string memory toml, string memory key) internal pure returns (string[] memory) { + return vm.parseTomlStringArray(toml, key); + } + + function readAddress(string memory toml, string memory key) internal pure returns (address) { + return vm.parseTomlAddress(toml, key); + } + + function readAddressArray(string memory toml, string memory key) internal pure returns (address[] memory) { + return vm.parseTomlAddressArray(toml, key); + } + + function readBool(string memory toml, string memory key) internal pure returns (bool) { + return vm.parseTomlBool(toml, key); + } + + function readBoolArray(string memory toml, string memory key) internal pure returns (bool[] memory) { + return vm.parseTomlBoolArray(toml, key); + } + + function readBytes(string memory toml, string memory key) internal pure returns (bytes memory) { + return vm.parseTomlBytes(toml, key); + } + + function readBytesArray(string memory toml, string memory key) internal pure returns (bytes[] memory) { + return vm.parseTomlBytesArray(toml, key); + } + + function readUintOr(string memory toml, string memory key, uint256 defaultValue) internal view returns (uint256) { + return keyExists(toml, key) ? readUint(toml, key) : defaultValue; + } + + function readUintArrayOr(string memory toml, string memory key, uint256[] memory defaultValue) + internal + view + returns (uint256[] memory) + { + return keyExists(toml, key) ? readUintArray(toml, key) : defaultValue; + } + + function readIntOr(string memory toml, string memory key, int256 defaultValue) internal view returns (int256) { + return keyExists(toml, key) ? readInt(toml, key) : defaultValue; + } + + function readIntArrayOr(string memory toml, string memory key, int256[] memory defaultValue) + internal + view + returns (int256[] memory) + { + return keyExists(toml, key) ? readIntArray(toml, key) : defaultValue; + } + + function readBytes32Or(string memory toml, string memory key, bytes32 defaultValue) + internal + view + returns (bytes32) + { + return keyExists(toml, key) ? readBytes32(toml, key) : defaultValue; + } + + function readBytes32ArrayOr(string memory toml, string memory key, bytes32[] memory defaultValue) + internal + view + returns (bytes32[] memory) + { + return keyExists(toml, key) ? readBytes32Array(toml, key) : defaultValue; + } + + function readStringOr(string memory toml, string memory key, string memory defaultValue) + internal + view + returns (string memory) + { + return keyExists(toml, key) ? readString(toml, key) : defaultValue; + } + + function readStringArrayOr(string memory toml, string memory key, string[] memory defaultValue) + internal + view + returns (string[] memory) + { + return keyExists(toml, key) ? readStringArray(toml, key) : defaultValue; + } + + function readAddressOr(string memory toml, string memory key, address defaultValue) + internal + view + returns (address) + { + return keyExists(toml, key) ? readAddress(toml, key) : defaultValue; + } + + function readAddressArrayOr(string memory toml, string memory key, address[] memory defaultValue) + internal + view + returns (address[] memory) + { + return keyExists(toml, key) ? readAddressArray(toml, key) : defaultValue; + } + + function readBoolOr(string memory toml, string memory key, bool defaultValue) internal view returns (bool) { + return keyExists(toml, key) ? readBool(toml, key) : defaultValue; + } + + function readBoolArrayOr(string memory toml, string memory key, bool[] memory defaultValue) + internal + view + returns (bool[] memory) + { + return keyExists(toml, key) ? readBoolArray(toml, key) : defaultValue; + } + + function readBytesOr(string memory toml, string memory key, bytes memory defaultValue) + internal + view + returns (bytes memory) + { + return keyExists(toml, key) ? readBytes(toml, key) : defaultValue; + } + + function readBytesArrayOr(string memory toml, string memory key, bytes[] memory defaultValue) + internal + view + returns (bytes[] memory) + { + return keyExists(toml, key) ? readBytesArray(toml, key) : defaultValue; + } + + function serialize(string memory jsonKey, string memory rootObject) internal returns (string memory) { + return vm.serializeJson(jsonKey, rootObject); + } + + function serialize(string memory jsonKey, string memory key, bool value) internal returns (string memory) { + return vm.serializeBool(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, bool[] memory value) + internal + returns (string memory) + { + return vm.serializeBool(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, uint256 value) internal returns (string memory) { + return vm.serializeUint(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, uint256[] memory value) + internal + returns (string memory) + { + return vm.serializeUint(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, int256 value) internal returns (string memory) { + return vm.serializeInt(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, int256[] memory value) + internal + returns (string memory) + { + return vm.serializeInt(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, address value) internal returns (string memory) { + return vm.serializeAddress(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, address[] memory value) + internal + returns (string memory) + { + return vm.serializeAddress(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, bytes32 value) internal returns (string memory) { + return vm.serializeBytes32(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, bytes32[] memory value) + internal + returns (string memory) + { + return vm.serializeBytes32(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, bytes memory value) internal returns (string memory) { + return vm.serializeBytes(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, bytes[] memory value) + internal + returns (string memory) + { + return vm.serializeBytes(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, string memory value) + internal + returns (string memory) + { + return vm.serializeString(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, string[] memory value) + internal + returns (string memory) + { + return vm.serializeString(jsonKey, key, value); + } + + function write(string memory jsonKey, string memory path) internal { + vm.writeToml(jsonKey, path); + } + + function write(string memory jsonKey, string memory path, string memory valueKey) internal { + vm.writeToml(jsonKey, path, valueKey); + } +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdUtils.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdUtils.sol new file mode 100644 index 0000000000..9321df1430 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/StdUtils.sol @@ -0,0 +1,208 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +import {IMulticall3} from "./interfaces/IMulticall3.sol"; +import {VmSafe} from "./Vm.sol"; + +abstract contract StdUtils { + /*////////////////////////////////////////////////////////////////////////// + CONSTANTS + //////////////////////////////////////////////////////////////////////////*/ + + IMulticall3 private constant multicall = IMulticall3(0xcA11bde05977b3631167028862bE2a173976CA11); + VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); + address private constant CONSOLE2_ADDRESS = 0x000000000000000000636F6e736F6c652e6c6f67; + uint256 private constant INT256_MIN_ABS = + 57896044618658097711785492504343953926634992332820282019728792003956564819968; + uint256 private constant SECP256K1_ORDER = + 115792089237316195423570985008687907852837564279074904382605163141518161494337; + uint256 private constant UINT256_MAX = + 115792089237316195423570985008687907853269984665640564039457584007913129639935; + + // Used by default when deploying with create2, https://github.com/Arachnid/deterministic-deployment-proxy. + address private constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C; + + /*////////////////////////////////////////////////////////////////////////// + INTERNAL FUNCTIONS + //////////////////////////////////////////////////////////////////////////*/ + + function _bound(uint256 x, uint256 min, uint256 max) internal pure virtual returns (uint256 result) { + require(min <= max, "StdUtils bound(uint256,uint256,uint256): Max is less than min."); + // If x is between min and max, return x directly. This is to ensure that dictionary values + // do not get shifted if the min is nonzero. More info: https://github.com/foundry-rs/forge-std/issues/188 + if (x >= min && x <= max) return x; + + uint256 size = max - min + 1; + + // If the value is 0, 1, 2, 3, wrap that to min, min+1, min+2, min+3. Similarly for the UINT256_MAX side. + // This helps ensure coverage of the min/max values. + if (x <= 3 && size > x) return min + x; + if (x >= UINT256_MAX - 3 && size > UINT256_MAX - x) return max - (UINT256_MAX - x); + + // Otherwise, wrap x into the range [min, max], i.e. the range is inclusive. + if (x > max) { + uint256 diff = x - max; + uint256 rem = diff % size; + if (rem == 0) return max; + result = min + rem - 1; + } else if (x < min) { + uint256 diff = min - x; + uint256 rem = diff % size; + if (rem == 0) return min; + result = max - rem + 1; + } + } + + function bound(uint256 x, uint256 min, uint256 max) internal pure virtual returns (uint256 result) { + result = _bound(x, min, max); + console2_log_StdUtils("Bound result", result); + } + + function _bound(int256 x, int256 min, int256 max) internal pure virtual returns (int256 result) { + require(min <= max, "StdUtils bound(int256,int256,int256): Max is less than min."); + + // Shifting all int256 values to uint256 to use _bound function. The range of two types are: + // int256 : -(2**255) ~ (2**255 - 1) + // uint256: 0 ~ (2**256 - 1) + // So, add 2**255, INT256_MIN_ABS to the integer values. + // + // If the given integer value is -2**255, we cannot use `-uint256(-x)` because of the overflow. + // So, use `~uint256(x) + 1` instead. + uint256 _x = x < 0 ? (INT256_MIN_ABS - ~uint256(x) - 1) : (uint256(x) + INT256_MIN_ABS); + uint256 _min = min < 0 ? (INT256_MIN_ABS - ~uint256(min) - 1) : (uint256(min) + INT256_MIN_ABS); + uint256 _max = max < 0 ? (INT256_MIN_ABS - ~uint256(max) - 1) : (uint256(max) + INT256_MIN_ABS); + + uint256 y = _bound(_x, _min, _max); + + // To move it back to int256 value, subtract INT256_MIN_ABS at here. + result = y < INT256_MIN_ABS ? int256(~(INT256_MIN_ABS - y) + 1) : int256(y - INT256_MIN_ABS); + } + + function bound(int256 x, int256 min, int256 max) internal pure virtual returns (int256 result) { + result = _bound(x, min, max); + console2_log_StdUtils("Bound result", vm.toString(result)); + } + + function boundPrivateKey(uint256 privateKey) internal pure virtual returns (uint256 result) { + result = _bound(privateKey, 1, SECP256K1_ORDER - 1); + } + + function bytesToUint(bytes memory b) internal pure virtual returns (uint256) { + require(b.length <= 32, "StdUtils bytesToUint(bytes): Bytes length exceeds 32."); + return abi.decode(abi.encodePacked(new bytes(32 - b.length), b), (uint256)); + } + + /// @dev Compute the address a contract will be deployed at for a given deployer address and nonce + function computeCreateAddress(address deployer, uint256 nonce) internal pure virtual returns (address) { + console2_log_StdUtils("computeCreateAddress is deprecated. Please use vm.computeCreateAddress instead."); + return vm.computeCreateAddress(deployer, nonce); + } + + function computeCreate2Address(bytes32 salt, bytes32 initcodeHash, address deployer) + internal + pure + virtual + returns (address) + { + console2_log_StdUtils("computeCreate2Address is deprecated. Please use vm.computeCreate2Address instead."); + return vm.computeCreate2Address(salt, initcodeHash, deployer); + } + + /// @dev returns the address of a contract created with CREATE2 using the default CREATE2 deployer + function computeCreate2Address(bytes32 salt, bytes32 initCodeHash) internal pure returns (address) { + console2_log_StdUtils("computeCreate2Address is deprecated. Please use vm.computeCreate2Address instead."); + return vm.computeCreate2Address(salt, initCodeHash); + } + + /// @dev returns the hash of the init code (creation code + no args) used in CREATE2 with no constructor arguments + /// @param creationCode the creation code of a contract C, as returned by type(C).creationCode + function hashInitCode(bytes memory creationCode) internal pure returns (bytes32) { + return hashInitCode(creationCode, ""); + } + + /// @dev returns the hash of the init code (creation code + ABI-encoded args) used in CREATE2 + /// @param creationCode the creation code of a contract C, as returned by type(C).creationCode + /// @param args the ABI-encoded arguments to the constructor of C + function hashInitCode(bytes memory creationCode, bytes memory args) internal pure returns (bytes32) { + return keccak256(abi.encodePacked(creationCode, args)); + } + + // Performs a single call with Multicall3 to query the ERC-20 token balances of the given addresses. + function getTokenBalances(address token, address[] memory addresses) + internal + virtual + returns (uint256[] memory balances) + { + uint256 tokenCodeSize; + assembly { + tokenCodeSize := extcodesize(token) + } + require(tokenCodeSize > 0, "StdUtils getTokenBalances(address,address[]): Token address is not a contract."); + + // ABI encode the aggregate call to Multicall3. + uint256 length = addresses.length; + IMulticall3.Call[] memory calls = new IMulticall3.Call[](length); + for (uint256 i = 0; i < length; ++i) { + // 0x70a08231 = bytes4("balanceOf(address)")) + calls[i] = IMulticall3.Call({target: token, callData: abi.encodeWithSelector(0x70a08231, (addresses[i]))}); + } + + // Make the aggregate call. + (, bytes[] memory returnData) = multicall.aggregate(calls); + + // ABI decode the return data and return the balances. + balances = new uint256[](length); + for (uint256 i = 0; i < length; ++i) { + balances[i] = abi.decode(returnData[i], (uint256)); + } + } + + /*////////////////////////////////////////////////////////////////////////// + PRIVATE FUNCTIONS + //////////////////////////////////////////////////////////////////////////*/ + + function addressFromLast20Bytes(bytes32 bytesValue) private pure returns (address) { + return address(uint160(uint256(bytesValue))); + } + + // This section is used to prevent the compilation of console, which shortens the compilation time when console is + // not used elsewhere. We also trick the compiler into letting us make the console log methods as `pure` to avoid + // any breaking changes to function signatures. + function _castLogPayloadViewToPure(function(bytes memory) internal view fnIn) + internal + pure + returns (function(bytes memory) internal pure fnOut) + { + assembly { + fnOut := fnIn + } + } + + function _sendLogPayload(bytes memory payload) internal pure { + _castLogPayloadViewToPure(_sendLogPayloadView)(payload); + } + + function _sendLogPayloadView(bytes memory payload) private view { + uint256 payloadLength = payload.length; + address consoleAddress = CONSOLE2_ADDRESS; + /// @solidity memory-safe-assembly + assembly { + let payloadStart := add(payload, 32) + let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0) + } + } + + function console2_log_StdUtils(string memory p0) private pure { + _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); + } + + function console2_log_StdUtils(string memory p0, uint256 p1) private pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256)", p0, p1)); + } + + function console2_log_StdUtils(string memory p0, string memory p1) private pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1)); + } +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/Test.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/Test.sol new file mode 100644 index 0000000000..11b18f29f3 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/Test.sol @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +// šŸ’¬ ABOUT +// Forge Std's default Test. + +// 🧩 MODULES +import {console} from "./console.sol"; +import {console2} from "./console2.sol"; +import {safeconsole} from "./safeconsole.sol"; +import {StdAssertions} from "./StdAssertions.sol"; +import {StdChains} from "./StdChains.sol"; +import {StdCheats} from "./StdCheats.sol"; +import {StdConstants} from "./StdConstants.sol"; +import {stdError} from "./StdError.sol"; +import {StdInvariant} from "./StdInvariant.sol"; +import {stdJson} from "./StdJson.sol"; +import {stdMath} from "./StdMath.sol"; +import {StdStorage, stdStorage} from "./StdStorage.sol"; +import {StdStyle} from "./StdStyle.sol"; +import {stdToml} from "./StdToml.sol"; +import {StdUtils} from "./StdUtils.sol"; +import {Vm} from "./Vm.sol"; + +// šŸ“¦ BOILERPLATE +import {TestBase} from "./Base.sol"; + +// ā­ļø TEST +abstract contract Test is TestBase, StdAssertions, StdChains, StdCheats, StdInvariant, StdUtils { + // Note: IS_TEST() must return true. + bool public IS_TEST = true; +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/Vm.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/Vm.sol new file mode 100644 index 0000000000..cd883706a1 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/Vm.sol @@ -0,0 +1,2494 @@ +// Automatically @generated by scripts/vm.py. Do not modify manually. + +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity >=0.6.2 <0.9.0; +pragma experimental ABIEncoderV2; + +/// The `VmSafe` interface does not allow manipulation of the EVM state or other actions that may +/// result in Script simulations differing from on-chain execution. It is recommended to only use +/// these cheats in scripts. +interface VmSafe { + /// A modification applied to either `msg.sender` or `tx.origin`. Returned by `readCallers`. + enum CallerMode { + // No caller modification is currently active. + None, + // A one time broadcast triggered by a `vm.broadcast()` call is currently active. + Broadcast, + // A recurrent broadcast triggered by a `vm.startBroadcast()` call is currently active. + RecurrentBroadcast, + // A one time prank triggered by a `vm.prank()` call is currently active. + Prank, + // A recurrent prank triggered by a `vm.startPrank()` call is currently active. + RecurrentPrank + } + + /// The kind of account access that occurred. + enum AccountAccessKind { + // The account was called. + Call, + // The account was called via delegatecall. + DelegateCall, + // The account was called via callcode. + CallCode, + // The account was called via staticcall. + StaticCall, + // The account was created. + Create, + // The account was selfdestructed. + SelfDestruct, + // Synthetic access indicating the current context has resumed after a previous sub-context (AccountAccess). + Resume, + // The account's balance was read. + Balance, + // The account's codesize was read. + Extcodesize, + // The account's codehash was read. + Extcodehash, + // The account's code was copied. + Extcodecopy + } + + /// Forge execution contexts. + enum ForgeContext { + // Test group execution context (test, coverage or snapshot). + TestGroup, + // `forge test` execution context. + Test, + // `forge coverage` execution context. + Coverage, + // `forge snapshot` execution context. + Snapshot, + // Script group execution context (dry run, broadcast or resume). + ScriptGroup, + // `forge script` execution context. + ScriptDryRun, + // `forge script --broadcast` execution context. + ScriptBroadcast, + // `forge script --resume` execution context. + ScriptResume, + // Unknown `forge` execution context. + Unknown + } + + /// The transaction type (`txType`) of the broadcast. + enum BroadcastTxType { + // Represents a CALL broadcast tx. + Call, + // Represents a CREATE broadcast tx. + Create, + // Represents a CREATE2 broadcast tx. + Create2 + } + + /// An Ethereum log. Returned by `getRecordedLogs`. + struct Log { + // The topics of the log, including the signature, if any. + bytes32[] topics; + // The raw data of the log. + bytes data; + // The address of the log's emitter. + address emitter; + } + + /// An RPC URL and its alias. Returned by `rpcUrlStructs`. + struct Rpc { + // The alias of the RPC URL. + string key; + // The RPC URL. + string url; + } + + /// An RPC log object. Returned by `eth_getLogs`. + struct EthGetLogs { + // The address of the log's emitter. + address emitter; + // The topics of the log, including the signature, if any. + bytes32[] topics; + // The raw data of the log. + bytes data; + // The block hash. + bytes32 blockHash; + // The block number. + uint64 blockNumber; + // The transaction hash. + bytes32 transactionHash; + // The transaction index in the block. + uint64 transactionIndex; + // The log index. + uint256 logIndex; + // Whether the log was removed. + bool removed; + } + + /// A single entry in a directory listing. Returned by `readDir`. + struct DirEntry { + // The error message, if any. + string errorMessage; + // The path of the entry. + string path; + // The depth of the entry. + uint64 depth; + // Whether the entry is a directory. + bool isDir; + // Whether the entry is a symlink. + bool isSymlink; + } + + /// Metadata information about a file. + /// This structure is returned from the `fsMetadata` function and represents known + /// metadata about a file such as its permissions, size, modification + /// times, etc. + struct FsMetadata { + // True if this metadata is for a directory. + bool isDir; + // True if this metadata is for a symlink. + bool isSymlink; + // The size of the file, in bytes, this metadata is for. + uint256 length; + // True if this metadata is for a readonly (unwritable) file. + bool readOnly; + // The last modification time listed in this metadata. + uint256 modified; + // The last access time of this metadata. + uint256 accessed; + // The creation time listed in this metadata. + uint256 created; + } + + /// A wallet with a public and private key. + struct Wallet { + // The wallet's address. + address addr; + // The wallet's public key `X`. + uint256 publicKeyX; + // The wallet's public key `Y`. + uint256 publicKeyY; + // The wallet's private key. + uint256 privateKey; + } + + /// The result of a `tryFfi` call. + struct FfiResult { + // The exit code of the call. + int32 exitCode; + // The optionally hex-decoded `stdout` data. + bytes stdout; + // The `stderr` data. + bytes stderr; + } + + /// Information on the chain and fork. + struct ChainInfo { + // The fork identifier. Set to zero if no fork is active. + uint256 forkId; + // The chain ID of the current fork. + uint256 chainId; + } + + /// Information about a blockchain. + struct Chain { + // The chain name. + string name; + // The chain's Chain ID. + uint256 chainId; + // The chain's alias. (i.e. what gets specified in `foundry.toml`). + string chainAlias; + // A default RPC endpoint for this chain. + string rpcUrl; + } + + /// The result of a `stopAndReturnStateDiff` call. + struct AccountAccess { + // The chain and fork the access occurred. + ChainInfo chainInfo; + // The kind of account access that determines what the account is. + // If kind is Call, DelegateCall, StaticCall or CallCode, then the account is the callee. + // If kind is Create, then the account is the newly created account. + // If kind is SelfDestruct, then the account is the selfdestruct recipient. + // If kind is a Resume, then account represents a account context that has resumed. + AccountAccessKind kind; + // The account that was accessed. + // It's either the account created, callee or a selfdestruct recipient for CREATE, CALL or SELFDESTRUCT. + address account; + // What accessed the account. + address accessor; + // If the account was initialized or empty prior to the access. + // An account is considered initialized if it has code, a + // non-zero nonce, or a non-zero balance. + bool initialized; + // The previous balance of the accessed account. + uint256 oldBalance; + // The potential new balance of the accessed account. + // That is, all balance changes are recorded here, even if reverts occurred. + uint256 newBalance; + // Code of the account deployed by CREATE. + bytes deployedCode; + // Value passed along with the account access + uint256 value; + // Input data provided to the CREATE or CALL + bytes data; + // If this access reverted in either the current or parent context. + bool reverted; + // An ordered list of storage accesses made during an account access operation. + StorageAccess[] storageAccesses; + // Call depth traversed during the recording of state differences + uint64 depth; + // The previous nonce of the accessed account. + uint64 oldNonce; + // The new nonce of the accessed account. + uint64 newNonce; + } + + /// The storage accessed during an `AccountAccess`. + struct StorageAccess { + // The account whose storage was accessed. + address account; + // The slot that was accessed. + bytes32 slot; + // If the access was a write. + bool isWrite; + // The previous value of the slot. + bytes32 previousValue; + // The new value of the slot. + bytes32 newValue; + // If the access was reverted. + bool reverted; + } + + /// Gas used. Returned by `lastCallGas`. + struct Gas { + // The gas limit of the call. + uint64 gasLimit; + // The total gas used. + uint64 gasTotalUsed; + // DEPRECATED: The amount of gas used for memory expansion. Ref: + uint64 gasMemoryUsed; + // The amount of gas refunded. + int64 gasRefunded; + // The amount of gas remaining. + uint64 gasRemaining; + } + + /// The result of the `stopDebugTraceRecording` call + struct DebugStep { + // The stack before executing the step of the run. + // stack\[0\] represents the top of the stack. + // and only stack data relevant to the opcode execution is contained. + uint256[] stack; + // The memory input data before executing the step of the run. + // only input data relevant to the opcode execution is contained. + // e.g. for MLOAD, it will have memory\[offset:offset+32\] copied here. + // the offset value can be get by the stack data. + bytes memoryInput; + // The opcode that was accessed. + uint8 opcode; + // The call depth of the step. + uint64 depth; + // Whether the call end up with out of gas error. + bool isOutOfGas; + // The contract address where the opcode is running + address contractAddr; + } + + /// Represents a transaction's broadcast details. + struct BroadcastTxSummary { + // The hash of the transaction that was broadcasted + bytes32 txHash; + // Represent the type of transaction among CALL, CREATE, CREATE2 + BroadcastTxType txType; + // The address of the contract that was called or created. + // This is address of the contract that is created if the txType is CREATE or CREATE2. + address contractAddress; + // The block number the transaction landed in. + uint64 blockNumber; + // Status of the transaction, retrieved from the transaction receipt. + bool success; + } + + /// Holds a signed EIP-7702 authorization for an authority account to delegate to an implementation. + struct SignedDelegation { + // The y-parity of the recovered secp256k1 signature (0 or 1). + uint8 v; + // First 32 bytes of the signature. + bytes32 r; + // Second 32 bytes of the signature. + bytes32 s; + // The current nonce of the authority account at signing time. + // Used to ensure signature can't be replayed after account nonce changes. + uint64 nonce; + // Address of the contract implementation that will be delegated to. + // Gets encoded into delegation code: 0xef0100 || implementation. + address implementation; + } + + /// Represents a "potential" revert reason from a single subsequent call when using `vm.assumeNoReverts`. + /// Reverts that match will result in a FOUNDRY::ASSUME rejection, whereas unmatched reverts will be surfaced + /// as normal. + struct PotentialRevert { + // The allowed origin of the revert opcode; address(0) allows reverts from any address + address reverter; + // When true, only matches on the beginning of the revert data, otherwise, matches on entire revert data + bool partialMatch; + // The data to use to match encountered reverts + bytes revertData; + } + + /// An EIP-2930 access list item. + struct AccessListItem { + // The address to be added in access list. + address target; + // The storage keys to be added in access list. + bytes32[] storageKeys; + } + + // ======== Crypto ======== + + /// Derives a private key from the name, labels the account with that name, and returns the wallet. + function createWallet(string calldata walletLabel) external returns (Wallet memory wallet); + + /// Generates a wallet from the private key and returns the wallet. + function createWallet(uint256 privateKey) external returns (Wallet memory wallet); + + /// Generates a wallet from the private key, labels the account with that name, and returns the wallet. + function createWallet(uint256 privateKey, string calldata walletLabel) external returns (Wallet memory wallet); + + /// Derive a private key from a provided mnemonic string (or mnemonic file path) + /// at the derivation path `m/44'/60'/0'/0/{index}`. + function deriveKey(string calldata mnemonic, uint32 index) external pure returns (uint256 privateKey); + + /// Derive a private key from a provided mnemonic string (or mnemonic file path) + /// at `{derivationPath}{index}`. + function deriveKey(string calldata mnemonic, string calldata derivationPath, uint32 index) + external + pure + returns (uint256 privateKey); + + /// Derive a private key from a provided mnemonic string (or mnemonic file path) in the specified language + /// at the derivation path `m/44'/60'/0'/0/{index}`. + function deriveKey(string calldata mnemonic, uint32 index, string calldata language) + external + pure + returns (uint256 privateKey); + + /// Derive a private key from a provided mnemonic string (or mnemonic file path) in the specified language + /// at `{derivationPath}{index}`. + function deriveKey(string calldata mnemonic, string calldata derivationPath, uint32 index, string calldata language) + external + pure + returns (uint256 privateKey); + + /// Derives secp256r1 public key from the provided `privateKey`. + function publicKeyP256(uint256 privateKey) external pure returns (uint256 publicKeyX, uint256 publicKeyY); + + /// Adds a private key to the local forge wallet and returns the address. + function rememberKey(uint256 privateKey) external returns (address keyAddr); + + /// Derive a set number of wallets from a mnemonic at the derivation path `m/44'/60'/0'/0/{0..count}`. + /// The respective private keys are saved to the local forge wallet for later use and their addresses are returned. + function rememberKeys(string calldata mnemonic, string calldata derivationPath, uint32 count) + external + returns (address[] memory keyAddrs); + + /// Derive a set number of wallets from a mnemonic in the specified language at the derivation path `m/44'/60'/0'/0/{0..count}`. + /// The respective private keys are saved to the local forge wallet for later use and their addresses are returned. + function rememberKeys( + string calldata mnemonic, + string calldata derivationPath, + string calldata language, + uint32 count + ) external returns (address[] memory keyAddrs); + + /// Signs data with a `Wallet`. + /// Returns a compact signature (`r`, `vs`) as per EIP-2098, where `vs` encodes both the + /// signature's `s` value, and the recovery id `v` in a single bytes32. + /// This format reduces the signature size from 65 to 64 bytes. + function signCompact(Wallet calldata wallet, bytes32 digest) external returns (bytes32 r, bytes32 vs); + + /// Signs `digest` with `privateKey` using the secp256k1 curve. + /// Returns a compact signature (`r`, `vs`) as per EIP-2098, where `vs` encodes both the + /// signature's `s` value, and the recovery id `v` in a single bytes32. + /// This format reduces the signature size from 65 to 64 bytes. + function signCompact(uint256 privateKey, bytes32 digest) external pure returns (bytes32 r, bytes32 vs); + + /// Signs `digest` with signer provided to script using the secp256k1 curve. + /// Returns a compact signature (`r`, `vs`) as per EIP-2098, where `vs` encodes both the + /// signature's `s` value, and the recovery id `v` in a single bytes32. + /// This format reduces the signature size from 65 to 64 bytes. + /// If `--sender` is provided, the signer with provided address is used, otherwise, + /// if exactly one signer is provided to the script, that signer is used. + /// Raises error if signer passed through `--sender` does not match any unlocked signers or + /// if `--sender` is not provided and not exactly one signer is passed to the script. + function signCompact(bytes32 digest) external pure returns (bytes32 r, bytes32 vs); + + /// Signs `digest` with signer provided to script using the secp256k1 curve. + /// Returns a compact signature (`r`, `vs`) as per EIP-2098, where `vs` encodes both the + /// signature's `s` value, and the recovery id `v` in a single bytes32. + /// This format reduces the signature size from 65 to 64 bytes. + /// Raises error if none of the signers passed into the script have provided address. + function signCompact(address signer, bytes32 digest) external pure returns (bytes32 r, bytes32 vs); + + /// Signs `digest` with `privateKey` using the secp256r1 curve. + function signP256(uint256 privateKey, bytes32 digest) external pure returns (bytes32 r, bytes32 s); + + /// Signs data with a `Wallet`. + function sign(Wallet calldata wallet, bytes32 digest) external returns (uint8 v, bytes32 r, bytes32 s); + + /// Signs `digest` with `privateKey` using the secp256k1 curve. + function sign(uint256 privateKey, bytes32 digest) external pure returns (uint8 v, bytes32 r, bytes32 s); + + /// Signs `digest` with signer provided to script using the secp256k1 curve. + /// If `--sender` is provided, the signer with provided address is used, otherwise, + /// if exactly one signer is provided to the script, that signer is used. + /// Raises error if signer passed through `--sender` does not match any unlocked signers or + /// if `--sender` is not provided and not exactly one signer is passed to the script. + function sign(bytes32 digest) external pure returns (uint8 v, bytes32 r, bytes32 s); + + /// Signs `digest` with signer provided to script using the secp256k1 curve. + /// Raises error if none of the signers passed into the script have provided address. + function sign(address signer, bytes32 digest) external pure returns (uint8 v, bytes32 r, bytes32 s); + + // ======== Environment ======== + + /// Gets the environment variable `name` and parses it as `address`. + /// Reverts if the variable was not found or could not be parsed. + function envAddress(string calldata name) external view returns (address value); + + /// Gets the environment variable `name` and parses it as an array of `address`, delimited by `delim`. + /// Reverts if the variable was not found or could not be parsed. + function envAddress(string calldata name, string calldata delim) external view returns (address[] memory value); + + /// Gets the environment variable `name` and parses it as `bool`. + /// Reverts if the variable was not found or could not be parsed. + function envBool(string calldata name) external view returns (bool value); + + /// Gets the environment variable `name` and parses it as an array of `bool`, delimited by `delim`. + /// Reverts if the variable was not found or could not be parsed. + function envBool(string calldata name, string calldata delim) external view returns (bool[] memory value); + + /// Gets the environment variable `name` and parses it as `bytes32`. + /// Reverts if the variable was not found or could not be parsed. + function envBytes32(string calldata name) external view returns (bytes32 value); + + /// Gets the environment variable `name` and parses it as an array of `bytes32`, delimited by `delim`. + /// Reverts if the variable was not found or could not be parsed. + function envBytes32(string calldata name, string calldata delim) external view returns (bytes32[] memory value); + + /// Gets the environment variable `name` and parses it as `bytes`. + /// Reverts if the variable was not found or could not be parsed. + function envBytes(string calldata name) external view returns (bytes memory value); + + /// Gets the environment variable `name` and parses it as an array of `bytes`, delimited by `delim`. + /// Reverts if the variable was not found or could not be parsed. + function envBytes(string calldata name, string calldata delim) external view returns (bytes[] memory value); + + /// Gets the environment variable `name` and returns true if it exists, else returns false. + function envExists(string calldata name) external view returns (bool result); + + /// Gets the environment variable `name` and parses it as `int256`. + /// Reverts if the variable was not found or could not be parsed. + function envInt(string calldata name) external view returns (int256 value); + + /// Gets the environment variable `name` and parses it as an array of `int256`, delimited by `delim`. + /// Reverts if the variable was not found or could not be parsed. + function envInt(string calldata name, string calldata delim) external view returns (int256[] memory value); + + /// Gets the environment variable `name` and parses it as `bool`. + /// Reverts if the variable could not be parsed. + /// Returns `defaultValue` if the variable was not found. + function envOr(string calldata name, bool defaultValue) external view returns (bool value); + + /// Gets the environment variable `name` and parses it as `uint256`. + /// Reverts if the variable could not be parsed. + /// Returns `defaultValue` if the variable was not found. + function envOr(string calldata name, uint256 defaultValue) external view returns (uint256 value); + + /// Gets the environment variable `name` and parses it as an array of `address`, delimited by `delim`. + /// Reverts if the variable could not be parsed. + /// Returns `defaultValue` if the variable was not found. + function envOr(string calldata name, string calldata delim, address[] calldata defaultValue) + external + view + returns (address[] memory value); + + /// Gets the environment variable `name` and parses it as an array of `bytes32`, delimited by `delim`. + /// Reverts if the variable could not be parsed. + /// Returns `defaultValue` if the variable was not found. + function envOr(string calldata name, string calldata delim, bytes32[] calldata defaultValue) + external + view + returns (bytes32[] memory value); + + /// Gets the environment variable `name` and parses it as an array of `string`, delimited by `delim`. + /// Reverts if the variable could not be parsed. + /// Returns `defaultValue` if the variable was not found. + function envOr(string calldata name, string calldata delim, string[] calldata defaultValue) + external + view + returns (string[] memory value); + + /// Gets the environment variable `name` and parses it as an array of `bytes`, delimited by `delim`. + /// Reverts if the variable could not be parsed. + /// Returns `defaultValue` if the variable was not found. + function envOr(string calldata name, string calldata delim, bytes[] calldata defaultValue) + external + view + returns (bytes[] memory value); + + /// Gets the environment variable `name` and parses it as `int256`. + /// Reverts if the variable could not be parsed. + /// Returns `defaultValue` if the variable was not found. + function envOr(string calldata name, int256 defaultValue) external view returns (int256 value); + + /// Gets the environment variable `name` and parses it as `address`. + /// Reverts if the variable could not be parsed. + /// Returns `defaultValue` if the variable was not found. + function envOr(string calldata name, address defaultValue) external view returns (address value); + + /// Gets the environment variable `name` and parses it as `bytes32`. + /// Reverts if the variable could not be parsed. + /// Returns `defaultValue` if the variable was not found. + function envOr(string calldata name, bytes32 defaultValue) external view returns (bytes32 value); + + /// Gets the environment variable `name` and parses it as `string`. + /// Reverts if the variable could not be parsed. + /// Returns `defaultValue` if the variable was not found. + function envOr(string calldata name, string calldata defaultValue) external view returns (string memory value); + + /// Gets the environment variable `name` and parses it as `bytes`. + /// Reverts if the variable could not be parsed. + /// Returns `defaultValue` if the variable was not found. + function envOr(string calldata name, bytes calldata defaultValue) external view returns (bytes memory value); + + /// Gets the environment variable `name` and parses it as an array of `bool`, delimited by `delim`. + /// Reverts if the variable could not be parsed. + /// Returns `defaultValue` if the variable was not found. + function envOr(string calldata name, string calldata delim, bool[] calldata defaultValue) + external + view + returns (bool[] memory value); + + /// Gets the environment variable `name` and parses it as an array of `uint256`, delimited by `delim`. + /// Reverts if the variable could not be parsed. + /// Returns `defaultValue` if the variable was not found. + function envOr(string calldata name, string calldata delim, uint256[] calldata defaultValue) + external + view + returns (uint256[] memory value); + + /// Gets the environment variable `name` and parses it as an array of `int256`, delimited by `delim`. + /// Reverts if the variable could not be parsed. + /// Returns `defaultValue` if the variable was not found. + function envOr(string calldata name, string calldata delim, int256[] calldata defaultValue) + external + view + returns (int256[] memory value); + + /// Gets the environment variable `name` and parses it as `string`. + /// Reverts if the variable was not found or could not be parsed. + function envString(string calldata name) external view returns (string memory value); + + /// Gets the environment variable `name` and parses it as an array of `string`, delimited by `delim`. + /// Reverts if the variable was not found or could not be parsed. + function envString(string calldata name, string calldata delim) external view returns (string[] memory value); + + /// Gets the environment variable `name` and parses it as `uint256`. + /// Reverts if the variable was not found or could not be parsed. + function envUint(string calldata name) external view returns (uint256 value); + + /// Gets the environment variable `name` and parses it as an array of `uint256`, delimited by `delim`. + /// Reverts if the variable was not found or could not be parsed. + function envUint(string calldata name, string calldata delim) external view returns (uint256[] memory value); + + /// Returns true if `forge` command was executed in given context. + function isContext(ForgeContext context) external view returns (bool result); + + /// Resolves the env variable placeholders of a given input string. + function resolveEnv(string calldata input) external returns (string memory); + + /// Sets environment variables. + function setEnv(string calldata name, string calldata value) external; + + // ======== EVM ======== + + /// Gets all accessed reads and write slot from a `vm.record` session, for a given address. + function accesses(address target) external view returns (bytes32[] memory readSlots, bytes32[] memory writeSlots); + + /// Gets the address for a given private key. + function addr(uint256 privateKey) external pure returns (address keyAddr); + + /// Gets all the logs according to specified filter. + function eth_getLogs(uint256 fromBlock, uint256 toBlock, address target, bytes32[] calldata topics) + external + view + returns (EthGetLogs[] memory logs); + + /// Gets the current `block.blobbasefee`. + /// You should use this instead of `block.blobbasefee` if you use `vm.blobBaseFee`, as `block.blobbasefee` is assumed to be constant across a transaction, + /// and as a result will get optimized out by the compiler. + /// See https://github.com/foundry-rs/foundry/issues/6180 + function getBlobBaseFee() external view returns (uint256 blobBaseFee); + + /// Gets the current `block.number`. + /// You should use this instead of `block.number` if you use `vm.roll`, as `block.number` is assumed to be constant across a transaction, + /// and as a result will get optimized out by the compiler. + /// See https://github.com/foundry-rs/foundry/issues/6180 + function getBlockNumber() external view returns (uint256 height); + + /// Gets the current `block.timestamp`. + /// You should use this instead of `block.timestamp` if you use `vm.warp`, as `block.timestamp` is assumed to be constant across a transaction, + /// and as a result will get optimized out by the compiler. + /// See https://github.com/foundry-rs/foundry/issues/6180 + function getBlockTimestamp() external view returns (uint256 timestamp); + + /// Gets the current `block.chainid` of the currently selected environment. + /// You should use this instead of `block.chainid` if you use `vm.selectFork` or `vm.createSelectFork`, as `block.chainid` could be assumed + /// to be constant across a transaction, and as a result will get optimized out by the compiler. + /// See https://github.com/foundry-rs/foundry/issues/6180 + function getChainId() external view returns (uint256 blockChainId); + + /// Gets the map key and parent of a mapping at a given slot, for a given address. + function getMappingKeyAndParentOf(address target, bytes32 elementSlot) + external + view + returns (bool found, bytes32 key, bytes32 parent); + + /// Gets the number of elements in the mapping at the given slot, for a given address. + function getMappingLength(address target, bytes32 mappingSlot) external view returns (uint256 length); + + /// Gets the elements at index idx of the mapping at the given slot, for a given address. The + /// index must be less than the length of the mapping (i.e. the number of keys in the mapping). + function getMappingSlotAt(address target, bytes32 mappingSlot, uint256 idx) external view returns (bytes32 value); + + /// Gets the nonce of an account. + function getNonce(address account) external view returns (uint64 nonce); + + /// Get the nonce of a `Wallet`. + function getNonce(Wallet calldata wallet) external view returns (uint64 nonce); + + /// Gets the RLP encoded block header for a given block number. + /// Returns the block header in the same format as `cast block --raw`. + function getRawBlockHeader(uint256 blockNumber) external view returns (bytes memory rlpHeader); + + /// Gets all the recorded logs. + function getRecordedLogs() external view returns (Log[] memory logs); + + /// Returns state diffs from current `vm.startStateDiffRecording` session. + function getStateDiff() external view returns (string memory diff); + + /// Returns state diffs from current `vm.startStateDiffRecording` session, in json format. + function getStateDiffJson() external view returns (string memory diff); + + /// Returns an array of `StorageAccess` from current `vm.stateStateDiffRecording` session + function getStorageAccesses() external view returns (StorageAccess[] memory storageAccesses); + + /// Gets the gas used in the last call from the callee perspective. + function lastCallGas() external view returns (Gas memory gas); + + /// Loads a storage slot from an address. + function load(address target, bytes32 slot) external view returns (bytes32 data); + + /// Pauses gas metering (i.e. gas usage is not counted). Noop if already paused. + function pauseGasMetering() external; + + /// Records all storage reads and writes. Use `accesses` to get the recorded data. + /// Subsequent calls to `record` will clear the previous data. + function record() external; + + /// Record all the transaction logs. + function recordLogs() external; + + /// Reset gas metering (i.e. gas usage is set to gas limit). + function resetGasMetering() external; + + /// Resumes gas metering (i.e. gas usage is counted again). Noop if already on. + function resumeGasMetering() external; + + /// Performs an Ethereum JSON-RPC request to the current fork URL. + function rpc(string calldata method, string calldata params) external returns (bytes memory data); + + /// Performs an Ethereum JSON-RPC request to the given endpoint. + function rpc(string calldata urlOrAlias, string calldata method, string calldata params) + external + returns (bytes memory data); + + /// Records the debug trace during the run. + function startDebugTraceRecording() external; + + /// Starts recording all map SSTOREs for later retrieval. + function startMappingRecording() external; + + /// Record all account accesses as part of CREATE, CALL or SELFDESTRUCT opcodes in order, + /// along with the context of the calls + function startStateDiffRecording() external; + + /// Stop debug trace recording and returns the recorded debug trace. + function stopAndReturnDebugTraceRecording() external returns (DebugStep[] memory step); + + /// Returns an ordered array of all account accesses from a `vm.startStateDiffRecording` session. + function stopAndReturnStateDiff() external returns (AccountAccess[] memory accountAccesses); + + /// Stops recording all map SSTOREs for later retrieval and clears the recorded data. + function stopMappingRecording() external; + + /// Stops recording storage reads and writes. + function stopRecord() external; + + // ======== Filesystem ======== + + /// Closes file for reading, resetting the offset and allowing to read it from beginning with readLine. + /// `path` is relative to the project root. + function closeFile(string calldata path) external; + + /// Copies the contents of one file to another. This function will **overwrite** the contents of `to`. + /// On success, the total number of bytes copied is returned and it is equal to the length of the `to` file as reported by `metadata`. + /// Both `from` and `to` are relative to the project root. + function copyFile(string calldata from, string calldata to) external returns (uint64 copied); + + /// Creates a new, empty directory at the provided path. + /// This cheatcode will revert in the following situations, but is not limited to just these cases: + /// - User lacks permissions to modify `path`. + /// - A parent of the given path doesn't exist and `recursive` is false. + /// - `path` already exists and `recursive` is false. + /// `path` is relative to the project root. + function createDir(string calldata path, bool recursive) external; + + /// Deploys a contract from an artifact file. Takes in the relative path to the json file or the path to the + /// artifact in the form of :: where and parts are optional. + function deployCode(string calldata artifactPath) external returns (address deployedAddress); + + /// Deploys a contract from an artifact file. Takes in the relative path to the json file or the path to the + /// artifact in the form of :: where and parts are optional. + /// Additionally accepts abi-encoded constructor arguments. + function deployCode(string calldata artifactPath, bytes calldata constructorArgs) + external + returns (address deployedAddress); + + /// Deploys a contract from an artifact file. Takes in the relative path to the json file or the path to the + /// artifact in the form of :: where and parts are optional. + /// Additionally accepts `msg.value`. + function deployCode(string calldata artifactPath, uint256 value) external returns (address deployedAddress); + + /// Deploys a contract from an artifact file. Takes in the relative path to the json file or the path to the + /// artifact in the form of :: where and parts are optional. + /// Additionally accepts abi-encoded constructor arguments and `msg.value`. + function deployCode(string calldata artifactPath, bytes calldata constructorArgs, uint256 value) + external + returns (address deployedAddress); + + /// Deploys a contract from an artifact file, using the CREATE2 salt. Takes in the relative path to the json file or the path to the + /// artifact in the form of :: where and parts are optional. + function deployCode(string calldata artifactPath, bytes32 salt) external returns (address deployedAddress); + + /// Deploys a contract from an artifact file, using the CREATE2 salt. Takes in the relative path to the json file or the path to the + /// artifact in the form of :: where and parts are optional. + /// Additionally accepts abi-encoded constructor arguments. + function deployCode(string calldata artifactPath, bytes calldata constructorArgs, bytes32 salt) + external + returns (address deployedAddress); + + /// Deploys a contract from an artifact file, using the CREATE2 salt. Takes in the relative path to the json file or the path to the + /// artifact in the form of :: where and parts are optional. + /// Additionally accepts `msg.value`. + function deployCode(string calldata artifactPath, uint256 value, bytes32 salt) + external + returns (address deployedAddress); + + /// Deploys a contract from an artifact file, using the CREATE2 salt. Takes in the relative path to the json file or the path to the + /// artifact in the form of :: where and parts are optional. + /// Additionally accepts abi-encoded constructor arguments and `msg.value`. + function deployCode(string calldata artifactPath, bytes calldata constructorArgs, uint256 value, bytes32 salt) + external + returns (address deployedAddress); + + /// Returns true if the given path points to an existing entity, else returns false. + function exists(string calldata path) external view returns (bool result); + + /// Performs a foreign function call via the terminal. + function ffi(string[] calldata commandInput) external returns (bytes memory result); + + /// Given a path, query the file system to get information about a file, directory, etc. + function fsMetadata(string calldata path) external view returns (FsMetadata memory metadata); + + /// Gets the artifact path from code (aka. creation code). + function getArtifactPathByCode(bytes calldata code) external view returns (string memory path); + + /// Gets the artifact path from deployed code (aka. runtime code). + function getArtifactPathByDeployedCode(bytes calldata deployedCode) external view returns (string memory path); + + /// Returns the most recent broadcast for the given contract on `chainId` matching `txType`. + /// For example: + /// The most recent deployment can be fetched by passing `txType` as `CREATE` or `CREATE2`. + /// The most recent call can be fetched by passing `txType` as `CALL`. + function getBroadcast(string calldata contractName, uint64 chainId, BroadcastTxType txType) + external + view + returns (BroadcastTxSummary memory); + + /// Returns all broadcasts for the given contract on `chainId` with the specified `txType`. + /// Sorted such that the most recent broadcast is the first element, and the oldest is the last. i.e descending order of BroadcastTxSummary.blockNumber. + function getBroadcasts(string calldata contractName, uint64 chainId, BroadcastTxType txType) + external + view + returns (BroadcastTxSummary[] memory); + + /// Returns all broadcasts for the given contract on `chainId`. + /// Sorted such that the most recent broadcast is the first element, and the oldest is the last. i.e descending order of BroadcastTxSummary.blockNumber. + function getBroadcasts(string calldata contractName, uint64 chainId) + external + view + returns (BroadcastTxSummary[] memory); + + /// Gets the creation bytecode from an artifact file. Takes in the relative path to the json file or the path to the + /// artifact in the form of :: where and parts are optional. + function getCode(string calldata artifactPath) external view returns (bytes memory creationBytecode); + + /// Gets the deployed bytecode from an artifact file. Takes in the relative path to the json file or the path to the + /// artifact in the form of :: where and parts are optional. + function getDeployedCode(string calldata artifactPath) external view returns (bytes memory runtimeBytecode); + + /// Returns the most recent deployment for the current `chainId`. + function getDeployment(string calldata contractName) external view returns (address deployedAddress); + + /// Returns the most recent deployment for the given contract on `chainId` + function getDeployment(string calldata contractName, uint64 chainId) + external + view + returns (address deployedAddress); + + /// Returns all deployments for the given contract on `chainId` + /// Sorted in descending order of deployment time i.e descending order of BroadcastTxSummary.blockNumber. + /// The most recent deployment is the first element, and the oldest is the last. + function getDeployments(string calldata contractName, uint64 chainId) + external + view + returns (address[] memory deployedAddresses); + + /// Returns true if the path exists on disk and is pointing at a directory, else returns false. + function isDir(string calldata path) external view returns (bool result); + + /// Returns true if the path exists on disk and is pointing at a regular file, else returns false. + function isFile(string calldata path) external view returns (bool result); + + /// Get the path of the current project root. + function projectRoot() external view returns (string memory path); + + /// Prompts the user for a string value in the terminal. + function prompt(string calldata promptText) external returns (string memory input); + + /// Prompts the user for an address in the terminal. + function promptAddress(string calldata promptText) external returns (address); + + /// Prompts the user for a hidden string value in the terminal. + function promptSecret(string calldata promptText) external returns (string memory input); + + /// Prompts the user for hidden uint256 in the terminal (usually pk). + function promptSecretUint(string calldata promptText) external returns (uint256); + + /// Prompts the user for uint256 in the terminal. + function promptUint(string calldata promptText) external returns (uint256); + + /// Reads the directory at the given path recursively, up to `maxDepth`. + /// `maxDepth` defaults to 1, meaning only the direct children of the given directory will be returned. + /// Follows symbolic links if `followLinks` is true. + function readDir(string calldata path) external view returns (DirEntry[] memory entries); + + /// See `readDir(string)`. + function readDir(string calldata path, uint64 maxDepth) external view returns (DirEntry[] memory entries); + + /// See `readDir(string)`. + function readDir(string calldata path, uint64 maxDepth, bool followLinks) + external + view + returns (DirEntry[] memory entries); + + /// Reads the entire content of file to string. `path` is relative to the project root. + function readFile(string calldata path) external view returns (string memory data); + + /// Reads the entire content of file as binary. `path` is relative to the project root. + function readFileBinary(string calldata path) external view returns (bytes memory data); + + /// Reads next line of file to string. + function readLine(string calldata path) external view returns (string memory line); + + /// Reads a symbolic link, returning the path that the link points to. + /// This cheatcode will revert in the following situations, but is not limited to just these cases: + /// - `path` is not a symbolic link. + /// - `path` does not exist. + function readLink(string calldata linkPath) external view returns (string memory targetPath); + + /// Removes a directory at the provided path. + /// This cheatcode will revert in the following situations, but is not limited to just these cases: + /// - `path` doesn't exist. + /// - `path` isn't a directory. + /// - User lacks permissions to modify `path`. + /// - The directory is not empty and `recursive` is false. + /// `path` is relative to the project root. + function removeDir(string calldata path, bool recursive) external; + + /// Removes a file from the filesystem. + /// This cheatcode will revert in the following situations, but is not limited to just these cases: + /// - `path` points to a directory. + /// - The file doesn't exist. + /// - The user lacks permissions to remove the file. + /// `path` is relative to the project root. + function removeFile(string calldata path) external; + + /// Performs a foreign function call via terminal and returns the exit code, stdout, and stderr. + function tryFfi(string[] calldata commandInput) external returns (FfiResult memory result); + + /// Returns the time since unix epoch in milliseconds. + function unixTime() external view returns (uint256 milliseconds); + + /// Writes data to file, creating a file if it does not exist, and entirely replacing its contents if it does. + /// `path` is relative to the project root. + function writeFile(string calldata path, string calldata data) external; + + /// Writes binary data to a file, creating a file if it does not exist, and entirely replacing its contents if it does. + /// `path` is relative to the project root. + function writeFileBinary(string calldata path, bytes calldata data) external; + + /// Writes line to file, creating a file if it does not exist. + /// `path` is relative to the project root. + function writeLine(string calldata path, string calldata data) external; + + // ======== JSON ======== + + /// Checks if `key` exists in a JSON object. + function keyExistsJson(string calldata json, string calldata key) external view returns (bool); + + /// Parses a string of JSON data at `key` and coerces it to `address`. + function parseJsonAddress(string calldata json, string calldata key) external pure returns (address); + + /// Parses a string of JSON data at `key` and coerces it to `address[]`. + function parseJsonAddressArray(string calldata json, string calldata key) + external + pure + returns (address[] memory); + + /// Parses a string of JSON data at `key` and coerces it to `bool`. + function parseJsonBool(string calldata json, string calldata key) external pure returns (bool); + + /// Parses a string of JSON data at `key` and coerces it to `bool[]`. + function parseJsonBoolArray(string calldata json, string calldata key) external pure returns (bool[] memory); + + /// Parses a string of JSON data at `key` and coerces it to `bytes`. + function parseJsonBytes(string calldata json, string calldata key) external pure returns (bytes memory); + + /// Parses a string of JSON data at `key` and coerces it to `bytes32`. + function parseJsonBytes32(string calldata json, string calldata key) external pure returns (bytes32); + + /// Parses a string of JSON data at `key` and coerces it to `bytes32[]`. + function parseJsonBytes32Array(string calldata json, string calldata key) + external + pure + returns (bytes32[] memory); + + /// Parses a string of JSON data at `key` and coerces it to `bytes[]`. + function parseJsonBytesArray(string calldata json, string calldata key) external pure returns (bytes[] memory); + + /// Parses a string of JSON data at `key` and coerces it to `int256`. + function parseJsonInt(string calldata json, string calldata key) external pure returns (int256); + + /// Parses a string of JSON data at `key` and coerces it to `int256[]`. + function parseJsonIntArray(string calldata json, string calldata key) external pure returns (int256[] memory); + + /// Returns an array of all the keys in a JSON object. + function parseJsonKeys(string calldata json, string calldata key) external pure returns (string[] memory keys); + + /// Parses a string of JSON data at `key` and coerces it to `string`. + function parseJsonString(string calldata json, string calldata key) external pure returns (string memory); + + /// Parses a string of JSON data at `key` and coerces it to `string[]`. + function parseJsonStringArray(string calldata json, string calldata key) external pure returns (string[] memory); + + /// Parses a string of JSON data at `key` and coerces it to type array corresponding to `typeDescription`. + function parseJsonTypeArray(string calldata json, string calldata key, string calldata typeDescription) + external + pure + returns (bytes memory); + + /// Parses a string of JSON data and coerces it to type corresponding to `typeDescription`. + function parseJsonType(string calldata json, string calldata typeDescription) + external + pure + returns (bytes memory); + + /// Parses a string of JSON data at `key` and coerces it to type corresponding to `typeDescription`. + function parseJsonType(string calldata json, string calldata key, string calldata typeDescription) + external + pure + returns (bytes memory); + + /// Parses a string of JSON data at `key` and coerces it to `uint256`. + function parseJsonUint(string calldata json, string calldata key) external pure returns (uint256); + + /// Parses a string of JSON data at `key` and coerces it to `uint256[]`. + function parseJsonUintArray(string calldata json, string calldata key) external pure returns (uint256[] memory); + + /// ABI-encodes a JSON object. + function parseJson(string calldata json) external pure returns (bytes memory abiEncodedData); + + /// ABI-encodes a JSON object at `key`. + function parseJson(string calldata json, string calldata key) external pure returns (bytes memory abiEncodedData); + + /// See `serializeJson`. + function serializeAddress(string calldata objectKey, string calldata valueKey, address value) + external + returns (string memory json); + + /// See `serializeJson`. + function serializeAddress(string calldata objectKey, string calldata valueKey, address[] calldata values) + external + returns (string memory json); + + /// See `serializeJson`. + function serializeBool(string calldata objectKey, string calldata valueKey, bool value) + external + returns (string memory json); + + /// See `serializeJson`. + function serializeBool(string calldata objectKey, string calldata valueKey, bool[] calldata values) + external + returns (string memory json); + + /// See `serializeJson`. + function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32 value) + external + returns (string memory json); + + /// See `serializeJson`. + function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32[] calldata values) + external + returns (string memory json); + + /// See `serializeJson`. + function serializeBytes(string calldata objectKey, string calldata valueKey, bytes calldata value) + external + returns (string memory json); + + /// See `serializeJson`. + function serializeBytes(string calldata objectKey, string calldata valueKey, bytes[] calldata values) + external + returns (string memory json); + + /// See `serializeJson`. + function serializeInt(string calldata objectKey, string calldata valueKey, int256 value) + external + returns (string memory json); + + /// See `serializeJson`. + function serializeInt(string calldata objectKey, string calldata valueKey, int256[] calldata values) + external + returns (string memory json); + + /// Serializes a key and value to a JSON object stored in-memory that can be later written to a file. + /// Returns the stringified version of the specific JSON file up to that moment. + function serializeJson(string calldata objectKey, string calldata value) external returns (string memory json); + + /// See `serializeJson`. + function serializeJsonType(string calldata typeDescription, bytes calldata value) + external + pure + returns (string memory json); + + /// See `serializeJson`. + function serializeJsonType( + string calldata objectKey, + string calldata valueKey, + string calldata typeDescription, + bytes calldata value + ) external returns (string memory json); + + /// See `serializeJson`. + function serializeString(string calldata objectKey, string calldata valueKey, string calldata value) + external + returns (string memory json); + + /// See `serializeJson`. + function serializeString(string calldata objectKey, string calldata valueKey, string[] calldata values) + external + returns (string memory json); + + /// See `serializeJson`. + function serializeUintToHex(string calldata objectKey, string calldata valueKey, uint256 value) + external + returns (string memory json); + + /// See `serializeJson`. + function serializeUint(string calldata objectKey, string calldata valueKey, uint256 value) + external + returns (string memory json); + + /// See `serializeJson`. + function serializeUint(string calldata objectKey, string calldata valueKey, uint256[] calldata values) + external + returns (string memory json); + + /// Write a serialized JSON object to a file. If the file exists, it will be overwritten. + function writeJson(string calldata json, string calldata path) external; + + /// Write a serialized JSON object to an **existing** JSON file, replacing a value with key = + /// This is useful to replace a specific value of a JSON file, without having to parse the entire thing. + /// This cheatcode will create new keys if they didn't previously exist. + function writeJson(string calldata json, string calldata path, string calldata valueKey) external; + + /// Checks if `key` exists in a JSON object + /// `keyExists` is being deprecated in favor of `keyExistsJson`. It will be removed in future versions. + function keyExists(string calldata json, string calldata key) external view returns (bool); + + // ======== Scripting ======== + + /// Attach an EIP-4844 blob to the next call + function attachBlob(bytes calldata blob) external; + + /// Designate the next call as an EIP-7702 transaction + function attachDelegation(SignedDelegation calldata signedDelegation) external; + + /// Designate the next call as an EIP-7702 transaction, with optional cross-chain validity. + function attachDelegation(SignedDelegation calldata signedDelegation, bool crossChain) external; + + /// Takes a signed transaction and broadcasts it to the network. + function broadcastRawTransaction(bytes calldata data) external; + + /// Has the next call (at this call depth only) create transactions that can later be signed and sent onchain. + /// Broadcasting address is determined by checking the following in order: + /// 1. If `--sender` argument was provided, that address is used. + /// 2. If exactly one signer (e.g. private key, hw wallet, keystore) is set when `forge broadcast` is invoked, that signer is used. + /// 3. Otherwise, default foundry sender (1804c8AB1F12E6bbf3894d4083f33e07309d1f38) is used. + function broadcast() external; + + /// Has the next call (at this call depth only) create a transaction with the address provided + /// as the sender that can later be signed and sent onchain. + function broadcast(address signer) external; + + /// Has the next call (at this call depth only) create a transaction with the private key + /// provided as the sender that can later be signed and sent onchain. + function broadcast(uint256 privateKey) external; + + /// Returns addresses of available unlocked wallets in the script environment. + function getWallets() external view returns (address[] memory wallets); + + /// Sign an EIP-7702 authorization and designate the next call as an EIP-7702 transaction + function signAndAttachDelegation(address implementation, uint256 privateKey) + external + returns (SignedDelegation memory signedDelegation); + + /// Sign an EIP-7702 authorization and designate the next call as an EIP-7702 transaction for specific nonce + function signAndAttachDelegation(address implementation, uint256 privateKey, uint64 nonce) + external + returns (SignedDelegation memory signedDelegation); + + /// Sign an EIP-7702 authorization and designate the next call as an EIP-7702 transaction, with optional cross-chain validity. + function signAndAttachDelegation(address implementation, uint256 privateKey, bool crossChain) + external + returns (SignedDelegation memory signedDelegation); + + /// Sign an EIP-7702 authorization for delegation + function signDelegation(address implementation, uint256 privateKey) + external + returns (SignedDelegation memory signedDelegation); + + /// Sign an EIP-7702 authorization for delegation for specific nonce + function signDelegation(address implementation, uint256 privateKey, uint64 nonce) + external + returns (SignedDelegation memory signedDelegation); + + /// Sign an EIP-7702 authorization for delegation, with optional cross-chain validity. + function signDelegation(address implementation, uint256 privateKey, bool crossChain) + external + returns (SignedDelegation memory signedDelegation); + + /// Has all subsequent calls (at this call depth only) create transactions that can later be signed and sent onchain. + /// Broadcasting address is determined by checking the following in order: + /// 1. If `--sender` argument was provided, that address is used. + /// 2. If exactly one signer (e.g. private key, hw wallet, keystore) is set when `forge broadcast` is invoked, that signer is used. + /// 3. Otherwise, default foundry sender (1804c8AB1F12E6bbf3894d4083f33e07309d1f38) is used. + function startBroadcast() external; + + /// Has all subsequent calls (at this call depth only) create transactions with the address + /// provided that can later be signed and sent onchain. + function startBroadcast(address signer) external; + + /// Has all subsequent calls (at this call depth only) create transactions with the private key + /// provided that can later be signed and sent onchain. + function startBroadcast(uint256 privateKey) external; + + /// Stops collecting onchain transactions. + function stopBroadcast() external; + + // ======== String ======== + + /// Returns true if `search` is found in `subject`, false otherwise. + function contains(string calldata subject, string calldata search) external pure returns (bool result); + + /// Returns the index of the first occurrence of a `key` in an `input` string. + /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `key` is not found. + /// Returns 0 in case of an empty `key`. + function indexOf(string calldata input, string calldata key) external pure returns (uint256); + + /// Parses the given `string` into an `address`. + function parseAddress(string calldata stringifiedValue) external pure returns (address parsedValue); + + /// Parses the given `string` into a `bool`. + function parseBool(string calldata stringifiedValue) external pure returns (bool parsedValue); + + /// Parses the given `string` into `bytes`. + function parseBytes(string calldata stringifiedValue) external pure returns (bytes memory parsedValue); + + /// Parses the given `string` into a `bytes32`. + function parseBytes32(string calldata stringifiedValue) external pure returns (bytes32 parsedValue); + + /// Parses the given `string` into a `int256`. + function parseInt(string calldata stringifiedValue) external pure returns (int256 parsedValue); + + /// Parses the given `string` into a `uint256`. + function parseUint(string calldata stringifiedValue) external pure returns (uint256 parsedValue); + + /// Replaces occurrences of `from` in the given `string` with `to`. + function replace(string calldata input, string calldata from, string calldata to) + external + pure + returns (string memory output); + + /// Splits the given `string` into an array of strings divided by the `delimiter`. + function split(string calldata input, string calldata delimiter) external pure returns (string[] memory outputs); + + /// Converts the given `string` value to Lowercase. + function toLowercase(string calldata input) external pure returns (string memory output); + + /// Converts the given value to a `string`. + function toString(address value) external pure returns (string memory stringifiedValue); + + /// Converts the given value to a `string`. + function toString(bytes calldata value) external pure returns (string memory stringifiedValue); + + /// Converts the given value to a `string`. + function toString(bytes32 value) external pure returns (string memory stringifiedValue); + + /// Converts the given value to a `string`. + function toString(bool value) external pure returns (string memory stringifiedValue); + + /// Converts the given value to a `string`. + function toString(uint256 value) external pure returns (string memory stringifiedValue); + + /// Converts the given value to a `string`. + function toString(int256 value) external pure returns (string memory stringifiedValue); + + /// Converts the given `string` value to Uppercase. + function toUppercase(string calldata input) external pure returns (string memory output); + + /// Trims leading and trailing whitespace from the given `string` value. + function trim(string calldata input) external pure returns (string memory output); + + // ======== Testing ======== + + /// Compares two `uint256` values. Expects difference to be less than or equal to `maxDelta`. + /// Formats values with decimals in failure message. + function assertApproxEqAbsDecimal(uint256 left, uint256 right, uint256 maxDelta, uint256 decimals) external pure; + + /// Compares two `uint256` values. Expects difference to be less than or equal to `maxDelta`. + /// Formats values with decimals in failure message. Includes error message into revert string on failure. + function assertApproxEqAbsDecimal( + uint256 left, + uint256 right, + uint256 maxDelta, + uint256 decimals, + string calldata error + ) external pure; + + /// Compares two `int256` values. Expects difference to be less than or equal to `maxDelta`. + /// Formats values with decimals in failure message. + function assertApproxEqAbsDecimal(int256 left, int256 right, uint256 maxDelta, uint256 decimals) external pure; + + /// Compares two `int256` values. Expects difference to be less than or equal to `maxDelta`. + /// Formats values with decimals in failure message. Includes error message into revert string on failure. + function assertApproxEqAbsDecimal( + int256 left, + int256 right, + uint256 maxDelta, + uint256 decimals, + string calldata error + ) external pure; + + /// Compares two `uint256` values. Expects difference to be less than or equal to `maxDelta`. + function assertApproxEqAbs(uint256 left, uint256 right, uint256 maxDelta) external pure; + + /// Compares two `uint256` values. Expects difference to be less than or equal to `maxDelta`. + /// Includes error message into revert string on failure. + function assertApproxEqAbs(uint256 left, uint256 right, uint256 maxDelta, string calldata error) external pure; + + /// Compares two `int256` values. Expects difference to be less than or equal to `maxDelta`. + function assertApproxEqAbs(int256 left, int256 right, uint256 maxDelta) external pure; + + /// Compares two `int256` values. Expects difference to be less than or equal to `maxDelta`. + /// Includes error message into revert string on failure. + function assertApproxEqAbs(int256 left, int256 right, uint256 maxDelta, string calldata error) external pure; + + /// Compares two `uint256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. + /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% + /// Formats values with decimals in failure message. + function assertApproxEqRelDecimal(uint256 left, uint256 right, uint256 maxPercentDelta, uint256 decimals) + external + pure; + + /// Compares two `uint256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. + /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% + /// Formats values with decimals in failure message. Includes error message into revert string on failure. + function assertApproxEqRelDecimal( + uint256 left, + uint256 right, + uint256 maxPercentDelta, + uint256 decimals, + string calldata error + ) external pure; + + /// Compares two `int256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. + /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% + /// Formats values with decimals in failure message. + function assertApproxEqRelDecimal(int256 left, int256 right, uint256 maxPercentDelta, uint256 decimals) + external + pure; + + /// Compares two `int256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. + /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% + /// Formats values with decimals in failure message. Includes error message into revert string on failure. + function assertApproxEqRelDecimal( + int256 left, + int256 right, + uint256 maxPercentDelta, + uint256 decimals, + string calldata error + ) external pure; + + /// Compares two `uint256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. + /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% + function assertApproxEqRel(uint256 left, uint256 right, uint256 maxPercentDelta) external pure; + + /// Compares two `uint256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. + /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% + /// Includes error message into revert string on failure. + function assertApproxEqRel(uint256 left, uint256 right, uint256 maxPercentDelta, string calldata error) + external + pure; + + /// Compares two `int256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. + /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% + function assertApproxEqRel(int256 left, int256 right, uint256 maxPercentDelta) external pure; + + /// Compares two `int256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. + /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% + /// Includes error message into revert string on failure. + function assertApproxEqRel(int256 left, int256 right, uint256 maxPercentDelta, string calldata error) + external + pure; + + /// Asserts that two `uint256` values are equal, formatting them with decimals in failure message. + function assertEqDecimal(uint256 left, uint256 right, uint256 decimals) external pure; + + /// Asserts that two `uint256` values are equal, formatting them with decimals in failure message. + /// Includes error message into revert string on failure. + function assertEqDecimal(uint256 left, uint256 right, uint256 decimals, string calldata error) external pure; + + /// Asserts that two `int256` values are equal, formatting them with decimals in failure message. + function assertEqDecimal(int256 left, int256 right, uint256 decimals) external pure; + + /// Asserts that two `int256` values are equal, formatting them with decimals in failure message. + /// Includes error message into revert string on failure. + function assertEqDecimal(int256 left, int256 right, uint256 decimals, string calldata error) external pure; + + /// Asserts that two `bool` values are equal. + function assertEq(bool left, bool right) external pure; + + /// Asserts that two `bool` values are equal and includes error message into revert string on failure. + function assertEq(bool left, bool right, string calldata error) external pure; + + /// Asserts that two `string` values are equal. + function assertEq(string calldata left, string calldata right) external pure; + + /// Asserts that two `string` values are equal and includes error message into revert string on failure. + function assertEq(string calldata left, string calldata right, string calldata error) external pure; + + /// Asserts that two `bytes` values are equal. + function assertEq(bytes calldata left, bytes calldata right) external pure; + + /// Asserts that two `bytes` values are equal and includes error message into revert string on failure. + function assertEq(bytes calldata left, bytes calldata right, string calldata error) external pure; + + /// Asserts that two arrays of `bool` values are equal. + function assertEq(bool[] calldata left, bool[] calldata right) external pure; + + /// Asserts that two arrays of `bool` values are equal and includes error message into revert string on failure. + function assertEq(bool[] calldata left, bool[] calldata right, string calldata error) external pure; + + /// Asserts that two arrays of `uint256 values are equal. + function assertEq(uint256[] calldata left, uint256[] calldata right) external pure; + + /// Asserts that two arrays of `uint256` values are equal and includes error message into revert string on failure. + function assertEq(uint256[] calldata left, uint256[] calldata right, string calldata error) external pure; + + /// Asserts that two arrays of `int256` values are equal. + function assertEq(int256[] calldata left, int256[] calldata right) external pure; + + /// Asserts that two arrays of `int256` values are equal and includes error message into revert string on failure. + function assertEq(int256[] calldata left, int256[] calldata right, string calldata error) external pure; + + /// Asserts that two `uint256` values are equal. + function assertEq(uint256 left, uint256 right) external pure; + + /// Asserts that two arrays of `address` values are equal. + function assertEq(address[] calldata left, address[] calldata right) external pure; + + /// Asserts that two arrays of `address` values are equal and includes error message into revert string on failure. + function assertEq(address[] calldata left, address[] calldata right, string calldata error) external pure; + + /// Asserts that two arrays of `bytes32` values are equal. + function assertEq(bytes32[] calldata left, bytes32[] calldata right) external pure; + + /// Asserts that two arrays of `bytes32` values are equal and includes error message into revert string on failure. + function assertEq(bytes32[] calldata left, bytes32[] calldata right, string calldata error) external pure; + + /// Asserts that two arrays of `string` values are equal. + function assertEq(string[] calldata left, string[] calldata right) external pure; + + /// Asserts that two arrays of `string` values are equal and includes error message into revert string on failure. + function assertEq(string[] calldata left, string[] calldata right, string calldata error) external pure; + + /// Asserts that two arrays of `bytes` values are equal. + function assertEq(bytes[] calldata left, bytes[] calldata right) external pure; + + /// Asserts that two arrays of `bytes` values are equal and includes error message into revert string on failure. + function assertEq(bytes[] calldata left, bytes[] calldata right, string calldata error) external pure; + + /// Asserts that two `uint256` values are equal and includes error message into revert string on failure. + function assertEq(uint256 left, uint256 right, string calldata error) external pure; + + /// Asserts that two `int256` values are equal. + function assertEq(int256 left, int256 right) external pure; + + /// Asserts that two `int256` values are equal and includes error message into revert string on failure. + function assertEq(int256 left, int256 right, string calldata error) external pure; + + /// Asserts that two `address` values are equal. + function assertEq(address left, address right) external pure; + + /// Asserts that two `address` values are equal and includes error message into revert string on failure. + function assertEq(address left, address right, string calldata error) external pure; + + /// Asserts that two `bytes32` values are equal. + function assertEq(bytes32 left, bytes32 right) external pure; + + /// Asserts that two `bytes32` values are equal and includes error message into revert string on failure. + function assertEq(bytes32 left, bytes32 right, string calldata error) external pure; + + /// Asserts that the given condition is false. + function assertFalse(bool condition) external pure; + + /// Asserts that the given condition is false and includes error message into revert string on failure. + function assertFalse(bool condition, string calldata error) external pure; + + /// Compares two `uint256` values. Expects first value to be greater than or equal to second. + /// Formats values with decimals in failure message. + function assertGeDecimal(uint256 left, uint256 right, uint256 decimals) external pure; + + /// Compares two `uint256` values. Expects first value to be greater than or equal to second. + /// Formats values with decimals in failure message. Includes error message into revert string on failure. + function assertGeDecimal(uint256 left, uint256 right, uint256 decimals, string calldata error) external pure; + + /// Compares two `int256` values. Expects first value to be greater than or equal to second. + /// Formats values with decimals in failure message. + function assertGeDecimal(int256 left, int256 right, uint256 decimals) external pure; + + /// Compares two `int256` values. Expects first value to be greater than or equal to second. + /// Formats values with decimals in failure message. Includes error message into revert string on failure. + function assertGeDecimal(int256 left, int256 right, uint256 decimals, string calldata error) external pure; + + /// Compares two `uint256` values. Expects first value to be greater than or equal to second. + function assertGe(uint256 left, uint256 right) external pure; + + /// Compares two `uint256` values. Expects first value to be greater than or equal to second. + /// Includes error message into revert string on failure. + function assertGe(uint256 left, uint256 right, string calldata error) external pure; + + /// Compares two `int256` values. Expects first value to be greater than or equal to second. + function assertGe(int256 left, int256 right) external pure; + + /// Compares two `int256` values. Expects first value to be greater than or equal to second. + /// Includes error message into revert string on failure. + function assertGe(int256 left, int256 right, string calldata error) external pure; + + /// Compares two `uint256` values. Expects first value to be greater than second. + /// Formats values with decimals in failure message. + function assertGtDecimal(uint256 left, uint256 right, uint256 decimals) external pure; + + /// Compares two `uint256` values. Expects first value to be greater than second. + /// Formats values with decimals in failure message. Includes error message into revert string on failure. + function assertGtDecimal(uint256 left, uint256 right, uint256 decimals, string calldata error) external pure; + + /// Compares two `int256` values. Expects first value to be greater than second. + /// Formats values with decimals in failure message. + function assertGtDecimal(int256 left, int256 right, uint256 decimals) external pure; + + /// Compares two `int256` values. Expects first value to be greater than second. + /// Formats values with decimals in failure message. Includes error message into revert string on failure. + function assertGtDecimal(int256 left, int256 right, uint256 decimals, string calldata error) external pure; + + /// Compares two `uint256` values. Expects first value to be greater than second. + function assertGt(uint256 left, uint256 right) external pure; + + /// Compares two `uint256` values. Expects first value to be greater than second. + /// Includes error message into revert string on failure. + function assertGt(uint256 left, uint256 right, string calldata error) external pure; + + /// Compares two `int256` values. Expects first value to be greater than second. + function assertGt(int256 left, int256 right) external pure; + + /// Compares two `int256` values. Expects first value to be greater than second. + /// Includes error message into revert string on failure. + function assertGt(int256 left, int256 right, string calldata error) external pure; + + /// Compares two `uint256` values. Expects first value to be less than or equal to second. + /// Formats values with decimals in failure message. + function assertLeDecimal(uint256 left, uint256 right, uint256 decimals) external pure; + + /// Compares two `uint256` values. Expects first value to be less than or equal to second. + /// Formats values with decimals in failure message. Includes error message into revert string on failure. + function assertLeDecimal(uint256 left, uint256 right, uint256 decimals, string calldata error) external pure; + + /// Compares two `int256` values. Expects first value to be less than or equal to second. + /// Formats values with decimals in failure message. + function assertLeDecimal(int256 left, int256 right, uint256 decimals) external pure; + + /// Compares two `int256` values. Expects first value to be less than or equal to second. + /// Formats values with decimals in failure message. Includes error message into revert string on failure. + function assertLeDecimal(int256 left, int256 right, uint256 decimals, string calldata error) external pure; + + /// Compares two `uint256` values. Expects first value to be less than or equal to second. + function assertLe(uint256 left, uint256 right) external pure; + + /// Compares two `uint256` values. Expects first value to be less than or equal to second. + /// Includes error message into revert string on failure. + function assertLe(uint256 left, uint256 right, string calldata error) external pure; + + /// Compares two `int256` values. Expects first value to be less than or equal to second. + function assertLe(int256 left, int256 right) external pure; + + /// Compares two `int256` values. Expects first value to be less than or equal to second. + /// Includes error message into revert string on failure. + function assertLe(int256 left, int256 right, string calldata error) external pure; + + /// Compares two `uint256` values. Expects first value to be less than second. + /// Formats values with decimals in failure message. + function assertLtDecimal(uint256 left, uint256 right, uint256 decimals) external pure; + + /// Compares two `uint256` values. Expects first value to be less than second. + /// Formats values with decimals in failure message. Includes error message into revert string on failure. + function assertLtDecimal(uint256 left, uint256 right, uint256 decimals, string calldata error) external pure; + + /// Compares two `int256` values. Expects first value to be less than second. + /// Formats values with decimals in failure message. + function assertLtDecimal(int256 left, int256 right, uint256 decimals) external pure; + + /// Compares two `int256` values. Expects first value to be less than second. + /// Formats values with decimals in failure message. Includes error message into revert string on failure. + function assertLtDecimal(int256 left, int256 right, uint256 decimals, string calldata error) external pure; + + /// Compares two `uint256` values. Expects first value to be less than second. + function assertLt(uint256 left, uint256 right) external pure; + + /// Compares two `uint256` values. Expects first value to be less than second. + /// Includes error message into revert string on failure. + function assertLt(uint256 left, uint256 right, string calldata error) external pure; + + /// Compares two `int256` values. Expects first value to be less than second. + function assertLt(int256 left, int256 right) external pure; + + /// Compares two `int256` values. Expects first value to be less than second. + /// Includes error message into revert string on failure. + function assertLt(int256 left, int256 right, string calldata error) external pure; + + /// Asserts that two `uint256` values are not equal, formatting them with decimals in failure message. + function assertNotEqDecimal(uint256 left, uint256 right, uint256 decimals) external pure; + + /// Asserts that two `uint256` values are not equal, formatting them with decimals in failure message. + /// Includes error message into revert string on failure. + function assertNotEqDecimal(uint256 left, uint256 right, uint256 decimals, string calldata error) external pure; + + /// Asserts that two `int256` values are not equal, formatting them with decimals in failure message. + function assertNotEqDecimal(int256 left, int256 right, uint256 decimals) external pure; + + /// Asserts that two `int256` values are not equal, formatting them with decimals in failure message. + /// Includes error message into revert string on failure. + function assertNotEqDecimal(int256 left, int256 right, uint256 decimals, string calldata error) external pure; + + /// Asserts that two `bool` values are not equal. + function assertNotEq(bool left, bool right) external pure; + + /// Asserts that two `bool` values are not equal and includes error message into revert string on failure. + function assertNotEq(bool left, bool right, string calldata error) external pure; + + /// Asserts that two `string` values are not equal. + function assertNotEq(string calldata left, string calldata right) external pure; + + /// Asserts that two `string` values are not equal and includes error message into revert string on failure. + function assertNotEq(string calldata left, string calldata right, string calldata error) external pure; + + /// Asserts that two `bytes` values are not equal. + function assertNotEq(bytes calldata left, bytes calldata right) external pure; + + /// Asserts that two `bytes` values are not equal and includes error message into revert string on failure. + function assertNotEq(bytes calldata left, bytes calldata right, string calldata error) external pure; + + /// Asserts that two arrays of `bool` values are not equal. + function assertNotEq(bool[] calldata left, bool[] calldata right) external pure; + + /// Asserts that two arrays of `bool` values are not equal and includes error message into revert string on failure. + function assertNotEq(bool[] calldata left, bool[] calldata right, string calldata error) external pure; + + /// Asserts that two arrays of `uint256` values are not equal. + function assertNotEq(uint256[] calldata left, uint256[] calldata right) external pure; + + /// Asserts that two arrays of `uint256` values are not equal and includes error message into revert string on failure. + function assertNotEq(uint256[] calldata left, uint256[] calldata right, string calldata error) external pure; + + /// Asserts that two arrays of `int256` values are not equal. + function assertNotEq(int256[] calldata left, int256[] calldata right) external pure; + + /// Asserts that two arrays of `int256` values are not equal and includes error message into revert string on failure. + function assertNotEq(int256[] calldata left, int256[] calldata right, string calldata error) external pure; + + /// Asserts that two `uint256` values are not equal. + function assertNotEq(uint256 left, uint256 right) external pure; + + /// Asserts that two arrays of `address` values are not equal. + function assertNotEq(address[] calldata left, address[] calldata right) external pure; + + /// Asserts that two arrays of `address` values are not equal and includes error message into revert string on failure. + function assertNotEq(address[] calldata left, address[] calldata right, string calldata error) external pure; + + /// Asserts that two arrays of `bytes32` values are not equal. + function assertNotEq(bytes32[] calldata left, bytes32[] calldata right) external pure; + + /// Asserts that two arrays of `bytes32` values are not equal and includes error message into revert string on failure. + function assertNotEq(bytes32[] calldata left, bytes32[] calldata right, string calldata error) external pure; + + /// Asserts that two arrays of `string` values are not equal. + function assertNotEq(string[] calldata left, string[] calldata right) external pure; + + /// Asserts that two arrays of `string` values are not equal and includes error message into revert string on failure. + function assertNotEq(string[] calldata left, string[] calldata right, string calldata error) external pure; + + /// Asserts that two arrays of `bytes` values are not equal. + function assertNotEq(bytes[] calldata left, bytes[] calldata right) external pure; + + /// Asserts that two arrays of `bytes` values are not equal and includes error message into revert string on failure. + function assertNotEq(bytes[] calldata left, bytes[] calldata right, string calldata error) external pure; + + /// Asserts that two `uint256` values are not equal and includes error message into revert string on failure. + function assertNotEq(uint256 left, uint256 right, string calldata error) external pure; + + /// Asserts that two `int256` values are not equal. + function assertNotEq(int256 left, int256 right) external pure; + + /// Asserts that two `int256` values are not equal and includes error message into revert string on failure. + function assertNotEq(int256 left, int256 right, string calldata error) external pure; + + /// Asserts that two `address` values are not equal. + function assertNotEq(address left, address right) external pure; + + /// Asserts that two `address` values are not equal and includes error message into revert string on failure. + function assertNotEq(address left, address right, string calldata error) external pure; + + /// Asserts that two `bytes32` values are not equal. + function assertNotEq(bytes32 left, bytes32 right) external pure; + + /// Asserts that two `bytes32` values are not equal and includes error message into revert string on failure. + function assertNotEq(bytes32 left, bytes32 right, string calldata error) external pure; + + /// Asserts that the given condition is true. + function assertTrue(bool condition) external pure; + + /// Asserts that the given condition is true and includes error message into revert string on failure. + function assertTrue(bool condition, string calldata error) external pure; + + /// If the condition is false, discard this run's fuzz inputs and generate new ones. + function assume(bool condition) external pure; + + /// Discard this run's fuzz inputs and generate new ones if next call reverted. + function assumeNoRevert() external pure; + + /// Discard this run's fuzz inputs and generate new ones if next call reverts with the potential revert parameters. + function assumeNoRevert(PotentialRevert calldata potentialRevert) external pure; + + /// Discard this run's fuzz inputs and generate new ones if next call reverts with the any of the potential revert parameters. + function assumeNoRevert(PotentialRevert[] calldata potentialReverts) external pure; + + /// Writes a breakpoint to jump to in the debugger. + function breakpoint(string calldata char) external pure; + + /// Writes a conditional breakpoint to jump to in the debugger. + function breakpoint(string calldata char, bool value) external pure; + + /// Returns true if the current Foundry version is greater than or equal to the given version. + /// The given version string must be in the format `major.minor.patch`. + /// This is equivalent to `foundryVersionCmp(version) >= 0`. + function foundryVersionAtLeast(string calldata version) external view returns (bool); + + /// Compares the current Foundry version with the given version string. + /// The given version string must be in the format `major.minor.patch`. + /// Returns: + /// -1 if current Foundry version is less than the given version + /// 0 if current Foundry version equals the given version + /// 1 if current Foundry version is greater than the given version + /// This result can then be used with a comparison operator against `0`. + /// For example, to check if the current Foundry version is greater than or equal to `1.0.0`: + /// `if (foundryVersionCmp("1.0.0") >= 0) { ... }` + function foundryVersionCmp(string calldata version) external view returns (int256); + + /// Returns a Chain struct for specific alias + function getChain(string calldata chainAlias) external view returns (Chain memory chain); + + /// Returns a Chain struct for specific chainId + function getChain(uint256 chainId) external view returns (Chain memory chain); + + /// Returns the Foundry version. + /// Format: -+.. + /// Sample output: 0.3.0-nightly+3cb96bde9b.1737036656.debug + /// Note: Build timestamps may vary slightly across platforms due to separate CI jobs. + /// For reliable version comparisons, use UNIX format (e.g., >= 1700000000) + /// to compare timestamps while ignoring minor time differences. + function getFoundryVersion() external view returns (string memory version); + + /// Returns the RPC url for the given alias. + function rpcUrl(string calldata rpcAlias) external view returns (string memory json); + + /// Returns all rpc urls and their aliases as structs. + function rpcUrlStructs() external view returns (Rpc[] memory urls); + + /// Returns all rpc urls and their aliases `[alias, url][]`. + function rpcUrls() external view returns (string[2][] memory urls); + + /// Suspends execution of the main thread for `duration` milliseconds. + function sleep(uint256 duration) external; + + // ======== Toml ======== + + /// Checks if `key` exists in a TOML table. + function keyExistsToml(string calldata toml, string calldata key) external view returns (bool); + + /// Parses a string of TOML data at `key` and coerces it to `address`. + function parseTomlAddress(string calldata toml, string calldata key) external pure returns (address); + + /// Parses a string of TOML data at `key` and coerces it to `address[]`. + function parseTomlAddressArray(string calldata toml, string calldata key) + external + pure + returns (address[] memory); + + /// Parses a string of TOML data at `key` and coerces it to `bool`. + function parseTomlBool(string calldata toml, string calldata key) external pure returns (bool); + + /// Parses a string of TOML data at `key` and coerces it to `bool[]`. + function parseTomlBoolArray(string calldata toml, string calldata key) external pure returns (bool[] memory); + + /// Parses a string of TOML data at `key` and coerces it to `bytes`. + function parseTomlBytes(string calldata toml, string calldata key) external pure returns (bytes memory); + + /// Parses a string of TOML data at `key` and coerces it to `bytes32`. + function parseTomlBytes32(string calldata toml, string calldata key) external pure returns (bytes32); + + /// Parses a string of TOML data at `key` and coerces it to `bytes32[]`. + function parseTomlBytes32Array(string calldata toml, string calldata key) + external + pure + returns (bytes32[] memory); + + /// Parses a string of TOML data at `key` and coerces it to `bytes[]`. + function parseTomlBytesArray(string calldata toml, string calldata key) external pure returns (bytes[] memory); + + /// Parses a string of TOML data at `key` and coerces it to `int256`. + function parseTomlInt(string calldata toml, string calldata key) external pure returns (int256); + + /// Parses a string of TOML data at `key` and coerces it to `int256[]`. + function parseTomlIntArray(string calldata toml, string calldata key) external pure returns (int256[] memory); + + /// Returns an array of all the keys in a TOML table. + function parseTomlKeys(string calldata toml, string calldata key) external pure returns (string[] memory keys); + + /// Parses a string of TOML data at `key` and coerces it to `string`. + function parseTomlString(string calldata toml, string calldata key) external pure returns (string memory); + + /// Parses a string of TOML data at `key` and coerces it to `string[]`. + function parseTomlStringArray(string calldata toml, string calldata key) external pure returns (string[] memory); + + /// Parses a string of TOML data at `key` and coerces it to type array corresponding to `typeDescription`. + function parseTomlTypeArray(string calldata toml, string calldata key, string calldata typeDescription) + external + pure + returns (bytes memory); + + /// Parses a string of TOML data and coerces it to type corresponding to `typeDescription`. + function parseTomlType(string calldata toml, string calldata typeDescription) + external + pure + returns (bytes memory); + + /// Parses a string of TOML data at `key` and coerces it to type corresponding to `typeDescription`. + function parseTomlType(string calldata toml, string calldata key, string calldata typeDescription) + external + pure + returns (bytes memory); + + /// Parses a string of TOML data at `key` and coerces it to `uint256`. + function parseTomlUint(string calldata toml, string calldata key) external pure returns (uint256); + + /// Parses a string of TOML data at `key` and coerces it to `uint256[]`. + function parseTomlUintArray(string calldata toml, string calldata key) external pure returns (uint256[] memory); + + /// ABI-encodes a TOML table. + function parseToml(string calldata toml) external pure returns (bytes memory abiEncodedData); + + /// ABI-encodes a TOML table at `key`. + function parseToml(string calldata toml, string calldata key) external pure returns (bytes memory abiEncodedData); + + /// Takes serialized JSON, converts to TOML and write a serialized TOML to a file. + function writeToml(string calldata json, string calldata path) external; + + /// Takes serialized JSON, converts to TOML and write a serialized TOML table to an **existing** TOML file, replacing a value with key = + /// This is useful to replace a specific value of a TOML file, without having to parse the entire thing. + /// This cheatcode will create new keys if they didn't previously exist. + function writeToml(string calldata json, string calldata path, string calldata valueKey) external; + + // ======== Utilities ======== + + /// Returns an uint256 value bounded in given range and different from the current one. + function bound(uint256 current, uint256 min, uint256 max) external view returns (uint256); + + /// Returns an int256 value bounded in given range and different from the current one. + function bound(int256 current, int256 min, int256 max) external view returns (int256); + + /// Compute the address of a contract created with CREATE2 using the given CREATE2 deployer. + function computeCreate2Address(bytes32 salt, bytes32 initCodeHash, address deployer) + external + pure + returns (address); + + /// Compute the address of a contract created with CREATE2 using the default CREATE2 deployer. + function computeCreate2Address(bytes32 salt, bytes32 initCodeHash) external pure returns (address); + + /// Compute the address a contract will be deployed at for a given deployer address and nonce. + function computeCreateAddress(address deployer, uint256 nonce) external pure returns (address); + + /// Utility cheatcode to copy storage of `from` contract to another `to` contract. + function copyStorage(address from, address to) external; + + /// Generates the struct hash of the canonical EIP-712 type representation and its abi-encoded data. + /// Supports 2 different inputs: + /// 1. Name of the type (i.e. "PermitSingle"): + /// * requires previous binding generation with `forge bind-json`. + /// * bindings will be retrieved from the path configured in `foundry.toml`. + /// 2. String representation of the type (i.e. "Foo(Bar bar) Bar(uint256 baz)"). + /// * Note: the cheatcode will use the canonical type even if the input is malformated + /// with the wrong order of elements or with extra whitespaces. + function eip712HashStruct(string calldata typeNameOrDefinition, bytes calldata abiEncodedData) + external + pure + returns (bytes32 typeHash); + + /// Generates the struct hash of the canonical EIP-712 type representation and its abi-encoded data. + /// Requires previous binding generation with `forge bind-json`. + /// Params: + /// * `bindingsPath`: path where the output of `forge bind-json` is stored. + /// * `typeName`: Name of the type (i.e. "PermitSingle"). + /// * `abiEncodedData`: ABI-encoded data for the struct that is being hashed. + function eip712HashStruct(string calldata bindingsPath, string calldata typeName, bytes calldata abiEncodedData) + external + pure + returns (bytes32 typeHash); + + /// Generates the hash of the canonical EIP-712 type representation. + /// Supports 2 different inputs: + /// 1. Name of the type (i.e. "Transaction"): + /// * requires previous binding generation with `forge bind-json`. + /// * bindings will be retrieved from the path configured in `foundry.toml`. + /// 2. String representation of the type (i.e. "Foo(Bar bar) Bar(uint256 baz)"). + /// * Note: the cheatcode will output the canonical type even if the input is malformated + /// with the wrong order of elements or with extra whitespaces. + function eip712HashType(string calldata typeNameOrDefinition) external pure returns (bytes32 typeHash); + + /// Generates the hash of the canonical EIP-712 type representation. + /// Requires previous binding generation with `forge bind-json`. + /// Params: + /// * `bindingsPath`: path where the output of `forge bind-json` is stored. + /// * `typeName`: Name of the type (i.e. "Transaction"). + function eip712HashType(string calldata bindingsPath, string calldata typeName) + external + pure + returns (bytes32 typeHash); + + /// Generates a ready-to-sign digest of human-readable typed data following the EIP-712 standard. + function eip712HashTypedData(string calldata jsonData) external pure returns (bytes32 digest); + + /// Returns ENS namehash for provided string. + function ensNamehash(string calldata name) external pure returns (bytes32); + + /// Gets the label for the specified address. + function getLabel(address account) external view returns (string memory currentLabel); + + /// Labels an address in call traces. + function label(address account, string calldata newLabel) external; + + /// Pauses collection of call traces. Useful in cases when you want to skip tracing of + /// complex calls which are not useful for debugging. + function pauseTracing() external view; + + /// Returns a random `address`. + function randomAddress() external view returns (address); + + /// Returns a random `bool`. + function randomBool() external view returns (bool); + + /// Returns a random byte array value of the given length. + function randomBytes(uint256 len) external view returns (bytes memory); + + /// Returns a random fixed-size byte array of length 4. + function randomBytes4() external view returns (bytes4); + + /// Returns a random fixed-size byte array of length 8. + function randomBytes8() external view returns (bytes8); + + /// Returns a random `int256` value. + function randomInt() external view returns (int256); + + /// Returns a random `int256` value of given bits. + function randomInt(uint256 bits) external view returns (int256); + + /// Returns a random uint256 value. + function randomUint() external view returns (uint256); + + /// Returns random uint256 value between the provided range (=min..=max). + function randomUint(uint256 min, uint256 max) external view returns (uint256); + + /// Returns a random `uint256` value of given bits. + function randomUint(uint256 bits) external view returns (uint256); + + /// Unpauses collection of call traces. + function resumeTracing() external view; + + /// Utility cheatcode to set arbitrary storage for given target address. + function setArbitraryStorage(address target) external; + + /// Utility cheatcode to set arbitrary storage for given target address and overwrite + /// any storage slots that have been previously set. + function setArbitraryStorage(address target, bool overwrite) external; + + /// Set RNG seed. + function setSeed(uint256 seed) external; + + /// Randomly shuffles an array. + function shuffle(uint256[] calldata array) external returns (uint256[] memory); + + /// Sorts an array in ascending order. + function sort(uint256[] calldata array) external returns (uint256[] memory); + + /// Encodes a `bytes` value to a base64url string. + function toBase64URL(bytes calldata data) external pure returns (string memory); + + /// Encodes a `string` value to a base64url string. + function toBase64URL(string calldata data) external pure returns (string memory); + + /// Encodes a `bytes` value to a base64 string. + function toBase64(bytes calldata data) external pure returns (string memory); + + /// Encodes a `string` value to a base64 string. + function toBase64(string calldata data) external pure returns (string memory); +} + +/// The `Vm` interface does allow manipulation of the EVM state. These are all intended to be used +/// in tests, but it is not recommended to use these cheats in scripts. +interface Vm is VmSafe { + // ======== EVM ======== + + /// Utility cheatcode to set an EIP-2930 access list for all subsequent transactions. + function accessList(AccessListItem[] calldata access) external; + + /// Returns the identifier of the currently active fork. Reverts if no fork is currently active. + function activeFork() external view returns (uint256 forkId); + + /// In forking mode, explicitly grant the given address cheatcode access. + function allowCheatcodes(address account) external; + + /// Sets `block.blobbasefee` + function blobBaseFee(uint256 newBlobBaseFee) external; + + /// Sets the blobhashes in the transaction. + /// Not available on EVM versions before Cancun. + /// If used on unsupported EVM versions it will revert. + function blobhashes(bytes32[] calldata hashes) external; + + /// Sets `block.chainid`. + function chainId(uint256 newChainId) external; + + /// Clears all mocked calls. + function clearMockedCalls() external; + + /// Clones a source account code, state, balance and nonce to a target account and updates in-memory EVM state. + function cloneAccount(address source, address target) external; + + /// Sets `block.coinbase`. + function coinbase(address newCoinbase) external; + + /// Marks the slots of an account and the account address as cold. + function cool(address target) external; + + /// Utility cheatcode to mark specific storage slot as cold, simulating no prior read. + function coolSlot(address target, bytes32 slot) external; + + /// Creates a new fork with the given endpoint and the _latest_ block and returns the identifier of the fork. + function createFork(string calldata urlOrAlias) external returns (uint256 forkId); + + /// Creates a new fork with the given endpoint and block and returns the identifier of the fork. + function createFork(string calldata urlOrAlias, uint256 blockNumber) external returns (uint256 forkId); + + /// Creates a new fork with the given endpoint and at the block the given transaction was mined in, + /// replays all transaction mined in the block before the transaction, and returns the identifier of the fork. + function createFork(string calldata urlOrAlias, bytes32 txHash) external returns (uint256 forkId); + + /// Creates and also selects a new fork with the given endpoint and the latest block and returns the identifier of the fork. + function createSelectFork(string calldata urlOrAlias) external returns (uint256 forkId); + + /// Creates and also selects a new fork with the given endpoint and block and returns the identifier of the fork. + function createSelectFork(string calldata urlOrAlias, uint256 blockNumber) external returns (uint256 forkId); + + /// Creates and also selects new fork with the given endpoint and at the block the given transaction was mined in, + /// replays all transaction mined in the block before the transaction, returns the identifier of the fork. + function createSelectFork(string calldata urlOrAlias, bytes32 txHash) external returns (uint256 forkId); + + /// Sets an address' balance. + function deal(address account, uint256 newBalance) external; + + /// Removes the snapshot with the given ID created by `snapshot`. + /// Takes the snapshot ID to delete. + /// Returns `true` if the snapshot was successfully deleted. + /// Returns `false` if the snapshot does not exist. + function deleteStateSnapshot(uint256 snapshotId) external returns (bool success); + + /// Removes _all_ snapshots previously created by `snapshot`. + function deleteStateSnapshots() external; + + /// Sets `block.difficulty`. + /// Not available on EVM versions from Paris onwards. Use `prevrandao` instead. + /// Reverts if used on unsupported EVM versions. + function difficulty(uint256 newDifficulty) external; + + /// Dump a genesis JSON file's `allocs` to disk. + function dumpState(string calldata pathToStateJson) external; + + /// Sets an address' code. + function etch(address target, bytes calldata newRuntimeBytecode) external; + + /// Sets `block.basefee`. + function fee(uint256 newBasefee) external; + + /// Gets the blockhashes from the current transaction. + /// Not available on EVM versions before Cancun. + /// If used on unsupported EVM versions it will revert. + function getBlobhashes() external view returns (bytes32[] memory hashes); + + /// Returns true if the account is marked as persistent. + function isPersistent(address account) external view returns (bool persistent); + + /// Load a genesis JSON file's `allocs` into the in-memory EVM state. + function loadAllocs(string calldata pathToAllocsJson) external; + + /// Marks that the account(s) should use persistent storage across fork swaps in a multifork setup + /// Meaning, changes made to the state of this account will be kept when switching forks. + function makePersistent(address account) external; + + /// See `makePersistent(address)`. + function makePersistent(address account0, address account1) external; + + /// See `makePersistent(address)`. + function makePersistent(address account0, address account1, address account2) external; + + /// See `makePersistent(address)`. + function makePersistent(address[] calldata accounts) external; + + /// Reverts a call to an address with specified revert data. + function mockCallRevert(address callee, bytes calldata data, bytes calldata revertData) external; + + /// Reverts a call to an address with a specific `msg.value`, with specified revert data. + function mockCallRevert(address callee, uint256 msgValue, bytes calldata data, bytes calldata revertData) + external; + + /// Reverts a call to an address with specified revert data. + /// Overload to pass the function selector directly `token.approve.selector` instead of `abi.encodeWithSelector(token.approve.selector)`. + function mockCallRevert(address callee, bytes4 data, bytes calldata revertData) external; + + /// Reverts a call to an address with a specific `msg.value`, with specified revert data. + /// Overload to pass the function selector directly `token.approve.selector` instead of `abi.encodeWithSelector(token.approve.selector)`. + function mockCallRevert(address callee, uint256 msgValue, bytes4 data, bytes calldata revertData) external; + + /// Mocks a call to an address, returning specified data. + /// Calldata can either be strict or a partial match, e.g. if you only + /// pass a Solidity selector to the expected calldata, then the entire Solidity + /// function will be mocked. + function mockCall(address callee, bytes calldata data, bytes calldata returnData) external; + + /// Mocks a call to an address with a specific `msg.value`, returning specified data. + /// Calldata match takes precedence over `msg.value` in case of ambiguity. + function mockCall(address callee, uint256 msgValue, bytes calldata data, bytes calldata returnData) external; + + /// Mocks a call to an address, returning specified data. + /// Calldata can either be strict or a partial match, e.g. if you only + /// pass a Solidity selector to the expected calldata, then the entire Solidity + /// function will be mocked. + /// Overload to pass the function selector directly `token.approve.selector` instead of `abi.encodeWithSelector(token.approve.selector)`. + function mockCall(address callee, bytes4 data, bytes calldata returnData) external; + + /// Mocks a call to an address with a specific `msg.value`, returning specified data. + /// Calldata match takes precedence over `msg.value` in case of ambiguity. + /// Overload to pass the function selector directly `token.approve.selector` instead of `abi.encodeWithSelector(token.approve.selector)`. + function mockCall(address callee, uint256 msgValue, bytes4 data, bytes calldata returnData) external; + + /// Mocks multiple calls to an address, returning specified data for each call. + function mockCalls(address callee, bytes calldata data, bytes[] calldata returnData) external; + + /// Mocks multiple calls to an address with a specific `msg.value`, returning specified data for each call. + function mockCalls(address callee, uint256 msgValue, bytes calldata data, bytes[] calldata returnData) external; + + /// Whenever a call is made to `callee` with calldata `data`, this cheatcode instead calls + /// `target` with the same calldata. This functionality is similar to a delegate call made to + /// `target` contract from `callee`. + /// Can be used to substitute a call to a function with another implementation that captures + /// the primary logic of the original function but is easier to reason about. + /// If calldata is not a strict match then partial match by selector is attempted. + function mockFunction(address callee, address target, bytes calldata data) external; + + /// Utility cheatcode to remove any EIP-2930 access list set by `accessList` cheatcode. + function noAccessList() external; + + /// Sets the *next* call's `msg.sender` to be the input address. + function prank(address msgSender) external; + + /// Sets the *next* call's `msg.sender` to be the input address, and the `tx.origin` to be the second input. + function prank(address msgSender, address txOrigin) external; + + /// Sets the *next* delegate call's `msg.sender` to be the input address. + function prank(address msgSender, bool delegateCall) external; + + /// Sets the *next* delegate call's `msg.sender` to be the input address, and the `tx.origin` to be the second input. + function prank(address msgSender, address txOrigin, bool delegateCall) external; + + /// Sets `block.prevrandao`. + /// Not available on EVM versions before Paris. Use `difficulty` instead. + /// If used on unsupported EVM versions it will revert. + function prevrandao(bytes32 newPrevrandao) external; + + /// Sets `block.prevrandao`. + /// Not available on EVM versions before Paris. Use `difficulty` instead. + /// If used on unsupported EVM versions it will revert. + function prevrandao(uint256 newPrevrandao) external; + + /// Reads the current `msg.sender` and `tx.origin` from state and reports if there is any active caller modification. + function readCallers() external view returns (CallerMode callerMode, address msgSender, address txOrigin); + + /// Resets the nonce of an account to 0 for EOAs and 1 for contract accounts. + function resetNonce(address account) external; + + /// Revert the state of the EVM to a previous snapshot + /// Takes the snapshot ID to revert to. + /// Returns `true` if the snapshot was successfully reverted. + /// Returns `false` if the snapshot does not exist. + /// **Note:** This does not automatically delete the snapshot. To delete the snapshot use `deleteStateSnapshot`. + function revertToState(uint256 snapshotId) external returns (bool success); + + /// Revert the state of the EVM to a previous snapshot and automatically deletes the snapshots + /// Takes the snapshot ID to revert to. + /// Returns `true` if the snapshot was successfully reverted and deleted. + /// Returns `false` if the snapshot does not exist. + function revertToStateAndDelete(uint256 snapshotId) external returns (bool success); + + /// Revokes persistent status from the address, previously added via `makePersistent`. + function revokePersistent(address account) external; + + /// See `revokePersistent(address)`. + function revokePersistent(address[] calldata accounts) external; + + /// Sets `block.height`. + function roll(uint256 newHeight) external; + + /// Updates the currently active fork to given block number + /// This is similar to `roll` but for the currently active fork. + function rollFork(uint256 blockNumber) external; + + /// Updates the currently active fork to given transaction. This will `rollFork` with the number + /// of the block the transaction was mined in and replays all transaction mined before it in the block. + function rollFork(bytes32 txHash) external; + + /// Updates the given fork to given block number. + function rollFork(uint256 forkId, uint256 blockNumber) external; + + /// Updates the given fork to block number of the given transaction and replays all transaction mined before it in the block. + function rollFork(uint256 forkId, bytes32 txHash) external; + + /// Takes a fork identifier created by `createFork` and sets the corresponding forked state as active. + function selectFork(uint256 forkId) external; + + /// Set blockhash for the current block. + /// It only sets the blockhash for blocks where `block.number - 256 <= number < block.number`. + function setBlockhash(uint256 blockNumber, bytes32 blockHash) external; + + /// Sets the nonce of an account. Must be higher than the current nonce of the account. + function setNonce(address account, uint64 newNonce) external; + + /// Sets the nonce of an account to an arbitrary value. + function setNonceUnsafe(address account, uint64 newNonce) external; + + /// Snapshot capture the gas usage of the last call by name from the callee perspective. + function snapshotGasLastCall(string calldata name) external returns (uint256 gasUsed); + + /// Snapshot capture the gas usage of the last call by name in a group from the callee perspective. + function snapshotGasLastCall(string calldata group, string calldata name) external returns (uint256 gasUsed); + + /// Snapshot the current state of the evm. + /// Returns the ID of the snapshot that was created. + /// To revert a snapshot use `revertToState`. + function snapshotState() external returns (uint256 snapshotId); + + /// Snapshot capture an arbitrary numerical value by name. + /// The group name is derived from the contract name. + function snapshotValue(string calldata name, uint256 value) external; + + /// Snapshot capture an arbitrary numerical value by name in a group. + function snapshotValue(string calldata group, string calldata name, uint256 value) external; + + /// Sets all subsequent calls' `msg.sender` to be the input address until `stopPrank` is called. + function startPrank(address msgSender) external; + + /// Sets all subsequent calls' `msg.sender` to be the input address until `stopPrank` is called, and the `tx.origin` to be the second input. + function startPrank(address msgSender, address txOrigin) external; + + /// Sets all subsequent delegate calls' `msg.sender` to be the input address until `stopPrank` is called. + function startPrank(address msgSender, bool delegateCall) external; + + /// Sets all subsequent delegate calls' `msg.sender` to be the input address until `stopPrank` is called, and the `tx.origin` to be the second input. + function startPrank(address msgSender, address txOrigin, bool delegateCall) external; + + /// Start a snapshot capture of the current gas usage by name. + /// The group name is derived from the contract name. + function startSnapshotGas(string calldata name) external; + + /// Start a snapshot capture of the current gas usage by name in a group. + function startSnapshotGas(string calldata group, string calldata name) external; + + /// Resets subsequent calls' `msg.sender` to be `address(this)`. + function stopPrank() external; + + /// Stop the snapshot capture of the current gas by latest snapshot name, capturing the gas used since the start. + function stopSnapshotGas() external returns (uint256 gasUsed); + + /// Stop the snapshot capture of the current gas usage by name, capturing the gas used since the start. + /// The group name is derived from the contract name. + function stopSnapshotGas(string calldata name) external returns (uint256 gasUsed); + + /// Stop the snapshot capture of the current gas usage by name in a group, capturing the gas used since the start. + function stopSnapshotGas(string calldata group, string calldata name) external returns (uint256 gasUsed); + + /// Stores a value to an address' storage slot. + function store(address target, bytes32 slot, bytes32 value) external; + + /// Fetches the given transaction from the active fork and executes it on the current state. + function transact(bytes32 txHash) external; + + /// Fetches the given transaction from the given fork and executes it on the current state. + function transact(uint256 forkId, bytes32 txHash) external; + + /// Sets `tx.gasprice`. + function txGasPrice(uint256 newGasPrice) external; + + /// Utility cheatcode to mark specific storage slot as warm, simulating a prior read. + function warmSlot(address target, bytes32 slot) external; + + /// Sets `block.timestamp`. + function warp(uint256 newTimestamp) external; + + /// `deleteSnapshot` is being deprecated in favor of `deleteStateSnapshot`. It will be removed in future versions. + function deleteSnapshot(uint256 snapshotId) external returns (bool success); + + /// `deleteSnapshots` is being deprecated in favor of `deleteStateSnapshots`. It will be removed in future versions. + function deleteSnapshots() external; + + /// `revertToAndDelete` is being deprecated in favor of `revertToStateAndDelete`. It will be removed in future versions. + function revertToAndDelete(uint256 snapshotId) external returns (bool success); + + /// `revertTo` is being deprecated in favor of `revertToState`. It will be removed in future versions. + function revertTo(uint256 snapshotId) external returns (bool success); + + /// `snapshot` is being deprecated in favor of `snapshotState`. It will be removed in future versions. + function snapshot() external returns (uint256 snapshotId); + + // ======== Testing ======== + + /// Expect a call to an address with the specified `msg.value` and calldata, and a *minimum* amount of gas. + function expectCallMinGas(address callee, uint256 msgValue, uint64 minGas, bytes calldata data) external; + + /// Expect given number of calls to an address with the specified `msg.value` and calldata, and a *minimum* amount of gas. + function expectCallMinGas(address callee, uint256 msgValue, uint64 minGas, bytes calldata data, uint64 count) + external; + + /// Expects a call to an address with the specified calldata. + /// Calldata can either be a strict or a partial match. + function expectCall(address callee, bytes calldata data) external; + + /// Expects given number of calls to an address with the specified calldata. + function expectCall(address callee, bytes calldata data, uint64 count) external; + + /// Expects a call to an address with the specified `msg.value` and calldata. + function expectCall(address callee, uint256 msgValue, bytes calldata data) external; + + /// Expects given number of calls to an address with the specified `msg.value` and calldata. + function expectCall(address callee, uint256 msgValue, bytes calldata data, uint64 count) external; + + /// Expect a call to an address with the specified `msg.value`, gas, and calldata. + function expectCall(address callee, uint256 msgValue, uint64 gas, bytes calldata data) external; + + /// Expects given number of calls to an address with the specified `msg.value`, gas, and calldata. + function expectCall(address callee, uint256 msgValue, uint64 gas, bytes calldata data, uint64 count) external; + + /// Expects the deployment of the specified bytecode by the specified address using the CREATE opcode + function expectCreate(bytes calldata bytecode, address deployer) external; + + /// Expects the deployment of the specified bytecode by the specified address using the CREATE2 opcode + function expectCreate2(bytes calldata bytecode, address deployer) external; + + /// Prepare an expected anonymous log with (bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData.). + /// Call this function, then emit an anonymous event, then call a function. Internally after the call, we check if + /// logs were emitted in the expected order with the expected topics and data (as specified by the booleans). + function expectEmitAnonymous(bool checkTopic0, bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData) + external; + + /// Same as the previous method, but also checks supplied address against emitting contract. + function expectEmitAnonymous( + bool checkTopic0, + bool checkTopic1, + bool checkTopic2, + bool checkTopic3, + bool checkData, + address emitter + ) external; + + /// Prepare an expected anonymous log with all topic and data checks enabled. + /// Call this function, then emit an anonymous event, then call a function. Internally after the call, we check if + /// logs were emitted in the expected order with the expected topics and data. + function expectEmitAnonymous() external; + + /// Same as the previous method, but also checks supplied address against emitting contract. + function expectEmitAnonymous(address emitter) external; + + /// Prepare an expected log with (bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData.). + /// Call this function, then emit an event, then call a function. Internally after the call, we check if + /// logs were emitted in the expected order with the expected topics and data (as specified by the booleans). + function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData) external; + + /// Same as the previous method, but also checks supplied address against emitting contract. + function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData, address emitter) + external; + + /// Prepare an expected log with all topic and data checks enabled. + /// Call this function, then emit an event, then call a function. Internally after the call, we check if + /// logs were emitted in the expected order with the expected topics and data. + function expectEmit() external; + + /// Same as the previous method, but also checks supplied address against emitting contract. + function expectEmit(address emitter) external; + + /// Expect a given number of logs with the provided topics. + function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData, uint64 count) external; + + /// Expect a given number of logs from a specific emitter with the provided topics. + function expectEmit( + bool checkTopic1, + bool checkTopic2, + bool checkTopic3, + bool checkData, + address emitter, + uint64 count + ) external; + + /// Expect a given number of logs with all topic and data checks enabled. + function expectEmit(uint64 count) external; + + /// Expect a given number of logs from a specific emitter with all topic and data checks enabled. + function expectEmit(address emitter, uint64 count) external; + + /// Expects an error on next call that starts with the revert data. + function expectPartialRevert(bytes4 revertData) external; + + /// Expects an error on next call to reverter address, that starts with the revert data. + function expectPartialRevert(bytes4 revertData, address reverter) external; + + /// Expects an error on next call with any revert data. + function expectRevert() external; + + /// Expects an error on next call that exactly matches the revert data. + function expectRevert(bytes4 revertData) external; + + /// Expects a `count` number of reverts from the upcoming calls from the reverter address that match the revert data. + function expectRevert(bytes4 revertData, address reverter, uint64 count) external; + + /// Expects a `count` number of reverts from the upcoming calls from the reverter address that exactly match the revert data. + function expectRevert(bytes calldata revertData, address reverter, uint64 count) external; + + /// Expects an error on next call that exactly matches the revert data. + function expectRevert(bytes calldata revertData) external; + + /// Expects an error with any revert data on next call to reverter address. + function expectRevert(address reverter) external; + + /// Expects an error from reverter address on next call, with any revert data. + function expectRevert(bytes4 revertData, address reverter) external; + + /// Expects an error from reverter address on next call, that exactly matches the revert data. + function expectRevert(bytes calldata revertData, address reverter) external; + + /// Expects a `count` number of reverts from the upcoming calls with any revert data or reverter. + function expectRevert(uint64 count) external; + + /// Expects a `count` number of reverts from the upcoming calls that match the revert data. + function expectRevert(bytes4 revertData, uint64 count) external; + + /// Expects a `count` number of reverts from the upcoming calls that exactly match the revert data. + function expectRevert(bytes calldata revertData, uint64 count) external; + + /// Expects a `count` number of reverts from the upcoming calls from the reverter address. + function expectRevert(address reverter, uint64 count) external; + + /// Only allows memory writes to offsets [0x00, 0x60) ∪ [min, max) in the current subcontext. If any other + /// memory is written to, the test will fail. Can be called multiple times to add more ranges to the set. + function expectSafeMemory(uint64 min, uint64 max) external; + + /// Only allows memory writes to offsets [0x00, 0x60) ∪ [min, max) in the next created subcontext. + /// If any other memory is written to, the test will fail. Can be called multiple times to add more ranges + /// to the set. + function expectSafeMemoryCall(uint64 min, uint64 max) external; + + /// Marks a test as skipped. Must be called at the top level of a test. + function skip(bool skipTest) external; + + /// Marks a test as skipped with a reason. Must be called at the top level of a test. + function skip(bool skipTest, string calldata reason) external; + + /// Stops all safe memory expectation in the current subcontext. + function stopExpectSafeMemory() external; + + // ======== Utilities ======== + + /// Causes the next contract creation (via new) to fail and return its initcode in the returndata buffer. + /// This allows type-safe access to the initcode payload that would be used for contract creation. + /// Example usage: + /// vm.interceptInitcode(); + /// bytes memory initcode; + /// try new MyContract(param1, param2) { assert(false); } + /// catch (bytes memory interceptedInitcode) { initcode = interceptedInitcode; } + function interceptInitcode() external; +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/console.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/console.sol new file mode 100644 index 0000000000..4fdb6679ed --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/console.sol @@ -0,0 +1,1560 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.4.22 <0.9.0; + +library console { + address constant CONSOLE_ADDRESS = + 0x000000000000000000636F6e736F6c652e6c6f67; + + function _sendLogPayloadImplementation(bytes memory payload) internal view { + address consoleAddress = CONSOLE_ADDRESS; + /// @solidity memory-safe-assembly + assembly { + pop( + staticcall( + gas(), + consoleAddress, + add(payload, 32), + mload(payload), + 0, + 0 + ) + ) + } + } + + function _castToPure( + function(bytes memory) internal view fnIn + ) internal pure returns (function(bytes memory) pure fnOut) { + assembly { + fnOut := fnIn + } + } + + function _sendLogPayload(bytes memory payload) internal pure { + _castToPure(_sendLogPayloadImplementation)(payload); + } + + function log() internal pure { + _sendLogPayload(abi.encodeWithSignature("log()")); + } + + function logInt(int256 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(int256)", p0)); + } + + function logUint(uint256 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0)); + } + + function logString(string memory p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); + } + + function logBool(bool p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); + } + + function logAddress(address p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); + } + + function logBytes(bytes memory p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes)", p0)); + } + + function logBytes1(bytes1 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0)); + } + + function logBytes2(bytes2 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0)); + } + + function logBytes3(bytes3 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0)); + } + + function logBytes4(bytes4 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0)); + } + + function logBytes5(bytes5 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0)); + } + + function logBytes6(bytes6 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0)); + } + + function logBytes7(bytes7 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0)); + } + + function logBytes8(bytes8 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0)); + } + + function logBytes9(bytes9 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0)); + } + + function logBytes10(bytes10 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0)); + } + + function logBytes11(bytes11 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0)); + } + + function logBytes12(bytes12 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0)); + } + + function logBytes13(bytes13 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0)); + } + + function logBytes14(bytes14 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0)); + } + + function logBytes15(bytes15 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0)); + } + + function logBytes16(bytes16 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0)); + } + + function logBytes17(bytes17 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0)); + } + + function logBytes18(bytes18 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0)); + } + + function logBytes19(bytes19 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0)); + } + + function logBytes20(bytes20 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0)); + } + + function logBytes21(bytes21 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0)); + } + + function logBytes22(bytes22 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0)); + } + + function logBytes23(bytes23 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0)); + } + + function logBytes24(bytes24 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0)); + } + + function logBytes25(bytes25 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0)); + } + + function logBytes26(bytes26 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0)); + } + + function logBytes27(bytes27 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0)); + } + + function logBytes28(bytes28 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0)); + } + + function logBytes29(bytes29 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0)); + } + + function logBytes30(bytes30 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0)); + } + + function logBytes31(bytes31 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0)); + } + + function logBytes32(bytes32 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0)); + } + + function log(uint256 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0)); + } + + function log(int256 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(int256)", p0)); + } + + function log(string memory p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); + } + + function log(bool p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); + } + + function log(address p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); + } + + function log(uint256 p0, uint256 p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256)", p0, p1)); + } + + function log(uint256 p0, string memory p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string)", p0, p1)); + } + + function log(uint256 p0, bool p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool)", p0, p1)); + } + + function log(uint256 p0, address p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address)", p0, p1)); + } + + function log(string memory p0, uint256 p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256)", p0, p1)); + } + + function log(string memory p0, int256 p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,int256)", p0, p1)); + } + + function log(string memory p0, string memory p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1)); + } + + function log(string memory p0, bool p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1)); + } + + function log(string memory p0, address p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1)); + } + + function log(bool p0, uint256 p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256)", p0, p1)); + } + + function log(bool p0, string memory p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1)); + } + + function log(bool p0, bool p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1)); + } + + function log(bool p0, address p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1)); + } + + function log(address p0, uint256 p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256)", p0, p1)); + } + + function log(address p0, string memory p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1)); + } + + function log(address p0, bool p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1)); + } + + function log(address p0, address p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1)); + } + + function log(uint256 p0, uint256 p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256)", p0, p1, p2)); + } + + function log(uint256 p0, uint256 p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string)", p0, p1, p2)); + } + + function log(uint256 p0, uint256 p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool)", p0, p1, p2)); + } + + function log(uint256 p0, uint256 p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address)", p0, p1, p2)); + } + + function log(uint256 p0, string memory p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256)", p0, p1, p2)); + } + + function log(uint256 p0, string memory p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string)", p0, p1, p2)); + } + + function log(uint256 p0, string memory p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool)", p0, p1, p2)); + } + + function log(uint256 p0, string memory p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address)", p0, p1, p2)); + } + + function log(uint256 p0, bool p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256)", p0, p1, p2)); + } + + function log(uint256 p0, bool p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string)", p0, p1, p2)); + } + + function log(uint256 p0, bool p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool)", p0, p1, p2)); + } + + function log(uint256 p0, bool p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address)", p0, p1, p2)); + } + + function log(uint256 p0, address p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256)", p0, p1, p2)); + } + + function log(uint256 p0, address p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string)", p0, p1, p2)); + } + + function log(uint256 p0, address p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool)", p0, p1, p2)); + } + + function log(uint256 p0, address p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address)", p0, p1, p2)); + } + + function log(string memory p0, uint256 p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256)", p0, p1, p2)); + } + + function log(string memory p0, uint256 p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string)", p0, p1, p2)); + } + + function log(string memory p0, uint256 p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool)", p0, p1, p2)); + } + + function log(string memory p0, uint256 p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address)", p0, p1, p2)); + } + + function log(string memory p0, string memory p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256)", p0, p1, p2)); + } + + function log(string memory p0, string memory p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2)); + } + + function log(string memory p0, string memory p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2)); + } + + function log(string memory p0, string memory p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2)); + } + + function log(string memory p0, bool p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256)", p0, p1, p2)); + } + + function log(string memory p0, bool p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2)); + } + + function log(string memory p0, bool p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2)); + } + + function log(string memory p0, bool p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2)); + } + + function log(string memory p0, address p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256)", p0, p1, p2)); + } + + function log(string memory p0, address p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2)); + } + + function log(string memory p0, address p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2)); + } + + function log(string memory p0, address p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2)); + } + + function log(bool p0, uint256 p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256)", p0, p1, p2)); + } + + function log(bool p0, uint256 p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string)", p0, p1, p2)); + } + + function log(bool p0, uint256 p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool)", p0, p1, p2)); + } + + function log(bool p0, uint256 p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address)", p0, p1, p2)); + } + + function log(bool p0, string memory p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256)", p0, p1, p2)); + } + + function log(bool p0, string memory p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2)); + } + + function log(bool p0, string memory p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2)); + } + + function log(bool p0, string memory p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2)); + } + + function log(bool p0, bool p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256)", p0, p1, p2)); + } + + function log(bool p0, bool p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2)); + } + + function log(bool p0, bool p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2)); + } + + function log(bool p0, bool p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2)); + } + + function log(bool p0, address p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256)", p0, p1, p2)); + } + + function log(bool p0, address p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2)); + } + + function log(bool p0, address p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2)); + } + + function log(bool p0, address p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2)); + } + + function log(address p0, uint256 p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256)", p0, p1, p2)); + } + + function log(address p0, uint256 p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string)", p0, p1, p2)); + } + + function log(address p0, uint256 p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool)", p0, p1, p2)); + } + + function log(address p0, uint256 p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address)", p0, p1, p2)); + } + + function log(address p0, string memory p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256)", p0, p1, p2)); + } + + function log(address p0, string memory p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2)); + } + + function log(address p0, string memory p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2)); + } + + function log(address p0, string memory p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2)); + } + + function log(address p0, bool p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256)", p0, p1, p2)); + } + + function log(address p0, bool p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2)); + } + + function log(address p0, bool p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2)); + } + + function log(address p0, bool p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2)); + } + + function log(address p0, address p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256)", p0, p1, p2)); + } + + function log(address p0, address p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2)); + } + + function log(address p0, address p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2)); + } + + function log(address p0, address p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2)); + } + + function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,string)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,address)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,string)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,address)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,string)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,address)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,string)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,address)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,string)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,address)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,string)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,address)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,string)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,address)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,string)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,bool)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,address)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,string)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,bool)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,address)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,string)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,bool)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,address)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,string)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,bool)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,address)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,string)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,bool)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,address)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,string)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,bool)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,address)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,string)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,bool)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,address)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3)); + } +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/console2.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/console2.sol new file mode 100644 index 0000000000..03531d91d3 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/console2.sol @@ -0,0 +1,4 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.4.22 <0.9.0; + +import {console as console2} from "./console.sol"; diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/interfaces/IERC1155.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/interfaces/IERC1155.sol new file mode 100644 index 0000000000..ffc82984a7 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/interfaces/IERC1155.sol @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +import {IERC165} from "./IERC165.sol"; + +/// @title ERC-1155 Multi Token Standard +/// @dev See https://eips.ethereum.org/EIPS/eip-1155 +/// Note: The ERC-165 identifier for this interface is 0xd9b67a26. +interface IERC1155 is IERC165 { + /// @dev + /// - Either `TransferSingle` or `TransferBatch` MUST emit when tokens are transferred, including zero value transfers as well as minting or burning (see "Safe Transfer Rules" section of the standard). + /// - The `_operator` argument MUST be the address of an account/contract that is approved to make the transfer (SHOULD be msg.sender). + /// - The `_from` argument MUST be the address of the holder whose balance is decreased. + /// - The `_to` argument MUST be the address of the recipient whose balance is increased. + /// - The `_id` argument MUST be the token type being transferred. + /// - The `_value` argument MUST be the number of tokens the holder balance is decreased by and match what the recipient balance is increased by. + /// - When minting/creating tokens, the `_from` argument MUST be set to `0x0` (i.e. zero address). + /// - When burning/destroying tokens, the `_to` argument MUST be set to `0x0` (i.e. zero address). + event TransferSingle( + address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _value + ); + + /// @dev + /// - Either `TransferSingle` or `TransferBatch` MUST emit when tokens are transferred, including zero value transfers as well as minting or burning (see "Safe Transfer Rules" section of the standard). + /// - The `_operator` argument MUST be the address of an account/contract that is approved to make the transfer (SHOULD be msg.sender). + /// - The `_from` argument MUST be the address of the holder whose balance is decreased. + /// - The `_to` argument MUST be the address of the recipient whose balance is increased. + /// - The `_ids` argument MUST be the list of tokens being transferred. + /// - The `_values` argument MUST be the list of number of tokens (matching the list and order of tokens specified in _ids) the holder balance is decreased by and match what the recipient balance is increased by. + /// - When minting/creating tokens, the `_from` argument MUST be set to `0x0` (i.e. zero address). + /// - When burning/destroying tokens, the `_to` argument MUST be set to `0x0` (i.e. zero address). + event TransferBatch( + address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _values + ); + + /// @dev MUST emit when approval for a second party/operator address to manage all tokens for an owner address is enabled or disabled (absence of an event assumes disabled). + event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); + + /// @dev MUST emit when the URI is updated for a token ID. URIs are defined in RFC 3986. + /// The URI MUST point to a JSON file that conforms to the "ERC-1155 Metadata URI JSON Schema". + event URI(string _value, uint256 indexed _id); + + /// @notice Transfers `_value` amount of an `_id` from the `_from` address to the `_to` address specified (with safety call). + /// @dev Caller must be approved to manage the tokens being transferred out of the `_from` account (see "Approval" section of the standard). + /// - MUST revert if `_to` is the zero address. + /// - MUST revert if balance of holder for token `_id` is lower than the `_value` sent. + /// - MUST revert on any other error. + /// - MUST emit the `TransferSingle` event to reflect the balance change (see "Safe Transfer Rules" section of the standard). + /// - After the above conditions are met, this function MUST check if `_to` is a smart contract (e.g. code size > 0). If so, it MUST call `onERC1155Received` on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard). + /// @param _from Source address + /// @param _to Target address + /// @param _id ID of the token type + /// @param _value Transfer amount + /// @param _data Additional data with no specified format, MUST be sent unaltered in call to `onERC1155Received` on `_to` + function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, bytes calldata _data) external; + + /// @notice Transfers `_values` amount(s) of `_ids` from the `_from` address to the `_to` address specified (with safety call). + /// @dev Caller must be approved to manage the tokens being transferred out of the `_from` account (see "Approval" section of the standard). + /// - MUST revert if `_to` is the zero address. + /// - MUST revert if length of `_ids` is not the same as length of `_values`. + /// - MUST revert if any of the balance(s) of the holder(s) for token(s) in `_ids` is lower than the respective amount(s) in `_values` sent to the recipient. + /// - MUST revert on any other error. + /// - MUST emit `TransferSingle` or `TransferBatch` event(s) such that all the balance changes are reflected (see "Safe Transfer Rules" section of the standard). + /// - Balance changes and events MUST follow the ordering of the arrays (_ids[0]/_values[0] before _ids[1]/_values[1], etc). + /// - After the above conditions for the transfer(s) in the batch are met, this function MUST check if `_to` is a smart contract (e.g. code size > 0). If so, it MUST call the relevant `ERC1155TokenReceiver` hook(s) on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard). + /// @param _from Source address + /// @param _to Target address + /// @param _ids IDs of each token type (order and length must match _values array) + /// @param _values Transfer amounts per token type (order and length must match _ids array) + /// @param _data Additional data with no specified format, MUST be sent unaltered in call to the `ERC1155TokenReceiver` hook(s) on `_to` + function safeBatchTransferFrom( + address _from, + address _to, + uint256[] calldata _ids, + uint256[] calldata _values, + bytes calldata _data + ) external; + + /// @notice Get the balance of an account's tokens. + /// @param _owner The address of the token holder + /// @param _id ID of the token + /// @return The _owner's balance of the token type requested + function balanceOf(address _owner, uint256 _id) external view returns (uint256); + + /// @notice Get the balance of multiple account/token pairs + /// @param _owners The addresses of the token holders + /// @param _ids ID of the tokens + /// @return The _owner's balance of the token types requested (i.e. balance for each (owner, id) pair) + function balanceOfBatch(address[] calldata _owners, uint256[] calldata _ids) + external + view + returns (uint256[] memory); + + /// @notice Enable or disable approval for a third party ("operator") to manage all of the caller's tokens. + /// @dev MUST emit the ApprovalForAll event on success. + /// @param _operator Address to add to the set of authorized operators + /// @param _approved True if the operator is approved, false to revoke approval + function setApprovalForAll(address _operator, bool _approved) external; + + /// @notice Queries the approval status of an operator for a given owner. + /// @param _owner The owner of the tokens + /// @param _operator Address of authorized operator + /// @return True if the operator is approved, false if not + function isApprovedForAll(address _owner, address _operator) external view returns (bool); +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/interfaces/IERC165.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/interfaces/IERC165.sol new file mode 100644 index 0000000000..9af4bf800f --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/interfaces/IERC165.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +interface IERC165 { + /// @notice Query if a contract implements an interface + /// @param interfaceID The interface identifier, as specified in ERC-165 + /// @dev Interface identification is specified in ERC-165. This function + /// uses less than 30,000 gas. + /// @return `true` if the contract implements `interfaceID` and + /// `interfaceID` is not 0xffffffff, `false` otherwise + function supportsInterface(bytes4 interfaceID) external view returns (bool); +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/interfaces/IERC20.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/interfaces/IERC20.sol new file mode 100644 index 0000000000..ba40806c3b --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/interfaces/IERC20.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +/// @dev Interface of the ERC20 standard as defined in the EIP. +/// @dev This includes the optional name, symbol, and decimals metadata. +interface IERC20 { + /// @dev Emitted when `value` tokens are moved from one account (`from`) to another (`to`). + event Transfer(address indexed from, address indexed to, uint256 value); + + /// @dev Emitted when the allowance of a `spender` for an `owner` is set, where `value` + /// is the new allowance. + event Approval(address indexed owner, address indexed spender, uint256 value); + + /// @notice Returns the amount of tokens in existence. + function totalSupply() external view returns (uint256); + + /// @notice Returns the amount of tokens owned by `account`. + function balanceOf(address account) external view returns (uint256); + + /// @notice Moves `amount` tokens from the caller's account to `to`. + function transfer(address to, uint256 amount) external returns (bool); + + /// @notice Returns the remaining number of tokens that `spender` is allowed + /// to spend on behalf of `owner` + function allowance(address owner, address spender) external view returns (uint256); + + /// @notice Sets `amount` as the allowance of `spender` over the caller's tokens. + /// @dev Be aware of front-running risks: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 + function approve(address spender, uint256 amount) external returns (bool); + + /// @notice Moves `amount` tokens from `from` to `to` using the allowance mechanism. + /// `amount` is then deducted from the caller's allowance. + function transferFrom(address from, address to, uint256 amount) external returns (bool); + + /// @notice Returns the name of the token. + function name() external view returns (string memory); + + /// @notice Returns the symbol of the token. + function symbol() external view returns (string memory); + + /// @notice Returns the decimals places of the token. + function decimals() external view returns (uint8); +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/interfaces/IERC4626.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/interfaces/IERC4626.sol new file mode 100644 index 0000000000..c645a0fecf --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/interfaces/IERC4626.sol @@ -0,0 +1,190 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +import {IERC20} from "./IERC20.sol"; + +/// @dev Interface of the ERC4626 "Tokenized Vault Standard", as defined in +/// https://eips.ethereum.org/EIPS/eip-4626 +interface IERC4626 is IERC20 { + event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares); + + event Withdraw( + address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares + ); + + /// @notice Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing. + /// @dev + /// - MUST be an ERC-20 token contract. + /// - MUST NOT revert. + function asset() external view returns (address assetTokenAddress); + + /// @notice Returns the total amount of the underlying asset that is ā€œmanagedā€ by Vault. + /// @dev + /// - SHOULD include any compounding that occurs from yield. + /// - MUST be inclusive of any fees that are charged against assets in the Vault. + /// - MUST NOT revert. + function totalAssets() external view returns (uint256 totalManagedAssets); + + /// @notice Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal + /// scenario where all the conditions are met. + /// @dev + /// - MUST NOT be inclusive of any fees that are charged against assets in the Vault. + /// - MUST NOT show any variations depending on the caller. + /// - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. + /// - MUST NOT revert. + /// + /// NOTE: This calculation MAY NOT reflect the ā€œper-userā€ price-per-share, and instead should reflect the + /// ā€œaverage-user’sā€ price-per-share, meaning what the average user should expect to see when exchanging to and + /// from. + function convertToShares(uint256 assets) external view returns (uint256 shares); + + /// @notice Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal + /// scenario where all the conditions are met. + /// @dev + /// - MUST NOT be inclusive of any fees that are charged against assets in the Vault. + /// - MUST NOT show any variations depending on the caller. + /// - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. + /// - MUST NOT revert. + /// + /// NOTE: This calculation MAY NOT reflect the ā€œper-userā€ price-per-share, and instead should reflect the + /// ā€œaverage-user’sā€ price-per-share, meaning what the average user should expect to see when exchanging to and + /// from. + function convertToAssets(uint256 shares) external view returns (uint256 assets); + + /// @notice Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver, + /// through a deposit call. + /// @dev + /// - MUST return a limited value if receiver is subject to some deposit limit. + /// - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited. + /// - MUST NOT revert. + function maxDeposit(address receiver) external view returns (uint256 maxAssets); + + /// @notice Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given + /// current on-chain conditions. + /// @dev + /// - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit + /// call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called + /// in the same transaction. + /// - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the + /// deposit would be accepted, regardless if the user has enough tokens approved, etc. + /// - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. + /// - MUST NOT revert. + /// + /// NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in + /// share price or some other type of condition, meaning the depositor will lose assets by depositing. + function previewDeposit(uint256 assets) external view returns (uint256 shares); + + /// @notice Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens. + /// @dev + /// - MUST emit the Deposit event. + /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the + /// deposit execution, and are accounted for during deposit. + /// - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not + /// approving enough underlying tokens to the Vault contract, etc). + /// + /// NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. + function deposit(uint256 assets, address receiver) external returns (uint256 shares); + + /// @notice Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call. + /// @dev + /// - MUST return a limited value if receiver is subject to some mint limit. + /// - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted. + /// - MUST NOT revert. + function maxMint(address receiver) external view returns (uint256 maxShares); + + /// @notice Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given + /// current on-chain conditions. + /// @dev + /// - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call + /// in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the + /// same transaction. + /// - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint + /// would be accepted, regardless if the user has enough tokens approved, etc. + /// - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. + /// - MUST NOT revert. + /// + /// NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in + /// share price or some other type of condition, meaning the depositor will lose assets by minting. + function previewMint(uint256 shares) external view returns (uint256 assets); + + /// @notice Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens. + /// @dev + /// - MUST emit the Deposit event. + /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint + /// execution, and are accounted for during mint. + /// - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not + /// approving enough underlying tokens to the Vault contract, etc). + /// + /// NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. + function mint(uint256 shares, address receiver) external returns (uint256 assets); + + /// @notice Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the + /// Vault, through a withdrawal call. + /// @dev + /// - MUST return a limited value if owner is subject to some withdrawal limit or timelock. + /// - MUST NOT revert. + function maxWithdraw(address owner) external view returns (uint256 maxAssets); + + /// @notice Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block, + /// given current on-chain conditions. + /// @dev + /// - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw + /// call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if + /// called + /// in the same transaction. + /// - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though + /// the withdrawal would be accepted, regardless if the user has enough shares, etc. + /// - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. + /// - MUST NOT revert. + /// + /// NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in + /// share price or some other type of condition, meaning the depositor will lose assets by depositing. + function previewWithdraw(uint256 assets) external view returns (uint256 shares); + + /// @notice Burns shares from owner and sends exactly assets of underlying tokens to receiver. + /// @dev + /// - MUST emit the Withdraw event. + /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the + /// withdraw execution, and are accounted for during withdrawal. + /// - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner + /// not having enough shares, etc). + /// + /// Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed. + /// Those methods should be performed separately. + function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares); + + /// @notice Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault, + /// through a redeem call. + /// @dev + /// - MUST return a limited value if owner is subject to some withdrawal limit or timelock. + /// - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock. + /// - MUST NOT revert. + function maxRedeem(address owner) external view returns (uint256 maxShares); + + /// @notice Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block, + /// given current on-chain conditions. + /// @dev + /// - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call + /// in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the + /// same transaction. + /// - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the + /// redemption would be accepted, regardless if the user has enough shares, etc. + /// - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. + /// - MUST NOT revert. + /// + /// NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in + /// share price or some other type of condition, meaning the depositor will lose assets by redeeming. + function previewRedeem(uint256 shares) external view returns (uint256 assets); + + /// @notice Burns exactly shares from owner and sends assets of underlying tokens to receiver. + /// @dev + /// - MUST emit the Withdraw event. + /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the + /// redeem execution, and are accounted for during redeem. + /// - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner + /// not having enough shares, etc). + /// + /// NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed. + /// Those methods should be performed separately. + function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets); +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/interfaces/IERC6909.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/interfaces/IERC6909.sol new file mode 100644 index 0000000000..6e11cb460d --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/interfaces/IERC6909.sol @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +import {IERC165} from "./IERC165.sol"; + +/// @dev Required interface of an ERC-6909 compliant contract, as defined in +/// https://eips.ethereum.org/EIPS/eip-6909 +interface IERC6909 is IERC165 { + /// @dev Emitted when the allowance of a `spender` for an `owner` is set for a token of type `id`. + event Approval(address indexed owner, address indexed spender, uint256 indexed id, uint256 amount); + + /// @dev Emitted when `owner` grants or revokes operator status for a `spender`. + event OperatorSet(address indexed owner, address indexed spender, bool approved); + + /// @dev Emitted when `amount` tokens of type `id` are moved from `sender` to `receiver` initiated by `caller`. + event Transfer( + address caller, address indexed sender, address indexed receiver, uint256 indexed id, uint256 amount + ); + + ///@dev Returns the amount of tokens of type `id` owned by `owner`. + function balanceOf(address owner, uint256 id) external view returns (uint256); + + /// @dev Returns the amount of tokens of type `id` that `spender` is allowed to spend on behalf of `owner`. + /// NOTE: Does not include operator allowances. + function allowance(address owner, address spender, uint256 id) external view returns (uint256); + + /// @dev Returns true if `spender` is set as an operator for `owner`. + function isOperator(address owner, address spender) external view returns (bool); + + /// @dev Sets an approval to `spender` for `amount` tokens of type `id` from the caller's tokens. + /// Must return true. + function approve(address spender, uint256 id, uint256 amount) external returns (bool); + + /// @dev Grants or revokes unlimited transfer permission of any token id to `spender` for the caller's tokens. + /// Must return true. + function setOperator(address spender, bool approved) external returns (bool); + + /// @dev Transfers `amount` of token type `id` from the caller's account to `receiver`. + /// Must return true. + function transfer(address receiver, uint256 id, uint256 amount) external returns (bool); + + /// @dev Transfers `amount` of token type `id` from `sender` to `receiver`. + /// Must return true. + function transferFrom(address sender, address receiver, uint256 id, uint256 amount) external returns (bool); +} + +/// @dev Optional extension of {IERC6909} that adds metadata functions. +interface IERC6909Metadata is IERC6909 { + /// @dev Returns the name of the token of type `id`. + function name(uint256 id) external view returns (string memory); + + /// @dev Returns the ticker symbol of the token of type `id`. + function symbol(uint256 id) external view returns (string memory); + + /// @dev Returns the number of decimals for the token of type `id`. + function decimals(uint256 id) external view returns (uint8); +} + +/// @dev Optional extension of {IERC6909} that adds content URI functions. +interface IERC6909ContentURI is IERC6909 { + /// @dev Returns URI for the contract. + function contractURI() external view returns (string memory); + + /// @dev Returns the URI for the token of type `id`. + function tokenURI(uint256 id) external view returns (string memory); +} + +/// @dev Optional extension of {IERC6909} that adds a token supply function. +interface IERC6909TokenSupply is IERC6909 { + /// @dev Returns the total supply of the token of type `id`. + function totalSupply(uint256 id) external view returns (uint256); +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/interfaces/IERC721.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/interfaces/IERC721.sol new file mode 100644 index 0000000000..21a4a94dea --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/interfaces/IERC721.sol @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +import {IERC165} from "./IERC165.sol"; + +/// @title ERC-721 Non-Fungible Token Standard +/// @dev See https://eips.ethereum.org/EIPS/eip-721 +/// Note: the ERC-165 identifier for this interface is 0x80ac58cd. +interface IERC721 is IERC165 { + /// @dev This emits when ownership of any NFT changes by any mechanism. + /// This event emits when NFTs are created (`from` == 0) and destroyed + /// (`to` == 0). Exception: during contract creation, any number of NFTs + /// may be created and assigned without emitting Transfer. At the time of + /// any transfer, the approved address for that NFT (if any) is reset to none. + event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId); + + /// @dev This emits when the approved address for an NFT is changed or + /// reaffirmed. The zero address indicates there is no approved address. + /// When a Transfer event emits, this also indicates that the approved + /// address for that NFT (if any) is reset to none. + event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId); + + /// @dev This emits when an operator is enabled or disabled for an owner. + /// The operator can manage all NFTs of the owner. + event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); + + /// @notice Count all NFTs assigned to an owner + /// @dev NFTs assigned to the zero address are considered invalid, and this + /// function throws for queries about the zero address. + /// @param _owner An address for whom to query the balance + /// @return The number of NFTs owned by `_owner`, possibly zero + function balanceOf(address _owner) external view returns (uint256); + + /// @notice Find the owner of an NFT + /// @dev NFTs assigned to zero address are considered invalid, and queries + /// about them do throw. + /// @param _tokenId The identifier for an NFT + /// @return The address of the owner of the NFT + function ownerOf(uint256 _tokenId) external view returns (address); + + /// @notice Transfers the ownership of an NFT from one address to another address + /// @dev Throws unless `msg.sender` is the current owner, an authorized + /// operator, or the approved address for this NFT. Throws if `_from` is + /// not the current owner. Throws if `_to` is the zero address. Throws if + /// `_tokenId` is not a valid NFT. When transfer is complete, this function + /// checks if `_to` is a smart contract (code size > 0). If so, it calls + /// `onERC721Received` on `_to` and throws if the return value is not + /// `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`. + /// @param _from The current owner of the NFT + /// @param _to The new owner + /// @param _tokenId The NFT to transfer + /// @param data Additional data with no specified format, sent in call to `_to` + function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes calldata data) external payable; + + /// @notice Transfers the ownership of an NFT from one address to another address + /// @dev This works identically to the other function with an extra data parameter, + /// except this function just sets data to "". + /// @param _from The current owner of the NFT + /// @param _to The new owner + /// @param _tokenId The NFT to transfer + function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable; + + /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE + /// TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE + /// THEY MAY BE PERMANENTLY LOST + /// @dev Throws unless `msg.sender` is the current owner, an authorized + /// operator, or the approved address for this NFT. Throws if `_from` is + /// not the current owner. Throws if `_to` is the zero address. Throws if + /// `_tokenId` is not a valid NFT. + /// @param _from The current owner of the NFT + /// @param _to The new owner + /// @param _tokenId The NFT to transfer + function transferFrom(address _from, address _to, uint256 _tokenId) external payable; + + /// @notice Change or reaffirm the approved address for an NFT + /// @dev The zero address indicates there is no approved address. + /// Throws unless `msg.sender` is the current NFT owner, or an authorized + /// operator of the current owner. + /// @param _approved The new approved NFT controller + /// @param _tokenId The NFT to approve + function approve(address _approved, uint256 _tokenId) external payable; + + /// @notice Enable or disable approval for a third party ("operator") to manage + /// all of `msg.sender`'s assets + /// @dev Emits the ApprovalForAll event. The contract MUST allow + /// multiple operators per owner. + /// @param _operator Address to add to the set of authorized operators + /// @param _approved True if the operator is approved, false to revoke approval + function setApprovalForAll(address _operator, bool _approved) external; + + /// @notice Get the approved address for a single NFT + /// @dev Throws if `_tokenId` is not a valid NFT. + /// @param _tokenId The NFT to find the approved address for + /// @return The approved address for this NFT, or the zero address if there is none + function getApproved(uint256 _tokenId) external view returns (address); + + /// @notice Query if an address is an authorized operator for another address + /// @param _owner The address that owns the NFTs + /// @param _operator The address that acts on behalf of the owner + /// @return True if `_operator` is an approved operator for `_owner`, false otherwise + function isApprovedForAll(address _owner, address _operator) external view returns (bool); +} + +/// @dev Note: the ERC-165 identifier for this interface is 0x150b7a02. +interface IERC721TokenReceiver { + /// @notice Handle the receipt of an NFT + /// @dev The ERC721 smart contract calls this function on the recipient + /// after a `transfer`. This function MAY throw to revert and reject the + /// transfer. Return of other than the magic value MUST result in the + /// transaction being reverted. + /// Note: the contract address is always the message sender. + /// @param _operator The address which called `safeTransferFrom` function + /// @param _from The address which previously owned the token + /// @param _tokenId The NFT identifier which is being transferred + /// @param _data Additional data with no specified format + /// @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` + /// unless throwing + function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes calldata _data) + external + returns (bytes4); +} + +/// @title ERC-721 Non-Fungible Token Standard, optional metadata extension +/// @dev See https://eips.ethereum.org/EIPS/eip-721 +/// Note: the ERC-165 identifier for this interface is 0x5b5e139f. +interface IERC721Metadata is IERC721 { + /// @notice A descriptive name for a collection of NFTs in this contract + function name() external view returns (string memory _name); + + /// @notice An abbreviated name for NFTs in this contract + function symbol() external view returns (string memory _symbol); + + /// @notice A distinct Uniform Resource Identifier (URI) for a given asset. + /// @dev Throws if `_tokenId` is not a valid NFT. URIs are defined in RFC + /// 3986. The URI may point to a JSON file that conforms to the "ERC721 + /// Metadata JSON Schema". + function tokenURI(uint256 _tokenId) external view returns (string memory); +} + +/// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension +/// @dev See https://eips.ethereum.org/EIPS/eip-721 +/// Note: the ERC-165 identifier for this interface is 0x780e9d63. +interface IERC721Enumerable is IERC721 { + /// @notice Count NFTs tracked by this contract + /// @return A count of valid NFTs tracked by this contract, where each one of + /// them has an assigned and queryable owner not equal to the zero address + function totalSupply() external view returns (uint256); + + /// @notice Enumerate valid NFTs + /// @dev Throws if `_index` >= `totalSupply()`. + /// @param _index A counter less than `totalSupply()` + /// @return The token identifier for the `_index`th NFT, + /// (sort order not specified) + function tokenByIndex(uint256 _index) external view returns (uint256); + + /// @notice Enumerate NFTs assigned to an owner + /// @dev Throws if `_index` >= `balanceOf(_owner)` or if + /// `_owner` is the zero address, representing invalid NFTs. + /// @param _owner An address where we are interested in NFTs owned by them + /// @param _index A counter less than `balanceOf(_owner)` + /// @return The token identifier for the `_index`th NFT assigned to `_owner`, + /// (sort order not specified) + function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256); +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/interfaces/IERC7540.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/interfaces/IERC7540.sol new file mode 100644 index 0000000000..91a38ca359 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/interfaces/IERC7540.sol @@ -0,0 +1,150 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +import {IERC7575} from "./IERC7575.sol"; + +/// @dev Interface of the base operator logic of ERC7540, as defined in +/// https://eips.ethereum.org/EIPS/eip-7540 +interface IERC7540Operator { + /** + * @dev The event emitted when an operator is set. + * + * @param controller The address of the controller. + * @param operator The address of the operator. + * @param approved The approval status. + */ + event OperatorSet(address indexed controller, address indexed operator, bool approved); + + /** + * @dev Sets or removes an operator for the caller. + * + * @param operator The address of the operator. + * @param approved The approval status. + * @return Whether the call was executed successfully or not + */ + function setOperator(address operator, bool approved) external returns (bool); + + /** + * @dev Returns `true` if the `operator` is approved as an operator for an `controller`. + * + * @param controller The address of the controller. + * @param operator The address of the operator. + * @return status The approval status + */ + function isOperator(address controller, address operator) external view returns (bool status); +} + +/// @dev Interface of the asynchronous deposit Vault interface of ERC7540, as defined in +/// https://eips.ethereum.org/EIPS/eip-7540 +interface IERC7540Deposit is IERC7540Operator { + event DepositRequest( + address indexed controller, address indexed owner, uint256 indexed requestId, address sender, uint256 assets + ); + /** + * @dev Transfers assets from sender into the Vault and submits a Request for asynchronous deposit. + * + * - MUST support ERC-20 approve / transferFrom on asset as a deposit Request flow. + * - MUST revert if all of assets cannot be requested for deposit. + * - owner MUST be msg.sender unless some unspecified explicit approval is given by the caller, + * approval of ERC-20 tokens from owner to sender is NOT enough. + * + * @param assets the amount of deposit assets to transfer from owner + * @param controller the controller of the request who will be able to operate the request + * @param owner the source of the deposit assets + * + * NOTE: most implementations will require pre-approval of the Vault with the Vault's underlying asset token. + */ + + function requestDeposit(uint256 assets, address controller, address owner) external returns (uint256 requestId); + + /** + * @dev Returns the amount of requested assets in Pending state. + * + * - MUST NOT include any assets in Claimable state for deposit or mint. + * - MUST NOT show any variations depending on the caller. + * - MUST NOT revert unless due to integer overflow caused by an unreasonably large input. + */ + function pendingDepositRequest(uint256 requestId, address controller) + external + view + returns (uint256 pendingAssets); + + /** + * @dev Returns the amount of requested assets in Claimable state for the controller to deposit or mint. + * + * - MUST NOT include any assets in Pending state. + * - MUST NOT show any variations depending on the caller. + * - MUST NOT revert unless due to integer overflow caused by an unreasonably large input. + */ + function claimableDepositRequest(uint256 requestId, address controller) + external + view + returns (uint256 claimableAssets); + + /** + * @dev Mints shares Vault shares to receiver by claiming the Request of the controller. + * + * - MUST emit the Deposit event. + * - controller MUST equal msg.sender unless the controller has approved the msg.sender as an operator. + */ + function deposit(uint256 assets, address receiver, address controller) external returns (uint256 shares); + + /** + * @dev Mints exactly shares Vault shares to receiver by claiming the Request of the controller. + * + * - MUST emit the Deposit event. + * - controller MUST equal msg.sender unless the controller has approved the msg.sender as an operator. + */ + function mint(uint256 shares, address receiver, address controller) external returns (uint256 assets); +} + +/// @dev Interface of the asynchronous deposit Vault interface of ERC7540, as defined in +/// https://eips.ethereum.org/EIPS/eip-7540 +interface IERC7540Redeem is IERC7540Operator { + event RedeemRequest( + address indexed controller, address indexed owner, uint256 indexed requestId, address sender, uint256 assets + ); + + /** + * @dev Assumes control of shares from sender into the Vault and submits a Request for asynchronous redeem. + * + * - MUST support a redeem Request flow where the control of shares is taken from sender directly + * where msg.sender has ERC-20 approval over the shares of owner. + * - MUST revert if all of shares cannot be requested for redeem. + * + * @param shares the amount of shares to be redeemed to transfer from owner + * @param controller the controller of the request who will be able to operate the request + * @param owner the source of the shares to be redeemed + * + * NOTE: most implementations will require pre-approval of the Vault with the Vault's share token. + */ + function requestRedeem(uint256 shares, address controller, address owner) external returns (uint256 requestId); + + /** + * @dev Returns the amount of requested shares in Pending state. + * + * - MUST NOT include any shares in Claimable state for redeem or withdraw. + * - MUST NOT show any variations depending on the caller. + * - MUST NOT revert unless due to integer overflow caused by an unreasonably large input. + */ + function pendingRedeemRequest(uint256 requestId, address controller) + external + view + returns (uint256 pendingShares); + + /** + * @dev Returns the amount of requested shares in Claimable state for the controller to redeem or withdraw. + * + * - MUST NOT include any shares in Pending state for redeem or withdraw. + * - MUST NOT show any variations depending on the caller. + * - MUST NOT revert unless due to integer overflow caused by an unreasonably large input. + */ + function claimableRedeemRequest(uint256 requestId, address controller) + external + view + returns (uint256 claimableShares); +} + +/// @dev Interface of the fully asynchronous Vault interface of ERC7540, as defined in +/// https://eips.ethereum.org/EIPS/eip-7540 +interface IERC7540 is IERC7540Deposit, IERC7540Redeem, IERC7575 {} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/interfaces/IERC7575.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/interfaces/IERC7575.sol new file mode 100644 index 0000000000..207e3e7fec --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/interfaces/IERC7575.sol @@ -0,0 +1,241 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +import {IERC165} from "./IERC165.sol"; + +/// @dev Interface of the ERC7575 "Multi-Asset ERC-4626 Vaults", as defined in +/// https://eips.ethereum.org/EIPS/eip-7575 +interface IERC7575 is IERC165 { + event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares); + event Withdraw( + address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares + ); + + /** + * @dev Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing. + * + * - MUST be an ERC-20 token contract. + * - MUST NOT revert. + */ + function asset() external view returns (address assetTokenAddress); + + /** + * @dev Returns the address of the share token + * + * - MUST be an ERC-20 token contract. + * - MUST NOT revert. + */ + function share() external view returns (address shareTokenAddress); + + /** + * @dev Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal + * scenario where all the conditions are met. + * + * - MUST NOT be inclusive of any fees that are charged against assets in the Vault. + * - MUST NOT show any variations depending on the caller. + * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. + * - MUST NOT revert. + * + * NOTE: This calculation MAY NOT reflect the ā€œper-userā€ price-per-share, and instead should reflect the + * ā€œaverage-user’sā€ price-per-share, meaning what the average user should expect to see when exchanging to and + * from. + */ + function convertToShares(uint256 assets) external view returns (uint256 shares); + + /** + * @dev Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal + * scenario where all the conditions are met. + * + * - MUST NOT be inclusive of any fees that are charged against assets in the Vault. + * - MUST NOT show any variations depending on the caller. + * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. + * - MUST NOT revert. + * + * NOTE: This calculation MAY NOT reflect the ā€œper-userā€ price-per-share, and instead should reflect the + * ā€œaverage-user’sā€ price-per-share, meaning what the average user should expect to see when exchanging to and + * from. + */ + function convertToAssets(uint256 shares) external view returns (uint256 assets); + + /** + * @dev Returns the total amount of the underlying asset that is ā€œmanagedā€ by Vault. + * + * - SHOULD include any compounding that occurs from yield. + * - MUST be inclusive of any fees that are charged against assets in the Vault. + * - MUST NOT revert. + */ + function totalAssets() external view returns (uint256 totalManagedAssets); + + /** + * @dev Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver, + * through a deposit call. + * + * - MUST return a limited value if receiver is subject to some deposit limit. + * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited. + * - MUST NOT revert. + */ + function maxDeposit(address receiver) external view returns (uint256 maxAssets); + + /** + * @dev Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given + * current on-chain conditions. + * + * - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit + * call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called + * in the same transaction. + * - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the + * deposit would be accepted, regardless if the user has enough tokens approved, etc. + * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. + * - MUST NOT revert. + * + * NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in + * share price or some other type of condition, meaning the depositor will lose assets by depositing. + */ + function previewDeposit(uint256 assets) external view returns (uint256 shares); + + /** + * @dev Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens. + * + * - MUST emit the Deposit event. + * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the + * deposit execution, and are accounted for during deposit. + * - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not + * approving enough underlying tokens to the Vault contract, etc). + * + * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. + */ + function deposit(uint256 assets, address receiver) external returns (uint256 shares); + + /** + * @dev Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call. + * - MUST return a limited value if receiver is subject to some mint limit. + * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted. + * - MUST NOT revert. + */ + function maxMint(address receiver) external view returns (uint256 maxShares); + + /** + * @dev Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given + * current on-chain conditions. + * + * - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call + * in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the + * same transaction. + * - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint + * would be accepted, regardless if the user has enough tokens approved, etc. + * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. + * - MUST NOT revert. + * + * NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in + * share price or some other type of condition, meaning the depositor will lose assets by minting. + */ + function previewMint(uint256 shares) external view returns (uint256 assets); + + /** + * @dev Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens. + * + * - MUST emit the Deposit event. + * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint + * execution, and are accounted for during mint. + * - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not + * approving enough underlying tokens to the Vault contract, etc). + * + * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. + */ + function mint(uint256 shares, address receiver) external returns (uint256 assets); + + /** + * @dev Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the + * Vault, through a withdraw call. + * + * - MUST return a limited value if owner is subject to some withdrawal limit or timelock. + * - MUST NOT revert. + */ + function maxWithdraw(address owner) external view returns (uint256 maxAssets); + + /** + * @dev Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block, + * given current on-chain conditions. + * + * - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw + * call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if + * called + * in the same transaction. + * - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though + * the withdrawal would be accepted, regardless if the user has enough shares, etc. + * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. + * - MUST NOT revert. + * + * NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in + * share price or some other type of condition, meaning the depositor will lose assets by depositing. + */ + function previewWithdraw(uint256 assets) external view returns (uint256 shares); + + /** + * @dev Burns shares from owner and sends exactly assets of underlying tokens to receiver. + * + * - MUST emit the Withdraw event. + * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the + * withdraw execution, and are accounted for during withdraw. + * - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner + * not having enough shares, etc). + * + * Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed. + * Those methods should be performed separately. + */ + function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares); + + /** + * @dev Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault, + * through a redeem call. + * + * - MUST return a limited value if owner is subject to some withdrawal limit or timelock. + * - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock. + * - MUST NOT revert. + */ + function maxRedeem(address owner) external view returns (uint256 maxShares); + + /** + * @dev Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block, + * given current on-chain conditions. + * + * - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call + * in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the + * same transaction. + * - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the + * redemption would be accepted, regardless if the user has enough shares, etc. + * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. + * - MUST NOT revert. + * + * NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in + * share price or some other type of condition, meaning the depositor will lose assets by redeeming. + */ + function previewRedeem(uint256 shares) external view returns (uint256 assets); + + /** + * @dev Burns exactly shares from owner and sends assets of underlying tokens to receiver. + * + * - MUST emit the Withdraw event. + * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the + * redeem execution, and are accounted for during redeem. + * - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner + * not having enough shares, etc). + * + * NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed. + * Those methods should be performed separately. + */ + function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets); +} + +/// @dev Interface of the ERC20 share token, as defined in +/// https://eips.ethereum.org/EIPS/eip-7575 +interface IERC7575Share is IERC165 { + event VaultUpdate(address indexed asset, address vault); + + /** + * @dev Returns the address of the Vault for the given asset. + * + * @param asset the ERC-20 token to deposit with into the Vault + */ + function vault(address asset) external view returns (address); +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/interfaces/IMulticall3.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/interfaces/IMulticall3.sol new file mode 100644 index 0000000000..0d031b71dc --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/interfaces/IMulticall3.sol @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +interface IMulticall3 { + struct Call { + address target; + bytes callData; + } + + struct Call3 { + address target; + bool allowFailure; + bytes callData; + } + + struct Call3Value { + address target; + bool allowFailure; + uint256 value; + bytes callData; + } + + struct Result { + bool success; + bytes returnData; + } + + function aggregate(Call[] calldata calls) + external + payable + returns (uint256 blockNumber, bytes[] memory returnData); + + function aggregate3(Call3[] calldata calls) external payable returns (Result[] memory returnData); + + function aggregate3Value(Call3Value[] calldata calls) external payable returns (Result[] memory returnData); + + function blockAndAggregate(Call[] calldata calls) + external + payable + returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData); + + function getBasefee() external view returns (uint256 basefee); + + function getBlockHash(uint256 blockNumber) external view returns (bytes32 blockHash); + + function getBlockNumber() external view returns (uint256 blockNumber); + + function getChainId() external view returns (uint256 chainid); + + function getCurrentBlockCoinbase() external view returns (address coinbase); + + function getCurrentBlockDifficulty() external view returns (uint256 difficulty); + + function getCurrentBlockGasLimit() external view returns (uint256 gaslimit); + + function getCurrentBlockTimestamp() external view returns (uint256 timestamp); + + function getEthBalance(address addr) external view returns (uint256 balance); + + function getLastBlockHash() external view returns (bytes32 blockHash); + + function tryAggregate(bool requireSuccess, Call[] calldata calls) + external + payable + returns (Result[] memory returnData); + + function tryBlockAndAggregate(bool requireSuccess, Call[] calldata calls) + external + payable + returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData); +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/safeconsole.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/safeconsole.sol new file mode 100644 index 0000000000..87c475a5b0 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/src/safeconsole.sol @@ -0,0 +1,13937 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +/// @author philogy +/// @dev Code generated automatically by script. +library safeconsole { + uint256 constant CONSOLE_ADDR = 0x000000000000000000000000000000000000000000636F6e736F6c652e6c6f67; + + // Credit to [0age](https://twitter.com/z0age/status/1654922202930888704) and [0xdapper](https://github.com/foundry-rs/forge-std/pull/374) + // for the view-to-pure log trick. + function _sendLogPayload(uint256 offset, uint256 size) private pure { + function(uint256, uint256) internal view fnIn = _sendLogPayloadView; + function(uint256, uint256) internal pure pureSendLogPayload; + /// @solidity memory-safe-assembly + assembly { + pureSendLogPayload := fnIn + } + pureSendLogPayload(offset, size); + } + + function _sendLogPayloadView(uint256 offset, uint256 size) private view { + /// @solidity memory-safe-assembly + assembly { + pop(staticcall(gas(), CONSOLE_ADDR, offset, size, 0x0, 0x0)) + } + } + + function _memcopy(uint256 fromOffset, uint256 toOffset, uint256 length) private pure { + function(uint256, uint256, uint256) internal view fnIn = _memcopyView; + function(uint256, uint256, uint256) internal pure pureMemcopy; + /// @solidity memory-safe-assembly + assembly { + pureMemcopy := fnIn + } + pureMemcopy(fromOffset, toOffset, length); + } + + function _memcopyView(uint256 fromOffset, uint256 toOffset, uint256 length) private view { + /// @solidity memory-safe-assembly + assembly { + pop(staticcall(gas(), 0x4, fromOffset, length, toOffset, length)) + } + } + + function logMemory(uint256 offset, uint256 length) internal pure { + if (offset >= 0x60) { + // Sufficient memory before slice to prepare call header. + bytes32 m0; + bytes32 m1; + bytes32 m2; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(sub(offset, 0x60)) + m1 := mload(sub(offset, 0x40)) + m2 := mload(sub(offset, 0x20)) + // Selector of `log(bytes)`. + mstore(sub(offset, 0x60), 0x0be77f56) + mstore(sub(offset, 0x40), 0x20) + mstore(sub(offset, 0x20), length) + } + _sendLogPayload(offset - 0x44, length + 0x44); + /// @solidity memory-safe-assembly + assembly { + mstore(sub(offset, 0x60), m0) + mstore(sub(offset, 0x40), m1) + mstore(sub(offset, 0x20), m2) + } + } else { + // Insufficient space, so copy slice forward, add header and reverse. + bytes32 m0; + bytes32 m1; + bytes32 m2; + uint256 endOffset = offset + length; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(add(endOffset, 0x00)) + m1 := mload(add(endOffset, 0x20)) + m2 := mload(add(endOffset, 0x40)) + } + _memcopy(offset, offset + 0x60, length); + /// @solidity memory-safe-assembly + assembly { + // Selector of `log(bytes)`. + mstore(add(offset, 0x00), 0x0be77f56) + mstore(add(offset, 0x20), 0x20) + mstore(add(offset, 0x40), length) + } + _sendLogPayload(offset + 0x1c, length + 0x44); + _memcopy(offset + 0x60, offset, length); + /// @solidity memory-safe-assembly + assembly { + mstore(add(endOffset, 0x00), m0) + mstore(add(endOffset, 0x20), m1) + mstore(add(endOffset, 0x40), m2) + } + } + } + + function log(address p0) internal pure { + bytes32 m0; + bytes32 m1; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + // Selector of `log(address)`. + mstore(0x00, 0x2c2ecbc2) + mstore(0x20, p0) + } + _sendLogPayload(0x1c, 0x24); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + } + } + + function log(bool p0) internal pure { + bytes32 m0; + bytes32 m1; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + // Selector of `log(bool)`. + mstore(0x00, 0x32458eed) + mstore(0x20, p0) + } + _sendLogPayload(0x1c, 0x24); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + } + } + + function log(uint256 p0) internal pure { + bytes32 m0; + bytes32 m1; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + // Selector of `log(uint256)`. + mstore(0x00, 0xf82c50f1) + mstore(0x20, p0) + } + _sendLogPayload(0x1c, 0x24); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + } + } + + function log(bytes32 p0) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(string)`. + mstore(0x00, 0x41304fac) + mstore(0x20, 0x20) + writeString(0x40, p0) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(address p0, address p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + // Selector of `log(address,address)`. + mstore(0x00, 0xdaf0d4aa) + mstore(0x20, p0) + mstore(0x40, p1) + } + _sendLogPayload(0x1c, 0x44); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + } + } + + function log(address p0, bool p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + // Selector of `log(address,bool)`. + mstore(0x00, 0x75b605d3) + mstore(0x20, p0) + mstore(0x40, p1) + } + _sendLogPayload(0x1c, 0x44); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + } + } + + function log(address p0, uint256 p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + // Selector of `log(address,uint256)`. + mstore(0x00, 0x8309e8a8) + mstore(0x20, p0) + mstore(0x40, p1) + } + _sendLogPayload(0x1c, 0x44); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + } + } + + function log(address p0, bytes32 p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,string)`. + mstore(0x00, 0x759f86bb) + mstore(0x20, p0) + mstore(0x40, 0x40) + writeString(0x60, p1) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, address p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + // Selector of `log(bool,address)`. + mstore(0x00, 0x853c4849) + mstore(0x20, p0) + mstore(0x40, p1) + } + _sendLogPayload(0x1c, 0x44); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + } + } + + function log(bool p0, bool p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + // Selector of `log(bool,bool)`. + mstore(0x00, 0x2a110e83) + mstore(0x20, p0) + mstore(0x40, p1) + } + _sendLogPayload(0x1c, 0x44); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + } + } + + function log(bool p0, uint256 p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + // Selector of `log(bool,uint256)`. + mstore(0x00, 0x399174d3) + mstore(0x20, p0) + mstore(0x40, p1) + } + _sendLogPayload(0x1c, 0x44); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + } + } + + function log(bool p0, bytes32 p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,string)`. + mstore(0x00, 0x8feac525) + mstore(0x20, p0) + mstore(0x40, 0x40) + writeString(0x60, p1) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, address p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + // Selector of `log(uint256,address)`. + mstore(0x00, 0x69276c86) + mstore(0x20, p0) + mstore(0x40, p1) + } + _sendLogPayload(0x1c, 0x44); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + } + } + + function log(uint256 p0, bool p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + // Selector of `log(uint256,bool)`. + mstore(0x00, 0x1c9d7eb3) + mstore(0x20, p0) + mstore(0x40, p1) + } + _sendLogPayload(0x1c, 0x44); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + } + } + + function log(uint256 p0, uint256 p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + // Selector of `log(uint256,uint256)`. + mstore(0x00, 0xf666715a) + mstore(0x20, p0) + mstore(0x40, p1) + } + _sendLogPayload(0x1c, 0x44); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + } + } + + function log(uint256 p0, bytes32 p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,string)`. + mstore(0x00, 0x643fd0df) + mstore(0x20, p0) + mstore(0x40, 0x40) + writeString(0x60, p1) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bytes32 p0, address p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(string,address)`. + mstore(0x00, 0x319af333) + mstore(0x20, 0x40) + mstore(0x40, p1) + writeString(0x60, p0) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bytes32 p0, bool p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(string,bool)`. + mstore(0x00, 0xc3b55635) + mstore(0x20, 0x40) + mstore(0x40, p1) + writeString(0x60, p0) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bytes32 p0, uint256 p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(string,uint256)`. + mstore(0x00, 0xb60e72cc) + mstore(0x20, 0x40) + mstore(0x40, p1) + writeString(0x60, p0) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bytes32 p0, bytes32 p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,string)`. + mstore(0x00, 0x4b5c4277) + mstore(0x20, 0x40) + mstore(0x40, 0x80) + writeString(0x60, p0) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, address p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(address,address,address)`. + mstore(0x00, 0x018c84c2) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(address p0, address p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(address,address,bool)`. + mstore(0x00, 0xf2a66286) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(address p0, address p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(address,address,uint256)`. + mstore(0x00, 0x17fe6185) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(address p0, address p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(address,address,string)`. + mstore(0x00, 0x007150be) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x60) + writeString(0x80, p2) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(address p0, bool p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(address,bool,address)`. + mstore(0x00, 0xf11699ed) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(address p0, bool p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(address,bool,bool)`. + mstore(0x00, 0xeb830c92) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(address p0, bool p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(address,bool,uint256)`. + mstore(0x00, 0x9c4f99fb) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(address p0, bool p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(address,bool,string)`. + mstore(0x00, 0x212255cc) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x60) + writeString(0x80, p2) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(address p0, uint256 p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(address,uint256,address)`. + mstore(0x00, 0x7bc0d848) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(address p0, uint256 p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(address,uint256,bool)`. + mstore(0x00, 0x678209a8) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(address p0, uint256 p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(address,uint256,uint256)`. + mstore(0x00, 0xb69bcaf6) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(address p0, uint256 p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(address,uint256,string)`. + mstore(0x00, 0xa1f2e8aa) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x60) + writeString(0x80, p2) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(address p0, bytes32 p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(address,string,address)`. + mstore(0x00, 0xf08744e8) + mstore(0x20, p0) + mstore(0x40, 0x60) + mstore(0x60, p2) + writeString(0x80, p1) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(address p0, bytes32 p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(address,string,bool)`. + mstore(0x00, 0xcf020fb1) + mstore(0x20, p0) + mstore(0x40, 0x60) + mstore(0x60, p2) + writeString(0x80, p1) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(address p0, bytes32 p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(address,string,uint256)`. + mstore(0x00, 0x67dd6ff1) + mstore(0x20, p0) + mstore(0x40, 0x60) + mstore(0x60, p2) + writeString(0x80, p1) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(address p0, bytes32 p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + // Selector of `log(address,string,string)`. + mstore(0x00, 0xfb772265) + mstore(0x20, p0) + mstore(0x40, 0x60) + mstore(0x60, 0xa0) + writeString(0x80, p1) + writeString(0xc0, p2) + } + _sendLogPayload(0x1c, 0xe4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + } + } + + function log(bool p0, address p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(bool,address,address)`. + mstore(0x00, 0xd2763667) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(bool p0, address p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(bool,address,bool)`. + mstore(0x00, 0x18c9c746) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(bool p0, address p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(bool,address,uint256)`. + mstore(0x00, 0x5f7b9afb) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(bool p0, address p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(bool,address,string)`. + mstore(0x00, 0xde9a9270) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x60) + writeString(0x80, p2) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bool p0, bool p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(bool,bool,address)`. + mstore(0x00, 0x1078f68d) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(bool p0, bool p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(bool,bool,bool)`. + mstore(0x00, 0x50709698) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(bool p0, bool p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(bool,bool,uint256)`. + mstore(0x00, 0x12f21602) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(bool p0, bool p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(bool,bool,string)`. + mstore(0x00, 0x2555fa46) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x60) + writeString(0x80, p2) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bool p0, uint256 p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(bool,uint256,address)`. + mstore(0x00, 0x088ef9d2) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(bool p0, uint256 p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(bool,uint256,bool)`. + mstore(0x00, 0xe8defba9) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(bool p0, uint256 p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(bool,uint256,uint256)`. + mstore(0x00, 0x37103367) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(bool p0, uint256 p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(bool,uint256,string)`. + mstore(0x00, 0xc3fc3970) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x60) + writeString(0x80, p2) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bool p0, bytes32 p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(bool,string,address)`. + mstore(0x00, 0x9591b953) + mstore(0x20, p0) + mstore(0x40, 0x60) + mstore(0x60, p2) + writeString(0x80, p1) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bool p0, bytes32 p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(bool,string,bool)`. + mstore(0x00, 0xdbb4c247) + mstore(0x20, p0) + mstore(0x40, 0x60) + mstore(0x60, p2) + writeString(0x80, p1) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bool p0, bytes32 p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(bool,string,uint256)`. + mstore(0x00, 0x1093ee11) + mstore(0x20, p0) + mstore(0x40, 0x60) + mstore(0x60, p2) + writeString(0x80, p1) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bool p0, bytes32 p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + // Selector of `log(bool,string,string)`. + mstore(0x00, 0xb076847f) + mstore(0x20, p0) + mstore(0x40, 0x60) + mstore(0x60, 0xa0) + writeString(0x80, p1) + writeString(0xc0, p2) + } + _sendLogPayload(0x1c, 0xe4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + } + } + + function log(uint256 p0, address p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(uint256,address,address)`. + mstore(0x00, 0xbcfd9be0) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(uint256 p0, address p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(uint256,address,bool)`. + mstore(0x00, 0x9b6ec042) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(uint256 p0, address p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(uint256,address,uint256)`. + mstore(0x00, 0x5a9b5ed5) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(uint256 p0, address p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(uint256,address,string)`. + mstore(0x00, 0x63cb41f9) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x60) + writeString(0x80, p2) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(uint256 p0, bool p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(uint256,bool,address)`. + mstore(0x00, 0x35085f7b) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(uint256 p0, bool p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(uint256,bool,bool)`. + mstore(0x00, 0x20718650) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(uint256 p0, bool p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(uint256,bool,uint256)`. + mstore(0x00, 0x20098014) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(uint256 p0, bool p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(uint256,bool,string)`. + mstore(0x00, 0x85775021) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x60) + writeString(0x80, p2) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(uint256 p0, uint256 p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(uint256,uint256,address)`. + mstore(0x00, 0x5c96b331) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(uint256 p0, uint256 p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(uint256,uint256,bool)`. + mstore(0x00, 0x4766da72) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(uint256 p0, uint256 p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(uint256,uint256,uint256)`. + mstore(0x00, 0xd1ed7a3c) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(uint256 p0, uint256 p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(uint256,uint256,string)`. + mstore(0x00, 0x71d04af2) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x60) + writeString(0x80, p2) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(uint256 p0, bytes32 p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(uint256,string,address)`. + mstore(0x00, 0x7afac959) + mstore(0x20, p0) + mstore(0x40, 0x60) + mstore(0x60, p2) + writeString(0x80, p1) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(uint256 p0, bytes32 p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(uint256,string,bool)`. + mstore(0x00, 0x4ceda75a) + mstore(0x20, p0) + mstore(0x40, 0x60) + mstore(0x60, p2) + writeString(0x80, p1) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(uint256 p0, bytes32 p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(uint256,string,uint256)`. + mstore(0x00, 0x37aa7d4c) + mstore(0x20, p0) + mstore(0x40, 0x60) + mstore(0x60, p2) + writeString(0x80, p1) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(uint256 p0, bytes32 p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + // Selector of `log(uint256,string,string)`. + mstore(0x00, 0xb115611f) + mstore(0x20, p0) + mstore(0x40, 0x60) + mstore(0x60, 0xa0) + writeString(0x80, p1) + writeString(0xc0, p2) + } + _sendLogPayload(0x1c, 0xe4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + } + } + + function log(bytes32 p0, address p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(string,address,address)`. + mstore(0x00, 0xfcec75e0) + mstore(0x20, 0x60) + mstore(0x40, p1) + mstore(0x60, p2) + writeString(0x80, p0) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bytes32 p0, address p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(string,address,bool)`. + mstore(0x00, 0xc91d5ed4) + mstore(0x20, 0x60) + mstore(0x40, p1) + mstore(0x60, p2) + writeString(0x80, p0) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bytes32 p0, address p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(string,address,uint256)`. + mstore(0x00, 0x0d26b925) + mstore(0x20, 0x60) + mstore(0x40, p1) + mstore(0x60, p2) + writeString(0x80, p0) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bytes32 p0, address p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + // Selector of `log(string,address,string)`. + mstore(0x00, 0xe0e9ad4f) + mstore(0x20, 0x60) + mstore(0x40, p1) + mstore(0x60, 0xa0) + writeString(0x80, p0) + writeString(0xc0, p2) + } + _sendLogPayload(0x1c, 0xe4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + } + } + + function log(bytes32 p0, bool p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(string,bool,address)`. + mstore(0x00, 0x932bbb38) + mstore(0x20, 0x60) + mstore(0x40, p1) + mstore(0x60, p2) + writeString(0x80, p0) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bytes32 p0, bool p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(string,bool,bool)`. + mstore(0x00, 0x850b7ad6) + mstore(0x20, 0x60) + mstore(0x40, p1) + mstore(0x60, p2) + writeString(0x80, p0) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bytes32 p0, bool p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(string,bool,uint256)`. + mstore(0x00, 0xc95958d6) + mstore(0x20, 0x60) + mstore(0x40, p1) + mstore(0x60, p2) + writeString(0x80, p0) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bytes32 p0, bool p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + // Selector of `log(string,bool,string)`. + mstore(0x00, 0xe298f47d) + mstore(0x20, 0x60) + mstore(0x40, p1) + mstore(0x60, 0xa0) + writeString(0x80, p0) + writeString(0xc0, p2) + } + _sendLogPayload(0x1c, 0xe4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + } + } + + function log(bytes32 p0, uint256 p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(string,uint256,address)`. + mstore(0x00, 0x1c7ec448) + mstore(0x20, 0x60) + mstore(0x40, p1) + mstore(0x60, p2) + writeString(0x80, p0) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bytes32 p0, uint256 p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(string,uint256,bool)`. + mstore(0x00, 0xca7733b1) + mstore(0x20, 0x60) + mstore(0x40, p1) + mstore(0x60, p2) + writeString(0x80, p0) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bytes32 p0, uint256 p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(string,uint256,uint256)`. + mstore(0x00, 0xca47c4eb) + mstore(0x20, 0x60) + mstore(0x40, p1) + mstore(0x60, p2) + writeString(0x80, p0) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bytes32 p0, uint256 p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + // Selector of `log(string,uint256,string)`. + mstore(0x00, 0x5970e089) + mstore(0x20, 0x60) + mstore(0x40, p1) + mstore(0x60, 0xa0) + writeString(0x80, p0) + writeString(0xc0, p2) + } + _sendLogPayload(0x1c, 0xe4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + } + } + + function log(bytes32 p0, bytes32 p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + // Selector of `log(string,string,address)`. + mstore(0x00, 0x95ed0195) + mstore(0x20, 0x60) + mstore(0x40, 0xa0) + mstore(0x60, p2) + writeString(0x80, p0) + writeString(0xc0, p1) + } + _sendLogPayload(0x1c, 0xe4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + } + } + + function log(bytes32 p0, bytes32 p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + // Selector of `log(string,string,bool)`. + mstore(0x00, 0xb0e0f9b5) + mstore(0x20, 0x60) + mstore(0x40, 0xa0) + mstore(0x60, p2) + writeString(0x80, p0) + writeString(0xc0, p1) + } + _sendLogPayload(0x1c, 0xe4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + } + } + + function log(bytes32 p0, bytes32 p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + // Selector of `log(string,string,uint256)`. + mstore(0x00, 0x5821efa1) + mstore(0x20, 0x60) + mstore(0x40, 0xa0) + mstore(0x60, p2) + writeString(0x80, p0) + writeString(0xc0, p1) + } + _sendLogPayload(0x1c, 0xe4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + } + } + + function log(bytes32 p0, bytes32 p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + // Selector of `log(string,string,string)`. + mstore(0x00, 0x2ced7cef) + mstore(0x20, 0x60) + mstore(0x40, 0xa0) + mstore(0x60, 0xe0) + writeString(0x80, p0) + writeString(0xc0, p1) + writeString(0x100, p2) + } + _sendLogPayload(0x1c, 0x124); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + } + } + + function log(address p0, address p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,address,address,address)`. + mstore(0x00, 0x665bf134) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, address p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,address,address,bool)`. + mstore(0x00, 0x0e378994) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, address p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,address,address,uint256)`. + mstore(0x00, 0x94250d77) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, address p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,address,address,string)`. + mstore(0x00, 0xf808da20) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, address p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,address,bool,address)`. + mstore(0x00, 0x9f1bc36e) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, address p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,address,bool,bool)`. + mstore(0x00, 0x2cd4134a) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, address p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,address,bool,uint256)`. + mstore(0x00, 0x3971e78c) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, address p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,address,bool,string)`. + mstore(0x00, 0xaa6540c8) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, address p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,address,uint256,address)`. + mstore(0x00, 0x8da6def5) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, address p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,address,uint256,bool)`. + mstore(0x00, 0x9b4254e2) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, address p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,address,uint256,uint256)`. + mstore(0x00, 0xbe553481) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, address p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,address,uint256,string)`. + mstore(0x00, 0xfdb4f990) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, address p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,address,string,address)`. + mstore(0x00, 0x8f736d16) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, address p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,address,string,bool)`. + mstore(0x00, 0x6f1a594e) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, address p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,address,string,uint256)`. + mstore(0x00, 0xef1cefe7) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, address p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(address,address,string,string)`. + mstore(0x00, 0x21bdaf25) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, 0xc0) + writeString(0xa0, p2) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(address p0, bool p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,bool,address,address)`. + mstore(0x00, 0x660375dd) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, bool p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,bool,address,bool)`. + mstore(0x00, 0xa6f50b0f) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, bool p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,bool,address,uint256)`. + mstore(0x00, 0xa75c59de) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, bool p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,bool,address,string)`. + mstore(0x00, 0x2dd778e6) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bool p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,bool,bool,address)`. + mstore(0x00, 0xcf394485) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, bool p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,bool,bool,bool)`. + mstore(0x00, 0xcac43479) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, bool p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,bool,bool,uint256)`. + mstore(0x00, 0x8c4e5de6) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, bool p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,bool,bool,string)`. + mstore(0x00, 0xdfc4a2e8) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bool p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,bool,uint256,address)`. + mstore(0x00, 0xccf790a1) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, bool p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,bool,uint256,bool)`. + mstore(0x00, 0xc4643e20) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, bool p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,bool,uint256,uint256)`. + mstore(0x00, 0x386ff5f4) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, bool p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,bool,uint256,string)`. + mstore(0x00, 0x0aa6cfad) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bool p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,bool,string,address)`. + mstore(0x00, 0x19fd4956) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bool p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,bool,string,bool)`. + mstore(0x00, 0x50ad461d) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bool p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,bool,string,uint256)`. + mstore(0x00, 0x80e6a20b) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bool p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(address,bool,string,string)`. + mstore(0x00, 0x475c5c33) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, 0xc0) + writeString(0xa0, p2) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(address p0, uint256 p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,uint256,address,address)`. + mstore(0x00, 0x478d1c62) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, uint256 p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,uint256,address,bool)`. + mstore(0x00, 0xa1bcc9b3) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, uint256 p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,uint256,address,uint256)`. + mstore(0x00, 0x100f650e) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, uint256 p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,uint256,address,string)`. + mstore(0x00, 0x1da986ea) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, uint256 p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,uint256,bool,address)`. + mstore(0x00, 0xa31bfdcc) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, uint256 p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,uint256,bool,bool)`. + mstore(0x00, 0x3bf5e537) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, uint256 p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,uint256,bool,uint256)`. + mstore(0x00, 0x22f6b999) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, uint256 p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,uint256,bool,string)`. + mstore(0x00, 0xc5ad85f9) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, uint256 p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,uint256,uint256,address)`. + mstore(0x00, 0x20e3984d) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, uint256 p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,uint256,uint256,bool)`. + mstore(0x00, 0x66f1bc67) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,uint256,uint256,uint256)`. + mstore(0x00, 0x34f0e636) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, uint256 p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,uint256,uint256,string)`. + mstore(0x00, 0x4a28c017) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, uint256 p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,uint256,string,address)`. + mstore(0x00, 0x5c430d47) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, uint256 p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,uint256,string,bool)`. + mstore(0x00, 0xcf18105c) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, uint256 p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,uint256,string,uint256)`. + mstore(0x00, 0xbf01f891) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, uint256 p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(address,uint256,string,string)`. + mstore(0x00, 0x88a8c406) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, 0xc0) + writeString(0xa0, p2) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(address p0, bytes32 p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,string,address,address)`. + mstore(0x00, 0x0d36fa20) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bytes32 p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,string,address,bool)`. + mstore(0x00, 0x0df12b76) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bytes32 p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,string,address,uint256)`. + mstore(0x00, 0x457fe3cf) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bytes32 p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(address,string,address,string)`. + mstore(0x00, 0xf7e36245) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p1) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(address p0, bytes32 p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,string,bool,address)`. + mstore(0x00, 0x205871c2) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bytes32 p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,string,bool,bool)`. + mstore(0x00, 0x5f1d5c9f) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bytes32 p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,string,bool,uint256)`. + mstore(0x00, 0x515e38b6) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bytes32 p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(address,string,bool,string)`. + mstore(0x00, 0xbc0b61fe) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p1) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(address p0, bytes32 p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,string,uint256,address)`. + mstore(0x00, 0x63183678) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bytes32 p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,string,uint256,bool)`. + mstore(0x00, 0x0ef7e050) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bytes32 p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,string,uint256,uint256)`. + mstore(0x00, 0x1dc8e1b8) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bytes32 p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(address,string,uint256,string)`. + mstore(0x00, 0x448830a8) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p1) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(address p0, bytes32 p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(address,string,string,address)`. + mstore(0x00, 0xa04e2f87) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p1) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(address p0, bytes32 p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(address,string,string,bool)`. + mstore(0x00, 0x35a5071f) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p1) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(address p0, bytes32 p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(address,string,string,uint256)`. + mstore(0x00, 0x159f8927) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p1) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(address p0, bytes32 p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + // Selector of `log(address,string,string,string)`. + mstore(0x00, 0x5d02c50b) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, 0xc0) + mstore(0x80, 0x100) + writeString(0xa0, p1) + writeString(0xe0, p2) + writeString(0x120, p3) + } + _sendLogPayload(0x1c, 0x144); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + } + } + + function log(bool p0, address p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,address,address,address)`. + mstore(0x00, 0x1d14d001) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, address p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,address,address,bool)`. + mstore(0x00, 0x46600be0) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, address p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,address,address,uint256)`. + mstore(0x00, 0x0c66d1be) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, address p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,address,address,string)`. + mstore(0x00, 0xd812a167) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, address p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,address,bool,address)`. + mstore(0x00, 0x1c41a336) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, address p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,address,bool,bool)`. + mstore(0x00, 0x6a9c478b) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, address p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,address,bool,uint256)`. + mstore(0x00, 0x07831502) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, address p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,address,bool,string)`. + mstore(0x00, 0x4a66cb34) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, address p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,address,uint256,address)`. + mstore(0x00, 0x136b05dd) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, address p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,address,uint256,bool)`. + mstore(0x00, 0xd6019f1c) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, address p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,address,uint256,uint256)`. + mstore(0x00, 0x7bf181a1) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, address p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,address,uint256,string)`. + mstore(0x00, 0x51f09ff8) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, address p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,address,string,address)`. + mstore(0x00, 0x6f7c603e) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, address p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,address,string,bool)`. + mstore(0x00, 0xe2bfd60b) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, address p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,address,string,uint256)`. + mstore(0x00, 0xc21f64c7) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, address p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(bool,address,string,string)`. + mstore(0x00, 0xa73c1db6) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, 0xc0) + writeString(0xa0, p2) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bool p0, bool p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,bool,address,address)`. + mstore(0x00, 0xf4880ea4) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, bool p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,bool,address,bool)`. + mstore(0x00, 0xc0a302d8) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, bool p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,bool,address,uint256)`. + mstore(0x00, 0x4c123d57) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, bool p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,bool,address,string)`. + mstore(0x00, 0xa0a47963) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bool p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,bool,bool,address)`. + mstore(0x00, 0x8c329b1a) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, bool p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,bool,bool,bool)`. + mstore(0x00, 0x3b2a5ce0) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, bool p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,bool,bool,uint256)`. + mstore(0x00, 0x6d7045c1) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, bool p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,bool,bool,string)`. + mstore(0x00, 0x2ae408d4) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bool p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,bool,uint256,address)`. + mstore(0x00, 0x54a7a9a0) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, bool p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,bool,uint256,bool)`. + mstore(0x00, 0x619e4d0e) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, bool p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,bool,uint256,uint256)`. + mstore(0x00, 0x0bb00eab) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, bool p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,bool,uint256,string)`. + mstore(0x00, 0x7dd4d0e0) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bool p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,bool,string,address)`. + mstore(0x00, 0xf9ad2b89) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bool p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,bool,string,bool)`. + mstore(0x00, 0xb857163a) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bool p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,bool,string,uint256)`. + mstore(0x00, 0xe3a9ca2f) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bool p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(bool,bool,string,string)`. + mstore(0x00, 0x6d1e8751) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, 0xc0) + writeString(0xa0, p2) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bool p0, uint256 p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,uint256,address,address)`. + mstore(0x00, 0x26f560a8) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, uint256 p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,uint256,address,bool)`. + mstore(0x00, 0xb4c314ff) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, uint256 p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,uint256,address,uint256)`. + mstore(0x00, 0x1537dc87) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, uint256 p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,uint256,address,string)`. + mstore(0x00, 0x1bb3b09a) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, uint256 p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,uint256,bool,address)`. + mstore(0x00, 0x9acd3616) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, uint256 p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,uint256,bool,bool)`. + mstore(0x00, 0xceb5f4d7) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, uint256 p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,uint256,bool,uint256)`. + mstore(0x00, 0x7f9bbca2) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, uint256 p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,uint256,bool,string)`. + mstore(0x00, 0x9143dbb1) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, uint256 p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,uint256,uint256,address)`. + mstore(0x00, 0x00dd87b9) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, uint256 p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,uint256,uint256,bool)`. + mstore(0x00, 0xbe984353) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,uint256,uint256,uint256)`. + mstore(0x00, 0x374bb4b2) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, uint256 p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,uint256,uint256,string)`. + mstore(0x00, 0x8e69fb5d) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, uint256 p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,uint256,string,address)`. + mstore(0x00, 0xfedd1fff) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, uint256 p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,uint256,string,bool)`. + mstore(0x00, 0xe5e70b2b) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, uint256 p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,uint256,string,uint256)`. + mstore(0x00, 0x6a1199e2) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, uint256 p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(bool,uint256,string,string)`. + mstore(0x00, 0xf5bc2249) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, 0xc0) + writeString(0xa0, p2) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bool p0, bytes32 p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,string,address,address)`. + mstore(0x00, 0x2b2b18dc) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bytes32 p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,string,address,bool)`. + mstore(0x00, 0x6dd434ca) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bytes32 p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,string,address,uint256)`. + mstore(0x00, 0xa5cada94) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bytes32 p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(bool,string,address,string)`. + mstore(0x00, 0x12d6c788) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p1) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bool p0, bytes32 p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,string,bool,address)`. + mstore(0x00, 0x538e06ab) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bytes32 p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,string,bool,bool)`. + mstore(0x00, 0xdc5e935b) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bytes32 p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,string,bool,uint256)`. + mstore(0x00, 0x1606a393) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bytes32 p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(bool,string,bool,string)`. + mstore(0x00, 0x483d0416) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p1) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bool p0, bytes32 p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,string,uint256,address)`. + mstore(0x00, 0x1596a1ce) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bytes32 p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,string,uint256,bool)`. + mstore(0x00, 0x6b0e5d53) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bytes32 p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,string,uint256,uint256)`. + mstore(0x00, 0x28863fcb) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bytes32 p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(bool,string,uint256,string)`. + mstore(0x00, 0x1ad96de6) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p1) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bool p0, bytes32 p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(bool,string,string,address)`. + mstore(0x00, 0x97d394d8) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p1) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bool p0, bytes32 p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(bool,string,string,bool)`. + mstore(0x00, 0x1e4b87e5) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p1) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bool p0, bytes32 p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(bool,string,string,uint256)`. + mstore(0x00, 0x7be0c3eb) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p1) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bool p0, bytes32 p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + // Selector of `log(bool,string,string,string)`. + mstore(0x00, 0x1762e32a) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, 0xc0) + mstore(0x80, 0x100) + writeString(0xa0, p1) + writeString(0xe0, p2) + writeString(0x120, p3) + } + _sendLogPayload(0x1c, 0x144); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + } + } + + function log(uint256 p0, address p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,address,address,address)`. + mstore(0x00, 0x2488b414) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, address p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,address,address,bool)`. + mstore(0x00, 0x091ffaf5) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, address p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,address,address,uint256)`. + mstore(0x00, 0x736efbb6) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, address p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,address,address,string)`. + mstore(0x00, 0x031c6f73) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, address p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,address,bool,address)`. + mstore(0x00, 0xef72c513) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, address p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,address,bool,bool)`. + mstore(0x00, 0xe351140f) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, address p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,address,bool,uint256)`. + mstore(0x00, 0x5abd992a) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, address p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,address,bool,string)`. + mstore(0x00, 0x90fb06aa) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, address p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,address,uint256,address)`. + mstore(0x00, 0x15c127b5) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, address p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,address,uint256,bool)`. + mstore(0x00, 0x5f743a7c) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,address,uint256,uint256)`. + mstore(0x00, 0x0c9cd9c1) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, address p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,address,uint256,string)`. + mstore(0x00, 0xddb06521) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, address p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,address,string,address)`. + mstore(0x00, 0x9cba8fff) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, address p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,address,string,bool)`. + mstore(0x00, 0xcc32ab07) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, address p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,address,string,uint256)`. + mstore(0x00, 0x46826b5d) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, address p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(uint256,address,string,string)`. + mstore(0x00, 0x3e128ca3) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, 0xc0) + writeString(0xa0, p2) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(uint256 p0, bool p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,bool,address,address)`. + mstore(0x00, 0xa1ef4cbb) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, bool p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,bool,address,bool)`. + mstore(0x00, 0x454d54a5) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, bool p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,bool,address,uint256)`. + mstore(0x00, 0x078287f5) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, bool p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,bool,address,string)`. + mstore(0x00, 0xade052c7) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bool p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,bool,bool,address)`. + mstore(0x00, 0x69640b59) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, bool p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,bool,bool,bool)`. + mstore(0x00, 0xb6f577a1) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, bool p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,bool,bool,uint256)`. + mstore(0x00, 0x7464ce23) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, bool p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,bool,bool,string)`. + mstore(0x00, 0xdddb9561) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bool p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,bool,uint256,address)`. + mstore(0x00, 0x88cb6041) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, bool p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,bool,uint256,bool)`. + mstore(0x00, 0x91a02e2a) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,bool,uint256,uint256)`. + mstore(0x00, 0xc6acc7a8) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, bool p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,bool,uint256,string)`. + mstore(0x00, 0xde03e774) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bool p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,bool,string,address)`. + mstore(0x00, 0xef529018) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bool p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,bool,string,bool)`. + mstore(0x00, 0xeb928d7f) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bool p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,bool,string,uint256)`. + mstore(0x00, 0x2c1d0746) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bool p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(uint256,bool,string,string)`. + mstore(0x00, 0x68c8b8bd) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, 0xc0) + writeString(0xa0, p2) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(uint256 p0, uint256 p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,uint256,address,address)`. + mstore(0x00, 0x56a5d1b1) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, uint256 p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,uint256,address,bool)`. + mstore(0x00, 0x15cac476) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,uint256,address,uint256)`. + mstore(0x00, 0x88f6e4b2) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, uint256 p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,uint256,address,string)`. + mstore(0x00, 0x6cde40b8) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, uint256 p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,uint256,bool,address)`. + mstore(0x00, 0x9a816a83) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, uint256 p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,uint256,bool,bool)`. + mstore(0x00, 0xab085ae6) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,uint256,bool,uint256)`. + mstore(0x00, 0xeb7f6fd2) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, uint256 p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,uint256,bool,string)`. + mstore(0x00, 0xa5b4fc99) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,uint256,uint256,address)`. + mstore(0x00, 0xfa8185af) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,uint256,uint256,bool)`. + mstore(0x00, 0xc598d185) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,uint256,uint256,uint256)`. + mstore(0x00, 0x193fb800) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, uint256 p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,uint256,uint256,string)`. + mstore(0x00, 0x59cfcbe3) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, uint256 p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,uint256,string,address)`. + mstore(0x00, 0x42d21db7) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, uint256 p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,uint256,string,bool)`. + mstore(0x00, 0x7af6ab25) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, uint256 p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,uint256,string,uint256)`. + mstore(0x00, 0x5da297eb) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, uint256 p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(uint256,uint256,string,string)`. + mstore(0x00, 0x27d8afd2) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, 0xc0) + writeString(0xa0, p2) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(uint256 p0, bytes32 p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,string,address,address)`. + mstore(0x00, 0x6168ed61) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bytes32 p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,string,address,bool)`. + mstore(0x00, 0x90c30a56) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bytes32 p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,string,address,uint256)`. + mstore(0x00, 0xe8d3018d) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bytes32 p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(uint256,string,address,string)`. + mstore(0x00, 0x9c3adfa1) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p1) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(uint256 p0, bytes32 p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,string,bool,address)`. + mstore(0x00, 0xae2ec581) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bytes32 p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,string,bool,bool)`. + mstore(0x00, 0xba535d9c) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bytes32 p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,string,bool,uint256)`. + mstore(0x00, 0xcf009880) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bytes32 p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(uint256,string,bool,string)`. + mstore(0x00, 0xd2d423cd) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p1) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(uint256 p0, bytes32 p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,string,uint256,address)`. + mstore(0x00, 0x3b2279b4) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bytes32 p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,string,uint256,bool)`. + mstore(0x00, 0x691a8f74) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bytes32 p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,string,uint256,uint256)`. + mstore(0x00, 0x82c25b74) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bytes32 p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(uint256,string,uint256,string)`. + mstore(0x00, 0xb7b914ca) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p1) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(uint256 p0, bytes32 p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(uint256,string,string,address)`. + mstore(0x00, 0xd583c602) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p1) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(uint256 p0, bytes32 p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(uint256,string,string,bool)`. + mstore(0x00, 0xb3a6b6bd) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p1) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(uint256 p0, bytes32 p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(uint256,string,string,uint256)`. + mstore(0x00, 0xb028c9bd) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p1) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(uint256 p0, bytes32 p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + // Selector of `log(uint256,string,string,string)`. + mstore(0x00, 0x21ad0683) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, 0xc0) + mstore(0x80, 0x100) + writeString(0xa0, p1) + writeString(0xe0, p2) + writeString(0x120, p3) + } + _sendLogPayload(0x1c, 0x144); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + } + } + + function log(bytes32 p0, address p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,address,address,address)`. + mstore(0x00, 0xed8f28f6) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, address p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,address,address,bool)`. + mstore(0x00, 0xb59dbd60) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, address p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,address,address,uint256)`. + mstore(0x00, 0x8ef3f399) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, address p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,address,address,string)`. + mstore(0x00, 0x800a1c67) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p0) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, address p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,address,bool,address)`. + mstore(0x00, 0x223603bd) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, address p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,address,bool,bool)`. + mstore(0x00, 0x79884c2b) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, address p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,address,bool,uint256)`. + mstore(0x00, 0x3e9f866a) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, address p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,address,bool,string)`. + mstore(0x00, 0x0454c079) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p0) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, address p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,address,uint256,address)`. + mstore(0x00, 0x63fb8bc5) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, address p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,address,uint256,bool)`. + mstore(0x00, 0xfc4845f0) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, address p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,address,uint256,uint256)`. + mstore(0x00, 0xf8f51b1e) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, address p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,address,uint256,string)`. + mstore(0x00, 0x5a477632) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p0) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, address p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,address,string,address)`. + mstore(0x00, 0xaabc9a31) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, address p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,address,string,bool)`. + mstore(0x00, 0x5f15d28c) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, address p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,address,string,uint256)`. + mstore(0x00, 0x91d1112e) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, address p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + // Selector of `log(string,address,string,string)`. + mstore(0x00, 0x245986f2) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, 0xc0) + mstore(0x80, 0x100) + writeString(0xa0, p0) + writeString(0xe0, p2) + writeString(0x120, p3) + } + _sendLogPayload(0x1c, 0x144); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + } + } + + function log(bytes32 p0, bool p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,bool,address,address)`. + mstore(0x00, 0x33e9dd1d) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, bool p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,bool,address,bool)`. + mstore(0x00, 0x958c28c6) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, bool p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,bool,address,uint256)`. + mstore(0x00, 0x5d08bb05) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, bool p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,bool,address,string)`. + mstore(0x00, 0x2d8e33a4) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p0) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bool p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,bool,bool,address)`. + mstore(0x00, 0x7190a529) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, bool p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,bool,bool,bool)`. + mstore(0x00, 0x895af8c5) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, bool p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,bool,bool,uint256)`. + mstore(0x00, 0x8e3f78a9) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, bool p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,bool,bool,string)`. + mstore(0x00, 0x9d22d5dd) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p0) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bool p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,bool,uint256,address)`. + mstore(0x00, 0x935e09bf) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, bool p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,bool,uint256,bool)`. + mstore(0x00, 0x8af7cf8a) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, bool p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,bool,uint256,uint256)`. + mstore(0x00, 0x64b5bb67) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, bool p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,bool,uint256,string)`. + mstore(0x00, 0x742d6ee7) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p0) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bool p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,bool,string,address)`. + mstore(0x00, 0xe0625b29) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bool p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,bool,string,bool)`. + mstore(0x00, 0x3f8a701d) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bool p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,bool,string,uint256)`. + mstore(0x00, 0x24f91465) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bool p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + // Selector of `log(string,bool,string,string)`. + mstore(0x00, 0xa826caeb) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, 0xc0) + mstore(0x80, 0x100) + writeString(0xa0, p0) + writeString(0xe0, p2) + writeString(0x120, p3) + } + _sendLogPayload(0x1c, 0x144); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + } + } + + function log(bytes32 p0, uint256 p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,uint256,address,address)`. + mstore(0x00, 0x5ea2b7ae) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, uint256 p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,uint256,address,bool)`. + mstore(0x00, 0x82112a42) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, uint256 p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,uint256,address,uint256)`. + mstore(0x00, 0x4f04fdc6) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, uint256 p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,uint256,address,string)`. + mstore(0x00, 0x9ffb2f93) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p0) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, uint256 p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,uint256,bool,address)`. + mstore(0x00, 0xe0e95b98) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, uint256 p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,uint256,bool,bool)`. + mstore(0x00, 0x354c36d6) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, uint256 p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,uint256,bool,uint256)`. + mstore(0x00, 0xe41b6f6f) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, uint256 p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,uint256,bool,string)`. + mstore(0x00, 0xabf73a98) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p0) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, uint256 p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,uint256,uint256,address)`. + mstore(0x00, 0xe21de278) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, uint256 p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,uint256,uint256,bool)`. + mstore(0x00, 0x7626db92) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, uint256 p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,uint256,uint256,uint256)`. + mstore(0x00, 0xa7a87853) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, uint256 p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,uint256,uint256,string)`. + mstore(0x00, 0x854b3496) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p0) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, uint256 p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,uint256,string,address)`. + mstore(0x00, 0x7c4632a4) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, uint256 p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,uint256,string,bool)`. + mstore(0x00, 0x7d24491d) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, uint256 p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,uint256,string,uint256)`. + mstore(0x00, 0xc67ea9d1) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, uint256 p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + // Selector of `log(string,uint256,string,string)`. + mstore(0x00, 0x5ab84e1f) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, 0xc0) + mstore(0x80, 0x100) + writeString(0xa0, p0) + writeString(0xe0, p2) + writeString(0x120, p3) + } + _sendLogPayload(0x1c, 0x144); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + } + } + + function log(bytes32 p0, bytes32 p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,string,address,address)`. + mstore(0x00, 0x439c7bef) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p1) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bytes32 p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,string,address,bool)`. + mstore(0x00, 0x5ccd4e37) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p1) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bytes32 p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,string,address,uint256)`. + mstore(0x00, 0x7cc3c607) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p1) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bytes32 p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + // Selector of `log(string,string,address,string)`. + mstore(0x00, 0xeb1bff80) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, p2) + mstore(0x80, 0x100) + writeString(0xa0, p0) + writeString(0xe0, p1) + writeString(0x120, p3) + } + _sendLogPayload(0x1c, 0x144); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + } + } + + function log(bytes32 p0, bytes32 p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,string,bool,address)`. + mstore(0x00, 0xc371c7db) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p1) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bytes32 p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,string,bool,bool)`. + mstore(0x00, 0x40785869) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p1) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bytes32 p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,string,bool,uint256)`. + mstore(0x00, 0xd6aefad2) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p1) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bytes32 p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + // Selector of `log(string,string,bool,string)`. + mstore(0x00, 0x5e84b0ea) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, p2) + mstore(0x80, 0x100) + writeString(0xa0, p0) + writeString(0xe0, p1) + writeString(0x120, p3) + } + _sendLogPayload(0x1c, 0x144); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + } + } + + function log(bytes32 p0, bytes32 p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,string,uint256,address)`. + mstore(0x00, 0x1023f7b2) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p1) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bytes32 p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,string,uint256,bool)`. + mstore(0x00, 0xc3a8a654) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p1) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bytes32 p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,string,uint256,uint256)`. + mstore(0x00, 0xf45d7d2c) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p1) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bytes32 p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + // Selector of `log(string,string,uint256,string)`. + mstore(0x00, 0x5d1a971a) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, p2) + mstore(0x80, 0x100) + writeString(0xa0, p0) + writeString(0xe0, p1) + writeString(0x120, p3) + } + _sendLogPayload(0x1c, 0x144); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + } + } + + function log(bytes32 p0, bytes32 p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + // Selector of `log(string,string,string,address)`. + mstore(0x00, 0x6d572f44) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, 0x100) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p1) + writeString(0x120, p2) + } + _sendLogPayload(0x1c, 0x144); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + } + } + + function log(bytes32 p0, bytes32 p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + // Selector of `log(string,string,string,bool)`. + mstore(0x00, 0x2c1754ed) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, 0x100) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p1) + writeString(0x120, p2) + } + _sendLogPayload(0x1c, 0x144); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + } + } + + function log(bytes32 p0, bytes32 p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + // Selector of `log(string,string,string,uint256)`. + mstore(0x00, 0x8eafb02b) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, 0x100) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p1) + writeString(0x120, p2) + } + _sendLogPayload(0x1c, 0x144); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + } + } + + function log(bytes32 p0, bytes32 p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + bytes32 m11; + bytes32 m12; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + m11 := mload(0x160) + m12 := mload(0x180) + // Selector of `log(string,string,string,string)`. + mstore(0x00, 0xde68f20a) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, 0x100) + mstore(0x80, 0x140) + writeString(0xa0, p0) + writeString(0xe0, p1) + writeString(0x120, p2) + writeString(0x160, p3) + } + _sendLogPayload(0x1c, 0x184); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + mstore(0x160, m11) + mstore(0x180, m12) + } + } +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/CommonBase.t.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/CommonBase.t.sol new file mode 100644 index 0000000000..4a6eb34fd8 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/CommonBase.t.sol @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import {CommonBase} from "../src/Base.sol"; +import {StdConstants} from "../src/StdConstants.sol"; +import {Test} from "../src/Test.sol"; + +contract CommonBaseTest is Test { + function testVmAddressValue() public pure { + assertEq(VM_ADDRESS, address(StdConstants.VM)); + } + + function testConsoleValue() public pure { + assertEq(CONSOLE, StdConstants.CONSOLE); + } + + function testCreate2FactoryValue() public pure { + assertEq(CREATE2_FACTORY, StdConstants.CREATE2_FACTORY); + } + + function testDefaultSenderValue() public pure { + assertEq(DEFAULT_SENDER, StdConstants.DEFAULT_SENDER); + } + + function testDefaultTestContractValue() public pure { + assertEq(DEFAULT_TEST_CONTRACT, StdConstants.DEFAULT_TEST_CONTRACT); + } + + function testMulticall3AddressValue() public pure { + assertEq(MULTICALL3_ADDRESS, address(StdConstants.MULTICALL3_ADDRESS)); + } + + function testSecp256k1OrderValue() public pure { + assertEq(SECP256K1_ORDER, StdConstants.SECP256K1_ORDER); + } + + function testUint256MaxValue() public pure { + assertEq(UINT256_MAX, type(uint256).max); + } + + function testVmValue() public pure { + assertEq(address(vm), address(StdConstants.VM)); + } +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/Config.t.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/Config.t.sol new file mode 100644 index 0000000000..8e2342cade --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/Config.t.sol @@ -0,0 +1,352 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +import {Test} from "../src/Test.sol"; +import {Config} from "../src/Config.sol"; +import {StdConfig} from "../src/StdConfig.sol"; + +contract ConfigTest is Test, Config { + function setUp() public { + vm.setEnv("MAINNET_RPC", "https://eth.llamarpc.com"); + vm.setEnv("WETH_MAINNET", "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"); + vm.setEnv("OPTIMISM_RPC", "https://mainnet.optimism.io"); + vm.setEnv("WETH_OPTIMISM", "0x4200000000000000000000000000000000000006"); + } + + function test_loadConfig() public { + // Deploy the config contract with the test fixture. + _loadConfig("./test/fixtures/config.toml", false); + + // -- MAINNET -------------------------------------------------------------- + + // Read and assert RPC URL for Mainnet (chain ID 1) + assertEq(config.getRpcUrl(1), "https://eth.llamarpc.com"); + + // Read and assert boolean values + assertTrue(config.get(1, "is_live").toBool()); + bool[] memory bool_array = config.get(1, "bool_array").toBoolArray(); + assertTrue(bool_array[0]); + assertFalse(bool_array[1]); + + // Read and assert address values + assertEq(config.get(1, "weth").toAddress(), 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2); + address[] memory address_array = config.get(1, "deps").toAddressArray(); + assertEq(address_array[0], 0x0000000000000000000000000000000000000000); + assertEq(address_array[1], 0x1111111111111111111111111111111111111111); + + // Read and assert bytes32 values + assertEq(config.get(1, "word").toBytes32(), bytes32(uint256(1234))); + bytes32[] memory bytes32_array = config.get(1, "word_array").toBytes32Array(); + assertEq(bytes32_array[0], bytes32(uint256(5678))); + assertEq(bytes32_array[1], bytes32(uint256(9999))); + + // Read and assert uint values + assertEq(config.get(1, "number").toUint256(), 1234); + uint256[] memory uint_array = config.get(1, "number_array").toUint256Array(); + assertEq(uint_array[0], 5678); + assertEq(uint_array[1], 9999); + + // Read and assert int values + assertEq(config.get(1, "signed_number").toInt256(), -1234); + int256[] memory int_array = config.get(1, "signed_number_array").toInt256Array(); + assertEq(int_array[0], -5678); + assertEq(int_array[1], 9999); + + // Read and assert bytes values + assertEq(config.get(1, "b").toBytes(), hex"abcd"); + bytes[] memory bytes_array = config.get(1, "b_array").toBytesArray(); + assertEq(bytes_array[0], hex"dead"); + assertEq(bytes_array[1], hex"beef"); + + // Read and assert string values + assertEq(config.get(1, "str").toString(), "foo"); + string[] memory string_array = config.get(1, "str_array").toStringArray(); + assertEq(string_array[0], "bar"); + assertEq(string_array[1], "baz"); + + // -- OPTIMISM ------------------------------------------------------------ + + // Read and assert RPC URL for Optimism (chain ID 10) + assertEq(config.getRpcUrl(10), "https://mainnet.optimism.io"); + + // Read and assert boolean values + assertFalse(config.get(10, "is_live").toBool()); + bool_array = config.get(10, "bool_array").toBoolArray(); + assertFalse(bool_array[0]); + assertTrue(bool_array[1]); + + // Read and assert address values + assertEq(config.get(10, "weth").toAddress(), 0x4200000000000000000000000000000000000006); + address_array = config.get(10, "deps").toAddressArray(); + assertEq(address_array[0], 0x2222222222222222222222222222222222222222); + assertEq(address_array[1], 0x3333333333333333333333333333333333333333); + + // Read and assert bytes32 values + assertEq(config.get(10, "word").toBytes32(), bytes32(uint256(9999))); + bytes32_array = config.get(10, "word_array").toBytes32Array(); + assertEq(bytes32_array[0], bytes32(uint256(1234))); + assertEq(bytes32_array[1], bytes32(uint256(5678))); + + // Read and assert uint values + assertEq(config.get(10, "number").toUint256(), 9999); + uint_array = config.get(10, "number_array").toUint256Array(); + assertEq(uint_array[0], 1234); + assertEq(uint_array[1], 5678); + + // Read and assert int values + assertEq(config.get(10, "signed_number").toInt256(), 9999); + int_array = config.get(10, "signed_number_array").toInt256Array(); + assertEq(int_array[0], -1234); + assertEq(int_array[1], -5678); + + // Read and assert bytes values + assertEq(config.get(10, "b").toBytes(), hex"dcba"); + bytes_array = config.get(10, "b_array").toBytesArray(); + assertEq(bytes_array[0], hex"c0ffee"); + assertEq(bytes_array[1], hex"babe"); + + // Read and assert string values + assertEq(config.get(10, "str").toString(), "alice"); + string_array = config.get(10, "str_array").toStringArray(); + assertEq(string_array[0], "bob"); + assertEq(string_array[1], "charlie"); + } + + function test_loadConfigAndForks() public { + _loadConfigAndForks("./test/fixtures/config.toml", false); + + // assert that the map of chain id and fork ids is created and that the chain ids actually match + assertEq(forkOf[1], 0); + vm.selectFork(forkOf[1]); + assertEq(vm.getChainId(), 1); + + assertEq(forkOf[10], 1); + vm.selectFork(forkOf[10]); + assertEq(vm.getChainId(), 10); + } + + function test_writeConfig() public { + // Create a temporary copy of the config file to avoid modifying the original. + string memory originalConfig = "./test/fixtures/config.toml"; + string memory testConfig = "./test/fixtures/config.t.toml"; + vm.copyFile(originalConfig, testConfig); + + // Deploy the config contract with the temporary fixture. + _loadConfig(testConfig, false); + + // Enable writing to file bypassing the context check. + vm.store(address(config), bytes32(uint256(5)), bytes32(uint256(1))); + + { + // Update a single boolean value and verify the change. + config.set(1, "is_live", false); + + assertFalse(config.get(1, "is_live").toBool()); + + string memory content = vm.readFile(testConfig); + assertFalse(vm.parseTomlBool(content, "$.mainnet.bool.is_live")); + + // Update a single address value and verify the change. + address new_addr = 0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF; + config.set(1, "weth", new_addr); + + assertEq(config.get(1, "weth").toAddress(), new_addr); + + content = vm.readFile(testConfig); + assertEq(vm.parseTomlAddress(content, "$.mainnet.address.weth"), new_addr); + + // Update a uint array and verify the change. + uint256[] memory new_numbers = new uint256[](3); + new_numbers[0] = 1; + new_numbers[1] = 2; + new_numbers[2] = 3; + config.set(10, "number_array", new_numbers); + + uint256[] memory updated_numbers_mem = config.get(10, "number_array").toUint256Array(); + assertEq(updated_numbers_mem.length, 3); + assertEq(updated_numbers_mem[0], 1); + assertEq(updated_numbers_mem[1], 2); + assertEq(updated_numbers_mem[2], 3); + + content = vm.readFile(testConfig); + uint256[] memory updated_numbers_disk = vm.parseTomlUintArray(content, "$.optimism.uint.number_array"); + assertEq(updated_numbers_disk.length, 3); + assertEq(updated_numbers_disk[0], 1); + assertEq(updated_numbers_disk[1], 2); + assertEq(updated_numbers_disk[2], 3); + + // Update a string array and verify the change. + string[] memory new_strings = new string[](2); + new_strings[0] = "hello"; + new_strings[1] = "world"; + config.set(1, "str_array", new_strings); + + string[] memory updated_strings_mem = config.get(1, "str_array").toStringArray(); + assertEq(updated_strings_mem.length, 2); + assertEq(updated_strings_mem[0], "hello"); + assertEq(updated_strings_mem[1], "world"); + + content = vm.readFile(testConfig); + string[] memory updated_strings_disk = vm.parseTomlStringArray(content, "$.mainnet.string.str_array"); + assertEq(updated_strings_disk.length, 2); + assertEq(updated_strings_disk[0], "hello"); + assertEq(updated_strings_disk[1], "world"); + + // Create a new uint variable and verify the change. + config.set(1, "new_uint", uint256(42)); + + assertEq(config.get(1, "new_uint").toUint256(), 42); + + content = vm.readFile(testConfig); + assertEq(vm.parseTomlUint(content, "$.mainnet.uint.new_uint"), 42); + + // Create a new int variable and verify the change. + config.set(1, "new_int", int256(-42)); + + assertEq(config.get(1, "new_int").toInt256(), -42); + + content = vm.readFile(testConfig); + assertEq(vm.parseTomlInt(content, "$.mainnet.int.new_int"), -42); + + // Create a new int array and verify the change. + int256[] memory new_ints = new int256[](2); + new_ints[0] = -100; + new_ints[1] = 200; + config.set(10, "new_ints", new_ints); + + int256[] memory updated_ints_mem = config.get(10, "new_ints").toInt256Array(); + assertEq(updated_ints_mem.length, 2); + assertEq(updated_ints_mem[0], -100); + assertEq(updated_ints_mem[1], 200); + + content = vm.readFile(testConfig); + int256[] memory updated_ints_disk = vm.parseTomlIntArray(content, "$.optimism.int.new_ints"); + assertEq(updated_ints_disk.length, 2); + assertEq(updated_ints_disk[0], -100); + assertEq(updated_ints_disk[1], 200); + + // Create a new bytes32 array and verify the change. + bytes32[] memory new_words = new bytes32[](2); + new_words[0] = bytes32(uint256(0xDEAD)); + new_words[1] = bytes32(uint256(0xBEEF)); + config.set(10, "new_words", new_words); + + bytes32[] memory updated_words_mem = config.get(10, "new_words").toBytes32Array(); + assertEq(updated_words_mem.length, 2); + assertEq(updated_words_mem[0], new_words[0]); + assertEq(updated_words_mem[1], new_words[1]); + + content = vm.readFile(testConfig); + bytes32[] memory updated_words_disk = vm.parseTomlBytes32Array(content, "$.optimism.bytes32.new_words"); + assertEq(updated_words_disk.length, 2); + assertEq(vm.toString(updated_words_disk[0]), vm.toString(new_words[0])); + assertEq(vm.toString(updated_words_disk[1]), vm.toString(new_words[1])); + } + + // Clean up the temporary file. + vm.removeFile(testConfig); + } + + function test_writeUpdatesBackToFile() public { + // Create a temporary copy of the config file to avoid modifying the original. + string memory originalConfig = "./test/fixtures/config.toml"; + string memory testConfig = "./test/fixtures/write_config.t.toml"; + vm.copyFile(originalConfig, testConfig); + + // Deploy the config contract with `writeToFile = false` (disabled). + _loadConfig(testConfig, false); + + // Update a single boolean value and verify the file is NOT changed. + config.set(1, "is_live", false); + string memory content = vm.readFile(testConfig); + assertTrue(vm.parseTomlBool(content, "$.mainnet.bool.is_live"), "File should not be updated yet"); + + // Enable writing to file bypassing the context check. + vm.store(address(config), bytes32(uint256(5)), bytes32(uint256(1))); + + // Update the value again and verify the file IS changed. + config.set(1, "is_live", false); + content = vm.readFile(testConfig); + assertFalse(vm.parseTomlBool(content, "$.mainnet.bool.is_live"), "File should be updated now"); + + // Disable writing to file. + config.writeUpdatesBackToFile(false); + + // Update the value again and verify the file is NOT changed. + config.set(1, "is_live", true); + content = vm.readFile(testConfig); + assertFalse(vm.parseTomlBool(content, "$.mainnet.bool.is_live"), "File should not be updated again"); + + // Clean up the temporary file. + vm.removeFile(testConfig); + } + + function testRevert_WriteToFileInForbiddenCtxt() public { + // Cannot initialize enabling writing to file unless we are in SCRIPT mode. + vm.expectRevert(StdConfig.WriteToFileInForbiddenCtxt.selector); + _loadConfig("./test/fixtures/config.toml", true); + + // Initialize with `writeToFile = false`. + _loadConfig("./test/fixtures/config.toml", false); + + // Cannot enable writing to file unless we are in SCRIPT mode. + vm.expectRevert(StdConfig.WriteToFileInForbiddenCtxt.selector); + config.writeUpdatesBackToFile(true); + } + + function testRevert_InvalidChainKey() public { + // Create a fixture with an invalid chain key + string memory invalidChainConfig = "./test/fixtures/config_invalid_chain.toml"; + vm.writeFile( + invalidChainConfig, + string.concat( + "[mainnet]\n", + "endpoint_url = \"https://eth.llamarpc.com\"\n", + "\n", + "[mainnet.uint]\n", + "valid_number = 123\n", + "\n", + "# Invalid chain key (not a number and not a valid alias)\n", + "[invalid_chain]\n", + "endpoint_url = \"https://invalid.com\"\n", + "\n", + "[invalid_chain_9999.uint]\n", + "some_value = 456\n" + ) + ); + + vm.expectRevert(abi.encodeWithSelector(StdConfig.InvalidChainKey.selector, "invalid_chain")); + new StdConfig(invalidChainConfig, false); + vm.removeFile(invalidChainConfig); + } + + function testRevert_ChainNotInitialized() public { + _loadConfig("./test/fixtures/config.toml", false); + + // Enable writing to file bypassing the context check. + vm.store(address(config), bytes32(uint256(5)), bytes32(uint256(1))); + + // Try to write a value for a non-existent chain ID + vm.expectRevert(abi.encodeWithSelector(StdConfig.ChainNotInitialized.selector, uint256(999999))); + config.set(999999, "some_key", uint256(123)); + } + + function testRevert_UnableToParseVariable() public { + // Create a temporary fixture with an unparsable variable + string memory badParseConfig = "./test/fixtures/config_bad_parse.toml"; + vm.writeFile( + badParseConfig, + string.concat( + "[mainnet]\n", + "endpoint_url = \"https://eth.llamarpc.com\"\n", + "\n", + "[mainnet.uint]\n", + "bad_value = \"not_a_number\"\n" + ) + ); + + vm.expectRevert(abi.encodeWithSelector(StdConfig.UnableToParseVariable.selector, "bad_value")); + new StdConfig(badParseConfig, false); + vm.removeFile(badParseConfig); + } +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/LibVariable.t.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/LibVariable.t.sol new file mode 100644 index 0000000000..2fc00a91ab --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/LibVariable.t.sol @@ -0,0 +1,434 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +import {Test} from "../src/Test.sol"; +import {Variable, Type, TypeKind, LibVariable} from "../src/LibVariable.sol"; + +contract LibVariableTest is Test { + using LibVariable for Type; + using LibVariable for TypeKind; + + LibVariableHelper internal helper; + + bytes internal expectedErr; + Variable internal uninitVar; + Variable internal boolVar; + Variable internal addressVar; + Variable internal bytes32Var; + Variable internal uintVar; + Variable internal intVar; + Variable internal stringVar; + Variable internal bytesVar; + Variable internal boolArrayVar; + Variable internal addressArrayVar; + Variable internal bytes32ArrayVar; + Variable internal uintArrayVar; + Variable internal intArrayVar; + Variable internal stringArrayVar; + Variable internal bytesArrayVar; + + function setUp() public { + helper = new LibVariableHelper(); + + // UNINITIALIZED + uninitVar = Variable(Type(TypeKind.None, false), ""); + + // SINGLE VALUES + boolVar = Variable(Type(TypeKind.Bool, false), abi.encode(true)); + addressVar = Variable(Type(TypeKind.Address, false), abi.encode(address(0xdeadbeef))); + bytes32Var = Variable(Type(TypeKind.Bytes32, false), abi.encode(bytes32(uint256(42)))); + uintVar = Variable(Type(TypeKind.Uint256, false), abi.encode(uint256(123))); + intVar = Variable(Type(TypeKind.Int256, false), abi.encode(int256(-123))); + stringVar = Variable(Type(TypeKind.String, false), abi.encode("hello world")); + bytesVar = Variable(Type(TypeKind.Bytes, false), abi.encode(hex"c0ffee")); + + // ARRAY VALUES + bool[] memory bools = new bool[](2); + bools[0] = true; + bools[1] = false; + boolArrayVar = Variable(Type(TypeKind.Bool, true), abi.encode(bools)); + + address[] memory addrs = new address[](2); + addrs[0] = address(0x1); + addrs[1] = address(0x2); + addressArrayVar = Variable(Type(TypeKind.Address, true), abi.encode(addrs)); + + bytes32[] memory b32s = new bytes32[](2); + b32s[0] = bytes32(uint256(1)); + b32s[1] = bytes32(uint256(2)); + bytes32ArrayVar = Variable(Type(TypeKind.Bytes32, true), abi.encode(b32s)); + + uint256[] memory uints = new uint256[](2); + uints[0] = 1; + uints[1] = 2; + uintArrayVar = Variable(Type(TypeKind.Uint256, true), abi.encode(uints)); + + int256[] memory ints = new int256[](2); + ints[0] = -1; + ints[1] = 2; + intArrayVar = Variable(Type(TypeKind.Int256, true), abi.encode(ints)); + + string[] memory strings = new string[](2); + strings[0] = "one"; + strings[1] = "two"; + stringArrayVar = Variable(Type(TypeKind.String, true), abi.encode(strings)); + + bytes[] memory b = new bytes[](2); + b[0] = hex"01"; + b[1] = hex"02"; + bytesArrayVar = Variable(Type(TypeKind.Bytes, true), abi.encode(b)); + } + + // -- SUCCESS CASES -------------------------------------------------------- + + function test_TypeHelpers() public view { + // TypeKind.toString() + assertEq(TypeKind.None.toString(), "none"); + assertEq(TypeKind.Bool.toString(), "bool"); + assertEq(TypeKind.Address.toString(), "address"); + assertEq(TypeKind.Bytes32.toString(), "bytes32"); + assertEq(TypeKind.Uint256.toString(), "uint256"); + assertEq(TypeKind.Int256.toString(), "int256"); + assertEq(TypeKind.String.toString(), "string"); + assertEq(TypeKind.Bytes.toString(), "bytes"); + + // TypeKind.toTomlKey() + assertEq(TypeKind.Uint256.toTomlKey(), "uint"); + assertEq(TypeKind.Int256.toTomlKey(), "int"); + assertEq(TypeKind.Bytes32.toTomlKey(), "bytes32"); + + // Type.toString() + assertEq(boolVar.ty.toString(), "bool"); + assertEq(boolArrayVar.ty.toString(), "bool[]"); + assertEq(uintVar.ty.toString(), "uint256"); + assertEq(uintArrayVar.ty.toString(), "uint256[]"); + assertEq(uninitVar.ty.toString(), "none"); + + // Type.isEqual() + assertTrue(boolVar.ty.isEqual(Type(TypeKind.Bool, false))); + assertFalse(boolVar.ty.isEqual(Type(TypeKind.Bool, true))); + assertFalse(boolVar.ty.isEqual(Type(TypeKind.Address, false))); + + // Type.assertEq() + boolVar.ty.assertEq(Type(TypeKind.Bool, false)); + uintArrayVar.ty.assertEq(Type(TypeKind.Uint256, true)); + } + + function test_Coercion() public view { + // Single values + assertTrue(helper.toBool(boolVar)); + assertEq(helper.toAddress(addressVar), address(0xdeadbeef)); + assertEq(helper.toBytes32(bytes32Var), bytes32(uint256(42))); + assertEq(helper.toUint256(uintVar), 123); + assertEq(helper.toInt256(intVar), -123); + assertEq(helper.toString(stringVar), "hello world"); + assertEq(helper.toBytes(bytesVar), hex"c0ffee"); + + // Bool array + bool[] memory bools = helper.toBoolArray(boolArrayVar); + assertEq(bools.length, 2); + assertTrue(bools[0]); + assertFalse(bools[1]); + + // Address array + address[] memory addrs = helper.toAddressArray(addressArrayVar); + assertEq(addrs.length, 2); + assertEq(addrs[0], address(0x1)); + assertEq(addrs[1], address(0x2)); + + // String array + string[] memory strings = helper.toStringArray(stringArrayVar); + assertEq(strings.length, 2); + assertEq(strings[0], "one"); + assertEq(strings[1], "two"); + } + + function test_Downcasting() public view { + // Uint downcasting + Variable memory v_uint_small = Variable(Type(TypeKind.Uint256, false), abi.encode(uint256(100))); + assertEq(helper.toUint128(v_uint_small), 100); + assertEq(helper.toUint64(v_uint_small), 100); + assertEq(helper.toUint32(v_uint_small), 100); + assertEq(helper.toUint16(v_uint_small), 100); + assertEq(helper.toUint8(v_uint_small), 100); + + // Uint array downcasting + uint256[] memory small_uints = new uint256[](2); + small_uints[0] = 10; + small_uints[1] = 20; + Variable memory v_uint_array_small = Variable(Type(TypeKind.Uint256, true), abi.encode(small_uints)); + uint8[] memory u8_array = helper.toUint8Array(v_uint_array_small); + assertEq(u8_array[0], 10); + assertEq(u8_array[1], 20); + + // Int downcasting + Variable memory v_int_small_pos = Variable(Type(TypeKind.Int256, false), abi.encode(int256(100))); + Variable memory v_int_small_neg = Variable(Type(TypeKind.Int256, false), abi.encode(int256(-100))); + assertEq(helper.toInt128(v_int_small_pos), 100); + assertEq(helper.toInt64(v_int_small_neg), -100); + assertEq(helper.toInt32(v_int_small_pos), 100); + assertEq(helper.toInt16(v_int_small_neg), -100); + assertEq(helper.toInt8(v_int_small_pos), 100); + + // Int array downcasting + int256[] memory small_ints = new int256[](2); + small_ints[0] = -10; + small_ints[1] = 20; + Variable memory intArraySmall = Variable(Type(TypeKind.Int256, true), abi.encode(small_ints)); + int8[] memory i8_array = helper.toInt8Array(intArraySmall); + assertEq(i8_array[0], -10); + assertEq(i8_array[1], 20); + } + + // -- REVERT CASES --------------------------------------------------------- + + function testRevert_NotInitialized() public { + vm.expectRevert(LibVariable.NotInitialized.selector); + helper.toBool(uninitVar); + + vm.expectRevert(LibVariable.NotInitialized.selector); + helper.toAddressArray(uninitVar); + } + + function testRevert_assertExists() public { + vm.expectRevert(LibVariable.NotInitialized.selector); + helper.assertExists(uninitVar); + } + + function testRevert_TypeMismatch() public { + // Single values + vm.expectRevert(abi.encodeWithSelector(LibVariable.TypeMismatch.selector, "uint256", "bool")); + helper.toUint256(boolVar); + + vm.expectRevert(abi.encodeWithSelector(LibVariable.TypeMismatch.selector, "address", "string")); + helper.toAddress(stringVar); + + // Arrays + vm.expectRevert(abi.encodeWithSelector(LibVariable.TypeMismatch.selector, "uint256[]", "bool[]")); + helper.toUint256Array(boolArrayVar); + + vm.expectRevert(abi.encodeWithSelector(LibVariable.TypeMismatch.selector, "address[]", "string[]")); + helper.toAddressArray(stringArrayVar); + + // Single value to array + vm.expectRevert(abi.encodeWithSelector(LibVariable.TypeMismatch.selector, "bool[]", "bool")); + helper.toBoolArray(boolVar); + + // Array to single value + vm.expectRevert(abi.encodeWithSelector(LibVariable.TypeMismatch.selector, "bool", "bool[]")); + helper.toBool(boolArrayVar); + + // assertEq reverts + vm.expectRevert(abi.encodeWithSelector(LibVariable.TypeMismatch.selector, "uint256", "bool")); + helper.assertEq(boolVar.ty, Type(TypeKind.Uint256, false)); + } + + function testRevert_UnsafeCast() public { + // uint overflow + Variable memory uintLarge = Variable(Type(TypeKind.Uint256, false), abi.encode(uint256(type(uint128).max) + 1)); + expectedErr = abi.encodeWithSelector(LibVariable.UnsafeCast.selector, "value does not fit in 'uint128'"); + vm.expectRevert(expectedErr); + helper.toUint128(uintLarge); + + // int overflow + Variable memory intLarge = Variable(Type(TypeKind.Int256, false), abi.encode(int256(type(int128).max) + 1)); + expectedErr = abi.encodeWithSelector(LibVariable.UnsafeCast.selector, "value does not fit in 'int128'"); + + vm.expectRevert(expectedErr); + helper.toInt128(intLarge); + + // int underflow + Variable memory intSmall = Variable(Type(TypeKind.Int256, false), abi.encode(int256(type(int128).min) - 1)); + expectedErr = abi.encodeWithSelector(LibVariable.UnsafeCast.selector, "value does not fit in 'int128'"); + + vm.expectRevert(expectedErr); + helper.toInt128(intSmall); + + // uint array overflow + uint256[] memory uintArray = new uint256[](2); + uintArray[0] = 10; + uintArray[1] = uint256(type(uint64).max) + 1; + Variable memory uintArrayLarge = Variable(Type(TypeKind.Uint256, true), abi.encode(uintArray)); + expectedErr = abi.encodeWithSelector(LibVariable.UnsafeCast.selector, "value in array does not fit in 'uint64'"); + + vm.expectRevert(expectedErr); + helper.toUint64Array(uintArrayLarge); + + // int array overflow + int256[] memory intArray = new int256[](2); + intArray[0] = 10; + intArray[1] = int256(type(int64).max) + 1; + Variable memory intArrayLarge = Variable(Type(TypeKind.Int256, true), abi.encode(intArray)); + expectedErr = abi.encodeWithSelector(LibVariable.UnsafeCast.selector, "value in array does not fit in 'int64'"); + + vm.expectRevert(expectedErr); + helper.toInt64Array(intArrayLarge); + + // int array underflow + intArray[0] = 10; + intArray[1] = int256(type(int64).min) - 1; + Variable memory intArraySmall = Variable(Type(TypeKind.Int256, true), abi.encode(intArray)); + expectedErr = abi.encodeWithSelector(LibVariable.UnsafeCast.selector, "value in array does not fit in 'int64'"); + + vm.expectRevert(expectedErr); + helper.toInt64Array(intArraySmall); + } +} + +/// @dev We must use an external helper contract to ensure proper call depth for `vm.expectRevert`, +/// as direct library calls are inlined by the compiler, causing call depth issues. +contract LibVariableHelper { + using LibVariable for Type; + using LibVariable for TypeKind; + + // Assertions + function assertExists(Variable memory v) external pure { + v.assertExists(); + } + + function assertEq(Type memory t1, Type memory t2) external pure { + t1.assertEq(t2); + } + + // Single Value Coercion + function toBool(Variable memory v) external pure returns (bool) { + return v.toBool(); + } + + function toAddress(Variable memory v) external pure returns (address) { + return v.toAddress(); + } + + function toBytes32(Variable memory v) external pure returns (bytes32) { + return v.toBytes32(); + } + + function toUint256(Variable memory v) external pure returns (uint256) { + return v.toUint256(); + } + + function toInt256(Variable memory v) external pure returns (int256) { + return v.toInt256(); + } + + function toString(Variable memory v) external pure returns (string memory) { + return v.toString(); + } + + function toBytes(Variable memory v) external pure returns (bytes memory) { + return v.toBytes(); + } + + // Array Coercion + function toBoolArray(Variable memory v) external pure returns (bool[] memory) { + return v.toBoolArray(); + } + + function toAddressArray(Variable memory v) external pure returns (address[] memory) { + return v.toAddressArray(); + } + + function toBytes32Array(Variable memory v) external pure returns (bytes32[] memory) { + return v.toBytes32Array(); + } + + function toUint256Array(Variable memory v) external pure returns (uint256[] memory) { + return v.toUint256Array(); + } + + function toInt256Array(Variable memory v) external pure returns (int256[] memory) { + return v.toInt256Array(); + } + + function toStringArray(Variable memory v) external pure returns (string[] memory) { + return v.toStringArray(); + } + + function toBytesArray(Variable memory v) external pure returns (bytes[] memory) { + return v.toBytesArray(); + } + + // Uint Downcasting + function toUint128(Variable memory v) external pure returns (uint128) { + return v.toUint128(); + } + + function toUint64(Variable memory v) external pure returns (uint64) { + return v.toUint64(); + } + + function toUint32(Variable memory v) external pure returns (uint32) { + return v.toUint32(); + } + + function toUint16(Variable memory v) external pure returns (uint16) { + return v.toUint16(); + } + + function toUint8(Variable memory v) external pure returns (uint8) { + return v.toUint8(); + } + + // Int Downcasting + function toInt128(Variable memory v) external pure returns (int128) { + return v.toInt128(); + } + + function toInt64(Variable memory v) external pure returns (int64) { + return v.toInt64(); + } + + function toInt32(Variable memory v) external pure returns (int32) { + return v.toInt32(); + } + + function toInt16(Variable memory v) external pure returns (int16) { + return v.toInt16(); + } + + function toInt8(Variable memory v) external pure returns (int8) { + return v.toInt8(); + } + + // Uint Array Downcasting + function toUint128Array(Variable memory v) external pure returns (uint128[] memory) { + return v.toUint128Array(); + } + + function toUint64Array(Variable memory v) external pure returns (uint64[] memory) { + return v.toUint64Array(); + } + + function toUint32Array(Variable memory v) external pure returns (uint32[] memory) { + return v.toUint32Array(); + } + + function toUint16Array(Variable memory v) external pure returns (uint16[] memory) { + return v.toUint16Array(); + } + + function toUint8Array(Variable memory v) external pure returns (uint8[] memory) { + return v.toUint8Array(); + } + + // Int Array Downcasting + function toInt128Array(Variable memory v) external pure returns (int128[] memory) { + return v.toInt128Array(); + } + + function toInt64Array(Variable memory v) external pure returns (int64[] memory) { + return v.toInt64Array(); + } + + function toInt32Array(Variable memory v) external pure returns (int32[] memory) { + return v.toInt32Array(); + } + + function toInt16Array(Variable memory v) external pure returns (int16[] memory) { + return v.toInt16Array(); + } + + function toInt8Array(Variable memory v) external pure returns (int8[] memory) { + return v.toInt8Array(); + } +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/StdAssertions.t.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/StdAssertions.t.sol new file mode 100644 index 0000000000..acc0c1e812 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/StdAssertions.t.sol @@ -0,0 +1,141 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import {StdAssertions} from "../src/StdAssertions.sol"; +import {Vm} from "../src/Vm.sol"; + +interface VmInternal is Vm { + function _expectCheatcodeRevert(bytes memory message) external; +} + +contract StdAssertionsTest is StdAssertions { + string constant errorMessage = "User provided message"; + uint256 constant maxDecimals = 77; + + bool constant SHOULD_REVERT = true; + bool constant SHOULD_RETURN = false; + + bool constant STRICT_REVERT_DATA = true; + bool constant NON_STRICT_REVERT_DATA = false; + + VmInternal constant vm = VmInternal(address(uint160(uint256(keccak256("hevm cheat code"))))); + + function testFuzz_AssertEqCall_Return_Pass( + bytes memory callDataA, + bytes memory callDataB, + bytes memory returnData, + bool strictRevertData + ) external { + address targetA = address(new TestMockCall(returnData, SHOULD_RETURN)); + address targetB = address(new TestMockCall(returnData, SHOULD_RETURN)); + + assertEqCall(targetA, callDataA, targetB, callDataB, strictRevertData); + } + + function testFuzz_RevertWhenCalled_AssertEqCall_Return_Fail( + bytes memory callDataA, + bytes memory callDataB, + bytes memory returnDataA, + bytes memory returnDataB, + bool strictRevertData + ) external { + vm.assume(keccak256(returnDataA) != keccak256(returnDataB)); + + address targetA = address(new TestMockCall(returnDataA, SHOULD_RETURN)); + address targetB = address(new TestMockCall(returnDataB, SHOULD_RETURN)); + + vm._expectCheatcodeRevert( + bytes( + string.concat( + "Call return data does not match: ", vm.toString(returnDataA), " != ", vm.toString(returnDataB) + ) + ) + ); + assertEqCall(targetA, callDataA, targetB, callDataB, strictRevertData); + } + + function testFuzz_AssertEqCall_Revert_Pass( + bytes memory callDataA, + bytes memory callDataB, + bytes memory revertDataA, + bytes memory revertDataB + ) external { + address targetA = address(new TestMockCall(revertDataA, SHOULD_REVERT)); + address targetB = address(new TestMockCall(revertDataB, SHOULD_REVERT)); + + assertEqCall(targetA, callDataA, targetB, callDataB, NON_STRICT_REVERT_DATA); + } + + function testFuzz_RevertWhenCalled_AssertEqCall_Revert_Fail( + bytes memory callDataA, + bytes memory callDataB, + bytes memory revertDataA, + bytes memory revertDataB + ) external { + vm.assume(keccak256(revertDataA) != keccak256(revertDataB)); + + address targetA = address(new TestMockCall(revertDataA, SHOULD_REVERT)); + address targetB = address(new TestMockCall(revertDataB, SHOULD_REVERT)); + + vm._expectCheatcodeRevert( + bytes( + string.concat( + "Call revert data does not match: ", vm.toString(revertDataA), " != ", vm.toString(revertDataB) + ) + ) + ); + assertEqCall(targetA, callDataA, targetB, callDataB, STRICT_REVERT_DATA); + } + + function testFuzz_RevertWhenCalled_AssertEqCall_Fail( + bytes memory callDataA, + bytes memory callDataB, + bytes memory returnDataA, + bytes memory returnDataB, + bool strictRevertData + ) external { + address targetA = address(new TestMockCall(returnDataA, SHOULD_RETURN)); + address targetB = address(new TestMockCall(returnDataB, SHOULD_REVERT)); + + vm.expectRevert(bytes("assertion failed")); + this.assertEqCallExternal(targetA, callDataA, targetB, callDataB, strictRevertData); + + vm.expectRevert(bytes("assertion failed")); + this.assertEqCallExternal(targetB, callDataB, targetA, callDataA, strictRevertData); + } + + // Helper function to test outcome of assertEqCall via `expect` cheatcodes + function assertEqCallExternal( + address targetA, + bytes memory callDataA, + address targetB, + bytes memory callDataB, + bool strictRevertData + ) public { + assertEqCall(targetA, callDataA, targetB, callDataB, strictRevertData); + } +} + +contract TestMockCall { + bytes returnData; + bool shouldRevert; + + constructor(bytes memory returnData_, bool shouldRevert_) { + returnData = returnData_; + shouldRevert = shouldRevert_; + } + + fallback() external payable { + bytes memory returnData_ = returnData; + + if (shouldRevert) { + assembly { + revert(add(returnData_, 0x20), mload(returnData_)) + } + } else { + assembly { + return(add(returnData_, 0x20), mload(returnData_)) + } + } + } +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/StdChains.t.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/StdChains.t.sol new file mode 100644 index 0000000000..9522b37d02 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/StdChains.t.sol @@ -0,0 +1,227 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import {Test} from "../src/Test.sol"; + +contract StdChainsMock is Test { + function exposed_getChain(string memory chainAlias) public returns (Chain memory) { + return getChain(chainAlias); + } + + function exposed_getChain(uint256 chainId) public returns (Chain memory) { + return getChain(chainId); + } + + function exposed_setChain(string memory chainAlias, ChainData memory chainData) public { + setChain(chainAlias, chainData); + } + + function exposed_setFallbackToDefaultRpcUrls(bool useDefault) public { + setFallbackToDefaultRpcUrls(useDefault); + } +} + +contract StdChainsTest is Test { + function test_ChainRpcInitialization() public { + // RPCs specified in `foundry.toml` should be updated. + assertEq(getChain(1).rpcUrl, "https://eth.merkle.io"); + assertEq(getChain("optimism_sepolia").rpcUrl, "https://sepolia.optimism.io/"); + assertEq(getChain("arbitrum_one_sepolia").rpcUrl, "https://sepolia-rollup.arbitrum.io/rpc/"); + + // Environment variables should be the next fallback + assertEq(getChain("arbitrum_nova").rpcUrl, "https://nova.arbitrum.io/rpc"); + vm.setEnv("ARBITRUM_NOVA_RPC_URL", "myoverride"); + assertEq(getChain("arbitrum_nova").rpcUrl, "myoverride"); + vm.setEnv("ARBITRUM_NOVA_RPC_URL", "https://nova.arbitrum.io/rpc"); + + // Cannot override RPCs defined in `foundry.toml` + vm.setEnv("MAINNET_RPC_URL", "myoverride2"); + assertEq(getChain("mainnet").rpcUrl, "https://eth.merkle.io"); + + // Other RPCs should remain unchanged. + assertEq(getChain(31337).rpcUrl, "http://127.0.0.1:8545"); + assertEq(getChain("sepolia").rpcUrl, "https://sepolia.infura.io/v3/b9794ad1ddf84dfb8c34d6bb5dca2001"); + } + + // Named with a leading underscore to clarify this is not intended to be run as a normal test, + // and is intended to be used in the below `test_Rpcs` test. + function _testRpc(string memory rpcAlias) internal { + string memory rpcUrl = getChain(rpcAlias).rpcUrl; + vm.createSelectFork(rpcUrl); + } + + // Ensure we can connect to the default RPC URL for each chain. + // Currently commented out since this is slow and public RPCs are flaky, often resulting in failing CI. + // function test_Rpcs() public { + // _testRpc("mainnet"); + // _testRpc("sepolia"); + // _testRpc("holesky"); + // _testRpc("optimism"); + // _testRpc("optimism_sepolia"); + // _testRpc("arbitrum_one"); + // _testRpc("arbitrum_one_sepolia"); + // _testRpc("arbitrum_nova"); + // _testRpc("polygon"); + // _testRpc("polygon_amoy"); + // _testRpc("avalanche"); + // _testRpc("avalanche_fuji"); + // _testRpc("bnb_smart_chain"); + // _testRpc("bnb_smart_chain_testnet"); + // _testRpc("gnosis_chain"); + // _testRpc("moonbeam"); + // _testRpc("moonriver"); + // _testRpc("moonbase"); + // _testRpc("base_sepolia"); + // _testRpc("base"); + // _testRpc("blast_sepolia"); + // _testRpc("blast"); + // _testRpc("fantom_opera"); + // _testRpc("fantom_opera_testnet"); + // _testRpc("fraxtal"); + // _testRpc("fraxtal_testnet"); + // _testRpc("berachain_bartio_testnet"); + // _testRpc("flare"); + // _testRpc("flare_coston2"); + // } + + function test_RevertIf_ChainNotFound() public { + // We deploy a mock to properly test the revert. + StdChainsMock stdChainsMock = new StdChainsMock(); + + vm.expectRevert("StdChains getChain(string): Chain with alias \"does_not_exist\" not found."); + stdChainsMock.exposed_getChain("does_not_exist"); + } + + function test_RevertIf_SetChain_ChainIdExist_FirstTest() public { + // We deploy a mock to properly test the revert. + StdChainsMock stdChainsMock = new StdChainsMock(); + + vm.expectRevert("StdChains setChain(string,ChainData): Chain ID 31337 already used by \"anvil\"."); + stdChainsMock.exposed_setChain("anvil2", ChainData("Anvil", 31337, "URL")); + } + + function test_RevertIf_ChainBubbleUp() public { + // We deploy a mock to properly test the revert. + StdChainsMock stdChainsMock = new StdChainsMock(); + + stdChainsMock.exposed_setChain("needs_undefined_env_var", ChainData("", 123456789, "")); + // Forge environment variable error. + vm.expectRevert(); + stdChainsMock.exposed_getChain("needs_undefined_env_var"); + } + + function test_RevertIf_SetChain_ChainIdExists_SecondTest() public { + // We deploy a mock to properly test the revert. + StdChainsMock stdChainsMock = new StdChainsMock(); + + stdChainsMock.exposed_setChain("custom_chain", ChainData("Custom Chain", 123456789, "https://custom.chain/")); + + vm.expectRevert('StdChains setChain(string,ChainData): Chain ID 123456789 already used by "custom_chain".'); + + stdChainsMock.exposed_setChain("another_custom_chain", ChainData("", 123456789, "")); + } + + function test_SetChain() public { + setChain("custom_chain", ChainData("Custom Chain", 123456789, "https://custom.chain/")); + Chain memory customChain = getChain("custom_chain"); + assertEq(customChain.name, "Custom Chain"); + assertEq(customChain.chainId, 123456789); + assertEq(customChain.chainAlias, "custom_chain"); + assertEq(customChain.rpcUrl, "https://custom.chain/"); + Chain memory chainById = getChain(123456789); + assertEq(chainById.name, customChain.name); + assertEq(chainById.chainId, customChain.chainId); + assertEq(chainById.chainAlias, customChain.chainAlias); + assertEq(chainById.rpcUrl, customChain.rpcUrl); + customChain.name = "Another Custom Chain"; + customChain.chainId = 987654321; + setChain("another_custom_chain", customChain); + Chain memory anotherCustomChain = getChain("another_custom_chain"); + assertEq(anotherCustomChain.name, "Another Custom Chain"); + assertEq(anotherCustomChain.chainId, 987654321); + assertEq(anotherCustomChain.chainAlias, "another_custom_chain"); + assertEq(anotherCustomChain.rpcUrl, "https://custom.chain/"); + // Verify the first chain data was not overwritten + chainById = getChain(123456789); + assertEq(chainById.name, "Custom Chain"); + assertEq(chainById.chainId, 123456789); + } + + function test_RevertIf_SetEmptyAlias() public { + // We deploy a mock to properly test the revert. + StdChainsMock stdChainsMock = new StdChainsMock(); + + vm.expectRevert("StdChains setChain(string,ChainData): Chain alias cannot be the empty string."); + stdChainsMock.exposed_setChain("", ChainData("", 123456789, "")); + } + + function test_RevertIf_SetNoChainId0() public { + // We deploy a mock to properly test the revert. + StdChainsMock stdChainsMock = new StdChainsMock(); + + vm.expectRevert("StdChains setChain(string,ChainData): Chain ID cannot be 0."); + stdChainsMock.exposed_setChain("alias", ChainData("", 0, "")); + } + + function test_RevertIf_GetNoChainId0() public { + // We deploy a mock to properly test the revert. + StdChainsMock stdChainsMock = new StdChainsMock(); + + vm.expectRevert("StdChains getChain(uint256): Chain ID cannot be 0."); + stdChainsMock.exposed_getChain(0); + } + + function test_RevertIf_GetNoEmptyAlias() public { + // We deploy a mock to properly test the revert. + StdChainsMock stdChainsMock = new StdChainsMock(); + + vm.expectRevert("StdChains getChain(string): Chain alias cannot be the empty string."); + stdChainsMock.exposed_getChain(""); + } + + function test_RevertIf_ChainNotInitialized() public { + // We deploy a mock to properly test the revert. + StdChainsMock stdChainsMock = new StdChainsMock(); + + vm.expectRevert("StdChains getChain(string): Chain with alias \"no_such_alias\" not found."); + stdChainsMock.exposed_getChain("no_such_alias"); + } + + function test_RevertIf_ChainAliasNotFound() public { + // We deploy a mock to properly test the revert. + StdChainsMock stdChainsMock = new StdChainsMock(); + + vm.expectRevert("StdChains getChain(uint256): Chain with ID 321 not found."); + + stdChainsMock.exposed_getChain(321); + } + + function test_SetChain_ExistingOne() public { + // We deploy a mock to properly test the revert. + StdChainsMock stdChainsMock = new StdChainsMock(); + + setChain("custom_chain", ChainData("Custom Chain", 123456789, "https://custom.chain/")); + assertEq(getChain(123456789).chainId, 123456789); + + setChain("custom_chain", ChainData("Modified Chain", 9999999999999999999, "https://modified.chain/")); + vm.expectRevert("StdChains getChain(uint256): Chain with ID 123456789 not found."); + stdChainsMock.exposed_getChain(123456789); + + Chain memory modifiedChain = getChain(9999999999999999999); + assertEq(modifiedChain.name, "Modified Chain"); + assertEq(modifiedChain.chainId, 9999999999999999999); + assertEq(modifiedChain.rpcUrl, "https://modified.chain/"); + } + + function test_RevertIf_DontUseDefaultRpcUrl() public { + // We deploy a mock to properly test the revert. + StdChainsMock stdChainsMock = new StdChainsMock(); + + // Should error if default RPCs flag is set to false. + stdChainsMock.exposed_setFallbackToDefaultRpcUrls(false); + vm.expectRevert(); + stdChainsMock.exposed_getChain(31337); + vm.expectRevert(); + stdChainsMock.exposed_getChain("sepolia"); + } +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/StdCheats.t.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/StdCheats.t.sol new file mode 100644 index 0000000000..57dbcc2915 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/StdCheats.t.sol @@ -0,0 +1,639 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import {StdCheats} from "../src/StdCheats.sol"; +import {Test} from "../src/Test.sol"; +import {stdJson} from "../src/StdJson.sol"; +import {stdToml} from "../src/StdToml.sol"; +import {IERC20} from "../src/interfaces/IERC20.sol"; + +contract StdCheatsTest is Test { + Bar test; + + using stdJson for string; + + function setUp() public { + test = new Bar(); + } + + function test_Skip() public { + vm.warp(100); + skip(25); + assertEq(block.timestamp, 125); + } + + function test_Rewind() public { + vm.warp(100); + rewind(25); + assertEq(block.timestamp, 75); + } + + function test_Hoax() public { + hoax(address(1337)); + test.bar{value: 100}(address(1337)); + } + + function test_HoaxOrigin() public { + hoax(address(1337), address(1337)); + test.origin{value: 100}(address(1337)); + } + + function test_HoaxDifferentAddresses() public { + hoax(address(1337), address(7331)); + test.origin{value: 100}(address(1337), address(7331)); + } + + function test_StartHoax() public { + startHoax(address(1337)); + test.bar{value: 100}(address(1337)); + test.bar{value: 100}(address(1337)); + vm.stopPrank(); + test.bar(address(this)); + } + + function test_StartHoaxOrigin() public { + startHoax(address(1337), address(1337)); + test.origin{value: 100}(address(1337)); + test.origin{value: 100}(address(1337)); + vm.stopPrank(); + test.bar(address(this)); + } + + function test_ChangePrankMsgSender() public { + vm.startPrank(address(1337)); + test.bar(address(1337)); + changePrank(address(0xdead)); + test.bar(address(0xdead)); + changePrank(address(1337)); + test.bar(address(1337)); + vm.stopPrank(); + } + + function test_ChangePrankMsgSenderAndTxOrigin() public { + vm.startPrank(address(1337), address(1338)); + test.origin(address(1337), address(1338)); + changePrank(address(0xdead), address(0xbeef)); + test.origin(address(0xdead), address(0xbeef)); + changePrank(address(1337), address(1338)); + test.origin(address(1337), address(1338)); + vm.stopPrank(); + } + + function test_MakeAccountEquivalence() public { + Account memory account = makeAccount("1337"); + (address addr, uint256 key) = makeAddrAndKey("1337"); + assertEq(account.addr, addr); + assertEq(account.key, key); + } + + function test_MakeAddrEquivalence() public { + (address addr,) = makeAddrAndKey("1337"); + assertEq(makeAddr("1337"), addr); + } + + function test_MakeAddrSigning() public { + (address addr, uint256 key) = makeAddrAndKey("1337"); + bytes32 hash = keccak256("some_message"); + + (uint8 v, bytes32 r, bytes32 s) = vm.sign(key, hash); + assertEq(ecrecover(hash, v, r, s), addr); + } + + function test_Deal() public { + deal(address(this), 1 ether); + assertEq(address(this).balance, 1 ether); + } + + function test_DealToken() public { + Bar barToken = new Bar(); + address bar = address(barToken); + deal(bar, address(this), 10000e18); + assertEq(barToken.balanceOf(address(this)), 10000e18); + } + + function test_DealTokenAdjustTotalSupply() public { + Bar barToken = new Bar(); + address bar = address(barToken); + deal(bar, address(this), 10000e18, true); + assertEq(barToken.balanceOf(address(this)), 10000e18); + assertEq(barToken.totalSupply(), 20000e18); + deal(bar, address(this), 0, true); + assertEq(barToken.balanceOf(address(this)), 0); + assertEq(barToken.totalSupply(), 10000e18); + } + + function test_DealERC1155Token() public { + BarERC1155 barToken = new BarERC1155(); + address bar = address(barToken); + dealERC1155(bar, address(this), 0, 10000e18, false); + assertEq(barToken.balanceOf(address(this), 0), 10000e18); + } + + function test_DealERC1155TokenAdjustTotalSupply() public { + BarERC1155 barToken = new BarERC1155(); + address bar = address(barToken); + dealERC1155(bar, address(this), 0, 10000e18, true); + assertEq(barToken.balanceOf(address(this), 0), 10000e18); + assertEq(barToken.totalSupply(0), 20000e18); + dealERC1155(bar, address(this), 0, 0, true); + assertEq(barToken.balanceOf(address(this), 0), 0); + assertEq(barToken.totalSupply(0), 10000e18); + } + + function test_DealERC721Token() public { + BarERC721 barToken = new BarERC721(); + address bar = address(barToken); + dealERC721(bar, address(2), 1); + assertEq(barToken.balanceOf(address(2)), 1); + assertEq(barToken.balanceOf(address(1)), 0); + dealERC721(bar, address(1), 2); + assertEq(barToken.balanceOf(address(1)), 1); + assertEq(barToken.balanceOf(bar), 1); + } + + function test_DeployCode() public { + address deployed = deployCode("StdCheats.t.sol:Bar", bytes("")); + assertEq(string(getCode(deployed)), string(getCode(address(test)))); + } + + function test_DestroyAccount() public { + // deploy something to destroy it + BarERC721 barToken = new BarERC721(); + address bar = address(barToken); + vm.setNonce(bar, 10); + deal(bar, 100); + + uint256 prevThisBalance = address(this).balance; + uint256 size; + assembly { + size := extcodesize(bar) + } + + assertGt(size, 0); + assertEq(bar.balance, 100); + assertEq(vm.getNonce(bar), 10); + + destroyAccount(bar, address(this)); + assembly { + size := extcodesize(bar) + } + assertEq(address(this).balance, prevThisBalance + 100); + assertEq(vm.getNonce(bar), 0); + assertEq(size, 0); + assertEq(bar.balance, 0); + } + + function test_DeployCodeNoArgs() public { + address deployed = deployCode("StdCheats.t.sol:Bar"); + assertEq(string(getCode(deployed)), string(getCode(address(test)))); + } + + function test_DeployCodeVal() public { + address deployed = deployCode("StdCheats.t.sol:Bar", bytes(""), 1 ether); + assertEq(string(getCode(deployed)), string(getCode(address(test)))); + assertEq(deployed.balance, 1 ether); + } + + function test_DeployCodeValNoArgs() public { + address deployed = deployCode("StdCheats.t.sol:Bar", 1 ether); + assertEq(string(getCode(deployed)), string(getCode(address(test)))); + assertEq(deployed.balance, 1 ether); + } + + // We need this so we can call "this.deployCode" rather than "deployCode" directly + function deployCodeHelper(string memory what) external { + deployCode(what); + } + + function test_RevertIf_DeployCodeFail() public { + vm.expectRevert(bytes("StdCheats deployCode(string): Deployment failed.")); + this.deployCodeHelper("StdCheats.t.sol:RevertingContract"); + } + + function getCode(address who) internal view returns (bytes memory o_code) { + /// @solidity memory-safe-assembly + assembly { + // retrieve the size of the code, this needs assembly + let size := extcodesize(who) + // allocate output byte array - this could also be done without assembly + // by using o_code = new bytes(size) + o_code := mload(0x40) + // new "memory end" including padding + mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), not(0x1f)))) + // store length in memory + mstore(o_code, size) + // actually retrieve the code, this needs assembly + extcodecopy(who, add(o_code, 0x20), 0, size) + } + } + + function test_DeriveRememberKey() public { + string memory mnemonic = "test test test test test test test test test test test junk"; + + (address deployer, uint256 privateKey) = deriveRememberKey(mnemonic, 0); + assertEq(deployer, 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266); + assertEq(privateKey, 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80); + } + + function test_BytesToUint() public pure { + assertEq(3, bytesToUint_test(hex"03")); + assertEq(2, bytesToUint_test(hex"02")); + assertEq(255, bytesToUint_test(hex"ff")); + assertEq(29625, bytesToUint_test(hex"73b9")); + } + + function test_ParseJsonTxDetail() public view { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); + string memory json = vm.readFile(path); + bytes memory transactionDetails = json.parseRaw(".transactions[0].tx"); + RawTx1559Detail memory rawTxDetail = abi.decode(transactionDetails, (RawTx1559Detail)); + Tx1559Detail memory txDetail = rawToConvertedEIP1559Detail(rawTxDetail); + assertEq(txDetail.from, 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266); + assertEq(txDetail.to, 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512); + assertEq( + txDetail.data, + hex"23e99187000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000013370000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004" + ); + assertEq(txDetail.nonce, 3); + assertEq(txDetail.txType, 2); + assertEq(txDetail.gas, 29625); + assertEq(txDetail.value, 0); + } + + function test_ReadEIP1559Transaction() public view { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); + uint256 index = 0; + Tx1559 memory transaction = readTx1559(path, index); + transaction; + } + + function test_ReadEIP1559Transactions() public view { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); + Tx1559[] memory transactions = readTx1559s(path); + transactions; + } + + function test_ReadReceipt() public view { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); + uint256 index = 5; + Receipt memory receipt = readReceipt(path, index); + assertEq( + receipt.logsBloom, + hex"00000000000800000000000000000010000000000000000000000000000180000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100" + ); + } + + function test_ReadReceipts() public view { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); + Receipt[] memory receipts = readReceipts(path); + receipts; + } + + function test_GasMeteringModifier() public { + uint256 gas_start_normal = gasleft(); + addInLoop(); + uint256 gas_used_normal = gas_start_normal - gasleft(); + + uint256 gas_start_single = gasleft(); + addInLoopNoGas(); + uint256 gas_used_single = gas_start_single - gasleft(); + + uint256 gas_start_double = gasleft(); + addInLoopNoGasNoGas(); + uint256 gas_used_double = gas_start_double - gasleft(); + + assertTrue(gas_used_double + gas_used_single < gas_used_normal); + } + + function addInLoop() internal pure returns (uint256) { + uint256 b; + for (uint256 i; i < 10000; i++) { + b += i; + } + return b; + } + + function addInLoopNoGas() internal noGasMetering returns (uint256) { + return addInLoop(); + } + + function addInLoopNoGasNoGas() internal noGasMetering returns (uint256) { + return addInLoopNoGas(); + } + + function bytesToUint_test(bytes memory b) private pure returns (uint256) { + uint256 number; + for (uint256 i = 0; i < b.length; i++) { + number = number + uint256(uint8(b[i])) * (2 ** (8 * (b.length - (i + 1)))); + } + return number; + } + + function testFuzz_AssumeAddressIsNot(address addr) external { + // skip over Payable and NonPayable enums + for (uint8 i = 2; i < uint8(type(AddressType).max); i++) { + assumeAddressIsNot(addr, AddressType(i)); + } + assertTrue(addr != address(0)); + assertTrue(addr < address(1) || addr > address(9)); + assertTrue(addr != address(vm) || addr != 0x000000000000000000636F6e736F6c652e6c6f67); + } + + function test_AssumePayable() external { + // We deploy a mock version so we can properly test the revert. + StdCheatsMock stdCheatsMock = new StdCheatsMock(); + + // all should revert since these addresses are not payable + + // VM address + vm.expectRevert(); + stdCheatsMock.exposed_assumePayable(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); + + // Console address + vm.expectRevert(); + stdCheatsMock.exposed_assumePayable(0x000000000000000000636F6e736F6c652e6c6f67); + + // Create2Deployer + vm.expectRevert(); + stdCheatsMock.exposed_assumePayable(0x4e59b44847b379578588920cA78FbF26c0B4956C); + + // all should pass since these addresses are payable + + // vitalik.eth + stdCheatsMock.exposed_assumePayable(0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045); + + // mock payable contract + MockContractPayable cp = new MockContractPayable(); + stdCheatsMock.exposed_assumePayable(address(cp)); + } + + function test_AssumeNotPayable() external { + // We deploy a mock version so we can properly test the revert. + StdCheatsMock stdCheatsMock = new StdCheatsMock(); + + // all should pass since these addresses are not payable + + // VM address + stdCheatsMock.exposed_assumeNotPayable(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); + + // Console address + stdCheatsMock.exposed_assumeNotPayable(0x000000000000000000636F6e736F6c652e6c6f67); + + // Create2Deployer + stdCheatsMock.exposed_assumeNotPayable(0x4e59b44847b379578588920cA78FbF26c0B4956C); + + // all should revert since these addresses are payable + + // vitalik.eth + vm.expectRevert(); + stdCheatsMock.exposed_assumeNotPayable(0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045); + + // mock payable contract + MockContractPayable cp = new MockContractPayable(); + vm.expectRevert(); + stdCheatsMock.exposed_assumeNotPayable(address(cp)); + } + + function testFuzz_AssumeNotPrecompile(address addr) external { + assumeNotPrecompile(addr, getChain("optimism_sepolia").chainId); + assertTrue( + addr < address(1) || (addr > address(9) && addr < address(0x4200000000000000000000000000000000000000)) + || addr > address(0x4200000000000000000000000000000000000800) + ); + } + + function testFuzz_AssumeNotForgeAddress(address addr) external pure { + assumeNotForgeAddress(addr); + assertTrue( + addr != address(vm) && addr != 0x000000000000000000636F6e736F6c652e6c6f67 + && addr != 0x4e59b44847b379578588920cA78FbF26c0B4956C + ); + } + + function test_RevertIf_CannotDeployCodeTo() external { + vm.expectRevert("StdCheats deployCodeTo(string,bytes,uint256,address): Failed to create runtime bytecode."); + this._revertDeployCodeTo(); + } + + function _revertDeployCodeTo() external { + deployCodeTo("StdCheats.t.sol:RevertingContract", address(0)); + } + + function test_DeployCodeTo() external { + address arbitraryAddress = makeAddr("arbitraryAddress"); + + deployCodeTo( + "StdCheats.t.sol:MockContractWithConstructorArgs", + abi.encode(uint256(6), true, bytes20(arbitraryAddress)), + 1 ether, + arbitraryAddress + ); + + MockContractWithConstructorArgs ct = MockContractWithConstructorArgs(arbitraryAddress); + + assertEq(arbitraryAddress.balance, 1 ether); + assertEq(ct.x(), 6); + assertTrue(ct.y()); + assertEq(ct.z(), bytes20(arbitraryAddress)); + } +} + +contract StdCheatsMock is StdCheats { + function exposed_assumePayable(address addr) external { + assumePayable(addr); + } + + function exposed_assumeNotPayable(address addr) external { + assumeNotPayable(addr); + } + + // We deploy a mock version so we can properly test expected reverts. + function exposed_assumeNotBlacklisted(address token, address addr) external view { + return assumeNotBlacklisted(token, addr); + } +} + +contract StdCheatsForkTest is Test { + address internal constant USDC_BLACKLISTED_USER = 0x1E34A77868E19A6647b1f2F47B51ed72dEDE95DD; + address internal constant USDT_BLACKLISTED_USER = 0x8f8a8F4B54a2aAC7799d7bc81368aC27b852822A; + + MockUSDT public USDT; + MockUSDC public USDC; + + function setUp() public { + USDT = new MockUSDT(); + USDC = new MockUSDC(); + + USDC.setBlacklisted(USDC_BLACKLISTED_USER, true); + USDT.setBlacklisted(USDT_BLACKLISTED_USER, true); + } + + function test_RevertIf_CannotAssumeNoBlacklisted_EOA() external { + // We deploy a mock version so we can properly test the revert. + StdCheatsMock stdCheatsMock = new StdCheatsMock(); + address eoa = vm.addr({privateKey: 1}); + vm.expectRevert("StdCheats assumeNotBlacklisted(address,address): Token address is not a contract."); + stdCheatsMock.exposed_assumeNotBlacklisted(eoa, address(0)); + } + + function testFuzz_AssumeNotBlacklisted_TokenWithoutBlacklist(address addr) external view { + assumeNotBlacklisted(address(USDC), addr); + assumeNotBlacklisted(address(USDT), addr); + assertTrue(true); + } + + function test_RevertIf_AssumeNoBlacklisted_USDC() external { + // We deploy a mock version so we can properly test the revert. + StdCheatsMock stdCheatsMock = new StdCheatsMock(); + vm.expectRevert(); + stdCheatsMock.exposed_assumeNotBlacklisted(address(USDC), USDC_BLACKLISTED_USER); + } + + function testFuzz_AssumeNotBlacklisted_USDC(address addr) external view { + assumeNotBlacklisted(address(USDC), addr); + assertFalse(USDCLike(USDC).isBlacklisted(addr)); + } + + function test_RevertIf_AssumeNoBlacklisted_USDT() external { + // We deploy a mock version so we can properly test the revert. + StdCheatsMock stdCheatsMock = new StdCheatsMock(); + vm.expectRevert(); + stdCheatsMock.exposed_assumeNotBlacklisted(address(USDT), USDT_BLACKLISTED_USER); + } + + function testFuzz_AssumeNotBlacklisted_USDT(address addr) external view { + assumeNotBlacklisted(address(USDT), addr); + assertFalse(USDTLike(USDT).isBlackListed(addr)); + } +} + +/// @dev https://etherscan.io/token/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48#readProxyContract +interface USDCLike { + function isBlacklisted(address) external view returns (bool); +} + +/// @dev https://etherscan.io/token/0xdac17f958d2ee523a2206206994597c13d831ec7#readContract +interface USDTLike { + function isBlackListed(address) external view returns (bool); +} + +contract MockUSDT is USDTLike { + mapping(address => bool) private blacklist; + + function isBlackListed(address addr) external view returns (bool) { + return blacklist[addr]; + } + + function setBlacklisted(address addr, bool value) external { + blacklist[addr] = value; + } +} + +contract MockUSDC is USDCLike { + mapping(address => bool) private blacklist; + + function isBlacklisted(address addr) external view returns (bool) { + return blacklist[addr]; + } + + function setBlacklisted(address addr, bool value) external { + blacklist[addr] = value; + } +} + +contract Bar { + constructor() payable { + /// `DEAL` STDCHEAT + totalSupply = 10000e18; + balanceOf[address(this)] = totalSupply; + } + + /// `HOAX` and `CHANGEPRANK` STDCHEATS + function bar(address expectedSender) public payable { + require(msg.sender == expectedSender, "!prank"); + } + + function origin(address expectedSender) public payable { + require(msg.sender == expectedSender, "!prank"); + require(tx.origin == expectedSender, "!prank"); + } + + function origin(address expectedSender, address expectedOrigin) public payable { + require(msg.sender == expectedSender, "!prank"); + require(tx.origin == expectedOrigin, "!prank"); + } + + /// `DEAL` STDCHEAT + mapping(address => uint256) public balanceOf; + uint256 public totalSupply; +} + +contract BarERC1155 { + constructor() payable { + /// `DEALERC1155` STDCHEAT + _totalSupply[0] = 10000e18; + _balances[0][address(this)] = _totalSupply[0]; + } + + function balanceOf(address account, uint256 id) public view virtual returns (uint256) { + return _balances[id][account]; + } + + function totalSupply(uint256 id) public view virtual returns (uint256) { + return _totalSupply[id]; + } + + /// `DEALERC1155` STDCHEAT + mapping(uint256 => mapping(address => uint256)) private _balances; + mapping(uint256 => uint256) private _totalSupply; +} + +contract BarERC721 { + constructor() payable { + /// `DEALERC721` STDCHEAT + _owners[1] = address(1); + _balances[address(1)] = 1; + _owners[2] = address(this); + _owners[3] = address(this); + _balances[address(this)] = 2; + } + + function balanceOf(address owner) public view virtual returns (uint256) { + return _balances[owner]; + } + + function ownerOf(uint256 tokenId) public view virtual returns (address) { + address owner = _owners[tokenId]; + return owner; + } + + mapping(uint256 => address) private _owners; + mapping(address => uint256) private _balances; +} + +contract RevertingContract { + constructor() { + revert(); + } +} + +contract MockContractWithConstructorArgs { + uint256 public immutable x; + bool public y; + bytes20 public z; + + constructor(uint256 _x, bool _y, bytes20 _z) payable { + x = _x; + y = _y; + z = _z; + } +} + +contract MockContractPayable { + receive() external payable {} +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/StdConstants.t.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/StdConstants.t.sol new file mode 100644 index 0000000000..7a00530f48 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/StdConstants.t.sol @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import {StdConstants} from "../src/StdConstants.sol"; +import {Test} from "../src/Test.sol"; + +contract StdConstantsTest is Test { + function testVm() public view { + assertEq(StdConstants.VM.getBlockNumber(), 1); + } + + function testVmDerivation() public pure { + assertEq(address(StdConstants.VM), address(uint160(uint256(keccak256("hevm cheat code"))))); + } + + function testConsoleDerivation() public pure { + assertEq(StdConstants.CONSOLE, address(uint160(uint88(bytes11("console.log"))))); + } + + function testDefaultSender() public view { + assertEq(StdConstants.DEFAULT_SENDER, msg.sender); + } + + function testDefaultSenderDerivation() public pure { + assertEq(StdConstants.DEFAULT_SENDER, address(uint160(uint256(keccak256("foundry default caller"))))); + } + + function testDefaultTestContract() public { + assertEq(StdConstants.DEFAULT_TEST_CONTRACT, address(new Dummy())); + } + + function testDefaultTestContractDerivation() public view { + assertEq(address(this), StdConstants.VM.computeCreateAddress(StdConstants.DEFAULT_SENDER, 1)); + assertEq(StdConstants.DEFAULT_TEST_CONTRACT, StdConstants.VM.computeCreateAddress(address(this), 1)); + } +} + +contract Dummy {} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/StdError.t.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/StdError.t.sol new file mode 100644 index 0000000000..29803d5d52 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/StdError.t.sol @@ -0,0 +1,120 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0 <0.9.0; + +import {stdError} from "../src/StdError.sol"; +import {Test} from "../src/Test.sol"; + +contract StdErrorsTest is Test { + ErrorsTest test; + + function setUp() public { + test = new ErrorsTest(); + } + + function test_RevertIf_AssertionError() public { + vm.expectRevert(stdError.assertionError); + test.assertionError(); + } + + function test_RevertIf_ArithmeticError() public { + vm.expectRevert(stdError.arithmeticError); + test.arithmeticError(10); + } + + function test_RevertIf_DivisionError() public { + vm.expectRevert(stdError.divisionError); + test.divError(0); + } + + function test_RevertIf_ModError() public { + vm.expectRevert(stdError.divisionError); + test.modError(0); + } + + function test_RevertIf_EnumConversionError() public { + vm.expectRevert(stdError.enumConversionError); + test.enumConversion(1); + } + + function test_RevertIf_EncodeStgError() public { + vm.expectRevert(stdError.encodeStorageError); + test.encodeStgError(); + } + + function test_RevertIf_PopError() public { + vm.expectRevert(stdError.popError); + test.pop(); + } + + function test_RevertIf_IndexOOBError() public { + vm.expectRevert(stdError.indexOOBError); + test.indexOOBError(1); + } + + function test_RevertIf_MemOverflowError() public { + vm.expectRevert(stdError.memOverflowError); + test.mem(); + } + + function test_RevertIf_InternError() public { + vm.expectRevert(stdError.zeroVarError); + test.intern(); + } +} + +contract ErrorsTest { + enum T { + T1 + } + + uint256[] public someArr; + bytes someBytes; + + function assertionError() public pure { + assert(false); + } + + function arithmeticError(uint256 a) public pure { + a -= 100; + } + + function divError(uint256 a) public pure { + 100 / a; + } + + function modError(uint256 a) public pure { + 100 % a; + } + + function enumConversion(uint256 a) public pure { + T(a); + } + + function encodeStgError() public { + /// @solidity memory-safe-assembly + assembly { + sstore(someBytes.slot, 1) + } + keccak256(someBytes); + } + + function pop() public { + someArr.pop(); + } + + function indexOOBError(uint256 a) public pure { + uint256[] memory t = new uint256[](0); + t[a]; + } + + function mem() public pure { + uint256 l = 2 ** 256 / 32; + new uint256[](l); + } + + function intern() public returns (uint256) { + function(uint256) internal returns (uint256) x; + x(2); + return 7; + } +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/StdJson.t.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/StdJson.t.sol new file mode 100644 index 0000000000..6bedfcc9a8 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/StdJson.t.sol @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import {Test, stdJson} from "../src/Test.sol"; + +contract StdJsonTest is Test { + using stdJson for string; + + string root; + string path; + + function setUp() public { + root = vm.projectRoot(); + path = string.concat(root, "/test/fixtures/test.json"); + } + + struct SimpleJson { + uint256 a; + string b; + } + + struct NestedJson { + uint256 a; + string b; + SimpleJson c; + } + + function test_readJson() public view { + string memory json = vm.readFile(path); + assertEq(json.readUint(".a"), 123); + } + + function test_writeJson() public { + string memory json = "json"; + json.serialize("a", uint256(123)); + string memory semiFinal = json.serialize("b", string("test")); + string memory finalJson = json.serialize("c", semiFinal); + finalJson.write(path); + + string memory json_ = vm.readFile(path); + bytes memory data = json_.parseRaw("$"); + NestedJson memory decodedData = abi.decode(data, (NestedJson)); + + assertEq(decodedData.a, 123); + assertEq(decodedData.b, "test"); + assertEq(decodedData.c.a, 123); + assertEq(decodedData.c.b, "test"); + } +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/StdMath.t.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/StdMath.t.sol new file mode 100644 index 0000000000..d1269a02ac --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/StdMath.t.sol @@ -0,0 +1,202 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0 <0.9.0; + +import {stdMath} from "../src/StdMath.sol"; +import {Test, stdError} from "../src/Test.sol"; + +contract StdMathMock is Test { + function exposed_percentDelta(uint256 a, uint256 b) public pure returns (uint256) { + return stdMath.percentDelta(a, b); + } + + function exposed_percentDelta(int256 a, int256 b) public pure returns (uint256) { + return stdMath.percentDelta(a, b); + } +} + +contract StdMathTest is Test { + function test_GetAbs() external pure { + assertEq(stdMath.abs(-50), 50); + assertEq(stdMath.abs(50), 50); + assertEq(stdMath.abs(-1337), 1337); + assertEq(stdMath.abs(0), 0); + + assertEq(stdMath.abs(type(int256).min), (type(uint256).max >> 1) + 1); + assertEq(stdMath.abs(type(int256).max), (type(uint256).max >> 1)); + } + + function testFuzz_GetAbs(int256 a) external pure { + uint256 manualAbs = getAbs(a); + + uint256 abs = stdMath.abs(a); + + assertEq(abs, manualAbs); + } + + function test_GetDelta_Uint() external pure { + assertEq(stdMath.delta(uint256(0), uint256(0)), 0); + assertEq(stdMath.delta(uint256(0), uint256(1337)), 1337); + assertEq(stdMath.delta(uint256(0), type(uint64).max), type(uint64).max); + assertEq(stdMath.delta(uint256(0), type(uint128).max), type(uint128).max); + assertEq(stdMath.delta(uint256(0), type(uint256).max), type(uint256).max); + + assertEq(stdMath.delta(0, uint256(0)), 0); + assertEq(stdMath.delta(1337, uint256(0)), 1337); + assertEq(stdMath.delta(type(uint64).max, uint256(0)), type(uint64).max); + assertEq(stdMath.delta(type(uint128).max, uint256(0)), type(uint128).max); + assertEq(stdMath.delta(type(uint256).max, uint256(0)), type(uint256).max); + + assertEq(stdMath.delta(1337, uint256(1337)), 0); + assertEq(stdMath.delta(type(uint256).max, type(uint256).max), 0); + assertEq(stdMath.delta(5000, uint256(1250)), 3750); + } + + function testFuzz_GetDelta_Uint(uint256 a, uint256 b) external pure { + uint256 manualDelta = a > b ? a - b : b - a; + + uint256 delta = stdMath.delta(a, b); + + assertEq(delta, manualDelta); + } + + function test_GetDelta_Int() external pure { + assertEq(stdMath.delta(int256(0), int256(0)), 0); + assertEq(stdMath.delta(int256(0), int256(1337)), 1337); + assertEq(stdMath.delta(int256(0), type(int64).max), type(uint64).max >> 1); + assertEq(stdMath.delta(int256(0), type(int128).max), type(uint128).max >> 1); + assertEq(stdMath.delta(int256(0), type(int256).max), type(uint256).max >> 1); + + assertEq(stdMath.delta(0, int256(0)), 0); + assertEq(stdMath.delta(1337, int256(0)), 1337); + assertEq(stdMath.delta(type(int64).max, int256(0)), type(uint64).max >> 1); + assertEq(stdMath.delta(type(int128).max, int256(0)), type(uint128).max >> 1); + assertEq(stdMath.delta(type(int256).max, int256(0)), type(uint256).max >> 1); + + assertEq(stdMath.delta(-0, int256(0)), 0); + assertEq(stdMath.delta(-1337, int256(0)), 1337); + assertEq(stdMath.delta(type(int64).min, int256(0)), (type(uint64).max >> 1) + 1); + assertEq(stdMath.delta(type(int128).min, int256(0)), (type(uint128).max >> 1) + 1); + assertEq(stdMath.delta(type(int256).min, int256(0)), (type(uint256).max >> 1) + 1); + + assertEq(stdMath.delta(int256(0), -0), 0); + assertEq(stdMath.delta(int256(0), -1337), 1337); + assertEq(stdMath.delta(int256(0), type(int64).min), (type(uint64).max >> 1) + 1); + assertEq(stdMath.delta(int256(0), type(int128).min), (type(uint128).max >> 1) + 1); + assertEq(stdMath.delta(int256(0), type(int256).min), (type(uint256).max >> 1) + 1); + + assertEq(stdMath.delta(1337, int256(1337)), 0); + assertEq(stdMath.delta(type(int256).max, type(int256).max), 0); + assertEq(stdMath.delta(type(int256).min, type(int256).min), 0); + assertEq(stdMath.delta(type(int256).min, type(int256).max), type(uint256).max); + assertEq(stdMath.delta(5000, int256(1250)), 3750); + } + + function testFuzz_GetDelta_Int(int256 a, int256 b) external pure { + uint256 absA = getAbs(a); + uint256 absB = getAbs(b); + uint256 absDelta = absA > absB ? absA - absB : absB - absA; + + uint256 manualDelta; + if ((a >= 0 && b >= 0) || (a < 0 && b < 0)) { + manualDelta = absDelta; + } + // (a < 0 && b >= 0) || (a >= 0 && b < 0) + else { + manualDelta = absA + absB; + } + + uint256 delta = stdMath.delta(a, b); + + assertEq(delta, manualDelta); + } + + function test_GetPercentDelta_Uint() external { + StdMathMock stdMathMock = new StdMathMock(); + + assertEq(stdMath.percentDelta(uint256(0), uint256(1337)), 1e18); + assertEq(stdMath.percentDelta(uint256(0), type(uint64).max), 1e18); + assertEq(stdMath.percentDelta(uint256(0), type(uint128).max), 1e18); + assertEq(stdMath.percentDelta(uint256(0), type(uint192).max), 1e18); + + assertEq(stdMath.percentDelta(1337, uint256(1337)), 0); + assertEq(stdMath.percentDelta(type(uint192).max, type(uint192).max), 0); + assertEq(stdMath.percentDelta(0, uint256(2500)), 1e18); + assertEq(stdMath.percentDelta(2500, uint256(2500)), 0); + assertEq(stdMath.percentDelta(5000, uint256(2500)), 1e18); + assertEq(stdMath.percentDelta(7500, uint256(2500)), 2e18); + + vm.expectRevert(stdError.divisionError); + stdMathMock.exposed_percentDelta(uint256(1), 0); + } + + function testFuzz_GetPercentDelta_Uint(uint192 a, uint192 b) external pure { + vm.assume(b != 0); + uint256 manualDelta = a > b ? a - b : b - a; + + uint256 manualPercentDelta = manualDelta * 1e18 / b; + uint256 percentDelta = stdMath.percentDelta(a, b); + + assertEq(percentDelta, manualPercentDelta); + } + + function test_GetPercentDelta_Int() external { + // We deploy a mock version so we can properly test the revert. + StdMathMock stdMathMock = new StdMathMock(); + + assertEq(stdMath.percentDelta(int256(0), int256(1337)), 1e18); + assertEq(stdMath.percentDelta(int256(0), -1337), 1e18); + assertEq(stdMath.percentDelta(int256(0), type(int64).min), 1e18); + assertEq(stdMath.percentDelta(int256(0), type(int128).min), 1e18); + assertEq(stdMath.percentDelta(int256(0), type(int192).min), 1e18); + assertEq(stdMath.percentDelta(int256(0), type(int64).max), 1e18); + assertEq(stdMath.percentDelta(int256(0), type(int128).max), 1e18); + assertEq(stdMath.percentDelta(int256(0), type(int192).max), 1e18); + + assertEq(stdMath.percentDelta(1337, int256(1337)), 0); + assertEq(stdMath.percentDelta(type(int192).max, type(int192).max), 0); + assertEq(stdMath.percentDelta(type(int192).min, type(int192).min), 0); + + assertEq(stdMath.percentDelta(type(int192).min, type(int192).max), 2e18); // rounds the 1 wei diff down + assertEq(stdMath.percentDelta(type(int192).max, type(int192).min), 2e18 - 1); // rounds the 1 wei diff down + assertEq(stdMath.percentDelta(0, int256(2500)), 1e18); + assertEq(stdMath.percentDelta(2500, int256(2500)), 0); + assertEq(stdMath.percentDelta(5000, int256(2500)), 1e18); + assertEq(stdMath.percentDelta(7500, int256(2500)), 2e18); + + vm.expectRevert(stdError.divisionError); + stdMathMock.exposed_percentDelta(int256(1), 0); + } + + function testFuzz_GetPercentDelta_Int(int192 a, int192 b) external pure { + vm.assume(b != 0); + uint256 absA = getAbs(a); + uint256 absB = getAbs(b); + uint256 absDelta = absA > absB ? absA - absB : absB - absA; + + uint256 manualDelta; + if ((a >= 0 && b >= 0) || (a < 0 && b < 0)) { + manualDelta = absDelta; + } + // (a < 0 && b >= 0) || (a >= 0 && b < 0) + else { + manualDelta = absA + absB; + } + + uint256 manualPercentDelta = manualDelta * 1e18 / absB; + uint256 percentDelta = stdMath.percentDelta(a, b); + + assertEq(percentDelta, manualPercentDelta); + } + + /*////////////////////////////////////////////////////////////////////////// + HELPERS + //////////////////////////////////////////////////////////////////////////*/ + + function getAbs(int256 a) private pure returns (uint256) { + if (a < 0) { + return a == type(int256).min ? uint256(type(int256).max) + 1 : uint256(-a); + } + + return uint256(a); + } +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/StdStorage.t.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/StdStorage.t.sol new file mode 100644 index 0000000000..46604f8668 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/StdStorage.t.sol @@ -0,0 +1,488 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import {stdStorage, StdStorage} from "../src/StdStorage.sol"; +import {Test} from "../src/Test.sol"; + +contract StdStorageTest is Test { + using stdStorage for StdStorage; + + StorageTest internal test; + + function setUp() public { + test = new StorageTest(); + } + + function test_StorageHidden() public { + assertEq(uint256(keccak256("my.random.var")), stdstore.target(address(test)).sig("hidden()").find()); + } + + function test_StorageObvious() public { + assertEq(uint256(0), stdstore.target(address(test)).sig("exists()").find()); + } + + function test_StorageExtraSload() public { + assertEq(16, stdstore.target(address(test)).sig(test.extra_sload.selector).find()); + } + + function test_StorageCheckedWriteHidden() public { + stdstore.target(address(test)).sig(test.hidden.selector).checked_write(100); + assertEq(uint256(test.hidden()), 100); + } + + function test_StorageCheckedWriteObvious() public { + stdstore.target(address(test)).sig(test.exists.selector).checked_write(100); + assertEq(test.exists(), 100); + } + + function test_StorageCheckedWriteSignedIntegerHidden() public { + stdstore.target(address(test)).sig(test.hidden.selector).checked_write_int(-100); + assertEq(int256(uint256(test.hidden())), -100); + } + + function test_StorageCheckedWriteSignedIntegerObvious() public { + stdstore.target(address(test)).sig(test.tG.selector).checked_write_int(-100); + assertEq(test.tG(), -100); + } + + function test_StorageMapStructA() public { + uint256 slot = + stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(0).find(); + assertEq(uint256(keccak256(abi.encode(address(this), 4))), slot); + } + + function test_StorageMapStructB() public { + uint256 slot = + stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(1).find(); + assertEq(uint256(keccak256(abi.encode(address(this), 4))) + 1, slot); + } + + function test_StorageDeepMap() public { + uint256 slot = stdstore.target(address(test)).sig(test.deep_map.selector).with_key(address(this)).with_key( + address(this) + ).find(); + assertEq(uint256(keccak256(abi.encode(address(this), keccak256(abi.encode(address(this), uint256(5)))))), slot); + } + + function test_StorageCheckedWriteDeepMap() public { + stdstore.target(address(test)).sig(test.deep_map.selector).with_key(address(this)).with_key(address(this)) + .checked_write(100); + assertEq(100, test.deep_map(address(this), address(this))); + } + + function test_StorageDeepMapStructA() public { + uint256 slot = stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)) + .with_key(address(this)).depth(0).find(); + assertEq( + bytes32(uint256(keccak256(abi.encode(address(this), keccak256(abi.encode(address(this), uint256(6)))))) + 0), + bytes32(slot) + ); + } + + function test_StorageDeepMapStructB() public { + uint256 slot = stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)) + .with_key(address(this)).depth(1).find(); + assertEq( + bytes32(uint256(keccak256(abi.encode(address(this), keccak256(abi.encode(address(this), uint256(6)))))) + 1), + bytes32(slot) + ); + } + + function test_StorageCheckedWriteDeepMapStructA() public { + stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)).with_key( + address(this) + ).depth(0).checked_write(100); + (uint256 a, uint256 b) = test.deep_map_struct(address(this), address(this)); + assertEq(100, a); + assertEq(0, b); + } + + function test_StorageCheckedWriteDeepMapStructB() public { + stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)).with_key( + address(this) + ).depth(1).checked_write(100); + (uint256 a, uint256 b) = test.deep_map_struct(address(this), address(this)); + assertEq(0, a); + assertEq(100, b); + } + + function test_StorageCheckedWriteMapStructA() public { + stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(0).checked_write(100); + (uint256 a, uint256 b) = test.map_struct(address(this)); + assertEq(a, 100); + assertEq(b, 0); + } + + function test_StorageCheckedWriteMapStructB() public { + stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(1).checked_write(100); + (uint256 a, uint256 b) = test.map_struct(address(this)); + assertEq(a, 0); + assertEq(b, 100); + } + + function test_StorageStructA() public { + uint256 slot = stdstore.target(address(test)).sig(test.basic.selector).depth(0).find(); + assertEq(uint256(7), slot); + } + + function test_StorageStructB() public { + uint256 slot = stdstore.target(address(test)).sig(test.basic.selector).depth(1).find(); + assertEq(uint256(7) + 1, slot); + } + + function test_StorageCheckedWriteStructA() public { + stdstore.target(address(test)).sig(test.basic.selector).depth(0).checked_write(100); + (uint256 a, uint256 b) = test.basic(); + assertEq(a, 100); + assertEq(b, 1337); + } + + function test_StorageCheckedWriteStructB() public { + stdstore.target(address(test)).sig(test.basic.selector).depth(1).checked_write(100); + (uint256 a, uint256 b) = test.basic(); + assertEq(a, 1337); + assertEq(b, 100); + } + + function test_StorageMapAddrFound() public { + uint256 slot = stdstore.target(address(test)).sig(test.map_addr.selector).with_key(address(this)).find(); + assertEq(uint256(keccak256(abi.encode(address(this), uint256(1)))), slot); + } + + function test_StorageMapAddrRoot() public { + (uint256 slot, bytes32 key) = + stdstore.target(address(test)).sig(test.map_addr.selector).with_key(address(this)).parent(); + assertEq(address(uint160(uint256(key))), address(this)); + assertEq(uint256(1), slot); + slot = stdstore.target(address(test)).sig(test.map_addr.selector).with_key(address(this)).root(); + assertEq(uint256(1), slot); + } + + function test_StorageMapUintFound() public { + uint256 slot = stdstore.target(address(test)).sig(test.map_uint.selector).with_key(100).find(); + assertEq(uint256(keccak256(abi.encode(100, uint256(2)))), slot); + } + + function test_StorageCheckedWriteMapUint() public { + stdstore.target(address(test)).sig(test.map_uint.selector).with_key(100).checked_write(100); + assertEq(100, test.map_uint(100)); + } + + function test_StorageCheckedWriteMapAddr() public { + stdstore.target(address(test)).sig(test.map_addr.selector).with_key(address(this)).checked_write(100); + assertEq(100, test.map_addr(address(this))); + } + + function test_StorageCheckedWriteMapBool() public { + stdstore.target(address(test)).sig(test.map_bool.selector).with_key(address(this)).checked_write(true); + assertTrue(test.map_bool(address(this))); + } + + function testFuzz_StorageCheckedWriteMapPacked(address addr, uint128 value) public { + stdstore.enable_packed_slots().target(address(test)).sig(test.read_struct_lower.selector).with_key(addr) + .checked_write(value); + assertEq(test.read_struct_lower(addr), value); + + stdstore.enable_packed_slots().target(address(test)).sig(test.read_struct_upper.selector).with_key(addr) + .checked_write(value); + assertEq(test.read_struct_upper(addr), value); + } + + function test_StorageCheckedWriteMapPackedFullSuccess() public { + uint256 full = test.map_packed(address(1337)); + // keep upper 128, set lower 128 to 1337 + full = (full & (uint256((1 << 128) - 1) << 128)) | 1337; + stdstore.target(address(test)).sig(test.map_packed.selector).with_key(address(uint160(1337))).checked_write( + full + ); + assertEq(1337, test.read_struct_lower(address(1337))); + } + + function test_RevertStorageConst() public { + StorageTestTarget target = new StorageTestTarget(test); + + vm.expectRevert("stdStorage find(StdStorage): No storage use detected for target."); + target.expectRevertStorageConst(); + } + + function testFuzz_StorageNativePack(uint248 val1, uint248 val2, bool boolVal1, bool boolVal2) public { + stdstore.enable_packed_slots().target(address(test)).sig(test.tA.selector).checked_write(val1); + stdstore.enable_packed_slots().target(address(test)).sig(test.tB.selector).checked_write(boolVal1); + stdstore.enable_packed_slots().target(address(test)).sig(test.tC.selector).checked_write(boolVal2); + stdstore.enable_packed_slots().target(address(test)).sig(test.tD.selector).checked_write(val2); + + assertEq(test.tA(), val1); + assertEq(test.tB(), boolVal1); + assertEq(test.tC(), boolVal2); + assertEq(test.tD(), val2); + } + + function test_StorageReadBytes32() public { + bytes32 val = stdstore.target(address(test)).sig(test.tE.selector).read_bytes32(); + assertEq(val, hex"1337"); + } + + function test_StorageReadBool_False() public { + bool val = stdstore.target(address(test)).sig(test.tB.selector).read_bool(); + assertEq(val, false); + } + + function test_StorageReadBool_True() public { + bool val = stdstore.target(address(test)).sig(test.tH.selector).read_bool(); + assertEq(val, true); + } + + function test_RevertIf_ReadingNonBoolValue() public { + vm.expectRevert("stdStorage read_bool(StdStorage): Cannot decode. Make sure you are reading a bool."); + this.readNonBoolValue(); + } + + function readNonBoolValue() public { + stdstore.target(address(test)).sig(test.tE.selector).read_bool(); + } + + function test_StorageReadAddress() public { + address val = stdstore.target(address(test)).sig(test.tF.selector).read_address(); + assertEq(val, address(1337)); + } + + function test_StorageReadUint() public { + uint256 val = stdstore.target(address(test)).sig(test.exists.selector).read_uint(); + assertEq(val, 1); + } + + function test_StorageReadInt() public { + int256 val = stdstore.target(address(test)).sig(test.tG.selector).read_int(); + assertEq(val, type(int256).min); + } + + function testFuzz_Packed(uint256 val, uint8 elemToGet) public { + // This function tries an assortment of packed slots, shifts meaning number of elements + // that are packed. Shiftsizes are the size of each element, i.e. 8 means a data type that is 8 bits, 16 == 16 bits, etc. + // Combined, these determine how a slot is packed. Making it random is too hard to avoid global rejection limit + // and make it performant. + + // change the number of shifts + for (uint256 i = 1; i < 5; i++) { + uint256 shifts = i; + + elemToGet = uint8(bound(elemToGet, 0, shifts - 1)); + + uint256[] memory shiftSizes = new uint256[](shifts); + for (uint256 j; j < shifts; j++) { + shiftSizes[j] = 8 * (j + 1); + } + + test.setRandomPacking(val); + + uint256 leftBits; + uint256 rightBits; + for (uint256 j; j < shiftSizes.length; j++) { + if (j < elemToGet) { + leftBits += shiftSizes[j]; + } else if (elemToGet != j) { + rightBits += shiftSizes[j]; + } + } + + // we may have some right bits unaccounted for + leftBits += 256 - (leftBits + shiftSizes[elemToGet] + rightBits); + // clear left bits, then clear right bits and realign + uint256 expectedValToRead = (val << leftBits) >> (leftBits + rightBits); + + uint256 readVal = stdstore.target(address(test)).enable_packed_slots().sig( + "getRandomPacked(uint8,uint8[],uint8)" + ).with_calldata(abi.encode(shifts, shiftSizes, elemToGet)).read_uint(); + + assertEq(readVal, expectedValToRead); + } + } + + function testFuzz_Packed2(uint256 nvars, uint256 seed) public { + // Number of random variables to generate. + nvars = bound(nvars, 1, 20); + + // This will decrease as we generate values in the below loop. + uint256 bitsRemaining = 256; + + // Generate a random value and size for each variable. + uint256[] memory vals = new uint256[](nvars); + uint256[] memory sizes = new uint256[](nvars); + uint256[] memory offsets = new uint256[](nvars); + + for (uint256 i = 0; i < nvars; i++) { + // Generate a random value and size. + offsets[i] = i == 0 ? 0 : offsets[i - 1] + sizes[i - 1]; + + uint256 nvarsRemaining = nvars - i; + uint256 maxVarSize = bitsRemaining - nvarsRemaining + 1; + sizes[i] = bound(uint256(keccak256(abi.encodePacked(seed, i + 256))), 1, maxVarSize); + bitsRemaining -= sizes[i]; + + uint256 maxVal; + uint256 varSize = sizes[i]; + assembly { + // mask = (1 << varSize) - 1 + maxVal := sub(shl(varSize, 1), 1) + } + vals[i] = bound(uint256(keccak256(abi.encodePacked(seed, i))), 0, maxVal); + } + + // Pack all values into the slot. + for (uint256 i = 0; i < nvars; i++) { + stdstore.enable_packed_slots().target(address(test)).sig("getRandomPacked(uint256,uint256)").with_key( + sizes[i] + ).with_key(offsets[i]).checked_write(vals[i]); + } + + // Verify the read data matches. + for (uint256 i = 0; i < nvars; i++) { + uint256 readVal = stdstore.enable_packed_slots().target(address(test)).sig( + "getRandomPacked(uint256,uint256)" + ).with_key(sizes[i]).with_key(offsets[i]).read_uint(); + + uint256 retVal = test.getRandomPacked(sizes[i], offsets[i]); + + assertEq(readVal, vals[i]); + assertEq(retVal, vals[i]); + } + } + + function testEdgeCaseArray() public { + stdstore.target(address(test)).sig("edgeCaseArray(uint256)").with_key(uint256(0)).checked_write(1); + assertEq(test.edgeCaseArray(0), 1); + } +} + +contract StorageTestTarget { + using stdStorage for StdStorage; + + StdStorage internal stdstore; + StorageTest internal test; + + constructor(StorageTest test_) { + test = test_; + } + + function expectRevertStorageConst() public { + stdstore.target(address(test)).sig("const()").find(); + } +} + +contract StorageTest { + uint256 public exists = 1; + mapping(address => uint256) public map_addr; + mapping(uint256 => uint256) public map_uint; + mapping(address => uint256) public map_packed; + mapping(address => UnpackedStruct) public map_struct; + mapping(address => mapping(address => uint256)) public deep_map; + mapping(address => mapping(address => UnpackedStruct)) public deep_map_struct; + UnpackedStruct public basic; + + uint248 public tA; + bool public tB; + + bool public tC = false; + uint248 public tD = 1; + + struct UnpackedStruct { + uint256 a; + uint256 b; + } + + mapping(address => bool) public map_bool; + + bytes32 public tE = hex"1337"; + address public tF = address(1337); + int256 public tG = type(int256).min; + bool public tH = true; + bytes32 private tI = ~bytes32(hex"1337"); + + uint256 randomPacking; + + // Array with length matching values of elements. + uint256[] public edgeCaseArray = [3, 3, 3]; + + constructor() { + basic = UnpackedStruct({a: 1337, b: 1337}); + + uint256 two = (1 << 128) | 1; + map_packed[msg.sender] = two; + map_packed[address(uint160(1337))] = 1 << 128; + } + + function read_struct_upper(address who) public view returns (uint256) { + return map_packed[who] >> 128; + } + + function read_struct_lower(address who) public view returns (uint256) { + return map_packed[who] & ((1 << 128) - 1); + } + + function hidden() public view returns (bytes32 t) { + bytes32 slot = keccak256("my.random.var"); + /// @solidity memory-safe-assembly + assembly { + t := sload(slot) + } + } + + function const() public pure returns (bytes32 t) { + t = bytes32(hex"1337"); + } + + function extra_sload() public view returns (bytes32 t) { + // trigger read on slot `tE`, and make a staticcall to make sure compiler doesn't optimize this SLOAD away + assembly { + pop(staticcall(gas(), sload(tE.slot), 0, 0, 0, 0)) + } + t = tI; + } + + function setRandomPacking(uint256 val) public { + randomPacking = val; + } + + function _getMask(uint256 size) internal pure returns (uint256 mask) { + assembly { + // mask = (1 << size) - 1 + mask := sub(shl(size, 1), 1) + } + } + + function setRandomPacking(uint256 val, uint256 size, uint256 offset) public { + // Generate mask based on the size of the value + uint256 mask = _getMask(size); + // Zero out all bits for the word we're about to set + uint256 cleanedWord = randomPacking & ~(mask << offset); + // Place val in the correct spot of the cleaned word + randomPacking = cleanedWord | val << offset; + } + + function getRandomPacked(uint256 size, uint256 offset) public view returns (uint256) { + // Generate mask based on the size of the value + uint256 mask = _getMask(size); + // Shift to place the bits in the correct position, and use mask to zero out remaining bits + return (randomPacking >> offset) & mask; + } + + function getRandomPacked(uint8 shifts, uint8[] memory shiftSizes, uint8 elem) public view returns (uint256) { + require(elem < shifts, "!elem"); + uint256 leftBits; + uint256 rightBits; + + for (uint256 i; i < shiftSizes.length; i++) { + if (i < elem) { + leftBits += shiftSizes[i]; + } else if (elem != i) { + rightBits += shiftSizes[i]; + } + } + + // we may have some right bits unaccounted for + leftBits += 256 - (leftBits + shiftSizes[elem] + rightBits); + + // clear left bits, then clear right bits and realign + return (randomPacking << leftBits) >> (leftBits + rightBits); + } +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/StdStyle.t.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/StdStyle.t.sol new file mode 100644 index 0000000000..974e756fe5 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/StdStyle.t.sol @@ -0,0 +1,110 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import {Test, console2, StdStyle} from "../src/Test.sol"; + +contract StdStyleTest is Test { + function test_StyleColor() public pure { + console2.log(StdStyle.red("StdStyle.red String Test")); + console2.log(StdStyle.red(uint256(10e18))); + console2.log(StdStyle.red(int256(-10e18))); + console2.log(StdStyle.red(true)); + console2.log(StdStyle.red(address(0))); + console2.log(StdStyle.redBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.redBytes32("StdStyle.redBytes32")); + console2.log(StdStyle.green("StdStyle.green String Test")); + console2.log(StdStyle.green(uint256(10e18))); + console2.log(StdStyle.green(int256(-10e18))); + console2.log(StdStyle.green(true)); + console2.log(StdStyle.green(address(0))); + console2.log(StdStyle.greenBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.greenBytes32("StdStyle.greenBytes32")); + console2.log(StdStyle.yellow("StdStyle.yellow String Test")); + console2.log(StdStyle.yellow(uint256(10e18))); + console2.log(StdStyle.yellow(int256(-10e18))); + console2.log(StdStyle.yellow(true)); + console2.log(StdStyle.yellow(address(0))); + console2.log(StdStyle.yellowBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.yellowBytes32("StdStyle.yellowBytes32")); + console2.log(StdStyle.blue("StdStyle.blue String Test")); + console2.log(StdStyle.blue(uint256(10e18))); + console2.log(StdStyle.blue(int256(-10e18))); + console2.log(StdStyle.blue(true)); + console2.log(StdStyle.blue(address(0))); + console2.log(StdStyle.blueBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.blueBytes32("StdStyle.blueBytes32")); + console2.log(StdStyle.magenta("StdStyle.magenta String Test")); + console2.log(StdStyle.magenta(uint256(10e18))); + console2.log(StdStyle.magenta(int256(-10e18))); + console2.log(StdStyle.magenta(true)); + console2.log(StdStyle.magenta(address(0))); + console2.log(StdStyle.magentaBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.magentaBytes32("StdStyle.magentaBytes32")); + console2.log(StdStyle.cyan("StdStyle.cyan String Test")); + console2.log(StdStyle.cyan(uint256(10e18))); + console2.log(StdStyle.cyan(int256(-10e18))); + console2.log(StdStyle.cyan(true)); + console2.log(StdStyle.cyan(address(0))); + console2.log(StdStyle.cyanBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.cyanBytes32("StdStyle.cyanBytes32")); + } + + function test_StyleFontWeight() public pure { + console2.log(StdStyle.bold("StdStyle.bold String Test")); + console2.log(StdStyle.bold(uint256(10e18))); + console2.log(StdStyle.bold(int256(-10e18))); + console2.log(StdStyle.bold(address(0))); + console2.log(StdStyle.bold(true)); + console2.log(StdStyle.boldBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.boldBytes32("StdStyle.boldBytes32")); + console2.log(StdStyle.dim("StdStyle.dim String Test")); + console2.log(StdStyle.dim(uint256(10e18))); + console2.log(StdStyle.dim(int256(-10e18))); + console2.log(StdStyle.dim(address(0))); + console2.log(StdStyle.dim(true)); + console2.log(StdStyle.dimBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.dimBytes32("StdStyle.dimBytes32")); + console2.log(StdStyle.italic("StdStyle.italic String Test")); + console2.log(StdStyle.italic(uint256(10e18))); + console2.log(StdStyle.italic(int256(-10e18))); + console2.log(StdStyle.italic(address(0))); + console2.log(StdStyle.italic(true)); + console2.log(StdStyle.italicBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.italicBytes32("StdStyle.italicBytes32")); + console2.log(StdStyle.underline("StdStyle.underline String Test")); + console2.log(StdStyle.underline(uint256(10e18))); + console2.log(StdStyle.underline(int256(-10e18))); + console2.log(StdStyle.underline(address(0))); + console2.log(StdStyle.underline(true)); + console2.log(StdStyle.underlineBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.underlineBytes32("StdStyle.underlineBytes32")); + console2.log(StdStyle.inverse("StdStyle.inverse String Test")); + console2.log(StdStyle.inverse(uint256(10e18))); + console2.log(StdStyle.inverse(int256(-10e18))); + console2.log(StdStyle.inverse(address(0))); + console2.log(StdStyle.inverse(true)); + console2.log(StdStyle.inverseBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.inverseBytes32("StdStyle.inverseBytes32")); + } + + function test_StyleCombined() public pure { + console2.log(StdStyle.red(StdStyle.bold("Red Bold String Test"))); + console2.log(StdStyle.green(StdStyle.dim(uint256(10e18)))); + console2.log(StdStyle.yellow(StdStyle.italic(int256(-10e18)))); + console2.log(StdStyle.blue(StdStyle.underline(address(0)))); + console2.log(StdStyle.magenta(StdStyle.inverse(true))); + } + + function test_StyleCustom() public pure { + console2.log(h1("Custom Style 1")); + console2.log(h2("Custom Style 2")); + } + + function h1(string memory a) private pure returns (string memory) { + return StdStyle.cyan(StdStyle.inverse(StdStyle.bold(a))); + } + + function h2(string memory a) private pure returns (string memory) { + return StdStyle.magenta(StdStyle.bold(StdStyle.underline(a))); + } +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/StdToml.t.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/StdToml.t.sol new file mode 100644 index 0000000000..5a45f4f5c9 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/StdToml.t.sol @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import {Test, stdToml} from "../src/Test.sol"; + +contract StdTomlTest is Test { + using stdToml for string; + + string root; + string path; + + function setUp() public { + root = vm.projectRoot(); + path = string.concat(root, "/test/fixtures/test.toml"); + } + + struct SimpleToml { + uint256 a; + string b; + } + + struct NestedToml { + uint256 a; + string b; + SimpleToml c; + } + + function test_readToml() public view { + string memory json = vm.readFile(path); + assertEq(json.readUint(".a"), 123); + } + + function test_writeToml() public { + string memory json = "json"; + json.serialize("a", uint256(123)); + string memory semiFinal = json.serialize("b", string("test")); + string memory finalJson = json.serialize("c", semiFinal); + finalJson.write(path); + + string memory toml = vm.readFile(path); + bytes memory data = toml.parseRaw("$"); + NestedToml memory decodedData = abi.decode(data, (NestedToml)); + + assertEq(decodedData.a, 123); + assertEq(decodedData.b, "test"); + assertEq(decodedData.c.a, 123); + assertEq(decodedData.c.b, "test"); + } +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/StdUtils.t.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/StdUtils.t.sol new file mode 100644 index 0000000000..aee801b2cf --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/StdUtils.t.sol @@ -0,0 +1,342 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import {Test, StdUtils} from "../src/Test.sol"; + +contract StdUtilsMock is StdUtils { + // We deploy a mock version so we can properly test expected reverts. + function exposed_getTokenBalances(address token, address[] memory addresses) + external + returns (uint256[] memory balances) + { + return getTokenBalances(token, addresses); + } + + function exposed_bound(int256 num, int256 min, int256 max) external pure returns (int256) { + return bound(num, min, max); + } + + function exposed_bound(uint256 num, uint256 min, uint256 max) external pure returns (uint256) { + return bound(num, min, max); + } + + function exposed_bytesToUint(bytes memory b) external pure returns (uint256) { + return bytesToUint(b); + } +} + +contract StdUtilsTest is Test { + /*////////////////////////////////////////////////////////////////////////// + BOUND UINT + //////////////////////////////////////////////////////////////////////////*/ + + function test_Bound() public pure { + assertEq(bound(uint256(5), 0, 4), 0); + assertEq(bound(uint256(0), 69, 69), 69); + assertEq(bound(uint256(0), 68, 69), 68); + assertEq(bound(uint256(10), 150, 190), 174); + assertEq(bound(uint256(300), 2800, 3200), 3107); + assertEq(bound(uint256(9999), 1337, 6666), 4669); + } + + function test_Bound_WithinRange() public pure { + assertEq(bound(uint256(51), 50, 150), 51); + assertEq(bound(uint256(51), 50, 150), bound(bound(uint256(51), 50, 150), 50, 150)); + assertEq(bound(uint256(149), 50, 150), 149); + assertEq(bound(uint256(149), 50, 150), bound(bound(uint256(149), 50, 150), 50, 150)); + } + + function test_Bound_EdgeCoverage() public pure { + assertEq(bound(uint256(0), 50, 150), 50); + assertEq(bound(uint256(1), 50, 150), 51); + assertEq(bound(uint256(2), 50, 150), 52); + assertEq(bound(uint256(3), 50, 150), 53); + assertEq(bound(type(uint256).max, 50, 150), 150); + assertEq(bound(type(uint256).max - 1, 50, 150), 149); + assertEq(bound(type(uint256).max - 2, 50, 150), 148); + assertEq(bound(type(uint256).max - 3, 50, 150), 147); + } + + function testFuzz_Bound_DistributionIsEven(uint256 min, uint256 size) public pure { + size = size % 100 + 1; + min = bound(min, UINT256_MAX / 2, UINT256_MAX / 2 + size); + uint256 max = min + size - 1; + uint256 result; + + for (uint256 i = 1; i <= size * 4; ++i) { + // x > max + result = bound(max + i, min, max); + assertEq(result, min + (i - 1) % size); + // x < min + result = bound(min - i, min, max); + assertEq(result, max - (i - 1) % size); + } + } + + function testFuzz_Bound(uint256 num, uint256 min, uint256 max) public pure { + if (min > max) (min, max) = (max, min); + + uint256 result = bound(num, min, max); + + assertGe(result, min); + assertLe(result, max); + assertEq(result, bound(result, min, max)); + if (num >= min && num <= max) assertEq(result, num); + } + + function test_BoundUint256Max() public pure { + assertEq(bound(0, type(uint256).max - 1, type(uint256).max), type(uint256).max - 1); + assertEq(bound(1, type(uint256).max - 1, type(uint256).max), type(uint256).max); + } + + function test_RevertIf_BoundMaxLessThanMin() public { + // We deploy a mock version so we can properly test the revert. + StdUtilsMock stdUtils = new StdUtilsMock(); + + vm.expectRevert(bytes("StdUtils bound(uint256,uint256,uint256): Max is less than min.")); + stdUtils.exposed_bound(uint256(5), 100, 10); + } + + function testFuzz_RevertIf_BoundMaxLessThanMin(uint256 num, uint256 min, uint256 max) public { + // We deploy a mock version so we can properly test the revert. + StdUtilsMock stdUtils = new StdUtilsMock(); + + vm.assume(min > max); + vm.expectRevert(bytes("StdUtils bound(uint256,uint256,uint256): Max is less than min.")); + stdUtils.exposed_bound(num, min, max); + } + + /*////////////////////////////////////////////////////////////////////////// + BOUND INT + //////////////////////////////////////////////////////////////////////////*/ + + function test_BoundInt() public pure { + assertEq(bound(-3, 0, 4), 2); + assertEq(bound(0, -69, -69), -69); + assertEq(bound(0, -69, -68), -68); + assertEq(bound(-10, 150, 190), 154); + assertEq(bound(-300, 2800, 3200), 2908); + assertEq(bound(9999, -1337, 6666), 1995); + } + + function test_BoundInt_WithinRange() public pure { + assertEq(bound(51, -50, 150), 51); + assertEq(bound(51, -50, 150), bound(bound(51, -50, 150), -50, 150)); + assertEq(bound(149, -50, 150), 149); + assertEq(bound(149, -50, 150), bound(bound(149, -50, 150), -50, 150)); + } + + function test_BoundInt_EdgeCoverage() public pure { + assertEq(bound(type(int256).min, -50, 150), -50); + assertEq(bound(type(int256).min + 1, -50, 150), -49); + assertEq(bound(type(int256).min + 2, -50, 150), -48); + assertEq(bound(type(int256).min + 3, -50, 150), -47); + assertEq(bound(type(int256).min, 10, 150), 10); + assertEq(bound(type(int256).min + 1, 10, 150), 11); + assertEq(bound(type(int256).min + 2, 10, 150), 12); + assertEq(bound(type(int256).min + 3, 10, 150), 13); + + assertEq(bound(type(int256).max, -50, 150), 150); + assertEq(bound(type(int256).max - 1, -50, 150), 149); + assertEq(bound(type(int256).max - 2, -50, 150), 148); + assertEq(bound(type(int256).max - 3, -50, 150), 147); + assertEq(bound(type(int256).max, -50, -10), -10); + assertEq(bound(type(int256).max - 1, -50, -10), -11); + assertEq(bound(type(int256).max - 2, -50, -10), -12); + assertEq(bound(type(int256).max - 3, -50, -10), -13); + } + + function testFuzz_BoundInt_DistributionIsEven(int256 min, uint256 size) public pure { + size = size % 100 + 1; + min = bound(min, -int256(size / 2), int256(size - size / 2)); + int256 max = min + int256(size) - 1; + int256 result; + + for (uint256 i = 1; i <= size * 4; ++i) { + // x > max + result = bound(max + int256(i), min, max); + assertEq(result, min + int256((i - 1) % size)); + // x < min + result = bound(min - int256(i), min, max); + assertEq(result, max - int256((i - 1) % size)); + } + } + + function testFuzz_BoundInt(int256 num, int256 min, int256 max) public pure { + if (min > max) (min, max) = (max, min); + + int256 result = bound(num, min, max); + + assertGe(result, min); + assertLe(result, max); + assertEq(result, bound(result, min, max)); + if (num >= min && num <= max) assertEq(result, num); + } + + function test_BoundIntInt256Max() public pure { + assertEq(bound(0, type(int256).max - 1, type(int256).max), type(int256).max - 1); + assertEq(bound(1, type(int256).max - 1, type(int256).max), type(int256).max); + } + + function test_BoundIntInt256Min() public pure { + assertEq(bound(0, type(int256).min, type(int256).min + 1), type(int256).min); + assertEq(bound(1, type(int256).min, type(int256).min + 1), type(int256).min + 1); + } + + function test_RevertIf_BoundIntMaxLessThanMin() public { + // We deploy a mock version so we can properly test the revert. + StdUtilsMock stdUtils = new StdUtilsMock(); + + vm.expectRevert(bytes("StdUtils bound(int256,int256,int256): Max is less than min.")); + stdUtils.exposed_bound(-5, 100, 10); + } + + function testFuzz_RevertIf_BoundIntMaxLessThanMin(int256 num, int256 min, int256 max) public { + // We deploy a mock version so we can properly test the revert. + StdUtilsMock stdUtils = new StdUtilsMock(); + + vm.assume(min > max); + vm.expectRevert(bytes("StdUtils bound(int256,int256,int256): Max is less than min.")); + stdUtils.exposed_bound(num, min, max); + } + + /*////////////////////////////////////////////////////////////////////////// + BOUND PRIVATE KEY + //////////////////////////////////////////////////////////////////////////*/ + + function test_BoundPrivateKey() public pure { + assertEq(boundPrivateKey(0), 1); + assertEq(boundPrivateKey(1), 1); + assertEq(boundPrivateKey(300), 300); + assertEq(boundPrivateKey(9999), 9999); + assertEq(boundPrivateKey(SECP256K1_ORDER - 1), SECP256K1_ORDER - 1); + assertEq(boundPrivateKey(SECP256K1_ORDER), 1); + assertEq(boundPrivateKey(SECP256K1_ORDER + 1), 2); + assertEq(boundPrivateKey(UINT256_MAX), UINT256_MAX & SECP256K1_ORDER - 1); // x&y is equivalent to x-x%y + } + + /*////////////////////////////////////////////////////////////////////////// + BYTES TO UINT + //////////////////////////////////////////////////////////////////////////*/ + + function test_BytesToUint() external pure { + bytes memory maxUint = hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; + bytes memory two = hex"02"; + bytes memory millionEther = hex"d3c21bcecceda1000000"; + + assertEq(bytesToUint(maxUint), type(uint256).max); + assertEq(bytesToUint(two), 2); + assertEq(bytesToUint(millionEther), 1_000_000 ether); + } + + function test_RevertIf_BytesLengthExceeds32() external { + // We deploy a mock version so we can properly test the revert. + StdUtilsMock stdUtils = new StdUtilsMock(); + + bytes memory thirty3Bytes = hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; + vm.expectRevert("StdUtils bytesToUint(bytes): Bytes length exceeds 32."); + stdUtils.exposed_bytesToUint(thirty3Bytes); + } + + /*////////////////////////////////////////////////////////////////////////// + COMPUTE CREATE ADDRESS + //////////////////////////////////////////////////////////////////////////*/ + + function test_ComputeCreateAddress() external pure { + address deployer = 0x6C9FC64A53c1b71FB3f9Af64d1ae3A4931A5f4E9; + uint256 nonce = 14; + address createAddress = computeCreateAddress(deployer, nonce); + assertEq(createAddress, 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45); + } + + /*////////////////////////////////////////////////////////////////////////// + COMPUTE CREATE2 ADDRESS + //////////////////////////////////////////////////////////////////////////*/ + + function test_ComputeCreate2Address() external pure { + bytes32 salt = bytes32(uint256(31415)); + bytes32 initcodeHash = keccak256(abi.encode(0x6080)); + address deployer = 0x6C9FC64A53c1b71FB3f9Af64d1ae3A4931A5f4E9; + address create2Address = computeCreate2Address(salt, initcodeHash, deployer); + assertEq(create2Address, 0xB147a5d25748fda14b463EB04B111027C290f4d3); + } + + function test_ComputeCreate2AddressWithDefaultDeployer() external pure { + bytes32 salt = 0xc290c670fde54e5ef686f9132cbc8711e76a98f0333a438a92daa442c71403c0; + bytes32 initcodeHash = hashInitCode(hex"6080", ""); + assertEq(initcodeHash, 0x1a578b7a4b0b5755db6d121b4118d4bc68fe170dca840c59bc922f14175a76b0); + address create2Address = computeCreate2Address(salt, initcodeHash); + assertEq(create2Address, 0xc0ffEe2198a06235aAbFffe5Db0CacF1717f5Ac6); + } +} + +contract StdUtilsForkTest is Test { + /*////////////////////////////////////////////////////////////////////////// + GET TOKEN BALANCES + //////////////////////////////////////////////////////////////////////////*/ + + address internal SHIB = 0x95aD61b0a150d79219dCF64E1E6Cc01f0B64C4cE; + address internal SHIB_HOLDER_0 = 0x855F5981e831D83e6A4b4EBFCAdAa68D92333170; + address internal SHIB_HOLDER_1 = 0x8F509A90c2e47779cA408Fe00d7A72e359229AdA; + address internal SHIB_HOLDER_2 = 0x0e3bbc0D04fF62211F71f3e4C45d82ad76224385; + + address internal USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; + address internal USDC_HOLDER_0 = 0xDa9CE944a37d218c3302F6B82a094844C6ECEb17; + address internal USDC_HOLDER_1 = 0x3e67F4721E6d1c41a015f645eFa37BEd854fcf52; + + function setUp() public { + // All tests of the `getTokenBalances` method are fork tests using live contracts. + vm.createSelectFork({urlOrAlias: "mainnet", blockNumber: 16_428_900}); + } + + function test_RevertIf_CannotGetTokenBalances_NonTokenContract() external { + // We deploy a mock version so we can properly test the revert. + StdUtilsMock stdUtils = new StdUtilsMock(); + + // The UniswapV2Factory contract has neither a `balanceOf` function nor a fallback function, + // so the `balanceOf` call should revert. + address token = address(0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f); + address[] memory addresses = new address[](1); + addresses[0] = USDC_HOLDER_0; + + vm.expectRevert("Multicall3: call failed"); + stdUtils.exposed_getTokenBalances(token, addresses); + } + + function test_RevertIf_CannotGetTokenBalances_EOA() external { + // We deploy a mock version so we can properly test the revert. + StdUtilsMock stdUtils = new StdUtilsMock(); + + address eoa = vm.addr({privateKey: 1}); + address[] memory addresses = new address[](1); + addresses[0] = USDC_HOLDER_0; + vm.expectRevert("StdUtils getTokenBalances(address,address[]): Token address is not a contract."); + stdUtils.exposed_getTokenBalances(eoa, addresses); + } + + function test_GetTokenBalances_Empty() external { + address[] memory addresses = new address[](0); + uint256[] memory balances = getTokenBalances(USDC, addresses); + assertEq(balances.length, 0); + } + + function test_GetTokenBalances_USDC() external { + address[] memory addresses = new address[](2); + addresses[0] = USDC_HOLDER_0; + addresses[1] = USDC_HOLDER_1; + uint256[] memory balances = getTokenBalances(USDC, addresses); + assertEq(balances[0], 159_000_000_000_000); + assertEq(balances[1], 131_350_000_000_000); + } + + function test_GetTokenBalances_SHIB() external { + address[] memory addresses = new address[](3); + addresses[0] = SHIB_HOLDER_0; + addresses[1] = SHIB_HOLDER_1; + addresses[2] = SHIB_HOLDER_2; + uint256[] memory balances = getTokenBalances(SHIB, addresses); + assertEq(balances[0], 3_323_256_285_484.42e18); + assertEq(balances[1], 1_271_702_771_149.99999928e18); + assertEq(balances[2], 606_357_106_247e18); + } +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/Vm.t.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/Vm.t.sol new file mode 100644 index 0000000000..1b99e3db11 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/Vm.t.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0 <0.9.0; + +import {Test} from "../src/Test.sol"; +import {Vm, VmSafe} from "../src/Vm.sol"; + +// These tests ensure that functions are never accidentally removed from a Vm interface, or +// inadvertently moved between Vm and VmSafe. These tests must be updated each time a function is +// added to or removed from Vm or VmSafe. +contract VmTest is Test { + function test_VmInterfaceId() public pure { + assertEq(type(Vm).interfaceId, bytes4(0xe835828d), "Vm"); + } + + function test_VmSafeInterfaceId() public pure { + assertEq(type(VmSafe).interfaceId, bytes4(0xe02727c3), "VmSafe"); + } +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/compilation/CompilationScript.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/compilation/CompilationScript.sol new file mode 100644 index 0000000000..d3d88a0b5c --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/compilation/CompilationScript.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +import {Script} from "../../src/Script.sol"; + +// The purpose of this contract is to benchmark compilation time to avoid accidentally introducing +// a change that results in very long compilation times with via-ir. See https://github.com/foundry-rs/forge-std/issues/207 +contract CompilationScript is Script {} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/compilation/CompilationScriptBase.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/compilation/CompilationScriptBase.sol new file mode 100644 index 0000000000..65b5bedbe2 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/compilation/CompilationScriptBase.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +import {ScriptBase} from "../../src/Script.sol"; + +// The purpose of this contract is to benchmark compilation time to avoid accidentally introducing +// a change that results in very long compilation times with via-ir. See https://github.com/foundry-rs/forge-std/issues/207 +contract CompilationScriptBase is ScriptBase {} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/compilation/CompilationTest.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/compilation/CompilationTest.sol new file mode 100644 index 0000000000..2a9dec57f0 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/compilation/CompilationTest.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +import {Test} from "../../src/Test.sol"; + +// The purpose of this contract is to benchmark compilation time to avoid accidentally introducing +// a change that results in very long compilation times with via-ir. See https://github.com/foundry-rs/forge-std/issues/207 +contract CompilationTest is Test {} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/compilation/CompilationTestBase.sol b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/compilation/CompilationTestBase.sol new file mode 100644 index 0000000000..32b3fc5be6 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/compilation/CompilationTestBase.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +import {TestBase} from "../../src/Test.sol"; + +// The purpose of this contract is to benchmark compilation time to avoid accidentally introducing +// a change that results in very long compilation times with via-ir. See https://github.com/foundry-rs/forge-std/issues/207 +contract CompilationTestBase is TestBase {} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/fixtures/broadcast.log.json b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/fixtures/broadcast.log.json new file mode 100644 index 0000000000..0a0200bca9 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/fixtures/broadcast.log.json @@ -0,0 +1,187 @@ +{ + "transactions": [ + { + "hash": "0xc6006863c267735a11476b7f15b15bc718e117e2da114a2be815dd651e1a509f", + "type": "CALL", + "contractName": "Test", + "contractAddress": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", + "function": "multiple_arguments(uint256,address,uint256[]):(uint256)", + "arguments": ["1", "0000000000000000000000000000000000001337", "[3,4]"], + "tx": { + "type": "0x02", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", + "gas": "0x73b9", + "value": "0x0", + "data": "0x23e99187000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000013370000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004", + "nonce": "0x3", + "accessList": [] + } + }, + { + "hash": "0xedf2b38d8d896519a947a1acf720f859bb35c0c5ecb8dd7511995b67b9853298", + "type": "CALL", + "contractName": "Test", + "contractAddress": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", + "function": "inc():(uint256)", + "arguments": [], + "tx": { + "type": "0x02", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", + "gas": "0xdcb2", + "value": "0x0", + "data": "0x371303c0", + "nonce": "0x4", + "accessList": [] + } + }, + { + "hash": "0xa57e8e3981a6c861442e46c9471bd19cb3e21f9a8a6c63a72e7b5c47c6675a7c", + "type": "CALL", + "contractName": "Test", + "contractAddress": "0x7c6b4bbe207d642d98d5c537142d85209e585087", + "function": "t(uint256):(uint256)", + "arguments": ["1"], + "tx": { + "type": "0x02", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": "0x7c6b4bbe207d642d98d5c537142d85209e585087", + "gas": "0x8599", + "value": "0x0", + "data": "0xafe29f710000000000000000000000000000000000000000000000000000000000000001", + "nonce": "0x5", + "accessList": [] + } + } + ], + "receipts": [ + { + "transactionHash": "0x481dc86e40bba90403c76f8e144aa9ff04c1da2164299d0298573835f0991181", + "transactionIndex": "0x0", + "blockHash": "0xef0730448490304e5403be0fa8f8ce64f118e9adcca60c07a2ae1ab921d748af", + "blockNumber": "0x1", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": null, + "cumulativeGasUsed": "0x13f3a", + "gasUsed": "0x13f3a", + "contractAddress": "0x5fbdb2315678afecb367f032d93f642f64180aa3", + "logs": [], + "status": "0x1", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "effectiveGasPrice": "0xee6b2800" + }, + { + "transactionHash": "0x6a187183545b8a9e7f1790e847139379bf5622baff2cb43acf3f5c79470af782", + "transactionIndex": "0x0", + "blockHash": "0xf3acb96a90071640c2a8c067ae4e16aad87e634ea8d8bbbb5b352fba86ba0148", + "blockNumber": "0x2", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": null, + "cumulativeGasUsed": "0x45d80", + "gasUsed": "0x45d80", + "contractAddress": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", + "logs": [], + "status": "0x1", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "effectiveGasPrice": "0xee6b2800" + }, + { + "transactionHash": "0x064ad173b4867bdef2fb60060bbdaf01735fbf10414541ea857772974e74ea9d", + "transactionIndex": "0x0", + "blockHash": "0x8373d02109d3ee06a0225f23da4c161c656ccc48fe0fcee931d325508ae73e58", + "blockNumber": "0x3", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": "0x4e59b44847b379578588920ca78fbf26c0b4956c", + "cumulativeGasUsed": "0x45feb", + "gasUsed": "0x45feb", + "contractAddress": null, + "logs": [], + "status": "0x1", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "effectiveGasPrice": "0xee6b2800" + }, + { + "transactionHash": "0xc6006863c267735a11476b7f15b15bc718e117e2da114a2be815dd651e1a509f", + "transactionIndex": "0x0", + "blockHash": "0x16712fae5c0e18f75045f84363fb6b4d9a9fe25e660c4ce286833a533c97f629", + "blockNumber": "0x4", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", + "cumulativeGasUsed": "0x5905", + "gasUsed": "0x5905", + "contractAddress": null, + "logs": [], + "status": "0x1", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "effectiveGasPrice": "0xee6b2800" + }, + { + "transactionHash": "0xedf2b38d8d896519a947a1acf720f859bb35c0c5ecb8dd7511995b67b9853298", + "transactionIndex": "0x0", + "blockHash": "0x156b88c3eb9a1244ba00a1834f3f70de735b39e3e59006dd03af4fe7d5480c11", + "blockNumber": "0x5", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", + "cumulativeGasUsed": "0xa9c4", + "gasUsed": "0xa9c4", + "contractAddress": null, + "logs": [], + "status": "0x1", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "effectiveGasPrice": "0xee6b2800" + }, + { + "transactionHash": "0xa57e8e3981a6c861442e46c9471bd19cb3e21f9a8a6c63a72e7b5c47c6675a7c", + "transactionIndex": "0x0", + "blockHash": "0xcf61faca67dbb2c28952b0b8a379e53b1505ae0821e84779679390cb8571cadb", + "blockNumber": "0x6", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": "0x7c6b4bbe207d642d98d5c537142d85209e585087", + "cumulativeGasUsed": "0x66c5", + "gasUsed": "0x66c5", + "contractAddress": null, + "logs": [ + { + "address": "0x7c6b4bbe207d642d98d5c537142d85209e585087", + "topics": [ + "0x0b2e13ff20ac7b474198655583edf70dedd2c1dc980e329c4fbb2fc0748b796b" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000046865726500000000000000000000000000000000000000000000000000000000", + "blockHash": "0xcf61faca67dbb2c28952b0b8a379e53b1505ae0821e84779679390cb8571cadb", + "blockNumber": "0x6", + "transactionHash": "0xa57e8e3981a6c861442e46c9471bd19cb3e21f9a8a6c63a72e7b5c47c6675a7c", + "transactionIndex": "0x1", + "logIndex": "0x0", + "transactionLogIndex": "0x0", + "removed": false + } + ], + "status": "0x1", + "logsBloom": "0x00000000000800000000000000000010000000000000000000000000000180000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100", + "effectiveGasPrice": "0xee6b2800" + }, + { + "transactionHash": "0x11fbb10230c168ca1e36a7e5c69a6dbcd04fd9e64ede39d10a83e36ee8065c16", + "transactionIndex": "0x0", + "blockHash": "0xf1e0ed2eda4e923626ec74621006ed50b3fc27580dc7b4cf68a07ca77420e29c", + "blockNumber": "0x7", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": "0x0000000000000000000000000000000000001337", + "cumulativeGasUsed": "0x5208", + "gasUsed": "0x5208", + "contractAddress": null, + "logs": [], + "status": "0x1", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "effectiveGasPrice": "0xee6b2800" + } + ], + "libraries": [ + "src/Broadcast.t.sol:F:0x5fbdb2315678afecb367f032d93f642f64180aa3" + ], + "pending": [], + "path": "broadcast/Broadcast.t.sol/31337/run-latest.json", + "returns": {}, + "timestamp": 1655140035 +} diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/fixtures/config.toml b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/fixtures/config.toml new file mode 100644 index 0000000000..e6dcccca58 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/fixtures/config.toml @@ -0,0 +1,81 @@ +# ------------------------------------------------ +# EXAMPLE DEPLOYMENT CONFIG +# ------------------------------------------------ + +# -- MAINNET ------------------------------------- + +[mainnet] +endpoint_url = "${MAINNET_RPC}" + +[mainnet.bool] +is_live = true +bool_array = [true, false] + +[mainnet.address] +weth = "${WETH_MAINNET}" +deps = [ + "0x0000000000000000000000000000000000000000", + "0x1111111111111111111111111111111111111111", +] + +[mainnet.uint] +number = 1234 +number_array = [5678, 9999] + +[mainnet.int] +signed_number = -1234 +signed_number_array = [-5678, 9999] + +[mainnet.bytes32] +word = "0x00000000000000000000000000000000000000000000000000000000000004d2" # 1234 +word_array = [ + "0x000000000000000000000000000000000000000000000000000000000000162e", # 5678 + "0x000000000000000000000000000000000000000000000000000000000000270f", # 9999 +] + +[mainnet.bytes] +b = "0xabcd" +b_array = ["0xdead", "0xbeef"] + +[mainnet.string] +str = "foo" +str_array = ["bar", "baz"] + +# -- OPTIMISM ------------------------------------ + +[optimism] +endpoint_url = "${OPTIMISM_RPC}" + +[optimism.bool] +is_live = false +bool_array = [false, true] + +[optimism.address] +weth = "${WETH_OPTIMISM}" +deps = [ + "0x2222222222222222222222222222222222222222", + "0x3333333333333333333333333333333333333333", +] + +[optimism.uint] +number = 9999 +number_array = [1234, 5678] + +[optimism.int] +signed_number = 9999 +signed_number_array = [-1234, -5678] + +[optimism.bytes32] +word = "0x000000000000000000000000000000000000000000000000000000000000270f" # 9999 +word_array = [ + "0x00000000000000000000000000000000000000000000000000000000000004d2", # 1234 + "0x000000000000000000000000000000000000000000000000000000000000162e", # 5678 +] + +[optimism.bytes] +b = "0xdcba" +b_array = ["0xc0ffee", "0xbabe"] + +[optimism.string] +str = "alice" +str_array = ["bob", "charlie"] diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/fixtures/test.json b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/fixtures/test.json new file mode 100644 index 0000000000..caebf6d965 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/fixtures/test.json @@ -0,0 +1,8 @@ +{ + "a": 123, + "b": "test", + "c": { + "a": 123, + "b": "test" + } +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/fixtures/test.toml b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/fixtures/test.toml new file mode 100644 index 0000000000..60692bc750 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/lib/forge-std/test/fixtures/test.toml @@ -0,0 +1,6 @@ +a = 123 +b = "test" + +[c] +a = 123 +b = "test" diff --git a/packages/wallet/wallet-contracts/Counter/script/Counter.s.sol b/packages/wallet/wallet-contracts/Counter/script/Counter.s.sol new file mode 100644 index 0000000000..f01d69c399 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/script/Counter.s.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import {Script} from "forge-std/Script.sol"; +import {Counter} from "../src/Counter.sol"; + +contract CounterScript is Script { + Counter public counter; + + function setUp() public {} + + function run() public { + vm.startBroadcast(); + + counter = new Counter(); + + vm.stopBroadcast(); + } +} diff --git a/packages/wallet/wallet-contracts/Counter/src/Counter.sol b/packages/wallet/wallet-contracts/Counter/src/Counter.sol new file mode 100644 index 0000000000..aded7997b0 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/src/Counter.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +contract Counter { + uint256 public number; + + function setNumber(uint256 newNumber) public { + number = newNumber; + } + + function increment() public { + number++; + } +} diff --git a/packages/wallet/wallet-contracts/Counter/test/Counter.t.sol b/packages/wallet/wallet-contracts/Counter/test/Counter.t.sol new file mode 100644 index 0000000000..4831910836 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/test/Counter.t.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import {Test} from "forge-std/Test.sol"; +import {Counter} from "../src/Counter.sol"; + +contract CounterTest is Test { + Counter public counter; + + function setUp() public { + counter = new Counter(); + counter.setNumber(0); + } + + function test_Increment() public { + counter.increment(); + assertEq(counter.number(), 1); + } + + function testFuzz_SetNumber(uint256 x) public { + counter.setNumber(x); + assertEq(counter.number(), x); + } +} diff --git a/packages/wallet/wallet-contracts/Counter/utils/JsonBindings.sol b/packages/wallet/wallet-contracts/Counter/utils/JsonBindings.sol new file mode 100644 index 0000000000..740d475227 --- /dev/null +++ b/packages/wallet/wallet-contracts/Counter/utils/JsonBindings.sol @@ -0,0 +1,18 @@ +// Automatically generated by forge bind-json. + +pragma solidity >=0.6.2 <0.9.0; +pragma experimental ABIEncoderV2; + + +interface Vm { + function parseJsonTypeArray(string calldata json, string calldata key, string calldata typeDescription) external pure returns (bytes memory); + function parseJsonType(string calldata json, string calldata typeDescription) external pure returns (bytes memory); + function parseJsonType(string calldata json, string calldata key, string calldata typeDescription) external pure returns (bytes memory); + function serializeJsonType(string calldata typeDescription, bytes memory value) external pure returns (string memory json); + function serializeJsonType(string calldata objectKey, string calldata valueKey, string calldata typeDescription, bytes memory value) external returns (string memory json); +} + +library JsonBindings { + Vm constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + +} diff --git a/packages/wallet/wallet-contracts/LICENSE b/packages/wallet/wallet-contracts/LICENSE new file mode 100644 index 0000000000..bf69ef4b95 --- /dev/null +++ b/packages/wallet/wallet-contracts/LICENSE @@ -0,0 +1,219 @@ + Copyright (c) 2017-present Horizon Blockchain Games Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + ------------------------------------------------------------------------ + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/wallet/wallet-contracts/README.md b/packages/wallet/wallet-contracts/README.md new file mode 100644 index 0000000000..03031621f3 --- /dev/null +++ b/packages/wallet/wallet-contracts/README.md @@ -0,0 +1,56 @@ +# Sequence Smart Wallet Contracts + +Ethereum contracts for the Sequence Smart Wallet at [https://sequence.app](https://sequence.app). + +For more information, visit [https://sequence.build](https://sequence.build) + +## Usage + +Please visit [https://sequence.app](https://sequence.app) to access the Sequence Wallet via your Web Browser, or +download "Sequence Wallet" from the respective Apple/Google stores. + +You may also access, interface, or develop your own Sequence Wallet via [sequence.js](https://github.com/0xsequence/sequence.js). The +sequence.js library offers a full open source library to interact, create, deploy and manage a Sequence Smart Wallet Account, +as defined by the contracts in this repository. Also see [go-sequence](https://github.com/0xsequence/go-sequence) for an implementation +in Go. + +## Connecting your Dapp with Sequence Wallet + +If you wish to use Sequence Wallet in your Dapp, simply use [sequence.js](https://github.com/0xsequence/sequence.js). Sequence.js +is an Ethereum client library built on [ethers.js](https://github.com/ethers-io/ethers.js), that provides an additional +Sequence Smart Wallet Signer. + +Please refer to the [sequence.js](https://github.com/0xsequence/sequence.js) repository for usage instructions. + +# Developing a Custom Wallet UI for Sequence (Advanced!) + +If you wish to use the Sequence Wallet Contracts `@0xsequence/wallet-contracts` directly: + +1. Install the contracts: `pnpm add @0xsequence/wallet-contracts` or `npm install @0xsequence/wallet-contracts` +2. Install the Sequence Wallet libraries: `pnpm add @0xsequence/wallet` or `npm install @0xsequence/wallet`. You can view the source, + of the [wallet libraries](https://github.com/0xsequence/sequence.js/tree/master/packages/wallet), and review the + [Sequence tests](https://github.com/0xsequence/sequence.js/tree/master/packages/0xsequence) for sample usage. + +**NOTE:** this integration is only needed if you want low-level access to the Sequence Wallet contracts, such as if you'd building +your own custom wallet, or perhaps a CLI tool for managing your wallet. + +## Security Review + +`@0xsequence/wallet-contracts` has been audited by independent parties. + +### V2 Audits + +- [Consensys Diligence](https://github.com/0xsequence/wallet-contracts/blob/master/audits/v2/consensys-horizon-sequence-wallet-audit-2023-02.pdf) - February 2023 +- [Zellic](https://github.com/0xsequence/wallet-contracts/raw/master/audits/Quantstamp_Arcadeum_Report_Final.pdf) - March 2023 + +### V1 Audits + +- [Consensys Diligence](https://github.com/0xsequence/wallet-contracts/blob/master/audits/v1/Consensys_Diligence.md) - May 2020 +- [Quantstamp - initial audit](https://github.com/0xsequence/wallet-contracts/raw/master/audits/v1/Quantstamp_Arcadeum_Report_Final.pdf) - July 2020 +- [Quantstamp - audit of new capability, nested Sequence signers](https://github.com/0xsequence/wallet-contracts/raw/master/audits/v1/sequence_quantstamp_audit_feb_2021.pdf) - February 2021 + +## License + +Copyright (c) 2017-present [Horizon Blockchain Games Inc](https://horizon.io). + +Licensed under [Apache-2.0](https://github.com/0xsequence/erc-1155/blob/master/LICENSE) diff --git a/packages/wallet/wallet-contracts/audits/v1/Consensys_Diligence.md b/packages/wallet/wallet-contracts/audits/v1/Consensys_Diligence.md new file mode 100644 index 0000000000..aabcfc3591 --- /dev/null +++ b/packages/wallet/wallet-contracts/audits/v1/Consensys_Diligence.md @@ -0,0 +1,7 @@ +# Consensys Diligence report May 2020 + +[View full report](https://diligence.consensys.net/audits/private/cnhjwtpa-horizon-wallet/) + +Please note, Sequence Wallet was formerly known as "Arcadeum Wallet". Any references of "Arcadeum" +are synonymous with "Sequence", and this repository. + diff --git a/packages/wallet/wallet-contracts/audits/v1/Quantstamp_Arcadeum_Report_Final.pdf b/packages/wallet/wallet-contracts/audits/v1/Quantstamp_Arcadeum_Report_Final.pdf new file mode 100644 index 0000000000..f78c80a74e Binary files /dev/null and b/packages/wallet/wallet-contracts/audits/v1/Quantstamp_Arcadeum_Report_Final.pdf differ diff --git a/packages/wallet/wallet-contracts/audits/v1/sequence_quantstamp_audit_feb_2021.pdf b/packages/wallet/wallet-contracts/audits/v1/sequence_quantstamp_audit_feb_2021.pdf new file mode 100644 index 0000000000..27c38975ff Binary files /dev/null and b/packages/wallet/wallet-contracts/audits/v1/sequence_quantstamp_audit_feb_2021.pdf differ diff --git a/packages/wallet/wallet-contracts/audits/v2/Sequence Wallet - Zellic Audit Report.pdf b/packages/wallet/wallet-contracts/audits/v2/Sequence Wallet - Zellic Audit Report.pdf new file mode 100644 index 0000000000..817b25d7aa Binary files /dev/null and b/packages/wallet/wallet-contracts/audits/v2/Sequence Wallet - Zellic Audit Report.pdf differ diff --git a/packages/wallet/wallet-contracts/audits/v2/consensys-horizon-sequence-wallet-audit-2023-02.pdf b/packages/wallet/wallet-contracts/audits/v2/consensys-horizon-sequence-wallet-audit-2023-02.pdf new file mode 100644 index 0000000000..407ded4d20 Binary files /dev/null and b/packages/wallet/wallet-contracts/audits/v2/consensys-horizon-sequence-wallet-audit-2023-02.pdf differ diff --git a/packages/wallet/wallet-contracts/config/PROD.env.sample b/packages/wallet/wallet-contracts/config/PROD.env.sample new file mode 100644 index 0000000000..a5f1dfeba8 --- /dev/null +++ b/packages/wallet/wallet-contracts/config/PROD.env.sample @@ -0,0 +1,3 @@ +ETH_MNEMONIC="" +INFURA_API_KEY="" +ETHERSCAN="" diff --git a/packages/wallet/wallet-contracts/contracts/Factory.sol b/packages/wallet/wallet-contracts/contracts/Factory.sol new file mode 100644 index 0000000000..89c3d0e4be --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/Factory.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "./Wallet.sol"; + +contract Factory { + error DeployFailed(address _mainModule, bytes32 _salt); + + /** + * @notice Will deploy a new wallet instance + * @param _mainModule Address of the main module to be used by the wallet + * @param _salt Salt used to generate the wallet, which is the imageHash + * of the wallet's configuration. + * @dev It is recommended to not have more than 200 signers as opcode repricing + * could make transactions impossible to execute as all the signers must be + * passed for each transaction. + */ + function deploy(address _mainModule, bytes32 _salt) public payable returns (address _contract) { + bytes memory code = abi.encodePacked(Wallet.creationCode, uint256(uint160(_mainModule))); + assembly { _contract := create2(callvalue(), add(code, 32), mload(code), _salt) } + if (_contract == address(0)) revert DeployFailed(_mainModule, _salt); + } +} diff --git a/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/metadata.json b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/metadata.json new file mode 100644 index 0000000000..d57a0c8c60 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/metadata.json @@ -0,0 +1 @@ +{"compiler":{"version":"0.8.18+commit.87f61d96"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"uint256","name":"_space","type":"uint256"},{"internalType":"uint256","name":"_provided","type":"uint256"},{"internalType":"uint256","name":"_current","type":"uint256"}],"name":"BadNonce","type":"error"},{"inputs":[{"internalType":"bytes","name":"_code","type":"bytes"}],"name":"CreateFailed","type":"error"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"DelegateCallNotAllowed","type":"error"},{"inputs":[],"name":"EmptySignature","type":"error"},{"inputs":[],"name":"ImageHashIsZero","type":"error"},{"inputs":[{"internalType":"bytes32","name":"_hash","type":"bytes32"},{"internalType":"address","name":"_addr","type":"address"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"InvalidNestedSignature","type":"error"},{"inputs":[{"internalType":"bytes","name":"_signature","type":"bytes"},{"internalType":"bytes32","name":"_s","type":"bytes32"}],"name":"InvalidSValue","type":"error"},{"inputs":[{"internalType":"bytes32","name":"_hash","type":"bytes32"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"InvalidSignature","type":"error"},{"inputs":[{"internalType":"uint256","name":"_flag","type":"uint256"}],"name":"InvalidSignatureFlag","type":"error"},{"inputs":[{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"InvalidSignatureLength","type":"error"},{"inputs":[{"internalType":"bytes1","name":"_type","type":"bytes1"}],"name":"InvalidSignatureType","type":"error"},{"inputs":[{"internalType":"bytes","name":"_signature","type":"bytes"},{"internalType":"uint256","name":"_v","type":"uint256"}],"name":"InvalidVValue","type":"error"},{"inputs":[{"internalType":"bytes","name":"_signature","type":"bytes"},{"internalType":"uint256","name":"threshold","type":"uint256"},{"internalType":"uint256","name":"_weight","type":"uint256"}],"name":"LowWeightChainedSignature","type":"error"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"},{"internalType":"uint256","name":"_requested","type":"uint256"},{"internalType":"uint256","name":"_available","type":"uint256"}],"name":"NotEnoughGas","type":"error"},{"inputs":[],"name":"NotSupported","type":"error"},{"inputs":[],"name":"OnlyDelegatecall","type":"error"},{"inputs":[{"internalType":"address","name":"_sender","type":"address"},{"internalType":"address","name":"_self","type":"address"}],"name":"OnlySelfAuth","type":"error"},{"inputs":[{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"SignerIsAddress0","type":"error"},{"inputs":[{"internalType":"bytes","name":"_signature","type":"bytes"},{"internalType":"uint256","name":"_type","type":"uint256"},{"internalType":"bool","name":"_recoverMode","type":"bool"}],"name":"UnsupportedSignatureType","type":"error"},{"inputs":[{"internalType":"uint256","name":"_current","type":"uint256"},{"internalType":"uint256","name":"_prev","type":"uint256"}],"name":"WrongChainedCheckpointOrder","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_contract","type":"address"}],"name":"CreatedContract","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"newImageHash","type":"bytes32"}],"name":"ImageHashUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_space","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newNonce","type":"uint256"}],"name":"NonceChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_tx","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"_index","type":"uint256"}],"name":"TxExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"_tx","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"_index","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"_reason","type":"bytes"}],"name":"TxFailed","type":"event"},{"inputs":[],"name":"SET_IMAGE_HASH_TYPE_HASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_code","type":"bytes"}],"name":"createContract","outputs":[{"internalType":"address","name":"addr","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"bool","name":"delegateCall","type":"bool"},{"internalType":"bool","name":"revertOnError","type":"bool"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct IModuleCalls.Transaction[]","name":"_txs","type":"tuple[]"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"execute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_hash","type":"bytes32"},{"internalType":"bytes","name":"_signatures","type":"bytes"}],"name":"isValidSignature","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_data","type":"bytes"},{"internalType":"bytes","name":"_signatures","type":"bytes"}],"name":"isValidSignature","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_space","type":"uint256"}],"name":"readNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"bool","name":"delegateCall","type":"bool"},{"internalType":"bool","name":"revertOnError","type":"bool"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct IModuleCalls.Transaction[]","name":"_txs","type":"tuple[]"}],"name":"selfExecute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_digest","type":"bytes32"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"signatureRecovery","outputs":[{"internalType":"uint256","name":"threshold","type":"uint256"},{"internalType":"uint256","name":"weight","type":"uint256"},{"internalType":"bytes32","name":"imageHash","type":"bytes32"},{"internalType":"bytes32","name":"subdigest","type":"bytes32"},{"internalType":"uint256","name":"checkpoint","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_imageHash","type":"bytes32"}],"name":"updateImageHash","outputs":[],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"kind":"dev","methods":{"createContract(bytes)":{"params":{"_code":"Creation code of the contract"},"returns":{"addr":"The address of the created contract"}},"execute((bool,bool,uint256,address,uint256,bytes)[],uint256,bytes)":{"params":{"_txs":"Transactions to process"}},"isValidSignature(bytes,bytes)":{"details":"MUST return the correct magic value if the signature provided is valid for the provided data > The bytes4 magic value to return when signature is valid is 0x20c13b0b : bytes4(keccak256(\"isValidSignature(bytes,bytes)\"))","params":{"_data":"Arbitrary length data signed on the behalf of address(this)","_signatures":"Signature byte array associated with _data. Encoded as abi.encode(Signature[], Configs)"},"returns":{"_0":"magicValue Magic value 0x20c13b0b if the signature is valid and 0x0 otherwise"}},"isValidSignature(bytes32,bytes)":{"details":"MUST return the correct magic value if the signature provided is valid for the provided hash > The bytes4 magic value to return when signature is valid is 0x1626ba7e : bytes4(keccak256(\"isValidSignature(bytes32,bytes)\"))","params":{"_hash":"keccak256 hash that was signed","_signatures":"Signature byte array associated with _data. Encoded as abi.encode(Signature[], Configs)"},"returns":{"_0":"magicValue Magic value 0x1626ba7e if the signature is valid and 0x0 otherwise"}},"nonce()":{"details":"The default nonce space is 0x00","returns":{"_0":"The next nonce"}},"readNonce(uint256)":{"params":{"_space":"Nonce space, each space keeps an independent nonce count"},"returns":{"_0":"The next nonce"}},"selfExecute((bool,bool,uint256,address,uint256,bytes)[])":{"params":{"_txs":"Transactions to process"}},"signatureRecovery(bytes32,bytes)":{"details":"The signature must be prefixed with a type byte, which is used to determine the recovery method.","params":{"_digest":"Digest of the signed data.","_signature":"A Sequence signature."},"returns":{"checkpoint":"A nonce that is incremented every time a new configuration is set.","imageHash":"The imageHash of the configuration that signed the message.","subdigest":"A modified version of the original digest, unique for each wallet/network.","threshold":"The required number of signatures needed to consider the signature valid.","weight":"The actual number of signatures collected in the signature."}},"supportsInterface(bytes4)":{"params":{"_interfaceID":"The interface identifier, as specified in ERC-165"},"returns":{"_0":"`true` if the contract implements `_interfaceID`"}},"updateImageHash(bytes32)":{"params":{"_imageHash":"New required image hash of the signature"}}},"version":1},"userdoc":{"kind":"user","methods":{"createContract(bytes)":{"notice":"Creates a contract forwarding eth value"},"execute((bool,bool,uint256,address,uint256,bytes)[],uint256,bytes)":{"notice":"Allow any caller to execute an action"},"isValidSignature(bytes,bytes)":{"notice":"Verifies whether the provided signature is valid with respect to the provided data"},"isValidSignature(bytes32,bytes)":{"notice":"Verifies whether the provided signature is valid with respect to the provided hash"},"nonce()":{"notice":"Returns the next nonce of the default nonce space"},"readNonce(uint256)":{"notice":"Returns the next nonce of the given nonce space"},"selfExecute((bool,bool,uint256,address,uint256,bytes)[])":{"notice":"Allow any caller to execute an action"},"signatureRecovery(bytes32,bytes)":{"notice":"Recovers the threshold, weight, imageHash, subdigest, and checkpoint of a signature."},"supportsInterface(bytes4)":{"notice":"Query if a contract implements an interface"},"updateImageHash(bytes32)":{"notice":"Updates the signers configuration of the wallet"}},"notice":"GuestModule implements a Sequence wallet without signatures, nonce or replay protection. executing transactions using this wallet is not an authenticated process, and can be done by any address.This contract is completely public with no security, designed to execute pre-signed transactions and use Sequence tools without using the wallets.","version":1}},"settings":{"compilationTarget":{"contracts/modules/GuestModule.sol":"GuestModule"},"evmVersion":"paris","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":true,"runs":500000},"remappings":[]},"sources":{"contracts/interfaces/IERC1271Wallet.sol":{"keccak256":"0x2d7881bca678833feb385fd59e5d8ad6d596160ab51daa7030372654b3dbc38c","license":"Apache-2.0","urls":["bzz-raw://010f44c05b7285a55de939f9989727d53dfb87fd2d2534a832a70e0e081bb5f1","dweb:/ipfs/QmQcujWErxjktsKyyiTySaFuR7Vaq6fUA9SUzPkde2txVK"]},"contracts/modules/GuestModule.sol":{"keccak256":"0x14c92b44eac100edbfea10d0d02728752a6be277c267c3776dc563ff963271b1","license":"Apache-2.0","urls":["bzz-raw://e440eb91039118ce26bb66fd549d5e6b59863983efbe6c2617b92e2c4f0aab66","dweb:/ipfs/QmeTd2xBKEv4S4Rp9S4TSY4WwUUDjtA7xiJYiJqkVUio7d"]},"contracts/modules/commons/ModuleAuth.sol":{"keccak256":"0x58c028f02e3517de6c39584bcf1cedd4e7b23f575c24b363cbad4960a74f8a0b","license":"Apache-2.0","urls":["bzz-raw://f9652fead22c9fe8510de8427e2db354ed145ff30f49f85d1c717e293e5df665","dweb:/ipfs/QmSJPFQxRE5n17DNB5Bu2jwRo17yLS7igMQGt3bvKkdLAP"]},"contracts/modules/commons/ModuleCalls.sol":{"keccak256":"0x80c0151dbd444f96c2f935e70a6d3cc57e307588fa21d7eace67e568dd3d35c1","license":"Apache-2.0","urls":["bzz-raw://39a856555a5eb900e67d351e667135f245ccebd304d692b35fc8bdc83aec1b53","dweb:/ipfs/QmUdWfa7GcTGM5gk7qYbNCHtsxF4o8dXHzr6HbdFng5sQm"]},"contracts/modules/commons/ModuleCreator.sol":{"keccak256":"0x16b1400988f6b7bd4d32bdcb36ee2fbd644fb2c8ca571becc0c32e03602bd303","license":"Apache-2.0","urls":["bzz-raw://8bd4681fb4cff10f4e98e45618fbc52ed0a4c7d4fcf614f34a587ad20cd16855","dweb:/ipfs/QmbA2LYBH1x8WX8CaeiFYMU5rjyLGgNCF32r9fQbXuoqwJ"]},"contracts/modules/commons/ModuleERC165.sol":{"keccak256":"0xd4ae13a3d20fd7ab52ad16af6a06e7244daea450b796251e911091cac104d05f","license":"Apache-2.0","urls":["bzz-raw://8de37ec20a6b649e9fe3fb42276e4660ff546bca8b467f72beb35396ab5e62d6","dweb:/ipfs/QmXT2SxBZKitkbKLbGbbNLhUbw2ataRpQ2DHafvhG953RE"]},"contracts/modules/commons/ModuleNonce.sol":{"keccak256":"0x3b5388842f763a5347d632a0e0e8499a54b6f0b0a6eb7f7d3d848319defa042d","license":"Apache-2.0","urls":["bzz-raw://b36fa5a88a4e174967f850bf2bb78c787d8016ef7b5eee3e2f883fbfe9b87a7d","dweb:/ipfs/QmTDZiPiQGe1fmTKKzdwzBE1xjkh8apTotW1SQRUCFXf4q"]},"contracts/modules/commons/ModuleOnlyDelegatecall.sol":{"keccak256":"0x32bdb1d343eee2e32fd9d0f1d6dc0e265411d0821bd908881822f0f26f0887f8","license":"Apache-2.0","urls":["bzz-raw://1537c4f60a609751013bdc69eb1c6e6218982d91013115bc4e28cb84f816cd91","dweb:/ipfs/QmSjkSTrrB4vuxECcm5cRG7YmraF53QWRgftxS827KcQLW"]},"contracts/modules/commons/ModuleSelfAuth.sol":{"keccak256":"0x91545de5c77cfac86c5686c4e1f338a18ee7adb689ac0234848d7a7fc8a560db","license":"Apache-2.0","urls":["bzz-raw://dc89d05d8099ba4c3c2cf85737796d439899b5a04e6b87b1ea43f687ae08848a","dweb:/ipfs/QmatU8gRvFkK3Yn1MYAekzi48Waw3cDLtXJpduvju9HFUu"]},"contracts/modules/commons/ModuleStorage.sol":{"keccak256":"0x876c6a40cba975df4f7dfe24e02d153b2ee758975b6d1eda494ecd4b7244aa8e","license":"Apache-2.0","urls":["bzz-raw://b9be3f7930476d528ce10a121701421f0fb251b7d6b7cd579917375e6b283bb4","dweb:/ipfs/QmSbvbYQvTk8KYJZ7QqSKB9Y4M1X3UDhS6k765Zr1BAwK8"]},"contracts/modules/commons/interfaces/IModuleAuth.sol":{"keccak256":"0x24c6b05c32cb344b3b0aebd01fbd8bfc69f8c8e29fca340b262d9612c34d51e2","license":"Apache-2.0","urls":["bzz-raw://5f6c004946f0cbc4b3e52d45248337146bc82569da894ecff3cbdc5a0dca95c3","dweb:/ipfs/QmNSgDMQ7SHL6AJuzTSRbY2kgciHF1SKWfH6MaPH1N3TpR"]},"contracts/modules/commons/interfaces/IModuleCalls.sol":{"keccak256":"0xde065c15e38eb009c3dc8f99dfefdd1d6d244dd12a889a8b57edd90d32fb4395","license":"Apache-2.0","urls":["bzz-raw://23608955786060457f79267795a61eb89b3910b683fc136c749548369425088f","dweb:/ipfs/QmXNorcQBF1Qk21y3aEJRiiHVtwm61zP4ttA1ZzmRjyHnz"]},"contracts/modules/commons/interfaces/IModuleCreator.sol":{"keccak256":"0xa206dd3d424b8cd1c4f1400aa344cbc974480fea02f0fb371b872558e5ff4e6d","license":"Apache-2.0","urls":["bzz-raw://ea14c75f43a0008c582dcbae3ba3c900e446e28039dfdbb059d326ec5cc6a2d2","dweb:/ipfs/QmRfF6BmUWiFkCgzVFbLcHsUCNz5q2XkkcwXPX57ViTK4D"]},"contracts/modules/commons/submodules/auth/SequenceBaseSig.sol":{"keccak256":"0xe0565e24e94204d4b254ace42d124d3279256090921a4818cbbf9747cbb14e04","license":"Apache-2.0","urls":["bzz-raw://4293a4762b0816738511f697efd04a0e881d4c409bd15ac1c4e7261fe5e482a2","dweb:/ipfs/QmcHbEBne4fvpcD7RTJHCL6q9czoLa7KHneaCeYfXuWiGu"]},"contracts/modules/commons/submodules/auth/SequenceChainedSig.sol":{"keccak256":"0x755fbf6c106fe1c3c375c41c95c38269873717d8e683678b5fdbf6c8d3426306","license":"Apache-2.0","urls":["bzz-raw://7c7c92e72dd94f16b5c004d38c2d92eb2b760fd29a939945ed275633b0f93fa5","dweb:/ipfs/QmVdCG7Aw7aVV67z5mUKZa4VqhXHdLqy3SKxPfxaxq54p2"]},"contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol":{"keccak256":"0x6de353f8c7f44c4294914a4917458ce90ae2f7ecd2d84074fe12d4a4f1485ee5","license":"Apache-2.0","urls":["bzz-raw://369f979b79a3d3fd0336ab14b3accadb63e4784324afc34f8db11d1988526afd","dweb:/ipfs/QmavmBZ354wTaXQ6ixBd8GrC9HwtRqn4MoNhCVJcx11off"]},"contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol":{"keccak256":"0xa3ac8b8d31f20a8732bb4ebad53b42b334ec29041de0224bd494913ef0b2ad07","license":"Apache-2.0","urls":["bzz-raw://5a81d4eb3f47b09a8835b2fd53e0baa2e23cb604db3b10dae82543a5bcc52fa4","dweb:/ipfs/QmQ9XSSgbaagWArmZJJ366bdJ7HfxUxn9jdnWwN6SxUSeY"]},"contracts/modules/commons/submodules/nonce/SubModuleNonce.sol":{"keccak256":"0x98520e740b0822ec053d21f376b8be8a58e93228f3758f9228a7d00e1f60950f","license":"Apache-2.0","urls":["bzz-raw://31226706c004f1a4315d6b8d37621b46f4d5807c16e1ce72675c1431ed9006a2","dweb:/ipfs/QmdSSyCuPex2E2VTd6UMYy9WAq9eJNZ6vHSUomntNknzXE"]},"contracts/utils/LibBytes.sol":{"keccak256":"0xd780faf34527a323c96577c57370d175a2b6149db7ebea0937592eb389e52805","license":"Apache-2.0","urls":["bzz-raw://7a41a47e72f5761d912367c041ddab41620175d63059ad71ff681a87d8cf0e98","dweb:/ipfs/QmfEFuLaVyx9vQc83dS48wTcLtbBiWTNMdHSi5hAWA379i"]},"contracts/utils/LibBytesPointer.sol":{"keccak256":"0xbda56396592db18a248d4062cd36abd586a11d92a2d25483d8c597f890859b15","license":"Apache-2.0","urls":["bzz-raw://a6ee93bcb7ccd1d1b8979c9530b1ca452d0757794995b62793b6e197670b9f25","dweb:/ipfs/QmbNkhTPzF1YgU4Qgu4SRFXZ8AwFjyG18EzuMZ32anrQ4Y"]},"contracts/utils/LibOptim.sol":{"keccak256":"0x4c558b8c9d0dff2322d5d812e83a3abe25a9e60c8f646507f8a9c7fa2a2453af","license":"Apache-2.0","urls":["bzz-raw://6f0796c75d117770e220c136b60d96b5cf1d4875ccbbd0afb564ed27aa220335","dweb:/ipfs/QmQxYm6CMCqJiKsB3sguqWu8rggmaQgpuq8BZhAEveqNAM"]},"contracts/utils/SignatureValidator.sol":{"keccak256":"0x7ac5dd35cbc776693eecfd8e7e86af139c7b054c43be4f97e6c8929417c17dba","license":"Apache-2.0","urls":["bzz-raw://4a452d8acad5246538ac352887081d732098dcab869c79a43a5f916e7e76f353","dweb:/ipfs/QmeazDSxfKBSGyCGjmk7G79UbvYMRcbr2eUU9ThyqSvNhv"]}},"version":1} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/interfaces/IERC1271Wallet.sol b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/interfaces/IERC1271Wallet.sol new file mode 100644 index 0000000000..5572aaea43 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/interfaces/IERC1271Wallet.sol @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + + +interface IERC1271Wallet { + + /** + * @notice Verifies whether the provided signature is valid with respect to the provided data + * @dev MUST return the correct magic value if the signature provided is valid for the provided data + * > The bytes4 magic value to return when signature is valid is 0x20c13b0b : bytes4(keccak256("isValidSignature(bytes,bytes)") + * > This function MAY modify Ethereum's state + * @param _data Arbitrary length data signed on the behalf of address(this) + * @param _signature Signature byte array associated with _data + * @return magicValue Magic value 0x20c13b0b if the signature is valid and 0x0 otherwise + */ + function isValidSignature( + bytes calldata _data, + bytes calldata _signature) + external + view + returns (bytes4 magicValue); + + /** + * @notice Verifies whether the provided signature is valid with respect to the provided hash + * @dev MUST return the correct magic value if the signature provided is valid for the provided hash + * > The bytes4 magic value to return when signature is valid is 0x20c13b0b : bytes4(keccak256("isValidSignature(bytes,bytes)") + * > This function MAY modify Ethereum's state + * @param _hash keccak256 hash that was signed + * @param _signature Signature byte array associated with _data + * @return magicValue Magic value 0x20c13b0b if the signature is valid and 0x0 otherwise + */ + function isValidSignature( + bytes32 _hash, + bytes calldata _signature) + external + view + returns (bytes4 magicValue); +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/GuestModule.sol b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/GuestModule.sol new file mode 100644 index 0000000000..54cb770a88 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/GuestModule.sol @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "../utils/LibOptim.sol"; + +import "./commons/submodules/auth/SequenceBaseSig.sol"; + +import "./commons/ModuleAuth.sol"; +import "./commons/ModuleCalls.sol"; +import "./commons/ModuleCreator.sol"; + + +/** + * GuestModule implements a Sequence wallet without signatures, nonce or replay protection. + * executing transactions using this wallet is not an authenticated process, and can be done by any address. + * + * @notice This contract is completely public with no security, designed to execute pre-signed transactions + * and use Sequence tools without using the wallets. + */ +contract GuestModule is + ModuleAuth, + ModuleCalls, + ModuleCreator +{ + error DelegateCallNotAllowed(uint256 _index); + error NotSupported(); + + /** + * @notice Allow any caller to execute an action + * @param _txs Transactions to process + */ + function execute( + Transaction[] calldata _txs, + uint256, + bytes calldata + ) public override { + // Hash transaction bundle + bytes32 txHash = SequenceBaseSig.subdigest(keccak256(abi.encode('guest:', _txs))); + + // Execute the transactions + _executeGuest(txHash, _txs); + } + + /** + * @notice Allow any caller to execute an action + * @param _txs Transactions to process + */ + function selfExecute( + Transaction[] calldata _txs + ) public override { + // Hash transaction bundle + bytes32 txHash = SequenceBaseSig.subdigest(keccak256(abi.encode('self:', _txs))); + + // Execute the transactions + _executeGuest(txHash, _txs); + } + + /** + * @notice Executes a list of transactions + * @param _txHash Hash of the batch of transactions + * @param _txs Transactions to execute + */ + function _executeGuest( + bytes32 _txHash, + Transaction[] calldata _txs + ) private { + // Execute transaction + uint256 size = _txs.length; + for (uint256 i = 0; i < size; i++) { + Transaction calldata transaction = _txs[i]; + + if (transaction.delegateCall) revert DelegateCallNotAllowed(i); + + uint256 gasLimit = transaction.gasLimit; + if (gasleft() < gasLimit) revert NotEnoughGas(i, gasLimit, gasleft()); + + bool success = LibOptim.call( + transaction.target, + transaction.value, + gasLimit == 0 ? gasleft() : gasLimit, + transaction.data + ); + + if (success) { + emit TxExecuted(_txHash, i); + } else { + _revertBytes( + transaction.revertOnError, + _txHash, + i, + LibOptim.returnData() + ); + } + } + } + + /** + * @notice Validates any signature image, because the wallet is public and has no owner. + * @return true, all signatures are valid. + */ + function _isValidImage(bytes32) internal override pure returns (bool) { + return true; + } + + /** + * Not supported. + */ + function _updateImageHash(bytes32) internal override virtual { + revert NotSupported(); + } + + /** + * @notice Query if a contract implements an interface + * @param _interfaceID The interface identifier, as specified in ERC-165 + * @return `true` if the contract implements `_interfaceID` + */ + function supportsInterface( + bytes4 _interfaceID + ) public override ( + ModuleAuth, + ModuleCalls, + ModuleCreator + ) pure returns (bool) { + return super.supportsInterface(_interfaceID); + } +} diff --git a/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/artifacts/GuestModule.json b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/artifacts/GuestModule.json new file mode 100644 index 0000000000..a1977cfea3 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/artifacts/GuestModule.json @@ -0,0 +1,14655 @@ +{ + "deploy": { + "VM:-": { + "linkReferences": {}, + "autoDeployLib": true + }, + "main:1": { + "linkReferences": {}, + "autoDeployLib": true + }, + "ropsten:3": { + "linkReferences": {}, + "autoDeployLib": true + }, + "rinkeby:4": { + "linkReferences": {}, + "autoDeployLib": true + }, + "kovan:42": { + "linkReferences": {}, + "autoDeployLib": true + }, + "goerli:5": { + "linkReferences": {}, + "autoDeployLib": true + }, + "Custom": { + "linkReferences": {}, + "autoDeployLib": true + } + }, + "data": { + "bytecode": { + "functionDebugData": { + "@_1068": { + "entryPoint": null, + "id": 1068, + "parameterSlots": 0, + "returnSlots": 0 + } + }, + "generatedSources": [], + "linkReferences": {}, + "object": "60a060405234801561001057600080fd5b50306080526080516121de61002d600039600050506121de6000f3fe6080604052600436106100bc5760003560e01c806361c2926c116100745780638c3f55631161004e5780638c3f55631461025357806390042baf14610273578063affed0e0146102ab57600080fd5b806361c2926c146101cb5780637a9a1628146101eb578063853c50681461020b57600080fd5b806320c13b0b116100a557806320c13b0b14610147578063295614261461016757806357c56d6b1461018957600080fd5b806301ffc9a7146100c15780631626ba7e146100f6575b600080fd5b3480156100cd57600080fd5b506100e16100dc366004611880565b6102c0565b60405190151581526020015b60405180910390f35b34801561010257600080fd5b506101166101113660046118e6565b6102d1565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016100ed565b34801561015357600080fd5b50610116610162366004611932565b61031e565b34801561017357600080fd5b5061018761018236600461199e565b610383565b005b34801561019557600080fd5b506101bd7f8713a7c4465f6fbee2b6e9d6646d1d9f83fec929edfc4baf661f3c865bdd04d181565b6040519081526020016100ed565b3480156101d757600080fd5b506101876101e63660046119fc565b6103d5565b3480156101f757600080fd5b50610187610206366004611a3e565b61041a565b34801561021757600080fd5b5061022b6102263660046118e6565b610447565b604080519586526020860194909452928401919091526060830152608082015260a0016100ed565b34801561025f57600080fd5b506101bd61026e36600461199e565b61060f565b610286610281366004611ae7565b61063b565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100ed565b3480156102b757600080fd5b506101bd610725565b60006102cb82610736565b92915050565b6000806102df858585610792565b509050801561031157507f1626ba7e000000000000000000000000000000000000000000000000000000009050610317565b50600090505b9392505050565b6000806103438686604051610334929190611bb6565b60405180910390208585610792565b509050801561037557507f20c13b0b00000000000000000000000000000000000000000000000000000000905061037b565b50600090505b949350505050565b3330146103c9576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044015b60405180910390fd5b6103d2816107ca565b50565b600061040883836040516020016103ed929190611d97565b604051602081830303815290604052805190602001206107fc565b9050610415818484610881565b505050565b600061043286866040516020016103ed929190611ddf565b905061043f818787610881565b505050505050565b6000806000806000808787600081811061046357610463611e27565b909101357fff000000000000000000000000000000000000000000000000000000000000001691508190506104b95761049b896107fc565b92506104a8838989610a0e565b929850909650945091506106049050565b7fff00000000000000000000000000000000000000000000000000000000000000818116016104f8576104eb896107fc565b92506104a8838989610a5f565b7ffe000000000000000000000000000000000000000000000000000000000000007fff0000000000000000000000000000000000000000000000000000000000000082160161054a576104eb89610a8b565b7ffd000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216016105ae5761059e898989610af8565b9550955095509550955050610604565b6040517f6085cd820000000000000000000000000000000000000000000000000000000081527fff00000000000000000000000000000000000000000000000000000000000000821660048201526024016103c0565b939792965093509350565b60006102cb7f8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e83610c75565b600033301461067e576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044016103c0565b81516020830134f0905073ffffffffffffffffffffffffffffffffffffffff81166106d757816040517f0d2571910000000000000000000000000000000000000000000000000000000081526004016103c09190611eba565b60405173ffffffffffffffffffffffffffffffffffffffff821681527fa506ad4e7f05eceba62a023c3219e5bd98a615f4fa87e2afb08a2da5cf62bf0c9060200160405180910390a1919050565b6000610731600061060f565b905090565b60007f6ffbd451000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083160161078957506001919050565b6102cb82610cd3565b60008060008060006107a5888888610447565b509650919450925090508282108015906107bd575060015b9450505050935093915050565b6040517fa038794000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f190100000000000000000000000000000000000000000000000000000000000060208201524660228201527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b166042820152605681018290526000906076015b604051602081830303815290604052805190602001209050919050565b8060005b81811015610a0757368484838181106108a0576108a0611e27565b90506020028101906108b29190611ecd565b90506108c16020820182611f0b565b156108fb576040517f230d1ccc000000000000000000000000000000000000000000000000000000008152600481018390526024016103c0565b6040810135805a101561094e5782815a6040517f2bb3e3ba0000000000000000000000000000000000000000000000000000000081526004810193909352602483019190915260448201526064016103c0565b60006109886109636080850160608601611f26565b608085013584156109745784610976565b5a5b61098360a0880188611f41565b610d2f565b905080156109cf57877f5c4eeb02dabf8976016ab414d617f9a162936dcace3cdef8c69ef6e262ad5ae7856040516109c291815260200190565b60405180910390a26109f1565b6109f16109e26040850160208601611f0b565b89866109ec610d4c565b610d6b565b50505080806109ff90611fd5565b915050610885565b5050505050565b6000808080610a2987610a24876006818b61200d565b610db9565b6000908152873560f01c6020818152604080842084526002909a013560e01c908190529890912090999198509695509350505050565b6000808080610a7a87610a75876001818b61200d565b610a0e565b935093509350935093509350935093565b6040517f190100000000000000000000000000000000000000000000000000000000000060208201526000602282018190527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b1660428301526056820183905290607601610864565b6000808080806004600188013560e81c82610b138383612037565b9050610b258b61022683868d8f61200d565b939b5091995097509550935087871015610b7d57610b4581848b8d61200d565b89896040517fb006aba00000000000000000000000000000000000000000000000000000000081526004016103c0949392919061204a565b8092505b88831015610c675760038301928a013560e81c9150610ba08383612037565b90506000610bc2610bb08861124f565b8c8c879086926102269392919061200d565b939c50919a5098509091505088881015610c1a57610be282858c8e61200d565b8a8a6040517fb006aba00000000000000000000000000000000000000000000000000000000081526004016103c0949392919061204a565b848110610c5d576040517f37daf62b00000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016103c0565b9350915081610b81565b505050939792965093509350565b6000808383604051602001610c94929190918252602082015260400190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052805160209091012054949350505050565b60007fe4a77bbc000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831601610d2657506001919050565b6102cb82611283565b6000604051828482376000808483898b8af1979650505050505050565b60603d604051915060208201818101604052818352816000823e505090565b8315610d7957805160208201fd5b827fab46c69f7f32e1bf09b0725853da82a211e5402a0600296ab499a2fb5ea3b4198383604051610dab929190612071565b60405180910390a250505050565b60008060005b8381101561124657600181019085013560f81c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8101610e6057601582019186013560f881901c9060581c73ffffffffffffffffffffffffffffffffffffffff81169074ff000000000000000000000000000000000000000016811785610e465780610e55565b60008681526020829052604090205b955050505050610dbf565b80610ef65760018201918681013560f81c906043016000610e8c8a610e8784888c8e61200d565b61136d565b60ff841697909701969194508491905060a083901b74ff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff82161786610edb5780610eea565b60008781526020829052604090205b96505050505050610dbf565b6002810361101e576000808784013560f881901c9060581c73ffffffffffffffffffffffffffffffffffffffff16601586019550909250905060008885013560e81c600386018162ffffff169150809650819250505060008186019050610f6f8b848c8c8a908692610f6a9392919061200d565b611630565b610fb7578a83610f8183898d8f61200d565b6040517f9a9462320000000000000000000000000000000000000000000000000000000081526004016103c0949392919061208a565b60ff8416979097019694508460a084901b74ff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff841617876110025780611011565b60008881526020829052604090205b9750505050505050610dbf565b60038103611051576020820191860135836110395780611048565b60008481526020829052604090205b93505050610dbf565b6004810361109d576003808301928781013560e81c919082010160008061107e8b610a2485898d8f61200d565b60009889526020526040909720969097019650909350610dbf92505050565b600681036111a55760008287013560f81c60018401935060ff16905060008784013560f01c60028501945061ffff16905060008885013560e81c600386018162ffffff16915080965081925050506000818601905060008061110b8d8d8d8b908792610a249392919061200d565b9398508893909250905084821061112157988501985b604080517f53657175656e6365206e657374656420636f6e6669673a0a0000000000000000602080830191909152603882018490526058820188905260788083018a90528351808403909101815260989092019092528051910120896111875780611196565b60008a81526020829052604090205b99505050505050505050610dbf565b600581036112115760208201918601358781036111e0577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff94505b60006111eb82611817565b9050846111f85780611207565b60008581526020829052604090205b9450505050610dbf565b6040517fb2505f7c000000000000000000000000000000000000000000000000000000008152600481018290526024016103c0565b50935093915050565b7f8713a7c4465f6fbee2b6e9d6646d1d9f83fec929edfc4baf661f3c865bdd04d160009081526020829052604081206102cb565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fac6a444e00000000000000000000000000000000000000000000000000000000148061131657507fffffffff0000000000000000000000000000000000000000000000000000000082167f36e7817500000000000000000000000000000000000000000000000000000000145b1561132357506001919050565b7f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316146102cb565b6000604282146113ad5782826040517f2ee17a3d0000000000000000000000000000000000000000000000000000000081526004016103c09291906120ca565b60006113c66113bd6001856120de565b85013560f81c90565b60ff169050604084013560f81c843560208601357f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a081111561143a578686826040517fad4aac760000000000000000000000000000000000000000000000000000000081526004016103c0939291906120f1565b8260ff16601b1415801561145257508260ff16601c14155b1561148f578686846040517fe578897e0000000000000000000000000000000000000000000000000000000081526004016103c093929190612115565b600184036114fc576040805160008152602081018083528a905260ff851691810191909152606081018390526080810182905260019060a0015b6020604051602081039080840390855afa1580156114eb573d6000803e3d6000fd5b5050506020604051035194506115d4565b60028403611599576040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101899052600190605c01604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600084529083018083525260ff861690820152606081018490526080810183905260a0016114c9565b86868560016040517f9dfba8520000000000000000000000000000000000000000000000000000000081526004016103c0949392919061213c565b73ffffffffffffffffffffffffffffffffffffffff85166116255786866040517f6c1719d20000000000000000000000000000000000000000000000000000000081526004016103c09291906120ca565b505050509392505050565b600081810361166b576040517fac241e1100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000838361167a6001826120de565b81811061168957611689611e27565b919091013560f81c91505060018114806116a35750600281145b156116e8578473ffffffffffffffffffffffffffffffffffffffff166116ca87868661136d565b73ffffffffffffffffffffffffffffffffffffffff1614915061180e565b600381036117d35773ffffffffffffffffffffffffffffffffffffffff8516631626ba7e878660008761171c6001826120de565b926117299392919061200d565b6040518463ffffffff1660e01b815260040161174793929190612168565b602060405180830381865afa158015611764573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611788919061218b565b7fffffffff00000000000000000000000000000000000000000000000000000000167f1626ba7e0000000000000000000000000000000000000000000000000000000014915061180e565b83838260006040517f9dfba8520000000000000000000000000000000000000000000000000000000081526004016103c0949392919061213c565b50949350505050565b6040517f53657175656e636520737461746963206469676573743a0a0000000000000000602082015260388101829052600090605801610864565b7fffffffff00000000000000000000000000000000000000000000000000000000811681146103d257600080fd5b60006020828403121561189257600080fd5b813561031781611852565b60008083601f8401126118af57600080fd5b50813567ffffffffffffffff8111156118c757600080fd5b6020830191508360208285010111156118df57600080fd5b9250929050565b6000806000604084860312156118fb57600080fd5b83359250602084013567ffffffffffffffff81111561191957600080fd5b6119258682870161189d565b9497909650939450505050565b6000806000806040858703121561194857600080fd5b843567ffffffffffffffff8082111561196057600080fd5b61196c8883890161189d565b9096509450602087013591508082111561198557600080fd5b506119928782880161189d565b95989497509550505050565b6000602082840312156119b057600080fd5b5035919050565b60008083601f8401126119c957600080fd5b50813567ffffffffffffffff8111156119e157600080fd5b6020830191508360208260051b85010111156118df57600080fd5b60008060208385031215611a0f57600080fd5b823567ffffffffffffffff811115611a2657600080fd5b611a32858286016119b7565b90969095509350505050565b600080600080600060608688031215611a5657600080fd5b853567ffffffffffffffff80821115611a6e57600080fd5b611a7a89838a016119b7565b9097509550602088013594506040880135915080821115611a9a57600080fd5b50611aa78882890161189d565b969995985093965092949392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215611af957600080fd5b813567ffffffffffffffff80821115611b1157600080fd5b818401915084601f830112611b2557600080fd5b813581811115611b3757611b37611ab8565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715611b7d57611b7d611ab8565b81604052828152876020848701011115611b9657600080fd5b826020860160208301376000928101602001929092525095945050505050565b8183823760009101908152919050565b80358015158114611bd657600080fd5b919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611bd657600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b81835260006020808501808196508560051b810191508460005b87811015611d8a57828403895281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff41883603018112611ca157600080fd5b870160c0611cae82611bc6565b15158652611cbd878301611bc6565b15158688015260408281013590870152606073ffffffffffffffffffffffffffffffffffffffff611cef828501611bdb565b16908701526080828101359087015260a080830135368490037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1018112611d3557600080fd5b90920187810192903567ffffffffffffffff811115611d5357600080fd5b803603841315611d6257600080fd5b8282890152611d748389018286611bff565b9c89019c97505050928601925050600101611c62565b5091979650505050505050565b60408152600560408201527f73656c663a000000000000000000000000000000000000000000000000000000606082015260806020820152600061037b608083018486611c48565b60408152600660408201527f67756573743a0000000000000000000000000000000000000000000000000000606082015260806020820152600061037b608083018486611c48565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000815180845260005b81811015611e7c57602081850181015186830182015201611e60565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006103176020830184611e56565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff41833603018112611f0157600080fd5b9190910192915050565b600060208284031215611f1d57600080fd5b61031782611bc6565b600060208284031215611f3857600080fd5b61031782611bdb565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611f7657600080fd5b83018035915067ffffffffffffffff821115611f9157600080fd5b6020019150368190038213156118df57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361200657612006611fa6565b5060010190565b6000808585111561201d57600080fd5b8386111561202a57600080fd5b5050820193919092039150565b808201808211156102cb576102cb611fa6565b60608152600061205e606083018688611bff565b6020830194909452506040015292915050565b82815260406020820152600061037b6040830184611e56565b84815273ffffffffffffffffffffffffffffffffffffffff841660208201526060604082015260006120c0606083018486611bff565b9695505050505050565b60208152600061037b602083018486611bff565b818103818111156102cb576102cb611fa6565b604081526000612105604083018587611bff565b9050826020830152949350505050565b604081526000612129604083018587611bff565b905060ff83166020830152949350505050565b606081526000612150606083018688611bff565b60208301949094525090151560409091015292915050565b838152604060208201526000612182604083018486611bff565b95945050505050565b60006020828403121561219d57600080fd5b81516103178161185256fea26469706673582212209bb95d18e97f278aa47e0c04c20d5a6af9bdb6d473c6d4051192cd96fc17866864736f6c63430008120033", + "opcodes": "PUSH1 0xA0 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP ADDRESS PUSH1 0x80 MSTORE PUSH1 0x80 MLOAD PUSH2 0x21DE PUSH2 0x2D PUSH1 0x0 CODECOPY PUSH1 0x0 POP POP PUSH2 0x21DE PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0xBC JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x61C2926C GT PUSH2 0x74 JUMPI DUP1 PUSH4 0x8C3F5563 GT PUSH2 0x4E JUMPI DUP1 PUSH4 0x8C3F5563 EQ PUSH2 0x253 JUMPI DUP1 PUSH4 0x90042BAF EQ PUSH2 0x273 JUMPI DUP1 PUSH4 0xAFFED0E0 EQ PUSH2 0x2AB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x61C2926C EQ PUSH2 0x1CB JUMPI DUP1 PUSH4 0x7A9A1628 EQ PUSH2 0x1EB JUMPI DUP1 PUSH4 0x853C5068 EQ PUSH2 0x20B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x20C13B0B GT PUSH2 0xA5 JUMPI DUP1 PUSH4 0x20C13B0B EQ PUSH2 0x147 JUMPI DUP1 PUSH4 0x29561426 EQ PUSH2 0x167 JUMPI DUP1 PUSH4 0x57C56D6B EQ PUSH2 0x189 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x1FFC9A7 EQ PUSH2 0xC1 JUMPI DUP1 PUSH4 0x1626BA7E EQ PUSH2 0xF6 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xCD JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xE1 PUSH2 0xDC CALLDATASIZE PUSH1 0x4 PUSH2 0x1880 JUMP JUMPDEST PUSH2 0x2C0 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x102 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x116 PUSH2 0x111 CALLDATASIZE PUSH1 0x4 PUSH2 0x18E6 JUMP JUMPDEST PUSH2 0x2D1 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xED JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x153 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x116 PUSH2 0x162 CALLDATASIZE PUSH1 0x4 PUSH2 0x1932 JUMP JUMPDEST PUSH2 0x31E JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x173 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x187 PUSH2 0x182 CALLDATASIZE PUSH1 0x4 PUSH2 0x199E JUMP JUMPDEST PUSH2 0x383 JUMP JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x195 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1BD PUSH32 0x8713A7C4465F6FBEE2B6E9D6646D1D9F83FEC929EDFC4BAF661F3C865BDD04D1 DUP2 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xED JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1D7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x187 PUSH2 0x1E6 CALLDATASIZE PUSH1 0x4 PUSH2 0x19FC JUMP JUMPDEST PUSH2 0x3D5 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1F7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x187 PUSH2 0x206 CALLDATASIZE PUSH1 0x4 PUSH2 0x1A3E JUMP JUMPDEST PUSH2 0x41A JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x217 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x22B PUSH2 0x226 CALLDATASIZE PUSH1 0x4 PUSH2 0x18E6 JUMP JUMPDEST PUSH2 0x447 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP6 DUP7 MSTORE PUSH1 0x20 DUP7 ADD SWAP5 SWAP1 SWAP5 MSTORE SWAP3 DUP5 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x60 DUP4 ADD MSTORE PUSH1 0x80 DUP3 ADD MSTORE PUSH1 0xA0 ADD PUSH2 0xED JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x25F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1BD PUSH2 0x26E CALLDATASIZE PUSH1 0x4 PUSH2 0x199E JUMP JUMPDEST PUSH2 0x60F JUMP JUMPDEST PUSH2 0x286 PUSH2 0x281 CALLDATASIZE PUSH1 0x4 PUSH2 0x1AE7 JUMP JUMPDEST PUSH2 0x63B JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xED JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2B7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1BD PUSH2 0x725 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x2CB DUP3 PUSH2 0x736 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH2 0x2DF DUP6 DUP6 DUP6 PUSH2 0x792 JUMP JUMPDEST POP SWAP1 POP DUP1 ISZERO PUSH2 0x311 JUMPI POP PUSH32 0x1626BA7E00000000000000000000000000000000000000000000000000000000 SWAP1 POP PUSH2 0x317 JUMP JUMPDEST POP PUSH1 0x0 SWAP1 POP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH2 0x343 DUP7 DUP7 PUSH1 0x40 MLOAD PUSH2 0x334 SWAP3 SWAP2 SWAP1 PUSH2 0x1BB6 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 KECCAK256 DUP6 DUP6 PUSH2 0x792 JUMP JUMPDEST POP SWAP1 POP DUP1 ISZERO PUSH2 0x375 JUMPI POP PUSH32 0x20C13B0B00000000000000000000000000000000000000000000000000000000 SWAP1 POP PUSH2 0x37B JUMP JUMPDEST POP PUSH1 0x0 SWAP1 POP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST CALLER ADDRESS EQ PUSH2 0x3C9 JUMPI PUSH1 0x40 MLOAD PUSH32 0xE125889400000000000000000000000000000000000000000000000000000000 DUP2 MSTORE CALLER PUSH1 0x4 DUP3 ADD MSTORE ADDRESS PUSH1 0x24 DUP3 ADD MSTORE PUSH1 0x44 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH2 0x3D2 DUP2 PUSH2 0x7CA JUMP JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x408 DUP4 DUP4 PUSH1 0x40 MLOAD PUSH1 0x20 ADD PUSH2 0x3ED SWAP3 SWAP2 SWAP1 PUSH2 0x1D97 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE DUP1 MLOAD SWAP1 PUSH1 0x20 ADD KECCAK256 PUSH2 0x7FC JUMP JUMPDEST SWAP1 POP PUSH2 0x415 DUP2 DUP5 DUP5 PUSH2 0x881 JUMP JUMPDEST POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x432 DUP7 DUP7 PUSH1 0x40 MLOAD PUSH1 0x20 ADD PUSH2 0x3ED SWAP3 SWAP2 SWAP1 PUSH2 0x1DDF JUMP JUMPDEST SWAP1 POP PUSH2 0x43F DUP2 DUP8 DUP8 PUSH2 0x881 JUMP JUMPDEST POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 DUP8 DUP8 PUSH1 0x0 DUP2 DUP2 LT PUSH2 0x463 JUMPI PUSH2 0x463 PUSH2 0x1E27 JUMP JUMPDEST SWAP1 SWAP2 ADD CALLDATALOAD PUSH32 0xFF00000000000000000000000000000000000000000000000000000000000000 AND SWAP2 POP DUP2 SWAP1 POP PUSH2 0x4B9 JUMPI PUSH2 0x49B DUP10 PUSH2 0x7FC JUMP JUMPDEST SWAP3 POP PUSH2 0x4A8 DUP4 DUP10 DUP10 PUSH2 0xA0E JUMP JUMPDEST SWAP3 SWAP9 POP SWAP1 SWAP7 POP SWAP5 POP SWAP2 POP PUSH2 0x604 SWAP1 POP JUMP JUMPDEST PUSH32 0xFF00000000000000000000000000000000000000000000000000000000000000 DUP2 DUP2 AND ADD PUSH2 0x4F8 JUMPI PUSH2 0x4EB DUP10 PUSH2 0x7FC JUMP JUMPDEST SWAP3 POP PUSH2 0x4A8 DUP4 DUP10 DUP10 PUSH2 0xA5F JUMP JUMPDEST PUSH32 0xFE00000000000000000000000000000000000000000000000000000000000000 PUSH32 0xFF00000000000000000000000000000000000000000000000000000000000000 DUP3 AND ADD PUSH2 0x54A JUMPI PUSH2 0x4EB DUP10 PUSH2 0xA8B JUMP JUMPDEST PUSH32 0xFD00000000000000000000000000000000000000000000000000000000000000 PUSH32 0xFF00000000000000000000000000000000000000000000000000000000000000 DUP3 AND ADD PUSH2 0x5AE JUMPI PUSH2 0x59E DUP10 DUP10 DUP10 PUSH2 0xAF8 JUMP JUMPDEST SWAP6 POP SWAP6 POP SWAP6 POP SWAP6 POP SWAP6 POP POP PUSH2 0x604 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x6085CD8200000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH32 0xFF00000000000000000000000000000000000000000000000000000000000000 DUP3 AND PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x24 ADD PUSH2 0x3C0 JUMP JUMPDEST SWAP4 SWAP8 SWAP3 SWAP7 POP SWAP4 POP SWAP4 POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x2CB PUSH32 0x8D0BF1FD623D628C741362C1289948E57B3E2905218C676D3E69ABEE36D6AE2E DUP4 PUSH2 0xC75 JUMP JUMPDEST PUSH1 0x0 CALLER ADDRESS EQ PUSH2 0x67E JUMPI PUSH1 0x40 MLOAD PUSH32 0xE125889400000000000000000000000000000000000000000000000000000000 DUP2 MSTORE CALLER PUSH1 0x4 DUP3 ADD MSTORE ADDRESS PUSH1 0x24 DUP3 ADD MSTORE PUSH1 0x44 ADD PUSH2 0x3C0 JUMP JUMPDEST DUP2 MLOAD PUSH1 0x20 DUP4 ADD CALLVALUE CREATE SWAP1 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND PUSH2 0x6D7 JUMPI DUP2 PUSH1 0x40 MLOAD PUSH32 0xD25719100000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP2 SWAP1 PUSH2 0x1EBA JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 AND DUP2 MSTORE PUSH32 0xA506AD4E7F05ECEBA62A023C3219E5BD98A615F4FA87E2AFB08A2DA5CF62BF0C SWAP1 PUSH1 0x20 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x731 PUSH1 0x0 PUSH2 0x60F JUMP JUMPDEST SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH32 0x6FFBD45100000000000000000000000000000000000000000000000000000000 PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP4 AND ADD PUSH2 0x789 JUMPI POP PUSH1 0x1 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH2 0x2CB DUP3 PUSH2 0xCD3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x7A5 DUP9 DUP9 DUP9 PUSH2 0x447 JUMP JUMPDEST POP SWAP7 POP SWAP2 SWAP5 POP SWAP3 POP SWAP1 POP DUP3 DUP3 LT DUP1 ISZERO SWAP1 PUSH2 0x7BD JUMPI POP PUSH1 0x1 JUMPDEST SWAP5 POP POP POP POP SWAP4 POP SWAP4 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0xA038794000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x1901000000000000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE CHAINID PUSH1 0x22 DUP3 ADD MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000 ADDRESS PUSH1 0x60 SHL AND PUSH1 0x42 DUP3 ADD MSTORE PUSH1 0x56 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x0 SWAP1 PUSH1 0x76 ADD JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE DUP1 MLOAD SWAP1 PUSH1 0x20 ADD KECCAK256 SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST DUP1 PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0xA07 JUMPI CALLDATASIZE DUP5 DUP5 DUP4 DUP2 DUP2 LT PUSH2 0x8A0 JUMPI PUSH2 0x8A0 PUSH2 0x1E27 JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL DUP2 ADD SWAP1 PUSH2 0x8B2 SWAP2 SWAP1 PUSH2 0x1ECD JUMP JUMPDEST SWAP1 POP PUSH2 0x8C1 PUSH1 0x20 DUP3 ADD DUP3 PUSH2 0x1F0B JUMP JUMPDEST ISZERO PUSH2 0x8FB JUMPI PUSH1 0x40 MLOAD PUSH32 0x230D1CCC00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 DUP2 ADD DUP4 SWAP1 MSTORE PUSH1 0x24 ADD PUSH2 0x3C0 JUMP JUMPDEST PUSH1 0x40 DUP2 ADD CALLDATALOAD DUP1 GAS LT ISZERO PUSH2 0x94E JUMPI DUP3 DUP2 GAS PUSH1 0x40 MLOAD PUSH32 0x2BB3E3BA00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 DUP2 ADD SWAP4 SWAP1 SWAP4 MSTORE PUSH1 0x24 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 ADD PUSH2 0x3C0 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x988 PUSH2 0x963 PUSH1 0x80 DUP6 ADD PUSH1 0x60 DUP7 ADD PUSH2 0x1F26 JUMP JUMPDEST PUSH1 0x80 DUP6 ADD CALLDATALOAD DUP5 ISZERO PUSH2 0x974 JUMPI DUP5 PUSH2 0x976 JUMP JUMPDEST GAS JUMPDEST PUSH2 0x983 PUSH1 0xA0 DUP9 ADD DUP9 PUSH2 0x1F41 JUMP JUMPDEST PUSH2 0xD2F JUMP JUMPDEST SWAP1 POP DUP1 ISZERO PUSH2 0x9CF JUMPI DUP8 PUSH32 0x5C4EEB02DABF8976016AB414D617F9A162936DCACE3CDEF8C69EF6E262AD5AE7 DUP6 PUSH1 0x40 MLOAD PUSH2 0x9C2 SWAP2 DUP2 MSTORE PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG2 PUSH2 0x9F1 JUMP JUMPDEST PUSH2 0x9F1 PUSH2 0x9E2 PUSH1 0x40 DUP6 ADD PUSH1 0x20 DUP7 ADD PUSH2 0x1F0B JUMP JUMPDEST DUP10 DUP7 PUSH2 0x9EC PUSH2 0xD4C JUMP JUMPDEST PUSH2 0xD6B JUMP JUMPDEST POP POP POP DUP1 DUP1 PUSH2 0x9FF SWAP1 PUSH2 0x1FD5 JUMP JUMPDEST SWAP2 POP POP PUSH2 0x885 JUMP JUMPDEST POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP1 DUP1 PUSH2 0xA29 DUP8 PUSH2 0xA24 DUP8 PUSH1 0x6 DUP2 DUP12 PUSH2 0x200D JUMP JUMPDEST PUSH2 0xDB9 JUMP JUMPDEST PUSH1 0x0 SWAP1 DUP2 MSTORE DUP8 CALLDATALOAD PUSH1 0xF0 SHR PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 DUP5 MSTORE PUSH1 0x2 SWAP1 SWAP11 ADD CALLDATALOAD PUSH1 0xE0 SHR SWAP1 DUP2 SWAP1 MSTORE SWAP9 SWAP1 SWAP2 KECCAK256 SWAP1 SWAP10 SWAP2 SWAP9 POP SWAP7 SWAP6 POP SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP1 DUP1 PUSH2 0xA7A DUP8 PUSH2 0xA75 DUP8 PUSH1 0x1 DUP2 DUP12 PUSH2 0x200D JUMP JUMPDEST PUSH2 0xA0E JUMP JUMPDEST SWAP4 POP SWAP4 POP SWAP4 POP SWAP4 POP SWAP4 POP SWAP4 POP SWAP4 POP SWAP4 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x1901000000000000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x0 PUSH1 0x22 DUP3 ADD DUP2 SWAP1 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000 ADDRESS PUSH1 0x60 SHL AND PUSH1 0x42 DUP4 ADD MSTORE PUSH1 0x56 DUP3 ADD DUP4 SWAP1 MSTORE SWAP1 PUSH1 0x76 ADD PUSH2 0x864 JUMP JUMPDEST PUSH1 0x0 DUP1 DUP1 DUP1 DUP1 PUSH1 0x4 PUSH1 0x1 DUP9 ADD CALLDATALOAD PUSH1 0xE8 SHR DUP3 PUSH2 0xB13 DUP4 DUP4 PUSH2 0x2037 JUMP JUMPDEST SWAP1 POP PUSH2 0xB25 DUP12 PUSH2 0x226 DUP4 DUP7 DUP14 DUP16 PUSH2 0x200D JUMP JUMPDEST SWAP4 SWAP12 POP SWAP2 SWAP10 POP SWAP8 POP SWAP6 POP SWAP4 POP DUP8 DUP8 LT ISZERO PUSH2 0xB7D JUMPI PUSH2 0xB45 DUP2 DUP5 DUP12 DUP14 PUSH2 0x200D JUMP JUMPDEST DUP10 DUP10 PUSH1 0x40 MLOAD PUSH32 0xB006ABA000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x204A JUMP JUMPDEST DUP1 SWAP3 POP JUMPDEST DUP9 DUP4 LT ISZERO PUSH2 0xC67 JUMPI PUSH1 0x3 DUP4 ADD SWAP3 DUP11 ADD CALLDATALOAD PUSH1 0xE8 SHR SWAP2 POP PUSH2 0xBA0 DUP4 DUP4 PUSH2 0x2037 JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0xBC2 PUSH2 0xBB0 DUP9 PUSH2 0x124F JUMP JUMPDEST DUP13 DUP13 DUP8 SWAP1 DUP7 SWAP3 PUSH2 0x226 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x200D JUMP JUMPDEST SWAP4 SWAP13 POP SWAP2 SWAP11 POP SWAP9 POP SWAP1 SWAP2 POP POP DUP9 DUP9 LT ISZERO PUSH2 0xC1A JUMPI PUSH2 0xBE2 DUP3 DUP6 DUP13 DUP15 PUSH2 0x200D JUMP JUMPDEST DUP11 DUP11 PUSH1 0x40 MLOAD PUSH32 0xB006ABA000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x204A JUMP JUMPDEST DUP5 DUP2 LT PUSH2 0xC5D JUMPI PUSH1 0x40 MLOAD PUSH32 0x37DAF62B00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x24 DUP2 ADD DUP7 SWAP1 MSTORE PUSH1 0x44 ADD PUSH2 0x3C0 JUMP JUMPDEST SWAP4 POP SWAP2 POP DUP2 PUSH2 0xB81 JUMP JUMPDEST POP POP POP SWAP4 SWAP8 SWAP3 SWAP7 POP SWAP4 POP SWAP4 POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 DUP4 PUSH1 0x40 MLOAD PUSH1 0x20 ADD PUSH2 0xC94 SWAP3 SWAP2 SWAP1 SWAP2 DUP3 MSTORE PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP2 DUP5 SUB ADD DUP2 MSTORE SWAP2 SWAP1 MSTORE DUP1 MLOAD PUSH1 0x20 SWAP1 SWAP2 ADD KECCAK256 SLOAD SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH32 0xE4A77BBC00000000000000000000000000000000000000000000000000000000 PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP4 AND ADD PUSH2 0xD26 JUMPI POP PUSH1 0x1 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH2 0x2CB DUP3 PUSH2 0x1283 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 MLOAD DUP3 DUP5 DUP3 CALLDATACOPY PUSH1 0x0 DUP1 DUP5 DUP4 DUP10 DUP12 DUP11 CALL SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x60 RETURNDATASIZE PUSH1 0x40 MLOAD SWAP2 POP PUSH1 0x20 DUP3 ADD DUP2 DUP2 ADD PUSH1 0x40 MSTORE DUP2 DUP4 MSTORE DUP2 PUSH1 0x0 DUP3 RETURNDATACOPY POP POP SWAP1 JUMP JUMPDEST DUP4 ISZERO PUSH2 0xD79 JUMPI DUP1 MLOAD PUSH1 0x20 DUP3 ADD REVERT JUMPDEST DUP3 PUSH32 0xAB46C69F7F32E1BF09B0725853DA82A211E5402A0600296AB499A2FB5EA3B419 DUP4 DUP4 PUSH1 0x40 MLOAD PUSH2 0xDAB SWAP3 SWAP2 SWAP1 PUSH2 0x2071 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG2 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x1246 JUMPI PUSH1 0x1 DUP2 ADD SWAP1 DUP6 ADD CALLDATALOAD PUSH1 0xF8 SHR PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 ADD PUSH2 0xE60 JUMPI PUSH1 0x15 DUP3 ADD SWAP2 DUP7 ADD CALLDATALOAD PUSH1 0xF8 DUP2 SWAP1 SHR SWAP1 PUSH1 0x58 SHR PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND SWAP1 PUSH21 0xFF0000000000000000000000000000000000000000 AND DUP2 OR DUP6 PUSH2 0xE46 JUMPI DUP1 PUSH2 0xE55 JUMP JUMPDEST PUSH1 0x0 DUP7 DUP2 MSTORE PUSH1 0x20 DUP3 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 JUMPDEST SWAP6 POP POP POP POP POP PUSH2 0xDBF JUMP JUMPDEST DUP1 PUSH2 0xEF6 JUMPI PUSH1 0x1 DUP3 ADD SWAP2 DUP7 DUP2 ADD CALLDATALOAD PUSH1 0xF8 SHR SWAP1 PUSH1 0x43 ADD PUSH1 0x0 PUSH2 0xE8C DUP11 PUSH2 0xE87 DUP5 DUP9 DUP13 DUP15 PUSH2 0x200D JUMP JUMPDEST PUSH2 0x136D JUMP JUMPDEST PUSH1 0xFF DUP5 AND SWAP8 SWAP1 SWAP8 ADD SWAP7 SWAP2 SWAP5 POP DUP5 SWAP2 SWAP1 POP PUSH1 0xA0 DUP4 SWAP1 SHL PUSH21 0xFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 AND OR DUP7 PUSH2 0xEDB JUMPI DUP1 PUSH2 0xEEA JUMP JUMPDEST PUSH1 0x0 DUP8 DUP2 MSTORE PUSH1 0x20 DUP3 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 JUMPDEST SWAP7 POP POP POP POP POP POP PUSH2 0xDBF JUMP JUMPDEST PUSH1 0x2 DUP2 SUB PUSH2 0x101E JUMPI PUSH1 0x0 DUP1 DUP8 DUP5 ADD CALLDATALOAD PUSH1 0xF8 DUP2 SWAP1 SHR SWAP1 PUSH1 0x58 SHR PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x15 DUP7 ADD SWAP6 POP SWAP1 SWAP3 POP SWAP1 POP PUSH1 0x0 DUP9 DUP6 ADD CALLDATALOAD PUSH1 0xE8 SHR PUSH1 0x3 DUP7 ADD DUP2 PUSH3 0xFFFFFF AND SWAP2 POP DUP1 SWAP7 POP DUP2 SWAP3 POP POP POP PUSH1 0x0 DUP2 DUP7 ADD SWAP1 POP PUSH2 0xF6F DUP12 DUP5 DUP13 DUP13 DUP11 SWAP1 DUP7 SWAP3 PUSH2 0xF6A SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x200D JUMP JUMPDEST PUSH2 0x1630 JUMP JUMPDEST PUSH2 0xFB7 JUMPI DUP11 DUP4 PUSH2 0xF81 DUP4 DUP10 DUP14 DUP16 PUSH2 0x200D JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x9A94623200000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x208A JUMP JUMPDEST PUSH1 0xFF DUP5 AND SWAP8 SWAP1 SWAP8 ADD SWAP7 SWAP5 POP DUP5 PUSH1 0xA0 DUP5 SWAP1 SHL PUSH21 0xFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP5 AND OR DUP8 PUSH2 0x1002 JUMPI DUP1 PUSH2 0x1011 JUMP JUMPDEST PUSH1 0x0 DUP9 DUP2 MSTORE PUSH1 0x20 DUP3 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 JUMPDEST SWAP8 POP POP POP POP POP POP POP PUSH2 0xDBF JUMP JUMPDEST PUSH1 0x3 DUP2 SUB PUSH2 0x1051 JUMPI PUSH1 0x20 DUP3 ADD SWAP2 DUP7 ADD CALLDATALOAD DUP4 PUSH2 0x1039 JUMPI DUP1 PUSH2 0x1048 JUMP JUMPDEST PUSH1 0x0 DUP5 DUP2 MSTORE PUSH1 0x20 DUP3 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 JUMPDEST SWAP4 POP POP POP PUSH2 0xDBF JUMP JUMPDEST PUSH1 0x4 DUP2 SUB PUSH2 0x109D JUMPI PUSH1 0x3 DUP1 DUP4 ADD SWAP3 DUP8 DUP2 ADD CALLDATALOAD PUSH1 0xE8 SHR SWAP2 SWAP1 DUP3 ADD ADD PUSH1 0x0 DUP1 PUSH2 0x107E DUP12 PUSH2 0xA24 DUP6 DUP10 DUP14 DUP16 PUSH2 0x200D JUMP JUMPDEST PUSH1 0x0 SWAP9 DUP10 MSTORE PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 SWAP8 KECCAK256 SWAP7 SWAP1 SWAP8 ADD SWAP7 POP SWAP1 SWAP4 POP PUSH2 0xDBF SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x6 DUP2 SUB PUSH2 0x11A5 JUMPI PUSH1 0x0 DUP3 DUP8 ADD CALLDATALOAD PUSH1 0xF8 SHR PUSH1 0x1 DUP5 ADD SWAP4 POP PUSH1 0xFF AND SWAP1 POP PUSH1 0x0 DUP8 DUP5 ADD CALLDATALOAD PUSH1 0xF0 SHR PUSH1 0x2 DUP6 ADD SWAP5 POP PUSH2 0xFFFF AND SWAP1 POP PUSH1 0x0 DUP9 DUP6 ADD CALLDATALOAD PUSH1 0xE8 SHR PUSH1 0x3 DUP7 ADD DUP2 PUSH3 0xFFFFFF AND SWAP2 POP DUP1 SWAP7 POP DUP2 SWAP3 POP POP POP PUSH1 0x0 DUP2 DUP7 ADD SWAP1 POP PUSH1 0x0 DUP1 PUSH2 0x110B DUP14 DUP14 DUP14 DUP12 SWAP1 DUP8 SWAP3 PUSH2 0xA24 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x200D JUMP JUMPDEST SWAP4 SWAP9 POP DUP9 SWAP4 SWAP1 SWAP3 POP SWAP1 POP DUP5 DUP3 LT PUSH2 0x1121 JUMPI SWAP9 DUP6 ADD SWAP9 JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x53657175656E6365206E657374656420636F6E6669673A0A0000000000000000 PUSH1 0x20 DUP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x38 DUP3 ADD DUP5 SWAP1 MSTORE PUSH1 0x58 DUP3 ADD DUP9 SWAP1 MSTORE PUSH1 0x78 DUP1 DUP4 ADD DUP11 SWAP1 MSTORE DUP4 MLOAD DUP1 DUP5 SUB SWAP1 SWAP2 ADD DUP2 MSTORE PUSH1 0x98 SWAP1 SWAP3 ADD SWAP1 SWAP3 MSTORE DUP1 MLOAD SWAP2 ADD KECCAK256 DUP10 PUSH2 0x1187 JUMPI DUP1 PUSH2 0x1196 JUMP JUMPDEST PUSH1 0x0 DUP11 DUP2 MSTORE PUSH1 0x20 DUP3 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 JUMPDEST SWAP10 POP POP POP POP POP POP POP POP POP PUSH2 0xDBF JUMP JUMPDEST PUSH1 0x5 DUP2 SUB PUSH2 0x1211 JUMPI PUSH1 0x20 DUP3 ADD SWAP2 DUP7 ADD CALLDATALOAD DUP8 DUP2 SUB PUSH2 0x11E0 JUMPI PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP5 POP JUMPDEST PUSH1 0x0 PUSH2 0x11EB DUP3 PUSH2 0x1817 JUMP JUMPDEST SWAP1 POP DUP5 PUSH2 0x11F8 JUMPI DUP1 PUSH2 0x1207 JUMP JUMPDEST PUSH1 0x0 DUP6 DUP2 MSTORE PUSH1 0x20 DUP3 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 JUMPDEST SWAP5 POP POP POP POP PUSH2 0xDBF JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0xB2505F7C00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x24 ADD PUSH2 0x3C0 JUMP JUMPDEST POP SWAP4 POP SWAP4 SWAP2 POP POP JUMP JUMPDEST PUSH32 0x8713A7C4465F6FBEE2B6E9D6646D1D9F83FEC929EDFC4BAF661F3C865BDD04D1 PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x20 DUP3 SWAP1 MSTORE PUSH1 0x40 DUP2 KECCAK256 PUSH2 0x2CB JUMP JUMPDEST PUSH1 0x0 PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP3 AND PUSH32 0xAC6A444E00000000000000000000000000000000000000000000000000000000 EQ DUP1 PUSH2 0x1316 JUMPI POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP3 AND PUSH32 0x36E7817500000000000000000000000000000000000000000000000000000000 EQ JUMPDEST ISZERO PUSH2 0x1323 JUMPI POP PUSH1 0x1 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH32 0x1FFC9A700000000000000000000000000000000000000000000000000000000 PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP4 AND EQ PUSH2 0x2CB JUMP JUMPDEST PUSH1 0x0 PUSH1 0x42 DUP3 EQ PUSH2 0x13AD JUMPI DUP3 DUP3 PUSH1 0x40 MLOAD PUSH32 0x2EE17A3D00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP3 SWAP2 SWAP1 PUSH2 0x20CA JUMP JUMPDEST PUSH1 0x0 PUSH2 0x13C6 PUSH2 0x13BD PUSH1 0x1 DUP6 PUSH2 0x20DE JUMP JUMPDEST DUP6 ADD CALLDATALOAD PUSH1 0xF8 SHR SWAP1 JUMP JUMPDEST PUSH1 0xFF AND SWAP1 POP PUSH1 0x40 DUP5 ADD CALLDATALOAD PUSH1 0xF8 SHR DUP5 CALLDATALOAD PUSH1 0x20 DUP7 ADD CALLDATALOAD PUSH32 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 DUP2 GT ISZERO PUSH2 0x143A JUMPI DUP7 DUP7 DUP3 PUSH1 0x40 MLOAD PUSH32 0xAD4AAC7600000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x20F1 JUMP JUMPDEST DUP3 PUSH1 0xFF AND PUSH1 0x1B EQ ISZERO DUP1 ISZERO PUSH2 0x1452 JUMPI POP DUP3 PUSH1 0xFF AND PUSH1 0x1C EQ ISZERO JUMPDEST ISZERO PUSH2 0x148F JUMPI DUP7 DUP7 DUP5 PUSH1 0x40 MLOAD PUSH32 0xE578897E00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x2115 JUMP JUMPDEST PUSH1 0x1 DUP5 SUB PUSH2 0x14FC JUMPI PUSH1 0x40 DUP1 MLOAD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 DUP2 ADD DUP1 DUP4 MSTORE DUP11 SWAP1 MSTORE PUSH1 0xFF DUP6 AND SWAP2 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x60 DUP2 ADD DUP4 SWAP1 MSTORE PUSH1 0x80 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x1 SWAP1 PUSH1 0xA0 ADD JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 SUB SWAP1 DUP1 DUP5 SUB SWAP1 DUP6 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x14EB JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP PUSH1 0x20 PUSH1 0x40 MLOAD SUB MLOAD SWAP5 POP PUSH2 0x15D4 JUMP JUMPDEST PUSH1 0x2 DUP5 SUB PUSH2 0x1599 JUMPI PUSH1 0x40 MLOAD PUSH32 0x19457468657265756D205369676E6564204D6573736167653A0A333200000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x3C DUP2 ADD DUP10 SWAP1 MSTORE PUSH1 0x1 SWAP1 PUSH1 0x5C ADD PUSH1 0x40 DUP1 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP2 DUP5 SUB ADD DUP2 MSTORE DUP3 DUP3 MSTORE DUP1 MLOAD PUSH1 0x20 SWAP2 DUP3 ADD KECCAK256 PUSH1 0x0 DUP5 MSTORE SWAP1 DUP4 ADD DUP1 DUP4 MSTORE MSTORE PUSH1 0xFF DUP7 AND SWAP1 DUP3 ADD MSTORE PUSH1 0x60 DUP2 ADD DUP5 SWAP1 MSTORE PUSH1 0x80 DUP2 ADD DUP4 SWAP1 MSTORE PUSH1 0xA0 ADD PUSH2 0x14C9 JUMP JUMPDEST DUP7 DUP7 DUP6 PUSH1 0x1 PUSH1 0x40 MLOAD PUSH32 0x9DFBA85200000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x213C JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP6 AND PUSH2 0x1625 JUMPI DUP7 DUP7 PUSH1 0x40 MLOAD PUSH32 0x6C1719D200000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP3 SWAP2 SWAP1 PUSH2 0x20CA JUMP JUMPDEST POP POP POP POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 SUB PUSH2 0x166B JUMPI PUSH1 0x40 MLOAD PUSH32 0xAC241E1100000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 DUP4 DUP4 PUSH2 0x167A PUSH1 0x1 DUP3 PUSH2 0x20DE JUMP JUMPDEST DUP2 DUP2 LT PUSH2 0x1689 JUMPI PUSH2 0x1689 PUSH2 0x1E27 JUMP JUMPDEST SWAP2 SWAP1 SWAP2 ADD CALLDATALOAD PUSH1 0xF8 SHR SWAP2 POP POP PUSH1 0x1 DUP2 EQ DUP1 PUSH2 0x16A3 JUMPI POP PUSH1 0x2 DUP2 EQ JUMPDEST ISZERO PUSH2 0x16E8 JUMPI DUP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH2 0x16CA DUP8 DUP7 DUP7 PUSH2 0x136D JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ SWAP2 POP PUSH2 0x180E JUMP JUMPDEST PUSH1 0x3 DUP2 SUB PUSH2 0x17D3 JUMPI PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP6 AND PUSH4 0x1626BA7E DUP8 DUP7 PUSH1 0x0 DUP8 PUSH2 0x171C PUSH1 0x1 DUP3 PUSH2 0x20DE JUMP JUMPDEST SWAP3 PUSH2 0x1729 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x200D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP5 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x1747 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x2168 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x1764 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x1788 SWAP2 SWAP1 PUSH2 0x218B JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND PUSH32 0x1626BA7E00000000000000000000000000000000000000000000000000000000 EQ SWAP2 POP PUSH2 0x180E JUMP JUMPDEST DUP4 DUP4 DUP3 PUSH1 0x0 PUSH1 0x40 MLOAD PUSH32 0x9DFBA85200000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x213C JUMP JUMPDEST POP SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x53657175656E636520737461746963206469676573743A0A0000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x38 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x0 SWAP1 PUSH1 0x58 ADD PUSH2 0x864 JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND DUP2 EQ PUSH2 0x3D2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1892 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x317 DUP2 PUSH2 0x1852 JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 PUSH1 0x1F DUP5 ADD SLT PUSH2 0x18AF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x18C7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 DUP4 ADD SWAP2 POP DUP4 PUSH1 0x20 DUP3 DUP6 ADD ADD GT ISZERO PUSH2 0x18DF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x40 DUP5 DUP7 SUB SLT ISZERO PUSH2 0x18FB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 CALLDATALOAD SWAP3 POP PUSH1 0x20 DUP5 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x1919 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x1925 DUP7 DUP3 DUP8 ADD PUSH2 0x189D JUMP JUMPDEST SWAP5 SWAP8 SWAP1 SWAP7 POP SWAP4 SWAP5 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x40 DUP6 DUP8 SUB SLT ISZERO PUSH2 0x1948 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0x1960 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x196C DUP9 DUP4 DUP10 ADD PUSH2 0x189D JUMP JUMPDEST SWAP1 SWAP7 POP SWAP5 POP PUSH1 0x20 DUP8 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0x1985 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1992 DUP8 DUP3 DUP9 ADD PUSH2 0x189D JUMP JUMPDEST SWAP6 SWAP9 SWAP5 SWAP8 POP SWAP6 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x19B0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP CALLDATALOAD SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 PUSH1 0x1F DUP5 ADD SLT PUSH2 0x19C9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x19E1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 DUP4 ADD SWAP2 POP DUP4 PUSH1 0x20 DUP3 PUSH1 0x5 SHL DUP6 ADD ADD GT ISZERO PUSH2 0x18DF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x20 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x1A0F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x1A26 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x1A32 DUP6 DUP3 DUP7 ADD PUSH2 0x19B7 JUMP JUMPDEST SWAP1 SWAP7 SWAP1 SWAP6 POP SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP7 DUP9 SUB SLT ISZERO PUSH2 0x1A56 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP6 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0x1A6E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x1A7A DUP10 DUP4 DUP11 ADD PUSH2 0x19B7 JUMP JUMPDEST SWAP1 SWAP8 POP SWAP6 POP PUSH1 0x20 DUP9 ADD CALLDATALOAD SWAP5 POP PUSH1 0x40 DUP9 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0x1A9A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1AA7 DUP9 DUP3 DUP10 ADD PUSH2 0x189D JUMP JUMPDEST SWAP7 SWAP10 SWAP6 SWAP9 POP SWAP4 SWAP7 POP SWAP3 SWAP5 SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH32 0x4E487B7100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 MSTORE PUSH1 0x41 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1AF9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0x1B11 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 DUP5 ADD SWAP2 POP DUP5 PUSH1 0x1F DUP4 ADD SLT PUSH2 0x1B25 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD DUP2 DUP2 GT ISZERO PUSH2 0x1B37 JUMPI PUSH2 0x1B37 PUSH2 0x1AB8 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1F DUP3 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 DUP2 AND PUSH1 0x3F ADD AND DUP2 ADD SWAP1 DUP4 DUP3 GT DUP2 DUP4 LT OR ISZERO PUSH2 0x1B7D JUMPI PUSH2 0x1B7D PUSH2 0x1AB8 JUMP JUMPDEST DUP2 PUSH1 0x40 MSTORE DUP3 DUP2 MSTORE DUP8 PUSH1 0x20 DUP5 DUP8 ADD ADD GT ISZERO PUSH2 0x1B96 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP4 ADD CALLDATACOPY PUSH1 0x0 SWAP3 DUP2 ADD PUSH1 0x20 ADD SWAP3 SWAP1 SWAP3 MSTORE POP SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST DUP2 DUP4 DUP3 CALLDATACOPY PUSH1 0x0 SWAP2 ADD SWAP1 DUP2 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST DUP1 CALLDATALOAD DUP1 ISZERO ISZERO DUP2 EQ PUSH2 0x1BD6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP2 SWAP1 POP JUMP JUMPDEST DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND DUP2 EQ PUSH2 0x1BD6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 DUP4 MSTORE DUP2 DUP2 PUSH1 0x20 DUP6 ADD CALLDATACOPY POP PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 ADD ADD MSTORE PUSH1 0x0 PUSH1 0x20 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 PUSH1 0x1F DUP5 ADD AND DUP5 ADD ADD SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST DUP2 DUP4 MSTORE PUSH1 0x0 PUSH1 0x20 DUP1 DUP6 ADD DUP1 DUP2 SWAP7 POP DUP6 PUSH1 0x5 SHL DUP2 ADD SWAP2 POP DUP5 PUSH1 0x0 JUMPDEST DUP8 DUP2 LT ISZERO PUSH2 0x1D8A JUMPI DUP3 DUP5 SUB DUP10 MSTORE DUP2 CALLDATALOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 DUP9 CALLDATASIZE SUB ADD DUP2 SLT PUSH2 0x1CA1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP8 ADD PUSH1 0xC0 PUSH2 0x1CAE DUP3 PUSH2 0x1BC6 JUMP JUMPDEST ISZERO ISZERO DUP7 MSTORE PUSH2 0x1CBD DUP8 DUP4 ADD PUSH2 0x1BC6 JUMP JUMPDEST ISZERO ISZERO DUP7 DUP9 ADD MSTORE PUSH1 0x40 DUP3 DUP2 ADD CALLDATALOAD SWAP1 DUP8 ADD MSTORE PUSH1 0x60 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH2 0x1CEF DUP3 DUP6 ADD PUSH2 0x1BDB JUMP JUMPDEST AND SWAP1 DUP8 ADD MSTORE PUSH1 0x80 DUP3 DUP2 ADD CALLDATALOAD SWAP1 DUP8 ADD MSTORE PUSH1 0xA0 DUP1 DUP4 ADD CALLDATALOAD CALLDATASIZE DUP5 SWAP1 SUB PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 ADD DUP2 SLT PUSH2 0x1D35 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP1 SWAP3 ADD DUP8 DUP2 ADD SWAP3 SWAP1 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x1D53 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 CALLDATASIZE SUB DUP5 SGT ISZERO PUSH2 0x1D62 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 DUP3 DUP10 ADD MSTORE PUSH2 0x1D74 DUP4 DUP10 ADD DUP3 DUP7 PUSH2 0x1BFF JUMP JUMPDEST SWAP13 DUP10 ADD SWAP13 SWAP8 POP POP POP SWAP3 DUP7 ADD SWAP3 POP POP PUSH1 0x1 ADD PUSH2 0x1C62 JUMP JUMPDEST POP SWAP2 SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP2 MSTORE PUSH1 0x5 PUSH1 0x40 DUP3 ADD MSTORE PUSH32 0x73656C663A000000000000000000000000000000000000000000000000000000 PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x0 PUSH2 0x37B PUSH1 0x80 DUP4 ADD DUP5 DUP7 PUSH2 0x1C48 JUMP JUMPDEST PUSH1 0x40 DUP2 MSTORE PUSH1 0x6 PUSH1 0x40 DUP3 ADD MSTORE PUSH32 0x67756573743A0000000000000000000000000000000000000000000000000000 PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x0 PUSH2 0x37B PUSH1 0x80 DUP4 ADD DUP5 DUP7 PUSH2 0x1C48 JUMP JUMPDEST PUSH32 0x4E487B7100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 MSTORE PUSH1 0x32 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 DUP2 MLOAD DUP1 DUP5 MSTORE PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0x1E7C JUMPI PUSH1 0x20 DUP2 DUP6 ADD DUP2 ADD MLOAD DUP7 DUP4 ADD DUP3 ADD MSTORE ADD PUSH2 0x1E60 JUMP JUMPDEST POP PUSH1 0x0 PUSH1 0x20 DUP3 DUP7 ADD ADD MSTORE PUSH1 0x20 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 PUSH1 0x1F DUP4 ADD AND DUP6 ADD ADD SWAP2 POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x20 DUP2 MSTORE PUSH1 0x0 PUSH2 0x317 PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0x1E56 JUMP JUMPDEST PUSH1 0x0 DUP3 CALLDATALOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 DUP4 CALLDATASIZE SUB ADD DUP2 SLT PUSH2 0x1F01 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP2 SWAP1 SWAP2 ADD SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1F1D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x317 DUP3 PUSH2 0x1BC6 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1F38 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x317 DUP3 PUSH2 0x1BDB JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 CALLDATALOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 DUP5 CALLDATASIZE SUB ADD DUP2 SLT PUSH2 0x1F76 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 ADD DUP1 CALLDATALOAD SWAP2 POP PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x1F91 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 ADD SWAP2 POP CALLDATASIZE DUP2 SWAP1 SUB DUP3 SGT ISZERO PUSH2 0x18DF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH32 0x4E487B7100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 MSTORE PUSH1 0x11 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 SUB PUSH2 0x2006 JUMPI PUSH2 0x2006 PUSH2 0x1FA6 JUMP JUMPDEST POP PUSH1 0x1 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 DUP6 DUP6 GT ISZERO PUSH2 0x201D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 DUP7 GT ISZERO PUSH2 0x202A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP POP DUP3 ADD SWAP4 SWAP2 SWAP1 SWAP3 SUB SWAP2 POP JUMP JUMPDEST DUP1 DUP3 ADD DUP1 DUP3 GT ISZERO PUSH2 0x2CB JUMPI PUSH2 0x2CB PUSH2 0x1FA6 JUMP JUMPDEST PUSH1 0x60 DUP2 MSTORE PUSH1 0x0 PUSH2 0x205E PUSH1 0x60 DUP4 ADD DUP7 DUP9 PUSH2 0x1BFF JUMP JUMPDEST PUSH1 0x20 DUP4 ADD SWAP5 SWAP1 SWAP5 MSTORE POP PUSH1 0x40 ADD MSTORE SWAP3 SWAP2 POP POP JUMP JUMPDEST DUP3 DUP2 MSTORE PUSH1 0x40 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x0 PUSH2 0x37B PUSH1 0x40 DUP4 ADD DUP5 PUSH2 0x1E56 JUMP JUMPDEST DUP5 DUP2 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP5 AND PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x60 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x0 PUSH2 0x20C0 PUSH1 0x60 DUP4 ADD DUP5 DUP7 PUSH2 0x1BFF JUMP JUMPDEST SWAP7 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x20 DUP2 MSTORE PUSH1 0x0 PUSH2 0x37B PUSH1 0x20 DUP4 ADD DUP5 DUP7 PUSH2 0x1BFF JUMP JUMPDEST DUP2 DUP2 SUB DUP2 DUP2 GT ISZERO PUSH2 0x2CB JUMPI PUSH2 0x2CB PUSH2 0x1FA6 JUMP JUMPDEST PUSH1 0x40 DUP2 MSTORE PUSH1 0x0 PUSH2 0x2105 PUSH1 0x40 DUP4 ADD DUP6 DUP8 PUSH2 0x1BFF JUMP JUMPDEST SWAP1 POP DUP3 PUSH1 0x20 DUP4 ADD MSTORE SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP2 MSTORE PUSH1 0x0 PUSH2 0x2129 PUSH1 0x40 DUP4 ADD DUP6 DUP8 PUSH2 0x1BFF JUMP JUMPDEST SWAP1 POP PUSH1 0xFF DUP4 AND PUSH1 0x20 DUP4 ADD MSTORE SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x60 DUP2 MSTORE PUSH1 0x0 PUSH2 0x2150 PUSH1 0x60 DUP4 ADD DUP7 DUP9 PUSH2 0x1BFF JUMP JUMPDEST PUSH1 0x20 DUP4 ADD SWAP5 SWAP1 SWAP5 MSTORE POP SWAP1 ISZERO ISZERO PUSH1 0x40 SWAP1 SWAP2 ADD MSTORE SWAP3 SWAP2 POP POP JUMP JUMPDEST DUP4 DUP2 MSTORE PUSH1 0x40 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x0 PUSH2 0x2182 PUSH1 0x40 DUP4 ADD DUP5 DUP7 PUSH2 0x1BFF JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x219D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 MLOAD PUSH2 0x317 DUP2 PUSH2 0x1852 JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 SWAP12 0xB9 0x5D XOR 0xE9 PUSH32 0x278AA47E0C04C20D5A6AF9BDB6D473C6D4051192CD96FC17866864736F6C6343 STOP ADDMOD SLT STOP CALLER ", + "sourceMap": "640:2693:1:-:0;;;;;;;;;;;;-1:-1:-1;200:4:7;185:20;;640:2693:1;;;;;;;;;;;" + }, + "deployedBytecode": { + "functionDebugData": { + "@SET_IMAGE_HASH_TYPE_HASH_2042": { + "entryPoint": null, + "id": 2042, + "parameterSlots": 0, + "returnSlots": 0 + }, + "@_executeGuest_199": { + "entryPoint": 2177, + "id": 199, + "parameterSlots": 3, + "returnSlots": 0 + }, + "@_hashSetImageHashStruct_2071": { + "entryPoint": 4687, + "id": 2071, + "parameterSlots": 1, + "returnSlots": 1 + }, + "@_isValidImage_211": { + "entryPoint": null, + "id": 211, + "parameterSlots": 1, + "returnSlots": 1 + }, + "@_leafForAddressAndWeight_1424": { + "entryPoint": null, + "id": 1424, + "parameterSlots": 2, + "returnSlots": 1 + }, + "@_leafForHardcodedSubdigest_1441": { + "entryPoint": 6167, + "id": 1441, + "parameterSlots": 1, + "returnSlots": 1 + }, + "@_leafForNested_1464": { + "entryPoint": null, + "id": 1464, + "parameterSlots": 3, + "returnSlots": 1 + }, + "@_revertBytes_807": { + "entryPoint": 3435, + "id": 807, + "parameterSlots": 4, + "returnSlots": 0 + }, + "@_signatureValidation_457": { + "entryPoint": 1938, + "id": 457, + "parameterSlots": 3, + "returnSlots": 2 + }, + "@_updateImageHash_222": { + "entryPoint": 1994, + "id": 222, + "parameterSlots": 1, + "returnSlots": 0 + }, + "@call_2515": { + "entryPoint": 3375, + "id": 2515, + "parameterSlots": 5, + "returnSlots": 1 + }, + "@chainedRecover_2217": { + "entryPoint": 2808, + "id": 2217, + "parameterSlots": 3, + "returnSlots": 5 + }, + "@createContract_876": { + "entryPoint": 1595, + "id": 876, + "parameterSlots": 1, + "returnSlots": 1 + }, + "@execute_74": { + "entryPoint": 1050, + "id": 74, + "parameterSlots": 5, + "returnSlots": 0 + }, + "@fkeccak256_2491": { + "entryPoint": null, + "id": 2491, + "parameterSlots": 2, + "returnSlots": 1 + }, + "@isValidSignature_2797": { + "entryPoint": 5680, + "id": 2797, + "parameterSlots": 4, + "returnSlots": 1 + }, + "@isValidSignature_488": { + "entryPoint": 798, + "id": 488, + "parameterSlots": 4, + "returnSlots": 1 + }, + "@isValidSignature_517": { + "entryPoint": 721, + "id": 517, + "parameterSlots": 3, + "returnSlots": 1 + }, + "@nonce_955": { + "entryPoint": 1829, + "id": 955, + "parameterSlots": 0, + "returnSlots": 1 + }, + "@readBytes32Map_1178": { + "entryPoint": 3189, + "id": 1178, + "parameterSlots": 2, + "returnSlots": 1 + }, + "@readBytes32_2339": { + "entryPoint": null, + "id": 2339, + "parameterSlots": 3, + "returnSlots": 1 + }, + "@readBytes32_2475": { + "entryPoint": null, + "id": 2475, + "parameterSlots": 3, + "returnSlots": 2 + }, + "@readFirstUint16_2361": { + "entryPoint": null, + "id": 2361, + "parameterSlots": 2, + "returnSlots": 1 + }, + "@readNonce_976": { + "entryPoint": 1551, + "id": 976, + "parameterSlots": 1, + "returnSlots": 1 + }, + "@readUint16_2433": { + "entryPoint": null, + "id": 2433, + "parameterSlots": 3, + "returnSlots": 2 + }, + "@readUint24_2447": { + "entryPoint": null, + "id": 2447, + "parameterSlots": 3, + "returnSlots": 2 + }, + "@readUint32_2373": { + "entryPoint": null, + "id": 2373, + "parameterSlots": 3, + "returnSlots": 1 + }, + "@readUint8Address_2419": { + "entryPoint": null, + "id": 2419, + "parameterSlots": 3, + "returnSlots": 3 + }, + "@readUint8_2351": { + "entryPoint": null, + "id": 2351, + "parameterSlots": 3, + "returnSlots": 1 + }, + "@readUint8_2403": { + "entryPoint": null, + "id": 2403, + "parameterSlots": 3, + "returnSlots": 2 + }, + "@recoverBranch_1954": { + "entryPoint": 3513, + "id": 1954, + "parameterSlots": 3, + "returnSlots": 2 + }, + "@recoverSigner_2715": { + "entryPoint": 4973, + "id": 2715, + "parameterSlots": 3, + "returnSlots": 1 + }, + "@recover_2020": { + "entryPoint": 2574, + "id": 2020, + "parameterSlots": 3, + "returnSlots": 4 + }, + "@recover_2246": { + "entryPoint": 2655, + "id": 2246, + "parameterSlots": 3, + "returnSlots": 4 + }, + "@returnData_2499": { + "entryPoint": 3404, + "id": 2499, + "parameterSlots": 0, + "returnSlots": 1 + }, + "@selfExecute_102": { + "entryPoint": 981, + "id": 102, + "parameterSlots": 2, + "returnSlots": 0 + }, + "@signatureRecovery_413": { + "entryPoint": 1095, + "id": 413, + "parameterSlots": 3, + "returnSlots": 5 + }, + "@subdigest_1394": { + "entryPoint": 2044, + "id": 1394, + "parameterSlots": 1, + "returnSlots": 1 + }, + "@subdigest_2274": { + "entryPoint": 2699, + "id": 2274, + "parameterSlots": 1, + "returnSlots": 1 + }, + "@supportsInterface_240": { + "entryPoint": 704, + "id": 240, + "parameterSlots": 1, + "returnSlots": 1 + }, + "@supportsInterface_549": { + "entryPoint": 4739, + "id": 549, + "parameterSlots": 1, + "returnSlots": 1 + }, + "@supportsInterface_832": { + "entryPoint": 3283, + "id": 832, + "parameterSlots": 1, + "returnSlots": 1 + }, + "@supportsInterface_901": { + "entryPoint": 1846, + "id": 901, + "parameterSlots": 1, + "returnSlots": 1 + }, + "@supportsInterface_919": { + "entryPoint": null, + "id": 919, + "parameterSlots": 1, + "returnSlots": 1 + }, + "@updateImageHash_563": { + "entryPoint": 899, + "id": 563, + "parameterSlots": 1, + "returnSlots": 0 + }, + "abi_decode_address": { + "entryPoint": 7131, + "id": null, + "parameterSlots": 1, + "returnSlots": 1 + }, + "abi_decode_array_struct_Transaction_calldata_dyn_calldata": { + "entryPoint": 6583, + "id": null, + "parameterSlots": 2, + "returnSlots": 2 + }, + "abi_decode_bool": { + "entryPoint": 7110, + "id": null, + "parameterSlots": 1, + "returnSlots": 1 + }, + "abi_decode_bytes_calldata": { + "entryPoint": 6301, + "id": null, + "parameterSlots": 2, + "returnSlots": 2 + }, + "abi_decode_tuple_t_address": { + "entryPoint": 7974, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_decode_tuple_t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr": { + "entryPoint": 6652, + "id": null, + "parameterSlots": 2, + "returnSlots": 2 + }, + "abi_decode_tuple_t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptrt_uint256t_bytes_calldata_ptr": { + "entryPoint": 6718, + "id": null, + "parameterSlots": 2, + "returnSlots": 5 + }, + "abi_decode_tuple_t_bool": { + "entryPoint": 7947, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_decode_tuple_t_bytes32": { + "entryPoint": 6558, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_decode_tuple_t_bytes32t_bytes_calldata_ptr": { + "entryPoint": 6374, + "id": null, + "parameterSlots": 2, + "returnSlots": 3 + }, + "abi_decode_tuple_t_bytes4": { + "entryPoint": 6272, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_decode_tuple_t_bytes4_fromMemory": { + "entryPoint": 8587, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_decode_tuple_t_bytes_calldata_ptrt_bytes_calldata_ptr": { + "entryPoint": 6450, + "id": null, + "parameterSlots": 2, + "returnSlots": 4 + }, + "abi_decode_tuple_t_bytes_memory_ptr": { + "entryPoint": 6887, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_decode_tuple_t_uint256": { + "entryPoint": null, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_array_struct_Transaction_calldata_dyn_calldata": { + "entryPoint": 7240, + "id": null, + "parameterSlots": 3, + "returnSlots": 1 + }, + "abi_encode_bytes": { + "entryPoint": 7766, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_bytes_calldata": { + "entryPoint": 7167, + "id": null, + "parameterSlots": 3, + "returnSlots": 1 + }, + "abi_encode_tuple_packed_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__nonPadded_inplace_fromStack_reversed": { + "entryPoint": 7094, + "id": null, + "parameterSlots": 3, + "returnSlots": 1 + }, + "abi_encode_tuple_packed_t_stringliteral_178a2411ab6fbc1ba11064408972259c558d0e82fd48b0aba3ad81d14f065e73_t_bytes32__to_t_string_memory_ptr_t_bytes32__nonPadded_inplace_fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_tuple_packed_t_stringliteral_301a50b291d33ce1e8e9064e3f6a6c51d902ec22892b50d58abf6357c6a45541_t_uint256_t_address_t_bytes32__to_t_string_memory_ptr_t_uint256_t_address_t_bytes32__nonPadded_inplace_fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 4, + "returnSlots": 1 + }, + "abi_encode_tuple_packed_t_stringliteral_583557e68bca91e5400591dbc9ae31043113c95e3cd985463ae532f51d706f8c_t_bytes32__to_t_string_memory_ptr_t_bytes32__nonPadded_inplace_fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_tuple_packed_t_stringliteral_58d1832f15932b40f8da147bd99ac98efab990f25a786a2229b05ee5f5be41a7_t_bytes32_t_uint256_t_uint256__to_t_string_memory_ptr_t_bytes32_t_uint256_t_uint256__nonPadded_inplace_fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 4, + "returnSlots": 1 + }, + "abi_encode_tuple_t_address__to_t_address__fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_tuple_t_address_t_address__to_t_address_t_address__fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 3, + "returnSlots": 1 + }, + "abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_tuple_t_bytes1__to_t_bytes1__fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_tuple_t_bytes32__to_t_bytes32__fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_tuple_t_bytes32_t_address_t_bytes_calldata_ptr_slice__to_t_bytes32_t_address_t_bytes_memory_ptr__fromStack_reversed": { + "entryPoint": 8330, + "id": null, + "parameterSlots": 5, + "returnSlots": 1 + }, + "abi_encode_tuple_t_bytes32_t_bytes32__to_t_bytes32_t_bytes32__fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 3, + "returnSlots": 1 + }, + "abi_encode_tuple_t_bytes32_t_bytes_calldata_ptr_slice__to_t_bytes32_t_bytes_memory_ptr__fromStack_reversed": { + "entryPoint": 8552, + "id": null, + "parameterSlots": 4, + "returnSlots": 1 + }, + "abi_encode_tuple_t_bytes32_t_uint8_t_bytes32_t_bytes32__to_t_bytes32_t_uint8_t_bytes32_t_bytes32__fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 5, + "returnSlots": 1 + }, + "abi_encode_tuple_t_bytes4__to_t_bytes4__fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_tuple_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__fromStack_reversed": { + "entryPoint": 8394, + "id": null, + "parameterSlots": 3, + "returnSlots": 1 + }, + "abi_encode_tuple_t_bytes_calldata_ptr_slice_t_uint256_t_uint256__to_t_bytes_memory_ptr_t_uint256_t_uint256__fromStack_reversed": { + "entryPoint": 8266, + "id": null, + "parameterSlots": 5, + "returnSlots": 1 + }, + "abi_encode_tuple_t_bytes_calldata_ptr_t_bytes32__to_t_bytes_memory_ptr_t_bytes32__fromStack_reversed": { + "entryPoint": 8433, + "id": null, + "parameterSlots": 4, + "returnSlots": 1 + }, + "abi_encode_tuple_t_bytes_calldata_ptr_t_uint256_t_bool__to_t_bytes_memory_ptr_t_uint256_t_bool__fromStack_reversed": { + "entryPoint": 8508, + "id": null, + "parameterSlots": 5, + "returnSlots": 1 + }, + "abi_encode_tuple_t_bytes_calldata_ptr_t_uint8__to_t_bytes_memory_ptr_t_uint256__fromStack_reversed": { + "entryPoint": 8469, + "id": null, + "parameterSlots": 4, + "returnSlots": 1 + }, + "abi_encode_tuple_t_bytes_memory_ptr__to_t_bytes_memory_ptr__fromStack_reversed": { + "entryPoint": 7866, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_tuple_t_stringliteral_4dfa0bed92fb5c2df0b47ce555e6e6b89f746e856aa9783c634a4987edcbf682_t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr__to_t_string_memory_ptr_t_array$_t_struct$_Transaction_$1292_memory_ptr_$dyn_memory_ptr__fromStack_reversed": { + "entryPoint": 7647, + "id": null, + "parameterSlots": 3, + "returnSlots": 1 + }, + "abi_encode_tuple_t_stringliteral_bf9461da9f9c0123d3a54c61147a274d8fdb5d5c1e488665fb11b9edbbc32845_t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr__to_t_string_memory_ptr_t_array$_t_struct$_Transaction_$1292_memory_ptr_$dyn_memory_ptr__fromStack_reversed": { + "entryPoint": 7575, + "id": null, + "parameterSlots": 3, + "returnSlots": 1 + }, + "abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_tuple_t_uint256_t_bytes_memory_ptr__to_t_uint256_t_bytes_memory_ptr__fromStack_reversed": { + "entryPoint": 8305, + "id": null, + "parameterSlots": 3, + "returnSlots": 1 + }, + "abi_encode_tuple_t_uint256_t_uint256__to_t_uint256_t_uint256__fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 3, + "returnSlots": 1 + }, + "abi_encode_tuple_t_uint256_t_uint256_t_bytes32_t_bytes32_t_uint256__to_t_uint256_t_uint256_t_bytes32_t_bytes32_t_uint256__fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 6, + "returnSlots": 1 + }, + "abi_encode_tuple_t_uint256_t_uint256_t_uint256__to_t_uint256_t_uint256_t_uint256__fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 4, + "returnSlots": 1 + }, + "access_calldata_tail_t_bytes_calldata_ptr": { + "entryPoint": 8001, + "id": null, + "parameterSlots": 2, + "returnSlots": 2 + }, + "access_calldata_tail_t_struct$_Transaction_$1292_calldata_ptr": { + "entryPoint": 7885, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "calldata_array_index_range_access_t_bytes_calldata_ptr": { + "entryPoint": 8205, + "id": null, + "parameterSlots": 4, + "returnSlots": 2 + }, + "checked_add_t_uint256": { + "entryPoint": 8247, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "checked_sub_t_uint256": { + "entryPoint": 8414, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "increment_t_uint256": { + "entryPoint": 8149, + "id": null, + "parameterSlots": 1, + "returnSlots": 1 + }, + "panic_error_0x11": { + "entryPoint": 8102, + "id": null, + "parameterSlots": 0, + "returnSlots": 0 + }, + "panic_error_0x32": { + "entryPoint": 7719, + "id": null, + "parameterSlots": 0, + "returnSlots": 0 + }, + "panic_error_0x41": { + "entryPoint": 6840, + "id": null, + "parameterSlots": 0, + "returnSlots": 0 + }, + "validator_revert_bytes4": { + "entryPoint": 6226, + "id": null, + "parameterSlots": 1, + "returnSlots": 0 + } + }, + "generatedSources": [ + { + "ast": { + "nodeType": "YulBlock", + "src": "0:20962:22", + "statements": [ + { + "nodeType": "YulBlock", + "src": "6:3:22", + "statements": [] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "58:133:22", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "169:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "178:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "181:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "171:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "171:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "171:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "81:5:22" + }, + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "92:5:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "99:66:22", + "type": "", + "value": "0xffffffff00000000000000000000000000000000000000000000000000000000" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "88:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "88:78:22" + } + ], + "functionName": { + "name": "eq", + "nodeType": "YulIdentifier", + "src": "78:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "78:89:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "71:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "71:97:22" + }, + "nodeType": "YulIf", + "src": "68:117:22" + } + ] + }, + "name": "validator_revert_bytes4", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "47:5:22", + "type": "" + } + ], + "src": "14:177:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "265:176:22", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "311:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "320:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "323:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "313:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "313:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "313:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "286:7:22" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "295:9:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "282:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "282:23:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "307:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "278:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "278:32:22" + }, + "nodeType": "YulIf", + "src": "275:52:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "336:36:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "362:9:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "349:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "349:23:22" + }, + "variables": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "340:5:22", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "405:5:22" + } + ], + "functionName": { + "name": "validator_revert_bytes4", + "nodeType": "YulIdentifier", + "src": "381:23:22" + }, + "nodeType": "YulFunctionCall", + "src": "381:30:22" + }, + "nodeType": "YulExpressionStatement", + "src": "381:30:22" + }, + { + "nodeType": "YulAssignment", + "src": "420:15:22", + "value": { + "name": "value", + "nodeType": "YulIdentifier", + "src": "430:5:22" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "420:6:22" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_bytes4", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "231:9:22", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "242:7:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "254:6:22", + "type": "" + } + ], + "src": "196:245:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "541:92:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "551:26:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "563:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "574:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "559:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "559:18:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "551:4:22" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "593:9:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "618:6:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "611:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "611:14:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "604:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "604:22:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "586:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "586:41:22" + }, + "nodeType": "YulExpressionStatement", + "src": "586:41:22" + } + ] + }, + "name": "abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "510:9:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "521:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "532:4:22", + "type": "" + } + ], + "src": "446:187:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "710:275:22", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "759:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "768:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "771:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "761:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "761:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "761:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "738:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "746:4:22", + "type": "", + "value": "0x1f" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "734:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "734:17:22" + }, + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "753:3:22" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "730:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "730:27:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "723:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "723:35:22" + }, + "nodeType": "YulIf", + "src": "720:55:22" + }, + { + "nodeType": "YulAssignment", + "src": "784:30:22", + "value": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "807:6:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "794:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "794:20:22" + }, + "variableNames": [ + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "784:6:22" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "857:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "866:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "869:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "859:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "859:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "859:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "829:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "837:18:22", + "type": "", + "value": "0xffffffffffffffff" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "826:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "826:30:22" + }, + "nodeType": "YulIf", + "src": "823:50:22" + }, + { + "nodeType": "YulAssignment", + "src": "882:29:22", + "value": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "898:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "906:4:22", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "894:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "894:17:22" + }, + "variableNames": [ + { + "name": "arrayPos", + "nodeType": "YulIdentifier", + "src": "882:8:22" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "963:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "972:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "975:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "965:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "965:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "965:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "934:6:22" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "942:6:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "930:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "930:19:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "951:4:22", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "926:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "926:30:22" + }, + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "958:3:22" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "923:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "923:39:22" + }, + "nodeType": "YulIf", + "src": "920:59:22" + } + ] + }, + "name": "abi_decode_bytes_calldata", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "673:6:22", + "type": "" + }, + { + "name": "end", + "nodeType": "YulTypedName", + "src": "681:3:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "arrayPos", + "nodeType": "YulTypedName", + "src": "689:8:22", + "type": "" + }, + { + "name": "length", + "nodeType": "YulTypedName", + "src": "699:6:22", + "type": "" + } + ], + "src": "638:347:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1096:371:22", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "1142:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1151:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1154:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "1144:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "1144:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "1144:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "1117:7:22" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1126:9:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "1113:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "1113:23:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1138:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "1109:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "1109:32:22" + }, + "nodeType": "YulIf", + "src": "1106:52:22" + }, + { + "nodeType": "YulAssignment", + "src": "1167:33:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1190:9:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "1177:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "1177:23:22" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "1167:6:22" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "1209:46:22", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1240:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1251:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1236:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "1236:18:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "1223:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "1223:32:22" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "1213:6:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1298:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1307:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1310:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "1300:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "1300:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "1300:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "1270:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1278:18:22", + "type": "", + "value": "0xffffffffffffffff" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "1267:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "1267:30:22" + }, + "nodeType": "YulIf", + "src": "1264:50:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "1323:84:22", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1379:9:22" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "1390:6:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1375:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "1375:22:22" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "1399:7:22" + } + ], + "functionName": { + "name": "abi_decode_bytes_calldata", + "nodeType": "YulIdentifier", + "src": "1349:25:22" + }, + "nodeType": "YulFunctionCall", + "src": "1349:58:22" + }, + "variables": [ + { + "name": "value1_1", + "nodeType": "YulTypedName", + "src": "1327:8:22", + "type": "" + }, + { + "name": "value2_1", + "nodeType": "YulTypedName", + "src": "1337:8:22", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "1416:18:22", + "value": { + "name": "value1_1", + "nodeType": "YulIdentifier", + "src": "1426:8:22" + }, + "variableNames": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "1416:6:22" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "1443:18:22", + "value": { + "name": "value2_1", + "nodeType": "YulIdentifier", + "src": "1453:8:22" + }, + "variableNames": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "1443:6:22" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_bytes32t_bytes_calldata_ptr", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "1046:9:22", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "1057:7:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "1069:6:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "1077:6:22", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "1085:6:22", + "type": "" + } + ], + "src": "990:477:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1571:149:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "1581:26:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1593:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1604:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1589:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "1589:18:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "1581:4:22" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1623:9:22" + }, + { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "1638:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1646:66:22", + "type": "", + "value": "0xffffffff00000000000000000000000000000000000000000000000000000000" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "1634:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "1634:79:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "1616:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "1616:98:22" + }, + "nodeType": "YulExpressionStatement", + "src": "1616:98:22" + } + ] + }, + "name": "abi_encode_tuple_t_bytes4__to_t_bytes4__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "1540:9:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "1551:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "1562:4:22", + "type": "" + } + ], + "src": "1472:248:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1850:592:22", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "1896:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1905:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1908:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "1898:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "1898:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "1898:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "1871:7:22" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1880:9:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "1867:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "1867:23:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1892:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "1863:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "1863:32:22" + }, + "nodeType": "YulIf", + "src": "1860:52:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "1921:37:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1948:9:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "1935:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "1935:23:22" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "1925:6:22", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "1967:28:22", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1977:18:22", + "type": "", + "value": "0xffffffffffffffff" + }, + "variables": [ + { + "name": "_1", + "nodeType": "YulTypedName", + "src": "1971:2:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "2022:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2031:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2034:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "2024:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "2024:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "2024:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "2010:6:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "2018:2:22" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "2007:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "2007:14:22" + }, + "nodeType": "YulIf", + "src": "2004:34:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "2047:84:22", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2103:9:22" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "2114:6:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2099:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "2099:22:22" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "2123:7:22" + } + ], + "functionName": { + "name": "abi_decode_bytes_calldata", + "nodeType": "YulIdentifier", + "src": "2073:25:22" + }, + "nodeType": "YulFunctionCall", + "src": "2073:58:22" + }, + "variables": [ + { + "name": "value0_1", + "nodeType": "YulTypedName", + "src": "2051:8:22", + "type": "" + }, + { + "name": "value1_1", + "nodeType": "YulTypedName", + "src": "2061:8:22", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "2140:18:22", + "value": { + "name": "value0_1", + "nodeType": "YulIdentifier", + "src": "2150:8:22" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "2140:6:22" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "2167:18:22", + "value": { + "name": "value1_1", + "nodeType": "YulIdentifier", + "src": "2177:8:22" + }, + "variableNames": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "2167:6:22" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "2194:48:22", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2227:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2238:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2223:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "2223:18:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "2210:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "2210:32:22" + }, + "variables": [ + { + "name": "offset_1", + "nodeType": "YulTypedName", + "src": "2198:8:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "2271:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2280:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2283:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "2273:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "2273:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "2273:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "offset_1", + "nodeType": "YulIdentifier", + "src": "2257:8:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "2267:2:22" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "2254:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "2254:16:22" + }, + "nodeType": "YulIf", + "src": "2251:36:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "2296:86:22", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2352:9:22" + }, + { + "name": "offset_1", + "nodeType": "YulIdentifier", + "src": "2363:8:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2348:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "2348:24:22" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "2374:7:22" + } + ], + "functionName": { + "name": "abi_decode_bytes_calldata", + "nodeType": "YulIdentifier", + "src": "2322:25:22" + }, + "nodeType": "YulFunctionCall", + "src": "2322:60:22" + }, + "variables": [ + { + "name": "value2_1", + "nodeType": "YulTypedName", + "src": "2300:8:22", + "type": "" + }, + { + "name": "value3_1", + "nodeType": "YulTypedName", + "src": "2310:8:22", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "2391:18:22", + "value": { + "name": "value2_1", + "nodeType": "YulIdentifier", + "src": "2401:8:22" + }, + "variableNames": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "2391:6:22" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "2418:18:22", + "value": { + "name": "value3_1", + "nodeType": "YulIdentifier", + "src": "2428:8:22" + }, + "variableNames": [ + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "2418:6:22" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_bytes_calldata_ptrt_bytes_calldata_ptr", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "1792:9:22", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "1803:7:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "1815:6:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "1823:6:22", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "1831:6:22", + "type": "" + }, + { + "name": "value3", + "nodeType": "YulTypedName", + "src": "1839:6:22", + "type": "" + } + ], + "src": "1725:717:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "2517:110:22", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "2563:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2572:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2575:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "2565:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "2565:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "2565:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "2538:7:22" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2547:9:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "2534:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "2534:23:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2559:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "2530:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "2530:32:22" + }, + "nodeType": "YulIf", + "src": "2527:52:22" + }, + { + "nodeType": "YulAssignment", + "src": "2588:33:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2611:9:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "2598:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "2598:23:22" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "2588:6:22" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_bytes32", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "2483:9:22", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "2494:7:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "2506:6:22", + "type": "" + } + ], + "src": "2447:180:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "2733:76:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "2743:26:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2755:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2766:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2751:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "2751:18:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "2743:4:22" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2785:9:22" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "2796:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "2778:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "2778:25:22" + }, + "nodeType": "YulExpressionStatement", + "src": "2778:25:22" + } + ] + }, + "name": "abi_encode_tuple_t_bytes32__to_t_bytes32__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "2702:9:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "2713:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "2724:4:22", + "type": "" + } + ], + "src": "2632:177:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "2918:283:22", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "2967:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2976:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2979:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "2969:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "2969:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "2969:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "2946:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2954:4:22", + "type": "", + "value": "0x1f" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2942:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "2942:17:22" + }, + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "2961:3:22" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "2938:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "2938:27:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "2931:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "2931:35:22" + }, + "nodeType": "YulIf", + "src": "2928:55:22" + }, + { + "nodeType": "YulAssignment", + "src": "2992:30:22", + "value": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "3015:6:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "3002:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "3002:20:22" + }, + "variableNames": [ + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "2992:6:22" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "3065:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3074:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3077:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "3067:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "3067:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "3067:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "3037:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3045:18:22", + "type": "", + "value": "0xffffffffffffffff" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "3034:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "3034:30:22" + }, + "nodeType": "YulIf", + "src": "3031:50:22" + }, + { + "nodeType": "YulAssignment", + "src": "3090:29:22", + "value": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "3106:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3114:4:22", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "3102:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "3102:17:22" + }, + "variableNames": [ + { + "name": "arrayPos", + "nodeType": "YulIdentifier", + "src": "3090:8:22" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "3179:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3188:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3191:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "3181:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "3181:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "3181:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "3142:6:22" + }, + { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3154:1:22", + "type": "", + "value": "5" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "3157:6:22" + } + ], + "functionName": { + "name": "shl", + "nodeType": "YulIdentifier", + "src": "3150:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "3150:14:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "3138:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "3138:27:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3167:4:22", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "3134:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "3134:38:22" + }, + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "3174:3:22" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "3131:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "3131:47:22" + }, + "nodeType": "YulIf", + "src": "3128:67:22" + } + ] + }, + "name": "abi_decode_array_struct_Transaction_calldata_dyn_calldata", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "2881:6:22", + "type": "" + }, + { + "name": "end", + "nodeType": "YulTypedName", + "src": "2889:3:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "arrayPos", + "nodeType": "YulTypedName", + "src": "2897:8:22", + "type": "" + }, + { + "name": "length", + "nodeType": "YulTypedName", + "src": "2907:6:22", + "type": "" + } + ], + "src": "2814:387:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "3342:352:22", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "3388:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3397:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3400:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "3390:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "3390:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "3390:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "3363:7:22" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "3372:9:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "3359:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "3359:23:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3384:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "3355:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "3355:32:22" + }, + "nodeType": "YulIf", + "src": "3352:52:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "3413:37:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "3440:9:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "3427:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "3427:23:22" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "3417:6:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "3493:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3502:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3505:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "3495:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "3495:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "3495:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "3465:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3473:18:22", + "type": "", + "value": "0xffffffffffffffff" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "3462:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "3462:30:22" + }, + "nodeType": "YulIf", + "src": "3459:50:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "3518:116:22", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "3606:9:22" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "3617:6:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "3602:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "3602:22:22" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "3626:7:22" + } + ], + "functionName": { + "name": "abi_decode_array_struct_Transaction_calldata_dyn_calldata", + "nodeType": "YulIdentifier", + "src": "3544:57:22" + }, + "nodeType": "YulFunctionCall", + "src": "3544:90:22" + }, + "variables": [ + { + "name": "value0_1", + "nodeType": "YulTypedName", + "src": "3522:8:22", + "type": "" + }, + { + "name": "value1_1", + "nodeType": "YulTypedName", + "src": "3532:8:22", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "3643:18:22", + "value": { + "name": "value0_1", + "nodeType": "YulIdentifier", + "src": "3653:8:22" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "3643:6:22" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "3670:18:22", + "value": { + "name": "value1_1", + "nodeType": "YulIdentifier", + "src": "3680:8:22" + }, + "variableNames": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "3670:6:22" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "3300:9:22", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "3311:7:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "3323:6:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "3331:6:22", + "type": "" + } + ], + "src": "3206:488:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "3888:675:22", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "3934:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3943:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3946:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "3936:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "3936:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "3936:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "3909:7:22" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "3918:9:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "3905:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "3905:23:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3930:2:22", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "3901:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "3901:32:22" + }, + "nodeType": "YulIf", + "src": "3898:52:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "3959:37:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "3986:9:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "3973:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "3973:23:22" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "3963:6:22", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "4005:28:22", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4015:18:22", + "type": "", + "value": "0xffffffffffffffff" + }, + "variables": [ + { + "name": "_1", + "nodeType": "YulTypedName", + "src": "4009:2:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "4060:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4069:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4072:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "4062:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "4062:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "4062:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "4048:6:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "4056:2:22" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "4045:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "4045:14:22" + }, + "nodeType": "YulIf", + "src": "4042:34:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "4085:116:22", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4173:9:22" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "4184:6:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4169:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "4169:22:22" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "4193:7:22" + } + ], + "functionName": { + "name": "abi_decode_array_struct_Transaction_calldata_dyn_calldata", + "nodeType": "YulIdentifier", + "src": "4111:57:22" + }, + "nodeType": "YulFunctionCall", + "src": "4111:90:22" + }, + "variables": [ + { + "name": "value0_1", + "nodeType": "YulTypedName", + "src": "4089:8:22", + "type": "" + }, + { + "name": "value1_1", + "nodeType": "YulTypedName", + "src": "4099:8:22", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "4210:18:22", + "value": { + "name": "value0_1", + "nodeType": "YulIdentifier", + "src": "4220:8:22" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "4210:6:22" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "4237:18:22", + "value": { + "name": "value1_1", + "nodeType": "YulIdentifier", + "src": "4247:8:22" + }, + "variableNames": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "4237:6:22" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "4264:42:22", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4291:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4302:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4287:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "4287:18:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "4274:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "4274:32:22" + }, + "variableNames": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "4264:6:22" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "4315:48:22", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4348:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4359:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4344:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "4344:18:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "4331:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "4331:32:22" + }, + "variables": [ + { + "name": "offset_1", + "nodeType": "YulTypedName", + "src": "4319:8:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "4392:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4401:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4404:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "4394:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "4394:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "4394:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "offset_1", + "nodeType": "YulIdentifier", + "src": "4378:8:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "4388:2:22" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "4375:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "4375:16:22" + }, + "nodeType": "YulIf", + "src": "4372:36:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "4417:86:22", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4473:9:22" + }, + { + "name": "offset_1", + "nodeType": "YulIdentifier", + "src": "4484:8:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4469:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "4469:24:22" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "4495:7:22" + } + ], + "functionName": { + "name": "abi_decode_bytes_calldata", + "nodeType": "YulIdentifier", + "src": "4443:25:22" + }, + "nodeType": "YulFunctionCall", + "src": "4443:60:22" + }, + "variables": [ + { + "name": "value3_1", + "nodeType": "YulTypedName", + "src": "4421:8:22", + "type": "" + }, + { + "name": "value4_1", + "nodeType": "YulTypedName", + "src": "4431:8:22", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "4512:18:22", + "value": { + "name": "value3_1", + "nodeType": "YulIdentifier", + "src": "4522:8:22" + }, + "variableNames": [ + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "4512:6:22" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "4539:18:22", + "value": { + "name": "value4_1", + "nodeType": "YulIdentifier", + "src": "4549:8:22" + }, + "variableNames": [ + { + "name": "value4", + "nodeType": "YulIdentifier", + "src": "4539:6:22" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptrt_uint256t_bytes_calldata_ptr", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "3822:9:22", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "3833:7:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "3845:6:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "3853:6:22", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "3861:6:22", + "type": "" + }, + { + "name": "value3", + "nodeType": "YulTypedName", + "src": "3869:6:22", + "type": "" + }, + { + "name": "value4", + "nodeType": "YulTypedName", + "src": "3877:6:22", + "type": "" + } + ], + "src": "3699:864:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "4781:250:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "4791:27:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4803:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4814:3:22", + "type": "", + "value": "160" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4799:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "4799:19:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "4791:4:22" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4834:9:22" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "4845:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "4827:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "4827:25:22" + }, + "nodeType": "YulExpressionStatement", + "src": "4827:25:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4872:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4883:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4868:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "4868:18:22" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "4888:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "4861:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "4861:34:22" + }, + "nodeType": "YulExpressionStatement", + "src": "4861:34:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4915:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4926:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4911:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "4911:18:22" + }, + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "4931:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "4904:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "4904:34:22" + }, + "nodeType": "YulExpressionStatement", + "src": "4904:34:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4958:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4969:2:22", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4954:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "4954:18:22" + }, + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "4974:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "4947:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "4947:34:22" + }, + "nodeType": "YulExpressionStatement", + "src": "4947:34:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5001:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5012:3:22", + "type": "", + "value": "128" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4997:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "4997:19:22" + }, + { + "name": "value4", + "nodeType": "YulIdentifier", + "src": "5018:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "4990:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "4990:35:22" + }, + "nodeType": "YulExpressionStatement", + "src": "4990:35:22" + } + ] + }, + "name": "abi_encode_tuple_t_uint256_t_uint256_t_bytes32_t_bytes32_t_uint256__to_t_uint256_t_uint256_t_bytes32_t_bytes32_t_uint256__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "4718:9:22", + "type": "" + }, + { + "name": "value4", + "nodeType": "YulTypedName", + "src": "4729:6:22", + "type": "" + }, + { + "name": "value3", + "nodeType": "YulTypedName", + "src": "4737:6:22", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "4745:6:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "4753:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "4761:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "4772:4:22", + "type": "" + } + ], + "src": "4568:463:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "5106:110:22", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "5152:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5161:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5164:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "5154:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "5154:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "5154:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "5127:7:22" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5136:9:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "5123:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "5123:23:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5148:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "5119:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "5119:32:22" + }, + "nodeType": "YulIf", + "src": "5116:52:22" + }, + { + "nodeType": "YulAssignment", + "src": "5177:33:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5200:9:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "5187:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "5187:23:22" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "5177:6:22" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_uint256", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "5072:9:22", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "5083:7:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "5095:6:22", + "type": "" + } + ], + "src": "5036:180:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "5322:76:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "5332:26:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5344:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5355:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "5340:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "5340:18:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "5332:4:22" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5374:9:22" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "5385:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "5367:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "5367:25:22" + }, + "nodeType": "YulExpressionStatement", + "src": "5367:25:22" + } + ] + }, + "name": "abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "5291:9:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "5302:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "5313:4:22", + "type": "" + } + ], + "src": "5221:177:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "5435:152:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5452:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5455:77:22", + "type": "", + "value": "35408467139433450592217433187231851964531694900788300625387963629091585785856" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "5445:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "5445:88:22" + }, + "nodeType": "YulExpressionStatement", + "src": "5445:88:22" + }, + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5549:1:22", + "type": "", + "value": "4" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5552:4:22", + "type": "", + "value": "0x41" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "5542:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "5542:15:22" + }, + "nodeType": "YulExpressionStatement", + "src": "5542:15:22" + }, + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5573:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5576:4:22", + "type": "", + "value": "0x24" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "5566:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "5566:15:22" + }, + "nodeType": "YulExpressionStatement", + "src": "5566:15:22" + } + ] + }, + "name": "panic_error_0x41", + "nodeType": "YulFunctionDefinition", + "src": "5403:184:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "5671:901:22", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "5717:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5726:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5729:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "5719:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "5719:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "5719:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "5692:7:22" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5701:9:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "5688:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "5688:23:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5713:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "5684:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "5684:32:22" + }, + "nodeType": "YulIf", + "src": "5681:52:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "5742:37:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5769:9:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "5756:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "5756:23:22" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "5746:6:22", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "5788:28:22", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5798:18:22", + "type": "", + "value": "0xffffffffffffffff" + }, + "variables": [ + { + "name": "_1", + "nodeType": "YulTypedName", + "src": "5792:2:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "5843:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5852:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5855:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "5845:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "5845:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "5845:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "5831:6:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "5839:2:22" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "5828:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "5828:14:22" + }, + "nodeType": "YulIf", + "src": "5825:34:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "5868:32:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5882:9:22" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "5893:6:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "5878:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "5878:22:22" + }, + "variables": [ + { + "name": "_2", + "nodeType": "YulTypedName", + "src": "5872:2:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "5948:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5957:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5960:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "5950:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "5950:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "5950:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "5927:2:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5931:4:22", + "type": "", + "value": "0x1f" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "5923:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "5923:13:22" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "5938:7:22" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "5919:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "5919:27:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "5912:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "5912:35:22" + }, + "nodeType": "YulIf", + "src": "5909:55:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "5973:26:22", + "value": { + "arguments": [ + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "5996:2:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "5983:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "5983:16:22" + }, + "variables": [ + { + "name": "_3", + "nodeType": "YulTypedName", + "src": "5977:2:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "6022:22:22", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "panic_error_0x41", + "nodeType": "YulIdentifier", + "src": "6024:16:22" + }, + "nodeType": "YulFunctionCall", + "src": "6024:18:22" + }, + "nodeType": "YulExpressionStatement", + "src": "6024:18:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "_3", + "nodeType": "YulIdentifier", + "src": "6014:2:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "6018:2:22" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "6011:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "6011:10:22" + }, + "nodeType": "YulIf", + "src": "6008:36:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "6053:76:22", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6063:66:22", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0" + }, + "variables": [ + { + "name": "_4", + "nodeType": "YulTypedName", + "src": "6057:2:22", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "6138:23:22", + "value": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6158:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "6152:5:22" + }, + "nodeType": "YulFunctionCall", + "src": "6152:9:22" + }, + "variables": [ + { + "name": "memPtr", + "nodeType": "YulTypedName", + "src": "6142:6:22", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "6170:71:22", + "value": { + "arguments": [ + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "6192:6:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "_3", + "nodeType": "YulIdentifier", + "src": "6216:2:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6220:4:22", + "type": "", + "value": "0x1f" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6212:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "6212:13:22" + }, + { + "name": "_4", + "nodeType": "YulIdentifier", + "src": "6227:2:22" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "6208:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "6208:22:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6232:2:22", + "type": "", + "value": "63" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6204:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "6204:31:22" + }, + { + "name": "_4", + "nodeType": "YulIdentifier", + "src": "6237:2:22" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "6200:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "6200:40:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6188:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "6188:53:22" + }, + "variables": [ + { + "name": "newFreePtr", + "nodeType": "YulTypedName", + "src": "6174:10:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "6300:22:22", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "panic_error_0x41", + "nodeType": "YulIdentifier", + "src": "6302:16:22" + }, + "nodeType": "YulFunctionCall", + "src": "6302:18:22" + }, + "nodeType": "YulExpressionStatement", + "src": "6302:18:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "newFreePtr", + "nodeType": "YulIdentifier", + "src": "6259:10:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "6271:2:22" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "6256:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "6256:18:22" + }, + { + "arguments": [ + { + "name": "newFreePtr", + "nodeType": "YulIdentifier", + "src": "6279:10:22" + }, + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "6291:6:22" + } + ], + "functionName": { + "name": "lt", + "nodeType": "YulIdentifier", + "src": "6276:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "6276:22:22" + } + ], + "functionName": { + "name": "or", + "nodeType": "YulIdentifier", + "src": "6253:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "6253:46:22" + }, + "nodeType": "YulIf", + "src": "6250:72:22" + }, + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6338:2:22", + "type": "", + "value": "64" + }, + { + "name": "newFreePtr", + "nodeType": "YulIdentifier", + "src": "6342:10:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "6331:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "6331:22:22" + }, + "nodeType": "YulExpressionStatement", + "src": "6331:22:22" + }, + { + "expression": { + "arguments": [ + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "6369:6:22" + }, + { + "name": "_3", + "nodeType": "YulIdentifier", + "src": "6377:2:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "6362:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "6362:18:22" + }, + "nodeType": "YulExpressionStatement", + "src": "6362:18:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "6426:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6435:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6438:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "6428:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "6428:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "6428:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "6403:2:22" + }, + { + "name": "_3", + "nodeType": "YulIdentifier", + "src": "6407:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6399:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "6399:11:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6412:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6395:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "6395:20:22" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "6417:7:22" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "6392:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "6392:33:22" + }, + "nodeType": "YulIf", + "src": "6389:53:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "6468:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6476:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6464:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "6464:15:22" + }, + { + "arguments": [ + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "6485:2:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6489:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6481:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "6481:11:22" + }, + { + "name": "_3", + "nodeType": "YulIdentifier", + "src": "6494:2:22" + } + ], + "functionName": { + "name": "calldatacopy", + "nodeType": "YulIdentifier", + "src": "6451:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "6451:46:22" + }, + "nodeType": "YulExpressionStatement", + "src": "6451:46:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "6521:6:22" + }, + { + "name": "_3", + "nodeType": "YulIdentifier", + "src": "6529:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6517:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "6517:15:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6534:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6513:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "6513:24:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6539:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "6506:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "6506:35:22" + }, + "nodeType": "YulExpressionStatement", + "src": "6506:35:22" + }, + { + "nodeType": "YulAssignment", + "src": "6550:16:22", + "value": { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "6560:6:22" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "6550:6:22" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_bytes_memory_ptr", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "5637:9:22", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "5648:7:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "5660:6:22", + "type": "" + } + ], + "src": "5592:980:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "6678:125:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "6688:26:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "6700:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6711:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6696:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "6696:18:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "6688:4:22" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "6730:9:22" + }, + { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "6745:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6753:42:22", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffff" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "6741:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "6741:55:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "6723:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "6723:74:22" + }, + "nodeType": "YulExpressionStatement", + "src": "6723:74:22" + } + ] + }, + "name": "abi_encode_tuple_t_address__to_t_address__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "6647:9:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "6658:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "6669:4:22", + "type": "" + } + ], + "src": "6577:226:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "6955:124:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "6978:3:22" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "6983:6:22" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "6991:6:22" + } + ], + "functionName": { + "name": "calldatacopy", + "nodeType": "YulIdentifier", + "src": "6965:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "6965:33:22" + }, + "nodeType": "YulExpressionStatement", + "src": "6965:33:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "7007:26:22", + "value": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "7021:3:22" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "7026:6:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7017:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "7017:16:22" + }, + "variables": [ + { + "name": "_1", + "nodeType": "YulTypedName", + "src": "7011:2:22", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "7049:2:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7053:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "7042:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "7042:13:22" + }, + "nodeType": "YulExpressionStatement", + "src": "7042:13:22" + }, + { + "nodeType": "YulAssignment", + "src": "7064:9:22", + "value": { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "7071:2:22" + }, + "variableNames": [ + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "7064:3:22" + } + ] + } + ] + }, + "name": "abi_encode_tuple_packed_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__nonPadded_inplace_fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "pos", + "nodeType": "YulTypedName", + "src": "6923:3:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "6928:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "6936:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "end", + "nodeType": "YulTypedName", + "src": "6947:3:22", + "type": "" + } + ], + "src": "6808:271:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "7213:198:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "7223:26:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "7235:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7246:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7231:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "7231:18:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "7223:4:22" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "7258:52:22", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7268:42:22", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffff" + }, + "variables": [ + { + "name": "_1", + "nodeType": "YulTypedName", + "src": "7262:2:22", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "7326:9:22" + }, + { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "7341:6:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "7349:2:22" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "7337:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "7337:15:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "7319:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "7319:34:22" + }, + "nodeType": "YulExpressionStatement", + "src": "7319:34:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "7373:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7384:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7369:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "7369:18:22" + }, + { + "arguments": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "7393:6:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "7401:2:22" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "7389:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "7389:15:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "7362:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "7362:43:22" + }, + "nodeType": "YulExpressionStatement", + "src": "7362:43:22" + } + ] + }, + "name": "abi_encode_tuple_t_address_t_address__to_t_address_t_address__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "7174:9:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "7185:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "7193:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "7204:4:22", + "type": "" + } + ], + "src": "7084:327:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "7462:114:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "7472:29:22", + "value": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "7494:6:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "7481:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "7481:20:22" + }, + "variableNames": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "7472:5:22" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "7554:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7563:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7566:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "7556:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "7556:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "7556:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "7523:5:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "7544:5:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "7537:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "7537:13:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "7530:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "7530:21:22" + } + ], + "functionName": { + "name": "eq", + "nodeType": "YulIdentifier", + "src": "7520:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "7520:32:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "7513:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "7513:40:22" + }, + "nodeType": "YulIf", + "src": "7510:60:22" + } + ] + }, + "name": "abi_decode_bool", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "7441:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "7452:5:22", + "type": "" + } + ], + "src": "7416:160:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "7630:147:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "7640:29:22", + "value": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "7662:6:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "7649:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "7649:20:22" + }, + "variableNames": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "7640:5:22" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "7755:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7764:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7767:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "7757:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "7757:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "7757:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "7691:5:22" + }, + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "7702:5:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7709:42:22", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffff" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "7698:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "7698:54:22" + } + ], + "functionName": { + "name": "eq", + "nodeType": "YulIdentifier", + "src": "7688:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "7688:65:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "7681:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "7681:73:22" + }, + "nodeType": "YulIf", + "src": "7678:93:22" + } + ] + }, + "name": "abi_decode_address", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "7609:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "7620:5:22", + "type": "" + } + ], + "src": "7581:196:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "7848:259:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "7865:3:22" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "7870:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "7858:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "7858:19:22" + }, + "nodeType": "YulExpressionStatement", + "src": "7858:19:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "7903:3:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7908:4:22", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7899:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "7899:14:22" + }, + { + "name": "start", + "nodeType": "YulIdentifier", + "src": "7915:5:22" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "7922:6:22" + } + ], + "functionName": { + "name": "calldatacopy", + "nodeType": "YulIdentifier", + "src": "7886:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "7886:43:22" + }, + "nodeType": "YulExpressionStatement", + "src": "7886:43:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "7953:3:22" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "7958:6:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7949:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "7949:16:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7967:4:22", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7945:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "7945:27:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7974:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "7938:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "7938:38:22" + }, + "nodeType": "YulExpressionStatement", + "src": "7938:38:22" + }, + { + "nodeType": "YulAssignment", + "src": "7985:116:22", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "8000:3:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "8013:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8021:2:22", + "type": "", + "value": "31" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "8009:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "8009:15:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8026:66:22", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "8005:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "8005:88:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7996:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "7996:98:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8096:4:22", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7992:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "7992:109:22" + }, + "variableNames": [ + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "7985:3:22" + } + ] + } + ] + }, + "name": "abi_encode_bytes_calldata", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "start", + "nodeType": "YulTypedName", + "src": "7817:5:22", + "type": "" + }, + { + "name": "length", + "nodeType": "YulTypedName", + "src": "7824:6:22", + "type": "" + }, + { + "name": "pos", + "nodeType": "YulTypedName", + "src": "7832:3:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "end", + "nodeType": "YulTypedName", + "src": "7840:3:22", + "type": "" + } + ], + "src": "7782:325:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "8210:1930:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "8227:3:22" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "8232:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "8220:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "8220:19:22" + }, + "nodeType": "YulExpressionStatement", + "src": "8220:19:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "8248:14:22", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8258:4:22", + "type": "", + "value": "0x20" + }, + "variables": [ + { + "name": "_1", + "nodeType": "YulTypedName", + "src": "8252:2:22", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "8271:31:22", + "value": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "8294:3:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "8299:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "8290:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "8290:12:22" + }, + "variables": [ + { + "name": "updated_pos", + "nodeType": "YulTypedName", + "src": "8275:11:22", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "8311:24:22", + "value": { + "name": "updated_pos", + "nodeType": "YulIdentifier", + "src": "8324:11:22" + }, + "variables": [ + { + "name": "pos_1", + "nodeType": "YulTypedName", + "src": "8315:5:22", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "8344:18:22", + "value": { + "name": "updated_pos", + "nodeType": "YulIdentifier", + "src": "8351:11:22" + }, + "variableNames": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "8344:3:22" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "8371:38:22", + "value": { + "arguments": [ + { + "name": "pos_1", + "nodeType": "YulIdentifier", + "src": "8387:5:22" + }, + { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8398:1:22", + "type": "", + "value": "5" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "8401:6:22" + } + ], + "functionName": { + "name": "shl", + "nodeType": "YulIdentifier", + "src": "8394:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "8394:14:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "8383:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "8383:26:22" + }, + "variables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "8375:4:22", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "8418:19:22", + "value": { + "name": "value", + "nodeType": "YulIdentifier", + "src": "8432:5:22" + }, + "variables": [ + { + "name": "srcPtr", + "nodeType": "YulTypedName", + "src": "8422:6:22", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "8446:10:22", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8455:1:22", + "type": "", + "value": "0" + }, + "variables": [ + { + "name": "i", + "nodeType": "YulTypedName", + "src": "8450:1:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "8514:1600:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "8535:3:22" + }, + { + "arguments": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "8544:4:22" + }, + { + "name": "pos_1", + "nodeType": "YulIdentifier", + "src": "8550:5:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "8540:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "8540:16:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "8528:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "8528:29:22" + }, + "nodeType": "YulExpressionStatement", + "src": "8528:29:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "8570:46:22", + "value": { + "arguments": [ + { + "name": "srcPtr", + "nodeType": "YulIdentifier", + "src": "8609:6:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "8596:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "8596:20:22" + }, + "variables": [ + { + "name": "rel_offset_of_tail", + "nodeType": "YulTypedName", + "src": "8574:18:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "8765:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8774:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8777:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "8767:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "8767:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "8767:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "rel_offset_of_tail", + "nodeType": "YulIdentifier", + "src": "8643:18:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "arguments": [], + "functionName": { + "name": "calldatasize", + "nodeType": "YulIdentifier", + "src": "8671:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "8671:14:22" + }, + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "8687:5:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "8667:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "8667:26:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8695:66:22", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff41" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "8663:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "8663:99:22" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "8639:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "8639:124:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "8632:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "8632:132:22" + }, + "nodeType": "YulIf", + "src": "8629:152:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "8794:45:22", + "value": { + "arguments": [ + { + "name": "rel_offset_of_tail", + "nodeType": "YulIdentifier", + "src": "8813:18:22" + }, + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "8833:5:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "8809:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "8809:30:22" + }, + "variables": [ + { + "name": "value_1", + "nodeType": "YulTypedName", + "src": "8798:7:22", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "8852:14:22", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8862:4:22", + "type": "", + "value": "0xc0" + }, + "variables": [ + { + "name": "_2", + "nodeType": "YulTypedName", + "src": "8856:2:22", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "8886:4:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "value_1", + "nodeType": "YulIdentifier", + "src": "8922:7:22" + } + ], + "functionName": { + "name": "abi_decode_bool", + "nodeType": "YulIdentifier", + "src": "8906:15:22" + }, + "nodeType": "YulFunctionCall", + "src": "8906:24:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "8899:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "8899:32:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "8892:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "8892:40:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "8879:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "8879:54:22" + }, + "nodeType": "YulExpressionStatement", + "src": "8879:54:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "8957:4:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "8963:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "8953:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "8953:13:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "value_1", + "nodeType": "YulIdentifier", + "src": "9002:7:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "9011:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "8998:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "8998:16:22" + } + ], + "functionName": { + "name": "abi_decode_bool", + "nodeType": "YulIdentifier", + "src": "8982:15:22" + }, + "nodeType": "YulFunctionCall", + "src": "8982:33:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "8975:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "8975:41:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "8968:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "8968:49:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "8946:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "8946:72:22" + }, + "nodeType": "YulExpressionStatement", + "src": "8946:72:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "9031:14:22", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9041:4:22", + "type": "", + "value": "0x40" + }, + "variables": [ + { + "name": "_3", + "nodeType": "YulTypedName", + "src": "9035:2:22", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "9069:4:22" + }, + { + "name": "_3", + "nodeType": "YulIdentifier", + "src": "9075:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9065:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "9065:13:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "name": "value_1", + "nodeType": "YulIdentifier", + "src": "9097:7:22" + }, + { + "name": "_3", + "nodeType": "YulIdentifier", + "src": "9106:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9093:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "9093:16:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "9080:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "9080:30:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "9058:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "9058:53:22" + }, + "nodeType": "YulExpressionStatement", + "src": "9058:53:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "9124:14:22", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9134:4:22", + "type": "", + "value": "0x60" + }, + "variables": [ + { + "name": "_4", + "nodeType": "YulTypedName", + "src": "9128:2:22", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "9162:4:22" + }, + { + "name": "_4", + "nodeType": "YulIdentifier", + "src": "9168:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9158:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "9158:13:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "value_1", + "nodeType": "YulIdentifier", + "src": "9200:7:22" + }, + { + "name": "_4", + "nodeType": "YulIdentifier", + "src": "9209:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9196:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "9196:16:22" + } + ], + "functionName": { + "name": "abi_decode_address", + "nodeType": "YulIdentifier", + "src": "9177:18:22" + }, + "nodeType": "YulFunctionCall", + "src": "9177:36:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9215:42:22", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffff" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "9173:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "9173:85:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "9151:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "9151:108:22" + }, + "nodeType": "YulExpressionStatement", + "src": "9151:108:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "9272:14:22", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9282:4:22", + "type": "", + "value": "0x80" + }, + "variables": [ + { + "name": "_5", + "nodeType": "YulTypedName", + "src": "9276:2:22", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "9310:4:22" + }, + { + "name": "_5", + "nodeType": "YulIdentifier", + "src": "9316:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9306:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "9306:13:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "name": "value_1", + "nodeType": "YulIdentifier", + "src": "9338:7:22" + }, + { + "name": "_5", + "nodeType": "YulIdentifier", + "src": "9347:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9334:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "9334:16:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "9321:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "9321:30:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "9299:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "9299:53:22" + }, + "nodeType": "YulExpressionStatement", + "src": "9299:53:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "9365:14:22", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9375:4:22", + "type": "", + "value": "0xa0" + }, + "variables": [ + { + "name": "_6", + "nodeType": "YulTypedName", + "src": "9369:2:22", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "9392:58:22", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "value_1", + "nodeType": "YulIdentifier", + "src": "9437:7:22" + }, + { + "name": "_6", + "nodeType": "YulIdentifier", + "src": "9446:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9433:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "9433:16:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "9420:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "9420:30:22" + }, + "variables": [ + { + "name": "rel_offset_of_tail_1", + "nodeType": "YulTypedName", + "src": "9396:20:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "9603:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9612:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9615:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "9605:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "9605:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "9605:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "rel_offset_of_tail_1", + "nodeType": "YulIdentifier", + "src": "9477:20:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "arguments": [], + "functionName": { + "name": "calldatasize", + "nodeType": "YulIdentifier", + "src": "9507:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "9507:14:22" + }, + { + "name": "value_1", + "nodeType": "YulIdentifier", + "src": "9523:7:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "9503:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "9503:28:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9533:66:22", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9499:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "9499:101:22" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "9473:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "9473:128:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "9466:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "9466:136:22" + }, + "nodeType": "YulIf", + "src": "9463:156:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "9632:49:22", + "value": { + "arguments": [ + { + "name": "rel_offset_of_tail_1", + "nodeType": "YulIdentifier", + "src": "9651:20:22" + }, + { + "name": "value_1", + "nodeType": "YulIdentifier", + "src": "9673:7:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9647:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "9647:34:22" + }, + "variables": [ + { + "name": "value_2", + "nodeType": "YulTypedName", + "src": "9636:7:22", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "9694:37:22", + "value": { + "arguments": [ + { + "name": "value_2", + "nodeType": "YulIdentifier", + "src": "9723:7:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "9710:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "9710:21:22" + }, + "variables": [ + { + "name": "length_1", + "nodeType": "YulTypedName", + "src": "9698:8:22", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "9744:31:22", + "value": { + "arguments": [ + { + "name": "value_2", + "nodeType": "YulIdentifier", + "src": "9763:7:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "9772:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9759:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "9759:16:22" + }, + "variables": [ + { + "name": "value_3", + "nodeType": "YulTypedName", + "src": "9748:7:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "9824:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9833:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9836:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "9826:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "9826:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "9826:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "length_1", + "nodeType": "YulIdentifier", + "src": "9794:8:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9804:18:22", + "type": "", + "value": "0xffffffffffffffff" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "9791:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "9791:32:22" + }, + "nodeType": "YulIf", + "src": "9788:52:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "9900:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9909:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9912:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "9902:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "9902:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "9902:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "value_3", + "nodeType": "YulIdentifier", + "src": "9860:7:22" + }, + { + "arguments": [ + { + "arguments": [], + "functionName": { + "name": "calldatasize", + "nodeType": "YulIdentifier", + "src": "9873:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "9873:14:22" + }, + { + "name": "length_1", + "nodeType": "YulIdentifier", + "src": "9889:8:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "9869:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "9869:29:22" + } + ], + "functionName": { + "name": "sgt", + "nodeType": "YulIdentifier", + "src": "9856:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "9856:43:22" + }, + "nodeType": "YulIf", + "src": "9853:63:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "9940:4:22" + }, + { + "name": "_6", + "nodeType": "YulIdentifier", + "src": "9946:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9936:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "9936:13:22" + }, + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "9951:2:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "9929:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "9929:25:22" + }, + "nodeType": "YulExpressionStatement", + "src": "9929:25:22" + }, + { + "nodeType": "YulAssignment", + "src": "9967:67:22", + "value": { + "arguments": [ + { + "name": "value_3", + "nodeType": "YulIdentifier", + "src": "10001:7:22" + }, + { + "name": "length_1", + "nodeType": "YulIdentifier", + "src": "10010:8:22" + }, + { + "arguments": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "10024:4:22" + }, + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "10030:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "10020:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "10020:13:22" + } + ], + "functionName": { + "name": "abi_encode_bytes_calldata", + "nodeType": "YulIdentifier", + "src": "9975:25:22" + }, + "nodeType": "YulFunctionCall", + "src": "9975:59:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "9967:4:22" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "10047:25:22", + "value": { + "arguments": [ + { + "name": "srcPtr", + "nodeType": "YulIdentifier", + "src": "10061:6:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "10069:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "10057:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "10057:15:22" + }, + "variableNames": [ + { + "name": "srcPtr", + "nodeType": "YulIdentifier", + "src": "10047:6:22" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "10085:19:22", + "value": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "10096:3:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "10101:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "10092:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "10092:12:22" + }, + "variableNames": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "10085:3:22" + } + ] + } + ] + }, + "condition": { + "arguments": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "8476:1:22" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "8479:6:22" + } + ], + "functionName": { + "name": "lt", + "nodeType": "YulIdentifier", + "src": "8473:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "8473:13:22" + }, + "nodeType": "YulForLoop", + "post": { + "nodeType": "YulBlock", + "src": "8487:18:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "8489:14:22", + "value": { + "arguments": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "8498:1:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8501:1:22", + "type": "", + "value": "1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "8494:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "8494:9:22" + }, + "variableNames": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "8489:1:22" + } + ] + } + ] + }, + "pre": { + "nodeType": "YulBlock", + "src": "8469:3:22", + "statements": [] + }, + "src": "8465:1649:22" + }, + { + "nodeType": "YulAssignment", + "src": "10123:11:22", + "value": { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "10130:4:22" + }, + "variableNames": [ + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "10123:3:22" + } + ] + } + ] + }, + "name": "abi_encode_array_struct_Transaction_calldata_dyn_calldata", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "8179:5:22", + "type": "" + }, + { + "name": "length", + "nodeType": "YulTypedName", + "src": "8186:6:22", + "type": "" + }, + { + "name": "pos", + "nodeType": "YulTypedName", + "src": "8194:3:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "end", + "nodeType": "YulTypedName", + "src": "8202:3:22", + "type": "" + } + ], + "src": "8112:2028:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "10467:272:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "10484:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10495:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "10477:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "10477:21:22" + }, + "nodeType": "YulExpressionStatement", + "src": "10477:21:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "10518:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10529:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "10514:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "10514:18:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10534:1:22", + "type": "", + "value": "5" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "10507:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "10507:29:22" + }, + "nodeType": "YulExpressionStatement", + "src": "10507:29:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "10556:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10567:2:22", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "10552:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "10552:18:22" + }, + { + "hexValue": "73656c663a", + "kind": "string", + "nodeType": "YulLiteral", + "src": "10572:7:22", + "type": "", + "value": "self:" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "10545:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "10545:35:22" + }, + "nodeType": "YulExpressionStatement", + "src": "10545:35:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "10600:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10611:4:22", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "10596:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "10596:20:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10618:3:22", + "type": "", + "value": "128" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "10589:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "10589:33:22" + }, + "nodeType": "YulExpressionStatement", + "src": "10589:33:22" + }, + { + "nodeType": "YulAssignment", + "src": "10631:102:22", + "value": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "10697:6:22" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "10705:6:22" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "10717:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10728:3:22", + "type": "", + "value": "128" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "10713:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "10713:19:22" + } + ], + "functionName": { + "name": "abi_encode_array_struct_Transaction_calldata_dyn_calldata", + "nodeType": "YulIdentifier", + "src": "10639:57:22" + }, + "nodeType": "YulFunctionCall", + "src": "10639:94:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "10631:4:22" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_stringliteral_bf9461da9f9c0123d3a54c61147a274d8fdb5d5c1e488665fb11b9edbbc32845_t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr__to_t_string_memory_ptr_t_array$_t_struct$_Transaction_$1292_memory_ptr_$dyn_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "10428:9:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "10439:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "10447:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "10458:4:22", + "type": "" + } + ], + "src": "10145:594:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "11066:273:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "11083:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11094:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "11076:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "11076:21:22" + }, + "nodeType": "YulExpressionStatement", + "src": "11076:21:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "11117:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11128:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "11113:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "11113:18:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11133:1:22", + "type": "", + "value": "6" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "11106:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "11106:29:22" + }, + "nodeType": "YulExpressionStatement", + "src": "11106:29:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "11155:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11166:2:22", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "11151:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "11151:18:22" + }, + { + "hexValue": "67756573743a", + "kind": "string", + "nodeType": "YulLiteral", + "src": "11171:8:22", + "type": "", + "value": "guest:" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "11144:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "11144:36:22" + }, + "nodeType": "YulExpressionStatement", + "src": "11144:36:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "11200:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11211:4:22", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "11196:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "11196:20:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11218:3:22", + "type": "", + "value": "128" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "11189:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "11189:33:22" + }, + "nodeType": "YulExpressionStatement", + "src": "11189:33:22" + }, + { + "nodeType": "YulAssignment", + "src": "11231:102:22", + "value": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "11297:6:22" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "11305:6:22" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "11317:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11328:3:22", + "type": "", + "value": "128" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "11313:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "11313:19:22" + } + ], + "functionName": { + "name": "abi_encode_array_struct_Transaction_calldata_dyn_calldata", + "nodeType": "YulIdentifier", + "src": "11239:57:22" + }, + "nodeType": "YulFunctionCall", + "src": "11239:94:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "11231:4:22" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_stringliteral_4dfa0bed92fb5c2df0b47ce555e6e6b89f746e856aa9783c634a4987edcbf682_t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr__to_t_string_memory_ptr_t_array$_t_struct$_Transaction_$1292_memory_ptr_$dyn_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "11027:9:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "11038:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "11046:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "11057:4:22", + "type": "" + } + ], + "src": "10744:595:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "11376:152:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11393:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11396:77:22", + "type": "", + "value": "35408467139433450592217433187231851964531694900788300625387963629091585785856" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "11386:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "11386:88:22" + }, + "nodeType": "YulExpressionStatement", + "src": "11386:88:22" + }, + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11490:1:22", + "type": "", + "value": "4" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11493:4:22", + "type": "", + "value": "0x32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "11483:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "11483:15:22" + }, + "nodeType": "YulExpressionStatement", + "src": "11483:15:22" + }, + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11514:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11517:4:22", + "type": "", + "value": "0x24" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "11507:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "11507:15:22" + }, + "nodeType": "YulExpressionStatement", + "src": "11507:15:22" + } + ] + }, + "name": "panic_error_0x32", + "nodeType": "YulFunctionDefinition", + "src": "11344:184:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "11632:149:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "11642:26:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "11654:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11665:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "11650:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "11650:18:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "11642:4:22" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "11684:9:22" + }, + { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "11699:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11707:66:22", + "type": "", + "value": "0xff00000000000000000000000000000000000000000000000000000000000000" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "11695:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "11695:79:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "11677:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "11677:98:22" + }, + "nodeType": "YulExpressionStatement", + "src": "11677:98:22" + } + ] + }, + "name": "abi_encode_tuple_t_bytes1__to_t_bytes1__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "11601:9:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "11612:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "11623:4:22", + "type": "" + } + ], + "src": "11533:248:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "11835:432:22", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "11845:26:22", + "value": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "11865:5:22" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "11859:5:22" + }, + "nodeType": "YulFunctionCall", + "src": "11859:12:22" + }, + "variables": [ + { + "name": "length", + "nodeType": "YulTypedName", + "src": "11849:6:22", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "11887:3:22" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "11892:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "11880:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "11880:19:22" + }, + "nodeType": "YulExpressionStatement", + "src": "11880:19:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "11908:10:22", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11917:1:22", + "type": "", + "value": "0" + }, + "variables": [ + { + "name": "i", + "nodeType": "YulTypedName", + "src": "11912:1:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "11979:110:22", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "11993:14:22", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12003:4:22", + "type": "", + "value": "0x20" + }, + "variables": [ + { + "name": "_1", + "nodeType": "YulTypedName", + "src": "11997:2:22", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "12035:3:22" + }, + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "12040:1:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12031:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "12031:11:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "12044:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12027:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "12027:20:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "12063:5:22" + }, + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "12070:1:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12059:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "12059:13:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "12074:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12055:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "12055:22:22" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "12049:5:22" + }, + "nodeType": "YulFunctionCall", + "src": "12049:29:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "12020:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "12020:59:22" + }, + "nodeType": "YulExpressionStatement", + "src": "12020:59:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "11938:1:22" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "11941:6:22" + } + ], + "functionName": { + "name": "lt", + "nodeType": "YulIdentifier", + "src": "11935:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "11935:13:22" + }, + "nodeType": "YulForLoop", + "post": { + "nodeType": "YulBlock", + "src": "11949:21:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "11951:17:22", + "value": { + "arguments": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "11960:1:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11963:4:22", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "11956:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "11956:12:22" + }, + "variableNames": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "11951:1:22" + } + ] + } + ] + }, + "pre": { + "nodeType": "YulBlock", + "src": "11931:3:22", + "statements": [] + }, + "src": "11927:162:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "12113:3:22" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "12118:6:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12109:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "12109:16:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12127:4:22", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12105:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "12105:27:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12134:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "12098:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "12098:38:22" + }, + "nodeType": "YulExpressionStatement", + "src": "12098:38:22" + }, + { + "nodeType": "YulAssignment", + "src": "12145:116:22", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "12160:3:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "12173:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12181:2:22", + "type": "", + "value": "31" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12169:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "12169:15:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12186:66:22", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "12165:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "12165:88:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12156:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "12156:98:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12256:4:22", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12152:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "12152:109:22" + }, + "variableNames": [ + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "12145:3:22" + } + ] + } + ] + }, + "name": "abi_encode_bytes", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "11812:5:22", + "type": "" + }, + { + "name": "pos", + "nodeType": "YulTypedName", + "src": "11819:3:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "end", + "nodeType": "YulTypedName", + "src": "11827:3:22", + "type": "" + } + ], + "src": "11786:481:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "12391:98:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "12408:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12419:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "12401:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "12401:21:22" + }, + "nodeType": "YulExpressionStatement", + "src": "12401:21:22" + }, + { + "nodeType": "YulAssignment", + "src": "12431:52:22", + "value": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "12456:6:22" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "12468:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12479:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12464:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "12464:18:22" + } + ], + "functionName": { + "name": "abi_encode_bytes", + "nodeType": "YulIdentifier", + "src": "12439:16:22" + }, + "nodeType": "YulFunctionCall", + "src": "12439:44:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "12431:4:22" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_bytes_memory_ptr__to_t_bytes_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "12360:9:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "12371:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "12382:4:22", + "type": "" + } + ], + "src": "12272:217:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "12770:315:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "12787:3:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12792:66:22", + "type": "", + "value": "0x1901000000000000000000000000000000000000000000000000000000000000" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "12780:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "12780:79:22" + }, + "nodeType": "YulExpressionStatement", + "src": "12780:79:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "12879:3:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12884:1:22", + "type": "", + "value": "2" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12875:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "12875:11:22" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "12888:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "12868:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "12868:27:22" + }, + "nodeType": "YulExpressionStatement", + "src": "12868:27:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "12915:3:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12920:2:22", + "type": "", + "value": "34" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12911:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "12911:12:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12933:2:22", + "type": "", + "value": "96" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "12937:6:22" + } + ], + "functionName": { + "name": "shl", + "nodeType": "YulIdentifier", + "src": "12929:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "12929:15:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12946:66:22", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffff000000000000000000000000" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "12925:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "12925:88:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "12904:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "12904:110:22" + }, + "nodeType": "YulExpressionStatement", + "src": "12904:110:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "13034:3:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13039:2:22", + "type": "", + "value": "54" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "13030:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "13030:12:22" + }, + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "13044:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "13023:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "13023:28:22" + }, + "nodeType": "YulExpressionStatement", + "src": "13023:28:22" + }, + { + "nodeType": "YulAssignment", + "src": "13060:19:22", + "value": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "13071:3:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13076:2:22", + "type": "", + "value": "86" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "13067:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "13067:12:22" + }, + "variableNames": [ + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "13060:3:22" + } + ] + } + ] + }, + "name": "abi_encode_tuple_packed_t_stringliteral_301a50b291d33ce1e8e9064e3f6a6c51d902ec22892b50d58abf6357c6a45541_t_uint256_t_address_t_bytes32__to_t_string_memory_ptr_t_uint256_t_address_t_bytes32__nonPadded_inplace_fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "pos", + "nodeType": "YulTypedName", + "src": "12730:3:22", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "12735:6:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "12743:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "12751:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "end", + "nodeType": "YulTypedName", + "src": "12762:3:22", + "type": "" + } + ], + "src": "12494:591:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "13196:281:22", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "13206:51:22", + "value": { + "arguments": [ + { + "name": "ptr_to_tail", + "nodeType": "YulIdentifier", + "src": "13245:11:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "13232:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "13232:25:22" + }, + "variables": [ + { + "name": "rel_offset_of_tail", + "nodeType": "YulTypedName", + "src": "13210:18:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "13405:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13414:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13417:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "13407:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "13407:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "13407:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "rel_offset_of_tail", + "nodeType": "YulIdentifier", + "src": "13280:18:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "arguments": [], + "functionName": { + "name": "calldatasize", + "nodeType": "YulIdentifier", + "src": "13308:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "13308:14:22" + }, + { + "name": "base_ref", + "nodeType": "YulIdentifier", + "src": "13324:8:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "13304:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "13304:29:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13335:66:22", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff41" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "13300:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "13300:102:22" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "13276:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "13276:127:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "13269:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "13269:135:22" + }, + "nodeType": "YulIf", + "src": "13266:155:22" + }, + { + "nodeType": "YulAssignment", + "src": "13430:41:22", + "value": { + "arguments": [ + { + "name": "base_ref", + "nodeType": "YulIdentifier", + "src": "13442:8:22" + }, + { + "name": "rel_offset_of_tail", + "nodeType": "YulIdentifier", + "src": "13452:18:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "13438:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "13438:33:22" + }, + "variableNames": [ + { + "name": "addr", + "nodeType": "YulIdentifier", + "src": "13430:4:22" + } + ] + } + ] + }, + "name": "access_calldata_tail_t_struct$_Transaction_$1292_calldata_ptr", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "base_ref", + "nodeType": "YulTypedName", + "src": "13161:8:22", + "type": "" + }, + { + "name": "ptr_to_tail", + "nodeType": "YulTypedName", + "src": "13171:11:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "addr", + "nodeType": "YulTypedName", + "src": "13187:4:22", + "type": "" + } + ], + "src": "13090:387:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "13549:113:22", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "13595:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13604:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13607:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "13597:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "13597:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "13597:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "13570:7:22" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13579:9:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "13566:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "13566:23:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13591:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "13562:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "13562:32:22" + }, + "nodeType": "YulIf", + "src": "13559:52:22" + }, + { + "nodeType": "YulAssignment", + "src": "13620:36:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13646:9:22" + } + ], + "functionName": { + "name": "abi_decode_bool", + "nodeType": "YulIdentifier", + "src": "13630:15:22" + }, + "nodeType": "YulFunctionCall", + "src": "13630:26:22" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "13620:6:22" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_bool", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "13515:9:22", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "13526:7:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "13538:6:22", + "type": "" + } + ], + "src": "13482:180:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "13824:162:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "13834:26:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13846:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13857:2:22", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "13842:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "13842:18:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "13834:4:22" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13876:9:22" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "13887:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "13869:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "13869:25:22" + }, + "nodeType": "YulExpressionStatement", + "src": "13869:25:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13914:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13925:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "13910:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "13910:18:22" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "13930:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "13903:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "13903:34:22" + }, + "nodeType": "YulExpressionStatement", + "src": "13903:34:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13957:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13968:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "13953:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "13953:18:22" + }, + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "13973:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "13946:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "13946:34:22" + }, + "nodeType": "YulExpressionStatement", + "src": "13946:34:22" + } + ] + }, + "name": "abi_encode_tuple_t_uint256_t_uint256_t_uint256__to_t_uint256_t_uint256_t_uint256__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "13777:9:22", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "13788:6:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "13796:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "13804:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "13815:4:22", + "type": "" + } + ], + "src": "13667:319:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "14061:116:22", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "14107:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14116:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14119:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "14109:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "14109:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "14109:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "14082:7:22" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "14091:9:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "14078:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "14078:23:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14103:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "14074:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "14074:32:22" + }, + "nodeType": "YulIf", + "src": "14071:52:22" + }, + { + "nodeType": "YulAssignment", + "src": "14132:39:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "14161:9:22" + } + ], + "functionName": { + "name": "abi_decode_address", + "nodeType": "YulIdentifier", + "src": "14142:18:22" + }, + "nodeType": "YulFunctionCall", + "src": "14142:29:22" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "14132:6:22" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_address", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "14027:9:22", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "14038:7:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "14050:6:22", + "type": "" + } + ], + "src": "13991:186:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "14276:486:22", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "14286:51:22", + "value": { + "arguments": [ + { + "name": "ptr_to_tail", + "nodeType": "YulIdentifier", + "src": "14325:11:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "14312:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "14312:25:22" + }, + "variables": [ + { + "name": "rel_offset_of_tail", + "nodeType": "YulTypedName", + "src": "14290:18:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "14485:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14494:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14497:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "14487:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "14487:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "14487:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "rel_offset_of_tail", + "nodeType": "YulIdentifier", + "src": "14360:18:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "arguments": [], + "functionName": { + "name": "calldatasize", + "nodeType": "YulIdentifier", + "src": "14388:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "14388:14:22" + }, + { + "name": "base_ref", + "nodeType": "YulIdentifier", + "src": "14404:8:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "14384:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "14384:29:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14415:66:22", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "14380:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "14380:102:22" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "14356:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "14356:127:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "14349:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "14349:135:22" + }, + "nodeType": "YulIf", + "src": "14346:155:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "14510:47:22", + "value": { + "arguments": [ + { + "name": "base_ref", + "nodeType": "YulIdentifier", + "src": "14528:8:22" + }, + { + "name": "rel_offset_of_tail", + "nodeType": "YulIdentifier", + "src": "14538:18:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "14524:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "14524:33:22" + }, + "variables": [ + { + "name": "addr_1", + "nodeType": "YulTypedName", + "src": "14514:6:22", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "14566:30:22", + "value": { + "arguments": [ + { + "name": "addr_1", + "nodeType": "YulIdentifier", + "src": "14589:6:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "14576:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "14576:20:22" + }, + "variableNames": [ + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "14566:6:22" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "14639:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14648:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14651:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "14641:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "14641:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "14641:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "14611:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14619:18:22", + "type": "", + "value": "0xffffffffffffffff" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "14608:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "14608:30:22" + }, + "nodeType": "YulIf", + "src": "14605:50:22" + }, + { + "nodeType": "YulAssignment", + "src": "14664:25:22", + "value": { + "arguments": [ + { + "name": "addr_1", + "nodeType": "YulIdentifier", + "src": "14676:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14684:4:22", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "14672:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "14672:17:22" + }, + "variableNames": [ + { + "name": "addr", + "nodeType": "YulIdentifier", + "src": "14664:4:22" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "14740:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14749:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14752:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "14742:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "14742:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "14742:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "addr", + "nodeType": "YulIdentifier", + "src": "14705:4:22" + }, + { + "arguments": [ + { + "arguments": [], + "functionName": { + "name": "calldatasize", + "nodeType": "YulIdentifier", + "src": "14715:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "14715:14:22" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "14731:6:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "14711:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "14711:27:22" + } + ], + "functionName": { + "name": "sgt", + "nodeType": "YulIdentifier", + "src": "14701:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "14701:38:22" + }, + "nodeType": "YulIf", + "src": "14698:58:22" + } + ] + }, + "name": "access_calldata_tail_t_bytes_calldata_ptr", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "base_ref", + "nodeType": "YulTypedName", + "src": "14233:8:22", + "type": "" + }, + { + "name": "ptr_to_tail", + "nodeType": "YulTypedName", + "src": "14243:11:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "addr", + "nodeType": "YulTypedName", + "src": "14259:4:22", + "type": "" + }, + { + "name": "length", + "nodeType": "YulTypedName", + "src": "14265:6:22", + "type": "" + } + ], + "src": "14182:580:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "14799:152:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14816:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14819:77:22", + "type": "", + "value": "35408467139433450592217433187231851964531694900788300625387963629091585785856" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "14809:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "14809:88:22" + }, + "nodeType": "YulExpressionStatement", + "src": "14809:88:22" + }, + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14913:1:22", + "type": "", + "value": "4" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14916:4:22", + "type": "", + "value": "0x11" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "14906:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "14906:15:22" + }, + "nodeType": "YulExpressionStatement", + "src": "14906:15:22" + }, + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14937:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14940:4:22", + "type": "", + "value": "0x24" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "14930:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "14930:15:22" + }, + "nodeType": "YulExpressionStatement", + "src": "14930:15:22" + } + ] + }, + "name": "panic_error_0x11", + "nodeType": "YulFunctionDefinition", + "src": "14767:184:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "15003:148:22", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "15094:22:22", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "panic_error_0x11", + "nodeType": "YulIdentifier", + "src": "15096:16:22" + }, + "nodeType": "YulFunctionCall", + "src": "15096:18:22" + }, + "nodeType": "YulExpressionStatement", + "src": "15096:18:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "15019:5:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15026:66:22", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + } + ], + "functionName": { + "name": "eq", + "nodeType": "YulIdentifier", + "src": "15016:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "15016:77:22" + }, + "nodeType": "YulIf", + "src": "15013:103:22" + }, + { + "nodeType": "YulAssignment", + "src": "15125:20:22", + "value": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "15136:5:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15143:1:22", + "type": "", + "value": "1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "15132:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "15132:13:22" + }, + "variableNames": [ + { + "name": "ret", + "nodeType": "YulIdentifier", + "src": "15125:3:22" + } + ] + } + ] + }, + "name": "increment_t_uint256", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "14985:5:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "ret", + "nodeType": "YulTypedName", + "src": "14995:3:22", + "type": "" + } + ], + "src": "14956:195:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "15286:201:22", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "15324:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15333:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15336:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "15326:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "15326:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "15326:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "startIndex", + "nodeType": "YulIdentifier", + "src": "15302:10:22" + }, + { + "name": "endIndex", + "nodeType": "YulIdentifier", + "src": "15314:8:22" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "15299:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "15299:24:22" + }, + "nodeType": "YulIf", + "src": "15296:44:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "15373:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15382:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15385:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "15375:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "15375:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "15375:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "endIndex", + "nodeType": "YulIdentifier", + "src": "15355:8:22" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "15365:6:22" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "15352:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "15352:20:22" + }, + "nodeType": "YulIf", + "src": "15349:40:22" + }, + { + "nodeType": "YulAssignment", + "src": "15398:36:22", + "value": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "15415:6:22" + }, + { + "name": "startIndex", + "nodeType": "YulIdentifier", + "src": "15423:10:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "15411:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "15411:23:22" + }, + "variableNames": [ + { + "name": "offsetOut", + "nodeType": "YulIdentifier", + "src": "15398:9:22" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "15443:38:22", + "value": { + "arguments": [ + { + "name": "endIndex", + "nodeType": "YulIdentifier", + "src": "15460:8:22" + }, + { + "name": "startIndex", + "nodeType": "YulIdentifier", + "src": "15470:10:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "15456:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "15456:25:22" + }, + "variableNames": [ + { + "name": "lengthOut", + "nodeType": "YulIdentifier", + "src": "15443:9:22" + } + ] + } + ] + }, + "name": "calldata_array_index_range_access_t_bytes_calldata_ptr", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "15220:6:22", + "type": "" + }, + { + "name": "length", + "nodeType": "YulTypedName", + "src": "15228:6:22", + "type": "" + }, + { + "name": "startIndex", + "nodeType": "YulTypedName", + "src": "15236:10:22", + "type": "" + }, + { + "name": "endIndex", + "nodeType": "YulTypedName", + "src": "15248:8:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "offsetOut", + "nodeType": "YulTypedName", + "src": "15261:9:22", + "type": "" + }, + { + "name": "lengthOut", + "nodeType": "YulTypedName", + "src": "15272:9:22", + "type": "" + } + ], + "src": "15156:331:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "15540:77:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "15550:16:22", + "value": { + "arguments": [ + { + "name": "x", + "nodeType": "YulIdentifier", + "src": "15561:1:22" + }, + { + "name": "y", + "nodeType": "YulIdentifier", + "src": "15564:1:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "15557:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "15557:9:22" + }, + "variableNames": [ + { + "name": "sum", + "nodeType": "YulIdentifier", + "src": "15550:3:22" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "15589:22:22", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "panic_error_0x11", + "nodeType": "YulIdentifier", + "src": "15591:16:22" + }, + "nodeType": "YulFunctionCall", + "src": "15591:18:22" + }, + "nodeType": "YulExpressionStatement", + "src": "15591:18:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "x", + "nodeType": "YulIdentifier", + "src": "15581:1:22" + }, + { + "name": "sum", + "nodeType": "YulIdentifier", + "src": "15584:3:22" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "15578:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "15578:10:22" + }, + "nodeType": "YulIf", + "src": "15575:36:22" + } + ] + }, + "name": "checked_add_t_uint256", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "x", + "nodeType": "YulTypedName", + "src": "15523:1:22", + "type": "" + }, + { + "name": "y", + "nodeType": "YulTypedName", + "src": "15526:1:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "sum", + "nodeType": "YulTypedName", + "src": "15532:3:22", + "type": "" + } + ], + "src": "15492:125:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "15813:201:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "15830:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15841:2:22", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "15823:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "15823:21:22" + }, + "nodeType": "YulExpressionStatement", + "src": "15823:21:22" + }, + { + "nodeType": "YulAssignment", + "src": "15853:69:22", + "value": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "15887:6:22" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "15895:6:22" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "15907:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15918:2:22", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "15903:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "15903:18:22" + } + ], + "functionName": { + "name": "abi_encode_bytes_calldata", + "nodeType": "YulIdentifier", + "src": "15861:25:22" + }, + "nodeType": "YulFunctionCall", + "src": "15861:61:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "15853:4:22" + } + ] + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "15942:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15953:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "15938:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "15938:18:22" + }, + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "15958:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "15931:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "15931:34:22" + }, + "nodeType": "YulExpressionStatement", + "src": "15931:34:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "15985:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15996:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "15981:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "15981:18:22" + }, + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "16001:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "15974:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "15974:34:22" + }, + "nodeType": "YulExpressionStatement", + "src": "15974:34:22" + } + ] + }, + "name": "abi_encode_tuple_t_bytes_calldata_ptr_slice_t_uint256_t_uint256__to_t_bytes_memory_ptr_t_uint256_t_uint256__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "15758:9:22", + "type": "" + }, + { + "name": "value3", + "nodeType": "YulTypedName", + "src": "15769:6:22", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "15777:6:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "15785:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "15793:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "15804:4:22", + "type": "" + } + ], + "src": "15622:392:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "16148:119:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "16158:26:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16170:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16181:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "16166:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "16166:18:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "16158:4:22" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16200:9:22" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "16211:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "16193:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "16193:25:22" + }, + "nodeType": "YulExpressionStatement", + "src": "16193:25:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16238:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16249:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "16234:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "16234:18:22" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "16254:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "16227:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "16227:34:22" + }, + "nodeType": "YulExpressionStatement", + "src": "16227:34:22" + } + ] + }, + "name": "abi_encode_tuple_t_uint256_t_uint256__to_t_uint256_t_uint256__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "16109:9:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "16120:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "16128:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "16139:4:22", + "type": "" + } + ], + "src": "16019:248:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "16401:119:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "16411:26:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16423:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16434:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "16419:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "16419:18:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "16411:4:22" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16453:9:22" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "16464:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "16446:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "16446:25:22" + }, + "nodeType": "YulExpressionStatement", + "src": "16446:25:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16491:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16502:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "16487:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "16487:18:22" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "16507:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "16480:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "16480:34:22" + }, + "nodeType": "YulExpressionStatement", + "src": "16480:34:22" + } + ] + }, + "name": "abi_encode_tuple_t_bytes32_t_bytes32__to_t_bytes32_t_bytes32__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "16362:9:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "16373:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "16381:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "16392:4:22", + "type": "" + } + ], + "src": "16272:248:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "16672:141:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16689:9:22" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "16700:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "16682:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "16682:25:22" + }, + "nodeType": "YulExpressionStatement", + "src": "16682:25:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16727:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16738:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "16723:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "16723:18:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16743:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "16716:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "16716:30:22" + }, + "nodeType": "YulExpressionStatement", + "src": "16716:30:22" + }, + { + "nodeType": "YulAssignment", + "src": "16755:52:22", + "value": { + "arguments": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "16780:6:22" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16792:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16803:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "16788:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "16788:18:22" + } + ], + "functionName": { + "name": "abi_encode_bytes", + "nodeType": "YulIdentifier", + "src": "16763:16:22" + }, + "nodeType": "YulFunctionCall", + "src": "16763:44:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "16755:4:22" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_uint256_t_bytes_memory_ptr__to_t_uint256_t_bytes_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "16633:9:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "16644:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "16652:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "16663:4:22", + "type": "" + } + ], + "src": "16525:288:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "17009:250:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17026:9:22" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "17037:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "17019:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "17019:25:22" + }, + "nodeType": "YulExpressionStatement", + "src": "17019:25:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17064:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17075:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "17060:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "17060:18:22" + }, + { + "arguments": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "17084:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17092:42:22", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffff" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "17080:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "17080:55:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "17053:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "17053:83:22" + }, + "nodeType": "YulExpressionStatement", + "src": "17053:83:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17156:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17167:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "17152:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "17152:18:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17172:2:22", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "17145:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "17145:30:22" + }, + "nodeType": "YulExpressionStatement", + "src": "17145:30:22" + }, + { + "nodeType": "YulAssignment", + "src": "17184:69:22", + "value": { + "arguments": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "17218:6:22" + }, + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "17226:6:22" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17238:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17249:2:22", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "17234:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "17234:18:22" + } + ], + "functionName": { + "name": "abi_encode_bytes_calldata", + "nodeType": "YulIdentifier", + "src": "17192:25:22" + }, + "nodeType": "YulFunctionCall", + "src": "17192:61:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "17184:4:22" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_bytes32_t_address_t_bytes_calldata_ptr_slice__to_t_bytes32_t_address_t_bytes_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "16954:9:22", + "type": "" + }, + { + "name": "value3", + "nodeType": "YulTypedName", + "src": "16965:6:22", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "16973:6:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "16981:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "16989:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "17000:4:22", + "type": "" + } + ], + "src": "16818:441:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "17393:115:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17410:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17421:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "17403:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "17403:21:22" + }, + "nodeType": "YulExpressionStatement", + "src": "17403:21:22" + }, + { + "nodeType": "YulAssignment", + "src": "17433:69:22", + "value": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "17467:6:22" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "17475:6:22" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17487:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17498:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "17483:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "17483:18:22" + } + ], + "functionName": { + "name": "abi_encode_bytes_calldata", + "nodeType": "YulIdentifier", + "src": "17441:25:22" + }, + "nodeType": "YulFunctionCall", + "src": "17441:61:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "17433:4:22" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "17354:9:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "17365:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "17373:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "17384:4:22", + "type": "" + } + ], + "src": "17264:244:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "17562:79:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "17572:17:22", + "value": { + "arguments": [ + { + "name": "x", + "nodeType": "YulIdentifier", + "src": "17584:1:22" + }, + { + "name": "y", + "nodeType": "YulIdentifier", + "src": "17587:1:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "17580:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "17580:9:22" + }, + "variableNames": [ + { + "name": "diff", + "nodeType": "YulIdentifier", + "src": "17572:4:22" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "17613:22:22", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "panic_error_0x11", + "nodeType": "YulIdentifier", + "src": "17615:16:22" + }, + "nodeType": "YulFunctionCall", + "src": "17615:18:22" + }, + "nodeType": "YulExpressionStatement", + "src": "17615:18:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "diff", + "nodeType": "YulIdentifier", + "src": "17604:4:22" + }, + { + "name": "x", + "nodeType": "YulIdentifier", + "src": "17610:1:22" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "17601:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "17601:11:22" + }, + "nodeType": "YulIf", + "src": "17598:37:22" + } + ] + }, + "name": "checked_sub_t_uint256", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "x", + "nodeType": "YulTypedName", + "src": "17544:1:22", + "type": "" + }, + { + "name": "y", + "nodeType": "YulTypedName", + "src": "17547:1:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "diff", + "nodeType": "YulTypedName", + "src": "17553:4:22", + "type": "" + } + ], + "src": "17513:128:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "17803:158:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17820:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17831:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "17813:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "17813:21:22" + }, + "nodeType": "YulExpressionStatement", + "src": "17813:21:22" + }, + { + "nodeType": "YulAssignment", + "src": "17843:69:22", + "value": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "17877:6:22" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "17885:6:22" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17897:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17908:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "17893:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "17893:18:22" + } + ], + "functionName": { + "name": "abi_encode_bytes_calldata", + "nodeType": "YulIdentifier", + "src": "17851:25:22" + }, + "nodeType": "YulFunctionCall", + "src": "17851:61:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "17843:4:22" + } + ] + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17932:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17943:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "17928:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "17928:18:22" + }, + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "17948:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "17921:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "17921:34:22" + }, + "nodeType": "YulExpressionStatement", + "src": "17921:34:22" + } + ] + }, + "name": "abi_encode_tuple_t_bytes_calldata_ptr_t_bytes32__to_t_bytes_memory_ptr_t_bytes32__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "17756:9:22", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "17767:6:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "17775:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "17783:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "17794:4:22", + "type": "" + } + ], + "src": "17646:315:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "18121:169:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "18138:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "18149:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "18131:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "18131:21:22" + }, + "nodeType": "YulExpressionStatement", + "src": "18131:21:22" + }, + { + "nodeType": "YulAssignment", + "src": "18161:69:22", + "value": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "18195:6:22" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "18203:6:22" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "18215:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "18226:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "18211:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "18211:18:22" + } + ], + "functionName": { + "name": "abi_encode_bytes_calldata", + "nodeType": "YulIdentifier", + "src": "18169:25:22" + }, + "nodeType": "YulFunctionCall", + "src": "18169:61:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "18161:4:22" + } + ] + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "18250:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "18261:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "18246:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "18246:18:22" + }, + { + "arguments": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "18270:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "18278:4:22", + "type": "", + "value": "0xff" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "18266:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "18266:17:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "18239:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "18239:45:22" + }, + "nodeType": "YulExpressionStatement", + "src": "18239:45:22" + } + ] + }, + "name": "abi_encode_tuple_t_bytes_calldata_ptr_t_uint8__to_t_bytes_memory_ptr_t_uint256__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "18074:9:22", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "18085:6:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "18093:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "18101:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "18112:4:22", + "type": "" + } + ], + "src": "17966:324:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "18476:217:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "18486:27:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "18498:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "18509:3:22", + "type": "", + "value": "128" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "18494:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "18494:19:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "18486:4:22" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "18529:9:22" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "18540:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "18522:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "18522:25:22" + }, + "nodeType": "YulExpressionStatement", + "src": "18522:25:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "18567:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "18578:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "18563:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "18563:18:22" + }, + { + "arguments": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "18587:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "18595:4:22", + "type": "", + "value": "0xff" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "18583:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "18583:17:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "18556:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "18556:45:22" + }, + "nodeType": "YulExpressionStatement", + "src": "18556:45:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "18621:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "18632:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "18617:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "18617:18:22" + }, + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "18637:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "18610:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "18610:34:22" + }, + "nodeType": "YulExpressionStatement", + "src": "18610:34:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "18664:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "18675:2:22", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "18660:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "18660:18:22" + }, + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "18680:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "18653:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "18653:34:22" + }, + "nodeType": "YulExpressionStatement", + "src": "18653:34:22" + } + ] + }, + "name": "abi_encode_tuple_t_bytes32_t_uint8_t_bytes32_t_bytes32__to_t_bytes32_t_uint8_t_bytes32_t_bytes32__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "18421:9:22", + "type": "" + }, + { + "name": "value3", + "nodeType": "YulTypedName", + "src": "18432:6:22", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "18440:6:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "18448:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "18456:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "18467:4:22", + "type": "" + } + ], + "src": "18295:398:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "18918:160:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "18935:3:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "18940:66:22", + "type": "", + "value": "0x19457468657265756d205369676e6564204d6573736167653a0a333200000000" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "18928:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "18928:79:22" + }, + "nodeType": "YulExpressionStatement", + "src": "18928:79:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "19027:3:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "19032:2:22", + "type": "", + "value": "28" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "19023:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "19023:12:22" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "19037:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "19016:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "19016:28:22" + }, + "nodeType": "YulExpressionStatement", + "src": "19016:28:22" + }, + { + "nodeType": "YulAssignment", + "src": "19053:19:22", + "value": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "19064:3:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "19069:2:22", + "type": "", + "value": "60" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "19060:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "19060:12:22" + }, + "variableNames": [ + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "19053:3:22" + } + ] + } + ] + }, + "name": "abi_encode_tuple_packed_t_stringliteral_178a2411ab6fbc1ba11064408972259c558d0e82fd48b0aba3ad81d14f065e73_t_bytes32__to_t_string_memory_ptr_t_bytes32__nonPadded_inplace_fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "pos", + "nodeType": "YulTypedName", + "src": "18894:3:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "18899:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "end", + "nodeType": "YulTypedName", + "src": "18910:3:22", + "type": "" + } + ], + "src": "18698:380:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "19262:217:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "19279:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "19290:2:22", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "19272:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "19272:21:22" + }, + "nodeType": "YulExpressionStatement", + "src": "19272:21:22" + }, + { + "nodeType": "YulAssignment", + "src": "19302:69:22", + "value": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "19336:6:22" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "19344:6:22" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "19356:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "19367:2:22", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "19352:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "19352:18:22" + } + ], + "functionName": { + "name": "abi_encode_bytes_calldata", + "nodeType": "YulIdentifier", + "src": "19310:25:22" + }, + "nodeType": "YulFunctionCall", + "src": "19310:61:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "19302:4:22" + } + ] + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "19391:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "19402:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "19387:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "19387:18:22" + }, + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "19407:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "19380:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "19380:34:22" + }, + "nodeType": "YulExpressionStatement", + "src": "19380:34:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "19434:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "19445:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "19430:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "19430:18:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "19464:6:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "19457:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "19457:14:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "19450:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "19450:22:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "19423:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "19423:50:22" + }, + "nodeType": "YulExpressionStatement", + "src": "19423:50:22" + } + ] + }, + "name": "abi_encode_tuple_t_bytes_calldata_ptr_t_uint256_t_bool__to_t_bytes_memory_ptr_t_uint256_t_bool__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "19207:9:22", + "type": "" + }, + { + "name": "value3", + "nodeType": "YulTypedName", + "src": "19218:6:22", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "19226:6:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "19234:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "19242:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "19253:4:22", + "type": "" + } + ], + "src": "19083:396:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "19647:158:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "19664:9:22" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "19675:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "19657:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "19657:25:22" + }, + "nodeType": "YulExpressionStatement", + "src": "19657:25:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "19702:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "19713:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "19698:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "19698:18:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "19718:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "19691:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "19691:30:22" + }, + "nodeType": "YulExpressionStatement", + "src": "19691:30:22" + }, + { + "nodeType": "YulAssignment", + "src": "19730:69:22", + "value": { + "arguments": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "19764:6:22" + }, + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "19772:6:22" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "19784:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "19795:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "19780:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "19780:18:22" + } + ], + "functionName": { + "name": "abi_encode_bytes_calldata", + "nodeType": "YulIdentifier", + "src": "19738:25:22" + }, + "nodeType": "YulFunctionCall", + "src": "19738:61:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "19730:4:22" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_bytes32_t_bytes_calldata_ptr_slice__to_t_bytes32_t_bytes_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "19600:9:22", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "19611:6:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "19619:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "19627:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "19638:4:22", + "type": "" + } + ], + "src": "19484:321:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "19890:169:22", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "19936:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "19945:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "19948:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "19938:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "19938:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "19938:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "19911:7:22" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "19920:9:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "19907:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "19907:23:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "19932:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "19903:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "19903:32:22" + }, + "nodeType": "YulIf", + "src": "19900:52:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "19961:29:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "19980:9:22" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "19974:5:22" + }, + "nodeType": "YulFunctionCall", + "src": "19974:16:22" + }, + "variables": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "19965:5:22", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "20023:5:22" + } + ], + "functionName": { + "name": "validator_revert_bytes4", + "nodeType": "YulIdentifier", + "src": "19999:23:22" + }, + "nodeType": "YulFunctionCall", + "src": "19999:30:22" + }, + "nodeType": "YulExpressionStatement", + "src": "19999:30:22" + }, + { + "nodeType": "YulAssignment", + "src": "20038:15:22", + "value": { + "name": "value", + "nodeType": "YulIdentifier", + "src": "20048:5:22" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "20038:6:22" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_bytes4_fromMemory", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "19856:9:22", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "19867:7:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "19879:6:22", + "type": "" + } + ], + "src": "19810:249:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "20340:235:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "20357:3:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "20362:66:22", + "type": "", + "value": "0x53657175656e6365206e657374656420636f6e6669673a0a0000000000000000" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "20350:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "20350:79:22" + }, + "nodeType": "YulExpressionStatement", + "src": "20350:79:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "20449:3:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "20454:2:22", + "type": "", + "value": "24" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "20445:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "20445:12:22" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "20459:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "20438:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "20438:28:22" + }, + "nodeType": "YulExpressionStatement", + "src": "20438:28:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "20486:3:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "20491:2:22", + "type": "", + "value": "56" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "20482:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "20482:12:22" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "20496:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "20475:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "20475:28:22" + }, + "nodeType": "YulExpressionStatement", + "src": "20475:28:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "20523:3:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "20528:2:22", + "type": "", + "value": "88" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "20519:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "20519:12:22" + }, + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "20533:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "20512:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "20512:28:22" + }, + "nodeType": "YulExpressionStatement", + "src": "20512:28:22" + }, + { + "nodeType": "YulAssignment", + "src": "20549:20:22", + "value": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "20560:3:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "20565:3:22", + "type": "", + "value": "120" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "20556:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "20556:13:22" + }, + "variableNames": [ + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "20549:3:22" + } + ] + } + ] + }, + "name": "abi_encode_tuple_packed_t_stringliteral_58d1832f15932b40f8da147bd99ac98efab990f25a786a2229b05ee5f5be41a7_t_bytes32_t_uint256_t_uint256__to_t_string_memory_ptr_t_bytes32_t_uint256_t_uint256__nonPadded_inplace_fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "pos", + "nodeType": "YulTypedName", + "src": "20300:3:22", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "20305:6:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "20313:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "20321:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "end", + "nodeType": "YulTypedName", + "src": "20332:3:22", + "type": "" + } + ], + "src": "20064:511:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "20800:160:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "20817:3:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "20822:66:22", + "type": "", + "value": "0x53657175656e636520737461746963206469676573743a0a0000000000000000" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "20810:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "20810:79:22" + }, + "nodeType": "YulExpressionStatement", + "src": "20810:79:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "20909:3:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "20914:2:22", + "type": "", + "value": "24" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "20905:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "20905:12:22" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "20919:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "20898:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "20898:28:22" + }, + "nodeType": "YulExpressionStatement", + "src": "20898:28:22" + }, + { + "nodeType": "YulAssignment", + "src": "20935:19:22", + "value": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "20946:3:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "20951:2:22", + "type": "", + "value": "56" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "20942:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "20942:12:22" + }, + "variableNames": [ + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "20935:3:22" + } + ] + } + ] + }, + "name": "abi_encode_tuple_packed_t_stringliteral_583557e68bca91e5400591dbc9ae31043113c95e3cd985463ae532f51d706f8c_t_bytes32__to_t_string_memory_ptr_t_bytes32__nonPadded_inplace_fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "pos", + "nodeType": "YulTypedName", + "src": "20776:3:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "20781:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "end", + "nodeType": "YulTypedName", + "src": "20792:3:22", + "type": "" + } + ], + "src": "20580:380:22" + } + ] + }, + "contents": "{\n { }\n function validator_revert_bytes4(value)\n {\n if iszero(eq(value, and(value, 0xffffffff00000000000000000000000000000000000000000000000000000000))) { revert(0, 0) }\n }\n function abi_decode_tuple_t_bytes4(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_bytes4(value)\n value0 := value\n }\n function abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, iszero(iszero(value0)))\n }\n function abi_decode_bytes_calldata(offset, end) -> arrayPos, length\n {\n if iszero(slt(add(offset, 0x1f), end)) { revert(0, 0) }\n length := calldataload(offset)\n if gt(length, 0xffffffffffffffff) { revert(0, 0) }\n arrayPos := add(offset, 0x20)\n if gt(add(add(offset, length), 0x20), end) { revert(0, 0) }\n }\n function abi_decode_tuple_t_bytes32t_bytes_calldata_ptr(headStart, dataEnd) -> value0, value1, value2\n {\n if slt(sub(dataEnd, headStart), 64) { revert(0, 0) }\n value0 := calldataload(headStart)\n let offset := calldataload(add(headStart, 32))\n if gt(offset, 0xffffffffffffffff) { revert(0, 0) }\n let value1_1, value2_1 := abi_decode_bytes_calldata(add(headStart, offset), dataEnd)\n value1 := value1_1\n value2 := value2_1\n }\n function abi_encode_tuple_t_bytes4__to_t_bytes4__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, and(value0, 0xffffffff00000000000000000000000000000000000000000000000000000000))\n }\n function abi_decode_tuple_t_bytes_calldata_ptrt_bytes_calldata_ptr(headStart, dataEnd) -> value0, value1, value2, value3\n {\n if slt(sub(dataEnd, headStart), 64) { revert(0, 0) }\n let offset := calldataload(headStart)\n let _1 := 0xffffffffffffffff\n if gt(offset, _1) { revert(0, 0) }\n let value0_1, value1_1 := abi_decode_bytes_calldata(add(headStart, offset), dataEnd)\n value0 := value0_1\n value1 := value1_1\n let offset_1 := calldataload(add(headStart, 32))\n if gt(offset_1, _1) { revert(0, 0) }\n let value2_1, value3_1 := abi_decode_bytes_calldata(add(headStart, offset_1), dataEnd)\n value2 := value2_1\n value3 := value3_1\n }\n function abi_decode_tuple_t_bytes32(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n value0 := calldataload(headStart)\n }\n function abi_encode_tuple_t_bytes32__to_t_bytes32__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, value0)\n }\n function abi_decode_array_struct_Transaction_calldata_dyn_calldata(offset, end) -> arrayPos, length\n {\n if iszero(slt(add(offset, 0x1f), end)) { revert(0, 0) }\n length := calldataload(offset)\n if gt(length, 0xffffffffffffffff) { revert(0, 0) }\n arrayPos := add(offset, 0x20)\n if gt(add(add(offset, shl(5, length)), 0x20), end) { revert(0, 0) }\n }\n function abi_decode_tuple_t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr(headStart, dataEnd) -> value0, value1\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let offset := calldataload(headStart)\n if gt(offset, 0xffffffffffffffff) { revert(0, 0) }\n let value0_1, value1_1 := abi_decode_array_struct_Transaction_calldata_dyn_calldata(add(headStart, offset), dataEnd)\n value0 := value0_1\n value1 := value1_1\n }\n function abi_decode_tuple_t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptrt_uint256t_bytes_calldata_ptr(headStart, dataEnd) -> value0, value1, value2, value3, value4\n {\n if slt(sub(dataEnd, headStart), 96) { revert(0, 0) }\n let offset := calldataload(headStart)\n let _1 := 0xffffffffffffffff\n if gt(offset, _1) { revert(0, 0) }\n let value0_1, value1_1 := abi_decode_array_struct_Transaction_calldata_dyn_calldata(add(headStart, offset), dataEnd)\n value0 := value0_1\n value1 := value1_1\n value2 := calldataload(add(headStart, 32))\n let offset_1 := calldataload(add(headStart, 64))\n if gt(offset_1, _1) { revert(0, 0) }\n let value3_1, value4_1 := abi_decode_bytes_calldata(add(headStart, offset_1), dataEnd)\n value3 := value3_1\n value4 := value4_1\n }\n function abi_encode_tuple_t_uint256_t_uint256_t_bytes32_t_bytes32_t_uint256__to_t_uint256_t_uint256_t_bytes32_t_bytes32_t_uint256__fromStack_reversed(headStart, value4, value3, value2, value1, value0) -> tail\n {\n tail := add(headStart, 160)\n mstore(headStart, value0)\n mstore(add(headStart, 32), value1)\n mstore(add(headStart, 64), value2)\n mstore(add(headStart, 96), value3)\n mstore(add(headStart, 128), value4)\n }\n function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n value0 := calldataload(headStart)\n }\n function abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, value0)\n }\n function panic_error_0x41()\n {\n mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n mstore(4, 0x41)\n revert(0, 0x24)\n }\n function abi_decode_tuple_t_bytes_memory_ptr(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let offset := calldataload(headStart)\n let _1 := 0xffffffffffffffff\n if gt(offset, _1) { revert(0, 0) }\n let _2 := add(headStart, offset)\n if iszero(slt(add(_2, 0x1f), dataEnd)) { revert(0, 0) }\n let _3 := calldataload(_2)\n if gt(_3, _1) { panic_error_0x41() }\n let _4 := 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0\n let memPtr := mload(64)\n let newFreePtr := add(memPtr, and(add(and(add(_3, 0x1f), _4), 63), _4))\n if or(gt(newFreePtr, _1), lt(newFreePtr, memPtr)) { panic_error_0x41() }\n mstore(64, newFreePtr)\n mstore(memPtr, _3)\n if gt(add(add(_2, _3), 32), dataEnd) { revert(0, 0) }\n calldatacopy(add(memPtr, 32), add(_2, 32), _3)\n mstore(add(add(memPtr, _3), 32), 0)\n value0 := memPtr\n }\n function abi_encode_tuple_t_address__to_t_address__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, and(value0, 0xffffffffffffffffffffffffffffffffffffffff))\n }\n function abi_encode_tuple_packed_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__nonPadded_inplace_fromStack_reversed(pos, value1, value0) -> end\n {\n calldatacopy(pos, value0, value1)\n let _1 := add(pos, value1)\n mstore(_1, 0)\n end := _1\n }\n function abi_encode_tuple_t_address_t_address__to_t_address_t_address__fromStack_reversed(headStart, value1, value0) -> tail\n {\n tail := add(headStart, 64)\n let _1 := 0xffffffffffffffffffffffffffffffffffffffff\n mstore(headStart, and(value0, _1))\n mstore(add(headStart, 32), and(value1, _1))\n }\n function abi_decode_bool(offset) -> value\n {\n value := calldataload(offset)\n if iszero(eq(value, iszero(iszero(value)))) { revert(0, 0) }\n }\n function abi_decode_address(offset) -> value\n {\n value := calldataload(offset)\n if iszero(eq(value, and(value, 0xffffffffffffffffffffffffffffffffffffffff))) { revert(0, 0) }\n }\n function abi_encode_bytes_calldata(start, length, pos) -> end\n {\n mstore(pos, length)\n calldatacopy(add(pos, 0x20), start, length)\n mstore(add(add(pos, length), 0x20), 0)\n end := add(add(pos, and(add(length, 31), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0)), 0x20)\n }\n function abi_encode_array_struct_Transaction_calldata_dyn_calldata(value, length, pos) -> end\n {\n mstore(pos, length)\n let _1 := 0x20\n let updated_pos := add(pos, _1)\n let pos_1 := updated_pos\n pos := updated_pos\n let tail := add(pos_1, shl(5, length))\n let srcPtr := value\n let i := 0\n for { } lt(i, length) { i := add(i, 1) }\n {\n mstore(pos, sub(tail, pos_1))\n let rel_offset_of_tail := calldataload(srcPtr)\n if iszero(slt(rel_offset_of_tail, add(sub(calldatasize(), value), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff41))) { revert(0, 0) }\n let value_1 := add(rel_offset_of_tail, value)\n let _2 := 0xc0\n mstore(tail, iszero(iszero(abi_decode_bool(value_1))))\n mstore(add(tail, _1), iszero(iszero(abi_decode_bool(add(value_1, _1)))))\n let _3 := 0x40\n mstore(add(tail, _3), calldataload(add(value_1, _3)))\n let _4 := 0x60\n mstore(add(tail, _4), and(abi_decode_address(add(value_1, _4)), 0xffffffffffffffffffffffffffffffffffffffff))\n let _5 := 0x80\n mstore(add(tail, _5), calldataload(add(value_1, _5)))\n let _6 := 0xa0\n let rel_offset_of_tail_1 := calldataload(add(value_1, _6))\n if iszero(slt(rel_offset_of_tail_1, add(sub(calldatasize(), value_1), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1))) { revert(0, 0) }\n let value_2 := add(rel_offset_of_tail_1, value_1)\n let length_1 := calldataload(value_2)\n let value_3 := add(value_2, _1)\n if gt(length_1, 0xffffffffffffffff) { revert(0, 0) }\n if sgt(value_3, sub(calldatasize(), length_1)) { revert(0, 0) }\n mstore(add(tail, _6), _2)\n tail := abi_encode_bytes_calldata(value_3, length_1, add(tail, _2))\n srcPtr := add(srcPtr, _1)\n pos := add(pos, _1)\n }\n end := tail\n }\n function abi_encode_tuple_t_stringliteral_bf9461da9f9c0123d3a54c61147a274d8fdb5d5c1e488665fb11b9edbbc32845_t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr__to_t_string_memory_ptr_t_array$_t_struct$_Transaction_$1292_memory_ptr_$dyn_memory_ptr__fromStack_reversed(headStart, value1, value0) -> tail\n {\n mstore(headStart, 64)\n mstore(add(headStart, 64), 5)\n mstore(add(headStart, 96), \"self:\")\n mstore(add(headStart, 0x20), 128)\n tail := abi_encode_array_struct_Transaction_calldata_dyn_calldata(value0, value1, add(headStart, 128))\n }\n function abi_encode_tuple_t_stringliteral_4dfa0bed92fb5c2df0b47ce555e6e6b89f746e856aa9783c634a4987edcbf682_t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr__to_t_string_memory_ptr_t_array$_t_struct$_Transaction_$1292_memory_ptr_$dyn_memory_ptr__fromStack_reversed(headStart, value1, value0) -> tail\n {\n mstore(headStart, 64)\n mstore(add(headStart, 64), 6)\n mstore(add(headStart, 96), \"guest:\")\n mstore(add(headStart, 0x20), 128)\n tail := abi_encode_array_struct_Transaction_calldata_dyn_calldata(value0, value1, add(headStart, 128))\n }\n function panic_error_0x32()\n {\n mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n mstore(4, 0x32)\n revert(0, 0x24)\n }\n function abi_encode_tuple_t_bytes1__to_t_bytes1__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, and(value0, 0xff00000000000000000000000000000000000000000000000000000000000000))\n }\n function abi_encode_bytes(value, pos) -> end\n {\n let length := mload(value)\n mstore(pos, length)\n let i := 0\n for { } lt(i, length) { i := add(i, 0x20) }\n {\n let _1 := 0x20\n mstore(add(add(pos, i), _1), mload(add(add(value, i), _1)))\n }\n mstore(add(add(pos, length), 0x20), 0)\n end := add(add(pos, and(add(length, 31), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0)), 0x20)\n }\n function abi_encode_tuple_t_bytes_memory_ptr__to_t_bytes_memory_ptr__fromStack_reversed(headStart, value0) -> tail\n {\n mstore(headStart, 32)\n tail := abi_encode_bytes(value0, add(headStart, 32))\n }\n function abi_encode_tuple_packed_t_stringliteral_301a50b291d33ce1e8e9064e3f6a6c51d902ec22892b50d58abf6357c6a45541_t_uint256_t_address_t_bytes32__to_t_string_memory_ptr_t_uint256_t_address_t_bytes32__nonPadded_inplace_fromStack_reversed(pos, value2, value1, value0) -> end\n {\n mstore(pos, 0x1901000000000000000000000000000000000000000000000000000000000000)\n mstore(add(pos, 2), value0)\n mstore(add(pos, 34), and(shl(96, value1), 0xffffffffffffffffffffffffffffffffffffffff000000000000000000000000))\n mstore(add(pos, 54), value2)\n end := add(pos, 86)\n }\n function access_calldata_tail_t_struct$_Transaction_$1292_calldata_ptr(base_ref, ptr_to_tail) -> addr\n {\n let rel_offset_of_tail := calldataload(ptr_to_tail)\n if iszero(slt(rel_offset_of_tail, add(sub(calldatasize(), base_ref), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff41))) { revert(0, 0) }\n addr := add(base_ref, rel_offset_of_tail)\n }\n function abi_decode_tuple_t_bool(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n value0 := abi_decode_bool(headStart)\n }\n function abi_encode_tuple_t_uint256_t_uint256_t_uint256__to_t_uint256_t_uint256_t_uint256__fromStack_reversed(headStart, value2, value1, value0) -> tail\n {\n tail := add(headStart, 96)\n mstore(headStart, value0)\n mstore(add(headStart, 32), value1)\n mstore(add(headStart, 64), value2)\n }\n function abi_decode_tuple_t_address(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n value0 := abi_decode_address(headStart)\n }\n function access_calldata_tail_t_bytes_calldata_ptr(base_ref, ptr_to_tail) -> addr, length\n {\n let rel_offset_of_tail := calldataload(ptr_to_tail)\n if iszero(slt(rel_offset_of_tail, add(sub(calldatasize(), base_ref), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1))) { revert(0, 0) }\n let addr_1 := add(base_ref, rel_offset_of_tail)\n length := calldataload(addr_1)\n if gt(length, 0xffffffffffffffff) { revert(0, 0) }\n addr := add(addr_1, 0x20)\n if sgt(addr, sub(calldatasize(), length)) { revert(0, 0) }\n }\n function panic_error_0x11()\n {\n mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n mstore(4, 0x11)\n revert(0, 0x24)\n }\n function increment_t_uint256(value) -> ret\n {\n if eq(value, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) { panic_error_0x11() }\n ret := add(value, 1)\n }\n function calldata_array_index_range_access_t_bytes_calldata_ptr(offset, length, startIndex, endIndex) -> offsetOut, lengthOut\n {\n if gt(startIndex, endIndex) { revert(0, 0) }\n if gt(endIndex, length) { revert(0, 0) }\n offsetOut := add(offset, startIndex)\n lengthOut := sub(endIndex, startIndex)\n }\n function checked_add_t_uint256(x, y) -> sum\n {\n sum := add(x, y)\n if gt(x, sum) { panic_error_0x11() }\n }\n function abi_encode_tuple_t_bytes_calldata_ptr_slice_t_uint256_t_uint256__to_t_bytes_memory_ptr_t_uint256_t_uint256__fromStack_reversed(headStart, value3, value2, value1, value0) -> tail\n {\n mstore(headStart, 96)\n tail := abi_encode_bytes_calldata(value0, value1, add(headStart, 96))\n mstore(add(headStart, 32), value2)\n mstore(add(headStart, 64), value3)\n }\n function abi_encode_tuple_t_uint256_t_uint256__to_t_uint256_t_uint256__fromStack_reversed(headStart, value1, value0) -> tail\n {\n tail := add(headStart, 64)\n mstore(headStart, value0)\n mstore(add(headStart, 32), value1)\n }\n function abi_encode_tuple_t_bytes32_t_bytes32__to_t_bytes32_t_bytes32__fromStack_reversed(headStart, value1, value0) -> tail\n {\n tail := add(headStart, 64)\n mstore(headStart, value0)\n mstore(add(headStart, 32), value1)\n }\n function abi_encode_tuple_t_uint256_t_bytes_memory_ptr__to_t_uint256_t_bytes_memory_ptr__fromStack_reversed(headStart, value1, value0) -> tail\n {\n mstore(headStart, value0)\n mstore(add(headStart, 32), 64)\n tail := abi_encode_bytes(value1, add(headStart, 64))\n }\n function abi_encode_tuple_t_bytes32_t_address_t_bytes_calldata_ptr_slice__to_t_bytes32_t_address_t_bytes_memory_ptr__fromStack_reversed(headStart, value3, value2, value1, value0) -> tail\n {\n mstore(headStart, value0)\n mstore(add(headStart, 32), and(value1, 0xffffffffffffffffffffffffffffffffffffffff))\n mstore(add(headStart, 64), 96)\n tail := abi_encode_bytes_calldata(value2, value3, add(headStart, 96))\n }\n function abi_encode_tuple_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__fromStack_reversed(headStart, value1, value0) -> tail\n {\n mstore(headStart, 32)\n tail := abi_encode_bytes_calldata(value0, value1, add(headStart, 32))\n }\n function checked_sub_t_uint256(x, y) -> diff\n {\n diff := sub(x, y)\n if gt(diff, x) { panic_error_0x11() }\n }\n function abi_encode_tuple_t_bytes_calldata_ptr_t_bytes32__to_t_bytes_memory_ptr_t_bytes32__fromStack_reversed(headStart, value2, value1, value0) -> tail\n {\n mstore(headStart, 64)\n tail := abi_encode_bytes_calldata(value0, value1, add(headStart, 64))\n mstore(add(headStart, 32), value2)\n }\n function abi_encode_tuple_t_bytes_calldata_ptr_t_uint8__to_t_bytes_memory_ptr_t_uint256__fromStack_reversed(headStart, value2, value1, value0) -> tail\n {\n mstore(headStart, 64)\n tail := abi_encode_bytes_calldata(value0, value1, add(headStart, 64))\n mstore(add(headStart, 32), and(value2, 0xff))\n }\n function abi_encode_tuple_t_bytes32_t_uint8_t_bytes32_t_bytes32__to_t_bytes32_t_uint8_t_bytes32_t_bytes32__fromStack_reversed(headStart, value3, value2, value1, value0) -> tail\n {\n tail := add(headStart, 128)\n mstore(headStart, value0)\n mstore(add(headStart, 32), and(value1, 0xff))\n mstore(add(headStart, 64), value2)\n mstore(add(headStart, 96), value3)\n }\n function abi_encode_tuple_packed_t_stringliteral_178a2411ab6fbc1ba11064408972259c558d0e82fd48b0aba3ad81d14f065e73_t_bytes32__to_t_string_memory_ptr_t_bytes32__nonPadded_inplace_fromStack_reversed(pos, value0) -> end\n {\n mstore(pos, 0x19457468657265756d205369676e6564204d6573736167653a0a333200000000)\n mstore(add(pos, 28), value0)\n end := add(pos, 60)\n }\n function abi_encode_tuple_t_bytes_calldata_ptr_t_uint256_t_bool__to_t_bytes_memory_ptr_t_uint256_t_bool__fromStack_reversed(headStart, value3, value2, value1, value0) -> tail\n {\n mstore(headStart, 96)\n tail := abi_encode_bytes_calldata(value0, value1, add(headStart, 96))\n mstore(add(headStart, 32), value2)\n mstore(add(headStart, 64), iszero(iszero(value3)))\n }\n function abi_encode_tuple_t_bytes32_t_bytes_calldata_ptr_slice__to_t_bytes32_t_bytes_memory_ptr__fromStack_reversed(headStart, value2, value1, value0) -> tail\n {\n mstore(headStart, value0)\n mstore(add(headStart, 32), 64)\n tail := abi_encode_bytes_calldata(value1, value2, add(headStart, 64))\n }\n function abi_decode_tuple_t_bytes4_fromMemory(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let value := mload(headStart)\n validator_revert_bytes4(value)\n value0 := value\n }\n function abi_encode_tuple_packed_t_stringliteral_58d1832f15932b40f8da147bd99ac98efab990f25a786a2229b05ee5f5be41a7_t_bytes32_t_uint256_t_uint256__to_t_string_memory_ptr_t_bytes32_t_uint256_t_uint256__nonPadded_inplace_fromStack_reversed(pos, value2, value1, value0) -> end\n {\n mstore(pos, 0x53657175656e6365206e657374656420636f6e6669673a0a0000000000000000)\n mstore(add(pos, 24), value0)\n mstore(add(pos, 56), value1)\n mstore(add(pos, 88), value2)\n end := add(pos, 120)\n }\n function abi_encode_tuple_packed_t_stringliteral_583557e68bca91e5400591dbc9ae31043113c95e3cd985463ae532f51d706f8c_t_bytes32__to_t_string_memory_ptr_t_bytes32__nonPadded_inplace_fromStack_reversed(pos, value0) -> end\n {\n mstore(pos, 0x53657175656e636520737461746963206469676573743a0a0000000000000000)\n mstore(add(pos, 24), value0)\n end := add(pos, 56)\n }\n}", + "id": 22, + "language": "Yul", + "name": "#utility.yul" + } + ], + "immutableReferences": {}, + "linkReferences": {}, + "object": "6080604052600436106100bc5760003560e01c806361c2926c116100745780638c3f55631161004e5780638c3f55631461025357806390042baf14610273578063affed0e0146102ab57600080fd5b806361c2926c146101cb5780637a9a1628146101eb578063853c50681461020b57600080fd5b806320c13b0b116100a557806320c13b0b14610147578063295614261461016757806357c56d6b1461018957600080fd5b806301ffc9a7146100c15780631626ba7e146100f6575b600080fd5b3480156100cd57600080fd5b506100e16100dc366004611880565b6102c0565b60405190151581526020015b60405180910390f35b34801561010257600080fd5b506101166101113660046118e6565b6102d1565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016100ed565b34801561015357600080fd5b50610116610162366004611932565b61031e565b34801561017357600080fd5b5061018761018236600461199e565b610383565b005b34801561019557600080fd5b506101bd7f8713a7c4465f6fbee2b6e9d6646d1d9f83fec929edfc4baf661f3c865bdd04d181565b6040519081526020016100ed565b3480156101d757600080fd5b506101876101e63660046119fc565b6103d5565b3480156101f757600080fd5b50610187610206366004611a3e565b61041a565b34801561021757600080fd5b5061022b6102263660046118e6565b610447565b604080519586526020860194909452928401919091526060830152608082015260a0016100ed565b34801561025f57600080fd5b506101bd61026e36600461199e565b61060f565b610286610281366004611ae7565b61063b565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100ed565b3480156102b757600080fd5b506101bd610725565b60006102cb82610736565b92915050565b6000806102df858585610792565b509050801561031157507f1626ba7e000000000000000000000000000000000000000000000000000000009050610317565b50600090505b9392505050565b6000806103438686604051610334929190611bb6565b60405180910390208585610792565b509050801561037557507f20c13b0b00000000000000000000000000000000000000000000000000000000905061037b565b50600090505b949350505050565b3330146103c9576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044015b60405180910390fd5b6103d2816107ca565b50565b600061040883836040516020016103ed929190611d97565b604051602081830303815290604052805190602001206107fc565b9050610415818484610881565b505050565b600061043286866040516020016103ed929190611ddf565b905061043f818787610881565b505050505050565b6000806000806000808787600081811061046357610463611e27565b909101357fff000000000000000000000000000000000000000000000000000000000000001691508190506104b95761049b896107fc565b92506104a8838989610a0e565b929850909650945091506106049050565b7fff00000000000000000000000000000000000000000000000000000000000000818116016104f8576104eb896107fc565b92506104a8838989610a5f565b7ffe000000000000000000000000000000000000000000000000000000000000007fff0000000000000000000000000000000000000000000000000000000000000082160161054a576104eb89610a8b565b7ffd000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216016105ae5761059e898989610af8565b9550955095509550955050610604565b6040517f6085cd820000000000000000000000000000000000000000000000000000000081527fff00000000000000000000000000000000000000000000000000000000000000821660048201526024016103c0565b939792965093509350565b60006102cb7f8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e83610c75565b600033301461067e576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044016103c0565b81516020830134f0905073ffffffffffffffffffffffffffffffffffffffff81166106d757816040517f0d2571910000000000000000000000000000000000000000000000000000000081526004016103c09190611eba565b60405173ffffffffffffffffffffffffffffffffffffffff821681527fa506ad4e7f05eceba62a023c3219e5bd98a615f4fa87e2afb08a2da5cf62bf0c9060200160405180910390a1919050565b6000610731600061060f565b905090565b60007f6ffbd451000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083160161078957506001919050565b6102cb82610cd3565b60008060008060006107a5888888610447565b509650919450925090508282108015906107bd575060015b9450505050935093915050565b6040517fa038794000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f190100000000000000000000000000000000000000000000000000000000000060208201524660228201527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b166042820152605681018290526000906076015b604051602081830303815290604052805190602001209050919050565b8060005b81811015610a0757368484838181106108a0576108a0611e27565b90506020028101906108b29190611ecd565b90506108c16020820182611f0b565b156108fb576040517f230d1ccc000000000000000000000000000000000000000000000000000000008152600481018390526024016103c0565b6040810135805a101561094e5782815a6040517f2bb3e3ba0000000000000000000000000000000000000000000000000000000081526004810193909352602483019190915260448201526064016103c0565b60006109886109636080850160608601611f26565b608085013584156109745784610976565b5a5b61098360a0880188611f41565b610d2f565b905080156109cf57877f5c4eeb02dabf8976016ab414d617f9a162936dcace3cdef8c69ef6e262ad5ae7856040516109c291815260200190565b60405180910390a26109f1565b6109f16109e26040850160208601611f0b565b89866109ec610d4c565b610d6b565b50505080806109ff90611fd5565b915050610885565b5050505050565b6000808080610a2987610a24876006818b61200d565b610db9565b6000908152873560f01c6020818152604080842084526002909a013560e01c908190529890912090999198509695509350505050565b6000808080610a7a87610a75876001818b61200d565b610a0e565b935093509350935093509350935093565b6040517f190100000000000000000000000000000000000000000000000000000000000060208201526000602282018190527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b1660428301526056820183905290607601610864565b6000808080806004600188013560e81c82610b138383612037565b9050610b258b61022683868d8f61200d565b939b5091995097509550935087871015610b7d57610b4581848b8d61200d565b89896040517fb006aba00000000000000000000000000000000000000000000000000000000081526004016103c0949392919061204a565b8092505b88831015610c675760038301928a013560e81c9150610ba08383612037565b90506000610bc2610bb08861124f565b8c8c879086926102269392919061200d565b939c50919a5098509091505088881015610c1a57610be282858c8e61200d565b8a8a6040517fb006aba00000000000000000000000000000000000000000000000000000000081526004016103c0949392919061204a565b848110610c5d576040517f37daf62b00000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016103c0565b9350915081610b81565b505050939792965093509350565b6000808383604051602001610c94929190918252602082015260400190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052805160209091012054949350505050565b60007fe4a77bbc000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831601610d2657506001919050565b6102cb82611283565b6000604051828482376000808483898b8af1979650505050505050565b60603d604051915060208201818101604052818352816000823e505090565b8315610d7957805160208201fd5b827fab46c69f7f32e1bf09b0725853da82a211e5402a0600296ab499a2fb5ea3b4198383604051610dab929190612071565b60405180910390a250505050565b60008060005b8381101561124657600181019085013560f81c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8101610e6057601582019186013560f881901c9060581c73ffffffffffffffffffffffffffffffffffffffff81169074ff000000000000000000000000000000000000000016811785610e465780610e55565b60008681526020829052604090205b955050505050610dbf565b80610ef65760018201918681013560f81c906043016000610e8c8a610e8784888c8e61200d565b61136d565b60ff841697909701969194508491905060a083901b74ff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff82161786610edb5780610eea565b60008781526020829052604090205b96505050505050610dbf565b6002810361101e576000808784013560f881901c9060581c73ffffffffffffffffffffffffffffffffffffffff16601586019550909250905060008885013560e81c600386018162ffffff169150809650819250505060008186019050610f6f8b848c8c8a908692610f6a9392919061200d565b611630565b610fb7578a83610f8183898d8f61200d565b6040517f9a9462320000000000000000000000000000000000000000000000000000000081526004016103c0949392919061208a565b60ff8416979097019694508460a084901b74ff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff841617876110025780611011565b60008881526020829052604090205b9750505050505050610dbf565b60038103611051576020820191860135836110395780611048565b60008481526020829052604090205b93505050610dbf565b6004810361109d576003808301928781013560e81c919082010160008061107e8b610a2485898d8f61200d565b60009889526020526040909720969097019650909350610dbf92505050565b600681036111a55760008287013560f81c60018401935060ff16905060008784013560f01c60028501945061ffff16905060008885013560e81c600386018162ffffff16915080965081925050506000818601905060008061110b8d8d8d8b908792610a249392919061200d565b9398508893909250905084821061112157988501985b604080517f53657175656e6365206e657374656420636f6e6669673a0a0000000000000000602080830191909152603882018490526058820188905260788083018a90528351808403909101815260989092019092528051910120896111875780611196565b60008a81526020829052604090205b99505050505050505050610dbf565b600581036112115760208201918601358781036111e0577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff94505b60006111eb82611817565b9050846111f85780611207565b60008581526020829052604090205b9450505050610dbf565b6040517fb2505f7c000000000000000000000000000000000000000000000000000000008152600481018290526024016103c0565b50935093915050565b7f8713a7c4465f6fbee2b6e9d6646d1d9f83fec929edfc4baf661f3c865bdd04d160009081526020829052604081206102cb565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fac6a444e00000000000000000000000000000000000000000000000000000000148061131657507fffffffff0000000000000000000000000000000000000000000000000000000082167f36e7817500000000000000000000000000000000000000000000000000000000145b1561132357506001919050565b7f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316146102cb565b6000604282146113ad5782826040517f2ee17a3d0000000000000000000000000000000000000000000000000000000081526004016103c09291906120ca565b60006113c66113bd6001856120de565b85013560f81c90565b60ff169050604084013560f81c843560208601357f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a081111561143a578686826040517fad4aac760000000000000000000000000000000000000000000000000000000081526004016103c0939291906120f1565b8260ff16601b1415801561145257508260ff16601c14155b1561148f578686846040517fe578897e0000000000000000000000000000000000000000000000000000000081526004016103c093929190612115565b600184036114fc576040805160008152602081018083528a905260ff851691810191909152606081018390526080810182905260019060a0015b6020604051602081039080840390855afa1580156114eb573d6000803e3d6000fd5b5050506020604051035194506115d4565b60028403611599576040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101899052600190605c01604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600084529083018083525260ff861690820152606081018490526080810183905260a0016114c9565b86868560016040517f9dfba8520000000000000000000000000000000000000000000000000000000081526004016103c0949392919061213c565b73ffffffffffffffffffffffffffffffffffffffff85166116255786866040517f6c1719d20000000000000000000000000000000000000000000000000000000081526004016103c09291906120ca565b505050509392505050565b600081810361166b576040517fac241e1100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000838361167a6001826120de565b81811061168957611689611e27565b919091013560f81c91505060018114806116a35750600281145b156116e8578473ffffffffffffffffffffffffffffffffffffffff166116ca87868661136d565b73ffffffffffffffffffffffffffffffffffffffff1614915061180e565b600381036117d35773ffffffffffffffffffffffffffffffffffffffff8516631626ba7e878660008761171c6001826120de565b926117299392919061200d565b6040518463ffffffff1660e01b815260040161174793929190612168565b602060405180830381865afa158015611764573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611788919061218b565b7fffffffff00000000000000000000000000000000000000000000000000000000167f1626ba7e0000000000000000000000000000000000000000000000000000000014915061180e565b83838260006040517f9dfba8520000000000000000000000000000000000000000000000000000000081526004016103c0949392919061213c565b50949350505050565b6040517f53657175656e636520737461746963206469676573743a0a0000000000000000602082015260388101829052600090605801610864565b7fffffffff00000000000000000000000000000000000000000000000000000000811681146103d257600080fd5b60006020828403121561189257600080fd5b813561031781611852565b60008083601f8401126118af57600080fd5b50813567ffffffffffffffff8111156118c757600080fd5b6020830191508360208285010111156118df57600080fd5b9250929050565b6000806000604084860312156118fb57600080fd5b83359250602084013567ffffffffffffffff81111561191957600080fd5b6119258682870161189d565b9497909650939450505050565b6000806000806040858703121561194857600080fd5b843567ffffffffffffffff8082111561196057600080fd5b61196c8883890161189d565b9096509450602087013591508082111561198557600080fd5b506119928782880161189d565b95989497509550505050565b6000602082840312156119b057600080fd5b5035919050565b60008083601f8401126119c957600080fd5b50813567ffffffffffffffff8111156119e157600080fd5b6020830191508360208260051b85010111156118df57600080fd5b60008060208385031215611a0f57600080fd5b823567ffffffffffffffff811115611a2657600080fd5b611a32858286016119b7565b90969095509350505050565b600080600080600060608688031215611a5657600080fd5b853567ffffffffffffffff80821115611a6e57600080fd5b611a7a89838a016119b7565b9097509550602088013594506040880135915080821115611a9a57600080fd5b50611aa78882890161189d565b969995985093965092949392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215611af957600080fd5b813567ffffffffffffffff80821115611b1157600080fd5b818401915084601f830112611b2557600080fd5b813581811115611b3757611b37611ab8565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715611b7d57611b7d611ab8565b81604052828152876020848701011115611b9657600080fd5b826020860160208301376000928101602001929092525095945050505050565b8183823760009101908152919050565b80358015158114611bd657600080fd5b919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611bd657600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b81835260006020808501808196508560051b810191508460005b87811015611d8a57828403895281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff41883603018112611ca157600080fd5b870160c0611cae82611bc6565b15158652611cbd878301611bc6565b15158688015260408281013590870152606073ffffffffffffffffffffffffffffffffffffffff611cef828501611bdb565b16908701526080828101359087015260a080830135368490037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1018112611d3557600080fd5b90920187810192903567ffffffffffffffff811115611d5357600080fd5b803603841315611d6257600080fd5b8282890152611d748389018286611bff565b9c89019c97505050928601925050600101611c62565b5091979650505050505050565b60408152600560408201527f73656c663a000000000000000000000000000000000000000000000000000000606082015260806020820152600061037b608083018486611c48565b60408152600660408201527f67756573743a0000000000000000000000000000000000000000000000000000606082015260806020820152600061037b608083018486611c48565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000815180845260005b81811015611e7c57602081850181015186830182015201611e60565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006103176020830184611e56565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff41833603018112611f0157600080fd5b9190910192915050565b600060208284031215611f1d57600080fd5b61031782611bc6565b600060208284031215611f3857600080fd5b61031782611bdb565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611f7657600080fd5b83018035915067ffffffffffffffff821115611f9157600080fd5b6020019150368190038213156118df57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361200657612006611fa6565b5060010190565b6000808585111561201d57600080fd5b8386111561202a57600080fd5b5050820193919092039150565b808201808211156102cb576102cb611fa6565b60608152600061205e606083018688611bff565b6020830194909452506040015292915050565b82815260406020820152600061037b6040830184611e56565b84815273ffffffffffffffffffffffffffffffffffffffff841660208201526060604082015260006120c0606083018486611bff565b9695505050505050565b60208152600061037b602083018486611bff565b818103818111156102cb576102cb611fa6565b604081526000612105604083018587611bff565b9050826020830152949350505050565b604081526000612129604083018587611bff565b905060ff83166020830152949350505050565b606081526000612150606083018688611bff565b60208301949094525090151560409091015292915050565b838152604060208201526000612182604083018486611bff565b95945050505050565b60006020828403121561219d57600080fd5b81516103178161185256fea26469706673582212209bb95d18e97f278aa47e0c04c20d5a6af9bdb6d473c6d4051192cd96fc17866864736f6c63430008120033", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0xBC JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x61C2926C GT PUSH2 0x74 JUMPI DUP1 PUSH4 0x8C3F5563 GT PUSH2 0x4E JUMPI DUP1 PUSH4 0x8C3F5563 EQ PUSH2 0x253 JUMPI DUP1 PUSH4 0x90042BAF EQ PUSH2 0x273 JUMPI DUP1 PUSH4 0xAFFED0E0 EQ PUSH2 0x2AB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x61C2926C EQ PUSH2 0x1CB JUMPI DUP1 PUSH4 0x7A9A1628 EQ PUSH2 0x1EB JUMPI DUP1 PUSH4 0x853C5068 EQ PUSH2 0x20B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x20C13B0B GT PUSH2 0xA5 JUMPI DUP1 PUSH4 0x20C13B0B EQ PUSH2 0x147 JUMPI DUP1 PUSH4 0x29561426 EQ PUSH2 0x167 JUMPI DUP1 PUSH4 0x57C56D6B EQ PUSH2 0x189 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x1FFC9A7 EQ PUSH2 0xC1 JUMPI DUP1 PUSH4 0x1626BA7E EQ PUSH2 0xF6 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xCD JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xE1 PUSH2 0xDC CALLDATASIZE PUSH1 0x4 PUSH2 0x1880 JUMP JUMPDEST PUSH2 0x2C0 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x102 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x116 PUSH2 0x111 CALLDATASIZE PUSH1 0x4 PUSH2 0x18E6 JUMP JUMPDEST PUSH2 0x2D1 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xED JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x153 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x116 PUSH2 0x162 CALLDATASIZE PUSH1 0x4 PUSH2 0x1932 JUMP JUMPDEST PUSH2 0x31E JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x173 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x187 PUSH2 0x182 CALLDATASIZE PUSH1 0x4 PUSH2 0x199E JUMP JUMPDEST PUSH2 0x383 JUMP JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x195 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1BD PUSH32 0x8713A7C4465F6FBEE2B6E9D6646D1D9F83FEC929EDFC4BAF661F3C865BDD04D1 DUP2 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xED JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1D7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x187 PUSH2 0x1E6 CALLDATASIZE PUSH1 0x4 PUSH2 0x19FC JUMP JUMPDEST PUSH2 0x3D5 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1F7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x187 PUSH2 0x206 CALLDATASIZE PUSH1 0x4 PUSH2 0x1A3E JUMP JUMPDEST PUSH2 0x41A JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x217 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x22B PUSH2 0x226 CALLDATASIZE PUSH1 0x4 PUSH2 0x18E6 JUMP JUMPDEST PUSH2 0x447 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP6 DUP7 MSTORE PUSH1 0x20 DUP7 ADD SWAP5 SWAP1 SWAP5 MSTORE SWAP3 DUP5 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x60 DUP4 ADD MSTORE PUSH1 0x80 DUP3 ADD MSTORE PUSH1 0xA0 ADD PUSH2 0xED JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x25F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1BD PUSH2 0x26E CALLDATASIZE PUSH1 0x4 PUSH2 0x199E JUMP JUMPDEST PUSH2 0x60F JUMP JUMPDEST PUSH2 0x286 PUSH2 0x281 CALLDATASIZE PUSH1 0x4 PUSH2 0x1AE7 JUMP JUMPDEST PUSH2 0x63B JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xED JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2B7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1BD PUSH2 0x725 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x2CB DUP3 PUSH2 0x736 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH2 0x2DF DUP6 DUP6 DUP6 PUSH2 0x792 JUMP JUMPDEST POP SWAP1 POP DUP1 ISZERO PUSH2 0x311 JUMPI POP PUSH32 0x1626BA7E00000000000000000000000000000000000000000000000000000000 SWAP1 POP PUSH2 0x317 JUMP JUMPDEST POP PUSH1 0x0 SWAP1 POP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH2 0x343 DUP7 DUP7 PUSH1 0x40 MLOAD PUSH2 0x334 SWAP3 SWAP2 SWAP1 PUSH2 0x1BB6 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 KECCAK256 DUP6 DUP6 PUSH2 0x792 JUMP JUMPDEST POP SWAP1 POP DUP1 ISZERO PUSH2 0x375 JUMPI POP PUSH32 0x20C13B0B00000000000000000000000000000000000000000000000000000000 SWAP1 POP PUSH2 0x37B JUMP JUMPDEST POP PUSH1 0x0 SWAP1 POP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST CALLER ADDRESS EQ PUSH2 0x3C9 JUMPI PUSH1 0x40 MLOAD PUSH32 0xE125889400000000000000000000000000000000000000000000000000000000 DUP2 MSTORE CALLER PUSH1 0x4 DUP3 ADD MSTORE ADDRESS PUSH1 0x24 DUP3 ADD MSTORE PUSH1 0x44 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH2 0x3D2 DUP2 PUSH2 0x7CA JUMP JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x408 DUP4 DUP4 PUSH1 0x40 MLOAD PUSH1 0x20 ADD PUSH2 0x3ED SWAP3 SWAP2 SWAP1 PUSH2 0x1D97 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE DUP1 MLOAD SWAP1 PUSH1 0x20 ADD KECCAK256 PUSH2 0x7FC JUMP JUMPDEST SWAP1 POP PUSH2 0x415 DUP2 DUP5 DUP5 PUSH2 0x881 JUMP JUMPDEST POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x432 DUP7 DUP7 PUSH1 0x40 MLOAD PUSH1 0x20 ADD PUSH2 0x3ED SWAP3 SWAP2 SWAP1 PUSH2 0x1DDF JUMP JUMPDEST SWAP1 POP PUSH2 0x43F DUP2 DUP8 DUP8 PUSH2 0x881 JUMP JUMPDEST POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 DUP8 DUP8 PUSH1 0x0 DUP2 DUP2 LT PUSH2 0x463 JUMPI PUSH2 0x463 PUSH2 0x1E27 JUMP JUMPDEST SWAP1 SWAP2 ADD CALLDATALOAD PUSH32 0xFF00000000000000000000000000000000000000000000000000000000000000 AND SWAP2 POP DUP2 SWAP1 POP PUSH2 0x4B9 JUMPI PUSH2 0x49B DUP10 PUSH2 0x7FC JUMP JUMPDEST SWAP3 POP PUSH2 0x4A8 DUP4 DUP10 DUP10 PUSH2 0xA0E JUMP JUMPDEST SWAP3 SWAP9 POP SWAP1 SWAP7 POP SWAP5 POP SWAP2 POP PUSH2 0x604 SWAP1 POP JUMP JUMPDEST PUSH32 0xFF00000000000000000000000000000000000000000000000000000000000000 DUP2 DUP2 AND ADD PUSH2 0x4F8 JUMPI PUSH2 0x4EB DUP10 PUSH2 0x7FC JUMP JUMPDEST SWAP3 POP PUSH2 0x4A8 DUP4 DUP10 DUP10 PUSH2 0xA5F JUMP JUMPDEST PUSH32 0xFE00000000000000000000000000000000000000000000000000000000000000 PUSH32 0xFF00000000000000000000000000000000000000000000000000000000000000 DUP3 AND ADD PUSH2 0x54A JUMPI PUSH2 0x4EB DUP10 PUSH2 0xA8B JUMP JUMPDEST PUSH32 0xFD00000000000000000000000000000000000000000000000000000000000000 PUSH32 0xFF00000000000000000000000000000000000000000000000000000000000000 DUP3 AND ADD PUSH2 0x5AE JUMPI PUSH2 0x59E DUP10 DUP10 DUP10 PUSH2 0xAF8 JUMP JUMPDEST SWAP6 POP SWAP6 POP SWAP6 POP SWAP6 POP SWAP6 POP POP PUSH2 0x604 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x6085CD8200000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH32 0xFF00000000000000000000000000000000000000000000000000000000000000 DUP3 AND PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x24 ADD PUSH2 0x3C0 JUMP JUMPDEST SWAP4 SWAP8 SWAP3 SWAP7 POP SWAP4 POP SWAP4 POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x2CB PUSH32 0x8D0BF1FD623D628C741362C1289948E57B3E2905218C676D3E69ABEE36D6AE2E DUP4 PUSH2 0xC75 JUMP JUMPDEST PUSH1 0x0 CALLER ADDRESS EQ PUSH2 0x67E JUMPI PUSH1 0x40 MLOAD PUSH32 0xE125889400000000000000000000000000000000000000000000000000000000 DUP2 MSTORE CALLER PUSH1 0x4 DUP3 ADD MSTORE ADDRESS PUSH1 0x24 DUP3 ADD MSTORE PUSH1 0x44 ADD PUSH2 0x3C0 JUMP JUMPDEST DUP2 MLOAD PUSH1 0x20 DUP4 ADD CALLVALUE CREATE SWAP1 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND PUSH2 0x6D7 JUMPI DUP2 PUSH1 0x40 MLOAD PUSH32 0xD25719100000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP2 SWAP1 PUSH2 0x1EBA JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 AND DUP2 MSTORE PUSH32 0xA506AD4E7F05ECEBA62A023C3219E5BD98A615F4FA87E2AFB08A2DA5CF62BF0C SWAP1 PUSH1 0x20 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x731 PUSH1 0x0 PUSH2 0x60F JUMP JUMPDEST SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH32 0x6FFBD45100000000000000000000000000000000000000000000000000000000 PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP4 AND ADD PUSH2 0x789 JUMPI POP PUSH1 0x1 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH2 0x2CB DUP3 PUSH2 0xCD3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x7A5 DUP9 DUP9 DUP9 PUSH2 0x447 JUMP JUMPDEST POP SWAP7 POP SWAP2 SWAP5 POP SWAP3 POP SWAP1 POP DUP3 DUP3 LT DUP1 ISZERO SWAP1 PUSH2 0x7BD JUMPI POP PUSH1 0x1 JUMPDEST SWAP5 POP POP POP POP SWAP4 POP SWAP4 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0xA038794000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x1901000000000000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE CHAINID PUSH1 0x22 DUP3 ADD MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000 ADDRESS PUSH1 0x60 SHL AND PUSH1 0x42 DUP3 ADD MSTORE PUSH1 0x56 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x0 SWAP1 PUSH1 0x76 ADD JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE DUP1 MLOAD SWAP1 PUSH1 0x20 ADD KECCAK256 SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST DUP1 PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0xA07 JUMPI CALLDATASIZE DUP5 DUP5 DUP4 DUP2 DUP2 LT PUSH2 0x8A0 JUMPI PUSH2 0x8A0 PUSH2 0x1E27 JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL DUP2 ADD SWAP1 PUSH2 0x8B2 SWAP2 SWAP1 PUSH2 0x1ECD JUMP JUMPDEST SWAP1 POP PUSH2 0x8C1 PUSH1 0x20 DUP3 ADD DUP3 PUSH2 0x1F0B JUMP JUMPDEST ISZERO PUSH2 0x8FB JUMPI PUSH1 0x40 MLOAD PUSH32 0x230D1CCC00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 DUP2 ADD DUP4 SWAP1 MSTORE PUSH1 0x24 ADD PUSH2 0x3C0 JUMP JUMPDEST PUSH1 0x40 DUP2 ADD CALLDATALOAD DUP1 GAS LT ISZERO PUSH2 0x94E JUMPI DUP3 DUP2 GAS PUSH1 0x40 MLOAD PUSH32 0x2BB3E3BA00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 DUP2 ADD SWAP4 SWAP1 SWAP4 MSTORE PUSH1 0x24 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 ADD PUSH2 0x3C0 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x988 PUSH2 0x963 PUSH1 0x80 DUP6 ADD PUSH1 0x60 DUP7 ADD PUSH2 0x1F26 JUMP JUMPDEST PUSH1 0x80 DUP6 ADD CALLDATALOAD DUP5 ISZERO PUSH2 0x974 JUMPI DUP5 PUSH2 0x976 JUMP JUMPDEST GAS JUMPDEST PUSH2 0x983 PUSH1 0xA0 DUP9 ADD DUP9 PUSH2 0x1F41 JUMP JUMPDEST PUSH2 0xD2F JUMP JUMPDEST SWAP1 POP DUP1 ISZERO PUSH2 0x9CF JUMPI DUP8 PUSH32 0x5C4EEB02DABF8976016AB414D617F9A162936DCACE3CDEF8C69EF6E262AD5AE7 DUP6 PUSH1 0x40 MLOAD PUSH2 0x9C2 SWAP2 DUP2 MSTORE PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG2 PUSH2 0x9F1 JUMP JUMPDEST PUSH2 0x9F1 PUSH2 0x9E2 PUSH1 0x40 DUP6 ADD PUSH1 0x20 DUP7 ADD PUSH2 0x1F0B JUMP JUMPDEST DUP10 DUP7 PUSH2 0x9EC PUSH2 0xD4C JUMP JUMPDEST PUSH2 0xD6B JUMP JUMPDEST POP POP POP DUP1 DUP1 PUSH2 0x9FF SWAP1 PUSH2 0x1FD5 JUMP JUMPDEST SWAP2 POP POP PUSH2 0x885 JUMP JUMPDEST POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP1 DUP1 PUSH2 0xA29 DUP8 PUSH2 0xA24 DUP8 PUSH1 0x6 DUP2 DUP12 PUSH2 0x200D JUMP JUMPDEST PUSH2 0xDB9 JUMP JUMPDEST PUSH1 0x0 SWAP1 DUP2 MSTORE DUP8 CALLDATALOAD PUSH1 0xF0 SHR PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 DUP5 MSTORE PUSH1 0x2 SWAP1 SWAP11 ADD CALLDATALOAD PUSH1 0xE0 SHR SWAP1 DUP2 SWAP1 MSTORE SWAP9 SWAP1 SWAP2 KECCAK256 SWAP1 SWAP10 SWAP2 SWAP9 POP SWAP7 SWAP6 POP SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP1 DUP1 PUSH2 0xA7A DUP8 PUSH2 0xA75 DUP8 PUSH1 0x1 DUP2 DUP12 PUSH2 0x200D JUMP JUMPDEST PUSH2 0xA0E JUMP JUMPDEST SWAP4 POP SWAP4 POP SWAP4 POP SWAP4 POP SWAP4 POP SWAP4 POP SWAP4 POP SWAP4 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x1901000000000000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x0 PUSH1 0x22 DUP3 ADD DUP2 SWAP1 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000 ADDRESS PUSH1 0x60 SHL AND PUSH1 0x42 DUP4 ADD MSTORE PUSH1 0x56 DUP3 ADD DUP4 SWAP1 MSTORE SWAP1 PUSH1 0x76 ADD PUSH2 0x864 JUMP JUMPDEST PUSH1 0x0 DUP1 DUP1 DUP1 DUP1 PUSH1 0x4 PUSH1 0x1 DUP9 ADD CALLDATALOAD PUSH1 0xE8 SHR DUP3 PUSH2 0xB13 DUP4 DUP4 PUSH2 0x2037 JUMP JUMPDEST SWAP1 POP PUSH2 0xB25 DUP12 PUSH2 0x226 DUP4 DUP7 DUP14 DUP16 PUSH2 0x200D JUMP JUMPDEST SWAP4 SWAP12 POP SWAP2 SWAP10 POP SWAP8 POP SWAP6 POP SWAP4 POP DUP8 DUP8 LT ISZERO PUSH2 0xB7D JUMPI PUSH2 0xB45 DUP2 DUP5 DUP12 DUP14 PUSH2 0x200D JUMP JUMPDEST DUP10 DUP10 PUSH1 0x40 MLOAD PUSH32 0xB006ABA000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x204A JUMP JUMPDEST DUP1 SWAP3 POP JUMPDEST DUP9 DUP4 LT ISZERO PUSH2 0xC67 JUMPI PUSH1 0x3 DUP4 ADD SWAP3 DUP11 ADD CALLDATALOAD PUSH1 0xE8 SHR SWAP2 POP PUSH2 0xBA0 DUP4 DUP4 PUSH2 0x2037 JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0xBC2 PUSH2 0xBB0 DUP9 PUSH2 0x124F JUMP JUMPDEST DUP13 DUP13 DUP8 SWAP1 DUP7 SWAP3 PUSH2 0x226 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x200D JUMP JUMPDEST SWAP4 SWAP13 POP SWAP2 SWAP11 POP SWAP9 POP SWAP1 SWAP2 POP POP DUP9 DUP9 LT ISZERO PUSH2 0xC1A JUMPI PUSH2 0xBE2 DUP3 DUP6 DUP13 DUP15 PUSH2 0x200D JUMP JUMPDEST DUP11 DUP11 PUSH1 0x40 MLOAD PUSH32 0xB006ABA000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x204A JUMP JUMPDEST DUP5 DUP2 LT PUSH2 0xC5D JUMPI PUSH1 0x40 MLOAD PUSH32 0x37DAF62B00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x24 DUP2 ADD DUP7 SWAP1 MSTORE PUSH1 0x44 ADD PUSH2 0x3C0 JUMP JUMPDEST SWAP4 POP SWAP2 POP DUP2 PUSH2 0xB81 JUMP JUMPDEST POP POP POP SWAP4 SWAP8 SWAP3 SWAP7 POP SWAP4 POP SWAP4 POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 DUP4 PUSH1 0x40 MLOAD PUSH1 0x20 ADD PUSH2 0xC94 SWAP3 SWAP2 SWAP1 SWAP2 DUP3 MSTORE PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP2 DUP5 SUB ADD DUP2 MSTORE SWAP2 SWAP1 MSTORE DUP1 MLOAD PUSH1 0x20 SWAP1 SWAP2 ADD KECCAK256 SLOAD SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH32 0xE4A77BBC00000000000000000000000000000000000000000000000000000000 PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP4 AND ADD PUSH2 0xD26 JUMPI POP PUSH1 0x1 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH2 0x2CB DUP3 PUSH2 0x1283 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 MLOAD DUP3 DUP5 DUP3 CALLDATACOPY PUSH1 0x0 DUP1 DUP5 DUP4 DUP10 DUP12 DUP11 CALL SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x60 RETURNDATASIZE PUSH1 0x40 MLOAD SWAP2 POP PUSH1 0x20 DUP3 ADD DUP2 DUP2 ADD PUSH1 0x40 MSTORE DUP2 DUP4 MSTORE DUP2 PUSH1 0x0 DUP3 RETURNDATACOPY POP POP SWAP1 JUMP JUMPDEST DUP4 ISZERO PUSH2 0xD79 JUMPI DUP1 MLOAD PUSH1 0x20 DUP3 ADD REVERT JUMPDEST DUP3 PUSH32 0xAB46C69F7F32E1BF09B0725853DA82A211E5402A0600296AB499A2FB5EA3B419 DUP4 DUP4 PUSH1 0x40 MLOAD PUSH2 0xDAB SWAP3 SWAP2 SWAP1 PUSH2 0x2071 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG2 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x1246 JUMPI PUSH1 0x1 DUP2 ADD SWAP1 DUP6 ADD CALLDATALOAD PUSH1 0xF8 SHR PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 ADD PUSH2 0xE60 JUMPI PUSH1 0x15 DUP3 ADD SWAP2 DUP7 ADD CALLDATALOAD PUSH1 0xF8 DUP2 SWAP1 SHR SWAP1 PUSH1 0x58 SHR PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND SWAP1 PUSH21 0xFF0000000000000000000000000000000000000000 AND DUP2 OR DUP6 PUSH2 0xE46 JUMPI DUP1 PUSH2 0xE55 JUMP JUMPDEST PUSH1 0x0 DUP7 DUP2 MSTORE PUSH1 0x20 DUP3 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 JUMPDEST SWAP6 POP POP POP POP POP PUSH2 0xDBF JUMP JUMPDEST DUP1 PUSH2 0xEF6 JUMPI PUSH1 0x1 DUP3 ADD SWAP2 DUP7 DUP2 ADD CALLDATALOAD PUSH1 0xF8 SHR SWAP1 PUSH1 0x43 ADD PUSH1 0x0 PUSH2 0xE8C DUP11 PUSH2 0xE87 DUP5 DUP9 DUP13 DUP15 PUSH2 0x200D JUMP JUMPDEST PUSH2 0x136D JUMP JUMPDEST PUSH1 0xFF DUP5 AND SWAP8 SWAP1 SWAP8 ADD SWAP7 SWAP2 SWAP5 POP DUP5 SWAP2 SWAP1 POP PUSH1 0xA0 DUP4 SWAP1 SHL PUSH21 0xFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 AND OR DUP7 PUSH2 0xEDB JUMPI DUP1 PUSH2 0xEEA JUMP JUMPDEST PUSH1 0x0 DUP8 DUP2 MSTORE PUSH1 0x20 DUP3 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 JUMPDEST SWAP7 POP POP POP POP POP POP PUSH2 0xDBF JUMP JUMPDEST PUSH1 0x2 DUP2 SUB PUSH2 0x101E JUMPI PUSH1 0x0 DUP1 DUP8 DUP5 ADD CALLDATALOAD PUSH1 0xF8 DUP2 SWAP1 SHR SWAP1 PUSH1 0x58 SHR PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x15 DUP7 ADD SWAP6 POP SWAP1 SWAP3 POP SWAP1 POP PUSH1 0x0 DUP9 DUP6 ADD CALLDATALOAD PUSH1 0xE8 SHR PUSH1 0x3 DUP7 ADD DUP2 PUSH3 0xFFFFFF AND SWAP2 POP DUP1 SWAP7 POP DUP2 SWAP3 POP POP POP PUSH1 0x0 DUP2 DUP7 ADD SWAP1 POP PUSH2 0xF6F DUP12 DUP5 DUP13 DUP13 DUP11 SWAP1 DUP7 SWAP3 PUSH2 0xF6A SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x200D JUMP JUMPDEST PUSH2 0x1630 JUMP JUMPDEST PUSH2 0xFB7 JUMPI DUP11 DUP4 PUSH2 0xF81 DUP4 DUP10 DUP14 DUP16 PUSH2 0x200D JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x9A94623200000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x208A JUMP JUMPDEST PUSH1 0xFF DUP5 AND SWAP8 SWAP1 SWAP8 ADD SWAP7 SWAP5 POP DUP5 PUSH1 0xA0 DUP5 SWAP1 SHL PUSH21 0xFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP5 AND OR DUP8 PUSH2 0x1002 JUMPI DUP1 PUSH2 0x1011 JUMP JUMPDEST PUSH1 0x0 DUP9 DUP2 MSTORE PUSH1 0x20 DUP3 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 JUMPDEST SWAP8 POP POP POP POP POP POP POP PUSH2 0xDBF JUMP JUMPDEST PUSH1 0x3 DUP2 SUB PUSH2 0x1051 JUMPI PUSH1 0x20 DUP3 ADD SWAP2 DUP7 ADD CALLDATALOAD DUP4 PUSH2 0x1039 JUMPI DUP1 PUSH2 0x1048 JUMP JUMPDEST PUSH1 0x0 DUP5 DUP2 MSTORE PUSH1 0x20 DUP3 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 JUMPDEST SWAP4 POP POP POP PUSH2 0xDBF JUMP JUMPDEST PUSH1 0x4 DUP2 SUB PUSH2 0x109D JUMPI PUSH1 0x3 DUP1 DUP4 ADD SWAP3 DUP8 DUP2 ADD CALLDATALOAD PUSH1 0xE8 SHR SWAP2 SWAP1 DUP3 ADD ADD PUSH1 0x0 DUP1 PUSH2 0x107E DUP12 PUSH2 0xA24 DUP6 DUP10 DUP14 DUP16 PUSH2 0x200D JUMP JUMPDEST PUSH1 0x0 SWAP9 DUP10 MSTORE PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 SWAP8 KECCAK256 SWAP7 SWAP1 SWAP8 ADD SWAP7 POP SWAP1 SWAP4 POP PUSH2 0xDBF SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x6 DUP2 SUB PUSH2 0x11A5 JUMPI PUSH1 0x0 DUP3 DUP8 ADD CALLDATALOAD PUSH1 0xF8 SHR PUSH1 0x1 DUP5 ADD SWAP4 POP PUSH1 0xFF AND SWAP1 POP PUSH1 0x0 DUP8 DUP5 ADD CALLDATALOAD PUSH1 0xF0 SHR PUSH1 0x2 DUP6 ADD SWAP5 POP PUSH2 0xFFFF AND SWAP1 POP PUSH1 0x0 DUP9 DUP6 ADD CALLDATALOAD PUSH1 0xE8 SHR PUSH1 0x3 DUP7 ADD DUP2 PUSH3 0xFFFFFF AND SWAP2 POP DUP1 SWAP7 POP DUP2 SWAP3 POP POP POP PUSH1 0x0 DUP2 DUP7 ADD SWAP1 POP PUSH1 0x0 DUP1 PUSH2 0x110B DUP14 DUP14 DUP14 DUP12 SWAP1 DUP8 SWAP3 PUSH2 0xA24 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x200D JUMP JUMPDEST SWAP4 SWAP9 POP DUP9 SWAP4 SWAP1 SWAP3 POP SWAP1 POP DUP5 DUP3 LT PUSH2 0x1121 JUMPI SWAP9 DUP6 ADD SWAP9 JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x53657175656E6365206E657374656420636F6E6669673A0A0000000000000000 PUSH1 0x20 DUP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x38 DUP3 ADD DUP5 SWAP1 MSTORE PUSH1 0x58 DUP3 ADD DUP9 SWAP1 MSTORE PUSH1 0x78 DUP1 DUP4 ADD DUP11 SWAP1 MSTORE DUP4 MLOAD DUP1 DUP5 SUB SWAP1 SWAP2 ADD DUP2 MSTORE PUSH1 0x98 SWAP1 SWAP3 ADD SWAP1 SWAP3 MSTORE DUP1 MLOAD SWAP2 ADD KECCAK256 DUP10 PUSH2 0x1187 JUMPI DUP1 PUSH2 0x1196 JUMP JUMPDEST PUSH1 0x0 DUP11 DUP2 MSTORE PUSH1 0x20 DUP3 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 JUMPDEST SWAP10 POP POP POP POP POP POP POP POP POP PUSH2 0xDBF JUMP JUMPDEST PUSH1 0x5 DUP2 SUB PUSH2 0x1211 JUMPI PUSH1 0x20 DUP3 ADD SWAP2 DUP7 ADD CALLDATALOAD DUP8 DUP2 SUB PUSH2 0x11E0 JUMPI PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP5 POP JUMPDEST PUSH1 0x0 PUSH2 0x11EB DUP3 PUSH2 0x1817 JUMP JUMPDEST SWAP1 POP DUP5 PUSH2 0x11F8 JUMPI DUP1 PUSH2 0x1207 JUMP JUMPDEST PUSH1 0x0 DUP6 DUP2 MSTORE PUSH1 0x20 DUP3 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 JUMPDEST SWAP5 POP POP POP POP PUSH2 0xDBF JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0xB2505F7C00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x24 ADD PUSH2 0x3C0 JUMP JUMPDEST POP SWAP4 POP SWAP4 SWAP2 POP POP JUMP JUMPDEST PUSH32 0x8713A7C4465F6FBEE2B6E9D6646D1D9F83FEC929EDFC4BAF661F3C865BDD04D1 PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x20 DUP3 SWAP1 MSTORE PUSH1 0x40 DUP2 KECCAK256 PUSH2 0x2CB JUMP JUMPDEST PUSH1 0x0 PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP3 AND PUSH32 0xAC6A444E00000000000000000000000000000000000000000000000000000000 EQ DUP1 PUSH2 0x1316 JUMPI POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP3 AND PUSH32 0x36E7817500000000000000000000000000000000000000000000000000000000 EQ JUMPDEST ISZERO PUSH2 0x1323 JUMPI POP PUSH1 0x1 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH32 0x1FFC9A700000000000000000000000000000000000000000000000000000000 PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP4 AND EQ PUSH2 0x2CB JUMP JUMPDEST PUSH1 0x0 PUSH1 0x42 DUP3 EQ PUSH2 0x13AD JUMPI DUP3 DUP3 PUSH1 0x40 MLOAD PUSH32 0x2EE17A3D00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP3 SWAP2 SWAP1 PUSH2 0x20CA JUMP JUMPDEST PUSH1 0x0 PUSH2 0x13C6 PUSH2 0x13BD PUSH1 0x1 DUP6 PUSH2 0x20DE JUMP JUMPDEST DUP6 ADD CALLDATALOAD PUSH1 0xF8 SHR SWAP1 JUMP JUMPDEST PUSH1 0xFF AND SWAP1 POP PUSH1 0x40 DUP5 ADD CALLDATALOAD PUSH1 0xF8 SHR DUP5 CALLDATALOAD PUSH1 0x20 DUP7 ADD CALLDATALOAD PUSH32 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 DUP2 GT ISZERO PUSH2 0x143A JUMPI DUP7 DUP7 DUP3 PUSH1 0x40 MLOAD PUSH32 0xAD4AAC7600000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x20F1 JUMP JUMPDEST DUP3 PUSH1 0xFF AND PUSH1 0x1B EQ ISZERO DUP1 ISZERO PUSH2 0x1452 JUMPI POP DUP3 PUSH1 0xFF AND PUSH1 0x1C EQ ISZERO JUMPDEST ISZERO PUSH2 0x148F JUMPI DUP7 DUP7 DUP5 PUSH1 0x40 MLOAD PUSH32 0xE578897E00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x2115 JUMP JUMPDEST PUSH1 0x1 DUP5 SUB PUSH2 0x14FC JUMPI PUSH1 0x40 DUP1 MLOAD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 DUP2 ADD DUP1 DUP4 MSTORE DUP11 SWAP1 MSTORE PUSH1 0xFF DUP6 AND SWAP2 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x60 DUP2 ADD DUP4 SWAP1 MSTORE PUSH1 0x80 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x1 SWAP1 PUSH1 0xA0 ADD JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 SUB SWAP1 DUP1 DUP5 SUB SWAP1 DUP6 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x14EB JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP PUSH1 0x20 PUSH1 0x40 MLOAD SUB MLOAD SWAP5 POP PUSH2 0x15D4 JUMP JUMPDEST PUSH1 0x2 DUP5 SUB PUSH2 0x1599 JUMPI PUSH1 0x40 MLOAD PUSH32 0x19457468657265756D205369676E6564204D6573736167653A0A333200000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x3C DUP2 ADD DUP10 SWAP1 MSTORE PUSH1 0x1 SWAP1 PUSH1 0x5C ADD PUSH1 0x40 DUP1 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP2 DUP5 SUB ADD DUP2 MSTORE DUP3 DUP3 MSTORE DUP1 MLOAD PUSH1 0x20 SWAP2 DUP3 ADD KECCAK256 PUSH1 0x0 DUP5 MSTORE SWAP1 DUP4 ADD DUP1 DUP4 MSTORE MSTORE PUSH1 0xFF DUP7 AND SWAP1 DUP3 ADD MSTORE PUSH1 0x60 DUP2 ADD DUP5 SWAP1 MSTORE PUSH1 0x80 DUP2 ADD DUP4 SWAP1 MSTORE PUSH1 0xA0 ADD PUSH2 0x14C9 JUMP JUMPDEST DUP7 DUP7 DUP6 PUSH1 0x1 PUSH1 0x40 MLOAD PUSH32 0x9DFBA85200000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x213C JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP6 AND PUSH2 0x1625 JUMPI DUP7 DUP7 PUSH1 0x40 MLOAD PUSH32 0x6C1719D200000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP3 SWAP2 SWAP1 PUSH2 0x20CA JUMP JUMPDEST POP POP POP POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 SUB PUSH2 0x166B JUMPI PUSH1 0x40 MLOAD PUSH32 0xAC241E1100000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 DUP4 DUP4 PUSH2 0x167A PUSH1 0x1 DUP3 PUSH2 0x20DE JUMP JUMPDEST DUP2 DUP2 LT PUSH2 0x1689 JUMPI PUSH2 0x1689 PUSH2 0x1E27 JUMP JUMPDEST SWAP2 SWAP1 SWAP2 ADD CALLDATALOAD PUSH1 0xF8 SHR SWAP2 POP POP PUSH1 0x1 DUP2 EQ DUP1 PUSH2 0x16A3 JUMPI POP PUSH1 0x2 DUP2 EQ JUMPDEST ISZERO PUSH2 0x16E8 JUMPI DUP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH2 0x16CA DUP8 DUP7 DUP7 PUSH2 0x136D JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ SWAP2 POP PUSH2 0x180E JUMP JUMPDEST PUSH1 0x3 DUP2 SUB PUSH2 0x17D3 JUMPI PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP6 AND PUSH4 0x1626BA7E DUP8 DUP7 PUSH1 0x0 DUP8 PUSH2 0x171C PUSH1 0x1 DUP3 PUSH2 0x20DE JUMP JUMPDEST SWAP3 PUSH2 0x1729 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x200D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP5 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x1747 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x2168 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x1764 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x1788 SWAP2 SWAP1 PUSH2 0x218B JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND PUSH32 0x1626BA7E00000000000000000000000000000000000000000000000000000000 EQ SWAP2 POP PUSH2 0x180E JUMP JUMPDEST DUP4 DUP4 DUP3 PUSH1 0x0 PUSH1 0x40 MLOAD PUSH32 0x9DFBA85200000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x213C JUMP JUMPDEST POP SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x53657175656E636520737461746963206469676573743A0A0000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x38 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x0 SWAP1 PUSH1 0x58 ADD PUSH2 0x864 JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND DUP2 EQ PUSH2 0x3D2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1892 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x317 DUP2 PUSH2 0x1852 JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 PUSH1 0x1F DUP5 ADD SLT PUSH2 0x18AF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x18C7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 DUP4 ADD SWAP2 POP DUP4 PUSH1 0x20 DUP3 DUP6 ADD ADD GT ISZERO PUSH2 0x18DF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x40 DUP5 DUP7 SUB SLT ISZERO PUSH2 0x18FB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 CALLDATALOAD SWAP3 POP PUSH1 0x20 DUP5 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x1919 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x1925 DUP7 DUP3 DUP8 ADD PUSH2 0x189D JUMP JUMPDEST SWAP5 SWAP8 SWAP1 SWAP7 POP SWAP4 SWAP5 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x40 DUP6 DUP8 SUB SLT ISZERO PUSH2 0x1948 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0x1960 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x196C DUP9 DUP4 DUP10 ADD PUSH2 0x189D JUMP JUMPDEST SWAP1 SWAP7 POP SWAP5 POP PUSH1 0x20 DUP8 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0x1985 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1992 DUP8 DUP3 DUP9 ADD PUSH2 0x189D JUMP JUMPDEST SWAP6 SWAP9 SWAP5 SWAP8 POP SWAP6 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x19B0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP CALLDATALOAD SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 PUSH1 0x1F DUP5 ADD SLT PUSH2 0x19C9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x19E1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 DUP4 ADD SWAP2 POP DUP4 PUSH1 0x20 DUP3 PUSH1 0x5 SHL DUP6 ADD ADD GT ISZERO PUSH2 0x18DF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x20 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x1A0F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x1A26 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x1A32 DUP6 DUP3 DUP7 ADD PUSH2 0x19B7 JUMP JUMPDEST SWAP1 SWAP7 SWAP1 SWAP6 POP SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP7 DUP9 SUB SLT ISZERO PUSH2 0x1A56 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP6 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0x1A6E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x1A7A DUP10 DUP4 DUP11 ADD PUSH2 0x19B7 JUMP JUMPDEST SWAP1 SWAP8 POP SWAP6 POP PUSH1 0x20 DUP9 ADD CALLDATALOAD SWAP5 POP PUSH1 0x40 DUP9 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0x1A9A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1AA7 DUP9 DUP3 DUP10 ADD PUSH2 0x189D JUMP JUMPDEST SWAP7 SWAP10 SWAP6 SWAP9 POP SWAP4 SWAP7 POP SWAP3 SWAP5 SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH32 0x4E487B7100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 MSTORE PUSH1 0x41 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1AF9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0x1B11 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 DUP5 ADD SWAP2 POP DUP5 PUSH1 0x1F DUP4 ADD SLT PUSH2 0x1B25 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD DUP2 DUP2 GT ISZERO PUSH2 0x1B37 JUMPI PUSH2 0x1B37 PUSH2 0x1AB8 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1F DUP3 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 DUP2 AND PUSH1 0x3F ADD AND DUP2 ADD SWAP1 DUP4 DUP3 GT DUP2 DUP4 LT OR ISZERO PUSH2 0x1B7D JUMPI PUSH2 0x1B7D PUSH2 0x1AB8 JUMP JUMPDEST DUP2 PUSH1 0x40 MSTORE DUP3 DUP2 MSTORE DUP8 PUSH1 0x20 DUP5 DUP8 ADD ADD GT ISZERO PUSH2 0x1B96 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP4 ADD CALLDATACOPY PUSH1 0x0 SWAP3 DUP2 ADD PUSH1 0x20 ADD SWAP3 SWAP1 SWAP3 MSTORE POP SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST DUP2 DUP4 DUP3 CALLDATACOPY PUSH1 0x0 SWAP2 ADD SWAP1 DUP2 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST DUP1 CALLDATALOAD DUP1 ISZERO ISZERO DUP2 EQ PUSH2 0x1BD6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP2 SWAP1 POP JUMP JUMPDEST DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND DUP2 EQ PUSH2 0x1BD6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 DUP4 MSTORE DUP2 DUP2 PUSH1 0x20 DUP6 ADD CALLDATACOPY POP PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 ADD ADD MSTORE PUSH1 0x0 PUSH1 0x20 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 PUSH1 0x1F DUP5 ADD AND DUP5 ADD ADD SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST DUP2 DUP4 MSTORE PUSH1 0x0 PUSH1 0x20 DUP1 DUP6 ADD DUP1 DUP2 SWAP7 POP DUP6 PUSH1 0x5 SHL DUP2 ADD SWAP2 POP DUP5 PUSH1 0x0 JUMPDEST DUP8 DUP2 LT ISZERO PUSH2 0x1D8A JUMPI DUP3 DUP5 SUB DUP10 MSTORE DUP2 CALLDATALOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 DUP9 CALLDATASIZE SUB ADD DUP2 SLT PUSH2 0x1CA1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP8 ADD PUSH1 0xC0 PUSH2 0x1CAE DUP3 PUSH2 0x1BC6 JUMP JUMPDEST ISZERO ISZERO DUP7 MSTORE PUSH2 0x1CBD DUP8 DUP4 ADD PUSH2 0x1BC6 JUMP JUMPDEST ISZERO ISZERO DUP7 DUP9 ADD MSTORE PUSH1 0x40 DUP3 DUP2 ADD CALLDATALOAD SWAP1 DUP8 ADD MSTORE PUSH1 0x60 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH2 0x1CEF DUP3 DUP6 ADD PUSH2 0x1BDB JUMP JUMPDEST AND SWAP1 DUP8 ADD MSTORE PUSH1 0x80 DUP3 DUP2 ADD CALLDATALOAD SWAP1 DUP8 ADD MSTORE PUSH1 0xA0 DUP1 DUP4 ADD CALLDATALOAD CALLDATASIZE DUP5 SWAP1 SUB PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 ADD DUP2 SLT PUSH2 0x1D35 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP1 SWAP3 ADD DUP8 DUP2 ADD SWAP3 SWAP1 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x1D53 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 CALLDATASIZE SUB DUP5 SGT ISZERO PUSH2 0x1D62 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 DUP3 DUP10 ADD MSTORE PUSH2 0x1D74 DUP4 DUP10 ADD DUP3 DUP7 PUSH2 0x1BFF JUMP JUMPDEST SWAP13 DUP10 ADD SWAP13 SWAP8 POP POP POP SWAP3 DUP7 ADD SWAP3 POP POP PUSH1 0x1 ADD PUSH2 0x1C62 JUMP JUMPDEST POP SWAP2 SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP2 MSTORE PUSH1 0x5 PUSH1 0x40 DUP3 ADD MSTORE PUSH32 0x73656C663A000000000000000000000000000000000000000000000000000000 PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x0 PUSH2 0x37B PUSH1 0x80 DUP4 ADD DUP5 DUP7 PUSH2 0x1C48 JUMP JUMPDEST PUSH1 0x40 DUP2 MSTORE PUSH1 0x6 PUSH1 0x40 DUP3 ADD MSTORE PUSH32 0x67756573743A0000000000000000000000000000000000000000000000000000 PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x0 PUSH2 0x37B PUSH1 0x80 DUP4 ADD DUP5 DUP7 PUSH2 0x1C48 JUMP JUMPDEST PUSH32 0x4E487B7100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 MSTORE PUSH1 0x32 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 DUP2 MLOAD DUP1 DUP5 MSTORE PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0x1E7C JUMPI PUSH1 0x20 DUP2 DUP6 ADD DUP2 ADD MLOAD DUP7 DUP4 ADD DUP3 ADD MSTORE ADD PUSH2 0x1E60 JUMP JUMPDEST POP PUSH1 0x0 PUSH1 0x20 DUP3 DUP7 ADD ADD MSTORE PUSH1 0x20 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 PUSH1 0x1F DUP4 ADD AND DUP6 ADD ADD SWAP2 POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x20 DUP2 MSTORE PUSH1 0x0 PUSH2 0x317 PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0x1E56 JUMP JUMPDEST PUSH1 0x0 DUP3 CALLDATALOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 DUP4 CALLDATASIZE SUB ADD DUP2 SLT PUSH2 0x1F01 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP2 SWAP1 SWAP2 ADD SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1F1D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x317 DUP3 PUSH2 0x1BC6 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1F38 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x317 DUP3 PUSH2 0x1BDB JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 CALLDATALOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 DUP5 CALLDATASIZE SUB ADD DUP2 SLT PUSH2 0x1F76 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 ADD DUP1 CALLDATALOAD SWAP2 POP PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x1F91 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 ADD SWAP2 POP CALLDATASIZE DUP2 SWAP1 SUB DUP3 SGT ISZERO PUSH2 0x18DF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH32 0x4E487B7100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 MSTORE PUSH1 0x11 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 SUB PUSH2 0x2006 JUMPI PUSH2 0x2006 PUSH2 0x1FA6 JUMP JUMPDEST POP PUSH1 0x1 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 DUP6 DUP6 GT ISZERO PUSH2 0x201D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 DUP7 GT ISZERO PUSH2 0x202A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP POP DUP3 ADD SWAP4 SWAP2 SWAP1 SWAP3 SUB SWAP2 POP JUMP JUMPDEST DUP1 DUP3 ADD DUP1 DUP3 GT ISZERO PUSH2 0x2CB JUMPI PUSH2 0x2CB PUSH2 0x1FA6 JUMP JUMPDEST PUSH1 0x60 DUP2 MSTORE PUSH1 0x0 PUSH2 0x205E PUSH1 0x60 DUP4 ADD DUP7 DUP9 PUSH2 0x1BFF JUMP JUMPDEST PUSH1 0x20 DUP4 ADD SWAP5 SWAP1 SWAP5 MSTORE POP PUSH1 0x40 ADD MSTORE SWAP3 SWAP2 POP POP JUMP JUMPDEST DUP3 DUP2 MSTORE PUSH1 0x40 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x0 PUSH2 0x37B PUSH1 0x40 DUP4 ADD DUP5 PUSH2 0x1E56 JUMP JUMPDEST DUP5 DUP2 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP5 AND PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x60 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x0 PUSH2 0x20C0 PUSH1 0x60 DUP4 ADD DUP5 DUP7 PUSH2 0x1BFF JUMP JUMPDEST SWAP7 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x20 DUP2 MSTORE PUSH1 0x0 PUSH2 0x37B PUSH1 0x20 DUP4 ADD DUP5 DUP7 PUSH2 0x1BFF JUMP JUMPDEST DUP2 DUP2 SUB DUP2 DUP2 GT ISZERO PUSH2 0x2CB JUMPI PUSH2 0x2CB PUSH2 0x1FA6 JUMP JUMPDEST PUSH1 0x40 DUP2 MSTORE PUSH1 0x0 PUSH2 0x2105 PUSH1 0x40 DUP4 ADD DUP6 DUP8 PUSH2 0x1BFF JUMP JUMPDEST SWAP1 POP DUP3 PUSH1 0x20 DUP4 ADD MSTORE SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP2 MSTORE PUSH1 0x0 PUSH2 0x2129 PUSH1 0x40 DUP4 ADD DUP6 DUP8 PUSH2 0x1BFF JUMP JUMPDEST SWAP1 POP PUSH1 0xFF DUP4 AND PUSH1 0x20 DUP4 ADD MSTORE SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x60 DUP2 MSTORE PUSH1 0x0 PUSH2 0x2150 PUSH1 0x60 DUP4 ADD DUP7 DUP9 PUSH2 0x1BFF JUMP JUMPDEST PUSH1 0x20 DUP4 ADD SWAP5 SWAP1 SWAP5 MSTORE POP SWAP1 ISZERO ISZERO PUSH1 0x40 SWAP1 SWAP2 ADD MSTORE SWAP3 SWAP2 POP POP JUMP JUMPDEST DUP4 DUP2 MSTORE PUSH1 0x40 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x0 PUSH2 0x2182 PUSH1 0x40 DUP4 ADD DUP5 DUP7 PUSH2 0x1BFF JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x219D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 MLOAD PUSH2 0x317 DUP2 PUSH2 0x1852 JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 SWAP12 0xB9 0x5D XOR 0xE9 PUSH32 0x278AA47E0C04C20D5A6AF9BDB6D473C6D4051192CD96FC17866864736F6C6343 STOP ADDMOD SLT STOP CALLER ", + "sourceMap": "640:2693:1:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3127:204;;;;;;;;;;-1:-1:-1;3127:204:1;;;;;:::i;:::-;;:::i;:::-;;;611:14:22;;604:22;586:41;;574:2;559:18;3127:204:1;;;;;;;;5489:316:2;;;;;;;;;;-1:-1:-1;5489:316:2;;;;;:::i;:::-;;:::i;:::-;;;1646:66:22;1634:79;;;1616:98;;1604:2;1589:18;5489:316:2;1472:248:22;4525:332:2;;;;;;;;;;-1:-1:-1;4525:332:2;;;;;:::i;:::-;;:::i;6456:119::-;;;;;;;;;;-1:-1:-1;6456:119:2;;;;;:::i;:::-;;:::i;:::-;;811:95:14;;;;;;;;;;;;862:44;811:95;;;;;2778:25:22;;;2766:2;2751:18;811:95:14;2632:177:22;1290:262:1;;;;;;;;;;-1:-1:-1;1290:262:1;;;;;:::i;:::-;;:::i;890:292::-;;;;;;;;;;-1:-1:-1;890:292:1;;;;;:::i;:::-;;:::i;1675:1486:2:-;;;;;;;;;;-1:-1:-1;1675:1486:2;;;;;:::i;:::-;;:::i;:::-;;;;4827:25:22;;;4883:2;4868:18;;4861:34;;;;4911:18;;;4904:34;;;;4969:2;4954:18;;4947:34;5012:3;4997:19;;4990:35;4814:3;4799:19;1675:1486:2;4568:463:22;938:156:6;;;;;;;;;;-1:-1:-1;938:156:6;;;;;:::i;:::-;;:::i;456:276:4:-;;;;;;:::i;:::-;;:::i;:::-;;;6753:42:22;6741:55;;;6723:74;;6711:2;6696:18;456:276:4;6577:226:22;670:87:6;;;;;;;;;;;;;:::i;3127:204:1:-;3270:4;3289:37;3313:12;3289:23;:37::i;:::-;3282:44;3127:204;-1:-1:-1;;3127:204:1:o;5489:316:2:-;5608:6;5650:12;5667:40;5688:5;5695:11;;5667:20;:40::i;:::-;5649:58;;;5717:7;5713:65;;;-1:-1:-1;5741:30:2;;-1:-1:-1;5734:37:2;;5713:65;-1:-1:-1;5798:1:2;;-1:-1:-1;5489:316:2;;;;;;:::o;4525:332::-;4651:6;4693:12;4710:51;4741:5;;4731:16;;;;;;;:::i;:::-;;;;;;;;4749:11;;4710:20;:51::i;:::-;4692:69;;;4771:7;4767:63;;;-1:-1:-1;4795:28:2;;-1:-1:-1;4788:35:2;;4767:63;-1:-1:-1;4850:1:2;;-1:-1:-1;4525:332:2;;;;;;;:::o;6456:119::-;178:10:8;200:4;178:27;174:94;;222:39;;;;;235:10;222:39;;;7319:34:22;255:4:8;7369:18:22;;;7362:43;7231:18;;222:39:8;;;;;;;;174:94;6542:28:2::1;6559:10;6542:16;:28::i;:::-;6456:119:::0;:::o;1290:262:1:-;1401:14;1418:63;1474:4;;1454:25;;;;;;;;;:::i;:::-;;;;;;;;;;;;;1444:36;;;;;;1418:25;:63::i;:::-;1401:80;;1520:27;1534:6;1542:4;;1520:13;:27::i;:::-;1364:188;1290:262;;:::o;890:292::-;1030:14;1047:64;1104:4;;1083:26;;;;;;;;;:::i;1047:64::-;1030:81;;1150:27;1164:6;1172:4;;1150:13;:27::i;:::-;993:189;890:292;;;;;:::o;1675:1486:2:-;1801:17;1824:14;1844:17;1867;1890:18;1919:20;1942:10;;1953:1;1942:13;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;1942:13:2;;-1:-1:-1;1962:303:2;;2057:34;2083:7;2057:25;:34::i;:::-;2045:46;;2144;2168:9;2179:10;;2144:23;:46::i;:::-;2099:91;;-1:-1:-1;2099:91:2;;-1:-1:-1;2099:91:2;-1:-1:-1;2099:91:2;-1:-1:-1;2198:60:2;;-1:-1:-1;2198:60:2;1962:303;2275:29;;;;;2271:310;;2370:34;2396:7;2370:25;:34::i;:::-;2358:46;;2457:49;2484:9;2495:10;;2457:26;:49::i;2271:310::-;2591:33;;;;;2587:319;;2690:39;2721:7;2690:30;:39::i;2587:319::-;2916:29;;;;;2912:196;;3066:35;3081:7;3090:10;;3066:14;:35::i;:::-;3059:42;;;;;;;;;;;;;2912:196;3121:35;;;;;11707:66:22;11695:79;;3121:35:2;;;11677:98:22;11650:18;;3121:35:2;11533:248:22;1675:1486:2;;;;;;;;;;:::o;938:156:6:-;1002:7;1032:56;453:66;1080:6;1032:28;:56::i;456:276:4:-;550:12;178:10:8;200:4;178:27;174:94;;222:39;;;;;235:10;222:39;;;7319:34:22;255:4:8;7369:18:22;;;7362:43;7231:18;;222:39:8;7084:327:22;174:94:8;631:5:4::1;625:12;620:2;613:5;609:14;596:11;589:49;581:57:::0;-1:-1:-1;649:18:4::1;::::0;::::1;645:50;;689:5;676:19;;;;;;;;;;;:::i;645:50::-;706:21;::::0;6753:42:22;6741:55;;6723:74;;706:21:4::1;::::0;6711:2:22;6696:18;706:21:4::1;;;;;;;456:276:::0;;;:::o;670:87:6:-;718:7;740:12;750:1;740:9;:12::i;:::-;733:19;;670:87;:::o;942:233:4:-;1028:4;1044:48;;;;;1040:80;;-1:-1:-1;1109:4:4;;942:233;-1:-1:-1;942:233:4:o;1040:80::-;1133:37;1157:12;1133:23;:37::i;3480:386:2:-;3611:12;3629:17;3657;3676:14;3692:17;3760:38;3778:7;3787:10;;3760:17;:38::i;:::-;-1:-1:-1;3715:83:2;-1:-1:-1;3715:83:2;;-1:-1:-1;3715:83:2;-1:-1:-1;3715:83:2;-1:-1:-1;3814:19:2;;;;;;:47;;-1:-1:-1;2779:4:1;3837:24:2;3804:57;;3651:215;;;3480:386;;;;;;:::o;2824:93:1:-;2898:14;;;;;;;;;;;;;;1173:224:13;1279:107;;12792:66:22;1279:107:13;;;12780:79:22;1325:13:13;12875:11:22;;;12868:27;12946:66;1356:4:13;12933:2:22;12929:15;12925:88;12911:12;;;12904:110;13030:12;;;13023:28;;;1240:7:13;;13067:12:22;;1279:107:13;;;;;;;;;;;;;1262:130;;;;;;1255:137;;1173:224;;;:::o;1710:834:1:-;1847:4;1832:12;1864:676;1888:4;1884:1;:8;1864:676;;;1907:32;1942:4;;1947:1;1942:7;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;1907:42;-1:-1:-1;1962:24:1;;;;1907:42;1962:24;:::i;:::-;1958:62;;;1995:25;;;;;;;;2778::22;;;2751:18;;1995:25:1;2632:177:22;1958:62:1;2048:20;;;;;2080:9;:20;2076:69;;;2122:1;2125:8;2135:9;2109:36;;;;;;;;13869:25:22;;;;13910:18;;;13903:34;;;;13953:18;;;13946:34;13842:18;;2109:36:1;13667:319:22;2076:69:1;2154:12;2169:148;2192:18;;;;;;;;:::i;:::-;2220:17;;;;2247:13;;:36;;2275:8;2247:36;;;2263:9;2247:36;2293:16;;;;:11;:16;:::i;:::-;2169:13;:148::i;:::-;2154:163;;2330:7;2326:208;;;2365:7;2354:22;2374:1;2354:22;;;;2778:25:22;;2766:2;2751:18;;2632:177;2354:22:1;;;;;;;;2326:208;;;2401:124;2425:25;;;;;;;;:::i;:::-;2462:7;2481:1;2494:21;:19;:21::i;:::-;2401:12;:124::i;:::-;1899:641;;;1894:3;;;;;:::i;:::-;;;;1864:676;;;;1799:745;1710:834;;;:::o;8892:642:13:-;8996:17;;;;9131:41;9145:10;9157:14;:10;9168:1;9157:10;;:14;:::i;:::-;9131:13;:41::i;:::-;622:9:20;656:13;;;1585:25:18;;1626:3;1622:14;683:2:20;676:14;;;715:2;702:16;;;656:13;;9379:1:13;2034:23:18;;;2021:37;2074:3;2070:14;676::20;;;;702:16;;;;1622:14:18;;9109:63:13;;-1:-1:-1;702:16:20;2070:14:18;-1:-1:-1;8892:642:13;-1:-1:-1;;;;8892:642:13:o;648:262:15:-;752:17;;;;854:51;878:10;890:14;:10;901:1;890:10;;:14;:::i;:::-;854:23;:51::i;:::-;847:58;;;;;;;;648:262;;;;;;;:::o;404:213:16:-;502:104;;12792:66:22;502:104:16;;;12780:79:22;463:7:16;12875:11:22;;;12868:27;;;12946:66;576:4:16;12933:2:22;12929:15;12925:88;12911:12;;;12904:110;13030:12;;;13023:28;;;463:7:16;13067:12:22;;502:104:16;12494:591:22;2320:2059:14;2428:17;;;;;3378:14:19;2563:1:14;3290:25:19;;3277:39;3336:3;3332:14;2428:17:14;2768:16;3378:14:19;3332;2768:16:14;:::i;:::-;2750:34;-1:-1:-1;2883:72:14;2908:7;2923:26;2750:34;2934:6;2923:10;;:26;:::i;2883:72::-;2791:164;;-1:-1:-1;2791:164:14;;-1:-1:-1;2791:164:14;-1:-1:-1;2791:164:14;-1:-1:-1;2791:164:14;-1:-1:-1;2966:18:14;;;2962:118;;;3027:26;3045:7;3038:6;3027:10;;:26;:::i;:::-;3055:9;3066:6;3001:72;;;;;;;;;;;;;;:::i;2962:118::-;3095:7;3086:16;;3283:1092;3290:26;;;3283:1092;;;3390:1:19;3378:14;;;3290:25;;3277:39;3336:3;3332:14;;-1:-1:-1;3444:16:14;3378:14:19;3332;3444:16:14;:::i;:::-;3434:26;;3469:22;3687:105;3714:34;3738:9;3714:23;:34::i;:::-;3758:10;;3769:6;3758:26;3776:7;3758:26;;;;;;;:::i;3687:105::-;3500:292;;-1:-1:-1;3500:292:14;;-1:-1:-1;3500:292:14;-1:-1:-1;3500:292:14;;-1:-1:-1;;3833:18:14;;;3829:122;;;3896:26;3914:7;3907:6;3896:10;;:26;:::i;:::-;3924:9;3935:6;3870:72;;;;;;;;;;;;;;:::i;3829:122::-;4216:10;4198:14;:28;4194:115;;4245:55;;;;;;;;16193:25:22;;;16234:18;;;16227:34;;;16166:18;;4245:55:14;16019:248:22;4194:115:14;4330:14;-1:-1:-1;4361:7:14;-1:-1:-1;4361:7:14;3283:1092;;;2540:1839;;;2320:2059;;;;;;;;;:::o;490:187:9:-;568:11;587;622:4;628:7;611:25;;;;;;;;16193::22;;;16249:2;16234:18;;16227:34;16181:2;16166:18;;16019:248;611:25:9;;;;;;;;;;;;;;601:36;;611:25;601:36;;;;661:10;;490:187;-1:-1:-1;;;;490:187:9:o;4140:231:3:-;4226:4;4242:46;;;;;4238:78;;-1:-1:-1;4305:4:3;;4140:231;-1:-1:-1;4140:231:3:o;4238:78::-;4329:37;4353:12;4329:23;:37::i;1525:353:20:-;1640:6;1688:4;1682:11;1732:12;1718;1713:3;1700:45;1859:1;1848;1826:12;1813:3;1799:4;1786:3;1772:4;1758:110;1753:115;1525:353;-1:-1:-1;;;;;;;1525:353:20:o;852:271::-;897:14;948:16;982:4;976:11;971:16;;1014:2;1011:1;1007:10;1048:4;1041:5;1037:16;1031:4;1024:30;1071:4;1068:1;1061:15;1108:4;1105:1;1098:5;1083:30;;;852:271;:::o;3644:286:3:-;3781:14;3777:149;;;3849:7;3843:14;3836:4;3827:7;3823:18;3816:42;3777:149;3894:7;3885:34;3903:6;3911:7;3885:34;;;;;;;:::i;:::-;;;;;;;;3644:286;;;;:::o;3525:4708:13:-;3635:14;3655:12;3696:14;3765:4458;3772:26;;;3765:4458;;;1475:1:19;1463:14;;;1390:25;;1377:39;1432:3;1428:14;3923:20:13;;;3919:402;;2205:2:19;2193:15;;;2046:25;;2033:39;2088:3;2084:14;;;;2118:2;2114:13;2129:42;2110:62;;;1873:23:13;;:49;;4231:4;:59;;4286:4;4231:59;;;622:9:20;656:13;;;683:2;676:14;;;715:2;702:16;;4252:31:13;4224:66;;4302:8;;;;;;3919:402;4335:4;4331:679;;1475:1:19;1463:14;;;1390:25;;;1377:39;1432:3;1428:14;;4560:11:13;;4396:16;4598:72;4631:10;4643:26;4560:11;1463:14:19;4643:10:13;1390:25:19;4643:26:13;:::i;:::-;4598:32;:72::i;:::-;4764:20;;;;;;;;4691:7;;-1:-1:-1;4691:7:13;;4764:20;-1:-1:-1;1893:3:13;1873:23;;;;;1899;;;1873:49;4920:4;:59;;4975:4;4920:59;;;622:9:20;656:13;;;683:2;676:14;;;715:2;702:16;;4941:31:13;4913:66;;4991:8;;;;;;;4331:679;625:1;5024:4;:30;5020:932;;5104:16;;2046:25:19;;;2033:39;2088:3;2084:14;;;;2118:2;2114:13;2129:42;2110:62;2205:2;2193:15;;5146:64:13;-1:-1:-1;5146:64:13;;-1:-1:-1;5146:64:13;-1:-1:-1;5256:12:13;3290:25:19;;;3277:39;3336:3;3332:14;3390:1;3378:14;;5280:46:13;;;;;;;;;;;;;5380:15;5407:4;5398:6;:13;5380:31;;5428:81;5464:10;5476:4;5482:10;;5493:6;5482:26;5500:7;5482:26;;;;;;;:::i;:::-;5428:35;:81::i;:::-;5423:190;;5555:10;5567:4;5573:26;5591:7;5584:6;5573:10;;:26;:::i;:::-;5532:68;;;;;;;;;;;;;;:::i;5423:190::-;5706:20;;;;;;;;;-1:-1:-1;5706:20:13;1893:3;1873:23;;;;;1899;;;1873:49;5862:4;:59;;5917:4;5862:59;;;622:9:20;656:13;;;683:2;676:14;;;715:2;702:16;;5883:31:13;5855:66;;5933:8;;;;;;;;5020:932;667:1;5966:4;:17;5962:243;;4550:2:19;4536:17;;;4487:27;;4474:41;6115:4:13;:59;;6170:4;6115:59;;;622:9:20;656:13;;;683:2;676:14;;;715:2;702:16;;6136:31:13;6108:66;;6186:8;;;;5962:243;711:1;6219:4;:19;6215:472;;3390:1:19;3378:14;;;;3290:25;;;3277:39;3336:3;3332:14;;6409:13:13;;;;6309:12;;6494:53;6508:10;6520:26;6409:13;3378:14:19;6520:10:13;3290:25:19;6520:26:13;:::i;6494:53::-;622:9:20;656:13;;;683:2;676:14;715:2;702:16;;;6560:17:13;;;;;-1:-1:-1;6649:7:13;;-1:-1:-1;6668:8:13;;-1:-1:-1;;;6668:8:13;6215:472;802:1;6701:4;:19;6697:979;;6864:22;1390:25:19;;;1377:39;1432:3;1428:14;1475:1;1463:14;;6898:55:13;-1:-1:-1;6898:55:13;;;-1:-1:-1;6966:25:13;2699::19;;;2686:39;2745:3;2741:14;2797:1;2785:14;;7003:59:13;-1:-1:-1;7003:59:13;;;-1:-1:-1;7075:12:13;3290:25:19;;;3277:39;3336:3;3332:14;3390:1;3378:14;;7099:46:13;;;;;;;;;;;;;7157:15;7184:4;7175:6;:13;7157:31;;7201:22;7225:20;7290:53;7304:10;7316;;7327:6;7316:26;7334:7;7316:26;;;;;;;:::i;7290:53::-;7364:7;;-1:-1:-1;7364:7:13;;7257:86;;-1:-1:-1;7257:86:13;-1:-1:-1;7388:35:13;;;7384:92;;7439:24;;;;7384:92;2976:73;;;20362:66:22;2976:73:13;;;;20350:79:22;;;;20445:12;;;20438:28;;;20482:12;;;20475:28;;;20519:12;;;;20512:28;;;2976:73:13;;;;;;;;;;20556:13:22;;;;2976:73:13;;;2966:84;;;;;7585:4;:59;;7640:4;7585:59;;;622:9:20;656:13;;;683:2;676:14;;;715:2;702:16;;7606:31:13;7578:66;;7657:8;;;;;;;;;;6697:979;758:1;7690:4;:22;7686:485;;4550:2:19;4536:17;;;4487:27;;4474:41;7920:23:13;;;7916:82;;7968:17;7959:26;;7916:82;8010:12;8025:37;8052:9;8025:26;:37::i;:::-;8010:52;-1:-1:-1;8081:4:13;:59;;8136:4;8081:59;;;622:9:20;656:13;;;683:2;676:14;;;715:2;702:16;;8102:31:13;8074:66;;8152:8;;;;;7686:485;8188:26;;;;;;;;2778:25:22;;;2751:18;;8188:26:13;2632:177:22;3765:4458:13;3678:4551;3525:4708;;;;;;:::o;1296:160:14:-;862:44;1372:7;656:13:20;;;683:2;676:14;;;715:2;702:16;;1394:57:14;543:185:20;6015:300:2;6101:4;6124:45;;;6140:29;6124:45;;:103;;-1:-1:-1;6179:48:2;;;6195:32;6179:48;6124:103;6113:147;;;-1:-1:-1;6249:4:2;;6015:300;-1:-1:-1;6015:300:2:o;6113:147::-;725:31:5;709:47;;;;6273:37:2;613:148:5;1767:2316:21;1867:14;1914:2;1893:23;;1889:70;;1948:10;;1925:34;;;;;;;;;;;;:::i;1889:70::-;1965:21;1989:43;2010:21;2030:1;2010:10;:21;:::i;:::-;1226:23:18;;1213:37;1266:3;1262:14;;1071:215;1989:43:21;1965:67;;;-1:-1:-1;2115:2:21;1226:23:18;;1213:37;1266:3;1262:14;795:37;;2202:2:21;808:23:18;;795:37;3209:66:21;3196:79;;3192:135;;;3306:10;;3318:1;3292:28;;;;;;;;;;;;;:::i;3192:135::-;3337:1;:7;;3342:2;3337:7;;:18;;;;;3348:1;:7;;3353:2;3348:7;;3337:18;3333:74;;;3386:10;;3398:1;3372:28;;;;;;;;;;;;;:::i;3333:74::-;1253:1;3447:13;:32;3443:509;;3498:25;;;;;;;;;;;;18522::22;;;18595:4;18583:17;;18563:18;;;18556:45;;;;18617:18;;;18610:34;;;18660:18;;;18653:34;;;3498:25:21;;18494:19:22;;3498:25:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3489:34;;3443:509;;;1303:1;3608:13;:34;3604:348;;3690:59;;18940:66:22;3690:59:21;;;18928:79:22;19023:12;;;19016:28;;;3661:130:21;;19060:12:22;;3690:59:21;;;;;;;;;;;;;3680:70;;3690:59;3680:70;;;;3661:130;;;;;;;;;18522:25:22;18595:4;18583:17;;18563:18;;;18556:45;18617:18;;;18610:34;;;18660:18;;;18653:34;;;18494:19;;3661:130:21;18295:398:22;3604:348:21;3913:10;;3925:13;3940:4;3888:57;;;;;;;;;;;;;;:::i;3604:348::-;3999:22;;;3995:63;;4047:10;;4030:28;;;;;;;;;;;;:::i;3995:63::-;4065:13;;;;1767:2316;;;;;:::o;4411:951::-;4535:10;4557:22;;;4553:66;;4596:16;;;;;;;;;;;;;;4553:66;4625:21;4655:10;;4666:21;4686:1;4655:10;4666:21;:::i;:::-;4655:33;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;;1253:1:21;4699:32;;;:70;;;1303:1;4735:13;:34;4699:70;4695:663;;;4873:7;4837:43;;:32;4851:5;4858:10;;4837:13;:32::i;:::-;:43;;;4829:51;;4695:663;;;1359:1;4898:13;:40;4894:464;;5060:40;;;;5101:5;5108:10;5119:1;5108:10;5121:21;5141:1;5108:10;5121:21;:::i;:::-;5108:35;;;;;;;:::i;:::-;5060:84;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5030:114;;:26;:114;;-1:-1:-1;4894:464:21;;;5318:10;;5330:13;5345:5;5293:58;;;;;;;;;;;;;;:::i;4894:464::-;4547:815;4411:951;;;;;;:::o;2227:182:13:-;2346:57;;20822:66:22;2346:57:13;;;20810:79:22;20905:12;;;20898:28;;;2314:7:13;;20942:12:22;;2346:57:13;20580:380:22;14:177;99:66;92:5;88:78;81:5;78:89;68:117;;181:1;178;171:12;196:245;254:6;307:2;295:9;286:7;282:23;278:32;275:52;;;323:1;320;313:12;275:52;362:9;349:23;381:30;405:5;381:30;:::i;638:347::-;689:8;699:6;753:3;746:4;738:6;734:17;730:27;720:55;;771:1;768;761:12;720:55;-1:-1:-1;794:20:22;;837:18;826:30;;823:50;;;869:1;866;859:12;823:50;906:4;898:6;894:17;882:29;;958:3;951:4;942:6;934;930:19;926:30;923:39;920:59;;;975:1;972;965:12;920:59;638:347;;;;;:::o;990:477::-;1069:6;1077;1085;1138:2;1126:9;1117:7;1113:23;1109:32;1106:52;;;1154:1;1151;1144:12;1106:52;1190:9;1177:23;1167:33;;1251:2;1240:9;1236:18;1223:32;1278:18;1270:6;1267:30;1264:50;;;1310:1;1307;1300:12;1264:50;1349:58;1399:7;1390:6;1379:9;1375:22;1349:58;:::i;:::-;990:477;;1426:8;;-1:-1:-1;1323:84:22;;-1:-1:-1;;;;990:477:22:o;1725:717::-;1815:6;1823;1831;1839;1892:2;1880:9;1871:7;1867:23;1863:32;1860:52;;;1908:1;1905;1898:12;1860:52;1948:9;1935:23;1977:18;2018:2;2010:6;2007:14;2004:34;;;2034:1;2031;2024:12;2004:34;2073:58;2123:7;2114:6;2103:9;2099:22;2073:58;:::i;:::-;2150:8;;-1:-1:-1;2047:84:22;-1:-1:-1;2238:2:22;2223:18;;2210:32;;-1:-1:-1;2254:16:22;;;2251:36;;;2283:1;2280;2273:12;2251:36;;2322:60;2374:7;2363:8;2352:9;2348:24;2322:60;:::i;:::-;1725:717;;;;-1:-1:-1;2401:8:22;-1:-1:-1;;;;1725:717:22:o;2447:180::-;2506:6;2559:2;2547:9;2538:7;2534:23;2530:32;2527:52;;;2575:1;2572;2565:12;2527:52;-1:-1:-1;2598:23:22;;2447:180;-1:-1:-1;2447:180:22:o;2814:387::-;2897:8;2907:6;2961:3;2954:4;2946:6;2942:17;2938:27;2928:55;;2979:1;2976;2969:12;2928:55;-1:-1:-1;3002:20:22;;3045:18;3034:30;;3031:50;;;3077:1;3074;3067:12;3031:50;3114:4;3106:6;3102:17;3090:29;;3174:3;3167:4;3157:6;3154:1;3150:14;3142:6;3138:27;3134:38;3131:47;3128:67;;;3191:1;3188;3181:12;3206:488;3323:6;3331;3384:2;3372:9;3363:7;3359:23;3355:32;3352:52;;;3400:1;3397;3390:12;3352:52;3440:9;3427:23;3473:18;3465:6;3462:30;3459:50;;;3505:1;3502;3495:12;3459:50;3544:90;3626:7;3617:6;3606:9;3602:22;3544:90;:::i;:::-;3653:8;;3518:116;;-1:-1:-1;3206:488:22;-1:-1:-1;;;;3206:488:22:o;3699:864::-;3845:6;3853;3861;3869;3877;3930:2;3918:9;3909:7;3905:23;3901:32;3898:52;;;3946:1;3943;3936:12;3898:52;3986:9;3973:23;4015:18;4056:2;4048:6;4045:14;4042:34;;;4072:1;4069;4062:12;4042:34;4111:90;4193:7;4184:6;4173:9;4169:22;4111:90;:::i;:::-;4220:8;;-1:-1:-1;4085:116:22;-1:-1:-1;4302:2:22;4287:18;;4274:32;;-1:-1:-1;4359:2:22;4344:18;;4331:32;;-1:-1:-1;4375:16:22;;;4372:36;;;4404:1;4401;4394:12;4372:36;;4443:60;4495:7;4484:8;4473:9;4469:24;4443:60;:::i;:::-;3699:864;;;;-1:-1:-1;3699:864:22;;-1:-1:-1;4522:8:22;;4417:86;3699:864;-1:-1:-1;;;3699:864:22:o;5403:184::-;5455:77;5452:1;5445:88;5552:4;5549:1;5542:15;5576:4;5573:1;5566:15;5592:980;5660:6;5713:2;5701:9;5692:7;5688:23;5684:32;5681:52;;;5729:1;5726;5719:12;5681:52;5769:9;5756:23;5798:18;5839:2;5831:6;5828:14;5825:34;;;5855:1;5852;5845:12;5825:34;5893:6;5882:9;5878:22;5868:32;;5938:7;5931:4;5927:2;5923:13;5919:27;5909:55;;5960:1;5957;5950:12;5909:55;5996:2;5983:16;6018:2;6014;6011:10;6008:36;;;6024:18;;:::i;:::-;6158:2;6152:9;6220:4;6212:13;;6063:66;6208:22;;;6232:2;6204:31;6200:40;6188:53;;;6256:18;;;6276:22;;;6253:46;6250:72;;;6302:18;;:::i;:::-;6342:10;6338:2;6331:22;6377:2;6369:6;6362:18;6417:7;6412:2;6407;6403;6399:11;6395:20;6392:33;6389:53;;;6438:1;6435;6428:12;6389:53;6494:2;6489;6485;6481:11;6476:2;6468:6;6464:15;6451:46;6539:1;6517:15;;;6534:2;6513:24;6506:35;;;;-1:-1:-1;6521:6:22;5592:980;-1:-1:-1;;;;;5592:980:22:o;6808:271::-;6991:6;6983;6978:3;6965:33;6947:3;7017:16;;7042:13;;;7017:16;6808:271;-1:-1:-1;6808:271:22:o;7416:160::-;7481:20;;7537:13;;7530:21;7520:32;;7510:60;;7566:1;7563;7556:12;7510:60;7416:160;;;:::o;7581:196::-;7649:20;;7709:42;7698:54;;7688:65;;7678:93;;7767:1;7764;7757:12;7782:325;7870:6;7865:3;7858:19;7922:6;7915:5;7908:4;7903:3;7899:14;7886:43;;7974:1;7967:4;7958:6;7953:3;7949:16;7945:27;7938:38;7840:3;8096:4;8026:66;8021:2;8013:6;8009:15;8005:88;8000:3;7996:98;7992:109;7985:116;;7782:325;;;;:::o;8112:2028::-;8232:6;8227:3;8220:19;8202:3;8258:4;8299:2;8294:3;8290:12;8324:11;8351;8344:18;;8401:6;8398:1;8394:14;8387:5;8383:26;8371:38;;8432:5;8455:1;8465:1649;8479:6;8476:1;8473:13;8465:1649;;;8550:5;8544:4;8540:16;8535:3;8528:29;8609:6;8596:20;8695:66;8687:5;8671:14;8667:26;8663:99;8643:18;8639:124;8629:152;;8777:1;8774;8767:12;8629:152;8809:30;;8862:4;8906:24;8809:30;8906:24;:::i;:::-;8899:32;8892:40;8886:4;8879:54;8982:33;9011:2;9002:7;8998:16;8982:33;:::i;:::-;8975:41;8968:49;8953:13;;;8946:72;9041:4;9093:16;;;9080:30;9065:13;;;9058:53;9134:4;9215:42;9177:36;9196:16;;;9177:36;:::i;:::-;9173:85;9158:13;;;9151:108;9282:4;9334:16;;;9321:30;9306:13;;;9299:53;9375:4;9433:16;;;9420:30;9507:14;9503:28;;;9533:66;9499:101;9473:128;;9463:156;;9615:1;9612;9605:12;9463:156;9647:34;;;9759:16;;;;-1:-1:-1;9710:21:22;9804:18;9791:32;;9788:52;;;9836:1;9833;9826:12;9788:52;9889:8;9873:14;9869:29;9860:7;9856:43;9853:63;;;9912:1;9909;9902:12;9853:63;9951:2;9946;9940:4;9936:13;9929:25;9975:59;10030:2;10024:4;10020:13;10010:8;10001:7;9975:59;:::i;:::-;10092:12;;;;9967:67;-1:-1:-1;;;10057:15:22;;;;-1:-1:-1;;8501:1:22;8494:9;8465:1649;;;-1:-1:-1;10130:4:22;;8112:2028;-1:-1:-1;;;;;;;8112:2028:22:o;10145:594::-;10495:2;10484:9;10477:21;10534:1;10529:2;10518:9;10514:18;10507:29;10572:7;10567:2;10556:9;10552:18;10545:35;10618:3;10611:4;10600:9;10596:20;10589:33;10458:4;10639:94;10728:3;10717:9;10713:19;10705:6;10697;10639:94;:::i;10744:595::-;11094:2;11083:9;11076:21;11133:1;11128:2;11117:9;11113:18;11106:29;11171:8;11166:2;11155:9;11151:18;11144:36;11218:3;11211:4;11200:9;11196:20;11189:33;11057:4;11239:94;11328:3;11317:9;11313:19;11305:6;11297;11239:94;:::i;11344:184::-;11396:77;11393:1;11386:88;11493:4;11490:1;11483:15;11517:4;11514:1;11507:15;11786:481;11827:3;11865:5;11859:12;11892:6;11887:3;11880:19;11917:1;11927:162;11941:6;11938:1;11935:13;11927:162;;;12003:4;12059:13;;;12055:22;;12049:29;12031:11;;;12027:20;;12020:59;11956:12;11927:162;;;11931:3;12134:1;12127:4;12118:6;12113:3;12109:16;12105:27;12098:38;12256:4;12186:66;12181:2;12173:6;12169:15;12165:88;12160:3;12156:98;12152:109;12145:116;;;11786:481;;;;:::o;12272:217::-;12419:2;12408:9;12401:21;12382:4;12439:44;12479:2;12468:9;12464:18;12456:6;12439:44;:::i;13090:387::-;13187:4;13245:11;13232:25;13335:66;13324:8;13308:14;13304:29;13300:102;13280:18;13276:127;13266:155;;13417:1;13414;13407:12;13266:155;13438:33;;;;;13090:387;-1:-1:-1;;13090:387:22:o;13482:180::-;13538:6;13591:2;13579:9;13570:7;13566:23;13562:32;13559:52;;;13607:1;13604;13597:12;13559:52;13630:26;13646:9;13630:26;:::i;13991:186::-;14050:6;14103:2;14091:9;14082:7;14078:23;14074:32;14071:52;;;14119:1;14116;14109:12;14071:52;14142:29;14161:9;14142:29;:::i;14182:580::-;14259:4;14265:6;14325:11;14312:25;14415:66;14404:8;14388:14;14384:29;14380:102;14360:18;14356:127;14346:155;;14497:1;14494;14487:12;14346:155;14524:33;;14576:20;;;-1:-1:-1;14619:18:22;14608:30;;14605:50;;;14651:1;14648;14641:12;14605:50;14684:4;14672:17;;-1:-1:-1;14715:14:22;14711:27;;;14701:38;;14698:58;;;14752:1;14749;14742:12;14767:184;14819:77;14816:1;14809:88;14916:4;14913:1;14906:15;14940:4;14937:1;14930:15;14956:195;14995:3;15026:66;15019:5;15016:77;15013:103;;15096:18;;:::i;:::-;-1:-1:-1;15143:1:22;15132:13;;14956:195::o;15156:331::-;15261:9;15272;15314:8;15302:10;15299:24;15296:44;;;15336:1;15333;15326:12;15296:44;15365:6;15355:8;15352:20;15349:40;;;15385:1;15382;15375:12;15349:40;-1:-1:-1;;15411:23:22;;;15456:25;;;;;-1:-1:-1;15156:331:22:o;15492:125::-;15557:9;;;15578:10;;;15575:36;;;15591:18;;:::i;15622:392::-;15841:2;15830:9;15823:21;15804:4;15861:61;15918:2;15907:9;15903:18;15895:6;15887;15861:61;:::i;:::-;15953:2;15938:18;;15931:34;;;;-1:-1:-1;15996:2:22;15981:18;15974:34;15853:69;15622:392;-1:-1:-1;;15622:392:22:o;16525:288::-;16700:6;16689:9;16682:25;16743:2;16738;16727:9;16723:18;16716:30;16663:4;16763:44;16803:2;16792:9;16788:18;16780:6;16763:44;:::i;16818:441::-;17037:6;17026:9;17019:25;17092:42;17084:6;17080:55;17075:2;17064:9;17060:18;17053:83;17172:2;17167;17156:9;17152:18;17145:30;17000:4;17192:61;17249:2;17238:9;17234:18;17226:6;17218;17192:61;:::i;:::-;17184:69;16818:441;-1:-1:-1;;;;;;16818:441:22:o;17264:244::-;17421:2;17410:9;17403:21;17384:4;17441:61;17498:2;17487:9;17483:18;17475:6;17467;17441:61;:::i;17513:128::-;17580:9;;;17601:11;;;17598:37;;;17615:18;;:::i;17646:315::-;17831:2;17820:9;17813:21;17794:4;17851:61;17908:2;17897:9;17893:18;17885:6;17877;17851:61;:::i;:::-;17843:69;;17948:6;17943:2;17932:9;17928:18;17921:34;17646:315;;;;;;:::o;17966:324::-;18149:2;18138:9;18131:21;18112:4;18169:61;18226:2;18215:9;18211:18;18203:6;18195;18169:61;:::i;:::-;18161:69;;18278:4;18270:6;18266:17;18261:2;18250:9;18246:18;18239:45;17966:324;;;;;;:::o;19083:396::-;19290:2;19279:9;19272:21;19253:4;19310:61;19367:2;19356:9;19352:18;19344:6;19336;19310:61;:::i;:::-;19402:2;19387:18;;19380:34;;;;-1:-1:-1;19457:14:22;;19450:22;19445:2;19430:18;;;19423:50;19302:69;19083:396;-1:-1:-1;;19083:396:22:o;19484:321::-;19675:6;19664:9;19657:25;19718:2;19713;19702:9;19698:18;19691:30;19638:4;19738:61;19795:2;19784:9;19780:18;19772:6;19764;19738:61;:::i;:::-;19730:69;19484:321;-1:-1:-1;;;;;19484:321:22:o;19810:249::-;19879:6;19932:2;19920:9;19911:7;19907:23;19903:32;19900:52;;;19948:1;19945;19938:12;19900:52;19980:9;19974:16;19999:30;20023:5;19999:30;:::i" + }, + "gasEstimates": { + "creation": { + "codeDepositCost": "1734000", + "executionCost": "infinite", + "totalCost": "infinite" + }, + "external": { + "SET_IMAGE_HASH_TYPE_HASH()": "262", + "createContract(bytes)": "infinite", + "execute((bool,bool,uint256,address,uint256,bytes)[],uint256,bytes)": "infinite", + "isValidSignature(bytes,bytes)": "infinite", + "isValidSignature(bytes32,bytes)": "infinite", + "nonce()": "2645", + "readNonce(uint256)": "2640", + "selfExecute((bool,bool,uint256,address,uint256,bytes)[])": "infinite", + "signatureRecovery(bytes32,bytes)": "infinite", + "supportsInterface(bytes4)": "infinite", + "updateImageHash(bytes32)": "357" + }, + "internal": { + "_executeGuest(bytes32,struct IModuleCalls.Transaction calldata[] calldata)": "infinite", + "_isValidImage(bytes32)": "infinite", + "_updateImageHash(bytes32)": "infinite" + } + }, + "methodIdentifiers": { + "SET_IMAGE_HASH_TYPE_HASH()": "57c56d6b", + "createContract(bytes)": "90042baf", + "execute((bool,bool,uint256,address,uint256,bytes)[],uint256,bytes)": "7a9a1628", + "isValidSignature(bytes,bytes)": "20c13b0b", + "isValidSignature(bytes32,bytes)": "1626ba7e", + "nonce()": "affed0e0", + "readNonce(uint256)": "8c3f5563", + "selfExecute((bool,bool,uint256,address,uint256,bytes)[])": "61c2926c", + "signatureRecovery(bytes32,bytes)": "853c5068", + "supportsInterface(bytes4)": "01ffc9a7", + "updateImageHash(bytes32)": "29561426" + } + }, + "abi": [ + { + "inputs": [ + { + "internalType": "uint256", + "name": "_space", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_provided", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_current", + "type": "uint256" + } + ], + "name": "BadNonce", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_code", + "type": "bytes" + } + ], + "name": "CreateFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_index", + "type": "uint256" + } + ], + "name": "DelegateCallNotAllowed", + "type": "error" + }, + { + "inputs": [], + "name": "EmptySignature", + "type": "error" + }, + { + "inputs": [], + "name": "ImageHashIsZero", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "_addr", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "InvalidNestedSignature", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + }, + { + "internalType": "bytes32", + "name": "_s", + "type": "bytes32" + } + ], + "name": "InvalidSValue", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "InvalidSignature", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_flag", + "type": "uint256" + } + ], + "name": "InvalidSignatureFlag", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "InvalidSignatureLength", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes1", + "name": "_type", + "type": "bytes1" + } + ], + "name": "InvalidSignatureType", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_v", + "type": "uint256" + } + ], + "name": "InvalidVValue", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "threshold", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_weight", + "type": "uint256" + } + ], + "name": "LowWeightChainedSignature", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_index", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_requested", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_available", + "type": "uint256" + } + ], + "name": "NotEnoughGas", + "type": "error" + }, + { + "inputs": [], + "name": "NotSupported", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyDelegatecall", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_sender", + "type": "address" + }, + { + "internalType": "address", + "name": "_self", + "type": "address" + } + ], + "name": "OnlySelfAuth", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "SignerIsAddress0", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_type", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_recoverMode", + "type": "bool" + } + ], + "name": "UnsupportedSignatureType", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_current", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_prev", + "type": "uint256" + } + ], + "name": "WrongChainedCheckpointOrder", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_contract", + "type": "address" + } + ], + "name": "CreatedContract", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "newImageHash", + "type": "bytes32" + } + ], + "name": "ImageHashUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_space", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_newNonce", + "type": "uint256" + } + ], + "name": "NonceChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "_tx", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_index", + "type": "uint256" + } + ], + "name": "TxExecuted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "_tx", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_index", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_reason", + "type": "bytes" + } + ], + "name": "TxFailed", + "type": "event" + }, + { + "inputs": [], + "name": "SET_IMAGE_HASH_TYPE_HASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_code", + "type": "bytes" + } + ], + "name": "createContract", + "outputs": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bool", + "name": "delegateCall", + "type": "bool" + }, + { + "internalType": "bool", + "name": "revertOnError", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + }, + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "internalType": "struct IModuleCalls.Transaction[]", + "name": "_txs", + "type": "tuple[]" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "execute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_signatures", + "type": "bytes" + } + ], + "name": "isValidSignature", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "_signatures", + "type": "bytes" + } + ], + "name": "isValidSignature", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_space", + "type": "uint256" + } + ], + "name": "readNonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bool", + "name": "delegateCall", + "type": "bool" + }, + { + "internalType": "bool", + "name": "revertOnError", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + }, + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "internalType": "struct IModuleCalls.Transaction[]", + "name": "_txs", + "type": "tuple[]" + } + ], + "name": "selfExecute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_digest", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "signatureRecovery", + "outputs": [ + { + "internalType": "uint256", + "name": "threshold", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "weight", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "imageHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "subdigest", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "checkpoint", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceID", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_imageHash", + "type": "bytes32" + } + ], + "name": "updateImageHash", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ] +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/artifacts/GuestModule_metadata.json b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/artifacts/GuestModule_metadata.json new file mode 100644 index 0000000000..4298c56c90 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/artifacts/GuestModule_metadata.json @@ -0,0 +1,985 @@ +{ + "compiler": { + "version": "0.8.18+commit.87f61d96" + }, + "language": "Solidity", + "output": { + "abi": [ + { + "inputs": [ + { + "internalType": "uint256", + "name": "_space", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_provided", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_current", + "type": "uint256" + } + ], + "name": "BadNonce", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_code", + "type": "bytes" + } + ], + "name": "CreateFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_index", + "type": "uint256" + } + ], + "name": "DelegateCallNotAllowed", + "type": "error" + }, + { + "inputs": [], + "name": "EmptySignature", + "type": "error" + }, + { + "inputs": [], + "name": "ImageHashIsZero", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "_addr", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "InvalidNestedSignature", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + }, + { + "internalType": "bytes32", + "name": "_s", + "type": "bytes32" + } + ], + "name": "InvalidSValue", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "InvalidSignature", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_flag", + "type": "uint256" + } + ], + "name": "InvalidSignatureFlag", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "InvalidSignatureLength", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes1", + "name": "_type", + "type": "bytes1" + } + ], + "name": "InvalidSignatureType", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_v", + "type": "uint256" + } + ], + "name": "InvalidVValue", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "threshold", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_weight", + "type": "uint256" + } + ], + "name": "LowWeightChainedSignature", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_index", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_requested", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_available", + "type": "uint256" + } + ], + "name": "NotEnoughGas", + "type": "error" + }, + { + "inputs": [], + "name": "NotSupported", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyDelegatecall", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_sender", + "type": "address" + }, + { + "internalType": "address", + "name": "_self", + "type": "address" + } + ], + "name": "OnlySelfAuth", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "SignerIsAddress0", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_type", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_recoverMode", + "type": "bool" + } + ], + "name": "UnsupportedSignatureType", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_current", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_prev", + "type": "uint256" + } + ], + "name": "WrongChainedCheckpointOrder", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_contract", + "type": "address" + } + ], + "name": "CreatedContract", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "newImageHash", + "type": "bytes32" + } + ], + "name": "ImageHashUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_space", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_newNonce", + "type": "uint256" + } + ], + "name": "NonceChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "_tx", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_index", + "type": "uint256" + } + ], + "name": "TxExecuted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "_tx", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_index", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_reason", + "type": "bytes" + } + ], + "name": "TxFailed", + "type": "event" + }, + { + "inputs": [], + "name": "SET_IMAGE_HASH_TYPE_HASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_code", + "type": "bytes" + } + ], + "name": "createContract", + "outputs": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bool", + "name": "delegateCall", + "type": "bool" + }, + { + "internalType": "bool", + "name": "revertOnError", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + }, + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "internalType": "struct IModuleCalls.Transaction[]", + "name": "_txs", + "type": "tuple[]" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "execute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_signatures", + "type": "bytes" + } + ], + "name": "isValidSignature", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "_signatures", + "type": "bytes" + } + ], + "name": "isValidSignature", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_space", + "type": "uint256" + } + ], + "name": "readNonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bool", + "name": "delegateCall", + "type": "bool" + }, + { + "internalType": "bool", + "name": "revertOnError", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + }, + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "internalType": "struct IModuleCalls.Transaction[]", + "name": "_txs", + "type": "tuple[]" + } + ], + "name": "selfExecute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_digest", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "signatureRecovery", + "outputs": [ + { + "internalType": "uint256", + "name": "threshold", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "weight", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "imageHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "subdigest", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "checkpoint", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceID", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_imageHash", + "type": "bytes32" + } + ], + "name": "updateImageHash", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "devdoc": { + "kind": "dev", + "methods": { + "createContract(bytes)": { + "params": { + "_code": "Creation code of the contract" + }, + "returns": { + "addr": "The address of the created contract" + } + }, + "execute((bool,bool,uint256,address,uint256,bytes)[],uint256,bytes)": { + "params": { + "_txs": "Transactions to process" + } + }, + "isValidSignature(bytes,bytes)": { + "details": "MUST return the correct magic value if the signature provided is valid for the provided data > The bytes4 magic value to return when signature is valid is 0x20c13b0b : bytes4(keccak256(\"isValidSignature(bytes,bytes)\"))", + "params": { + "_data": "Arbitrary length data signed on the behalf of address(this)", + "_signatures": "Signature byte array associated with _data. Encoded as abi.encode(Signature[], Configs)" + }, + "returns": { + "_0": "magicValue Magic value 0x20c13b0b if the signature is valid and 0x0 otherwise" + } + }, + "isValidSignature(bytes32,bytes)": { + "details": "MUST return the correct magic value if the signature provided is valid for the provided hash > The bytes4 magic value to return when signature is valid is 0x1626ba7e : bytes4(keccak256(\"isValidSignature(bytes32,bytes)\"))", + "params": { + "_hash": "keccak256 hash that was signed", + "_signatures": "Signature byte array associated with _data. Encoded as abi.encode(Signature[], Configs)" + }, + "returns": { + "_0": "magicValue Magic value 0x1626ba7e if the signature is valid and 0x0 otherwise" + } + }, + "nonce()": { + "details": "The default nonce space is 0x00", + "returns": { + "_0": "The next nonce" + } + }, + "readNonce(uint256)": { + "params": { + "_space": "Nonce space, each space keeps an independent nonce count" + }, + "returns": { + "_0": "The next nonce" + } + }, + "selfExecute((bool,bool,uint256,address,uint256,bytes)[])": { + "params": { + "_txs": "Transactions to process" + } + }, + "signatureRecovery(bytes32,bytes)": { + "details": "The signature must be prefixed with a type byte, which is used to determine the recovery method.", + "params": { + "_digest": "Digest of the signed data.", + "_signature": "A Sequence signature." + }, + "returns": { + "checkpoint": "A nonce that is incremented every time a new configuration is set.", + "imageHash": "The imageHash of the configuration that signed the message.", + "subdigest": "A modified version of the original digest, unique for each wallet/network.", + "threshold": "The required number of signatures needed to consider the signature valid.", + "weight": "The actual number of signatures collected in the signature." + } + }, + "supportsInterface(bytes4)": { + "params": { + "_interfaceID": "The interface identifier, as specified in ERC-165" + }, + "returns": { + "_0": "`true` if the contract implements `_interfaceID`" + } + }, + "updateImageHash(bytes32)": { + "params": { + "_imageHash": "New required image hash of the signature" + } + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "createContract(bytes)": { + "notice": "Creates a contract forwarding eth value" + }, + "execute((bool,bool,uint256,address,uint256,bytes)[],uint256,bytes)": { + "notice": "Allow any caller to execute an action" + }, + "isValidSignature(bytes,bytes)": { + "notice": "Verifies whether the provided signature is valid with respect to the provided data" + }, + "isValidSignature(bytes32,bytes)": { + "notice": "Verifies whether the provided signature is valid with respect to the provided hash" + }, + "nonce()": { + "notice": "Returns the next nonce of the default nonce space" + }, + "readNonce(uint256)": { + "notice": "Returns the next nonce of the given nonce space" + }, + "selfExecute((bool,bool,uint256,address,uint256,bytes)[])": { + "notice": "Allow any caller to execute an action" + }, + "signatureRecovery(bytes32,bytes)": { + "notice": "Recovers the threshold, weight, imageHash, subdigest, and checkpoint of a signature." + }, + "supportsInterface(bytes4)": { + "notice": "Query if a contract implements an interface" + }, + "updateImageHash(bytes32)": { + "notice": "Updates the signers configuration of the wallet" + } + }, + "notice": "GuestModule implements a Sequence wallet without signatures, nonce or replay protection. executing transactions using this wallet is not an authenticated process, and can be done by any address.This contract is completely public with no security, designed to execute pre-signed transactions and use Sequence tools without using the wallets.", + "version": 1 + } + }, + "settings": { + "compilationTarget": { + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol": "GuestModule" + }, + "evmVersion": "paris", + "libraries": {}, + "metadata": { + "bytecodeHash": "ipfs" + }, + "optimizer": { + "enabled": true, + "runs": 500000 + }, + "remappings": [ + ":@0xsequence/contracts-library/=src/", + ":@0xsequence/erc-1155/=lib/0xsequence/erc-1155/src/", + ":@0xsequence/erc20-meta-token/=lib/0xsequence/erc20-meta-token/src/", + ":@openzeppelin/=lib/openzeppelin/", + ":ds-test/=lib/forge-std/lib/ds-test/src/", + ":erc721a-upgradeable/=lib/chiru-labs/erc721a-upgradeable/", + ":erc721a/=lib/chiru-labs/erc721a/", + ":forge-std/=lib/forge-std/src/", + ":murky/=lib/murky/src/", + ":solady/=lib/solady/src/" + ] + }, + "sources": { + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/interfaces/IERC1271Wallet.sol": { + "keccak256": "0x2d7881bca678833feb385fd59e5d8ad6d596160ab51daa7030372654b3dbc38c", + "license": "Apache-2.0", + "urls": [ + "bzz-raw://010f44c05b7285a55de939f9989727d53dfb87fd2d2534a832a70e0e081bb5f1", + "dweb:/ipfs/QmQcujWErxjktsKyyiTySaFuR7Vaq6fUA9SUzPkde2txVK" + ] + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol": { + "keccak256": "0x14c92b44eac100edbfea10d0d02728752a6be277c267c3776dc563ff963271b1", + "license": "Apache-2.0", + "urls": [ + "bzz-raw://e440eb91039118ce26bb66fd549d5e6b59863983efbe6c2617b92e2c4f0aab66", + "dweb:/ipfs/QmeTd2xBKEv4S4Rp9S4TSY4WwUUDjtA7xiJYiJqkVUio7d" + ] + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol": { + "keccak256": "0x58c028f02e3517de6c39584bcf1cedd4e7b23f575c24b363cbad4960a74f8a0b", + "license": "Apache-2.0", + "urls": [ + "bzz-raw://f9652fead22c9fe8510de8427e2db354ed145ff30f49f85d1c717e293e5df665", + "dweb:/ipfs/QmSJPFQxRE5n17DNB5Bu2jwRo17yLS7igMQGt3bvKkdLAP" + ] + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol": { + "keccak256": "0x80c0151dbd444f96c2f935e70a6d3cc57e307588fa21d7eace67e568dd3d35c1", + "license": "Apache-2.0", + "urls": [ + "bzz-raw://39a856555a5eb900e67d351e667135f245ccebd304d692b35fc8bdc83aec1b53", + "dweb:/ipfs/QmUdWfa7GcTGM5gk7qYbNCHtsxF4o8dXHzr6HbdFng5sQm" + ] + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol": { + "keccak256": "0x16b1400988f6b7bd4d32bdcb36ee2fbd644fb2c8ca571becc0c32e03602bd303", + "license": "Apache-2.0", + "urls": [ + "bzz-raw://8bd4681fb4cff10f4e98e45618fbc52ed0a4c7d4fcf614f34a587ad20cd16855", + "dweb:/ipfs/QmbA2LYBH1x8WX8CaeiFYMU5rjyLGgNCF32r9fQbXuoqwJ" + ] + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleERC165.sol": { + "keccak256": "0xd4ae13a3d20fd7ab52ad16af6a06e7244daea450b796251e911091cac104d05f", + "license": "Apache-2.0", + "urls": [ + "bzz-raw://8de37ec20a6b649e9fe3fb42276e4660ff546bca8b467f72beb35396ab5e62d6", + "dweb:/ipfs/QmXT2SxBZKitkbKLbGbbNLhUbw2ataRpQ2DHafvhG953RE" + ] + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol": { + "keccak256": "0x3b5388842f763a5347d632a0e0e8499a54b6f0b0a6eb7f7d3d848319defa042d", + "license": "Apache-2.0", + "urls": [ + "bzz-raw://b36fa5a88a4e174967f850bf2bb78c787d8016ef7b5eee3e2f883fbfe9b87a7d", + "dweb:/ipfs/QmTDZiPiQGe1fmTKKzdwzBE1xjkh8apTotW1SQRUCFXf4q" + ] + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleOnlyDelegatecall.sol": { + "keccak256": "0x32bdb1d343eee2e32fd9d0f1d6dc0e265411d0821bd908881822f0f26f0887f8", + "license": "Apache-2.0", + "urls": [ + "bzz-raw://1537c4f60a609751013bdc69eb1c6e6218982d91013115bc4e28cb84f816cd91", + "dweb:/ipfs/QmSjkSTrrB4vuxECcm5cRG7YmraF53QWRgftxS827KcQLW" + ] + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol": { + "keccak256": "0x91545de5c77cfac86c5686c4e1f338a18ee7adb689ac0234848d7a7fc8a560db", + "license": "Apache-2.0", + "urls": [ + "bzz-raw://dc89d05d8099ba4c3c2cf85737796d439899b5a04e6b87b1ea43f687ae08848a", + "dweb:/ipfs/QmatU8gRvFkK3Yn1MYAekzi48Waw3cDLtXJpduvju9HFUu" + ] + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol": { + "keccak256": "0x876c6a40cba975df4f7dfe24e02d153b2ee758975b6d1eda494ecd4b7244aa8e", + "license": "Apache-2.0", + "urls": [ + "bzz-raw://b9be3f7930476d528ce10a121701421f0fb251b7d6b7cd579917375e6b283bb4", + "dweb:/ipfs/QmSbvbYQvTk8KYJZ7QqSKB9Y4M1X3UDhS6k765Zr1BAwK8" + ] + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleAuth.sol": { + "keccak256": "0x24c6b05c32cb344b3b0aebd01fbd8bfc69f8c8e29fca340b262d9612c34d51e2", + "license": "Apache-2.0", + "urls": [ + "bzz-raw://5f6c004946f0cbc4b3e52d45248337146bc82569da894ecff3cbdc5a0dca95c3", + "dweb:/ipfs/QmNSgDMQ7SHL6AJuzTSRbY2kgciHF1SKWfH6MaPH1N3TpR" + ] + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCalls.sol": { + "keccak256": "0xde065c15e38eb009c3dc8f99dfefdd1d6d244dd12a889a8b57edd90d32fb4395", + "license": "Apache-2.0", + "urls": [ + "bzz-raw://23608955786060457f79267795a61eb89b3910b683fc136c749548369425088f", + "dweb:/ipfs/QmXNorcQBF1Qk21y3aEJRiiHVtwm61zP4ttA1ZzmRjyHnz" + ] + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCreator.sol": { + "keccak256": "0xa206dd3d424b8cd1c4f1400aa344cbc974480fea02f0fb371b872558e5ff4e6d", + "license": "Apache-2.0", + "urls": [ + "bzz-raw://ea14c75f43a0008c582dcbae3ba3c900e446e28039dfdbb059d326ec5cc6a2d2", + "dweb:/ipfs/QmRfF6BmUWiFkCgzVFbLcHsUCNz5q2XkkcwXPX57ViTK4D" + ] + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol": { + "keccak256": "0xe0565e24e94204d4b254ace42d124d3279256090921a4818cbbf9747cbb14e04", + "license": "Apache-2.0", + "urls": [ + "bzz-raw://4293a4762b0816738511f697efd04a0e881d4c409bd15ac1c4e7261fe5e482a2", + "dweb:/ipfs/QmcHbEBne4fvpcD7RTJHCL6q9czoLa7KHneaCeYfXuWiGu" + ] + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol": { + "keccak256": "0x755fbf6c106fe1c3c375c41c95c38269873717d8e683678b5fdbf6c8d3426306", + "license": "Apache-2.0", + "urls": [ + "bzz-raw://7c7c92e72dd94f16b5c004d38c2d92eb2b760fd29a939945ed275633b0f93fa5", + "dweb:/ipfs/QmVdCG7Aw7aVV67z5mUKZa4VqhXHdLqy3SKxPfxaxq54p2" + ] + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol": { + "keccak256": "0x6de353f8c7f44c4294914a4917458ce90ae2f7ecd2d84074fe12d4a4f1485ee5", + "license": "Apache-2.0", + "urls": [ + "bzz-raw://369f979b79a3d3fd0336ab14b3accadb63e4784324afc34f8db11d1988526afd", + "dweb:/ipfs/QmavmBZ354wTaXQ6ixBd8GrC9HwtRqn4MoNhCVJcx11off" + ] + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol": { + "keccak256": "0xa3ac8b8d31f20a8732bb4ebad53b42b334ec29041de0224bd494913ef0b2ad07", + "license": "Apache-2.0", + "urls": [ + "bzz-raw://5a81d4eb3f47b09a8835b2fd53e0baa2e23cb604db3b10dae82543a5bcc52fa4", + "dweb:/ipfs/QmQ9XSSgbaagWArmZJJ366bdJ7HfxUxn9jdnWwN6SxUSeY" + ] + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol": { + "keccak256": "0x98520e740b0822ec053d21f376b8be8a58e93228f3758f9228a7d00e1f60950f", + "license": "Apache-2.0", + "urls": [ + "bzz-raw://31226706c004f1a4315d6b8d37621b46f4d5807c16e1ce72675c1431ed9006a2", + "dweb:/ipfs/QmdSSyCuPex2E2VTd6UMYy9WAq9eJNZ6vHSUomntNknzXE" + ] + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol": { + "keccak256": "0xd780faf34527a323c96577c57370d175a2b6149db7ebea0937592eb389e52805", + "license": "Apache-2.0", + "urls": [ + "bzz-raw://7a41a47e72f5761d912367c041ddab41620175d63059ad71ff681a87d8cf0e98", + "dweb:/ipfs/QmfEFuLaVyx9vQc83dS48wTcLtbBiWTNMdHSi5hAWA379i" + ] + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol": { + "keccak256": "0xbda56396592db18a248d4062cd36abd586a11d92a2d25483d8c597f890859b15", + "license": "Apache-2.0", + "urls": [ + "bzz-raw://a6ee93bcb7ccd1d1b8979c9530b1ca452d0757794995b62793b6e197670b9f25", + "dweb:/ipfs/QmbNkhTPzF1YgU4Qgu4SRFXZ8AwFjyG18EzuMZ32anrQ4Y" + ] + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol": { + "keccak256": "0x4c558b8c9d0dff2322d5d812e83a3abe25a9e60c8f646507f8a9c7fa2a2453af", + "license": "Apache-2.0", + "urls": [ + "bzz-raw://6f0796c75d117770e220c136b60d96b5cf1d4875ccbbd0afb564ed27aa220335", + "dweb:/ipfs/QmQxYm6CMCqJiKsB3sguqWu8rggmaQgpuq8BZhAEveqNAM" + ] + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol": { + "keccak256": "0x7ac5dd35cbc776693eecfd8e7e86af139c7b054c43be4f97e6c8929417c17dba", + "license": "Apache-2.0", + "urls": [ + "bzz-raw://4a452d8acad5246538ac352887081d732098dcab869c79a43a5f916e7e76f353", + "dweb:/ipfs/QmeazDSxfKBSGyCGjmk7G79UbvYMRcbr2eUU9ThyqSvNhv" + ] + } + }, + "version": 1 +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/artifacts/build-info/c563de663c25f57de739af959840b24e.json b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/artifacts/build-info/c563de663c25f57de739af959840b24e.json new file mode 100644 index 0000000000..2dc39dd261 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/artifacts/build-info/c563de663c25f57de739af959840b24e.json @@ -0,0 +1,96556 @@ +{ + "id": "c563de663c25f57de739af959840b24e", + "_format": "hh-sol-build-info-1", + "solcVersion": "0.8.18", + "solcLongVersion": "0.8.18+commit.87f61d96", + "input": { + "language": "Solidity", + "sources": { + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.18;\n\nimport \"../utils/LibOptim.sol\";\n\nimport \"./commons/submodules/auth/SequenceBaseSig.sol\";\n\nimport \"./commons/ModuleAuth.sol\";\nimport \"./commons/ModuleCalls.sol\";\nimport \"./commons/ModuleCreator.sol\";\n\n\n/**\n * GuestModule implements a Sequence wallet without signatures, nonce or replay protection.\n * executing transactions using this wallet is not an authenticated process, and can be done by any address.\n *\n * @notice This contract is completely public with no security, designed to execute pre-signed transactions\n * and use Sequence tools without using the wallets.\n */\ncontract GuestModule is\n ModuleAuth,\n ModuleCalls,\n ModuleCreator\n{\n error DelegateCallNotAllowed(uint256 _index);\n error NotSupported();\n\n /**\n * @notice Allow any caller to execute an action\n * @param _txs Transactions to process\n */\n function execute(\n Transaction[] calldata _txs,\n uint256,\n bytes calldata\n ) public override {\n // Hash transaction bundle\n bytes32 txHash = SequenceBaseSig.subdigest(keccak256(abi.encode('guest:', _txs)));\n\n // Execute the transactions\n _executeGuest(txHash, _txs);\n }\n\n /**\n * @notice Allow any caller to execute an action\n * @param _txs Transactions to process\n */\n function selfExecute(\n Transaction[] calldata _txs\n ) public override {\n // Hash transaction bundle\n bytes32 txHash = SequenceBaseSig.subdigest(keccak256(abi.encode('self:', _txs)));\n\n // Execute the transactions\n _executeGuest(txHash, _txs);\n }\n\n /**\n * @notice Executes a list of transactions\n * @param _txHash Hash of the batch of transactions\n * @param _txs Transactions to execute\n */\n function _executeGuest(\n bytes32 _txHash,\n Transaction[] calldata _txs\n ) private {\n // Execute transaction\n uint256 size = _txs.length;\n for (uint256 i = 0; i < size; i++) {\n Transaction calldata transaction = _txs[i];\n\n if (transaction.delegateCall) revert DelegateCallNotAllowed(i);\n\n uint256 gasLimit = transaction.gasLimit;\n if (gasleft() < gasLimit) revert NotEnoughGas(i, gasLimit, gasleft());\n\n bool success = LibOptim.call(\n transaction.target,\n transaction.value,\n gasLimit == 0 ? gasleft() : gasLimit,\n transaction.data\n );\n\n if (success) {\n emit TxExecuted(_txHash, i);\n } else {\n _revertBytes(\n transaction.revertOnError,\n _txHash,\n i,\n LibOptim.returnData()\n );\n }\n }\n }\n\n /**\n * @notice Validates any signature image, because the wallet is public and has no owner.\n * @return true, all signatures are valid.\n */\n function _isValidImage(bytes32) internal override pure returns (bool) {\n return true;\n }\n\n /**\n * Not supported.\n */\n function _updateImageHash(bytes32) internal override virtual {\n revert NotSupported();\n }\n\n /**\n * @notice Query if a contract implements an interface\n * @param _interfaceID The interface identifier, as specified in ERC-165\n * @return `true` if the contract implements `_interfaceID`\n */\n function supportsInterface(\n bytes4 _interfaceID\n ) public override (\n ModuleAuth,\n ModuleCalls,\n ModuleCreator\n ) pure returns (bool) {\n return super.supportsInterface(_interfaceID);\n }\n}\n" + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.18;\n\nimport \"./interfaces/IModuleCreator.sol\";\n\nimport \"./ModuleSelfAuth.sol\";\nimport \"./ModuleERC165.sol\";\n\n\ncontract ModuleCreator is IModuleCreator, ModuleERC165, ModuleSelfAuth {\n event CreatedContract(address _contract);\n\n /**\n * @notice Creates a contract forwarding eth value\n * @param _code Creation code of the contract\n * @return addr The address of the created contract\n */\n function createContract(bytes memory _code) public override virtual payable onlySelf returns (address addr) {\n assembly { addr := create(callvalue(), add(_code, 32), mload(_code)) }\n if (addr == address(0)) revert CreateFailed(_code);\n emit CreatedContract(addr);\n }\n\n /**\n * @notice Query if a contract implements an interface\n * @param _interfaceID The interface identifier, as specified in ERC-165\n * @return `true` if the contract implements `_interfaceID`\n */\n function supportsInterface(bytes4 _interfaceID) public override virtual pure returns (bool) {\n if (_interfaceID == type(IModuleCreator).interfaceId) {\n return true;\n }\n\n return super.supportsInterface(_interfaceID);\n }\n}\n" + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.18;\n\nimport \"./ModuleSelfAuth.sol\";\nimport \"./ModuleStorage.sol\";\nimport \"./ModuleERC165.sol\";\nimport \"./ModuleNonce.sol\";\nimport \"./ModuleOnlyDelegatecall.sol\";\n\nimport \"./interfaces/IModuleCalls.sol\";\nimport \"./interfaces/IModuleAuth.sol\";\n\nimport \"./submodules/nonce/SubModuleNonce.sol\";\nimport \"./submodules/auth/SequenceBaseSig.sol\";\n\nimport \"../../utils/LibOptim.sol\";\n\n\nabstract contract ModuleCalls is IModuleCalls, IModuleAuth, ModuleERC165, ModuleOnlyDelegatecall, ModuleSelfAuth, ModuleNonce {\n /**\n * @notice Allow wallet owner to execute an action\n * @dev Relayers must ensure that the gasLimit specified for each transaction\n * is acceptable to them. A user could specify large enough that it could\n * consume all the gas available.\n * @param _txs Transactions to process\n * @param _nonce Signature nonce (may contain an encoded space)\n * @param _signature Encoded signature\n */\n function execute(\n Transaction[] calldata _txs,\n uint256 _nonce,\n bytes calldata _signature\n ) external override virtual onlyDelegatecall {\n // Validate and update nonce\n _validateNonce(_nonce);\n\n // Hash and verify transaction bundle\n (bool isValid, bytes32 txHash) = _signatureValidation(\n keccak256(\n abi.encode(\n _nonce,\n _txs\n )\n ),\n _signature\n );\n\n if (!isValid) {\n revert InvalidSignature(txHash, _signature);\n }\n\n // Execute the transactions\n _execute(txHash, _txs);\n }\n\n /**\n * @notice Allow wallet to execute an action\n * without signing the message\n * @param _txs Transactions to execute\n */\n function selfExecute(\n Transaction[] calldata _txs\n ) external override virtual onlySelf {\n // Hash transaction bundle\n bytes32 txHash = SequenceBaseSig.subdigest(\n keccak256(\n abi.encode('self:', _txs)\n )\n );\n\n // Execute the transactions\n _execute(txHash, _txs);\n }\n\n /**\n * @notice Executes a list of transactions\n * @param _txHash Hash of the batch of transactions\n * @param _txs Transactions to execute\n */\n function _execute(\n bytes32 _txHash,\n Transaction[] calldata _txs\n ) private {\n unchecked {\n // Execute transaction\n uint256 size = _txs.length;\n for (uint256 i = 0; i < size; i++) {\n Transaction calldata transaction = _txs[i];\n uint256 gasLimit = transaction.gasLimit;\n\n if (gasleft() < gasLimit) revert NotEnoughGas(i, gasLimit, gasleft());\n\n bool success;\n if (transaction.delegateCall) {\n success = LibOptim.delegatecall(\n transaction.target,\n gasLimit == 0 ? gasleft() : gasLimit,\n transaction.data\n );\n } else {\n success = LibOptim.call(\n transaction.target,\n transaction.value,\n gasLimit == 0 ? gasleft() : gasLimit,\n transaction.data\n );\n }\n\n if (success) {\n emit TxExecuted(_txHash, i);\n } else {\n // Avoid copy of return data until neccesary\n _revertBytes(\n transaction.revertOnError,\n _txHash,\n i,\n LibOptim.returnData()\n );\n }\n }\n }\n }\n\n /**\n * @notice Logs a failed transaction, reverts if the transaction is not optional\n * @param _revertOnError Signals if it should revert or just log\n * @param _txHash Hash of the transaction\n * @param _index Index of the transaction in the batch\n * @param _reason Encoded revert message\n */\n function _revertBytes(\n bool _revertOnError,\n bytes32 _txHash,\n uint256 _index,\n bytes memory _reason\n ) internal {\n if (_revertOnError) {\n assembly { revert(add(_reason, 0x20), mload(_reason)) }\n } else {\n emit TxFailed(_txHash, _index, _reason);\n }\n }\n\n /**\n * @notice Query if a contract implements an interface\n * @param _interfaceID The interface identifier, as specified in ERC-165\n * @return `true` if the contract implements `_interfaceID`\n */\n function supportsInterface(bytes4 _interfaceID) public override virtual pure returns (bool) {\n if (_interfaceID == type(IModuleCalls).interfaceId) {\n return true;\n }\n\n return super.supportsInterface(_interfaceID);\n }\n}\n" + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.18;\n\nimport \"../../utils/LibBytes.sol\";\nimport \"../../interfaces/IERC1271Wallet.sol\";\n\nimport \"./interfaces/IModuleAuth.sol\";\n\nimport \"./ModuleERC165.sol\";\n\nimport \"./submodules/auth/SequenceBaseSig.sol\";\nimport \"./submodules/auth/SequenceDynamicSig.sol\";\nimport \"./submodules/auth/SequenceNoChainIdSig.sol\";\nimport \"./submodules/auth/SequenceChainedSig.sol\";\n\n\nabstract contract ModuleAuth is\n IModuleAuth,\n ModuleERC165,\n IERC1271Wallet,\n SequenceChainedSig\n{\n using LibBytes for bytes;\n\n bytes1 internal constant LEGACY_TYPE = hex\"00\";\n bytes1 internal constant DYNAMIC_TYPE = hex\"01\";\n bytes1 internal constant NO_CHAIN_ID_TYPE = hex\"02\";\n bytes1 internal constant CHAINED_TYPE = hex\"03\";\n\n bytes4 internal constant SELECTOR_ERC1271_BYTES_BYTES = 0x20c13b0b;\n bytes4 internal constant SELECTOR_ERC1271_BYTES32_BYTES = 0x1626ba7e;\n\n /**\n * @notice Recovers the threshold, weight, imageHash, subdigest, and checkpoint of a signature.\n * @dev The signature must be prefixed with a type byte, which is used to determine the recovery method.\n *\n * @param _digest Digest of the signed data.\n * @param _signature A Sequence signature.\n *\n * @return threshold The required number of signatures needed to consider the signature valid.\n * @return weight The actual number of signatures collected in the signature.\n * @return imageHash The imageHash of the configuration that signed the message.\n * @return subdigest A modified version of the original digest, unique for each wallet/network.\n * @return checkpoint A nonce that is incremented every time a new configuration is set.\n */\n function signatureRecovery(\n bytes32 _digest,\n bytes calldata _signature\n ) public override virtual view returns (\n uint256 threshold,\n uint256 weight,\n bytes32 imageHash,\n bytes32 subdigest,\n uint256 checkpoint\n ) {\n bytes1 signatureType = _signature[0];\n\n if (signatureType == LEGACY_TYPE) {\n // networkId digest + base recover\n subdigest = SequenceBaseSig.subdigest(_digest);\n (threshold, weight, imageHash, checkpoint) = SequenceBaseSig.recover(subdigest, _signature);\n return (threshold, weight, imageHash, subdigest, checkpoint);\n }\n\n if (signatureType == DYNAMIC_TYPE) {\n // networkId digest + dynamic recover\n subdigest = SequenceBaseSig.subdigest(_digest);\n (threshold, weight, imageHash, checkpoint) = SequenceDynamicSig.recover(subdigest, _signature);\n return (threshold, weight, imageHash, subdigest, checkpoint);\n }\n\n if (signatureType == NO_CHAIN_ID_TYPE) {\n // noChainId digest + dynamic recover\n subdigest = SequenceNoChainIdSig.subdigest(_digest);\n (threshold, weight, imageHash, checkpoint) = SequenceDynamicSig.recover(subdigest, _signature);\n return (threshold, weight, imageHash, subdigest, checkpoint);\n }\n\n if (signatureType == CHAINED_TYPE) {\n // original digest + chained recover\n // (subdigest will be computed in the chained recover)\n return chainedRecover(_digest, _signature);\n }\n\n revert InvalidSignatureType(signatureType);\n }\n\n /**\n * @dev Validates a signature.\n *\n * @param _digest Digest of the signed data.\n * @param _signature A Sequence signature.\n *\n * @return isValid Indicates whether the signature is valid or not.\n * @return subdigest A modified version of the original digest, unique for each wallet/network.\n */\n function _signatureValidation(\n bytes32 _digest,\n bytes calldata _signature\n ) internal override virtual view returns (\n bool isValid,\n bytes32 subdigest\n ) {\n uint256 threshold; uint256 weight; bytes32 imageHash;\n (threshold, weight, imageHash, subdigest,) = signatureRecovery(_digest, _signature);\n isValid = weight >= threshold && _isValidImage(imageHash);\n }\n\n /**\n * @notice Verifies whether the provided signature is valid with respect to the provided data\n * @dev MUST return the correct magic value if the signature provided is valid for the provided data\n * > The bytes4 magic value to return when signature is valid is 0x20c13b0b : bytes4(keccak256(\"isValidSignature(bytes,bytes)\"))\n * @param _data Arbitrary length data signed on the behalf of address(this)\n * @param _signatures Signature byte array associated with _data.\n * Encoded as abi.encode(Signature[], Configs)\n * @return magicValue Magic value 0x20c13b0b if the signature is valid and 0x0 otherwise\n */\n function isValidSignature(\n bytes calldata _data,\n bytes calldata _signatures\n ) public override virtual view returns (bytes4) {\n // Validate signatures\n (bool isValid,) = _signatureValidation(keccak256(_data), _signatures);\n if (isValid) {\n return SELECTOR_ERC1271_BYTES_BYTES;\n }\n\n return bytes4(0);\n }\n\n /**\n * @notice Verifies whether the provided signature is valid with respect to the provided hash\n * @dev MUST return the correct magic value if the signature provided is valid for the provided hash\n * > The bytes4 magic value to return when signature is valid is 0x1626ba7e : bytes4(keccak256(\"isValidSignature(bytes32,bytes)\"))\n * @param _hash keccak256 hash that was signed\n * @param _signatures Signature byte array associated with _data.\n * Encoded as abi.encode(Signature[], Configs)\n * @return magicValue Magic value 0x1626ba7e if the signature is valid and 0x0 otherwise\n */\n function isValidSignature(\n bytes32 _hash,\n bytes calldata _signatures\n ) public override virtual view returns (bytes4) {\n // Validate signatures\n (bool isValid,) = _signatureValidation(_hash, _signatures);\n if (isValid) {\n return SELECTOR_ERC1271_BYTES32_BYTES;\n }\n\n return bytes4(0);\n }\n\n /**\n * @notice Query if a contract implements an interface\n * @param _interfaceID The interface identifier, as specified in ERC-165\n * @return `true` if the contract implements `_interfaceID`\n */\n function supportsInterface(bytes4 _interfaceID) public override virtual pure returns (bool) {\n if (\n _interfaceID == type(IModuleAuth).interfaceId ||\n _interfaceID == type(IERC1271Wallet).interfaceId\n ) {\n return true;\n }\n\n return super.supportsInterface(_interfaceID);\n }\n\n /**\n * @notice Updates the signers configuration of the wallet\n * @param _imageHash New required image hash of the signature\n */\n function updateImageHash(bytes32 _imageHash) external override virtual onlySelf {\n _updateImageHash(_imageHash);\n }\n}\n" + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.18;\n\nimport \"../../../../utils/SignatureValidator.sol\";\nimport \"../../../../utils/LibBytesPointer.sol\";\nimport \"../../../../utils/LibBytes.sol\";\nimport \"../../../../utils/LibOptim.sol\";\n\n\n/**\n * @title SequenceBaseSig Library\n * @author Agustin Aguilar (aa@horizon.io)\n * @notice A Solidity implementation for handling signatures in the Sequence protocol.\n */\nlibrary SequenceBaseSig {\n using LibBytesPointer for bytes;\n\n uint256 private constant FLAG_SIGNATURE = 0;\n uint256 private constant FLAG_ADDRESS = 1;\n uint256 private constant FLAG_DYNAMIC_SIGNATURE = 2;\n uint256 private constant FLAG_NODE = 3;\n uint256 private constant FLAG_BRANCH = 4;\n uint256 private constant FLAG_SUBDIGEST = 5;\n uint256 private constant FLAG_NESTED = 6;\n\n error InvalidNestedSignature(bytes32 _hash, address _addr, bytes _signature);\n error InvalidSignatureFlag(uint256 _flag);\n\n /**\n * @notice Generates a subdigest for the input digest (unique for this wallet and network).\n * @param _digest The input digest to generate the subdigest from.\n * @return bytes32 The subdigest generated from the input digest.\n */\n function subdigest(\n bytes32 _digest\n ) internal view returns (bytes32) {\n return keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n block.chainid,\n address(this),\n _digest\n )\n );\n }\n\n /**\n * @notice Generates the leaf for an address and weight.\n * @dev The leaf is generated by concatenating the address and weight.\n *\n * @param _addr The address to generate the leaf for.\n * @param _weight The weight to generate the leaf for.\n * @return bytes32 The leaf generated from the address and weight.\n */\n function _leafForAddressAndWeight(\n address _addr,\n uint96 _weight\n ) internal pure returns (bytes32) {\n unchecked {\n return bytes32(uint256(_weight) << 160 | uint256(uint160(_addr)));\n }\n }\n\n /**\n * @notice Generates the leaf for a hardcoded subdigest.\n * @dev The leaf is generated by hashing 'Sequence static digest:\\n' and the subdigest.\n * @param _subdigest The subdigest to generate the leaf for.\n * @return bytes32 The leaf generated from the hardcoded subdigest.\n */\n function _leafForHardcodedSubdigest(\n bytes32 _subdigest\n ) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked('Sequence static digest:\\n', _subdigest));\n }\n\n /**\n * @notice Generates the leaf for a nested tree node.\n * @dev The leaf is generated by hashing 'Sequence nested config:\\n', the node, the threshold and the weight.\n *\n * @param _node The root of the node to generate the leaf for.\n * @param _threshold The internal threshold of the tree.\n * @param _weight The external weight of the tree.\n * @return bytes32 The leaf generated from the nested tree.\n */\n function _leafForNested(\n bytes32 _node,\n uint256 _threshold,\n uint256 _weight\n ) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked('Sequence nested config:\\n', _node, _threshold, _weight));\n }\n\n /**\n * @notice Returns the weight and root of a signature branch.\n * @dev If the signature contains a hardcoded subdigest, and it matches the input digest, then the weight is set to 2 ** 256 - 1.\n *\n * @param _subdigest The digest to verify the signature against.\n * @param _signature The signature branch to recover.\n * @return weight The total weight of the recovered signatures.\n * @return root The root hash of the recovered configuration.\n */\n function recoverBranch(\n bytes32 _subdigest,\n bytes calldata _signature\n ) internal view returns (\n uint256 weight,\n bytes32 root\n ) {\n unchecked {\n uint256 rindex;\n\n // Iterate until the image is completed\n while (rindex < _signature.length) {\n // Read next item type\n uint256 flag;\n (flag, rindex) = _signature.readUint8(rindex);\n\n if (flag == FLAG_ADDRESS) {\n // Read plain address\n uint8 addrWeight; address addr;\n (addrWeight, addr, rindex) = _signature.readUint8Address(rindex);\n\n // Write weight and address to image\n bytes32 node = _leafForAddressAndWeight(addr, addrWeight);\n root = root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node;\n continue;\n }\n\n if (flag == FLAG_SIGNATURE) {\n // Read weight\n uint8 addrWeight;\n (addrWeight, rindex) = _signature.readUint8(rindex);\n\n // Read single signature and recover signer\n uint256 nrindex = rindex + 66;\n address addr = SignatureValidator.recoverSigner(_subdigest, _signature[rindex:nrindex]);\n rindex = nrindex;\n\n // Acumulate total weight of the signature\n weight += addrWeight;\n\n // Write weight and address to image\n bytes32 node = _leafForAddressAndWeight(addr, addrWeight);\n root = root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node;\n continue;\n }\n\n if (flag == FLAG_DYNAMIC_SIGNATURE) {\n // Read signer and weight\n uint8 addrWeight; address addr;\n (addrWeight, addr, rindex) = _signature.readUint8Address(rindex);\n\n // Read signature size\n uint256 size;\n (size, rindex) = _signature.readUint24(rindex);\n\n // Read dynamic size signature\n uint256 nrindex = rindex + size;\n if (!SignatureValidator.isValidSignature(_subdigest, addr, _signature[rindex:nrindex])) {\n revert InvalidNestedSignature(_subdigest, addr, _signature[rindex:nrindex]);\n }\n rindex = nrindex;\n\n // Acumulate total weight of the signature\n weight += addrWeight;\n\n // Write weight and address to image\n bytes32 node = _leafForAddressAndWeight(addr, addrWeight);\n root = root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node;\n continue;\n }\n\n if (flag == FLAG_NODE) {\n // Read node hash\n bytes32 node;\n (node, rindex) = _signature.readBytes32(rindex);\n root = root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node;\n continue;\n }\n\n if (flag == FLAG_BRANCH) {\n // Enter a branch of the signature merkle tree\n uint256 size;\n (size, rindex) = _signature.readUint24(rindex);\n uint256 nrindex = rindex + size;\n\n uint256 nweight; bytes32 node;\n (nweight, node) = recoverBranch(_subdigest, _signature[rindex:nrindex]);\n\n weight += nweight;\n root = LibOptim.fkeccak256(root, node);\n\n rindex = nrindex;\n continue;\n }\n\n if (flag == FLAG_NESTED) {\n // Enter a branch of the signature merkle tree\n // but with an internal threshold and an external fixed weight\n uint256 externalWeight;\n (externalWeight, rindex) = _signature.readUint8(rindex);\n\n uint256 internalThreshold;\n (internalThreshold, rindex) = _signature.readUint16(rindex);\n\n uint256 size;\n (size, rindex) = _signature.readUint24(rindex);\n uint256 nrindex = rindex + size;\n\n uint256 internalWeight; bytes32 internalRoot;\n (internalWeight, internalRoot) = recoverBranch(_subdigest, _signature[rindex:nrindex]);\n rindex = nrindex;\n\n if (internalWeight >= internalThreshold) {\n weight += externalWeight;\n }\n\n bytes32 node = _leafForNested(internalRoot, internalThreshold, externalWeight);\n root = root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node;\n\n continue;\n }\n\n if (flag == FLAG_SUBDIGEST) {\n // A hardcoded always accepted digest\n // it pushes the weight to the maximum\n bytes32 hardcoded;\n (hardcoded, rindex) = _signature.readBytes32(rindex);\n if (hardcoded == _subdigest) {\n weight = type(uint256).max;\n }\n\n bytes32 node = _leafForHardcodedSubdigest(hardcoded);\n root = root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node;\n continue;\n }\n\n revert InvalidSignatureFlag(flag);\n }\n }\n }\n\n /**\n * @notice Returns the threshold, weight, root, and checkpoint of a signature.\n * @dev To verify the signature, the weight must be greater than or equal to the threshold, and the root\n * must match the expected `imageHash` of the wallet.\n *\n * @param _subdigest The digest to verify the signature against.\n * @param _signature The signature to recover.\n * @return threshold The minimum weight required for the signature to be valid.\n * @return weight The total weight of the recovered signatures.\n * @return imageHash The root hash of the recovered configuration\n * @return checkpoint The checkpoint of the signature.\n */\n function recover(\n bytes32 _subdigest,\n bytes calldata _signature\n ) internal view returns (\n uint256 threshold,\n uint256 weight,\n bytes32 imageHash,\n uint256 checkpoint\n ) {\n unchecked {\n (weight, imageHash) = recoverBranch(_subdigest, _signature[6:]);\n\n // Threshold & checkpoint are the top nodes\n // (but they are first on the signature)\n threshold = LibBytes.readFirstUint16(_signature);\n checkpoint = LibBytes.readUint32(_signature, 2);\n\n imageHash = LibOptim.fkeccak256(imageHash, bytes32(threshold));\n imageHash = LibOptim.fkeccak256(imageHash, bytes32(checkpoint));\n }\n }\n}\n" + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.18;\n\n/**\n * @title Library for optimized EVM operations\n * @author Agustin Aguilar (aa@horizon.io)\n * @notice This library contains functions for optimizing certain EVM operations.\n */\nlibrary LibOptim {\n\n /**\n * @notice Computes the keccak256 hash of two 32-byte inputs.\n * @dev It uses only scratch memory space.\n * @param _a The first 32 bytes of the hash.\n * @param _b The second 32 bytes of the hash.\n * @return c The keccak256 hash of the two 32-byte inputs.\n */\n function fkeccak256(\n bytes32 _a,\n bytes32 _b\n ) internal pure returns (bytes32 c) {\n assembly {\n mstore(0, _a)\n mstore(32, _b)\n c := keccak256(0, 64)\n }\n }\n\n /**\n * @notice Returns the return data from the last call.\n * @return r The return data from the last call.\n */\n function returnData() internal pure returns (bytes memory r) {\n assembly {\n let size := returndatasize()\n r := mload(0x40)\n let start := add(r, 32)\n mstore(0x40, add(start, size))\n mstore(r, size)\n returndatacopy(start, 0, size)\n }\n }\n\n /**\n * @notice Calls another contract with the given parameters.\n * @dev This method doesn't increase the memory pointer.\n * @param _to The address of the contract to call.\n * @param _val The value to send to the contract.\n * @param _gas The amount of gas to provide for the call.\n * @param _data The data to send to the contract.\n * @return r The success status of the call.\n */\n function call(\n address _to,\n uint256 _val,\n uint256 _gas,\n bytes calldata _data\n ) internal returns (bool r) {\n assembly {\n let tmp := mload(0x40)\n calldatacopy(tmp, _data.offset, _data.length)\n\n r := call(\n _gas,\n _to,\n _val,\n tmp,\n _data.length,\n 0,\n 0\n )\n }\n }\n\n /**\n * @notice Calls another contract with the given parameters, using delegatecall.\n * @dev This method doesn't increase the memory pointer.\n * @param _to The address of the contract to call.\n * @param _gas The amount of gas to provide for the call.\n * @param _data The data to send to the contract.\n * @return r The success status of the call.\n */\n function delegatecall(\n address _to,\n uint256 _gas,\n bytes calldata _data\n ) internal returns (bool r) {\n assembly {\n let tmp := mload(0x40)\n calldatacopy(tmp, _data.offset, _data.length)\n\n r := delegatecall(\n _gas,\n _to,\n tmp,\n _data.length,\n 0,\n 0\n )\n }\n }\n}\n" + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.18;\n\n\n/**\n * @title Library for reading data from bytes arrays\n * @author Agustin Aguilar (aa@horizon.io)\n * @notice This library contains functions for reading data from bytes arrays.\n *\n * @dev These functions do not check if the input index is within the bounds of the data array.\n * Reading out of bounds may return dirty values.\n */\nlibrary LibBytes {\n\n /**\n * @notice Returns the bytes32 value at the given index in the input data.\n * @param data The input data.\n * @param index The index of the value to retrieve.\n * @return a The bytes32 value at the given index.\n */\n function readBytes32(\n bytes calldata data,\n uint256 index\n ) internal pure returns (\n bytes32 a\n ) {\n assembly {\n a := calldataload(add(data.offset, index))\n }\n }\n\n /**\n * @notice Returns the uint8 value at the given index in the input data.\n * @param data The input data.\n * @param index The index of the value to retrieve.\n * @return a The uint8 value at the given index.\n */\n function readUint8(\n bytes calldata data,\n uint256 index\n ) internal pure returns (\n uint8 a\n ) {\n assembly {\n let word := calldataload(add(index, data.offset))\n a := shr(248, word)\n }\n }\n\n /**\n * @notice Returns the first uint16 value in the input data.\n * @param data The input data.\n * @return a The first uint16 value in the input data.\n */\n function readFirstUint16(\n bytes calldata data\n ) internal pure returns (\n uint16 a\n ) {\n assembly {\n let word := calldataload(data.offset)\n a := shr(240, word)\n }\n }\n\n /**\n * @notice Returns the uint32 value at the given index in the input data.\n * @param data The input data.\n * @param index The index of the value to retrieve.\n * @return a The uint32 value at the given index.\n */\n function readUint32(\n bytes calldata data,\n uint256 index\n ) internal pure returns (\n uint32 a\n ) {\n assembly {\n let word := calldataload(add(index, data.offset))\n a := shr(224, word)\n }\n }\n}\n" + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.18;\n\n\n/**\n * @title Library for reading data from bytes arrays with a pointer\n * @author Agustin Aguilar (aa@horizon.io)\n * @notice This library contains functions for reading data from bytes arrays with a pointer.\n *\n * @dev These functions do not check if the input index is within the bounds of the data array.\n * Reading out of bounds may return dirty values.\n */\nlibrary LibBytesPointer {\n\n /**\n * @dev Returns the first uint16 value in the input data and updates the pointer.\n * @param _data The input data.\n * @return a The first uint16 value.\n * @return newPointer The new pointer.\n */\n function readFirstUint16(\n bytes calldata _data\n ) internal pure returns (\n uint16 a,\n uint256 newPointer\n ) {\n assembly {\n let word := calldataload(_data.offset)\n a := shr(240, word)\n newPointer := 2\n }\n }\n\n /**\n * @notice Returns the uint8 value at the given index in the input data and updates the pointer.\n * @param _data The input data.\n * @param _index The index of the value to retrieve.\n * @return a The uint8 value at the given index.\n * @return newPointer The new pointer.\n */\n function readUint8(\n bytes calldata _data,\n uint256 _index\n ) internal pure returns (\n uint8 a,\n uint256 newPointer\n ) {\n assembly {\n let word := calldataload(add(_index, _data.offset))\n a := shr(248, word)\n newPointer := add(_index, 1)\n }\n }\n\n /**\n * @notice Returns the uint8 value and the address at the given index in the input data and updates the pointer.\n * @param _data The input data.\n * @param _index The index of the value to retrieve.\n * @return a The uint8 value at the given index.\n * @return b The following address value.\n * @return newPointer The new pointer.\n */\n function readUint8Address(\n bytes calldata _data,\n uint256 _index\n ) internal pure returns (\n uint8 a,\n address b,\n uint256 newPointer\n ) {\n assembly {\n let word := calldataload(add(_index, _data.offset))\n a := shr(248, word)\n b := and(shr(88, word), 0xffffffffffffffffffffffffffffffffffffffff)\n newPointer := add(_index, 21)\n }\n }\n\n /**\n * @notice Returns the uint16 value at the given index in the input data and updates the pointer.\n * @param _data The input data.\n * @param _index The index of the value to retrieve.\n * @return a The uint16 value at the given index.\n * @return newPointer The new pointer.\n */\n function readUint16(\n bytes calldata _data,\n uint256 _index\n ) internal pure returns (\n uint16 a,\n uint256 newPointer\n ) {\n assembly {\n let word := calldataload(add(_index, _data.offset))\n a := and(shr(240, word), 0xffff)\n newPointer := add(_index, 2)\n }\n }\n\n /**\n * @notice Returns the uint24 value at the given index in the input data and updates the pointer.\n * @param _data The input data.\n * @param _index The index of the value to retrieve.\n * @return a The uint24 value at the given index.\n * @return newPointer The new pointer.\n */\n function readUint24(\n bytes calldata _data,\n uint256 _index\n ) internal pure returns (\n uint24 a,\n uint256 newPointer\n ) {\n assembly {\n let word := calldataload(add(_index, _data.offset))\n a := and(shr(232, word), 0xffffff)\n newPointer := add(_index, 3)\n }\n }\n\n /**\n * @notice Returns the uint64 value at the given index in the input data and updates the pointer.\n * @param _data The input data.\n * @param _index The index of the value to retrieve.\n * @return a The uint64 value at the given index.\n * @return newPointer The new pointer.\n */\n function readUint64(\n bytes calldata _data,\n uint256 _index\n ) internal pure returns (\n uint64 a,\n uint256 newPointer\n ) {\n assembly {\n let word := calldataload(add(_index, _data.offset))\n a := and(shr(192, word), 0xffffffffffffffff)\n newPointer := add(_index, 8)\n }\n }\n\n /**\n * @notice Returns the bytes32 value at the given index in the input data and updates the pointer.\n * @param _data The input data.\n * @param _pointer The index of the value to retrieve.\n * @return a The bytes32 value at the given index.\n * @return newPointer The new pointer.\n */\n function readBytes32(\n bytes calldata _data,\n uint256 _pointer\n ) internal pure returns (\n bytes32 a,\n uint256 newPointer\n ) {\n assembly {\n a := calldataload(add(_pointer, _data.offset))\n newPointer := add(_pointer, 32)\n }\n }\n}\n" + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.18;\n\nimport \"../interfaces/IERC1271Wallet.sol\";\n\nimport \"./LibBytes.sol\";\n\n/**\n * @dev Contains logic for signature validation.\n * Signatures from wallet contracts assume ERC-1271 support (https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1271.md)\n * Notes: Methods are strongly inspired by contracts in https://github.com/0xProject/0x-monorepo/blob/development/\n */\nlibrary SignatureValidator {\n // Errors\n error InvalidSignatureLength(bytes _signature);\n error EmptySignature();\n error InvalidSValue(bytes _signature, bytes32 _s);\n error InvalidVValue(bytes _signature, uint256 _v);\n error UnsupportedSignatureType(bytes _signature, uint256 _type, bool _recoverMode);\n error SignerIsAddress0(bytes _signature);\n\n using LibBytes for bytes;\n\n /***********************************|\n | Variables |\n |__________________________________*/\n\n // bytes4(keccak256(\"isValidSignature(bytes,bytes)\"))\n bytes4 constant internal ERC1271_MAGICVALUE = 0x20c13b0b;\n\n // bytes4(keccak256(\"isValidSignature(bytes32,bytes)\"))\n bytes4 constant internal ERC1271_MAGICVALUE_BYTES32 = 0x1626ba7e;\n\n // Allowed signature types.\n uint256 private constant SIG_TYPE_EIP712 = 1;\n uint256 private constant SIG_TYPE_ETH_SIGN = 2;\n uint256 private constant SIG_TYPE_WALLET_BYTES32 = 3;\n\n /***********************************|\n | Signature Functions |\n |__________________________________*/\n\n /**\n * @notice Recover the signer of hash, assuming it's an EOA account\n * @dev Only for SignatureType.EIP712 and SignatureType.EthSign signatures\n * @param _hash Hash that was signed\n * encoded as (bytes32 r, bytes32 s, uint8 v, ... , SignatureType sigType)\n */\n function recoverSigner(\n bytes32 _hash,\n bytes calldata _signature\n ) internal pure returns (address signer) {\n if (_signature.length != 66) revert InvalidSignatureLength(_signature);\n uint256 signatureType = _signature.readUint8(_signature.length - 1);\n\n // Variables are not scoped in Solidity.\n uint8 v = _signature.readUint8(64);\n bytes32 r = _signature.readBytes32(0);\n bytes32 s = _signature.readBytes32(32);\n\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n //\n // Source OpenZeppelin\n // https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/cryptography/ECDSA.sol\n\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n revert InvalidSValue(_signature, s);\n }\n\n if (v != 27 && v != 28) {\n revert InvalidVValue(_signature, v);\n }\n\n // Signature using EIP712\n if (signatureType == SIG_TYPE_EIP712) {\n signer = ecrecover(_hash, v, r, s);\n\n // Signed using web3.eth_sign() or Ethers wallet.signMessage()\n } else if (signatureType == SIG_TYPE_ETH_SIGN) {\n signer = ecrecover(\n keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", _hash)),\n v,\n r,\n s\n );\n\n } else {\n // We cannot recover the signer for any other signature type.\n revert UnsupportedSignatureType(_signature, signatureType, true);\n }\n\n // Prevent signer from being 0x0\n if (signer == address(0x0)) revert SignerIsAddress0(_signature);\n\n return signer;\n }\n\n /**\n * @notice Returns true if the provided signature is valid for the given signer.\n * @dev Supports SignatureType.EIP712, SignatureType.EthSign, and ERC1271 signatures\n * @param _hash Hash that was signed\n * @param _signer Address of the signer candidate\n * @param _signature Signature byte array\n */\n function isValidSignature(\n bytes32 _hash,\n address _signer,\n bytes calldata _signature\n ) internal view returns (bool valid) {\n if (_signature.length == 0) {\n revert EmptySignature();\n }\n\n uint256 signatureType = uint8(_signature[_signature.length - 1]);\n if (signatureType == SIG_TYPE_EIP712 || signatureType == SIG_TYPE_ETH_SIGN) {\n // Recover signer and compare with provided\n valid = recoverSigner(_hash, _signature) == _signer;\n\n } else if (signatureType == SIG_TYPE_WALLET_BYTES32) {\n // Remove signature type before calling ERC1271, restore after call\n valid = ERC1271_MAGICVALUE_BYTES32 == IERC1271Wallet(_signer).isValidSignature(_hash, _signature[0:_signature.length - 1]);\n\n } else {\n // We cannot validate any other signature type.\n // We revert because we can say nothing about its validity.\n revert UnsupportedSignatureType(_signature, signatureType, false);\n }\n }\n}\n" + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleERC165.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.18;\n\n\nabstract contract ModuleERC165 {\n /**\n * @notice Query if a contract implements an interface\n * @param _interfaceID The interface identifier, as specified in ERC-165\n * @dev Adding new hooks will not lead to them being reported by this function\n * without upgrading the wallet. In addition, developers must ensure that\n * all inherited contracts by the main module don't conflict and are accounted\n * to be supported by the supportsInterface method.\n * @return `true` if the contract implements `_interfaceID`\n */\n function supportsInterface(bytes4 _interfaceID) virtual public pure returns (bool) {\n return _interfaceID == this.supportsInterface.selector;\n }\n}\n" + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.18;\n\n\ncontract ModuleSelfAuth {\n error OnlySelfAuth(address _sender, address _self);\n\n modifier onlySelf() {\n if (msg.sender != address(this)) {\n revert OnlySelfAuth(msg.sender, address(this));\n }\n _;\n }\n}\n" + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCreator.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.18;\n\n\ninterface IModuleCreator {\n error CreateFailed(bytes _code);\n\n /**\n * @notice Creates a contract forwarding eth value\n * @param _code Creation code of the contract\n * @return addr The address of the created contract\n */\n function createContract(bytes calldata _code) external payable returns (address addr);\n}\n" + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.18;\n\n\nlibrary SubModuleNonce {\n // Nonce schema\n //\n // - space[160]:nonce[96]\n //\n uint256 internal constant NONCE_BITS = 96;\n bytes32 internal constant NONCE_MASK = bytes32(uint256(type(uint96).max));\n\n /**\n * @notice Decodes a raw nonce\n * @dev Schema: space[160]:type[96]\n * @param _rawNonce Nonce to be decoded\n * @return _space The nonce space of the raw nonce\n * @return _nonce The nonce of the raw nonce\n */\n function decodeNonce(uint256 _rawNonce) internal pure returns (\n uint256 _space,\n uint256 _nonce\n ) {\n unchecked {\n // Decode nonce\n _space = _rawNonce >> NONCE_BITS;\n _nonce = uint256(bytes32(_rawNonce) & NONCE_MASK);\n }\n }\n}\n" + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleAuth.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.18;\n\n\nabstract contract IModuleAuth {\n // IMAGE_HASH_KEY = keccak256(\"org.arcadeum.module.auth.upgradable.image.hash\");\n bytes32 internal constant IMAGE_HASH_KEY = bytes32(0xea7157fa25e3aa17d0ae2d5280fa4e24d421c61842aa85e45194e1145aa72bf8);\n\n event ImageHashUpdated(bytes32 newImageHash);\n\n // Errors\n error ImageHashIsZero();\n error InvalidSignatureType(bytes1 _type);\n\n function _signatureValidation(\n bytes32 _digest,\n bytes calldata _signature\n ) internal virtual view returns (\n bool isValid,\n bytes32 subdigest\n );\n\n function signatureRecovery(\n bytes32 _digest,\n bytes calldata _signature\n ) public virtual view returns (\n uint256 threshold,\n uint256 weight,\n bytes32 imageHash,\n bytes32 subdigest,\n uint256 checkpoint\n );\n\n /**\n * @notice Validates the signature image\n * @return true if the signature image is valid\n */\n function _isValidImage(bytes32) internal virtual view returns (bool) {\n return false;\n }\n\n /**\n * @notice Updates the signers configuration of the wallet\n * @param _imageHash New required image hash of the signature\n */\n function updateImageHash(bytes32 _imageHash) external virtual;\n\n /**\n * @notice Updates the signers configuration of the wallet\n * @param _imageHash New required image hash of the signature\n */\n function _updateImageHash(bytes32 _imageHash) internal virtual;\n}\n" + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCalls.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.18;\n\n\ninterface IModuleCalls {\n // Events\n event TxFailed(bytes32 indexed _tx, uint256 _index, bytes _reason);\n event TxExecuted(bytes32 indexed _tx, uint256 _index);\n\n // Errors\n error NotEnoughGas(uint256 _index, uint256 _requested, uint256 _available);\n error InvalidSignature(bytes32 _hash, bytes _signature);\n\n // Transaction structure\n struct Transaction {\n bool delegateCall; // Performs delegatecall\n bool revertOnError; // Reverts transaction bundle if tx fails\n uint256 gasLimit; // Maximum gas to be forwarded\n address target; // Address of the contract to call\n uint256 value; // Amount of ETH to pass with the call\n bytes data; // calldata to pass\n }\n\n /**\n * @notice Allow wallet owner to execute an action\n * @param _txs Transactions to process\n * @param _nonce Signature nonce (may contain an encoded space)\n * @param _signature Encoded signature\n */\n function execute(\n Transaction[] calldata _txs,\n uint256 _nonce,\n bytes calldata _signature\n ) external;\n\n /**\n * @notice Allow wallet to execute an action\n * without signing the message\n * @param _txs Transactions to execute\n */\n function selfExecute(\n Transaction[] calldata _txs\n ) external;\n}\n" + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleOnlyDelegatecall.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.18;\n\n\ncontract ModuleOnlyDelegatecall {\n address private immutable self;\n\n error OnlyDelegatecall();\n\n constructor() {\n self = address(this);\n }\n\n /**\n * @notice Modifier that only allows functions to be called via delegatecall.\n */\n modifier onlyDelegatecall() {\n if (address(this) == self) {\n revert OnlyDelegatecall();\n }\n _;\n }\n}\n" + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.18;\n\nimport \"./ModuleStorage.sol\";\n\nimport \"./submodules/nonce/SubModuleNonce.sol\";\n\n\ncontract ModuleNonce {\n // Events\n event NonceChange(uint256 _space, uint256 _newNonce);\n\n // Errors\n error BadNonce(uint256 _space, uint256 _provided, uint256 _current);\n\n // NONCE_KEY = keccak256(\"org.arcadeum.module.calls.nonce\");\n bytes32 private constant NONCE_KEY = bytes32(0x8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e);\n\n /**\n * @notice Returns the next nonce of the default nonce space\n * @dev The default nonce space is 0x00\n * @return The next nonce\n */\n function nonce() external virtual view returns (uint256) {\n return readNonce(0);\n }\n\n /**\n * @notice Returns the next nonce of the given nonce space\n * @param _space Nonce space, each space keeps an independent nonce count\n * @return The next nonce\n */\n function readNonce(uint256 _space) public virtual view returns (uint256) {\n return uint256(ModuleStorage.readBytes32Map(NONCE_KEY, bytes32(_space)));\n }\n\n /**\n * @notice Changes the next nonce of the given nonce space\n * @param _space Nonce space, each space keeps an independent nonce count\n * @param _nonce Nonce to write on the space\n */\n function _writeNonce(uint256 _space, uint256 _nonce) internal {\n ModuleStorage.writeBytes32Map(NONCE_KEY, bytes32(_space), bytes32(_nonce));\n }\n\n /**\n * @notice Verify if a nonce is valid\n * @param _rawNonce Nonce to validate (may contain an encoded space)\n */\n function _validateNonce(uint256 _rawNonce) internal virtual {\n // Retrieve current nonce for this wallet\n (uint256 space, uint256 providedNonce) = SubModuleNonce.decodeNonce(_rawNonce);\n\n uint256 currentNonce = readNonce(space);\n if (currentNonce != providedNonce) {\n revert BadNonce(space, providedNonce, currentNonce);\n }\n\n unchecked {\n uint256 newNonce = providedNonce + 1;\n\n _writeNonce(space, newNonce);\n emit NonceChange(space, newNonce);\n return;\n }\n }\n}\n" + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.18;\n\n\nlibrary ModuleStorage {\n function writeBytes32(bytes32 _key, bytes32 _val) internal {\n assembly { sstore(_key, _val) }\n }\n\n function readBytes32(bytes32 _key) internal view returns (bytes32 val) {\n assembly { val := sload(_key) }\n }\n\n function writeBytes32Map(bytes32 _key, bytes32 _subKey, bytes32 _val) internal {\n bytes32 key = keccak256(abi.encode(_key, _subKey));\n assembly { sstore(key, _val) }\n }\n\n function readBytes32Map(bytes32 _key, bytes32 _subKey) internal view returns (bytes32 val) {\n bytes32 key = keccak256(abi.encode(_key, _subKey));\n assembly { val := sload(key) }\n }\n}\n" + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.18;\n\nimport \"./SequenceBaseSig.sol\";\n\nimport \"../../interfaces/IModuleAuth.sol\";\n\nimport \"../../ModuleSelfAuth.sol\";\nimport \"../../ModuleStorage.sol\";\n\nimport \"../../../../utils/LibBytesPointer.sol\";\nimport \"../../../../utils/LibOptim.sol\";\n\n/**\n * @title Sequence chained auth recovery submodule\n * @author Agustin Aguilar (aa@horizon.io)\n * @notice Defines Sequence signatures that work by delegating control to new configurations.\n * @dev The delegations can be chained together, the first signature is the one that is used to validate\n * the message, the last signature must match the current on-chain configuration of the wallet.\n */\nabstract contract SequenceChainedSig is IModuleAuth, ModuleSelfAuth {\n using LibBytesPointer for bytes;\n\n bytes32 public constant SET_IMAGE_HASH_TYPE_HASH = keccak256(\"SetImageHash(bytes32 imageHash)\");\n\n error LowWeightChainedSignature(bytes _signature, uint256 threshold, uint256 _weight);\n error WrongChainedCheckpointOrder(uint256 _current, uint256 _prev);\n\n /**\n * @notice Defined the special token that must be signed to delegate control to a new configuration.\n * @param _imageHash The hash of the new configuration.\n * @return bytes32 The message hash to be signed.\n */\n function _hashSetImageHashStruct(bytes32 _imageHash) internal pure returns (bytes32) {\n return LibOptim.fkeccak256(SET_IMAGE_HASH_TYPE_HASH, _imageHash);\n }\n\n /**\n * @notice Returns the threshold, weight, root, and checkpoint of a (chained) signature.\n * \n * @dev This method return the `threshold`, `weight` and `imageHash` of the last signature in the chain.\n * Intermediate signatures are validated directly in this method. The `subdigest` is the one of the\n * first signature in the chain (since that's the one that is used to validate the message).\n *\n * @param _digest The digest to recover the signature from.\n * @param _signature The signature to recover.\n * @return threshold The threshold of the (last) signature.\n * @return weight The weight of the (last) signature.\n * @return imageHash The image hash of the (last) signature.\n * @return subdigest The subdigest of the (first) signature in the chain.\n * @return checkpoint The checkpoint of the (last) signature.\n */\n function chainedRecover(\n bytes32 _digest,\n bytes calldata _signature\n ) internal view returns (\n uint256 threshold,\n uint256 weight,\n bytes32 imageHash,\n bytes32 subdigest,\n uint256 checkpoint\n ) {\n uint256 rindex = 1;\n uint256 sigSize;\n\n //\n // First signature out of the loop\n //\n\n // First uint24 is the size of the signature\n (sigSize, rindex) = _signature.readUint24(rindex);\n uint256 nrindex = sigSize + rindex;\n\n (\n threshold,\n weight,\n imageHash,\n subdigest,\n checkpoint\n ) = signatureRecovery(\n _digest,\n _signature[rindex:nrindex]\n );\n\n if (weight < threshold) {\n revert LowWeightChainedSignature(_signature[rindex:nrindex], threshold, weight);\n }\n\n rindex = nrindex;\n\n // The following signatures are handled by this loop.\n // This is done this way because the first signature does not have a\n // checkpoint to be validated against.\n while (rindex < _signature.length) {\n // First uint24 is the size of the signature\n (sigSize, rindex) = _signature.readUint24(rindex);\n nrindex = sigSize + rindex;\n\n uint256 nextCheckpoint;\n\n (\n threshold,\n weight,\n imageHash,,\n // Do not change the subdigest;\n // it should remain that of the first signature.\n nextCheckpoint\n ) = signatureRecovery(\n _hashSetImageHashStruct(imageHash),\n _signature[rindex:nrindex]\n );\n\n // Validate signature\n if (weight < threshold) {\n revert LowWeightChainedSignature(_signature[rindex:nrindex], threshold, weight);\n }\n\n // Checkpoints must be provided in descending order\n // since the first signature is the one that is used to validate the message\n // and the last signature is the one that is used to validate the current configuration\n if (nextCheckpoint >= checkpoint) {\n revert WrongChainedCheckpointOrder(nextCheckpoint, checkpoint);\n }\n\n checkpoint = nextCheckpoint;\n rindex = nrindex;\n }\n }\n}\n" + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.18;\n\n\nlibrary SequenceNoChainIdSig {\n\n /**\n * @notice Computes a subdigest for a Sequence signature that works on all chains.\n * @dev The subdigest is computed by removing the chain ID from the digest (using 0 instead).\n * @param _digest The digest of the chain of signatures.\n * @return bytes32 The subdigest with no chain ID.\n */\n function subdigest(bytes32 _digest) internal view returns (bytes32) {\n return keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n uint256(0),\n address(this),\n _digest\n )\n );\n }\n}\n" + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.18;\n\nimport \"./SequenceBaseSig.sol\";\n\n\nlibrary SequenceDynamicSig {\n\n /**\n * @notice Recover a \"dynamically encoded\" Sequence signature.\n * @dev The Signature is stripped of the first byte, which is the encoding flag.\n *\n * @param _subdigest The digest of the signature.\n * @param _signature The Sequence signature.\n * @return threshold The threshold weight required to validate the signature.\n * @return weight The weight of the signature.\n * @return imageHash The hash of the recovered configuration.\n * @return checkpoint The checkpoint of the configuration.\n */\n function recover(\n bytes32 _subdigest,\n bytes calldata _signature\n ) internal view returns (\n uint256 threshold,\n uint256 weight,\n bytes32 imageHash,\n uint256 checkpoint\n ) {\n return SequenceBaseSig.recover(_subdigest, _signature[1:]);\n }\n}\n" + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/interfaces/IERC1271Wallet.sol": { + "content": "// SPDX-License-Identifier: Apache-2.0\npragma solidity 0.8.18;\n\n\ninterface IERC1271Wallet {\n\n /**\n * @notice Verifies whether the provided signature is valid with respect to the provided data\n * @dev MUST return the correct magic value if the signature provided is valid for the provided data\n * > The bytes4 magic value to return when signature is valid is 0x20c13b0b : bytes4(keccak256(\"isValidSignature(bytes,bytes)\")\n * > This function MAY modify Ethereum's state\n * @param _data Arbitrary length data signed on the behalf of address(this)\n * @param _signature Signature byte array associated with _data\n * @return magicValue Magic value 0x20c13b0b if the signature is valid and 0x0 otherwise\n */\n function isValidSignature(\n bytes calldata _data,\n bytes calldata _signature)\n external\n view\n returns (bytes4 magicValue);\n\n /**\n * @notice Verifies whether the provided signature is valid with respect to the provided hash\n * @dev MUST return the correct magic value if the signature provided is valid for the provided hash\n * > The bytes4 magic value to return when signature is valid is 0x20c13b0b : bytes4(keccak256(\"isValidSignature(bytes,bytes)\")\n * > This function MAY modify Ethereum's state\n * @param _hash keccak256 hash that was signed\n * @param _signature Signature byte array associated with _data\n * @return magicValue Magic value 0x20c13b0b if the signature is valid and 0x0 otherwise\n */\n function isValidSignature(\n bytes32 _hash,\n bytes calldata _signature)\n external\n view\n returns (bytes4 magicValue);\n}" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 500000 + }, + "outputSelection": { + "*": { + "": [ + "ast" + ], + "*": [ + "abi", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.legacyAssembly", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "evm.gasEstimates", + "evm.assembly" + ] + } + }, + "remappings": [ + "@0xsequence/contracts-library/=src/", + "ds-test/=lib/forge-std/lib/ds-test/src/", + "forge-std/=lib/forge-std/src/", + "murky/=lib/murky/src/", + "@0xsequence/erc20-meta-token/=lib/0xsequence/erc20-meta-token/src/", + "@0xsequence/erc-1155/=lib/0xsequence/erc-1155/src/", + "erc721a/=lib/chiru-labs/erc721a/", + "erc721a-upgradeable/=lib/chiru-labs/erc721a-upgradeable/", + "@openzeppelin/=lib/openzeppelin/", + "solady/=lib/solady/src/" + ] + } + }, + "output": { + "contracts": { + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/interfaces/IERC1271Wallet.sol": { + "IERC1271Wallet": { + "abi": [ + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "isValidSignature", + "outputs": [ + { + "internalType": "bytes4", + "name": "magicValue", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "isValidSignature", + "outputs": [ + { + "internalType": "bytes4", + "name": "magicValue", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "devdoc": { + "kind": "dev", + "methods": { + "isValidSignature(bytes,bytes)": { + "details": "MUST return the correct magic value if the signature provided is valid for the provided data > The bytes4 magic value to return when signature is valid is 0x20c13b0b : bytes4(keccak256(\"isValidSignature(bytes,bytes)\") > This function MAY modify Ethereum's state", + "params": { + "_data": "Arbitrary length data signed on the behalf of address(this)", + "_signature": "Signature byte array associated with _data" + }, + "returns": { + "magicValue": "Magic value 0x20c13b0b if the signature is valid and 0x0 otherwise" + } + }, + "isValidSignature(bytes32,bytes)": { + "details": "MUST return the correct magic value if the signature provided is valid for the provided hash > The bytes4 magic value to return when signature is valid is 0x20c13b0b : bytes4(keccak256(\"isValidSignature(bytes,bytes)\") > This function MAY modify Ethereum's state", + "params": { + "_hash": "keccak256 hash that was signed", + "_signature": "Signature byte array associated with _data" + }, + "returns": { + "magicValue": "Magic value 0x20c13b0b if the signature is valid and 0x0 otherwise" + } + } + }, + "version": 1 + }, + "evm": { + "assembly": "", + "bytecode": { + "functionDebugData": {}, + "generatedSources": [], + "linkReferences": {}, + "object": "", + "opcodes": "", + "sourceMap": "" + }, + "deployedBytecode": { + "functionDebugData": {}, + "generatedSources": [], + "immutableReferences": {}, + "linkReferences": {}, + "object": "", + "opcodes": "", + "sourceMap": "" + }, + "gasEstimates": null, + "legacyAssembly": null, + "methodIdentifiers": { + "isValidSignature(bytes,bytes)": "20c13b0b", + "isValidSignature(bytes32,bytes)": "1626ba7e" + } + }, + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_hash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"isValidSignature\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"magicValue\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"isValidSignature\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"magicValue\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"isValidSignature(bytes,bytes)\":{\"details\":\"MUST return the correct magic value if the signature provided is valid for the provided data > The bytes4 magic value to return when signature is valid is 0x20c13b0b : bytes4(keccak256(\\\"isValidSignature(bytes,bytes)\\\") > This function MAY modify Ethereum's state\",\"params\":{\"_data\":\"Arbitrary length data signed on the behalf of address(this)\",\"_signature\":\"Signature byte array associated with _data\"},\"returns\":{\"magicValue\":\"Magic value 0x20c13b0b if the signature is valid and 0x0 otherwise\"}},\"isValidSignature(bytes32,bytes)\":{\"details\":\"MUST return the correct magic value if the signature provided is valid for the provided hash > The bytes4 magic value to return when signature is valid is 0x20c13b0b : bytes4(keccak256(\\\"isValidSignature(bytes,bytes)\\\") > This function MAY modify Ethereum's state\",\"params\":{\"_hash\":\"keccak256 hash that was signed\",\"_signature\":\"Signature byte array associated with _data\"},\"returns\":{\"magicValue\":\"Magic value 0x20c13b0b if the signature is valid and 0x0 otherwise\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"isValidSignature(bytes,bytes)\":{\"notice\":\"Verifies whether the provided signature is valid with respect to the provided data\"},\"isValidSignature(bytes32,bytes)\":{\"notice\":\"Verifies whether the provided signature is valid with respect to the provided hash\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/interfaces/IERC1271Wallet.sol\":\"IERC1271Wallet\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":500000},\"remappings\":[\":@0xsequence/contracts-library/=src/\",\":@0xsequence/erc-1155/=lib/0xsequence/erc-1155/src/\",\":@0xsequence/erc20-meta-token/=lib/0xsequence/erc20-meta-token/src/\",\":@openzeppelin/=lib/openzeppelin/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc721a-upgradeable/=lib/chiru-labs/erc721a-upgradeable/\",\":erc721a/=lib/chiru-labs/erc721a/\",\":forge-std/=lib/forge-std/src/\",\":murky/=lib/murky/src/\",\":solady/=lib/solady/src/\"]},\"sources\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/interfaces/IERC1271Wallet.sol\":{\"keccak256\":\"0x2d7881bca678833feb385fd59e5d8ad6d596160ab51daa7030372654b3dbc38c\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://010f44c05b7285a55de939f9989727d53dfb87fd2d2534a832a70e0e081bb5f1\",\"dweb:/ipfs/QmQcujWErxjktsKyyiTySaFuR7Vaq6fUA9SUzPkde2txVK\"]}},\"version\":1}", + "storageLayout": { + "storage": [], + "types": null + }, + "userdoc": { + "kind": "user", + "methods": { + "isValidSignature(bytes,bytes)": { + "notice": "Verifies whether the provided signature is valid with respect to the provided data" + }, + "isValidSignature(bytes32,bytes)": { + "notice": "Verifies whether the provided signature is valid with respect to the provided hash" + } + }, + "version": 1 + } + } + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol": { + "GuestModule": { + "abi": [ + { + "inputs": [ + { + "internalType": "uint256", + "name": "_space", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_provided", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_current", + "type": "uint256" + } + ], + "name": "BadNonce", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_code", + "type": "bytes" + } + ], + "name": "CreateFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_index", + "type": "uint256" + } + ], + "name": "DelegateCallNotAllowed", + "type": "error" + }, + { + "inputs": [], + "name": "EmptySignature", + "type": "error" + }, + { + "inputs": [], + "name": "ImageHashIsZero", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "_addr", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "InvalidNestedSignature", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + }, + { + "internalType": "bytes32", + "name": "_s", + "type": "bytes32" + } + ], + "name": "InvalidSValue", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "InvalidSignature", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_flag", + "type": "uint256" + } + ], + "name": "InvalidSignatureFlag", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "InvalidSignatureLength", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes1", + "name": "_type", + "type": "bytes1" + } + ], + "name": "InvalidSignatureType", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_v", + "type": "uint256" + } + ], + "name": "InvalidVValue", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "threshold", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_weight", + "type": "uint256" + } + ], + "name": "LowWeightChainedSignature", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_index", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_requested", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_available", + "type": "uint256" + } + ], + "name": "NotEnoughGas", + "type": "error" + }, + { + "inputs": [], + "name": "NotSupported", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyDelegatecall", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_sender", + "type": "address" + }, + { + "internalType": "address", + "name": "_self", + "type": "address" + } + ], + "name": "OnlySelfAuth", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "SignerIsAddress0", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_type", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_recoverMode", + "type": "bool" + } + ], + "name": "UnsupportedSignatureType", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_current", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_prev", + "type": "uint256" + } + ], + "name": "WrongChainedCheckpointOrder", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_contract", + "type": "address" + } + ], + "name": "CreatedContract", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "newImageHash", + "type": "bytes32" + } + ], + "name": "ImageHashUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_space", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_newNonce", + "type": "uint256" + } + ], + "name": "NonceChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "_tx", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_index", + "type": "uint256" + } + ], + "name": "TxExecuted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "_tx", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_index", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_reason", + "type": "bytes" + } + ], + "name": "TxFailed", + "type": "event" + }, + { + "inputs": [], + "name": "SET_IMAGE_HASH_TYPE_HASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_code", + "type": "bytes" + } + ], + "name": "createContract", + "outputs": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bool", + "name": "delegateCall", + "type": "bool" + }, + { + "internalType": "bool", + "name": "revertOnError", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + }, + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "internalType": "struct IModuleCalls.Transaction[]", + "name": "_txs", + "type": "tuple[]" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "execute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_signatures", + "type": "bytes" + } + ], + "name": "isValidSignature", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "_signatures", + "type": "bytes" + } + ], + "name": "isValidSignature", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_space", + "type": "uint256" + } + ], + "name": "readNonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bool", + "name": "delegateCall", + "type": "bool" + }, + { + "internalType": "bool", + "name": "revertOnError", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + }, + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "internalType": "struct IModuleCalls.Transaction[]", + "name": "_txs", + "type": "tuple[]" + } + ], + "name": "selfExecute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_digest", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "signatureRecovery", + "outputs": [ + { + "internalType": "uint256", + "name": "threshold", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "weight", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "imageHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "subdigest", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "checkpoint", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceID", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_imageHash", + "type": "bytes32" + } + ], + "name": "updateImageHash", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "devdoc": { + "kind": "dev", + "methods": { + "createContract(bytes)": { + "params": { + "_code": "Creation code of the contract" + }, + "returns": { + "addr": "The address of the created contract" + } + }, + "execute((bool,bool,uint256,address,uint256,bytes)[],uint256,bytes)": { + "params": { + "_txs": "Transactions to process" + } + }, + "isValidSignature(bytes,bytes)": { + "details": "MUST return the correct magic value if the signature provided is valid for the provided data > The bytes4 magic value to return when signature is valid is 0x20c13b0b : bytes4(keccak256(\"isValidSignature(bytes,bytes)\"))", + "params": { + "_data": "Arbitrary length data signed on the behalf of address(this)", + "_signatures": "Signature byte array associated with _data. Encoded as abi.encode(Signature[], Configs)" + }, + "returns": { + "_0": "magicValue Magic value 0x20c13b0b if the signature is valid and 0x0 otherwise" + } + }, + "isValidSignature(bytes32,bytes)": { + "details": "MUST return the correct magic value if the signature provided is valid for the provided hash > The bytes4 magic value to return when signature is valid is 0x1626ba7e : bytes4(keccak256(\"isValidSignature(bytes32,bytes)\"))", + "params": { + "_hash": "keccak256 hash that was signed", + "_signatures": "Signature byte array associated with _data. Encoded as abi.encode(Signature[], Configs)" + }, + "returns": { + "_0": "magicValue Magic value 0x1626ba7e if the signature is valid and 0x0 otherwise" + } + }, + "nonce()": { + "details": "The default nonce space is 0x00", + "returns": { + "_0": "The next nonce" + } + }, + "readNonce(uint256)": { + "params": { + "_space": "Nonce space, each space keeps an independent nonce count" + }, + "returns": { + "_0": "The next nonce" + } + }, + "selfExecute((bool,bool,uint256,address,uint256,bytes)[])": { + "params": { + "_txs": "Transactions to process" + } + }, + "signatureRecovery(bytes32,bytes)": { + "details": "The signature must be prefixed with a type byte, which is used to determine the recovery method.", + "params": { + "_digest": "Digest of the signed data.", + "_signature": "A Sequence signature." + }, + "returns": { + "checkpoint": "A nonce that is incremented every time a new configuration is set.", + "imageHash": "The imageHash of the configuration that signed the message.", + "subdigest": "A modified version of the original digest, unique for each wallet/network.", + "threshold": "The required number of signatures needed to consider the signature valid.", + "weight": "The actual number of signatures collected in the signature." + } + }, + "supportsInterface(bytes4)": { + "params": { + "_interfaceID": "The interface identifier, as specified in ERC-165" + }, + "returns": { + "_0": "`true` if the contract implements `_interfaceID`" + } + }, + "updateImageHash(bytes32)": { + "params": { + "_imageHash": "New required image hash of the signature" + } + } + }, + "version": 1 + }, + "evm": { + "assembly": " /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":640:3333 contract GuestModule is... */\n mstore(0x40, 0xa0)\n callvalue\n dup1\n iszero\n tag_1\n jumpi\n 0x00\n dup1\n revert\ntag_1:\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleOnlyDelegatecall.sol\":200:204 this */\n address\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleOnlyDelegatecall.sol\":185:205 self = address(this) */\n 0x80\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":640:3333 contract GuestModule is... */\n mload(0x80)\n codecopy(0x00, dataOffset(sub_0), dataSize(sub_0))\n 0x00\n assignImmutable(\"0x4ffc9d227228e624d76834105f24ceb5cb9c5a8675150ad2031c88a10259e303\")\n return(0x00, dataSize(sub_0))\nstop\n\nsub_0: assembly {\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":640:3333 contract GuestModule is... */\n mstore(0x40, 0x80)\n jumpi(tag_1, lt(calldatasize, 0x04))\n shr(0xe0, calldataload(0x00))\n dup1\n 0x61c2926c\n gt\n tag_13\n jumpi\n dup1\n 0x8c3f5563\n gt\n tag_14\n jumpi\n dup1\n 0x8c3f5563\n eq\n tag_10\n jumpi\n dup1\n 0x90042baf\n eq\n tag_11\n jumpi\n dup1\n 0xaffed0e0\n eq\n tag_12\n jumpi\n 0x00\n dup1\n revert\n tag_14:\n dup1\n 0x61c2926c\n eq\n tag_7\n jumpi\n dup1\n 0x7a9a1628\n eq\n tag_8\n jumpi\n dup1\n 0x853c5068\n eq\n tag_9\n jumpi\n 0x00\n dup1\n revert\n tag_13:\n dup1\n 0x20c13b0b\n gt\n tag_15\n jumpi\n dup1\n 0x20c13b0b\n eq\n tag_4\n jumpi\n dup1\n 0x29561426\n eq\n tag_5\n jumpi\n dup1\n 0x57c56d6b\n eq\n tag_6\n jumpi\n 0x00\n dup1\n revert\n tag_15:\n dup1\n 0x01ffc9a7\n eq\n tag_2\n jumpi\n dup1\n 0x1626ba7e\n eq\n tag_3\n jumpi\n tag_1:\n 0x00\n dup1\n revert\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":3127:3331 function supportsInterface(... */\n tag_2:\n callvalue\n dup1\n iszero\n tag_16\n jumpi\n 0x00\n dup1\n revert\n tag_16:\n pop\n tag_17\n tag_18\n calldatasize\n 0x04\n tag_19\n jump\t// in\n tag_18:\n tag_20\n jump\t// in\n tag_17:\n mload(0x40)\n /* \"#utility.yul\":611:625 */\n swap1\n iszero\n /* \"#utility.yul\":604:626 */\n iszero\n /* \"#utility.yul\":586:627 */\n dup2\n mstore\n /* \"#utility.yul\":574:576 */\n 0x20\n /* \"#utility.yul\":559:577 */\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":3127:3331 function supportsInterface(... */\n tag_21:\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n return\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":5489:5805 function isValidSignature(... */\n tag_3:\n callvalue\n dup1\n iszero\n tag_23\n jumpi\n 0x00\n dup1\n revert\n tag_23:\n pop\n tag_24\n tag_25\n calldatasize\n 0x04\n tag_26\n jump\t// in\n tag_25:\n tag_27\n jump\t// in\n tag_24:\n mload(0x40)\n /* \"#utility.yul\":1646:1712 */\n 0xffffffff00000000000000000000000000000000000000000000000000000000\n /* \"#utility.yul\":1634:1713 */\n swap1\n swap2\n and\n /* \"#utility.yul\":1616:1714 */\n dup2\n mstore\n /* \"#utility.yul\":1604:1606 */\n 0x20\n /* \"#utility.yul\":1589:1607 */\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":5489:5805 function isValidSignature(... */\n tag_21\n /* \"#utility.yul\":1472:1720 */\n jump\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":4525:4857 function isValidSignature(... */\n tag_4:\n callvalue\n dup1\n iszero\n tag_30\n jumpi\n 0x00\n dup1\n revert\n tag_30:\n pop\n tag_24\n tag_32\n calldatasize\n 0x04\n tag_33\n jump\t// in\n tag_32:\n tag_34\n jump\t// in\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":6456:6575 function updateImageHash(bytes32 _imageHash) external override virtual onlySelf {... */\n tag_5:\n callvalue\n dup1\n iszero\n tag_36\n jumpi\n 0x00\n dup1\n revert\n tag_36:\n pop\n tag_37\n tag_38\n calldatasize\n 0x04\n tag_39\n jump\t// in\n tag_38:\n tag_40\n jump\t// in\n tag_37:\n stop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":811:906 bytes32 public constant SET_IMAGE_HASH_TYPE_HASH = keccak256(\"SetImageHash(bytes32 imageHash)\") */\n tag_6:\n callvalue\n dup1\n iszero\n tag_41\n jumpi\n 0x00\n dup1\n revert\n tag_41:\n pop\n tag_42\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":862:906 keccak256(\"SetImageHash(bytes32 imageHash)\") */\n 0x8713a7c4465f6fbee2b6e9d6646d1d9f83fec929edfc4baf661f3c865bdd04d1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":811:906 bytes32 public constant SET_IMAGE_HASH_TYPE_HASH = keccak256(\"SetImageHash(bytes32 imageHash)\") */\n dup2\n jump\n tag_42:\n mload(0x40)\n /* \"#utility.yul\":2778:2803 */\n swap1\n dup2\n mstore\n /* \"#utility.yul\":2766:2768 */\n 0x20\n /* \"#utility.yul\":2751:2769 */\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":811:906 bytes32 public constant SET_IMAGE_HASH_TYPE_HASH = keccak256(\"SetImageHash(bytes32 imageHash)\") */\n tag_21\n /* \"#utility.yul\":2632:2809 */\n jump\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1290:1552 function selfExecute(... */\n tag_7:\n callvalue\n dup1\n iszero\n tag_46\n jumpi\n 0x00\n dup1\n revert\n tag_46:\n pop\n tag_37\n tag_48\n calldatasize\n 0x04\n tag_49\n jump\t// in\n tag_48:\n tag_50\n jump\t// in\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":890:1182 function execute(... */\n tag_8:\n callvalue\n dup1\n iszero\n tag_51\n jumpi\n 0x00\n dup1\n revert\n tag_51:\n pop\n tag_37\n tag_53\n calldatasize\n 0x04\n tag_54\n jump\t// in\n tag_53:\n tag_55\n jump\t// in\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":1675:3161 function signatureRecovery(... */\n tag_9:\n callvalue\n dup1\n iszero\n tag_56\n jumpi\n 0x00\n dup1\n revert\n tag_56:\n pop\n tag_57\n tag_58\n calldatasize\n 0x04\n tag_26\n jump\t// in\n tag_58:\n tag_59\n jump\t// in\n tag_57:\n 0x40\n dup1\n mload\n /* \"#utility.yul\":4827:4852 */\n swap6\n dup7\n mstore\n /* \"#utility.yul\":4883:4885 */\n 0x20\n /* \"#utility.yul\":4868:4886 */\n dup7\n add\n /* \"#utility.yul\":4861:4895 */\n swap5\n swap1\n swap5\n mstore\n /* \"#utility.yul\":4911:4929 */\n swap3\n dup5\n add\n /* \"#utility.yul\":4904:4938 */\n swap2\n swap1\n swap2\n mstore\n /* \"#utility.yul\":4969:4971 */\n 0x60\n /* \"#utility.yul\":4954:4972 */\n dup4\n add\n /* \"#utility.yul\":4947:4981 */\n mstore\n /* \"#utility.yul\":5012:5015 */\n 0x80\n /* \"#utility.yul\":4997:5016 */\n dup3\n add\n /* \"#utility.yul\":4990:5025 */\n mstore\n /* \"#utility.yul\":4814:4817 */\n 0xa0\n /* \"#utility.yul\":4799:4818 */\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":1675:3161 function signatureRecovery(... */\n tag_21\n /* \"#utility.yul\":4568:5031 */\n jump\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":938:1094 function readNonce(uint256 _space) public virtual view returns (uint256) {... */\n tag_10:\n callvalue\n dup1\n iszero\n tag_62\n jumpi\n 0x00\n dup1\n revert\n tag_62:\n pop\n tag_42\n tag_64\n calldatasize\n 0x04\n tag_39\n jump\t// in\n tag_64:\n tag_66\n jump\t// in\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":456:732 function createContract(bytes memory _code) public override virtual payable onlySelf returns (address addr) {... */\n tag_11:\n tag_69\n tag_70\n calldatasize\n 0x04\n tag_71\n jump\t// in\n tag_70:\n tag_72\n jump\t// in\n tag_69:\n mload(0x40)\n /* \"#utility.yul\":6753:6795 */\n 0xffffffffffffffffffffffffffffffffffffffff\n /* \"#utility.yul\":6741:6796 */\n swap1\n swap2\n and\n /* \"#utility.yul\":6723:6797 */\n dup2\n mstore\n /* \"#utility.yul\":6711:6713 */\n 0x20\n /* \"#utility.yul\":6696:6714 */\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":456:732 function createContract(bytes memory _code) public override virtual payable onlySelf returns (address addr) {... */\n tag_21\n /* \"#utility.yul\":6577:6803 */\n jump\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":670:757 function nonce() external virtual view returns (uint256) {... */\n tag_12:\n callvalue\n dup1\n iszero\n tag_75\n jumpi\n 0x00\n dup1\n revert\n tag_75:\n pop\n tag_42\n tag_77\n jump\t// in\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":3127:3331 function supportsInterface(... */\n tag_20:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":3270:3274 bool */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":3289:3326 super.supportsInterface(_interfaceID) */\n tag_80\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":3313:3325 _interfaceID */\n dup3\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":3289:3312 super.supportsInterface */\n tag_81\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":3289:3326 super.supportsInterface(_interfaceID) */\n jump\t// in\n tag_80:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":3282:3326 return super.supportsInterface(_interfaceID) */\n swap3\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":3127:3331 function supportsInterface(... */\n swap2\n pop\n pop\n jump\t// out\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":5489:5805 function isValidSignature(... */\n tag_27:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":5608:5614 bytes4 */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":5650:5662 bool isValid */\n dup1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":5667:5707 _signatureValidation(_hash, _signatures) */\n tag_83\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":5688:5693 _hash */\n dup6\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":5695:5706 _signatures */\n dup6\n dup6\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":5667:5687 _signatureValidation */\n tag_84\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":5667:5707 _signatureValidation(_hash, _signatures) */\n jump\t// in\n tag_83:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":5649:5707 (bool isValid,) = _signatureValidation(_hash, _signatures) */\n pop\n swap1\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":5717:5724 isValid */\n dup1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":5713:5778 if (isValid) {... */\n iszero\n tag_85\n jumpi\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":5741:5771 SELECTOR_ERC1271_BYTES32_BYTES */\n 0x1626ba7e00000000000000000000000000000000000000000000000000000000\n swap1\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":5734:5771 return SELECTOR_ERC1271_BYTES32_BYTES */\n jump(tag_82)\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":5713:5778 if (isValid) {... */\n tag_85:\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":5798:5799 0 */\n 0x00\n swap1\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":5489:5805 function isValidSignature(... */\n tag_82:\n swap4\n swap3\n pop\n pop\n pop\n jump\t// out\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":4525:4857 function isValidSignature(... */\n tag_34:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":4651:4657 bytes4 */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":4693:4705 bool isValid */\n dup1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":4710:4761 _signatureValidation(keccak256(_data), _signatures) */\n tag_87\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":4741:4746 _data */\n dup7\n dup7\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":4731:4747 keccak256(_data) */\n mload(0x40)\n tag_88\n swap3\n swap2\n swap1\n tag_89\n jump\t// in\n tag_88:\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n keccak256\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":4749:4760 _signatures */\n dup6\n dup6\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":4710:4730 _signatureValidation */\n tag_84\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":4710:4761 _signatureValidation(keccak256(_data), _signatures) */\n jump\t// in\n tag_87:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":4692:4761 (bool isValid,) = _signatureValidation(keccak256(_data), _signatures) */\n pop\n swap1\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":4771:4778 isValid */\n dup1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":4767:4830 if (isValid) {... */\n iszero\n tag_90\n jumpi\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":4795:4823 SELECTOR_ERC1271_BYTES_BYTES */\n 0x20c13b0b00000000000000000000000000000000000000000000000000000000\n swap1\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":4788:4823 return SELECTOR_ERC1271_BYTES_BYTES */\n jump(tag_86)\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":4767:4830 if (isValid) {... */\n tag_90:\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":4850:4851 0 */\n 0x00\n swap1\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":4525:4857 function isValidSignature(... */\n tag_86:\n swap5\n swap4\n pop\n pop\n pop\n pop\n jump\t// out\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":6456:6575 function updateImageHash(bytes32 _imageHash) external override virtual onlySelf {... */\n tag_40:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":178:188 msg.sender */\n caller\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":200:204 this */\n address\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":178:205 msg.sender != address(this) */\n eq\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":174:268 if (msg.sender != address(this)) {... */\n tag_92\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":222:261 OnlySelfAuth(msg.sender, address(this)) */\n mload(0x40)\n 0xe125889400000000000000000000000000000000000000000000000000000000\n dup2\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":235:245 msg.sender */\n caller\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":222:261 OnlySelfAuth(msg.sender, address(this)) */\n 0x04\n dup3\n add\n /* \"#utility.yul\":7319:7353 */\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":255:259 this */\n address\n /* \"#utility.yul\":7369:7387 */\n 0x24\n dup3\n add\n /* \"#utility.yul\":7362:7405 */\n mstore\n /* \"#utility.yul\":7231:7249 */\n 0x44\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":222:261 OnlySelfAuth(msg.sender, address(this)) */\n tag_93:\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n revert\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":174:268 if (msg.sender != address(this)) {... */\n tag_92:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":6542:6570 _updateImageHash(_imageHash) */\n tag_96\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":6559:6569 _imageHash */\n dup2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":6542:6558 _updateImageHash */\n tag_97\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":6542:6570 _updateImageHash(_imageHash) */\n jump\t// in\n tag_96:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":6456:6575 function updateImageHash(bytes32 _imageHash) external override virtual onlySelf {... */\n pop\n jump\t// out\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1290:1552 function selfExecute(... */\n tag_50:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1401:1415 bytes32 txHash */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1418:1481 SequenceBaseSig.subdigest(keccak256(abi.encode('self:', _txs))) */\n tag_99\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1474:1478 _txs */\n dup4\n dup4\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1454:1479 abi.encode('self:', _txs) */\n add(0x20, mload(0x40))\n tag_100\n swap3\n swap2\n swap1\n tag_101\n jump\t// in\n tag_100:\n mload(0x40)\n 0x20\n dup2\n dup4\n sub\n sub\n dup2\n mstore\n swap1\n 0x40\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1444:1480 keccak256(abi.encode('self:', _txs)) */\n dup1\n mload\n swap1\n 0x20\n add\n keccak256\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1418:1443 SequenceBaseSig.subdigest */\n tag_102\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1418:1481 SequenceBaseSig.subdigest(keccak256(abi.encode('self:', _txs))) */\n jump\t// in\n tag_99:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1401:1481 bytes32 txHash = SequenceBaseSig.subdigest(keccak256(abi.encode('self:', _txs))) */\n swap1\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1520:1547 _executeGuest(txHash, _txs) */\n tag_103\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1534:1540 txHash */\n dup2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1542:1546 _txs */\n dup5\n dup5\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1520:1533 _executeGuest */\n tag_104\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1520:1547 _executeGuest(txHash, _txs) */\n jump\t// in\n tag_103:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1364:1552 {... */\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1290:1552 function selfExecute(... */\n pop\n pop\n jump\t// out\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":890:1182 function execute(... */\n tag_55:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1030:1044 bytes32 txHash */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1047:1111 SequenceBaseSig.subdigest(keccak256(abi.encode('guest:', _txs))) */\n tag_106\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1104:1108 _txs */\n dup7\n dup7\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1083:1109 abi.encode('guest:', _txs) */\n add(0x20, mload(0x40))\n tag_100\n swap3\n swap2\n swap1\n tag_108\n jump\t// in\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1047:1111 SequenceBaseSig.subdigest(keccak256(abi.encode('guest:', _txs))) */\n tag_106:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1030:1111 bytes32 txHash = SequenceBaseSig.subdigest(keccak256(abi.encode('guest:', _txs))) */\n swap1\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1150:1177 _executeGuest(txHash, _txs) */\n tag_109\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1164:1170 txHash */\n dup2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1172:1176 _txs */\n dup8\n dup8\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1150:1163 _executeGuest */\n tag_104\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1150:1177 _executeGuest(txHash, _txs) */\n jump\t// in\n tag_109:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":993:1182 {... */\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":890:1182 function execute(... */\n pop\n pop\n pop\n pop\n pop\n jump\t// out\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":1675:3161 function signatureRecovery(... */\n tag_59:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":1801:1818 uint256 threshold */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":1824:1838 uint256 weight */\n dup1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":1844:1861 bytes32 imageHash */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":1867:1884 bytes32 subdigest */\n dup1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":1890:1908 uint256 checkpoint */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":1919:1939 bytes1 signatureType */\n dup1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":1942:1952 _signature */\n dup8\n dup8\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":1953:1954 0 */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":1942:1955 _signature[0] */\n dup2\n dup2\n lt\n tag_112\n jumpi\n tag_112\n tag_113\n jump\t// in\n tag_112:\n swap1\n swap2\n add\n calldataload\n 0xff00000000000000000000000000000000000000000000000000000000000000\n and\n swap2\n pop\n dup2\n swap1\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":1962:2265 if (signatureType == LEGACY_TYPE) {... */\n tag_114\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":2057:2091 SequenceBaseSig.subdigest(_digest) */\n tag_115\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":2083:2090 _digest */\n dup10\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":2057:2082 SequenceBaseSig.subdigest */\n tag_102\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":2057:2091 SequenceBaseSig.subdigest(_digest) */\n jump\t// in\n tag_115:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":2045:2091 subdigest = SequenceBaseSig.subdigest(_digest) */\n swap3\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":2144:2190 SequenceBaseSig.recover(subdigest, _signature) */\n tag_116\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":2168:2177 subdigest */\n dup4\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":2179:2189 _signature */\n dup10\n dup10\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":2144:2167 SequenceBaseSig.recover */\n tag_117\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":2144:2190 SequenceBaseSig.recover(subdigest, _signature) */\n jump\t// in\n tag_116:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":2099:2190 (threshold, weight, imageHash, checkpoint) = SequenceBaseSig.recover(subdigest, _signature) */\n swap3\n swap9\n pop\n swap1\n swap7\n pop\n swap5\n pop\n swap2\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":2198:2258 return (threshold, weight, imageHash, subdigest, checkpoint) */\n tag_110\n swap1\n pop\n jump\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":1962:2265 if (signatureType == LEGACY_TYPE) {... */\n tag_114:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":2275:2304 signatureType == DYNAMIC_TYPE */\n 0xff00000000000000000000000000000000000000000000000000000000000000\n dup2\n dup2\n and\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":2271:2581 if (signatureType == DYNAMIC_TYPE) {... */\n tag_118\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":2370:2404 SequenceBaseSig.subdigest(_digest) */\n tag_119\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":2396:2403 _digest */\n dup10\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":2370:2395 SequenceBaseSig.subdigest */\n tag_102\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":2370:2404 SequenceBaseSig.subdigest(_digest) */\n jump\t// in\n tag_119:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":2358:2404 subdigest = SequenceBaseSig.subdigest(_digest) */\n swap3\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":2457:2506 SequenceDynamicSig.recover(subdigest, _signature) */\n tag_116\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":2484:2493 subdigest */\n dup4\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":2495:2505 _signature */\n dup10\n dup10\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":2457:2483 SequenceDynamicSig.recover */\n tag_121\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":2457:2506 SequenceDynamicSig.recover(subdigest, _signature) */\n jump\t// in\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":2271:2581 if (signatureType == DYNAMIC_TYPE) {... */\n tag_118:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":2591:2624 signatureType == NO_CHAIN_ID_TYPE */\n 0xfe00000000000000000000000000000000000000000000000000000000000000\n 0xff00000000000000000000000000000000000000000000000000000000000000\n dup3\n and\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":2587:2906 if (signatureType == NO_CHAIN_ID_TYPE) {... */\n tag_122\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":2690:2729 SequenceNoChainIdSig.subdigest(_digest) */\n tag_119\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":2721:2728 _digest */\n dup10\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":2690:2720 SequenceNoChainIdSig.subdigest */\n tag_124\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":2690:2729 SequenceNoChainIdSig.subdigest(_digest) */\n jump\t// in\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":2587:2906 if (signatureType == NO_CHAIN_ID_TYPE) {... */\n tag_122:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":2916:2945 signatureType == CHAINED_TYPE */\n 0xfd00000000000000000000000000000000000000000000000000000000000000\n 0xff00000000000000000000000000000000000000000000000000000000000000\n dup3\n and\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":2912:3108 if (signatureType == CHAINED_TYPE) {... */\n tag_126\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":3066:3101 chainedRecover(_digest, _signature) */\n tag_127\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":3081:3088 _digest */\n dup10\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":3090:3100 _signature */\n dup10\n dup10\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":3066:3080 chainedRecover */\n tag_128\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":3066:3101 chainedRecover(_digest, _signature) */\n jump\t// in\n tag_127:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":3059:3101 return chainedRecover(_digest, _signature) */\n swap6\n pop\n swap6\n pop\n swap6\n pop\n swap6\n pop\n swap6\n pop\n pop\n jump(tag_110)\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":2912:3108 if (signatureType == CHAINED_TYPE) {... */\n tag_126:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":3121:3156 InvalidSignatureType(signatureType) */\n mload(0x40)\n 0x6085cd8200000000000000000000000000000000000000000000000000000000\n dup2\n mstore\n /* \"#utility.yul\":11707:11773 */\n 0xff00000000000000000000000000000000000000000000000000000000000000\n /* \"#utility.yul\":11695:11774 */\n dup3\n and\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":3121:3156 InvalidSignatureType(signatureType) */\n 0x04\n dup3\n add\n /* \"#utility.yul\":11677:11775 */\n mstore\n /* \"#utility.yul\":11650:11668 */\n 0x24\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":3121:3156 InvalidSignatureType(signatureType) */\n tag_93\n /* \"#utility.yul\":11533:11781 */\n jump\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":1675:3161 function signatureRecovery(... */\n tag_110:\n swap4\n swap8\n swap3\n swap7\n pop\n swap4\n pop\n swap4\n pop\n jump\t// out\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":938:1094 function readNonce(uint256 _space) public virtual view returns (uint256) {... */\n tag_66:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":1002:1009 uint256 */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":1032:1088 ModuleStorage.readBytes32Map(NONCE_KEY, bytes32(_space)) */\n tag_80\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":453:519 0x8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e */\n 0x8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":1080:1086 _space */\n dup4\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":1032:1060 ModuleStorage.readBytes32Map */\n tag_133\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":1032:1088 ModuleStorage.readBytes32Map(NONCE_KEY, bytes32(_space)) */\n jump\t// in\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":456:732 function createContract(bytes memory _code) public override virtual payable onlySelf returns (address addr) {... */\n tag_72:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":550:562 address addr */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":178:188 msg.sender */\n caller\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":200:204 this */\n address\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":178:205 msg.sender != address(this) */\n eq\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":174:268 if (msg.sender != address(this)) {... */\n tag_135\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":222:261 OnlySelfAuth(msg.sender, address(this)) */\n mload(0x40)\n 0xe125889400000000000000000000000000000000000000000000000000000000\n dup2\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":235:245 msg.sender */\n caller\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":222:261 OnlySelfAuth(msg.sender, address(this)) */\n 0x04\n dup3\n add\n /* \"#utility.yul\":7319:7353 */\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":255:259 this */\n address\n /* \"#utility.yul\":7369:7387 */\n 0x24\n dup3\n add\n /* \"#utility.yul\":7362:7405 */\n mstore\n /* \"#utility.yul\":7231:7249 */\n 0x44\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":222:261 OnlySelfAuth(msg.sender, address(this)) */\n tag_93\n /* \"#utility.yul\":7084:7411 */\n jump\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":174:268 if (msg.sender != address(this)) {... */\n tag_135:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":631:636 _code */\n dup2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":625:637 mload(_code) */\n mload\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":620:622 32 */\n 0x20\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":613:618 _code */\n dup4\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":609:623 add(_code, 32) */\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":596:607 callvalue() */\n callvalue\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":589:638 create(callvalue(), add(_code, 32), mload(_code)) */\n create\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":581:638 addr := create(callvalue(), add(_code, 32), mload(_code)) */\n swap1\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":649:667 addr == address(0) */\n 0xffffffffffffffffffffffffffffffffffffffff\n dup2\n and\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":645:695 if (addr == address(0)) revert CreateFailed(_code) */\n tag_138\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":689:694 _code */\n dup2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":676:695 CreateFailed(_code) */\n mload(0x40)\n 0x0d25719100000000000000000000000000000000000000000000000000000000\n dup2\n mstore\n 0x04\n add\n tag_93\n swap2\n swap1\n tag_140\n jump\t// in\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":645:695 if (addr == address(0)) revert CreateFailed(_code) */\n tag_138:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":706:727 CreatedContract(addr) */\n mload(0x40)\n /* \"#utility.yul\":6753:6795 */\n 0xffffffffffffffffffffffffffffffffffffffff\n /* \"#utility.yul\":6741:6796 */\n dup3\n and\n /* \"#utility.yul\":6723:6797 */\n dup2\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":706:727 CreatedContract(addr) */\n 0xa506ad4e7f05eceba62a023c3219e5bd98a615f4fa87e2afb08a2da5cf62bf0c\n swap1\n /* \"#utility.yul\":6711:6713 */\n 0x20\n /* \"#utility.yul\":6696:6714 */\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":706:727 CreatedContract(addr) */\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n log1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":456:732 function createContract(bytes memory _code) public override virtual payable onlySelf returns (address addr) {... */\n swap2\n swap1\n pop\n jump\t// out\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":670:757 function nonce() external virtual view returns (uint256) {... */\n tag_77:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":718:725 uint256 */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":740:752 readNonce(0) */\n tag_143\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":750:751 0 */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":740:749 readNonce */\n tag_66\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":740:752 readNonce(0) */\n jump\t// in\n tag_143:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":733:752 return readNonce(0) */\n swap1\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":670:757 function nonce() external virtual view returns (uint256) {... */\n swap1\n jump\t// out\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":942:1175 function supportsInterface(bytes4 _interfaceID) public override virtual pure returns (bool) {... */\n tag_81:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":1028:1032 bool */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":1044:1092 _interfaceID == type(IModuleCreator).interfaceId */\n 0x6ffbd45100000000000000000000000000000000000000000000000000000000\n 0xffffffff00000000000000000000000000000000000000000000000000000000\n dup4\n and\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":1040:1120 if (_interfaceID == type(IModuleCreator).interfaceId) {... */\n tag_145\n jumpi\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":1109:1113 true */\n 0x01\n swap2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":942:1175 function supportsInterface(bytes4 _interfaceID) public override virtual pure returns (bool) {... */\n swap1\n pop\n jump\t// out\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":1040:1120 if (_interfaceID == type(IModuleCreator).interfaceId) {... */\n tag_145:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":1133:1170 super.supportsInterface(_interfaceID) */\n tag_80\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":1157:1169 _interfaceID */\n dup3\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":1133:1156 super.supportsInterface */\n tag_147\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":1133:1170 super.supportsInterface(_interfaceID) */\n jump\t// in\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":3480:3866 function _signatureValidation(... */\n tag_84:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":3611:3623 bool isValid */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":3629:3646 bytes32 subdigest */\n dup1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":3657:3674 uint256 threshold */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":3676:3690 uint256 weight */\n dup1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":3692:3709 bytes32 imageHash */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":3760:3798 signatureRecovery(_digest, _signature) */\n tag_149\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":3778:3785 _digest */\n dup9\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":3787:3797 _signature */\n dup9\n dup9\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":3760:3777 signatureRecovery */\n tag_59\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":3760:3798 signatureRecovery(_digest, _signature) */\n jump\t// in\n tag_149:\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":3715:3798 (threshold, weight, imageHash, subdigest,) = signatureRecovery(_digest, _signature) */\n swap7\n pop\n swap2\n swap5\n pop\n swap3\n pop\n swap1\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":3814:3833 weight >= threshold */\n dup3\n dup3\n lt\n dup1\n iszero\n swap1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":3814:3861 weight >= threshold && _isValidImage(imageHash) */\n tag_151\n jumpi\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2779:2783 true */\n 0x01\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":3837:3861 _isValidImage(imageHash) */\n tag_151:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":3804:3861 isValid = weight >= threshold && _isValidImage(imageHash) */\n swap5\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":3651:3866 {... */\n pop\n pop\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":3480:3866 function _signatureValidation(... */\n swap4\n pop\n swap4\n swap2\n pop\n pop\n jump\t// out\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2824:2917 function _updateImageHash(bytes32) internal override virtual {... */\n tag_97:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2898:2912 NotSupported() */\n mload(0x40)\n 0xa038794000000000000000000000000000000000000000000000000000000000\n dup2\n mstore\n 0x04\n add\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n revert\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":1173:1397 function subdigest(... */\n tag_102:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":1279:1386 abi.encodePacked(... */\n mload(0x40)\n /* \"#utility.yul\":12792:12858 */\n 0x1901000000000000000000000000000000000000000000000000000000000000\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":1279:1386 abi.encodePacked(... */\n 0x20\n dup3\n add\n /* \"#utility.yul\":12780:12859 */\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":1325:1338 block.chainid */\n chainid\n /* \"#utility.yul\":12875:12886 */\n 0x22\n dup3\n add\n /* \"#utility.yul\":12868:12895 */\n mstore\n /* \"#utility.yul\":12946:13012 */\n 0xffffffffffffffffffffffffffffffffffffffff000000000000000000000000\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":1356:1360 this */\n address\n /* \"#utility.yul\":12933:12935 */\n 0x60\n /* \"#utility.yul\":12929:12944 */\n shl\n /* \"#utility.yul\":12925:13013 */\n and\n /* \"#utility.yul\":12911:12923 */\n 0x42\n dup3\n add\n /* \"#utility.yul\":12904:13014 */\n mstore\n /* \"#utility.yul\":13030:13042 */\n 0x56\n dup2\n add\n /* \"#utility.yul\":13023:13051 */\n dup3\n swap1\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":1240:1247 bytes32 */\n 0x00\n swap1\n /* \"#utility.yul\":13067:13079 */\n 0x76\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":1279:1386 abi.encodePacked(... */\n tag_155:\n mload(0x40)\n 0x20\n dup2\n dup4\n sub\n sub\n dup2\n mstore\n swap1\n 0x40\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":1262:1392 keccak256(... */\n dup1\n mload\n swap1\n 0x20\n add\n keccak256\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":1255:1392 return keccak256(... */\n swap1\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":1173:1397 function subdigest(... */\n swap2\n swap1\n pop\n jump\t// out\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1710:2544 function _executeGuest(... */\n tag_104:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1847:1851 _txs */\n dup1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1832:1844 uint256 size */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1864:2540 for (uint256 i = 0; i < size; i++) {... */\n tag_158:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1888:1892 size */\n dup2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1884:1885 i */\n dup2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1884:1892 i < size */\n lt\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1864:2540 for (uint256 i = 0; i < size; i++) {... */\n iszero\n tag_159\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1907:1939 Transaction calldata transaction */\n calldatasize\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1942:1946 _txs */\n dup5\n dup5\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1947:1948 i */\n dup4\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1942:1949 _txs[i] */\n dup2\n dup2\n lt\n tag_162\n jumpi\n tag_162\n tag_113\n jump\t// in\n tag_162:\n swap1\n pop\n 0x20\n mul\n dup2\n add\n swap1\n tag_163\n swap2\n swap1\n tag_164\n jump\t// in\n tag_163:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1907:1949 Transaction calldata transaction = _txs[i] */\n swap1\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1962:1986 transaction.delegateCall */\n tag_165\n 0x20\n dup3\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1907:1949 Transaction calldata transaction = _txs[i] */\n dup3\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1962:1986 transaction.delegateCall */\n tag_166\n jump\t// in\n tag_165:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1958:2020 if (transaction.delegateCall) revert DelegateCallNotAllowed(i) */\n iszero\n tag_167\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1995:2020 DelegateCallNotAllowed(i) */\n mload(0x40)\n 0x230d1ccc00000000000000000000000000000000000000000000000000000000\n dup2\n mstore\n 0x04\n dup2\n add\n /* \"#utility.yul\":2778:2803 */\n dup4\n swap1\n mstore\n /* \"#utility.yul\":2751:2769 */\n 0x24\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1995:2020 DelegateCallNotAllowed(i) */\n tag_93\n /* \"#utility.yul\":2632:2809 */\n jump\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1958:2020 if (transaction.delegateCall) revert DelegateCallNotAllowed(i) */\n tag_167:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2048:2068 transaction.gasLimit */\n 0x40\n dup2\n add\n calldataload\n dup1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2080:2089 gasleft() */\n gas\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2080:2100 gasleft() < gasLimit */\n lt\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2076:2145 if (gasleft() < gasLimit) revert NotEnoughGas(i, gasLimit, gasleft()) */\n iszero\n tag_169\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2122:2123 i */\n dup3\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2125:2133 gasLimit */\n dup2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2135:2144 gasleft() */\n gas\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2109:2145 NotEnoughGas(i, gasLimit, gasleft()) */\n mload(0x40)\n 0x2bb3e3ba00000000000000000000000000000000000000000000000000000000\n dup2\n mstore\n 0x04\n dup2\n add\n /* \"#utility.yul\":13869:13894 */\n swap4\n swap1\n swap4\n mstore\n /* \"#utility.yul\":13910:13928 */\n 0x24\n dup4\n add\n /* \"#utility.yul\":13903:13937 */\n swap2\n swap1\n swap2\n mstore\n /* \"#utility.yul\":13953:13971 */\n 0x44\n dup3\n add\n /* \"#utility.yul\":13946:13980 */\n mstore\n /* \"#utility.yul\":13842:13860 */\n 0x64\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2109:2145 NotEnoughGas(i, gasLimit, gasleft()) */\n tag_93\n /* \"#utility.yul\":13667:13986 */\n jump\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2076:2145 if (gasleft() < gasLimit) revert NotEnoughGas(i, gasLimit, gasleft()) */\n tag_169:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2154:2166 bool success */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2169:2317 LibOptim.call(... */\n tag_172\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2192:2210 transaction.target */\n tag_173\n 0x80\n dup6\n add\n 0x60\n dup7\n add\n tag_174\n jump\t// in\n tag_173:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2220:2237 transaction.value */\n 0x80\n dup6\n add\n calldataload\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2247:2260 gasLimit == 0 */\n dup5\n iszero\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2247:2283 gasLimit == 0 ? gasleft() : gasLimit */\n tag_175\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2275:2283 gasLimit */\n dup5\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2247:2283 gasLimit == 0 ? gasleft() : gasLimit */\n jump(tag_176)\n tag_175:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2263:2272 gasleft() */\n gas\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2247:2283 gasLimit == 0 ? gasleft() : gasLimit */\n tag_176:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2293:2309 transaction.data */\n tag_177\n 0xa0\n dup9\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2293:2304 transaction */\n dup9\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2293:2309 transaction.data */\n tag_178\n jump\t// in\n tag_177:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2169:2182 LibOptim.call */\n tag_179\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2169:2317 LibOptim.call(... */\n jump\t// in\n tag_172:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2154:2317 bool success = LibOptim.call(... */\n swap1\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2330:2337 success */\n dup1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2326:2534 if (success) {... */\n iszero\n tag_180\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2365:2372 _txHash */\n dup8\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2354:2376 TxExecuted(_txHash, i) */\n 0x5c4eeb02dabf8976016ab414d617f9a162936dcace3cdef8c69ef6e262ad5ae7\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2374:2375 i */\n dup6\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2354:2376 TxExecuted(_txHash, i) */\n mload(0x40)\n tag_181\n swap2\n /* \"#utility.yul\":2778:2803 */\n dup2\n mstore\n /* \"#utility.yul\":2766:2768 */\n 0x20\n /* \"#utility.yul\":2751:2769 */\n add\n swap1\n /* \"#utility.yul\":2632:2809 */\n jump\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2354:2376 TxExecuted(_txHash, i) */\n tag_181:\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n log2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2326:2534 if (success) {... */\n jump(tag_183)\n tag_180:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2401:2525 _revertBytes(... */\n tag_183\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2425:2450 transaction.revertOnError */\n tag_184\n 0x40\n dup6\n add\n 0x20\n dup7\n add\n tag_166\n jump\t// in\n tag_184:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2462:2469 _txHash */\n dup10\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2481:2482 i */\n dup7\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2494:2515 LibOptim.returnData() */\n tag_185\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2494:2513 LibOptim.returnData */\n tag_186\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2494:2515 LibOptim.returnData() */\n jump\t// in\n tag_185:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2401:2413 _revertBytes */\n tag_187\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":2401:2525 _revertBytes(... */\n jump\t// in\n tag_183:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1899:2540 {... */\n pop\n pop\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1894:1897 i++ */\n dup1\n dup1\n tag_188\n swap1\n tag_189\n jump\t// in\n tag_188:\n swap2\n pop\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1864:2540 for (uint256 i = 0; i < size; i++) {... */\n jump(tag_158)\n tag_159:\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1799:2544 {... */\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":1710:2544 function _executeGuest(... */\n pop\n pop\n pop\n jump\t// out\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":8892:9534 function recover(... */\n tag_117:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":8996:9013 uint256 threshold */\n 0x00\n dup1\n dup1\n dup1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":9131:9172 recoverBranch(_subdigest, _signature[6:]) */\n tag_191\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":9145:9155 _subdigest */\n dup8\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":9157:9171 _signature[6:] */\n tag_192\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":9157:9167 _signature */\n dup8\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":9168:9169 6 */\n 0x06\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":9157:9167 _signature */\n dup2\n dup12\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":9157:9171 _signature[6:] */\n tag_193\n jump\t// in\n tag_192:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":9131:9144 recoverBranch */\n tag_194\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":9131:9172 recoverBranch(_subdigest, _signature[6:]) */\n jump\t// in\n tag_191:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":622:631 bytes32 c */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":656:669 mstore(0, _a) */\n swap1\n dup2\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol\":1585:1610 calldataload(data.offset) */\n dup8\n calldataload\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol\":1626:1629 240 */\n 0xf0\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol\":1622:1636 shr(240, word) */\n shr\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":683:685 32 */\n 0x20\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":676:690 mstore(32, _b) */\n dup2\n dup2\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":715:717 64 */\n 0x40\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":702:718 keccak256(0, 64) */\n dup1\n dup5\n keccak256\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":656:669 mstore(0, _a) */\n dup5\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":9379:9380 2 */\n 0x02\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol\":2034:2057 add(index, data.offset) */\n swap1\n swap11\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol\":2021:2058 calldataload(add(index, data.offset)) */\n calldataload\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol\":2074:2077 224 */\n 0xe0\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol\":2070:2084 shr(224, word) */\n shr\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":676:690 mstore(32, _b) */\n swap1\n dup2\n swap1\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":702:718 keccak256(0, 64) */\n swap9\n swap1\n swap2\n keccak256\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol\":1622:1636 shr(240, word) */\n swap1\n swap10\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":9109:9172 (weight, imageHash) = recoverBranch(_subdigest, _signature[6:]) */\n swap2\n swap9\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":702:718 keccak256(0, 64) */\n swap7\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol\":2070:2084 shr(224, word) */\n swap6\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":8892:9534 function recover(... */\n swap4\n pop\n pop\n pop\n pop\n jump\t// out\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol\":648:910 function recover(... */\n tag_121:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol\":752:769 uint256 threshold */\n 0x00\n dup1\n dup1\n dup1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol\":854:905 SequenceBaseSig.recover(_subdigest, _signature[1:]) */\n tag_203\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol\":878:888 _subdigest */\n dup8\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol\":890:904 _signature[1:] */\n tag_204\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol\":890:900 _signature */\n dup8\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol\":901:902 1 */\n 0x01\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol\":890:900 _signature */\n dup2\n dup12\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol\":890:904 _signature[1:] */\n tag_193\n jump\t// in\n tag_204:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol\":854:877 SequenceBaseSig.recover */\n tag_117\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol\":854:905 SequenceBaseSig.recover(_subdigest, _signature[1:]) */\n jump\t// in\n tag_203:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol\":847:905 return SequenceBaseSig.recover(_subdigest, _signature[1:]) */\n swap4\n pop\n swap4\n pop\n swap4\n pop\n swap4\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol\":648:910 function recover(... */\n swap4\n pop\n swap4\n pop\n swap4\n pop\n swap4\n jump\t// out\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol\":404:617 function subdigest(bytes32 _digest) internal view returns (bytes32) {... */\n tag_124:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol\":502:606 abi.encodePacked(... */\n mload(0x40)\n /* \"#utility.yul\":12792:12858 */\n 0x1901000000000000000000000000000000000000000000000000000000000000\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol\":502:606 abi.encodePacked(... */\n 0x20\n dup3\n add\n /* \"#utility.yul\":12780:12859 */\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol\":463:470 bytes32 */\n 0x00\n /* \"#utility.yul\":12875:12886 */\n 0x22\n dup3\n add\n /* \"#utility.yul\":12868:12895 */\n dup2\n swap1\n mstore\n /* \"#utility.yul\":12946:13012 */\n 0xffffffffffffffffffffffffffffffffffffffff000000000000000000000000\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol\":576:580 this */\n address\n /* \"#utility.yul\":12933:12935 */\n 0x60\n /* \"#utility.yul\":12929:12944 */\n shl\n /* \"#utility.yul\":12925:13013 */\n and\n /* \"#utility.yul\":12911:12923 */\n 0x42\n dup4\n add\n /* \"#utility.yul\":12904:13014 */\n mstore\n /* \"#utility.yul\":13030:13042 */\n 0x56\n dup3\n add\n /* \"#utility.yul\":13023:13051 */\n dup4\n swap1\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol\":463:470 bytes32 */\n swap1\n /* \"#utility.yul\":13067:13079 */\n 0x76\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol\":502:606 abi.encodePacked(... */\n tag_155\n /* \"#utility.yul\":12494:13085 */\n jump\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":2320:4379 function chainedRecover(... */\n tag_128:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":2428:2445 uint256 threshold */\n 0x00\n dup1\n dup1\n dup1\n dup1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":3378:3392 add(_index, 3) */\n 0x04\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":2563:2564 1 */\n 0x01\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":3290:3315 add(_index, _data.offset) */\n dup9\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":3277:3316 calldataload(add(_index, _data.offset)) */\n calldataload\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":3336:3339 232 */\n 0xe8\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":3332:3346 shr(232, word) */\n shr\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":2428:2445 uint256 threshold */\n dup3\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":2768:2784 sigSize + rindex */\n tag_210\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":3378:3392 add(_index, 3) */\n dup4\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":3332:3346 shr(232, word) */\n dup4\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":2768:2784 sigSize + rindex */\n tag_211\n jump\t// in\n tag_210:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":2750:2784 uint256 nrindex = sigSize + rindex */\n swap1\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":2883:2955 signatureRecovery(... */\n tag_212\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":2908:2915 _digest */\n dup12\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":2923:2949 _signature[rindex:nrindex] */\n tag_58\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":2750:2784 uint256 nrindex = sigSize + rindex */\n dup4\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":2934:2940 rindex */\n dup7\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":2923:2933 _signature */\n dup14\n dup16\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":2923:2949 _signature[rindex:nrindex] */\n tag_193\n jump\t// in\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":2883:2955 signatureRecovery(... */\n tag_212:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":2791:2955 (... */\n swap4\n swap12\n pop\n swap2\n swap10\n pop\n swap8\n pop\n swap6\n pop\n swap4\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":2966:2984 weight < threshold */\n dup8\n dup8\n lt\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":2962:3080 if (weight < threshold) {... */\n iszero\n tag_214\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3027:3053 _signature[rindex:nrindex] */\n tag_215\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3045:3052 nrindex */\n dup2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3038:3044 rindex */\n dup5\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3027:3037 _signature */\n dup12\n dup14\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3027:3053 _signature[rindex:nrindex] */\n tag_193\n jump\t// in\n tag_215:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3055:3064 threshold */\n dup10\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3066:3072 weight */\n dup10\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3001:3073 LowWeightChainedSignature(_signature[rindex:nrindex], threshold, weight) */\n mload(0x40)\n 0xb006aba000000000000000000000000000000000000000000000000000000000\n dup2\n mstore\n 0x04\n add\n tag_93\n swap5\n swap4\n swap3\n swap2\n swap1\n tag_217\n jump\t// in\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":2962:3080 if (weight < threshold) {... */\n tag_214:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3095:3102 nrindex */\n dup1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3086:3102 rindex = nrindex */\n swap3\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3283:4375 while (rindex < _signature.length) {... */\n tag_218:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3290:3316 rindex < _signature.length */\n dup9\n dup4\n lt\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3283:4375 while (rindex < _signature.length) {... */\n iszero\n tag_219\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":3390:3391 3 */\n 0x03\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":3378:3392 add(_index, 3) */\n dup4\n add\n swap3\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":3290:3315 add(_index, _data.offset) */\n dup11\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":3277:3316 calldataload(add(_index, _data.offset)) */\n calldataload\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":3336:3339 232 */\n 0xe8\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":3332:3346 shr(232, word) */\n shr\n swap2\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3444:3460 sigSize + rindex */\n tag_221\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":3378:3392 add(_index, 3) */\n dup4\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":3332:3346 shr(232, word) */\n dup4\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3444:3460 sigSize + rindex */\n tag_211\n jump\t// in\n tag_221:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3434:3460 nrindex = sigSize + rindex */\n swap1\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3469:3491 uint256 nextCheckpoint */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3687:3792 signatureRecovery(... */\n tag_222\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3714:3748 _hashSetImageHashStruct(imageHash) */\n tag_223\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3738:3747 imageHash */\n dup9\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3714:3737 _hashSetImageHashStruct */\n tag_224\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3714:3748 _hashSetImageHashStruct(imageHash) */\n jump\t// in\n tag_223:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3758:3768 _signature */\n dup13\n dup13\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3769:3775 rindex */\n dup8\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3758:3784 _signature[rindex:nrindex] */\n swap1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3776:3783 nrindex */\n dup7\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3758:3784 _signature[rindex:nrindex] */\n swap3\n tag_58\n swap4\n swap3\n swap2\n swap1\n tag_193\n jump\t// in\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3687:3792 signatureRecovery(... */\n tag_222:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3500:3792 (... */\n swap4\n swap13\n pop\n swap2\n swap11\n pop\n swap9\n pop\n swap1\n swap2\n pop\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3833:3851 weight < threshold */\n dup9\n dup9\n lt\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3829:3951 if (weight < threshold) {... */\n iszero\n tag_226\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3896:3922 _signature[rindex:nrindex] */\n tag_227\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3914:3921 nrindex */\n dup3\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3907:3913 rindex */\n dup6\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3896:3906 _signature */\n dup13\n dup15\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3896:3922 _signature[rindex:nrindex] */\n tag_193\n jump\t// in\n tag_227:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3924:3933 threshold */\n dup11\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3935:3941 weight */\n dup11\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3870:3942 LowWeightChainedSignature(_signature[rindex:nrindex], threshold, weight) */\n mload(0x40)\n 0xb006aba000000000000000000000000000000000000000000000000000000000\n dup2\n mstore\n 0x04\n add\n tag_93\n swap5\n swap4\n swap3\n swap2\n swap1\n tag_217\n jump\t// in\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3829:3951 if (weight < threshold) {... */\n tag_226:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":4216:4226 checkpoint */\n dup5\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":4198:4212 nextCheckpoint */\n dup2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":4198:4226 nextCheckpoint >= checkpoint */\n lt\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":4194:4309 if (nextCheckpoint >= checkpoint) {... */\n tag_229\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":4245:4300 WrongChainedCheckpointOrder(nextCheckpoint, checkpoint) */\n mload(0x40)\n 0x37daf62b00000000000000000000000000000000000000000000000000000000\n dup2\n mstore\n 0x04\n dup2\n add\n /* \"#utility.yul\":16193:16218 */\n dup3\n swap1\n mstore\n /* \"#utility.yul\":16234:16252 */\n 0x24\n dup2\n add\n /* \"#utility.yul\":16227:16261 */\n dup7\n swap1\n mstore\n /* \"#utility.yul\":16166:16184 */\n 0x44\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":4245:4300 WrongChainedCheckpointOrder(nextCheckpoint, checkpoint) */\n tag_93\n /* \"#utility.yul\":16019:16267 */\n jump\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":4194:4309 if (nextCheckpoint >= checkpoint) {... */\n tag_229:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":4330:4344 nextCheckpoint */\n swap4\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":4361:4368 nrindex */\n swap2\n pop\n dup2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":3283:4375 while (rindex < _signature.length) {... */\n jump(tag_218)\n tag_219:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":2540:4379 {... */\n pop\n pop\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":2320:4379 function chainedRecover(... */\n swap4\n swap8\n swap3\n swap7\n pop\n swap4\n pop\n swap4\n pop\n jump\t// out\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol\":490:677 function readBytes32Map(bytes32 _key, bytes32 _subKey) internal view returns (bytes32 val) {... */\n tag_133:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol\":568:579 bytes32 val */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol\":587:598 bytes32 key */\n dup1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol\":622:626 _key */\n dup4\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol\":628:635 _subKey */\n dup4\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol\":611:636 abi.encode(_key, _subKey) */\n add(0x20, mload(0x40))\n tag_233\n swap3\n swap2\n swap1\n /* \"#utility.yul\":16193:16218 */\n swap2\n dup3\n mstore\n /* \"#utility.yul\":16249:16251 */\n 0x20\n /* \"#utility.yul\":16234:16252 */\n dup3\n add\n /* \"#utility.yul\":16227:16261 */\n mstore\n /* \"#utility.yul\":16181:16183 */\n 0x40\n /* \"#utility.yul\":16166:16184 */\n add\n swap1\n /* \"#utility.yul\":16019:16267 */\n jump\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol\":611:636 abi.encode(_key, _subKey) */\n tag_233:\n 0x40\n dup1\n mload\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0\n dup2\n dup5\n sub\n add\n dup2\n mstore\n swap2\n swap1\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol\":601:637 keccak256(abi.encode(_key, _subKey)) */\n dup1\n mload\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol\":611:636 abi.encode(_key, _subKey) */\n 0x20\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol\":601:637 keccak256(abi.encode(_key, _subKey)) */\n swap1\n swap2\n add\n keccak256\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol\":661:671 sload(key) */\n sload\n swap5\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol\":490:677 function readBytes32Map(bytes32 _key, bytes32 _subKey) internal view returns (bytes32 val) {... */\n swap4\n pop\n pop\n pop\n pop\n jump\t// out\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol\":4140:4371 function supportsInterface(bytes4 _interfaceID) public override virtual pure returns (bool) {... */\n tag_147:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol\":4226:4230 bool */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol\":4242:4288 _interfaceID == type(IModuleCalls).interfaceId */\n 0xe4a77bbc00000000000000000000000000000000000000000000000000000000\n 0xffffffff00000000000000000000000000000000000000000000000000000000\n dup4\n and\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol\":4238:4316 if (_interfaceID == type(IModuleCalls).interfaceId) {... */\n tag_236\n jumpi\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol\":4305:4309 true */\n 0x01\n swap2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol\":4140:4371 function supportsInterface(bytes4 _interfaceID) public override virtual pure returns (bool) {... */\n swap1\n pop\n jump\t// out\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol\":4238:4316 if (_interfaceID == type(IModuleCalls).interfaceId) {... */\n tag_236:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol\":4329:4366 super.supportsInterface(_interfaceID) */\n tag_80\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol\":4353:4365 _interfaceID */\n dup3\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol\":4329:4352 super.supportsInterface */\n tag_238\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol\":4329:4366 super.supportsInterface(_interfaceID) */\n jump\t// in\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":1525:1878 function call(... */\n tag_179:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":1640:1646 bool r */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":1688:1692 0x40 */\n 0x40\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":1682:1693 mload(0x40) */\n mload\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":1732:1744 _data.length */\n dup3\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":1718:1730 _data.offset */\n dup5\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":1713:1716 tmp */\n dup3\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":1700:1745 calldatacopy(tmp, _data.offset, _data.length) */\n calldatacopy\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":1859:1860 0 */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":1848:1849 0 */\n dup1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":1826:1838 _data.length */\n dup5\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":1813:1816 tmp */\n dup4\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":1799:1803 _val */\n dup10\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":1786:1789 _to */\n dup12\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":1772:1776 _gas */\n dup11\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":1758:1868 call(... */\n call\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":1753:1868 r := call(... */\n swap8\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":1525:1878 function call(... */\n swap7\n pop\n pop\n pop\n pop\n pop\n pop\n pop\n jump\t// out\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":852:1123 function returnData() internal pure returns (bytes memory r) {... */\n tag_186:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":897:911 bytes memory r */\n 0x60\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":948:964 returndatasize() */\n returndatasize\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":982:986 0x40 */\n 0x40\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":976:987 mload(0x40) */\n mload\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":971:987 r := mload(0x40) */\n swap2\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":1014:1016 32 */\n 0x20\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":1011:1012 r */\n dup3\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":1007:1017 add(r, 32) */\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":1048:1052 size */\n dup2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":1041:1046 start */\n dup2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":1037:1053 add(start, size) */\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":1031:1035 0x40 */\n 0x40\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":1024:1054 mstore(0x40, add(start, size)) */\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":1071:1075 size */\n dup2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":1068:1069 r */\n dup4\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":1061:1076 mstore(r, size) */\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":1108:1112 size */\n dup2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":1105:1106 0 */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":1098:1103 start */\n dup3\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":1083:1113 returndatacopy(start, 0, size) */\n returndatacopy\n pop\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":852:1123 function returnData() internal pure returns (bytes memory r) {... */\n swap1\n jump\t// out\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol\":3644:3930 function _revertBytes(... */\n tag_187:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol\":3781:3795 _revertOnError */\n dup4\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol\":3777:3926 if (_revertOnError) {... */\n iszero\n tag_243\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol\":3849:3856 _reason */\n dup1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol\":3843:3857 mload(_reason) */\n mload\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol\":3836:3840 0x20 */\n 0x20\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol\":3827:3834 _reason */\n dup3\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol\":3823:3841 add(_reason, 0x20) */\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol\":3816:3858 revert(add(_reason, 0x20), mload(_reason)) */\n revert\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol\":3777:3926 if (_revertOnError) {... */\n tag_243:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol\":3894:3901 _txHash */\n dup3\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol\":3885:3919 TxFailed(_txHash, _index, _reason) */\n 0xab46c69f7f32e1bf09b0725853da82a211e5402a0600296ab499a2fb5ea3b419\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol\":3903:3909 _index */\n dup4\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol\":3911:3918 _reason */\n dup4\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol\":3885:3919 TxFailed(_txHash, _index, _reason) */\n mload(0x40)\n tag_245\n swap3\n swap2\n swap1\n tag_246\n jump\t// in\n tag_245:\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n log2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol\":3644:3930 function _revertBytes(... */\n pop\n pop\n pop\n pop\n jump\t// out\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":3525:8233 function recoverBranch(... */\n tag_194:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":3635:3649 uint256 weight */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":3655:3667 bytes32 root */\n dup1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":3696:3710 uint256 rindex */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":3765:8223 while (rindex < _signature.length) {... */\n tag_248:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":3772:3798 rindex < _signature.length */\n dup4\n dup2\n lt\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":3765:8223 while (rindex < _signature.length) {... */\n iszero\n tag_249\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":1475:1476 1 */\n 0x01\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":1463:1477 add(_index, 1) */\n dup2\n add\n swap1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":1390:1415 add(_index, _data.offset) */\n dup6\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":1377:1416 calldataload(add(_index, _data.offset)) */\n calldataload\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":1432:1435 248 */\n 0xf8\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":1428:1442 shr(248, word) */\n shr\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":3923:3943 flag == FLAG_ADDRESS */\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n dup2\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":3919:4321 if (flag == FLAG_ADDRESS) {... */\n tag_252\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":2205:2207 21 */\n 0x15\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":2193:2208 add(_index, 21) */\n dup3\n add\n swap2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":2046:2071 add(_index, _data.offset) */\n dup7\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":2033:2072 calldataload(add(_index, _data.offset)) */\n calldataload\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":2088:2091 248 */\n 0xf8\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":2084:2098 shr(248, word) */\n dup2\n swap1\n shr\n swap1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":2118:2120 88 */\n 0x58\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":2114:2127 shr(88, word) */\n shr\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":2129:2171 0xffffffffffffffffffffffffffffffffffffffff */\n 0xffffffffffffffffffffffffffffffffffffffff\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":2110:2172 and(shr(88, word), 0xffffffffffffffffffffffffffffffffffffffff) */\n dup2\n and\n swap1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":1873:1896 uint256(_weight) << 160 */\n 0xff0000000000000000000000000000000000000000\n and\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":1873:1922 uint256(_weight) << 160 | uint256(uint160(_addr)) */\n dup2\n or\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":4231:4235 root */\n dup6\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":4231:4290 root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node */\n tag_257\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":4286:4290 node */\n dup1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":4231:4290 root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node */\n jump(tag_259)\n tag_257:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":622:631 bytes32 c */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":656:669 mstore(0, _a) */\n dup7\n dup2\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":683:685 32 */\n 0x20\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":676:690 mstore(32, _b) */\n dup3\n swap1\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":715:717 64 */\n 0x40\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":702:718 keccak256(0, 64) */\n swap1\n keccak256\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":4252:4283 LibOptim.fkeccak256(root, node) */\n tag_259:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":4224:4290 root = root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node */\n swap6\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":4302:4310 continue */\n pop\n pop\n pop\n pop\n jump(tag_248)\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":3919:4321 if (flag == FLAG_ADDRESS) {... */\n tag_252:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":4335:4339 flag */\n dup1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":4331:5010 if (flag == FLAG_SIGNATURE) {... */\n tag_260\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":1475:1476 1 */\n 0x01\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":1463:1477 add(_index, 1) */\n dup3\n add\n swap2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":1390:1415 add(_index, _data.offset) */\n dup7\n dup2\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":1377:1416 calldataload(add(_index, _data.offset)) */\n calldataload\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":1432:1435 248 */\n 0xf8\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":1428:1442 shr(248, word) */\n shr\n swap1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":4560:4571 rindex + 66 */\n 0x43\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":4396:4412 uint8 addrWeight */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":4598:4670 SignatureValidator.recoverSigner(_subdigest, _signature[rindex:nrindex]) */\n tag_262\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":4631:4641 _subdigest */\n dup11\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":4643:4669 _signature[rindex:nrindex] */\n tag_263\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":4560:4571 rindex + 66 */\n dup5\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":1463:1477 add(_index, 1) */\n dup9\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":4643:4653 _signature */\n dup13\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":1390:1415 add(_index, _data.offset) */\n dup15\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":4643:4669 _signature[rindex:nrindex] */\n tag_193\n jump\t// in\n tag_263:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":4598:4630 SignatureValidator.recoverSigner */\n tag_264\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":4598:4670 SignatureValidator.recoverSigner(_subdigest, _signature[rindex:nrindex]) */\n jump\t// in\n tag_262:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":4764:4784 weight += addrWeight */\n 0xff\n dup5\n and\n swap8\n swap1\n swap8\n add\n swap7\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":4691:4698 nrindex */\n swap2\n swap5\n pop\n dup5\n swap2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":4764:4784 weight += addrWeight */\n swap1\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":1893:1896 160 */\n 0xa0\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":1873:1896 uint256(_weight) << 160 */\n dup4\n swap1\n shl\n 0xff0000000000000000000000000000000000000000\n and\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":1899:1922 uint256(uint160(_addr)) */\n 0xffffffffffffffffffffffffffffffffffffffff\n dup3\n and\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":1873:1922 uint256(_weight) << 160 | uint256(uint160(_addr)) */\n or\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":4920:4924 root */\n dup7\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":4920:4979 root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node */\n tag_266\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":4975:4979 node */\n dup1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":4920:4979 root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node */\n jump(tag_268)\n tag_266:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":622:631 bytes32 c */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":656:669 mstore(0, _a) */\n dup8\n dup2\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":683:685 32 */\n 0x20\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":676:690 mstore(32, _b) */\n dup3\n swap1\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":715:717 64 */\n 0x40\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":702:718 keccak256(0, 64) */\n swap1\n keccak256\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":4941:4972 LibOptim.fkeccak256(root, node) */\n tag_268:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":4913:4979 root = root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node */\n swap7\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":4991:4999 continue */\n pop\n pop\n pop\n pop\n pop\n jump(tag_248)\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":4331:5010 if (flag == FLAG_SIGNATURE) {... */\n tag_260:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":625:626 2 */\n 0x02\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5024:5028 flag */\n dup2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5024:5054 flag == FLAG_DYNAMIC_SIGNATURE */\n sub\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5020:5952 if (flag == FLAG_DYNAMIC_SIGNATURE) {... */\n tag_269\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5104:5120 uint8 addrWeight */\n 0x00\n dup1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":2046:2071 add(_index, _data.offset) */\n dup8\n dup5\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":2033:2072 calldataload(add(_index, _data.offset)) */\n calldataload\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":2088:2091 248 */\n 0xf8\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":2084:2098 shr(248, word) */\n dup2\n swap1\n shr\n swap1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":2118:2120 88 */\n 0x58\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":2114:2127 shr(88, word) */\n shr\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":2129:2171 0xffffffffffffffffffffffffffffffffffffffff */\n 0xffffffffffffffffffffffffffffffffffffffff\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":2110:2172 and(shr(88, word), 0xffffffffffffffffffffffffffffffffffffffff) */\n and\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":2205:2207 21 */\n 0x15\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":2193:2208 add(_index, 21) */\n dup7\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5146:5210 (addrWeight, addr, rindex) = _signature.readUint8Address(rindex) */\n swap6\n pop\n swap1\n swap3\n pop\n swap1\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5256:5268 uint256 size */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":3290:3315 add(_index, _data.offset) */\n dup9\n dup6\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":3277:3316 calldataload(add(_index, _data.offset)) */\n calldataload\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":3336:3339 232 */\n 0xe8\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":3332:3346 shr(232, word) */\n shr\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":3390:3391 3 */\n 0x03\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":3378:3392 add(_index, 3) */\n dup7\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5280:5326 (size, rindex) = _signature.readUint24(rindex) */\n dup2\n 0xffffff\n and\n swap2\n pop\n dup1\n swap7\n pop\n dup2\n swap3\n pop\n pop\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5380:5395 uint256 nrindex */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5407:5411 size */\n dup2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5398:5404 rindex */\n dup7\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5398:5411 rindex + size */\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5380:5411 uint256 nrindex = rindex + size */\n swap1\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5428:5509 SignatureValidator.isValidSignature(_subdigest, addr, _signature[rindex:nrindex]) */\n tag_272\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5464:5474 _subdigest */\n dup12\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5476:5480 addr */\n dup5\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5482:5492 _signature */\n dup13\n dup13\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5493:5499 rindex */\n dup11\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5482:5508 _signature[rindex:nrindex] */\n swap1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5500:5507 nrindex */\n dup7\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5482:5508 _signature[rindex:nrindex] */\n swap3\n tag_273\n swap4\n swap3\n swap2\n swap1\n tag_193\n jump\t// in\n tag_273:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5428:5463 SignatureValidator.isValidSignature */\n tag_274\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5428:5509 SignatureValidator.isValidSignature(_subdigest, addr, _signature[rindex:nrindex]) */\n jump\t// in\n tag_272:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5423:5613 if (!SignatureValidator.isValidSignature(_subdigest, addr, _signature[rindex:nrindex])) {... */\n tag_275\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5555:5565 _subdigest */\n dup11\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5567:5571 addr */\n dup4\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5573:5599 _signature[rindex:nrindex] */\n tag_276\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5591:5598 nrindex */\n dup4\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5584:5590 rindex */\n dup10\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5573:5583 _signature */\n dup14\n dup16\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5573:5599 _signature[rindex:nrindex] */\n tag_193\n jump\t// in\n tag_276:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5532:5600 InvalidNestedSignature(_subdigest, addr, _signature[rindex:nrindex]) */\n mload(0x40)\n 0x9a94623200000000000000000000000000000000000000000000000000000000\n dup2\n mstore\n 0x04\n add\n tag_93\n swap5\n swap4\n swap3\n swap2\n swap1\n tag_278\n jump\t// in\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5423:5613 if (!SignatureValidator.isValidSignature(_subdigest, addr, _signature[rindex:nrindex])) {... */\n tag_275:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5706:5726 weight += addrWeight */\n 0xff\n dup5\n and\n swap8\n swap1\n swap8\n add\n swap7\n swap5\n pop\n dup5\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":1893:1896 160 */\n 0xa0\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":1873:1896 uint256(_weight) << 160 */\n dup5\n swap1\n shl\n 0xff0000000000000000000000000000000000000000\n and\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":1899:1922 uint256(uint160(_addr)) */\n 0xffffffffffffffffffffffffffffffffffffffff\n dup5\n and\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":1873:1922 uint256(_weight) << 160 | uint256(uint160(_addr)) */\n or\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5862:5866 root */\n dup8\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5862:5921 root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node */\n tag_280\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5917:5921 node */\n dup1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5862:5921 root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node */\n jump(tag_282)\n tag_280:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":622:631 bytes32 c */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":656:669 mstore(0, _a) */\n dup9\n dup2\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":683:685 32 */\n 0x20\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":676:690 mstore(32, _b) */\n dup3\n swap1\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":715:717 64 */\n 0x40\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":702:718 keccak256(0, 64) */\n swap1\n keccak256\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5883:5914 LibOptim.fkeccak256(root, node) */\n tag_282:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5855:5921 root = root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node */\n swap8\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5933:5941 continue */\n pop\n pop\n pop\n pop\n pop\n pop\n jump(tag_248)\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5020:5952 if (flag == FLAG_DYNAMIC_SIGNATURE) {... */\n tag_269:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":667:668 3 */\n 0x03\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5966:5970 flag */\n dup2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5966:5983 flag == FLAG_NODE */\n sub\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5962:6205 if (flag == FLAG_NODE) {... */\n tag_283\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":4550:4552 32 */\n 0x20\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":4536:4553 add(_pointer, 32) */\n dup3\n add\n swap2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":4487:4514 add(_pointer, _data.offset) */\n dup7\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":4474:4515 calldataload(add(_pointer, _data.offset)) */\n calldataload\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":6115:6119 root */\n dup4\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":6115:6174 root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node */\n tag_286\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":6170:6174 node */\n dup1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":6115:6174 root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node */\n jump(tag_288)\n tag_286:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":622:631 bytes32 c */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":656:669 mstore(0, _a) */\n dup5\n dup2\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":683:685 32 */\n 0x20\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":676:690 mstore(32, _b) */\n dup3\n swap1\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":715:717 64 */\n 0x40\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":702:718 keccak256(0, 64) */\n swap1\n keccak256\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":6136:6167 LibOptim.fkeccak256(root, node) */\n tag_288:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":6108:6174 root = root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node */\n swap4\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":6186:6194 continue */\n pop\n pop\n jump(tag_248)\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":5962:6205 if (flag == FLAG_NODE) {... */\n tag_283:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":711:712 4 */\n 0x04\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":6219:6223 flag */\n dup2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":6219:6238 flag == FLAG_BRANCH */\n sub\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":6215:6687 if (flag == FLAG_BRANCH) {... */\n tag_289\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":3390:3391 3 */\n 0x03\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":3378:3392 add(_index, 3) */\n dup1\n dup4\n add\n swap3\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":3290:3315 add(_index, _data.offset) */\n dup8\n dup2\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":3277:3316 calldataload(add(_index, _data.offset)) */\n calldataload\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":3336:3339 232 */\n 0xe8\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":3332:3346 shr(232, word) */\n shr\n swap2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":6409:6422 rindex + size */\n swap1\n dup3\n add\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":6309:6321 uint256 size */\n 0x00\n dup1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":6494:6547 recoverBranch(_subdigest, _signature[rindex:nrindex]) */\n tag_291\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":6508:6518 _subdigest */\n dup12\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":6520:6546 _signature[rindex:nrindex] */\n tag_192\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":6409:6422 rindex + size */\n dup6\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":3378:3392 add(_index, 3) */\n dup10\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":6520:6530 _signature */\n dup14\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":3290:3315 add(_index, _data.offset) */\n dup16\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":6520:6546 _signature[rindex:nrindex] */\n tag_193\n jump\t// in\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":6494:6547 recoverBranch(_subdigest, _signature[rindex:nrindex]) */\n tag_291:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":622:631 bytes32 c */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":656:669 mstore(0, _a) */\n swap9\n dup10\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":683:685 32 */\n 0x20\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":676:690 mstore(32, _b) */\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":715:717 64 */\n 0x40\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":702:718 keccak256(0, 64) */\n swap1\n swap8\n keccak256\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":6560:6577 weight += nweight */\n swap7\n swap1\n swap8\n add\n swap7\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":6649:6656 nrindex */\n swap1\n swap4\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":6668:6676 continue */\n tag_248\n swap3\n pop\n pop\n pop\n jump\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":6215:6687 if (flag == FLAG_BRANCH) {... */\n tag_289:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":802:803 6 */\n 0x06\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":6701:6705 flag */\n dup2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":6701:6720 flag == FLAG_NESTED */\n sub\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":6697:7676 if (flag == FLAG_NESTED) {... */\n tag_294\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":6864:6886 uint256 externalWeight */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":1390:1415 add(_index, _data.offset) */\n dup3\n dup8\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":1377:1416 calldataload(add(_index, _data.offset)) */\n calldataload\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":1432:1435 248 */\n 0xf8\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":1428:1442 shr(248, word) */\n shr\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":1475:1476 1 */\n 0x01\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":1463:1477 add(_index, 1) */\n dup5\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":6898:6953 (externalWeight, rindex) = _signature.readUint8(rindex) */\n swap4\n pop\n 0xff\n and\n swap1\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":6966:6991 uint256 internalThreshold */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":2699:2724 add(_index, _data.offset) */\n dup8\n dup5\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":2686:2725 calldataload(add(_index, _data.offset)) */\n calldataload\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":2745:2748 240 */\n 0xf0\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":2741:2755 shr(240, word) */\n shr\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":2797:2798 2 */\n 0x02\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":2785:2799 add(_index, 2) */\n dup6\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7003:7062 (internalThreshold, rindex) = _signature.readUint16(rindex) */\n swap5\n pop\n 0xffff\n and\n swap1\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7075:7087 uint256 size */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":3290:3315 add(_index, _data.offset) */\n dup9\n dup6\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":3277:3316 calldataload(add(_index, _data.offset)) */\n calldataload\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":3336:3339 232 */\n 0xe8\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":3332:3346 shr(232, word) */\n shr\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":3390:3391 3 */\n 0x03\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":3378:3392 add(_index, 3) */\n dup7\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7099:7145 (size, rindex) = _signature.readUint24(rindex) */\n dup2\n 0xffffff\n and\n swap2\n pop\n dup1\n swap7\n pop\n dup2\n swap3\n pop\n pop\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7157:7172 uint256 nrindex */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7184:7188 size */\n dup2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7175:7181 rindex */\n dup7\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7175:7188 rindex + size */\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7157:7188 uint256 nrindex = rindex + size */\n swap1\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7201:7223 uint256 internalWeight */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7225:7245 bytes32 internalRoot */\n dup1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7290:7343 recoverBranch(_subdigest, _signature[rindex:nrindex]) */\n tag_299\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7304:7314 _subdigest */\n dup14\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7316:7326 _signature */\n dup14\n dup14\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7327:7333 rindex */\n dup12\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7316:7342 _signature[rindex:nrindex] */\n swap1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7334:7341 nrindex */\n dup8\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7316:7342 _signature[rindex:nrindex] */\n swap3\n tag_192\n swap4\n swap3\n swap2\n swap1\n tag_193\n jump\t// in\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7290:7343 recoverBranch(_subdigest, _signature[rindex:nrindex]) */\n tag_299:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7364:7371 nrindex */\n swap4\n swap9\n pop\n dup9\n swap4\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7257:7343 (internalWeight, internalRoot) = recoverBranch(_subdigest, _signature[rindex:nrindex]) */\n swap1\n swap3\n pop\n swap1\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7388:7423 internalWeight >= internalThreshold */\n dup5\n dup3\n lt\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7384:7476 if (internalWeight >= internalThreshold) {... */\n tag_301\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7439:7463 weight += externalWeight */\n swap9\n dup6\n add\n swap9\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7384:7476 if (internalWeight >= internalThreshold) {... */\n tag_301:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":2976:3049 abi.encodePacked('Sequence nested config:\\n', _node, _threshold, _weight) */\n 0x40\n dup1\n mload\n /* \"#utility.yul\":20362:20428 */\n 0x53657175656e6365206e657374656420636f6e6669673a0a0000000000000000\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":2976:3049 abi.encodePacked('Sequence nested config:\\n', _node, _threshold, _weight) */\n 0x20\n dup1\n dup4\n add\n /* \"#utility.yul\":20350:20429 */\n swap2\n swap1\n swap2\n mstore\n /* \"#utility.yul\":20445:20457 */\n 0x38\n dup3\n add\n /* \"#utility.yul\":20438:20466 */\n dup5\n swap1\n mstore\n /* \"#utility.yul\":20482:20494 */\n 0x58\n dup3\n add\n /* \"#utility.yul\":20475:20503 */\n dup9\n swap1\n mstore\n /* \"#utility.yul\":20519:20531 */\n 0x78\n dup1\n dup4\n add\n /* \"#utility.yul\":20512:20540 */\n dup11\n swap1\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":2976:3049 abi.encodePacked('Sequence nested config:\\n', _node, _threshold, _weight) */\n dup4\n mload\n dup1\n dup5\n sub\n swap1\n swap2\n add\n dup2\n mstore\n /* \"#utility.yul\":20556:20569 */\n 0x98\n swap1\n swap3\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":2976:3049 abi.encodePacked('Sequence nested config:\\n', _node, _threshold, _weight) */\n swap1\n swap3\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":2966:3050 keccak256(abi.encodePacked('Sequence nested config:\\n', _node, _threshold, _weight)) */\n dup1\n mload\n swap2\n add\n keccak256\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7585:7589 root */\n dup10\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7585:7644 root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node */\n tag_304\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7640:7644 node */\n dup1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7585:7644 root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node */\n jump(tag_306)\n tag_304:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":622:631 bytes32 c */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":656:669 mstore(0, _a) */\n dup11\n dup2\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":683:685 32 */\n 0x20\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":676:690 mstore(32, _b) */\n dup3\n swap1\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":715:717 64 */\n 0x40\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":702:718 keccak256(0, 64) */\n swap1\n keccak256\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7606:7637 LibOptim.fkeccak256(root, node) */\n tag_306:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7578:7644 root = root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node */\n swap10\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7657:7665 continue */\n pop\n pop\n pop\n pop\n pop\n pop\n pop\n pop\n jump(tag_248)\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":6697:7676 if (flag == FLAG_NESTED) {... */\n tag_294:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":758:759 5 */\n 0x05\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7690:7694 flag */\n dup2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7690:7712 flag == FLAG_SUBDIGEST */\n sub\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7686:8171 if (flag == FLAG_SUBDIGEST) {... */\n tag_307\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":4550:4552 32 */\n 0x20\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":4536:4553 add(_pointer, 32) */\n dup3\n add\n swap2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":4487:4514 add(_pointer, _data.offset) */\n dup7\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":4474:4515 calldataload(add(_pointer, _data.offset)) */\n calldataload\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7920:7943 hardcoded == _subdigest */\n dup8\n dup2\n sub\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7916:7998 if (hardcoded == _subdigest) {... */\n tag_309\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7968:7985 type(uint256).max */\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7959:7985 weight = type(uint256).max */\n swap5\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7916:7998 if (hardcoded == _subdigest) {... */\n tag_309:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":8010:8022 bytes32 node */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":8025:8062 _leafForHardcodedSubdigest(hardcoded) */\n tag_310\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":8052:8061 hardcoded */\n dup3\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":8025:8051 _leafForHardcodedSubdigest */\n tag_311\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":8025:8062 _leafForHardcodedSubdigest(hardcoded) */\n jump\t// in\n tag_310:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":8010:8062 bytes32 node = _leafForHardcodedSubdigest(hardcoded) */\n swap1\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":8081:8085 root */\n dup5\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":8081:8140 root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node */\n tag_312\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":8136:8140 node */\n dup1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":8081:8140 root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node */\n jump(tag_314)\n tag_312:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":622:631 bytes32 c */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":656:669 mstore(0, _a) */\n dup6\n dup2\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":683:685 32 */\n 0x20\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":676:690 mstore(32, _b) */\n dup3\n swap1\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":715:717 64 */\n 0x40\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":702:718 keccak256(0, 64) */\n swap1\n keccak256\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":8102:8133 LibOptim.fkeccak256(root, node) */\n tag_314:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":8074:8140 root = root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node */\n swap5\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":8152:8160 continue */\n pop\n pop\n pop\n jump(tag_248)\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":7686:8171 if (flag == FLAG_SUBDIGEST) {... */\n tag_307:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":8188:8214 InvalidSignatureFlag(flag) */\n mload(0x40)\n 0xb2505f7c00000000000000000000000000000000000000000000000000000000\n dup2\n mstore\n 0x04\n dup2\n add\n /* \"#utility.yul\":2778:2803 */\n dup3\n swap1\n mstore\n /* \"#utility.yul\":2751:2769 */\n 0x24\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":8188:8214 InvalidSignatureFlag(flag) */\n tag_93\n /* \"#utility.yul\":2632:2809 */\n jump\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":3765:8223 while (rindex < _signature.length) {... */\n tag_249:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":3678:8229 unchecked {... */\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":3525:8233 function recoverBranch(... */\n swap4\n pop\n swap4\n swap2\n pop\n pop\n jump\t// out\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":1296:1456 function _hashSetImageHashStruct(bytes32 _imageHash) internal pure returns (bytes32) {... */\n tag_224:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":862:906 keccak256(\"SetImageHash(bytes32 imageHash)\") */\n 0x8713a7c4465f6fbee2b6e9d6646d1d9f83fec929edfc4baf661f3c865bdd04d1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":1372:1379 bytes32 */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":656:669 mstore(0, _a) */\n swap1\n dup2\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":683:685 32 */\n 0x20\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":676:690 mstore(32, _b) */\n dup3\n swap1\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":715:717 64 */\n 0x40\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":702:718 keccak256(0, 64) */\n dup2\n keccak256\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":1394:1451 LibOptim.fkeccak256(SET_IMAGE_HASH_TYPE_HASH, _imageHash) */\n tag_80\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":543:728 function fkeccak256(... */\n jump\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":6015:6315 function supportsInterface(bytes4 _interfaceID) public override virtual pure returns (bool) {... */\n tag_238:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":6101:6105 bool */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":6124:6169 _interfaceID == type(IModuleAuth).interfaceId */\n 0xffffffff00000000000000000000000000000000000000000000000000000000\n dup3\n and\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":6140:6169 type(IModuleAuth).interfaceId */\n 0xac6a444e00000000000000000000000000000000000000000000000000000000\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":6124:6169 _interfaceID == type(IModuleAuth).interfaceId */\n eq\n dup1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":6124:6227 _interfaceID == type(IModuleAuth).interfaceId ||... */\n tag_323\n jumpi\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":6179:6227 _interfaceID == type(IERC1271Wallet).interfaceId */\n 0xffffffff00000000000000000000000000000000000000000000000000000000\n dup3\n and\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":6195:6227 type(IERC1271Wallet).interfaceId */\n 0x36e7817500000000000000000000000000000000000000000000000000000000\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":6179:6227 _interfaceID == type(IERC1271Wallet).interfaceId */\n eq\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":6124:6227 _interfaceID == type(IModuleAuth).interfaceId ||... */\n tag_323:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":6113:6260 if (... */\n iszero\n tag_324\n jumpi\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":6249:6253 true */\n 0x01\n swap2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":6015:6315 function supportsInterface(bytes4 _interfaceID) public override virtual pure returns (bool) {... */\n swap1\n pop\n jump\t// out\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":6113:6260 if (... */\n tag_324:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleERC165.sol\":725:756 this.supportsInterface.selector */\n 0x01ffc9a700000000000000000000000000000000000000000000000000000000\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleERC165.sol\":709:756 _interfaceID == this.supportsInterface.selector */\n 0xffffffff00000000000000000000000000000000000000000000000000000000\n dup4\n and\n eq\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":6273:6310 super.supportsInterface(_interfaceID) */\n tag_80\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleERC165.sol\":613:761 function supportsInterface(bytes4 _interfaceID) virtual public pure returns (bool) {... */\n jump\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":1767:4083 function recoverSigner(... */\n tag_264:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":1867:1881 address signer */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":1914:1916 66 */\n 0x42\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":1893:1916 _signature.length != 66 */\n dup3\n eq\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":1889:1959 if (_signature.length != 66) revert InvalidSignatureLength(_signature) */\n tag_331\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":1948:1958 _signature */\n dup3\n dup3\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":1925:1959 InvalidSignatureLength(_signature) */\n mload(0x40)\n 0x2ee17a3d00000000000000000000000000000000000000000000000000000000\n dup2\n mstore\n 0x04\n add\n tag_93\n swap3\n swap2\n swap1\n tag_333\n jump\t// in\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":1889:1959 if (_signature.length != 66) revert InvalidSignatureLength(_signature) */\n tag_331:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":1965:1986 uint256 signatureType */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":1989:2032 _signature.readUint8(_signature.length - 1) */\n tag_334\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":2010:2031 _signature.length - 1 */\n tag_335\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":2030:2031 1 */\n 0x01\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":2010:2020 _signature */\n dup6\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":2010:2031 _signature.length - 1 */\n tag_336\n jump\t// in\n tag_335:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol\":1226:1249 add(index, data.offset) */\n dup6\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol\":1213:1250 calldataload(add(index, data.offset)) */\n calldataload\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol\":1266:1269 248 */\n 0xf8\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol\":1262:1276 shr(248, word) */\n shr\n swap1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol\":1071:1286 function readUint8(... */\n jump\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":1989:2032 _signature.readUint8(_signature.length - 1) */\n tag_334:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":1965:2032 uint256 signatureType = _signature.readUint8(_signature.length - 1) */\n 0xff\n and\n swap1\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":2115:2117 64 */\n 0x40\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol\":1226:1249 add(index, data.offset) */\n dup5\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol\":1213:1250 calldataload(add(index, data.offset)) */\n calldataload\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol\":1266:1269 248 */\n 0xf8\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol\":1262:1276 shr(248, word) */\n shr\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol\":795:832 calldataload(add(data.offset, index)) */\n dup5\n calldataload\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":2202:2204 32 */\n 0x20\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol\":808:831 add(data.offset, index) */\n dup7\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol\":795:832 calldataload(add(data.offset, index)) */\n calldataload\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3209:3275 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 */\n 0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3196:3275 uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 */\n dup2\n gt\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3192:3327 if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {... */\n iszero\n tag_342\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3306:3316 _signature */\n dup7\n dup7\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3318:3319 s */\n dup3\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3292:3320 InvalidSValue(_signature, s) */\n mload(0x40)\n 0xad4aac7600000000000000000000000000000000000000000000000000000000\n dup2\n mstore\n 0x04\n add\n tag_93\n swap4\n swap3\n swap2\n swap1\n tag_344\n jump\t// in\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3192:3327 if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {... */\n tag_342:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3337:3338 v */\n dup3\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3337:3344 v != 27 */\n 0xff\n and\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3342:3344 27 */\n 0x1b\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3337:3344 v != 27 */\n eq\n iszero\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3337:3355 v != 27 && v != 28 */\n dup1\n iszero\n tag_345\n jumpi\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3348:3349 v */\n dup3\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3348:3355 v != 28 */\n 0xff\n and\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3353:3355 28 */\n 0x1c\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3348:3355 v != 28 */\n eq\n iszero\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3337:3355 v != 27 && v != 28 */\n tag_345:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3333:3407 if (v != 27 && v != 28) {... */\n iszero\n tag_346\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3386:3396 _signature */\n dup7\n dup7\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3398:3399 v */\n dup5\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3372:3400 InvalidVValue(_signature, v) */\n mload(0x40)\n 0xe578897e00000000000000000000000000000000000000000000000000000000\n dup2\n mstore\n 0x04\n add\n tag_93\n swap4\n swap3\n swap2\n swap1\n tag_348\n jump\t// in\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3333:3407 if (v != 27 && v != 28) {... */\n tag_346:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":1253:1254 1 */\n 0x01\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3447:3460 signatureType */\n dup5\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3447:3479 signatureType == SIG_TYPE_EIP712 */\n sub\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3443:3952 if (signatureType == SIG_TYPE_EIP712) {... */\n tag_349\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3498:3523 ecrecover(_hash, v, r, s) */\n 0x40\n dup1\n mload\n 0x00\n dup2\n mstore\n 0x20\n dup2\n add\n dup1\n dup4\n mstore\n /* \"#utility.yul\":18522:18547 */\n dup11\n swap1\n mstore\n /* \"#utility.yul\":18595:18599 */\n 0xff\n /* \"#utility.yul\":18583:18600 */\n dup6\n and\n /* \"#utility.yul\":18563:18581 */\n swap2\n dup2\n add\n /* \"#utility.yul\":18556:18601 */\n swap2\n swap1\n swap2\n mstore\n /* \"#utility.yul\":18617:18635 */\n 0x60\n dup2\n add\n /* \"#utility.yul\":18610:18644 */\n dup4\n swap1\n mstore\n /* \"#utility.yul\":18660:18678 */\n 0x80\n dup2\n add\n /* \"#utility.yul\":18653:18687 */\n dup3\n swap1\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3498:3523 ecrecover(_hash, v, r, s) */\n 0x01\n swap1\n /* \"#utility.yul\":18494:18513 */\n 0xa0\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3498:3523 ecrecover(_hash, v, r, s) */\n tag_350:\n 0x20\n mload(0x40)\n 0x20\n dup2\n sub\n swap1\n dup1\n dup5\n sub\n swap1\n dup6\n gas\n staticcall\n iszero\n dup1\n iszero\n tag_353\n jumpi\n returndatasize\n 0x00\n dup1\n returndatacopy\n revert(0x00, returndatasize)\n tag_353:\n pop\n pop\n pop\n mload(sub(mload(0x40), 0x20))\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3489:3523 signer = ecrecover(_hash, v, r, s) */\n swap5\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3443:3952 if (signatureType == SIG_TYPE_EIP712) {... */\n jump(tag_361)\n tag_349:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":1303:1304 2 */\n 0x02\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3608:3621 signatureType */\n dup5\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3608:3642 signatureType == SIG_TYPE_ETH_SIGN */\n sub\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3604:3952 if (signatureType == SIG_TYPE_ETH_SIGN) {... */\n tag_355\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3690:3749 abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", _hash) */\n mload(0x40)\n /* \"#utility.yul\":18940:19006 */\n 0x19457468657265756d205369676e6564204d6573736167653a0a333200000000\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3690:3749 abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", _hash) */\n 0x20\n dup3\n add\n /* \"#utility.yul\":18928:19007 */\n mstore\n /* \"#utility.yul\":19023:19035 */\n 0x3c\n dup2\n add\n /* \"#utility.yul\":19016:19044 */\n dup10\n swap1\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3661:3791 ecrecover(... */\n 0x01\n swap1\n /* \"#utility.yul\":19060:19072 */\n 0x5c\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3690:3749 abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", _hash) */\n 0x40\n dup1\n mload\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0\n dup2\n dup5\n sub\n add\n dup2\n mstore\n dup3\n dup3\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3680:3750 keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", _hash)) */\n dup1\n mload\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3690:3749 abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", _hash) */\n 0x20\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3680:3750 keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", _hash)) */\n swap2\n dup3\n add\n keccak256\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3661:3791 ecrecover(... */\n 0x00\n dup5\n mstore\n swap1\n dup4\n add\n dup1\n dup4\n mstore\n /* \"#utility.yul\":18522:18547 */\n mstore\n /* \"#utility.yul\":18595:18599 */\n 0xff\n /* \"#utility.yul\":18583:18600 */\n dup7\n and\n /* \"#utility.yul\":18563:18581 */\n swap1\n dup3\n add\n /* \"#utility.yul\":18556:18601 */\n mstore\n /* \"#utility.yul\":18617:18635 */\n 0x60\n dup2\n add\n /* \"#utility.yul\":18610:18644 */\n dup5\n swap1\n mstore\n /* \"#utility.yul\":18660:18678 */\n 0x80\n dup2\n add\n /* \"#utility.yul\":18653:18687 */\n dup4\n swap1\n mstore\n /* \"#utility.yul\":18494:18513 */\n 0xa0\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3661:3791 ecrecover(... */\n tag_350\n /* \"#utility.yul\":18295:18693 */\n jump\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3604:3952 if (signatureType == SIG_TYPE_ETH_SIGN) {... */\n tag_355:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3913:3923 _signature */\n dup7\n dup7\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3925:3938 signatureType */\n dup6\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3940:3944 true */\n 0x01\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3888:3945 UnsupportedSignatureType(_signature, signatureType, true) */\n mload(0x40)\n 0x9dfba85200000000000000000000000000000000000000000000000000000000\n dup2\n mstore\n 0x04\n add\n tag_93\n swap5\n swap4\n swap3\n swap2\n swap1\n tag_363\n jump\t// in\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3604:3952 if (signatureType == SIG_TYPE_ETH_SIGN) {... */\n tag_361:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3999:4021 signer == address(0x0) */\n 0xffffffffffffffffffffffffffffffffffffffff\n dup6\n and\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3995:4058 if (signer == address(0x0)) revert SignerIsAddress0(_signature) */\n tag_364\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4047:4057 _signature */\n dup7\n dup7\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4030:4058 SignerIsAddress0(_signature) */\n mload(0x40)\n 0x6c1719d200000000000000000000000000000000000000000000000000000000\n dup2\n mstore\n 0x04\n add\n tag_93\n swap3\n swap2\n swap1\n tag_333\n jump\t// in\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":3995:4058 if (signer == address(0x0)) revert SignerIsAddress0(_signature) */\n tag_364:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4065:4078 return signer */\n pop\n pop\n pop\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":1767:4083 function recoverSigner(... */\n swap4\n swap3\n pop\n pop\n pop\n jump\t// out\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4411:5362 function isValidSignature(... */\n tag_274:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4535:4545 bool valid */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4557:4579 _signature.length == 0 */\n dup2\n dup2\n sub\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4553:4619 if (_signature.length == 0) {... */\n tag_367\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4596:4612 EmptySignature() */\n mload(0x40)\n 0xac241e1100000000000000000000000000000000000000000000000000000000\n dup2\n mstore\n 0x04\n add\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n revert\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4553:4619 if (_signature.length == 0) {... */\n tag_367:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4625:4646 uint256 signatureType */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4655:4665 _signature */\n dup4\n dup4\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4666:4687 _signature.length - 1 */\n tag_368\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4686:4687 1 */\n 0x01\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4655:4665 _signature */\n dup3\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4666:4687 _signature.length - 1 */\n tag_336\n jump\t// in\n tag_368:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4655:4688 _signature[_signature.length - 1] */\n dup2\n dup2\n lt\n tag_370\n jumpi\n tag_370\n tag_113\n jump\t// in\n tag_370:\n swap2\n swap1\n swap2\n add\n calldataload\n 0xf8\n shr\n swap2\n pop\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":1253:1254 1 */\n 0x01\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4699:4731 signatureType == SIG_TYPE_EIP712 */\n dup2\n eq\n dup1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4699:4769 signatureType == SIG_TYPE_EIP712 || signatureType == SIG_TYPE_ETH_SIGN */\n tag_371\n jumpi\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":1303:1304 2 */\n 0x02\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4735:4748 signatureType */\n dup2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4735:4769 signatureType == SIG_TYPE_ETH_SIGN */\n eq\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4699:4769 signatureType == SIG_TYPE_EIP712 || signatureType == SIG_TYPE_ETH_SIGN */\n tag_371:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4695:5358 if (signatureType == SIG_TYPE_EIP712 || signatureType == SIG_TYPE_ETH_SIGN) {... */\n iszero\n tag_372\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4873:4880 _signer */\n dup5\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4837:4880 recoverSigner(_hash, _signature) == _signer */\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4837:4869 recoverSigner(_hash, _signature) */\n tag_373\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4851:4856 _hash */\n dup8\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4858:4868 _signature */\n dup7\n dup7\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4837:4850 recoverSigner */\n tag_264\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4837:4869 recoverSigner(_hash, _signature) */\n jump\t// in\n tag_373:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4837:4880 recoverSigner(_hash, _signature) == _signer */\n 0xffffffffffffffffffffffffffffffffffffffff\n and\n eq\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4829:4880 valid = recoverSigner(_hash, _signature) == _signer */\n swap2\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4695:5358 if (signatureType == SIG_TYPE_EIP712 || signatureType == SIG_TYPE_ETH_SIGN) {... */\n jump(tag_384)\n tag_372:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":1359:1360 3 */\n 0x03\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4898:4911 signatureType */\n dup2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4898:4938 signatureType == SIG_TYPE_WALLET_BYTES32 */\n sub\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4894:5358 if (signatureType == SIG_TYPE_WALLET_BYTES32) {... */\n tag_375\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":5060:5100 IERC1271Wallet(_signer).isValidSignature */\n 0xffffffffffffffffffffffffffffffffffffffff\n dup6\n and\n 0x1626ba7e\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":5101:5106 _hash */\n dup8\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":5108:5118 _signature */\n dup7\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":5119:5120 0 */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":5108:5118 _signature */\n dup8\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":5121:5142 _signature.length - 1 */\n tag_376\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":5141:5142 1 */\n 0x01\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":5108:5118 _signature */\n dup3\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":5121:5142 _signature.length - 1 */\n tag_336\n jump\t// in\n tag_376:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":5108:5143 _signature[0:_signature.length - 1] */\n swap3\n tag_377\n swap4\n swap3\n swap2\n swap1\n tag_193\n jump\t// in\n tag_377:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":5060:5144 IERC1271Wallet(_signer).isValidSignature(_hash, _signature[0:_signature.length - 1]) */\n mload(0x40)\n dup5\n 0xffffffff\n and\n 0xe0\n shl\n dup2\n mstore\n 0x04\n add\n tag_378\n swap4\n swap3\n swap2\n swap1\n tag_379\n jump\t// in\n tag_378:\n 0x20\n mload(0x40)\n dup1\n dup4\n sub\n dup2\n dup7\n gas\n staticcall\n iszero\n dup1\n iszero\n tag_381\n jumpi\n returndatasize\n 0x00\n dup1\n returndatacopy\n revert(0x00, returndatasize)\n tag_381:\n pop\n pop\n pop\n pop\n mload(0x40)\n returndatasize\n not(0x1f)\n 0x1f\n dup3\n add\n and\n dup3\n add\n dup1\n 0x40\n mstore\n pop\n dup2\n add\n swap1\n tag_382\n swap2\n swap1\n tag_383\n jump\t// in\n tag_382:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":5030:5144 ERC1271_MAGICVALUE_BYTES32 == IERC1271Wallet(_signer).isValidSignature(_hash, _signature[0:_signature.length - 1]) */\n 0xffffffff00000000000000000000000000000000000000000000000000000000\n and\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":5030:5056 ERC1271_MAGICVALUE_BYTES32 */\n 0x1626ba7e00000000000000000000000000000000000000000000000000000000\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":5030:5144 ERC1271_MAGICVALUE_BYTES32 == IERC1271Wallet(_signer).isValidSignature(_hash, _signature[0:_signature.length - 1]) */\n eq\n swap2\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4894:5358 if (signatureType == SIG_TYPE_WALLET_BYTES32) {... */\n jump(tag_384)\n tag_375:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":5318:5328 _signature */\n dup4\n dup4\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":5330:5343 signatureType */\n dup3\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":5345:5350 false */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":5293:5351 UnsupportedSignatureType(_signature, signatureType, false) */\n mload(0x40)\n 0x9dfba85200000000000000000000000000000000000000000000000000000000\n dup2\n mstore\n 0x04\n add\n tag_93\n swap5\n swap4\n swap3\n swap2\n swap1\n tag_363\n jump\t// in\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4894:5358 if (signatureType == SIG_TYPE_WALLET_BYTES32) {... */\n tag_384:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4547:5362 {... */\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":4411:5362 function isValidSignature(... */\n swap5\n swap4\n pop\n pop\n pop\n pop\n jump\t// out\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":2227:2409 function _leafForHardcodedSubdigest(... */\n tag_311:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":2346:2403 abi.encodePacked('Sequence static digest:\\n', _subdigest) */\n mload(0x40)\n /* \"#utility.yul\":20822:20888 */\n 0x53657175656e636520737461746963206469676573743a0a0000000000000000\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":2346:2403 abi.encodePacked('Sequence static digest:\\n', _subdigest) */\n 0x20\n dup3\n add\n /* \"#utility.yul\":20810:20889 */\n mstore\n /* \"#utility.yul\":20905:20917 */\n 0x38\n dup2\n add\n /* \"#utility.yul\":20898:20926 */\n dup3\n swap1\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":2314:2321 bytes32 */\n 0x00\n swap1\n /* \"#utility.yul\":20942:20954 */\n 0x58\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":2346:2403 abi.encodePacked('Sequence static digest:\\n', _subdigest) */\n tag_155\n /* \"#utility.yul\":20580:20960 */\n jump\n /* \"#utility.yul\":14:191 */\n tag_397:\n /* \"#utility.yul\":99:165 */\n 0xffffffff00000000000000000000000000000000000000000000000000000000\n /* \"#utility.yul\":92:97 */\n dup2\n /* \"#utility.yul\":88:166 */\n and\n /* \"#utility.yul\":81:86 */\n dup2\n /* \"#utility.yul\":78:167 */\n eq\n /* \"#utility.yul\":68:185 */\n tag_96\n jumpi\n /* \"#utility.yul\":181:182 */\n 0x00\n /* \"#utility.yul\":178:179 */\n dup1\n /* \"#utility.yul\":171:183 */\n revert\n /* \"#utility.yul\":196:441 */\n tag_19:\n /* \"#utility.yul\":254:260 */\n 0x00\n /* \"#utility.yul\":307:309 */\n 0x20\n /* \"#utility.yul\":295:304 */\n dup3\n /* \"#utility.yul\":286:293 */\n dup5\n /* \"#utility.yul\":282:305 */\n sub\n /* \"#utility.yul\":278:310 */\n slt\n /* \"#utility.yul\":275:327 */\n iszero\n tag_411\n jumpi\n /* \"#utility.yul\":323:324 */\n 0x00\n /* \"#utility.yul\":320:321 */\n dup1\n /* \"#utility.yul\":313:325 */\n revert\n /* \"#utility.yul\":275:327 */\n tag_411:\n /* \"#utility.yul\":362:371 */\n dup2\n /* \"#utility.yul\":349:372 */\n calldataload\n /* \"#utility.yul\":381:411 */\n tag_82\n /* \"#utility.yul\":405:410 */\n dup2\n /* \"#utility.yul\":381:411 */\n tag_397\n jump\t// in\n /* \"#utility.yul\":638:985 */\n tag_398:\n /* \"#utility.yul\":689:697 */\n 0x00\n /* \"#utility.yul\":699:705 */\n dup1\n /* \"#utility.yul\":753:756 */\n dup4\n /* \"#utility.yul\":746:750 */\n 0x1f\n /* \"#utility.yul\":738:744 */\n dup5\n /* \"#utility.yul\":734:751 */\n add\n /* \"#utility.yul\":730:757 */\n slt\n /* \"#utility.yul\":720:775 */\n tag_415\n jumpi\n /* \"#utility.yul\":771:772 */\n 0x00\n /* \"#utility.yul\":768:769 */\n dup1\n /* \"#utility.yul\":761:773 */\n revert\n /* \"#utility.yul\":720:775 */\n tag_415:\n pop\n /* \"#utility.yul\":794:814 */\n dup2\n calldataload\n /* \"#utility.yul\":837:855 */\n 0xffffffffffffffff\n /* \"#utility.yul\":826:856 */\n dup2\n gt\n /* \"#utility.yul\":823:873 */\n iszero\n tag_416\n jumpi\n /* \"#utility.yul\":869:870 */\n 0x00\n /* \"#utility.yul\":866:867 */\n dup1\n /* \"#utility.yul\":859:871 */\n revert\n /* \"#utility.yul\":823:873 */\n tag_416:\n /* \"#utility.yul\":906:910 */\n 0x20\n /* \"#utility.yul\":898:904 */\n dup4\n /* \"#utility.yul\":894:911 */\n add\n /* \"#utility.yul\":882:911 */\n swap2\n pop\n /* \"#utility.yul\":958:961 */\n dup4\n /* \"#utility.yul\":951:955 */\n 0x20\n /* \"#utility.yul\":942:948 */\n dup3\n /* \"#utility.yul\":934:940 */\n dup6\n /* \"#utility.yul\":930:949 */\n add\n /* \"#utility.yul\":926:956 */\n add\n /* \"#utility.yul\":923:962 */\n gt\n /* \"#utility.yul\":920:979 */\n iszero\n tag_417\n jumpi\n /* \"#utility.yul\":975:976 */\n 0x00\n /* \"#utility.yul\":972:973 */\n dup1\n /* \"#utility.yul\":965:977 */\n revert\n /* \"#utility.yul\":920:979 */\n tag_417:\n /* \"#utility.yul\":638:985 */\n swap3\n pop\n swap3\n swap1\n pop\n jump\t// out\n /* \"#utility.yul\":990:1467 */\n tag_26:\n /* \"#utility.yul\":1069:1075 */\n 0x00\n /* \"#utility.yul\":1077:1083 */\n dup1\n /* \"#utility.yul\":1085:1091 */\n 0x00\n /* \"#utility.yul\":1138:1140 */\n 0x40\n /* \"#utility.yul\":1126:1135 */\n dup5\n /* \"#utility.yul\":1117:1124 */\n dup7\n /* \"#utility.yul\":1113:1136 */\n sub\n /* \"#utility.yul\":1109:1141 */\n slt\n /* \"#utility.yul\":1106:1158 */\n iszero\n tag_419\n jumpi\n /* \"#utility.yul\":1154:1155 */\n 0x00\n /* \"#utility.yul\":1151:1152 */\n dup1\n /* \"#utility.yul\":1144:1156 */\n revert\n /* \"#utility.yul\":1106:1158 */\n tag_419:\n /* \"#utility.yul\":1190:1199 */\n dup4\n /* \"#utility.yul\":1177:1200 */\n calldataload\n /* \"#utility.yul\":1167:1200 */\n swap3\n pop\n /* \"#utility.yul\":1251:1253 */\n 0x20\n /* \"#utility.yul\":1240:1249 */\n dup5\n /* \"#utility.yul\":1236:1254 */\n add\n /* \"#utility.yul\":1223:1255 */\n calldataload\n /* \"#utility.yul\":1278:1296 */\n 0xffffffffffffffff\n /* \"#utility.yul\":1270:1276 */\n dup2\n /* \"#utility.yul\":1267:1297 */\n gt\n /* \"#utility.yul\":1264:1314 */\n iszero\n tag_420\n jumpi\n /* \"#utility.yul\":1310:1311 */\n 0x00\n /* \"#utility.yul\":1307:1308 */\n dup1\n /* \"#utility.yul\":1300:1312 */\n revert\n /* \"#utility.yul\":1264:1314 */\n tag_420:\n /* \"#utility.yul\":1349:1407 */\n tag_421\n /* \"#utility.yul\":1399:1406 */\n dup7\n /* \"#utility.yul\":1390:1396 */\n dup3\n /* \"#utility.yul\":1379:1388 */\n dup8\n /* \"#utility.yul\":1375:1397 */\n add\n /* \"#utility.yul\":1349:1407 */\n tag_398\n jump\t// in\n tag_421:\n /* \"#utility.yul\":990:1467 */\n swap5\n swap8\n /* \"#utility.yul\":1426:1434 */\n swap1\n swap7\n pop\n /* \"#utility.yul\":1323:1407 */\n swap4\n swap5\n pop\n pop\n pop\n pop\n /* \"#utility.yul\":990:1467 */\n jump\t// out\n /* \"#utility.yul\":1725:2442 */\n tag_33:\n /* \"#utility.yul\":1815:1821 */\n 0x00\n /* \"#utility.yul\":1823:1829 */\n dup1\n /* \"#utility.yul\":1831:1837 */\n 0x00\n /* \"#utility.yul\":1839:1845 */\n dup1\n /* \"#utility.yul\":1892:1894 */\n 0x40\n /* \"#utility.yul\":1880:1889 */\n dup6\n /* \"#utility.yul\":1871:1878 */\n dup8\n /* \"#utility.yul\":1867:1890 */\n sub\n /* \"#utility.yul\":1863:1895 */\n slt\n /* \"#utility.yul\":1860:1912 */\n iszero\n tag_424\n jumpi\n /* \"#utility.yul\":1908:1909 */\n 0x00\n /* \"#utility.yul\":1905:1906 */\n dup1\n /* \"#utility.yul\":1898:1910 */\n revert\n /* \"#utility.yul\":1860:1912 */\n tag_424:\n /* \"#utility.yul\":1948:1957 */\n dup5\n /* \"#utility.yul\":1935:1958 */\n calldataload\n /* \"#utility.yul\":1977:1995 */\n 0xffffffffffffffff\n /* \"#utility.yul\":2018:2020 */\n dup1\n /* \"#utility.yul\":2010:2016 */\n dup3\n /* \"#utility.yul\":2007:2021 */\n gt\n /* \"#utility.yul\":2004:2038 */\n iszero\n tag_425\n jumpi\n /* \"#utility.yul\":2034:2035 */\n 0x00\n /* \"#utility.yul\":2031:2032 */\n dup1\n /* \"#utility.yul\":2024:2036 */\n revert\n /* \"#utility.yul\":2004:2038 */\n tag_425:\n /* \"#utility.yul\":2073:2131 */\n tag_426\n /* \"#utility.yul\":2123:2130 */\n dup9\n /* \"#utility.yul\":2114:2120 */\n dup4\n /* \"#utility.yul\":2103:2112 */\n dup10\n /* \"#utility.yul\":2099:2121 */\n add\n /* \"#utility.yul\":2073:2131 */\n tag_398\n jump\t// in\n tag_426:\n /* \"#utility.yul\":2150:2158 */\n swap1\n swap7\n pop\n /* \"#utility.yul\":2047:2131 */\n swap5\n pop\n /* \"#utility.yul\":2238:2240 */\n 0x20\n /* \"#utility.yul\":2223:2241 */\n dup8\n add\n /* \"#utility.yul\":2210:2242 */\n calldataload\n swap2\n pop\n /* \"#utility.yul\":2254:2270 */\n dup1\n dup3\n gt\n /* \"#utility.yul\":2251:2287 */\n iszero\n tag_427\n jumpi\n /* \"#utility.yul\":2283:2284 */\n 0x00\n /* \"#utility.yul\":2280:2281 */\n dup1\n /* \"#utility.yul\":2273:2285 */\n revert\n /* \"#utility.yul\":2251:2287 */\n tag_427:\n pop\n /* \"#utility.yul\":2322:2382 */\n tag_428\n /* \"#utility.yul\":2374:2381 */\n dup8\n /* \"#utility.yul\":2363:2371 */\n dup3\n /* \"#utility.yul\":2352:2361 */\n dup9\n /* \"#utility.yul\":2348:2372 */\n add\n /* \"#utility.yul\":2322:2382 */\n tag_398\n jump\t// in\n tag_428:\n /* \"#utility.yul\":1725:2442 */\n swap6\n swap9\n swap5\n swap8\n pop\n /* \"#utility.yul\":2401:2409 */\n swap6\n pop\n pop\n pop\n pop\n /* \"#utility.yul\":1725:2442 */\n jump\t// out\n /* \"#utility.yul\":2447:2627 */\n tag_39:\n /* \"#utility.yul\":2506:2512 */\n 0x00\n /* \"#utility.yul\":2559:2561 */\n 0x20\n /* \"#utility.yul\":2547:2556 */\n dup3\n /* \"#utility.yul\":2538:2545 */\n dup5\n /* \"#utility.yul\":2534:2557 */\n sub\n /* \"#utility.yul\":2530:2562 */\n slt\n /* \"#utility.yul\":2527:2579 */\n iszero\n tag_430\n jumpi\n /* \"#utility.yul\":2575:2576 */\n 0x00\n /* \"#utility.yul\":2572:2573 */\n dup1\n /* \"#utility.yul\":2565:2577 */\n revert\n /* \"#utility.yul\":2527:2579 */\n tag_430:\n pop\n /* \"#utility.yul\":2598:2621 */\n calldataload\n swap2\n /* \"#utility.yul\":2447:2627 */\n swap1\n pop\n jump\t// out\n /* \"#utility.yul\":2814:3201 */\n tag_399:\n /* \"#utility.yul\":2897:2905 */\n 0x00\n /* \"#utility.yul\":2907:2913 */\n dup1\n /* \"#utility.yul\":2961:2964 */\n dup4\n /* \"#utility.yul\":2954:2958 */\n 0x1f\n /* \"#utility.yul\":2946:2952 */\n dup5\n /* \"#utility.yul\":2942:2959 */\n add\n /* \"#utility.yul\":2938:2965 */\n slt\n /* \"#utility.yul\":2928:2983 */\n tag_433\n jumpi\n /* \"#utility.yul\":2979:2980 */\n 0x00\n /* \"#utility.yul\":2976:2977 */\n dup1\n /* \"#utility.yul\":2969:2981 */\n revert\n /* \"#utility.yul\":2928:2983 */\n tag_433:\n pop\n /* \"#utility.yul\":3002:3022 */\n dup2\n calldataload\n /* \"#utility.yul\":3045:3063 */\n 0xffffffffffffffff\n /* \"#utility.yul\":3034:3064 */\n dup2\n gt\n /* \"#utility.yul\":3031:3081 */\n iszero\n tag_434\n jumpi\n /* \"#utility.yul\":3077:3078 */\n 0x00\n /* \"#utility.yul\":3074:3075 */\n dup1\n /* \"#utility.yul\":3067:3079 */\n revert\n /* \"#utility.yul\":3031:3081 */\n tag_434:\n /* \"#utility.yul\":3114:3118 */\n 0x20\n /* \"#utility.yul\":3106:3112 */\n dup4\n /* \"#utility.yul\":3102:3119 */\n add\n /* \"#utility.yul\":3090:3119 */\n swap2\n pop\n /* \"#utility.yul\":3174:3177 */\n dup4\n /* \"#utility.yul\":3167:3171 */\n 0x20\n /* \"#utility.yul\":3157:3163 */\n dup3\n /* \"#utility.yul\":3154:3155 */\n 0x05\n /* \"#utility.yul\":3150:3164 */\n shl\n /* \"#utility.yul\":3142:3148 */\n dup6\n /* \"#utility.yul\":3138:3165 */\n add\n /* \"#utility.yul\":3134:3172 */\n add\n /* \"#utility.yul\":3131:3178 */\n gt\n /* \"#utility.yul\":3128:3195 */\n iszero\n tag_417\n jumpi\n /* \"#utility.yul\":3191:3192 */\n 0x00\n /* \"#utility.yul\":3188:3189 */\n dup1\n /* \"#utility.yul\":3181:3193 */\n revert\n /* \"#utility.yul\":3206:3694 */\n tag_49:\n /* \"#utility.yul\":3323:3329 */\n 0x00\n /* \"#utility.yul\":3331:3337 */\n dup1\n /* \"#utility.yul\":3384:3386 */\n 0x20\n /* \"#utility.yul\":3372:3381 */\n dup4\n /* \"#utility.yul\":3363:3370 */\n dup6\n /* \"#utility.yul\":3359:3382 */\n sub\n /* \"#utility.yul\":3355:3387 */\n slt\n /* \"#utility.yul\":3352:3404 */\n iszero\n tag_437\n jumpi\n /* \"#utility.yul\":3400:3401 */\n 0x00\n /* \"#utility.yul\":3397:3398 */\n dup1\n /* \"#utility.yul\":3390:3402 */\n revert\n /* \"#utility.yul\":3352:3404 */\n tag_437:\n /* \"#utility.yul\":3440:3449 */\n dup3\n /* \"#utility.yul\":3427:3450 */\n calldataload\n /* \"#utility.yul\":3473:3491 */\n 0xffffffffffffffff\n /* \"#utility.yul\":3465:3471 */\n dup2\n /* \"#utility.yul\":3462:3492 */\n gt\n /* \"#utility.yul\":3459:3509 */\n iszero\n tag_438\n jumpi\n /* \"#utility.yul\":3505:3506 */\n 0x00\n /* \"#utility.yul\":3502:3503 */\n dup1\n /* \"#utility.yul\":3495:3507 */\n revert\n /* \"#utility.yul\":3459:3509 */\n tag_438:\n /* \"#utility.yul\":3544:3634 */\n tag_439\n /* \"#utility.yul\":3626:3633 */\n dup6\n /* \"#utility.yul\":3617:3623 */\n dup3\n /* \"#utility.yul\":3606:3615 */\n dup7\n /* \"#utility.yul\":3602:3624 */\n add\n /* \"#utility.yul\":3544:3634 */\n tag_399\n jump\t// in\n tag_439:\n /* \"#utility.yul\":3653:3661 */\n swap1\n swap7\n /* \"#utility.yul\":3518:3634 */\n swap1\n swap6\n pop\n /* \"#utility.yul\":3206:3694 */\n swap4\n pop\n pop\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":3699:4563 */\n tag_54:\n /* \"#utility.yul\":3845:3851 */\n 0x00\n /* \"#utility.yul\":3853:3859 */\n dup1\n /* \"#utility.yul\":3861:3867 */\n 0x00\n /* \"#utility.yul\":3869:3875 */\n dup1\n /* \"#utility.yul\":3877:3883 */\n 0x00\n /* \"#utility.yul\":3930:3932 */\n 0x60\n /* \"#utility.yul\":3918:3927 */\n dup7\n /* \"#utility.yul\":3909:3916 */\n dup9\n /* \"#utility.yul\":3905:3928 */\n sub\n /* \"#utility.yul\":3901:3933 */\n slt\n /* \"#utility.yul\":3898:3950 */\n iszero\n tag_441\n jumpi\n /* \"#utility.yul\":3946:3947 */\n 0x00\n /* \"#utility.yul\":3943:3944 */\n dup1\n /* \"#utility.yul\":3936:3948 */\n revert\n /* \"#utility.yul\":3898:3950 */\n tag_441:\n /* \"#utility.yul\":3986:3995 */\n dup6\n /* \"#utility.yul\":3973:3996 */\n calldataload\n /* \"#utility.yul\":4015:4033 */\n 0xffffffffffffffff\n /* \"#utility.yul\":4056:4058 */\n dup1\n /* \"#utility.yul\":4048:4054 */\n dup3\n /* \"#utility.yul\":4045:4059 */\n gt\n /* \"#utility.yul\":4042:4076 */\n iszero\n tag_442\n jumpi\n /* \"#utility.yul\":4072:4073 */\n 0x00\n /* \"#utility.yul\":4069:4070 */\n dup1\n /* \"#utility.yul\":4062:4074 */\n revert\n /* \"#utility.yul\":4042:4076 */\n tag_442:\n /* \"#utility.yul\":4111:4201 */\n tag_443\n /* \"#utility.yul\":4193:4200 */\n dup10\n /* \"#utility.yul\":4184:4190 */\n dup4\n /* \"#utility.yul\":4173:4182 */\n dup11\n /* \"#utility.yul\":4169:4191 */\n add\n /* \"#utility.yul\":4111:4201 */\n tag_399\n jump\t// in\n tag_443:\n /* \"#utility.yul\":4220:4228 */\n swap1\n swap8\n pop\n /* \"#utility.yul\":4085:4201 */\n swap6\n pop\n /* \"#utility.yul\":4302:4304 */\n 0x20\n /* \"#utility.yul\":4287:4305 */\n dup9\n add\n /* \"#utility.yul\":4274:4306 */\n calldataload\n swap5\n pop\n /* \"#utility.yul\":4359:4361 */\n 0x40\n /* \"#utility.yul\":4344:4362 */\n dup9\n add\n /* \"#utility.yul\":4331:4363 */\n calldataload\n swap2\n pop\n /* \"#utility.yul\":4375:4391 */\n dup1\n dup3\n gt\n /* \"#utility.yul\":4372:4408 */\n iszero\n tag_444\n jumpi\n /* \"#utility.yul\":4404:4405 */\n 0x00\n /* \"#utility.yul\":4401:4402 */\n dup1\n /* \"#utility.yul\":4394:4406 */\n revert\n /* \"#utility.yul\":4372:4408 */\n tag_444:\n pop\n /* \"#utility.yul\":4443:4503 */\n tag_445\n /* \"#utility.yul\":4495:4502 */\n dup9\n /* \"#utility.yul\":4484:4492 */\n dup3\n /* \"#utility.yul\":4473:4482 */\n dup10\n /* \"#utility.yul\":4469:4493 */\n add\n /* \"#utility.yul\":4443:4503 */\n tag_398\n jump\t// in\n tag_445:\n /* \"#utility.yul\":3699:4563 */\n swap7\n swap10\n swap6\n swap9\n pop\n swap4\n swap7\n pop\n /* \"#utility.yul\":4522:4530 */\n swap3\n swap5\n /* \"#utility.yul\":4417:4503 */\n swap4\n /* \"#utility.yul\":3699:4563 */\n swap3\n pop\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":5403:5587 */\n tag_400:\n /* \"#utility.yul\":5455:5532 */\n 0x4e487b7100000000000000000000000000000000000000000000000000000000\n /* \"#utility.yul\":5452:5453 */\n 0x00\n /* \"#utility.yul\":5445:5533 */\n mstore\n /* \"#utility.yul\":5552:5556 */\n 0x41\n /* \"#utility.yul\":5549:5550 */\n 0x04\n /* \"#utility.yul\":5542:5557 */\n mstore\n /* \"#utility.yul\":5576:5580 */\n 0x24\n /* \"#utility.yul\":5573:5574 */\n 0x00\n /* \"#utility.yul\":5566:5581 */\n revert\n /* \"#utility.yul\":5592:6572 */\n tag_71:\n /* \"#utility.yul\":5660:5666 */\n 0x00\n /* \"#utility.yul\":5713:5715 */\n 0x20\n /* \"#utility.yul\":5701:5710 */\n dup3\n /* \"#utility.yul\":5692:5699 */\n dup5\n /* \"#utility.yul\":5688:5711 */\n sub\n /* \"#utility.yul\":5684:5716 */\n slt\n /* \"#utility.yul\":5681:5733 */\n iszero\n tag_452\n jumpi\n /* \"#utility.yul\":5729:5730 */\n 0x00\n /* \"#utility.yul\":5726:5727 */\n dup1\n /* \"#utility.yul\":5719:5731 */\n revert\n /* \"#utility.yul\":5681:5733 */\n tag_452:\n /* \"#utility.yul\":5769:5778 */\n dup2\n /* \"#utility.yul\":5756:5779 */\n calldataload\n /* \"#utility.yul\":5798:5816 */\n 0xffffffffffffffff\n /* \"#utility.yul\":5839:5841 */\n dup1\n /* \"#utility.yul\":5831:5837 */\n dup3\n /* \"#utility.yul\":5828:5842 */\n gt\n /* \"#utility.yul\":5825:5859 */\n iszero\n tag_453\n jumpi\n /* \"#utility.yul\":5855:5856 */\n 0x00\n /* \"#utility.yul\":5852:5853 */\n dup1\n /* \"#utility.yul\":5845:5857 */\n revert\n /* \"#utility.yul\":5825:5859 */\n tag_453:\n /* \"#utility.yul\":5893:5899 */\n dup2\n /* \"#utility.yul\":5882:5891 */\n dup5\n /* \"#utility.yul\":5878:5900 */\n add\n /* \"#utility.yul\":5868:5900 */\n swap2\n pop\n /* \"#utility.yul\":5938:5945 */\n dup5\n /* \"#utility.yul\":5931:5935 */\n 0x1f\n /* \"#utility.yul\":5927:5929 */\n dup4\n /* \"#utility.yul\":5923:5936 */\n add\n /* \"#utility.yul\":5919:5946 */\n slt\n /* \"#utility.yul\":5909:5964 */\n tag_454\n jumpi\n /* \"#utility.yul\":5960:5961 */\n 0x00\n /* \"#utility.yul\":5957:5958 */\n dup1\n /* \"#utility.yul\":5950:5962 */\n revert\n /* \"#utility.yul\":5909:5964 */\n tag_454:\n /* \"#utility.yul\":5996:5998 */\n dup2\n /* \"#utility.yul\":5983:5999 */\n calldataload\n /* \"#utility.yul\":6018:6020 */\n dup2\n /* \"#utility.yul\":6014:6016 */\n dup2\n /* \"#utility.yul\":6011:6021 */\n gt\n /* \"#utility.yul\":6008:6044 */\n iszero\n tag_456\n jumpi\n /* \"#utility.yul\":6024:6042 */\n tag_456\n tag_400\n jump\t// in\n tag_456:\n /* \"#utility.yul\":6158:6160 */\n 0x40\n /* \"#utility.yul\":6152:6161 */\n mload\n /* \"#utility.yul\":6220:6224 */\n 0x1f\n /* \"#utility.yul\":6212:6225 */\n dup3\n add\n /* \"#utility.yul\":6063:6129 */\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0\n /* \"#utility.yul\":6208:6230 */\n swap1\n dup2\n and\n /* \"#utility.yul\":6232:6234 */\n 0x3f\n /* \"#utility.yul\":6204:6235 */\n add\n /* \"#utility.yul\":6200:6240 */\n and\n /* \"#utility.yul\":6188:6241 */\n dup2\n add\n swap1\n /* \"#utility.yul\":6256:6274 */\n dup4\n dup3\n gt\n /* \"#utility.yul\":6276:6298 */\n dup2\n dup4\n lt\n /* \"#utility.yul\":6253:6299 */\n or\n /* \"#utility.yul\":6250:6322 */\n iszero\n tag_458\n jumpi\n /* \"#utility.yul\":6302:6320 */\n tag_458\n tag_400\n jump\t// in\n tag_458:\n /* \"#utility.yul\":6342:6352 */\n dup2\n /* \"#utility.yul\":6338:6340 */\n 0x40\n /* \"#utility.yul\":6331:6353 */\n mstore\n /* \"#utility.yul\":6377:6379 */\n dup3\n /* \"#utility.yul\":6369:6375 */\n dup2\n /* \"#utility.yul\":6362:6380 */\n mstore\n /* \"#utility.yul\":6417:6424 */\n dup8\n /* \"#utility.yul\":6412:6414 */\n 0x20\n /* \"#utility.yul\":6407:6409 */\n dup5\n /* \"#utility.yul\":6403:6405 */\n dup8\n /* \"#utility.yul\":6399:6410 */\n add\n /* \"#utility.yul\":6395:6415 */\n add\n /* \"#utility.yul\":6392:6425 */\n gt\n /* \"#utility.yul\":6389:6442 */\n iszero\n tag_459\n jumpi\n /* \"#utility.yul\":6438:6439 */\n 0x00\n /* \"#utility.yul\":6435:6436 */\n dup1\n /* \"#utility.yul\":6428:6440 */\n revert\n /* \"#utility.yul\":6389:6442 */\n tag_459:\n /* \"#utility.yul\":6494:6496 */\n dup3\n /* \"#utility.yul\":6489:6491 */\n 0x20\n /* \"#utility.yul\":6485:6487 */\n dup7\n /* \"#utility.yul\":6481:6492 */\n add\n /* \"#utility.yul\":6476:6478 */\n 0x20\n /* \"#utility.yul\":6468:6474 */\n dup4\n /* \"#utility.yul\":6464:6479 */\n add\n /* \"#utility.yul\":6451:6497 */\n calldatacopy\n /* \"#utility.yul\":6539:6540 */\n 0x00\n /* \"#utility.yul\":6517:6532 */\n swap3\n dup2\n add\n /* \"#utility.yul\":6534:6536 */\n 0x20\n /* \"#utility.yul\":6513:6537 */\n add\n /* \"#utility.yul\":6506:6541 */\n swap3\n swap1\n swap3\n mstore\n pop\n /* \"#utility.yul\":6521:6527 */\n swap6\n /* \"#utility.yul\":5592:6572 */\n swap5\n pop\n pop\n pop\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":6808:7079 */\n tag_89:\n /* \"#utility.yul\":6991:6997 */\n dup2\n /* \"#utility.yul\":6983:6989 */\n dup4\n /* \"#utility.yul\":6978:6981 */\n dup3\n /* \"#utility.yul\":6965:6998 */\n calldatacopy\n /* \"#utility.yul\":6947:6950 */\n 0x00\n /* \"#utility.yul\":7017:7033 */\n swap2\n add\n /* \"#utility.yul\":7042:7055 */\n swap1\n dup2\n mstore\n /* \"#utility.yul\":7017:7033 */\n swap2\n /* \"#utility.yul\":6808:7079 */\n swap1\n pop\n jump\t// out\n /* \"#utility.yul\":7416:7576 */\n tag_401:\n /* \"#utility.yul\":7481:7501 */\n dup1\n calldataload\n /* \"#utility.yul\":7537:7550 */\n dup1\n iszero\n /* \"#utility.yul\":7530:7551 */\n iszero\n /* \"#utility.yul\":7520:7552 */\n dup2\n eq\n /* \"#utility.yul\":7510:7570 */\n tag_464\n jumpi\n /* \"#utility.yul\":7566:7567 */\n 0x00\n /* \"#utility.yul\":7563:7564 */\n dup1\n /* \"#utility.yul\":7556:7568 */\n revert\n /* \"#utility.yul\":7510:7570 */\n tag_464:\n /* \"#utility.yul\":7416:7576 */\n swap2\n swap1\n pop\n jump\t// out\n /* \"#utility.yul\":7581:7777 */\n tag_402:\n /* \"#utility.yul\":7649:7669 */\n dup1\n calldataload\n /* \"#utility.yul\":7709:7751 */\n 0xffffffffffffffffffffffffffffffffffffffff\n /* \"#utility.yul\":7698:7752 */\n dup2\n and\n /* \"#utility.yul\":7688:7753 */\n dup2\n eq\n /* \"#utility.yul\":7678:7771 */\n tag_464\n jumpi\n /* \"#utility.yul\":7767:7768 */\n 0x00\n /* \"#utility.yul\":7764:7765 */\n dup1\n /* \"#utility.yul\":7757:7769 */\n revert\n /* \"#utility.yul\":7782:8107 */\n tag_403:\n /* \"#utility.yul\":7870:7876 */\n dup2\n /* \"#utility.yul\":7865:7868 */\n dup4\n /* \"#utility.yul\":7858:7877 */\n mstore\n /* \"#utility.yul\":7922:7928 */\n dup2\n /* \"#utility.yul\":7915:7920 */\n dup2\n /* \"#utility.yul\":7908:7912 */\n 0x20\n /* \"#utility.yul\":7903:7906 */\n dup6\n /* \"#utility.yul\":7899:7913 */\n add\n /* \"#utility.yul\":7886:7929 */\n calldatacopy\n pop\n /* \"#utility.yul\":7974:7975 */\n 0x00\n /* \"#utility.yul\":7967:7971 */\n 0x20\n /* \"#utility.yul\":7958:7964 */\n dup3\n /* \"#utility.yul\":7953:7956 */\n dup5\n /* \"#utility.yul\":7949:7965 */\n add\n /* \"#utility.yul\":7945:7972 */\n add\n /* \"#utility.yul\":7938:7976 */\n mstore\n /* \"#utility.yul\":7840:7843 */\n 0x00\n /* \"#utility.yul\":8096:8100 */\n 0x20\n /* \"#utility.yul\":8026:8092 */\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0\n /* \"#utility.yul\":8021:8023 */\n 0x1f\n /* \"#utility.yul\":8013:8019 */\n dup5\n /* \"#utility.yul\":8009:8024 */\n add\n /* \"#utility.yul\":8005:8093 */\n and\n /* \"#utility.yul\":8000:8003 */\n dup5\n /* \"#utility.yul\":7996:8094 */\n add\n /* \"#utility.yul\":7992:8101 */\n add\n /* \"#utility.yul\":7985:8101 */\n swap1\n pop\n /* \"#utility.yul\":7782:8107 */\n swap3\n swap2\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":8112:10140 */\n tag_404:\n /* \"#utility.yul\":8232:8238 */\n dup2\n /* \"#utility.yul\":8227:8230 */\n dup4\n /* \"#utility.yul\":8220:8239 */\n mstore\n /* \"#utility.yul\":8202:8205 */\n 0x00\n /* \"#utility.yul\":8258:8262 */\n 0x20\n /* \"#utility.yul\":8299:8301 */\n dup1\n /* \"#utility.yul\":8294:8297 */\n dup6\n /* \"#utility.yul\":8290:8302 */\n add\n /* \"#utility.yul\":8324:8335 */\n dup1\n /* \"#utility.yul\":8351:8362 */\n dup2\n /* \"#utility.yul\":8344:8362 */\n swap7\n pop\n /* \"#utility.yul\":8401:8407 */\n dup6\n /* \"#utility.yul\":8398:8399 */\n 0x05\n /* \"#utility.yul\":8394:8408 */\n shl\n /* \"#utility.yul\":8387:8392 */\n dup2\n /* \"#utility.yul\":8383:8409 */\n add\n /* \"#utility.yul\":8371:8409 */\n swap2\n pop\n /* \"#utility.yul\":8432:8437 */\n dup5\n /* \"#utility.yul\":8455:8456 */\n 0x00\n /* \"#utility.yul\":8465:10114 */\n tag_469:\n /* \"#utility.yul\":8479:8485 */\n dup8\n /* \"#utility.yul\":8476:8477 */\n dup2\n /* \"#utility.yul\":8473:8486 */\n lt\n /* \"#utility.yul\":8465:10114 */\n iszero\n tag_471\n jumpi\n /* \"#utility.yul\":8550:8555 */\n dup3\n /* \"#utility.yul\":8544:8548 */\n dup5\n /* \"#utility.yul\":8540:8556 */\n sub\n /* \"#utility.yul\":8535:8538 */\n dup10\n /* \"#utility.yul\":8528:8557 */\n mstore\n /* \"#utility.yul\":8609:8615 */\n dup2\n /* \"#utility.yul\":8596:8616 */\n calldataload\n /* \"#utility.yul\":8695:8761 */\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff41\n /* \"#utility.yul\":8687:8692 */\n dup9\n /* \"#utility.yul\":8671:8685 */\n calldatasize\n /* \"#utility.yul\":8667:8693 */\n sub\n /* \"#utility.yul\":8663:8762 */\n add\n /* \"#utility.yul\":8643:8661 */\n dup2\n /* \"#utility.yul\":8639:8763 */\n slt\n /* \"#utility.yul\":8629:8781 */\n tag_472\n jumpi\n /* \"#utility.yul\":8777:8778 */\n 0x00\n /* \"#utility.yul\":8774:8775 */\n dup1\n /* \"#utility.yul\":8767:8779 */\n revert\n /* \"#utility.yul\":8629:8781 */\n tag_472:\n /* \"#utility.yul\":8809:8839 */\n dup8\n add\n /* \"#utility.yul\":8862:8866 */\n 0xc0\n /* \"#utility.yul\":8906:8930 */\n tag_473\n /* \"#utility.yul\":8809:8839 */\n dup3\n /* \"#utility.yul\":8906:8930 */\n tag_401\n jump\t// in\n tag_473:\n /* \"#utility.yul\":8899:8931 */\n iszero\n /* \"#utility.yul\":8892:8932 */\n iszero\n /* \"#utility.yul\":8886:8890 */\n dup7\n /* \"#utility.yul\":8879:8933 */\n mstore\n /* \"#utility.yul\":8982:9015 */\n tag_474\n /* \"#utility.yul\":9011:9013 */\n dup8\n /* \"#utility.yul\":9002:9009 */\n dup4\n /* \"#utility.yul\":8998:9014 */\n add\n /* \"#utility.yul\":8982:9015 */\n tag_401\n jump\t// in\n tag_474:\n /* \"#utility.yul\":8975:9016 */\n iszero\n /* \"#utility.yul\":8968:9017 */\n iszero\n /* \"#utility.yul\":8953:8966 */\n dup7\n dup9\n add\n /* \"#utility.yul\":8946:9018 */\n mstore\n /* \"#utility.yul\":9041:9045 */\n 0x40\n /* \"#utility.yul\":9093:9109 */\n dup3\n dup2\n add\n /* \"#utility.yul\":9080:9110 */\n calldataload\n /* \"#utility.yul\":9065:9078 */\n swap1\n dup8\n add\n /* \"#utility.yul\":9058:9111 */\n mstore\n /* \"#utility.yul\":9134:9138 */\n 0x60\n /* \"#utility.yul\":9215:9257 */\n 0xffffffffffffffffffffffffffffffffffffffff\n /* \"#utility.yul\":9177:9213 */\n tag_475\n /* \"#utility.yul\":9196:9212 */\n dup3\n dup6\n add\n /* \"#utility.yul\":9177:9213 */\n tag_402\n jump\t// in\n tag_475:\n /* \"#utility.yul\":9173:9258 */\n and\n /* \"#utility.yul\":9158:9171 */\n swap1\n dup8\n add\n /* \"#utility.yul\":9151:9259 */\n mstore\n /* \"#utility.yul\":9282:9286 */\n 0x80\n /* \"#utility.yul\":9334:9350 */\n dup3\n dup2\n add\n /* \"#utility.yul\":9321:9351 */\n calldataload\n /* \"#utility.yul\":9306:9319 */\n swap1\n dup8\n add\n /* \"#utility.yul\":9299:9352 */\n mstore\n /* \"#utility.yul\":9375:9379 */\n 0xa0\n /* \"#utility.yul\":9433:9449 */\n dup1\n dup4\n add\n /* \"#utility.yul\":9420:9450 */\n calldataload\n /* \"#utility.yul\":9507:9521 */\n calldatasize\n /* \"#utility.yul\":9503:9531 */\n dup5\n swap1\n sub\n /* \"#utility.yul\":9533:9599 */\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1\n /* \"#utility.yul\":9499:9600 */\n add\n /* \"#utility.yul\":9473:9601 */\n dup2\n slt\n /* \"#utility.yul\":9463:9619 */\n tag_476\n jumpi\n /* \"#utility.yul\":9615:9616 */\n 0x00\n /* \"#utility.yul\":9612:9613 */\n dup1\n /* \"#utility.yul\":9605:9617 */\n revert\n /* \"#utility.yul\":9463:9619 */\n tag_476:\n /* \"#utility.yul\":9647:9681 */\n swap1\n swap3\n add\n /* \"#utility.yul\":9759:9775 */\n dup8\n dup2\n add\n swap3\n swap1\n /* \"#utility.yul\":9710:9731 */\n calldataload\n /* \"#utility.yul\":9804:9822 */\n 0xffffffffffffffff\n /* \"#utility.yul\":9791:9823 */\n dup2\n gt\n /* \"#utility.yul\":9788:9840 */\n iszero\n tag_477\n jumpi\n /* \"#utility.yul\":9836:9837 */\n 0x00\n /* \"#utility.yul\":9833:9834 */\n dup1\n /* \"#utility.yul\":9826:9838 */\n revert\n /* \"#utility.yul\":9788:9840 */\n tag_477:\n /* \"#utility.yul\":9889:9897 */\n dup1\n /* \"#utility.yul\":9873:9887 */\n calldatasize\n /* \"#utility.yul\":9869:9898 */\n sub\n /* \"#utility.yul\":9860:9867 */\n dup5\n /* \"#utility.yul\":9856:9899 */\n sgt\n /* \"#utility.yul\":9853:9916 */\n iszero\n tag_478\n jumpi\n /* \"#utility.yul\":9912:9913 */\n 0x00\n /* \"#utility.yul\":9909:9910 */\n dup1\n /* \"#utility.yul\":9902:9914 */\n revert\n /* \"#utility.yul\":9853:9916 */\n tag_478:\n /* \"#utility.yul\":9951:9953 */\n dup3\n /* \"#utility.yul\":9946:9948 */\n dup3\n /* \"#utility.yul\":9940:9944 */\n dup10\n /* \"#utility.yul\":9936:9949 */\n add\n /* \"#utility.yul\":9929:9954 */\n mstore\n /* \"#utility.yul\":9975:10034 */\n tag_479\n /* \"#utility.yul\":10030:10032 */\n dup4\n /* \"#utility.yul\":10024:10028 */\n dup10\n /* \"#utility.yul\":10020:10033 */\n add\n /* \"#utility.yul\":10010:10018 */\n dup3\n /* \"#utility.yul\":10001:10008 */\n dup7\n /* \"#utility.yul\":9975:10034 */\n tag_403\n jump\t// in\n tag_479:\n /* \"#utility.yul\":10092:10104 */\n swap13\n dup10\n add\n swap13\n /* \"#utility.yul\":9967:10034 */\n swap8\n pop\n pop\n pop\n /* \"#utility.yul\":10057:10072 */\n swap3\n dup7\n add\n swap3\n pop\n pop\n /* \"#utility.yul\":8501:8502 */\n 0x01\n /* \"#utility.yul\":8494:8503 */\n add\n /* \"#utility.yul\":8465:10114 */\n jump(tag_469)\n tag_471:\n pop\n /* \"#utility.yul\":10130:10134 */\n swap2\n swap8\n /* \"#utility.yul\":8112:10140 */\n swap7\n pop\n pop\n pop\n pop\n pop\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":10145:10739 */\n tag_101:\n /* \"#utility.yul\":10495:10497 */\n 0x40\n /* \"#utility.yul\":10484:10493 */\n dup2\n /* \"#utility.yul\":10477:10498 */\n mstore\n /* \"#utility.yul\":10534:10535 */\n 0x05\n /* \"#utility.yul\":10529:10531 */\n 0x40\n /* \"#utility.yul\":10518:10527 */\n dup3\n /* \"#utility.yul\":10514:10532 */\n add\n /* \"#utility.yul\":10507:10536 */\n mstore\n /* \"#utility.yul\":10572:10579 */\n 0x73656c663a000000000000000000000000000000000000000000000000000000\n /* \"#utility.yul\":10567:10569 */\n 0x60\n /* \"#utility.yul\":10556:10565 */\n dup3\n /* \"#utility.yul\":10552:10570 */\n add\n /* \"#utility.yul\":10545:10580 */\n mstore\n /* \"#utility.yul\":10618:10621 */\n 0x80\n /* \"#utility.yul\":10611:10615 */\n 0x20\n /* \"#utility.yul\":10600:10609 */\n dup3\n /* \"#utility.yul\":10596:10616 */\n add\n /* \"#utility.yul\":10589:10622 */\n mstore\n /* \"#utility.yul\":10458:10462 */\n 0x00\n /* \"#utility.yul\":10639:10733 */\n tag_86\n /* \"#utility.yul\":10728:10731 */\n 0x80\n /* \"#utility.yul\":10717:10726 */\n dup4\n /* \"#utility.yul\":10713:10732 */\n add\n /* \"#utility.yul\":10705:10711 */\n dup5\n /* \"#utility.yul\":10697:10703 */\n dup7\n /* \"#utility.yul\":10639:10733 */\n tag_404\n jump\t// in\n /* \"#utility.yul\":10744:11339 */\n tag_108:\n /* \"#utility.yul\":11094:11096 */\n 0x40\n /* \"#utility.yul\":11083:11092 */\n dup2\n /* \"#utility.yul\":11076:11097 */\n mstore\n /* \"#utility.yul\":11133:11134 */\n 0x06\n /* \"#utility.yul\":11128:11130 */\n 0x40\n /* \"#utility.yul\":11117:11126 */\n dup3\n /* \"#utility.yul\":11113:11131 */\n add\n /* \"#utility.yul\":11106:11135 */\n mstore\n /* \"#utility.yul\":11171:11179 */\n 0x67756573743a0000000000000000000000000000000000000000000000000000\n /* \"#utility.yul\":11166:11168 */\n 0x60\n /* \"#utility.yul\":11155:11164 */\n dup3\n /* \"#utility.yul\":11151:11169 */\n add\n /* \"#utility.yul\":11144:11180 */\n mstore\n /* \"#utility.yul\":11218:11221 */\n 0x80\n /* \"#utility.yul\":11211:11215 */\n 0x20\n /* \"#utility.yul\":11200:11209 */\n dup3\n /* \"#utility.yul\":11196:11216 */\n add\n /* \"#utility.yul\":11189:11222 */\n mstore\n /* \"#utility.yul\":11057:11061 */\n 0x00\n /* \"#utility.yul\":11239:11333 */\n tag_86\n /* \"#utility.yul\":11328:11331 */\n 0x80\n /* \"#utility.yul\":11317:11326 */\n dup4\n /* \"#utility.yul\":11313:11332 */\n add\n /* \"#utility.yul\":11305:11311 */\n dup5\n /* \"#utility.yul\":11297:11303 */\n dup7\n /* \"#utility.yul\":11239:11333 */\n tag_404\n jump\t// in\n /* \"#utility.yul\":11344:11528 */\n tag_113:\n /* \"#utility.yul\":11396:11473 */\n 0x4e487b7100000000000000000000000000000000000000000000000000000000\n /* \"#utility.yul\":11393:11394 */\n 0x00\n /* \"#utility.yul\":11386:11474 */\n mstore\n /* \"#utility.yul\":11493:11497 */\n 0x32\n /* \"#utility.yul\":11490:11491 */\n 0x04\n /* \"#utility.yul\":11483:11498 */\n mstore\n /* \"#utility.yul\":11517:11521 */\n 0x24\n /* \"#utility.yul\":11514:11515 */\n 0x00\n /* \"#utility.yul\":11507:11522 */\n revert\n /* \"#utility.yul\":11786:12267 */\n tag_405:\n /* \"#utility.yul\":11827:11830 */\n 0x00\n /* \"#utility.yul\":11865:11870 */\n dup2\n /* \"#utility.yul\":11859:11871 */\n mload\n /* \"#utility.yul\":11892:11898 */\n dup1\n /* \"#utility.yul\":11887:11890 */\n dup5\n /* \"#utility.yul\":11880:11899 */\n mstore\n /* \"#utility.yul\":11917:11918 */\n 0x00\n /* \"#utility.yul\":11927:12089 */\n tag_487:\n /* \"#utility.yul\":11941:11947 */\n dup2\n /* \"#utility.yul\":11938:11939 */\n dup2\n /* \"#utility.yul\":11935:11948 */\n lt\n /* \"#utility.yul\":11927:12089 */\n iszero\n tag_489\n jumpi\n /* \"#utility.yul\":12003:12007 */\n 0x20\n /* \"#utility.yul\":12059:12072 */\n dup2\n dup6\n add\n /* \"#utility.yul\":12055:12077 */\n dup2\n add\n /* \"#utility.yul\":12049:12078 */\n mload\n /* \"#utility.yul\":12031:12042 */\n dup7\n dup4\n add\n /* \"#utility.yul\":12027:12047 */\n dup3\n add\n /* \"#utility.yul\":12020:12079 */\n mstore\n /* \"#utility.yul\":11956:11968 */\n add\n /* \"#utility.yul\":11927:12089 */\n jump(tag_487)\n tag_489:\n /* \"#utility.yul\":11931:11934 */\n pop\n /* \"#utility.yul\":12134:12135 */\n 0x00\n /* \"#utility.yul\":12127:12131 */\n 0x20\n /* \"#utility.yul\":12118:12124 */\n dup3\n /* \"#utility.yul\":12113:12116 */\n dup7\n /* \"#utility.yul\":12109:12125 */\n add\n /* \"#utility.yul\":12105:12132 */\n add\n /* \"#utility.yul\":12098:12136 */\n mstore\n /* \"#utility.yul\":12256:12260 */\n 0x20\n /* \"#utility.yul\":12186:12252 */\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0\n /* \"#utility.yul\":12181:12183 */\n 0x1f\n /* \"#utility.yul\":12173:12179 */\n dup4\n /* \"#utility.yul\":12169:12184 */\n add\n /* \"#utility.yul\":12165:12253 */\n and\n /* \"#utility.yul\":12160:12163 */\n dup6\n /* \"#utility.yul\":12156:12254 */\n add\n /* \"#utility.yul\":12152:12261 */\n add\n /* \"#utility.yul\":12145:12261 */\n swap2\n pop\n pop\n /* \"#utility.yul\":11786:12267 */\n swap3\n swap2\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":12272:12489 */\n tag_140:\n /* \"#utility.yul\":12419:12421 */\n 0x20\n /* \"#utility.yul\":12408:12417 */\n dup2\n /* \"#utility.yul\":12401:12422 */\n mstore\n /* \"#utility.yul\":12382:12386 */\n 0x00\n /* \"#utility.yul\":12439:12483 */\n tag_82\n /* \"#utility.yul\":12479:12481 */\n 0x20\n /* \"#utility.yul\":12468:12477 */\n dup4\n /* \"#utility.yul\":12464:12482 */\n add\n /* \"#utility.yul\":12456:12462 */\n dup5\n /* \"#utility.yul\":12439:12483 */\n tag_405\n jump\t// in\n /* \"#utility.yul\":13090:13477 */\n tag_164:\n /* \"#utility.yul\":13187:13191 */\n 0x00\n /* \"#utility.yul\":13245:13256 */\n dup3\n /* \"#utility.yul\":13232:13257 */\n calldataload\n /* \"#utility.yul\":13335:13401 */\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff41\n /* \"#utility.yul\":13324:13332 */\n dup4\n /* \"#utility.yul\":13308:13322 */\n calldatasize\n /* \"#utility.yul\":13304:13333 */\n sub\n /* \"#utility.yul\":13300:13402 */\n add\n /* \"#utility.yul\":13280:13298 */\n dup2\n /* \"#utility.yul\":13276:13403 */\n slt\n /* \"#utility.yul\":13266:13421 */\n tag_494\n jumpi\n /* \"#utility.yul\":13417:13418 */\n 0x00\n /* \"#utility.yul\":13414:13415 */\n dup1\n /* \"#utility.yul\":13407:13419 */\n revert\n /* \"#utility.yul\":13266:13421 */\n tag_494:\n /* \"#utility.yul\":13438:13471 */\n swap2\n swap1\n swap2\n add\n swap3\n /* \"#utility.yul\":13090:13477 */\n swap2\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":13482:13662 */\n tag_166:\n /* \"#utility.yul\":13538:13544 */\n 0x00\n /* \"#utility.yul\":13591:13593 */\n 0x20\n /* \"#utility.yul\":13579:13588 */\n dup3\n /* \"#utility.yul\":13570:13577 */\n dup5\n /* \"#utility.yul\":13566:13589 */\n sub\n /* \"#utility.yul\":13562:13594 */\n slt\n /* \"#utility.yul\":13559:13611 */\n iszero\n tag_496\n jumpi\n /* \"#utility.yul\":13607:13608 */\n 0x00\n /* \"#utility.yul\":13604:13605 */\n dup1\n /* \"#utility.yul\":13597:13609 */\n revert\n /* \"#utility.yul\":13559:13611 */\n tag_496:\n /* \"#utility.yul\":13630:13656 */\n tag_82\n /* \"#utility.yul\":13646:13655 */\n dup3\n /* \"#utility.yul\":13630:13656 */\n tag_401\n jump\t// in\n /* \"#utility.yul\":13991:14177 */\n tag_174:\n /* \"#utility.yul\":14050:14056 */\n 0x00\n /* \"#utility.yul\":14103:14105 */\n 0x20\n /* \"#utility.yul\":14091:14100 */\n dup3\n /* \"#utility.yul\":14082:14089 */\n dup5\n /* \"#utility.yul\":14078:14101 */\n sub\n /* \"#utility.yul\":14074:14106 */\n slt\n /* \"#utility.yul\":14071:14123 */\n iszero\n tag_500\n jumpi\n /* \"#utility.yul\":14119:14120 */\n 0x00\n /* \"#utility.yul\":14116:14117 */\n dup1\n /* \"#utility.yul\":14109:14121 */\n revert\n /* \"#utility.yul\":14071:14123 */\n tag_500:\n /* \"#utility.yul\":14142:14171 */\n tag_82\n /* \"#utility.yul\":14161:14170 */\n dup3\n /* \"#utility.yul\":14142:14171 */\n tag_402\n jump\t// in\n /* \"#utility.yul\":14182:14762 */\n tag_178:\n /* \"#utility.yul\":14259:14263 */\n 0x00\n /* \"#utility.yul\":14265:14271 */\n dup1\n /* \"#utility.yul\":14325:14336 */\n dup4\n /* \"#utility.yul\":14312:14337 */\n calldataload\n /* \"#utility.yul\":14415:14481 */\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1\n /* \"#utility.yul\":14404:14412 */\n dup5\n /* \"#utility.yul\":14388:14402 */\n calldatasize\n /* \"#utility.yul\":14384:14413 */\n sub\n /* \"#utility.yul\":14380:14482 */\n add\n /* \"#utility.yul\":14360:14378 */\n dup2\n /* \"#utility.yul\":14356:14483 */\n slt\n /* \"#utility.yul\":14346:14501 */\n tag_503\n jumpi\n /* \"#utility.yul\":14497:14498 */\n 0x00\n /* \"#utility.yul\":14494:14495 */\n dup1\n /* \"#utility.yul\":14487:14499 */\n revert\n /* \"#utility.yul\":14346:14501 */\n tag_503:\n /* \"#utility.yul\":14524:14557 */\n dup4\n add\n /* \"#utility.yul\":14576:14596 */\n dup1\n calldataload\n swap2\n pop\n /* \"#utility.yul\":14619:14637 */\n 0xffffffffffffffff\n /* \"#utility.yul\":14608:14638 */\n dup3\n gt\n /* \"#utility.yul\":14605:14655 */\n iszero\n tag_504\n jumpi\n /* \"#utility.yul\":14651:14652 */\n 0x00\n /* \"#utility.yul\":14648:14649 */\n dup1\n /* \"#utility.yul\":14641:14653 */\n revert\n /* \"#utility.yul\":14605:14655 */\n tag_504:\n /* \"#utility.yul\":14684:14688 */\n 0x20\n /* \"#utility.yul\":14672:14689 */\n add\n swap2\n pop\n /* \"#utility.yul\":14715:14729 */\n calldatasize\n /* \"#utility.yul\":14711:14738 */\n dup2\n swap1\n sub\n /* \"#utility.yul\":14701:14739 */\n dup3\n sgt\n /* \"#utility.yul\":14698:14756 */\n iszero\n tag_417\n jumpi\n /* \"#utility.yul\":14752:14753 */\n 0x00\n /* \"#utility.yul\":14749:14750 */\n dup1\n /* \"#utility.yul\":14742:14754 */\n revert\n /* \"#utility.yul\":14767:14951 */\n tag_406:\n /* \"#utility.yul\":14819:14896 */\n 0x4e487b7100000000000000000000000000000000000000000000000000000000\n /* \"#utility.yul\":14816:14817 */\n 0x00\n /* \"#utility.yul\":14809:14897 */\n mstore\n /* \"#utility.yul\":14916:14920 */\n 0x11\n /* \"#utility.yul\":14913:14914 */\n 0x04\n /* \"#utility.yul\":14906:14921 */\n mstore\n /* \"#utility.yul\":14940:14944 */\n 0x24\n /* \"#utility.yul\":14937:14938 */\n 0x00\n /* \"#utility.yul\":14930:14945 */\n revert\n /* \"#utility.yul\":14956:15151 */\n tag_189:\n /* \"#utility.yul\":14995:14998 */\n 0x00\n /* \"#utility.yul\":15026:15092 */\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\n /* \"#utility.yul\":15019:15024 */\n dup3\n /* \"#utility.yul\":15016:15093 */\n sub\n /* \"#utility.yul\":15013:15116 */\n tag_509\n jumpi\n /* \"#utility.yul\":15096:15114 */\n tag_509\n tag_406\n jump\t// in\n tag_509:\n pop\n /* \"#utility.yul\":15143:15144 */\n 0x01\n /* \"#utility.yul\":15132:15145 */\n add\n swap1\n /* \"#utility.yul\":14956:15151 */\n jump\t// out\n /* \"#utility.yul\":15156:15487 */\n tag_193:\n /* \"#utility.yul\":15261:15270 */\n 0x00\n /* \"#utility.yul\":15272:15281 */\n dup1\n /* \"#utility.yul\":15314:15322 */\n dup6\n /* \"#utility.yul\":15302:15312 */\n dup6\n /* \"#utility.yul\":15299:15323 */\n gt\n /* \"#utility.yul\":15296:15340 */\n iszero\n tag_511\n jumpi\n /* \"#utility.yul\":15336:15337 */\n 0x00\n /* \"#utility.yul\":15333:15334 */\n dup1\n /* \"#utility.yul\":15326:15338 */\n revert\n /* \"#utility.yul\":15296:15340 */\n tag_511:\n /* \"#utility.yul\":15365:15371 */\n dup4\n /* \"#utility.yul\":15355:15363 */\n dup7\n /* \"#utility.yul\":15352:15372 */\n gt\n /* \"#utility.yul\":15349:15389 */\n iszero\n tag_512\n jumpi\n /* \"#utility.yul\":15385:15386 */\n 0x00\n /* \"#utility.yul\":15382:15383 */\n dup1\n /* \"#utility.yul\":15375:15387 */\n revert\n /* \"#utility.yul\":15349:15389 */\n tag_512:\n pop\n pop\n /* \"#utility.yul\":15411:15434 */\n dup3\n add\n swap4\n /* \"#utility.yul\":15456:15481 */\n swap2\n swap1\n swap3\n sub\n swap2\n pop\n /* \"#utility.yul\":15156:15487 */\n jump\t// out\n /* \"#utility.yul\":15492:15617 */\n tag_211:\n /* \"#utility.yul\":15557:15566 */\n dup1\n dup3\n add\n /* \"#utility.yul\":15578:15588 */\n dup1\n dup3\n gt\n /* \"#utility.yul\":15575:15611 */\n iszero\n tag_80\n jumpi\n /* \"#utility.yul\":15591:15609 */\n tag_80\n tag_406\n jump\t// in\n /* \"#utility.yul\":15622:16014 */\n tag_217:\n /* \"#utility.yul\":15841:15843 */\n 0x60\n /* \"#utility.yul\":15830:15839 */\n dup2\n /* \"#utility.yul\":15823:15844 */\n mstore\n /* \"#utility.yul\":15804:15808 */\n 0x00\n /* \"#utility.yul\":15861:15922 */\n tag_517\n /* \"#utility.yul\":15918:15920 */\n 0x60\n /* \"#utility.yul\":15907:15916 */\n dup4\n /* \"#utility.yul\":15903:15921 */\n add\n /* \"#utility.yul\":15895:15901 */\n dup7\n /* \"#utility.yul\":15887:15893 */\n dup9\n /* \"#utility.yul\":15861:15922 */\n tag_403\n jump\t// in\n tag_517:\n /* \"#utility.yul\":15953:15955 */\n 0x20\n /* \"#utility.yul\":15938:15956 */\n dup4\n add\n /* \"#utility.yul\":15931:15965 */\n swap5\n swap1\n swap5\n mstore\n pop\n /* \"#utility.yul\":15996:15998 */\n 0x40\n /* \"#utility.yul\":15981:15999 */\n add\n /* \"#utility.yul\":15974:16008 */\n mstore\n /* \"#utility.yul\":15853:15922 */\n swap3\n /* \"#utility.yul\":15622:16014 */\n swap2\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":16525:16813 */\n tag_246:\n /* \"#utility.yul\":16700:16706 */\n dup3\n /* \"#utility.yul\":16689:16698 */\n dup2\n /* \"#utility.yul\":16682:16707 */\n mstore\n /* \"#utility.yul\":16743:16745 */\n 0x40\n /* \"#utility.yul\":16738:16740 */\n 0x20\n /* \"#utility.yul\":16727:16736 */\n dup3\n /* \"#utility.yul\":16723:16741 */\n add\n /* \"#utility.yul\":16716:16746 */\n mstore\n /* \"#utility.yul\":16663:16667 */\n 0x00\n /* \"#utility.yul\":16763:16807 */\n tag_86\n /* \"#utility.yul\":16803:16805 */\n 0x40\n /* \"#utility.yul\":16792:16801 */\n dup4\n /* \"#utility.yul\":16788:16806 */\n add\n /* \"#utility.yul\":16780:16786 */\n dup5\n /* \"#utility.yul\":16763:16807 */\n tag_405\n jump\t// in\n /* \"#utility.yul\":16818:17259 */\n tag_278:\n /* \"#utility.yul\":17037:17043 */\n dup5\n /* \"#utility.yul\":17026:17035 */\n dup2\n /* \"#utility.yul\":17019:17044 */\n mstore\n /* \"#utility.yul\":17092:17134 */\n 0xffffffffffffffffffffffffffffffffffffffff\n /* \"#utility.yul\":17084:17090 */\n dup5\n /* \"#utility.yul\":17080:17135 */\n and\n /* \"#utility.yul\":17075:17077 */\n 0x20\n /* \"#utility.yul\":17064:17073 */\n dup3\n /* \"#utility.yul\":17060:17078 */\n add\n /* \"#utility.yul\":17053:17136 */\n mstore\n /* \"#utility.yul\":17172:17174 */\n 0x60\n /* \"#utility.yul\":17167:17169 */\n 0x40\n /* \"#utility.yul\":17156:17165 */\n dup3\n /* \"#utility.yul\":17152:17170 */\n add\n /* \"#utility.yul\":17145:17175 */\n mstore\n /* \"#utility.yul\":17000:17004 */\n 0x00\n /* \"#utility.yul\":17192:17253 */\n tag_523\n /* \"#utility.yul\":17249:17251 */\n 0x60\n /* \"#utility.yul\":17238:17247 */\n dup4\n /* \"#utility.yul\":17234:17252 */\n add\n /* \"#utility.yul\":17226:17232 */\n dup5\n /* \"#utility.yul\":17218:17224 */\n dup7\n /* \"#utility.yul\":17192:17253 */\n tag_403\n jump\t// in\n tag_523:\n /* \"#utility.yul\":17184:17253 */\n swap7\n /* \"#utility.yul\":16818:17259 */\n swap6\n pop\n pop\n pop\n pop\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":17264:17508 */\n tag_333:\n /* \"#utility.yul\":17421:17423 */\n 0x20\n /* \"#utility.yul\":17410:17419 */\n dup2\n /* \"#utility.yul\":17403:17424 */\n mstore\n /* \"#utility.yul\":17384:17388 */\n 0x00\n /* \"#utility.yul\":17441:17502 */\n tag_86\n /* \"#utility.yul\":17498:17500 */\n 0x20\n /* \"#utility.yul\":17487:17496 */\n dup4\n /* \"#utility.yul\":17483:17501 */\n add\n /* \"#utility.yul\":17475:17481 */\n dup5\n /* \"#utility.yul\":17467:17473 */\n dup7\n /* \"#utility.yul\":17441:17502 */\n tag_403\n jump\t// in\n /* \"#utility.yul\":17513:17641 */\n tag_336:\n /* \"#utility.yul\":17580:17589 */\n dup2\n dup2\n sub\n /* \"#utility.yul\":17601:17612 */\n dup2\n dup2\n gt\n /* \"#utility.yul\":17598:17635 */\n iszero\n tag_80\n jumpi\n /* \"#utility.yul\":17615:17633 */\n tag_80\n tag_406\n jump\t// in\n /* \"#utility.yul\":17646:17961 */\n tag_344:\n /* \"#utility.yul\":17831:17833 */\n 0x40\n /* \"#utility.yul\":17820:17829 */\n dup2\n /* \"#utility.yul\":17813:17834 */\n mstore\n /* \"#utility.yul\":17794:17798 */\n 0x00\n /* \"#utility.yul\":17851:17912 */\n tag_530\n /* \"#utility.yul\":17908:17910 */\n 0x40\n /* \"#utility.yul\":17897:17906 */\n dup4\n /* \"#utility.yul\":17893:17911 */\n add\n /* \"#utility.yul\":17885:17891 */\n dup6\n /* \"#utility.yul\":17877:17883 */\n dup8\n /* \"#utility.yul\":17851:17912 */\n tag_403\n jump\t// in\n tag_530:\n /* \"#utility.yul\":17843:17912 */\n swap1\n pop\n /* \"#utility.yul\":17948:17954 */\n dup3\n /* \"#utility.yul\":17943:17945 */\n 0x20\n /* \"#utility.yul\":17932:17941 */\n dup4\n /* \"#utility.yul\":17928:17946 */\n add\n /* \"#utility.yul\":17921:17955 */\n mstore\n /* \"#utility.yul\":17646:17961 */\n swap5\n swap4\n pop\n pop\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":17966:18290 */\n tag_348:\n /* \"#utility.yul\":18149:18151 */\n 0x40\n /* \"#utility.yul\":18138:18147 */\n dup2\n /* \"#utility.yul\":18131:18152 */\n mstore\n /* \"#utility.yul\":18112:18116 */\n 0x00\n /* \"#utility.yul\":18169:18230 */\n tag_532\n /* \"#utility.yul\":18226:18228 */\n 0x40\n /* \"#utility.yul\":18215:18224 */\n dup4\n /* \"#utility.yul\":18211:18229 */\n add\n /* \"#utility.yul\":18203:18209 */\n dup6\n /* \"#utility.yul\":18195:18201 */\n dup8\n /* \"#utility.yul\":18169:18230 */\n tag_403\n jump\t// in\n tag_532:\n /* \"#utility.yul\":18161:18230 */\n swap1\n pop\n /* \"#utility.yul\":18278:18282 */\n 0xff\n /* \"#utility.yul\":18270:18276 */\n dup4\n /* \"#utility.yul\":18266:18283 */\n and\n /* \"#utility.yul\":18261:18263 */\n 0x20\n /* \"#utility.yul\":18250:18259 */\n dup4\n /* \"#utility.yul\":18246:18264 */\n add\n /* \"#utility.yul\":18239:18284 */\n mstore\n /* \"#utility.yul\":17966:18290 */\n swap5\n swap4\n pop\n pop\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":19083:19479 */\n tag_363:\n /* \"#utility.yul\":19290:19292 */\n 0x60\n /* \"#utility.yul\":19279:19288 */\n dup2\n /* \"#utility.yul\":19272:19293 */\n mstore\n /* \"#utility.yul\":19253:19257 */\n 0x00\n /* \"#utility.yul\":19310:19371 */\n tag_536\n /* \"#utility.yul\":19367:19369 */\n 0x60\n /* \"#utility.yul\":19356:19365 */\n dup4\n /* \"#utility.yul\":19352:19370 */\n add\n /* \"#utility.yul\":19344:19350 */\n dup7\n /* \"#utility.yul\":19336:19342 */\n dup9\n /* \"#utility.yul\":19310:19371 */\n tag_403\n jump\t// in\n tag_536:\n /* \"#utility.yul\":19402:19404 */\n 0x20\n /* \"#utility.yul\":19387:19405 */\n dup4\n add\n /* \"#utility.yul\":19380:19414 */\n swap5\n swap1\n swap5\n mstore\n pop\n /* \"#utility.yul\":19457:19471 */\n swap1\n iszero\n /* \"#utility.yul\":19450:19472 */\n iszero\n /* \"#utility.yul\":19445:19447 */\n 0x40\n /* \"#utility.yul\":19430:19448 */\n swap1\n swap2\n add\n /* \"#utility.yul\":19423:19473 */\n mstore\n /* \"#utility.yul\":19302:19371 */\n swap3\n /* \"#utility.yul\":19083:19479 */\n swap2\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":19484:19805 */\n tag_379:\n /* \"#utility.yul\":19675:19681 */\n dup4\n /* \"#utility.yul\":19664:19673 */\n dup2\n /* \"#utility.yul\":19657:19682 */\n mstore\n /* \"#utility.yul\":19718:19720 */\n 0x40\n /* \"#utility.yul\":19713:19715 */\n 0x20\n /* \"#utility.yul\":19702:19711 */\n dup3\n /* \"#utility.yul\":19698:19716 */\n add\n /* \"#utility.yul\":19691:19721 */\n mstore\n /* \"#utility.yul\":19638:19642 */\n 0x00\n /* \"#utility.yul\":19738:19799 */\n tag_538\n /* \"#utility.yul\":19795:19797 */\n 0x40\n /* \"#utility.yul\":19784:19793 */\n dup4\n /* \"#utility.yul\":19780:19798 */\n add\n /* \"#utility.yul\":19772:19778 */\n dup5\n /* \"#utility.yul\":19764:19770 */\n dup7\n /* \"#utility.yul\":19738:19799 */\n tag_403\n jump\t// in\n tag_538:\n /* \"#utility.yul\":19730:19799 */\n swap6\n /* \"#utility.yul\":19484:19805 */\n swap5\n pop\n pop\n pop\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":19810:20059 */\n tag_383:\n /* \"#utility.yul\":19879:19885 */\n 0x00\n /* \"#utility.yul\":19932:19934 */\n 0x20\n /* \"#utility.yul\":19920:19929 */\n dup3\n /* \"#utility.yul\":19911:19918 */\n dup5\n /* \"#utility.yul\":19907:19930 */\n sub\n /* \"#utility.yul\":19903:19935 */\n slt\n /* \"#utility.yul\":19900:19952 */\n iszero\n tag_540\n jumpi\n /* \"#utility.yul\":19948:19949 */\n 0x00\n /* \"#utility.yul\":19945:19946 */\n dup1\n /* \"#utility.yul\":19938:19950 */\n revert\n /* \"#utility.yul\":19900:19952 */\n tag_540:\n /* \"#utility.yul\":19980:19989 */\n dup2\n /* \"#utility.yul\":19974:19990 */\n mload\n /* \"#utility.yul\":19999:20029 */\n tag_82\n /* \"#utility.yul\":20023:20028 */\n dup2\n /* \"#utility.yul\":19999:20029 */\n tag_397\n jump\t// in\n\n auxdata: 0xa26469706673582212209bb95d18e97f278aa47e0c04c20d5a6af9bdb6d473c6d4051192cd96fc17866864736f6c63430008120033\n}\n", + "bytecode": { + "functionDebugData": { + "@_1068": { + "entryPoint": null, + "id": 1068, + "parameterSlots": 0, + "returnSlots": 0 + } + }, + "generatedSources": [], + "linkReferences": {}, + "object": "60a060405234801561001057600080fd5b50306080526080516121de61002d600039600050506121de6000f3fe6080604052600436106100bc5760003560e01c806361c2926c116100745780638c3f55631161004e5780638c3f55631461025357806390042baf14610273578063affed0e0146102ab57600080fd5b806361c2926c146101cb5780637a9a1628146101eb578063853c50681461020b57600080fd5b806320c13b0b116100a557806320c13b0b14610147578063295614261461016757806357c56d6b1461018957600080fd5b806301ffc9a7146100c15780631626ba7e146100f6575b600080fd5b3480156100cd57600080fd5b506100e16100dc366004611880565b6102c0565b60405190151581526020015b60405180910390f35b34801561010257600080fd5b506101166101113660046118e6565b6102d1565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016100ed565b34801561015357600080fd5b50610116610162366004611932565b61031e565b34801561017357600080fd5b5061018761018236600461199e565b610383565b005b34801561019557600080fd5b506101bd7f8713a7c4465f6fbee2b6e9d6646d1d9f83fec929edfc4baf661f3c865bdd04d181565b6040519081526020016100ed565b3480156101d757600080fd5b506101876101e63660046119fc565b6103d5565b3480156101f757600080fd5b50610187610206366004611a3e565b61041a565b34801561021757600080fd5b5061022b6102263660046118e6565b610447565b604080519586526020860194909452928401919091526060830152608082015260a0016100ed565b34801561025f57600080fd5b506101bd61026e36600461199e565b61060f565b610286610281366004611ae7565b61063b565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100ed565b3480156102b757600080fd5b506101bd610725565b60006102cb82610736565b92915050565b6000806102df858585610792565b509050801561031157507f1626ba7e000000000000000000000000000000000000000000000000000000009050610317565b50600090505b9392505050565b6000806103438686604051610334929190611bb6565b60405180910390208585610792565b509050801561037557507f20c13b0b00000000000000000000000000000000000000000000000000000000905061037b565b50600090505b949350505050565b3330146103c9576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044015b60405180910390fd5b6103d2816107ca565b50565b600061040883836040516020016103ed929190611d97565b604051602081830303815290604052805190602001206107fc565b9050610415818484610881565b505050565b600061043286866040516020016103ed929190611ddf565b905061043f818787610881565b505050505050565b6000806000806000808787600081811061046357610463611e27565b909101357fff000000000000000000000000000000000000000000000000000000000000001691508190506104b95761049b896107fc565b92506104a8838989610a0e565b929850909650945091506106049050565b7fff00000000000000000000000000000000000000000000000000000000000000818116016104f8576104eb896107fc565b92506104a8838989610a5f565b7ffe000000000000000000000000000000000000000000000000000000000000007fff0000000000000000000000000000000000000000000000000000000000000082160161054a576104eb89610a8b565b7ffd000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216016105ae5761059e898989610af8565b9550955095509550955050610604565b6040517f6085cd820000000000000000000000000000000000000000000000000000000081527fff00000000000000000000000000000000000000000000000000000000000000821660048201526024016103c0565b939792965093509350565b60006102cb7f8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e83610c75565b600033301461067e576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044016103c0565b81516020830134f0905073ffffffffffffffffffffffffffffffffffffffff81166106d757816040517f0d2571910000000000000000000000000000000000000000000000000000000081526004016103c09190611eba565b60405173ffffffffffffffffffffffffffffffffffffffff821681527fa506ad4e7f05eceba62a023c3219e5bd98a615f4fa87e2afb08a2da5cf62bf0c9060200160405180910390a1919050565b6000610731600061060f565b905090565b60007f6ffbd451000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083160161078957506001919050565b6102cb82610cd3565b60008060008060006107a5888888610447565b509650919450925090508282108015906107bd575060015b9450505050935093915050565b6040517fa038794000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f190100000000000000000000000000000000000000000000000000000000000060208201524660228201527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b166042820152605681018290526000906076015b604051602081830303815290604052805190602001209050919050565b8060005b81811015610a0757368484838181106108a0576108a0611e27565b90506020028101906108b29190611ecd565b90506108c16020820182611f0b565b156108fb576040517f230d1ccc000000000000000000000000000000000000000000000000000000008152600481018390526024016103c0565b6040810135805a101561094e5782815a6040517f2bb3e3ba0000000000000000000000000000000000000000000000000000000081526004810193909352602483019190915260448201526064016103c0565b60006109886109636080850160608601611f26565b608085013584156109745784610976565b5a5b61098360a0880188611f41565b610d2f565b905080156109cf57877f5c4eeb02dabf8976016ab414d617f9a162936dcace3cdef8c69ef6e262ad5ae7856040516109c291815260200190565b60405180910390a26109f1565b6109f16109e26040850160208601611f0b565b89866109ec610d4c565b610d6b565b50505080806109ff90611fd5565b915050610885565b5050505050565b6000808080610a2987610a24876006818b61200d565b610db9565b6000908152873560f01c6020818152604080842084526002909a013560e01c908190529890912090999198509695509350505050565b6000808080610a7a87610a75876001818b61200d565b610a0e565b935093509350935093509350935093565b6040517f190100000000000000000000000000000000000000000000000000000000000060208201526000602282018190527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b1660428301526056820183905290607601610864565b6000808080806004600188013560e81c82610b138383612037565b9050610b258b61022683868d8f61200d565b939b5091995097509550935087871015610b7d57610b4581848b8d61200d565b89896040517fb006aba00000000000000000000000000000000000000000000000000000000081526004016103c0949392919061204a565b8092505b88831015610c675760038301928a013560e81c9150610ba08383612037565b90506000610bc2610bb08861124f565b8c8c879086926102269392919061200d565b939c50919a5098509091505088881015610c1a57610be282858c8e61200d565b8a8a6040517fb006aba00000000000000000000000000000000000000000000000000000000081526004016103c0949392919061204a565b848110610c5d576040517f37daf62b00000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016103c0565b9350915081610b81565b505050939792965093509350565b6000808383604051602001610c94929190918252602082015260400190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052805160209091012054949350505050565b60007fe4a77bbc000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831601610d2657506001919050565b6102cb82611283565b6000604051828482376000808483898b8af1979650505050505050565b60603d604051915060208201818101604052818352816000823e505090565b8315610d7957805160208201fd5b827fab46c69f7f32e1bf09b0725853da82a211e5402a0600296ab499a2fb5ea3b4198383604051610dab929190612071565b60405180910390a250505050565b60008060005b8381101561124657600181019085013560f81c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8101610e6057601582019186013560f881901c9060581c73ffffffffffffffffffffffffffffffffffffffff81169074ff000000000000000000000000000000000000000016811785610e465780610e55565b60008681526020829052604090205b955050505050610dbf565b80610ef65760018201918681013560f81c906043016000610e8c8a610e8784888c8e61200d565b61136d565b60ff841697909701969194508491905060a083901b74ff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff82161786610edb5780610eea565b60008781526020829052604090205b96505050505050610dbf565b6002810361101e576000808784013560f881901c9060581c73ffffffffffffffffffffffffffffffffffffffff16601586019550909250905060008885013560e81c600386018162ffffff169150809650819250505060008186019050610f6f8b848c8c8a908692610f6a9392919061200d565b611630565b610fb7578a83610f8183898d8f61200d565b6040517f9a9462320000000000000000000000000000000000000000000000000000000081526004016103c0949392919061208a565b60ff8416979097019694508460a084901b74ff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff841617876110025780611011565b60008881526020829052604090205b9750505050505050610dbf565b60038103611051576020820191860135836110395780611048565b60008481526020829052604090205b93505050610dbf565b6004810361109d576003808301928781013560e81c919082010160008061107e8b610a2485898d8f61200d565b60009889526020526040909720969097019650909350610dbf92505050565b600681036111a55760008287013560f81c60018401935060ff16905060008784013560f01c60028501945061ffff16905060008885013560e81c600386018162ffffff16915080965081925050506000818601905060008061110b8d8d8d8b908792610a249392919061200d565b9398508893909250905084821061112157988501985b604080517f53657175656e6365206e657374656420636f6e6669673a0a0000000000000000602080830191909152603882018490526058820188905260788083018a90528351808403909101815260989092019092528051910120896111875780611196565b60008a81526020829052604090205b99505050505050505050610dbf565b600581036112115760208201918601358781036111e0577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff94505b60006111eb82611817565b9050846111f85780611207565b60008581526020829052604090205b9450505050610dbf565b6040517fb2505f7c000000000000000000000000000000000000000000000000000000008152600481018290526024016103c0565b50935093915050565b7f8713a7c4465f6fbee2b6e9d6646d1d9f83fec929edfc4baf661f3c865bdd04d160009081526020829052604081206102cb565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fac6a444e00000000000000000000000000000000000000000000000000000000148061131657507fffffffff0000000000000000000000000000000000000000000000000000000082167f36e7817500000000000000000000000000000000000000000000000000000000145b1561132357506001919050565b7f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316146102cb565b6000604282146113ad5782826040517f2ee17a3d0000000000000000000000000000000000000000000000000000000081526004016103c09291906120ca565b60006113c66113bd6001856120de565b85013560f81c90565b60ff169050604084013560f81c843560208601357f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a081111561143a578686826040517fad4aac760000000000000000000000000000000000000000000000000000000081526004016103c0939291906120f1565b8260ff16601b1415801561145257508260ff16601c14155b1561148f578686846040517fe578897e0000000000000000000000000000000000000000000000000000000081526004016103c093929190612115565b600184036114fc576040805160008152602081018083528a905260ff851691810191909152606081018390526080810182905260019060a0015b6020604051602081039080840390855afa1580156114eb573d6000803e3d6000fd5b5050506020604051035194506115d4565b60028403611599576040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101899052600190605c01604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600084529083018083525260ff861690820152606081018490526080810183905260a0016114c9565b86868560016040517f9dfba8520000000000000000000000000000000000000000000000000000000081526004016103c0949392919061213c565b73ffffffffffffffffffffffffffffffffffffffff85166116255786866040517f6c1719d20000000000000000000000000000000000000000000000000000000081526004016103c09291906120ca565b505050509392505050565b600081810361166b576040517fac241e1100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000838361167a6001826120de565b81811061168957611689611e27565b919091013560f81c91505060018114806116a35750600281145b156116e8578473ffffffffffffffffffffffffffffffffffffffff166116ca87868661136d565b73ffffffffffffffffffffffffffffffffffffffff1614915061180e565b600381036117d35773ffffffffffffffffffffffffffffffffffffffff8516631626ba7e878660008761171c6001826120de565b926117299392919061200d565b6040518463ffffffff1660e01b815260040161174793929190612168565b602060405180830381865afa158015611764573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611788919061218b565b7fffffffff00000000000000000000000000000000000000000000000000000000167f1626ba7e0000000000000000000000000000000000000000000000000000000014915061180e565b83838260006040517f9dfba8520000000000000000000000000000000000000000000000000000000081526004016103c0949392919061213c565b50949350505050565b6040517f53657175656e636520737461746963206469676573743a0a0000000000000000602082015260388101829052600090605801610864565b7fffffffff00000000000000000000000000000000000000000000000000000000811681146103d257600080fd5b60006020828403121561189257600080fd5b813561031781611852565b60008083601f8401126118af57600080fd5b50813567ffffffffffffffff8111156118c757600080fd5b6020830191508360208285010111156118df57600080fd5b9250929050565b6000806000604084860312156118fb57600080fd5b83359250602084013567ffffffffffffffff81111561191957600080fd5b6119258682870161189d565b9497909650939450505050565b6000806000806040858703121561194857600080fd5b843567ffffffffffffffff8082111561196057600080fd5b61196c8883890161189d565b9096509450602087013591508082111561198557600080fd5b506119928782880161189d565b95989497509550505050565b6000602082840312156119b057600080fd5b5035919050565b60008083601f8401126119c957600080fd5b50813567ffffffffffffffff8111156119e157600080fd5b6020830191508360208260051b85010111156118df57600080fd5b60008060208385031215611a0f57600080fd5b823567ffffffffffffffff811115611a2657600080fd5b611a32858286016119b7565b90969095509350505050565b600080600080600060608688031215611a5657600080fd5b853567ffffffffffffffff80821115611a6e57600080fd5b611a7a89838a016119b7565b9097509550602088013594506040880135915080821115611a9a57600080fd5b50611aa78882890161189d565b969995985093965092949392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215611af957600080fd5b813567ffffffffffffffff80821115611b1157600080fd5b818401915084601f830112611b2557600080fd5b813581811115611b3757611b37611ab8565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715611b7d57611b7d611ab8565b81604052828152876020848701011115611b9657600080fd5b826020860160208301376000928101602001929092525095945050505050565b8183823760009101908152919050565b80358015158114611bd657600080fd5b919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611bd657600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b81835260006020808501808196508560051b810191508460005b87811015611d8a57828403895281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff41883603018112611ca157600080fd5b870160c0611cae82611bc6565b15158652611cbd878301611bc6565b15158688015260408281013590870152606073ffffffffffffffffffffffffffffffffffffffff611cef828501611bdb565b16908701526080828101359087015260a080830135368490037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1018112611d3557600080fd5b90920187810192903567ffffffffffffffff811115611d5357600080fd5b803603841315611d6257600080fd5b8282890152611d748389018286611bff565b9c89019c97505050928601925050600101611c62565b5091979650505050505050565b60408152600560408201527f73656c663a000000000000000000000000000000000000000000000000000000606082015260806020820152600061037b608083018486611c48565b60408152600660408201527f67756573743a0000000000000000000000000000000000000000000000000000606082015260806020820152600061037b608083018486611c48565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000815180845260005b81811015611e7c57602081850181015186830182015201611e60565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006103176020830184611e56565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff41833603018112611f0157600080fd5b9190910192915050565b600060208284031215611f1d57600080fd5b61031782611bc6565b600060208284031215611f3857600080fd5b61031782611bdb565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611f7657600080fd5b83018035915067ffffffffffffffff821115611f9157600080fd5b6020019150368190038213156118df57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361200657612006611fa6565b5060010190565b6000808585111561201d57600080fd5b8386111561202a57600080fd5b5050820193919092039150565b808201808211156102cb576102cb611fa6565b60608152600061205e606083018688611bff565b6020830194909452506040015292915050565b82815260406020820152600061037b6040830184611e56565b84815273ffffffffffffffffffffffffffffffffffffffff841660208201526060604082015260006120c0606083018486611bff565b9695505050505050565b60208152600061037b602083018486611bff565b818103818111156102cb576102cb611fa6565b604081526000612105604083018587611bff565b9050826020830152949350505050565b604081526000612129604083018587611bff565b905060ff83166020830152949350505050565b606081526000612150606083018688611bff565b60208301949094525090151560409091015292915050565b838152604060208201526000612182604083018486611bff565b95945050505050565b60006020828403121561219d57600080fd5b81516103178161185256fea26469706673582212209bb95d18e97f278aa47e0c04c20d5a6af9bdb6d473c6d4051192cd96fc17866864736f6c63430008120033", + "opcodes": "PUSH1 0xA0 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP ADDRESS PUSH1 0x80 MSTORE PUSH1 0x80 MLOAD PUSH2 0x21DE PUSH2 0x2D PUSH1 0x0 CODECOPY PUSH1 0x0 POP POP PUSH2 0x21DE PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0xBC JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x61C2926C GT PUSH2 0x74 JUMPI DUP1 PUSH4 0x8C3F5563 GT PUSH2 0x4E JUMPI DUP1 PUSH4 0x8C3F5563 EQ PUSH2 0x253 JUMPI DUP1 PUSH4 0x90042BAF EQ PUSH2 0x273 JUMPI DUP1 PUSH4 0xAFFED0E0 EQ PUSH2 0x2AB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x61C2926C EQ PUSH2 0x1CB JUMPI DUP1 PUSH4 0x7A9A1628 EQ PUSH2 0x1EB JUMPI DUP1 PUSH4 0x853C5068 EQ PUSH2 0x20B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x20C13B0B GT PUSH2 0xA5 JUMPI DUP1 PUSH4 0x20C13B0B EQ PUSH2 0x147 JUMPI DUP1 PUSH4 0x29561426 EQ PUSH2 0x167 JUMPI DUP1 PUSH4 0x57C56D6B EQ PUSH2 0x189 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x1FFC9A7 EQ PUSH2 0xC1 JUMPI DUP1 PUSH4 0x1626BA7E EQ PUSH2 0xF6 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xCD JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xE1 PUSH2 0xDC CALLDATASIZE PUSH1 0x4 PUSH2 0x1880 JUMP JUMPDEST PUSH2 0x2C0 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x102 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x116 PUSH2 0x111 CALLDATASIZE PUSH1 0x4 PUSH2 0x18E6 JUMP JUMPDEST PUSH2 0x2D1 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xED JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x153 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x116 PUSH2 0x162 CALLDATASIZE PUSH1 0x4 PUSH2 0x1932 JUMP JUMPDEST PUSH2 0x31E JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x173 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x187 PUSH2 0x182 CALLDATASIZE PUSH1 0x4 PUSH2 0x199E JUMP JUMPDEST PUSH2 0x383 JUMP JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x195 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1BD PUSH32 0x8713A7C4465F6FBEE2B6E9D6646D1D9F83FEC929EDFC4BAF661F3C865BDD04D1 DUP2 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xED JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1D7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x187 PUSH2 0x1E6 CALLDATASIZE PUSH1 0x4 PUSH2 0x19FC JUMP JUMPDEST PUSH2 0x3D5 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1F7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x187 PUSH2 0x206 CALLDATASIZE PUSH1 0x4 PUSH2 0x1A3E JUMP JUMPDEST PUSH2 0x41A JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x217 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x22B PUSH2 0x226 CALLDATASIZE PUSH1 0x4 PUSH2 0x18E6 JUMP JUMPDEST PUSH2 0x447 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP6 DUP7 MSTORE PUSH1 0x20 DUP7 ADD SWAP5 SWAP1 SWAP5 MSTORE SWAP3 DUP5 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x60 DUP4 ADD MSTORE PUSH1 0x80 DUP3 ADD MSTORE PUSH1 0xA0 ADD PUSH2 0xED JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x25F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1BD PUSH2 0x26E CALLDATASIZE PUSH1 0x4 PUSH2 0x199E JUMP JUMPDEST PUSH2 0x60F JUMP JUMPDEST PUSH2 0x286 PUSH2 0x281 CALLDATASIZE PUSH1 0x4 PUSH2 0x1AE7 JUMP JUMPDEST PUSH2 0x63B JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xED JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2B7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1BD PUSH2 0x725 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x2CB DUP3 PUSH2 0x736 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH2 0x2DF DUP6 DUP6 DUP6 PUSH2 0x792 JUMP JUMPDEST POP SWAP1 POP DUP1 ISZERO PUSH2 0x311 JUMPI POP PUSH32 0x1626BA7E00000000000000000000000000000000000000000000000000000000 SWAP1 POP PUSH2 0x317 JUMP JUMPDEST POP PUSH1 0x0 SWAP1 POP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH2 0x343 DUP7 DUP7 PUSH1 0x40 MLOAD PUSH2 0x334 SWAP3 SWAP2 SWAP1 PUSH2 0x1BB6 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 KECCAK256 DUP6 DUP6 PUSH2 0x792 JUMP JUMPDEST POP SWAP1 POP DUP1 ISZERO PUSH2 0x375 JUMPI POP PUSH32 0x20C13B0B00000000000000000000000000000000000000000000000000000000 SWAP1 POP PUSH2 0x37B JUMP JUMPDEST POP PUSH1 0x0 SWAP1 POP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST CALLER ADDRESS EQ PUSH2 0x3C9 JUMPI PUSH1 0x40 MLOAD PUSH32 0xE125889400000000000000000000000000000000000000000000000000000000 DUP2 MSTORE CALLER PUSH1 0x4 DUP3 ADD MSTORE ADDRESS PUSH1 0x24 DUP3 ADD MSTORE PUSH1 0x44 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH2 0x3D2 DUP2 PUSH2 0x7CA JUMP JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x408 DUP4 DUP4 PUSH1 0x40 MLOAD PUSH1 0x20 ADD PUSH2 0x3ED SWAP3 SWAP2 SWAP1 PUSH2 0x1D97 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE DUP1 MLOAD SWAP1 PUSH1 0x20 ADD KECCAK256 PUSH2 0x7FC JUMP JUMPDEST SWAP1 POP PUSH2 0x415 DUP2 DUP5 DUP5 PUSH2 0x881 JUMP JUMPDEST POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x432 DUP7 DUP7 PUSH1 0x40 MLOAD PUSH1 0x20 ADD PUSH2 0x3ED SWAP3 SWAP2 SWAP1 PUSH2 0x1DDF JUMP JUMPDEST SWAP1 POP PUSH2 0x43F DUP2 DUP8 DUP8 PUSH2 0x881 JUMP JUMPDEST POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 DUP8 DUP8 PUSH1 0x0 DUP2 DUP2 LT PUSH2 0x463 JUMPI PUSH2 0x463 PUSH2 0x1E27 JUMP JUMPDEST SWAP1 SWAP2 ADD CALLDATALOAD PUSH32 0xFF00000000000000000000000000000000000000000000000000000000000000 AND SWAP2 POP DUP2 SWAP1 POP PUSH2 0x4B9 JUMPI PUSH2 0x49B DUP10 PUSH2 0x7FC JUMP JUMPDEST SWAP3 POP PUSH2 0x4A8 DUP4 DUP10 DUP10 PUSH2 0xA0E JUMP JUMPDEST SWAP3 SWAP9 POP SWAP1 SWAP7 POP SWAP5 POP SWAP2 POP PUSH2 0x604 SWAP1 POP JUMP JUMPDEST PUSH32 0xFF00000000000000000000000000000000000000000000000000000000000000 DUP2 DUP2 AND ADD PUSH2 0x4F8 JUMPI PUSH2 0x4EB DUP10 PUSH2 0x7FC JUMP JUMPDEST SWAP3 POP PUSH2 0x4A8 DUP4 DUP10 DUP10 PUSH2 0xA5F JUMP JUMPDEST PUSH32 0xFE00000000000000000000000000000000000000000000000000000000000000 PUSH32 0xFF00000000000000000000000000000000000000000000000000000000000000 DUP3 AND ADD PUSH2 0x54A JUMPI PUSH2 0x4EB DUP10 PUSH2 0xA8B JUMP JUMPDEST PUSH32 0xFD00000000000000000000000000000000000000000000000000000000000000 PUSH32 0xFF00000000000000000000000000000000000000000000000000000000000000 DUP3 AND ADD PUSH2 0x5AE JUMPI PUSH2 0x59E DUP10 DUP10 DUP10 PUSH2 0xAF8 JUMP JUMPDEST SWAP6 POP SWAP6 POP SWAP6 POP SWAP6 POP SWAP6 POP POP PUSH2 0x604 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x6085CD8200000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH32 0xFF00000000000000000000000000000000000000000000000000000000000000 DUP3 AND PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x24 ADD PUSH2 0x3C0 JUMP JUMPDEST SWAP4 SWAP8 SWAP3 SWAP7 POP SWAP4 POP SWAP4 POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x2CB PUSH32 0x8D0BF1FD623D628C741362C1289948E57B3E2905218C676D3E69ABEE36D6AE2E DUP4 PUSH2 0xC75 JUMP JUMPDEST PUSH1 0x0 CALLER ADDRESS EQ PUSH2 0x67E JUMPI PUSH1 0x40 MLOAD PUSH32 0xE125889400000000000000000000000000000000000000000000000000000000 DUP2 MSTORE CALLER PUSH1 0x4 DUP3 ADD MSTORE ADDRESS PUSH1 0x24 DUP3 ADD MSTORE PUSH1 0x44 ADD PUSH2 0x3C0 JUMP JUMPDEST DUP2 MLOAD PUSH1 0x20 DUP4 ADD CALLVALUE CREATE SWAP1 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND PUSH2 0x6D7 JUMPI DUP2 PUSH1 0x40 MLOAD PUSH32 0xD25719100000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP2 SWAP1 PUSH2 0x1EBA JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 AND DUP2 MSTORE PUSH32 0xA506AD4E7F05ECEBA62A023C3219E5BD98A615F4FA87E2AFB08A2DA5CF62BF0C SWAP1 PUSH1 0x20 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x731 PUSH1 0x0 PUSH2 0x60F JUMP JUMPDEST SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH32 0x6FFBD45100000000000000000000000000000000000000000000000000000000 PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP4 AND ADD PUSH2 0x789 JUMPI POP PUSH1 0x1 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH2 0x2CB DUP3 PUSH2 0xCD3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x7A5 DUP9 DUP9 DUP9 PUSH2 0x447 JUMP JUMPDEST POP SWAP7 POP SWAP2 SWAP5 POP SWAP3 POP SWAP1 POP DUP3 DUP3 LT DUP1 ISZERO SWAP1 PUSH2 0x7BD JUMPI POP PUSH1 0x1 JUMPDEST SWAP5 POP POP POP POP SWAP4 POP SWAP4 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0xA038794000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x1901000000000000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE CHAINID PUSH1 0x22 DUP3 ADD MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000 ADDRESS PUSH1 0x60 SHL AND PUSH1 0x42 DUP3 ADD MSTORE PUSH1 0x56 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x0 SWAP1 PUSH1 0x76 ADD JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE DUP1 MLOAD SWAP1 PUSH1 0x20 ADD KECCAK256 SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST DUP1 PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0xA07 JUMPI CALLDATASIZE DUP5 DUP5 DUP4 DUP2 DUP2 LT PUSH2 0x8A0 JUMPI PUSH2 0x8A0 PUSH2 0x1E27 JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL DUP2 ADD SWAP1 PUSH2 0x8B2 SWAP2 SWAP1 PUSH2 0x1ECD JUMP JUMPDEST SWAP1 POP PUSH2 0x8C1 PUSH1 0x20 DUP3 ADD DUP3 PUSH2 0x1F0B JUMP JUMPDEST ISZERO PUSH2 0x8FB JUMPI PUSH1 0x40 MLOAD PUSH32 0x230D1CCC00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 DUP2 ADD DUP4 SWAP1 MSTORE PUSH1 0x24 ADD PUSH2 0x3C0 JUMP JUMPDEST PUSH1 0x40 DUP2 ADD CALLDATALOAD DUP1 GAS LT ISZERO PUSH2 0x94E JUMPI DUP3 DUP2 GAS PUSH1 0x40 MLOAD PUSH32 0x2BB3E3BA00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 DUP2 ADD SWAP4 SWAP1 SWAP4 MSTORE PUSH1 0x24 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 ADD PUSH2 0x3C0 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x988 PUSH2 0x963 PUSH1 0x80 DUP6 ADD PUSH1 0x60 DUP7 ADD PUSH2 0x1F26 JUMP JUMPDEST PUSH1 0x80 DUP6 ADD CALLDATALOAD DUP5 ISZERO PUSH2 0x974 JUMPI DUP5 PUSH2 0x976 JUMP JUMPDEST GAS JUMPDEST PUSH2 0x983 PUSH1 0xA0 DUP9 ADD DUP9 PUSH2 0x1F41 JUMP JUMPDEST PUSH2 0xD2F JUMP JUMPDEST SWAP1 POP DUP1 ISZERO PUSH2 0x9CF JUMPI DUP8 PUSH32 0x5C4EEB02DABF8976016AB414D617F9A162936DCACE3CDEF8C69EF6E262AD5AE7 DUP6 PUSH1 0x40 MLOAD PUSH2 0x9C2 SWAP2 DUP2 MSTORE PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG2 PUSH2 0x9F1 JUMP JUMPDEST PUSH2 0x9F1 PUSH2 0x9E2 PUSH1 0x40 DUP6 ADD PUSH1 0x20 DUP7 ADD PUSH2 0x1F0B JUMP JUMPDEST DUP10 DUP7 PUSH2 0x9EC PUSH2 0xD4C JUMP JUMPDEST PUSH2 0xD6B JUMP JUMPDEST POP POP POP DUP1 DUP1 PUSH2 0x9FF SWAP1 PUSH2 0x1FD5 JUMP JUMPDEST SWAP2 POP POP PUSH2 0x885 JUMP JUMPDEST POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP1 DUP1 PUSH2 0xA29 DUP8 PUSH2 0xA24 DUP8 PUSH1 0x6 DUP2 DUP12 PUSH2 0x200D JUMP JUMPDEST PUSH2 0xDB9 JUMP JUMPDEST PUSH1 0x0 SWAP1 DUP2 MSTORE DUP8 CALLDATALOAD PUSH1 0xF0 SHR PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 DUP5 MSTORE PUSH1 0x2 SWAP1 SWAP11 ADD CALLDATALOAD PUSH1 0xE0 SHR SWAP1 DUP2 SWAP1 MSTORE SWAP9 SWAP1 SWAP2 KECCAK256 SWAP1 SWAP10 SWAP2 SWAP9 POP SWAP7 SWAP6 POP SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP1 DUP1 PUSH2 0xA7A DUP8 PUSH2 0xA75 DUP8 PUSH1 0x1 DUP2 DUP12 PUSH2 0x200D JUMP JUMPDEST PUSH2 0xA0E JUMP JUMPDEST SWAP4 POP SWAP4 POP SWAP4 POP SWAP4 POP SWAP4 POP SWAP4 POP SWAP4 POP SWAP4 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x1901000000000000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x0 PUSH1 0x22 DUP3 ADD DUP2 SWAP1 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000 ADDRESS PUSH1 0x60 SHL AND PUSH1 0x42 DUP4 ADD MSTORE PUSH1 0x56 DUP3 ADD DUP4 SWAP1 MSTORE SWAP1 PUSH1 0x76 ADD PUSH2 0x864 JUMP JUMPDEST PUSH1 0x0 DUP1 DUP1 DUP1 DUP1 PUSH1 0x4 PUSH1 0x1 DUP9 ADD CALLDATALOAD PUSH1 0xE8 SHR DUP3 PUSH2 0xB13 DUP4 DUP4 PUSH2 0x2037 JUMP JUMPDEST SWAP1 POP PUSH2 0xB25 DUP12 PUSH2 0x226 DUP4 DUP7 DUP14 DUP16 PUSH2 0x200D JUMP JUMPDEST SWAP4 SWAP12 POP SWAP2 SWAP10 POP SWAP8 POP SWAP6 POP SWAP4 POP DUP8 DUP8 LT ISZERO PUSH2 0xB7D JUMPI PUSH2 0xB45 DUP2 DUP5 DUP12 DUP14 PUSH2 0x200D JUMP JUMPDEST DUP10 DUP10 PUSH1 0x40 MLOAD PUSH32 0xB006ABA000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x204A JUMP JUMPDEST DUP1 SWAP3 POP JUMPDEST DUP9 DUP4 LT ISZERO PUSH2 0xC67 JUMPI PUSH1 0x3 DUP4 ADD SWAP3 DUP11 ADD CALLDATALOAD PUSH1 0xE8 SHR SWAP2 POP PUSH2 0xBA0 DUP4 DUP4 PUSH2 0x2037 JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0xBC2 PUSH2 0xBB0 DUP9 PUSH2 0x124F JUMP JUMPDEST DUP13 DUP13 DUP8 SWAP1 DUP7 SWAP3 PUSH2 0x226 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x200D JUMP JUMPDEST SWAP4 SWAP13 POP SWAP2 SWAP11 POP SWAP9 POP SWAP1 SWAP2 POP POP DUP9 DUP9 LT ISZERO PUSH2 0xC1A JUMPI PUSH2 0xBE2 DUP3 DUP6 DUP13 DUP15 PUSH2 0x200D JUMP JUMPDEST DUP11 DUP11 PUSH1 0x40 MLOAD PUSH32 0xB006ABA000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x204A JUMP JUMPDEST DUP5 DUP2 LT PUSH2 0xC5D JUMPI PUSH1 0x40 MLOAD PUSH32 0x37DAF62B00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x24 DUP2 ADD DUP7 SWAP1 MSTORE PUSH1 0x44 ADD PUSH2 0x3C0 JUMP JUMPDEST SWAP4 POP SWAP2 POP DUP2 PUSH2 0xB81 JUMP JUMPDEST POP POP POP SWAP4 SWAP8 SWAP3 SWAP7 POP SWAP4 POP SWAP4 POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 DUP4 PUSH1 0x40 MLOAD PUSH1 0x20 ADD PUSH2 0xC94 SWAP3 SWAP2 SWAP1 SWAP2 DUP3 MSTORE PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP2 DUP5 SUB ADD DUP2 MSTORE SWAP2 SWAP1 MSTORE DUP1 MLOAD PUSH1 0x20 SWAP1 SWAP2 ADD KECCAK256 SLOAD SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH32 0xE4A77BBC00000000000000000000000000000000000000000000000000000000 PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP4 AND ADD PUSH2 0xD26 JUMPI POP PUSH1 0x1 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH2 0x2CB DUP3 PUSH2 0x1283 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 MLOAD DUP3 DUP5 DUP3 CALLDATACOPY PUSH1 0x0 DUP1 DUP5 DUP4 DUP10 DUP12 DUP11 CALL SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x60 RETURNDATASIZE PUSH1 0x40 MLOAD SWAP2 POP PUSH1 0x20 DUP3 ADD DUP2 DUP2 ADD PUSH1 0x40 MSTORE DUP2 DUP4 MSTORE DUP2 PUSH1 0x0 DUP3 RETURNDATACOPY POP POP SWAP1 JUMP JUMPDEST DUP4 ISZERO PUSH2 0xD79 JUMPI DUP1 MLOAD PUSH1 0x20 DUP3 ADD REVERT JUMPDEST DUP3 PUSH32 0xAB46C69F7F32E1BF09B0725853DA82A211E5402A0600296AB499A2FB5EA3B419 DUP4 DUP4 PUSH1 0x40 MLOAD PUSH2 0xDAB SWAP3 SWAP2 SWAP1 PUSH2 0x2071 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG2 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x1246 JUMPI PUSH1 0x1 DUP2 ADD SWAP1 DUP6 ADD CALLDATALOAD PUSH1 0xF8 SHR PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 ADD PUSH2 0xE60 JUMPI PUSH1 0x15 DUP3 ADD SWAP2 DUP7 ADD CALLDATALOAD PUSH1 0xF8 DUP2 SWAP1 SHR SWAP1 PUSH1 0x58 SHR PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND SWAP1 PUSH21 0xFF0000000000000000000000000000000000000000 AND DUP2 OR DUP6 PUSH2 0xE46 JUMPI DUP1 PUSH2 0xE55 JUMP JUMPDEST PUSH1 0x0 DUP7 DUP2 MSTORE PUSH1 0x20 DUP3 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 JUMPDEST SWAP6 POP POP POP POP POP PUSH2 0xDBF JUMP JUMPDEST DUP1 PUSH2 0xEF6 JUMPI PUSH1 0x1 DUP3 ADD SWAP2 DUP7 DUP2 ADD CALLDATALOAD PUSH1 0xF8 SHR SWAP1 PUSH1 0x43 ADD PUSH1 0x0 PUSH2 0xE8C DUP11 PUSH2 0xE87 DUP5 DUP9 DUP13 DUP15 PUSH2 0x200D JUMP JUMPDEST PUSH2 0x136D JUMP JUMPDEST PUSH1 0xFF DUP5 AND SWAP8 SWAP1 SWAP8 ADD SWAP7 SWAP2 SWAP5 POP DUP5 SWAP2 SWAP1 POP PUSH1 0xA0 DUP4 SWAP1 SHL PUSH21 0xFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 AND OR DUP7 PUSH2 0xEDB JUMPI DUP1 PUSH2 0xEEA JUMP JUMPDEST PUSH1 0x0 DUP8 DUP2 MSTORE PUSH1 0x20 DUP3 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 JUMPDEST SWAP7 POP POP POP POP POP POP PUSH2 0xDBF JUMP JUMPDEST PUSH1 0x2 DUP2 SUB PUSH2 0x101E JUMPI PUSH1 0x0 DUP1 DUP8 DUP5 ADD CALLDATALOAD PUSH1 0xF8 DUP2 SWAP1 SHR SWAP1 PUSH1 0x58 SHR PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x15 DUP7 ADD SWAP6 POP SWAP1 SWAP3 POP SWAP1 POP PUSH1 0x0 DUP9 DUP6 ADD CALLDATALOAD PUSH1 0xE8 SHR PUSH1 0x3 DUP7 ADD DUP2 PUSH3 0xFFFFFF AND SWAP2 POP DUP1 SWAP7 POP DUP2 SWAP3 POP POP POP PUSH1 0x0 DUP2 DUP7 ADD SWAP1 POP PUSH2 0xF6F DUP12 DUP5 DUP13 DUP13 DUP11 SWAP1 DUP7 SWAP3 PUSH2 0xF6A SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x200D JUMP JUMPDEST PUSH2 0x1630 JUMP JUMPDEST PUSH2 0xFB7 JUMPI DUP11 DUP4 PUSH2 0xF81 DUP4 DUP10 DUP14 DUP16 PUSH2 0x200D JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x9A94623200000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x208A JUMP JUMPDEST PUSH1 0xFF DUP5 AND SWAP8 SWAP1 SWAP8 ADD SWAP7 SWAP5 POP DUP5 PUSH1 0xA0 DUP5 SWAP1 SHL PUSH21 0xFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP5 AND OR DUP8 PUSH2 0x1002 JUMPI DUP1 PUSH2 0x1011 JUMP JUMPDEST PUSH1 0x0 DUP9 DUP2 MSTORE PUSH1 0x20 DUP3 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 JUMPDEST SWAP8 POP POP POP POP POP POP POP PUSH2 0xDBF JUMP JUMPDEST PUSH1 0x3 DUP2 SUB PUSH2 0x1051 JUMPI PUSH1 0x20 DUP3 ADD SWAP2 DUP7 ADD CALLDATALOAD DUP4 PUSH2 0x1039 JUMPI DUP1 PUSH2 0x1048 JUMP JUMPDEST PUSH1 0x0 DUP5 DUP2 MSTORE PUSH1 0x20 DUP3 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 JUMPDEST SWAP4 POP POP POP PUSH2 0xDBF JUMP JUMPDEST PUSH1 0x4 DUP2 SUB PUSH2 0x109D JUMPI PUSH1 0x3 DUP1 DUP4 ADD SWAP3 DUP8 DUP2 ADD CALLDATALOAD PUSH1 0xE8 SHR SWAP2 SWAP1 DUP3 ADD ADD PUSH1 0x0 DUP1 PUSH2 0x107E DUP12 PUSH2 0xA24 DUP6 DUP10 DUP14 DUP16 PUSH2 0x200D JUMP JUMPDEST PUSH1 0x0 SWAP9 DUP10 MSTORE PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 SWAP8 KECCAK256 SWAP7 SWAP1 SWAP8 ADD SWAP7 POP SWAP1 SWAP4 POP PUSH2 0xDBF SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x6 DUP2 SUB PUSH2 0x11A5 JUMPI PUSH1 0x0 DUP3 DUP8 ADD CALLDATALOAD PUSH1 0xF8 SHR PUSH1 0x1 DUP5 ADD SWAP4 POP PUSH1 0xFF AND SWAP1 POP PUSH1 0x0 DUP8 DUP5 ADD CALLDATALOAD PUSH1 0xF0 SHR PUSH1 0x2 DUP6 ADD SWAP5 POP PUSH2 0xFFFF AND SWAP1 POP PUSH1 0x0 DUP9 DUP6 ADD CALLDATALOAD PUSH1 0xE8 SHR PUSH1 0x3 DUP7 ADD DUP2 PUSH3 0xFFFFFF AND SWAP2 POP DUP1 SWAP7 POP DUP2 SWAP3 POP POP POP PUSH1 0x0 DUP2 DUP7 ADD SWAP1 POP PUSH1 0x0 DUP1 PUSH2 0x110B DUP14 DUP14 DUP14 DUP12 SWAP1 DUP8 SWAP3 PUSH2 0xA24 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x200D JUMP JUMPDEST SWAP4 SWAP9 POP DUP9 SWAP4 SWAP1 SWAP3 POP SWAP1 POP DUP5 DUP3 LT PUSH2 0x1121 JUMPI SWAP9 DUP6 ADD SWAP9 JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x53657175656E6365206E657374656420636F6E6669673A0A0000000000000000 PUSH1 0x20 DUP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x38 DUP3 ADD DUP5 SWAP1 MSTORE PUSH1 0x58 DUP3 ADD DUP9 SWAP1 MSTORE PUSH1 0x78 DUP1 DUP4 ADD DUP11 SWAP1 MSTORE DUP4 MLOAD DUP1 DUP5 SUB SWAP1 SWAP2 ADD DUP2 MSTORE PUSH1 0x98 SWAP1 SWAP3 ADD SWAP1 SWAP3 MSTORE DUP1 MLOAD SWAP2 ADD KECCAK256 DUP10 PUSH2 0x1187 JUMPI DUP1 PUSH2 0x1196 JUMP JUMPDEST PUSH1 0x0 DUP11 DUP2 MSTORE PUSH1 0x20 DUP3 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 JUMPDEST SWAP10 POP POP POP POP POP POP POP POP POP PUSH2 0xDBF JUMP JUMPDEST PUSH1 0x5 DUP2 SUB PUSH2 0x1211 JUMPI PUSH1 0x20 DUP3 ADD SWAP2 DUP7 ADD CALLDATALOAD DUP8 DUP2 SUB PUSH2 0x11E0 JUMPI PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP5 POP JUMPDEST PUSH1 0x0 PUSH2 0x11EB DUP3 PUSH2 0x1817 JUMP JUMPDEST SWAP1 POP DUP5 PUSH2 0x11F8 JUMPI DUP1 PUSH2 0x1207 JUMP JUMPDEST PUSH1 0x0 DUP6 DUP2 MSTORE PUSH1 0x20 DUP3 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 JUMPDEST SWAP5 POP POP POP POP PUSH2 0xDBF JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0xB2505F7C00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x24 ADD PUSH2 0x3C0 JUMP JUMPDEST POP SWAP4 POP SWAP4 SWAP2 POP POP JUMP JUMPDEST PUSH32 0x8713A7C4465F6FBEE2B6E9D6646D1D9F83FEC929EDFC4BAF661F3C865BDD04D1 PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x20 DUP3 SWAP1 MSTORE PUSH1 0x40 DUP2 KECCAK256 PUSH2 0x2CB JUMP JUMPDEST PUSH1 0x0 PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP3 AND PUSH32 0xAC6A444E00000000000000000000000000000000000000000000000000000000 EQ DUP1 PUSH2 0x1316 JUMPI POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP3 AND PUSH32 0x36E7817500000000000000000000000000000000000000000000000000000000 EQ JUMPDEST ISZERO PUSH2 0x1323 JUMPI POP PUSH1 0x1 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH32 0x1FFC9A700000000000000000000000000000000000000000000000000000000 PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP4 AND EQ PUSH2 0x2CB JUMP JUMPDEST PUSH1 0x0 PUSH1 0x42 DUP3 EQ PUSH2 0x13AD JUMPI DUP3 DUP3 PUSH1 0x40 MLOAD PUSH32 0x2EE17A3D00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP3 SWAP2 SWAP1 PUSH2 0x20CA JUMP JUMPDEST PUSH1 0x0 PUSH2 0x13C6 PUSH2 0x13BD PUSH1 0x1 DUP6 PUSH2 0x20DE JUMP JUMPDEST DUP6 ADD CALLDATALOAD PUSH1 0xF8 SHR SWAP1 JUMP JUMPDEST PUSH1 0xFF AND SWAP1 POP PUSH1 0x40 DUP5 ADD CALLDATALOAD PUSH1 0xF8 SHR DUP5 CALLDATALOAD PUSH1 0x20 DUP7 ADD CALLDATALOAD PUSH32 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 DUP2 GT ISZERO PUSH2 0x143A JUMPI DUP7 DUP7 DUP3 PUSH1 0x40 MLOAD PUSH32 0xAD4AAC7600000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x20F1 JUMP JUMPDEST DUP3 PUSH1 0xFF AND PUSH1 0x1B EQ ISZERO DUP1 ISZERO PUSH2 0x1452 JUMPI POP DUP3 PUSH1 0xFF AND PUSH1 0x1C EQ ISZERO JUMPDEST ISZERO PUSH2 0x148F JUMPI DUP7 DUP7 DUP5 PUSH1 0x40 MLOAD PUSH32 0xE578897E00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x2115 JUMP JUMPDEST PUSH1 0x1 DUP5 SUB PUSH2 0x14FC JUMPI PUSH1 0x40 DUP1 MLOAD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 DUP2 ADD DUP1 DUP4 MSTORE DUP11 SWAP1 MSTORE PUSH1 0xFF DUP6 AND SWAP2 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x60 DUP2 ADD DUP4 SWAP1 MSTORE PUSH1 0x80 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x1 SWAP1 PUSH1 0xA0 ADD JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 SUB SWAP1 DUP1 DUP5 SUB SWAP1 DUP6 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x14EB JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP PUSH1 0x20 PUSH1 0x40 MLOAD SUB MLOAD SWAP5 POP PUSH2 0x15D4 JUMP JUMPDEST PUSH1 0x2 DUP5 SUB PUSH2 0x1599 JUMPI PUSH1 0x40 MLOAD PUSH32 0x19457468657265756D205369676E6564204D6573736167653A0A333200000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x3C DUP2 ADD DUP10 SWAP1 MSTORE PUSH1 0x1 SWAP1 PUSH1 0x5C ADD PUSH1 0x40 DUP1 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP2 DUP5 SUB ADD DUP2 MSTORE DUP3 DUP3 MSTORE DUP1 MLOAD PUSH1 0x20 SWAP2 DUP3 ADD KECCAK256 PUSH1 0x0 DUP5 MSTORE SWAP1 DUP4 ADD DUP1 DUP4 MSTORE MSTORE PUSH1 0xFF DUP7 AND SWAP1 DUP3 ADD MSTORE PUSH1 0x60 DUP2 ADD DUP5 SWAP1 MSTORE PUSH1 0x80 DUP2 ADD DUP4 SWAP1 MSTORE PUSH1 0xA0 ADD PUSH2 0x14C9 JUMP JUMPDEST DUP7 DUP7 DUP6 PUSH1 0x1 PUSH1 0x40 MLOAD PUSH32 0x9DFBA85200000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x213C JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP6 AND PUSH2 0x1625 JUMPI DUP7 DUP7 PUSH1 0x40 MLOAD PUSH32 0x6C1719D200000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP3 SWAP2 SWAP1 PUSH2 0x20CA JUMP JUMPDEST POP POP POP POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 SUB PUSH2 0x166B JUMPI PUSH1 0x40 MLOAD PUSH32 0xAC241E1100000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 DUP4 DUP4 PUSH2 0x167A PUSH1 0x1 DUP3 PUSH2 0x20DE JUMP JUMPDEST DUP2 DUP2 LT PUSH2 0x1689 JUMPI PUSH2 0x1689 PUSH2 0x1E27 JUMP JUMPDEST SWAP2 SWAP1 SWAP2 ADD CALLDATALOAD PUSH1 0xF8 SHR SWAP2 POP POP PUSH1 0x1 DUP2 EQ DUP1 PUSH2 0x16A3 JUMPI POP PUSH1 0x2 DUP2 EQ JUMPDEST ISZERO PUSH2 0x16E8 JUMPI DUP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH2 0x16CA DUP8 DUP7 DUP7 PUSH2 0x136D JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ SWAP2 POP PUSH2 0x180E JUMP JUMPDEST PUSH1 0x3 DUP2 SUB PUSH2 0x17D3 JUMPI PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP6 AND PUSH4 0x1626BA7E DUP8 DUP7 PUSH1 0x0 DUP8 PUSH2 0x171C PUSH1 0x1 DUP3 PUSH2 0x20DE JUMP JUMPDEST SWAP3 PUSH2 0x1729 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x200D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP5 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x1747 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x2168 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x1764 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x1788 SWAP2 SWAP1 PUSH2 0x218B JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND PUSH32 0x1626BA7E00000000000000000000000000000000000000000000000000000000 EQ SWAP2 POP PUSH2 0x180E JUMP JUMPDEST DUP4 DUP4 DUP3 PUSH1 0x0 PUSH1 0x40 MLOAD PUSH32 0x9DFBA85200000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x213C JUMP JUMPDEST POP SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x53657175656E636520737461746963206469676573743A0A0000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x38 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x0 SWAP1 PUSH1 0x58 ADD PUSH2 0x864 JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND DUP2 EQ PUSH2 0x3D2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1892 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x317 DUP2 PUSH2 0x1852 JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 PUSH1 0x1F DUP5 ADD SLT PUSH2 0x18AF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x18C7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 DUP4 ADD SWAP2 POP DUP4 PUSH1 0x20 DUP3 DUP6 ADD ADD GT ISZERO PUSH2 0x18DF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x40 DUP5 DUP7 SUB SLT ISZERO PUSH2 0x18FB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 CALLDATALOAD SWAP3 POP PUSH1 0x20 DUP5 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x1919 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x1925 DUP7 DUP3 DUP8 ADD PUSH2 0x189D JUMP JUMPDEST SWAP5 SWAP8 SWAP1 SWAP7 POP SWAP4 SWAP5 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x40 DUP6 DUP8 SUB SLT ISZERO PUSH2 0x1948 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0x1960 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x196C DUP9 DUP4 DUP10 ADD PUSH2 0x189D JUMP JUMPDEST SWAP1 SWAP7 POP SWAP5 POP PUSH1 0x20 DUP8 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0x1985 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1992 DUP8 DUP3 DUP9 ADD PUSH2 0x189D JUMP JUMPDEST SWAP6 SWAP9 SWAP5 SWAP8 POP SWAP6 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x19B0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP CALLDATALOAD SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 PUSH1 0x1F DUP5 ADD SLT PUSH2 0x19C9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x19E1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 DUP4 ADD SWAP2 POP DUP4 PUSH1 0x20 DUP3 PUSH1 0x5 SHL DUP6 ADD ADD GT ISZERO PUSH2 0x18DF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x20 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x1A0F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x1A26 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x1A32 DUP6 DUP3 DUP7 ADD PUSH2 0x19B7 JUMP JUMPDEST SWAP1 SWAP7 SWAP1 SWAP6 POP SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP7 DUP9 SUB SLT ISZERO PUSH2 0x1A56 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP6 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0x1A6E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x1A7A DUP10 DUP4 DUP11 ADD PUSH2 0x19B7 JUMP JUMPDEST SWAP1 SWAP8 POP SWAP6 POP PUSH1 0x20 DUP9 ADD CALLDATALOAD SWAP5 POP PUSH1 0x40 DUP9 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0x1A9A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1AA7 DUP9 DUP3 DUP10 ADD PUSH2 0x189D JUMP JUMPDEST SWAP7 SWAP10 SWAP6 SWAP9 POP SWAP4 SWAP7 POP SWAP3 SWAP5 SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH32 0x4E487B7100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 MSTORE PUSH1 0x41 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1AF9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0x1B11 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 DUP5 ADD SWAP2 POP DUP5 PUSH1 0x1F DUP4 ADD SLT PUSH2 0x1B25 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD DUP2 DUP2 GT ISZERO PUSH2 0x1B37 JUMPI PUSH2 0x1B37 PUSH2 0x1AB8 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1F DUP3 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 DUP2 AND PUSH1 0x3F ADD AND DUP2 ADD SWAP1 DUP4 DUP3 GT DUP2 DUP4 LT OR ISZERO PUSH2 0x1B7D JUMPI PUSH2 0x1B7D PUSH2 0x1AB8 JUMP JUMPDEST DUP2 PUSH1 0x40 MSTORE DUP3 DUP2 MSTORE DUP8 PUSH1 0x20 DUP5 DUP8 ADD ADD GT ISZERO PUSH2 0x1B96 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP4 ADD CALLDATACOPY PUSH1 0x0 SWAP3 DUP2 ADD PUSH1 0x20 ADD SWAP3 SWAP1 SWAP3 MSTORE POP SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST DUP2 DUP4 DUP3 CALLDATACOPY PUSH1 0x0 SWAP2 ADD SWAP1 DUP2 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST DUP1 CALLDATALOAD DUP1 ISZERO ISZERO DUP2 EQ PUSH2 0x1BD6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP2 SWAP1 POP JUMP JUMPDEST DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND DUP2 EQ PUSH2 0x1BD6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 DUP4 MSTORE DUP2 DUP2 PUSH1 0x20 DUP6 ADD CALLDATACOPY POP PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 ADD ADD MSTORE PUSH1 0x0 PUSH1 0x20 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 PUSH1 0x1F DUP5 ADD AND DUP5 ADD ADD SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST DUP2 DUP4 MSTORE PUSH1 0x0 PUSH1 0x20 DUP1 DUP6 ADD DUP1 DUP2 SWAP7 POP DUP6 PUSH1 0x5 SHL DUP2 ADD SWAP2 POP DUP5 PUSH1 0x0 JUMPDEST DUP8 DUP2 LT ISZERO PUSH2 0x1D8A JUMPI DUP3 DUP5 SUB DUP10 MSTORE DUP2 CALLDATALOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 DUP9 CALLDATASIZE SUB ADD DUP2 SLT PUSH2 0x1CA1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP8 ADD PUSH1 0xC0 PUSH2 0x1CAE DUP3 PUSH2 0x1BC6 JUMP JUMPDEST ISZERO ISZERO DUP7 MSTORE PUSH2 0x1CBD DUP8 DUP4 ADD PUSH2 0x1BC6 JUMP JUMPDEST ISZERO ISZERO DUP7 DUP9 ADD MSTORE PUSH1 0x40 DUP3 DUP2 ADD CALLDATALOAD SWAP1 DUP8 ADD MSTORE PUSH1 0x60 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH2 0x1CEF DUP3 DUP6 ADD PUSH2 0x1BDB JUMP JUMPDEST AND SWAP1 DUP8 ADD MSTORE PUSH1 0x80 DUP3 DUP2 ADD CALLDATALOAD SWAP1 DUP8 ADD MSTORE PUSH1 0xA0 DUP1 DUP4 ADD CALLDATALOAD CALLDATASIZE DUP5 SWAP1 SUB PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 ADD DUP2 SLT PUSH2 0x1D35 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP1 SWAP3 ADD DUP8 DUP2 ADD SWAP3 SWAP1 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x1D53 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 CALLDATASIZE SUB DUP5 SGT ISZERO PUSH2 0x1D62 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 DUP3 DUP10 ADD MSTORE PUSH2 0x1D74 DUP4 DUP10 ADD DUP3 DUP7 PUSH2 0x1BFF JUMP JUMPDEST SWAP13 DUP10 ADD SWAP13 SWAP8 POP POP POP SWAP3 DUP7 ADD SWAP3 POP POP PUSH1 0x1 ADD PUSH2 0x1C62 JUMP JUMPDEST POP SWAP2 SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP2 MSTORE PUSH1 0x5 PUSH1 0x40 DUP3 ADD MSTORE PUSH32 0x73656C663A000000000000000000000000000000000000000000000000000000 PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x0 PUSH2 0x37B PUSH1 0x80 DUP4 ADD DUP5 DUP7 PUSH2 0x1C48 JUMP JUMPDEST PUSH1 0x40 DUP2 MSTORE PUSH1 0x6 PUSH1 0x40 DUP3 ADD MSTORE PUSH32 0x67756573743A0000000000000000000000000000000000000000000000000000 PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x0 PUSH2 0x37B PUSH1 0x80 DUP4 ADD DUP5 DUP7 PUSH2 0x1C48 JUMP JUMPDEST PUSH32 0x4E487B7100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 MSTORE PUSH1 0x32 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 DUP2 MLOAD DUP1 DUP5 MSTORE PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0x1E7C JUMPI PUSH1 0x20 DUP2 DUP6 ADD DUP2 ADD MLOAD DUP7 DUP4 ADD DUP3 ADD MSTORE ADD PUSH2 0x1E60 JUMP JUMPDEST POP PUSH1 0x0 PUSH1 0x20 DUP3 DUP7 ADD ADD MSTORE PUSH1 0x20 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 PUSH1 0x1F DUP4 ADD AND DUP6 ADD ADD SWAP2 POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x20 DUP2 MSTORE PUSH1 0x0 PUSH2 0x317 PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0x1E56 JUMP JUMPDEST PUSH1 0x0 DUP3 CALLDATALOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 DUP4 CALLDATASIZE SUB ADD DUP2 SLT PUSH2 0x1F01 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP2 SWAP1 SWAP2 ADD SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1F1D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x317 DUP3 PUSH2 0x1BC6 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1F38 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x317 DUP3 PUSH2 0x1BDB JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 CALLDATALOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 DUP5 CALLDATASIZE SUB ADD DUP2 SLT PUSH2 0x1F76 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 ADD DUP1 CALLDATALOAD SWAP2 POP PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x1F91 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 ADD SWAP2 POP CALLDATASIZE DUP2 SWAP1 SUB DUP3 SGT ISZERO PUSH2 0x18DF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH32 0x4E487B7100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 MSTORE PUSH1 0x11 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 SUB PUSH2 0x2006 JUMPI PUSH2 0x2006 PUSH2 0x1FA6 JUMP JUMPDEST POP PUSH1 0x1 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 DUP6 DUP6 GT ISZERO PUSH2 0x201D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 DUP7 GT ISZERO PUSH2 0x202A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP POP DUP3 ADD SWAP4 SWAP2 SWAP1 SWAP3 SUB SWAP2 POP JUMP JUMPDEST DUP1 DUP3 ADD DUP1 DUP3 GT ISZERO PUSH2 0x2CB JUMPI PUSH2 0x2CB PUSH2 0x1FA6 JUMP JUMPDEST PUSH1 0x60 DUP2 MSTORE PUSH1 0x0 PUSH2 0x205E PUSH1 0x60 DUP4 ADD DUP7 DUP9 PUSH2 0x1BFF JUMP JUMPDEST PUSH1 0x20 DUP4 ADD SWAP5 SWAP1 SWAP5 MSTORE POP PUSH1 0x40 ADD MSTORE SWAP3 SWAP2 POP POP JUMP JUMPDEST DUP3 DUP2 MSTORE PUSH1 0x40 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x0 PUSH2 0x37B PUSH1 0x40 DUP4 ADD DUP5 PUSH2 0x1E56 JUMP JUMPDEST DUP5 DUP2 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP5 AND PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x60 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x0 PUSH2 0x20C0 PUSH1 0x60 DUP4 ADD DUP5 DUP7 PUSH2 0x1BFF JUMP JUMPDEST SWAP7 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x20 DUP2 MSTORE PUSH1 0x0 PUSH2 0x37B PUSH1 0x20 DUP4 ADD DUP5 DUP7 PUSH2 0x1BFF JUMP JUMPDEST DUP2 DUP2 SUB DUP2 DUP2 GT ISZERO PUSH2 0x2CB JUMPI PUSH2 0x2CB PUSH2 0x1FA6 JUMP JUMPDEST PUSH1 0x40 DUP2 MSTORE PUSH1 0x0 PUSH2 0x2105 PUSH1 0x40 DUP4 ADD DUP6 DUP8 PUSH2 0x1BFF JUMP JUMPDEST SWAP1 POP DUP3 PUSH1 0x20 DUP4 ADD MSTORE SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP2 MSTORE PUSH1 0x0 PUSH2 0x2129 PUSH1 0x40 DUP4 ADD DUP6 DUP8 PUSH2 0x1BFF JUMP JUMPDEST SWAP1 POP PUSH1 0xFF DUP4 AND PUSH1 0x20 DUP4 ADD MSTORE SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x60 DUP2 MSTORE PUSH1 0x0 PUSH2 0x2150 PUSH1 0x60 DUP4 ADD DUP7 DUP9 PUSH2 0x1BFF JUMP JUMPDEST PUSH1 0x20 DUP4 ADD SWAP5 SWAP1 SWAP5 MSTORE POP SWAP1 ISZERO ISZERO PUSH1 0x40 SWAP1 SWAP2 ADD MSTORE SWAP3 SWAP2 POP POP JUMP JUMPDEST DUP4 DUP2 MSTORE PUSH1 0x40 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x0 PUSH2 0x2182 PUSH1 0x40 DUP4 ADD DUP5 DUP7 PUSH2 0x1BFF JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x219D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 MLOAD PUSH2 0x317 DUP2 PUSH2 0x1852 JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 SWAP12 0xB9 0x5D XOR 0xE9 PUSH32 0x278AA47E0C04C20D5A6AF9BDB6D473C6D4051192CD96FC17866864736F6C6343 STOP ADDMOD SLT STOP CALLER ", + "sourceMap": "640:2693:1:-:0;;;;;;;;;;;;-1:-1:-1;200:4:7;185:20;;640:2693:1;;;;;;;;;;;" + }, + "deployedBytecode": { + "functionDebugData": { + "@SET_IMAGE_HASH_TYPE_HASH_2042": { + "entryPoint": null, + "id": 2042, + "parameterSlots": 0, + "returnSlots": 0 + }, + "@_executeGuest_199": { + "entryPoint": 2177, + "id": 199, + "parameterSlots": 3, + "returnSlots": 0 + }, + "@_hashSetImageHashStruct_2071": { + "entryPoint": 4687, + "id": 2071, + "parameterSlots": 1, + "returnSlots": 1 + }, + "@_isValidImage_211": { + "entryPoint": null, + "id": 211, + "parameterSlots": 1, + "returnSlots": 1 + }, + "@_leafForAddressAndWeight_1424": { + "entryPoint": null, + "id": 1424, + "parameterSlots": 2, + "returnSlots": 1 + }, + "@_leafForHardcodedSubdigest_1441": { + "entryPoint": 6167, + "id": 1441, + "parameterSlots": 1, + "returnSlots": 1 + }, + "@_leafForNested_1464": { + "entryPoint": null, + "id": 1464, + "parameterSlots": 3, + "returnSlots": 1 + }, + "@_revertBytes_807": { + "entryPoint": 3435, + "id": 807, + "parameterSlots": 4, + "returnSlots": 0 + }, + "@_signatureValidation_457": { + "entryPoint": 1938, + "id": 457, + "parameterSlots": 3, + "returnSlots": 2 + }, + "@_updateImageHash_222": { + "entryPoint": 1994, + "id": 222, + "parameterSlots": 1, + "returnSlots": 0 + }, + "@call_2515": { + "entryPoint": 3375, + "id": 2515, + "parameterSlots": 5, + "returnSlots": 1 + }, + "@chainedRecover_2217": { + "entryPoint": 2808, + "id": 2217, + "parameterSlots": 3, + "returnSlots": 5 + }, + "@createContract_876": { + "entryPoint": 1595, + "id": 876, + "parameterSlots": 1, + "returnSlots": 1 + }, + "@execute_74": { + "entryPoint": 1050, + "id": 74, + "parameterSlots": 5, + "returnSlots": 0 + }, + "@fkeccak256_2491": { + "entryPoint": null, + "id": 2491, + "parameterSlots": 2, + "returnSlots": 1 + }, + "@isValidSignature_2797": { + "entryPoint": 5680, + "id": 2797, + "parameterSlots": 4, + "returnSlots": 1 + }, + "@isValidSignature_488": { + "entryPoint": 798, + "id": 488, + "parameterSlots": 4, + "returnSlots": 1 + }, + "@isValidSignature_517": { + "entryPoint": 721, + "id": 517, + "parameterSlots": 3, + "returnSlots": 1 + }, + "@nonce_955": { + "entryPoint": 1829, + "id": 955, + "parameterSlots": 0, + "returnSlots": 1 + }, + "@readBytes32Map_1178": { + "entryPoint": 3189, + "id": 1178, + "parameterSlots": 2, + "returnSlots": 1 + }, + "@readBytes32_2339": { + "entryPoint": null, + "id": 2339, + "parameterSlots": 3, + "returnSlots": 1 + }, + "@readBytes32_2475": { + "entryPoint": null, + "id": 2475, + "parameterSlots": 3, + "returnSlots": 2 + }, + "@readFirstUint16_2361": { + "entryPoint": null, + "id": 2361, + "parameterSlots": 2, + "returnSlots": 1 + }, + "@readNonce_976": { + "entryPoint": 1551, + "id": 976, + "parameterSlots": 1, + "returnSlots": 1 + }, + "@readUint16_2433": { + "entryPoint": null, + "id": 2433, + "parameterSlots": 3, + "returnSlots": 2 + }, + "@readUint24_2447": { + "entryPoint": null, + "id": 2447, + "parameterSlots": 3, + "returnSlots": 2 + }, + "@readUint32_2373": { + "entryPoint": null, + "id": 2373, + "parameterSlots": 3, + "returnSlots": 1 + }, + "@readUint8Address_2419": { + "entryPoint": null, + "id": 2419, + "parameterSlots": 3, + "returnSlots": 3 + }, + "@readUint8_2351": { + "entryPoint": null, + "id": 2351, + "parameterSlots": 3, + "returnSlots": 1 + }, + "@readUint8_2403": { + "entryPoint": null, + "id": 2403, + "parameterSlots": 3, + "returnSlots": 2 + }, + "@recoverBranch_1954": { + "entryPoint": 3513, + "id": 1954, + "parameterSlots": 3, + "returnSlots": 2 + }, + "@recoverSigner_2715": { + "entryPoint": 4973, + "id": 2715, + "parameterSlots": 3, + "returnSlots": 1 + }, + "@recover_2020": { + "entryPoint": 2574, + "id": 2020, + "parameterSlots": 3, + "returnSlots": 4 + }, + "@recover_2246": { + "entryPoint": 2655, + "id": 2246, + "parameterSlots": 3, + "returnSlots": 4 + }, + "@returnData_2499": { + "entryPoint": 3404, + "id": 2499, + "parameterSlots": 0, + "returnSlots": 1 + }, + "@selfExecute_102": { + "entryPoint": 981, + "id": 102, + "parameterSlots": 2, + "returnSlots": 0 + }, + "@signatureRecovery_413": { + "entryPoint": 1095, + "id": 413, + "parameterSlots": 3, + "returnSlots": 5 + }, + "@subdigest_1394": { + "entryPoint": 2044, + "id": 1394, + "parameterSlots": 1, + "returnSlots": 1 + }, + "@subdigest_2274": { + "entryPoint": 2699, + "id": 2274, + "parameterSlots": 1, + "returnSlots": 1 + }, + "@supportsInterface_240": { + "entryPoint": 704, + "id": 240, + "parameterSlots": 1, + "returnSlots": 1 + }, + "@supportsInterface_549": { + "entryPoint": 4739, + "id": 549, + "parameterSlots": 1, + "returnSlots": 1 + }, + "@supportsInterface_832": { + "entryPoint": 3283, + "id": 832, + "parameterSlots": 1, + "returnSlots": 1 + }, + "@supportsInterface_901": { + "entryPoint": 1846, + "id": 901, + "parameterSlots": 1, + "returnSlots": 1 + }, + "@supportsInterface_919": { + "entryPoint": null, + "id": 919, + "parameterSlots": 1, + "returnSlots": 1 + }, + "@updateImageHash_563": { + "entryPoint": 899, + "id": 563, + "parameterSlots": 1, + "returnSlots": 0 + }, + "abi_decode_address": { + "entryPoint": 7131, + "id": null, + "parameterSlots": 1, + "returnSlots": 1 + }, + "abi_decode_array_struct_Transaction_calldata_dyn_calldata": { + "entryPoint": 6583, + "id": null, + "parameterSlots": 2, + "returnSlots": 2 + }, + "abi_decode_bool": { + "entryPoint": 7110, + "id": null, + "parameterSlots": 1, + "returnSlots": 1 + }, + "abi_decode_bytes_calldata": { + "entryPoint": 6301, + "id": null, + "parameterSlots": 2, + "returnSlots": 2 + }, + "abi_decode_tuple_t_address": { + "entryPoint": 7974, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_decode_tuple_t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr": { + "entryPoint": 6652, + "id": null, + "parameterSlots": 2, + "returnSlots": 2 + }, + "abi_decode_tuple_t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptrt_uint256t_bytes_calldata_ptr": { + "entryPoint": 6718, + "id": null, + "parameterSlots": 2, + "returnSlots": 5 + }, + "abi_decode_tuple_t_bool": { + "entryPoint": 7947, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_decode_tuple_t_bytes32": { + "entryPoint": 6558, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_decode_tuple_t_bytes32t_bytes_calldata_ptr": { + "entryPoint": 6374, + "id": null, + "parameterSlots": 2, + "returnSlots": 3 + }, + "abi_decode_tuple_t_bytes4": { + "entryPoint": 6272, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_decode_tuple_t_bytes4_fromMemory": { + "entryPoint": 8587, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_decode_tuple_t_bytes_calldata_ptrt_bytes_calldata_ptr": { + "entryPoint": 6450, + "id": null, + "parameterSlots": 2, + "returnSlots": 4 + }, + "abi_decode_tuple_t_bytes_memory_ptr": { + "entryPoint": 6887, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_decode_tuple_t_uint256": { + "entryPoint": null, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_array_struct_Transaction_calldata_dyn_calldata": { + "entryPoint": 7240, + "id": null, + "parameterSlots": 3, + "returnSlots": 1 + }, + "abi_encode_bytes": { + "entryPoint": 7766, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_bytes_calldata": { + "entryPoint": 7167, + "id": null, + "parameterSlots": 3, + "returnSlots": 1 + }, + "abi_encode_tuple_packed_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__nonPadded_inplace_fromStack_reversed": { + "entryPoint": 7094, + "id": null, + "parameterSlots": 3, + "returnSlots": 1 + }, + "abi_encode_tuple_packed_t_stringliteral_178a2411ab6fbc1ba11064408972259c558d0e82fd48b0aba3ad81d14f065e73_t_bytes32__to_t_string_memory_ptr_t_bytes32__nonPadded_inplace_fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_tuple_packed_t_stringliteral_301a50b291d33ce1e8e9064e3f6a6c51d902ec22892b50d58abf6357c6a45541_t_uint256_t_address_t_bytes32__to_t_string_memory_ptr_t_uint256_t_address_t_bytes32__nonPadded_inplace_fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 4, + "returnSlots": 1 + }, + "abi_encode_tuple_packed_t_stringliteral_583557e68bca91e5400591dbc9ae31043113c95e3cd985463ae532f51d706f8c_t_bytes32__to_t_string_memory_ptr_t_bytes32__nonPadded_inplace_fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_tuple_packed_t_stringliteral_58d1832f15932b40f8da147bd99ac98efab990f25a786a2229b05ee5f5be41a7_t_bytes32_t_uint256_t_uint256__to_t_string_memory_ptr_t_bytes32_t_uint256_t_uint256__nonPadded_inplace_fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 4, + "returnSlots": 1 + }, + "abi_encode_tuple_t_address__to_t_address__fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_tuple_t_address_t_address__to_t_address_t_address__fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 3, + "returnSlots": 1 + }, + "abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_tuple_t_bytes1__to_t_bytes1__fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_tuple_t_bytes32__to_t_bytes32__fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_tuple_t_bytes32_t_address_t_bytes_calldata_ptr_slice__to_t_bytes32_t_address_t_bytes_memory_ptr__fromStack_reversed": { + "entryPoint": 8330, + "id": null, + "parameterSlots": 5, + "returnSlots": 1 + }, + "abi_encode_tuple_t_bytes32_t_bytes32__to_t_bytes32_t_bytes32__fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 3, + "returnSlots": 1 + }, + "abi_encode_tuple_t_bytes32_t_bytes_calldata_ptr_slice__to_t_bytes32_t_bytes_memory_ptr__fromStack_reversed": { + "entryPoint": 8552, + "id": null, + "parameterSlots": 4, + "returnSlots": 1 + }, + "abi_encode_tuple_t_bytes32_t_uint8_t_bytes32_t_bytes32__to_t_bytes32_t_uint8_t_bytes32_t_bytes32__fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 5, + "returnSlots": 1 + }, + "abi_encode_tuple_t_bytes4__to_t_bytes4__fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_tuple_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__fromStack_reversed": { + "entryPoint": 8394, + "id": null, + "parameterSlots": 3, + "returnSlots": 1 + }, + "abi_encode_tuple_t_bytes_calldata_ptr_slice_t_uint256_t_uint256__to_t_bytes_memory_ptr_t_uint256_t_uint256__fromStack_reversed": { + "entryPoint": 8266, + "id": null, + "parameterSlots": 5, + "returnSlots": 1 + }, + "abi_encode_tuple_t_bytes_calldata_ptr_t_bytes32__to_t_bytes_memory_ptr_t_bytes32__fromStack_reversed": { + "entryPoint": 8433, + "id": null, + "parameterSlots": 4, + "returnSlots": 1 + }, + "abi_encode_tuple_t_bytes_calldata_ptr_t_uint256_t_bool__to_t_bytes_memory_ptr_t_uint256_t_bool__fromStack_reversed": { + "entryPoint": 8508, + "id": null, + "parameterSlots": 5, + "returnSlots": 1 + }, + "abi_encode_tuple_t_bytes_calldata_ptr_t_uint8__to_t_bytes_memory_ptr_t_uint256__fromStack_reversed": { + "entryPoint": 8469, + "id": null, + "parameterSlots": 4, + "returnSlots": 1 + }, + "abi_encode_tuple_t_bytes_memory_ptr__to_t_bytes_memory_ptr__fromStack_reversed": { + "entryPoint": 7866, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_tuple_t_stringliteral_4dfa0bed92fb5c2df0b47ce555e6e6b89f746e856aa9783c634a4987edcbf682_t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr__to_t_string_memory_ptr_t_array$_t_struct$_Transaction_$1292_memory_ptr_$dyn_memory_ptr__fromStack_reversed": { + "entryPoint": 7647, + "id": null, + "parameterSlots": 3, + "returnSlots": 1 + }, + "abi_encode_tuple_t_stringliteral_bf9461da9f9c0123d3a54c61147a274d8fdb5d5c1e488665fb11b9edbbc32845_t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr__to_t_string_memory_ptr_t_array$_t_struct$_Transaction_$1292_memory_ptr_$dyn_memory_ptr__fromStack_reversed": { + "entryPoint": 7575, + "id": null, + "parameterSlots": 3, + "returnSlots": 1 + }, + "abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_tuple_t_uint256_t_bytes_memory_ptr__to_t_uint256_t_bytes_memory_ptr__fromStack_reversed": { + "entryPoint": 8305, + "id": null, + "parameterSlots": 3, + "returnSlots": 1 + }, + "abi_encode_tuple_t_uint256_t_uint256__to_t_uint256_t_uint256__fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 3, + "returnSlots": 1 + }, + "abi_encode_tuple_t_uint256_t_uint256_t_bytes32_t_bytes32_t_uint256__to_t_uint256_t_uint256_t_bytes32_t_bytes32_t_uint256__fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 6, + "returnSlots": 1 + }, + "abi_encode_tuple_t_uint256_t_uint256_t_uint256__to_t_uint256_t_uint256_t_uint256__fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 4, + "returnSlots": 1 + }, + "access_calldata_tail_t_bytes_calldata_ptr": { + "entryPoint": 8001, + "id": null, + "parameterSlots": 2, + "returnSlots": 2 + }, + "access_calldata_tail_t_struct$_Transaction_$1292_calldata_ptr": { + "entryPoint": 7885, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "calldata_array_index_range_access_t_bytes_calldata_ptr": { + "entryPoint": 8205, + "id": null, + "parameterSlots": 4, + "returnSlots": 2 + }, + "checked_add_t_uint256": { + "entryPoint": 8247, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "checked_sub_t_uint256": { + "entryPoint": 8414, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "increment_t_uint256": { + "entryPoint": 8149, + "id": null, + "parameterSlots": 1, + "returnSlots": 1 + }, + "panic_error_0x11": { + "entryPoint": 8102, + "id": null, + "parameterSlots": 0, + "returnSlots": 0 + }, + "panic_error_0x32": { + "entryPoint": 7719, + "id": null, + "parameterSlots": 0, + "returnSlots": 0 + }, + "panic_error_0x41": { + "entryPoint": 6840, + "id": null, + "parameterSlots": 0, + "returnSlots": 0 + }, + "validator_revert_bytes4": { + "entryPoint": 6226, + "id": null, + "parameterSlots": 1, + "returnSlots": 0 + } + }, + "generatedSources": [ + { + "ast": { + "nodeType": "YulBlock", + "src": "0:20962:22", + "statements": [ + { + "nodeType": "YulBlock", + "src": "6:3:22", + "statements": [] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "58:133:22", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "169:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "178:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "181:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "171:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "171:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "171:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "81:5:22" + }, + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "92:5:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "99:66:22", + "type": "", + "value": "0xffffffff00000000000000000000000000000000000000000000000000000000" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "88:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "88:78:22" + } + ], + "functionName": { + "name": "eq", + "nodeType": "YulIdentifier", + "src": "78:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "78:89:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "71:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "71:97:22" + }, + "nodeType": "YulIf", + "src": "68:117:22" + } + ] + }, + "name": "validator_revert_bytes4", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "47:5:22", + "type": "" + } + ], + "src": "14:177:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "265:176:22", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "311:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "320:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "323:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "313:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "313:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "313:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "286:7:22" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "295:9:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "282:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "282:23:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "307:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "278:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "278:32:22" + }, + "nodeType": "YulIf", + "src": "275:52:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "336:36:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "362:9:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "349:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "349:23:22" + }, + "variables": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "340:5:22", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "405:5:22" + } + ], + "functionName": { + "name": "validator_revert_bytes4", + "nodeType": "YulIdentifier", + "src": "381:23:22" + }, + "nodeType": "YulFunctionCall", + "src": "381:30:22" + }, + "nodeType": "YulExpressionStatement", + "src": "381:30:22" + }, + { + "nodeType": "YulAssignment", + "src": "420:15:22", + "value": { + "name": "value", + "nodeType": "YulIdentifier", + "src": "430:5:22" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "420:6:22" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_bytes4", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "231:9:22", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "242:7:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "254:6:22", + "type": "" + } + ], + "src": "196:245:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "541:92:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "551:26:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "563:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "574:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "559:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "559:18:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "551:4:22" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "593:9:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "618:6:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "611:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "611:14:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "604:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "604:22:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "586:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "586:41:22" + }, + "nodeType": "YulExpressionStatement", + "src": "586:41:22" + } + ] + }, + "name": "abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "510:9:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "521:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "532:4:22", + "type": "" + } + ], + "src": "446:187:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "710:275:22", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "759:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "768:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "771:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "761:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "761:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "761:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "738:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "746:4:22", + "type": "", + "value": "0x1f" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "734:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "734:17:22" + }, + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "753:3:22" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "730:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "730:27:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "723:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "723:35:22" + }, + "nodeType": "YulIf", + "src": "720:55:22" + }, + { + "nodeType": "YulAssignment", + "src": "784:30:22", + "value": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "807:6:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "794:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "794:20:22" + }, + "variableNames": [ + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "784:6:22" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "857:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "866:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "869:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "859:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "859:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "859:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "829:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "837:18:22", + "type": "", + "value": "0xffffffffffffffff" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "826:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "826:30:22" + }, + "nodeType": "YulIf", + "src": "823:50:22" + }, + { + "nodeType": "YulAssignment", + "src": "882:29:22", + "value": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "898:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "906:4:22", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "894:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "894:17:22" + }, + "variableNames": [ + { + "name": "arrayPos", + "nodeType": "YulIdentifier", + "src": "882:8:22" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "963:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "972:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "975:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "965:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "965:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "965:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "934:6:22" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "942:6:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "930:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "930:19:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "951:4:22", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "926:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "926:30:22" + }, + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "958:3:22" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "923:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "923:39:22" + }, + "nodeType": "YulIf", + "src": "920:59:22" + } + ] + }, + "name": "abi_decode_bytes_calldata", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "673:6:22", + "type": "" + }, + { + "name": "end", + "nodeType": "YulTypedName", + "src": "681:3:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "arrayPos", + "nodeType": "YulTypedName", + "src": "689:8:22", + "type": "" + }, + { + "name": "length", + "nodeType": "YulTypedName", + "src": "699:6:22", + "type": "" + } + ], + "src": "638:347:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1096:371:22", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "1142:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1151:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1154:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "1144:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "1144:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "1144:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "1117:7:22" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1126:9:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "1113:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "1113:23:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1138:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "1109:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "1109:32:22" + }, + "nodeType": "YulIf", + "src": "1106:52:22" + }, + { + "nodeType": "YulAssignment", + "src": "1167:33:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1190:9:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "1177:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "1177:23:22" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "1167:6:22" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "1209:46:22", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1240:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1251:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1236:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "1236:18:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "1223:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "1223:32:22" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "1213:6:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1298:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1307:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1310:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "1300:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "1300:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "1300:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "1270:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1278:18:22", + "type": "", + "value": "0xffffffffffffffff" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "1267:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "1267:30:22" + }, + "nodeType": "YulIf", + "src": "1264:50:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "1323:84:22", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1379:9:22" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "1390:6:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1375:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "1375:22:22" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "1399:7:22" + } + ], + "functionName": { + "name": "abi_decode_bytes_calldata", + "nodeType": "YulIdentifier", + "src": "1349:25:22" + }, + "nodeType": "YulFunctionCall", + "src": "1349:58:22" + }, + "variables": [ + { + "name": "value1_1", + "nodeType": "YulTypedName", + "src": "1327:8:22", + "type": "" + }, + { + "name": "value2_1", + "nodeType": "YulTypedName", + "src": "1337:8:22", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "1416:18:22", + "value": { + "name": "value1_1", + "nodeType": "YulIdentifier", + "src": "1426:8:22" + }, + "variableNames": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "1416:6:22" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "1443:18:22", + "value": { + "name": "value2_1", + "nodeType": "YulIdentifier", + "src": "1453:8:22" + }, + "variableNames": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "1443:6:22" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_bytes32t_bytes_calldata_ptr", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "1046:9:22", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "1057:7:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "1069:6:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "1077:6:22", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "1085:6:22", + "type": "" + } + ], + "src": "990:477:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1571:149:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "1581:26:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1593:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1604:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1589:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "1589:18:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "1581:4:22" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1623:9:22" + }, + { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "1638:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1646:66:22", + "type": "", + "value": "0xffffffff00000000000000000000000000000000000000000000000000000000" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "1634:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "1634:79:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "1616:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "1616:98:22" + }, + "nodeType": "YulExpressionStatement", + "src": "1616:98:22" + } + ] + }, + "name": "abi_encode_tuple_t_bytes4__to_t_bytes4__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "1540:9:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "1551:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "1562:4:22", + "type": "" + } + ], + "src": "1472:248:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1850:592:22", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "1896:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1905:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1908:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "1898:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "1898:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "1898:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "1871:7:22" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1880:9:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "1867:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "1867:23:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1892:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "1863:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "1863:32:22" + }, + "nodeType": "YulIf", + "src": "1860:52:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "1921:37:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1948:9:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "1935:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "1935:23:22" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "1925:6:22", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "1967:28:22", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1977:18:22", + "type": "", + "value": "0xffffffffffffffff" + }, + "variables": [ + { + "name": "_1", + "nodeType": "YulTypedName", + "src": "1971:2:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "2022:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2031:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2034:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "2024:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "2024:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "2024:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "2010:6:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "2018:2:22" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "2007:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "2007:14:22" + }, + "nodeType": "YulIf", + "src": "2004:34:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "2047:84:22", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2103:9:22" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "2114:6:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2099:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "2099:22:22" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "2123:7:22" + } + ], + "functionName": { + "name": "abi_decode_bytes_calldata", + "nodeType": "YulIdentifier", + "src": "2073:25:22" + }, + "nodeType": "YulFunctionCall", + "src": "2073:58:22" + }, + "variables": [ + { + "name": "value0_1", + "nodeType": "YulTypedName", + "src": "2051:8:22", + "type": "" + }, + { + "name": "value1_1", + "nodeType": "YulTypedName", + "src": "2061:8:22", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "2140:18:22", + "value": { + "name": "value0_1", + "nodeType": "YulIdentifier", + "src": "2150:8:22" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "2140:6:22" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "2167:18:22", + "value": { + "name": "value1_1", + "nodeType": "YulIdentifier", + "src": "2177:8:22" + }, + "variableNames": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "2167:6:22" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "2194:48:22", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2227:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2238:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2223:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "2223:18:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "2210:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "2210:32:22" + }, + "variables": [ + { + "name": "offset_1", + "nodeType": "YulTypedName", + "src": "2198:8:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "2271:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2280:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2283:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "2273:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "2273:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "2273:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "offset_1", + "nodeType": "YulIdentifier", + "src": "2257:8:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "2267:2:22" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "2254:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "2254:16:22" + }, + "nodeType": "YulIf", + "src": "2251:36:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "2296:86:22", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2352:9:22" + }, + { + "name": "offset_1", + "nodeType": "YulIdentifier", + "src": "2363:8:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2348:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "2348:24:22" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "2374:7:22" + } + ], + "functionName": { + "name": "abi_decode_bytes_calldata", + "nodeType": "YulIdentifier", + "src": "2322:25:22" + }, + "nodeType": "YulFunctionCall", + "src": "2322:60:22" + }, + "variables": [ + { + "name": "value2_1", + "nodeType": "YulTypedName", + "src": "2300:8:22", + "type": "" + }, + { + "name": "value3_1", + "nodeType": "YulTypedName", + "src": "2310:8:22", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "2391:18:22", + "value": { + "name": "value2_1", + "nodeType": "YulIdentifier", + "src": "2401:8:22" + }, + "variableNames": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "2391:6:22" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "2418:18:22", + "value": { + "name": "value3_1", + "nodeType": "YulIdentifier", + "src": "2428:8:22" + }, + "variableNames": [ + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "2418:6:22" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_bytes_calldata_ptrt_bytes_calldata_ptr", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "1792:9:22", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "1803:7:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "1815:6:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "1823:6:22", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "1831:6:22", + "type": "" + }, + { + "name": "value3", + "nodeType": "YulTypedName", + "src": "1839:6:22", + "type": "" + } + ], + "src": "1725:717:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "2517:110:22", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "2563:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2572:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2575:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "2565:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "2565:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "2565:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "2538:7:22" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2547:9:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "2534:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "2534:23:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2559:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "2530:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "2530:32:22" + }, + "nodeType": "YulIf", + "src": "2527:52:22" + }, + { + "nodeType": "YulAssignment", + "src": "2588:33:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2611:9:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "2598:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "2598:23:22" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "2588:6:22" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_bytes32", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "2483:9:22", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "2494:7:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "2506:6:22", + "type": "" + } + ], + "src": "2447:180:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "2733:76:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "2743:26:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2755:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2766:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2751:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "2751:18:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "2743:4:22" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2785:9:22" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "2796:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "2778:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "2778:25:22" + }, + "nodeType": "YulExpressionStatement", + "src": "2778:25:22" + } + ] + }, + "name": "abi_encode_tuple_t_bytes32__to_t_bytes32__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "2702:9:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "2713:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "2724:4:22", + "type": "" + } + ], + "src": "2632:177:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "2918:283:22", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "2967:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2976:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2979:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "2969:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "2969:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "2969:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "2946:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2954:4:22", + "type": "", + "value": "0x1f" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2942:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "2942:17:22" + }, + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "2961:3:22" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "2938:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "2938:27:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "2931:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "2931:35:22" + }, + "nodeType": "YulIf", + "src": "2928:55:22" + }, + { + "nodeType": "YulAssignment", + "src": "2992:30:22", + "value": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "3015:6:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "3002:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "3002:20:22" + }, + "variableNames": [ + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "2992:6:22" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "3065:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3074:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3077:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "3067:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "3067:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "3067:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "3037:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3045:18:22", + "type": "", + "value": "0xffffffffffffffff" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "3034:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "3034:30:22" + }, + "nodeType": "YulIf", + "src": "3031:50:22" + }, + { + "nodeType": "YulAssignment", + "src": "3090:29:22", + "value": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "3106:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3114:4:22", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "3102:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "3102:17:22" + }, + "variableNames": [ + { + "name": "arrayPos", + "nodeType": "YulIdentifier", + "src": "3090:8:22" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "3179:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3188:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3191:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "3181:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "3181:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "3181:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "3142:6:22" + }, + { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3154:1:22", + "type": "", + "value": "5" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "3157:6:22" + } + ], + "functionName": { + "name": "shl", + "nodeType": "YulIdentifier", + "src": "3150:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "3150:14:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "3138:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "3138:27:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3167:4:22", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "3134:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "3134:38:22" + }, + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "3174:3:22" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "3131:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "3131:47:22" + }, + "nodeType": "YulIf", + "src": "3128:67:22" + } + ] + }, + "name": "abi_decode_array_struct_Transaction_calldata_dyn_calldata", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "2881:6:22", + "type": "" + }, + { + "name": "end", + "nodeType": "YulTypedName", + "src": "2889:3:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "arrayPos", + "nodeType": "YulTypedName", + "src": "2897:8:22", + "type": "" + }, + { + "name": "length", + "nodeType": "YulTypedName", + "src": "2907:6:22", + "type": "" + } + ], + "src": "2814:387:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "3342:352:22", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "3388:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3397:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3400:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "3390:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "3390:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "3390:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "3363:7:22" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "3372:9:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "3359:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "3359:23:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3384:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "3355:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "3355:32:22" + }, + "nodeType": "YulIf", + "src": "3352:52:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "3413:37:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "3440:9:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "3427:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "3427:23:22" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "3417:6:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "3493:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3502:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3505:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "3495:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "3495:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "3495:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "3465:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3473:18:22", + "type": "", + "value": "0xffffffffffffffff" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "3462:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "3462:30:22" + }, + "nodeType": "YulIf", + "src": "3459:50:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "3518:116:22", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "3606:9:22" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "3617:6:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "3602:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "3602:22:22" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "3626:7:22" + } + ], + "functionName": { + "name": "abi_decode_array_struct_Transaction_calldata_dyn_calldata", + "nodeType": "YulIdentifier", + "src": "3544:57:22" + }, + "nodeType": "YulFunctionCall", + "src": "3544:90:22" + }, + "variables": [ + { + "name": "value0_1", + "nodeType": "YulTypedName", + "src": "3522:8:22", + "type": "" + }, + { + "name": "value1_1", + "nodeType": "YulTypedName", + "src": "3532:8:22", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "3643:18:22", + "value": { + "name": "value0_1", + "nodeType": "YulIdentifier", + "src": "3653:8:22" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "3643:6:22" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "3670:18:22", + "value": { + "name": "value1_1", + "nodeType": "YulIdentifier", + "src": "3680:8:22" + }, + "variableNames": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "3670:6:22" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "3300:9:22", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "3311:7:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "3323:6:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "3331:6:22", + "type": "" + } + ], + "src": "3206:488:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "3888:675:22", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "3934:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3943:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3946:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "3936:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "3936:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "3936:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "3909:7:22" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "3918:9:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "3905:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "3905:23:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3930:2:22", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "3901:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "3901:32:22" + }, + "nodeType": "YulIf", + "src": "3898:52:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "3959:37:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "3986:9:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "3973:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "3973:23:22" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "3963:6:22", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "4005:28:22", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4015:18:22", + "type": "", + "value": "0xffffffffffffffff" + }, + "variables": [ + { + "name": "_1", + "nodeType": "YulTypedName", + "src": "4009:2:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "4060:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4069:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4072:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "4062:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "4062:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "4062:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "4048:6:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "4056:2:22" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "4045:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "4045:14:22" + }, + "nodeType": "YulIf", + "src": "4042:34:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "4085:116:22", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4173:9:22" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "4184:6:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4169:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "4169:22:22" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "4193:7:22" + } + ], + "functionName": { + "name": "abi_decode_array_struct_Transaction_calldata_dyn_calldata", + "nodeType": "YulIdentifier", + "src": "4111:57:22" + }, + "nodeType": "YulFunctionCall", + "src": "4111:90:22" + }, + "variables": [ + { + "name": "value0_1", + "nodeType": "YulTypedName", + "src": "4089:8:22", + "type": "" + }, + { + "name": "value1_1", + "nodeType": "YulTypedName", + "src": "4099:8:22", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "4210:18:22", + "value": { + "name": "value0_1", + "nodeType": "YulIdentifier", + "src": "4220:8:22" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "4210:6:22" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "4237:18:22", + "value": { + "name": "value1_1", + "nodeType": "YulIdentifier", + "src": "4247:8:22" + }, + "variableNames": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "4237:6:22" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "4264:42:22", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4291:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4302:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4287:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "4287:18:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "4274:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "4274:32:22" + }, + "variableNames": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "4264:6:22" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "4315:48:22", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4348:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4359:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4344:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "4344:18:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "4331:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "4331:32:22" + }, + "variables": [ + { + "name": "offset_1", + "nodeType": "YulTypedName", + "src": "4319:8:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "4392:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4401:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4404:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "4394:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "4394:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "4394:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "offset_1", + "nodeType": "YulIdentifier", + "src": "4378:8:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "4388:2:22" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "4375:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "4375:16:22" + }, + "nodeType": "YulIf", + "src": "4372:36:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "4417:86:22", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4473:9:22" + }, + { + "name": "offset_1", + "nodeType": "YulIdentifier", + "src": "4484:8:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4469:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "4469:24:22" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "4495:7:22" + } + ], + "functionName": { + "name": "abi_decode_bytes_calldata", + "nodeType": "YulIdentifier", + "src": "4443:25:22" + }, + "nodeType": "YulFunctionCall", + "src": "4443:60:22" + }, + "variables": [ + { + "name": "value3_1", + "nodeType": "YulTypedName", + "src": "4421:8:22", + "type": "" + }, + { + "name": "value4_1", + "nodeType": "YulTypedName", + "src": "4431:8:22", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "4512:18:22", + "value": { + "name": "value3_1", + "nodeType": "YulIdentifier", + "src": "4522:8:22" + }, + "variableNames": [ + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "4512:6:22" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "4539:18:22", + "value": { + "name": "value4_1", + "nodeType": "YulIdentifier", + "src": "4549:8:22" + }, + "variableNames": [ + { + "name": "value4", + "nodeType": "YulIdentifier", + "src": "4539:6:22" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptrt_uint256t_bytes_calldata_ptr", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "3822:9:22", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "3833:7:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "3845:6:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "3853:6:22", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "3861:6:22", + "type": "" + }, + { + "name": "value3", + "nodeType": "YulTypedName", + "src": "3869:6:22", + "type": "" + }, + { + "name": "value4", + "nodeType": "YulTypedName", + "src": "3877:6:22", + "type": "" + } + ], + "src": "3699:864:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "4781:250:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "4791:27:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4803:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4814:3:22", + "type": "", + "value": "160" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4799:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "4799:19:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "4791:4:22" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4834:9:22" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "4845:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "4827:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "4827:25:22" + }, + "nodeType": "YulExpressionStatement", + "src": "4827:25:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4872:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4883:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4868:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "4868:18:22" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "4888:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "4861:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "4861:34:22" + }, + "nodeType": "YulExpressionStatement", + "src": "4861:34:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4915:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4926:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4911:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "4911:18:22" + }, + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "4931:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "4904:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "4904:34:22" + }, + "nodeType": "YulExpressionStatement", + "src": "4904:34:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "4958:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4969:2:22", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4954:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "4954:18:22" + }, + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "4974:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "4947:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "4947:34:22" + }, + "nodeType": "YulExpressionStatement", + "src": "4947:34:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5001:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5012:3:22", + "type": "", + "value": "128" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4997:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "4997:19:22" + }, + { + "name": "value4", + "nodeType": "YulIdentifier", + "src": "5018:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "4990:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "4990:35:22" + }, + "nodeType": "YulExpressionStatement", + "src": "4990:35:22" + } + ] + }, + "name": "abi_encode_tuple_t_uint256_t_uint256_t_bytes32_t_bytes32_t_uint256__to_t_uint256_t_uint256_t_bytes32_t_bytes32_t_uint256__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "4718:9:22", + "type": "" + }, + { + "name": "value4", + "nodeType": "YulTypedName", + "src": "4729:6:22", + "type": "" + }, + { + "name": "value3", + "nodeType": "YulTypedName", + "src": "4737:6:22", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "4745:6:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "4753:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "4761:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "4772:4:22", + "type": "" + } + ], + "src": "4568:463:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "5106:110:22", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "5152:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5161:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5164:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "5154:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "5154:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "5154:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "5127:7:22" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5136:9:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "5123:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "5123:23:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5148:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "5119:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "5119:32:22" + }, + "nodeType": "YulIf", + "src": "5116:52:22" + }, + { + "nodeType": "YulAssignment", + "src": "5177:33:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5200:9:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "5187:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "5187:23:22" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "5177:6:22" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_uint256", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "5072:9:22", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "5083:7:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "5095:6:22", + "type": "" + } + ], + "src": "5036:180:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "5322:76:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "5332:26:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5344:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5355:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "5340:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "5340:18:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "5332:4:22" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5374:9:22" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "5385:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "5367:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "5367:25:22" + }, + "nodeType": "YulExpressionStatement", + "src": "5367:25:22" + } + ] + }, + "name": "abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "5291:9:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "5302:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "5313:4:22", + "type": "" + } + ], + "src": "5221:177:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "5435:152:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5452:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5455:77:22", + "type": "", + "value": "35408467139433450592217433187231851964531694900788300625387963629091585785856" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "5445:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "5445:88:22" + }, + "nodeType": "YulExpressionStatement", + "src": "5445:88:22" + }, + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5549:1:22", + "type": "", + "value": "4" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5552:4:22", + "type": "", + "value": "0x41" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "5542:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "5542:15:22" + }, + "nodeType": "YulExpressionStatement", + "src": "5542:15:22" + }, + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5573:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5576:4:22", + "type": "", + "value": "0x24" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "5566:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "5566:15:22" + }, + "nodeType": "YulExpressionStatement", + "src": "5566:15:22" + } + ] + }, + "name": "panic_error_0x41", + "nodeType": "YulFunctionDefinition", + "src": "5403:184:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "5671:901:22", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "5717:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5726:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5729:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "5719:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "5719:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "5719:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "5692:7:22" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5701:9:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "5688:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "5688:23:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5713:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "5684:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "5684:32:22" + }, + "nodeType": "YulIf", + "src": "5681:52:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "5742:37:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5769:9:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "5756:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "5756:23:22" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "5746:6:22", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "5788:28:22", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5798:18:22", + "type": "", + "value": "0xffffffffffffffff" + }, + "variables": [ + { + "name": "_1", + "nodeType": "YulTypedName", + "src": "5792:2:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "5843:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5852:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5855:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "5845:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "5845:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "5845:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "5831:6:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "5839:2:22" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "5828:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "5828:14:22" + }, + "nodeType": "YulIf", + "src": "5825:34:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "5868:32:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "5882:9:22" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "5893:6:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "5878:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "5878:22:22" + }, + "variables": [ + { + "name": "_2", + "nodeType": "YulTypedName", + "src": "5872:2:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "5948:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5957:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5960:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "5950:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "5950:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "5950:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "5927:2:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "5931:4:22", + "type": "", + "value": "0x1f" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "5923:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "5923:13:22" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "5938:7:22" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "5919:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "5919:27:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "5912:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "5912:35:22" + }, + "nodeType": "YulIf", + "src": "5909:55:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "5973:26:22", + "value": { + "arguments": [ + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "5996:2:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "5983:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "5983:16:22" + }, + "variables": [ + { + "name": "_3", + "nodeType": "YulTypedName", + "src": "5977:2:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "6022:22:22", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "panic_error_0x41", + "nodeType": "YulIdentifier", + "src": "6024:16:22" + }, + "nodeType": "YulFunctionCall", + "src": "6024:18:22" + }, + "nodeType": "YulExpressionStatement", + "src": "6024:18:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "_3", + "nodeType": "YulIdentifier", + "src": "6014:2:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "6018:2:22" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "6011:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "6011:10:22" + }, + "nodeType": "YulIf", + "src": "6008:36:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "6053:76:22", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6063:66:22", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0" + }, + "variables": [ + { + "name": "_4", + "nodeType": "YulTypedName", + "src": "6057:2:22", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "6138:23:22", + "value": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6158:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "6152:5:22" + }, + "nodeType": "YulFunctionCall", + "src": "6152:9:22" + }, + "variables": [ + { + "name": "memPtr", + "nodeType": "YulTypedName", + "src": "6142:6:22", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "6170:71:22", + "value": { + "arguments": [ + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "6192:6:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "_3", + "nodeType": "YulIdentifier", + "src": "6216:2:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6220:4:22", + "type": "", + "value": "0x1f" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6212:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "6212:13:22" + }, + { + "name": "_4", + "nodeType": "YulIdentifier", + "src": "6227:2:22" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "6208:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "6208:22:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6232:2:22", + "type": "", + "value": "63" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6204:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "6204:31:22" + }, + { + "name": "_4", + "nodeType": "YulIdentifier", + "src": "6237:2:22" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "6200:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "6200:40:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6188:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "6188:53:22" + }, + "variables": [ + { + "name": "newFreePtr", + "nodeType": "YulTypedName", + "src": "6174:10:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "6300:22:22", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "panic_error_0x41", + "nodeType": "YulIdentifier", + "src": "6302:16:22" + }, + "nodeType": "YulFunctionCall", + "src": "6302:18:22" + }, + "nodeType": "YulExpressionStatement", + "src": "6302:18:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "newFreePtr", + "nodeType": "YulIdentifier", + "src": "6259:10:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "6271:2:22" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "6256:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "6256:18:22" + }, + { + "arguments": [ + { + "name": "newFreePtr", + "nodeType": "YulIdentifier", + "src": "6279:10:22" + }, + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "6291:6:22" + } + ], + "functionName": { + "name": "lt", + "nodeType": "YulIdentifier", + "src": "6276:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "6276:22:22" + } + ], + "functionName": { + "name": "or", + "nodeType": "YulIdentifier", + "src": "6253:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "6253:46:22" + }, + "nodeType": "YulIf", + "src": "6250:72:22" + }, + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6338:2:22", + "type": "", + "value": "64" + }, + { + "name": "newFreePtr", + "nodeType": "YulIdentifier", + "src": "6342:10:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "6331:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "6331:22:22" + }, + "nodeType": "YulExpressionStatement", + "src": "6331:22:22" + }, + { + "expression": { + "arguments": [ + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "6369:6:22" + }, + { + "name": "_3", + "nodeType": "YulIdentifier", + "src": "6377:2:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "6362:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "6362:18:22" + }, + "nodeType": "YulExpressionStatement", + "src": "6362:18:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "6426:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6435:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6438:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "6428:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "6428:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "6428:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "6403:2:22" + }, + { + "name": "_3", + "nodeType": "YulIdentifier", + "src": "6407:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6399:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "6399:11:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6412:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6395:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "6395:20:22" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "6417:7:22" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "6392:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "6392:33:22" + }, + "nodeType": "YulIf", + "src": "6389:53:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "6468:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6476:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6464:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "6464:15:22" + }, + { + "arguments": [ + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "6485:2:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6489:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6481:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "6481:11:22" + }, + { + "name": "_3", + "nodeType": "YulIdentifier", + "src": "6494:2:22" + } + ], + "functionName": { + "name": "calldatacopy", + "nodeType": "YulIdentifier", + "src": "6451:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "6451:46:22" + }, + "nodeType": "YulExpressionStatement", + "src": "6451:46:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "6521:6:22" + }, + { + "name": "_3", + "nodeType": "YulIdentifier", + "src": "6529:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6517:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "6517:15:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6534:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6513:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "6513:24:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6539:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "6506:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "6506:35:22" + }, + "nodeType": "YulExpressionStatement", + "src": "6506:35:22" + }, + { + "nodeType": "YulAssignment", + "src": "6550:16:22", + "value": { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "6560:6:22" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "6550:6:22" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_bytes_memory_ptr", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "5637:9:22", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "5648:7:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "5660:6:22", + "type": "" + } + ], + "src": "5592:980:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "6678:125:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "6688:26:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "6700:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6711:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "6696:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "6696:18:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "6688:4:22" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "6730:9:22" + }, + { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "6745:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "6753:42:22", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffff" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "6741:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "6741:55:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "6723:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "6723:74:22" + }, + "nodeType": "YulExpressionStatement", + "src": "6723:74:22" + } + ] + }, + "name": "abi_encode_tuple_t_address__to_t_address__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "6647:9:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "6658:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "6669:4:22", + "type": "" + } + ], + "src": "6577:226:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "6955:124:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "6978:3:22" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "6983:6:22" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "6991:6:22" + } + ], + "functionName": { + "name": "calldatacopy", + "nodeType": "YulIdentifier", + "src": "6965:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "6965:33:22" + }, + "nodeType": "YulExpressionStatement", + "src": "6965:33:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "7007:26:22", + "value": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "7021:3:22" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "7026:6:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7017:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "7017:16:22" + }, + "variables": [ + { + "name": "_1", + "nodeType": "YulTypedName", + "src": "7011:2:22", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "7049:2:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7053:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "7042:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "7042:13:22" + }, + "nodeType": "YulExpressionStatement", + "src": "7042:13:22" + }, + { + "nodeType": "YulAssignment", + "src": "7064:9:22", + "value": { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "7071:2:22" + }, + "variableNames": [ + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "7064:3:22" + } + ] + } + ] + }, + "name": "abi_encode_tuple_packed_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__nonPadded_inplace_fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "pos", + "nodeType": "YulTypedName", + "src": "6923:3:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "6928:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "6936:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "end", + "nodeType": "YulTypedName", + "src": "6947:3:22", + "type": "" + } + ], + "src": "6808:271:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "7213:198:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "7223:26:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "7235:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7246:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7231:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "7231:18:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "7223:4:22" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "7258:52:22", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7268:42:22", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffff" + }, + "variables": [ + { + "name": "_1", + "nodeType": "YulTypedName", + "src": "7262:2:22", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "7326:9:22" + }, + { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "7341:6:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "7349:2:22" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "7337:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "7337:15:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "7319:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "7319:34:22" + }, + "nodeType": "YulExpressionStatement", + "src": "7319:34:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "7373:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7384:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7369:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "7369:18:22" + }, + { + "arguments": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "7393:6:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "7401:2:22" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "7389:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "7389:15:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "7362:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "7362:43:22" + }, + "nodeType": "YulExpressionStatement", + "src": "7362:43:22" + } + ] + }, + "name": "abi_encode_tuple_t_address_t_address__to_t_address_t_address__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "7174:9:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "7185:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "7193:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "7204:4:22", + "type": "" + } + ], + "src": "7084:327:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "7462:114:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "7472:29:22", + "value": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "7494:6:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "7481:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "7481:20:22" + }, + "variableNames": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "7472:5:22" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "7554:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7563:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7566:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "7556:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "7556:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "7556:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "7523:5:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "7544:5:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "7537:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "7537:13:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "7530:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "7530:21:22" + } + ], + "functionName": { + "name": "eq", + "nodeType": "YulIdentifier", + "src": "7520:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "7520:32:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "7513:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "7513:40:22" + }, + "nodeType": "YulIf", + "src": "7510:60:22" + } + ] + }, + "name": "abi_decode_bool", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "7441:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "7452:5:22", + "type": "" + } + ], + "src": "7416:160:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "7630:147:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "7640:29:22", + "value": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "7662:6:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "7649:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "7649:20:22" + }, + "variableNames": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "7640:5:22" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "7755:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7764:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7767:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "7757:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "7757:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "7757:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "7691:5:22" + }, + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "7702:5:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7709:42:22", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffff" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "7698:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "7698:54:22" + } + ], + "functionName": { + "name": "eq", + "nodeType": "YulIdentifier", + "src": "7688:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "7688:65:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "7681:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "7681:73:22" + }, + "nodeType": "YulIf", + "src": "7678:93:22" + } + ] + }, + "name": "abi_decode_address", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "7609:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "7620:5:22", + "type": "" + } + ], + "src": "7581:196:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "7848:259:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "7865:3:22" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "7870:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "7858:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "7858:19:22" + }, + "nodeType": "YulExpressionStatement", + "src": "7858:19:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "7903:3:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7908:4:22", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7899:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "7899:14:22" + }, + { + "name": "start", + "nodeType": "YulIdentifier", + "src": "7915:5:22" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "7922:6:22" + } + ], + "functionName": { + "name": "calldatacopy", + "nodeType": "YulIdentifier", + "src": "7886:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "7886:43:22" + }, + "nodeType": "YulExpressionStatement", + "src": "7886:43:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "7953:3:22" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "7958:6:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7949:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "7949:16:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7967:4:22", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7945:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "7945:27:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "7974:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "7938:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "7938:38:22" + }, + "nodeType": "YulExpressionStatement", + "src": "7938:38:22" + }, + { + "nodeType": "YulAssignment", + "src": "7985:116:22", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "8000:3:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "8013:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8021:2:22", + "type": "", + "value": "31" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "8009:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "8009:15:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8026:66:22", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "8005:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "8005:88:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7996:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "7996:98:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8096:4:22", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "7992:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "7992:109:22" + }, + "variableNames": [ + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "7985:3:22" + } + ] + } + ] + }, + "name": "abi_encode_bytes_calldata", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "start", + "nodeType": "YulTypedName", + "src": "7817:5:22", + "type": "" + }, + { + "name": "length", + "nodeType": "YulTypedName", + "src": "7824:6:22", + "type": "" + }, + { + "name": "pos", + "nodeType": "YulTypedName", + "src": "7832:3:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "end", + "nodeType": "YulTypedName", + "src": "7840:3:22", + "type": "" + } + ], + "src": "7782:325:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "8210:1930:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "8227:3:22" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "8232:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "8220:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "8220:19:22" + }, + "nodeType": "YulExpressionStatement", + "src": "8220:19:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "8248:14:22", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8258:4:22", + "type": "", + "value": "0x20" + }, + "variables": [ + { + "name": "_1", + "nodeType": "YulTypedName", + "src": "8252:2:22", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "8271:31:22", + "value": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "8294:3:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "8299:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "8290:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "8290:12:22" + }, + "variables": [ + { + "name": "updated_pos", + "nodeType": "YulTypedName", + "src": "8275:11:22", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "8311:24:22", + "value": { + "name": "updated_pos", + "nodeType": "YulIdentifier", + "src": "8324:11:22" + }, + "variables": [ + { + "name": "pos_1", + "nodeType": "YulTypedName", + "src": "8315:5:22", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "8344:18:22", + "value": { + "name": "updated_pos", + "nodeType": "YulIdentifier", + "src": "8351:11:22" + }, + "variableNames": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "8344:3:22" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "8371:38:22", + "value": { + "arguments": [ + { + "name": "pos_1", + "nodeType": "YulIdentifier", + "src": "8387:5:22" + }, + { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8398:1:22", + "type": "", + "value": "5" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "8401:6:22" + } + ], + "functionName": { + "name": "shl", + "nodeType": "YulIdentifier", + "src": "8394:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "8394:14:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "8383:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "8383:26:22" + }, + "variables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "8375:4:22", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "8418:19:22", + "value": { + "name": "value", + "nodeType": "YulIdentifier", + "src": "8432:5:22" + }, + "variables": [ + { + "name": "srcPtr", + "nodeType": "YulTypedName", + "src": "8422:6:22", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "8446:10:22", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8455:1:22", + "type": "", + "value": "0" + }, + "variables": [ + { + "name": "i", + "nodeType": "YulTypedName", + "src": "8450:1:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "8514:1600:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "8535:3:22" + }, + { + "arguments": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "8544:4:22" + }, + { + "name": "pos_1", + "nodeType": "YulIdentifier", + "src": "8550:5:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "8540:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "8540:16:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "8528:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "8528:29:22" + }, + "nodeType": "YulExpressionStatement", + "src": "8528:29:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "8570:46:22", + "value": { + "arguments": [ + { + "name": "srcPtr", + "nodeType": "YulIdentifier", + "src": "8609:6:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "8596:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "8596:20:22" + }, + "variables": [ + { + "name": "rel_offset_of_tail", + "nodeType": "YulTypedName", + "src": "8574:18:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "8765:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8774:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8777:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "8767:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "8767:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "8767:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "rel_offset_of_tail", + "nodeType": "YulIdentifier", + "src": "8643:18:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "arguments": [], + "functionName": { + "name": "calldatasize", + "nodeType": "YulIdentifier", + "src": "8671:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "8671:14:22" + }, + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "8687:5:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "8667:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "8667:26:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8695:66:22", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff41" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "8663:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "8663:99:22" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "8639:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "8639:124:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "8632:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "8632:132:22" + }, + "nodeType": "YulIf", + "src": "8629:152:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "8794:45:22", + "value": { + "arguments": [ + { + "name": "rel_offset_of_tail", + "nodeType": "YulIdentifier", + "src": "8813:18:22" + }, + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "8833:5:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "8809:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "8809:30:22" + }, + "variables": [ + { + "name": "value_1", + "nodeType": "YulTypedName", + "src": "8798:7:22", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "8852:14:22", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8862:4:22", + "type": "", + "value": "0xc0" + }, + "variables": [ + { + "name": "_2", + "nodeType": "YulTypedName", + "src": "8856:2:22", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "8886:4:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "value_1", + "nodeType": "YulIdentifier", + "src": "8922:7:22" + } + ], + "functionName": { + "name": "abi_decode_bool", + "nodeType": "YulIdentifier", + "src": "8906:15:22" + }, + "nodeType": "YulFunctionCall", + "src": "8906:24:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "8899:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "8899:32:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "8892:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "8892:40:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "8879:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "8879:54:22" + }, + "nodeType": "YulExpressionStatement", + "src": "8879:54:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "8957:4:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "8963:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "8953:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "8953:13:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "value_1", + "nodeType": "YulIdentifier", + "src": "9002:7:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "9011:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "8998:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "8998:16:22" + } + ], + "functionName": { + "name": "abi_decode_bool", + "nodeType": "YulIdentifier", + "src": "8982:15:22" + }, + "nodeType": "YulFunctionCall", + "src": "8982:33:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "8975:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "8975:41:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "8968:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "8968:49:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "8946:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "8946:72:22" + }, + "nodeType": "YulExpressionStatement", + "src": "8946:72:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "9031:14:22", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9041:4:22", + "type": "", + "value": "0x40" + }, + "variables": [ + { + "name": "_3", + "nodeType": "YulTypedName", + "src": "9035:2:22", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "9069:4:22" + }, + { + "name": "_3", + "nodeType": "YulIdentifier", + "src": "9075:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9065:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "9065:13:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "name": "value_1", + "nodeType": "YulIdentifier", + "src": "9097:7:22" + }, + { + "name": "_3", + "nodeType": "YulIdentifier", + "src": "9106:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9093:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "9093:16:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "9080:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "9080:30:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "9058:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "9058:53:22" + }, + "nodeType": "YulExpressionStatement", + "src": "9058:53:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "9124:14:22", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9134:4:22", + "type": "", + "value": "0x60" + }, + "variables": [ + { + "name": "_4", + "nodeType": "YulTypedName", + "src": "9128:2:22", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "9162:4:22" + }, + { + "name": "_4", + "nodeType": "YulIdentifier", + "src": "9168:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9158:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "9158:13:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "value_1", + "nodeType": "YulIdentifier", + "src": "9200:7:22" + }, + { + "name": "_4", + "nodeType": "YulIdentifier", + "src": "9209:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9196:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "9196:16:22" + } + ], + "functionName": { + "name": "abi_decode_address", + "nodeType": "YulIdentifier", + "src": "9177:18:22" + }, + "nodeType": "YulFunctionCall", + "src": "9177:36:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9215:42:22", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffff" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "9173:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "9173:85:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "9151:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "9151:108:22" + }, + "nodeType": "YulExpressionStatement", + "src": "9151:108:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "9272:14:22", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9282:4:22", + "type": "", + "value": "0x80" + }, + "variables": [ + { + "name": "_5", + "nodeType": "YulTypedName", + "src": "9276:2:22", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "9310:4:22" + }, + { + "name": "_5", + "nodeType": "YulIdentifier", + "src": "9316:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9306:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "9306:13:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "name": "value_1", + "nodeType": "YulIdentifier", + "src": "9338:7:22" + }, + { + "name": "_5", + "nodeType": "YulIdentifier", + "src": "9347:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9334:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "9334:16:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "9321:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "9321:30:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "9299:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "9299:53:22" + }, + "nodeType": "YulExpressionStatement", + "src": "9299:53:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "9365:14:22", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9375:4:22", + "type": "", + "value": "0xa0" + }, + "variables": [ + { + "name": "_6", + "nodeType": "YulTypedName", + "src": "9369:2:22", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "9392:58:22", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "value_1", + "nodeType": "YulIdentifier", + "src": "9437:7:22" + }, + { + "name": "_6", + "nodeType": "YulIdentifier", + "src": "9446:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9433:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "9433:16:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "9420:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "9420:30:22" + }, + "variables": [ + { + "name": "rel_offset_of_tail_1", + "nodeType": "YulTypedName", + "src": "9396:20:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "9603:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9612:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9615:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "9605:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "9605:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "9605:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "rel_offset_of_tail_1", + "nodeType": "YulIdentifier", + "src": "9477:20:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "arguments": [], + "functionName": { + "name": "calldatasize", + "nodeType": "YulIdentifier", + "src": "9507:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "9507:14:22" + }, + { + "name": "value_1", + "nodeType": "YulIdentifier", + "src": "9523:7:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "9503:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "9503:28:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9533:66:22", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9499:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "9499:101:22" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "9473:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "9473:128:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "9466:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "9466:136:22" + }, + "nodeType": "YulIf", + "src": "9463:156:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "9632:49:22", + "value": { + "arguments": [ + { + "name": "rel_offset_of_tail_1", + "nodeType": "YulIdentifier", + "src": "9651:20:22" + }, + { + "name": "value_1", + "nodeType": "YulIdentifier", + "src": "9673:7:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9647:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "9647:34:22" + }, + "variables": [ + { + "name": "value_2", + "nodeType": "YulTypedName", + "src": "9636:7:22", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "9694:37:22", + "value": { + "arguments": [ + { + "name": "value_2", + "nodeType": "YulIdentifier", + "src": "9723:7:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "9710:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "9710:21:22" + }, + "variables": [ + { + "name": "length_1", + "nodeType": "YulTypedName", + "src": "9698:8:22", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "9744:31:22", + "value": { + "arguments": [ + { + "name": "value_2", + "nodeType": "YulIdentifier", + "src": "9763:7:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "9772:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9759:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "9759:16:22" + }, + "variables": [ + { + "name": "value_3", + "nodeType": "YulTypedName", + "src": "9748:7:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "9824:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9833:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9836:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "9826:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "9826:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "9826:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "length_1", + "nodeType": "YulIdentifier", + "src": "9794:8:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9804:18:22", + "type": "", + "value": "0xffffffffffffffff" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "9791:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "9791:32:22" + }, + "nodeType": "YulIf", + "src": "9788:52:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "9900:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9909:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "9912:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "9902:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "9902:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "9902:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "value_3", + "nodeType": "YulIdentifier", + "src": "9860:7:22" + }, + { + "arguments": [ + { + "arguments": [], + "functionName": { + "name": "calldatasize", + "nodeType": "YulIdentifier", + "src": "9873:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "9873:14:22" + }, + { + "name": "length_1", + "nodeType": "YulIdentifier", + "src": "9889:8:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "9869:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "9869:29:22" + } + ], + "functionName": { + "name": "sgt", + "nodeType": "YulIdentifier", + "src": "9856:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "9856:43:22" + }, + "nodeType": "YulIf", + "src": "9853:63:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "9940:4:22" + }, + { + "name": "_6", + "nodeType": "YulIdentifier", + "src": "9946:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "9936:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "9936:13:22" + }, + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "9951:2:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "9929:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "9929:25:22" + }, + "nodeType": "YulExpressionStatement", + "src": "9929:25:22" + }, + { + "nodeType": "YulAssignment", + "src": "9967:67:22", + "value": { + "arguments": [ + { + "name": "value_3", + "nodeType": "YulIdentifier", + "src": "10001:7:22" + }, + { + "name": "length_1", + "nodeType": "YulIdentifier", + "src": "10010:8:22" + }, + { + "arguments": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "10024:4:22" + }, + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "10030:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "10020:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "10020:13:22" + } + ], + "functionName": { + "name": "abi_encode_bytes_calldata", + "nodeType": "YulIdentifier", + "src": "9975:25:22" + }, + "nodeType": "YulFunctionCall", + "src": "9975:59:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "9967:4:22" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "10047:25:22", + "value": { + "arguments": [ + { + "name": "srcPtr", + "nodeType": "YulIdentifier", + "src": "10061:6:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "10069:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "10057:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "10057:15:22" + }, + "variableNames": [ + { + "name": "srcPtr", + "nodeType": "YulIdentifier", + "src": "10047:6:22" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "10085:19:22", + "value": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "10096:3:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "10101:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "10092:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "10092:12:22" + }, + "variableNames": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "10085:3:22" + } + ] + } + ] + }, + "condition": { + "arguments": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "8476:1:22" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "8479:6:22" + } + ], + "functionName": { + "name": "lt", + "nodeType": "YulIdentifier", + "src": "8473:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "8473:13:22" + }, + "nodeType": "YulForLoop", + "post": { + "nodeType": "YulBlock", + "src": "8487:18:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "8489:14:22", + "value": { + "arguments": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "8498:1:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "8501:1:22", + "type": "", + "value": "1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "8494:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "8494:9:22" + }, + "variableNames": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "8489:1:22" + } + ] + } + ] + }, + "pre": { + "nodeType": "YulBlock", + "src": "8469:3:22", + "statements": [] + }, + "src": "8465:1649:22" + }, + { + "nodeType": "YulAssignment", + "src": "10123:11:22", + "value": { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "10130:4:22" + }, + "variableNames": [ + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "10123:3:22" + } + ] + } + ] + }, + "name": "abi_encode_array_struct_Transaction_calldata_dyn_calldata", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "8179:5:22", + "type": "" + }, + { + "name": "length", + "nodeType": "YulTypedName", + "src": "8186:6:22", + "type": "" + }, + { + "name": "pos", + "nodeType": "YulTypedName", + "src": "8194:3:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "end", + "nodeType": "YulTypedName", + "src": "8202:3:22", + "type": "" + } + ], + "src": "8112:2028:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "10467:272:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "10484:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10495:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "10477:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "10477:21:22" + }, + "nodeType": "YulExpressionStatement", + "src": "10477:21:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "10518:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10529:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "10514:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "10514:18:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10534:1:22", + "type": "", + "value": "5" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "10507:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "10507:29:22" + }, + "nodeType": "YulExpressionStatement", + "src": "10507:29:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "10556:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10567:2:22", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "10552:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "10552:18:22" + }, + { + "hexValue": "73656c663a", + "kind": "string", + "nodeType": "YulLiteral", + "src": "10572:7:22", + "type": "", + "value": "self:" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "10545:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "10545:35:22" + }, + "nodeType": "YulExpressionStatement", + "src": "10545:35:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "10600:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10611:4:22", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "10596:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "10596:20:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10618:3:22", + "type": "", + "value": "128" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "10589:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "10589:33:22" + }, + "nodeType": "YulExpressionStatement", + "src": "10589:33:22" + }, + { + "nodeType": "YulAssignment", + "src": "10631:102:22", + "value": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "10697:6:22" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "10705:6:22" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "10717:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "10728:3:22", + "type": "", + "value": "128" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "10713:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "10713:19:22" + } + ], + "functionName": { + "name": "abi_encode_array_struct_Transaction_calldata_dyn_calldata", + "nodeType": "YulIdentifier", + "src": "10639:57:22" + }, + "nodeType": "YulFunctionCall", + "src": "10639:94:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "10631:4:22" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_stringliteral_bf9461da9f9c0123d3a54c61147a274d8fdb5d5c1e488665fb11b9edbbc32845_t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr__to_t_string_memory_ptr_t_array$_t_struct$_Transaction_$1292_memory_ptr_$dyn_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "10428:9:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "10439:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "10447:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "10458:4:22", + "type": "" + } + ], + "src": "10145:594:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "11066:273:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "11083:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11094:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "11076:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "11076:21:22" + }, + "nodeType": "YulExpressionStatement", + "src": "11076:21:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "11117:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11128:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "11113:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "11113:18:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11133:1:22", + "type": "", + "value": "6" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "11106:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "11106:29:22" + }, + "nodeType": "YulExpressionStatement", + "src": "11106:29:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "11155:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11166:2:22", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "11151:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "11151:18:22" + }, + { + "hexValue": "67756573743a", + "kind": "string", + "nodeType": "YulLiteral", + "src": "11171:8:22", + "type": "", + "value": "guest:" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "11144:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "11144:36:22" + }, + "nodeType": "YulExpressionStatement", + "src": "11144:36:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "11200:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11211:4:22", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "11196:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "11196:20:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11218:3:22", + "type": "", + "value": "128" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "11189:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "11189:33:22" + }, + "nodeType": "YulExpressionStatement", + "src": "11189:33:22" + }, + { + "nodeType": "YulAssignment", + "src": "11231:102:22", + "value": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "11297:6:22" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "11305:6:22" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "11317:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11328:3:22", + "type": "", + "value": "128" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "11313:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "11313:19:22" + } + ], + "functionName": { + "name": "abi_encode_array_struct_Transaction_calldata_dyn_calldata", + "nodeType": "YulIdentifier", + "src": "11239:57:22" + }, + "nodeType": "YulFunctionCall", + "src": "11239:94:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "11231:4:22" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_stringliteral_4dfa0bed92fb5c2df0b47ce555e6e6b89f746e856aa9783c634a4987edcbf682_t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr__to_t_string_memory_ptr_t_array$_t_struct$_Transaction_$1292_memory_ptr_$dyn_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "11027:9:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "11038:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "11046:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "11057:4:22", + "type": "" + } + ], + "src": "10744:595:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "11376:152:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11393:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11396:77:22", + "type": "", + "value": "35408467139433450592217433187231851964531694900788300625387963629091585785856" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "11386:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "11386:88:22" + }, + "nodeType": "YulExpressionStatement", + "src": "11386:88:22" + }, + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11490:1:22", + "type": "", + "value": "4" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11493:4:22", + "type": "", + "value": "0x32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "11483:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "11483:15:22" + }, + "nodeType": "YulExpressionStatement", + "src": "11483:15:22" + }, + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11514:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11517:4:22", + "type": "", + "value": "0x24" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "11507:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "11507:15:22" + }, + "nodeType": "YulExpressionStatement", + "src": "11507:15:22" + } + ] + }, + "name": "panic_error_0x32", + "nodeType": "YulFunctionDefinition", + "src": "11344:184:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "11632:149:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "11642:26:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "11654:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11665:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "11650:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "11650:18:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "11642:4:22" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "11684:9:22" + }, + { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "11699:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11707:66:22", + "type": "", + "value": "0xff00000000000000000000000000000000000000000000000000000000000000" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "11695:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "11695:79:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "11677:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "11677:98:22" + }, + "nodeType": "YulExpressionStatement", + "src": "11677:98:22" + } + ] + }, + "name": "abi_encode_tuple_t_bytes1__to_t_bytes1__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "11601:9:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "11612:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "11623:4:22", + "type": "" + } + ], + "src": "11533:248:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "11835:432:22", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "11845:26:22", + "value": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "11865:5:22" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "11859:5:22" + }, + "nodeType": "YulFunctionCall", + "src": "11859:12:22" + }, + "variables": [ + { + "name": "length", + "nodeType": "YulTypedName", + "src": "11849:6:22", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "11887:3:22" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "11892:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "11880:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "11880:19:22" + }, + "nodeType": "YulExpressionStatement", + "src": "11880:19:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "11908:10:22", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11917:1:22", + "type": "", + "value": "0" + }, + "variables": [ + { + "name": "i", + "nodeType": "YulTypedName", + "src": "11912:1:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "11979:110:22", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "11993:14:22", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12003:4:22", + "type": "", + "value": "0x20" + }, + "variables": [ + { + "name": "_1", + "nodeType": "YulTypedName", + "src": "11997:2:22", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "12035:3:22" + }, + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "12040:1:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12031:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "12031:11:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "12044:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12027:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "12027:20:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "12063:5:22" + }, + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "12070:1:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12059:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "12059:13:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "12074:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12055:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "12055:22:22" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "12049:5:22" + }, + "nodeType": "YulFunctionCall", + "src": "12049:29:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "12020:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "12020:59:22" + }, + "nodeType": "YulExpressionStatement", + "src": "12020:59:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "11938:1:22" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "11941:6:22" + } + ], + "functionName": { + "name": "lt", + "nodeType": "YulIdentifier", + "src": "11935:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "11935:13:22" + }, + "nodeType": "YulForLoop", + "post": { + "nodeType": "YulBlock", + "src": "11949:21:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "11951:17:22", + "value": { + "arguments": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "11960:1:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "11963:4:22", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "11956:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "11956:12:22" + }, + "variableNames": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "11951:1:22" + } + ] + } + ] + }, + "pre": { + "nodeType": "YulBlock", + "src": "11931:3:22", + "statements": [] + }, + "src": "11927:162:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "12113:3:22" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "12118:6:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12109:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "12109:16:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12127:4:22", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12105:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "12105:27:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12134:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "12098:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "12098:38:22" + }, + "nodeType": "YulExpressionStatement", + "src": "12098:38:22" + }, + { + "nodeType": "YulAssignment", + "src": "12145:116:22", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "12160:3:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "12173:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12181:2:22", + "type": "", + "value": "31" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12169:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "12169:15:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12186:66:22", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "12165:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "12165:88:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12156:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "12156:98:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12256:4:22", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12152:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "12152:109:22" + }, + "variableNames": [ + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "12145:3:22" + } + ] + } + ] + }, + "name": "abi_encode_bytes", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "11812:5:22", + "type": "" + }, + { + "name": "pos", + "nodeType": "YulTypedName", + "src": "11819:3:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "end", + "nodeType": "YulTypedName", + "src": "11827:3:22", + "type": "" + } + ], + "src": "11786:481:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "12391:98:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "12408:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12419:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "12401:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "12401:21:22" + }, + "nodeType": "YulExpressionStatement", + "src": "12401:21:22" + }, + { + "nodeType": "YulAssignment", + "src": "12431:52:22", + "value": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "12456:6:22" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "12468:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12479:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12464:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "12464:18:22" + } + ], + "functionName": { + "name": "abi_encode_bytes", + "nodeType": "YulIdentifier", + "src": "12439:16:22" + }, + "nodeType": "YulFunctionCall", + "src": "12439:44:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "12431:4:22" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_bytes_memory_ptr__to_t_bytes_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "12360:9:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "12371:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "12382:4:22", + "type": "" + } + ], + "src": "12272:217:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "12770:315:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "12787:3:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12792:66:22", + "type": "", + "value": "0x1901000000000000000000000000000000000000000000000000000000000000" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "12780:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "12780:79:22" + }, + "nodeType": "YulExpressionStatement", + "src": "12780:79:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "12879:3:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12884:1:22", + "type": "", + "value": "2" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12875:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "12875:11:22" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "12888:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "12868:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "12868:27:22" + }, + "nodeType": "YulExpressionStatement", + "src": "12868:27:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "12915:3:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12920:2:22", + "type": "", + "value": "34" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "12911:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "12911:12:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12933:2:22", + "type": "", + "value": "96" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "12937:6:22" + } + ], + "functionName": { + "name": "shl", + "nodeType": "YulIdentifier", + "src": "12929:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "12929:15:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "12946:66:22", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffff000000000000000000000000" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "12925:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "12925:88:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "12904:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "12904:110:22" + }, + "nodeType": "YulExpressionStatement", + "src": "12904:110:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "13034:3:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13039:2:22", + "type": "", + "value": "54" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "13030:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "13030:12:22" + }, + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "13044:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "13023:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "13023:28:22" + }, + "nodeType": "YulExpressionStatement", + "src": "13023:28:22" + }, + { + "nodeType": "YulAssignment", + "src": "13060:19:22", + "value": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "13071:3:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13076:2:22", + "type": "", + "value": "86" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "13067:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "13067:12:22" + }, + "variableNames": [ + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "13060:3:22" + } + ] + } + ] + }, + "name": "abi_encode_tuple_packed_t_stringliteral_301a50b291d33ce1e8e9064e3f6a6c51d902ec22892b50d58abf6357c6a45541_t_uint256_t_address_t_bytes32__to_t_string_memory_ptr_t_uint256_t_address_t_bytes32__nonPadded_inplace_fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "pos", + "nodeType": "YulTypedName", + "src": "12730:3:22", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "12735:6:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "12743:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "12751:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "end", + "nodeType": "YulTypedName", + "src": "12762:3:22", + "type": "" + } + ], + "src": "12494:591:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "13196:281:22", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "13206:51:22", + "value": { + "arguments": [ + { + "name": "ptr_to_tail", + "nodeType": "YulIdentifier", + "src": "13245:11:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "13232:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "13232:25:22" + }, + "variables": [ + { + "name": "rel_offset_of_tail", + "nodeType": "YulTypedName", + "src": "13210:18:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "13405:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13414:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13417:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "13407:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "13407:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "13407:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "rel_offset_of_tail", + "nodeType": "YulIdentifier", + "src": "13280:18:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "arguments": [], + "functionName": { + "name": "calldatasize", + "nodeType": "YulIdentifier", + "src": "13308:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "13308:14:22" + }, + { + "name": "base_ref", + "nodeType": "YulIdentifier", + "src": "13324:8:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "13304:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "13304:29:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13335:66:22", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff41" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "13300:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "13300:102:22" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "13276:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "13276:127:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "13269:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "13269:135:22" + }, + "nodeType": "YulIf", + "src": "13266:155:22" + }, + { + "nodeType": "YulAssignment", + "src": "13430:41:22", + "value": { + "arguments": [ + { + "name": "base_ref", + "nodeType": "YulIdentifier", + "src": "13442:8:22" + }, + { + "name": "rel_offset_of_tail", + "nodeType": "YulIdentifier", + "src": "13452:18:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "13438:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "13438:33:22" + }, + "variableNames": [ + { + "name": "addr", + "nodeType": "YulIdentifier", + "src": "13430:4:22" + } + ] + } + ] + }, + "name": "access_calldata_tail_t_struct$_Transaction_$1292_calldata_ptr", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "base_ref", + "nodeType": "YulTypedName", + "src": "13161:8:22", + "type": "" + }, + { + "name": "ptr_to_tail", + "nodeType": "YulTypedName", + "src": "13171:11:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "addr", + "nodeType": "YulTypedName", + "src": "13187:4:22", + "type": "" + } + ], + "src": "13090:387:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "13549:113:22", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "13595:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13604:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13607:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "13597:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "13597:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "13597:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "13570:7:22" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13579:9:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "13566:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "13566:23:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13591:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "13562:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "13562:32:22" + }, + "nodeType": "YulIf", + "src": "13559:52:22" + }, + { + "nodeType": "YulAssignment", + "src": "13620:36:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13646:9:22" + } + ], + "functionName": { + "name": "abi_decode_bool", + "nodeType": "YulIdentifier", + "src": "13630:15:22" + }, + "nodeType": "YulFunctionCall", + "src": "13630:26:22" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "13620:6:22" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_bool", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "13515:9:22", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "13526:7:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "13538:6:22", + "type": "" + } + ], + "src": "13482:180:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "13824:162:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "13834:26:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13846:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13857:2:22", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "13842:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "13842:18:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "13834:4:22" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13876:9:22" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "13887:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "13869:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "13869:25:22" + }, + "nodeType": "YulExpressionStatement", + "src": "13869:25:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13914:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13925:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "13910:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "13910:18:22" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "13930:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "13903:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "13903:34:22" + }, + "nodeType": "YulExpressionStatement", + "src": "13903:34:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "13957:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "13968:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "13953:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "13953:18:22" + }, + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "13973:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "13946:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "13946:34:22" + }, + "nodeType": "YulExpressionStatement", + "src": "13946:34:22" + } + ] + }, + "name": "abi_encode_tuple_t_uint256_t_uint256_t_uint256__to_t_uint256_t_uint256_t_uint256__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "13777:9:22", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "13788:6:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "13796:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "13804:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "13815:4:22", + "type": "" + } + ], + "src": "13667:319:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "14061:116:22", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "14107:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14116:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14119:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "14109:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "14109:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "14109:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "14082:7:22" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "14091:9:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "14078:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "14078:23:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14103:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "14074:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "14074:32:22" + }, + "nodeType": "YulIf", + "src": "14071:52:22" + }, + { + "nodeType": "YulAssignment", + "src": "14132:39:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "14161:9:22" + } + ], + "functionName": { + "name": "abi_decode_address", + "nodeType": "YulIdentifier", + "src": "14142:18:22" + }, + "nodeType": "YulFunctionCall", + "src": "14142:29:22" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "14132:6:22" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_address", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "14027:9:22", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "14038:7:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "14050:6:22", + "type": "" + } + ], + "src": "13991:186:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "14276:486:22", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "14286:51:22", + "value": { + "arguments": [ + { + "name": "ptr_to_tail", + "nodeType": "YulIdentifier", + "src": "14325:11:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "14312:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "14312:25:22" + }, + "variables": [ + { + "name": "rel_offset_of_tail", + "nodeType": "YulTypedName", + "src": "14290:18:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "14485:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14494:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14497:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "14487:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "14487:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "14487:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "rel_offset_of_tail", + "nodeType": "YulIdentifier", + "src": "14360:18:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "arguments": [], + "functionName": { + "name": "calldatasize", + "nodeType": "YulIdentifier", + "src": "14388:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "14388:14:22" + }, + { + "name": "base_ref", + "nodeType": "YulIdentifier", + "src": "14404:8:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "14384:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "14384:29:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14415:66:22", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "14380:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "14380:102:22" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "14356:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "14356:127:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "14349:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "14349:135:22" + }, + "nodeType": "YulIf", + "src": "14346:155:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "14510:47:22", + "value": { + "arguments": [ + { + "name": "base_ref", + "nodeType": "YulIdentifier", + "src": "14528:8:22" + }, + { + "name": "rel_offset_of_tail", + "nodeType": "YulIdentifier", + "src": "14538:18:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "14524:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "14524:33:22" + }, + "variables": [ + { + "name": "addr_1", + "nodeType": "YulTypedName", + "src": "14514:6:22", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "14566:30:22", + "value": { + "arguments": [ + { + "name": "addr_1", + "nodeType": "YulIdentifier", + "src": "14589:6:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "14576:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "14576:20:22" + }, + "variableNames": [ + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "14566:6:22" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "14639:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14648:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14651:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "14641:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "14641:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "14641:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "14611:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14619:18:22", + "type": "", + "value": "0xffffffffffffffff" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "14608:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "14608:30:22" + }, + "nodeType": "YulIf", + "src": "14605:50:22" + }, + { + "nodeType": "YulAssignment", + "src": "14664:25:22", + "value": { + "arguments": [ + { + "name": "addr_1", + "nodeType": "YulIdentifier", + "src": "14676:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14684:4:22", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "14672:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "14672:17:22" + }, + "variableNames": [ + { + "name": "addr", + "nodeType": "YulIdentifier", + "src": "14664:4:22" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "14740:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14749:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14752:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "14742:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "14742:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "14742:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "addr", + "nodeType": "YulIdentifier", + "src": "14705:4:22" + }, + { + "arguments": [ + { + "arguments": [], + "functionName": { + "name": "calldatasize", + "nodeType": "YulIdentifier", + "src": "14715:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "14715:14:22" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "14731:6:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "14711:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "14711:27:22" + } + ], + "functionName": { + "name": "sgt", + "nodeType": "YulIdentifier", + "src": "14701:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "14701:38:22" + }, + "nodeType": "YulIf", + "src": "14698:58:22" + } + ] + }, + "name": "access_calldata_tail_t_bytes_calldata_ptr", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "base_ref", + "nodeType": "YulTypedName", + "src": "14233:8:22", + "type": "" + }, + { + "name": "ptr_to_tail", + "nodeType": "YulTypedName", + "src": "14243:11:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "addr", + "nodeType": "YulTypedName", + "src": "14259:4:22", + "type": "" + }, + { + "name": "length", + "nodeType": "YulTypedName", + "src": "14265:6:22", + "type": "" + } + ], + "src": "14182:580:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "14799:152:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14816:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14819:77:22", + "type": "", + "value": "35408467139433450592217433187231851964531694900788300625387963629091585785856" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "14809:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "14809:88:22" + }, + "nodeType": "YulExpressionStatement", + "src": "14809:88:22" + }, + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14913:1:22", + "type": "", + "value": "4" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14916:4:22", + "type": "", + "value": "0x11" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "14906:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "14906:15:22" + }, + "nodeType": "YulExpressionStatement", + "src": "14906:15:22" + }, + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14937:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "14940:4:22", + "type": "", + "value": "0x24" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "14930:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "14930:15:22" + }, + "nodeType": "YulExpressionStatement", + "src": "14930:15:22" + } + ] + }, + "name": "panic_error_0x11", + "nodeType": "YulFunctionDefinition", + "src": "14767:184:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "15003:148:22", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "15094:22:22", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "panic_error_0x11", + "nodeType": "YulIdentifier", + "src": "15096:16:22" + }, + "nodeType": "YulFunctionCall", + "src": "15096:18:22" + }, + "nodeType": "YulExpressionStatement", + "src": "15096:18:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "15019:5:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15026:66:22", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + } + ], + "functionName": { + "name": "eq", + "nodeType": "YulIdentifier", + "src": "15016:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "15016:77:22" + }, + "nodeType": "YulIf", + "src": "15013:103:22" + }, + { + "nodeType": "YulAssignment", + "src": "15125:20:22", + "value": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "15136:5:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15143:1:22", + "type": "", + "value": "1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "15132:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "15132:13:22" + }, + "variableNames": [ + { + "name": "ret", + "nodeType": "YulIdentifier", + "src": "15125:3:22" + } + ] + } + ] + }, + "name": "increment_t_uint256", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "14985:5:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "ret", + "nodeType": "YulTypedName", + "src": "14995:3:22", + "type": "" + } + ], + "src": "14956:195:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "15286:201:22", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "15324:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15333:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15336:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "15326:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "15326:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "15326:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "startIndex", + "nodeType": "YulIdentifier", + "src": "15302:10:22" + }, + { + "name": "endIndex", + "nodeType": "YulIdentifier", + "src": "15314:8:22" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "15299:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "15299:24:22" + }, + "nodeType": "YulIf", + "src": "15296:44:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "15373:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15382:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15385:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "15375:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "15375:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "15375:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "endIndex", + "nodeType": "YulIdentifier", + "src": "15355:8:22" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "15365:6:22" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "15352:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "15352:20:22" + }, + "nodeType": "YulIf", + "src": "15349:40:22" + }, + { + "nodeType": "YulAssignment", + "src": "15398:36:22", + "value": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "15415:6:22" + }, + { + "name": "startIndex", + "nodeType": "YulIdentifier", + "src": "15423:10:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "15411:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "15411:23:22" + }, + "variableNames": [ + { + "name": "offsetOut", + "nodeType": "YulIdentifier", + "src": "15398:9:22" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "15443:38:22", + "value": { + "arguments": [ + { + "name": "endIndex", + "nodeType": "YulIdentifier", + "src": "15460:8:22" + }, + { + "name": "startIndex", + "nodeType": "YulIdentifier", + "src": "15470:10:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "15456:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "15456:25:22" + }, + "variableNames": [ + { + "name": "lengthOut", + "nodeType": "YulIdentifier", + "src": "15443:9:22" + } + ] + } + ] + }, + "name": "calldata_array_index_range_access_t_bytes_calldata_ptr", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "15220:6:22", + "type": "" + }, + { + "name": "length", + "nodeType": "YulTypedName", + "src": "15228:6:22", + "type": "" + }, + { + "name": "startIndex", + "nodeType": "YulTypedName", + "src": "15236:10:22", + "type": "" + }, + { + "name": "endIndex", + "nodeType": "YulTypedName", + "src": "15248:8:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "offsetOut", + "nodeType": "YulTypedName", + "src": "15261:9:22", + "type": "" + }, + { + "name": "lengthOut", + "nodeType": "YulTypedName", + "src": "15272:9:22", + "type": "" + } + ], + "src": "15156:331:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "15540:77:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "15550:16:22", + "value": { + "arguments": [ + { + "name": "x", + "nodeType": "YulIdentifier", + "src": "15561:1:22" + }, + { + "name": "y", + "nodeType": "YulIdentifier", + "src": "15564:1:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "15557:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "15557:9:22" + }, + "variableNames": [ + { + "name": "sum", + "nodeType": "YulIdentifier", + "src": "15550:3:22" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "15589:22:22", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "panic_error_0x11", + "nodeType": "YulIdentifier", + "src": "15591:16:22" + }, + "nodeType": "YulFunctionCall", + "src": "15591:18:22" + }, + "nodeType": "YulExpressionStatement", + "src": "15591:18:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "x", + "nodeType": "YulIdentifier", + "src": "15581:1:22" + }, + { + "name": "sum", + "nodeType": "YulIdentifier", + "src": "15584:3:22" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "15578:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "15578:10:22" + }, + "nodeType": "YulIf", + "src": "15575:36:22" + } + ] + }, + "name": "checked_add_t_uint256", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "x", + "nodeType": "YulTypedName", + "src": "15523:1:22", + "type": "" + }, + { + "name": "y", + "nodeType": "YulTypedName", + "src": "15526:1:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "sum", + "nodeType": "YulTypedName", + "src": "15532:3:22", + "type": "" + } + ], + "src": "15492:125:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "15813:201:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "15830:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15841:2:22", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "15823:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "15823:21:22" + }, + "nodeType": "YulExpressionStatement", + "src": "15823:21:22" + }, + { + "nodeType": "YulAssignment", + "src": "15853:69:22", + "value": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "15887:6:22" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "15895:6:22" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "15907:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15918:2:22", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "15903:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "15903:18:22" + } + ], + "functionName": { + "name": "abi_encode_bytes_calldata", + "nodeType": "YulIdentifier", + "src": "15861:25:22" + }, + "nodeType": "YulFunctionCall", + "src": "15861:61:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "15853:4:22" + } + ] + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "15942:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15953:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "15938:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "15938:18:22" + }, + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "15958:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "15931:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "15931:34:22" + }, + "nodeType": "YulExpressionStatement", + "src": "15931:34:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "15985:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "15996:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "15981:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "15981:18:22" + }, + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "16001:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "15974:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "15974:34:22" + }, + "nodeType": "YulExpressionStatement", + "src": "15974:34:22" + } + ] + }, + "name": "abi_encode_tuple_t_bytes_calldata_ptr_slice_t_uint256_t_uint256__to_t_bytes_memory_ptr_t_uint256_t_uint256__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "15758:9:22", + "type": "" + }, + { + "name": "value3", + "nodeType": "YulTypedName", + "src": "15769:6:22", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "15777:6:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "15785:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "15793:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "15804:4:22", + "type": "" + } + ], + "src": "15622:392:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "16148:119:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "16158:26:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16170:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16181:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "16166:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "16166:18:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "16158:4:22" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16200:9:22" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "16211:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "16193:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "16193:25:22" + }, + "nodeType": "YulExpressionStatement", + "src": "16193:25:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16238:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16249:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "16234:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "16234:18:22" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "16254:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "16227:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "16227:34:22" + }, + "nodeType": "YulExpressionStatement", + "src": "16227:34:22" + } + ] + }, + "name": "abi_encode_tuple_t_uint256_t_uint256__to_t_uint256_t_uint256__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "16109:9:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "16120:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "16128:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "16139:4:22", + "type": "" + } + ], + "src": "16019:248:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "16401:119:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "16411:26:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16423:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16434:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "16419:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "16419:18:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "16411:4:22" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16453:9:22" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "16464:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "16446:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "16446:25:22" + }, + "nodeType": "YulExpressionStatement", + "src": "16446:25:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16491:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16502:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "16487:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "16487:18:22" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "16507:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "16480:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "16480:34:22" + }, + "nodeType": "YulExpressionStatement", + "src": "16480:34:22" + } + ] + }, + "name": "abi_encode_tuple_t_bytes32_t_bytes32__to_t_bytes32_t_bytes32__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "16362:9:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "16373:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "16381:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "16392:4:22", + "type": "" + } + ], + "src": "16272:248:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "16672:141:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16689:9:22" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "16700:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "16682:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "16682:25:22" + }, + "nodeType": "YulExpressionStatement", + "src": "16682:25:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16727:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16738:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "16723:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "16723:18:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16743:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "16716:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "16716:30:22" + }, + "nodeType": "YulExpressionStatement", + "src": "16716:30:22" + }, + { + "nodeType": "YulAssignment", + "src": "16755:52:22", + "value": { + "arguments": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "16780:6:22" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "16792:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "16803:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "16788:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "16788:18:22" + } + ], + "functionName": { + "name": "abi_encode_bytes", + "nodeType": "YulIdentifier", + "src": "16763:16:22" + }, + "nodeType": "YulFunctionCall", + "src": "16763:44:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "16755:4:22" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_uint256_t_bytes_memory_ptr__to_t_uint256_t_bytes_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "16633:9:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "16644:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "16652:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "16663:4:22", + "type": "" + } + ], + "src": "16525:288:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "17009:250:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17026:9:22" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "17037:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "17019:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "17019:25:22" + }, + "nodeType": "YulExpressionStatement", + "src": "17019:25:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17064:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17075:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "17060:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "17060:18:22" + }, + { + "arguments": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "17084:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17092:42:22", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffff" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "17080:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "17080:55:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "17053:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "17053:83:22" + }, + "nodeType": "YulExpressionStatement", + "src": "17053:83:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17156:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17167:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "17152:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "17152:18:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17172:2:22", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "17145:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "17145:30:22" + }, + "nodeType": "YulExpressionStatement", + "src": "17145:30:22" + }, + { + "nodeType": "YulAssignment", + "src": "17184:69:22", + "value": { + "arguments": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "17218:6:22" + }, + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "17226:6:22" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17238:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17249:2:22", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "17234:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "17234:18:22" + } + ], + "functionName": { + "name": "abi_encode_bytes_calldata", + "nodeType": "YulIdentifier", + "src": "17192:25:22" + }, + "nodeType": "YulFunctionCall", + "src": "17192:61:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "17184:4:22" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_bytes32_t_address_t_bytes_calldata_ptr_slice__to_t_bytes32_t_address_t_bytes_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "16954:9:22", + "type": "" + }, + { + "name": "value3", + "nodeType": "YulTypedName", + "src": "16965:6:22", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "16973:6:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "16981:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "16989:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "17000:4:22", + "type": "" + } + ], + "src": "16818:441:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "17393:115:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17410:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17421:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "17403:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "17403:21:22" + }, + "nodeType": "YulExpressionStatement", + "src": "17403:21:22" + }, + { + "nodeType": "YulAssignment", + "src": "17433:69:22", + "value": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "17467:6:22" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "17475:6:22" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17487:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17498:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "17483:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "17483:18:22" + } + ], + "functionName": { + "name": "abi_encode_bytes_calldata", + "nodeType": "YulIdentifier", + "src": "17441:25:22" + }, + "nodeType": "YulFunctionCall", + "src": "17441:61:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "17433:4:22" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "17354:9:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "17365:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "17373:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "17384:4:22", + "type": "" + } + ], + "src": "17264:244:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "17562:79:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "17572:17:22", + "value": { + "arguments": [ + { + "name": "x", + "nodeType": "YulIdentifier", + "src": "17584:1:22" + }, + { + "name": "y", + "nodeType": "YulIdentifier", + "src": "17587:1:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "17580:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "17580:9:22" + }, + "variableNames": [ + { + "name": "diff", + "nodeType": "YulIdentifier", + "src": "17572:4:22" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "17613:22:22", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "panic_error_0x11", + "nodeType": "YulIdentifier", + "src": "17615:16:22" + }, + "nodeType": "YulFunctionCall", + "src": "17615:18:22" + }, + "nodeType": "YulExpressionStatement", + "src": "17615:18:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "diff", + "nodeType": "YulIdentifier", + "src": "17604:4:22" + }, + { + "name": "x", + "nodeType": "YulIdentifier", + "src": "17610:1:22" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "17601:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "17601:11:22" + }, + "nodeType": "YulIf", + "src": "17598:37:22" + } + ] + }, + "name": "checked_sub_t_uint256", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "x", + "nodeType": "YulTypedName", + "src": "17544:1:22", + "type": "" + }, + { + "name": "y", + "nodeType": "YulTypedName", + "src": "17547:1:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "diff", + "nodeType": "YulTypedName", + "src": "17553:4:22", + "type": "" + } + ], + "src": "17513:128:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "17803:158:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17820:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17831:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "17813:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "17813:21:22" + }, + "nodeType": "YulExpressionStatement", + "src": "17813:21:22" + }, + { + "nodeType": "YulAssignment", + "src": "17843:69:22", + "value": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "17877:6:22" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "17885:6:22" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17897:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17908:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "17893:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "17893:18:22" + } + ], + "functionName": { + "name": "abi_encode_bytes_calldata", + "nodeType": "YulIdentifier", + "src": "17851:25:22" + }, + "nodeType": "YulFunctionCall", + "src": "17851:61:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "17843:4:22" + } + ] + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "17932:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "17943:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "17928:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "17928:18:22" + }, + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "17948:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "17921:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "17921:34:22" + }, + "nodeType": "YulExpressionStatement", + "src": "17921:34:22" + } + ] + }, + "name": "abi_encode_tuple_t_bytes_calldata_ptr_t_bytes32__to_t_bytes_memory_ptr_t_bytes32__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "17756:9:22", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "17767:6:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "17775:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "17783:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "17794:4:22", + "type": "" + } + ], + "src": "17646:315:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "18121:169:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "18138:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "18149:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "18131:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "18131:21:22" + }, + "nodeType": "YulExpressionStatement", + "src": "18131:21:22" + }, + { + "nodeType": "YulAssignment", + "src": "18161:69:22", + "value": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "18195:6:22" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "18203:6:22" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "18215:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "18226:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "18211:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "18211:18:22" + } + ], + "functionName": { + "name": "abi_encode_bytes_calldata", + "nodeType": "YulIdentifier", + "src": "18169:25:22" + }, + "nodeType": "YulFunctionCall", + "src": "18169:61:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "18161:4:22" + } + ] + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "18250:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "18261:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "18246:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "18246:18:22" + }, + { + "arguments": [ + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "18270:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "18278:4:22", + "type": "", + "value": "0xff" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "18266:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "18266:17:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "18239:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "18239:45:22" + }, + "nodeType": "YulExpressionStatement", + "src": "18239:45:22" + } + ] + }, + "name": "abi_encode_tuple_t_bytes_calldata_ptr_t_uint8__to_t_bytes_memory_ptr_t_uint256__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "18074:9:22", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "18085:6:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "18093:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "18101:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "18112:4:22", + "type": "" + } + ], + "src": "17966:324:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "18476:217:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "18486:27:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "18498:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "18509:3:22", + "type": "", + "value": "128" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "18494:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "18494:19:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "18486:4:22" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "18529:9:22" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "18540:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "18522:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "18522:25:22" + }, + "nodeType": "YulExpressionStatement", + "src": "18522:25:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "18567:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "18578:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "18563:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "18563:18:22" + }, + { + "arguments": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "18587:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "18595:4:22", + "type": "", + "value": "0xff" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "18583:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "18583:17:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "18556:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "18556:45:22" + }, + "nodeType": "YulExpressionStatement", + "src": "18556:45:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "18621:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "18632:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "18617:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "18617:18:22" + }, + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "18637:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "18610:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "18610:34:22" + }, + "nodeType": "YulExpressionStatement", + "src": "18610:34:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "18664:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "18675:2:22", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "18660:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "18660:18:22" + }, + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "18680:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "18653:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "18653:34:22" + }, + "nodeType": "YulExpressionStatement", + "src": "18653:34:22" + } + ] + }, + "name": "abi_encode_tuple_t_bytes32_t_uint8_t_bytes32_t_bytes32__to_t_bytes32_t_uint8_t_bytes32_t_bytes32__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "18421:9:22", + "type": "" + }, + { + "name": "value3", + "nodeType": "YulTypedName", + "src": "18432:6:22", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "18440:6:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "18448:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "18456:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "18467:4:22", + "type": "" + } + ], + "src": "18295:398:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "18918:160:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "18935:3:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "18940:66:22", + "type": "", + "value": "0x19457468657265756d205369676e6564204d6573736167653a0a333200000000" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "18928:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "18928:79:22" + }, + "nodeType": "YulExpressionStatement", + "src": "18928:79:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "19027:3:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "19032:2:22", + "type": "", + "value": "28" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "19023:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "19023:12:22" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "19037:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "19016:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "19016:28:22" + }, + "nodeType": "YulExpressionStatement", + "src": "19016:28:22" + }, + { + "nodeType": "YulAssignment", + "src": "19053:19:22", + "value": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "19064:3:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "19069:2:22", + "type": "", + "value": "60" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "19060:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "19060:12:22" + }, + "variableNames": [ + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "19053:3:22" + } + ] + } + ] + }, + "name": "abi_encode_tuple_packed_t_stringliteral_178a2411ab6fbc1ba11064408972259c558d0e82fd48b0aba3ad81d14f065e73_t_bytes32__to_t_string_memory_ptr_t_bytes32__nonPadded_inplace_fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "pos", + "nodeType": "YulTypedName", + "src": "18894:3:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "18899:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "end", + "nodeType": "YulTypedName", + "src": "18910:3:22", + "type": "" + } + ], + "src": "18698:380:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "19262:217:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "19279:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "19290:2:22", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "19272:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "19272:21:22" + }, + "nodeType": "YulExpressionStatement", + "src": "19272:21:22" + }, + { + "nodeType": "YulAssignment", + "src": "19302:69:22", + "value": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "19336:6:22" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "19344:6:22" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "19356:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "19367:2:22", + "type": "", + "value": "96" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "19352:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "19352:18:22" + } + ], + "functionName": { + "name": "abi_encode_bytes_calldata", + "nodeType": "YulIdentifier", + "src": "19310:25:22" + }, + "nodeType": "YulFunctionCall", + "src": "19310:61:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "19302:4:22" + } + ] + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "19391:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "19402:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "19387:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "19387:18:22" + }, + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "19407:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "19380:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "19380:34:22" + }, + "nodeType": "YulExpressionStatement", + "src": "19380:34:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "19434:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "19445:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "19430:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "19430:18:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "name": "value3", + "nodeType": "YulIdentifier", + "src": "19464:6:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "19457:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "19457:14:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "19450:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "19450:22:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "19423:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "19423:50:22" + }, + "nodeType": "YulExpressionStatement", + "src": "19423:50:22" + } + ] + }, + "name": "abi_encode_tuple_t_bytes_calldata_ptr_t_uint256_t_bool__to_t_bytes_memory_ptr_t_uint256_t_bool__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "19207:9:22", + "type": "" + }, + { + "name": "value3", + "nodeType": "YulTypedName", + "src": "19218:6:22", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "19226:6:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "19234:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "19242:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "19253:4:22", + "type": "" + } + ], + "src": "19083:396:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "19647:158:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "19664:9:22" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "19675:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "19657:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "19657:25:22" + }, + "nodeType": "YulExpressionStatement", + "src": "19657:25:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "19702:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "19713:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "19698:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "19698:18:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "19718:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "19691:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "19691:30:22" + }, + "nodeType": "YulExpressionStatement", + "src": "19691:30:22" + }, + { + "nodeType": "YulAssignment", + "src": "19730:69:22", + "value": { + "arguments": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "19764:6:22" + }, + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "19772:6:22" + }, + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "19784:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "19795:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "19780:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "19780:18:22" + } + ], + "functionName": { + "name": "abi_encode_bytes_calldata", + "nodeType": "YulIdentifier", + "src": "19738:25:22" + }, + "nodeType": "YulFunctionCall", + "src": "19738:61:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "19730:4:22" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_bytes32_t_bytes_calldata_ptr_slice__to_t_bytes32_t_bytes_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "19600:9:22", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "19611:6:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "19619:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "19627:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "19638:4:22", + "type": "" + } + ], + "src": "19484:321:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "19890:169:22", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "19936:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "19945:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "19948:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "19938:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "19938:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "19938:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "19911:7:22" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "19920:9:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "19907:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "19907:23:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "19932:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "19903:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "19903:32:22" + }, + "nodeType": "YulIf", + "src": "19900:52:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "19961:29:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "19980:9:22" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "19974:5:22" + }, + "nodeType": "YulFunctionCall", + "src": "19974:16:22" + }, + "variables": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "19965:5:22", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "20023:5:22" + } + ], + "functionName": { + "name": "validator_revert_bytes4", + "nodeType": "YulIdentifier", + "src": "19999:23:22" + }, + "nodeType": "YulFunctionCall", + "src": "19999:30:22" + }, + "nodeType": "YulExpressionStatement", + "src": "19999:30:22" + }, + { + "nodeType": "YulAssignment", + "src": "20038:15:22", + "value": { + "name": "value", + "nodeType": "YulIdentifier", + "src": "20048:5:22" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "20038:6:22" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_bytes4_fromMemory", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "19856:9:22", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "19867:7:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "19879:6:22", + "type": "" + } + ], + "src": "19810:249:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "20340:235:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "20357:3:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "20362:66:22", + "type": "", + "value": "0x53657175656e6365206e657374656420636f6e6669673a0a0000000000000000" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "20350:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "20350:79:22" + }, + "nodeType": "YulExpressionStatement", + "src": "20350:79:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "20449:3:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "20454:2:22", + "type": "", + "value": "24" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "20445:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "20445:12:22" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "20459:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "20438:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "20438:28:22" + }, + "nodeType": "YulExpressionStatement", + "src": "20438:28:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "20486:3:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "20491:2:22", + "type": "", + "value": "56" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "20482:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "20482:12:22" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "20496:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "20475:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "20475:28:22" + }, + "nodeType": "YulExpressionStatement", + "src": "20475:28:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "20523:3:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "20528:2:22", + "type": "", + "value": "88" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "20519:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "20519:12:22" + }, + { + "name": "value2", + "nodeType": "YulIdentifier", + "src": "20533:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "20512:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "20512:28:22" + }, + "nodeType": "YulExpressionStatement", + "src": "20512:28:22" + }, + { + "nodeType": "YulAssignment", + "src": "20549:20:22", + "value": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "20560:3:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "20565:3:22", + "type": "", + "value": "120" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "20556:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "20556:13:22" + }, + "variableNames": [ + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "20549:3:22" + } + ] + } + ] + }, + "name": "abi_encode_tuple_packed_t_stringliteral_58d1832f15932b40f8da147bd99ac98efab990f25a786a2229b05ee5f5be41a7_t_bytes32_t_uint256_t_uint256__to_t_string_memory_ptr_t_bytes32_t_uint256_t_uint256__nonPadded_inplace_fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "pos", + "nodeType": "YulTypedName", + "src": "20300:3:22", + "type": "" + }, + { + "name": "value2", + "nodeType": "YulTypedName", + "src": "20305:6:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "20313:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "20321:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "end", + "nodeType": "YulTypedName", + "src": "20332:3:22", + "type": "" + } + ], + "src": "20064:511:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "20800:160:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "20817:3:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "20822:66:22", + "type": "", + "value": "0x53657175656e636520737461746963206469676573743a0a0000000000000000" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "20810:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "20810:79:22" + }, + "nodeType": "YulExpressionStatement", + "src": "20810:79:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "20909:3:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "20914:2:22", + "type": "", + "value": "24" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "20905:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "20905:12:22" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "20919:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "20898:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "20898:28:22" + }, + "nodeType": "YulExpressionStatement", + "src": "20898:28:22" + }, + { + "nodeType": "YulAssignment", + "src": "20935:19:22", + "value": { + "arguments": [ + { + "name": "pos", + "nodeType": "YulIdentifier", + "src": "20946:3:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "20951:2:22", + "type": "", + "value": "56" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "20942:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "20942:12:22" + }, + "variableNames": [ + { + "name": "end", + "nodeType": "YulIdentifier", + "src": "20935:3:22" + } + ] + } + ] + }, + "name": "abi_encode_tuple_packed_t_stringliteral_583557e68bca91e5400591dbc9ae31043113c95e3cd985463ae532f51d706f8c_t_bytes32__to_t_string_memory_ptr_t_bytes32__nonPadded_inplace_fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "pos", + "nodeType": "YulTypedName", + "src": "20776:3:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "20781:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "end", + "nodeType": "YulTypedName", + "src": "20792:3:22", + "type": "" + } + ], + "src": "20580:380:22" + } + ] + }, + "contents": "{\n { }\n function validator_revert_bytes4(value)\n {\n if iszero(eq(value, and(value, 0xffffffff00000000000000000000000000000000000000000000000000000000))) { revert(0, 0) }\n }\n function abi_decode_tuple_t_bytes4(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let value := calldataload(headStart)\n validator_revert_bytes4(value)\n value0 := value\n }\n function abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, iszero(iszero(value0)))\n }\n function abi_decode_bytes_calldata(offset, end) -> arrayPos, length\n {\n if iszero(slt(add(offset, 0x1f), end)) { revert(0, 0) }\n length := calldataload(offset)\n if gt(length, 0xffffffffffffffff) { revert(0, 0) }\n arrayPos := add(offset, 0x20)\n if gt(add(add(offset, length), 0x20), end) { revert(0, 0) }\n }\n function abi_decode_tuple_t_bytes32t_bytes_calldata_ptr(headStart, dataEnd) -> value0, value1, value2\n {\n if slt(sub(dataEnd, headStart), 64) { revert(0, 0) }\n value0 := calldataload(headStart)\n let offset := calldataload(add(headStart, 32))\n if gt(offset, 0xffffffffffffffff) { revert(0, 0) }\n let value1_1, value2_1 := abi_decode_bytes_calldata(add(headStart, offset), dataEnd)\n value1 := value1_1\n value2 := value2_1\n }\n function abi_encode_tuple_t_bytes4__to_t_bytes4__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, and(value0, 0xffffffff00000000000000000000000000000000000000000000000000000000))\n }\n function abi_decode_tuple_t_bytes_calldata_ptrt_bytes_calldata_ptr(headStart, dataEnd) -> value0, value1, value2, value3\n {\n if slt(sub(dataEnd, headStart), 64) { revert(0, 0) }\n let offset := calldataload(headStart)\n let _1 := 0xffffffffffffffff\n if gt(offset, _1) { revert(0, 0) }\n let value0_1, value1_1 := abi_decode_bytes_calldata(add(headStart, offset), dataEnd)\n value0 := value0_1\n value1 := value1_1\n let offset_1 := calldataload(add(headStart, 32))\n if gt(offset_1, _1) { revert(0, 0) }\n let value2_1, value3_1 := abi_decode_bytes_calldata(add(headStart, offset_1), dataEnd)\n value2 := value2_1\n value3 := value3_1\n }\n function abi_decode_tuple_t_bytes32(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n value0 := calldataload(headStart)\n }\n function abi_encode_tuple_t_bytes32__to_t_bytes32__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, value0)\n }\n function abi_decode_array_struct_Transaction_calldata_dyn_calldata(offset, end) -> arrayPos, length\n {\n if iszero(slt(add(offset, 0x1f), end)) { revert(0, 0) }\n length := calldataload(offset)\n if gt(length, 0xffffffffffffffff) { revert(0, 0) }\n arrayPos := add(offset, 0x20)\n if gt(add(add(offset, shl(5, length)), 0x20), end) { revert(0, 0) }\n }\n function abi_decode_tuple_t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr(headStart, dataEnd) -> value0, value1\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let offset := calldataload(headStart)\n if gt(offset, 0xffffffffffffffff) { revert(0, 0) }\n let value0_1, value1_1 := abi_decode_array_struct_Transaction_calldata_dyn_calldata(add(headStart, offset), dataEnd)\n value0 := value0_1\n value1 := value1_1\n }\n function abi_decode_tuple_t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptrt_uint256t_bytes_calldata_ptr(headStart, dataEnd) -> value0, value1, value2, value3, value4\n {\n if slt(sub(dataEnd, headStart), 96) { revert(0, 0) }\n let offset := calldataload(headStart)\n let _1 := 0xffffffffffffffff\n if gt(offset, _1) { revert(0, 0) }\n let value0_1, value1_1 := abi_decode_array_struct_Transaction_calldata_dyn_calldata(add(headStart, offset), dataEnd)\n value0 := value0_1\n value1 := value1_1\n value2 := calldataload(add(headStart, 32))\n let offset_1 := calldataload(add(headStart, 64))\n if gt(offset_1, _1) { revert(0, 0) }\n let value3_1, value4_1 := abi_decode_bytes_calldata(add(headStart, offset_1), dataEnd)\n value3 := value3_1\n value4 := value4_1\n }\n function abi_encode_tuple_t_uint256_t_uint256_t_bytes32_t_bytes32_t_uint256__to_t_uint256_t_uint256_t_bytes32_t_bytes32_t_uint256__fromStack_reversed(headStart, value4, value3, value2, value1, value0) -> tail\n {\n tail := add(headStart, 160)\n mstore(headStart, value0)\n mstore(add(headStart, 32), value1)\n mstore(add(headStart, 64), value2)\n mstore(add(headStart, 96), value3)\n mstore(add(headStart, 128), value4)\n }\n function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n value0 := calldataload(headStart)\n }\n function abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, value0)\n }\n function panic_error_0x41()\n {\n mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n mstore(4, 0x41)\n revert(0, 0x24)\n }\n function abi_decode_tuple_t_bytes_memory_ptr(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let offset := calldataload(headStart)\n let _1 := 0xffffffffffffffff\n if gt(offset, _1) { revert(0, 0) }\n let _2 := add(headStart, offset)\n if iszero(slt(add(_2, 0x1f), dataEnd)) { revert(0, 0) }\n let _3 := calldataload(_2)\n if gt(_3, _1) { panic_error_0x41() }\n let _4 := 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0\n let memPtr := mload(64)\n let newFreePtr := add(memPtr, and(add(and(add(_3, 0x1f), _4), 63), _4))\n if or(gt(newFreePtr, _1), lt(newFreePtr, memPtr)) { panic_error_0x41() }\n mstore(64, newFreePtr)\n mstore(memPtr, _3)\n if gt(add(add(_2, _3), 32), dataEnd) { revert(0, 0) }\n calldatacopy(add(memPtr, 32), add(_2, 32), _3)\n mstore(add(add(memPtr, _3), 32), 0)\n value0 := memPtr\n }\n function abi_encode_tuple_t_address__to_t_address__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, and(value0, 0xffffffffffffffffffffffffffffffffffffffff))\n }\n function abi_encode_tuple_packed_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__nonPadded_inplace_fromStack_reversed(pos, value1, value0) -> end\n {\n calldatacopy(pos, value0, value1)\n let _1 := add(pos, value1)\n mstore(_1, 0)\n end := _1\n }\n function abi_encode_tuple_t_address_t_address__to_t_address_t_address__fromStack_reversed(headStart, value1, value0) -> tail\n {\n tail := add(headStart, 64)\n let _1 := 0xffffffffffffffffffffffffffffffffffffffff\n mstore(headStart, and(value0, _1))\n mstore(add(headStart, 32), and(value1, _1))\n }\n function abi_decode_bool(offset) -> value\n {\n value := calldataload(offset)\n if iszero(eq(value, iszero(iszero(value)))) { revert(0, 0) }\n }\n function abi_decode_address(offset) -> value\n {\n value := calldataload(offset)\n if iszero(eq(value, and(value, 0xffffffffffffffffffffffffffffffffffffffff))) { revert(0, 0) }\n }\n function abi_encode_bytes_calldata(start, length, pos) -> end\n {\n mstore(pos, length)\n calldatacopy(add(pos, 0x20), start, length)\n mstore(add(add(pos, length), 0x20), 0)\n end := add(add(pos, and(add(length, 31), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0)), 0x20)\n }\n function abi_encode_array_struct_Transaction_calldata_dyn_calldata(value, length, pos) -> end\n {\n mstore(pos, length)\n let _1 := 0x20\n let updated_pos := add(pos, _1)\n let pos_1 := updated_pos\n pos := updated_pos\n let tail := add(pos_1, shl(5, length))\n let srcPtr := value\n let i := 0\n for { } lt(i, length) { i := add(i, 1) }\n {\n mstore(pos, sub(tail, pos_1))\n let rel_offset_of_tail := calldataload(srcPtr)\n if iszero(slt(rel_offset_of_tail, add(sub(calldatasize(), value), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff41))) { revert(0, 0) }\n let value_1 := add(rel_offset_of_tail, value)\n let _2 := 0xc0\n mstore(tail, iszero(iszero(abi_decode_bool(value_1))))\n mstore(add(tail, _1), iszero(iszero(abi_decode_bool(add(value_1, _1)))))\n let _3 := 0x40\n mstore(add(tail, _3), calldataload(add(value_1, _3)))\n let _4 := 0x60\n mstore(add(tail, _4), and(abi_decode_address(add(value_1, _4)), 0xffffffffffffffffffffffffffffffffffffffff))\n let _5 := 0x80\n mstore(add(tail, _5), calldataload(add(value_1, _5)))\n let _6 := 0xa0\n let rel_offset_of_tail_1 := calldataload(add(value_1, _6))\n if iszero(slt(rel_offset_of_tail_1, add(sub(calldatasize(), value_1), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1))) { revert(0, 0) }\n let value_2 := add(rel_offset_of_tail_1, value_1)\n let length_1 := calldataload(value_2)\n let value_3 := add(value_2, _1)\n if gt(length_1, 0xffffffffffffffff) { revert(0, 0) }\n if sgt(value_3, sub(calldatasize(), length_1)) { revert(0, 0) }\n mstore(add(tail, _6), _2)\n tail := abi_encode_bytes_calldata(value_3, length_1, add(tail, _2))\n srcPtr := add(srcPtr, _1)\n pos := add(pos, _1)\n }\n end := tail\n }\n function abi_encode_tuple_t_stringliteral_bf9461da9f9c0123d3a54c61147a274d8fdb5d5c1e488665fb11b9edbbc32845_t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr__to_t_string_memory_ptr_t_array$_t_struct$_Transaction_$1292_memory_ptr_$dyn_memory_ptr__fromStack_reversed(headStart, value1, value0) -> tail\n {\n mstore(headStart, 64)\n mstore(add(headStart, 64), 5)\n mstore(add(headStart, 96), \"self:\")\n mstore(add(headStart, 0x20), 128)\n tail := abi_encode_array_struct_Transaction_calldata_dyn_calldata(value0, value1, add(headStart, 128))\n }\n function abi_encode_tuple_t_stringliteral_4dfa0bed92fb5c2df0b47ce555e6e6b89f746e856aa9783c634a4987edcbf682_t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr__to_t_string_memory_ptr_t_array$_t_struct$_Transaction_$1292_memory_ptr_$dyn_memory_ptr__fromStack_reversed(headStart, value1, value0) -> tail\n {\n mstore(headStart, 64)\n mstore(add(headStart, 64), 6)\n mstore(add(headStart, 96), \"guest:\")\n mstore(add(headStart, 0x20), 128)\n tail := abi_encode_array_struct_Transaction_calldata_dyn_calldata(value0, value1, add(headStart, 128))\n }\n function panic_error_0x32()\n {\n mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n mstore(4, 0x32)\n revert(0, 0x24)\n }\n function abi_encode_tuple_t_bytes1__to_t_bytes1__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, and(value0, 0xff00000000000000000000000000000000000000000000000000000000000000))\n }\n function abi_encode_bytes(value, pos) -> end\n {\n let length := mload(value)\n mstore(pos, length)\n let i := 0\n for { } lt(i, length) { i := add(i, 0x20) }\n {\n let _1 := 0x20\n mstore(add(add(pos, i), _1), mload(add(add(value, i), _1)))\n }\n mstore(add(add(pos, length), 0x20), 0)\n end := add(add(pos, and(add(length, 31), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0)), 0x20)\n }\n function abi_encode_tuple_t_bytes_memory_ptr__to_t_bytes_memory_ptr__fromStack_reversed(headStart, value0) -> tail\n {\n mstore(headStart, 32)\n tail := abi_encode_bytes(value0, add(headStart, 32))\n }\n function abi_encode_tuple_packed_t_stringliteral_301a50b291d33ce1e8e9064e3f6a6c51d902ec22892b50d58abf6357c6a45541_t_uint256_t_address_t_bytes32__to_t_string_memory_ptr_t_uint256_t_address_t_bytes32__nonPadded_inplace_fromStack_reversed(pos, value2, value1, value0) -> end\n {\n mstore(pos, 0x1901000000000000000000000000000000000000000000000000000000000000)\n mstore(add(pos, 2), value0)\n mstore(add(pos, 34), and(shl(96, value1), 0xffffffffffffffffffffffffffffffffffffffff000000000000000000000000))\n mstore(add(pos, 54), value2)\n end := add(pos, 86)\n }\n function access_calldata_tail_t_struct$_Transaction_$1292_calldata_ptr(base_ref, ptr_to_tail) -> addr\n {\n let rel_offset_of_tail := calldataload(ptr_to_tail)\n if iszero(slt(rel_offset_of_tail, add(sub(calldatasize(), base_ref), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff41))) { revert(0, 0) }\n addr := add(base_ref, rel_offset_of_tail)\n }\n function abi_decode_tuple_t_bool(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n value0 := abi_decode_bool(headStart)\n }\n function abi_encode_tuple_t_uint256_t_uint256_t_uint256__to_t_uint256_t_uint256_t_uint256__fromStack_reversed(headStart, value2, value1, value0) -> tail\n {\n tail := add(headStart, 96)\n mstore(headStart, value0)\n mstore(add(headStart, 32), value1)\n mstore(add(headStart, 64), value2)\n }\n function abi_decode_tuple_t_address(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n value0 := abi_decode_address(headStart)\n }\n function access_calldata_tail_t_bytes_calldata_ptr(base_ref, ptr_to_tail) -> addr, length\n {\n let rel_offset_of_tail := calldataload(ptr_to_tail)\n if iszero(slt(rel_offset_of_tail, add(sub(calldatasize(), base_ref), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1))) { revert(0, 0) }\n let addr_1 := add(base_ref, rel_offset_of_tail)\n length := calldataload(addr_1)\n if gt(length, 0xffffffffffffffff) { revert(0, 0) }\n addr := add(addr_1, 0x20)\n if sgt(addr, sub(calldatasize(), length)) { revert(0, 0) }\n }\n function panic_error_0x11()\n {\n mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n mstore(4, 0x11)\n revert(0, 0x24)\n }\n function increment_t_uint256(value) -> ret\n {\n if eq(value, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) { panic_error_0x11() }\n ret := add(value, 1)\n }\n function calldata_array_index_range_access_t_bytes_calldata_ptr(offset, length, startIndex, endIndex) -> offsetOut, lengthOut\n {\n if gt(startIndex, endIndex) { revert(0, 0) }\n if gt(endIndex, length) { revert(0, 0) }\n offsetOut := add(offset, startIndex)\n lengthOut := sub(endIndex, startIndex)\n }\n function checked_add_t_uint256(x, y) -> sum\n {\n sum := add(x, y)\n if gt(x, sum) { panic_error_0x11() }\n }\n function abi_encode_tuple_t_bytes_calldata_ptr_slice_t_uint256_t_uint256__to_t_bytes_memory_ptr_t_uint256_t_uint256__fromStack_reversed(headStart, value3, value2, value1, value0) -> tail\n {\n mstore(headStart, 96)\n tail := abi_encode_bytes_calldata(value0, value1, add(headStart, 96))\n mstore(add(headStart, 32), value2)\n mstore(add(headStart, 64), value3)\n }\n function abi_encode_tuple_t_uint256_t_uint256__to_t_uint256_t_uint256__fromStack_reversed(headStart, value1, value0) -> tail\n {\n tail := add(headStart, 64)\n mstore(headStart, value0)\n mstore(add(headStart, 32), value1)\n }\n function abi_encode_tuple_t_bytes32_t_bytes32__to_t_bytes32_t_bytes32__fromStack_reversed(headStart, value1, value0) -> tail\n {\n tail := add(headStart, 64)\n mstore(headStart, value0)\n mstore(add(headStart, 32), value1)\n }\n function abi_encode_tuple_t_uint256_t_bytes_memory_ptr__to_t_uint256_t_bytes_memory_ptr__fromStack_reversed(headStart, value1, value0) -> tail\n {\n mstore(headStart, value0)\n mstore(add(headStart, 32), 64)\n tail := abi_encode_bytes(value1, add(headStart, 64))\n }\n function abi_encode_tuple_t_bytes32_t_address_t_bytes_calldata_ptr_slice__to_t_bytes32_t_address_t_bytes_memory_ptr__fromStack_reversed(headStart, value3, value2, value1, value0) -> tail\n {\n mstore(headStart, value0)\n mstore(add(headStart, 32), and(value1, 0xffffffffffffffffffffffffffffffffffffffff))\n mstore(add(headStart, 64), 96)\n tail := abi_encode_bytes_calldata(value2, value3, add(headStart, 96))\n }\n function abi_encode_tuple_t_bytes_calldata_ptr__to_t_bytes_memory_ptr__fromStack_reversed(headStart, value1, value0) -> tail\n {\n mstore(headStart, 32)\n tail := abi_encode_bytes_calldata(value0, value1, add(headStart, 32))\n }\n function checked_sub_t_uint256(x, y) -> diff\n {\n diff := sub(x, y)\n if gt(diff, x) { panic_error_0x11() }\n }\n function abi_encode_tuple_t_bytes_calldata_ptr_t_bytes32__to_t_bytes_memory_ptr_t_bytes32__fromStack_reversed(headStart, value2, value1, value0) -> tail\n {\n mstore(headStart, 64)\n tail := abi_encode_bytes_calldata(value0, value1, add(headStart, 64))\n mstore(add(headStart, 32), value2)\n }\n function abi_encode_tuple_t_bytes_calldata_ptr_t_uint8__to_t_bytes_memory_ptr_t_uint256__fromStack_reversed(headStart, value2, value1, value0) -> tail\n {\n mstore(headStart, 64)\n tail := abi_encode_bytes_calldata(value0, value1, add(headStart, 64))\n mstore(add(headStart, 32), and(value2, 0xff))\n }\n function abi_encode_tuple_t_bytes32_t_uint8_t_bytes32_t_bytes32__to_t_bytes32_t_uint8_t_bytes32_t_bytes32__fromStack_reversed(headStart, value3, value2, value1, value0) -> tail\n {\n tail := add(headStart, 128)\n mstore(headStart, value0)\n mstore(add(headStart, 32), and(value1, 0xff))\n mstore(add(headStart, 64), value2)\n mstore(add(headStart, 96), value3)\n }\n function abi_encode_tuple_packed_t_stringliteral_178a2411ab6fbc1ba11064408972259c558d0e82fd48b0aba3ad81d14f065e73_t_bytes32__to_t_string_memory_ptr_t_bytes32__nonPadded_inplace_fromStack_reversed(pos, value0) -> end\n {\n mstore(pos, 0x19457468657265756d205369676e6564204d6573736167653a0a333200000000)\n mstore(add(pos, 28), value0)\n end := add(pos, 60)\n }\n function abi_encode_tuple_t_bytes_calldata_ptr_t_uint256_t_bool__to_t_bytes_memory_ptr_t_uint256_t_bool__fromStack_reversed(headStart, value3, value2, value1, value0) -> tail\n {\n mstore(headStart, 96)\n tail := abi_encode_bytes_calldata(value0, value1, add(headStart, 96))\n mstore(add(headStart, 32), value2)\n mstore(add(headStart, 64), iszero(iszero(value3)))\n }\n function abi_encode_tuple_t_bytes32_t_bytes_calldata_ptr_slice__to_t_bytes32_t_bytes_memory_ptr__fromStack_reversed(headStart, value2, value1, value0) -> tail\n {\n mstore(headStart, value0)\n mstore(add(headStart, 32), 64)\n tail := abi_encode_bytes_calldata(value1, value2, add(headStart, 64))\n }\n function abi_decode_tuple_t_bytes4_fromMemory(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let value := mload(headStart)\n validator_revert_bytes4(value)\n value0 := value\n }\n function abi_encode_tuple_packed_t_stringliteral_58d1832f15932b40f8da147bd99ac98efab990f25a786a2229b05ee5f5be41a7_t_bytes32_t_uint256_t_uint256__to_t_string_memory_ptr_t_bytes32_t_uint256_t_uint256__nonPadded_inplace_fromStack_reversed(pos, value2, value1, value0) -> end\n {\n mstore(pos, 0x53657175656e6365206e657374656420636f6e6669673a0a0000000000000000)\n mstore(add(pos, 24), value0)\n mstore(add(pos, 56), value1)\n mstore(add(pos, 88), value2)\n end := add(pos, 120)\n }\n function abi_encode_tuple_packed_t_stringliteral_583557e68bca91e5400591dbc9ae31043113c95e3cd985463ae532f51d706f8c_t_bytes32__to_t_string_memory_ptr_t_bytes32__nonPadded_inplace_fromStack_reversed(pos, value0) -> end\n {\n mstore(pos, 0x53657175656e636520737461746963206469676573743a0a0000000000000000)\n mstore(add(pos, 24), value0)\n end := add(pos, 56)\n }\n}", + "id": 22, + "language": "Yul", + "name": "#utility.yul" + } + ], + "immutableReferences": {}, + "linkReferences": {}, + "object": "6080604052600436106100bc5760003560e01c806361c2926c116100745780638c3f55631161004e5780638c3f55631461025357806390042baf14610273578063affed0e0146102ab57600080fd5b806361c2926c146101cb5780637a9a1628146101eb578063853c50681461020b57600080fd5b806320c13b0b116100a557806320c13b0b14610147578063295614261461016757806357c56d6b1461018957600080fd5b806301ffc9a7146100c15780631626ba7e146100f6575b600080fd5b3480156100cd57600080fd5b506100e16100dc366004611880565b6102c0565b60405190151581526020015b60405180910390f35b34801561010257600080fd5b506101166101113660046118e6565b6102d1565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016100ed565b34801561015357600080fd5b50610116610162366004611932565b61031e565b34801561017357600080fd5b5061018761018236600461199e565b610383565b005b34801561019557600080fd5b506101bd7f8713a7c4465f6fbee2b6e9d6646d1d9f83fec929edfc4baf661f3c865bdd04d181565b6040519081526020016100ed565b3480156101d757600080fd5b506101876101e63660046119fc565b6103d5565b3480156101f757600080fd5b50610187610206366004611a3e565b61041a565b34801561021757600080fd5b5061022b6102263660046118e6565b610447565b604080519586526020860194909452928401919091526060830152608082015260a0016100ed565b34801561025f57600080fd5b506101bd61026e36600461199e565b61060f565b610286610281366004611ae7565b61063b565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100ed565b3480156102b757600080fd5b506101bd610725565b60006102cb82610736565b92915050565b6000806102df858585610792565b509050801561031157507f1626ba7e000000000000000000000000000000000000000000000000000000009050610317565b50600090505b9392505050565b6000806103438686604051610334929190611bb6565b60405180910390208585610792565b509050801561037557507f20c13b0b00000000000000000000000000000000000000000000000000000000905061037b565b50600090505b949350505050565b3330146103c9576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044015b60405180910390fd5b6103d2816107ca565b50565b600061040883836040516020016103ed929190611d97565b604051602081830303815290604052805190602001206107fc565b9050610415818484610881565b505050565b600061043286866040516020016103ed929190611ddf565b905061043f818787610881565b505050505050565b6000806000806000808787600081811061046357610463611e27565b909101357fff000000000000000000000000000000000000000000000000000000000000001691508190506104b95761049b896107fc565b92506104a8838989610a0e565b929850909650945091506106049050565b7fff00000000000000000000000000000000000000000000000000000000000000818116016104f8576104eb896107fc565b92506104a8838989610a5f565b7ffe000000000000000000000000000000000000000000000000000000000000007fff0000000000000000000000000000000000000000000000000000000000000082160161054a576104eb89610a8b565b7ffd000000000000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000008216016105ae5761059e898989610af8565b9550955095509550955050610604565b6040517f6085cd820000000000000000000000000000000000000000000000000000000081527fff00000000000000000000000000000000000000000000000000000000000000821660048201526024016103c0565b939792965093509350565b60006102cb7f8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e83610c75565b600033301461067e576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044016103c0565b81516020830134f0905073ffffffffffffffffffffffffffffffffffffffff81166106d757816040517f0d2571910000000000000000000000000000000000000000000000000000000081526004016103c09190611eba565b60405173ffffffffffffffffffffffffffffffffffffffff821681527fa506ad4e7f05eceba62a023c3219e5bd98a615f4fa87e2afb08a2da5cf62bf0c9060200160405180910390a1919050565b6000610731600061060f565b905090565b60007f6ffbd451000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000083160161078957506001919050565b6102cb82610cd3565b60008060008060006107a5888888610447565b509650919450925090508282108015906107bd575060015b9450505050935093915050565b6040517fa038794000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f190100000000000000000000000000000000000000000000000000000000000060208201524660228201527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b166042820152605681018290526000906076015b604051602081830303815290604052805190602001209050919050565b8060005b81811015610a0757368484838181106108a0576108a0611e27565b90506020028101906108b29190611ecd565b90506108c16020820182611f0b565b156108fb576040517f230d1ccc000000000000000000000000000000000000000000000000000000008152600481018390526024016103c0565b6040810135805a101561094e5782815a6040517f2bb3e3ba0000000000000000000000000000000000000000000000000000000081526004810193909352602483019190915260448201526064016103c0565b60006109886109636080850160608601611f26565b608085013584156109745784610976565b5a5b61098360a0880188611f41565b610d2f565b905080156109cf57877f5c4eeb02dabf8976016ab414d617f9a162936dcace3cdef8c69ef6e262ad5ae7856040516109c291815260200190565b60405180910390a26109f1565b6109f16109e26040850160208601611f0b565b89866109ec610d4c565b610d6b565b50505080806109ff90611fd5565b915050610885565b5050505050565b6000808080610a2987610a24876006818b61200d565b610db9565b6000908152873560f01c6020818152604080842084526002909a013560e01c908190529890912090999198509695509350505050565b6000808080610a7a87610a75876001818b61200d565b610a0e565b935093509350935093509350935093565b6040517f190100000000000000000000000000000000000000000000000000000000000060208201526000602282018190527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b1660428301526056820183905290607601610864565b6000808080806004600188013560e81c82610b138383612037565b9050610b258b61022683868d8f61200d565b939b5091995097509550935087871015610b7d57610b4581848b8d61200d565b89896040517fb006aba00000000000000000000000000000000000000000000000000000000081526004016103c0949392919061204a565b8092505b88831015610c675760038301928a013560e81c9150610ba08383612037565b90506000610bc2610bb08861124f565b8c8c879086926102269392919061200d565b939c50919a5098509091505088881015610c1a57610be282858c8e61200d565b8a8a6040517fb006aba00000000000000000000000000000000000000000000000000000000081526004016103c0949392919061204a565b848110610c5d576040517f37daf62b00000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016103c0565b9350915081610b81565b505050939792965093509350565b6000808383604051602001610c94929190918252602082015260400190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052805160209091012054949350505050565b60007fe4a77bbc000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831601610d2657506001919050565b6102cb82611283565b6000604051828482376000808483898b8af1979650505050505050565b60603d604051915060208201818101604052818352816000823e505090565b8315610d7957805160208201fd5b827fab46c69f7f32e1bf09b0725853da82a211e5402a0600296ab499a2fb5ea3b4198383604051610dab929190612071565b60405180910390a250505050565b60008060005b8381101561124657600181019085013560f81c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8101610e6057601582019186013560f881901c9060581c73ffffffffffffffffffffffffffffffffffffffff81169074ff000000000000000000000000000000000000000016811785610e465780610e55565b60008681526020829052604090205b955050505050610dbf565b80610ef65760018201918681013560f81c906043016000610e8c8a610e8784888c8e61200d565b61136d565b60ff841697909701969194508491905060a083901b74ff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff82161786610edb5780610eea565b60008781526020829052604090205b96505050505050610dbf565b6002810361101e576000808784013560f881901c9060581c73ffffffffffffffffffffffffffffffffffffffff16601586019550909250905060008885013560e81c600386018162ffffff169150809650819250505060008186019050610f6f8b848c8c8a908692610f6a9392919061200d565b611630565b610fb7578a83610f8183898d8f61200d565b6040517f9a9462320000000000000000000000000000000000000000000000000000000081526004016103c0949392919061208a565b60ff8416979097019694508460a084901b74ff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff841617876110025780611011565b60008881526020829052604090205b9750505050505050610dbf565b60038103611051576020820191860135836110395780611048565b60008481526020829052604090205b93505050610dbf565b6004810361109d576003808301928781013560e81c919082010160008061107e8b610a2485898d8f61200d565b60009889526020526040909720969097019650909350610dbf92505050565b600681036111a55760008287013560f81c60018401935060ff16905060008784013560f01c60028501945061ffff16905060008885013560e81c600386018162ffffff16915080965081925050506000818601905060008061110b8d8d8d8b908792610a249392919061200d565b9398508893909250905084821061112157988501985b604080517f53657175656e6365206e657374656420636f6e6669673a0a0000000000000000602080830191909152603882018490526058820188905260788083018a90528351808403909101815260989092019092528051910120896111875780611196565b60008a81526020829052604090205b99505050505050505050610dbf565b600581036112115760208201918601358781036111e0577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff94505b60006111eb82611817565b9050846111f85780611207565b60008581526020829052604090205b9450505050610dbf565b6040517fb2505f7c000000000000000000000000000000000000000000000000000000008152600481018290526024016103c0565b50935093915050565b7f8713a7c4465f6fbee2b6e9d6646d1d9f83fec929edfc4baf661f3c865bdd04d160009081526020829052604081206102cb565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fac6a444e00000000000000000000000000000000000000000000000000000000148061131657507fffffffff0000000000000000000000000000000000000000000000000000000082167f36e7817500000000000000000000000000000000000000000000000000000000145b1561132357506001919050565b7f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316146102cb565b6000604282146113ad5782826040517f2ee17a3d0000000000000000000000000000000000000000000000000000000081526004016103c09291906120ca565b60006113c66113bd6001856120de565b85013560f81c90565b60ff169050604084013560f81c843560208601357f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a081111561143a578686826040517fad4aac760000000000000000000000000000000000000000000000000000000081526004016103c0939291906120f1565b8260ff16601b1415801561145257508260ff16601c14155b1561148f578686846040517fe578897e0000000000000000000000000000000000000000000000000000000081526004016103c093929190612115565b600184036114fc576040805160008152602081018083528a905260ff851691810191909152606081018390526080810182905260019060a0015b6020604051602081039080840390855afa1580156114eb573d6000803e3d6000fd5b5050506020604051035194506115d4565b60028403611599576040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101899052600190605c01604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600084529083018083525260ff861690820152606081018490526080810183905260a0016114c9565b86868560016040517f9dfba8520000000000000000000000000000000000000000000000000000000081526004016103c0949392919061213c565b73ffffffffffffffffffffffffffffffffffffffff85166116255786866040517f6c1719d20000000000000000000000000000000000000000000000000000000081526004016103c09291906120ca565b505050509392505050565b600081810361166b576040517fac241e1100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000838361167a6001826120de565b81811061168957611689611e27565b919091013560f81c91505060018114806116a35750600281145b156116e8578473ffffffffffffffffffffffffffffffffffffffff166116ca87868661136d565b73ffffffffffffffffffffffffffffffffffffffff1614915061180e565b600381036117d35773ffffffffffffffffffffffffffffffffffffffff8516631626ba7e878660008761171c6001826120de565b926117299392919061200d565b6040518463ffffffff1660e01b815260040161174793929190612168565b602060405180830381865afa158015611764573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611788919061218b565b7fffffffff00000000000000000000000000000000000000000000000000000000167f1626ba7e0000000000000000000000000000000000000000000000000000000014915061180e565b83838260006040517f9dfba8520000000000000000000000000000000000000000000000000000000081526004016103c0949392919061213c565b50949350505050565b6040517f53657175656e636520737461746963206469676573743a0a0000000000000000602082015260388101829052600090605801610864565b7fffffffff00000000000000000000000000000000000000000000000000000000811681146103d257600080fd5b60006020828403121561189257600080fd5b813561031781611852565b60008083601f8401126118af57600080fd5b50813567ffffffffffffffff8111156118c757600080fd5b6020830191508360208285010111156118df57600080fd5b9250929050565b6000806000604084860312156118fb57600080fd5b83359250602084013567ffffffffffffffff81111561191957600080fd5b6119258682870161189d565b9497909650939450505050565b6000806000806040858703121561194857600080fd5b843567ffffffffffffffff8082111561196057600080fd5b61196c8883890161189d565b9096509450602087013591508082111561198557600080fd5b506119928782880161189d565b95989497509550505050565b6000602082840312156119b057600080fd5b5035919050565b60008083601f8401126119c957600080fd5b50813567ffffffffffffffff8111156119e157600080fd5b6020830191508360208260051b85010111156118df57600080fd5b60008060208385031215611a0f57600080fd5b823567ffffffffffffffff811115611a2657600080fd5b611a32858286016119b7565b90969095509350505050565b600080600080600060608688031215611a5657600080fd5b853567ffffffffffffffff80821115611a6e57600080fd5b611a7a89838a016119b7565b9097509550602088013594506040880135915080821115611a9a57600080fd5b50611aa78882890161189d565b969995985093965092949392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215611af957600080fd5b813567ffffffffffffffff80821115611b1157600080fd5b818401915084601f830112611b2557600080fd5b813581811115611b3757611b37611ab8565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715611b7d57611b7d611ab8565b81604052828152876020848701011115611b9657600080fd5b826020860160208301376000928101602001929092525095945050505050565b8183823760009101908152919050565b80358015158114611bd657600080fd5b919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611bd657600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b81835260006020808501808196508560051b810191508460005b87811015611d8a57828403895281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff41883603018112611ca157600080fd5b870160c0611cae82611bc6565b15158652611cbd878301611bc6565b15158688015260408281013590870152606073ffffffffffffffffffffffffffffffffffffffff611cef828501611bdb565b16908701526080828101359087015260a080830135368490037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1018112611d3557600080fd5b90920187810192903567ffffffffffffffff811115611d5357600080fd5b803603841315611d6257600080fd5b8282890152611d748389018286611bff565b9c89019c97505050928601925050600101611c62565b5091979650505050505050565b60408152600560408201527f73656c663a000000000000000000000000000000000000000000000000000000606082015260806020820152600061037b608083018486611c48565b60408152600660408201527f67756573743a0000000000000000000000000000000000000000000000000000606082015260806020820152600061037b608083018486611c48565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000815180845260005b81811015611e7c57602081850181015186830182015201611e60565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6020815260006103176020830184611e56565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff41833603018112611f0157600080fd5b9190910192915050565b600060208284031215611f1d57600080fd5b61031782611bc6565b600060208284031215611f3857600080fd5b61031782611bdb565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611f7657600080fd5b83018035915067ffffffffffffffff821115611f9157600080fd5b6020019150368190038213156118df57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361200657612006611fa6565b5060010190565b6000808585111561201d57600080fd5b8386111561202a57600080fd5b5050820193919092039150565b808201808211156102cb576102cb611fa6565b60608152600061205e606083018688611bff565b6020830194909452506040015292915050565b82815260406020820152600061037b6040830184611e56565b84815273ffffffffffffffffffffffffffffffffffffffff841660208201526060604082015260006120c0606083018486611bff565b9695505050505050565b60208152600061037b602083018486611bff565b818103818111156102cb576102cb611fa6565b604081526000612105604083018587611bff565b9050826020830152949350505050565b604081526000612129604083018587611bff565b905060ff83166020830152949350505050565b606081526000612150606083018688611bff565b60208301949094525090151560409091015292915050565b838152604060208201526000612182604083018486611bff565b95945050505050565b60006020828403121561219d57600080fd5b81516103178161185256fea26469706673582212209bb95d18e97f278aa47e0c04c20d5a6af9bdb6d473c6d4051192cd96fc17866864736f6c63430008120033", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0xBC JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x61C2926C GT PUSH2 0x74 JUMPI DUP1 PUSH4 0x8C3F5563 GT PUSH2 0x4E JUMPI DUP1 PUSH4 0x8C3F5563 EQ PUSH2 0x253 JUMPI DUP1 PUSH4 0x90042BAF EQ PUSH2 0x273 JUMPI DUP1 PUSH4 0xAFFED0E0 EQ PUSH2 0x2AB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x61C2926C EQ PUSH2 0x1CB JUMPI DUP1 PUSH4 0x7A9A1628 EQ PUSH2 0x1EB JUMPI DUP1 PUSH4 0x853C5068 EQ PUSH2 0x20B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x20C13B0B GT PUSH2 0xA5 JUMPI DUP1 PUSH4 0x20C13B0B EQ PUSH2 0x147 JUMPI DUP1 PUSH4 0x29561426 EQ PUSH2 0x167 JUMPI DUP1 PUSH4 0x57C56D6B EQ PUSH2 0x189 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 PUSH4 0x1FFC9A7 EQ PUSH2 0xC1 JUMPI DUP1 PUSH4 0x1626BA7E EQ PUSH2 0xF6 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0xCD JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0xE1 PUSH2 0xDC CALLDATASIZE PUSH1 0x4 PUSH2 0x1880 JUMP JUMPDEST PUSH2 0x2C0 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x102 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x116 PUSH2 0x111 CALLDATASIZE PUSH1 0x4 PUSH2 0x18E6 JUMP JUMPDEST PUSH2 0x2D1 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xED JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x153 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x116 PUSH2 0x162 CALLDATASIZE PUSH1 0x4 PUSH2 0x1932 JUMP JUMPDEST PUSH2 0x31E JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x173 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x187 PUSH2 0x182 CALLDATASIZE PUSH1 0x4 PUSH2 0x199E JUMP JUMPDEST PUSH2 0x383 JUMP JUMPDEST STOP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x195 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1BD PUSH32 0x8713A7C4465F6FBEE2B6E9D6646D1D9F83FEC929EDFC4BAF661F3C865BDD04D1 DUP2 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xED JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1D7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x187 PUSH2 0x1E6 CALLDATASIZE PUSH1 0x4 PUSH2 0x19FC JUMP JUMPDEST PUSH2 0x3D5 JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x1F7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x187 PUSH2 0x206 CALLDATASIZE PUSH1 0x4 PUSH2 0x1A3E JUMP JUMPDEST PUSH2 0x41A JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x217 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x22B PUSH2 0x226 CALLDATASIZE PUSH1 0x4 PUSH2 0x18E6 JUMP JUMPDEST PUSH2 0x447 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD SWAP6 DUP7 MSTORE PUSH1 0x20 DUP7 ADD SWAP5 SWAP1 SWAP5 MSTORE SWAP3 DUP5 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x60 DUP4 ADD MSTORE PUSH1 0x80 DUP3 ADD MSTORE PUSH1 0xA0 ADD PUSH2 0xED JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x25F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1BD PUSH2 0x26E CALLDATASIZE PUSH1 0x4 PUSH2 0x199E JUMP JUMPDEST PUSH2 0x60F JUMP JUMPDEST PUSH2 0x286 PUSH2 0x281 CALLDATASIZE PUSH1 0x4 PUSH2 0x1AE7 JUMP JUMPDEST PUSH2 0x63B JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0xED JUMP JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x2B7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1BD PUSH2 0x725 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x2CB DUP3 PUSH2 0x736 JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH2 0x2DF DUP6 DUP6 DUP6 PUSH2 0x792 JUMP JUMPDEST POP SWAP1 POP DUP1 ISZERO PUSH2 0x311 JUMPI POP PUSH32 0x1626BA7E00000000000000000000000000000000000000000000000000000000 SWAP1 POP PUSH2 0x317 JUMP JUMPDEST POP PUSH1 0x0 SWAP1 POP JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH2 0x343 DUP7 DUP7 PUSH1 0x40 MLOAD PUSH2 0x334 SWAP3 SWAP2 SWAP1 PUSH2 0x1BB6 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 KECCAK256 DUP6 DUP6 PUSH2 0x792 JUMP JUMPDEST POP SWAP1 POP DUP1 ISZERO PUSH2 0x375 JUMPI POP PUSH32 0x20C13B0B00000000000000000000000000000000000000000000000000000000 SWAP1 POP PUSH2 0x37B JUMP JUMPDEST POP PUSH1 0x0 SWAP1 POP JUMPDEST SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST CALLER ADDRESS EQ PUSH2 0x3C9 JUMPI PUSH1 0x40 MLOAD PUSH32 0xE125889400000000000000000000000000000000000000000000000000000000 DUP2 MSTORE CALLER PUSH1 0x4 DUP3 ADD MSTORE ADDRESS PUSH1 0x24 DUP3 ADD MSTORE PUSH1 0x44 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH2 0x3D2 DUP2 PUSH2 0x7CA JUMP JUMPDEST POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x408 DUP4 DUP4 PUSH1 0x40 MLOAD PUSH1 0x20 ADD PUSH2 0x3ED SWAP3 SWAP2 SWAP1 PUSH2 0x1D97 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE DUP1 MLOAD SWAP1 PUSH1 0x20 ADD KECCAK256 PUSH2 0x7FC JUMP JUMPDEST SWAP1 POP PUSH2 0x415 DUP2 DUP5 DUP5 PUSH2 0x881 JUMP JUMPDEST POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x432 DUP7 DUP7 PUSH1 0x40 MLOAD PUSH1 0x20 ADD PUSH2 0x3ED SWAP3 SWAP2 SWAP1 PUSH2 0x1DDF JUMP JUMPDEST SWAP1 POP PUSH2 0x43F DUP2 DUP8 DUP8 PUSH2 0x881 JUMP JUMPDEST POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 DUP8 DUP8 PUSH1 0x0 DUP2 DUP2 LT PUSH2 0x463 JUMPI PUSH2 0x463 PUSH2 0x1E27 JUMP JUMPDEST SWAP1 SWAP2 ADD CALLDATALOAD PUSH32 0xFF00000000000000000000000000000000000000000000000000000000000000 AND SWAP2 POP DUP2 SWAP1 POP PUSH2 0x4B9 JUMPI PUSH2 0x49B DUP10 PUSH2 0x7FC JUMP JUMPDEST SWAP3 POP PUSH2 0x4A8 DUP4 DUP10 DUP10 PUSH2 0xA0E JUMP JUMPDEST SWAP3 SWAP9 POP SWAP1 SWAP7 POP SWAP5 POP SWAP2 POP PUSH2 0x604 SWAP1 POP JUMP JUMPDEST PUSH32 0xFF00000000000000000000000000000000000000000000000000000000000000 DUP2 DUP2 AND ADD PUSH2 0x4F8 JUMPI PUSH2 0x4EB DUP10 PUSH2 0x7FC JUMP JUMPDEST SWAP3 POP PUSH2 0x4A8 DUP4 DUP10 DUP10 PUSH2 0xA5F JUMP JUMPDEST PUSH32 0xFE00000000000000000000000000000000000000000000000000000000000000 PUSH32 0xFF00000000000000000000000000000000000000000000000000000000000000 DUP3 AND ADD PUSH2 0x54A JUMPI PUSH2 0x4EB DUP10 PUSH2 0xA8B JUMP JUMPDEST PUSH32 0xFD00000000000000000000000000000000000000000000000000000000000000 PUSH32 0xFF00000000000000000000000000000000000000000000000000000000000000 DUP3 AND ADD PUSH2 0x5AE JUMPI PUSH2 0x59E DUP10 DUP10 DUP10 PUSH2 0xAF8 JUMP JUMPDEST SWAP6 POP SWAP6 POP SWAP6 POP SWAP6 POP SWAP6 POP POP PUSH2 0x604 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x6085CD8200000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH32 0xFF00000000000000000000000000000000000000000000000000000000000000 DUP3 AND PUSH1 0x4 DUP3 ADD MSTORE PUSH1 0x24 ADD PUSH2 0x3C0 JUMP JUMPDEST SWAP4 SWAP8 SWAP3 SWAP7 POP SWAP4 POP SWAP4 POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x2CB PUSH32 0x8D0BF1FD623D628C741362C1289948E57B3E2905218C676D3E69ABEE36D6AE2E DUP4 PUSH2 0xC75 JUMP JUMPDEST PUSH1 0x0 CALLER ADDRESS EQ PUSH2 0x67E JUMPI PUSH1 0x40 MLOAD PUSH32 0xE125889400000000000000000000000000000000000000000000000000000000 DUP2 MSTORE CALLER PUSH1 0x4 DUP3 ADD MSTORE ADDRESS PUSH1 0x24 DUP3 ADD MSTORE PUSH1 0x44 ADD PUSH2 0x3C0 JUMP JUMPDEST DUP2 MLOAD PUSH1 0x20 DUP4 ADD CALLVALUE CREATE SWAP1 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND PUSH2 0x6D7 JUMPI DUP2 PUSH1 0x40 MLOAD PUSH32 0xD25719100000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP2 SWAP1 PUSH2 0x1EBA JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 AND DUP2 MSTORE PUSH32 0xA506AD4E7F05ECEBA62A023C3219E5BD98A615F4FA87E2AFB08A2DA5CF62BF0C SWAP1 PUSH1 0x20 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0x731 PUSH1 0x0 PUSH2 0x60F JUMP JUMPDEST SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 PUSH32 0x6FFBD45100000000000000000000000000000000000000000000000000000000 PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP4 AND ADD PUSH2 0x789 JUMPI POP PUSH1 0x1 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH2 0x2CB DUP3 PUSH2 0xCD3 JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH2 0x7A5 DUP9 DUP9 DUP9 PUSH2 0x447 JUMP JUMPDEST POP SWAP7 POP SWAP2 SWAP5 POP SWAP3 POP SWAP1 POP DUP3 DUP3 LT DUP1 ISZERO SWAP1 PUSH2 0x7BD JUMPI POP PUSH1 0x1 JUMPDEST SWAP5 POP POP POP POP SWAP4 POP SWAP4 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0xA038794000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x1901000000000000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE CHAINID PUSH1 0x22 DUP3 ADD MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000 ADDRESS PUSH1 0x60 SHL AND PUSH1 0x42 DUP3 ADD MSTORE PUSH1 0x56 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x0 SWAP1 PUSH1 0x76 ADD JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 DUP4 SUB SUB DUP2 MSTORE SWAP1 PUSH1 0x40 MSTORE DUP1 MLOAD SWAP1 PUSH1 0x20 ADD KECCAK256 SWAP1 POP SWAP2 SWAP1 POP JUMP JUMPDEST DUP1 PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0xA07 JUMPI CALLDATASIZE DUP5 DUP5 DUP4 DUP2 DUP2 LT PUSH2 0x8A0 JUMPI PUSH2 0x8A0 PUSH2 0x1E27 JUMP JUMPDEST SWAP1 POP PUSH1 0x20 MUL DUP2 ADD SWAP1 PUSH2 0x8B2 SWAP2 SWAP1 PUSH2 0x1ECD JUMP JUMPDEST SWAP1 POP PUSH2 0x8C1 PUSH1 0x20 DUP3 ADD DUP3 PUSH2 0x1F0B JUMP JUMPDEST ISZERO PUSH2 0x8FB JUMPI PUSH1 0x40 MLOAD PUSH32 0x230D1CCC00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 DUP2 ADD DUP4 SWAP1 MSTORE PUSH1 0x24 ADD PUSH2 0x3C0 JUMP JUMPDEST PUSH1 0x40 DUP2 ADD CALLDATALOAD DUP1 GAS LT ISZERO PUSH2 0x94E JUMPI DUP3 DUP2 GAS PUSH1 0x40 MLOAD PUSH32 0x2BB3E3BA00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 DUP2 ADD SWAP4 SWAP1 SWAP4 MSTORE PUSH1 0x24 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x44 DUP3 ADD MSTORE PUSH1 0x64 ADD PUSH2 0x3C0 JUMP JUMPDEST PUSH1 0x0 PUSH2 0x988 PUSH2 0x963 PUSH1 0x80 DUP6 ADD PUSH1 0x60 DUP7 ADD PUSH2 0x1F26 JUMP JUMPDEST PUSH1 0x80 DUP6 ADD CALLDATALOAD DUP5 ISZERO PUSH2 0x974 JUMPI DUP5 PUSH2 0x976 JUMP JUMPDEST GAS JUMPDEST PUSH2 0x983 PUSH1 0xA0 DUP9 ADD DUP9 PUSH2 0x1F41 JUMP JUMPDEST PUSH2 0xD2F JUMP JUMPDEST SWAP1 POP DUP1 ISZERO PUSH2 0x9CF JUMPI DUP8 PUSH32 0x5C4EEB02DABF8976016AB414D617F9A162936DCACE3CDEF8C69EF6E262AD5AE7 DUP6 PUSH1 0x40 MLOAD PUSH2 0x9C2 SWAP2 DUP2 MSTORE PUSH1 0x20 ADD SWAP1 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG2 PUSH2 0x9F1 JUMP JUMPDEST PUSH2 0x9F1 PUSH2 0x9E2 PUSH1 0x40 DUP6 ADD PUSH1 0x20 DUP7 ADD PUSH2 0x1F0B JUMP JUMPDEST DUP10 DUP7 PUSH2 0x9EC PUSH2 0xD4C JUMP JUMPDEST PUSH2 0xD6B JUMP JUMPDEST POP POP POP DUP1 DUP1 PUSH2 0x9FF SWAP1 PUSH2 0x1FD5 JUMP JUMPDEST SWAP2 POP POP PUSH2 0x885 JUMP JUMPDEST POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP1 DUP1 PUSH2 0xA29 DUP8 PUSH2 0xA24 DUP8 PUSH1 0x6 DUP2 DUP12 PUSH2 0x200D JUMP JUMPDEST PUSH2 0xDB9 JUMP JUMPDEST PUSH1 0x0 SWAP1 DUP2 MSTORE DUP8 CALLDATALOAD PUSH1 0xF0 SHR PUSH1 0x20 DUP2 DUP2 MSTORE PUSH1 0x40 DUP1 DUP5 KECCAK256 DUP5 MSTORE PUSH1 0x2 SWAP1 SWAP11 ADD CALLDATALOAD PUSH1 0xE0 SHR SWAP1 DUP2 SWAP1 MSTORE SWAP9 SWAP1 SWAP2 KECCAK256 SWAP1 SWAP10 SWAP2 SWAP9 POP SWAP7 SWAP6 POP SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP1 DUP1 PUSH2 0xA7A DUP8 PUSH2 0xA75 DUP8 PUSH1 0x1 DUP2 DUP12 PUSH2 0x200D JUMP JUMPDEST PUSH2 0xA0E JUMP JUMPDEST SWAP4 POP SWAP4 POP SWAP4 POP SWAP4 POP SWAP4 POP SWAP4 POP SWAP4 POP SWAP4 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x1901000000000000000000000000000000000000000000000000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x0 PUSH1 0x22 DUP3 ADD DUP2 SWAP1 MSTORE PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000 ADDRESS PUSH1 0x60 SHL AND PUSH1 0x42 DUP4 ADD MSTORE PUSH1 0x56 DUP3 ADD DUP4 SWAP1 MSTORE SWAP1 PUSH1 0x76 ADD PUSH2 0x864 JUMP JUMPDEST PUSH1 0x0 DUP1 DUP1 DUP1 DUP1 PUSH1 0x4 PUSH1 0x1 DUP9 ADD CALLDATALOAD PUSH1 0xE8 SHR DUP3 PUSH2 0xB13 DUP4 DUP4 PUSH2 0x2037 JUMP JUMPDEST SWAP1 POP PUSH2 0xB25 DUP12 PUSH2 0x226 DUP4 DUP7 DUP14 DUP16 PUSH2 0x200D JUMP JUMPDEST SWAP4 SWAP12 POP SWAP2 SWAP10 POP SWAP8 POP SWAP6 POP SWAP4 POP DUP8 DUP8 LT ISZERO PUSH2 0xB7D JUMPI PUSH2 0xB45 DUP2 DUP5 DUP12 DUP14 PUSH2 0x200D JUMP JUMPDEST DUP10 DUP10 PUSH1 0x40 MLOAD PUSH32 0xB006ABA000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x204A JUMP JUMPDEST DUP1 SWAP3 POP JUMPDEST DUP9 DUP4 LT ISZERO PUSH2 0xC67 JUMPI PUSH1 0x3 DUP4 ADD SWAP3 DUP11 ADD CALLDATALOAD PUSH1 0xE8 SHR SWAP2 POP PUSH2 0xBA0 DUP4 DUP4 PUSH2 0x2037 JUMP JUMPDEST SWAP1 POP PUSH1 0x0 PUSH2 0xBC2 PUSH2 0xBB0 DUP9 PUSH2 0x124F JUMP JUMPDEST DUP13 DUP13 DUP8 SWAP1 DUP7 SWAP3 PUSH2 0x226 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x200D JUMP JUMPDEST SWAP4 SWAP13 POP SWAP2 SWAP11 POP SWAP9 POP SWAP1 SWAP2 POP POP DUP9 DUP9 LT ISZERO PUSH2 0xC1A JUMPI PUSH2 0xBE2 DUP3 DUP6 DUP13 DUP15 PUSH2 0x200D JUMP JUMPDEST DUP11 DUP11 PUSH1 0x40 MLOAD PUSH32 0xB006ABA000000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x204A JUMP JUMPDEST DUP5 DUP2 LT PUSH2 0xC5D JUMPI PUSH1 0x40 MLOAD PUSH32 0x37DAF62B00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x24 DUP2 ADD DUP7 SWAP1 MSTORE PUSH1 0x44 ADD PUSH2 0x3C0 JUMP JUMPDEST SWAP4 POP SWAP2 POP DUP2 PUSH2 0xB81 JUMP JUMPDEST POP POP POP SWAP4 SWAP8 SWAP3 SWAP7 POP SWAP4 POP SWAP4 POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 DUP4 PUSH1 0x40 MLOAD PUSH1 0x20 ADD PUSH2 0xC94 SWAP3 SWAP2 SWAP1 SWAP2 DUP3 MSTORE PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP2 DUP5 SUB ADD DUP2 MSTORE SWAP2 SWAP1 MSTORE DUP1 MLOAD PUSH1 0x20 SWAP1 SWAP2 ADD KECCAK256 SLOAD SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH32 0xE4A77BBC00000000000000000000000000000000000000000000000000000000 PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP4 AND ADD PUSH2 0xD26 JUMPI POP PUSH1 0x1 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH2 0x2CB DUP3 PUSH2 0x1283 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x40 MLOAD DUP3 DUP5 DUP3 CALLDATACOPY PUSH1 0x0 DUP1 DUP5 DUP4 DUP10 DUP12 DUP11 CALL SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x60 RETURNDATASIZE PUSH1 0x40 MLOAD SWAP2 POP PUSH1 0x20 DUP3 ADD DUP2 DUP2 ADD PUSH1 0x40 MSTORE DUP2 DUP4 MSTORE DUP2 PUSH1 0x0 DUP3 RETURNDATACOPY POP POP SWAP1 JUMP JUMPDEST DUP4 ISZERO PUSH2 0xD79 JUMPI DUP1 MLOAD PUSH1 0x20 DUP3 ADD REVERT JUMPDEST DUP3 PUSH32 0xAB46C69F7F32E1BF09B0725853DA82A211E5402A0600296AB499A2FB5EA3B419 DUP4 DUP4 PUSH1 0x40 MLOAD PUSH2 0xDAB SWAP3 SWAP2 SWAP1 PUSH2 0x2071 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG2 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x1246 JUMPI PUSH1 0x1 DUP2 ADD SWAP1 DUP6 ADD CALLDATALOAD PUSH1 0xF8 SHR PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 ADD PUSH2 0xE60 JUMPI PUSH1 0x15 DUP3 ADD SWAP2 DUP7 ADD CALLDATALOAD PUSH1 0xF8 DUP2 SWAP1 SHR SWAP1 PUSH1 0x58 SHR PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND SWAP1 PUSH21 0xFF0000000000000000000000000000000000000000 AND DUP2 OR DUP6 PUSH2 0xE46 JUMPI DUP1 PUSH2 0xE55 JUMP JUMPDEST PUSH1 0x0 DUP7 DUP2 MSTORE PUSH1 0x20 DUP3 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 JUMPDEST SWAP6 POP POP POP POP POP PUSH2 0xDBF JUMP JUMPDEST DUP1 PUSH2 0xEF6 JUMPI PUSH1 0x1 DUP3 ADD SWAP2 DUP7 DUP2 ADD CALLDATALOAD PUSH1 0xF8 SHR SWAP1 PUSH1 0x43 ADD PUSH1 0x0 PUSH2 0xE8C DUP11 PUSH2 0xE87 DUP5 DUP9 DUP13 DUP15 PUSH2 0x200D JUMP JUMPDEST PUSH2 0x136D JUMP JUMPDEST PUSH1 0xFF DUP5 AND SWAP8 SWAP1 SWAP8 ADD SWAP7 SWAP2 SWAP5 POP DUP5 SWAP2 SWAP1 POP PUSH1 0xA0 DUP4 SWAP1 SHL PUSH21 0xFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 AND OR DUP7 PUSH2 0xEDB JUMPI DUP1 PUSH2 0xEEA JUMP JUMPDEST PUSH1 0x0 DUP8 DUP2 MSTORE PUSH1 0x20 DUP3 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 JUMPDEST SWAP7 POP POP POP POP POP POP PUSH2 0xDBF JUMP JUMPDEST PUSH1 0x2 DUP2 SUB PUSH2 0x101E JUMPI PUSH1 0x0 DUP1 DUP8 DUP5 ADD CALLDATALOAD PUSH1 0xF8 DUP2 SWAP1 SHR SWAP1 PUSH1 0x58 SHR PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH1 0x15 DUP7 ADD SWAP6 POP SWAP1 SWAP3 POP SWAP1 POP PUSH1 0x0 DUP9 DUP6 ADD CALLDATALOAD PUSH1 0xE8 SHR PUSH1 0x3 DUP7 ADD DUP2 PUSH3 0xFFFFFF AND SWAP2 POP DUP1 SWAP7 POP DUP2 SWAP3 POP POP POP PUSH1 0x0 DUP2 DUP7 ADD SWAP1 POP PUSH2 0xF6F DUP12 DUP5 DUP13 DUP13 DUP11 SWAP1 DUP7 SWAP3 PUSH2 0xF6A SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x200D JUMP JUMPDEST PUSH2 0x1630 JUMP JUMPDEST PUSH2 0xFB7 JUMPI DUP11 DUP4 PUSH2 0xF81 DUP4 DUP10 DUP14 DUP16 PUSH2 0x200D JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x9A94623200000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x208A JUMP JUMPDEST PUSH1 0xFF DUP5 AND SWAP8 SWAP1 SWAP8 ADD SWAP7 SWAP5 POP DUP5 PUSH1 0xA0 DUP5 SWAP1 SHL PUSH21 0xFF0000000000000000000000000000000000000000 AND PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP5 AND OR DUP8 PUSH2 0x1002 JUMPI DUP1 PUSH2 0x1011 JUMP JUMPDEST PUSH1 0x0 DUP9 DUP2 MSTORE PUSH1 0x20 DUP3 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 JUMPDEST SWAP8 POP POP POP POP POP POP POP PUSH2 0xDBF JUMP JUMPDEST PUSH1 0x3 DUP2 SUB PUSH2 0x1051 JUMPI PUSH1 0x20 DUP3 ADD SWAP2 DUP7 ADD CALLDATALOAD DUP4 PUSH2 0x1039 JUMPI DUP1 PUSH2 0x1048 JUMP JUMPDEST PUSH1 0x0 DUP5 DUP2 MSTORE PUSH1 0x20 DUP3 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 JUMPDEST SWAP4 POP POP POP PUSH2 0xDBF JUMP JUMPDEST PUSH1 0x4 DUP2 SUB PUSH2 0x109D JUMPI PUSH1 0x3 DUP1 DUP4 ADD SWAP3 DUP8 DUP2 ADD CALLDATALOAD PUSH1 0xE8 SHR SWAP2 SWAP1 DUP3 ADD ADD PUSH1 0x0 DUP1 PUSH2 0x107E DUP12 PUSH2 0xA24 DUP6 DUP10 DUP14 DUP16 PUSH2 0x200D JUMP JUMPDEST PUSH1 0x0 SWAP9 DUP10 MSTORE PUSH1 0x20 MSTORE PUSH1 0x40 SWAP1 SWAP8 KECCAK256 SWAP7 SWAP1 SWAP8 ADD SWAP7 POP SWAP1 SWAP4 POP PUSH2 0xDBF SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x6 DUP2 SUB PUSH2 0x11A5 JUMPI PUSH1 0x0 DUP3 DUP8 ADD CALLDATALOAD PUSH1 0xF8 SHR PUSH1 0x1 DUP5 ADD SWAP4 POP PUSH1 0xFF AND SWAP1 POP PUSH1 0x0 DUP8 DUP5 ADD CALLDATALOAD PUSH1 0xF0 SHR PUSH1 0x2 DUP6 ADD SWAP5 POP PUSH2 0xFFFF AND SWAP1 POP PUSH1 0x0 DUP9 DUP6 ADD CALLDATALOAD PUSH1 0xE8 SHR PUSH1 0x3 DUP7 ADD DUP2 PUSH3 0xFFFFFF AND SWAP2 POP DUP1 SWAP7 POP DUP2 SWAP3 POP POP POP PUSH1 0x0 DUP2 DUP7 ADD SWAP1 POP PUSH1 0x0 DUP1 PUSH2 0x110B DUP14 DUP14 DUP14 DUP12 SWAP1 DUP8 SWAP3 PUSH2 0xA24 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x200D JUMP JUMPDEST SWAP4 SWAP9 POP DUP9 SWAP4 SWAP1 SWAP3 POP SWAP1 POP DUP5 DUP3 LT PUSH2 0x1121 JUMPI SWAP9 DUP6 ADD SWAP9 JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0x53657175656E6365206E657374656420636F6E6669673A0A0000000000000000 PUSH1 0x20 DUP1 DUP4 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x38 DUP3 ADD DUP5 SWAP1 MSTORE PUSH1 0x58 DUP3 ADD DUP9 SWAP1 MSTORE PUSH1 0x78 DUP1 DUP4 ADD DUP11 SWAP1 MSTORE DUP4 MLOAD DUP1 DUP5 SUB SWAP1 SWAP2 ADD DUP2 MSTORE PUSH1 0x98 SWAP1 SWAP3 ADD SWAP1 SWAP3 MSTORE DUP1 MLOAD SWAP2 ADD KECCAK256 DUP10 PUSH2 0x1187 JUMPI DUP1 PUSH2 0x1196 JUMP JUMPDEST PUSH1 0x0 DUP11 DUP2 MSTORE PUSH1 0x20 DUP3 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 JUMPDEST SWAP10 POP POP POP POP POP POP POP POP POP PUSH2 0xDBF JUMP JUMPDEST PUSH1 0x5 DUP2 SUB PUSH2 0x1211 JUMPI PUSH1 0x20 DUP3 ADD SWAP2 DUP7 ADD CALLDATALOAD DUP8 DUP2 SUB PUSH2 0x11E0 JUMPI PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP5 POP JUMPDEST PUSH1 0x0 PUSH2 0x11EB DUP3 PUSH2 0x1817 JUMP JUMPDEST SWAP1 POP DUP5 PUSH2 0x11F8 JUMPI DUP1 PUSH2 0x1207 JUMP JUMPDEST PUSH1 0x0 DUP6 DUP2 MSTORE PUSH1 0x20 DUP3 SWAP1 MSTORE PUSH1 0x40 SWAP1 KECCAK256 JUMPDEST SWAP5 POP POP POP POP PUSH2 0xDBF JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0xB2505F7C00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x24 ADD PUSH2 0x3C0 JUMP JUMPDEST POP SWAP4 POP SWAP4 SWAP2 POP POP JUMP JUMPDEST PUSH32 0x8713A7C4465F6FBEE2B6E9D6646D1D9F83FEC929EDFC4BAF661F3C865BDD04D1 PUSH1 0x0 SWAP1 DUP2 MSTORE PUSH1 0x20 DUP3 SWAP1 MSTORE PUSH1 0x40 DUP2 KECCAK256 PUSH2 0x2CB JUMP JUMPDEST PUSH1 0x0 PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP3 AND PUSH32 0xAC6A444E00000000000000000000000000000000000000000000000000000000 EQ DUP1 PUSH2 0x1316 JUMPI POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP3 AND PUSH32 0x36E7817500000000000000000000000000000000000000000000000000000000 EQ JUMPDEST ISZERO PUSH2 0x1323 JUMPI POP PUSH1 0x1 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH32 0x1FFC9A700000000000000000000000000000000000000000000000000000000 PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP4 AND EQ PUSH2 0x2CB JUMP JUMPDEST PUSH1 0x0 PUSH1 0x42 DUP3 EQ PUSH2 0x13AD JUMPI DUP3 DUP3 PUSH1 0x40 MLOAD PUSH32 0x2EE17A3D00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP3 SWAP2 SWAP1 PUSH2 0x20CA JUMP JUMPDEST PUSH1 0x0 PUSH2 0x13C6 PUSH2 0x13BD PUSH1 0x1 DUP6 PUSH2 0x20DE JUMP JUMPDEST DUP6 ADD CALLDATALOAD PUSH1 0xF8 SHR SWAP1 JUMP JUMPDEST PUSH1 0xFF AND SWAP1 POP PUSH1 0x40 DUP5 ADD CALLDATALOAD PUSH1 0xF8 SHR DUP5 CALLDATALOAD PUSH1 0x20 DUP7 ADD CALLDATALOAD PUSH32 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 DUP2 GT ISZERO PUSH2 0x143A JUMPI DUP7 DUP7 DUP3 PUSH1 0x40 MLOAD PUSH32 0xAD4AAC7600000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x20F1 JUMP JUMPDEST DUP3 PUSH1 0xFF AND PUSH1 0x1B EQ ISZERO DUP1 ISZERO PUSH2 0x1452 JUMPI POP DUP3 PUSH1 0xFF AND PUSH1 0x1C EQ ISZERO JUMPDEST ISZERO PUSH2 0x148F JUMPI DUP7 DUP7 DUP5 PUSH1 0x40 MLOAD PUSH32 0xE578897E00000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x2115 JUMP JUMPDEST PUSH1 0x1 DUP5 SUB PUSH2 0x14FC JUMPI PUSH1 0x40 DUP1 MLOAD PUSH1 0x0 DUP2 MSTORE PUSH1 0x20 DUP2 ADD DUP1 DUP4 MSTORE DUP11 SWAP1 MSTORE PUSH1 0xFF DUP6 AND SWAP2 DUP2 ADD SWAP2 SWAP1 SWAP2 MSTORE PUSH1 0x60 DUP2 ADD DUP4 SWAP1 MSTORE PUSH1 0x80 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x1 SWAP1 PUSH1 0xA0 ADD JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD PUSH1 0x20 DUP2 SUB SWAP1 DUP1 DUP5 SUB SWAP1 DUP6 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x14EB JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP PUSH1 0x20 PUSH1 0x40 MLOAD SUB MLOAD SWAP5 POP PUSH2 0x15D4 JUMP JUMPDEST PUSH1 0x2 DUP5 SUB PUSH2 0x1599 JUMPI PUSH1 0x40 MLOAD PUSH32 0x19457468657265756D205369676E6564204D6573736167653A0A333200000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x3C DUP2 ADD DUP10 SWAP1 MSTORE PUSH1 0x1 SWAP1 PUSH1 0x5C ADD PUSH1 0x40 DUP1 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP2 DUP5 SUB ADD DUP2 MSTORE DUP3 DUP3 MSTORE DUP1 MLOAD PUSH1 0x20 SWAP2 DUP3 ADD KECCAK256 PUSH1 0x0 DUP5 MSTORE SWAP1 DUP4 ADD DUP1 DUP4 MSTORE MSTORE PUSH1 0xFF DUP7 AND SWAP1 DUP3 ADD MSTORE PUSH1 0x60 DUP2 ADD DUP5 SWAP1 MSTORE PUSH1 0x80 DUP2 ADD DUP4 SWAP1 MSTORE PUSH1 0xA0 ADD PUSH2 0x14C9 JUMP JUMPDEST DUP7 DUP7 DUP6 PUSH1 0x1 PUSH1 0x40 MLOAD PUSH32 0x9DFBA85200000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x213C JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP6 AND PUSH2 0x1625 JUMPI DUP7 DUP7 PUSH1 0x40 MLOAD PUSH32 0x6C1719D200000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP3 SWAP2 SWAP1 PUSH2 0x20CA JUMP JUMPDEST POP POP POP POP SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP2 DUP2 SUB PUSH2 0x166B JUMPI PUSH1 0x40 MLOAD PUSH32 0xAC241E1100000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST PUSH1 0x0 DUP4 DUP4 PUSH2 0x167A PUSH1 0x1 DUP3 PUSH2 0x20DE JUMP JUMPDEST DUP2 DUP2 LT PUSH2 0x1689 JUMPI PUSH2 0x1689 PUSH2 0x1E27 JUMP JUMPDEST SWAP2 SWAP1 SWAP2 ADD CALLDATALOAD PUSH1 0xF8 SHR SWAP2 POP POP PUSH1 0x1 DUP2 EQ DUP1 PUSH2 0x16A3 JUMPI POP PUSH1 0x2 DUP2 EQ JUMPDEST ISZERO PUSH2 0x16E8 JUMPI DUP5 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND PUSH2 0x16CA DUP8 DUP7 DUP7 PUSH2 0x136D JUMP JUMPDEST PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AND EQ SWAP2 POP PUSH2 0x180E JUMP JUMPDEST PUSH1 0x3 DUP2 SUB PUSH2 0x17D3 JUMPI PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP6 AND PUSH4 0x1626BA7E DUP8 DUP7 PUSH1 0x0 DUP8 PUSH2 0x171C PUSH1 0x1 DUP3 PUSH2 0x20DE JUMP JUMPDEST SWAP3 PUSH2 0x1729 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x200D JUMP JUMPDEST PUSH1 0x40 MLOAD DUP5 PUSH4 0xFFFFFFFF AND PUSH1 0xE0 SHL DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x1747 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x2168 JUMP JUMPDEST PUSH1 0x20 PUSH1 0x40 MLOAD DUP1 DUP4 SUB DUP2 DUP7 GAS STATICCALL ISZERO DUP1 ISZERO PUSH2 0x1764 JUMPI RETURNDATASIZE PUSH1 0x0 DUP1 RETURNDATACOPY RETURNDATASIZE PUSH1 0x0 REVERT JUMPDEST POP POP POP POP PUSH1 0x40 MLOAD RETURNDATASIZE PUSH1 0x1F NOT PUSH1 0x1F DUP3 ADD AND DUP3 ADD DUP1 PUSH1 0x40 MSTORE POP DUP2 ADD SWAP1 PUSH2 0x1788 SWAP2 SWAP1 PUSH2 0x218B JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND PUSH32 0x1626BA7E00000000000000000000000000000000000000000000000000000000 EQ SWAP2 POP PUSH2 0x180E JUMP JUMPDEST DUP4 DUP4 DUP3 PUSH1 0x0 PUSH1 0x40 MLOAD PUSH32 0x9DFBA85200000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x3C0 SWAP5 SWAP4 SWAP3 SWAP2 SWAP1 PUSH2 0x213C JUMP JUMPDEST POP SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH32 0x53657175656E636520737461746963206469676573743A0A0000000000000000 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x38 DUP2 ADD DUP3 SWAP1 MSTORE PUSH1 0x0 SWAP1 PUSH1 0x58 ADD PUSH2 0x864 JUMP JUMPDEST PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND DUP2 EQ PUSH2 0x3D2 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1892 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH2 0x317 DUP2 PUSH2 0x1852 JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 PUSH1 0x1F DUP5 ADD SLT PUSH2 0x18AF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x18C7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 DUP4 ADD SWAP2 POP DUP4 PUSH1 0x20 DUP3 DUP6 ADD ADD GT ISZERO PUSH2 0x18DF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP3 POP SWAP3 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x40 DUP5 DUP7 SUB SLT ISZERO PUSH2 0x18FB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 CALLDATALOAD SWAP3 POP PUSH1 0x20 DUP5 ADD CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x1919 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x1925 DUP7 DUP3 DUP8 ADD PUSH2 0x189D JUMP JUMPDEST SWAP5 SWAP8 SWAP1 SWAP7 POP SWAP4 SWAP5 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x40 DUP6 DUP8 SUB SLT ISZERO PUSH2 0x1948 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP5 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0x1960 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x196C DUP9 DUP4 DUP10 ADD PUSH2 0x189D JUMP JUMPDEST SWAP1 SWAP7 POP SWAP5 POP PUSH1 0x20 DUP8 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0x1985 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1992 DUP8 DUP3 DUP9 ADD PUSH2 0x189D JUMP JUMPDEST SWAP6 SWAP9 SWAP5 SWAP8 POP SWAP6 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x19B0 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP CALLDATALOAD SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 PUSH1 0x1F DUP5 ADD SLT PUSH2 0x19C9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x19E1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 DUP4 ADD SWAP2 POP DUP4 PUSH1 0x20 DUP3 PUSH1 0x5 SHL DUP6 ADD ADD GT ISZERO PUSH2 0x18DF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x20 DUP4 DUP6 SUB SLT ISZERO PUSH2 0x1A0F JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x1A26 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x1A32 DUP6 DUP3 DUP7 ADD PUSH2 0x19B7 JUMP JUMPDEST SWAP1 SWAP7 SWAP1 SWAP6 POP SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 DUP1 PUSH1 0x0 DUP1 PUSH1 0x0 PUSH1 0x60 DUP7 DUP9 SUB SLT ISZERO PUSH2 0x1A56 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP6 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0x1A6E JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x1A7A DUP10 DUP4 DUP11 ADD PUSH2 0x19B7 JUMP JUMPDEST SWAP1 SWAP8 POP SWAP6 POP PUSH1 0x20 DUP9 ADD CALLDATALOAD SWAP5 POP PUSH1 0x40 DUP9 ADD CALLDATALOAD SWAP2 POP DUP1 DUP3 GT ISZERO PUSH2 0x1A9A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x1AA7 DUP9 DUP3 DUP10 ADD PUSH2 0x189D JUMP JUMPDEST SWAP7 SWAP10 SWAP6 SWAP9 POP SWAP4 SWAP7 POP SWAP3 SWAP5 SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH32 0x4E487B7100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 MSTORE PUSH1 0x41 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1AF9 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0x1B11 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 DUP5 ADD SWAP2 POP DUP5 PUSH1 0x1F DUP4 ADD SLT PUSH2 0x1B25 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD DUP2 DUP2 GT ISZERO PUSH2 0x1B37 JUMPI PUSH2 0x1B37 PUSH2 0x1AB8 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1F DUP3 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 DUP2 AND PUSH1 0x3F ADD AND DUP2 ADD SWAP1 DUP4 DUP3 GT DUP2 DUP4 LT OR ISZERO PUSH2 0x1B7D JUMPI PUSH2 0x1B7D PUSH2 0x1AB8 JUMP JUMPDEST DUP2 PUSH1 0x40 MSTORE DUP3 DUP2 MSTORE DUP8 PUSH1 0x20 DUP5 DUP8 ADD ADD GT ISZERO PUSH2 0x1B96 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP4 ADD CALLDATACOPY PUSH1 0x0 SWAP3 DUP2 ADD PUSH1 0x20 ADD SWAP3 SWAP1 SWAP3 MSTORE POP SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST DUP2 DUP4 DUP3 CALLDATACOPY PUSH1 0x0 SWAP2 ADD SWAP1 DUP2 MSTORE SWAP2 SWAP1 POP JUMP JUMPDEST DUP1 CALLDATALOAD DUP1 ISZERO ISZERO DUP2 EQ PUSH2 0x1BD6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP2 SWAP1 POP JUMP JUMPDEST DUP1 CALLDATALOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND DUP2 EQ PUSH2 0x1BD6 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 DUP4 MSTORE DUP2 DUP2 PUSH1 0x20 DUP6 ADD CALLDATACOPY POP PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 ADD ADD MSTORE PUSH1 0x0 PUSH1 0x20 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 PUSH1 0x1F DUP5 ADD AND DUP5 ADD ADD SWAP1 POP SWAP3 SWAP2 POP POP JUMP JUMPDEST DUP2 DUP4 MSTORE PUSH1 0x0 PUSH1 0x20 DUP1 DUP6 ADD DUP1 DUP2 SWAP7 POP DUP6 PUSH1 0x5 SHL DUP2 ADD SWAP2 POP DUP5 PUSH1 0x0 JUMPDEST DUP8 DUP2 LT ISZERO PUSH2 0x1D8A JUMPI DUP3 DUP5 SUB DUP10 MSTORE DUP2 CALLDATALOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 DUP9 CALLDATASIZE SUB ADD DUP2 SLT PUSH2 0x1CA1 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP8 ADD PUSH1 0xC0 PUSH2 0x1CAE DUP3 PUSH2 0x1BC6 JUMP JUMPDEST ISZERO ISZERO DUP7 MSTORE PUSH2 0x1CBD DUP8 DUP4 ADD PUSH2 0x1BC6 JUMP JUMPDEST ISZERO ISZERO DUP7 DUP9 ADD MSTORE PUSH1 0x40 DUP3 DUP2 ADD CALLDATALOAD SWAP1 DUP8 ADD MSTORE PUSH1 0x60 PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF PUSH2 0x1CEF DUP3 DUP6 ADD PUSH2 0x1BDB JUMP JUMPDEST AND SWAP1 DUP8 ADD MSTORE PUSH1 0x80 DUP3 DUP2 ADD CALLDATALOAD SWAP1 DUP8 ADD MSTORE PUSH1 0xA0 DUP1 DUP4 ADD CALLDATALOAD CALLDATASIZE DUP5 SWAP1 SUB PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 ADD DUP2 SLT PUSH2 0x1D35 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP1 SWAP3 ADD DUP8 DUP2 ADD SWAP3 SWAP1 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP2 GT ISZERO PUSH2 0x1D53 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP1 CALLDATASIZE SUB DUP5 SGT ISZERO PUSH2 0x1D62 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 DUP3 DUP10 ADD MSTORE PUSH2 0x1D74 DUP4 DUP10 ADD DUP3 DUP7 PUSH2 0x1BFF JUMP JUMPDEST SWAP13 DUP10 ADD SWAP13 SWAP8 POP POP POP SWAP3 DUP7 ADD SWAP3 POP POP PUSH1 0x1 ADD PUSH2 0x1C62 JUMP JUMPDEST POP SWAP2 SWAP8 SWAP7 POP POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP2 MSTORE PUSH1 0x5 PUSH1 0x40 DUP3 ADD MSTORE PUSH32 0x73656C663A000000000000000000000000000000000000000000000000000000 PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x0 PUSH2 0x37B PUSH1 0x80 DUP4 ADD DUP5 DUP7 PUSH2 0x1C48 JUMP JUMPDEST PUSH1 0x40 DUP2 MSTORE PUSH1 0x6 PUSH1 0x40 DUP3 ADD MSTORE PUSH32 0x67756573743A0000000000000000000000000000000000000000000000000000 PUSH1 0x60 DUP3 ADD MSTORE PUSH1 0x80 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x0 PUSH2 0x37B PUSH1 0x80 DUP4 ADD DUP5 DUP7 PUSH2 0x1C48 JUMP JUMPDEST PUSH32 0x4E487B7100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 MSTORE PUSH1 0x32 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 DUP2 MLOAD DUP1 DUP5 MSTORE PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0x1E7C JUMPI PUSH1 0x20 DUP2 DUP6 ADD DUP2 ADD MLOAD DUP7 DUP4 ADD DUP3 ADD MSTORE ADD PUSH2 0x1E60 JUMP JUMPDEST POP PUSH1 0x0 PUSH1 0x20 DUP3 DUP7 ADD ADD MSTORE PUSH1 0x20 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 PUSH1 0x1F DUP4 ADD AND DUP6 ADD ADD SWAP2 POP POP SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x20 DUP2 MSTORE PUSH1 0x0 PUSH2 0x317 PUSH1 0x20 DUP4 ADD DUP5 PUSH2 0x1E56 JUMP JUMPDEST PUSH1 0x0 DUP3 CALLDATALOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41 DUP4 CALLDATASIZE SUB ADD DUP2 SLT PUSH2 0x1F01 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP2 SWAP1 SWAP2 ADD SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1F1D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x317 DUP3 PUSH2 0x1BC6 JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x1F38 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x317 DUP3 PUSH2 0x1BDB JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 CALLDATALOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 DUP5 CALLDATASIZE SUB ADD DUP2 SLT PUSH2 0x1F76 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 ADD DUP1 CALLDATALOAD SWAP2 POP PUSH8 0xFFFFFFFFFFFFFFFF DUP3 GT ISZERO PUSH2 0x1F91 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH1 0x20 ADD SWAP2 POP CALLDATASIZE DUP2 SWAP1 SUB DUP3 SGT ISZERO PUSH2 0x18DF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH32 0x4E487B7100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 MSTORE PUSH1 0x11 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 SUB PUSH2 0x2006 JUMPI PUSH2 0x2006 PUSH2 0x1FA6 JUMP JUMPDEST POP PUSH1 0x1 ADD SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 DUP6 DUP6 GT ISZERO PUSH2 0x201D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP4 DUP7 GT ISZERO PUSH2 0x202A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP POP DUP3 ADD SWAP4 SWAP2 SWAP1 SWAP3 SUB SWAP2 POP JUMP JUMPDEST DUP1 DUP3 ADD DUP1 DUP3 GT ISZERO PUSH2 0x2CB JUMPI PUSH2 0x2CB PUSH2 0x1FA6 JUMP JUMPDEST PUSH1 0x60 DUP2 MSTORE PUSH1 0x0 PUSH2 0x205E PUSH1 0x60 DUP4 ADD DUP7 DUP9 PUSH2 0x1BFF JUMP JUMPDEST PUSH1 0x20 DUP4 ADD SWAP5 SWAP1 SWAP5 MSTORE POP PUSH1 0x40 ADD MSTORE SWAP3 SWAP2 POP POP JUMP JUMPDEST DUP3 DUP2 MSTORE PUSH1 0x40 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x0 PUSH2 0x37B PUSH1 0x40 DUP4 ADD DUP5 PUSH2 0x1E56 JUMP JUMPDEST DUP5 DUP2 MSTORE PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP5 AND PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x60 PUSH1 0x40 DUP3 ADD MSTORE PUSH1 0x0 PUSH2 0x20C0 PUSH1 0x60 DUP4 ADD DUP5 DUP7 PUSH2 0x1BFF JUMP JUMPDEST SWAP7 SWAP6 POP POP POP POP POP POP JUMP JUMPDEST PUSH1 0x20 DUP2 MSTORE PUSH1 0x0 PUSH2 0x37B PUSH1 0x20 DUP4 ADD DUP5 DUP7 PUSH2 0x1BFF JUMP JUMPDEST DUP2 DUP2 SUB DUP2 DUP2 GT ISZERO PUSH2 0x2CB JUMPI PUSH2 0x2CB PUSH2 0x1FA6 JUMP JUMPDEST PUSH1 0x40 DUP2 MSTORE PUSH1 0x0 PUSH2 0x2105 PUSH1 0x40 DUP4 ADD DUP6 DUP8 PUSH2 0x1BFF JUMP JUMPDEST SWAP1 POP DUP3 PUSH1 0x20 DUP4 ADD MSTORE SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x40 DUP2 MSTORE PUSH1 0x0 PUSH2 0x2129 PUSH1 0x40 DUP4 ADD DUP6 DUP8 PUSH2 0x1BFF JUMP JUMPDEST SWAP1 POP PUSH1 0xFF DUP4 AND PUSH1 0x20 DUP4 ADD MSTORE SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x60 DUP2 MSTORE PUSH1 0x0 PUSH2 0x2150 PUSH1 0x60 DUP4 ADD DUP7 DUP9 PUSH2 0x1BFF JUMP JUMPDEST PUSH1 0x20 DUP4 ADD SWAP5 SWAP1 SWAP5 MSTORE POP SWAP1 ISZERO ISZERO PUSH1 0x40 SWAP1 SWAP2 ADD MSTORE SWAP3 SWAP2 POP POP JUMP JUMPDEST DUP4 DUP2 MSTORE PUSH1 0x40 PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x0 PUSH2 0x2182 PUSH1 0x40 DUP4 ADD DUP5 DUP7 PUSH2 0x1BFF JUMP JUMPDEST SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x219D JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 MLOAD PUSH2 0x317 DUP2 PUSH2 0x1852 JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 SWAP12 0xB9 0x5D XOR 0xE9 PUSH32 0x278AA47E0C04C20D5A6AF9BDB6D473C6D4051192CD96FC17866864736F6C6343 STOP ADDMOD SLT STOP CALLER ", + "sourceMap": "640:2693:1:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3127:204;;;;;;;;;;-1:-1:-1;3127:204:1;;;;;:::i;:::-;;:::i;:::-;;;611:14:22;;604:22;586:41;;574:2;559:18;3127:204:1;;;;;;;;5489:316:2;;;;;;;;;;-1:-1:-1;5489:316:2;;;;;:::i;:::-;;:::i;:::-;;;1646:66:22;1634:79;;;1616:98;;1604:2;1589:18;5489:316:2;1472:248:22;4525:332:2;;;;;;;;;;-1:-1:-1;4525:332:2;;;;;:::i;:::-;;:::i;6456:119::-;;;;;;;;;;-1:-1:-1;6456:119:2;;;;;:::i;:::-;;:::i;:::-;;811:95:14;;;;;;;;;;;;862:44;811:95;;;;;2778:25:22;;;2766:2;2751:18;811:95:14;2632:177:22;1290:262:1;;;;;;;;;;-1:-1:-1;1290:262:1;;;;;:::i;:::-;;:::i;890:292::-;;;;;;;;;;-1:-1:-1;890:292:1;;;;;:::i;:::-;;:::i;1675:1486:2:-;;;;;;;;;;-1:-1:-1;1675:1486:2;;;;;:::i;:::-;;:::i;:::-;;;;4827:25:22;;;4883:2;4868:18;;4861:34;;;;4911:18;;;4904:34;;;;4969:2;4954:18;;4947:34;5012:3;4997:19;;4990:35;4814:3;4799:19;1675:1486:2;4568:463:22;938:156:6;;;;;;;;;;-1:-1:-1;938:156:6;;;;;:::i;:::-;;:::i;456:276:4:-;;;;;;:::i;:::-;;:::i;:::-;;;6753:42:22;6741:55;;;6723:74;;6711:2;6696:18;456:276:4;6577:226:22;670:87:6;;;;;;;;;;;;;:::i;3127:204:1:-;3270:4;3289:37;3313:12;3289:23;:37::i;:::-;3282:44;3127:204;-1:-1:-1;;3127:204:1:o;5489:316:2:-;5608:6;5650:12;5667:40;5688:5;5695:11;;5667:20;:40::i;:::-;5649:58;;;5717:7;5713:65;;;-1:-1:-1;5741:30:2;;-1:-1:-1;5734:37:2;;5713:65;-1:-1:-1;5798:1:2;;-1:-1:-1;5489:316:2;;;;;;:::o;4525:332::-;4651:6;4693:12;4710:51;4741:5;;4731:16;;;;;;;:::i;:::-;;;;;;;;4749:11;;4710:20;:51::i;:::-;4692:69;;;4771:7;4767:63;;;-1:-1:-1;4795:28:2;;-1:-1:-1;4788:35:2;;4767:63;-1:-1:-1;4850:1:2;;-1:-1:-1;4525:332:2;;;;;;;:::o;6456:119::-;178:10:8;200:4;178:27;174:94;;222:39;;;;;235:10;222:39;;;7319:34:22;255:4:8;7369:18:22;;;7362:43;7231:18;;222:39:8;;;;;;;;174:94;6542:28:2::1;6559:10;6542:16;:28::i;:::-;6456:119:::0;:::o;1290:262:1:-;1401:14;1418:63;1474:4;;1454:25;;;;;;;;;:::i;:::-;;;;;;;;;;;;;1444:36;;;;;;1418:25;:63::i;:::-;1401:80;;1520:27;1534:6;1542:4;;1520:13;:27::i;:::-;1364:188;1290:262;;:::o;890:292::-;1030:14;1047:64;1104:4;;1083:26;;;;;;;;;:::i;1047:64::-;1030:81;;1150:27;1164:6;1172:4;;1150:13;:27::i;:::-;993:189;890:292;;;;;:::o;1675:1486:2:-;1801:17;1824:14;1844:17;1867;1890:18;1919:20;1942:10;;1953:1;1942:13;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;1942:13:2;;-1:-1:-1;1962:303:2;;2057:34;2083:7;2057:25;:34::i;:::-;2045:46;;2144;2168:9;2179:10;;2144:23;:46::i;:::-;2099:91;;-1:-1:-1;2099:91:2;;-1:-1:-1;2099:91:2;-1:-1:-1;2099:91:2;-1:-1:-1;2198:60:2;;-1:-1:-1;2198:60:2;1962:303;2275:29;;;;;2271:310;;2370:34;2396:7;2370:25;:34::i;:::-;2358:46;;2457:49;2484:9;2495:10;;2457:26;:49::i;2271:310::-;2591:33;;;;;2587:319;;2690:39;2721:7;2690:30;:39::i;2587:319::-;2916:29;;;;;2912:196;;3066:35;3081:7;3090:10;;3066:14;:35::i;:::-;3059:42;;;;;;;;;;;;;2912:196;3121:35;;;;;11707:66:22;11695:79;;3121:35:2;;;11677:98:22;11650:18;;3121:35:2;11533:248:22;1675:1486:2;;;;;;;;;;:::o;938:156:6:-;1002:7;1032:56;453:66;1080:6;1032:28;:56::i;456:276:4:-;550:12;178:10:8;200:4;178:27;174:94;;222:39;;;;;235:10;222:39;;;7319:34:22;255:4:8;7369:18:22;;;7362:43;7231:18;;222:39:8;7084:327:22;174:94:8;631:5:4::1;625:12;620:2;613:5;609:14;596:11;589:49;581:57:::0;-1:-1:-1;649:18:4::1;::::0;::::1;645:50;;689:5;676:19;;;;;;;;;;;:::i;645:50::-;706:21;::::0;6753:42:22;6741:55;;6723:74;;706:21:4::1;::::0;6711:2:22;6696:18;706:21:4::1;;;;;;;456:276:::0;;;:::o;670:87:6:-;718:7;740:12;750:1;740:9;:12::i;:::-;733:19;;670:87;:::o;942:233:4:-;1028:4;1044:48;;;;;1040:80;;-1:-1:-1;1109:4:4;;942:233;-1:-1:-1;942:233:4:o;1040:80::-;1133:37;1157:12;1133:23;:37::i;3480:386:2:-;3611:12;3629:17;3657;3676:14;3692:17;3760:38;3778:7;3787:10;;3760:17;:38::i;:::-;-1:-1:-1;3715:83:2;-1:-1:-1;3715:83:2;;-1:-1:-1;3715:83:2;-1:-1:-1;3715:83:2;-1:-1:-1;3814:19:2;;;;;;:47;;-1:-1:-1;2779:4:1;3837:24:2;3804:57;;3651:215;;;3480:386;;;;;;:::o;2824:93:1:-;2898:14;;;;;;;;;;;;;;1173:224:13;1279:107;;12792:66:22;1279:107:13;;;12780:79:22;1325:13:13;12875:11:22;;;12868:27;12946:66;1356:4:13;12933:2:22;12929:15;12925:88;12911:12;;;12904:110;13030:12;;;13023:28;;;1240:7:13;;13067:12:22;;1279:107:13;;;;;;;;;;;;;1262:130;;;;;;1255:137;;1173:224;;;:::o;1710:834:1:-;1847:4;1832:12;1864:676;1888:4;1884:1;:8;1864:676;;;1907:32;1942:4;;1947:1;1942:7;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;1907:42;-1:-1:-1;1962:24:1;;;;1907:42;1962:24;:::i;:::-;1958:62;;;1995:25;;;;;;;;2778::22;;;2751:18;;1995:25:1;2632:177:22;1958:62:1;2048:20;;;;;2080:9;:20;2076:69;;;2122:1;2125:8;2135:9;2109:36;;;;;;;;13869:25:22;;;;13910:18;;;13903:34;;;;13953:18;;;13946:34;13842:18;;2109:36:1;13667:319:22;2076:69:1;2154:12;2169:148;2192:18;;;;;;;;:::i;:::-;2220:17;;;;2247:13;;:36;;2275:8;2247:36;;;2263:9;2247:36;2293:16;;;;:11;:16;:::i;:::-;2169:13;:148::i;:::-;2154:163;;2330:7;2326:208;;;2365:7;2354:22;2374:1;2354:22;;;;2778:25:22;;2766:2;2751:18;;2632:177;2354:22:1;;;;;;;;2326:208;;;2401:124;2425:25;;;;;;;;:::i;:::-;2462:7;2481:1;2494:21;:19;:21::i;:::-;2401:12;:124::i;:::-;1899:641;;;1894:3;;;;;:::i;:::-;;;;1864:676;;;;1799:745;1710:834;;;:::o;8892:642:13:-;8996:17;;;;9131:41;9145:10;9157:14;:10;9168:1;9157:10;;:14;:::i;:::-;9131:13;:41::i;:::-;622:9:20;656:13;;;1585:25:18;;1626:3;1622:14;683:2:20;676:14;;;715:2;702:16;;;656:13;;9379:1:13;2034:23:18;;;2021:37;2074:3;2070:14;676::20;;;;702:16;;;;1622:14:18;;9109:63:13;;-1:-1:-1;702:16:20;2070:14:18;-1:-1:-1;8892:642:13;-1:-1:-1;;;;8892:642:13:o;648:262:15:-;752:17;;;;854:51;878:10;890:14;:10;901:1;890:10;;:14;:::i;:::-;854:23;:51::i;:::-;847:58;;;;;;;;648:262;;;;;;;:::o;404:213:16:-;502:104;;12792:66:22;502:104:16;;;12780:79:22;463:7:16;12875:11:22;;;12868:27;;;12946:66;576:4:16;12933:2:22;12929:15;12925:88;12911:12;;;12904:110;13030:12;;;13023:28;;;463:7:16;13067:12:22;;502:104:16;12494:591:22;2320:2059:14;2428:17;;;;;3378:14:19;2563:1:14;3290:25:19;;3277:39;3336:3;3332:14;2428:17:14;2768:16;3378:14:19;3332;2768:16:14;:::i;:::-;2750:34;-1:-1:-1;2883:72:14;2908:7;2923:26;2750:34;2934:6;2923:10;;:26;:::i;2883:72::-;2791:164;;-1:-1:-1;2791:164:14;;-1:-1:-1;2791:164:14;-1:-1:-1;2791:164:14;-1:-1:-1;2791:164:14;-1:-1:-1;2966:18:14;;;2962:118;;;3027:26;3045:7;3038:6;3027:10;;:26;:::i;:::-;3055:9;3066:6;3001:72;;;;;;;;;;;;;;:::i;2962:118::-;3095:7;3086:16;;3283:1092;3290:26;;;3283:1092;;;3390:1:19;3378:14;;;3290:25;;3277:39;3336:3;3332:14;;-1:-1:-1;3444:16:14;3378:14:19;3332;3444:16:14;:::i;:::-;3434:26;;3469:22;3687:105;3714:34;3738:9;3714:23;:34::i;:::-;3758:10;;3769:6;3758:26;3776:7;3758:26;;;;;;;:::i;3687:105::-;3500:292;;-1:-1:-1;3500:292:14;;-1:-1:-1;3500:292:14;-1:-1:-1;3500:292:14;;-1:-1:-1;;3833:18:14;;;3829:122;;;3896:26;3914:7;3907:6;3896:10;;:26;:::i;:::-;3924:9;3935:6;3870:72;;;;;;;;;;;;;;:::i;3829:122::-;4216:10;4198:14;:28;4194:115;;4245:55;;;;;;;;16193:25:22;;;16234:18;;;16227:34;;;16166:18;;4245:55:14;16019:248:22;4194:115:14;4330:14;-1:-1:-1;4361:7:14;-1:-1:-1;4361:7:14;3283:1092;;;2540:1839;;;2320:2059;;;;;;;;;:::o;490:187:9:-;568:11;587;622:4;628:7;611:25;;;;;;;;16193::22;;;16249:2;16234:18;;16227:34;16181:2;16166:18;;16019:248;611:25:9;;;;;;;;;;;;;;601:36;;611:25;601:36;;;;661:10;;490:187;-1:-1:-1;;;;490:187:9:o;4140:231:3:-;4226:4;4242:46;;;;;4238:78;;-1:-1:-1;4305:4:3;;4140:231;-1:-1:-1;4140:231:3:o;4238:78::-;4329:37;4353:12;4329:23;:37::i;1525:353:20:-;1640:6;1688:4;1682:11;1732:12;1718;1713:3;1700:45;1859:1;1848;1826:12;1813:3;1799:4;1786:3;1772:4;1758:110;1753:115;1525:353;-1:-1:-1;;;;;;;1525:353:20:o;852:271::-;897:14;948:16;982:4;976:11;971:16;;1014:2;1011:1;1007:10;1048:4;1041:5;1037:16;1031:4;1024:30;1071:4;1068:1;1061:15;1108:4;1105:1;1098:5;1083:30;;;852:271;:::o;3644:286:3:-;3781:14;3777:149;;;3849:7;3843:14;3836:4;3827:7;3823:18;3816:42;3777:149;3894:7;3885:34;3903:6;3911:7;3885:34;;;;;;;:::i;:::-;;;;;;;;3644:286;;;;:::o;3525:4708:13:-;3635:14;3655:12;3696:14;3765:4458;3772:26;;;3765:4458;;;1475:1:19;1463:14;;;1390:25;;1377:39;1432:3;1428:14;3923:20:13;;;3919:402;;2205:2:19;2193:15;;;2046:25;;2033:39;2088:3;2084:14;;;;2118:2;2114:13;2129:42;2110:62;;;1873:23:13;;:49;;4231:4;:59;;4286:4;4231:59;;;622:9:20;656:13;;;683:2;676:14;;;715:2;702:16;;4252:31:13;4224:66;;4302:8;;;;;;3919:402;4335:4;4331:679;;1475:1:19;1463:14;;;1390:25;;;1377:39;1432:3;1428:14;;4560:11:13;;4396:16;4598:72;4631:10;4643:26;4560:11;1463:14:19;4643:10:13;1390:25:19;4643:26:13;:::i;:::-;4598:32;:72::i;:::-;4764:20;;;;;;;;4691:7;;-1:-1:-1;4691:7:13;;4764:20;-1:-1:-1;1893:3:13;1873:23;;;;;1899;;;1873:49;4920:4;:59;;4975:4;4920:59;;;622:9:20;656:13;;;683:2;676:14;;;715:2;702:16;;4941:31:13;4913:66;;4991:8;;;;;;;4331:679;625:1;5024:4;:30;5020:932;;5104:16;;2046:25:19;;;2033:39;2088:3;2084:14;;;;2118:2;2114:13;2129:42;2110:62;2205:2;2193:15;;5146:64:13;-1:-1:-1;5146:64:13;;-1:-1:-1;5146:64:13;-1:-1:-1;5256:12:13;3290:25:19;;;3277:39;3336:3;3332:14;3390:1;3378:14;;5280:46:13;;;;;;;;;;;;;5380:15;5407:4;5398:6;:13;5380:31;;5428:81;5464:10;5476:4;5482:10;;5493:6;5482:26;5500:7;5482:26;;;;;;;:::i;:::-;5428:35;:81::i;:::-;5423:190;;5555:10;5567:4;5573:26;5591:7;5584:6;5573:10;;:26;:::i;:::-;5532:68;;;;;;;;;;;;;;:::i;5423:190::-;5706:20;;;;;;;;;-1:-1:-1;5706:20:13;1893:3;1873:23;;;;;1899;;;1873:49;5862:4;:59;;5917:4;5862:59;;;622:9:20;656:13;;;683:2;676:14;;;715:2;702:16;;5883:31:13;5855:66;;5933:8;;;;;;;;5020:932;667:1;5966:4;:17;5962:243;;4550:2:19;4536:17;;;4487:27;;4474:41;6115:4:13;:59;;6170:4;6115:59;;;622:9:20;656:13;;;683:2;676:14;;;715:2;702:16;;6136:31:13;6108:66;;6186:8;;;;5962:243;711:1;6219:4;:19;6215:472;;3390:1:19;3378:14;;;;3290:25;;;3277:39;3336:3;3332:14;;6409:13:13;;;;6309:12;;6494:53;6508:10;6520:26;6409:13;3378:14:19;6520:10:13;3290:25:19;6520:26:13;:::i;6494:53::-;622:9:20;656:13;;;683:2;676:14;715:2;702:16;;;6560:17:13;;;;;-1:-1:-1;6649:7:13;;-1:-1:-1;6668:8:13;;-1:-1:-1;;;6668:8:13;6215:472;802:1;6701:4;:19;6697:979;;6864:22;1390:25:19;;;1377:39;1432:3;1428:14;1475:1;1463:14;;6898:55:13;-1:-1:-1;6898:55:13;;;-1:-1:-1;6966:25:13;2699::19;;;2686:39;2745:3;2741:14;2797:1;2785:14;;7003:59:13;-1:-1:-1;7003:59:13;;;-1:-1:-1;7075:12:13;3290:25:19;;;3277:39;3336:3;3332:14;3390:1;3378:14;;7099:46:13;;;;;;;;;;;;;7157:15;7184:4;7175:6;:13;7157:31;;7201:22;7225:20;7290:53;7304:10;7316;;7327:6;7316:26;7334:7;7316:26;;;;;;;:::i;7290:53::-;7364:7;;-1:-1:-1;7364:7:13;;7257:86;;-1:-1:-1;7257:86:13;-1:-1:-1;7388:35:13;;;7384:92;;7439:24;;;;7384:92;2976:73;;;20362:66:22;2976:73:13;;;;20350:79:22;;;;20445:12;;;20438:28;;;20482:12;;;20475:28;;;20519:12;;;;20512:28;;;2976:73:13;;;;;;;;;;20556:13:22;;;;2976:73:13;;;2966:84;;;;;7585:4;:59;;7640:4;7585:59;;;622:9:20;656:13;;;683:2;676:14;;;715:2;702:16;;7606:31:13;7578:66;;7657:8;;;;;;;;;;6697:979;758:1;7690:4;:22;7686:485;;4550:2:19;4536:17;;;4487:27;;4474:41;7920:23:13;;;7916:82;;7968:17;7959:26;;7916:82;8010:12;8025:37;8052:9;8025:26;:37::i;:::-;8010:52;-1:-1:-1;8081:4:13;:59;;8136:4;8081:59;;;622:9:20;656:13;;;683:2;676:14;;;715:2;702:16;;8102:31:13;8074:66;;8152:8;;;;;7686:485;8188:26;;;;;;;;2778:25:22;;;2751:18;;8188:26:13;2632:177:22;3765:4458:13;3678:4551;3525:4708;;;;;;:::o;1296:160:14:-;862:44;1372:7;656:13:20;;;683:2;676:14;;;715:2;702:16;;1394:57:14;543:185:20;6015:300:2;6101:4;6124:45;;;6140:29;6124:45;;:103;;-1:-1:-1;6179:48:2;;;6195:32;6179:48;6124:103;6113:147;;;-1:-1:-1;6249:4:2;;6015:300;-1:-1:-1;6015:300:2:o;6113:147::-;725:31:5;709:47;;;;6273:37:2;613:148:5;1767:2316:21;1867:14;1914:2;1893:23;;1889:70;;1948:10;;1925:34;;;;;;;;;;;;:::i;1889:70::-;1965:21;1989:43;2010:21;2030:1;2010:10;:21;:::i;:::-;1226:23:18;;1213:37;1266:3;1262:14;;1071:215;1989:43:21;1965:67;;;-1:-1:-1;2115:2:21;1226:23:18;;1213:37;1266:3;1262:14;795:37;;2202:2:21;808:23:18;;795:37;3209:66:21;3196:79;;3192:135;;;3306:10;;3318:1;3292:28;;;;;;;;;;;;;:::i;3192:135::-;3337:1;:7;;3342:2;3337:7;;:18;;;;;3348:1;:7;;3353:2;3348:7;;3337:18;3333:74;;;3386:10;;3398:1;3372:28;;;;;;;;;;;;;:::i;3333:74::-;1253:1;3447:13;:32;3443:509;;3498:25;;;;;;;;;;;;18522::22;;;18595:4;18583:17;;18563:18;;;18556:45;;;;18617:18;;;18610:34;;;18660:18;;;18653:34;;;3498:25:21;;18494:19:22;;3498:25:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3489:34;;3443:509;;;1303:1;3608:13;:34;3604:348;;3690:59;;18940:66:22;3690:59:21;;;18928:79:22;19023:12;;;19016:28;;;3661:130:21;;19060:12:22;;3690:59:21;;;;;;;;;;;;;3680:70;;3690:59;3680:70;;;;3661:130;;;;;;;;;18522:25:22;18595:4;18583:17;;18563:18;;;18556:45;18617:18;;;18610:34;;;18660:18;;;18653:34;;;18494:19;;3661:130:21;18295:398:22;3604:348:21;3913:10;;3925:13;3940:4;3888:57;;;;;;;;;;;;;;:::i;3604:348::-;3999:22;;;3995:63;;4047:10;;4030:28;;;;;;;;;;;;:::i;3995:63::-;4065:13;;;;1767:2316;;;;;:::o;4411:951::-;4535:10;4557:22;;;4553:66;;4596:16;;;;;;;;;;;;;;4553:66;4625:21;4655:10;;4666:21;4686:1;4655:10;4666:21;:::i;:::-;4655:33;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;;1253:1:21;4699:32;;;:70;;;1303:1;4735:13;:34;4699:70;4695:663;;;4873:7;4837:43;;:32;4851:5;4858:10;;4837:13;:32::i;:::-;:43;;;4829:51;;4695:663;;;1359:1;4898:13;:40;4894:464;;5060:40;;;;5101:5;5108:10;5119:1;5108:10;5121:21;5141:1;5108:10;5121:21;:::i;:::-;5108:35;;;;;;;:::i;:::-;5060:84;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5030:114;;:26;:114;;-1:-1:-1;4894:464:21;;;5318:10;;5330:13;5345:5;5293:58;;;;;;;;;;;;;;:::i;4894:464::-;4547:815;4411:951;;;;;;:::o;2227:182:13:-;2346:57;;20822:66:22;2346:57:13;;;20810:79:22;20905:12;;;20898:28;;;2314:7:13;;20942:12:22;;2346:57:13;20580:380:22;14:177;99:66;92:5;88:78;81:5;78:89;68:117;;181:1;178;171:12;196:245;254:6;307:2;295:9;286:7;282:23;278:32;275:52;;;323:1;320;313:12;275:52;362:9;349:23;381:30;405:5;381:30;:::i;638:347::-;689:8;699:6;753:3;746:4;738:6;734:17;730:27;720:55;;771:1;768;761:12;720:55;-1:-1:-1;794:20:22;;837:18;826:30;;823:50;;;869:1;866;859:12;823:50;906:4;898:6;894:17;882:29;;958:3;951:4;942:6;934;930:19;926:30;923:39;920:59;;;975:1;972;965:12;920:59;638:347;;;;;:::o;990:477::-;1069:6;1077;1085;1138:2;1126:9;1117:7;1113:23;1109:32;1106:52;;;1154:1;1151;1144:12;1106:52;1190:9;1177:23;1167:33;;1251:2;1240:9;1236:18;1223:32;1278:18;1270:6;1267:30;1264:50;;;1310:1;1307;1300:12;1264:50;1349:58;1399:7;1390:6;1379:9;1375:22;1349:58;:::i;:::-;990:477;;1426:8;;-1:-1:-1;1323:84:22;;-1:-1:-1;;;;990:477:22:o;1725:717::-;1815:6;1823;1831;1839;1892:2;1880:9;1871:7;1867:23;1863:32;1860:52;;;1908:1;1905;1898:12;1860:52;1948:9;1935:23;1977:18;2018:2;2010:6;2007:14;2004:34;;;2034:1;2031;2024:12;2004:34;2073:58;2123:7;2114:6;2103:9;2099:22;2073:58;:::i;:::-;2150:8;;-1:-1:-1;2047:84:22;-1:-1:-1;2238:2:22;2223:18;;2210:32;;-1:-1:-1;2254:16:22;;;2251:36;;;2283:1;2280;2273:12;2251:36;;2322:60;2374:7;2363:8;2352:9;2348:24;2322:60;:::i;:::-;1725:717;;;;-1:-1:-1;2401:8:22;-1:-1:-1;;;;1725:717:22:o;2447:180::-;2506:6;2559:2;2547:9;2538:7;2534:23;2530:32;2527:52;;;2575:1;2572;2565:12;2527:52;-1:-1:-1;2598:23:22;;2447:180;-1:-1:-1;2447:180:22:o;2814:387::-;2897:8;2907:6;2961:3;2954:4;2946:6;2942:17;2938:27;2928:55;;2979:1;2976;2969:12;2928:55;-1:-1:-1;3002:20:22;;3045:18;3034:30;;3031:50;;;3077:1;3074;3067:12;3031:50;3114:4;3106:6;3102:17;3090:29;;3174:3;3167:4;3157:6;3154:1;3150:14;3142:6;3138:27;3134:38;3131:47;3128:67;;;3191:1;3188;3181:12;3206:488;3323:6;3331;3384:2;3372:9;3363:7;3359:23;3355:32;3352:52;;;3400:1;3397;3390:12;3352:52;3440:9;3427:23;3473:18;3465:6;3462:30;3459:50;;;3505:1;3502;3495:12;3459:50;3544:90;3626:7;3617:6;3606:9;3602:22;3544:90;:::i;:::-;3653:8;;3518:116;;-1:-1:-1;3206:488:22;-1:-1:-1;;;;3206:488:22:o;3699:864::-;3845:6;3853;3861;3869;3877;3930:2;3918:9;3909:7;3905:23;3901:32;3898:52;;;3946:1;3943;3936:12;3898:52;3986:9;3973:23;4015:18;4056:2;4048:6;4045:14;4042:34;;;4072:1;4069;4062:12;4042:34;4111:90;4193:7;4184:6;4173:9;4169:22;4111:90;:::i;:::-;4220:8;;-1:-1:-1;4085:116:22;-1:-1:-1;4302:2:22;4287:18;;4274:32;;-1:-1:-1;4359:2:22;4344:18;;4331:32;;-1:-1:-1;4375:16:22;;;4372:36;;;4404:1;4401;4394:12;4372:36;;4443:60;4495:7;4484:8;4473:9;4469:24;4443:60;:::i;:::-;3699:864;;;;-1:-1:-1;3699:864:22;;-1:-1:-1;4522:8:22;;4417:86;3699:864;-1:-1:-1;;;3699:864:22:o;5403:184::-;5455:77;5452:1;5445:88;5552:4;5549:1;5542:15;5576:4;5573:1;5566:15;5592:980;5660:6;5713:2;5701:9;5692:7;5688:23;5684:32;5681:52;;;5729:1;5726;5719:12;5681:52;5769:9;5756:23;5798:18;5839:2;5831:6;5828:14;5825:34;;;5855:1;5852;5845:12;5825:34;5893:6;5882:9;5878:22;5868:32;;5938:7;5931:4;5927:2;5923:13;5919:27;5909:55;;5960:1;5957;5950:12;5909:55;5996:2;5983:16;6018:2;6014;6011:10;6008:36;;;6024:18;;:::i;:::-;6158:2;6152:9;6220:4;6212:13;;6063:66;6208:22;;;6232:2;6204:31;6200:40;6188:53;;;6256:18;;;6276:22;;;6253:46;6250:72;;;6302:18;;:::i;:::-;6342:10;6338:2;6331:22;6377:2;6369:6;6362:18;6417:7;6412:2;6407;6403;6399:11;6395:20;6392:33;6389:53;;;6438:1;6435;6428:12;6389:53;6494:2;6489;6485;6481:11;6476:2;6468:6;6464:15;6451:46;6539:1;6517:15;;;6534:2;6513:24;6506:35;;;;-1:-1:-1;6521:6:22;5592:980;-1:-1:-1;;;;;5592:980:22:o;6808:271::-;6991:6;6983;6978:3;6965:33;6947:3;7017:16;;7042:13;;;7017:16;6808:271;-1:-1:-1;6808:271:22:o;7416:160::-;7481:20;;7537:13;;7530:21;7520:32;;7510:60;;7566:1;7563;7556:12;7510:60;7416:160;;;:::o;7581:196::-;7649:20;;7709:42;7698:54;;7688:65;;7678:93;;7767:1;7764;7757:12;7782:325;7870:6;7865:3;7858:19;7922:6;7915:5;7908:4;7903:3;7899:14;7886:43;;7974:1;7967:4;7958:6;7953:3;7949:16;7945:27;7938:38;7840:3;8096:4;8026:66;8021:2;8013:6;8009:15;8005:88;8000:3;7996:98;7992:109;7985:116;;7782:325;;;;:::o;8112:2028::-;8232:6;8227:3;8220:19;8202:3;8258:4;8299:2;8294:3;8290:12;8324:11;8351;8344:18;;8401:6;8398:1;8394:14;8387:5;8383:26;8371:38;;8432:5;8455:1;8465:1649;8479:6;8476:1;8473:13;8465:1649;;;8550:5;8544:4;8540:16;8535:3;8528:29;8609:6;8596:20;8695:66;8687:5;8671:14;8667:26;8663:99;8643:18;8639:124;8629:152;;8777:1;8774;8767:12;8629:152;8809:30;;8862:4;8906:24;8809:30;8906:24;:::i;:::-;8899:32;8892:40;8886:4;8879:54;8982:33;9011:2;9002:7;8998:16;8982:33;:::i;:::-;8975:41;8968:49;8953:13;;;8946:72;9041:4;9093:16;;;9080:30;9065:13;;;9058:53;9134:4;9215:42;9177:36;9196:16;;;9177:36;:::i;:::-;9173:85;9158:13;;;9151:108;9282:4;9334:16;;;9321:30;9306:13;;;9299:53;9375:4;9433:16;;;9420:30;9507:14;9503:28;;;9533:66;9499:101;9473:128;;9463:156;;9615:1;9612;9605:12;9463:156;9647:34;;;9759:16;;;;-1:-1:-1;9710:21:22;9804:18;9791:32;;9788:52;;;9836:1;9833;9826:12;9788:52;9889:8;9873:14;9869:29;9860:7;9856:43;9853:63;;;9912:1;9909;9902:12;9853:63;9951:2;9946;9940:4;9936:13;9929:25;9975:59;10030:2;10024:4;10020:13;10010:8;10001:7;9975:59;:::i;:::-;10092:12;;;;9967:67;-1:-1:-1;;;10057:15:22;;;;-1:-1:-1;;8501:1:22;8494:9;8465:1649;;;-1:-1:-1;10130:4:22;;8112:2028;-1:-1:-1;;;;;;;8112:2028:22:o;10145:594::-;10495:2;10484:9;10477:21;10534:1;10529:2;10518:9;10514:18;10507:29;10572:7;10567:2;10556:9;10552:18;10545:35;10618:3;10611:4;10600:9;10596:20;10589:33;10458:4;10639:94;10728:3;10717:9;10713:19;10705:6;10697;10639:94;:::i;10744:595::-;11094:2;11083:9;11076:21;11133:1;11128:2;11117:9;11113:18;11106:29;11171:8;11166:2;11155:9;11151:18;11144:36;11218:3;11211:4;11200:9;11196:20;11189:33;11057:4;11239:94;11328:3;11317:9;11313:19;11305:6;11297;11239:94;:::i;11344:184::-;11396:77;11393:1;11386:88;11493:4;11490:1;11483:15;11517:4;11514:1;11507:15;11786:481;11827:3;11865:5;11859:12;11892:6;11887:3;11880:19;11917:1;11927:162;11941:6;11938:1;11935:13;11927:162;;;12003:4;12059:13;;;12055:22;;12049:29;12031:11;;;12027:20;;12020:59;11956:12;11927:162;;;11931:3;12134:1;12127:4;12118:6;12113:3;12109:16;12105:27;12098:38;12256:4;12186:66;12181:2;12173:6;12169:15;12165:88;12160:3;12156:98;12152:109;12145:116;;;11786:481;;;;:::o;12272:217::-;12419:2;12408:9;12401:21;12382:4;12439:44;12479:2;12468:9;12464:18;12456:6;12439:44;:::i;13090:387::-;13187:4;13245:11;13232:25;13335:66;13324:8;13308:14;13304:29;13300:102;13280:18;13276:127;13266:155;;13417:1;13414;13407:12;13266:155;13438:33;;;;;13090:387;-1:-1:-1;;13090:387:22:o;13482:180::-;13538:6;13591:2;13579:9;13570:7;13566:23;13562:32;13559:52;;;13607:1;13604;13597:12;13559:52;13630:26;13646:9;13630:26;:::i;13991:186::-;14050:6;14103:2;14091:9;14082:7;14078:23;14074:32;14071:52;;;14119:1;14116;14109:12;14071:52;14142:29;14161:9;14142:29;:::i;14182:580::-;14259:4;14265:6;14325:11;14312:25;14415:66;14404:8;14388:14;14384:29;14380:102;14360:18;14356:127;14346:155;;14497:1;14494;14487:12;14346:155;14524:33;;14576:20;;;-1:-1:-1;14619:18:22;14608:30;;14605:50;;;14651:1;14648;14641:12;14605:50;14684:4;14672:17;;-1:-1:-1;14715:14:22;14711:27;;;14701:38;;14698:58;;;14752:1;14749;14742:12;14767:184;14819:77;14816:1;14809:88;14916:4;14913:1;14906:15;14940:4;14937:1;14930:15;14956:195;14995:3;15026:66;15019:5;15016:77;15013:103;;15096:18;;:::i;:::-;-1:-1:-1;15143:1:22;15132:13;;14956:195::o;15156:331::-;15261:9;15272;15314:8;15302:10;15299:24;15296:44;;;15336:1;15333;15326:12;15296:44;15365:6;15355:8;15352:20;15349:40;;;15385:1;15382;15375:12;15349:40;-1:-1:-1;;15411:23:22;;;15456:25;;;;;-1:-1:-1;15156:331:22:o;15492:125::-;15557:9;;;15578:10;;;15575:36;;;15591:18;;:::i;15622:392::-;15841:2;15830:9;15823:21;15804:4;15861:61;15918:2;15907:9;15903:18;15895:6;15887;15861:61;:::i;:::-;15953:2;15938:18;;15931:34;;;;-1:-1:-1;15996:2:22;15981:18;15974:34;15853:69;15622:392;-1:-1:-1;;15622:392:22:o;16525:288::-;16700:6;16689:9;16682:25;16743:2;16738;16727:9;16723:18;16716:30;16663:4;16763:44;16803:2;16792:9;16788:18;16780:6;16763:44;:::i;16818:441::-;17037:6;17026:9;17019:25;17092:42;17084:6;17080:55;17075:2;17064:9;17060:18;17053:83;17172:2;17167;17156:9;17152:18;17145:30;17000:4;17192:61;17249:2;17238:9;17234:18;17226:6;17218;17192:61;:::i;:::-;17184:69;16818:441;-1:-1:-1;;;;;;16818:441:22:o;17264:244::-;17421:2;17410:9;17403:21;17384:4;17441:61;17498:2;17487:9;17483:18;17475:6;17467;17441:61;:::i;17513:128::-;17580:9;;;17601:11;;;17598:37;;;17615:18;;:::i;17646:315::-;17831:2;17820:9;17813:21;17794:4;17851:61;17908:2;17897:9;17893:18;17885:6;17877;17851:61;:::i;:::-;17843:69;;17948:6;17943:2;17932:9;17928:18;17921:34;17646:315;;;;;;:::o;17966:324::-;18149:2;18138:9;18131:21;18112:4;18169:61;18226:2;18215:9;18211:18;18203:6;18195;18169:61;:::i;:::-;18161:69;;18278:4;18270:6;18266:17;18261:2;18250:9;18246:18;18239:45;17966:324;;;;;;:::o;19083:396::-;19290:2;19279:9;19272:21;19253:4;19310:61;19367:2;19356:9;19352:18;19344:6;19336;19310:61;:::i;:::-;19402:2;19387:18;;19380:34;;;;-1:-1:-1;19457:14:22;;19450:22;19445:2;19430:18;;;19423:50;19302:69;19083:396;-1:-1:-1;;19083:396:22:o;19484:321::-;19675:6;19664:9;19657:25;19718:2;19713;19702:9;19698:18;19691:30;19638:4;19738:61;19795:2;19784:9;19780:18;19772:6;19764;19738:61;:::i;:::-;19730:69;19484:321;-1:-1:-1;;;;;19484:321:22:o;19810:249::-;19879:6;19932:2;19920:9;19911:7;19907:23;19903:32;19900:52;;;19948:1;19945;19938:12;19900:52;19980:9;19974:16;19999:30;20023:5;19999:30;:::i" + }, + "gasEstimates": { + "creation": { + "codeDepositCost": "1734000", + "executionCost": "infinite", + "totalCost": "infinite" + }, + "external": { + "SET_IMAGE_HASH_TYPE_HASH()": "262", + "createContract(bytes)": "infinite", + "execute((bool,bool,uint256,address,uint256,bytes)[],uint256,bytes)": "infinite", + "isValidSignature(bytes,bytes)": "infinite", + "isValidSignature(bytes32,bytes)": "infinite", + "nonce()": "2645", + "readNonce(uint256)": "2640", + "selfExecute((bool,bool,uint256,address,uint256,bytes)[])": "infinite", + "signatureRecovery(bytes32,bytes)": "infinite", + "supportsInterface(bytes4)": "infinite", + "updateImageHash(bytes32)": "357" + }, + "internal": { + "_executeGuest(bytes32,struct IModuleCalls.Transaction calldata[] calldata)": "infinite", + "_isValidImage(bytes32)": "infinite", + "_updateImageHash(bytes32)": "infinite" + } + }, + "legacyAssembly": { + ".code": [ + { + "begin": 640, + "end": 3333, + "name": "PUSH", + "source": 1, + "value": "A0" + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH", + "source": 1, + "value": "40" + }, + { + "begin": 640, + "end": 3333, + "name": "MSTORE", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "CALLVALUE", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "DUP1", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "ISZERO", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH [tag]", + "source": 1, + "value": "1" + }, + { + "begin": 640, + "end": 3333, + "name": "JUMPI", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 640, + "end": 3333, + "name": "DUP1", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "REVERT", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "tag", + "source": 1, + "value": "1" + }, + { + "begin": 640, + "end": 3333, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 200, + "end": 204, + "name": "ADDRESS", + "source": 7 + }, + { + "begin": 185, + "end": 205, + "name": "PUSH", + "source": 7, + "value": "80" + }, + { + "begin": 185, + "end": 205, + "name": "MSTORE", + "source": 7 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH", + "source": 1, + "value": "80" + }, + { + "begin": 640, + "end": 3333, + "name": "MLOAD", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH #[$]", + "source": 1, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH [$]", + "source": 1, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 640, + "end": 3333, + "name": "CODECOPY", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 640, + "end": 3333, + "name": "ASSIGNIMMUTABLE", + "source": 1, + "value": "1055" + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH #[$]", + "source": 1, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 640, + "end": 3333, + "name": "RETURN", + "source": 1 + } + ], + ".data": { + "0": { + ".auxdata": "a26469706673582212209bb95d18e97f278aa47e0c04c20d5a6af9bdb6d473c6d4051192cd96fc17866864736f6c63430008120033", + ".code": [ + { + "begin": 640, + "end": 3333, + "name": "PUSH", + "source": 1, + "value": "80" + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH", + "source": 1, + "value": "40" + }, + { + "begin": 640, + "end": 3333, + "name": "MSTORE", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH", + "source": 1, + "value": "4" + }, + { + "begin": 640, + "end": 3333, + "name": "CALLDATASIZE", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "LT", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH [tag]", + "source": 1, + "value": "1" + }, + { + "begin": 640, + "end": 3333, + "name": "JUMPI", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 640, + "end": 3333, + "name": "CALLDATALOAD", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH", + "source": 1, + "value": "E0" + }, + { + "begin": 640, + "end": 3333, + "name": "SHR", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "DUP1", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH", + "source": 1, + "value": "61C2926C" + }, + { + "begin": 640, + "end": 3333, + "name": "GT", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH [tag]", + "source": 1, + "value": "13" + }, + { + "begin": 640, + "end": 3333, + "name": "JUMPI", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "DUP1", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH", + "source": 1, + "value": "8C3F5563" + }, + { + "begin": 640, + "end": 3333, + "name": "GT", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH [tag]", + "source": 1, + "value": "14" + }, + { + "begin": 640, + "end": 3333, + "name": "JUMPI", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "DUP1", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH", + "source": 1, + "value": "8C3F5563" + }, + { + "begin": 640, + "end": 3333, + "name": "EQ", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH [tag]", + "source": 1, + "value": "10" + }, + { + "begin": 640, + "end": 3333, + "name": "JUMPI", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "DUP1", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH", + "source": 1, + "value": "90042BAF" + }, + { + "begin": 640, + "end": 3333, + "name": "EQ", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH [tag]", + "source": 1, + "value": "11" + }, + { + "begin": 640, + "end": 3333, + "name": "JUMPI", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "DUP1", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH", + "source": 1, + "value": "AFFED0E0" + }, + { + "begin": 640, + "end": 3333, + "name": "EQ", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH [tag]", + "source": 1, + "value": "12" + }, + { + "begin": 640, + "end": 3333, + "name": "JUMPI", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 640, + "end": 3333, + "name": "DUP1", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "REVERT", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "tag", + "source": 1, + "value": "14" + }, + { + "begin": 640, + "end": 3333, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "DUP1", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH", + "source": 1, + "value": "61C2926C" + }, + { + "begin": 640, + "end": 3333, + "name": "EQ", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH [tag]", + "source": 1, + "value": "7" + }, + { + "begin": 640, + "end": 3333, + "name": "JUMPI", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "DUP1", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH", + "source": 1, + "value": "7A9A1628" + }, + { + "begin": 640, + "end": 3333, + "name": "EQ", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH [tag]", + "source": 1, + "value": "8" + }, + { + "begin": 640, + "end": 3333, + "name": "JUMPI", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "DUP1", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH", + "source": 1, + "value": "853C5068" + }, + { + "begin": 640, + "end": 3333, + "name": "EQ", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH [tag]", + "source": 1, + "value": "9" + }, + { + "begin": 640, + "end": 3333, + "name": "JUMPI", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 640, + "end": 3333, + "name": "DUP1", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "REVERT", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "tag", + "source": 1, + "value": "13" + }, + { + "begin": 640, + "end": 3333, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "DUP1", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH", + "source": 1, + "value": "20C13B0B" + }, + { + "begin": 640, + "end": 3333, + "name": "GT", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH [tag]", + "source": 1, + "value": "15" + }, + { + "begin": 640, + "end": 3333, + "name": "JUMPI", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "DUP1", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH", + "source": 1, + "value": "20C13B0B" + }, + { + "begin": 640, + "end": 3333, + "name": "EQ", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH [tag]", + "source": 1, + "value": "4" + }, + { + "begin": 640, + "end": 3333, + "name": "JUMPI", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "DUP1", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH", + "source": 1, + "value": "29561426" + }, + { + "begin": 640, + "end": 3333, + "name": "EQ", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH [tag]", + "source": 1, + "value": "5" + }, + { + "begin": 640, + "end": 3333, + "name": "JUMPI", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "DUP1", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH", + "source": 1, + "value": "57C56D6B" + }, + { + "begin": 640, + "end": 3333, + "name": "EQ", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH [tag]", + "source": 1, + "value": "6" + }, + { + "begin": 640, + "end": 3333, + "name": "JUMPI", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 640, + "end": 3333, + "name": "DUP1", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "REVERT", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "tag", + "source": 1, + "value": "15" + }, + { + "begin": 640, + "end": 3333, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "DUP1", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH", + "source": 1, + "value": "1FFC9A7" + }, + { + "begin": 640, + "end": 3333, + "name": "EQ", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH [tag]", + "source": 1, + "value": "2" + }, + { + "begin": 640, + "end": 3333, + "name": "JUMPI", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "DUP1", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH", + "source": 1, + "value": "1626BA7E" + }, + { + "begin": 640, + "end": 3333, + "name": "EQ", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH [tag]", + "source": 1, + "value": "3" + }, + { + "begin": 640, + "end": 3333, + "name": "JUMPI", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "tag", + "source": 1, + "value": "1" + }, + { + "begin": 640, + "end": 3333, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 640, + "end": 3333, + "name": "DUP1", + "source": 1 + }, + { + "begin": 640, + "end": 3333, + "name": "REVERT", + "source": 1 + }, + { + "begin": 3127, + "end": 3331, + "name": "tag", + "source": 1, + "value": "2" + }, + { + "begin": 3127, + "end": 3331, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 3127, + "end": 3331, + "name": "CALLVALUE", + "source": 1 + }, + { + "begin": 3127, + "end": 3331, + "name": "DUP1", + "source": 1 + }, + { + "begin": 3127, + "end": 3331, + "name": "ISZERO", + "source": 1 + }, + { + "begin": 3127, + "end": 3331, + "name": "PUSH [tag]", + "source": 1, + "value": "16" + }, + { + "begin": 3127, + "end": 3331, + "name": "JUMPI", + "source": 1 + }, + { + "begin": 3127, + "end": 3331, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 3127, + "end": 3331, + "name": "DUP1", + "source": 1 + }, + { + "begin": 3127, + "end": 3331, + "name": "REVERT", + "source": 1 + }, + { + "begin": 3127, + "end": 3331, + "name": "tag", + "source": 1, + "value": "16" + }, + { + "begin": 3127, + "end": 3331, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 3127, + "end": 3331, + "name": "PUSH [tag]", + "source": 1, + "value": "17" + }, + { + "begin": 3127, + "end": 3331, + "name": "PUSH [tag]", + "source": 1, + "value": "18" + }, + { + "begin": 3127, + "end": 3331, + "name": "CALLDATASIZE", + "source": 1 + }, + { + "begin": 3127, + "end": 3331, + "name": "PUSH", + "source": 1, + "value": "4" + }, + { + "begin": 3127, + "end": 3331, + "name": "PUSH [tag]", + "source": 1, + "value": "19" + }, + { + "begin": 3127, + "end": 3331, + "jumpType": "[in]", + "name": "JUMP", + "source": 1 + }, + { + "begin": 3127, + "end": 3331, + "name": "tag", + "source": 1, + "value": "18" + }, + { + "begin": 3127, + "end": 3331, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 3127, + "end": 3331, + "name": "PUSH [tag]", + "source": 1, + "value": "20" + }, + { + "begin": 3127, + "end": 3331, + "jumpType": "[in]", + "name": "JUMP", + "source": 1 + }, + { + "begin": 3127, + "end": 3331, + "name": "tag", + "source": 1, + "value": "17" + }, + { + "begin": 3127, + "end": 3331, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 3127, + "end": 3331, + "name": "PUSH", + "source": 1, + "value": "40" + }, + { + "begin": 3127, + "end": 3331, + "name": "MLOAD", + "source": 1 + }, + { + "begin": 611, + "end": 625, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 611, + "end": 625, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 604, + "end": 626, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 586, + "end": 627, + "name": "DUP2", + "source": 22 + }, + { + "begin": 586, + "end": 627, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 574, + "end": 576, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 559, + "end": 577, + "name": "ADD", + "source": 22 + }, + { + "begin": 3127, + "end": 3331, + "name": "tag", + "source": 1, + "value": "21" + }, + { + "begin": 3127, + "end": 3331, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 3127, + "end": 3331, + "name": "PUSH", + "source": 1, + "value": "40" + }, + { + "begin": 3127, + "end": 3331, + "name": "MLOAD", + "source": 1 + }, + { + "begin": 3127, + "end": 3331, + "name": "DUP1", + "source": 1 + }, + { + "begin": 3127, + "end": 3331, + "name": "SWAP2", + "source": 1 + }, + { + "begin": 3127, + "end": 3331, + "name": "SUB", + "source": 1 + }, + { + "begin": 3127, + "end": 3331, + "name": "SWAP1", + "source": 1 + }, + { + "begin": 3127, + "end": 3331, + "name": "RETURN", + "source": 1 + }, + { + "begin": 5489, + "end": 5805, + "name": "tag", + "source": 2, + "value": "3" + }, + { + "begin": 5489, + "end": 5805, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": 5489, + "end": 5805, + "name": "CALLVALUE", + "source": 2 + }, + { + "begin": 5489, + "end": 5805, + "name": "DUP1", + "source": 2 + }, + { + "begin": 5489, + "end": 5805, + "name": "ISZERO", + "source": 2 + }, + { + "begin": 5489, + "end": 5805, + "name": "PUSH [tag]", + "source": 2, + "value": "23" + }, + { + "begin": 5489, + "end": 5805, + "name": "JUMPI", + "source": 2 + }, + { + "begin": 5489, + "end": 5805, + "name": "PUSH", + "source": 2, + "value": "0" + }, + { + "begin": 5489, + "end": 5805, + "name": "DUP1", + "source": 2 + }, + { + "begin": 5489, + "end": 5805, + "name": "REVERT", + "source": 2 + }, + { + "begin": 5489, + "end": 5805, + "name": "tag", + "source": 2, + "value": "23" + }, + { + "begin": 5489, + "end": 5805, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 5489, + "end": 5805, + "name": "PUSH [tag]", + "source": 2, + "value": "24" + }, + { + "begin": 5489, + "end": 5805, + "name": "PUSH [tag]", + "source": 2, + "value": "25" + }, + { + "begin": 5489, + "end": 5805, + "name": "CALLDATASIZE", + "source": 2 + }, + { + "begin": 5489, + "end": 5805, + "name": "PUSH", + "source": 2, + "value": "4" + }, + { + "begin": 5489, + "end": 5805, + "name": "PUSH [tag]", + "source": 2, + "value": "26" + }, + { + "begin": 5489, + "end": 5805, + "jumpType": "[in]", + "name": "JUMP", + "source": 2 + }, + { + "begin": 5489, + "end": 5805, + "name": "tag", + "source": 2, + "value": "25" + }, + { + "begin": 5489, + "end": 5805, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": 5489, + "end": 5805, + "name": "PUSH [tag]", + "source": 2, + "value": "27" + }, + { + "begin": 5489, + "end": 5805, + "jumpType": "[in]", + "name": "JUMP", + "source": 2 + }, + { + "begin": 5489, + "end": 5805, + "name": "tag", + "source": 2, + "value": "24" + }, + { + "begin": 5489, + "end": 5805, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": 5489, + "end": 5805, + "name": "PUSH", + "source": 2, + "value": "40" + }, + { + "begin": 5489, + "end": 5805, + "name": "MLOAD", + "source": 2 + }, + { + "begin": 1646, + "end": 1712, + "name": "PUSH", + "source": 22, + "value": "FFFFFFFF00000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 1634, + "end": 1713, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 1634, + "end": 1713, + "name": "SWAP2", + "source": 22 + }, + { + "begin": 1634, + "end": 1713, + "name": "AND", + "source": 22 + }, + { + "begin": 1616, + "end": 1714, + "name": "DUP2", + "source": 22 + }, + { + "begin": 1616, + "end": 1714, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 1604, + "end": 1606, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 1589, + "end": 1607, + "name": "ADD", + "source": 22 + }, + { + "begin": 5489, + "end": 5805, + "name": "PUSH [tag]", + "source": 2, + "value": "21" + }, + { + "begin": 1472, + "end": 1720, + "name": "JUMP", + "source": 22 + }, + { + "begin": 4525, + "end": 4857, + "name": "tag", + "source": 2, + "value": "4" + }, + { + "begin": 4525, + "end": 4857, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": 4525, + "end": 4857, + "name": "CALLVALUE", + "source": 2 + }, + { + "begin": 4525, + "end": 4857, + "name": "DUP1", + "source": 2 + }, + { + "begin": 4525, + "end": 4857, + "name": "ISZERO", + "source": 2 + }, + { + "begin": 4525, + "end": 4857, + "name": "PUSH [tag]", + "source": 2, + "value": "30" + }, + { + "begin": 4525, + "end": 4857, + "name": "JUMPI", + "source": 2 + }, + { + "begin": 4525, + "end": 4857, + "name": "PUSH", + "source": 2, + "value": "0" + }, + { + "begin": 4525, + "end": 4857, + "name": "DUP1", + "source": 2 + }, + { + "begin": 4525, + "end": 4857, + "name": "REVERT", + "source": 2 + }, + { + "begin": 4525, + "end": 4857, + "name": "tag", + "source": 2, + "value": "30" + }, + { + "begin": 4525, + "end": 4857, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 4525, + "end": 4857, + "name": "PUSH [tag]", + "source": 2, + "value": "24" + }, + { + "begin": 4525, + "end": 4857, + "name": "PUSH [tag]", + "source": 2, + "value": "32" + }, + { + "begin": 4525, + "end": 4857, + "name": "CALLDATASIZE", + "source": 2 + }, + { + "begin": 4525, + "end": 4857, + "name": "PUSH", + "source": 2, + "value": "4" + }, + { + "begin": 4525, + "end": 4857, + "name": "PUSH [tag]", + "source": 2, + "value": "33" + }, + { + "begin": 4525, + "end": 4857, + "jumpType": "[in]", + "name": "JUMP", + "source": 2 + }, + { + "begin": 4525, + "end": 4857, + "name": "tag", + "source": 2, + "value": "32" + }, + { + "begin": 4525, + "end": 4857, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": 4525, + "end": 4857, + "name": "PUSH [tag]", + "source": 2, + "value": "34" + }, + { + "begin": 4525, + "end": 4857, + "jumpType": "[in]", + "name": "JUMP", + "source": 2 + }, + { + "begin": 6456, + "end": 6575, + "name": "tag", + "source": 2, + "value": "5" + }, + { + "begin": 6456, + "end": 6575, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": 6456, + "end": 6575, + "name": "CALLVALUE", + "source": 2 + }, + { + "begin": 6456, + "end": 6575, + "name": "DUP1", + "source": 2 + }, + { + "begin": 6456, + "end": 6575, + "name": "ISZERO", + "source": 2 + }, + { + "begin": 6456, + "end": 6575, + "name": "PUSH [tag]", + "source": 2, + "value": "36" + }, + { + "begin": 6456, + "end": 6575, + "name": "JUMPI", + "source": 2 + }, + { + "begin": 6456, + "end": 6575, + "name": "PUSH", + "source": 2, + "value": "0" + }, + { + "begin": 6456, + "end": 6575, + "name": "DUP1", + "source": 2 + }, + { + "begin": 6456, + "end": 6575, + "name": "REVERT", + "source": 2 + }, + { + "begin": 6456, + "end": 6575, + "name": "tag", + "source": 2, + "value": "36" + }, + { + "begin": 6456, + "end": 6575, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 6456, + "end": 6575, + "name": "PUSH [tag]", + "source": 2, + "value": "37" + }, + { + "begin": 6456, + "end": 6575, + "name": "PUSH [tag]", + "source": 2, + "value": "38" + }, + { + "begin": 6456, + "end": 6575, + "name": "CALLDATASIZE", + "source": 2 + }, + { + "begin": 6456, + "end": 6575, + "name": "PUSH", + "source": 2, + "value": "4" + }, + { + "begin": 6456, + "end": 6575, + "name": "PUSH [tag]", + "source": 2, + "value": "39" + }, + { + "begin": 6456, + "end": 6575, + "jumpType": "[in]", + "name": "JUMP", + "source": 2 + }, + { + "begin": 6456, + "end": 6575, + "name": "tag", + "source": 2, + "value": "38" + }, + { + "begin": 6456, + "end": 6575, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": 6456, + "end": 6575, + "name": "PUSH [tag]", + "source": 2, + "value": "40" + }, + { + "begin": 6456, + "end": 6575, + "jumpType": "[in]", + "name": "JUMP", + "source": 2 + }, + { + "begin": 6456, + "end": 6575, + "name": "tag", + "source": 2, + "value": "37" + }, + { + "begin": 6456, + "end": 6575, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": 6456, + "end": 6575, + "name": "STOP", + "source": 2 + }, + { + "begin": 811, + "end": 906, + "name": "tag", + "source": 14, + "value": "6" + }, + { + "begin": 811, + "end": 906, + "name": "JUMPDEST", + "source": 14 + }, + { + "begin": 811, + "end": 906, + "name": "CALLVALUE", + "source": 14 + }, + { + "begin": 811, + "end": 906, + "name": "DUP1", + "source": 14 + }, + { + "begin": 811, + "end": 906, + "name": "ISZERO", + "source": 14 + }, + { + "begin": 811, + "end": 906, + "name": "PUSH [tag]", + "source": 14, + "value": "41" + }, + { + "begin": 811, + "end": 906, + "name": "JUMPI", + "source": 14 + }, + { + "begin": 811, + "end": 906, + "name": "PUSH", + "source": 14, + "value": "0" + }, + { + "begin": 811, + "end": 906, + "name": "DUP1", + "source": 14 + }, + { + "begin": 811, + "end": 906, + "name": "REVERT", + "source": 14 + }, + { + "begin": 811, + "end": 906, + "name": "tag", + "source": 14, + "value": "41" + }, + { + "begin": 811, + "end": 906, + "name": "JUMPDEST", + "source": 14 + }, + { + "begin": 811, + "end": 906, + "name": "POP", + "source": 14 + }, + { + "begin": 811, + "end": 906, + "name": "PUSH [tag]", + "source": 14, + "value": "42" + }, + { + "begin": 862, + "end": 906, + "name": "PUSH", + "source": 14, + "value": "8713A7C4465F6FBEE2B6E9D6646D1D9F83FEC929EDFC4BAF661F3C865BDD04D1" + }, + { + "begin": 811, + "end": 906, + "name": "DUP2", + "source": 14 + }, + { + "begin": 811, + "end": 906, + "name": "JUMP", + "source": 14 + }, + { + "begin": 811, + "end": 906, + "name": "tag", + "source": 14, + "value": "42" + }, + { + "begin": 811, + "end": 906, + "name": "JUMPDEST", + "source": 14 + }, + { + "begin": 811, + "end": 906, + "name": "PUSH", + "source": 14, + "value": "40" + }, + { + "begin": 811, + "end": 906, + "name": "MLOAD", + "source": 14 + }, + { + "begin": 2778, + "end": 2803, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 2778, + "end": 2803, + "name": "DUP2", + "source": 22 + }, + { + "begin": 2778, + "end": 2803, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 2766, + "end": 2768, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 2751, + "end": 2769, + "name": "ADD", + "source": 22 + }, + { + "begin": 811, + "end": 906, + "name": "PUSH [tag]", + "source": 14, + "value": "21" + }, + { + "begin": 2632, + "end": 2809, + "name": "JUMP", + "source": 22 + }, + { + "begin": 1290, + "end": 1552, + "name": "tag", + "source": 1, + "value": "7" + }, + { + "begin": 1290, + "end": 1552, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 1290, + "end": 1552, + "name": "CALLVALUE", + "source": 1 + }, + { + "begin": 1290, + "end": 1552, + "name": "DUP1", + "source": 1 + }, + { + "begin": 1290, + "end": 1552, + "name": "ISZERO", + "source": 1 + }, + { + "begin": 1290, + "end": 1552, + "name": "PUSH [tag]", + "source": 1, + "value": "46" + }, + { + "begin": 1290, + "end": 1552, + "name": "JUMPI", + "source": 1 + }, + { + "begin": 1290, + "end": 1552, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 1290, + "end": 1552, + "name": "DUP1", + "source": 1 + }, + { + "begin": 1290, + "end": 1552, + "name": "REVERT", + "source": 1 + }, + { + "begin": 1290, + "end": 1552, + "name": "tag", + "source": 1, + "value": "46" + }, + { + "begin": 1290, + "end": 1552, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 1290, + "end": 1552, + "name": "PUSH [tag]", + "source": 1, + "value": "37" + }, + { + "begin": 1290, + "end": 1552, + "name": "PUSH [tag]", + "source": 1, + "value": "48" + }, + { + "begin": 1290, + "end": 1552, + "name": "CALLDATASIZE", + "source": 1 + }, + { + "begin": 1290, + "end": 1552, + "name": "PUSH", + "source": 1, + "value": "4" + }, + { + "begin": 1290, + "end": 1552, + "name": "PUSH [tag]", + "source": 1, + "value": "49" + }, + { + "begin": 1290, + "end": 1552, + "jumpType": "[in]", + "name": "JUMP", + "source": 1 + }, + { + "begin": 1290, + "end": 1552, + "name": "tag", + "source": 1, + "value": "48" + }, + { + "begin": 1290, + "end": 1552, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 1290, + "end": 1552, + "name": "PUSH [tag]", + "source": 1, + "value": "50" + }, + { + "begin": 1290, + "end": 1552, + "jumpType": "[in]", + "name": "JUMP", + "source": 1 + }, + { + "begin": 890, + "end": 1182, + "name": "tag", + "source": 1, + "value": "8" + }, + { + "begin": 890, + "end": 1182, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 890, + "end": 1182, + "name": "CALLVALUE", + "source": 1 + }, + { + "begin": 890, + "end": 1182, + "name": "DUP1", + "source": 1 + }, + { + "begin": 890, + "end": 1182, + "name": "ISZERO", + "source": 1 + }, + { + "begin": 890, + "end": 1182, + "name": "PUSH [tag]", + "source": 1, + "value": "51" + }, + { + "begin": 890, + "end": 1182, + "name": "JUMPI", + "source": 1 + }, + { + "begin": 890, + "end": 1182, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 890, + "end": 1182, + "name": "DUP1", + "source": 1 + }, + { + "begin": 890, + "end": 1182, + "name": "REVERT", + "source": 1 + }, + { + "begin": 890, + "end": 1182, + "name": "tag", + "source": 1, + "value": "51" + }, + { + "begin": 890, + "end": 1182, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 890, + "end": 1182, + "name": "PUSH [tag]", + "source": 1, + "value": "37" + }, + { + "begin": 890, + "end": 1182, + "name": "PUSH [tag]", + "source": 1, + "value": "53" + }, + { + "begin": 890, + "end": 1182, + "name": "CALLDATASIZE", + "source": 1 + }, + { + "begin": 890, + "end": 1182, + "name": "PUSH", + "source": 1, + "value": "4" + }, + { + "begin": 890, + "end": 1182, + "name": "PUSH [tag]", + "source": 1, + "value": "54" + }, + { + "begin": 890, + "end": 1182, + "jumpType": "[in]", + "name": "JUMP", + "source": 1 + }, + { + "begin": 890, + "end": 1182, + "name": "tag", + "source": 1, + "value": "53" + }, + { + "begin": 890, + "end": 1182, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 890, + "end": 1182, + "name": "PUSH [tag]", + "source": 1, + "value": "55" + }, + { + "begin": 890, + "end": 1182, + "jumpType": "[in]", + "name": "JUMP", + "source": 1 + }, + { + "begin": 1675, + "end": 3161, + "name": "tag", + "source": 2, + "value": "9" + }, + { + "begin": 1675, + "end": 3161, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": 1675, + "end": 3161, + "name": "CALLVALUE", + "source": 2 + }, + { + "begin": 1675, + "end": 3161, + "name": "DUP1", + "source": 2 + }, + { + "begin": 1675, + "end": 3161, + "name": "ISZERO", + "source": 2 + }, + { + "begin": 1675, + "end": 3161, + "name": "PUSH [tag]", + "source": 2, + "value": "56" + }, + { + "begin": 1675, + "end": 3161, + "name": "JUMPI", + "source": 2 + }, + { + "begin": 1675, + "end": 3161, + "name": "PUSH", + "source": 2, + "value": "0" + }, + { + "begin": 1675, + "end": 3161, + "name": "DUP1", + "source": 2 + }, + { + "begin": 1675, + "end": 3161, + "name": "REVERT", + "source": 2 + }, + { + "begin": 1675, + "end": 3161, + "name": "tag", + "source": 2, + "value": "56" + }, + { + "begin": 1675, + "end": 3161, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 1675, + "end": 3161, + "name": "PUSH [tag]", + "source": 2, + "value": "57" + }, + { + "begin": 1675, + "end": 3161, + "name": "PUSH [tag]", + "source": 2, + "value": "58" + }, + { + "begin": 1675, + "end": 3161, + "name": "CALLDATASIZE", + "source": 2 + }, + { + "begin": 1675, + "end": 3161, + "name": "PUSH", + "source": 2, + "value": "4" + }, + { + "begin": 1675, + "end": 3161, + "name": "PUSH [tag]", + "source": 2, + "value": "26" + }, + { + "begin": 1675, + "end": 3161, + "jumpType": "[in]", + "name": "JUMP", + "source": 2 + }, + { + "begin": 1675, + "end": 3161, + "name": "tag", + "source": 2, + "value": "58" + }, + { + "begin": 1675, + "end": 3161, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": 1675, + "end": 3161, + "name": "PUSH [tag]", + "source": 2, + "value": "59" + }, + { + "begin": 1675, + "end": 3161, + "jumpType": "[in]", + "name": "JUMP", + "source": 2 + }, + { + "begin": 1675, + "end": 3161, + "name": "tag", + "source": 2, + "value": "57" + }, + { + "begin": 1675, + "end": 3161, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": 1675, + "end": 3161, + "name": "PUSH", + "source": 2, + "value": "40" + }, + { + "begin": 1675, + "end": 3161, + "name": "DUP1", + "source": 2 + }, + { + "begin": 1675, + "end": 3161, + "name": "MLOAD", + "source": 2 + }, + { + "begin": 4827, + "end": 4852, + "name": "SWAP6", + "source": 22 + }, + { + "begin": 4827, + "end": 4852, + "name": "DUP7", + "source": 22 + }, + { + "begin": 4827, + "end": 4852, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 4883, + "end": 4885, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 4868, + "end": 4886, + "name": "DUP7", + "source": 22 + }, + { + "begin": 4868, + "end": 4886, + "name": "ADD", + "source": 22 + }, + { + "begin": 4861, + "end": 4895, + "name": "SWAP5", + "source": 22 + }, + { + "begin": 4861, + "end": 4895, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 4861, + "end": 4895, + "name": "SWAP5", + "source": 22 + }, + { + "begin": 4861, + "end": 4895, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 4911, + "end": 4929, + "name": "SWAP3", + "source": 22 + }, + { + "begin": 4911, + "end": 4929, + "name": "DUP5", + "source": 22 + }, + { + "begin": 4911, + "end": 4929, + "name": "ADD", + "source": 22 + }, + { + "begin": 4904, + "end": 4938, + "name": "SWAP2", + "source": 22 + }, + { + "begin": 4904, + "end": 4938, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 4904, + "end": 4938, + "name": "SWAP2", + "source": 22 + }, + { + "begin": 4904, + "end": 4938, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 4969, + "end": 4971, + "name": "PUSH", + "source": 22, + "value": "60" + }, + { + "begin": 4954, + "end": 4972, + "name": "DUP4", + "source": 22 + }, + { + "begin": 4954, + "end": 4972, + "name": "ADD", + "source": 22 + }, + { + "begin": 4947, + "end": 4981, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 5012, + "end": 5015, + "name": "PUSH", + "source": 22, + "value": "80" + }, + { + "begin": 4997, + "end": 5016, + "name": "DUP3", + "source": 22 + }, + { + "begin": 4997, + "end": 5016, + "name": "ADD", + "source": 22 + }, + { + "begin": 4990, + "end": 5025, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 4814, + "end": 4817, + "name": "PUSH", + "source": 22, + "value": "A0" + }, + { + "begin": 4799, + "end": 4818, + "name": "ADD", + "source": 22 + }, + { + "begin": 1675, + "end": 3161, + "name": "PUSH [tag]", + "source": 2, + "value": "21" + }, + { + "begin": 4568, + "end": 5031, + "name": "JUMP", + "source": 22 + }, + { + "begin": 938, + "end": 1094, + "name": "tag", + "source": 6, + "value": "10" + }, + { + "begin": 938, + "end": 1094, + "name": "JUMPDEST", + "source": 6 + }, + { + "begin": 938, + "end": 1094, + "name": "CALLVALUE", + "source": 6 + }, + { + "begin": 938, + "end": 1094, + "name": "DUP1", + "source": 6 + }, + { + "begin": 938, + "end": 1094, + "name": "ISZERO", + "source": 6 + }, + { + "begin": 938, + "end": 1094, + "name": "PUSH [tag]", + "source": 6, + "value": "62" + }, + { + "begin": 938, + "end": 1094, + "name": "JUMPI", + "source": 6 + }, + { + "begin": 938, + "end": 1094, + "name": "PUSH", + "source": 6, + "value": "0" + }, + { + "begin": 938, + "end": 1094, + "name": "DUP1", + "source": 6 + }, + { + "begin": 938, + "end": 1094, + "name": "REVERT", + "source": 6 + }, + { + "begin": 938, + "end": 1094, + "name": "tag", + "source": 6, + "value": "62" + }, + { + "begin": 938, + "end": 1094, + "name": "JUMPDEST", + "source": 6 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 938, + "end": 1094, + "name": "PUSH [tag]", + "source": 6, + "value": "42" + }, + { + "begin": 938, + "end": 1094, + "name": "PUSH [tag]", + "source": 6, + "value": "64" + }, + { + "begin": 938, + "end": 1094, + "name": "CALLDATASIZE", + "source": 6 + }, + { + "begin": 938, + "end": 1094, + "name": "PUSH", + "source": 6, + "value": "4" + }, + { + "begin": 938, + "end": 1094, + "name": "PUSH [tag]", + "source": 6, + "value": "39" + }, + { + "begin": 938, + "end": 1094, + "jumpType": "[in]", + "name": "JUMP", + "source": 6 + }, + { + "begin": 938, + "end": 1094, + "name": "tag", + "source": 6, + "value": "64" + }, + { + "begin": 938, + "end": 1094, + "name": "JUMPDEST", + "source": 6 + }, + { + "begin": 938, + "end": 1094, + "name": "PUSH [tag]", + "source": 6, + "value": "66" + }, + { + "begin": 938, + "end": 1094, + "jumpType": "[in]", + "name": "JUMP", + "source": 6 + }, + { + "begin": 456, + "end": 732, + "name": "tag", + "source": 4, + "value": "11" + }, + { + "begin": 456, + "end": 732, + "name": "JUMPDEST", + "source": 4 + }, + { + "begin": 456, + "end": 732, + "name": "PUSH [tag]", + "source": 4, + "value": "69" + }, + { + "begin": 456, + "end": 732, + "name": "PUSH [tag]", + "source": 4, + "value": "70" + }, + { + "begin": 456, + "end": 732, + "name": "CALLDATASIZE", + "source": 4 + }, + { + "begin": 456, + "end": 732, + "name": "PUSH", + "source": 4, + "value": "4" + }, + { + "begin": 456, + "end": 732, + "name": "PUSH [tag]", + "source": 4, + "value": "71" + }, + { + "begin": 456, + "end": 732, + "jumpType": "[in]", + "name": "JUMP", + "source": 4 + }, + { + "begin": 456, + "end": 732, + "name": "tag", + "source": 4, + "value": "70" + }, + { + "begin": 456, + "end": 732, + "name": "JUMPDEST", + "source": 4 + }, + { + "begin": 456, + "end": 732, + "name": "PUSH [tag]", + "source": 4, + "value": "72" + }, + { + "begin": 456, + "end": 732, + "jumpType": "[in]", + "name": "JUMP", + "source": 4 + }, + { + "begin": 456, + "end": 732, + "name": "tag", + "source": 4, + "value": "69" + }, + { + "begin": 456, + "end": 732, + "name": "JUMPDEST", + "source": 4 + }, + { + "begin": 456, + "end": 732, + "name": "PUSH", + "source": 4, + "value": "40" + }, + { + "begin": 456, + "end": 732, + "name": "MLOAD", + "source": 4 + }, + { + "begin": 6753, + "end": 6795, + "name": "PUSH", + "source": 22, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { + "begin": 6741, + "end": 6796, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 6741, + "end": 6796, + "name": "SWAP2", + "source": 22 + }, + { + "begin": 6741, + "end": 6796, + "name": "AND", + "source": 22 + }, + { + "begin": 6723, + "end": 6797, + "name": "DUP2", + "source": 22 + }, + { + "begin": 6723, + "end": 6797, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 6711, + "end": 6713, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 6696, + "end": 6714, + "name": "ADD", + "source": 22 + }, + { + "begin": 456, + "end": 732, + "name": "PUSH [tag]", + "source": 4, + "value": "21" + }, + { + "begin": 6577, + "end": 6803, + "name": "JUMP", + "source": 22 + }, + { + "begin": 670, + "end": 757, + "name": "tag", + "source": 6, + "value": "12" + }, + { + "begin": 670, + "end": 757, + "name": "JUMPDEST", + "source": 6 + }, + { + "begin": 670, + "end": 757, + "name": "CALLVALUE", + "source": 6 + }, + { + "begin": 670, + "end": 757, + "name": "DUP1", + "source": 6 + }, + { + "begin": 670, + "end": 757, + "name": "ISZERO", + "source": 6 + }, + { + "begin": 670, + "end": 757, + "name": "PUSH [tag]", + "source": 6, + "value": "75" + }, + { + "begin": 670, + "end": 757, + "name": "JUMPI", + "source": 6 + }, + { + "begin": 670, + "end": 757, + "name": "PUSH", + "source": 6, + "value": "0" + }, + { + "begin": 670, + "end": 757, + "name": "DUP1", + "source": 6 + }, + { + "begin": 670, + "end": 757, + "name": "REVERT", + "source": 6 + }, + { + "begin": 670, + "end": 757, + "name": "tag", + "source": 6, + "value": "75" + }, + { + "begin": 670, + "end": 757, + "name": "JUMPDEST", + "source": 6 + }, + { + "begin": 670, + "end": 757, + "name": "POP", + "source": 6 + }, + { + "begin": 670, + "end": 757, + "name": "PUSH [tag]", + "source": 6, + "value": "42" + }, + { + "begin": 670, + "end": 757, + "name": "PUSH [tag]", + "source": 6, + "value": "77" + }, + { + "begin": 670, + "end": 757, + "jumpType": "[in]", + "name": "JUMP", + "source": 6 + }, + { + "begin": 3127, + "end": 3331, + "name": "tag", + "source": 1, + "value": "20" + }, + { + "begin": 3127, + "end": 3331, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 3270, + "end": 3274, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 3289, + "end": 3326, + "name": "PUSH [tag]", + "source": 1, + "value": "80" + }, + { + "begin": 3313, + "end": 3325, + "name": "DUP3", + "source": 1 + }, + { + "begin": 3289, + "end": 3312, + "name": "PUSH [tag]", + "source": 1, + "value": "81" + }, + { + "begin": 3289, + "end": 3326, + "jumpType": "[in]", + "name": "JUMP", + "source": 1 + }, + { + "begin": 3289, + "end": 3326, + "name": "tag", + "source": 1, + "value": "80" + }, + { + "begin": 3289, + "end": 3326, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 3282, + "end": 3326, + "name": "SWAP3", + "source": 1 + }, + { + "begin": 3127, + "end": 3331, + "name": "SWAP2", + "source": 1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 3127, + "end": 3331, + "jumpType": "[out]", + "name": "JUMP", + "source": 1 + }, + { + "begin": 5489, + "end": 5805, + "name": "tag", + "source": 2, + "value": "27" + }, + { + "begin": 5489, + "end": 5805, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": 5608, + "end": 5614, + "name": "PUSH", + "source": 2, + "value": "0" + }, + { + "begin": 5650, + "end": 5662, + "name": "DUP1", + "source": 2 + }, + { + "begin": 5667, + "end": 5707, + "name": "PUSH [tag]", + "source": 2, + "value": "83" + }, + { + "begin": 5688, + "end": 5693, + "name": "DUP6", + "source": 2 + }, + { + "begin": 5695, + "end": 5706, + "name": "DUP6", + "source": 2 + }, + { + "begin": 5695, + "end": 5706, + "name": "DUP6", + "source": 2 + }, + { + "begin": 5667, + "end": 5687, + "name": "PUSH [tag]", + "source": 2, + "value": "84" + }, + { + "begin": 5667, + "end": 5707, + "jumpType": "[in]", + "name": "JUMP", + "source": 2 + }, + { + "begin": 5667, + "end": 5707, + "name": "tag", + "source": 2, + "value": "83" + }, + { + "begin": 5667, + "end": 5707, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": 5649, + "end": 5707, + "name": "POP", + "source": 2 + }, + { + "begin": 5649, + "end": 5707, + "name": "SWAP1", + "source": 2 + }, + { + "begin": 5649, + "end": 5707, + "name": "POP", + "source": 2 + }, + { + "begin": 5717, + "end": 5724, + "name": "DUP1", + "source": 2 + }, + { + "begin": 5713, + "end": 5778, + "name": "ISZERO", + "source": 2 + }, + { + "begin": 5713, + "end": 5778, + "name": "PUSH [tag]", + "source": 2, + "value": "85" + }, + { + "begin": 5713, + "end": 5778, + "name": "JUMPI", + "source": 2 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 5741, + "end": 5771, + "name": "PUSH", + "source": 2, + "value": "1626BA7E00000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 5741, + "end": 5771, + "name": "SWAP1", + "source": 2 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 5734, + "end": 5771, + "name": "PUSH [tag]", + "source": 2, + "value": "82" + }, + { + "begin": 5734, + "end": 5771, + "name": "JUMP", + "source": 2 + }, + { + "begin": 5713, + "end": 5778, + "name": "tag", + "source": 2, + "value": "85" + }, + { + "begin": 5713, + "end": 5778, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 5798, + "end": 5799, + "name": "PUSH", + "source": 2, + "value": "0" + }, + { + "begin": 5798, + "end": 5799, + "name": "SWAP1", + "source": 2 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 5489, + "end": 5805, + "name": "tag", + "source": 2, + "value": "82" + }, + { + "begin": 5489, + "end": 5805, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": 5489, + "end": 5805, + "name": "SWAP4", + "source": 2 + }, + { + "begin": 5489, + "end": 5805, + "name": "SWAP3", + "source": 2 + }, + { + "begin": 5489, + "end": 5805, + "name": "POP", + "source": 2 + }, + { + "begin": 5489, + "end": 5805, + "name": "POP", + "source": 2 + }, + { + "begin": 5489, + "end": 5805, + "name": "POP", + "source": 2 + }, + { + "begin": 5489, + "end": 5805, + "jumpType": "[out]", + "name": "JUMP", + "source": 2 + }, + { + "begin": 4525, + "end": 4857, + "name": "tag", + "source": 2, + "value": "34" + }, + { + "begin": 4525, + "end": 4857, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": 4651, + "end": 4657, + "name": "PUSH", + "source": 2, + "value": "0" + }, + { + "begin": 4693, + "end": 4705, + "name": "DUP1", + "source": 2 + }, + { + "begin": 4710, + "end": 4761, + "name": "PUSH [tag]", + "source": 2, + "value": "87" + }, + { + "begin": 4741, + "end": 4746, + "name": "DUP7", + "source": 2 + }, + { + "begin": 4741, + "end": 4746, + "name": "DUP7", + "source": 2 + }, + { + "begin": 4731, + "end": 4747, + "name": "PUSH", + "source": 2, + "value": "40" + }, + { + "begin": 4731, + "end": 4747, + "name": "MLOAD", + "source": 2 + }, + { + "begin": 4731, + "end": 4747, + "name": "PUSH [tag]", + "source": 2, + "value": "88" + }, + { + "begin": 4731, + "end": 4747, + "name": "SWAP3", + "source": 2 + }, + { + "begin": 4731, + "end": 4747, + "name": "SWAP2", + "source": 2 + }, + { + "begin": 4731, + "end": 4747, + "name": "SWAP1", + "source": 2 + }, + { + "begin": 4731, + "end": 4747, + "name": "PUSH [tag]", + "source": 2, + "value": "89" + }, + { + "begin": 4731, + "end": 4747, + "jumpType": "[in]", + "name": "JUMP", + "source": 2 + }, + { + "begin": 4731, + "end": 4747, + "name": "tag", + "source": 2, + "value": "88" + }, + { + "begin": 4731, + "end": 4747, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": 4731, + "end": 4747, + "name": "PUSH", + "source": 2, + "value": "40" + }, + { + "begin": 4731, + "end": 4747, + "name": "MLOAD", + "source": 2 + }, + { + "begin": 4731, + "end": 4747, + "name": "DUP1", + "source": 2 + }, + { + "begin": 4731, + "end": 4747, + "name": "SWAP2", + "source": 2 + }, + { + "begin": 4731, + "end": 4747, + "name": "SUB", + "source": 2 + }, + { + "begin": 4731, + "end": 4747, + "name": "SWAP1", + "source": 2 + }, + { + "begin": 4731, + "end": 4747, + "name": "KECCAK256", + "source": 2 + }, + { + "begin": 4749, + "end": 4760, + "name": "DUP6", + "source": 2 + }, + { + "begin": 4749, + "end": 4760, + "name": "DUP6", + "source": 2 + }, + { + "begin": 4710, + "end": 4730, + "name": "PUSH [tag]", + "source": 2, + "value": "84" + }, + { + "begin": 4710, + "end": 4761, + "jumpType": "[in]", + "name": "JUMP", + "source": 2 + }, + { + "begin": 4710, + "end": 4761, + "name": "tag", + "source": 2, + "value": "87" + }, + { + "begin": 4710, + "end": 4761, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": 4692, + "end": 4761, + "name": "POP", + "source": 2 + }, + { + "begin": 4692, + "end": 4761, + "name": "SWAP1", + "source": 2 + }, + { + "begin": 4692, + "end": 4761, + "name": "POP", + "source": 2 + }, + { + "begin": 4771, + "end": 4778, + "name": "DUP1", + "source": 2 + }, + { + "begin": 4767, + "end": 4830, + "name": "ISZERO", + "source": 2 + }, + { + "begin": 4767, + "end": 4830, + "name": "PUSH [tag]", + "source": 2, + "value": "90" + }, + { + "begin": 4767, + "end": 4830, + "name": "JUMPI", + "source": 2 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 4795, + "end": 4823, + "name": "PUSH", + "source": 2, + "value": "20C13B0B00000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 4795, + "end": 4823, + "name": "SWAP1", + "source": 2 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 4788, + "end": 4823, + "name": "PUSH [tag]", + "source": 2, + "value": "86" + }, + { + "begin": 4788, + "end": 4823, + "name": "JUMP", + "source": 2 + }, + { + "begin": 4767, + "end": 4830, + "name": "tag", + "source": 2, + "value": "90" + }, + { + "begin": 4767, + "end": 4830, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 4850, + "end": 4851, + "name": "PUSH", + "source": 2, + "value": "0" + }, + { + "begin": 4850, + "end": 4851, + "name": "SWAP1", + "source": 2 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 4525, + "end": 4857, + "name": "tag", + "source": 2, + "value": "86" + }, + { + "begin": 4525, + "end": 4857, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": 4525, + "end": 4857, + "name": "SWAP5", + "source": 2 + }, + { + "begin": 4525, + "end": 4857, + "name": "SWAP4", + "source": 2 + }, + { + "begin": 4525, + "end": 4857, + "name": "POP", + "source": 2 + }, + { + "begin": 4525, + "end": 4857, + "name": "POP", + "source": 2 + }, + { + "begin": 4525, + "end": 4857, + "name": "POP", + "source": 2 + }, + { + "begin": 4525, + "end": 4857, + "name": "POP", + "source": 2 + }, + { + "begin": 4525, + "end": 4857, + "jumpType": "[out]", + "name": "JUMP", + "source": 2 + }, + { + "begin": 6456, + "end": 6575, + "name": "tag", + "source": 2, + "value": "40" + }, + { + "begin": 6456, + "end": 6575, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": 178, + "end": 188, + "name": "CALLER", + "source": 8 + }, + { + "begin": 200, + "end": 204, + "name": "ADDRESS", + "source": 8 + }, + { + "begin": 178, + "end": 205, + "name": "EQ", + "source": 8 + }, + { + "begin": 174, + "end": 268, + "name": "PUSH [tag]", + "source": 8, + "value": "92" + }, + { + "begin": 174, + "end": 268, + "name": "JUMPI", + "source": 8 + }, + { + "begin": 222, + "end": 261, + "name": "PUSH", + "source": 8, + "value": "40" + }, + { + "begin": 222, + "end": 261, + "name": "MLOAD", + "source": 8 + }, + { + "begin": 222, + "end": 261, + "name": "PUSH", + "source": 8, + "value": "E125889400000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 222, + "end": 261, + "name": "DUP2", + "source": 8 + }, + { + "begin": 222, + "end": 261, + "name": "MSTORE", + "source": 8 + }, + { + "begin": 235, + "end": 245, + "name": "CALLER", + "source": 8 + }, + { + "begin": 222, + "end": 261, + "name": "PUSH", + "source": 8, + "value": "4" + }, + { + "begin": 222, + "end": 261, + "name": "DUP3", + "source": 8 + }, + { + "begin": 222, + "end": 261, + "name": "ADD", + "source": 8 + }, + { + "begin": 7319, + "end": 7353, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 255, + "end": 259, + "name": "ADDRESS", + "source": 8 + }, + { + "begin": 7369, + "end": 7387, + "name": "PUSH", + "source": 22, + "value": "24" + }, + { + "begin": 7369, + "end": 7387, + "name": "DUP3", + "source": 22 + }, + { + "begin": 7369, + "end": 7387, + "name": "ADD", + "source": 22 + }, + { + "begin": 7362, + "end": 7405, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 7231, + "end": 7249, + "name": "PUSH", + "source": 22, + "value": "44" + }, + { + "begin": 7231, + "end": 7249, + "name": "ADD", + "source": 22 + }, + { + "begin": 222, + "end": 261, + "name": "tag", + "source": 8, + "value": "93" + }, + { + "begin": 222, + "end": 261, + "name": "JUMPDEST", + "source": 8 + }, + { + "begin": 222, + "end": 261, + "name": "PUSH", + "source": 8, + "value": "40" + }, + { + "begin": 222, + "end": 261, + "name": "MLOAD", + "source": 8 + }, + { + "begin": 222, + "end": 261, + "name": "DUP1", + "source": 8 + }, + { + "begin": 222, + "end": 261, + "name": "SWAP2", + "source": 8 + }, + { + "begin": 222, + "end": 261, + "name": "SUB", + "source": 8 + }, + { + "begin": 222, + "end": 261, + "name": "SWAP1", + "source": 8 + }, + { + "begin": 222, + "end": 261, + "name": "REVERT", + "source": 8 + }, + { + "begin": 174, + "end": 268, + "name": "tag", + "source": 8, + "value": "92" + }, + { + "begin": 174, + "end": 268, + "name": "JUMPDEST", + "source": 8 + }, + { + "begin": 6542, + "end": 6570, + "modifierDepth": 1, + "name": "PUSH [tag]", + "source": 2, + "value": "96" + }, + { + "begin": 6559, + "end": 6569, + "modifierDepth": 1, + "name": "DUP2", + "source": 2 + }, + { + "begin": 6542, + "end": 6558, + "modifierDepth": 1, + "name": "PUSH [tag]", + "source": 2, + "value": "97" + }, + { + "begin": 6542, + "end": 6570, + "jumpType": "[in]", + "modifierDepth": 1, + "name": "JUMP", + "source": 2 + }, + { + "begin": 6542, + "end": 6570, + "modifierDepth": 1, + "name": "tag", + "source": 2, + "value": "96" + }, + { + "begin": 6542, + "end": 6570, + "modifierDepth": 1, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": 6456, + "end": 6575, + "name": "POP", + "source": 2 + }, + { + "begin": 6456, + "end": 6575, + "jumpType": "[out]", + "name": "JUMP", + "source": 2 + }, + { + "begin": 1290, + "end": 1552, + "name": "tag", + "source": 1, + "value": "50" + }, + { + "begin": 1290, + "end": 1552, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 1401, + "end": 1415, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 1418, + "end": 1481, + "name": "PUSH [tag]", + "source": 1, + "value": "99" + }, + { + "begin": 1474, + "end": 1478, + "name": "DUP4", + "source": 1 + }, + { + "begin": 1474, + "end": 1478, + "name": "DUP4", + "source": 1 + }, + { + "begin": 1454, + "end": 1479, + "name": "PUSH", + "source": 1, + "value": "40" + }, + { + "begin": 1454, + "end": 1479, + "name": "MLOAD", + "source": 1 + }, + { + "begin": 1454, + "end": 1479, + "name": "PUSH", + "source": 1, + "value": "20" + }, + { + "begin": 1454, + "end": 1479, + "name": "ADD", + "source": 1 + }, + { + "begin": 1454, + "end": 1479, + "name": "PUSH [tag]", + "source": 1, + "value": "100" + }, + { + "begin": 1454, + "end": 1479, + "name": "SWAP3", + "source": 1 + }, + { + "begin": 1454, + "end": 1479, + "name": "SWAP2", + "source": 1 + }, + { + "begin": 1454, + "end": 1479, + "name": "SWAP1", + "source": 1 + }, + { + "begin": 1454, + "end": 1479, + "name": "PUSH [tag]", + "source": 1, + "value": "101" + }, + { + "begin": 1454, + "end": 1479, + "jumpType": "[in]", + "name": "JUMP", + "source": 1 + }, + { + "begin": 1454, + "end": 1479, + "name": "tag", + "source": 1, + "value": "100" + }, + { + "begin": 1454, + "end": 1479, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 1454, + "end": 1479, + "name": "PUSH", + "source": 1, + "value": "40" + }, + { + "begin": 1454, + "end": 1479, + "name": "MLOAD", + "source": 1 + }, + { + "begin": 1454, + "end": 1479, + "name": "PUSH", + "source": 1, + "value": "20" + }, + { + "begin": 1454, + "end": 1479, + "name": "DUP2", + "source": 1 + }, + { + "begin": 1454, + "end": 1479, + "name": "DUP4", + "source": 1 + }, + { + "begin": 1454, + "end": 1479, + "name": "SUB", + "source": 1 + }, + { + "begin": 1454, + "end": 1479, + "name": "SUB", + "source": 1 + }, + { + "begin": 1454, + "end": 1479, + "name": "DUP2", + "source": 1 + }, + { + "begin": 1454, + "end": 1479, + "name": "MSTORE", + "source": 1 + }, + { + "begin": 1454, + "end": 1479, + "name": "SWAP1", + "source": 1 + }, + { + "begin": 1454, + "end": 1479, + "name": "PUSH", + "source": 1, + "value": "40" + }, + { + "begin": 1454, + "end": 1479, + "name": "MSTORE", + "source": 1 + }, + { + "begin": 1444, + "end": 1480, + "name": "DUP1", + "source": 1 + }, + { + "begin": 1444, + "end": 1480, + "name": "MLOAD", + "source": 1 + }, + { + "begin": 1444, + "end": 1480, + "name": "SWAP1", + "source": 1 + }, + { + "begin": 1444, + "end": 1480, + "name": "PUSH", + "source": 1, + "value": "20" + }, + { + "begin": 1444, + "end": 1480, + "name": "ADD", + "source": 1 + }, + { + "begin": 1444, + "end": 1480, + "name": "KECCAK256", + "source": 1 + }, + { + "begin": 1418, + "end": 1443, + "name": "PUSH [tag]", + "source": 1, + "value": "102" + }, + { + "begin": 1418, + "end": 1481, + "jumpType": "[in]", + "name": "JUMP", + "source": 1 + }, + { + "begin": 1418, + "end": 1481, + "name": "tag", + "source": 1, + "value": "99" + }, + { + "begin": 1418, + "end": 1481, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 1401, + "end": 1481, + "name": "SWAP1", + "source": 1 + }, + { + "begin": 1401, + "end": 1481, + "name": "POP", + "source": 1 + }, + { + "begin": 1520, + "end": 1547, + "name": "PUSH [tag]", + "source": 1, + "value": "103" + }, + { + "begin": 1534, + "end": 1540, + "name": "DUP2", + "source": 1 + }, + { + "begin": 1542, + "end": 1546, + "name": "DUP5", + "source": 1 + }, + { + "begin": 1542, + "end": 1546, + "name": "DUP5", + "source": 1 + }, + { + "begin": 1520, + "end": 1533, + "name": "PUSH [tag]", + "source": 1, + "value": "104" + }, + { + "begin": 1520, + "end": 1547, + "jumpType": "[in]", + "name": "JUMP", + "source": 1 + }, + { + "begin": 1520, + "end": 1547, + "name": "tag", + "source": 1, + "value": "103" + }, + { + "begin": 1520, + "end": 1547, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 1364, + "end": 1552, + "name": "POP", + "source": 1 + }, + { + "begin": 1290, + "end": 1552, + "name": "POP", + "source": 1 + }, + { + "begin": 1290, + "end": 1552, + "name": "POP", + "source": 1 + }, + { + "begin": 1290, + "end": 1552, + "jumpType": "[out]", + "name": "JUMP", + "source": 1 + }, + { + "begin": 890, + "end": 1182, + "name": "tag", + "source": 1, + "value": "55" + }, + { + "begin": 890, + "end": 1182, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 1030, + "end": 1044, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 1047, + "end": 1111, + "name": "PUSH [tag]", + "source": 1, + "value": "106" + }, + { + "begin": 1104, + "end": 1108, + "name": "DUP7", + "source": 1 + }, + { + "begin": 1104, + "end": 1108, + "name": "DUP7", + "source": 1 + }, + { + "begin": 1083, + "end": 1109, + "name": "PUSH", + "source": 1, + "value": "40" + }, + { + "begin": 1083, + "end": 1109, + "name": "MLOAD", + "source": 1 + }, + { + "begin": 1083, + "end": 1109, + "name": "PUSH", + "source": 1, + "value": "20" + }, + { + "begin": 1083, + "end": 1109, + "name": "ADD", + "source": 1 + }, + { + "begin": 1083, + "end": 1109, + "name": "PUSH [tag]", + "source": 1, + "value": "100" + }, + { + "begin": 1083, + "end": 1109, + "name": "SWAP3", + "source": 1 + }, + { + "begin": 1083, + "end": 1109, + "name": "SWAP2", + "source": 1 + }, + { + "begin": 1083, + "end": 1109, + "name": "SWAP1", + "source": 1 + }, + { + "begin": 1083, + "end": 1109, + "name": "PUSH [tag]", + "source": 1, + "value": "108" + }, + { + "begin": 1083, + "end": 1109, + "jumpType": "[in]", + "name": "JUMP", + "source": 1 + }, + { + "begin": 1047, + "end": 1111, + "name": "tag", + "source": 1, + "value": "106" + }, + { + "begin": 1047, + "end": 1111, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 1030, + "end": 1111, + "name": "SWAP1", + "source": 1 + }, + { + "begin": 1030, + "end": 1111, + "name": "POP", + "source": 1 + }, + { + "begin": 1150, + "end": 1177, + "name": "PUSH [tag]", + "source": 1, + "value": "109" + }, + { + "begin": 1164, + "end": 1170, + "name": "DUP2", + "source": 1 + }, + { + "begin": 1172, + "end": 1176, + "name": "DUP8", + "source": 1 + }, + { + "begin": 1172, + "end": 1176, + "name": "DUP8", + "source": 1 + }, + { + "begin": 1150, + "end": 1163, + "name": "PUSH [tag]", + "source": 1, + "value": "104" + }, + { + "begin": 1150, + "end": 1177, + "jumpType": "[in]", + "name": "JUMP", + "source": 1 + }, + { + "begin": 1150, + "end": 1177, + "name": "tag", + "source": 1, + "value": "109" + }, + { + "begin": 1150, + "end": 1177, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 993, + "end": 1182, + "name": "POP", + "source": 1 + }, + { + "begin": 890, + "end": 1182, + "name": "POP", + "source": 1 + }, + { + "begin": 890, + "end": 1182, + "name": "POP", + "source": 1 + }, + { + "begin": 890, + "end": 1182, + "name": "POP", + "source": 1 + }, + { + "begin": 890, + "end": 1182, + "name": "POP", + "source": 1 + }, + { + "begin": 890, + "end": 1182, + "name": "POP", + "source": 1 + }, + { + "begin": 890, + "end": 1182, + "jumpType": "[out]", + "name": "JUMP", + "source": 1 + }, + { + "begin": 1675, + "end": 3161, + "name": "tag", + "source": 2, + "value": "59" + }, + { + "begin": 1675, + "end": 3161, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": 1801, + "end": 1818, + "name": "PUSH", + "source": 2, + "value": "0" + }, + { + "begin": 1824, + "end": 1838, + "name": "DUP1", + "source": 2 + }, + { + "begin": 1844, + "end": 1861, + "name": "PUSH", + "source": 2, + "value": "0" + }, + { + "begin": 1867, + "end": 1884, + "name": "DUP1", + "source": 2 + }, + { + "begin": 1890, + "end": 1908, + "name": "PUSH", + "source": 2, + "value": "0" + }, + { + "begin": 1919, + "end": 1939, + "name": "DUP1", + "source": 2 + }, + { + "begin": 1942, + "end": 1952, + "name": "DUP8", + "source": 2 + }, + { + "begin": 1942, + "end": 1952, + "name": "DUP8", + "source": 2 + }, + { + "begin": 1953, + "end": 1954, + "name": "PUSH", + "source": 2, + "value": "0" + }, + { + "begin": 1942, + "end": 1955, + "name": "DUP2", + "source": 2 + }, + { + "begin": 1942, + "end": 1955, + "name": "DUP2", + "source": 2 + }, + { + "begin": 1942, + "end": 1955, + "name": "LT", + "source": 2 + }, + { + "begin": 1942, + "end": 1955, + "name": "PUSH [tag]", + "source": 2, + "value": "112" + }, + { + "begin": 1942, + "end": 1955, + "name": "JUMPI", + "source": 2 + }, + { + "begin": 1942, + "end": 1955, + "name": "PUSH [tag]", + "source": 2, + "value": "112" + }, + { + "begin": 1942, + "end": 1955, + "name": "PUSH [tag]", + "source": 2, + "value": "113" + }, + { + "begin": 1942, + "end": 1955, + "jumpType": "[in]", + "name": "JUMP", + "source": 2 + }, + { + "begin": 1942, + "end": 1955, + "name": "tag", + "source": 2, + "value": "112" + }, + { + "begin": 1942, + "end": 1955, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": 1942, + "end": 1955, + "name": "SWAP1", + "source": 2 + }, + { + "begin": 1942, + "end": 1955, + "name": "SWAP2", + "source": 2 + }, + { + "begin": 1942, + "end": 1955, + "name": "ADD", + "source": 2 + }, + { + "begin": 1942, + "end": 1955, + "name": "CALLDATALOAD", + "source": 2 + }, + { + "begin": 1942, + "end": 1955, + "name": "PUSH", + "source": 2, + "value": "FF00000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 1942, + "end": 1955, + "name": "AND", + "source": 2 + }, + { + "begin": 1942, + "end": 1955, + "name": "SWAP2", + "source": 2 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 1942, + "end": 1955, + "name": "DUP2", + "source": 2 + }, + { + "begin": 1942, + "end": 1955, + "name": "SWAP1", + "source": 2 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 1962, + "end": 2265, + "name": "PUSH [tag]", + "source": 2, + "value": "114" + }, + { + "begin": 1962, + "end": 2265, + "name": "JUMPI", + "source": 2 + }, + { + "begin": 2057, + "end": 2091, + "name": "PUSH [tag]", + "source": 2, + "value": "115" + }, + { + "begin": 2083, + "end": 2090, + "name": "DUP10", + "source": 2 + }, + { + "begin": 2057, + "end": 2082, + "name": "PUSH [tag]", + "source": 2, + "value": "102" + }, + { + "begin": 2057, + "end": 2091, + "jumpType": "[in]", + "name": "JUMP", + "source": 2 + }, + { + "begin": 2057, + "end": 2091, + "name": "tag", + "source": 2, + "value": "115" + }, + { + "begin": 2057, + "end": 2091, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": 2045, + "end": 2091, + "name": "SWAP3", + "source": 2 + }, + { + "begin": 2045, + "end": 2091, + "name": "POP", + "source": 2 + }, + { + "begin": 2144, + "end": 2190, + "name": "PUSH [tag]", + "source": 2, + "value": "116" + }, + { + "begin": 2168, + "end": 2177, + "name": "DUP4", + "source": 2 + }, + { + "begin": 2179, + "end": 2189, + "name": "DUP10", + "source": 2 + }, + { + "begin": 2179, + "end": 2189, + "name": "DUP10", + "source": 2 + }, + { + "begin": 2144, + "end": 2167, + "name": "PUSH [tag]", + "source": 2, + "value": "117" + }, + { + "begin": 2144, + "end": 2190, + "jumpType": "[in]", + "name": "JUMP", + "source": 2 + }, + { + "begin": 2144, + "end": 2190, + "name": "tag", + "source": 2, + "value": "116" + }, + { + "begin": 2144, + "end": 2190, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": 2099, + "end": 2190, + "name": "SWAP3", + "source": 2 + }, + { + "begin": 2099, + "end": 2190, + "name": "SWAP9", + "source": 2 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 2099, + "end": 2190, + "name": "SWAP1", + "source": 2 + }, + { + "begin": 2099, + "end": 2190, + "name": "SWAP7", + "source": 2 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 2099, + "end": 2190, + "name": "SWAP5", + "source": 2 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 2099, + "end": 2190, + "name": "SWAP2", + "source": 2 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 2198, + "end": 2258, + "name": "PUSH [tag]", + "source": 2, + "value": "110" + }, + { + "begin": 2198, + "end": 2258, + "name": "SWAP1", + "source": 2 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 2198, + "end": 2258, + "name": "JUMP", + "source": 2 + }, + { + "begin": 1962, + "end": 2265, + "name": "tag", + "source": 2, + "value": "114" + }, + { + "begin": 1962, + "end": 2265, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": 2275, + "end": 2304, + "name": "PUSH", + "source": 2, + "value": "FF00000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 2275, + "end": 2304, + "name": "DUP2", + "source": 2 + }, + { + "begin": 2275, + "end": 2304, + "name": "DUP2", + "source": 2 + }, + { + "begin": 2275, + "end": 2304, + "name": "AND", + "source": 2 + }, + { + "begin": 2275, + "end": 2304, + "name": "ADD", + "source": 2 + }, + { + "begin": 2271, + "end": 2581, + "name": "PUSH [tag]", + "source": 2, + "value": "118" + }, + { + "begin": 2271, + "end": 2581, + "name": "JUMPI", + "source": 2 + }, + { + "begin": 2370, + "end": 2404, + "name": "PUSH [tag]", + "source": 2, + "value": "119" + }, + { + "begin": 2396, + "end": 2403, + "name": "DUP10", + "source": 2 + }, + { + "begin": 2370, + "end": 2395, + "name": "PUSH [tag]", + "source": 2, + "value": "102" + }, + { + "begin": 2370, + "end": 2404, + "jumpType": "[in]", + "name": "JUMP", + "source": 2 + }, + { + "begin": 2370, + "end": 2404, + "name": "tag", + "source": 2, + "value": "119" + }, + { + "begin": 2370, + "end": 2404, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": 2358, + "end": 2404, + "name": "SWAP3", + "source": 2 + }, + { + "begin": 2358, + "end": 2404, + "name": "POP", + "source": 2 + }, + { + "begin": 2457, + "end": 2506, + "name": "PUSH [tag]", + "source": 2, + "value": "116" + }, + { + "begin": 2484, + "end": 2493, + "name": "DUP4", + "source": 2 + }, + { + "begin": 2495, + "end": 2505, + "name": "DUP10", + "source": 2 + }, + { + "begin": 2495, + "end": 2505, + "name": "DUP10", + "source": 2 + }, + { + "begin": 2457, + "end": 2483, + "name": "PUSH [tag]", + "source": 2, + "value": "121" + }, + { + "begin": 2457, + "end": 2506, + "jumpType": "[in]", + "name": "JUMP", + "source": 2 + }, + { + "begin": 2271, + "end": 2581, + "name": "tag", + "source": 2, + "value": "118" + }, + { + "begin": 2271, + "end": 2581, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": 2591, + "end": 2624, + "name": "PUSH", + "source": 2, + "value": "FE00000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 2591, + "end": 2624, + "name": "PUSH", + "source": 2, + "value": "FF00000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 2591, + "end": 2624, + "name": "DUP3", + "source": 2 + }, + { + "begin": 2591, + "end": 2624, + "name": "AND", + "source": 2 + }, + { + "begin": 2591, + "end": 2624, + "name": "ADD", + "source": 2 + }, + { + "begin": 2587, + "end": 2906, + "name": "PUSH [tag]", + "source": 2, + "value": "122" + }, + { + "begin": 2587, + "end": 2906, + "name": "JUMPI", + "source": 2 + }, + { + "begin": 2690, + "end": 2729, + "name": "PUSH [tag]", + "source": 2, + "value": "119" + }, + { + "begin": 2721, + "end": 2728, + "name": "DUP10", + "source": 2 + }, + { + "begin": 2690, + "end": 2720, + "name": "PUSH [tag]", + "source": 2, + "value": "124" + }, + { + "begin": 2690, + "end": 2729, + "jumpType": "[in]", + "name": "JUMP", + "source": 2 + }, + { + "begin": 2587, + "end": 2906, + "name": "tag", + "source": 2, + "value": "122" + }, + { + "begin": 2587, + "end": 2906, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": 2916, + "end": 2945, + "name": "PUSH", + "source": 2, + "value": "FD00000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 2916, + "end": 2945, + "name": "PUSH", + "source": 2, + "value": "FF00000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 2916, + "end": 2945, + "name": "DUP3", + "source": 2 + }, + { + "begin": 2916, + "end": 2945, + "name": "AND", + "source": 2 + }, + { + "begin": 2916, + "end": 2945, + "name": "ADD", + "source": 2 + }, + { + "begin": 2912, + "end": 3108, + "name": "PUSH [tag]", + "source": 2, + "value": "126" + }, + { + "begin": 2912, + "end": 3108, + "name": "JUMPI", + "source": 2 + }, + { + "begin": 3066, + "end": 3101, + "name": "PUSH [tag]", + "source": 2, + "value": "127" + }, + { + "begin": 3081, + "end": 3088, + "name": "DUP10", + "source": 2 + }, + { + "begin": 3090, + "end": 3100, + "name": "DUP10", + "source": 2 + }, + { + "begin": 3090, + "end": 3100, + "name": "DUP10", + "source": 2 + }, + { + "begin": 3066, + "end": 3080, + "name": "PUSH [tag]", + "source": 2, + "value": "128" + }, + { + "begin": 3066, + "end": 3101, + "jumpType": "[in]", + "name": "JUMP", + "source": 2 + }, + { + "begin": 3066, + "end": 3101, + "name": "tag", + "source": 2, + "value": "127" + }, + { + "begin": 3066, + "end": 3101, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": 3059, + "end": 3101, + "name": "SWAP6", + "source": 2 + }, + { + "begin": 3059, + "end": 3101, + "name": "POP", + "source": 2 + }, + { + "begin": 3059, + "end": 3101, + "name": "SWAP6", + "source": 2 + }, + { + "begin": 3059, + "end": 3101, + "name": "POP", + "source": 2 + }, + { + "begin": 3059, + "end": 3101, + "name": "SWAP6", + "source": 2 + }, + { + "begin": 3059, + "end": 3101, + "name": "POP", + "source": 2 + }, + { + "begin": 3059, + "end": 3101, + "name": "SWAP6", + "source": 2 + }, + { + "begin": 3059, + "end": 3101, + "name": "POP", + "source": 2 + }, + { + "begin": 3059, + "end": 3101, + "name": "SWAP6", + "source": 2 + }, + { + "begin": 3059, + "end": 3101, + "name": "POP", + "source": 2 + }, + { + "begin": 3059, + "end": 3101, + "name": "POP", + "source": 2 + }, + { + "begin": 3059, + "end": 3101, + "name": "PUSH [tag]", + "source": 2, + "value": "110" + }, + { + "begin": 3059, + "end": 3101, + "name": "JUMP", + "source": 2 + }, + { + "begin": 2912, + "end": 3108, + "name": "tag", + "source": 2, + "value": "126" + }, + { + "begin": 2912, + "end": 3108, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": 3121, + "end": 3156, + "name": "PUSH", + "source": 2, + "value": "40" + }, + { + "begin": 3121, + "end": 3156, + "name": "MLOAD", + "source": 2 + }, + { + "begin": 3121, + "end": 3156, + "name": "PUSH", + "source": 2, + "value": "6085CD8200000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 3121, + "end": 3156, + "name": "DUP2", + "source": 2 + }, + { + "begin": 3121, + "end": 3156, + "name": "MSTORE", + "source": 2 + }, + { + "begin": 11707, + "end": 11773, + "name": "PUSH", + "source": 22, + "value": "FF00000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 11695, + "end": 11774, + "name": "DUP3", + "source": 22 + }, + { + "begin": 11695, + "end": 11774, + "name": "AND", + "source": 22 + }, + { + "begin": 3121, + "end": 3156, + "name": "PUSH", + "source": 2, + "value": "4" + }, + { + "begin": 3121, + "end": 3156, + "name": "DUP3", + "source": 2 + }, + { + "begin": 3121, + "end": 3156, + "name": "ADD", + "source": 2 + }, + { + "begin": 11677, + "end": 11775, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 11650, + "end": 11668, + "name": "PUSH", + "source": 22, + "value": "24" + }, + { + "begin": 11650, + "end": 11668, + "name": "ADD", + "source": 22 + }, + { + "begin": 3121, + "end": 3156, + "name": "PUSH [tag]", + "source": 2, + "value": "93" + }, + { + "begin": 11533, + "end": 11781, + "name": "JUMP", + "source": 22 + }, + { + "begin": 1675, + "end": 3161, + "name": "tag", + "source": 2, + "value": "110" + }, + { + "begin": 1675, + "end": 3161, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": 1675, + "end": 3161, + "name": "SWAP4", + "source": 2 + }, + { + "begin": 1675, + "end": 3161, + "name": "SWAP8", + "source": 2 + }, + { + "begin": 1675, + "end": 3161, + "name": "SWAP3", + "source": 2 + }, + { + "begin": 1675, + "end": 3161, + "name": "SWAP7", + "source": 2 + }, + { + "begin": 1675, + "end": 3161, + "name": "POP", + "source": 2 + }, + { + "begin": 1675, + "end": 3161, + "name": "SWAP4", + "source": 2 + }, + { + "begin": 1675, + "end": 3161, + "name": "POP", + "source": 2 + }, + { + "begin": 1675, + "end": 3161, + "name": "SWAP4", + "source": 2 + }, + { + "begin": 1675, + "end": 3161, + "name": "POP", + "source": 2 + }, + { + "begin": 1675, + "end": 3161, + "jumpType": "[out]", + "name": "JUMP", + "source": 2 + }, + { + "begin": 938, + "end": 1094, + "name": "tag", + "source": 6, + "value": "66" + }, + { + "begin": 938, + "end": 1094, + "name": "JUMPDEST", + "source": 6 + }, + { + "begin": 1002, + "end": 1009, + "name": "PUSH", + "source": 6, + "value": "0" + }, + { + "begin": 1032, + "end": 1088, + "name": "PUSH [tag]", + "source": 6, + "value": "80" + }, + { + "begin": 453, + "end": 519, + "name": "PUSH", + "source": 6, + "value": "8D0BF1FD623D628C741362C1289948E57B3E2905218C676D3E69ABEE36D6AE2E" + }, + { + "begin": 1080, + "end": 1086, + "name": "DUP4", + "source": 6 + }, + { + "begin": 1032, + "end": 1060, + "name": "PUSH [tag]", + "source": 6, + "value": "133" + }, + { + "begin": 1032, + "end": 1088, + "jumpType": "[in]", + "name": "JUMP", + "source": 6 + }, + { + "begin": 456, + "end": 732, + "name": "tag", + "source": 4, + "value": "72" + }, + { + "begin": 456, + "end": 732, + "name": "JUMPDEST", + "source": 4 + }, + { + "begin": 550, + "end": 562, + "name": "PUSH", + "source": 4, + "value": "0" + }, + { + "begin": 178, + "end": 188, + "name": "CALLER", + "source": 8 + }, + { + "begin": 200, + "end": 204, + "name": "ADDRESS", + "source": 8 + }, + { + "begin": 178, + "end": 205, + "name": "EQ", + "source": 8 + }, + { + "begin": 174, + "end": 268, + "name": "PUSH [tag]", + "source": 8, + "value": "135" + }, + { + "begin": 174, + "end": 268, + "name": "JUMPI", + "source": 8 + }, + { + "begin": 222, + "end": 261, + "name": "PUSH", + "source": 8, + "value": "40" + }, + { + "begin": 222, + "end": 261, + "name": "MLOAD", + "source": 8 + }, + { + "begin": 222, + "end": 261, + "name": "PUSH", + "source": 8, + "value": "E125889400000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 222, + "end": 261, + "name": "DUP2", + "source": 8 + }, + { + "begin": 222, + "end": 261, + "name": "MSTORE", + "source": 8 + }, + { + "begin": 235, + "end": 245, + "name": "CALLER", + "source": 8 + }, + { + "begin": 222, + "end": 261, + "name": "PUSH", + "source": 8, + "value": "4" + }, + { + "begin": 222, + "end": 261, + "name": "DUP3", + "source": 8 + }, + { + "begin": 222, + "end": 261, + "name": "ADD", + "source": 8 + }, + { + "begin": 7319, + "end": 7353, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 255, + "end": 259, + "name": "ADDRESS", + "source": 8 + }, + { + "begin": 7369, + "end": 7387, + "name": "PUSH", + "source": 22, + "value": "24" + }, + { + "begin": 7369, + "end": 7387, + "name": "DUP3", + "source": 22 + }, + { + "begin": 7369, + "end": 7387, + "name": "ADD", + "source": 22 + }, + { + "begin": 7362, + "end": 7405, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 7231, + "end": 7249, + "name": "PUSH", + "source": 22, + "value": "44" + }, + { + "begin": 7231, + "end": 7249, + "name": "ADD", + "source": 22 + }, + { + "begin": 222, + "end": 261, + "name": "PUSH [tag]", + "source": 8, + "value": "93" + }, + { + "begin": 7084, + "end": 7411, + "name": "JUMP", + "source": 22 + }, + { + "begin": 174, + "end": 268, + "name": "tag", + "source": 8, + "value": "135" + }, + { + "begin": 174, + "end": 268, + "name": "JUMPDEST", + "source": 8 + }, + { + "begin": 631, + "end": 636, + "modifierDepth": 1, + "name": "DUP2", + "source": 4 + }, + { + "begin": 625, + "end": 637, + "modifierDepth": 1, + "name": "MLOAD", + "source": 4 + }, + { + "begin": 620, + "end": 622, + "modifierDepth": 1, + "name": "PUSH", + "source": 4, + "value": "20" + }, + { + "begin": 613, + "end": 618, + "modifierDepth": 1, + "name": "DUP4", + "source": 4 + }, + { + "begin": 609, + "end": 623, + "modifierDepth": 1, + "name": "ADD", + "source": 4 + }, + { + "begin": 596, + "end": 607, + "modifierDepth": 1, + "name": "CALLVALUE", + "source": 4 + }, + { + "begin": 589, + "end": 638, + "modifierDepth": 1, + "name": "CREATE", + "source": 4 + }, + { + "begin": 581, + "end": 638, + "name": "SWAP1", + "source": 4 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 649, + "end": 667, + "modifierDepth": 1, + "name": "PUSH", + "source": 4, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { + "begin": 649, + "end": 667, + "name": "DUP2", + "source": 4 + }, + { + "begin": 649, + "end": 667, + "modifierDepth": 1, + "name": "AND", + "source": 4 + }, + { + "begin": 645, + "end": 695, + "modifierDepth": 1, + "name": "PUSH [tag]", + "source": 4, + "value": "138" + }, + { + "begin": 645, + "end": 695, + "modifierDepth": 1, + "name": "JUMPI", + "source": 4 + }, + { + "begin": 689, + "end": 694, + "modifierDepth": 1, + "name": "DUP2", + "source": 4 + }, + { + "begin": 676, + "end": 695, + "modifierDepth": 1, + "name": "PUSH", + "source": 4, + "value": "40" + }, + { + "begin": 676, + "end": 695, + "modifierDepth": 1, + "name": "MLOAD", + "source": 4 + }, + { + "begin": 676, + "end": 695, + "modifierDepth": 1, + "name": "PUSH", + "source": 4, + "value": "D25719100000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 676, + "end": 695, + "modifierDepth": 1, + "name": "DUP2", + "source": 4 + }, + { + "begin": 676, + "end": 695, + "modifierDepth": 1, + "name": "MSTORE", + "source": 4 + }, + { + "begin": 676, + "end": 695, + "modifierDepth": 1, + "name": "PUSH", + "source": 4, + "value": "4" + }, + { + "begin": 676, + "end": 695, + "modifierDepth": 1, + "name": "ADD", + "source": 4 + }, + { + "begin": 676, + "end": 695, + "modifierDepth": 1, + "name": "PUSH [tag]", + "source": 4, + "value": "93" + }, + { + "begin": 676, + "end": 695, + "modifierDepth": 1, + "name": "SWAP2", + "source": 4 + }, + { + "begin": 676, + "end": 695, + "modifierDepth": 1, + "name": "SWAP1", + "source": 4 + }, + { + "begin": 676, + "end": 695, + "modifierDepth": 1, + "name": "PUSH [tag]", + "source": 4, + "value": "140" + }, + { + "begin": 676, + "end": 695, + "jumpType": "[in]", + "modifierDepth": 1, + "name": "JUMP", + "source": 4 + }, + { + "begin": 645, + "end": 695, + "modifierDepth": 1, + "name": "tag", + "source": 4, + "value": "138" + }, + { + "begin": 645, + "end": 695, + "modifierDepth": 1, + "name": "JUMPDEST", + "source": 4 + }, + { + "begin": 706, + "end": 727, + "modifierDepth": 1, + "name": "PUSH", + "source": 4, + "value": "40" + }, + { + "begin": 706, + "end": 727, + "name": "MLOAD", + "source": 4 + }, + { + "begin": 6753, + "end": 6795, + "name": "PUSH", + "source": 22, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { + "begin": 6741, + "end": 6796, + "name": "DUP3", + "source": 22 + }, + { + "begin": 6741, + "end": 6796, + "name": "AND", + "source": 22 + }, + { + "begin": 6723, + "end": 6797, + "name": "DUP2", + "source": 22 + }, + { + "begin": 6723, + "end": 6797, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 706, + "end": 727, + "modifierDepth": 1, + "name": "PUSH", + "source": 4, + "value": "A506AD4E7F05ECEBA62A023C3219E5BD98A615F4FA87E2AFB08A2DA5CF62BF0C" + }, + { + "begin": 706, + "end": 727, + "name": "SWAP1", + "source": 4 + }, + { + "begin": 6711, + "end": 6713, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 6696, + "end": 6714, + "name": "ADD", + "source": 22 + }, + { + "begin": 706, + "end": 727, + "modifierDepth": 1, + "name": "PUSH", + "source": 4, + "value": "40" + }, + { + "begin": 706, + "end": 727, + "modifierDepth": 1, + "name": "MLOAD", + "source": 4 + }, + { + "begin": 706, + "end": 727, + "modifierDepth": 1, + "name": "DUP1", + "source": 4 + }, + { + "begin": 706, + "end": 727, + "modifierDepth": 1, + "name": "SWAP2", + "source": 4 + }, + { + "begin": 706, + "end": 727, + "modifierDepth": 1, + "name": "SUB", + "source": 4 + }, + { + "begin": 706, + "end": 727, + "modifierDepth": 1, + "name": "SWAP1", + "source": 4 + }, + { + "begin": 706, + "end": 727, + "modifierDepth": 1, + "name": "LOG1", + "source": 4 + }, + { + "begin": 456, + "end": 732, + "name": "SWAP2", + "source": 4 + }, + { + "begin": 456, + "end": 732, + "name": "SWAP1", + "source": 4 + }, + { + "begin": 456, + "end": 732, + "name": "POP", + "source": 4 + }, + { + "begin": 456, + "end": 732, + "jumpType": "[out]", + "name": "JUMP", + "source": 4 + }, + { + "begin": 670, + "end": 757, + "name": "tag", + "source": 6, + "value": "77" + }, + { + "begin": 670, + "end": 757, + "name": "JUMPDEST", + "source": 6 + }, + { + "begin": 718, + "end": 725, + "name": "PUSH", + "source": 6, + "value": "0" + }, + { + "begin": 740, + "end": 752, + "name": "PUSH [tag]", + "source": 6, + "value": "143" + }, + { + "begin": 750, + "end": 751, + "name": "PUSH", + "source": 6, + "value": "0" + }, + { + "begin": 740, + "end": 749, + "name": "PUSH [tag]", + "source": 6, + "value": "66" + }, + { + "begin": 740, + "end": 752, + "jumpType": "[in]", + "name": "JUMP", + "source": 6 + }, + { + "begin": 740, + "end": 752, + "name": "tag", + "source": 6, + "value": "143" + }, + { + "begin": 740, + "end": 752, + "name": "JUMPDEST", + "source": 6 + }, + { + "begin": 733, + "end": 752, + "name": "SWAP1", + "source": 6 + }, + { + "begin": 733, + "end": 752, + "name": "POP", + "source": 6 + }, + { + "begin": 670, + "end": 757, + "name": "SWAP1", + "source": 6 + }, + { + "begin": 670, + "end": 757, + "jumpType": "[out]", + "name": "JUMP", + "source": 6 + }, + { + "begin": 942, + "end": 1175, + "name": "tag", + "source": 4, + "value": "81" + }, + { + "begin": 942, + "end": 1175, + "name": "JUMPDEST", + "source": 4 + }, + { + "begin": 1028, + "end": 1032, + "name": "PUSH", + "source": 4, + "value": "0" + }, + { + "begin": 1044, + "end": 1092, + "name": "PUSH", + "source": 4, + "value": "6FFBD45100000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 1044, + "end": 1092, + "name": "PUSH", + "source": 4, + "value": "FFFFFFFF00000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 1044, + "end": 1092, + "name": "DUP4", + "source": 4 + }, + { + "begin": 1044, + "end": 1092, + "name": "AND", + "source": 4 + }, + { + "begin": 1044, + "end": 1092, + "name": "ADD", + "source": 4 + }, + { + "begin": 1040, + "end": 1120, + "name": "PUSH [tag]", + "source": 4, + "value": "145" + }, + { + "begin": 1040, + "end": 1120, + "name": "JUMPI", + "source": 4 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 1109, + "end": 1113, + "name": "PUSH", + "source": 4, + "value": "1" + }, + { + "begin": 1109, + "end": 1113, + "name": "SWAP2", + "source": 4 + }, + { + "begin": 942, + "end": 1175, + "name": "SWAP1", + "source": 4 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 942, + "end": 1175, + "jumpType": "[out]", + "name": "JUMP", + "source": 4 + }, + { + "begin": 1040, + "end": 1120, + "name": "tag", + "source": 4, + "value": "145" + }, + { + "begin": 1040, + "end": 1120, + "name": "JUMPDEST", + "source": 4 + }, + { + "begin": 1133, + "end": 1170, + "name": "PUSH [tag]", + "source": 4, + "value": "80" + }, + { + "begin": 1157, + "end": 1169, + "name": "DUP3", + "source": 4 + }, + { + "begin": 1133, + "end": 1156, + "name": "PUSH [tag]", + "source": 4, + "value": "147" + }, + { + "begin": 1133, + "end": 1170, + "jumpType": "[in]", + "name": "JUMP", + "source": 4 + }, + { + "begin": 3480, + "end": 3866, + "name": "tag", + "source": 2, + "value": "84" + }, + { + "begin": 3480, + "end": 3866, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": 3611, + "end": 3623, + "name": "PUSH", + "source": 2, + "value": "0" + }, + { + "begin": 3629, + "end": 3646, + "name": "DUP1", + "source": 2 + }, + { + "begin": 3657, + "end": 3674, + "name": "PUSH", + "source": 2, + "value": "0" + }, + { + "begin": 3676, + "end": 3690, + "name": "DUP1", + "source": 2 + }, + { + "begin": 3692, + "end": 3709, + "name": "PUSH", + "source": 2, + "value": "0" + }, + { + "begin": 3760, + "end": 3798, + "name": "PUSH [tag]", + "source": 2, + "value": "149" + }, + { + "begin": 3778, + "end": 3785, + "name": "DUP9", + "source": 2 + }, + { + "begin": 3787, + "end": 3797, + "name": "DUP9", + "source": 2 + }, + { + "begin": 3787, + "end": 3797, + "name": "DUP9", + "source": 2 + }, + { + "begin": 3760, + "end": 3777, + "name": "PUSH [tag]", + "source": 2, + "value": "59" + }, + { + "begin": 3760, + "end": 3798, + "jumpType": "[in]", + "name": "JUMP", + "source": 2 + }, + { + "begin": 3760, + "end": 3798, + "name": "tag", + "source": 2, + "value": "149" + }, + { + "begin": 3760, + "end": 3798, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 3715, + "end": 3798, + "name": "SWAP7", + "source": 2 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 3715, + "end": 3798, + "name": "SWAP2", + "source": 2 + }, + { + "begin": 3715, + "end": 3798, + "name": "SWAP5", + "source": 2 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 3715, + "end": 3798, + "name": "SWAP3", + "source": 2 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 3715, + "end": 3798, + "name": "SWAP1", + "source": 2 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 3814, + "end": 3833, + "name": "DUP3", + "source": 2 + }, + { + "begin": 3814, + "end": 3833, + "name": "DUP3", + "source": 2 + }, + { + "begin": 3814, + "end": 3833, + "name": "LT", + "source": 2 + }, + { + "begin": 3814, + "end": 3833, + "name": "DUP1", + "source": 2 + }, + { + "begin": 3814, + "end": 3833, + "name": "ISZERO", + "source": 2 + }, + { + "begin": 3814, + "end": 3833, + "name": "SWAP1", + "source": 2 + }, + { + "begin": 3814, + "end": 3861, + "name": "PUSH [tag]", + "source": 2, + "value": "151" + }, + { + "begin": 3814, + "end": 3861, + "name": "JUMPI", + "source": 2 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 2779, + "end": 2783, + "name": "PUSH", + "source": 1, + "value": "1" + }, + { + "begin": 3837, + "end": 3861, + "name": "tag", + "source": 2, + "value": "151" + }, + { + "begin": 3837, + "end": 3861, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": 3804, + "end": 3861, + "name": "SWAP5", + "source": 2 + }, + { + "begin": 3804, + "end": 3861, + "name": "POP", + "source": 2 + }, + { + "begin": 3651, + "end": 3866, + "name": "POP", + "source": 2 + }, + { + "begin": 3651, + "end": 3866, + "name": "POP", + "source": 2 + }, + { + "begin": 3651, + "end": 3866, + "name": "POP", + "source": 2 + }, + { + "begin": 3480, + "end": 3866, + "name": "SWAP4", + "source": 2 + }, + { + "begin": 3480, + "end": 3866, + "name": "POP", + "source": 2 + }, + { + "begin": 3480, + "end": 3866, + "name": "SWAP4", + "source": 2 + }, + { + "begin": 3480, + "end": 3866, + "name": "SWAP2", + "source": 2 + }, + { + "begin": 3480, + "end": 3866, + "name": "POP", + "source": 2 + }, + { + "begin": 3480, + "end": 3866, + "name": "POP", + "source": 2 + }, + { + "begin": 3480, + "end": 3866, + "jumpType": "[out]", + "name": "JUMP", + "source": 2 + }, + { + "begin": 2824, + "end": 2917, + "name": "tag", + "source": 1, + "value": "97" + }, + { + "begin": 2824, + "end": 2917, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 2898, + "end": 2912, + "name": "PUSH", + "source": 1, + "value": "40" + }, + { + "begin": 2898, + "end": 2912, + "name": "MLOAD", + "source": 1 + }, + { + "begin": 2898, + "end": 2912, + "name": "PUSH", + "source": 1, + "value": "A038794000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 2898, + "end": 2912, + "name": "DUP2", + "source": 1 + }, + { + "begin": 2898, + "end": 2912, + "name": "MSTORE", + "source": 1 + }, + { + "begin": 2898, + "end": 2912, + "name": "PUSH", + "source": 1, + "value": "4" + }, + { + "begin": 2898, + "end": 2912, + "name": "ADD", + "source": 1 + }, + { + "begin": 2898, + "end": 2912, + "name": "PUSH", + "source": 1, + "value": "40" + }, + { + "begin": 2898, + "end": 2912, + "name": "MLOAD", + "source": 1 + }, + { + "begin": 2898, + "end": 2912, + "name": "DUP1", + "source": 1 + }, + { + "begin": 2898, + "end": 2912, + "name": "SWAP2", + "source": 1 + }, + { + "begin": 2898, + "end": 2912, + "name": "SUB", + "source": 1 + }, + { + "begin": 2898, + "end": 2912, + "name": "SWAP1", + "source": 1 + }, + { + "begin": 2898, + "end": 2912, + "name": "REVERT", + "source": 1 + }, + { + "begin": 1173, + "end": 1397, + "name": "tag", + "source": 13, + "value": "102" + }, + { + "begin": 1173, + "end": 1397, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 1279, + "end": 1386, + "name": "PUSH", + "source": 13, + "value": "40" + }, + { + "begin": 1279, + "end": 1386, + "name": "MLOAD", + "source": 13 + }, + { + "begin": 12792, + "end": 12858, + "name": "PUSH", + "source": 22, + "value": "1901000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 1279, + "end": 1386, + "name": "PUSH", + "source": 13, + "value": "20" + }, + { + "begin": 1279, + "end": 1386, + "name": "DUP3", + "source": 13 + }, + { + "begin": 1279, + "end": 1386, + "name": "ADD", + "source": 13 + }, + { + "begin": 12780, + "end": 12859, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 1325, + "end": 1338, + "name": "CHAINID", + "source": 13 + }, + { + "begin": 12875, + "end": 12886, + "name": "PUSH", + "source": 22, + "value": "22" + }, + { + "begin": 12875, + "end": 12886, + "name": "DUP3", + "source": 22 + }, + { + "begin": 12875, + "end": 12886, + "name": "ADD", + "source": 22 + }, + { + "begin": 12868, + "end": 12895, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 12946, + "end": 13012, + "name": "PUSH", + "source": 22, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000" + }, + { + "begin": 1356, + "end": 1360, + "name": "ADDRESS", + "source": 13 + }, + { + "begin": 12933, + "end": 12935, + "name": "PUSH", + "source": 22, + "value": "60" + }, + { + "begin": 12929, + "end": 12944, + "name": "SHL", + "source": 22 + }, + { + "begin": 12925, + "end": 13013, + "name": "AND", + "source": 22 + }, + { + "begin": 12911, + "end": 12923, + "name": "PUSH", + "source": 22, + "value": "42" + }, + { + "begin": 12911, + "end": 12923, + "name": "DUP3", + "source": 22 + }, + { + "begin": 12911, + "end": 12923, + "name": "ADD", + "source": 22 + }, + { + "begin": 12904, + "end": 13014, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 13030, + "end": 13042, + "name": "PUSH", + "source": 22, + "value": "56" + }, + { + "begin": 13030, + "end": 13042, + "name": "DUP2", + "source": 22 + }, + { + "begin": 13030, + "end": 13042, + "name": "ADD", + "source": 22 + }, + { + "begin": 13023, + "end": 13051, + "name": "DUP3", + "source": 22 + }, + { + "begin": 13023, + "end": 13051, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 13023, + "end": 13051, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 1240, + "end": 1247, + "name": "PUSH", + "source": 13, + "value": "0" + }, + { + "begin": 1240, + "end": 1247, + "name": "SWAP1", + "source": 13 + }, + { + "begin": 13067, + "end": 13079, + "name": "PUSH", + "source": 22, + "value": "76" + }, + { + "begin": 13067, + "end": 13079, + "name": "ADD", + "source": 22 + }, + { + "begin": 1279, + "end": 1386, + "name": "tag", + "source": 13, + "value": "155" + }, + { + "begin": 1279, + "end": 1386, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 1279, + "end": 1386, + "name": "PUSH", + "source": 13, + "value": "40" + }, + { + "begin": 1279, + "end": 1386, + "name": "MLOAD", + "source": 13 + }, + { + "begin": 1279, + "end": 1386, + "name": "PUSH", + "source": 13, + "value": "20" + }, + { + "begin": 1279, + "end": 1386, + "name": "DUP2", + "source": 13 + }, + { + "begin": 1279, + "end": 1386, + "name": "DUP4", + "source": 13 + }, + { + "begin": 1279, + "end": 1386, + "name": "SUB", + "source": 13 + }, + { + "begin": 1279, + "end": 1386, + "name": "SUB", + "source": 13 + }, + { + "begin": 1279, + "end": 1386, + "name": "DUP2", + "source": 13 + }, + { + "begin": 1279, + "end": 1386, + "name": "MSTORE", + "source": 13 + }, + { + "begin": 1279, + "end": 1386, + "name": "SWAP1", + "source": 13 + }, + { + "begin": 1279, + "end": 1386, + "name": "PUSH", + "source": 13, + "value": "40" + }, + { + "begin": 1279, + "end": 1386, + "name": "MSTORE", + "source": 13 + }, + { + "begin": 1262, + "end": 1392, + "name": "DUP1", + "source": 13 + }, + { + "begin": 1262, + "end": 1392, + "name": "MLOAD", + "source": 13 + }, + { + "begin": 1262, + "end": 1392, + "name": "SWAP1", + "source": 13 + }, + { + "begin": 1262, + "end": 1392, + "name": "PUSH", + "source": 13, + "value": "20" + }, + { + "begin": 1262, + "end": 1392, + "name": "ADD", + "source": 13 + }, + { + "begin": 1262, + "end": 1392, + "name": "KECCAK256", + "source": 13 + }, + { + "begin": 1255, + "end": 1392, + "name": "SWAP1", + "source": 13 + }, + { + "begin": 1255, + "end": 1392, + "name": "POP", + "source": 13 + }, + { + "begin": 1173, + "end": 1397, + "name": "SWAP2", + "source": 13 + }, + { + "begin": 1173, + "end": 1397, + "name": "SWAP1", + "source": 13 + }, + { + "begin": 1173, + "end": 1397, + "name": "POP", + "source": 13 + }, + { + "begin": 1173, + "end": 1397, + "jumpType": "[out]", + "name": "JUMP", + "source": 13 + }, + { + "begin": 1710, + "end": 2544, + "name": "tag", + "source": 1, + "value": "104" + }, + { + "begin": 1710, + "end": 2544, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 1847, + "end": 1851, + "name": "DUP1", + "source": 1 + }, + { + "begin": 1832, + "end": 1844, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 1864, + "end": 2540, + "name": "tag", + "source": 1, + "value": "158" + }, + { + "begin": 1864, + "end": 2540, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 1888, + "end": 1892, + "name": "DUP2", + "source": 1 + }, + { + "begin": 1884, + "end": 1885, + "name": "DUP2", + "source": 1 + }, + { + "begin": 1884, + "end": 1892, + "name": "LT", + "source": 1 + }, + { + "begin": 1864, + "end": 2540, + "name": "ISZERO", + "source": 1 + }, + { + "begin": 1864, + "end": 2540, + "name": "PUSH [tag]", + "source": 1, + "value": "159" + }, + { + "begin": 1864, + "end": 2540, + "name": "JUMPI", + "source": 1 + }, + { + "begin": 1907, + "end": 1939, + "name": "CALLDATASIZE", + "source": 1 + }, + { + "begin": 1942, + "end": 1946, + "name": "DUP5", + "source": 1 + }, + { + "begin": 1942, + "end": 1946, + "name": "DUP5", + "source": 1 + }, + { + "begin": 1947, + "end": 1948, + "name": "DUP4", + "source": 1 + }, + { + "begin": 1942, + "end": 1949, + "name": "DUP2", + "source": 1 + }, + { + "begin": 1942, + "end": 1949, + "name": "DUP2", + "source": 1 + }, + { + "begin": 1942, + "end": 1949, + "name": "LT", + "source": 1 + }, + { + "begin": 1942, + "end": 1949, + "name": "PUSH [tag]", + "source": 1, + "value": "162" + }, + { + "begin": 1942, + "end": 1949, + "name": "JUMPI", + "source": 1 + }, + { + "begin": 1942, + "end": 1949, + "name": "PUSH [tag]", + "source": 1, + "value": "162" + }, + { + "begin": 1942, + "end": 1949, + "name": "PUSH [tag]", + "source": 1, + "value": "113" + }, + { + "begin": 1942, + "end": 1949, + "jumpType": "[in]", + "name": "JUMP", + "source": 1 + }, + { + "begin": 1942, + "end": 1949, + "name": "tag", + "source": 1, + "value": "162" + }, + { + "begin": 1942, + "end": 1949, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 1942, + "end": 1949, + "name": "SWAP1", + "source": 1 + }, + { + "begin": 1942, + "end": 1949, + "name": "POP", + "source": 1 + }, + { + "begin": 1942, + "end": 1949, + "name": "PUSH", + "source": 1, + "value": "20" + }, + { + "begin": 1942, + "end": 1949, + "name": "MUL", + "source": 1 + }, + { + "begin": 1942, + "end": 1949, + "name": "DUP2", + "source": 1 + }, + { + "begin": 1942, + "end": 1949, + "name": "ADD", + "source": 1 + }, + { + "begin": 1942, + "end": 1949, + "name": "SWAP1", + "source": 1 + }, + { + "begin": 1942, + "end": 1949, + "name": "PUSH [tag]", + "source": 1, + "value": "163" + }, + { + "begin": 1942, + "end": 1949, + "name": "SWAP2", + "source": 1 + }, + { + "begin": 1942, + "end": 1949, + "name": "SWAP1", + "source": 1 + }, + { + "begin": 1942, + "end": 1949, + "name": "PUSH [tag]", + "source": 1, + "value": "164" + }, + { + "begin": 1942, + "end": 1949, + "jumpType": "[in]", + "name": "JUMP", + "source": 1 + }, + { + "begin": 1942, + "end": 1949, + "name": "tag", + "source": 1, + "value": "163" + }, + { + "begin": 1942, + "end": 1949, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 1907, + "end": 1949, + "name": "SWAP1", + "source": 1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 1962, + "end": 1986, + "name": "PUSH [tag]", + "source": 1, + "value": "165" + }, + { + "begin": 1962, + "end": 1986, + "name": "PUSH", + "source": 1, + "value": "20" + }, + { + "begin": 1962, + "end": 1986, + "name": "DUP3", + "source": 1 + }, + { + "begin": 1962, + "end": 1986, + "name": "ADD", + "source": 1 + }, + { + "begin": 1907, + "end": 1949, + "name": "DUP3", + "source": 1 + }, + { + "begin": 1962, + "end": 1986, + "name": "PUSH [tag]", + "source": 1, + "value": "166" + }, + { + "begin": 1962, + "end": 1986, + "jumpType": "[in]", + "name": "JUMP", + "source": 1 + }, + { + "begin": 1962, + "end": 1986, + "name": "tag", + "source": 1, + "value": "165" + }, + { + "begin": 1962, + "end": 1986, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 1958, + "end": 2020, + "name": "ISZERO", + "source": 1 + }, + { + "begin": 1958, + "end": 2020, + "name": "PUSH [tag]", + "source": 1, + "value": "167" + }, + { + "begin": 1958, + "end": 2020, + "name": "JUMPI", + "source": 1 + }, + { + "begin": 1995, + "end": 2020, + "name": "PUSH", + "source": 1, + "value": "40" + }, + { + "begin": 1995, + "end": 2020, + "name": "MLOAD", + "source": 1 + }, + { + "begin": 1995, + "end": 2020, + "name": "PUSH", + "source": 1, + "value": "230D1CCC00000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 1995, + "end": 2020, + "name": "DUP2", + "source": 1 + }, + { + "begin": 1995, + "end": 2020, + "name": "MSTORE", + "source": 1 + }, + { + "begin": 1995, + "end": 2020, + "name": "PUSH", + "source": 1, + "value": "4" + }, + { + "begin": 1995, + "end": 2020, + "name": "DUP2", + "source": 1 + }, + { + "begin": 1995, + "end": 2020, + "name": "ADD", + "source": 1 + }, + { + "begin": 2778, + "end": 2803, + "name": "DUP4", + "source": 22 + }, + { + "begin": 2778, + "end": 2803, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 2778, + "end": 2803, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 2751, + "end": 2769, + "name": "PUSH", + "source": 22, + "value": "24" + }, + { + "begin": 2751, + "end": 2769, + "name": "ADD", + "source": 22 + }, + { + "begin": 1995, + "end": 2020, + "name": "PUSH [tag]", + "source": 1, + "value": "93" + }, + { + "begin": 2632, + "end": 2809, + "name": "JUMP", + "source": 22 + }, + { + "begin": 1958, + "end": 2020, + "name": "tag", + "source": 1, + "value": "167" + }, + { + "begin": 1958, + "end": 2020, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 2048, + "end": 2068, + "name": "PUSH", + "source": 1, + "value": "40" + }, + { + "begin": 2048, + "end": 2068, + "name": "DUP2", + "source": 1 + }, + { + "begin": 2048, + "end": 2068, + "name": "ADD", + "source": 1 + }, + { + "begin": 2048, + "end": 2068, + "name": "CALLDATALOAD", + "source": 1 + }, + { + "begin": 2048, + "end": 2068, + "name": "DUP1", + "source": 1 + }, + { + "begin": 2080, + "end": 2089, + "name": "GAS", + "source": 1 + }, + { + "begin": 2080, + "end": 2100, + "name": "LT", + "source": 1 + }, + { + "begin": 2076, + "end": 2145, + "name": "ISZERO", + "source": 1 + }, + { + "begin": 2076, + "end": 2145, + "name": "PUSH [tag]", + "source": 1, + "value": "169" + }, + { + "begin": 2076, + "end": 2145, + "name": "JUMPI", + "source": 1 + }, + { + "begin": 2122, + "end": 2123, + "name": "DUP3", + "source": 1 + }, + { + "begin": 2125, + "end": 2133, + "name": "DUP2", + "source": 1 + }, + { + "begin": 2135, + "end": 2144, + "name": "GAS", + "source": 1 + }, + { + "begin": 2109, + "end": 2145, + "name": "PUSH", + "source": 1, + "value": "40" + }, + { + "begin": 2109, + "end": 2145, + "name": "MLOAD", + "source": 1 + }, + { + "begin": 2109, + "end": 2145, + "name": "PUSH", + "source": 1, + "value": "2BB3E3BA00000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 2109, + "end": 2145, + "name": "DUP2", + "source": 1 + }, + { + "begin": 2109, + "end": 2145, + "name": "MSTORE", + "source": 1 + }, + { + "begin": 2109, + "end": 2145, + "name": "PUSH", + "source": 1, + "value": "4" + }, + { + "begin": 2109, + "end": 2145, + "name": "DUP2", + "source": 1 + }, + { + "begin": 2109, + "end": 2145, + "name": "ADD", + "source": 1 + }, + { + "begin": 13869, + "end": 13894, + "name": "SWAP4", + "source": 22 + }, + { + "begin": 13869, + "end": 13894, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 13869, + "end": 13894, + "name": "SWAP4", + "source": 22 + }, + { + "begin": 13869, + "end": 13894, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 13910, + "end": 13928, + "name": "PUSH", + "source": 22, + "value": "24" + }, + { + "begin": 13910, + "end": 13928, + "name": "DUP4", + "source": 22 + }, + { + "begin": 13910, + "end": 13928, + "name": "ADD", + "source": 22 + }, + { + "begin": 13903, + "end": 13937, + "name": "SWAP2", + "source": 22 + }, + { + "begin": 13903, + "end": 13937, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 13903, + "end": 13937, + "name": "SWAP2", + "source": 22 + }, + { + "begin": 13903, + "end": 13937, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 13953, + "end": 13971, + "name": "PUSH", + "source": 22, + "value": "44" + }, + { + "begin": 13953, + "end": 13971, + "name": "DUP3", + "source": 22 + }, + { + "begin": 13953, + "end": 13971, + "name": "ADD", + "source": 22 + }, + { + "begin": 13946, + "end": 13980, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 13842, + "end": 13860, + "name": "PUSH", + "source": 22, + "value": "64" + }, + { + "begin": 13842, + "end": 13860, + "name": "ADD", + "source": 22 + }, + { + "begin": 2109, + "end": 2145, + "name": "PUSH [tag]", + "source": 1, + "value": "93" + }, + { + "begin": 13667, + "end": 13986, + "name": "JUMP", + "source": 22 + }, + { + "begin": 2076, + "end": 2145, + "name": "tag", + "source": 1, + "value": "169" + }, + { + "begin": 2076, + "end": 2145, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 2154, + "end": 2166, + "name": "PUSH", + "source": 1, + "value": "0" + }, + { + "begin": 2169, + "end": 2317, + "name": "PUSH [tag]", + "source": 1, + "value": "172" + }, + { + "begin": 2192, + "end": 2210, + "name": "PUSH [tag]", + "source": 1, + "value": "173" + }, + { + "begin": 2192, + "end": 2210, + "name": "PUSH", + "source": 1, + "value": "80" + }, + { + "begin": 2192, + "end": 2210, + "name": "DUP6", + "source": 1 + }, + { + "begin": 2192, + "end": 2210, + "name": "ADD", + "source": 1 + }, + { + "begin": 2192, + "end": 2210, + "name": "PUSH", + "source": 1, + "value": "60" + }, + { + "begin": 2192, + "end": 2210, + "name": "DUP7", + "source": 1 + }, + { + "begin": 2192, + "end": 2210, + "name": "ADD", + "source": 1 + }, + { + "begin": 2192, + "end": 2210, + "name": "PUSH [tag]", + "source": 1, + "value": "174" + }, + { + "begin": 2192, + "end": 2210, + "jumpType": "[in]", + "name": "JUMP", + "source": 1 + }, + { + "begin": 2192, + "end": 2210, + "name": "tag", + "source": 1, + "value": "173" + }, + { + "begin": 2192, + "end": 2210, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 2220, + "end": 2237, + "name": "PUSH", + "source": 1, + "value": "80" + }, + { + "begin": 2220, + "end": 2237, + "name": "DUP6", + "source": 1 + }, + { + "begin": 2220, + "end": 2237, + "name": "ADD", + "source": 1 + }, + { + "begin": 2220, + "end": 2237, + "name": "CALLDATALOAD", + "source": 1 + }, + { + "begin": 2247, + "end": 2260, + "name": "DUP5", + "source": 1 + }, + { + "begin": 2247, + "end": 2260, + "name": "ISZERO", + "source": 1 + }, + { + "begin": 2247, + "end": 2283, + "name": "PUSH [tag]", + "source": 1, + "value": "175" + }, + { + "begin": 2247, + "end": 2283, + "name": "JUMPI", + "source": 1 + }, + { + "begin": 2275, + "end": 2283, + "name": "DUP5", + "source": 1 + }, + { + "begin": 2247, + "end": 2283, + "name": "PUSH [tag]", + "source": 1, + "value": "176" + }, + { + "begin": 2247, + "end": 2283, + "name": "JUMP", + "source": 1 + }, + { + "begin": 2247, + "end": 2283, + "name": "tag", + "source": 1, + "value": "175" + }, + { + "begin": 2247, + "end": 2283, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 2263, + "end": 2272, + "name": "GAS", + "source": 1 + }, + { + "begin": 2247, + "end": 2283, + "name": "tag", + "source": 1, + "value": "176" + }, + { + "begin": 2247, + "end": 2283, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 2293, + "end": 2309, + "name": "PUSH [tag]", + "source": 1, + "value": "177" + }, + { + "begin": 2293, + "end": 2309, + "name": "PUSH", + "source": 1, + "value": "A0" + }, + { + "begin": 2293, + "end": 2309, + "name": "DUP9", + "source": 1 + }, + { + "begin": 2293, + "end": 2309, + "name": "ADD", + "source": 1 + }, + { + "begin": 2293, + "end": 2304, + "name": "DUP9", + "source": 1 + }, + { + "begin": 2293, + "end": 2309, + "name": "PUSH [tag]", + "source": 1, + "value": "178" + }, + { + "begin": 2293, + "end": 2309, + "jumpType": "[in]", + "name": "JUMP", + "source": 1 + }, + { + "begin": 2293, + "end": 2309, + "name": "tag", + "source": 1, + "value": "177" + }, + { + "begin": 2293, + "end": 2309, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 2169, + "end": 2182, + "name": "PUSH [tag]", + "source": 1, + "value": "179" + }, + { + "begin": 2169, + "end": 2317, + "jumpType": "[in]", + "name": "JUMP", + "source": 1 + }, + { + "begin": 2169, + "end": 2317, + "name": "tag", + "source": 1, + "value": "172" + }, + { + "begin": 2169, + "end": 2317, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 2154, + "end": 2317, + "name": "SWAP1", + "source": 1 + }, + { + "begin": 2154, + "end": 2317, + "name": "POP", + "source": 1 + }, + { + "begin": 2330, + "end": 2337, + "name": "DUP1", + "source": 1 + }, + { + "begin": 2326, + "end": 2534, + "name": "ISZERO", + "source": 1 + }, + { + "begin": 2326, + "end": 2534, + "name": "PUSH [tag]", + "source": 1, + "value": "180" + }, + { + "begin": 2326, + "end": 2534, + "name": "JUMPI", + "source": 1 + }, + { + "begin": 2365, + "end": 2372, + "name": "DUP8", + "source": 1 + }, + { + "begin": 2354, + "end": 2376, + "name": "PUSH", + "source": 1, + "value": "5C4EEB02DABF8976016AB414D617F9A162936DCACE3CDEF8C69EF6E262AD5AE7" + }, + { + "begin": 2374, + "end": 2375, + "name": "DUP6", + "source": 1 + }, + { + "begin": 2354, + "end": 2376, + "name": "PUSH", + "source": 1, + "value": "40" + }, + { + "begin": 2354, + "end": 2376, + "name": "MLOAD", + "source": 1 + }, + { + "begin": 2354, + "end": 2376, + "name": "PUSH [tag]", + "source": 1, + "value": "181" + }, + { + "begin": 2354, + "end": 2376, + "name": "SWAP2", + "source": 1 + }, + { + "begin": 2778, + "end": 2803, + "name": "DUP2", + "source": 22 + }, + { + "begin": 2778, + "end": 2803, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 2766, + "end": 2768, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 2751, + "end": 2769, + "name": "ADD", + "source": 22 + }, + { + "begin": 2751, + "end": 2769, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 2632, + "end": 2809, + "name": "JUMP", + "source": 22 + }, + { + "begin": 2354, + "end": 2376, + "name": "tag", + "source": 1, + "value": "181" + }, + { + "begin": 2354, + "end": 2376, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 2354, + "end": 2376, + "name": "PUSH", + "source": 1, + "value": "40" + }, + { + "begin": 2354, + "end": 2376, + "name": "MLOAD", + "source": 1 + }, + { + "begin": 2354, + "end": 2376, + "name": "DUP1", + "source": 1 + }, + { + "begin": 2354, + "end": 2376, + "name": "SWAP2", + "source": 1 + }, + { + "begin": 2354, + "end": 2376, + "name": "SUB", + "source": 1 + }, + { + "begin": 2354, + "end": 2376, + "name": "SWAP1", + "source": 1 + }, + { + "begin": 2354, + "end": 2376, + "name": "LOG2", + "source": 1 + }, + { + "begin": 2326, + "end": 2534, + "name": "PUSH [tag]", + "source": 1, + "value": "183" + }, + { + "begin": 2326, + "end": 2534, + "name": "JUMP", + "source": 1 + }, + { + "begin": 2326, + "end": 2534, + "name": "tag", + "source": 1, + "value": "180" + }, + { + "begin": 2326, + "end": 2534, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 2401, + "end": 2525, + "name": "PUSH [tag]", + "source": 1, + "value": "183" + }, + { + "begin": 2425, + "end": 2450, + "name": "PUSH [tag]", + "source": 1, + "value": "184" + }, + { + "begin": 2425, + "end": 2450, + "name": "PUSH", + "source": 1, + "value": "40" + }, + { + "begin": 2425, + "end": 2450, + "name": "DUP6", + "source": 1 + }, + { + "begin": 2425, + "end": 2450, + "name": "ADD", + "source": 1 + }, + { + "begin": 2425, + "end": 2450, + "name": "PUSH", + "source": 1, + "value": "20" + }, + { + "begin": 2425, + "end": 2450, + "name": "DUP7", + "source": 1 + }, + { + "begin": 2425, + "end": 2450, + "name": "ADD", + "source": 1 + }, + { + "begin": 2425, + "end": 2450, + "name": "PUSH [tag]", + "source": 1, + "value": "166" + }, + { + "begin": 2425, + "end": 2450, + "jumpType": "[in]", + "name": "JUMP", + "source": 1 + }, + { + "begin": 2425, + "end": 2450, + "name": "tag", + "source": 1, + "value": "184" + }, + { + "begin": 2425, + "end": 2450, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 2462, + "end": 2469, + "name": "DUP10", + "source": 1 + }, + { + "begin": 2481, + "end": 2482, + "name": "DUP7", + "source": 1 + }, + { + "begin": 2494, + "end": 2515, + "name": "PUSH [tag]", + "source": 1, + "value": "185" + }, + { + "begin": 2494, + "end": 2513, + "name": "PUSH [tag]", + "source": 1, + "value": "186" + }, + { + "begin": 2494, + "end": 2515, + "jumpType": "[in]", + "name": "JUMP", + "source": 1 + }, + { + "begin": 2494, + "end": 2515, + "name": "tag", + "source": 1, + "value": "185" + }, + { + "begin": 2494, + "end": 2515, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 2401, + "end": 2413, + "name": "PUSH [tag]", + "source": 1, + "value": "187" + }, + { + "begin": 2401, + "end": 2525, + "jumpType": "[in]", + "name": "JUMP", + "source": 1 + }, + { + "begin": 2401, + "end": 2525, + "name": "tag", + "source": 1, + "value": "183" + }, + { + "begin": 2401, + "end": 2525, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 1899, + "end": 2540, + "name": "POP", + "source": 1 + }, + { + "begin": 1899, + "end": 2540, + "name": "POP", + "source": 1 + }, + { + "begin": 1899, + "end": 2540, + "name": "POP", + "source": 1 + }, + { + "begin": 1894, + "end": 1897, + "name": "DUP1", + "source": 1 + }, + { + "begin": 1894, + "end": 1897, + "name": "DUP1", + "source": 1 + }, + { + "begin": 1894, + "end": 1897, + "name": "PUSH [tag]", + "source": 1, + "value": "188" + }, + { + "begin": 1894, + "end": 1897, + "name": "SWAP1", + "source": 1 + }, + { + "begin": 1894, + "end": 1897, + "name": "PUSH [tag]", + "source": 1, + "value": "189" + }, + { + "begin": 1894, + "end": 1897, + "jumpType": "[in]", + "name": "JUMP", + "source": 1 + }, + { + "begin": 1894, + "end": 1897, + "name": "tag", + "source": 1, + "value": "188" + }, + { + "begin": 1894, + "end": 1897, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 1894, + "end": 1897, + "name": "SWAP2", + "source": 1 + }, + { + "begin": 1894, + "end": 1897, + "name": "POP", + "source": 1 + }, + { + "begin": 1894, + "end": 1897, + "name": "POP", + "source": 1 + }, + { + "begin": 1864, + "end": 2540, + "name": "PUSH [tag]", + "source": 1, + "value": "158" + }, + { + "begin": 1864, + "end": 2540, + "name": "JUMP", + "source": 1 + }, + { + "begin": 1864, + "end": 2540, + "name": "tag", + "source": 1, + "value": "159" + }, + { + "begin": 1864, + "end": 2540, + "name": "JUMPDEST", + "source": 1 + }, + { + "begin": 1864, + "end": 2540, + "name": "POP", + "source": 1 + }, + { + "begin": 1799, + "end": 2544, + "name": "POP", + "source": 1 + }, + { + "begin": 1710, + "end": 2544, + "name": "POP", + "source": 1 + }, + { + "begin": 1710, + "end": 2544, + "name": "POP", + "source": 1 + }, + { + "begin": 1710, + "end": 2544, + "name": "POP", + "source": 1 + }, + { + "begin": 1710, + "end": 2544, + "jumpType": "[out]", + "name": "JUMP", + "source": 1 + }, + { + "begin": 8892, + "end": 9534, + "name": "tag", + "source": 13, + "value": "117" + }, + { + "begin": 8892, + "end": 9534, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 8996, + "end": 9013, + "name": "PUSH", + "source": 13, + "value": "0" + }, + { + "begin": 8996, + "end": 9013, + "name": "DUP1", + "source": 13 + }, + { + "begin": 8996, + "end": 9013, + "name": "DUP1", + "source": 13 + }, + { + "begin": 8996, + "end": 9013, + "name": "DUP1", + "source": 13 + }, + { + "begin": 9131, + "end": 9172, + "name": "PUSH [tag]", + "source": 13, + "value": "191" + }, + { + "begin": 9145, + "end": 9155, + "name": "DUP8", + "source": 13 + }, + { + "begin": 9157, + "end": 9171, + "name": "PUSH [tag]", + "source": 13, + "value": "192" + }, + { + "begin": 9157, + "end": 9167, + "name": "DUP8", + "source": 13 + }, + { + "begin": 9168, + "end": 9169, + "name": "PUSH", + "source": 13, + "value": "6" + }, + { + "begin": 9157, + "end": 9167, + "name": "DUP2", + "source": 13 + }, + { + "begin": 9157, + "end": 9167, + "name": "DUP12", + "source": 13 + }, + { + "begin": 9157, + "end": 9171, + "name": "PUSH [tag]", + "source": 13, + "value": "193" + }, + { + "begin": 9157, + "end": 9171, + "jumpType": "[in]", + "name": "JUMP", + "source": 13 + }, + { + "begin": 9157, + "end": 9171, + "name": "tag", + "source": 13, + "value": "192" + }, + { + "begin": 9157, + "end": 9171, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 9131, + "end": 9144, + "name": "PUSH [tag]", + "source": 13, + "value": "194" + }, + { + "begin": 9131, + "end": 9172, + "jumpType": "[in]", + "name": "JUMP", + "source": 13 + }, + { + "begin": 9131, + "end": 9172, + "name": "tag", + "source": 13, + "value": "191" + }, + { + "begin": 9131, + "end": 9172, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 622, + "end": 631, + "name": "PUSH", + "source": 20, + "value": "0" + }, + { + "begin": 656, + "end": 669, + "name": "SWAP1", + "source": 20 + }, + { + "begin": 656, + "end": 669, + "name": "DUP2", + "source": 20 + }, + { + "begin": 656, + "end": 669, + "name": "MSTORE", + "source": 20 + }, + { + "begin": 1585, + "end": 1610, + "name": "DUP8", + "source": 18 + }, + { + "begin": 1585, + "end": 1610, + "name": "CALLDATALOAD", + "source": 18 + }, + { + "begin": 1626, + "end": 1629, + "name": "PUSH", + "source": 18, + "value": "F0" + }, + { + "begin": 1622, + "end": 1636, + "name": "SHR", + "source": 18 + }, + { + "begin": 683, + "end": 685, + "name": "PUSH", + "source": 20, + "value": "20" + }, + { + "begin": 676, + "end": 690, + "name": "DUP2", + "source": 20 + }, + { + "begin": 676, + "end": 690, + "name": "DUP2", + "source": 20 + }, + { + "begin": 676, + "end": 690, + "name": "MSTORE", + "source": 20 + }, + { + "begin": 715, + "end": 717, + "name": "PUSH", + "source": 20, + "value": "40" + }, + { + "begin": 702, + "end": 718, + "name": "DUP1", + "source": 20 + }, + { + "begin": 702, + "end": 718, + "name": "DUP5", + "source": 20 + }, + { + "begin": 702, + "end": 718, + "name": "KECCAK256", + "source": 20 + }, + { + "begin": 656, + "end": 669, + "name": "DUP5", + "source": 20 + }, + { + "begin": 656, + "end": 669, + "name": "MSTORE", + "source": 20 + }, + { + "begin": 9379, + "end": 9380, + "name": "PUSH", + "source": 13, + "value": "2" + }, + { + "begin": 2034, + "end": 2057, + "name": "SWAP1", + "source": 18 + }, + { + "begin": 2034, + "end": 2057, + "name": "SWAP11", + "source": 18 + }, + { + "begin": 2034, + "end": 2057, + "name": "ADD", + "source": 18 + }, + { + "begin": 2021, + "end": 2058, + "name": "CALLDATALOAD", + "source": 18 + }, + { + "begin": 2074, + "end": 2077, + "name": "PUSH", + "source": 18, + "value": "E0" + }, + { + "begin": 2070, + "end": 2084, + "name": "SHR", + "source": 18 + }, + { + "begin": 676, + "end": 690, + "name": "SWAP1", + "source": 20 + }, + { + "begin": 676, + "end": 690, + "name": "DUP2", + "source": 20 + }, + { + "begin": 676, + "end": 690, + "name": "SWAP1", + "source": 20 + }, + { + "begin": 676, + "end": 690, + "name": "MSTORE", + "source": 20 + }, + { + "begin": 702, + "end": 718, + "name": "SWAP9", + "source": 20 + }, + { + "begin": 702, + "end": 718, + "name": "SWAP1", + "source": 20 + }, + { + "begin": 702, + "end": 718, + "name": "SWAP2", + "source": 20 + }, + { + "begin": 702, + "end": 718, + "name": "KECCAK256", + "source": 20 + }, + { + "begin": 1622, + "end": 1636, + "name": "SWAP1", + "source": 18 + }, + { + "begin": 1622, + "end": 1636, + "name": "SWAP10", + "source": 18 + }, + { + "begin": 9109, + "end": 9172, + "name": "SWAP2", + "source": 13 + }, + { + "begin": 9109, + "end": 9172, + "name": "SWAP9", + "source": 13 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 702, + "end": 718, + "name": "SWAP7", + "source": 20 + }, + { + "begin": 2070, + "end": 2084, + "name": "SWAP6", + "source": 18 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 8892, + "end": 9534, + "name": "SWAP4", + "source": 13 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 8892, + "end": 9534, + "jumpType": "[out]", + "name": "JUMP", + "source": 13 + }, + { + "begin": 648, + "end": 910, + "name": "tag", + "source": 15, + "value": "121" + }, + { + "begin": 648, + "end": 910, + "name": "JUMPDEST", + "source": 15 + }, + { + "begin": 752, + "end": 769, + "name": "PUSH", + "source": 15, + "value": "0" + }, + { + "begin": 752, + "end": 769, + "name": "DUP1", + "source": 15 + }, + { + "begin": 752, + "end": 769, + "name": "DUP1", + "source": 15 + }, + { + "begin": 752, + "end": 769, + "name": "DUP1", + "source": 15 + }, + { + "begin": 854, + "end": 905, + "name": "PUSH [tag]", + "source": 15, + "value": "203" + }, + { + "begin": 878, + "end": 888, + "name": "DUP8", + "source": 15 + }, + { + "begin": 890, + "end": 904, + "name": "PUSH [tag]", + "source": 15, + "value": "204" + }, + { + "begin": 890, + "end": 900, + "name": "DUP8", + "source": 15 + }, + { + "begin": 901, + "end": 902, + "name": "PUSH", + "source": 15, + "value": "1" + }, + { + "begin": 890, + "end": 900, + "name": "DUP2", + "source": 15 + }, + { + "begin": 890, + "end": 900, + "name": "DUP12", + "source": 15 + }, + { + "begin": 890, + "end": 904, + "name": "PUSH [tag]", + "source": 15, + "value": "193" + }, + { + "begin": 890, + "end": 904, + "jumpType": "[in]", + "name": "JUMP", + "source": 15 + }, + { + "begin": 890, + "end": 904, + "name": "tag", + "source": 15, + "value": "204" + }, + { + "begin": 890, + "end": 904, + "name": "JUMPDEST", + "source": 15 + }, + { + "begin": 854, + "end": 877, + "name": "PUSH [tag]", + "source": 15, + "value": "117" + }, + { + "begin": 854, + "end": 905, + "jumpType": "[in]", + "name": "JUMP", + "source": 15 + }, + { + "begin": 854, + "end": 905, + "name": "tag", + "source": 15, + "value": "203" + }, + { + "begin": 854, + "end": 905, + "name": "JUMPDEST", + "source": 15 + }, + { + "begin": 847, + "end": 905, + "name": "SWAP4", + "source": 15 + }, + { + "begin": 847, + "end": 905, + "name": "POP", + "source": 15 + }, + { + "begin": 847, + "end": 905, + "name": "SWAP4", + "source": 15 + }, + { + "begin": 847, + "end": 905, + "name": "POP", + "source": 15 + }, + { + "begin": 847, + "end": 905, + "name": "SWAP4", + "source": 15 + }, + { + "begin": 847, + "end": 905, + "name": "POP", + "source": 15 + }, + { + "begin": 847, + "end": 905, + "name": "SWAP4", + "source": 15 + }, + { + "begin": 847, + "end": 905, + "name": "POP", + "source": 15 + }, + { + "begin": 648, + "end": 910, + "name": "SWAP4", + "source": 15 + }, + { + "begin": 648, + "end": 910, + "name": "POP", + "source": 15 + }, + { + "begin": 648, + "end": 910, + "name": "SWAP4", + "source": 15 + }, + { + "begin": 648, + "end": 910, + "name": "POP", + "source": 15 + }, + { + "begin": 648, + "end": 910, + "name": "SWAP4", + "source": 15 + }, + { + "begin": 648, + "end": 910, + "name": "POP", + "source": 15 + }, + { + "begin": 648, + "end": 910, + "name": "SWAP4", + "source": 15 + }, + { + "begin": 648, + "end": 910, + "jumpType": "[out]", + "name": "JUMP", + "source": 15 + }, + { + "begin": 404, + "end": 617, + "name": "tag", + "source": 16, + "value": "124" + }, + { + "begin": 404, + "end": 617, + "name": "JUMPDEST", + "source": 16 + }, + { + "begin": 502, + "end": 606, + "name": "PUSH", + "source": 16, + "value": "40" + }, + { + "begin": 502, + "end": 606, + "name": "MLOAD", + "source": 16 + }, + { + "begin": 12792, + "end": 12858, + "name": "PUSH", + "source": 22, + "value": "1901000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 502, + "end": 606, + "name": "PUSH", + "source": 16, + "value": "20" + }, + { + "begin": 502, + "end": 606, + "name": "DUP3", + "source": 16 + }, + { + "begin": 502, + "end": 606, + "name": "ADD", + "source": 16 + }, + { + "begin": 12780, + "end": 12859, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 463, + "end": 470, + "name": "PUSH", + "source": 16, + "value": "0" + }, + { + "begin": 12875, + "end": 12886, + "name": "PUSH", + "source": 22, + "value": "22" + }, + { + "begin": 12875, + "end": 12886, + "name": "DUP3", + "source": 22 + }, + { + "begin": 12875, + "end": 12886, + "name": "ADD", + "source": 22 + }, + { + "begin": 12868, + "end": 12895, + "name": "DUP2", + "source": 22 + }, + { + "begin": 12868, + "end": 12895, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 12868, + "end": 12895, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 12946, + "end": 13012, + "name": "PUSH", + "source": 22, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000" + }, + { + "begin": 576, + "end": 580, + "name": "ADDRESS", + "source": 16 + }, + { + "begin": 12933, + "end": 12935, + "name": "PUSH", + "source": 22, + "value": "60" + }, + { + "begin": 12929, + "end": 12944, + "name": "SHL", + "source": 22 + }, + { + "begin": 12925, + "end": 13013, + "name": "AND", + "source": 22 + }, + { + "begin": 12911, + "end": 12923, + "name": "PUSH", + "source": 22, + "value": "42" + }, + { + "begin": 12911, + "end": 12923, + "name": "DUP4", + "source": 22 + }, + { + "begin": 12911, + "end": 12923, + "name": "ADD", + "source": 22 + }, + { + "begin": 12904, + "end": 13014, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 13030, + "end": 13042, + "name": "PUSH", + "source": 22, + "value": "56" + }, + { + "begin": 13030, + "end": 13042, + "name": "DUP3", + "source": 22 + }, + { + "begin": 13030, + "end": 13042, + "name": "ADD", + "source": 22 + }, + { + "begin": 13023, + "end": 13051, + "name": "DUP4", + "source": 22 + }, + { + "begin": 13023, + "end": 13051, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 13023, + "end": 13051, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 463, + "end": 470, + "name": "SWAP1", + "source": 16 + }, + { + "begin": 13067, + "end": 13079, + "name": "PUSH", + "source": 22, + "value": "76" + }, + { + "begin": 13067, + "end": 13079, + "name": "ADD", + "source": 22 + }, + { + "begin": 502, + "end": 606, + "name": "PUSH [tag]", + "source": 16, + "value": "155" + }, + { + "begin": 12494, + "end": 13085, + "name": "JUMP", + "source": 22 + }, + { + "begin": 2320, + "end": 4379, + "name": "tag", + "source": 14, + "value": "128" + }, + { + "begin": 2320, + "end": 4379, + "name": "JUMPDEST", + "source": 14 + }, + { + "begin": 2428, + "end": 2445, + "name": "PUSH", + "source": 14, + "value": "0" + }, + { + "begin": 2428, + "end": 2445, + "name": "DUP1", + "source": 14 + }, + { + "begin": 2428, + "end": 2445, + "name": "DUP1", + "source": 14 + }, + { + "begin": 2428, + "end": 2445, + "name": "DUP1", + "source": 14 + }, + { + "begin": 2428, + "end": 2445, + "name": "DUP1", + "source": 14 + }, + { + "begin": 3378, + "end": 3392, + "name": "PUSH", + "source": 19, + "value": "4" + }, + { + "begin": 2563, + "end": 2564, + "name": "PUSH", + "source": 14, + "value": "1" + }, + { + "begin": 3290, + "end": 3315, + "name": "DUP9", + "source": 19 + }, + { + "begin": 3290, + "end": 3315, + "name": "ADD", + "source": 19 + }, + { + "begin": 3277, + "end": 3316, + "name": "CALLDATALOAD", + "source": 19 + }, + { + "begin": 3336, + "end": 3339, + "name": "PUSH", + "source": 19, + "value": "E8" + }, + { + "begin": 3332, + "end": 3346, + "name": "SHR", + "source": 19 + }, + { + "begin": 2428, + "end": 2445, + "name": "DUP3", + "source": 14 + }, + { + "begin": 2768, + "end": 2784, + "name": "PUSH [tag]", + "source": 14, + "value": "210" + }, + { + "begin": 3378, + "end": 3392, + "name": "DUP4", + "source": 19 + }, + { + "begin": 3332, + "end": 3346, + "name": "DUP4", + "source": 19 + }, + { + "begin": 2768, + "end": 2784, + "name": "PUSH [tag]", + "source": 14, + "value": "211" + }, + { + "begin": 2768, + "end": 2784, + "jumpType": "[in]", + "name": "JUMP", + "source": 14 + }, + { + "begin": 2768, + "end": 2784, + "name": "tag", + "source": 14, + "value": "210" + }, + { + "begin": 2768, + "end": 2784, + "name": "JUMPDEST", + "source": 14 + }, + { + "begin": 2750, + "end": 2784, + "name": "SWAP1", + "source": 14 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 2883, + "end": 2955, + "name": "PUSH [tag]", + "source": 14, + "value": "212" + }, + { + "begin": 2908, + "end": 2915, + "name": "DUP12", + "source": 14 + }, + { + "begin": 2923, + "end": 2949, + "name": "PUSH [tag]", + "source": 14, + "value": "58" + }, + { + "begin": 2750, + "end": 2784, + "name": "DUP4", + "source": 14 + }, + { + "begin": 2934, + "end": 2940, + "name": "DUP7", + "source": 14 + }, + { + "begin": 2923, + "end": 2933, + "name": "DUP14", + "source": 14 + }, + { + "begin": 2923, + "end": 2933, + "name": "DUP16", + "source": 14 + }, + { + "begin": 2923, + "end": 2949, + "name": "PUSH [tag]", + "source": 14, + "value": "193" + }, + { + "begin": 2923, + "end": 2949, + "jumpType": "[in]", + "name": "JUMP", + "source": 14 + }, + { + "begin": 2883, + "end": 2955, + "name": "tag", + "source": 14, + "value": "212" + }, + { + "begin": 2883, + "end": 2955, + "name": "JUMPDEST", + "source": 14 + }, + { + "begin": 2791, + "end": 2955, + "name": "SWAP4", + "source": 14 + }, + { + "begin": 2791, + "end": 2955, + "name": "SWAP12", + "source": 14 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 2791, + "end": 2955, + "name": "SWAP2", + "source": 14 + }, + { + "begin": 2791, + "end": 2955, + "name": "SWAP10", + "source": 14 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 2791, + "end": 2955, + "name": "SWAP8", + "source": 14 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 2791, + "end": 2955, + "name": "SWAP6", + "source": 14 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 2791, + "end": 2955, + "name": "SWAP4", + "source": 14 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 2966, + "end": 2984, + "name": "DUP8", + "source": 14 + }, + { + "begin": 2966, + "end": 2984, + "name": "DUP8", + "source": 14 + }, + { + "begin": 2966, + "end": 2984, + "name": "LT", + "source": 14 + }, + { + "begin": 2962, + "end": 3080, + "name": "ISZERO", + "source": 14 + }, + { + "begin": 2962, + "end": 3080, + "name": "PUSH [tag]", + "source": 14, + "value": "214" + }, + { + "begin": 2962, + "end": 3080, + "name": "JUMPI", + "source": 14 + }, + { + "begin": 3027, + "end": 3053, + "name": "PUSH [tag]", + "source": 14, + "value": "215" + }, + { + "begin": 3045, + "end": 3052, + "name": "DUP2", + "source": 14 + }, + { + "begin": 3038, + "end": 3044, + "name": "DUP5", + "source": 14 + }, + { + "begin": 3027, + "end": 3037, + "name": "DUP12", + "source": 14 + }, + { + "begin": 3027, + "end": 3037, + "name": "DUP14", + "source": 14 + }, + { + "begin": 3027, + "end": 3053, + "name": "PUSH [tag]", + "source": 14, + "value": "193" + }, + { + "begin": 3027, + "end": 3053, + "jumpType": "[in]", + "name": "JUMP", + "source": 14 + }, + { + "begin": 3027, + "end": 3053, + "name": "tag", + "source": 14, + "value": "215" + }, + { + "begin": 3027, + "end": 3053, + "name": "JUMPDEST", + "source": 14 + }, + { + "begin": 3055, + "end": 3064, + "name": "DUP10", + "source": 14 + }, + { + "begin": 3066, + "end": 3072, + "name": "DUP10", + "source": 14 + }, + { + "begin": 3001, + "end": 3073, + "name": "PUSH", + "source": 14, + "value": "40" + }, + { + "begin": 3001, + "end": 3073, + "name": "MLOAD", + "source": 14 + }, + { + "begin": 3001, + "end": 3073, + "name": "PUSH", + "source": 14, + "value": "B006ABA000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 3001, + "end": 3073, + "name": "DUP2", + "source": 14 + }, + { + "begin": 3001, + "end": 3073, + "name": "MSTORE", + "source": 14 + }, + { + "begin": 3001, + "end": 3073, + "name": "PUSH", + "source": 14, + "value": "4" + }, + { + "begin": 3001, + "end": 3073, + "name": "ADD", + "source": 14 + }, + { + "begin": 3001, + "end": 3073, + "name": "PUSH [tag]", + "source": 14, + "value": "93" + }, + { + "begin": 3001, + "end": 3073, + "name": "SWAP5", + "source": 14 + }, + { + "begin": 3001, + "end": 3073, + "name": "SWAP4", + "source": 14 + }, + { + "begin": 3001, + "end": 3073, + "name": "SWAP3", + "source": 14 + }, + { + "begin": 3001, + "end": 3073, + "name": "SWAP2", + "source": 14 + }, + { + "begin": 3001, + "end": 3073, + "name": "SWAP1", + "source": 14 + }, + { + "begin": 3001, + "end": 3073, + "name": "PUSH [tag]", + "source": 14, + "value": "217" + }, + { + "begin": 3001, + "end": 3073, + "jumpType": "[in]", + "name": "JUMP", + "source": 14 + }, + { + "begin": 2962, + "end": 3080, + "name": "tag", + "source": 14, + "value": "214" + }, + { + "begin": 2962, + "end": 3080, + "name": "JUMPDEST", + "source": 14 + }, + { + "begin": 3095, + "end": 3102, + "name": "DUP1", + "source": 14 + }, + { + "begin": 3086, + "end": 3102, + "name": "SWAP3", + "source": 14 + }, + { + "begin": 3086, + "end": 3102, + "name": "POP", + "source": 14 + }, + { + "begin": 3283, + "end": 4375, + "name": "tag", + "source": 14, + "value": "218" + }, + { + "begin": 3283, + "end": 4375, + "name": "JUMPDEST", + "source": 14 + }, + { + "begin": 3290, + "end": 3316, + "name": "DUP9", + "source": 14 + }, + { + "begin": 3290, + "end": 3316, + "name": "DUP4", + "source": 14 + }, + { + "begin": 3290, + "end": 3316, + "name": "LT", + "source": 14 + }, + { + "begin": 3283, + "end": 4375, + "name": "ISZERO", + "source": 14 + }, + { + "begin": 3283, + "end": 4375, + "name": "PUSH [tag]", + "source": 14, + "value": "219" + }, + { + "begin": 3283, + "end": 4375, + "name": "JUMPI", + "source": 14 + }, + { + "begin": 3390, + "end": 3391, + "name": "PUSH", + "source": 19, + "value": "3" + }, + { + "begin": 3378, + "end": 3392, + "name": "DUP4", + "source": 19 + }, + { + "begin": 3378, + "end": 3392, + "name": "ADD", + "source": 19 + }, + { + "begin": 3378, + "end": 3392, + "name": "SWAP3", + "source": 19 + }, + { + "begin": 3290, + "end": 3315, + "name": "DUP11", + "source": 19 + }, + { + "begin": 3290, + "end": 3315, + "name": "ADD", + "source": 19 + }, + { + "begin": 3277, + "end": 3316, + "name": "CALLDATALOAD", + "source": 19 + }, + { + "begin": 3336, + "end": 3339, + "name": "PUSH", + "source": 19, + "value": "E8" + }, + { + "begin": 3332, + "end": 3346, + "name": "SHR", + "source": 19 + }, + { + "begin": 3332, + "end": 3346, + "name": "SWAP2", + "source": 19 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 3444, + "end": 3460, + "name": "PUSH [tag]", + "source": 14, + "value": "221" + }, + { + "begin": 3378, + "end": 3392, + "name": "DUP4", + "source": 19 + }, + { + "begin": 3332, + "end": 3346, + "name": "DUP4", + "source": 19 + }, + { + "begin": 3444, + "end": 3460, + "name": "PUSH [tag]", + "source": 14, + "value": "211" + }, + { + "begin": 3444, + "end": 3460, + "jumpType": "[in]", + "name": "JUMP", + "source": 14 + }, + { + "begin": 3444, + "end": 3460, + "name": "tag", + "source": 14, + "value": "221" + }, + { + "begin": 3444, + "end": 3460, + "name": "JUMPDEST", + "source": 14 + }, + { + "begin": 3434, + "end": 3460, + "name": "SWAP1", + "source": 14 + }, + { + "begin": 3434, + "end": 3460, + "name": "POP", + "source": 14 + }, + { + "begin": 3469, + "end": 3491, + "name": "PUSH", + "source": 14, + "value": "0" + }, + { + "begin": 3687, + "end": 3792, + "name": "PUSH [tag]", + "source": 14, + "value": "222" + }, + { + "begin": 3714, + "end": 3748, + "name": "PUSH [tag]", + "source": 14, + "value": "223" + }, + { + "begin": 3738, + "end": 3747, + "name": "DUP9", + "source": 14 + }, + { + "begin": 3714, + "end": 3737, + "name": "PUSH [tag]", + "source": 14, + "value": "224" + }, + { + "begin": 3714, + "end": 3748, + "jumpType": "[in]", + "name": "JUMP", + "source": 14 + }, + { + "begin": 3714, + "end": 3748, + "name": "tag", + "source": 14, + "value": "223" + }, + { + "begin": 3714, + "end": 3748, + "name": "JUMPDEST", + "source": 14 + }, + { + "begin": 3758, + "end": 3768, + "name": "DUP13", + "source": 14 + }, + { + "begin": 3758, + "end": 3768, + "name": "DUP13", + "source": 14 + }, + { + "begin": 3769, + "end": 3775, + "name": "DUP8", + "source": 14 + }, + { + "begin": 3758, + "end": 3784, + "name": "SWAP1", + "source": 14 + }, + { + "begin": 3776, + "end": 3783, + "name": "DUP7", + "source": 14 + }, + { + "begin": 3758, + "end": 3784, + "name": "SWAP3", + "source": 14 + }, + { + "begin": 3758, + "end": 3784, + "name": "PUSH [tag]", + "source": 14, + "value": "58" + }, + { + "begin": 3758, + "end": 3784, + "name": "SWAP4", + "source": 14 + }, + { + "begin": 3758, + "end": 3784, + "name": "SWAP3", + "source": 14 + }, + { + "begin": 3758, + "end": 3784, + "name": "SWAP2", + "source": 14 + }, + { + "begin": 3758, + "end": 3784, + "name": "SWAP1", + "source": 14 + }, + { + "begin": 3758, + "end": 3784, + "name": "PUSH [tag]", + "source": 14, + "value": "193" + }, + { + "begin": 3758, + "end": 3784, + "jumpType": "[in]", + "name": "JUMP", + "source": 14 + }, + { + "begin": 3687, + "end": 3792, + "name": "tag", + "source": 14, + "value": "222" + }, + { + "begin": 3687, + "end": 3792, + "name": "JUMPDEST", + "source": 14 + }, + { + "begin": 3500, + "end": 3792, + "name": "SWAP4", + "source": 14 + }, + { + "begin": 3500, + "end": 3792, + "name": "SWAP13", + "source": 14 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 3500, + "end": 3792, + "name": "SWAP2", + "source": 14 + }, + { + "begin": 3500, + "end": 3792, + "name": "SWAP11", + "source": 14 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 3500, + "end": 3792, + "name": "SWAP9", + "source": 14 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 3500, + "end": 3792, + "name": "SWAP1", + "source": 14 + }, + { + "begin": 3500, + "end": 3792, + "name": "SWAP2", + "source": 14 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 3833, + "end": 3851, + "name": "DUP9", + "source": 14 + }, + { + "begin": 3833, + "end": 3851, + "name": "DUP9", + "source": 14 + }, + { + "begin": 3833, + "end": 3851, + "name": "LT", + "source": 14 + }, + { + "begin": 3829, + "end": 3951, + "name": "ISZERO", + "source": 14 + }, + { + "begin": 3829, + "end": 3951, + "name": "PUSH [tag]", + "source": 14, + "value": "226" + }, + { + "begin": 3829, + "end": 3951, + "name": "JUMPI", + "source": 14 + }, + { + "begin": 3896, + "end": 3922, + "name": "PUSH [tag]", + "source": 14, + "value": "227" + }, + { + "begin": 3914, + "end": 3921, + "name": "DUP3", + "source": 14 + }, + { + "begin": 3907, + "end": 3913, + "name": "DUP6", + "source": 14 + }, + { + "begin": 3896, + "end": 3906, + "name": "DUP13", + "source": 14 + }, + { + "begin": 3896, + "end": 3906, + "name": "DUP15", + "source": 14 + }, + { + "begin": 3896, + "end": 3922, + "name": "PUSH [tag]", + "source": 14, + "value": "193" + }, + { + "begin": 3896, + "end": 3922, + "jumpType": "[in]", + "name": "JUMP", + "source": 14 + }, + { + "begin": 3896, + "end": 3922, + "name": "tag", + "source": 14, + "value": "227" + }, + { + "begin": 3896, + "end": 3922, + "name": "JUMPDEST", + "source": 14 + }, + { + "begin": 3924, + "end": 3933, + "name": "DUP11", + "source": 14 + }, + { + "begin": 3935, + "end": 3941, + "name": "DUP11", + "source": 14 + }, + { + "begin": 3870, + "end": 3942, + "name": "PUSH", + "source": 14, + "value": "40" + }, + { + "begin": 3870, + "end": 3942, + "name": "MLOAD", + "source": 14 + }, + { + "begin": 3870, + "end": 3942, + "name": "PUSH", + "source": 14, + "value": "B006ABA000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 3870, + "end": 3942, + "name": "DUP2", + "source": 14 + }, + { + "begin": 3870, + "end": 3942, + "name": "MSTORE", + "source": 14 + }, + { + "begin": 3870, + "end": 3942, + "name": "PUSH", + "source": 14, + "value": "4" + }, + { + "begin": 3870, + "end": 3942, + "name": "ADD", + "source": 14 + }, + { + "begin": 3870, + "end": 3942, + "name": "PUSH [tag]", + "source": 14, + "value": "93" + }, + { + "begin": 3870, + "end": 3942, + "name": "SWAP5", + "source": 14 + }, + { + "begin": 3870, + "end": 3942, + "name": "SWAP4", + "source": 14 + }, + { + "begin": 3870, + "end": 3942, + "name": "SWAP3", + "source": 14 + }, + { + "begin": 3870, + "end": 3942, + "name": "SWAP2", + "source": 14 + }, + { + "begin": 3870, + "end": 3942, + "name": "SWAP1", + "source": 14 + }, + { + "begin": 3870, + "end": 3942, + "name": "PUSH [tag]", + "source": 14, + "value": "217" + }, + { + "begin": 3870, + "end": 3942, + "jumpType": "[in]", + "name": "JUMP", + "source": 14 + }, + { + "begin": 3829, + "end": 3951, + "name": "tag", + "source": 14, + "value": "226" + }, + { + "begin": 3829, + "end": 3951, + "name": "JUMPDEST", + "source": 14 + }, + { + "begin": 4216, + "end": 4226, + "name": "DUP5", + "source": 14 + }, + { + "begin": 4198, + "end": 4212, + "name": "DUP2", + "source": 14 + }, + { + "begin": 4198, + "end": 4226, + "name": "LT", + "source": 14 + }, + { + "begin": 4194, + "end": 4309, + "name": "PUSH [tag]", + "source": 14, + "value": "229" + }, + { + "begin": 4194, + "end": 4309, + "name": "JUMPI", + "source": 14 + }, + { + "begin": 4245, + "end": 4300, + "name": "PUSH", + "source": 14, + "value": "40" + }, + { + "begin": 4245, + "end": 4300, + "name": "MLOAD", + "source": 14 + }, + { + "begin": 4245, + "end": 4300, + "name": "PUSH", + "source": 14, + "value": "37DAF62B00000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 4245, + "end": 4300, + "name": "DUP2", + "source": 14 + }, + { + "begin": 4245, + "end": 4300, + "name": "MSTORE", + "source": 14 + }, + { + "begin": 4245, + "end": 4300, + "name": "PUSH", + "source": 14, + "value": "4" + }, + { + "begin": 4245, + "end": 4300, + "name": "DUP2", + "source": 14 + }, + { + "begin": 4245, + "end": 4300, + "name": "ADD", + "source": 14 + }, + { + "begin": 16193, + "end": 16218, + "name": "DUP3", + "source": 22 + }, + { + "begin": 16193, + "end": 16218, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 16193, + "end": 16218, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 16234, + "end": 16252, + "name": "PUSH", + "source": 22, + "value": "24" + }, + { + "begin": 16234, + "end": 16252, + "name": "DUP2", + "source": 22 + }, + { + "begin": 16234, + "end": 16252, + "name": "ADD", + "source": 22 + }, + { + "begin": 16227, + "end": 16261, + "name": "DUP7", + "source": 22 + }, + { + "begin": 16227, + "end": 16261, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 16227, + "end": 16261, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 16166, + "end": 16184, + "name": "PUSH", + "source": 22, + "value": "44" + }, + { + "begin": 16166, + "end": 16184, + "name": "ADD", + "source": 22 + }, + { + "begin": 4245, + "end": 4300, + "name": "PUSH [tag]", + "source": 14, + "value": "93" + }, + { + "begin": 16019, + "end": 16267, + "name": "JUMP", + "source": 22 + }, + { + "begin": 4194, + "end": 4309, + "name": "tag", + "source": 14, + "value": "229" + }, + { + "begin": 4194, + "end": 4309, + "name": "JUMPDEST", + "source": 14 + }, + { + "begin": 4330, + "end": 4344, + "name": "SWAP4", + "source": 14 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 4361, + "end": 4368, + "name": "SWAP2", + "source": 14 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 4361, + "end": 4368, + "name": "DUP2", + "source": 14 + }, + { + "begin": 3283, + "end": 4375, + "name": "PUSH [tag]", + "source": 14, + "value": "218" + }, + { + "begin": 3283, + "end": 4375, + "name": "JUMP", + "source": 14 + }, + { + "begin": 3283, + "end": 4375, + "name": "tag", + "source": 14, + "value": "219" + }, + { + "begin": 3283, + "end": 4375, + "name": "JUMPDEST", + "source": 14 + }, + { + "begin": 2540, + "end": 4379, + "name": "POP", + "source": 14 + }, + { + "begin": 2540, + "end": 4379, + "name": "POP", + "source": 14 + }, + { + "begin": 2540, + "end": 4379, + "name": "POP", + "source": 14 + }, + { + "begin": 2320, + "end": 4379, + "name": "SWAP4", + "source": 14 + }, + { + "begin": 2320, + "end": 4379, + "name": "SWAP8", + "source": 14 + }, + { + "begin": 2320, + "end": 4379, + "name": "SWAP3", + "source": 14 + }, + { + "begin": 2320, + "end": 4379, + "name": "SWAP7", + "source": 14 + }, + { + "begin": 2320, + "end": 4379, + "name": "POP", + "source": 14 + }, + { + "begin": 2320, + "end": 4379, + "name": "SWAP4", + "source": 14 + }, + { + "begin": 2320, + "end": 4379, + "name": "POP", + "source": 14 + }, + { + "begin": 2320, + "end": 4379, + "name": "SWAP4", + "source": 14 + }, + { + "begin": 2320, + "end": 4379, + "name": "POP", + "source": 14 + }, + { + "begin": 2320, + "end": 4379, + "jumpType": "[out]", + "name": "JUMP", + "source": 14 + }, + { + "begin": 490, + "end": 677, + "name": "tag", + "source": 9, + "value": "133" + }, + { + "begin": 490, + "end": 677, + "name": "JUMPDEST", + "source": 9 + }, + { + "begin": 568, + "end": 579, + "name": "PUSH", + "source": 9, + "value": "0" + }, + { + "begin": 587, + "end": 598, + "name": "DUP1", + "source": 9 + }, + { + "begin": 622, + "end": 626, + "name": "DUP4", + "source": 9 + }, + { + "begin": 628, + "end": 635, + "name": "DUP4", + "source": 9 + }, + { + "begin": 611, + "end": 636, + "name": "PUSH", + "source": 9, + "value": "40" + }, + { + "begin": 611, + "end": 636, + "name": "MLOAD", + "source": 9 + }, + { + "begin": 611, + "end": 636, + "name": "PUSH", + "source": 9, + "value": "20" + }, + { + "begin": 611, + "end": 636, + "name": "ADD", + "source": 9 + }, + { + "begin": 611, + "end": 636, + "name": "PUSH [tag]", + "source": 9, + "value": "233" + }, + { + "begin": 611, + "end": 636, + "name": "SWAP3", + "source": 9 + }, + { + "begin": 611, + "end": 636, + "name": "SWAP2", + "source": 9 + }, + { + "begin": 611, + "end": 636, + "name": "SWAP1", + "source": 9 + }, + { + "begin": 16193, + "end": 16218, + "name": "SWAP2", + "source": 22 + }, + { + "begin": 16193, + "end": 16218, + "name": "DUP3", + "source": 22 + }, + { + "begin": 16193, + "end": 16218, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 16249, + "end": 16251, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 16234, + "end": 16252, + "name": "DUP3", + "source": 22 + }, + { + "begin": 16234, + "end": 16252, + "name": "ADD", + "source": 22 + }, + { + "begin": 16227, + "end": 16261, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 16181, + "end": 16183, + "name": "PUSH", + "source": 22, + "value": "40" + }, + { + "begin": 16166, + "end": 16184, + "name": "ADD", + "source": 22 + }, + { + "begin": 16166, + "end": 16184, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 16019, + "end": 16267, + "name": "JUMP", + "source": 22 + }, + { + "begin": 611, + "end": 636, + "name": "tag", + "source": 9, + "value": "233" + }, + { + "begin": 611, + "end": 636, + "name": "JUMPDEST", + "source": 9 + }, + { + "begin": 611, + "end": 636, + "name": "PUSH", + "source": 9, + "value": "40" + }, + { + "begin": 611, + "end": 636, + "name": "DUP1", + "source": 9 + }, + { + "begin": 611, + "end": 636, + "name": "MLOAD", + "source": 9 + }, + { + "begin": 611, + "end": 636, + "name": "PUSH", + "source": 9, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0" + }, + { + "begin": 611, + "end": 636, + "name": "DUP2", + "source": 9 + }, + { + "begin": 611, + "end": 636, + "name": "DUP5", + "source": 9 + }, + { + "begin": 611, + "end": 636, + "name": "SUB", + "source": 9 + }, + { + "begin": 611, + "end": 636, + "name": "ADD", + "source": 9 + }, + { + "begin": 611, + "end": 636, + "name": "DUP2", + "source": 9 + }, + { + "begin": 611, + "end": 636, + "name": "MSTORE", + "source": 9 + }, + { + "begin": 611, + "end": 636, + "name": "SWAP2", + "source": 9 + }, + { + "begin": 611, + "end": 636, + "name": "SWAP1", + "source": 9 + }, + { + "begin": 611, + "end": 636, + "name": "MSTORE", + "source": 9 + }, + { + "begin": 601, + "end": 637, + "name": "DUP1", + "source": 9 + }, + { + "begin": 601, + "end": 637, + "name": "MLOAD", + "source": 9 + }, + { + "begin": 611, + "end": 636, + "name": "PUSH", + "source": 9, + "value": "20" + }, + { + "begin": 601, + "end": 637, + "name": "SWAP1", + "source": 9 + }, + { + "begin": 601, + "end": 637, + "name": "SWAP2", + "source": 9 + }, + { + "begin": 601, + "end": 637, + "name": "ADD", + "source": 9 + }, + { + "begin": 601, + "end": 637, + "name": "KECCAK256", + "source": 9 + }, + { + "begin": 661, + "end": 671, + "name": "SLOAD", + "source": 9 + }, + { + "begin": 661, + "end": 671, + "name": "SWAP5", + "source": 9 + }, + { + "begin": 490, + "end": 677, + "name": "SWAP4", + "source": 9 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 490, + "end": 677, + "jumpType": "[out]", + "name": "JUMP", + "source": 9 + }, + { + "begin": 4140, + "end": 4371, + "name": "tag", + "source": 3, + "value": "147" + }, + { + "begin": 4140, + "end": 4371, + "name": "JUMPDEST", + "source": 3 + }, + { + "begin": 4226, + "end": 4230, + "name": "PUSH", + "source": 3, + "value": "0" + }, + { + "begin": 4242, + "end": 4288, + "name": "PUSH", + "source": 3, + "value": "E4A77BBC00000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 4242, + "end": 4288, + "name": "PUSH", + "source": 3, + "value": "FFFFFFFF00000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 4242, + "end": 4288, + "name": "DUP4", + "source": 3 + }, + { + "begin": 4242, + "end": 4288, + "name": "AND", + "source": 3 + }, + { + "begin": 4242, + "end": 4288, + "name": "ADD", + "source": 3 + }, + { + "begin": 4238, + "end": 4316, + "name": "PUSH [tag]", + "source": 3, + "value": "236" + }, + { + "begin": 4238, + "end": 4316, + "name": "JUMPI", + "source": 3 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 4305, + "end": 4309, + "name": "PUSH", + "source": 3, + "value": "1" + }, + { + "begin": 4305, + "end": 4309, + "name": "SWAP2", + "source": 3 + }, + { + "begin": 4140, + "end": 4371, + "name": "SWAP1", + "source": 3 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 4140, + "end": 4371, + "jumpType": "[out]", + "name": "JUMP", + "source": 3 + }, + { + "begin": 4238, + "end": 4316, + "name": "tag", + "source": 3, + "value": "236" + }, + { + "begin": 4238, + "end": 4316, + "name": "JUMPDEST", + "source": 3 + }, + { + "begin": 4329, + "end": 4366, + "name": "PUSH [tag]", + "source": 3, + "value": "80" + }, + { + "begin": 4353, + "end": 4365, + "name": "DUP3", + "source": 3 + }, + { + "begin": 4329, + "end": 4352, + "name": "PUSH [tag]", + "source": 3, + "value": "238" + }, + { + "begin": 4329, + "end": 4366, + "jumpType": "[in]", + "name": "JUMP", + "source": 3 + }, + { + "begin": 1525, + "end": 1878, + "name": "tag", + "source": 20, + "value": "179" + }, + { + "begin": 1525, + "end": 1878, + "name": "JUMPDEST", + "source": 20 + }, + { + "begin": 1640, + "end": 1646, + "name": "PUSH", + "source": 20, + "value": "0" + }, + { + "begin": 1688, + "end": 1692, + "name": "PUSH", + "source": 20, + "value": "40" + }, + { + "begin": 1682, + "end": 1693, + "name": "MLOAD", + "source": 20 + }, + { + "begin": 1732, + "end": 1744, + "name": "DUP3", + "source": 20 + }, + { + "begin": 1718, + "end": 1730, + "name": "DUP5", + "source": 20 + }, + { + "begin": 1713, + "end": 1716, + "name": "DUP3", + "source": 20 + }, + { + "begin": 1700, + "end": 1745, + "name": "CALLDATACOPY", + "source": 20 + }, + { + "begin": 1859, + "end": 1860, + "name": "PUSH", + "source": 20, + "value": "0" + }, + { + "begin": 1848, + "end": 1849, + "name": "DUP1", + "source": 20 + }, + { + "begin": 1826, + "end": 1838, + "name": "DUP5", + "source": 20 + }, + { + "begin": 1813, + "end": 1816, + "name": "DUP4", + "source": 20 + }, + { + "begin": 1799, + "end": 1803, + "name": "DUP10", + "source": 20 + }, + { + "begin": 1786, + "end": 1789, + "name": "DUP12", + "source": 20 + }, + { + "begin": 1772, + "end": 1776, + "name": "DUP11", + "source": 20 + }, + { + "begin": 1758, + "end": 1868, + "name": "CALL", + "source": 20 + }, + { + "begin": 1753, + "end": 1868, + "name": "SWAP8", + "source": 20 + }, + { + "begin": 1525, + "end": 1878, + "name": "SWAP7", + "source": 20 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 1525, + "end": 1878, + "jumpType": "[out]", + "name": "JUMP", + "source": 20 + }, + { + "begin": 852, + "end": 1123, + "name": "tag", + "source": 20, + "value": "186" + }, + { + "begin": 852, + "end": 1123, + "name": "JUMPDEST", + "source": 20 + }, + { + "begin": 897, + "end": 911, + "name": "PUSH", + "source": 20, + "value": "60" + }, + { + "begin": 948, + "end": 964, + "name": "RETURNDATASIZE", + "source": 20 + }, + { + "begin": 982, + "end": 986, + "name": "PUSH", + "source": 20, + "value": "40" + }, + { + "begin": 976, + "end": 987, + "name": "MLOAD", + "source": 20 + }, + { + "begin": 971, + "end": 987, + "name": "SWAP2", + "source": 20 + }, + { + "begin": 971, + "end": 987, + "name": "POP", + "source": 20 + }, + { + "begin": 1014, + "end": 1016, + "name": "PUSH", + "source": 20, + "value": "20" + }, + { + "begin": 1011, + "end": 1012, + "name": "DUP3", + "source": 20 + }, + { + "begin": 1007, + "end": 1017, + "name": "ADD", + "source": 20 + }, + { + "begin": 1048, + "end": 1052, + "name": "DUP2", + "source": 20 + }, + { + "begin": 1041, + "end": 1046, + "name": "DUP2", + "source": 20 + }, + { + "begin": 1037, + "end": 1053, + "name": "ADD", + "source": 20 + }, + { + "begin": 1031, + "end": 1035, + "name": "PUSH", + "source": 20, + "value": "40" + }, + { + "begin": 1024, + "end": 1054, + "name": "MSTORE", + "source": 20 + }, + { + "begin": 1071, + "end": 1075, + "name": "DUP2", + "source": 20 + }, + { + "begin": 1068, + "end": 1069, + "name": "DUP4", + "source": 20 + }, + { + "begin": 1061, + "end": 1076, + "name": "MSTORE", + "source": 20 + }, + { + "begin": 1108, + "end": 1112, + "name": "DUP2", + "source": 20 + }, + { + "begin": 1105, + "end": 1106, + "name": "PUSH", + "source": 20, + "value": "0" + }, + { + "begin": 1098, + "end": 1103, + "name": "DUP3", + "source": 20 + }, + { + "begin": 1083, + "end": 1113, + "name": "RETURNDATACOPY", + "source": 20 + }, + { + "begin": 1083, + "end": 1113, + "name": "POP", + "source": 20 + }, + { + "begin": 1083, + "end": 1113, + "name": "POP", + "source": 20 + }, + { + "begin": 852, + "end": 1123, + "name": "SWAP1", + "source": 20 + }, + { + "begin": 852, + "end": 1123, + "jumpType": "[out]", + "name": "JUMP", + "source": 20 + }, + { + "begin": 3644, + "end": 3930, + "name": "tag", + "source": 3, + "value": "187" + }, + { + "begin": 3644, + "end": 3930, + "name": "JUMPDEST", + "source": 3 + }, + { + "begin": 3781, + "end": 3795, + "name": "DUP4", + "source": 3 + }, + { + "begin": 3777, + "end": 3926, + "name": "ISZERO", + "source": 3 + }, + { + "begin": 3777, + "end": 3926, + "name": "PUSH [tag]", + "source": 3, + "value": "243" + }, + { + "begin": 3777, + "end": 3926, + "name": "JUMPI", + "source": 3 + }, + { + "begin": 3849, + "end": 3856, + "name": "DUP1", + "source": 3 + }, + { + "begin": 3843, + "end": 3857, + "name": "MLOAD", + "source": 3 + }, + { + "begin": 3836, + "end": 3840, + "name": "PUSH", + "source": 3, + "value": "20" + }, + { + "begin": 3827, + "end": 3834, + "name": "DUP3", + "source": 3 + }, + { + "begin": 3823, + "end": 3841, + "name": "ADD", + "source": 3 + }, + { + "begin": 3816, + "end": 3858, + "name": "REVERT", + "source": 3 + }, + { + "begin": 3777, + "end": 3926, + "name": "tag", + "source": 3, + "value": "243" + }, + { + "begin": 3777, + "end": 3926, + "name": "JUMPDEST", + "source": 3 + }, + { + "begin": 3894, + "end": 3901, + "name": "DUP3", + "source": 3 + }, + { + "begin": 3885, + "end": 3919, + "name": "PUSH", + "source": 3, + "value": "AB46C69F7F32E1BF09B0725853DA82A211E5402A0600296AB499A2FB5EA3B419" + }, + { + "begin": 3903, + "end": 3909, + "name": "DUP4", + "source": 3 + }, + { + "begin": 3911, + "end": 3918, + "name": "DUP4", + "source": 3 + }, + { + "begin": 3885, + "end": 3919, + "name": "PUSH", + "source": 3, + "value": "40" + }, + { + "begin": 3885, + "end": 3919, + "name": "MLOAD", + "source": 3 + }, + { + "begin": 3885, + "end": 3919, + "name": "PUSH [tag]", + "source": 3, + "value": "245" + }, + { + "begin": 3885, + "end": 3919, + "name": "SWAP3", + "source": 3 + }, + { + "begin": 3885, + "end": 3919, + "name": "SWAP2", + "source": 3 + }, + { + "begin": 3885, + "end": 3919, + "name": "SWAP1", + "source": 3 + }, + { + "begin": 3885, + "end": 3919, + "name": "PUSH [tag]", + "source": 3, + "value": "246" + }, + { + "begin": 3885, + "end": 3919, + "jumpType": "[in]", + "name": "JUMP", + "source": 3 + }, + { + "begin": 3885, + "end": 3919, + "name": "tag", + "source": 3, + "value": "245" + }, + { + "begin": 3885, + "end": 3919, + "name": "JUMPDEST", + "source": 3 + }, + { + "begin": 3885, + "end": 3919, + "name": "PUSH", + "source": 3, + "value": "40" + }, + { + "begin": 3885, + "end": 3919, + "name": "MLOAD", + "source": 3 + }, + { + "begin": 3885, + "end": 3919, + "name": "DUP1", + "source": 3 + }, + { + "begin": 3885, + "end": 3919, + "name": "SWAP2", + "source": 3 + }, + { + "begin": 3885, + "end": 3919, + "name": "SUB", + "source": 3 + }, + { + "begin": 3885, + "end": 3919, + "name": "SWAP1", + "source": 3 + }, + { + "begin": 3885, + "end": 3919, + "name": "LOG2", + "source": 3 + }, + { + "begin": 3644, + "end": 3930, + "name": "POP", + "source": 3 + }, + { + "begin": 3644, + "end": 3930, + "name": "POP", + "source": 3 + }, + { + "begin": 3644, + "end": 3930, + "name": "POP", + "source": 3 + }, + { + "begin": 3644, + "end": 3930, + "name": "POP", + "source": 3 + }, + { + "begin": 3644, + "end": 3930, + "jumpType": "[out]", + "name": "JUMP", + "source": 3 + }, + { + "begin": 3525, + "end": 8233, + "name": "tag", + "source": 13, + "value": "194" + }, + { + "begin": 3525, + "end": 8233, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 3635, + "end": 3649, + "name": "PUSH", + "source": 13, + "value": "0" + }, + { + "begin": 3655, + "end": 3667, + "name": "DUP1", + "source": 13 + }, + { + "begin": 3696, + "end": 3710, + "name": "PUSH", + "source": 13, + "value": "0" + }, + { + "begin": 3765, + "end": 8223, + "name": "tag", + "source": 13, + "value": "248" + }, + { + "begin": 3765, + "end": 8223, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 3772, + "end": 3798, + "name": "DUP4", + "source": 13 + }, + { + "begin": 3772, + "end": 3798, + "name": "DUP2", + "source": 13 + }, + { + "begin": 3772, + "end": 3798, + "name": "LT", + "source": 13 + }, + { + "begin": 3765, + "end": 8223, + "name": "ISZERO", + "source": 13 + }, + { + "begin": 3765, + "end": 8223, + "name": "PUSH [tag]", + "source": 13, + "value": "249" + }, + { + "begin": 3765, + "end": 8223, + "name": "JUMPI", + "source": 13 + }, + { + "begin": 1475, + "end": 1476, + "name": "PUSH", + "source": 19, + "value": "1" + }, + { + "begin": 1463, + "end": 1477, + "name": "DUP2", + "source": 19 + }, + { + "begin": 1463, + "end": 1477, + "name": "ADD", + "source": 19 + }, + { + "begin": 1463, + "end": 1477, + "name": "SWAP1", + "source": 19 + }, + { + "begin": 1390, + "end": 1415, + "name": "DUP6", + "source": 19 + }, + { + "begin": 1390, + "end": 1415, + "name": "ADD", + "source": 19 + }, + { + "begin": 1377, + "end": 1416, + "name": "CALLDATALOAD", + "source": 19 + }, + { + "begin": 1432, + "end": 1435, + "name": "PUSH", + "source": 19, + "value": "F8" + }, + { + "begin": 1428, + "end": 1442, + "name": "SHR", + "source": 19 + }, + { + "begin": 3923, + "end": 3943, + "name": "PUSH", + "source": 13, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { + "begin": 3923, + "end": 3943, + "name": "DUP2", + "source": 13 + }, + { + "begin": 3923, + "end": 3943, + "name": "ADD", + "source": 13 + }, + { + "begin": 3919, + "end": 4321, + "name": "PUSH [tag]", + "source": 13, + "value": "252" + }, + { + "begin": 3919, + "end": 4321, + "name": "JUMPI", + "source": 13 + }, + { + "begin": 2205, + "end": 2207, + "name": "PUSH", + "source": 19, + "value": "15" + }, + { + "begin": 2193, + "end": 2208, + "name": "DUP3", + "source": 19 + }, + { + "begin": 2193, + "end": 2208, + "name": "ADD", + "source": 19 + }, + { + "begin": 2193, + "end": 2208, + "name": "SWAP2", + "source": 19 + }, + { + "begin": 2046, + "end": 2071, + "name": "DUP7", + "source": 19 + }, + { + "begin": 2046, + "end": 2071, + "name": "ADD", + "source": 19 + }, + { + "begin": 2033, + "end": 2072, + "name": "CALLDATALOAD", + "source": 19 + }, + { + "begin": 2088, + "end": 2091, + "name": "PUSH", + "source": 19, + "value": "F8" + }, + { + "begin": 2084, + "end": 2098, + "name": "DUP2", + "source": 19 + }, + { + "begin": 2084, + "end": 2098, + "name": "SWAP1", + "source": 19 + }, + { + "begin": 2084, + "end": 2098, + "name": "SHR", + "source": 19 + }, + { + "begin": 2084, + "end": 2098, + "name": "SWAP1", + "source": 19 + }, + { + "begin": 2118, + "end": 2120, + "name": "PUSH", + "source": 19, + "value": "58" + }, + { + "begin": 2114, + "end": 2127, + "name": "SHR", + "source": 19 + }, + { + "begin": 2129, + "end": 2171, + "name": "PUSH", + "source": 19, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { + "begin": 2110, + "end": 2172, + "name": "DUP2", + "source": 19 + }, + { + "begin": 2110, + "end": 2172, + "name": "AND", + "source": 19 + }, + { + "begin": 2110, + "end": 2172, + "name": "SWAP1", + "source": 19 + }, + { + "begin": 1873, + "end": 1896, + "name": "PUSH", + "source": 13, + "value": "FF0000000000000000000000000000000000000000" + }, + { + "begin": 1873, + "end": 1896, + "name": "AND", + "source": 13 + }, + { + "begin": 1873, + "end": 1922, + "name": "DUP2", + "source": 13 + }, + { + "begin": 1873, + "end": 1922, + "name": "OR", + "source": 13 + }, + { + "begin": 4231, + "end": 4235, + "name": "DUP6", + "source": 13 + }, + { + "begin": 4231, + "end": 4290, + "name": "PUSH [tag]", + "source": 13, + "value": "257" + }, + { + "begin": 4231, + "end": 4290, + "name": "JUMPI", + "source": 13 + }, + { + "begin": 4286, + "end": 4290, + "name": "DUP1", + "source": 13 + }, + { + "begin": 4231, + "end": 4290, + "name": "PUSH [tag]", + "source": 13, + "value": "259" + }, + { + "begin": 4231, + "end": 4290, + "name": "JUMP", + "source": 13 + }, + { + "begin": 4231, + "end": 4290, + "name": "tag", + "source": 13, + "value": "257" + }, + { + "begin": 4231, + "end": 4290, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 622, + "end": 631, + "name": "PUSH", + "source": 20, + "value": "0" + }, + { + "begin": 656, + "end": 669, + "name": "DUP7", + "source": 20 + }, + { + "begin": 656, + "end": 669, + "name": "DUP2", + "source": 20 + }, + { + "begin": 656, + "end": 669, + "name": "MSTORE", + "source": 20 + }, + { + "begin": 683, + "end": 685, + "name": "PUSH", + "source": 20, + "value": "20" + }, + { + "begin": 676, + "end": 690, + "name": "DUP3", + "source": 20 + }, + { + "begin": 676, + "end": 690, + "name": "SWAP1", + "source": 20 + }, + { + "begin": 676, + "end": 690, + "name": "MSTORE", + "source": 20 + }, + { + "begin": 715, + "end": 717, + "name": "PUSH", + "source": 20, + "value": "40" + }, + { + "begin": 702, + "end": 718, + "name": "SWAP1", + "source": 20 + }, + { + "begin": 702, + "end": 718, + "name": "KECCAK256", + "source": 20 + }, + { + "begin": 4252, + "end": 4283, + "name": "tag", + "source": 13, + "value": "259" + }, + { + "begin": 4252, + "end": 4283, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 4224, + "end": 4290, + "name": "SWAP6", + "source": 13 + }, + { + "begin": 4224, + "end": 4290, + "name": "POP", + "source": 13 + }, + { + "begin": 4302, + "end": 4310, + "name": "POP", + "source": 13 + }, + { + "begin": 4302, + "end": 4310, + "name": "POP", + "source": 13 + }, + { + "begin": 4302, + "end": 4310, + "name": "POP", + "source": 13 + }, + { + "begin": 4302, + "end": 4310, + "name": "POP", + "source": 13 + }, + { + "begin": 4302, + "end": 4310, + "name": "PUSH [tag]", + "source": 13, + "value": "248" + }, + { + "begin": 4302, + "end": 4310, + "name": "JUMP", + "source": 13 + }, + { + "begin": 3919, + "end": 4321, + "name": "tag", + "source": 13, + "value": "252" + }, + { + "begin": 3919, + "end": 4321, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 4335, + "end": 4339, + "name": "DUP1", + "source": 13 + }, + { + "begin": 4331, + "end": 5010, + "name": "PUSH [tag]", + "source": 13, + "value": "260" + }, + { + "begin": 4331, + "end": 5010, + "name": "JUMPI", + "source": 13 + }, + { + "begin": 1475, + "end": 1476, + "name": "PUSH", + "source": 19, + "value": "1" + }, + { + "begin": 1463, + "end": 1477, + "name": "DUP3", + "source": 19 + }, + { + "begin": 1463, + "end": 1477, + "name": "ADD", + "source": 19 + }, + { + "begin": 1463, + "end": 1477, + "name": "SWAP2", + "source": 19 + }, + { + "begin": 1390, + "end": 1415, + "name": "DUP7", + "source": 19 + }, + { + "begin": 1390, + "end": 1415, + "name": "DUP2", + "source": 19 + }, + { + "begin": 1390, + "end": 1415, + "name": "ADD", + "source": 19 + }, + { + "begin": 1377, + "end": 1416, + "name": "CALLDATALOAD", + "source": 19 + }, + { + "begin": 1432, + "end": 1435, + "name": "PUSH", + "source": 19, + "value": "F8" + }, + { + "begin": 1428, + "end": 1442, + "name": "SHR", + "source": 19 + }, + { + "begin": 1428, + "end": 1442, + "name": "SWAP1", + "source": 19 + }, + { + "begin": 4560, + "end": 4571, + "name": "PUSH", + "source": 13, + "value": "43" + }, + { + "begin": 4560, + "end": 4571, + "name": "ADD", + "source": 13 + }, + { + "begin": 4396, + "end": 4412, + "name": "PUSH", + "source": 13, + "value": "0" + }, + { + "begin": 4598, + "end": 4670, + "name": "PUSH [tag]", + "source": 13, + "value": "262" + }, + { + "begin": 4631, + "end": 4641, + "name": "DUP11", + "source": 13 + }, + { + "begin": 4643, + "end": 4669, + "name": "PUSH [tag]", + "source": 13, + "value": "263" + }, + { + "begin": 4560, + "end": 4571, + "name": "DUP5", + "source": 13 + }, + { + "begin": 1463, + "end": 1477, + "name": "DUP9", + "source": 19 + }, + { + "begin": 4643, + "end": 4653, + "name": "DUP13", + "source": 13 + }, + { + "begin": 1390, + "end": 1415, + "name": "DUP15", + "source": 19 + }, + { + "begin": 4643, + "end": 4669, + "name": "PUSH [tag]", + "source": 13, + "value": "193" + }, + { + "begin": 4643, + "end": 4669, + "jumpType": "[in]", + "name": "JUMP", + "source": 13 + }, + { + "begin": 4643, + "end": 4669, + "name": "tag", + "source": 13, + "value": "263" + }, + { + "begin": 4643, + "end": 4669, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 4598, + "end": 4630, + "name": "PUSH [tag]", + "source": 13, + "value": "264" + }, + { + "begin": 4598, + "end": 4670, + "jumpType": "[in]", + "name": "JUMP", + "source": 13 + }, + { + "begin": 4598, + "end": 4670, + "name": "tag", + "source": 13, + "value": "262" + }, + { + "begin": 4598, + "end": 4670, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 4764, + "end": 4784, + "name": "PUSH", + "source": 13, + "value": "FF" + }, + { + "begin": 4764, + "end": 4784, + "name": "DUP5", + "source": 13 + }, + { + "begin": 4764, + "end": 4784, + "name": "AND", + "source": 13 + }, + { + "begin": 4764, + "end": 4784, + "name": "SWAP8", + "source": 13 + }, + { + "begin": 4764, + "end": 4784, + "name": "SWAP1", + "source": 13 + }, + { + "begin": 4764, + "end": 4784, + "name": "SWAP8", + "source": 13 + }, + { + "begin": 4764, + "end": 4784, + "name": "ADD", + "source": 13 + }, + { + "begin": 4764, + "end": 4784, + "name": "SWAP7", + "source": 13 + }, + { + "begin": 4691, + "end": 4698, + "name": "SWAP2", + "source": 13 + }, + { + "begin": 4691, + "end": 4698, + "name": "SWAP5", + "source": 13 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 4691, + "end": 4698, + "name": "DUP5", + "source": 13 + }, + { + "begin": 4691, + "end": 4698, + "name": "SWAP2", + "source": 13 + }, + { + "begin": 4764, + "end": 4784, + "name": "SWAP1", + "source": 13 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 1893, + "end": 1896, + "name": "PUSH", + "source": 13, + "value": "A0" + }, + { + "begin": 1873, + "end": 1896, + "name": "DUP4", + "source": 13 + }, + { + "begin": 1873, + "end": 1896, + "name": "SWAP1", + "source": 13 + }, + { + "begin": 1873, + "end": 1896, + "name": "SHL", + "source": 13 + }, + { + "begin": 1873, + "end": 1896, + "name": "PUSH", + "source": 13, + "value": "FF0000000000000000000000000000000000000000" + }, + { + "begin": 1873, + "end": 1896, + "name": "AND", + "source": 13 + }, + { + "begin": 1899, + "end": 1922, + "name": "PUSH", + "source": 13, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { + "begin": 1899, + "end": 1922, + "name": "DUP3", + "source": 13 + }, + { + "begin": 1899, + "end": 1922, + "name": "AND", + "source": 13 + }, + { + "begin": 1873, + "end": 1922, + "name": "OR", + "source": 13 + }, + { + "begin": 4920, + "end": 4924, + "name": "DUP7", + "source": 13 + }, + { + "begin": 4920, + "end": 4979, + "name": "PUSH [tag]", + "source": 13, + "value": "266" + }, + { + "begin": 4920, + "end": 4979, + "name": "JUMPI", + "source": 13 + }, + { + "begin": 4975, + "end": 4979, + "name": "DUP1", + "source": 13 + }, + { + "begin": 4920, + "end": 4979, + "name": "PUSH [tag]", + "source": 13, + "value": "268" + }, + { + "begin": 4920, + "end": 4979, + "name": "JUMP", + "source": 13 + }, + { + "begin": 4920, + "end": 4979, + "name": "tag", + "source": 13, + "value": "266" + }, + { + "begin": 4920, + "end": 4979, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 622, + "end": 631, + "name": "PUSH", + "source": 20, + "value": "0" + }, + { + "begin": 656, + "end": 669, + "name": "DUP8", + "source": 20 + }, + { + "begin": 656, + "end": 669, + "name": "DUP2", + "source": 20 + }, + { + "begin": 656, + "end": 669, + "name": "MSTORE", + "source": 20 + }, + { + "begin": 683, + "end": 685, + "name": "PUSH", + "source": 20, + "value": "20" + }, + { + "begin": 676, + "end": 690, + "name": "DUP3", + "source": 20 + }, + { + "begin": 676, + "end": 690, + "name": "SWAP1", + "source": 20 + }, + { + "begin": 676, + "end": 690, + "name": "MSTORE", + "source": 20 + }, + { + "begin": 715, + "end": 717, + "name": "PUSH", + "source": 20, + "value": "40" + }, + { + "begin": 702, + "end": 718, + "name": "SWAP1", + "source": 20 + }, + { + "begin": 702, + "end": 718, + "name": "KECCAK256", + "source": 20 + }, + { + "begin": 4941, + "end": 4972, + "name": "tag", + "source": 13, + "value": "268" + }, + { + "begin": 4941, + "end": 4972, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 4913, + "end": 4979, + "name": "SWAP7", + "source": 13 + }, + { + "begin": 4913, + "end": 4979, + "name": "POP", + "source": 13 + }, + { + "begin": 4991, + "end": 4999, + "name": "POP", + "source": 13 + }, + { + "begin": 4991, + "end": 4999, + "name": "POP", + "source": 13 + }, + { + "begin": 4991, + "end": 4999, + "name": "POP", + "source": 13 + }, + { + "begin": 4991, + "end": 4999, + "name": "POP", + "source": 13 + }, + { + "begin": 4991, + "end": 4999, + "name": "POP", + "source": 13 + }, + { + "begin": 4991, + "end": 4999, + "name": "PUSH [tag]", + "source": 13, + "value": "248" + }, + { + "begin": 4991, + "end": 4999, + "name": "JUMP", + "source": 13 + }, + { + "begin": 4331, + "end": 5010, + "name": "tag", + "source": 13, + "value": "260" + }, + { + "begin": 4331, + "end": 5010, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 625, + "end": 626, + "name": "PUSH", + "source": 13, + "value": "2" + }, + { + "begin": 5024, + "end": 5028, + "name": "DUP2", + "source": 13 + }, + { + "begin": 5024, + "end": 5054, + "name": "SUB", + "source": 13 + }, + { + "begin": 5020, + "end": 5952, + "name": "PUSH [tag]", + "source": 13, + "value": "269" + }, + { + "begin": 5020, + "end": 5952, + "name": "JUMPI", + "source": 13 + }, + { + "begin": 5104, + "end": 5120, + "name": "PUSH", + "source": 13, + "value": "0" + }, + { + "begin": 5104, + "end": 5120, + "name": "DUP1", + "source": 13 + }, + { + "begin": 2046, + "end": 2071, + "name": "DUP8", + "source": 19 + }, + { + "begin": 2046, + "end": 2071, + "name": "DUP5", + "source": 19 + }, + { + "begin": 2046, + "end": 2071, + "name": "ADD", + "source": 19 + }, + { + "begin": 2033, + "end": 2072, + "name": "CALLDATALOAD", + "source": 19 + }, + { + "begin": 2088, + "end": 2091, + "name": "PUSH", + "source": 19, + "value": "F8" + }, + { + "begin": 2084, + "end": 2098, + "name": "DUP2", + "source": 19 + }, + { + "begin": 2084, + "end": 2098, + "name": "SWAP1", + "source": 19 + }, + { + "begin": 2084, + "end": 2098, + "name": "SHR", + "source": 19 + }, + { + "begin": 2084, + "end": 2098, + "name": "SWAP1", + "source": 19 + }, + { + "begin": 2118, + "end": 2120, + "name": "PUSH", + "source": 19, + "value": "58" + }, + { + "begin": 2114, + "end": 2127, + "name": "SHR", + "source": 19 + }, + { + "begin": 2129, + "end": 2171, + "name": "PUSH", + "source": 19, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { + "begin": 2110, + "end": 2172, + "name": "AND", + "source": 19 + }, + { + "begin": 2205, + "end": 2207, + "name": "PUSH", + "source": 19, + "value": "15" + }, + { + "begin": 2193, + "end": 2208, + "name": "DUP7", + "source": 19 + }, + { + "begin": 2193, + "end": 2208, + "name": "ADD", + "source": 19 + }, + { + "begin": 5146, + "end": 5210, + "name": "SWAP6", + "source": 13 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 5146, + "end": 5210, + "name": "SWAP1", + "source": 13 + }, + { + "begin": 5146, + "end": 5210, + "name": "SWAP3", + "source": 13 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 5146, + "end": 5210, + "name": "SWAP1", + "source": 13 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 5256, + "end": 5268, + "name": "PUSH", + "source": 13, + "value": "0" + }, + { + "begin": 3290, + "end": 3315, + "name": "DUP9", + "source": 19 + }, + { + "begin": 3290, + "end": 3315, + "name": "DUP6", + "source": 19 + }, + { + "begin": 3290, + "end": 3315, + "name": "ADD", + "source": 19 + }, + { + "begin": 3277, + "end": 3316, + "name": "CALLDATALOAD", + "source": 19 + }, + { + "begin": 3336, + "end": 3339, + "name": "PUSH", + "source": 19, + "value": "E8" + }, + { + "begin": 3332, + "end": 3346, + "name": "SHR", + "source": 19 + }, + { + "begin": 3390, + "end": 3391, + "name": "PUSH", + "source": 19, + "value": "3" + }, + { + "begin": 3378, + "end": 3392, + "name": "DUP7", + "source": 19 + }, + { + "begin": 3378, + "end": 3392, + "name": "ADD", + "source": 19 + }, + { + "begin": 5280, + "end": 5326, + "name": "DUP2", + "source": 13 + }, + { + "begin": 5280, + "end": 5326, + "name": "PUSH", + "source": 13, + "value": "FFFFFF" + }, + { + "begin": 5280, + "end": 5326, + "name": "AND", + "source": 13 + }, + { + "begin": 5280, + "end": 5326, + "name": "SWAP2", + "source": 13 + }, + { + "begin": 5280, + "end": 5326, + "name": "POP", + "source": 13 + }, + { + "begin": 5280, + "end": 5326, + "name": "DUP1", + "source": 13 + }, + { + "begin": 5280, + "end": 5326, + "name": "SWAP7", + "source": 13 + }, + { + "begin": 5280, + "end": 5326, + "name": "POP", + "source": 13 + }, + { + "begin": 5280, + "end": 5326, + "name": "DUP2", + "source": 13 + }, + { + "begin": 5280, + "end": 5326, + "name": "SWAP3", + "source": 13 + }, + { + "begin": 5280, + "end": 5326, + "name": "POP", + "source": 13 + }, + { + "begin": 5280, + "end": 5326, + "name": "POP", + "source": 13 + }, + { + "begin": 5280, + "end": 5326, + "name": "POP", + "source": 13 + }, + { + "begin": 5380, + "end": 5395, + "name": "PUSH", + "source": 13, + "value": "0" + }, + { + "begin": 5407, + "end": 5411, + "name": "DUP2", + "source": 13 + }, + { + "begin": 5398, + "end": 5404, + "name": "DUP7", + "source": 13 + }, + { + "begin": 5398, + "end": 5411, + "name": "ADD", + "source": 13 + }, + { + "begin": 5380, + "end": 5411, + "name": "SWAP1", + "source": 13 + }, + { + "begin": 5380, + "end": 5411, + "name": "POP", + "source": 13 + }, + { + "begin": 5428, + "end": 5509, + "name": "PUSH [tag]", + "source": 13, + "value": "272" + }, + { + "begin": 5464, + "end": 5474, + "name": "DUP12", + "source": 13 + }, + { + "begin": 5476, + "end": 5480, + "name": "DUP5", + "source": 13 + }, + { + "begin": 5482, + "end": 5492, + "name": "DUP13", + "source": 13 + }, + { + "begin": 5482, + "end": 5492, + "name": "DUP13", + "source": 13 + }, + { + "begin": 5493, + "end": 5499, + "name": "DUP11", + "source": 13 + }, + { + "begin": 5482, + "end": 5508, + "name": "SWAP1", + "source": 13 + }, + { + "begin": 5500, + "end": 5507, + "name": "DUP7", + "source": 13 + }, + { + "begin": 5482, + "end": 5508, + "name": "SWAP3", + "source": 13 + }, + { + "begin": 5482, + "end": 5508, + "name": "PUSH [tag]", + "source": 13, + "value": "273" + }, + { + "begin": 5482, + "end": 5508, + "name": "SWAP4", + "source": 13 + }, + { + "begin": 5482, + "end": 5508, + "name": "SWAP3", + "source": 13 + }, + { + "begin": 5482, + "end": 5508, + "name": "SWAP2", + "source": 13 + }, + { + "begin": 5482, + "end": 5508, + "name": "SWAP1", + "source": 13 + }, + { + "begin": 5482, + "end": 5508, + "name": "PUSH [tag]", + "source": 13, + "value": "193" + }, + { + "begin": 5482, + "end": 5508, + "jumpType": "[in]", + "name": "JUMP", + "source": 13 + }, + { + "begin": 5482, + "end": 5508, + "name": "tag", + "source": 13, + "value": "273" + }, + { + "begin": 5482, + "end": 5508, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 5428, + "end": 5463, + "name": "PUSH [tag]", + "source": 13, + "value": "274" + }, + { + "begin": 5428, + "end": 5509, + "jumpType": "[in]", + "name": "JUMP", + "source": 13 + }, + { + "begin": 5428, + "end": 5509, + "name": "tag", + "source": 13, + "value": "272" + }, + { + "begin": 5428, + "end": 5509, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 5423, + "end": 5613, + "name": "PUSH [tag]", + "source": 13, + "value": "275" + }, + { + "begin": 5423, + "end": 5613, + "name": "JUMPI", + "source": 13 + }, + { + "begin": 5555, + "end": 5565, + "name": "DUP11", + "source": 13 + }, + { + "begin": 5567, + "end": 5571, + "name": "DUP4", + "source": 13 + }, + { + "begin": 5573, + "end": 5599, + "name": "PUSH [tag]", + "source": 13, + "value": "276" + }, + { + "begin": 5591, + "end": 5598, + "name": "DUP4", + "source": 13 + }, + { + "begin": 5584, + "end": 5590, + "name": "DUP10", + "source": 13 + }, + { + "begin": 5573, + "end": 5583, + "name": "DUP14", + "source": 13 + }, + { + "begin": 5573, + "end": 5583, + "name": "DUP16", + "source": 13 + }, + { + "begin": 5573, + "end": 5599, + "name": "PUSH [tag]", + "source": 13, + "value": "193" + }, + { + "begin": 5573, + "end": 5599, + "jumpType": "[in]", + "name": "JUMP", + "source": 13 + }, + { + "begin": 5573, + "end": 5599, + "name": "tag", + "source": 13, + "value": "276" + }, + { + "begin": 5573, + "end": 5599, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 5532, + "end": 5600, + "name": "PUSH", + "source": 13, + "value": "40" + }, + { + "begin": 5532, + "end": 5600, + "name": "MLOAD", + "source": 13 + }, + { + "begin": 5532, + "end": 5600, + "name": "PUSH", + "source": 13, + "value": "9A94623200000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 5532, + "end": 5600, + "name": "DUP2", + "source": 13 + }, + { + "begin": 5532, + "end": 5600, + "name": "MSTORE", + "source": 13 + }, + { + "begin": 5532, + "end": 5600, + "name": "PUSH", + "source": 13, + "value": "4" + }, + { + "begin": 5532, + "end": 5600, + "name": "ADD", + "source": 13 + }, + { + "begin": 5532, + "end": 5600, + "name": "PUSH [tag]", + "source": 13, + "value": "93" + }, + { + "begin": 5532, + "end": 5600, + "name": "SWAP5", + "source": 13 + }, + { + "begin": 5532, + "end": 5600, + "name": "SWAP4", + "source": 13 + }, + { + "begin": 5532, + "end": 5600, + "name": "SWAP3", + "source": 13 + }, + { + "begin": 5532, + "end": 5600, + "name": "SWAP2", + "source": 13 + }, + { + "begin": 5532, + "end": 5600, + "name": "SWAP1", + "source": 13 + }, + { + "begin": 5532, + "end": 5600, + "name": "PUSH [tag]", + "source": 13, + "value": "278" + }, + { + "begin": 5532, + "end": 5600, + "jumpType": "[in]", + "name": "JUMP", + "source": 13 + }, + { + "begin": 5423, + "end": 5613, + "name": "tag", + "source": 13, + "value": "275" + }, + { + "begin": 5423, + "end": 5613, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 5706, + "end": 5726, + "name": "PUSH", + "source": 13, + "value": "FF" + }, + { + "begin": 5706, + "end": 5726, + "name": "DUP5", + "source": 13 + }, + { + "begin": 5706, + "end": 5726, + "name": "AND", + "source": 13 + }, + { + "begin": 5706, + "end": 5726, + "name": "SWAP8", + "source": 13 + }, + { + "begin": 5706, + "end": 5726, + "name": "SWAP1", + "source": 13 + }, + { + "begin": 5706, + "end": 5726, + "name": "SWAP8", + "source": 13 + }, + { + "begin": 5706, + "end": 5726, + "name": "ADD", + "source": 13 + }, + { + "begin": 5706, + "end": 5726, + "name": "SWAP7", + "source": 13 + }, + { + "begin": 5706, + "end": 5726, + "name": "SWAP5", + "source": 13 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 5706, + "end": 5726, + "name": "DUP5", + "source": 13 + }, + { + "begin": 1893, + "end": 1896, + "name": "PUSH", + "source": 13, + "value": "A0" + }, + { + "begin": 1873, + "end": 1896, + "name": "DUP5", + "source": 13 + }, + { + "begin": 1873, + "end": 1896, + "name": "SWAP1", + "source": 13 + }, + { + "begin": 1873, + "end": 1896, + "name": "SHL", + "source": 13 + }, + { + "begin": 1873, + "end": 1896, + "name": "PUSH", + "source": 13, + "value": "FF0000000000000000000000000000000000000000" + }, + { + "begin": 1873, + "end": 1896, + "name": "AND", + "source": 13 + }, + { + "begin": 1899, + "end": 1922, + "name": "PUSH", + "source": 13, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { + "begin": 1899, + "end": 1922, + "name": "DUP5", + "source": 13 + }, + { + "begin": 1899, + "end": 1922, + "name": "AND", + "source": 13 + }, + { + "begin": 1873, + "end": 1922, + "name": "OR", + "source": 13 + }, + { + "begin": 5862, + "end": 5866, + "name": "DUP8", + "source": 13 + }, + { + "begin": 5862, + "end": 5921, + "name": "PUSH [tag]", + "source": 13, + "value": "280" + }, + { + "begin": 5862, + "end": 5921, + "name": "JUMPI", + "source": 13 + }, + { + "begin": 5917, + "end": 5921, + "name": "DUP1", + "source": 13 + }, + { + "begin": 5862, + "end": 5921, + "name": "PUSH [tag]", + "source": 13, + "value": "282" + }, + { + "begin": 5862, + "end": 5921, + "name": "JUMP", + "source": 13 + }, + { + "begin": 5862, + "end": 5921, + "name": "tag", + "source": 13, + "value": "280" + }, + { + "begin": 5862, + "end": 5921, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 622, + "end": 631, + "name": "PUSH", + "source": 20, + "value": "0" + }, + { + "begin": 656, + "end": 669, + "name": "DUP9", + "source": 20 + }, + { + "begin": 656, + "end": 669, + "name": "DUP2", + "source": 20 + }, + { + "begin": 656, + "end": 669, + "name": "MSTORE", + "source": 20 + }, + { + "begin": 683, + "end": 685, + "name": "PUSH", + "source": 20, + "value": "20" + }, + { + "begin": 676, + "end": 690, + "name": "DUP3", + "source": 20 + }, + { + "begin": 676, + "end": 690, + "name": "SWAP1", + "source": 20 + }, + { + "begin": 676, + "end": 690, + "name": "MSTORE", + "source": 20 + }, + { + "begin": 715, + "end": 717, + "name": "PUSH", + "source": 20, + "value": "40" + }, + { + "begin": 702, + "end": 718, + "name": "SWAP1", + "source": 20 + }, + { + "begin": 702, + "end": 718, + "name": "KECCAK256", + "source": 20 + }, + { + "begin": 5883, + "end": 5914, + "name": "tag", + "source": 13, + "value": "282" + }, + { + "begin": 5883, + "end": 5914, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 5855, + "end": 5921, + "name": "SWAP8", + "source": 13 + }, + { + "begin": 5855, + "end": 5921, + "name": "POP", + "source": 13 + }, + { + "begin": 5933, + "end": 5941, + "name": "POP", + "source": 13 + }, + { + "begin": 5933, + "end": 5941, + "name": "POP", + "source": 13 + }, + { + "begin": 5933, + "end": 5941, + "name": "POP", + "source": 13 + }, + { + "begin": 5933, + "end": 5941, + "name": "POP", + "source": 13 + }, + { + "begin": 5933, + "end": 5941, + "name": "POP", + "source": 13 + }, + { + "begin": 5933, + "end": 5941, + "name": "POP", + "source": 13 + }, + { + "begin": 5933, + "end": 5941, + "name": "PUSH [tag]", + "source": 13, + "value": "248" + }, + { + "begin": 5933, + "end": 5941, + "name": "JUMP", + "source": 13 + }, + { + "begin": 5020, + "end": 5952, + "name": "tag", + "source": 13, + "value": "269" + }, + { + "begin": 5020, + "end": 5952, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 667, + "end": 668, + "name": "PUSH", + "source": 13, + "value": "3" + }, + { + "begin": 5966, + "end": 5970, + "name": "DUP2", + "source": 13 + }, + { + "begin": 5966, + "end": 5983, + "name": "SUB", + "source": 13 + }, + { + "begin": 5962, + "end": 6205, + "name": "PUSH [tag]", + "source": 13, + "value": "283" + }, + { + "begin": 5962, + "end": 6205, + "name": "JUMPI", + "source": 13 + }, + { + "begin": 4550, + "end": 4552, + "name": "PUSH", + "source": 19, + "value": "20" + }, + { + "begin": 4536, + "end": 4553, + "name": "DUP3", + "source": 19 + }, + { + "begin": 4536, + "end": 4553, + "name": "ADD", + "source": 19 + }, + { + "begin": 4536, + "end": 4553, + "name": "SWAP2", + "source": 19 + }, + { + "begin": 4487, + "end": 4514, + "name": "DUP7", + "source": 19 + }, + { + "begin": 4487, + "end": 4514, + "name": "ADD", + "source": 19 + }, + { + "begin": 4474, + "end": 4515, + "name": "CALLDATALOAD", + "source": 19 + }, + { + "begin": 6115, + "end": 6119, + "name": "DUP4", + "source": 13 + }, + { + "begin": 6115, + "end": 6174, + "name": "PUSH [tag]", + "source": 13, + "value": "286" + }, + { + "begin": 6115, + "end": 6174, + "name": "JUMPI", + "source": 13 + }, + { + "begin": 6170, + "end": 6174, + "name": "DUP1", + "source": 13 + }, + { + "begin": 6115, + "end": 6174, + "name": "PUSH [tag]", + "source": 13, + "value": "288" + }, + { + "begin": 6115, + "end": 6174, + "name": "JUMP", + "source": 13 + }, + { + "begin": 6115, + "end": 6174, + "name": "tag", + "source": 13, + "value": "286" + }, + { + "begin": 6115, + "end": 6174, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 622, + "end": 631, + "name": "PUSH", + "source": 20, + "value": "0" + }, + { + "begin": 656, + "end": 669, + "name": "DUP5", + "source": 20 + }, + { + "begin": 656, + "end": 669, + "name": "DUP2", + "source": 20 + }, + { + "begin": 656, + "end": 669, + "name": "MSTORE", + "source": 20 + }, + { + "begin": 683, + "end": 685, + "name": "PUSH", + "source": 20, + "value": "20" + }, + { + "begin": 676, + "end": 690, + "name": "DUP3", + "source": 20 + }, + { + "begin": 676, + "end": 690, + "name": "SWAP1", + "source": 20 + }, + { + "begin": 676, + "end": 690, + "name": "MSTORE", + "source": 20 + }, + { + "begin": 715, + "end": 717, + "name": "PUSH", + "source": 20, + "value": "40" + }, + { + "begin": 702, + "end": 718, + "name": "SWAP1", + "source": 20 + }, + { + "begin": 702, + "end": 718, + "name": "KECCAK256", + "source": 20 + }, + { + "begin": 6136, + "end": 6167, + "name": "tag", + "source": 13, + "value": "288" + }, + { + "begin": 6136, + "end": 6167, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 6108, + "end": 6174, + "name": "SWAP4", + "source": 13 + }, + { + "begin": 6108, + "end": 6174, + "name": "POP", + "source": 13 + }, + { + "begin": 6186, + "end": 6194, + "name": "POP", + "source": 13 + }, + { + "begin": 6186, + "end": 6194, + "name": "POP", + "source": 13 + }, + { + "begin": 6186, + "end": 6194, + "name": "PUSH [tag]", + "source": 13, + "value": "248" + }, + { + "begin": 6186, + "end": 6194, + "name": "JUMP", + "source": 13 + }, + { + "begin": 5962, + "end": 6205, + "name": "tag", + "source": 13, + "value": "283" + }, + { + "begin": 5962, + "end": 6205, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 711, + "end": 712, + "name": "PUSH", + "source": 13, + "value": "4" + }, + { + "begin": 6219, + "end": 6223, + "name": "DUP2", + "source": 13 + }, + { + "begin": 6219, + "end": 6238, + "name": "SUB", + "source": 13 + }, + { + "begin": 6215, + "end": 6687, + "name": "PUSH [tag]", + "source": 13, + "value": "289" + }, + { + "begin": 6215, + "end": 6687, + "name": "JUMPI", + "source": 13 + }, + { + "begin": 3390, + "end": 3391, + "name": "PUSH", + "source": 19, + "value": "3" + }, + { + "begin": 3378, + "end": 3392, + "name": "DUP1", + "source": 19 + }, + { + "begin": 3378, + "end": 3392, + "name": "DUP4", + "source": 19 + }, + { + "begin": 3378, + "end": 3392, + "name": "ADD", + "source": 19 + }, + { + "begin": 3378, + "end": 3392, + "name": "SWAP3", + "source": 19 + }, + { + "begin": 3290, + "end": 3315, + "name": "DUP8", + "source": 19 + }, + { + "begin": 3290, + "end": 3315, + "name": "DUP2", + "source": 19 + }, + { + "begin": 3290, + "end": 3315, + "name": "ADD", + "source": 19 + }, + { + "begin": 3277, + "end": 3316, + "name": "CALLDATALOAD", + "source": 19 + }, + { + "begin": 3336, + "end": 3339, + "name": "PUSH", + "source": 19, + "value": "E8" + }, + { + "begin": 3332, + "end": 3346, + "name": "SHR", + "source": 19 + }, + { + "begin": 3332, + "end": 3346, + "name": "SWAP2", + "source": 19 + }, + { + "begin": 6409, + "end": 6422, + "name": "SWAP1", + "source": 13 + }, + { + "begin": 6409, + "end": 6422, + "name": "DUP3", + "source": 13 + }, + { + "begin": 6409, + "end": 6422, + "name": "ADD", + "source": 13 + }, + { + "begin": 6409, + "end": 6422, + "name": "ADD", + "source": 13 + }, + { + "begin": 6309, + "end": 6321, + "name": "PUSH", + "source": 13, + "value": "0" + }, + { + "begin": 6309, + "end": 6321, + "name": "DUP1", + "source": 13 + }, + { + "begin": 6494, + "end": 6547, + "name": "PUSH [tag]", + "source": 13, + "value": "291" + }, + { + "begin": 6508, + "end": 6518, + "name": "DUP12", + "source": 13 + }, + { + "begin": 6520, + "end": 6546, + "name": "PUSH [tag]", + "source": 13, + "value": "192" + }, + { + "begin": 6409, + "end": 6422, + "name": "DUP6", + "source": 13 + }, + { + "begin": 3378, + "end": 3392, + "name": "DUP10", + "source": 19 + }, + { + "begin": 6520, + "end": 6530, + "name": "DUP14", + "source": 13 + }, + { + "begin": 3290, + "end": 3315, + "name": "DUP16", + "source": 19 + }, + { + "begin": 6520, + "end": 6546, + "name": "PUSH [tag]", + "source": 13, + "value": "193" + }, + { + "begin": 6520, + "end": 6546, + "jumpType": "[in]", + "name": "JUMP", + "source": 13 + }, + { + "begin": 6494, + "end": 6547, + "name": "tag", + "source": 13, + "value": "291" + }, + { + "begin": 6494, + "end": 6547, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 622, + "end": 631, + "name": "PUSH", + "source": 20, + "value": "0" + }, + { + "begin": 656, + "end": 669, + "name": "SWAP9", + "source": 20 + }, + { + "begin": 656, + "end": 669, + "name": "DUP10", + "source": 20 + }, + { + "begin": 656, + "end": 669, + "name": "MSTORE", + "source": 20 + }, + { + "begin": 683, + "end": 685, + "name": "PUSH", + "source": 20, + "value": "20" + }, + { + "begin": 676, + "end": 690, + "name": "MSTORE", + "source": 20 + }, + { + "begin": 715, + "end": 717, + "name": "PUSH", + "source": 20, + "value": "40" + }, + { + "begin": 702, + "end": 718, + "name": "SWAP1", + "source": 20 + }, + { + "begin": 702, + "end": 718, + "name": "SWAP8", + "source": 20 + }, + { + "begin": 702, + "end": 718, + "name": "KECCAK256", + "source": 20 + }, + { + "begin": 6560, + "end": 6577, + "name": "SWAP7", + "source": 13 + }, + { + "begin": 6560, + "end": 6577, + "name": "SWAP1", + "source": 13 + }, + { + "begin": 6560, + "end": 6577, + "name": "SWAP8", + "source": 13 + }, + { + "begin": 6560, + "end": 6577, + "name": "ADD", + "source": 13 + }, + { + "begin": 6560, + "end": 6577, + "name": "SWAP7", + "source": 13 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 6649, + "end": 6656, + "name": "SWAP1", + "source": 13 + }, + { + "begin": 6649, + "end": 6656, + "name": "SWAP4", + "source": 13 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 6668, + "end": 6676, + "name": "PUSH [tag]", + "source": 13, + "value": "248" + }, + { + "begin": 6668, + "end": 6676, + "name": "SWAP3", + "source": 13 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 6668, + "end": 6676, + "name": "JUMP", + "source": 13 + }, + { + "begin": 6215, + "end": 6687, + "name": "tag", + "source": 13, + "value": "289" + }, + { + "begin": 6215, + "end": 6687, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 802, + "end": 803, + "name": "PUSH", + "source": 13, + "value": "6" + }, + { + "begin": 6701, + "end": 6705, + "name": "DUP2", + "source": 13 + }, + { + "begin": 6701, + "end": 6720, + "name": "SUB", + "source": 13 + }, + { + "begin": 6697, + "end": 7676, + "name": "PUSH [tag]", + "source": 13, + "value": "294" + }, + { + "begin": 6697, + "end": 7676, + "name": "JUMPI", + "source": 13 + }, + { + "begin": 6864, + "end": 6886, + "name": "PUSH", + "source": 13, + "value": "0" + }, + { + "begin": 1390, + "end": 1415, + "name": "DUP3", + "source": 19 + }, + { + "begin": 1390, + "end": 1415, + "name": "DUP8", + "source": 19 + }, + { + "begin": 1390, + "end": 1415, + "name": "ADD", + "source": 19 + }, + { + "begin": 1377, + "end": 1416, + "name": "CALLDATALOAD", + "source": 19 + }, + { + "begin": 1432, + "end": 1435, + "name": "PUSH", + "source": 19, + "value": "F8" + }, + { + "begin": 1428, + "end": 1442, + "name": "SHR", + "source": 19 + }, + { + "begin": 1475, + "end": 1476, + "name": "PUSH", + "source": 19, + "value": "1" + }, + { + "begin": 1463, + "end": 1477, + "name": "DUP5", + "source": 19 + }, + { + "begin": 1463, + "end": 1477, + "name": "ADD", + "source": 19 + }, + { + "begin": 6898, + "end": 6953, + "name": "SWAP4", + "source": 13 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 6898, + "end": 6953, + "name": "PUSH", + "source": 13, + "value": "FF" + }, + { + "begin": 6898, + "end": 6953, + "name": "AND", + "source": 13 + }, + { + "begin": 6898, + "end": 6953, + "name": "SWAP1", + "source": 13 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 6966, + "end": 6991, + "name": "PUSH", + "source": 13, + "value": "0" + }, + { + "begin": 2699, + "end": 2724, + "name": "DUP8", + "source": 19 + }, + { + "begin": 2699, + "end": 2724, + "name": "DUP5", + "source": 19 + }, + { + "begin": 2699, + "end": 2724, + "name": "ADD", + "source": 19 + }, + { + "begin": 2686, + "end": 2725, + "name": "CALLDATALOAD", + "source": 19 + }, + { + "begin": 2745, + "end": 2748, + "name": "PUSH", + "source": 19, + "value": "F0" + }, + { + "begin": 2741, + "end": 2755, + "name": "SHR", + "source": 19 + }, + { + "begin": 2797, + "end": 2798, + "name": "PUSH", + "source": 19, + "value": "2" + }, + { + "begin": 2785, + "end": 2799, + "name": "DUP6", + "source": 19 + }, + { + "begin": 2785, + "end": 2799, + "name": "ADD", + "source": 19 + }, + { + "begin": 7003, + "end": 7062, + "name": "SWAP5", + "source": 13 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 7003, + "end": 7062, + "name": "PUSH", + "source": 13, + "value": "FFFF" + }, + { + "begin": 7003, + "end": 7062, + "name": "AND", + "source": 13 + }, + { + "begin": 7003, + "end": 7062, + "name": "SWAP1", + "source": 13 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 7075, + "end": 7087, + "name": "PUSH", + "source": 13, + "value": "0" + }, + { + "begin": 3290, + "end": 3315, + "name": "DUP9", + "source": 19 + }, + { + "begin": 3290, + "end": 3315, + "name": "DUP6", + "source": 19 + }, + { + "begin": 3290, + "end": 3315, + "name": "ADD", + "source": 19 + }, + { + "begin": 3277, + "end": 3316, + "name": "CALLDATALOAD", + "source": 19 + }, + { + "begin": 3336, + "end": 3339, + "name": "PUSH", + "source": 19, + "value": "E8" + }, + { + "begin": 3332, + "end": 3346, + "name": "SHR", + "source": 19 + }, + { + "begin": 3390, + "end": 3391, + "name": "PUSH", + "source": 19, + "value": "3" + }, + { + "begin": 3378, + "end": 3392, + "name": "DUP7", + "source": 19 + }, + { + "begin": 3378, + "end": 3392, + "name": "ADD", + "source": 19 + }, + { + "begin": 7099, + "end": 7145, + "name": "DUP2", + "source": 13 + }, + { + "begin": 7099, + "end": 7145, + "name": "PUSH", + "source": 13, + "value": "FFFFFF" + }, + { + "begin": 7099, + "end": 7145, + "name": "AND", + "source": 13 + }, + { + "begin": 7099, + "end": 7145, + "name": "SWAP2", + "source": 13 + }, + { + "begin": 7099, + "end": 7145, + "name": "POP", + "source": 13 + }, + { + "begin": 7099, + "end": 7145, + "name": "DUP1", + "source": 13 + }, + { + "begin": 7099, + "end": 7145, + "name": "SWAP7", + "source": 13 + }, + { + "begin": 7099, + "end": 7145, + "name": "POP", + "source": 13 + }, + { + "begin": 7099, + "end": 7145, + "name": "DUP2", + "source": 13 + }, + { + "begin": 7099, + "end": 7145, + "name": "SWAP3", + "source": 13 + }, + { + "begin": 7099, + "end": 7145, + "name": "POP", + "source": 13 + }, + { + "begin": 7099, + "end": 7145, + "name": "POP", + "source": 13 + }, + { + "begin": 7099, + "end": 7145, + "name": "POP", + "source": 13 + }, + { + "begin": 7157, + "end": 7172, + "name": "PUSH", + "source": 13, + "value": "0" + }, + { + "begin": 7184, + "end": 7188, + "name": "DUP2", + "source": 13 + }, + { + "begin": 7175, + "end": 7181, + "name": "DUP7", + "source": 13 + }, + { + "begin": 7175, + "end": 7188, + "name": "ADD", + "source": 13 + }, + { + "begin": 7157, + "end": 7188, + "name": "SWAP1", + "source": 13 + }, + { + "begin": 7157, + "end": 7188, + "name": "POP", + "source": 13 + }, + { + "begin": 7201, + "end": 7223, + "name": "PUSH", + "source": 13, + "value": "0" + }, + { + "begin": 7225, + "end": 7245, + "name": "DUP1", + "source": 13 + }, + { + "begin": 7290, + "end": 7343, + "name": "PUSH [tag]", + "source": 13, + "value": "299" + }, + { + "begin": 7304, + "end": 7314, + "name": "DUP14", + "source": 13 + }, + { + "begin": 7316, + "end": 7326, + "name": "DUP14", + "source": 13 + }, + { + "begin": 7316, + "end": 7326, + "name": "DUP14", + "source": 13 + }, + { + "begin": 7327, + "end": 7333, + "name": "DUP12", + "source": 13 + }, + { + "begin": 7316, + "end": 7342, + "name": "SWAP1", + "source": 13 + }, + { + "begin": 7334, + "end": 7341, + "name": "DUP8", + "source": 13 + }, + { + "begin": 7316, + "end": 7342, + "name": "SWAP3", + "source": 13 + }, + { + "begin": 7316, + "end": 7342, + "name": "PUSH [tag]", + "source": 13, + "value": "192" + }, + { + "begin": 7316, + "end": 7342, + "name": "SWAP4", + "source": 13 + }, + { + "begin": 7316, + "end": 7342, + "name": "SWAP3", + "source": 13 + }, + { + "begin": 7316, + "end": 7342, + "name": "SWAP2", + "source": 13 + }, + { + "begin": 7316, + "end": 7342, + "name": "SWAP1", + "source": 13 + }, + { + "begin": 7316, + "end": 7342, + "name": "PUSH [tag]", + "source": 13, + "value": "193" + }, + { + "begin": 7316, + "end": 7342, + "jumpType": "[in]", + "name": "JUMP", + "source": 13 + }, + { + "begin": 7290, + "end": 7343, + "name": "tag", + "source": 13, + "value": "299" + }, + { + "begin": 7290, + "end": 7343, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 7364, + "end": 7371, + "name": "SWAP4", + "source": 13 + }, + { + "begin": 7364, + "end": 7371, + "name": "SWAP9", + "source": 13 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 7364, + "end": 7371, + "name": "DUP9", + "source": 13 + }, + { + "begin": 7364, + "end": 7371, + "name": "SWAP4", + "source": 13 + }, + { + "begin": 7257, + "end": 7343, + "name": "SWAP1", + "source": 13 + }, + { + "begin": 7257, + "end": 7343, + "name": "SWAP3", + "source": 13 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 7257, + "end": 7343, + "name": "SWAP1", + "source": 13 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 7388, + "end": 7423, + "name": "DUP5", + "source": 13 + }, + { + "begin": 7388, + "end": 7423, + "name": "DUP3", + "source": 13 + }, + { + "begin": 7388, + "end": 7423, + "name": "LT", + "source": 13 + }, + { + "begin": 7384, + "end": 7476, + "name": "PUSH [tag]", + "source": 13, + "value": "301" + }, + { + "begin": 7384, + "end": 7476, + "name": "JUMPI", + "source": 13 + }, + { + "begin": 7439, + "end": 7463, + "name": "SWAP9", + "source": 13 + }, + { + "begin": 7439, + "end": 7463, + "name": "DUP6", + "source": 13 + }, + { + "begin": 7439, + "end": 7463, + "name": "ADD", + "source": 13 + }, + { + "begin": 7439, + "end": 7463, + "name": "SWAP9", + "source": 13 + }, + { + "begin": 7384, + "end": 7476, + "name": "tag", + "source": 13, + "value": "301" + }, + { + "begin": 7384, + "end": 7476, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 2976, + "end": 3049, + "name": "PUSH", + "source": 13, + "value": "40" + }, + { + "begin": 2976, + "end": 3049, + "name": "DUP1", + "source": 13 + }, + { + "begin": 2976, + "end": 3049, + "name": "MLOAD", + "source": 13 + }, + { + "begin": 20362, + "end": 20428, + "name": "PUSH", + "source": 22, + "value": "53657175656E6365206E657374656420636F6E6669673A0A0000000000000000" + }, + { + "begin": 2976, + "end": 3049, + "name": "PUSH", + "source": 13, + "value": "20" + }, + { + "begin": 2976, + "end": 3049, + "name": "DUP1", + "source": 13 + }, + { + "begin": 2976, + "end": 3049, + "name": "DUP4", + "source": 13 + }, + { + "begin": 2976, + "end": 3049, + "name": "ADD", + "source": 13 + }, + { + "begin": 20350, + "end": 20429, + "name": "SWAP2", + "source": 22 + }, + { + "begin": 20350, + "end": 20429, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 20350, + "end": 20429, + "name": "SWAP2", + "source": 22 + }, + { + "begin": 20350, + "end": 20429, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 20445, + "end": 20457, + "name": "PUSH", + "source": 22, + "value": "38" + }, + { + "begin": 20445, + "end": 20457, + "name": "DUP3", + "source": 22 + }, + { + "begin": 20445, + "end": 20457, + "name": "ADD", + "source": 22 + }, + { + "begin": 20438, + "end": 20466, + "name": "DUP5", + "source": 22 + }, + { + "begin": 20438, + "end": 20466, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 20438, + "end": 20466, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 20482, + "end": 20494, + "name": "PUSH", + "source": 22, + "value": "58" + }, + { + "begin": 20482, + "end": 20494, + "name": "DUP3", + "source": 22 + }, + { + "begin": 20482, + "end": 20494, + "name": "ADD", + "source": 22 + }, + { + "begin": 20475, + "end": 20503, + "name": "DUP9", + "source": 22 + }, + { + "begin": 20475, + "end": 20503, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 20475, + "end": 20503, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 20519, + "end": 20531, + "name": "PUSH", + "source": 22, + "value": "78" + }, + { + "begin": 20519, + "end": 20531, + "name": "DUP1", + "source": 22 + }, + { + "begin": 20519, + "end": 20531, + "name": "DUP4", + "source": 22 + }, + { + "begin": 20519, + "end": 20531, + "name": "ADD", + "source": 22 + }, + { + "begin": 20512, + "end": 20540, + "name": "DUP11", + "source": 22 + }, + { + "begin": 20512, + "end": 20540, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 20512, + "end": 20540, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 2976, + "end": 3049, + "name": "DUP4", + "source": 13 + }, + { + "begin": 2976, + "end": 3049, + "name": "MLOAD", + "source": 13 + }, + { + "begin": 2976, + "end": 3049, + "name": "DUP1", + "source": 13 + }, + { + "begin": 2976, + "end": 3049, + "name": "DUP5", + "source": 13 + }, + { + "begin": 2976, + "end": 3049, + "name": "SUB", + "source": 13 + }, + { + "begin": 2976, + "end": 3049, + "name": "SWAP1", + "source": 13 + }, + { + "begin": 2976, + "end": 3049, + "name": "SWAP2", + "source": 13 + }, + { + "begin": 2976, + "end": 3049, + "name": "ADD", + "source": 13 + }, + { + "begin": 2976, + "end": 3049, + "name": "DUP2", + "source": 13 + }, + { + "begin": 2976, + "end": 3049, + "name": "MSTORE", + "source": 13 + }, + { + "begin": 20556, + "end": 20569, + "name": "PUSH", + "source": 22, + "value": "98" + }, + { + "begin": 20556, + "end": 20569, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 20556, + "end": 20569, + "name": "SWAP3", + "source": 22 + }, + { + "begin": 20556, + "end": 20569, + "name": "ADD", + "source": 22 + }, + { + "begin": 2976, + "end": 3049, + "name": "SWAP1", + "source": 13 + }, + { + "begin": 2976, + "end": 3049, + "name": "SWAP3", + "source": 13 + }, + { + "begin": 2976, + "end": 3049, + "name": "MSTORE", + "source": 13 + }, + { + "begin": 2966, + "end": 3050, + "name": "DUP1", + "source": 13 + }, + { + "begin": 2966, + "end": 3050, + "name": "MLOAD", + "source": 13 + }, + { + "begin": 2966, + "end": 3050, + "name": "SWAP2", + "source": 13 + }, + { + "begin": 2966, + "end": 3050, + "name": "ADD", + "source": 13 + }, + { + "begin": 2966, + "end": 3050, + "name": "KECCAK256", + "source": 13 + }, + { + "begin": 7585, + "end": 7589, + "name": "DUP10", + "source": 13 + }, + { + "begin": 7585, + "end": 7644, + "name": "PUSH [tag]", + "source": 13, + "value": "304" + }, + { + "begin": 7585, + "end": 7644, + "name": "JUMPI", + "source": 13 + }, + { + "begin": 7640, + "end": 7644, + "name": "DUP1", + "source": 13 + }, + { + "begin": 7585, + "end": 7644, + "name": "PUSH [tag]", + "source": 13, + "value": "306" + }, + { + "begin": 7585, + "end": 7644, + "name": "JUMP", + "source": 13 + }, + { + "begin": 7585, + "end": 7644, + "name": "tag", + "source": 13, + "value": "304" + }, + { + "begin": 7585, + "end": 7644, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 622, + "end": 631, + "name": "PUSH", + "source": 20, + "value": "0" + }, + { + "begin": 656, + "end": 669, + "name": "DUP11", + "source": 20 + }, + { + "begin": 656, + "end": 669, + "name": "DUP2", + "source": 20 + }, + { + "begin": 656, + "end": 669, + "name": "MSTORE", + "source": 20 + }, + { + "begin": 683, + "end": 685, + "name": "PUSH", + "source": 20, + "value": "20" + }, + { + "begin": 676, + "end": 690, + "name": "DUP3", + "source": 20 + }, + { + "begin": 676, + "end": 690, + "name": "SWAP1", + "source": 20 + }, + { + "begin": 676, + "end": 690, + "name": "MSTORE", + "source": 20 + }, + { + "begin": 715, + "end": 717, + "name": "PUSH", + "source": 20, + "value": "40" + }, + { + "begin": 702, + "end": 718, + "name": "SWAP1", + "source": 20 + }, + { + "begin": 702, + "end": 718, + "name": "KECCAK256", + "source": 20 + }, + { + "begin": 7606, + "end": 7637, + "name": "tag", + "source": 13, + "value": "306" + }, + { + "begin": 7606, + "end": 7637, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 7578, + "end": 7644, + "name": "SWAP10", + "source": 13 + }, + { + "begin": 7578, + "end": 7644, + "name": "POP", + "source": 13 + }, + { + "begin": 7657, + "end": 7665, + "name": "POP", + "source": 13 + }, + { + "begin": 7657, + "end": 7665, + "name": "POP", + "source": 13 + }, + { + "begin": 7657, + "end": 7665, + "name": "POP", + "source": 13 + }, + { + "begin": 7657, + "end": 7665, + "name": "POP", + "source": 13 + }, + { + "begin": 7657, + "end": 7665, + "name": "POP", + "source": 13 + }, + { + "begin": 7657, + "end": 7665, + "name": "POP", + "source": 13 + }, + { + "begin": 7657, + "end": 7665, + "name": "POP", + "source": 13 + }, + { + "begin": 7657, + "end": 7665, + "name": "POP", + "source": 13 + }, + { + "begin": 7657, + "end": 7665, + "name": "PUSH [tag]", + "source": 13, + "value": "248" + }, + { + "begin": 7657, + "end": 7665, + "name": "JUMP", + "source": 13 + }, + { + "begin": 6697, + "end": 7676, + "name": "tag", + "source": 13, + "value": "294" + }, + { + "begin": 6697, + "end": 7676, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 758, + "end": 759, + "name": "PUSH", + "source": 13, + "value": "5" + }, + { + "begin": 7690, + "end": 7694, + "name": "DUP2", + "source": 13 + }, + { + "begin": 7690, + "end": 7712, + "name": "SUB", + "source": 13 + }, + { + "begin": 7686, + "end": 8171, + "name": "PUSH [tag]", + "source": 13, + "value": "307" + }, + { + "begin": 7686, + "end": 8171, + "name": "JUMPI", + "source": 13 + }, + { + "begin": 4550, + "end": 4552, + "name": "PUSH", + "source": 19, + "value": "20" + }, + { + "begin": 4536, + "end": 4553, + "name": "DUP3", + "source": 19 + }, + { + "begin": 4536, + "end": 4553, + "name": "ADD", + "source": 19 + }, + { + "begin": 4536, + "end": 4553, + "name": "SWAP2", + "source": 19 + }, + { + "begin": 4487, + "end": 4514, + "name": "DUP7", + "source": 19 + }, + { + "begin": 4487, + "end": 4514, + "name": "ADD", + "source": 19 + }, + { + "begin": 4474, + "end": 4515, + "name": "CALLDATALOAD", + "source": 19 + }, + { + "begin": 7920, + "end": 7943, + "name": "DUP8", + "source": 13 + }, + { + "begin": 7920, + "end": 7943, + "name": "DUP2", + "source": 13 + }, + { + "begin": 7920, + "end": 7943, + "name": "SUB", + "source": 13 + }, + { + "begin": 7916, + "end": 7998, + "name": "PUSH [tag]", + "source": 13, + "value": "309" + }, + { + "begin": 7916, + "end": 7998, + "name": "JUMPI", + "source": 13 + }, + { + "begin": 7968, + "end": 7985, + "name": "PUSH", + "source": 13, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { + "begin": 7959, + "end": 7985, + "name": "SWAP5", + "source": 13 + }, + { + "begin": 7959, + "end": 7985, + "name": "POP", + "source": 13 + }, + { + "begin": 7916, + "end": 7998, + "name": "tag", + "source": 13, + "value": "309" + }, + { + "begin": 7916, + "end": 7998, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 8010, + "end": 8022, + "name": "PUSH", + "source": 13, + "value": "0" + }, + { + "begin": 8025, + "end": 8062, + "name": "PUSH [tag]", + "source": 13, + "value": "310" + }, + { + "begin": 8052, + "end": 8061, + "name": "DUP3", + "source": 13 + }, + { + "begin": 8025, + "end": 8051, + "name": "PUSH [tag]", + "source": 13, + "value": "311" + }, + { + "begin": 8025, + "end": 8062, + "jumpType": "[in]", + "name": "JUMP", + "source": 13 + }, + { + "begin": 8025, + "end": 8062, + "name": "tag", + "source": 13, + "value": "310" + }, + { + "begin": 8025, + "end": 8062, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 8010, + "end": 8062, + "name": "SWAP1", + "source": 13 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 8081, + "end": 8085, + "name": "DUP5", + "source": 13 + }, + { + "begin": 8081, + "end": 8140, + "name": "PUSH [tag]", + "source": 13, + "value": "312" + }, + { + "begin": 8081, + "end": 8140, + "name": "JUMPI", + "source": 13 + }, + { + "begin": 8136, + "end": 8140, + "name": "DUP1", + "source": 13 + }, + { + "begin": 8081, + "end": 8140, + "name": "PUSH [tag]", + "source": 13, + "value": "314" + }, + { + "begin": 8081, + "end": 8140, + "name": "JUMP", + "source": 13 + }, + { + "begin": 8081, + "end": 8140, + "name": "tag", + "source": 13, + "value": "312" + }, + { + "begin": 8081, + "end": 8140, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 622, + "end": 631, + "name": "PUSH", + "source": 20, + "value": "0" + }, + { + "begin": 656, + "end": 669, + "name": "DUP6", + "source": 20 + }, + { + "begin": 656, + "end": 669, + "name": "DUP2", + "source": 20 + }, + { + "begin": 656, + "end": 669, + "name": "MSTORE", + "source": 20 + }, + { + "begin": 683, + "end": 685, + "name": "PUSH", + "source": 20, + "value": "20" + }, + { + "begin": 676, + "end": 690, + "name": "DUP3", + "source": 20 + }, + { + "begin": 676, + "end": 690, + "name": "SWAP1", + "source": 20 + }, + { + "begin": 676, + "end": 690, + "name": "MSTORE", + "source": 20 + }, + { + "begin": 715, + "end": 717, + "name": "PUSH", + "source": 20, + "value": "40" + }, + { + "begin": 702, + "end": 718, + "name": "SWAP1", + "source": 20 + }, + { + "begin": 702, + "end": 718, + "name": "KECCAK256", + "source": 20 + }, + { + "begin": 8102, + "end": 8133, + "name": "tag", + "source": 13, + "value": "314" + }, + { + "begin": 8102, + "end": 8133, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 8074, + "end": 8140, + "name": "SWAP5", + "source": 13 + }, + { + "begin": 8074, + "end": 8140, + "name": "POP", + "source": 13 + }, + { + "begin": 8152, + "end": 8160, + "name": "POP", + "source": 13 + }, + { + "begin": 8152, + "end": 8160, + "name": "POP", + "source": 13 + }, + { + "begin": 8152, + "end": 8160, + "name": "POP", + "source": 13 + }, + { + "begin": 8152, + "end": 8160, + "name": "PUSH [tag]", + "source": 13, + "value": "248" + }, + { + "begin": 8152, + "end": 8160, + "name": "JUMP", + "source": 13 + }, + { + "begin": 7686, + "end": 8171, + "name": "tag", + "source": 13, + "value": "307" + }, + { + "begin": 7686, + "end": 8171, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 8188, + "end": 8214, + "name": "PUSH", + "source": 13, + "value": "40" + }, + { + "begin": 8188, + "end": 8214, + "name": "MLOAD", + "source": 13 + }, + { + "begin": 8188, + "end": 8214, + "name": "PUSH", + "source": 13, + "value": "B2505F7C00000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 8188, + "end": 8214, + "name": "DUP2", + "source": 13 + }, + { + "begin": 8188, + "end": 8214, + "name": "MSTORE", + "source": 13 + }, + { + "begin": 8188, + "end": 8214, + "name": "PUSH", + "source": 13, + "value": "4" + }, + { + "begin": 8188, + "end": 8214, + "name": "DUP2", + "source": 13 + }, + { + "begin": 8188, + "end": 8214, + "name": "ADD", + "source": 13 + }, + { + "begin": 2778, + "end": 2803, + "name": "DUP3", + "source": 22 + }, + { + "begin": 2778, + "end": 2803, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 2778, + "end": 2803, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 2751, + "end": 2769, + "name": "PUSH", + "source": 22, + "value": "24" + }, + { + "begin": 2751, + "end": 2769, + "name": "ADD", + "source": 22 + }, + { + "begin": 8188, + "end": 8214, + "name": "PUSH [tag]", + "source": 13, + "value": "93" + }, + { + "begin": 2632, + "end": 2809, + "name": "JUMP", + "source": 22 + }, + { + "begin": 3765, + "end": 8223, + "name": "tag", + "source": 13, + "value": "249" + }, + { + "begin": 3765, + "end": 8223, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 3678, + "end": 8229, + "name": "POP", + "source": 13 + }, + { + "begin": 3525, + "end": 8233, + "name": "SWAP4", + "source": 13 + }, + { + "begin": 3525, + "end": 8233, + "name": "POP", + "source": 13 + }, + { + "begin": 3525, + "end": 8233, + "name": "SWAP4", + "source": 13 + }, + { + "begin": 3525, + "end": 8233, + "name": "SWAP2", + "source": 13 + }, + { + "begin": 3525, + "end": 8233, + "name": "POP", + "source": 13 + }, + { + "begin": 3525, + "end": 8233, + "name": "POP", + "source": 13 + }, + { + "begin": 3525, + "end": 8233, + "jumpType": "[out]", + "name": "JUMP", + "source": 13 + }, + { + "begin": 1296, + "end": 1456, + "name": "tag", + "source": 14, + "value": "224" + }, + { + "begin": 1296, + "end": 1456, + "name": "JUMPDEST", + "source": 14 + }, + { + "begin": 862, + "end": 906, + "name": "PUSH", + "source": 14, + "value": "8713A7C4465F6FBEE2B6E9D6646D1D9F83FEC929EDFC4BAF661F3C865BDD04D1" + }, + { + "begin": 1372, + "end": 1379, + "name": "PUSH", + "source": 14, + "value": "0" + }, + { + "begin": 656, + "end": 669, + "name": "SWAP1", + "source": 20 + }, + { + "begin": 656, + "end": 669, + "name": "DUP2", + "source": 20 + }, + { + "begin": 656, + "end": 669, + "name": "MSTORE", + "source": 20 + }, + { + "begin": 683, + "end": 685, + "name": "PUSH", + "source": 20, + "value": "20" + }, + { + "begin": 676, + "end": 690, + "name": "DUP3", + "source": 20 + }, + { + "begin": 676, + "end": 690, + "name": "SWAP1", + "source": 20 + }, + { + "begin": 676, + "end": 690, + "name": "MSTORE", + "source": 20 + }, + { + "begin": 715, + "end": 717, + "name": "PUSH", + "source": 20, + "value": "40" + }, + { + "begin": 702, + "end": 718, + "name": "DUP2", + "source": 20 + }, + { + "begin": 702, + "end": 718, + "name": "KECCAK256", + "source": 20 + }, + { + "begin": 1394, + "end": 1451, + "name": "PUSH [tag]", + "source": 14, + "value": "80" + }, + { + "begin": 543, + "end": 728, + "name": "JUMP", + "source": 20 + }, + { + "begin": 6015, + "end": 6315, + "name": "tag", + "source": 2, + "value": "238" + }, + { + "begin": 6015, + "end": 6315, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": 6101, + "end": 6105, + "name": "PUSH", + "source": 2, + "value": "0" + }, + { + "begin": 6124, + "end": 6169, + "name": "PUSH", + "source": 2, + "value": "FFFFFFFF00000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 6124, + "end": 6169, + "name": "DUP3", + "source": 2 + }, + { + "begin": 6124, + "end": 6169, + "name": "AND", + "source": 2 + }, + { + "begin": 6140, + "end": 6169, + "name": "PUSH", + "source": 2, + "value": "AC6A444E00000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 6124, + "end": 6169, + "name": "EQ", + "source": 2 + }, + { + "begin": 6124, + "end": 6169, + "name": "DUP1", + "source": 2 + }, + { + "begin": 6124, + "end": 6227, + "name": "PUSH [tag]", + "source": 2, + "value": "323" + }, + { + "begin": 6124, + "end": 6227, + "name": "JUMPI", + "source": 2 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 6179, + "end": 6227, + "name": "PUSH", + "source": 2, + "value": "FFFFFFFF00000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 6179, + "end": 6227, + "name": "DUP3", + "source": 2 + }, + { + "begin": 6179, + "end": 6227, + "name": "AND", + "source": 2 + }, + { + "begin": 6195, + "end": 6227, + "name": "PUSH", + "source": 2, + "value": "36E7817500000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 6179, + "end": 6227, + "name": "EQ", + "source": 2 + }, + { + "begin": 6124, + "end": 6227, + "name": "tag", + "source": 2, + "value": "323" + }, + { + "begin": 6124, + "end": 6227, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": 6113, + "end": 6260, + "name": "ISZERO", + "source": 2 + }, + { + "begin": 6113, + "end": 6260, + "name": "PUSH [tag]", + "source": 2, + "value": "324" + }, + { + "begin": 6113, + "end": 6260, + "name": "JUMPI", + "source": 2 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 6249, + "end": 6253, + "name": "PUSH", + "source": 2, + "value": "1" + }, + { + "begin": 6249, + "end": 6253, + "name": "SWAP2", + "source": 2 + }, + { + "begin": 6015, + "end": 6315, + "name": "SWAP1", + "source": 2 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 6015, + "end": 6315, + "jumpType": "[out]", + "name": "JUMP", + "source": 2 + }, + { + "begin": 6113, + "end": 6260, + "name": "tag", + "source": 2, + "value": "324" + }, + { + "begin": 6113, + "end": 6260, + "name": "JUMPDEST", + "source": 2 + }, + { + "begin": 725, + "end": 756, + "name": "PUSH", + "source": 5, + "value": "1FFC9A700000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 709, + "end": 756, + "name": "PUSH", + "source": 5, + "value": "FFFFFFFF00000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 709, + "end": 756, + "name": "DUP4", + "source": 5 + }, + { + "begin": 709, + "end": 756, + "name": "AND", + "source": 5 + }, + { + "begin": 709, + "end": 756, + "name": "EQ", + "source": 5 + }, + { + "begin": 6273, + "end": 6310, + "name": "PUSH [tag]", + "source": 2, + "value": "80" + }, + { + "begin": 613, + "end": 761, + "name": "JUMP", + "source": 5 + }, + { + "begin": 1767, + "end": 4083, + "name": "tag", + "source": 21, + "value": "264" + }, + { + "begin": 1767, + "end": 4083, + "name": "JUMPDEST", + "source": 21 + }, + { + "begin": 1867, + "end": 1881, + "name": "PUSH", + "source": 21, + "value": "0" + }, + { + "begin": 1914, + "end": 1916, + "name": "PUSH", + "source": 21, + "value": "42" + }, + { + "begin": 1893, + "end": 1916, + "name": "DUP3", + "source": 21 + }, + { + "begin": 1893, + "end": 1916, + "name": "EQ", + "source": 21 + }, + { + "begin": 1889, + "end": 1959, + "name": "PUSH [tag]", + "source": 21, + "value": "331" + }, + { + "begin": 1889, + "end": 1959, + "name": "JUMPI", + "source": 21 + }, + { + "begin": 1948, + "end": 1958, + "name": "DUP3", + "source": 21 + }, + { + "begin": 1948, + "end": 1958, + "name": "DUP3", + "source": 21 + }, + { + "begin": 1925, + "end": 1959, + "name": "PUSH", + "source": 21, + "value": "40" + }, + { + "begin": 1925, + "end": 1959, + "name": "MLOAD", + "source": 21 + }, + { + "begin": 1925, + "end": 1959, + "name": "PUSH", + "source": 21, + "value": "2EE17A3D00000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 1925, + "end": 1959, + "name": "DUP2", + "source": 21 + }, + { + "begin": 1925, + "end": 1959, + "name": "MSTORE", + "source": 21 + }, + { + "begin": 1925, + "end": 1959, + "name": "PUSH", + "source": 21, + "value": "4" + }, + { + "begin": 1925, + "end": 1959, + "name": "ADD", + "source": 21 + }, + { + "begin": 1925, + "end": 1959, + "name": "PUSH [tag]", + "source": 21, + "value": "93" + }, + { + "begin": 1925, + "end": 1959, + "name": "SWAP3", + "source": 21 + }, + { + "begin": 1925, + "end": 1959, + "name": "SWAP2", + "source": 21 + }, + { + "begin": 1925, + "end": 1959, + "name": "SWAP1", + "source": 21 + }, + { + "begin": 1925, + "end": 1959, + "name": "PUSH [tag]", + "source": 21, + "value": "333" + }, + { + "begin": 1925, + "end": 1959, + "jumpType": "[in]", + "name": "JUMP", + "source": 21 + }, + { + "begin": 1889, + "end": 1959, + "name": "tag", + "source": 21, + "value": "331" + }, + { + "begin": 1889, + "end": 1959, + "name": "JUMPDEST", + "source": 21 + }, + { + "begin": 1965, + "end": 1986, + "name": "PUSH", + "source": 21, + "value": "0" + }, + { + "begin": 1989, + "end": 2032, + "name": "PUSH [tag]", + "source": 21, + "value": "334" + }, + { + "begin": 2010, + "end": 2031, + "name": "PUSH [tag]", + "source": 21, + "value": "335" + }, + { + "begin": 2030, + "end": 2031, + "name": "PUSH", + "source": 21, + "value": "1" + }, + { + "begin": 2010, + "end": 2020, + "name": "DUP6", + "source": 21 + }, + { + "begin": 2010, + "end": 2031, + "name": "PUSH [tag]", + "source": 21, + "value": "336" + }, + { + "begin": 2010, + "end": 2031, + "jumpType": "[in]", + "name": "JUMP", + "source": 21 + }, + { + "begin": 2010, + "end": 2031, + "name": "tag", + "source": 21, + "value": "335" + }, + { + "begin": 2010, + "end": 2031, + "name": "JUMPDEST", + "source": 21 + }, + { + "begin": 1226, + "end": 1249, + "name": "DUP6", + "source": 18 + }, + { + "begin": 1226, + "end": 1249, + "name": "ADD", + "source": 18 + }, + { + "begin": 1213, + "end": 1250, + "name": "CALLDATALOAD", + "source": 18 + }, + { + "begin": 1266, + "end": 1269, + "name": "PUSH", + "source": 18, + "value": "F8" + }, + { + "begin": 1262, + "end": 1276, + "name": "SHR", + "source": 18 + }, + { + "begin": 1262, + "end": 1276, + "name": "SWAP1", + "source": 18 + }, + { + "begin": 1071, + "end": 1286, + "name": "JUMP", + "source": 18 + }, + { + "begin": 1989, + "end": 2032, + "name": "tag", + "source": 21, + "value": "334" + }, + { + "begin": 1989, + "end": 2032, + "name": "JUMPDEST", + "source": 21 + }, + { + "begin": 1965, + "end": 2032, + "name": "PUSH", + "source": 21, + "value": "FF" + }, + { + "begin": 1965, + "end": 2032, + "name": "AND", + "source": 21 + }, + { + "begin": 1965, + "end": 2032, + "name": "SWAP1", + "source": 21 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 2115, + "end": 2117, + "name": "PUSH", + "source": 21, + "value": "40" + }, + { + "begin": 1226, + "end": 1249, + "name": "DUP5", + "source": 18 + }, + { + "begin": 1226, + "end": 1249, + "name": "ADD", + "source": 18 + }, + { + "begin": 1213, + "end": 1250, + "name": "CALLDATALOAD", + "source": 18 + }, + { + "begin": 1266, + "end": 1269, + "name": "PUSH", + "source": 18, + "value": "F8" + }, + { + "begin": 1262, + "end": 1276, + "name": "SHR", + "source": 18 + }, + { + "begin": 795, + "end": 832, + "name": "DUP5", + "source": 18 + }, + { + "begin": 795, + "end": 832, + "name": "CALLDATALOAD", + "source": 18 + }, + { + "begin": 2202, + "end": 2204, + "name": "PUSH", + "source": 21, + "value": "20" + }, + { + "begin": 808, + "end": 831, + "name": "DUP7", + "source": 18 + }, + { + "begin": 808, + "end": 831, + "name": "ADD", + "source": 18 + }, + { + "begin": 795, + "end": 832, + "name": "CALLDATALOAD", + "source": 18 + }, + { + "begin": 3209, + "end": 3275, + "name": "PUSH", + "source": 21, + "value": "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0" + }, + { + "begin": 3196, + "end": 3275, + "name": "DUP2", + "source": 21 + }, + { + "begin": 3196, + "end": 3275, + "name": "GT", + "source": 21 + }, + { + "begin": 3192, + "end": 3327, + "name": "ISZERO", + "source": 21 + }, + { + "begin": 3192, + "end": 3327, + "name": "PUSH [tag]", + "source": 21, + "value": "342" + }, + { + "begin": 3192, + "end": 3327, + "name": "JUMPI", + "source": 21 + }, + { + "begin": 3306, + "end": 3316, + "name": "DUP7", + "source": 21 + }, + { + "begin": 3306, + "end": 3316, + "name": "DUP7", + "source": 21 + }, + { + "begin": 3318, + "end": 3319, + "name": "DUP3", + "source": 21 + }, + { + "begin": 3292, + "end": 3320, + "name": "PUSH", + "source": 21, + "value": "40" + }, + { + "begin": 3292, + "end": 3320, + "name": "MLOAD", + "source": 21 + }, + { + "begin": 3292, + "end": 3320, + "name": "PUSH", + "source": 21, + "value": "AD4AAC7600000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 3292, + "end": 3320, + "name": "DUP2", + "source": 21 + }, + { + "begin": 3292, + "end": 3320, + "name": "MSTORE", + "source": 21 + }, + { + "begin": 3292, + "end": 3320, + "name": "PUSH", + "source": 21, + "value": "4" + }, + { + "begin": 3292, + "end": 3320, + "name": "ADD", + "source": 21 + }, + { + "begin": 3292, + "end": 3320, + "name": "PUSH [tag]", + "source": 21, + "value": "93" + }, + { + "begin": 3292, + "end": 3320, + "name": "SWAP4", + "source": 21 + }, + { + "begin": 3292, + "end": 3320, + "name": "SWAP3", + "source": 21 + }, + { + "begin": 3292, + "end": 3320, + "name": "SWAP2", + "source": 21 + }, + { + "begin": 3292, + "end": 3320, + "name": "SWAP1", + "source": 21 + }, + { + "begin": 3292, + "end": 3320, + "name": "PUSH [tag]", + "source": 21, + "value": "344" + }, + { + "begin": 3292, + "end": 3320, + "jumpType": "[in]", + "name": "JUMP", + "source": 21 + }, + { + "begin": 3192, + "end": 3327, + "name": "tag", + "source": 21, + "value": "342" + }, + { + "begin": 3192, + "end": 3327, + "name": "JUMPDEST", + "source": 21 + }, + { + "begin": 3337, + "end": 3338, + "name": "DUP3", + "source": 21 + }, + { + "begin": 3337, + "end": 3344, + "name": "PUSH", + "source": 21, + "value": "FF" + }, + { + "begin": 3337, + "end": 3344, + "name": "AND", + "source": 21 + }, + { + "begin": 3342, + "end": 3344, + "name": "PUSH", + "source": 21, + "value": "1B" + }, + { + "begin": 3337, + "end": 3344, + "name": "EQ", + "source": 21 + }, + { + "begin": 3337, + "end": 3344, + "name": "ISZERO", + "source": 21 + }, + { + "begin": 3337, + "end": 3355, + "name": "DUP1", + "source": 21 + }, + { + "begin": 3337, + "end": 3355, + "name": "ISZERO", + "source": 21 + }, + { + "begin": 3337, + "end": 3355, + "name": "PUSH [tag]", + "source": 21, + "value": "345" + }, + { + "begin": 3337, + "end": 3355, + "name": "JUMPI", + "source": 21 + }, + { + "begin": 3337, + "end": 3355, + "name": "POP", + "source": 21 + }, + { + "begin": 3348, + "end": 3349, + "name": "DUP3", + "source": 21 + }, + { + "begin": 3348, + "end": 3355, + "name": "PUSH", + "source": 21, + "value": "FF" + }, + { + "begin": 3348, + "end": 3355, + "name": "AND", + "source": 21 + }, + { + "begin": 3353, + "end": 3355, + "name": "PUSH", + "source": 21, + "value": "1C" + }, + { + "begin": 3348, + "end": 3355, + "name": "EQ", + "source": 21 + }, + { + "begin": 3348, + "end": 3355, + "name": "ISZERO", + "source": 21 + }, + { + "begin": 3337, + "end": 3355, + "name": "tag", + "source": 21, + "value": "345" + }, + { + "begin": 3337, + "end": 3355, + "name": "JUMPDEST", + "source": 21 + }, + { + "begin": 3333, + "end": 3407, + "name": "ISZERO", + "source": 21 + }, + { + "begin": 3333, + "end": 3407, + "name": "PUSH [tag]", + "source": 21, + "value": "346" + }, + { + "begin": 3333, + "end": 3407, + "name": "JUMPI", + "source": 21 + }, + { + "begin": 3386, + "end": 3396, + "name": "DUP7", + "source": 21 + }, + { + "begin": 3386, + "end": 3396, + "name": "DUP7", + "source": 21 + }, + { + "begin": 3398, + "end": 3399, + "name": "DUP5", + "source": 21 + }, + { + "begin": 3372, + "end": 3400, + "name": "PUSH", + "source": 21, + "value": "40" + }, + { + "begin": 3372, + "end": 3400, + "name": "MLOAD", + "source": 21 + }, + { + "begin": 3372, + "end": 3400, + "name": "PUSH", + "source": 21, + "value": "E578897E00000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 3372, + "end": 3400, + "name": "DUP2", + "source": 21 + }, + { + "begin": 3372, + "end": 3400, + "name": "MSTORE", + "source": 21 + }, + { + "begin": 3372, + "end": 3400, + "name": "PUSH", + "source": 21, + "value": "4" + }, + { + "begin": 3372, + "end": 3400, + "name": "ADD", + "source": 21 + }, + { + "begin": 3372, + "end": 3400, + "name": "PUSH [tag]", + "source": 21, + "value": "93" + }, + { + "begin": 3372, + "end": 3400, + "name": "SWAP4", + "source": 21 + }, + { + "begin": 3372, + "end": 3400, + "name": "SWAP3", + "source": 21 + }, + { + "begin": 3372, + "end": 3400, + "name": "SWAP2", + "source": 21 + }, + { + "begin": 3372, + "end": 3400, + "name": "SWAP1", + "source": 21 + }, + { + "begin": 3372, + "end": 3400, + "name": "PUSH [tag]", + "source": 21, + "value": "348" + }, + { + "begin": 3372, + "end": 3400, + "jumpType": "[in]", + "name": "JUMP", + "source": 21 + }, + { + "begin": 3333, + "end": 3407, + "name": "tag", + "source": 21, + "value": "346" + }, + { + "begin": 3333, + "end": 3407, + "name": "JUMPDEST", + "source": 21 + }, + { + "begin": 1253, + "end": 1254, + "name": "PUSH", + "source": 21, + "value": "1" + }, + { + "begin": 3447, + "end": 3460, + "name": "DUP5", + "source": 21 + }, + { + "begin": 3447, + "end": 3479, + "name": "SUB", + "source": 21 + }, + { + "begin": 3443, + "end": 3952, + "name": "PUSH [tag]", + "source": 21, + "value": "349" + }, + { + "begin": 3443, + "end": 3952, + "name": "JUMPI", + "source": 21 + }, + { + "begin": 3498, + "end": 3523, + "name": "PUSH", + "source": 21, + "value": "40" + }, + { + "begin": 3498, + "end": 3523, + "name": "DUP1", + "source": 21 + }, + { + "begin": 3498, + "end": 3523, + "name": "MLOAD", + "source": 21 + }, + { + "begin": 3498, + "end": 3523, + "name": "PUSH", + "source": 21, + "value": "0" + }, + { + "begin": 3498, + "end": 3523, + "name": "DUP2", + "source": 21 + }, + { + "begin": 3498, + "end": 3523, + "name": "MSTORE", + "source": 21 + }, + { + "begin": 3498, + "end": 3523, + "name": "PUSH", + "source": 21, + "value": "20" + }, + { + "begin": 3498, + "end": 3523, + "name": "DUP2", + "source": 21 + }, + { + "begin": 3498, + "end": 3523, + "name": "ADD", + "source": 21 + }, + { + "begin": 3498, + "end": 3523, + "name": "DUP1", + "source": 21 + }, + { + "begin": 3498, + "end": 3523, + "name": "DUP4", + "source": 21 + }, + { + "begin": 3498, + "end": 3523, + "name": "MSTORE", + "source": 21 + }, + { + "begin": 18522, + "end": 18547, + "name": "DUP11", + "source": 22 + }, + { + "begin": 18522, + "end": 18547, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 18522, + "end": 18547, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 18595, + "end": 18599, + "name": "PUSH", + "source": 22, + "value": "FF" + }, + { + "begin": 18583, + "end": 18600, + "name": "DUP6", + "source": 22 + }, + { + "begin": 18583, + "end": 18600, + "name": "AND", + "source": 22 + }, + { + "begin": 18563, + "end": 18581, + "name": "SWAP2", + "source": 22 + }, + { + "begin": 18563, + "end": 18581, + "name": "DUP2", + "source": 22 + }, + { + "begin": 18563, + "end": 18581, + "name": "ADD", + "source": 22 + }, + { + "begin": 18556, + "end": 18601, + "name": "SWAP2", + "source": 22 + }, + { + "begin": 18556, + "end": 18601, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 18556, + "end": 18601, + "name": "SWAP2", + "source": 22 + }, + { + "begin": 18556, + "end": 18601, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 18617, + "end": 18635, + "name": "PUSH", + "source": 22, + "value": "60" + }, + { + "begin": 18617, + "end": 18635, + "name": "DUP2", + "source": 22 + }, + { + "begin": 18617, + "end": 18635, + "name": "ADD", + "source": 22 + }, + { + "begin": 18610, + "end": 18644, + "name": "DUP4", + "source": 22 + }, + { + "begin": 18610, + "end": 18644, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 18610, + "end": 18644, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 18660, + "end": 18678, + "name": "PUSH", + "source": 22, + "value": "80" + }, + { + "begin": 18660, + "end": 18678, + "name": "DUP2", + "source": 22 + }, + { + "begin": 18660, + "end": 18678, + "name": "ADD", + "source": 22 + }, + { + "begin": 18653, + "end": 18687, + "name": "DUP3", + "source": 22 + }, + { + "begin": 18653, + "end": 18687, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 18653, + "end": 18687, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 3498, + "end": 3523, + "name": "PUSH", + "source": 21, + "value": "1" + }, + { + "begin": 3498, + "end": 3523, + "name": "SWAP1", + "source": 21 + }, + { + "begin": 18494, + "end": 18513, + "name": "PUSH", + "source": 22, + "value": "A0" + }, + { + "begin": 18494, + "end": 18513, + "name": "ADD", + "source": 22 + }, + { + "begin": 3498, + "end": 3523, + "name": "tag", + "source": 21, + "value": "350" + }, + { + "begin": 3498, + "end": 3523, + "name": "JUMPDEST", + "source": 21 + }, + { + "begin": 3498, + "end": 3523, + "name": "PUSH", + "source": 21, + "value": "20" + }, + { + "begin": 3498, + "end": 3523, + "name": "PUSH", + "source": 21, + "value": "40" + }, + { + "begin": 3498, + "end": 3523, + "name": "MLOAD", + "source": 21 + }, + { + "begin": 3498, + "end": 3523, + "name": "PUSH", + "source": 21, + "value": "20" + }, + { + "begin": 3498, + "end": 3523, + "name": "DUP2", + "source": 21 + }, + { + "begin": 3498, + "end": 3523, + "name": "SUB", + "source": 21 + }, + { + "begin": 3498, + "end": 3523, + "name": "SWAP1", + "source": 21 + }, + { + "begin": 3498, + "end": 3523, + "name": "DUP1", + "source": 21 + }, + { + "begin": 3498, + "end": 3523, + "name": "DUP5", + "source": 21 + }, + { + "begin": 3498, + "end": 3523, + "name": "SUB", + "source": 21 + }, + { + "begin": 3498, + "end": 3523, + "name": "SWAP1", + "source": 21 + }, + { + "begin": 3498, + "end": 3523, + "name": "DUP6", + "source": 21 + }, + { + "begin": 3498, + "end": 3523, + "name": "GAS", + "source": 21 + }, + { + "begin": 3498, + "end": 3523, + "name": "STATICCALL", + "source": 21 + }, + { + "begin": 3498, + "end": 3523, + "name": "ISZERO", + "source": 21 + }, + { + "begin": 3498, + "end": 3523, + "name": "DUP1", + "source": 21 + }, + { + "begin": 3498, + "end": 3523, + "name": "ISZERO", + "source": 21 + }, + { + "begin": 3498, + "end": 3523, + "name": "PUSH [tag]", + "source": 21, + "value": "353" + }, + { + "begin": 3498, + "end": 3523, + "name": "JUMPI", + "source": 21 + }, + { + "begin": 3498, + "end": 3523, + "name": "RETURNDATASIZE", + "source": 21 + }, + { + "begin": 3498, + "end": 3523, + "name": "PUSH", + "source": 21, + "value": "0" + }, + { + "begin": 3498, + "end": 3523, + "name": "DUP1", + "source": 21 + }, + { + "begin": 3498, + "end": 3523, + "name": "RETURNDATACOPY", + "source": 21 + }, + { + "begin": 3498, + "end": 3523, + "name": "RETURNDATASIZE", + "source": 21 + }, + { + "begin": 3498, + "end": 3523, + "name": "PUSH", + "source": 21, + "value": "0" + }, + { + "begin": 3498, + "end": 3523, + "name": "REVERT", + "source": 21 + }, + { + "begin": 3498, + "end": 3523, + "name": "tag", + "source": 21, + "value": "353" + }, + { + "begin": 3498, + "end": 3523, + "name": "JUMPDEST", + "source": 21 + }, + { + "begin": 3498, + "end": 3523, + "name": "POP", + "source": 21 + }, + { + "begin": 3498, + "end": 3523, + "name": "POP", + "source": 21 + }, + { + "begin": 3498, + "end": 3523, + "name": "POP", + "source": 21 + }, + { + "begin": 3498, + "end": 3523, + "name": "PUSH", + "source": 21, + "value": "20" + }, + { + "begin": 3498, + "end": 3523, + "name": "PUSH", + "source": 21, + "value": "40" + }, + { + "begin": 3498, + "end": 3523, + "name": "MLOAD", + "source": 21 + }, + { + "begin": 3498, + "end": 3523, + "name": "SUB", + "source": 21 + }, + { + "begin": 3498, + "end": 3523, + "name": "MLOAD", + "source": 21 + }, + { + "begin": 3489, + "end": 3523, + "name": "SWAP5", + "source": 21 + }, + { + "begin": 3489, + "end": 3523, + "name": "POP", + "source": 21 + }, + { + "begin": 3443, + "end": 3952, + "name": "PUSH [tag]", + "source": 21, + "value": "361" + }, + { + "begin": 3443, + "end": 3952, + "name": "JUMP", + "source": 21 + }, + { + "begin": 3443, + "end": 3952, + "name": "tag", + "source": 21, + "value": "349" + }, + { + "begin": 3443, + "end": 3952, + "name": "JUMPDEST", + "source": 21 + }, + { + "begin": 1303, + "end": 1304, + "name": "PUSH", + "source": 21, + "value": "2" + }, + { + "begin": 3608, + "end": 3621, + "name": "DUP5", + "source": 21 + }, + { + "begin": 3608, + "end": 3642, + "name": "SUB", + "source": 21 + }, + { + "begin": 3604, + "end": 3952, + "name": "PUSH [tag]", + "source": 21, + "value": "355" + }, + { + "begin": 3604, + "end": 3952, + "name": "JUMPI", + "source": 21 + }, + { + "begin": 3690, + "end": 3749, + "name": "PUSH", + "source": 21, + "value": "40" + }, + { + "begin": 3690, + "end": 3749, + "name": "MLOAD", + "source": 21 + }, + { + "begin": 18940, + "end": 19006, + "name": "PUSH", + "source": 22, + "value": "19457468657265756D205369676E6564204D6573736167653A0A333200000000" + }, + { + "begin": 3690, + "end": 3749, + "name": "PUSH", + "source": 21, + "value": "20" + }, + { + "begin": 3690, + "end": 3749, + "name": "DUP3", + "source": 21 + }, + { + "begin": 3690, + "end": 3749, + "name": "ADD", + "source": 21 + }, + { + "begin": 18928, + "end": 19007, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 19023, + "end": 19035, + "name": "PUSH", + "source": 22, + "value": "3C" + }, + { + "begin": 19023, + "end": 19035, + "name": "DUP2", + "source": 22 + }, + { + "begin": 19023, + "end": 19035, + "name": "ADD", + "source": 22 + }, + { + "begin": 19016, + "end": 19044, + "name": "DUP10", + "source": 22 + }, + { + "begin": 19016, + "end": 19044, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 19016, + "end": 19044, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 3661, + "end": 3791, + "name": "PUSH", + "source": 21, + "value": "1" + }, + { + "begin": 3661, + "end": 3791, + "name": "SWAP1", + "source": 21 + }, + { + "begin": 19060, + "end": 19072, + "name": "PUSH", + "source": 22, + "value": "5C" + }, + { + "begin": 19060, + "end": 19072, + "name": "ADD", + "source": 22 + }, + { + "begin": 3690, + "end": 3749, + "name": "PUSH", + "source": 21, + "value": "40" + }, + { + "begin": 3690, + "end": 3749, + "name": "DUP1", + "source": 21 + }, + { + "begin": 3690, + "end": 3749, + "name": "MLOAD", + "source": 21 + }, + { + "begin": 3690, + "end": 3749, + "name": "PUSH", + "source": 21, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0" + }, + { + "begin": 3690, + "end": 3749, + "name": "DUP2", + "source": 21 + }, + { + "begin": 3690, + "end": 3749, + "name": "DUP5", + "source": 21 + }, + { + "begin": 3690, + "end": 3749, + "name": "SUB", + "source": 21 + }, + { + "begin": 3690, + "end": 3749, + "name": "ADD", + "source": 21 + }, + { + "begin": 3690, + "end": 3749, + "name": "DUP2", + "source": 21 + }, + { + "begin": 3690, + "end": 3749, + "name": "MSTORE", + "source": 21 + }, + { + "begin": 3690, + "end": 3749, + "name": "DUP3", + "source": 21 + }, + { + "begin": 3690, + "end": 3749, + "name": "DUP3", + "source": 21 + }, + { + "begin": 3690, + "end": 3749, + "name": "MSTORE", + "source": 21 + }, + { + "begin": 3680, + "end": 3750, + "name": "DUP1", + "source": 21 + }, + { + "begin": 3680, + "end": 3750, + "name": "MLOAD", + "source": 21 + }, + { + "begin": 3690, + "end": 3749, + "name": "PUSH", + "source": 21, + "value": "20" + }, + { + "begin": 3680, + "end": 3750, + "name": "SWAP2", + "source": 21 + }, + { + "begin": 3680, + "end": 3750, + "name": "DUP3", + "source": 21 + }, + { + "begin": 3680, + "end": 3750, + "name": "ADD", + "source": 21 + }, + { + "begin": 3680, + "end": 3750, + "name": "KECCAK256", + "source": 21 + }, + { + "begin": 3661, + "end": 3791, + "name": "PUSH", + "source": 21, + "value": "0" + }, + { + "begin": 3661, + "end": 3791, + "name": "DUP5", + "source": 21 + }, + { + "begin": 3661, + "end": 3791, + "name": "MSTORE", + "source": 21 + }, + { + "begin": 3661, + "end": 3791, + "name": "SWAP1", + "source": 21 + }, + { + "begin": 3661, + "end": 3791, + "name": "DUP4", + "source": 21 + }, + { + "begin": 3661, + "end": 3791, + "name": "ADD", + "source": 21 + }, + { + "begin": 3661, + "end": 3791, + "name": "DUP1", + "source": 21 + }, + { + "begin": 3661, + "end": 3791, + "name": "DUP4", + "source": 21 + }, + { + "begin": 3661, + "end": 3791, + "name": "MSTORE", + "source": 21 + }, + { + "begin": 18522, + "end": 18547, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 18595, + "end": 18599, + "name": "PUSH", + "source": 22, + "value": "FF" + }, + { + "begin": 18583, + "end": 18600, + "name": "DUP7", + "source": 22 + }, + { + "begin": 18583, + "end": 18600, + "name": "AND", + "source": 22 + }, + { + "begin": 18563, + "end": 18581, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 18563, + "end": 18581, + "name": "DUP3", + "source": 22 + }, + { + "begin": 18563, + "end": 18581, + "name": "ADD", + "source": 22 + }, + { + "begin": 18556, + "end": 18601, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 18617, + "end": 18635, + "name": "PUSH", + "source": 22, + "value": "60" + }, + { + "begin": 18617, + "end": 18635, + "name": "DUP2", + "source": 22 + }, + { + "begin": 18617, + "end": 18635, + "name": "ADD", + "source": 22 + }, + { + "begin": 18610, + "end": 18644, + "name": "DUP5", + "source": 22 + }, + { + "begin": 18610, + "end": 18644, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 18610, + "end": 18644, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 18660, + "end": 18678, + "name": "PUSH", + "source": 22, + "value": "80" + }, + { + "begin": 18660, + "end": 18678, + "name": "DUP2", + "source": 22 + }, + { + "begin": 18660, + "end": 18678, + "name": "ADD", + "source": 22 + }, + { + "begin": 18653, + "end": 18687, + "name": "DUP4", + "source": 22 + }, + { + "begin": 18653, + "end": 18687, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 18653, + "end": 18687, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 18494, + "end": 18513, + "name": "PUSH", + "source": 22, + "value": "A0" + }, + { + "begin": 18494, + "end": 18513, + "name": "ADD", + "source": 22 + }, + { + "begin": 3661, + "end": 3791, + "name": "PUSH [tag]", + "source": 21, + "value": "350" + }, + { + "begin": 18295, + "end": 18693, + "name": "JUMP", + "source": 22 + }, + { + "begin": 3604, + "end": 3952, + "name": "tag", + "source": 21, + "value": "355" + }, + { + "begin": 3604, + "end": 3952, + "name": "JUMPDEST", + "source": 21 + }, + { + "begin": 3913, + "end": 3923, + "name": "DUP7", + "source": 21 + }, + { + "begin": 3913, + "end": 3923, + "name": "DUP7", + "source": 21 + }, + { + "begin": 3925, + "end": 3938, + "name": "DUP6", + "source": 21 + }, + { + "begin": 3940, + "end": 3944, + "name": "PUSH", + "source": 21, + "value": "1" + }, + { + "begin": 3888, + "end": 3945, + "name": "PUSH", + "source": 21, + "value": "40" + }, + { + "begin": 3888, + "end": 3945, + "name": "MLOAD", + "source": 21 + }, + { + "begin": 3888, + "end": 3945, + "name": "PUSH", + "source": 21, + "value": "9DFBA85200000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 3888, + "end": 3945, + "name": "DUP2", + "source": 21 + }, + { + "begin": 3888, + "end": 3945, + "name": "MSTORE", + "source": 21 + }, + { + "begin": 3888, + "end": 3945, + "name": "PUSH", + "source": 21, + "value": "4" + }, + { + "begin": 3888, + "end": 3945, + "name": "ADD", + "source": 21 + }, + { + "begin": 3888, + "end": 3945, + "name": "PUSH [tag]", + "source": 21, + "value": "93" + }, + { + "begin": 3888, + "end": 3945, + "name": "SWAP5", + "source": 21 + }, + { + "begin": 3888, + "end": 3945, + "name": "SWAP4", + "source": 21 + }, + { + "begin": 3888, + "end": 3945, + "name": "SWAP3", + "source": 21 + }, + { + "begin": 3888, + "end": 3945, + "name": "SWAP2", + "source": 21 + }, + { + "begin": 3888, + "end": 3945, + "name": "SWAP1", + "source": 21 + }, + { + "begin": 3888, + "end": 3945, + "name": "PUSH [tag]", + "source": 21, + "value": "363" + }, + { + "begin": 3888, + "end": 3945, + "jumpType": "[in]", + "name": "JUMP", + "source": 21 + }, + { + "begin": 3604, + "end": 3952, + "name": "tag", + "source": 21, + "value": "361" + }, + { + "begin": 3604, + "end": 3952, + "name": "JUMPDEST", + "source": 21 + }, + { + "begin": 3999, + "end": 4021, + "name": "PUSH", + "source": 21, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { + "begin": 3999, + "end": 4021, + "name": "DUP6", + "source": 21 + }, + { + "begin": 3999, + "end": 4021, + "name": "AND", + "source": 21 + }, + { + "begin": 3995, + "end": 4058, + "name": "PUSH [tag]", + "source": 21, + "value": "364" + }, + { + "begin": 3995, + "end": 4058, + "name": "JUMPI", + "source": 21 + }, + { + "begin": 4047, + "end": 4057, + "name": "DUP7", + "source": 21 + }, + { + "begin": 4047, + "end": 4057, + "name": "DUP7", + "source": 21 + }, + { + "begin": 4030, + "end": 4058, + "name": "PUSH", + "source": 21, + "value": "40" + }, + { + "begin": 4030, + "end": 4058, + "name": "MLOAD", + "source": 21 + }, + { + "begin": 4030, + "end": 4058, + "name": "PUSH", + "source": 21, + "value": "6C1719D200000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 4030, + "end": 4058, + "name": "DUP2", + "source": 21 + }, + { + "begin": 4030, + "end": 4058, + "name": "MSTORE", + "source": 21 + }, + { + "begin": 4030, + "end": 4058, + "name": "PUSH", + "source": 21, + "value": "4" + }, + { + "begin": 4030, + "end": 4058, + "name": "ADD", + "source": 21 + }, + { + "begin": 4030, + "end": 4058, + "name": "PUSH [tag]", + "source": 21, + "value": "93" + }, + { + "begin": 4030, + "end": 4058, + "name": "SWAP3", + "source": 21 + }, + { + "begin": 4030, + "end": 4058, + "name": "SWAP2", + "source": 21 + }, + { + "begin": 4030, + "end": 4058, + "name": "SWAP1", + "source": 21 + }, + { + "begin": 4030, + "end": 4058, + "name": "PUSH [tag]", + "source": 21, + "value": "333" + }, + { + "begin": 4030, + "end": 4058, + "jumpType": "[in]", + "name": "JUMP", + "source": 21 + }, + { + "begin": 3995, + "end": 4058, + "name": "tag", + "source": 21, + "value": "364" + }, + { + "begin": 3995, + "end": 4058, + "name": "JUMPDEST", + "source": 21 + }, + { + "begin": 4065, + "end": 4078, + "name": "POP", + "source": 21 + }, + { + "begin": 4065, + "end": 4078, + "name": "POP", + "source": 21 + }, + { + "begin": 4065, + "end": 4078, + "name": "POP", + "source": 21 + }, + { + "begin": 4065, + "end": 4078, + "name": "POP", + "source": 21 + }, + { + "begin": 1767, + "end": 4083, + "name": "SWAP4", + "source": 21 + }, + { + "begin": 1767, + "end": 4083, + "name": "SWAP3", + "source": 21 + }, + { + "begin": 1767, + "end": 4083, + "name": "POP", + "source": 21 + }, + { + "begin": 1767, + "end": 4083, + "name": "POP", + "source": 21 + }, + { + "begin": 1767, + "end": 4083, + "name": "POP", + "source": 21 + }, + { + "begin": 1767, + "end": 4083, + "jumpType": "[out]", + "name": "JUMP", + "source": 21 + }, + { + "begin": 4411, + "end": 5362, + "name": "tag", + "source": 21, + "value": "274" + }, + { + "begin": 4411, + "end": 5362, + "name": "JUMPDEST", + "source": 21 + }, + { + "begin": 4535, + "end": 4545, + "name": "PUSH", + "source": 21, + "value": "0" + }, + { + "begin": 4557, + "end": 4579, + "name": "DUP2", + "source": 21 + }, + { + "begin": 4557, + "end": 4579, + "name": "DUP2", + "source": 21 + }, + { + "begin": 4557, + "end": 4579, + "name": "SUB", + "source": 21 + }, + { + "begin": 4553, + "end": 4619, + "name": "PUSH [tag]", + "source": 21, + "value": "367" + }, + { + "begin": 4553, + "end": 4619, + "name": "JUMPI", + "source": 21 + }, + { + "begin": 4596, + "end": 4612, + "name": "PUSH", + "source": 21, + "value": "40" + }, + { + "begin": 4596, + "end": 4612, + "name": "MLOAD", + "source": 21 + }, + { + "begin": 4596, + "end": 4612, + "name": "PUSH", + "source": 21, + "value": "AC241E1100000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 4596, + "end": 4612, + "name": "DUP2", + "source": 21 + }, + { + "begin": 4596, + "end": 4612, + "name": "MSTORE", + "source": 21 + }, + { + "begin": 4596, + "end": 4612, + "name": "PUSH", + "source": 21, + "value": "4" + }, + { + "begin": 4596, + "end": 4612, + "name": "ADD", + "source": 21 + }, + { + "begin": 4596, + "end": 4612, + "name": "PUSH", + "source": 21, + "value": "40" + }, + { + "begin": 4596, + "end": 4612, + "name": "MLOAD", + "source": 21 + }, + { + "begin": 4596, + "end": 4612, + "name": "DUP1", + "source": 21 + }, + { + "begin": 4596, + "end": 4612, + "name": "SWAP2", + "source": 21 + }, + { + "begin": 4596, + "end": 4612, + "name": "SUB", + "source": 21 + }, + { + "begin": 4596, + "end": 4612, + "name": "SWAP1", + "source": 21 + }, + { + "begin": 4596, + "end": 4612, + "name": "REVERT", + "source": 21 + }, + { + "begin": 4553, + "end": 4619, + "name": "tag", + "source": 21, + "value": "367" + }, + { + "begin": 4553, + "end": 4619, + "name": "JUMPDEST", + "source": 21 + }, + { + "begin": 4625, + "end": 4646, + "name": "PUSH", + "source": 21, + "value": "0" + }, + { + "begin": 4655, + "end": 4665, + "name": "DUP4", + "source": 21 + }, + { + "begin": 4655, + "end": 4665, + "name": "DUP4", + "source": 21 + }, + { + "begin": 4666, + "end": 4687, + "name": "PUSH [tag]", + "source": 21, + "value": "368" + }, + { + "begin": 4686, + "end": 4687, + "name": "PUSH", + "source": 21, + "value": "1" + }, + { + "begin": 4655, + "end": 4665, + "name": "DUP3", + "source": 21 + }, + { + "begin": 4666, + "end": 4687, + "name": "PUSH [tag]", + "source": 21, + "value": "336" + }, + { + "begin": 4666, + "end": 4687, + "jumpType": "[in]", + "name": "JUMP", + "source": 21 + }, + { + "begin": 4666, + "end": 4687, + "name": "tag", + "source": 21, + "value": "368" + }, + { + "begin": 4666, + "end": 4687, + "name": "JUMPDEST", + "source": 21 + }, + { + "begin": 4655, + "end": 4688, + "name": "DUP2", + "source": 21 + }, + { + "begin": 4655, + "end": 4688, + "name": "DUP2", + "source": 21 + }, + { + "begin": 4655, + "end": 4688, + "name": "LT", + "source": 21 + }, + { + "begin": 4655, + "end": 4688, + "name": "PUSH [tag]", + "source": 21, + "value": "370" + }, + { + "begin": 4655, + "end": 4688, + "name": "JUMPI", + "source": 21 + }, + { + "begin": 4655, + "end": 4688, + "name": "PUSH [tag]", + "source": 21, + "value": "370" + }, + { + "begin": 4655, + "end": 4688, + "name": "PUSH [tag]", + "source": 21, + "value": "113" + }, + { + "begin": 4655, + "end": 4688, + "jumpType": "[in]", + "name": "JUMP", + "source": 21 + }, + { + "begin": 4655, + "end": 4688, + "name": "tag", + "source": 21, + "value": "370" + }, + { + "begin": 4655, + "end": 4688, + "name": "JUMPDEST", + "source": 21 + }, + { + "begin": 4655, + "end": 4688, + "name": "SWAP2", + "source": 21 + }, + { + "begin": 4655, + "end": 4688, + "name": "SWAP1", + "source": 21 + }, + { + "begin": 4655, + "end": 4688, + "name": "SWAP2", + "source": 21 + }, + { + "begin": 4655, + "end": 4688, + "name": "ADD", + "source": 21 + }, + { + "begin": 4655, + "end": 4688, + "name": "CALLDATALOAD", + "source": 21 + }, + { + "begin": 4655, + "end": 4688, + "name": "PUSH", + "source": 21, + "value": "F8" + }, + { + "begin": 4655, + "end": 4688, + "name": "SHR", + "source": 21 + }, + { + "begin": 4655, + "end": 4688, + "name": "SWAP2", + "source": 21 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 1253, + "end": 1254, + "name": "PUSH", + "source": 21, + "value": "1" + }, + { + "begin": 4699, + "end": 4731, + "name": "DUP2", + "source": 21 + }, + { + "begin": 4699, + "end": 4731, + "name": "EQ", + "source": 21 + }, + { + "begin": 4699, + "end": 4731, + "name": "DUP1", + "source": 21 + }, + { + "begin": 4699, + "end": 4769, + "name": "PUSH [tag]", + "source": 21, + "value": "371" + }, + { + "begin": 4699, + "end": 4769, + "name": "JUMPI", + "source": 21 + }, + { + "begin": 4699, + "end": 4769, + "name": "POP", + "source": 21 + }, + { + "begin": 1303, + "end": 1304, + "name": "PUSH", + "source": 21, + "value": "2" + }, + { + "begin": 4735, + "end": 4748, + "name": "DUP2", + "source": 21 + }, + { + "begin": 4735, + "end": 4769, + "name": "EQ", + "source": 21 + }, + { + "begin": 4699, + "end": 4769, + "name": "tag", + "source": 21, + "value": "371" + }, + { + "begin": 4699, + "end": 4769, + "name": "JUMPDEST", + "source": 21 + }, + { + "begin": 4695, + "end": 5358, + "name": "ISZERO", + "source": 21 + }, + { + "begin": 4695, + "end": 5358, + "name": "PUSH [tag]", + "source": 21, + "value": "372" + }, + { + "begin": 4695, + "end": 5358, + "name": "JUMPI", + "source": 21 + }, + { + "begin": 4873, + "end": 4880, + "name": "DUP5", + "source": 21 + }, + { + "begin": 4837, + "end": 4880, + "name": "PUSH", + "source": 21, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { + "begin": 4837, + "end": 4880, + "name": "AND", + "source": 21 + }, + { + "begin": 4837, + "end": 4869, + "name": "PUSH [tag]", + "source": 21, + "value": "373" + }, + { + "begin": 4851, + "end": 4856, + "name": "DUP8", + "source": 21 + }, + { + "begin": 4858, + "end": 4868, + "name": "DUP7", + "source": 21 + }, + { + "begin": 4858, + "end": 4868, + "name": "DUP7", + "source": 21 + }, + { + "begin": 4837, + "end": 4850, + "name": "PUSH [tag]", + "source": 21, + "value": "264" + }, + { + "begin": 4837, + "end": 4869, + "jumpType": "[in]", + "name": "JUMP", + "source": 21 + }, + { + "begin": 4837, + "end": 4869, + "name": "tag", + "source": 21, + "value": "373" + }, + { + "begin": 4837, + "end": 4869, + "name": "JUMPDEST", + "source": 21 + }, + { + "begin": 4837, + "end": 4880, + "name": "PUSH", + "source": 21, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { + "begin": 4837, + "end": 4880, + "name": "AND", + "source": 21 + }, + { + "begin": 4837, + "end": 4880, + "name": "EQ", + "source": 21 + }, + { + "begin": 4829, + "end": 4880, + "name": "SWAP2", + "source": 21 + }, + { + "begin": 4829, + "end": 4880, + "name": "POP", + "source": 21 + }, + { + "begin": 4695, + "end": 5358, + "name": "PUSH [tag]", + "source": 21, + "value": "384" + }, + { + "begin": 4695, + "end": 5358, + "name": "JUMP", + "source": 21 + }, + { + "begin": 4695, + "end": 5358, + "name": "tag", + "source": 21, + "value": "372" + }, + { + "begin": 4695, + "end": 5358, + "name": "JUMPDEST", + "source": 21 + }, + { + "begin": 1359, + "end": 1360, + "name": "PUSH", + "source": 21, + "value": "3" + }, + { + "begin": 4898, + "end": 4911, + "name": "DUP2", + "source": 21 + }, + { + "begin": 4898, + "end": 4938, + "name": "SUB", + "source": 21 + }, + { + "begin": 4894, + "end": 5358, + "name": "PUSH [tag]", + "source": 21, + "value": "375" + }, + { + "begin": 4894, + "end": 5358, + "name": "JUMPI", + "source": 21 + }, + { + "begin": 5060, + "end": 5100, + "name": "PUSH", + "source": 21, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { + "begin": 5060, + "end": 5100, + "name": "DUP6", + "source": 21 + }, + { + "begin": 5060, + "end": 5100, + "name": "AND", + "source": 21 + }, + { + "begin": 5060, + "end": 5100, + "name": "PUSH", + "source": 21, + "value": "1626BA7E" + }, + { + "begin": 5101, + "end": 5106, + "name": "DUP8", + "source": 21 + }, + { + "begin": 5108, + "end": 5118, + "name": "DUP7", + "source": 21 + }, + { + "begin": 5119, + "end": 5120, + "name": "PUSH", + "source": 21, + "value": "0" + }, + { + "begin": 5108, + "end": 5118, + "name": "DUP8", + "source": 21 + }, + { + "begin": 5121, + "end": 5142, + "name": "PUSH [tag]", + "source": 21, + "value": "376" + }, + { + "begin": 5141, + "end": 5142, + "name": "PUSH", + "source": 21, + "value": "1" + }, + { + "begin": 5108, + "end": 5118, + "name": "DUP3", + "source": 21 + }, + { + "begin": 5121, + "end": 5142, + "name": "PUSH [tag]", + "source": 21, + "value": "336" + }, + { + "begin": 5121, + "end": 5142, + "jumpType": "[in]", + "name": "JUMP", + "source": 21 + }, + { + "begin": 5121, + "end": 5142, + "name": "tag", + "source": 21, + "value": "376" + }, + { + "begin": 5121, + "end": 5142, + "name": "JUMPDEST", + "source": 21 + }, + { + "begin": 5108, + "end": 5143, + "name": "SWAP3", + "source": 21 + }, + { + "begin": 5108, + "end": 5143, + "name": "PUSH [tag]", + "source": 21, + "value": "377" + }, + { + "begin": 5108, + "end": 5143, + "name": "SWAP4", + "source": 21 + }, + { + "begin": 5108, + "end": 5143, + "name": "SWAP3", + "source": 21 + }, + { + "begin": 5108, + "end": 5143, + "name": "SWAP2", + "source": 21 + }, + { + "begin": 5108, + "end": 5143, + "name": "SWAP1", + "source": 21 + }, + { + "begin": 5108, + "end": 5143, + "name": "PUSH [tag]", + "source": 21, + "value": "193" + }, + { + "begin": 5108, + "end": 5143, + "jumpType": "[in]", + "name": "JUMP", + "source": 21 + }, + { + "begin": 5108, + "end": 5143, + "name": "tag", + "source": 21, + "value": "377" + }, + { + "begin": 5108, + "end": 5143, + "name": "JUMPDEST", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "PUSH", + "source": 21, + "value": "40" + }, + { + "begin": 5060, + "end": 5144, + "name": "MLOAD", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "DUP5", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "PUSH", + "source": 21, + "value": "FFFFFFFF" + }, + { + "begin": 5060, + "end": 5144, + "name": "AND", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "PUSH", + "source": 21, + "value": "E0" + }, + { + "begin": 5060, + "end": 5144, + "name": "SHL", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "DUP2", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "MSTORE", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "PUSH", + "source": 21, + "value": "4" + }, + { + "begin": 5060, + "end": 5144, + "name": "ADD", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "PUSH [tag]", + "source": 21, + "value": "378" + }, + { + "begin": 5060, + "end": 5144, + "name": "SWAP4", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "SWAP3", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "SWAP2", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "SWAP1", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "PUSH [tag]", + "source": 21, + "value": "379" + }, + { + "begin": 5060, + "end": 5144, + "jumpType": "[in]", + "name": "JUMP", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "tag", + "source": 21, + "value": "378" + }, + { + "begin": 5060, + "end": 5144, + "name": "JUMPDEST", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "PUSH", + "source": 21, + "value": "20" + }, + { + "begin": 5060, + "end": 5144, + "name": "PUSH", + "source": 21, + "value": "40" + }, + { + "begin": 5060, + "end": 5144, + "name": "MLOAD", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "DUP1", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "DUP4", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "SUB", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "DUP2", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "DUP7", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "GAS", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "STATICCALL", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "ISZERO", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "DUP1", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "ISZERO", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "PUSH [tag]", + "source": 21, + "value": "381" + }, + { + "begin": 5060, + "end": 5144, + "name": "JUMPI", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "RETURNDATASIZE", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "PUSH", + "source": 21, + "value": "0" + }, + { + "begin": 5060, + "end": 5144, + "name": "DUP1", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "RETURNDATACOPY", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "RETURNDATASIZE", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "PUSH", + "source": 21, + "value": "0" + }, + { + "begin": 5060, + "end": 5144, + "name": "REVERT", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "tag", + "source": 21, + "value": "381" + }, + { + "begin": 5060, + "end": 5144, + "name": "JUMPDEST", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "POP", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "POP", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "POP", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "POP", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "PUSH", + "source": 21, + "value": "40" + }, + { + "begin": 5060, + "end": 5144, + "name": "MLOAD", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "RETURNDATASIZE", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "PUSH", + "source": 21, + "value": "1F" + }, + { + "begin": 5060, + "end": 5144, + "name": "NOT", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "PUSH", + "source": 21, + "value": "1F" + }, + { + "begin": 5060, + "end": 5144, + "name": "DUP3", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "ADD", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "AND", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "DUP3", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "ADD", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "DUP1", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "PUSH", + "source": 21, + "value": "40" + }, + { + "begin": 5060, + "end": 5144, + "name": "MSTORE", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "POP", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "DUP2", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "ADD", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "SWAP1", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "PUSH [tag]", + "source": 21, + "value": "382" + }, + { + "begin": 5060, + "end": 5144, + "name": "SWAP2", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "SWAP1", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "PUSH [tag]", + "source": 21, + "value": "383" + }, + { + "begin": 5060, + "end": 5144, + "jumpType": "[in]", + "name": "JUMP", + "source": 21 + }, + { + "begin": 5060, + "end": 5144, + "name": "tag", + "source": 21, + "value": "382" + }, + { + "begin": 5060, + "end": 5144, + "name": "JUMPDEST", + "source": 21 + }, + { + "begin": 5030, + "end": 5144, + "name": "PUSH", + "source": 21, + "value": "FFFFFFFF00000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 5030, + "end": 5144, + "name": "AND", + "source": 21 + }, + { + "begin": 5030, + "end": 5056, + "name": "PUSH", + "source": 21, + "value": "1626BA7E00000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 5030, + "end": 5144, + "name": "EQ", + "source": 21 + }, + { + "begin": 5030, + "end": 5144, + "name": "SWAP2", + "source": 21 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 4894, + "end": 5358, + "name": "PUSH [tag]", + "source": 21, + "value": "384" + }, + { + "begin": 4894, + "end": 5358, + "name": "JUMP", + "source": 21 + }, + { + "begin": 4894, + "end": 5358, + "name": "tag", + "source": 21, + "value": "375" + }, + { + "begin": 4894, + "end": 5358, + "name": "JUMPDEST", + "source": 21 + }, + { + "begin": 5318, + "end": 5328, + "name": "DUP4", + "source": 21 + }, + { + "begin": 5318, + "end": 5328, + "name": "DUP4", + "source": 21 + }, + { + "begin": 5330, + "end": 5343, + "name": "DUP3", + "source": 21 + }, + { + "begin": 5345, + "end": 5350, + "name": "PUSH", + "source": 21, + "value": "0" + }, + { + "begin": 5293, + "end": 5351, + "name": "PUSH", + "source": 21, + "value": "40" + }, + { + "begin": 5293, + "end": 5351, + "name": "MLOAD", + "source": 21 + }, + { + "begin": 5293, + "end": 5351, + "name": "PUSH", + "source": 21, + "value": "9DFBA85200000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 5293, + "end": 5351, + "name": "DUP2", + "source": 21 + }, + { + "begin": 5293, + "end": 5351, + "name": "MSTORE", + "source": 21 + }, + { + "begin": 5293, + "end": 5351, + "name": "PUSH", + "source": 21, + "value": "4" + }, + { + "begin": 5293, + "end": 5351, + "name": "ADD", + "source": 21 + }, + { + "begin": 5293, + "end": 5351, + "name": "PUSH [tag]", + "source": 21, + "value": "93" + }, + { + "begin": 5293, + "end": 5351, + "name": "SWAP5", + "source": 21 + }, + { + "begin": 5293, + "end": 5351, + "name": "SWAP4", + "source": 21 + }, + { + "begin": 5293, + "end": 5351, + "name": "SWAP3", + "source": 21 + }, + { + "begin": 5293, + "end": 5351, + "name": "SWAP2", + "source": 21 + }, + { + "begin": 5293, + "end": 5351, + "name": "SWAP1", + "source": 21 + }, + { + "begin": 5293, + "end": 5351, + "name": "PUSH [tag]", + "source": 21, + "value": "363" + }, + { + "begin": 5293, + "end": 5351, + "jumpType": "[in]", + "name": "JUMP", + "source": 21 + }, + { + "begin": 4894, + "end": 5358, + "name": "tag", + "source": 21, + "value": "384" + }, + { + "begin": 4894, + "end": 5358, + "name": "JUMPDEST", + "source": 21 + }, + { + "begin": 4547, + "end": 5362, + "name": "POP", + "source": 21 + }, + { + "begin": 4411, + "end": 5362, + "name": "SWAP5", + "source": 21 + }, + { + "begin": 4411, + "end": 5362, + "name": "SWAP4", + "source": 21 + }, + { + "begin": 4411, + "end": 5362, + "name": "POP", + "source": 21 + }, + { + "begin": 4411, + "end": 5362, + "name": "POP", + "source": 21 + }, + { + "begin": 4411, + "end": 5362, + "name": "POP", + "source": 21 + }, + { + "begin": 4411, + "end": 5362, + "name": "POP", + "source": 21 + }, + { + "begin": 4411, + "end": 5362, + "jumpType": "[out]", + "name": "JUMP", + "source": 21 + }, + { + "begin": 2227, + "end": 2409, + "name": "tag", + "source": 13, + "value": "311" + }, + { + "begin": 2227, + "end": 2409, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 2346, + "end": 2403, + "name": "PUSH", + "source": 13, + "value": "40" + }, + { + "begin": 2346, + "end": 2403, + "name": "MLOAD", + "source": 13 + }, + { + "begin": 20822, + "end": 20888, + "name": "PUSH", + "source": 22, + "value": "53657175656E636520737461746963206469676573743A0A0000000000000000" + }, + { + "begin": 2346, + "end": 2403, + "name": "PUSH", + "source": 13, + "value": "20" + }, + { + "begin": 2346, + "end": 2403, + "name": "DUP3", + "source": 13 + }, + { + "begin": 2346, + "end": 2403, + "name": "ADD", + "source": 13 + }, + { + "begin": 20810, + "end": 20889, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 20905, + "end": 20917, + "name": "PUSH", + "source": 22, + "value": "38" + }, + { + "begin": 20905, + "end": 20917, + "name": "DUP2", + "source": 22 + }, + { + "begin": 20905, + "end": 20917, + "name": "ADD", + "source": 22 + }, + { + "begin": 20898, + "end": 20926, + "name": "DUP3", + "source": 22 + }, + { + "begin": 20898, + "end": 20926, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 20898, + "end": 20926, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 2314, + "end": 2321, + "name": "PUSH", + "source": 13, + "value": "0" + }, + { + "begin": 2314, + "end": 2321, + "name": "SWAP1", + "source": 13 + }, + { + "begin": 20942, + "end": 20954, + "name": "PUSH", + "source": 22, + "value": "58" + }, + { + "begin": 20942, + "end": 20954, + "name": "ADD", + "source": 22 + }, + { + "begin": 2346, + "end": 2403, + "name": "PUSH [tag]", + "source": 13, + "value": "155" + }, + { + "begin": 20580, + "end": 20960, + "name": "JUMP", + "source": 22 + }, + { + "begin": 14, + "end": 191, + "name": "tag", + "source": 22, + "value": "397" + }, + { + "begin": 14, + "end": 191, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 99, + "end": 165, + "name": "PUSH", + "source": 22, + "value": "FFFFFFFF00000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 92, + "end": 97, + "name": "DUP2", + "source": 22 + }, + { + "begin": 88, + "end": 166, + "name": "AND", + "source": 22 + }, + { + "begin": 81, + "end": 86, + "name": "DUP2", + "source": 22 + }, + { + "begin": 78, + "end": 167, + "name": "EQ", + "source": 22 + }, + { + "begin": 68, + "end": 185, + "name": "PUSH [tag]", + "source": 22, + "value": "96" + }, + { + "begin": 68, + "end": 185, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 181, + "end": 182, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 178, + "end": 179, + "name": "DUP1", + "source": 22 + }, + { + "begin": 171, + "end": 183, + "name": "REVERT", + "source": 22 + }, + { + "begin": 196, + "end": 441, + "name": "tag", + "source": 22, + "value": "19" + }, + { + "begin": 196, + "end": 441, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 254, + "end": 260, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 307, + "end": 309, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 295, + "end": 304, + "name": "DUP3", + "source": 22 + }, + { + "begin": 286, + "end": 293, + "name": "DUP5", + "source": 22 + }, + { + "begin": 282, + "end": 305, + "name": "SUB", + "source": 22 + }, + { + "begin": 278, + "end": 310, + "name": "SLT", + "source": 22 + }, + { + "begin": 275, + "end": 327, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 275, + "end": 327, + "name": "PUSH [tag]", + "source": 22, + "value": "411" + }, + { + "begin": 275, + "end": 327, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 323, + "end": 324, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 320, + "end": 321, + "name": "DUP1", + "source": 22 + }, + { + "begin": 313, + "end": 325, + "name": "REVERT", + "source": 22 + }, + { + "begin": 275, + "end": 327, + "name": "tag", + "source": 22, + "value": "411" + }, + { + "begin": 275, + "end": 327, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 362, + "end": 371, + "name": "DUP2", + "source": 22 + }, + { + "begin": 349, + "end": 372, + "name": "CALLDATALOAD", + "source": 22 + }, + { + "begin": 381, + "end": 411, + "name": "PUSH [tag]", + "source": 22, + "value": "82" + }, + { + "begin": 405, + "end": 410, + "name": "DUP2", + "source": 22 + }, + { + "begin": 381, + "end": 411, + "name": "PUSH [tag]", + "source": 22, + "value": "397" + }, + { + "begin": 381, + "end": 411, + "jumpType": "[in]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 638, + "end": 985, + "name": "tag", + "source": 22, + "value": "398" + }, + { + "begin": 638, + "end": 985, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 689, + "end": 697, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 699, + "end": 705, + "name": "DUP1", + "source": 22 + }, + { + "begin": 753, + "end": 756, + "name": "DUP4", + "source": 22 + }, + { + "begin": 746, + "end": 750, + "name": "PUSH", + "source": 22, + "value": "1F" + }, + { + "begin": 738, + "end": 744, + "name": "DUP5", + "source": 22 + }, + { + "begin": 734, + "end": 751, + "name": "ADD", + "source": 22 + }, + { + "begin": 730, + "end": 757, + "name": "SLT", + "source": 22 + }, + { + "begin": 720, + "end": 775, + "name": "PUSH [tag]", + "source": 22, + "value": "415" + }, + { + "begin": 720, + "end": 775, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 771, + "end": 772, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 768, + "end": 769, + "name": "DUP1", + "source": 22 + }, + { + "begin": 761, + "end": 773, + "name": "REVERT", + "source": 22 + }, + { + "begin": 720, + "end": 775, + "name": "tag", + "source": 22, + "value": "415" + }, + { + "begin": 720, + "end": 775, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 794, + "end": 814, + "name": "DUP2", + "source": 22 + }, + { + "begin": 794, + "end": 814, + "name": "CALLDATALOAD", + "source": 22 + }, + { + "begin": 837, + "end": 855, + "name": "PUSH", + "source": 22, + "value": "FFFFFFFFFFFFFFFF" + }, + { + "begin": 826, + "end": 856, + "name": "DUP2", + "source": 22 + }, + { + "begin": 826, + "end": 856, + "name": "GT", + "source": 22 + }, + { + "begin": 823, + "end": 873, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 823, + "end": 873, + "name": "PUSH [tag]", + "source": 22, + "value": "416" + }, + { + "begin": 823, + "end": 873, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 869, + "end": 870, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 866, + "end": 867, + "name": "DUP1", + "source": 22 + }, + { + "begin": 859, + "end": 871, + "name": "REVERT", + "source": 22 + }, + { + "begin": 823, + "end": 873, + "name": "tag", + "source": 22, + "value": "416" + }, + { + "begin": 823, + "end": 873, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 906, + "end": 910, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 898, + "end": 904, + "name": "DUP4", + "source": 22 + }, + { + "begin": 894, + "end": 911, + "name": "ADD", + "source": 22 + }, + { + "begin": 882, + "end": 911, + "name": "SWAP2", + "source": 22 + }, + { + "begin": 882, + "end": 911, + "name": "POP", + "source": 22 + }, + { + "begin": 958, + "end": 961, + "name": "DUP4", + "source": 22 + }, + { + "begin": 951, + "end": 955, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 942, + "end": 948, + "name": "DUP3", + "source": 22 + }, + { + "begin": 934, + "end": 940, + "name": "DUP6", + "source": 22 + }, + { + "begin": 930, + "end": 949, + "name": "ADD", + "source": 22 + }, + { + "begin": 926, + "end": 956, + "name": "ADD", + "source": 22 + }, + { + "begin": 923, + "end": 962, + "name": "GT", + "source": 22 + }, + { + "begin": 920, + "end": 979, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 920, + "end": 979, + "name": "PUSH [tag]", + "source": 22, + "value": "417" + }, + { + "begin": 920, + "end": 979, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 975, + "end": 976, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 972, + "end": 973, + "name": "DUP1", + "source": 22 + }, + { + "begin": 965, + "end": 977, + "name": "REVERT", + "source": 22 + }, + { + "begin": 920, + "end": 979, + "name": "tag", + "source": 22, + "value": "417" + }, + { + "begin": 920, + "end": 979, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 638, + "end": 985, + "name": "SWAP3", + "source": 22 + }, + { + "begin": 638, + "end": 985, + "name": "POP", + "source": 22 + }, + { + "begin": 638, + "end": 985, + "name": "SWAP3", + "source": 22 + }, + { + "begin": 638, + "end": 985, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 638, + "end": 985, + "name": "POP", + "source": 22 + }, + { + "begin": 638, + "end": 985, + "jumpType": "[out]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 990, + "end": 1467, + "name": "tag", + "source": 22, + "value": "26" + }, + { + "begin": 990, + "end": 1467, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 1069, + "end": 1075, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 1077, + "end": 1083, + "name": "DUP1", + "source": 22 + }, + { + "begin": 1085, + "end": 1091, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 1138, + "end": 1140, + "name": "PUSH", + "source": 22, + "value": "40" + }, + { + "begin": 1126, + "end": 1135, + "name": "DUP5", + "source": 22 + }, + { + "begin": 1117, + "end": 1124, + "name": "DUP7", + "source": 22 + }, + { + "begin": 1113, + "end": 1136, + "name": "SUB", + "source": 22 + }, + { + "begin": 1109, + "end": 1141, + "name": "SLT", + "source": 22 + }, + { + "begin": 1106, + "end": 1158, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 1106, + "end": 1158, + "name": "PUSH [tag]", + "source": 22, + "value": "419" + }, + { + "begin": 1106, + "end": 1158, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 1154, + "end": 1155, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 1151, + "end": 1152, + "name": "DUP1", + "source": 22 + }, + { + "begin": 1144, + "end": 1156, + "name": "REVERT", + "source": 22 + }, + { + "begin": 1106, + "end": 1158, + "name": "tag", + "source": 22, + "value": "419" + }, + { + "begin": 1106, + "end": 1158, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 1190, + "end": 1199, + "name": "DUP4", + "source": 22 + }, + { + "begin": 1177, + "end": 1200, + "name": "CALLDATALOAD", + "source": 22 + }, + { + "begin": 1167, + "end": 1200, + "name": "SWAP3", + "source": 22 + }, + { + "begin": 1167, + "end": 1200, + "name": "POP", + "source": 22 + }, + { + "begin": 1251, + "end": 1253, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 1240, + "end": 1249, + "name": "DUP5", + "source": 22 + }, + { + "begin": 1236, + "end": 1254, + "name": "ADD", + "source": 22 + }, + { + "begin": 1223, + "end": 1255, + "name": "CALLDATALOAD", + "source": 22 + }, + { + "begin": 1278, + "end": 1296, + "name": "PUSH", + "source": 22, + "value": "FFFFFFFFFFFFFFFF" + }, + { + "begin": 1270, + "end": 1276, + "name": "DUP2", + "source": 22 + }, + { + "begin": 1267, + "end": 1297, + "name": "GT", + "source": 22 + }, + { + "begin": 1264, + "end": 1314, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 1264, + "end": 1314, + "name": "PUSH [tag]", + "source": 22, + "value": "420" + }, + { + "begin": 1264, + "end": 1314, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 1310, + "end": 1311, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 1307, + "end": 1308, + "name": "DUP1", + "source": 22 + }, + { + "begin": 1300, + "end": 1312, + "name": "REVERT", + "source": 22 + }, + { + "begin": 1264, + "end": 1314, + "name": "tag", + "source": 22, + "value": "420" + }, + { + "begin": 1264, + "end": 1314, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 1349, + "end": 1407, + "name": "PUSH [tag]", + "source": 22, + "value": "421" + }, + { + "begin": 1399, + "end": 1406, + "name": "DUP7", + "source": 22 + }, + { + "begin": 1390, + "end": 1396, + "name": "DUP3", + "source": 22 + }, + { + "begin": 1379, + "end": 1388, + "name": "DUP8", + "source": 22 + }, + { + "begin": 1375, + "end": 1397, + "name": "ADD", + "source": 22 + }, + { + "begin": 1349, + "end": 1407, + "name": "PUSH [tag]", + "source": 22, + "value": "398" + }, + { + "begin": 1349, + "end": 1407, + "jumpType": "[in]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 1349, + "end": 1407, + "name": "tag", + "source": 22, + "value": "421" + }, + { + "begin": 1349, + "end": 1407, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 990, + "end": 1467, + "name": "SWAP5", + "source": 22 + }, + { + "begin": 990, + "end": 1467, + "name": "SWAP8", + "source": 22 + }, + { + "begin": 1426, + "end": 1434, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 1426, + "end": 1434, + "name": "SWAP7", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 1323, + "end": 1407, + "name": "SWAP4", + "source": 22 + }, + { + "begin": 1323, + "end": 1407, + "name": "SWAP5", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 990, + "end": 1467, + "jumpType": "[out]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 1725, + "end": 2442, + "name": "tag", + "source": 22, + "value": "33" + }, + { + "begin": 1725, + "end": 2442, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 1815, + "end": 1821, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 1823, + "end": 1829, + "name": "DUP1", + "source": 22 + }, + { + "begin": 1831, + "end": 1837, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 1839, + "end": 1845, + "name": "DUP1", + "source": 22 + }, + { + "begin": 1892, + "end": 1894, + "name": "PUSH", + "source": 22, + "value": "40" + }, + { + "begin": 1880, + "end": 1889, + "name": "DUP6", + "source": 22 + }, + { + "begin": 1871, + "end": 1878, + "name": "DUP8", + "source": 22 + }, + { + "begin": 1867, + "end": 1890, + "name": "SUB", + "source": 22 + }, + { + "begin": 1863, + "end": 1895, + "name": "SLT", + "source": 22 + }, + { + "begin": 1860, + "end": 1912, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 1860, + "end": 1912, + "name": "PUSH [tag]", + "source": 22, + "value": "424" + }, + { + "begin": 1860, + "end": 1912, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 1908, + "end": 1909, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 1905, + "end": 1906, + "name": "DUP1", + "source": 22 + }, + { + "begin": 1898, + "end": 1910, + "name": "REVERT", + "source": 22 + }, + { + "begin": 1860, + "end": 1912, + "name": "tag", + "source": 22, + "value": "424" + }, + { + "begin": 1860, + "end": 1912, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 1948, + "end": 1957, + "name": "DUP5", + "source": 22 + }, + { + "begin": 1935, + "end": 1958, + "name": "CALLDATALOAD", + "source": 22 + }, + { + "begin": 1977, + "end": 1995, + "name": "PUSH", + "source": 22, + "value": "FFFFFFFFFFFFFFFF" + }, + { + "begin": 2018, + "end": 2020, + "name": "DUP1", + "source": 22 + }, + { + "begin": 2010, + "end": 2016, + "name": "DUP3", + "source": 22 + }, + { + "begin": 2007, + "end": 2021, + "name": "GT", + "source": 22 + }, + { + "begin": 2004, + "end": 2038, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 2004, + "end": 2038, + "name": "PUSH [tag]", + "source": 22, + "value": "425" + }, + { + "begin": 2004, + "end": 2038, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 2034, + "end": 2035, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 2031, + "end": 2032, + "name": "DUP1", + "source": 22 + }, + { + "begin": 2024, + "end": 2036, + "name": "REVERT", + "source": 22 + }, + { + "begin": 2004, + "end": 2038, + "name": "tag", + "source": 22, + "value": "425" + }, + { + "begin": 2004, + "end": 2038, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 2073, + "end": 2131, + "name": "PUSH [tag]", + "source": 22, + "value": "426" + }, + { + "begin": 2123, + "end": 2130, + "name": "DUP9", + "source": 22 + }, + { + "begin": 2114, + "end": 2120, + "name": "DUP4", + "source": 22 + }, + { + "begin": 2103, + "end": 2112, + "name": "DUP10", + "source": 22 + }, + { + "begin": 2099, + "end": 2121, + "name": "ADD", + "source": 22 + }, + { + "begin": 2073, + "end": 2131, + "name": "PUSH [tag]", + "source": 22, + "value": "398" + }, + { + "begin": 2073, + "end": 2131, + "jumpType": "[in]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 2073, + "end": 2131, + "name": "tag", + "source": 22, + "value": "426" + }, + { + "begin": 2073, + "end": 2131, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 2150, + "end": 2158, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 2150, + "end": 2158, + "name": "SWAP7", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 2047, + "end": 2131, + "name": "SWAP5", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 2238, + "end": 2240, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 2223, + "end": 2241, + "name": "DUP8", + "source": 22 + }, + { + "begin": 2223, + "end": 2241, + "name": "ADD", + "source": 22 + }, + { + "begin": 2210, + "end": 2242, + "name": "CALLDATALOAD", + "source": 22 + }, + { + "begin": 2210, + "end": 2242, + "name": "SWAP2", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 2254, + "end": 2270, + "name": "DUP1", + "source": 22 + }, + { + "begin": 2254, + "end": 2270, + "name": "DUP3", + "source": 22 + }, + { + "begin": 2254, + "end": 2270, + "name": "GT", + "source": 22 + }, + { + "begin": 2251, + "end": 2287, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 2251, + "end": 2287, + "name": "PUSH [tag]", + "source": 22, + "value": "427" + }, + { + "begin": 2251, + "end": 2287, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 2283, + "end": 2284, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 2280, + "end": 2281, + "name": "DUP1", + "source": 22 + }, + { + "begin": 2273, + "end": 2285, + "name": "REVERT", + "source": 22 + }, + { + "begin": 2251, + "end": 2287, + "name": "tag", + "source": 22, + "value": "427" + }, + { + "begin": 2251, + "end": 2287, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 2251, + "end": 2287, + "name": "POP", + "source": 22 + }, + { + "begin": 2322, + "end": 2382, + "name": "PUSH [tag]", + "source": 22, + "value": "428" + }, + { + "begin": 2374, + "end": 2381, + "name": "DUP8", + "source": 22 + }, + { + "begin": 2363, + "end": 2371, + "name": "DUP3", + "source": 22 + }, + { + "begin": 2352, + "end": 2361, + "name": "DUP9", + "source": 22 + }, + { + "begin": 2348, + "end": 2372, + "name": "ADD", + "source": 22 + }, + { + "begin": 2322, + "end": 2382, + "name": "PUSH [tag]", + "source": 22, + "value": "398" + }, + { + "begin": 2322, + "end": 2382, + "jumpType": "[in]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 2322, + "end": 2382, + "name": "tag", + "source": 22, + "value": "428" + }, + { + "begin": 2322, + "end": 2382, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 1725, + "end": 2442, + "name": "SWAP6", + "source": 22 + }, + { + "begin": 1725, + "end": 2442, + "name": "SWAP9", + "source": 22 + }, + { + "begin": 1725, + "end": 2442, + "name": "SWAP5", + "source": 22 + }, + { + "begin": 1725, + "end": 2442, + "name": "SWAP8", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 2401, + "end": 2409, + "name": "SWAP6", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 1725, + "end": 2442, + "jumpType": "[out]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 2447, + "end": 2627, + "name": "tag", + "source": 22, + "value": "39" + }, + { + "begin": 2447, + "end": 2627, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 2506, + "end": 2512, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 2559, + "end": 2561, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 2547, + "end": 2556, + "name": "DUP3", + "source": 22 + }, + { + "begin": 2538, + "end": 2545, + "name": "DUP5", + "source": 22 + }, + { + "begin": 2534, + "end": 2557, + "name": "SUB", + "source": 22 + }, + { + "begin": 2530, + "end": 2562, + "name": "SLT", + "source": 22 + }, + { + "begin": 2527, + "end": 2579, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 2527, + "end": 2579, + "name": "PUSH [tag]", + "source": 22, + "value": "430" + }, + { + "begin": 2527, + "end": 2579, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 2575, + "end": 2576, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 2572, + "end": 2573, + "name": "DUP1", + "source": 22 + }, + { + "begin": 2565, + "end": 2577, + "name": "REVERT", + "source": 22 + }, + { + "begin": 2527, + "end": 2579, + "name": "tag", + "source": 22, + "value": "430" + }, + { + "begin": 2527, + "end": 2579, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 2598, + "end": 2621, + "name": "CALLDATALOAD", + "source": 22 + }, + { + "begin": 2598, + "end": 2621, + "name": "SWAP2", + "source": 22 + }, + { + "begin": 2447, + "end": 2627, + "name": "SWAP1", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 2447, + "end": 2627, + "jumpType": "[out]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 2814, + "end": 3201, + "name": "tag", + "source": 22, + "value": "399" + }, + { + "begin": 2814, + "end": 3201, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 2897, + "end": 2905, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 2907, + "end": 2913, + "name": "DUP1", + "source": 22 + }, + { + "begin": 2961, + "end": 2964, + "name": "DUP4", + "source": 22 + }, + { + "begin": 2954, + "end": 2958, + "name": "PUSH", + "source": 22, + "value": "1F" + }, + { + "begin": 2946, + "end": 2952, + "name": "DUP5", + "source": 22 + }, + { + "begin": 2942, + "end": 2959, + "name": "ADD", + "source": 22 + }, + { + "begin": 2938, + "end": 2965, + "name": "SLT", + "source": 22 + }, + { + "begin": 2928, + "end": 2983, + "name": "PUSH [tag]", + "source": 22, + "value": "433" + }, + { + "begin": 2928, + "end": 2983, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 2979, + "end": 2980, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 2976, + "end": 2977, + "name": "DUP1", + "source": 22 + }, + { + "begin": 2969, + "end": 2981, + "name": "REVERT", + "source": 22 + }, + { + "begin": 2928, + "end": 2983, + "name": "tag", + "source": 22, + "value": "433" + }, + { + "begin": 2928, + "end": 2983, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 3002, + "end": 3022, + "name": "DUP2", + "source": 22 + }, + { + "begin": 3002, + "end": 3022, + "name": "CALLDATALOAD", + "source": 22 + }, + { + "begin": 3045, + "end": 3063, + "name": "PUSH", + "source": 22, + "value": "FFFFFFFFFFFFFFFF" + }, + { + "begin": 3034, + "end": 3064, + "name": "DUP2", + "source": 22 + }, + { + "begin": 3034, + "end": 3064, + "name": "GT", + "source": 22 + }, + { + "begin": 3031, + "end": 3081, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 3031, + "end": 3081, + "name": "PUSH [tag]", + "source": 22, + "value": "434" + }, + { + "begin": 3031, + "end": 3081, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 3077, + "end": 3078, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 3074, + "end": 3075, + "name": "DUP1", + "source": 22 + }, + { + "begin": 3067, + "end": 3079, + "name": "REVERT", + "source": 22 + }, + { + "begin": 3031, + "end": 3081, + "name": "tag", + "source": 22, + "value": "434" + }, + { + "begin": 3031, + "end": 3081, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 3114, + "end": 3118, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 3106, + "end": 3112, + "name": "DUP4", + "source": 22 + }, + { + "begin": 3102, + "end": 3119, + "name": "ADD", + "source": 22 + }, + { + "begin": 3090, + "end": 3119, + "name": "SWAP2", + "source": 22 + }, + { + "begin": 3090, + "end": 3119, + "name": "POP", + "source": 22 + }, + { + "begin": 3174, + "end": 3177, + "name": "DUP4", + "source": 22 + }, + { + "begin": 3167, + "end": 3171, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 3157, + "end": 3163, + "name": "DUP3", + "source": 22 + }, + { + "begin": 3154, + "end": 3155, + "name": "PUSH", + "source": 22, + "value": "5" + }, + { + "begin": 3150, + "end": 3164, + "name": "SHL", + "source": 22 + }, + { + "begin": 3142, + "end": 3148, + "name": "DUP6", + "source": 22 + }, + { + "begin": 3138, + "end": 3165, + "name": "ADD", + "source": 22 + }, + { + "begin": 3134, + "end": 3172, + "name": "ADD", + "source": 22 + }, + { + "begin": 3131, + "end": 3178, + "name": "GT", + "source": 22 + }, + { + "begin": 3128, + "end": 3195, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 3128, + "end": 3195, + "name": "PUSH [tag]", + "source": 22, + "value": "417" + }, + { + "begin": 3128, + "end": 3195, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 3191, + "end": 3192, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 3188, + "end": 3189, + "name": "DUP1", + "source": 22 + }, + { + "begin": 3181, + "end": 3193, + "name": "REVERT", + "source": 22 + }, + { + "begin": 3206, + "end": 3694, + "name": "tag", + "source": 22, + "value": "49" + }, + { + "begin": 3206, + "end": 3694, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 3323, + "end": 3329, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 3331, + "end": 3337, + "name": "DUP1", + "source": 22 + }, + { + "begin": 3384, + "end": 3386, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 3372, + "end": 3381, + "name": "DUP4", + "source": 22 + }, + { + "begin": 3363, + "end": 3370, + "name": "DUP6", + "source": 22 + }, + { + "begin": 3359, + "end": 3382, + "name": "SUB", + "source": 22 + }, + { + "begin": 3355, + "end": 3387, + "name": "SLT", + "source": 22 + }, + { + "begin": 3352, + "end": 3404, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 3352, + "end": 3404, + "name": "PUSH [tag]", + "source": 22, + "value": "437" + }, + { + "begin": 3352, + "end": 3404, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 3400, + "end": 3401, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 3397, + "end": 3398, + "name": "DUP1", + "source": 22 + }, + { + "begin": 3390, + "end": 3402, + "name": "REVERT", + "source": 22 + }, + { + "begin": 3352, + "end": 3404, + "name": "tag", + "source": 22, + "value": "437" + }, + { + "begin": 3352, + "end": 3404, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 3440, + "end": 3449, + "name": "DUP3", + "source": 22 + }, + { + "begin": 3427, + "end": 3450, + "name": "CALLDATALOAD", + "source": 22 + }, + { + "begin": 3473, + "end": 3491, + "name": "PUSH", + "source": 22, + "value": "FFFFFFFFFFFFFFFF" + }, + { + "begin": 3465, + "end": 3471, + "name": "DUP2", + "source": 22 + }, + { + "begin": 3462, + "end": 3492, + "name": "GT", + "source": 22 + }, + { + "begin": 3459, + "end": 3509, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 3459, + "end": 3509, + "name": "PUSH [tag]", + "source": 22, + "value": "438" + }, + { + "begin": 3459, + "end": 3509, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 3505, + "end": 3506, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 3502, + "end": 3503, + "name": "DUP1", + "source": 22 + }, + { + "begin": 3495, + "end": 3507, + "name": "REVERT", + "source": 22 + }, + { + "begin": 3459, + "end": 3509, + "name": "tag", + "source": 22, + "value": "438" + }, + { + "begin": 3459, + "end": 3509, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 3544, + "end": 3634, + "name": "PUSH [tag]", + "source": 22, + "value": "439" + }, + { + "begin": 3626, + "end": 3633, + "name": "DUP6", + "source": 22 + }, + { + "begin": 3617, + "end": 3623, + "name": "DUP3", + "source": 22 + }, + { + "begin": 3606, + "end": 3615, + "name": "DUP7", + "source": 22 + }, + { + "begin": 3602, + "end": 3624, + "name": "ADD", + "source": 22 + }, + { + "begin": 3544, + "end": 3634, + "name": "PUSH [tag]", + "source": 22, + "value": "399" + }, + { + "begin": 3544, + "end": 3634, + "jumpType": "[in]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 3544, + "end": 3634, + "name": "tag", + "source": 22, + "value": "439" + }, + { + "begin": 3544, + "end": 3634, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 3653, + "end": 3661, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 3653, + "end": 3661, + "name": "SWAP7", + "source": 22 + }, + { + "begin": 3518, + "end": 3634, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 3518, + "end": 3634, + "name": "SWAP6", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 3206, + "end": 3694, + "name": "SWAP4", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 3206, + "end": 3694, + "jumpType": "[out]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 3699, + "end": 4563, + "name": "tag", + "source": 22, + "value": "54" + }, + { + "begin": 3699, + "end": 4563, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 3845, + "end": 3851, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 3853, + "end": 3859, + "name": "DUP1", + "source": 22 + }, + { + "begin": 3861, + "end": 3867, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 3869, + "end": 3875, + "name": "DUP1", + "source": 22 + }, + { + "begin": 3877, + "end": 3883, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 3930, + "end": 3932, + "name": "PUSH", + "source": 22, + "value": "60" + }, + { + "begin": 3918, + "end": 3927, + "name": "DUP7", + "source": 22 + }, + { + "begin": 3909, + "end": 3916, + "name": "DUP9", + "source": 22 + }, + { + "begin": 3905, + "end": 3928, + "name": "SUB", + "source": 22 + }, + { + "begin": 3901, + "end": 3933, + "name": "SLT", + "source": 22 + }, + { + "begin": 3898, + "end": 3950, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 3898, + "end": 3950, + "name": "PUSH [tag]", + "source": 22, + "value": "441" + }, + { + "begin": 3898, + "end": 3950, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 3946, + "end": 3947, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 3943, + "end": 3944, + "name": "DUP1", + "source": 22 + }, + { + "begin": 3936, + "end": 3948, + "name": "REVERT", + "source": 22 + }, + { + "begin": 3898, + "end": 3950, + "name": "tag", + "source": 22, + "value": "441" + }, + { + "begin": 3898, + "end": 3950, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 3986, + "end": 3995, + "name": "DUP6", + "source": 22 + }, + { + "begin": 3973, + "end": 3996, + "name": "CALLDATALOAD", + "source": 22 + }, + { + "begin": 4015, + "end": 4033, + "name": "PUSH", + "source": 22, + "value": "FFFFFFFFFFFFFFFF" + }, + { + "begin": 4056, + "end": 4058, + "name": "DUP1", + "source": 22 + }, + { + "begin": 4048, + "end": 4054, + "name": "DUP3", + "source": 22 + }, + { + "begin": 4045, + "end": 4059, + "name": "GT", + "source": 22 + }, + { + "begin": 4042, + "end": 4076, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 4042, + "end": 4076, + "name": "PUSH [tag]", + "source": 22, + "value": "442" + }, + { + "begin": 4042, + "end": 4076, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 4072, + "end": 4073, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 4069, + "end": 4070, + "name": "DUP1", + "source": 22 + }, + { + "begin": 4062, + "end": 4074, + "name": "REVERT", + "source": 22 + }, + { + "begin": 4042, + "end": 4076, + "name": "tag", + "source": 22, + "value": "442" + }, + { + "begin": 4042, + "end": 4076, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 4111, + "end": 4201, + "name": "PUSH [tag]", + "source": 22, + "value": "443" + }, + { + "begin": 4193, + "end": 4200, + "name": "DUP10", + "source": 22 + }, + { + "begin": 4184, + "end": 4190, + "name": "DUP4", + "source": 22 + }, + { + "begin": 4173, + "end": 4182, + "name": "DUP11", + "source": 22 + }, + { + "begin": 4169, + "end": 4191, + "name": "ADD", + "source": 22 + }, + { + "begin": 4111, + "end": 4201, + "name": "PUSH [tag]", + "source": 22, + "value": "399" + }, + { + "begin": 4111, + "end": 4201, + "jumpType": "[in]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 4111, + "end": 4201, + "name": "tag", + "source": 22, + "value": "443" + }, + { + "begin": 4111, + "end": 4201, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 4220, + "end": 4228, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 4220, + "end": 4228, + "name": "SWAP8", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 4085, + "end": 4201, + "name": "SWAP6", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 4302, + "end": 4304, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 4287, + "end": 4305, + "name": "DUP9", + "source": 22 + }, + { + "begin": 4287, + "end": 4305, + "name": "ADD", + "source": 22 + }, + { + "begin": 4274, + "end": 4306, + "name": "CALLDATALOAD", + "source": 22 + }, + { + "begin": 4274, + "end": 4306, + "name": "SWAP5", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 4359, + "end": 4361, + "name": "PUSH", + "source": 22, + "value": "40" + }, + { + "begin": 4344, + "end": 4362, + "name": "DUP9", + "source": 22 + }, + { + "begin": 4344, + "end": 4362, + "name": "ADD", + "source": 22 + }, + { + "begin": 4331, + "end": 4363, + "name": "CALLDATALOAD", + "source": 22 + }, + { + "begin": 4331, + "end": 4363, + "name": "SWAP2", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 4375, + "end": 4391, + "name": "DUP1", + "source": 22 + }, + { + "begin": 4375, + "end": 4391, + "name": "DUP3", + "source": 22 + }, + { + "begin": 4375, + "end": 4391, + "name": "GT", + "source": 22 + }, + { + "begin": 4372, + "end": 4408, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 4372, + "end": 4408, + "name": "PUSH [tag]", + "source": 22, + "value": "444" + }, + { + "begin": 4372, + "end": 4408, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 4404, + "end": 4405, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 4401, + "end": 4402, + "name": "DUP1", + "source": 22 + }, + { + "begin": 4394, + "end": 4406, + "name": "REVERT", + "source": 22 + }, + { + "begin": 4372, + "end": 4408, + "name": "tag", + "source": 22, + "value": "444" + }, + { + "begin": 4372, + "end": 4408, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 4372, + "end": 4408, + "name": "POP", + "source": 22 + }, + { + "begin": 4443, + "end": 4503, + "name": "PUSH [tag]", + "source": 22, + "value": "445" + }, + { + "begin": 4495, + "end": 4502, + "name": "DUP9", + "source": 22 + }, + { + "begin": 4484, + "end": 4492, + "name": "DUP3", + "source": 22 + }, + { + "begin": 4473, + "end": 4482, + "name": "DUP10", + "source": 22 + }, + { + "begin": 4469, + "end": 4493, + "name": "ADD", + "source": 22 + }, + { + "begin": 4443, + "end": 4503, + "name": "PUSH [tag]", + "source": 22, + "value": "398" + }, + { + "begin": 4443, + "end": 4503, + "jumpType": "[in]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 4443, + "end": 4503, + "name": "tag", + "source": 22, + "value": "445" + }, + { + "begin": 4443, + "end": 4503, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 3699, + "end": 4563, + "name": "SWAP7", + "source": 22 + }, + { + "begin": 3699, + "end": 4563, + "name": "SWAP10", + "source": 22 + }, + { + "begin": 3699, + "end": 4563, + "name": "SWAP6", + "source": 22 + }, + { + "begin": 3699, + "end": 4563, + "name": "SWAP9", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 3699, + "end": 4563, + "name": "SWAP4", + "source": 22 + }, + { + "begin": 3699, + "end": 4563, + "name": "SWAP7", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 4522, + "end": 4530, + "name": "SWAP3", + "source": 22 + }, + { + "begin": 4522, + "end": 4530, + "name": "SWAP5", + "source": 22 + }, + { + "begin": 4417, + "end": 4503, + "name": "SWAP4", + "source": 22 + }, + { + "begin": 3699, + "end": 4563, + "name": "SWAP3", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 3699, + "end": 4563, + "jumpType": "[out]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 5403, + "end": 5587, + "name": "tag", + "source": 22, + "value": "400" + }, + { + "begin": 5403, + "end": 5587, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 5455, + "end": 5532, + "name": "PUSH", + "source": 22, + "value": "4E487B7100000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 5452, + "end": 5453, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 5445, + "end": 5533, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 5552, + "end": 5556, + "name": "PUSH", + "source": 22, + "value": "41" + }, + { + "begin": 5549, + "end": 5550, + "name": "PUSH", + "source": 22, + "value": "4" + }, + { + "begin": 5542, + "end": 5557, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 5576, + "end": 5580, + "name": "PUSH", + "source": 22, + "value": "24" + }, + { + "begin": 5573, + "end": 5574, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 5566, + "end": 5581, + "name": "REVERT", + "source": 22 + }, + { + "begin": 5592, + "end": 6572, + "name": "tag", + "source": 22, + "value": "71" + }, + { + "begin": 5592, + "end": 6572, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 5660, + "end": 5666, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 5713, + "end": 5715, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 5701, + "end": 5710, + "name": "DUP3", + "source": 22 + }, + { + "begin": 5692, + "end": 5699, + "name": "DUP5", + "source": 22 + }, + { + "begin": 5688, + "end": 5711, + "name": "SUB", + "source": 22 + }, + { + "begin": 5684, + "end": 5716, + "name": "SLT", + "source": 22 + }, + { + "begin": 5681, + "end": 5733, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 5681, + "end": 5733, + "name": "PUSH [tag]", + "source": 22, + "value": "452" + }, + { + "begin": 5681, + "end": 5733, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 5729, + "end": 5730, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 5726, + "end": 5727, + "name": "DUP1", + "source": 22 + }, + { + "begin": 5719, + "end": 5731, + "name": "REVERT", + "source": 22 + }, + { + "begin": 5681, + "end": 5733, + "name": "tag", + "source": 22, + "value": "452" + }, + { + "begin": 5681, + "end": 5733, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 5769, + "end": 5778, + "name": "DUP2", + "source": 22 + }, + { + "begin": 5756, + "end": 5779, + "name": "CALLDATALOAD", + "source": 22 + }, + { + "begin": 5798, + "end": 5816, + "name": "PUSH", + "source": 22, + "value": "FFFFFFFFFFFFFFFF" + }, + { + "begin": 5839, + "end": 5841, + "name": "DUP1", + "source": 22 + }, + { + "begin": 5831, + "end": 5837, + "name": "DUP3", + "source": 22 + }, + { + "begin": 5828, + "end": 5842, + "name": "GT", + "source": 22 + }, + { + "begin": 5825, + "end": 5859, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 5825, + "end": 5859, + "name": "PUSH [tag]", + "source": 22, + "value": "453" + }, + { + "begin": 5825, + "end": 5859, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 5855, + "end": 5856, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 5852, + "end": 5853, + "name": "DUP1", + "source": 22 + }, + { + "begin": 5845, + "end": 5857, + "name": "REVERT", + "source": 22 + }, + { + "begin": 5825, + "end": 5859, + "name": "tag", + "source": 22, + "value": "453" + }, + { + "begin": 5825, + "end": 5859, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 5893, + "end": 5899, + "name": "DUP2", + "source": 22 + }, + { + "begin": 5882, + "end": 5891, + "name": "DUP5", + "source": 22 + }, + { + "begin": 5878, + "end": 5900, + "name": "ADD", + "source": 22 + }, + { + "begin": 5868, + "end": 5900, + "name": "SWAP2", + "source": 22 + }, + { + "begin": 5868, + "end": 5900, + "name": "POP", + "source": 22 + }, + { + "begin": 5938, + "end": 5945, + "name": "DUP5", + "source": 22 + }, + { + "begin": 5931, + "end": 5935, + "name": "PUSH", + "source": 22, + "value": "1F" + }, + { + "begin": 5927, + "end": 5929, + "name": "DUP4", + "source": 22 + }, + { + "begin": 5923, + "end": 5936, + "name": "ADD", + "source": 22 + }, + { + "begin": 5919, + "end": 5946, + "name": "SLT", + "source": 22 + }, + { + "begin": 5909, + "end": 5964, + "name": "PUSH [tag]", + "source": 22, + "value": "454" + }, + { + "begin": 5909, + "end": 5964, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 5960, + "end": 5961, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 5957, + "end": 5958, + "name": "DUP1", + "source": 22 + }, + { + "begin": 5950, + "end": 5962, + "name": "REVERT", + "source": 22 + }, + { + "begin": 5909, + "end": 5964, + "name": "tag", + "source": 22, + "value": "454" + }, + { + "begin": 5909, + "end": 5964, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 5996, + "end": 5998, + "name": "DUP2", + "source": 22 + }, + { + "begin": 5983, + "end": 5999, + "name": "CALLDATALOAD", + "source": 22 + }, + { + "begin": 6018, + "end": 6020, + "name": "DUP2", + "source": 22 + }, + { + "begin": 6014, + "end": 6016, + "name": "DUP2", + "source": 22 + }, + { + "begin": 6011, + "end": 6021, + "name": "GT", + "source": 22 + }, + { + "begin": 6008, + "end": 6044, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 6008, + "end": 6044, + "name": "PUSH [tag]", + "source": 22, + "value": "456" + }, + { + "begin": 6008, + "end": 6044, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 6024, + "end": 6042, + "name": "PUSH [tag]", + "source": 22, + "value": "456" + }, + { + "begin": 6024, + "end": 6042, + "name": "PUSH [tag]", + "source": 22, + "value": "400" + }, + { + "begin": 6024, + "end": 6042, + "jumpType": "[in]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 6024, + "end": 6042, + "name": "tag", + "source": 22, + "value": "456" + }, + { + "begin": 6024, + "end": 6042, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 6158, + "end": 6160, + "name": "PUSH", + "source": 22, + "value": "40" + }, + { + "begin": 6152, + "end": 6161, + "name": "MLOAD", + "source": 22 + }, + { + "begin": 6220, + "end": 6224, + "name": "PUSH", + "source": 22, + "value": "1F" + }, + { + "begin": 6212, + "end": 6225, + "name": "DUP3", + "source": 22 + }, + { + "begin": 6212, + "end": 6225, + "name": "ADD", + "source": 22 + }, + { + "begin": 6063, + "end": 6129, + "name": "PUSH", + "source": 22, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0" + }, + { + "begin": 6208, + "end": 6230, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 6208, + "end": 6230, + "name": "DUP2", + "source": 22 + }, + { + "begin": 6208, + "end": 6230, + "name": "AND", + "source": 22 + }, + { + "begin": 6232, + "end": 6234, + "name": "PUSH", + "source": 22, + "value": "3F" + }, + { + "begin": 6204, + "end": 6235, + "name": "ADD", + "source": 22 + }, + { + "begin": 6200, + "end": 6240, + "name": "AND", + "source": 22 + }, + { + "begin": 6188, + "end": 6241, + "name": "DUP2", + "source": 22 + }, + { + "begin": 6188, + "end": 6241, + "name": "ADD", + "source": 22 + }, + { + "begin": 6188, + "end": 6241, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 6256, + "end": 6274, + "name": "DUP4", + "source": 22 + }, + { + "begin": 6256, + "end": 6274, + "name": "DUP3", + "source": 22 + }, + { + "begin": 6256, + "end": 6274, + "name": "GT", + "source": 22 + }, + { + "begin": 6276, + "end": 6298, + "name": "DUP2", + "source": 22 + }, + { + "begin": 6276, + "end": 6298, + "name": "DUP4", + "source": 22 + }, + { + "begin": 6276, + "end": 6298, + "name": "LT", + "source": 22 + }, + { + "begin": 6253, + "end": 6299, + "name": "OR", + "source": 22 + }, + { + "begin": 6250, + "end": 6322, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 6250, + "end": 6322, + "name": "PUSH [tag]", + "source": 22, + "value": "458" + }, + { + "begin": 6250, + "end": 6322, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 6302, + "end": 6320, + "name": "PUSH [tag]", + "source": 22, + "value": "458" + }, + { + "begin": 6302, + "end": 6320, + "name": "PUSH [tag]", + "source": 22, + "value": "400" + }, + { + "begin": 6302, + "end": 6320, + "jumpType": "[in]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 6302, + "end": 6320, + "name": "tag", + "source": 22, + "value": "458" + }, + { + "begin": 6302, + "end": 6320, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 6342, + "end": 6352, + "name": "DUP2", + "source": 22 + }, + { + "begin": 6338, + "end": 6340, + "name": "PUSH", + "source": 22, + "value": "40" + }, + { + "begin": 6331, + "end": 6353, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 6377, + "end": 6379, + "name": "DUP3", + "source": 22 + }, + { + "begin": 6369, + "end": 6375, + "name": "DUP2", + "source": 22 + }, + { + "begin": 6362, + "end": 6380, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 6417, + "end": 6424, + "name": "DUP8", + "source": 22 + }, + { + "begin": 6412, + "end": 6414, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 6407, + "end": 6409, + "name": "DUP5", + "source": 22 + }, + { + "begin": 6403, + "end": 6405, + "name": "DUP8", + "source": 22 + }, + { + "begin": 6399, + "end": 6410, + "name": "ADD", + "source": 22 + }, + { + "begin": 6395, + "end": 6415, + "name": "ADD", + "source": 22 + }, + { + "begin": 6392, + "end": 6425, + "name": "GT", + "source": 22 + }, + { + "begin": 6389, + "end": 6442, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 6389, + "end": 6442, + "name": "PUSH [tag]", + "source": 22, + "value": "459" + }, + { + "begin": 6389, + "end": 6442, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 6438, + "end": 6439, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 6435, + "end": 6436, + "name": "DUP1", + "source": 22 + }, + { + "begin": 6428, + "end": 6440, + "name": "REVERT", + "source": 22 + }, + { + "begin": 6389, + "end": 6442, + "name": "tag", + "source": 22, + "value": "459" + }, + { + "begin": 6389, + "end": 6442, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 6494, + "end": 6496, + "name": "DUP3", + "source": 22 + }, + { + "begin": 6489, + "end": 6491, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 6485, + "end": 6487, + "name": "DUP7", + "source": 22 + }, + { + "begin": 6481, + "end": 6492, + "name": "ADD", + "source": 22 + }, + { + "begin": 6476, + "end": 6478, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 6468, + "end": 6474, + "name": "DUP4", + "source": 22 + }, + { + "begin": 6464, + "end": 6479, + "name": "ADD", + "source": 22 + }, + { + "begin": 6451, + "end": 6497, + "name": "CALLDATACOPY", + "source": 22 + }, + { + "begin": 6539, + "end": 6540, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 6517, + "end": 6532, + "name": "SWAP3", + "source": 22 + }, + { + "begin": 6517, + "end": 6532, + "name": "DUP2", + "source": 22 + }, + { + "begin": 6517, + "end": 6532, + "name": "ADD", + "source": 22 + }, + { + "begin": 6534, + "end": 6536, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 6513, + "end": 6537, + "name": "ADD", + "source": 22 + }, + { + "begin": 6506, + "end": 6541, + "name": "SWAP3", + "source": 22 + }, + { + "begin": 6506, + "end": 6541, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 6506, + "end": 6541, + "name": "SWAP3", + "source": 22 + }, + { + "begin": 6506, + "end": 6541, + "name": "MSTORE", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 6521, + "end": 6527, + "name": "SWAP6", + "source": 22 + }, + { + "begin": 5592, + "end": 6572, + "name": "SWAP5", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 5592, + "end": 6572, + "jumpType": "[out]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 6808, + "end": 7079, + "name": "tag", + "source": 22, + "value": "89" + }, + { + "begin": 6808, + "end": 7079, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 6991, + "end": 6997, + "name": "DUP2", + "source": 22 + }, + { + "begin": 6983, + "end": 6989, + "name": "DUP4", + "source": 22 + }, + { + "begin": 6978, + "end": 6981, + "name": "DUP3", + "source": 22 + }, + { + "begin": 6965, + "end": 6998, + "name": "CALLDATACOPY", + "source": 22 + }, + { + "begin": 6947, + "end": 6950, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 7017, + "end": 7033, + "name": "SWAP2", + "source": 22 + }, + { + "begin": 7017, + "end": 7033, + "name": "ADD", + "source": 22 + }, + { + "begin": 7042, + "end": 7055, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 7042, + "end": 7055, + "name": "DUP2", + "source": 22 + }, + { + "begin": 7042, + "end": 7055, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 7017, + "end": 7033, + "name": "SWAP2", + "source": 22 + }, + { + "begin": 6808, + "end": 7079, + "name": "SWAP1", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 6808, + "end": 7079, + "jumpType": "[out]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 7416, + "end": 7576, + "name": "tag", + "source": 22, + "value": "401" + }, + { + "begin": 7416, + "end": 7576, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 7481, + "end": 7501, + "name": "DUP1", + "source": 22 + }, + { + "begin": 7481, + "end": 7501, + "name": "CALLDATALOAD", + "source": 22 + }, + { + "begin": 7537, + "end": 7550, + "name": "DUP1", + "source": 22 + }, + { + "begin": 7537, + "end": 7550, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 7530, + "end": 7551, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 7520, + "end": 7552, + "name": "DUP2", + "source": 22 + }, + { + "begin": 7520, + "end": 7552, + "name": "EQ", + "source": 22 + }, + { + "begin": 7510, + "end": 7570, + "name": "PUSH [tag]", + "source": 22, + "value": "464" + }, + { + "begin": 7510, + "end": 7570, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 7566, + "end": 7567, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 7563, + "end": 7564, + "name": "DUP1", + "source": 22 + }, + { + "begin": 7556, + "end": 7568, + "name": "REVERT", + "source": 22 + }, + { + "begin": 7510, + "end": 7570, + "name": "tag", + "source": 22, + "value": "464" + }, + { + "begin": 7510, + "end": 7570, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 7416, + "end": 7576, + "name": "SWAP2", + "source": 22 + }, + { + "begin": 7416, + "end": 7576, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 7416, + "end": 7576, + "name": "POP", + "source": 22 + }, + { + "begin": 7416, + "end": 7576, + "jumpType": "[out]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 7581, + "end": 7777, + "name": "tag", + "source": 22, + "value": "402" + }, + { + "begin": 7581, + "end": 7777, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 7649, + "end": 7669, + "name": "DUP1", + "source": 22 + }, + { + "begin": 7649, + "end": 7669, + "name": "CALLDATALOAD", + "source": 22 + }, + { + "begin": 7709, + "end": 7751, + "name": "PUSH", + "source": 22, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { + "begin": 7698, + "end": 7752, + "name": "DUP2", + "source": 22 + }, + { + "begin": 7698, + "end": 7752, + "name": "AND", + "source": 22 + }, + { + "begin": 7688, + "end": 7753, + "name": "DUP2", + "source": 22 + }, + { + "begin": 7688, + "end": 7753, + "name": "EQ", + "source": 22 + }, + { + "begin": 7678, + "end": 7771, + "name": "PUSH [tag]", + "source": 22, + "value": "464" + }, + { + "begin": 7678, + "end": 7771, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 7767, + "end": 7768, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 7764, + "end": 7765, + "name": "DUP1", + "source": 22 + }, + { + "begin": 7757, + "end": 7769, + "name": "REVERT", + "source": 22 + }, + { + "begin": 7782, + "end": 8107, + "name": "tag", + "source": 22, + "value": "403" + }, + { + "begin": 7782, + "end": 8107, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 7870, + "end": 7876, + "name": "DUP2", + "source": 22 + }, + { + "begin": 7865, + "end": 7868, + "name": "DUP4", + "source": 22 + }, + { + "begin": 7858, + "end": 7877, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 7922, + "end": 7928, + "name": "DUP2", + "source": 22 + }, + { + "begin": 7915, + "end": 7920, + "name": "DUP2", + "source": 22 + }, + { + "begin": 7908, + "end": 7912, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 7903, + "end": 7906, + "name": "DUP6", + "source": 22 + }, + { + "begin": 7899, + "end": 7913, + "name": "ADD", + "source": 22 + }, + { + "begin": 7886, + "end": 7929, + "name": "CALLDATACOPY", + "source": 22 + }, + { + "begin": 7886, + "end": 7929, + "name": "POP", + "source": 22 + }, + { + "begin": 7974, + "end": 7975, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 7967, + "end": 7971, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 7958, + "end": 7964, + "name": "DUP3", + "source": 22 + }, + { + "begin": 7953, + "end": 7956, + "name": "DUP5", + "source": 22 + }, + { + "begin": 7949, + "end": 7965, + "name": "ADD", + "source": 22 + }, + { + "begin": 7945, + "end": 7972, + "name": "ADD", + "source": 22 + }, + { + "begin": 7938, + "end": 7976, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 7840, + "end": 7843, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 8096, + "end": 8100, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 8026, + "end": 8092, + "name": "PUSH", + "source": 22, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0" + }, + { + "begin": 8021, + "end": 8023, + "name": "PUSH", + "source": 22, + "value": "1F" + }, + { + "begin": 8013, + "end": 8019, + "name": "DUP5", + "source": 22 + }, + { + "begin": 8009, + "end": 8024, + "name": "ADD", + "source": 22 + }, + { + "begin": 8005, + "end": 8093, + "name": "AND", + "source": 22 + }, + { + "begin": 8000, + "end": 8003, + "name": "DUP5", + "source": 22 + }, + { + "begin": 7996, + "end": 8094, + "name": "ADD", + "source": 22 + }, + { + "begin": 7992, + "end": 8101, + "name": "ADD", + "source": 22 + }, + { + "begin": 7985, + "end": 8101, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 7985, + "end": 8101, + "name": "POP", + "source": 22 + }, + { + "begin": 7782, + "end": 8107, + "name": "SWAP3", + "source": 22 + }, + { + "begin": 7782, + "end": 8107, + "name": "SWAP2", + "source": 22 + }, + { + "begin": 7782, + "end": 8107, + "name": "POP", + "source": 22 + }, + { + "begin": 7782, + "end": 8107, + "name": "POP", + "source": 22 + }, + { + "begin": 7782, + "end": 8107, + "jumpType": "[out]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 8112, + "end": 10140, + "name": "tag", + "source": 22, + "value": "404" + }, + { + "begin": 8112, + "end": 10140, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 8232, + "end": 8238, + "name": "DUP2", + "source": 22 + }, + { + "begin": 8227, + "end": 8230, + "name": "DUP4", + "source": 22 + }, + { + "begin": 8220, + "end": 8239, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 8202, + "end": 8205, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 8258, + "end": 8262, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 8299, + "end": 8301, + "name": "DUP1", + "source": 22 + }, + { + "begin": 8294, + "end": 8297, + "name": "DUP6", + "source": 22 + }, + { + "begin": 8290, + "end": 8302, + "name": "ADD", + "source": 22 + }, + { + "begin": 8324, + "end": 8335, + "name": "DUP1", + "source": 22 + }, + { + "begin": 8351, + "end": 8362, + "name": "DUP2", + "source": 22 + }, + { + "begin": 8344, + "end": 8362, + "name": "SWAP7", + "source": 22 + }, + { + "begin": 8344, + "end": 8362, + "name": "POP", + "source": 22 + }, + { + "begin": 8401, + "end": 8407, + "name": "DUP6", + "source": 22 + }, + { + "begin": 8398, + "end": 8399, + "name": "PUSH", + "source": 22, + "value": "5" + }, + { + "begin": 8394, + "end": 8408, + "name": "SHL", + "source": 22 + }, + { + "begin": 8387, + "end": 8392, + "name": "DUP2", + "source": 22 + }, + { + "begin": 8383, + "end": 8409, + "name": "ADD", + "source": 22 + }, + { + "begin": 8371, + "end": 8409, + "name": "SWAP2", + "source": 22 + }, + { + "begin": 8371, + "end": 8409, + "name": "POP", + "source": 22 + }, + { + "begin": 8432, + "end": 8437, + "name": "DUP5", + "source": 22 + }, + { + "begin": 8455, + "end": 8456, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 8465, + "end": 10114, + "name": "tag", + "source": 22, + "value": "469" + }, + { + "begin": 8465, + "end": 10114, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 8479, + "end": 8485, + "name": "DUP8", + "source": 22 + }, + { + "begin": 8476, + "end": 8477, + "name": "DUP2", + "source": 22 + }, + { + "begin": 8473, + "end": 8486, + "name": "LT", + "source": 22 + }, + { + "begin": 8465, + "end": 10114, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 8465, + "end": 10114, + "name": "PUSH [tag]", + "source": 22, + "value": "471" + }, + { + "begin": 8465, + "end": 10114, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 8550, + "end": 8555, + "name": "DUP3", + "source": 22 + }, + { + "begin": 8544, + "end": 8548, + "name": "DUP5", + "source": 22 + }, + { + "begin": 8540, + "end": 8556, + "name": "SUB", + "source": 22 + }, + { + "begin": 8535, + "end": 8538, + "name": "DUP10", + "source": 22 + }, + { + "begin": 8528, + "end": 8557, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 8609, + "end": 8615, + "name": "DUP2", + "source": 22 + }, + { + "begin": 8596, + "end": 8616, + "name": "CALLDATALOAD", + "source": 22 + }, + { + "begin": 8695, + "end": 8761, + "name": "PUSH", + "source": 22, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41" + }, + { + "begin": 8687, + "end": 8692, + "name": "DUP9", + "source": 22 + }, + { + "begin": 8671, + "end": 8685, + "name": "CALLDATASIZE", + "source": 22 + }, + { + "begin": 8667, + "end": 8693, + "name": "SUB", + "source": 22 + }, + { + "begin": 8663, + "end": 8762, + "name": "ADD", + "source": 22 + }, + { + "begin": 8643, + "end": 8661, + "name": "DUP2", + "source": 22 + }, + { + "begin": 8639, + "end": 8763, + "name": "SLT", + "source": 22 + }, + { + "begin": 8629, + "end": 8781, + "name": "PUSH [tag]", + "source": 22, + "value": "472" + }, + { + "begin": 8629, + "end": 8781, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 8777, + "end": 8778, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 8774, + "end": 8775, + "name": "DUP1", + "source": 22 + }, + { + "begin": 8767, + "end": 8779, + "name": "REVERT", + "source": 22 + }, + { + "begin": 8629, + "end": 8781, + "name": "tag", + "source": 22, + "value": "472" + }, + { + "begin": 8629, + "end": 8781, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 8809, + "end": 8839, + "name": "DUP8", + "source": 22 + }, + { + "begin": 8809, + "end": 8839, + "name": "ADD", + "source": 22 + }, + { + "begin": 8862, + "end": 8866, + "name": "PUSH", + "source": 22, + "value": "C0" + }, + { + "begin": 8906, + "end": 8930, + "name": "PUSH [tag]", + "source": 22, + "value": "473" + }, + { + "begin": 8809, + "end": 8839, + "name": "DUP3", + "source": 22 + }, + { + "begin": 8906, + "end": 8930, + "name": "PUSH [tag]", + "source": 22, + "value": "401" + }, + { + "begin": 8906, + "end": 8930, + "jumpType": "[in]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 8906, + "end": 8930, + "name": "tag", + "source": 22, + "value": "473" + }, + { + "begin": 8906, + "end": 8930, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 8899, + "end": 8931, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 8892, + "end": 8932, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 8886, + "end": 8890, + "name": "DUP7", + "source": 22 + }, + { + "begin": 8879, + "end": 8933, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 8982, + "end": 9015, + "name": "PUSH [tag]", + "source": 22, + "value": "474" + }, + { + "begin": 9011, + "end": 9013, + "name": "DUP8", + "source": 22 + }, + { + "begin": 9002, + "end": 9009, + "name": "DUP4", + "source": 22 + }, + { + "begin": 8998, + "end": 9014, + "name": "ADD", + "source": 22 + }, + { + "begin": 8982, + "end": 9015, + "name": "PUSH [tag]", + "source": 22, + "value": "401" + }, + { + "begin": 8982, + "end": 9015, + "jumpType": "[in]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 8982, + "end": 9015, + "name": "tag", + "source": 22, + "value": "474" + }, + { + "begin": 8982, + "end": 9015, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 8975, + "end": 9016, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 8968, + "end": 9017, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 8953, + "end": 8966, + "name": "DUP7", + "source": 22 + }, + { + "begin": 8953, + "end": 8966, + "name": "DUP9", + "source": 22 + }, + { + "begin": 8953, + "end": 8966, + "name": "ADD", + "source": 22 + }, + { + "begin": 8946, + "end": 9018, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 9041, + "end": 9045, + "name": "PUSH", + "source": 22, + "value": "40" + }, + { + "begin": 9093, + "end": 9109, + "name": "DUP3", + "source": 22 + }, + { + "begin": 9093, + "end": 9109, + "name": "DUP2", + "source": 22 + }, + { + "begin": 9093, + "end": 9109, + "name": "ADD", + "source": 22 + }, + { + "begin": 9080, + "end": 9110, + "name": "CALLDATALOAD", + "source": 22 + }, + { + "begin": 9065, + "end": 9078, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 9065, + "end": 9078, + "name": "DUP8", + "source": 22 + }, + { + "begin": 9065, + "end": 9078, + "name": "ADD", + "source": 22 + }, + { + "begin": 9058, + "end": 9111, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 9134, + "end": 9138, + "name": "PUSH", + "source": 22, + "value": "60" + }, + { + "begin": 9215, + "end": 9257, + "name": "PUSH", + "source": 22, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { + "begin": 9177, + "end": 9213, + "name": "PUSH [tag]", + "source": 22, + "value": "475" + }, + { + "begin": 9196, + "end": 9212, + "name": "DUP3", + "source": 22 + }, + { + "begin": 9196, + "end": 9212, + "name": "DUP6", + "source": 22 + }, + { + "begin": 9196, + "end": 9212, + "name": "ADD", + "source": 22 + }, + { + "begin": 9177, + "end": 9213, + "name": "PUSH [tag]", + "source": 22, + "value": "402" + }, + { + "begin": 9177, + "end": 9213, + "jumpType": "[in]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 9177, + "end": 9213, + "name": "tag", + "source": 22, + "value": "475" + }, + { + "begin": 9177, + "end": 9213, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 9173, + "end": 9258, + "name": "AND", + "source": 22 + }, + { + "begin": 9158, + "end": 9171, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 9158, + "end": 9171, + "name": "DUP8", + "source": 22 + }, + { + "begin": 9158, + "end": 9171, + "name": "ADD", + "source": 22 + }, + { + "begin": 9151, + "end": 9259, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 9282, + "end": 9286, + "name": "PUSH", + "source": 22, + "value": "80" + }, + { + "begin": 9334, + "end": 9350, + "name": "DUP3", + "source": 22 + }, + { + "begin": 9334, + "end": 9350, + "name": "DUP2", + "source": 22 + }, + { + "begin": 9334, + "end": 9350, + "name": "ADD", + "source": 22 + }, + { + "begin": 9321, + "end": 9351, + "name": "CALLDATALOAD", + "source": 22 + }, + { + "begin": 9306, + "end": 9319, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 9306, + "end": 9319, + "name": "DUP8", + "source": 22 + }, + { + "begin": 9306, + "end": 9319, + "name": "ADD", + "source": 22 + }, + { + "begin": 9299, + "end": 9352, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 9375, + "end": 9379, + "name": "PUSH", + "source": 22, + "value": "A0" + }, + { + "begin": 9433, + "end": 9449, + "name": "DUP1", + "source": 22 + }, + { + "begin": 9433, + "end": 9449, + "name": "DUP4", + "source": 22 + }, + { + "begin": 9433, + "end": 9449, + "name": "ADD", + "source": 22 + }, + { + "begin": 9420, + "end": 9450, + "name": "CALLDATALOAD", + "source": 22 + }, + { + "begin": 9507, + "end": 9521, + "name": "CALLDATASIZE", + "source": 22 + }, + { + "begin": 9503, + "end": 9531, + "name": "DUP5", + "source": 22 + }, + { + "begin": 9503, + "end": 9531, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 9503, + "end": 9531, + "name": "SUB", + "source": 22 + }, + { + "begin": 9533, + "end": 9599, + "name": "PUSH", + "source": 22, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1" + }, + { + "begin": 9499, + "end": 9600, + "name": "ADD", + "source": 22 + }, + { + "begin": 9473, + "end": 9601, + "name": "DUP2", + "source": 22 + }, + { + "begin": 9473, + "end": 9601, + "name": "SLT", + "source": 22 + }, + { + "begin": 9463, + "end": 9619, + "name": "PUSH [tag]", + "source": 22, + "value": "476" + }, + { + "begin": 9463, + "end": 9619, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 9615, + "end": 9616, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 9612, + "end": 9613, + "name": "DUP1", + "source": 22 + }, + { + "begin": 9605, + "end": 9617, + "name": "REVERT", + "source": 22 + }, + { + "begin": 9463, + "end": 9619, + "name": "tag", + "source": 22, + "value": "476" + }, + { + "begin": 9463, + "end": 9619, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 9647, + "end": 9681, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 9647, + "end": 9681, + "name": "SWAP3", + "source": 22 + }, + { + "begin": 9647, + "end": 9681, + "name": "ADD", + "source": 22 + }, + { + "begin": 9759, + "end": 9775, + "name": "DUP8", + "source": 22 + }, + { + "begin": 9759, + "end": 9775, + "name": "DUP2", + "source": 22 + }, + { + "begin": 9759, + "end": 9775, + "name": "ADD", + "source": 22 + }, + { + "begin": 9759, + "end": 9775, + "name": "SWAP3", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "SWAP1", + "source": -1 + }, + { + "begin": 9710, + "end": 9731, + "name": "CALLDATALOAD", + "source": 22 + }, + { + "begin": 9804, + "end": 9822, + "name": "PUSH", + "source": 22, + "value": "FFFFFFFFFFFFFFFF" + }, + { + "begin": 9791, + "end": 9823, + "name": "DUP2", + "source": 22 + }, + { + "begin": 9791, + "end": 9823, + "name": "GT", + "source": 22 + }, + { + "begin": 9788, + "end": 9840, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 9788, + "end": 9840, + "name": "PUSH [tag]", + "source": 22, + "value": "477" + }, + { + "begin": 9788, + "end": 9840, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 9836, + "end": 9837, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 9833, + "end": 9834, + "name": "DUP1", + "source": 22 + }, + { + "begin": 9826, + "end": 9838, + "name": "REVERT", + "source": 22 + }, + { + "begin": 9788, + "end": 9840, + "name": "tag", + "source": 22, + "value": "477" + }, + { + "begin": 9788, + "end": 9840, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 9889, + "end": 9897, + "name": "DUP1", + "source": 22 + }, + { + "begin": 9873, + "end": 9887, + "name": "CALLDATASIZE", + "source": 22 + }, + { + "begin": 9869, + "end": 9898, + "name": "SUB", + "source": 22 + }, + { + "begin": 9860, + "end": 9867, + "name": "DUP5", + "source": 22 + }, + { + "begin": 9856, + "end": 9899, + "name": "SGT", + "source": 22 + }, + { + "begin": 9853, + "end": 9916, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 9853, + "end": 9916, + "name": "PUSH [tag]", + "source": 22, + "value": "478" + }, + { + "begin": 9853, + "end": 9916, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 9912, + "end": 9913, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 9909, + "end": 9910, + "name": "DUP1", + "source": 22 + }, + { + "begin": 9902, + "end": 9914, + "name": "REVERT", + "source": 22 + }, + { + "begin": 9853, + "end": 9916, + "name": "tag", + "source": 22, + "value": "478" + }, + { + "begin": 9853, + "end": 9916, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 9951, + "end": 9953, + "name": "DUP3", + "source": 22 + }, + { + "begin": 9946, + "end": 9948, + "name": "DUP3", + "source": 22 + }, + { + "begin": 9940, + "end": 9944, + "name": "DUP10", + "source": 22 + }, + { + "begin": 9936, + "end": 9949, + "name": "ADD", + "source": 22 + }, + { + "begin": 9929, + "end": 9954, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 9975, + "end": 10034, + "name": "PUSH [tag]", + "source": 22, + "value": "479" + }, + { + "begin": 10030, + "end": 10032, + "name": "DUP4", + "source": 22 + }, + { + "begin": 10024, + "end": 10028, + "name": "DUP10", + "source": 22 + }, + { + "begin": 10020, + "end": 10033, + "name": "ADD", + "source": 22 + }, + { + "begin": 10010, + "end": 10018, + "name": "DUP3", + "source": 22 + }, + { + "begin": 10001, + "end": 10008, + "name": "DUP7", + "source": 22 + }, + { + "begin": 9975, + "end": 10034, + "name": "PUSH [tag]", + "source": 22, + "value": "403" + }, + { + "begin": 9975, + "end": 10034, + "jumpType": "[in]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 9975, + "end": 10034, + "name": "tag", + "source": 22, + "value": "479" + }, + { + "begin": 9975, + "end": 10034, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 10092, + "end": 10104, + "name": "SWAP13", + "source": 22 + }, + { + "begin": 10092, + "end": 10104, + "name": "DUP10", + "source": 22 + }, + { + "begin": 10092, + "end": 10104, + "name": "ADD", + "source": 22 + }, + { + "begin": 10092, + "end": 10104, + "name": "SWAP13", + "source": 22 + }, + { + "begin": 9967, + "end": 10034, + "name": "SWAP8", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 10057, + "end": 10072, + "name": "SWAP3", + "source": 22 + }, + { + "begin": 10057, + "end": 10072, + "name": "DUP7", + "source": 22 + }, + { + "begin": 10057, + "end": 10072, + "name": "ADD", + "source": 22 + }, + { + "begin": 10057, + "end": 10072, + "name": "SWAP3", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 8501, + "end": 8502, + "name": "PUSH", + "source": 22, + "value": "1" + }, + { + "begin": 8494, + "end": 8503, + "name": "ADD", + "source": 22 + }, + { + "begin": 8465, + "end": 10114, + "name": "PUSH [tag]", + "source": 22, + "value": "469" + }, + { + "begin": 8465, + "end": 10114, + "name": "JUMP", + "source": 22 + }, + { + "begin": 8465, + "end": 10114, + "name": "tag", + "source": 22, + "value": "471" + }, + { + "begin": 8465, + "end": 10114, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 10130, + "end": 10134, + "name": "SWAP2", + "source": 22 + }, + { + "begin": 10130, + "end": 10134, + "name": "SWAP8", + "source": 22 + }, + { + "begin": 8112, + "end": 10140, + "name": "SWAP7", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 8112, + "end": 10140, + "jumpType": "[out]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 10145, + "end": 10739, + "name": "tag", + "source": 22, + "value": "101" + }, + { + "begin": 10145, + "end": 10739, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 10495, + "end": 10497, + "name": "PUSH", + "source": 22, + "value": "40" + }, + { + "begin": 10484, + "end": 10493, + "name": "DUP2", + "source": 22 + }, + { + "begin": 10477, + "end": 10498, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 10534, + "end": 10535, + "name": "PUSH", + "source": 22, + "value": "5" + }, + { + "begin": 10529, + "end": 10531, + "name": "PUSH", + "source": 22, + "value": "40" + }, + { + "begin": 10518, + "end": 10527, + "name": "DUP3", + "source": 22 + }, + { + "begin": 10514, + "end": 10532, + "name": "ADD", + "source": 22 + }, + { + "begin": 10507, + "end": 10536, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 10572, + "end": 10579, + "name": "PUSH", + "source": 22, + "value": "73656C663A000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 10567, + "end": 10569, + "name": "PUSH", + "source": 22, + "value": "60" + }, + { + "begin": 10556, + "end": 10565, + "name": "DUP3", + "source": 22 + }, + { + "begin": 10552, + "end": 10570, + "name": "ADD", + "source": 22 + }, + { + "begin": 10545, + "end": 10580, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 10618, + "end": 10621, + "name": "PUSH", + "source": 22, + "value": "80" + }, + { + "begin": 10611, + "end": 10615, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 10600, + "end": 10609, + "name": "DUP3", + "source": 22 + }, + { + "begin": 10596, + "end": 10616, + "name": "ADD", + "source": 22 + }, + { + "begin": 10589, + "end": 10622, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 10458, + "end": 10462, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 10639, + "end": 10733, + "name": "PUSH [tag]", + "source": 22, + "value": "86" + }, + { + "begin": 10728, + "end": 10731, + "name": "PUSH", + "source": 22, + "value": "80" + }, + { + "begin": 10717, + "end": 10726, + "name": "DUP4", + "source": 22 + }, + { + "begin": 10713, + "end": 10732, + "name": "ADD", + "source": 22 + }, + { + "begin": 10705, + "end": 10711, + "name": "DUP5", + "source": 22 + }, + { + "begin": 10697, + "end": 10703, + "name": "DUP7", + "source": 22 + }, + { + "begin": 10639, + "end": 10733, + "name": "PUSH [tag]", + "source": 22, + "value": "404" + }, + { + "begin": 10639, + "end": 10733, + "jumpType": "[in]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 10744, + "end": 11339, + "name": "tag", + "source": 22, + "value": "108" + }, + { + "begin": 10744, + "end": 11339, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 11094, + "end": 11096, + "name": "PUSH", + "source": 22, + "value": "40" + }, + { + "begin": 11083, + "end": 11092, + "name": "DUP2", + "source": 22 + }, + { + "begin": 11076, + "end": 11097, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 11133, + "end": 11134, + "name": "PUSH", + "source": 22, + "value": "6" + }, + { + "begin": 11128, + "end": 11130, + "name": "PUSH", + "source": 22, + "value": "40" + }, + { + "begin": 11117, + "end": 11126, + "name": "DUP3", + "source": 22 + }, + { + "begin": 11113, + "end": 11131, + "name": "ADD", + "source": 22 + }, + { + "begin": 11106, + "end": 11135, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 11171, + "end": 11179, + "name": "PUSH", + "source": 22, + "value": "67756573743A0000000000000000000000000000000000000000000000000000" + }, + { + "begin": 11166, + "end": 11168, + "name": "PUSH", + "source": 22, + "value": "60" + }, + { + "begin": 11155, + "end": 11164, + "name": "DUP3", + "source": 22 + }, + { + "begin": 11151, + "end": 11169, + "name": "ADD", + "source": 22 + }, + { + "begin": 11144, + "end": 11180, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 11218, + "end": 11221, + "name": "PUSH", + "source": 22, + "value": "80" + }, + { + "begin": 11211, + "end": 11215, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 11200, + "end": 11209, + "name": "DUP3", + "source": 22 + }, + { + "begin": 11196, + "end": 11216, + "name": "ADD", + "source": 22 + }, + { + "begin": 11189, + "end": 11222, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 11057, + "end": 11061, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 11239, + "end": 11333, + "name": "PUSH [tag]", + "source": 22, + "value": "86" + }, + { + "begin": 11328, + "end": 11331, + "name": "PUSH", + "source": 22, + "value": "80" + }, + { + "begin": 11317, + "end": 11326, + "name": "DUP4", + "source": 22 + }, + { + "begin": 11313, + "end": 11332, + "name": "ADD", + "source": 22 + }, + { + "begin": 11305, + "end": 11311, + "name": "DUP5", + "source": 22 + }, + { + "begin": 11297, + "end": 11303, + "name": "DUP7", + "source": 22 + }, + { + "begin": 11239, + "end": 11333, + "name": "PUSH [tag]", + "source": 22, + "value": "404" + }, + { + "begin": 11239, + "end": 11333, + "jumpType": "[in]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 11344, + "end": 11528, + "name": "tag", + "source": 22, + "value": "113" + }, + { + "begin": 11344, + "end": 11528, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 11396, + "end": 11473, + "name": "PUSH", + "source": 22, + "value": "4E487B7100000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 11393, + "end": 11394, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 11386, + "end": 11474, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 11493, + "end": 11497, + "name": "PUSH", + "source": 22, + "value": "32" + }, + { + "begin": 11490, + "end": 11491, + "name": "PUSH", + "source": 22, + "value": "4" + }, + { + "begin": 11483, + "end": 11498, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 11517, + "end": 11521, + "name": "PUSH", + "source": 22, + "value": "24" + }, + { + "begin": 11514, + "end": 11515, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 11507, + "end": 11522, + "name": "REVERT", + "source": 22 + }, + { + "begin": 11786, + "end": 12267, + "name": "tag", + "source": 22, + "value": "405" + }, + { + "begin": 11786, + "end": 12267, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 11827, + "end": 11830, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 11865, + "end": 11870, + "name": "DUP2", + "source": 22 + }, + { + "begin": 11859, + "end": 11871, + "name": "MLOAD", + "source": 22 + }, + { + "begin": 11892, + "end": 11898, + "name": "DUP1", + "source": 22 + }, + { + "begin": 11887, + "end": 11890, + "name": "DUP5", + "source": 22 + }, + { + "begin": 11880, + "end": 11899, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 11917, + "end": 11918, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 11927, + "end": 12089, + "name": "tag", + "source": 22, + "value": "487" + }, + { + "begin": 11927, + "end": 12089, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 11941, + "end": 11947, + "name": "DUP2", + "source": 22 + }, + { + "begin": 11938, + "end": 11939, + "name": "DUP2", + "source": 22 + }, + { + "begin": 11935, + "end": 11948, + "name": "LT", + "source": 22 + }, + { + "begin": 11927, + "end": 12089, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 11927, + "end": 12089, + "name": "PUSH [tag]", + "source": 22, + "value": "489" + }, + { + "begin": 11927, + "end": 12089, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 12003, + "end": 12007, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 12059, + "end": 12072, + "name": "DUP2", + "source": 22 + }, + { + "begin": 12059, + "end": 12072, + "name": "DUP6", + "source": 22 + }, + { + "begin": 12059, + "end": 12072, + "name": "ADD", + "source": 22 + }, + { + "begin": 12055, + "end": 12077, + "name": "DUP2", + "source": 22 + }, + { + "begin": 12055, + "end": 12077, + "name": "ADD", + "source": 22 + }, + { + "begin": 12049, + "end": 12078, + "name": "MLOAD", + "source": 22 + }, + { + "begin": 12031, + "end": 12042, + "name": "DUP7", + "source": 22 + }, + { + "begin": 12031, + "end": 12042, + "name": "DUP4", + "source": 22 + }, + { + "begin": 12031, + "end": 12042, + "name": "ADD", + "source": 22 + }, + { + "begin": 12027, + "end": 12047, + "name": "DUP3", + "source": 22 + }, + { + "begin": 12027, + "end": 12047, + "name": "ADD", + "source": 22 + }, + { + "begin": 12020, + "end": 12079, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 11956, + "end": 11968, + "name": "ADD", + "source": 22 + }, + { + "begin": 11927, + "end": 12089, + "name": "PUSH [tag]", + "source": 22, + "value": "487" + }, + { + "begin": 11927, + "end": 12089, + "name": "JUMP", + "source": 22 + }, + { + "begin": 11927, + "end": 12089, + "name": "tag", + "source": 22, + "value": "489" + }, + { + "begin": 11927, + "end": 12089, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 11931, + "end": 11934, + "name": "POP", + "source": 22 + }, + { + "begin": 12134, + "end": 12135, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 12127, + "end": 12131, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 12118, + "end": 12124, + "name": "DUP3", + "source": 22 + }, + { + "begin": 12113, + "end": 12116, + "name": "DUP7", + "source": 22 + }, + { + "begin": 12109, + "end": 12125, + "name": "ADD", + "source": 22 + }, + { + "begin": 12105, + "end": 12132, + "name": "ADD", + "source": 22 + }, + { + "begin": 12098, + "end": 12136, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 12256, + "end": 12260, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 12186, + "end": 12252, + "name": "PUSH", + "source": 22, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0" + }, + { + "begin": 12181, + "end": 12183, + "name": "PUSH", + "source": 22, + "value": "1F" + }, + { + "begin": 12173, + "end": 12179, + "name": "DUP4", + "source": 22 + }, + { + "begin": 12169, + "end": 12184, + "name": "ADD", + "source": 22 + }, + { + "begin": 12165, + "end": 12253, + "name": "AND", + "source": 22 + }, + { + "begin": 12160, + "end": 12163, + "name": "DUP6", + "source": 22 + }, + { + "begin": 12156, + "end": 12254, + "name": "ADD", + "source": 22 + }, + { + "begin": 12152, + "end": 12261, + "name": "ADD", + "source": 22 + }, + { + "begin": 12145, + "end": 12261, + "name": "SWAP2", + "source": 22 + }, + { + "begin": 12145, + "end": 12261, + "name": "POP", + "source": 22 + }, + { + "begin": 12145, + "end": 12261, + "name": "POP", + "source": 22 + }, + { + "begin": 11786, + "end": 12267, + "name": "SWAP3", + "source": 22 + }, + { + "begin": 11786, + "end": 12267, + "name": "SWAP2", + "source": 22 + }, + { + "begin": 11786, + "end": 12267, + "name": "POP", + "source": 22 + }, + { + "begin": 11786, + "end": 12267, + "name": "POP", + "source": 22 + }, + { + "begin": 11786, + "end": 12267, + "jumpType": "[out]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 12272, + "end": 12489, + "name": "tag", + "source": 22, + "value": "140" + }, + { + "begin": 12272, + "end": 12489, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 12419, + "end": 12421, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 12408, + "end": 12417, + "name": "DUP2", + "source": 22 + }, + { + "begin": 12401, + "end": 12422, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 12382, + "end": 12386, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 12439, + "end": 12483, + "name": "PUSH [tag]", + "source": 22, + "value": "82" + }, + { + "begin": 12479, + "end": 12481, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 12468, + "end": 12477, + "name": "DUP4", + "source": 22 + }, + { + "begin": 12464, + "end": 12482, + "name": "ADD", + "source": 22 + }, + { + "begin": 12456, + "end": 12462, + "name": "DUP5", + "source": 22 + }, + { + "begin": 12439, + "end": 12483, + "name": "PUSH [tag]", + "source": 22, + "value": "405" + }, + { + "begin": 12439, + "end": 12483, + "jumpType": "[in]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 13090, + "end": 13477, + "name": "tag", + "source": 22, + "value": "164" + }, + { + "begin": 13090, + "end": 13477, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 13187, + "end": 13191, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 13245, + "end": 13256, + "name": "DUP3", + "source": 22 + }, + { + "begin": 13232, + "end": 13257, + "name": "CALLDATALOAD", + "source": 22 + }, + { + "begin": 13335, + "end": 13401, + "name": "PUSH", + "source": 22, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF41" + }, + { + "begin": 13324, + "end": 13332, + "name": "DUP4", + "source": 22 + }, + { + "begin": 13308, + "end": 13322, + "name": "CALLDATASIZE", + "source": 22 + }, + { + "begin": 13304, + "end": 13333, + "name": "SUB", + "source": 22 + }, + { + "begin": 13300, + "end": 13402, + "name": "ADD", + "source": 22 + }, + { + "begin": 13280, + "end": 13298, + "name": "DUP2", + "source": 22 + }, + { + "begin": 13276, + "end": 13403, + "name": "SLT", + "source": 22 + }, + { + "begin": 13266, + "end": 13421, + "name": "PUSH [tag]", + "source": 22, + "value": "494" + }, + { + "begin": 13266, + "end": 13421, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 13417, + "end": 13418, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 13414, + "end": 13415, + "name": "DUP1", + "source": 22 + }, + { + "begin": 13407, + "end": 13419, + "name": "REVERT", + "source": 22 + }, + { + "begin": 13266, + "end": 13421, + "name": "tag", + "source": 22, + "value": "494" + }, + { + "begin": 13266, + "end": 13421, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 13438, + "end": 13471, + "name": "SWAP2", + "source": 22 + }, + { + "begin": 13438, + "end": 13471, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 13438, + "end": 13471, + "name": "SWAP2", + "source": 22 + }, + { + "begin": 13438, + "end": 13471, + "name": "ADD", + "source": 22 + }, + { + "begin": 13438, + "end": 13471, + "name": "SWAP3", + "source": 22 + }, + { + "begin": 13090, + "end": 13477, + "name": "SWAP2", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 13090, + "end": 13477, + "jumpType": "[out]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 13482, + "end": 13662, + "name": "tag", + "source": 22, + "value": "166" + }, + { + "begin": 13482, + "end": 13662, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 13538, + "end": 13544, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 13591, + "end": 13593, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 13579, + "end": 13588, + "name": "DUP3", + "source": 22 + }, + { + "begin": 13570, + "end": 13577, + "name": "DUP5", + "source": 22 + }, + { + "begin": 13566, + "end": 13589, + "name": "SUB", + "source": 22 + }, + { + "begin": 13562, + "end": 13594, + "name": "SLT", + "source": 22 + }, + { + "begin": 13559, + "end": 13611, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 13559, + "end": 13611, + "name": "PUSH [tag]", + "source": 22, + "value": "496" + }, + { + "begin": 13559, + "end": 13611, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 13607, + "end": 13608, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 13604, + "end": 13605, + "name": "DUP1", + "source": 22 + }, + { + "begin": 13597, + "end": 13609, + "name": "REVERT", + "source": 22 + }, + { + "begin": 13559, + "end": 13611, + "name": "tag", + "source": 22, + "value": "496" + }, + { + "begin": 13559, + "end": 13611, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 13630, + "end": 13656, + "name": "PUSH [tag]", + "source": 22, + "value": "82" + }, + { + "begin": 13646, + "end": 13655, + "name": "DUP3", + "source": 22 + }, + { + "begin": 13630, + "end": 13656, + "name": "PUSH [tag]", + "source": 22, + "value": "401" + }, + { + "begin": 13630, + "end": 13656, + "jumpType": "[in]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 13991, + "end": 14177, + "name": "tag", + "source": 22, + "value": "174" + }, + { + "begin": 13991, + "end": 14177, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 14050, + "end": 14056, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 14103, + "end": 14105, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 14091, + "end": 14100, + "name": "DUP3", + "source": 22 + }, + { + "begin": 14082, + "end": 14089, + "name": "DUP5", + "source": 22 + }, + { + "begin": 14078, + "end": 14101, + "name": "SUB", + "source": 22 + }, + { + "begin": 14074, + "end": 14106, + "name": "SLT", + "source": 22 + }, + { + "begin": 14071, + "end": 14123, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 14071, + "end": 14123, + "name": "PUSH [tag]", + "source": 22, + "value": "500" + }, + { + "begin": 14071, + "end": 14123, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 14119, + "end": 14120, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 14116, + "end": 14117, + "name": "DUP1", + "source": 22 + }, + { + "begin": 14109, + "end": 14121, + "name": "REVERT", + "source": 22 + }, + { + "begin": 14071, + "end": 14123, + "name": "tag", + "source": 22, + "value": "500" + }, + { + "begin": 14071, + "end": 14123, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 14142, + "end": 14171, + "name": "PUSH [tag]", + "source": 22, + "value": "82" + }, + { + "begin": 14161, + "end": 14170, + "name": "DUP3", + "source": 22 + }, + { + "begin": 14142, + "end": 14171, + "name": "PUSH [tag]", + "source": 22, + "value": "402" + }, + { + "begin": 14142, + "end": 14171, + "jumpType": "[in]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 14182, + "end": 14762, + "name": "tag", + "source": 22, + "value": "178" + }, + { + "begin": 14182, + "end": 14762, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 14259, + "end": 14263, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 14265, + "end": 14271, + "name": "DUP1", + "source": 22 + }, + { + "begin": 14325, + "end": 14336, + "name": "DUP4", + "source": 22 + }, + { + "begin": 14312, + "end": 14337, + "name": "CALLDATALOAD", + "source": 22 + }, + { + "begin": 14415, + "end": 14481, + "name": "PUSH", + "source": 22, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1" + }, + { + "begin": 14404, + "end": 14412, + "name": "DUP5", + "source": 22 + }, + { + "begin": 14388, + "end": 14402, + "name": "CALLDATASIZE", + "source": 22 + }, + { + "begin": 14384, + "end": 14413, + "name": "SUB", + "source": 22 + }, + { + "begin": 14380, + "end": 14482, + "name": "ADD", + "source": 22 + }, + { + "begin": 14360, + "end": 14378, + "name": "DUP2", + "source": 22 + }, + { + "begin": 14356, + "end": 14483, + "name": "SLT", + "source": 22 + }, + { + "begin": 14346, + "end": 14501, + "name": "PUSH [tag]", + "source": 22, + "value": "503" + }, + { + "begin": 14346, + "end": 14501, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 14497, + "end": 14498, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 14494, + "end": 14495, + "name": "DUP1", + "source": 22 + }, + { + "begin": 14487, + "end": 14499, + "name": "REVERT", + "source": 22 + }, + { + "begin": 14346, + "end": 14501, + "name": "tag", + "source": 22, + "value": "503" + }, + { + "begin": 14346, + "end": 14501, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 14524, + "end": 14557, + "name": "DUP4", + "source": 22 + }, + { + "begin": 14524, + "end": 14557, + "name": "ADD", + "source": 22 + }, + { + "begin": 14576, + "end": 14596, + "name": "DUP1", + "source": 22 + }, + { + "begin": 14576, + "end": 14596, + "name": "CALLDATALOAD", + "source": 22 + }, + { + "begin": 14576, + "end": 14596, + "name": "SWAP2", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 14619, + "end": 14637, + "name": "PUSH", + "source": 22, + "value": "FFFFFFFFFFFFFFFF" + }, + { + "begin": 14608, + "end": 14638, + "name": "DUP3", + "source": 22 + }, + { + "begin": 14608, + "end": 14638, + "name": "GT", + "source": 22 + }, + { + "begin": 14605, + "end": 14655, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 14605, + "end": 14655, + "name": "PUSH [tag]", + "source": 22, + "value": "504" + }, + { + "begin": 14605, + "end": 14655, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 14651, + "end": 14652, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 14648, + "end": 14649, + "name": "DUP1", + "source": 22 + }, + { + "begin": 14641, + "end": 14653, + "name": "REVERT", + "source": 22 + }, + { + "begin": 14605, + "end": 14655, + "name": "tag", + "source": 22, + "value": "504" + }, + { + "begin": 14605, + "end": 14655, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 14684, + "end": 14688, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 14672, + "end": 14689, + "name": "ADD", + "source": 22 + }, + { + "begin": 14672, + "end": 14689, + "name": "SWAP2", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 14715, + "end": 14729, + "name": "CALLDATASIZE", + "source": 22 + }, + { + "begin": 14711, + "end": 14738, + "name": "DUP2", + "source": 22 + }, + { + "begin": 14711, + "end": 14738, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 14711, + "end": 14738, + "name": "SUB", + "source": 22 + }, + { + "begin": 14701, + "end": 14739, + "name": "DUP3", + "source": 22 + }, + { + "begin": 14701, + "end": 14739, + "name": "SGT", + "source": 22 + }, + { + "begin": 14698, + "end": 14756, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 14698, + "end": 14756, + "name": "PUSH [tag]", + "source": 22, + "value": "417" + }, + { + "begin": 14698, + "end": 14756, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 14752, + "end": 14753, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 14749, + "end": 14750, + "name": "DUP1", + "source": 22 + }, + { + "begin": 14742, + "end": 14754, + "name": "REVERT", + "source": 22 + }, + { + "begin": 14767, + "end": 14951, + "name": "tag", + "source": 22, + "value": "406" + }, + { + "begin": 14767, + "end": 14951, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 14819, + "end": 14896, + "name": "PUSH", + "source": 22, + "value": "4E487B7100000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 14816, + "end": 14817, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 14809, + "end": 14897, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 14916, + "end": 14920, + "name": "PUSH", + "source": 22, + "value": "11" + }, + { + "begin": 14913, + "end": 14914, + "name": "PUSH", + "source": 22, + "value": "4" + }, + { + "begin": 14906, + "end": 14921, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 14940, + "end": 14944, + "name": "PUSH", + "source": 22, + "value": "24" + }, + { + "begin": 14937, + "end": 14938, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 14930, + "end": 14945, + "name": "REVERT", + "source": 22 + }, + { + "begin": 14956, + "end": 15151, + "name": "tag", + "source": 22, + "value": "189" + }, + { + "begin": 14956, + "end": 15151, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 14995, + "end": 14998, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 15026, + "end": 15092, + "name": "PUSH", + "source": 22, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { + "begin": 15019, + "end": 15024, + "name": "DUP3", + "source": 22 + }, + { + "begin": 15016, + "end": 15093, + "name": "SUB", + "source": 22 + }, + { + "begin": 15013, + "end": 15116, + "name": "PUSH [tag]", + "source": 22, + "value": "509" + }, + { + "begin": 15013, + "end": 15116, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 15096, + "end": 15114, + "name": "PUSH [tag]", + "source": 22, + "value": "509" + }, + { + "begin": 15096, + "end": 15114, + "name": "PUSH [tag]", + "source": 22, + "value": "406" + }, + { + "begin": 15096, + "end": 15114, + "jumpType": "[in]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 15096, + "end": 15114, + "name": "tag", + "source": 22, + "value": "509" + }, + { + "begin": 15096, + "end": 15114, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 15143, + "end": 15144, + "name": "PUSH", + "source": 22, + "value": "1" + }, + { + "begin": 15132, + "end": 15145, + "name": "ADD", + "source": 22 + }, + { + "begin": 15132, + "end": 15145, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 14956, + "end": 15151, + "jumpType": "[out]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 15156, + "end": 15487, + "name": "tag", + "source": 22, + "value": "193" + }, + { + "begin": 15156, + "end": 15487, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 15261, + "end": 15270, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 15272, + "end": 15281, + "name": "DUP1", + "source": 22 + }, + { + "begin": 15314, + "end": 15322, + "name": "DUP6", + "source": 22 + }, + { + "begin": 15302, + "end": 15312, + "name": "DUP6", + "source": 22 + }, + { + "begin": 15299, + "end": 15323, + "name": "GT", + "source": 22 + }, + { + "begin": 15296, + "end": 15340, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 15296, + "end": 15340, + "name": "PUSH [tag]", + "source": 22, + "value": "511" + }, + { + "begin": 15296, + "end": 15340, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 15336, + "end": 15337, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 15333, + "end": 15334, + "name": "DUP1", + "source": 22 + }, + { + "begin": 15326, + "end": 15338, + "name": "REVERT", + "source": 22 + }, + { + "begin": 15296, + "end": 15340, + "name": "tag", + "source": 22, + "value": "511" + }, + { + "begin": 15296, + "end": 15340, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 15365, + "end": 15371, + "name": "DUP4", + "source": 22 + }, + { + "begin": 15355, + "end": 15363, + "name": "DUP7", + "source": 22 + }, + { + "begin": 15352, + "end": 15372, + "name": "GT", + "source": 22 + }, + { + "begin": 15349, + "end": 15389, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 15349, + "end": 15389, + "name": "PUSH [tag]", + "source": 22, + "value": "512" + }, + { + "begin": 15349, + "end": 15389, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 15385, + "end": 15386, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 15382, + "end": 15383, + "name": "DUP1", + "source": 22 + }, + { + "begin": 15375, + "end": 15387, + "name": "REVERT", + "source": 22 + }, + { + "begin": 15349, + "end": 15389, + "name": "tag", + "source": 22, + "value": "512" + }, + { + "begin": 15349, + "end": 15389, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 15411, + "end": 15434, + "name": "DUP3", + "source": 22 + }, + { + "begin": 15411, + "end": 15434, + "name": "ADD", + "source": 22 + }, + { + "begin": 15411, + "end": 15434, + "name": "SWAP4", + "source": 22 + }, + { + "begin": 15456, + "end": 15481, + "name": "SWAP2", + "source": 22 + }, + { + "begin": 15456, + "end": 15481, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 15456, + "end": 15481, + "name": "SWAP3", + "source": 22 + }, + { + "begin": 15456, + "end": 15481, + "name": "SUB", + "source": 22 + }, + { + "begin": 15456, + "end": 15481, + "name": "SWAP2", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 15156, + "end": 15487, + "jumpType": "[out]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 15492, + "end": 15617, + "name": "tag", + "source": 22, + "value": "211" + }, + { + "begin": 15492, + "end": 15617, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 15557, + "end": 15566, + "name": "DUP1", + "source": 22 + }, + { + "begin": 15557, + "end": 15566, + "name": "DUP3", + "source": 22 + }, + { + "begin": 15557, + "end": 15566, + "name": "ADD", + "source": 22 + }, + { + "begin": 15578, + "end": 15588, + "name": "DUP1", + "source": 22 + }, + { + "begin": 15578, + "end": 15588, + "name": "DUP3", + "source": 22 + }, + { + "begin": 15578, + "end": 15588, + "name": "GT", + "source": 22 + }, + { + "begin": 15575, + "end": 15611, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 15575, + "end": 15611, + "name": "PUSH [tag]", + "source": 22, + "value": "80" + }, + { + "begin": 15575, + "end": 15611, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 15591, + "end": 15609, + "name": "PUSH [tag]", + "source": 22, + "value": "80" + }, + { + "begin": 15591, + "end": 15609, + "name": "PUSH [tag]", + "source": 22, + "value": "406" + }, + { + "begin": 15591, + "end": 15609, + "jumpType": "[in]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 15622, + "end": 16014, + "name": "tag", + "source": 22, + "value": "217" + }, + { + "begin": 15622, + "end": 16014, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 15841, + "end": 15843, + "name": "PUSH", + "source": 22, + "value": "60" + }, + { + "begin": 15830, + "end": 15839, + "name": "DUP2", + "source": 22 + }, + { + "begin": 15823, + "end": 15844, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 15804, + "end": 15808, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 15861, + "end": 15922, + "name": "PUSH [tag]", + "source": 22, + "value": "517" + }, + { + "begin": 15918, + "end": 15920, + "name": "PUSH", + "source": 22, + "value": "60" + }, + { + "begin": 15907, + "end": 15916, + "name": "DUP4", + "source": 22 + }, + { + "begin": 15903, + "end": 15921, + "name": "ADD", + "source": 22 + }, + { + "begin": 15895, + "end": 15901, + "name": "DUP7", + "source": 22 + }, + { + "begin": 15887, + "end": 15893, + "name": "DUP9", + "source": 22 + }, + { + "begin": 15861, + "end": 15922, + "name": "PUSH [tag]", + "source": 22, + "value": "403" + }, + { + "begin": 15861, + "end": 15922, + "jumpType": "[in]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 15861, + "end": 15922, + "name": "tag", + "source": 22, + "value": "517" + }, + { + "begin": 15861, + "end": 15922, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 15953, + "end": 15955, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 15938, + "end": 15956, + "name": "DUP4", + "source": 22 + }, + { + "begin": 15938, + "end": 15956, + "name": "ADD", + "source": 22 + }, + { + "begin": 15931, + "end": 15965, + "name": "SWAP5", + "source": 22 + }, + { + "begin": 15931, + "end": 15965, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 15931, + "end": 15965, + "name": "SWAP5", + "source": 22 + }, + { + "begin": 15931, + "end": 15965, + "name": "MSTORE", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 15996, + "end": 15998, + "name": "PUSH", + "source": 22, + "value": "40" + }, + { + "begin": 15981, + "end": 15999, + "name": "ADD", + "source": 22 + }, + { + "begin": 15974, + "end": 16008, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 15853, + "end": 15922, + "name": "SWAP3", + "source": 22 + }, + { + "begin": 15622, + "end": 16014, + "name": "SWAP2", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 15622, + "end": 16014, + "jumpType": "[out]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 16525, + "end": 16813, + "name": "tag", + "source": 22, + "value": "246" + }, + { + "begin": 16525, + "end": 16813, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 16700, + "end": 16706, + "name": "DUP3", + "source": 22 + }, + { + "begin": 16689, + "end": 16698, + "name": "DUP2", + "source": 22 + }, + { + "begin": 16682, + "end": 16707, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 16743, + "end": 16745, + "name": "PUSH", + "source": 22, + "value": "40" + }, + { + "begin": 16738, + "end": 16740, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 16727, + "end": 16736, + "name": "DUP3", + "source": 22 + }, + { + "begin": 16723, + "end": 16741, + "name": "ADD", + "source": 22 + }, + { + "begin": 16716, + "end": 16746, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 16663, + "end": 16667, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 16763, + "end": 16807, + "name": "PUSH [tag]", + "source": 22, + "value": "86" + }, + { + "begin": 16803, + "end": 16805, + "name": "PUSH", + "source": 22, + "value": "40" + }, + { + "begin": 16792, + "end": 16801, + "name": "DUP4", + "source": 22 + }, + { + "begin": 16788, + "end": 16806, + "name": "ADD", + "source": 22 + }, + { + "begin": 16780, + "end": 16786, + "name": "DUP5", + "source": 22 + }, + { + "begin": 16763, + "end": 16807, + "name": "PUSH [tag]", + "source": 22, + "value": "405" + }, + { + "begin": 16763, + "end": 16807, + "jumpType": "[in]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 16818, + "end": 17259, + "name": "tag", + "source": 22, + "value": "278" + }, + { + "begin": 16818, + "end": 17259, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 17037, + "end": 17043, + "name": "DUP5", + "source": 22 + }, + { + "begin": 17026, + "end": 17035, + "name": "DUP2", + "source": 22 + }, + { + "begin": 17019, + "end": 17044, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 17092, + "end": 17134, + "name": "PUSH", + "source": 22, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { + "begin": 17084, + "end": 17090, + "name": "DUP5", + "source": 22 + }, + { + "begin": 17080, + "end": 17135, + "name": "AND", + "source": 22 + }, + { + "begin": 17075, + "end": 17077, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 17064, + "end": 17073, + "name": "DUP3", + "source": 22 + }, + { + "begin": 17060, + "end": 17078, + "name": "ADD", + "source": 22 + }, + { + "begin": 17053, + "end": 17136, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 17172, + "end": 17174, + "name": "PUSH", + "source": 22, + "value": "60" + }, + { + "begin": 17167, + "end": 17169, + "name": "PUSH", + "source": 22, + "value": "40" + }, + { + "begin": 17156, + "end": 17165, + "name": "DUP3", + "source": 22 + }, + { + "begin": 17152, + "end": 17170, + "name": "ADD", + "source": 22 + }, + { + "begin": 17145, + "end": 17175, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 17000, + "end": 17004, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 17192, + "end": 17253, + "name": "PUSH [tag]", + "source": 22, + "value": "523" + }, + { + "begin": 17249, + "end": 17251, + "name": "PUSH", + "source": 22, + "value": "60" + }, + { + "begin": 17238, + "end": 17247, + "name": "DUP4", + "source": 22 + }, + { + "begin": 17234, + "end": 17252, + "name": "ADD", + "source": 22 + }, + { + "begin": 17226, + "end": 17232, + "name": "DUP5", + "source": 22 + }, + { + "begin": 17218, + "end": 17224, + "name": "DUP7", + "source": 22 + }, + { + "begin": 17192, + "end": 17253, + "name": "PUSH [tag]", + "source": 22, + "value": "403" + }, + { + "begin": 17192, + "end": 17253, + "jumpType": "[in]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 17192, + "end": 17253, + "name": "tag", + "source": 22, + "value": "523" + }, + { + "begin": 17192, + "end": 17253, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 17184, + "end": 17253, + "name": "SWAP7", + "source": 22 + }, + { + "begin": 16818, + "end": 17259, + "name": "SWAP6", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 16818, + "end": 17259, + "jumpType": "[out]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 17264, + "end": 17508, + "name": "tag", + "source": 22, + "value": "333" + }, + { + "begin": 17264, + "end": 17508, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 17421, + "end": 17423, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 17410, + "end": 17419, + "name": "DUP2", + "source": 22 + }, + { + "begin": 17403, + "end": 17424, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 17384, + "end": 17388, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 17441, + "end": 17502, + "name": "PUSH [tag]", + "source": 22, + "value": "86" + }, + { + "begin": 17498, + "end": 17500, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 17487, + "end": 17496, + "name": "DUP4", + "source": 22 + }, + { + "begin": 17483, + "end": 17501, + "name": "ADD", + "source": 22 + }, + { + "begin": 17475, + "end": 17481, + "name": "DUP5", + "source": 22 + }, + { + "begin": 17467, + "end": 17473, + "name": "DUP7", + "source": 22 + }, + { + "begin": 17441, + "end": 17502, + "name": "PUSH [tag]", + "source": 22, + "value": "403" + }, + { + "begin": 17441, + "end": 17502, + "jumpType": "[in]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 17513, + "end": 17641, + "name": "tag", + "source": 22, + "value": "336" + }, + { + "begin": 17513, + "end": 17641, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 17580, + "end": 17589, + "name": "DUP2", + "source": 22 + }, + { + "begin": 17580, + "end": 17589, + "name": "DUP2", + "source": 22 + }, + { + "begin": 17580, + "end": 17589, + "name": "SUB", + "source": 22 + }, + { + "begin": 17601, + "end": 17612, + "name": "DUP2", + "source": 22 + }, + { + "begin": 17601, + "end": 17612, + "name": "DUP2", + "source": 22 + }, + { + "begin": 17601, + "end": 17612, + "name": "GT", + "source": 22 + }, + { + "begin": 17598, + "end": 17635, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 17598, + "end": 17635, + "name": "PUSH [tag]", + "source": 22, + "value": "80" + }, + { + "begin": 17598, + "end": 17635, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 17615, + "end": 17633, + "name": "PUSH [tag]", + "source": 22, + "value": "80" + }, + { + "begin": 17615, + "end": 17633, + "name": "PUSH [tag]", + "source": 22, + "value": "406" + }, + { + "begin": 17615, + "end": 17633, + "jumpType": "[in]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 17646, + "end": 17961, + "name": "tag", + "source": 22, + "value": "344" + }, + { + "begin": 17646, + "end": 17961, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 17831, + "end": 17833, + "name": "PUSH", + "source": 22, + "value": "40" + }, + { + "begin": 17820, + "end": 17829, + "name": "DUP2", + "source": 22 + }, + { + "begin": 17813, + "end": 17834, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 17794, + "end": 17798, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 17851, + "end": 17912, + "name": "PUSH [tag]", + "source": 22, + "value": "530" + }, + { + "begin": 17908, + "end": 17910, + "name": "PUSH", + "source": 22, + "value": "40" + }, + { + "begin": 17897, + "end": 17906, + "name": "DUP4", + "source": 22 + }, + { + "begin": 17893, + "end": 17911, + "name": "ADD", + "source": 22 + }, + { + "begin": 17885, + "end": 17891, + "name": "DUP6", + "source": 22 + }, + { + "begin": 17877, + "end": 17883, + "name": "DUP8", + "source": 22 + }, + { + "begin": 17851, + "end": 17912, + "name": "PUSH [tag]", + "source": 22, + "value": "403" + }, + { + "begin": 17851, + "end": 17912, + "jumpType": "[in]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 17851, + "end": 17912, + "name": "tag", + "source": 22, + "value": "530" + }, + { + "begin": 17851, + "end": 17912, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 17843, + "end": 17912, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 17843, + "end": 17912, + "name": "POP", + "source": 22 + }, + { + "begin": 17948, + "end": 17954, + "name": "DUP3", + "source": 22 + }, + { + "begin": 17943, + "end": 17945, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 17932, + "end": 17941, + "name": "DUP4", + "source": 22 + }, + { + "begin": 17928, + "end": 17946, + "name": "ADD", + "source": 22 + }, + { + "begin": 17921, + "end": 17955, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 17646, + "end": 17961, + "name": "SWAP5", + "source": 22 + }, + { + "begin": 17646, + "end": 17961, + "name": "SWAP4", + "source": 22 + }, + { + "begin": 17646, + "end": 17961, + "name": "POP", + "source": 22 + }, + { + "begin": 17646, + "end": 17961, + "name": "POP", + "source": 22 + }, + { + "begin": 17646, + "end": 17961, + "name": "POP", + "source": 22 + }, + { + "begin": 17646, + "end": 17961, + "name": "POP", + "source": 22 + }, + { + "begin": 17646, + "end": 17961, + "jumpType": "[out]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 17966, + "end": 18290, + "name": "tag", + "source": 22, + "value": "348" + }, + { + "begin": 17966, + "end": 18290, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 18149, + "end": 18151, + "name": "PUSH", + "source": 22, + "value": "40" + }, + { + "begin": 18138, + "end": 18147, + "name": "DUP2", + "source": 22 + }, + { + "begin": 18131, + "end": 18152, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 18112, + "end": 18116, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 18169, + "end": 18230, + "name": "PUSH [tag]", + "source": 22, + "value": "532" + }, + { + "begin": 18226, + "end": 18228, + "name": "PUSH", + "source": 22, + "value": "40" + }, + { + "begin": 18215, + "end": 18224, + "name": "DUP4", + "source": 22 + }, + { + "begin": 18211, + "end": 18229, + "name": "ADD", + "source": 22 + }, + { + "begin": 18203, + "end": 18209, + "name": "DUP6", + "source": 22 + }, + { + "begin": 18195, + "end": 18201, + "name": "DUP8", + "source": 22 + }, + { + "begin": 18169, + "end": 18230, + "name": "PUSH [tag]", + "source": 22, + "value": "403" + }, + { + "begin": 18169, + "end": 18230, + "jumpType": "[in]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 18169, + "end": 18230, + "name": "tag", + "source": 22, + "value": "532" + }, + { + "begin": 18169, + "end": 18230, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 18161, + "end": 18230, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 18161, + "end": 18230, + "name": "POP", + "source": 22 + }, + { + "begin": 18278, + "end": 18282, + "name": "PUSH", + "source": 22, + "value": "FF" + }, + { + "begin": 18270, + "end": 18276, + "name": "DUP4", + "source": 22 + }, + { + "begin": 18266, + "end": 18283, + "name": "AND", + "source": 22 + }, + { + "begin": 18261, + "end": 18263, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 18250, + "end": 18259, + "name": "DUP4", + "source": 22 + }, + { + "begin": 18246, + "end": 18264, + "name": "ADD", + "source": 22 + }, + { + "begin": 18239, + "end": 18284, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 17966, + "end": 18290, + "name": "SWAP5", + "source": 22 + }, + { + "begin": 17966, + "end": 18290, + "name": "SWAP4", + "source": 22 + }, + { + "begin": 17966, + "end": 18290, + "name": "POP", + "source": 22 + }, + { + "begin": 17966, + "end": 18290, + "name": "POP", + "source": 22 + }, + { + "begin": 17966, + "end": 18290, + "name": "POP", + "source": 22 + }, + { + "begin": 17966, + "end": 18290, + "name": "POP", + "source": 22 + }, + { + "begin": 17966, + "end": 18290, + "jumpType": "[out]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 19083, + "end": 19479, + "name": "tag", + "source": 22, + "value": "363" + }, + { + "begin": 19083, + "end": 19479, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 19290, + "end": 19292, + "name": "PUSH", + "source": 22, + "value": "60" + }, + { + "begin": 19279, + "end": 19288, + "name": "DUP2", + "source": 22 + }, + { + "begin": 19272, + "end": 19293, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 19253, + "end": 19257, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 19310, + "end": 19371, + "name": "PUSH [tag]", + "source": 22, + "value": "536" + }, + { + "begin": 19367, + "end": 19369, + "name": "PUSH", + "source": 22, + "value": "60" + }, + { + "begin": 19356, + "end": 19365, + "name": "DUP4", + "source": 22 + }, + { + "begin": 19352, + "end": 19370, + "name": "ADD", + "source": 22 + }, + { + "begin": 19344, + "end": 19350, + "name": "DUP7", + "source": 22 + }, + { + "begin": 19336, + "end": 19342, + "name": "DUP9", + "source": 22 + }, + { + "begin": 19310, + "end": 19371, + "name": "PUSH [tag]", + "source": 22, + "value": "403" + }, + { + "begin": 19310, + "end": 19371, + "jumpType": "[in]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 19310, + "end": 19371, + "name": "tag", + "source": 22, + "value": "536" + }, + { + "begin": 19310, + "end": 19371, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 19402, + "end": 19404, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 19387, + "end": 19405, + "name": "DUP4", + "source": 22 + }, + { + "begin": 19387, + "end": 19405, + "name": "ADD", + "source": 22 + }, + { + "begin": 19380, + "end": 19414, + "name": "SWAP5", + "source": 22 + }, + { + "begin": 19380, + "end": 19414, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 19380, + "end": 19414, + "name": "SWAP5", + "source": 22 + }, + { + "begin": 19380, + "end": 19414, + "name": "MSTORE", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 19457, + "end": 19471, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 19457, + "end": 19471, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 19450, + "end": 19472, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 19445, + "end": 19447, + "name": "PUSH", + "source": 22, + "value": "40" + }, + { + "begin": 19430, + "end": 19448, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 19430, + "end": 19448, + "name": "SWAP2", + "source": 22 + }, + { + "begin": 19430, + "end": 19448, + "name": "ADD", + "source": 22 + }, + { + "begin": 19423, + "end": 19473, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 19302, + "end": 19371, + "name": "SWAP3", + "source": 22 + }, + { + "begin": 19083, + "end": 19479, + "name": "SWAP2", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 19083, + "end": 19479, + "jumpType": "[out]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 19484, + "end": 19805, + "name": "tag", + "source": 22, + "value": "379" + }, + { + "begin": 19484, + "end": 19805, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 19675, + "end": 19681, + "name": "DUP4", + "source": 22 + }, + { + "begin": 19664, + "end": 19673, + "name": "DUP2", + "source": 22 + }, + { + "begin": 19657, + "end": 19682, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 19718, + "end": 19720, + "name": "PUSH", + "source": 22, + "value": "40" + }, + { + "begin": 19713, + "end": 19715, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 19702, + "end": 19711, + "name": "DUP3", + "source": 22 + }, + { + "begin": 19698, + "end": 19716, + "name": "ADD", + "source": 22 + }, + { + "begin": 19691, + "end": 19721, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 19638, + "end": 19642, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 19738, + "end": 19799, + "name": "PUSH [tag]", + "source": 22, + "value": "538" + }, + { + "begin": 19795, + "end": 19797, + "name": "PUSH", + "source": 22, + "value": "40" + }, + { + "begin": 19784, + "end": 19793, + "name": "DUP4", + "source": 22 + }, + { + "begin": 19780, + "end": 19798, + "name": "ADD", + "source": 22 + }, + { + "begin": 19772, + "end": 19778, + "name": "DUP5", + "source": 22 + }, + { + "begin": 19764, + "end": 19770, + "name": "DUP7", + "source": 22 + }, + { + "begin": 19738, + "end": 19799, + "name": "PUSH [tag]", + "source": 22, + "value": "403" + }, + { + "begin": 19738, + "end": 19799, + "jumpType": "[in]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 19738, + "end": 19799, + "name": "tag", + "source": 22, + "value": "538" + }, + { + "begin": 19738, + "end": 19799, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 19730, + "end": 19799, + "name": "SWAP6", + "source": 22 + }, + { + "begin": 19484, + "end": 19805, + "name": "SWAP5", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 19484, + "end": 19805, + "jumpType": "[out]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 19810, + "end": 20059, + "name": "tag", + "source": 22, + "value": "383" + }, + { + "begin": 19810, + "end": 20059, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 19879, + "end": 19885, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 19932, + "end": 19934, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 19920, + "end": 19929, + "name": "DUP3", + "source": 22 + }, + { + "begin": 19911, + "end": 19918, + "name": "DUP5", + "source": 22 + }, + { + "begin": 19907, + "end": 19930, + "name": "SUB", + "source": 22 + }, + { + "begin": 19903, + "end": 19935, + "name": "SLT", + "source": 22 + }, + { + "begin": 19900, + "end": 19952, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 19900, + "end": 19952, + "name": "PUSH [tag]", + "source": 22, + "value": "540" + }, + { + "begin": 19900, + "end": 19952, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 19948, + "end": 19949, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 19945, + "end": 19946, + "name": "DUP1", + "source": 22 + }, + { + "begin": 19938, + "end": 19950, + "name": "REVERT", + "source": 22 + }, + { + "begin": 19900, + "end": 19952, + "name": "tag", + "source": 22, + "value": "540" + }, + { + "begin": 19900, + "end": 19952, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 19980, + "end": 19989, + "name": "DUP2", + "source": 22 + }, + { + "begin": 19974, + "end": 19990, + "name": "MLOAD", + "source": 22 + }, + { + "begin": 19999, + "end": 20029, + "name": "PUSH [tag]", + "source": 22, + "value": "82" + }, + { + "begin": 20023, + "end": 20028, + "name": "DUP2", + "source": 22 + }, + { + "begin": 19999, + "end": 20029, + "name": "PUSH [tag]", + "source": 22, + "value": "397" + }, + { + "begin": 19999, + "end": 20029, + "jumpType": "[in]", + "name": "JUMP", + "source": 22 + } + ] + } + }, + "sourceList": [ + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/interfaces/IERC1271Wallet.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleERC165.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleOnlyDelegatecall.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCalls.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCreator.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol", + "#utility.yul" + ] + }, + "methodIdentifiers": { + "SET_IMAGE_HASH_TYPE_HASH()": "57c56d6b", + "createContract(bytes)": "90042baf", + "execute((bool,bool,uint256,address,uint256,bytes)[],uint256,bytes)": "7a9a1628", + "isValidSignature(bytes,bytes)": "20c13b0b", + "isValidSignature(bytes32,bytes)": "1626ba7e", + "nonce()": "affed0e0", + "readNonce(uint256)": "8c3f5563", + "selfExecute((bool,bool,uint256,address,uint256,bytes)[])": "61c2926c", + "signatureRecovery(bytes32,bytes)": "853c5068", + "supportsInterface(bytes4)": "01ffc9a7", + "updateImageHash(bytes32)": "29561426" + } + }, + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_space\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_provided\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_current\",\"type\":\"uint256\"}],\"name\":\"BadNonce\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_code\",\"type\":\"bytes\"}],\"name\":\"CreateFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"DelegateCallNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptySignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ImageHashIsZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_hash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"InvalidNestedSignature\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"},{\"internalType\":\"bytes32\",\"name\":\"_s\",\"type\":\"bytes32\"}],\"name\":\"InvalidSValue\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_hash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_flag\",\"type\":\"uint256\"}],\"name\":\"InvalidSignatureFlag\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"InvalidSignatureLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes1\",\"name\":\"_type\",\"type\":\"bytes1\"}],\"name\":\"InvalidSignatureType\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_v\",\"type\":\"uint256\"}],\"name\":\"InvalidVValue\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_weight\",\"type\":\"uint256\"}],\"name\":\"LowWeightChainedSignature\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_requested\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_available\",\"type\":\"uint256\"}],\"name\":\"NotEnoughGas\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotSupported\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyDelegatecall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_self\",\"type\":\"address\"}],\"name\":\"OnlySelfAuth\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"SignerIsAddress0\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_type\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"_recoverMode\",\"type\":\"bool\"}],\"name\":\"UnsupportedSignatureType\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_current\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_prev\",\"type\":\"uint256\"}],\"name\":\"WrongChainedCheckpointOrder\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_contract\",\"type\":\"address\"}],\"name\":\"CreatedContract\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"newImageHash\",\"type\":\"bytes32\"}],\"name\":\"ImageHashUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_space\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_newNonce\",\"type\":\"uint256\"}],\"name\":\"NonceChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_tx\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"TxExecuted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_tx\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_reason\",\"type\":\"bytes\"}],\"name\":\"TxFailed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"SET_IMAGE_HASH_TYPE_HASH\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_code\",\"type\":\"bytes\"}],\"name\":\"createContract\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"delegateCall\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"revertOnError\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"struct IModuleCalls.Transaction[]\",\"name\":\"_txs\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_hash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_signatures\",\"type\":\"bytes\"}],\"name\":\"isValidSignature\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"_signatures\",\"type\":\"bytes\"}],\"name\":\"isValidSignature\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_space\",\"type\":\"uint256\"}],\"name\":\"readNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"delegateCall\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"revertOnError\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"struct IModuleCalls.Transaction[]\",\"name\":\"_txs\",\"type\":\"tuple[]\"}],\"name\":\"selfExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_digest\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"signatureRecovery\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"imageHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"subdigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"checkpoint\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_interfaceID\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_imageHash\",\"type\":\"bytes32\"}],\"name\":\"updateImageHash\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"createContract(bytes)\":{\"params\":{\"_code\":\"Creation code of the contract\"},\"returns\":{\"addr\":\"The address of the created contract\"}},\"execute((bool,bool,uint256,address,uint256,bytes)[],uint256,bytes)\":{\"params\":{\"_txs\":\"Transactions to process\"}},\"isValidSignature(bytes,bytes)\":{\"details\":\"MUST return the correct magic value if the signature provided is valid for the provided data > The bytes4 magic value to return when signature is valid is 0x20c13b0b : bytes4(keccak256(\\\"isValidSignature(bytes,bytes)\\\"))\",\"params\":{\"_data\":\"Arbitrary length data signed on the behalf of address(this)\",\"_signatures\":\"Signature byte array associated with _data. Encoded as abi.encode(Signature[], Configs)\"},\"returns\":{\"_0\":\"magicValue Magic value 0x20c13b0b if the signature is valid and 0x0 otherwise\"}},\"isValidSignature(bytes32,bytes)\":{\"details\":\"MUST return the correct magic value if the signature provided is valid for the provided hash > The bytes4 magic value to return when signature is valid is 0x1626ba7e : bytes4(keccak256(\\\"isValidSignature(bytes32,bytes)\\\"))\",\"params\":{\"_hash\":\"keccak256 hash that was signed\",\"_signatures\":\"Signature byte array associated with _data. Encoded as abi.encode(Signature[], Configs)\"},\"returns\":{\"_0\":\"magicValue Magic value 0x1626ba7e if the signature is valid and 0x0 otherwise\"}},\"nonce()\":{\"details\":\"The default nonce space is 0x00\",\"returns\":{\"_0\":\"The next nonce\"}},\"readNonce(uint256)\":{\"params\":{\"_space\":\"Nonce space, each space keeps an independent nonce count\"},\"returns\":{\"_0\":\"The next nonce\"}},\"selfExecute((bool,bool,uint256,address,uint256,bytes)[])\":{\"params\":{\"_txs\":\"Transactions to process\"}},\"signatureRecovery(bytes32,bytes)\":{\"details\":\"The signature must be prefixed with a type byte, which is used to determine the recovery method.\",\"params\":{\"_digest\":\"Digest of the signed data.\",\"_signature\":\"A Sequence signature.\"},\"returns\":{\"checkpoint\":\"A nonce that is incremented every time a new configuration is set.\",\"imageHash\":\"The imageHash of the configuration that signed the message.\",\"subdigest\":\"A modified version of the original digest, unique for each wallet/network.\",\"threshold\":\"The required number of signatures needed to consider the signature valid.\",\"weight\":\"The actual number of signatures collected in the signature.\"}},\"supportsInterface(bytes4)\":{\"params\":{\"_interfaceID\":\"The interface identifier, as specified in ERC-165\"},\"returns\":{\"_0\":\"`true` if the contract implements `_interfaceID`\"}},\"updateImageHash(bytes32)\":{\"params\":{\"_imageHash\":\"New required image hash of the signature\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"createContract(bytes)\":{\"notice\":\"Creates a contract forwarding eth value\"},\"execute((bool,bool,uint256,address,uint256,bytes)[],uint256,bytes)\":{\"notice\":\"Allow any caller to execute an action\"},\"isValidSignature(bytes,bytes)\":{\"notice\":\"Verifies whether the provided signature is valid with respect to the provided data\"},\"isValidSignature(bytes32,bytes)\":{\"notice\":\"Verifies whether the provided signature is valid with respect to the provided hash\"},\"nonce()\":{\"notice\":\"Returns the next nonce of the default nonce space\"},\"readNonce(uint256)\":{\"notice\":\"Returns the next nonce of the given nonce space\"},\"selfExecute((bool,bool,uint256,address,uint256,bytes)[])\":{\"notice\":\"Allow any caller to execute an action\"},\"signatureRecovery(bytes32,bytes)\":{\"notice\":\"Recovers the threshold, weight, imageHash, subdigest, and checkpoint of a signature.\"},\"supportsInterface(bytes4)\":{\"notice\":\"Query if a contract implements an interface\"},\"updateImageHash(bytes32)\":{\"notice\":\"Updates the signers configuration of the wallet\"}},\"notice\":\"GuestModule implements a Sequence wallet without signatures, nonce or replay protection. executing transactions using this wallet is not an authenticated process, and can be done by any address.This contract is completely public with no security, designed to execute pre-signed transactions and use Sequence tools without using the wallets.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":\"GuestModule\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":500000},\"remappings\":[\":@0xsequence/contracts-library/=src/\",\":@0xsequence/erc-1155/=lib/0xsequence/erc-1155/src/\",\":@0xsequence/erc20-meta-token/=lib/0xsequence/erc20-meta-token/src/\",\":@openzeppelin/=lib/openzeppelin/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc721a-upgradeable/=lib/chiru-labs/erc721a-upgradeable/\",\":erc721a/=lib/chiru-labs/erc721a/\",\":forge-std/=lib/forge-std/src/\",\":murky/=lib/murky/src/\",\":solady/=lib/solady/src/\"]},\"sources\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/interfaces/IERC1271Wallet.sol\":{\"keccak256\":\"0x2d7881bca678833feb385fd59e5d8ad6d596160ab51daa7030372654b3dbc38c\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://010f44c05b7285a55de939f9989727d53dfb87fd2d2534a832a70e0e081bb5f1\",\"dweb:/ipfs/QmQcujWErxjktsKyyiTySaFuR7Vaq6fUA9SUzPkde2txVK\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol\":{\"keccak256\":\"0x14c92b44eac100edbfea10d0d02728752a6be277c267c3776dc563ff963271b1\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://e440eb91039118ce26bb66fd549d5e6b59863983efbe6c2617b92e2c4f0aab66\",\"dweb:/ipfs/QmeTd2xBKEv4S4Rp9S4TSY4WwUUDjtA7xiJYiJqkVUio7d\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":{\"keccak256\":\"0x58c028f02e3517de6c39584bcf1cedd4e7b23f575c24b363cbad4960a74f8a0b\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://f9652fead22c9fe8510de8427e2db354ed145ff30f49f85d1c717e293e5df665\",\"dweb:/ipfs/QmSJPFQxRE5n17DNB5Bu2jwRo17yLS7igMQGt3bvKkdLAP\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol\":{\"keccak256\":\"0x80c0151dbd444f96c2f935e70a6d3cc57e307588fa21d7eace67e568dd3d35c1\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://39a856555a5eb900e67d351e667135f245ccebd304d692b35fc8bdc83aec1b53\",\"dweb:/ipfs/QmUdWfa7GcTGM5gk7qYbNCHtsxF4o8dXHzr6HbdFng5sQm\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":{\"keccak256\":\"0x16b1400988f6b7bd4d32bdcb36ee2fbd644fb2c8ca571becc0c32e03602bd303\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://8bd4681fb4cff10f4e98e45618fbc52ed0a4c7d4fcf614f34a587ad20cd16855\",\"dweb:/ipfs/QmbA2LYBH1x8WX8CaeiFYMU5rjyLGgNCF32r9fQbXuoqwJ\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleERC165.sol\":{\"keccak256\":\"0xd4ae13a3d20fd7ab52ad16af6a06e7244daea450b796251e911091cac104d05f\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://8de37ec20a6b649e9fe3fb42276e4660ff546bca8b467f72beb35396ab5e62d6\",\"dweb:/ipfs/QmXT2SxBZKitkbKLbGbbNLhUbw2ataRpQ2DHafvhG953RE\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":{\"keccak256\":\"0x3b5388842f763a5347d632a0e0e8499a54b6f0b0a6eb7f7d3d848319defa042d\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://b36fa5a88a4e174967f850bf2bb78c787d8016ef7b5eee3e2f883fbfe9b87a7d\",\"dweb:/ipfs/QmTDZiPiQGe1fmTKKzdwzBE1xjkh8apTotW1SQRUCFXf4q\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleOnlyDelegatecall.sol\":{\"keccak256\":\"0x32bdb1d343eee2e32fd9d0f1d6dc0e265411d0821bd908881822f0f26f0887f8\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://1537c4f60a609751013bdc69eb1c6e6218982d91013115bc4e28cb84f816cd91\",\"dweb:/ipfs/QmSjkSTrrB4vuxECcm5cRG7YmraF53QWRgftxS827KcQLW\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":{\"keccak256\":\"0x91545de5c77cfac86c5686c4e1f338a18ee7adb689ac0234848d7a7fc8a560db\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://dc89d05d8099ba4c3c2cf85737796d439899b5a04e6b87b1ea43f687ae08848a\",\"dweb:/ipfs/QmatU8gRvFkK3Yn1MYAekzi48Waw3cDLtXJpduvju9HFUu\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol\":{\"keccak256\":\"0x876c6a40cba975df4f7dfe24e02d153b2ee758975b6d1eda494ecd4b7244aa8e\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://b9be3f7930476d528ce10a121701421f0fb251b7d6b7cd579917375e6b283bb4\",\"dweb:/ipfs/QmSbvbYQvTk8KYJZ7QqSKB9Y4M1X3UDhS6k765Zr1BAwK8\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleAuth.sol\":{\"keccak256\":\"0x24c6b05c32cb344b3b0aebd01fbd8bfc69f8c8e29fca340b262d9612c34d51e2\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://5f6c004946f0cbc4b3e52d45248337146bc82569da894ecff3cbdc5a0dca95c3\",\"dweb:/ipfs/QmNSgDMQ7SHL6AJuzTSRbY2kgciHF1SKWfH6MaPH1N3TpR\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCalls.sol\":{\"keccak256\":\"0xde065c15e38eb009c3dc8f99dfefdd1d6d244dd12a889a8b57edd90d32fb4395\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://23608955786060457f79267795a61eb89b3910b683fc136c749548369425088f\",\"dweb:/ipfs/QmXNorcQBF1Qk21y3aEJRiiHVtwm61zP4ttA1ZzmRjyHnz\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCreator.sol\":{\"keccak256\":\"0xa206dd3d424b8cd1c4f1400aa344cbc974480fea02f0fb371b872558e5ff4e6d\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://ea14c75f43a0008c582dcbae3ba3c900e446e28039dfdbb059d326ec5cc6a2d2\",\"dweb:/ipfs/QmRfF6BmUWiFkCgzVFbLcHsUCNz5q2XkkcwXPX57ViTK4D\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":{\"keccak256\":\"0xe0565e24e94204d4b254ace42d124d3279256090921a4818cbbf9747cbb14e04\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://4293a4762b0816738511f697efd04a0e881d4c409bd15ac1c4e7261fe5e482a2\",\"dweb:/ipfs/QmcHbEBne4fvpcD7RTJHCL6q9czoLa7KHneaCeYfXuWiGu\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":{\"keccak256\":\"0x755fbf6c106fe1c3c375c41c95c38269873717d8e683678b5fdbf6c8d3426306\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://7c7c92e72dd94f16b5c004d38c2d92eb2b760fd29a939945ed275633b0f93fa5\",\"dweb:/ipfs/QmVdCG7Aw7aVV67z5mUKZa4VqhXHdLqy3SKxPfxaxq54p2\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol\":{\"keccak256\":\"0x6de353f8c7f44c4294914a4917458ce90ae2f7ecd2d84074fe12d4a4f1485ee5\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://369f979b79a3d3fd0336ab14b3accadb63e4784324afc34f8db11d1988526afd\",\"dweb:/ipfs/QmavmBZ354wTaXQ6ixBd8GrC9HwtRqn4MoNhCVJcx11off\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol\":{\"keccak256\":\"0xa3ac8b8d31f20a8732bb4ebad53b42b334ec29041de0224bd494913ef0b2ad07\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://5a81d4eb3f47b09a8835b2fd53e0baa2e23cb604db3b10dae82543a5bcc52fa4\",\"dweb:/ipfs/QmQ9XSSgbaagWArmZJJ366bdJ7HfxUxn9jdnWwN6SxUSeY\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol\":{\"keccak256\":\"0x98520e740b0822ec053d21f376b8be8a58e93228f3758f9228a7d00e1f60950f\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://31226706c004f1a4315d6b8d37621b46f4d5807c16e1ce72675c1431ed9006a2\",\"dweb:/ipfs/QmdSSyCuPex2E2VTd6UMYy9WAq9eJNZ6vHSUomntNknzXE\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol\":{\"keccak256\":\"0xd780faf34527a323c96577c57370d175a2b6149db7ebea0937592eb389e52805\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://7a41a47e72f5761d912367c041ddab41620175d63059ad71ff681a87d8cf0e98\",\"dweb:/ipfs/QmfEFuLaVyx9vQc83dS48wTcLtbBiWTNMdHSi5hAWA379i\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":{\"keccak256\":\"0xbda56396592db18a248d4062cd36abd586a11d92a2d25483d8c597f890859b15\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://a6ee93bcb7ccd1d1b8979c9530b1ca452d0757794995b62793b6e197670b9f25\",\"dweb:/ipfs/QmbNkhTPzF1YgU4Qgu4SRFXZ8AwFjyG18EzuMZ32anrQ4Y\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":{\"keccak256\":\"0x4c558b8c9d0dff2322d5d812e83a3abe25a9e60c8f646507f8a9c7fa2a2453af\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://6f0796c75d117770e220c136b60d96b5cf1d4875ccbbd0afb564ed27aa220335\",\"dweb:/ipfs/QmQxYm6CMCqJiKsB3sguqWu8rggmaQgpuq8BZhAEveqNAM\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":{\"keccak256\":\"0x7ac5dd35cbc776693eecfd8e7e86af139c7b054c43be4f97e6c8929417c17dba\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://4a452d8acad5246538ac352887081d732098dcab869c79a43a5f916e7e76f353\",\"dweb:/ipfs/QmeazDSxfKBSGyCGjmk7G79UbvYMRcbr2eUU9ThyqSvNhv\"]}},\"version\":1}", + "storageLayout": { + "storage": [], + "types": null + }, + "userdoc": { + "kind": "user", + "methods": { + "createContract(bytes)": { + "notice": "Creates a contract forwarding eth value" + }, + "execute((bool,bool,uint256,address,uint256,bytes)[],uint256,bytes)": { + "notice": "Allow any caller to execute an action" + }, + "isValidSignature(bytes,bytes)": { + "notice": "Verifies whether the provided signature is valid with respect to the provided data" + }, + "isValidSignature(bytes32,bytes)": { + "notice": "Verifies whether the provided signature is valid with respect to the provided hash" + }, + "nonce()": { + "notice": "Returns the next nonce of the default nonce space" + }, + "readNonce(uint256)": { + "notice": "Returns the next nonce of the given nonce space" + }, + "selfExecute((bool,bool,uint256,address,uint256,bytes)[])": { + "notice": "Allow any caller to execute an action" + }, + "signatureRecovery(bytes32,bytes)": { + "notice": "Recovers the threshold, weight, imageHash, subdigest, and checkpoint of a signature." + }, + "supportsInterface(bytes4)": { + "notice": "Query if a contract implements an interface" + }, + "updateImageHash(bytes32)": { + "notice": "Updates the signers configuration of the wallet" + } + }, + "notice": "GuestModule implements a Sequence wallet without signatures, nonce or replay protection. executing transactions using this wallet is not an authenticated process, and can be done by any address.This contract is completely public with no security, designed to execute pre-signed transactions and use Sequence tools without using the wallets.", + "version": 1 + } + } + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol": { + "ModuleAuth": { + "abi": [ + { + "inputs": [], + "name": "EmptySignature", + "type": "error" + }, + { + "inputs": [], + "name": "ImageHashIsZero", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "_addr", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "InvalidNestedSignature", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + }, + { + "internalType": "bytes32", + "name": "_s", + "type": "bytes32" + } + ], + "name": "InvalidSValue", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_flag", + "type": "uint256" + } + ], + "name": "InvalidSignatureFlag", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "InvalidSignatureLength", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes1", + "name": "_type", + "type": "bytes1" + } + ], + "name": "InvalidSignatureType", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_v", + "type": "uint256" + } + ], + "name": "InvalidVValue", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "threshold", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_weight", + "type": "uint256" + } + ], + "name": "LowWeightChainedSignature", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_sender", + "type": "address" + }, + { + "internalType": "address", + "name": "_self", + "type": "address" + } + ], + "name": "OnlySelfAuth", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "SignerIsAddress0", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_type", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_recoverMode", + "type": "bool" + } + ], + "name": "UnsupportedSignatureType", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_current", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_prev", + "type": "uint256" + } + ], + "name": "WrongChainedCheckpointOrder", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "newImageHash", + "type": "bytes32" + } + ], + "name": "ImageHashUpdated", + "type": "event" + }, + { + "inputs": [], + "name": "SET_IMAGE_HASH_TYPE_HASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_signatures", + "type": "bytes" + } + ], + "name": "isValidSignature", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "_signatures", + "type": "bytes" + } + ], + "name": "isValidSignature", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_digest", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "signatureRecovery", + "outputs": [ + { + "internalType": "uint256", + "name": "threshold", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "weight", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "imageHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "subdigest", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "checkpoint", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceID", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_imageHash", + "type": "bytes32" + } + ], + "name": "updateImageHash", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "devdoc": { + "kind": "dev", + "methods": { + "isValidSignature(bytes,bytes)": { + "details": "MUST return the correct magic value if the signature provided is valid for the provided data > The bytes4 magic value to return when signature is valid is 0x20c13b0b : bytes4(keccak256(\"isValidSignature(bytes,bytes)\"))", + "params": { + "_data": "Arbitrary length data signed on the behalf of address(this)", + "_signatures": "Signature byte array associated with _data. Encoded as abi.encode(Signature[], Configs)" + }, + "returns": { + "_0": "magicValue Magic value 0x20c13b0b if the signature is valid and 0x0 otherwise" + } + }, + "isValidSignature(bytes32,bytes)": { + "details": "MUST return the correct magic value if the signature provided is valid for the provided hash > The bytes4 magic value to return when signature is valid is 0x1626ba7e : bytes4(keccak256(\"isValidSignature(bytes32,bytes)\"))", + "params": { + "_hash": "keccak256 hash that was signed", + "_signatures": "Signature byte array associated with _data. Encoded as abi.encode(Signature[], Configs)" + }, + "returns": { + "_0": "magicValue Magic value 0x1626ba7e if the signature is valid and 0x0 otherwise" + } + }, + "signatureRecovery(bytes32,bytes)": { + "details": "The signature must be prefixed with a type byte, which is used to determine the recovery method.", + "params": { + "_digest": "Digest of the signed data.", + "_signature": "A Sequence signature." + }, + "returns": { + "checkpoint": "A nonce that is incremented every time a new configuration is set.", + "imageHash": "The imageHash of the configuration that signed the message.", + "subdigest": "A modified version of the original digest, unique for each wallet/network.", + "threshold": "The required number of signatures needed to consider the signature valid.", + "weight": "The actual number of signatures collected in the signature." + } + }, + "supportsInterface(bytes4)": { + "params": { + "_interfaceID": "The interface identifier, as specified in ERC-165" + }, + "returns": { + "_0": "`true` if the contract implements `_interfaceID`" + } + }, + "updateImageHash(bytes32)": { + "params": { + "_imageHash": "New required image hash of the signature" + } + } + }, + "version": 1 + }, + "evm": { + "assembly": "", + "bytecode": { + "functionDebugData": {}, + "generatedSources": [], + "linkReferences": {}, + "object": "", + "opcodes": "", + "sourceMap": "" + }, + "deployedBytecode": { + "functionDebugData": {}, + "generatedSources": [], + "immutableReferences": {}, + "linkReferences": {}, + "object": "", + "opcodes": "", + "sourceMap": "" + }, + "gasEstimates": null, + "legacyAssembly": null, + "methodIdentifiers": { + "SET_IMAGE_HASH_TYPE_HASH()": "57c56d6b", + "isValidSignature(bytes,bytes)": "20c13b0b", + "isValidSignature(bytes32,bytes)": "1626ba7e", + "signatureRecovery(bytes32,bytes)": "853c5068", + "supportsInterface(bytes4)": "01ffc9a7", + "updateImageHash(bytes32)": "29561426" + } + }, + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"EmptySignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ImageHashIsZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_hash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"InvalidNestedSignature\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"},{\"internalType\":\"bytes32\",\"name\":\"_s\",\"type\":\"bytes32\"}],\"name\":\"InvalidSValue\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_flag\",\"type\":\"uint256\"}],\"name\":\"InvalidSignatureFlag\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"InvalidSignatureLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes1\",\"name\":\"_type\",\"type\":\"bytes1\"}],\"name\":\"InvalidSignatureType\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_v\",\"type\":\"uint256\"}],\"name\":\"InvalidVValue\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_weight\",\"type\":\"uint256\"}],\"name\":\"LowWeightChainedSignature\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_self\",\"type\":\"address\"}],\"name\":\"OnlySelfAuth\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"SignerIsAddress0\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_type\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"_recoverMode\",\"type\":\"bool\"}],\"name\":\"UnsupportedSignatureType\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_current\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_prev\",\"type\":\"uint256\"}],\"name\":\"WrongChainedCheckpointOrder\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"newImageHash\",\"type\":\"bytes32\"}],\"name\":\"ImageHashUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"SET_IMAGE_HASH_TYPE_HASH\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_hash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_signatures\",\"type\":\"bytes\"}],\"name\":\"isValidSignature\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"_signatures\",\"type\":\"bytes\"}],\"name\":\"isValidSignature\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_digest\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"signatureRecovery\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"imageHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"subdigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"checkpoint\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_interfaceID\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_imageHash\",\"type\":\"bytes32\"}],\"name\":\"updateImageHash\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"isValidSignature(bytes,bytes)\":{\"details\":\"MUST return the correct magic value if the signature provided is valid for the provided data > The bytes4 magic value to return when signature is valid is 0x20c13b0b : bytes4(keccak256(\\\"isValidSignature(bytes,bytes)\\\"))\",\"params\":{\"_data\":\"Arbitrary length data signed on the behalf of address(this)\",\"_signatures\":\"Signature byte array associated with _data. Encoded as abi.encode(Signature[], Configs)\"},\"returns\":{\"_0\":\"magicValue Magic value 0x20c13b0b if the signature is valid and 0x0 otherwise\"}},\"isValidSignature(bytes32,bytes)\":{\"details\":\"MUST return the correct magic value if the signature provided is valid for the provided hash > The bytes4 magic value to return when signature is valid is 0x1626ba7e : bytes4(keccak256(\\\"isValidSignature(bytes32,bytes)\\\"))\",\"params\":{\"_hash\":\"keccak256 hash that was signed\",\"_signatures\":\"Signature byte array associated with _data. Encoded as abi.encode(Signature[], Configs)\"},\"returns\":{\"_0\":\"magicValue Magic value 0x1626ba7e if the signature is valid and 0x0 otherwise\"}},\"signatureRecovery(bytes32,bytes)\":{\"details\":\"The signature must be prefixed with a type byte, which is used to determine the recovery method.\",\"params\":{\"_digest\":\"Digest of the signed data.\",\"_signature\":\"A Sequence signature.\"},\"returns\":{\"checkpoint\":\"A nonce that is incremented every time a new configuration is set.\",\"imageHash\":\"The imageHash of the configuration that signed the message.\",\"subdigest\":\"A modified version of the original digest, unique for each wallet/network.\",\"threshold\":\"The required number of signatures needed to consider the signature valid.\",\"weight\":\"The actual number of signatures collected in the signature.\"}},\"supportsInterface(bytes4)\":{\"params\":{\"_interfaceID\":\"The interface identifier, as specified in ERC-165\"},\"returns\":{\"_0\":\"`true` if the contract implements `_interfaceID`\"}},\"updateImageHash(bytes32)\":{\"params\":{\"_imageHash\":\"New required image hash of the signature\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"isValidSignature(bytes,bytes)\":{\"notice\":\"Verifies whether the provided signature is valid with respect to the provided data\"},\"isValidSignature(bytes32,bytes)\":{\"notice\":\"Verifies whether the provided signature is valid with respect to the provided hash\"},\"signatureRecovery(bytes32,bytes)\":{\"notice\":\"Recovers the threshold, weight, imageHash, subdigest, and checkpoint of a signature.\"},\"supportsInterface(bytes4)\":{\"notice\":\"Query if a contract implements an interface\"},\"updateImageHash(bytes32)\":{\"notice\":\"Updates the signers configuration of the wallet\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":\"ModuleAuth\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":500000},\"remappings\":[\":@0xsequence/contracts-library/=src/\",\":@0xsequence/erc-1155/=lib/0xsequence/erc-1155/src/\",\":@0xsequence/erc20-meta-token/=lib/0xsequence/erc20-meta-token/src/\",\":@openzeppelin/=lib/openzeppelin/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc721a-upgradeable/=lib/chiru-labs/erc721a-upgradeable/\",\":erc721a/=lib/chiru-labs/erc721a/\",\":forge-std/=lib/forge-std/src/\",\":murky/=lib/murky/src/\",\":solady/=lib/solady/src/\"]},\"sources\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/interfaces/IERC1271Wallet.sol\":{\"keccak256\":\"0x2d7881bca678833feb385fd59e5d8ad6d596160ab51daa7030372654b3dbc38c\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://010f44c05b7285a55de939f9989727d53dfb87fd2d2534a832a70e0e081bb5f1\",\"dweb:/ipfs/QmQcujWErxjktsKyyiTySaFuR7Vaq6fUA9SUzPkde2txVK\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol\":{\"keccak256\":\"0x58c028f02e3517de6c39584bcf1cedd4e7b23f575c24b363cbad4960a74f8a0b\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://f9652fead22c9fe8510de8427e2db354ed145ff30f49f85d1c717e293e5df665\",\"dweb:/ipfs/QmSJPFQxRE5n17DNB5Bu2jwRo17yLS7igMQGt3bvKkdLAP\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleERC165.sol\":{\"keccak256\":\"0xd4ae13a3d20fd7ab52ad16af6a06e7244daea450b796251e911091cac104d05f\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://8de37ec20a6b649e9fe3fb42276e4660ff546bca8b467f72beb35396ab5e62d6\",\"dweb:/ipfs/QmXT2SxBZKitkbKLbGbbNLhUbw2ataRpQ2DHafvhG953RE\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":{\"keccak256\":\"0x91545de5c77cfac86c5686c4e1f338a18ee7adb689ac0234848d7a7fc8a560db\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://dc89d05d8099ba4c3c2cf85737796d439899b5a04e6b87b1ea43f687ae08848a\",\"dweb:/ipfs/QmatU8gRvFkK3Yn1MYAekzi48Waw3cDLtXJpduvju9HFUu\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol\":{\"keccak256\":\"0x876c6a40cba975df4f7dfe24e02d153b2ee758975b6d1eda494ecd4b7244aa8e\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://b9be3f7930476d528ce10a121701421f0fb251b7d6b7cd579917375e6b283bb4\",\"dweb:/ipfs/QmSbvbYQvTk8KYJZ7QqSKB9Y4M1X3UDhS6k765Zr1BAwK8\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleAuth.sol\":{\"keccak256\":\"0x24c6b05c32cb344b3b0aebd01fbd8bfc69f8c8e29fca340b262d9612c34d51e2\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://5f6c004946f0cbc4b3e52d45248337146bc82569da894ecff3cbdc5a0dca95c3\",\"dweb:/ipfs/QmNSgDMQ7SHL6AJuzTSRbY2kgciHF1SKWfH6MaPH1N3TpR\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":{\"keccak256\":\"0xe0565e24e94204d4b254ace42d124d3279256090921a4818cbbf9747cbb14e04\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://4293a4762b0816738511f697efd04a0e881d4c409bd15ac1c4e7261fe5e482a2\",\"dweb:/ipfs/QmcHbEBne4fvpcD7RTJHCL6q9czoLa7KHneaCeYfXuWiGu\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":{\"keccak256\":\"0x755fbf6c106fe1c3c375c41c95c38269873717d8e683678b5fdbf6c8d3426306\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://7c7c92e72dd94f16b5c004d38c2d92eb2b760fd29a939945ed275633b0f93fa5\",\"dweb:/ipfs/QmVdCG7Aw7aVV67z5mUKZa4VqhXHdLqy3SKxPfxaxq54p2\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol\":{\"keccak256\":\"0x6de353f8c7f44c4294914a4917458ce90ae2f7ecd2d84074fe12d4a4f1485ee5\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://369f979b79a3d3fd0336ab14b3accadb63e4784324afc34f8db11d1988526afd\",\"dweb:/ipfs/QmavmBZ354wTaXQ6ixBd8GrC9HwtRqn4MoNhCVJcx11off\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol\":{\"keccak256\":\"0xa3ac8b8d31f20a8732bb4ebad53b42b334ec29041de0224bd494913ef0b2ad07\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://5a81d4eb3f47b09a8835b2fd53e0baa2e23cb604db3b10dae82543a5bcc52fa4\",\"dweb:/ipfs/QmQ9XSSgbaagWArmZJJ366bdJ7HfxUxn9jdnWwN6SxUSeY\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol\":{\"keccak256\":\"0xd780faf34527a323c96577c57370d175a2b6149db7ebea0937592eb389e52805\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://7a41a47e72f5761d912367c041ddab41620175d63059ad71ff681a87d8cf0e98\",\"dweb:/ipfs/QmfEFuLaVyx9vQc83dS48wTcLtbBiWTNMdHSi5hAWA379i\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":{\"keccak256\":\"0xbda56396592db18a248d4062cd36abd586a11d92a2d25483d8c597f890859b15\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://a6ee93bcb7ccd1d1b8979c9530b1ca452d0757794995b62793b6e197670b9f25\",\"dweb:/ipfs/QmbNkhTPzF1YgU4Qgu4SRFXZ8AwFjyG18EzuMZ32anrQ4Y\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":{\"keccak256\":\"0x4c558b8c9d0dff2322d5d812e83a3abe25a9e60c8f646507f8a9c7fa2a2453af\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://6f0796c75d117770e220c136b60d96b5cf1d4875ccbbd0afb564ed27aa220335\",\"dweb:/ipfs/QmQxYm6CMCqJiKsB3sguqWu8rggmaQgpuq8BZhAEveqNAM\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":{\"keccak256\":\"0x7ac5dd35cbc776693eecfd8e7e86af139c7b054c43be4f97e6c8929417c17dba\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://4a452d8acad5246538ac352887081d732098dcab869c79a43a5f916e7e76f353\",\"dweb:/ipfs/QmeazDSxfKBSGyCGjmk7G79UbvYMRcbr2eUU9ThyqSvNhv\"]}},\"version\":1}", + "storageLayout": { + "storage": [], + "types": null + }, + "userdoc": { + "kind": "user", + "methods": { + "isValidSignature(bytes,bytes)": { + "notice": "Verifies whether the provided signature is valid with respect to the provided data" + }, + "isValidSignature(bytes32,bytes)": { + "notice": "Verifies whether the provided signature is valid with respect to the provided hash" + }, + "signatureRecovery(bytes32,bytes)": { + "notice": "Recovers the threshold, weight, imageHash, subdigest, and checkpoint of a signature." + }, + "supportsInterface(bytes4)": { + "notice": "Query if a contract implements an interface" + }, + "updateImageHash(bytes32)": { + "notice": "Updates the signers configuration of the wallet" + } + }, + "version": 1 + } + } + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol": { + "ModuleCalls": { + "abi": [ + { + "inputs": [ + { + "internalType": "uint256", + "name": "_space", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_provided", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_current", + "type": "uint256" + } + ], + "name": "BadNonce", + "type": "error" + }, + { + "inputs": [], + "name": "ImageHashIsZero", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "InvalidSignature", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes1", + "name": "_type", + "type": "bytes1" + } + ], + "name": "InvalidSignatureType", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_index", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_requested", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_available", + "type": "uint256" + } + ], + "name": "NotEnoughGas", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyDelegatecall", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_sender", + "type": "address" + }, + { + "internalType": "address", + "name": "_self", + "type": "address" + } + ], + "name": "OnlySelfAuth", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "newImageHash", + "type": "bytes32" + } + ], + "name": "ImageHashUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_space", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_newNonce", + "type": "uint256" + } + ], + "name": "NonceChange", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "_tx", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_index", + "type": "uint256" + } + ], + "name": "TxExecuted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "_tx", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_index", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_reason", + "type": "bytes" + } + ], + "name": "TxFailed", + "type": "event" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bool", + "name": "delegateCall", + "type": "bool" + }, + { + "internalType": "bool", + "name": "revertOnError", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + }, + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "internalType": "struct IModuleCalls.Transaction[]", + "name": "_txs", + "type": "tuple[]" + }, + { + "internalType": "uint256", + "name": "_nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "execute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "nonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_space", + "type": "uint256" + } + ], + "name": "readNonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bool", + "name": "delegateCall", + "type": "bool" + }, + { + "internalType": "bool", + "name": "revertOnError", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + }, + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "internalType": "struct IModuleCalls.Transaction[]", + "name": "_txs", + "type": "tuple[]" + } + ], + "name": "selfExecute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_digest", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "signatureRecovery", + "outputs": [ + { + "internalType": "uint256", + "name": "threshold", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "weight", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "imageHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "subdigest", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "checkpoint", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceID", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_imageHash", + "type": "bytes32" + } + ], + "name": "updateImageHash", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "devdoc": { + "kind": "dev", + "methods": { + "execute((bool,bool,uint256,address,uint256,bytes)[],uint256,bytes)": { + "details": "Relayers must ensure that the gasLimit specified for each transaction is acceptable to them. A user could specify large enough that it could consume all the gas available.", + "params": { + "_nonce": "Signature nonce (may contain an encoded space)", + "_signature": "Encoded signature", + "_txs": "Transactions to process" + } + }, + "nonce()": { + "details": "The default nonce space is 0x00", + "returns": { + "_0": "The next nonce" + } + }, + "readNonce(uint256)": { + "params": { + "_space": "Nonce space, each space keeps an independent nonce count" + }, + "returns": { + "_0": "The next nonce" + } + }, + "selfExecute((bool,bool,uint256,address,uint256,bytes)[])": { + "params": { + "_txs": "Transactions to execute" + } + }, + "supportsInterface(bytes4)": { + "params": { + "_interfaceID": "The interface identifier, as specified in ERC-165" + }, + "returns": { + "_0": "`true` if the contract implements `_interfaceID`" + } + }, + "updateImageHash(bytes32)": { + "params": { + "_imageHash": "New required image hash of the signature" + } + } + }, + "version": 1 + }, + "evm": { + "assembly": "", + "bytecode": { + "functionDebugData": {}, + "generatedSources": [], + "linkReferences": {}, + "object": "", + "opcodes": "", + "sourceMap": "" + }, + "deployedBytecode": { + "functionDebugData": {}, + "generatedSources": [], + "immutableReferences": {}, + "linkReferences": {}, + "object": "", + "opcodes": "", + "sourceMap": "" + }, + "gasEstimates": null, + "legacyAssembly": null, + "methodIdentifiers": { + "execute((bool,bool,uint256,address,uint256,bytes)[],uint256,bytes)": "7a9a1628", + "nonce()": "affed0e0", + "readNonce(uint256)": "8c3f5563", + "selfExecute((bool,bool,uint256,address,uint256,bytes)[])": "61c2926c", + "signatureRecovery(bytes32,bytes)": "853c5068", + "supportsInterface(bytes4)": "01ffc9a7", + "updateImageHash(bytes32)": "29561426" + } + }, + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_space\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_provided\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_current\",\"type\":\"uint256\"}],\"name\":\"BadNonce\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ImageHashIsZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_hash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes1\",\"name\":\"_type\",\"type\":\"bytes1\"}],\"name\":\"InvalidSignatureType\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_requested\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_available\",\"type\":\"uint256\"}],\"name\":\"NotEnoughGas\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyDelegatecall\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_self\",\"type\":\"address\"}],\"name\":\"OnlySelfAuth\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"newImageHash\",\"type\":\"bytes32\"}],\"name\":\"ImageHashUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_space\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_newNonce\",\"type\":\"uint256\"}],\"name\":\"NonceChange\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_tx\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"TxExecuted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_tx\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_reason\",\"type\":\"bytes\"}],\"name\":\"TxFailed\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"delegateCall\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"revertOnError\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"struct IModuleCalls.Transaction[]\",\"name\":\"_txs\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_space\",\"type\":\"uint256\"}],\"name\":\"readNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"delegateCall\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"revertOnError\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"struct IModuleCalls.Transaction[]\",\"name\":\"_txs\",\"type\":\"tuple[]\"}],\"name\":\"selfExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_digest\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"signatureRecovery\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"imageHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"subdigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"checkpoint\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_interfaceID\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_imageHash\",\"type\":\"bytes32\"}],\"name\":\"updateImageHash\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"execute((bool,bool,uint256,address,uint256,bytes)[],uint256,bytes)\":{\"details\":\"Relayers must ensure that the gasLimit specified for each transaction is acceptable to them. A user could specify large enough that it could consume all the gas available.\",\"params\":{\"_nonce\":\"Signature nonce (may contain an encoded space)\",\"_signature\":\"Encoded signature\",\"_txs\":\"Transactions to process\"}},\"nonce()\":{\"details\":\"The default nonce space is 0x00\",\"returns\":{\"_0\":\"The next nonce\"}},\"readNonce(uint256)\":{\"params\":{\"_space\":\"Nonce space, each space keeps an independent nonce count\"},\"returns\":{\"_0\":\"The next nonce\"}},\"selfExecute((bool,bool,uint256,address,uint256,bytes)[])\":{\"params\":{\"_txs\":\"Transactions to execute\"}},\"supportsInterface(bytes4)\":{\"params\":{\"_interfaceID\":\"The interface identifier, as specified in ERC-165\"},\"returns\":{\"_0\":\"`true` if the contract implements `_interfaceID`\"}},\"updateImageHash(bytes32)\":{\"params\":{\"_imageHash\":\"New required image hash of the signature\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"execute((bool,bool,uint256,address,uint256,bytes)[],uint256,bytes)\":{\"notice\":\"Allow wallet owner to execute an action\"},\"nonce()\":{\"notice\":\"Returns the next nonce of the default nonce space\"},\"readNonce(uint256)\":{\"notice\":\"Returns the next nonce of the given nonce space\"},\"selfExecute((bool,bool,uint256,address,uint256,bytes)[])\":{\"notice\":\"Allow wallet to execute an action without signing the message\"},\"supportsInterface(bytes4)\":{\"notice\":\"Query if a contract implements an interface\"},\"updateImageHash(bytes32)\":{\"notice\":\"Updates the signers configuration of the wallet\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol\":\"ModuleCalls\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":500000},\"remappings\":[\":@0xsequence/contracts-library/=src/\",\":@0xsequence/erc-1155/=lib/0xsequence/erc-1155/src/\",\":@0xsequence/erc20-meta-token/=lib/0xsequence/erc20-meta-token/src/\",\":@openzeppelin/=lib/openzeppelin/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc721a-upgradeable/=lib/chiru-labs/erc721a-upgradeable/\",\":erc721a/=lib/chiru-labs/erc721a/\",\":forge-std/=lib/forge-std/src/\",\":murky/=lib/murky/src/\",\":solady/=lib/solady/src/\"]},\"sources\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/interfaces/IERC1271Wallet.sol\":{\"keccak256\":\"0x2d7881bca678833feb385fd59e5d8ad6d596160ab51daa7030372654b3dbc38c\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://010f44c05b7285a55de939f9989727d53dfb87fd2d2534a832a70e0e081bb5f1\",\"dweb:/ipfs/QmQcujWErxjktsKyyiTySaFuR7Vaq6fUA9SUzPkde2txVK\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol\":{\"keccak256\":\"0x80c0151dbd444f96c2f935e70a6d3cc57e307588fa21d7eace67e568dd3d35c1\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://39a856555a5eb900e67d351e667135f245ccebd304d692b35fc8bdc83aec1b53\",\"dweb:/ipfs/QmUdWfa7GcTGM5gk7qYbNCHtsxF4o8dXHzr6HbdFng5sQm\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleERC165.sol\":{\"keccak256\":\"0xd4ae13a3d20fd7ab52ad16af6a06e7244daea450b796251e911091cac104d05f\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://8de37ec20a6b649e9fe3fb42276e4660ff546bca8b467f72beb35396ab5e62d6\",\"dweb:/ipfs/QmXT2SxBZKitkbKLbGbbNLhUbw2ataRpQ2DHafvhG953RE\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":{\"keccak256\":\"0x3b5388842f763a5347d632a0e0e8499a54b6f0b0a6eb7f7d3d848319defa042d\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://b36fa5a88a4e174967f850bf2bb78c787d8016ef7b5eee3e2f883fbfe9b87a7d\",\"dweb:/ipfs/QmTDZiPiQGe1fmTKKzdwzBE1xjkh8apTotW1SQRUCFXf4q\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleOnlyDelegatecall.sol\":{\"keccak256\":\"0x32bdb1d343eee2e32fd9d0f1d6dc0e265411d0821bd908881822f0f26f0887f8\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://1537c4f60a609751013bdc69eb1c6e6218982d91013115bc4e28cb84f816cd91\",\"dweb:/ipfs/QmSjkSTrrB4vuxECcm5cRG7YmraF53QWRgftxS827KcQLW\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":{\"keccak256\":\"0x91545de5c77cfac86c5686c4e1f338a18ee7adb689ac0234848d7a7fc8a560db\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://dc89d05d8099ba4c3c2cf85737796d439899b5a04e6b87b1ea43f687ae08848a\",\"dweb:/ipfs/QmatU8gRvFkK3Yn1MYAekzi48Waw3cDLtXJpduvju9HFUu\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol\":{\"keccak256\":\"0x876c6a40cba975df4f7dfe24e02d153b2ee758975b6d1eda494ecd4b7244aa8e\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://b9be3f7930476d528ce10a121701421f0fb251b7d6b7cd579917375e6b283bb4\",\"dweb:/ipfs/QmSbvbYQvTk8KYJZ7QqSKB9Y4M1X3UDhS6k765Zr1BAwK8\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleAuth.sol\":{\"keccak256\":\"0x24c6b05c32cb344b3b0aebd01fbd8bfc69f8c8e29fca340b262d9612c34d51e2\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://5f6c004946f0cbc4b3e52d45248337146bc82569da894ecff3cbdc5a0dca95c3\",\"dweb:/ipfs/QmNSgDMQ7SHL6AJuzTSRbY2kgciHF1SKWfH6MaPH1N3TpR\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCalls.sol\":{\"keccak256\":\"0xde065c15e38eb009c3dc8f99dfefdd1d6d244dd12a889a8b57edd90d32fb4395\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://23608955786060457f79267795a61eb89b3910b683fc136c749548369425088f\",\"dweb:/ipfs/QmXNorcQBF1Qk21y3aEJRiiHVtwm61zP4ttA1ZzmRjyHnz\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":{\"keccak256\":\"0xe0565e24e94204d4b254ace42d124d3279256090921a4818cbbf9747cbb14e04\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://4293a4762b0816738511f697efd04a0e881d4c409bd15ac1c4e7261fe5e482a2\",\"dweb:/ipfs/QmcHbEBne4fvpcD7RTJHCL6q9czoLa7KHneaCeYfXuWiGu\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol\":{\"keccak256\":\"0x98520e740b0822ec053d21f376b8be8a58e93228f3758f9228a7d00e1f60950f\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://31226706c004f1a4315d6b8d37621b46f4d5807c16e1ce72675c1431ed9006a2\",\"dweb:/ipfs/QmdSSyCuPex2E2VTd6UMYy9WAq9eJNZ6vHSUomntNknzXE\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol\":{\"keccak256\":\"0xd780faf34527a323c96577c57370d175a2b6149db7ebea0937592eb389e52805\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://7a41a47e72f5761d912367c041ddab41620175d63059ad71ff681a87d8cf0e98\",\"dweb:/ipfs/QmfEFuLaVyx9vQc83dS48wTcLtbBiWTNMdHSi5hAWA379i\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":{\"keccak256\":\"0xbda56396592db18a248d4062cd36abd586a11d92a2d25483d8c597f890859b15\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://a6ee93bcb7ccd1d1b8979c9530b1ca452d0757794995b62793b6e197670b9f25\",\"dweb:/ipfs/QmbNkhTPzF1YgU4Qgu4SRFXZ8AwFjyG18EzuMZ32anrQ4Y\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":{\"keccak256\":\"0x4c558b8c9d0dff2322d5d812e83a3abe25a9e60c8f646507f8a9c7fa2a2453af\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://6f0796c75d117770e220c136b60d96b5cf1d4875ccbbd0afb564ed27aa220335\",\"dweb:/ipfs/QmQxYm6CMCqJiKsB3sguqWu8rggmaQgpuq8BZhAEveqNAM\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":{\"keccak256\":\"0x7ac5dd35cbc776693eecfd8e7e86af139c7b054c43be4f97e6c8929417c17dba\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://4a452d8acad5246538ac352887081d732098dcab869c79a43a5f916e7e76f353\",\"dweb:/ipfs/QmeazDSxfKBSGyCGjmk7G79UbvYMRcbr2eUU9ThyqSvNhv\"]}},\"version\":1}", + "storageLayout": { + "storage": [], + "types": null + }, + "userdoc": { + "kind": "user", + "methods": { + "execute((bool,bool,uint256,address,uint256,bytes)[],uint256,bytes)": { + "notice": "Allow wallet owner to execute an action" + }, + "nonce()": { + "notice": "Returns the next nonce of the default nonce space" + }, + "readNonce(uint256)": { + "notice": "Returns the next nonce of the given nonce space" + }, + "selfExecute((bool,bool,uint256,address,uint256,bytes)[])": { + "notice": "Allow wallet to execute an action without signing the message" + }, + "supportsInterface(bytes4)": { + "notice": "Query if a contract implements an interface" + }, + "updateImageHash(bytes32)": { + "notice": "Updates the signers configuration of the wallet" + } + }, + "version": 1 + } + } + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol": { + "ModuleCreator": { + "abi": [ + { + "inputs": [ + { + "internalType": "bytes", + "name": "_code", + "type": "bytes" + } + ], + "name": "CreateFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_sender", + "type": "address" + }, + { + "internalType": "address", + "name": "_self", + "type": "address" + } + ], + "name": "OnlySelfAuth", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_contract", + "type": "address" + } + ], + "name": "CreatedContract", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_code", + "type": "bytes" + } + ], + "name": "createContract", + "outputs": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceID", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "devdoc": { + "kind": "dev", + "methods": { + "createContract(bytes)": { + "params": { + "_code": "Creation code of the contract" + }, + "returns": { + "addr": "The address of the created contract" + } + }, + "supportsInterface(bytes4)": { + "params": { + "_interfaceID": "The interface identifier, as specified in ERC-165" + }, + "returns": { + "_0": "`true` if the contract implements `_interfaceID`" + } + } + }, + "version": 1 + }, + "evm": { + "assembly": " /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":169:1177 contract ModuleCreator is IModuleCreator, ModuleERC165, ModuleSelfAuth {... */\n mstore(0x40, 0x80)\n callvalue\n dup1\n iszero\n tag_1\n jumpi\n 0x00\n dup1\n revert\ntag_1:\n pop\n dataSize(sub_0)\n dup1\n dataOffset(sub_0)\n 0x00\n codecopy\n 0x00\n return\nstop\n\nsub_0: assembly {\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":169:1177 contract ModuleCreator is IModuleCreator, ModuleERC165, ModuleSelfAuth {... */\n mstore(0x40, 0x80)\n jumpi(tag_1, lt(calldatasize, 0x04))\n shr(0xe0, calldataload(0x00))\n dup1\n 0x01ffc9a7\n eq\n tag_2\n jumpi\n dup1\n 0x90042baf\n eq\n tag_3\n jumpi\n tag_1:\n 0x00\n dup1\n revert\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":942:1175 function supportsInterface(bytes4 _interfaceID) public override virtual pure returns (bool) {... */\n tag_2:\n callvalue\n dup1\n iszero\n tag_4\n jumpi\n 0x00\n dup1\n revert\n tag_4:\n pop\n tag_5\n tag_6\n calldatasize\n 0x04\n tag_7\n jump\t// in\n tag_6:\n tag_8\n jump\t// in\n tag_5:\n mload(0x40)\n /* \"#utility.yul\":516:530 */\n swap1\n iszero\n /* \"#utility.yul\":509:531 */\n iszero\n /* \"#utility.yul\":491:532 */\n dup2\n mstore\n /* \"#utility.yul\":479:481 */\n 0x20\n /* \"#utility.yul\":464:482 */\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":942:1175 function supportsInterface(bytes4 _interfaceID) public override virtual pure returns (bool) {... */\n tag_9:\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n return\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":456:732 function createContract(bytes memory _code) public override virtual payable onlySelf returns (address addr) {... */\n tag_3:\n tag_11\n tag_12\n calldatasize\n 0x04\n tag_13\n jump\t// in\n tag_12:\n tag_14\n jump\t// in\n tag_11:\n mload(0x40)\n /* \"#utility.yul\":1893:1935 */\n 0xffffffffffffffffffffffffffffffffffffffff\n /* \"#utility.yul\":1881:1936 */\n swap1\n swap2\n and\n /* \"#utility.yul\":1863:1937 */\n dup2\n mstore\n /* \"#utility.yul\":1851:1853 */\n 0x20\n /* \"#utility.yul\":1836:1854 */\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":456:732 function createContract(bytes memory _code) public override virtual payable onlySelf returns (address addr) {... */\n tag_9\n /* \"#utility.yul\":1717:1943 */\n jump\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":942:1175 function supportsInterface(bytes4 _interfaceID) public override virtual pure returns (bool) {... */\n tag_8:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":1028:1032 bool */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":1044:1092 _interfaceID == type(IModuleCreator).interfaceId */\n 0x6ffbd45100000000000000000000000000000000000000000000000000000000\n 0xffffffff00000000000000000000000000000000000000000000000000000000\n dup4\n and\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":1040:1120 if (_interfaceID == type(IModuleCreator).interfaceId) {... */\n tag_18\n jumpi\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":1109:1113 true */\n 0x01\n swap2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":942:1175 function supportsInterface(bytes4 _interfaceID) public override virtual pure returns (bool) {... */\n swap1\n pop\n jump\t// out\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":1040:1120 if (_interfaceID == type(IModuleCreator).interfaceId) {... */\n tag_18:\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleERC165.sol\":709:756 _interfaceID == this.supportsInterface.selector */\n 0xffffffff00000000000000000000000000000000000000000000000000000000\n and\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleERC165.sol\":725:756 this.supportsInterface.selector */\n 0x01ffc9a700000000000000000000000000000000000000000000000000000000\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleERC165.sol\":709:756 _interfaceID == this.supportsInterface.selector */\n eq\n swap1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":942:1175 function supportsInterface(bytes4 _interfaceID) public override virtual pure returns (bool) {... */\n jump\t// out\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":456:732 function createContract(bytes memory _code) public override virtual payable onlySelf returns (address addr) {... */\n tag_14:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":550:562 address addr */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":178:188 msg.sender */\n caller\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":200:204 this */\n address\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":178:205 msg.sender != address(this) */\n eq\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":174:268 if (msg.sender != address(this)) {... */\n tag_22\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":222:261 OnlySelfAuth(msg.sender, address(this)) */\n mload(0x40)\n 0xe125889400000000000000000000000000000000000000000000000000000000\n dup2\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":235:245 msg.sender */\n caller\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":222:261 OnlySelfAuth(msg.sender, address(this)) */\n 0x04\n dup3\n add\n /* \"#utility.yul\":2183:2217 */\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":255:259 this */\n address\n /* \"#utility.yul\":2233:2251 */\n 0x24\n dup3\n add\n /* \"#utility.yul\":2226:2269 */\n mstore\n /* \"#utility.yul\":2095:2113 */\n 0x44\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":222:261 OnlySelfAuth(msg.sender, address(this)) */\n tag_23:\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n revert\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":174:268 if (msg.sender != address(this)) {... */\n tag_22:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":631:636 _code */\n dup2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":625:637 mload(_code) */\n mload\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":620:622 32 */\n 0x20\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":613:618 _code */\n dup4\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":609:623 add(_code, 32) */\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":596:607 callvalue() */\n callvalue\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":589:638 create(callvalue(), add(_code, 32), mload(_code)) */\n create\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":581:638 addr := create(callvalue(), add(_code, 32), mload(_code)) */\n swap1\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":649:667 addr == address(0) */\n 0xffffffffffffffffffffffffffffffffffffffff\n dup2\n and\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":645:695 if (addr == address(0)) revert CreateFailed(_code) */\n tag_26\n jumpi\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":689:694 _code */\n dup2\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":676:695 CreateFailed(_code) */\n mload(0x40)\n 0x0d25719100000000000000000000000000000000000000000000000000000000\n dup2\n mstore\n 0x04\n add\n tag_23\n swap2\n swap1\n tag_28\n jump\t// in\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":645:695 if (addr == address(0)) revert CreateFailed(_code) */\n tag_26:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":706:727 CreatedContract(addr) */\n mload(0x40)\n /* \"#utility.yul\":1893:1935 */\n 0xffffffffffffffffffffffffffffffffffffffff\n /* \"#utility.yul\":1881:1936 */\n dup3\n and\n /* \"#utility.yul\":1863:1937 */\n dup2\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":706:727 CreatedContract(addr) */\n 0xa506ad4e7f05eceba62a023c3219e5bd98a615f4fa87e2afb08a2da5cf62bf0c\n swap1\n /* \"#utility.yul\":1851:1853 */\n 0x20\n /* \"#utility.yul\":1836:1854 */\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":706:727 CreatedContract(addr) */\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n log1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":456:732 function createContract(bytes memory _code) public override virtual payable onlySelf returns (address addr) {... */\n swap2\n swap1\n pop\n jump\t// out\n /* \"#utility.yul\":14:346 */\n tag_7:\n /* \"#utility.yul\":72:78 */\n 0x00\n /* \"#utility.yul\":125:127 */\n 0x20\n /* \"#utility.yul\":113:122 */\n dup3\n /* \"#utility.yul\":104:111 */\n dup5\n /* \"#utility.yul\":100:123 */\n sub\n /* \"#utility.yul\":96:128 */\n slt\n /* \"#utility.yul\":93:145 */\n iszero\n tag_34\n jumpi\n /* \"#utility.yul\":141:142 */\n 0x00\n /* \"#utility.yul\":138:139 */\n dup1\n /* \"#utility.yul\":131:143 */\n revert\n /* \"#utility.yul\":93:145 */\n tag_34:\n /* \"#utility.yul\":180:189 */\n dup2\n /* \"#utility.yul\":167:190 */\n calldataload\n /* \"#utility.yul\":230:296 */\n 0xffffffff00000000000000000000000000000000000000000000000000000000\n /* \"#utility.yul\":223:228 */\n dup2\n /* \"#utility.yul\":219:297 */\n and\n /* \"#utility.yul\":212:217 */\n dup2\n /* \"#utility.yul\":209:298 */\n eq\n /* \"#utility.yul\":199:316 */\n tag_35\n jumpi\n /* \"#utility.yul\":312:313 */\n 0x00\n /* \"#utility.yul\":309:310 */\n dup1\n /* \"#utility.yul\":302:314 */\n revert\n /* \"#utility.yul\":199:316 */\n tag_35:\n /* \"#utility.yul\":335:340 */\n swap4\n /* \"#utility.yul\":14:346 */\n swap3\n pop\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":543:727 */\n tag_31:\n /* \"#utility.yul\":595:672 */\n 0x4e487b7100000000000000000000000000000000000000000000000000000000\n /* \"#utility.yul\":592:593 */\n 0x00\n /* \"#utility.yul\":585:673 */\n mstore\n /* \"#utility.yul\":692:696 */\n 0x41\n /* \"#utility.yul\":689:690 */\n 0x04\n /* \"#utility.yul\":682:697 */\n mstore\n /* \"#utility.yul\":716:720 */\n 0x24\n /* \"#utility.yul\":713:714 */\n 0x00\n /* \"#utility.yul\":706:721 */\n revert\n /* \"#utility.yul\":732:1712 */\n tag_13:\n /* \"#utility.yul\":800:806 */\n 0x00\n /* \"#utility.yul\":853:855 */\n 0x20\n /* \"#utility.yul\":841:850 */\n dup3\n /* \"#utility.yul\":832:839 */\n dup5\n /* \"#utility.yul\":828:851 */\n sub\n /* \"#utility.yul\":824:856 */\n slt\n /* \"#utility.yul\":821:873 */\n iszero\n tag_39\n jumpi\n /* \"#utility.yul\":869:870 */\n 0x00\n /* \"#utility.yul\":866:867 */\n dup1\n /* \"#utility.yul\":859:871 */\n revert\n /* \"#utility.yul\":821:873 */\n tag_39:\n /* \"#utility.yul\":909:918 */\n dup2\n /* \"#utility.yul\":896:919 */\n calldataload\n /* \"#utility.yul\":938:956 */\n 0xffffffffffffffff\n /* \"#utility.yul\":979:981 */\n dup1\n /* \"#utility.yul\":971:977 */\n dup3\n /* \"#utility.yul\":968:982 */\n gt\n /* \"#utility.yul\":965:999 */\n iszero\n tag_40\n jumpi\n /* \"#utility.yul\":995:996 */\n 0x00\n /* \"#utility.yul\":992:993 */\n dup1\n /* \"#utility.yul\":985:997 */\n revert\n /* \"#utility.yul\":965:999 */\n tag_40:\n /* \"#utility.yul\":1033:1039 */\n dup2\n /* \"#utility.yul\":1022:1031 */\n dup5\n /* \"#utility.yul\":1018:1040 */\n add\n /* \"#utility.yul\":1008:1040 */\n swap2\n pop\n /* \"#utility.yul\":1078:1085 */\n dup5\n /* \"#utility.yul\":1071:1075 */\n 0x1f\n /* \"#utility.yul\":1067:1069 */\n dup4\n /* \"#utility.yul\":1063:1076 */\n add\n /* \"#utility.yul\":1059:1086 */\n slt\n /* \"#utility.yul\":1049:1104 */\n tag_41\n jumpi\n /* \"#utility.yul\":1100:1101 */\n 0x00\n /* \"#utility.yul\":1097:1098 */\n dup1\n /* \"#utility.yul\":1090:1102 */\n revert\n /* \"#utility.yul\":1049:1104 */\n tag_41:\n /* \"#utility.yul\":1136:1138 */\n dup2\n /* \"#utility.yul\":1123:1139 */\n calldataload\n /* \"#utility.yul\":1158:1160 */\n dup2\n /* \"#utility.yul\":1154:1156 */\n dup2\n /* \"#utility.yul\":1151:1161 */\n gt\n /* \"#utility.yul\":1148:1184 */\n iszero\n tag_43\n jumpi\n /* \"#utility.yul\":1164:1182 */\n tag_43\n tag_31\n jump\t// in\n tag_43:\n /* \"#utility.yul\":1298:1300 */\n 0x40\n /* \"#utility.yul\":1292:1301 */\n mload\n /* \"#utility.yul\":1360:1364 */\n 0x1f\n /* \"#utility.yul\":1352:1365 */\n dup3\n add\n /* \"#utility.yul\":1203:1269 */\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0\n /* \"#utility.yul\":1348:1370 */\n swap1\n dup2\n and\n /* \"#utility.yul\":1372:1374 */\n 0x3f\n /* \"#utility.yul\":1344:1375 */\n add\n /* \"#utility.yul\":1340:1380 */\n and\n /* \"#utility.yul\":1328:1381 */\n dup2\n add\n swap1\n /* \"#utility.yul\":1396:1414 */\n dup4\n dup3\n gt\n /* \"#utility.yul\":1416:1438 */\n dup2\n dup4\n lt\n /* \"#utility.yul\":1393:1439 */\n or\n /* \"#utility.yul\":1390:1462 */\n iszero\n tag_45\n jumpi\n /* \"#utility.yul\":1442:1460 */\n tag_45\n tag_31\n jump\t// in\n tag_45:\n /* \"#utility.yul\":1482:1492 */\n dup2\n /* \"#utility.yul\":1478:1480 */\n 0x40\n /* \"#utility.yul\":1471:1493 */\n mstore\n /* \"#utility.yul\":1517:1519 */\n dup3\n /* \"#utility.yul\":1509:1515 */\n dup2\n /* \"#utility.yul\":1502:1520 */\n mstore\n /* \"#utility.yul\":1557:1564 */\n dup8\n /* \"#utility.yul\":1552:1554 */\n 0x20\n /* \"#utility.yul\":1547:1549 */\n dup5\n /* \"#utility.yul\":1543:1545 */\n dup8\n /* \"#utility.yul\":1539:1550 */\n add\n /* \"#utility.yul\":1535:1555 */\n add\n /* \"#utility.yul\":1532:1565 */\n gt\n /* \"#utility.yul\":1529:1582 */\n iszero\n tag_46\n jumpi\n /* \"#utility.yul\":1578:1579 */\n 0x00\n /* \"#utility.yul\":1575:1576 */\n dup1\n /* \"#utility.yul\":1568:1580 */\n revert\n /* \"#utility.yul\":1529:1582 */\n tag_46:\n /* \"#utility.yul\":1634:1636 */\n dup3\n /* \"#utility.yul\":1629:1631 */\n 0x20\n /* \"#utility.yul\":1625:1627 */\n dup7\n /* \"#utility.yul\":1621:1632 */\n add\n /* \"#utility.yul\":1616:1618 */\n 0x20\n /* \"#utility.yul\":1608:1614 */\n dup4\n /* \"#utility.yul\":1604:1619 */\n add\n /* \"#utility.yul\":1591:1637 */\n calldatacopy\n /* \"#utility.yul\":1679:1680 */\n 0x00\n /* \"#utility.yul\":1657:1672 */\n swap3\n dup2\n add\n /* \"#utility.yul\":1674:1676 */\n 0x20\n /* \"#utility.yul\":1653:1677 */\n add\n /* \"#utility.yul\":1646:1681 */\n swap3\n swap1\n swap3\n mstore\n pop\n /* \"#utility.yul\":1661:1667 */\n swap6\n /* \"#utility.yul\":732:1712 */\n swap5\n pop\n pop\n pop\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":2280:2885 */\n tag_28:\n /* \"#utility.yul\":2390:2394 */\n 0x00\n /* \"#utility.yul\":2419:2421 */\n 0x20\n /* \"#utility.yul\":2448:2450 */\n dup1\n /* \"#utility.yul\":2437:2446 */\n dup4\n /* \"#utility.yul\":2430:2451 */\n mstore\n /* \"#utility.yul\":2480:2486 */\n dup4\n /* \"#utility.yul\":2474:2487 */\n mload\n /* \"#utility.yul\":2523:2529 */\n dup1\n /* \"#utility.yul\":2518:2520 */\n dup3\n /* \"#utility.yul\":2507:2516 */\n dup6\n /* \"#utility.yul\":2503:2521 */\n add\n /* \"#utility.yul\":2496:2530 */\n mstore\n /* \"#utility.yul\":2548:2549 */\n 0x00\n /* \"#utility.yul\":2558:2698 */\n tag_50:\n /* \"#utility.yul\":2572:2578 */\n dup2\n /* \"#utility.yul\":2569:2570 */\n dup2\n /* \"#utility.yul\":2566:2579 */\n lt\n /* \"#utility.yul\":2558:2698 */\n iszero\n tag_52\n jumpi\n /* \"#utility.yul\":2667:2681 */\n dup6\n dup2\n add\n /* \"#utility.yul\":2663:2686 */\n dup4\n add\n /* \"#utility.yul\":2657:2687 */\n mload\n /* \"#utility.yul\":2633:2650 */\n dup6\n dup3\n add\n /* \"#utility.yul\":2652:2654 */\n 0x40\n /* \"#utility.yul\":2629:2655 */\n add\n /* \"#utility.yul\":2622:2688 */\n mstore\n /* \"#utility.yul\":2587:2597 */\n dup3\n add\n /* \"#utility.yul\":2558:2698 */\n jump(tag_50)\n tag_52:\n /* \"#utility.yul\":2562:2565 */\n pop\n /* \"#utility.yul\":2747:2748 */\n 0x00\n /* \"#utility.yul\":2742:2744 */\n 0x40\n /* \"#utility.yul\":2733:2739 */\n dup3\n /* \"#utility.yul\":2722:2731 */\n dup7\n /* \"#utility.yul\":2718:2740 */\n add\n /* \"#utility.yul\":2714:2745 */\n add\n /* \"#utility.yul\":2707:2749 */\n mstore\n /* \"#utility.yul\":2876:2878 */\n 0x40\n /* \"#utility.yul\":2806:2872 */\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0\n /* \"#utility.yul\":2801:2803 */\n 0x1f\n /* \"#utility.yul\":2793:2799 */\n dup4\n /* \"#utility.yul\":2789:2804 */\n add\n /* \"#utility.yul\":2785:2873 */\n and\n /* \"#utility.yul\":2774:2783 */\n dup6\n /* \"#utility.yul\":2770:2874 */\n add\n /* \"#utility.yul\":2766:2879 */\n add\n /* \"#utility.yul\":2758:2879 */\n swap3\n pop\n pop\n pop\n /* \"#utility.yul\":2280:2885 */\n swap3\n swap2\n pop\n pop\n jump\t// out\n\n auxdata: 0xa264697066735822122001c76a69e8b3fef98970ac002bb7976078d0e17b12897e7965b9442691a3a58464736f6c63430008120033\n}\n", + "bytecode": { + "functionDebugData": {}, + "generatedSources": [], + "linkReferences": {}, + "object": "608060405234801561001057600080fd5b5061040e806100206000396000f3fe6080604052600436106100295760003560e01c806301ffc9a71461002e57806390042baf14610063575b600080fd5b34801561003a57600080fd5b5061004e610049366004610225565b61009b565b60405190151581526020015b60405180910390f35b61007661007136600461029d565b610136565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161005a565b60007f6ffbd451000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316016100ee57506001919050565b507fffffffff00000000000000000000000000000000000000000000000000000000167f01ffc9a7000000000000000000000000000000000000000000000000000000001490565b600033301461017e576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044015b60405180910390fd5b81516020830134f0905073ffffffffffffffffffffffffffffffffffffffff81166101d757816040517f0d257191000000000000000000000000000000000000000000000000000000008152600401610175919061036c565b60405173ffffffffffffffffffffffffffffffffffffffff821681527fa506ad4e7f05eceba62a023c3219e5bd98a615f4fa87e2afb08a2da5cf62bf0c9060200160405180910390a1919050565b60006020828403121561023757600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461026757600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156102af57600080fd5b813567ffffffffffffffff808211156102c757600080fd5b818401915084601f8301126102db57600080fd5b8135818111156102ed576102ed61026e565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156103335761033361026e565b8160405282815287602084870101111561034c57600080fd5b826020860160208301376000928101602001929092525095945050505050565b600060208083528351808285015260005b818110156103995785810183015185820160400152820161037d565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f830116850101925050509291505056fea264697066735822122001c76a69e8b3fef98970ac002bb7976078d0e17b12897e7965b9442691a3a58464736f6c63430008120033", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x40E DUP1 PUSH2 0x20 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x29 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x1FFC9A7 EQ PUSH2 0x2E JUMPI DUP1 PUSH4 0x90042BAF EQ PUSH2 0x63 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x3A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x4E PUSH2 0x49 CALLDATASIZE PUSH1 0x4 PUSH2 0x225 JUMP JUMPDEST PUSH2 0x9B JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x76 PUSH2 0x71 CALLDATASIZE PUSH1 0x4 PUSH2 0x29D JUMP JUMPDEST PUSH2 0x136 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0x5A JUMP JUMPDEST PUSH1 0x0 PUSH32 0x6FFBD45100000000000000000000000000000000000000000000000000000000 PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP4 AND ADD PUSH2 0xEE JUMPI POP PUSH1 0x1 SWAP2 SWAP1 POP JUMP JUMPDEST POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND PUSH32 0x1FFC9A700000000000000000000000000000000000000000000000000000000 EQ SWAP1 JUMP JUMPDEST PUSH1 0x0 CALLER ADDRESS EQ PUSH2 0x17E JUMPI PUSH1 0x40 MLOAD PUSH32 0xE125889400000000000000000000000000000000000000000000000000000000 DUP2 MSTORE CALLER PUSH1 0x4 DUP3 ADD MSTORE ADDRESS PUSH1 0x24 DUP3 ADD MSTORE PUSH1 0x44 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST DUP2 MLOAD PUSH1 0x20 DUP4 ADD CALLVALUE CREATE SWAP1 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND PUSH2 0x1D7 JUMPI DUP2 PUSH1 0x40 MLOAD PUSH32 0xD25719100000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x175 SWAP2 SWAP1 PUSH2 0x36C JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 AND DUP2 MSTORE PUSH32 0xA506AD4E7F05ECEBA62A023C3219E5BD98A615F4FA87E2AFB08A2DA5CF62BF0C SWAP1 PUSH1 0x20 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x237 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND DUP2 EQ PUSH2 0x267 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH32 0x4E487B7100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 MSTORE PUSH1 0x41 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x2AF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0x2C7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 DUP5 ADD SWAP2 POP DUP5 PUSH1 0x1F DUP4 ADD SLT PUSH2 0x2DB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD DUP2 DUP2 GT ISZERO PUSH2 0x2ED JUMPI PUSH2 0x2ED PUSH2 0x26E JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1F DUP3 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 DUP2 AND PUSH1 0x3F ADD AND DUP2 ADD SWAP1 DUP4 DUP3 GT DUP2 DUP4 LT OR ISZERO PUSH2 0x333 JUMPI PUSH2 0x333 PUSH2 0x26E JUMP JUMPDEST DUP2 PUSH1 0x40 MSTORE DUP3 DUP2 MSTORE DUP8 PUSH1 0x20 DUP5 DUP8 ADD ADD GT ISZERO PUSH2 0x34C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP4 ADD CALLDATACOPY PUSH1 0x0 SWAP3 DUP2 ADD PUSH1 0x20 ADD SWAP3 SWAP1 SWAP3 MSTORE POP SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP1 DUP4 MSTORE DUP4 MLOAD DUP1 DUP3 DUP6 ADD MSTORE PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0x399 JUMPI DUP6 DUP2 ADD DUP4 ADD MLOAD DUP6 DUP3 ADD PUSH1 0x40 ADD MSTORE DUP3 ADD PUSH2 0x37D JUMP JUMPDEST POP PUSH1 0x0 PUSH1 0x40 DUP3 DUP7 ADD ADD MSTORE PUSH1 0x40 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 PUSH1 0x1F DUP4 ADD AND DUP6 ADD ADD SWAP3 POP POP POP SWAP3 SWAP2 POP POP JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 ADD 0xC7 PUSH11 0x69E8B3FEF98970AC002BB7 SWAP8 PUSH1 0x78 0xD0 0xE1 PUSH28 0x12897E7965B9442691A3A58464736F6C634300081200330000000000 ", + "sourceMap": "169:1008:4:-:0;;;;;;;;;;;;;;;;;;;" + }, + "deployedBytecode": { + "functionDebugData": { + "@createContract_876": { + "entryPoint": 310, + "id": 876, + "parameterSlots": 1, + "returnSlots": 1 + }, + "@supportsInterface_901": { + "entryPoint": 155, + "id": 901, + "parameterSlots": 1, + "returnSlots": 1 + }, + "@supportsInterface_919": { + "entryPoint": null, + "id": 919, + "parameterSlots": 1, + "returnSlots": 1 + }, + "abi_decode_tuple_t_bytes4": { + "entryPoint": 549, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_decode_tuple_t_bytes_memory_ptr": { + "entryPoint": 669, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_tuple_t_address__to_t_address__fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_tuple_t_address_t_address__to_t_address_t_address__fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 3, + "returnSlots": 1 + }, + "abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_tuple_t_bytes_memory_ptr__to_t_bytes_memory_ptr__fromStack_reversed": { + "entryPoint": 876, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "panic_error_0x41": { + "entryPoint": 622, + "id": null, + "parameterSlots": 0, + "returnSlots": 0 + } + }, + "generatedSources": [ + { + "ast": { + "nodeType": "YulBlock", + "src": "0:2887:22", + "statements": [ + { + "nodeType": "YulBlock", + "src": "6:3:22", + "statements": [] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "83:263:22", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "129:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "138:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "141:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "131:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "131:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "131:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "104:7:22" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "113:9:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "100:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "100:23:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "125:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "96:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "96:32:22" + }, + "nodeType": "YulIf", + "src": "93:52:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "154:36:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "180:9:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "167:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "167:23:22" + }, + "variables": [ + { + "name": "value", + "nodeType": "YulTypedName", + "src": "158:5:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "300:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "309:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "312:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "302:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "302:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "302:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "212:5:22" + }, + { + "arguments": [ + { + "name": "value", + "nodeType": "YulIdentifier", + "src": "223:5:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "230:66:22", + "type": "", + "value": "0xffffffff00000000000000000000000000000000000000000000000000000000" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "219:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "219:78:22" + } + ], + "functionName": { + "name": "eq", + "nodeType": "YulIdentifier", + "src": "209:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "209:89:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "202:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "202:97:22" + }, + "nodeType": "YulIf", + "src": "199:117:22" + }, + { + "nodeType": "YulAssignment", + "src": "325:15:22", + "value": { + "name": "value", + "nodeType": "YulIdentifier", + "src": "335:5:22" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "325:6:22" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_bytes4", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "49:9:22", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "60:7:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "72:6:22", + "type": "" + } + ], + "src": "14:332:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "446:92:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "456:26:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "468:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "479:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "464:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "464:18:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "456:4:22" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "498:9:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "523:6:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "516:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "516:14:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "509:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "509:22:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "491:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "491:41:22" + }, + "nodeType": "YulExpressionStatement", + "src": "491:41:22" + } + ] + }, + "name": "abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "415:9:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "426:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "437:4:22", + "type": "" + } + ], + "src": "351:187:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "575:152:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "592:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "595:77:22", + "type": "", + "value": "35408467139433450592217433187231851964531694900788300625387963629091585785856" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "585:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "585:88:22" + }, + "nodeType": "YulExpressionStatement", + "src": "585:88:22" + }, + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "689:1:22", + "type": "", + "value": "4" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "692:4:22", + "type": "", + "value": "0x41" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "682:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "682:15:22" + }, + "nodeType": "YulExpressionStatement", + "src": "682:15:22" + }, + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "713:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "716:4:22", + "type": "", + "value": "0x24" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "706:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "706:15:22" + }, + "nodeType": "YulExpressionStatement", + "src": "706:15:22" + } + ] + }, + "name": "panic_error_0x41", + "nodeType": "YulFunctionDefinition", + "src": "543:184:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "811:901:22", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "857:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "866:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "869:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "859:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "859:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "859:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "832:7:22" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "841:9:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "828:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "828:23:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "853:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "824:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "824:32:22" + }, + "nodeType": "YulIf", + "src": "821:52:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "882:37:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "909:9:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "896:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "896:23:22" + }, + "variables": [ + { + "name": "offset", + "nodeType": "YulTypedName", + "src": "886:6:22", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "928:28:22", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "938:18:22", + "type": "", + "value": "0xffffffffffffffff" + }, + "variables": [ + { + "name": "_1", + "nodeType": "YulTypedName", + "src": "932:2:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "983:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "992:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "995:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "985:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "985:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "985:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "971:6:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "979:2:22" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "968:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "968:14:22" + }, + "nodeType": "YulIf", + "src": "965:34:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "1008:32:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1022:9:22" + }, + { + "name": "offset", + "nodeType": "YulIdentifier", + "src": "1033:6:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1018:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "1018:22:22" + }, + "variables": [ + { + "name": "_2", + "nodeType": "YulTypedName", + "src": "1012:2:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1088:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1097:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1100:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "1090:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "1090:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "1090:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "1067:2:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1071:4:22", + "type": "", + "value": "0x1f" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1063:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "1063:13:22" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "1078:7:22" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "1059:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "1059:27:22" + } + ], + "functionName": { + "name": "iszero", + "nodeType": "YulIdentifier", + "src": "1052:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "1052:35:22" + }, + "nodeType": "YulIf", + "src": "1049:55:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "1113:26:22", + "value": { + "arguments": [ + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "1136:2:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "1123:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "1123:16:22" + }, + "variables": [ + { + "name": "_3", + "nodeType": "YulTypedName", + "src": "1117:2:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1162:22:22", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "panic_error_0x41", + "nodeType": "YulIdentifier", + "src": "1164:16:22" + }, + "nodeType": "YulFunctionCall", + "src": "1164:18:22" + }, + "nodeType": "YulExpressionStatement", + "src": "1164:18:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "_3", + "nodeType": "YulIdentifier", + "src": "1154:2:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "1158:2:22" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "1151:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "1151:10:22" + }, + "nodeType": "YulIf", + "src": "1148:36:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "1193:76:22", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1203:66:22", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0" + }, + "variables": [ + { + "name": "_4", + "nodeType": "YulTypedName", + "src": "1197:2:22", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "1278:23:22", + "value": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1298:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "1292:5:22" + }, + "nodeType": "YulFunctionCall", + "src": "1292:9:22" + }, + "variables": [ + { + "name": "memPtr", + "nodeType": "YulTypedName", + "src": "1282:6:22", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "1310:71:22", + "value": { + "arguments": [ + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "1332:6:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "_3", + "nodeType": "YulIdentifier", + "src": "1356:2:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1360:4:22", + "type": "", + "value": "0x1f" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1352:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "1352:13:22" + }, + { + "name": "_4", + "nodeType": "YulIdentifier", + "src": "1367:2:22" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "1348:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "1348:22:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1372:2:22", + "type": "", + "value": "63" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1344:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "1344:31:22" + }, + { + "name": "_4", + "nodeType": "YulIdentifier", + "src": "1377:2:22" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "1340:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "1340:40:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1328:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "1328:53:22" + }, + "variables": [ + { + "name": "newFreePtr", + "nodeType": "YulTypedName", + "src": "1314:10:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1440:22:22", + "statements": [ + { + "expression": { + "arguments": [], + "functionName": { + "name": "panic_error_0x41", + "nodeType": "YulIdentifier", + "src": "1442:16:22" + }, + "nodeType": "YulFunctionCall", + "src": "1442:18:22" + }, + "nodeType": "YulExpressionStatement", + "src": "1442:18:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "newFreePtr", + "nodeType": "YulIdentifier", + "src": "1399:10:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "1411:2:22" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "1396:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "1396:18:22" + }, + { + "arguments": [ + { + "name": "newFreePtr", + "nodeType": "YulIdentifier", + "src": "1419:10:22" + }, + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "1431:6:22" + } + ], + "functionName": { + "name": "lt", + "nodeType": "YulIdentifier", + "src": "1416:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "1416:22:22" + } + ], + "functionName": { + "name": "or", + "nodeType": "YulIdentifier", + "src": "1393:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "1393:46:22" + }, + "nodeType": "YulIf", + "src": "1390:72:22" + }, + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1478:2:22", + "type": "", + "value": "64" + }, + { + "name": "newFreePtr", + "nodeType": "YulIdentifier", + "src": "1482:10:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "1471:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "1471:22:22" + }, + "nodeType": "YulExpressionStatement", + "src": "1471:22:22" + }, + { + "expression": { + "arguments": [ + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "1509:6:22" + }, + { + "name": "_3", + "nodeType": "YulIdentifier", + "src": "1517:2:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "1502:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "1502:18:22" + }, + "nodeType": "YulExpressionStatement", + "src": "1502:18:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1566:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1575:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1578:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "1568:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "1568:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "1568:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "1543:2:22" + }, + { + "name": "_3", + "nodeType": "YulIdentifier", + "src": "1547:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1539:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "1539:11:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1552:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1535:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "1535:20:22" + }, + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "1557:7:22" + } + ], + "functionName": { + "name": "gt", + "nodeType": "YulIdentifier", + "src": "1532:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "1532:33:22" + }, + "nodeType": "YulIf", + "src": "1529:53:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "1608:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1616:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1604:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "1604:15:22" + }, + { + "arguments": [ + { + "name": "_2", + "nodeType": "YulIdentifier", + "src": "1625:2:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1629:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1621:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "1621:11:22" + }, + { + "name": "_3", + "nodeType": "YulIdentifier", + "src": "1634:2:22" + } + ], + "functionName": { + "name": "calldatacopy", + "nodeType": "YulIdentifier", + "src": "1591:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "1591:46:22" + }, + "nodeType": "YulExpressionStatement", + "src": "1591:46:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "1661:6:22" + }, + { + "name": "_3", + "nodeType": "YulIdentifier", + "src": "1669:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1657:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "1657:15:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1674:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1653:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "1653:24:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1679:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "1646:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "1646:35:22" + }, + "nodeType": "YulExpressionStatement", + "src": "1646:35:22" + }, + { + "nodeType": "YulAssignment", + "src": "1690:16:22", + "value": { + "name": "memPtr", + "nodeType": "YulIdentifier", + "src": "1700:6:22" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "1690:6:22" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_bytes_memory_ptr", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "777:9:22", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "788:7:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "800:6:22", + "type": "" + } + ], + "src": "732:980:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "1818:125:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "1828:26:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1840:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1851:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1836:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "1836:18:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "1828:4:22" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "1870:9:22" + }, + { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "1885:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1893:42:22", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffff" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "1881:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "1881:55:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "1863:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "1863:74:22" + }, + "nodeType": "YulExpressionStatement", + "src": "1863:74:22" + } + ] + }, + "name": "abi_encode_tuple_t_address__to_t_address__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "1787:9:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "1798:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "1809:4:22", + "type": "" + } + ], + "src": "1717:226:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "2077:198:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "2087:26:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2099:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2110:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2095:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "2095:18:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "2087:4:22" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "2122:52:22", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2132:42:22", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffff" + }, + "variables": [ + { + "name": "_1", + "nodeType": "YulTypedName", + "src": "2126:2:22", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2190:9:22" + }, + { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "2205:6:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "2213:2:22" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "2201:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "2201:15:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "2183:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "2183:34:22" + }, + "nodeType": "YulExpressionStatement", + "src": "2183:34:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2237:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2248:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2233:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "2233:18:22" + }, + { + "arguments": [ + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "2257:6:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "2265:2:22" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "2253:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "2253:15:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "2226:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "2226:43:22" + }, + "nodeType": "YulExpressionStatement", + "src": "2226:43:22" + } + ] + }, + "name": "abi_encode_tuple_t_address_t_address__to_t_address_t_address__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "2038:9:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "2049:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "2057:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "2068:4:22", + "type": "" + } + ], + "src": "1948:327:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "2399:486:22", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "2409:12:22", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2419:2:22", + "type": "", + "value": "32" + }, + "variables": [ + { + "name": "_1", + "nodeType": "YulTypedName", + "src": "2413:2:22", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2437:9:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "2448:2:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "2430:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "2430:21:22" + }, + "nodeType": "YulExpressionStatement", + "src": "2430:21:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "2460:27:22", + "value": { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "2480:6:22" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "2474:5:22" + }, + "nodeType": "YulFunctionCall", + "src": "2474:13:22" + }, + "variables": [ + { + "name": "length", + "nodeType": "YulTypedName", + "src": "2464:6:22", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2507:9:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "2518:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2503:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "2503:18:22" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "2523:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "2496:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "2496:34:22" + }, + "nodeType": "YulExpressionStatement", + "src": "2496:34:22" + }, + { + "nodeType": "YulVariableDeclaration", + "src": "2539:10:22", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2548:1:22", + "type": "", + "value": "0" + }, + "variables": [ + { + "name": "i", + "nodeType": "YulTypedName", + "src": "2543:1:22", + "type": "" + } + ] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "2608:90:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2637:9:22" + }, + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "2648:1:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2633:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "2633:17:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2652:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2629:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "2629:26:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "2671:6:22" + }, + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "2679:1:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2667:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "2667:14:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "2683:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2663:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "2663:23:22" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "2657:5:22" + }, + "nodeType": "YulFunctionCall", + "src": "2657:30:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "2622:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "2622:66:22" + }, + "nodeType": "YulExpressionStatement", + "src": "2622:66:22" + } + ] + }, + "condition": { + "arguments": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "2569:1:22" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "2572:6:22" + } + ], + "functionName": { + "name": "lt", + "nodeType": "YulIdentifier", + "src": "2566:2:22" + }, + "nodeType": "YulFunctionCall", + "src": "2566:13:22" + }, + "nodeType": "YulForLoop", + "post": { + "nodeType": "YulBlock", + "src": "2580:19:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "2582:15:22", + "value": { + "arguments": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "2591:1:22" + }, + { + "name": "_1", + "nodeType": "YulIdentifier", + "src": "2594:2:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2587:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "2587:10:22" + }, + "variableNames": [ + { + "name": "i", + "nodeType": "YulIdentifier", + "src": "2582:1:22" + } + ] + } + ] + }, + "pre": { + "nodeType": "YulBlock", + "src": "2562:3:22", + "statements": [] + }, + "src": "2558:140:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2722:9:22" + }, + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "2733:6:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2718:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "2718:22:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2742:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2714:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "2714:31:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2747:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "2707:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "2707:42:22" + }, + "nodeType": "YulExpressionStatement", + "src": "2707:42:22" + }, + { + "nodeType": "YulAssignment", + "src": "2758:121:22", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "2774:9:22" + }, + { + "arguments": [ + { + "arguments": [ + { + "name": "length", + "nodeType": "YulIdentifier", + "src": "2793:6:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2801:2:22", + "type": "", + "value": "31" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2789:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "2789:15:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2806:66:22", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "2785:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "2785:88:22" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2770:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "2770:104:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2876:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2766:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "2766:113:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "2758:4:22" + } + ] + } + ] + }, + "name": "abi_encode_tuple_t_bytes_memory_ptr__to_t_bytes_memory_ptr__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "2368:9:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "2379:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "2390:4:22", + "type": "" + } + ], + "src": "2280:605:22" + } + ] + }, + "contents": "{\n { }\n function abi_decode_tuple_t_bytes4(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let value := calldataload(headStart)\n if iszero(eq(value, and(value, 0xffffffff00000000000000000000000000000000000000000000000000000000))) { revert(0, 0) }\n value0 := value\n }\n function abi_encode_tuple_t_bool__to_t_bool__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, iszero(iszero(value0)))\n }\n function panic_error_0x41()\n {\n mstore(0, 35408467139433450592217433187231851964531694900788300625387963629091585785856)\n mstore(4, 0x41)\n revert(0, 0x24)\n }\n function abi_decode_tuple_t_bytes_memory_ptr(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n let offset := calldataload(headStart)\n let _1 := 0xffffffffffffffff\n if gt(offset, _1) { revert(0, 0) }\n let _2 := add(headStart, offset)\n if iszero(slt(add(_2, 0x1f), dataEnd)) { revert(0, 0) }\n let _3 := calldataload(_2)\n if gt(_3, _1) { panic_error_0x41() }\n let _4 := 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0\n let memPtr := mload(64)\n let newFreePtr := add(memPtr, and(add(and(add(_3, 0x1f), _4), 63), _4))\n if or(gt(newFreePtr, _1), lt(newFreePtr, memPtr)) { panic_error_0x41() }\n mstore(64, newFreePtr)\n mstore(memPtr, _3)\n if gt(add(add(_2, _3), 32), dataEnd) { revert(0, 0) }\n calldatacopy(add(memPtr, 32), add(_2, 32), _3)\n mstore(add(add(memPtr, _3), 32), 0)\n value0 := memPtr\n }\n function abi_encode_tuple_t_address__to_t_address__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, and(value0, 0xffffffffffffffffffffffffffffffffffffffff))\n }\n function abi_encode_tuple_t_address_t_address__to_t_address_t_address__fromStack_reversed(headStart, value1, value0) -> tail\n {\n tail := add(headStart, 64)\n let _1 := 0xffffffffffffffffffffffffffffffffffffffff\n mstore(headStart, and(value0, _1))\n mstore(add(headStart, 32), and(value1, _1))\n }\n function abi_encode_tuple_t_bytes_memory_ptr__to_t_bytes_memory_ptr__fromStack_reversed(headStart, value0) -> tail\n {\n let _1 := 32\n mstore(headStart, _1)\n let length := mload(value0)\n mstore(add(headStart, _1), length)\n let i := 0\n for { } lt(i, length) { i := add(i, _1) }\n {\n mstore(add(add(headStart, i), 64), mload(add(add(value0, i), _1)))\n }\n mstore(add(add(headStart, length), 64), 0)\n tail := add(add(headStart, and(add(length, 31), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0)), 64)\n }\n}", + "id": 22, + "language": "Yul", + "name": "#utility.yul" + } + ], + "immutableReferences": {}, + "linkReferences": {}, + "object": "6080604052600436106100295760003560e01c806301ffc9a71461002e57806390042baf14610063575b600080fd5b34801561003a57600080fd5b5061004e610049366004610225565b61009b565b60405190151581526020015b60405180910390f35b61007661007136600461029d565b610136565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161005a565b60007f6ffbd451000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316016100ee57506001919050565b507fffffffff00000000000000000000000000000000000000000000000000000000167f01ffc9a7000000000000000000000000000000000000000000000000000000001490565b600033301461017e576040517fe12588940000000000000000000000000000000000000000000000000000000081523360048201523060248201526044015b60405180910390fd5b81516020830134f0905073ffffffffffffffffffffffffffffffffffffffff81166101d757816040517f0d257191000000000000000000000000000000000000000000000000000000008152600401610175919061036c565b60405173ffffffffffffffffffffffffffffffffffffffff821681527fa506ad4e7f05eceba62a023c3219e5bd98a615f4fa87e2afb08a2da5cf62bf0c9060200160405180910390a1919050565b60006020828403121561023757600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461026757600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000602082840312156102af57600080fd5b813567ffffffffffffffff808211156102c757600080fd5b818401915084601f8301126102db57600080fd5b8135818111156102ed576102ed61026e565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156103335761033361026e565b8160405282815287602084870101111561034c57600080fd5b826020860160208301376000928101602001929092525095945050505050565b600060208083528351808285015260005b818110156103995785810183015185820160400152820161037d565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f830116850101925050509291505056fea264697066735822122001c76a69e8b3fef98970ac002bb7976078d0e17b12897e7965b9442691a3a58464736f6c63430008120033", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x29 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x1FFC9A7 EQ PUSH2 0x2E JUMPI DUP1 PUSH4 0x90042BAF EQ PUSH2 0x63 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x3A JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x4E PUSH2 0x49 CALLDATASIZE PUSH1 0x4 PUSH2 0x225 JUMP JUMPDEST PUSH2 0x9B JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 ISZERO ISZERO DUP2 MSTORE PUSH1 0x20 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x76 PUSH2 0x71 CALLDATASIZE PUSH1 0x4 PUSH2 0x29D JUMP JUMPDEST PUSH2 0x136 JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SWAP1 SWAP2 AND DUP2 MSTORE PUSH1 0x20 ADD PUSH2 0x5A JUMP JUMPDEST PUSH1 0x0 PUSH32 0x6FFBD45100000000000000000000000000000000000000000000000000000000 PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP4 AND ADD PUSH2 0xEE JUMPI POP PUSH1 0x1 SWAP2 SWAP1 POP JUMP JUMPDEST POP PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 AND PUSH32 0x1FFC9A700000000000000000000000000000000000000000000000000000000 EQ SWAP1 JUMP JUMPDEST PUSH1 0x0 CALLER ADDRESS EQ PUSH2 0x17E JUMPI PUSH1 0x40 MLOAD PUSH32 0xE125889400000000000000000000000000000000000000000000000000000000 DUP2 MSTORE CALLER PUSH1 0x4 DUP3 ADD MSTORE ADDRESS PUSH1 0x24 DUP3 ADD MSTORE PUSH1 0x44 ADD JUMPDEST PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 REVERT JUMPDEST DUP2 MLOAD PUSH1 0x20 DUP4 ADD CALLVALUE CREATE SWAP1 POP PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP2 AND PUSH2 0x1D7 JUMPI DUP2 PUSH1 0x40 MLOAD PUSH32 0xD25719100000000000000000000000000000000000000000000000000000000 DUP2 MSTORE PUSH1 0x4 ADD PUSH2 0x175 SWAP2 SWAP1 PUSH2 0x36C JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH20 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DUP3 AND DUP2 MSTORE PUSH32 0xA506AD4E7F05ECEBA62A023C3219E5BD98A615F4FA87E2AFB08A2DA5CF62BF0C SWAP1 PUSH1 0x20 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 LOG1 SWAP2 SWAP1 POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x237 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH32 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 DUP2 AND DUP2 EQ PUSH2 0x267 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST SWAP4 SWAP3 POP POP POP JUMP JUMPDEST PUSH32 0x4E487B7100000000000000000000000000000000000000000000000000000000 PUSH1 0x0 MSTORE PUSH1 0x41 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x2AF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD PUSH8 0xFFFFFFFFFFFFFFFF DUP1 DUP3 GT ISZERO PUSH2 0x2C7 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 DUP5 ADD SWAP2 POP DUP5 PUSH1 0x1F DUP4 ADD SLT PUSH2 0x2DB JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP2 CALLDATALOAD DUP2 DUP2 GT ISZERO PUSH2 0x2ED JUMPI PUSH2 0x2ED PUSH2 0x26E JUMP JUMPDEST PUSH1 0x40 MLOAD PUSH1 0x1F DUP3 ADD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 SWAP1 DUP2 AND PUSH1 0x3F ADD AND DUP2 ADD SWAP1 DUP4 DUP3 GT DUP2 DUP4 LT OR ISZERO PUSH2 0x333 JUMPI PUSH2 0x333 PUSH2 0x26E JUMP JUMPDEST DUP2 PUSH1 0x40 MSTORE DUP3 DUP2 MSTORE DUP8 PUSH1 0x20 DUP5 DUP8 ADD ADD GT ISZERO PUSH2 0x34C JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST DUP3 PUSH1 0x20 DUP7 ADD PUSH1 0x20 DUP4 ADD CALLDATACOPY PUSH1 0x0 SWAP3 DUP2 ADD PUSH1 0x20 ADD SWAP3 SWAP1 SWAP3 MSTORE POP SWAP6 SWAP5 POP POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP1 DUP4 MSTORE DUP4 MLOAD DUP1 DUP3 DUP6 ADD MSTORE PUSH1 0x0 JUMPDEST DUP2 DUP2 LT ISZERO PUSH2 0x399 JUMPI DUP6 DUP2 ADD DUP4 ADD MLOAD DUP6 DUP3 ADD PUSH1 0x40 ADD MSTORE DUP3 ADD PUSH2 0x37D JUMP JUMPDEST POP PUSH1 0x0 PUSH1 0x40 DUP3 DUP7 ADD ADD MSTORE PUSH1 0x40 PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 PUSH1 0x1F DUP4 ADD AND DUP6 ADD ADD SWAP3 POP POP POP SWAP3 SWAP2 POP POP JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 ADD 0xC7 PUSH11 0x69E8B3FEF98970AC002BB7 SWAP8 PUSH1 0x78 0xD0 0xE1 PUSH28 0x12897E7965B9442691A3A58464736F6C634300081200330000000000 ", + "sourceMap": "169:1008:4:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;942:233;;;;;;;;;;-1:-1:-1;942:233:4;;;;;:::i;:::-;;:::i;:::-;;;516:14:22;;509:22;491:41;;479:2;464:18;942:233:4;;;;;;;;456:276;;;;;;:::i;:::-;;:::i;:::-;;;1893:42:22;1881:55;;;1863:74;;1851:2;1836:18;456:276:4;1717:226:22;942:233:4;1028:4;1044:48;;;;;1040:80;;-1:-1:-1;1109:4:4;;942:233;-1:-1:-1;942:233:4:o;1040:80::-;-1:-1:-1;709:47:5;;725:31;709:47;;942:233:4:o;456:276::-;550:12;178:10:8;200:4;178:27;174:94;;222:39;;;;;235:10;222:39;;;2183:34:22;255:4:8;2233:18:22;;;2226:43;2095:18;;222:39:8;;;;;;;;174:94;631:5:4::1;625:12;620:2;613:5;609:14;596:11;589:49;581:57:::0;-1:-1:-1;649:18:4::1;::::0;::::1;645:50;;689:5;676:19;;;;;;;;;;;:::i;645:50::-;706:21;::::0;1893:42:22;1881:55;;1863:74;;706:21:4::1;::::0;1851:2:22;1836:18;706:21:4::1;;;;;;;456:276:::0;;;:::o;14:332:22:-;72:6;125:2;113:9;104:7;100:23;96:32;93:52;;;141:1;138;131:12;93:52;180:9;167:23;230:66;223:5;219:78;212:5;209:89;199:117;;312:1;309;302:12;199:117;335:5;14:332;-1:-1:-1;;;14:332:22:o;543:184::-;595:77;592:1;585:88;692:4;689:1;682:15;716:4;713:1;706:15;732:980;800:6;853:2;841:9;832:7;828:23;824:32;821:52;;;869:1;866;859:12;821:52;909:9;896:23;938:18;979:2;971:6;968:14;965:34;;;995:1;992;985:12;965:34;1033:6;1022:9;1018:22;1008:32;;1078:7;1071:4;1067:2;1063:13;1059:27;1049:55;;1100:1;1097;1090:12;1049:55;1136:2;1123:16;1158:2;1154;1151:10;1148:36;;;1164:18;;:::i;:::-;1298:2;1292:9;1360:4;1352:13;;1203:66;1348:22;;;1372:2;1344:31;1340:40;1328:53;;;1396:18;;;1416:22;;;1393:46;1390:72;;;1442:18;;:::i;:::-;1482:10;1478:2;1471:22;1517:2;1509:6;1502:18;1557:7;1552:2;1547;1543;1539:11;1535:20;1532:33;1529:53;;;1578:1;1575;1568:12;1529:53;1634:2;1629;1625;1621:11;1616:2;1608:6;1604:15;1591:46;1679:1;1657:15;;;1674:2;1653:24;1646:35;;;;-1:-1:-1;1661:6:22;732:980;-1:-1:-1;;;;;732:980:22:o;2280:605::-;2390:4;2419:2;2448;2437:9;2430:21;2480:6;2474:13;2523:6;2518:2;2507:9;2503:18;2496:34;2548:1;2558:140;2572:6;2569:1;2566:13;2558:140;;;2667:14;;;2663:23;;2657:30;2633:17;;;2652:2;2629:26;2622:66;2587:10;;2558:140;;;2562:3;2747:1;2742:2;2733:6;2722:9;2718:22;2714:31;2707:42;2876:2;2806:66;2801:2;2793:6;2789:15;2785:88;2774:9;2770:104;2766:113;2758:121;;;;2280:605;;;;:::o" + }, + "gasEstimates": { + "creation": { + "codeDepositCost": "207600", + "executionCost": "251", + "totalCost": "207851" + }, + "external": { + "createContract(bytes)": "infinite", + "supportsInterface(bytes4)": "334" + } + }, + "legacyAssembly": { + ".code": [ + { + "begin": 169, + "end": 1177, + "name": "PUSH", + "source": 4, + "value": "80" + }, + { + "begin": 169, + "end": 1177, + "name": "PUSH", + "source": 4, + "value": "40" + }, + { + "begin": 169, + "end": 1177, + "name": "MSTORE", + "source": 4 + }, + { + "begin": 169, + "end": 1177, + "name": "CALLVALUE", + "source": 4 + }, + { + "begin": 169, + "end": 1177, + "name": "DUP1", + "source": 4 + }, + { + "begin": 169, + "end": 1177, + "name": "ISZERO", + "source": 4 + }, + { + "begin": 169, + "end": 1177, + "name": "PUSH [tag]", + "source": 4, + "value": "1" + }, + { + "begin": 169, + "end": 1177, + "name": "JUMPI", + "source": 4 + }, + { + "begin": 169, + "end": 1177, + "name": "PUSH", + "source": 4, + "value": "0" + }, + { + "begin": 169, + "end": 1177, + "name": "DUP1", + "source": 4 + }, + { + "begin": 169, + "end": 1177, + "name": "REVERT", + "source": 4 + }, + { + "begin": 169, + "end": 1177, + "name": "tag", + "source": 4, + "value": "1" + }, + { + "begin": 169, + "end": 1177, + "name": "JUMPDEST", + "source": 4 + }, + { + "begin": 169, + "end": 1177, + "name": "POP", + "source": 4 + }, + { + "begin": 169, + "end": 1177, + "name": "PUSH #[$]", + "source": 4, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 169, + "end": 1177, + "name": "DUP1", + "source": 4 + }, + { + "begin": 169, + "end": 1177, + "name": "PUSH [$]", + "source": 4, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 169, + "end": 1177, + "name": "PUSH", + "source": 4, + "value": "0" + }, + { + "begin": 169, + "end": 1177, + "name": "CODECOPY", + "source": 4 + }, + { + "begin": 169, + "end": 1177, + "name": "PUSH", + "source": 4, + "value": "0" + }, + { + "begin": 169, + "end": 1177, + "name": "RETURN", + "source": 4 + } + ], + ".data": { + "0": { + ".auxdata": "a264697066735822122001c76a69e8b3fef98970ac002bb7976078d0e17b12897e7965b9442691a3a58464736f6c63430008120033", + ".code": [ + { + "begin": 169, + "end": 1177, + "name": "PUSH", + "source": 4, + "value": "80" + }, + { + "begin": 169, + "end": 1177, + "name": "PUSH", + "source": 4, + "value": "40" + }, + { + "begin": 169, + "end": 1177, + "name": "MSTORE", + "source": 4 + }, + { + "begin": 169, + "end": 1177, + "name": "PUSH", + "source": 4, + "value": "4" + }, + { + "begin": 169, + "end": 1177, + "name": "CALLDATASIZE", + "source": 4 + }, + { + "begin": 169, + "end": 1177, + "name": "LT", + "source": 4 + }, + { + "begin": 169, + "end": 1177, + "name": "PUSH [tag]", + "source": 4, + "value": "1" + }, + { + "begin": 169, + "end": 1177, + "name": "JUMPI", + "source": 4 + }, + { + "begin": 169, + "end": 1177, + "name": "PUSH", + "source": 4, + "value": "0" + }, + { + "begin": 169, + "end": 1177, + "name": "CALLDATALOAD", + "source": 4 + }, + { + "begin": 169, + "end": 1177, + "name": "PUSH", + "source": 4, + "value": "E0" + }, + { + "begin": 169, + "end": 1177, + "name": "SHR", + "source": 4 + }, + { + "begin": 169, + "end": 1177, + "name": "DUP1", + "source": 4 + }, + { + "begin": 169, + "end": 1177, + "name": "PUSH", + "source": 4, + "value": "1FFC9A7" + }, + { + "begin": 169, + "end": 1177, + "name": "EQ", + "source": 4 + }, + { + "begin": 169, + "end": 1177, + "name": "PUSH [tag]", + "source": 4, + "value": "2" + }, + { + "begin": 169, + "end": 1177, + "name": "JUMPI", + "source": 4 + }, + { + "begin": 169, + "end": 1177, + "name": "DUP1", + "source": 4 + }, + { + "begin": 169, + "end": 1177, + "name": "PUSH", + "source": 4, + "value": "90042BAF" + }, + { + "begin": 169, + "end": 1177, + "name": "EQ", + "source": 4 + }, + { + "begin": 169, + "end": 1177, + "name": "PUSH [tag]", + "source": 4, + "value": "3" + }, + { + "begin": 169, + "end": 1177, + "name": "JUMPI", + "source": 4 + }, + { + "begin": 169, + "end": 1177, + "name": "tag", + "source": 4, + "value": "1" + }, + { + "begin": 169, + "end": 1177, + "name": "JUMPDEST", + "source": 4 + }, + { + "begin": 169, + "end": 1177, + "name": "PUSH", + "source": 4, + "value": "0" + }, + { + "begin": 169, + "end": 1177, + "name": "DUP1", + "source": 4 + }, + { + "begin": 169, + "end": 1177, + "name": "REVERT", + "source": 4 + }, + { + "begin": 942, + "end": 1175, + "name": "tag", + "source": 4, + "value": "2" + }, + { + "begin": 942, + "end": 1175, + "name": "JUMPDEST", + "source": 4 + }, + { + "begin": 942, + "end": 1175, + "name": "CALLVALUE", + "source": 4 + }, + { + "begin": 942, + "end": 1175, + "name": "DUP1", + "source": 4 + }, + { + "begin": 942, + "end": 1175, + "name": "ISZERO", + "source": 4 + }, + { + "begin": 942, + "end": 1175, + "name": "PUSH [tag]", + "source": 4, + "value": "4" + }, + { + "begin": 942, + "end": 1175, + "name": "JUMPI", + "source": 4 + }, + { + "begin": 942, + "end": 1175, + "name": "PUSH", + "source": 4, + "value": "0" + }, + { + "begin": 942, + "end": 1175, + "name": "DUP1", + "source": 4 + }, + { + "begin": 942, + "end": 1175, + "name": "REVERT", + "source": 4 + }, + { + "begin": 942, + "end": 1175, + "name": "tag", + "source": 4, + "value": "4" + }, + { + "begin": 942, + "end": 1175, + "name": "JUMPDEST", + "source": 4 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 942, + "end": 1175, + "name": "PUSH [tag]", + "source": 4, + "value": "5" + }, + { + "begin": 942, + "end": 1175, + "name": "PUSH [tag]", + "source": 4, + "value": "6" + }, + { + "begin": 942, + "end": 1175, + "name": "CALLDATASIZE", + "source": 4 + }, + { + "begin": 942, + "end": 1175, + "name": "PUSH", + "source": 4, + "value": "4" + }, + { + "begin": 942, + "end": 1175, + "name": "PUSH [tag]", + "source": 4, + "value": "7" + }, + { + "begin": 942, + "end": 1175, + "jumpType": "[in]", + "name": "JUMP", + "source": 4 + }, + { + "begin": 942, + "end": 1175, + "name": "tag", + "source": 4, + "value": "6" + }, + { + "begin": 942, + "end": 1175, + "name": "JUMPDEST", + "source": 4 + }, + { + "begin": 942, + "end": 1175, + "name": "PUSH [tag]", + "source": 4, + "value": "8" + }, + { + "begin": 942, + "end": 1175, + "jumpType": "[in]", + "name": "JUMP", + "source": 4 + }, + { + "begin": 942, + "end": 1175, + "name": "tag", + "source": 4, + "value": "5" + }, + { + "begin": 942, + "end": 1175, + "name": "JUMPDEST", + "source": 4 + }, + { + "begin": 942, + "end": 1175, + "name": "PUSH", + "source": 4, + "value": "40" + }, + { + "begin": 942, + "end": 1175, + "name": "MLOAD", + "source": 4 + }, + { + "begin": 516, + "end": 530, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 516, + "end": 530, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 509, + "end": 531, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 491, + "end": 532, + "name": "DUP2", + "source": 22 + }, + { + "begin": 491, + "end": 532, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 479, + "end": 481, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 464, + "end": 482, + "name": "ADD", + "source": 22 + }, + { + "begin": 942, + "end": 1175, + "name": "tag", + "source": 4, + "value": "9" + }, + { + "begin": 942, + "end": 1175, + "name": "JUMPDEST", + "source": 4 + }, + { + "begin": 942, + "end": 1175, + "name": "PUSH", + "source": 4, + "value": "40" + }, + { + "begin": 942, + "end": 1175, + "name": "MLOAD", + "source": 4 + }, + { + "begin": 942, + "end": 1175, + "name": "DUP1", + "source": 4 + }, + { + "begin": 942, + "end": 1175, + "name": "SWAP2", + "source": 4 + }, + { + "begin": 942, + "end": 1175, + "name": "SUB", + "source": 4 + }, + { + "begin": 942, + "end": 1175, + "name": "SWAP1", + "source": 4 + }, + { + "begin": 942, + "end": 1175, + "name": "RETURN", + "source": 4 + }, + { + "begin": 456, + "end": 732, + "name": "tag", + "source": 4, + "value": "3" + }, + { + "begin": 456, + "end": 732, + "name": "JUMPDEST", + "source": 4 + }, + { + "begin": 456, + "end": 732, + "name": "PUSH [tag]", + "source": 4, + "value": "11" + }, + { + "begin": 456, + "end": 732, + "name": "PUSH [tag]", + "source": 4, + "value": "12" + }, + { + "begin": 456, + "end": 732, + "name": "CALLDATASIZE", + "source": 4 + }, + { + "begin": 456, + "end": 732, + "name": "PUSH", + "source": 4, + "value": "4" + }, + { + "begin": 456, + "end": 732, + "name": "PUSH [tag]", + "source": 4, + "value": "13" + }, + { + "begin": 456, + "end": 732, + "jumpType": "[in]", + "name": "JUMP", + "source": 4 + }, + { + "begin": 456, + "end": 732, + "name": "tag", + "source": 4, + "value": "12" + }, + { + "begin": 456, + "end": 732, + "name": "JUMPDEST", + "source": 4 + }, + { + "begin": 456, + "end": 732, + "name": "PUSH [tag]", + "source": 4, + "value": "14" + }, + { + "begin": 456, + "end": 732, + "jumpType": "[in]", + "name": "JUMP", + "source": 4 + }, + { + "begin": 456, + "end": 732, + "name": "tag", + "source": 4, + "value": "11" + }, + { + "begin": 456, + "end": 732, + "name": "JUMPDEST", + "source": 4 + }, + { + "begin": 456, + "end": 732, + "name": "PUSH", + "source": 4, + "value": "40" + }, + { + "begin": 456, + "end": 732, + "name": "MLOAD", + "source": 4 + }, + { + "begin": 1893, + "end": 1935, + "name": "PUSH", + "source": 22, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { + "begin": 1881, + "end": 1936, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 1881, + "end": 1936, + "name": "SWAP2", + "source": 22 + }, + { + "begin": 1881, + "end": 1936, + "name": "AND", + "source": 22 + }, + { + "begin": 1863, + "end": 1937, + "name": "DUP2", + "source": 22 + }, + { + "begin": 1863, + "end": 1937, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 1851, + "end": 1853, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 1836, + "end": 1854, + "name": "ADD", + "source": 22 + }, + { + "begin": 456, + "end": 732, + "name": "PUSH [tag]", + "source": 4, + "value": "9" + }, + { + "begin": 1717, + "end": 1943, + "name": "JUMP", + "source": 22 + }, + { + "begin": 942, + "end": 1175, + "name": "tag", + "source": 4, + "value": "8" + }, + { + "begin": 942, + "end": 1175, + "name": "JUMPDEST", + "source": 4 + }, + { + "begin": 1028, + "end": 1032, + "name": "PUSH", + "source": 4, + "value": "0" + }, + { + "begin": 1044, + "end": 1092, + "name": "PUSH", + "source": 4, + "value": "6FFBD45100000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 1044, + "end": 1092, + "name": "PUSH", + "source": 4, + "value": "FFFFFFFF00000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 1044, + "end": 1092, + "name": "DUP4", + "source": 4 + }, + { + "begin": 1044, + "end": 1092, + "name": "AND", + "source": 4 + }, + { + "begin": 1044, + "end": 1092, + "name": "ADD", + "source": 4 + }, + { + "begin": 1040, + "end": 1120, + "name": "PUSH [tag]", + "source": 4, + "value": "18" + }, + { + "begin": 1040, + "end": 1120, + "name": "JUMPI", + "source": 4 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 1109, + "end": 1113, + "name": "PUSH", + "source": 4, + "value": "1" + }, + { + "begin": 1109, + "end": 1113, + "name": "SWAP2", + "source": 4 + }, + { + "begin": 942, + "end": 1175, + "name": "SWAP1", + "source": 4 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 942, + "end": 1175, + "jumpType": "[out]", + "name": "JUMP", + "source": 4 + }, + { + "begin": 1040, + "end": 1120, + "name": "tag", + "source": 4, + "value": "18" + }, + { + "begin": 1040, + "end": 1120, + "name": "JUMPDEST", + "source": 4 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 709, + "end": 756, + "name": "PUSH", + "source": 5, + "value": "FFFFFFFF00000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 709, + "end": 756, + "name": "AND", + "source": 5 + }, + { + "begin": 725, + "end": 756, + "name": "PUSH", + "source": 5, + "value": "1FFC9A700000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 709, + "end": 756, + "name": "EQ", + "source": 5 + }, + { + "begin": 709, + "end": 756, + "name": "SWAP1", + "source": 5 + }, + { + "begin": 942, + "end": 1175, + "jumpType": "[out]", + "name": "JUMP", + "source": 4 + }, + { + "begin": 456, + "end": 732, + "name": "tag", + "source": 4, + "value": "14" + }, + { + "begin": 456, + "end": 732, + "name": "JUMPDEST", + "source": 4 + }, + { + "begin": 550, + "end": 562, + "name": "PUSH", + "source": 4, + "value": "0" + }, + { + "begin": 178, + "end": 188, + "name": "CALLER", + "source": 8 + }, + { + "begin": 200, + "end": 204, + "name": "ADDRESS", + "source": 8 + }, + { + "begin": 178, + "end": 205, + "name": "EQ", + "source": 8 + }, + { + "begin": 174, + "end": 268, + "name": "PUSH [tag]", + "source": 8, + "value": "22" + }, + { + "begin": 174, + "end": 268, + "name": "JUMPI", + "source": 8 + }, + { + "begin": 222, + "end": 261, + "name": "PUSH", + "source": 8, + "value": "40" + }, + { + "begin": 222, + "end": 261, + "name": "MLOAD", + "source": 8 + }, + { + "begin": 222, + "end": 261, + "name": "PUSH", + "source": 8, + "value": "E125889400000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 222, + "end": 261, + "name": "DUP2", + "source": 8 + }, + { + "begin": 222, + "end": 261, + "name": "MSTORE", + "source": 8 + }, + { + "begin": 235, + "end": 245, + "name": "CALLER", + "source": 8 + }, + { + "begin": 222, + "end": 261, + "name": "PUSH", + "source": 8, + "value": "4" + }, + { + "begin": 222, + "end": 261, + "name": "DUP3", + "source": 8 + }, + { + "begin": 222, + "end": 261, + "name": "ADD", + "source": 8 + }, + { + "begin": 2183, + "end": 2217, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 255, + "end": 259, + "name": "ADDRESS", + "source": 8 + }, + { + "begin": 2233, + "end": 2251, + "name": "PUSH", + "source": 22, + "value": "24" + }, + { + "begin": 2233, + "end": 2251, + "name": "DUP3", + "source": 22 + }, + { + "begin": 2233, + "end": 2251, + "name": "ADD", + "source": 22 + }, + { + "begin": 2226, + "end": 2269, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 2095, + "end": 2113, + "name": "PUSH", + "source": 22, + "value": "44" + }, + { + "begin": 2095, + "end": 2113, + "name": "ADD", + "source": 22 + }, + { + "begin": 222, + "end": 261, + "name": "tag", + "source": 8, + "value": "23" + }, + { + "begin": 222, + "end": 261, + "name": "JUMPDEST", + "source": 8 + }, + { + "begin": 222, + "end": 261, + "name": "PUSH", + "source": 8, + "value": "40" + }, + { + "begin": 222, + "end": 261, + "name": "MLOAD", + "source": 8 + }, + { + "begin": 222, + "end": 261, + "name": "DUP1", + "source": 8 + }, + { + "begin": 222, + "end": 261, + "name": "SWAP2", + "source": 8 + }, + { + "begin": 222, + "end": 261, + "name": "SUB", + "source": 8 + }, + { + "begin": 222, + "end": 261, + "name": "SWAP1", + "source": 8 + }, + { + "begin": 222, + "end": 261, + "name": "REVERT", + "source": 8 + }, + { + "begin": 174, + "end": 268, + "name": "tag", + "source": 8, + "value": "22" + }, + { + "begin": 174, + "end": 268, + "name": "JUMPDEST", + "source": 8 + }, + { + "begin": 631, + "end": 636, + "modifierDepth": 1, + "name": "DUP2", + "source": 4 + }, + { + "begin": 625, + "end": 637, + "modifierDepth": 1, + "name": "MLOAD", + "source": 4 + }, + { + "begin": 620, + "end": 622, + "modifierDepth": 1, + "name": "PUSH", + "source": 4, + "value": "20" + }, + { + "begin": 613, + "end": 618, + "modifierDepth": 1, + "name": "DUP4", + "source": 4 + }, + { + "begin": 609, + "end": 623, + "modifierDepth": 1, + "name": "ADD", + "source": 4 + }, + { + "begin": 596, + "end": 607, + "modifierDepth": 1, + "name": "CALLVALUE", + "source": 4 + }, + { + "begin": 589, + "end": 638, + "modifierDepth": 1, + "name": "CREATE", + "source": 4 + }, + { + "begin": 581, + "end": 638, + "name": "SWAP1", + "source": 4 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 649, + "end": 667, + "modifierDepth": 1, + "name": "PUSH", + "source": 4, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { + "begin": 649, + "end": 667, + "name": "DUP2", + "source": 4 + }, + { + "begin": 649, + "end": 667, + "modifierDepth": 1, + "name": "AND", + "source": 4 + }, + { + "begin": 645, + "end": 695, + "modifierDepth": 1, + "name": "PUSH [tag]", + "source": 4, + "value": "26" + }, + { + "begin": 645, + "end": 695, + "modifierDepth": 1, + "name": "JUMPI", + "source": 4 + }, + { + "begin": 689, + "end": 694, + "modifierDepth": 1, + "name": "DUP2", + "source": 4 + }, + { + "begin": 676, + "end": 695, + "modifierDepth": 1, + "name": "PUSH", + "source": 4, + "value": "40" + }, + { + "begin": 676, + "end": 695, + "modifierDepth": 1, + "name": "MLOAD", + "source": 4 + }, + { + "begin": 676, + "end": 695, + "modifierDepth": 1, + "name": "PUSH", + "source": 4, + "value": "D25719100000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 676, + "end": 695, + "modifierDepth": 1, + "name": "DUP2", + "source": 4 + }, + { + "begin": 676, + "end": 695, + "modifierDepth": 1, + "name": "MSTORE", + "source": 4 + }, + { + "begin": 676, + "end": 695, + "modifierDepth": 1, + "name": "PUSH", + "source": 4, + "value": "4" + }, + { + "begin": 676, + "end": 695, + "modifierDepth": 1, + "name": "ADD", + "source": 4 + }, + { + "begin": 676, + "end": 695, + "modifierDepth": 1, + "name": "PUSH [tag]", + "source": 4, + "value": "23" + }, + { + "begin": 676, + "end": 695, + "modifierDepth": 1, + "name": "SWAP2", + "source": 4 + }, + { + "begin": 676, + "end": 695, + "modifierDepth": 1, + "name": "SWAP1", + "source": 4 + }, + { + "begin": 676, + "end": 695, + "modifierDepth": 1, + "name": "PUSH [tag]", + "source": 4, + "value": "28" + }, + { + "begin": 676, + "end": 695, + "jumpType": "[in]", + "modifierDepth": 1, + "name": "JUMP", + "source": 4 + }, + { + "begin": 645, + "end": 695, + "modifierDepth": 1, + "name": "tag", + "source": 4, + "value": "26" + }, + { + "begin": 645, + "end": 695, + "modifierDepth": 1, + "name": "JUMPDEST", + "source": 4 + }, + { + "begin": 706, + "end": 727, + "modifierDepth": 1, + "name": "PUSH", + "source": 4, + "value": "40" + }, + { + "begin": 706, + "end": 727, + "name": "MLOAD", + "source": 4 + }, + { + "begin": 1893, + "end": 1935, + "name": "PUSH", + "source": 22, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + }, + { + "begin": 1881, + "end": 1936, + "name": "DUP3", + "source": 22 + }, + { + "begin": 1881, + "end": 1936, + "name": "AND", + "source": 22 + }, + { + "begin": 1863, + "end": 1937, + "name": "DUP2", + "source": 22 + }, + { + "begin": 1863, + "end": 1937, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 706, + "end": 727, + "modifierDepth": 1, + "name": "PUSH", + "source": 4, + "value": "A506AD4E7F05ECEBA62A023C3219E5BD98A615F4FA87E2AFB08A2DA5CF62BF0C" + }, + { + "begin": 706, + "end": 727, + "name": "SWAP1", + "source": 4 + }, + { + "begin": 1851, + "end": 1853, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 1836, + "end": 1854, + "name": "ADD", + "source": 22 + }, + { + "begin": 706, + "end": 727, + "modifierDepth": 1, + "name": "PUSH", + "source": 4, + "value": "40" + }, + { + "begin": 706, + "end": 727, + "modifierDepth": 1, + "name": "MLOAD", + "source": 4 + }, + { + "begin": 706, + "end": 727, + "modifierDepth": 1, + "name": "DUP1", + "source": 4 + }, + { + "begin": 706, + "end": 727, + "modifierDepth": 1, + "name": "SWAP2", + "source": 4 + }, + { + "begin": 706, + "end": 727, + "modifierDepth": 1, + "name": "SUB", + "source": 4 + }, + { + "begin": 706, + "end": 727, + "modifierDepth": 1, + "name": "SWAP1", + "source": 4 + }, + { + "begin": 706, + "end": 727, + "modifierDepth": 1, + "name": "LOG1", + "source": 4 + }, + { + "begin": 456, + "end": 732, + "name": "SWAP2", + "source": 4 + }, + { + "begin": 456, + "end": 732, + "name": "SWAP1", + "source": 4 + }, + { + "begin": 456, + "end": 732, + "name": "POP", + "source": 4 + }, + { + "begin": 456, + "end": 732, + "jumpType": "[out]", + "name": "JUMP", + "source": 4 + }, + { + "begin": 14, + "end": 346, + "name": "tag", + "source": 22, + "value": "7" + }, + { + "begin": 14, + "end": 346, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 72, + "end": 78, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 125, + "end": 127, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 113, + "end": 122, + "name": "DUP3", + "source": 22 + }, + { + "begin": 104, + "end": 111, + "name": "DUP5", + "source": 22 + }, + { + "begin": 100, + "end": 123, + "name": "SUB", + "source": 22 + }, + { + "begin": 96, + "end": 128, + "name": "SLT", + "source": 22 + }, + { + "begin": 93, + "end": 145, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 93, + "end": 145, + "name": "PUSH [tag]", + "source": 22, + "value": "34" + }, + { + "begin": 93, + "end": 145, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 141, + "end": 142, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 138, + "end": 139, + "name": "DUP1", + "source": 22 + }, + { + "begin": 131, + "end": 143, + "name": "REVERT", + "source": 22 + }, + { + "begin": 93, + "end": 145, + "name": "tag", + "source": 22, + "value": "34" + }, + { + "begin": 93, + "end": 145, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 180, + "end": 189, + "name": "DUP2", + "source": 22 + }, + { + "begin": 167, + "end": 190, + "name": "CALLDATALOAD", + "source": 22 + }, + { + "begin": 230, + "end": 296, + "name": "PUSH", + "source": 22, + "value": "FFFFFFFF00000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 223, + "end": 228, + "name": "DUP2", + "source": 22 + }, + { + "begin": 219, + "end": 297, + "name": "AND", + "source": 22 + }, + { + "begin": 212, + "end": 217, + "name": "DUP2", + "source": 22 + }, + { + "begin": 209, + "end": 298, + "name": "EQ", + "source": 22 + }, + { + "begin": 199, + "end": 316, + "name": "PUSH [tag]", + "source": 22, + "value": "35" + }, + { + "begin": 199, + "end": 316, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 312, + "end": 313, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 309, + "end": 310, + "name": "DUP1", + "source": 22 + }, + { + "begin": 302, + "end": 314, + "name": "REVERT", + "source": 22 + }, + { + "begin": 199, + "end": 316, + "name": "tag", + "source": 22, + "value": "35" + }, + { + "begin": 199, + "end": 316, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 335, + "end": 340, + "name": "SWAP4", + "source": 22 + }, + { + "begin": 14, + "end": 346, + "name": "SWAP3", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 14, + "end": 346, + "jumpType": "[out]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 543, + "end": 727, + "name": "tag", + "source": 22, + "value": "31" + }, + { + "begin": 543, + "end": 727, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 595, + "end": 672, + "name": "PUSH", + "source": 22, + "value": "4E487B7100000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 592, + "end": 593, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 585, + "end": 673, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 692, + "end": 696, + "name": "PUSH", + "source": 22, + "value": "41" + }, + { + "begin": 689, + "end": 690, + "name": "PUSH", + "source": 22, + "value": "4" + }, + { + "begin": 682, + "end": 697, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 716, + "end": 720, + "name": "PUSH", + "source": 22, + "value": "24" + }, + { + "begin": 713, + "end": 714, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 706, + "end": 721, + "name": "REVERT", + "source": 22 + }, + { + "begin": 732, + "end": 1712, + "name": "tag", + "source": 22, + "value": "13" + }, + { + "begin": 732, + "end": 1712, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 800, + "end": 806, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 853, + "end": 855, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 841, + "end": 850, + "name": "DUP3", + "source": 22 + }, + { + "begin": 832, + "end": 839, + "name": "DUP5", + "source": 22 + }, + { + "begin": 828, + "end": 851, + "name": "SUB", + "source": 22 + }, + { + "begin": 824, + "end": 856, + "name": "SLT", + "source": 22 + }, + { + "begin": 821, + "end": 873, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 821, + "end": 873, + "name": "PUSH [tag]", + "source": 22, + "value": "39" + }, + { + "begin": 821, + "end": 873, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 869, + "end": 870, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 866, + "end": 867, + "name": "DUP1", + "source": 22 + }, + { + "begin": 859, + "end": 871, + "name": "REVERT", + "source": 22 + }, + { + "begin": 821, + "end": 873, + "name": "tag", + "source": 22, + "value": "39" + }, + { + "begin": 821, + "end": 873, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 909, + "end": 918, + "name": "DUP2", + "source": 22 + }, + { + "begin": 896, + "end": 919, + "name": "CALLDATALOAD", + "source": 22 + }, + { + "begin": 938, + "end": 956, + "name": "PUSH", + "source": 22, + "value": "FFFFFFFFFFFFFFFF" + }, + { + "begin": 979, + "end": 981, + "name": "DUP1", + "source": 22 + }, + { + "begin": 971, + "end": 977, + "name": "DUP3", + "source": 22 + }, + { + "begin": 968, + "end": 982, + "name": "GT", + "source": 22 + }, + { + "begin": 965, + "end": 999, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 965, + "end": 999, + "name": "PUSH [tag]", + "source": 22, + "value": "40" + }, + { + "begin": 965, + "end": 999, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 995, + "end": 996, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 992, + "end": 993, + "name": "DUP1", + "source": 22 + }, + { + "begin": 985, + "end": 997, + "name": "REVERT", + "source": 22 + }, + { + "begin": 965, + "end": 999, + "name": "tag", + "source": 22, + "value": "40" + }, + { + "begin": 965, + "end": 999, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 1033, + "end": 1039, + "name": "DUP2", + "source": 22 + }, + { + "begin": 1022, + "end": 1031, + "name": "DUP5", + "source": 22 + }, + { + "begin": 1018, + "end": 1040, + "name": "ADD", + "source": 22 + }, + { + "begin": 1008, + "end": 1040, + "name": "SWAP2", + "source": 22 + }, + { + "begin": 1008, + "end": 1040, + "name": "POP", + "source": 22 + }, + { + "begin": 1078, + "end": 1085, + "name": "DUP5", + "source": 22 + }, + { + "begin": 1071, + "end": 1075, + "name": "PUSH", + "source": 22, + "value": "1F" + }, + { + "begin": 1067, + "end": 1069, + "name": "DUP4", + "source": 22 + }, + { + "begin": 1063, + "end": 1076, + "name": "ADD", + "source": 22 + }, + { + "begin": 1059, + "end": 1086, + "name": "SLT", + "source": 22 + }, + { + "begin": 1049, + "end": 1104, + "name": "PUSH [tag]", + "source": 22, + "value": "41" + }, + { + "begin": 1049, + "end": 1104, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 1100, + "end": 1101, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 1097, + "end": 1098, + "name": "DUP1", + "source": 22 + }, + { + "begin": 1090, + "end": 1102, + "name": "REVERT", + "source": 22 + }, + { + "begin": 1049, + "end": 1104, + "name": "tag", + "source": 22, + "value": "41" + }, + { + "begin": 1049, + "end": 1104, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 1136, + "end": 1138, + "name": "DUP2", + "source": 22 + }, + { + "begin": 1123, + "end": 1139, + "name": "CALLDATALOAD", + "source": 22 + }, + { + "begin": 1158, + "end": 1160, + "name": "DUP2", + "source": 22 + }, + { + "begin": 1154, + "end": 1156, + "name": "DUP2", + "source": 22 + }, + { + "begin": 1151, + "end": 1161, + "name": "GT", + "source": 22 + }, + { + "begin": 1148, + "end": 1184, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 1148, + "end": 1184, + "name": "PUSH [tag]", + "source": 22, + "value": "43" + }, + { + "begin": 1148, + "end": 1184, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 1164, + "end": 1182, + "name": "PUSH [tag]", + "source": 22, + "value": "43" + }, + { + "begin": 1164, + "end": 1182, + "name": "PUSH [tag]", + "source": 22, + "value": "31" + }, + { + "begin": 1164, + "end": 1182, + "jumpType": "[in]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 1164, + "end": 1182, + "name": "tag", + "source": 22, + "value": "43" + }, + { + "begin": 1164, + "end": 1182, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 1298, + "end": 1300, + "name": "PUSH", + "source": 22, + "value": "40" + }, + { + "begin": 1292, + "end": 1301, + "name": "MLOAD", + "source": 22 + }, + { + "begin": 1360, + "end": 1364, + "name": "PUSH", + "source": 22, + "value": "1F" + }, + { + "begin": 1352, + "end": 1365, + "name": "DUP3", + "source": 22 + }, + { + "begin": 1352, + "end": 1365, + "name": "ADD", + "source": 22 + }, + { + "begin": 1203, + "end": 1269, + "name": "PUSH", + "source": 22, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0" + }, + { + "begin": 1348, + "end": 1370, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 1348, + "end": 1370, + "name": "DUP2", + "source": 22 + }, + { + "begin": 1348, + "end": 1370, + "name": "AND", + "source": 22 + }, + { + "begin": 1372, + "end": 1374, + "name": "PUSH", + "source": 22, + "value": "3F" + }, + { + "begin": 1344, + "end": 1375, + "name": "ADD", + "source": 22 + }, + { + "begin": 1340, + "end": 1380, + "name": "AND", + "source": 22 + }, + { + "begin": 1328, + "end": 1381, + "name": "DUP2", + "source": 22 + }, + { + "begin": 1328, + "end": 1381, + "name": "ADD", + "source": 22 + }, + { + "begin": 1328, + "end": 1381, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 1396, + "end": 1414, + "name": "DUP4", + "source": 22 + }, + { + "begin": 1396, + "end": 1414, + "name": "DUP3", + "source": 22 + }, + { + "begin": 1396, + "end": 1414, + "name": "GT", + "source": 22 + }, + { + "begin": 1416, + "end": 1438, + "name": "DUP2", + "source": 22 + }, + { + "begin": 1416, + "end": 1438, + "name": "DUP4", + "source": 22 + }, + { + "begin": 1416, + "end": 1438, + "name": "LT", + "source": 22 + }, + { + "begin": 1393, + "end": 1439, + "name": "OR", + "source": 22 + }, + { + "begin": 1390, + "end": 1462, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 1390, + "end": 1462, + "name": "PUSH [tag]", + "source": 22, + "value": "45" + }, + { + "begin": 1390, + "end": 1462, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 1442, + "end": 1460, + "name": "PUSH [tag]", + "source": 22, + "value": "45" + }, + { + "begin": 1442, + "end": 1460, + "name": "PUSH [tag]", + "source": 22, + "value": "31" + }, + { + "begin": 1442, + "end": 1460, + "jumpType": "[in]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 1442, + "end": 1460, + "name": "tag", + "source": 22, + "value": "45" + }, + { + "begin": 1442, + "end": 1460, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 1482, + "end": 1492, + "name": "DUP2", + "source": 22 + }, + { + "begin": 1478, + "end": 1480, + "name": "PUSH", + "source": 22, + "value": "40" + }, + { + "begin": 1471, + "end": 1493, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 1517, + "end": 1519, + "name": "DUP3", + "source": 22 + }, + { + "begin": 1509, + "end": 1515, + "name": "DUP2", + "source": 22 + }, + { + "begin": 1502, + "end": 1520, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 1557, + "end": 1564, + "name": "DUP8", + "source": 22 + }, + { + "begin": 1552, + "end": 1554, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 1547, + "end": 1549, + "name": "DUP5", + "source": 22 + }, + { + "begin": 1543, + "end": 1545, + "name": "DUP8", + "source": 22 + }, + { + "begin": 1539, + "end": 1550, + "name": "ADD", + "source": 22 + }, + { + "begin": 1535, + "end": 1555, + "name": "ADD", + "source": 22 + }, + { + "begin": 1532, + "end": 1565, + "name": "GT", + "source": 22 + }, + { + "begin": 1529, + "end": 1582, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 1529, + "end": 1582, + "name": "PUSH [tag]", + "source": 22, + "value": "46" + }, + { + "begin": 1529, + "end": 1582, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 1578, + "end": 1579, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 1575, + "end": 1576, + "name": "DUP1", + "source": 22 + }, + { + "begin": 1568, + "end": 1580, + "name": "REVERT", + "source": 22 + }, + { + "begin": 1529, + "end": 1582, + "name": "tag", + "source": 22, + "value": "46" + }, + { + "begin": 1529, + "end": 1582, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 1634, + "end": 1636, + "name": "DUP3", + "source": 22 + }, + { + "begin": 1629, + "end": 1631, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 1625, + "end": 1627, + "name": "DUP7", + "source": 22 + }, + { + "begin": 1621, + "end": 1632, + "name": "ADD", + "source": 22 + }, + { + "begin": 1616, + "end": 1618, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 1608, + "end": 1614, + "name": "DUP4", + "source": 22 + }, + { + "begin": 1604, + "end": 1619, + "name": "ADD", + "source": 22 + }, + { + "begin": 1591, + "end": 1637, + "name": "CALLDATACOPY", + "source": 22 + }, + { + "begin": 1679, + "end": 1680, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 1657, + "end": 1672, + "name": "SWAP3", + "source": 22 + }, + { + "begin": 1657, + "end": 1672, + "name": "DUP2", + "source": 22 + }, + { + "begin": 1657, + "end": 1672, + "name": "ADD", + "source": 22 + }, + { + "begin": 1674, + "end": 1676, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 1653, + "end": 1677, + "name": "ADD", + "source": 22 + }, + { + "begin": 1646, + "end": 1681, + "name": "SWAP3", + "source": 22 + }, + { + "begin": 1646, + "end": 1681, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 1646, + "end": 1681, + "name": "SWAP3", + "source": 22 + }, + { + "begin": 1646, + "end": 1681, + "name": "MSTORE", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 1661, + "end": 1667, + "name": "SWAP6", + "source": 22 + }, + { + "begin": 732, + "end": 1712, + "name": "SWAP5", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 732, + "end": 1712, + "jumpType": "[out]", + "name": "JUMP", + "source": 22 + }, + { + "begin": 2280, + "end": 2885, + "name": "tag", + "source": 22, + "value": "28" + }, + { + "begin": 2280, + "end": 2885, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 2390, + "end": 2394, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 2419, + "end": 2421, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 2448, + "end": 2450, + "name": "DUP1", + "source": 22 + }, + { + "begin": 2437, + "end": 2446, + "name": "DUP4", + "source": 22 + }, + { + "begin": 2430, + "end": 2451, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 2480, + "end": 2486, + "name": "DUP4", + "source": 22 + }, + { + "begin": 2474, + "end": 2487, + "name": "MLOAD", + "source": 22 + }, + { + "begin": 2523, + "end": 2529, + "name": "DUP1", + "source": 22 + }, + { + "begin": 2518, + "end": 2520, + "name": "DUP3", + "source": 22 + }, + { + "begin": 2507, + "end": 2516, + "name": "DUP6", + "source": 22 + }, + { + "begin": 2503, + "end": 2521, + "name": "ADD", + "source": 22 + }, + { + "begin": 2496, + "end": 2530, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 2548, + "end": 2549, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 2558, + "end": 2698, + "name": "tag", + "source": 22, + "value": "50" + }, + { + "begin": 2558, + "end": 2698, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 2572, + "end": 2578, + "name": "DUP2", + "source": 22 + }, + { + "begin": 2569, + "end": 2570, + "name": "DUP2", + "source": 22 + }, + { + "begin": 2566, + "end": 2579, + "name": "LT", + "source": 22 + }, + { + "begin": 2558, + "end": 2698, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 2558, + "end": 2698, + "name": "PUSH [tag]", + "source": 22, + "value": "52" + }, + { + "begin": 2558, + "end": 2698, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 2667, + "end": 2681, + "name": "DUP6", + "source": 22 + }, + { + "begin": 2667, + "end": 2681, + "name": "DUP2", + "source": 22 + }, + { + "begin": 2667, + "end": 2681, + "name": "ADD", + "source": 22 + }, + { + "begin": 2663, + "end": 2686, + "name": "DUP4", + "source": 22 + }, + { + "begin": 2663, + "end": 2686, + "name": "ADD", + "source": 22 + }, + { + "begin": 2657, + "end": 2687, + "name": "MLOAD", + "source": 22 + }, + { + "begin": 2633, + "end": 2650, + "name": "DUP6", + "source": 22 + }, + { + "begin": 2633, + "end": 2650, + "name": "DUP3", + "source": 22 + }, + { + "begin": 2633, + "end": 2650, + "name": "ADD", + "source": 22 + }, + { + "begin": 2652, + "end": 2654, + "name": "PUSH", + "source": 22, + "value": "40" + }, + { + "begin": 2629, + "end": 2655, + "name": "ADD", + "source": 22 + }, + { + "begin": 2622, + "end": 2688, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 2587, + "end": 2597, + "name": "DUP3", + "source": 22 + }, + { + "begin": 2587, + "end": 2597, + "name": "ADD", + "source": 22 + }, + { + "begin": 2558, + "end": 2698, + "name": "PUSH [tag]", + "source": 22, + "value": "50" + }, + { + "begin": 2558, + "end": 2698, + "name": "JUMP", + "source": 22 + }, + { + "begin": 2558, + "end": 2698, + "name": "tag", + "source": 22, + "value": "52" + }, + { + "begin": 2558, + "end": 2698, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 2562, + "end": 2565, + "name": "POP", + "source": 22 + }, + { + "begin": 2747, + "end": 2748, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 2742, + "end": 2744, + "name": "PUSH", + "source": 22, + "value": "40" + }, + { + "begin": 2733, + "end": 2739, + "name": "DUP3", + "source": 22 + }, + { + "begin": 2722, + "end": 2731, + "name": "DUP7", + "source": 22 + }, + { + "begin": 2718, + "end": 2740, + "name": "ADD", + "source": 22 + }, + { + "begin": 2714, + "end": 2745, + "name": "ADD", + "source": 22 + }, + { + "begin": 2707, + "end": 2749, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 2876, + "end": 2878, + "name": "PUSH", + "source": 22, + "value": "40" + }, + { + "begin": 2806, + "end": 2872, + "name": "PUSH", + "source": 22, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0" + }, + { + "begin": 2801, + "end": 2803, + "name": "PUSH", + "source": 22, + "value": "1F" + }, + { + "begin": 2793, + "end": 2799, + "name": "DUP4", + "source": 22 + }, + { + "begin": 2789, + "end": 2804, + "name": "ADD", + "source": 22 + }, + { + "begin": 2785, + "end": 2873, + "name": "AND", + "source": 22 + }, + { + "begin": 2774, + "end": 2783, + "name": "DUP6", + "source": 22 + }, + { + "begin": 2770, + "end": 2874, + "name": "ADD", + "source": 22 + }, + { + "begin": 2766, + "end": 2879, + "name": "ADD", + "source": 22 + }, + { + "begin": 2758, + "end": 2879, + "name": "SWAP3", + "source": 22 + }, + { + "begin": 2758, + "end": 2879, + "name": "POP", + "source": 22 + }, + { + "begin": 2758, + "end": 2879, + "name": "POP", + "source": 22 + }, + { + "begin": 2758, + "end": 2879, + "name": "POP", + "source": 22 + }, + { + "begin": 2280, + "end": 2885, + "name": "SWAP3", + "source": 22 + }, + { + "begin": 2280, + "end": 2885, + "name": "SWAP2", + "source": 22 + }, + { + "begin": 2280, + "end": 2885, + "name": "POP", + "source": 22 + }, + { + "begin": 2280, + "end": 2885, + "name": "POP", + "source": 22 + }, + { + "begin": 2280, + "end": 2885, + "jumpType": "[out]", + "name": "JUMP", + "source": 22 + } + ] + } + }, + "sourceList": [ + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/interfaces/IERC1271Wallet.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleERC165.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleOnlyDelegatecall.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCalls.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCreator.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol", + "#utility.yul" + ] + }, + "methodIdentifiers": { + "createContract(bytes)": "90042baf", + "supportsInterface(bytes4)": "01ffc9a7" + } + }, + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_code\",\"type\":\"bytes\"}],\"name\":\"CreateFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_self\",\"type\":\"address\"}],\"name\":\"OnlySelfAuth\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_contract\",\"type\":\"address\"}],\"name\":\"CreatedContract\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_code\",\"type\":\"bytes\"}],\"name\":\"createContract\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_interfaceID\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"createContract(bytes)\":{\"params\":{\"_code\":\"Creation code of the contract\"},\"returns\":{\"addr\":\"The address of the created contract\"}},\"supportsInterface(bytes4)\":{\"params\":{\"_interfaceID\":\"The interface identifier, as specified in ERC-165\"},\"returns\":{\"_0\":\"`true` if the contract implements `_interfaceID`\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"createContract(bytes)\":{\"notice\":\"Creates a contract forwarding eth value\"},\"supportsInterface(bytes4)\":{\"notice\":\"Query if a contract implements an interface\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":\"ModuleCreator\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":500000},\"remappings\":[\":@0xsequence/contracts-library/=src/\",\":@0xsequence/erc-1155/=lib/0xsequence/erc-1155/src/\",\":@0xsequence/erc20-meta-token/=lib/0xsequence/erc20-meta-token/src/\",\":@openzeppelin/=lib/openzeppelin/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc721a-upgradeable/=lib/chiru-labs/erc721a-upgradeable/\",\":erc721a/=lib/chiru-labs/erc721a/\",\":forge-std/=lib/forge-std/src/\",\":murky/=lib/murky/src/\",\":solady/=lib/solady/src/\"]},\"sources\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol\":{\"keccak256\":\"0x16b1400988f6b7bd4d32bdcb36ee2fbd644fb2c8ca571becc0c32e03602bd303\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://8bd4681fb4cff10f4e98e45618fbc52ed0a4c7d4fcf614f34a587ad20cd16855\",\"dweb:/ipfs/QmbA2LYBH1x8WX8CaeiFYMU5rjyLGgNCF32r9fQbXuoqwJ\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleERC165.sol\":{\"keccak256\":\"0xd4ae13a3d20fd7ab52ad16af6a06e7244daea450b796251e911091cac104d05f\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://8de37ec20a6b649e9fe3fb42276e4660ff546bca8b467f72beb35396ab5e62d6\",\"dweb:/ipfs/QmXT2SxBZKitkbKLbGbbNLhUbw2ataRpQ2DHafvhG953RE\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":{\"keccak256\":\"0x91545de5c77cfac86c5686c4e1f338a18ee7adb689ac0234848d7a7fc8a560db\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://dc89d05d8099ba4c3c2cf85737796d439899b5a04e6b87b1ea43f687ae08848a\",\"dweb:/ipfs/QmatU8gRvFkK3Yn1MYAekzi48Waw3cDLtXJpduvju9HFUu\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCreator.sol\":{\"keccak256\":\"0xa206dd3d424b8cd1c4f1400aa344cbc974480fea02f0fb371b872558e5ff4e6d\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://ea14c75f43a0008c582dcbae3ba3c900e446e28039dfdbb059d326ec5cc6a2d2\",\"dweb:/ipfs/QmRfF6BmUWiFkCgzVFbLcHsUCNz5q2XkkcwXPX57ViTK4D\"]}},\"version\":1}", + "storageLayout": { + "storage": [], + "types": null + }, + "userdoc": { + "kind": "user", + "methods": { + "createContract(bytes)": { + "notice": "Creates a contract forwarding eth value" + }, + "supportsInterface(bytes4)": { + "notice": "Query if a contract implements an interface" + } + }, + "version": 1 + } + } + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleERC165.sol": { + "ModuleERC165": { + "abi": [ + { + "inputs": [ + { + "internalType": "bytes4", + "name": "_interfaceID", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "devdoc": { + "kind": "dev", + "methods": { + "supportsInterface(bytes4)": { + "details": "Adding new hooks will not lead to them being reported by this function without upgrading the wallet. In addition, developers must ensure that all inherited contracts by the main module don't conflict and are accounted to be supported by the supportsInterface method.", + "params": { + "_interfaceID": "The interface identifier, as specified in ERC-165" + }, + "returns": { + "_0": "`true` if the contract implements `_interfaceID`" + } + } + }, + "version": 1 + }, + "evm": { + "assembly": "", + "bytecode": { + "functionDebugData": {}, + "generatedSources": [], + "linkReferences": {}, + "object": "", + "opcodes": "", + "sourceMap": "" + }, + "deployedBytecode": { + "functionDebugData": {}, + "generatedSources": [], + "immutableReferences": {}, + "linkReferences": {}, + "object": "", + "opcodes": "", + "sourceMap": "" + }, + "gasEstimates": null, + "legacyAssembly": null, + "methodIdentifiers": { + "supportsInterface(bytes4)": "01ffc9a7" + } + }, + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"_interfaceID\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"supportsInterface(bytes4)\":{\"details\":\"Adding new hooks will not lead to them being reported by this function without upgrading the wallet. In addition, developers must ensure that all inherited contracts by the main module don't conflict and are accounted to be supported by the supportsInterface method.\",\"params\":{\"_interfaceID\":\"The interface identifier, as specified in ERC-165\"},\"returns\":{\"_0\":\"`true` if the contract implements `_interfaceID`\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"supportsInterface(bytes4)\":{\"notice\":\"Query if a contract implements an interface\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleERC165.sol\":\"ModuleERC165\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":500000},\"remappings\":[\":@0xsequence/contracts-library/=src/\",\":@0xsequence/erc-1155/=lib/0xsequence/erc-1155/src/\",\":@0xsequence/erc20-meta-token/=lib/0xsequence/erc20-meta-token/src/\",\":@openzeppelin/=lib/openzeppelin/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc721a-upgradeable/=lib/chiru-labs/erc721a-upgradeable/\",\":erc721a/=lib/chiru-labs/erc721a/\",\":forge-std/=lib/forge-std/src/\",\":murky/=lib/murky/src/\",\":solady/=lib/solady/src/\"]},\"sources\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleERC165.sol\":{\"keccak256\":\"0xd4ae13a3d20fd7ab52ad16af6a06e7244daea450b796251e911091cac104d05f\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://8de37ec20a6b649e9fe3fb42276e4660ff546bca8b467f72beb35396ab5e62d6\",\"dweb:/ipfs/QmXT2SxBZKitkbKLbGbbNLhUbw2ataRpQ2DHafvhG953RE\"]}},\"version\":1}", + "storageLayout": { + "storage": [], + "types": null + }, + "userdoc": { + "kind": "user", + "methods": { + "supportsInterface(bytes4)": { + "notice": "Query if a contract implements an interface" + } + }, + "version": 1 + } + } + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol": { + "ModuleNonce": { + "abi": [ + { + "inputs": [ + { + "internalType": "uint256", + "name": "_space", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_provided", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_current", + "type": "uint256" + } + ], + "name": "BadNonce", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_space", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_newNonce", + "type": "uint256" + } + ], + "name": "NonceChange", + "type": "event" + }, + { + "inputs": [], + "name": "nonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_space", + "type": "uint256" + } + ], + "name": "readNonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "devdoc": { + "kind": "dev", + "methods": { + "nonce()": { + "details": "The default nonce space is 0x00", + "returns": { + "_0": "The next nonce" + } + }, + "readNonce(uint256)": { + "params": { + "_space": "Nonce space, each space keeps an independent nonce count" + }, + "returns": { + "_0": "The next nonce" + } + } + }, + "version": 1 + }, + "evm": { + "assembly": " /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":145:2076 contract ModuleNonce {... */\n mstore(0x40, 0x80)\n callvalue\n dup1\n iszero\n tag_1\n jumpi\n 0x00\n dup1\n revert\ntag_1:\n pop\n dataSize(sub_0)\n dup1\n dataOffset(sub_0)\n 0x00\n codecopy\n 0x00\n return\nstop\n\nsub_0: assembly {\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":145:2076 contract ModuleNonce {... */\n mstore(0x40, 0x80)\n callvalue\n dup1\n iszero\n tag_1\n jumpi\n 0x00\n dup1\n revert\n tag_1:\n pop\n jumpi(tag_2, lt(calldatasize, 0x04))\n shr(0xe0, calldataload(0x00))\n dup1\n 0x8c3f5563\n eq\n tag_3\n jumpi\n dup1\n 0xaffed0e0\n eq\n tag_4\n jumpi\n tag_2:\n 0x00\n dup1\n revert\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":938:1094 function readNonce(uint256 _space) public virtual view returns (uint256) {... */\n tag_3:\n tag_5\n tag_6\n calldatasize\n 0x04\n tag_7\n jump\t// in\n tag_6:\n tag_8\n jump\t// in\n tag_5:\n mload(0x40)\n /* \"#utility.yul\":345:370 */\n swap1\n dup2\n mstore\n /* \"#utility.yul\":333:335 */\n 0x20\n /* \"#utility.yul\":318:336 */\n add\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":938:1094 function readNonce(uint256 _space) public virtual view returns (uint256) {... */\n mload(0x40)\n dup1\n swap2\n sub\n swap1\n return\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":670:757 function nonce() external virtual view returns (uint256) {... */\n tag_4:\n tag_5\n tag_12\n jump\t// in\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":938:1094 function readNonce(uint256 _space) public virtual view returns (uint256) {... */\n tag_8:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":1002:1009 uint256 */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":1032:1088 ModuleStorage.readBytes32Map(NONCE_KEY, bytes32(_space)) */\n tag_15\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":453:519 0x8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e */\n 0x8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":1080:1086 _space */\n dup4\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":1032:1060 ModuleStorage.readBytes32Map */\n tag_16\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":1032:1088 ModuleStorage.readBytes32Map(NONCE_KEY, bytes32(_space)) */\n jump\t// in\n tag_15:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":1024:1089 uint256(ModuleStorage.readBytes32Map(NONCE_KEY, bytes32(_space))) */\n swap3\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":938:1094 function readNonce(uint256 _space) public virtual view returns (uint256) {... */\n swap2\n pop\n pop\n jump\t// out\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":670:757 function nonce() external virtual view returns (uint256) {... */\n tag_12:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":718:725 uint256 */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":740:752 readNonce(0) */\n tag_18\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":750:751 0 */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":740:749 readNonce */\n tag_8\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":740:752 readNonce(0) */\n jump\t// in\n tag_18:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":733:752 return readNonce(0) */\n swap1\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":670:757 function nonce() external virtual view returns (uint256) {... */\n swap1\n jump\t// out\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol\":490:677 function readBytes32Map(bytes32 _key, bytes32 _subKey) internal view returns (bytes32 val) {... */\n tag_16:\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol\":568:579 bytes32 val */\n 0x00\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol\":587:598 bytes32 key */\n dup1\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol\":622:626 _key */\n dup4\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol\":628:635 _subKey */\n dup4\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol\":611:636 abi.encode(_key, _subKey) */\n add(0x20, mload(0x40))\n tag_20\n swap3\n swap2\n swap1\n /* \"#utility.yul\":555:580 */\n swap2\n dup3\n mstore\n /* \"#utility.yul\":611:613 */\n 0x20\n /* \"#utility.yul\":596:614 */\n dup3\n add\n /* \"#utility.yul\":589:623 */\n mstore\n /* \"#utility.yul\":543:545 */\n 0x40\n /* \"#utility.yul\":528:546 */\n add\n swap1\n /* \"#utility.yul\":381:629 */\n jump\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol\":611:636 abi.encode(_key, _subKey) */\n tag_20:\n 0x40\n dup1\n mload\n 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0\n dup2\n dup5\n sub\n add\n dup2\n mstore\n swap2\n swap1\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol\":601:637 keccak256(abi.encode(_key, _subKey)) */\n dup1\n mload\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol\":611:636 abi.encode(_key, _subKey) */\n 0x20\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol\":601:637 keccak256(abi.encode(_key, _subKey)) */\n swap1\n swap2\n add\n keccak256\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol\":661:671 sload(key) */\n sload\n swap5\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol\":490:677 function readBytes32Map(bytes32 _key, bytes32 _subKey) internal view returns (bytes32 val) {... */\n swap4\n pop\n pop\n pop\n pop\n jump\t// out\n /* \"#utility.yul\":14:194 */\n tag_7:\n /* \"#utility.yul\":73:79 */\n 0x00\n /* \"#utility.yul\":126:128 */\n 0x20\n /* \"#utility.yul\":114:123 */\n dup3\n /* \"#utility.yul\":105:112 */\n dup5\n /* \"#utility.yul\":101:124 */\n sub\n /* \"#utility.yul\":97:129 */\n slt\n /* \"#utility.yul\":94:146 */\n iszero\n tag_24\n jumpi\n /* \"#utility.yul\":142:143 */\n 0x00\n /* \"#utility.yul\":139:140 */\n dup1\n /* \"#utility.yul\":132:144 */\n revert\n /* \"#utility.yul\":94:146 */\n tag_24:\n pop\n /* \"#utility.yul\":165:188 */\n calldataload\n swap2\n /* \"#utility.yul\":14:194 */\n swap1\n pop\n jump\t// out\n\n auxdata: 0xa264697066735822122096307c37b71eb1ad75d89220df55103f539339b39b69638a2d573cf67d84ea6164736f6c63430008120033\n}\n", + "bytecode": { + "functionDebugData": {}, + "generatedSources": [], + "linkReferences": {}, + "object": "608060405234801561001057600080fd5b50610158806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80638c3f55631461003b578063affed0e014610060575b600080fd5b61004e610049366004610109565b610068565b60405190815260200160405180910390f35b61004e61009a565b60006100947f8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e836100ab565b92915050565b60006100a66000610068565b905090565b60008083836040516020016100ca929190918252602082015260400190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052805160209091012054949350505050565b60006020828403121561011b57600080fd5b503591905056fea264697066735822122096307c37b71eb1ad75d89220df55103f539339b39b69638a2d573cf67d84ea6164736f6c63430008120033", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x158 DUP1 PUSH2 0x20 PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH2 0x36 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x8C3F5563 EQ PUSH2 0x3B JUMPI DUP1 PUSH4 0xAFFED0E0 EQ PUSH2 0x60 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x4E PUSH2 0x49 CALLDATASIZE PUSH1 0x4 PUSH2 0x109 JUMP JUMPDEST PUSH2 0x68 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x4E PUSH2 0x9A JUMP JUMPDEST PUSH1 0x0 PUSH2 0x94 PUSH32 0x8D0BF1FD623D628C741362C1289948E57B3E2905218C676D3E69ABEE36D6AE2E DUP4 PUSH2 0xAB JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0xA6 PUSH1 0x0 PUSH2 0x68 JUMP JUMPDEST SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 DUP4 PUSH1 0x40 MLOAD PUSH1 0x20 ADD PUSH2 0xCA SWAP3 SWAP2 SWAP1 SWAP2 DUP3 MSTORE PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP2 DUP5 SUB ADD DUP2 MSTORE SWAP2 SWAP1 MSTORE DUP1 MLOAD PUSH1 0x20 SWAP1 SWAP2 ADD KECCAK256 SLOAD SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x11B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP CALLDATALOAD SWAP2 SWAP1 POP JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 SWAP7 ADDRESS PUSH29 0x37B71EB1AD75D89220DF55103F539339B39B69638A2D573CF67D84EA61 PUSH5 0x736F6C6343 STOP ADDMOD SLT STOP CALLER ", + "sourceMap": "145:1931:6:-:0;;;;;;;;;;;;;;;;;;;" + }, + "deployedBytecode": { + "functionDebugData": { + "@nonce_955": { + "entryPoint": 154, + "id": 955, + "parameterSlots": 0, + "returnSlots": 1 + }, + "@readBytes32Map_1178": { + "entryPoint": 171, + "id": 1178, + "parameterSlots": 2, + "returnSlots": 1 + }, + "@readNonce_976": { + "entryPoint": 104, + "id": 976, + "parameterSlots": 1, + "returnSlots": 1 + }, + "abi_decode_tuple_t_uint256": { + "entryPoint": 265, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + }, + "abi_encode_tuple_t_bytes32_t_bytes32__to_t_bytes32_t_bytes32__fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 3, + "returnSlots": 1 + }, + "abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed": { + "entryPoint": null, + "id": null, + "parameterSlots": 2, + "returnSlots": 1 + } + }, + "generatedSources": [ + { + "ast": { + "nodeType": "YulBlock", + "src": "0:631:22", + "statements": [ + { + "nodeType": "YulBlock", + "src": "6:3:22", + "statements": [] + }, + { + "body": { + "nodeType": "YulBlock", + "src": "84:110:22", + "statements": [ + { + "body": { + "nodeType": "YulBlock", + "src": "130:16:22", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "139:1:22", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "142:1:22", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "132:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "132:12:22" + }, + "nodeType": "YulExpressionStatement", + "src": "132:12:22" + } + ] + }, + "condition": { + "arguments": [ + { + "arguments": [ + { + "name": "dataEnd", + "nodeType": "YulIdentifier", + "src": "105:7:22" + }, + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "114:9:22" + } + ], + "functionName": { + "name": "sub", + "nodeType": "YulIdentifier", + "src": "101:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "101:23:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "126:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "slt", + "nodeType": "YulIdentifier", + "src": "97:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "97:32:22" + }, + "nodeType": "YulIf", + "src": "94:52:22" + }, + { + "nodeType": "YulAssignment", + "src": "155:33:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "178:9:22" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "165:12:22" + }, + "nodeType": "YulFunctionCall", + "src": "165:23:22" + }, + "variableNames": [ + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "155:6:22" + } + ] + } + ] + }, + "name": "abi_decode_tuple_t_uint256", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "50:9:22", + "type": "" + }, + { + "name": "dataEnd", + "nodeType": "YulTypedName", + "src": "61:7:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "73:6:22", + "type": "" + } + ], + "src": "14:180:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "300:76:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "310:26:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "322:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "333:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "318:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "318:18:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "310:4:22" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "352:9:22" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "363:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "345:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "345:25:22" + }, + "nodeType": "YulExpressionStatement", + "src": "345:25:22" + } + ] + }, + "name": "abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "269:9:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "280:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "291:4:22", + "type": "" + } + ], + "src": "199:177:22" + }, + { + "body": { + "nodeType": "YulBlock", + "src": "510:119:22", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "520:26:22", + "value": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "532:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "543:2:22", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "528:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "528:18:22" + }, + "variableNames": [ + { + "name": "tail", + "nodeType": "YulIdentifier", + "src": "520:4:22" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "562:9:22" + }, + { + "name": "value0", + "nodeType": "YulIdentifier", + "src": "573:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "555:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "555:25:22" + }, + "nodeType": "YulExpressionStatement", + "src": "555:25:22" + }, + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "headStart", + "nodeType": "YulIdentifier", + "src": "600:9:22" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "611:2:22", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "596:3:22" + }, + "nodeType": "YulFunctionCall", + "src": "596:18:22" + }, + { + "name": "value1", + "nodeType": "YulIdentifier", + "src": "616:6:22" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "589:6:22" + }, + "nodeType": "YulFunctionCall", + "src": "589:34:22" + }, + "nodeType": "YulExpressionStatement", + "src": "589:34:22" + } + ] + }, + "name": "abi_encode_tuple_t_bytes32_t_bytes32__to_t_bytes32_t_bytes32__fromStack_reversed", + "nodeType": "YulFunctionDefinition", + "parameters": [ + { + "name": "headStart", + "nodeType": "YulTypedName", + "src": "471:9:22", + "type": "" + }, + { + "name": "value1", + "nodeType": "YulTypedName", + "src": "482:6:22", + "type": "" + }, + { + "name": "value0", + "nodeType": "YulTypedName", + "src": "490:6:22", + "type": "" + } + ], + "returnVariables": [ + { + "name": "tail", + "nodeType": "YulTypedName", + "src": "501:4:22", + "type": "" + } + ], + "src": "381:248:22" + } + ] + }, + "contents": "{\n { }\n function abi_decode_tuple_t_uint256(headStart, dataEnd) -> value0\n {\n if slt(sub(dataEnd, headStart), 32) { revert(0, 0) }\n value0 := calldataload(headStart)\n }\n function abi_encode_tuple_t_uint256__to_t_uint256__fromStack_reversed(headStart, value0) -> tail\n {\n tail := add(headStart, 32)\n mstore(headStart, value0)\n }\n function abi_encode_tuple_t_bytes32_t_bytes32__to_t_bytes32_t_bytes32__fromStack_reversed(headStart, value1, value0) -> tail\n {\n tail := add(headStart, 64)\n mstore(headStart, value0)\n mstore(add(headStart, 32), value1)\n }\n}", + "id": 22, + "language": "Yul", + "name": "#utility.yul" + } + ], + "immutableReferences": {}, + "linkReferences": {}, + "object": "608060405234801561001057600080fd5b50600436106100365760003560e01c80638c3f55631461003b578063affed0e014610060575b600080fd5b61004e610049366004610109565b610068565b60405190815260200160405180910390f35b61004e61009a565b60006100947f8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e836100ab565b92915050565b60006100a66000610068565b905090565b60008083836040516020016100ca929190918252602082015260400190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052805160209091012054949350505050565b60006020828403121561011b57600080fd5b503591905056fea264697066735822122096307c37b71eb1ad75d89220df55103f539339b39b69638a2d573cf67d84ea6164736f6c63430008120033", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x4 CALLDATASIZE LT PUSH2 0x36 JUMPI PUSH1 0x0 CALLDATALOAD PUSH1 0xE0 SHR DUP1 PUSH4 0x8C3F5563 EQ PUSH2 0x3B JUMPI DUP1 PUSH4 0xAFFED0E0 EQ PUSH2 0x60 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST PUSH2 0x4E PUSH2 0x49 CALLDATASIZE PUSH1 0x4 PUSH2 0x109 JUMP JUMPDEST PUSH2 0x68 JUMP JUMPDEST PUSH1 0x40 MLOAD SWAP1 DUP2 MSTORE PUSH1 0x20 ADD PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH2 0x4E PUSH2 0x9A JUMP JUMPDEST PUSH1 0x0 PUSH2 0x94 PUSH32 0x8D0BF1FD623D628C741362C1289948E57B3E2905218C676D3E69ABEE36D6AE2E DUP4 PUSH2 0xAB JUMP JUMPDEST SWAP3 SWAP2 POP POP JUMP JUMPDEST PUSH1 0x0 PUSH2 0xA6 PUSH1 0x0 PUSH2 0x68 JUMP JUMPDEST SWAP1 POP SWAP1 JUMP JUMPDEST PUSH1 0x0 DUP1 DUP4 DUP4 PUSH1 0x40 MLOAD PUSH1 0x20 ADD PUSH2 0xCA SWAP3 SWAP2 SWAP1 SWAP2 DUP3 MSTORE PUSH1 0x20 DUP3 ADD MSTORE PUSH1 0x40 ADD SWAP1 JUMP JUMPDEST PUSH1 0x40 DUP1 MLOAD PUSH32 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 DUP2 DUP5 SUB ADD DUP2 MSTORE SWAP2 SWAP1 MSTORE DUP1 MLOAD PUSH1 0x20 SWAP1 SWAP2 ADD KECCAK256 SLOAD SWAP5 SWAP4 POP POP POP POP JUMP JUMPDEST PUSH1 0x0 PUSH1 0x20 DUP3 DUP5 SUB SLT ISZERO PUSH2 0x11B JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP CALLDATALOAD SWAP2 SWAP1 POP JUMP INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 SWAP7 ADDRESS PUSH29 0x37B71EB1AD75D89220DF55103F539339B39B69638A2D573CF67D84EA61 PUSH5 0x736F6C6343 STOP ADDMOD SLT STOP CALLER ", + "sourceMap": "145:1931:6:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;938:156;;;;;;:::i;:::-;;:::i;:::-;;;345:25:22;;;333:2;318:18;938:156:6;;;;;;;670:87;;;:::i;938:156::-;1002:7;1032:56;453:66;1080:6;1032:28;:56::i;:::-;1024:65;938:156;-1:-1:-1;;938:156:6:o;670:87::-;718:7;740:12;750:1;740:9;:12::i;:::-;733:19;;670:87;:::o;490:187:9:-;568:11;587;622:4;628:7;611:25;;;;;;;;555::22;;;611:2;596:18;;589:34;543:2;528:18;;381:248;611:25:9;;;;;;;;;;;;;;601:36;;611:25;601:36;;;;661:10;;490:187;-1:-1:-1;;;;490:187:9:o;14:180:22:-;73:6;126:2;114:9;105:7;101:23;97:32;94:52;;;142:1;139;132:12;94:52;-1:-1:-1;165:23:22;;14:180;-1:-1:-1;14:180:22:o" + }, + "gasEstimates": { + "creation": { + "codeDepositCost": "68800", + "executionCost": "117", + "totalCost": "68917" + }, + "external": { + "nonce()": "2567", + "readNonce(uint256)": "2584" + }, + "internal": { + "_validateNonce(uint256)": "infinite", + "_writeNonce(uint256,uint256)": "infinite" + } + }, + "legacyAssembly": { + ".code": [ + { + "begin": 145, + "end": 2076, + "name": "PUSH", + "source": 6, + "value": "80" + }, + { + "begin": 145, + "end": 2076, + "name": "PUSH", + "source": 6, + "value": "40" + }, + { + "begin": 145, + "end": 2076, + "name": "MSTORE", + "source": 6 + }, + { + "begin": 145, + "end": 2076, + "name": "CALLVALUE", + "source": 6 + }, + { + "begin": 145, + "end": 2076, + "name": "DUP1", + "source": 6 + }, + { + "begin": 145, + "end": 2076, + "name": "ISZERO", + "source": 6 + }, + { + "begin": 145, + "end": 2076, + "name": "PUSH [tag]", + "source": 6, + "value": "1" + }, + { + "begin": 145, + "end": 2076, + "name": "JUMPI", + "source": 6 + }, + { + "begin": 145, + "end": 2076, + "name": "PUSH", + "source": 6, + "value": "0" + }, + { + "begin": 145, + "end": 2076, + "name": "DUP1", + "source": 6 + }, + { + "begin": 145, + "end": 2076, + "name": "REVERT", + "source": 6 + }, + { + "begin": 145, + "end": 2076, + "name": "tag", + "source": 6, + "value": "1" + }, + { + "begin": 145, + "end": 2076, + "name": "JUMPDEST", + "source": 6 + }, + { + "begin": 145, + "end": 2076, + "name": "POP", + "source": 6 + }, + { + "begin": 145, + "end": 2076, + "name": "PUSH #[$]", + "source": 6, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 145, + "end": 2076, + "name": "DUP1", + "source": 6 + }, + { + "begin": 145, + "end": 2076, + "name": "PUSH [$]", + "source": 6, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 145, + "end": 2076, + "name": "PUSH", + "source": 6, + "value": "0" + }, + { + "begin": 145, + "end": 2076, + "name": "CODECOPY", + "source": 6 + }, + { + "begin": 145, + "end": 2076, + "name": "PUSH", + "source": 6, + "value": "0" + }, + { + "begin": 145, + "end": 2076, + "name": "RETURN", + "source": 6 + } + ], + ".data": { + "0": { + ".auxdata": "a264697066735822122096307c37b71eb1ad75d89220df55103f539339b39b69638a2d573cf67d84ea6164736f6c63430008120033", + ".code": [ + { + "begin": 145, + "end": 2076, + "name": "PUSH", + "source": 6, + "value": "80" + }, + { + "begin": 145, + "end": 2076, + "name": "PUSH", + "source": 6, + "value": "40" + }, + { + "begin": 145, + "end": 2076, + "name": "MSTORE", + "source": 6 + }, + { + "begin": 145, + "end": 2076, + "name": "CALLVALUE", + "source": 6 + }, + { + "begin": 145, + "end": 2076, + "name": "DUP1", + "source": 6 + }, + { + "begin": 145, + "end": 2076, + "name": "ISZERO", + "source": 6 + }, + { + "begin": 145, + "end": 2076, + "name": "PUSH [tag]", + "source": 6, + "value": "1" + }, + { + "begin": 145, + "end": 2076, + "name": "JUMPI", + "source": 6 + }, + { + "begin": 145, + "end": 2076, + "name": "PUSH", + "source": 6, + "value": "0" + }, + { + "begin": 145, + "end": 2076, + "name": "DUP1", + "source": 6 + }, + { + "begin": 145, + "end": 2076, + "name": "REVERT", + "source": 6 + }, + { + "begin": 145, + "end": 2076, + "name": "tag", + "source": 6, + "value": "1" + }, + { + "begin": 145, + "end": 2076, + "name": "JUMPDEST", + "source": 6 + }, + { + "begin": 145, + "end": 2076, + "name": "POP", + "source": 6 + }, + { + "begin": 145, + "end": 2076, + "name": "PUSH", + "source": 6, + "value": "4" + }, + { + "begin": 145, + "end": 2076, + "name": "CALLDATASIZE", + "source": 6 + }, + { + "begin": 145, + "end": 2076, + "name": "LT", + "source": 6 + }, + { + "begin": 145, + "end": 2076, + "name": "PUSH [tag]", + "source": 6, + "value": "2" + }, + { + "begin": 145, + "end": 2076, + "name": "JUMPI", + "source": 6 + }, + { + "begin": 145, + "end": 2076, + "name": "PUSH", + "source": 6, + "value": "0" + }, + { + "begin": 145, + "end": 2076, + "name": "CALLDATALOAD", + "source": 6 + }, + { + "begin": 145, + "end": 2076, + "name": "PUSH", + "source": 6, + "value": "E0" + }, + { + "begin": 145, + "end": 2076, + "name": "SHR", + "source": 6 + }, + { + "begin": 145, + "end": 2076, + "name": "DUP1", + "source": 6 + }, + { + "begin": 145, + "end": 2076, + "name": "PUSH", + "source": 6, + "value": "8C3F5563" + }, + { + "begin": 145, + "end": 2076, + "name": "EQ", + "source": 6 + }, + { + "begin": 145, + "end": 2076, + "name": "PUSH [tag]", + "source": 6, + "value": "3" + }, + { + "begin": 145, + "end": 2076, + "name": "JUMPI", + "source": 6 + }, + { + "begin": 145, + "end": 2076, + "name": "DUP1", + "source": 6 + }, + { + "begin": 145, + "end": 2076, + "name": "PUSH", + "source": 6, + "value": "AFFED0E0" + }, + { + "begin": 145, + "end": 2076, + "name": "EQ", + "source": 6 + }, + { + "begin": 145, + "end": 2076, + "name": "PUSH [tag]", + "source": 6, + "value": "4" + }, + { + "begin": 145, + "end": 2076, + "name": "JUMPI", + "source": 6 + }, + { + "begin": 145, + "end": 2076, + "name": "tag", + "source": 6, + "value": "2" + }, + { + "begin": 145, + "end": 2076, + "name": "JUMPDEST", + "source": 6 + }, + { + "begin": 145, + "end": 2076, + "name": "PUSH", + "source": 6, + "value": "0" + }, + { + "begin": 145, + "end": 2076, + "name": "DUP1", + "source": 6 + }, + { + "begin": 145, + "end": 2076, + "name": "REVERT", + "source": 6 + }, + { + "begin": 938, + "end": 1094, + "name": "tag", + "source": 6, + "value": "3" + }, + { + "begin": 938, + "end": 1094, + "name": "JUMPDEST", + "source": 6 + }, + { + "begin": 938, + "end": 1094, + "name": "PUSH [tag]", + "source": 6, + "value": "5" + }, + { + "begin": 938, + "end": 1094, + "name": "PUSH [tag]", + "source": 6, + "value": "6" + }, + { + "begin": 938, + "end": 1094, + "name": "CALLDATASIZE", + "source": 6 + }, + { + "begin": 938, + "end": 1094, + "name": "PUSH", + "source": 6, + "value": "4" + }, + { + "begin": 938, + "end": 1094, + "name": "PUSH [tag]", + "source": 6, + "value": "7" + }, + { + "begin": 938, + "end": 1094, + "jumpType": "[in]", + "name": "JUMP", + "source": 6 + }, + { + "begin": 938, + "end": 1094, + "name": "tag", + "source": 6, + "value": "6" + }, + { + "begin": 938, + "end": 1094, + "name": "JUMPDEST", + "source": 6 + }, + { + "begin": 938, + "end": 1094, + "name": "PUSH [tag]", + "source": 6, + "value": "8" + }, + { + "begin": 938, + "end": 1094, + "jumpType": "[in]", + "name": "JUMP", + "source": 6 + }, + { + "begin": 938, + "end": 1094, + "name": "tag", + "source": 6, + "value": "5" + }, + { + "begin": 938, + "end": 1094, + "name": "JUMPDEST", + "source": 6 + }, + { + "begin": 938, + "end": 1094, + "name": "PUSH", + "source": 6, + "value": "40" + }, + { + "begin": 938, + "end": 1094, + "name": "MLOAD", + "source": 6 + }, + { + "begin": 345, + "end": 370, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 345, + "end": 370, + "name": "DUP2", + "source": 22 + }, + { + "begin": 345, + "end": 370, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 333, + "end": 335, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 318, + "end": 336, + "name": "ADD", + "source": 22 + }, + { + "begin": 938, + "end": 1094, + "name": "PUSH", + "source": 6, + "value": "40" + }, + { + "begin": 938, + "end": 1094, + "name": "MLOAD", + "source": 6 + }, + { + "begin": 938, + "end": 1094, + "name": "DUP1", + "source": 6 + }, + { + "begin": 938, + "end": 1094, + "name": "SWAP2", + "source": 6 + }, + { + "begin": 938, + "end": 1094, + "name": "SUB", + "source": 6 + }, + { + "begin": 938, + "end": 1094, + "name": "SWAP1", + "source": 6 + }, + { + "begin": 938, + "end": 1094, + "name": "RETURN", + "source": 6 + }, + { + "begin": 670, + "end": 757, + "name": "tag", + "source": 6, + "value": "4" + }, + { + "begin": 670, + "end": 757, + "name": "JUMPDEST", + "source": 6 + }, + { + "begin": 670, + "end": 757, + "name": "PUSH [tag]", + "source": 6, + "value": "5" + }, + { + "begin": 670, + "end": 757, + "name": "PUSH [tag]", + "source": 6, + "value": "12" + }, + { + "begin": 670, + "end": 757, + "jumpType": "[in]", + "name": "JUMP", + "source": 6 + }, + { + "begin": 938, + "end": 1094, + "name": "tag", + "source": 6, + "value": "8" + }, + { + "begin": 938, + "end": 1094, + "name": "JUMPDEST", + "source": 6 + }, + { + "begin": 1002, + "end": 1009, + "name": "PUSH", + "source": 6, + "value": "0" + }, + { + "begin": 1032, + "end": 1088, + "name": "PUSH [tag]", + "source": 6, + "value": "15" + }, + { + "begin": 453, + "end": 519, + "name": "PUSH", + "source": 6, + "value": "8D0BF1FD623D628C741362C1289948E57B3E2905218C676D3E69ABEE36D6AE2E" + }, + { + "begin": 1080, + "end": 1086, + "name": "DUP4", + "source": 6 + }, + { + "begin": 1032, + "end": 1060, + "name": "PUSH [tag]", + "source": 6, + "value": "16" + }, + { + "begin": 1032, + "end": 1088, + "jumpType": "[in]", + "name": "JUMP", + "source": 6 + }, + { + "begin": 1032, + "end": 1088, + "name": "tag", + "source": 6, + "value": "15" + }, + { + "begin": 1032, + "end": 1088, + "name": "JUMPDEST", + "source": 6 + }, + { + "begin": 1024, + "end": 1089, + "name": "SWAP3", + "source": 6 + }, + { + "begin": 938, + "end": 1094, + "name": "SWAP2", + "source": 6 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 938, + "end": 1094, + "jumpType": "[out]", + "name": "JUMP", + "source": 6 + }, + { + "begin": 670, + "end": 757, + "name": "tag", + "source": 6, + "value": "12" + }, + { + "begin": 670, + "end": 757, + "name": "JUMPDEST", + "source": 6 + }, + { + "begin": 718, + "end": 725, + "name": "PUSH", + "source": 6, + "value": "0" + }, + { + "begin": 740, + "end": 752, + "name": "PUSH [tag]", + "source": 6, + "value": "18" + }, + { + "begin": 750, + "end": 751, + "name": "PUSH", + "source": 6, + "value": "0" + }, + { + "begin": 740, + "end": 749, + "name": "PUSH [tag]", + "source": 6, + "value": "8" + }, + { + "begin": 740, + "end": 752, + "jumpType": "[in]", + "name": "JUMP", + "source": 6 + }, + { + "begin": 740, + "end": 752, + "name": "tag", + "source": 6, + "value": "18" + }, + { + "begin": 740, + "end": 752, + "name": "JUMPDEST", + "source": 6 + }, + { + "begin": 733, + "end": 752, + "name": "SWAP1", + "source": 6 + }, + { + "begin": 733, + "end": 752, + "name": "POP", + "source": 6 + }, + { + "begin": 670, + "end": 757, + "name": "SWAP1", + "source": 6 + }, + { + "begin": 670, + "end": 757, + "jumpType": "[out]", + "name": "JUMP", + "source": 6 + }, + { + "begin": 490, + "end": 677, + "name": "tag", + "source": 9, + "value": "16" + }, + { + "begin": 490, + "end": 677, + "name": "JUMPDEST", + "source": 9 + }, + { + "begin": 568, + "end": 579, + "name": "PUSH", + "source": 9, + "value": "0" + }, + { + "begin": 587, + "end": 598, + "name": "DUP1", + "source": 9 + }, + { + "begin": 622, + "end": 626, + "name": "DUP4", + "source": 9 + }, + { + "begin": 628, + "end": 635, + "name": "DUP4", + "source": 9 + }, + { + "begin": 611, + "end": 636, + "name": "PUSH", + "source": 9, + "value": "40" + }, + { + "begin": 611, + "end": 636, + "name": "MLOAD", + "source": 9 + }, + { + "begin": 611, + "end": 636, + "name": "PUSH", + "source": 9, + "value": "20" + }, + { + "begin": 611, + "end": 636, + "name": "ADD", + "source": 9 + }, + { + "begin": 611, + "end": 636, + "name": "PUSH [tag]", + "source": 9, + "value": "20" + }, + { + "begin": 611, + "end": 636, + "name": "SWAP3", + "source": 9 + }, + { + "begin": 611, + "end": 636, + "name": "SWAP2", + "source": 9 + }, + { + "begin": 611, + "end": 636, + "name": "SWAP1", + "source": 9 + }, + { + "begin": 555, + "end": 580, + "name": "SWAP2", + "source": 22 + }, + { + "begin": 555, + "end": 580, + "name": "DUP3", + "source": 22 + }, + { + "begin": 555, + "end": 580, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 611, + "end": 613, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 596, + "end": 614, + "name": "DUP3", + "source": 22 + }, + { + "begin": 596, + "end": 614, + "name": "ADD", + "source": 22 + }, + { + "begin": 589, + "end": 623, + "name": "MSTORE", + "source": 22 + }, + { + "begin": 543, + "end": 545, + "name": "PUSH", + "source": 22, + "value": "40" + }, + { + "begin": 528, + "end": 546, + "name": "ADD", + "source": 22 + }, + { + "begin": 528, + "end": 546, + "name": "SWAP1", + "source": 22 + }, + { + "begin": 381, + "end": 629, + "name": "JUMP", + "source": 22 + }, + { + "begin": 611, + "end": 636, + "name": "tag", + "source": 9, + "value": "20" + }, + { + "begin": 611, + "end": 636, + "name": "JUMPDEST", + "source": 9 + }, + { + "begin": 611, + "end": 636, + "name": "PUSH", + "source": 9, + "value": "40" + }, + { + "begin": 611, + "end": 636, + "name": "DUP1", + "source": 9 + }, + { + "begin": 611, + "end": 636, + "name": "MLOAD", + "source": 9 + }, + { + "begin": 611, + "end": 636, + "name": "PUSH", + "source": 9, + "value": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0" + }, + { + "begin": 611, + "end": 636, + "name": "DUP2", + "source": 9 + }, + { + "begin": 611, + "end": 636, + "name": "DUP5", + "source": 9 + }, + { + "begin": 611, + "end": 636, + "name": "SUB", + "source": 9 + }, + { + "begin": 611, + "end": 636, + "name": "ADD", + "source": 9 + }, + { + "begin": 611, + "end": 636, + "name": "DUP2", + "source": 9 + }, + { + "begin": 611, + "end": 636, + "name": "MSTORE", + "source": 9 + }, + { + "begin": 611, + "end": 636, + "name": "SWAP2", + "source": 9 + }, + { + "begin": 611, + "end": 636, + "name": "SWAP1", + "source": 9 + }, + { + "begin": 611, + "end": 636, + "name": "MSTORE", + "source": 9 + }, + { + "begin": 601, + "end": 637, + "name": "DUP1", + "source": 9 + }, + { + "begin": 601, + "end": 637, + "name": "MLOAD", + "source": 9 + }, + { + "begin": 611, + "end": 636, + "name": "PUSH", + "source": 9, + "value": "20" + }, + { + "begin": 601, + "end": 637, + "name": "SWAP1", + "source": 9 + }, + { + "begin": 601, + "end": 637, + "name": "SWAP2", + "source": 9 + }, + { + "begin": 601, + "end": 637, + "name": "ADD", + "source": 9 + }, + { + "begin": 601, + "end": 637, + "name": "KECCAK256", + "source": 9 + }, + { + "begin": 661, + "end": 671, + "name": "SLOAD", + "source": 9 + }, + { + "begin": 661, + "end": 671, + "name": "SWAP5", + "source": 9 + }, + { + "begin": 490, + "end": 677, + "name": "SWAP4", + "source": 9 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 490, + "end": 677, + "jumpType": "[out]", + "name": "JUMP", + "source": 9 + }, + { + "begin": 14, + "end": 194, + "name": "tag", + "source": 22, + "value": "7" + }, + { + "begin": 14, + "end": 194, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": 73, + "end": 79, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 126, + "end": 128, + "name": "PUSH", + "source": 22, + "value": "20" + }, + { + "begin": 114, + "end": 123, + "name": "DUP3", + "source": 22 + }, + { + "begin": 105, + "end": 112, + "name": "DUP5", + "source": 22 + }, + { + "begin": 101, + "end": 124, + "name": "SUB", + "source": 22 + }, + { + "begin": 97, + "end": 129, + "name": "SLT", + "source": 22 + }, + { + "begin": 94, + "end": 146, + "name": "ISZERO", + "source": 22 + }, + { + "begin": 94, + "end": 146, + "name": "PUSH [tag]", + "source": 22, + "value": "24" + }, + { + "begin": 94, + "end": 146, + "name": "JUMPI", + "source": 22 + }, + { + "begin": 142, + "end": 143, + "name": "PUSH", + "source": 22, + "value": "0" + }, + { + "begin": 139, + "end": 140, + "name": "DUP1", + "source": 22 + }, + { + "begin": 132, + "end": 144, + "name": "REVERT", + "source": 22 + }, + { + "begin": 94, + "end": 146, + "name": "tag", + "source": 22, + "value": "24" + }, + { + "begin": 94, + "end": 146, + "name": "JUMPDEST", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 165, + "end": 188, + "name": "CALLDATALOAD", + "source": 22 + }, + { + "begin": 165, + "end": 188, + "name": "SWAP2", + "source": 22 + }, + { + "begin": 14, + "end": 194, + "name": "SWAP1", + "source": 22 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 14, + "end": 194, + "jumpType": "[out]", + "name": "JUMP", + "source": 22 + } + ] + } + }, + "sourceList": [ + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/interfaces/IERC1271Wallet.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleERC165.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleOnlyDelegatecall.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCalls.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCreator.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol", + "#utility.yul" + ] + }, + "methodIdentifiers": { + "nonce()": "affed0e0", + "readNonce(uint256)": "8c3f5563" + } + }, + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_space\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_provided\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_current\",\"type\":\"uint256\"}],\"name\":\"BadNonce\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_space\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_newNonce\",\"type\":\"uint256\"}],\"name\":\"NonceChange\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_space\",\"type\":\"uint256\"}],\"name\":\"readNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"nonce()\":{\"details\":\"The default nonce space is 0x00\",\"returns\":{\"_0\":\"The next nonce\"}},\"readNonce(uint256)\":{\"params\":{\"_space\":\"Nonce space, each space keeps an independent nonce count\"},\"returns\":{\"_0\":\"The next nonce\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"nonce()\":{\"notice\":\"Returns the next nonce of the default nonce space\"},\"readNonce(uint256)\":{\"notice\":\"Returns the next nonce of the given nonce space\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":\"ModuleNonce\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":500000},\"remappings\":[\":@0xsequence/contracts-library/=src/\",\":@0xsequence/erc-1155/=lib/0xsequence/erc-1155/src/\",\":@0xsequence/erc20-meta-token/=lib/0xsequence/erc20-meta-token/src/\",\":@openzeppelin/=lib/openzeppelin/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc721a-upgradeable/=lib/chiru-labs/erc721a-upgradeable/\",\":erc721a/=lib/chiru-labs/erc721a/\",\":forge-std/=lib/forge-std/src/\",\":murky/=lib/murky/src/\",\":solady/=lib/solady/src/\"]},\"sources\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol\":{\"keccak256\":\"0x3b5388842f763a5347d632a0e0e8499a54b6f0b0a6eb7f7d3d848319defa042d\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://b36fa5a88a4e174967f850bf2bb78c787d8016ef7b5eee3e2f883fbfe9b87a7d\",\"dweb:/ipfs/QmTDZiPiQGe1fmTKKzdwzBE1xjkh8apTotW1SQRUCFXf4q\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol\":{\"keccak256\":\"0x876c6a40cba975df4f7dfe24e02d153b2ee758975b6d1eda494ecd4b7244aa8e\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://b9be3f7930476d528ce10a121701421f0fb251b7d6b7cd579917375e6b283bb4\",\"dweb:/ipfs/QmSbvbYQvTk8KYJZ7QqSKB9Y4M1X3UDhS6k765Zr1BAwK8\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol\":{\"keccak256\":\"0x98520e740b0822ec053d21f376b8be8a58e93228f3758f9228a7d00e1f60950f\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://31226706c004f1a4315d6b8d37621b46f4d5807c16e1ce72675c1431ed9006a2\",\"dweb:/ipfs/QmdSSyCuPex2E2VTd6UMYy9WAq9eJNZ6vHSUomntNknzXE\"]}},\"version\":1}", + "storageLayout": { + "storage": [], + "types": null + }, + "userdoc": { + "kind": "user", + "methods": { + "nonce()": { + "notice": "Returns the next nonce of the default nonce space" + }, + "readNonce(uint256)": { + "notice": "Returns the next nonce of the given nonce space" + } + }, + "version": 1 + } + } + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleOnlyDelegatecall.sol": { + "ModuleOnlyDelegatecall": { + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "OnlyDelegatecall", + "type": "error" + } + ], + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "evm": { + "assembly": " /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleOnlyDelegatecall.sol\":65:420 contract ModuleOnlyDelegatecall {... */\n mstore(0x40, 0xa0)\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleOnlyDelegatecall.sol\":165:210 constructor() {... */\n callvalue\n dup1\n iszero\n tag_1\n jumpi\n 0x00\n dup1\n revert\ntag_1:\n pop\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleOnlyDelegatecall.sol\":200:204 this */\n address\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleOnlyDelegatecall.sol\":185:205 self = address(this) */\n 0x80\n mstore\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleOnlyDelegatecall.sol\":65:420 contract ModuleOnlyDelegatecall {... */\n mload(0x80)\n codecopy(0x00, dataOffset(sub_0), dataSize(sub_0))\n 0x00\n assignImmutable(\"0x4ffc9d227228e624d76834105f24ceb5cb9c5a8675150ad2031c88a10259e303\")\n return(0x00, dataSize(sub_0))\nstop\n\nsub_0: assembly {\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleOnlyDelegatecall.sol\":65:420 contract ModuleOnlyDelegatecall {... */\n mstore(0x40, 0x80)\n 0x00\n dup1\n revert\n\n auxdata: 0xa26469706673582212201515345980b9c882b79d269c45fcfe8e69bce35d66d1c0de8bfe8dba0fe333fc64736f6c63430008120033\n}\n", + "bytecode": { + "functionDebugData": { + "@_1068": { + "entryPoint": null, + "id": 1068, + "parameterSlots": 0, + "returnSlots": 0 + } + }, + "generatedSources": [], + "linkReferences": {}, + "object": "60a0604052348015600f57600080fd5b5030608052608051603f602960003960005050603f6000f3fe6080604052600080fdfea26469706673582212201515345980b9c882b79d269c45fcfe8e69bce35d66d1c0de8bfe8dba0fe333fc64736f6c63430008120033", + "opcodes": "PUSH1 0xA0 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH1 0xF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP ADDRESS PUSH1 0x80 MSTORE PUSH1 0x80 MLOAD PUSH1 0x3F PUSH1 0x29 PUSH1 0x0 CODECOPY PUSH1 0x0 POP POP PUSH1 0x3F PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 ISZERO ISZERO CALLVALUE MSIZE DUP1 0xB9 0xC8 DUP3 0xB7 SWAP14 0x26 SWAP13 GASLIMIT 0xFC INVALID DUP15 PUSH10 0xBCE35D66D1C0DE8BFE8D 0xBA 0xF 0xE3 CALLER 0xFC PUSH5 0x736F6C6343 STOP ADDMOD SLT STOP CALLER ", + "sourceMap": "65:355:7:-:0;;;165:45;;;;;;;;;-1:-1:-1;200:4:7;185:20;;65:355;;;;;;;;;;;" + }, + "deployedBytecode": { + "functionDebugData": {}, + "generatedSources": [], + "immutableReferences": {}, + "linkReferences": {}, + "object": "6080604052600080fdfea26469706673582212201515345980b9c882b79d269c45fcfe8e69bce35d66d1c0de8bfe8dba0fe333fc64736f6c63430008120033", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 ISZERO ISZERO CALLVALUE MSIZE DUP1 0xB9 0xC8 DUP3 0xB7 SWAP14 0x26 SWAP13 GASLIMIT 0xFC INVALID DUP15 PUSH10 0xBCE35D66D1C0DE8BFE8D 0xBA 0xF 0xE3 CALLER 0xFC PUSH5 0x736F6C6343 STOP ADDMOD SLT STOP CALLER ", + "sourceMap": "65:355:7:-:0;;;;;" + }, + "gasEstimates": { + "creation": { + "codeDepositCost": "12600", + "executionCost": "infinite", + "totalCost": "infinite" + } + }, + "legacyAssembly": { + ".code": [ + { + "begin": 65, + "end": 420, + "name": "PUSH", + "source": 7, + "value": "A0" + }, + { + "begin": 65, + "end": 420, + "name": "PUSH", + "source": 7, + "value": "40" + }, + { + "begin": 65, + "end": 420, + "name": "MSTORE", + "source": 7 + }, + { + "begin": 165, + "end": 210, + "name": "CALLVALUE", + "source": 7 + }, + { + "begin": 165, + "end": 210, + "name": "DUP1", + "source": 7 + }, + { + "begin": 165, + "end": 210, + "name": "ISZERO", + "source": 7 + }, + { + "begin": 165, + "end": 210, + "name": "PUSH [tag]", + "source": 7, + "value": "1" + }, + { + "begin": 165, + "end": 210, + "name": "JUMPI", + "source": 7 + }, + { + "begin": 165, + "end": 210, + "name": "PUSH", + "source": 7, + "value": "0" + }, + { + "begin": 165, + "end": 210, + "name": "DUP1", + "source": 7 + }, + { + "begin": 165, + "end": 210, + "name": "REVERT", + "source": 7 + }, + { + "begin": 165, + "end": 210, + "name": "tag", + "source": 7, + "value": "1" + }, + { + "begin": 165, + "end": 210, + "name": "JUMPDEST", + "source": 7 + }, + { + "begin": -1, + "end": -1, + "name": "POP", + "source": -1 + }, + { + "begin": 200, + "end": 204, + "name": "ADDRESS", + "source": 7 + }, + { + "begin": 185, + "end": 205, + "name": "PUSH", + "source": 7, + "value": "80" + }, + { + "begin": 185, + "end": 205, + "name": "MSTORE", + "source": 7 + }, + { + "begin": 65, + "end": 420, + "name": "PUSH", + "source": 7, + "value": "80" + }, + { + "begin": 65, + "end": 420, + "name": "MLOAD", + "source": 7 + }, + { + "begin": 65, + "end": 420, + "name": "PUSH #[$]", + "source": 7, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 65, + "end": 420, + "name": "PUSH [$]", + "source": 7, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 65, + "end": 420, + "name": "PUSH", + "source": 7, + "value": "0" + }, + { + "begin": 65, + "end": 420, + "name": "CODECOPY", + "source": 7 + }, + { + "begin": 65, + "end": 420, + "name": "PUSH", + "source": 7, + "value": "0" + }, + { + "begin": 65, + "end": 420, + "name": "ASSIGNIMMUTABLE", + "source": 7, + "value": "1055" + }, + { + "begin": 65, + "end": 420, + "name": "PUSH #[$]", + "source": 7, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 65, + "end": 420, + "name": "PUSH", + "source": 7, + "value": "0" + }, + { + "begin": 65, + "end": 420, + "name": "RETURN", + "source": 7 + } + ], + ".data": { + "0": { + ".auxdata": "a26469706673582212201515345980b9c882b79d269c45fcfe8e69bce35d66d1c0de8bfe8dba0fe333fc64736f6c63430008120033", + ".code": [ + { + "begin": 65, + "end": 420, + "name": "PUSH", + "source": 7, + "value": "80" + }, + { + "begin": 65, + "end": 420, + "name": "PUSH", + "source": 7, + "value": "40" + }, + { + "begin": 65, + "end": 420, + "name": "MSTORE", + "source": 7 + }, + { + "begin": 65, + "end": 420, + "name": "PUSH", + "source": 7, + "value": "0" + }, + { + "begin": 65, + "end": 420, + "name": "DUP1", + "source": 7 + }, + { + "begin": 65, + "end": 420, + "name": "REVERT", + "source": 7 + } + ] + } + }, + "sourceList": [ + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/interfaces/IERC1271Wallet.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleERC165.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleOnlyDelegatecall.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCalls.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCreator.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol", + "#utility.yul" + ] + }, + "methodIdentifiers": {} + }, + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"OnlyDelegatecall\",\"type\":\"error\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleOnlyDelegatecall.sol\":\"ModuleOnlyDelegatecall\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":500000},\"remappings\":[\":@0xsequence/contracts-library/=src/\",\":@0xsequence/erc-1155/=lib/0xsequence/erc-1155/src/\",\":@0xsequence/erc20-meta-token/=lib/0xsequence/erc20-meta-token/src/\",\":@openzeppelin/=lib/openzeppelin/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc721a-upgradeable/=lib/chiru-labs/erc721a-upgradeable/\",\":erc721a/=lib/chiru-labs/erc721a/\",\":forge-std/=lib/forge-std/src/\",\":murky/=lib/murky/src/\",\":solady/=lib/solady/src/\"]},\"sources\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleOnlyDelegatecall.sol\":{\"keccak256\":\"0x32bdb1d343eee2e32fd9d0f1d6dc0e265411d0821bd908881822f0f26f0887f8\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://1537c4f60a609751013bdc69eb1c6e6218982d91013115bc4e28cb84f816cd91\",\"dweb:/ipfs/QmSjkSTrrB4vuxECcm5cRG7YmraF53QWRgftxS827KcQLW\"]}},\"version\":1}", + "storageLayout": { + "storage": [], + "types": null + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + } + } + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol": { + "ModuleSelfAuth": { + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_sender", + "type": "address" + }, + { + "internalType": "address", + "name": "_self", + "type": "address" + } + ], + "name": "OnlySelfAuth", + "type": "error" + } + ], + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "evm": { + "assembly": " /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":65:281 contract ModuleSelfAuth {... */\n mstore(0x40, 0x80)\n callvalue\n dup1\n iszero\n tag_1\n jumpi\n 0x00\n dup1\n revert\ntag_1:\n pop\n dataSize(sub_0)\n dup1\n dataOffset(sub_0)\n 0x00\n codecopy\n 0x00\n return\nstop\n\nsub_0: assembly {\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":65:281 contract ModuleSelfAuth {... */\n mstore(0x40, 0x80)\n 0x00\n dup1\n revert\n\n auxdata: 0xa2646970667358221220396fc0aa947578a12e6d47ac958aa78118e45e6db5b5f8680d4fcb2019dc056664736f6c63430008120033\n}\n", + "bytecode": { + "functionDebugData": {}, + "generatedSources": [], + "linkReferences": {}, + "object": "6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea2646970667358221220396fc0aa947578a12e6d47ac958aa78118e45e6db5b5f8680d4fcb2019dc056664736f6c63430008120033", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE CALLVALUE DUP1 ISZERO PUSH1 0xF JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH1 0x3F DUP1 PUSH1 0x1D PUSH1 0x0 CODECOPY PUSH1 0x0 RETURN INVALID PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 CODECOPY PUSH16 0xC0AA947578A12E6D47AC958AA78118E4 0x5E PUSH14 0xB5B5F8680D4FCB2019DC05666473 PUSH16 0x6C634300081200330000000000000000 ", + "sourceMap": "65:216:8:-:0;;;;;;;;;;;;;;;;;;;" + }, + "deployedBytecode": { + "functionDebugData": {}, + "generatedSources": [], + "immutableReferences": {}, + "linkReferences": {}, + "object": "6080604052600080fdfea2646970667358221220396fc0aa947578a12e6d47ac958aa78118e45e6db5b5f8680d4fcb2019dc056664736f6c63430008120033", + "opcodes": "PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 CODECOPY PUSH16 0xC0AA947578A12E6D47AC958AA78118E4 0x5E PUSH14 0xB5B5F8680D4FCB2019DC05666473 PUSH16 0x6C634300081200330000000000000000 ", + "sourceMap": "65:216:8:-:0;;;;;" + }, + "gasEstimates": { + "creation": { + "codeDepositCost": "12600", + "executionCost": "66", + "totalCost": "12666" + } + }, + "legacyAssembly": { + ".code": [ + { + "begin": 65, + "end": 281, + "name": "PUSH", + "source": 8, + "value": "80" + }, + { + "begin": 65, + "end": 281, + "name": "PUSH", + "source": 8, + "value": "40" + }, + { + "begin": 65, + "end": 281, + "name": "MSTORE", + "source": 8 + }, + { + "begin": 65, + "end": 281, + "name": "CALLVALUE", + "source": 8 + }, + { + "begin": 65, + "end": 281, + "name": "DUP1", + "source": 8 + }, + { + "begin": 65, + "end": 281, + "name": "ISZERO", + "source": 8 + }, + { + "begin": 65, + "end": 281, + "name": "PUSH [tag]", + "source": 8, + "value": "1" + }, + { + "begin": 65, + "end": 281, + "name": "JUMPI", + "source": 8 + }, + { + "begin": 65, + "end": 281, + "name": "PUSH", + "source": 8, + "value": "0" + }, + { + "begin": 65, + "end": 281, + "name": "DUP1", + "source": 8 + }, + { + "begin": 65, + "end": 281, + "name": "REVERT", + "source": 8 + }, + { + "begin": 65, + "end": 281, + "name": "tag", + "source": 8, + "value": "1" + }, + { + "begin": 65, + "end": 281, + "name": "JUMPDEST", + "source": 8 + }, + { + "begin": 65, + "end": 281, + "name": "POP", + "source": 8 + }, + { + "begin": 65, + "end": 281, + "name": "PUSH #[$]", + "source": 8, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 65, + "end": 281, + "name": "DUP1", + "source": 8 + }, + { + "begin": 65, + "end": 281, + "name": "PUSH [$]", + "source": 8, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 65, + "end": 281, + "name": "PUSH", + "source": 8, + "value": "0" + }, + { + "begin": 65, + "end": 281, + "name": "CODECOPY", + "source": 8 + }, + { + "begin": 65, + "end": 281, + "name": "PUSH", + "source": 8, + "value": "0" + }, + { + "begin": 65, + "end": 281, + "name": "RETURN", + "source": 8 + } + ], + ".data": { + "0": { + ".auxdata": "a2646970667358221220396fc0aa947578a12e6d47ac958aa78118e45e6db5b5f8680d4fcb2019dc056664736f6c63430008120033", + ".code": [ + { + "begin": 65, + "end": 281, + "name": "PUSH", + "source": 8, + "value": "80" + }, + { + "begin": 65, + "end": 281, + "name": "PUSH", + "source": 8, + "value": "40" + }, + { + "begin": 65, + "end": 281, + "name": "MSTORE", + "source": 8 + }, + { + "begin": 65, + "end": 281, + "name": "PUSH", + "source": 8, + "value": "0" + }, + { + "begin": 65, + "end": 281, + "name": "DUP1", + "source": 8 + }, + { + "begin": 65, + "end": 281, + "name": "REVERT", + "source": 8 + } + ] + } + }, + "sourceList": [ + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/interfaces/IERC1271Wallet.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleERC165.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleOnlyDelegatecall.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCalls.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCreator.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol", + "#utility.yul" + ] + }, + "methodIdentifiers": {} + }, + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_self\",\"type\":\"address\"}],\"name\":\"OnlySelfAuth\",\"type\":\"error\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":\"ModuleSelfAuth\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":500000},\"remappings\":[\":@0xsequence/contracts-library/=src/\",\":@0xsequence/erc-1155/=lib/0xsequence/erc-1155/src/\",\":@0xsequence/erc20-meta-token/=lib/0xsequence/erc20-meta-token/src/\",\":@openzeppelin/=lib/openzeppelin/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc721a-upgradeable/=lib/chiru-labs/erc721a-upgradeable/\",\":erc721a/=lib/chiru-labs/erc721a/\",\":forge-std/=lib/forge-std/src/\",\":murky/=lib/murky/src/\",\":solady/=lib/solady/src/\"]},\"sources\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":{\"keccak256\":\"0x91545de5c77cfac86c5686c4e1f338a18ee7adb689ac0234848d7a7fc8a560db\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://dc89d05d8099ba4c3c2cf85737796d439899b5a04e6b87b1ea43f687ae08848a\",\"dweb:/ipfs/QmatU8gRvFkK3Yn1MYAekzi48Waw3cDLtXJpduvju9HFUu\"]}},\"version\":1}", + "storageLayout": { + "storage": [], + "types": null + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + } + } + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol": { + "ModuleStorage": { + "abi": [], + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "evm": { + "assembly": " /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol\":65:679 library ModuleStorage {... */\n dataSize(sub_0)\n dataOffset(sub_0)\n 0x0b\n dup3\n dup3\n dup3\n codecopy\n dup1\n mload\n 0x00\n byte\n 0x73\n eq\n tag_1\n jumpi\n mstore(0x00, shl(0xe0, 0x4e487b71))\n mstore(0x04, 0x00)\n revert(0x00, 0x24)\ntag_1:\n mstore(0x00, address)\n 0x73\n dup2\n mstore8\n dup3\n dup2\n return\nstop\n\nsub_0: assembly {\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol\":65:679 library ModuleStorage {... */\n eq(address, deployTimeAddress())\n mstore(0x40, 0x80)\n 0x00\n dup1\n revert\n\n auxdata: 0xa264697066735822122055b5e58f321540dc1eb3c539fbeff9918a32f6db2cb889e0c660fd49a99fd80d64736f6c63430008120033\n}\n", + "bytecode": { + "functionDebugData": {}, + "generatedSources": [], + "linkReferences": {}, + "object": "60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122055b5e58f321540dc1eb3c539fbeff9918a32f6db2cb889e0c660fd49a99fd80d64736f6c63430008120033", + "opcodes": "PUSH1 0x56 PUSH1 0x37 PUSH1 0xB DUP3 DUP3 DUP3 CODECOPY DUP1 MLOAD PUSH1 0x0 BYTE PUSH1 0x73 EQ PUSH1 0x2A JUMPI PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x0 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST ADDRESS PUSH1 0x0 MSTORE PUSH1 0x73 DUP2 MSTORE8 DUP3 DUP2 RETURN INVALID PUSH20 0x0 ADDRESS EQ PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 SSTORE 0xB5 0xE5 DUP16 ORIGIN ISZERO BLOCKHASH 0xDC 0x1E 0xB3 0xC5 CODECOPY 0xFB 0xEF 0xF9 SWAP2 DUP11 ORIGIN 0xF6 0xDB 0x2C 0xB8 DUP10 0xE0 0xC6 PUSH1 0xFD 0x49 0xA9 SWAP16 0xD8 0xD PUSH5 0x736F6C6343 STOP ADDMOD SLT STOP CALLER ", + "sourceMap": "65:614:9:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;65:614:9;;;;;;;;;;;;;;;;;" + }, + "deployedBytecode": { + "functionDebugData": {}, + "generatedSources": [], + "immutableReferences": {}, + "linkReferences": {}, + "object": "73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122055b5e58f321540dc1eb3c539fbeff9918a32f6db2cb889e0c660fd49a99fd80d64736f6c63430008120033", + "opcodes": "PUSH20 0x0 ADDRESS EQ PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 SSTORE 0xB5 0xE5 DUP16 ORIGIN ISZERO BLOCKHASH 0xDC 0x1E 0xB3 0xC5 CODECOPY 0xFB 0xEF 0xF9 SWAP2 DUP11 ORIGIN 0xF6 0xDB 0x2C 0xB8 DUP10 0xE0 0xC6 PUSH1 0xFD 0x49 0xA9 SWAP16 0xD8 0xD PUSH5 0x736F6C6343 STOP ADDMOD SLT STOP CALLER ", + "sourceMap": "65:614:9:-:0;;;;;;;;" + }, + "gasEstimates": { + "creation": { + "codeDepositCost": "17200", + "executionCost": "103", + "totalCost": "17303" + }, + "internal": { + "readBytes32(bytes32)": "infinite", + "readBytes32Map(bytes32,bytes32)": "infinite", + "writeBytes32(bytes32,bytes32)": "infinite", + "writeBytes32Map(bytes32,bytes32,bytes32)": "infinite" + } + }, + "legacyAssembly": { + ".code": [ + { + "begin": 65, + "end": 679, + "name": "PUSH #[$]", + "source": 9, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 65, + "end": 679, + "name": "PUSH [$]", + "source": 9, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 65, + "end": 679, + "name": "PUSH", + "source": 9, + "value": "B" + }, + { + "begin": 65, + "end": 679, + "name": "DUP3", + "source": 9 + }, + { + "begin": 65, + "end": 679, + "name": "DUP3", + "source": 9 + }, + { + "begin": 65, + "end": 679, + "name": "DUP3", + "source": 9 + }, + { + "begin": 65, + "end": 679, + "name": "CODECOPY", + "source": 9 + }, + { + "begin": 65, + "end": 679, + "name": "DUP1", + "source": 9 + }, + { + "begin": 65, + "end": 679, + "name": "MLOAD", + "source": 9 + }, + { + "begin": 65, + "end": 679, + "name": "PUSH", + "source": 9, + "value": "0" + }, + { + "begin": 65, + "end": 679, + "name": "BYTE", + "source": 9 + }, + { + "begin": 65, + "end": 679, + "name": "PUSH", + "source": 9, + "value": "73" + }, + { + "begin": 65, + "end": 679, + "name": "EQ", + "source": 9 + }, + { + "begin": 65, + "end": 679, + "name": "PUSH [tag]", + "source": 9, + "value": "1" + }, + { + "begin": 65, + "end": 679, + "name": "JUMPI", + "source": 9 + }, + { + "begin": -1, + "end": -1, + "name": "PUSH", + "source": -1, + "value": "4E487B71" + }, + { + "begin": -1, + "end": -1, + "name": "PUSH", + "source": -1, + "value": "E0" + }, + { + "begin": -1, + "end": -1, + "name": "SHL", + "source": -1 + }, + { + "begin": 65, + "end": 679, + "name": "PUSH", + "source": 9, + "value": "0" + }, + { + "begin": 65, + "end": 679, + "name": "MSTORE", + "source": 9 + }, + { + "begin": 65, + "end": 679, + "name": "PUSH", + "source": 9, + "value": "0" + }, + { + "begin": 65, + "end": 679, + "name": "PUSH", + "source": 9, + "value": "4" + }, + { + "begin": 65, + "end": 679, + "name": "MSTORE", + "source": 9 + }, + { + "begin": 65, + "end": 679, + "name": "PUSH", + "source": 9, + "value": "24" + }, + { + "begin": 65, + "end": 679, + "name": "PUSH", + "source": 9, + "value": "0" + }, + { + "begin": 65, + "end": 679, + "name": "REVERT", + "source": 9 + }, + { + "begin": 65, + "end": 679, + "name": "tag", + "source": 9, + "value": "1" + }, + { + "begin": 65, + "end": 679, + "name": "JUMPDEST", + "source": 9 + }, + { + "begin": 65, + "end": 679, + "name": "ADDRESS", + "source": 9 + }, + { + "begin": 65, + "end": 679, + "name": "PUSH", + "source": 9, + "value": "0" + }, + { + "begin": 65, + "end": 679, + "name": "MSTORE", + "source": 9 + }, + { + "begin": 65, + "end": 679, + "name": "PUSH", + "source": 9, + "value": "73" + }, + { + "begin": 65, + "end": 679, + "name": "DUP2", + "source": 9 + }, + { + "begin": 65, + "end": 679, + "name": "MSTORE8", + "source": 9 + }, + { + "begin": 65, + "end": 679, + "name": "DUP3", + "source": 9 + }, + { + "begin": 65, + "end": 679, + "name": "DUP2", + "source": 9 + }, + { + "begin": 65, + "end": 679, + "name": "RETURN", + "source": 9 + } + ], + ".data": { + "0": { + ".auxdata": "a264697066735822122055b5e58f321540dc1eb3c539fbeff9918a32f6db2cb889e0c660fd49a99fd80d64736f6c63430008120033", + ".code": [ + { + "begin": 65, + "end": 679, + "name": "PUSHDEPLOYADDRESS", + "source": 9 + }, + { + "begin": 65, + "end": 679, + "name": "ADDRESS", + "source": 9 + }, + { + "begin": 65, + "end": 679, + "name": "EQ", + "source": 9 + }, + { + "begin": 65, + "end": 679, + "name": "PUSH", + "source": 9, + "value": "80" + }, + { + "begin": 65, + "end": 679, + "name": "PUSH", + "source": 9, + "value": "40" + }, + { + "begin": 65, + "end": 679, + "name": "MSTORE", + "source": 9 + }, + { + "begin": 65, + "end": 679, + "name": "PUSH", + "source": 9, + "value": "0" + }, + { + "begin": 65, + "end": 679, + "name": "DUP1", + "source": 9 + }, + { + "begin": 65, + "end": 679, + "name": "REVERT", + "source": 9 + } + ] + } + }, + "sourceList": [ + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/interfaces/IERC1271Wallet.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleERC165.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleOnlyDelegatecall.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCalls.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCreator.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol", + "#utility.yul" + ] + }, + "methodIdentifiers": {} + }, + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol\":\"ModuleStorage\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":500000},\"remappings\":[\":@0xsequence/contracts-library/=src/\",\":@0xsequence/erc-1155/=lib/0xsequence/erc-1155/src/\",\":@0xsequence/erc20-meta-token/=lib/0xsequence/erc20-meta-token/src/\",\":@openzeppelin/=lib/openzeppelin/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc721a-upgradeable/=lib/chiru-labs/erc721a-upgradeable/\",\":erc721a/=lib/chiru-labs/erc721a/\",\":forge-std/=lib/forge-std/src/\",\":murky/=lib/murky/src/\",\":solady/=lib/solady/src/\"]},\"sources\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol\":{\"keccak256\":\"0x876c6a40cba975df4f7dfe24e02d153b2ee758975b6d1eda494ecd4b7244aa8e\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://b9be3f7930476d528ce10a121701421f0fb251b7d6b7cd579917375e6b283bb4\",\"dweb:/ipfs/QmSbvbYQvTk8KYJZ7QqSKB9Y4M1X3UDhS6k765Zr1BAwK8\"]}},\"version\":1}", + "storageLayout": { + "storage": [], + "types": null + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + } + } + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleAuth.sol": { + "IModuleAuth": { + "abi": [ + { + "inputs": [], + "name": "ImageHashIsZero", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes1", + "name": "_type", + "type": "bytes1" + } + ], + "name": "InvalidSignatureType", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "newImageHash", + "type": "bytes32" + } + ], + "name": "ImageHashUpdated", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_digest", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "signatureRecovery", + "outputs": [ + { + "internalType": "uint256", + "name": "threshold", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "weight", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "imageHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "subdigest", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "checkpoint", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_imageHash", + "type": "bytes32" + } + ], + "name": "updateImageHash", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "devdoc": { + "kind": "dev", + "methods": { + "updateImageHash(bytes32)": { + "params": { + "_imageHash": "New required image hash of the signature" + } + } + }, + "version": 1 + }, + "evm": { + "assembly": "", + "bytecode": { + "functionDebugData": {}, + "generatedSources": [], + "linkReferences": {}, + "object": "", + "opcodes": "", + "sourceMap": "" + }, + "deployedBytecode": { + "functionDebugData": {}, + "generatedSources": [], + "immutableReferences": {}, + "linkReferences": {}, + "object": "", + "opcodes": "", + "sourceMap": "" + }, + "gasEstimates": null, + "legacyAssembly": null, + "methodIdentifiers": { + "signatureRecovery(bytes32,bytes)": "853c5068", + "updateImageHash(bytes32)": "29561426" + } + }, + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"ImageHashIsZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes1\",\"name\":\"_type\",\"type\":\"bytes1\"}],\"name\":\"InvalidSignatureType\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"newImageHash\",\"type\":\"bytes32\"}],\"name\":\"ImageHashUpdated\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_digest\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"signatureRecovery\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"imageHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"subdigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"checkpoint\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_imageHash\",\"type\":\"bytes32\"}],\"name\":\"updateImageHash\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"updateImageHash(bytes32)\":{\"params\":{\"_imageHash\":\"New required image hash of the signature\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"updateImageHash(bytes32)\":{\"notice\":\"Updates the signers configuration of the wallet\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleAuth.sol\":\"IModuleAuth\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":500000},\"remappings\":[\":@0xsequence/contracts-library/=src/\",\":@0xsequence/erc-1155/=lib/0xsequence/erc-1155/src/\",\":@0xsequence/erc20-meta-token/=lib/0xsequence/erc20-meta-token/src/\",\":@openzeppelin/=lib/openzeppelin/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc721a-upgradeable/=lib/chiru-labs/erc721a-upgradeable/\",\":erc721a/=lib/chiru-labs/erc721a/\",\":forge-std/=lib/forge-std/src/\",\":murky/=lib/murky/src/\",\":solady/=lib/solady/src/\"]},\"sources\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleAuth.sol\":{\"keccak256\":\"0x24c6b05c32cb344b3b0aebd01fbd8bfc69f8c8e29fca340b262d9612c34d51e2\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://5f6c004946f0cbc4b3e52d45248337146bc82569da894ecff3cbdc5a0dca95c3\",\"dweb:/ipfs/QmNSgDMQ7SHL6AJuzTSRbY2kgciHF1SKWfH6MaPH1N3TpR\"]}},\"version\":1}", + "storageLayout": { + "storage": [], + "types": null + }, + "userdoc": { + "kind": "user", + "methods": { + "updateImageHash(bytes32)": { + "notice": "Updates the signers configuration of the wallet" + } + }, + "version": 1 + } + } + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCalls.sol": { + "IModuleCalls": { + "abi": [ + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "InvalidSignature", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_index", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_requested", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_available", + "type": "uint256" + } + ], + "name": "NotEnoughGas", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "_tx", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_index", + "type": "uint256" + } + ], + "name": "TxExecuted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "_tx", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_index", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_reason", + "type": "bytes" + } + ], + "name": "TxFailed", + "type": "event" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bool", + "name": "delegateCall", + "type": "bool" + }, + { + "internalType": "bool", + "name": "revertOnError", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + }, + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "internalType": "struct IModuleCalls.Transaction[]", + "name": "_txs", + "type": "tuple[]" + }, + { + "internalType": "uint256", + "name": "_nonce", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "execute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bool", + "name": "delegateCall", + "type": "bool" + }, + { + "internalType": "bool", + "name": "revertOnError", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "gasLimit", + "type": "uint256" + }, + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "internalType": "struct IModuleCalls.Transaction[]", + "name": "_txs", + "type": "tuple[]" + } + ], + "name": "selfExecute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "devdoc": { + "kind": "dev", + "methods": { + "execute((bool,bool,uint256,address,uint256,bytes)[],uint256,bytes)": { + "params": { + "_nonce": "Signature nonce (may contain an encoded space)", + "_signature": "Encoded signature", + "_txs": "Transactions to process" + } + }, + "selfExecute((bool,bool,uint256,address,uint256,bytes)[])": { + "params": { + "_txs": "Transactions to execute" + } + } + }, + "version": 1 + }, + "evm": { + "assembly": "", + "bytecode": { + "functionDebugData": {}, + "generatedSources": [], + "linkReferences": {}, + "object": "", + "opcodes": "", + "sourceMap": "" + }, + "deployedBytecode": { + "functionDebugData": {}, + "generatedSources": [], + "immutableReferences": {}, + "linkReferences": {}, + "object": "", + "opcodes": "", + "sourceMap": "" + }, + "gasEstimates": null, + "legacyAssembly": null, + "methodIdentifiers": { + "execute((bool,bool,uint256,address,uint256,bytes)[],uint256,bytes)": "7a9a1628", + "selfExecute((bool,bool,uint256,address,uint256,bytes)[])": "61c2926c" + } + }, + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_hash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_requested\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_available\",\"type\":\"uint256\"}],\"name\":\"NotEnoughGas\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_tx\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"}],\"name\":\"TxExecuted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"_tx\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_index\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_reason\",\"type\":\"bytes\"}],\"name\":\"TxFailed\",\"type\":\"event\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"delegateCall\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"revertOnError\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"struct IModuleCalls.Transaction[]\",\"name\":\"_txs\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"_nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"delegateCall\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"revertOnError\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"struct IModuleCalls.Transaction[]\",\"name\":\"_txs\",\"type\":\"tuple[]\"}],\"name\":\"selfExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"execute((bool,bool,uint256,address,uint256,bytes)[],uint256,bytes)\":{\"params\":{\"_nonce\":\"Signature nonce (may contain an encoded space)\",\"_signature\":\"Encoded signature\",\"_txs\":\"Transactions to process\"}},\"selfExecute((bool,bool,uint256,address,uint256,bytes)[])\":{\"params\":{\"_txs\":\"Transactions to execute\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"execute((bool,bool,uint256,address,uint256,bytes)[],uint256,bytes)\":{\"notice\":\"Allow wallet owner to execute an action\"},\"selfExecute((bool,bool,uint256,address,uint256,bytes)[])\":{\"notice\":\"Allow wallet to execute an action without signing the message\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCalls.sol\":\"IModuleCalls\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":500000},\"remappings\":[\":@0xsequence/contracts-library/=src/\",\":@0xsequence/erc-1155/=lib/0xsequence/erc-1155/src/\",\":@0xsequence/erc20-meta-token/=lib/0xsequence/erc20-meta-token/src/\",\":@openzeppelin/=lib/openzeppelin/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc721a-upgradeable/=lib/chiru-labs/erc721a-upgradeable/\",\":erc721a/=lib/chiru-labs/erc721a/\",\":forge-std/=lib/forge-std/src/\",\":murky/=lib/murky/src/\",\":solady/=lib/solady/src/\"]},\"sources\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCalls.sol\":{\"keccak256\":\"0xde065c15e38eb009c3dc8f99dfefdd1d6d244dd12a889a8b57edd90d32fb4395\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://23608955786060457f79267795a61eb89b3910b683fc136c749548369425088f\",\"dweb:/ipfs/QmXNorcQBF1Qk21y3aEJRiiHVtwm61zP4ttA1ZzmRjyHnz\"]}},\"version\":1}", + "storageLayout": { + "storage": [], + "types": null + }, + "userdoc": { + "kind": "user", + "methods": { + "execute((bool,bool,uint256,address,uint256,bytes)[],uint256,bytes)": { + "notice": "Allow wallet owner to execute an action" + }, + "selfExecute((bool,bool,uint256,address,uint256,bytes)[])": { + "notice": "Allow wallet to execute an action without signing the message" + } + }, + "version": 1 + } + } + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCreator.sol": { + "IModuleCreator": { + "abi": [ + { + "inputs": [ + { + "internalType": "bytes", + "name": "_code", + "type": "bytes" + } + ], + "name": "CreateFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_code", + "type": "bytes" + } + ], + "name": "createContract", + "outputs": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + } + ], + "stateMutability": "payable", + "type": "function" + } + ], + "devdoc": { + "kind": "dev", + "methods": { + "createContract(bytes)": { + "params": { + "_code": "Creation code of the contract" + }, + "returns": { + "addr": "The address of the created contract" + } + } + }, + "version": 1 + }, + "evm": { + "assembly": "", + "bytecode": { + "functionDebugData": {}, + "generatedSources": [], + "linkReferences": {}, + "object": "", + "opcodes": "", + "sourceMap": "" + }, + "deployedBytecode": { + "functionDebugData": {}, + "generatedSources": [], + "immutableReferences": {}, + "linkReferences": {}, + "object": "", + "opcodes": "", + "sourceMap": "" + }, + "gasEstimates": null, + "legacyAssembly": null, + "methodIdentifiers": { + "createContract(bytes)": "90042baf" + } + }, + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_code\",\"type\":\"bytes\"}],\"name\":\"CreateFailed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_code\",\"type\":\"bytes\"}],\"name\":\"createContract\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"createContract(bytes)\":{\"params\":{\"_code\":\"Creation code of the contract\"},\"returns\":{\"addr\":\"The address of the created contract\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"createContract(bytes)\":{\"notice\":\"Creates a contract forwarding eth value\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCreator.sol\":\"IModuleCreator\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":500000},\"remappings\":[\":@0xsequence/contracts-library/=src/\",\":@0xsequence/erc-1155/=lib/0xsequence/erc-1155/src/\",\":@0xsequence/erc20-meta-token/=lib/0xsequence/erc20-meta-token/src/\",\":@openzeppelin/=lib/openzeppelin/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc721a-upgradeable/=lib/chiru-labs/erc721a-upgradeable/\",\":erc721a/=lib/chiru-labs/erc721a/\",\":forge-std/=lib/forge-std/src/\",\":murky/=lib/murky/src/\",\":solady/=lib/solady/src/\"]},\"sources\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCreator.sol\":{\"keccak256\":\"0xa206dd3d424b8cd1c4f1400aa344cbc974480fea02f0fb371b872558e5ff4e6d\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://ea14c75f43a0008c582dcbae3ba3c900e446e28039dfdbb059d326ec5cc6a2d2\",\"dweb:/ipfs/QmRfF6BmUWiFkCgzVFbLcHsUCNz5q2XkkcwXPX57ViTK4D\"]}},\"version\":1}", + "storageLayout": { + "storage": [], + "types": null + }, + "userdoc": { + "kind": "user", + "methods": { + "createContract(bytes)": { + "notice": "Creates a contract forwarding eth value" + } + }, + "version": 1 + } + } + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol": { + "SequenceBaseSig": { + "abi": [ + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "_addr", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "InvalidNestedSignature", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_flag", + "type": "uint256" + } + ], + "name": "InvalidSignatureFlag", + "type": "error" + } + ], + "devdoc": { + "author": "Agustin Aguilar (aa@horizon.io)", + "kind": "dev", + "methods": {}, + "title": "SequenceBaseSig Library", + "version": 1 + }, + "evm": { + "assembly": " /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":419:9536 library SequenceBaseSig {... */\n dataSize(sub_0)\n dataOffset(sub_0)\n 0x0b\n dup3\n dup3\n dup3\n codecopy\n dup1\n mload\n 0x00\n byte\n 0x73\n eq\n tag_1\n jumpi\n mstore(0x00, shl(0xe0, 0x4e487b71))\n mstore(0x04, 0x00)\n revert(0x00, 0x24)\ntag_1:\n mstore(0x00, address)\n 0x73\n dup2\n mstore8\n dup3\n dup2\n return\nstop\n\nsub_0: assembly {\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":419:9536 library SequenceBaseSig {... */\n eq(address, deployTimeAddress())\n mstore(0x40, 0x80)\n 0x00\n dup1\n revert\n\n auxdata: 0xa26469706673582212208df7fadefb88448ef7f4d3ade6c9b119a5809f9dda955b39d53d545dfcdfed0a64736f6c63430008120033\n}\n", + "bytecode": { + "functionDebugData": {}, + "generatedSources": [], + "linkReferences": {}, + "object": "60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212208df7fadefb88448ef7f4d3ade6c9b119a5809f9dda955b39d53d545dfcdfed0a64736f6c63430008120033", + "opcodes": "PUSH1 0x56 PUSH1 0x37 PUSH1 0xB DUP3 DUP3 DUP3 CODECOPY DUP1 MLOAD PUSH1 0x0 BYTE PUSH1 0x73 EQ PUSH1 0x2A JUMPI PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x0 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST ADDRESS PUSH1 0x0 MSTORE PUSH1 0x73 DUP2 MSTORE8 DUP3 DUP2 RETURN INVALID PUSH20 0x0 ADDRESS EQ PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 DUP14 0xF7 STATICCALL 0xDE 0xFB DUP9 PREVRANDAO DUP15 0xF7 DELEGATECALL 0xD3 0xAD 0xE6 0xC9 0xB1 NOT 0xA5 DUP1 SWAP16 SWAP14 0xDA SWAP6 JUMPDEST CODECOPY 0xD5 RETURNDATASIZE SLOAD 0x5D 0xFC 0xDF 0xED EXP PUSH5 0x736F6C6343 STOP ADDMOD SLT STOP CALLER ", + "sourceMap": "419:9117:13:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;419:9117:13;;;;;;;;;;;;;;;;;" + }, + "deployedBytecode": { + "functionDebugData": {}, + "generatedSources": [], + "immutableReferences": {}, + "linkReferences": {}, + "object": "73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212208df7fadefb88448ef7f4d3ade6c9b119a5809f9dda955b39d53d545dfcdfed0a64736f6c63430008120033", + "opcodes": "PUSH20 0x0 ADDRESS EQ PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 DUP14 0xF7 STATICCALL 0xDE 0xFB DUP9 PREVRANDAO DUP15 0xF7 DELEGATECALL 0xD3 0xAD 0xE6 0xC9 0xB1 NOT 0xA5 DUP1 SWAP16 SWAP14 0xDA SWAP6 JUMPDEST CODECOPY 0xD5 RETURNDATASIZE SLOAD 0x5D 0xFC 0xDF 0xED EXP PUSH5 0x736F6C6343 STOP ADDMOD SLT STOP CALLER ", + "sourceMap": "419:9117:13:-:0;;;;;;;;" + }, + "gasEstimates": { + "creation": { + "codeDepositCost": "17200", + "executionCost": "103", + "totalCost": "17303" + }, + "internal": { + "_leafForAddressAndWeight(address,uint96)": "infinite", + "_leafForHardcodedSubdigest(bytes32)": "infinite", + "_leafForNested(bytes32,uint256,uint256)": "infinite", + "recover(bytes32,bytes calldata)": "infinite", + "recoverBranch(bytes32,bytes calldata)": "infinite", + "subdigest(bytes32)": "infinite" + } + }, + "legacyAssembly": { + ".code": [ + { + "begin": 419, + "end": 9536, + "name": "PUSH #[$]", + "source": 13, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 419, + "end": 9536, + "name": "PUSH [$]", + "source": 13, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 419, + "end": 9536, + "name": "PUSH", + "source": 13, + "value": "B" + }, + { + "begin": 419, + "end": 9536, + "name": "DUP3", + "source": 13 + }, + { + "begin": 419, + "end": 9536, + "name": "DUP3", + "source": 13 + }, + { + "begin": 419, + "end": 9536, + "name": "DUP3", + "source": 13 + }, + { + "begin": 419, + "end": 9536, + "name": "CODECOPY", + "source": 13 + }, + { + "begin": 419, + "end": 9536, + "name": "DUP1", + "source": 13 + }, + { + "begin": 419, + "end": 9536, + "name": "MLOAD", + "source": 13 + }, + { + "begin": 419, + "end": 9536, + "name": "PUSH", + "source": 13, + "value": "0" + }, + { + "begin": 419, + "end": 9536, + "name": "BYTE", + "source": 13 + }, + { + "begin": 419, + "end": 9536, + "name": "PUSH", + "source": 13, + "value": "73" + }, + { + "begin": 419, + "end": 9536, + "name": "EQ", + "source": 13 + }, + { + "begin": 419, + "end": 9536, + "name": "PUSH [tag]", + "source": 13, + "value": "1" + }, + { + "begin": 419, + "end": 9536, + "name": "JUMPI", + "source": 13 + }, + { + "begin": -1, + "end": -1, + "name": "PUSH", + "source": -1, + "value": "4E487B71" + }, + { + "begin": -1, + "end": -1, + "name": "PUSH", + "source": -1, + "value": "E0" + }, + { + "begin": -1, + "end": -1, + "name": "SHL", + "source": -1 + }, + { + "begin": 419, + "end": 9536, + "name": "PUSH", + "source": 13, + "value": "0" + }, + { + "begin": 419, + "end": 9536, + "name": "MSTORE", + "source": 13 + }, + { + "begin": 419, + "end": 9536, + "name": "PUSH", + "source": 13, + "value": "0" + }, + { + "begin": 419, + "end": 9536, + "name": "PUSH", + "source": 13, + "value": "4" + }, + { + "begin": 419, + "end": 9536, + "name": "MSTORE", + "source": 13 + }, + { + "begin": 419, + "end": 9536, + "name": "PUSH", + "source": 13, + "value": "24" + }, + { + "begin": 419, + "end": 9536, + "name": "PUSH", + "source": 13, + "value": "0" + }, + { + "begin": 419, + "end": 9536, + "name": "REVERT", + "source": 13 + }, + { + "begin": 419, + "end": 9536, + "name": "tag", + "source": 13, + "value": "1" + }, + { + "begin": 419, + "end": 9536, + "name": "JUMPDEST", + "source": 13 + }, + { + "begin": 419, + "end": 9536, + "name": "ADDRESS", + "source": 13 + }, + { + "begin": 419, + "end": 9536, + "name": "PUSH", + "source": 13, + "value": "0" + }, + { + "begin": 419, + "end": 9536, + "name": "MSTORE", + "source": 13 + }, + { + "begin": 419, + "end": 9536, + "name": "PUSH", + "source": 13, + "value": "73" + }, + { + "begin": 419, + "end": 9536, + "name": "DUP2", + "source": 13 + }, + { + "begin": 419, + "end": 9536, + "name": "MSTORE8", + "source": 13 + }, + { + "begin": 419, + "end": 9536, + "name": "DUP3", + "source": 13 + }, + { + "begin": 419, + "end": 9536, + "name": "DUP2", + "source": 13 + }, + { + "begin": 419, + "end": 9536, + "name": "RETURN", + "source": 13 + } + ], + ".data": { + "0": { + ".auxdata": "a26469706673582212208df7fadefb88448ef7f4d3ade6c9b119a5809f9dda955b39d53d545dfcdfed0a64736f6c63430008120033", + ".code": [ + { + "begin": 419, + "end": 9536, + "name": "PUSHDEPLOYADDRESS", + "source": 13 + }, + { + "begin": 419, + "end": 9536, + "name": "ADDRESS", + "source": 13 + }, + { + "begin": 419, + "end": 9536, + "name": "EQ", + "source": 13 + }, + { + "begin": 419, + "end": 9536, + "name": "PUSH", + "source": 13, + "value": "80" + }, + { + "begin": 419, + "end": 9536, + "name": "PUSH", + "source": 13, + "value": "40" + }, + { + "begin": 419, + "end": 9536, + "name": "MSTORE", + "source": 13 + }, + { + "begin": 419, + "end": 9536, + "name": "PUSH", + "source": 13, + "value": "0" + }, + { + "begin": 419, + "end": 9536, + "name": "DUP1", + "source": 13 + }, + { + "begin": 419, + "end": 9536, + "name": "REVERT", + "source": 13 + } + ] + } + }, + "sourceList": [ + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/interfaces/IERC1271Wallet.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleERC165.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleOnlyDelegatecall.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCalls.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCreator.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol", + "#utility.yul" + ] + }, + "methodIdentifiers": {} + }, + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_hash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"InvalidNestedSignature\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_flag\",\"type\":\"uint256\"}],\"name\":\"InvalidSignatureFlag\",\"type\":\"error\"}],\"devdoc\":{\"author\":\"Agustin Aguilar (aa@horizon.io)\",\"kind\":\"dev\",\"methods\":{},\"title\":\"SequenceBaseSig Library\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"A Solidity implementation for handling signatures in the Sequence protocol.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":\"SequenceBaseSig\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":500000},\"remappings\":[\":@0xsequence/contracts-library/=src/\",\":@0xsequence/erc-1155/=lib/0xsequence/erc-1155/src/\",\":@0xsequence/erc20-meta-token/=lib/0xsequence/erc20-meta-token/src/\",\":@openzeppelin/=lib/openzeppelin/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc721a-upgradeable/=lib/chiru-labs/erc721a-upgradeable/\",\":erc721a/=lib/chiru-labs/erc721a/\",\":forge-std/=lib/forge-std/src/\",\":murky/=lib/murky/src/\",\":solady/=lib/solady/src/\"]},\"sources\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/interfaces/IERC1271Wallet.sol\":{\"keccak256\":\"0x2d7881bca678833feb385fd59e5d8ad6d596160ab51daa7030372654b3dbc38c\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://010f44c05b7285a55de939f9989727d53dfb87fd2d2534a832a70e0e081bb5f1\",\"dweb:/ipfs/QmQcujWErxjktsKyyiTySaFuR7Vaq6fUA9SUzPkde2txVK\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":{\"keccak256\":\"0xe0565e24e94204d4b254ace42d124d3279256090921a4818cbbf9747cbb14e04\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://4293a4762b0816738511f697efd04a0e881d4c409bd15ac1c4e7261fe5e482a2\",\"dweb:/ipfs/QmcHbEBne4fvpcD7RTJHCL6q9czoLa7KHneaCeYfXuWiGu\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol\":{\"keccak256\":\"0xd780faf34527a323c96577c57370d175a2b6149db7ebea0937592eb389e52805\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://7a41a47e72f5761d912367c041ddab41620175d63059ad71ff681a87d8cf0e98\",\"dweb:/ipfs/QmfEFuLaVyx9vQc83dS48wTcLtbBiWTNMdHSi5hAWA379i\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":{\"keccak256\":\"0xbda56396592db18a248d4062cd36abd586a11d92a2d25483d8c597f890859b15\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://a6ee93bcb7ccd1d1b8979c9530b1ca452d0757794995b62793b6e197670b9f25\",\"dweb:/ipfs/QmbNkhTPzF1YgU4Qgu4SRFXZ8AwFjyG18EzuMZ32anrQ4Y\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":{\"keccak256\":\"0x4c558b8c9d0dff2322d5d812e83a3abe25a9e60c8f646507f8a9c7fa2a2453af\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://6f0796c75d117770e220c136b60d96b5cf1d4875ccbbd0afb564ed27aa220335\",\"dweb:/ipfs/QmQxYm6CMCqJiKsB3sguqWu8rggmaQgpuq8BZhAEveqNAM\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":{\"keccak256\":\"0x7ac5dd35cbc776693eecfd8e7e86af139c7b054c43be4f97e6c8929417c17dba\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://4a452d8acad5246538ac352887081d732098dcab869c79a43a5f916e7e76f353\",\"dweb:/ipfs/QmeazDSxfKBSGyCGjmk7G79UbvYMRcbr2eUU9ThyqSvNhv\"]}},\"version\":1}", + "storageLayout": { + "storage": [], + "types": null + }, + "userdoc": { + "kind": "user", + "methods": {}, + "notice": "A Solidity implementation for handling signatures in the Sequence protocol.", + "version": 1 + } + } + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol": { + "SequenceChainedSig": { + "abi": [ + { + "inputs": [], + "name": "ImageHashIsZero", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes1", + "name": "_type", + "type": "bytes1" + } + ], + "name": "InvalidSignatureType", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "threshold", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_weight", + "type": "uint256" + } + ], + "name": "LowWeightChainedSignature", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_sender", + "type": "address" + }, + { + "internalType": "address", + "name": "_self", + "type": "address" + } + ], + "name": "OnlySelfAuth", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_current", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_prev", + "type": "uint256" + } + ], + "name": "WrongChainedCheckpointOrder", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "newImageHash", + "type": "bytes32" + } + ], + "name": "ImageHashUpdated", + "type": "event" + }, + { + "inputs": [], + "name": "SET_IMAGE_HASH_TYPE_HASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_digest", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "signatureRecovery", + "outputs": [ + { + "internalType": "uint256", + "name": "threshold", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "weight", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "imageHash", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "subdigest", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "checkpoint", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_imageHash", + "type": "bytes32" + } + ], + "name": "updateImageHash", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "devdoc": { + "author": "Agustin Aguilar (aa@horizon.io)", + "details": "The delegations can be chained together, the first signature is the one that is used to validate the message, the last signature must match the current on-chain configuration of the wallet.", + "kind": "dev", + "methods": { + "updateImageHash(bytes32)": { + "params": { + "_imageHash": "New required image hash of the signature" + } + } + }, + "title": "Sequence chained auth recovery submodule", + "version": 1 + }, + "evm": { + "assembly": "", + "bytecode": { + "functionDebugData": {}, + "generatedSources": [], + "linkReferences": {}, + "object": "", + "opcodes": "", + "sourceMap": "" + }, + "deployedBytecode": { + "functionDebugData": {}, + "generatedSources": [], + "immutableReferences": {}, + "linkReferences": {}, + "object": "", + "opcodes": "", + "sourceMap": "" + }, + "gasEstimates": null, + "legacyAssembly": null, + "methodIdentifiers": { + "SET_IMAGE_HASH_TYPE_HASH()": "57c56d6b", + "signatureRecovery(bytes32,bytes)": "853c5068", + "updateImageHash(bytes32)": "29561426" + } + }, + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"ImageHashIsZero\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes1\",\"name\":\"_type\",\"type\":\"bytes1\"}],\"name\":\"InvalidSignatureType\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_weight\",\"type\":\"uint256\"}],\"name\":\"LowWeightChainedSignature\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_self\",\"type\":\"address\"}],\"name\":\"OnlySelfAuth\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_current\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_prev\",\"type\":\"uint256\"}],\"name\":\"WrongChainedCheckpointOrder\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"newImageHash\",\"type\":\"bytes32\"}],\"name\":\"ImageHashUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"SET_IMAGE_HASH_TYPE_HASH\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_digest\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"signatureRecovery\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"imageHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"subdigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"checkpoint\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"_imageHash\",\"type\":\"bytes32\"}],\"name\":\"updateImageHash\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Agustin Aguilar (aa@horizon.io)\",\"details\":\"The delegations can be chained together, the first signature is the one that is used to validate the message, the last signature must match the current on-chain configuration of the wallet.\",\"kind\":\"dev\",\"methods\":{\"updateImageHash(bytes32)\":{\"params\":{\"_imageHash\":\"New required image hash of the signature\"}}},\"title\":\"Sequence chained auth recovery submodule\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"updateImageHash(bytes32)\":{\"notice\":\"Updates the signers configuration of the wallet\"}},\"notice\":\"Defines Sequence signatures that work by delegating control to new configurations.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":\"SequenceChainedSig\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":500000},\"remappings\":[\":@0xsequence/contracts-library/=src/\",\":@0xsequence/erc-1155/=lib/0xsequence/erc-1155/src/\",\":@0xsequence/erc20-meta-token/=lib/0xsequence/erc20-meta-token/src/\",\":@openzeppelin/=lib/openzeppelin/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc721a-upgradeable/=lib/chiru-labs/erc721a-upgradeable/\",\":erc721a/=lib/chiru-labs/erc721a/\",\":forge-std/=lib/forge-std/src/\",\":murky/=lib/murky/src/\",\":solady/=lib/solady/src/\"]},\"sources\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/interfaces/IERC1271Wallet.sol\":{\"keccak256\":\"0x2d7881bca678833feb385fd59e5d8ad6d596160ab51daa7030372654b3dbc38c\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://010f44c05b7285a55de939f9989727d53dfb87fd2d2534a832a70e0e081bb5f1\",\"dweb:/ipfs/QmQcujWErxjktsKyyiTySaFuR7Vaq6fUA9SUzPkde2txVK\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol\":{\"keccak256\":\"0x91545de5c77cfac86c5686c4e1f338a18ee7adb689ac0234848d7a7fc8a560db\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://dc89d05d8099ba4c3c2cf85737796d439899b5a04e6b87b1ea43f687ae08848a\",\"dweb:/ipfs/QmatU8gRvFkK3Yn1MYAekzi48Waw3cDLtXJpduvju9HFUu\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol\":{\"keccak256\":\"0x876c6a40cba975df4f7dfe24e02d153b2ee758975b6d1eda494ecd4b7244aa8e\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://b9be3f7930476d528ce10a121701421f0fb251b7d6b7cd579917375e6b283bb4\",\"dweb:/ipfs/QmSbvbYQvTk8KYJZ7QqSKB9Y4M1X3UDhS6k765Zr1BAwK8\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleAuth.sol\":{\"keccak256\":\"0x24c6b05c32cb344b3b0aebd01fbd8bfc69f8c8e29fca340b262d9612c34d51e2\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://5f6c004946f0cbc4b3e52d45248337146bc82569da894ecff3cbdc5a0dca95c3\",\"dweb:/ipfs/QmNSgDMQ7SHL6AJuzTSRbY2kgciHF1SKWfH6MaPH1N3TpR\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":{\"keccak256\":\"0xe0565e24e94204d4b254ace42d124d3279256090921a4818cbbf9747cbb14e04\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://4293a4762b0816738511f697efd04a0e881d4c409bd15ac1c4e7261fe5e482a2\",\"dweb:/ipfs/QmcHbEBne4fvpcD7RTJHCL6q9czoLa7KHneaCeYfXuWiGu\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol\":{\"keccak256\":\"0x755fbf6c106fe1c3c375c41c95c38269873717d8e683678b5fdbf6c8d3426306\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://7c7c92e72dd94f16b5c004d38c2d92eb2b760fd29a939945ed275633b0f93fa5\",\"dweb:/ipfs/QmVdCG7Aw7aVV67z5mUKZa4VqhXHdLqy3SKxPfxaxq54p2\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol\":{\"keccak256\":\"0xd780faf34527a323c96577c57370d175a2b6149db7ebea0937592eb389e52805\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://7a41a47e72f5761d912367c041ddab41620175d63059ad71ff681a87d8cf0e98\",\"dweb:/ipfs/QmfEFuLaVyx9vQc83dS48wTcLtbBiWTNMdHSi5hAWA379i\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":{\"keccak256\":\"0xbda56396592db18a248d4062cd36abd586a11d92a2d25483d8c597f890859b15\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://a6ee93bcb7ccd1d1b8979c9530b1ca452d0757794995b62793b6e197670b9f25\",\"dweb:/ipfs/QmbNkhTPzF1YgU4Qgu4SRFXZ8AwFjyG18EzuMZ32anrQ4Y\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":{\"keccak256\":\"0x4c558b8c9d0dff2322d5d812e83a3abe25a9e60c8f646507f8a9c7fa2a2453af\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://6f0796c75d117770e220c136b60d96b5cf1d4875ccbbd0afb564ed27aa220335\",\"dweb:/ipfs/QmQxYm6CMCqJiKsB3sguqWu8rggmaQgpuq8BZhAEveqNAM\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":{\"keccak256\":\"0x7ac5dd35cbc776693eecfd8e7e86af139c7b054c43be4f97e6c8929417c17dba\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://4a452d8acad5246538ac352887081d732098dcab869c79a43a5f916e7e76f353\",\"dweb:/ipfs/QmeazDSxfKBSGyCGjmk7G79UbvYMRcbr2eUU9ThyqSvNhv\"]}},\"version\":1}", + "storageLayout": { + "storage": [], + "types": null + }, + "userdoc": { + "kind": "user", + "methods": { + "updateImageHash(bytes32)": { + "notice": "Updates the signers configuration of the wallet" + } + }, + "notice": "Defines Sequence signatures that work by delegating control to new configurations.", + "version": 1 + } + } + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol": { + "SequenceDynamicSig": { + "abi": [], + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "evm": { + "assembly": " /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol\":98:912 library SequenceDynamicSig {... */\n dataSize(sub_0)\n dataOffset(sub_0)\n 0x0b\n dup3\n dup3\n dup3\n codecopy\n dup1\n mload\n 0x00\n byte\n 0x73\n eq\n tag_1\n jumpi\n mstore(0x00, shl(0xe0, 0x4e487b71))\n mstore(0x04, 0x00)\n revert(0x00, 0x24)\ntag_1:\n mstore(0x00, address)\n 0x73\n dup2\n mstore8\n dup3\n dup2\n return\nstop\n\nsub_0: assembly {\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol\":98:912 library SequenceDynamicSig {... */\n eq(address, deployTimeAddress())\n mstore(0x40, 0x80)\n 0x00\n dup1\n revert\n\n auxdata: 0xa2646970667358221220988e7a0efd834caf932b23f5964fd75fc66e99c5c9a0302666625fa77c52b63864736f6c63430008120033\n}\n", + "bytecode": { + "functionDebugData": {}, + "generatedSources": [], + "linkReferences": {}, + "object": "60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220988e7a0efd834caf932b23f5964fd75fc66e99c5c9a0302666625fa77c52b63864736f6c63430008120033", + "opcodes": "PUSH1 0x56 PUSH1 0x37 PUSH1 0xB DUP3 DUP3 DUP3 CODECOPY DUP1 MLOAD PUSH1 0x0 BYTE PUSH1 0x73 EQ PUSH1 0x2A JUMPI PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x0 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST ADDRESS PUSH1 0x0 MSTORE PUSH1 0x73 DUP2 MSTORE8 DUP3 DUP2 RETURN INVALID PUSH20 0x0 ADDRESS EQ PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 SWAP9 DUP15 PUSH27 0xEFD834CAF932B23F5964FD75FC66E99C5C9A0302666625FA77C52 0xB6 CODESIZE PUSH5 0x736F6C6343 STOP ADDMOD SLT STOP CALLER ", + "sourceMap": "98:814:15:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;98:814:15;;;;;;;;;;;;;;;;;" + }, + "deployedBytecode": { + "functionDebugData": {}, + "generatedSources": [], + "immutableReferences": {}, + "linkReferences": {}, + "object": "73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220988e7a0efd834caf932b23f5964fd75fc66e99c5c9a0302666625fa77c52b63864736f6c63430008120033", + "opcodes": "PUSH20 0x0 ADDRESS EQ PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 SWAP9 DUP15 PUSH27 0xEFD834CAF932B23F5964FD75FC66E99C5C9A0302666625FA77C52 0xB6 CODESIZE PUSH5 0x736F6C6343 STOP ADDMOD SLT STOP CALLER ", + "sourceMap": "98:814:15:-:0;;;;;;;;" + }, + "gasEstimates": { + "creation": { + "codeDepositCost": "17200", + "executionCost": "103", + "totalCost": "17303" + }, + "internal": { + "recover(bytes32,bytes calldata)": "infinite" + } + }, + "legacyAssembly": { + ".code": [ + { + "begin": 98, + "end": 912, + "name": "PUSH #[$]", + "source": 15, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 98, + "end": 912, + "name": "PUSH [$]", + "source": 15, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 98, + "end": 912, + "name": "PUSH", + "source": 15, + "value": "B" + }, + { + "begin": 98, + "end": 912, + "name": "DUP3", + "source": 15 + }, + { + "begin": 98, + "end": 912, + "name": "DUP3", + "source": 15 + }, + { + "begin": 98, + "end": 912, + "name": "DUP3", + "source": 15 + }, + { + "begin": 98, + "end": 912, + "name": "CODECOPY", + "source": 15 + }, + { + "begin": 98, + "end": 912, + "name": "DUP1", + "source": 15 + }, + { + "begin": 98, + "end": 912, + "name": "MLOAD", + "source": 15 + }, + { + "begin": 98, + "end": 912, + "name": "PUSH", + "source": 15, + "value": "0" + }, + { + "begin": 98, + "end": 912, + "name": "BYTE", + "source": 15 + }, + { + "begin": 98, + "end": 912, + "name": "PUSH", + "source": 15, + "value": "73" + }, + { + "begin": 98, + "end": 912, + "name": "EQ", + "source": 15 + }, + { + "begin": 98, + "end": 912, + "name": "PUSH [tag]", + "source": 15, + "value": "1" + }, + { + "begin": 98, + "end": 912, + "name": "JUMPI", + "source": 15 + }, + { + "begin": -1, + "end": -1, + "name": "PUSH", + "source": -1, + "value": "4E487B71" + }, + { + "begin": -1, + "end": -1, + "name": "PUSH", + "source": -1, + "value": "E0" + }, + { + "begin": -1, + "end": -1, + "name": "SHL", + "source": -1 + }, + { + "begin": 98, + "end": 912, + "name": "PUSH", + "source": 15, + "value": "0" + }, + { + "begin": 98, + "end": 912, + "name": "MSTORE", + "source": 15 + }, + { + "begin": 98, + "end": 912, + "name": "PUSH", + "source": 15, + "value": "0" + }, + { + "begin": 98, + "end": 912, + "name": "PUSH", + "source": 15, + "value": "4" + }, + { + "begin": 98, + "end": 912, + "name": "MSTORE", + "source": 15 + }, + { + "begin": 98, + "end": 912, + "name": "PUSH", + "source": 15, + "value": "24" + }, + { + "begin": 98, + "end": 912, + "name": "PUSH", + "source": 15, + "value": "0" + }, + { + "begin": 98, + "end": 912, + "name": "REVERT", + "source": 15 + }, + { + "begin": 98, + "end": 912, + "name": "tag", + "source": 15, + "value": "1" + }, + { + "begin": 98, + "end": 912, + "name": "JUMPDEST", + "source": 15 + }, + { + "begin": 98, + "end": 912, + "name": "ADDRESS", + "source": 15 + }, + { + "begin": 98, + "end": 912, + "name": "PUSH", + "source": 15, + "value": "0" + }, + { + "begin": 98, + "end": 912, + "name": "MSTORE", + "source": 15 + }, + { + "begin": 98, + "end": 912, + "name": "PUSH", + "source": 15, + "value": "73" + }, + { + "begin": 98, + "end": 912, + "name": "DUP2", + "source": 15 + }, + { + "begin": 98, + "end": 912, + "name": "MSTORE8", + "source": 15 + }, + { + "begin": 98, + "end": 912, + "name": "DUP3", + "source": 15 + }, + { + "begin": 98, + "end": 912, + "name": "DUP2", + "source": 15 + }, + { + "begin": 98, + "end": 912, + "name": "RETURN", + "source": 15 + } + ], + ".data": { + "0": { + ".auxdata": "a2646970667358221220988e7a0efd834caf932b23f5964fd75fc66e99c5c9a0302666625fa77c52b63864736f6c63430008120033", + ".code": [ + { + "begin": 98, + "end": 912, + "name": "PUSHDEPLOYADDRESS", + "source": 15 + }, + { + "begin": 98, + "end": 912, + "name": "ADDRESS", + "source": 15 + }, + { + "begin": 98, + "end": 912, + "name": "EQ", + "source": 15 + }, + { + "begin": 98, + "end": 912, + "name": "PUSH", + "source": 15, + "value": "80" + }, + { + "begin": 98, + "end": 912, + "name": "PUSH", + "source": 15, + "value": "40" + }, + { + "begin": 98, + "end": 912, + "name": "MSTORE", + "source": 15 + }, + { + "begin": 98, + "end": 912, + "name": "PUSH", + "source": 15, + "value": "0" + }, + { + "begin": 98, + "end": 912, + "name": "DUP1", + "source": 15 + }, + { + "begin": 98, + "end": 912, + "name": "REVERT", + "source": 15 + } + ] + } + }, + "sourceList": [ + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/interfaces/IERC1271Wallet.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleERC165.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleOnlyDelegatecall.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCalls.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCreator.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol", + "#utility.yul" + ] + }, + "methodIdentifiers": {} + }, + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol\":\"SequenceDynamicSig\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":500000},\"remappings\":[\":@0xsequence/contracts-library/=src/\",\":@0xsequence/erc-1155/=lib/0xsequence/erc-1155/src/\",\":@0xsequence/erc20-meta-token/=lib/0xsequence/erc20-meta-token/src/\",\":@openzeppelin/=lib/openzeppelin/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc721a-upgradeable/=lib/chiru-labs/erc721a-upgradeable/\",\":erc721a/=lib/chiru-labs/erc721a/\",\":forge-std/=lib/forge-std/src/\",\":murky/=lib/murky/src/\",\":solady/=lib/solady/src/\"]},\"sources\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/interfaces/IERC1271Wallet.sol\":{\"keccak256\":\"0x2d7881bca678833feb385fd59e5d8ad6d596160ab51daa7030372654b3dbc38c\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://010f44c05b7285a55de939f9989727d53dfb87fd2d2534a832a70e0e081bb5f1\",\"dweb:/ipfs/QmQcujWErxjktsKyyiTySaFuR7Vaq6fUA9SUzPkde2txVK\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol\":{\"keccak256\":\"0xe0565e24e94204d4b254ace42d124d3279256090921a4818cbbf9747cbb14e04\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://4293a4762b0816738511f697efd04a0e881d4c409bd15ac1c4e7261fe5e482a2\",\"dweb:/ipfs/QmcHbEBne4fvpcD7RTJHCL6q9czoLa7KHneaCeYfXuWiGu\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol\":{\"keccak256\":\"0x6de353f8c7f44c4294914a4917458ce90ae2f7ecd2d84074fe12d4a4f1485ee5\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://369f979b79a3d3fd0336ab14b3accadb63e4784324afc34f8db11d1988526afd\",\"dweb:/ipfs/QmavmBZ354wTaXQ6ixBd8GrC9HwtRqn4MoNhCVJcx11off\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol\":{\"keccak256\":\"0xd780faf34527a323c96577c57370d175a2b6149db7ebea0937592eb389e52805\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://7a41a47e72f5761d912367c041ddab41620175d63059ad71ff681a87d8cf0e98\",\"dweb:/ipfs/QmfEFuLaVyx9vQc83dS48wTcLtbBiWTNMdHSi5hAWA379i\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":{\"keccak256\":\"0xbda56396592db18a248d4062cd36abd586a11d92a2d25483d8c597f890859b15\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://a6ee93bcb7ccd1d1b8979c9530b1ca452d0757794995b62793b6e197670b9f25\",\"dweb:/ipfs/QmbNkhTPzF1YgU4Qgu4SRFXZ8AwFjyG18EzuMZ32anrQ4Y\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":{\"keccak256\":\"0x4c558b8c9d0dff2322d5d812e83a3abe25a9e60c8f646507f8a9c7fa2a2453af\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://6f0796c75d117770e220c136b60d96b5cf1d4875ccbbd0afb564ed27aa220335\",\"dweb:/ipfs/QmQxYm6CMCqJiKsB3sguqWu8rggmaQgpuq8BZhAEveqNAM\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":{\"keccak256\":\"0x7ac5dd35cbc776693eecfd8e7e86af139c7b054c43be4f97e6c8929417c17dba\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://4a452d8acad5246538ac352887081d732098dcab869c79a43a5f916e7e76f353\",\"dweb:/ipfs/QmeazDSxfKBSGyCGjmk7G79UbvYMRcbr2eUU9ThyqSvNhv\"]}},\"version\":1}", + "storageLayout": { + "storage": [], + "types": null + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + } + } + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol": { + "SequenceNoChainIdSig": { + "abi": [], + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "evm": { + "assembly": " /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol\":65:619 library SequenceNoChainIdSig {... */\n dataSize(sub_0)\n dataOffset(sub_0)\n 0x0b\n dup3\n dup3\n dup3\n codecopy\n dup1\n mload\n 0x00\n byte\n 0x73\n eq\n tag_1\n jumpi\n mstore(0x00, shl(0xe0, 0x4e487b71))\n mstore(0x04, 0x00)\n revert(0x00, 0x24)\ntag_1:\n mstore(0x00, address)\n 0x73\n dup2\n mstore8\n dup3\n dup2\n return\nstop\n\nsub_0: assembly {\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol\":65:619 library SequenceNoChainIdSig {... */\n eq(address, deployTimeAddress())\n mstore(0x40, 0x80)\n 0x00\n dup1\n revert\n\n auxdata: 0xa264697066735822122017d1b2b94cb2d25bb2c8abe419506b6917bfa14841e22660d017f50ee442141b64736f6c63430008120033\n}\n", + "bytecode": { + "functionDebugData": {}, + "generatedSources": [], + "linkReferences": {}, + "object": "60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122017d1b2b94cb2d25bb2c8abe419506b6917bfa14841e22660d017f50ee442141b64736f6c63430008120033", + "opcodes": "PUSH1 0x56 PUSH1 0x37 PUSH1 0xB DUP3 DUP3 DUP3 CODECOPY DUP1 MLOAD PUSH1 0x0 BYTE PUSH1 0x73 EQ PUSH1 0x2A JUMPI PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x0 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST ADDRESS PUSH1 0x0 MSTORE PUSH1 0x73 DUP2 MSTORE8 DUP3 DUP2 RETURN INVALID PUSH20 0x0 ADDRESS EQ PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 OR 0xD1 0xB2 0xB9 0x4C 0xB2 0xD2 JUMPDEST 0xB2 0xC8 0xAB 0xE4 NOT POP PUSH12 0x6917BFA14841E22660D017F5 0xE 0xE4 TIMESTAMP EQ SHL PUSH5 0x736F6C6343 STOP ADDMOD SLT STOP CALLER ", + "sourceMap": "65:554:16:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;65:554:16;;;;;;;;;;;;;;;;;" + }, + "deployedBytecode": { + "functionDebugData": {}, + "generatedSources": [], + "immutableReferences": {}, + "linkReferences": {}, + "object": "73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122017d1b2b94cb2d25bb2c8abe419506b6917bfa14841e22660d017f50ee442141b64736f6c63430008120033", + "opcodes": "PUSH20 0x0 ADDRESS EQ PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 OR 0xD1 0xB2 0xB9 0x4C 0xB2 0xD2 JUMPDEST 0xB2 0xC8 0xAB 0xE4 NOT POP PUSH12 0x6917BFA14841E22660D017F5 0xE 0xE4 TIMESTAMP EQ SHL PUSH5 0x736F6C6343 STOP ADDMOD SLT STOP CALLER ", + "sourceMap": "65:554:16:-:0;;;;;;;;" + }, + "gasEstimates": { + "creation": { + "codeDepositCost": "17200", + "executionCost": "103", + "totalCost": "17303" + }, + "internal": { + "subdigest(bytes32)": "infinite" + } + }, + "legacyAssembly": { + ".code": [ + { + "begin": 65, + "end": 619, + "name": "PUSH #[$]", + "source": 16, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 65, + "end": 619, + "name": "PUSH [$]", + "source": 16, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 65, + "end": 619, + "name": "PUSH", + "source": 16, + "value": "B" + }, + { + "begin": 65, + "end": 619, + "name": "DUP3", + "source": 16 + }, + { + "begin": 65, + "end": 619, + "name": "DUP3", + "source": 16 + }, + { + "begin": 65, + "end": 619, + "name": "DUP3", + "source": 16 + }, + { + "begin": 65, + "end": 619, + "name": "CODECOPY", + "source": 16 + }, + { + "begin": 65, + "end": 619, + "name": "DUP1", + "source": 16 + }, + { + "begin": 65, + "end": 619, + "name": "MLOAD", + "source": 16 + }, + { + "begin": 65, + "end": 619, + "name": "PUSH", + "source": 16, + "value": "0" + }, + { + "begin": 65, + "end": 619, + "name": "BYTE", + "source": 16 + }, + { + "begin": 65, + "end": 619, + "name": "PUSH", + "source": 16, + "value": "73" + }, + { + "begin": 65, + "end": 619, + "name": "EQ", + "source": 16 + }, + { + "begin": 65, + "end": 619, + "name": "PUSH [tag]", + "source": 16, + "value": "1" + }, + { + "begin": 65, + "end": 619, + "name": "JUMPI", + "source": 16 + }, + { + "begin": -1, + "end": -1, + "name": "PUSH", + "source": -1, + "value": "4E487B71" + }, + { + "begin": -1, + "end": -1, + "name": "PUSH", + "source": -1, + "value": "E0" + }, + { + "begin": -1, + "end": -1, + "name": "SHL", + "source": -1 + }, + { + "begin": 65, + "end": 619, + "name": "PUSH", + "source": 16, + "value": "0" + }, + { + "begin": 65, + "end": 619, + "name": "MSTORE", + "source": 16 + }, + { + "begin": 65, + "end": 619, + "name": "PUSH", + "source": 16, + "value": "0" + }, + { + "begin": 65, + "end": 619, + "name": "PUSH", + "source": 16, + "value": "4" + }, + { + "begin": 65, + "end": 619, + "name": "MSTORE", + "source": 16 + }, + { + "begin": 65, + "end": 619, + "name": "PUSH", + "source": 16, + "value": "24" + }, + { + "begin": 65, + "end": 619, + "name": "PUSH", + "source": 16, + "value": "0" + }, + { + "begin": 65, + "end": 619, + "name": "REVERT", + "source": 16 + }, + { + "begin": 65, + "end": 619, + "name": "tag", + "source": 16, + "value": "1" + }, + { + "begin": 65, + "end": 619, + "name": "JUMPDEST", + "source": 16 + }, + { + "begin": 65, + "end": 619, + "name": "ADDRESS", + "source": 16 + }, + { + "begin": 65, + "end": 619, + "name": "PUSH", + "source": 16, + "value": "0" + }, + { + "begin": 65, + "end": 619, + "name": "MSTORE", + "source": 16 + }, + { + "begin": 65, + "end": 619, + "name": "PUSH", + "source": 16, + "value": "73" + }, + { + "begin": 65, + "end": 619, + "name": "DUP2", + "source": 16 + }, + { + "begin": 65, + "end": 619, + "name": "MSTORE8", + "source": 16 + }, + { + "begin": 65, + "end": 619, + "name": "DUP3", + "source": 16 + }, + { + "begin": 65, + "end": 619, + "name": "DUP2", + "source": 16 + }, + { + "begin": 65, + "end": 619, + "name": "RETURN", + "source": 16 + } + ], + ".data": { + "0": { + ".auxdata": "a264697066735822122017d1b2b94cb2d25bb2c8abe419506b6917bfa14841e22660d017f50ee442141b64736f6c63430008120033", + ".code": [ + { + "begin": 65, + "end": 619, + "name": "PUSHDEPLOYADDRESS", + "source": 16 + }, + { + "begin": 65, + "end": 619, + "name": "ADDRESS", + "source": 16 + }, + { + "begin": 65, + "end": 619, + "name": "EQ", + "source": 16 + }, + { + "begin": 65, + "end": 619, + "name": "PUSH", + "source": 16, + "value": "80" + }, + { + "begin": 65, + "end": 619, + "name": "PUSH", + "source": 16, + "value": "40" + }, + { + "begin": 65, + "end": 619, + "name": "MSTORE", + "source": 16 + }, + { + "begin": 65, + "end": 619, + "name": "PUSH", + "source": 16, + "value": "0" + }, + { + "begin": 65, + "end": 619, + "name": "DUP1", + "source": 16 + }, + { + "begin": 65, + "end": 619, + "name": "REVERT", + "source": 16 + } + ] + } + }, + "sourceList": [ + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/interfaces/IERC1271Wallet.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleERC165.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleOnlyDelegatecall.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCalls.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCreator.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol", + "#utility.yul" + ] + }, + "methodIdentifiers": {} + }, + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol\":\"SequenceNoChainIdSig\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":500000},\"remappings\":[\":@0xsequence/contracts-library/=src/\",\":@0xsequence/erc-1155/=lib/0xsequence/erc-1155/src/\",\":@0xsequence/erc20-meta-token/=lib/0xsequence/erc20-meta-token/src/\",\":@openzeppelin/=lib/openzeppelin/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc721a-upgradeable/=lib/chiru-labs/erc721a-upgradeable/\",\":erc721a/=lib/chiru-labs/erc721a/\",\":forge-std/=lib/forge-std/src/\",\":murky/=lib/murky/src/\",\":solady/=lib/solady/src/\"]},\"sources\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol\":{\"keccak256\":\"0xa3ac8b8d31f20a8732bb4ebad53b42b334ec29041de0224bd494913ef0b2ad07\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://5a81d4eb3f47b09a8835b2fd53e0baa2e23cb604db3b10dae82543a5bcc52fa4\",\"dweb:/ipfs/QmQ9XSSgbaagWArmZJJ366bdJ7HfxUxn9jdnWwN6SxUSeY\"]}},\"version\":1}", + "storageLayout": { + "storage": [], + "types": null + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + } + } + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol": { + "SubModuleNonce": { + "abi": [], + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "evm": { + "assembly": " /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol\":65:751 library SubModuleNonce {... */\n dataSize(sub_0)\n dataOffset(sub_0)\n 0x0b\n dup3\n dup3\n dup3\n codecopy\n dup1\n mload\n 0x00\n byte\n 0x73\n eq\n tag_1\n jumpi\n mstore(0x00, shl(0xe0, 0x4e487b71))\n mstore(0x04, 0x00)\n revert(0x00, 0x24)\ntag_1:\n mstore(0x00, address)\n 0x73\n dup2\n mstore8\n dup3\n dup2\n return\nstop\n\nsub_0: assembly {\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol\":65:751 library SubModuleNonce {... */\n eq(address, deployTimeAddress())\n mstore(0x40, 0x80)\n 0x00\n dup1\n revert\n\n auxdata: 0xa26469706673582212208609e09d11153aed5ba8eb4ae9c6915a536fd4523605bce53bc4a2f1e304f84264736f6c63430008120033\n}\n", + "bytecode": { + "functionDebugData": {}, + "generatedSources": [], + "linkReferences": {}, + "object": "60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212208609e09d11153aed5ba8eb4ae9c6915a536fd4523605bce53bc4a2f1e304f84264736f6c63430008120033", + "opcodes": "PUSH1 0x56 PUSH1 0x37 PUSH1 0xB DUP3 DUP3 DUP3 CODECOPY DUP1 MLOAD PUSH1 0x0 BYTE PUSH1 0x73 EQ PUSH1 0x2A JUMPI PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x0 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST ADDRESS PUSH1 0x0 MSTORE PUSH1 0x73 DUP2 MSTORE8 DUP3 DUP2 RETURN INVALID PUSH20 0x0 ADDRESS EQ PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 DUP7 MULMOD 0xE0 SWAP14 GT ISZERO GASPRICE 0xED JUMPDEST 0xA8 0xEB 0x4A 0xE9 0xC6 SWAP2 GAS MSTORE8 PUSH16 0xD4523605BCE53BC4A2F1E304F8426473 PUSH16 0x6C634300081200330000000000000000 ", + "sourceMap": "65:686:17:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;65:686:17;;;;;;;;;;;;;;;;;" + }, + "deployedBytecode": { + "functionDebugData": {}, + "generatedSources": [], + "immutableReferences": {}, + "linkReferences": {}, + "object": "73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212208609e09d11153aed5ba8eb4ae9c6915a536fd4523605bce53bc4a2f1e304f84264736f6c63430008120033", + "opcodes": "PUSH20 0x0 ADDRESS EQ PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 DUP7 MULMOD 0xE0 SWAP14 GT ISZERO GASPRICE 0xED JUMPDEST 0xA8 0xEB 0x4A 0xE9 0xC6 SWAP2 GAS MSTORE8 PUSH16 0xD4523605BCE53BC4A2F1E304F8426473 PUSH16 0x6C634300081200330000000000000000 ", + "sourceMap": "65:686:17:-:0;;;;;;;;" + }, + "gasEstimates": { + "creation": { + "codeDepositCost": "17200", + "executionCost": "103", + "totalCost": "17303" + }, + "internal": { + "decodeNonce(uint256)": "infinite" + } + }, + "legacyAssembly": { + ".code": [ + { + "begin": 65, + "end": 751, + "name": "PUSH #[$]", + "source": 17, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 65, + "end": 751, + "name": "PUSH [$]", + "source": 17, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 65, + "end": 751, + "name": "PUSH", + "source": 17, + "value": "B" + }, + { + "begin": 65, + "end": 751, + "name": "DUP3", + "source": 17 + }, + { + "begin": 65, + "end": 751, + "name": "DUP3", + "source": 17 + }, + { + "begin": 65, + "end": 751, + "name": "DUP3", + "source": 17 + }, + { + "begin": 65, + "end": 751, + "name": "CODECOPY", + "source": 17 + }, + { + "begin": 65, + "end": 751, + "name": "DUP1", + "source": 17 + }, + { + "begin": 65, + "end": 751, + "name": "MLOAD", + "source": 17 + }, + { + "begin": 65, + "end": 751, + "name": "PUSH", + "source": 17, + "value": "0" + }, + { + "begin": 65, + "end": 751, + "name": "BYTE", + "source": 17 + }, + { + "begin": 65, + "end": 751, + "name": "PUSH", + "source": 17, + "value": "73" + }, + { + "begin": 65, + "end": 751, + "name": "EQ", + "source": 17 + }, + { + "begin": 65, + "end": 751, + "name": "PUSH [tag]", + "source": 17, + "value": "1" + }, + { + "begin": 65, + "end": 751, + "name": "JUMPI", + "source": 17 + }, + { + "begin": -1, + "end": -1, + "name": "PUSH", + "source": -1, + "value": "4E487B71" + }, + { + "begin": -1, + "end": -1, + "name": "PUSH", + "source": -1, + "value": "E0" + }, + { + "begin": -1, + "end": -1, + "name": "SHL", + "source": -1 + }, + { + "begin": 65, + "end": 751, + "name": "PUSH", + "source": 17, + "value": "0" + }, + { + "begin": 65, + "end": 751, + "name": "MSTORE", + "source": 17 + }, + { + "begin": 65, + "end": 751, + "name": "PUSH", + "source": 17, + "value": "0" + }, + { + "begin": 65, + "end": 751, + "name": "PUSH", + "source": 17, + "value": "4" + }, + { + "begin": 65, + "end": 751, + "name": "MSTORE", + "source": 17 + }, + { + "begin": 65, + "end": 751, + "name": "PUSH", + "source": 17, + "value": "24" + }, + { + "begin": 65, + "end": 751, + "name": "PUSH", + "source": 17, + "value": "0" + }, + { + "begin": 65, + "end": 751, + "name": "REVERT", + "source": 17 + }, + { + "begin": 65, + "end": 751, + "name": "tag", + "source": 17, + "value": "1" + }, + { + "begin": 65, + "end": 751, + "name": "JUMPDEST", + "source": 17 + }, + { + "begin": 65, + "end": 751, + "name": "ADDRESS", + "source": 17 + }, + { + "begin": 65, + "end": 751, + "name": "PUSH", + "source": 17, + "value": "0" + }, + { + "begin": 65, + "end": 751, + "name": "MSTORE", + "source": 17 + }, + { + "begin": 65, + "end": 751, + "name": "PUSH", + "source": 17, + "value": "73" + }, + { + "begin": 65, + "end": 751, + "name": "DUP2", + "source": 17 + }, + { + "begin": 65, + "end": 751, + "name": "MSTORE8", + "source": 17 + }, + { + "begin": 65, + "end": 751, + "name": "DUP3", + "source": 17 + }, + { + "begin": 65, + "end": 751, + "name": "DUP2", + "source": 17 + }, + { + "begin": 65, + "end": 751, + "name": "RETURN", + "source": 17 + } + ], + ".data": { + "0": { + ".auxdata": "a26469706673582212208609e09d11153aed5ba8eb4ae9c6915a536fd4523605bce53bc4a2f1e304f84264736f6c63430008120033", + ".code": [ + { + "begin": 65, + "end": 751, + "name": "PUSHDEPLOYADDRESS", + "source": 17 + }, + { + "begin": 65, + "end": 751, + "name": "ADDRESS", + "source": 17 + }, + { + "begin": 65, + "end": 751, + "name": "EQ", + "source": 17 + }, + { + "begin": 65, + "end": 751, + "name": "PUSH", + "source": 17, + "value": "80" + }, + { + "begin": 65, + "end": 751, + "name": "PUSH", + "source": 17, + "value": "40" + }, + { + "begin": 65, + "end": 751, + "name": "MSTORE", + "source": 17 + }, + { + "begin": 65, + "end": 751, + "name": "PUSH", + "source": 17, + "value": "0" + }, + { + "begin": 65, + "end": 751, + "name": "DUP1", + "source": 17 + }, + { + "begin": 65, + "end": 751, + "name": "REVERT", + "source": 17 + } + ] + } + }, + "sourceList": [ + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/interfaces/IERC1271Wallet.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleERC165.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleOnlyDelegatecall.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCalls.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCreator.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol", + "#utility.yul" + ] + }, + "methodIdentifiers": {} + }, + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol\":\"SubModuleNonce\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":500000},\"remappings\":[\":@0xsequence/contracts-library/=src/\",\":@0xsequence/erc-1155/=lib/0xsequence/erc-1155/src/\",\":@0xsequence/erc20-meta-token/=lib/0xsequence/erc20-meta-token/src/\",\":@openzeppelin/=lib/openzeppelin/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc721a-upgradeable/=lib/chiru-labs/erc721a-upgradeable/\",\":erc721a/=lib/chiru-labs/erc721a/\",\":forge-std/=lib/forge-std/src/\",\":murky/=lib/murky/src/\",\":solady/=lib/solady/src/\"]},\"sources\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol\":{\"keccak256\":\"0x98520e740b0822ec053d21f376b8be8a58e93228f3758f9228a7d00e1f60950f\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://31226706c004f1a4315d6b8d37621b46f4d5807c16e1ce72675c1431ed9006a2\",\"dweb:/ipfs/QmdSSyCuPex2E2VTd6UMYy9WAq9eJNZ6vHSUomntNknzXE\"]}},\"version\":1}", + "storageLayout": { + "storage": [], + "types": null + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + } + } + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol": { + "LibBytes": { + "abi": [], + "devdoc": { + "author": "Agustin Aguilar (aa@horizon.io)", + "details": "These functions do not check if the input index is within the bounds of the data array. Reading out of bounds may return dirty values.", + "kind": "dev", + "methods": {}, + "title": "Library for reading data from bytes arrays", + "version": 1 + }, + "evm": { + "assembly": " /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol\":405:2096 library LibBytes {... */\n dataSize(sub_0)\n dataOffset(sub_0)\n 0x0b\n dup3\n dup3\n dup3\n codecopy\n dup1\n mload\n 0x00\n byte\n 0x73\n eq\n tag_1\n jumpi\n mstore(0x00, shl(0xe0, 0x4e487b71))\n mstore(0x04, 0x00)\n revert(0x00, 0x24)\ntag_1:\n mstore(0x00, address)\n 0x73\n dup2\n mstore8\n dup3\n dup2\n return\nstop\n\nsub_0: assembly {\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol\":405:2096 library LibBytes {... */\n eq(address, deployTimeAddress())\n mstore(0x40, 0x80)\n 0x00\n dup1\n revert\n\n auxdata: 0xa2646970667358221220b00d0cee4061dc303d853fadda969d1de6324d7d0f32be48bae08404d30b621f64736f6c63430008120033\n}\n", + "bytecode": { + "functionDebugData": {}, + "generatedSources": [], + "linkReferences": {}, + "object": "60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220b00d0cee4061dc303d853fadda969d1de6324d7d0f32be48bae08404d30b621f64736f6c63430008120033", + "opcodes": "PUSH1 0x56 PUSH1 0x37 PUSH1 0xB DUP3 DUP3 DUP3 CODECOPY DUP1 MLOAD PUSH1 0x0 BYTE PUSH1 0x73 EQ PUSH1 0x2A JUMPI PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x0 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST ADDRESS PUSH1 0x0 MSTORE PUSH1 0x73 DUP2 MSTORE8 DUP3 DUP2 RETURN INVALID PUSH20 0x0 ADDRESS EQ PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 0xB0 0xD 0xC 0xEE BLOCKHASH PUSH2 0xDC30 RETURNDATASIZE DUP6 EXTCODEHASH 0xAD 0xDA SWAP7 SWAP14 SAR 0xE6 ORIGIN 0x4D PUSH30 0xF32BE48BAE08404D30B621F64736F6C6343000812003300000000000000 ", + "sourceMap": "405:1691:18:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;405:1691:18;;;;;;;;;;;;;;;;;" + }, + "deployedBytecode": { + "functionDebugData": {}, + "generatedSources": [], + "immutableReferences": {}, + "linkReferences": {}, + "object": "73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220b00d0cee4061dc303d853fadda969d1de6324d7d0f32be48bae08404d30b621f64736f6c63430008120033", + "opcodes": "PUSH20 0x0 ADDRESS EQ PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 0xB0 0xD 0xC 0xEE BLOCKHASH PUSH2 0xDC30 RETURNDATASIZE DUP6 EXTCODEHASH 0xAD 0xDA SWAP7 SWAP14 SAR 0xE6 ORIGIN 0x4D PUSH30 0xF32BE48BAE08404D30B621F64736F6C6343000812003300000000000000 ", + "sourceMap": "405:1691:18:-:0;;;;;;;;" + }, + "gasEstimates": { + "creation": { + "codeDepositCost": "17200", + "executionCost": "103", + "totalCost": "17303" + }, + "internal": { + "readBytes32(bytes calldata,uint256)": "infinite", + "readFirstUint16(bytes calldata)": "infinite", + "readUint32(bytes calldata,uint256)": "infinite", + "readUint8(bytes calldata,uint256)": "infinite" + } + }, + "legacyAssembly": { + ".code": [ + { + "begin": 405, + "end": 2096, + "name": "PUSH #[$]", + "source": 18, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 405, + "end": 2096, + "name": "PUSH [$]", + "source": 18, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 405, + "end": 2096, + "name": "PUSH", + "source": 18, + "value": "B" + }, + { + "begin": 405, + "end": 2096, + "name": "DUP3", + "source": 18 + }, + { + "begin": 405, + "end": 2096, + "name": "DUP3", + "source": 18 + }, + { + "begin": 405, + "end": 2096, + "name": "DUP3", + "source": 18 + }, + { + "begin": 405, + "end": 2096, + "name": "CODECOPY", + "source": 18 + }, + { + "begin": 405, + "end": 2096, + "name": "DUP1", + "source": 18 + }, + { + "begin": 405, + "end": 2096, + "name": "MLOAD", + "source": 18 + }, + { + "begin": 405, + "end": 2096, + "name": "PUSH", + "source": 18, + "value": "0" + }, + { + "begin": 405, + "end": 2096, + "name": "BYTE", + "source": 18 + }, + { + "begin": 405, + "end": 2096, + "name": "PUSH", + "source": 18, + "value": "73" + }, + { + "begin": 405, + "end": 2096, + "name": "EQ", + "source": 18 + }, + { + "begin": 405, + "end": 2096, + "name": "PUSH [tag]", + "source": 18, + "value": "1" + }, + { + "begin": 405, + "end": 2096, + "name": "JUMPI", + "source": 18 + }, + { + "begin": -1, + "end": -1, + "name": "PUSH", + "source": -1, + "value": "4E487B71" + }, + { + "begin": -1, + "end": -1, + "name": "PUSH", + "source": -1, + "value": "E0" + }, + { + "begin": -1, + "end": -1, + "name": "SHL", + "source": -1 + }, + { + "begin": 405, + "end": 2096, + "name": "PUSH", + "source": 18, + "value": "0" + }, + { + "begin": 405, + "end": 2096, + "name": "MSTORE", + "source": 18 + }, + { + "begin": 405, + "end": 2096, + "name": "PUSH", + "source": 18, + "value": "0" + }, + { + "begin": 405, + "end": 2096, + "name": "PUSH", + "source": 18, + "value": "4" + }, + { + "begin": 405, + "end": 2096, + "name": "MSTORE", + "source": 18 + }, + { + "begin": 405, + "end": 2096, + "name": "PUSH", + "source": 18, + "value": "24" + }, + { + "begin": 405, + "end": 2096, + "name": "PUSH", + "source": 18, + "value": "0" + }, + { + "begin": 405, + "end": 2096, + "name": "REVERT", + "source": 18 + }, + { + "begin": 405, + "end": 2096, + "name": "tag", + "source": 18, + "value": "1" + }, + { + "begin": 405, + "end": 2096, + "name": "JUMPDEST", + "source": 18 + }, + { + "begin": 405, + "end": 2096, + "name": "ADDRESS", + "source": 18 + }, + { + "begin": 405, + "end": 2096, + "name": "PUSH", + "source": 18, + "value": "0" + }, + { + "begin": 405, + "end": 2096, + "name": "MSTORE", + "source": 18 + }, + { + "begin": 405, + "end": 2096, + "name": "PUSH", + "source": 18, + "value": "73" + }, + { + "begin": 405, + "end": 2096, + "name": "DUP2", + "source": 18 + }, + { + "begin": 405, + "end": 2096, + "name": "MSTORE8", + "source": 18 + }, + { + "begin": 405, + "end": 2096, + "name": "DUP3", + "source": 18 + }, + { + "begin": 405, + "end": 2096, + "name": "DUP2", + "source": 18 + }, + { + "begin": 405, + "end": 2096, + "name": "RETURN", + "source": 18 + } + ], + ".data": { + "0": { + ".auxdata": "a2646970667358221220b00d0cee4061dc303d853fadda969d1de6324d7d0f32be48bae08404d30b621f64736f6c63430008120033", + ".code": [ + { + "begin": 405, + "end": 2096, + "name": "PUSHDEPLOYADDRESS", + "source": 18 + }, + { + "begin": 405, + "end": 2096, + "name": "ADDRESS", + "source": 18 + }, + { + "begin": 405, + "end": 2096, + "name": "EQ", + "source": 18 + }, + { + "begin": 405, + "end": 2096, + "name": "PUSH", + "source": 18, + "value": "80" + }, + { + "begin": 405, + "end": 2096, + "name": "PUSH", + "source": 18, + "value": "40" + }, + { + "begin": 405, + "end": 2096, + "name": "MSTORE", + "source": 18 + }, + { + "begin": 405, + "end": 2096, + "name": "PUSH", + "source": 18, + "value": "0" + }, + { + "begin": 405, + "end": 2096, + "name": "DUP1", + "source": 18 + }, + { + "begin": 405, + "end": 2096, + "name": "REVERT", + "source": 18 + } + ] + } + }, + "sourceList": [ + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/interfaces/IERC1271Wallet.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleERC165.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleOnlyDelegatecall.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCalls.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCreator.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol", + "#utility.yul" + ] + }, + "methodIdentifiers": {} + }, + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"author\":\"Agustin Aguilar (aa@horizon.io)\",\"details\":\"These functions do not check if the input index is within the bounds of the data array. Reading out of bounds may return dirty values.\",\"kind\":\"dev\",\"methods\":{},\"title\":\"Library for reading data from bytes arrays\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"This library contains functions for reading data from bytes arrays.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol\":\"LibBytes\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":500000},\"remappings\":[\":@0xsequence/contracts-library/=src/\",\":@0xsequence/erc-1155/=lib/0xsequence/erc-1155/src/\",\":@0xsequence/erc20-meta-token/=lib/0xsequence/erc20-meta-token/src/\",\":@openzeppelin/=lib/openzeppelin/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc721a-upgradeable/=lib/chiru-labs/erc721a-upgradeable/\",\":erc721a/=lib/chiru-labs/erc721a/\",\":forge-std/=lib/forge-std/src/\",\":murky/=lib/murky/src/\",\":solady/=lib/solady/src/\"]},\"sources\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol\":{\"keccak256\":\"0xd780faf34527a323c96577c57370d175a2b6149db7ebea0937592eb389e52805\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://7a41a47e72f5761d912367c041ddab41620175d63059ad71ff681a87d8cf0e98\",\"dweb:/ipfs/QmfEFuLaVyx9vQc83dS48wTcLtbBiWTNMdHSi5hAWA379i\"]}},\"version\":1}", + "storageLayout": { + "storage": [], + "types": null + }, + "userdoc": { + "kind": "user", + "methods": {}, + "notice": "This library contains functions for reading data from bytes arrays.", + "version": 1 + } + } + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol": { + "LibBytesPointer": { + "abi": [], + "devdoc": { + "author": "Agustin Aguilar (aa@horizon.io)", + "details": "These functions do not check if the input index is within the bounds of the data array. Reading out of bounds may return dirty values.", + "kind": "dev", + "methods": {}, + "title": "Library for reading data from bytes arrays with a pointer", + "version": 1 + }, + "evm": { + "assembly": " /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":435:4565 library LibBytesPointer {... */\n dataSize(sub_0)\n dataOffset(sub_0)\n 0x0b\n dup3\n dup3\n dup3\n codecopy\n dup1\n mload\n 0x00\n byte\n 0x73\n eq\n tag_1\n jumpi\n mstore(0x00, shl(0xe0, 0x4e487b71))\n mstore(0x04, 0x00)\n revert(0x00, 0x24)\ntag_1:\n mstore(0x00, address)\n 0x73\n dup2\n mstore8\n dup3\n dup2\n return\nstop\n\nsub_0: assembly {\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":435:4565 library LibBytesPointer {... */\n eq(address, deployTimeAddress())\n mstore(0x40, 0x80)\n 0x00\n dup1\n revert\n\n auxdata: 0xa2646970667358221220d0f4a33b1bd37a24b174a2b3b0b481e96309d638af5db4e4de3ac1de1aa243ff64736f6c63430008120033\n}\n", + "bytecode": { + "functionDebugData": {}, + "generatedSources": [], + "linkReferences": {}, + "object": "60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220d0f4a33b1bd37a24b174a2b3b0b481e96309d638af5db4e4de3ac1de1aa243ff64736f6c63430008120033", + "opcodes": "PUSH1 0x56 PUSH1 0x37 PUSH1 0xB DUP3 DUP3 DUP3 CODECOPY DUP1 MLOAD PUSH1 0x0 BYTE PUSH1 0x73 EQ PUSH1 0x2A JUMPI PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x0 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST ADDRESS PUSH1 0x0 MSTORE PUSH1 0x73 DUP2 MSTORE8 DUP3 DUP2 RETURN INVALID PUSH20 0x0 ADDRESS EQ PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 0xD0 DELEGATECALL LOG3 EXTCODESIZE SHL 0xD3 PUSH27 0x24B174A2B3B0B481E96309D638AF5DB4E4DE3AC1DE1AA243FF6473 PUSH16 0x6C634300081200330000000000000000 ", + "sourceMap": "435:4130:19:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;435:4130:19;;;;;;;;;;;;;;;;;" + }, + "deployedBytecode": { + "functionDebugData": {}, + "generatedSources": [], + "immutableReferences": {}, + "linkReferences": {}, + "object": "73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220d0f4a33b1bd37a24b174a2b3b0b481e96309d638af5db4e4de3ac1de1aa243ff64736f6c63430008120033", + "opcodes": "PUSH20 0x0 ADDRESS EQ PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 0xD0 DELEGATECALL LOG3 EXTCODESIZE SHL 0xD3 PUSH27 0x24B174A2B3B0B481E96309D638AF5DB4E4DE3AC1DE1AA243FF6473 PUSH16 0x6C634300081200330000000000000000 ", + "sourceMap": "435:4130:19:-:0;;;;;;;;" + }, + "gasEstimates": { + "creation": { + "codeDepositCost": "17200", + "executionCost": "103", + "totalCost": "17303" + }, + "internal": { + "readBytes32(bytes calldata,uint256)": "infinite", + "readFirstUint16(bytes calldata)": "infinite", + "readUint16(bytes calldata,uint256)": "infinite", + "readUint24(bytes calldata,uint256)": "infinite", + "readUint64(bytes calldata,uint256)": "infinite", + "readUint8(bytes calldata,uint256)": "infinite", + "readUint8Address(bytes calldata,uint256)": "infinite" + } + }, + "legacyAssembly": { + ".code": [ + { + "begin": 435, + "end": 4565, + "name": "PUSH #[$]", + "source": 19, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 435, + "end": 4565, + "name": "PUSH [$]", + "source": 19, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 435, + "end": 4565, + "name": "PUSH", + "source": 19, + "value": "B" + }, + { + "begin": 435, + "end": 4565, + "name": "DUP3", + "source": 19 + }, + { + "begin": 435, + "end": 4565, + "name": "DUP3", + "source": 19 + }, + { + "begin": 435, + "end": 4565, + "name": "DUP3", + "source": 19 + }, + { + "begin": 435, + "end": 4565, + "name": "CODECOPY", + "source": 19 + }, + { + "begin": 435, + "end": 4565, + "name": "DUP1", + "source": 19 + }, + { + "begin": 435, + "end": 4565, + "name": "MLOAD", + "source": 19 + }, + { + "begin": 435, + "end": 4565, + "name": "PUSH", + "source": 19, + "value": "0" + }, + { + "begin": 435, + "end": 4565, + "name": "BYTE", + "source": 19 + }, + { + "begin": 435, + "end": 4565, + "name": "PUSH", + "source": 19, + "value": "73" + }, + { + "begin": 435, + "end": 4565, + "name": "EQ", + "source": 19 + }, + { + "begin": 435, + "end": 4565, + "name": "PUSH [tag]", + "source": 19, + "value": "1" + }, + { + "begin": 435, + "end": 4565, + "name": "JUMPI", + "source": 19 + }, + { + "begin": -1, + "end": -1, + "name": "PUSH", + "source": -1, + "value": "4E487B71" + }, + { + "begin": -1, + "end": -1, + "name": "PUSH", + "source": -1, + "value": "E0" + }, + { + "begin": -1, + "end": -1, + "name": "SHL", + "source": -1 + }, + { + "begin": 435, + "end": 4565, + "name": "PUSH", + "source": 19, + "value": "0" + }, + { + "begin": 435, + "end": 4565, + "name": "MSTORE", + "source": 19 + }, + { + "begin": 435, + "end": 4565, + "name": "PUSH", + "source": 19, + "value": "0" + }, + { + "begin": 435, + "end": 4565, + "name": "PUSH", + "source": 19, + "value": "4" + }, + { + "begin": 435, + "end": 4565, + "name": "MSTORE", + "source": 19 + }, + { + "begin": 435, + "end": 4565, + "name": "PUSH", + "source": 19, + "value": "24" + }, + { + "begin": 435, + "end": 4565, + "name": "PUSH", + "source": 19, + "value": "0" + }, + { + "begin": 435, + "end": 4565, + "name": "REVERT", + "source": 19 + }, + { + "begin": 435, + "end": 4565, + "name": "tag", + "source": 19, + "value": "1" + }, + { + "begin": 435, + "end": 4565, + "name": "JUMPDEST", + "source": 19 + }, + { + "begin": 435, + "end": 4565, + "name": "ADDRESS", + "source": 19 + }, + { + "begin": 435, + "end": 4565, + "name": "PUSH", + "source": 19, + "value": "0" + }, + { + "begin": 435, + "end": 4565, + "name": "MSTORE", + "source": 19 + }, + { + "begin": 435, + "end": 4565, + "name": "PUSH", + "source": 19, + "value": "73" + }, + { + "begin": 435, + "end": 4565, + "name": "DUP2", + "source": 19 + }, + { + "begin": 435, + "end": 4565, + "name": "MSTORE8", + "source": 19 + }, + { + "begin": 435, + "end": 4565, + "name": "DUP3", + "source": 19 + }, + { + "begin": 435, + "end": 4565, + "name": "DUP2", + "source": 19 + }, + { + "begin": 435, + "end": 4565, + "name": "RETURN", + "source": 19 + } + ], + ".data": { + "0": { + ".auxdata": "a2646970667358221220d0f4a33b1bd37a24b174a2b3b0b481e96309d638af5db4e4de3ac1de1aa243ff64736f6c63430008120033", + ".code": [ + { + "begin": 435, + "end": 4565, + "name": "PUSHDEPLOYADDRESS", + "source": 19 + }, + { + "begin": 435, + "end": 4565, + "name": "ADDRESS", + "source": 19 + }, + { + "begin": 435, + "end": 4565, + "name": "EQ", + "source": 19 + }, + { + "begin": 435, + "end": 4565, + "name": "PUSH", + "source": 19, + "value": "80" + }, + { + "begin": 435, + "end": 4565, + "name": "PUSH", + "source": 19, + "value": "40" + }, + { + "begin": 435, + "end": 4565, + "name": "MSTORE", + "source": 19 + }, + { + "begin": 435, + "end": 4565, + "name": "PUSH", + "source": 19, + "value": "0" + }, + { + "begin": 435, + "end": 4565, + "name": "DUP1", + "source": 19 + }, + { + "begin": 435, + "end": 4565, + "name": "REVERT", + "source": 19 + } + ] + } + }, + "sourceList": [ + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/interfaces/IERC1271Wallet.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleERC165.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleOnlyDelegatecall.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCalls.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCreator.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol", + "#utility.yul" + ] + }, + "methodIdentifiers": {} + }, + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"author\":\"Agustin Aguilar (aa@horizon.io)\",\"details\":\"These functions do not check if the input index is within the bounds of the data array. Reading out of bounds may return dirty values.\",\"kind\":\"dev\",\"methods\":{},\"title\":\"Library for reading data from bytes arrays with a pointer\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"This library contains functions for reading data from bytes arrays with a pointer.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":\"LibBytesPointer\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":500000},\"remappings\":[\":@0xsequence/contracts-library/=src/\",\":@0xsequence/erc-1155/=lib/0xsequence/erc-1155/src/\",\":@0xsequence/erc20-meta-token/=lib/0xsequence/erc20-meta-token/src/\",\":@openzeppelin/=lib/openzeppelin/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc721a-upgradeable/=lib/chiru-labs/erc721a-upgradeable/\",\":erc721a/=lib/chiru-labs/erc721a/\",\":forge-std/=lib/forge-std/src/\",\":murky/=lib/murky/src/\",\":solady/=lib/solady/src/\"]},\"sources\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol\":{\"keccak256\":\"0xbda56396592db18a248d4062cd36abd586a11d92a2d25483d8c597f890859b15\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://a6ee93bcb7ccd1d1b8979c9530b1ca452d0757794995b62793b6e197670b9f25\",\"dweb:/ipfs/QmbNkhTPzF1YgU4Qgu4SRFXZ8AwFjyG18EzuMZ32anrQ4Y\"]}},\"version\":1}", + "storageLayout": { + "storage": [], + "types": null + }, + "userdoc": { + "kind": "user", + "methods": {}, + "notice": "This library contains functions for reading data from bytes arrays with a pointer.", + "version": 1 + } + } + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol": { + "LibOptim": { + "abi": [], + "devdoc": { + "author": "Agustin Aguilar (aa@horizon.io)", + "kind": "dev", + "methods": {}, + "title": "Library for optimized EVM operations", + "version": 1 + }, + "evm": { + "assembly": " /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":244:2587 library LibOptim {... */\n dataSize(sub_0)\n dataOffset(sub_0)\n 0x0b\n dup3\n dup3\n dup3\n codecopy\n dup1\n mload\n 0x00\n byte\n 0x73\n eq\n tag_1\n jumpi\n mstore(0x00, shl(0xe0, 0x4e487b71))\n mstore(0x04, 0x00)\n revert(0x00, 0x24)\ntag_1:\n mstore(0x00, address)\n 0x73\n dup2\n mstore8\n dup3\n dup2\n return\nstop\n\nsub_0: assembly {\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":244:2587 library LibOptim {... */\n eq(address, deployTimeAddress())\n mstore(0x40, 0x80)\n 0x00\n dup1\n revert\n\n auxdata: 0xa26469706673582212205f4f74640fb3a38d4d73f90f221f7f681ee2035d59f6b9d140c2e9aad1ae2bac64736f6c63430008120033\n}\n", + "bytecode": { + "functionDebugData": {}, + "generatedSources": [], + "linkReferences": {}, + "object": "60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212205f4f74640fb3a38d4d73f90f221f7f681ee2035d59f6b9d140c2e9aad1ae2bac64736f6c63430008120033", + "opcodes": "PUSH1 0x56 PUSH1 0x37 PUSH1 0xB DUP3 DUP3 DUP3 CODECOPY DUP1 MLOAD PUSH1 0x0 BYTE PUSH1 0x73 EQ PUSH1 0x2A JUMPI PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x0 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST ADDRESS PUSH1 0x0 MSTORE PUSH1 0x73 DUP2 MSTORE8 DUP3 DUP2 RETURN INVALID PUSH20 0x0 ADDRESS EQ PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 0x5F 0x4F PUSH21 0x640FB3A38D4D73F90F221F7F681EE2035D59F6B9D1 BLOCKHASH 0xC2 0xE9 0xAA 0xD1 0xAE 0x2B 0xAC PUSH5 0x736F6C6343 STOP ADDMOD SLT STOP CALLER ", + "sourceMap": "244:2343:20:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;244:2343:20;;;;;;;;;;;;;;;;;" + }, + "deployedBytecode": { + "functionDebugData": {}, + "generatedSources": [], + "immutableReferences": {}, + "linkReferences": {}, + "object": "73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212205f4f74640fb3a38d4d73f90f221f7f681ee2035d59f6b9d140c2e9aad1ae2bac64736f6c63430008120033", + "opcodes": "PUSH20 0x0 ADDRESS EQ PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 0x5F 0x4F PUSH21 0x640FB3A38D4D73F90F221F7F681EE2035D59F6B9D1 BLOCKHASH 0xC2 0xE9 0xAA 0xD1 0xAE 0x2B 0xAC PUSH5 0x736F6C6343 STOP ADDMOD SLT STOP CALLER ", + "sourceMap": "244:2343:20:-:0;;;;;;;;" + }, + "gasEstimates": { + "creation": { + "codeDepositCost": "17200", + "executionCost": "103", + "totalCost": "17303" + }, + "internal": { + "call(address,uint256,uint256,bytes calldata)": "infinite", + "delegatecall(address,uint256,bytes calldata)": "infinite", + "fkeccak256(bytes32,bytes32)": "infinite", + "returnData()": "infinite" + } + }, + "legacyAssembly": { + ".code": [ + { + "begin": 244, + "end": 2587, + "name": "PUSH #[$]", + "source": 20, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 244, + "end": 2587, + "name": "PUSH [$]", + "source": 20, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 244, + "end": 2587, + "name": "PUSH", + "source": 20, + "value": "B" + }, + { + "begin": 244, + "end": 2587, + "name": "DUP3", + "source": 20 + }, + { + "begin": 244, + "end": 2587, + "name": "DUP3", + "source": 20 + }, + { + "begin": 244, + "end": 2587, + "name": "DUP3", + "source": 20 + }, + { + "begin": 244, + "end": 2587, + "name": "CODECOPY", + "source": 20 + }, + { + "begin": 244, + "end": 2587, + "name": "DUP1", + "source": 20 + }, + { + "begin": 244, + "end": 2587, + "name": "MLOAD", + "source": 20 + }, + { + "begin": 244, + "end": 2587, + "name": "PUSH", + "source": 20, + "value": "0" + }, + { + "begin": 244, + "end": 2587, + "name": "BYTE", + "source": 20 + }, + { + "begin": 244, + "end": 2587, + "name": "PUSH", + "source": 20, + "value": "73" + }, + { + "begin": 244, + "end": 2587, + "name": "EQ", + "source": 20 + }, + { + "begin": 244, + "end": 2587, + "name": "PUSH [tag]", + "source": 20, + "value": "1" + }, + { + "begin": 244, + "end": 2587, + "name": "JUMPI", + "source": 20 + }, + { + "begin": -1, + "end": -1, + "name": "PUSH", + "source": -1, + "value": "4E487B71" + }, + { + "begin": -1, + "end": -1, + "name": "PUSH", + "source": -1, + "value": "E0" + }, + { + "begin": -1, + "end": -1, + "name": "SHL", + "source": -1 + }, + { + "begin": 244, + "end": 2587, + "name": "PUSH", + "source": 20, + "value": "0" + }, + { + "begin": 244, + "end": 2587, + "name": "MSTORE", + "source": 20 + }, + { + "begin": 244, + "end": 2587, + "name": "PUSH", + "source": 20, + "value": "0" + }, + { + "begin": 244, + "end": 2587, + "name": "PUSH", + "source": 20, + "value": "4" + }, + { + "begin": 244, + "end": 2587, + "name": "MSTORE", + "source": 20 + }, + { + "begin": 244, + "end": 2587, + "name": "PUSH", + "source": 20, + "value": "24" + }, + { + "begin": 244, + "end": 2587, + "name": "PUSH", + "source": 20, + "value": "0" + }, + { + "begin": 244, + "end": 2587, + "name": "REVERT", + "source": 20 + }, + { + "begin": 244, + "end": 2587, + "name": "tag", + "source": 20, + "value": "1" + }, + { + "begin": 244, + "end": 2587, + "name": "JUMPDEST", + "source": 20 + }, + { + "begin": 244, + "end": 2587, + "name": "ADDRESS", + "source": 20 + }, + { + "begin": 244, + "end": 2587, + "name": "PUSH", + "source": 20, + "value": "0" + }, + { + "begin": 244, + "end": 2587, + "name": "MSTORE", + "source": 20 + }, + { + "begin": 244, + "end": 2587, + "name": "PUSH", + "source": 20, + "value": "73" + }, + { + "begin": 244, + "end": 2587, + "name": "DUP2", + "source": 20 + }, + { + "begin": 244, + "end": 2587, + "name": "MSTORE8", + "source": 20 + }, + { + "begin": 244, + "end": 2587, + "name": "DUP3", + "source": 20 + }, + { + "begin": 244, + "end": 2587, + "name": "DUP2", + "source": 20 + }, + { + "begin": 244, + "end": 2587, + "name": "RETURN", + "source": 20 + } + ], + ".data": { + "0": { + ".auxdata": "a26469706673582212205f4f74640fb3a38d4d73f90f221f7f681ee2035d59f6b9d140c2e9aad1ae2bac64736f6c63430008120033", + ".code": [ + { + "begin": 244, + "end": 2587, + "name": "PUSHDEPLOYADDRESS", + "source": 20 + }, + { + "begin": 244, + "end": 2587, + "name": "ADDRESS", + "source": 20 + }, + { + "begin": 244, + "end": 2587, + "name": "EQ", + "source": 20 + }, + { + "begin": 244, + "end": 2587, + "name": "PUSH", + "source": 20, + "value": "80" + }, + { + "begin": 244, + "end": 2587, + "name": "PUSH", + "source": 20, + "value": "40" + }, + { + "begin": 244, + "end": 2587, + "name": "MSTORE", + "source": 20 + }, + { + "begin": 244, + "end": 2587, + "name": "PUSH", + "source": 20, + "value": "0" + }, + { + "begin": 244, + "end": 2587, + "name": "DUP1", + "source": 20 + }, + { + "begin": 244, + "end": 2587, + "name": "REVERT", + "source": 20 + } + ] + } + }, + "sourceList": [ + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/interfaces/IERC1271Wallet.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleERC165.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleOnlyDelegatecall.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCalls.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCreator.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol", + "#utility.yul" + ] + }, + "methodIdentifiers": {} + }, + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"author\":\"Agustin Aguilar (aa@horizon.io)\",\"kind\":\"dev\",\"methods\":{},\"title\":\"Library for optimized EVM operations\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"This library contains functions for optimizing certain EVM operations.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":\"LibOptim\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":500000},\"remappings\":[\":@0xsequence/contracts-library/=src/\",\":@0xsequence/erc-1155/=lib/0xsequence/erc-1155/src/\",\":@0xsequence/erc20-meta-token/=lib/0xsequence/erc20-meta-token/src/\",\":@openzeppelin/=lib/openzeppelin/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc721a-upgradeable/=lib/chiru-labs/erc721a-upgradeable/\",\":erc721a/=lib/chiru-labs/erc721a/\",\":forge-std/=lib/forge-std/src/\",\":murky/=lib/murky/src/\",\":solady/=lib/solady/src/\"]},\"sources\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol\":{\"keccak256\":\"0x4c558b8c9d0dff2322d5d812e83a3abe25a9e60c8f646507f8a9c7fa2a2453af\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://6f0796c75d117770e220c136b60d96b5cf1d4875ccbbd0afb564ed27aa220335\",\"dweb:/ipfs/QmQxYm6CMCqJiKsB3sguqWu8rggmaQgpuq8BZhAEveqNAM\"]}},\"version\":1}", + "storageLayout": { + "storage": [], + "types": null + }, + "userdoc": { + "kind": "user", + "methods": {}, + "notice": "This library contains functions for optimizing certain EVM operations.", + "version": 1 + } + } + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol": { + "SignatureValidator": { + "abi": [ + { + "inputs": [], + "name": "EmptySignature", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + }, + { + "internalType": "bytes32", + "name": "_s", + "type": "bytes32" + } + ], + "name": "InvalidSValue", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "InvalidSignatureLength", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_v", + "type": "uint256" + } + ], + "name": "InvalidVValue", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + } + ], + "name": "SignerIsAddress0", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "_signature", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_type", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_recoverMode", + "type": "bool" + } + ], + "name": "UnsupportedSignatureType", + "type": "error" + } + ], + "devdoc": { + "details": "Contains logic for signature validation. Signatures from wallet contracts assume ERC-1271 support (https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1271.md) Notes: Methods are strongly inspired by contracts in https://github.com/0xProject/0x-monorepo/blob/development/", + "kind": "dev", + "methods": {}, + "version": 1 + }, + "evm": { + "assembly": " /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":430:5364 library SignatureValidator {... */\n dataSize(sub_0)\n dataOffset(sub_0)\n 0x0b\n dup3\n dup3\n dup3\n codecopy\n dup1\n mload\n 0x00\n byte\n 0x73\n eq\n tag_1\n jumpi\n mstore(0x00, shl(0xe0, 0x4e487b71))\n mstore(0x04, 0x00)\n revert(0x00, 0x24)\ntag_1:\n mstore(0x00, address)\n 0x73\n dup2\n mstore8\n dup3\n dup2\n return\nstop\n\nsub_0: assembly {\n /* \"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":430:5364 library SignatureValidator {... */\n eq(address, deployTimeAddress())\n mstore(0x40, 0x80)\n 0x00\n dup1\n revert\n\n auxdata: 0xa26469706673582212207a75fc4c1f66fe757bfffc4be7a9fe45a8e63a8665fbf6a76ca76ea37740ce0c64736f6c63430008120033\n}\n", + "bytecode": { + "functionDebugData": {}, + "generatedSources": [], + "linkReferences": {}, + "object": "60566037600b82828239805160001a607314602a57634e487b7160e01b600052600060045260246000fd5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212207a75fc4c1f66fe757bfffc4be7a9fe45a8e63a8665fbf6a76ca76ea37740ce0c64736f6c63430008120033", + "opcodes": "PUSH1 0x56 PUSH1 0x37 PUSH1 0xB DUP3 DUP3 DUP3 CODECOPY DUP1 MLOAD PUSH1 0x0 BYTE PUSH1 0x73 EQ PUSH1 0x2A JUMPI PUSH4 0x4E487B71 PUSH1 0xE0 SHL PUSH1 0x0 MSTORE PUSH1 0x0 PUSH1 0x4 MSTORE PUSH1 0x24 PUSH1 0x0 REVERT JUMPDEST ADDRESS PUSH1 0x0 MSTORE PUSH1 0x73 DUP2 MSTORE8 DUP3 DUP2 RETURN INVALID PUSH20 0x0 ADDRESS EQ PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 PUSH27 0x75FC4C1F66FE757BFFFC4BE7A9FE45A8E63A8665FBF6A76CA76EA3 PUSH24 0x40CE0C64736F6C6343000812003300000000000000000000 ", + "sourceMap": "430:4934:21:-:0;;;;;;;;;;;;;;;-1:-1:-1;;;430:4934:21;;;;;;;;;;;;;;;;;" + }, + "deployedBytecode": { + "functionDebugData": {}, + "generatedSources": [], + "immutableReferences": {}, + "linkReferences": {}, + "object": "73000000000000000000000000000000000000000030146080604052600080fdfea26469706673582212207a75fc4c1f66fe757bfffc4be7a9fe45a8e63a8665fbf6a76ca76ea37740ce0c64736f6c63430008120033", + "opcodes": "PUSH20 0x0 ADDRESS EQ PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x0 DUP1 REVERT INVALID LOG2 PUSH5 0x6970667358 0x22 SLT KECCAK256 PUSH27 0x75FC4C1F66FE757BFFFC4BE7A9FE45A8E63A8665FBF6A76CA76EA3 PUSH24 0x40CE0C64736F6C6343000812003300000000000000000000 ", + "sourceMap": "430:4934:21:-:0;;;;;;;;" + }, + "gasEstimates": { + "creation": { + "codeDepositCost": "17200", + "executionCost": "103", + "totalCost": "17303" + }, + "internal": { + "isValidSignature(bytes32,address,bytes calldata)": "infinite", + "recoverSigner(bytes32,bytes calldata)": "infinite" + } + }, + "legacyAssembly": { + ".code": [ + { + "begin": 430, + "end": 5364, + "name": "PUSH #[$]", + "source": 21, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 430, + "end": 5364, + "name": "PUSH [$]", + "source": 21, + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "begin": 430, + "end": 5364, + "name": "PUSH", + "source": 21, + "value": "B" + }, + { + "begin": 430, + "end": 5364, + "name": "DUP3", + "source": 21 + }, + { + "begin": 430, + "end": 5364, + "name": "DUP3", + "source": 21 + }, + { + "begin": 430, + "end": 5364, + "name": "DUP3", + "source": 21 + }, + { + "begin": 430, + "end": 5364, + "name": "CODECOPY", + "source": 21 + }, + { + "begin": 430, + "end": 5364, + "name": "DUP1", + "source": 21 + }, + { + "begin": 430, + "end": 5364, + "name": "MLOAD", + "source": 21 + }, + { + "begin": 430, + "end": 5364, + "name": "PUSH", + "source": 21, + "value": "0" + }, + { + "begin": 430, + "end": 5364, + "name": "BYTE", + "source": 21 + }, + { + "begin": 430, + "end": 5364, + "name": "PUSH", + "source": 21, + "value": "73" + }, + { + "begin": 430, + "end": 5364, + "name": "EQ", + "source": 21 + }, + { + "begin": 430, + "end": 5364, + "name": "PUSH [tag]", + "source": 21, + "value": "1" + }, + { + "begin": 430, + "end": 5364, + "name": "JUMPI", + "source": 21 + }, + { + "begin": -1, + "end": -1, + "name": "PUSH", + "source": -1, + "value": "4E487B71" + }, + { + "begin": -1, + "end": -1, + "name": "PUSH", + "source": -1, + "value": "E0" + }, + { + "begin": -1, + "end": -1, + "name": "SHL", + "source": -1 + }, + { + "begin": 430, + "end": 5364, + "name": "PUSH", + "source": 21, + "value": "0" + }, + { + "begin": 430, + "end": 5364, + "name": "MSTORE", + "source": 21 + }, + { + "begin": 430, + "end": 5364, + "name": "PUSH", + "source": 21, + "value": "0" + }, + { + "begin": 430, + "end": 5364, + "name": "PUSH", + "source": 21, + "value": "4" + }, + { + "begin": 430, + "end": 5364, + "name": "MSTORE", + "source": 21 + }, + { + "begin": 430, + "end": 5364, + "name": "PUSH", + "source": 21, + "value": "24" + }, + { + "begin": 430, + "end": 5364, + "name": "PUSH", + "source": 21, + "value": "0" + }, + { + "begin": 430, + "end": 5364, + "name": "REVERT", + "source": 21 + }, + { + "begin": 430, + "end": 5364, + "name": "tag", + "source": 21, + "value": "1" + }, + { + "begin": 430, + "end": 5364, + "name": "JUMPDEST", + "source": 21 + }, + { + "begin": 430, + "end": 5364, + "name": "ADDRESS", + "source": 21 + }, + { + "begin": 430, + "end": 5364, + "name": "PUSH", + "source": 21, + "value": "0" + }, + { + "begin": 430, + "end": 5364, + "name": "MSTORE", + "source": 21 + }, + { + "begin": 430, + "end": 5364, + "name": "PUSH", + "source": 21, + "value": "73" + }, + { + "begin": 430, + "end": 5364, + "name": "DUP2", + "source": 21 + }, + { + "begin": 430, + "end": 5364, + "name": "MSTORE8", + "source": 21 + }, + { + "begin": 430, + "end": 5364, + "name": "DUP3", + "source": 21 + }, + { + "begin": 430, + "end": 5364, + "name": "DUP2", + "source": 21 + }, + { + "begin": 430, + "end": 5364, + "name": "RETURN", + "source": 21 + } + ], + ".data": { + "0": { + ".auxdata": "a26469706673582212207a75fc4c1f66fe757bfffc4be7a9fe45a8e63a8665fbf6a76ca76ea37740ce0c64736f6c63430008120033", + ".code": [ + { + "begin": 430, + "end": 5364, + "name": "PUSHDEPLOYADDRESS", + "source": 21 + }, + { + "begin": 430, + "end": 5364, + "name": "ADDRESS", + "source": 21 + }, + { + "begin": 430, + "end": 5364, + "name": "EQ", + "source": 21 + }, + { + "begin": 430, + "end": 5364, + "name": "PUSH", + "source": 21, + "value": "80" + }, + { + "begin": 430, + "end": 5364, + "name": "PUSH", + "source": 21, + "value": "40" + }, + { + "begin": 430, + "end": 5364, + "name": "MSTORE", + "source": 21 + }, + { + "begin": 430, + "end": 5364, + "name": "PUSH", + "source": 21, + "value": "0" + }, + { + "begin": 430, + "end": 5364, + "name": "DUP1", + "source": 21 + }, + { + "begin": 430, + "end": 5364, + "name": "REVERT", + "source": 21 + } + ] + } + }, + "sourceList": [ + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/interfaces/IERC1271Wallet.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleERC165.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleOnlyDelegatecall.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleAuth.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCalls.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCreator.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol", + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol", + "#utility.yul" + ] + }, + "methodIdentifiers": {} + }, + "metadata": "{\"compiler\":{\"version\":\"0.8.18+commit.87f61d96\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"EmptySignature\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"},{\"internalType\":\"bytes32\",\"name\":\"_s\",\"type\":\"bytes32\"}],\"name\":\"InvalidSValue\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"InvalidSignatureLength\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_v\",\"type\":\"uint256\"}],\"name\":\"InvalidVValue\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"}],\"name\":\"SignerIsAddress0\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_signature\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_type\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"_recoverMode\",\"type\":\"bool\"}],\"name\":\"UnsupportedSignatureType\",\"type\":\"error\"}],\"devdoc\":{\"details\":\"Contains logic for signature validation. Signatures from wallet contracts assume ERC-1271 support (https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1271.md) Notes: Methods are strongly inspired by contracts in https://github.com/0xProject/0x-monorepo/blob/development/\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":\"SignatureValidator\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":500000},\"remappings\":[\":@0xsequence/contracts-library/=src/\",\":@0xsequence/erc-1155/=lib/0xsequence/erc-1155/src/\",\":@0xsequence/erc20-meta-token/=lib/0xsequence/erc20-meta-token/src/\",\":@openzeppelin/=lib/openzeppelin/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc721a-upgradeable/=lib/chiru-labs/erc721a-upgradeable/\",\":erc721a/=lib/chiru-labs/erc721a/\",\":forge-std/=lib/forge-std/src/\",\":murky/=lib/murky/src/\",\":solady/=lib/solady/src/\"]},\"sources\":{\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/interfaces/IERC1271Wallet.sol\":{\"keccak256\":\"0x2d7881bca678833feb385fd59e5d8ad6d596160ab51daa7030372654b3dbc38c\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://010f44c05b7285a55de939f9989727d53dfb87fd2d2534a832a70e0e081bb5f1\",\"dweb:/ipfs/QmQcujWErxjktsKyyiTySaFuR7Vaq6fUA9SUzPkde2txVK\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol\":{\"keccak256\":\"0xd780faf34527a323c96577c57370d175a2b6149db7ebea0937592eb389e52805\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://7a41a47e72f5761d912367c041ddab41620175d63059ad71ff681a87d8cf0e98\",\"dweb:/ipfs/QmfEFuLaVyx9vQc83dS48wTcLtbBiWTNMdHSi5hAWA379i\"]},\"sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol\":{\"keccak256\":\"0x7ac5dd35cbc776693eecfd8e7e86af139c7b054c43be4f97e6c8929417c17dba\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://4a452d8acad5246538ac352887081d732098dcab869c79a43a5f916e7e76f353\",\"dweb:/ipfs/QmeazDSxfKBSGyCGjmk7G79UbvYMRcbr2eUU9ThyqSvNhv\"]}},\"version\":1}", + "storageLayout": { + "storage": [], + "types": null + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + } + } + } + }, + "sources": { + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/interfaces/IERC1271Wallet.sol": { + "ast": { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/interfaces/IERC1271Wallet.sol", + "exportedSymbols": { + "IERC1271Wallet": [ + 22 + ] + }, + "id": 23, + "license": "Apache-2.0", + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 1, + "literals": [ + "solidity", + "0.8", + ".18" + ], + "nodeType": "PragmaDirective", + "src": "39:23:0" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "IERC1271Wallet", + "contractDependencies": [], + "contractKind": "interface", + "fullyImplemented": false, + "id": 22, + "linearizedBaseContracts": [ + 22 + ], + "name": "IERC1271Wallet", + "nameLocation": "75:14:0", + "nodeType": "ContractDefinition", + "nodes": [ + { + "documentation": { + "id": 2, + "nodeType": "StructuredDocumentation", + "src": "95:633:0", + "text": " @notice Verifies whether the provided signature is valid with respect to the provided data\n @dev MUST return the correct magic value if the signature provided is valid for the provided data\n > The bytes4 magic value to return when signature is valid is 0x20c13b0b : bytes4(keccak256(\"isValidSignature(bytes,bytes)\")\n > This function MAY modify Ethereum's state\n @param _data Arbitrary length data signed on the behalf of address(this)\n @param _signature Signature byte array associated with _data\n @return magicValue Magic value 0x20c13b0b if the signature is valid and 0x0 otherwise" + }, + "functionSelector": "20c13b0b", + "id": 11, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "isValidSignature", + "nameLocation": "740:16:0", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 7, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 4, + "mutability": "mutable", + "name": "_data", + "nameLocation": "777:5:0", + "nodeType": "VariableDeclaration", + "scope": 11, + "src": "762:20:0", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 3, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "762:5:0", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 6, + "mutability": "mutable", + "name": "_signature", + "nameLocation": "803:10:0", + "nodeType": "VariableDeclaration", + "scope": 11, + "src": "788:25:0", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 5, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "788:5:0", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "756:58:0" + }, + "returnParameters": { + "id": 10, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 9, + "mutability": "mutable", + "name": "magicValue", + "nameLocation": "857:10:0", + "nodeType": "VariableDeclaration", + "scope": 11, + "src": "850:17:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + }, + "typeName": { + "id": 8, + "name": "bytes4", + "nodeType": "ElementaryTypeName", + "src": "850:6:0", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "visibility": "internal" + } + ], + "src": "849:19:0" + }, + "scope": 22, + "src": "731:138:0", + "stateMutability": "view", + "virtual": false, + "visibility": "external" + }, + { + "documentation": { + "id": 12, + "nodeType": "StructuredDocumentation", + "src": "873:604:0", + "text": " @notice Verifies whether the provided signature is valid with respect to the provided hash\n @dev MUST return the correct magic value if the signature provided is valid for the provided hash\n > The bytes4 magic value to return when signature is valid is 0x20c13b0b : bytes4(keccak256(\"isValidSignature(bytes,bytes)\")\n > This function MAY modify Ethereum's state\n @param _hash keccak256 hash that was signed\n @param _signature Signature byte array associated with _data\n @return magicValue Magic value 0x20c13b0b if the signature is valid and 0x0 otherwise" + }, + "functionSelector": "1626ba7e", + "id": 21, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "isValidSignature", + "nameLocation": "1489:16:0", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 17, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 14, + "mutability": "mutable", + "name": "_hash", + "nameLocation": "1519:5:0", + "nodeType": "VariableDeclaration", + "scope": 21, + "src": "1511:13:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 13, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1511:7:0", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 16, + "mutability": "mutable", + "name": "_signature", + "nameLocation": "1545:10:0", + "nodeType": "VariableDeclaration", + "scope": 21, + "src": "1530:25:0", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 15, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "1530:5:0", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "1505:51:0" + }, + "returnParameters": { + "id": 20, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 19, + "mutability": "mutable", + "name": "magicValue", + "nameLocation": "1599:10:0", + "nodeType": "VariableDeclaration", + "scope": 21, + "src": "1592:17:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + }, + "typeName": { + "id": 18, + "name": "bytes4", + "nodeType": "ElementaryTypeName", + "src": "1592:6:0", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "visibility": "internal" + } + ], + "src": "1591:19:0" + }, + "scope": 22, + "src": "1480:131:0", + "stateMutability": "view", + "virtual": false, + "visibility": "external" + } + ], + "scope": 23, + "src": "65:1548:0", + "usedErrors": [] + } + ], + "src": "39:1574:0" + }, + "id": 0 + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol": { + "ast": { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/GuestModule.sol", + "exportedSymbols": { + "GuestModule": [ + 241 + ], + "IERC1271Wallet": [ + 22 + ], + "IModuleAuth": [ + 1249 + ], + "IModuleCalls": [ + 1313 + ], + "IModuleCreator": [ + 1328 + ], + "LibBytes": [ + 2374 + ], + "LibBytesPointer": [ + 2476 + ], + "LibOptim": [ + 2530 + ], + "ModuleAuth": [ + 564 + ], + "ModuleCalls": [ + 833 + ], + "ModuleCreator": [ + 902 + ], + "ModuleERC165": [ + 920 + ], + "ModuleNonce": [ + 1051 + ], + "ModuleOnlyDelegatecall": [ + 1085 + ], + "ModuleSelfAuth": [ + 1116 + ], + "ModuleStorage": [ + 1179 + ], + "SequenceBaseSig": [ + 2021 + ], + "SequenceChainedSig": [ + 2218 + ], + "SequenceDynamicSig": [ + 2247 + ], + "SequenceNoChainIdSig": [ + 2275 + ], + "SignatureValidator": [ + 2798 + ], + "SubModuleNonce": [ + 2324 + ] + }, + "id": 242, + "license": "Apache-2.0", + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 24, + "literals": [ + "solidity", + "0.8", + ".18" + ], + "nodeType": "PragmaDirective", + "src": "39:23:1" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol", + "file": "../utils/LibOptim.sol", + "id": 25, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 242, + "sourceUnit": 2531, + "src": "64:31:1", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol", + "file": "./commons/submodules/auth/SequenceBaseSig.sol", + "id": 26, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 242, + "sourceUnit": 2022, + "src": "97:55:1", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol", + "file": "./commons/ModuleAuth.sol", + "id": 27, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 242, + "sourceUnit": 565, + "src": "154:34:1", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol", + "file": "./commons/ModuleCalls.sol", + "id": 28, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 242, + "sourceUnit": 834, + "src": "189:35:1", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol", + "file": "./commons/ModuleCreator.sol", + "id": 29, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 242, + "sourceUnit": 903, + "src": "225:37:1", + "symbolAliases": [], + "unitAlias": "" + }, + { + "abstract": false, + "baseContracts": [ + { + "baseName": { + "id": 31, + "name": "ModuleAuth", + "nameLocations": [ + "666:10:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 564, + "src": "666:10:1" + }, + "id": 32, + "nodeType": "InheritanceSpecifier", + "src": "666:10:1" + }, + { + "baseName": { + "id": 33, + "name": "ModuleCalls", + "nameLocations": [ + "680:11:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 833, + "src": "680:11:1" + }, + "id": 34, + "nodeType": "InheritanceSpecifier", + "src": "680:11:1" + }, + { + "baseName": { + "id": 35, + "name": "ModuleCreator", + "nameLocations": [ + "695:13:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 902, + "src": "695:13:1" + }, + "id": 36, + "nodeType": "InheritanceSpecifier", + "src": "695:13:1" + } + ], + "canonicalName": "GuestModule", + "contractDependencies": [], + "contractKind": "contract", + "documentation": { + "id": 30, + "nodeType": "StructuredDocumentation", + "src": "265:374:1", + "text": " GuestModule implements a Sequence wallet without signatures, nonce or replay protection.\n executing transactions using this wallet is not an authenticated process, and can be done by any address.\n @notice This contract is completely public with no security, designed to execute pre-signed transactions\n and use Sequence tools without using the wallets." + }, + "fullyImplemented": true, + "id": 241, + "linearizedBaseContracts": [ + 241, + 902, + 833, + 1051, + 564, + 2218, + 1116, + 1085, + 22, + 920, + 1328, + 1249, + 1313 + ], + "name": "GuestModule", + "nameLocation": "649:11:1", + "nodeType": "ContractDefinition", + "nodes": [ + { + "errorSelector": "230d1ccc", + "id": 40, + "name": "DelegateCallNotAllowed", + "nameLocation": "719:22:1", + "nodeType": "ErrorDefinition", + "parameters": { + "id": 39, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 38, + "mutability": "mutable", + "name": "_index", + "nameLocation": "750:6:1", + "nodeType": "VariableDeclaration", + "scope": 40, + "src": "742:14:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 37, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "742:7:1", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "741:16:1" + }, + "src": "713:45:1" + }, + { + "errorSelector": "a0387940", + "id": 42, + "name": "NotSupported", + "nameLocation": "767:12:1", + "nodeType": "ErrorDefinition", + "parameters": { + "id": 41, + "nodeType": "ParameterList", + "parameters": [], + "src": "779:2:1" + }, + "src": "761:21:1" + }, + { + "baseFunctions": [ + 637 + ], + "body": { + "id": 73, + "nodeType": "Block", + "src": "993:189:1", + "statements": [ + { + "assignments": [ + 56 + ], + "declarations": [ + { + "constant": false, + "id": 56, + "mutability": "mutable", + "name": "txHash", + "nameLocation": "1038:6:1", + "nodeType": "VariableDeclaration", + "scope": 73, + "src": "1030:14:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 55, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1030:7:1", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "id": 67, + "initialValue": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "hexValue": "67756573743a", + "id": 62, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1094:8:1", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_4dfa0bed92fb5c2df0b47ce555e6e6b89f746e856aa9783c634a4987edcbf682", + "typeString": "literal_string \"guest:\"" + }, + "value": "guest:" + }, + { + "id": 63, + "name": "_txs", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 47, + "src": "1104:4:1", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction calldata[] calldata" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_stringliteral_4dfa0bed92fb5c2df0b47ce555e6e6b89f746e856aa9783c634a4987edcbf682", + "typeString": "literal_string \"guest:\"" + }, + { + "typeIdentifier": "t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction calldata[] calldata" + } + ], + "expression": { + "id": 60, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967295, + "src": "1083:3:1", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 61, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "1087:6:1", + "memberName": "encode", + "nodeType": "MemberAccess", + "src": "1083:10:1", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencode_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 64, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1083:26:1", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 59, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967288, + "src": "1073:9:1", + "typeDescriptions": { + "typeIdentifier": "t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$", + "typeString": "function (bytes memory) pure returns (bytes32)" + } + }, + "id": 65, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1073:37:1", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "expression": { + "id": 57, + "name": "SequenceBaseSig", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2021, + "src": "1047:15:1", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_SequenceBaseSig_$2021_$", + "typeString": "type(library SequenceBaseSig)" + } + }, + "id": 58, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "1063:9:1", + "memberName": "subdigest", + "nodeType": "MemberAccess", + "referencedDeclaration": 1394, + "src": "1047:25:1", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$returns$_t_bytes32_$", + "typeString": "function (bytes32) view returns (bytes32)" + } + }, + "id": 66, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1047:64:1", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "1030:81:1" + }, + { + "expression": { + "arguments": [ + { + "id": 69, + "name": "txHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 56, + "src": "1164:6:1", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 70, + "name": "_txs", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 47, + "src": "1172:4:1", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction calldata[] calldata" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction calldata[] calldata" + } + ], + "id": 68, + "name": "_executeGuest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 199, + "src": "1150:13:1", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr_$returns$__$", + "typeString": "function (bytes32,struct IModuleCalls.Transaction calldata[] calldata)" + } + }, + "id": 71, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1150:27:1", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 72, + "nodeType": "ExpressionStatement", + "src": "1150:27:1" + } + ] + }, + "documentation": { + "id": 43, + "nodeType": "StructuredDocumentation", + "src": "786:101:1", + "text": " @notice Allow any caller to execute an action\n @param _txs Transactions to process" + }, + "functionSelector": "7a9a1628", + "id": 74, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "execute", + "nameLocation": "899:7:1", + "nodeType": "FunctionDefinition", + "overrides": { + "id": 53, + "nodeType": "OverrideSpecifier", + "overrides": [], + "src": "984:8:1" + }, + "parameters": { + "id": 52, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 47, + "mutability": "mutable", + "name": "_txs", + "nameLocation": "935:4:1", + "nodeType": "VariableDeclaration", + "scope": 74, + "src": "912:27:1", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction[]" + }, + "typeName": { + "baseType": { + "id": 45, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 44, + "name": "Transaction", + "nameLocations": [ + "912:11:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1292, + "src": "912:11:1" + }, + "referencedDeclaration": 1292, + "src": "912:11:1", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Transaction_$1292_storage_ptr", + "typeString": "struct IModuleCalls.Transaction" + } + }, + "id": 46, + "nodeType": "ArrayTypeName", + "src": "912:13:1", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Transaction_$1292_storage_$dyn_storage_ptr", + "typeString": "struct IModuleCalls.Transaction[]" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 49, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 74, + "src": "945:7:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 48, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "945:7:1", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 51, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 74, + "src": "958:14:1", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 50, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "958:5:1", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "906:70:1" + }, + "returnParameters": { + "id": 54, + "nodeType": "ParameterList", + "parameters": [], + "src": "993:0:1" + }, + "scope": 241, + "src": "890:292:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + }, + { + "baseFunctions": [ + 667 + ], + "body": { + "id": 101, + "nodeType": "Block", + "src": "1364:188:1", + "statements": [ + { + "assignments": [ + 84 + ], + "declarations": [ + { + "constant": false, + "id": 84, + "mutability": "mutable", + "name": "txHash", + "nameLocation": "1409:6:1", + "nodeType": "VariableDeclaration", + "scope": 101, + "src": "1401:14:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 83, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1401:7:1", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "id": 95, + "initialValue": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "hexValue": "73656c663a", + "id": 90, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1465:7:1", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_bf9461da9f9c0123d3a54c61147a274d8fdb5d5c1e488665fb11b9edbbc32845", + "typeString": "literal_string \"self:\"" + }, + "value": "self:" + }, + { + "id": 91, + "name": "_txs", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 79, + "src": "1474:4:1", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction calldata[] calldata" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_stringliteral_bf9461da9f9c0123d3a54c61147a274d8fdb5d5c1e488665fb11b9edbbc32845", + "typeString": "literal_string \"self:\"" + }, + { + "typeIdentifier": "t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction calldata[] calldata" + } + ], + "expression": { + "id": 88, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967295, + "src": "1454:3:1", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 89, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "1458:6:1", + "memberName": "encode", + "nodeType": "MemberAccess", + "src": "1454:10:1", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencode_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 92, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1454:25:1", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 87, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967288, + "src": "1444:9:1", + "typeDescriptions": { + "typeIdentifier": "t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$", + "typeString": "function (bytes memory) pure returns (bytes32)" + } + }, + "id": 93, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1444:36:1", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "expression": { + "id": 85, + "name": "SequenceBaseSig", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2021, + "src": "1418:15:1", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_SequenceBaseSig_$2021_$", + "typeString": "type(library SequenceBaseSig)" + } + }, + "id": 86, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "1434:9:1", + "memberName": "subdigest", + "nodeType": "MemberAccess", + "referencedDeclaration": 1394, + "src": "1418:25:1", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$returns$_t_bytes32_$", + "typeString": "function (bytes32) view returns (bytes32)" + } + }, + "id": 94, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1418:63:1", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "1401:80:1" + }, + { + "expression": { + "arguments": [ + { + "id": 97, + "name": "txHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 84, + "src": "1534:6:1", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 98, + "name": "_txs", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 79, + "src": "1542:4:1", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction calldata[] calldata" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction calldata[] calldata" + } + ], + "id": 96, + "name": "_executeGuest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 199, + "src": "1520:13:1", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr_$returns$__$", + "typeString": "function (bytes32,struct IModuleCalls.Transaction calldata[] calldata)" + } + }, + "id": 99, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1520:27:1", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 100, + "nodeType": "ExpressionStatement", + "src": "1520:27:1" + } + ] + }, + "documentation": { + "id": 75, + "nodeType": "StructuredDocumentation", + "src": "1186:101:1", + "text": " @notice Allow any caller to execute an action\n @param _txs Transactions to process" + }, + "functionSelector": "61c2926c", + "id": 102, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "selfExecute", + "nameLocation": "1299:11:1", + "nodeType": "FunctionDefinition", + "overrides": { + "id": 81, + "nodeType": "OverrideSpecifier", + "overrides": [], + "src": "1355:8:1" + }, + "parameters": { + "id": 80, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 79, + "mutability": "mutable", + "name": "_txs", + "nameLocation": "1339:4:1", + "nodeType": "VariableDeclaration", + "scope": 102, + "src": "1316:27:1", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction[]" + }, + "typeName": { + "baseType": { + "id": 77, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 76, + "name": "Transaction", + "nameLocations": [ + "1316:11:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1292, + "src": "1316:11:1" + }, + "referencedDeclaration": 1292, + "src": "1316:11:1", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Transaction_$1292_storage_ptr", + "typeString": "struct IModuleCalls.Transaction" + } + }, + "id": 78, + "nodeType": "ArrayTypeName", + "src": "1316:13:1", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Transaction_$1292_storage_$dyn_storage_ptr", + "typeString": "struct IModuleCalls.Transaction[]" + } + }, + "visibility": "internal" + } + ], + "src": "1310:37:1" + }, + "returnParameters": { + "id": 82, + "nodeType": "ParameterList", + "parameters": [], + "src": "1364:0:1" + }, + "scope": 241, + "src": "1290:262:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + }, + { + "body": { + "id": 198, + "nodeType": "Block", + "src": "1799:745:1", + "statements": [ + { + "assignments": [ + 113 + ], + "declarations": [ + { + "constant": false, + "id": 113, + "mutability": "mutable", + "name": "size", + "nameLocation": "1840:4:1", + "nodeType": "VariableDeclaration", + "scope": 198, + "src": "1832:12:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 112, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1832:7:1", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 116, + "initialValue": { + "expression": { + "id": 114, + "name": "_txs", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 109, + "src": "1847:4:1", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction calldata[] calldata" + } + }, + "id": 115, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "1852:6:1", + "memberName": "length", + "nodeType": "MemberAccess", + "src": "1847:11:1", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "1832:26:1" + }, + { + "body": { + "id": 196, + "nodeType": "Block", + "src": "1899:641:1", + "statements": [ + { + "assignments": [ + 129 + ], + "declarations": [ + { + "constant": false, + "id": 129, + "mutability": "mutable", + "name": "transaction", + "nameLocation": "1928:11:1", + "nodeType": "VariableDeclaration", + "scope": 196, + "src": "1907:32:1", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Transaction_$1292_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction" + }, + "typeName": { + "id": 128, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 127, + "name": "Transaction", + "nameLocations": [ + "1907:11:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1292, + "src": "1907:11:1" + }, + "referencedDeclaration": 1292, + "src": "1907:11:1", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Transaction_$1292_storage_ptr", + "typeString": "struct IModuleCalls.Transaction" + } + }, + "visibility": "internal" + } + ], + "id": 133, + "initialValue": { + "baseExpression": { + "id": 130, + "name": "_txs", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 109, + "src": "1942:4:1", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction calldata[] calldata" + } + }, + "id": 132, + "indexExpression": { + "id": 131, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 118, + "src": "1947:1:1", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "1942:7:1", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Transaction_$1292_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction calldata" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "1907:42:1" + }, + { + "condition": { + "expression": { + "id": 134, + "name": "transaction", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 129, + "src": "1962:11:1", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Transaction_$1292_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction calldata" + } + }, + "id": 135, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "1974:12:1", + "memberName": "delegateCall", + "nodeType": "MemberAccess", + "referencedDeclaration": 1281, + "src": "1962:24:1", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 140, + "nodeType": "IfStatement", + "src": "1958:62:1", + "trueBody": { + "errorCall": { + "arguments": [ + { + "id": 137, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 118, + "src": "2018:1:1", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 136, + "name": "DelegateCallNotAllowed", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 40, + "src": "1995:22:1", + "typeDescriptions": { + "typeIdentifier": "t_function_error_pure$_t_uint256_$returns$__$", + "typeString": "function (uint256) pure" + } + }, + "id": 138, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1995:25:1", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 139, + "nodeType": "RevertStatement", + "src": "1988:32:1" + } + }, + { + "assignments": [ + 142 + ], + "declarations": [ + { + "constant": false, + "id": 142, + "mutability": "mutable", + "name": "gasLimit", + "nameLocation": "2037:8:1", + "nodeType": "VariableDeclaration", + "scope": 196, + "src": "2029:16:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 141, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2029:7:1", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 145, + "initialValue": { + "expression": { + "id": 143, + "name": "transaction", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 129, + "src": "2048:11:1", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Transaction_$1292_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction calldata" + } + }, + "id": 144, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2060:8:1", + "memberName": "gasLimit", + "nodeType": "MemberAccess", + "referencedDeclaration": 1285, + "src": "2048:20:1", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "2029:39:1" + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 149, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 146, + "name": "gasleft", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967289, + "src": "2080:7:1", + "typeDescriptions": { + "typeIdentifier": "t_function_gasleft_view$__$returns$_t_uint256_$", + "typeString": "function () view returns (uint256)" + } + }, + "id": 147, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2080:9:1", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "id": 148, + "name": "gasLimit", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 142, + "src": "2092:8:1", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "2080:20:1", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 157, + "nodeType": "IfStatement", + "src": "2076:69:1", + "trueBody": { + "errorCall": { + "arguments": [ + { + "id": 151, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 118, + "src": "2122:1:1", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 152, + "name": "gasLimit", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 142, + "src": "2125:8:1", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 153, + "name": "gasleft", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967289, + "src": "2135:7:1", + "typeDescriptions": { + "typeIdentifier": "t_function_gasleft_view$__$returns$_t_uint256_$", + "typeString": "function () view returns (uint256)" + } + }, + "id": 154, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2135:9:1", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 150, + "name": "NotEnoughGas", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1273, + "src": "2109:12:1", + "typeDescriptions": { + "typeIdentifier": "t_function_error_pure$_t_uint256_$_t_uint256_$_t_uint256_$returns$__$", + "typeString": "function (uint256,uint256,uint256) pure" + } + }, + "id": 155, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2109:36:1", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 156, + "nodeType": "RevertStatement", + "src": "2102:43:1" + } + }, + { + "assignments": [ + 159 + ], + "declarations": [ + { + "constant": false, + "id": 159, + "mutability": "mutable", + "name": "success", + "nameLocation": "2159:7:1", + "nodeType": "VariableDeclaration", + "scope": 196, + "src": "2154:12:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 158, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "2154:4:1", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "id": 176, + "initialValue": { + "arguments": [ + { + "expression": { + "id": 162, + "name": "transaction", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 129, + "src": "2192:11:1", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Transaction_$1292_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction calldata" + } + }, + "id": 163, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2204:6:1", + "memberName": "target", + "nodeType": "MemberAccess", + "referencedDeclaration": 1287, + "src": "2192:18:1", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "expression": { + "id": 164, + "name": "transaction", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 129, + "src": "2220:11:1", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Transaction_$1292_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction calldata" + } + }, + "id": 165, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2232:5:1", + "memberName": "value", + "nodeType": "MemberAccess", + "referencedDeclaration": 1289, + "src": "2220:17:1", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 168, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 166, + "name": "gasLimit", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 142, + "src": "2247:8:1", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "hexValue": "30", + "id": 167, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "2259:1:1", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "2247:13:1", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": { + "id": 171, + "name": "gasLimit", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 142, + "src": "2275:8:1", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 172, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "2247:36:1", + "trueExpression": { + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 169, + "name": "gasleft", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967289, + "src": "2263:7:1", + "typeDescriptions": { + "typeIdentifier": "t_function_gasleft_view$__$returns$_t_uint256_$", + "typeString": "function () view returns (uint256)" + } + }, + "id": 170, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2263:9:1", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "expression": { + "id": 173, + "name": "transaction", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 129, + "src": "2293:11:1", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Transaction_$1292_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction calldata" + } + }, + "id": 174, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2305:4:1", + "memberName": "data", + "nodeType": "MemberAccess", + "referencedDeclaration": 1291, + "src": "2293:16:1", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + ], + "expression": { + "id": 160, + "name": "LibOptim", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2530, + "src": "2169:8:1", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_LibOptim_$2530_$", + "typeString": "type(library LibOptim)" + } + }, + "id": 161, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2178:4:1", + "memberName": "call", + "nodeType": "MemberAccess", + "referencedDeclaration": 2515, + "src": "2169:13:1", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_uint256_$_t_uint256_$_t_bytes_calldata_ptr_$returns$_t_bool_$", + "typeString": "function (address,uint256,uint256,bytes calldata) returns (bool)" + } + }, + "id": 175, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2169:148:1", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "2154:163:1" + }, + { + "condition": { + "id": 177, + "name": "success", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 159, + "src": "2330:7:1", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": { + "id": 194, + "nodeType": "Block", + "src": "2391:143:1", + "statements": [ + { + "expression": { + "arguments": [ + { + "expression": { + "id": 185, + "name": "transaction", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 129, + "src": "2425:11:1", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Transaction_$1292_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction calldata" + } + }, + "id": 186, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2437:13:1", + "memberName": "revertOnError", + "nodeType": "MemberAccess", + "referencedDeclaration": 1283, + "src": "2425:25:1", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "id": 187, + "name": "_txHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 105, + "src": "2462:7:1", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 188, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 118, + "src": "2481:1:1", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "arguments": [], + "expression": { + "argumentTypes": [], + "expression": { + "id": 189, + "name": "LibOptim", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2530, + "src": "2494:8:1", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_LibOptim_$2530_$", + "typeString": "type(library LibOptim)" + } + }, + "id": 190, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2503:10:1", + "memberName": "returnData", + "nodeType": "MemberAccess", + "referencedDeclaration": 2499, + "src": "2494:19:1", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 191, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2494:21:1", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 184, + "name": "_revertBytes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 807, + "src": "2401:12:1", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bool_$_t_bytes32_$_t_uint256_$_t_bytes_memory_ptr_$returns$__$", + "typeString": "function (bool,bytes32,uint256,bytes memory)" + } + }, + "id": 192, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2401:124:1", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 193, + "nodeType": "ExpressionStatement", + "src": "2401:124:1" + } + ] + }, + "id": 195, + "nodeType": "IfStatement", + "src": "2326:208:1", + "trueBody": { + "id": 183, + "nodeType": "Block", + "src": "2339:46:1", + "statements": [ + { + "eventCall": { + "arguments": [ + { + "id": 179, + "name": "_txHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 105, + "src": "2365:7:1", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 180, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 118, + "src": "2374:1:1", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 178, + "name": "TxExecuted", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1265, + "src": "2354:10:1", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_bytes32_$_t_uint256_$returns$__$", + "typeString": "function (bytes32,uint256)" + } + }, + "id": 181, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2354:22:1", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 182, + "nodeType": "EmitStatement", + "src": "2349:27:1" + } + ] + } + } + ] + }, + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 123, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 121, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 118, + "src": "1884:1:1", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "id": 122, + "name": "size", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 113, + "src": "1888:4:1", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "1884:8:1", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 197, + "initializationExpression": { + "assignments": [ + 118 + ], + "declarations": [ + { + "constant": false, + "id": 118, + "mutability": "mutable", + "name": "i", + "nameLocation": "1877:1:1", + "nodeType": "VariableDeclaration", + "scope": 197, + "src": "1869:9:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 117, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1869:7:1", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 120, + "initialValue": { + "hexValue": "30", + "id": 119, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1881:1:1", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "nodeType": "VariableDeclarationStatement", + "src": "1869:13:1" + }, + "loopExpression": { + "expression": { + "id": 125, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": false, + "src": "1894:3:1", + "subExpression": { + "id": 124, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 118, + "src": "1894:1:1", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 126, + "nodeType": "ExpressionStatement", + "src": "1894:3:1" + }, + "nodeType": "ForStatement", + "src": "1864:676:1" + } + ] + }, + "documentation": { + "id": 103, + "nodeType": "StructuredDocumentation", + "src": "1556:151:1", + "text": " @notice Executes a list of transactions\n @param _txHash Hash of the batch of transactions\n @param _txs Transactions to execute" + }, + "id": 199, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "_executeGuest", + "nameLocation": "1719:13:1", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 110, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 105, + "mutability": "mutable", + "name": "_txHash", + "nameLocation": "1746:7:1", + "nodeType": "VariableDeclaration", + "scope": 199, + "src": "1738:15:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 104, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1738:7:1", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 109, + "mutability": "mutable", + "name": "_txs", + "nameLocation": "1782:4:1", + "nodeType": "VariableDeclaration", + "scope": 199, + "src": "1759:27:1", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction[]" + }, + "typeName": { + "baseType": { + "id": 107, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 106, + "name": "Transaction", + "nameLocations": [ + "1759:11:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1292, + "src": "1759:11:1" + }, + "referencedDeclaration": 1292, + "src": "1759:11:1", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Transaction_$1292_storage_ptr", + "typeString": "struct IModuleCalls.Transaction" + } + }, + "id": 108, + "nodeType": "ArrayTypeName", + "src": "1759:13:1", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Transaction_$1292_storage_$dyn_storage_ptr", + "typeString": "struct IModuleCalls.Transaction[]" + } + }, + "visibility": "internal" + } + ], + "src": "1732:58:1" + }, + "returnParameters": { + "id": 111, + "nodeType": "ParameterList", + "parameters": [], + "src": "1799:0:1" + }, + "scope": 241, + "src": "1710:834:1", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "private" + }, + { + "baseFunctions": [ + 1236 + ], + "body": { + "id": 210, + "nodeType": "Block", + "src": "2766:22:1", + "statements": [ + { + "expression": { + "hexValue": "74727565", + "id": 208, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "2779:4:1", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "functionReturnParameters": 207, + "id": 209, + "nodeType": "Return", + "src": "2772:11:1" + } + ] + }, + "documentation": { + "id": 200, + "nodeType": "StructuredDocumentation", + "src": "2548:145:1", + "text": " @notice Validates any signature image, because the wallet is public and has no owner.\n @return true, all signatures are valid." + }, + "id": 211, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "_isValidImage", + "nameLocation": "2705:13:1", + "nodeType": "FunctionDefinition", + "overrides": { + "id": 204, + "nodeType": "OverrideSpecifier", + "overrides": [], + "src": "2737:8:1" + }, + "parameters": { + "id": 203, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 202, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 211, + "src": "2719:7:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 201, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2719:7:1", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "2718:9:1" + }, + "returnParameters": { + "id": 207, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 206, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 211, + "src": "2760:4:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 205, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "2760:4:1", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "src": "2759:6:1" + }, + "scope": 241, + "src": "2696:92:1", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "baseFunctions": [ + 1248 + ], + "body": { + "id": 221, + "nodeType": "Block", + "src": "2885:32:1", + "statements": [ + { + "errorCall": { + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 218, + "name": "NotSupported", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 42, + "src": "2898:12:1", + "typeDescriptions": { + "typeIdentifier": "t_function_error_pure$__$returns$__$", + "typeString": "function () pure" + } + }, + "id": 219, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2898:14:1", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 220, + "nodeType": "RevertStatement", + "src": "2891:21:1" + } + ] + }, + "documentation": { + "id": 212, + "nodeType": "StructuredDocumentation", + "src": "2792:29:1", + "text": " Not supported." + }, + "id": 222, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "_updateImageHash", + "nameLocation": "2833:16:1", + "nodeType": "FunctionDefinition", + "overrides": { + "id": 216, + "nodeType": "OverrideSpecifier", + "overrides": [], + "src": "2868:8:1" + }, + "parameters": { + "id": 215, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 214, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 222, + "src": "2850:7:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 213, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2850:7:1", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "2849:9:1" + }, + "returnParameters": { + "id": 217, + "nodeType": "ParameterList", + "parameters": [], + "src": "2885:0:1" + }, + "scope": 241, + "src": "2824:93:1", + "stateMutability": "nonpayable", + "virtual": true, + "visibility": "internal" + }, + { + "baseFunctions": [ + 549, + 832, + 901 + ], + "body": { + "id": 239, + "nodeType": "Block", + "src": "3276:55:1", + "statements": [ + { + "expression": { + "arguments": [ + { + "id": 236, + "name": "_interfaceID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 225, + "src": "3313:12:1", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + ], + "expression": { + "id": 234, + "name": "super", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967271, + "src": "3289:5:1", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_super$_GuestModule_$241_$", + "typeString": "type(contract super GuestModule)" + } + }, + "id": 235, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "3295:17:1", + "memberName": "supportsInterface", + "nodeType": "MemberAccess", + "referencedDeclaration": 901, + "src": "3289:23:1", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes4_$returns$_t_bool_$", + "typeString": "function (bytes4) pure returns (bool)" + } + }, + "id": 237, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3289:37:1", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "functionReturnParameters": 233, + "id": 238, + "nodeType": "Return", + "src": "3282:44:1" + } + ] + }, + "documentation": { + "id": 223, + "nodeType": "StructuredDocumentation", + "src": "2921:203:1", + "text": " @notice Query if a contract implements an interface\n @param _interfaceID The interface identifier, as specified in ERC-165\n @return `true` if the contract implements `_interfaceID`" + }, + "functionSelector": "01ffc9a7", + "id": 240, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "supportsInterface", + "nameLocation": "3136:17:1", + "nodeType": "FunctionDefinition", + "overrides": { + "id": 230, + "nodeType": "OverrideSpecifier", + "overrides": [ + { + "id": 227, + "name": "ModuleAuth", + "nameLocations": [ + "3205:10:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 564, + "src": "3205:10:1" + }, + { + "id": 228, + "name": "ModuleCalls", + "nameLocations": [ + "3221:11:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 833, + "src": "3221:11:1" + }, + { + "id": 229, + "name": "ModuleCreator", + "nameLocations": [ + "3238:13:1" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 902, + "src": "3238:13:1" + } + ], + "src": "3190:65:1" + }, + "parameters": { + "id": 226, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 225, + "mutability": "mutable", + "name": "_interfaceID", + "nameLocation": "3166:12:1", + "nodeType": "VariableDeclaration", + "scope": 240, + "src": "3159:19:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + }, + "typeName": { + "id": 224, + "name": "bytes4", + "nodeType": "ElementaryTypeName", + "src": "3159:6:1", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "visibility": "internal" + } + ], + "src": "3153:29:1" + }, + "returnParameters": { + "id": 233, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 232, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 240, + "src": "3270:4:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 231, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "3270:4:1", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "src": "3269:6:1" + }, + "scope": 241, + "src": "3127:204:1", + "stateMutability": "pure", + "virtual": false, + "visibility": "public" + } + ], + "scope": 242, + "src": "640:2693:1", + "usedErrors": [ + 40, + 42, + 938, + 1057, + 1093, + 1193, + 1197, + 1273, + 1279, + 1319, + 1367, + 1371, + 2050, + 2056, + 2539, + 2541, + 2547, + 2553, + 2561, + 2565 + ] + } + ], + "src": "39:3295:1" + }, + "id": 1 + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol": { + "ast": { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleAuth.sol", + "exportedSymbols": { + "IERC1271Wallet": [ + 22 + ], + "IModuleAuth": [ + 1249 + ], + "LibBytes": [ + 2374 + ], + "LibBytesPointer": [ + 2476 + ], + "LibOptim": [ + 2530 + ], + "ModuleAuth": [ + 564 + ], + "ModuleERC165": [ + 920 + ], + "ModuleSelfAuth": [ + 1116 + ], + "ModuleStorage": [ + 1179 + ], + "SequenceBaseSig": [ + 2021 + ], + "SequenceChainedSig": [ + 2218 + ], + "SequenceDynamicSig": [ + 2247 + ], + "SequenceNoChainIdSig": [ + 2275 + ], + "SignatureValidator": [ + 2798 + ] + }, + "id": 565, + "license": "Apache-2.0", + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 243, + "literals": [ + "solidity", + "0.8", + ".18" + ], + "nodeType": "PragmaDirective", + "src": "39:23:2" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol", + "file": "../../utils/LibBytes.sol", + "id": 244, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 565, + "sourceUnit": 2375, + "src": "64:34:2", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/interfaces/IERC1271Wallet.sol", + "file": "../../interfaces/IERC1271Wallet.sol", + "id": 245, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 565, + "sourceUnit": 23, + "src": "99:45:2", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleAuth.sol", + "file": "./interfaces/IModuleAuth.sol", + "id": 246, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 565, + "sourceUnit": 1250, + "src": "146:38:2", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleERC165.sol", + "file": "./ModuleERC165.sol", + "id": 247, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 565, + "sourceUnit": 921, + "src": "186:28:2", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol", + "file": "./submodules/auth/SequenceBaseSig.sol", + "id": 248, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 565, + "sourceUnit": 2022, + "src": "216:47:2", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol", + "file": "./submodules/auth/SequenceDynamicSig.sol", + "id": 249, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 565, + "sourceUnit": 2248, + "src": "264:50:2", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol", + "file": "./submodules/auth/SequenceNoChainIdSig.sol", + "id": 250, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 565, + "sourceUnit": 2276, + "src": "315:52:2", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol", + "file": "./submodules/auth/SequenceChainedSig.sol", + "id": 251, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 565, + "sourceUnit": 2219, + "src": "368:50:2", + "symbolAliases": [], + "unitAlias": "" + }, + { + "abstract": true, + "baseContracts": [ + { + "baseName": { + "id": 252, + "name": "IModuleAuth", + "nameLocations": [ + "455:11:2" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1249, + "src": "455:11:2" + }, + "id": 253, + "nodeType": "InheritanceSpecifier", + "src": "455:11:2" + }, + { + "baseName": { + "id": 254, + "name": "ModuleERC165", + "nameLocations": [ + "470:12:2" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 920, + "src": "470:12:2" + }, + "id": 255, + "nodeType": "InheritanceSpecifier", + "src": "470:12:2" + }, + { + "baseName": { + "id": 256, + "name": "IERC1271Wallet", + "nameLocations": [ + "486:14:2" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 22, + "src": "486:14:2" + }, + "id": 257, + "nodeType": "InheritanceSpecifier", + "src": "486:14:2" + }, + { + "baseName": { + "id": 258, + "name": "SequenceChainedSig", + "nameLocations": [ + "504:18:2" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 2218, + "src": "504:18:2" + }, + "id": 259, + "nodeType": "InheritanceSpecifier", + "src": "504:18:2" + } + ], + "canonicalName": "ModuleAuth", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": false, + "id": 564, + "linearizedBaseContracts": [ + 564, + 2218, + 1116, + 22, + 920, + 1249 + ], + "name": "ModuleAuth", + "nameLocation": "439:10:2", + "nodeType": "ContractDefinition", + "nodes": [ + { + "global": false, + "id": 262, + "libraryName": { + "id": 260, + "name": "LibBytes", + "nameLocations": [ + "533:8:2" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 2374, + "src": "533:8:2" + }, + "nodeType": "UsingForDirective", + "src": "527:25:2", + "typeName": { + "id": 261, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "546:5:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + } + }, + { + "constant": true, + "id": 265, + "mutability": "constant", + "name": "LEGACY_TYPE", + "nameLocation": "581:11:2", + "nodeType": "VariableDeclaration", + "scope": 564, + "src": "556:46:2", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes1", + "typeString": "bytes1" + }, + "typeName": { + "id": 263, + "name": "bytes1", + "nodeType": "ElementaryTypeName", + "src": "556:6:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes1", + "typeString": "bytes1" + } + }, + "value": { + "hexValue": "00", + "id": 264, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "hexString", + "lValueRequested": false, + "nodeType": "Literal", + "src": "595:7:2", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_bc36789e7a1e281436464229828f817d6612f7b477d66591ff96a9e064bcc98a", + "typeString": "literal_string hex\"00\"" + }, + "value": "\u0000" + }, + "visibility": "internal" + }, + { + "constant": true, + "id": 268, + "mutability": "constant", + "name": "DYNAMIC_TYPE", + "nameLocation": "631:12:2", + "nodeType": "VariableDeclaration", + "scope": 564, + "src": "606:47:2", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes1", + "typeString": "bytes1" + }, + "typeName": { + "id": 266, + "name": "bytes1", + "nodeType": "ElementaryTypeName", + "src": "606:6:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes1", + "typeString": "bytes1" + } + }, + "value": { + "hexValue": "01", + "id": 267, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "hexString", + "lValueRequested": false, + "nodeType": "Literal", + "src": "646:7:2", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_5fe7f977e71dba2ea1a68e21057beebb9be2ac30c6410aa38d4f3fbe41dcffd2", + "typeString": "literal_string hex\"01\"" + }, + "value": "\u0001" + }, + "visibility": "internal" + }, + { + "constant": true, + "id": 271, + "mutability": "constant", + "name": "NO_CHAIN_ID_TYPE", + "nameLocation": "682:16:2", + "nodeType": "VariableDeclaration", + "scope": 564, + "src": "657:51:2", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes1", + "typeString": "bytes1" + }, + "typeName": { + "id": 269, + "name": "bytes1", + "nodeType": "ElementaryTypeName", + "src": "657:6:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes1", + "typeString": "bytes1" + } + }, + "value": { + "hexValue": "02", + "id": 270, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "hexString", + "lValueRequested": false, + "nodeType": "Literal", + "src": "701:7:2", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_f2ee15ea639b73fa3db9b34a245bdfa015c260c598b211bf05a1ecc4b3e3b4f2", + "typeString": "literal_string hex\"02\"" + }, + "value": "\u0002" + }, + "visibility": "internal" + }, + { + "constant": true, + "id": 274, + "mutability": "constant", + "name": "CHAINED_TYPE", + "nameLocation": "737:12:2", + "nodeType": "VariableDeclaration", + "scope": 564, + "src": "712:47:2", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes1", + "typeString": "bytes1" + }, + "typeName": { + "id": 272, + "name": "bytes1", + "nodeType": "ElementaryTypeName", + "src": "712:6:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes1", + "typeString": "bytes1" + } + }, + "value": { + "hexValue": "03", + "id": 273, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "hexString", + "lValueRequested": false, + "nodeType": "Literal", + "src": "752:7:2", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_69c322e3248a5dfc29d73c5b0553b0185a35cd5bb6386747517ef7e53b15e287", + "typeString": "literal_string hex\"03\"" + }, + "value": "\u0003" + }, + "visibility": "internal" + }, + { + "constant": true, + "id": 277, + "mutability": "constant", + "name": "SELECTOR_ERC1271_BYTES_BYTES", + "nameLocation": "789:28:2", + "nodeType": "VariableDeclaration", + "scope": 564, + "src": "764:66:2", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + }, + "typeName": { + "id": 275, + "name": "bytes4", + "nodeType": "ElementaryTypeName", + "src": "764:6:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "value": { + "hexValue": "30783230633133623062", + "id": 276, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "820:10:2", + "typeDescriptions": { + "typeIdentifier": "t_rational_549534475_by_1", + "typeString": "int_const 549534475" + }, + "value": "0x20c13b0b" + }, + "visibility": "internal" + }, + { + "constant": true, + "id": 280, + "mutability": "constant", + "name": "SELECTOR_ERC1271_BYTES32_BYTES", + "nameLocation": "859:30:2", + "nodeType": "VariableDeclaration", + "scope": 564, + "src": "834:68:2", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + }, + "typeName": { + "id": 278, + "name": "bytes4", + "nodeType": "ElementaryTypeName", + "src": "834:6:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "value": { + "hexValue": "30783136323662613765", + "id": 279, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "892:10:2", + "typeDescriptions": { + "typeIdentifier": "t_rational_371636862_by_1", + "typeString": "int_const 371636862" + }, + "value": "0x1626ba7e" + }, + "visibility": "internal" + }, + { + "baseFunctions": [ + 1225 + ], + "body": { + "id": 412, + "nodeType": "Block", + "src": "1913:1248:2", + "statements": [ + { + "assignments": [ + 300 + ], + "declarations": [ + { + "constant": false, + "id": 300, + "mutability": "mutable", + "name": "signatureType", + "nameLocation": "1926:13:2", + "nodeType": "VariableDeclaration", + "scope": 412, + "src": "1919:20:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes1", + "typeString": "bytes1" + }, + "typeName": { + "id": 299, + "name": "bytes1", + "nodeType": "ElementaryTypeName", + "src": "1919:6:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes1", + "typeString": "bytes1" + } + }, + "visibility": "internal" + } + ], + "id": 304, + "initialValue": { + "baseExpression": { + "id": 301, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 285, + "src": "1942:10:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "id": 303, + "indexExpression": { + "hexValue": "30", + "id": 302, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1953:1:2", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "1942:13:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes1", + "typeString": "bytes1" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "1919:36:2" + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_bytes1", + "typeString": "bytes1" + }, + "id": 307, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 305, + "name": "signatureType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 300, + "src": "1966:13:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes1", + "typeString": "bytes1" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "id": 306, + "name": "LEGACY_TYPE", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 265, + "src": "1983:11:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes1", + "typeString": "bytes1" + } + }, + "src": "1966:28:2", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 335, + "nodeType": "IfStatement", + "src": "1962:303:2", + "trueBody": { + "id": 334, + "nodeType": "Block", + "src": "1996:269:2", + "statements": [ + { + "expression": { + "id": 313, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 308, + "name": "subdigest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 295, + "src": "2045:9:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 311, + "name": "_digest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 283, + "src": "2083:7:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "expression": { + "id": 309, + "name": "SequenceBaseSig", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2021, + "src": "2057:15:2", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_SequenceBaseSig_$2021_$", + "typeString": "type(library SequenceBaseSig)" + } + }, + "id": 310, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2073:9:2", + "memberName": "subdigest", + "nodeType": "MemberAccess", + "referencedDeclaration": 1394, + "src": "2057:25:2", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$returns$_t_bytes32_$", + "typeString": "function (bytes32) view returns (bytes32)" + } + }, + "id": 312, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2057:34:2", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "2045:46:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 314, + "nodeType": "ExpressionStatement", + "src": "2045:46:2" + }, + { + "expression": { + "id": 325, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "components": [ + { + "id": 315, + "name": "threshold", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 289, + "src": "2100:9:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 316, + "name": "weight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 291, + "src": "2111:6:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 317, + "name": "imageHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 293, + "src": "2119:9:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 318, + "name": "checkpoint", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 297, + "src": "2130:10:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 319, + "isConstant": false, + "isInlineArray": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "TupleExpression", + "src": "2099:42:2", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_uint256_$_t_bytes32_$_t_uint256_$", + "typeString": "tuple(uint256,uint256,bytes32,uint256)" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 322, + "name": "subdigest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 295, + "src": "2168:9:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 323, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 285, + "src": "2179:10:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + ], + "expression": { + "id": 320, + "name": "SequenceBaseSig", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2021, + "src": "2144:15:2", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_SequenceBaseSig_$2021_$", + "typeString": "type(library SequenceBaseSig)" + } + }, + "id": 321, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2160:7:2", + "memberName": "recover", + "nodeType": "MemberAccess", + "referencedDeclaration": 2020, + "src": "2144:23:2", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$_t_bytes_calldata_ptr_$returns$_t_uint256_$_t_uint256_$_t_bytes32_$_t_uint256_$", + "typeString": "function (bytes32,bytes calldata) view returns (uint256,uint256,bytes32,uint256)" + } + }, + "id": 324, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2144:46:2", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_uint256_$_t_bytes32_$_t_uint256_$", + "typeString": "tuple(uint256,uint256,bytes32,uint256)" + } + }, + "src": "2099:91:2", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 326, + "nodeType": "ExpressionStatement", + "src": "2099:91:2" + }, + { + "expression": { + "components": [ + { + "id": 327, + "name": "threshold", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 289, + "src": "2206:9:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 328, + "name": "weight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 291, + "src": "2217:6:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 329, + "name": "imageHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 293, + "src": "2225:9:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 330, + "name": "subdigest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 295, + "src": "2236:9:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 331, + "name": "checkpoint", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 297, + "src": "2247:10:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 332, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "2205:53:2", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_uint256_$_t_bytes32_$_t_bytes32_$_t_uint256_$", + "typeString": "tuple(uint256,uint256,bytes32,bytes32,uint256)" + } + }, + "functionReturnParameters": 298, + "id": 333, + "nodeType": "Return", + "src": "2198:60:2" + } + ] + } + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_bytes1", + "typeString": "bytes1" + }, + "id": 338, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 336, + "name": "signatureType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 300, + "src": "2275:13:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes1", + "typeString": "bytes1" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "id": 337, + "name": "DYNAMIC_TYPE", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 268, + "src": "2292:12:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes1", + "typeString": "bytes1" + } + }, + "src": "2275:29:2", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 366, + "nodeType": "IfStatement", + "src": "2271:310:2", + "trueBody": { + "id": 365, + "nodeType": "Block", + "src": "2306:275:2", + "statements": [ + { + "expression": { + "id": 344, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 339, + "name": "subdigest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 295, + "src": "2358:9:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 342, + "name": "_digest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 283, + "src": "2396:7:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "expression": { + "id": 340, + "name": "SequenceBaseSig", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2021, + "src": "2370:15:2", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_SequenceBaseSig_$2021_$", + "typeString": "type(library SequenceBaseSig)" + } + }, + "id": 341, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2386:9:2", + "memberName": "subdigest", + "nodeType": "MemberAccess", + "referencedDeclaration": 1394, + "src": "2370:25:2", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$returns$_t_bytes32_$", + "typeString": "function (bytes32) view returns (bytes32)" + } + }, + "id": 343, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2370:34:2", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "2358:46:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 345, + "nodeType": "ExpressionStatement", + "src": "2358:46:2" + }, + { + "expression": { + "id": 356, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "components": [ + { + "id": 346, + "name": "threshold", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 289, + "src": "2413:9:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 347, + "name": "weight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 291, + "src": "2424:6:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 348, + "name": "imageHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 293, + "src": "2432:9:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 349, + "name": "checkpoint", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 297, + "src": "2443:10:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 350, + "isConstant": false, + "isInlineArray": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "TupleExpression", + "src": "2412:42:2", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_uint256_$_t_bytes32_$_t_uint256_$", + "typeString": "tuple(uint256,uint256,bytes32,uint256)" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 353, + "name": "subdigest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 295, + "src": "2484:9:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 354, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 285, + "src": "2495:10:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + ], + "expression": { + "id": 351, + "name": "SequenceDynamicSig", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2247, + "src": "2457:18:2", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_SequenceDynamicSig_$2247_$", + "typeString": "type(library SequenceDynamicSig)" + } + }, + "id": 352, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2476:7:2", + "memberName": "recover", + "nodeType": "MemberAccess", + "referencedDeclaration": 2246, + "src": "2457:26:2", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$_t_bytes_calldata_ptr_$returns$_t_uint256_$_t_uint256_$_t_bytes32_$_t_uint256_$", + "typeString": "function (bytes32,bytes calldata) view returns (uint256,uint256,bytes32,uint256)" + } + }, + "id": 355, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2457:49:2", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_uint256_$_t_bytes32_$_t_uint256_$", + "typeString": "tuple(uint256,uint256,bytes32,uint256)" + } + }, + "src": "2412:94:2", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 357, + "nodeType": "ExpressionStatement", + "src": "2412:94:2" + }, + { + "expression": { + "components": [ + { + "id": 358, + "name": "threshold", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 289, + "src": "2522:9:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 359, + "name": "weight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 291, + "src": "2533:6:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 360, + "name": "imageHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 293, + "src": "2541:9:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 361, + "name": "subdigest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 295, + "src": "2552:9:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 362, + "name": "checkpoint", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 297, + "src": "2563:10:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 363, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "2521:53:2", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_uint256_$_t_bytes32_$_t_bytes32_$_t_uint256_$", + "typeString": "tuple(uint256,uint256,bytes32,bytes32,uint256)" + } + }, + "functionReturnParameters": 298, + "id": 364, + "nodeType": "Return", + "src": "2514:60:2" + } + ] + } + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_bytes1", + "typeString": "bytes1" + }, + "id": 369, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 367, + "name": "signatureType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 300, + "src": "2591:13:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes1", + "typeString": "bytes1" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "id": 368, + "name": "NO_CHAIN_ID_TYPE", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 271, + "src": "2608:16:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes1", + "typeString": "bytes1" + } + }, + "src": "2591:33:2", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 397, + "nodeType": "IfStatement", + "src": "2587:319:2", + "trueBody": { + "id": 396, + "nodeType": "Block", + "src": "2626:280:2", + "statements": [ + { + "expression": { + "id": 375, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 370, + "name": "subdigest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 295, + "src": "2678:9:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 373, + "name": "_digest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 283, + "src": "2721:7:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "expression": { + "id": 371, + "name": "SequenceNoChainIdSig", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2275, + "src": "2690:20:2", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_SequenceNoChainIdSig_$2275_$", + "typeString": "type(library SequenceNoChainIdSig)" + } + }, + "id": 372, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2711:9:2", + "memberName": "subdigest", + "nodeType": "MemberAccess", + "referencedDeclaration": 2274, + "src": "2690:30:2", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$returns$_t_bytes32_$", + "typeString": "function (bytes32) view returns (bytes32)" + } + }, + "id": 374, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2690:39:2", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "2678:51:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 376, + "nodeType": "ExpressionStatement", + "src": "2678:51:2" + }, + { + "expression": { + "id": 387, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "components": [ + { + "id": 377, + "name": "threshold", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 289, + "src": "2738:9:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 378, + "name": "weight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 291, + "src": "2749:6:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 379, + "name": "imageHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 293, + "src": "2757:9:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 380, + "name": "checkpoint", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 297, + "src": "2768:10:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 381, + "isConstant": false, + "isInlineArray": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "TupleExpression", + "src": "2737:42:2", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_uint256_$_t_bytes32_$_t_uint256_$", + "typeString": "tuple(uint256,uint256,bytes32,uint256)" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 384, + "name": "subdigest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 295, + "src": "2809:9:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 385, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 285, + "src": "2820:10:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + ], + "expression": { + "id": 382, + "name": "SequenceDynamicSig", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2247, + "src": "2782:18:2", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_SequenceDynamicSig_$2247_$", + "typeString": "type(library SequenceDynamicSig)" + } + }, + "id": 383, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2801:7:2", + "memberName": "recover", + "nodeType": "MemberAccess", + "referencedDeclaration": 2246, + "src": "2782:26:2", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$_t_bytes_calldata_ptr_$returns$_t_uint256_$_t_uint256_$_t_bytes32_$_t_uint256_$", + "typeString": "function (bytes32,bytes calldata) view returns (uint256,uint256,bytes32,uint256)" + } + }, + "id": 386, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2782:49:2", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_uint256_$_t_bytes32_$_t_uint256_$", + "typeString": "tuple(uint256,uint256,bytes32,uint256)" + } + }, + "src": "2737:94:2", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 388, + "nodeType": "ExpressionStatement", + "src": "2737:94:2" + }, + { + "expression": { + "components": [ + { + "id": 389, + "name": "threshold", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 289, + "src": "2847:9:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 390, + "name": "weight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 291, + "src": "2858:6:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 391, + "name": "imageHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 293, + "src": "2866:9:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 392, + "name": "subdigest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 295, + "src": "2877:9:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 393, + "name": "checkpoint", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 297, + "src": "2888:10:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 394, + "isConstant": false, + "isInlineArray": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "TupleExpression", + "src": "2846:53:2", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_uint256_$_t_bytes32_$_t_bytes32_$_t_uint256_$", + "typeString": "tuple(uint256,uint256,bytes32,bytes32,uint256)" + } + }, + "functionReturnParameters": 298, + "id": 395, + "nodeType": "Return", + "src": "2839:60:2" + } + ] + } + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_bytes1", + "typeString": "bytes1" + }, + "id": 400, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 398, + "name": "signatureType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 300, + "src": "2916:13:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes1", + "typeString": "bytes1" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "id": 399, + "name": "CHAINED_TYPE", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 274, + "src": "2933:12:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes1", + "typeString": "bytes1" + } + }, + "src": "2916:29:2", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 407, + "nodeType": "IfStatement", + "src": "2912:196:2", + "trueBody": { + "id": 406, + "nodeType": "Block", + "src": "2947:161:2", + "statements": [ + { + "expression": { + "arguments": [ + { + "id": 402, + "name": "_digest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 283, + "src": "3081:7:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 403, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 285, + "src": "3090:10:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + ], + "id": 401, + "name": "chainedRecover", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2217, + "src": "3066:14:2", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$_t_bytes_calldata_ptr_$returns$_t_uint256_$_t_uint256_$_t_bytes32_$_t_bytes32_$_t_uint256_$", + "typeString": "function (bytes32,bytes calldata) view returns (uint256,uint256,bytes32,bytes32,uint256)" + } + }, + "id": 404, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3066:35:2", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_uint256_$_t_bytes32_$_t_bytes32_$_t_uint256_$", + "typeString": "tuple(uint256,uint256,bytes32,bytes32,uint256)" + } + }, + "functionReturnParameters": 298, + "id": 405, + "nodeType": "Return", + "src": "3059:42:2" + } + ] + } + }, + { + "errorCall": { + "arguments": [ + { + "id": 409, + "name": "signatureType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 300, + "src": "3142:13:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes1", + "typeString": "bytes1" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes1", + "typeString": "bytes1" + } + ], + "id": 408, + "name": "InvalidSignatureType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1197, + "src": "3121:20:2", + "typeDescriptions": { + "typeIdentifier": "t_function_error_pure$_t_bytes1_$returns$__$", + "typeString": "function (bytes1) pure" + } + }, + "id": 410, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3121:35:2", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 411, + "nodeType": "RevertStatement", + "src": "3114:42:2" + } + ] + }, + "documentation": { + "id": 281, + "nodeType": "StructuredDocumentation", + "src": "907:765:2", + "text": " @notice Recovers the threshold, weight, imageHash, subdigest, and checkpoint of a signature.\n @dev The signature must be prefixed with a type byte, which is used to determine the recovery method.\n @param _digest Digest of the signed data.\n @param _signature A Sequence signature.\n @return threshold The required number of signatures needed to consider the signature valid.\n @return weight The actual number of signatures collected in the signature.\n @return imageHash The imageHash of the configuration that signed the message.\n @return subdigest A modified version of the original digest, unique for each wallet/network.\n @return checkpoint A nonce that is incremented every time a new configuration is set." + }, + "functionSelector": "853c5068", + "id": 413, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "signatureRecovery", + "nameLocation": "1684:17:2", + "nodeType": "FunctionDefinition", + "overrides": { + "id": 287, + "nodeType": "OverrideSpecifier", + "overrides": [], + "src": "1765:8:2" + }, + "parameters": { + "id": 286, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 283, + "mutability": "mutable", + "name": "_digest", + "nameLocation": "1715:7:2", + "nodeType": "VariableDeclaration", + "scope": 413, + "src": "1707:15:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 282, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1707:7:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 285, + "mutability": "mutable", + "name": "_signature", + "nameLocation": "1743:10:2", + "nodeType": "VariableDeclaration", + "scope": 413, + "src": "1728:25:2", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 284, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "1728:5:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "1701:56:2" + }, + "returnParameters": { + "id": 298, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 289, + "mutability": "mutable", + "name": "threshold", + "nameLocation": "1809:9:2", + "nodeType": "VariableDeclaration", + "scope": 413, + "src": "1801:17:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 288, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1801:7:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 291, + "mutability": "mutable", + "name": "weight", + "nameLocation": "1832:6:2", + "nodeType": "VariableDeclaration", + "scope": 413, + "src": "1824:14:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 290, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1824:7:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 293, + "mutability": "mutable", + "name": "imageHash", + "nameLocation": "1852:9:2", + "nodeType": "VariableDeclaration", + "scope": 413, + "src": "1844:17:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 292, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1844:7:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 295, + "mutability": "mutable", + "name": "subdigest", + "nameLocation": "1875:9:2", + "nodeType": "VariableDeclaration", + "scope": 413, + "src": "1867:17:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 294, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1867:7:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 297, + "mutability": "mutable", + "name": "checkpoint", + "nameLocation": "1898:10:2", + "nodeType": "VariableDeclaration", + "scope": 413, + "src": "1890:18:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 296, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1890:7:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "1795:117:2" + }, + "scope": 564, + "src": "1675:1486:2", + "stateMutability": "view", + "virtual": true, + "visibility": "public" + }, + { + "baseFunctions": [ + 1208 + ], + "body": { + "id": 456, + "nodeType": "Block", + "src": "3651:215:2", + "statements": [ + { + "assignments": [ + 427 + ], + "declarations": [ + { + "constant": false, + "id": 427, + "mutability": "mutable", + "name": "threshold", + "nameLocation": "3665:9:2", + "nodeType": "VariableDeclaration", + "scope": 456, + "src": "3657:17:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 426, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3657:7:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 428, + "nodeType": "VariableDeclarationStatement", + "src": "3657:17:2" + }, + { + "assignments": [ + 430 + ], + "declarations": [ + { + "constant": false, + "id": 430, + "mutability": "mutable", + "name": "weight", + "nameLocation": "3684:6:2", + "nodeType": "VariableDeclaration", + "scope": 456, + "src": "3676:14:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 429, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3676:7:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 431, + "nodeType": "VariableDeclarationStatement", + "src": "3676:14:2" + }, + { + "assignments": [ + 433 + ], + "declarations": [ + { + "constant": false, + "id": 433, + "mutability": "mutable", + "name": "imageHash", + "nameLocation": "3700:9:2", + "nodeType": "VariableDeclaration", + "scope": 456, + "src": "3692:17:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 432, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "3692:7:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "id": 434, + "nodeType": "VariableDeclarationStatement", + "src": "3692:17:2" + }, + { + "expression": { + "id": 444, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "components": [ + { + "id": 435, + "name": "threshold", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 427, + "src": "3716:9:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 436, + "name": "weight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 430, + "src": "3727:6:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 437, + "name": "imageHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 433, + "src": "3735:9:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 438, + "name": "subdigest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 424, + "src": "3746:9:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + null + ], + "id": 439, + "isConstant": false, + "isInlineArray": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "TupleExpression", + "src": "3715:42:2", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_uint256_$_t_bytes32_$_t_bytes32_$__$", + "typeString": "tuple(uint256,uint256,bytes32,bytes32,)" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 441, + "name": "_digest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 416, + "src": "3778:7:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 442, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 418, + "src": "3787:10:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + ], + "id": 440, + "name": "signatureRecovery", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 413 + ], + "referencedDeclaration": 413, + "src": "3760:17:2", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$_t_bytes_calldata_ptr_$returns$_t_uint256_$_t_uint256_$_t_bytes32_$_t_bytes32_$_t_uint256_$", + "typeString": "function (bytes32,bytes calldata) view returns (uint256,uint256,bytes32,bytes32,uint256)" + } + }, + "id": 443, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3760:38:2", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_uint256_$_t_bytes32_$_t_bytes32_$_t_uint256_$", + "typeString": "tuple(uint256,uint256,bytes32,bytes32,uint256)" + } + }, + "src": "3715:83:2", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 445, + "nodeType": "ExpressionStatement", + "src": "3715:83:2" + }, + { + "expression": { + "id": 454, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 446, + "name": "isValid", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 422, + "src": "3804:7:2", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 453, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 449, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 447, + "name": "weight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 430, + "src": "3814:6:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">=", + "rightExpression": { + "id": 448, + "name": "threshold", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 427, + "src": "3824:9:2", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "3814:19:2", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": { + "arguments": [ + { + "id": 451, + "name": "imageHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 433, + "src": "3851:9:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 450, + "name": "_isValidImage", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1236, + "src": "3837:13:2", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$returns$_t_bool_$", + "typeString": "function (bytes32) view returns (bool)" + } + }, + "id": 452, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3837:24:2", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "3814:47:2", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "3804:57:2", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 455, + "nodeType": "ExpressionStatement", + "src": "3804:57:2" + } + ] + }, + "documentation": { + "id": 414, + "nodeType": "StructuredDocumentation", + "src": "3165:312:2", + "text": " @dev Validates a signature.\n @param _digest Digest of the signed data.\n @param _signature A Sequence signature.\n @return isValid Indicates whether the signature is valid or not.\n @return subdigest A modified version of the original digest, unique for each wallet/network." + }, + "id": 457, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "_signatureValidation", + "nameLocation": "3489:20:2", + "nodeType": "FunctionDefinition", + "overrides": { + "id": 420, + "nodeType": "OverrideSpecifier", + "overrides": [], + "src": "3575:8:2" + }, + "parameters": { + "id": 419, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 416, + "mutability": "mutable", + "name": "_digest", + "nameLocation": "3523:7:2", + "nodeType": "VariableDeclaration", + "scope": 457, + "src": "3515:15:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 415, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "3515:7:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 418, + "mutability": "mutable", + "name": "_signature", + "nameLocation": "3551:10:2", + "nodeType": "VariableDeclaration", + "scope": 457, + "src": "3536:25:2", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 417, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "3536:5:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "3509:56:2" + }, + "returnParameters": { + "id": 425, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 422, + "mutability": "mutable", + "name": "isValid", + "nameLocation": "3616:7:2", + "nodeType": "VariableDeclaration", + "scope": 457, + "src": "3611:12:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 421, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "3611:4:2", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 424, + "mutability": "mutable", + "name": "subdigest", + "nameLocation": "3637:9:2", + "nodeType": "VariableDeclaration", + "scope": 457, + "src": "3629:17:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 423, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "3629:7:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "3605:45:2" + }, + "scope": 564, + "src": "3480:386:2", + "stateMutability": "view", + "virtual": true, + "visibility": "internal" + }, + { + "baseFunctions": [ + 11 + ], + "body": { + "id": 487, + "nodeType": "Block", + "src": "4659:198:2", + "statements": [ + { + "assignments": [ + 469, + null + ], + "declarations": [ + { + "constant": false, + "id": 469, + "mutability": "mutable", + "name": "isValid", + "nameLocation": "4698:7:2", + "nodeType": "VariableDeclaration", + "scope": 487, + "src": "4693:12:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 468, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "4693:4:2", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + }, + null + ], + "id": 476, + "initialValue": { + "arguments": [ + { + "arguments": [ + { + "id": 472, + "name": "_data", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 460, + "src": "4741:5:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + ], + "id": 471, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967288, + "src": "4731:9:2", + "typeDescriptions": { + "typeIdentifier": "t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$", + "typeString": "function (bytes memory) pure returns (bytes32)" + } + }, + "id": 473, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "4731:16:2", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 474, + "name": "_signatures", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 462, + "src": "4749:11:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + ], + "id": 470, + "name": "_signatureValidation", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 457 + ], + "referencedDeclaration": 457, + "src": "4710:20:2", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$_t_bytes_calldata_ptr_$returns$_t_bool_$_t_bytes32_$", + "typeString": "function (bytes32,bytes calldata) view returns (bool,bytes32)" + } + }, + "id": 475, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "4710:51:2", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_bool_$_t_bytes32_$", + "typeString": "tuple(bool,bytes32)" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "4692:69:2" + }, + { + "condition": { + "id": 477, + "name": "isValid", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 469, + "src": "4771:7:2", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 481, + "nodeType": "IfStatement", + "src": "4767:63:2", + "trueBody": { + "id": 480, + "nodeType": "Block", + "src": "4780:50:2", + "statements": [ + { + "expression": { + "id": 478, + "name": "SELECTOR_ERC1271_BYTES_BYTES", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 277, + "src": "4795:28:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "functionReturnParameters": 467, + "id": 479, + "nodeType": "Return", + "src": "4788:35:2" + } + ] + } + }, + { + "expression": { + "arguments": [ + { + "hexValue": "30", + "id": 484, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4850:1:2", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 483, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "4843:6:2", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes4_$", + "typeString": "type(bytes4)" + }, + "typeName": { + "id": 482, + "name": "bytes4", + "nodeType": "ElementaryTypeName", + "src": "4843:6:2", + "typeDescriptions": {} + } + }, + "id": 485, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "4843:9:2", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "functionReturnParameters": 467, + "id": 486, + "nodeType": "Return", + "src": "4836:16:2" + } + ] + }, + "documentation": { + "id": 458, + "nodeType": "StructuredDocumentation", + "src": "3870:652:2", + "text": " @notice Verifies whether the provided signature is valid with respect to the provided data\n @dev MUST return the correct magic value if the signature provided is valid for the provided data\n > The bytes4 magic value to return when signature is valid is 0x20c13b0b : bytes4(keccak256(\"isValidSignature(bytes,bytes)\"))\n @param _data Arbitrary length data signed on the behalf of address(this)\n @param _signatures Signature byte array associated with _data.\n Encoded as abi.encode(Signature[], Configs)\n @return magicValue Magic value 0x20c13b0b if the signature is valid and 0x0 otherwise" + }, + "functionSelector": "20c13b0b", + "id": 488, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "isValidSignature", + "nameLocation": "4534:16:2", + "nodeType": "FunctionDefinition", + "overrides": { + "id": 464, + "nodeType": "OverrideSpecifier", + "overrides": [], + "src": "4620:8:2" + }, + "parameters": { + "id": 463, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 460, + "mutability": "mutable", + "name": "_data", + "nameLocation": "4571:5:2", + "nodeType": "VariableDeclaration", + "scope": 488, + "src": "4556:20:2", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 459, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "4556:5:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 462, + "mutability": "mutable", + "name": "_signatures", + "nameLocation": "4597:11:2", + "nodeType": "VariableDeclaration", + "scope": 488, + "src": "4582:26:2", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 461, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "4582:5:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "4550:62:2" + }, + "returnParameters": { + "id": 467, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 466, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 488, + "src": "4651:6:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + }, + "typeName": { + "id": 465, + "name": "bytes4", + "nodeType": "ElementaryTypeName", + "src": "4651:6:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "visibility": "internal" + } + ], + "src": "4650:8:2" + }, + "scope": 564, + "src": "4525:332:2", + "stateMutability": "view", + "virtual": true, + "visibility": "public" + }, + { + "baseFunctions": [ + 21 + ], + "body": { + "id": 516, + "nodeType": "Block", + "src": "5616:189:2", + "statements": [ + { + "assignments": [ + 500, + null + ], + "declarations": [ + { + "constant": false, + "id": 500, + "mutability": "mutable", + "name": "isValid", + "nameLocation": "5655:7:2", + "nodeType": "VariableDeclaration", + "scope": 516, + "src": "5650:12:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 499, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "5650:4:2", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + }, + null + ], + "id": 505, + "initialValue": { + "arguments": [ + { + "id": 502, + "name": "_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 491, + "src": "5688:5:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 503, + "name": "_signatures", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 493, + "src": "5695:11:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + ], + "id": 501, + "name": "_signatureValidation", + "nodeType": "Identifier", + "overloadedDeclarations": [ + 457 + ], + "referencedDeclaration": 457, + "src": "5667:20:2", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$_t_bytes_calldata_ptr_$returns$_t_bool_$_t_bytes32_$", + "typeString": "function (bytes32,bytes calldata) view returns (bool,bytes32)" + } + }, + "id": 504, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "5667:40:2", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_bool_$_t_bytes32_$", + "typeString": "tuple(bool,bytes32)" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "5649:58:2" + }, + { + "condition": { + "id": 506, + "name": "isValid", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 500, + "src": "5717:7:2", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 510, + "nodeType": "IfStatement", + "src": "5713:65:2", + "trueBody": { + "id": 509, + "nodeType": "Block", + "src": "5726:52:2", + "statements": [ + { + "expression": { + "id": 507, + "name": "SELECTOR_ERC1271_BYTES32_BYTES", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 280, + "src": "5741:30:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "functionReturnParameters": 498, + "id": 508, + "nodeType": "Return", + "src": "5734:37:2" + } + ] + } + }, + { + "expression": { + "arguments": [ + { + "hexValue": "30", + "id": 513, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5798:1:2", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 512, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "5791:6:2", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes4_$", + "typeString": "type(bytes4)" + }, + "typeName": { + "id": 511, + "name": "bytes4", + "nodeType": "ElementaryTypeName", + "src": "5791:6:2", + "typeDescriptions": {} + } + }, + "id": 514, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "5791:9:2", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "functionReturnParameters": 498, + "id": 515, + "nodeType": "Return", + "src": "5784:16:2" + } + ] + }, + "documentation": { + "id": 489, + "nodeType": "StructuredDocumentation", + "src": "4861:625:2", + "text": " @notice Verifies whether the provided signature is valid with respect to the provided hash\n @dev MUST return the correct magic value if the signature provided is valid for the provided hash\n > The bytes4 magic value to return when signature is valid is 0x1626ba7e : bytes4(keccak256(\"isValidSignature(bytes32,bytes)\"))\n @param _hash keccak256 hash that was signed\n @param _signatures Signature byte array associated with _data.\n Encoded as abi.encode(Signature[], Configs)\n @return magicValue Magic value 0x1626ba7e if the signature is valid and 0x0 otherwise" + }, + "functionSelector": "1626ba7e", + "id": 517, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "isValidSignature", + "nameLocation": "5498:16:2", + "nodeType": "FunctionDefinition", + "overrides": { + "id": 495, + "nodeType": "OverrideSpecifier", + "overrides": [], + "src": "5577:8:2" + }, + "parameters": { + "id": 494, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 491, + "mutability": "mutable", + "name": "_hash", + "nameLocation": "5528:5:2", + "nodeType": "VariableDeclaration", + "scope": 517, + "src": "5520:13:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 490, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "5520:7:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 493, + "mutability": "mutable", + "name": "_signatures", + "nameLocation": "5554:11:2", + "nodeType": "VariableDeclaration", + "scope": 517, + "src": "5539:26:2", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 492, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "5539:5:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "5514:55:2" + }, + "returnParameters": { + "id": 498, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 497, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 517, + "src": "5608:6:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + }, + "typeName": { + "id": 496, + "name": "bytes4", + "nodeType": "ElementaryTypeName", + "src": "5608:6:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "visibility": "internal" + } + ], + "src": "5607:8:2" + }, + "scope": 564, + "src": "5489:316:2", + "stateMutability": "view", + "virtual": true, + "visibility": "public" + }, + { + "baseFunctions": [ + 919 + ], + "body": { + "id": 548, + "nodeType": "Block", + "src": "6107:208:2", + "statements": [ + { + "condition": { + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 538, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "commonType": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + }, + "id": 531, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 526, + "name": "_interfaceID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 520, + "src": "6124:12:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "expression": { + "arguments": [ + { + "id": 528, + "name": "IModuleAuth", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1249, + "src": "6145:11:2", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_IModuleAuth_$1249_$", + "typeString": "type(contract IModuleAuth)" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_type$_t_contract$_IModuleAuth_$1249_$", + "typeString": "type(contract IModuleAuth)" + } + ], + "id": 527, + "name": "type", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967269, + "src": "6140:4:2", + "typeDescriptions": { + "typeIdentifier": "t_function_metatype_pure$__$returns$__$", + "typeString": "function () pure" + } + }, + "id": 529, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "6140:17:2", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_magic_meta_type_t_contract$_IModuleAuth_$1249", + "typeString": "type(contract IModuleAuth)" + } + }, + "id": 530, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "6158:11:2", + "memberName": "interfaceId", + "nodeType": "MemberAccess", + "src": "6140:29:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "src": "6124:45:2", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "||", + "rightExpression": { + "commonType": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + }, + "id": 537, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 532, + "name": "_interfaceID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 520, + "src": "6179:12:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "expression": { + "arguments": [ + { + "id": 534, + "name": "IERC1271Wallet", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22, + "src": "6200:14:2", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_IERC1271Wallet_$22_$", + "typeString": "type(contract IERC1271Wallet)" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_type$_t_contract$_IERC1271Wallet_$22_$", + "typeString": "type(contract IERC1271Wallet)" + } + ], + "id": 533, + "name": "type", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967269, + "src": "6195:4:2", + "typeDescriptions": { + "typeIdentifier": "t_function_metatype_pure$__$returns$__$", + "typeString": "function () pure" + } + }, + "id": 535, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "6195:20:2", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_magic_meta_type_t_contract$_IERC1271Wallet_$22", + "typeString": "type(contract IERC1271Wallet)" + } + }, + "id": 536, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "6216:11:2", + "memberName": "interfaceId", + "nodeType": "MemberAccess", + "src": "6195:32:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "src": "6179:48:2", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "6124:103:2", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 542, + "nodeType": "IfStatement", + "src": "6113:147:2", + "trueBody": { + "id": 541, + "nodeType": "Block", + "src": "6234:26:2", + "statements": [ + { + "expression": { + "hexValue": "74727565", + "id": 539, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "6249:4:2", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "functionReturnParameters": 525, + "id": 540, + "nodeType": "Return", + "src": "6242:11:2" + } + ] + } + }, + { + "expression": { + "arguments": [ + { + "id": 545, + "name": "_interfaceID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 520, + "src": "6297:12:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + ], + "expression": { + "id": 543, + "name": "super", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967271, + "src": "6273:5:2", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_super$_ModuleAuth_$564_$", + "typeString": "type(contract super ModuleAuth)" + } + }, + "id": 544, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "6279:17:2", + "memberName": "supportsInterface", + "nodeType": "MemberAccess", + "referencedDeclaration": 919, + "src": "6273:23:2", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes4_$returns$_t_bool_$", + "typeString": "function (bytes4) pure returns (bool)" + } + }, + "id": 546, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "6273:37:2", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "functionReturnParameters": 525, + "id": 547, + "nodeType": "Return", + "src": "6266:44:2" + } + ] + }, + "documentation": { + "id": 518, + "nodeType": "StructuredDocumentation", + "src": "5809:203:2", + "text": " @notice Query if a contract implements an interface\n @param _interfaceID The interface identifier, as specified in ERC-165\n @return `true` if the contract implements `_interfaceID`" + }, + "functionSelector": "01ffc9a7", + "id": 549, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "supportsInterface", + "nameLocation": "6024:17:2", + "nodeType": "FunctionDefinition", + "overrides": { + "id": 522, + "nodeType": "OverrideSpecifier", + "overrides": [], + "src": "6070:8:2" + }, + "parameters": { + "id": 521, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 520, + "mutability": "mutable", + "name": "_interfaceID", + "nameLocation": "6049:12:2", + "nodeType": "VariableDeclaration", + "scope": 549, + "src": "6042:19:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + }, + "typeName": { + "id": 519, + "name": "bytes4", + "nodeType": "ElementaryTypeName", + "src": "6042:6:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "visibility": "internal" + } + ], + "src": "6041:21:2" + }, + "returnParameters": { + "id": 525, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 524, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 549, + "src": "6101:4:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 523, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "6101:4:2", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "src": "6100:6:2" + }, + "scope": 564, + "src": "6015:300:2", + "stateMutability": "pure", + "virtual": true, + "visibility": "public" + }, + { + "baseFunctions": [ + 1242 + ], + "body": { + "id": 562, + "nodeType": "Block", + "src": "6536:39:2", + "statements": [ + { + "expression": { + "arguments": [ + { + "id": 559, + "name": "_imageHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 552, + "src": "6559:10:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 558, + "name": "_updateImageHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1248, + "src": "6542:16:2", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$returns$__$", + "typeString": "function (bytes32)" + } + }, + "id": 560, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "6542:28:2", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 561, + "nodeType": "ExpressionStatement", + "src": "6542:28:2" + } + ] + }, + "documentation": { + "id": 550, + "nodeType": "StructuredDocumentation", + "src": "6319:134:2", + "text": " @notice Updates the signers configuration of the wallet\n @param _imageHash New required image hash of the signature" + }, + "functionSelector": "29561426", + "id": 563, + "implemented": true, + "kind": "function", + "modifiers": [ + { + "id": 556, + "kind": "modifierInvocation", + "modifierName": { + "id": 555, + "name": "onlySelf", + "nameLocations": [ + "6527:8:2" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1115, + "src": "6527:8:2" + }, + "nodeType": "ModifierInvocation", + "src": "6527:8:2" + } + ], + "name": "updateImageHash", + "nameLocation": "6465:15:2", + "nodeType": "FunctionDefinition", + "overrides": { + "id": 554, + "nodeType": "OverrideSpecifier", + "overrides": [], + "src": "6510:8:2" + }, + "parameters": { + "id": 553, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 552, + "mutability": "mutable", + "name": "_imageHash", + "nameLocation": "6489:10:2", + "nodeType": "VariableDeclaration", + "scope": 563, + "src": "6481:18:2", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 551, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "6481:7:2", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "6480:20:2" + }, + "returnParameters": { + "id": 557, + "nodeType": "ParameterList", + "parameters": [], + "src": "6536:0:2" + }, + "scope": 564, + "src": "6456:119:2", + "stateMutability": "nonpayable", + "virtual": true, + "visibility": "external" + } + ], + "scope": 565, + "src": "421:6156:2", + "usedErrors": [ + 1093, + 1193, + 1197, + 1367, + 1371, + 2050, + 2056, + 2539, + 2541, + 2547, + 2553, + 2561, + 2565 + ] + } + ], + "src": "39:6539:2" + }, + "id": 2 + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol": { + "ast": { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCalls.sol", + "exportedSymbols": { + "IERC1271Wallet": [ + 22 + ], + "IModuleAuth": [ + 1249 + ], + "IModuleCalls": [ + 1313 + ], + "LibBytes": [ + 2374 + ], + "LibBytesPointer": [ + 2476 + ], + "LibOptim": [ + 2530 + ], + "ModuleCalls": [ + 833 + ], + "ModuleERC165": [ + 920 + ], + "ModuleNonce": [ + 1051 + ], + "ModuleOnlyDelegatecall": [ + 1085 + ], + "ModuleSelfAuth": [ + 1116 + ], + "ModuleStorage": [ + 1179 + ], + "SequenceBaseSig": [ + 2021 + ], + "SignatureValidator": [ + 2798 + ], + "SubModuleNonce": [ + 2324 + ] + }, + "id": 834, + "license": "Apache-2.0", + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 566, + "literals": [ + "solidity", + "0.8", + ".18" + ], + "nodeType": "PragmaDirective", + "src": "39:23:3" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol", + "file": "./ModuleSelfAuth.sol", + "id": 567, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 834, + "sourceUnit": 1117, + "src": "64:30:3", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol", + "file": "./ModuleStorage.sol", + "id": 568, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 834, + "sourceUnit": 1180, + "src": "95:29:3", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleERC165.sol", + "file": "./ModuleERC165.sol", + "id": 569, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 834, + "sourceUnit": 921, + "src": "125:28:3", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol", + "file": "./ModuleNonce.sol", + "id": 570, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 834, + "sourceUnit": 1052, + "src": "154:27:3", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleOnlyDelegatecall.sol", + "file": "./ModuleOnlyDelegatecall.sol", + "id": 571, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 834, + "sourceUnit": 1086, + "src": "182:38:3", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCalls.sol", + "file": "./interfaces/IModuleCalls.sol", + "id": 572, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 834, + "sourceUnit": 1314, + "src": "222:39:3", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleAuth.sol", + "file": "./interfaces/IModuleAuth.sol", + "id": 573, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 834, + "sourceUnit": 1250, + "src": "262:38:3", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol", + "file": "./submodules/nonce/SubModuleNonce.sol", + "id": 574, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 834, + "sourceUnit": 2325, + "src": "302:47:3", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol", + "file": "./submodules/auth/SequenceBaseSig.sol", + "id": 575, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 834, + "sourceUnit": 2022, + "src": "350:47:3", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol", + "file": "../../utils/LibOptim.sol", + "id": 576, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 834, + "sourceUnit": 2531, + "src": "399:34:3", + "symbolAliases": [], + "unitAlias": "" + }, + { + "abstract": true, + "baseContracts": [ + { + "baseName": { + "id": 577, + "name": "IModuleCalls", + "nameLocations": [ + "469:12:3" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1313, + "src": "469:12:3" + }, + "id": 578, + "nodeType": "InheritanceSpecifier", + "src": "469:12:3" + }, + { + "baseName": { + "id": 579, + "name": "IModuleAuth", + "nameLocations": [ + "483:11:3" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1249, + "src": "483:11:3" + }, + "id": 580, + "nodeType": "InheritanceSpecifier", + "src": "483:11:3" + }, + { + "baseName": { + "id": 581, + "name": "ModuleERC165", + "nameLocations": [ + "496:12:3" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 920, + "src": "496:12:3" + }, + "id": 582, + "nodeType": "InheritanceSpecifier", + "src": "496:12:3" + }, + { + "baseName": { + "id": 583, + "name": "ModuleOnlyDelegatecall", + "nameLocations": [ + "510:22:3" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1085, + "src": "510:22:3" + }, + "id": 584, + "nodeType": "InheritanceSpecifier", + "src": "510:22:3" + }, + { + "baseName": { + "id": 585, + "name": "ModuleSelfAuth", + "nameLocations": [ + "534:14:3" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1116, + "src": "534:14:3" + }, + "id": 586, + "nodeType": "InheritanceSpecifier", + "src": "534:14:3" + }, + { + "baseName": { + "id": 587, + "name": "ModuleNonce", + "nameLocations": [ + "550:11:3" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1051, + "src": "550:11:3" + }, + "id": 588, + "nodeType": "InheritanceSpecifier", + "src": "550:11:3" + } + ], + "canonicalName": "ModuleCalls", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": false, + "id": 833, + "linearizedBaseContracts": [ + 833, + 1051, + 1116, + 1085, + 920, + 1249, + 1313 + ], + "name": "ModuleCalls", + "nameLocation": "454:11:3", + "nodeType": "ContractDefinition", + "nodes": [ + { + "baseFunctions": [ + 1304 + ], + "body": { + "id": 636, + "nodeType": "Block", + "src": "1142:420:3", + "statements": [ + { + "expression": { + "arguments": [ + { + "id": 604, + "name": "_nonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 595, + "src": "1196:6:3", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 603, + "name": "_validateNonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1050, + "src": "1181:14:3", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_uint256_$returns$__$", + "typeString": "function (uint256)" + } + }, + "id": 605, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1181:22:3", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 606, + "nodeType": "ExpressionStatement", + "src": "1181:22:3" + }, + { + "assignments": [ + 608, + 610 + ], + "declarations": [ + { + "constant": false, + "id": 608, + "mutability": "mutable", + "name": "isValid", + "nameLocation": "1258:7:3", + "nodeType": "VariableDeclaration", + "scope": 636, + "src": "1253:12:3", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 607, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "1253:4:3", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 610, + "mutability": "mutable", + "name": "txHash", + "nameLocation": "1275:6:3", + "nodeType": "VariableDeclaration", + "scope": 636, + "src": "1267:14:3", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 609, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1267:7:3", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "id": 621, + "initialValue": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "id": 615, + "name": "_nonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 595, + "src": "1354:6:3", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 616, + "name": "_txs", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 593, + "src": "1372:4:3", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction calldata[] calldata" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction calldata[] calldata" + } + ], + "expression": { + "id": 613, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967295, + "src": "1332:3:3", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 614, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "1336:6:3", + "memberName": "encode", + "nodeType": "MemberAccess", + "src": "1332:10:3", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencode_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 617, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1332:54:3", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 612, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967288, + "src": "1313:9:3", + "typeDescriptions": { + "typeIdentifier": "t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$", + "typeString": "function (bytes memory) pure returns (bytes32)" + } + }, + "id": 618, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1313:81:3", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 619, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 597, + "src": "1402:10:3", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + ], + "id": 611, + "name": "_signatureValidation", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1208, + "src": "1285:20:3", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$_t_bytes_calldata_ptr_$returns$_t_bool_$_t_bytes32_$", + "typeString": "function (bytes32,bytes calldata) view returns (bool,bytes32)" + } + }, + "id": 620, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1285:133:3", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_bool_$_t_bytes32_$", + "typeString": "tuple(bool,bytes32)" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "1252:166:3" + }, + { + "condition": { + "id": 623, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "!", + "prefix": true, + "src": "1429:8:3", + "subExpression": { + "id": 622, + "name": "isValid", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 608, + "src": "1430:7:3", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 630, + "nodeType": "IfStatement", + "src": "1425:72:3", + "trueBody": { + "id": 629, + "nodeType": "Block", + "src": "1439:58:3", + "statements": [ + { + "errorCall": { + "arguments": [ + { + "id": 625, + "name": "txHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 610, + "src": "1471:6:3", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 626, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 597, + "src": "1479:10:3", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + ], + "id": 624, + "name": "InvalidSignature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1279, + "src": "1454:16:3", + "typeDescriptions": { + "typeIdentifier": "t_function_error_pure$_t_bytes32_$_t_bytes_memory_ptr_$returns$__$", + "typeString": "function (bytes32,bytes memory) pure" + } + }, + "id": 627, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1454:36:3", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 628, + "nodeType": "RevertStatement", + "src": "1447:43:3" + } + ] + } + }, + { + "expression": { + "arguments": [ + { + "id": 632, + "name": "txHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 610, + "src": "1544:6:3", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 633, + "name": "_txs", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 593, + "src": "1552:4:3", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction calldata[] calldata" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction calldata[] calldata" + } + ], + "id": 631, + "name": "_execute", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 783, + "src": "1535:8:3", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr_$returns$__$", + "typeString": "function (bytes32,struct IModuleCalls.Transaction calldata[] calldata)" + } + }, + "id": 634, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1535:22:3", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 635, + "nodeType": "ExpressionStatement", + "src": "1535:22:3" + } + ] + }, + "documentation": { + "id": 589, + "nodeType": "StructuredDocumentation", + "src": "566:425:3", + "text": " @notice Allow wallet owner to execute an action\n @dev Relayers must ensure that the gasLimit specified for each transaction\n is acceptable to them. A user could specify large enough that it could\n consume all the gas available.\n @param _txs Transactions to process\n @param _nonce Signature nonce (may contain an encoded space)\n @param _signature Encoded signature" + }, + "functionSelector": "7a9a1628", + "id": 637, + "implemented": true, + "kind": "function", + "modifiers": [ + { + "id": 601, + "kind": "modifierInvocation", + "modifierName": { + "id": 600, + "name": "onlyDelegatecall", + "nameLocations": [ + "1125:16:3" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1084, + "src": "1125:16:3" + }, + "nodeType": "ModifierInvocation", + "src": "1125:16:3" + } + ], + "name": "execute", + "nameLocation": "1003:7:3", + "nodeType": "FunctionDefinition", + "overrides": { + "id": 599, + "nodeType": "OverrideSpecifier", + "overrides": [], + "src": "1108:8:3" + }, + "parameters": { + "id": 598, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 593, + "mutability": "mutable", + "name": "_txs", + "nameLocation": "1039:4:3", + "nodeType": "VariableDeclaration", + "scope": 637, + "src": "1016:27:3", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction[]" + }, + "typeName": { + "baseType": { + "id": 591, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 590, + "name": "Transaction", + "nameLocations": [ + "1016:11:3" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1292, + "src": "1016:11:3" + }, + "referencedDeclaration": 1292, + "src": "1016:11:3", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Transaction_$1292_storage_ptr", + "typeString": "struct IModuleCalls.Transaction" + } + }, + "id": 592, + "nodeType": "ArrayTypeName", + "src": "1016:13:3", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Transaction_$1292_storage_$dyn_storage_ptr", + "typeString": "struct IModuleCalls.Transaction[]" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 595, + "mutability": "mutable", + "name": "_nonce", + "nameLocation": "1057:6:3", + "nodeType": "VariableDeclaration", + "scope": 637, + "src": "1049:14:3", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 594, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1049:7:3", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 597, + "mutability": "mutable", + "name": "_signature", + "nameLocation": "1084:10:3", + "nodeType": "VariableDeclaration", + "scope": 637, + "src": "1069:25:3", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 596, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "1069:5:3", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "1010:88:3" + }, + "returnParameters": { + "id": 602, + "nodeType": "ParameterList", + "parameters": [], + "src": "1142:0:3" + }, + "scope": 833, + "src": "994:568:3", + "stateMutability": "nonpayable", + "virtual": true, + "visibility": "external" + }, + { + "baseFunctions": [ + 1312 + ], + "body": { + "id": 666, + "nodeType": "Block", + "src": "1795:211:3", + "statements": [ + { + "assignments": [ + 649 + ], + "declarations": [ + { + "constant": false, + "id": 649, + "mutability": "mutable", + "name": "txHash", + "nameLocation": "1840:6:3", + "nodeType": "VariableDeclaration", + "scope": 666, + "src": "1832:14:3", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 648, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1832:7:3", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "id": 660, + "initialValue": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "hexValue": "73656c663a", + "id": 655, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1912:7:3", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_bf9461da9f9c0123d3a54c61147a274d8fdb5d5c1e488665fb11b9edbbc32845", + "typeString": "literal_string \"self:\"" + }, + "value": "self:" + }, + { + "id": 656, + "name": "_txs", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 642, + "src": "1921:4:3", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction calldata[] calldata" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_stringliteral_bf9461da9f9c0123d3a54c61147a274d8fdb5d5c1e488665fb11b9edbbc32845", + "typeString": "literal_string \"self:\"" + }, + { + "typeIdentifier": "t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction calldata[] calldata" + } + ], + "expression": { + "id": 653, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967295, + "src": "1901:3:3", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 654, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "1905:6:3", + "memberName": "encode", + "nodeType": "MemberAccess", + "src": "1901:10:3", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencode_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 657, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1901:25:3", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 652, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967288, + "src": "1882:9:3", + "typeDescriptions": { + "typeIdentifier": "t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$", + "typeString": "function (bytes memory) pure returns (bytes32)" + } + }, + "id": 658, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1882:52:3", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "expression": { + "id": 650, + "name": "SequenceBaseSig", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2021, + "src": "1849:15:3", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_SequenceBaseSig_$2021_$", + "typeString": "type(library SequenceBaseSig)" + } + }, + "id": 651, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "1865:9:3", + "memberName": "subdigest", + "nodeType": "MemberAccess", + "referencedDeclaration": 1394, + "src": "1849:25:3", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$returns$_t_bytes32_$", + "typeString": "function (bytes32) view returns (bytes32)" + } + }, + "id": 659, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1849:91:3", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "1832:108:3" + }, + { + "expression": { + "arguments": [ + { + "id": 662, + "name": "txHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 649, + "src": "1988:6:3", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 663, + "name": "_txs", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 642, + "src": "1996:4:3", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction calldata[] calldata" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction calldata[] calldata" + } + ], + "id": 661, + "name": "_execute", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 783, + "src": "1979:8:3", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr_$returns$__$", + "typeString": "function (bytes32,struct IModuleCalls.Transaction calldata[] calldata)" + } + }, + "id": 664, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1979:22:3", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 665, + "nodeType": "ExpressionStatement", + "src": "1979:22:3" + } + ] + }, + "documentation": { + "id": 638, + "nodeType": "StructuredDocumentation", + "src": "1566:133:3", + "text": " @notice Allow wallet to execute an action\n without signing the message\n @param _txs Transactions to execute" + }, + "functionSelector": "61c2926c", + "id": 667, + "implemented": true, + "kind": "function", + "modifiers": [ + { + "id": 646, + "kind": "modifierInvocation", + "modifierName": { + "id": 645, + "name": "onlySelf", + "nameLocations": [ + "1786:8:3" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1115, + "src": "1786:8:3" + }, + "nodeType": "ModifierInvocation", + "src": "1786:8:3" + } + ], + "name": "selfExecute", + "nameLocation": "1711:11:3", + "nodeType": "FunctionDefinition", + "overrides": { + "id": 644, + "nodeType": "OverrideSpecifier", + "overrides": [], + "src": "1769:8:3" + }, + "parameters": { + "id": 643, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 642, + "mutability": "mutable", + "name": "_txs", + "nameLocation": "1751:4:3", + "nodeType": "VariableDeclaration", + "scope": 667, + "src": "1728:27:3", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction[]" + }, + "typeName": { + "baseType": { + "id": 640, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 639, + "name": "Transaction", + "nameLocations": [ + "1728:11:3" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1292, + "src": "1728:11:3" + }, + "referencedDeclaration": 1292, + "src": "1728:11:3", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Transaction_$1292_storage_ptr", + "typeString": "struct IModuleCalls.Transaction" + } + }, + "id": 641, + "nodeType": "ArrayTypeName", + "src": "1728:13:3", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Transaction_$1292_storage_$dyn_storage_ptr", + "typeString": "struct IModuleCalls.Transaction[]" + } + }, + "visibility": "internal" + } + ], + "src": "1722:37:3" + }, + "returnParameters": { + "id": 647, + "nodeType": "ParameterList", + "parameters": [], + "src": "1795:0:3" + }, + "scope": 833, + "src": "1702:304:3", + "stateMutability": "nonpayable", + "virtual": true, + "visibility": "external" + }, + { + "body": { + "id": 782, + "nodeType": "Block", + "src": "2248:1060:3", + "statements": [ + { + "id": 781, + "nodeType": "UncheckedBlock", + "src": "2254:1050:3", + "statements": [ + { + "assignments": [ + 678 + ], + "declarations": [ + { + "constant": false, + "id": 678, + "mutability": "mutable", + "name": "size", + "nameLocation": "2309:4:3", + "nodeType": "VariableDeclaration", + "scope": 781, + "src": "2301:12:3", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 677, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2301:7:3", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 681, + "initialValue": { + "expression": { + "id": 679, + "name": "_txs", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 674, + "src": "2316:4:3", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction calldata[] calldata" + } + }, + "id": 680, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2321:6:3", + "memberName": "length", + "nodeType": "MemberAccess", + "src": "2316:11:3", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "2301:26:3" + }, + { + "body": { + "id": 779, + "nodeType": "Block", + "src": "2370:928:3", + "statements": [ + { + "assignments": [ + 694 + ], + "declarations": [ + { + "constant": false, + "id": 694, + "mutability": "mutable", + "name": "transaction", + "nameLocation": "2401:11:3", + "nodeType": "VariableDeclaration", + "scope": 779, + "src": "2380:32:3", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Transaction_$1292_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction" + }, + "typeName": { + "id": 693, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 692, + "name": "Transaction", + "nameLocations": [ + "2380:11:3" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1292, + "src": "2380:11:3" + }, + "referencedDeclaration": 1292, + "src": "2380:11:3", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Transaction_$1292_storage_ptr", + "typeString": "struct IModuleCalls.Transaction" + } + }, + "visibility": "internal" + } + ], + "id": 698, + "initialValue": { + "baseExpression": { + "id": 695, + "name": "_txs", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 674, + "src": "2415:4:3", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction calldata[] calldata" + } + }, + "id": 697, + "indexExpression": { + "id": 696, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 683, + "src": "2420:1:3", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "2415:7:3", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Transaction_$1292_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction calldata" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "2380:42:3" + }, + { + "assignments": [ + 700 + ], + "declarations": [ + { + "constant": false, + "id": 700, + "mutability": "mutable", + "name": "gasLimit", + "nameLocation": "2440:8:3", + "nodeType": "VariableDeclaration", + "scope": 779, + "src": "2432:16:3", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 699, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2432:7:3", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 703, + "initialValue": { + "expression": { + "id": 701, + "name": "transaction", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 694, + "src": "2451:11:3", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Transaction_$1292_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction calldata" + } + }, + "id": 702, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2463:8:3", + "memberName": "gasLimit", + "nodeType": "MemberAccess", + "referencedDeclaration": 1285, + "src": "2451:20:3", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "2432:39:3" + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 707, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 704, + "name": "gasleft", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967289, + "src": "2486:7:3", + "typeDescriptions": { + "typeIdentifier": "t_function_gasleft_view$__$returns$_t_uint256_$", + "typeString": "function () view returns (uint256)" + } + }, + "id": 705, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2486:9:3", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "id": 706, + "name": "gasLimit", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 700, + "src": "2498:8:3", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "2486:20:3", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 715, + "nodeType": "IfStatement", + "src": "2482:69:3", + "trueBody": { + "errorCall": { + "arguments": [ + { + "id": 709, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 683, + "src": "2528:1:3", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 710, + "name": "gasLimit", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 700, + "src": "2531:8:3", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 711, + "name": "gasleft", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967289, + "src": "2541:7:3", + "typeDescriptions": { + "typeIdentifier": "t_function_gasleft_view$__$returns$_t_uint256_$", + "typeString": "function () view returns (uint256)" + } + }, + "id": 712, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2541:9:3", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 708, + "name": "NotEnoughGas", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1273, + "src": "2515:12:3", + "typeDescriptions": { + "typeIdentifier": "t_function_error_pure$_t_uint256_$_t_uint256_$_t_uint256_$returns$__$", + "typeString": "function (uint256,uint256,uint256) pure" + } + }, + "id": 713, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2515:36:3", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 714, + "nodeType": "RevertStatement", + "src": "2508:43:3" + } + }, + { + "assignments": [ + 717 + ], + "declarations": [ + { + "constant": false, + "id": 717, + "mutability": "mutable", + "name": "success", + "nameLocation": "2567:7:3", + "nodeType": "VariableDeclaration", + "scope": 779, + "src": "2562:12:3", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 716, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "2562:4:3", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "id": 718, + "nodeType": "VariableDeclarationStatement", + "src": "2562:12:3" + }, + { + "condition": { + "expression": { + "id": 719, + "name": "transaction", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 694, + "src": "2588:11:3", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Transaction_$1292_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction calldata" + } + }, + "id": 720, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2600:12:3", + "memberName": "delegateCall", + "nodeType": "MemberAccess", + "referencedDeclaration": 1281, + "src": "2588:24:3", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": { + "id": 758, + "nodeType": "Block", + "src": "2798:201:3", + "statements": [ + { + "expression": { + "id": 756, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 739, + "name": "success", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 717, + "src": "2810:7:3", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "expression": { + "id": 742, + "name": "transaction", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 694, + "src": "2847:11:3", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Transaction_$1292_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction calldata" + } + }, + "id": 743, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2859:6:3", + "memberName": "target", + "nodeType": "MemberAccess", + "referencedDeclaration": 1287, + "src": "2847:18:3", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "expression": { + "id": 744, + "name": "transaction", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 694, + "src": "2879:11:3", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Transaction_$1292_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction calldata" + } + }, + "id": 745, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2891:5:3", + "memberName": "value", + "nodeType": "MemberAccess", + "referencedDeclaration": 1289, + "src": "2879:17:3", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 748, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 746, + "name": "gasLimit", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 700, + "src": "2910:8:3", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "hexValue": "30", + "id": 747, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "2922:1:3", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "2910:13:3", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": { + "id": 751, + "name": "gasLimit", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 700, + "src": "2938:8:3", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 752, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "2910:36:3", + "trueExpression": { + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 749, + "name": "gasleft", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967289, + "src": "2926:7:3", + "typeDescriptions": { + "typeIdentifier": "t_function_gasleft_view$__$returns$_t_uint256_$", + "typeString": "function () view returns (uint256)" + } + }, + "id": 750, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2926:9:3", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "expression": { + "id": 753, + "name": "transaction", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 694, + "src": "2960:11:3", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Transaction_$1292_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction calldata" + } + }, + "id": 754, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2972:4:3", + "memberName": "data", + "nodeType": "MemberAccess", + "referencedDeclaration": 1291, + "src": "2960:16:3", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + ], + "expression": { + "id": 740, + "name": "LibOptim", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2530, + "src": "2820:8:3", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_LibOptim_$2530_$", + "typeString": "type(library LibOptim)" + } + }, + "id": 741, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2829:4:3", + "memberName": "call", + "nodeType": "MemberAccess", + "referencedDeclaration": 2515, + "src": "2820:13:3", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_uint256_$_t_uint256_$_t_bytes_calldata_ptr_$returns$_t_bool_$", + "typeString": "function (address,uint256,uint256,bytes calldata) returns (bool)" + } + }, + "id": 755, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2820:168:3", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "2810:178:3", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 757, + "nodeType": "ExpressionStatement", + "src": "2810:178:3" + } + ] + }, + "id": 759, + "nodeType": "IfStatement", + "src": "2584:415:3", + "trueBody": { + "id": 738, + "nodeType": "Block", + "src": "2614:178:3", + "statements": [ + { + "expression": { + "id": 736, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 721, + "name": "success", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 717, + "src": "2626:7:3", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "expression": { + "id": 724, + "name": "transaction", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 694, + "src": "2671:11:3", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Transaction_$1292_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction calldata" + } + }, + "id": 725, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2683:6:3", + "memberName": "target", + "nodeType": "MemberAccess", + "referencedDeclaration": 1287, + "src": "2671:18:3", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 728, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 726, + "name": "gasLimit", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 700, + "src": "2703:8:3", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "hexValue": "30", + "id": 727, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "2715:1:3", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "2703:13:3", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": { + "id": 731, + "name": "gasLimit", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 700, + "src": "2731:8:3", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 732, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "2703:36:3", + "trueExpression": { + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 729, + "name": "gasleft", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967289, + "src": "2719:7:3", + "typeDescriptions": { + "typeIdentifier": "t_function_gasleft_view$__$returns$_t_uint256_$", + "typeString": "function () view returns (uint256)" + } + }, + "id": 730, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2719:9:3", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "expression": { + "id": 733, + "name": "transaction", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 694, + "src": "2753:11:3", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Transaction_$1292_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction calldata" + } + }, + "id": 734, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2765:4:3", + "memberName": "data", + "nodeType": "MemberAccess", + "referencedDeclaration": 1291, + "src": "2753:16:3", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + ], + "expression": { + "id": 722, + "name": "LibOptim", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2530, + "src": "2636:8:3", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_LibOptim_$2530_$", + "typeString": "type(library LibOptim)" + } + }, + "id": 723, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2645:12:3", + "memberName": "delegatecall", + "nodeType": "MemberAccess", + "referencedDeclaration": 2529, + "src": "2636:21:3", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_address_$_t_uint256_$_t_bytes_calldata_ptr_$returns$_t_bool_$", + "typeString": "function (address,uint256,bytes calldata) returns (bool)" + } + }, + "id": 735, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2636:145:3", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "2626:155:3", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 737, + "nodeType": "ExpressionStatement", + "src": "2626:155:3" + } + ] + } + }, + { + "condition": { + "id": 760, + "name": "success", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 717, + "src": "3013:7:3", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": { + "id": 777, + "nodeType": "Block", + "src": "3078:212:3", + "statements": [ + { + "expression": { + "arguments": [ + { + "expression": { + "id": 768, + "name": "transaction", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 694, + "src": "3171:11:3", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Transaction_$1292_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction calldata" + } + }, + "id": 769, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "3183:13:3", + "memberName": "revertOnError", + "nodeType": "MemberAccess", + "referencedDeclaration": 1283, + "src": "3171:25:3", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + { + "id": 770, + "name": "_txHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 670, + "src": "3210:7:3", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 771, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 683, + "src": "3231:1:3", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "arguments": [], + "expression": { + "argumentTypes": [], + "expression": { + "id": 772, + "name": "LibOptim", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2530, + "src": "3246:8:3", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_LibOptim_$2530_$", + "typeString": "type(library LibOptim)" + } + }, + "id": 773, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "3255:10:3", + "memberName": "returnData", + "nodeType": "MemberAccess", + "referencedDeclaration": 2499, + "src": "3246:19:3", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 774, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3246:21:3", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 767, + "name": "_revertBytes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 807, + "src": "3145:12:3", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bool_$_t_bytes32_$_t_uint256_$_t_bytes_memory_ptr_$returns$__$", + "typeString": "function (bool,bytes32,uint256,bytes memory)" + } + }, + "id": 775, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3145:134:3", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 776, + "nodeType": "ExpressionStatement", + "src": "3145:134:3" + } + ] + }, + "id": 778, + "nodeType": "IfStatement", + "src": "3009:281:3", + "trueBody": { + "id": 766, + "nodeType": "Block", + "src": "3022:50:3", + "statements": [ + { + "eventCall": { + "arguments": [ + { + "id": 762, + "name": "_txHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 670, + "src": "3050:7:3", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 763, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 683, + "src": "3059:1:3", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 761, + "name": "TxExecuted", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1265, + "src": "3039:10:3", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_bytes32_$_t_uint256_$returns$__$", + "typeString": "function (bytes32,uint256)" + } + }, + "id": 764, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3039:22:3", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 765, + "nodeType": "EmitStatement", + "src": "3034:27:3" + } + ] + } + } + ] + }, + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 688, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 686, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 683, + "src": "2355:1:3", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "id": 687, + "name": "size", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 678, + "src": "2359:4:3", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "2355:8:3", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 780, + "initializationExpression": { + "assignments": [ + 683 + ], + "declarations": [ + { + "constant": false, + "id": 683, + "mutability": "mutable", + "name": "i", + "nameLocation": "2348:1:3", + "nodeType": "VariableDeclaration", + "scope": 780, + "src": "2340:9:3", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 682, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2340:7:3", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 685, + "initialValue": { + "hexValue": "30", + "id": 684, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "2352:1:3", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "nodeType": "VariableDeclarationStatement", + "src": "2340:13:3" + }, + "loopExpression": { + "expression": { + "id": 690, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": false, + "src": "2365:3:3", + "subExpression": { + "id": 689, + "name": "i", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 683, + "src": "2365:1:3", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 691, + "nodeType": "ExpressionStatement", + "src": "2365:3:3" + }, + "nodeType": "ForStatement", + "src": "2335:963:3" + } + ] + } + ] + }, + "documentation": { + "id": 668, + "nodeType": "StructuredDocumentation", + "src": "2010:151:3", + "text": " @notice Executes a list of transactions\n @param _txHash Hash of the batch of transactions\n @param _txs Transactions to execute" + }, + "id": 783, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "_execute", + "nameLocation": "2173:8:3", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 675, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 670, + "mutability": "mutable", + "name": "_txHash", + "nameLocation": "2195:7:3", + "nodeType": "VariableDeclaration", + "scope": 783, + "src": "2187:15:3", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 669, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2187:7:3", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 674, + "mutability": "mutable", + "name": "_txs", + "nameLocation": "2231:4:3", + "nodeType": "VariableDeclaration", + "scope": 783, + "src": "2208:27:3", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction[]" + }, + "typeName": { + "baseType": { + "id": 672, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 671, + "name": "Transaction", + "nameLocations": [ + "2208:11:3" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1292, + "src": "2208:11:3" + }, + "referencedDeclaration": 1292, + "src": "2208:11:3", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Transaction_$1292_storage_ptr", + "typeString": "struct IModuleCalls.Transaction" + } + }, + "id": 673, + "nodeType": "ArrayTypeName", + "src": "2208:13:3", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Transaction_$1292_storage_$dyn_storage_ptr", + "typeString": "struct IModuleCalls.Transaction[]" + } + }, + "visibility": "internal" + } + ], + "src": "2181:58:3" + }, + "returnParameters": { + "id": 676, + "nodeType": "ParameterList", + "parameters": [], + "src": "2248:0:3" + }, + "scope": 833, + "src": "2164:1144:3", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "private" + }, + { + "body": { + "id": 806, + "nodeType": "Block", + "src": "3771:159:3", + "statements": [ + { + "condition": { + "id": 795, + "name": "_revertOnError", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 786, + "src": "3781:14:3", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": { + "id": 804, + "nodeType": "Block", + "src": "3872:54:3", + "statements": [ + { + "eventCall": { + "arguments": [ + { + "id": 799, + "name": "_txHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 788, + "src": "3894:7:3", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 800, + "name": "_index", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 790, + "src": "3903:6:3", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 801, + "name": "_reason", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 792, + "src": "3911:7:3", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 798, + "name": "TxFailed", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1259, + "src": "3885:8:3", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_bytes32_$_t_uint256_$_t_bytes_memory_ptr_$returns$__$", + "typeString": "function (bytes32,uint256,bytes memory)" + } + }, + "id": 802, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3885:34:3", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 803, + "nodeType": "EmitStatement", + "src": "3880:39:3" + } + ] + }, + "id": 805, + "nodeType": "IfStatement", + "src": "3777:149:3", + "trueBody": { + "id": 797, + "nodeType": "Block", + "src": "3797:69:3", + "statements": [ + { + "AST": { + "nodeType": "YulBlock", + "src": "3814:46:3", + "statements": [ + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "name": "_reason", + "nodeType": "YulIdentifier", + "src": "3827:7:3" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3836:4:3", + "type": "", + "value": "0x20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "3823:3:3" + }, + "nodeType": "YulFunctionCall", + "src": "3823:18:3" + }, + { + "arguments": [ + { + "name": "_reason", + "nodeType": "YulIdentifier", + "src": "3849:7:3" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "3843:5:3" + }, + "nodeType": "YulFunctionCall", + "src": "3843:14:3" + } + ], + "functionName": { + "name": "revert", + "nodeType": "YulIdentifier", + "src": "3816:6:3" + }, + "nodeType": "YulFunctionCall", + "src": "3816:42:3" + }, + "nodeType": "YulExpressionStatement", + "src": "3816:42:3" + } + ] + }, + "evmVersion": "paris", + "externalReferences": [ + { + "declaration": 792, + "isOffset": false, + "isSlot": false, + "src": "3827:7:3", + "valueSize": 1 + }, + { + "declaration": 792, + "isOffset": false, + "isSlot": false, + "src": "3849:7:3", + "valueSize": 1 + } + ], + "id": 796, + "nodeType": "InlineAssembly", + "src": "3805:55:3" + } + ] + } + } + ] + }, + "documentation": { + "id": 784, + "nodeType": "StructuredDocumentation", + "src": "3312:329:3", + "text": " @notice Logs a failed transaction, reverts if the transaction is not optional\n @param _revertOnError Signals if it should revert or just log\n @param _txHash Hash of the transaction\n @param _index Index of the transaction in the batch\n @param _reason Encoded revert message" + }, + "id": 807, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "_revertBytes", + "nameLocation": "3653:12:3", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 793, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 786, + "mutability": "mutable", + "name": "_revertOnError", + "nameLocation": "3676:14:3", + "nodeType": "VariableDeclaration", + "scope": 807, + "src": "3671:19:3", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 785, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "3671:4:3", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 788, + "mutability": "mutable", + "name": "_txHash", + "nameLocation": "3704:7:3", + "nodeType": "VariableDeclaration", + "scope": 807, + "src": "3696:15:3", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 787, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "3696:7:3", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 790, + "mutability": "mutable", + "name": "_index", + "nameLocation": "3725:6:3", + "nodeType": "VariableDeclaration", + "scope": 807, + "src": "3717:14:3", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 789, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3717:7:3", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 792, + "mutability": "mutable", + "name": "_reason", + "nameLocation": "3750:7:3", + "nodeType": "VariableDeclaration", + "scope": 807, + "src": "3737:20:3", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 791, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "3737:5:3", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "3665:96:3" + }, + "returnParameters": { + "id": 794, + "nodeType": "ParameterList", + "parameters": [], + "src": "3771:0:3" + }, + "scope": 833, + "src": "3644:286:3", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + }, + { + "baseFunctions": [ + 919 + ], + "body": { + "id": 831, + "nodeType": "Block", + "src": "4232:139:3", + "statements": [ + { + "condition": { + "commonType": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + }, + "id": 821, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 816, + "name": "_interfaceID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 810, + "src": "4242:12:3", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "expression": { + "arguments": [ + { + "id": 818, + "name": "IModuleCalls", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1313, + "src": "4263:12:3", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_IModuleCalls_$1313_$", + "typeString": "type(contract IModuleCalls)" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_type$_t_contract$_IModuleCalls_$1313_$", + "typeString": "type(contract IModuleCalls)" + } + ], + "id": 817, + "name": "type", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967269, + "src": "4258:4:3", + "typeDescriptions": { + "typeIdentifier": "t_function_metatype_pure$__$returns$__$", + "typeString": "function () pure" + } + }, + "id": 819, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "4258:18:3", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_magic_meta_type_t_contract$_IModuleCalls_$1313", + "typeString": "type(contract IModuleCalls)" + } + }, + "id": 820, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "4277:11:3", + "memberName": "interfaceId", + "nodeType": "MemberAccess", + "src": "4258:30:3", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "src": "4242:46:3", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 825, + "nodeType": "IfStatement", + "src": "4238:78:3", + "trueBody": { + "id": 824, + "nodeType": "Block", + "src": "4290:26:3", + "statements": [ + { + "expression": { + "hexValue": "74727565", + "id": 822, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4305:4:3", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "functionReturnParameters": 815, + "id": 823, + "nodeType": "Return", + "src": "4298:11:3" + } + ] + } + }, + { + "expression": { + "arguments": [ + { + "id": 828, + "name": "_interfaceID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 810, + "src": "4353:12:3", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + ], + "expression": { + "id": 826, + "name": "super", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967271, + "src": "4329:5:3", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_super$_ModuleCalls_$833_$", + "typeString": "type(contract super ModuleCalls)" + } + }, + "id": 827, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "4335:17:3", + "memberName": "supportsInterface", + "nodeType": "MemberAccess", + "referencedDeclaration": 919, + "src": "4329:23:3", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes4_$returns$_t_bool_$", + "typeString": "function (bytes4) pure returns (bool)" + } + }, + "id": 829, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "4329:37:3", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "functionReturnParameters": 815, + "id": 830, + "nodeType": "Return", + "src": "4322:44:3" + } + ] + }, + "documentation": { + "id": 808, + "nodeType": "StructuredDocumentation", + "src": "3934:203:3", + "text": " @notice Query if a contract implements an interface\n @param _interfaceID The interface identifier, as specified in ERC-165\n @return `true` if the contract implements `_interfaceID`" + }, + "functionSelector": "01ffc9a7", + "id": 832, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "supportsInterface", + "nameLocation": "4149:17:3", + "nodeType": "FunctionDefinition", + "overrides": { + "id": 812, + "nodeType": "OverrideSpecifier", + "overrides": [], + "src": "4195:8:3" + }, + "parameters": { + "id": 811, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 810, + "mutability": "mutable", + "name": "_interfaceID", + "nameLocation": "4174:12:3", + "nodeType": "VariableDeclaration", + "scope": 832, + "src": "4167:19:3", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + }, + "typeName": { + "id": 809, + "name": "bytes4", + "nodeType": "ElementaryTypeName", + "src": "4167:6:3", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "visibility": "internal" + } + ], + "src": "4166:21:3" + }, + "returnParameters": { + "id": 815, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 814, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 832, + "src": "4226:4:3", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 813, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "4226:4:3", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "src": "4225:6:3" + }, + "scope": 833, + "src": "4140:231:3", + "stateMutability": "pure", + "virtual": true, + "visibility": "public" + } + ], + "scope": 834, + "src": "436:3937:3", + "usedErrors": [ + 938, + 1057, + 1093, + 1193, + 1197, + 1273, + 1279 + ] + } + ], + "src": "39:4335:3" + }, + "id": 3 + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol": { + "ast": { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleCreator.sol", + "exportedSymbols": { + "IModuleCreator": [ + 1328 + ], + "ModuleCreator": [ + 902 + ], + "ModuleERC165": [ + 920 + ], + "ModuleSelfAuth": [ + 1116 + ] + }, + "id": 903, + "license": "Apache-2.0", + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 835, + "literals": [ + "solidity", + "0.8", + ".18" + ], + "nodeType": "PragmaDirective", + "src": "39:23:4" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCreator.sol", + "file": "./interfaces/IModuleCreator.sol", + "id": 836, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 903, + "sourceUnit": 1329, + "src": "64:41:4", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol", + "file": "./ModuleSelfAuth.sol", + "id": 837, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 903, + "sourceUnit": 1117, + "src": "107:30:4", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleERC165.sol", + "file": "./ModuleERC165.sol", + "id": 838, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 903, + "sourceUnit": 921, + "src": "138:28:4", + "symbolAliases": [], + "unitAlias": "" + }, + { + "abstract": false, + "baseContracts": [ + { + "baseName": { + "id": 839, + "name": "IModuleCreator", + "nameLocations": [ + "195:14:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1328, + "src": "195:14:4" + }, + "id": 840, + "nodeType": "InheritanceSpecifier", + "src": "195:14:4" + }, + { + "baseName": { + "id": 841, + "name": "ModuleERC165", + "nameLocations": [ + "211:12:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 920, + "src": "211:12:4" + }, + "id": 842, + "nodeType": "InheritanceSpecifier", + "src": "211:12:4" + }, + { + "baseName": { + "id": 843, + "name": "ModuleSelfAuth", + "nameLocations": [ + "225:14:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1116, + "src": "225:14:4" + }, + "id": 844, + "nodeType": "InheritanceSpecifier", + "src": "225:14:4" + } + ], + "canonicalName": "ModuleCreator", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 902, + "linearizedBaseContracts": [ + 902, + 1116, + 920, + 1328 + ], + "name": "ModuleCreator", + "nameLocation": "178:13:4", + "nodeType": "ContractDefinition", + "nodes": [ + { + "anonymous": false, + "eventSelector": "a506ad4e7f05eceba62a023c3219e5bd98a615f4fa87e2afb08a2da5cf62bf0c", + "id": 848, + "name": "CreatedContract", + "nameLocation": "250:15:4", + "nodeType": "EventDefinition", + "parameters": { + "id": 847, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 846, + "indexed": false, + "mutability": "mutable", + "name": "_contract", + "nameLocation": "274:9:4", + "nodeType": "VariableDeclaration", + "scope": 848, + "src": "266:17:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 845, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "266:7:4", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "265:19:4" + }, + "src": "244:41:4" + }, + { + "baseFunctions": [ + 1327 + ], + "body": { + "id": 875, + "nodeType": "Block", + "src": "564:168:4", + "statements": [ + { + "AST": { + "nodeType": "YulBlock", + "src": "579:61:4", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "581:57:4", + "value": { + "arguments": [ + { + "arguments": [], + "functionName": { + "name": "callvalue", + "nodeType": "YulIdentifier", + "src": "596:9:4" + }, + "nodeType": "YulFunctionCall", + "src": "596:11:4" + }, + { + "arguments": [ + { + "name": "_code", + "nodeType": "YulIdentifier", + "src": "613:5:4" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "620:2:4", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "609:3:4" + }, + "nodeType": "YulFunctionCall", + "src": "609:14:4" + }, + { + "arguments": [ + { + "name": "_code", + "nodeType": "YulIdentifier", + "src": "631:5:4" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "625:5:4" + }, + "nodeType": "YulFunctionCall", + "src": "625:12:4" + } + ], + "functionName": { + "name": "create", + "nodeType": "YulIdentifier", + "src": "589:6:4" + }, + "nodeType": "YulFunctionCall", + "src": "589:49:4" + }, + "variableNames": [ + { + "name": "addr", + "nodeType": "YulIdentifier", + "src": "581:4:4" + } + ] + } + ] + }, + "evmVersion": "paris", + "externalReferences": [ + { + "declaration": 851, + "isOffset": false, + "isSlot": false, + "src": "613:5:4", + "valueSize": 1 + }, + { + "declaration": 851, + "isOffset": false, + "isSlot": false, + "src": "631:5:4", + "valueSize": 1 + }, + { + "declaration": 857, + "isOffset": false, + "isSlot": false, + "src": "581:4:4", + "valueSize": 1 + } + ], + "id": 859, + "nodeType": "InlineAssembly", + "src": "570:70:4" + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 865, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 860, + "name": "addr", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 857, + "src": "649:4:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "arguments": [ + { + "hexValue": "30", + "id": 863, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "665:1:4", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 862, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "657:7:4", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": { + "id": 861, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "657:7:4", + "typeDescriptions": {} + } + }, + "id": 864, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "657:10:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "649:18:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 870, + "nodeType": "IfStatement", + "src": "645:50:4", + "trueBody": { + "errorCall": { + "arguments": [ + { + "id": 867, + "name": "_code", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 851, + "src": "689:5:4", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 866, + "name": "CreateFailed", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1319, + "src": "676:12:4", + "typeDescriptions": { + "typeIdentifier": "t_function_error_pure$_t_bytes_memory_ptr_$returns$__$", + "typeString": "function (bytes memory) pure" + } + }, + "id": 868, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "676:19:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 869, + "nodeType": "RevertStatement", + "src": "669:26:4" + } + }, + { + "eventCall": { + "arguments": [ + { + "id": 872, + "name": "addr", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 857, + "src": "722:4:4", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 871, + "name": "CreatedContract", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 848, + "src": "706:15:4", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_address_$returns$__$", + "typeString": "function (address)" + } + }, + "id": 873, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "706:21:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 874, + "nodeType": "EmitStatement", + "src": "701:26:4" + } + ] + }, + "documentation": { + "id": 849, + "nodeType": "StructuredDocumentation", + "src": "289:164:4", + "text": " @notice Creates a contract forwarding eth value\n @param _code Creation code of the contract\n @return addr The address of the created contract" + }, + "functionSelector": "90042baf", + "id": 876, + "implemented": true, + "kind": "function", + "modifiers": [ + { + "id": 855, + "kind": "modifierInvocation", + "modifierName": { + "id": 854, + "name": "onlySelf", + "nameLocations": [ + "532:8:4" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1115, + "src": "532:8:4" + }, + "nodeType": "ModifierInvocation", + "src": "532:8:4" + } + ], + "name": "createContract", + "nameLocation": "465:14:4", + "nodeType": "FunctionDefinition", + "overrides": { + "id": 853, + "nodeType": "OverrideSpecifier", + "overrides": [], + "src": "507:8:4" + }, + "parameters": { + "id": 852, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 851, + "mutability": "mutable", + "name": "_code", + "nameLocation": "493:5:4", + "nodeType": "VariableDeclaration", + "scope": 876, + "src": "480:18:4", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 850, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "480:5:4", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "479:20:4" + }, + "returnParameters": { + "id": 858, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 857, + "mutability": "mutable", + "name": "addr", + "nameLocation": "558:4:4", + "nodeType": "VariableDeclaration", + "scope": 876, + "src": "550:12:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 856, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "550:7:4", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "549:14:4" + }, + "scope": 902, + "src": "456:276:4", + "stateMutability": "payable", + "virtual": true, + "visibility": "public" + }, + { + "baseFunctions": [ + 919 + ], + "body": { + "id": 900, + "nodeType": "Block", + "src": "1034:141:4", + "statements": [ + { + "condition": { + "commonType": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + }, + "id": 890, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 885, + "name": "_interfaceID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 879, + "src": "1044:12:4", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "expression": { + "arguments": [ + { + "id": 887, + "name": "IModuleCreator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1328, + "src": "1065:14:4", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_IModuleCreator_$1328_$", + "typeString": "type(contract IModuleCreator)" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_type$_t_contract$_IModuleCreator_$1328_$", + "typeString": "type(contract IModuleCreator)" + } + ], + "id": 886, + "name": "type", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967269, + "src": "1060:4:4", + "typeDescriptions": { + "typeIdentifier": "t_function_metatype_pure$__$returns$__$", + "typeString": "function () pure" + } + }, + "id": 888, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1060:20:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_magic_meta_type_t_contract$_IModuleCreator_$1328", + "typeString": "type(contract IModuleCreator)" + } + }, + "id": 889, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "1081:11:4", + "memberName": "interfaceId", + "nodeType": "MemberAccess", + "src": "1060:32:4", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "src": "1044:48:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 894, + "nodeType": "IfStatement", + "src": "1040:80:4", + "trueBody": { + "id": 893, + "nodeType": "Block", + "src": "1094:26:4", + "statements": [ + { + "expression": { + "hexValue": "74727565", + "id": 891, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1109:4:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + }, + "functionReturnParameters": 884, + "id": 892, + "nodeType": "Return", + "src": "1102:11:4" + } + ] + } + }, + { + "expression": { + "arguments": [ + { + "id": 897, + "name": "_interfaceID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 879, + "src": "1157:12:4", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + ], + "expression": { + "id": 895, + "name": "super", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967271, + "src": "1133:5:4", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_super$_ModuleCreator_$902_$", + "typeString": "type(contract super ModuleCreator)" + } + }, + "id": 896, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "1139:17:4", + "memberName": "supportsInterface", + "nodeType": "MemberAccess", + "referencedDeclaration": 919, + "src": "1133:23:4", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes4_$returns$_t_bool_$", + "typeString": "function (bytes4) pure returns (bool)" + } + }, + "id": 898, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1133:37:4", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "functionReturnParameters": 884, + "id": 899, + "nodeType": "Return", + "src": "1126:44:4" + } + ] + }, + "documentation": { + "id": 877, + "nodeType": "StructuredDocumentation", + "src": "736:203:4", + "text": " @notice Query if a contract implements an interface\n @param _interfaceID The interface identifier, as specified in ERC-165\n @return `true` if the contract implements `_interfaceID`" + }, + "functionSelector": "01ffc9a7", + "id": 901, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "supportsInterface", + "nameLocation": "951:17:4", + "nodeType": "FunctionDefinition", + "overrides": { + "id": 881, + "nodeType": "OverrideSpecifier", + "overrides": [], + "src": "997:8:4" + }, + "parameters": { + "id": 880, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 879, + "mutability": "mutable", + "name": "_interfaceID", + "nameLocation": "976:12:4", + "nodeType": "VariableDeclaration", + "scope": 901, + "src": "969:19:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + }, + "typeName": { + "id": 878, + "name": "bytes4", + "nodeType": "ElementaryTypeName", + "src": "969:6:4", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "visibility": "internal" + } + ], + "src": "968:21:4" + }, + "returnParameters": { + "id": 884, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 883, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 901, + "src": "1028:4:4", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 882, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "1028:4:4", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "src": "1027:6:4" + }, + "scope": 902, + "src": "942:233:4", + "stateMutability": "pure", + "virtual": true, + "visibility": "public" + } + ], + "scope": 903, + "src": "169:1008:4", + "usedErrors": [ + 1093, + 1319 + ] + } + ], + "src": "39:1139:4" + }, + "id": 4 + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleERC165.sol": { + "ast": { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleERC165.sol", + "exportedSymbols": { + "ModuleERC165": [ + 920 + ] + }, + "id": 921, + "license": "Apache-2.0", + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 904, + "literals": [ + "solidity", + "0.8", + ".18" + ], + "nodeType": "PragmaDirective", + "src": "39:23:5" + }, + { + "abstract": true, + "baseContracts": [], + "canonicalName": "ModuleERC165", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 920, + "linearizedBaseContracts": [ + 920 + ], + "name": "ModuleERC165", + "nameLocation": "83:12:5", + "nodeType": "ContractDefinition", + "nodes": [ + { + "body": { + "id": 918, + "nodeType": "Block", + "src": "696:65:5", + "statements": [ + { + "expression": { + "commonType": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + }, + "id": 916, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 912, + "name": "_interfaceID", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 907, + "src": "709:12:5", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "expression": { + "expression": { + "id": 913, + "name": "this", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967268, + "src": "725:4:5", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ModuleERC165_$920", + "typeString": "contract ModuleERC165" + } + }, + "id": 914, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "730:17:5", + "memberName": "supportsInterface", + "nodeType": "MemberAccess", + "referencedDeclaration": 919, + "src": "725:22:5", + "typeDescriptions": { + "typeIdentifier": "t_function_external_pure$_t_bytes4_$returns$_t_bool_$", + "typeString": "function (bytes4) pure external returns (bool)" + } + }, + "id": 915, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "748:8:5", + "memberName": "selector", + "nodeType": "MemberAccess", + "src": "725:31:5", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "src": "709:47:5", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "functionReturnParameters": 911, + "id": 917, + "nodeType": "Return", + "src": "702:54:5" + } + ] + }, + "documentation": { + "id": 905, + "nodeType": "StructuredDocumentation", + "src": "100:510:5", + "text": " @notice Query if a contract implements an interface\n @param _interfaceID The interface identifier, as specified in ERC-165\n @dev Adding new hooks will not lead to them being reported by this function\n without upgrading the wallet. In addition, developers must ensure that\n all inherited contracts by the main module don't conflict and are accounted\n to be supported by the supportsInterface method.\n @return `true` if the contract implements `_interfaceID`" + }, + "functionSelector": "01ffc9a7", + "id": 919, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "supportsInterface", + "nameLocation": "622:17:5", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 908, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 907, + "mutability": "mutable", + "name": "_interfaceID", + "nameLocation": "647:12:5", + "nodeType": "VariableDeclaration", + "scope": 919, + "src": "640:19:5", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + }, + "typeName": { + "id": 906, + "name": "bytes4", + "nodeType": "ElementaryTypeName", + "src": "640:6:5", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "visibility": "internal" + } + ], + "src": "639:21:5" + }, + "returnParameters": { + "id": 911, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 910, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 919, + "src": "690:4:5", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 909, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "690:4:5", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "src": "689:6:5" + }, + "scope": 920, + "src": "613:148:5", + "stateMutability": "pure", + "virtual": true, + "visibility": "public" + } + ], + "scope": 921, + "src": "65:698:5", + "usedErrors": [] + } + ], + "src": "39:725:5" + }, + "id": 5 + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol": { + "ast": { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleNonce.sol", + "exportedSymbols": { + "ModuleNonce": [ + 1051 + ], + "ModuleStorage": [ + 1179 + ], + "SubModuleNonce": [ + 2324 + ] + }, + "id": 1052, + "license": "Apache-2.0", + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 922, + "literals": [ + "solidity", + "0.8", + ".18" + ], + "nodeType": "PragmaDirective", + "src": "39:23:6" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol", + "file": "./ModuleStorage.sol", + "id": 923, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 1052, + "sourceUnit": 1180, + "src": "64:29:6", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol", + "file": "./submodules/nonce/SubModuleNonce.sol", + "id": 924, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 1052, + "sourceUnit": 2325, + "src": "95:47:6", + "symbolAliases": [], + "unitAlias": "" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "ModuleNonce", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 1051, + "linearizedBaseContracts": [ + 1051 + ], + "name": "ModuleNonce", + "nameLocation": "154:11:6", + "nodeType": "ContractDefinition", + "nodes": [ + { + "anonymous": false, + "eventSelector": "1f180c27086c7a39ea2a7b25239d1ab92348f07ca7bb59d1438fcf527568f881", + "id": 930, + "name": "NonceChange", + "nameLocation": "188:11:6", + "nodeType": "EventDefinition", + "parameters": { + "id": 929, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 926, + "indexed": false, + "mutability": "mutable", + "name": "_space", + "nameLocation": "208:6:6", + "nodeType": "VariableDeclaration", + "scope": 930, + "src": "200:14:6", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 925, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "200:7:6", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 928, + "indexed": false, + "mutability": "mutable", + "name": "_newNonce", + "nameLocation": "224:9:6", + "nodeType": "VariableDeclaration", + "scope": 930, + "src": "216:17:6", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 927, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "216:7:6", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "199:35:6" + }, + "src": "182:53:6" + }, + { + "errorSelector": "9b6514f4", + "id": 938, + "name": "BadNonce", + "nameLocation": "257:8:6", + "nodeType": "ErrorDefinition", + "parameters": { + "id": 937, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 932, + "mutability": "mutable", + "name": "_space", + "nameLocation": "274:6:6", + "nodeType": "VariableDeclaration", + "scope": 938, + "src": "266:14:6", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 931, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "266:7:6", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 934, + "mutability": "mutable", + "name": "_provided", + "nameLocation": "290:9:6", + "nodeType": "VariableDeclaration", + "scope": 938, + "src": "282:17:6", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 933, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "282:7:6", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 936, + "mutability": "mutable", + "name": "_current", + "nameLocation": "309:8:6", + "nodeType": "VariableDeclaration", + "scope": 938, + "src": "301:16:6", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 935, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "301:7:6", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "265:53:6" + }, + "src": "251:68:6" + }, + { + "constant": true, + "id": 944, + "mutability": "constant", + "name": "NONCE_KEY", + "nameLocation": "433:9:6", + "nodeType": "VariableDeclaration", + "scope": 1051, + "src": "408:112:6", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 939, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "408:7:6", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": { + "arguments": [ + { + "hexValue": "307838643062663166643632336436323863373431333632633132383939343865353762336532393035323138633637366433653639616265653336643661653265", + "id": 942, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "453:66:6", + "typeDescriptions": { + "typeIdentifier": "t_rational_63797217120035063192835264220719863994123296260065566452921212441289018486318_by_1", + "typeString": "int_const 6379...(69 digits omitted)...6318" + }, + "value": "0x8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_63797217120035063192835264220719863994123296260065566452921212441289018486318_by_1", + "typeString": "int_const 6379...(69 digits omitted)...6318" + } + ], + "id": 941, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "445:7:6", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes32_$", + "typeString": "type(bytes32)" + }, + "typeName": { + "id": 940, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "445:7:6", + "typeDescriptions": {} + } + }, + "id": 943, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "445:75:6", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "private" + }, + { + "body": { + "id": 954, + "nodeType": "Block", + "src": "727:30:6", + "statements": [ + { + "expression": { + "arguments": [ + { + "hexValue": "30", + "id": 951, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "750:1:6", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 950, + "name": "readNonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 976, + "src": "740:9:6", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_uint256_$returns$_t_uint256_$", + "typeString": "function (uint256) view returns (uint256)" + } + }, + "id": 952, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "740:12:6", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 949, + "id": 953, + "nodeType": "Return", + "src": "733:19:6" + } + ] + }, + "documentation": { + "id": 945, + "nodeType": "StructuredDocumentation", + "src": "525:142:6", + "text": " @notice Returns the next nonce of the default nonce space\n @dev The default nonce space is 0x00\n @return The next nonce" + }, + "functionSelector": "affed0e0", + "id": 955, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "nonce", + "nameLocation": "679:5:6", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 946, + "nodeType": "ParameterList", + "parameters": [], + "src": "684:2:6" + }, + "returnParameters": { + "id": 949, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 948, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 955, + "src": "718:7:6", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 947, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "718:7:6", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "717:9:6" + }, + "scope": 1051, + "src": "670:87:6", + "stateMutability": "view", + "virtual": true, + "visibility": "external" + }, + { + "body": { + "id": 975, + "nodeType": "Block", + "src": "1011:83:6", + "statements": [ + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "id": 967, + "name": "NONCE_KEY", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 944, + "src": "1061:9:6", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "arguments": [ + { + "id": 970, + "name": "_space", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 958, + "src": "1080:6:6", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 969, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "1072:7:6", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes32_$", + "typeString": "type(bytes32)" + }, + "typeName": { + "id": 968, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1072:7:6", + "typeDescriptions": {} + } + }, + "id": 971, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1072:15:6", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "expression": { + "id": 965, + "name": "ModuleStorage", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1179, + "src": "1032:13:6", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_ModuleStorage_$1179_$", + "typeString": "type(library ModuleStorage)" + } + }, + "id": 966, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "1046:14:6", + "memberName": "readBytes32Map", + "nodeType": "MemberAccess", + "referencedDeclaration": 1178, + "src": "1032:28:6", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$_t_bytes32_$returns$_t_bytes32_$", + "typeString": "function (bytes32,bytes32) view returns (bytes32)" + } + }, + "id": 972, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1032:56:6", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 964, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "1024:7:6", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint256_$", + "typeString": "type(uint256)" + }, + "typeName": { + "id": 963, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1024:7:6", + "typeDescriptions": {} + } + }, + "id": 973, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1024:65:6", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "functionReturnParameters": 962, + "id": 974, + "nodeType": "Return", + "src": "1017:72:6" + } + ] + }, + "documentation": { + "id": 956, + "nodeType": "StructuredDocumentation", + "src": "761:174:6", + "text": " @notice Returns the next nonce of the given nonce space\n @param _space Nonce space, each space keeps an independent nonce count\n @return The next nonce" + }, + "functionSelector": "8c3f5563", + "id": 976, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "readNonce", + "nameLocation": "947:9:6", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 959, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 958, + "mutability": "mutable", + "name": "_space", + "nameLocation": "965:6:6", + "nodeType": "VariableDeclaration", + "scope": 976, + "src": "957:14:6", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 957, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "957:7:6", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "956:16:6" + }, + "returnParameters": { + "id": 962, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 961, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 976, + "src": "1002:7:6", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 960, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1002:7:6", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "1001:9:6" + }, + "scope": 1051, + "src": "938:156:6", + "stateMutability": "view", + "virtual": true, + "visibility": "public" + }, + { + "body": { + "id": 998, + "nodeType": "Block", + "src": "1356:85:6", + "statements": [ + { + "expression": { + "arguments": [ + { + "id": 987, + "name": "NONCE_KEY", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 944, + "src": "1392:9:6", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "arguments": [ + { + "id": 990, + "name": "_space", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 979, + "src": "1411:6:6", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 989, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "1403:7:6", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes32_$", + "typeString": "type(bytes32)" + }, + "typeName": { + "id": 988, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1403:7:6", + "typeDescriptions": {} + } + }, + "id": 991, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1403:15:6", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "arguments": [ + { + "id": 994, + "name": "_nonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 981, + "src": "1428:6:6", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 993, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "1420:7:6", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes32_$", + "typeString": "type(bytes32)" + }, + "typeName": { + "id": 992, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1420:7:6", + "typeDescriptions": {} + } + }, + "id": 995, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1420:15:6", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "expression": { + "id": 984, + "name": "ModuleStorage", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1179, + "src": "1362:13:6", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_ModuleStorage_$1179_$", + "typeString": "type(library ModuleStorage)" + } + }, + "id": 986, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "1376:15:6", + "memberName": "writeBytes32Map", + "nodeType": "MemberAccess", + "referencedDeclaration": 1157, + "src": "1362:29:6", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_bytes32_$_t_bytes32_$_t_bytes32_$returns$__$", + "typeString": "function (bytes32,bytes32,bytes32)" + } + }, + "id": 996, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1362:74:6", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 997, + "nodeType": "ExpressionStatement", + "src": "1362:74:6" + } + ] + }, + "documentation": { + "id": 977, + "nodeType": "StructuredDocumentation", + "src": "1098:193:6", + "text": " @notice Changes the next nonce of the given nonce space\n @param _space Nonce space, each space keeps an independent nonce count\n @param _nonce Nonce to write on the space" + }, + "id": 999, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "_writeNonce", + "nameLocation": "1303:11:6", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 982, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 979, + "mutability": "mutable", + "name": "_space", + "nameLocation": "1323:6:6", + "nodeType": "VariableDeclaration", + "scope": 999, + "src": "1315:14:6", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 978, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1315:7:6", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 981, + "mutability": "mutable", + "name": "_nonce", + "nameLocation": "1339:6:6", + "nodeType": "VariableDeclaration", + "scope": 999, + "src": "1331:14:6", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 980, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1331:7:6", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "1314:32:6" + }, + "returnParameters": { + "id": 983, + "nodeType": "ParameterList", + "parameters": [], + "src": "1356:0:6" + }, + "scope": 1051, + "src": "1294:147:6", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + }, + { + "body": { + "id": 1049, + "nodeType": "Block", + "src": "1628:446:6", + "statements": [ + { + "assignments": [ + 1006, + 1008 + ], + "declarations": [ + { + "constant": false, + "id": 1006, + "mutability": "mutable", + "name": "space", + "nameLocation": "1689:5:6", + "nodeType": "VariableDeclaration", + "scope": 1049, + "src": "1681:13:6", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1005, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1681:7:6", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1008, + "mutability": "mutable", + "name": "providedNonce", + "nameLocation": "1704:13:6", + "nodeType": "VariableDeclaration", + "scope": 1049, + "src": "1696:21:6", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1007, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1696:7:6", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 1013, + "initialValue": { + "arguments": [ + { + "id": 1011, + "name": "_rawNonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1002, + "src": "1748:9:6", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "id": 1009, + "name": "SubModuleNonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2324, + "src": "1721:14:6", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_SubModuleNonce_$2324_$", + "typeString": "type(library SubModuleNonce)" + } + }, + "id": 1010, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "1736:11:6", + "memberName": "decodeNonce", + "nodeType": "MemberAccess", + "referencedDeclaration": 2323, + "src": "1721:26:6", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_uint256_$returns$_t_uint256_$_t_uint256_$", + "typeString": "function (uint256) pure returns (uint256,uint256)" + } + }, + "id": 1012, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1721:37:6", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_uint256_$", + "typeString": "tuple(uint256,uint256)" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "1680:78:6" + }, + { + "assignments": [ + 1015 + ], + "declarations": [ + { + "constant": false, + "id": 1015, + "mutability": "mutable", + "name": "currentNonce", + "nameLocation": "1773:12:6", + "nodeType": "VariableDeclaration", + "scope": 1049, + "src": "1765:20:6", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1014, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1765:7:6", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 1019, + "initialValue": { + "arguments": [ + { + "id": 1017, + "name": "space", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1006, + "src": "1798:5:6", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 1016, + "name": "readNonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 976, + "src": "1788:9:6", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_uint256_$returns$_t_uint256_$", + "typeString": "function (uint256) view returns (uint256)" + } + }, + "id": 1018, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1788:16:6", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "1765:39:6" + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 1022, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 1020, + "name": "currentNonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1015, + "src": "1814:12:6", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "id": 1021, + "name": "providedNonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1008, + "src": "1830:13:6", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "1814:29:6", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 1030, + "nodeType": "IfStatement", + "src": "1810:101:6", + "trueBody": { + "id": 1029, + "nodeType": "Block", + "src": "1845:66:6", + "statements": [ + { + "errorCall": { + "arguments": [ + { + "id": 1024, + "name": "space", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1006, + "src": "1869:5:6", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 1025, + "name": "providedNonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1008, + "src": "1876:13:6", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 1026, + "name": "currentNonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1015, + "src": "1891:12:6", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 1023, + "name": "BadNonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 938, + "src": "1860:8:6", + "typeDescriptions": { + "typeIdentifier": "t_function_error_pure$_t_uint256_$_t_uint256_$_t_uint256_$returns$__$", + "typeString": "function (uint256,uint256,uint256) pure" + } + }, + "id": 1027, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1860:44:6", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1028, + "nodeType": "RevertStatement", + "src": "1853:51:6" + } + ] + } + }, + { + "id": 1048, + "nodeType": "UncheckedBlock", + "src": "1917:153:6", + "statements": [ + { + "assignments": [ + 1032 + ], + "declarations": [ + { + "constant": false, + "id": 1032, + "mutability": "mutable", + "name": "newNonce", + "nameLocation": "1943:8:6", + "nodeType": "VariableDeclaration", + "scope": 1048, + "src": "1935:16:6", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1031, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1935:7:6", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 1036, + "initialValue": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 1035, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 1033, + "name": "providedNonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1008, + "src": "1954:13:6", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": { + "hexValue": "31", + "id": 1034, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1970:1:6", + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "1954:17:6", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "1935:36:6" + }, + { + "expression": { + "arguments": [ + { + "id": 1038, + "name": "space", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1006, + "src": "1992:5:6", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 1039, + "name": "newNonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1032, + "src": "1999:8:6", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 1037, + "name": "_writeNonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 999, + "src": "1980:11:6", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_nonpayable$_t_uint256_$_t_uint256_$returns$__$", + "typeString": "function (uint256,uint256)" + } + }, + "id": 1040, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1980:28:6", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1041, + "nodeType": "ExpressionStatement", + "src": "1980:28:6" + }, + { + "eventCall": { + "arguments": [ + { + "id": 1043, + "name": "space", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1006, + "src": "2033:5:6", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 1044, + "name": "newNonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1032, + "src": "2040:8:6", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 1042, + "name": "NonceChange", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 930, + "src": "2021:11:6", + "typeDescriptions": { + "typeIdentifier": "t_function_event_nonpayable$_t_uint256_$_t_uint256_$returns$__$", + "typeString": "function (uint256,uint256)" + } + }, + "id": 1045, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2021:28:6", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1046, + "nodeType": "EmitStatement", + "src": "2016:33:6" + }, + { + "functionReturnParameters": 1004, + "id": 1047, + "nodeType": "Return", + "src": "2057:7:6" + } + ] + } + ] + }, + "documentation": { + "id": 1000, + "nodeType": "StructuredDocumentation", + "src": "1445:120:6", + "text": " @notice Verify if a nonce is valid\n @param _rawNonce Nonce to validate (may contain an encoded space)" + }, + "id": 1050, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "_validateNonce", + "nameLocation": "1577:14:6", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 1003, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1002, + "mutability": "mutable", + "name": "_rawNonce", + "nameLocation": "1600:9:6", + "nodeType": "VariableDeclaration", + "scope": 1050, + "src": "1592:17:6", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1001, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1592:7:6", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "1591:19:6" + }, + "returnParameters": { + "id": 1004, + "nodeType": "ParameterList", + "parameters": [], + "src": "1628:0:6" + }, + "scope": 1051, + "src": "1568:506:6", + "stateMutability": "nonpayable", + "virtual": true, + "visibility": "internal" + } + ], + "scope": 1052, + "src": "145:1931:6", + "usedErrors": [ + 938 + ] + } + ], + "src": "39:2038:6" + }, + "id": 6 + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleOnlyDelegatecall.sol": { + "ast": { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleOnlyDelegatecall.sol", + "exportedSymbols": { + "ModuleOnlyDelegatecall": [ + 1085 + ] + }, + "id": 1086, + "license": "Apache-2.0", + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 1053, + "literals": [ + "solidity", + "0.8", + ".18" + ], + "nodeType": "PragmaDirective", + "src": "39:23:7" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "ModuleOnlyDelegatecall", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 1085, + "linearizedBaseContracts": [ + 1085 + ], + "name": "ModuleOnlyDelegatecall", + "nameLocation": "74:22:7", + "nodeType": "ContractDefinition", + "nodes": [ + { + "constant": false, + "id": 1055, + "mutability": "immutable", + "name": "self", + "nameLocation": "127:4:7", + "nodeType": "VariableDeclaration", + "scope": 1085, + "src": "101:30:7", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 1054, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "101:7:7", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "private" + }, + { + "errorSelector": "0a57d61d", + "id": 1057, + "name": "OnlyDelegatecall", + "nameLocation": "142:16:7", + "nodeType": "ErrorDefinition", + "parameters": { + "id": 1056, + "nodeType": "ParameterList", + "parameters": [], + "src": "158:2:7" + }, + "src": "136:25:7" + }, + { + "body": { + "id": 1067, + "nodeType": "Block", + "src": "179:31:7", + "statements": [ + { + "expression": { + "id": 1065, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 1060, + "name": "self", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1055, + "src": "185:4:7", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 1063, + "name": "this", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967268, + "src": "200:4:7", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ModuleOnlyDelegatecall_$1085", + "typeString": "contract ModuleOnlyDelegatecall" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_contract$_ModuleOnlyDelegatecall_$1085", + "typeString": "contract ModuleOnlyDelegatecall" + } + ], + "id": 1062, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "192:7:7", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": { + "id": 1061, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "192:7:7", + "typeDescriptions": {} + } + }, + "id": 1064, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "192:13:7", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "185:20:7", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 1066, + "nodeType": "ExpressionStatement", + "src": "185:20:7" + } + ] + }, + "id": 1068, + "implemented": true, + "kind": "constructor", + "modifiers": [], + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 1058, + "nodeType": "ParameterList", + "parameters": [], + "src": "176:2:7" + }, + "returnParameters": { + "id": 1059, + "nodeType": "ParameterList", + "parameters": [], + "src": "179:0:7" + }, + "scope": 1085, + "src": "165:45:7", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "public" + }, + { + "body": { + "id": 1083, + "nodeType": "Block", + "src": "334:84:7", + "statements": [ + { + "condition": { + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 1076, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "arguments": [ + { + "id": 1073, + "name": "this", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967268, + "src": "352:4:7", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ModuleOnlyDelegatecall_$1085", + "typeString": "contract ModuleOnlyDelegatecall" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_contract$_ModuleOnlyDelegatecall_$1085", + "typeString": "contract ModuleOnlyDelegatecall" + } + ], + "id": 1072, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "344:7:7", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": { + "id": 1071, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "344:7:7", + "typeDescriptions": {} + } + }, + "id": 1074, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "344:13:7", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "id": 1075, + "name": "self", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1055, + "src": "361:4:7", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "344:21:7", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 1081, + "nodeType": "IfStatement", + "src": "340:67:7", + "trueBody": { + "id": 1080, + "nodeType": "Block", + "src": "367:40:7", + "statements": [ + { + "errorCall": { + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 1077, + "name": "OnlyDelegatecall", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1057, + "src": "382:16:7", + "typeDescriptions": { + "typeIdentifier": "t_function_error_pure$__$returns$__$", + "typeString": "function () pure" + } + }, + "id": 1078, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "382:18:7", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1079, + "nodeType": "RevertStatement", + "src": "375:25:7" + } + ] + } + }, + { + "id": 1082, + "nodeType": "PlaceholderStatement", + "src": "412:1:7" + } + ] + }, + "documentation": { + "id": 1069, + "nodeType": "StructuredDocumentation", + "src": "214:89:7", + "text": " @notice Modifier that only allows functions to be called via delegatecall." + }, + "id": 1084, + "name": "onlyDelegatecall", + "nameLocation": "315:16:7", + "nodeType": "ModifierDefinition", + "parameters": { + "id": 1070, + "nodeType": "ParameterList", + "parameters": [], + "src": "331:2:7" + }, + "src": "306:112:7", + "virtual": false, + "visibility": "internal" + } + ], + "scope": 1086, + "src": "65:355:7", + "usedErrors": [ + 1057 + ] + } + ], + "src": "39:382:7" + }, + "id": 7 + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol": { + "ast": { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol", + "exportedSymbols": { + "ModuleSelfAuth": [ + 1116 + ] + }, + "id": 1117, + "license": "Apache-2.0", + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 1087, + "literals": [ + "solidity", + "0.8", + ".18" + ], + "nodeType": "PragmaDirective", + "src": "39:23:8" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "ModuleSelfAuth", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 1116, + "linearizedBaseContracts": [ + 1116 + ], + "name": "ModuleSelfAuth", + "nameLocation": "74:14:8", + "nodeType": "ContractDefinition", + "nodes": [ + { + "errorSelector": "e1258894", + "id": 1093, + "name": "OnlySelfAuth", + "nameLocation": "99:12:8", + "nodeType": "ErrorDefinition", + "parameters": { + "id": 1092, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1089, + "mutability": "mutable", + "name": "_sender", + "nameLocation": "120:7:8", + "nodeType": "VariableDeclaration", + "scope": 1093, + "src": "112:15:8", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 1088, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "112:7:8", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1091, + "mutability": "mutable", + "name": "_self", + "nameLocation": "137:5:8", + "nodeType": "VariableDeclaration", + "scope": 1093, + "src": "129:13:8", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 1090, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "129:7:8", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "111:32:8" + }, + "src": "93:51:8" + }, + { + "body": { + "id": 1114, + "nodeType": "Block", + "src": "168:111:8", + "statements": [ + { + "condition": { + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 1101, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "expression": { + "id": 1095, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967281, + "src": "178:3:8", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 1096, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "182:6:8", + "memberName": "sender", + "nodeType": "MemberAccess", + "src": "178:10:8", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "arguments": [ + { + "id": 1099, + "name": "this", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967268, + "src": "200:4:8", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ModuleSelfAuth_$1116", + "typeString": "contract ModuleSelfAuth" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_contract$_ModuleSelfAuth_$1116", + "typeString": "contract ModuleSelfAuth" + } + ], + "id": 1098, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "192:7:8", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": { + "id": 1097, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "192:7:8", + "typeDescriptions": {} + } + }, + "id": 1100, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "192:13:8", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "178:27:8", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 1112, + "nodeType": "IfStatement", + "src": "174:94:8", + "trueBody": { + "id": 1111, + "nodeType": "Block", + "src": "207:61:8", + "statements": [ + { + "errorCall": { + "arguments": [ + { + "expression": { + "id": 1103, + "name": "msg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967281, + "src": "235:3:8", + "typeDescriptions": { + "typeIdentifier": "t_magic_message", + "typeString": "msg" + } + }, + "id": 1104, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "239:6:8", + "memberName": "sender", + "nodeType": "MemberAccess", + "src": "235:10:8", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "arguments": [ + { + "id": 1107, + "name": "this", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967268, + "src": "255:4:8", + "typeDescriptions": { + "typeIdentifier": "t_contract$_ModuleSelfAuth_$1116", + "typeString": "contract ModuleSelfAuth" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_contract$_ModuleSelfAuth_$1116", + "typeString": "contract ModuleSelfAuth" + } + ], + "id": 1106, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "247:7:8", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": { + "id": 1105, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "247:7:8", + "typeDescriptions": {} + } + }, + "id": 1108, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "247:13:8", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 1102, + "name": "OnlySelfAuth", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1093, + "src": "222:12:8", + "typeDescriptions": { + "typeIdentifier": "t_function_error_pure$_t_address_$_t_address_$returns$__$", + "typeString": "function (address,address) pure" + } + }, + "id": 1109, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "222:39:8", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1110, + "nodeType": "RevertStatement", + "src": "215:46:8" + } + ] + } + }, + { + "id": 1113, + "nodeType": "PlaceholderStatement", + "src": "273:1:8" + } + ] + }, + "id": 1115, + "name": "onlySelf", + "nameLocation": "157:8:8", + "nodeType": "ModifierDefinition", + "parameters": { + "id": 1094, + "nodeType": "ParameterList", + "parameters": [], + "src": "165:2:8" + }, + "src": "148:131:8", + "virtual": false, + "visibility": "internal" + } + ], + "scope": 1117, + "src": "65:216:8", + "usedErrors": [ + 1093 + ] + } + ], + "src": "39:243:8" + }, + "id": 8 + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol": { + "ast": { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol", + "exportedSymbols": { + "ModuleStorage": [ + 1179 + ] + }, + "id": 1180, + "license": "Apache-2.0", + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 1118, + "literals": [ + "solidity", + "0.8", + ".18" + ], + "nodeType": "PragmaDirective", + "src": "39:23:9" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "ModuleStorage", + "contractDependencies": [], + "contractKind": "library", + "fullyImplemented": true, + "id": 1179, + "linearizedBaseContracts": [ + 1179 + ], + "name": "ModuleStorage", + "nameLocation": "73:13:9", + "nodeType": "ContractDefinition", + "nodes": [ + { + "body": { + "id": 1126, + "nodeType": "Block", + "src": "150:41:9", + "statements": [ + { + "AST": { + "nodeType": "YulBlock", + "src": "165:22:9", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "_key", + "nodeType": "YulIdentifier", + "src": "174:4:9" + }, + { + "name": "_val", + "nodeType": "YulIdentifier", + "src": "180:4:9" + } + ], + "functionName": { + "name": "sstore", + "nodeType": "YulIdentifier", + "src": "167:6:9" + }, + "nodeType": "YulFunctionCall", + "src": "167:18:9" + }, + "nodeType": "YulExpressionStatement", + "src": "167:18:9" + } + ] + }, + "evmVersion": "paris", + "externalReferences": [ + { + "declaration": 1120, + "isOffset": false, + "isSlot": false, + "src": "174:4:9", + "valueSize": 1 + }, + { + "declaration": 1122, + "isOffset": false, + "isSlot": false, + "src": "180:4:9", + "valueSize": 1 + } + ], + "id": 1125, + "nodeType": "InlineAssembly", + "src": "156:31:9" + } + ] + }, + "id": 1127, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "writeBytes32", + "nameLocation": "100:12:9", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 1123, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1120, + "mutability": "mutable", + "name": "_key", + "nameLocation": "121:4:9", + "nodeType": "VariableDeclaration", + "scope": 1127, + "src": "113:12:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1119, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "113:7:9", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1122, + "mutability": "mutable", + "name": "_val", + "nameLocation": "135:4:9", + "nodeType": "VariableDeclaration", + "scope": 1127, + "src": "127:12:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1121, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "127:7:9", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "112:28:9" + }, + "returnParameters": { + "id": 1124, + "nodeType": "ParameterList", + "parameters": [], + "src": "150:0:9" + }, + "scope": 1179, + "src": "91:100:9", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + }, + { + "body": { + "id": 1135, + "nodeType": "Block", + "src": "266:41:9", + "statements": [ + { + "AST": { + "nodeType": "YulBlock", + "src": "281:22:9", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "283:18:9", + "value": { + "arguments": [ + { + "name": "_key", + "nodeType": "YulIdentifier", + "src": "296:4:9" + } + ], + "functionName": { + "name": "sload", + "nodeType": "YulIdentifier", + "src": "290:5:9" + }, + "nodeType": "YulFunctionCall", + "src": "290:11:9" + }, + "variableNames": [ + { + "name": "val", + "nodeType": "YulIdentifier", + "src": "283:3:9" + } + ] + } + ] + }, + "evmVersion": "paris", + "externalReferences": [ + { + "declaration": 1129, + "isOffset": false, + "isSlot": false, + "src": "296:4:9", + "valueSize": 1 + }, + { + "declaration": 1132, + "isOffset": false, + "isSlot": false, + "src": "283:3:9", + "valueSize": 1 + } + ], + "id": 1134, + "nodeType": "InlineAssembly", + "src": "272:31:9" + } + ] + }, + "id": 1136, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "readBytes32", + "nameLocation": "204:11:9", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 1130, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1129, + "mutability": "mutable", + "name": "_key", + "nameLocation": "224:4:9", + "nodeType": "VariableDeclaration", + "scope": 1136, + "src": "216:12:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1128, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "216:7:9", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "215:14:9" + }, + "returnParameters": { + "id": 1133, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1132, + "mutability": "mutable", + "name": "val", + "nameLocation": "261:3:9", + "nodeType": "VariableDeclaration", + "scope": 1136, + "src": "253:11:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1131, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "253:7:9", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "252:13:9" + }, + "scope": 1179, + "src": "195:112:9", + "stateMutability": "view", + "virtual": false, + "visibility": "internal" + }, + { + "body": { + "id": 1156, + "nodeType": "Block", + "src": "390:96:9", + "statements": [ + { + "assignments": [ + 1146 + ], + "declarations": [ + { + "constant": false, + "id": 1146, + "mutability": "mutable", + "name": "key", + "nameLocation": "404:3:9", + "nodeType": "VariableDeclaration", + "scope": 1156, + "src": "396:11:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1145, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "396:7:9", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "id": 1154, + "initialValue": { + "arguments": [ + { + "arguments": [ + { + "id": 1150, + "name": "_key", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1138, + "src": "431:4:9", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 1151, + "name": "_subKey", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1140, + "src": "437:7:9", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "expression": { + "id": 1148, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967295, + "src": "420:3:9", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 1149, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "424:6:9", + "memberName": "encode", + "nodeType": "MemberAccess", + "src": "420:10:9", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencode_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 1152, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "420:25:9", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 1147, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967288, + "src": "410:9:9", + "typeDescriptions": { + "typeIdentifier": "t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$", + "typeString": "function (bytes memory) pure returns (bytes32)" + } + }, + "id": 1153, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "410:36:9", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "396:50:9" + }, + { + "AST": { + "nodeType": "YulBlock", + "src": "461:21:9", + "statements": [ + { + "expression": { + "arguments": [ + { + "name": "key", + "nodeType": "YulIdentifier", + "src": "470:3:9" + }, + { + "name": "_val", + "nodeType": "YulIdentifier", + "src": "475:4:9" + } + ], + "functionName": { + "name": "sstore", + "nodeType": "YulIdentifier", + "src": "463:6:9" + }, + "nodeType": "YulFunctionCall", + "src": "463:17:9" + }, + "nodeType": "YulExpressionStatement", + "src": "463:17:9" + } + ] + }, + "evmVersion": "paris", + "externalReferences": [ + { + "declaration": 1142, + "isOffset": false, + "isSlot": false, + "src": "475:4:9", + "valueSize": 1 + }, + { + "declaration": 1146, + "isOffset": false, + "isSlot": false, + "src": "470:3:9", + "valueSize": 1 + } + ], + "id": 1155, + "nodeType": "InlineAssembly", + "src": "452:30:9" + } + ] + }, + "id": 1157, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "writeBytes32Map", + "nameLocation": "320:15:9", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 1143, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1138, + "mutability": "mutable", + "name": "_key", + "nameLocation": "344:4:9", + "nodeType": "VariableDeclaration", + "scope": 1157, + "src": "336:12:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1137, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "336:7:9", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1140, + "mutability": "mutable", + "name": "_subKey", + "nameLocation": "358:7:9", + "nodeType": "VariableDeclaration", + "scope": 1157, + "src": "350:15:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1139, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "350:7:9", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1142, + "mutability": "mutable", + "name": "_val", + "nameLocation": "375:4:9", + "nodeType": "VariableDeclaration", + "scope": 1157, + "src": "367:12:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1141, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "367:7:9", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "335:45:9" + }, + "returnParameters": { + "id": 1144, + "nodeType": "ParameterList", + "parameters": [], + "src": "390:0:9" + }, + "scope": 1179, + "src": "311:175:9", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + }, + { + "body": { + "id": 1177, + "nodeType": "Block", + "src": "581:96:9", + "statements": [ + { + "assignments": [ + 1167 + ], + "declarations": [ + { + "constant": false, + "id": 1167, + "mutability": "mutable", + "name": "key", + "nameLocation": "595:3:9", + "nodeType": "VariableDeclaration", + "scope": 1177, + "src": "587:11:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1166, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "587:7:9", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "id": 1175, + "initialValue": { + "arguments": [ + { + "arguments": [ + { + "id": 1171, + "name": "_key", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1159, + "src": "622:4:9", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 1172, + "name": "_subKey", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1161, + "src": "628:7:9", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "expression": { + "id": 1169, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967295, + "src": "611:3:9", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 1170, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "615:6:9", + "memberName": "encode", + "nodeType": "MemberAccess", + "src": "611:10:9", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencode_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 1173, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "611:25:9", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 1168, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967288, + "src": "601:9:9", + "typeDescriptions": { + "typeIdentifier": "t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$", + "typeString": "function (bytes memory) pure returns (bytes32)" + } + }, + "id": 1174, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "601:36:9", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "587:50:9" + }, + { + "AST": { + "nodeType": "YulBlock", + "src": "652:21:9", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "654:17:9", + "value": { + "arguments": [ + { + "name": "key", + "nodeType": "YulIdentifier", + "src": "667:3:9" + } + ], + "functionName": { + "name": "sload", + "nodeType": "YulIdentifier", + "src": "661:5:9" + }, + "nodeType": "YulFunctionCall", + "src": "661:10:9" + }, + "variableNames": [ + { + "name": "val", + "nodeType": "YulIdentifier", + "src": "654:3:9" + } + ] + } + ] + }, + "evmVersion": "paris", + "externalReferences": [ + { + "declaration": 1167, + "isOffset": false, + "isSlot": false, + "src": "667:3:9", + "valueSize": 1 + }, + { + "declaration": 1164, + "isOffset": false, + "isSlot": false, + "src": "654:3:9", + "valueSize": 1 + } + ], + "id": 1176, + "nodeType": "InlineAssembly", + "src": "643:30:9" + } + ] + }, + "id": 1178, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "readBytes32Map", + "nameLocation": "499:14:9", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 1162, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1159, + "mutability": "mutable", + "name": "_key", + "nameLocation": "522:4:9", + "nodeType": "VariableDeclaration", + "scope": 1178, + "src": "514:12:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1158, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "514:7:9", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1161, + "mutability": "mutable", + "name": "_subKey", + "nameLocation": "536:7:9", + "nodeType": "VariableDeclaration", + "scope": 1178, + "src": "528:15:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1160, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "528:7:9", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "513:31:9" + }, + "returnParameters": { + "id": 1165, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1164, + "mutability": "mutable", + "name": "val", + "nameLocation": "576:3:9", + "nodeType": "VariableDeclaration", + "scope": 1178, + "src": "568:11:9", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1163, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "568:7:9", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "567:13:9" + }, + "scope": 1179, + "src": "490:187:9", + "stateMutability": "view", + "virtual": false, + "visibility": "internal" + } + ], + "scope": 1180, + "src": "65:614:9", + "usedErrors": [] + } + ], + "src": "39:641:9" + }, + "id": 9 + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleAuth.sol": { + "ast": { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleAuth.sol", + "exportedSymbols": { + "IModuleAuth": [ + 1249 + ] + }, + "id": 1250, + "license": "Apache-2.0", + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 1181, + "literals": [ + "solidity", + "0.8", + ".18" + ], + "nodeType": "PragmaDirective", + "src": "39:23:10" + }, + { + "abstract": true, + "baseContracts": [], + "canonicalName": "IModuleAuth", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": false, + "id": 1249, + "linearizedBaseContracts": [ + 1249 + ], + "name": "IModuleAuth", + "nameLocation": "83:11:10", + "nodeType": "ContractDefinition", + "nodes": [ + { + "constant": true, + "id": 1187, + "mutability": "constant", + "name": "IMAGE_HASH_KEY", + "nameLocation": "231:14:10", + "nodeType": "VariableDeclaration", + "scope": 1249, + "src": "205:118:10", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1182, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "205:7:10", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": { + "arguments": [ + { + "hexValue": "307865613731353766613235653361613137643061653264353238306661346532346434323163363138343261613835653435313934653131343561613732626638", + "id": 1185, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "256:66:10", + "typeDescriptions": { + "typeIdentifier": "t_rational_106041467482713340379632507891644215435067329692436463218523020519418825747448_by_1", + "typeString": "int_const 1060...(70 digits omitted)...7448" + }, + "value": "0xea7157fa25e3aa17d0ae2d5280fa4e24d421c61842aa85e45194e1145aa72bf8" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_106041467482713340379632507891644215435067329692436463218523020519418825747448_by_1", + "typeString": "int_const 1060...(70 digits omitted)...7448" + } + ], + "id": 1184, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "248:7:10", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes32_$", + "typeString": "type(bytes32)" + }, + "typeName": { + "id": 1183, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "248:7:10", + "typeDescriptions": {} + } + }, + "id": 1186, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "248:75:10", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "anonymous": false, + "eventSelector": "307ed6bd941ee9fc80f369c94af5fa11e25bab5102a6140191756c5474a30bfa", + "id": 1191, + "name": "ImageHashUpdated", + "nameLocation": "334:16:10", + "nodeType": "EventDefinition", + "parameters": { + "id": 1190, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1189, + "indexed": false, + "mutability": "mutable", + "name": "newImageHash", + "nameLocation": "359:12:10", + "nodeType": "VariableDeclaration", + "scope": 1191, + "src": "351:20:10", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1188, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "351:7:10", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "350:22:10" + }, + "src": "328:45:10" + }, + { + "errorSelector": "4294d127", + "id": 1193, + "name": "ImageHashIsZero", + "nameLocation": "395:15:10", + "nodeType": "ErrorDefinition", + "parameters": { + "id": 1192, + "nodeType": "ParameterList", + "parameters": [], + "src": "410:2:10" + }, + "src": "389:24:10" + }, + { + "errorSelector": "6085cd82", + "id": 1197, + "name": "InvalidSignatureType", + "nameLocation": "422:20:10", + "nodeType": "ErrorDefinition", + "parameters": { + "id": 1196, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1195, + "mutability": "mutable", + "name": "_type", + "nameLocation": "450:5:10", + "nodeType": "VariableDeclaration", + "scope": 1197, + "src": "443:12:10", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes1", + "typeString": "bytes1" + }, + "typeName": { + "id": 1194, + "name": "bytes1", + "nodeType": "ElementaryTypeName", + "src": "443:6:10", + "typeDescriptions": { + "typeIdentifier": "t_bytes1", + "typeString": "bytes1" + } + }, + "visibility": "internal" + } + ], + "src": "442:14:10" + }, + "src": "416:41:10" + }, + { + "id": 1208, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "_signatureValidation", + "nameLocation": "470:20:10", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 1202, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1199, + "mutability": "mutable", + "name": "_digest", + "nameLocation": "504:7:10", + "nodeType": "VariableDeclaration", + "scope": 1208, + "src": "496:15:10", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1198, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "496:7:10", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1201, + "mutability": "mutable", + "name": "_signature", + "nameLocation": "532:10:10", + "nodeType": "VariableDeclaration", + "scope": 1208, + "src": "517:25:10", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 1200, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "517:5:10", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "490:56:10" + }, + "returnParameters": { + "id": 1207, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1204, + "mutability": "mutable", + "name": "isValid", + "nameLocation": "588:7:10", + "nodeType": "VariableDeclaration", + "scope": 1208, + "src": "583:12:10", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 1203, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "583:4:10", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1206, + "mutability": "mutable", + "name": "subdigest", + "nameLocation": "609:9:10", + "nodeType": "VariableDeclaration", + "scope": 1208, + "src": "601:17:10", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1205, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "601:7:10", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "577:45:10" + }, + "scope": 1249, + "src": "461:162:10", + "stateMutability": "view", + "virtual": true, + "visibility": "internal" + }, + { + "functionSelector": "853c5068", + "id": 1225, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "signatureRecovery", + "nameLocation": "636:17:10", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 1213, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1210, + "mutability": "mutable", + "name": "_digest", + "nameLocation": "667:7:10", + "nodeType": "VariableDeclaration", + "scope": 1225, + "src": "659:15:10", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1209, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "659:7:10", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1212, + "mutability": "mutable", + "name": "_signature", + "nameLocation": "695:10:10", + "nodeType": "VariableDeclaration", + "scope": 1225, + "src": "680:25:10", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 1211, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "680:5:10", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "653:56:10" + }, + "returnParameters": { + "id": 1224, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1215, + "mutability": "mutable", + "name": "threshold", + "nameLocation": "752:9:10", + "nodeType": "VariableDeclaration", + "scope": 1225, + "src": "744:17:10", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1214, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "744:7:10", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1217, + "mutability": "mutable", + "name": "weight", + "nameLocation": "775:6:10", + "nodeType": "VariableDeclaration", + "scope": 1225, + "src": "767:14:10", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1216, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "767:7:10", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1219, + "mutability": "mutable", + "name": "imageHash", + "nameLocation": "795:9:10", + "nodeType": "VariableDeclaration", + "scope": 1225, + "src": "787:17:10", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1218, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "787:7:10", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1221, + "mutability": "mutable", + "name": "subdigest", + "nameLocation": "818:9:10", + "nodeType": "VariableDeclaration", + "scope": 1225, + "src": "810:17:10", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1220, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "810:7:10", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1223, + "mutability": "mutable", + "name": "checkpoint", + "nameLocation": "841:10:10", + "nodeType": "VariableDeclaration", + "scope": 1225, + "src": "833:18:10", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1222, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "833:7:10", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "738:117:10" + }, + "scope": 1249, + "src": "627:229:10", + "stateMutability": "view", + "virtual": true, + "visibility": "public" + }, + { + "body": { + "id": 1235, + "nodeType": "Block", + "src": "1034:23:10", + "statements": [ + { + "expression": { + "hexValue": "66616c7365", + "id": 1233, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1047:5:10", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + }, + "functionReturnParameters": 1232, + "id": 1234, + "nodeType": "Return", + "src": "1040:12:10" + } + ] + }, + "documentation": { + "id": 1226, + "nodeType": "StructuredDocumentation", + "src": "860:102:10", + "text": " @notice Validates the signature image\n @return true if the signature image is valid" + }, + "id": 1236, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "_isValidImage", + "nameLocation": "974:13:10", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 1229, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1228, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 1236, + "src": "988:7:10", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1227, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "988:7:10", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "987:9:10" + }, + "returnParameters": { + "id": 1232, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1231, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 1236, + "src": "1028:4:10", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 1230, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "1028:4:10", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "src": "1027:6:10" + }, + "scope": 1249, + "src": "965:92:10", + "stateMutability": "view", + "virtual": true, + "visibility": "internal" + }, + { + "documentation": { + "id": 1237, + "nodeType": "StructuredDocumentation", + "src": "1061:134:10", + "text": " @notice Updates the signers configuration of the wallet\n @param _imageHash New required image hash of the signature" + }, + "functionSelector": "29561426", + "id": 1242, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "updateImageHash", + "nameLocation": "1207:15:10", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 1240, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1239, + "mutability": "mutable", + "name": "_imageHash", + "nameLocation": "1231:10:10", + "nodeType": "VariableDeclaration", + "scope": 1242, + "src": "1223:18:10", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1238, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1223:7:10", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "1222:20:10" + }, + "returnParameters": { + "id": 1241, + "nodeType": "ParameterList", + "parameters": [], + "src": "1259:0:10" + }, + "scope": 1249, + "src": "1198:62:10", + "stateMutability": "nonpayable", + "virtual": true, + "visibility": "external" + }, + { + "documentation": { + "id": 1243, + "nodeType": "StructuredDocumentation", + "src": "1264:134:10", + "text": " @notice Updates the signers configuration of the wallet\n @param _imageHash New required image hash of the signature" + }, + "id": 1248, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "_updateImageHash", + "nameLocation": "1410:16:10", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 1246, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1245, + "mutability": "mutable", + "name": "_imageHash", + "nameLocation": "1435:10:10", + "nodeType": "VariableDeclaration", + "scope": 1248, + "src": "1427:18:10", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1244, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1427:7:10", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "1426:20:10" + }, + "returnParameters": { + "id": 1247, + "nodeType": "ParameterList", + "parameters": [], + "src": "1463:0:10" + }, + "scope": 1249, + "src": "1401:63:10", + "stateMutability": "nonpayable", + "virtual": true, + "visibility": "internal" + } + ], + "scope": 1250, + "src": "65:1401:10", + "usedErrors": [ + 1193, + 1197 + ] + } + ], + "src": "39:1428:10" + }, + "id": 10 + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCalls.sol": { + "ast": { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCalls.sol", + "exportedSymbols": { + "IModuleCalls": [ + 1313 + ] + }, + "id": 1314, + "license": "Apache-2.0", + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 1251, + "literals": [ + "solidity", + "0.8", + ".18" + ], + "nodeType": "PragmaDirective", + "src": "39:23:11" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "IModuleCalls", + "contractDependencies": [], + "contractKind": "interface", + "fullyImplemented": false, + "id": 1313, + "linearizedBaseContracts": [ + 1313 + ], + "name": "IModuleCalls", + "nameLocation": "75:12:11", + "nodeType": "ContractDefinition", + "nodes": [ + { + "anonymous": false, + "eventSelector": "ab46c69f7f32e1bf09b0725853da82a211e5402a0600296ab499a2fb5ea3b419", + "id": 1259, + "name": "TxFailed", + "nameLocation": "110:8:11", + "nodeType": "EventDefinition", + "parameters": { + "id": 1258, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1253, + "indexed": true, + "mutability": "mutable", + "name": "_tx", + "nameLocation": "135:3:11", + "nodeType": "VariableDeclaration", + "scope": 1259, + "src": "119:19:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1252, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "119:7:11", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1255, + "indexed": false, + "mutability": "mutable", + "name": "_index", + "nameLocation": "148:6:11", + "nodeType": "VariableDeclaration", + "scope": 1259, + "src": "140:14:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1254, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "140:7:11", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1257, + "indexed": false, + "mutability": "mutable", + "name": "_reason", + "nameLocation": "162:7:11", + "nodeType": "VariableDeclaration", + "scope": 1259, + "src": "156:13:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 1256, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "156:5:11", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "118:52:11" + }, + "src": "104:67:11" + }, + { + "anonymous": false, + "eventSelector": "5c4eeb02dabf8976016ab414d617f9a162936dcace3cdef8c69ef6e262ad5ae7", + "id": 1265, + "name": "TxExecuted", + "nameLocation": "180:10:11", + "nodeType": "EventDefinition", + "parameters": { + "id": 1264, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1261, + "indexed": true, + "mutability": "mutable", + "name": "_tx", + "nameLocation": "207:3:11", + "nodeType": "VariableDeclaration", + "scope": 1265, + "src": "191:19:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1260, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "191:7:11", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1263, + "indexed": false, + "mutability": "mutable", + "name": "_index", + "nameLocation": "220:6:11", + "nodeType": "VariableDeclaration", + "scope": 1265, + "src": "212:14:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1262, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "212:7:11", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "190:37:11" + }, + "src": "174:54:11" + }, + { + "errorSelector": "2bb3e3ba", + "id": 1273, + "name": "NotEnoughGas", + "nameLocation": "250:12:11", + "nodeType": "ErrorDefinition", + "parameters": { + "id": 1272, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1267, + "mutability": "mutable", + "name": "_index", + "nameLocation": "271:6:11", + "nodeType": "VariableDeclaration", + "scope": 1273, + "src": "263:14:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1266, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "263:7:11", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1269, + "mutability": "mutable", + "name": "_requested", + "nameLocation": "287:10:11", + "nodeType": "VariableDeclaration", + "scope": 1273, + "src": "279:18:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1268, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "279:7:11", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1271, + "mutability": "mutable", + "name": "_available", + "nameLocation": "307:10:11", + "nodeType": "VariableDeclaration", + "scope": 1273, + "src": "299:18:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1270, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "299:7:11", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "262:56:11" + }, + "src": "244:75:11" + }, + { + "errorSelector": "8f4a234f", + "id": 1279, + "name": "InvalidSignature", + "nameLocation": "328:16:11", + "nodeType": "ErrorDefinition", + "parameters": { + "id": 1278, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1275, + "mutability": "mutable", + "name": "_hash", + "nameLocation": "353:5:11", + "nodeType": "VariableDeclaration", + "scope": 1279, + "src": "345:13:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1274, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "345:7:11", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1277, + "mutability": "mutable", + "name": "_signature", + "nameLocation": "366:10:11", + "nodeType": "VariableDeclaration", + "scope": 1279, + "src": "360:16:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 1276, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "360:5:11", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "344:33:11" + }, + "src": "322:56:11" + }, + { + "canonicalName": "IModuleCalls.Transaction", + "id": 1292, + "members": [ + { + "constant": false, + "id": 1281, + "mutability": "mutable", + "name": "delegateCall", + "nameLocation": "439:12:11", + "nodeType": "VariableDeclaration", + "scope": 1292, + "src": "434:17:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 1280, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "434:4:11", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1283, + "mutability": "mutable", + "name": "revertOnError", + "nameLocation": "489:13:11", + "nodeType": "VariableDeclaration", + "scope": 1292, + "src": "484:18:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 1282, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "484:4:11", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1285, + "mutability": "mutable", + "name": "gasLimit", + "nameLocation": "559:8:11", + "nodeType": "VariableDeclaration", + "scope": 1292, + "src": "551:16:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1284, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "551:7:11", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1287, + "mutability": "mutable", + "name": "target", + "nameLocation": "615:6:11", + "nodeType": "VariableDeclaration", + "scope": 1292, + "src": "607:14:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 1286, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "607:7:11", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1289, + "mutability": "mutable", + "name": "value", + "nameLocation": "675:5:11", + "nodeType": "VariableDeclaration", + "scope": 1292, + "src": "667:13:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1288, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "667:7:11", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1291, + "mutability": "mutable", + "name": "data", + "nameLocation": "737:4:11", + "nodeType": "VariableDeclaration", + "scope": 1292, + "src": "731:10:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 1290, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "731:5:11", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "name": "Transaction", + "nameLocation": "416:11:11", + "nodeType": "StructDefinition", + "scope": 1313, + "src": "409:366:11", + "visibility": "public" + }, + { + "documentation": { + "id": 1293, + "nodeType": "StructuredDocumentation", + "src": "779:223:11", + "text": " @notice Allow wallet owner to execute an action\n @param _txs Transactions to process\n @param _nonce Signature nonce (may contain an encoded space)\n @param _signature Encoded signature" + }, + "functionSelector": "7a9a1628", + "id": 1304, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "execute", + "nameLocation": "1014:7:11", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 1302, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1297, + "mutability": "mutable", + "name": "_txs", + "nameLocation": "1050:4:11", + "nodeType": "VariableDeclaration", + "scope": 1304, + "src": "1027:27:11", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction[]" + }, + "typeName": { + "baseType": { + "id": 1295, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 1294, + "name": "Transaction", + "nameLocations": [ + "1027:11:11" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1292, + "src": "1027:11:11" + }, + "referencedDeclaration": 1292, + "src": "1027:11:11", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Transaction_$1292_storage_ptr", + "typeString": "struct IModuleCalls.Transaction" + } + }, + "id": 1296, + "nodeType": "ArrayTypeName", + "src": "1027:13:11", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Transaction_$1292_storage_$dyn_storage_ptr", + "typeString": "struct IModuleCalls.Transaction[]" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1299, + "mutability": "mutable", + "name": "_nonce", + "nameLocation": "1068:6:11", + "nodeType": "VariableDeclaration", + "scope": 1304, + "src": "1060:14:11", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1298, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1060:7:11", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1301, + "mutability": "mutable", + "name": "_signature", + "nameLocation": "1095:10:11", + "nodeType": "VariableDeclaration", + "scope": 1304, + "src": "1080:25:11", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 1300, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "1080:5:11", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "1021:88:11" + }, + "returnParameters": { + "id": 1303, + "nodeType": "ParameterList", + "parameters": [], + "src": "1118:0:11" + }, + "scope": 1313, + "src": "1005:114:11", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "documentation": { + "id": 1305, + "nodeType": "StructuredDocumentation", + "src": "1123:133:11", + "text": " @notice Allow wallet to execute an action\n without signing the message\n @param _txs Transactions to execute" + }, + "functionSelector": "61c2926c", + "id": 1312, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "selfExecute", + "nameLocation": "1268:11:11", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 1310, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1309, + "mutability": "mutable", + "name": "_txs", + "nameLocation": "1308:4:11", + "nodeType": "VariableDeclaration", + "scope": 1312, + "src": "1285:27:11", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Transaction_$1292_calldata_ptr_$dyn_calldata_ptr", + "typeString": "struct IModuleCalls.Transaction[]" + }, + "typeName": { + "baseType": { + "id": 1307, + "nodeType": "UserDefinedTypeName", + "pathNode": { + "id": 1306, + "name": "Transaction", + "nameLocations": [ + "1285:11:11" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1292, + "src": "1285:11:11" + }, + "referencedDeclaration": 1292, + "src": "1285:11:11", + "typeDescriptions": { + "typeIdentifier": "t_struct$_Transaction_$1292_storage_ptr", + "typeString": "struct IModuleCalls.Transaction" + } + }, + "id": 1308, + "nodeType": "ArrayTypeName", + "src": "1285:13:11", + "typeDescriptions": { + "typeIdentifier": "t_array$_t_struct$_Transaction_$1292_storage_$dyn_storage_ptr", + "typeString": "struct IModuleCalls.Transaction[]" + } + }, + "visibility": "internal" + } + ], + "src": "1279:37:11" + }, + "returnParameters": { + "id": 1311, + "nodeType": "ParameterList", + "parameters": [], + "src": "1325:0:11" + }, + "scope": 1313, + "src": "1259:67:11", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + } + ], + "scope": 1314, + "src": "65:1263:11", + "usedErrors": [ + 1273, + 1279 + ] + } + ], + "src": "39:1290:11" + }, + "id": 11 + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCreator.sol": { + "ast": { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleCreator.sol", + "exportedSymbols": { + "IModuleCreator": [ + 1328 + ] + }, + "id": 1329, + "license": "Apache-2.0", + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 1315, + "literals": [ + "solidity", + "0.8", + ".18" + ], + "nodeType": "PragmaDirective", + "src": "39:23:12" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "IModuleCreator", + "contractDependencies": [], + "contractKind": "interface", + "fullyImplemented": false, + "id": 1328, + "linearizedBaseContracts": [ + 1328 + ], + "name": "IModuleCreator", + "nameLocation": "75:14:12", + "nodeType": "ContractDefinition", + "nodes": [ + { + "errorSelector": "0d257191", + "id": 1319, + "name": "CreateFailed", + "nameLocation": "100:12:12", + "nodeType": "ErrorDefinition", + "parameters": { + "id": 1318, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1317, + "mutability": "mutable", + "name": "_code", + "nameLocation": "119:5:12", + "nodeType": "VariableDeclaration", + "scope": 1319, + "src": "113:11:12", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 1316, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "113:5:12", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "112:13:12" + }, + "src": "94:32:12" + }, + { + "documentation": { + "id": 1320, + "nodeType": "StructuredDocumentation", + "src": "130:164:12", + "text": " @notice Creates a contract forwarding eth value\n @param _code Creation code of the contract\n @return addr The address of the created contract" + }, + "functionSelector": "90042baf", + "id": 1327, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "createContract", + "nameLocation": "306:14:12", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 1323, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1322, + "mutability": "mutable", + "name": "_code", + "nameLocation": "336:5:12", + "nodeType": "VariableDeclaration", + "scope": 1327, + "src": "321:20:12", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 1321, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "321:5:12", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "320:22:12" + }, + "returnParameters": { + "id": 1326, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1325, + "mutability": "mutable", + "name": "addr", + "nameLocation": "377:4:12", + "nodeType": "VariableDeclaration", + "scope": 1327, + "src": "369:12:12", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 1324, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "369:7:12", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "368:14:12" + }, + "scope": 1328, + "src": "297:86:12", + "stateMutability": "payable", + "virtual": false, + "visibility": "external" + } + ], + "scope": 1329, + "src": "65:320:12", + "usedErrors": [ + 1319 + ] + } + ], + "src": "39:347:12" + }, + "id": 12 + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol": { + "ast": { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol", + "exportedSymbols": { + "IERC1271Wallet": [ + 22 + ], + "LibBytes": [ + 2374 + ], + "LibBytesPointer": [ + 2476 + ], + "LibOptim": [ + 2530 + ], + "SequenceBaseSig": [ + 2021 + ], + "SignatureValidator": [ + 2798 + ] + }, + "id": 2022, + "license": "Apache-2.0", + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 1330, + "literals": [ + "solidity", + "0.8", + ".18" + ], + "nodeType": "PragmaDirective", + "src": "39:23:13" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol", + "file": "../../../../utils/SignatureValidator.sol", + "id": 1331, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 2022, + "sourceUnit": 2799, + "src": "64:50:13", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol", + "file": "../../../../utils/LibBytesPointer.sol", + "id": 1332, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 2022, + "sourceUnit": 2477, + "src": "115:47:13", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol", + "file": "../../../../utils/LibBytes.sol", + "id": 1333, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 2022, + "sourceUnit": 2375, + "src": "163:40:13", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol", + "file": "../../../../utils/LibOptim.sol", + "id": 1334, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 2022, + "sourceUnit": 2531, + "src": "204:40:13", + "symbolAliases": [], + "unitAlias": "" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "SequenceBaseSig", + "contractDependencies": [], + "contractKind": "library", + "documentation": { + "id": 1335, + "nodeType": "StructuredDocumentation", + "src": "247:171:13", + "text": " @title SequenceBaseSig Library\n @author Agustin Aguilar (aa@horizon.io)\n @notice A Solidity implementation for handling signatures in the Sequence protocol." + }, + "fullyImplemented": true, + "id": 2021, + "linearizedBaseContracts": [ + 2021 + ], + "name": "SequenceBaseSig", + "nameLocation": "427:15:13", + "nodeType": "ContractDefinition", + "nodes": [ + { + "global": false, + "id": 1338, + "libraryName": { + "id": 1336, + "name": "LibBytesPointer", + "nameLocations": [ + "453:15:13" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 2476, + "src": "453:15:13" + }, + "nodeType": "UsingForDirective", + "src": "447:32:13", + "typeName": { + "id": 1337, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "473:5:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + } + }, + { + "constant": true, + "id": 1341, + "mutability": "constant", + "name": "FLAG_SIGNATURE", + "nameLocation": "508:14:13", + "nodeType": "VariableDeclaration", + "scope": 2021, + "src": "483:43:13", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1339, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "483:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": { + "hexValue": "30", + "id": 1340, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "525:1:13", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "visibility": "private" + }, + { + "constant": true, + "id": 1344, + "mutability": "constant", + "name": "FLAG_ADDRESS", + "nameLocation": "555:12:13", + "nodeType": "VariableDeclaration", + "scope": 2021, + "src": "530:41:13", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1342, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "530:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": { + "hexValue": "31", + "id": 1343, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "570:1:13", + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "visibility": "private" + }, + { + "constant": true, + "id": 1347, + "mutability": "constant", + "name": "FLAG_DYNAMIC_SIGNATURE", + "nameLocation": "600:22:13", + "nodeType": "VariableDeclaration", + "scope": 2021, + "src": "575:51:13", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1345, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "575:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": { + "hexValue": "32", + "id": 1346, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "625:1:13", + "typeDescriptions": { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + }, + "visibility": "private" + }, + { + "constant": true, + "id": 1350, + "mutability": "constant", + "name": "FLAG_NODE", + "nameLocation": "655:9:13", + "nodeType": "VariableDeclaration", + "scope": 2021, + "src": "630:38:13", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1348, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "630:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": { + "hexValue": "33", + "id": 1349, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "667:1:13", + "typeDescriptions": { + "typeIdentifier": "t_rational_3_by_1", + "typeString": "int_const 3" + }, + "value": "3" + }, + "visibility": "private" + }, + { + "constant": true, + "id": 1353, + "mutability": "constant", + "name": "FLAG_BRANCH", + "nameLocation": "697:11:13", + "nodeType": "VariableDeclaration", + "scope": 2021, + "src": "672:40:13", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1351, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "672:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": { + "hexValue": "34", + "id": 1352, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "711:1:13", + "typeDescriptions": { + "typeIdentifier": "t_rational_4_by_1", + "typeString": "int_const 4" + }, + "value": "4" + }, + "visibility": "private" + }, + { + "constant": true, + "id": 1356, + "mutability": "constant", + "name": "FLAG_SUBDIGEST", + "nameLocation": "741:14:13", + "nodeType": "VariableDeclaration", + "scope": 2021, + "src": "716:43:13", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1354, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "716:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": { + "hexValue": "35", + "id": 1355, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "758:1:13", + "typeDescriptions": { + "typeIdentifier": "t_rational_5_by_1", + "typeString": "int_const 5" + }, + "value": "5" + }, + "visibility": "private" + }, + { + "constant": true, + "id": 1359, + "mutability": "constant", + "name": "FLAG_NESTED", + "nameLocation": "788:11:13", + "nodeType": "VariableDeclaration", + "scope": 2021, + "src": "763:40:13", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1357, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "763:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": { + "hexValue": "36", + "id": 1358, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "802:1:13", + "typeDescriptions": { + "typeIdentifier": "t_rational_6_by_1", + "typeString": "int_const 6" + }, + "value": "6" + }, + "visibility": "private" + }, + { + "errorSelector": "9a946232", + "id": 1367, + "name": "InvalidNestedSignature", + "nameLocation": "814:22:13", + "nodeType": "ErrorDefinition", + "parameters": { + "id": 1366, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1361, + "mutability": "mutable", + "name": "_hash", + "nameLocation": "845:5:13", + "nodeType": "VariableDeclaration", + "scope": 1367, + "src": "837:13:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1360, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "837:7:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1363, + "mutability": "mutable", + "name": "_addr", + "nameLocation": "860:5:13", + "nodeType": "VariableDeclaration", + "scope": 1367, + "src": "852:13:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 1362, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "852:7:13", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1365, + "mutability": "mutable", + "name": "_signature", + "nameLocation": "873:10:13", + "nodeType": "VariableDeclaration", + "scope": 1367, + "src": "867:16:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 1364, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "867:5:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "836:48:13" + }, + "src": "808:77:13" + }, + { + "errorSelector": "b2505f7c", + "id": 1371, + "name": "InvalidSignatureFlag", + "nameLocation": "894:20:13", + "nodeType": "ErrorDefinition", + "parameters": { + "id": 1370, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1369, + "mutability": "mutable", + "name": "_flag", + "nameLocation": "923:5:13", + "nodeType": "VariableDeclaration", + "scope": 1371, + "src": "915:13:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1368, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "915:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "914:15:13" + }, + "src": "888:42:13" + }, + { + "body": { + "id": 1393, + "nodeType": "Block", + "src": "1249:148:13", + "statements": [ + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "hexValue": "1901", + "id": 1382, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1305:10:13", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_301a50b291d33ce1e8e9064e3f6a6c51d902ec22892b50d58abf6357c6a45541", + "typeString": "literal_string hex\"1901\"" + }, + "value": "\u0019\u0001" + }, + { + "expression": { + "id": 1383, + "name": "block", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967292, + "src": "1325:5:13", + "typeDescriptions": { + "typeIdentifier": "t_magic_block", + "typeString": "block" + } + }, + "id": 1384, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "1331:7:13", + "memberName": "chainid", + "nodeType": "MemberAccess", + "src": "1325:13:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "arguments": [ + { + "id": 1387, + "name": "this", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967268, + "src": "1356:4:13", + "typeDescriptions": { + "typeIdentifier": "t_contract$_SequenceBaseSig_$2021", + "typeString": "library SequenceBaseSig" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_contract$_SequenceBaseSig_$2021", + "typeString": "library SequenceBaseSig" + } + ], + "id": 1386, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "1348:7:13", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": { + "id": 1385, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1348:7:13", + "typeDescriptions": {} + } + }, + "id": 1388, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1348:13:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 1389, + "name": "_digest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1374, + "src": "1371:7:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_stringliteral_301a50b291d33ce1e8e9064e3f6a6c51d902ec22892b50d58abf6357c6a45541", + "typeString": "literal_string hex\"1901\"" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "expression": { + "id": 1380, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967295, + "src": "1279:3:13", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 1381, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "1283:12:13", + "memberName": "encodePacked", + "nodeType": "MemberAccess", + "src": "1279:16:13", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencodepacked_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 1390, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1279:107:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 1379, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967288, + "src": "1262:9:13", + "typeDescriptions": { + "typeIdentifier": "t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$", + "typeString": "function (bytes memory) pure returns (bytes32)" + } + }, + "id": 1391, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1262:130:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "functionReturnParameters": 1378, + "id": 1392, + "nodeType": "Return", + "src": "1255:137:13" + } + ] + }, + "documentation": { + "id": 1372, + "nodeType": "StructuredDocumentation", + "src": "934:236:13", + "text": " @notice Generates a subdigest for the input digest (unique for this wallet and network).\n @param _digest The input digest to generate the subdigest from.\n @return bytes32 The subdigest generated from the input digest." + }, + "id": 1394, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "subdigest", + "nameLocation": "1182:9:13", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 1375, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1374, + "mutability": "mutable", + "name": "_digest", + "nameLocation": "1205:7:13", + "nodeType": "VariableDeclaration", + "scope": 1394, + "src": "1197:15:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1373, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1197:7:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "1191:25:13" + }, + "returnParameters": { + "id": 1378, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1377, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 1394, + "src": "1240:7:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1376, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1240:7:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "1239:9:13" + }, + "scope": 2021, + "src": "1173:224:13", + "stateMutability": "view", + "virtual": false, + "visibility": "internal" + }, + { + "body": { + "id": 1423, + "nodeType": "Block", + "src": "1834:100:13", + "statements": [ + { + "id": 1422, + "nodeType": "UncheckedBlock", + "src": "1840:90:13", + "statements": [ + { + "expression": { + "arguments": [ + { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 1419, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 1411, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "arguments": [ + { + "id": 1408, + "name": "_weight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1399, + "src": "1881:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint96", + "typeString": "uint96" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint96", + "typeString": "uint96" + } + ], + "id": 1407, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "1873:7:13", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint256_$", + "typeString": "type(uint256)" + }, + "typeName": { + "id": 1406, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1873:7:13", + "typeDescriptions": {} + } + }, + "id": 1409, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1873:16:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<<", + "rightExpression": { + "hexValue": "313630", + "id": 1410, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1893:3:13", + "typeDescriptions": { + "typeIdentifier": "t_rational_160_by_1", + "typeString": "int_const 160" + }, + "value": "160" + }, + "src": "1873:23:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "|", + "rightExpression": { + "arguments": [ + { + "arguments": [ + { + "id": 1416, + "name": "_addr", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1397, + "src": "1915:5:13", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 1415, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "1907:7:13", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint160_$", + "typeString": "type(uint160)" + }, + "typeName": { + "id": 1414, + "name": "uint160", + "nodeType": "ElementaryTypeName", + "src": "1907:7:13", + "typeDescriptions": {} + } + }, + "id": 1417, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1907:14:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint160", + "typeString": "uint160" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint160", + "typeString": "uint160" + } + ], + "id": 1413, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "1899:7:13", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint256_$", + "typeString": "type(uint256)" + }, + "typeName": { + "id": 1412, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1899:7:13", + "typeDescriptions": {} + } + }, + "id": 1418, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1899:23:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "1873:49:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 1405, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "1865:7:13", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes32_$", + "typeString": "type(bytes32)" + }, + "typeName": { + "id": 1404, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1865:7:13", + "typeDescriptions": {} + } + }, + "id": 1420, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1865:58:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "functionReturnParameters": 1403, + "id": 1421, + "nodeType": "Return", + "src": "1858:65:13" + } + ] + } + ] + }, + "documentation": { + "id": 1395, + "nodeType": "StructuredDocumentation", + "src": "1401:321:13", + "text": " @notice Generates the leaf for an address and weight.\n @dev The leaf is generated by concatenating the address and weight.\n @param _addr The address to generate the leaf for.\n @param _weight The weight to generate the leaf for.\n @return bytes32 The leaf generated from the address and weight." + }, + "id": 1424, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "_leafForAddressAndWeight", + "nameLocation": "1734:24:13", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 1400, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1397, + "mutability": "mutable", + "name": "_addr", + "nameLocation": "1772:5:13", + "nodeType": "VariableDeclaration", + "scope": 1424, + "src": "1764:13:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 1396, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1764:7:13", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1399, + "mutability": "mutable", + "name": "_weight", + "nameLocation": "1790:7:13", + "nodeType": "VariableDeclaration", + "scope": 1424, + "src": "1783:14:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint96", + "typeString": "uint96" + }, + "typeName": { + "id": 1398, + "name": "uint96", + "nodeType": "ElementaryTypeName", + "src": "1783:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint96", + "typeString": "uint96" + } + }, + "visibility": "internal" + } + ], + "src": "1758:43:13" + }, + "returnParameters": { + "id": 1403, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1402, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 1424, + "src": "1825:7:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1401, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1825:7:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "1824:9:13" + }, + "scope": 2021, + "src": "1725:209:13", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": { + "id": 1440, + "nodeType": "Block", + "src": "2323:86:13", + "statements": [ + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "hexValue": "53657175656e636520737461746963206469676573743a0a", + "id": 1435, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "2363:27:13", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_583557e68bca91e5400591dbc9ae31043113c95e3cd985463ae532f51d706f8c", + "typeString": "literal_string hex\"53657175656e636520737461746963206469676573743a0a\"" + }, + "value": "Sequence static digest:\n" + }, + { + "id": 1436, + "name": "_subdigest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1427, + "src": "2392:10:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_stringliteral_583557e68bca91e5400591dbc9ae31043113c95e3cd985463ae532f51d706f8c", + "typeString": "literal_string hex\"53657175656e636520737461746963206469676573743a0a\"" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "expression": { + "id": 1433, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967295, + "src": "2346:3:13", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 1434, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "2350:12:13", + "memberName": "encodePacked", + "nodeType": "MemberAccess", + "src": "2346:16:13", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencodepacked_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 1437, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2346:57:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 1432, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967288, + "src": "2336:9:13", + "typeDescriptions": { + "typeIdentifier": "t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$", + "typeString": "function (bytes memory) pure returns (bytes32)" + } + }, + "id": 1438, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2336:68:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "functionReturnParameters": 1431, + "id": 1439, + "nodeType": "Return", + "src": "2329:75:13" + } + ] + }, + "documentation": { + "id": 1425, + "nodeType": "StructuredDocumentation", + "src": "1938:286:13", + "text": " @notice Generates the leaf for a hardcoded subdigest.\n @dev The leaf is generated by hashing 'Sequence static digest:\\n' and the subdigest.\n @param _subdigest The subdigest to generate the leaf for.\n @return bytes32 The leaf generated from the hardcoded subdigest." + }, + "id": 1441, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "_leafForHardcodedSubdigest", + "nameLocation": "2236:26:13", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 1428, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1427, + "mutability": "mutable", + "name": "_subdigest", + "nameLocation": "2276:10:13", + "nodeType": "VariableDeclaration", + "scope": 1441, + "src": "2268:18:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1426, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2268:7:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "2262:28:13" + }, + "returnParameters": { + "id": 1431, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1430, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 1441, + "src": "2314:7:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1429, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2314:7:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "2313:9:13" + }, + "scope": 2021, + "src": "2227:182:13", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": { + "id": 1463, + "nodeType": "Block", + "src": "2953:102:13", + "statements": [ + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "hexValue": "53657175656e6365206e657374656420636f6e6669673a0a", + "id": 1456, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "2993:27:13", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_58d1832f15932b40f8da147bd99ac98efab990f25a786a2229b05ee5f5be41a7", + "typeString": "literal_string hex\"53657175656e6365206e657374656420636f6e6669673a0a\"" + }, + "value": "Sequence nested config:\n" + }, + { + "id": 1457, + "name": "_node", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1444, + "src": "3022:5:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 1458, + "name": "_threshold", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1446, + "src": "3029:10:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 1459, + "name": "_weight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1448, + "src": "3041:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_stringliteral_58d1832f15932b40f8da147bd99ac98efab990f25a786a2229b05ee5f5be41a7", + "typeString": "literal_string hex\"53657175656e6365206e657374656420636f6e6669673a0a\"" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "id": 1454, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967295, + "src": "2976:3:13", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 1455, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "2980:12:13", + "memberName": "encodePacked", + "nodeType": "MemberAccess", + "src": "2976:16:13", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencodepacked_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 1460, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2976:73:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 1453, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967288, + "src": "2966:9:13", + "typeDescriptions": { + "typeIdentifier": "t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$", + "typeString": "function (bytes memory) pure returns (bytes32)" + } + }, + "id": 1461, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2966:84:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "functionReturnParameters": 1452, + "id": 1462, + "nodeType": "Return", + "src": "2959:91:13" + } + ] + }, + "documentation": { + "id": 1442, + "nodeType": "StructuredDocumentation", + "src": "2413:413:13", + "text": " @notice Generates the leaf for a nested tree node.\n @dev The leaf is generated by hashing 'Sequence nested config:\\n', the node, the threshold and the weight.\n @param _node The root of the node to generate the leaf for.\n @param _threshold The internal threshold of the tree.\n @param _weight The external weight of the tree.\n @return bytes32 The leaf generated from the nested tree." + }, + "id": 1464, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "_leafForNested", + "nameLocation": "2838:14:13", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 1449, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1444, + "mutability": "mutable", + "name": "_node", + "nameLocation": "2866:5:13", + "nodeType": "VariableDeclaration", + "scope": 1464, + "src": "2858:13:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1443, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2858:7:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1446, + "mutability": "mutable", + "name": "_threshold", + "nameLocation": "2885:10:13", + "nodeType": "VariableDeclaration", + "scope": 1464, + "src": "2877:18:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1445, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2877:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1448, + "mutability": "mutable", + "name": "_weight", + "nameLocation": "2909:7:13", + "nodeType": "VariableDeclaration", + "scope": 1464, + "src": "2901:15:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1447, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2901:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "2852:68:13" + }, + "returnParameters": { + "id": 1452, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1451, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 1464, + "src": "2944:7:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1450, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2944:7:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "2943:9:13" + }, + "scope": 2021, + "src": "2829:226:13", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": { + "id": 1953, + "nodeType": "Block", + "src": "3672:4561:13", + "statements": [ + { + "id": 1952, + "nodeType": "UncheckedBlock", + "src": "3678:4551:13", + "statements": [ + { + "assignments": [ + 1477 + ], + "declarations": [ + { + "constant": false, + "id": 1477, + "mutability": "mutable", + "name": "rindex", + "nameLocation": "3704:6:13", + "nodeType": "VariableDeclaration", + "scope": 1952, + "src": "3696:14:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1476, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3696:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 1478, + "nodeType": "VariableDeclarationStatement", + "src": "3696:14:13" + }, + { + "body": { + "id": 1950, + "nodeType": "Block", + "src": "3800:4423:13", + "statements": [ + { + "assignments": [ + 1484 + ], + "declarations": [ + { + "constant": false, + "id": 1484, + "mutability": "mutable", + "name": "flag", + "nameLocation": "3849:4:13", + "nodeType": "VariableDeclaration", + "scope": 1950, + "src": "3841:12:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1483, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3841:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 1485, + "nodeType": "VariableDeclarationStatement", + "src": "3841:12:13" + }, + { + "expression": { + "id": 1493, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "components": [ + { + "id": 1486, + "name": "flag", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1484, + "src": "3864:4:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 1487, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1477, + "src": "3870:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 1488, + "isConstant": false, + "isInlineArray": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "TupleExpression", + "src": "3863:14:13", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_uint256_$", + "typeString": "tuple(uint256,uint256)" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 1491, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1477, + "src": "3901:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "id": 1489, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1469, + "src": "3880:10:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "id": 1490, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "3891:9:13", + "memberName": "readUint8", + "nodeType": "MemberAccess", + "referencedDeclaration": 2403, + "src": "3880:20:13", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes_calldata_ptr_$_t_uint256_$returns$_t_uint8_$_t_uint256_$attached_to$_t_bytes_calldata_ptr_$", + "typeString": "function (bytes calldata,uint256) pure returns (uint8,uint256)" + } + }, + "id": 1492, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3880:28:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint8_$_t_uint256_$", + "typeString": "tuple(uint8,uint256)" + } + }, + "src": "3863:45:13", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1494, + "nodeType": "ExpressionStatement", + "src": "3863:45:13" + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 1497, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 1495, + "name": "flag", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1484, + "src": "3923:4:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "id": 1496, + "name": "FLAG_ADDRESS", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1344, + "src": "3931:12:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "3923:20:13", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 1539, + "nodeType": "IfStatement", + "src": "3919:402:13", + "trueBody": { + "id": 1538, + "nodeType": "Block", + "src": "3945:376:13", + "statements": [ + { + "assignments": [ + 1499 + ], + "declarations": [ + { + "constant": false, + "id": 1499, + "mutability": "mutable", + "name": "addrWeight", + "nameLocation": "3995:10:13", + "nodeType": "VariableDeclaration", + "scope": 1538, + "src": "3989:16:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 1498, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "3989:5:13", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "visibility": "internal" + } + ], + "id": 1500, + "nodeType": "VariableDeclarationStatement", + "src": "3989:16:13" + }, + { + "assignments": [ + 1502 + ], + "declarations": [ + { + "constant": false, + "id": 1502, + "mutability": "mutable", + "name": "addr", + "nameLocation": "4015:4:13", + "nodeType": "VariableDeclaration", + "scope": 1538, + "src": "4007:12:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 1501, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "4007:7:13", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "id": 1503, + "nodeType": "VariableDeclarationStatement", + "src": "4007:12:13" + }, + { + "expression": { + "id": 1512, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "components": [ + { + "id": 1504, + "name": "addrWeight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1499, + "src": "4032:10:13", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + { + "id": 1505, + "name": "addr", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1502, + "src": "4044:4:13", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 1506, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1477, + "src": "4050:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 1507, + "isConstant": false, + "isInlineArray": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "TupleExpression", + "src": "4031:26:13", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint8_$_t_address_$_t_uint256_$", + "typeString": "tuple(uint8,address,uint256)" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 1510, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1477, + "src": "4088:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "id": 1508, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1469, + "src": "4060:10:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "id": 1509, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "4071:16:13", + "memberName": "readUint8Address", + "nodeType": "MemberAccess", + "referencedDeclaration": 2419, + "src": "4060:27:13", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes_calldata_ptr_$_t_uint256_$returns$_t_uint8_$_t_address_$_t_uint256_$attached_to$_t_bytes_calldata_ptr_$", + "typeString": "function (bytes calldata,uint256) pure returns (uint8,address,uint256)" + } + }, + "id": 1511, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "4060:35:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint8_$_t_address_$_t_uint256_$", + "typeString": "tuple(uint8,address,uint256)" + } + }, + "src": "4031:64:13", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1513, + "nodeType": "ExpressionStatement", + "src": "4031:64:13" + }, + { + "assignments": [ + 1515 + ], + "declarations": [ + { + "constant": false, + "id": 1515, + "mutability": "mutable", + "name": "node", + "nameLocation": "4163:4:13", + "nodeType": "VariableDeclaration", + "scope": 1538, + "src": "4155:12:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1514, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "4155:7:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "id": 1520, + "initialValue": { + "arguments": [ + { + "id": 1517, + "name": "addr", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1502, + "src": "4195:4:13", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 1518, + "name": "addrWeight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1499, + "src": "4201:10:13", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + ], + "id": 1516, + "name": "_leafForAddressAndWeight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1424, + "src": "4170:24:13", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_address_$_t_uint96_$returns$_t_bytes32_$", + "typeString": "function (address,uint96) pure returns (bytes32)" + } + }, + "id": 1519, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "4170:42:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "4155:57:13" + }, + { + "expression": { + "id": 1535, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 1521, + "name": "root", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1474, + "src": "4224:4:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "condition": { + "commonType": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 1527, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 1522, + "name": "root", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1474, + "src": "4231:4:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "arguments": [ + { + "hexValue": "30", + "id": 1525, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4247:1:13", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 1524, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "4239:7:13", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes32_$", + "typeString": "type(bytes32)" + }, + "typeName": { + "id": 1523, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "4239:7:13", + "typeDescriptions": {} + } + }, + "id": 1526, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "4239:10:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "4231:18:13", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": { + "id": 1533, + "name": "node", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1515, + "src": "4286:4:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 1534, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "4231:59:13", + "trueExpression": { + "arguments": [ + { + "id": 1530, + "name": "root", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1474, + "src": "4272:4:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 1531, + "name": "node", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1515, + "src": "4278:4:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "expression": { + "id": 1528, + "name": "LibOptim", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2530, + "src": "4252:8:13", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_LibOptim_$2530_$", + "typeString": "type(library LibOptim)" + } + }, + "id": 1529, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "4261:10:13", + "memberName": "fkeccak256", + "nodeType": "MemberAccess", + "referencedDeclaration": 2491, + "src": "4252:19:13", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes32_$_t_bytes32_$returns$_t_bytes32_$", + "typeString": "function (bytes32,bytes32) pure returns (bytes32)" + } + }, + "id": 1532, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "4252:31:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "4224:66:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 1536, + "nodeType": "ExpressionStatement", + "src": "4224:66:13" + }, + { + "id": 1537, + "nodeType": "Continue", + "src": "4302:8:13" + } + ] + } + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 1542, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 1540, + "name": "flag", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1484, + "src": "4335:4:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "id": 1541, + "name": "FLAG_SIGNATURE", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1341, + "src": "4343:14:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "4335:22:13", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 1605, + "nodeType": "IfStatement", + "src": "4331:679:13", + "trueBody": { + "id": 1604, + "nodeType": "Block", + "src": "4359:651:13", + "statements": [ + { + "assignments": [ + 1544 + ], + "declarations": [ + { + "constant": false, + "id": 1544, + "mutability": "mutable", + "name": "addrWeight", + "nameLocation": "4402:10:13", + "nodeType": "VariableDeclaration", + "scope": 1604, + "src": "4396:16:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 1543, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "4396:5:13", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "visibility": "internal" + } + ], + "id": 1545, + "nodeType": "VariableDeclarationStatement", + "src": "4396:16:13" + }, + { + "expression": { + "id": 1553, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "components": [ + { + "id": 1546, + "name": "addrWeight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1544, + "src": "4425:10:13", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + { + "id": 1547, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1477, + "src": "4437:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 1548, + "isConstant": false, + "isInlineArray": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "TupleExpression", + "src": "4424:20:13", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint8_$_t_uint256_$", + "typeString": "tuple(uint8,uint256)" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 1551, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1477, + "src": "4468:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "id": 1549, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1469, + "src": "4447:10:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "id": 1550, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "4458:9:13", + "memberName": "readUint8", + "nodeType": "MemberAccess", + "referencedDeclaration": 2403, + "src": "4447:20:13", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes_calldata_ptr_$_t_uint256_$returns$_t_uint8_$_t_uint256_$attached_to$_t_bytes_calldata_ptr_$", + "typeString": "function (bytes calldata,uint256) pure returns (uint8,uint256)" + } + }, + "id": 1552, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "4447:28:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint8_$_t_uint256_$", + "typeString": "tuple(uint8,uint256)" + } + }, + "src": "4424:51:13", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1554, + "nodeType": "ExpressionStatement", + "src": "4424:51:13" + }, + { + "assignments": [ + 1556 + ], + "declarations": [ + { + "constant": false, + "id": 1556, + "mutability": "mutable", + "name": "nrindex", + "nameLocation": "4550:7:13", + "nodeType": "VariableDeclaration", + "scope": 1604, + "src": "4542:15:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1555, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "4542:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 1560, + "initialValue": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 1559, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 1557, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1477, + "src": "4560:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": { + "hexValue": "3636", + "id": 1558, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4569:2:13", + "typeDescriptions": { + "typeIdentifier": "t_rational_66_by_1", + "typeString": "int_const 66" + }, + "value": "66" + }, + "src": "4560:11:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "4542:29:13" + }, + { + "assignments": [ + 1562 + ], + "declarations": [ + { + "constant": false, + "id": 1562, + "mutability": "mutable", + "name": "addr", + "nameLocation": "4591:4:13", + "nodeType": "VariableDeclaration", + "scope": 1604, + "src": "4583:12:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 1561, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "4583:7:13", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "id": 1571, + "initialValue": { + "arguments": [ + { + "id": 1565, + "name": "_subdigest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1467, + "src": "4631:10:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "baseExpression": { + "id": 1566, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1469, + "src": "4643:10:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "endExpression": { + "id": 1568, + "name": "nrindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1556, + "src": "4661:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 1569, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexRangeAccess", + "src": "4643:26:13", + "startExpression": { + "id": 1567, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1477, + "src": "4654:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr_slice", + "typeString": "bytes calldata slice" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes_calldata_ptr_slice", + "typeString": "bytes calldata slice" + } + ], + "expression": { + "id": 1563, + "name": "SignatureValidator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2798, + "src": "4598:18:13", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_SignatureValidator_$2798_$", + "typeString": "type(library SignatureValidator)" + } + }, + "id": 1564, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "4617:13:13", + "memberName": "recoverSigner", + "nodeType": "MemberAccess", + "referencedDeclaration": 2715, + "src": "4598:32:13", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes32_$_t_bytes_calldata_ptr_$returns$_t_address_$", + "typeString": "function (bytes32,bytes calldata) pure returns (address)" + } + }, + "id": 1570, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "4598:72:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "4583:87:13" + }, + { + "expression": { + "id": 1574, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 1572, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1477, + "src": "4682:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "id": 1573, + "name": "nrindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1556, + "src": "4691:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "4682:16:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 1575, + "nodeType": "ExpressionStatement", + "src": "4682:16:13" + }, + { + "expression": { + "id": 1578, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 1576, + "name": "weight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1472, + "src": "4764:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "+=", + "rightHandSide": { + "id": 1577, + "name": "addrWeight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1544, + "src": "4774:10:13", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "src": "4764:20:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 1579, + "nodeType": "ExpressionStatement", + "src": "4764:20:13" + }, + { + "assignments": [ + 1581 + ], + "declarations": [ + { + "constant": false, + "id": 1581, + "mutability": "mutable", + "name": "node", + "nameLocation": "4852:4:13", + "nodeType": "VariableDeclaration", + "scope": 1604, + "src": "4844:12:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1580, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "4844:7:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "id": 1586, + "initialValue": { + "arguments": [ + { + "id": 1583, + "name": "addr", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1562, + "src": "4884:4:13", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 1584, + "name": "addrWeight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1544, + "src": "4890:10:13", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + ], + "id": 1582, + "name": "_leafForAddressAndWeight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1424, + "src": "4859:24:13", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_address_$_t_uint96_$returns$_t_bytes32_$", + "typeString": "function (address,uint96) pure returns (bytes32)" + } + }, + "id": 1585, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "4859:42:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "4844:57:13" + }, + { + "expression": { + "id": 1601, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 1587, + "name": "root", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1474, + "src": "4913:4:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "condition": { + "commonType": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 1593, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 1588, + "name": "root", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1474, + "src": "4920:4:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "arguments": [ + { + "hexValue": "30", + "id": 1591, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4936:1:13", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 1590, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "4928:7:13", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes32_$", + "typeString": "type(bytes32)" + }, + "typeName": { + "id": 1589, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "4928:7:13", + "typeDescriptions": {} + } + }, + "id": 1592, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "4928:10:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "4920:18:13", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": { + "id": 1599, + "name": "node", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1581, + "src": "4975:4:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 1600, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "4920:59:13", + "trueExpression": { + "arguments": [ + { + "id": 1596, + "name": "root", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1474, + "src": "4961:4:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 1597, + "name": "node", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1581, + "src": "4967:4:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "expression": { + "id": 1594, + "name": "LibOptim", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2530, + "src": "4941:8:13", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_LibOptim_$2530_$", + "typeString": "type(library LibOptim)" + } + }, + "id": 1595, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "4950:10:13", + "memberName": "fkeccak256", + "nodeType": "MemberAccess", + "referencedDeclaration": 2491, + "src": "4941:19:13", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes32_$_t_bytes32_$returns$_t_bytes32_$", + "typeString": "function (bytes32,bytes32) pure returns (bytes32)" + } + }, + "id": 1598, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "4941:31:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "4913:66:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 1602, + "nodeType": "ExpressionStatement", + "src": "4913:66:13" + }, + { + "id": 1603, + "nodeType": "Continue", + "src": "4991:8:13" + } + ] + } + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 1608, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 1606, + "name": "flag", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1484, + "src": "5024:4:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "id": 1607, + "name": "FLAG_DYNAMIC_SIGNATURE", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1347, + "src": "5032:22:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "5024:30:13", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 1697, + "nodeType": "IfStatement", + "src": "5020:932:13", + "trueBody": { + "id": 1696, + "nodeType": "Block", + "src": "5056:896:13", + "statements": [ + { + "assignments": [ + 1610 + ], + "declarations": [ + { + "constant": false, + "id": 1610, + "mutability": "mutable", + "name": "addrWeight", + "nameLocation": "5110:10:13", + "nodeType": "VariableDeclaration", + "scope": 1696, + "src": "5104:16:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 1609, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "5104:5:13", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "visibility": "internal" + } + ], + "id": 1611, + "nodeType": "VariableDeclarationStatement", + "src": "5104:16:13" + }, + { + "assignments": [ + 1613 + ], + "declarations": [ + { + "constant": false, + "id": 1613, + "mutability": "mutable", + "name": "addr", + "nameLocation": "5130:4:13", + "nodeType": "VariableDeclaration", + "scope": 1696, + "src": "5122:12:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 1612, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "5122:7:13", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "id": 1614, + "nodeType": "VariableDeclarationStatement", + "src": "5122:12:13" + }, + { + "expression": { + "id": 1623, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "components": [ + { + "id": 1615, + "name": "addrWeight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1610, + "src": "5147:10:13", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + { + "id": 1616, + "name": "addr", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1613, + "src": "5159:4:13", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 1617, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1477, + "src": "5165:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 1618, + "isConstant": false, + "isInlineArray": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "TupleExpression", + "src": "5146:26:13", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint8_$_t_address_$_t_uint256_$", + "typeString": "tuple(uint8,address,uint256)" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 1621, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1477, + "src": "5203:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "id": 1619, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1469, + "src": "5175:10:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "id": 1620, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "5186:16:13", + "memberName": "readUint8Address", + "nodeType": "MemberAccess", + "referencedDeclaration": 2419, + "src": "5175:27:13", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes_calldata_ptr_$_t_uint256_$returns$_t_uint8_$_t_address_$_t_uint256_$attached_to$_t_bytes_calldata_ptr_$", + "typeString": "function (bytes calldata,uint256) pure returns (uint8,address,uint256)" + } + }, + "id": 1622, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "5175:35:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint8_$_t_address_$_t_uint256_$", + "typeString": "tuple(uint8,address,uint256)" + } + }, + "src": "5146:64:13", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1624, + "nodeType": "ExpressionStatement", + "src": "5146:64:13" + }, + { + "assignments": [ + 1626 + ], + "declarations": [ + { + "constant": false, + "id": 1626, + "mutability": "mutable", + "name": "size", + "nameLocation": "5264:4:13", + "nodeType": "VariableDeclaration", + "scope": 1696, + "src": "5256:12:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1625, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "5256:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 1627, + "nodeType": "VariableDeclarationStatement", + "src": "5256:12:13" + }, + { + "expression": { + "id": 1635, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "components": [ + { + "id": 1628, + "name": "size", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1626, + "src": "5281:4:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 1629, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1477, + "src": "5287:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 1630, + "isConstant": false, + "isInlineArray": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "TupleExpression", + "src": "5280:14:13", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_uint256_$", + "typeString": "tuple(uint256,uint256)" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 1633, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1477, + "src": "5319:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "id": 1631, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1469, + "src": "5297:10:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "id": 1632, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "5308:10:13", + "memberName": "readUint24", + "nodeType": "MemberAccess", + "referencedDeclaration": 2447, + "src": "5297:21:13", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes_calldata_ptr_$_t_uint256_$returns$_t_uint24_$_t_uint256_$attached_to$_t_bytes_calldata_ptr_$", + "typeString": "function (bytes calldata,uint256) pure returns (uint24,uint256)" + } + }, + "id": 1634, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "5297:29:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint24_$_t_uint256_$", + "typeString": "tuple(uint24,uint256)" + } + }, + "src": "5280:46:13", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1636, + "nodeType": "ExpressionStatement", + "src": "5280:46:13" + }, + { + "assignments": [ + 1638 + ], + "declarations": [ + { + "constant": false, + "id": 1638, + "mutability": "mutable", + "name": "nrindex", + "nameLocation": "5388:7:13", + "nodeType": "VariableDeclaration", + "scope": 1696, + "src": "5380:15:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1637, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "5380:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 1642, + "initialValue": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 1641, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 1639, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1477, + "src": "5398:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": { + "id": 1640, + "name": "size", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1626, + "src": "5407:4:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "5398:13:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "5380:31:13" + }, + { + "condition": { + "id": 1652, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "!", + "prefix": true, + "src": "5427:82:13", + "subExpression": { + "arguments": [ + { + "id": 1645, + "name": "_subdigest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1467, + "src": "5464:10:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 1646, + "name": "addr", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1613, + "src": "5476:4:13", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "baseExpression": { + "id": 1647, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1469, + "src": "5482:10:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "endExpression": { + "id": 1649, + "name": "nrindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1638, + "src": "5500:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 1650, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexRangeAccess", + "src": "5482:26:13", + "startExpression": { + "id": 1648, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1477, + "src": "5493:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr_slice", + "typeString": "bytes calldata slice" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_bytes_calldata_ptr_slice", + "typeString": "bytes calldata slice" + } + ], + "expression": { + "id": 1643, + "name": "SignatureValidator", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2798, + "src": "5428:18:13", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_SignatureValidator_$2798_$", + "typeString": "type(library SignatureValidator)" + } + }, + "id": 1644, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "5447:16:13", + "memberName": "isValidSignature", + "nodeType": "MemberAccess", + "referencedDeclaration": 2797, + "src": "5428:35:13", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$_t_address_$_t_bytes_calldata_ptr_$returns$_t_bool_$", + "typeString": "function (bytes32,address,bytes calldata) view returns (bool)" + } + }, + "id": 1651, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "5428:81:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 1663, + "nodeType": "IfStatement", + "src": "5423:190:13", + "trueBody": { + "id": 1662, + "nodeType": "Block", + "src": "5511:102:13", + "statements": [ + { + "errorCall": { + "arguments": [ + { + "id": 1654, + "name": "_subdigest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1467, + "src": "5555:10:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 1655, + "name": "addr", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1613, + "src": "5567:4:13", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "baseExpression": { + "id": 1656, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1469, + "src": "5573:10:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "endExpression": { + "id": 1658, + "name": "nrindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1638, + "src": "5591:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 1659, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexRangeAccess", + "src": "5573:26:13", + "startExpression": { + "id": 1657, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1477, + "src": "5584:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr_slice", + "typeString": "bytes calldata slice" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_bytes_calldata_ptr_slice", + "typeString": "bytes calldata slice" + } + ], + "id": 1653, + "name": "InvalidNestedSignature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1367, + "src": "5532:22:13", + "typeDescriptions": { + "typeIdentifier": "t_function_error_pure$_t_bytes32_$_t_address_$_t_bytes_memory_ptr_$returns$__$", + "typeString": "function (bytes32,address,bytes memory) pure" + } + }, + "id": 1660, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "5532:68:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1661, + "nodeType": "RevertStatement", + "src": "5525:75:13" + } + ] + } + }, + { + "expression": { + "id": 1666, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 1664, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1477, + "src": "5624:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "id": 1665, + "name": "nrindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1638, + "src": "5633:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "5624:16:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 1667, + "nodeType": "ExpressionStatement", + "src": "5624:16:13" + }, + { + "expression": { + "id": 1670, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 1668, + "name": "weight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1472, + "src": "5706:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "+=", + "rightHandSide": { + "id": 1669, + "name": "addrWeight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1610, + "src": "5716:10:13", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "src": "5706:20:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 1671, + "nodeType": "ExpressionStatement", + "src": "5706:20:13" + }, + { + "assignments": [ + 1673 + ], + "declarations": [ + { + "constant": false, + "id": 1673, + "mutability": "mutable", + "name": "node", + "nameLocation": "5794:4:13", + "nodeType": "VariableDeclaration", + "scope": 1696, + "src": "5786:12:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1672, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "5786:7:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "id": 1678, + "initialValue": { + "arguments": [ + { + "id": 1675, + "name": "addr", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1613, + "src": "5826:4:13", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 1676, + "name": "addrWeight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1610, + "src": "5832:10:13", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + ], + "id": 1674, + "name": "_leafForAddressAndWeight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1424, + "src": "5801:24:13", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_address_$_t_uint96_$returns$_t_bytes32_$", + "typeString": "function (address,uint96) pure returns (bytes32)" + } + }, + "id": 1677, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "5801:42:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "5786:57:13" + }, + { + "expression": { + "id": 1693, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 1679, + "name": "root", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1474, + "src": "5855:4:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "condition": { + "commonType": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 1685, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 1680, + "name": "root", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1474, + "src": "5862:4:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "arguments": [ + { + "hexValue": "30", + "id": 1683, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5878:1:13", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 1682, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "5870:7:13", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes32_$", + "typeString": "type(bytes32)" + }, + "typeName": { + "id": 1681, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "5870:7:13", + "typeDescriptions": {} + } + }, + "id": 1684, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "5870:10:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "5862:18:13", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": { + "id": 1691, + "name": "node", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1673, + "src": "5917:4:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 1692, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "5862:59:13", + "trueExpression": { + "arguments": [ + { + "id": 1688, + "name": "root", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1474, + "src": "5903:4:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 1689, + "name": "node", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1673, + "src": "5909:4:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "expression": { + "id": 1686, + "name": "LibOptim", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2530, + "src": "5883:8:13", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_LibOptim_$2530_$", + "typeString": "type(library LibOptim)" + } + }, + "id": 1687, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "5892:10:13", + "memberName": "fkeccak256", + "nodeType": "MemberAccess", + "referencedDeclaration": 2491, + "src": "5883:19:13", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes32_$_t_bytes32_$returns$_t_bytes32_$", + "typeString": "function (bytes32,bytes32) pure returns (bytes32)" + } + }, + "id": 1690, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "5883:31:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "5855:66:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 1694, + "nodeType": "ExpressionStatement", + "src": "5855:66:13" + }, + { + "id": 1695, + "nodeType": "Continue", + "src": "5933:8:13" + } + ] + } + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 1700, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 1698, + "name": "flag", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1484, + "src": "5966:4:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "id": 1699, + "name": "FLAG_NODE", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1350, + "src": "5974:9:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "5966:17:13", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 1731, + "nodeType": "IfStatement", + "src": "5962:243:13", + "trueBody": { + "id": 1730, + "nodeType": "Block", + "src": "5985:220:13", + "statements": [ + { + "assignments": [ + 1702 + ], + "declarations": [ + { + "constant": false, + "id": 1702, + "mutability": "mutable", + "name": "node", + "nameLocation": "6033:4:13", + "nodeType": "VariableDeclaration", + "scope": 1730, + "src": "6025:12:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1701, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "6025:7:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "id": 1703, + "nodeType": "VariableDeclarationStatement", + "src": "6025:12:13" + }, + { + "expression": { + "id": 1711, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "components": [ + { + "id": 1704, + "name": "node", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1702, + "src": "6050:4:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 1705, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1477, + "src": "6056:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 1706, + "isConstant": false, + "isInlineArray": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "TupleExpression", + "src": "6049:14:13", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_bytes32_$_t_uint256_$", + "typeString": "tuple(bytes32,uint256)" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 1709, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1477, + "src": "6089:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "id": 1707, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1469, + "src": "6066:10:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "id": 1708, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "6077:11:13", + "memberName": "readBytes32", + "nodeType": "MemberAccess", + "referencedDeclaration": 2475, + "src": "6066:22:13", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes_calldata_ptr_$_t_uint256_$returns$_t_bytes32_$_t_uint256_$attached_to$_t_bytes_calldata_ptr_$", + "typeString": "function (bytes calldata,uint256) pure returns (bytes32,uint256)" + } + }, + "id": 1710, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "6066:30:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_bytes32_$_t_uint256_$", + "typeString": "tuple(bytes32,uint256)" + } + }, + "src": "6049:47:13", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1712, + "nodeType": "ExpressionStatement", + "src": "6049:47:13" + }, + { + "expression": { + "id": 1727, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 1713, + "name": "root", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1474, + "src": "6108:4:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "condition": { + "commonType": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 1719, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 1714, + "name": "root", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1474, + "src": "6115:4:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "arguments": [ + { + "hexValue": "30", + "id": 1717, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "6131:1:13", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 1716, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "6123:7:13", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes32_$", + "typeString": "type(bytes32)" + }, + "typeName": { + "id": 1715, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "6123:7:13", + "typeDescriptions": {} + } + }, + "id": 1718, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "6123:10:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "6115:18:13", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": { + "id": 1725, + "name": "node", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1702, + "src": "6170:4:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 1726, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "6115:59:13", + "trueExpression": { + "arguments": [ + { + "id": 1722, + "name": "root", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1474, + "src": "6156:4:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 1723, + "name": "node", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1702, + "src": "6162:4:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "expression": { + "id": 1720, + "name": "LibOptim", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2530, + "src": "6136:8:13", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_LibOptim_$2530_$", + "typeString": "type(library LibOptim)" + } + }, + "id": 1721, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "6145:10:13", + "memberName": "fkeccak256", + "nodeType": "MemberAccess", + "referencedDeclaration": 2491, + "src": "6136:19:13", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes32_$_t_bytes32_$returns$_t_bytes32_$", + "typeString": "function (bytes32,bytes32) pure returns (bytes32)" + } + }, + "id": 1724, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "6136:31:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "6108:66:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 1728, + "nodeType": "ExpressionStatement", + "src": "6108:66:13" + }, + { + "id": 1729, + "nodeType": "Continue", + "src": "6186:8:13" + } + ] + } + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 1734, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 1732, + "name": "flag", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1484, + "src": "6219:4:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "id": 1733, + "name": "FLAG_BRANCH", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1353, + "src": "6227:11:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "6219:19:13", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 1789, + "nodeType": "IfStatement", + "src": "6215:472:13", + "trueBody": { + "id": 1788, + "nodeType": "Block", + "src": "6240:447:13", + "statements": [ + { + "assignments": [ + 1736 + ], + "declarations": [ + { + "constant": false, + "id": 1736, + "mutability": "mutable", + "name": "size", + "nameLocation": "6317:4:13", + "nodeType": "VariableDeclaration", + "scope": 1788, + "src": "6309:12:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1735, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "6309:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 1737, + "nodeType": "VariableDeclarationStatement", + "src": "6309:12:13" + }, + { + "expression": { + "id": 1745, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "components": [ + { + "id": 1738, + "name": "size", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1736, + "src": "6334:4:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 1739, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1477, + "src": "6340:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 1740, + "isConstant": false, + "isInlineArray": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "TupleExpression", + "src": "6333:14:13", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_uint256_$", + "typeString": "tuple(uint256,uint256)" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 1743, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1477, + "src": "6372:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "id": 1741, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1469, + "src": "6350:10:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "id": 1742, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "6361:10:13", + "memberName": "readUint24", + "nodeType": "MemberAccess", + "referencedDeclaration": 2447, + "src": "6350:21:13", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes_calldata_ptr_$_t_uint256_$returns$_t_uint24_$_t_uint256_$attached_to$_t_bytes_calldata_ptr_$", + "typeString": "function (bytes calldata,uint256) pure returns (uint24,uint256)" + } + }, + "id": 1744, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "6350:29:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint24_$_t_uint256_$", + "typeString": "tuple(uint24,uint256)" + } + }, + "src": "6333:46:13", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1746, + "nodeType": "ExpressionStatement", + "src": "6333:46:13" + }, + { + "assignments": [ + 1748 + ], + "declarations": [ + { + "constant": false, + "id": 1748, + "mutability": "mutable", + "name": "nrindex", + "nameLocation": "6399:7:13", + "nodeType": "VariableDeclaration", + "scope": 1788, + "src": "6391:15:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1747, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "6391:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 1752, + "initialValue": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 1751, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 1749, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1477, + "src": "6409:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": { + "id": 1750, + "name": "size", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1736, + "src": "6418:4:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "6409:13:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "6391:31:13" + }, + { + "assignments": [ + 1754 + ], + "declarations": [ + { + "constant": false, + "id": 1754, + "mutability": "mutable", + "name": "nweight", + "nameLocation": "6443:7:13", + "nodeType": "VariableDeclaration", + "scope": 1788, + "src": "6435:15:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1753, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "6435:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 1755, + "nodeType": "VariableDeclarationStatement", + "src": "6435:15:13" + }, + { + "assignments": [ + 1757 + ], + "declarations": [ + { + "constant": false, + "id": 1757, + "mutability": "mutable", + "name": "node", + "nameLocation": "6460:4:13", + "nodeType": "VariableDeclaration", + "scope": 1788, + "src": "6452:12:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1756, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "6452:7:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "id": 1758, + "nodeType": "VariableDeclarationStatement", + "src": "6452:12:13" + }, + { + "expression": { + "id": 1769, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "components": [ + { + "id": 1759, + "name": "nweight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1754, + "src": "6477:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 1760, + "name": "node", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1757, + "src": "6486:4:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 1761, + "isConstant": false, + "isInlineArray": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "TupleExpression", + "src": "6476:15:13", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_bytes32_$", + "typeString": "tuple(uint256,bytes32)" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 1763, + "name": "_subdigest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1467, + "src": "6508:10:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "baseExpression": { + "id": 1764, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1469, + "src": "6520:10:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "endExpression": { + "id": 1766, + "name": "nrindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1748, + "src": "6538:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 1767, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexRangeAccess", + "src": "6520:26:13", + "startExpression": { + "id": 1765, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1477, + "src": "6531:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr_slice", + "typeString": "bytes calldata slice" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes_calldata_ptr_slice", + "typeString": "bytes calldata slice" + } + ], + "id": 1762, + "name": "recoverBranch", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1954, + "src": "6494:13:13", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$_t_bytes_calldata_ptr_$returns$_t_uint256_$_t_bytes32_$", + "typeString": "function (bytes32,bytes calldata) view returns (uint256,bytes32)" + } + }, + "id": 1768, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "6494:53:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_bytes32_$", + "typeString": "tuple(uint256,bytes32)" + } + }, + "src": "6476:71:13", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1770, + "nodeType": "ExpressionStatement", + "src": "6476:71:13" + }, + { + "expression": { + "id": 1773, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 1771, + "name": "weight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1472, + "src": "6560:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "+=", + "rightHandSide": { + "id": 1772, + "name": "nweight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1754, + "src": "6570:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "6560:17:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 1774, + "nodeType": "ExpressionStatement", + "src": "6560:17:13" + }, + { + "expression": { + "id": 1781, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 1775, + "name": "root", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1474, + "src": "6589:4:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 1778, + "name": "root", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1474, + "src": "6616:4:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 1779, + "name": "node", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1757, + "src": "6622:4:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "expression": { + "id": 1776, + "name": "LibOptim", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2530, + "src": "6596:8:13", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_LibOptim_$2530_$", + "typeString": "type(library LibOptim)" + } + }, + "id": 1777, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "6605:10:13", + "memberName": "fkeccak256", + "nodeType": "MemberAccess", + "referencedDeclaration": 2491, + "src": "6596:19:13", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes32_$_t_bytes32_$returns$_t_bytes32_$", + "typeString": "function (bytes32,bytes32) pure returns (bytes32)" + } + }, + "id": 1780, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "6596:31:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "6589:38:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 1782, + "nodeType": "ExpressionStatement", + "src": "6589:38:13" + }, + { + "expression": { + "id": 1785, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 1783, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1477, + "src": "6640:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "id": 1784, + "name": "nrindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1748, + "src": "6649:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "6640:16:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 1786, + "nodeType": "ExpressionStatement", + "src": "6640:16:13" + }, + { + "id": 1787, + "nodeType": "Continue", + "src": "6668:8:13" + } + ] + } + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 1792, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 1790, + "name": "flag", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1484, + "src": "6701:4:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "id": 1791, + "name": "FLAG_NESTED", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1359, + "src": "6709:11:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "6701:19:13", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 1892, + "nodeType": "IfStatement", + "src": "6697:979:13", + "trueBody": { + "id": 1891, + "nodeType": "Block", + "src": "6722:954:13", + "statements": [ + { + "assignments": [ + 1794 + ], + "declarations": [ + { + "constant": false, + "id": 1794, + "mutability": "mutable", + "name": "externalWeight", + "nameLocation": "6872:14:13", + "nodeType": "VariableDeclaration", + "scope": 1891, + "src": "6864:22:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1793, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "6864:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 1795, + "nodeType": "VariableDeclarationStatement", + "src": "6864:22:13" + }, + { + "expression": { + "id": 1803, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "components": [ + { + "id": 1796, + "name": "externalWeight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1794, + "src": "6899:14:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 1797, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1477, + "src": "6915:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 1798, + "isConstant": false, + "isInlineArray": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "TupleExpression", + "src": "6898:24:13", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_uint256_$", + "typeString": "tuple(uint256,uint256)" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 1801, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1477, + "src": "6946:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "id": 1799, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1469, + "src": "6925:10:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "id": 1800, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "6936:9:13", + "memberName": "readUint8", + "nodeType": "MemberAccess", + "referencedDeclaration": 2403, + "src": "6925:20:13", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes_calldata_ptr_$_t_uint256_$returns$_t_uint8_$_t_uint256_$attached_to$_t_bytes_calldata_ptr_$", + "typeString": "function (bytes calldata,uint256) pure returns (uint8,uint256)" + } + }, + "id": 1802, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "6925:28:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint8_$_t_uint256_$", + "typeString": "tuple(uint8,uint256)" + } + }, + "src": "6898:55:13", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1804, + "nodeType": "ExpressionStatement", + "src": "6898:55:13" + }, + { + "assignments": [ + 1806 + ], + "declarations": [ + { + "constant": false, + "id": 1806, + "mutability": "mutable", + "name": "internalThreshold", + "nameLocation": "6974:17:13", + "nodeType": "VariableDeclaration", + "scope": 1891, + "src": "6966:25:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1805, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "6966:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 1807, + "nodeType": "VariableDeclarationStatement", + "src": "6966:25:13" + }, + { + "expression": { + "id": 1815, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "components": [ + { + "id": 1808, + "name": "internalThreshold", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1806, + "src": "7004:17:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 1809, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1477, + "src": "7023:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 1810, + "isConstant": false, + "isInlineArray": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "TupleExpression", + "src": "7003:27:13", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_uint256_$", + "typeString": "tuple(uint256,uint256)" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 1813, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1477, + "src": "7055:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "id": 1811, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1469, + "src": "7033:10:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "id": 1812, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "7044:10:13", + "memberName": "readUint16", + "nodeType": "MemberAccess", + "referencedDeclaration": 2433, + "src": "7033:21:13", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes_calldata_ptr_$_t_uint256_$returns$_t_uint16_$_t_uint256_$attached_to$_t_bytes_calldata_ptr_$", + "typeString": "function (bytes calldata,uint256) pure returns (uint16,uint256)" + } + }, + "id": 1814, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "7033:29:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint16_$_t_uint256_$", + "typeString": "tuple(uint16,uint256)" + } + }, + "src": "7003:59:13", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1816, + "nodeType": "ExpressionStatement", + "src": "7003:59:13" + }, + { + "assignments": [ + 1818 + ], + "declarations": [ + { + "constant": false, + "id": 1818, + "mutability": "mutable", + "name": "size", + "nameLocation": "7083:4:13", + "nodeType": "VariableDeclaration", + "scope": 1891, + "src": "7075:12:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1817, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "7075:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 1819, + "nodeType": "VariableDeclarationStatement", + "src": "7075:12:13" + }, + { + "expression": { + "id": 1827, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "components": [ + { + "id": 1820, + "name": "size", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1818, + "src": "7100:4:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 1821, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1477, + "src": "7106:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 1822, + "isConstant": false, + "isInlineArray": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "TupleExpression", + "src": "7099:14:13", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_uint256_$", + "typeString": "tuple(uint256,uint256)" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 1825, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1477, + "src": "7138:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "id": 1823, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1469, + "src": "7116:10:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "id": 1824, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "7127:10:13", + "memberName": "readUint24", + "nodeType": "MemberAccess", + "referencedDeclaration": 2447, + "src": "7116:21:13", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes_calldata_ptr_$_t_uint256_$returns$_t_uint24_$_t_uint256_$attached_to$_t_bytes_calldata_ptr_$", + "typeString": "function (bytes calldata,uint256) pure returns (uint24,uint256)" + } + }, + "id": 1826, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "7116:29:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint24_$_t_uint256_$", + "typeString": "tuple(uint24,uint256)" + } + }, + "src": "7099:46:13", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1828, + "nodeType": "ExpressionStatement", + "src": "7099:46:13" + }, + { + "assignments": [ + 1830 + ], + "declarations": [ + { + "constant": false, + "id": 1830, + "mutability": "mutable", + "name": "nrindex", + "nameLocation": "7165:7:13", + "nodeType": "VariableDeclaration", + "scope": 1891, + "src": "7157:15:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1829, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "7157:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 1834, + "initialValue": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 1833, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 1831, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1477, + "src": "7175:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": { + "id": 1832, + "name": "size", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1818, + "src": "7184:4:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7175:13:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "7157:31:13" + }, + { + "assignments": [ + 1836 + ], + "declarations": [ + { + "constant": false, + "id": 1836, + "mutability": "mutable", + "name": "internalWeight", + "nameLocation": "7209:14:13", + "nodeType": "VariableDeclaration", + "scope": 1891, + "src": "7201:22:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1835, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "7201:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 1837, + "nodeType": "VariableDeclarationStatement", + "src": "7201:22:13" + }, + { + "assignments": [ + 1839 + ], + "declarations": [ + { + "constant": false, + "id": 1839, + "mutability": "mutable", + "name": "internalRoot", + "nameLocation": "7233:12:13", + "nodeType": "VariableDeclaration", + "scope": 1891, + "src": "7225:20:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1838, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "7225:7:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "id": 1840, + "nodeType": "VariableDeclarationStatement", + "src": "7225:20:13" + }, + { + "expression": { + "id": 1851, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "components": [ + { + "id": 1841, + "name": "internalWeight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1836, + "src": "7258:14:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 1842, + "name": "internalRoot", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1839, + "src": "7274:12:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 1843, + "isConstant": false, + "isInlineArray": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "TupleExpression", + "src": "7257:30:13", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_bytes32_$", + "typeString": "tuple(uint256,bytes32)" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 1845, + "name": "_subdigest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1467, + "src": "7304:10:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "baseExpression": { + "id": 1846, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1469, + "src": "7316:10:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "endExpression": { + "id": 1848, + "name": "nrindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1830, + "src": "7334:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 1849, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexRangeAccess", + "src": "7316:26:13", + "startExpression": { + "id": 1847, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1477, + "src": "7327:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr_slice", + "typeString": "bytes calldata slice" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes_calldata_ptr_slice", + "typeString": "bytes calldata slice" + } + ], + "id": 1844, + "name": "recoverBranch", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1954, + "src": "7290:13:13", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$_t_bytes_calldata_ptr_$returns$_t_uint256_$_t_bytes32_$", + "typeString": "function (bytes32,bytes calldata) view returns (uint256,bytes32)" + } + }, + "id": 1850, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "7290:53:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_bytes32_$", + "typeString": "tuple(uint256,bytes32)" + } + }, + "src": "7257:86:13", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1852, + "nodeType": "ExpressionStatement", + "src": "7257:86:13" + }, + { + "expression": { + "id": 1855, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 1853, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1477, + "src": "7355:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "id": 1854, + "name": "nrindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1830, + "src": "7364:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7355:16:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 1856, + "nodeType": "ExpressionStatement", + "src": "7355:16:13" + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 1859, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 1857, + "name": "internalWeight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1836, + "src": "7388:14:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">=", + "rightExpression": { + "id": 1858, + "name": "internalThreshold", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1806, + "src": "7406:17:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7388:35:13", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 1865, + "nodeType": "IfStatement", + "src": "7384:92:13", + "trueBody": { + "id": 1864, + "nodeType": "Block", + "src": "7425:51:13", + "statements": [ + { + "expression": { + "id": 1862, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 1860, + "name": "weight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1472, + "src": "7439:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "+=", + "rightHandSide": { + "id": 1861, + "name": "externalWeight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1794, + "src": "7449:14:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7439:24:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 1863, + "nodeType": "ExpressionStatement", + "src": "7439:24:13" + } + ] + } + }, + { + "assignments": [ + 1867 + ], + "declarations": [ + { + "constant": false, + "id": 1867, + "mutability": "mutable", + "name": "node", + "nameLocation": "7496:4:13", + "nodeType": "VariableDeclaration", + "scope": 1891, + "src": "7488:12:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1866, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "7488:7:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "id": 1873, + "initialValue": { + "arguments": [ + { + "id": 1869, + "name": "internalRoot", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1839, + "src": "7518:12:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 1870, + "name": "internalThreshold", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1806, + "src": "7532:17:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 1871, + "name": "externalWeight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1794, + "src": "7551:14:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 1868, + "name": "_leafForNested", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1464, + "src": "7503:14:13", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes32_$_t_uint256_$_t_uint256_$returns$_t_bytes32_$", + "typeString": "function (bytes32,uint256,uint256) pure returns (bytes32)" + } + }, + "id": 1872, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "7503:63:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "7488:78:13" + }, + { + "expression": { + "id": 1888, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 1874, + "name": "root", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1474, + "src": "7578:4:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "condition": { + "commonType": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 1880, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 1875, + "name": "root", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1474, + "src": "7585:4:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "arguments": [ + { + "hexValue": "30", + "id": 1878, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "7601:1:13", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 1877, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "7593:7:13", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes32_$", + "typeString": "type(bytes32)" + }, + "typeName": { + "id": 1876, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "7593:7:13", + "typeDescriptions": {} + } + }, + "id": 1879, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "7593:10:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "7585:18:13", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": { + "id": 1886, + "name": "node", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1867, + "src": "7640:4:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 1887, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "7585:59:13", + "trueExpression": { + "arguments": [ + { + "id": 1883, + "name": "root", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1474, + "src": "7626:4:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 1884, + "name": "node", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1867, + "src": "7632:4:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "expression": { + "id": 1881, + "name": "LibOptim", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2530, + "src": "7606:8:13", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_LibOptim_$2530_$", + "typeString": "type(library LibOptim)" + } + }, + "id": 1882, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "7615:10:13", + "memberName": "fkeccak256", + "nodeType": "MemberAccess", + "referencedDeclaration": 2491, + "src": "7606:19:13", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes32_$_t_bytes32_$returns$_t_bytes32_$", + "typeString": "function (bytes32,bytes32) pure returns (bytes32)" + } + }, + "id": 1885, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "7606:31:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "7578:66:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 1889, + "nodeType": "ExpressionStatement", + "src": "7578:66:13" + }, + { + "id": 1890, + "nodeType": "Continue", + "src": "7657:8:13" + } + ] + } + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 1895, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 1893, + "name": "flag", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1484, + "src": "7690:4:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "id": 1894, + "name": "FLAG_SUBDIGEST", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1356, + "src": "7698:14:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7690:22:13", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 1945, + "nodeType": "IfStatement", + "src": "7686:485:13", + "trueBody": { + "id": 1944, + "nodeType": "Block", + "src": "7714:457:13", + "statements": [ + { + "assignments": [ + 1897 + ], + "declarations": [ + { + "constant": false, + "id": 1897, + "mutability": "mutable", + "name": "hardcoded", + "nameLocation": "7831:9:13", + "nodeType": "VariableDeclaration", + "scope": 1944, + "src": "7823:17:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1896, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "7823:7:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "id": 1898, + "nodeType": "VariableDeclarationStatement", + "src": "7823:17:13" + }, + { + "expression": { + "id": 1906, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "components": [ + { + "id": 1899, + "name": "hardcoded", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1897, + "src": "7853:9:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 1900, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1477, + "src": "7864:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 1901, + "isConstant": false, + "isInlineArray": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "TupleExpression", + "src": "7852:19:13", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_bytes32_$_t_uint256_$", + "typeString": "tuple(bytes32,uint256)" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 1904, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1477, + "src": "7897:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "id": 1902, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1469, + "src": "7874:10:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "id": 1903, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "7885:11:13", + "memberName": "readBytes32", + "nodeType": "MemberAccess", + "referencedDeclaration": 2475, + "src": "7874:22:13", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes_calldata_ptr_$_t_uint256_$returns$_t_bytes32_$_t_uint256_$attached_to$_t_bytes_calldata_ptr_$", + "typeString": "function (bytes calldata,uint256) pure returns (bytes32,uint256)" + } + }, + "id": 1905, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "7874:30:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_bytes32_$_t_uint256_$", + "typeString": "tuple(bytes32,uint256)" + } + }, + "src": "7852:52:13", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1907, + "nodeType": "ExpressionStatement", + "src": "7852:52:13" + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 1910, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 1908, + "name": "hardcoded", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1897, + "src": "7920:9:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "id": 1909, + "name": "_subdigest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1467, + "src": "7933:10:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "7920:23:13", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 1920, + "nodeType": "IfStatement", + "src": "7916:82:13", + "trueBody": { + "id": 1919, + "nodeType": "Block", + "src": "7945:53:13", + "statements": [ + { + "expression": { + "id": 1917, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 1911, + "name": "weight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1472, + "src": "7959:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "expression": { + "arguments": [ + { + "id": 1914, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "7973:7:13", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint256_$", + "typeString": "type(uint256)" + }, + "typeName": { + "id": 1913, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "7973:7:13", + "typeDescriptions": {} + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_type$_t_uint256_$", + "typeString": "type(uint256)" + } + ], + "id": 1912, + "name": "type", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967269, + "src": "7968:4:13", + "typeDescriptions": { + "typeIdentifier": "t_function_metatype_pure$__$returns$__$", + "typeString": "function () pure" + } + }, + "id": 1915, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "7968:13:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_magic_meta_type_t_uint256", + "typeString": "type(uint256)" + } + }, + "id": 1916, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "7982:3:13", + "memberName": "max", + "nodeType": "MemberAccess", + "src": "7968:17:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "7959:26:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 1918, + "nodeType": "ExpressionStatement", + "src": "7959:26:13" + } + ] + } + }, + { + "assignments": [ + 1922 + ], + "declarations": [ + { + "constant": false, + "id": 1922, + "mutability": "mutable", + "name": "node", + "nameLocation": "8018:4:13", + "nodeType": "VariableDeclaration", + "scope": 1944, + "src": "8010:12:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1921, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "8010:7:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "id": 1926, + "initialValue": { + "arguments": [ + { + "id": 1924, + "name": "hardcoded", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1897, + "src": "8052:9:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 1923, + "name": "_leafForHardcodedSubdigest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1441, + "src": "8025:26:13", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes32_$returns$_t_bytes32_$", + "typeString": "function (bytes32) pure returns (bytes32)" + } + }, + "id": 1925, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "8025:37:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "8010:52:13" + }, + { + "expression": { + "id": 1941, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 1927, + "name": "root", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1474, + "src": "8074:4:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "condition": { + "commonType": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 1933, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 1928, + "name": "root", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1474, + "src": "8081:4:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "arguments": [ + { + "hexValue": "30", + "id": 1931, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "8097:1:13", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 1930, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "8089:7:13", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes32_$", + "typeString": "type(bytes32)" + }, + "typeName": { + "id": 1929, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "8089:7:13", + "typeDescriptions": {} + } + }, + "id": 1932, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "8089:10:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "8081:18:13", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseExpression": { + "id": 1939, + "name": "node", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1922, + "src": "8136:4:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 1940, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "Conditional", + "src": "8081:59:13", + "trueExpression": { + "arguments": [ + { + "id": 1936, + "name": "root", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1474, + "src": "8122:4:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 1937, + "name": "node", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1922, + "src": "8128:4:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "expression": { + "id": 1934, + "name": "LibOptim", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2530, + "src": "8102:8:13", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_LibOptim_$2530_$", + "typeString": "type(library LibOptim)" + } + }, + "id": 1935, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "8111:10:13", + "memberName": "fkeccak256", + "nodeType": "MemberAccess", + "referencedDeclaration": 2491, + "src": "8102:19:13", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes32_$_t_bytes32_$returns$_t_bytes32_$", + "typeString": "function (bytes32,bytes32) pure returns (bytes32)" + } + }, + "id": 1938, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "8102:31:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "8074:66:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 1942, + "nodeType": "ExpressionStatement", + "src": "8074:66:13" + }, + { + "id": 1943, + "nodeType": "Continue", + "src": "8152:8:13" + } + ] + } + }, + { + "errorCall": { + "arguments": [ + { + "id": 1947, + "name": "flag", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1484, + "src": "8209:4:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 1946, + "name": "InvalidSignatureFlag", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1371, + "src": "8188:20:13", + "typeDescriptions": { + "typeIdentifier": "t_function_error_pure$_t_uint256_$returns$__$", + "typeString": "function (uint256) pure" + } + }, + "id": 1948, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "8188:26:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1949, + "nodeType": "RevertStatement", + "src": "8181:33:13" + } + ] + }, + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 1482, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 1479, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1477, + "src": "3772:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "expression": { + "id": 1480, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1469, + "src": "3781:10:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "id": 1481, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "3792:6:13", + "memberName": "length", + "nodeType": "MemberAccess", + "src": "3781:17:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "3772:26:13", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 1951, + "nodeType": "WhileStatement", + "src": "3765:4458:13" + } + ] + } + ] + }, + "documentation": { + "id": 1465, + "nodeType": "StructuredDocumentation", + "src": "3059:463:13", + "text": " @notice Returns the weight and root of a signature branch.\n @dev If the signature contains a hardcoded subdigest, and it matches the input digest, then the weight is set to 2 ** 256 - 1.\n @param _subdigest The digest to verify the signature against.\n @param _signature The signature branch to recover.\n @return weight The total weight of the recovered signatures.\n @return root The root hash of the recovered configuration." + }, + "id": 1954, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "recoverBranch", + "nameLocation": "3534:13:13", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 1470, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1467, + "mutability": "mutable", + "name": "_subdigest", + "nameLocation": "3561:10:13", + "nodeType": "VariableDeclaration", + "scope": 1954, + "src": "3553:18:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1466, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "3553:7:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1469, + "mutability": "mutable", + "name": "_signature", + "nameLocation": "3592:10:13", + "nodeType": "VariableDeclaration", + "scope": 1954, + "src": "3577:25:13", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 1468, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "3577:5:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "3547:59:13" + }, + "returnParameters": { + "id": 1475, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1472, + "mutability": "mutable", + "name": "weight", + "nameLocation": "3643:6:13", + "nodeType": "VariableDeclaration", + "scope": 1954, + "src": "3635:14:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1471, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3635:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1474, + "mutability": "mutable", + "name": "root", + "nameLocation": "3663:4:13", + "nodeType": "VariableDeclaration", + "scope": 1954, + "src": "3655:12:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1473, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "3655:7:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "3629:42:13" + }, + "scope": 2021, + "src": "3525:4708:13", + "stateMutability": "view", + "virtual": false, + "visibility": "internal" + }, + { + "body": { + "id": 2019, + "nodeType": "Block", + "src": "9085:449:13", + "statements": [ + { + "id": 2018, + "nodeType": "UncheckedBlock", + "src": "9091:439:13", + "statements": [ + { + "expression": { + "id": 1979, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "components": [ + { + "id": 1970, + "name": "weight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1964, + "src": "9110:6:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 1971, + "name": "imageHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1966, + "src": "9118:9:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "id": 1972, + "isConstant": false, + "isInlineArray": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "TupleExpression", + "src": "9109:19:13", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_bytes32_$", + "typeString": "tuple(uint256,bytes32)" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 1974, + "name": "_subdigest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1957, + "src": "9145:10:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "baseExpression": { + "id": 1975, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1959, + "src": "9157:10:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "id": 1977, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexRangeAccess", + "src": "9157:14:13", + "startExpression": { + "hexValue": "36", + "id": 1976, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "9168:1:13", + "typeDescriptions": { + "typeIdentifier": "t_rational_6_by_1", + "typeString": "int_const 6" + }, + "value": "6" + }, + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr_slice", + "typeString": "bytes calldata slice" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes_calldata_ptr_slice", + "typeString": "bytes calldata slice" + } + ], + "id": 1973, + "name": "recoverBranch", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1954, + "src": "9131:13:13", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$_t_bytes_calldata_ptr_$returns$_t_uint256_$_t_bytes32_$", + "typeString": "function (bytes32,bytes calldata) view returns (uint256,bytes32)" + } + }, + "id": 1978, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "9131:41:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_bytes32_$", + "typeString": "tuple(uint256,bytes32)" + } + }, + "src": "9109:63:13", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 1980, + "nodeType": "ExpressionStatement", + "src": "9109:63:13" + }, + { + "expression": { + "id": 1986, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 1981, + "name": "threshold", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1962, + "src": "9278:9:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 1984, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1959, + "src": "9315:10:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + ], + "expression": { + "id": 1982, + "name": "LibBytes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2374, + "src": "9290:8:13", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_LibBytes_$2374_$", + "typeString": "type(library LibBytes)" + } + }, + "id": 1983, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "9299:15:13", + "memberName": "readFirstUint16", + "nodeType": "MemberAccess", + "referencedDeclaration": 2361, + "src": "9290:24:13", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes_calldata_ptr_$returns$_t_uint16_$", + "typeString": "function (bytes calldata) pure returns (uint16)" + } + }, + "id": 1985, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "9290:36:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint16", + "typeString": "uint16" + } + }, + "src": "9278:48:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 1987, + "nodeType": "ExpressionStatement", + "src": "9278:48:13" + }, + { + "expression": { + "id": 1994, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 1988, + "name": "checkpoint", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1968, + "src": "9334:10:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 1991, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1959, + "src": "9367:10:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + { + "hexValue": "32", + "id": 1992, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "9379:1:13", + "typeDescriptions": { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + }, + { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + } + ], + "expression": { + "id": 1989, + "name": "LibBytes", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2374, + "src": "9347:8:13", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_LibBytes_$2374_$", + "typeString": "type(library LibBytes)" + } + }, + "id": 1990, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "9356:10:13", + "memberName": "readUint32", + "nodeType": "MemberAccess", + "referencedDeclaration": 2373, + "src": "9347:19:13", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes_calldata_ptr_$_t_uint256_$returns$_t_uint32_$", + "typeString": "function (bytes calldata,uint256) pure returns (uint32)" + } + }, + "id": 1993, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "9347:34:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "src": "9334:47:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 1995, + "nodeType": "ExpressionStatement", + "src": "9334:47:13" + }, + { + "expression": { + "id": 2005, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 1996, + "name": "imageHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1966, + "src": "9390:9:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 1999, + "name": "imageHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1966, + "src": "9422:9:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "arguments": [ + { + "id": 2002, + "name": "threshold", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1962, + "src": "9441:9:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 2001, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "9433:7:13", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes32_$", + "typeString": "type(bytes32)" + }, + "typeName": { + "id": 2000, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "9433:7:13", + "typeDescriptions": {} + } + }, + "id": 2003, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "9433:18:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "expression": { + "id": 1997, + "name": "LibOptim", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2530, + "src": "9402:8:13", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_LibOptim_$2530_$", + "typeString": "type(library LibOptim)" + } + }, + "id": 1998, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "9411:10:13", + "memberName": "fkeccak256", + "nodeType": "MemberAccess", + "referencedDeclaration": 2491, + "src": "9402:19:13", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes32_$_t_bytes32_$returns$_t_bytes32_$", + "typeString": "function (bytes32,bytes32) pure returns (bytes32)" + } + }, + "id": 2004, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "9402:50:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "9390:62:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 2006, + "nodeType": "ExpressionStatement", + "src": "9390:62:13" + }, + { + "expression": { + "id": 2016, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 2007, + "name": "imageHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1966, + "src": "9460:9:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 2010, + "name": "imageHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1966, + "src": "9492:9:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "arguments": [ + { + "id": 2013, + "name": "checkpoint", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1968, + "src": "9511:10:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 2012, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "9503:7:13", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes32_$", + "typeString": "type(bytes32)" + }, + "typeName": { + "id": 2011, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "9503:7:13", + "typeDescriptions": {} + } + }, + "id": 2014, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "9503:19:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "expression": { + "id": 2008, + "name": "LibOptim", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2530, + "src": "9472:8:13", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_LibOptim_$2530_$", + "typeString": "type(library LibOptim)" + } + }, + "id": 2009, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "9481:10:13", + "memberName": "fkeccak256", + "nodeType": "MemberAccess", + "referencedDeclaration": 2491, + "src": "9472:19:13", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes32_$_t_bytes32_$returns$_t_bytes32_$", + "typeString": "function (bytes32,bytes32) pure returns (bytes32)" + } + }, + "id": 2015, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "9472:51:13", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "9460:63:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "id": 2017, + "nodeType": "ExpressionStatement", + "src": "9460:63:13" + } + ] + } + ] + }, + "documentation": { + "id": 1955, + "nodeType": "StructuredDocumentation", + "src": "8237:652:13", + "text": " @notice Returns the threshold, weight, root, and checkpoint of a signature.\n @dev To verify the signature, the weight must be greater than or equal to the threshold, and the root\n must match the expected `imageHash` of the wallet.\n @param _subdigest The digest to verify the signature against.\n @param _signature The signature to recover.\n @return threshold The minimum weight required for the signature to be valid.\n @return weight The total weight of the recovered signatures.\n @return imageHash The root hash of the recovered configuration\n @return checkpoint The checkpoint of the signature." + }, + "id": 2020, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "recover", + "nameLocation": "8901:7:13", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 1960, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1957, + "mutability": "mutable", + "name": "_subdigest", + "nameLocation": "8922:10:13", + "nodeType": "VariableDeclaration", + "scope": 2020, + "src": "8914:18:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1956, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "8914:7:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1959, + "mutability": "mutable", + "name": "_signature", + "nameLocation": "8953:10:13", + "nodeType": "VariableDeclaration", + "scope": 2020, + "src": "8938:25:13", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 1958, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "8938:5:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "8908:59:13" + }, + "returnParameters": { + "id": 1969, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 1962, + "mutability": "mutable", + "name": "threshold", + "nameLocation": "9004:9:13", + "nodeType": "VariableDeclaration", + "scope": 2020, + "src": "8996:17:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1961, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "8996:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1964, + "mutability": "mutable", + "name": "weight", + "nameLocation": "9027:6:13", + "nodeType": "VariableDeclaration", + "scope": 2020, + "src": "9019:14:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1963, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "9019:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1966, + "mutability": "mutable", + "name": "imageHash", + "nameLocation": "9047:9:13", + "nodeType": "VariableDeclaration", + "scope": 2020, + "src": "9039:17:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 1965, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "9039:7:13", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 1968, + "mutability": "mutable", + "name": "checkpoint", + "nameLocation": "9070:10:13", + "nodeType": "VariableDeclaration", + "scope": 2020, + "src": "9062:18:13", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 1967, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "9062:7:13", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "8990:94:13" + }, + "scope": 2021, + "src": "8892:642:13", + "stateMutability": "view", + "virtual": false, + "visibility": "internal" + } + ], + "scope": 2022, + "src": "419:9117:13", + "usedErrors": [ + 1367, + 1371 + ] + } + ], + "src": "39:9498:13" + }, + "id": 13 + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol": { + "ast": { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol", + "exportedSymbols": { + "IERC1271Wallet": [ + 22 + ], + "IModuleAuth": [ + 1249 + ], + "LibBytes": [ + 2374 + ], + "LibBytesPointer": [ + 2476 + ], + "LibOptim": [ + 2530 + ], + "ModuleSelfAuth": [ + 1116 + ], + "ModuleStorage": [ + 1179 + ], + "SequenceBaseSig": [ + 2021 + ], + "SequenceChainedSig": [ + 2218 + ], + "SignatureValidator": [ + 2798 + ] + }, + "id": 2219, + "license": "Apache-2.0", + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 2023, + "literals": [ + "solidity", + "0.8", + ".18" + ], + "nodeType": "PragmaDirective", + "src": "39:23:14" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol", + "file": "./SequenceBaseSig.sol", + "id": 2024, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 2219, + "sourceUnit": 2022, + "src": "64:31:14", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/interfaces/IModuleAuth.sol", + "file": "../../interfaces/IModuleAuth.sol", + "id": 2025, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 2219, + "sourceUnit": 1250, + "src": "97:42:14", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleSelfAuth.sol", + "file": "../../ModuleSelfAuth.sol", + "id": 2026, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 2219, + "sourceUnit": 1117, + "src": "141:34:14", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/ModuleStorage.sol", + "file": "../../ModuleStorage.sol", + "id": 2027, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 2219, + "sourceUnit": 1180, + "src": "176:33:14", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol", + "file": "../../../../utils/LibBytesPointer.sol", + "id": 2028, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 2219, + "sourceUnit": 2477, + "src": "211:47:14", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol", + "file": "../../../../utils/LibOptim.sol", + "id": 2029, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 2219, + "sourceUnit": 2531, + "src": "259:40:14", + "symbolAliases": [], + "unitAlias": "" + }, + { + "abstract": true, + "baseContracts": [ + { + "baseName": { + "id": 2031, + "name": "IModuleAuth", + "nameLocations": [ + "743:11:14" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1249, + "src": "743:11:14" + }, + "id": 2032, + "nodeType": "InheritanceSpecifier", + "src": "743:11:14" + }, + { + "baseName": { + "id": 2033, + "name": "ModuleSelfAuth", + "nameLocations": [ + "756:14:14" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 1116, + "src": "756:14:14" + }, + "id": 2034, + "nodeType": "InheritanceSpecifier", + "src": "756:14:14" + } + ], + "canonicalName": "SequenceChainedSig", + "contractDependencies": [], + "contractKind": "contract", + "documentation": { + "id": 2030, + "nodeType": "StructuredDocumentation", + "src": "301:401:14", + "text": " @title Sequence chained auth recovery submodule\n @author Agustin Aguilar (aa@horizon.io)\n @notice Defines Sequence signatures that work by delegating control to new configurations.\n @dev The delegations can be chained together, the first signature is the one that is used to validate\n the message, the last signature must match the current on-chain configuration of the wallet." + }, + "fullyImplemented": false, + "id": 2218, + "linearizedBaseContracts": [ + 2218, + 1116, + 1249 + ], + "name": "SequenceChainedSig", + "nameLocation": "721:18:14", + "nodeType": "ContractDefinition", + "nodes": [ + { + "global": false, + "id": 2037, + "libraryName": { + "id": 2035, + "name": "LibBytesPointer", + "nameLocations": [ + "781:15:14" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 2476, + "src": "781:15:14" + }, + "nodeType": "UsingForDirective", + "src": "775:32:14", + "typeName": { + "id": 2036, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "801:5:14", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + } + }, + { + "constant": true, + "functionSelector": "57c56d6b", + "id": 2042, + "mutability": "constant", + "name": "SET_IMAGE_HASH_TYPE_HASH", + "nameLocation": "835:24:14", + "nodeType": "VariableDeclaration", + "scope": 2218, + "src": "811:95:14", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 2038, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "811:7:14", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": { + "arguments": [ + { + "hexValue": "536574496d61676548617368286279746573333220696d6167654861736829", + "id": 2040, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "872:33:14", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_8713a7c4465f6fbee2b6e9d6646d1d9f83fec929edfc4baf661f3c865bdd04d1", + "typeString": "literal_string \"SetImageHash(bytes32 imageHash)\"" + }, + "value": "SetImageHash(bytes32 imageHash)" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_stringliteral_8713a7c4465f6fbee2b6e9d6646d1d9f83fec929edfc4baf661f3c865bdd04d1", + "typeString": "literal_string \"SetImageHash(bytes32 imageHash)\"" + } + ], + "id": 2039, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967288, + "src": "862:9:14", + "typeDescriptions": { + "typeIdentifier": "t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$", + "typeString": "function (bytes memory) pure returns (bytes32)" + } + }, + "id": 2041, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "862:44:14", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "public" + }, + { + "errorSelector": "b006aba0", + "id": 2050, + "name": "LowWeightChainedSignature", + "nameLocation": "917:25:14", + "nodeType": "ErrorDefinition", + "parameters": { + "id": 2049, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2044, + "mutability": "mutable", + "name": "_signature", + "nameLocation": "949:10:14", + "nodeType": "VariableDeclaration", + "scope": 2050, + "src": "943:16:14", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 2043, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "943:5:14", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2046, + "mutability": "mutable", + "name": "threshold", + "nameLocation": "969:9:14", + "nodeType": "VariableDeclaration", + "scope": 2050, + "src": "961:17:14", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2045, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "961:7:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2048, + "mutability": "mutable", + "name": "_weight", + "nameLocation": "988:7:14", + "nodeType": "VariableDeclaration", + "scope": 2050, + "src": "980:15:14", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2047, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "980:7:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "942:54:14" + }, + "src": "911:86:14" + }, + { + "errorSelector": "37daf62b", + "id": 2056, + "name": "WrongChainedCheckpointOrder", + "nameLocation": "1006:27:14", + "nodeType": "ErrorDefinition", + "parameters": { + "id": 2055, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2052, + "mutability": "mutable", + "name": "_current", + "nameLocation": "1042:8:14", + "nodeType": "VariableDeclaration", + "scope": 2056, + "src": "1034:16:14", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2051, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1034:7:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2054, + "mutability": "mutable", + "name": "_prev", + "nameLocation": "1060:5:14", + "nodeType": "VariableDeclaration", + "scope": 2056, + "src": "1052:13:14", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2053, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1052:7:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "1033:33:14" + }, + "src": "1000:67:14" + }, + { + "body": { + "id": 2070, + "nodeType": "Block", + "src": "1381:75:14", + "statements": [ + { + "expression": { + "arguments": [ + { + "id": 2066, + "name": "SET_IMAGE_HASH_TYPE_HASH", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2042, + "src": "1414:24:14", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 2067, + "name": "_imageHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2059, + "src": "1440:10:14", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "expression": { + "id": 2064, + "name": "LibOptim", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2530, + "src": "1394:8:14", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_LibOptim_$2530_$", + "typeString": "type(library LibOptim)" + } + }, + "id": 2065, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "1403:10:14", + "memberName": "fkeccak256", + "nodeType": "MemberAccess", + "referencedDeclaration": 2491, + "src": "1394:19:14", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes32_$_t_bytes32_$returns$_t_bytes32_$", + "typeString": "function (bytes32,bytes32) pure returns (bytes32)" + } + }, + "id": 2068, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1394:57:14", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "functionReturnParameters": 2063, + "id": 2069, + "nodeType": "Return", + "src": "1387:64:14" + } + ] + }, + "documentation": { + "id": 2057, + "nodeType": "StructuredDocumentation", + "src": "1071:222:14", + "text": " @notice Defined the special token that must be signed to delegate control to a new configuration.\n @param _imageHash The hash of the new configuration.\n @return bytes32 The message hash to be signed." + }, + "id": 2071, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "_hashSetImageHashStruct", + "nameLocation": "1305:23:14", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 2060, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2059, + "mutability": "mutable", + "name": "_imageHash", + "nameLocation": "1337:10:14", + "nodeType": "VariableDeclaration", + "scope": 2071, + "src": "1329:18:14", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 2058, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1329:7:14", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "1328:20:14" + }, + "returnParameters": { + "id": 2063, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2062, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2071, + "src": "1372:7:14", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 2061, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1372:7:14", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "1371:9:14" + }, + "scope": 2218, + "src": "1296:160:14", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": { + "id": 2216, + "nodeType": "Block", + "src": "2540:1839:14", + "statements": [ + { + "assignments": [ + 2090 + ], + "declarations": [ + { + "constant": false, + "id": 2090, + "mutability": "mutable", + "name": "rindex", + "nameLocation": "2554:6:14", + "nodeType": "VariableDeclaration", + "scope": 2216, + "src": "2546:14:14", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2089, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2546:7:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 2092, + "initialValue": { + "hexValue": "31", + "id": 2091, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "2563:1:14", + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "nodeType": "VariableDeclarationStatement", + "src": "2546:18:14" + }, + { + "assignments": [ + 2094 + ], + "declarations": [ + { + "constant": false, + "id": 2094, + "mutability": "mutable", + "name": "sigSize", + "nameLocation": "2578:7:14", + "nodeType": "VariableDeclaration", + "scope": 2216, + "src": "2570:15:14", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2093, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2570:7:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 2095, + "nodeType": "VariableDeclarationStatement", + "src": "2570:15:14" + }, + { + "expression": { + "id": 2103, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "components": [ + { + "id": 2096, + "name": "sigSize", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2094, + "src": "2696:7:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 2097, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2090, + "src": "2705:6:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 2098, + "isConstant": false, + "isInlineArray": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "TupleExpression", + "src": "2695:17:14", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_uint256_$", + "typeString": "tuple(uint256,uint256)" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 2101, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2090, + "src": "2737:6:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "id": 2099, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2076, + "src": "2715:10:14", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "id": 2100, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2726:10:14", + "memberName": "readUint24", + "nodeType": "MemberAccess", + "referencedDeclaration": 2447, + "src": "2715:21:14", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes_calldata_ptr_$_t_uint256_$returns$_t_uint24_$_t_uint256_$attached_to$_t_bytes_calldata_ptr_$", + "typeString": "function (bytes calldata,uint256) pure returns (uint24,uint256)" + } + }, + "id": 2102, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2715:29:14", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint24_$_t_uint256_$", + "typeString": "tuple(uint24,uint256)" + } + }, + "src": "2695:49:14", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2104, + "nodeType": "ExpressionStatement", + "src": "2695:49:14" + }, + { + "assignments": [ + 2106 + ], + "declarations": [ + { + "constant": false, + "id": 2106, + "mutability": "mutable", + "name": "nrindex", + "nameLocation": "2758:7:14", + "nodeType": "VariableDeclaration", + "scope": 2216, + "src": "2750:15:14", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2105, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2750:7:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 2110, + "initialValue": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2109, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 2107, + "name": "sigSize", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2094, + "src": "2768:7:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": { + "id": 2108, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2090, + "src": "2778:6:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "2768:16:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "2750:34:14" + }, + { + "expression": { + "id": 2124, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "components": [ + { + "id": 2111, + "name": "threshold", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2079, + "src": "2799:9:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 2112, + "name": "weight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2081, + "src": "2816:6:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 2113, + "name": "imageHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2083, + "src": "2830:9:14", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 2114, + "name": "subdigest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2085, + "src": "2847:9:14", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 2115, + "name": "checkpoint", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2087, + "src": "2864:10:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 2116, + "isConstant": false, + "isInlineArray": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "TupleExpression", + "src": "2791:89:14", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_uint256_$_t_bytes32_$_t_bytes32_$_t_uint256_$", + "typeString": "tuple(uint256,uint256,bytes32,bytes32,uint256)" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 2118, + "name": "_digest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2074, + "src": "2908:7:14", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "baseExpression": { + "id": 2119, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2076, + "src": "2923:10:14", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "endExpression": { + "id": 2121, + "name": "nrindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2106, + "src": "2941:7:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2122, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexRangeAccess", + "src": "2923:26:14", + "startExpression": { + "id": 2120, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2090, + "src": "2934:6:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr_slice", + "typeString": "bytes calldata slice" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes_calldata_ptr_slice", + "typeString": "bytes calldata slice" + } + ], + "id": 2117, + "name": "signatureRecovery", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1225, + "src": "2883:17:14", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$_t_bytes_calldata_ptr_$returns$_t_uint256_$_t_uint256_$_t_bytes32_$_t_bytes32_$_t_uint256_$", + "typeString": "function (bytes32,bytes calldata) view returns (uint256,uint256,bytes32,bytes32,uint256)" + } + }, + "id": 2123, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2883:72:14", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_uint256_$_t_bytes32_$_t_bytes32_$_t_uint256_$", + "typeString": "tuple(uint256,uint256,bytes32,bytes32,uint256)" + } + }, + "src": "2791:164:14", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2125, + "nodeType": "ExpressionStatement", + "src": "2791:164:14" + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2128, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 2126, + "name": "weight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2081, + "src": "2966:6:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "id": 2127, + "name": "threshold", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2079, + "src": "2975:9:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "2966:18:14", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 2139, + "nodeType": "IfStatement", + "src": "2962:118:14", + "trueBody": { + "id": 2138, + "nodeType": "Block", + "src": "2986:94:14", + "statements": [ + { + "errorCall": { + "arguments": [ + { + "baseExpression": { + "id": 2130, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2076, + "src": "3027:10:14", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "endExpression": { + "id": 2132, + "name": "nrindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2106, + "src": "3045:7:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2133, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexRangeAccess", + "src": "3027:26:14", + "startExpression": { + "id": 2131, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2090, + "src": "3038:6:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr_slice", + "typeString": "bytes calldata slice" + } + }, + { + "id": 2134, + "name": "threshold", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2079, + "src": "3055:9:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 2135, + "name": "weight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2081, + "src": "3066:6:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_calldata_ptr_slice", + "typeString": "bytes calldata slice" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 2129, + "name": "LowWeightChainedSignature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2050, + "src": "3001:25:14", + "typeDescriptions": { + "typeIdentifier": "t_function_error_pure$_t_bytes_memory_ptr_$_t_uint256_$_t_uint256_$returns$__$", + "typeString": "function (bytes memory,uint256,uint256) pure" + } + }, + "id": 2136, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3001:72:14", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2137, + "nodeType": "RevertStatement", + "src": "2994:79:14" + } + ] + } + }, + { + "expression": { + "id": 2142, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 2140, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2090, + "src": "3086:6:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "id": 2141, + "name": "nrindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2106, + "src": "3095:7:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "3086:16:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2143, + "nodeType": "ExpressionStatement", + "src": "3086:16:14" + }, + { + "body": { + "id": 2214, + "nodeType": "Block", + "src": "3318:1057:14", + "statements": [ + { + "expression": { + "id": 2155, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "components": [ + { + "id": 2148, + "name": "sigSize", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2094, + "src": "3378:7:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 2149, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2090, + "src": "3387:6:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 2150, + "isConstant": false, + "isInlineArray": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "TupleExpression", + "src": "3377:17:14", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_uint256_$", + "typeString": "tuple(uint256,uint256)" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 2153, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2090, + "src": "3419:6:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "id": 2151, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2076, + "src": "3397:10:14", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "id": 2152, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "3408:10:14", + "memberName": "readUint24", + "nodeType": "MemberAccess", + "referencedDeclaration": 2447, + "src": "3397:21:14", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes_calldata_ptr_$_t_uint256_$returns$_t_uint24_$_t_uint256_$attached_to$_t_bytes_calldata_ptr_$", + "typeString": "function (bytes calldata,uint256) pure returns (uint24,uint256)" + } + }, + "id": 2154, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3397:29:14", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint24_$_t_uint256_$", + "typeString": "tuple(uint24,uint256)" + } + }, + "src": "3377:49:14", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2156, + "nodeType": "ExpressionStatement", + "src": "3377:49:14" + }, + { + "expression": { + "id": 2161, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 2157, + "name": "nrindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2106, + "src": "3434:7:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2160, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 2158, + "name": "sigSize", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2094, + "src": "3444:7:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": { + "id": 2159, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2090, + "src": "3454:6:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "3444:16:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "3434:26:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2162, + "nodeType": "ExpressionStatement", + "src": "3434:26:14" + }, + { + "assignments": [ + 2164 + ], + "declarations": [ + { + "constant": false, + "id": 2164, + "mutability": "mutable", + "name": "nextCheckpoint", + "nameLocation": "3477:14:14", + "nodeType": "VariableDeclaration", + "scope": 2214, + "src": "3469:22:14", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2163, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3469:7:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 2165, + "nodeType": "VariableDeclarationStatement", + "src": "3469:22:14" + }, + { + "expression": { + "id": 2180, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "components": [ + { + "id": 2166, + "name": "threshold", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2079, + "src": "3510:9:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 2167, + "name": "weight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2081, + "src": "3529:6:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 2168, + "name": "imageHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2083, + "src": "3545:9:14", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + null, + { + "id": 2169, + "name": "nextCheckpoint", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2164, + "src": "3662:14:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "id": 2170, + "isConstant": false, + "isInlineArray": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "TupleExpression", + "src": "3500:184:14", + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_uint256_$_t_bytes32_$__$_t_uint256_$", + "typeString": "tuple(uint256,uint256,bytes32,,uint256)" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "arguments": [ + { + "id": 2173, + "name": "imageHash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2083, + "src": "3738:9:14", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 2172, + "name": "_hashSetImageHashStruct", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2071, + "src": "3714:23:14", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes32_$returns$_t_bytes32_$", + "typeString": "function (bytes32) pure returns (bytes32)" + } + }, + "id": 2174, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3714:34:14", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "baseExpression": { + "id": 2175, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2076, + "src": "3758:10:14", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "endExpression": { + "id": 2177, + "name": "nrindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2106, + "src": "3776:7:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2178, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexRangeAccess", + "src": "3758:26:14", + "startExpression": { + "id": 2176, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2090, + "src": "3769:6:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr_slice", + "typeString": "bytes calldata slice" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes_calldata_ptr_slice", + "typeString": "bytes calldata slice" + } + ], + "id": 2171, + "name": "signatureRecovery", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 1225, + "src": "3687:17:14", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$_t_bytes_calldata_ptr_$returns$_t_uint256_$_t_uint256_$_t_bytes32_$_t_bytes32_$_t_uint256_$", + "typeString": "function (bytes32,bytes calldata) view returns (uint256,uint256,bytes32,bytes32,uint256)" + } + }, + "id": 2179, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3687:105:14", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_uint256_$_t_bytes32_$_t_bytes32_$_t_uint256_$", + "typeString": "tuple(uint256,uint256,bytes32,bytes32,uint256)" + } + }, + "src": "3500:292:14", + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2181, + "nodeType": "ExpressionStatement", + "src": "3500:292:14" + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2184, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 2182, + "name": "weight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2081, + "src": "3833:6:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "id": 2183, + "name": "threshold", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2079, + "src": "3842:9:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "3833:18:14", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 2195, + "nodeType": "IfStatement", + "src": "3829:122:14", + "trueBody": { + "id": 2194, + "nodeType": "Block", + "src": "3853:98:14", + "statements": [ + { + "errorCall": { + "arguments": [ + { + "baseExpression": { + "id": 2186, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2076, + "src": "3896:10:14", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "endExpression": { + "id": 2188, + "name": "nrindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2106, + "src": "3914:7:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2189, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexRangeAccess", + "src": "3896:26:14", + "startExpression": { + "id": 2187, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2090, + "src": "3907:6:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr_slice", + "typeString": "bytes calldata slice" + } + }, + { + "id": 2190, + "name": "threshold", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2079, + "src": "3924:9:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 2191, + "name": "weight", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2081, + "src": "3935:6:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_calldata_ptr_slice", + "typeString": "bytes calldata slice" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 2185, + "name": "LowWeightChainedSignature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2050, + "src": "3870:25:14", + "typeDescriptions": { + "typeIdentifier": "t_function_error_pure$_t_bytes_memory_ptr_$_t_uint256_$_t_uint256_$returns$__$", + "typeString": "function (bytes memory,uint256,uint256) pure" + } + }, + "id": 2192, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3870:72:14", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2193, + "nodeType": "RevertStatement", + "src": "3863:79:14" + } + ] + } + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2198, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 2196, + "name": "nextCheckpoint", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2164, + "src": "4198:14:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">=", + "rightExpression": { + "id": 2197, + "name": "checkpoint", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2087, + "src": "4216:10:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "4198:28:14", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 2205, + "nodeType": "IfStatement", + "src": "4194:115:14", + "trueBody": { + "id": 2204, + "nodeType": "Block", + "src": "4228:81:14", + "statements": [ + { + "errorCall": { + "arguments": [ + { + "id": 2200, + "name": "nextCheckpoint", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2164, + "src": "4273:14:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "id": 2201, + "name": "checkpoint", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2087, + "src": "4289:10:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 2199, + "name": "WrongChainedCheckpointOrder", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2056, + "src": "4245:27:14", + "typeDescriptions": { + "typeIdentifier": "t_function_error_pure$_t_uint256_$_t_uint256_$returns$__$", + "typeString": "function (uint256,uint256) pure" + } + }, + "id": 2202, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "4245:55:14", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2203, + "nodeType": "RevertStatement", + "src": "4238:62:14" + } + ] + } + }, + { + "expression": { + "id": 2208, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 2206, + "name": "checkpoint", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2087, + "src": "4317:10:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "id": 2207, + "name": "nextCheckpoint", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2164, + "src": "4330:14:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "4317:27:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2209, + "nodeType": "ExpressionStatement", + "src": "4317:27:14" + }, + { + "expression": { + "id": 2212, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 2210, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2090, + "src": "4352:6:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "id": 2211, + "name": "nrindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2106, + "src": "4361:7:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "4352:16:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2213, + "nodeType": "ExpressionStatement", + "src": "4352:16:14" + } + ] + }, + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2147, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 2144, + "name": "rindex", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2090, + "src": "3290:6:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "<", + "rightExpression": { + "expression": { + "id": 2145, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2076, + "src": "3299:10:14", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "id": 2146, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "3310:6:14", + "memberName": "length", + "nodeType": "MemberAccess", + "src": "3299:17:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "3290:26:14", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 2215, + "nodeType": "WhileStatement", + "src": "3283:1092:14" + } + ] + }, + "documentation": { + "id": 2072, + "nodeType": "StructuredDocumentation", + "src": "1460:857:14", + "text": " @notice Returns the threshold, weight, root, and checkpoint of a (chained) signature.\n \n @dev This method return the `threshold`, `weight` and `imageHash` of the last signature in the chain.\n Intermediate signatures are validated directly in this method. The `subdigest` is the one of the\n first signature in the chain (since that's the one that is used to validate the message).\n @param _digest The digest to recover the signature from.\n @param _signature The signature to recover.\n @return threshold The threshold of the (last) signature.\n @return weight The weight of the (last) signature.\n @return imageHash The image hash of the (last) signature.\n @return subdigest The subdigest of the (first) signature in the chain.\n @return checkpoint The checkpoint of the (last) signature." + }, + "id": 2217, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "chainedRecover", + "nameLocation": "2329:14:14", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 2077, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2074, + "mutability": "mutable", + "name": "_digest", + "nameLocation": "2357:7:14", + "nodeType": "VariableDeclaration", + "scope": 2217, + "src": "2349:15:14", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 2073, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2349:7:14", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2076, + "mutability": "mutable", + "name": "_signature", + "nameLocation": "2385:10:14", + "nodeType": "VariableDeclaration", + "scope": 2217, + "src": "2370:25:14", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 2075, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "2370:5:14", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "2343:56:14" + }, + "returnParameters": { + "id": 2088, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2079, + "mutability": "mutable", + "name": "threshold", + "nameLocation": "2436:9:14", + "nodeType": "VariableDeclaration", + "scope": 2217, + "src": "2428:17:14", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2078, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2428:7:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2081, + "mutability": "mutable", + "name": "weight", + "nameLocation": "2459:6:14", + "nodeType": "VariableDeclaration", + "scope": 2217, + "src": "2451:14:14", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2080, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2451:7:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2083, + "mutability": "mutable", + "name": "imageHash", + "nameLocation": "2479:9:14", + "nodeType": "VariableDeclaration", + "scope": 2217, + "src": "2471:17:14", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 2082, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2471:7:14", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2085, + "mutability": "mutable", + "name": "subdigest", + "nameLocation": "2502:9:14", + "nodeType": "VariableDeclaration", + "scope": 2217, + "src": "2494:17:14", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 2084, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2494:7:14", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2087, + "mutability": "mutable", + "name": "checkpoint", + "nameLocation": "2525:10:14", + "nodeType": "VariableDeclaration", + "scope": 2217, + "src": "2517:18:14", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2086, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2517:7:14", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "2422:117:14" + }, + "scope": 2218, + "src": "2320:2059:14", + "stateMutability": "view", + "virtual": false, + "visibility": "internal" + } + ], + "scope": 2219, + "src": "703:3678:14", + "usedErrors": [ + 1093, + 1193, + 1197, + 2050, + 2056 + ] + } + ], + "src": "39:4343:14" + }, + "id": 14 + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol": { + "ast": { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol", + "exportedSymbols": { + "IERC1271Wallet": [ + 22 + ], + "LibBytes": [ + 2374 + ], + "LibBytesPointer": [ + 2476 + ], + "LibOptim": [ + 2530 + ], + "SequenceBaseSig": [ + 2021 + ], + "SequenceDynamicSig": [ + 2247 + ], + "SignatureValidator": [ + 2798 + ] + }, + "id": 2248, + "license": "Apache-2.0", + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 2220, + "literals": [ + "solidity", + "0.8", + ".18" + ], + "nodeType": "PragmaDirective", + "src": "39:23:15" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol", + "file": "./SequenceBaseSig.sol", + "id": 2221, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 2248, + "sourceUnit": 2022, + "src": "64:31:15", + "symbolAliases": [], + "unitAlias": "" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "SequenceDynamicSig", + "contractDependencies": [], + "contractKind": "library", + "fullyImplemented": true, + "id": 2247, + "linearizedBaseContracts": [ + 2247 + ], + "name": "SequenceDynamicSig", + "nameLocation": "106:18:15", + "nodeType": "ContractDefinition", + "nodes": [ + { + "body": { + "id": 2245, + "nodeType": "Block", + "src": "841:69:15", + "statements": [ + { + "expression": { + "arguments": [ + { + "id": 2239, + "name": "_subdigest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2224, + "src": "878:10:15", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "baseExpression": { + "id": 2240, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2226, + "src": "890:10:15", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "id": 2242, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexRangeAccess", + "src": "890:14:15", + "startExpression": { + "hexValue": "31", + "id": 2241, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "901:1:15", + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr_slice", + "typeString": "bytes calldata slice" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes_calldata_ptr_slice", + "typeString": "bytes calldata slice" + } + ], + "expression": { + "id": 2237, + "name": "SequenceBaseSig", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2021, + "src": "854:15:15", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_SequenceBaseSig_$2021_$", + "typeString": "type(library SequenceBaseSig)" + } + }, + "id": 2238, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "870:7:15", + "memberName": "recover", + "nodeType": "MemberAccess", + "referencedDeclaration": 2020, + "src": "854:23:15", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_view$_t_bytes32_$_t_bytes_calldata_ptr_$returns$_t_uint256_$_t_uint256_$_t_bytes32_$_t_uint256_$", + "typeString": "function (bytes32,bytes calldata) view returns (uint256,uint256,bytes32,uint256)" + } + }, + "id": 2243, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "854:51:15", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$_t_uint256_$_t_uint256_$_t_bytes32_$_t_uint256_$", + "typeString": "tuple(uint256,uint256,bytes32,uint256)" + } + }, + "functionReturnParameters": 2236, + "id": 2244, + "nodeType": "Return", + "src": "847:58:15" + } + ] + }, + "documentation": { + "id": 2222, + "nodeType": "StructuredDocumentation", + "src": "130:515:15", + "text": " @notice Recover a \"dynamically encoded\" Sequence signature.\n @dev The Signature is stripped of the first byte, which is the encoding flag.\n @param _subdigest The digest of the signature.\n @param _signature The Sequence signature.\n @return threshold The threshold weight required to validate the signature.\n @return weight The weight of the signature.\n @return imageHash The hash of the recovered configuration.\n @return checkpoint The checkpoint of the configuration." + }, + "id": 2246, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "recover", + "nameLocation": "657:7:15", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 2227, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2224, + "mutability": "mutable", + "name": "_subdigest", + "nameLocation": "678:10:15", + "nodeType": "VariableDeclaration", + "scope": 2246, + "src": "670:18:15", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 2223, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "670:7:15", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2226, + "mutability": "mutable", + "name": "_signature", + "nameLocation": "709:10:15", + "nodeType": "VariableDeclaration", + "scope": 2246, + "src": "694:25:15", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 2225, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "694:5:15", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "664:59:15" + }, + "returnParameters": { + "id": 2236, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2229, + "mutability": "mutable", + "name": "threshold", + "nameLocation": "760:9:15", + "nodeType": "VariableDeclaration", + "scope": 2246, + "src": "752:17:15", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2228, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "752:7:15", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2231, + "mutability": "mutable", + "name": "weight", + "nameLocation": "783:6:15", + "nodeType": "VariableDeclaration", + "scope": 2246, + "src": "775:14:15", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2230, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "775:7:15", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2233, + "mutability": "mutable", + "name": "imageHash", + "nameLocation": "803:9:15", + "nodeType": "VariableDeclaration", + "scope": 2246, + "src": "795:17:15", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 2232, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "795:7:15", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2235, + "mutability": "mutable", + "name": "checkpoint", + "nameLocation": "826:10:15", + "nodeType": "VariableDeclaration", + "scope": 2246, + "src": "818:18:15", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2234, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "818:7:15", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "746:94:15" + }, + "scope": 2247, + "src": "648:262:15", + "stateMutability": "view", + "virtual": false, + "visibility": "internal" + } + ], + "scope": 2248, + "src": "98:814:15", + "usedErrors": [] + } + ], + "src": "39:874:15" + }, + "id": 15 + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol": { + "ast": { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol", + "exportedSymbols": { + "SequenceNoChainIdSig": [ + 2275 + ] + }, + "id": 2276, + "license": "Apache-2.0", + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 2249, + "literals": [ + "solidity", + "0.8", + ".18" + ], + "nodeType": "PragmaDirective", + "src": "39:23:16" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "SequenceNoChainIdSig", + "contractDependencies": [], + "contractKind": "library", + "fullyImplemented": true, + "id": 2275, + "linearizedBaseContracts": [ + 2275 + ], + "name": "SequenceNoChainIdSig", + "nameLocation": "73:20:16", + "nodeType": "ContractDefinition", + "nodes": [ + { + "body": { + "id": 2273, + "nodeType": "Block", + "src": "472:145:16", + "statements": [ + { + "expression": { + "arguments": [ + { + "arguments": [ + { + "hexValue": "1901", + "id": 2260, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "528:10:16", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_301a50b291d33ce1e8e9064e3f6a6c51d902ec22892b50d58abf6357c6a45541", + "typeString": "literal_string hex\"1901\"" + }, + "value": "\u0019\u0001" + }, + { + "arguments": [ + { + "hexValue": "30", + "id": 2263, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "556:1:16", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 2262, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "548:7:16", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint256_$", + "typeString": "type(uint256)" + }, + "typeName": { + "id": 2261, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "548:7:16", + "typeDescriptions": {} + } + }, + "id": 2264, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "548:10:16", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "arguments": [ + { + "id": 2267, + "name": "this", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967268, + "src": "576:4:16", + "typeDescriptions": { + "typeIdentifier": "t_contract$_SequenceNoChainIdSig_$2275", + "typeString": "library SequenceNoChainIdSig" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_contract$_SequenceNoChainIdSig_$2275", + "typeString": "library SequenceNoChainIdSig" + } + ], + "id": 2266, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "568:7:16", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": { + "id": 2265, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "568:7:16", + "typeDescriptions": {} + } + }, + "id": 2268, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "568:13:16", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + { + "id": 2269, + "name": "_digest", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2252, + "src": "591:7:16", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_stringliteral_301a50b291d33ce1e8e9064e3f6a6c51d902ec22892b50d58abf6357c6a45541", + "typeString": "literal_string hex\"1901\"" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "expression": { + "id": 2258, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967295, + "src": "502:3:16", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 2259, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "506:12:16", + "memberName": "encodePacked", + "nodeType": "MemberAccess", + "src": "502:16:16", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencodepacked_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 2270, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "502:104:16", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 2257, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967288, + "src": "485:9:16", + "typeDescriptions": { + "typeIdentifier": "t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$", + "typeString": "function (bytes memory) pure returns (bytes32)" + } + }, + "id": 2271, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "485:127:16", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "functionReturnParameters": 2256, + "id": 2272, + "nodeType": "Return", + "src": "478:134:16" + } + ] + }, + "documentation": { + "id": 2250, + "nodeType": "StructuredDocumentation", + "src": "99:302:16", + "text": " @notice Computes a subdigest for a Sequence signature that works on all chains.\n @dev The subdigest is computed by removing the chain ID from the digest (using 0 instead).\n @param _digest The digest of the chain of signatures.\n @return bytes32 The subdigest with no chain ID." + }, + "id": 2274, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "subdigest", + "nameLocation": "413:9:16", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 2253, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2252, + "mutability": "mutable", + "name": "_digest", + "nameLocation": "431:7:16", + "nodeType": "VariableDeclaration", + "scope": 2274, + "src": "423:15:16", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 2251, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "423:7:16", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "422:17:16" + }, + "returnParameters": { + "id": 2256, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2255, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 2274, + "src": "463:7:16", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 2254, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "463:7:16", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "462:9:16" + }, + "scope": 2275, + "src": "404:213:16", + "stateMutability": "view", + "virtual": false, + "visibility": "internal" + } + ], + "scope": 2276, + "src": "65:554:16", + "usedErrors": [] + } + ], + "src": "39:581:16" + }, + "id": 16 + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol": { + "ast": { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol", + "exportedSymbols": { + "SubModuleNonce": [ + 2324 + ] + }, + "id": 2325, + "license": "Apache-2.0", + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 2277, + "literals": [ + "solidity", + "0.8", + ".18" + ], + "nodeType": "PragmaDirective", + "src": "39:23:17" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "SubModuleNonce", + "contractDependencies": [], + "contractKind": "library", + "fullyImplemented": true, + "id": 2324, + "linearizedBaseContracts": [ + 2324 + ], + "name": "SubModuleNonce", + "nameLocation": "73:14:17", + "nodeType": "ContractDefinition", + "nodes": [ + { + "constant": true, + "id": 2280, + "mutability": "constant", + "name": "NONCE_BITS", + "nameLocation": "174:10:17", + "nodeType": "VariableDeclaration", + "scope": 2324, + "src": "148:41:17", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2278, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "148:7:17", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": { + "hexValue": "3936", + "id": 2279, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "187:2:17", + "typeDescriptions": { + "typeIdentifier": "t_rational_96_by_1", + "typeString": "int_const 96" + }, + "value": "96" + }, + "visibility": "internal" + }, + { + "constant": true, + "id": 2293, + "mutability": "constant", + "name": "NONCE_MASK", + "nameLocation": "219:10:17", + "nodeType": "VariableDeclaration", + "scope": 2324, + "src": "193:73:17", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 2281, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "193:7:17", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "value": { + "arguments": [ + { + "arguments": [ + { + "expression": { + "arguments": [ + { + "id": 2288, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "253:6:17", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint96_$", + "typeString": "type(uint96)" + }, + "typeName": { + "id": 2287, + "name": "uint96", + "nodeType": "ElementaryTypeName", + "src": "253:6:17", + "typeDescriptions": {} + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_type$_t_uint96_$", + "typeString": "type(uint96)" + } + ], + "id": 2286, + "name": "type", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967269, + "src": "248:4:17", + "typeDescriptions": { + "typeIdentifier": "t_function_metatype_pure$__$returns$__$", + "typeString": "function () pure" + } + }, + "id": 2289, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "248:12:17", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_magic_meta_type_t_uint96", + "typeString": "type(uint96)" + } + }, + "id": 2290, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "261:3:17", + "memberName": "max", + "nodeType": "MemberAccess", + "src": "248:16:17", + "typeDescriptions": { + "typeIdentifier": "t_uint96", + "typeString": "uint96" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint96", + "typeString": "uint96" + } + ], + "id": 2285, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "240:7:17", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint256_$", + "typeString": "type(uint256)" + }, + "typeName": { + "id": 2284, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "240:7:17", + "typeDescriptions": {} + } + }, + "id": 2291, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "240:25:17", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 2283, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "232:7:17", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes32_$", + "typeString": "type(bytes32)" + }, + "typeName": { + "id": 2282, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "232:7:17", + "typeDescriptions": {} + } + }, + "id": 2292, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "232:34:17", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "body": { + "id": 2322, + "nodeType": "Block", + "src": "603:146:17", + "statements": [ + { + "id": 2321, + "nodeType": "UncheckedBlock", + "src": "609:136:17", + "statements": [ + { + "expression": { + "id": 2307, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 2303, + "name": "_space", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2299, + "src": "649:6:17", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2306, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 2304, + "name": "_rawNonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2296, + "src": "658:9:17", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">>", + "rightExpression": { + "id": 2305, + "name": "NONCE_BITS", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2280, + "src": "671:10:17", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "658:23:17", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "649:32:17", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2308, + "nodeType": "ExpressionStatement", + "src": "649:32:17" + }, + { + "expression": { + "id": 2319, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 2309, + "name": "_nonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2301, + "src": "689:6:17", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "commonType": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "id": 2317, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "arguments": [ + { + "id": 2314, + "name": "_rawNonce", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2296, + "src": "714:9:17", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "id": 2313, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "706:7:17", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_bytes32_$", + "typeString": "type(bytes32)" + }, + "typeName": { + "id": 2312, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "706:7:17", + "typeDescriptions": {} + } + }, + "id": 2315, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "706:18:17", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "BinaryOperation", + "operator": "&", + "rightExpression": { + "id": 2316, + "name": "NONCE_MASK", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2293, + "src": "727:10:17", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "src": "706:31:17", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 2311, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "698:7:17", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint256_$", + "typeString": "type(uint256)" + }, + "typeName": { + "id": 2310, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "698:7:17", + "typeDescriptions": {} + } + }, + "id": 2318, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "698:40:17", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "689:49:17", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2320, + "nodeType": "ExpressionStatement", + "src": "689:49:17" + } + ] + } + ] + }, + "documentation": { + "id": 2294, + "nodeType": "StructuredDocumentation", + "src": "271:222:17", + "text": " @notice Decodes a raw nonce\n @dev Schema: space[160]:type[96]\n @param _rawNonce Nonce to be decoded\n @return _space The nonce space of the raw nonce\n @return _nonce The nonce of the raw nonce" + }, + "id": 2323, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "decodeNonce", + "nameLocation": "505:11:17", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 2297, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2296, + "mutability": "mutable", + "name": "_rawNonce", + "nameLocation": "525:9:17", + "nodeType": "VariableDeclaration", + "scope": 2323, + "src": "517:17:17", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2295, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "517:7:17", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "516:19:17" + }, + "returnParameters": { + "id": 2302, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2299, + "mutability": "mutable", + "name": "_space", + "nameLocation": "572:6:17", + "nodeType": "VariableDeclaration", + "scope": 2323, + "src": "564:14:17", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2298, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "564:7:17", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2301, + "mutability": "mutable", + "name": "_nonce", + "nameLocation": "592:6:17", + "nodeType": "VariableDeclaration", + "scope": 2323, + "src": "584:14:17", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2300, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "584:7:17", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "558:44:17" + }, + "scope": 2324, + "src": "496:253:17", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + } + ], + "scope": 2325, + "src": "65:686:17", + "usedErrors": [] + } + ], + "src": "39:713:17" + }, + "id": 17 + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol": { + "ast": { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol", + "exportedSymbols": { + "LibBytes": [ + 2374 + ] + }, + "id": 2375, + "license": "Apache-2.0", + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 2326, + "literals": [ + "solidity", + "0.8", + ".18" + ], + "nodeType": "PragmaDirective", + "src": "39:23:18" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "LibBytes", + "contractDependencies": [], + "contractKind": "library", + "documentation": { + "id": 2327, + "nodeType": "StructuredDocumentation", + "src": "65:339:18", + "text": " @title Library for reading data from bytes arrays\n @author Agustin Aguilar (aa@horizon.io)\n @notice This library contains functions for reading data from bytes arrays.\n @dev These functions do not check if the input index is within the bounds of the data array.\n Reading out of bounds may return dirty values." + }, + "fullyImplemented": true, + "id": 2374, + "linearizedBaseContracts": [ + 2374 + ], + "name": "LibBytes", + "nameLocation": "413:8:18", + "nodeType": "ContractDefinition", + "nodes": [ + { + "body": { + "id": 2338, + "nodeType": "Block", + "src": "767:75:18", + "statements": [ + { + "AST": { + "nodeType": "YulBlock", + "src": "782:56:18", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "790:42:18", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "data.offset", + "nodeType": "YulIdentifier", + "src": "812:11:18" + }, + { + "name": "index", + "nodeType": "YulIdentifier", + "src": "825:5:18" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "808:3:18" + }, + "nodeType": "YulFunctionCall", + "src": "808:23:18" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "795:12:18" + }, + "nodeType": "YulFunctionCall", + "src": "795:37:18" + }, + "variableNames": [ + { + "name": "a", + "nodeType": "YulIdentifier", + "src": "790:1:18" + } + ] + } + ] + }, + "evmVersion": "paris", + "externalReferences": [ + { + "declaration": 2335, + "isOffset": false, + "isSlot": false, + "src": "790:1:18", + "valueSize": 1 + }, + { + "declaration": 2330, + "isOffset": true, + "isSlot": false, + "src": "812:11:18", + "suffix": "offset", + "valueSize": 1 + }, + { + "declaration": 2332, + "isOffset": false, + "isSlot": false, + "src": "825:5:18", + "valueSize": 1 + } + ], + "id": 2337, + "nodeType": "InlineAssembly", + "src": "773:65:18" + } + ] + }, + "documentation": { + "id": 2328, + "nodeType": "StructuredDocumentation", + "src": "427:226:18", + "text": " @notice Returns the bytes32 value at the given index in the input data.\n @param data The input data.\n @param index The index of the value to retrieve.\n @return a The bytes32 value at the given index." + }, + "id": 2339, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "readBytes32", + "nameLocation": "665:11:18", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 2333, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2330, + "mutability": "mutable", + "name": "data", + "nameLocation": "697:4:18", + "nodeType": "VariableDeclaration", + "scope": 2339, + "src": "682:19:18", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 2329, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "682:5:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2332, + "mutability": "mutable", + "name": "index", + "nameLocation": "715:5:18", + "nodeType": "VariableDeclaration", + "scope": 2339, + "src": "707:13:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2331, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "707:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "676:48:18" + }, + "returnParameters": { + "id": 2336, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2335, + "mutability": "mutable", + "name": "a", + "nameLocation": "761:1:18", + "nodeType": "VariableDeclaration", + "scope": 2339, + "src": "753:9:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 2334, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "753:7:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "747:19:18" + }, + "scope": 2374, + "src": "656:186:18", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": { + "id": 2350, + "nodeType": "Block", + "src": "1178:108:18", + "statements": [ + { + "AST": { + "nodeType": "YulBlock", + "src": "1193:89:18", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "1201:49:18", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "index", + "nodeType": "YulIdentifier", + "src": "1230:5:18" + }, + { + "name": "data.offset", + "nodeType": "YulIdentifier", + "src": "1237:11:18" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1226:3:18" + }, + "nodeType": "YulFunctionCall", + "src": "1226:23:18" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "1213:12:18" + }, + "nodeType": "YulFunctionCall", + "src": "1213:37:18" + }, + "variables": [ + { + "name": "word", + "nodeType": "YulTypedName", + "src": "1205:4:18", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "1257:19:18", + "value": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1266:3:18", + "type": "", + "value": "248" + }, + { + "name": "word", + "nodeType": "YulIdentifier", + "src": "1271:4:18" + } + ], + "functionName": { + "name": "shr", + "nodeType": "YulIdentifier", + "src": "1262:3:18" + }, + "nodeType": "YulFunctionCall", + "src": "1262:14:18" + }, + "variableNames": [ + { + "name": "a", + "nodeType": "YulIdentifier", + "src": "1257:1:18" + } + ] + } + ] + }, + "evmVersion": "paris", + "externalReferences": [ + { + "declaration": 2347, + "isOffset": false, + "isSlot": false, + "src": "1257:1:18", + "valueSize": 1 + }, + { + "declaration": 2342, + "isOffset": true, + "isSlot": false, + "src": "1237:11:18", + "suffix": "offset", + "valueSize": 1 + }, + { + "declaration": 2344, + "isOffset": false, + "isSlot": false, + "src": "1230:5:18", + "valueSize": 1 + } + ], + "id": 2349, + "nodeType": "InlineAssembly", + "src": "1184:98:18" + } + ] + }, + "documentation": { + "id": 2340, + "nodeType": "StructuredDocumentation", + "src": "846:222:18", + "text": " @notice Returns the uint8 value at the given index in the input data.\n @param data The input data.\n @param index The index of the value to retrieve.\n @return a The uint8 value at the given index." + }, + "id": 2351, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "readUint8", + "nameLocation": "1080:9:18", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 2345, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2342, + "mutability": "mutable", + "name": "data", + "nameLocation": "1110:4:18", + "nodeType": "VariableDeclaration", + "scope": 2351, + "src": "1095:19:18", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 2341, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "1095:5:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2344, + "mutability": "mutable", + "name": "index", + "nameLocation": "1128:5:18", + "nodeType": "VariableDeclaration", + "scope": 2351, + "src": "1120:13:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2343, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1120:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "1089:48:18" + }, + "returnParameters": { + "id": 2348, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2347, + "mutability": "mutable", + "name": "a", + "nameLocation": "1172:1:18", + "nodeType": "VariableDeclaration", + "scope": 2351, + "src": "1166:7:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 2346, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "1166:5:18", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "visibility": "internal" + } + ], + "src": "1160:17:18" + }, + "scope": 2374, + "src": "1071:215:18", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": { + "id": 2360, + "nodeType": "Block", + "src": "1550:96:18", + "statements": [ + { + "AST": { + "nodeType": "YulBlock", + "src": "1565:77:18", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "1573:37:18", + "value": { + "arguments": [ + { + "name": "data.offset", + "nodeType": "YulIdentifier", + "src": "1598:11:18" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "1585:12:18" + }, + "nodeType": "YulFunctionCall", + "src": "1585:25:18" + }, + "variables": [ + { + "name": "word", + "nodeType": "YulTypedName", + "src": "1577:4:18", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "1617:19:18", + "value": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1626:3:18", + "type": "", + "value": "240" + }, + { + "name": "word", + "nodeType": "YulIdentifier", + "src": "1631:4:18" + } + ], + "functionName": { + "name": "shr", + "nodeType": "YulIdentifier", + "src": "1622:3:18" + }, + "nodeType": "YulFunctionCall", + "src": "1622:14:18" + }, + "variableNames": [ + { + "name": "a", + "nodeType": "YulIdentifier", + "src": "1617:1:18" + } + ] + } + ] + }, + "evmVersion": "paris", + "externalReferences": [ + { + "declaration": 2357, + "isOffset": false, + "isSlot": false, + "src": "1617:1:18", + "valueSize": 1 + }, + { + "declaration": 2354, + "isOffset": true, + "isSlot": false, + "src": "1598:11:18", + "suffix": "offset", + "valueSize": 1 + } + ], + "id": 2359, + "nodeType": "InlineAssembly", + "src": "1556:86:18" + } + ] + }, + "documentation": { + "id": 2352, + "nodeType": "StructuredDocumentation", + "src": "1290:162:18", + "text": " @notice Returns the first uint16 value in the input data.\n @param data The input data.\n @return a The first uint16 value in the input data." + }, + "id": 2361, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "readFirstUint16", + "nameLocation": "1464:15:18", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 2355, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2354, + "mutability": "mutable", + "name": "data", + "nameLocation": "1500:4:18", + "nodeType": "VariableDeclaration", + "scope": 2361, + "src": "1485:19:18", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 2353, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "1485:5:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "1479:29:18" + }, + "returnParameters": { + "id": 2358, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2357, + "mutability": "mutable", + "name": "a", + "nameLocation": "1544:1:18", + "nodeType": "VariableDeclaration", + "scope": 2361, + "src": "1537:8:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint16", + "typeString": "uint16" + }, + "typeName": { + "id": 2356, + "name": "uint16", + "nodeType": "ElementaryTypeName", + "src": "1537:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint16", + "typeString": "uint16" + } + }, + "visibility": "internal" + } + ], + "src": "1531:18:18" + }, + "scope": 2374, + "src": "1455:191:18", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": { + "id": 2372, + "nodeType": "Block", + "src": "1986:108:18", + "statements": [ + { + "AST": { + "nodeType": "YulBlock", + "src": "2001:89:18", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "2009:49:18", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "index", + "nodeType": "YulIdentifier", + "src": "2038:5:18" + }, + { + "name": "data.offset", + "nodeType": "YulIdentifier", + "src": "2045:11:18" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2034:3:18" + }, + "nodeType": "YulFunctionCall", + "src": "2034:23:18" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "2021:12:18" + }, + "nodeType": "YulFunctionCall", + "src": "2021:37:18" + }, + "variables": [ + { + "name": "word", + "nodeType": "YulTypedName", + "src": "2013:4:18", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "2065:19:18", + "value": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2074:3:18", + "type": "", + "value": "224" + }, + { + "name": "word", + "nodeType": "YulIdentifier", + "src": "2079:4:18" + } + ], + "functionName": { + "name": "shr", + "nodeType": "YulIdentifier", + "src": "2070:3:18" + }, + "nodeType": "YulFunctionCall", + "src": "2070:14:18" + }, + "variableNames": [ + { + "name": "a", + "nodeType": "YulIdentifier", + "src": "2065:1:18" + } + ] + } + ] + }, + "evmVersion": "paris", + "externalReferences": [ + { + "declaration": 2369, + "isOffset": false, + "isSlot": false, + "src": "2065:1:18", + "valueSize": 1 + }, + { + "declaration": 2364, + "isOffset": true, + "isSlot": false, + "src": "2045:11:18", + "suffix": "offset", + "valueSize": 1 + }, + { + "declaration": 2366, + "isOffset": false, + "isSlot": false, + "src": "2038:5:18", + "valueSize": 1 + } + ], + "id": 2371, + "nodeType": "InlineAssembly", + "src": "1992:98:18" + } + ] + }, + "documentation": { + "id": 2362, + "nodeType": "StructuredDocumentation", + "src": "1650:224:18", + "text": " @notice Returns the uint32 value at the given index in the input data.\n @param data The input data.\n @param index The index of the value to retrieve.\n @return a The uint32 value at the given index." + }, + "id": 2373, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "readUint32", + "nameLocation": "1886:10:18", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 2367, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2364, + "mutability": "mutable", + "name": "data", + "nameLocation": "1917:4:18", + "nodeType": "VariableDeclaration", + "scope": 2373, + "src": "1902:19:18", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 2363, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "1902:5:18", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2366, + "mutability": "mutable", + "name": "index", + "nameLocation": "1935:5:18", + "nodeType": "VariableDeclaration", + "scope": 2373, + "src": "1927:13:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2365, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1927:7:18", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "1896:48:18" + }, + "returnParameters": { + "id": 2370, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2369, + "mutability": "mutable", + "name": "a", + "nameLocation": "1980:1:18", + "nodeType": "VariableDeclaration", + "scope": 2373, + "src": "1973:8:18", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + }, + "typeName": { + "id": 2368, + "name": "uint32", + "nodeType": "ElementaryTypeName", + "src": "1973:6:18", + "typeDescriptions": { + "typeIdentifier": "t_uint32", + "typeString": "uint32" + } + }, + "visibility": "internal" + } + ], + "src": "1967:18:18" + }, + "scope": 2374, + "src": "1877:217:18", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + } + ], + "scope": 2375, + "src": "405:1691:18", + "usedErrors": [] + } + ], + "src": "39:2058:18" + }, + "id": 18 + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol": { + "ast": { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytesPointer.sol", + "exportedSymbols": { + "LibBytesPointer": [ + 2476 + ] + }, + "id": 2477, + "license": "Apache-2.0", + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 2376, + "literals": [ + "solidity", + "0.8", + ".18" + ], + "nodeType": "PragmaDirective", + "src": "39:23:19" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "LibBytesPointer", + "contractDependencies": [], + "contractKind": "library", + "documentation": { + "id": 2377, + "nodeType": "StructuredDocumentation", + "src": "65:369:19", + "text": " @title Library for reading data from bytes arrays with a pointer\n @author Agustin Aguilar (aa@horizon.io)\n @notice This library contains functions for reading data from bytes arrays with a pointer.\n @dev These functions do not check if the input index is within the bounds of the data array.\n Reading out of bounds may return dirty values." + }, + "fullyImplemented": true, + "id": 2476, + "linearizedBaseContracts": [ + 2476 + ], + "name": "LibBytesPointer", + "nameLocation": "443:15:19", + "nodeType": "ContractDefinition", + "nodes": [ + { + "body": { + "id": 2388, + "nodeType": "Block", + "src": "794:119:19", + "statements": [ + { + "AST": { + "nodeType": "YulBlock", + "src": "809:100:19", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "817:38:19", + "value": { + "arguments": [ + { + "name": "_data.offset", + "nodeType": "YulIdentifier", + "src": "842:12:19" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "829:12:19" + }, + "nodeType": "YulFunctionCall", + "src": "829:26:19" + }, + "variables": [ + { + "name": "word", + "nodeType": "YulTypedName", + "src": "821:4:19", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "862:19:19", + "value": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "871:3:19", + "type": "", + "value": "240" + }, + { + "name": "word", + "nodeType": "YulIdentifier", + "src": "876:4:19" + } + ], + "functionName": { + "name": "shr", + "nodeType": "YulIdentifier", + "src": "867:3:19" + }, + "nodeType": "YulFunctionCall", + "src": "867:14:19" + }, + "variableNames": [ + { + "name": "a", + "nodeType": "YulIdentifier", + "src": "862:1:19" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "888:15:19", + "value": { + "kind": "number", + "nodeType": "YulLiteral", + "src": "902:1:19", + "type": "", + "value": "2" + }, + "variableNames": [ + { + "name": "newPointer", + "nodeType": "YulIdentifier", + "src": "888:10:19" + } + ] + } + ] + }, + "evmVersion": "paris", + "externalReferences": [ + { + "declaration": 2380, + "isOffset": true, + "isSlot": false, + "src": "842:12:19", + "suffix": "offset", + "valueSize": 1 + }, + { + "declaration": 2383, + "isOffset": false, + "isSlot": false, + "src": "862:1:19", + "valueSize": 1 + }, + { + "declaration": 2385, + "isOffset": false, + "isSlot": false, + "src": "888:10:19", + "valueSize": 1 + } + ], + "id": 2387, + "nodeType": "InlineAssembly", + "src": "800:109:19" + } + ] + }, + "documentation": { + "id": 2378, + "nodeType": "StructuredDocumentation", + "src": "464:207:19", + "text": " @dev Returns the first uint16 value in the input data and updates the pointer.\n @param _data The input data.\n @return a The first uint16 value.\n @return newPointer The new pointer." + }, + "id": 2389, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "readFirstUint16", + "nameLocation": "683:15:19", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 2381, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2380, + "mutability": "mutable", + "name": "_data", + "nameLocation": "719:5:19", + "nodeType": "VariableDeclaration", + "scope": 2389, + "src": "704:20:19", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 2379, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "704:5:19", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "698:30:19" + }, + "returnParameters": { + "id": 2386, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2383, + "mutability": "mutable", + "name": "a", + "nameLocation": "764:1:19", + "nodeType": "VariableDeclaration", + "scope": 2389, + "src": "757:8:19", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint16", + "typeString": "uint16" + }, + "typeName": { + "id": 2382, + "name": "uint16", + "nodeType": "ElementaryTypeName", + "src": "757:6:19", + "typeDescriptions": { + "typeIdentifier": "t_uint16", + "typeString": "uint16" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2385, + "mutability": "mutable", + "name": "newPointer", + "nameLocation": "779:10:19", + "nodeType": "VariableDeclaration", + "scope": 2389, + "src": "771:18:19", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2384, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "771:7:19", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "751:42:19" + }, + "scope": 2476, + "src": "674:239:19", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": { + "id": 2402, + "nodeType": "Block", + "src": "1342:145:19", + "statements": [ + { + "AST": { + "nodeType": "YulBlock", + "src": "1357:126:19", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "1365:51:19", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "_index", + "nodeType": "YulIdentifier", + "src": "1394:6:19" + }, + { + "name": "_data.offset", + "nodeType": "YulIdentifier", + "src": "1402:12:19" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1390:3:19" + }, + "nodeType": "YulFunctionCall", + "src": "1390:25:19" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "1377:12:19" + }, + "nodeType": "YulFunctionCall", + "src": "1377:39:19" + }, + "variables": [ + { + "name": "word", + "nodeType": "YulTypedName", + "src": "1369:4:19", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "1423:19:19", + "value": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1432:3:19", + "type": "", + "value": "248" + }, + { + "name": "word", + "nodeType": "YulIdentifier", + "src": "1437:4:19" + } + ], + "functionName": { + "name": "shr", + "nodeType": "YulIdentifier", + "src": "1428:3:19" + }, + "nodeType": "YulFunctionCall", + "src": "1428:14:19" + }, + "variableNames": [ + { + "name": "a", + "nodeType": "YulIdentifier", + "src": "1423:1:19" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "1449:28:19", + "value": { + "arguments": [ + { + "name": "_index", + "nodeType": "YulIdentifier", + "src": "1467:6:19" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1475:1:19", + "type": "", + "value": "1" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1463:3:19" + }, + "nodeType": "YulFunctionCall", + "src": "1463:14:19" + }, + "variableNames": [ + { + "name": "newPointer", + "nodeType": "YulIdentifier", + "src": "1449:10:19" + } + ] + } + ] + }, + "evmVersion": "paris", + "externalReferences": [ + { + "declaration": 2392, + "isOffset": true, + "isSlot": false, + "src": "1402:12:19", + "suffix": "offset", + "valueSize": 1 + }, + { + "declaration": 2394, + "isOffset": false, + "isSlot": false, + "src": "1394:6:19", + "valueSize": 1 + }, + { + "declaration": 2394, + "isOffset": false, + "isSlot": false, + "src": "1467:6:19", + "valueSize": 1 + }, + { + "declaration": 2397, + "isOffset": false, + "isSlot": false, + "src": "1423:1:19", + "valueSize": 1 + }, + { + "declaration": 2399, + "isOffset": false, + "isSlot": false, + "src": "1449:10:19", + "valueSize": 1 + } + ], + "id": 2401, + "nodeType": "InlineAssembly", + "src": "1348:135:19" + } + ] + }, + "documentation": { + "id": 2390, + "nodeType": "StructuredDocumentation", + "src": "917:289:19", + "text": " @notice Returns the uint8 value at the given index in the input data and updates the pointer.\n @param _data The input data.\n @param _index The index of the value to retrieve.\n @return a The uint8 value at the given index.\n @return newPointer The new pointer." + }, + "id": 2403, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "readUint8", + "nameLocation": "1218:9:19", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 2395, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2392, + "mutability": "mutable", + "name": "_data", + "nameLocation": "1248:5:19", + "nodeType": "VariableDeclaration", + "scope": 2403, + "src": "1233:20:19", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 2391, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "1233:5:19", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2394, + "mutability": "mutable", + "name": "_index", + "nameLocation": "1267:6:19", + "nodeType": "VariableDeclaration", + "scope": 2403, + "src": "1259:14:19", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2393, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1259:7:19", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "1227:50:19" + }, + "returnParameters": { + "id": 2400, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2397, + "mutability": "mutable", + "name": "a", + "nameLocation": "1312:1:19", + "nodeType": "VariableDeclaration", + "scope": 2403, + "src": "1306:7:19", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 2396, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "1306:5:19", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2399, + "mutability": "mutable", + "name": "newPointer", + "nameLocation": "1327:10:19", + "nodeType": "VariableDeclaration", + "scope": 2403, + "src": "1319:18:19", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2398, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1319:7:19", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "1300:41:19" + }, + "scope": 2476, + "src": "1209:278:19", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": { + "id": 2418, + "nodeType": "Block", + "src": "1998:220:19", + "statements": [ + { + "AST": { + "nodeType": "YulBlock", + "src": "2013:201:19", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "2021:51:19", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "_index", + "nodeType": "YulIdentifier", + "src": "2050:6:19" + }, + { + "name": "_data.offset", + "nodeType": "YulIdentifier", + "src": "2058:12:19" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2046:3:19" + }, + "nodeType": "YulFunctionCall", + "src": "2046:25:19" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "2033:12:19" + }, + "nodeType": "YulFunctionCall", + "src": "2033:39:19" + }, + "variables": [ + { + "name": "word", + "nodeType": "YulTypedName", + "src": "2025:4:19", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "2079:19:19", + "value": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2088:3:19", + "type": "", + "value": "248" + }, + { + "name": "word", + "nodeType": "YulIdentifier", + "src": "2093:4:19" + } + ], + "functionName": { + "name": "shr", + "nodeType": "YulIdentifier", + "src": "2084:3:19" + }, + "nodeType": "YulFunctionCall", + "src": "2084:14:19" + }, + "variableNames": [ + { + "name": "a", + "nodeType": "YulIdentifier", + "src": "2079:1:19" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "2105:67:19", + "value": { + "arguments": [ + { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2118:2:19", + "type": "", + "value": "88" + }, + { + "name": "word", + "nodeType": "YulIdentifier", + "src": "2122:4:19" + } + ], + "functionName": { + "name": "shr", + "nodeType": "YulIdentifier", + "src": "2114:3:19" + }, + "nodeType": "YulFunctionCall", + "src": "2114:13:19" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2129:42:19", + "type": "", + "value": "0xffffffffffffffffffffffffffffffffffffffff" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "2110:3:19" + }, + "nodeType": "YulFunctionCall", + "src": "2110:62:19" + }, + "variableNames": [ + { + "name": "b", + "nodeType": "YulIdentifier", + "src": "2105:1:19" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "2179:29:19", + "value": { + "arguments": [ + { + "name": "_index", + "nodeType": "YulIdentifier", + "src": "2197:6:19" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2205:2:19", + "type": "", + "value": "21" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2193:3:19" + }, + "nodeType": "YulFunctionCall", + "src": "2193:15:19" + }, + "variableNames": [ + { + "name": "newPointer", + "nodeType": "YulIdentifier", + "src": "2179:10:19" + } + ] + } + ] + }, + "evmVersion": "paris", + "externalReferences": [ + { + "declaration": 2406, + "isOffset": true, + "isSlot": false, + "src": "2058:12:19", + "suffix": "offset", + "valueSize": 1 + }, + { + "declaration": 2408, + "isOffset": false, + "isSlot": false, + "src": "2050:6:19", + "valueSize": 1 + }, + { + "declaration": 2408, + "isOffset": false, + "isSlot": false, + "src": "2197:6:19", + "valueSize": 1 + }, + { + "declaration": 2411, + "isOffset": false, + "isSlot": false, + "src": "2079:1:19", + "valueSize": 1 + }, + { + "declaration": 2413, + "isOffset": false, + "isSlot": false, + "src": "2105:1:19", + "valueSize": 1 + }, + { + "declaration": 2415, + "isOffset": false, + "isSlot": false, + "src": "2179:10:19", + "valueSize": 1 + } + ], + "id": 2417, + "nodeType": "InlineAssembly", + "src": "2004:210:19" + } + ] + }, + "documentation": { + "id": 2404, + "nodeType": "StructuredDocumentation", + "src": "1491:349:19", + "text": " @notice Returns the uint8 value and the address at the given index in the input data and updates the pointer.\n @param _data The input data.\n @param _index The index of the value to retrieve.\n @return a The uint8 value at the given index.\n @return b The following address value.\n @return newPointer The new pointer." + }, + "id": 2419, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "readUint8Address", + "nameLocation": "1852:16:19", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 2409, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2406, + "mutability": "mutable", + "name": "_data", + "nameLocation": "1889:5:19", + "nodeType": "VariableDeclaration", + "scope": 2419, + "src": "1874:20:19", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 2405, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "1874:5:19", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2408, + "mutability": "mutable", + "name": "_index", + "nameLocation": "1908:6:19", + "nodeType": "VariableDeclaration", + "scope": 2419, + "src": "1900:14:19", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2407, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1900:7:19", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "1868:50:19" + }, + "returnParameters": { + "id": 2416, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2411, + "mutability": "mutable", + "name": "a", + "nameLocation": "1953:1:19", + "nodeType": "VariableDeclaration", + "scope": 2419, + "src": "1947:7:19", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 2410, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "1947:5:19", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2413, + "mutability": "mutable", + "name": "b", + "nameLocation": "1968:1:19", + "nodeType": "VariableDeclaration", + "scope": 2419, + "src": "1960:9:19", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 2412, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1960:7:19", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2415, + "mutability": "mutable", + "name": "newPointer", + "nameLocation": "1983:10:19", + "nodeType": "VariableDeclaration", + "scope": 2419, + "src": "1975:18:19", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2414, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1975:7:19", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "1941:56:19" + }, + "scope": 2476, + "src": "1843:375:19", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": { + "id": 2432, + "nodeType": "Block", + "src": "2651:158:19", + "statements": [ + { + "AST": { + "nodeType": "YulBlock", + "src": "2666:139:19", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "2674:51:19", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "_index", + "nodeType": "YulIdentifier", + "src": "2703:6:19" + }, + { + "name": "_data.offset", + "nodeType": "YulIdentifier", + "src": "2711:12:19" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2699:3:19" + }, + "nodeType": "YulFunctionCall", + "src": "2699:25:19" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "2686:12:19" + }, + "nodeType": "YulFunctionCall", + "src": "2686:39:19" + }, + "variables": [ + { + "name": "word", + "nodeType": "YulTypedName", + "src": "2678:4:19", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "2732:32:19", + "value": { + "arguments": [ + { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2745:3:19", + "type": "", + "value": "240" + }, + { + "name": "word", + "nodeType": "YulIdentifier", + "src": "2750:4:19" + } + ], + "functionName": { + "name": "shr", + "nodeType": "YulIdentifier", + "src": "2741:3:19" + }, + "nodeType": "YulFunctionCall", + "src": "2741:14:19" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2757:6:19", + "type": "", + "value": "0xffff" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "2737:3:19" + }, + "nodeType": "YulFunctionCall", + "src": "2737:27:19" + }, + "variableNames": [ + { + "name": "a", + "nodeType": "YulIdentifier", + "src": "2732:1:19" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "2771:28:19", + "value": { + "arguments": [ + { + "name": "_index", + "nodeType": "YulIdentifier", + "src": "2789:6:19" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2797:1:19", + "type": "", + "value": "2" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "2785:3:19" + }, + "nodeType": "YulFunctionCall", + "src": "2785:14:19" + }, + "variableNames": [ + { + "name": "newPointer", + "nodeType": "YulIdentifier", + "src": "2771:10:19" + } + ] + } + ] + }, + "evmVersion": "paris", + "externalReferences": [ + { + "declaration": 2422, + "isOffset": true, + "isSlot": false, + "src": "2711:12:19", + "suffix": "offset", + "valueSize": 1 + }, + { + "declaration": 2424, + "isOffset": false, + "isSlot": false, + "src": "2703:6:19", + "valueSize": 1 + }, + { + "declaration": 2424, + "isOffset": false, + "isSlot": false, + "src": "2789:6:19", + "valueSize": 1 + }, + { + "declaration": 2427, + "isOffset": false, + "isSlot": false, + "src": "2732:1:19", + "valueSize": 1 + }, + { + "declaration": 2429, + "isOffset": false, + "isSlot": false, + "src": "2771:10:19", + "valueSize": 1 + } + ], + "id": 2431, + "nodeType": "InlineAssembly", + "src": "2657:148:19" + } + ] + }, + "documentation": { + "id": 2420, + "nodeType": "StructuredDocumentation", + "src": "2222:291:19", + "text": " @notice Returns the uint16 value at the given index in the input data and updates the pointer.\n @param _data The input data.\n @param _index The index of the value to retrieve.\n @return a The uint16 value at the given index.\n @return newPointer The new pointer." + }, + "id": 2433, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "readUint16", + "nameLocation": "2525:10:19", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 2425, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2422, + "mutability": "mutable", + "name": "_data", + "nameLocation": "2556:5:19", + "nodeType": "VariableDeclaration", + "scope": 2433, + "src": "2541:20:19", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 2421, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "2541:5:19", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2424, + "mutability": "mutable", + "name": "_index", + "nameLocation": "2575:6:19", + "nodeType": "VariableDeclaration", + "scope": 2433, + "src": "2567:14:19", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2423, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2567:7:19", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "2535:50:19" + }, + "returnParameters": { + "id": 2430, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2427, + "mutability": "mutable", + "name": "a", + "nameLocation": "2621:1:19", + "nodeType": "VariableDeclaration", + "scope": 2433, + "src": "2614:8:19", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint16", + "typeString": "uint16" + }, + "typeName": { + "id": 2426, + "name": "uint16", + "nodeType": "ElementaryTypeName", + "src": "2614:6:19", + "typeDescriptions": { + "typeIdentifier": "t_uint16", + "typeString": "uint16" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2429, + "mutability": "mutable", + "name": "newPointer", + "nameLocation": "2636:10:19", + "nodeType": "VariableDeclaration", + "scope": 2433, + "src": "2628:18:19", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2428, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2628:7:19", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "2608:42:19" + }, + "scope": 2476, + "src": "2516:293:19", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": { + "id": 2446, + "nodeType": "Block", + "src": "3242:160:19", + "statements": [ + { + "AST": { + "nodeType": "YulBlock", + "src": "3257:141:19", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "3265:51:19", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "_index", + "nodeType": "YulIdentifier", + "src": "3294:6:19" + }, + { + "name": "_data.offset", + "nodeType": "YulIdentifier", + "src": "3302:12:19" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "3290:3:19" + }, + "nodeType": "YulFunctionCall", + "src": "3290:25:19" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "3277:12:19" + }, + "nodeType": "YulFunctionCall", + "src": "3277:39:19" + }, + "variables": [ + { + "name": "word", + "nodeType": "YulTypedName", + "src": "3269:4:19", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "3323:34:19", + "value": { + "arguments": [ + { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3336:3:19", + "type": "", + "value": "232" + }, + { + "name": "word", + "nodeType": "YulIdentifier", + "src": "3341:4:19" + } + ], + "functionName": { + "name": "shr", + "nodeType": "YulIdentifier", + "src": "3332:3:19" + }, + "nodeType": "YulFunctionCall", + "src": "3332:14:19" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3348:8:19", + "type": "", + "value": "0xffffff" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "3328:3:19" + }, + "nodeType": "YulFunctionCall", + "src": "3328:29:19" + }, + "variableNames": [ + { + "name": "a", + "nodeType": "YulIdentifier", + "src": "3323:1:19" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "3364:28:19", + "value": { + "arguments": [ + { + "name": "_index", + "nodeType": "YulIdentifier", + "src": "3382:6:19" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3390:1:19", + "type": "", + "value": "3" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "3378:3:19" + }, + "nodeType": "YulFunctionCall", + "src": "3378:14:19" + }, + "variableNames": [ + { + "name": "newPointer", + "nodeType": "YulIdentifier", + "src": "3364:10:19" + } + ] + } + ] + }, + "evmVersion": "paris", + "externalReferences": [ + { + "declaration": 2436, + "isOffset": true, + "isSlot": false, + "src": "3302:12:19", + "suffix": "offset", + "valueSize": 1 + }, + { + "declaration": 2438, + "isOffset": false, + "isSlot": false, + "src": "3294:6:19", + "valueSize": 1 + }, + { + "declaration": 2438, + "isOffset": false, + "isSlot": false, + "src": "3382:6:19", + "valueSize": 1 + }, + { + "declaration": 2441, + "isOffset": false, + "isSlot": false, + "src": "3323:1:19", + "valueSize": 1 + }, + { + "declaration": 2443, + "isOffset": false, + "isSlot": false, + "src": "3364:10:19", + "valueSize": 1 + } + ], + "id": 2445, + "nodeType": "InlineAssembly", + "src": "3248:150:19" + } + ] + }, + "documentation": { + "id": 2434, + "nodeType": "StructuredDocumentation", + "src": "2813:291:19", + "text": " @notice Returns the uint24 value at the given index in the input data and updates the pointer.\n @param _data The input data.\n @param _index The index of the value to retrieve.\n @return a The uint24 value at the given index.\n @return newPointer The new pointer." + }, + "id": 2447, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "readUint24", + "nameLocation": "3116:10:19", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 2439, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2436, + "mutability": "mutable", + "name": "_data", + "nameLocation": "3147:5:19", + "nodeType": "VariableDeclaration", + "scope": 2447, + "src": "3132:20:19", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 2435, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "3132:5:19", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2438, + "mutability": "mutable", + "name": "_index", + "nameLocation": "3166:6:19", + "nodeType": "VariableDeclaration", + "scope": 2447, + "src": "3158:14:19", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2437, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3158:7:19", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "3126:50:19" + }, + "returnParameters": { + "id": 2444, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2441, + "mutability": "mutable", + "name": "a", + "nameLocation": "3212:1:19", + "nodeType": "VariableDeclaration", + "scope": 2447, + "src": "3205:8:19", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint24", + "typeString": "uint24" + }, + "typeName": { + "id": 2440, + "name": "uint24", + "nodeType": "ElementaryTypeName", + "src": "3205:6:19", + "typeDescriptions": { + "typeIdentifier": "t_uint24", + "typeString": "uint24" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2443, + "mutability": "mutable", + "name": "newPointer", + "nameLocation": "3227:10:19", + "nodeType": "VariableDeclaration", + "scope": 2447, + "src": "3219:18:19", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2442, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3219:7:19", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "3199:42:19" + }, + "scope": 2476, + "src": "3107:295:19", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": { + "id": 2460, + "nodeType": "Block", + "src": "3835:170:19", + "statements": [ + { + "AST": { + "nodeType": "YulBlock", + "src": "3850:151:19", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "3858:51:19", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "_index", + "nodeType": "YulIdentifier", + "src": "3887:6:19" + }, + { + "name": "_data.offset", + "nodeType": "YulIdentifier", + "src": "3895:12:19" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "3883:3:19" + }, + "nodeType": "YulFunctionCall", + "src": "3883:25:19" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "3870:12:19" + }, + "nodeType": "YulFunctionCall", + "src": "3870:39:19" + }, + "variables": [ + { + "name": "word", + "nodeType": "YulTypedName", + "src": "3862:4:19", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "3916:44:19", + "value": { + "arguments": [ + { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3929:3:19", + "type": "", + "value": "192" + }, + { + "name": "word", + "nodeType": "YulIdentifier", + "src": "3934:4:19" + } + ], + "functionName": { + "name": "shr", + "nodeType": "YulIdentifier", + "src": "3925:3:19" + }, + "nodeType": "YulFunctionCall", + "src": "3925:14:19" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3941:18:19", + "type": "", + "value": "0xffffffffffffffff" + } + ], + "functionName": { + "name": "and", + "nodeType": "YulIdentifier", + "src": "3921:3:19" + }, + "nodeType": "YulFunctionCall", + "src": "3921:39:19" + }, + "variableNames": [ + { + "name": "a", + "nodeType": "YulIdentifier", + "src": "3916:1:19" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "3967:28:19", + "value": { + "arguments": [ + { + "name": "_index", + "nodeType": "YulIdentifier", + "src": "3985:6:19" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "3993:1:19", + "type": "", + "value": "8" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "3981:3:19" + }, + "nodeType": "YulFunctionCall", + "src": "3981:14:19" + }, + "variableNames": [ + { + "name": "newPointer", + "nodeType": "YulIdentifier", + "src": "3967:10:19" + } + ] + } + ] + }, + "evmVersion": "paris", + "externalReferences": [ + { + "declaration": 2450, + "isOffset": true, + "isSlot": false, + "src": "3895:12:19", + "suffix": "offset", + "valueSize": 1 + }, + { + "declaration": 2452, + "isOffset": false, + "isSlot": false, + "src": "3887:6:19", + "valueSize": 1 + }, + { + "declaration": 2452, + "isOffset": false, + "isSlot": false, + "src": "3985:6:19", + "valueSize": 1 + }, + { + "declaration": 2455, + "isOffset": false, + "isSlot": false, + "src": "3916:1:19", + "valueSize": 1 + }, + { + "declaration": 2457, + "isOffset": false, + "isSlot": false, + "src": "3967:10:19", + "valueSize": 1 + } + ], + "id": 2459, + "nodeType": "InlineAssembly", + "src": "3841:160:19" + } + ] + }, + "documentation": { + "id": 2448, + "nodeType": "StructuredDocumentation", + "src": "3406:291:19", + "text": " @notice Returns the uint64 value at the given index in the input data and updates the pointer.\n @param _data The input data.\n @param _index The index of the value to retrieve.\n @return a The uint64 value at the given index.\n @return newPointer The new pointer." + }, + "id": 2461, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "readUint64", + "nameLocation": "3709:10:19", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 2453, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2450, + "mutability": "mutable", + "name": "_data", + "nameLocation": "3740:5:19", + "nodeType": "VariableDeclaration", + "scope": 2461, + "src": "3725:20:19", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 2449, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "3725:5:19", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2452, + "mutability": "mutable", + "name": "_index", + "nameLocation": "3759:6:19", + "nodeType": "VariableDeclaration", + "scope": 2461, + "src": "3751:14:19", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2451, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3751:7:19", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "3719:50:19" + }, + "returnParameters": { + "id": 2458, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2455, + "mutability": "mutable", + "name": "a", + "nameLocation": "3805:1:19", + "nodeType": "VariableDeclaration", + "scope": 2461, + "src": "3798:8:19", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint64", + "typeString": "uint64" + }, + "typeName": { + "id": 2454, + "name": "uint64", + "nodeType": "ElementaryTypeName", + "src": "3798:6:19", + "typeDescriptions": { + "typeIdentifier": "t_uint64", + "typeString": "uint64" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2457, + "mutability": "mutable", + "name": "newPointer", + "nameLocation": "3820:10:19", + "nodeType": "VariableDeclaration", + "scope": 2461, + "src": "3812:18:19", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2456, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3812:7:19", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "3792:42:19" + }, + "scope": 2476, + "src": "3700:305:19", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": { + "id": 2474, + "nodeType": "Block", + "src": "4446:117:19", + "statements": [ + { + "AST": { + "nodeType": "YulBlock", + "src": "4461:98:19", + "statements": [ + { + "nodeType": "YulAssignment", + "src": "4469:46:19", + "value": { + "arguments": [ + { + "arguments": [ + { + "name": "_pointer", + "nodeType": "YulIdentifier", + "src": "4491:8:19" + }, + { + "name": "_data.offset", + "nodeType": "YulIdentifier", + "src": "4501:12:19" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4487:3:19" + }, + "nodeType": "YulFunctionCall", + "src": "4487:27:19" + } + ], + "functionName": { + "name": "calldataload", + "nodeType": "YulIdentifier", + "src": "4474:12:19" + }, + "nodeType": "YulFunctionCall", + "src": "4474:41:19" + }, + "variableNames": [ + { + "name": "a", + "nodeType": "YulIdentifier", + "src": "4469:1:19" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "4522:31:19", + "value": { + "arguments": [ + { + "name": "_pointer", + "nodeType": "YulIdentifier", + "src": "4540:8:19" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "4550:2:19", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "4536:3:19" + }, + "nodeType": "YulFunctionCall", + "src": "4536:17:19" + }, + "variableNames": [ + { + "name": "newPointer", + "nodeType": "YulIdentifier", + "src": "4522:10:19" + } + ] + } + ] + }, + "evmVersion": "paris", + "externalReferences": [ + { + "declaration": 2464, + "isOffset": true, + "isSlot": false, + "src": "4501:12:19", + "suffix": "offset", + "valueSize": 1 + }, + { + "declaration": 2466, + "isOffset": false, + "isSlot": false, + "src": "4491:8:19", + "valueSize": 1 + }, + { + "declaration": 2466, + "isOffset": false, + "isSlot": false, + "src": "4540:8:19", + "valueSize": 1 + }, + { + "declaration": 2469, + "isOffset": false, + "isSlot": false, + "src": "4469:1:19", + "valueSize": 1 + }, + { + "declaration": 2471, + "isOffset": false, + "isSlot": false, + "src": "4522:10:19", + "valueSize": 1 + } + ], + "id": 2473, + "nodeType": "InlineAssembly", + "src": "4452:107:19" + } + ] + }, + "documentation": { + "id": 2462, + "nodeType": "StructuredDocumentation", + "src": "4009:295:19", + "text": " @notice Returns the bytes32 value at the given index in the input data and updates the pointer.\n @param _data The input data.\n @param _pointer The index of the value to retrieve.\n @return a The bytes32 value at the given index.\n @return newPointer The new pointer." + }, + "id": 2475, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "readBytes32", + "nameLocation": "4316:11:19", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 2467, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2464, + "mutability": "mutable", + "name": "_data", + "nameLocation": "4348:5:19", + "nodeType": "VariableDeclaration", + "scope": 2475, + "src": "4333:20:19", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 2463, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "4333:5:19", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2466, + "mutability": "mutable", + "name": "_pointer", + "nameLocation": "4367:8:19", + "nodeType": "VariableDeclaration", + "scope": 2475, + "src": "4359:16:19", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2465, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "4359:7:19", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "4327:52:19" + }, + "returnParameters": { + "id": 2472, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2469, + "mutability": "mutable", + "name": "a", + "nameLocation": "4416:1:19", + "nodeType": "VariableDeclaration", + "scope": 2475, + "src": "4408:9:19", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 2468, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "4408:7:19", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2471, + "mutability": "mutable", + "name": "newPointer", + "nameLocation": "4431:10:19", + "nodeType": "VariableDeclaration", + "scope": 2475, + "src": "4423:18:19", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2470, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "4423:7:19", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "4402:43:19" + }, + "scope": 2476, + "src": "4307:256:19", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + } + ], + "scope": 2477, + "src": "435:4130:19", + "usedErrors": [] + } + ], + "src": "39:4527:19" + }, + "id": 19 + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol": { + "ast": { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibOptim.sol", + "exportedSymbols": { + "LibOptim": [ + 2530 + ] + }, + "id": 2531, + "license": "Apache-2.0", + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 2478, + "literals": [ + "solidity", + "0.8", + ".18" + ], + "nodeType": "PragmaDirective", + "src": "39:23:20" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "LibOptim", + "contractDependencies": [], + "contractKind": "library", + "documentation": { + "id": 2479, + "nodeType": "StructuredDocumentation", + "src": "64:179:20", + "text": " @title Library for optimized EVM operations\n @author Agustin Aguilar (aa@horizon.io)\n @notice This library contains functions for optimizing certain EVM operations." + }, + "fullyImplemented": true, + "id": 2530, + "linearizedBaseContracts": [ + 2530 + ], + "name": "LibOptim", + "nameLocation": "252:8:20", + "nodeType": "ContractDefinition", + "nodes": [ + { + "body": { + "id": 2490, + "nodeType": "Block", + "src": "633:95:20", + "statements": [ + { + "AST": { + "nodeType": "YulBlock", + "src": "648:76:20", + "statements": [ + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "663:1:20", + "type": "", + "value": "0" + }, + { + "name": "_a", + "nodeType": "YulIdentifier", + "src": "666:2:20" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "656:6:20" + }, + "nodeType": "YulFunctionCall", + "src": "656:13:20" + }, + "nodeType": "YulExpressionStatement", + "src": "656:13:20" + }, + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "683:2:20", + "type": "", + "value": "32" + }, + { + "name": "_b", + "nodeType": "YulIdentifier", + "src": "687:2:20" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "676:6:20" + }, + "nodeType": "YulFunctionCall", + "src": "676:14:20" + }, + "nodeType": "YulExpressionStatement", + "src": "676:14:20" + }, + { + "nodeType": "YulAssignment", + "src": "697:21:20", + "value": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "712:1:20", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "715:2:20", + "type": "", + "value": "64" + } + ], + "functionName": { + "name": "keccak256", + "nodeType": "YulIdentifier", + "src": "702:9:20" + }, + "nodeType": "YulFunctionCall", + "src": "702:16:20" + }, + "variableNames": [ + { + "name": "c", + "nodeType": "YulIdentifier", + "src": "697:1:20" + } + ] + } + ] + }, + "evmVersion": "paris", + "externalReferences": [ + { + "declaration": 2482, + "isOffset": false, + "isSlot": false, + "src": "666:2:20", + "valueSize": 1 + }, + { + "declaration": 2484, + "isOffset": false, + "isSlot": false, + "src": "687:2:20", + "valueSize": 1 + }, + { + "declaration": 2487, + "isOffset": false, + "isSlot": false, + "src": "697:1:20", + "valueSize": 1 + } + ], + "id": 2489, + "nodeType": "InlineAssembly", + "src": "639:85:20" + } + ] + }, + "documentation": { + "id": 2480, + "nodeType": "StructuredDocumentation", + "src": "266:274:20", + "text": " @notice Computes the keccak256 hash of two 32-byte inputs.\n @dev It uses only scratch memory space.\n @param _a The first 32 bytes of the hash.\n @param _b The second 32 bytes of the hash.\n @return c The keccak256 hash of the two 32-byte inputs." + }, + "id": 2491, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "fkeccak256", + "nameLocation": "552:10:20", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 2485, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2482, + "mutability": "mutable", + "name": "_a", + "nameLocation": "576:2:20", + "nodeType": "VariableDeclaration", + "scope": 2491, + "src": "568:10:20", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 2481, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "568:7:20", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2484, + "mutability": "mutable", + "name": "_b", + "nameLocation": "592:2:20", + "nodeType": "VariableDeclaration", + "scope": 2491, + "src": "584:10:20", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 2483, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "584:7:20", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "562:36:20" + }, + "returnParameters": { + "id": 2488, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2487, + "mutability": "mutable", + "name": "c", + "nameLocation": "630:1:20", + "nodeType": "VariableDeclaration", + "scope": 2491, + "src": "622:9:20", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 2486, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "622:7:20", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "621:11:20" + }, + "scope": 2530, + "src": "543:185:20", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": { + "id": 2498, + "nodeType": "Block", + "src": "913:210:20", + "statements": [ + { + "AST": { + "nodeType": "YulBlock", + "src": "928:191:20", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "936:28:20", + "value": { + "arguments": [], + "functionName": { + "name": "returndatasize", + "nodeType": "YulIdentifier", + "src": "948:14:20" + }, + "nodeType": "YulFunctionCall", + "src": "948:16:20" + }, + "variables": [ + { + "name": "size", + "nodeType": "YulTypedName", + "src": "940:4:20", + "type": "" + } + ] + }, + { + "nodeType": "YulAssignment", + "src": "971:16:20", + "value": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "982:4:20", + "type": "", + "value": "0x40" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "976:5:20" + }, + "nodeType": "YulFunctionCall", + "src": "976:11:20" + }, + "variableNames": [ + { + "name": "r", + "nodeType": "YulIdentifier", + "src": "971:1:20" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "994:23:20", + "value": { + "arguments": [ + { + "name": "r", + "nodeType": "YulIdentifier", + "src": "1011:1:20" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1014:2:20", + "type": "", + "value": "32" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1007:3:20" + }, + "nodeType": "YulFunctionCall", + "src": "1007:10:20" + }, + "variables": [ + { + "name": "start", + "nodeType": "YulTypedName", + "src": "998:5:20", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1031:4:20", + "type": "", + "value": "0x40" + }, + { + "arguments": [ + { + "name": "start", + "nodeType": "YulIdentifier", + "src": "1041:5:20" + }, + { + "name": "size", + "nodeType": "YulIdentifier", + "src": "1048:4:20" + } + ], + "functionName": { + "name": "add", + "nodeType": "YulIdentifier", + "src": "1037:3:20" + }, + "nodeType": "YulFunctionCall", + "src": "1037:16:20" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "1024:6:20" + }, + "nodeType": "YulFunctionCall", + "src": "1024:30:20" + }, + "nodeType": "YulExpressionStatement", + "src": "1024:30:20" + }, + { + "expression": { + "arguments": [ + { + "name": "r", + "nodeType": "YulIdentifier", + "src": "1068:1:20" + }, + { + "name": "size", + "nodeType": "YulIdentifier", + "src": "1071:4:20" + } + ], + "functionName": { + "name": "mstore", + "nodeType": "YulIdentifier", + "src": "1061:6:20" + }, + "nodeType": "YulFunctionCall", + "src": "1061:15:20" + }, + "nodeType": "YulExpressionStatement", + "src": "1061:15:20" + }, + { + "expression": { + "arguments": [ + { + "name": "start", + "nodeType": "YulIdentifier", + "src": "1098:5:20" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1105:1:20", + "type": "", + "value": "0" + }, + { + "name": "size", + "nodeType": "YulIdentifier", + "src": "1108:4:20" + } + ], + "functionName": { + "name": "returndatacopy", + "nodeType": "YulIdentifier", + "src": "1083:14:20" + }, + "nodeType": "YulFunctionCall", + "src": "1083:30:20" + }, + "nodeType": "YulExpressionStatement", + "src": "1083:30:20" + } + ] + }, + "evmVersion": "paris", + "externalReferences": [ + { + "declaration": 2495, + "isOffset": false, + "isSlot": false, + "src": "1011:1:20", + "valueSize": 1 + }, + { + "declaration": 2495, + "isOffset": false, + "isSlot": false, + "src": "1068:1:20", + "valueSize": 1 + }, + { + "declaration": 2495, + "isOffset": false, + "isSlot": false, + "src": "971:1:20", + "valueSize": 1 + } + ], + "id": 2497, + "nodeType": "InlineAssembly", + "src": "919:200:20" + } + ] + }, + "documentation": { + "id": 2492, + "nodeType": "StructuredDocumentation", + "src": "732:117:20", + "text": " @notice Returns the return data from the last call.\n @return r The return data from the last call." + }, + "id": 2499, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "returnData", + "nameLocation": "861:10:20", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 2493, + "nodeType": "ParameterList", + "parameters": [], + "src": "871:2:20" + }, + "returnParameters": { + "id": 2496, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2495, + "mutability": "mutable", + "name": "r", + "nameLocation": "910:1:20", + "nodeType": "VariableDeclaration", + "scope": 2499, + "src": "897:14:20", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 2494, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "897:5:20", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "896:16:20" + }, + "scope": 2530, + "src": "852:271:20", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": { + "id": 2514, + "nodeType": "Block", + "src": "1648:230:20", + "statements": [ + { + "AST": { + "nodeType": "YulBlock", + "src": "1663:211:20", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "1671:22:20", + "value": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1688:4:20", + "type": "", + "value": "0x40" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "1682:5:20" + }, + "nodeType": "YulFunctionCall", + "src": "1682:11:20" + }, + "variables": [ + { + "name": "tmp", + "nodeType": "YulTypedName", + "src": "1675:3:20", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "tmp", + "nodeType": "YulIdentifier", + "src": "1713:3:20" + }, + { + "name": "_data.offset", + "nodeType": "YulIdentifier", + "src": "1718:12:20" + }, + { + "name": "_data.length", + "nodeType": "YulIdentifier", + "src": "1732:12:20" + } + ], + "functionName": { + "name": "calldatacopy", + "nodeType": "YulIdentifier", + "src": "1700:12:20" + }, + "nodeType": "YulFunctionCall", + "src": "1700:45:20" + }, + "nodeType": "YulExpressionStatement", + "src": "1700:45:20" + }, + { + "nodeType": "YulAssignment", + "src": "1753:115:20", + "value": { + "arguments": [ + { + "name": "_gas", + "nodeType": "YulIdentifier", + "src": "1772:4:20" + }, + { + "name": "_to", + "nodeType": "YulIdentifier", + "src": "1786:3:20" + }, + { + "name": "_val", + "nodeType": "YulIdentifier", + "src": "1799:4:20" + }, + { + "name": "tmp", + "nodeType": "YulIdentifier", + "src": "1813:3:20" + }, + { + "name": "_data.length", + "nodeType": "YulIdentifier", + "src": "1826:12:20" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1848:1:20", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "1859:1:20", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "call", + "nodeType": "YulIdentifier", + "src": "1758:4:20" + }, + "nodeType": "YulFunctionCall", + "src": "1758:110:20" + }, + "variableNames": [ + { + "name": "r", + "nodeType": "YulIdentifier", + "src": "1753:1:20" + } + ] + } + ] + }, + "evmVersion": "paris", + "externalReferences": [ + { + "declaration": 2508, + "isOffset": false, + "isSlot": false, + "src": "1732:12:20", + "suffix": "length", + "valueSize": 1 + }, + { + "declaration": 2508, + "isOffset": false, + "isSlot": false, + "src": "1826:12:20", + "suffix": "length", + "valueSize": 1 + }, + { + "declaration": 2508, + "isOffset": true, + "isSlot": false, + "src": "1718:12:20", + "suffix": "offset", + "valueSize": 1 + }, + { + "declaration": 2506, + "isOffset": false, + "isSlot": false, + "src": "1772:4:20", + "valueSize": 1 + }, + { + "declaration": 2502, + "isOffset": false, + "isSlot": false, + "src": "1786:3:20", + "valueSize": 1 + }, + { + "declaration": 2504, + "isOffset": false, + "isSlot": false, + "src": "1799:4:20", + "valueSize": 1 + }, + { + "declaration": 2511, + "isOffset": false, + "isSlot": false, + "src": "1753:1:20", + "valueSize": 1 + } + ], + "id": 2513, + "nodeType": "InlineAssembly", + "src": "1654:220:20" + } + ] + }, + "documentation": { + "id": 2500, + "nodeType": "StructuredDocumentation", + "src": "1127:395:20", + "text": " @notice Calls another contract with the given parameters.\n @dev This method doesn't increase the memory pointer.\n @param _to The address of the contract to call.\n @param _val The value to send to the contract.\n @param _gas The amount of gas to provide for the call.\n @param _data The data to send to the contract.\n @return r The success status of the call." + }, + "id": 2515, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "call", + "nameLocation": "1534:4:20", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 2509, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2502, + "mutability": "mutable", + "name": "_to", + "nameLocation": "1552:3:20", + "nodeType": "VariableDeclaration", + "scope": 2515, + "src": "1544:11:20", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 2501, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1544:7:20", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2504, + "mutability": "mutable", + "name": "_val", + "nameLocation": "1569:4:20", + "nodeType": "VariableDeclaration", + "scope": 2515, + "src": "1561:12:20", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2503, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1561:7:20", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2506, + "mutability": "mutable", + "name": "_gas", + "nameLocation": "1587:4:20", + "nodeType": "VariableDeclaration", + "scope": 2515, + "src": "1579:12:20", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2505, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1579:7:20", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2508, + "mutability": "mutable", + "name": "_data", + "nameLocation": "1612:5:20", + "nodeType": "VariableDeclaration", + "scope": 2515, + "src": "1597:20:20", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 2507, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "1597:5:20", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "1538:83:20" + }, + "returnParameters": { + "id": 2512, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2511, + "mutability": "mutable", + "name": "r", + "nameLocation": "1645:1:20", + "nodeType": "VariableDeclaration", + "scope": 2515, + "src": "1640:6:20", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 2510, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "1640:4:20", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "src": "1639:8:20" + }, + "scope": 2530, + "src": "1525:353:20", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + }, + { + "body": { + "id": 2528, + "nodeType": "Block", + "src": "2361:224:20", + "statements": [ + { + "AST": { + "nodeType": "YulBlock", + "src": "2376:205:20", + "statements": [ + { + "nodeType": "YulVariableDeclaration", + "src": "2384:22:20", + "value": { + "arguments": [ + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2401:4:20", + "type": "", + "value": "0x40" + } + ], + "functionName": { + "name": "mload", + "nodeType": "YulIdentifier", + "src": "2395:5:20" + }, + "nodeType": "YulFunctionCall", + "src": "2395:11:20" + }, + "variables": [ + { + "name": "tmp", + "nodeType": "YulTypedName", + "src": "2388:3:20", + "type": "" + } + ] + }, + { + "expression": { + "arguments": [ + { + "name": "tmp", + "nodeType": "YulIdentifier", + "src": "2426:3:20" + }, + { + "name": "_data.offset", + "nodeType": "YulIdentifier", + "src": "2431:12:20" + }, + { + "name": "_data.length", + "nodeType": "YulIdentifier", + "src": "2445:12:20" + } + ], + "functionName": { + "name": "calldatacopy", + "nodeType": "YulIdentifier", + "src": "2413:12:20" + }, + "nodeType": "YulFunctionCall", + "src": "2413:45:20" + }, + "nodeType": "YulExpressionStatement", + "src": "2413:45:20" + }, + { + "nodeType": "YulAssignment", + "src": "2466:109:20", + "value": { + "arguments": [ + { + "name": "_gas", + "nodeType": "YulIdentifier", + "src": "2493:4:20" + }, + { + "name": "_to", + "nodeType": "YulIdentifier", + "src": "2507:3:20" + }, + { + "name": "tmp", + "nodeType": "YulIdentifier", + "src": "2520:3:20" + }, + { + "name": "_data.length", + "nodeType": "YulIdentifier", + "src": "2533:12:20" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2555:1:20", + "type": "", + "value": "0" + }, + { + "kind": "number", + "nodeType": "YulLiteral", + "src": "2566:1:20", + "type": "", + "value": "0" + } + ], + "functionName": { + "name": "delegatecall", + "nodeType": "YulIdentifier", + "src": "2471:12:20" + }, + "nodeType": "YulFunctionCall", + "src": "2471:104:20" + }, + "variableNames": [ + { + "name": "r", + "nodeType": "YulIdentifier", + "src": "2466:1:20" + } + ] + } + ] + }, + "evmVersion": "paris", + "externalReferences": [ + { + "declaration": 2522, + "isOffset": false, + "isSlot": false, + "src": "2445:12:20", + "suffix": "length", + "valueSize": 1 + }, + { + "declaration": 2522, + "isOffset": false, + "isSlot": false, + "src": "2533:12:20", + "suffix": "length", + "valueSize": 1 + }, + { + "declaration": 2522, + "isOffset": true, + "isSlot": false, + "src": "2431:12:20", + "suffix": "offset", + "valueSize": 1 + }, + { + "declaration": 2520, + "isOffset": false, + "isSlot": false, + "src": "2493:4:20", + "valueSize": 1 + }, + { + "declaration": 2518, + "isOffset": false, + "isSlot": false, + "src": "2507:3:20", + "valueSize": 1 + }, + { + "declaration": 2525, + "isOffset": false, + "isSlot": false, + "src": "2466:1:20", + "valueSize": 1 + } + ], + "id": 2527, + "nodeType": "InlineAssembly", + "src": "2367:214:20" + } + ] + }, + "documentation": { + "id": 2516, + "nodeType": "StructuredDocumentation", + "src": "1882:363:20", + "text": " @notice Calls another contract with the given parameters, using delegatecall.\n @dev This method doesn't increase the memory pointer.\n @param _to The address of the contract to call.\n @param _gas The amount of gas to provide for the call.\n @param _data The data to send to the contract.\n @return r The success status of the call." + }, + "id": 2529, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "delegatecall", + "nameLocation": "2257:12:20", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 2523, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2518, + "mutability": "mutable", + "name": "_to", + "nameLocation": "2283:3:20", + "nodeType": "VariableDeclaration", + "scope": 2529, + "src": "2275:11:20", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 2517, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "2275:7:20", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2520, + "mutability": "mutable", + "name": "_gas", + "nameLocation": "2300:4:20", + "nodeType": "VariableDeclaration", + "scope": 2529, + "src": "2292:12:20", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2519, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "2292:7:20", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2522, + "mutability": "mutable", + "name": "_data", + "nameLocation": "2325:5:20", + "nodeType": "VariableDeclaration", + "scope": 2529, + "src": "2310:20:20", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 2521, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "2310:5:20", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "2269:65:20" + }, + "returnParameters": { + "id": 2526, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2525, + "mutability": "mutable", + "name": "r", + "nameLocation": "2358:1:20", + "nodeType": "VariableDeclaration", + "scope": 2529, + "src": "2353:6:20", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 2524, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "2353:4:20", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "src": "2352:8:20" + }, + "scope": 2530, + "src": "2248:337:20", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + } + ], + "scope": 2531, + "src": "244:2343:20", + "usedErrors": [] + } + ], + "src": "39:2549:20" + }, + "id": 20 + }, + "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol": { + "ast": { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/SignatureValidator.sol", + "exportedSymbols": { + "IERC1271Wallet": [ + 22 + ], + "LibBytes": [ + 2374 + ], + "SignatureValidator": [ + 2798 + ] + }, + "id": 2799, + "license": "Apache-2.0", + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 2532, + "literals": [ + "solidity", + "0.8", + ".18" + ], + "nodeType": "PragmaDirective", + "src": "39:23:21" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/interfaces/IERC1271Wallet.sol", + "file": "../interfaces/IERC1271Wallet.sol", + "id": 2533, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 2799, + "sourceUnit": 23, + "src": "64:42:21", + "symbolAliases": [], + "unitAlias": "" + }, + { + "absolutePath": "sourcify-verified/1/0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE/sources/contracts/utils/LibBytes.sol", + "file": "./LibBytes.sol", + "id": 2534, + "nameLocation": "-1:-1:-1", + "nodeType": "ImportDirective", + "scope": 2799, + "sourceUnit": 2375, + "src": "108:24:21", + "symbolAliases": [], + "unitAlias": "" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "SignatureValidator", + "contractDependencies": [], + "contractKind": "library", + "documentation": { + "id": 2535, + "nodeType": "StructuredDocumentation", + "src": "134:295:21", + "text": " @dev Contains logic for signature validation.\n Signatures from wallet contracts assume ERC-1271 support (https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1271.md)\n Notes: Methods are strongly inspired by contracts in https://github.com/0xProject/0x-monorepo/blob/development/" + }, + "fullyImplemented": true, + "id": 2798, + "linearizedBaseContracts": [ + 2798 + ], + "name": "SignatureValidator", + "nameLocation": "438:18:21", + "nodeType": "ContractDefinition", + "nodes": [ + { + "errorSelector": "2ee17a3d", + "id": 2539, + "name": "InvalidSignatureLength", + "nameLocation": "479:22:21", + "nodeType": "ErrorDefinition", + "parameters": { + "id": 2538, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2537, + "mutability": "mutable", + "name": "_signature", + "nameLocation": "508:10:21", + "nodeType": "VariableDeclaration", + "scope": 2539, + "src": "502:16:21", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 2536, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "502:5:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "501:18:21" + }, + "src": "473:47:21" + }, + { + "errorSelector": "ac241e11", + "id": 2541, + "name": "EmptySignature", + "nameLocation": "529:14:21", + "nodeType": "ErrorDefinition", + "parameters": { + "id": 2540, + "nodeType": "ParameterList", + "parameters": [], + "src": "543:2:21" + }, + "src": "523:23:21" + }, + { + "errorSelector": "ad4aac76", + "id": 2547, + "name": "InvalidSValue", + "nameLocation": "555:13:21", + "nodeType": "ErrorDefinition", + "parameters": { + "id": 2546, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2543, + "mutability": "mutable", + "name": "_signature", + "nameLocation": "575:10:21", + "nodeType": "VariableDeclaration", + "scope": 2547, + "src": "569:16:21", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 2542, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "569:5:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2545, + "mutability": "mutable", + "name": "_s", + "nameLocation": "595:2:21", + "nodeType": "VariableDeclaration", + "scope": 2547, + "src": "587:10:21", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 2544, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "587:7:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "src": "568:30:21" + }, + "src": "549:50:21" + }, + { + "errorSelector": "e578897e", + "id": 2553, + "name": "InvalidVValue", + "nameLocation": "608:13:21", + "nodeType": "ErrorDefinition", + "parameters": { + "id": 2552, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2549, + "mutability": "mutable", + "name": "_signature", + "nameLocation": "628:10:21", + "nodeType": "VariableDeclaration", + "scope": 2553, + "src": "622:16:21", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 2548, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "622:5:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2551, + "mutability": "mutable", + "name": "_v", + "nameLocation": "648:2:21", + "nodeType": "VariableDeclaration", + "scope": 2553, + "src": "640:10:21", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2550, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "640:7:21", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "621:30:21" + }, + "src": "602:50:21" + }, + { + "errorSelector": "9dfba852", + "id": 2561, + "name": "UnsupportedSignatureType", + "nameLocation": "661:24:21", + "nodeType": "ErrorDefinition", + "parameters": { + "id": 2560, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2555, + "mutability": "mutable", + "name": "_signature", + "nameLocation": "692:10:21", + "nodeType": "VariableDeclaration", + "scope": 2561, + "src": "686:16:21", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 2554, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "686:5:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2557, + "mutability": "mutable", + "name": "_type", + "nameLocation": "712:5:21", + "nodeType": "VariableDeclaration", + "scope": 2561, + "src": "704:13:21", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2556, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "704:7:21", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2559, + "mutability": "mutable", + "name": "_recoverMode", + "nameLocation": "724:12:21", + "nodeType": "VariableDeclaration", + "scope": 2561, + "src": "719:17:21", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 2558, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "719:4:21", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "src": "685:52:21" + }, + "src": "655:83:21" + }, + { + "errorSelector": "6c1719d2", + "id": 2565, + "name": "SignerIsAddress0", + "nameLocation": "747:16:21", + "nodeType": "ErrorDefinition", + "parameters": { + "id": 2564, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2563, + "mutability": "mutable", + "name": "_signature", + "nameLocation": "770:10:21", + "nodeType": "VariableDeclaration", + "scope": 2565, + "src": "764:16:21", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 2562, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "764:5:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "763:18:21" + }, + "src": "741:41:21" + }, + { + "global": false, + "id": 2568, + "libraryName": { + "id": 2566, + "name": "LibBytes", + "nameLocations": [ + "792:8:21" + ], + "nodeType": "IdentifierPath", + "referencedDeclaration": 2374, + "src": "792:8:21" + }, + "nodeType": "UsingForDirective", + "src": "786:25:21", + "typeName": { + "id": 2567, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "805:5:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + } + }, + { + "constant": true, + "id": 2571, + "mutability": "constant", + "name": "ERC1271_MAGICVALUE", + "nameLocation": "1017:18:21", + "nodeType": "VariableDeclaration", + "scope": 2798, + "src": "992:56:21", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + }, + "typeName": { + "id": 2569, + "name": "bytes4", + "nodeType": "ElementaryTypeName", + "src": "992:6:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "value": { + "hexValue": "30783230633133623062", + "id": 2570, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1038:10:21", + "typeDescriptions": { + "typeIdentifier": "t_rational_549534475_by_1", + "typeString": "int_const 549534475" + }, + "value": "0x20c13b0b" + }, + "visibility": "internal" + }, + { + "constant": true, + "id": 2574, + "mutability": "constant", + "name": "ERC1271_MAGICVALUE_BYTES32", + "nameLocation": "1136:26:21", + "nodeType": "VariableDeclaration", + "scope": 2798, + "src": "1111:64:21", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + }, + "typeName": { + "id": 2572, + "name": "bytes4", + "nodeType": "ElementaryTypeName", + "src": "1111:6:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "value": { + "hexValue": "30783136323662613765", + "id": 2573, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1165:10:21", + "typeDescriptions": { + "typeIdentifier": "t_rational_371636862_by_1", + "typeString": "int_const 371636862" + }, + "value": "0x1626ba7e" + }, + "visibility": "internal" + }, + { + "constant": true, + "id": 2577, + "mutability": "constant", + "name": "SIG_TYPE_EIP712", + "nameLocation": "1235:15:21", + "nodeType": "VariableDeclaration", + "scope": 2798, + "src": "1210:44:21", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2575, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1210:7:21", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": { + "hexValue": "31", + "id": 2576, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1253:1:21", + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "visibility": "private" + }, + { + "constant": true, + "id": 2580, + "mutability": "constant", + "name": "SIG_TYPE_ETH_SIGN", + "nameLocation": "1283:17:21", + "nodeType": "VariableDeclaration", + "scope": 2798, + "src": "1258:46:21", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2578, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1258:7:21", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": { + "hexValue": "32", + "id": 2579, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1303:1:21", + "typeDescriptions": { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + }, + "visibility": "private" + }, + { + "constant": true, + "id": 2583, + "mutability": "constant", + "name": "SIG_TYPE_WALLET_BYTES32", + "nameLocation": "1333:23:21", + "nodeType": "VariableDeclaration", + "scope": 2798, + "src": "1308:52:21", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2581, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1308:7:21", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": { + "hexValue": "33", + "id": 2582, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1359:1:21", + "typeDescriptions": { + "typeIdentifier": "t_rational_3_by_1", + "typeString": "int_const 3" + }, + "value": "3" + }, + "visibility": "private" + }, + { + "body": { + "id": 2714, + "nodeType": "Block", + "src": "1883:2200:21", + "statements": [ + { + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2596, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "expression": { + "id": 2593, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2588, + "src": "1893:10:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "id": 2594, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "1904:6:21", + "memberName": "length", + "nodeType": "MemberAccess", + "src": "1893:17:21", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "hexValue": "3636", + "id": 2595, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "1914:2:21", + "typeDescriptions": { + "typeIdentifier": "t_rational_66_by_1", + "typeString": "int_const 66" + }, + "value": "66" + }, + "src": "1893:23:21", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 2601, + "nodeType": "IfStatement", + "src": "1889:70:21", + "trueBody": { + "errorCall": { + "arguments": [ + { + "id": 2598, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2588, + "src": "1948:10:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + ], + "id": 2597, + "name": "InvalidSignatureLength", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2539, + "src": "1925:22:21", + "typeDescriptions": { + "typeIdentifier": "t_function_error_pure$_t_bytes_memory_ptr_$returns$__$", + "typeString": "function (bytes memory) pure" + } + }, + "id": 2599, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1925:34:21", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2600, + "nodeType": "RevertStatement", + "src": "1918:41:21" + } + }, + { + "assignments": [ + 2603 + ], + "declarations": [ + { + "constant": false, + "id": 2603, + "mutability": "mutable", + "name": "signatureType", + "nameLocation": "1973:13:21", + "nodeType": "VariableDeclaration", + "scope": 2714, + "src": "1965:21:21", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2602, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "1965:7:21", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 2611, + "initialValue": { + "arguments": [ + { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2609, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "expression": { + "id": 2606, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2588, + "src": "2010:10:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "id": 2607, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2021:6:21", + "memberName": "length", + "nodeType": "MemberAccess", + "src": "2010:17:21", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": { + "hexValue": "31", + "id": 2608, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "2030:1:21", + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "2010:21:21", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + ], + "expression": { + "id": 2604, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2588, + "src": "1989:10:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "id": 2605, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2000:9:21", + "memberName": "readUint8", + "nodeType": "MemberAccess", + "referencedDeclaration": 2351, + "src": "1989:20:21", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes_calldata_ptr_$_t_uint256_$returns$_t_uint8_$attached_to$_t_bytes_calldata_ptr_$", + "typeString": "function (bytes calldata,uint256) pure returns (uint8)" + } + }, + "id": 2610, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "1989:43:21", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "1965:67:21" + }, + { + "assignments": [ + 2613 + ], + "declarations": [ + { + "constant": false, + "id": 2613, + "mutability": "mutable", + "name": "v", + "nameLocation": "2090:1:21", + "nodeType": "VariableDeclaration", + "scope": 2714, + "src": "2084:7:21", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": { + "id": 2612, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "2084:5:21", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "visibility": "internal" + } + ], + "id": 2618, + "initialValue": { + "arguments": [ + { + "hexValue": "3634", + "id": 2616, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "2115:2:21", + "typeDescriptions": { + "typeIdentifier": "t_rational_64_by_1", + "typeString": "int_const 64" + }, + "value": "64" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_64_by_1", + "typeString": "int_const 64" + } + ], + "expression": { + "id": 2614, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2588, + "src": "2094:10:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "id": 2615, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2105:9:21", + "memberName": "readUint8", + "nodeType": "MemberAccess", + "referencedDeclaration": 2351, + "src": "2094:20:21", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes_calldata_ptr_$_t_uint256_$returns$_t_uint8_$attached_to$_t_bytes_calldata_ptr_$", + "typeString": "function (bytes calldata,uint256) pure returns (uint8)" + } + }, + "id": 2617, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2094:24:21", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "2084:34:21" + }, + { + "assignments": [ + 2620 + ], + "declarations": [ + { + "constant": false, + "id": 2620, + "mutability": "mutable", + "name": "r", + "nameLocation": "2132:1:21", + "nodeType": "VariableDeclaration", + "scope": 2714, + "src": "2124:9:21", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 2619, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2124:7:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "id": 2625, + "initialValue": { + "arguments": [ + { + "hexValue": "30", + "id": 2623, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "2159:1:21", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "expression": { + "id": 2621, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2588, + "src": "2136:10:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "id": 2622, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2147:11:21", + "memberName": "readBytes32", + "nodeType": "MemberAccess", + "referencedDeclaration": 2339, + "src": "2136:22:21", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes_calldata_ptr_$_t_uint256_$returns$_t_bytes32_$attached_to$_t_bytes_calldata_ptr_$", + "typeString": "function (bytes calldata,uint256) pure returns (bytes32)" + } + }, + "id": 2624, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2136:25:21", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "2124:37:21" + }, + { + "assignments": [ + 2627 + ], + "declarations": [ + { + "constant": false, + "id": 2627, + "mutability": "mutable", + "name": "s", + "nameLocation": "2175:1:21", + "nodeType": "VariableDeclaration", + "scope": 2714, + "src": "2167:9:21", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 2626, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "2167:7:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + } + ], + "id": 2632, + "initialValue": { + "arguments": [ + { + "hexValue": "3332", + "id": 2630, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "2202:2:21", + "typeDescriptions": { + "typeIdentifier": "t_rational_32_by_1", + "typeString": "int_const 32" + }, + "value": "32" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_32_by_1", + "typeString": "int_const 32" + } + ], + "expression": { + "id": 2628, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2588, + "src": "2179:10:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "id": 2629, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "2190:11:21", + "memberName": "readBytes32", + "nodeType": "MemberAccess", + "referencedDeclaration": 2339, + "src": "2179:22:21", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes_calldata_ptr_$_t_uint256_$returns$_t_bytes32_$attached_to$_t_bytes_calldata_ptr_$", + "typeString": "function (bytes calldata,uint256) pure returns (bytes32)" + } + }, + "id": 2631, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "2179:26:21", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "2167:38:21" + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2638, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "arguments": [ + { + "id": 2635, + "name": "s", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2627, + "src": "3204:1:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 2634, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "3196:7:21", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint256_$", + "typeString": "type(uint256)" + }, + "typeName": { + "id": 2633, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "3196:7:21", + "typeDescriptions": {} + } + }, + "id": 2636, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3196:10:21", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": ">", + "rightExpression": { + "hexValue": "307837464646464646464646464646464646464646464646464646464646464646463544353736453733353741343530314444464539324634363638314232304130", + "id": 2637, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "3209:66:21", + "typeDescriptions": { + "typeIdentifier": "t_rational_57896044618658097711785492504343953926418782139537452191302581570759080747168_by_1", + "typeString": "int_const 5789...(69 digits omitted)...7168" + }, + "value": "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0" + }, + "src": "3196:79:21", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 2645, + "nodeType": "IfStatement", + "src": "3192:135:21", + "trueBody": { + "id": 2644, + "nodeType": "Block", + "src": "3277:50:21", + "statements": [ + { + "errorCall": { + "arguments": [ + { + "id": 2640, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2588, + "src": "3306:10:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + { + "id": 2641, + "name": "s", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2627, + "src": "3318:1:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 2639, + "name": "InvalidSValue", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2547, + "src": "3292:13:21", + "typeDescriptions": { + "typeIdentifier": "t_function_error_pure$_t_bytes_memory_ptr_$_t_bytes32_$returns$__$", + "typeString": "function (bytes memory,bytes32) pure" + } + }, + "id": 2642, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3292:28:21", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2643, + "nodeType": "RevertStatement", + "src": "3285:35:21" + } + ] + } + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 2652, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "commonType": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "id": 2648, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 2646, + "name": "v", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2613, + "src": "3337:1:21", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "hexValue": "3237", + "id": 2647, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "3342:2:21", + "typeDescriptions": { + "typeIdentifier": "t_rational_27_by_1", + "typeString": "int_const 27" + }, + "value": "27" + }, + "src": "3337:7:21", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "&&", + "rightExpression": { + "commonType": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "id": 2651, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 2649, + "name": "v", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2613, + "src": "3348:1:21", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "nodeType": "BinaryOperation", + "operator": "!=", + "rightExpression": { + "hexValue": "3238", + "id": 2650, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "3353:2:21", + "typeDescriptions": { + "typeIdentifier": "t_rational_28_by_1", + "typeString": "int_const 28" + }, + "value": "28" + }, + "src": "3348:7:21", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "3337:18:21", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 2659, + "nodeType": "IfStatement", + "src": "3333:74:21", + "trueBody": { + "id": 2658, + "nodeType": "Block", + "src": "3357:50:21", + "statements": [ + { + "errorCall": { + "arguments": [ + { + "id": 2654, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2588, + "src": "3386:10:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + { + "id": 2655, + "name": "v", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2613, + "src": "3398:1:21", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + }, + { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + ], + "id": 2653, + "name": "InvalidVValue", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2553, + "src": "3372:13:21", + "typeDescriptions": { + "typeIdentifier": "t_function_error_pure$_t_bytes_memory_ptr_$_t_uint256_$returns$__$", + "typeString": "function (bytes memory,uint256) pure" + } + }, + "id": 2656, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3372:28:21", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2657, + "nodeType": "RevertStatement", + "src": "3365:35:21" + } + ] + } + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2662, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 2660, + "name": "signatureType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2603, + "src": "3447:13:21", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "id": 2661, + "name": "SIG_TYPE_EIP712", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2577, + "src": "3464:15:21", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "3447:32:21", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": { + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2675, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 2673, + "name": "signatureType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2603, + "src": "3608:13:21", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "id": 2674, + "name": "SIG_TYPE_ETH_SIGN", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2580, + "src": "3625:17:21", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "3608:34:21", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": { + "id": 2698, + "nodeType": "Block", + "src": "3805:147:21", + "statements": [ + { + "errorCall": { + "arguments": [ + { + "id": 2693, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2588, + "src": "3913:10:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + { + "id": 2694, + "name": "signatureType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2603, + "src": "3925:13:21", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "hexValue": "74727565", + "id": 2695, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "3940:4:21", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "true" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 2692, + "name": "UnsupportedSignatureType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2561, + "src": "3888:24:21", + "typeDescriptions": { + "typeIdentifier": "t_function_error_pure$_t_bytes_memory_ptr_$_t_uint256_$_t_bool_$returns$__$", + "typeString": "function (bytes memory,uint256,bool) pure" + } + }, + "id": 2696, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3888:57:21", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2697, + "nodeType": "RevertStatement", + "src": "3881:64:21" + } + ] + }, + "id": 2699, + "nodeType": "IfStatement", + "src": "3604:348:21", + "trueBody": { + "id": 2691, + "nodeType": "Block", + "src": "3644:155:21", + "statements": [ + { + "expression": { + "id": 2689, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 2676, + "name": "signer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2591, + "src": "3652:6:21", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "arguments": [ + { + "arguments": [ + { + "hexValue": "19457468657265756d205369676e6564204d6573736167653a0a3332", + "id": 2681, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "3707:34:21", + "typeDescriptions": { + "typeIdentifier": "t_stringliteral_178a2411ab6fbc1ba11064408972259c558d0e82fd48b0aba3ad81d14f065e73", + "typeString": "literal_string hex\"19457468657265756d205369676e6564204d6573736167653a0a3332\"" + }, + "value": "\u0019Ethereum Signed Message:\n32" + }, + { + "id": 2682, + "name": "_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2586, + "src": "3743:5:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_stringliteral_178a2411ab6fbc1ba11064408972259c558d0e82fd48b0aba3ad81d14f065e73", + "typeString": "literal_string hex\"19457468657265756d205369676e6564204d6573736167653a0a3332\"" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "expression": { + "id": 2679, + "name": "abi", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967295, + "src": "3690:3:21", + "typeDescriptions": { + "typeIdentifier": "t_magic_abi", + "typeString": "abi" + } + }, + "id": 2680, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "memberLocation": "3694:12:21", + "memberName": "encodePacked", + "nodeType": "MemberAccess", + "src": "3690:16:21", + "typeDescriptions": { + "typeIdentifier": "t_function_abiencodepacked_pure$__$returns$_t_bytes_memory_ptr_$", + "typeString": "function () pure returns (bytes memory)" + } + }, + "id": 2683, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3690:59:21", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_memory_ptr", + "typeString": "bytes memory" + } + ], + "id": 2678, + "name": "keccak256", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967288, + "src": "3680:9:21", + "typeDescriptions": { + "typeIdentifier": "t_function_keccak256_pure$_t_bytes_memory_ptr_$returns$_t_bytes32_$", + "typeString": "function (bytes memory) pure returns (bytes32)" + } + }, + "id": 2684, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3680:70:21", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 2685, + "name": "v", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2613, + "src": "3760:1:21", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + { + "id": 2686, + "name": "r", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2620, + "src": "3771:1:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 2687, + "name": "s", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2627, + "src": "3782:1:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 2677, + "name": "ecrecover", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967290, + "src": "3661:9:21", + "typeDescriptions": { + "typeIdentifier": "t_function_ecrecover_pure$_t_bytes32_$_t_uint8_$_t_bytes32_$_t_bytes32_$returns$_t_address_$", + "typeString": "function (bytes32,uint8,bytes32,bytes32) pure returns (address)" + } + }, + "id": 2688, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3661:130:21", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "3652:139:21", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 2690, + "nodeType": "ExpressionStatement", + "src": "3652:139:21" + } + ] + } + }, + "id": 2700, + "nodeType": "IfStatement", + "src": "3443:509:21", + "trueBody": { + "id": 2672, + "nodeType": "Block", + "src": "3481:117:21", + "statements": [ + { + "expression": { + "id": 2670, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 2663, + "name": "signer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2591, + "src": "3489:6:21", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "arguments": [ + { + "id": 2665, + "name": "_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2586, + "src": "3508:5:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 2666, + "name": "v", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2613, + "src": "3515:1:21", + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + { + "id": 2667, + "name": "r", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2620, + "src": "3518:1:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 2668, + "name": "s", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2627, + "src": "3521:1:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + ], + "id": 2664, + "name": "ecrecover", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4294967290, + "src": "3498:9:21", + "typeDescriptions": { + "typeIdentifier": "t_function_ecrecover_pure$_t_bytes32_$_t_uint8_$_t_bytes32_$_t_bytes32_$returns$_t_address_$", + "typeString": "function (bytes32,uint8,bytes32,bytes32) pure returns (address)" + } + }, + "id": 2669, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "3498:25:21", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "3489:34:21", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "id": 2671, + "nodeType": "ExpressionStatement", + "src": "3489:34:21" + } + ] + } + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 2706, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 2701, + "name": "signer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2591, + "src": "3999:6:21", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "arguments": [ + { + "hexValue": "307830", + "id": 2704, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4017:3:21", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0x0" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 2703, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "4009:7:21", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": { + "id": 2702, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "4009:7:21", + "typeDescriptions": {} + } + }, + "id": 2705, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "4009:12:21", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "3999:22:21", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 2711, + "nodeType": "IfStatement", + "src": "3995:63:21", + "trueBody": { + "errorCall": { + "arguments": [ + { + "id": 2708, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2588, + "src": "4047:10:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + ], + "id": 2707, + "name": "SignerIsAddress0", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2565, + "src": "4030:16:21", + "typeDescriptions": { + "typeIdentifier": "t_function_error_pure$_t_bytes_memory_ptr_$returns$__$", + "typeString": "function (bytes memory) pure" + } + }, + "id": 2709, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "4030:28:21", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2710, + "nodeType": "RevertStatement", + "src": "4023:35:21" + } + }, + { + "expression": { + "id": 2712, + "name": "signer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2591, + "src": "4072:6:21", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "functionReturnParameters": 2592, + "id": 2713, + "nodeType": "Return", + "src": "4065:13:21" + } + ] + }, + "documentation": { + "id": 2584, + "nodeType": "StructuredDocumentation", + "src": "1485:279:21", + "text": " @notice Recover the signer of hash, assuming it's an EOA account\n @dev Only for SignatureType.EIP712 and SignatureType.EthSign signatures\n @param _hash Hash that was signed\n encoded as (bytes32 r, bytes32 s, uint8 v, ... , SignatureType sigType)" + }, + "id": 2715, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "recoverSigner", + "nameLocation": "1776:13:21", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 2589, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2586, + "mutability": "mutable", + "name": "_hash", + "nameLocation": "1803:5:21", + "nodeType": "VariableDeclaration", + "scope": 2715, + "src": "1795:13:21", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 2585, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "1795:7:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2588, + "mutability": "mutable", + "name": "_signature", + "nameLocation": "1829:10:21", + "nodeType": "VariableDeclaration", + "scope": 2715, + "src": "1814:25:21", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 2587, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "1814:5:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "1789:54:21" + }, + "returnParameters": { + "id": 2592, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2591, + "mutability": "mutable", + "name": "signer", + "nameLocation": "1875:6:21", + "nodeType": "VariableDeclaration", + "scope": 2715, + "src": "1867:14:21", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 2590, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "1867:7:21", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + } + ], + "src": "1866:16:21" + }, + "scope": 2798, + "src": "1767:2316:21", + "stateMutability": "pure", + "virtual": false, + "visibility": "internal" + }, + { + "body": { + "id": 2796, + "nodeType": "Block", + "src": "4547:815:21", + "statements": [ + { + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2730, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "expression": { + "id": 2727, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2722, + "src": "4557:10:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "id": 2728, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "4568:6:21", + "memberName": "length", + "nodeType": "MemberAccess", + "src": "4557:17:21", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "hexValue": "30", + "id": 2729, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4578:1:21", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "src": "4557:22:21", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 2735, + "nodeType": "IfStatement", + "src": "4553:66:21", + "trueBody": { + "id": 2734, + "nodeType": "Block", + "src": "4581:38:21", + "statements": [ + { + "errorCall": { + "arguments": [], + "expression": { + "argumentTypes": [], + "id": 2731, + "name": "EmptySignature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2541, + "src": "4596:14:21", + "typeDescriptions": { + "typeIdentifier": "t_function_error_pure$__$returns$__$", + "typeString": "function () pure" + } + }, + "id": 2732, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "4596:16:21", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2733, + "nodeType": "RevertStatement", + "src": "4589:23:21" + } + ] + } + }, + { + "assignments": [ + 2737 + ], + "declarations": [ + { + "constant": false, + "id": 2737, + "mutability": "mutable", + "name": "signatureType", + "nameLocation": "4633:13:21", + "nodeType": "VariableDeclaration", + "scope": 2796, + "src": "4625:21:21", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2736, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "4625:7:21", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "id": 2747, + "initialValue": { + "arguments": [ + { + "baseExpression": { + "id": 2740, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2722, + "src": "4655:10:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "id": 2745, + "indexExpression": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2744, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "expression": { + "id": 2741, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2722, + "src": "4666:10:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "id": 2742, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "4677:6:21", + "memberName": "length", + "nodeType": "MemberAccess", + "src": "4666:17:21", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": { + "hexValue": "31", + "id": 2743, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "4686:1:21", + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "4666:21:21", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "4655:33:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes1", + "typeString": "bytes1" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes1", + "typeString": "bytes1" + } + ], + "id": 2739, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "4649:5:21", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_uint8_$", + "typeString": "type(uint8)" + }, + "typeName": { + "id": 2738, + "name": "uint8", + "nodeType": "ElementaryTypeName", + "src": "4649:5:21", + "typeDescriptions": {} + } + }, + "id": 2746, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "4649:40:21", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "4625:64:21" + }, + { + "condition": { + "commonType": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "id": 2754, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2750, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 2748, + "name": "signatureType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2737, + "src": "4699:13:21", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "id": 2749, + "name": "SIG_TYPE_EIP712", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2577, + "src": "4716:15:21", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "4699:32:21", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "BinaryOperation", + "operator": "||", + "rightExpression": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2753, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 2751, + "name": "signatureType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2737, + "src": "4735:13:21", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "id": 2752, + "name": "SIG_TYPE_ETH_SIGN", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2580, + "src": "4752:17:21", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "4735:34:21", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "4699:70:21", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": { + "condition": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2767, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 2765, + "name": "signatureType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2737, + "src": "4898:13:21", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "id": 2766, + "name": "SIG_TYPE_WALLET_BYTES32", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2583, + "src": "4915:23:21", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "src": "4898:40:21", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "falseBody": { + "id": 2793, + "nodeType": "Block", + "src": "5158:200:21", + "statements": [ + { + "errorCall": { + "arguments": [ + { + "id": 2788, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2722, + "src": "5318:10:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + { + "id": 2789, + "name": "signatureType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2737, + "src": "5330:13:21", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + { + "hexValue": "66616c7365", + "id": 2790, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "bool", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5345:5:21", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "value": "false" + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + }, + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + ], + "id": 2787, + "name": "UnsupportedSignatureType", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2561, + "src": "5293:24:21", + "typeDescriptions": { + "typeIdentifier": "t_function_error_pure$_t_bytes_memory_ptr_$_t_uint256_$_t_bool_$returns$__$", + "typeString": "function (bytes memory,uint256,bool) pure" + } + }, + "id": 2791, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "5293:58:21", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_tuple$__$", + "typeString": "tuple()" + } + }, + "id": 2792, + "nodeType": "RevertStatement", + "src": "5286:65:21" + } + ] + }, + "id": 2794, + "nodeType": "IfStatement", + "src": "4894:464:21", + "trueBody": { + "id": 2786, + "nodeType": "Block", + "src": "4940:212:21", + "statements": [ + { + "expression": { + "id": 2784, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 2768, + "name": "valid", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2725, + "src": "5022:5:21", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "commonType": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + }, + "id": 2783, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "id": 2769, + "name": "ERC1271_MAGICVALUE_BYTES32", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2574, + "src": "5030:26:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "arguments": [ + { + "id": 2774, + "name": "_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2718, + "src": "5101:5:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "baseExpression": { + "id": 2775, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2722, + "src": "5108:10:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "endExpression": { + "commonType": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "id": 2780, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "expression": { + "id": 2777, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2722, + "src": "5121:10:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + }, + "id": 2778, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "5132:6:21", + "memberName": "length", + "nodeType": "MemberAccess", + "src": "5121:17:21", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "nodeType": "BinaryOperation", + "operator": "-", + "rightExpression": { + "hexValue": "31", + "id": 2779, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5141:1:21", + "typeDescriptions": { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + }, + "src": "5121:21:21", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2781, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexRangeAccess", + "src": "5108:35:21", + "startExpression": { + "hexValue": "30", + "id": 2776, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "5119:1:21", + "typeDescriptions": { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + }, + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr_slice", + "typeString": "bytes calldata slice" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes_calldata_ptr_slice", + "typeString": "bytes calldata slice" + } + ], + "expression": { + "arguments": [ + { + "id": 2771, + "name": "_signer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2720, + "src": "5075:7:21", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_address", + "typeString": "address" + } + ], + "id": 2770, + "name": "IERC1271Wallet", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22, + "src": "5060:14:21", + "typeDescriptions": { + "typeIdentifier": "t_type$_t_contract$_IERC1271Wallet_$22_$", + "typeString": "type(contract IERC1271Wallet)" + } + }, + "id": 2772, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "5060:23:21", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_contract$_IERC1271Wallet_$22", + "typeString": "contract IERC1271Wallet" + } + }, + "id": 2773, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "memberLocation": "5084:16:21", + "memberName": "isValidSignature", + "nodeType": "MemberAccess", + "referencedDeclaration": 21, + "src": "5060:40:21", + "typeDescriptions": { + "typeIdentifier": "t_function_external_view$_t_bytes32_$_t_bytes_memory_ptr_$returns$_t_bytes4_$", + "typeString": "function (bytes32,bytes memory) view external returns (bytes4)" + } + }, + "id": 2782, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "5060:84:21", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_bytes4", + "typeString": "bytes4" + } + }, + "src": "5030:114:21", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "5022:122:21", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 2785, + "nodeType": "ExpressionStatement", + "src": "5022:122:21" + } + ] + } + }, + "id": 2795, + "nodeType": "IfStatement", + "src": "4695:663:21", + "trueBody": { + "id": 2764, + "nodeType": "Block", + "src": "4771:117:21", + "statements": [ + { + "expression": { + "id": 2762, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": { + "id": 2755, + "name": "valid", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2725, + "src": "4829:5:21", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": { + "commonType": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "id": 2761, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftExpression": { + "arguments": [ + { + "id": 2757, + "name": "_hash", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2718, + "src": "4851:5:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + { + "id": 2758, + "name": "_signature", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2722, + "src": "4858:10:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + } + ], + "expression": { + "argumentTypes": [ + { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes calldata" + } + ], + "id": 2756, + "name": "recoverSigner", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2715, + "src": "4837:13:21", + "typeDescriptions": { + "typeIdentifier": "t_function_internal_pure$_t_bytes32_$_t_bytes_calldata_ptr_$returns$_t_address_$", + "typeString": "function (bytes32,bytes calldata) pure returns (address)" + } + }, + "id": 2759, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "functionCall", + "lValueRequested": false, + "nameLocations": [], + "names": [], + "nodeType": "FunctionCall", + "src": "4837:32:21", + "tryCall": false, + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "BinaryOperation", + "operator": "==", + "rightExpression": { + "id": 2760, + "name": "_signer", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 2720, + "src": "4873:7:21", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "src": "4837:43:21", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "src": "4829:51:21", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "id": 2763, + "nodeType": "ExpressionStatement", + "src": "4829:51:21" + } + ] + } + } + ] + }, + "documentation": { + "id": 2716, + "nodeType": "StructuredDocumentation", + "src": "4086:322:21", + "text": " @notice Returns true if the provided signature is valid for the given signer.\n @dev Supports SignatureType.EIP712, SignatureType.EthSign, and ERC1271 signatures\n @param _hash Hash that was signed\n @param _signer Address of the signer candidate\n @param _signature Signature byte array" + }, + "id": 2797, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "isValidSignature", + "nameLocation": "4420:16:21", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 2723, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2718, + "mutability": "mutable", + "name": "_hash", + "nameLocation": "4450:5:21", + "nodeType": "VariableDeclaration", + "scope": 2797, + "src": "4442:13:21", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + }, + "typeName": { + "id": 2717, + "name": "bytes32", + "nodeType": "ElementaryTypeName", + "src": "4442:7:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes32", + "typeString": "bytes32" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2720, + "mutability": "mutable", + "name": "_signer", + "nameLocation": "4469:7:21", + "nodeType": "VariableDeclaration", + "scope": 2797, + "src": "4461:15:21", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": { + "id": 2719, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "4461:7:21", + "stateMutability": "nonpayable", + "typeDescriptions": { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "visibility": "internal" + }, + { + "constant": false, + "id": 2722, + "mutability": "mutable", + "name": "_signature", + "nameLocation": "4497:10:21", + "nodeType": "VariableDeclaration", + "scope": 2797, + "src": "4482:25:21", + "stateVariable": false, + "storageLocation": "calldata", + "typeDescriptions": { + "typeIdentifier": "t_bytes_calldata_ptr", + "typeString": "bytes" + }, + "typeName": { + "id": 2721, + "name": "bytes", + "nodeType": "ElementaryTypeName", + "src": "4482:5:21", + "typeDescriptions": { + "typeIdentifier": "t_bytes_storage_ptr", + "typeString": "bytes" + } + }, + "visibility": "internal" + } + ], + "src": "4436:75:21" + }, + "returnParameters": { + "id": 2726, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 2725, + "mutability": "mutable", + "name": "valid", + "nameLocation": "4540:5:21", + "nodeType": "VariableDeclaration", + "scope": 2797, + "src": "4535:10:21", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + }, + "typeName": { + "id": 2724, + "name": "bool", + "nodeType": "ElementaryTypeName", + "src": "4535:4:21", + "typeDescriptions": { + "typeIdentifier": "t_bool", + "typeString": "bool" + } + }, + "visibility": "internal" + } + ], + "src": "4534:12:21" + }, + "scope": 2798, + "src": "4411:951:21", + "stateMutability": "view", + "virtual": false, + "visibility": "internal" + } + ], + "scope": 2799, + "src": "430:4934:21", + "usedErrors": [ + 2539, + 2541, + 2547, + 2553, + 2561, + 2565 + ] + } + ], + "src": "39:5326:21" + }, + "id": 21 + } + } + } +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/ModuleAuth.sol b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/ModuleAuth.sol new file mode 100644 index 0000000000..f696777ca4 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/ModuleAuth.sol @@ -0,0 +1,176 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "../../utils/LibBytes.sol"; +import "../../interfaces/IERC1271Wallet.sol"; + +import "./interfaces/IModuleAuth.sol"; + +import "./ModuleERC165.sol"; + +import "./submodules/auth/SequenceBaseSig.sol"; +import "./submodules/auth/SequenceDynamicSig.sol"; +import "./submodules/auth/SequenceNoChainIdSig.sol"; +import "./submodules/auth/SequenceChainedSig.sol"; + + +abstract contract ModuleAuth is + IModuleAuth, + ModuleERC165, + IERC1271Wallet, + SequenceChainedSig +{ + using LibBytes for bytes; + + bytes1 internal constant LEGACY_TYPE = hex"00"; + bytes1 internal constant DYNAMIC_TYPE = hex"01"; + bytes1 internal constant NO_CHAIN_ID_TYPE = hex"02"; + bytes1 internal constant CHAINED_TYPE = hex"03"; + + bytes4 internal constant SELECTOR_ERC1271_BYTES_BYTES = 0x20c13b0b; + bytes4 internal constant SELECTOR_ERC1271_BYTES32_BYTES = 0x1626ba7e; + + /** + * @notice Recovers the threshold, weight, imageHash, subdigest, and checkpoint of a signature. + * @dev The signature must be prefixed with a type byte, which is used to determine the recovery method. + * + * @param _digest Digest of the signed data. + * @param _signature A Sequence signature. + * + * @return threshold The required number of signatures needed to consider the signature valid. + * @return weight The actual number of signatures collected in the signature. + * @return imageHash The imageHash of the configuration that signed the message. + * @return subdigest A modified version of the original digest, unique for each wallet/network. + * @return checkpoint A nonce that is incremented every time a new configuration is set. + */ + function signatureRecovery( + bytes32 _digest, + bytes calldata _signature + ) public override virtual view returns ( + uint256 threshold, + uint256 weight, + bytes32 imageHash, + bytes32 subdigest, + uint256 checkpoint + ) { + bytes1 signatureType = _signature[0]; + + if (signatureType == LEGACY_TYPE) { + // networkId digest + base recover + subdigest = SequenceBaseSig.subdigest(_digest); + (threshold, weight, imageHash, checkpoint) = SequenceBaseSig.recover(subdigest, _signature); + return (threshold, weight, imageHash, subdigest, checkpoint); + } + + if (signatureType == DYNAMIC_TYPE) { + // networkId digest + dynamic recover + subdigest = SequenceBaseSig.subdigest(_digest); + (threshold, weight, imageHash, checkpoint) = SequenceDynamicSig.recover(subdigest, _signature); + return (threshold, weight, imageHash, subdigest, checkpoint); + } + + if (signatureType == NO_CHAIN_ID_TYPE) { + // noChainId digest + dynamic recover + subdigest = SequenceNoChainIdSig.subdigest(_digest); + (threshold, weight, imageHash, checkpoint) = SequenceDynamicSig.recover(subdigest, _signature); + return (threshold, weight, imageHash, subdigest, checkpoint); + } + + if (signatureType == CHAINED_TYPE) { + // original digest + chained recover + // (subdigest will be computed in the chained recover) + return chainedRecover(_digest, _signature); + } + + revert InvalidSignatureType(signatureType); + } + + /** + * @dev Validates a signature. + * + * @param _digest Digest of the signed data. + * @param _signature A Sequence signature. + * + * @return isValid Indicates whether the signature is valid or not. + * @return subdigest A modified version of the original digest, unique for each wallet/network. + */ + function _signatureValidation( + bytes32 _digest, + bytes calldata _signature + ) internal override virtual view returns ( + bool isValid, + bytes32 subdigest + ) { + uint256 threshold; uint256 weight; bytes32 imageHash; + (threshold, weight, imageHash, subdigest,) = signatureRecovery(_digest, _signature); + isValid = weight >= threshold && _isValidImage(imageHash); + } + + /** + * @notice Verifies whether the provided signature is valid with respect to the provided data + * @dev MUST return the correct magic value if the signature provided is valid for the provided data + * > The bytes4 magic value to return when signature is valid is 0x20c13b0b : bytes4(keccak256("isValidSignature(bytes,bytes)")) + * @param _data Arbitrary length data signed on the behalf of address(this) + * @param _signatures Signature byte array associated with _data. + * Encoded as abi.encode(Signature[], Configs) + * @return magicValue Magic value 0x20c13b0b if the signature is valid and 0x0 otherwise + */ + function isValidSignature( + bytes calldata _data, + bytes calldata _signatures + ) public override virtual view returns (bytes4) { + // Validate signatures + (bool isValid,) = _signatureValidation(keccak256(_data), _signatures); + if (isValid) { + return SELECTOR_ERC1271_BYTES_BYTES; + } + + return bytes4(0); + } + + /** + * @notice Verifies whether the provided signature is valid with respect to the provided hash + * @dev MUST return the correct magic value if the signature provided is valid for the provided hash + * > The bytes4 magic value to return when signature is valid is 0x1626ba7e : bytes4(keccak256("isValidSignature(bytes32,bytes)")) + * @param _hash keccak256 hash that was signed + * @param _signatures Signature byte array associated with _data. + * Encoded as abi.encode(Signature[], Configs) + * @return magicValue Magic value 0x1626ba7e if the signature is valid and 0x0 otherwise + */ + function isValidSignature( + bytes32 _hash, + bytes calldata _signatures + ) public override virtual view returns (bytes4) { + // Validate signatures + (bool isValid,) = _signatureValidation(_hash, _signatures); + if (isValid) { + return SELECTOR_ERC1271_BYTES32_BYTES; + } + + return bytes4(0); + } + + /** + * @notice Query if a contract implements an interface + * @param _interfaceID The interface identifier, as specified in ERC-165 + * @return `true` if the contract implements `_interfaceID` + */ + function supportsInterface(bytes4 _interfaceID) public override virtual pure returns (bool) { + if ( + _interfaceID == type(IModuleAuth).interfaceId || + _interfaceID == type(IERC1271Wallet).interfaceId + ) { + return true; + } + + return super.supportsInterface(_interfaceID); + } + + /** + * @notice Updates the signers configuration of the wallet + * @param _imageHash New required image hash of the signature + */ + function updateImageHash(bytes32 _imageHash) external override virtual onlySelf { + _updateImageHash(_imageHash); + } +} diff --git a/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/ModuleCalls.sol b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/ModuleCalls.sol new file mode 100644 index 0000000000..c90e0c403f --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/ModuleCalls.sol @@ -0,0 +1,156 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "./ModuleSelfAuth.sol"; +import "./ModuleStorage.sol"; +import "./ModuleERC165.sol"; +import "./ModuleNonce.sol"; +import "./ModuleOnlyDelegatecall.sol"; + +import "./interfaces/IModuleCalls.sol"; +import "./interfaces/IModuleAuth.sol"; + +import "./submodules/nonce/SubModuleNonce.sol"; +import "./submodules/auth/SequenceBaseSig.sol"; + +import "../../utils/LibOptim.sol"; + + +abstract contract ModuleCalls is IModuleCalls, IModuleAuth, ModuleERC165, ModuleOnlyDelegatecall, ModuleSelfAuth, ModuleNonce { + /** + * @notice Allow wallet owner to execute an action + * @dev Relayers must ensure that the gasLimit specified for each transaction + * is acceptable to them. A user could specify large enough that it could + * consume all the gas available. + * @param _txs Transactions to process + * @param _nonce Signature nonce (may contain an encoded space) + * @param _signature Encoded signature + */ + function execute( + Transaction[] calldata _txs, + uint256 _nonce, + bytes calldata _signature + ) external override virtual onlyDelegatecall { + // Validate and update nonce + _validateNonce(_nonce); + + // Hash and verify transaction bundle + (bool isValid, bytes32 txHash) = _signatureValidation( + keccak256( + abi.encode( + _nonce, + _txs + ) + ), + _signature + ); + + if (!isValid) { + revert InvalidSignature(txHash, _signature); + } + + // Execute the transactions + _execute(txHash, _txs); + } + + /** + * @notice Allow wallet to execute an action + * without signing the message + * @param _txs Transactions to execute + */ + function selfExecute( + Transaction[] calldata _txs + ) external override virtual onlySelf { + // Hash transaction bundle + bytes32 txHash = SequenceBaseSig.subdigest( + keccak256( + abi.encode('self:', _txs) + ) + ); + + // Execute the transactions + _execute(txHash, _txs); + } + + /** + * @notice Executes a list of transactions + * @param _txHash Hash of the batch of transactions + * @param _txs Transactions to execute + */ + function _execute( + bytes32 _txHash, + Transaction[] calldata _txs + ) private { + unchecked { + // Execute transaction + uint256 size = _txs.length; + for (uint256 i = 0; i < size; i++) { + Transaction calldata transaction = _txs[i]; + uint256 gasLimit = transaction.gasLimit; + + if (gasleft() < gasLimit) revert NotEnoughGas(i, gasLimit, gasleft()); + + bool success; + if (transaction.delegateCall) { + success = LibOptim.delegatecall( + transaction.target, + gasLimit == 0 ? gasleft() : gasLimit, + transaction.data + ); + } else { + success = LibOptim.call( + transaction.target, + transaction.value, + gasLimit == 0 ? gasleft() : gasLimit, + transaction.data + ); + } + + if (success) { + emit TxExecuted(_txHash, i); + } else { + // Avoid copy of return data until neccesary + _revertBytes( + transaction.revertOnError, + _txHash, + i, + LibOptim.returnData() + ); + } + } + } + } + + /** + * @notice Logs a failed transaction, reverts if the transaction is not optional + * @param _revertOnError Signals if it should revert or just log + * @param _txHash Hash of the transaction + * @param _index Index of the transaction in the batch + * @param _reason Encoded revert message + */ + function _revertBytes( + bool _revertOnError, + bytes32 _txHash, + uint256 _index, + bytes memory _reason + ) internal { + if (_revertOnError) { + assembly { revert(add(_reason, 0x20), mload(_reason)) } + } else { + emit TxFailed(_txHash, _index, _reason); + } + } + + /** + * @notice Query if a contract implements an interface + * @param _interfaceID The interface identifier, as specified in ERC-165 + * @return `true` if the contract implements `_interfaceID` + */ + function supportsInterface(bytes4 _interfaceID) public override virtual pure returns (bool) { + if (_interfaceID == type(IModuleCalls).interfaceId) { + return true; + } + + return super.supportsInterface(_interfaceID); + } +} diff --git a/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/ModuleCreator.sol b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/ModuleCreator.sol new file mode 100644 index 0000000000..deec8e2617 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/ModuleCreator.sol @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "./interfaces/IModuleCreator.sol"; + +import "./ModuleSelfAuth.sol"; +import "./ModuleERC165.sol"; + + +contract ModuleCreator is IModuleCreator, ModuleERC165, ModuleSelfAuth { + event CreatedContract(address _contract); + + /** + * @notice Creates a contract forwarding eth value + * @param _code Creation code of the contract + * @return addr The address of the created contract + */ + function createContract(bytes memory _code) public override virtual payable onlySelf returns (address addr) { + assembly { addr := create(callvalue(), add(_code, 32), mload(_code)) } + if (addr == address(0)) revert CreateFailed(_code); + emit CreatedContract(addr); + } + + /** + * @notice Query if a contract implements an interface + * @param _interfaceID The interface identifier, as specified in ERC-165 + * @return `true` if the contract implements `_interfaceID` + */ + function supportsInterface(bytes4 _interfaceID) public override virtual pure returns (bool) { + if (_interfaceID == type(IModuleCreator).interfaceId) { + return true; + } + + return super.supportsInterface(_interfaceID); + } +} diff --git a/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/ModuleERC165.sol b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/ModuleERC165.sol new file mode 100644 index 0000000000..2e10bed9aa --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/ModuleERC165.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + + +abstract contract ModuleERC165 { + /** + * @notice Query if a contract implements an interface + * @param _interfaceID The interface identifier, as specified in ERC-165 + * @dev Adding new hooks will not lead to them being reported by this function + * without upgrading the wallet. In addition, developers must ensure that + * all inherited contracts by the main module don't conflict and are accounted + * to be supported by the supportsInterface method. + * @return `true` if the contract implements `_interfaceID` + */ + function supportsInterface(bytes4 _interfaceID) virtual public pure returns (bool) { + return _interfaceID == this.supportsInterface.selector; + } +} diff --git a/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/ModuleNonce.sol b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/ModuleNonce.sol new file mode 100644 index 0000000000..561f5c5f71 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/ModuleNonce.sol @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "./ModuleStorage.sol"; + +import "./submodules/nonce/SubModuleNonce.sol"; + + +contract ModuleNonce { + // Events + event NonceChange(uint256 _space, uint256 _newNonce); + + // Errors + error BadNonce(uint256 _space, uint256 _provided, uint256 _current); + + // NONCE_KEY = keccak256("org.arcadeum.module.calls.nonce"); + bytes32 private constant NONCE_KEY = bytes32(0x8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e); + + /** + * @notice Returns the next nonce of the default nonce space + * @dev The default nonce space is 0x00 + * @return The next nonce + */ + function nonce() external virtual view returns (uint256) { + return readNonce(0); + } + + /** + * @notice Returns the next nonce of the given nonce space + * @param _space Nonce space, each space keeps an independent nonce count + * @return The next nonce + */ + function readNonce(uint256 _space) public virtual view returns (uint256) { + return uint256(ModuleStorage.readBytes32Map(NONCE_KEY, bytes32(_space))); + } + + /** + * @notice Changes the next nonce of the given nonce space + * @param _space Nonce space, each space keeps an independent nonce count + * @param _nonce Nonce to write on the space + */ + function _writeNonce(uint256 _space, uint256 _nonce) internal { + ModuleStorage.writeBytes32Map(NONCE_KEY, bytes32(_space), bytes32(_nonce)); + } + + /** + * @notice Verify if a nonce is valid + * @param _rawNonce Nonce to validate (may contain an encoded space) + */ + function _validateNonce(uint256 _rawNonce) internal virtual { + // Retrieve current nonce for this wallet + (uint256 space, uint256 providedNonce) = SubModuleNonce.decodeNonce(_rawNonce); + + uint256 currentNonce = readNonce(space); + if (currentNonce != providedNonce) { + revert BadNonce(space, providedNonce, currentNonce); + } + + unchecked { + uint256 newNonce = providedNonce + 1; + + _writeNonce(space, newNonce); + emit NonceChange(space, newNonce); + return; + } + } +} diff --git a/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/ModuleOnlyDelegatecall.sol b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/ModuleOnlyDelegatecall.sol new file mode 100644 index 0000000000..cc33f51def --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/ModuleOnlyDelegatecall.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + + +contract ModuleOnlyDelegatecall { + address private immutable self; + + error OnlyDelegatecall(); + + constructor() { + self = address(this); + } + + /** + * @notice Modifier that only allows functions to be called via delegatecall. + */ + modifier onlyDelegatecall() { + if (address(this) == self) { + revert OnlyDelegatecall(); + } + _; + } +} diff --git a/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/ModuleSelfAuth.sol b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/ModuleSelfAuth.sol new file mode 100644 index 0000000000..4492d50829 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/ModuleSelfAuth.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + + +contract ModuleSelfAuth { + error OnlySelfAuth(address _sender, address _self); + + modifier onlySelf() { + if (msg.sender != address(this)) { + revert OnlySelfAuth(msg.sender, address(this)); + } + _; + } +} diff --git a/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/ModuleStorage.sol b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/ModuleStorage.sol new file mode 100644 index 0000000000..b614220661 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/ModuleStorage.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + + +library ModuleStorage { + function writeBytes32(bytes32 _key, bytes32 _val) internal { + assembly { sstore(_key, _val) } + } + + function readBytes32(bytes32 _key) internal view returns (bytes32 val) { + assembly { val := sload(_key) } + } + + function writeBytes32Map(bytes32 _key, bytes32 _subKey, bytes32 _val) internal { + bytes32 key = keccak256(abi.encode(_key, _subKey)); + assembly { sstore(key, _val) } + } + + function readBytes32Map(bytes32 _key, bytes32 _subKey) internal view returns (bytes32 val) { + bytes32 key = keccak256(abi.encode(_key, _subKey)); + assembly { val := sload(key) } + } +} diff --git a/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/interfaces/IModuleAuth.sol b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/interfaces/IModuleAuth.sol new file mode 100644 index 0000000000..46ae4a76e9 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/interfaces/IModuleAuth.sol @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + + +abstract contract IModuleAuth { + // IMAGE_HASH_KEY = keccak256("org.arcadeum.module.auth.upgradable.image.hash"); + bytes32 internal constant IMAGE_HASH_KEY = bytes32(0xea7157fa25e3aa17d0ae2d5280fa4e24d421c61842aa85e45194e1145aa72bf8); + + event ImageHashUpdated(bytes32 newImageHash); + + // Errors + error ImageHashIsZero(); + error InvalidSignatureType(bytes1 _type); + + function _signatureValidation( + bytes32 _digest, + bytes calldata _signature + ) internal virtual view returns ( + bool isValid, + bytes32 subdigest + ); + + function signatureRecovery( + bytes32 _digest, + bytes calldata _signature + ) public virtual view returns ( + uint256 threshold, + uint256 weight, + bytes32 imageHash, + bytes32 subdigest, + uint256 checkpoint + ); + + /** + * @notice Validates the signature image + * @return true if the signature image is valid + */ + function _isValidImage(bytes32) internal virtual view returns (bool) { + return false; + } + + /** + * @notice Updates the signers configuration of the wallet + * @param _imageHash New required image hash of the signature + */ + function updateImageHash(bytes32 _imageHash) external virtual; + + /** + * @notice Updates the signers configuration of the wallet + * @param _imageHash New required image hash of the signature + */ + function _updateImageHash(bytes32 _imageHash) internal virtual; +} diff --git a/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/interfaces/IModuleCalls.sol b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/interfaces/IModuleCalls.sol new file mode 100644 index 0000000000..9030ae7cda --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/interfaces/IModuleCalls.sol @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + + +interface IModuleCalls { + // Events + event TxFailed(bytes32 indexed _tx, uint256 _index, bytes _reason); + event TxExecuted(bytes32 indexed _tx, uint256 _index); + + // Errors + error NotEnoughGas(uint256 _index, uint256 _requested, uint256 _available); + error InvalidSignature(bytes32 _hash, bytes _signature); + + // Transaction structure + struct Transaction { + bool delegateCall; // Performs delegatecall + bool revertOnError; // Reverts transaction bundle if tx fails + uint256 gasLimit; // Maximum gas to be forwarded + address target; // Address of the contract to call + uint256 value; // Amount of ETH to pass with the call + bytes data; // calldata to pass + } + + /** + * @notice Allow wallet owner to execute an action + * @param _txs Transactions to process + * @param _nonce Signature nonce (may contain an encoded space) + * @param _signature Encoded signature + */ + function execute( + Transaction[] calldata _txs, + uint256 _nonce, + bytes calldata _signature + ) external; + + /** + * @notice Allow wallet to execute an action + * without signing the message + * @param _txs Transactions to execute + */ + function selfExecute( + Transaction[] calldata _txs + ) external; +} diff --git a/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/interfaces/IModuleCreator.sol b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/interfaces/IModuleCreator.sol new file mode 100644 index 0000000000..fcf18d2197 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/interfaces/IModuleCreator.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + + +interface IModuleCreator { + error CreateFailed(bytes _code); + + /** + * @notice Creates a contract forwarding eth value + * @param _code Creation code of the contract + * @return addr The address of the created contract + */ + function createContract(bytes calldata _code) external payable returns (address addr); +} diff --git a/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol new file mode 100644 index 0000000000..fbf5c10521 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol @@ -0,0 +1,276 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "../../../../utils/SignatureValidator.sol"; +import "../../../../utils/LibBytesPointer.sol"; +import "../../../../utils/LibBytes.sol"; +import "../../../../utils/LibOptim.sol"; + + +/** + * @title SequenceBaseSig Library + * @author Agustin Aguilar (aa@horizon.io) + * @notice A Solidity implementation for handling signatures in the Sequence protocol. + */ +library SequenceBaseSig { + using LibBytesPointer for bytes; + + uint256 private constant FLAG_SIGNATURE = 0; + uint256 private constant FLAG_ADDRESS = 1; + uint256 private constant FLAG_DYNAMIC_SIGNATURE = 2; + uint256 private constant FLAG_NODE = 3; + uint256 private constant FLAG_BRANCH = 4; + uint256 private constant FLAG_SUBDIGEST = 5; + uint256 private constant FLAG_NESTED = 6; + + error InvalidNestedSignature(bytes32 _hash, address _addr, bytes _signature); + error InvalidSignatureFlag(uint256 _flag); + + /** + * @notice Generates a subdigest for the input digest (unique for this wallet and network). + * @param _digest The input digest to generate the subdigest from. + * @return bytes32 The subdigest generated from the input digest. + */ + function subdigest( + bytes32 _digest + ) internal view returns (bytes32) { + return keccak256( + abi.encodePacked( + "\x19\x01", + block.chainid, + address(this), + _digest + ) + ); + } + + /** + * @notice Generates the leaf for an address and weight. + * @dev The leaf is generated by concatenating the address and weight. + * + * @param _addr The address to generate the leaf for. + * @param _weight The weight to generate the leaf for. + * @return bytes32 The leaf generated from the address and weight. + */ + function _leafForAddressAndWeight( + address _addr, + uint96 _weight + ) internal pure returns (bytes32) { + unchecked { + return bytes32(uint256(_weight) << 160 | uint256(uint160(_addr))); + } + } + + /** + * @notice Generates the leaf for a hardcoded subdigest. + * @dev The leaf is generated by hashing 'Sequence static digest:\n' and the subdigest. + * @param _subdigest The subdigest to generate the leaf for. + * @return bytes32 The leaf generated from the hardcoded subdigest. + */ + function _leafForHardcodedSubdigest( + bytes32 _subdigest + ) internal pure returns (bytes32) { + return keccak256(abi.encodePacked('Sequence static digest:\n', _subdigest)); + } + + /** + * @notice Generates the leaf for a nested tree node. + * @dev The leaf is generated by hashing 'Sequence nested config:\n', the node, the threshold and the weight. + * + * @param _node The root of the node to generate the leaf for. + * @param _threshold The internal threshold of the tree. + * @param _weight The external weight of the tree. + * @return bytes32 The leaf generated from the nested tree. + */ + function _leafForNested( + bytes32 _node, + uint256 _threshold, + uint256 _weight + ) internal pure returns (bytes32) { + return keccak256(abi.encodePacked('Sequence nested config:\n', _node, _threshold, _weight)); + } + + /** + * @notice Returns the weight and root of a signature branch. + * @dev If the signature contains a hardcoded subdigest, and it matches the input digest, then the weight is set to 2 ** 256 - 1. + * + * @param _subdigest The digest to verify the signature against. + * @param _signature The signature branch to recover. + * @return weight The total weight of the recovered signatures. + * @return root The root hash of the recovered configuration. + */ + function recoverBranch( + bytes32 _subdigest, + bytes calldata _signature + ) internal view returns ( + uint256 weight, + bytes32 root + ) { + unchecked { + uint256 rindex; + + // Iterate until the image is completed + while (rindex < _signature.length) { + // Read next item type + uint256 flag; + (flag, rindex) = _signature.readUint8(rindex); + + if (flag == FLAG_ADDRESS) { + // Read plain address + uint8 addrWeight; address addr; + (addrWeight, addr, rindex) = _signature.readUint8Address(rindex); + + // Write weight and address to image + bytes32 node = _leafForAddressAndWeight(addr, addrWeight); + root = root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node; + continue; + } + + if (flag == FLAG_SIGNATURE) { + // Read weight + uint8 addrWeight; + (addrWeight, rindex) = _signature.readUint8(rindex); + + // Read single signature and recover signer + uint256 nrindex = rindex + 66; + address addr = SignatureValidator.recoverSigner(_subdigest, _signature[rindex:nrindex]); + rindex = nrindex; + + // Acumulate total weight of the signature + weight += addrWeight; + + // Write weight and address to image + bytes32 node = _leafForAddressAndWeight(addr, addrWeight); + root = root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node; + continue; + } + + if (flag == FLAG_DYNAMIC_SIGNATURE) { + // Read signer and weight + uint8 addrWeight; address addr; + (addrWeight, addr, rindex) = _signature.readUint8Address(rindex); + + // Read signature size + uint256 size; + (size, rindex) = _signature.readUint24(rindex); + + // Read dynamic size signature + uint256 nrindex = rindex + size; + if (!SignatureValidator.isValidSignature(_subdigest, addr, _signature[rindex:nrindex])) { + revert InvalidNestedSignature(_subdigest, addr, _signature[rindex:nrindex]); + } + rindex = nrindex; + + // Acumulate total weight of the signature + weight += addrWeight; + + // Write weight and address to image + bytes32 node = _leafForAddressAndWeight(addr, addrWeight); + root = root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node; + continue; + } + + if (flag == FLAG_NODE) { + // Read node hash + bytes32 node; + (node, rindex) = _signature.readBytes32(rindex); + root = root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node; + continue; + } + + if (flag == FLAG_BRANCH) { + // Enter a branch of the signature merkle tree + uint256 size; + (size, rindex) = _signature.readUint24(rindex); + uint256 nrindex = rindex + size; + + uint256 nweight; bytes32 node; + (nweight, node) = recoverBranch(_subdigest, _signature[rindex:nrindex]); + + weight += nweight; + root = LibOptim.fkeccak256(root, node); + + rindex = nrindex; + continue; + } + + if (flag == FLAG_NESTED) { + // Enter a branch of the signature merkle tree + // but with an internal threshold and an external fixed weight + uint256 externalWeight; + (externalWeight, rindex) = _signature.readUint8(rindex); + + uint256 internalThreshold; + (internalThreshold, rindex) = _signature.readUint16(rindex); + + uint256 size; + (size, rindex) = _signature.readUint24(rindex); + uint256 nrindex = rindex + size; + + uint256 internalWeight; bytes32 internalRoot; + (internalWeight, internalRoot) = recoverBranch(_subdigest, _signature[rindex:nrindex]); + rindex = nrindex; + + if (internalWeight >= internalThreshold) { + weight += externalWeight; + } + + bytes32 node = _leafForNested(internalRoot, internalThreshold, externalWeight); + root = root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node; + + continue; + } + + if (flag == FLAG_SUBDIGEST) { + // A hardcoded always accepted digest + // it pushes the weight to the maximum + bytes32 hardcoded; + (hardcoded, rindex) = _signature.readBytes32(rindex); + if (hardcoded == _subdigest) { + weight = type(uint256).max; + } + + bytes32 node = _leafForHardcodedSubdigest(hardcoded); + root = root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node; + continue; + } + + revert InvalidSignatureFlag(flag); + } + } + } + + /** + * @notice Returns the threshold, weight, root, and checkpoint of a signature. + * @dev To verify the signature, the weight must be greater than or equal to the threshold, and the root + * must match the expected `imageHash` of the wallet. + * + * @param _subdigest The digest to verify the signature against. + * @param _signature The signature to recover. + * @return threshold The minimum weight required for the signature to be valid. + * @return weight The total weight of the recovered signatures. + * @return imageHash The root hash of the recovered configuration + * @return checkpoint The checkpoint of the signature. + */ + function recover( + bytes32 _subdigest, + bytes calldata _signature + ) internal view returns ( + uint256 threshold, + uint256 weight, + bytes32 imageHash, + uint256 checkpoint + ) { + unchecked { + (weight, imageHash) = recoverBranch(_subdigest, _signature[6:]); + + // Threshold & checkpoint are the top nodes + // (but they are first on the signature) + threshold = LibBytes.readFirstUint16(_signature); + checkpoint = LibBytes.readUint32(_signature, 2); + + imageHash = LibOptim.fkeccak256(imageHash, bytes32(threshold)); + imageHash = LibOptim.fkeccak256(imageHash, bytes32(checkpoint)); + } + } +} diff --git a/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol new file mode 100644 index 0000000000..e8ad0913f0 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol @@ -0,0 +1,129 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "./SequenceBaseSig.sol"; + +import "../../interfaces/IModuleAuth.sol"; + +import "../../ModuleSelfAuth.sol"; +import "../../ModuleStorage.sol"; + +import "../../../../utils/LibBytesPointer.sol"; +import "../../../../utils/LibOptim.sol"; + +/** + * @title Sequence chained auth recovery submodule + * @author Agustin Aguilar (aa@horizon.io) + * @notice Defines Sequence signatures that work by delegating control to new configurations. + * @dev The delegations can be chained together, the first signature is the one that is used to validate + * the message, the last signature must match the current on-chain configuration of the wallet. + */ +abstract contract SequenceChainedSig is IModuleAuth, ModuleSelfAuth { + using LibBytesPointer for bytes; + + bytes32 public constant SET_IMAGE_HASH_TYPE_HASH = keccak256("SetImageHash(bytes32 imageHash)"); + + error LowWeightChainedSignature(bytes _signature, uint256 threshold, uint256 _weight); + error WrongChainedCheckpointOrder(uint256 _current, uint256 _prev); + + /** + * @notice Defined the special token that must be signed to delegate control to a new configuration. + * @param _imageHash The hash of the new configuration. + * @return bytes32 The message hash to be signed. + */ + function _hashSetImageHashStruct(bytes32 _imageHash) internal pure returns (bytes32) { + return LibOptim.fkeccak256(SET_IMAGE_HASH_TYPE_HASH, _imageHash); + } + + /** + * @notice Returns the threshold, weight, root, and checkpoint of a (chained) signature. + * + * @dev This method return the `threshold`, `weight` and `imageHash` of the last signature in the chain. + * Intermediate signatures are validated directly in this method. The `subdigest` is the one of the + * first signature in the chain (since that's the one that is used to validate the message). + * + * @param _digest The digest to recover the signature from. + * @param _signature The signature to recover. + * @return threshold The threshold of the (last) signature. + * @return weight The weight of the (last) signature. + * @return imageHash The image hash of the (last) signature. + * @return subdigest The subdigest of the (first) signature in the chain. + * @return checkpoint The checkpoint of the (last) signature. + */ + function chainedRecover( + bytes32 _digest, + bytes calldata _signature + ) internal view returns ( + uint256 threshold, + uint256 weight, + bytes32 imageHash, + bytes32 subdigest, + uint256 checkpoint + ) { + uint256 rindex = 1; + uint256 sigSize; + + // + // First signature out of the loop + // + + // First uint24 is the size of the signature + (sigSize, rindex) = _signature.readUint24(rindex); + uint256 nrindex = sigSize + rindex; + + ( + threshold, + weight, + imageHash, + subdigest, + checkpoint + ) = signatureRecovery( + _digest, + _signature[rindex:nrindex] + ); + + if (weight < threshold) { + revert LowWeightChainedSignature(_signature[rindex:nrindex], threshold, weight); + } + + rindex = nrindex; + + // The following signatures are handled by this loop. + // This is done this way because the first signature does not have a + // checkpoint to be validated against. + while (rindex < _signature.length) { + // First uint24 is the size of the signature + (sigSize, rindex) = _signature.readUint24(rindex); + nrindex = sigSize + rindex; + + uint256 nextCheckpoint; + + ( + threshold, + weight, + imageHash,, + // Do not change the subdigest; + // it should remain that of the first signature. + nextCheckpoint + ) = signatureRecovery( + _hashSetImageHashStruct(imageHash), + _signature[rindex:nrindex] + ); + + // Validate signature + if (weight < threshold) { + revert LowWeightChainedSignature(_signature[rindex:nrindex], threshold, weight); + } + + // Checkpoints must be provided in descending order + // since the first signature is the one that is used to validate the message + // and the last signature is the one that is used to validate the current configuration + if (nextCheckpoint >= checkpoint) { + revert WrongChainedCheckpointOrder(nextCheckpoint, checkpoint); + } + + checkpoint = nextCheckpoint; + rindex = nrindex; + } + } +} diff --git a/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol new file mode 100644 index 0000000000..c8b64a9aad --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "./SequenceBaseSig.sol"; + + +library SequenceDynamicSig { + + /** + * @notice Recover a "dynamically encoded" Sequence signature. + * @dev The Signature is stripped of the first byte, which is the encoding flag. + * + * @param _subdigest The digest of the signature. + * @param _signature The Sequence signature. + * @return threshold The threshold weight required to validate the signature. + * @return weight The weight of the signature. + * @return imageHash The hash of the recovered configuration. + * @return checkpoint The checkpoint of the configuration. + */ + function recover( + bytes32 _subdigest, + bytes calldata _signature + ) internal view returns ( + uint256 threshold, + uint256 weight, + bytes32 imageHash, + uint256 checkpoint + ) { + return SequenceBaseSig.recover(_subdigest, _signature[1:]); + } +} diff --git a/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol new file mode 100644 index 0000000000..4b21bd505a --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + + +library SequenceNoChainIdSig { + + /** + * @notice Computes a subdigest for a Sequence signature that works on all chains. + * @dev The subdigest is computed by removing the chain ID from the digest (using 0 instead). + * @param _digest The digest of the chain of signatures. + * @return bytes32 The subdigest with no chain ID. + */ + function subdigest(bytes32 _digest) internal view returns (bytes32) { + return keccak256( + abi.encodePacked( + "\x19\x01", + uint256(0), + address(this), + _digest + ) + ); + } +} diff --git a/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol new file mode 100644 index 0000000000..71eb8ae5e6 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + + +library SubModuleNonce { + // Nonce schema + // + // - space[160]:nonce[96] + // + uint256 internal constant NONCE_BITS = 96; + bytes32 internal constant NONCE_MASK = bytes32(uint256(type(uint96).max)); + + /** + * @notice Decodes a raw nonce + * @dev Schema: space[160]:type[96] + * @param _rawNonce Nonce to be decoded + * @return _space The nonce space of the raw nonce + * @return _nonce The nonce of the raw nonce + */ + function decodeNonce(uint256 _rawNonce) internal pure returns ( + uint256 _space, + uint256 _nonce + ) { + unchecked { + // Decode nonce + _space = _rawNonce >> NONCE_BITS; + _nonce = uint256(bytes32(_rawNonce) & NONCE_MASK); + } + } +} diff --git a/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/utils/LibBytes.sol b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/utils/LibBytes.sol new file mode 100644 index 0000000000..3452c8db57 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/utils/LibBytes.sol @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + + +/** + * @title Library for reading data from bytes arrays + * @author Agustin Aguilar (aa@horizon.io) + * @notice This library contains functions for reading data from bytes arrays. + * + * @dev These functions do not check if the input index is within the bounds of the data array. + * Reading out of bounds may return dirty values. + */ +library LibBytes { + + /** + * @notice Returns the bytes32 value at the given index in the input data. + * @param data The input data. + * @param index The index of the value to retrieve. + * @return a The bytes32 value at the given index. + */ + function readBytes32( + bytes calldata data, + uint256 index + ) internal pure returns ( + bytes32 a + ) { + assembly { + a := calldataload(add(data.offset, index)) + } + } + + /** + * @notice Returns the uint8 value at the given index in the input data. + * @param data The input data. + * @param index The index of the value to retrieve. + * @return a The uint8 value at the given index. + */ + function readUint8( + bytes calldata data, + uint256 index + ) internal pure returns ( + uint8 a + ) { + assembly { + let word := calldataload(add(index, data.offset)) + a := shr(248, word) + } + } + + /** + * @notice Returns the first uint16 value in the input data. + * @param data The input data. + * @return a The first uint16 value in the input data. + */ + function readFirstUint16( + bytes calldata data + ) internal pure returns ( + uint16 a + ) { + assembly { + let word := calldataload(data.offset) + a := shr(240, word) + } + } + + /** + * @notice Returns the uint32 value at the given index in the input data. + * @param data The input data. + * @param index The index of the value to retrieve. + * @return a The uint32 value at the given index. + */ + function readUint32( + bytes calldata data, + uint256 index + ) internal pure returns ( + uint32 a + ) { + assembly { + let word := calldataload(add(index, data.offset)) + a := shr(224, word) + } + } +} diff --git a/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/utils/LibBytesPointer.sol b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/utils/LibBytesPointer.sol new file mode 100644 index 0000000000..b731a6cd06 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/utils/LibBytesPointer.sol @@ -0,0 +1,161 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + + +/** + * @title Library for reading data from bytes arrays with a pointer + * @author Agustin Aguilar (aa@horizon.io) + * @notice This library contains functions for reading data from bytes arrays with a pointer. + * + * @dev These functions do not check if the input index is within the bounds of the data array. + * Reading out of bounds may return dirty values. + */ +library LibBytesPointer { + + /** + * @dev Returns the first uint16 value in the input data and updates the pointer. + * @param _data The input data. + * @return a The first uint16 value. + * @return newPointer The new pointer. + */ + function readFirstUint16( + bytes calldata _data + ) internal pure returns ( + uint16 a, + uint256 newPointer + ) { + assembly { + let word := calldataload(_data.offset) + a := shr(240, word) + newPointer := 2 + } + } + + /** + * @notice Returns the uint8 value at the given index in the input data and updates the pointer. + * @param _data The input data. + * @param _index The index of the value to retrieve. + * @return a The uint8 value at the given index. + * @return newPointer The new pointer. + */ + function readUint8( + bytes calldata _data, + uint256 _index + ) internal pure returns ( + uint8 a, + uint256 newPointer + ) { + assembly { + let word := calldataload(add(_index, _data.offset)) + a := shr(248, word) + newPointer := add(_index, 1) + } + } + + /** + * @notice Returns the uint8 value and the address at the given index in the input data and updates the pointer. + * @param _data The input data. + * @param _index The index of the value to retrieve. + * @return a The uint8 value at the given index. + * @return b The following address value. + * @return newPointer The new pointer. + */ + function readUint8Address( + bytes calldata _data, + uint256 _index + ) internal pure returns ( + uint8 a, + address b, + uint256 newPointer + ) { + assembly { + let word := calldataload(add(_index, _data.offset)) + a := shr(248, word) + b := and(shr(88, word), 0xffffffffffffffffffffffffffffffffffffffff) + newPointer := add(_index, 21) + } + } + + /** + * @notice Returns the uint16 value at the given index in the input data and updates the pointer. + * @param _data The input data. + * @param _index The index of the value to retrieve. + * @return a The uint16 value at the given index. + * @return newPointer The new pointer. + */ + function readUint16( + bytes calldata _data, + uint256 _index + ) internal pure returns ( + uint16 a, + uint256 newPointer + ) { + assembly { + let word := calldataload(add(_index, _data.offset)) + a := and(shr(240, word), 0xffff) + newPointer := add(_index, 2) + } + } + + /** + * @notice Returns the uint24 value at the given index in the input data and updates the pointer. + * @param _data The input data. + * @param _index The index of the value to retrieve. + * @return a The uint24 value at the given index. + * @return newPointer The new pointer. + */ + function readUint24( + bytes calldata _data, + uint256 _index + ) internal pure returns ( + uint24 a, + uint256 newPointer + ) { + assembly { + let word := calldataload(add(_index, _data.offset)) + a := and(shr(232, word), 0xffffff) + newPointer := add(_index, 3) + } + } + + /** + * @notice Returns the uint64 value at the given index in the input data and updates the pointer. + * @param _data The input data. + * @param _index The index of the value to retrieve. + * @return a The uint64 value at the given index. + * @return newPointer The new pointer. + */ + function readUint64( + bytes calldata _data, + uint256 _index + ) internal pure returns ( + uint64 a, + uint256 newPointer + ) { + assembly { + let word := calldataload(add(_index, _data.offset)) + a := and(shr(192, word), 0xffffffffffffffff) + newPointer := add(_index, 8) + } + } + + /** + * @notice Returns the bytes32 value at the given index in the input data and updates the pointer. + * @param _data The input data. + * @param _pointer The index of the value to retrieve. + * @return a The bytes32 value at the given index. + * @return newPointer The new pointer. + */ + function readBytes32( + bytes calldata _data, + uint256 _pointer + ) internal pure returns ( + bytes32 a, + uint256 newPointer + ) { + assembly { + a := calldataload(add(_pointer, _data.offset)) + newPointer := add(_pointer, 32) + } + } +} diff --git a/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/utils/LibOptim.sol b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/utils/LibOptim.sol new file mode 100644 index 0000000000..fb5cf0dcd8 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/utils/LibOptim.sol @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +/** + * @title Library for optimized EVM operations + * @author Agustin Aguilar (aa@horizon.io) + * @notice This library contains functions for optimizing certain EVM operations. + */ +library LibOptim { + + /** + * @notice Computes the keccak256 hash of two 32-byte inputs. + * @dev It uses only scratch memory space. + * @param _a The first 32 bytes of the hash. + * @param _b The second 32 bytes of the hash. + * @return c The keccak256 hash of the two 32-byte inputs. + */ + function fkeccak256( + bytes32 _a, + bytes32 _b + ) internal pure returns (bytes32 c) { + assembly { + mstore(0, _a) + mstore(32, _b) + c := keccak256(0, 64) + } + } + + /** + * @notice Returns the return data from the last call. + * @return r The return data from the last call. + */ + function returnData() internal pure returns (bytes memory r) { + assembly { + let size := returndatasize() + r := mload(0x40) + let start := add(r, 32) + mstore(0x40, add(start, size)) + mstore(r, size) + returndatacopy(start, 0, size) + } + } + + /** + * @notice Calls another contract with the given parameters. + * @dev This method doesn't increase the memory pointer. + * @param _to The address of the contract to call. + * @param _val The value to send to the contract. + * @param _gas The amount of gas to provide for the call. + * @param _data The data to send to the contract. + * @return r The success status of the call. + */ + function call( + address _to, + uint256 _val, + uint256 _gas, + bytes calldata _data + ) internal returns (bool r) { + assembly { + let tmp := mload(0x40) + calldatacopy(tmp, _data.offset, _data.length) + + r := call( + _gas, + _to, + _val, + tmp, + _data.length, + 0, + 0 + ) + } + } + + /** + * @notice Calls another contract with the given parameters, using delegatecall. + * @dev This method doesn't increase the memory pointer. + * @param _to The address of the contract to call. + * @param _gas The amount of gas to provide for the call. + * @param _data The data to send to the contract. + * @return r The success status of the call. + */ + function delegatecall( + address _to, + uint256 _gas, + bytes calldata _data + ) internal returns (bool r) { + assembly { + let tmp := mload(0x40) + calldatacopy(tmp, _data.offset, _data.length) + + r := delegatecall( + _gas, + _to, + tmp, + _data.length, + 0, + 0 + ) + } + } +} diff --git a/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/utils/SignatureValidator.sol b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/utils/SignatureValidator.sol new file mode 100644 index 0000000000..23433a4e14 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/GuestModule-wallet/sources/contracts/utils/SignatureValidator.sol @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "../interfaces/IERC1271Wallet.sol"; + +import "./LibBytes.sol"; + +/** + * @dev Contains logic for signature validation. + * Signatures from wallet contracts assume ERC-1271 support (https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1271.md) + * Notes: Methods are strongly inspired by contracts in https://github.com/0xProject/0x-monorepo/blob/development/ + */ +library SignatureValidator { + // Errors + error InvalidSignatureLength(bytes _signature); + error EmptySignature(); + error InvalidSValue(bytes _signature, bytes32 _s); + error InvalidVValue(bytes _signature, uint256 _v); + error UnsupportedSignatureType(bytes _signature, uint256 _type, bool _recoverMode); + error SignerIsAddress0(bytes _signature); + + using LibBytes for bytes; + + /***********************************| + | Variables | + |__________________________________*/ + + // bytes4(keccak256("isValidSignature(bytes,bytes)")) + bytes4 constant internal ERC1271_MAGICVALUE = 0x20c13b0b; + + // bytes4(keccak256("isValidSignature(bytes32,bytes)")) + bytes4 constant internal ERC1271_MAGICVALUE_BYTES32 = 0x1626ba7e; + + // Allowed signature types. + uint256 private constant SIG_TYPE_EIP712 = 1; + uint256 private constant SIG_TYPE_ETH_SIGN = 2; + uint256 private constant SIG_TYPE_WALLET_BYTES32 = 3; + + /***********************************| + | Signature Functions | + |__________________________________*/ + + /** + * @notice Recover the signer of hash, assuming it's an EOA account + * @dev Only for SignatureType.EIP712 and SignatureType.EthSign signatures + * @param _hash Hash that was signed + * encoded as (bytes32 r, bytes32 s, uint8 v, ... , SignatureType sigType) + */ + function recoverSigner( + bytes32 _hash, + bytes calldata _signature + ) internal pure returns (address signer) { + if (_signature.length != 66) revert InvalidSignatureLength(_signature); + uint256 signatureType = _signature.readUint8(_signature.length - 1); + + // Variables are not scoped in Solidity. + uint8 v = _signature.readUint8(64); + bytes32 r = _signature.readBytes32(0); + bytes32 s = _signature.readBytes32(32); + + // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature + // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines + // the valid range for s in (281): 0 < s < secp256k1n Ć· 2 + 1, and for v in (282): v ∈ {27, 28}. Most + // signatures from current libraries generate a unique signature with an s-value in the lower half order. + // + // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value + // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or + // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept + // these malleable signatures as well. + // + // Source OpenZeppelin + // https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/cryptography/ECDSA.sol + + if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { + revert InvalidSValue(_signature, s); + } + + if (v != 27 && v != 28) { + revert InvalidVValue(_signature, v); + } + + // Signature using EIP712 + if (signatureType == SIG_TYPE_EIP712) { + signer = ecrecover(_hash, v, r, s); + + // Signed using web3.eth_sign() or Ethers wallet.signMessage() + } else if (signatureType == SIG_TYPE_ETH_SIGN) { + signer = ecrecover( + keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", _hash)), + v, + r, + s + ); + + } else { + // We cannot recover the signer for any other signature type. + revert UnsupportedSignatureType(_signature, signatureType, true); + } + + // Prevent signer from being 0x0 + if (signer == address(0x0)) revert SignerIsAddress0(_signature); + + return signer; + } + + /** + * @notice Returns true if the provided signature is valid for the given signer. + * @dev Supports SignatureType.EIP712, SignatureType.EthSign, and ERC1271 signatures + * @param _hash Hash that was signed + * @param _signer Address of the signer candidate + * @param _signature Signature byte array + */ + function isValidSignature( + bytes32 _hash, + address _signer, + bytes calldata _signature + ) internal view returns (bool valid) { + if (_signature.length == 0) { + revert EmptySignature(); + } + + uint256 signatureType = uint8(_signature[_signature.length - 1]); + if (signatureType == SIG_TYPE_EIP712 || signatureType == SIG_TYPE_ETH_SIGN) { + // Recover signer and compare with provided + valid = recoverSigner(_hash, _signature) == _signer; + + } else if (signatureType == SIG_TYPE_WALLET_BYTES32) { + // Remove signature type before calling ERC1271, restore after call + valid = ERC1271_MAGICVALUE_BYTES32 == IERC1271Wallet(_signer).isValidSignature(_hash, _signature[0:_signature.length - 1]); + + } else { + // We cannot validate any other signature type. + // We revert because we can say nothing about its validity. + revert UnsupportedSignatureType(_signature, signatureType, false); + } + } +} diff --git a/packages/wallet/wallet-contracts/contracts/Wallet.sol b/packages/wallet/wallet-contracts/contracts/Wallet.sol new file mode 100644 index 0000000000..aaeb5e61ed --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/Wallet.sol @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +/** + * Minimal upgradeable proxy implementation, delegates all calls to the address + * defined by the storage slot matching the wallet address. + * + * Inspired by EIP-1167 Implementation (https://eips.ethereum.org/EIPS/eip-1167) + * + * deployed code: + * + * 0x00 0x36 0x36 CALLDATASIZE cds + * 0x01 0x3d 0x3d RETURNDATASIZE 0 cds + * 0x02 0x3d 0x3d RETURNDATASIZE 0 0 cds + * 0x03 0x37 0x37 CALLDATACOPY + * 0x04 0x3d 0x3d RETURNDATASIZE 0 + * 0x05 0x3d 0x3d RETURNDATASIZE 0 0 + * 0x06 0x3d 0x3d RETURNDATASIZE 0 0 0 + * 0x07 0x36 0x36 CALLDATASIZE cds 0 0 0 + * 0x08 0x3d 0x3d RETURNDATASIZE 0 cds 0 0 0 + * 0x09 0x30 0x30 ADDRESS addr 0 cds 0 0 0 + * 0x0A 0x54 0x54 SLOAD imp 0 cds 0 0 0 + * 0x0B 0x5a 0x5a GAS gas imp 0 cds 0 0 0 + * 0x0C 0xf4 0xf4 DELEGATECALL suc 0 + * 0x0D 0x3d 0x3d RETURNDATASIZE rds suc 0 + * 0x0E 0x82 0x82 DUP3 0 rds suc 0 + * 0x0F 0x80 0x80 DUP1 0 0 rds suc 0 + * 0x10 0x3e 0x3e RETURNDATACOPY suc 0 + * 0x11 0x90 0x90 SWAP1 0 suc + * 0x12 0x3d 0x3d RETURNDATASIZE rds 0 suc + * 0x13 0x91 0x91 SWAP2 suc 0 rds + * 0x14 0x60 0x18 0x6018 PUSH1 0x18 suc 0 rds + * /-- 0x16 0x57 0x57 JUMPI 0 rds + * | 0x17 0xfd 0xfd REVERT + * \-> 0x18 0x5b 0x5b JUMPDEST 0 rds + * 0x19 0xf3 0xf3 RETURN + * + * flat deployed code: 0x363d3d373d3d3d363d30545af43d82803e903d91601857fd5bf3 + * + * deploy function: + * + * 0x00 0x60 0x3a 0x603a PUSH1 0x3a + * 0x02 0x60 0x0e 0x600e PUSH1 0x0e 0x3a + * 0x04 0x3d 0x3d RETURNDATASIZE 0 0x0e 0x3a + * 0x05 0x39 0x39 CODECOPY + * 0x06 0x60 0x1a 0x601a PUSH1 0x1a + * 0x08 0x80 0x80 DUP1 0x1a 0x1a + * 0x09 0x51 0x51 MLOAD imp 0x1a + * 0x0A 0x30 0x30 ADDRESS addr imp 0x1a + * 0x0B 0x55 0x55 SSTORE 0x1a + * 0x0C 0x3d 0x3d RETURNDATASIZE 0 0x1a + * 0x0D 0xf3 0xf3 RETURN + * [...deployed code] + * + * flat deploy function: 0x603a600e3d39601a805130553df3363d3d373d3d3d363d30545af43d82803e903d91601857fd5bf3 + */ +library Wallet { + bytes internal constant creationCode = + hex"603a600e3d39601a805130553df3363d3d373d3d3d363d30545af43d82803e903d91601857fd5bf3"; +} diff --git a/packages/wallet/wallet-contracts/contracts/hooks/WalletProxyHook.sol b/packages/wallet/wallet-contracts/contracts/hooks/WalletProxyHook.sol new file mode 100644 index 0000000000..ae1ad4d833 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/hooks/WalletProxyHook.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import {IWalletProxy} from "./interfaces/IWalletProxy.sol"; +import {Implementation} from "../modules/commons/Implementation.sol"; + +contract WalletProxyHook is IWalletProxy, Implementation { + /// @inheritdoc IWalletProxy + function PROXY_getImplementation() public view returns (address) { + return _getImplementation(); + } +} diff --git a/packages/wallet/wallet-contracts/contracts/hooks/interfaces/IWalletProxy.sol b/packages/wallet/wallet-contracts/contracts/hooks/interfaces/IWalletProxy.sol new file mode 100644 index 0000000000..385de7cf06 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/hooks/interfaces/IWalletProxy.sol @@ -0,0 +1,12 @@ +// Copyright Immutable Pty Ltd 2018 - 2023 +// SPDX-License-Identifier: Apache 2.0 +// https://github.com/immutable/contracts/blob/a04f7ecb8a79ad8f1b67f73f770e0545deb6cba2/contracts/allowlist/IWalletProxy.sol +pragma solidity 0.8.18; + +// Interface to retrieve the implemention stored inside the Proxy contract +/// Interface for Passport Wallet's proxy contract. +interface IWalletProxy { + // Returns the current implementation address used by the proxy contract + // solhint-disable-next-line func-name-mixedcase + function PROXY_getImplementation() external view returns (address); +} diff --git a/packages/wallet/wallet-contracts/contracts/interfaces/IERC1271Wallet.sol b/packages/wallet/wallet-contracts/contracts/interfaces/IERC1271Wallet.sol new file mode 100644 index 0000000000..169d17b43e --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/interfaces/IERC1271Wallet.sol @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +interface IERC1271Wallet { + /** + * @notice Verifies whether the provided signature is valid with respect to the provided data + * @dev MUST return the correct magic value if the signature provided is valid for the provided data + * > The bytes4 magic value to return when signature is valid is 0x20c13b0b : bytes4(keccak256("isValidSignature(bytes,bytes)") + * > This function MAY modify Ethereum's state + * @param _data Arbitrary length data signed on the behalf of address(this) + * @param _signature Signature byte array associated with _data + * @return magicValue Magic value 0x20c13b0b if the signature is valid and 0x0 otherwise + */ + function isValidSignature(bytes calldata _data, bytes calldata _signature) external view returns (bytes4 magicValue); + + /** + * @notice Verifies whether the provided signature is valid with respect to the provided hash + * @dev MUST return the correct magic value if the signature provided is valid for the provided hash + * > The bytes4 magic value to return when signature is valid is 0x20c13b0b : bytes4(keccak256("isValidSignature(bytes,bytes)") + * > This function MAY modify Ethereum's state + * @param _hash keccak256 hash that was signed + * @param _signature Signature byte array associated with _data + * @return magicValue Magic value 0x20c13b0b if the signature is valid and 0x0 otherwise + */ + function isValidSignature(bytes32 _hash, bytes calldata _signature) external view returns (bytes4 magicValue); +} diff --git a/packages/wallet/wallet-contracts/contracts/interfaces/receivers/IERC1155Receiver.sol b/packages/wallet/wallet-contracts/contracts/interfaces/receivers/IERC1155Receiver.sol new file mode 100644 index 0000000000..ae7a8c03f7 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/interfaces/receivers/IERC1155Receiver.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +interface IERC1155Receiver { + function onERC1155Received(address, address, uint256, uint256, bytes calldata) external returns (bytes4); + function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) + external + returns (bytes4); +} diff --git a/packages/wallet/wallet-contracts/contracts/interfaces/receivers/IERC223Receiver.sol b/packages/wallet/wallet-contracts/contracts/interfaces/receivers/IERC223Receiver.sol new file mode 100644 index 0000000000..2cbbc218a3 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/interfaces/receivers/IERC223Receiver.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +interface IERC223Receiver { + function tokenFallback(address, uint256, bytes calldata) external; +} diff --git a/packages/wallet/wallet-contracts/contracts/interfaces/receivers/IERC721Receiver.sol b/packages/wallet/wallet-contracts/contracts/interfaces/receivers/IERC721Receiver.sol new file mode 100644 index 0000000000..cfca58422a --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/interfaces/receivers/IERC721Receiver.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +interface IERC721Receiver { + function onERC721Received(address, address, uint256, bytes calldata) external returns (bytes4); +} diff --git a/packages/wallet/wallet-contracts/contracts/interfaces/receivers/IERC777Receiver.sol b/packages/wallet/wallet-contracts/contracts/interfaces/receivers/IERC777Receiver.sol new file mode 100644 index 0000000000..054c93d5ab --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/interfaces/receivers/IERC777Receiver.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +interface IERC777Receiver { + function tokensReceived(address, address, address, uint256, bytes calldata, bytes calldata) external; +} diff --git a/packages/wallet/wallet-contracts/contracts/interfaces/tokens/IERC1155.sol b/packages/wallet/wallet-contracts/contracts/interfaces/tokens/IERC1155.sol new file mode 100644 index 0000000000..3e4a428e66 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/interfaces/tokens/IERC1155.sol @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.18; + +interface IERC1155 { + function balanceOf(address account, uint256 id) external view returns (uint256); + function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) + external + view + returns (uint256[] memory); + function setApprovalForAll(address operator, bool approved) external; + function isApprovedForAll(address account, address operator) external view returns (bool); + function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external; + function safeBatchTransferFrom( + address from, + address to, + uint256[] calldata ids, + uint256[] calldata amounts, + bytes calldata data + ) external; + + event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); + event TransferBatch( + address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values + ); + event ApprovalForAll(address indexed account, address indexed operator, bool approved); + event URI(string value, uint256 indexed id); +} diff --git a/packages/wallet/wallet-contracts/contracts/interfaces/tokens/IERC20.sol b/packages/wallet/wallet-contracts/contracts/interfaces/tokens/IERC20.sol new file mode 100644 index 0000000000..5dddb36be8 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/interfaces/tokens/IERC20.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.18; + +interface IERC20 { + function totalSupply() external view returns (uint256); + function balanceOf(address account) external view returns (uint256); + function transfer(address recipient, uint256 amount) external returns (bool); + function allowance(address owner, address spender) external view returns (uint256); + function approve(address spender, uint256 amount) external returns (bool); + function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); + + event Transfer(address indexed from, address indexed to, uint256 value); + event Approval(address indexed owner, address indexed spender, uint256 value); +} diff --git a/packages/wallet/wallet-contracts/contracts/interfaces/tokens/IERC721.sol b/packages/wallet/wallet-contracts/contracts/interfaces/tokens/IERC721.sol new file mode 100644 index 0000000000..dbeb299df6 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/interfaces/tokens/IERC721.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.18; + +interface IERC721 { + function balanceOf(address owner) external view returns (uint256 balance); + function ownerOf(uint256 tokenId) external view returns (address owner); + function safeTransferFrom(address from, address to, uint256 tokenId) external; + function transferFrom(address from, address to, uint256 tokenId) external; + function approve(address to, uint256 tokenId) external; + function getApproved(uint256 tokenId) external view returns (address operator); + function setApprovalForAll(address operator, bool approved) external; + function isApprovedForAll(address owner, address operator) external view returns (bool); + function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; + + event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); + event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); + event ApprovalForAll(address indexed owner, address indexed operator, bool approved); +} diff --git a/packages/wallet/wallet-contracts/contracts/mocks/AlwaysRevertMock.sol b/packages/wallet/wallet-contracts/contracts/mocks/AlwaysRevertMock.sol new file mode 100644 index 0000000000..8cfcbecf2b --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/mocks/AlwaysRevertMock.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +contract AlwaysRevertMock { + fallback() external payable { + revert("AlwaysRevertMock#fallback: ALWAYS_REVERT"); + } +} diff --git a/packages/wallet/wallet-contracts/contracts/mocks/CallReceiverMock.sol b/packages/wallet/wallet-contracts/contracts/mocks/CallReceiverMock.sol new file mode 100644 index 0000000000..dcfec945e6 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/mocks/CallReceiverMock.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +contract CallReceiverMock { + uint256 public lastValA; + bytes public lastValB; + + bool revertFlag; + + constructor() payable {} + + function setRevertFlag(bool _revertFlag) external { + revertFlag = _revertFlag; + } + + function testCall(uint256 _valA, bytes calldata _valB) external payable { + require(!revertFlag, "CallReceiverMock#testCall: REVERT_FLAG"); + + lastValA = _valA; + lastValB = _valB; + } +} diff --git a/packages/wallet/wallet-contracts/contracts/mocks/DelegateCallMock.sol b/packages/wallet/wallet-contracts/contracts/mocks/DelegateCallMock.sol new file mode 100644 index 0000000000..f610ab8e99 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/mocks/DelegateCallMock.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +contract DelegateCallMock { + event Readed(uint256 _val); + + uint256 private constant REVERT_SLOT = uint256(keccak256("revert-flag")); + + mapping(uint256 => uint256) private store; + + function setRevertFlag(bool _revertFlag) external { + store[REVERT_SLOT] = _revertFlag ? 1 : 0; + } + + function write(uint256 _key, uint256 _val) external { + require(store[REVERT_SLOT] == 0, "DelegateCallMock#write: REVERT_FLAG"); + store[_key] = _val; + } + + function read(uint256 _key) external { + emit Readed(store[_key]); + } +} diff --git a/packages/wallet/wallet-contracts/contracts/mocks/ERC1155Mock.sol b/packages/wallet/wallet-contracts/contracts/mocks/ERC1155Mock.sol new file mode 100644 index 0000000000..8122a14e1f --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/mocks/ERC1155Mock.sol @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.18; + +contract ERC1155Mock { + string public name = "Mock ERC1155 Token"; + string public symbol = "MERC1155"; + address public owner; + + mapping(uint256 => mapping(address => uint256)) public balances; + mapping(address => mapping(address => bool)) public operatorApprovals; + + constructor() { + owner = msg.sender; + } + + modifier onlyOwner() { + require(msg.sender == owner, "Only owner can mint"); + _; + } + + function balanceOf(address account, uint256 id) public view returns (uint256) { + return balances[id][account]; + } + + function balanceOfBatch(address[] memory accounts, uint256[] memory ids) public view returns (uint256[] memory) { + require(accounts.length == ids.length, "Accounts and ids length mismatch"); + + uint256[] memory batchBalances = new uint256[](accounts.length); + for (uint256 i = 0; i < accounts.length; ++i) { + batchBalances[i] = balances[ids[i]][accounts[i]]; + } + return batchBalances; + } + + function mint(address to, uint256 id, uint256 amount) public onlyOwner { + require(to != address(0), "Cannot mint to zero address"); + + balances[id][to] += amount; + emit TransferSingle(msg.sender, address(0), to, id, amount); + } + + function safeTransferFrom(address from, address to, uint256 id, uint256 amount) public { + require(from == msg.sender || isApprovedForAll(from, msg.sender), "Not approved to transfer"); + + require(balances[id][from] >= amount, "Insufficient balance"); + balances[id][from] -= amount; + balances[id][to] += amount; + + emit TransferSingle(msg.sender, from, to, id, amount); + } + + function setApprovalForAll(address operator, bool approved) public { + operatorApprovals[msg.sender][operator] = approved; + emit ApprovalForAll(msg.sender, operator, approved); + } + + function isApprovedForAll(address account, address operator) public view returns (bool) { + return operatorApprovals[account][operator]; + } + + event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); + event ApprovalForAll(address indexed account, address indexed operator, bool approved); +} diff --git a/packages/wallet/wallet-contracts/contracts/mocks/ERC165CheckerMock.sol b/packages/wallet/wallet-contracts/contracts/mocks/ERC165CheckerMock.sol new file mode 100644 index 0000000000..f233001ffe --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/mocks/ERC165CheckerMock.sol @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +contract ERC165CheckerMock { + bytes4 constant InvalidID = 0xffffffff; + bytes4 constant ERC165ID = 0x01ffc9a7; + + function doesContractImplementInterface(address _contract, bytes4 _interfaceId) external view returns (bool) { + uint256 success; + uint256 result; + + (success, result) = noThrowCall(_contract, ERC165ID); + if (success == 0 || result == 0) { + return false; + } + + (success, result) = noThrowCall(_contract, InvalidID); + if (success == 0 || result != 0) { + return false; + } + + (success, result) = noThrowCall(_contract, _interfaceId); + if (success == 1 && result == 1) { + return true; + } + return false; + } + + function noThrowCall(address _contract, bytes4 _interfaceId) + private + view + returns (uint256 success, uint256 result) + { + bytes4 erc165ID = ERC165ID; + + assembly { + let x := mload(0x40) // Find empty storage location using "free memory pointer" + mstore(x, erc165ID) // Place signature at beginning of empty storage + mstore(add(x, 0x04), _interfaceId) // Place first argument directly next to signature + + success := staticcall( + 30000, // 30k gas + _contract, // To addr + x, // Inputs are stored at location x + 0x24, // Inputs are 36 bytes long + x, // Store output over input (saves space) + 0x20 // Outputs are 32 bytes long + ) + + result := mload(x) // Load the result + } + } +} diff --git a/packages/wallet/wallet-contracts/contracts/mocks/ERC20Mock.sol b/packages/wallet/wallet-contracts/contracts/mocks/ERC20Mock.sol new file mode 100644 index 0000000000..f2c7125a0f --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/mocks/ERC20Mock.sol @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.18; + +contract ERC20Mock { + string public name = "Mock ERC20 Token"; + string public symbol = "MERC20"; + uint8 public decimals = 18; + uint256 public totalSupply; + mapping(address => uint256) public balances; + mapping(address => mapping(address => uint256)) public allowances; + + constructor(uint256 initialSupply) { + totalSupply = initialSupply; + balances[msg.sender] = initialSupply; + } + + function balanceOf(address account) public view returns (uint256) { + return balances[account]; + } + + function transfer(address recipient, uint256 amount) public returns (bool) { + require(balances[msg.sender] >= amount, "Insufficient balance"); + balances[msg.sender] -= amount; + balances[recipient] += amount; + emit Transfer(msg.sender, recipient, amount); + return true; + } + + function allowance(address owner, address spender) public view returns (uint256) { + return allowances[owner][spender]; + } + + function approve(address spender, uint256 amount) public returns (bool) { + allowances[msg.sender][spender] = amount; + emit Approval(msg.sender, spender, amount); + return true; + } + + function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) { + require(balances[sender] >= amount, "Insufficient balance"); + require(allowances[sender][msg.sender] >= amount, "Allowance exceeded"); + balances[sender] -= amount; + balances[recipient] += amount; + allowances[sender][msg.sender] -= amount; + emit Transfer(sender, recipient, amount); + return true; + } + + event Transfer(address indexed from, address indexed to, uint256 value); + event Approval(address indexed owner, address indexed spender, uint256 value); +} diff --git a/packages/wallet/wallet-contracts/contracts/mocks/ERC721Mock.sol b/packages/wallet/wallet-contracts/contracts/mocks/ERC721Mock.sol new file mode 100644 index 0000000000..1ca70952d0 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/mocks/ERC721Mock.sol @@ -0,0 +1,86 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.18; + +contract ERC721Mock { + string public name = "Mock ERC721 Token"; + string public symbol = "MERC721"; + uint256 public totalSupply; + address public owner; + + mapping(address => uint256) public balances; + mapping(uint256 => address) public owners; + mapping(address => mapping(address => bool)) public operatorApprovals; + mapping(uint256 => address) public tokenApprovals; + + constructor() { + owner = msg.sender; + } + + modifier onlyOwner() { + require(msg.sender == owner, "Only owner can mint"); + _; + } + + function balanceOf(address _owner) public view returns (uint256) { + return balances[_owner]; + } + + function ownerOf(uint256 tokenId) public view returns (address) { + address tokenOwner = owners[tokenId]; + require(tokenOwner != address(0), "Token does not exist"); + return tokenOwner; + } + + function mint(address to, uint256 tokenId) public onlyOwner { + require(to != address(0), "Cannot mint to zero address"); + require(owners[tokenId] == address(0), "Token already minted"); + + owners[tokenId] = to; + balances[to] += 1; + totalSupply += 1; + + emit Transfer(address(0), to, tokenId); + } + + function transferFrom(address from, address to, uint256 tokenId) public { + require(ownerOf(tokenId) == from, "Not the owner of the token"); + require(to != address(0), "Cannot transfer to zero address"); + + require( + msg.sender == from || getApproved(tokenId) == msg.sender || isApprovedForAll(from, msg.sender), + "Not approved to transfer" + ); + + balances[from] -= 1; + balances[to] += 1; + owners[tokenId] = to; + + emit Transfer(from, to, tokenId); + } + + function approve(address to, uint256 tokenId) public { + address tokenOwner = ownerOf(tokenId); + require(to != tokenOwner, "Cannot approve current owner"); + require(msg.sender == tokenOwner || isApprovedForAll(tokenOwner, msg.sender), "Not approved"); + + tokenApprovals[tokenId] = to; + emit Approval(tokenOwner, to, tokenId); + } + + function getApproved(uint256 tokenId) public view returns (address) { + return tokenApprovals[tokenId]; + } + + function setApprovalForAll(address operator, bool approved) public { + operatorApprovals[msg.sender][operator] = approved; + emit ApprovalForAll(msg.sender, operator, approved); + } + + function isApprovedForAll(address _owner, address operator) public view returns (bool) { + return operatorApprovals[_owner][operator]; + } + + event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); + event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); + event ApprovalForAll(address indexed owner, address indexed operator, bool approved); +} diff --git a/packages/wallet/wallet-contracts/contracts/mocks/GasBurnerMock.sol b/packages/wallet/wallet-contracts/contracts/mocks/GasBurnerMock.sol new file mode 100644 index 0000000000..9407fdc095 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/mocks/GasBurnerMock.sol @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +contract GasBurnerMock { + event ProvidedGas(uint256 _val); + + function burnGas(uint256 _burn) external { + emit ProvidedGas(gasleft()); + + bytes32 stub; + uint256 initial = gasleft(); + + while (initial - gasleft() < _burn) { + stub = keccak256(abi.encode(stub)); + } + } +} diff --git a/packages/wallet/wallet-contracts/contracts/mocks/HookCallerMock.sol b/packages/wallet/wallet-contracts/contracts/mocks/HookCallerMock.sol new file mode 100644 index 0000000000..c7befffd75 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/mocks/HookCallerMock.sol @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "../interfaces/receivers/IERC1155Receiver.sol"; +import "../interfaces/receivers/IERC721Receiver.sol"; +import "../interfaces/receivers/IERC223Receiver.sol"; + +import "../interfaces/IERC1271Wallet.sol"; + +contract HookCallerMock { + function callERC1155Received(address _addr) external { + bytes4 result = IERC1155Receiver(_addr).onERC1155Received(address(this), msg.sender, 1, 2, msg.data); + + require(result == 0xf23a6e61, "HookCallerMock#callERC1155Received: INVALID_RETURN"); + } + + function callERC1155BatchReceived(address _addr) external { + uint256[] memory ids = new uint256[](3); + ids[0] = 1; + ids[1] = 2; + ids[2] = 3; + + uint256[] memory values = new uint256[](3); + values[0] = 200; + values[1] = 300; + values[2] = 400; + + bytes4 result = IERC1155Receiver(_addr).onERC1155BatchReceived(address(this), msg.sender, ids, values, msg.data); + + require(result == 0xbc197c81, "HookCallerMock#callERC1155BatchReceived: INVALID_RETURN"); + } + + function callERC721Received(address _addr) external { + bytes4 result = IERC721Receiver(_addr).onERC721Received(address(this), msg.sender, 1, msg.data); + + require(result == 0x150b7a02, "HookCallerMock#callERC721Received: INVALID_RETURN"); + } + + function callERC223Received(address _addr) external { + IERC223Receiver(_addr).tokenFallback(msg.sender, 1, msg.data); + } + + function callERC1271isValidSignatureData(address _addr, bytes calldata _data, bytes calldata _signature) + external + view + { + bytes4 result = IERC1271Wallet(_addr).isValidSignature(_data, _signature); + require(result == 0x20c13b0b, "HookCallerMock#callERC1271isValidSignatureData: INVALID_RETURN"); + } + + function callERC1271isValidSignatureHash(address _addr, bytes32 _hash, bytes calldata _signature) external view { + bytes4 result = IERC1271Wallet(_addr).isValidSignature(_hash, _signature); + require(result == 0x1626ba7e, "HookCallerMock#callERC1271isValidSignatureHash: INVALID_RETURN"); + } +} diff --git a/packages/wallet/wallet-contracts/contracts/mocks/HookMock.sol b/packages/wallet/wallet-contracts/contracts/mocks/HookMock.sol new file mode 100644 index 0000000000..3d77b8440f --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/mocks/HookMock.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +contract HookMock { + function onHookMockCall(uint256 _num) external pure returns (uint256) { + return _num * 2; + } +} diff --git a/packages/wallet/wallet-contracts/contracts/mocks/LibBytesImpl.sol b/packages/wallet/wallet-contracts/contracts/mocks/LibBytesImpl.sol new file mode 100644 index 0000000000..cd676602f9 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/mocks/LibBytesImpl.sol @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "../utils/LibBytes.sol"; + +contract LibBytesImpl { + using LibBytes for bytes; + + function readBytes32(bytes calldata data, uint256 index) external pure returns (bytes32 a) { + return LibBytes.readBytes32(data, index); + } + + function readUint8(bytes calldata data, uint256 index) external pure returns (uint8 a) { + return LibBytes.readUint8(data, index); + } + + function readUint32(bytes calldata data, uint256 index) external pure returns (uint32 a) { + return LibBytes.readUint32(data, index); + } +} diff --git a/packages/wallet/wallet-contracts/contracts/mocks/LibBytesPointerImpl.sol b/packages/wallet/wallet-contracts/contracts/mocks/LibBytesPointerImpl.sol new file mode 100644 index 0000000000..583b388397 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/mocks/LibBytesPointerImpl.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "../utils/LibBytesPointer.sol"; + +contract LibBytesPointerImpl { + using LibBytesPointer for bytes; + + function readFirstUint16(bytes calldata data) external pure returns (uint16 a, uint256 newPointer) { + return LibBytesPointer.readFirstUint16(data); + } + + function readUint16(bytes calldata data, uint256 index) external pure returns (uint16 a, uint256 newPointer) { + return LibBytesPointer.readUint16(data, index); + } + + function readUint24(bytes calldata data, uint256 index) external pure returns (uint24 a, uint256 newPointer) { + return LibBytesPointer.readUint24(data, index); + } + + function readUint64(bytes calldata data, uint256 index) external pure returns (uint64 a, uint256 newPointer) { + return LibBytesPointer.readUint64(data, index); + } +} diff --git a/packages/wallet/wallet-contracts/contracts/mocks/LibStringImp.sol b/packages/wallet/wallet-contracts/contracts/mocks/LibStringImp.sol new file mode 100644 index 0000000000..54db366bea --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/mocks/LibStringImp.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "../utils/LibString.sol"; + +contract LibStringImp { + using LibString for string; + + function prefixBase32(string calldata data) external pure returns (string memory) { + return LibString.prefixBase32(data); + } + + function prefixHexadecimal(string calldata data) external pure returns (string memory) { + return LibString.prefixHexadecimal(data); + } + + function bytesToBase32(bytes calldata data) external pure returns (string memory) { + return LibString.bytesToBase32(data); + } + + function bytesToHexadecimal(bytes calldata data) external pure returns (string memory) { + return LibString.bytesToHexadecimal(data); + } +} diff --git a/packages/wallet/wallet-contracts/contracts/mocks/ModuleMock.sol b/packages/wallet/wallet-contracts/contracts/mocks/ModuleMock.sol new file mode 100644 index 0000000000..5032d31ecf --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/mocks/ModuleMock.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +contract ModuleMock { + event Pong(); + + function ping() external { + emit Pong(); + } +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/GuestModule.sol b/packages/wallet/wallet-contracts/contracts/modules/GuestModule.sol new file mode 100644 index 0000000000..924fa359e5 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/GuestModule.sol @@ -0,0 +1,103 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "../utils/LibOptim.sol"; + +import "./commons/submodules/auth/SequenceBaseSig.sol"; + +import "./commons/ModuleAuth.sol"; +import "./commons/ModuleCalls.sol"; +import "./commons/ModuleCreator.sol"; + +/** + * GuestModule implements a Sequence wallet without signatures, nonce or replay protection. + * executing transactions using this wallet is not an authenticated process, and can be done by any address. + * + * @notice This contract is completely public with no security, designed to execute pre-signed transactions + * and use Sequence tools without using the wallets. + */ +contract GuestModule is ModuleAuth, ModuleCalls, ModuleCreator { + error DelegateCallNotAllowed(uint256 _index); + error NotSupported(); + + /** + * @notice Allow any caller to execute an action + * @param _txs Transactions to process + */ + function execute(Transaction[] calldata _txs, uint256, bytes calldata) public override { + // Hash transaction bundle + bytes32 txHash = SequenceBaseSig.subdigest(keccak256(abi.encode("guest:", _txs))); + + // Execute the transactions + _executeGuest(txHash, _txs); + } + + /** + * @notice Allow any caller to execute an action + * @param _txs Transactions to process + */ + function selfExecute(Transaction[] calldata _txs) public override { + // Hash transaction bundle + bytes32 txHash = SequenceBaseSig.subdigest(keccak256(abi.encode("self:", _txs))); + + // Execute the transactions + _executeGuest(txHash, _txs); + } + + /** + * @notice Executes a list of transactions + * @param _txHash Hash of the batch of transactions + * @param _txs Transactions to execute + */ + function _executeGuest(bytes32 _txHash, Transaction[] calldata _txs) private { + // Execute transaction + uint256 size = _txs.length; + for (uint256 i = 0; i < size; i++) { + Transaction calldata transaction = _txs[i]; + + if (transaction.delegateCall) revert DelegateCallNotAllowed(i); + + uint256 gasLimit = transaction.gasLimit; + if (gasleft() < gasLimit) revert NotEnoughGas(i, gasLimit, gasleft()); + + bool success = LibOptim.call( + transaction.target, transaction.value, gasLimit == 0 ? gasleft() : gasLimit, transaction.data + ); + + if (success) { + emit TxExecuted(_txHash, i); + } else { + _revertBytes(transaction.revertOnError, _txHash, i, LibOptim.returnData()); + } + } + } + + /** + * @notice Validates any signature image, because the wallet is public and has no owner. + * @return true, all signatures are valid. + */ + function _isValidImage(bytes32) internal pure override returns (bool) { + return true; + } + + /** + * Not supported. + */ + function _updateImageHash(bytes32) internal virtual override { + revert NotSupported(); + } + + /** + * @notice Query if a contract implements an interface + * @param _interfaceID The interface identifier, as specified in ERC-165 + * @return `true` if the contract implements `_interfaceID` + */ + function supportsInterface(bytes4 _interfaceID) + public + pure + override(ModuleAuth, ModuleCalls, ModuleCreator) + returns (bool) + { + return super.supportsInterface(_interfaceID); + } +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/MainModule.sol b/packages/wallet/wallet-contracts/contracts/modules/MainModule.sol new file mode 100644 index 0000000000..f6d87dafb1 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/MainModule.sol @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "./commons/ModuleAuthFixed.sol"; +import "./commons/ModuleHooks.sol"; +import "./commons/ModuleCalls.sol"; +import "./commons/ModuleCreator.sol"; +import "./commons/ModuleExtraAuth.sol"; +import "./commons/ModuleAuthConvenience.sol"; + +/** + * @notice Contains the core functionality Sequence wallets will inherit. + * @dev If using a new main module, developers must ensure that all inherited + * contracts by the main module don't conflict and are accounted for to be + * supported by the supportsInterface method. + */ +contract MainModule is + ModuleAuthFixed, + ModuleExtraAuth, + ModuleCalls, + ModuleHooks, + ModuleCreator, + ModuleAuthConvenience +{ + constructor(address _factory, address _mainModuleUpgradable) ModuleAuthFixed(_factory, _mainModuleUpgradable) {} + + function _isValidImage(bytes32 _imageHash) + internal + view + override(IModuleAuth, ModuleAuthFixed, ModuleExtraAuth) + returns (bool) + { + return super._isValidImage(_imageHash); + } + + /** + * @notice Query if a contract implements an interface + * @param _interfaceID The interface identifier, as specified in ERC-165 + * @return `true` if the contract implements `_interfaceID` + */ + function supportsInterface(bytes4 _interfaceID) + public + pure + override(ModuleAuthFixed, ModuleAuthConvenience, ModuleCalls, ModuleExtraAuth, ModuleHooks, ModuleCreator) + returns (bool) + { + return super.supportsInterface(_interfaceID); + } +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/MainModuleGasEstimation.sol b/packages/wallet/wallet-contracts/contracts/modules/MainModuleGasEstimation.sol new file mode 100644 index 0000000000..60938779b6 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/MainModuleGasEstimation.sol @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "./commons/gas-estimation/ModuleIgnoreAuthUpgradable.sol"; +import "./commons/gas-estimation/ModuleIgnoreNonceCalls.sol"; +import "./commons/ModuleHooks.sol"; +import "./commons/ModuleUpdate.sol"; +import "./commons/ModuleCreator.sol"; + +/** + * @notice Contains an alternative implementation of the MainModules that skips validation of + * signatures, this implementation SHOULD NOT be used directly on a wallet. + * + * Intended to be used only for gas estimation, using eth_call and overrides. + */ +contract MainModuleGasEstimation is + ModuleIgnoreAuthUpgradable, + ModuleIgnoreNonceCalls, + ModuleUpdate, + ModuleHooks, + ModuleCreator +{ + struct SimulateResult { + bool executed; + bool succeeded; + bytes result; + uint256 gasUsed; + } + + /** + * @notice Simulate each transaction in a bundle for gas usage and execution result + * @param _txs Transactions to process + * @return The gas used and execution result for each transaction in the bundle + */ + function simulateExecute(Transaction[] calldata _txs) public virtual returns (SimulateResult[] memory) { + unchecked { + SimulateResult[] memory results = new SimulateResult[](_txs.length); + + // Execute transaction + uint256 size = _txs.length; + for (uint256 i = 0; i < size; i++) { + Transaction calldata transaction = _txs[i]; + uint256 gasLimit = transaction.gasLimit; + + results[i].executed = true; + + if (gasleft() < gasLimit) { + results[i].succeeded = false; + results[i].result = + abi.encodeWithSelector(IModuleCalls.NotEnoughGas.selector, i, gasLimit, gasleft()); + break; + } + + if (transaction.delegateCall) { + uint256 initialGas = gasleft(); + + (results[i].succeeded, results[i].result) = + transaction.target.delegatecall{gas: gasLimit == 0 ? gasleft() : gasLimit}(transaction.data); + + results[i].gasUsed = initialGas - gasleft(); + } else { + uint256 initialGas = gasleft(); + + (results[i].succeeded, results[i].result) = transaction.target + .call{value: transaction.value, gas: gasLimit == 0 ? gasleft() : gasLimit}(transaction.data); + + results[i].gasUsed = initialGas - gasleft(); + } + + if (!results[i].succeeded && transaction.revertOnError) { + break; + } + } + + return results; + } + } + + function _isValidImage(bytes32 _imageHash) + internal + view + override(IModuleAuth, ModuleIgnoreAuthUpgradable) + returns (bool) + { + return super._isValidImage(_imageHash); + } + + /** + * @notice Query if a contract implements an interface + * @param _interfaceID The interface identifier, as specified in ERC-165 + * @dev If using a new main module, developers must ensure that all inherited + * contracts by the main module don't conflict and are accounted for to be + * supported by the supportsInterface method. + * @return `true` if the contract implements `_interfaceID` + */ + function supportsInterface(bytes4 _interfaceID) + public + pure + override(ModuleAuthUpgradable, ModuleCalls, ModuleUpdate, ModuleHooks, ModuleCreator) + returns (bool) + { + return super.supportsInterface(_interfaceID); + } +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/MainModuleUpgradable.sol b/packages/wallet/wallet-contracts/contracts/modules/MainModuleUpgradable.sol new file mode 100644 index 0000000000..5c83d4c5e2 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/MainModuleUpgradable.sol @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "./commons/ModuleAuthUpgradable.sol"; +import "./commons/ModuleHooks.sol"; +import "./commons/ModuleCalls.sol"; +import "./commons/ModuleUpdate.sol"; +import "./commons/ModuleCreator.sol"; +import "./commons/ModuleExtraAuth.sol"; +import "./commons/ModuleAuthConvenience.sol"; + +/** + * @notice Contains the core functionality Sequence wallets will inherit with + * the added functionality that the main module can be changed. + * @dev If using a new main module, developers must ensure that all inherited + * contracts by the main module don't conflict and are accounted for to be + * supported by the supportsInterface method. + */ +contract MainModuleUpgradable is + ModuleAuthUpgradable, + ModuleExtraAuth, + ModuleCalls, + ModuleUpdate, + ModuleHooks, + ModuleCreator, + ModuleAuthConvenience +{ + function _isValidImage(bytes32 _imageHash) + internal + view + override(IModuleAuth, ModuleAuthUpgradable, ModuleExtraAuth) + returns (bool) + { + return super._isValidImage(_imageHash); + } + + /** + * @notice Query if a contract implements an interface + * @param _interfaceID The interface identifier, as specified in ERC-165 + * @dev If using a new main module, developers must ensure that all inherited + * contracts by the main module don't conflict and are accounted for to be + * supported by the supportsInterface method. + * @return `true` if the contract implements `_interfaceID` + */ + function supportsInterface(bytes4 _interfaceID) + public + pure + override( + ModuleAuthUpgradable, + ModuleAuthConvenience, + ModuleCalls, + ModuleExtraAuth, + ModuleUpdate, + ModuleHooks, + ModuleCreator + ) + returns (bool) + { + return super.supportsInterface(_interfaceID); + } +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/commons/Implementation.sol b/packages/wallet/wallet-contracts/contracts/modules/commons/Implementation.sol new file mode 100644 index 0000000000..e517e21886 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/commons/Implementation.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +/** + * @dev Allows modules to access the implementation slot + */ +contract Implementation { + /** + * @notice Updates the Wallet implementation + * @param _imp New implementation address + * @dev The wallet implementation is stored on the storage slot + * defined by the address of the wallet itself + * WARNING updating this value may break the wallet and users + * must be confident that the new implementation is safe. + */ + function _setImplementation(address _imp) internal { + assembly { + sstore(address(), _imp) + } + } + + /** + * @notice Returns the Wallet implementation + * @return _imp The address of the current Wallet implementation + */ + function _getImplementation() internal view returns (address _imp) { + assembly { + _imp := sload(address()) + } + } +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleAuth.sol b/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleAuth.sol new file mode 100644 index 0000000000..f4cd03fef1 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleAuth.sol @@ -0,0 +1,166 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "../../utils/LibBytes.sol"; +import "../../interfaces/IERC1271Wallet.sol"; + +import "./interfaces/IModuleAuth.sol"; + +import "./ModuleERC165.sol"; + +import "./submodules/auth/SequenceBaseSig.sol"; +import "./submodules/auth/SequenceDynamicSig.sol"; +import "./submodules/auth/SequenceNoChainIdSig.sol"; +import "./submodules/auth/SequenceChainedSig.sol"; + +abstract contract ModuleAuth is IModuleAuth, ModuleERC165, IERC1271Wallet, SequenceChainedSig { + using LibBytes for bytes; + + bytes1 internal constant LEGACY_TYPE = hex"00"; + bytes1 internal constant DYNAMIC_TYPE = hex"01"; + bytes1 internal constant NO_CHAIN_ID_TYPE = hex"02"; + bytes1 internal constant CHAINED_TYPE = hex"03"; + + bytes4 internal constant SELECTOR_ERC1271_BYTES_BYTES = 0x20c13b0b; + bytes4 internal constant SELECTOR_ERC1271_BYTES32_BYTES = 0x1626ba7e; + + /** + * @notice Recovers the threshold, weight, imageHash, subdigest, and checkpoint of a signature. + * @dev The signature must be prefixed with a type byte, which is used to determine the recovery method. + * + * @param _digest Digest of the signed data. + * @param _signature A Sequence signature. + * + * @return threshold The required number of signatures needed to consider the signature valid. + * @return weight The actual number of signatures collected in the signature. + * @return imageHash The imageHash of the configuration that signed the message. + * @return subdigest A modified version of the original digest, unique for each wallet/network. + * @return checkpoint A nonce that is incremented every time a new configuration is set. + */ + function signatureRecovery(bytes32 _digest, bytes calldata _signature) + public + view + virtual + override + returns (uint256 threshold, uint256 weight, bytes32 imageHash, bytes32 subdigest, uint256 checkpoint) + { + bytes1 signatureType = _signature[0]; + + if (signatureType == LEGACY_TYPE) { + // networkId digest + base recover + subdigest = SequenceBaseSig.subdigest(_digest); + (threshold, weight, imageHash, checkpoint) = SequenceBaseSig.recover(subdigest, _signature); + return (threshold, weight, imageHash, subdigest, checkpoint); + } + + if (signatureType == DYNAMIC_TYPE) { + // networkId digest + dynamic recover + subdigest = SequenceBaseSig.subdigest(_digest); + (threshold, weight, imageHash, checkpoint) = SequenceDynamicSig.recover(subdigest, _signature); + return (threshold, weight, imageHash, subdigest, checkpoint); + } + + if (signatureType == NO_CHAIN_ID_TYPE) { + // noChainId digest + dynamic recover + subdigest = SequenceNoChainIdSig.subdigest(_digest); + (threshold, weight, imageHash, checkpoint) = SequenceDynamicSig.recover(subdigest, _signature); + return (threshold, weight, imageHash, subdigest, checkpoint); + } + + if (signatureType == CHAINED_TYPE) { + // original digest + chained recover + // (subdigest will be computed in the chained recover) + return chainedRecover(_digest, _signature); + } + + revert InvalidSignatureType(signatureType); + } + + /** + * @dev Validates a signature. + * + * @param _digest Digest of the signed data. + * @param _signature A Sequence signature. + * + * @return isValid Indicates whether the signature is valid or not. + * @return subdigest A modified version of the original digest, unique for each wallet/network. + */ + function _signatureValidation(bytes32 _digest, bytes calldata _signature) + internal + view + virtual + override + returns (bool isValid, bytes32 subdigest) + { + uint256 threshold; + uint256 weight; + bytes32 imageHash; + (threshold, weight, imageHash, subdigest,) = signatureRecovery(_digest, _signature); + isValid = weight >= threshold && _isValidImage(imageHash); + } + + /** + * @notice Verifies whether the provided signature is valid with respect to the provided data + * @dev MUST return the correct magic value if the signature provided is valid for the provided data + * > The bytes4 magic value to return when signature is valid is 0x20c13b0b : bytes4(keccak256("isValidSignature(bytes,bytes)")) + * @param _data Arbitrary length data signed on the behalf of address(this) + * @param _signatures Signature byte array associated with _data. + * Encoded as abi.encode(Signature[], Configs) + * @return magicValue Magic value 0x20c13b0b if the signature is valid and 0x0 otherwise + */ + function isValidSignature(bytes calldata _data, bytes calldata _signatures) + public + view + virtual + override + returns (bytes4) + { + // Validate signatures + (bool isValid,) = _signatureValidation(keccak256(_data), _signatures); + if (isValid) { + return SELECTOR_ERC1271_BYTES_BYTES; + } + + return bytes4(0); + } + + /** + * @notice Verifies whether the provided signature is valid with respect to the provided hash + * @dev MUST return the correct magic value if the signature provided is valid for the provided hash + * > The bytes4 magic value to return when signature is valid is 0x1626ba7e : bytes4(keccak256("isValidSignature(bytes32,bytes)")) + * @param _hash keccak256 hash that was signed + * @param _signatures Signature byte array associated with _data. + * Encoded as abi.encode(Signature[], Configs) + * @return magicValue Magic value 0x1626ba7e if the signature is valid and 0x0 otherwise + */ + function isValidSignature(bytes32 _hash, bytes calldata _signatures) public view virtual override returns (bytes4) { + // Validate signatures + (bool isValid,) = _signatureValidation(_hash, _signatures); + if (isValid) { + return SELECTOR_ERC1271_BYTES32_BYTES; + } + + return bytes4(0); + } + + /** + * @notice Query if a contract implements an interface + * @param _interfaceID The interface identifier, as specified in ERC-165 + * @return `true` if the contract implements `_interfaceID` + */ + function supportsInterface(bytes4 _interfaceID) public pure virtual override returns (bool) { + if (_interfaceID == type(IModuleAuth).interfaceId || _interfaceID == type(IERC1271Wallet).interfaceId) { + return true; + } + + return super.supportsInterface(_interfaceID); + } + + /** + * @notice Updates the signers configuration of the wallet + * @param _imageHash New required image hash of the signature + */ + function updateImageHash(bytes32 _imageHash) external virtual override onlySelf { + _updateImageHash(_imageHash); + } +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleAuthConvenience.sol b/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleAuthConvenience.sol new file mode 100644 index 0000000000..5ffc115230 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleAuthConvenience.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "./ModuleSelfAuth.sol"; +import "./ModuleAuth.sol"; +import "./ModuleIPFS.sol"; +import "./ModuleERC165.sol"; + +import "../../utils/LibString.sol"; + +abstract contract ModuleAuthConvenience is ModuleERC165, ModuleSelfAuth, ModuleAuth, ModuleIPFS { + /** + * @notice Updates the image hash and the IPFS root in a single operation. + * @dev These two operations are often performed together, so this function + * allows to save some gas by performing them in a single step. + * + * @param _imageHash The new image hash to be set. + * @param _ipfsRoot The new IPFS root to be set. + */ + function updateImageHashAndIPFS(bytes32 _imageHash, bytes32 _ipfsRoot) external onlySelf { + _updateImageHash(_imageHash); + _updateIPFSRoot(_ipfsRoot); + } + + /** + * @notice Query if a contract implements an interface + * @param _interfaceID The interface identifier, as specified in ERC-165 + * @return `true` if the contract implements `_interfaceID` + */ + function supportsInterface(bytes4 _interfaceID) + public + pure + virtual + override(ModuleERC165, ModuleAuth) + returns (bool) + { + if (_interfaceID == type(ModuleAuthConvenience).interfaceId) { + return true; + } + + return super.supportsInterface(_interfaceID); + } +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleAuthFixed.sol b/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleAuthFixed.sol new file mode 100644 index 0000000000..80160dc4c4 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleAuthFixed.sol @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "./ModuleAuth.sol"; +import "./ModuleUpdate.sol"; +import "./ModuleSelfAuth.sol"; +import "./ModuleStorage.sol"; + +import "../../Wallet.sol"; + +/** + * Implements ModuleAuth by validating the signature image against + * the salt used to deploy the contract + * + * This module allows wallets to be deployed with a default configuration + * without using any aditional contract storage + */ +abstract contract ModuleAuthFixed is ModuleSelfAuth, ModuleAuth, ModuleUpdate { + bytes32 public immutable INIT_CODE_HASH; + address public immutable FACTORY; + address public immutable UPGRADEABLE_IMPLEMENTATION; + + constructor(address _factory, address _mainModuleUpgradeable) { + // Build init code hash of the deployed wallets using that module + bytes32 initCodeHash = keccak256(abi.encodePacked(Wallet.creationCode, uint256(uint160(address(this))))); + + INIT_CODE_HASH = initCodeHash; + FACTORY = _factory; + UPGRADEABLE_IMPLEMENTATION = _mainModuleUpgradeable; + } + + /** + * @notice Updates the configuration of the wallet + * @dev In the process of updating the configuration, the wallet implementation + * is updated to the mainModuleUpgradeable, this only happens once in the + * lifetime of the wallet. + * + * @param _imageHash New required image hash of the signature + */ + function _updateImageHash(bytes32 _imageHash) internal virtual override { + // Update imageHash in storage + if (_imageHash == bytes32(0)) revert ImageHashIsZero(); + ModuleStorage.writeBytes32(IMAGE_HASH_KEY, _imageHash); + emit ImageHashUpdated(_imageHash); + + // Update wallet implementation to mainModuleUpgradeable + _updateImplementation(UPGRADEABLE_IMPLEMENTATION); + } + + /** + * @notice Validates the signature image with the salt used to deploy the contract + * @param _imageHash Hash image of signature + * @return true if the signature image is valid + */ + function _isValidImage(bytes32 _imageHash) internal view virtual override returns (bool) { + return address(uint160(uint256(keccak256(abi.encodePacked(hex"ff", FACTORY, _imageHash, INIT_CODE_HASH))))) + == address(this); + } + + /** + * @notice Query if a contract implements an interface + * @param _interfaceID The interface identifier, as specified in ERC-165 + * @return `true` if the contract implements `_interfaceID` + */ + function supportsInterface(bytes4 _interfaceID) + public + pure + virtual + override(ModuleAuth, ModuleUpdate) + returns (bool) + { + return super.supportsInterface(_interfaceID); + } +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleAuthUpgradable.sol b/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleAuthUpgradable.sol new file mode 100644 index 0000000000..c0585b4a13 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleAuthUpgradable.sol @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "./interfaces/IModuleAuthUpgradable.sol"; + +import "./ModuleSelfAuth.sol"; +import "./ModuleAuth.sol"; +import "./ModuleStorage.sol"; + +abstract contract ModuleAuthUpgradable is IModuleAuthUpgradable, ModuleSelfAuth, ModuleAuth { + /** + * @notice Updates the signers configuration of the wallet + * @param _imageHash New required image hash of the signature + */ + function _updateImageHash(bytes32 _imageHash) internal virtual override { + if (_imageHash == bytes32(0)) revert ImageHashIsZero(); + ModuleStorage.writeBytes32(IMAGE_HASH_KEY, _imageHash); + emit ImageHashUpdated(_imageHash); + } + + /** + * @notice Returns the current image hash of the wallet + */ + function imageHash() external view virtual override returns (bytes32) { + return ModuleStorage.readBytes32(IMAGE_HASH_KEY); + } + + /** + * @notice Validates the signature image with a valid image hash defined + * in the contract storage + * @param _imageHash Hash image of signature + * @return true if the signature image is valid + */ + function _isValidImage(bytes32 _imageHash) internal view virtual override returns (bool) { + return _imageHash != bytes32(0) && _imageHash == ModuleStorage.readBytes32(IMAGE_HASH_KEY); + } + + /** + * @notice Query if a contract implements an interface + * @param _interfaceID The interface identifier, as specified in ERC-165 + * @return `true` if the contract implements `_interfaceID` + */ + function supportsInterface(bytes4 _interfaceID) public pure virtual override returns (bool) { + if (_interfaceID == type(IModuleAuthUpgradable).interfaceId) { + return true; + } + + return super.supportsInterface(_interfaceID); + } +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleCalls.sol b/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleCalls.sol new file mode 100644 index 0000000000..44221fa61b --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleCalls.sol @@ -0,0 +1,131 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "./ModuleSelfAuth.sol"; +import "./ModuleStorage.sol"; +import "./ModuleERC165.sol"; +import "./ModuleNonce.sol"; +import "./ModuleOnlyDelegatecall.sol"; + +import "./interfaces/IModuleCalls.sol"; +import "./interfaces/IModuleAuth.sol"; + +import "./submodules/nonce/SubModuleNonce.sol"; +import "./submodules/auth/SequenceBaseSig.sol"; + +import "../../utils/LibOptim.sol"; + +abstract contract ModuleCalls is + IModuleCalls, + IModuleAuth, + ModuleERC165, + ModuleOnlyDelegatecall, + ModuleSelfAuth, + ModuleNonce +{ + /** + * @notice Allow wallet owner to execute an action + * @dev Relayers must ensure that the gasLimit specified for each transaction + * is acceptable to them. A user could specify large enough that it could + * consume all the gas available. + * @param _txs Transactions to process + * @param _nonce Signature nonce (may contain an encoded space) + * @param _signature Encoded signature + */ + function execute(Transaction[] calldata _txs, uint256 _nonce, bytes calldata _signature) + external + virtual + override + onlyDelegatecall + { + // Validate and update nonce + _validateNonce(_nonce); + + // Hash and verify transaction bundle + (bool isValid, bytes32 txHash) = _signatureValidation(keccak256(abi.encode(_nonce, _txs)), _signature); + + if (!isValid) { + revert InvalidSignature(txHash, _signature); + } + + // Execute the transactions + _execute(txHash, _txs); + } + + /** + * @notice Allow wallet to execute an action + * without signing the message + * @param _txs Transactions to execute + */ + function selfExecute(Transaction[] calldata _txs) external virtual override onlySelf { + // Hash transaction bundle + bytes32 txHash = SequenceBaseSig.subdigest(keccak256(abi.encode("self:", _txs))); + + // Execute the transactions + _execute(txHash, _txs); + } + + /** + * @notice Executes a list of transactions + * @param _txHash Hash of the batch of transactions + * @param _txs Transactions to execute + */ + function _execute(bytes32 _txHash, Transaction[] calldata _txs) private { + unchecked { + // Execute transaction + uint256 size = _txs.length; + for (uint256 i = 0; i < size; i++) { + Transaction calldata transaction = _txs[i]; + uint256 gasLimit = transaction.gasLimit; + + if (gasleft() < gasLimit) revert NotEnoughGas(i, gasLimit, gasleft()); + + bool success; + if (transaction.delegateCall) { + success = LibOptim.delegatecall( + transaction.target, gasLimit == 0 ? gasleft() : gasLimit, transaction.data + ); + } else { + success = LibOptim.call( + transaction.target, transaction.value, gasLimit == 0 ? gasleft() : gasLimit, transaction.data + ); + } + + if (success) { + emit TxExecuted(_txHash, i); + } else { + // Avoid copy of return data until neccesary + _revertBytes(transaction.revertOnError, _txHash, i, LibOptim.returnData()); + } + } + } + } + + /** + * @notice Logs a failed transaction, reverts if the transaction is not optional + * @param _revertOnError Signals if it should revert or just log + * @param _txHash Hash of the transaction + * @param _index Index of the transaction in the batch + * @param _reason Encoded revert message + */ + function _revertBytes(bool _revertOnError, bytes32 _txHash, uint256 _index, bytes memory _reason) internal { + if (_revertOnError) { + assembly { revert(add(_reason, 0x20), mload(_reason)) } + } else { + emit TxFailed(_txHash, _index, _reason); + } + } + + /** + * @notice Query if a contract implements an interface + * @param _interfaceID The interface identifier, as specified in ERC-165 + * @return `true` if the contract implements `_interfaceID` + */ + function supportsInterface(bytes4 _interfaceID) public pure virtual override returns (bool) { + if (_interfaceID == type(IModuleCalls).interfaceId) { + return true; + } + + return super.supportsInterface(_interfaceID); + } +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleCreator.sol b/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleCreator.sol new file mode 100644 index 0000000000..2e75ce1ae8 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleCreator.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "./interfaces/IModuleCreator.sol"; + +import "./ModuleSelfAuth.sol"; +import "./ModuleERC165.sol"; + +contract ModuleCreator is IModuleCreator, ModuleERC165, ModuleSelfAuth { + event CreatedContract(address _contract); + + /** + * @notice Creates a contract forwarding eth value + * @param _code Creation code of the contract + * @return addr The address of the created contract + */ + function createContract(bytes memory _code) public payable virtual override onlySelf returns (address addr) { + assembly { addr := create(callvalue(), add(_code, 32), mload(_code)) } + if (addr == address(0)) revert CreateFailed(_code); + emit CreatedContract(addr); + } + + /** + * @notice Query if a contract implements an interface + * @param _interfaceID The interface identifier, as specified in ERC-165 + * @return `true` if the contract implements `_interfaceID` + */ + function supportsInterface(bytes4 _interfaceID) public pure virtual override returns (bool) { + if (_interfaceID == type(IModuleCreator).interfaceId) { + return true; + } + + return super.supportsInterface(_interfaceID); + } +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleERC165.sol b/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleERC165.sol new file mode 100644 index 0000000000..8cf8eaad09 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleERC165.sol @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +abstract contract ModuleERC165 { + /** + * @notice Query if a contract implements an interface + * @param _interfaceID The interface identifier, as specified in ERC-165 + * @dev Adding new hooks will not lead to them being reported by this function + * without upgrading the wallet. In addition, developers must ensure that + * all inherited contracts by the main module don't conflict and are accounted + * to be supported by the supportsInterface method. + * @return `true` if the contract implements `_interfaceID` + */ + function supportsInterface(bytes4 _interfaceID) public pure virtual returns (bool) { + return _interfaceID == this.supportsInterface.selector; + } +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleERC5719.sol b/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleERC5719.sol new file mode 100644 index 0000000000..669e86d62c --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleERC5719.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "./ModuleIPFS.sol"; + +import "../../utils/LibString.sol"; + +contract ModuleERC5719 is ModuleIPFS { + function getAlternativeSignature(bytes32 _digest) external view returns (string memory) { + return string( + abi.encodePacked( + ipfsRoot(), + "/ERC5719/", + LibString.prefixHexadecimal(LibString.bytesToHexadecimal(abi.encodePacked(_digest))) + ) + ); + } +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleExtraAuth.sol b/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleExtraAuth.sol new file mode 100644 index 0000000000..f7642fc60a --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleExtraAuth.sol @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "./ModuleAuth.sol"; +import "./ModuleStorage.sol"; +import "./ModuleSelfAuth.sol"; +import "./ModuleERC165.sol"; + +abstract contract ModuleExtraAuth is ModuleERC165, ModuleSelfAuth, ModuleAuth { + // EXTRA_IMAGE_HASH_KEY = keccak256("org.sequence.module.static.auth.extra.image.hash"); + bytes32 private constant EXTRA_IMAGE_HASH_KEY = + bytes32(0x849e7bdc245db17e50b9f43086f1914d70eb4dab6dd89af4d541d53353ad97de); + + event SetExtraImageHash(bytes32 indexed _imageHash, uint256 _expiration); + + function _writeExpirationForImageHash(bytes32 _imageHash, uint256 _expiration) internal { + ModuleStorage.writeBytes32Map(EXTRA_IMAGE_HASH_KEY, _imageHash, bytes32(_expiration)); + } + + function _readExpirationForImageHash(bytes32 _imageHash) internal view returns (uint256 _expiration) { + return uint256(ModuleStorage.readBytes32Map(EXTRA_IMAGE_HASH_KEY, _imageHash)); + } + + function _isValidImage(bytes32 _imageHash) internal view virtual override returns (bool) { + if (super._isValidImage(_imageHash)) { + return true; + } + + uint256 expiration = _readExpirationForImageHash(_imageHash); + + // solhint-disable-next-line not-rely-on-time + return expiration != 0 && expiration > block.timestamp; + } + + function extraImageHash(bytes32 _imageHash) public view returns (uint256) { + return _readExpirationForImageHash(_imageHash); + } + + function setExtraImageHash(bytes32 _imageHash, uint256 _expiration) external onlySelf { + _writeExpirationForImageHash(_imageHash, _expiration); + + emit SetExtraImageHash(_imageHash, _expiration); + } + + function clearExtraImageHashes(bytes32[] calldata _imageHashes) external onlySelf { + unchecked { + uint256 imageHashesLength = _imageHashes.length; + for (uint256 i = 0; i < imageHashesLength; i++) { + bytes32 imageHash = _imageHashes[i]; + _writeExpirationForImageHash(imageHash, 0); + + emit SetExtraImageHash(imageHash, 0); + } + } + } + + /** + * @notice Query if a contract implements an interface + * @param _interfaceID The interface identifier, as specified in ERC-165 + * @return `true` if the contract implements `_interfaceID` + */ + function supportsInterface(bytes4 _interfaceID) + public + pure + virtual + override(ModuleERC165, ModuleAuth) + returns (bool) + { + if (_interfaceID == type(ModuleExtraAuth).interfaceId) { + return true; + } + + return super.supportsInterface(_interfaceID); + } +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleHooks.sol b/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleHooks.sol new file mode 100644 index 0000000000..f0fb61b284 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleHooks.sol @@ -0,0 +1,142 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "./interfaces/IModuleHooks.sol"; + +import "./ModuleSelfAuth.sol"; +import "./ModuleStorage.sol"; +import "./ModuleERC165.sol"; + +import "../../interfaces/receivers/IERC1155Receiver.sol"; +import "../../interfaces/receivers/IERC721Receiver.sol"; +import "../../interfaces/receivers/IERC223Receiver.sol"; + +contract ModuleHooks is IERC1155Receiver, IERC721Receiver, IModuleHooks, ModuleERC165, ModuleSelfAuth { + // HOOKS_KEY = keccak256("org.arcadeum.module.hooks.hooks"); + bytes32 private constant HOOKS_KEY = bytes32(0xbe27a319efc8734e89e26ba4bc95f5c788584163b959f03fa04e2d7ab4b9a120); + + /** + * @notice Reads the implementation hook of a signature + * @param _signature Signature function + * @return The address of the implementation hook, address(0) if none + */ + function readHook(bytes4 _signature) external view virtual override returns (address) { + return _readHook(_signature); + } + + /** + * @notice Adds a new hook to handle a given function selector + * @param _signature Signature function linked to the hook + * @param _implementation Hook implementation contract + * @dev Can't overwrite hooks that are part of the main module (those defined below) + */ + function addHook(bytes4 _signature, address _implementation) external virtual override onlySelf { + if (_readHook(_signature) != address(0)) revert HookAlreadyExists(_signature); + _writeHook(_signature, _implementation); + } + + /** + * @notice Removes a registered hook + * @param _signature Signature function linked to the hook + * @dev Can't remove hooks that are part of the main module (those defined below) + * without upgrading the wallet + */ + function removeHook(bytes4 _signature) external virtual override onlySelf { + if (_readHook(_signature) == address(0)) revert HookDoesNotExist(_signature); + _writeHook(_signature, address(0)); + } + + /** + * @notice Reads the implementation hook of a signature + * @param _signature Signature function + * @return The address of the implementation hook, address(0) if none + */ + function _readHook(bytes4 _signature) private view returns (address) { + return address(uint160(uint256(ModuleStorage.readBytes32Map(HOOKS_KEY, _signature)))); + } + + /** + * @notice Writes the implementation hook of a signature + * @param _signature Signature function + * @param _implementation Hook implementation contract + */ + function _writeHook(bytes4 _signature, address _implementation) private { + ModuleStorage.writeBytes32Map(HOOKS_KEY, _signature, bytes32(uint256(uint160(_implementation)))); + emit DefinedHook(_signature, _implementation); + } + + /** + * @notice Handle the receipt of a single ERC1155 token type. + * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` + */ + function onERC1155Received(address, address, uint256, uint256, bytes calldata) + external + virtual + override + returns (bytes4) + { + return ModuleHooks.onERC1155Received.selector; + } + + /** + * @notice Handle the receipt of multiple ERC1155 token types. + * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` + */ + function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) + external + virtual + override + returns (bytes4) + { + return ModuleHooks.onERC1155BatchReceived.selector; + } + + /** + * @notice Handle the receipt of a single ERC721 token. + * @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` + */ + function onERC721Received(address, address, uint256, bytes calldata) external virtual override returns (bytes4) { + return ModuleHooks.onERC721Received.selector; + } + + /** + * @notice Routes fallback calls through hooks + */ + fallback() external payable { + if (msg.data.length >= 4) { + address target = _readHook(msg.sig); + if (target != address(0)) { + (bool success, bytes memory result) = target.delegatecall(msg.data); + assembly { + if iszero(success) { + revert(add(result, 0x20), mload(result)) + } + + return(add(result, 0x20), mload(result)) + } + } + } + } + + /** + * @notice Allows the wallet to receive ETH + */ + receive() external payable {} + + /** + * @notice Query if a contract implements an interface + * @param _interfaceID The interface identifier, as specified in ERC-165 + * @return `true` if the contract implements `_interfaceID` + */ + function supportsInterface(bytes4 _interfaceID) public pure virtual override returns (bool) { + if ( + _interfaceID == type(IModuleHooks).interfaceId || _interfaceID == type(IERC1155Receiver).interfaceId + || _interfaceID == type(IERC721Receiver).interfaceId + || _interfaceID == type(IERC223Receiver).interfaceId + ) { + return true; + } + + return super.supportsInterface(_interfaceID); + } +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleIPFS.sol b/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleIPFS.sol new file mode 100644 index 0000000000..7241db83ea --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleIPFS.sol @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "./ModuleSelfAuth.sol"; +import "./ModuleStorage.sol"; + +import "../../utils/LibString.sol"; + +contract ModuleIPFS is ModuleSelfAuth { + event IPFSRootUpdated(bytes32 _hash); + + // IPFS_ROOT_KEY = keccak256("sequence.ipfs.root") + bytes32 private constant IPFS_ROOT_KEY = + bytes32(0x0eecac93ced8722d209199364cda3bc33da3bc3a23daef6be49ebd780511d033); + + function ipfsRootBytes32() public view returns (bytes32) { + return ModuleStorage.readBytes32(IPFS_ROOT_KEY); + } + + function ipfsRoot() public view returns (string memory) { + return string( + abi.encodePacked( + "ipfs://", + LibString.prefixBase32(LibString.bytesToBase32(abi.encodePacked(hex"01701220", ipfsRootBytes32()))) + ) + ); + } + + function updateIPFSRoot(bytes32 _hash) external onlySelf { + _updateIPFSRoot(_hash); + } + + function _updateIPFSRoot(bytes32 _hash) internal { + ModuleStorage.writeBytes32(IPFS_ROOT_KEY, _hash); + emit IPFSRootUpdated(_hash); + } +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleNonce.sol b/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleNonce.sol new file mode 100644 index 0000000000..ebdbaa31ac --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleNonce.sol @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "./ModuleStorage.sol"; + +import "./submodules/nonce/SubModuleNonce.sol"; + +contract ModuleNonce { + // Events + event NonceChange(uint256 _space, uint256 _newNonce); + + // Errors + error BadNonce(uint256 _space, uint256 _provided, uint256 _current); + + // NONCE_KEY = keccak256("org.arcadeum.module.calls.nonce"); + bytes32 private constant NONCE_KEY = bytes32(0x8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e); + + /** + * @notice Returns the next nonce of the default nonce space + * @dev The default nonce space is 0x00 + * @return The next nonce + */ + function nonce() external view virtual returns (uint256) { + return readNonce(0); + } + + /** + * @notice Returns the next nonce of the given nonce space + * @param _space Nonce space, each space keeps an independent nonce count + * @return The next nonce + */ + function readNonce(uint256 _space) public view virtual returns (uint256) { + return uint256(ModuleStorage.readBytes32Map(NONCE_KEY, bytes32(_space))); + } + + /** + * @notice Changes the next nonce of the given nonce space + * @param _space Nonce space, each space keeps an independent nonce count + * @param _nonce Nonce to write on the space + */ + function _writeNonce(uint256 _space, uint256 _nonce) internal { + ModuleStorage.writeBytes32Map(NONCE_KEY, bytes32(_space), bytes32(_nonce)); + } + + /** + * @notice Verify if a nonce is valid + * @param _rawNonce Nonce to validate (may contain an encoded space) + */ + function _validateNonce(uint256 _rawNonce) internal virtual { + // Retrieve current nonce for this wallet + (uint256 space, uint256 providedNonce) = SubModuleNonce.decodeNonce(_rawNonce); + + uint256 currentNonce = readNonce(space); + if (currentNonce != providedNonce) { + revert BadNonce(space, providedNonce, currentNonce); + } + + unchecked { + uint256 newNonce = providedNonce + 1; + + _writeNonce(space, newNonce); + emit NonceChange(space, newNonce); + return; + } + } +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleOnlyDelegatecall.sol b/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleOnlyDelegatecall.sol new file mode 100644 index 0000000000..6d4113a938 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleOnlyDelegatecall.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +contract ModuleOnlyDelegatecall { + address private immutable self; + + error OnlyDelegatecall(); + + constructor() { + self = address(this); + } + + /** + * @notice Modifier that only allows functions to be called via delegatecall. + */ + modifier onlyDelegatecall() { + if (address(this) == self) { + revert OnlyDelegatecall(); + } + _; + } +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleSelfAuth.sol b/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleSelfAuth.sol new file mode 100644 index 0000000000..42bfde5337 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleSelfAuth.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +contract ModuleSelfAuth { + error OnlySelfAuth(address _sender, address _self); + + modifier onlySelf() { + if (msg.sender != address(this)) { + revert OnlySelfAuth(msg.sender, address(this)); + } + _; + } +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleStorage.sol b/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleStorage.sol new file mode 100644 index 0000000000..61230a10a1 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleStorage.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +library ModuleStorage { + function writeBytes32(bytes32 _key, bytes32 _val) internal { + assembly { sstore(_key, _val) } + } + + function readBytes32(bytes32 _key) internal view returns (bytes32 val) { + assembly { val := sload(_key) } + } + + function writeBytes32Map(bytes32 _key, bytes32 _subKey, bytes32 _val) internal { + bytes32 key = keccak256(abi.encode(_key, _subKey)); + assembly { sstore(key, _val) } + } + + function readBytes32Map(bytes32 _key, bytes32 _subKey) internal view returns (bytes32 val) { + bytes32 key = keccak256(abi.encode(_key, _subKey)); + assembly { val := sload(key) } + } +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleUpdate.sol b/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleUpdate.sol new file mode 100644 index 0000000000..cc8cb7abd1 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/commons/ModuleUpdate.sol @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "./interfaces/IModuleUpdate.sol"; + +import "./Implementation.sol"; +import "./ModuleSelfAuth.sol"; +import "./ModuleERC165.sol"; + +import "../../utils/LibAddress.sol"; + +contract ModuleUpdate is IModuleUpdate, ModuleERC165, ModuleSelfAuth, Implementation { + using LibAddress for address; + + event ImplementationUpdated(address newImplementation); + + /** + * @notice Updates the implementation of the base wallet + * @param _implementation New main module implementation + * @dev WARNING Updating the implementation can brick the wallet + */ + function updateImplementation(address _implementation) external virtual override onlySelf { + _updateImplementation(_implementation); + } + + /** + * @notice Updates the implementation of the base wallet, used internally. + * @param _implementation New main module implementation + * @dev WARNING Updating the implementation can brick the wallet + */ + function _updateImplementation(address _implementation) internal virtual override { + if (!_implementation.isContract()) revert InvalidImplementation(_implementation); + _setImplementation(_implementation); + emit ImplementationUpdated(_implementation); + } + + /** + * @notice Query if a contract implements an interface + * @param _interfaceID The interface identifier, as specified in ERC-165 + * @return `true` if the contract implements `_interfaceID` + */ + function supportsInterface(bytes4 _interfaceID) public pure virtual override returns (bool) { + if (_interfaceID == type(IModuleUpdate).interfaceId) { + return true; + } + + return super.supportsInterface(_interfaceID); + } +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/commons/gas-estimation/ModuleIgnoreAuthUpgradable.sol b/packages/wallet/wallet-contracts/contracts/modules/commons/gas-estimation/ModuleIgnoreAuthUpgradable.sol new file mode 100644 index 0000000000..300ebaaa9b --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/commons/gas-estimation/ModuleIgnoreAuthUpgradable.sol @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "./../ModuleAuthUpgradable.sol"; + +/** + * @notice Implements ModuleAuthUpgradable but ignores the validity of the signature + * should only be used during gas estimation. + */ +abstract contract ModuleIgnoreAuthUpgradable is ModuleAuthUpgradable { + /** + * @notice Removes the signature validation from the module, by returning true for any _imageHash + * @param _imageHash Hash image of signature + * @return true always + */ + function _isValidImage(bytes32 _imageHash) internal view virtual override(ModuleAuthUpgradable) returns (bool) { + // Still validates the imageHash using the original mechanism for a more acurate estimation + return super._isValidImage(_imageHash) || true; + } +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/commons/gas-estimation/ModuleIgnoreNonceCalls.sol b/packages/wallet/wallet-contracts/contracts/modules/commons/gas-estimation/ModuleIgnoreNonceCalls.sol new file mode 100644 index 0000000000..86447adfe2 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/commons/gas-estimation/ModuleIgnoreNonceCalls.sol @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "./../ModuleCalls.sol"; + +import "./../submodules/nonce/SubModuleNonce.sol"; + +/** + * @notice Implements ModuleCalls but ignores the validity of the nonce + * should only be used during gas estimation. + */ +abstract contract ModuleIgnoreNonceCalls is ModuleCalls { + /** + * @notice Verify if a nonce is valid + * @param _rawNonce Nonce to validate (may contain an encoded space) + */ + function _validateNonce(uint256 _rawNonce) internal virtual override { + // Retrieve current nonce for this wallet + (uint256 space, uint256 providedNonce) = SubModuleNonce.decodeNonce(_rawNonce); + + uint256 currentNonce = readNonce(space); + if (currentNonce != providedNonce && false) { + revert BadNonce(space, providedNonce, currentNonce); + } + + unchecked { + uint256 newNonce = providedNonce + 1; + + _writeNonce(space, newNonce); + emit NonceChange(space, newNonce); + return; + } + } +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/commons/interfaces/IModuleAuth.sol b/packages/wallet/wallet-contracts/contracts/modules/commons/interfaces/IModuleAuth.sol new file mode 100644 index 0000000000..1311b09412 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/commons/interfaces/IModuleAuth.sol @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +abstract contract IModuleAuth { + // IMAGE_HASH_KEY = keccak256("org.arcadeum.module.auth.upgradable.image.hash"); + bytes32 internal constant IMAGE_HASH_KEY = + bytes32(0xea7157fa25e3aa17d0ae2d5280fa4e24d421c61842aa85e45194e1145aa72bf8); + + event ImageHashUpdated(bytes32 newImageHash); + + // Errors + error ImageHashIsZero(); + error InvalidSignatureType(bytes1 _type); + + function _signatureValidation(bytes32 _digest, bytes calldata _signature) + internal + view + virtual + returns (bool isValid, bytes32 subdigest); + + function signatureRecovery(bytes32 _digest, bytes calldata _signature) + public + view + virtual + returns (uint256 threshold, uint256 weight, bytes32 imageHash, bytes32 subdigest, uint256 checkpoint); + + /** + * @notice Validates the signature image + * @return true if the signature image is valid + */ + function _isValidImage(bytes32) internal view virtual returns (bool) { + return false; + } + + /** + * @notice Updates the signers configuration of the wallet + * @param _imageHash New required image hash of the signature + */ + function updateImageHash(bytes32 _imageHash) external virtual; + + /** + * @notice Updates the signers configuration of the wallet + * @param _imageHash New required image hash of the signature + */ + function _updateImageHash(bytes32 _imageHash) internal virtual; +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/commons/interfaces/IModuleAuthUpgradable.sol b/packages/wallet/wallet-contracts/contracts/modules/commons/interfaces/IModuleAuthUpgradable.sol new file mode 100644 index 0000000000..c782a7b895 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/commons/interfaces/IModuleAuthUpgradable.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +interface IModuleAuthUpgradable { + /** + * @notice Returns the current image hash of the wallet + */ + function imageHash() external view returns (bytes32); +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/commons/interfaces/IModuleCalls.sol b/packages/wallet/wallet-contracts/contracts/modules/commons/interfaces/IModuleCalls.sol new file mode 100644 index 0000000000..259130ea16 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/commons/interfaces/IModuleCalls.sol @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +interface IModuleCalls { + // Events + event TxFailed(bytes32 indexed _tx, uint256 _index, bytes _reason); + event TxExecuted(bytes32 indexed _tx, uint256 _index); + + // Errors + error NotEnoughGas(uint256 _index, uint256 _requested, uint256 _available); + error InvalidSignature(bytes32 _hash, bytes _signature); + + // Transaction structure + struct Transaction { + bool delegateCall; // Performs delegatecall + bool revertOnError; // Reverts transaction bundle if tx fails + uint256 gasLimit; // Maximum gas to be forwarded + address target; // Address of the contract to call + uint256 value; // Amount of ETH to pass with the call + bytes data; // calldata to pass + } + + /** + * @notice Allow wallet owner to execute an action + * @param _txs Transactions to process + * @param _nonce Signature nonce (may contain an encoded space) + * @param _signature Encoded signature + */ + function execute(Transaction[] calldata _txs, uint256 _nonce, bytes calldata _signature) external; + + /** + * @notice Allow wallet to execute an action + * without signing the message + * @param _txs Transactions to execute + */ + function selfExecute(Transaction[] calldata _txs) external; +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/commons/interfaces/IModuleCreator.sol b/packages/wallet/wallet-contracts/contracts/modules/commons/interfaces/IModuleCreator.sol new file mode 100644 index 0000000000..f658425bdb --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/commons/interfaces/IModuleCreator.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +interface IModuleCreator { + error CreateFailed(bytes _code); + + /** + * @notice Creates a contract forwarding eth value + * @param _code Creation code of the contract + * @return addr The address of the created contract + */ + function createContract(bytes calldata _code) external payable returns (address addr); +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/commons/interfaces/IModuleHooks.sol b/packages/wallet/wallet-contracts/contracts/modules/commons/interfaces/IModuleHooks.sol new file mode 100644 index 0000000000..3c38c60818 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/commons/interfaces/IModuleHooks.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +interface IModuleHooks { + // Errors + error HookAlreadyExists(bytes4 _signature); + error HookDoesNotExist(bytes4 _signature); + + // Events + event DefinedHook(bytes4 _signature, address _implementation); + + /** + * @notice Reads the implementation hook of a signature + * @param _signature Signature function + * @return The address of the implementation hook, address(0) if none + */ + function readHook(bytes4 _signature) external view returns (address); + + /** + * @notice Adds a new hook to handle a given function selector + * @param _signature Signature function linked to the hook + * @param _implementation Hook implementation contract + */ + function addHook(bytes4 _signature, address _implementation) external; + + /** + * @notice Removes a registered hook + * @param _signature Signature function linked to the hook + */ + function removeHook(bytes4 _signature) external; +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/commons/interfaces/IModuleUpdate.sol b/packages/wallet/wallet-contracts/contracts/modules/commons/interfaces/IModuleUpdate.sol new file mode 100644 index 0000000000..8818937524 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/commons/interfaces/IModuleUpdate.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +abstract contract IModuleUpdate { + // Errors + error InvalidImplementation(address _implementation); + + /** + * @notice Updates the implementation of the base wallet + * @param _implementation New main module implementation + * @dev WARNING Updating the implementation can brick the wallet + */ + function updateImplementation(address _implementation) external virtual; + + /** + * @notice Updates the implementation of the base wallet, used internally. + * @param _implementation New main module implementation + * @dev WARNING Updating the implementation can brick the wallet + */ + function _updateImplementation(address _implementation) internal virtual; +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol b/packages/wallet/wallet-contracts/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol new file mode 100644 index 0000000000..ea62144d0c --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol @@ -0,0 +1,255 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "../../../../utils/SignatureValidator.sol"; +import "../../../../utils/LibBytesPointer.sol"; +import "../../../../utils/LibBytes.sol"; +import "../../../../utils/LibOptim.sol"; + +/** + * @title SequenceBaseSig Library + * @author Agustin Aguilar (aa@horizon.io) + * @notice A Solidity implementation for handling signatures in the Sequence protocol. + */ +library SequenceBaseSig { + using LibBytesPointer for bytes; + + uint256 internal constant FLAG_SIGNATURE = 0; + uint256 internal constant FLAG_ADDRESS = 1; + uint256 internal constant FLAG_DYNAMIC_SIGNATURE = 2; + uint256 internal constant FLAG_NODE = 3; + uint256 internal constant FLAG_BRANCH = 4; + uint256 internal constant FLAG_SUBDIGEST = 5; + uint256 internal constant FLAG_NESTED = 6; + + error InvalidNestedSignature(bytes32 _hash, address _addr, bytes _signature); + error InvalidSignatureFlag(uint256 _flag); + + /** + * @notice Generates a subdigest for the input digest (unique for this wallet and network). + * @param _digest The input digest to generate the subdigest from. + * @return bytes32 The subdigest generated from the input digest. + */ + function subdigest(bytes32 _digest) internal view returns (bytes32) { + return keccak256(abi.encodePacked("\x19\x01", block.chainid, address(this), _digest)); + } + + /** + * @notice Generates the leaf for an address and weight. + * @dev The leaf is generated by concatenating the address and weight. + * + * @param _addr The address to generate the leaf for. + * @param _weight The weight to generate the leaf for. + * @return bytes32 The leaf generated from the address and weight. + */ + function _leafForAddressAndWeight(address _addr, uint96 _weight) internal pure returns (bytes32) { + unchecked { + return bytes32(uint256(_weight) << 160 | uint256(uint160(_addr))); + } + } + + /** + * @notice Generates the leaf for a hardcoded subdigest. + * @dev The leaf is generated by hashing 'Sequence static digest:\n' and the subdigest. + * @param _subdigest The subdigest to generate the leaf for. + * @return bytes32 The leaf generated from the hardcoded subdigest. + */ + function _leafForHardcodedSubdigest(bytes32 _subdigest) internal pure returns (bytes32) { + return keccak256(abi.encodePacked("Sequence static digest:\n", _subdigest)); + } + + /** + * @notice Generates the leaf for a nested tree node. + * @dev The leaf is generated by hashing 'Sequence nested config:\n', the node, the threshold and the weight. + * + * @param _node The root of the node to generate the leaf for. + * @param _threshold The internal threshold of the tree. + * @param _weight The external weight of the tree. + * @return bytes32 The leaf generated from the nested tree. + */ + function _leafForNested(bytes32 _node, uint256 _threshold, uint256 _weight) internal pure returns (bytes32) { + return keccak256(abi.encodePacked("Sequence nested config:\n", _node, _threshold, _weight)); + } + + /** + * @notice Returns the weight and root of a signature branch. + * @dev If the signature contains a hardcoded subdigest, and it matches the input digest, then the weight is set to 2 ** 256 - 1. + * + * @param _subdigest The digest to verify the signature against. + * @param _signature The signature branch to recover. + * @return weight The total weight of the recovered signatures. + * @return root The root hash of the recovered configuration. + */ + function recoverBranch(bytes32 _subdigest, bytes calldata _signature) + internal + view + returns (uint256 weight, bytes32 root) + { + unchecked { + uint256 rindex; + + // Iterate until the image is completed + while (rindex < _signature.length) { + // Read next item type + uint256 flag; + (flag, rindex) = _signature.readUint8(rindex); + + if (flag == FLAG_ADDRESS) { + // Read plain address + uint8 addrWeight; + address addr; + (addrWeight, addr, rindex) = _signature.readUint8Address(rindex); + + // Write weight and address to image + bytes32 node = _leafForAddressAndWeight(addr, addrWeight); + root = root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node; + continue; + } + + if (flag == FLAG_SIGNATURE) { + // Read weight + uint8 addrWeight; + (addrWeight, rindex) = _signature.readUint8(rindex); + + // Read single signature and recover signer + uint256 nrindex = rindex + 66; + address addr = SignatureValidator.recoverSigner(_subdigest, _signature[rindex:nrindex]); + rindex = nrindex; + + // Acumulate total weight of the signature + weight += addrWeight; + + // Write weight and address to image + bytes32 node = _leafForAddressAndWeight(addr, addrWeight); + root = root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node; + continue; + } + + if (flag == FLAG_DYNAMIC_SIGNATURE) { + // Read signer and weight + uint8 addrWeight; + address addr; + (addrWeight, addr, rindex) = _signature.readUint8Address(rindex); + + // Read signature size + uint256 size; + (size, rindex) = _signature.readUint24(rindex); + + // Read dynamic size signature + uint256 nrindex = rindex + size; + if (!SignatureValidator.isValidSignature(_subdigest, addr, _signature[rindex:nrindex])) { + revert InvalidNestedSignature(_subdigest, addr, _signature[rindex:nrindex]); + } + rindex = nrindex; + + // Acumulate total weight of the signature + weight += addrWeight; + + // Write weight and address to image + bytes32 node = _leafForAddressAndWeight(addr, addrWeight); + root = root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node; + continue; + } + + if (flag == FLAG_NODE) { + // Read node hash + bytes32 node; + (node, rindex) = _signature.readBytes32(rindex); + root = root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node; + continue; + } + + if (flag == FLAG_BRANCH) { + // Enter a branch of the signature merkle tree + uint256 size; + (size, rindex) = _signature.readUint24(rindex); + uint256 nrindex = rindex + size; + + uint256 nweight; + bytes32 node; + (nweight, node) = recoverBranch(_subdigest, _signature[rindex:nrindex]); + + weight += nweight; + root = LibOptim.fkeccak256(root, node); + + rindex = nrindex; + continue; + } + + if (flag == FLAG_NESTED) { + // Enter a branch of the signature merkle tree + // but with an internal threshold and an external fixed weight + uint256 externalWeight; + (externalWeight, rindex) = _signature.readUint8(rindex); + + uint256 internalThreshold; + (internalThreshold, rindex) = _signature.readUint16(rindex); + + uint256 size; + (size, rindex) = _signature.readUint24(rindex); + uint256 nrindex = rindex + size; + + uint256 internalWeight; + bytes32 internalRoot; + (internalWeight, internalRoot) = recoverBranch(_subdigest, _signature[rindex:nrindex]); + rindex = nrindex; + + if (internalWeight >= internalThreshold) { + weight += externalWeight; + } + + bytes32 node = _leafForNested(internalRoot, internalThreshold, externalWeight); + root = root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node; + + continue; + } + + if (flag == FLAG_SUBDIGEST) { + // A hardcoded always accepted digest + // it pushes the weight to the maximum + bytes32 hardcoded; + (hardcoded, rindex) = _signature.readBytes32(rindex); + if (hardcoded == _subdigest) { + weight = type(uint256).max; + } + + bytes32 node = _leafForHardcodedSubdigest(hardcoded); + root = root != bytes32(0) ? LibOptim.fkeccak256(root, node) : node; + continue; + } + + revert InvalidSignatureFlag(flag); + } + } + } + + /** + * @notice Returns the threshold, weight, root, and checkpoint of a signature. + * @dev To verify the signature, the weight must be greater than or equal to the threshold, and the root + * must match the expected `imageHash` of the wallet. + * + * @param _subdigest The digest to verify the signature against. + * @param _signature The signature to recover. + * @return threshold The minimum weight required for the signature to be valid. + * @return weight The total weight of the recovered signatures. + * @return imageHash The root hash of the recovered configuration + * @return checkpoint The checkpoint of the signature. + */ + function recover(bytes32 _subdigest, bytes calldata _signature) + internal + view + returns (uint256 threshold, uint256 weight, bytes32 imageHash, uint256 checkpoint) + { + unchecked { + (weight, imageHash) = recoverBranch(_subdigest, _signature[6:]); + + // Threshold & checkpoint are the top nodes + // (but they are first on the signature) + threshold = LibBytes.readFirstUint16(_signature); + checkpoint = LibBytes.readUint32(_signature, 2); + + imageHash = LibOptim.fkeccak256(imageHash, bytes32(threshold)); + imageHash = LibOptim.fkeccak256(imageHash, bytes32(checkpoint)); + } + } +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol b/packages/wallet/wallet-contracts/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol new file mode 100644 index 0000000000..cfa2486c8a --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "./SequenceBaseSig.sol"; + +import "../../interfaces/IModuleAuth.sol"; + +import "../../ModuleSelfAuth.sol"; +import "../../ModuleStorage.sol"; + +import "../../../../utils/LibBytesPointer.sol"; +import "../../../../utils/LibOptim.sol"; + +/** + * @title Sequence chained auth recovery submodule + * @author Agustin Aguilar (aa@horizon.io) + * @notice Defines Sequence signatures that work by delegating control to new configurations. + * @dev The delegations can be chained together, the first signature is the one that is used to validate + * the message, the last signature must match the current on-chain configuration of the wallet. + */ +abstract contract SequenceChainedSig is IModuleAuth, ModuleSelfAuth { + using LibBytesPointer for bytes; + + bytes32 public constant SET_IMAGE_HASH_TYPE_HASH = keccak256("SetImageHash(bytes32 imageHash)"); + + error LowWeightChainedSignature(bytes _signature, uint256 threshold, uint256 _weight); + error WrongChainedCheckpointOrder(uint256 _current, uint256 _prev); + + /** + * @notice Defined the special token that must be signed to delegate control to a new configuration. + * @param _imageHash The hash of the new configuration. + * @return bytes32 The message hash to be signed. + */ + function _hashSetImageHashStruct(bytes32 _imageHash) internal pure returns (bytes32) { + return LibOptim.fkeccak256(SET_IMAGE_HASH_TYPE_HASH, _imageHash); + } + + /** + * @notice Returns the threshold, weight, root, and checkpoint of a (chained) signature. + * + * @dev This method return the `threshold`, `weight` and `imageHash` of the last signature in the chain. + * Intermediate signatures are validated directly in this method. The `subdigest` is the one of the + * first signature in the chain (since that's the one that is used to validate the message). + * + * @param _digest The digest to recover the signature from. + * @param _signature The signature to recover. + * @return threshold The threshold of the (last) signature. + * @return weight The weight of the (last) signature. + * @return imageHash The image hash of the (last) signature. + * @return subdigest The subdigest of the (first) signature in the chain. + * @return checkpoint The checkpoint of the (last) signature. + */ + function chainedRecover(bytes32 _digest, bytes calldata _signature) + internal + view + returns (uint256 threshold, uint256 weight, bytes32 imageHash, bytes32 subdigest, uint256 checkpoint) + { + uint256 rindex = 1; + uint256 sigSize; + + // + // First signature out of the loop + // + + // First uint24 is the size of the signature + (sigSize, rindex) = _signature.readUint24(rindex); + uint256 nrindex = sigSize + rindex; + + (threshold, weight, imageHash, subdigest, checkpoint) = signatureRecovery(_digest, _signature[rindex:nrindex]); + + if (weight < threshold) { + revert LowWeightChainedSignature(_signature[rindex:nrindex], threshold, weight); + } + + rindex = nrindex; + + // The following signatures are handled by this loop. + // This is done this way because the first signature does not have a + // checkpoint to be validated against. + while (rindex < _signature.length) { + // First uint24 is the size of the signature + (sigSize, rindex) = _signature.readUint24(rindex); + nrindex = sigSize + rindex; + + uint256 nextCheckpoint; + + ( + threshold, + weight, + imageHash,, + // Do not change the subdigest; + // it should remain that of the first signature. + nextCheckpoint + ) = signatureRecovery(_hashSetImageHashStruct(imageHash), _signature[rindex:nrindex]); + + // Validate signature + if (weight < threshold) { + revert LowWeightChainedSignature(_signature[rindex:nrindex], threshold, weight); + } + + // Checkpoints must be provided in descending order + // since the first signature is the one that is used to validate the message + // and the last signature is the one that is used to validate the current configuration + if (nextCheckpoint >= checkpoint) { + revert WrongChainedCheckpointOrder(nextCheckpoint, checkpoint); + } + + checkpoint = nextCheckpoint; + rindex = nrindex; + } + } +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol b/packages/wallet/wallet-contracts/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol new file mode 100644 index 0000000000..a4704cac0b --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "./SequenceBaseSig.sol"; + +library SequenceDynamicSig { + /** + * @notice Recover a "dynamically encoded" Sequence signature. + * @dev The Signature is stripped of the first byte, which is the encoding flag. + * + * @param _subdigest The digest of the signature. + * @param _signature The Sequence signature. + * @return threshold The threshold weight required to validate the signature. + * @return weight The weight of the signature. + * @return imageHash The hash of the recovered configuration. + * @return checkpoint The checkpoint of the configuration. + */ + function recover(bytes32 _subdigest, bytes calldata _signature) + internal + view + returns (uint256 threshold, uint256 weight, bytes32 imageHash, uint256 checkpoint) + { + return SequenceBaseSig.recover(_subdigest, _signature[1:]); + } +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol b/packages/wallet/wallet-contracts/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol new file mode 100644 index 0000000000..d8fd0a9dc1 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +library SequenceNoChainIdSig { + /** + * @notice Computes a subdigest for a Sequence signature that works on all chains. + * @dev The subdigest is computed by removing the chain ID from the digest (using 0 instead). + * @param _digest The digest of the chain of signatures. + * @return bytes32 The subdigest with no chain ID. + */ + function subdigest(bytes32 _digest) internal view returns (bytes32) { + return keccak256(abi.encodePacked("\x19\x01", uint256(0), address(this), _digest)); + } +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol b/packages/wallet/wallet-contracts/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol new file mode 100644 index 0000000000..6ecee90e8b --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +library SubModuleNonce { + // Nonce schema + // + // - space[160]:nonce[96] + // + uint256 internal constant NONCE_BITS = 96; + bytes32 internal constant NONCE_MASK = bytes32(uint256(type(uint96).max)); + + /** + * @notice Decodes a raw nonce + * @dev Schema: space[160]:type[96] + * @param _rawNonce Nonce to be decoded + * @return _space The nonce space of the raw nonce + * @return _nonce The nonce of the raw nonce + */ + function decodeNonce(uint256 _rawNonce) internal pure returns (uint256 _space, uint256 _nonce) { + unchecked { + // Decode nonce + _space = _rawNonce >> NONCE_BITS; + _nonce = uint256(bytes32(_rawNonce) & NONCE_MASK); + } + } + + function encodeNonce(uint256 _space, uint256 _nonce) internal pure returns (uint256) { + unchecked { + // Combine space and nonce + return (_space << NONCE_BITS) | _nonce; + } + } +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/utils/GasEstimator.sol b/packages/wallet/wallet-contracts/contracts/modules/utils/GasEstimator.sol new file mode 100644 index 0000000000..fe1b1c5ef9 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/utils/GasEstimator.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +contract GasEstimator { + function estimate(address _to, bytes calldata _data) + external + returns (bool success, bytes memory result, uint256 gas) + { + // solhint-disable + uint256 initialGas = gasleft(); + (success, result) = _to.call(_data); + gas = initialGas - gasleft(); + // solhint-enable + } +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/utils/MultiCallUtils.sol b/packages/wallet/wallet-contracts/contracts/modules/utils/MultiCallUtils.sol new file mode 100644 index 0000000000..7ad33e6c77 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/utils/MultiCallUtils.sol @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "../commons/interfaces/IModuleCalls.sol"; + +contract MultiCallUtils { + // Errors + error DelegateCallNotAllowed(uint256 _index); + error CallReverted(uint256 _index, bytes _result); + + function multiCall(IModuleCalls.Transaction[] memory _txs) + public + payable + returns (bool[] memory _successes, bytes[] memory _results) + { + _successes = new bool[](_txs.length); + _results = new bytes[](_txs.length); + + for (uint256 i = 0; i < _txs.length; i++) { + IModuleCalls.Transaction memory transaction = _txs[i]; + + if (transaction.delegateCall) revert DelegateCallNotAllowed(i); + if (gasleft() < transaction.gasLimit) revert IModuleCalls.NotEnoughGas(i, transaction.gasLimit, gasleft()); + + // solhint-disable + (_successes[i], _results[i]) = transaction.target + .call{ + value: transaction.value, gas: transaction.gasLimit == 0 ? gasleft() : transaction.gasLimit + }(transaction.data); + // solhint-enable + + if (!_successes[i] && _txs[i].revertOnError) revert CallReverted(i, _results[i]); + } + } + + // /// + // Globals + // /// + + function callBlockhash(uint256 _i) external view returns (bytes32) { + return blockhash(_i); + } + + function callCoinbase() external view returns (address) { + return block.coinbase; + } + + function callDifficulty() external view returns (uint256) { + return block.prevrandao; // old block.difficulty + } + + function callPrevrandao() external view returns (uint256) { + return block.prevrandao; + } + + function callGasLimit() external view returns (uint256) { + return block.gaslimit; + } + + function callBlockNumber() external view returns (uint256) { + return block.number; + } + + function callTimestamp() external view returns (uint256) { + return block.timestamp; + } + + function callGasLeft() external view returns (uint256) { + return gasleft(); + } + + function callGasPrice() external view returns (uint256) { + return tx.gasprice; + } + + function callOrigin() external view returns (address) { + return tx.origin; + } + + function callBalanceOf(address _addr) external view returns (uint256) { + return _addr.balance; + } + + function callCodeSize(address _addr) external view returns (uint256 size) { + assembly { size := extcodesize(_addr) } + } + + function callCode(address _addr) external view returns (bytes memory code) { + assembly { + let size := extcodesize(_addr) + code := mload(0x40) + mstore(0x40, add(code, and(add(add(size, 0x20), 0x1f), not(0x1f)))) + mstore(code, size) + extcodecopy(_addr, add(code, 0x20), 0, size) + } + } + + function callCodeHash(address _addr) external view returns (bytes32 codeHash) { + assembly { codeHash := extcodehash(_addr) } + } + + function callChainId() external view returns (uint256 id) { + assembly { id := chainid() } + } +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/utils/RequireUtils.sol b/packages/wallet/wallet-contracts/contracts/modules/utils/RequireUtils.sol new file mode 100644 index 0000000000..e89f773217 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/utils/RequireUtils.sol @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "../commons/ModuleNonce.sol"; +import "../commons/submodules/nonce/SubModuleNonce.sol"; + +import "../../interfaces/tokens/IERC20.sol"; +import "../../interfaces/tokens/IERC721.sol"; +import "../../interfaces/tokens/IERC1155.sol"; + +contract RequireUtils { + /** + * @notice Validates that a given expiration hasn't expired + * @dev Used as an optional transaction on a Sequence batch, to create expirable transactions. + * + * @param _expiration Expiration to check + */ + function requireNonExpired(uint256 _expiration) external view { + require(block.timestamp < _expiration, "RequireUtils#requireNonExpired: EXPIRED"); + } + + /** + * @notice Validates that a given wallet has reached a given nonce + * @dev Used as an optional transaction on a Sequence batch, to define transaction execution order + * + * @param _wallet Sequence wallet + * @param _nonce Required nonce + */ + function requireMinNonce(address _wallet, uint256 _nonce) external view { + (uint256 space, uint256 nonce) = SubModuleNonce.decodeNonce(_nonce); + uint256 currentNonce = ModuleNonce(_wallet).readNonce(space); + require(currentNonce >= nonce, "RequireUtils#requireMinNonce: NONCE_BELOW_REQUIRED"); + } + + /** + * @notice Validates that a wallet has a minimum ERC20 token balance + * @param _token ERC20 token address + * @param _wallet Sequence wallet + * @param _minBalance Minimum required balance + */ + function requireMinERC20Balance(address _token, address _wallet, uint256 _minBalance) external view { + uint256 balance = IERC20(_token).balanceOf(_wallet); + require(balance >= _minBalance, "RequireUtils#requireMinERC20Balance: BALANCE_TOO_LOW"); + } + + /** + * @notice Validates that a wallet has a minimum ERC20 allowance for a spender + * @param _token ERC20 token address + * @param _owner Sequence wallet + * @param _spender Address allowed to spend the tokens + * @param _minAllowance Minimum required allowance + */ + function requireMinERC20Allowance(address _token, address _owner, address _spender, uint256 _minAllowance) + external + view + { + uint256 allowance = IERC20(_token).allowance(_owner, _spender); + require(allowance >= _minAllowance, "RequireUtils#requireMinERC20Allowance: ALLOWANCE_TOO_LOW"); + } + + /** + * @notice Validates that a wallet owns a specific ERC721 token + * @param _token ERC721 token address + * @param _wallet Sequence wallet + * @param _tokenId Token ID to check for ownership + */ + function requireERC721Ownership(address _token, address _wallet, uint256 _tokenId) external view { + address owner = IERC721(_token).ownerOf(_tokenId); + require(owner == _wallet, "RequireUtils#requireERC721Ownership: NOT_OWNER"); + } + + /** + * @notice Validates that an ERC721 token is approved for a specific spender + * @param _token ERC721 token address + * @param _owner Sequence wallet + * @param _spender Address that should have approval + * @param _tokenId Token ID to check for approval + */ + function requireERC721Approval(address _token, address _owner, address _spender, uint256 _tokenId) external view { + address approved = IERC721(_token).getApproved(_tokenId); + require( + approved == _spender || IERC721(_token).isApprovedForAll(_owner, _spender), + "RequireUtils#requireERC721Approval: NOT_APPROVED" + ); + } + + /** + * @notice Validates that a wallet has a minimum balance of an ERC1155 token + * @param _token ERC1155 token address + * @param _wallet Sequence wallet + * @param _tokenId Token ID to check + * @param _minBalance Minimum required balance + */ + function requireMinERC1155Balance(address _token, address _wallet, uint256 _tokenId, uint256 _minBalance) + external + view + { + uint256 balance = IERC1155(_token).balanceOf(_wallet, _tokenId); + require(balance >= _minBalance, "RequireUtils#requireMinERC1155Balance: BALANCE_TOO_LOW"); + } + + /** + * @notice Validates that an ERC1155 token is approved for a specific operator + * @param _token ERC1155 token address + * @param _owner Sequence wallet + * @param _operator Address that should have operator approval + */ + function requireERC1155Approval(address _token, address _owner, address _operator) external view { + bool isApproved = IERC1155(_token).isApprovedForAll(_owner, _operator); + require(isApproved, "RequireUtils#requireERC1155Approval: NOT_APPROVED"); + } +} diff --git a/packages/wallet/wallet-contracts/contracts/modules/utils/SequenceUtils.sol b/packages/wallet/wallet-contracts/contracts/modules/utils/SequenceUtils.sol new file mode 100644 index 0000000000..6e9f294fa8 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/modules/utils/SequenceUtils.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "./MultiCallUtils.sol"; +import "./RequireUtils.sol"; + +contract SequenceUtils is MultiCallUtils, RequireUtils {} diff --git a/packages/wallet/wallet-contracts/contracts/trust/Trust.sol b/packages/wallet/wallet-contracts/contracts/trust/Trust.sol new file mode 100644 index 0000000000..3bdfc359af --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/trust/Trust.sol @@ -0,0 +1,160 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "../interfaces/IERC1271Wallet.sol"; +import "../utils/SignatureValidator.sol"; + +function absDiff(uint256 a, uint256 b) pure returns (bool, uint256) { + if (a > b) { + return (true, a - b); + } + + return (false, b - a); +} + +contract Trust is IERC1271Wallet { + error UnlockInThePast(uint256 _unlocksAt, uint256 _elapsed); + error UnlockTooEarly(uint256 _unlocksAt, uint256 _diff); + + error NotOwner(address _sender); + error NotUnlocked(uint256 _unlocksAt); + error FailedTransaction(address payable _to, uint256 _value, bytes _data, bytes _result); + + error EmptySignature(); + error InvalidSignatureFlag(bytes _signature, bytes1 _flag); + error InvalidSignature(bytes32 _hash, bytes32 _rehash, address _signer, bytes _signature); + + event SetUnlocksAt(uint256 _unlocksAt); + event SentTransaction(address payable _to, uint256 _value, bytes _data, bytes _result); + + address public immutable owner; + address public immutable beneficiary; + uint256 public immutable duration; + + uint256 public unlocksAt = type(uint256).max; + + constructor(address _owner, address _beneficiary, uint256 _duration) { + owner = _owner; + beneficiary = _beneficiary; + duration = _duration; + } + + modifier onlyAllowed() { + if (msg.sender != owner) { + if (msg.sender != beneficiary) { + revert NotOwner(msg.sender); + } + + if (isLocked()) { + revert NotUnlocked(unlocksAt); + } + } + + _; + } + + modifier onlyMember() { + if (msg.sender != owner && msg.sender != beneficiary) { + revert NotOwner(msg.sender); + } + + _; + } + + function isLocked() public view returns (bool) { + return block.timestamp < unlocksAt; + } + + function setUnlocksAt(uint256 _unlocksAt) external onlyMember { + // Diff between the current time and the unlock time must be + // greater than the duration of the trust + (bool isPast, uint256 elapsed) = absDiff(block.timestamp, _unlocksAt); + if (isPast) { + revert UnlockInThePast(_unlocksAt, elapsed); + } + + if (elapsed < duration) { + revert UnlockTooEarly(_unlocksAt, elapsed); + } + + emit SetUnlocksAt(_unlocksAt); + unlocksAt = _unlocksAt; + } + + function sendTransaction(address payable _to, uint256 _value, bytes calldata _data) + external + onlyAllowed + returns (bytes memory) + { + (bool success, bytes memory result) = _to.call{value: _value}(_data); + + if (!success) { + revert FailedTransaction(_to, _value, _data, result); + } + + emit SentTransaction(_to, _value, _data, result); + return result; + } + + bytes4 internal constant SELECTOR_ERC1271_BYTES_BYTES = 0x20c13b0b; + bytes4 internal constant SELECTOR_ERC1271_BYTES32_BYTES = 0x1626ba7e; + + function isValidSignature(bytes calldata _data, bytes calldata _signature) external view returns (bytes4) { + bytes4 res = Trust(payable(address((this)))).isValidSignature(keccak256(_data), _signature); + + assert(res == SELECTOR_ERC1271_BYTES32_BYTES); + return SELECTOR_ERC1271_BYTES_BYTES; + } + + function isValidSignature(bytes32 _hash, bytes calldata _signature) external view returns (bytes4) { + if (_signature.length == 0) { + revert EmptySignature(); + } + + // The last byte determines how the signature is going to be interpreted + // 0x00 -> Signed by the owner + // 0x01 -> Signed by the beneficiary + // 0x02 -> Signed by the owner for any network + // 0x03 -> Signed by the beneficiary for any network + address signer; + uint256 chainId; + + { + bytes1 flag = _signature[_signature.length - 1]; + + if (flag == 0x00) { + signer = owner; + chainId = block.chainid; + } else if (flag == 0x01) { + signer = beneficiary; + chainId = block.chainid; + } else if (flag == 0x02) { + signer = owner; + chainId = 0; + } else if (flag == 0x03) { + signer = beneficiary; + chainId = 0; + } else { + revert InvalidSignatureFlag(_signature, flag); + } + } + + if (signer != owner && isLocked()) { + revert NotUnlocked(unlocksAt); + } + + // Re-hash the hash adding the address of the trust + // otherwise the signature will be valid for any trust + bytes32 rehash = keccak256(abi.encode(address(this), _hash, chainId)); + + // Validate the signature + if (!SignatureValidator.isValidSignature(rehash, signer, _signature[0:_signature.length - 1])) { + revert InvalidSignature(_hash, rehash, signer, _signature[0:_signature.length - 1]); + } + + return SELECTOR_ERC1271_BYTES32_BYTES; + } + + receive() external payable {} + fallback() external payable {} +} diff --git a/packages/wallet/wallet-contracts/contracts/trust/TrustFactory.sol b/packages/wallet/wallet-contracts/contracts/trust/TrustFactory.sol new file mode 100644 index 0000000000..1dd900efcb --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/trust/TrustFactory.sol @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "./Trust.sol"; + +contract TrustFactory { + function trustCreationCode() external pure returns (bytes memory) { + return type(Trust).creationCode; + } + + function addressOf(address _owner, address _beneficiary, uint256 _duration) external view returns (address) { + return address( + uint160( + uint256( + keccak256( + abi.encodePacked( + bytes1(0xff), + address(this), + bytes32(0), + keccak256( + abi.encodePacked(type(Trust).creationCode, abi.encode(_owner, _beneficiary, _duration)) + ) + ) + ) + ) + ) + ); + } + + function deploy(address _owner, address _beneficiary, uint256 _duration) external returns (Trust) { + return new Trust{salt: bytes32(0)}(_owner, _beneficiary, _duration); + } +} diff --git a/packages/wallet/wallet-contracts/contracts/utils/LibAddress.sol b/packages/wallet/wallet-contracts/contracts/utils/LibAddress.sol new file mode 100644 index 0000000000..9095dc64ad --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/utils/LibAddress.sol @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +library LibAddress { + /** + * @notice Will return true if provided address is a contract + * @param account Address to verify if contract or not + * @dev This contract will return false if called within the constructor of + * a contract's deployment, as the code is not yet stored on-chain. + */ + function isContract(address account) internal view returns (bool) { + uint256 csize; + // solhint-disable-next-line no-inline-assembly + assembly { csize := extcodesize(account) } + return csize != 0; + } +} diff --git a/packages/wallet/wallet-contracts/contracts/utils/LibBytes.sol b/packages/wallet/wallet-contracts/contracts/utils/LibBytes.sol new file mode 100644 index 0000000000..20860e754c --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/utils/LibBytes.sol @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +/** + * @title Library for reading data from bytes arrays + * @author Agustin Aguilar (aa@horizon.io) + * @notice This library contains functions for reading data from bytes arrays. + * + * @dev These functions do not check if the input index is within the bounds of the data array. + * Reading out of bounds may return dirty values. + */ +library LibBytes { + /** + * @notice Returns the bytes32 value at the given index in the input data. + * @param data The input data. + * @param index The index of the value to retrieve. + * @return a The bytes32 value at the given index. + */ + function readBytes32(bytes calldata data, uint256 index) internal pure returns (bytes32 a) { + assembly { + a := calldataload(add(data.offset, index)) + } + } + + /** + * @notice Returns the uint8 value at the given index in the input data. + * @param data The input data. + * @param index The index of the value to retrieve. + * @return a The uint8 value at the given index. + */ + function readUint8(bytes calldata data, uint256 index) internal pure returns (uint8 a) { + assembly { + let word := calldataload(add(index, data.offset)) + a := shr(248, word) + } + } + + /** + * @notice Returns the first uint16 value in the input data. + * @param data The input data. + * @return a The first uint16 value in the input data. + */ + function readFirstUint16(bytes calldata data) internal pure returns (uint16 a) { + assembly { + let word := calldataload(data.offset) + a := shr(240, word) + } + } + + /** + * @notice Returns the uint32 value at the given index in the input data. + * @param data The input data. + * @param index The index of the value to retrieve. + * @return a The uint32 value at the given index. + */ + function readUint32(bytes calldata data, uint256 index) internal pure returns (uint32 a) { + assembly { + let word := calldataload(add(index, data.offset)) + a := shr(224, word) + } + } + + function readMBytes4(bytes memory data, uint256 index) internal pure returns (bytes4 a) { + assembly { + let word := mload(add(add(data, 0x20), index)) + a := and(word, 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000) + } + } + + function readMBytes32(bytes memory data, uint256 index) internal pure returns (bytes32 a) { + assembly { + a := mload(add(add(data, 0x20), index)) + } + } +} diff --git a/packages/wallet/wallet-contracts/contracts/utils/LibBytesPointer.sol b/packages/wallet/wallet-contracts/contracts/utils/LibBytesPointer.sol new file mode 100644 index 0000000000..021f9b2496 --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/utils/LibBytesPointer.sol @@ -0,0 +1,150 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +/** + * @title Library for reading data from bytes arrays with a pointer + * @author Agustin Aguilar (aa@horizon.io) + * @notice This library contains functions for reading data from bytes arrays with a pointer. + * + * @dev These functions do not check if the input index is within the bounds of the data array. + * Reading out of bounds may return dirty values. + */ +library LibBytesPointer { + /** + * @dev Returns the first uint16 value in the input data and updates the pointer. + * @param _data The input data. + * @return a The first uint16 value. + * @return newPointer The new pointer. + */ + function readFirstUint16(bytes calldata _data) internal pure returns (uint16 a, uint256 newPointer) { + assembly { + let word := calldataload(_data.offset) + a := shr(240, word) + newPointer := 2 + } + } + + /** + * @notice Returns the uint8 value at the given index in the input data and updates the pointer. + * @param _data The input data. + * @param _index The index of the value to retrieve. + * @return a The uint8 value at the given index. + * @return newPointer The new pointer. + */ + function readUint8(bytes calldata _data, uint256 _index) internal pure returns (uint8 a, uint256 newPointer) { + assembly { + let word := calldataload(add(_index, _data.offset)) + a := shr(248, word) + newPointer := add(_index, 1) + } + } + + function readAddress(bytes calldata _data, uint256 _index) internal pure returns (address a, uint256 newPointer) { + assembly { + let word := calldataload(add(_index, _data.offset)) + a := and(shr(96, word), 0xffffffffffffffffffffffffffffffffffffffff) + newPointer := add(_index, 20) + } + } + + /** + * @notice Returns the uint8 value and the address at the given index in the input data and updates the pointer. + * @param _data The input data. + * @param _index The index of the value to retrieve. + * @return a The uint8 value at the given index. + * @return b The following address value. + * @return newPointer The new pointer. + */ + function readUint8Address(bytes calldata _data, uint256 _index) + internal + pure + returns (uint8 a, address b, uint256 newPointer) + { + assembly { + let word := calldataload(add(_index, _data.offset)) + a := shr(248, word) + b := and(shr(88, word), 0xffffffffffffffffffffffffffffffffffffffff) + newPointer := add(_index, 21) + } + } + + /** + * @notice Returns the uint16 value at the given index in the input data and updates the pointer. + * @param _data The input data. + * @param _index The index of the value to retrieve. + * @return a The uint16 value at the given index. + * @return newPointer The new pointer. + */ + function readUint16(bytes calldata _data, uint256 _index) internal pure returns (uint16 a, uint256 newPointer) { + assembly { + let word := calldataload(add(_index, _data.offset)) + a := and(shr(240, word), 0xffff) + newPointer := add(_index, 2) + } + } + + function readUintX(bytes calldata _data, uint256 _bytes, uint256 _index) + internal + pure + returns (uint256 a, uint256 newPointer) + { + assembly { + let word := calldataload(add(_index, _data.offset)) + let shift := sub(256, mul(_bytes, 8)) + a := and(shr(shift, word), sub(shl(mul(8, _bytes), 1), 1)) + newPointer := add(_index, _bytes) + } + } + + /** + * @notice Returns the uint24 value at the given index in the input data and updates the pointer. + * @param _data The input data. + * @param _index The index of the value to retrieve. + * @return a The uint24 value at the given index. + * @return newPointer The new pointer. + */ + function readUint24(bytes calldata _data, uint256 _index) internal pure returns (uint24 a, uint256 newPointer) { + assembly { + let word := calldataload(add(_index, _data.offset)) + a := and(shr(232, word), 0xffffff) + newPointer := add(_index, 3) + } + } + + /** + * @notice Returns the uint64 value at the given index in the input data and updates the pointer. + * @param _data The input data. + * @param _index The index of the value to retrieve. + * @return a The uint64 value at the given index. + * @return newPointer The new pointer. + */ + function readUint64(bytes calldata _data, uint256 _index) internal pure returns (uint64 a, uint256 newPointer) { + assembly { + let word := calldataload(add(_index, _data.offset)) + a := and(shr(192, word), 0xffffffffffffffff) + newPointer := add(_index, 8) + } + } + + function readBytes4(bytes calldata _data, uint256 _pointer) internal pure returns (bytes4 a, uint256 newPointer) { + assembly { + a := calldataload(add(_pointer, _data.offset)) + a := and(a, 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000) + newPointer := add(_pointer, 4) + } + } + + /** + * @notice Returns the bytes32 value at the given index in the input data and updates the pointer. + * @param _data The input data. + * @param _pointer The index of the value to retrieve. + * @return a The bytes32 value at the given index. + * @return newPointer The new pointer. + */ + function readBytes32(bytes calldata _data, uint256 _pointer) internal pure returns (bytes32 a, uint256 newPointer) { + assembly { + a := calldataload(add(_pointer, _data.offset)) + newPointer := add(_pointer, 32) + } + } +} diff --git a/packages/wallet/wallet-contracts/contracts/utils/LibOptim.sol b/packages/wallet/wallet-contracts/contracts/utils/LibOptim.sol new file mode 100644 index 0000000000..1a8674083d --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/utils/LibOptim.sol @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +/** + * @title Library for optimized EVM operations + * @author Agustin Aguilar (aa@horizon.io) + * @notice This library contains functions for optimizing certain EVM operations. + */ +library LibOptim { + /** + * @notice Computes the keccak256 hash of two 32-byte inputs. + * @dev It uses only scratch memory space. + * @param _a The first 32 bytes of the hash. + * @param _b The second 32 bytes of the hash. + * @return c The keccak256 hash of the two 32-byte inputs. + */ + function fkeccak256(bytes32 _a, bytes32 _b) internal pure returns (bytes32 c) { + assembly { + mstore(0, _a) + mstore(32, _b) + c := keccak256(0, 64) + } + } + + /** + * @notice Returns the return data from the last call. + * @return r The return data from the last call. + */ + function returnData() internal pure returns (bytes memory r) { + assembly { + let size := returndatasize() + r := mload(0x40) + let start := add(r, 32) + mstore(0x40, add(start, size)) + mstore(r, size) + returndatacopy(start, 0, size) + } + } + + /** + * @notice Calls another contract with the given parameters. + * @dev This method doesn't increase the memory pointer. + * @param _to The address of the contract to call. + * @param _val The value to send to the contract. + * @param _gas The amount of gas to provide for the call. + * @param _data The data to send to the contract. + * @return r The success status of the call. + */ + function call(address _to, uint256 _val, uint256 _gas, bytes calldata _data) internal returns (bool r) { + assembly { + let tmp := mload(0x40) + calldatacopy(tmp, _data.offset, _data.length) + + r := call(_gas, _to, _val, tmp, _data.length, 0, 0) + } + } + + /** + * @notice Calls another contract with the given parameters, using delegatecall. + * @dev This method doesn't increase the memory pointer. + * @param _to The address of the contract to call. + * @param _gas The amount of gas to provide for the call. + * @param _data The data to send to the contract. + * @return r The success status of the call. + */ + function delegatecall(address _to, uint256 _gas, bytes calldata _data) internal returns (bool r) { + assembly { + let tmp := mload(0x40) + calldatacopy(tmp, _data.offset, _data.length) + + r := delegatecall(_gas, _to, tmp, _data.length, 0, 0) + } + } +} diff --git a/packages/wallet/wallet-contracts/contracts/utils/LibString.sol b/packages/wallet/wallet-contracts/contracts/utils/LibString.sol new file mode 100644 index 0000000000..be352c5adf --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/utils/LibString.sol @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +/** + * @title Library for string manipulation operations + * @notice This library contains functions for manipulating strings in Solidity. + */ +library LibString { + bytes private constant ALPHABET_HEX_16 = "0123456789abcdef"; + bytes private constant ALPHABET_32 = "abcdefghijklmnopqrstuvwxyz234567"; + + /** + * @notice Prefixes a hexadecimal string with "0x". + * @param _hex The hexadecimal string to prefix. + * @return The prefixed hexadecimal string. + */ + function prefixHexadecimal(string memory _hex) internal pure returns (string memory) { + return string(abi.encodePacked("0x", _hex)); + } + + /** + * @notice Prefixes a base32 string with "b". + * @param _base32 The base32 string to prefix. + * @return The prefixed base32 string. + */ + function prefixBase32(string memory _base32) internal pure returns (string memory) { + return string(abi.encodePacked("b", _base32)); + } + + /** + * @notice Converts a byte array to a hexadecimal string. + * @param _bytes The byte array to convert. + * @return The resulting hexadecimal string. + */ + function bytesToHexadecimal(bytes memory _bytes) internal pure returns (string memory) { + uint256 bytesLength = _bytes.length; + bytes memory bytesArray = new bytes(bytesLength << 1); + + unchecked { + for (uint256 i = 0; i < bytesLength; i++) { + uint256 word = uint8(_bytes[i]); + uint256 ib = i << 1; + bytesArray[ib] = bytes1(ALPHABET_HEX_16[word >> 4]); + bytesArray[ib + 1] = bytes1(ALPHABET_HEX_16[word & 0xf]); + } + } + + return string(bytesArray); + } + + /** + * @notice Converts a byte array to a base32 string. + * @param _bytes The byte array to convert. + * @return The resulting base32 string. + */ + function bytesToBase32(bytes memory _bytes) internal pure returns (string memory) { + uint256 bytesLength = _bytes.length; + + uint256 t1 = bytesLength << 3; + + unchecked { + // base32-encoded length = ceil(# of bits / 5) + bytes memory bytesArray = new bytes((t1 + 4) / 5); + + uint256 bits = 0; + uint256 buffer = 0; + uint256 pointer = 0; + + for (uint256 i = 0; i < bytesLength; i++) { + buffer = (buffer << 8) | uint8(_bytes[i]); + bits += 8; + + while (bits >= 5) { + bits -= 5; + bytesArray[pointer] = bytes1(ALPHABET_32[(buffer >> bits) & 0x1f]); + pointer++; + } + } + + if (bits > 0) { + bytesArray[pointer] = bytes1(ALPHABET_32[(buffer << (5 - bits)) & 0x1f]); + } + + return string(bytesArray); + } + } +} diff --git a/packages/wallet/wallet-contracts/contracts/utils/SignatureValidator.sol b/packages/wallet/wallet-contracts/contracts/utils/SignatureValidator.sol new file mode 100644 index 0000000000..5af4e5bacb --- /dev/null +++ b/packages/wallet/wallet-contracts/contracts/utils/SignatureValidator.sol @@ -0,0 +1,127 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "../interfaces/IERC1271Wallet.sol"; + +import "./LibBytes.sol"; + +/** + * @dev Contains logic for signature validation. + * Signatures from wallet contracts assume ERC-1271 support (https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1271.md) + * Notes: Methods are strongly inspired by contracts in https://github.com/0xProject/0x-monorepo/blob/development/ + */ +library SignatureValidator { + // Errors + error InvalidSignatureLength(bytes _signature); + error EmptySignature(); + error InvalidSValue(bytes _signature, bytes32 _s); + error InvalidVValue(bytes _signature, uint256 _v); + error UnsupportedSignatureType(bytes _signature, uint256 _type, bool _recoverMode); + error SignerIsAddress0(bytes _signature); + + using LibBytes for bytes; + + /***********************************| + | Variables | + |__________________________________*/ + + // bytes4(keccak256("isValidSignature(bytes,bytes)")) + bytes4 internal constant ERC1271_MAGICVALUE = 0x20c13b0b; + + // bytes4(keccak256("isValidSignature(bytes32,bytes)")) + bytes4 internal constant ERC1271_MAGICVALUE_BYTES32 = 0x1626ba7e; + + // Allowed signature types. + uint256 private constant SIG_TYPE_EIP712 = 1; + uint256 private constant SIG_TYPE_ETH_SIGN = 2; + uint256 private constant SIG_TYPE_WALLET_BYTES32 = 3; + + /***********************************| + | Signature Functions | + |__________________________________*/ + + /** + * @notice Recover the signer of hash, assuming it's an EOA account + * @dev Only for SignatureType.EIP712 and SignatureType.EthSign signatures + * @param _hash Hash that was signed + * encoded as (bytes32 r, bytes32 s, uint8 v, ... , SignatureType sigType) + */ + function recoverSigner(bytes32 _hash, bytes calldata _signature) internal pure returns (address signer) { + if (_signature.length != 66) revert InvalidSignatureLength(_signature); + uint256 signatureType = _signature.readUint8(_signature.length - 1); + + // Variables are not scoped in Solidity. + uint8 v = _signature.readUint8(64); + bytes32 r = _signature.readBytes32(0); + bytes32 s = _signature.readBytes32(32); + + // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature + // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines + // the valid range for s in (281): 0 < s < secp256k1n Ć· 2 + 1, and for v in (282): v ∈ {27, 28}. Most + // signatures from current libraries generate a unique signature with an s-value in the lower half order. + // + // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value + // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or + // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept + // these malleable signatures as well. + // + // Source OpenZeppelin + // https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/cryptography/ECDSA.sol + + if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { + revert InvalidSValue(_signature, s); + } + + if (v != 27 && v != 28) { + revert InvalidVValue(_signature, v); + } + + // Signature using EIP712 + if (signatureType == SIG_TYPE_EIP712) { + signer = ecrecover(_hash, v, r, s); + + // Signed using web3.eth_sign() or Ethers wallet.signMessage() + } else if (signatureType == SIG_TYPE_ETH_SIGN) { + signer = ecrecover(keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", _hash)), v, r, s); + } else { + // We cannot recover the signer for any other signature type. + revert UnsupportedSignatureType(_signature, signatureType, true); + } + + // Prevent signer from being 0x0 + if (signer == address(0x0)) revert SignerIsAddress0(_signature); + + return signer; + } + + /** + * @notice Returns true if the provided signature is valid for the given signer. + * @dev Supports SignatureType.EIP712, SignatureType.EthSign, and ERC1271 signatures + * @param _hash Hash that was signed + * @param _signer Address of the signer candidate + * @param _signature Signature byte array + */ + function isValidSignature(bytes32 _hash, address _signer, bytes calldata _signature) + internal + view + returns (bool valid) + { + if (_signature.length == 0) { + revert EmptySignature(); + } + + uint256 signatureType = uint8(_signature[_signature.length - 1]); + if (signatureType == SIG_TYPE_EIP712 || signatureType == SIG_TYPE_ETH_SIGN) { + // Recover signer and compare with provided + valid = recoverSigner(_hash, _signature) == _signer; + } else if (signatureType == SIG_TYPE_WALLET_BYTES32) { + // Remove signature type before calling ERC1271, restore after call + valid = ERC1271_MAGICVALUE_BYTES32 + == IERC1271Wallet(_signer).isValidSignature(_hash, _signature[0:_signature.length - 1]); + } else { + // We cannot validate any other signature type. + // We revert because we can say nothing about its validity. + revert UnsupportedSignatureType(_signature, signatureType, false); + } + } +} diff --git a/packages/wallet/wallet-contracts/docs/book.css b/packages/wallet/wallet-contracts/docs/book.css new file mode 100644 index 0000000000..b5ce903f99 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/book.css @@ -0,0 +1,13 @@ +table { + margin: 0 auto; + border-collapse: collapse; + width: 100%; +} + +table td:first-child { + width: 15%; +} + +table td:nth-child(2) { + width: 25%; +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/docs/book.toml b/packages/wallet/wallet-contracts/docs/book.toml new file mode 100644 index 0000000000..22d0b1db75 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/book.toml @@ -0,0 +1,13 @@ +[book] +src = "src" +title = "" + +[output.html] +no-section-label = true +additional-js = ["solidity.min.js"] +additional-css = ["book.css"] +mathjax-support = true +git-repository-url = "https://github.com/0xsequence/wallet-contracts" + +[output.html.fold] +enable = true diff --git a/packages/wallet/wallet-contracts/docs/solidity.min.js b/packages/wallet/wallet-contracts/docs/solidity.min.js new file mode 100644 index 0000000000..1924932919 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/solidity.min.js @@ -0,0 +1,74 @@ +hljs.registerLanguage("solidity",(()=>{"use strict";function e(){try{return!0 +}catch(e){return!1}} +var a=/-?(\b0[xX]([a-fA-F0-9]_?)*[a-fA-F0-9]|(\b[1-9](_?\d)*(\.((\d_?)*\d)?)?|\.\d(_?\d)*)([eE][-+]?\d(_?\d)*)?|\b0)(?!\w|\$)/ +;e()&&(a=a.source.replace(/\\b/g,"(?{ +var a=r(e),o=l(e),c=/[A-Za-z_$][A-Za-z_$0-9.]*/,d=e.inherit(e.TITLE_MODE,{ +begin:/[A-Za-z$_][0-9A-Za-z$_]*/,lexemes:c,keywords:n}),u={className:"params", +begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,lexemes:c,keywords:n, +contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,a,o,s]},_={ +className:"operator",begin:/:=|->/};return{keywords:n,lexemes:c, +contains:[a,o,i,t,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,s,_,{ +className:"function",lexemes:c,beginKeywords:"function",end:"{",excludeEnd:!0, +contains:[d,u,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,_]}]}}, +solAposStringMode:r,solQuoteStringMode:l,HEX_APOS_STRING_MODE:i, +HEX_QUOTE_STRING_MODE:t,SOL_NUMBER:s,isNegativeLookbehindAvailable:e} +;const{baseAssembly:c,solAposStringMode:d,solQuoteStringMode:u,HEX_APOS_STRING_MODE:_,HEX_QUOTE_STRING_MODE:m,SOL_NUMBER:b,isNegativeLookbehindAvailable:E}=o +;return e=>{for(var a=d(e),s=u(e),n=[],i=0;i<32;i++)n[i]=i+1 +;var t=n.map((e=>8*e)),r=[];for(i=0;i<=80;i++)r[i]=i +;var l=n.map((e=>"bytes"+e)).join(" ")+" ",o=t.map((e=>"uint"+e)).join(" ")+" ",g=t.map((e=>"int"+e)).join(" ")+" ",M=[].concat.apply([],t.map((e=>r.map((a=>e+"x"+a))))),p={ +keyword:"var bool string int uint "+g+o+"byte bytes "+l+"fixed ufixed "+M.map((e=>"fixed"+e)).join(" ")+" "+M.map((e=>"ufixed"+e)).join(" ")+" enum struct mapping address new delete if else for while continue break return throw emit try catch revert unchecked _ function modifier event constructor fallback receive error virtual override constant immutable anonymous indexed storage memory calldata external public internal payable pure view private returns import from as using pragma contract interface library is abstract type assembly", +literal:"true false wei gwei szabo finney ether seconds minutes hours days weeks years", +built_in:"self this super selfdestruct suicide now msg block tx abi blockhash gasleft assert require Error Panic sha3 sha256 keccak256 ripemd160 ecrecover addmod mulmod log0 log1 log2 log3 log4" +},O={className:"operator",begin:/[+\-!~*\/%<>&^|=]/ +},C=/[A-Za-z_$][A-Za-z_$0-9]*/,N={className:"params",begin:/\(/,end:/\)/, +excludeBegin:!0,excludeEnd:!0,lexemes:C,keywords:p, +contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,a,s,b,"self"]},f={ +begin:/\.\s*/,end:/[^A-Za-z0-9$_\.]/,excludeBegin:!0,excludeEnd:!0,keywords:{ +built_in:"gas value selector address length push pop send transfer call callcode delegatecall staticcall balance code codehash wrap unwrap name creationCode runtimeCode interfaceId min max" +},relevance:2},y=e.inherit(e.TITLE_MODE,{begin:/[A-Za-z$_][0-9A-Za-z$_]*/, +lexemes:C,keywords:p}),w={className:"built_in", +begin:(E()?"(? 0x18 0x5b 0x5b JUMPDEST 0 rds +0x19 0xf3 0xf3 RETURN +flat deployed code: 0x363d3d373d3d3d363d30545af43d82803e903d91601857fd5bf3 +deploy function: +0x00 0x60 0x3a 0x603a PUSH1 0x3a +0x02 0x60 0x0e 0x600e PUSH1 0x0e 0x3a +0x04 0x3d 0x3d RETURNDATASIZE 0 0x0e 0x3a +0x05 0x39 0x39 CODECOPY +0x06 0x60 0x1a 0x601a PUSH1 0x1a +0x08 0x80 0x80 DUP1 0x1a 0x1a +0x09 0x51 0x51 MLOAD imp 0x1a +0x0A 0x30 0x30 ADDRESS addr imp 0x1a +0x0B 0x55 0x55 SSTORE 0x1a +0x0C 0x3d 0x3d RETURNDATASIZE 0 0x1a +0x0D 0xf3 0xf3 RETURN +[...deployed code] +flat deploy function: 0x603a600e3d39601a805130553df3363d3d373d3d3d363d30545af43d82803e903d91601857fd5bf3 + + +## State Variables +### creationCode + +```solidity +bytes internal constant creationCode = + hex"603a600e3d39601a805130553df3363d3d373d3d3d363d30545af43d82803e903d91601857fd5bf3" +``` + + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/hooks/README.md b/packages/wallet/wallet-contracts/docs/src/contracts/hooks/README.md new file mode 100644 index 0000000000..388d4a0a5b --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/hooks/README.md @@ -0,0 +1,5 @@ + + +# Contents +- [interfaces](/contracts/hooks/interfaces) +- [WalletProxyHook](WalletProxyHook.sol/contract.WalletProxyHook.md) diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/hooks/WalletProxyHook.sol/contract.WalletProxyHook.md b/packages/wallet/wallet-contracts/docs/src/contracts/hooks/WalletProxyHook.sol/contract.WalletProxyHook.md new file mode 100644 index 0000000000..070736509b --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/hooks/WalletProxyHook.sol/contract.WalletProxyHook.md @@ -0,0 +1,15 @@ +# WalletProxyHook +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/hooks/WalletProxyHook.sol) + +**Inherits:** +[IWalletProxy](/home/dargon789/wallet-contracts/docs/src/contracts/hooks/interfaces/IWalletProxy.sol/interface.IWalletProxy.md), [Implementation](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/Implementation.sol/contract.Implementation.md) + + +## Functions +### PROXY_getImplementation + + +```solidity +function PROXY_getImplementation() public view returns (address); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/hooks/interfaces/IWalletProxy.sol/interface.IWalletProxy.md b/packages/wallet/wallet-contracts/docs/src/contracts/hooks/interfaces/IWalletProxy.sol/interface.IWalletProxy.md new file mode 100644 index 0000000000..46775f431d --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/hooks/interfaces/IWalletProxy.sol/interface.IWalletProxy.md @@ -0,0 +1,14 @@ +# IWalletProxy +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/hooks/interfaces/IWalletProxy.sol) + +Interface for Passport Wallet's proxy contract. + + +## Functions +### PROXY_getImplementation + + +```solidity +function PROXY_getImplementation() external view returns (address); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/hooks/interfaces/README.md b/packages/wallet/wallet-contracts/docs/src/contracts/hooks/interfaces/README.md new file mode 100644 index 0000000000..d294d7392c --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/hooks/interfaces/README.md @@ -0,0 +1,4 @@ + + +# Contents +- [IWalletProxy](IWalletProxy.sol/interface.IWalletProxy.md) diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/interfaces/IERC1271Wallet.sol/interface.IERC1271Wallet.md b/packages/wallet/wallet-contracts/docs/src/contracts/interfaces/IERC1271Wallet.sol/interface.IERC1271Wallet.md new file mode 100644 index 0000000000..90fe5b6c0b --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/interfaces/IERC1271Wallet.sol/interface.IERC1271Wallet.md @@ -0,0 +1,57 @@ +# IERC1271Wallet +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/interfaces/IERC1271Wallet.sol) + + +## Functions +### isValidSignature + +Verifies whether the provided signature is valid with respect to the provided data + +MUST return the correct magic value if the signature provided is valid for the provided data +> The bytes4 magic value to return when signature is valid is 0x20c13b0b : bytes4(keccak256("isValidSignature(bytes,bytes)") +> This function MAY modify Ethereum's state + + +```solidity +function isValidSignature(bytes calldata _data, bytes calldata _signature) external view returns (bytes4 magicValue); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_data`|`bytes`| Arbitrary length data signed on the behalf of address(this)| +|`_signature`|`bytes`| Signature byte array associated with _data| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|`magicValue`|`bytes4`|Magic value 0x20c13b0b if the signature is valid and 0x0 otherwise| + + +### isValidSignature + +Verifies whether the provided signature is valid with respect to the provided hash + +MUST return the correct magic value if the signature provided is valid for the provided hash +> The bytes4 magic value to return when signature is valid is 0x20c13b0b : bytes4(keccak256("isValidSignature(bytes,bytes)") +> This function MAY modify Ethereum's state + + +```solidity +function isValidSignature(bytes32 _hash, bytes calldata _signature) external view returns (bytes4 magicValue); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_hash`|`bytes32`| keccak256 hash that was signed| +|`_signature`|`bytes`| Signature byte array associated with _data| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|`magicValue`|`bytes4`|Magic value 0x20c13b0b if the signature is valid and 0x0 otherwise| + + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/interfaces/README.md b/packages/wallet/wallet-contracts/docs/src/contracts/interfaces/README.md new file mode 100644 index 0000000000..482732f11e --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/interfaces/README.md @@ -0,0 +1,6 @@ + + +# Contents +- [receivers](/contracts/interfaces/receivers) +- [tokens](/contracts/interfaces/tokens) +- [IERC1271Wallet](IERC1271Wallet.sol/interface.IERC1271Wallet.md) diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/interfaces/receivers/IERC1155Receiver.sol/interface.IERC1155Receiver.md b/packages/wallet/wallet-contracts/docs/src/contracts/interfaces/receivers/IERC1155Receiver.sol/interface.IERC1155Receiver.md new file mode 100644 index 0000000000..15ae7d6f4f --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/interfaces/receivers/IERC1155Receiver.sol/interface.IERC1155Receiver.md @@ -0,0 +1,21 @@ +# IERC1155Receiver +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/interfaces/receivers/IERC1155Receiver.sol) + + +## Functions +### onERC1155Received + + +```solidity +function onERC1155Received(address, address, uint256, uint256, bytes calldata) external returns (bytes4); +``` + +### onERC1155BatchReceived + + +```solidity +function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) + external + returns (bytes4); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/interfaces/receivers/IERC223Receiver.sol/interface.IERC223Receiver.md b/packages/wallet/wallet-contracts/docs/src/contracts/interfaces/receivers/IERC223Receiver.sol/interface.IERC223Receiver.md new file mode 100644 index 0000000000..0cd75e79e6 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/interfaces/receivers/IERC223Receiver.sol/interface.IERC223Receiver.md @@ -0,0 +1,12 @@ +# IERC223Receiver +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/interfaces/receivers/IERC223Receiver.sol) + + +## Functions +### tokenFallback + + +```solidity +function tokenFallback(address, uint256, bytes calldata) external; +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/interfaces/receivers/IERC721Receiver.sol/interface.IERC721Receiver.md b/packages/wallet/wallet-contracts/docs/src/contracts/interfaces/receivers/IERC721Receiver.sol/interface.IERC721Receiver.md new file mode 100644 index 0000000000..bb3179c879 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/interfaces/receivers/IERC721Receiver.sol/interface.IERC721Receiver.md @@ -0,0 +1,12 @@ +# IERC721Receiver +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/interfaces/receivers/IERC721Receiver.sol) + + +## Functions +### onERC721Received + + +```solidity +function onERC721Received(address, address, uint256, bytes calldata) external returns (bytes4); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/interfaces/receivers/IERC777Receiver.sol/interface.IERC777Receiver.md b/packages/wallet/wallet-contracts/docs/src/contracts/interfaces/receivers/IERC777Receiver.sol/interface.IERC777Receiver.md new file mode 100644 index 0000000000..0ce16e2bb7 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/interfaces/receivers/IERC777Receiver.sol/interface.IERC777Receiver.md @@ -0,0 +1,12 @@ +# IERC777Receiver +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/interfaces/receivers/IERC777Receiver.sol) + + +## Functions +### tokensReceived + + +```solidity +function tokensReceived(address, address, address, uint256, bytes calldata, bytes calldata) external; +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/interfaces/receivers/README.md b/packages/wallet/wallet-contracts/docs/src/contracts/interfaces/receivers/README.md new file mode 100644 index 0000000000..b825f22b3c --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/interfaces/receivers/README.md @@ -0,0 +1,7 @@ + + +# Contents +- [IERC1155Receiver](IERC1155Receiver.sol/interface.IERC1155Receiver.md) +- [IERC223Receiver](IERC223Receiver.sol/interface.IERC223Receiver.md) +- [IERC721Receiver](IERC721Receiver.sol/interface.IERC721Receiver.md) +- [IERC777Receiver](IERC777Receiver.sol/interface.IERC777Receiver.md) diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/interfaces/tokens/IERC1155.sol/interface.IERC1155.md b/packages/wallet/wallet-contracts/docs/src/contracts/interfaces/tokens/IERC1155.sol/interface.IERC1155.md new file mode 100644 index 0000000000..9633499019 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/interfaces/tokens/IERC1155.sol/interface.IERC1155.md @@ -0,0 +1,83 @@ +# IERC1155 +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/interfaces/tokens/IERC1155.sol) + + +## Functions +### balanceOf + + +```solidity +function balanceOf(address account, uint256 id) external view returns (uint256); +``` + +### balanceOfBatch + + +```solidity +function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) + external + view + returns (uint256[] memory); +``` + +### setApprovalForAll + + +```solidity +function setApprovalForAll(address operator, bool approved) external; +``` + +### isApprovedForAll + + +```solidity +function isApprovedForAll(address account, address operator) external view returns (bool); +``` + +### safeTransferFrom + + +```solidity +function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external; +``` + +### safeBatchTransferFrom + + +```solidity +function safeBatchTransferFrom( + address from, + address to, + uint256[] calldata ids, + uint256[] calldata amounts, + bytes calldata data +) external; +``` + +## Events +### TransferSingle + +```solidity +event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); +``` + +### TransferBatch + +```solidity +event TransferBatch( + address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values +); +``` + +### ApprovalForAll + +```solidity +event ApprovalForAll(address indexed account, address indexed operator, bool approved); +``` + +### URI + +```solidity +event URI(string value, uint256 indexed id); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/interfaces/tokens/IERC20.sol/interface.IERC20.md b/packages/wallet/wallet-contracts/docs/src/contracts/interfaces/tokens/IERC20.sol/interface.IERC20.md new file mode 100644 index 0000000000..b725da4852 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/interfaces/tokens/IERC20.sol/interface.IERC20.md @@ -0,0 +1,60 @@ +# IERC20 +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/interfaces/tokens/IERC20.sol) + + +## Functions +### totalSupply + + +```solidity +function totalSupply() external view returns (uint256); +``` + +### balanceOf + + +```solidity +function balanceOf(address account) external view returns (uint256); +``` + +### transfer + + +```solidity +function transfer(address recipient, uint256 amount) external returns (bool); +``` + +### allowance + + +```solidity +function allowance(address owner, address spender) external view returns (uint256); +``` + +### approve + + +```solidity +function approve(address spender, uint256 amount) external returns (bool); +``` + +### transferFrom + + +```solidity +function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); +``` + +## Events +### Transfer + +```solidity +event Transfer(address indexed from, address indexed to, uint256 value); +``` + +### Approval + +```solidity +event Approval(address indexed owner, address indexed spender, uint256 value); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/interfaces/tokens/IERC721.sol/interface.IERC721.md b/packages/wallet/wallet-contracts/docs/src/contracts/interfaces/tokens/IERC721.sol/interface.IERC721.md new file mode 100644 index 0000000000..04afa1fca1 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/interfaces/tokens/IERC721.sol/interface.IERC721.md @@ -0,0 +1,87 @@ +# IERC721 +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/interfaces/tokens/IERC721.sol) + + +## Functions +### balanceOf + + +```solidity +function balanceOf(address owner) external view returns (uint256 balance); +``` + +### ownerOf + + +```solidity +function ownerOf(uint256 tokenId) external view returns (address owner); +``` + +### safeTransferFrom + + +```solidity +function safeTransferFrom(address from, address to, uint256 tokenId) external; +``` + +### transferFrom + + +```solidity +function transferFrom(address from, address to, uint256 tokenId) external; +``` + +### approve + + +```solidity +function approve(address to, uint256 tokenId) external; +``` + +### getApproved + + +```solidity +function getApproved(uint256 tokenId) external view returns (address operator); +``` + +### setApprovalForAll + + +```solidity +function setApprovalForAll(address operator, bool approved) external; +``` + +### isApprovedForAll + + +```solidity +function isApprovedForAll(address owner, address operator) external view returns (bool); +``` + +### safeTransferFrom + + +```solidity +function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; +``` + +## Events +### Transfer + +```solidity +event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); +``` + +### Approval + +```solidity +event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); +``` + +### ApprovalForAll + +```solidity +event ApprovalForAll(address indexed owner, address indexed operator, bool approved); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/interfaces/tokens/README.md b/packages/wallet/wallet-contracts/docs/src/contracts/interfaces/tokens/README.md new file mode 100644 index 0000000000..b3210e36c1 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/interfaces/tokens/README.md @@ -0,0 +1,6 @@ + + +# Contents +- [IERC1155](IERC1155.sol/interface.IERC1155.md) +- [IERC20](IERC20.sol/interface.IERC20.md) +- [IERC721](IERC721.sol/interface.IERC721.md) diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/mocks/AlwaysRevertMock.sol/contract.AlwaysRevertMock.md b/packages/wallet/wallet-contracts/docs/src/contracts/mocks/AlwaysRevertMock.sol/contract.AlwaysRevertMock.md new file mode 100644 index 0000000000..cbc78e73a2 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/mocks/AlwaysRevertMock.sol/contract.AlwaysRevertMock.md @@ -0,0 +1,12 @@ +# AlwaysRevertMock +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/mocks/AlwaysRevertMock.sol) + + +## Functions +### fallback + + +```solidity +fallback() external payable; +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/mocks/CallReceiverMock.sol/contract.CallReceiverMock.md b/packages/wallet/wallet-contracts/docs/src/contracts/mocks/CallReceiverMock.sol/contract.CallReceiverMock.md new file mode 100644 index 0000000000..971bcd4956 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/mocks/CallReceiverMock.sol/contract.CallReceiverMock.md @@ -0,0 +1,48 @@ +# CallReceiverMock +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/mocks/CallReceiverMock.sol) + + +## State Variables +### lastValA + +```solidity +uint256 public lastValA +``` + + +### lastValB + +```solidity +bytes public lastValB +``` + + +### revertFlag + +```solidity +bool revertFlag +``` + + +## Functions +### constructor + + +```solidity +constructor() payable; +``` + +### setRevertFlag + + +```solidity +function setRevertFlag(bool _revertFlag) external; +``` + +### testCall + + +```solidity +function testCall(uint256 _valA, bytes calldata _valB) external payable; +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/mocks/DelegateCallMock.sol/contract.DelegateCallMock.md b/packages/wallet/wallet-contracts/docs/src/contracts/mocks/DelegateCallMock.sol/contract.DelegateCallMock.md new file mode 100644 index 0000000000..27c8031675 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/mocks/DelegateCallMock.sol/contract.DelegateCallMock.md @@ -0,0 +1,48 @@ +# DelegateCallMock +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/mocks/DelegateCallMock.sol) + + +## State Variables +### REVERT_SLOT + +```solidity +uint256 private constant REVERT_SLOT = uint256(keccak256("revert-flag")) +``` + + +### store + +```solidity +mapping(uint256 => uint256) private store +``` + + +## Functions +### setRevertFlag + + +```solidity +function setRevertFlag(bool _revertFlag) external; +``` + +### write + + +```solidity +function write(uint256 _key, uint256 _val) external; +``` + +### read + + +```solidity +function read(uint256 _key) external; +``` + +## Events +### Readed + +```solidity +event Readed(uint256 _val); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/mocks/ERC1155Mock.sol/contract.ERC1155Mock.md b/packages/wallet/wallet-contracts/docs/src/contracts/mocks/ERC1155Mock.sol/contract.ERC1155Mock.md new file mode 100644 index 0000000000..07439ae1a0 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/mocks/ERC1155Mock.sol/contract.ERC1155Mock.md @@ -0,0 +1,110 @@ +# ERC1155Mock +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/mocks/ERC1155Mock.sol) + + +## State Variables +### name + +```solidity +string public name = "Mock ERC1155 Token" +``` + + +### symbol + +```solidity +string public symbol = "MERC1155" +``` + + +### owner + +```solidity +address public owner +``` + + +### balances + +```solidity +mapping(uint256 => mapping(address => uint256)) public balances +``` + + +### operatorApprovals + +```solidity +mapping(address => mapping(address => bool)) public operatorApprovals +``` + + +## Functions +### constructor + + +```solidity +constructor() ; +``` + +### onlyOwner + + +```solidity +modifier onlyOwner() ; +``` + +### balanceOf + + +```solidity +function balanceOf(address account, uint256 id) public view returns (uint256); +``` + +### balanceOfBatch + + +```solidity +function balanceOfBatch(address[] memory accounts, uint256[] memory ids) public view returns (uint256[] memory); +``` + +### mint + + +```solidity +function mint(address to, uint256 id, uint256 amount) public onlyOwner; +``` + +### safeTransferFrom + + +```solidity +function safeTransferFrom(address from, address to, uint256 id, uint256 amount) public; +``` + +### setApprovalForAll + + +```solidity +function setApprovalForAll(address operator, bool approved) public; +``` + +### isApprovedForAll + + +```solidity +function isApprovedForAll(address account, address operator) public view returns (bool); +``` + +## Events +### TransferSingle + +```solidity +event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); +``` + +### ApprovalForAll + +```solidity +event ApprovalForAll(address indexed account, address indexed operator, bool approved); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/mocks/ERC165CheckerMock.sol/contract.ERC165CheckerMock.md b/packages/wallet/wallet-contracts/docs/src/contracts/mocks/ERC165CheckerMock.sol/contract.ERC165CheckerMock.md new file mode 100644 index 0000000000..15df064f08 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/mocks/ERC165CheckerMock.sol/contract.ERC165CheckerMock.md @@ -0,0 +1,37 @@ +# ERC165CheckerMock +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/mocks/ERC165CheckerMock.sol) + + +## State Variables +### InvalidID + +```solidity +bytes4 constant InvalidID = 0xffffffff +``` + + +### ERC165ID + +```solidity +bytes4 constant ERC165ID = 0x01ffc9a7 +``` + + +## Functions +### doesContractImplementInterface + + +```solidity +function doesContractImplementInterface(address _contract, bytes4 _interfaceId) external view returns (bool); +``` + +### noThrowCall + + +```solidity +function noThrowCall(address _contract, bytes4 _interfaceId) + private + view + returns (uint256 success, uint256 result); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/mocks/ERC20Mock.sol/contract.ERC20Mock.md b/packages/wallet/wallet-contracts/docs/src/contracts/mocks/ERC20Mock.sol/contract.ERC20Mock.md new file mode 100644 index 0000000000..986bf48aff --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/mocks/ERC20Mock.sol/contract.ERC20Mock.md @@ -0,0 +1,103 @@ +# ERC20Mock +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/mocks/ERC20Mock.sol) + + +## State Variables +### name + +```solidity +string public name = "Mock ERC20 Token" +``` + + +### symbol + +```solidity +string public symbol = "MERC20" +``` + + +### decimals + +```solidity +uint8 public decimals = 18 +``` + + +### totalSupply + +```solidity +uint256 public totalSupply +``` + + +### balances + +```solidity +mapping(address => uint256) public balances +``` + + +### allowances + +```solidity +mapping(address => mapping(address => uint256)) public allowances +``` + + +## Functions +### constructor + + +```solidity +constructor(uint256 initialSupply) ; +``` + +### balanceOf + + +```solidity +function balanceOf(address account) public view returns (uint256); +``` + +### transfer + + +```solidity +function transfer(address recipient, uint256 amount) public returns (bool); +``` + +### allowance + + +```solidity +function allowance(address owner, address spender) public view returns (uint256); +``` + +### approve + + +```solidity +function approve(address spender, uint256 amount) public returns (bool); +``` + +### transferFrom + + +```solidity +function transferFrom(address sender, address recipient, uint256 amount) public returns (bool); +``` + +## Events +### Transfer + +```solidity +event Transfer(address indexed from, address indexed to, uint256 value); +``` + +### Approval + +```solidity +event Approval(address indexed owner, address indexed spender, uint256 value); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/mocks/ERC721Mock.sol/contract.ERC721Mock.md b/packages/wallet/wallet-contracts/docs/src/contracts/mocks/ERC721Mock.sol/contract.ERC721Mock.md new file mode 100644 index 0000000000..e8da713f0d --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/mocks/ERC721Mock.sol/contract.ERC721Mock.md @@ -0,0 +1,151 @@ +# ERC721Mock +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/mocks/ERC721Mock.sol) + + +## State Variables +### name + +```solidity +string public name = "Mock ERC721 Token" +``` + + +### symbol + +```solidity +string public symbol = "MERC721" +``` + + +### totalSupply + +```solidity +uint256 public totalSupply +``` + + +### owner + +```solidity +address public owner +``` + + +### balances + +```solidity +mapping(address => uint256) public balances +``` + + +### owners + +```solidity +mapping(uint256 => address) public owners +``` + + +### operatorApprovals + +```solidity +mapping(address => mapping(address => bool)) public operatorApprovals +``` + + +### tokenApprovals + +```solidity +mapping(uint256 => address) public tokenApprovals +``` + + +## Functions +### constructor + + +```solidity +constructor() ; +``` + +### onlyOwner + + +```solidity +modifier onlyOwner() ; +``` + +### balanceOf + + +```solidity +function balanceOf(address _owner) public view returns (uint256); +``` + +### ownerOf + + +```solidity +function ownerOf(uint256 tokenId) public view returns (address); +``` + +### mint + + +```solidity +function mint(address to, uint256 tokenId) public onlyOwner; +``` + +### transferFrom + + +```solidity +function transferFrom(address from, address to, uint256 tokenId) public; +``` + +### approve + + +```solidity +function approve(address to, uint256 tokenId) public; +``` + +### getApproved + + +```solidity +function getApproved(uint256 tokenId) public view returns (address); +``` + +### setApprovalForAll + + +```solidity +function setApprovalForAll(address operator, bool approved) public; +``` + +### isApprovedForAll + + +```solidity +function isApprovedForAll(address _owner, address operator) public view returns (bool); +``` + +## Events +### Transfer + +```solidity +event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); +``` + +### Approval + +```solidity +event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); +``` + +### ApprovalForAll + +```solidity +event ApprovalForAll(address indexed owner, address indexed operator, bool approved); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/mocks/GasBurnerMock.sol/contract.GasBurnerMock.md b/packages/wallet/wallet-contracts/docs/src/contracts/mocks/GasBurnerMock.sol/contract.GasBurnerMock.md new file mode 100644 index 0000000000..4b29aa335e --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/mocks/GasBurnerMock.sol/contract.GasBurnerMock.md @@ -0,0 +1,19 @@ +# GasBurnerMock +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/mocks/GasBurnerMock.sol) + + +## Functions +### burnGas + + +```solidity +function burnGas(uint256 _burn) external; +``` + +## Events +### ProvidedGas + +```solidity +event ProvidedGas(uint256 _val); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/mocks/HookCallerMock.sol/contract.HookCallerMock.md b/packages/wallet/wallet-contracts/docs/src/contracts/mocks/HookCallerMock.sol/contract.HookCallerMock.md new file mode 100644 index 0000000000..31228f830e --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/mocks/HookCallerMock.sol/contract.HookCallerMock.md @@ -0,0 +1,49 @@ +# HookCallerMock +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/mocks/HookCallerMock.sol) + + +## Functions +### callERC1155Received + + +```solidity +function callERC1155Received(address _addr) external; +``` + +### callERC1155BatchReceived + + +```solidity +function callERC1155BatchReceived(address _addr) external; +``` + +### callERC721Received + + +```solidity +function callERC721Received(address _addr) external; +``` + +### callERC223Received + + +```solidity +function callERC223Received(address _addr) external; +``` + +### callERC1271isValidSignatureData + + +```solidity +function callERC1271isValidSignatureData(address _addr, bytes calldata _data, bytes calldata _signature) + external + view; +``` + +### callERC1271isValidSignatureHash + + +```solidity +function callERC1271isValidSignatureHash(address _addr, bytes32 _hash, bytes calldata _signature) external view; +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/mocks/HookMock.sol/contract.HookMock.md b/packages/wallet/wallet-contracts/docs/src/contracts/mocks/HookMock.sol/contract.HookMock.md new file mode 100644 index 0000000000..cbbeaef8a4 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/mocks/HookMock.sol/contract.HookMock.md @@ -0,0 +1,12 @@ +# HookMock +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/mocks/HookMock.sol) + + +## Functions +### onHookMockCall + + +```solidity +function onHookMockCall(uint256 _num) external pure returns (uint256); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/mocks/LibBytesImpl.sol/contract.LibBytesImpl.md b/packages/wallet/wallet-contracts/docs/src/contracts/mocks/LibBytesImpl.sol/contract.LibBytesImpl.md new file mode 100644 index 0000000000..4e4c03e92b --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/mocks/LibBytesImpl.sol/contract.LibBytesImpl.md @@ -0,0 +1,26 @@ +# LibBytesImpl +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/mocks/LibBytesImpl.sol) + + +## Functions +### readBytes32 + + +```solidity +function readBytes32(bytes calldata data, uint256 index) external pure returns (bytes32 a); +``` + +### readUint8 + + +```solidity +function readUint8(bytes calldata data, uint256 index) external pure returns (uint8 a); +``` + +### readUint32 + + +```solidity +function readUint32(bytes calldata data, uint256 index) external pure returns (uint32 a); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/mocks/LibBytesPointerImpl.sol/contract.LibBytesPointerImpl.md b/packages/wallet/wallet-contracts/docs/src/contracts/mocks/LibBytesPointerImpl.sol/contract.LibBytesPointerImpl.md new file mode 100644 index 0000000000..dcc906b54b --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/mocks/LibBytesPointerImpl.sol/contract.LibBytesPointerImpl.md @@ -0,0 +1,33 @@ +# LibBytesPointerImpl +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/mocks/LibBytesPointerImpl.sol) + + +## Functions +### readFirstUint16 + + +```solidity +function readFirstUint16(bytes calldata data) external pure returns (uint16 a, uint256 newPointer); +``` + +### readUint16 + + +```solidity +function readUint16(bytes calldata data, uint256 index) external pure returns (uint16 a, uint256 newPointer); +``` + +### readUint24 + + +```solidity +function readUint24(bytes calldata data, uint256 index) external pure returns (uint24 a, uint256 newPointer); +``` + +### readUint64 + + +```solidity +function readUint64(bytes calldata data, uint256 index) external pure returns (uint64 a, uint256 newPointer); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/mocks/LibStringImp.sol/contract.LibStringImp.md b/packages/wallet/wallet-contracts/docs/src/contracts/mocks/LibStringImp.sol/contract.LibStringImp.md new file mode 100644 index 0000000000..dbe4b943ed --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/mocks/LibStringImp.sol/contract.LibStringImp.md @@ -0,0 +1,33 @@ +# LibStringImp +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/mocks/LibStringImp.sol) + + +## Functions +### prefixBase32 + + +```solidity +function prefixBase32(string calldata data) external pure returns (string memory); +``` + +### prefixHexadecimal + + +```solidity +function prefixHexadecimal(string calldata data) external pure returns (string memory); +``` + +### bytesToBase32 + + +```solidity +function bytesToBase32(bytes calldata data) external pure returns (string memory); +``` + +### bytesToHexadecimal + + +```solidity +function bytesToHexadecimal(bytes calldata data) external pure returns (string memory); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/mocks/ModuleMock.sol/contract.ModuleMock.md b/packages/wallet/wallet-contracts/docs/src/contracts/mocks/ModuleMock.sol/contract.ModuleMock.md new file mode 100644 index 0000000000..1f7091182d --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/mocks/ModuleMock.sol/contract.ModuleMock.md @@ -0,0 +1,19 @@ +# ModuleMock +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/mocks/ModuleMock.sol) + + +## Functions +### ping + + +```solidity +function ping() external; +``` + +## Events +### Pong + +```solidity +event Pong(); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/mocks/README.md b/packages/wallet/wallet-contracts/docs/src/contracts/mocks/README.md new file mode 100644 index 0000000000..c96d7e081d --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/mocks/README.md @@ -0,0 +1,17 @@ + + +# Contents +- [AlwaysRevertMock](AlwaysRevertMock.sol/contract.AlwaysRevertMock.md) +- [CallReceiverMock](CallReceiverMock.sol/contract.CallReceiverMock.md) +- [DelegateCallMock](DelegateCallMock.sol/contract.DelegateCallMock.md) +- [ERC1155Mock](ERC1155Mock.sol/contract.ERC1155Mock.md) +- [ERC165CheckerMock](ERC165CheckerMock.sol/contract.ERC165CheckerMock.md) +- [ERC20Mock](ERC20Mock.sol/contract.ERC20Mock.md) +- [ERC721Mock](ERC721Mock.sol/contract.ERC721Mock.md) +- [GasBurnerMock](GasBurnerMock.sol/contract.GasBurnerMock.md) +- [HookCallerMock](HookCallerMock.sol/contract.HookCallerMock.md) +- [HookMock](HookMock.sol/contract.HookMock.md) +- [LibBytesImpl](LibBytesImpl.sol/contract.LibBytesImpl.md) +- [LibBytesPointerImpl](LibBytesPointerImpl.sol/contract.LibBytesPointerImpl.md) +- [LibStringImp](LibStringImp.sol/contract.LibStringImp.md) +- [ModuleMock](ModuleMock.sol/contract.ModuleMock.md) diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/GuestModule.sol/contract.GuestModule.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/GuestModule.sol/contract.GuestModule.md new file mode 100644 index 0000000000..3c4bd106ba --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/GuestModule.sol/contract.GuestModule.md @@ -0,0 +1,124 @@ +# GuestModule +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/GuestModule.sol) + +**Inherits:** +[ModuleAuth](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleAuth.sol/abstract.ModuleAuth.md), [ModuleCalls](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleCalls.sol/abstract.ModuleCalls.md), [ModuleCreator](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleCreator.sol/contract.ModuleCreator.md) + +GuestModule implements a Sequence wallet without signatures, nonce or replay protection. +executing transactions using this wallet is not an authenticated process, and can be done by any address. + +This contract is completely public with no security, designed to execute pre-signed transactions +and use Sequence tools without using the wallets. + + +## Functions +### execute + +Allow any caller to execute an action + + +```solidity +function execute(Transaction[] calldata _txs, uint256, bytes calldata) public override; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_txs`|`Transaction[]`|Transactions to process| +|``|`uint256`|| +|``|`bytes`|| + + +### selfExecute + +Allow any caller to execute an action + + +```solidity +function selfExecute(Transaction[] calldata _txs) public override; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_txs`|`Transaction[]`|Transactions to process| + + +### _executeGuest + +Executes a list of transactions + + +```solidity +function _executeGuest(bytes32 _txHash, Transaction[] calldata _txs) private; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_txHash`|`bytes32`| Hash of the batch of transactions| +|`_txs`|`Transaction[]`| Transactions to execute| + + +### _isValidImage + +Validates any signature image, because the wallet is public and has no owner. + + +```solidity +function _isValidImage(bytes32) internal pure override returns (bool); +``` +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`bool`|true, all signatures are valid.| + + +### _updateImageHash + +Not supported. + + +```solidity +function _updateImageHash(bytes32) internal virtual override; +``` + +### supportsInterface + +Query if a contract implements an interface + + +```solidity +function supportsInterface(bytes4 _interfaceID) + public + pure + override(ModuleAuth, ModuleCalls, ModuleCreator) + returns (bool); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_interfaceID`|`bytes4`|The interface identifier, as specified in ERC-165| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`bool`|`true` if the contract implements `_interfaceID`| + + +## Errors +### DelegateCallNotAllowed + +```solidity +error DelegateCallNotAllowed(uint256 _index); +``` + +### NotSupported + +```solidity +error NotSupported(); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/MainModule.sol/contract.MainModule.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/MainModule.sol/contract.MainModule.md new file mode 100644 index 0000000000..3518e44562 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/MainModule.sol/contract.MainModule.md @@ -0,0 +1,57 @@ +# MainModule +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/MainModule.sol) + +**Inherits:** +[ModuleAuthFixed](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleAuthFixed.sol/abstract.ModuleAuthFixed.md), [ModuleExtraAuth](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleExtraAuth.sol/abstract.ModuleExtraAuth.md), [ModuleCalls](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleCalls.sol/abstract.ModuleCalls.md), [ModuleHooks](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleHooks.sol/contract.ModuleHooks.md), [ModuleCreator](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleCreator.sol/contract.ModuleCreator.md), [ModuleAuthConvenience](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleAuthConvenience.sol/abstract.ModuleAuthConvenience.md) + +Contains the core functionality Sequence wallets will inherit. + +If using a new main module, developers must ensure that all inherited +contracts by the main module don't conflict and are accounted for to be +supported by the supportsInterface method. + + +## Functions +### constructor + + +```solidity +constructor(address _factory, address _mainModuleUpgradable) ModuleAuthFixed(_factory, _mainModuleUpgradable); +``` + +### _isValidImage + + +```solidity +function _isValidImage(bytes32 _imageHash) + internal + view + override(IModuleAuth, ModuleAuthFixed, ModuleExtraAuth) + returns (bool); +``` + +### supportsInterface + +Query if a contract implements an interface + + +```solidity +function supportsInterface(bytes4 _interfaceID) + public + pure + override(ModuleAuthFixed, ModuleAuthConvenience, ModuleCalls, ModuleExtraAuth, ModuleHooks, ModuleCreator) + returns (bool); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_interfaceID`|`bytes4`|The interface identifier, as specified in ERC-165| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`bool`|`true` if the contract implements `_interfaceID`| + + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/MainModuleGasEstimation.sol/contract.MainModuleGasEstimation.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/MainModuleGasEstimation.sol/contract.MainModuleGasEstimation.md new file mode 100644 index 0000000000..1faeb0395f --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/MainModuleGasEstimation.sol/contract.MainModuleGasEstimation.md @@ -0,0 +1,85 @@ +# MainModuleGasEstimation +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/MainModuleGasEstimation.sol) + +**Inherits:** +[ModuleIgnoreAuthUpgradable](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/gas-estimation/ModuleIgnoreAuthUpgradable.sol/abstract.ModuleIgnoreAuthUpgradable.md), [ModuleIgnoreNonceCalls](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/gas-estimation/ModuleIgnoreNonceCalls.sol/abstract.ModuleIgnoreNonceCalls.md), [ModuleUpdate](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleUpdate.sol/contract.ModuleUpdate.md), [ModuleHooks](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleHooks.sol/contract.ModuleHooks.md), [ModuleCreator](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleCreator.sol/contract.ModuleCreator.md) + +Contains an alternative implementation of the MainModules that skips validation of +signatures, this implementation SHOULD NOT be used directly on a wallet. +Intended to be used only for gas estimation, using eth_call and overrides. + + +## Functions +### simulateExecute + +Simulate each transaction in a bundle for gas usage and execution result + + +```solidity +function simulateExecute(Transaction[] calldata _txs) public virtual returns (SimulateResult[] memory); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_txs`|`Transaction[]`|Transactions to process| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`SimulateResult[]`|The gas used and execution result for each transaction in the bundle| + + +### _isValidImage + + +```solidity +function _isValidImage(bytes32 _imageHash) + internal + view + override(IModuleAuth, ModuleIgnoreAuthUpgradable) + returns (bool); +``` + +### supportsInterface + +Query if a contract implements an interface + +If using a new main module, developers must ensure that all inherited +contracts by the main module don't conflict and are accounted for to be +supported by the supportsInterface method. + + +```solidity +function supportsInterface(bytes4 _interfaceID) + public + pure + override(ModuleAuthUpgradable, ModuleCalls, ModuleUpdate, ModuleHooks, ModuleCreator) + returns (bool); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_interfaceID`|`bytes4`|The interface identifier, as specified in ERC-165| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`bool`|`true` if the contract implements `_interfaceID`| + + +## Structs +### SimulateResult + +```solidity +struct SimulateResult { + bool executed; + bool succeeded; + bytes result; + uint256 gasUsed; +} +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/MainModuleUpgradable.sol/contract.MainModuleUpgradable.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/MainModuleUpgradable.sol/contract.MainModuleUpgradable.md new file mode 100644 index 0000000000..6d6d84d91d --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/MainModuleUpgradable.sol/contract.MainModuleUpgradable.md @@ -0,0 +1,63 @@ +# MainModuleUpgradable +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/MainModuleUpgradable.sol) + +**Inherits:** +[ModuleAuthUpgradable](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleAuthUpgradable.sol/abstract.ModuleAuthUpgradable.md), [ModuleExtraAuth](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleExtraAuth.sol/abstract.ModuleExtraAuth.md), [ModuleCalls](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleCalls.sol/abstract.ModuleCalls.md), [ModuleUpdate](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleUpdate.sol/contract.ModuleUpdate.md), [ModuleHooks](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleHooks.sol/contract.ModuleHooks.md), [ModuleCreator](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleCreator.sol/contract.ModuleCreator.md), [ModuleAuthConvenience](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleAuthConvenience.sol/abstract.ModuleAuthConvenience.md) + +Contains the core functionality Sequence wallets will inherit with +the added functionality that the main module can be changed. + +If using a new main module, developers must ensure that all inherited +contracts by the main module don't conflict and are accounted for to be +supported by the supportsInterface method. + + +## Functions +### _isValidImage + + +```solidity +function _isValidImage(bytes32 _imageHash) + internal + view + override(IModuleAuth, ModuleAuthUpgradable, ModuleExtraAuth) + returns (bool); +``` + +### supportsInterface + +Query if a contract implements an interface + +If using a new main module, developers must ensure that all inherited +contracts by the main module don't conflict and are accounted for to be +supported by the supportsInterface method. + + +```solidity +function supportsInterface(bytes4 _interfaceID) + public + pure + override( + ModuleAuthUpgradable, + ModuleAuthConvenience, + ModuleCalls, + ModuleExtraAuth, + ModuleUpdate, + ModuleHooks, + ModuleCreator + ) + returns (bool); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_interfaceID`|`bytes4`|The interface identifier, as specified in ERC-165| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`bool`|`true` if the contract implements `_interfaceID`| + + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/README.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/README.md new file mode 100644 index 0000000000..4aea181eda --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/README.md @@ -0,0 +1,9 @@ + + +# Contents +- [commons](/contracts/modules/commons) +- [utils](/contracts/modules/utils) +- [GuestModule](GuestModule.sol/contract.GuestModule.md) +- [MainModule](MainModule.sol/contract.MainModule.md) +- [MainModuleGasEstimation](MainModuleGasEstimation.sol/contract.MainModuleGasEstimation.md) +- [MainModuleUpgradable](MainModuleUpgradable.sol/contract.MainModuleUpgradable.md) diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/Implementation.sol/contract.Implementation.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/Implementation.sol/contract.Implementation.md new file mode 100644 index 0000000000..48ffca756e --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/Implementation.sol/contract.Implementation.md @@ -0,0 +1,42 @@ +# Implementation +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/commons/Implementation.sol) + +Allows modules to access the implementation slot + + +## Functions +### _setImplementation + +Updates the Wallet implementation + +The wallet implementation is stored on the storage slot +defined by the address of the wallet itself +WARNING updating this value may break the wallet and users +must be confident that the new implementation is safe. + + +```solidity +function _setImplementation(address _imp) internal; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_imp`|`address`|New implementation address| + + +### _getImplementation + +Returns the Wallet implementation + + +```solidity +function _getImplementation() internal view returns (address _imp); +``` +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|`_imp`|`address`|The address of the current Wallet implementation| + + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleAuth.sol/abstract.ModuleAuth.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleAuth.sol/abstract.ModuleAuth.md new file mode 100644 index 0000000000..08b9d690a8 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleAuth.sol/abstract.ModuleAuth.md @@ -0,0 +1,203 @@ +# ModuleAuth +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/commons/ModuleAuth.sol) + +**Inherits:** +[IModuleAuth](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/interfaces/IModuleAuth.sol/abstract.IModuleAuth.md), [ModuleERC165](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleERC165.sol/abstract.ModuleERC165.md), [IERC1271Wallet](/home/dargon789/wallet-contracts/docs/src/contracts/interfaces/IERC1271Wallet.sol/interface.IERC1271Wallet.md), [SequenceChainedSig](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol/abstract.SequenceChainedSig.md) + + +## State Variables +### LEGACY_TYPE + +```solidity +bytes1 internal constant LEGACY_TYPE = hex"00" +``` + + +### DYNAMIC_TYPE + +```solidity +bytes1 internal constant DYNAMIC_TYPE = hex"01" +``` + + +### NO_CHAIN_ID_TYPE + +```solidity +bytes1 internal constant NO_CHAIN_ID_TYPE = hex"02" +``` + + +### CHAINED_TYPE + +```solidity +bytes1 internal constant CHAINED_TYPE = hex"03" +``` + + +### SELECTOR_ERC1271_BYTES_BYTES + +```solidity +bytes4 internal constant SELECTOR_ERC1271_BYTES_BYTES = 0x20c13b0b +``` + + +### SELECTOR_ERC1271_BYTES32_BYTES + +```solidity +bytes4 internal constant SELECTOR_ERC1271_BYTES32_BYTES = 0x1626ba7e +``` + + +## Functions +### signatureRecovery + +Recovers the threshold, weight, imageHash, subdigest, and checkpoint of a signature. + +The signature must be prefixed with a type byte, which is used to determine the recovery method. + + +```solidity +function signatureRecovery(bytes32 _digest, bytes calldata _signature) + public + view + virtual + override + returns (uint256 threshold, uint256 weight, bytes32 imageHash, bytes32 subdigest, uint256 checkpoint); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_digest`|`bytes32`|Digest of the signed data.| +|`_signature`|`bytes`|A Sequence signature.| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|`threshold`|`uint256`|The required number of signatures needed to consider the signature valid.| +|`weight`|`uint256`|The actual number of signatures collected in the signature.| +|`imageHash`|`bytes32`|The imageHash of the configuration that signed the message.| +|`subdigest`|`bytes32`|A modified version of the original digest, unique for each wallet/network.| +|`checkpoint`|`uint256`|A nonce that is incremented every time a new configuration is set.| + + +### _signatureValidation + +Validates a signature. + + +```solidity +function _signatureValidation(bytes32 _digest, bytes calldata _signature) + internal + view + virtual + override + returns (bool isValid, bytes32 subdigest); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_digest`|`bytes32`|Digest of the signed data.| +|`_signature`|`bytes`|A Sequence signature.| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|`isValid`|`bool`|Indicates whether the signature is valid or not.| +|`subdigest`|`bytes32`|A modified version of the original digest, unique for each wallet/network.| + + +### isValidSignature + +Verifies whether the provided signature is valid with respect to the provided data + +MUST return the correct magic value if the signature provided is valid for the provided data +> The bytes4 magic value to return when signature is valid is 0x20c13b0b : bytes4(keccak256("isValidSignature(bytes,bytes)")) + + +```solidity +function isValidSignature(bytes calldata _data, bytes calldata _signatures) + public + view + virtual + override + returns (bytes4); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_data`|`bytes`| Arbitrary length data signed on the behalf of address(this)| +|`_signatures`|`bytes`|Signature byte array associated with _data. Encoded as abi.encode(Signature[], Configs)| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`bytes4`|magicValue Magic value 0x20c13b0b if the signature is valid and 0x0 otherwise| + + +### isValidSignature + +Verifies whether the provided signature is valid with respect to the provided hash + +MUST return the correct magic value if the signature provided is valid for the provided hash +> The bytes4 magic value to return when signature is valid is 0x1626ba7e : bytes4(keccak256("isValidSignature(bytes32,bytes)")) + + +```solidity +function isValidSignature(bytes32 _hash, bytes calldata _signatures) public view virtual override returns (bytes4); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_hash`|`bytes32`| keccak256 hash that was signed| +|`_signatures`|`bytes`|Signature byte array associated with _data. Encoded as abi.encode(Signature[], Configs)| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`bytes4`|magicValue Magic value 0x1626ba7e if the signature is valid and 0x0 otherwise| + + +### supportsInterface + +Query if a contract implements an interface + + +```solidity +function supportsInterface(bytes4 _interfaceID) public pure virtual override returns (bool); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_interfaceID`|`bytes4`|The interface identifier, as specified in ERC-165| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`bool`|`true` if the contract implements `_interfaceID`| + + +### updateImageHash + +Updates the signers configuration of the wallet + + +```solidity +function updateImageHash(bytes32 _imageHash) external virtual override onlySelf; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_imageHash`|`bytes32`|New required image hash of the signature| + + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleAuthConvenience.sol/abstract.ModuleAuthConvenience.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleAuthConvenience.sol/abstract.ModuleAuthConvenience.md new file mode 100644 index 0000000000..19295f3520 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleAuthConvenience.sol/abstract.ModuleAuthConvenience.md @@ -0,0 +1,53 @@ +# ModuleAuthConvenience +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/commons/ModuleAuthConvenience.sol) + +**Inherits:** +[ModuleERC165](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleERC165.sol/abstract.ModuleERC165.md), [ModuleSelfAuth](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleSelfAuth.sol/contract.ModuleSelfAuth.md), [ModuleAuth](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleAuth.sol/abstract.ModuleAuth.md), [ModuleIPFS](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleIPFS.sol/contract.ModuleIPFS.md) + + +## Functions +### updateImageHashAndIPFS + +Updates the image hash and the IPFS root in a single operation. + +These two operations are often performed together, so this function +allows to save some gas by performing them in a single step. + + +```solidity +function updateImageHashAndIPFS(bytes32 _imageHash, bytes32 _ipfsRoot) external onlySelf; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_imageHash`|`bytes32`|The new image hash to be set.| +|`_ipfsRoot`|`bytes32`|The new IPFS root to be set.| + + +### supportsInterface + +Query if a contract implements an interface + + +```solidity +function supportsInterface(bytes4 _interfaceID) + public + pure + virtual + override(ModuleERC165, ModuleAuth) + returns (bool); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_interfaceID`|`bytes4`|The interface identifier, as specified in ERC-165| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`bool`|`true` if the contract implements `_interfaceID`| + + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleAuthFixed.sol/abstract.ModuleAuthFixed.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleAuthFixed.sol/abstract.ModuleAuthFixed.md new file mode 100644 index 0000000000..06b88e89f0 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleAuthFixed.sol/abstract.ModuleAuthFixed.md @@ -0,0 +1,108 @@ +# ModuleAuthFixed +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/commons/ModuleAuthFixed.sol) + +**Inherits:** +[ModuleSelfAuth](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleSelfAuth.sol/contract.ModuleSelfAuth.md), [ModuleAuth](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleAuth.sol/abstract.ModuleAuth.md), [ModuleUpdate](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleUpdate.sol/contract.ModuleUpdate.md) + +Implements ModuleAuth by validating the signature image against +the salt used to deploy the contract +This module allows wallets to be deployed with a default configuration +without using any aditional contract storage + + +## State Variables +### INIT_CODE_HASH + +```solidity +bytes32 public immutable INIT_CODE_HASH +``` + + +### FACTORY + +```solidity +address public immutable FACTORY +``` + + +### UPGRADEABLE_IMPLEMENTATION + +```solidity +address public immutable UPGRADEABLE_IMPLEMENTATION +``` + + +## Functions +### constructor + + +```solidity +constructor(address _factory, address _mainModuleUpgradeable) ; +``` + +### _updateImageHash + +Updates the configuration of the wallet + +In the process of updating the configuration, the wallet implementation +is updated to the mainModuleUpgradeable, this only happens once in the +lifetime of the wallet. + + +```solidity +function _updateImageHash(bytes32 _imageHash) internal virtual override; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_imageHash`|`bytes32`|New required image hash of the signature| + + +### _isValidImage + +Validates the signature image with the salt used to deploy the contract + + +```solidity +function _isValidImage(bytes32 _imageHash) internal view virtual override returns (bool); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_imageHash`|`bytes32`|Hash image of signature| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`bool`|true if the signature image is valid| + + +### supportsInterface + +Query if a contract implements an interface + + +```solidity +function supportsInterface(bytes4 _interfaceID) + public + pure + virtual + override(ModuleAuth, ModuleUpdate) + returns (bool); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_interfaceID`|`bytes4`|The interface identifier, as specified in ERC-165| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`bool`|`true` if the contract implements `_interfaceID`| + + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleAuthUpgradable.sol/abstract.ModuleAuthUpgradable.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleAuthUpgradable.sol/abstract.ModuleAuthUpgradable.md new file mode 100644 index 0000000000..f89410fe4a --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleAuthUpgradable.sol/abstract.ModuleAuthUpgradable.md @@ -0,0 +1,75 @@ +# ModuleAuthUpgradable +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/commons/ModuleAuthUpgradable.sol) + +**Inherits:** +[IModuleAuthUpgradable](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/interfaces/IModuleAuthUpgradable.sol/interface.IModuleAuthUpgradable.md), [ModuleSelfAuth](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleSelfAuth.sol/contract.ModuleSelfAuth.md), [ModuleAuth](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleAuth.sol/abstract.ModuleAuth.md) + + +## Functions +### _updateImageHash + +Updates the signers configuration of the wallet + + +```solidity +function _updateImageHash(bytes32 _imageHash) internal virtual override; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_imageHash`|`bytes32`|New required image hash of the signature| + + +### imageHash + +Returns the current image hash of the wallet + + +```solidity +function imageHash() external view virtual override returns (bytes32); +``` + +### _isValidImage + +Validates the signature image with a valid image hash defined +in the contract storage + + +```solidity +function _isValidImage(bytes32 _imageHash) internal view virtual override returns (bool); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_imageHash`|`bytes32`|Hash image of signature| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`bool`|true if the signature image is valid| + + +### supportsInterface + +Query if a contract implements an interface + + +```solidity +function supportsInterface(bytes4 _interfaceID) public pure virtual override returns (bool); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_interfaceID`|`bytes4`|The interface identifier, as specified in ERC-165| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`bool`|`true` if the contract implements `_interfaceID`| + + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleCalls.sol/abstract.ModuleCalls.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleCalls.sol/abstract.ModuleCalls.md new file mode 100644 index 0000000000..a2d9ebc10a --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleCalls.sol/abstract.ModuleCalls.md @@ -0,0 +1,104 @@ +# ModuleCalls +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/commons/ModuleCalls.sol) + +**Inherits:** +[IModuleCalls](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/interfaces/IModuleCalls.sol/interface.IModuleCalls.md), [IModuleAuth](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/interfaces/IModuleAuth.sol/abstract.IModuleAuth.md), [ModuleERC165](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleERC165.sol/abstract.ModuleERC165.md), [ModuleOnlyDelegatecall](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleOnlyDelegatecall.sol/contract.ModuleOnlyDelegatecall.md), [ModuleSelfAuth](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleSelfAuth.sol/contract.ModuleSelfAuth.md), [ModuleNonce](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleNonce.sol/contract.ModuleNonce.md) + + +## Functions +### execute + +Allow wallet owner to execute an action + +Relayers must ensure that the gasLimit specified for each transaction +is acceptable to them. A user could specify large enough that it could +consume all the gas available. + + +```solidity +function execute(Transaction[] calldata _txs, uint256 _nonce, bytes calldata _signature) + external + virtual + override + onlyDelegatecall; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_txs`|`Transaction[]`| Transactions to process| +|`_nonce`|`uint256`| Signature nonce (may contain an encoded space)| +|`_signature`|`bytes`| Encoded signature| + + +### selfExecute + +Allow wallet to execute an action +without signing the message + + +```solidity +function selfExecute(Transaction[] calldata _txs) external virtual override onlySelf; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_txs`|`Transaction[]`| Transactions to execute| + + +### _execute + +Executes a list of transactions + + +```solidity +function _execute(bytes32 _txHash, Transaction[] calldata _txs) private; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_txHash`|`bytes32`| Hash of the batch of transactions| +|`_txs`|`Transaction[]`| Transactions to execute| + + +### _revertBytes + +Logs a failed transaction, reverts if the transaction is not optional + + +```solidity +function _revertBytes(bool _revertOnError, bytes32 _txHash, uint256 _index, bytes memory _reason) internal; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_revertOnError`|`bool`| Signals if it should revert or just log| +|`_txHash`|`bytes32`| Hash of the transaction| +|`_index`|`uint256`| Index of the transaction in the batch| +|`_reason`|`bytes`| Encoded revert message| + + +### supportsInterface + +Query if a contract implements an interface + + +```solidity +function supportsInterface(bytes4 _interfaceID) public pure virtual override returns (bool); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_interfaceID`|`bytes4`|The interface identifier, as specified in ERC-165| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`bool`|`true` if the contract implements `_interfaceID`| + + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleCreator.sol/contract.ModuleCreator.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleCreator.sol/contract.ModuleCreator.md new file mode 100644 index 0000000000..9ba53c0757 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleCreator.sol/contract.ModuleCreator.md @@ -0,0 +1,57 @@ +# ModuleCreator +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/commons/ModuleCreator.sol) + +**Inherits:** +[IModuleCreator](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/interfaces/IModuleCreator.sol/interface.IModuleCreator.md), [ModuleERC165](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleERC165.sol/abstract.ModuleERC165.md), [ModuleSelfAuth](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleSelfAuth.sol/contract.ModuleSelfAuth.md) + + +## Functions +### createContract + +Creates a contract forwarding eth value + + +```solidity +function createContract(bytes memory _code) public payable virtual override onlySelf returns (address addr); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_code`|`bytes`|Creation code of the contract| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|`addr`|`address`|The address of the created contract| + + +### supportsInterface + +Query if a contract implements an interface + + +```solidity +function supportsInterface(bytes4 _interfaceID) public pure virtual override returns (bool); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_interfaceID`|`bytes4`|The interface identifier, as specified in ERC-165| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`bool`|`true` if the contract implements `_interfaceID`| + + +## Events +### CreatedContract + +```solidity +event CreatedContract(address _contract); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleERC165.sol/abstract.ModuleERC165.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleERC165.sol/abstract.ModuleERC165.md new file mode 100644 index 0000000000..be2e7f2a46 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleERC165.sol/abstract.ModuleERC165.md @@ -0,0 +1,31 @@ +# ModuleERC165 +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/commons/ModuleERC165.sol) + + +## Functions +### supportsInterface + +Query if a contract implements an interface + +Adding new hooks will not lead to them being reported by this function +without upgrading the wallet. In addition, developers must ensure that +all inherited contracts by the main module don't conflict and are accounted +to be supported by the supportsInterface method. + + +```solidity +function supportsInterface(bytes4 _interfaceID) public pure virtual returns (bool); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_interfaceID`|`bytes4`|The interface identifier, as specified in ERC-165| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`bool`|`true` if the contract implements `_interfaceID`| + + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleERC5719.sol/contract.ModuleERC5719.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleERC5719.sol/contract.ModuleERC5719.md new file mode 100644 index 0000000000..85502e3785 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleERC5719.sol/contract.ModuleERC5719.md @@ -0,0 +1,15 @@ +# ModuleERC5719 +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/commons/ModuleERC5719.sol) + +**Inherits:** +[ModuleIPFS](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleIPFS.sol/contract.ModuleIPFS.md) + + +## Functions +### getAlternativeSignature + + +```solidity +function getAlternativeSignature(bytes32 _digest) external view returns (string memory); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleExtraAuth.sol/abstract.ModuleExtraAuth.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleExtraAuth.sol/abstract.ModuleExtraAuth.md new file mode 100644 index 0000000000..754cdce9e7 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleExtraAuth.sol/abstract.ModuleExtraAuth.md @@ -0,0 +1,92 @@ +# ModuleExtraAuth +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/commons/ModuleExtraAuth.sol) + +**Inherits:** +[ModuleERC165](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleERC165.sol/abstract.ModuleERC165.md), [ModuleSelfAuth](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleSelfAuth.sol/contract.ModuleSelfAuth.md), [ModuleAuth](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleAuth.sol/abstract.ModuleAuth.md) + + +## State Variables +### EXTRA_IMAGE_HASH_KEY + +```solidity +bytes32 private constant EXTRA_IMAGE_HASH_KEY = + bytes32(0x849e7bdc245db17e50b9f43086f1914d70eb4dab6dd89af4d541d53353ad97de) +``` + + +## Functions +### _writeExpirationForImageHash + + +```solidity +function _writeExpirationForImageHash(bytes32 _imageHash, uint256 _expiration) internal; +``` + +### _readExpirationForImageHash + + +```solidity +function _readExpirationForImageHash(bytes32 _imageHash) internal view returns (uint256 _expiration); +``` + +### _isValidImage + + +```solidity +function _isValidImage(bytes32 _imageHash) internal view virtual override returns (bool); +``` + +### extraImageHash + + +```solidity +function extraImageHash(bytes32 _imageHash) public view returns (uint256); +``` + +### setExtraImageHash + + +```solidity +function setExtraImageHash(bytes32 _imageHash, uint256 _expiration) external onlySelf; +``` + +### clearExtraImageHashes + + +```solidity +function clearExtraImageHashes(bytes32[] calldata _imageHashes) external onlySelf; +``` + +### supportsInterface + +Query if a contract implements an interface + + +```solidity +function supportsInterface(bytes4 _interfaceID) + public + pure + virtual + override(ModuleERC165, ModuleAuth) + returns (bool); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_interfaceID`|`bytes4`|The interface identifier, as specified in ERC-165| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`bool`|`true` if the contract implements `_interfaceID`| + + +## Events +### SetExtraImageHash + +```solidity +event SetExtraImageHash(bytes32 indexed _imageHash, uint256 _expiration); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleHooks.sol/contract.ModuleHooks.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleHooks.sol/contract.ModuleHooks.md new file mode 100644 index 0000000000..ba8fc7c128 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleHooks.sol/contract.ModuleHooks.md @@ -0,0 +1,202 @@ +# ModuleHooks +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/commons/ModuleHooks.sol) + +**Inherits:** +[IERC1155Receiver](/home/dargon789/wallet-contracts/docs/src/contracts/interfaces/receivers/IERC1155Receiver.sol/interface.IERC1155Receiver.md), [IERC721Receiver](/home/dargon789/wallet-contracts/docs/src/contracts/interfaces/receivers/IERC721Receiver.sol/interface.IERC721Receiver.md), [IModuleHooks](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/interfaces/IModuleHooks.sol/interface.IModuleHooks.md), [ModuleERC165](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleERC165.sol/abstract.ModuleERC165.md), [ModuleSelfAuth](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleSelfAuth.sol/contract.ModuleSelfAuth.md) + + +## State Variables +### HOOKS_KEY + +```solidity +bytes32 private constant HOOKS_KEY = bytes32(0xbe27a319efc8734e89e26ba4bc95f5c788584163b959f03fa04e2d7ab4b9a120) +``` + + +## Functions +### readHook + +Reads the implementation hook of a signature + + +```solidity +function readHook(bytes4 _signature) external view virtual override returns (address); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_signature`|`bytes4`|Signature function| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`address`|The address of the implementation hook, address(0) if none| + + +### addHook + +Adds a new hook to handle a given function selector + +Can't overwrite hooks that are part of the main module (those defined below) + + +```solidity +function addHook(bytes4 _signature, address _implementation) external virtual override onlySelf; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_signature`|`bytes4`|Signature function linked to the hook| +|`_implementation`|`address`|Hook implementation contract| + + +### removeHook + +Removes a registered hook + +Can't remove hooks that are part of the main module (those defined below) +without upgrading the wallet + + +```solidity +function removeHook(bytes4 _signature) external virtual override onlySelf; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_signature`|`bytes4`|Signature function linked to the hook| + + +### _readHook + +Reads the implementation hook of a signature + + +```solidity +function _readHook(bytes4 _signature) private view returns (address); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_signature`|`bytes4`|Signature function| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`address`|The address of the implementation hook, address(0) if none| + + +### _writeHook + +Writes the implementation hook of a signature + + +```solidity +function _writeHook(bytes4 _signature, address _implementation) private; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_signature`|`bytes4`|Signature function| +|`_implementation`|`address`|Hook implementation contract| + + +### onERC1155Received + +Handle the receipt of a single ERC1155 token type. + + +```solidity +function onERC1155Received(address, address, uint256, uint256, bytes calldata) + external + virtual + override + returns (bytes4); +``` +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`bytes4`|`bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`| + + +### onERC1155BatchReceived + +Handle the receipt of multiple ERC1155 token types. + + +```solidity +function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) + external + virtual + override + returns (bytes4); +``` +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`bytes4`|`bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`| + + +### onERC721Received + +Handle the receipt of a single ERC721 token. + + +```solidity +function onERC721Received(address, address, uint256, bytes calldata) external virtual override returns (bytes4); +``` +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`bytes4`|`bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`| + + +### fallback + +Routes fallback calls through hooks + + +```solidity +fallback() external payable; +``` + +### receive + +Allows the wallet to receive ETH + + +```solidity +receive() external payable; +``` + +### supportsInterface + +Query if a contract implements an interface + + +```solidity +function supportsInterface(bytes4 _interfaceID) public pure virtual override returns (bool); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_interfaceID`|`bytes4`|The interface identifier, as specified in ERC-165| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`bool`|`true` if the contract implements `_interfaceID`| + + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleIPFS.sol/contract.ModuleIPFS.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleIPFS.sol/contract.ModuleIPFS.md new file mode 100644 index 0000000000..d871bd84ca --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleIPFS.sol/contract.ModuleIPFS.md @@ -0,0 +1,52 @@ +# ModuleIPFS +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/commons/ModuleIPFS.sol) + +**Inherits:** +[ModuleSelfAuth](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleSelfAuth.sol/contract.ModuleSelfAuth.md) + + +## State Variables +### IPFS_ROOT_KEY + +```solidity +bytes32 private constant IPFS_ROOT_KEY = + bytes32(0x0eecac93ced8722d209199364cda3bc33da3bc3a23daef6be49ebd780511d033) +``` + + +## Functions +### ipfsRootBytes32 + + +```solidity +function ipfsRootBytes32() public view returns (bytes32); +``` + +### ipfsRoot + + +```solidity +function ipfsRoot() public view returns (string memory); +``` + +### updateIPFSRoot + + +```solidity +function updateIPFSRoot(bytes32 _hash) external onlySelf; +``` + +### _updateIPFSRoot + + +```solidity +function _updateIPFSRoot(bytes32 _hash) internal; +``` + +## Events +### IPFSRootUpdated + +```solidity +event IPFSRootUpdated(bytes32 _hash); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleNonce.sol/contract.ModuleNonce.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleNonce.sol/contract.ModuleNonce.md new file mode 100644 index 0000000000..a10e72eac9 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleNonce.sol/contract.ModuleNonce.md @@ -0,0 +1,96 @@ +# ModuleNonce +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/commons/ModuleNonce.sol) + + +## State Variables +### NONCE_KEY + +```solidity +bytes32 private constant NONCE_KEY = bytes32(0x8d0bf1fd623d628c741362c1289948e57b3e2905218c676d3e69abee36d6ae2e) +``` + + +## Functions +### nonce + +Returns the next nonce of the default nonce space + +The default nonce space is 0x00 + + +```solidity +function nonce() external view virtual returns (uint256); +``` +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`uint256`|The next nonce| + + +### readNonce + +Returns the next nonce of the given nonce space + + +```solidity +function readNonce(uint256 _space) public view virtual returns (uint256); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_space`|`uint256`|Nonce space, each space keeps an independent nonce count| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`uint256`|The next nonce| + + +### _writeNonce + +Changes the next nonce of the given nonce space + + +```solidity +function _writeNonce(uint256 _space, uint256 _nonce) internal; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_space`|`uint256`|Nonce space, each space keeps an independent nonce count| +|`_nonce`|`uint256`|Nonce to write on the space| + + +### _validateNonce + +Verify if a nonce is valid + + +```solidity +function _validateNonce(uint256 _rawNonce) internal virtual; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_rawNonce`|`uint256`|Nonce to validate (may contain an encoded space)| + + +## Events +### NonceChange + +```solidity +event NonceChange(uint256 _space, uint256 _newNonce); +``` + +## Errors +### BadNonce + +```solidity +error BadNonce(uint256 _space, uint256 _provided, uint256 _current); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleOnlyDelegatecall.sol/contract.ModuleOnlyDelegatecall.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleOnlyDelegatecall.sol/contract.ModuleOnlyDelegatecall.md new file mode 100644 index 0000000000..3704b9fbdf --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleOnlyDelegatecall.sol/contract.ModuleOnlyDelegatecall.md @@ -0,0 +1,36 @@ +# ModuleOnlyDelegatecall +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/commons/ModuleOnlyDelegatecall.sol) + + +## State Variables +### self + +```solidity +address private immutable self +``` + + +## Functions +### constructor + + +```solidity +constructor() ; +``` + +### onlyDelegatecall + +Modifier that only allows functions to be called via delegatecall. + + +```solidity +modifier onlyDelegatecall() ; +``` + +## Errors +### OnlyDelegatecall + +```solidity +error OnlyDelegatecall(); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleSelfAuth.sol/contract.ModuleSelfAuth.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleSelfAuth.sol/contract.ModuleSelfAuth.md new file mode 100644 index 0000000000..03e4b82442 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleSelfAuth.sol/contract.ModuleSelfAuth.md @@ -0,0 +1,19 @@ +# ModuleSelfAuth +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/commons/ModuleSelfAuth.sol) + + +## Functions +### onlySelf + + +```solidity +modifier onlySelf() ; +``` + +## Errors +### OnlySelfAuth + +```solidity +error OnlySelfAuth(address _sender, address _self); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleStorage.sol/library.ModuleStorage.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleStorage.sol/library.ModuleStorage.md new file mode 100644 index 0000000000..ecd0209c38 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleStorage.sol/library.ModuleStorage.md @@ -0,0 +1,33 @@ +# ModuleStorage +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/commons/ModuleStorage.sol) + + +## Functions +### writeBytes32 + + +```solidity +function writeBytes32(bytes32 _key, bytes32 _val) internal; +``` + +### readBytes32 + + +```solidity +function readBytes32(bytes32 _key) internal view returns (bytes32 val); +``` + +### writeBytes32Map + + +```solidity +function writeBytes32Map(bytes32 _key, bytes32 _subKey, bytes32 _val) internal; +``` + +### readBytes32Map + + +```solidity +function readBytes32Map(bytes32 _key, bytes32 _subKey) internal view returns (bytes32 val); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleUpdate.sol/contract.ModuleUpdate.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleUpdate.sol/contract.ModuleUpdate.md new file mode 100644 index 0000000000..91abdfdde0 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/ModuleUpdate.sol/contract.ModuleUpdate.md @@ -0,0 +1,70 @@ +# ModuleUpdate +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/commons/ModuleUpdate.sol) + +**Inherits:** +[IModuleUpdate](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/interfaces/IModuleUpdate.sol/abstract.IModuleUpdate.md), [ModuleERC165](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleERC165.sol/abstract.ModuleERC165.md), [ModuleSelfAuth](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleSelfAuth.sol/contract.ModuleSelfAuth.md), [Implementation](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/Implementation.sol/contract.Implementation.md) + + +## Functions +### updateImplementation + +Updates the implementation of the base wallet + +WARNING Updating the implementation can brick the wallet + + +```solidity +function updateImplementation(address _implementation) external virtual override onlySelf; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_implementation`|`address`|New main module implementation| + + +### _updateImplementation + +Updates the implementation of the base wallet, used internally. + +WARNING Updating the implementation can brick the wallet + + +```solidity +function _updateImplementation(address _implementation) internal virtual override; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_implementation`|`address`|New main module implementation| + + +### supportsInterface + +Query if a contract implements an interface + + +```solidity +function supportsInterface(bytes4 _interfaceID) public pure virtual override returns (bool); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_interfaceID`|`bytes4`|The interface identifier, as specified in ERC-165| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`bool`|`true` if the contract implements `_interfaceID`| + + +## Events +### ImplementationUpdated + +```solidity +event ImplementationUpdated(address newImplementation); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/README.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/README.md new file mode 100644 index 0000000000..59da911372 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/README.md @@ -0,0 +1,23 @@ + + +# Contents +- [gas-estimation](/contracts/modules/commons/gas-estimation) +- [interfaces](/contracts/modules/commons/interfaces) +- [submodules](/contracts/modules/commons/submodules) +- [Implementation](Implementation.sol/contract.Implementation.md) +- [ModuleAuth](ModuleAuth.sol/abstract.ModuleAuth.md) +- [ModuleAuthConvenience](ModuleAuthConvenience.sol/abstract.ModuleAuthConvenience.md) +- [ModuleAuthFixed](ModuleAuthFixed.sol/abstract.ModuleAuthFixed.md) +- [ModuleAuthUpgradable](ModuleAuthUpgradable.sol/abstract.ModuleAuthUpgradable.md) +- [ModuleCalls](ModuleCalls.sol/abstract.ModuleCalls.md) +- [ModuleCreator](ModuleCreator.sol/contract.ModuleCreator.md) +- [ModuleERC165](ModuleERC165.sol/abstract.ModuleERC165.md) +- [ModuleERC5719](ModuleERC5719.sol/contract.ModuleERC5719.md) +- [ModuleExtraAuth](ModuleExtraAuth.sol/abstract.ModuleExtraAuth.md) +- [ModuleHooks](ModuleHooks.sol/contract.ModuleHooks.md) +- [ModuleIPFS](ModuleIPFS.sol/contract.ModuleIPFS.md) +- [ModuleNonce](ModuleNonce.sol/contract.ModuleNonce.md) +- [ModuleOnlyDelegatecall](ModuleOnlyDelegatecall.sol/contract.ModuleOnlyDelegatecall.md) +- [ModuleSelfAuth](ModuleSelfAuth.sol/contract.ModuleSelfAuth.md) +- [ModuleStorage](ModuleStorage.sol/library.ModuleStorage.md) +- [ModuleUpdate](ModuleUpdate.sol/contract.ModuleUpdate.md) diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/gas-estimation/ModuleIgnoreAuthUpgradable.sol/abstract.ModuleIgnoreAuthUpgradable.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/gas-estimation/ModuleIgnoreAuthUpgradable.sol/abstract.ModuleIgnoreAuthUpgradable.md new file mode 100644 index 0000000000..d3da287bf1 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/gas-estimation/ModuleIgnoreAuthUpgradable.sol/abstract.ModuleIgnoreAuthUpgradable.md @@ -0,0 +1,32 @@ +# ModuleIgnoreAuthUpgradable +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/commons/gas-estimation/ModuleIgnoreAuthUpgradable.sol) + +**Inherits:** +[ModuleAuthUpgradable](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleAuthUpgradable.sol/abstract.ModuleAuthUpgradable.md) + +Implements ModuleAuthUpgradable but ignores the validity of the signature +should only be used during gas estimation. + + +## Functions +### _isValidImage + +Removes the signature validation from the module, by returning true for any _imageHash + + +```solidity +function _isValidImage(bytes32 _imageHash) internal view virtual override(ModuleAuthUpgradable) returns (bool); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_imageHash`|`bytes32`|Hash image of signature| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`bool`|true always| + + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/gas-estimation/ModuleIgnoreNonceCalls.sol/abstract.ModuleIgnoreNonceCalls.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/gas-estimation/ModuleIgnoreNonceCalls.sol/abstract.ModuleIgnoreNonceCalls.md new file mode 100644 index 0000000000..3895b32b25 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/gas-estimation/ModuleIgnoreNonceCalls.sol/abstract.ModuleIgnoreNonceCalls.md @@ -0,0 +1,26 @@ +# ModuleIgnoreNonceCalls +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/commons/gas-estimation/ModuleIgnoreNonceCalls.sol) + +**Inherits:** +[ModuleCalls](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleCalls.sol/abstract.ModuleCalls.md) + +Implements ModuleCalls but ignores the validity of the nonce +should only be used during gas estimation. + + +## Functions +### _validateNonce + +Verify if a nonce is valid + + +```solidity +function _validateNonce(uint256 _rawNonce) internal virtual override; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_rawNonce`|`uint256`|Nonce to validate (may contain an encoded space)| + + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/gas-estimation/README.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/gas-estimation/README.md new file mode 100644 index 0000000000..5a5ea3ddc5 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/gas-estimation/README.md @@ -0,0 +1,5 @@ + + +# Contents +- [ModuleIgnoreAuthUpgradable](ModuleIgnoreAuthUpgradable.sol/abstract.ModuleIgnoreAuthUpgradable.md) +- [ModuleIgnoreNonceCalls](ModuleIgnoreNonceCalls.sol/abstract.ModuleIgnoreNonceCalls.md) diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/interfaces/IModuleAuth.sol/abstract.IModuleAuth.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/interfaces/IModuleAuth.sol/abstract.IModuleAuth.md new file mode 100644 index 0000000000..7b62d2f9c4 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/interfaces/IModuleAuth.sol/abstract.IModuleAuth.md @@ -0,0 +1,101 @@ +# IModuleAuth +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/commons/interfaces/IModuleAuth.sol) + + +## State Variables +### IMAGE_HASH_KEY + +```solidity +bytes32 internal constant IMAGE_HASH_KEY = + bytes32(0xea7157fa25e3aa17d0ae2d5280fa4e24d421c61842aa85e45194e1145aa72bf8) +``` + + +## Functions +### _signatureValidation + + +```solidity +function _signatureValidation(bytes32 _digest, bytes calldata _signature) + internal + view + virtual + returns (bool isValid, bytes32 subdigest); +``` + +### signatureRecovery + + +```solidity +function signatureRecovery(bytes32 _digest, bytes calldata _signature) + public + view + virtual + returns (uint256 threshold, uint256 weight, bytes32 imageHash, bytes32 subdigest, uint256 checkpoint); +``` + +### _isValidImage + +Validates the signature image + + +```solidity +function _isValidImage(bytes32) internal view virtual returns (bool); +``` +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`bool`|true if the signature image is valid| + + +### updateImageHash + +Updates the signers configuration of the wallet + + +```solidity +function updateImageHash(bytes32 _imageHash) external virtual; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_imageHash`|`bytes32`|New required image hash of the signature| + + +### _updateImageHash + +Updates the signers configuration of the wallet + + +```solidity +function _updateImageHash(bytes32 _imageHash) internal virtual; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_imageHash`|`bytes32`|New required image hash of the signature| + + +## Events +### ImageHashUpdated + +```solidity +event ImageHashUpdated(bytes32 newImageHash); +``` + +## Errors +### ImageHashIsZero + +```solidity +error ImageHashIsZero(); +``` + +### InvalidSignatureType + +```solidity +error InvalidSignatureType(bytes1 _type); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/interfaces/IModuleAuthUpgradable.sol/interface.IModuleAuthUpgradable.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/interfaces/IModuleAuthUpgradable.sol/interface.IModuleAuthUpgradable.md new file mode 100644 index 0000000000..00f2551a1c --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/interfaces/IModuleAuthUpgradable.sol/interface.IModuleAuthUpgradable.md @@ -0,0 +1,14 @@ +# IModuleAuthUpgradable +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/commons/interfaces/IModuleAuthUpgradable.sol) + + +## Functions +### imageHash + +Returns the current image hash of the wallet + + +```solidity +function imageHash() external view returns (bytes32); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/interfaces/IModuleCalls.sol/interface.IModuleCalls.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/interfaces/IModuleCalls.sol/interface.IModuleCalls.md new file mode 100644 index 0000000000..c27a52b38d --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/interfaces/IModuleCalls.sol/interface.IModuleCalls.md @@ -0,0 +1,78 @@ +# IModuleCalls +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/commons/interfaces/IModuleCalls.sol) + + +## Functions +### execute + +Allow wallet owner to execute an action + + +```solidity +function execute(Transaction[] calldata _txs, uint256 _nonce, bytes calldata _signature) external; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_txs`|`Transaction[]`| Transactions to process| +|`_nonce`|`uint256`| Signature nonce (may contain an encoded space)| +|`_signature`|`bytes`| Encoded signature| + + +### selfExecute + +Allow wallet to execute an action +without signing the message + + +```solidity +function selfExecute(Transaction[] calldata _txs) external; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_txs`|`Transaction[]`| Transactions to execute| + + +## Events +### TxFailed + +```solidity +event TxFailed(bytes32 indexed _tx, uint256 _index, bytes _reason); +``` + +### TxExecuted + +```solidity +event TxExecuted(bytes32 indexed _tx, uint256 _index); +``` + +## Errors +### NotEnoughGas + +```solidity +error NotEnoughGas(uint256 _index, uint256 _requested, uint256 _available); +``` + +### InvalidSignature + +```solidity +error InvalidSignature(bytes32 _hash, bytes _signature); +``` + +## Structs +### Transaction + +```solidity +struct Transaction { + bool delegateCall; // Performs delegatecall + bool revertOnError; // Reverts transaction bundle if tx fails + uint256 gasLimit; // Maximum gas to be forwarded + address target; // Address of the contract to call + uint256 value; // Amount of ETH to pass with the call + bytes data; // calldata to pass +} +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/interfaces/IModuleCreator.sol/interface.IModuleCreator.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/interfaces/IModuleCreator.sol/interface.IModuleCreator.md new file mode 100644 index 0000000000..1b9319007e --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/interfaces/IModuleCreator.sol/interface.IModuleCreator.md @@ -0,0 +1,33 @@ +# IModuleCreator +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/commons/interfaces/IModuleCreator.sol) + + +## Functions +### createContract + +Creates a contract forwarding eth value + + +```solidity +function createContract(bytes calldata _code) external payable returns (address addr); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_code`|`bytes`|Creation code of the contract| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|`addr`|`address`|The address of the created contract| + + +## Errors +### CreateFailed + +```solidity +error CreateFailed(bytes _code); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/interfaces/IModuleHooks.sol/interface.IModuleHooks.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/interfaces/IModuleHooks.sol/interface.IModuleHooks.md new file mode 100644 index 0000000000..a1cc8907d9 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/interfaces/IModuleHooks.sol/interface.IModuleHooks.md @@ -0,0 +1,77 @@ +# IModuleHooks +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/commons/interfaces/IModuleHooks.sol) + + +## Functions +### readHook + +Reads the implementation hook of a signature + + +```solidity +function readHook(bytes4 _signature) external view returns (address); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_signature`|`bytes4`|Signature function| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`address`|The address of the implementation hook, address(0) if none| + + +### addHook + +Adds a new hook to handle a given function selector + + +```solidity +function addHook(bytes4 _signature, address _implementation) external; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_signature`|`bytes4`|Signature function linked to the hook| +|`_implementation`|`address`|Hook implementation contract| + + +### removeHook + +Removes a registered hook + + +```solidity +function removeHook(bytes4 _signature) external; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_signature`|`bytes4`|Signature function linked to the hook| + + +## Events +### DefinedHook + +```solidity +event DefinedHook(bytes4 _signature, address _implementation); +``` + +## Errors +### HookAlreadyExists + +```solidity +error HookAlreadyExists(bytes4 _signature); +``` + +### HookDoesNotExist + +```solidity +error HookDoesNotExist(bytes4 _signature); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/interfaces/IModuleUpdate.sol/abstract.IModuleUpdate.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/interfaces/IModuleUpdate.sol/abstract.IModuleUpdate.md new file mode 100644 index 0000000000..5a8be6f241 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/interfaces/IModuleUpdate.sol/abstract.IModuleUpdate.md @@ -0,0 +1,46 @@ +# IModuleUpdate +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/commons/interfaces/IModuleUpdate.sol) + + +## Functions +### updateImplementation + +Updates the implementation of the base wallet + +WARNING Updating the implementation can brick the wallet + + +```solidity +function updateImplementation(address _implementation) external virtual; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_implementation`|`address`|New main module implementation| + + +### _updateImplementation + +Updates the implementation of the base wallet, used internally. + +WARNING Updating the implementation can brick the wallet + + +```solidity +function _updateImplementation(address _implementation) internal virtual; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_implementation`|`address`|New main module implementation| + + +## Errors +### InvalidImplementation + +```solidity +error InvalidImplementation(address _implementation); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/interfaces/README.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/interfaces/README.md new file mode 100644 index 0000000000..c23c874119 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/interfaces/README.md @@ -0,0 +1,9 @@ + + +# Contents +- [IModuleAuth](IModuleAuth.sol/abstract.IModuleAuth.md) +- [IModuleAuthUpgradable](IModuleAuthUpgradable.sol/interface.IModuleAuthUpgradable.md) +- [IModuleCalls](IModuleCalls.sol/interface.IModuleCalls.md) +- [IModuleCreator](IModuleCreator.sol/interface.IModuleCreator.md) +- [IModuleHooks](IModuleHooks.sol/interface.IModuleHooks.md) +- [IModuleUpdate](IModuleUpdate.sol/abstract.IModuleUpdate.md) diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/submodules/README.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/submodules/README.md new file mode 100644 index 0000000000..86110985fd --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/submodules/README.md @@ -0,0 +1,5 @@ + + +# Contents +- [auth](/contracts/modules/commons/submodules/auth) +- [nonce](/contracts/modules/commons/submodules/nonce) diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/submodules/auth/README.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/submodules/auth/README.md new file mode 100644 index 0000000000..c19a5f59a6 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/submodules/auth/README.md @@ -0,0 +1,7 @@ + + +# Contents +- [SequenceBaseSig](SequenceBaseSig.sol/library.SequenceBaseSig.md) +- [SequenceChainedSig](SequenceChainedSig.sol/abstract.SequenceChainedSig.md) +- [SequenceDynamicSig](SequenceDynamicSig.sol/library.SequenceDynamicSig.md) +- [SequenceNoChainIdSig](SequenceNoChainIdSig.sol/library.SequenceNoChainIdSig.md) diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol/library.SequenceBaseSig.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol/library.SequenceBaseSig.md new file mode 100644 index 0000000000..73d8121a13 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol/library.SequenceBaseSig.md @@ -0,0 +1,225 @@ +# SequenceBaseSig +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/commons/submodules/auth/SequenceBaseSig.sol) + +**Author:** +Agustin Aguilar (aa@horizon.io) + +A Solidity implementation for handling signatures in the Sequence protocol. + + +## State Variables +### FLAG_SIGNATURE + +```solidity +uint256 internal constant FLAG_SIGNATURE = 0 +``` + + +### FLAG_ADDRESS + +```solidity +uint256 internal constant FLAG_ADDRESS = 1 +``` + + +### FLAG_DYNAMIC_SIGNATURE + +```solidity +uint256 internal constant FLAG_DYNAMIC_SIGNATURE = 2 +``` + + +### FLAG_NODE + +```solidity +uint256 internal constant FLAG_NODE = 3 +``` + + +### FLAG_BRANCH + +```solidity +uint256 internal constant FLAG_BRANCH = 4 +``` + + +### FLAG_SUBDIGEST + +```solidity +uint256 internal constant FLAG_SUBDIGEST = 5 +``` + + +### FLAG_NESTED + +```solidity +uint256 internal constant FLAG_NESTED = 6 +``` + + +## Functions +### subdigest + +Generates a subdigest for the input digest (unique for this wallet and network). + + +```solidity +function subdigest(bytes32 _digest) internal view returns (bytes32); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_digest`|`bytes32`|The input digest to generate the subdigest from.| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`bytes32`|bytes32 The subdigest generated from the input digest.| + + +### _leafForAddressAndWeight + +Generates the leaf for an address and weight. + +The leaf is generated by concatenating the address and weight. + + +```solidity +function _leafForAddressAndWeight(address _addr, uint96 _weight) internal pure returns (bytes32); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_addr`|`address`|The address to generate the leaf for.| +|`_weight`|`uint96`|The weight to generate the leaf for.| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`bytes32`|bytes32 The leaf generated from the address and weight.| + + +### _leafForHardcodedSubdigest + +Generates the leaf for a hardcoded subdigest. + +The leaf is generated by hashing 'Sequence static digest:\n' and the subdigest. + + +```solidity +function _leafForHardcodedSubdigest(bytes32 _subdigest) internal pure returns (bytes32); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_subdigest`|`bytes32`|The subdigest to generate the leaf for.| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`bytes32`|bytes32 The leaf generated from the hardcoded subdigest.| + + +### _leafForNested + +Generates the leaf for a nested tree node. + +The leaf is generated by hashing 'Sequence nested config:\n', the node, the threshold and the weight. + + +```solidity +function _leafForNested(bytes32 _node, uint256 _threshold, uint256 _weight) internal pure returns (bytes32); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_node`|`bytes32`|The root of the node to generate the leaf for.| +|`_threshold`|`uint256`|The internal threshold of the tree.| +|`_weight`|`uint256`|The external weight of the tree.| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`bytes32`|bytes32 The leaf generated from the nested tree.| + + +### recoverBranch + +Returns the weight and root of a signature branch. + +If the signature contains a hardcoded subdigest, and it matches the input digest, then the weight is set to 2 ** 256 - 1. + + +```solidity +function recoverBranch(bytes32 _subdigest, bytes calldata _signature) + internal + view + returns (uint256 weight, bytes32 root); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_subdigest`|`bytes32`|The digest to verify the signature against.| +|`_signature`|`bytes`|The signature branch to recover.| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|`weight`|`uint256`|The total weight of the recovered signatures.| +|`root`|`bytes32`|The root hash of the recovered configuration.| + + +### recover + +Returns the threshold, weight, root, and checkpoint of a signature. + +To verify the signature, the weight must be greater than or equal to the threshold, and the root +must match the expected `imageHash` of the wallet. + + +```solidity +function recover(bytes32 _subdigest, bytes calldata _signature) + internal + view + returns (uint256 threshold, uint256 weight, bytes32 imageHash, uint256 checkpoint); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_subdigest`|`bytes32`|The digest to verify the signature against.| +|`_signature`|`bytes`|The signature to recover.| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|`threshold`|`uint256`|The minimum weight required for the signature to be valid.| +|`weight`|`uint256`|The total weight of the recovered signatures.| +|`imageHash`|`bytes32`|The root hash of the recovered configuration| +|`checkpoint`|`uint256`|The checkpoint of the signature.| + + +## Errors +### InvalidNestedSignature + +```solidity +error InvalidNestedSignature(bytes32 _hash, address _addr, bytes _signature); +``` + +### InvalidSignatureFlag + +```solidity +error InvalidSignatureFlag(uint256 _flag); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol/abstract.SequenceChainedSig.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol/abstract.SequenceChainedSig.md new file mode 100644 index 0000000000..299493ce3c --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol/abstract.SequenceChainedSig.md @@ -0,0 +1,91 @@ +# SequenceChainedSig +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/commons/submodules/auth/SequenceChainedSig.sol) + +**Inherits:** +[IModuleAuth](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/interfaces/IModuleAuth.sol/abstract.IModuleAuth.md), [ModuleSelfAuth](/home/dargon789/wallet-contracts/docs/src/contracts/modules/commons/ModuleSelfAuth.sol/contract.ModuleSelfAuth.md) + +**Author:** +Agustin Aguilar (aa@horizon.io) + +Defines Sequence signatures that work by delegating control to new configurations. + +The delegations can be chained together, the first signature is the one that is used to validate +the message, the last signature must match the current on-chain configuration of the wallet. + + +## State Variables +### SET_IMAGE_HASH_TYPE_HASH + +```solidity +bytes32 public constant SET_IMAGE_HASH_TYPE_HASH = keccak256("SetImageHash(bytes32 imageHash)") +``` + + +## Functions +### _hashSetImageHashStruct + +Defined the special token that must be signed to delegate control to a new configuration. + + +```solidity +function _hashSetImageHashStruct(bytes32 _imageHash) internal pure returns (bytes32); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_imageHash`|`bytes32`|The hash of the new configuration.| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`bytes32`|bytes32 The message hash to be signed.| + + +### chainedRecover + +Returns the threshold, weight, root, and checkpoint of a (chained) signature. + +This method return the `threshold`, `weight` and `imageHash` of the last signature in the chain. +Intermediate signatures are validated directly in this method. The `subdigest` is the one of the +first signature in the chain (since that's the one that is used to validate the message). + + +```solidity +function chainedRecover(bytes32 _digest, bytes calldata _signature) + internal + view + returns (uint256 threshold, uint256 weight, bytes32 imageHash, bytes32 subdigest, uint256 checkpoint); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_digest`|`bytes32`|The digest to recover the signature from.| +|`_signature`|`bytes`|The signature to recover.| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|`threshold`|`uint256`|The threshold of the (last) signature.| +|`weight`|`uint256`|The weight of the (last) signature.| +|`imageHash`|`bytes32`|The image hash of the (last) signature.| +|`subdigest`|`bytes32`|The subdigest of the (first) signature in the chain.| +|`checkpoint`|`uint256`|The checkpoint of the (last) signature.| + + +## Errors +### LowWeightChainedSignature + +```solidity +error LowWeightChainedSignature(bytes _signature, uint256 threshold, uint256 _weight); +``` + +### WrongChainedCheckpointOrder + +```solidity +error WrongChainedCheckpointOrder(uint256 _current, uint256 _prev); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol/library.SequenceDynamicSig.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol/library.SequenceDynamicSig.md new file mode 100644 index 0000000000..9fe9b4a99d --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol/library.SequenceDynamicSig.md @@ -0,0 +1,35 @@ +# SequenceDynamicSig +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol) + + +## Functions +### recover + +Recover a "dynamically encoded" Sequence signature. + +The Signature is stripped of the first byte, which is the encoding flag. + + +```solidity +function recover(bytes32 _subdigest, bytes calldata _signature) + internal + view + returns (uint256 threshold, uint256 weight, bytes32 imageHash, uint256 checkpoint); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_subdigest`|`bytes32`|The digest of the signature.| +|`_signature`|`bytes`|The Sequence signature.| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|`threshold`|`uint256`|The threshold weight required to validate the signature.| +|`weight`|`uint256`|The weight of the signature.| +|`imageHash`|`bytes32`|The hash of the recovered configuration.| +|`checkpoint`|`uint256`|The checkpoint of the configuration.| + + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol/library.SequenceNoChainIdSig.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol/library.SequenceNoChainIdSig.md new file mode 100644 index 0000000000..b0cc788eab --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol/library.SequenceNoChainIdSig.md @@ -0,0 +1,28 @@ +# SequenceNoChainIdSig +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol) + + +## Functions +### subdigest + +Computes a subdigest for a Sequence signature that works on all chains. + +The subdigest is computed by removing the chain ID from the digest (using 0 instead). + + +```solidity +function subdigest(bytes32 _digest) internal view returns (bytes32); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_digest`|`bytes32`|The digest of the chain of signatures.| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`bytes32`|bytes32 The subdigest with no chain ID.| + + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/submodules/nonce/README.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/submodules/nonce/README.md new file mode 100644 index 0000000000..fe84b67cec --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/submodules/nonce/README.md @@ -0,0 +1,4 @@ + + +# Contents +- [SubModuleNonce](SubModuleNonce.sol/library.SubModuleNonce.md) diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol/library.SubModuleNonce.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol/library.SubModuleNonce.md new file mode 100644 index 0000000000..0f65c75a90 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol/library.SubModuleNonce.md @@ -0,0 +1,51 @@ +# SubModuleNonce +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/commons/submodules/nonce/SubModuleNonce.sol) + + +## State Variables +### NONCE_BITS + +```solidity +uint256 internal constant NONCE_BITS = 96 +``` + + +### NONCE_MASK + +```solidity +bytes32 internal constant NONCE_MASK = bytes32(uint256(type(uint96).max)) +``` + + +## Functions +### decodeNonce + +Decodes a raw nonce + +Schema: space[160]:type[96] + + +```solidity +function decodeNonce(uint256 _rawNonce) internal pure returns (uint256 _space, uint256 _nonce); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_rawNonce`|`uint256`|Nonce to be decoded| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|`_space`|`uint256`|The nonce space of the raw nonce| +|`_nonce`|`uint256`|The nonce of the raw nonce| + + +### encodeNonce + + +```solidity +function encodeNonce(uint256 _space, uint256 _nonce) internal pure returns (uint256); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/utils/GasEstimator.sol/contract.GasEstimator.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/utils/GasEstimator.sol/contract.GasEstimator.md new file mode 100644 index 0000000000..6e07e6de10 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/utils/GasEstimator.sol/contract.GasEstimator.md @@ -0,0 +1,14 @@ +# GasEstimator +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/utils/GasEstimator.sol) + + +## Functions +### estimate + + +```solidity +function estimate(address _to, bytes calldata _data) + external + returns (bool success, bytes memory result, uint256 gas); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/utils/MultiCallUtils.sol/contract.MultiCallUtils.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/utils/MultiCallUtils.sol/contract.MultiCallUtils.md new file mode 100644 index 0000000000..7dcf5e935e --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/utils/MultiCallUtils.sol/contract.MultiCallUtils.md @@ -0,0 +1,133 @@ +# MultiCallUtils +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/utils/MultiCallUtils.sol) + + +## Functions +### multiCall + + +```solidity +function multiCall(IModuleCalls.Transaction[] memory _txs) + public + payable + returns (bool[] memory _successes, bytes[] memory _results); +``` + +### callBlockhash + + +```solidity +function callBlockhash(uint256 _i) external view returns (bytes32); +``` + +### callCoinbase + + +```solidity +function callCoinbase() external view returns (address); +``` + +### callDifficulty + + +```solidity +function callDifficulty() external view returns (uint256); +``` + +### callPrevrandao + + +```solidity +function callPrevrandao() external view returns (uint256); +``` + +### callGasLimit + + +```solidity +function callGasLimit() external view returns (uint256); +``` + +### callBlockNumber + + +```solidity +function callBlockNumber() external view returns (uint256); +``` + +### callTimestamp + + +```solidity +function callTimestamp() external view returns (uint256); +``` + +### callGasLeft + + +```solidity +function callGasLeft() external view returns (uint256); +``` + +### callGasPrice + + +```solidity +function callGasPrice() external view returns (uint256); +``` + +### callOrigin + + +```solidity +function callOrigin() external view returns (address); +``` + +### callBalanceOf + + +```solidity +function callBalanceOf(address _addr) external view returns (uint256); +``` + +### callCodeSize + + +```solidity +function callCodeSize(address _addr) external view returns (uint256 size); +``` + +### callCode + + +```solidity +function callCode(address _addr) external view returns (bytes memory code); +``` + +### callCodeHash + + +```solidity +function callCodeHash(address _addr) external view returns (bytes32 codeHash); +``` + +### callChainId + + +```solidity +function callChainId() external view returns (uint256 id); +``` + +## Errors +### DelegateCallNotAllowed + +```solidity +error DelegateCallNotAllowed(uint256 _index); +``` + +### CallReverted + +```solidity +error CallReverted(uint256 _index, bytes _result); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/utils/README.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/utils/README.md new file mode 100644 index 0000000000..2e46e3c6ac --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/utils/README.md @@ -0,0 +1,7 @@ + + +# Contents +- [GasEstimator](GasEstimator.sol/contract.GasEstimator.md) +- [MultiCallUtils](MultiCallUtils.sol/contract.MultiCallUtils.md) +- [RequireUtils](RequireUtils.sol/contract.RequireUtils.md) +- [SequenceUtils](SequenceUtils.sol/contract.SequenceUtils.md) diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/utils/RequireUtils.sol/contract.RequireUtils.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/utils/RequireUtils.sol/contract.RequireUtils.md new file mode 100644 index 0000000000..fb8ff96cba --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/utils/RequireUtils.sol/contract.RequireUtils.md @@ -0,0 +1,149 @@ +# RequireUtils +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/utils/RequireUtils.sol) + + +## Functions +### requireNonExpired + +Validates that a given expiration hasn't expired + +Used as an optional transaction on a Sequence batch, to create expirable transactions. + + +```solidity +function requireNonExpired(uint256 _expiration) external view; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_expiration`|`uint256`| Expiration to check| + + +### requireMinNonce + +Validates that a given wallet has reached a given nonce + +Used as an optional transaction on a Sequence batch, to define transaction execution order + + +```solidity +function requireMinNonce(address _wallet, uint256 _nonce) external view; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_wallet`|`address`|Sequence wallet| +|`_nonce`|`uint256`| Required nonce| + + +### requireMinERC20Balance + +Validates that a wallet has a minimum ERC20 token balance + + +```solidity +function requireMinERC20Balance(address _token, address _wallet, uint256 _minBalance) external view; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_token`|`address`|ERC20 token address| +|`_wallet`|`address`|Sequence wallet| +|`_minBalance`|`uint256`|Minimum required balance| + + +### requireMinERC20Allowance + +Validates that a wallet has a minimum ERC20 allowance for a spender + + +```solidity +function requireMinERC20Allowance(address _token, address _owner, address _spender, uint256 _minAllowance) + external + view; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_token`|`address`|ERC20 token address| +|`_owner`|`address`|Sequence wallet| +|`_spender`|`address`|Address allowed to spend the tokens| +|`_minAllowance`|`uint256`|Minimum required allowance| + + +### requireERC721Ownership + +Validates that a wallet owns a specific ERC721 token + + +```solidity +function requireERC721Ownership(address _token, address _wallet, uint256 _tokenId) external view; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_token`|`address`|ERC721 token address| +|`_wallet`|`address`|Sequence wallet| +|`_tokenId`|`uint256`|Token ID to check for ownership| + + +### requireERC721Approval + +Validates that an ERC721 token is approved for a specific spender + + +```solidity +function requireERC721Approval(address _token, address _owner, address _spender, uint256 _tokenId) external view; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_token`|`address`|ERC721 token address| +|`_owner`|`address`|Sequence wallet| +|`_spender`|`address`|Address that should have approval| +|`_tokenId`|`uint256`|Token ID to check for approval| + + +### requireMinERC1155Balance + +Validates that a wallet has a minimum balance of an ERC1155 token + + +```solidity +function requireMinERC1155Balance(address _token, address _wallet, uint256 _tokenId, uint256 _minBalance) + external + view; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_token`|`address`|ERC1155 token address| +|`_wallet`|`address`|Sequence wallet| +|`_tokenId`|`uint256`|Token ID to check| +|`_minBalance`|`uint256`|Minimum required balance| + + +### requireERC1155Approval + +Validates that an ERC1155 token is approved for a specific operator + + +```solidity +function requireERC1155Approval(address _token, address _owner, address _operator) external view; +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_token`|`address`|ERC1155 token address| +|`_owner`|`address`|Sequence wallet| +|`_operator`|`address`|Address that should have operator approval| + + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/modules/utils/SequenceUtils.sol/contract.SequenceUtils.md b/packages/wallet/wallet-contracts/docs/src/contracts/modules/utils/SequenceUtils.sol/contract.SequenceUtils.md new file mode 100644 index 0000000000..f91b8e21cb --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/modules/utils/SequenceUtils.sol/contract.SequenceUtils.md @@ -0,0 +1,7 @@ +# SequenceUtils +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/modules/utils/SequenceUtils.sol) + +**Inherits:** +[MultiCallUtils](/home/dargon789/wallet-contracts/docs/src/contracts/modules/utils/MultiCallUtils.sol/contract.MultiCallUtils.md), [RequireUtils](/home/dargon789/wallet-contracts/docs/src/contracts/modules/utils/RequireUtils.sol/contract.RequireUtils.md) + + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/trust/README.md b/packages/wallet/wallet-contracts/docs/src/contracts/trust/README.md new file mode 100644 index 0000000000..4252abd93a --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/trust/README.md @@ -0,0 +1,6 @@ + + +# Contents +- [Trust](Trust.sol/contract.Trust.md) +- [absDiff](Trust.sol/function.absDiff.md) +- [TrustFactory](TrustFactory.sol/contract.TrustFactory.md) diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/trust/Trust.sol/contract.Trust.md b/packages/wallet/wallet-contracts/docs/src/contracts/trust/Trust.sol/contract.Trust.md new file mode 100644 index 0000000000..ed6d43c6fb --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/trust/Trust.sol/contract.Trust.md @@ -0,0 +1,186 @@ +# Trust +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/trust/Trust.sol) + +**Inherits:** +[IERC1271Wallet](/home/dargon789/wallet-contracts/docs/src/contracts/interfaces/IERC1271Wallet.sol/interface.IERC1271Wallet.md) + + +## State Variables +### owner + +```solidity +address public immutable owner +``` + + +### beneficiary + +```solidity +address public immutable beneficiary +``` + + +### duration + +```solidity +uint256 public immutable duration +``` + + +### unlocksAt + +```solidity +uint256 public unlocksAt = type(uint256).max +``` + + +### SELECTOR_ERC1271_BYTES_BYTES + +```solidity +bytes4 internal constant SELECTOR_ERC1271_BYTES_BYTES = 0x20c13b0b +``` + + +### SELECTOR_ERC1271_BYTES32_BYTES + +```solidity +bytes4 internal constant SELECTOR_ERC1271_BYTES32_BYTES = 0x1626ba7e +``` + + +## Functions +### constructor + + +```solidity +constructor(address _owner, address _beneficiary, uint256 _duration) ; +``` + +### onlyAllowed + + +```solidity +modifier onlyAllowed() ; +``` + +### onlyMember + + +```solidity +modifier onlyMember() ; +``` + +### isLocked + + +```solidity +function isLocked() public view returns (bool); +``` + +### setUnlocksAt + + +```solidity +function setUnlocksAt(uint256 _unlocksAt) external onlyMember; +``` + +### sendTransaction + + +```solidity +function sendTransaction(address payable _to, uint256 _value, bytes calldata _data) + external + onlyAllowed + returns (bytes memory); +``` + +### isValidSignature + + +```solidity +function isValidSignature(bytes calldata _data, bytes calldata _signature) external view returns (bytes4); +``` + +### isValidSignature + + +```solidity +function isValidSignature(bytes32 _hash, bytes calldata _signature) external view returns (bytes4); +``` + +### receive + + +```solidity +receive() external payable; +``` + +### fallback + + +```solidity +fallback() external payable; +``` + +## Events +### SetUnlocksAt + +```solidity +event SetUnlocksAt(uint256 _unlocksAt); +``` + +### SentTransaction + +```solidity +event SentTransaction(address payable _to, uint256 _value, bytes _data, bytes _result); +``` + +## Errors +### UnlockInThePast + +```solidity +error UnlockInThePast(uint256 _unlocksAt, uint256 _elapsed); +``` + +### UnlockTooEarly + +```solidity +error UnlockTooEarly(uint256 _unlocksAt, uint256 _diff); +``` + +### NotOwner + +```solidity +error NotOwner(address _sender); +``` + +### NotUnlocked + +```solidity +error NotUnlocked(uint256 _unlocksAt); +``` + +### FailedTransaction + +```solidity +error FailedTransaction(address payable _to, uint256 _value, bytes _data, bytes _result); +``` + +### EmptySignature + +```solidity +error EmptySignature(); +``` + +### InvalidSignatureFlag + +```solidity +error InvalidSignatureFlag(bytes _signature, bytes1 _flag); +``` + +### InvalidSignature + +```solidity +error InvalidSignature(bytes32 _hash, bytes32 _rehash, address _signer, bytes _signature); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/trust/Trust.sol/function.absDiff.md b/packages/wallet/wallet-contracts/docs/src/contracts/trust/Trust.sol/function.absDiff.md new file mode 100644 index 0000000000..97adf7e8f5 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/trust/Trust.sol/function.absDiff.md @@ -0,0 +1,8 @@ +# absDiff +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/trust/Trust.sol) + + +```solidity +function absDiff(uint256 a, uint256 b) pure returns (bool, uint256); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/trust/TrustFactory.sol/contract.TrustFactory.md b/packages/wallet/wallet-contracts/docs/src/contracts/trust/TrustFactory.sol/contract.TrustFactory.md new file mode 100644 index 0000000000..8f92c5125f --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/trust/TrustFactory.sol/contract.TrustFactory.md @@ -0,0 +1,26 @@ +# TrustFactory +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/trust/TrustFactory.sol) + + +## Functions +### trustCreationCode + + +```solidity +function trustCreationCode() external pure returns (bytes memory); +``` + +### addressOf + + +```solidity +function addressOf(address _owner, address _beneficiary, uint256 _duration) external view returns (address); +``` + +### deploy + + +```solidity +function deploy(address _owner, address _beneficiary, uint256 _duration) external returns (Trust); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/utils/LibAddress.sol/library.LibAddress.md b/packages/wallet/wallet-contracts/docs/src/contracts/utils/LibAddress.sol/library.LibAddress.md new file mode 100644 index 0000000000..f39aeb8990 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/utils/LibAddress.sol/library.LibAddress.md @@ -0,0 +1,23 @@ +# LibAddress +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/utils/LibAddress.sol) + + +## Functions +### isContract + +Will return true if provided address is a contract + +This contract will return false if called within the constructor of +a contract's deployment, as the code is not yet stored on-chain. + + +```solidity +function isContract(address account) internal view returns (bool); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`account`|`address`|Address to verify if contract or not| + + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/utils/LibBytes.sol/library.LibBytes.md b/packages/wallet/wallet-contracts/docs/src/contracts/utils/LibBytes.sol/library.LibBytes.md new file mode 100644 index 0000000000..4daa0b35a9 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/utils/LibBytes.sol/library.LibBytes.md @@ -0,0 +1,114 @@ +# LibBytes +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/utils/LibBytes.sol) + +**Author:** +Agustin Aguilar (aa@horizon.io) + +This library contains functions for reading data from bytes arrays. + +These functions do not check if the input index is within the bounds of the data array. +Reading out of bounds may return dirty values. + + +## Functions +### readBytes32 + +Returns the bytes32 value at the given index in the input data. + + +```solidity +function readBytes32(bytes calldata data, uint256 index) internal pure returns (bytes32 a); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`data`|`bytes`|The input data.| +|`index`|`uint256`|The index of the value to retrieve.| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|`a`|`bytes32`|The bytes32 value at the given index.| + + +### readUint8 + +Returns the uint8 value at the given index in the input data. + + +```solidity +function readUint8(bytes calldata data, uint256 index) internal pure returns (uint8 a); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`data`|`bytes`|The input data.| +|`index`|`uint256`|The index of the value to retrieve.| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|`a`|`uint8`|The uint8 value at the given index.| + + +### readFirstUint16 + +Returns the first uint16 value in the input data. + + +```solidity +function readFirstUint16(bytes calldata data) internal pure returns (uint16 a); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`data`|`bytes`|The input data.| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|`a`|`uint16`|The first uint16 value in the input data.| + + +### readUint32 + +Returns the uint32 value at the given index in the input data. + + +```solidity +function readUint32(bytes calldata data, uint256 index) internal pure returns (uint32 a); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`data`|`bytes`|The input data.| +|`index`|`uint256`|The index of the value to retrieve.| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|`a`|`uint32`|The uint32 value at the given index.| + + +### readMBytes4 + + +```solidity +function readMBytes4(bytes memory data, uint256 index) internal pure returns (bytes4 a); +``` + +### readMBytes32 + + +```solidity +function readMBytes32(bytes memory data, uint256 index) internal pure returns (bytes32 a); +``` + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/utils/LibBytesPointer.sol/library.LibBytesPointer.md b/packages/wallet/wallet-contracts/docs/src/contracts/utils/LibBytesPointer.sol/library.LibBytesPointer.md new file mode 100644 index 0000000000..3ba4bd7a06 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/utils/LibBytesPointer.sol/library.LibBytesPointer.md @@ -0,0 +1,201 @@ +# LibBytesPointer +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/utils/LibBytesPointer.sol) + +**Author:** +Agustin Aguilar (aa@horizon.io) + +This library contains functions for reading data from bytes arrays with a pointer. + +These functions do not check if the input index is within the bounds of the data array. +Reading out of bounds may return dirty values. + + +## Functions +### readFirstUint16 + +Returns the first uint16 value in the input data and updates the pointer. + + +```solidity +function readFirstUint16(bytes calldata _data) internal pure returns (uint16 a, uint256 newPointer); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_data`|`bytes`|The input data.| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|`a`|`uint16`|The first uint16 value.| +|`newPointer`|`uint256`|The new pointer.| + + +### readUint8 + +Returns the uint8 value at the given index in the input data and updates the pointer. + + +```solidity +function readUint8(bytes calldata _data, uint256 _index) internal pure returns (uint8 a, uint256 newPointer); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_data`|`bytes`|The input data.| +|`_index`|`uint256`|The index of the value to retrieve.| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|`a`|`uint8`|The uint8 value at the given index.| +|`newPointer`|`uint256`|The new pointer.| + + +### readAddress + + +```solidity +function readAddress(bytes calldata _data, uint256 _index) internal pure returns (address a, uint256 newPointer); +``` + +### readUint8Address + +Returns the uint8 value and the address at the given index in the input data and updates the pointer. + + +```solidity +function readUint8Address(bytes calldata _data, uint256 _index) + internal + pure + returns (uint8 a, address b, uint256 newPointer); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_data`|`bytes`|The input data.| +|`_index`|`uint256`|The index of the value to retrieve.| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|`a`|`uint8`|The uint8 value at the given index.| +|`b`|`address`|The following address value.| +|`newPointer`|`uint256`|The new pointer.| + + +### readUint16 + +Returns the uint16 value at the given index in the input data and updates the pointer. + + +```solidity +function readUint16(bytes calldata _data, uint256 _index) internal pure returns (uint16 a, uint256 newPointer); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_data`|`bytes`|The input data.| +|`_index`|`uint256`|The index of the value to retrieve.| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|`a`|`uint16`|The uint16 value at the given index.| +|`newPointer`|`uint256`|The new pointer.| + + +### readUintX + + +```solidity +function readUintX(bytes calldata _data, uint256 _bytes, uint256 _index) + internal + pure + returns (uint256 a, uint256 newPointer); +``` + +### readUint24 + +Returns the uint24 value at the given index in the input data and updates the pointer. + + +```solidity +function readUint24(bytes calldata _data, uint256 _index) internal pure returns (uint24 a, uint256 newPointer); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_data`|`bytes`|The input data.| +|`_index`|`uint256`|The index of the value to retrieve.| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|`a`|`uint24`|The uint24 value at the given index.| +|`newPointer`|`uint256`|The new pointer.| + + +### readUint64 + +Returns the uint64 value at the given index in the input data and updates the pointer. + + +```solidity +function readUint64(bytes calldata _data, uint256 _index) internal pure returns (uint64 a, uint256 newPointer); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_data`|`bytes`|The input data.| +|`_index`|`uint256`|The index of the value to retrieve.| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|`a`|`uint64`|The uint64 value at the given index.| +|`newPointer`|`uint256`|The new pointer.| + + +### readBytes4 + + +```solidity +function readBytes4(bytes calldata _data, uint256 _pointer) internal pure returns (bytes4 a, uint256 newPointer); +``` + +### readBytes32 + +Returns the bytes32 value at the given index in the input data and updates the pointer. + + +```solidity +function readBytes32(bytes calldata _data, uint256 _pointer) internal pure returns (bytes32 a, uint256 newPointer); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_data`|`bytes`|The input data.| +|`_pointer`|`uint256`|The index of the value to retrieve.| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|`a`|`bytes32`|The bytes32 value at the given index.| +|`newPointer`|`uint256`|The new pointer.| + + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/utils/LibOptim.sol/library.LibOptim.md b/packages/wallet/wallet-contracts/docs/src/contracts/utils/LibOptim.sol/library.LibOptim.md new file mode 100644 index 0000000000..3c5aa6bba9 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/utils/LibOptim.sol/library.LibOptim.md @@ -0,0 +1,100 @@ +# LibOptim +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/utils/LibOptim.sol) + +**Author:** +Agustin Aguilar (aa@horizon.io) + +This library contains functions for optimizing certain EVM operations. + + +## Functions +### fkeccak256 + +Computes the keccak256 hash of two 32-byte inputs. + +It uses only scratch memory space. + + +```solidity +function fkeccak256(bytes32 _a, bytes32 _b) internal pure returns (bytes32 c); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_a`|`bytes32`|The first 32 bytes of the hash.| +|`_b`|`bytes32`|The second 32 bytes of the hash.| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|`c`|`bytes32`|The keccak256 hash of the two 32-byte inputs.| + + +### returnData + +Returns the return data from the last call. + + +```solidity +function returnData() internal pure returns (bytes memory r); +``` +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|`r`|`bytes`|The return data from the last call.| + + +### call + +Calls another contract with the given parameters. + +This method doesn't increase the memory pointer. + + +```solidity +function call(address _to, uint256 _val, uint256 _gas, bytes calldata _data) internal returns (bool r); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_to`|`address`|The address of the contract to call.| +|`_val`|`uint256`|The value to send to the contract.| +|`_gas`|`uint256`|The amount of gas to provide for the call.| +|`_data`|`bytes`|The data to send to the contract.| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|`r`|`bool`|The success status of the call.| + + +### delegatecall + +Calls another contract with the given parameters, using delegatecall. + +This method doesn't increase the memory pointer. + + +```solidity +function delegatecall(address _to, uint256 _gas, bytes calldata _data) internal returns (bool r); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_to`|`address`|The address of the contract to call.| +|`_gas`|`uint256`|The amount of gas to provide for the call.| +|`_data`|`bytes`|The data to send to the contract.| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|`r`|`bool`|The success status of the call.| + + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/utils/LibString.sol/library.LibString.md b/packages/wallet/wallet-contracts/docs/src/contracts/utils/LibString.sol/library.LibString.md new file mode 100644 index 0000000000..9dfccb6370 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/utils/LibString.sol/library.LibString.md @@ -0,0 +1,106 @@ +# LibString +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/utils/LibString.sol) + +This library contains functions for manipulating strings in Solidity. + + +## State Variables +### ALPHABET_HEX_16 + +```solidity +bytes private constant ALPHABET_HEX_16 = "0123456789abcdef" +``` + + +### ALPHABET_32 + +```solidity +bytes private constant ALPHABET_32 = "abcdefghijklmnopqrstuvwxyz234567" +``` + + +## Functions +### prefixHexadecimal + +Prefixes a hexadecimal string with "0x". + + +```solidity +function prefixHexadecimal(string memory _hex) internal pure returns (string memory); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_hex`|`string`|The hexadecimal string to prefix.| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`string`|The prefixed hexadecimal string.| + + +### prefixBase32 + +Prefixes a base32 string with "b". + + +```solidity +function prefixBase32(string memory _base32) internal pure returns (string memory); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_base32`|`string`|The base32 string to prefix.| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`string`|The prefixed base32 string.| + + +### bytesToHexadecimal + +Converts a byte array to a hexadecimal string. + + +```solidity +function bytesToHexadecimal(bytes memory _bytes) internal pure returns (string memory); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_bytes`|`bytes`|The byte array to convert.| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`string`|The resulting hexadecimal string.| + + +### bytesToBase32 + +Converts a byte array to a base32 string. + + +```solidity +function bytesToBase32(bytes memory _bytes) internal pure returns (string memory); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_bytes`|`bytes`|The byte array to convert.| + +**Returns** + +|Name|Type|Description| +|----|----|-----------| +|``|`string`|The resulting base32 string.| + + diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/utils/README.md b/packages/wallet/wallet-contracts/docs/src/contracts/utils/README.md new file mode 100644 index 0000000000..43a6ef4777 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/utils/README.md @@ -0,0 +1,9 @@ + + +# Contents +- [LibAddress](LibAddress.sol/library.LibAddress.md) +- [LibBytes](LibBytes.sol/library.LibBytes.md) +- [LibBytesPointer](LibBytesPointer.sol/library.LibBytesPointer.md) +- [LibOptim](LibOptim.sol/library.LibOptim.md) +- [LibString](LibString.sol/library.LibString.md) +- [SignatureValidator](SignatureValidator.sol/library.SignatureValidator.md) diff --git a/packages/wallet/wallet-contracts/docs/src/contracts/utils/SignatureValidator.sol/library.SignatureValidator.md b/packages/wallet/wallet-contracts/docs/src/contracts/utils/SignatureValidator.sol/library.SignatureValidator.md new file mode 100644 index 0000000000..42767e4461 --- /dev/null +++ b/packages/wallet/wallet-contracts/docs/src/contracts/utils/SignatureValidator.sol/library.SignatureValidator.md @@ -0,0 +1,130 @@ +# SignatureValidator +[Git Source](https://github.com/0xsequence/wallet-contracts/blob/09c54e74c2803b55df32c0470f8b0e0ebe86f4c9/contracts/utils/SignatureValidator.sol) + +Contains logic for signature validation. +Signatures from wallet contracts assume ERC-1271 support (https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1271.md) +Notes: Methods are strongly inspired by contracts in https://github.com/0xProject/0x-monorepo/blob/development/ + + +## State Variables +### ERC1271_MAGICVALUE +| +| Variables | +|__________________________________ + + +```solidity +bytes4 internal constant ERC1271_MAGICVALUE = 0x20c13b0b +``` + + +### ERC1271_MAGICVALUE_BYTES32 + +```solidity +bytes4 internal constant ERC1271_MAGICVALUE_BYTES32 = 0x1626ba7e +``` + + +### SIG_TYPE_EIP712 + +```solidity +uint256 private constant SIG_TYPE_EIP712 = 1 +``` + + +### SIG_TYPE_ETH_SIGN + +```solidity +uint256 private constant SIG_TYPE_ETH_SIGN = 2 +``` + + +### SIG_TYPE_WALLET_BYTES32 + +```solidity +uint256 private constant SIG_TYPE_WALLET_BYTES32 = 3 +``` + + +## Functions +### recoverSigner + +| +| Signature Functions | +|__________________________________ + +Recover the signer of hash, assuming it's an EOA account + +Only for SignatureType.EIP712 and SignatureType.EthSign signatures + + +```solidity +function recoverSigner(bytes32 _hash, bytes calldata _signature) internal pure returns (address signer); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_hash`|`bytes32`| Hash that was signed encoded as (bytes32 r, bytes32 s, uint8 v, ... , SignatureType sigType)| +|`_signature`|`bytes`|| + + +### isValidSignature + +Returns true if the provided signature is valid for the given signer. + +Supports SignatureType.EIP712, SignatureType.EthSign, and ERC1271 signatures + + +```solidity +function isValidSignature(bytes32 _hash, address _signer, bytes calldata _signature) + internal + view + returns (bool valid); +``` +**Parameters** + +|Name|Type|Description| +|----|----|-----------| +|`_hash`|`bytes32`| Hash that was signed| +|`_signer`|`address`| Address of the signer candidate| +|`_signature`|`bytes`|Signature byte array| + + +## Errors +### InvalidSignatureLength + +```solidity +error InvalidSignatureLength(bytes _signature); +``` + +### EmptySignature + +```solidity +error EmptySignature(); +``` + +### InvalidSValue + +```solidity +error InvalidSValue(bytes _signature, bytes32 _s); +``` + +### InvalidVValue + +```solidity +error InvalidVValue(bytes _signature, uint256 _v); +``` + +### UnsupportedSignatureType + +```solidity +error UnsupportedSignatureType(bytes _signature, uint256 _type, bool _recoverMode); +``` + +### SignerIsAddress0 + +```solidity +error SignerIsAddress0(bytes _signature); +``` + diff --git a/packages/wallet/wallet-contracts/foundry.lock b/packages/wallet/wallet-contracts/foundry.lock new file mode 100644 index 0000000000..bca6a6d8c1 --- /dev/null +++ b/packages/wallet/wallet-contracts/foundry.lock @@ -0,0 +1,8 @@ +{ + "lib/forge-std": { + "rev": "73d44ec7d124e3831bc5f832267889ffb6f9bc3f" + }, + "lib/foundry-huff": { + "rev": "7648faf3990cc4561d52b71af03282fad3a803d8" + } +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/foundry.toml b/packages/wallet/wallet-contracts/foundry.toml new file mode 100644 index 0000000000..d26fe591fe --- /dev/null +++ b/packages/wallet/wallet-contracts/foundry.toml @@ -0,0 +1,11 @@ +[profile.default] +src = 'contracts' +out = 'foundry_artifacts' +libs = ["node_modules", "lib", "dependencies"] +test = 'foundry_test' + +ffi = true +max_test_rejects = 2048000 + +[dependencies] +forge-std = "1.11.0" diff --git a/packages/wallet/wallet-contracts/foundry_test/base/AdvTest.sol b/packages/wallet/wallet-contracts/foundry_test/base/AdvTest.sol new file mode 100644 index 0000000000..b79268c40e --- /dev/null +++ b/packages/wallet/wallet-contracts/foundry_test/base/AdvTest.sol @@ -0,0 +1,205 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "forge-std/Test.sol"; + +contract AdvTest is Test { + function signAndPack(uint256 _pk, bytes32 _hash) internal pure returns (bytes memory) { + (uint8 v, bytes32 r, bytes32 s) = vm.sign(_pk, _hash); + return abi.encodePacked(r, s, v); + } + + function signAndPack(uint256 _pk, bytes32 _hash, uint8 _sufix) internal pure returns (bytes memory) { + (uint8 v, bytes32 r, bytes32 s) = vm.sign(_pk, _hash); + return abi.encodePacked(r, s, v, _sufix); + } + + function mayBoundArr(uint256 _size) internal view returns (uint256) { + try vm.envUint("MAX_ARRAY_LEN") returns (uint256 b) { + return b == 0 ? _size : bound(_size, 0, b); + } catch { + return _size; + } + } + + function boundNoSys(address _a) internal view returns (address) { + address c2 = address(0x007109709ecfa91a80626ff3989d68f67f5b1dd12d); + address vm = address(0x004e59b44847b379578588920ca78fbf26c0b4956c); + address c3 = address(0x00000000000000000000636f6e736f6c652e6c6f67); + + boundNoPrecompile(_a); + boundDiff(_a, c2, vm, c3, address(this)); + + return _a; + } + + function boundNoPrecompile(address _a) internal pure returns (address) { + vm.assume(uint160(_a) > 10); + return _a; + } + + function boundDiff(address _a, address _b) internal pure returns (address) { + vm.assume(_a != _b); + return _a; + } + + function boundDiff(address _a, address _b, address _c) internal pure returns (address) { + address[] memory arr = new address[](2); + arr[0] = _b; + arr[1] = _c; + return boundDiff(_a, arr); + } + + function boundDiff(address _a, address _b, address _c, address _d) internal pure returns (address) { + address[] memory _arr = new address[](3); + _arr[0] = _b; + _arr[1] = _c; + _arr[2] = _d; + return boundDiff(_a, _arr); + } + + function boundDiff(address _a, address _b, address _c, address _d, address _e) internal pure returns (address) { + address[] memory _arr = new address[](4); + _arr[0] = _b; + _arr[1] = _c; + _arr[2] = _d; + _arr[3] = _e; + return boundDiff(_a, _arr); + } + + function boundDiff(address _a, address[] memory _b) internal pure returns (address) { + vm.assume(!inSet(_a, _b)); + return _a; + } + + function boundPk(uint256 _a) internal view returns (uint256) { + _a = bound(_a, 1, 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364139); + return _a; + } + + function boundDiff(uint256 _a, uint256 _b) internal pure returns (uint256) { + vm.assume(_a != _b); + return _a; + } + + function boundDiff(uint256 _a, uint256 _b, uint256 _c) internal pure returns (uint256) { + uint256[] memory arr = new uint256[](2); + arr[0] = _b; + arr[1] = _c; + return boundDiff(_a, arr); + } + + function boundDiff(uint256 _a, uint256 _b, uint256 _c, uint256 _d) internal pure returns (uint256) { + uint256[] memory _arr = new uint256[](3); + _arr[0] = _b; + _arr[1] = _c; + _arr[2] = _d; + return boundDiff(_a, _arr); + } + + function boundDiff(uint256 _a, uint256 _b, uint256 _c, uint256 _d, uint256 _e) internal pure returns (uint256) { + uint256[] memory _arr = new uint256[](4); + _arr[0] = _b; + _arr[1] = _c; + _arr[2] = _d; + _arr[3] = _e; + return boundDiff(_a, _arr); + } + + function boundDiff(uint256 _a, uint256 _b, uint256 _c, uint256 _d, uint256 _e, uint256 _f) + internal + pure + returns (uint256) + { + uint256[] memory _arr = new uint256[](5); + _arr[0] = _b; + _arr[1] = _c; + _arr[2] = _d; + _arr[3] = _e; + _arr[4] = _f; + return boundDiff(_a, _arr); + } + + function boundDiff(uint256 _a, uint256 _b, uint256 _c, uint256 _d, uint256 _e, uint256 _f, uint256 _g) + internal + pure + returns (uint256) + { + uint256[] memory _arr = new uint256[](6); + _arr[0] = _b; + _arr[1] = _c; + _arr[2] = _d; + _arr[3] = _e; + _arr[4] = _f; + _arr[5] = _g; + return boundDiff(_a, _arr); + } + + function boundDiff(uint256 _a, uint256 _b, uint256 _c, uint256 _d, uint256 _e, uint256 _f, uint256 _g, uint256 _h) + internal + pure + returns (uint256) + { + uint256[] memory _arr = new uint256[](7); + _arr[0] = _b; + _arr[1] = _c; + _arr[2] = _d; + _arr[3] = _e; + _arr[4] = _f; + _arr[5] = _g; + _arr[6] = _h; + return boundDiff(_a, _arr); + } + + function boundDiff(uint256 _a, uint256[] memory _b) internal pure returns (uint256) { + vm.assume(!inSet(_a, _b)); + return _a; + } + + function inSet(uint256 _a, uint256[] memory _b) internal pure returns (bool) { + unchecked { + for (uint256 i = 0; i < _b.length; i++) { + if (_a == _b[i]) { + return true; + } + } + + return false; + } + } + + function inSet(address _a, address[] memory _b) internal pure returns (bool) { + unchecked { + for (uint256 i = 0; i < _b.length; i++) { + if (_a == _b[i]) { + return true; + } + } + + return false; + } + } + + function boundNoContract(address _a) internal view returns (address) { + vm.assume(_a.code.length == 0); + return _a; + } + + function boundNoBalance(address _a) internal view returns (address) { + vm.assume(_a.balance == 0); + return _a; + } + + function replicate(bytes memory _data) internal { + (bool suc, bytes memory res) = address(this).call(_data); + if (!suc) { + assembly { + revert(add(res, 32), mload(res)) + } + } + } + + function addrToBytes32(address _addr) internal pure returns (bytes32) { + return bytes32(uint256(uint160(_addr))); + } +} diff --git a/packages/wallet/wallet-contracts/foundry_test/hooks/WalletProxyHook.t.sol b/packages/wallet/wallet-contracts/foundry_test/hooks/WalletProxyHook.t.sol new file mode 100644 index 0000000000..04ebf54cf6 --- /dev/null +++ b/packages/wallet/wallet-contracts/foundry_test/hooks/WalletProxyHook.t.sol @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "contracts/hooks/WalletProxyHook.sol"; +import "contracts/hooks/interfaces/IWalletProxy.sol"; +import "contracts/modules/commons/ModuleHooks.sol"; +import "contracts/Factory.sol"; + +import "foundry_test/base/AdvTest.sol"; + +contract WalletProxyHookTest is AdvTest { + ModuleHooks private template; + ModuleHooks private walletMod; + WalletProxyHook private wallet; + + function setUp() external { + Factory factory = new Factory(); + template = new ModuleHooks(); + walletMod = ModuleHooks(payable(factory.deploy(address(template), bytes32(0)))); + WalletProxyHook hook = new WalletProxyHook(); + + // Add hook + vm.prank(address(walletMod)); + walletMod.addHook(IWalletProxy.PROXY_getImplementation.selector, address(hook)); + + wallet = WalletProxyHook(address(walletMod)); + vm.label(address(wallet), "wallet"); + } + + // + // Get Implementation + // + + function test_PROXY_getImplementation() external { + assertEq(wallet.PROXY_getImplementation(), address(template)); + } +} diff --git a/packages/wallet/wallet-contracts/foundry_test/modules/commons/Implementation.t.sol b/packages/wallet/wallet-contracts/foundry_test/modules/commons/Implementation.t.sol new file mode 100644 index 0000000000..f974882809 --- /dev/null +++ b/packages/wallet/wallet-contracts/foundry_test/modules/commons/Implementation.t.sol @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "contracts/modules/commons/Implementation.sol"; +import "contracts/Factory.sol"; + +import "foundry_test/base/AdvTest.sol"; + +contract ImplementationImp is Implementation { + function setImplementation(address _imp) external { + _setImplementation(_imp); + } + + function getImplementation() external view returns (address) { + return _getImplementation(); + } + + function stub() external pure virtual returns (uint256) { + return 1; + } +} + +contract NextImplementation is ImplementationImp { + function stub() external pure override returns (uint256) { + return 2; + } +} + +contract ImplementationTest is AdvTest { + function test_setImplementation(address _imp, address _next) external { + boundNoContract(boundNoSys(_imp)); + + vm.etch(_imp, address(new ImplementationImp()).code); + + assertEq(ImplementationImp(_imp).getImplementation(), address(0)); + + ImplementationImp(_imp).setImplementation(_next); + + assertEq(ImplementationImp(_imp).getImplementation(), _next); + assertEq(vm.load(_imp, addrToBytes32(_imp)), addrToBytes32(_next)); + } + + function test_setImplementation_matchWallet(bytes32 _salt, address _imp, address _imp2) external { + Factory factory = new Factory(); + + ImplementationImp imp = new ImplementationImp(); + ImplementationImp imp2 = new NextImplementation(); + + boundNoContract(boundDiff(boundNoSys(_imp), address(factory))); + boundNoContract(boundDiff(boundNoSys(_imp2), address(factory))); + + vm.etch(_imp, address(imp).code); + address wallet = factory.deploy(_imp, _salt); + + assertEq(ImplementationImp(wallet).getImplementation(), _imp); + assertEq(ImplementationImp(wallet).stub(), 1); + + vm.etch(_imp2, address(imp2).code); + + ImplementationImp(wallet).setImplementation(_imp2); + + assertEq(ImplementationImp(wallet).getImplementation(), _imp2); + assertEq(vm.load(wallet, addrToBytes32(wallet)), addrToBytes32(_imp2)); + assertEq(ImplementationImp(wallet).stub(), 2); + } +} diff --git a/packages/wallet/wallet-contracts/foundry_test/modules/commons/ModuleCalls.t.sol b/packages/wallet/wallet-contracts/foundry_test/modules/commons/ModuleCalls.t.sol new file mode 100644 index 0000000000..493974bbec --- /dev/null +++ b/packages/wallet/wallet-contracts/foundry_test/modules/commons/ModuleCalls.t.sol @@ -0,0 +1,351 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "contracts/modules/commons/ModuleCalls.sol"; +import "contracts/Factory.sol"; + +import "foundry_test/base/AdvTest.sol"; + +contract ImmutableBytes { + bytes public b; + + constructor(bytes memory _b) { + b = _b; + } + + fallback() external payable {} + receive() external payable {} +} + +contract WillRevert { + ImmutableBytes private immutable ib; + + constructor(bytes memory _err) { + ib = new ImmutableBytes(_err); + } + + fallback() external payable { + _revert(); + } + + receive() external payable { + _revert(); + } + + function _revert() internal view { + bytes memory e = ib.b(); + assembly { + revert(add(e, 32), mload(e)) + } + } +} + +contract WillDelegateTo { + address private immutable expectSelf; + bytes32 private immutable expectData; + address private immutable delegate; + + constructor(address _expectSelf, bytes memory _expectData) { + expectSelf = _expectSelf; + expectData = keccak256(_expectData); + delegate = address(this); + } + + fallback() external payable { + _check(); + } + + receive() external payable { + _check(); + } + + function _check() internal { + bytes32 dataHash = keccak256(msg.data); + require(dataHash == expectData && address(this) == expectSelf); + + bytes32 key = keccak256(abi.encode(delegate)); + assembly { sstore(key, add(sload(key), 1)) } + } +} + +contract ModuleCallsImp is ModuleCalls { + function validateNonce(uint256 _rawNonce) external { + _validateNonce(_rawNonce); + } + + function writeNonce(uint256 _space, uint256 _nonce) external { + _writeNonce(_space, _nonce); + } + + // Module Auth imp + mapping(bytes32 => mapping(bytes => bytes32)) public sigToSubdigest; + mapping(bytes32 => mapping(bytes => bool)) public sigToIsValid; + + function _signatureValidation(bytes32 _digest, bytes calldata _signature) + internal + view + override + returns (bool isValid, bytes32 subdigest) + { + subdigest = sigToSubdigest[_digest][_signature]; + isValid = sigToIsValid[_digest][_signature]; + } + + function mockSignature(bytes32 _digest, bytes calldata _signature, bytes32 _subdigest, bool _isValid) external { + sigToSubdigest[_digest][_signature] = _subdigest; + sigToIsValid[_digest][_signature] = _isValid; + } + + function signatureRecovery(bytes32, bytes calldata) + public + view + override + returns (uint256, uint256, bytes32, bytes32, uint256) + {} + + function _isValidImage(bytes32) internal view override returns (bool) {} + + function updateImageHash(bytes32) external override {} + + function _updateImageHash(bytes32) internal override {} +} + +contract ModuleCallsTest is AdvTest { + ModuleCallsImp private template; + ModuleCallsImp private imp; + Factory private factory; + + function setUp() external { + template = new ModuleCallsImp(); + factory = new Factory(); + imp = ModuleCallsImp(factory.deploy(address(template), bytes32(0))); + } + + struct ToValAndData { + address target; + uint256 value; + bytes data; + } + + event TxExecuted(bytes32 _tx) anonymous; + event NonceChange(uint256 _space, uint256 _newNonce); + event TxFailed(bytes32 _tx, bytes _reason); + event GapNonceChange(uint256 _space, uint256 _oldNonce, uint256 _newNonce); + event NoNonceUsed(); + + function test_execute(ToValAndData[] memory _rtxs, bytes memory _sig, bytes32 _subdigest) external { + uint256 size = mayBoundArr(_rtxs.length); + IModuleCalls.Transaction[] memory txs = new IModuleCalls.Transaction[](size); + uint256 total; + + for (uint256 i = 0; i < size; i++) { + txs[i].data = _rtxs[i].data; + txs[i].target = boundNoBalance( + boundNoContract( + boundDiff(boundNoSys(_rtxs[i].target), address(template), address(imp), address(factory)) + ) + ); + txs[i].value = bound(_rtxs[i].value, 0, type(uint256).max - total); + + total += txs[i].value; + } + + vm.deal(address(imp), total); + bytes32 digest = keccak256(abi.encode(0, txs)); + imp.mockSignature(digest, _sig, _subdigest, false); + + vm.expectRevert(abi.encodeWithSignature("InvalidSignature(bytes32,bytes)", _subdigest, _sig)); + imp.execute(txs, 0, _sig); + + vm.expectRevert(abi.encodeWithSignature("BadNonce(uint256,uint256,uint256)", 0, 1, 0)); + imp.execute(txs, 1, _sig); + + imp.mockSignature(digest, _sig, _subdigest, true); + + vm.expectEmit(true, true, true, true, address(imp)); + emit NonceChange(0, 1); + + for (uint256 i = 0; i < size; i++) { + vm.expectCall(txs[i].target, txs[i].data); + } + + imp.execute(txs, 0, _sig); + + assertEq(imp.nonce(), 1); + + for (uint256 i = 0; i < size; i++) { + assertTrue(txs[i].target.balance >= txs[i].value); + } + } + + function test_execute_reverts( + ToValAndData[] memory _rtxs, + uint256 _reverti, + bool _revertsOnErr, + bool _delegateCall, + bytes memory _err, + bytes memory _sig, + bytes32 _subdigest + ) external { + uint256 size = mayBoundArr(_rtxs.length); + vm.assume(size != 0); + + IModuleCalls.Transaction[] memory txs = new IModuleCalls.Transaction[](size); + uint256 total; + + _reverti = bound(_reverti, 0, size - 1); + + address willRevert = address(new WillRevert(_err)); + + for (uint256 i = 0; i < size; i++) { + if (_reverti == i) { + txs[i].target = willRevert; + txs[i].revertOnError = _revertsOnErr; + txs[i].delegateCall = _delegateCall; + } else { + txs[i].target = boundNoBalance( + boundNoContract( + boundDiff(boundNoSys(_rtxs[i].target), address(template), address(imp), address(factory)) + ) + ); + } + + txs[i].data = _rtxs[i].data; + txs[i].value = bound(_rtxs[i].value, 0, type(uint256).max - total); + + total += txs[i].value; + } + + vm.deal(address(imp), total); + + bytes32 digest = keccak256(abi.encode(0, txs)); + imp.mockSignature(digest, _sig, _subdigest, true); + + if (_revertsOnErr) { + vm.expectRevert(_err); + } + + imp.execute(txs, 0, _sig); + + for (uint256 i = 0; i < size; i++) { + if (_revertsOnErr || txs[i].target == willRevert) { + assertEq(txs[i].target.balance, 0); + } else { + assertTrue(txs[i].target.balance >= txs[i].value); + } + } + } + + function test_execute_delegateCall(ToValAndData[] memory _rtxs, bytes memory _sig, bytes32 _subdigest) external { + uint256 size = mayBoundArr(_rtxs.length); + IModuleCalls.Transaction[] memory txs = new IModuleCalls.Transaction[](size); + + for (uint256 i = 0; i < size; i++) { + txs[i].data = _rtxs[i].data; + txs[i].target = address(new WillDelegateTo(address(imp), _rtxs[i].data)); + txs[i].value = _rtxs[i].value; + txs[i].delegateCall = true; + } + + bytes32 digest = keccak256(abi.encode(0, txs)); + imp.mockSignature(digest, _sig, _subdigest, true); + + imp.execute(txs, 0, _sig); + assertEq(imp.nonce(), 1); + + for (uint256 i = 0; i < size; i++) { + bytes32 key = keccak256(abi.encode(txs[i].target)); + assertTrue(uint256(vm.load(address(imp), key)) != 0); + } + } + + function test_selfExecute(ToValAndData[] memory _rtxs) external { + uint256 size = mayBoundArr(_rtxs.length); + IModuleCalls.Transaction[] memory txs = new IModuleCalls.Transaction[](size); + uint256 total; + + for (uint256 i = 0; i < size; i++) { + txs[i].data = _rtxs[i].data; + txs[i].target = boundNoBalance( + boundNoContract( + boundDiff(boundNoSys(_rtxs[i].target), address(template), address(imp), address(factory)) + ) + ); + txs[i].value = bound(_rtxs[i].value, 0, type(uint256).max - total); + + total += txs[i].value; + } + + vm.deal(address(imp), total); + + for (uint256 i = 0; i < size; i++) { + vm.expectCall(txs[i].target, txs[i].data); + } + + vm.prank(address(imp)); + imp.selfExecute(txs); + + for (uint256 i = 0; i < size; i++) { + assertTrue(txs[i].target.balance >= txs[i].value); + } + } + + function test_fail_selfExecute_NotSelf(ToValAndData[] memory _rtxs, address _notself) external { + _notself = boundDiff(_notself, address(imp)); + + uint256 size = mayBoundArr(_rtxs.length); + IModuleCalls.Transaction[] memory txs = new IModuleCalls.Transaction[](size); + + for (uint256 i = 0; i < size; i++) { + txs[i].data = _rtxs[i].data; + txs[i].target = _rtxs[i].target; + txs[i].value = _rtxs[i].value; + } + + vm.prank(_notself); + vm.expectRevert(abi.encodeWithSignature("OnlySelfAuth(address,address)", _notself, address(imp))); + imp.selfExecute(txs); + } + + function test_validateNonce_Normal(uint160 _space, uint88 _nonce) external { + uint256 encoded = uint256(abi.decode(abi.encodePacked(_space, uint8(0), _nonce), (bytes32))); + + imp.writeNonce(_space, _nonce); + + vm.expectEmit(true, true, true, true, address(imp)); + emit NonceChange(_space, uint256(_nonce) + 1); + imp.validateNonce(encoded); + + assertEq(imp.readNonce(_space), uint256(_nonce) + 1); + assertEq(imp.nonce(), _space == 0 ? uint256(_nonce) + 1 : 0); + } + + function test_fail_validateNonce_Normal_Bad(uint160 _space, uint88 _nonce, uint88 _badprev) external { + _badprev = uint88(boundDiff(_badprev, _nonce)); + + uint256 encoded = uint256(abi.decode(abi.encodePacked(_space, uint8(0), _nonce), (bytes32))); + + imp.writeNonce(_space, _badprev); + + vm.expectRevert(abi.encodeWithSignature("BadNonce(uint256,uint256,uint256)", _space, _nonce, _badprev)); + imp.validateNonce(encoded); + } + + function test_fail_noDelegatecall(ToValAndData[] memory _rtxs, bytes memory _sig, uint256 _nonce) external { + uint256 size = mayBoundArr(_rtxs.length); + IModuleCalls.Transaction[] memory txs = new IModuleCalls.Transaction[](size); + uint256 total; + + for (uint256 i = 0; i < size; i++) { + txs[i].data = _rtxs[i].data; + txs[i].target = boundNoSys(_rtxs[i].target); + txs[i].value = bound(_rtxs[i].value, 0, type(uint256).max - total); + + total += txs[i].value; + } + + vm.deal(address(imp), total); + vm.expectRevert(abi.encodeWithSignature("OnlyDelegatecall()")); + template.execute(txs, _nonce, _sig); + } +} diff --git a/packages/wallet/wallet-contracts/foundry_test/modules/commons/ModuleERC5719.t.sol b/packages/wallet/wallet-contracts/foundry_test/modules/commons/ModuleERC5719.t.sol new file mode 100644 index 0000000000..49fe4c1a08 --- /dev/null +++ b/packages/wallet/wallet-contracts/foundry_test/modules/commons/ModuleERC5719.t.sol @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "contracts/modules/commons/ModuleERC5719.sol"; + +import "foundry_test/base/AdvTest.sol"; + +contract ModuleERC5719Test is AdvTest { + ModuleERC5719 private module; + + function setUp() public { + module = new ModuleERC5719(); + } + + function test_getAlternativeSignature() external { + // 0xba5a3cbb592813d90eae65a3aac33e9b6dfc7be50623aa25e151fe3da06c8443 + // == + // ipfs://bafybeif2li6lwwjicpmq5ltfuovmgpu3nx6hxzigeovclykr7y62a3eeim + + // 0xb6f77d000c8791676d96aedac165dd1bb2da4a5baf78198b9f391fc76b893f46 + // == + // ipfs://bafybeifw656qadehsftw3fvo3lawlxi3wlneuw5ppamyxhzzd7dwxcj7iy + + vm.startPrank(address(module)); + + bytes32 root = 0xba5a3cbb592813d90eae65a3aac33e9b6dfc7be50623aa25e151fe3da06c8443; + module.updateIPFSRoot(root); + + assertEq( + module.getAlternativeSignature(0x64f16a2f2c80ab7f3b0e0edc67c0bf1399402dc389cfb4271ba58abe3f61ea16), + "ipfs://bafybeif2li6lwwjicpmq5ltfuovmgpu3nx6hxzigeovclykr7y62a3eeim/ERC5719/0x64f16a2f2c80ab7f3b0e0edc67c0bf1399402dc389cfb4271ba58abe3f61ea16" + ); + + root = 0xb6f77d000c8791676d96aedac165dd1bb2da4a5baf78198b9f391fc76b893f46; + module.updateIPFSRoot(root); + + assertEq( + module.getAlternativeSignature(0x11b858b3b52eb84e900639ebb082aeacb10bd9d239f58ae3f7092885cc3593b6), + "ipfs://bafybeifw656qadehsftw3fvo3lawlxi3wlneuw5ppamyxhzzd7dwxcj7iy/ERC5719/0x11b858b3b52eb84e900639ebb082aeacb10bd9d239f58ae3f7092885cc3593b6" + ); + } +} diff --git a/packages/wallet/wallet-contracts/foundry_test/modules/commons/ModuleExtraAuth.t.sol b/packages/wallet/wallet-contracts/foundry_test/modules/commons/ModuleExtraAuth.t.sol new file mode 100644 index 0000000000..3733500a42 --- /dev/null +++ b/packages/wallet/wallet-contracts/foundry_test/modules/commons/ModuleExtraAuth.t.sol @@ -0,0 +1,175 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "contracts/modules/commons/ModuleExtraAuth.sol"; + +import "foundry_test/base/AdvTest.sol"; + +contract ExtStore { + mapping(bytes32 => bool) private imageHashToIsValid; + + function setValidImageHash(bytes32 _imageHash, bool _isValid) external { + imageHashToIsValid[_imageHash] = _isValid; + } + + function isValidImage(bytes32 _imageHash) external view returns (bool) { + return imageHashToIsValid[_imageHash]; + } +} + +abstract contract ModuleAuthImp is IModuleAuth { + ExtStore private immutable EXT_STORE; + + constructor() { + EXT_STORE = new ExtStore(); + } + + function setValidImageHash(bytes32 _imageHash, bool _isValid) external { + EXT_STORE.setValidImageHash(_imageHash, _isValid); + } + + function _isValidImage(bytes32 _imageHash) internal view virtual override returns (bool) { + return EXT_STORE.isValidImage(_imageHash); + } +} + +contract ModuleExtraAuthImp2 is ModuleAuthImp, ModuleExtraAuth { + function _isValidImage(bytes32 _imageHash) internal view override(ModuleAuthImp, ModuleExtraAuth) returns (bool) { + return super._isValidImage(_imageHash); + } + + function isValidImage(bytes32 _imageHash) external view returns (bool) { + return _isValidImage(_imageHash); + } + + function _updateImageHash(bytes32) internal virtual override { + revert("not implemented"); + } +} + +contract ModuleExtraAuthTest is AdvTest { + ModuleExtraAuthImp2 private imp; + + function setUp() public { + imp = new ModuleExtraAuthImp2(); + } + + event SetExtraImageHash(bytes32 indexed _imageHash, uint256 _expiration); + + function test_shouldAcceptExtraImageHashes( + bytes32 _imageHashb, + bytes32 _imageHash1, + bytes32 _imageHash2, + uint256 _expiration1, + uint256 _expiration2 + ) external { + _expiration1 = bound(_expiration1, block.timestamp + 1, type(uint256).max); + _expiration2 = bound(_expiration2, block.timestamp + 1, type(uint256).max); + + assertFalse(imp.isValidImage(_imageHashb)); + assertFalse(imp.isValidImage(_imageHash1)); + assertFalse(imp.isValidImage(_imageHash2)); + + imp.setValidImageHash(_imageHashb, true); + assertTrue(imp.isValidImage(_imageHashb)); + assertEq(imp.isValidImage(_imageHash1), _imageHash1 == _imageHashb); + assertEq(imp.isValidImage(_imageHash2), _imageHash2 == _imageHashb); + + vm.prank(address(imp)); + vm.expectEmit(true, true, true, true, address(imp)); + emit SetExtraImageHash(_imageHash1, _expiration1); + imp.setExtraImageHash(_imageHash1, _expiration1); + + assertTrue(imp.isValidImage(_imageHash1)); + assertEq(imp.isValidImage(_imageHash2), _imageHash1 == _imageHash2 || _imageHashb == _imageHash2); + assertTrue(imp.isValidImage(_imageHashb)); + + vm.prank(address(imp)); + vm.expectEmit(true, true, true, true, address(imp)); + emit SetExtraImageHash(_imageHash2, _expiration2); + imp.setExtraImageHash(_imageHash2, _expiration2); + + assertTrue(imp.isValidImage(_imageHashb)); + assertTrue(imp.isValidImage(_imageHash1)); + assertTrue(imp.isValidImage(_imageHash2)); + } + + function test_shouldRejectExpiredImageHash( + bytes32 _imageHashb, + bytes32 _imageHash1, + bytes32 _imageHash2, + uint256 _expiration1, + uint256 _expiration2 + ) external { + _expiration1 = bound(_expiration1, block.timestamp + 1, type(uint256).max); + _expiration2 = bound(_expiration2, 0, block.timestamp); + + imp.setValidImageHash(_imageHashb, true); + + vm.prank(address(imp)); + vm.expectEmit(true, true, true, true, address(imp)); + emit SetExtraImageHash(_imageHash1, _expiration1); + imp.setExtraImageHash(_imageHash1, _expiration1); + + vm.prank(address(imp)); + vm.expectEmit(true, true, true, true, address(imp)); + emit SetExtraImageHash(_imageHash2, _expiration2); + imp.setExtraImageHash(_imageHash2, _expiration2); + + assertTrue(imp.isValidImage(_imageHashb)); + assertEq(imp.isValidImage(_imageHash1), _imageHash1 != _imageHash2 || _imageHash1 == _imageHashb); + assertEq(imp.isValidImage(_imageHash2), _imageHash2 == _imageHashb); + } + + struct SetIh { + bytes32 imageHash; + uint256 expiration; + } + + mapping(bytes32 => bool) private wasCleared; + + function test_shouldClearExtraImageHashes(bytes32 _base, SetIh[] calldata _set, bytes32[] calldata _clear) + external + { + uint256 sizeSet = mayBoundArr(_set.length); + uint256 sizeClear = mayBoundArr(_clear.length); + + imp.setValidImageHash(_base, true); + + vm.startPrank(address(imp)); + for (uint256 i = 0; i < sizeSet; i++) { + uint256 expiration = bound(_set[i].expiration, block.timestamp + 1, type(uint256).max); + imp.setExtraImageHash(_set[i].imageHash, expiration); + } + + bytes32[] memory toClear = new bytes32[](sizeClear); + for (uint256 i = 0; i < sizeClear; i++) { + toClear[i] = _clear[i]; + } + + imp.clearExtraImageHashes(toClear); + + for (uint256 i = 0; i < sizeClear; i++) { + assertEq(imp.isValidImage(_clear[i]), _clear[i] == _base); + wasCleared[_clear[i]] = true; + } + + for (uint256 i = 0; i < sizeSet; i++) { + assertEq(imp.isValidImage(_set[i].imageHash), _set[i].imageHash == _base || !wasCleared[_set[i].imageHash]); + } + } + + function test_fail_setExtraImageHash_notSelf(address _caller, bytes32 _imageHash, uint256 _expiration) external { + boundDiff(_caller, address(imp)); + vm.expectRevert(abi.encodeWithSignature("OnlySelfAuth(address,address)", _caller, address(imp))); + vm.prank(_caller); + imp.setExtraImageHash(_imageHash, _expiration); + } + + function test_fail_clearExtraImageHash_notSelf(address _caller, bytes32[] calldata _clear) external { + boundDiff(_caller, address(imp)); + vm.expectRevert(abi.encodeWithSignature("OnlySelfAuth(address,address)", _caller, address(imp))); + vm.prank(_caller); + imp.clearExtraImageHashes(_clear); + } +} diff --git a/packages/wallet/wallet-contracts/foundry_test/modules/commons/ModuleIPFS.t.sol b/packages/wallet/wallet-contracts/foundry_test/modules/commons/ModuleIPFS.t.sol new file mode 100644 index 0000000000..1210a5c2a8 --- /dev/null +++ b/packages/wallet/wallet-contracts/foundry_test/modules/commons/ModuleIPFS.t.sol @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "contracts/modules/commons/ModuleIPFS.sol"; + +import "foundry_test/base/AdvTest.sol"; + +contract ModuleIPFSTest is AdvTest { + ModuleIPFS private module; + + function setUp() public { + module = new ModuleIPFS(); + } + + function test_exposeRoot() external { + // 0xba5a3cbb592813d90eae65a3aac33e9b6dfc7be50623aa25e151fe3da06c8443 + // == + // ipfs://bafybeif2li6lwwjicpmq5ltfuovmgpu3nx6hxzigeovclykr7y62a3eeim + + // 0xb6f77d000c8791676d96aedac165dd1bb2da4a5baf78198b9f391fc76b893f46 + // == + // ipfs://bafybeifw656qadehsftw3fvo3lawlxi3wlneuw5ppamyxhzzd7dwxcj7iy + + vm.startPrank(address(module)); + + bytes32 root = 0xba5a3cbb592813d90eae65a3aac33e9b6dfc7be50623aa25e151fe3da06c8443; + module.updateIPFSRoot(root); + + assertEq(module.ipfsRootBytes32(), root); + assertEq(module.ipfsRoot(), "ipfs://bafybeif2li6lwwjicpmq5ltfuovmgpu3nx6hxzigeovclykr7y62a3eeim"); + + root = 0xb6f77d000c8791676d96aedac165dd1bb2da4a5baf78198b9f391fc76b893f46; + module.updateIPFSRoot(root); + + assertEq(module.ipfsRootBytes32(), root); + assertEq(module.ipfsRoot(), "ipfs://bafybeifw656qadehsftw3fvo3lawlxi3wlneuw5ppamyxhzzd7dwxcj7iy"); + } + + function test_fail_updateIPFSRoot_notSelf(address _notSelf) external { + boundDiff(_notSelf, address(module)); + + vm.prank(address(_notSelf)); + vm.expectRevert(abi.encodeWithSignature("OnlySelfAuth(address,address)", _notSelf, address(module))); + module.updateIPFSRoot(0x0); + } +} diff --git a/packages/wallet/wallet-contracts/foundry_test/modules/commons/ModuleStorage.t.sol b/packages/wallet/wallet-contracts/foundry_test/modules/commons/ModuleStorage.t.sol new file mode 100644 index 0000000000..4242ceaa91 --- /dev/null +++ b/packages/wallet/wallet-contracts/foundry_test/modules/commons/ModuleStorage.t.sol @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "contracts/modules/commons/ModuleStorage.sol"; + +import "foundry_test/base/AdvTest.sol"; + +contract ModuleStorageImp { + function writeBytes32(bytes32 _key, bytes32 _val) external { + ModuleStorage.writeBytes32(_key, _val); + } + + function readBytes32(bytes32 _key) external view returns (bytes32) { + return ModuleStorage.readBytes32(_key); + } + + function writeBytes32Map(bytes32 _key, bytes32 _subKey, bytes32 _val) external { + ModuleStorage.writeBytes32Map(_key, _subKey, _val); + } + + function readBytes32Map(bytes32 _key, bytes32 _subKey) external view returns (bytes32) { + return ModuleStorage.readBytes32Map(_key, _subKey); + } +} + +contract ModuleStorageTest is AdvTest { + ModuleStorageImp private imp; + + function setUp() external { + imp = new ModuleStorageImp(); + } + + function test_writeBytes32(bytes32 _key1, bytes32 _key2, bytes32 _val1, bytes32 _val2) external { + assertEq(imp.readBytes32(_key1), bytes32(0)); + assertEq(imp.readBytes32(_key2), bytes32(0)); + + bool equal = _key1 == _key2; + + imp.writeBytes32(_key1, _val1); + + bytes32 res1 = imp.readBytes32(_key1); + assertEq(res1, _val1); + assertEq(vm.load(address(imp), _key1), res1); + + imp.writeBytes32(_key2, _val2); + + bytes32 res2 = imp.readBytes32(_key2); + res1 = imp.readBytes32(_key1); + + assertEq(res1, equal ? _val2 : _val1); + assertEq(res2, _val2); + assertEq(vm.load(address(imp), _key1), res1); + assertEq(vm.load(address(imp), _key2), res2); + } + + function test_writeBytes32Map( + bytes32 _key1, + bytes32 _subkey1, + bytes32 _val1, + bytes32 _key2, + bytes32 _subkey2, + bytes32 _val2 + ) external { + bool equal = _key1 == _key2 && _subkey1 == _subkey2; + bytes32 slot1 = keccak256(abi.encode(_key1, _subkey1)); + bytes32 slot2 = keccak256(abi.encode(_key2, _subkey2)); + assertEq(slot1 == slot2, equal); + + imp.writeBytes32Map(_key1, _subkey1, _val1); + bytes32 res1 = imp.readBytes32Map(_key1, _subkey1); + assertEq(res1, _val1); + assertEq(vm.load(address(imp), slot1), res1); + + imp.writeBytes32Map(_key2, _subkey2, _val2); + + bytes32 res2 = imp.readBytes32Map(_key2, _subkey2); + res1 = imp.readBytes32Map(_key1, _subkey1); + + assertEq(res1, equal ? _val2 : _val1); + assertEq(res2, _val2); + assertEq(vm.load(address(imp), slot1), res1); + assertEq(vm.load(address(imp), slot2), res2); + } +} diff --git a/packages/wallet/wallet-contracts/foundry_test/modules/commons/submodules/auth/SequenceBaseSig.t.sol b/packages/wallet/wallet-contracts/foundry_test/modules/commons/submodules/auth/SequenceBaseSig.t.sol new file mode 100644 index 0000000000..aa163bd3af --- /dev/null +++ b/packages/wallet/wallet-contracts/foundry_test/modules/commons/submodules/auth/SequenceBaseSig.t.sol @@ -0,0 +1,325 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "contracts/modules/commons/submodules/auth/SequenceBaseSig.sol"; + +import "foundry_test/base/AdvTest.sol"; + +contract SequenceBaseSigImp { + function subdigest(bytes32 _digest) external view returns (bytes32) { + return SequenceBaseSig.subdigest(_digest); + } + + function leafForAddressAndWeight(address _addr, uint96 _weight) external pure returns (bytes32) { + return SequenceBaseSig._leafForAddressAndWeight(_addr, _weight); + } + + function recoverBranch(bytes32 _digest, bytes calldata _signature) + external + view + returns (uint256 weight, bytes32 root) + { + return SequenceBaseSig.recoverBranch(_digest, _signature); + } + + function recover(bytes32 _subdigest, bytes calldata _signature) + external + view + returns (uint256 threshold, uint256 weight, bytes32 imageHash, uint256 checkpoint) + { + return SequenceBaseSig.recover(_subdigest, _signature); + } +} + +contract SequenceBaseSigTest is AdvTest { + SequenceBaseSigImp private lib; + + uint8 private constant FLAG_SIGNATURE = 0; + uint8 private constant FLAG_ADDRESS = 1; + uint8 private constant FLAG_DYNAMIC_SIGNATURE = 2; + uint8 private constant FLAG_NODE = 3; + uint8 private constant FLAG_BRANCH = 4; + uint8 private constant FLAG_SUBDIGEST = 5; + uint8 private constant FLAG_NESTED = 6; + + function setUp() public { + lib = new SequenceBaseSigImp(); + } + + function test_subdigest(bytes32 _digest, uint256 _chainId) external { + _chainId = bound(_chainId, 0, type(uint64).max); + + bytes32 expected = keccak256(abi.encodePacked("\x19\x01", _chainId, address(lib), _digest)); + + vm.chainId(_chainId); + bytes32 actual = lib.subdigest(_digest); + assertEq(actual, expected); + } + + function test_subdigest_Fuzz_ChainId(bytes32 _digest, uint256 _chainId1, uint256 _chainId2) external { + _chainId1 = bound(_chainId1, 0, type(uint64).max); + _chainId2 = bound(_chainId2, 0, type(uint64).max); + + vm.chainId(_chainId1); + bytes32 subdigest1 = lib.subdigest(_digest); + + vm.chainId(_chainId2); + bytes32 subdigest2 = lib.subdigest(_digest); + + assertTrue(subdigest1 != subdigest2 || _chainId1 == _chainId2); + } + + function test_subdigest_Fuzz_Digest(bytes32 _digest1, bytes32 _digest2) external { + bytes32 subdigest1 = lib.subdigest(_digest1); + bytes32 subdigest2 = lib.subdigest(_digest2); + + assertTrue(subdigest1 != subdigest2 || _digest1 == _digest2); + } + + function test_subdigest_Fuzz_Address(bytes32 _digest, address _addr1, address _addr2) external { + boundNoSys(_addr1); + boundNoSys(_addr2); + + vm.etch(_addr1, address(lib).code); + vm.etch(_addr2, address(lib).code); + + bytes32 subdigest1 = SequenceBaseSigImp(_addr1).subdigest(_digest); + bytes32 subdigest2 = SequenceBaseSigImp(_addr2).subdigest(_digest); + + assertTrue(subdigest1 != subdigest2 || _addr1 == _addr2); + } + + function test_leafForAddressAndWeight(address _addr, uint96 _weight) external { + bytes32 expected = abi.decode(abi.encodePacked(_weight, _addr), (bytes32)); + bytes32 actual = lib.leafForAddressAndWeight(_addr, _weight); + assertEq(expected, actual); + } + + function test_leafForAddressAndWeight_fuzz(address _addr1, uint96 _weight1, address _addr2, uint96 _weight2) + external + { + bytes32 encoded1 = lib.leafForAddressAndWeight(_addr1, _weight1); + bytes32 encoded2 = lib.leafForAddressAndWeight(_addr2, _weight2); + assertEq(encoded1 == encoded2, _addr1 == _addr2 && _weight1 == _weight2); + } + + function test_leafForHardcodedSubdigest_fuzz(bytes32 _subdigest1, bytes32 _subdigest2) external { + bytes32 encoded1 = SequenceBaseSig._leafForHardcodedSubdigest(_subdigest1); + bytes32 encoded2 = SequenceBaseSig._leafForHardcodedSubdigest(_subdigest2); + assertEq(encoded1 == encoded2, _subdigest1 == _subdigest2); + } + + function test_leafForHardcodedSubdigest_fuzz_addr(address _addr, uint96 _weight, bytes32 _subdigest) external { + bytes32 encoded1 = SequenceBaseSig._leafForHardcodedSubdigest(_subdigest); + bytes32 encoded2 = SequenceBaseSig._leafForAddressAndWeight(_addr, _weight); + assertTrue(encoded1 != encoded2); + } + + function test_leafForNested_fuzz( + bytes32 _node1, + uint256 _threshold1, + uint256 _weight1, + bytes32 _node2, + uint256 _threshold2, + uint256 _weight2 + ) external { + bytes32 encoded1 = SequenceBaseSig._leafForNested(_node1, _threshold1, _weight1); + bytes32 encoded2 = SequenceBaseSig._leafForNested(_node2, _threshold2, _weight2); + assertEq(encoded1 == encoded2, _node1 == _node2 && _threshold1 == _threshold2 && _weight1 == _weight2); + } + + function test_leafForNested_fuzz_addr( + address _addr, + uint96 _weight, + bytes32 _node, + uint256 _threshold, + uint256 _nodeWeight + ) external { + bytes32 encoded1 = SequenceBaseSig._leafForNested(_node, _threshold, _nodeWeight); + bytes32 encoded2 = SequenceBaseSig._leafForAddressAndWeight(_addr, _weight); + assertTrue(encoded1 != encoded2); + } + + function test_leafForNested_fuzz_subdigest(bytes32 _subdigest, bytes32 _node, uint256 _threshold, uint256 _weight) + external + { + bytes32 encoded1 = SequenceBaseSig._leafForNested(_node, _threshold, _weight); + bytes32 encoded2 = SequenceBaseSig._leafForHardcodedSubdigest(_subdigest); + assertTrue(encoded1 != encoded2); + } + + function test_recoverBranch_Addresses(bytes32 _subdigest, bytes32 _seed, address[] calldata _addresses) external { + bytes memory signature; + bytes32 root; + + uint256 size = mayBoundArr(_addresses.length); + for (uint256 i = 0; i < size; i++) { + uint8 randomWeight = + uint8(bound(uint256(keccak256(abi.encode(_addresses[i], i, _seed))), 0, type(uint8).max)); + + signature = abi.encodePacked(signature, FLAG_ADDRESS, randomWeight, _addresses[i]); + bytes32 node = lib.leafForAddressAndWeight(_addresses[i], randomWeight); + root = root != bytes32(0) ? keccak256(abi.encodePacked(root, node)) : node; + } + + (uint256 recoveredWeight, bytes32 recoveredRoot) = lib.recoverBranch(_subdigest, signature); + assertEq(recoveredRoot, root); + assertEq(recoveredWeight, 0); + } + + function test_recoverBranch_Nodes(bytes32 _subdigest, bytes32[] calldata _nodes) external { + bytes memory signature; + bytes32 root; + + uint256 size = mayBoundArr(_nodes.length); + for (uint256 i = 0; i < size; i++) { + signature = abi.encodePacked(signature, FLAG_NODE, _nodes[i]); + root = root != bytes32(0) ? keccak256(abi.encodePacked(root, _nodes[i])) : _nodes[i]; + } + + (uint256 recoveredWeight, bytes32 recoveredRoot) = lib.recoverBranch(_subdigest, signature); + assertEq(recoveredRoot, root); + assertEq(recoveredWeight, 0); + } + + function test_recoverBranch_Signatures(bytes32 _subdigest, bytes32 _seed, uint256[] memory _pks) external { + bytes memory signature; + bytes32 root; + uint256 total; + + uint256 size = mayBoundArr(_pks.length); + for (uint256 i = 0; i < size; i++) { + _pks[i] = boundPk(_pks[i]); + + uint8 randomWeight = uint8(bound(uint256(keccak256(abi.encode(_pks[i], i, _seed))), 0, type(uint8).max)); + address addr = vm.addr(_pks[i]); + + // Determine if the pk will sign, dynamic sign or just sit as addr + uint256 op = bound(uint256(keccak256(abi.encode(_pks[i], i, _seed, 2))), 0, 2); + + if (op == 0) { + signature = abi.encodePacked(signature, FLAG_ADDRESS, randomWeight, addr); + } else { + bytes memory sigpart = signAndPack(_pks[i], _subdigest, 1); + + total += randomWeight; + + if (op == 1) { + signature = abi.encodePacked(signature, FLAG_SIGNATURE, randomWeight, sigpart); + } else { + signature = abi.encodePacked( + signature, FLAG_DYNAMIC_SIGNATURE, randomWeight, addr, uint24(sigpart.length), sigpart + ); + } + } + + bytes32 node = lib.leafForAddressAndWeight(addr, randomWeight); + root = root != bytes32(0) ? keccak256(abi.encodePacked(root, node)) : node; + } + + (uint256 recoveredWeight, bytes32 recoveredRoot) = lib.recoverBranch(_subdigest, signature); + assertEq(recoveredRoot, root); + assertEq(recoveredWeight, total); + } + + function test_recoverBranch_Branches(bytes32 _subdigest, bytes32 _seed, uint256[] memory _pks) external { + bytes memory signature; + bytes32 root; + uint256 total; + + // NOTICE: too much branching will lead to stack overflow + uint256 size = bound(_pks.length, 0, 32); + + for (uint256 i = 0; i < size; i++) { + if (i != 0) { + signature = abi.encodePacked(FLAG_BRANCH, uint24(signature.length), signature); + } + + _pks[i] = boundPk(_pks[i]); + + uint8 randomWeight = uint8(bound(uint256(keccak256(abi.encode(_pks[i], i, _seed))), 0, type(uint8).max)); + address addr = vm.addr(_pks[i]); + + // Determine if the pk will sign, dynamic sign or just sit as addr + uint256 op = bound(uint256(keccak256(abi.encode(_pks[i], i, _seed, 2))), 0, 2); + + if (op == 0) { + signature = abi.encodePacked(FLAG_ADDRESS, randomWeight, addr, signature); + } else { + bytes memory sigpart = signAndPack(_pks[i], _subdigest, 1); + + total += randomWeight; + + if (op == 1) { + signature = abi.encodePacked(FLAG_SIGNATURE, randomWeight, sigpart, signature); + } else { + signature = abi.encodePacked( + FLAG_DYNAMIC_SIGNATURE, randomWeight, addr, uint24(sigpart.length), sigpart, signature + ); + } + } + + bytes32 node = lib.leafForAddressAndWeight(addr, randomWeight); + // Hash in reverse order requires branching, root/node -> node/root + root = root != bytes32(0) ? keccak256(abi.encodePacked(node, root)) : node; + } + + (uint256 recoveredWeight, bytes32 recoveredRoot) = lib.recoverBranch(_subdigest, signature); + assertEq(recoveredRoot, root); + assertEq(recoveredWeight, total); + } + + function test_recoverBranch_Empty(bytes32 _hash) external { + (uint256 weight1, bytes32 root1) = lib.recoverBranch(_hash, abi.encodePacked(FLAG_NODE, bytes32(0))); + (uint256 weight2, bytes32 root2) = lib.recoverBranch(_hash, bytes("")); + + assertEq(weight2, 0); + assertEq(root2, bytes32(0)); + assertEq(weight1, weight2); + assertEq(root1, root2); + } + + function test_recoverBranch_Fail_InvalidFlag(uint8 _flag, bytes23 _hash, bytes calldata _sufix) external { + uint8( + boundDiff( + _flag, + FLAG_SIGNATURE, + FLAG_ADDRESS, + FLAG_DYNAMIC_SIGNATURE, + FLAG_NODE, + FLAG_BRANCH, + FLAG_SUBDIGEST, + FLAG_NESTED + ) + ); + + vm.expectRevert(abi.encodeWithSignature("InvalidSignatureFlag(uint256)", _flag)); + lib.recoverBranch(_hash, abi.encodePacked(_flag, _sufix)); + } + + function test_recover(bytes32 _subdigest, uint256 _pk, uint32 _checkpoint, uint16 _threshold, uint8 _weight) + external + { + _pk = boundPk(_pk); + + bytes memory signature = signAndPack(_pk, _subdigest, 1); + address addr = vm.addr(_pk); + + bytes32 expectImageHash = abi.decode(abi.encodePacked(uint96(_weight), addr), (bytes32)); + expectImageHash = keccak256(abi.encodePacked(expectImageHash, uint256(_threshold))); + expectImageHash = keccak256(abi.encodePacked(expectImageHash, uint256(_checkpoint))); + + bytes memory encoded = abi.encodePacked(_threshold, _checkpoint, FLAG_SIGNATURE, _weight, signature); + (uint256 threshold, uint256 weight, bytes32 imageHash, uint256 checkpoint) = lib.recover(_subdigest, encoded); + + assertEq(weight, _weight); + assertEq(threshold, _threshold); + assertEq(imageHash, expectImageHash); + assertEq(checkpoint, _checkpoint); + } + + function test_recover_Fail_EmptySignature(bytes32 _subdigest) external { + vm.expectRevert(); + lib.recover(_subdigest, bytes("")); + } +} diff --git a/packages/wallet/wallet-contracts/foundry_test/modules/commons/submodules/auth/SequenceChainedSig.t.sol b/packages/wallet/wallet-contracts/foundry_test/modules/commons/submodules/auth/SequenceChainedSig.t.sol new file mode 100644 index 0000000000..85ef23f14a --- /dev/null +++ b/packages/wallet/wallet-contracts/foundry_test/modules/commons/submodules/auth/SequenceChainedSig.t.sol @@ -0,0 +1,276 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "contracts/modules/commons/submodules/auth/SequenceChainedSig.sol"; + +import "foundry_test/base/AdvTest.sol"; + +contract SequenceChainedSigImp is SequenceChainedSig { + function pchainedRecover(bytes32 _digest, bytes calldata _signature) + external + view + returns (uint256 threshold, uint256 weight, bytes32 imageHash, bytes32 subdigest, uint256 checkpoint) + { + return chainedRecover(_digest, _signature); + } + + struct MockedSignature { + bool exists; + uint256 threshold; + uint256 weight; + bytes32 imageHash; + bytes32 subdigest; + uint256 checkpoint; + } + + mapping(bytes32 => mapping(bytes => MockedSignature)) public mockedSignatures; + + function isMocked(bytes32 _digest, bytes calldata _signature) external view returns (bool) { + return mockedSignatures[_digest][_signature].exists; + } + + function mockSignature( + bytes32 _digest, + bytes calldata _signature, + uint256 _threshold, + uint256 _weight, + bytes32 _imageHash, + bytes32 _subdigest, + uint256 _checkpoint + ) external { + MockedSignature memory sig; + + sig.exists = true; + sig.threshold = _threshold; + sig.weight = _weight; + sig.imageHash = _imageHash; + sig.subdigest = _subdigest; + sig.checkpoint = _checkpoint; + + mockedSignatures[_digest][_signature] = sig; + } + + function signatureRecovery(bytes32 _digest, bytes calldata _signature) + public + view + override + returns (uint256 threshold, uint256 weight, bytes32 imageHash, bytes32 subdigest, uint256 checkpoint) + { + if (mockedSignatures[_digest][_signature].exists) { + return ( + mockedSignatures[_digest][_signature].threshold, + mockedSignatures[_digest][_signature].weight, + mockedSignatures[_digest][_signature].imageHash, + mockedSignatures[_digest][_signature].subdigest, + mockedSignatures[_digest][_signature].checkpoint + ); + } else { + revert("invalid mocked signature"); + } + } + + function hashSetImageHashStruct(bytes32 _imageHash) external pure returns (bytes32) { + return _hashSetImageHashStruct(_imageHash); + } + + function _signatureValidation(bytes32, bytes calldata) internal pure override returns (bool, bytes32) { + revert("not implemented"); + } + + function _isValidImage(bytes32) internal pure override returns (bool) { + revert("not implemented"); + } + + function updateImageHash(bytes32) external pure override { + revert("not implemented"); + } + + function _updateImageHash(bytes32) internal pure override { + revert("not implemented"); + } +} + +contract SequenceChainedSigTest is AdvTest { + SequenceChainedSigImp private lib; + + function setUp() public { + lib = new SequenceChainedSigImp(); + } + + struct HashAndSignature { + bytes32 imageHash; + uint256 threshold; + uint256 weight; + uint56 checkpointDelta; + bytes signature; + } + + function test_chainedRecover(uint8 _prefix, bytes32 _digest, HashAndSignature[] memory _steps) external { + vm.assume(_steps.length > 0); + + bytes memory signature = abi.encodePacked(_prefix); + + uint256 size = boundDiff(mayBoundArr(_steps.length), 0); + + bytes32 nextDigest = _digest; + uint32 checkpoint = type(uint32).max; + + for (uint256 i = 0; i < size; i++) { + _steps[i].weight = bound(_steps[i].weight, _steps[i].threshold, type(uint256).max); + + if (i != 0) { + checkpoint -= uint32(bound(_steps[i].checkpointDelta, 1, type(uint24).max)); + } + + if (lib.isMocked(nextDigest, _steps[i].signature)) { + _steps[i].signature = abi.encodePacked(_steps[i].signature, _steps[i].imageHash); + } + + lib.mockSignature( + nextDigest, + _steps[i].signature, + _steps[i].threshold, + _steps[i].weight, + _steps[i].imageHash, + i == 0 ? _digest : nextDigest, + checkpoint + ); + + nextDigest = lib.hashSetImageHashStruct(_steps[i].imageHash); + signature = abi.encodePacked(signature, uint24(_steps[i].signature.length), _steps[i].signature); + } + + (uint256 threshold, uint256 weight, bytes32 imageHash, bytes32 subdigest, uint256 rcheckpoint) = + lib.pchainedRecover(_digest, signature); + + assertEq(imageHash, _steps[size - 1].imageHash); + assertEq(threshold, _steps[size - 1].threshold); + assertEq(weight, _steps[size - 1].weight); + assertEq(subdigest, _digest); + assertEq(rcheckpoint, checkpoint); + } + + function test_chainedRecover_Fail_LowWeight( + uint8 _prefix, + uint256 _badi, + bytes32 _digest, + HashAndSignature[] memory _steps + ) external { + vm.assume(_steps.length > 0); + + bytes memory signature = abi.encodePacked(_prefix); + + uint256 size = boundDiff(mayBoundArr(_steps.length), 0); + _badi = bound(_badi, 0, size - 1); + + bytes32 nextDigest = _digest; + uint64 checkpoint = type(uint64).max; + + for (uint256 i = 0; i < size; i++) { + if (i == _badi) { + _steps[i].threshold = bound(_steps[i].threshold, 1, type(uint256).max); + _steps[i].weight = bound(_steps[i].weight, 0, _steps[i].threshold - 1); + } else { + _steps[i].weight = bound(_steps[i].weight, _steps[i].threshold, type(uint256).max); + } + + if (i != 0) { + checkpoint -= uint64(bound(_steps[i].checkpointDelta, 1, type(uint56).max)); + } + + if (lib.isMocked(nextDigest, _steps[i].signature)) { + _steps[i].signature = abi.encodePacked(_steps[i].signature, _steps[i].imageHash); + } + + lib.mockSignature( + nextDigest, + _steps[i].signature, + _steps[i].threshold, + _steps[i].weight, + _steps[i].imageHash, + i == 0 ? _digest : nextDigest, + checkpoint + ); + + nextDigest = lib.hashSetImageHashStruct(_steps[i].imageHash); + signature = abi.encodePacked(signature, uint24(_steps[i].signature.length), _steps[i].signature); + } + + vm.expectRevert( + abi.encodeWithSignature( + "LowWeightChainedSignature(bytes,uint256,uint256)", + _steps[_badi].signature, + _steps[_badi].threshold, + _steps[_badi].weight + ) + ); + lib.pchainedRecover(_digest, signature); + } + + function test_chainedRecover_Fail_Checkpoint( + uint8 _prefix, + uint256 _badi, + bytes32 _digest, + HashAndSignature[] memory _steps + ) external { + vm.assume(_steps.length >= 1); + + bytes memory signature = abi.encodePacked(_prefix); + + uint256 size = boundDiff(mayBoundArr(_steps.length), 0); + _badi = bound(_badi, 0, size - 1); + + bytes32 nextDigest = _digest; + uint64 checkpoint = type(uint64).max; + + uint64 badCheckpoint; + uint64 prevToBadCheckpoint; + + for (uint256 i = 0; i < size; i++) { + _steps[i].weight = bound(_steps[i].weight, _steps[i].threshold, type(uint256).max); + + if (i != 0) { + if (_badi == i) { + prevToBadCheckpoint = checkpoint; + checkpoint = + uint64(bound(uint256(checkpoint) + _steps[i].checkpointDelta, checkpoint, type(uint64).max)); + badCheckpoint = checkpoint; + } else { + checkpoint -= uint64(bound(_steps[i].checkpointDelta, 1, type(uint56).max)); + } + } + + if (lib.isMocked(nextDigest, _steps[i].signature)) { + _steps[i].signature = abi.encodePacked(_steps[i].signature, _steps[i].imageHash); + } + + lib.mockSignature( + nextDigest, + _steps[i].signature, + _steps[i].threshold, + _steps[i].weight, + _steps[i].imageHash, + i == 0 ? _digest : nextDigest, + checkpoint + ); + + nextDigest = lib.hashSetImageHashStruct(_steps[i].imageHash); + signature = abi.encodePacked(signature, uint24(_steps[i].signature.length), _steps[i].signature); + } + + if (_badi != 0) { + vm.expectRevert( + abi.encodeWithSignature( + "WrongChainedCheckpointOrder(uint256,uint256)", badCheckpoint, prevToBadCheckpoint + ) + ); + } + + lib.pchainedRecover(_digest, signature); + } + + function test_chainedRecover_Fail_EmptySignature(bytes32 _digest) external { + vm.expectRevert(); + lib.pchainedRecover(_digest, bytes("")); + } +} diff --git a/packages/wallet/wallet-contracts/foundry_test/modules/commons/submodules/auth/SequenceDynamicSig.t.sol b/packages/wallet/wallet-contracts/foundry_test/modules/commons/submodules/auth/SequenceDynamicSig.t.sol new file mode 100644 index 0000000000..9651f4eb6f --- /dev/null +++ b/packages/wallet/wallet-contracts/foundry_test/modules/commons/submodules/auth/SequenceDynamicSig.t.sol @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "contracts/modules/commons/submodules/auth/SequenceBaseSig.sol"; +import "contracts/modules/commons/submodules/auth/SequenceDynamicSig.sol"; + +import "foundry_test/base/AdvTest.sol"; + +contract SequenceDynamicSigImp { + function recover(bytes32 _subdigest, bytes calldata _signature) + external + view + returns (uint256, uint256, bytes32, uint256) + { + return SequenceDynamicSig.recover(_subdigest, _signature); + } + + function recoverBase(bytes32 _subdigest, bytes calldata _signature) + external + view + returns (uint256 threshold, uint256 weight, bytes32 imageHash, uint256) + { + return SequenceBaseSig.recover(_subdigest, _signature); + } +} + +contract SequenceDynamicSigTest is AdvTest { + SequenceDynamicSigImp private lib; + + function setUp() public { + lib = new SequenceDynamicSigImp(); + } + + function test_recover_ignoreFirstByte( + uint8 _first, + bytes32 _subdigest, + uint256 _pk, + uint16 _threshold, + uint32 _checkpoint, + uint8 _weight + ) external { + _pk = boundPk(_pk); + + bytes memory encoded = + abi.encodePacked(_threshold, _checkpoint, uint8(0), _weight, signAndPack(_pk, _subdigest, 1)); + + (uint256 threshold1, uint256 weight1, bytes32 imageHash1, uint256 checkpoint1) = + lib.recover(_subdigest, abi.encodePacked(_first, encoded)); + (uint256 threshold2, uint256 weight2, bytes32 imageHash2, uint256 checkpoint2) = + lib.recoverBase(_subdigest, encoded); + + assertEq(threshold1, threshold2); + assertEq(weight1, weight2); + assertEq(imageHash1, imageHash2); + assertEq(checkpoint1, checkpoint2); + } +} diff --git a/packages/wallet/wallet-contracts/foundry_test/modules/commons/submodules/auth/SequenceNoChainIdSig.t.sol b/packages/wallet/wallet-contracts/foundry_test/modules/commons/submodules/auth/SequenceNoChainIdSig.t.sol new file mode 100644 index 0000000000..34534385af --- /dev/null +++ b/packages/wallet/wallet-contracts/foundry_test/modules/commons/submodules/auth/SequenceNoChainIdSig.t.sol @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "contracts/modules/commons/submodules/auth/SequenceNoChainIdSig.sol"; + +import "foundry_test/base/AdvTest.sol"; + +contract SequenceNoChainIdSigImp { + function subdigest(bytes32 _digest) external view returns (bytes32) { + return SequenceNoChainIdSig.subdigest(_digest); + } +} + +contract SequenceNoChainIdSigTest is AdvTest { + SequenceNoChainIdSigImp private lib; + + function setUp() public { + lib = new SequenceNoChainIdSigImp(); + } + + function test_subdigest_DiffDigest(bytes32 _digest1, bytes32 _digest2) external { + bytes32 res1 = lib.subdigest(_digest1); + bytes32 res2 = lib.subdigest(_digest2); + assertTrue(res1 != res2 || _digest1 == _digest2); + } + + function test_subdigest_DiffAddress(bytes32 _digest, address _addr1, address _addr2) external { + boundNoContract(boundNoSys(_addr1)); + boundNoContract(boundNoSys(_addr2)); + + vm.etch(_addr1, address(lib).code); + vm.etch(_addr2, address(lib).code); + + bytes32 res1 = SequenceNoChainIdSigImp(_addr1).subdigest(_digest); + bytes32 res2 = SequenceNoChainIdSigImp(_addr2).subdigest(_digest); + + assertTrue(res1 != res2 || _addr1 == _addr2); + } + + function test_subdigest_DiffChainId(bytes32 _digest, uint256 _chainId1, uint256 _chainId2) external { + _chainId1 = bound(_chainId1, 0, type(uint64).max); + _chainId2 = bound(_chainId2, 0, type(uint64).max); + + vm.chainId(_chainId1); + bytes32 res1 = lib.subdigest(_digest); + vm.chainId(_chainId2); + bytes32 res2 = lib.subdigest(_digest); + + assertTrue(res1 == res2); + } +} diff --git a/packages/wallet/wallet-contracts/foundry_test/modules/commons/submodules/nonce/SubModuleNonce.t.sol b/packages/wallet/wallet-contracts/foundry_test/modules/commons/submodules/nonce/SubModuleNonce.t.sol new file mode 100644 index 0000000000..4bc6a900f1 --- /dev/null +++ b/packages/wallet/wallet-contracts/foundry_test/modules/commons/submodules/nonce/SubModuleNonce.t.sol @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "contracts/modules/commons/submodules/nonce/SubModuleNonce.sol"; + +import "foundry_test/base/AdvTest.sol"; + +contract SubModuleNonceTest is AdvTest { + function test_decodeNonce(uint160 _space, uint96 _nonce) external { + uint256 encoded = abi.decode(abi.encodePacked(_space, _nonce), (uint256)); + (uint256 space2, uint256 nonce2) = SubModuleNonce.decodeNonce(encoded); + + assertEq(space2, _space); + assertEq(nonce2, _nonce); + } +} diff --git a/packages/wallet/wallet-contracts/foundry_test/modules/utils/L2CompressorEncoder.sol b/packages/wallet/wallet-contracts/foundry_test/modules/utils/L2CompressorEncoder.sol new file mode 100644 index 0000000000..bc94e84b65 --- /dev/null +++ b/packages/wallet/wallet-contracts/foundry_test/modules/utils/L2CompressorEncoder.sol @@ -0,0 +1,393 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +function requiredBytesFor(bytes32 value) pure returns (uint8) { + return requiredBytesFor(uint256(value)); +} + +function requiredBytesFor(uint256 value) pure returns (uint8) { + if (value <= type(uint8).max) { + return 1; + } else if (value <= type(uint16).max) { + return 2; + } else if (value <= type(uint24).max) { + return 3; + } else if (value <= type(uint32).max) { + return 4; + } else if (value <= type(uint40).max) { + return 5; + } else if (value <= type(uint48).max) { + return 6; + } else if (value <= type(uint56).max) { + return 7; + } else if (value <= type(uint64).max) { + return 8; + } else if (value <= type(uint72).max) { + return 9; + } else if (value <= type(uint80).max) { + return 10; + } else if (value <= type(uint88).max) { + return 11; + } else if (value <= type(uint96).max) { + return 12; + } else if (value <= type(uint104).max) { + return 13; + } else if (value <= type(uint112).max) { + return 14; + } else if (value <= type(uint120).max) { + return 15; + } else if (value <= type(uint128).max) { + return 16; + } else if (value <= type(uint136).max) { + return 17; + } else if (value <= type(uint144).max) { + return 18; + } else if (value <= type(uint152).max) { + return 19; + } else if (value <= type(uint160).max) { + return 20; + } else if (value <= type(uint168).max) { + return 21; + } else if (value <= type(uint176).max) { + return 22; + } else if (value <= type(uint184).max) { + return 23; + } else if (value <= type(uint192).max) { + return 24; + } else if (value <= type(uint200).max) { + return 25; + } else if (value <= type(uint208).max) { + return 26; + } else if (value <= type(uint216).max) { + return 27; + } else if (value <= type(uint224).max) { + return 28; + } else if (value <= type(uint232).max) { + return 29; + } else if (value <= type(uint240).max) { + return 30; + } else if (value <= type(uint248).max) { + return 31; + } + + return 32; +} + +function packToBytes(bytes32 value, uint256 b) pure returns (bytes memory) { + return packToBytes(uint256(value), b); +} + +function packToBytes(uint256 value, uint256 b) pure returns (bytes memory) { + if (b == 1) { + return abi.encodePacked(uint8(value)); + } else if (b == 2) { + return abi.encodePacked(uint16(value)); + } else if (b == 3) { + return abi.encodePacked(uint24(value)); + } else if (b == 4) { + return abi.encodePacked(uint32(value)); + } else if (b == 5) { + return abi.encodePacked(uint40(value)); + } else if (b == 6) { + return abi.encodePacked(uint48(value)); + } else if (b == 7) { + return abi.encodePacked(uint56(value)); + } else if (b == 8) { + return abi.encodePacked(uint64(value)); + } else if (b == 9) { + return abi.encodePacked(uint72(value)); + } else if (b == 10) { + return abi.encodePacked(uint80(value)); + } else if (b == 11) { + return abi.encodePacked(uint88(value)); + } else if (b == 12) { + return abi.encodePacked(uint96(value)); + } else if (b == 13) { + return abi.encodePacked(uint104(value)); + } else if (b == 14) { + return abi.encodePacked(uint112(value)); + } else if (b == 15) { + return abi.encodePacked(uint120(value)); + } else if (b == 16) { + return abi.encodePacked(uint128(value)); + } else if (b == 17) { + return abi.encodePacked(uint136(value)); + } else if (b == 18) { + return abi.encodePacked(uint144(value)); + } else if (b == 19) { + return abi.encodePacked(uint152(value)); + } else if (b == 20) { + return abi.encodePacked(uint160(value)); + } else if (b == 21) { + return abi.encodePacked(uint168(value)); + } else if (b == 22) { + return abi.encodePacked(uint176(value)); + } else if (b == 23) { + return abi.encodePacked(uint184(value)); + } else if (b == 24) { + return abi.encodePacked(uint192(value)); + } else if (b == 25) { + return abi.encodePacked(uint200(value)); + } else if (b == 26) { + return abi.encodePacked(uint208(value)); + } else if (b == 27) { + return abi.encodePacked(uint216(value)); + } else if (b == 28) { + return abi.encodePacked(uint224(value)); + } else if (b == 29) { + return abi.encodePacked(uint232(value)); + } else if (b == 30) { + return abi.encodePacked(uint240(value)); + } else if (b == 31) { + return abi.encodePacked(uint248(value)); + } else if (b == 32) { + return abi.encodePacked(uint256(value)); + } else { + revert("Invalid number of bytes"); + } +} + +function encodeWord(bytes32 _value) pure returns (bytes memory) { + return encodeWord(uint256(_value)); +} + +function encodeWord(uint256 _value) pure returns (bytes memory) { + uint256 highestFlag = 0x4f; + + if (_value < type(uint8).max - highestFlag) { + return abi.encodePacked(uint8(_value + highestFlag + 1)); + } + + uint8 b = requiredBytesFor(_value); + return abi.encodePacked(b, packToBytes(_value, b)); +} + +function build_flag(bool _delegateCall, bool _revertOnError, bool _hasGasLimit, bool _hasValue, bool _hasData) + pure + returns (uint8) +{ + uint8 res = 0; + + if (_delegateCall) { + res |= 128; + } + + if (_revertOnError) { + res |= 64; + } + + if (_hasGasLimit) { + res |= 32; + } + + if (_hasValue) { + res |= 16; + } + + // Hasdata uses first bit + if (_hasData) { + res |= 1; + } + + return res; +} + +function encode_raw_address(address _addr) pure returns (bytes memory) { + return encodeWord(uint256(uint160(_addr))); +} + +function encode_bytes_n(bytes memory _data) pure returns (bytes memory) { + return abi.encodePacked(uint8(0x2b), encodeWord(_data.length), _data); +} + +function encode_abi_call(bytes4 _selector) pure returns (bytes memory) { + return abi.encodePacked(uint8(0x2d), uint8(0x00), _selector); +} + +function encode_abi_call(bytes4 _selector, bytes32 _v1) pure returns (bytes memory) { + return abi.encodePacked(uint8(0x2e), uint8(0x00), _selector, encodeWord(_v1)); +} + +function encode_abi_call(bytes4 _selector, bytes32 _v1, bytes32 _v2) pure returns (bytes memory) { + return abi.encodePacked(uint8(0x2f), uint8(0x00), _selector, encodeWord(_v1), encodeWord(_v2)); +} + +function encode_abi_call(bytes4 _selector, bytes32 _v1, bytes32 _v2, bytes32 _v3) pure returns (bytes memory) { + return abi.encodePacked(uint8(0x30), uint8(0x00), _selector, encodeWord(_v1), encodeWord(_v2), encodeWord(_v3)); +} + +function encode_abi_call(bytes4 _selector, bytes32 _v1, bytes32 _v2, bytes32 _v3, bytes32 _v4) + pure + returns (bytes memory) +{ + return abi.encodePacked( + uint8(0x31), uint8(0x00), _selector, encodeWord(_v1), encodeWord(_v2), encodeWord(_v3), encodeWord(_v4) + ); +} + +function encode_abi_call(bytes4 _selector, bytes32 _v1, bytes32 _v2, bytes32 _v3, bytes32 _v4, bytes32 _v5) + pure + returns (bytes memory) +{ + return abi.encodePacked( + uint8(0x32), + uint8(0x00), + _selector, + encodeWord(_v1), + encodeWord(_v2), + encodeWord(_v3), + encodeWord(_v4), + encodeWord(_v5) + ); +} + +function encode_abi_call( + bytes4 _selector, + bytes32 _v1, + bytes32 _v2, + bytes32 _v3, + bytes32 _v4, + bytes32 _v5, + bytes32 _v6 +) pure returns (bytes memory) { + return abi.encodePacked( + uint8(0x33), + uint8(0x00), + _selector, + encodeWord(_v1), + encodeWord(_v2), + encodeWord(_v3), + encodeWord(_v4), + encodeWord(_v5), + encodeWord(_v6) + ); +} + +function encode_nested(bytes memory _a, bytes memory _b) pure returns (bytes memory) { + return abi.encodePacked(uint8(0x34), uint8(2), _a, _b); +} + +function encode_nested(bytes memory _a, bytes memory _b, bytes memory _c) pure returns (bytes memory) { + return abi.encodePacked(uint8(0x34), uint8(3), _a, _b, _c); +} + +function encode_nested(bytes[] memory _bs) pure returns (bytes memory) { + bytes memory res = abi.encodePacked(uint8(0x35), uint16(_bs.length)); + for (uint256 i = 0; i < _bs.length; i++) { + res = abi.encodePacked(res, _bs[i]); + } + return res; +} + +function encode_eoa_signature(uint8 _weight, bytes memory _sig) pure returns (bytes memory) { + if (_sig.length != 66) { + revert("Invalid signature length"); + } + + if (_weight != 0 && _weight <= 4) { + return abi.encodePacked(uint8(0x36 + _weight), _sig); + } + + return abi.encodePacked(uint8(0x36), uint8(_weight), _sig); +} + +function encode_address(uint8 _weight, address _addr) pure returns (bytes memory) { + if (_weight != 0 && _weight <= 4) { + return abi.encodePacked(uint8(0x3b + _weight), encodeWord(uint256(uint160(_addr)))); + } + + return abi.encodePacked(uint8(0x3b), uint8(_weight), encodeWord(uint256(uint160(_addr)))); +} + +function encode_node(bytes32 _node) pure returns (bytes memory) { + return abi.encodePacked(uint8(0x40), encodeWord(_node)); +} + +function encode_branch(bytes memory _nested) pure returns (bytes memory) { + return abi.encodePacked(uint8(0x41), encode_bytes_n(_nested)); +} + +function encode_subdigest(bytes32 _subdigest) pure returns (bytes memory) { + return abi.encodePacked(uint8(0x42), encodeWord(_subdigest)); +} + +function encode_nested(uint8 _weight, uint8 _threshold, bytes memory _nested) pure returns (bytes memory) { + return abi.encodePacked(uint8(0x43), uint8(_weight), uint8(_threshold), encode_bytes_n(_nested)); +} + +function encode_dynamic_signature(uint8 _weight, address _signer, bytes memory _signature) pure returns (bytes memory) { + return + abi.encodePacked(uint8(0x44), uint8(_weight), encodeWord(uint256(uint160(_signer))), encode_bytes_n(_signature)); +} + +function encode_sequence_signature(bool _noChainId, uint256 _threshold, uint32 _checkpoint, bytes memory _tree) + pure + returns (bytes memory) +{ + uint8 flag; + + bytes memory t; + + if (_noChainId) { + if (_threshold <= type(uint8).max) { + flag = 0x45; + t = abi.encodePacked(uint8(_threshold)); + } else { + flag = 0x47; + t = abi.encodePacked(uint16(_threshold)); + } + } else { + if (_threshold <= type(uint8).max) { + flag = 0x46; + t = abi.encodePacked(uint8(_threshold)); + } else { + flag = 0x48; + t = abi.encodePacked(uint16(_threshold)); + } + } + + return abi.encodePacked(flag, t, encodeWord(_checkpoint), encode_bytes_n(_tree)); +} + +function encode_sequence_chained_signatures(bytes[] memory _payloads) pure returns (bytes memory) { + bytes memory encoded; + + if (_payloads.length > type(uint8).max) { + encoded = abi.encodePacked(uint8(0x4a), uint16(_payloads.length)); + } else { + encoded = abi.encodePacked(uint8(0x49), uint8(_payloads.length)); + } + + for (uint256 i = 0; i < _payloads.length; i++) { + encoded = abi.encodePacked(encoded, encode_bytes_n(_payloads[i])); + } + + return encoded; +} + +function encode_abi_dynamic(bytes4 _selector, bool[] memory _isDynamic, bytes[] memory _values) + pure + returns (bytes memory) +{ + bytes memory encoded = abi.encodePacked(uint8(0x4b), uint8(0x00), _selector, uint8(_isDynamic.length)); + uint8 isDynamicBitmap = 0; + + // The first 8 values can be dynamic, this is marked using a bitmap + for (uint256 i = 0; i < 8 && i < _isDynamic.length; i++) { + if (_isDynamic[i]) { + isDynamicBitmap |= uint8(1 << i); + } + } + + encoded = abi.encodePacked(encoded, isDynamicBitmap); + + for (uint256 i = 0; i < _values.length; i++) { + if (_isDynamic[i]) { + encoded = abi.encodePacked(encoded, encode_bytes_n(_values[i])); + } else { + encoded = abi.encodePacked(encoded, encodeWord(abi.decode(_values[i], (uint256)))); + } + } + + return encoded; +} diff --git a/packages/wallet/wallet-contracts/foundry_test/modules/utils/L2CompressorHuff.t.sol b/packages/wallet/wallet-contracts/foundry_test/modules/utils/L2CompressorHuff.t.sol new file mode 100644 index 0000000000..0aef14817b --- /dev/null +++ b/packages/wallet/wallet-contracts/foundry_test/modules/utils/L2CompressorHuff.t.sol @@ -0,0 +1,284 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import "foundry_test/base/AdvTest.sol"; + +import "forge-std/console.sol"; +import "forge-std/console2.sol"; + +import {HuffConfig} from "foundry-huff/HuffConfig.sol"; +import {HuffDeployer} from "foundry-huff/HuffDeployer.sol"; + +import "contracts/modules/commons/interfaces/IModuleCalls.sol"; + +import "./L2CompressorEncoder.sol"; + +contract L2CompressorHuffTest is AdvTest { + address public imp; + + function setUp() public { + imp = address(HuffDeployer.config().with_evm_version("paris").deploy("L2Compressor")); + } + + function test_execute( + IModuleCalls.Transaction[] calldata _txs, + uint160 _space, + uint96 _nonce, + bytes calldata _signature + ) external { + vm.assume(_txs.length != 0 && _txs.length <= type(uint8).max); + + bytes32 packedNonce = abi.decode(abi.encodePacked(_space, _nonce), (bytes32)); + + bytes memory encoded = abi.encodePacked(hex"00", encodeWord(_space), encodeWord(_nonce), uint8(_txs.length)); + + for (uint256 i = 0; i < _txs.length; i++) { + IModuleCalls.Transaction memory t = _txs[i]; + + encoded = abi.encodePacked( + encoded, + build_flag(t.delegateCall, t.revertOnError, t.gasLimit != 0, t.value != 0, t.data.length != 0), + t.gasLimit != 0 ? encodeWord(t.gasLimit) : bytes(""), + encode_raw_address(t.target), + t.value != 0 ? encodeWord(t.value) : bytes(""), + t.data.length != 0 ? encode_bytes_n(t.data) : bytes("") + ); + } + + encoded = abi.encodePacked( + encoded, + encode_bytes_n(_signature), + encodeWord(uint256(uint160(address(0xEbD3186Ab4524330A866BE6866bE7bB55A173a23)))) + ); + + vm.expectCall( + address(0xEbD3186Ab4524330A866BE6866bE7bB55A173a23), + 0, + abi.encodeWithSelector(IModuleCalls.execute.selector, _txs, packedNonce, _signature) + ); + + (bool s, bytes memory r) = imp.call(encoded); + assertTrue(s); + assertEq(r, bytes("")); + } + + struct BatchMember { + IModuleCalls.Transaction[] txs; + uint160 space; + uint96 nonce; + bytes signature; + } + + function test_execute_many_2(BatchMember memory _batch1, BatchMember memory _batch2) external { + BatchMember[] memory batch = new BatchMember[](2); + batch[0] = _batch1; + batch[1] = _batch2; + test_execute_many(batch); + } + + function test_execute_many(BatchMember[] memory _batch) internal { + vm.assume(_batch.length != 0 && _batch.length <= type(uint8).max); + + uint256 size = mayBoundArr(_batch.length); + size = size == 0 ? 1 : size; + + bytes memory encoded = abi.encodePacked(hex"01", uint8(size)); + + for (uint256 i = 0; i < size; i++) { + vm.assume(_batch[i].txs.length <= type(uint8).max); + + if (_batch[i].txs.length == 0) { + _batch[i].txs = new IModuleCalls.Transaction[](1); + } + + bytes32 packedNonce = abi.decode(abi.encodePacked(_batch[i].space, _batch[i].nonce), (bytes32)); + + encoded = abi.encodePacked( + encoded, encodeWord(_batch[i].space), encodeWord(_batch[i].nonce), uint8(_batch[i].txs.length) + ); + + for (uint256 x = 0; x < _batch[i].txs.length; x++) { + IModuleCalls.Transaction memory t = _batch[i].txs[x]; + + encoded = abi.encodePacked( + encoded, + build_flag(t.delegateCall, t.revertOnError, t.gasLimit != 0, t.value != 0, t.data.length != 0), + t.gasLimit != 0 ? encodeWord(t.gasLimit) : bytes(""), + encode_raw_address(t.target), + t.value != 0 ? encodeWord(t.value) : bytes(""), + t.data.length != 0 ? encode_bytes_n(t.data) : bytes("") + ); + } + + // Derive a random address from i + address addr = address(uint160(uint256(keccak256(abi.encode(i))))); + + encoded = abi.encodePacked(encoded, encode_bytes_n(_batch[i].signature), encodeWord(uint256(uint160(addr)))); + + vm.expectCall( + addr, + 0, + abi.encodeWithSelector(IModuleCalls.execute.selector, _batch[i].txs, packedNonce, _batch[i].signature) + ); + } + + (bool s,) = imp.call{gas: type(uint64).max}(encoded); + assertTrue(s); + } + + function test_read_addresses() external { + vm.store(imp, bytes32(uint256(1)), bytes32(uint256(1000))); + vm.store(imp, bytes32(uint256(2)), bytes32(uint256(2000))); + + (bool s, bytes memory r) = imp.call(abi.encodePacked(hex"02", uint256(0))); + assertTrue(s); + + assertEq(r, abi.encode(bytes32(uint256(1000)))); + + (s, r) = imp.call(abi.encodePacked(hex"02", uint256(1))); + assertTrue(s); + + assertEq(r, abi.encode(bytes32(uint256(2000)))); + } + + function test_read_bytes32() external { + vm.store(imp, bytes32(uint256(0)) << 128, bytes32(uint256(1000))); + vm.store(imp, bytes32(uint256(1)) << 128, bytes32(uint256(2000))); + + (bool s, bytes memory r) = imp.call(abi.encodePacked(hex"03", uint256(0))); + assertTrue(s); + + assertEq(r, abi.encode(bytes32(uint256(1000)))); + + (s, r) = imp.call(abi.encodePacked(hex"03", uint256(1))); + assertTrue(s); + + assertEq(r, abi.encode(bytes32(uint256(2000)))); + } + + function test_read_storage_slots() external { + vm.store(imp, bytes32(uint256(0)) << 128, bytes32(uint256(1000))); + vm.store(imp, bytes32(uint256(1)) << 128, bytes32(uint256(2000))); + vm.store(imp, bytes32(uint256(1)), bytes32(uint256(4000))); + vm.store(imp, bytes32(uint256(2)), bytes32(uint256(5000))); + + (bool s, bytes memory r) = + imp.call(abi.encodePacked(hex"05", uint256(0) << 128, uint256(1), uint256(1) << 128, uint256(2))); + + assertTrue(s); + + assertEq(r, abi.encode(uint256(1000), uint256(4000), uint256(2000), uint256(5000))); + } + + function test_read_size() external { + bytes32 word = keccak256(abi.encode(uint256(0))); + vm.store(imp, bytes32(0), word); + + (bool s, bytes memory r) = imp.call(abi.encodePacked(hex"04")); + + assertTrue(s); + assertEq(r, abi.encode(word)); + } + + function test_decode_execute( + IModuleCalls.Transaction[] calldata _txs, + uint160 _space, + uint96 _nonce, + bytes calldata _signature + ) external { + vm.assume(_txs.length != 0 && _txs.length <= type(uint8).max); + + bytes32 packedNonce = abi.decode(abi.encodePacked(_space, _nonce), (bytes32)); + + bytes memory encoded = abi.encodePacked(hex"06", encodeWord(_space), encodeWord(_nonce), uint8(_txs.length)); + + for (uint256 i = 0; i < _txs.length; i++) { + IModuleCalls.Transaction memory t = _txs[i]; + + encoded = abi.encodePacked( + encoded, + build_flag(t.delegateCall, t.revertOnError, t.gasLimit != 0, t.value != 0, t.data.length != 0), + t.gasLimit != 0 ? encodeWord(t.gasLimit) : bytes(""), + encode_raw_address(t.target), + t.value != 0 ? encodeWord(t.value) : bytes(""), + t.data.length != 0 ? encode_bytes_n(t.data) : bytes("") + ); + } + + encoded = abi.encodePacked( + encoded, + encode_bytes_n(_signature), + encodeWord(uint256(uint160(address(0xEbD3186Ab4524330A866BE6866bE7bB55A173a23)))) + ); + + (bool s, bytes memory r) = imp.call(encoded); + assertTrue(s); + assertEq( + r, + abi.encodePacked( + abi.encodeWithSelector(IModuleCalls.execute.selector, _txs, packedNonce, _signature), + uint256(uint160(address(0xEbD3186Ab4524330A866BE6866bE7bB55A173a23))) + ) + ); + } + + function test_decode_execute_many_2(BatchMember memory _batch1, BatchMember memory _batch2) external { + BatchMember[] memory batch = new BatchMember[](2); + batch[0] = _batch1; + batch[1] = _batch2; + test_decode_execute_many(batch); + } + + function test_decode_execute_many(BatchMember[] memory _batch) internal { + vm.assume(_batch.length != 0 && _batch.length <= type(uint8).max); + + uint256 size = mayBoundArr(_batch.length); + size = size == 0 ? 1 : size; + + bytes memory encoded = abi.encodePacked(hex"07", uint8(size)); + + bytes memory expected; + + for (uint256 i = 0; i < size; i++) { + vm.assume(_batch[i].txs.length <= type(uint8).max); + + if (_batch[i].txs.length == 0) { + _batch[i].txs = new IModuleCalls.Transaction[](1); + } + + bytes32 packedNonce = abi.decode(abi.encodePacked(_batch[i].space, _batch[i].nonce), (bytes32)); + + encoded = abi.encodePacked( + encoded, encodeWord(_batch[i].space), encodeWord(_batch[i].nonce), uint8(_batch[i].txs.length) + ); + + for (uint256 x = 0; x < _batch[i].txs.length; x++) { + IModuleCalls.Transaction memory t = _batch[i].txs[x]; + + encoded = abi.encodePacked( + encoded, + build_flag(t.delegateCall, t.revertOnError, t.gasLimit != 0, t.value != 0, t.data.length != 0), + t.gasLimit != 0 ? encodeWord(t.gasLimit) : bytes(""), + encode_raw_address(t.target), + t.value != 0 ? encodeWord(t.value) : bytes(""), + t.data.length != 0 ? encode_bytes_n(t.data) : bytes("") + ); + } + + // Derive a random address from i + address addr = address(uint160(uint256(keccak256(abi.encode(i))))); + + encoded = abi.encodePacked(encoded, encode_bytes_n(_batch[i].signature), encodeWord(uint256(uint160(addr)))); + + expected = abi.encodePacked( + expected, + abi.encodeWithSelector(IModuleCalls.execute.selector, _batch[i].txs, packedNonce, _batch[i].signature), + uint256(uint160(addr)) + ); + } + + (bool s, bytes memory r) = imp.call{gas: type(uint64).max}(encoded); + assertTrue(s); + assertEq(r, expected); + } +} diff --git a/packages/wallet/wallet-contracts/foundry_test/modules/utils/L2CompressorHuffReadExecute.sol b/packages/wallet/wallet-contracts/foundry_test/modules/utils/L2CompressorHuffReadExecute.sol new file mode 100644 index 0000000000..d7c1f71d81 --- /dev/null +++ b/packages/wallet/wallet-contracts/foundry_test/modules/utils/L2CompressorHuffReadExecute.sol @@ -0,0 +1,143 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import "foundry_test/base/AdvTest.sol"; + +import "forge-std/console.sol"; +import "forge-std/console2.sol"; + +import {HuffConfig} from "foundry-huff/HuffConfig.sol"; +import {HuffDeployer} from "foundry-huff/HuffDeployer.sol"; + +import "contracts/modules/commons/interfaces/IModuleCalls.sol"; + +import "./L2CompressorEncoder.sol"; + +uint256 constant FMS = 0xa0; + +contract L2CompressorHuffReadExecuteTest is AdvTest { + address public imp; + + function setUp() public { + imp = address(HuffDeployer.config().with_evm_version("paris").deploy("imps/L2CompressorReadExecute")); + } + + function test_read_simple_execute( + IModuleCalls.Transaction[] calldata _txs, + uint160 _space, + uint96 _nonce, + bytes calldata _signature + ) external { + vm.assume(_txs.length != 0 && _txs.length <= type(uint8).max); + + bytes32 packedNonce = abi.decode(abi.encodePacked(_space, _nonce), (bytes32)); + + bytes memory encoded = abi.encodePacked(encodeWord(_space), encodeWord(_nonce), uint8(_txs.length)); + + for (uint256 i = 0; i < _txs.length; i++) { + IModuleCalls.Transaction memory t = _txs[i]; + + encoded = abi.encodePacked( + encoded, + build_flag(t.delegateCall, t.revertOnError, t.gasLimit != 0, t.value != 0, t.data.length != 0), + t.gasLimit != 0 ? encodeWord(t.gasLimit) : bytes(""), + encode_raw_address(t.target), + t.value != 0 ? encodeWord(t.value) : bytes(""), + t.data.length != 0 ? encode_bytes_n(t.data) : bytes("") + ); + } + + encoded = abi.encodePacked(encoded, encode_bytes_n(_signature)); + + (bool s, bytes memory r) = imp.staticcall(encoded); + + assertTrue(s); + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(rindex, encoded.length); + assertEq(windex, res.length + FMS); + + // Encode using solidity + bytes memory solidityEncoded = + abi.encodeWithSelector(IModuleCalls.execute.selector, _txs, packedNonce, _signature); + assertEq(solidityEncoded, res); + } + + function test_read_nested_execute( + address _wallet, + IModuleCalls.Transaction[] calldata _txs, + uint160 _space, + uint96 _nonce, + bytes calldata _signature + ) external { + vm.assume(_txs.length != 0 && _txs.length <= type(uint8).max); + bytes32 packedNonce = abi.decode(abi.encodePacked(_space, _nonce), (bytes32)); + + IModuleCalls.Transaction[] memory outerTx = new IModuleCalls.Transaction[](1); + outerTx[0] = IModuleCalls.Transaction({ + delegateCall: false, + revertOnError: false, + gasLimit: 0, + target: _wallet, + value: 0, + data: abi.encodeWithSelector(IModuleCalls.execute.selector, _txs, packedNonce, _signature) + }); + + bytes memory outerSignature = hex"112233"; + bytes32 outerNonce = bytes32(0); + + bytes memory encoded = abi.encodePacked( + encodeWord(bytes32(0)), + encodeWord(bytes32(0)), + uint8(1), // One transaction + build_flag( + outerTx[0].delegateCall, + outerTx[0].revertOnError, + outerTx[0].gasLimit != 0, + outerTx[0].value != 0, + outerTx[0].data.length != 0 + ), + bytes(""), + encode_raw_address(outerTx[0].target), + bytes("") + ); + + // Encode the inner transaction + encoded = abi.encodePacked( + encoded, + uint8(0x26), // Read EXECUTE flag + encodeWord(_space), + encodeWord(_nonce), + uint8(_txs.length) + ); + + for (uint256 i = 0; i < _txs.length; i++) { + IModuleCalls.Transaction memory t = _txs[i]; + + encoded = abi.encodePacked( + encoded, + build_flag(t.delegateCall, t.revertOnError, t.gasLimit != 0, t.value != 0, t.data.length != 0), + t.gasLimit != 0 ? encodeWord(t.gasLimit) : bytes(""), + encode_raw_address(t.target), + t.value != 0 ? encodeWord(t.value) : bytes(""), + t.data.length != 0 ? encode_bytes_n(t.data) : bytes("") + ); + } + + encoded = abi.encodePacked(encoded, encode_bytes_n(_signature)); + + // Encode the outer signature + encoded = abi.encodePacked(encoded, encode_bytes_n(outerSignature)); + + (bool s, bytes memory r) = imp.staticcall(encoded); + assertTrue(s); + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + assertEq(rindex, encoded.length); + assertEq(windex, res.length + FMS); + + // Encode using solidity + bytes memory solidityEncoded = + abi.encodeWithSelector(IModuleCalls.execute.selector, outerTx, outerNonce, outerSignature); + assertEq(solidityEncoded, res); + } +} diff --git a/packages/wallet/wallet-contracts/foundry_test/modules/utils/L2CompressorHuffReadFlag.t.sol b/packages/wallet/wallet-contracts/foundry_test/modules/utils/L2CompressorHuffReadFlag.t.sol new file mode 100644 index 0000000000..49e59668b7 --- /dev/null +++ b/packages/wallet/wallet-contracts/foundry_test/modules/utils/L2CompressorHuffReadFlag.t.sol @@ -0,0 +1,1018 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import "foundry_test/base/AdvTest.sol"; + +import "forge-std/console.sol"; +import "forge-std/console2.sol"; + +import {HuffConfig} from "foundry-huff/HuffConfig.sol"; +import {HuffDeployer} from "foundry-huff/HuffDeployer.sol"; + +import "contracts/modules/commons/interfaces/IModuleCalls.sol"; + +import "./L2CompressorEncoder.sol"; + +uint256 constant FMS = 0xa0; + +contract L2CompressorHuffReadFlagTests is AdvTest { + address public imp; + + function setUp() public { + imp = address(HuffDeployer.config().with_evm_version("paris").deploy("imps/L2CompressorReadFlag")); + } + + function test_read_flag_bytes32_one(uint8 _val) external { + (bool s, bytes memory r) = imp.staticcall(abi.encodePacked(hex"01", _val)); + + assertTrue(s); + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + assertEq(rindex, 2); + assertEq(windex, FMS + 32); + + assertEq(abi.encode(uint256(_val)), res); + } + + function test_read_flag_bytes32_two(uint16 _val) external { + (bool s, bytes memory r) = imp.staticcall(abi.encodePacked(hex"02", _val)); + + assertTrue(s); + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + assertEq(rindex, 3); + assertEq(windex, FMS + 32); + + assertEq(abi.encode(uint256(_val)), res); + } + + function test_read_flag_bytes32_x(uint256 _size, bytes memory _content) public { + _size = bound(_size, 1, 32); + + (bool s, bytes memory r) = imp.staticcall(abi.encodePacked(uint8(_size), _content)); + + assertTrue(s); + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + assertEq(rindex, 1 + _size); + assertEq(windex, FMS + 32); + + _content = abi.encodePacked(_content, bytes32(0)); + uint256 expected; + assembly { + expected := mload(add(_content, 0x20)) + expected := shr(sub(256, mul(_size, 8)), expected) + } + + assertEq(abi.encode(uint256(expected)), res); + } + + function test_read_flag_save_and_read_address(address _addr2) external { + address _addr = address(this); + (bool s, bytes memory r) = imp.call(abi.encodePacked(hex"21", _addr)); + + assertTrue(s); + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(rindex, 1 + 20); + assertEq(windex, FMS + 32); + + assertEq(abi.encode(_addr), res); + + // Read the address at index 1 + (s, r) = imp.staticcall(abi.encodePacked(hex"23", uint16(1))); + + assertTrue(s); + (rindex, windex, res) = abi.decode(r, (uint256, uint256, bytes)); + assertEq(rindex, 3); + assertEq(windex, FMS + 32); + + assertEq(abi.encode(_addr), res); + + // Save a second address + (s, r) = imp.call(abi.encodePacked(hex"21", _addr2)); + + assertTrue(s); + (rindex, windex, res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(rindex, 1 + 20); + assertEq(windex, FMS + 32); + + assertEq(abi.encode(_addr2), res); + + // Read second address using 3 bytes, 4 bytes and 5 bytes + (s, r) = imp.staticcall(abi.encodePacked(hex"24", uint24(2))); + + assertTrue(s); + (rindex, windex, res) = abi.decode(r, (uint256, uint256, bytes)); + assertEq(rindex, 4); + assertEq(windex, FMS + 32); + + assertEq(abi.encode(_addr2), res); + + (s, r) = imp.staticcall(abi.encodePacked(hex"25", uint32(2))); + + assertTrue(s); + (rindex, windex, res) = abi.decode(r, (uint256, uint256, bytes)); + assertEq(rindex, 5); + assertEq(windex, FMS + 32); + + assertEq(abi.encode(_addr2), res); + + (s, r) = imp.staticcall(abi.encodePacked(hex"25", uint32(2))); + + assertTrue(s); + (rindex, windex, res) = abi.decode(r, (uint256, uint256, bytes)); + assertEq(rindex, 5); + assertEq(windex, FMS + 32); + + assertEq(abi.encode(_addr2), res); + } + + function test_read_flag_save_and_read_bytes32(bytes32 _b1, bytes32 _b2) external { + (bool s, bytes memory r) = imp.call(abi.encodePacked(hex"22", _b1)); + + assertTrue(s); + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(rindex, 1 + 32); + assertEq(windex, FMS + 32); + + assertEq(abi.encode(_b1), res); + + // Read the address at index 1 + (s, r) = imp.staticcall(abi.encodePacked(hex"27", uint16(1))); + + assertTrue(s); + (rindex, windex, res) = abi.decode(r, (uint256, uint256, bytes)); + assertEq(rindex, 3); + assertEq(windex, FMS + 32); + + assertEq(abi.encode(_b1), res); + + // Save a second address + (s, r) = imp.call(abi.encodePacked(hex"22", _b2)); + + assertTrue(s); + (rindex, windex, res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(rindex, 1 + 32); + assertEq(windex, FMS + 32); + + assertEq(abi.encode(_b2), res); + + // Read second address using 3 bytes, 4 bytes and 5 bytes + (s, r) = imp.staticcall(abi.encodePacked(hex"28", uint24(2))); + + assertTrue(s); + (rindex, windex, res) = abi.decode(r, (uint256, uint256, bytes)); + assertEq(rindex, 4); + assertEq(windex, FMS + 32); + + assertEq(abi.encode(_b2), res); + + (s, r) = imp.staticcall(abi.encodePacked(hex"29", uint32(2))); + + assertTrue(s); + (rindex, windex, res) = abi.decode(r, (uint256, uint256, bytes)); + assertEq(rindex, 5); + assertEq(windex, FMS + 32); + + assertEq(abi.encode(_b2), res); + + (s, r) = imp.staticcall(abi.encodePacked(hex"29", uint32(2))); + + assertTrue(s); + (rindex, windex, res) = abi.decode(r, (uint256, uint256, bytes)); + assertEq(rindex, 5); + assertEq(windex, FMS + 32); + + assertEq(abi.encode(_b2), res); + } + + function test_read_flag_bytes_n(bytes calldata _data, bytes calldata _extra) external { + (bool s, bytes memory r) = + imp.staticcall(abi.encodePacked(hex"2b", hex"04", uint32(_data.length), _data, _extra)); + + assertTrue(s); + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(rindex, _data.length + 1 + 1 + 4); + assertEq(windex, FMS + _data.length); + assertEq(res, _data); + } + + function test_read_flag_abi_encode_0(bytes4 _selector) external { + bytes memory encoded = encode_abi_call(_selector); + (bool s, bytes memory r) = imp.staticcall(encoded); + + assertTrue(s); + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(rindex, encoded.length); + assertEq(windex, FMS + res.length); + assertEq(abi.encodePacked(_selector), res); + } + + function test_read_flag_abi_encode_1(bytes4 _selector, bytes32 _v1) external { + bytes memory encoded = encode_abi_call(_selector, _v1); + (bool s, bytes memory r) = imp.staticcall(encoded); + + assertTrue(s); + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(rindex, encoded.length); + assertEq(windex, FMS + res.length); + assertEq(abi.encodePacked(_selector, _v1), res); + } + + function test_read_flag_abi_encode_2(bytes4 _selector, bytes32 _v1, bytes32 _v2) external { + bytes memory encoded = encode_abi_call(_selector, _v1, _v2); + (bool s, bytes memory r) = imp.staticcall(encoded); + + assertTrue(s); + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(rindex, encoded.length); + assertEq(windex, FMS + res.length); + assertEq(abi.encodePacked(_selector, _v1, _v2), res); + } + + function test_read_flag_abi_encode_3(bytes4 _selector, bytes32 _v1, bytes32 _v2, bytes32 _v3) external { + bytes memory encoded = encode_abi_call(_selector, _v1, _v2, _v3); + (bool s, bytes memory r) = imp.staticcall(encoded); + + assertTrue(s); + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(rindex, encoded.length); + assertEq(windex, FMS + res.length); + assertEq(abi.encodePacked(_selector, _v1, _v2, _v3), res); + } + + function test_read_flag_abi_encode_4(bytes4 _selector, bytes32 _v1, bytes32 _v2, bytes32 _v3, bytes32 _v4) + external + { + bytes memory encoded = encode_abi_call(_selector, _v1, _v2, _v3, _v4); + (bool s, bytes memory r) = imp.staticcall(encoded); + + assertTrue(s); + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(rindex, encoded.length); + assertEq(windex, FMS + res.length); + assertEq(abi.encodePacked(_selector, _v1, _v2, _v3, _v4), res); + } + + function test_read_flag_abi_encode_5( + bytes4 _selector, + bytes32 _v1, + bytes32 _v2, + bytes32 _v3, + bytes32 _v4, + bytes32 _v5 + ) external { + bytes memory encoded = encode_abi_call(_selector, _v1, _v2, _v3, _v4, _v5); + (bool s, bytes memory r) = imp.staticcall(encoded); + + assertTrue(s); + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(rindex, encoded.length); + assertEq(windex, FMS + res.length); + assertEq(abi.encodePacked(_selector, _v1, _v2, _v3, _v4, _v5), res); + } + + function test_read_flag_abi_encode_5( + bytes4 _selector, + bytes32 _v1, + bytes32 _v2, + bytes32 _v3, + bytes32 _v4, + bytes32 _v5, + bytes32 _v6 + ) external { + bytes memory encoded = encode_abi_call(_selector, _v1, _v2, _v3, _v4, _v5, _v6); + (bool s, bytes memory r) = imp.staticcall(encoded); + + assertTrue(s); + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(rindex, encoded.length); + assertEq(windex, FMS + res.length); + assertEq(abi.encodePacked(_selector, _v1, _v2, _v3, _v4, _v5, _v6), res); + } + + function test_read_nested(bytes memory _dynamic, uint256 _val1, uint256 _val2) external { + bytes memory encoded = + encode_nested(encode_bytes_n(_dynamic), encode_nested(encodeWord(_val1), encodeWord(_val2))); + + (bool s, bytes memory r) = imp.staticcall(encoded); + assertEq(s, true); + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(rindex, encoded.length); + assertEq(windex, FMS + res.length); + assertEq(abi.encodePacked(_dynamic, _val1, _val2), res); + } + + function test_read_encode_nested_long() external { + bytes[] memory vals = new bytes[](2000); + + for (uint256 i = 0; i < vals.length; i++) { + vals[i] = encodeWord(i * 2); + } + + bytes memory encoded = encode_nested(vals); + + (bool s, bytes memory r) = imp.staticcall(encoded); + assertEq(s, true); + + bytes memory expected; + for (uint256 i = 0; i < vals.length; i++) { + expected = abi.encodePacked(expected, uint256(i * 2)); + } + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(rindex, encoded.length); + assertEq(windex, FMS + res.length); + assertEq(expected, res); + } + + function test_read_signature(uint8 _weight, bytes1[66] memory _sig) external { + bytes memory _sig2 = new bytes(66); + + for (uint256 i = 0; i < _sig.length; i++) { + _sig2[i] = _sig[i]; + } + + bytes memory encoded = encode_eoa_signature(_weight, _sig2); + + (bool s, bytes memory r) = imp.staticcall(encoded); + + assertTrue(s); + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(rindex, encoded.length); + assertEq(windex, FMS + res.length); + + assertEq(res, abi.encodePacked(uint8(0), _weight, _sig2)); + } + + function test_read_address(uint8 _weight, address _addr) external { + bytes memory encoded = encode_address(_weight, _addr); + + (bool s, bytes memory r) = imp.staticcall(encoded); + + assertTrue(s); + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(rindex, encoded.length); + assertEq(windex, FMS + res.length); + + assertEq(res, abi.encodePacked(uint8(1), _weight, _addr)); + } + + function test_read_node(bytes32 _node) external { + bytes memory encoded = encode_node(_node); + + (bool s, bytes memory r) = imp.staticcall(encoded); + + assertTrue(s); + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(rindex, encoded.length); + assertEq(windex, FMS + res.length); + + assertEq(res, abi.encodePacked(uint8(3), _node)); + } + + function test_read_subdigest(bytes32 _subdigest) external { + bytes memory encoded = encode_subdigest(_subdigest); + + (bool s, bytes memory r) = imp.staticcall(encoded); + + assertTrue(s); + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(rindex, encoded.length); + assertEq(windex, FMS + res.length); + + assertEq(res, abi.encodePacked(uint8(5), _subdigest)); + } + + function test_read_branch(bytes memory _data) external { + vm.assume(_data.length <= type(uint24).max); + + bytes memory encoded = encode_branch(_data); + + (bool s, bytes memory r) = imp.staticcall(encoded); + + assertTrue(s); + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(rindex, encoded.length); + assertEq(windex, FMS + res.length); + + assertEq(res, abi.encodePacked(uint8(4), uint24(_data.length), _data)); + } + + function test_read_nested(uint8 _weight, uint8 _threshold, bytes memory _data) external { + vm.assume(_data.length <= type(uint24).max); + + bytes memory encoded = encode_nested(_weight, _threshold, _data); + + (bool s, bytes memory r) = imp.staticcall(encoded); + + assertTrue(s); + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(rindex, encoded.length); + assertEq(windex, FMS + res.length); + + assertEq(res, abi.encodePacked(uint8(6), uint8(_weight), uint16(_threshold), uint24(_data.length), _data)); + } + + function test_read_dynamic_signature(uint8 _weight, address _signer, bytes memory _signature) external { + vm.assume(_signature.length <= type(uint24).max - 1); + + bytes memory encoded = encode_dynamic_signature(_weight, _signer, _signature); + + (bool s, bytes memory r) = imp.staticcall(encoded); + + assertTrue(s); + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(rindex, encoded.length); + assertEq(windex, FMS + res.length); + + assertEq( + res, + abi.encodePacked(uint8(2), uint8(_weight), _signer, uint24(_signature.length + 1), _signature, uint8(3)) + ); + } + + function test_read_sequence_signature(bool _noChainId, uint16 _threshold, uint32 _checkpoint, bytes memory _tree) + external + { + bytes memory encoded = encode_sequence_signature(_noChainId, _threshold, _checkpoint, _tree); + + (bool s, bytes memory r) = imp.staticcall(encoded); + + assertTrue(s); + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(rindex, encoded.length); + assertEq(windex, FMS + res.length); + + assertEq(res, abi.encodePacked(uint8(_noChainId ? 0x02 : 0x01), uint16(_threshold), uint32(_checkpoint), _tree)); + } + + function test_read_sequence_chained_signatures(bytes[] memory _signatures) external { + vm.assume(_signatures.length != 0); + for (uint256 i = 0; i < _signatures.length; i++) { + vm.assume(_signatures[i].length <= type(uint24).max); + } + + bytes memory encoded = encode_sequence_chained_signatures(_signatures); + + (bool s, bytes memory r) = imp.staticcall(encoded); + assertTrue(s); + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(windex, FMS + res.length); + assertEq(rindex, encoded.length); + + bytes memory expected = abi.encodePacked(uint8(0x03)); + + for (uint256 i = 0; i < _signatures.length; i++) { + expected = abi.encodePacked(expected, uint24(_signatures[i].length), _signatures[i]); + } + + assertEq(res, expected); + } + + function test_read_abi_dynamic_no_dynamic(bytes4 _selector, bytes32[] calldata _values) external { + vm.assume(_values.length <= type(uint8).max && _values.length != 0); + bool[] memory isDynamic = new bool[](_values.length); + bytes[] memory values = new bytes[](_values.length); + for (uint256 i = 0; i < _values.length; i++) { + values[i] = abi.encodePacked(_values[i]); + } + + bytes memory encoded = encode_abi_dynamic(_selector, isDynamic, values); + + (bool s, bytes memory r) = imp.staticcall(encoded); + assertTrue(s); + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(windex, FMS + res.length); + assertEq(rindex, encoded.length); + + assertEq(res, abi.encodePacked(_selector, _values)); + } + + function test_read_abi_dynamic_only_1(bytes4 _selector, bytes memory _data1) external { + bool[] memory isDynamic = new bool[](1); + bytes[] memory _values = new bytes[](1); + + isDynamic[0] = true; + + _values[0] = _data1; + + bytes memory encoded = encode_abi_dynamic(_selector, isDynamic, _values); + + (bool s, bytes memory r) = imp.staticcall(encoded); + + assertTrue(s); + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(windex, FMS + res.length); + assertEq(rindex, encoded.length); + + assertEq(res, abi.encodeWithSelector(_selector, _values[0])); + } + + function test_read_abi_dynamic_only_2(bytes4 _selector, bytes memory _data1, bytes memory _data2) external { + bool[] memory isDynamic = new bool[](2); + bytes[] memory _values = new bytes[](2); + + isDynamic[0] = true; + isDynamic[1] = true; + + _values[0] = _data1; + _values[1] = _data2; + + bytes memory encoded = encode_abi_dynamic(_selector, isDynamic, _values); + + (bool s, bytes memory r) = imp.staticcall(encoded); + + assertTrue(s); + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(windex, FMS + res.length); + assertEq(rindex, encoded.length); + + assertEq(res, abi.encodeWithSelector(_selector, _values[0], _values[1])); + } + + function test_read_abi_dynamic_only_3( + bytes4 _selector, + bytes memory _data1, + bytes memory _data2, + bytes memory _data3 + ) external { + bool[] memory isDynamic = new bool[](3); + bytes[] memory _values = new bytes[](3); + + isDynamic[0] = true; + isDynamic[1] = true; + isDynamic[2] = true; + + _values[0] = _data1; + _values[1] = _data2; + _values[2] = _data3; + + bytes memory encoded = encode_abi_dynamic(_selector, isDynamic, _values); + + (bool s, bytes memory r) = imp.staticcall(encoded); + + assertTrue(s); + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(windex, FMS + res.length); + assertEq(rindex, encoded.length); + + assertEq(res, abi.encodeWithSelector(_selector, _values[0], _values[1], _values[2])); + } + + function test_read_abi_dynamic_only_8( + bytes4 _selector, + bytes memory _data1, + bytes memory _data2, + bytes memory _data3, + bytes memory _data4, + bytes memory _data5, + bytes memory _data6, + bytes memory _data7, + bytes memory _data8 + ) external { + bytes memory r; + uint256 el; + + { + bool[] memory isDynamic = new bool[](8); + bytes[] memory _values = new bytes[](8); + + isDynamic[0] = true; + isDynamic[1] = true; + isDynamic[2] = true; + isDynamic[3] = true; + isDynamic[4] = true; + isDynamic[5] = true; + isDynamic[6] = true; + isDynamic[7] = true; + + _values[0] = _data1; + _values[1] = _data2; + _values[2] = _data3; + _values[3] = _data4; + _values[4] = _data5; + _values[5] = _data6; + _values[6] = _data7; + _values[7] = _data8; + + bool s; + bytes memory encoded = encode_abi_dynamic(_selector, isDynamic, _values); + + (s, r) = imp.staticcall(encoded); + el = encoded.length; + assertTrue(s); + } + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(windex, FMS + res.length); + assertEq(rindex, el); + + assertEq(res, abi.encodeWithSelector(_selector, _data1, _data2, _data3, _data4, _data5, _data6, _data7, _data8)); + } + + function test_read_mixed_2(bytes4 _selector, bytes32 _data1, bytes memory _data2) external { + bool[] memory isDynamic = new bool[](2); + bytes[] memory _values = new bytes[](2); + + isDynamic[0] = false; + isDynamic[1] = true; + + _values[0] = abi.encodePacked(_data1); + _values[1] = _data2; + + bytes memory encoded = encode_abi_dynamic(_selector, isDynamic, _values); + + (bool s, bytes memory r) = imp.staticcall(encoded); + + assertTrue(s); + + bytes memory expected = abi.encodeWithSelector(_selector, _data1, _data2); + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(windex, FMS + res.length); + assertEq(rindex, encoded.length); + + assertEq(res, expected); + } + + function test_read_mixed_2b(bytes4 _selector, bytes memory _data1, bytes32 _data2) external { + bool[] memory isDynamic = new bool[](2); + bytes[] memory _values = new bytes[](2); + + isDynamic[0] = true; + isDynamic[1] = false; + + _values[0] = _data1; + _values[1] = abi.encodePacked(_data2); + + bytes memory encoded = encode_abi_dynamic(_selector, isDynamic, _values); + + (bool s, bytes memory r) = imp.staticcall(encoded); + + assertTrue(s); + + bytes memory expected = abi.encodeWithSelector(_selector, _data1, _data2); + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(windex, FMS + res.length); + assertEq(rindex, encoded.length); + + assertEq(res, expected); + } + + function test_read_abi_mixed_8b( + bytes4 _selector, + bytes32 _data1, + bytes memory _data2, + bytes32 _data3, + bytes memory _data4, + bytes memory _data5, + bytes memory _data6, + bytes32 _data7, + bytes32 _data8 + ) external { + bytes memory r; + uint256 el; + + { + bool[] memory isDynamic = new bool[](8); + bytes[] memory _values = new bytes[](8); + + isDynamic[0] = false; + isDynamic[1] = true; + isDynamic[2] = false; + isDynamic[3] = true; + isDynamic[4] = true; + isDynamic[5] = true; + isDynamic[6] = false; + isDynamic[7] = false; + + _values[0] = abi.encodePacked(_data1); + _values[1] = _data2; + _values[2] = abi.encodePacked(_data3); + _values[3] = _data4; + _values[4] = _data5; + _values[5] = _data6; + _values[6] = abi.encodePacked(_data7); + _values[7] = abi.encodePacked(_data8); + + bool s; + bytes memory encoded = encode_abi_dynamic(_selector, isDynamic, _values); + + (s, r) = imp.staticcall(encoded); + el = encoded.length; + assertTrue(s); + } + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(windex, FMS + res.length); + assertEq(rindex, el); + + assertEq(res, abi.encodeWithSelector(_selector, _data1, _data2, _data3, _data4, _data5, _data6, _data7, _data8)); + } + + function test_read_abi_mixed_8b( + bytes4 _selector, + bytes memory _data1, + bytes32 _data2, + bytes32 _data3, + bytes memory _data4, + bytes memory _data5, + bytes32 _data6, + bytes memory _data7, + bytes memory _data8 + ) external { + bytes memory r; + uint256 el; + + { + bool[] memory isDynamic = new bool[](8); + bytes[] memory _values = new bytes[](8); + + isDynamic[0] = true; + isDynamic[1] = false; + isDynamic[2] = false; + isDynamic[3] = true; + isDynamic[4] = true; + isDynamic[5] = false; + isDynamic[6] = true; + isDynamic[7] = true; + + _values[0] = _data1; + _values[1] = abi.encodePacked(_data2); + _values[2] = abi.encodePacked(_data3); + _values[3] = _data4; + _values[4] = _data5; + _values[5] = abi.encodePacked(_data6); + _values[6] = _data7; + _values[7] = _data8; + + bool s; + bytes memory encoded = encode_abi_dynamic(_selector, isDynamic, _values); + + (s, r) = imp.staticcall(encoded); + el = encoded.length; + assertTrue(s); + } + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(windex, FMS + res.length); + assertEq(rindex, el); + + assertEq(res, abi.encodeWithSelector(_selector, _data1, _data2, _data3, _data4, _data5, _data6, _data7, _data8)); + } + + function test_read_no_op() external { + bytes memory encoded = abi.encodePacked(uint8(0x4c)); + + (bool s, bytes memory r) = imp.staticcall(encoded); + assertTrue(s); + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + assertEq(rindex, 1); + assertEq(windex, FMS + res.length); + assertEq(res.length, 0); + } + + function test_mirror_flag() external { + bytes memory encoded = abi.encodePacked( + encode_nested(encodeWord(type(uint256).max - 1), abi.encodePacked(uint8(0x4d), uint16(0x02))) + ); + + (bool s, bytes memory r) = imp.staticcall(encoded); + assertTrue(s); + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(windex, FMS + res.length); + assertEq(rindex, encoded.length); + assertEq(res, abi.encodePacked(type(uint256).max - 1, type(uint256).max - 1)); + } + + function test_copy_calldata() external { + bytes memory encoded = abi.encodePacked( + encode_nested(encodeWord(type(uint256).max - 1), abi.encodePacked(uint8(0x4e), uint16(0x03), uint8(0x21))) + ); + + (bool s, bytes memory r) = imp.staticcall(encoded); + assertTrue(s); + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(windex, FMS + res.length); + assertEq(rindex, encoded.length); + assertEq(res, abi.encodePacked(type(uint256).max - 1, type(uint256).max - 1, uint8(0x4e))); + } + + function test_read_storage_flag_addr(address _addr) external { + _addr = address(this); + bytes memory encoded = abi.encodePacked( + encode_nested(abi.encodePacked(uint8(0x21), _addr), abi.encodePacked(uint8(0x4f), uint16(0x02))) + ); + + (bool s, bytes memory r) = imp.call(encoded); + assertTrue(s); + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(windex, FMS + res.length); + assertEq(rindex, encoded.length); + assertEq(res, abi.encode(_addr, _addr)); + } + + function test_read_literal(uint256 _val) external { + bytes memory encoded = encodeWord(_val); + + (bool s, bytes memory r) = imp.call(encoded); + assertTrue(s); + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(windex, FMS + res.length); + assertEq(rindex, encoded.length); + assertEq(res, abi.encode(_val)); + } + + function test_read_pow_10(uint256 _exp) external { + _exp = bound(_exp, 0, 77); + + // First bit means we aren't going to multiply it after + bytes memory encoded = abi.encodePacked(uint8(0x00), uint8(_exp) | uint8(0x80)); + + (bool s, bytes memory r) = imp.call(encoded); + assertTrue(s); + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(windex, FMS + res.length); + assertEq(rindex, encoded.length); + assertEq(res, abi.encode(uint256(10 ** _exp))); + } + + function test_read_pow_10_and_mul(uint256 _exp, uint8 _mantissa) external { + _exp = bound(_exp, 1, 77); + + // First bit means we aren't going to multiply it after + bytes memory encoded = abi.encodePacked(uint8(0x00), uint8(_exp), uint8(_mantissa)); + + (bool s, bytes memory r) = imp.call(encoded); + assertTrue(s); + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + unchecked { + assertEq(windex, FMS + res.length); + assertEq(rindex, encoded.length); + assertEq(res, abi.encode(uint256(10 ** _exp) * uint256(_mantissa))); + } + } + + function test_read_pow_10_and_mul_l(uint256 _exp, uint256 _mantissa) external { + _exp = bound(_exp, 0, 63); + _mantissa = bound(_mantissa, 0, 0x3ffff); + + // Encode the 3 byte word, the first 3 bits are the exponent, the rest is the mantissa + bytes3 word = bytes3(uint24(_exp) << 18 | uint24(_mantissa)); + + // First bit means we aren't going to multiply it after + bytes memory encoded = abi.encodePacked(uint8(0x2a), word); + + (bool s, bytes memory r) = imp.call(encoded); + assertTrue(s); + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + uint256 expected; + unchecked { + expected = uint256(10 ** _exp) * uint256(_mantissa); + } + + unchecked { + assertEq(windex, FMS + res.length); + assertEq(rindex, encoded.length); + assertEq(res, abi.encode(expected)); + } + } + + function test_read_self_execute() external { + // vm.assume(_txs.length != 0 && _txs.length <= type(uint8).max); + + IModuleCalls.Transaction[] memory _txs = new IModuleCalls.Transaction[](1); + + bytes memory encoded = abi.encodePacked(uint8(0x00), uint8(0x00), uint8(_txs.length)); + + for (uint256 i = 0; i < _txs.length; i++) { + IModuleCalls.Transaction memory t = _txs[i]; + + encoded = abi.encodePacked( + encoded, + build_flag(t.delegateCall, t.revertOnError, t.gasLimit != 0, t.value != 0, t.data.length != 0), + t.gasLimit != 0 ? encodeWord(t.gasLimit) : bytes(""), + encode_raw_address(t.target), + t.value != 0 ? encodeWord(t.value) : bytes(""), + t.data.length != 0 ? encode_bytes_n(t.data) : bytes("") + ); + } + + (bool s, bytes memory r) = imp.staticcall(encoded); + + assertTrue(s); + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(rindex, encoded.length); + assertEq(windex, res.length + FMS); + + bytes memory solidityEncoded = abi.encodeWithSelector(IModuleCalls.selfExecute.selector, _txs); + assertEq(solidityEncoded, res); + } + + function test_read_flag_abi_encode_by_index() external { + bytes memory encoded = abi.encodePacked(uint8(0x2d), uint8(0x01)); + (bool s, bytes memory r) = imp.staticcall(encoded); + + assertTrue(s); + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(rindex, encoded.length); + assertEq(windex, FMS + res.length); + assertEq(hex"a9059cbb", res); + } + + function test_read_flag_abi_encode_by_index_2() external { + bytes memory encoded = abi.encodePacked(uint8(0x2d), uint8(0x02)); + (bool s, bytes memory r) = imp.staticcall(encoded); + + assertTrue(s); + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(rindex, encoded.length); + assertEq(windex, FMS + res.length); + assertEq(hex"095ea7b3", res); + } + + function test_read_flag_abi_encode_by_index_2_args(bytes32 _arg) external { + bytes memory encoded = abi.encodePacked(uint8(0x2e), uint8(0x01), encodeWord(_arg)); + (bool s, bytes memory r) = imp.staticcall(encoded); + + assertTrue(s); + + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(rindex, encoded.length); + assertEq(windex, FMS + res.length); + assertEq(abi.encodePacked(hex"a9059cbb", _arg), res); + } +} diff --git a/packages/wallet/wallet-contracts/foundry_test/modules/utils/L2CompressorHuffReadNonce.sol b/packages/wallet/wallet-contracts/foundry_test/modules/utils/L2CompressorHuffReadNonce.sol new file mode 100644 index 0000000000..ad10456850 --- /dev/null +++ b/packages/wallet/wallet-contracts/foundry_test/modules/utils/L2CompressorHuffReadNonce.sol @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import "foundry_test/base/AdvTest.sol"; + +import "forge-std/console.sol"; +import "forge-std/console2.sol"; + +import {HuffConfig} from "foundry-huff/HuffConfig.sol"; +import {HuffDeployer} from "foundry-huff/HuffDeployer.sol"; + +import "contracts/modules/commons/interfaces/IModuleCalls.sol"; + +uint256 constant FMS = 0xa0; + +import "./L2CompressorEncoder.sol"; + +contract L2CompressorHuffReadNonceTest is AdvTest { + address public imp; + + function setUp() public { + imp = address(HuffDeployer.config().with_evm_version("paris").deploy("imps/L2CompressorReadNonce")); + } + + function test_read_simple_nonce() external { + uint256 space = 76518466025766696338879503773554426820412884125; + uint256 nonce = 29095922913147819529123945996; + + bytes32 compact = 0x0d6734e95e00251b768924d47d52db3270fcc49d5e039555a5312d84eb305e0c; + + bytes memory encoded = abi.encodePacked(encodeWord(space), encodeWord(nonce)); + + (bool s, bytes memory r) = imp.staticcall(encoded); + + assertTrue(s); + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + assertEq(rindex, encoded.length); + assertEq(windex, res.length + FMS); + + assertEq(compact, abi.decode(res, (bytes32))); + } + + function test_read_nonce(uint160 _space, uint96 _nonce) external { + bytes memory encoded = abi.encodePacked(encodeWord(_space), encodeWord(_nonce)); + + (bool s, bytes memory r) = imp.staticcall(encoded); + + assertTrue(s); + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + assertEq(rindex, encoded.length); + assertEq(windex, res.length + FMS); + + assertEq(abi.encodePacked(_space, _nonce), res); + } +} diff --git a/packages/wallet/wallet-contracts/foundry_test/modules/utils/L2CompressorHuffReadTx.t.sol b/packages/wallet/wallet-contracts/foundry_test/modules/utils/L2CompressorHuffReadTx.t.sol new file mode 100644 index 0000000000..a8682f1daf --- /dev/null +++ b/packages/wallet/wallet-contracts/foundry_test/modules/utils/L2CompressorHuffReadTx.t.sol @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import "foundry_test/base/AdvTest.sol"; + +import "forge-std/console.sol"; +import "forge-std/console2.sol"; + +import {HuffConfig} from "foundry-huff/HuffConfig.sol"; +import {HuffDeployer} from "foundry-huff/HuffDeployer.sol"; + +import "contracts/modules/commons/interfaces/IModuleCalls.sol"; + +import "./L2CompressorEncoder.sol"; + +uint256 constant FMS = 0xa0; + +contract L2CompressorHuffReadTxTests is AdvTest { + address public imp; + + function setUp() public { + imp = address(HuffDeployer.config().with_evm_version("paris").deploy("imps/L2CompressorReadTx")); + } + + function test_read_simple_transaction(address _addr) external { + bytes memory encoded = abi.encodePacked(build_flag(true, true, false, false, false), encode_raw_address(_addr)); + + (bool s, bytes memory r) = imp.staticcall(encoded); + + assertTrue(s); + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + IModuleCalls.Transaction memory t; + t.delegateCall = true; + t.revertOnError = true; + t.target = _addr; + + assertEq(rindex, encoded.length); + assertEq(windex, res.length + FMS); + + // Abi encode prefixes with the point on which the data starts + // we don't do it on the compressor, so we need to append 32 + assertEq(abi.encodePacked(abi.encode(32), res), abi.encode(t)); + } + + function test_read_simple_transaction_with_data(address _addr, bytes memory _data) external { + bytes memory encoded = abi.encodePacked( + build_flag(true, true, false, false, true), encode_raw_address(_addr), encode_bytes_n(_data) + ); + + (bool s, bytes memory r) = imp.staticcall(encoded); + + assertTrue(s); + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + IModuleCalls.Transaction memory t; + t.delegateCall = true; + t.revertOnError = true; + t.target = _addr; + t.data = _data; + + assertEq(rindex, encoded.length); + assertEq(windex, res.length + FMS); + + // Abi encode prefixes with the point on which the data starts + // we don't do it on the compressor, so we need to append 32 + assertEq(abi.encodePacked(abi.encode(32), res), abi.encode(t)); + } + + function test_read_transaction(IModuleCalls.Transaction memory _tx) external { + bytes memory encoded = abi.encodePacked( + build_flag(_tx.delegateCall, _tx.revertOnError, _tx.gasLimit != 0, _tx.value != 0, _tx.data.length != 0), + _tx.gasLimit != 0 ? encodeWord(_tx.gasLimit) : bytes(""), + encode_raw_address(_tx.target), + _tx.value != 0 ? encodeWord(_tx.value) : bytes(""), + _tx.data.length != 0 ? encode_bytes_n(_tx.data) : bytes("") + ); + + console.logBytes(encoded); + + (bool s, bytes memory r) = imp.staticcall(encoded); + + assertTrue(s); + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(rindex, encoded.length); + assertEq(windex, res.length + FMS); + + // Abi encode prefixes with the point on which the data starts + // we don't do it on the compressor, so we need to append 32 + assertEq(abi.encodePacked(abi.encode(32), res), abi.encode(_tx)); + } +} diff --git a/packages/wallet/wallet-contracts/foundry_test/modules/utils/L2CompressorHuffReadTxs.t.sol b/packages/wallet/wallet-contracts/foundry_test/modules/utils/L2CompressorHuffReadTxs.t.sol new file mode 100644 index 0000000000..499a2c26f6 --- /dev/null +++ b/packages/wallet/wallet-contracts/foundry_test/modules/utils/L2CompressorHuffReadTxs.t.sol @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import "foundry_test/base/AdvTest.sol"; + +import "forge-std/console.sol"; +import "forge-std/console2.sol"; + +import {HuffConfig} from "foundry-huff/HuffConfig.sol"; +import {HuffDeployer} from "foundry-huff/HuffDeployer.sol"; + +import "contracts/modules/commons/interfaces/IModuleCalls.sol"; + +uint256 constant FMS = 0xa0; + +import "./L2CompressorEncoder.sol"; + +contract L2CompressorHuffReadTxTests is AdvTest { + address public imp; + + function setUp() public { + imp = address(HuffDeployer.config().with_evm_version("paris").deploy("imps/L2CompressorReadTxs")); + } + + function test_read_simple_2_transactions() external { + address _addr = address(0x1234567890123456789012345678901234567890); + address _addr2 = address(this); + bytes memory encoded = abi.encodePacked( + uint8(0x02), + build_flag(false, true, false, false, false), + encode_raw_address(_addr), + build_flag(true, true, false, false, false), + encode_raw_address(_addr2) + ); + + (bool s, bytes memory r) = imp.staticcall{gas: 10000}(encoded); + + assertTrue(s); + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + IModuleCalls.Transaction[] memory t = new IModuleCalls.Transaction[](2); + t[0].delegateCall = false; + t[0].revertOnError = true; + t[0].target = _addr; + t[1].delegateCall = true; + t[1].revertOnError = true; + t[1].target = _addr2; + + assertEq(rindex, encoded.length); + assertEq(windex, res.length + FMS); + + // Abi encode prefixes with the point on which the data starts + // we don't do it on the compressor, so we need to append 32 + assertEq(abi.encodePacked(abi.encode(32), res), abi.encode(t)); + } + + function test_read_simple_2_transactions_asymetric() external { + address _addr = address(0x1234567890123456789012345678901234567890); + address _addr2 = address(this); + bytes memory _data = hex"123456789012345678901234567890123456789012345678901234567890123456789011222211"; + + bytes memory encoded = abi.encodePacked( + uint8(0x02), + build_flag(false, true, false, false, true), + encode_raw_address(_addr), + encode_bytes_n(_data), + build_flag(true, true, false, false, false), + encode_raw_address(_addr2) + ); + + (bool s, bytes memory r) = imp.staticcall{gas: 10000}(encoded); + + assertTrue(s); + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + IModuleCalls.Transaction[] memory t = new IModuleCalls.Transaction[](2); + t[0].delegateCall = false; + t[0].revertOnError = true; + t[0].target = _addr; + t[0].data = _data; + t[1].delegateCall = true; + t[1].revertOnError = true; + t[1].target = _addr2; + + assertEq(rindex, encoded.length); + assertEq(windex, res.length + FMS); + + // Abi encode prefixes with the point on which the data starts + // we don't do it on the compressor, so we need to append 32 + assertEq(abi.encodePacked(abi.encode(32), res), abi.encode(t)); + } + + function test_read_transactions(IModuleCalls.Transaction[] memory _txs) external { + vm.assume(_txs.length != 0 && _txs.length <= type(uint8).max); + + bytes memory encoded = abi.encodePacked(uint8(_txs.length)); + + for (uint256 i = 0; i < _txs.length; i++) { + IModuleCalls.Transaction memory t = _txs[i]; + + encoded = abi.encodePacked( + encoded, + build_flag(t.delegateCall, t.revertOnError, t.gasLimit != 0, t.value != 0, t.data.length != 0), + t.gasLimit != 0 ? encodeWord(t.gasLimit) : bytes(""), + encode_raw_address(t.target), + t.value != 0 ? encodeWord(t.value) : bytes(""), + t.data.length != 0 ? encode_bytes_n(t.data) : bytes("") + ); + } + + (bool s, bytes memory r) = imp.staticcall(encoded); + + assertTrue(s); + (uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes)); + + assertEq(rindex, encoded.length); + assertEq(windex, res.length + FMS); + + // Abi encode prefixes with the point on which the data starts + // we don't do it on the compressor, so we need to append 32 + assertEq(abi.encodePacked(abi.encode(32), res), abi.encode(_txs)); + } +} diff --git a/packages/wallet/wallet-contracts/foundry_test/modules/utils/RequireUtils.t.sol b/packages/wallet/wallet-contracts/foundry_test/modules/utils/RequireUtils.t.sol new file mode 100644 index 0000000000..370c53726d --- /dev/null +++ b/packages/wallet/wallet-contracts/foundry_test/modules/utils/RequireUtils.t.sol @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "contracts/Factory.sol"; +import "contracts/modules/commons/ModuleCalls.sol"; +import "contracts/modules/utils/RequireUtils.sol"; + +import "contracts/mocks/ERC20Mock.sol"; +import "contracts/mocks/ERC721Mock.sol"; +import "contracts/mocks/ERC1155Mock.sol"; + +import "foundry_test/base/AdvTest.sol"; + +contract ModuleCallsImp is ModuleCalls { + function writeNonce(uint256 _space, uint256 _nonce) external { + _writeNonce(_space, _nonce); + } + + // Module Auth imp + mapping(bytes32 => mapping(bytes => bytes32)) public sigToSubdigest; + mapping(bytes32 => mapping(bytes => bool)) public sigToIsValid; + + function _signatureValidation(bytes32 _digest, bytes calldata _signature) + internal + view + override + returns (bool, bytes32) + {} + + function signatureRecovery(bytes32, bytes calldata) + public + view + override + returns (uint256, uint256, bytes32, bytes32, uint256) + {} + + function _isValidImage(bytes32) internal view override returns (bool) {} + + function updateImageHash(bytes32) external override {} + + function _updateImageHash(bytes32) internal override {} +} + +contract RequireUtilsTest is AdvTest { + ModuleCallsImp private imp; + RequireUtils private requireUtils; + ERC20Mock private erc20; + ERC721Mock private erc721; + ERC1155Mock private erc1155; + + function setUp() external { + requireUtils = new RequireUtils(); + ModuleCallsImp template = new ModuleCallsImp(); + Factory factory = new Factory(); + imp = ModuleCallsImp(factory.deploy(address(template), bytes32(0))); + erc20 = new ERC20Mock(1000 * 10 ** 18); + erc721 = new ERC721Mock(); + erc1155 = new ERC1155Mock(); + } + + function test_requireNonExpired(uint256 _expiration) external { + if (block.timestamp >= _expiration) { + vm.expectRevert(bytes("RequireUtils#requireNonExpired: EXPIRED")); + } + requireUtils.requireNonExpired(_expiration); + } + + function test_requireMinNonce(uint160 _space, uint96 _nonce, uint96 _nonceToCheck) external { + imp.writeNonce(_space, _nonce); + uint256 encoded = abi.decode(abi.encodePacked(_space, _nonceToCheck), (uint256)); + if (_nonce < _nonceToCheck) { + vm.expectRevert(bytes("RequireUtils#requireMinNonce: NONCE_BELOW_REQUIRED")); + } + requireUtils.requireMinNonce(address(imp), encoded); + } + + function test_requireMinNonceWithExactNonce(uint160 _space, uint96 _nonce) external { + imp.writeNonce(_space, _nonce); + uint256 encoded = abi.decode(abi.encodePacked(_space, _nonce), (uint256)); + requireUtils.requireMinNonce(address(imp), encoded); + } + + function test_requireMinERC20Balance(uint256 _minBalance) external { + uint256 balance = erc20.balanceOf(address(this)); + + if (balance < _minBalance) { + vm.expectRevert(bytes("RequireUtils#requireMinERC20Balance: BALANCE_TOO_LOW")); + } + requireUtils.requireMinERC20Balance(address(erc20), address(this), _minBalance); + } + + function test_requireMinERC20Allowance(uint256 _minAllowance) external { + erc20.approve(address(imp), 100 * 10 ** 18); + + uint256 allowance = erc20.allowance(address(this), address(imp)); + + if (allowance < _minAllowance) { + vm.expectRevert(bytes("RequireUtils#requireMinERC20Allowance: ALLOWANCE_TOO_LOW")); + } + requireUtils.requireMinERC20Allowance(address(erc20), address(this), address(imp), _minAllowance); + } + + function test_requireERC721Ownership(uint256 _tokenId) external { + if (_tokenId % 2 == 0) { + erc721.mint(address(imp), _tokenId); + } else { + erc721.mint(address(this), _tokenId); + } + + if (erc721.ownerOf(_tokenId) != address(this)) { + vm.expectRevert(bytes("RequireUtils#requireERC721Ownership: NOT_OWNER")); + } + requireUtils.requireERC721Ownership(address(erc721), address(this), _tokenId); + } + + function test_requireERC721Approval(uint256 _tokenId) external { + erc721.mint(address(this), _tokenId); + + if (_tokenId % 2 == 0) { + erc721.approve(address(imp), _tokenId); + } + + if (_tokenId % 5 == 0) { + erc721.setApprovalForAll(address(imp), true); + } + + address approved = erc721.getApproved(_tokenId); + + if (approved != address(imp) && !erc721.isApprovedForAll(address(this), address(imp))) { + vm.expectRevert(bytes("RequireUtils#requireERC721Approval: NOT_APPROVED")); + } + requireUtils.requireERC721Approval(address(erc721), address(this), address(imp), _tokenId); + } + + function test_requireMinERC1155Balance(uint256 _tokenId, uint256 _minBalance) external { + if (_tokenId % 2 == 0) { + erc1155.mint(address(this), _tokenId, _minBalance); + } + + uint256 balance = erc1155.balanceOf(address(this), _tokenId); + + if (balance < _minBalance) { + vm.expectRevert(bytes("RequireUtils#requireMinERC1155Balance: BALANCE_TOO_LOW")); + } + requireUtils.requireMinERC1155Balance(address(erc1155), address(this), _tokenId, _minBalance); + } + + function test_requireERC1155Approval(uint256 _tokenId) external { + if (_tokenId % 2 == 0) { + erc1155.setApprovalForAll(address(imp), true); + } + + if (!erc1155.isApprovedForAll(address(this), address(imp))) { + vm.expectRevert(bytes("RequireUtils#requireERC1155Approval: NOT_APPROVED")); + } + requireUtils.requireERC1155Approval(address(erc1155), address(this), address(imp)); + } +} diff --git a/packages/wallet/wallet-contracts/foundry_test/trust/Trust.t.sol b/packages/wallet/wallet-contracts/foundry_test/trust/Trust.t.sol new file mode 100644 index 0000000000..3563991e8a --- /dev/null +++ b/packages/wallet/wallet-contracts/foundry_test/trust/Trust.t.sol @@ -0,0 +1,867 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "contracts/trust/Trust.sol"; +import "contracts/interfaces/IERC1271Wallet.sol"; + +import "foundry_test/base/AdvTest.sol"; + +function min(uint256 a, uint256 b) pure returns (uint256) { + return a < b ? a : b; +} + +contract MockFail { + bytes revertData; + + constructor(bytes memory _revertData) { + revertData = _revertData; + } + + fallback() external payable { + bytes memory rd = revertData; + assembly { + revert(add(rd, 0x20), mload(rd)) + } + } +} + +contract MockContractSigner { + mapping(bytes32 => mapping(bytes => bytes4)) public staticSignatures; + bytes public staticRevertErr; + bool public staticReverts; + + function isValidSignature(bytes32 _hash, bytes calldata _signature) external view returns (bytes4 magicValue) { + if (staticReverts) { + bytes memory rd = staticRevertErr; + assembly { + revert(add(rd, 0x20), mload(rd)) + } + } + + return staticSignatures[_hash][_signature]; + } + + function setSignature(bytes32 _hash, bytes calldata _signature, bytes4 _magicValue) external { + staticSignatures[_hash][_signature] = _magicValue; + } + + function setRevertErr(bool _reverts, bytes calldata _revertErr) external { + staticRevertErr = _revertErr; + staticReverts = _reverts; + } +} + +contract TrustTest is AdvTest { + Trust private trust; + + function test_define_initial_parameters(uint256 _ownerPk, uint256 _beneficiaryPk, uint256 _duration) external { + trust = new Trust(vm.addr(boundPk(_ownerPk)), vm.addr(boundPk(_beneficiaryPk)), _duration); + assertEq(trust.owner(), vm.addr(boundPk(_ownerPk))); + assertEq(trust.beneficiary(), vm.addr(boundPk(_beneficiaryPk))); + assertEq(trust.duration(), _duration); + } + + function test_start_locked(uint256 _ownerPk, uint256 _beneficiaryPk, uint256 _duration) external { + trust = new Trust(vm.addr(boundPk(_ownerPk)), vm.addr(boundPk(_beneficiaryPk)), _duration); + assertEq(trust.isLocked(), true); + } + + function test_fail_schedule_unlock_too_early( + uint256 _ownerPk, + uint256 _beneficiaryPk, + uint256 _duration, + uint256 _schedule + ) external { + vm.assume(_duration != 0); + + _schedule = bound(_schedule, 0, _duration - 1); + trust = new Trust(vm.addr(boundPk(_ownerPk)), vm.addr(boundPk(_beneficiaryPk)), _duration); + + vm.prank(vm.addr(boundPk(_ownerPk))); + vm.expectRevert( + abi.encodeWithSignature("UnlockTooEarly(uint256,uint256)", block.timestamp + _schedule, _schedule) + ); + trust.setUnlocksAt(block.timestamp + _schedule); + + vm.prank(vm.addr(boundPk(_beneficiaryPk))); + vm.expectRevert( + abi.encodeWithSignature("UnlockTooEarly(uint256,uint256)", block.timestamp + _schedule, _schedule) + ); + trust.setUnlocksAt(block.timestamp + _schedule); + } + + function test_fail_schedule_in_the_past( + uint256 _ownerPk, + uint256 _beneficiaryPk, + uint256 _duration, + uint256 _schedule + ) external { + _schedule = bound(_schedule, 1, block.timestamp); + trust = new Trust(vm.addr(boundPk(_ownerPk)), vm.addr(boundPk(_beneficiaryPk)), _duration); + + vm.prank(vm.addr(boundPk(_ownerPk))); + vm.expectRevert( + abi.encodeWithSignature("UnlockInThePast(uint256,uint256)", block.timestamp - _schedule, _schedule) + ); + trust.setUnlocksAt(block.timestamp - _schedule); + + vm.prank(vm.addr(boundPk(_beneficiaryPk))); + vm.expectRevert( + abi.encodeWithSignature("UnlockInThePast(uint256,uint256)", block.timestamp - _schedule, _schedule) + ); + trust.setUnlocksAt(block.timestamp - _schedule); + } + + function test_fail_schedule_non_allowed( + uint256 _ownerPk, + uint256 _beneficiaryPk, + uint256 _badActorpk, + uint256 _duration, + uint256 _unlockAt + ) external { + _badActorpk = boundDiff(boundPk(_badActorpk), boundPk(_ownerPk), boundPk(_beneficiaryPk)); + + trust = new Trust(vm.addr(boundPk(_ownerPk)), vm.addr(boundPk(_beneficiaryPk)), _duration); + + vm.prank(vm.addr(boundPk(_badActorpk))); + vm.expectRevert(abi.encodeWithSignature("NotOwner(address)", vm.addr(boundPk(_badActorpk)))); + trust.setUnlocksAt(_unlockAt); + } + + event SetUnlocksAt(uint256 _unlocksAt); + + function test_schedule_unlock( + uint256 _ownerPk, + uint256 _beneficiaryPk, + bool _asOwner, + uint256 _duration, + uint256 _unlockAt + ) external { + _duration = bound(_duration, 0, type(uint256).max - block.timestamp); + _unlockAt = bound(_unlockAt, block.timestamp + _duration, type(uint256).max); + + trust = new Trust(vm.addr(boundPk(_ownerPk)), vm.addr(boundPk(_beneficiaryPk)), _duration); + + vm.prank(vm.addr(boundPk(_asOwner ? _ownerPk : _beneficiaryPk))); + + vm.expectEmit(true, true, true, true, address(trust)); + emit SetUnlocksAt(_unlockAt); + + trust.setUnlocksAt(_unlockAt); + assertEq(trust.unlocksAt(), _unlockAt); + } + + function test_wait_for_unlock( + uint256 _ownerPk, + uint256 _beneficiaryPk, + uint256 _duration, + uint256 _unlockAt, + uint256 _extra + ) external { + vm.assume(block.timestamp != type(uint256).max); + + _duration = bound(_duration, 0, (type(uint256).max - 1) - block.timestamp); + _unlockAt = bound(_unlockAt, block.timestamp + _duration, type(uint256).max - 1); + _extra = bound(_extra, 0, type(uint256).max - _unlockAt); + + trust = new Trust(vm.addr(boundPk(_ownerPk)), vm.addr(boundPk(_beneficiaryPk)), _duration); + + vm.prank(vm.addr(boundPk(_beneficiaryPk))); + trust.setUnlocksAt(_unlockAt); + + if (_duration > 0) { + vm.prank(vm.addr(boundPk(_beneficiaryPk))); + assertEq(trust.isLocked(), true); + } + + vm.warp(_unlockAt + _extra); + assertEq(trust.isLocked(), false); + } + + function gen_and_unlock( + uint256 _ownerPk, + uint256 _beneficiaryPk, + uint256 _duration, + uint256 _unlockAt, + uint256 _extra + ) internal returns (Trust) { + _duration = bound(_duration, 0, (type(uint256).max - 1) - block.timestamp); + _unlockAt = bound(_unlockAt, block.timestamp + _duration, type(uint256).max - 1); + _extra = bound(_extra, 0, type(uint256).max - _unlockAt); + + trust = new Trust(vm.addr(boundPk(_ownerPk)), vm.addr(boundPk(_beneficiaryPk)), _duration); + + vm.prank(vm.addr(boundPk(_beneficiaryPk))); + trust.setUnlocksAt(_unlockAt); + + vm.warp(_unlockAt + _extra); + + return trust; + } + + event SentTransaction(address _to, uint256 _value, bytes _data, bytes _result); + + function test_send_transaction_after_unlock( + uint256 _ownerPk, + uint256 _beneficiaryPk, + bool _ownerSender, + uint256 _duration, + uint256 _unlockAt, + uint256 _extra, + uint256 _toPk, + uint256 _value, + bytes calldata _data + ) external { + Trust t = gen_and_unlock(_ownerPk, _beneficiaryPk, _duration, _unlockAt, _extra); + + vm.deal(address(this), _value); + payable(address((t))).transfer(_value); + + vm.prank(vm.addr(boundPk(_ownerSender ? _ownerPk : _beneficiaryPk))); + vm.expectCall(vm.addr(boundPk(_toPk)), _value, _data); + + vm.expectEmit(true, true, true, true, address(t)); + emit SentTransaction(vm.addr(boundPk(_toPk)), _value, _data, new bytes(0)); + + t.sendTransaction(payable(vm.addr(boundPk(_toPk))), _value, _data); + + assertEq(vm.addr(boundPk(_toPk)).balance, _value); + } + + function test_send_transaction_pre_unlock_as_owner( + uint256 _ownerPk, + uint256 _beneficiaryPk, + uint256 _duration, + uint256 _unlockAt, + uint256 _toPk, + uint256 _value, + bytes calldata _data + ) external { + _duration = bound(_duration, 0, type(uint256).max - block.timestamp); + _unlockAt = bound(_unlockAt, block.timestamp + _duration, type(uint256).max); + + Trust t = new Trust(vm.addr(boundPk(_ownerPk)), vm.addr(boundPk(_beneficiaryPk)), _duration); + + vm.deal(address(this), _value); + payable(address((t))).transfer(_value); + + vm.prank(vm.addr(boundPk(_beneficiaryPk))); + t.setUnlocksAt(_unlockAt); + + vm.prank(vm.addr(boundPk(_ownerPk))); + vm.expectCall(vm.addr(boundPk(_toPk)), _value, _data); + t.sendTransaction(payable(vm.addr(boundPk(_toPk))), _value, _data); + } + + function test_fail_send_transaction_pre_unlock_as_beneficiary( + uint256 _ownerPk, + uint256 _beneficiaryPk, + uint256 _duration, + uint256 _unlockAt, + uint256 _toPk, + uint256 _value, + uint256 _elapsed, + bytes calldata _data + ) external { + _duration = bound(_duration, 1, type(uint256).max - block.timestamp); + _unlockAt = bound(_unlockAt, block.timestamp + _duration, type(uint256).max); + _elapsed = bound(_elapsed, 0, (_unlockAt - block.timestamp) - 1); + + vm.assume(vm.addr(boundPk(_ownerPk)) != vm.addr(boundPk(_beneficiaryPk))); + + Trust t = new Trust(vm.addr(boundPk(_ownerPk)), vm.addr(boundPk(_beneficiaryPk)), _duration); + + vm.deal(address(this), _value); + payable(address((t))).transfer(_value); + + vm.prank(vm.addr(boundPk(_beneficiaryPk))); + t.setUnlocksAt(_unlockAt); + + vm.warp(block.timestamp + _elapsed); + + assertEq(t.isLocked(), true); + + vm.prank(vm.addr(boundPk(_beneficiaryPk))); + vm.expectRevert(abi.encodeWithSignature("NotUnlocked(uint256)", _unlockAt)); + t.sendTransaction(payable(vm.addr(boundPk(_toPk))), _value, _data); + } + + function test_fail_send_transaction_non_allowed( + uint256 _ownerPk, + uint256 _beneficiaryPk, + uint256 _badActorPk, + uint256 _duration, + uint256 _unlockAt, + uint256 _elapsed, + uint256 _toPk, + uint256 _value, + bytes calldata _data + ) external { + _duration = bound(_duration, 0, type(uint256).max - block.timestamp); + _unlockAt = bound(_unlockAt, block.timestamp + _duration, type(uint256).max); + _elapsed = bound(_elapsed, 0, type(uint256).max - block.timestamp); + + _badActorPk = boundDiff(boundPk(_badActorPk), boundPk(_ownerPk), boundPk(_beneficiaryPk)); + + Trust t = new Trust(vm.addr(boundPk(_ownerPk)), vm.addr(boundPk(_beneficiaryPk)), _duration); + + vm.deal(address(this), _value); + payable(address((t))).transfer(_value); + + vm.prank(vm.addr(boundPk(_beneficiaryPk))); + t.setUnlocksAt(_unlockAt); + + vm.warp(block.timestamp + _elapsed); + + vm.prank(vm.addr(boundPk(_badActorPk))); + vm.expectRevert(abi.encodeWithSignature("NotOwner(address)", vm.addr(boundPk(_badActorPk)))); + t.sendTransaction(payable(vm.addr(boundPk(_toPk))), _value, _data); + } + + function test_fail_bubble_up_fail( + uint256 _ownerPk, + uint256 _beneficiaryPk, + bool _ownerSender, + uint256 _duration, + uint256 _unlockAt, + uint256 _value, + uint256 _extra, + bytes calldata _data, + bytes calldata _revertData + ) external { + address sender = vm.addr(boundPk(_ownerSender ? _ownerPk : _beneficiaryPk)); + + Trust t = gen_and_unlock(_ownerPk, _beneficiaryPk, _duration, _unlockAt, _extra); + + vm.deal(address(this), _value); + payable(address((t))).transfer(_value); + + MockFail mf = new MockFail(_revertData); + + vm.prank(sender); + + vm.expectRevert( + abi.encodeWithSignature( + "FailedTransaction(address,uint256,bytes,bytes)", address(mf), _value, _data, _revertData + ) + ); + + t.sendTransaction(payable(address(mf)), _value, _data); + } + + function test_isValidSignature( + uint256 _ownerPk, + uint256 _beneficiaryPk, + uint256 _duration, + uint256 _unlockAt, + uint256 _extra, + bool _signedByOwner, + bytes calldata _message + ) external { + uint256 signerPk = boundPk(_signedByOwner ? _ownerPk : _beneficiaryPk); + + Trust t = gen_and_unlock(_ownerPk, _beneficiaryPk, _duration, _unlockAt, _extra); + + bytes32 rawHash = keccak256(_message); + bytes32 finalHash = keccak256(abi.encode(address(t), rawHash, block.chainid)); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(signerPk, finalHash); + + bytes memory sig = abi.encodePacked(r, s, v, uint8(1), _signedByOwner ? bytes1(0x00) : bytes1(0x01)); + + assertEq(t.isValidSignature(rawHash, sig), bytes4(0x1626ba7e)); + assertEq(t.isValidSignature(_message, sig), bytes4(0x20c13b0b)); + } + + function test_isValidSignature_anyNetwork( + uint256 _ownerPk, + uint256 _beneficiaryPk, + uint256 _duration, + uint256 _unlockAt, + uint256 _extra, + uint64 _useChainId, + bool _signedByOwner, + bytes calldata _message + ) external { + uint256 signerPk = boundPk(_signedByOwner ? _ownerPk : _beneficiaryPk); + + Trust t = gen_and_unlock(_ownerPk, _beneficiaryPk, _duration, _unlockAt, _extra); + + bytes32 rawHash = keccak256(_message); + bytes32 finalHash = keccak256(abi.encode(address(t), rawHash, 0)); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(signerPk, finalHash); + + bytes memory sig = abi.encodePacked(r, s, v, uint8(1), _signedByOwner ? bytes1(0x02) : bytes1(0x03)); + + vm.chainId(_useChainId); + assertEq(t.isValidSignature(rawHash, sig), bytes4(0x1626ba7e)); + assertEq(t.isValidSignature(_message, sig), bytes4(0x20c13b0b)); + } + + function test_fail_isValidSignature_anyNetwork_wrongEncode( + uint256 _ownerPk, + uint256 _beneficiaryPk, + uint256 _duration, + uint256 _unlockAt, + uint256 _extra, + uint64 _useChainId, + bool _signedByOwner, + bytes calldata _message + ) external { + vm.assume(_useChainId != 0); + + uint256 signerPk = boundPk(_signedByOwner ? _ownerPk : _beneficiaryPk); + + Trust t = gen_and_unlock(_ownerPk, _beneficiaryPk, _duration, _unlockAt, _extra); + + bytes32 rawHash = keccak256(_message); + bytes32 finalHash = keccak256(abi.encode(address(t), rawHash, 0)); + bytes32 realHash = keccak256(abi.encode(address(t), rawHash, _useChainId)); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(signerPk, finalHash); + + bytes memory sig = abi.encodePacked(r, s, v, uint8(1), _signedByOwner ? bytes1(0x00) : bytes1(0x01)); + + vm.chainId(_useChainId); + + bytes memory revertErr = abi.encodeWithSignature( + "InvalidSignature(bytes32,bytes32,address,bytes)", + rawHash, + realHash, + vm.addr(signerPk), + abi.encodePacked(r, s, v, uint8(1)) + ); + + vm.expectRevert(revertErr); + t.isValidSignature(rawHash, sig); + + vm.expectRevert(revertErr); + t.isValidSignature(_message, sig); + } + + function test_fail_isValidSignature_anyNetwork_onlyEncode( + uint256 _ownerPk, + uint256 _beneficiaryPk, + uint256 _duration, + uint256 _unlockAt, + uint256 _extra, + uint64 _useChainId, + bool _signedByOwner, + bytes calldata _message + ) external { + vm.assume(_useChainId != 0); + + uint256 signerPk = boundPk(_signedByOwner ? _ownerPk : _beneficiaryPk); + + Trust t = gen_and_unlock(_ownerPk, _beneficiaryPk, _duration, _unlockAt, _extra); + + bytes32 rawHash = keccak256(_message); + bytes32 finalHash = keccak256(abi.encode(address(t), rawHash, _useChainId)); + bytes32 realHash = keccak256(abi.encode(address(t), rawHash, 0)); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(signerPk, finalHash); + + bytes memory sig = abi.encodePacked(r, s, v, uint8(1), _signedByOwner ? bytes1(0x02) : bytes1(0x03)); + + vm.chainId(_useChainId); + + bytes memory revertErr = abi.encodeWithSignature( + "InvalidSignature(bytes32,bytes32,address,bytes)", + rawHash, + realHash, + vm.addr(signerPk), + abi.encodePacked(r, s, v, uint8(1)) + ); + + vm.expectRevert(revertErr); + t.isValidSignature(rawHash, sig); + + vm.expectRevert(revertErr); + t.isValidSignature(_message, sig); + } + + function test_isValidSignature_pre_unlock_as_owner( + uint256 _ownerPk, + uint256 _beneficiaryPk, + uint256 _duration, + uint256 _unlockAt, + bytes calldata _message + ) external { + _duration = bound(_duration, 0, type(uint256).max - block.timestamp); + _unlockAt = bound(_unlockAt, block.timestamp + _duration, type(uint256).max); + + Trust t = new Trust(vm.addr(boundPk(_ownerPk)), vm.addr(boundPk(_beneficiaryPk)), _duration); + + vm.prank(vm.addr(boundPk(_beneficiaryPk))); + t.setUnlocksAt(_unlockAt); + + bytes32 rawHash = keccak256(_message); + bytes32 finalHash = keccak256(abi.encode(address(t), rawHash, block.chainid)); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(boundPk(_ownerPk), finalHash); + + bytes memory sig = abi.encodePacked(r, s, v, uint8(1), bytes1(0x00)); + + assertEq(t.isValidSignature(rawHash, sig), bytes4(0x1626ba7e)); + assertEq(t.isValidSignature(_message, sig), bytes4(0x20c13b0b)); + } + + function test_fail_isValidSignature_emptySignature( + uint256 _ownerPk, + uint256 _beneficiaryPk, + uint256 _duration, + uint256 _unlockAt, + bytes calldata _message + ) external { + _duration = bound(_duration, 0, type(uint256).max - block.timestamp); + _unlockAt = bound(_unlockAt, block.timestamp + _duration, type(uint256).max); + + Trust t = new Trust(vm.addr(boundPk(_ownerPk)), vm.addr(boundPk(_beneficiaryPk)), _duration); + + vm.prank(vm.addr(boundPk(_beneficiaryPk))); + t.setUnlocksAt(_unlockAt); + + bytes memory sig = new bytes(0); + + vm.expectRevert(abi.encodeWithSignature("EmptySignature()")); + t.isValidSignature(_message, sig); + + vm.expectRevert(abi.encodeWithSignature("EmptySignature()")); + t.isValidSignature(keccak256(_message), sig); + } + + function test_fail_isValidSignature_wrongSignatureFlag( + uint256 _ownerPk, + uint256 _beneficiaryPk, + uint256 _duration, + uint256 _unlockAt, + uint8 _signerFlag, + bytes calldata _signature, + bytes calldata _message + ) external { + _duration = bound(_duration, 0, type(uint256).max - block.timestamp); + _unlockAt = bound(_unlockAt, block.timestamp + _duration, type(uint256).max); + _signerFlag = uint8(bound(_signerFlag, 4, type(uint8).max)); + + Trust t = new Trust(vm.addr(boundPk(_ownerPk)), vm.addr(boundPk(_beneficiaryPk)), _duration); + + vm.prank(vm.addr(boundPk(_beneficiaryPk))); + t.setUnlocksAt(_unlockAt); + + bytes memory sig = abi.encodePacked(_signature, _signerFlag); + + vm.expectRevert(abi.encodeWithSignature("InvalidSignatureFlag(bytes,bytes1)", sig, bytes1(_signerFlag))); + t.isValidSignature(_message, sig); + + vm.expectRevert(abi.encodeWithSignature("InvalidSignatureFlag(bytes,bytes1)", sig, bytes1(_signerFlag))); + t.isValidSignature(keccak256(_message), sig); + } + + function test_fail_isValidSignature_pre_unlock_as_beneficiary( + uint256 _ownerPk, + uint256 _beneficiaryPk, + uint256 _duration, + uint256 _unlockAt, + bytes calldata _message + ) external { + _duration = bound(_duration, 1, type(uint256).max - block.timestamp); + _unlockAt = bound(_unlockAt, block.timestamp + _duration, type(uint256).max); + + vm.assume(boundPk(_ownerPk) != boundPk(_beneficiaryPk)); + Trust t = new Trust(vm.addr(boundPk(_ownerPk)), vm.addr(boundPk(_beneficiaryPk)), _duration); + + vm.prank(vm.addr(boundPk(_beneficiaryPk))); + t.setUnlocksAt(_unlockAt); + + bytes32 rawHash = keccak256(_message); + bytes32 finalHash = keccak256(abi.encode(address(t), rawHash, block.chainid)); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(boundPk(_beneficiaryPk), finalHash); + + bytes memory sig = abi.encodePacked(r, s, v, uint8(1), bytes1(0x01)); + + vm.expectRevert(abi.encodeWithSignature("NotUnlocked(uint256)", _unlockAt)); + t.isValidSignature(rawHash, sig); + + vm.expectRevert(abi.encodeWithSignature("NotUnlocked(uint256)", _unlockAt)); + t.isValidSignature(_message, sig); + } + + struct MemoryStruct1 { + bytes32 rawHash; + bytes32 finalHash; + uint8 v; + bytes32 r; + bytes32 s; + } + + function test_fail_isValidSignature_invalid_signature( + uint256 _ownerPk, + uint256 _beneficiaryPk, + uint256 _badSignerPk, + bool _signsOwner, + uint256 _duration, + uint256 _unlockAt, + bytes calldata _message + ) external { + _ownerPk = boundPk(_ownerPk); + _beneficiaryPk = boundPk(_beneficiaryPk); + _badSignerPk = boundPk(_badSignerPk); + + address expectedSigner = _signsOwner ? vm.addr(_ownerPk) : vm.addr(_beneficiaryPk); + + _duration = bound(_duration, 0, type(uint256).max - block.timestamp); + _unlockAt = bound(_unlockAt, block.timestamp + _duration, type(uint256).max); + + trust = new Trust(vm.addr(_ownerPk), vm.addr(_beneficiaryPk), _duration); + + vm.prank(vm.addr(_beneficiaryPk)); + trust.setUnlocksAt(_unlockAt); + + if (_signsOwner) { + vm.assume(_ownerPk != _badSignerPk); + } else { + vm.assume(_beneficiaryPk != _badSignerPk); + // Advance clock to unlock + vm.warp(_unlockAt); + } + + MemoryStruct1 memory m; + { + // Stack too deep manual workaround + bytes32 rawHash = keccak256(_message); + bytes32 finalHash = keccak256(abi.encode(address(trust), rawHash, block.chainid)); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(_badSignerPk, finalHash); + m.rawHash = rawHash; + m.finalHash = finalHash; + m.v = v; + m.r = r; + m.s = s; + } + + bytes memory sig = abi.encodePacked(m.r, m.s, m.v, uint8(1), _signsOwner ? bytes1(0x00) : bytes1(0x01)); + + bytes memory revertErr = abi.encodeWithSignature( + "InvalidSignature(bytes32,bytes32,address,bytes)", + m.rawHash, + m.finalHash, + expectedSigner, + abi.encodePacked(m.r, m.s, m.v, uint8(1)) + ); + + vm.expectRevert(revertErr); + trust.isValidSignature(m.rawHash, sig); + + vm.expectRevert(revertErr); + trust.isValidSignature(_message, sig); + } + + function test_accept_contract_signature_for_owner( + address _beneficiaryAddress, + uint256 _duration, + uint256 _unlockAt, + uint256 _elapsed, + bytes calldata _signature, + bytes calldata _message + ) external { + MockContractSigner mcs = new MockContractSigner(); + + _duration = bound(_duration, 0, type(uint256).max - block.timestamp); + _unlockAt = bound(_unlockAt, block.timestamp + _duration, type(uint256).max); + _elapsed = bound(_elapsed, 0, type(uint256).max - block.timestamp); + + trust = new Trust(address(mcs), _beneficiaryAddress, _duration); + + vm.prank(_beneficiaryAddress); + trust.setUnlocksAt(_unlockAt); + + vm.warp(block.timestamp + _elapsed); + + bytes32 rawHash = keccak256(_message); + bytes32 finalHash = keccak256(abi.encode(address(trust), rawHash, block.chainid)); + mcs.setSignature(finalHash, _signature, bytes4(0x1626ba7e)); + bytes memory sig = abi.encodePacked(_signature, uint8(3), bytes1(0x00)); + + assertEq(trust.isValidSignature(rawHash, sig), bytes4(0x1626ba7e)); + assertEq(trust.isValidSignature(_message, sig), bytes4(0x20c13b0b)); + } + + function test_fail_bad_contract_signature_for_owner( + address _beneficiaryAddress, + uint256 _duration, + uint256 _unlockAt, + uint256 _elapsed, + bytes4 _badReturnBytes, + bytes calldata _badSignature, + bytes calldata _message + ) external { + vm.assume(_badReturnBytes != bytes4(0x1626ba7e)); + + MockContractSigner mcs = new MockContractSigner(); + + _duration = bound(_duration, 0, type(uint256).max - block.timestamp); + _unlockAt = bound(_unlockAt, block.timestamp + _duration, type(uint256).max); + _elapsed = bound(_elapsed, 0, type(uint256).max - block.timestamp); + + trust = new Trust(address(mcs), _beneficiaryAddress, _duration); + + vm.prank(_beneficiaryAddress); + trust.setUnlocksAt(_unlockAt); + + vm.warp(block.timestamp + _elapsed); + + bytes32 rawHash = keccak256(_message); + bytes32 finalHash = keccak256(abi.encode(address(trust), rawHash, block.chainid)); + mcs.setSignature(finalHash, _badSignature, _badReturnBytes); + bytes memory sig = abi.encodePacked(_badSignature, uint8(3), bytes1(0x00)); + + bytes memory revertErr = abi.encodeWithSignature( + "InvalidSignature(bytes32,bytes32,address,bytes)", + rawHash, + finalHash, + address(mcs), + abi.encodePacked(_badSignature, uint8(3)) + ); + + vm.expectRevert(revertErr); + trust.isValidSignature(rawHash, sig); + + vm.expectRevert(revertErr); + trust.isValidSignature(_message, sig); + } + + function test_accept_contract_signature_for_beneficiary( + address _ownerAddress, + uint256 _duration, + uint256 _unlockAt, + uint256 _extra, + bytes calldata _signature, + bytes calldata _message + ) external { + MockContractSigner mcs = new MockContractSigner(); + + _duration = bound(_duration, 0, (type(uint256).max - 1) - block.timestamp); + _unlockAt = bound(_unlockAt, block.timestamp + _duration, type(uint256).max - 1); + _extra = bound(_extra, 0, type(uint256).max - _unlockAt); + + trust = new Trust(_ownerAddress, address(mcs), _duration); + + vm.prank(address(mcs)); + trust.setUnlocksAt(_unlockAt); + + vm.warp(_unlockAt + _extra); + + bytes32 rawHash = keccak256(_message); + bytes32 finalHash = keccak256(abi.encode(address(trust), rawHash, block.chainid)); + mcs.setSignature(finalHash, _signature, bytes4(0x1626ba7e)); + bytes memory sig = abi.encodePacked(_signature, uint8(3), bytes1(0x01)); + + assertEq(trust.isValidSignature(rawHash, sig), bytes4(0x1626ba7e)); + assertEq(trust.isValidSignature(_message, sig), bytes4(0x20c13b0b)); + } + + function test_fail_bad_contract_signature_for_beneficiary( + address _ownerAddress, + uint256 _duration, + uint256 _unlockAt, + uint256 _extra, + bytes4 _badReturnBytes, + bytes calldata _badSignature, + bytes calldata _message + ) external { + vm.assume(_badReturnBytes != bytes4(0x1626ba7e)); + + MockContractSigner mcs = new MockContractSigner(); + + _duration = bound(_duration, 0, (type(uint256).max - 1) - block.timestamp); + _unlockAt = bound(_unlockAt, block.timestamp + _duration, type(uint256).max - 1); + _extra = bound(_extra, 0, type(uint256).max - _unlockAt); + + trust = new Trust(_ownerAddress, address(mcs), _duration); + + vm.prank(address(mcs)); + trust.setUnlocksAt(_unlockAt); + + vm.warp(_unlockAt + _extra); + + bytes32 rawHash = keccak256(_message); + bytes32 finalHash = keccak256(abi.encode(address(trust), rawHash, block.chainid)); + mcs.setSignature(finalHash, _badSignature, _badReturnBytes); + bytes memory sig = abi.encodePacked(_badSignature, uint8(3), bytes1(0x01)); + + bytes memory revertErr = abi.encodeWithSignature( + "InvalidSignature(bytes32,bytes32,address,bytes)", + rawHash, + finalHash, + address(mcs), + abi.encodePacked(_badSignature, uint8(3)) + ); + + vm.expectRevert(revertErr); + trust.isValidSignature(rawHash, sig); + + vm.expectRevert(revertErr); + trust.isValidSignature(_message, sig); + } + + function test_fail_revert_contract_signer_owner( + address _beneficiaryAddress, + uint256 _duration, + uint256 _unlockAt, + uint256 _extra, + bytes calldata _revertErr, + bytes calldata _signature, + bytes calldata _message + ) external { + MockContractSigner mcs = new MockContractSigner(); + + _duration = bound(_duration, 0, type(uint256).max - block.timestamp); + _unlockAt = bound(_unlockAt, block.timestamp + _duration, type(uint256).max); + _extra = bound(_extra, 0, type(uint256).max - _unlockAt); + + trust = new Trust(address(mcs), _beneficiaryAddress, _duration); + + vm.prank(_beneficiaryAddress); + trust.setUnlocksAt(_unlockAt); + + vm.warp(block.timestamp + _extra); + + bytes32 rawHash = keccak256(_message); + mcs.setRevertErr(true, _revertErr); + bytes memory sig = abi.encodePacked(_signature, uint8(3), bytes1(0x00)); + + vm.expectRevert(_revertErr); + trust.isValidSignature(rawHash, sig); + + vm.expectRevert(_revertErr); + trust.isValidSignature(_message, sig); + } + + function test_fail_revert_contract_signer_beneficiary( + address _ownerAddress, + uint256 _duration, + uint256 _unlockAt, + uint256 _extra, + bytes calldata _revertErr, + bytes calldata _signature, + bytes calldata _message + ) external { + MockContractSigner mcs = new MockContractSigner(); + + _duration = bound(_duration, 0, (type(uint256).max - 1) - block.timestamp); + _unlockAt = bound(_unlockAt, block.timestamp + _duration, type(uint256).max - 1); + _extra = bound(_extra, 0, type(uint256).max - _unlockAt); + + trust = new Trust(_ownerAddress, address(mcs), _duration); + + vm.prank(address(mcs)); + trust.setUnlocksAt(_unlockAt); + + vm.warp(_unlockAt + _extra); + + bytes32 rawHash = keccak256(_message); + mcs.setRevertErr(true, _revertErr); + bytes memory sig = abi.encodePacked(_signature, uint8(3), bytes1(0x01)); + + vm.expectRevert(_revertErr); + trust.isValidSignature(rawHash, sig); + + vm.expectRevert(_revertErr); + trust.isValidSignature(_message, sig); + } +} diff --git a/packages/wallet/wallet-contracts/foundry_test/trust/TrustFactory.t.sol b/packages/wallet/wallet-contracts/foundry_test/trust/TrustFactory.t.sol new file mode 100644 index 0000000000..87e08cec25 --- /dev/null +++ b/packages/wallet/wallet-contracts/foundry_test/trust/TrustFactory.t.sol @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "contracts/trust/TrustFactory.sol"; + +import "foundry_test/base/AdvTest.sol"; + +contract TrustFactoryTest is AdvTest { + TrustFactory private factory; + + function setUp() external { + factory = new TrustFactory(); + } + + function test_create_trust(address _owner, address _beneficiary, uint256 _duration) external { + Trust trust = factory.deploy(_owner, _beneficiary, _duration); + address trustAddress = address(trust); + + assertEq(trust.owner(), _owner); + assertEq(trust.beneficiary(), _beneficiary); + assertEq(trust.duration(), _duration); + + uint256 codeSize; + assembly { codeSize := extcodesize(trustAddress) } + assertGt(codeSize, 0); + } + + function test_predict_address(address _owner, address _beneficiary, uint256 _duration) external { + address expected = factory.addressOf(_owner, _beneficiary, _duration); + address actual = address(factory.deploy(_owner, _beneficiary, _duration)); + assertEq(actual, expected); + } + + function test_fail_deploy_twice(address _owner, address _beneficiary, uint256 _duration) external { + factory.deploy(_owner, _beneficiary, _duration); + vm.expectRevert(); + factory.deploy(_owner, _beneficiary, _duration); + } + + function test_fail_deploy_low_gas(address _owner, address _beneficiary, uint256 _duration, uint256 _gas) external { + _gas = bound(_gas, 21000, block.gaslimit); + try factory.deploy{gas: _gas}(_owner, _beneficiary, _duration) returns (Trust trust) { + address trustAddress = address(trust); + // The address should have code, and never be the zero address + assertNotEq(trustAddress, address(0)); + uint256 codeSize; + assembly { codeSize := extcodesize(trustAddress) } + assertGt(codeSize, 0); + } catch { + // Ignore errors from low gas + } + } +} diff --git a/packages/wallet/wallet-contracts/foundry_test/utils/LibAddress.t.sol b/packages/wallet/wallet-contracts/foundry_test/utils/LibAddress.t.sol new file mode 100644 index 0000000000..525d6166bc --- /dev/null +++ b/packages/wallet/wallet-contracts/foundry_test/utils/LibAddress.t.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "contracts/utils/LibAddress.sol"; + +import "foundry_test/base/AdvTest.sol"; + +contract LibAddressTest is AdvTest { + function test_isContract(address _addr, bytes calldata _code) external { + boundNoSys(_addr); + + vm.etch(_addr, _code); + assertEq(LibAddress.isContract(_addr), _code.length > 0); + } +} diff --git a/packages/wallet/wallet-contracts/foundry_test/utils/LibBytes.t.sol b/packages/wallet/wallet-contracts/foundry_test/utils/LibBytes.t.sol new file mode 100644 index 0000000000..bfb5debae7 --- /dev/null +++ b/packages/wallet/wallet-contracts/foundry_test/utils/LibBytes.t.sol @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "contracts/utils/LibBytes.sol"; + +import "foundry_test/base/AdvTest.sol"; + +contract LibBytesImp { + using LibBytes for bytes; + + function readBytes32(bytes calldata _data, uint256 _index) external pure returns (bytes32) { + return _data.readBytes32(_index); + } + + function readUint8(bytes calldata _data, uint256 _index) external pure returns (uint8) { + return _data.readUint8(_index); + } + + function readFirstUint16(bytes calldata _data) external pure returns (uint16) { + return _data.readFirstUint16(); + } + + function readUint32(bytes calldata _data, uint256 _index) external pure returns (uint32) { + return _data.readUint32(_index); + } +} + +contract LibBytesTest is AdvTest { + LibBytesImp private lib; + + function setUp() external { + lib = new LibBytesImp(); + } + + function test_readBytes32(bytes calldata _prefix, bytes32 _data, bytes calldata _sufix) external { + bytes memory combined = abi.encodePacked(_prefix, _data, _sufix); + bytes32 actual = lib.readBytes32(combined, _prefix.length); + assertEq(actual, _data); + } + + function test_readBytes32_OutOfBounds(bytes calldata _data, uint256 _index) external view { + lib.readBytes32(_data, _index); + } + + function test_readBytes32_Fuzz_AbiDecode(bytes calldata _data, uint256 _index) external { + _index = bound(_index, 0, _data.length > 32 ? _data.length - 32 : 0); + bytes32 expected = abi.decode(abi.encodePacked(_data[_index:], bytes32(0)), (bytes32)); + bytes32 actual = lib.readBytes32(_data, _index); + assertEq(expected, actual); + } + + function test_readUint8(bytes calldata _prefix, uint8 _data, bytes calldata _sufix) external { + bytes memory combined = abi.encodePacked(_prefix, _data, _sufix); + uint8 expected = lib.readUint8(combined, _prefix.length); + assertEq(expected, _data); + } + + function test_readUint8_OutOfBounds(bytes calldata _data, uint256 _index) external view { + lib.readUint8(_data, _index); + } + + function test_readUint8_Fuzz_ReadByte(bytes calldata _data, uint256 _index) external { + vm.assume(_data.length >= 1); + + _index = bound(_index, 0, _data.length - 1); + uint8 expected = uint8(uint256(bytes32(_data[_index])) >> 248); + uint8 actual = lib.readUint8(_data, _index); + + assertEq(expected, actual); + } + + function test_readFirstUint16(uint16 _data, bytes calldata _sufix) external { + bytes memory combined = abi.encodePacked(_data, _sufix); + uint16 expected = lib.readFirstUint16(combined); + assertEq(expected, _data); + } + + function test_readFirstUint16_OutOfBounds(uint8 _data) external { + bytes memory encoded = abi.encodePacked(_data); + + uint16 actual = lib.readFirstUint16(bytes("")); + assertEq(actual, uint16(0)); + + actual = lib.readFirstUint16(encoded); + assertEq(actual, uint256(_data) << 8); + } + + function test_readFirstUint16_Fuzz_AbiDecode(bytes calldata _data) external { + uint256 expected = abi.decode(abi.encodePacked(_data, bytes32(0)), (uint256)); + uint16 actual = lib.readFirstUint16(_data); + + assertEq(expected >> 240, actual); + } + + function test_readUint32(bytes calldata _prefix, uint32 _data, bytes calldata _sufix) external { + bytes memory combined = abi.encodePacked(_prefix, _data, _sufix); + uint32 expected = lib.readUint32(combined, _prefix.length); + assertEq(expected, _data); + } +} diff --git a/packages/wallet/wallet-contracts/foundry_test/utils/LibBytesPointer.t.sol b/packages/wallet/wallet-contracts/foundry_test/utils/LibBytesPointer.t.sol new file mode 100644 index 0000000000..c8459d1875 --- /dev/null +++ b/packages/wallet/wallet-contracts/foundry_test/utils/LibBytesPointer.t.sol @@ -0,0 +1,152 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "contracts/utils/LibBytes.sol"; +import "contracts/utils/LibBytesPointer.sol"; + +import "foundry_test/base/AdvTest.sol"; + +contract LibBytesPointerImp { + using LibBytesPointer for bytes; + + function readFirstUint16(bytes calldata _data) external pure returns (uint16, uint256) { + return _data.readFirstUint16(); + } + + function readUint8(bytes calldata _data, uint256 _index) external pure returns (uint8, uint256) { + return _data.readUint8(_index); + } + + function readUint8Address(bytes calldata _data, uint256 _index) external pure returns (uint8, address, uint256) { + return _data.readUint8Address(_index); + } + + function readUint16(bytes calldata _data, uint256 _index) external pure returns (uint16, uint256) { + return _data.readUint16(_index); + } + + function readUint24(bytes calldata _data, uint256 _index) external pure returns (uint24, uint256) { + return _data.readUint24(_index); + } + + function readUint64(bytes calldata _data, uint256 _index) external pure returns (uint64, uint256) { + return _data.readUint64(_index); + } + + function readBytes32(bytes calldata _data, uint256 _index) external pure returns (bytes32, uint256) { + return _data.readBytes32(_index); + } +} + +contract LibBytesPointerTest is AdvTest { + using LibBytes for bytes; + + LibBytesPointerImp private lib; + + function setUp() public { + lib = new LibBytesPointerImp(); + } + + function test_readFirstUint16_Fuzz_LibBytes(bytes calldata _data) external { + uint16 expected = _data.readFirstUint16(); + (uint16 actual, uint256 index) = lib.readFirstUint16(_data); + assertEq(actual, expected); + assertEq(index, 2); + } + + function test_readUint8_Fuzz_LibBytes(bytes calldata _data, uint256 _pointer) external { + uint8 expected = _data.readUint8(_pointer); + (uint8 actual, uint256 newPointer) = lib.readUint8(_data, _pointer); + assertEq(actual, expected); + unchecked { + assertEq(newPointer, _pointer + 1); + } + } + + function test_readUint8Address(bytes calldata _prefix, uint8 _data1, address _data2, bytes calldata _sufix) + external + { + bytes memory combined = abi.encodePacked(_prefix, _data1, _data2, _sufix); + (uint8 actual1, address actual2, uint256 newPointer) = lib.readUint8Address(combined, _prefix.length); + assertEq(actual1, _data1); + assertEq(actual2, _data2); + assertEq(newPointer, _prefix.length + 21); + } + + function test_readUint8Address_OutOfBounds(bytes calldata _data, uint256 _pointer) external { + (,, uint256 newPointer) = lib.readUint8Address(_data, _pointer); + unchecked { + assertEq(newPointer, _pointer + 21); + } + } + + function test_readUint16_Fuzz_ReadFirstUint16(bytes calldata _data, uint256 _pointer) external { + vm.assume(_data.length >= 16); + + _pointer = bound(_pointer, 0, _data.length - 16); + (uint16 expected,) = lib.readFirstUint16(_data[_pointer:]); + (uint16 actual, uint256 newPointer) = lib.readUint16(_data, _pointer); + assertEq(actual, expected); + unchecked { + assertEq(newPointer, _pointer + 2); + } + } + + function test_readUint16_OutOfBounds(bytes calldata _data, uint256 _pointer) external { + (, uint256 newPointer) = lib.readUint16(_data, _pointer); + unchecked { + assertEq(newPointer, _pointer + 2); + } + } + + function test_readUint24(bytes calldata _prefix, uint24 _data, bytes calldata _sufix) external { + bytes memory combined = abi.encodePacked(_prefix, _data, _sufix); + (uint256 actual, uint256 newPointer) = lib.readUint24(combined, _prefix.length); + assertEq(actual, _data); + assertEq(newPointer, _prefix.length + 3); + } + + function test_readUint24_OutOfBounds(bytes calldata _data, uint256 _pointer) external { + (, uint256 newPointer) = lib.readUint24(_data, _pointer); + unchecked { + assertEq(newPointer, _pointer + 3); + } + } + + function test_readUint64(bytes calldata _prefix, uint64 _data, bytes calldata _sufix) external { + bytes memory combined = abi.encodePacked(_prefix, _data, _sufix); + (uint64 actual, uint256 newPointer) = lib.readUint64(combined, _prefix.length); + assertEq(actual, _data); + assertEq(newPointer, _prefix.length + 8); + } + + function test_readUint64_OutOfBounds(bytes calldata _data, uint256 _pointer) external { + (, uint256 newPointer) = lib.readUint64(_data, _pointer); + unchecked { + assertEq(newPointer, _pointer + 8); + } + } + + function test_readBytes32(bytes calldata _prefix, bytes32 _data, bytes calldata _sufix) external { + bytes memory combined = abi.encodePacked(_prefix, _data, _sufix); + (bytes32 actual, uint256 newPointer) = lib.readBytes32(combined, _prefix.length); + assertEq(actual, _data); + assertEq(newPointer, _prefix.length + 32); + } + + function test_readBytes32_OutOfBounds(bytes calldata _data, uint256 _pointer) external { + (, uint256 newPointer) = lib.readBytes32(_data, _pointer); + unchecked { + assertEq(newPointer, _pointer + 32); + } + } + + function test_readBytes32_Fuzz_LibBytes(bytes calldata _data, uint256 _index) external { + bytes32 expected = _data.readBytes32(_index); + (bytes32 actual, uint256 index) = lib.readBytes32(_data, _index); + assertEq(actual, expected); + unchecked { + assertEq(index, _index + 32); + } + } +} diff --git a/packages/wallet/wallet-contracts/foundry_test/utils/LibOptim.t.sol b/packages/wallet/wallet-contracts/foundry_test/utils/LibOptim.t.sol new file mode 100644 index 0000000000..ef80dbf90d --- /dev/null +++ b/packages/wallet/wallet-contracts/foundry_test/utils/LibOptim.t.sol @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "contracts/utils/LibOptim.sol"; + +import "foundry_test/base/AdvTest.sol"; + +contract WillReturn { + bytes private r; + + constructor(bytes memory _r) { + r = _r; + } + + fallback() external { + bytes memory res = r; + assembly { + return(add(res, 32), mload(res)) + } + } +} + +contract LibOptimTest is AdvTest { + function test_fkeccak256_Bytes32_Bytes32_Fuzz(bytes32 _a, bytes32 _b) external { + bytes32 expected = keccak256(abi.encodePacked(_a, _b)); + bytes32 actual = LibOptim.fkeccak256(_a, _b); + assertEq(expected, actual); + } + + function test_returnData_Fuzz(bytes memory _data) external { + WillReturn r = new WillReturn(_data); + + (bool suc, bytes memory res1) = address(r).call(bytes("")); + assertEq(suc, true); + assertEq(res1, _data); + + uint256 pointer1; + assembly { pointer1 := mload(0x40) } + assertTrue(pointer1 != 0); + + bytes memory optres = LibOptim.returnData(); + assertEq(res1, optres); + + uint256 pointer2; + assembly { pointer2 := mload(0x40) } + assertEq(pointer2 - pointer1, res1.length + 32); + + uint256 positionArr; + assembly { positionArr := optres } + assertEq(positionArr, pointer1); + } + + function test_call(address _to, uint256 _val, bytes calldata _data) external { + _to = boundNoSys(_to); + _to = boundDiff(_to, address(0x004e59b44847b379578588920ca78fbf26c0b4956c)); + + vm.expectCall(_to, _data); + vm.deal(_to, 0); + vm.deal(address(this), _val); + LibOptim.call(_to, _val, gasleft(), _data); + assertEq(_to.balance, _val); + } +} diff --git a/packages/wallet/wallet-contracts/foundry_test/utils/SignatureValidator.t.sol b/packages/wallet/wallet-contracts/foundry_test/utils/SignatureValidator.t.sol new file mode 100644 index 0000000000..6ce92787e1 --- /dev/null +++ b/packages/wallet/wallet-contracts/foundry_test/utils/SignatureValidator.t.sol @@ -0,0 +1,199 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity 0.8.18; + +import "contracts/utils/SignatureValidator.sol"; + +import "foundry_test/base/AdvTest.sol"; + +contract SignatureValidatorImp { + function recoverSigner(bytes32 _hash, bytes calldata _signature) external pure returns (address) { + return SignatureValidator.recoverSigner(_hash, _signature); + } + + function isValidSignature(bytes32 _hash, address _signer, bytes calldata _signature) external view returns (bool) { + return SignatureValidator.isValidSignature(_hash, _signer, _signature); + } +} + +contract SignatureValidatorTest is AdvTest { + SignatureValidatorImp private lib; + + uint8 private constant SIG_TYPE_EIP712 = 1; + uint8 private constant SIG_TYPE_ETH_SIGN = 2; + uint8 private constant SIG_TYPE_WALLET_BYTES32 = 3; + + function setUp() public { + lib = new SignatureValidatorImp(); + } + + function test_recoverSigner_EIP712(uint256 _pk, bytes32 _hash) external { + _pk = boundPk(_pk); + + address signer = vm.addr(_pk); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(_pk, _hash); + + address recovered = lib.recoverSigner(_hash, abi.encodePacked(r, s, v, SIG_TYPE_EIP712)); + assertEq(signer, recovered); + } + + function test_recoverSigner_ETHSIGN(uint256 _pk, bytes32 _hash) external { + _pk = boundPk(_pk); + + address signer = vm.addr(_pk); + (uint8 v, bytes32 r, bytes32 s) = + vm.sign(_pk, keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", _hash))); + + address recovered = lib.recoverSigner(_hash, abi.encodePacked(r, s, v, SIG_TYPE_ETH_SIGN)); + assertEq(signer, recovered); + } + + function test_recoverSigner_fail_InvalidSValue(bytes32 _hash, bytes32 _r, uint256 _s, uint8 _v, uint8 _type) + external + { + _s = bound(_s, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A1, type(uint256).max); + + bytes memory signature = abi.encodePacked(_r, _s, _v, _type); + vm.expectRevert(abi.encodeWithSignature("InvalidSValue(bytes,bytes32)", signature, _s)); + lib.recoverSigner(_hash, signature); + } + + function test_recoverSigner_fail_InvalidVValue(bytes32 _hash, bytes32 _r, uint256 _s, uint8 _v, uint8 _type) + external + { + _v = uint8(boundDiff(_v, 27, 28)); + + _s = bound(_s, 0, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0); + bytes memory signature = abi.encodePacked(_r, _s, _v, _type); + vm.expectRevert(abi.encodeWithSignature("InvalidVValue(bytes,uint256)", signature, _v)); + lib.recoverSigner(_hash, signature); + } + + function test_recoverSigner_fail_InvalidLength(bytes32 _hash, bytes calldata _signature) external { + vm.assume(_signature.length != 66); + + vm.expectRevert(abi.encodeWithSignature("InvalidSignatureLength(bytes)", _signature)); + lib.recoverSigner(_hash, _signature); + } + + function test_recoverSigner_fail_UnsupportedSignatureType( + bytes32 _hash, + bytes32 _r, + uint256 _s, + uint8 _v, + uint8 _type + ) external { + _type = uint8(boundDiff(_type, SIG_TYPE_EIP712, SIG_TYPE_ETH_SIGN)); + + _s = bound(_s, 0, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0); + _v = uint8(bound(_v, 27, 28)); + + bytes memory signature = abi.encodePacked(_r, _s, _v, _type); + vm.expectRevert(abi.encodeWithSignature("UnsupportedSignatureType(bytes,uint256,bool)", signature, _type, true)); + lib.recoverSigner(_hash, signature); + } + + function test_recoverSigner_fail_RecoverAddressZero(bytes32 _hash, bytes32 _r, uint256 _s, uint8 _v, uint8 _type) + external + { + _s = bound(_s, 0, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0); + _v = uint8(bound(_v, 27, 28)); + _type = uint8(bound(_type, SIG_TYPE_EIP712, SIG_TYPE_ETH_SIGN)); + + bytes memory signature = abi.encodePacked(_r, _s, _v, _type); + + try lib.recoverSigner(_hash, signature) returns (address res) { + assertTrue(res != address(0)); + } catch {} + } + + function test_isValidSignature_EIP712(uint256 _pk, bytes32 _hash) external { + _pk = boundPk(_pk); + + address signer = vm.addr(_pk); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(_pk, _hash); + + assertTrue(lib.isValidSignature(_hash, signer, abi.encodePacked(r, s, v, SIG_TYPE_EIP712))); + } + + function test_isValidSignature_ETHSIGN(uint256 _pk, bytes32 _hash) external { + _pk = boundPk(_pk); + + address signer = vm.addr(_pk); + (uint8 v, bytes32 r, bytes32 s) = + vm.sign(_pk, keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", _hash))); + + assertTrue(lib.isValidSignature(_hash, signer, abi.encodePacked(r, s, v, SIG_TYPE_ETH_SIGN))); + } + + function test_isValidSignature_WALLET_BYTES32(address _wallet, bytes32 _hash, bytes calldata _signature) external { + _wallet = boundNoSys(_wallet); + + bytes memory encodedSignature = abi.encodePacked(_signature, SIG_TYPE_WALLET_BYTES32); + + bytes memory expectCall = abi.encodeWithSignature("isValidSignature(bytes32,bytes)", _hash, _signature); + bytes memory expectResult = abi.encode(bytes4(keccak256("isValidSignature(bytes32,bytes)"))); + + vm.mockCall(_wallet, 0, expectCall, expectResult); + assertTrue(lib.isValidSignature(_hash, _wallet, encodedSignature)); + } + + function test_isValidSignature_Fail_WALLET_BYTES32_BadBytes4( + address _wallet, + bytes32 _hash, + bytes calldata _signature, + bytes4 _return + ) external { + vm.assume(bytes4(keccak256("isValidSignature(bytes32,bytes)")) != _return); + + _wallet = boundNoSys(_wallet); + + bytes memory encodedSignature = abi.encodePacked(_signature, SIG_TYPE_WALLET_BYTES32); + bytes memory expectCall = abi.encodeWithSignature("isValidSignature(bytes32,bytes)", _hash, _signature); + + vm.mockCall(_wallet, 0, expectCall, abi.encode(_return)); + assertFalse(lib.isValidSignature(_hash, _wallet, encodedSignature)); + } + + function test_isValidSignature_Fail_WALLET_BYTES32_BadReturn( + address _wallet, + bytes32 _hash, + bytes calldata _signature, + bytes calldata _return + ) external { + bytes memory goodReturn = abi.encode(bytes4(keccak256("isValidSignature(bytes32,bytes)"))); + vm.assume(keccak256(goodReturn) != keccak256(_return)); + + bytes memory encodedSignature = abi.encodePacked(_signature, SIG_TYPE_WALLET_BYTES32); + bytes memory expectCall = abi.encodeWithSignature("isValidSignature(bytes32,bytes)", _hash, _signature); + + bool retunedNotValid; + vm.mockCall(_wallet, 0, expectCall, abi.encode(_return)); + try lib.isValidSignature(_hash, _wallet, encodedSignature) returns (bool isValid) { + retunedNotValid = !isValid; + } catch { + retunedNotValid = true; + } + + assertTrue(retunedNotValid); + } + + function test_isValidSignature_Fail_EmptySignature(bytes32 _hash, address _signer) external { + vm.expectRevert(abi.encodeWithSignature("EmptySignature()")); + lib.isValidSignature(_hash, _signer, bytes("")); + } + + function test_isValidSignature_Fail_UnsupportedSignatureType( + bytes32 _hash, + address _signer, + bytes calldata _signature, + uint8 _type + ) external { + _type = uint8(boundDiff(_type, SIG_TYPE_EIP712, SIG_TYPE_ETH_SIGN, SIG_TYPE_WALLET_BYTES32)); + + bytes memory encodedSignature = abi.encodePacked(_signature, _type); + vm.expectRevert( + abi.encodeWithSignature("UnsupportedSignatureType(bytes,uint256,bool)", encodedSignature, _type, false) + ); + lib.isValidSignature(_hash, _signer, encodedSignature); + } +} diff --git a/packages/wallet/wallet-contracts/funding.json b/packages/wallet/wallet-contracts/funding.json new file mode 100644 index 0000000000..47313a81ae --- /dev/null +++ b/packages/wallet/wallet-contracts/funding.json @@ -0,0 +1,5 @@ +{ + "opRetro": { + "projectId": "0x62408999652f3bfa1be746d256bf5a4eb4719b993d40f07d2d60aaebee015018" + } +} diff --git a/packages/wallet/wallet-contracts/hardhat.config.ts b/packages/wallet/wallet-contracts/hardhat.config.ts new file mode 100644 index 0000000000..15254e7723 --- /dev/null +++ b/packages/wallet/wallet-contracts/hardhat.config.ts @@ -0,0 +1,72 @@ +import { HardhatUserConfig, task } from 'hardhat/config' +import { networkConfig } from './utils/config-loader' + +import '@nomicfoundation/hardhat-ethers' +import '@nomicfoundation/hardhat-verify' +import '@nomiclabs/hardhat-truffle5' +import '@nomiclabs/hardhat-web3' +import '@tenderly/hardhat-tenderly' + +import 'hardhat-gas-reporter' +import 'solidity-coverage' + +import './utils/benchmarker' + +const ganacheNetwork = { + url: 'http://127.0.0.1:8545', + blockGasLimit: 6000000000 +} + +const config: HardhatUserConfig = { + solidity: { + version: '0.8.18', + settings: { + optimizer: { + enabled: true, + runs: 500000 + } + } + }, + networks: { + mainnet: networkConfig('mainnet'), + ropsten: networkConfig('ropsten'), + kovan: networkConfig('kovan'), + goerli: networkConfig('goerli'), + polygon: networkConfig('polygon'), + polygonZkevm: networkConfig('polygon-zkevm'), + mumbai: networkConfig('mumbai'), + arbitrum: networkConfig('arbitrum'), + arbitrumGoerli: networkConfig('arbitrum-goerli'), + arbitrumNova: networkConfig('arbitrum-nova'), + optimism: networkConfig('optimism'), + bnb: networkConfig('bnb'), + bnbTestnet: networkConfig('bnb-testnet'), + gnosis: networkConfig('gnosis'), + avalanche: networkConfig('avalanche'), + avalancheFuji: networkConfig('avalanche-fuji'), + ganache: ganacheNetwork, + hardhat: { + blockGasLimit: 60000000 + } + }, + etherscan: { + // Your API key for Etherscan + // Obtain one at https://etherscan.io/ + apiKey: networkConfig('mainnet').etherscan + }, + mocha: { + timeout: process.env.COVERAGE ? 15 * 60 * 1000 : 30 * 1000 + }, + gasReporter: { + enabled: !!process.env.REPORT_GAS === true, + currency: 'USD', + gasPrice: 21, + showTimeSpent: true + }, + tenderly: { + project: 'horizon/sequence-dev-1', + username: 'Agusx1211-horizon' + } +} + +export default config diff --git a/packages/wallet/wallet-contracts/lib/forge-std/.github/workflows/ci.yml b/packages/wallet/wallet-contracts/lib/forge-std/.github/workflows/ci.yml new file mode 100644 index 0000000000..96b23365ec --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/.github/workflows/ci.yml @@ -0,0 +1,92 @@ +name: CI + +on: + workflow_dispatch: + pull_request: + push: + branches: + - master + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Install Foundry + uses: onbjerg/foundry-toolchain@v1 + with: + version: nightly + + - name: Print forge version + run: forge --version + + # Backwards compatibility checks. + - name: Check compatibility with 0.8.0 + if: always() + run: forge build --skip test --use solc:0.8.0 + + - name: Check compatibility with 0.7.6 + if: always() + run: forge build --skip test --use solc:0.7.6 + + - name: Check compatibility with 0.7.0 + if: always() + run: forge build --skip test --use solc:0.7.0 + + - name: Check compatibility with 0.6.12 + if: always() + run: forge build --skip test --use solc:0.6.12 + + - name: Check compatibility with 0.6.2 + if: always() + run: forge build --skip test --use solc:0.6.2 + + # via-ir compilation time checks. + - name: Measure compilation time of Test with 0.8.17 --via-ir + if: always() + run: forge build --skip test --contracts test/compilation/CompilationTest.sol --use solc:0.8.17 --via-ir + + - name: Measure compilation time of TestBase with 0.8.17 --via-ir + if: always() + run: forge build --skip test --contracts test/compilation/CompilationTestBase.sol --use solc:0.8.17 --via-ir + + - name: Measure compilation time of Script with 0.8.17 --via-ir + if: always() + run: forge build --skip test --contracts test/compilation/CompilationScript.sol --use solc:0.8.17 --via-ir + + - name: Measure compilation time of ScriptBase with 0.8.17 --via-ir + if: always() + run: forge build --skip test --contracts test/compilation/CompilationScriptBase.sol --use solc:0.8.17 --via-ir + + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Install Foundry + uses: onbjerg/foundry-toolchain@v1 + with: + version: nightly + + - name: Print forge version + run: forge --version + + - name: Run tests + run: forge test -vvv + + fmt: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Install Foundry + uses: onbjerg/foundry-toolchain@v1 + with: + version: nightly + + - name: Print forge version + run: forge --version + + - name: Check formatting + run: forge fmt --check diff --git a/packages/wallet/wallet-contracts/lib/forge-std/.github/workflows/sync.yml b/packages/wallet/wallet-contracts/lib/forge-std/.github/workflows/sync.yml new file mode 100644 index 0000000000..5a9e9d5913 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/.github/workflows/sync.yml @@ -0,0 +1,29 @@ +name: Sync Release Branch + +on: + release: + types: + - created + +jobs: + sync-release-branch: + runs-on: ubuntu-latest + if: startsWith(github.event.release.tag_name, 'v1') + steps: + - name: Check out the repo + uses: actions/checkout@v3 + with: + fetch-depth: 0 + ref: v1 + + - name: Configure Git + run: | + git config user.name github-actions[bot] + git config user.email 41898282+github-actions[bot]@users.noreply.github.com + + - name: Sync Release Branch + run: | + git fetch --tags + git checkout v1 + git reset --hard ${GITHUB_REF} + git push --force diff --git a/packages/wallet/wallet-contracts/lib/forge-std/.gitmodules b/packages/wallet/wallet-contracts/lib/forge-std/.gitmodules new file mode 100644 index 0000000000..e12471968b --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/.gitmodules @@ -0,0 +1,3 @@ +[submodule "lib/ds-test"] + path = lib/ds-test + url = https://github.com/dapphub/ds-test diff --git a/packages/wallet/wallet-contracts/lib/forge-std/LICENSE-APACHE b/packages/wallet/wallet-contracts/lib/forge-std/LICENSE-APACHE new file mode 100644 index 0000000000..cf01a499fb --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/LICENSE-APACHE @@ -0,0 +1,203 @@ +Copyright Contributors to Forge Standard Library + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/packages/wallet/wallet-contracts/lib/forge-std/LICENSE-MIT b/packages/wallet/wallet-contracts/lib/forge-std/LICENSE-MIT new file mode 100644 index 0000000000..28f98304ac --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright Contributors to Forge Standard Library + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE O THE USE OR OTHER +DEALINGS IN THE SOFTWARE.R diff --git a/packages/wallet/wallet-contracts/lib/forge-std/README.md b/packages/wallet/wallet-contracts/lib/forge-std/README.md new file mode 100644 index 0000000000..8494a7dd5e --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/README.md @@ -0,0 +1,250 @@ +# Forge Standard Library • [![CI status](https://github.com/foundry-rs/forge-std/actions/workflows/ci.yml/badge.svg)](https://github.com/foundry-rs/forge-std/actions/workflows/ci.yml) + +Forge Standard Library is a collection of helpful contracts and libraries for use with [Forge and Foundry](https://github.com/foundry-rs/foundry). It leverages Forge's cheatcodes to make writing tests easier and faster, while improving the UX of cheatcodes. + +**Learn how to use Forge-Std with the [šŸ“– Foundry Book (Forge-Std Guide)](https://book.getfoundry.sh/forge/forge-std.html).** + +## Install + +```bash +forge install foundry-rs/forge-std +``` + +## Contracts +### stdError + +This is a helper contract for errors and reverts. In Forge, this contract is particularly helpful for the `expectRevert` cheatcode, as it provides all compiler builtin errors. + +See the contract itself for all error codes. + +#### Example usage + +```solidity + +import "forge-std/Test.sol"; + +contract TestContract is Test { + ErrorsTest test; + + function setUp() public { + test = new ErrorsTest(); + } + + function testExpectArithmetic() public { + vm.expectRevert(stdError.arithmeticError); + test.arithmeticError(10); + } +} + +contract ErrorsTest { + function arithmeticError(uint256 a) public { + uint256 a = a - 100; + } +} +``` + +### stdStorage + +This is a rather large contract due to all of the overloading to make the UX decent. Primarily, it is a wrapper around the `record` and `accesses` cheatcodes. It can *always* find and write the storage slot(s) associated with a particular variable without knowing the storage layout. The one _major_ caveat to this is while a slot can be found for packed storage variables, we can't write to that variable safely. If a user tries to write to a packed slot, the execution throws an error, unless it is uninitialized (`bytes32(0)`). + +This works by recording all `SLOAD`s and `SSTORE`s during a function call. If there is a single slot read or written to, it immediately returns the slot. Otherwise, behind the scenes, we iterate through and check each one (assuming the user passed in a `depth` parameter). If the variable is a struct, you can pass in a `depth` parameter which is basically the field depth. + +I.e.: +```solidity +struct T { + // depth 0 + uint256 a; + // depth 1 + uint256 b; +} +``` + +#### Example usage + +```solidity +import "forge-std/Test.sol"; + +contract TestContract is Test { + using stdStorage for StdStorage; + + Storage test; + + function setUp() public { + test = new Storage(); + } + + function testFindExists() public { + // Lets say we want to find the slot for the public + // variable `exists`. We just pass in the function selector + // to the `find` command + uint256 slot = stdstore.target(address(test)).sig("exists()").find(); + assertEq(slot, 0); + } + + function testWriteExists() public { + // Lets say we want to write to the slot for the public + // variable `exists`. We just pass in the function selector + // to the `checked_write` command + stdstore.target(address(test)).sig("exists()").checked_write(100); + assertEq(test.exists(), 100); + } + + // It supports arbitrary storage layouts, like assembly based storage locations + function testFindHidden() public { + // `hidden` is a random hash of a bytes, iteration through slots would + // not find it. Our mechanism does + // Also, you can use the selector instead of a string + uint256 slot = stdstore.target(address(test)).sig(test.hidden.selector).find(); + assertEq(slot, uint256(keccak256("my.random.var"))); + } + + // If targeting a mapping, you have to pass in the keys necessary to perform the find + // i.e.: + function testFindMapping() public { + uint256 slot = stdstore + .target(address(test)) + .sig(test.map_addr.selector) + .with_key(address(this)) + .find(); + // in the `Storage` constructor, we wrote that this address' value was 1 in the map + // so when we load the slot, we expect it to be 1 + assertEq(uint(vm.load(address(test), bytes32(slot))), 1); + } + + // If the target is a struct, you can specify the field depth: + function testFindStruct() public { + // NOTE: see the depth parameter - 0 means 0th field, 1 means 1st field, etc. + uint256 slot_for_a_field = stdstore + .target(address(test)) + .sig(test.basicStruct.selector) + .depth(0) + .find(); + + uint256 slot_for_b_field = stdstore + .target(address(test)) + .sig(test.basicStruct.selector) + .depth(1) + .find(); + + assertEq(uint(vm.load(address(test), bytes32(slot_for_a_field))), 1); + assertEq(uint(vm.load(address(test), bytes32(slot_for_b_field))), 2); + } +} + +// A complex storage contract +contract Storage { + struct UnpackedStruct { + uint256 a; + uint256 b; + } + + constructor() { + map_addr[msg.sender] = 1; + } + + uint256 public exists = 1; + mapping(address => uint256) public map_addr; + // mapping(address => Packed) public map_packed; + mapping(address => UnpackedStruct) public map_struct; + mapping(address => mapping(address => uint256)) public deep_map; + mapping(address => mapping(address => UnpackedStruct)) public deep_map_struct; + UnpackedStruct public basicStruct = UnpackedStruct({ + a: 1, + b: 2 + }); + + function hidden() public view returns (bytes32 t) { + // an extremely hidden storage slot + bytes32 slot = keccak256("my.random.var"); + assembly { + t := sload(slot) + } + } +} +``` + +### stdCheats + +This is a wrapper over miscellaneous cheatcodes that need wrappers to be more dev friendly. Currently there are only functions related to `prank`. In general, users may expect ETH to be put into an address on `prank`, but this is not the case for safety reasons. Explicitly this `hoax` function should only be used for address that have expected balances as it will get overwritten. If an address already has ETH, you should just use `prank`. If you want to change that balance explicitly, just use `deal`. If you want to do both, `hoax` is also right for you. + + +#### Example usage: +```solidity + +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import "forge-std/Test.sol"; + +// Inherit the stdCheats +contract StdCheatsTest is Test { + Bar test; + function setUp() public { + test = new Bar(); + } + + function testHoax() public { + // we call `hoax`, which gives the target address + // eth and then calls `prank` + hoax(address(1337)); + test.bar{value: 100}(address(1337)); + + // overloaded to allow you to specify how much eth to + // initialize the address with + hoax(address(1337), 1); + test.bar{value: 1}(address(1337)); + } + + function testStartHoax() public { + // we call `startHoax`, which gives the target address + // eth and then calls `startPrank` + // + // it is also overloaded so that you can specify an eth amount + startHoax(address(1337)); + test.bar{value: 100}(address(1337)); + test.bar{value: 100}(address(1337)); + vm.stopPrank(); + test.bar(address(this)); + } +} + +contract Bar { + function bar(address expectedSender) public payable { + require(msg.sender == expectedSender, "!prank"); + } +} +``` + +### Std Assertions + +Expand upon the assertion functions from the `DSTest` library. + +### `console.log` + +Usage follows the same format as [Hardhat](https://hardhat.org/hardhat-network/reference/#console-log). +It's recommended to use `console2.sol` as shown below, as this will show the decoded logs in Forge traces. + +```solidity +// import it indirectly via Test.sol +import "forge-std/Test.sol"; +// or directly import it +import "forge-std/console2.sol"; +... +console2.log(someValue); +``` + +If you need compatibility with Hardhat, you must use the standard `console.sol` instead. +Due to a bug in `console.sol`, logs that use `uint256` or `int256` types will not be properly decoded in Forge traces. + +```solidity +// import it indirectly via Test.sol +import "forge-std/Test.sol"; +// or directly import it +import "forge-std/console.sol"; +... +console.log(someValue); +``` + +## License + +Forge Standard Library is offered under either [MIT](LICENSE-MIT) or [Apache 2.0](LICENSE-APACHE) license. diff --git a/packages/wallet/wallet-contracts/lib/forge-std/foundry.toml b/packages/wallet/wallet-contracts/lib/forge-std/foundry.toml new file mode 100644 index 0000000000..f9679ee61a --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/foundry.toml @@ -0,0 +1,21 @@ +[profile.default] +fs_permissions = [{ access = "read-write", path = "./"}] + +[rpc_endpoints] +# The RPC URLs are modified versions of the default for testing initialization. +mainnet = "https://mainnet.infura.io/v3/b1d3925804e74152b316ca7da97060d3" # Different API key. +optimism_goerli = "https://goerli.optimism.io/" # Adds a trailing slash. +arbitrum_one_goerli = "https://goerli-rollup.arbitrum.io/rpc/" # Adds a trailing slash. +needs_undefined_env_var = "${UNDEFINED_RPC_URL_PLACEHOLDER}" + +[fmt] +# These are all the `forge fmt` defaults. +line_length = 120 +tab_width = 4 +bracket_spacing = false +int_types = 'long' +multiline_func_header = 'attributes_first' +quote_style = 'double' +number_underscore = 'preserve' +single_line_statement_blocks = 'preserve' +ignore = ["src/console.sol", "src/console2.sol"] \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/lib/forge-std/lib/ds-test/.github/workflows/build.yml b/packages/wallet/wallet-contracts/lib/forge-std/lib/ds-test/.github/workflows/build.yml new file mode 100644 index 0000000000..d2ff97db70 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/lib/ds-test/.github/workflows/build.yml @@ -0,0 +1,41 @@ +name: "Build" +on: + pull_request: + push: +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: cachix/install-nix-action@v20 + with: + nix_path: nixpkgs=channel:nixos-unstable + extra_nix_config: | + access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} + + - name: setup dapp binary cache + uses: cachix/cachix-action@v12 + with: + name: dapp + + - name: install dapptools + run: nix profile install github:dapphub/dapptools#dapp --accept-flake-config + + - name: install foundry + uses: foundry-rs/foundry-toolchain@v1 + + - name: test with solc-0.5.17 + run: dapp --use solc-0.5.17 test -v + + - name: test with solc-0.6.11 + run: dapp --use solc-0.6.11 test -v + + - name: test with solc-0.7.6 + run: dapp --use solc-0.7.6 test -v + + - name: test with solc-0.8.18 + run: dapp --use solc-0.8.18 test -v + + - name: Run tests with foundry + run: forge test -vvv + diff --git a/packages/wallet/wallet-contracts/lib/forge-std/lib/ds-test/LICENSE b/packages/wallet/wallet-contracts/lib/forge-std/lib/ds-test/LICENSE new file mode 100644 index 0000000000..94a9ed024d --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/lib/ds-test/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/packages/wallet/wallet-contracts/lib/forge-std/lib/ds-test/Makefile b/packages/wallet/wallet-contracts/lib/forge-std/lib/ds-test/Makefile new file mode 100644 index 0000000000..661dac4868 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/lib/ds-test/Makefile @@ -0,0 +1,14 @@ +all:; dapp build + +test: + -dapp --use solc:0.4.23 build + -dapp --use solc:0.4.26 build + -dapp --use solc:0.5.17 build + -dapp --use solc:0.6.12 build + -dapp --use solc:0.7.5 build + +demo: + DAPP_SRC=demo dapp --use solc:0.7.5 build + -hevm dapp-test --verbose 3 + +.PHONY: test demo diff --git a/packages/wallet/wallet-contracts/lib/forge-std/lib/ds-test/default.nix b/packages/wallet/wallet-contracts/lib/forge-std/lib/ds-test/default.nix new file mode 100644 index 0000000000..cf65419ab4 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/lib/ds-test/default.nix @@ -0,0 +1,4 @@ +{ solidityPackage, dappsys }: solidityPackage { + name = "ds-test"; + src = ./src; +} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/lib/ds-test/demo/demo.sol b/packages/wallet/wallet-contracts/lib/forge-std/lib/ds-test/demo/demo.sol new file mode 100644 index 0000000000..f3bb48e701 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/lib/ds-test/demo/demo.sol @@ -0,0 +1,222 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity >=0.5.0; + +import "../src/test.sol"; + +contract DemoTest is DSTest { + function test_this() public pure { + require(true); + } + function test_logs() public { + emit log("-- log(string)"); + emit log("a string"); + + emit log("-- log_named_uint(string, uint)"); + emit log_named_uint("uint", 512); + + emit log("-- log_named_int(string, int)"); + emit log_named_int("int", -512); + + emit log("-- log_named_address(string, address)"); + emit log_named_address("address", address(this)); + + emit log("-- log_named_bytes32(string, bytes32)"); + emit log_named_bytes32("bytes32", "a string"); + + emit log("-- log_named_bytes(string, bytes)"); + emit log_named_bytes("bytes", hex"cafefe"); + + emit log("-- log_named_string(string, string)"); + emit log_named_string("string", "a string"); + + emit log("-- log_named_decimal_uint(string, uint, uint)"); + emit log_named_decimal_uint("decimal uint", 1.0e18, 18); + + emit log("-- log_named_decimal_int(string, int, uint)"); + emit log_named_decimal_int("decimal int", -1.0e18, 18); + } + event log_old_named_uint(bytes32,uint); + function test_old_logs() public { + emit log_old_named_uint("key", 500); + emit log_named_bytes32("bkey", "val"); + } + function test_trace() public view { + this.echo("string 1", "string 2"); + } + function test_multiline() public { + emit log("a multiline\\nstring"); + emit log("a multiline string"); + emit log_bytes("a string"); + emit log_bytes("a multiline\nstring"); + emit log_bytes("a multiline\\nstring"); + emit logs(hex"0000"); + emit log_named_bytes("0x0000", hex"0000"); + emit logs(hex"ff"); + } + function echo(string memory s1, string memory s2) public pure + returns (string memory, string memory) + { + return (s1, s2); + } + + function prove_this(uint x) public { + emit log_named_uint("sym x", x); + assertGt(x + 1, 0); + } + + function test_logn() public { + assembly { + log0(0x01, 0x02) + log1(0x01, 0x02, 0x03) + log2(0x01, 0x02, 0x03, 0x04) + log3(0x01, 0x02, 0x03, 0x04, 0x05) + } + } + + event MyEvent(uint, uint indexed, uint, uint indexed); + function test_events() public { + emit MyEvent(1, 2, 3, 4); + } + + function test_asserts() public { + string memory err = "this test has failed!"; + emit log("## assertTrue(bool)\n"); + assertTrue(false); + emit log("\n"); + assertTrue(false, err); + + emit log("\n## assertEq(address,address)\n"); + assertEq(address(this), msg.sender); + emit log("\n"); + assertEq(address(this), msg.sender, err); + + emit log("\n## assertEq32(bytes32,bytes32)\n"); + assertEq32("bytes 1", "bytes 2"); + emit log("\n"); + assertEq32("bytes 1", "bytes 2", err); + + emit log("\n## assertEq(bytes32,bytes32)\n"); + assertEq32("bytes 1", "bytes 2"); + emit log("\n"); + assertEq32("bytes 1", "bytes 2", err); + + emit log("\n## assertEq(uint,uint)\n"); + assertEq(uint(0), 1); + emit log("\n"); + assertEq(uint(0), 1, err); + + emit log("\n## assertEq(int,int)\n"); + assertEq(-1, -2); + emit log("\n"); + assertEq(-1, -2, err); + + emit log("\n## assertEqDecimal(int,int,uint)\n"); + assertEqDecimal(-1.0e18, -1.1e18, 18); + emit log("\n"); + assertEqDecimal(-1.0e18, -1.1e18, 18, err); + + emit log("\n## assertEqDecimal(uint,uint,uint)\n"); + assertEqDecimal(uint(1.0e18), 1.1e18, 18); + emit log("\n"); + assertEqDecimal(uint(1.0e18), 1.1e18, 18, err); + + emit log("\n## assertGt(uint,uint)\n"); + assertGt(uint(0), 0); + emit log("\n"); + assertGt(uint(0), 0, err); + + emit log("\n## assertGt(int,int)\n"); + assertGt(-1, -1); + emit log("\n"); + assertGt(-1, -1, err); + + emit log("\n## assertGtDecimal(int,int,uint)\n"); + assertGtDecimal(-2.0e18, -1.1e18, 18); + emit log("\n"); + assertGtDecimal(-2.0e18, -1.1e18, 18, err); + + emit log("\n## assertGtDecimal(uint,uint,uint)\n"); + assertGtDecimal(uint(1.0e18), 1.1e18, 18); + emit log("\n"); + assertGtDecimal(uint(1.0e18), 1.1e18, 18, err); + + emit log("\n## assertGe(uint,uint)\n"); + assertGe(uint(0), 1); + emit log("\n"); + assertGe(uint(0), 1, err); + + emit log("\n## assertGe(int,int)\n"); + assertGe(-1, 0); + emit log("\n"); + assertGe(-1, 0, err); + + emit log("\n## assertGeDecimal(int,int,uint)\n"); + assertGeDecimal(-2.0e18, -1.1e18, 18); + emit log("\n"); + assertGeDecimal(-2.0e18, -1.1e18, 18, err); + + emit log("\n## assertGeDecimal(uint,uint,uint)\n"); + assertGeDecimal(uint(1.0e18), 1.1e18, 18); + emit log("\n"); + assertGeDecimal(uint(1.0e18), 1.1e18, 18, err); + + emit log("\n## assertLt(uint,uint)\n"); + assertLt(uint(0), 0); + emit log("\n"); + assertLt(uint(0), 0, err); + + emit log("\n## assertLt(int,int)\n"); + assertLt(-1, -1); + emit log("\n"); + assertLt(-1, -1, err); + + emit log("\n## assertLtDecimal(int,int,uint)\n"); + assertLtDecimal(-1.0e18, -1.1e18, 18); + emit log("\n"); + assertLtDecimal(-1.0e18, -1.1e18, 18, err); + + emit log("\n## assertLtDecimal(uint,uint,uint)\n"); + assertLtDecimal(uint(2.0e18), 1.1e18, 18); + emit log("\n"); + assertLtDecimal(uint(2.0e18), 1.1e18, 18, err); + + emit log("\n## assertLe(uint,uint)\n"); + assertLe(uint(1), 0); + emit log("\n"); + assertLe(uint(1), 0, err); + + emit log("\n## assertLe(int,int)\n"); + assertLe(0, -1); + emit log("\n"); + assertLe(0, -1, err); + + emit log("\n## assertLeDecimal(int,int,uint)\n"); + assertLeDecimal(-1.0e18, -1.1e18, 18); + emit log("\n"); + assertLeDecimal(-1.0e18, -1.1e18, 18, err); + + emit log("\n## assertLeDecimal(uint,uint,uint)\n"); + assertLeDecimal(uint(2.0e18), 1.1e18, 18); + emit log("\n"); + assertLeDecimal(uint(2.0e18), 1.1e18, 18, err); + + emit log("\n## assertEq(string,string)\n"); + string memory s1 = "string 1"; + string memory s2 = "string 2"; + assertEq(s1, s2); + emit log("\n"); + assertEq(s1, s2, err); + + emit log("\n## assertEq0(bytes,bytes)\n"); + assertEq0(hex"abcdef01", hex"abcdef02"); + emit log("\n"); + assertEq0(hex"abcdef01", hex"abcdef02", err); + } +} + +contract DemoTestWithSetUp { + function setUp() public { + } + function test_pass() public pure { + } +} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/lib/ds-test/package.json b/packages/wallet/wallet-contracts/lib/forge-std/lib/ds-test/package.json new file mode 100644 index 0000000000..4802adaa32 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/lib/ds-test/package.json @@ -0,0 +1,15 @@ +{ + "name": "ds-test", + "version": "1.0.0", + "description": "Assertions, equality checks and other test helpers ", + "bugs": "https://github.com/dapphub/ds-test/issues", + "license": "GPL-3.0", + "author": "Contributors to ds-test", + "files": [ + "src/*" + ], + "repository": { + "type": "git", + "url": "https://github.com/dapphub/ds-test.git" + } +} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/lib/ds-test/src/test.sol b/packages/wallet/wallet-contracts/lib/forge-std/lib/ds-test/src/test.sol new file mode 100644 index 0000000000..2bf337567f --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/lib/ds-test/src/test.sol @@ -0,0 +1,592 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +pragma solidity >=0.5.0; + +contract DSTest { + event log (string); + event logs (bytes); + + event log_address (address); + event log_bytes32 (bytes32); + event log_int (int); + event log_uint (uint); + event log_bytes (bytes); + event log_string (string); + + event log_named_address (string key, address val); + event log_named_bytes32 (string key, bytes32 val); + event log_named_decimal_int (string key, int val, uint decimals); + event log_named_decimal_uint (string key, uint val, uint decimals); + event log_named_int (string key, int val); + event log_named_uint (string key, uint val); + event log_named_bytes (string key, bytes val); + event log_named_string (string key, string val); + + bool public IS_TEST = true; + bool private _failed; + + address constant HEVM_ADDRESS = + address(bytes20(uint160(uint256(keccak256('hevm cheat code'))))); + + modifier mayRevert() { _; } + modifier testopts(string memory) { _; } + + function failed() public returns (bool) { + if (_failed) { + return _failed; + } else { + bool globalFailed = false; + if (hasHEVMContext()) { + (, bytes memory retdata) = HEVM_ADDRESS.call( + abi.encodePacked( + bytes4(keccak256("load(address,bytes32)")), + abi.encode(HEVM_ADDRESS, bytes32("failed")) + ) + ); + globalFailed = abi.decode(retdata, (bool)); + } + return globalFailed; + } + } + + function fail() internal virtual { + if (hasHEVMContext()) { + (bool status, ) = HEVM_ADDRESS.call( + abi.encodePacked( + bytes4(keccak256("store(address,bytes32,bytes32)")), + abi.encode(HEVM_ADDRESS, bytes32("failed"), bytes32(uint256(0x01))) + ) + ); + status; // Silence compiler warnings + } + _failed = true; + } + + function hasHEVMContext() internal view returns (bool) { + uint256 hevmCodeSize = 0; + assembly { + hevmCodeSize := extcodesize(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D) + } + return hevmCodeSize > 0; + } + + modifier logs_gas() { + uint startGas = gasleft(); + _; + uint endGas = gasleft(); + emit log_named_uint("gas", startGas - endGas); + } + + function assertTrue(bool condition) internal { + if (!condition) { + emit log("Error: Assertion Failed"); + fail(); + } + } + + function assertTrue(bool condition, string memory err) internal { + if (!condition) { + emit log_named_string("Error", err); + assertTrue(condition); + } + } + + function assertEq(address a, address b) internal { + if (a != b) { + emit log("Error: a == b not satisfied [address]"); + emit log_named_address(" Left", a); + emit log_named_address(" Right", b); + fail(); + } + } + function assertEq(address a, address b, string memory err) internal { + if (a != b) { + emit log_named_string ("Error", err); + assertEq(a, b); + } + } + + function assertEq(bytes32 a, bytes32 b) internal { + if (a != b) { + emit log("Error: a == b not satisfied [bytes32]"); + emit log_named_bytes32(" Left", a); + emit log_named_bytes32(" Right", b); + fail(); + } + } + function assertEq(bytes32 a, bytes32 b, string memory err) internal { + if (a != b) { + emit log_named_string ("Error", err); + assertEq(a, b); + } + } + function assertEq32(bytes32 a, bytes32 b) internal { + assertEq(a, b); + } + function assertEq32(bytes32 a, bytes32 b, string memory err) internal { + assertEq(a, b, err); + } + + function assertEq(int a, int b) internal { + if (a != b) { + emit log("Error: a == b not satisfied [int]"); + emit log_named_int(" Left", a); + emit log_named_int(" Right", b); + fail(); + } + } + function assertEq(int a, int b, string memory err) internal { + if (a != b) { + emit log_named_string("Error", err); + assertEq(a, b); + } + } + function assertEq(uint a, uint b) internal { + if (a != b) { + emit log("Error: a == b not satisfied [uint]"); + emit log_named_uint(" Left", a); + emit log_named_uint(" Right", b); + fail(); + } + } + function assertEq(uint a, uint b, string memory err) internal { + if (a != b) { + emit log_named_string("Error", err); + assertEq(a, b); + } + } + function assertEqDecimal(int a, int b, uint decimals) internal { + if (a != b) { + emit log("Error: a == b not satisfied [decimal int]"); + emit log_named_decimal_int(" Left", a, decimals); + emit log_named_decimal_int(" Right", b, decimals); + fail(); + } + } + function assertEqDecimal(int a, int b, uint decimals, string memory err) internal { + if (a != b) { + emit log_named_string("Error", err); + assertEqDecimal(a, b, decimals); + } + } + function assertEqDecimal(uint a, uint b, uint decimals) internal { + if (a != b) { + emit log("Error: a == b not satisfied [decimal uint]"); + emit log_named_decimal_uint(" Left", a, decimals); + emit log_named_decimal_uint(" Right", b, decimals); + fail(); + } + } + function assertEqDecimal(uint a, uint b, uint decimals, string memory err) internal { + if (a != b) { + emit log_named_string("Error", err); + assertEqDecimal(a, b, decimals); + } + } + + function assertNotEq(address a, address b) internal { + if (a == b) { + emit log("Error: a != b not satisfied [address]"); + emit log_named_address(" Left", a); + emit log_named_address(" Right", b); + fail(); + } + } + function assertNotEq(address a, address b, string memory err) internal { + if (a == b) { + emit log_named_string ("Error", err); + assertNotEq(a, b); + } + } + + function assertNotEq(bytes32 a, bytes32 b) internal { + if (a == b) { + emit log("Error: a != b not satisfied [bytes32]"); + emit log_named_bytes32(" Left", a); + emit log_named_bytes32(" Right", b); + fail(); + } + } + function assertNotEq(bytes32 a, bytes32 b, string memory err) internal { + if (a == b) { + emit log_named_string ("Error", err); + assertNotEq(a, b); + } + } + function assertNotEq32(bytes32 a, bytes32 b) internal { + assertNotEq(a, b); + } + function assertNotEq32(bytes32 a, bytes32 b, string memory err) internal { + assertNotEq(a, b, err); + } + + function assertNotEq(int a, int b) internal { + if (a == b) { + emit log("Error: a != b not satisfied [int]"); + emit log_named_int(" Left", a); + emit log_named_int(" Right", b); + fail(); + } + } + function assertNotEq(int a, int b, string memory err) internal { + if (a == b) { + emit log_named_string("Error", err); + assertNotEq(a, b); + } + } + function assertNotEq(uint a, uint b) internal { + if (a == b) { + emit log("Error: a != b not satisfied [uint]"); + emit log_named_uint(" Left", a); + emit log_named_uint(" Right", b); + fail(); + } + } + function assertNotEq(uint a, uint b, string memory err) internal { + if (a == b) { + emit log_named_string("Error", err); + assertNotEq(a, b); + } + } + function assertNotEqDecimal(int a, int b, uint decimals) internal { + if (a == b) { + emit log("Error: a != b not satisfied [decimal int]"); + emit log_named_decimal_int(" Left", a, decimals); + emit log_named_decimal_int(" Right", b, decimals); + fail(); + } + } + function assertNotEqDecimal(int a, int b, uint decimals, string memory err) internal { + if (a == b) { + emit log_named_string("Error", err); + assertNotEqDecimal(a, b, decimals); + } + } + function assertNotEqDecimal(uint a, uint b, uint decimals) internal { + if (a == b) { + emit log("Error: a != b not satisfied [decimal uint]"); + emit log_named_decimal_uint(" Left", a, decimals); + emit log_named_decimal_uint(" Right", b, decimals); + fail(); + } + } + function assertNotEqDecimal(uint a, uint b, uint decimals, string memory err) internal { + if (a == b) { + emit log_named_string("Error", err); + assertNotEqDecimal(a, b, decimals); + } + } + + function assertGt(uint a, uint b) internal { + if (a <= b) { + emit log("Error: a > b not satisfied [uint]"); + emit log_named_uint(" Value a", a); + emit log_named_uint(" Value b", b); + fail(); + } + } + function assertGt(uint a, uint b, string memory err) internal { + if (a <= b) { + emit log_named_string("Error", err); + assertGt(a, b); + } + } + function assertGt(int a, int b) internal { + if (a <= b) { + emit log("Error: a > b not satisfied [int]"); + emit log_named_int(" Value a", a); + emit log_named_int(" Value b", b); + fail(); + } + } + function assertGt(int a, int b, string memory err) internal { + if (a <= b) { + emit log_named_string("Error", err); + assertGt(a, b); + } + } + function assertGtDecimal(int a, int b, uint decimals) internal { + if (a <= b) { + emit log("Error: a > b not satisfied [decimal int]"); + emit log_named_decimal_int(" Value a", a, decimals); + emit log_named_decimal_int(" Value b", b, decimals); + fail(); + } + } + function assertGtDecimal(int a, int b, uint decimals, string memory err) internal { + if (a <= b) { + emit log_named_string("Error", err); + assertGtDecimal(a, b, decimals); + } + } + function assertGtDecimal(uint a, uint b, uint decimals) internal { + if (a <= b) { + emit log("Error: a > b not satisfied [decimal uint]"); + emit log_named_decimal_uint(" Value a", a, decimals); + emit log_named_decimal_uint(" Value b", b, decimals); + fail(); + } + } + function assertGtDecimal(uint a, uint b, uint decimals, string memory err) internal { + if (a <= b) { + emit log_named_string("Error", err); + assertGtDecimal(a, b, decimals); + } + } + + function assertGe(uint a, uint b) internal { + if (a < b) { + emit log("Error: a >= b not satisfied [uint]"); + emit log_named_uint(" Value a", a); + emit log_named_uint(" Value b", b); + fail(); + } + } + function assertGe(uint a, uint b, string memory err) internal { + if (a < b) { + emit log_named_string("Error", err); + assertGe(a, b); + } + } + function assertGe(int a, int b) internal { + if (a < b) { + emit log("Error: a >= b not satisfied [int]"); + emit log_named_int(" Value a", a); + emit log_named_int(" Value b", b); + fail(); + } + } + function assertGe(int a, int b, string memory err) internal { + if (a < b) { + emit log_named_string("Error", err); + assertGe(a, b); + } + } + function assertGeDecimal(int a, int b, uint decimals) internal { + if (a < b) { + emit log("Error: a >= b not satisfied [decimal int]"); + emit log_named_decimal_int(" Value a", a, decimals); + emit log_named_decimal_int(" Value b", b, decimals); + fail(); + } + } + function assertGeDecimal(int a, int b, uint decimals, string memory err) internal { + if (a < b) { + emit log_named_string("Error", err); + assertGeDecimal(a, b, decimals); + } + } + function assertGeDecimal(uint a, uint b, uint decimals) internal { + if (a < b) { + emit log("Error: a >= b not satisfied [decimal uint]"); + emit log_named_decimal_uint(" Value a", a, decimals); + emit log_named_decimal_uint(" Value b", b, decimals); + fail(); + } + } + function assertGeDecimal(uint a, uint b, uint decimals, string memory err) internal { + if (a < b) { + emit log_named_string("Error", err); + assertGeDecimal(a, b, decimals); + } + } + + function assertLt(uint a, uint b) internal { + if (a >= b) { + emit log("Error: a < b not satisfied [uint]"); + emit log_named_uint(" Value a", a); + emit log_named_uint(" Value b", b); + fail(); + } + } + function assertLt(uint a, uint b, string memory err) internal { + if (a >= b) { + emit log_named_string("Error", err); + assertLt(a, b); + } + } + function assertLt(int a, int b) internal { + if (a >= b) { + emit log("Error: a < b not satisfied [int]"); + emit log_named_int(" Value a", a); + emit log_named_int(" Value b", b); + fail(); + } + } + function assertLt(int a, int b, string memory err) internal { + if (a >= b) { + emit log_named_string("Error", err); + assertLt(a, b); + } + } + function assertLtDecimal(int a, int b, uint decimals) internal { + if (a >= b) { + emit log("Error: a < b not satisfied [decimal int]"); + emit log_named_decimal_int(" Value a", a, decimals); + emit log_named_decimal_int(" Value b", b, decimals); + fail(); + } + } + function assertLtDecimal(int a, int b, uint decimals, string memory err) internal { + if (a >= b) { + emit log_named_string("Error", err); + assertLtDecimal(a, b, decimals); + } + } + function assertLtDecimal(uint a, uint b, uint decimals) internal { + if (a >= b) { + emit log("Error: a < b not satisfied [decimal uint]"); + emit log_named_decimal_uint(" Value a", a, decimals); + emit log_named_decimal_uint(" Value b", b, decimals); + fail(); + } + } + function assertLtDecimal(uint a, uint b, uint decimals, string memory err) internal { + if (a >= b) { + emit log_named_string("Error", err); + assertLtDecimal(a, b, decimals); + } + } + + function assertLe(uint a, uint b) internal { + if (a > b) { + emit log("Error: a <= b not satisfied [uint]"); + emit log_named_uint(" Value a", a); + emit log_named_uint(" Value b", b); + fail(); + } + } + function assertLe(uint a, uint b, string memory err) internal { + if (a > b) { + emit log_named_string("Error", err); + assertLe(a, b); + } + } + function assertLe(int a, int b) internal { + if (a > b) { + emit log("Error: a <= b not satisfied [int]"); + emit log_named_int(" Value a", a); + emit log_named_int(" Value b", b); + fail(); + } + } + function assertLe(int a, int b, string memory err) internal { + if (a > b) { + emit log_named_string("Error", err); + assertLe(a, b); + } + } + function assertLeDecimal(int a, int b, uint decimals) internal { + if (a > b) { + emit log("Error: a <= b not satisfied [decimal int]"); + emit log_named_decimal_int(" Value a", a, decimals); + emit log_named_decimal_int(" Value b", b, decimals); + fail(); + } + } + function assertLeDecimal(int a, int b, uint decimals, string memory err) internal { + if (a > b) { + emit log_named_string("Error", err); + assertLeDecimal(a, b, decimals); + } + } + function assertLeDecimal(uint a, uint b, uint decimals) internal { + if (a > b) { + emit log("Error: a <= b not satisfied [decimal uint]"); + emit log_named_decimal_uint(" Value a", a, decimals); + emit log_named_decimal_uint(" Value b", b, decimals); + fail(); + } + } + function assertLeDecimal(uint a, uint b, uint decimals, string memory err) internal { + if (a > b) { + emit log_named_string("Error", err); + assertLeDecimal(a, b, decimals); + } + } + + function assertEq(string memory a, string memory b) internal { + if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) { + emit log("Error: a == b not satisfied [string]"); + emit log_named_string(" Left", a); + emit log_named_string(" Right", b); + fail(); + } + } + function assertEq(string memory a, string memory b, string memory err) internal { + if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) { + emit log_named_string("Error", err); + assertEq(a, b); + } + } + + function assertNotEq(string memory a, string memory b) internal { + if (keccak256(abi.encodePacked(a)) == keccak256(abi.encodePacked(b))) { + emit log("Error: a != b not satisfied [string]"); + emit log_named_string(" Left", a); + emit log_named_string(" Right", b); + fail(); + } + } + function assertNotEq(string memory a, string memory b, string memory err) internal { + if (keccak256(abi.encodePacked(a)) == keccak256(abi.encodePacked(b))) { + emit log_named_string("Error", err); + assertNotEq(a, b); + } + } + + function checkEq0(bytes memory a, bytes memory b) internal pure returns (bool ok) { + ok = true; + if (a.length == b.length) { + for (uint i = 0; i < a.length; i++) { + if (a[i] != b[i]) { + ok = false; + } + } + } else { + ok = false; + } + } + function assertEq0(bytes memory a, bytes memory b) internal { + if (!checkEq0(a, b)) { + emit log("Error: a == b not satisfied [bytes]"); + emit log_named_bytes(" Left", a); + emit log_named_bytes(" Right", b); + fail(); + } + } + function assertEq0(bytes memory a, bytes memory b, string memory err) internal { + if (!checkEq0(a, b)) { + emit log_named_string("Error", err); + assertEq0(a, b); + } + } + + function assertNotEq0(bytes memory a, bytes memory b) internal { + if (checkEq0(a, b)) { + emit log("Error: a != b not satisfied [bytes]"); + emit log_named_bytes(" Left", a); + emit log_named_bytes(" Right", b); + fail(); + } + } + function assertNotEq0(bytes memory a, bytes memory b, string memory err) internal { + if (checkEq0(a, b)) { + emit log_named_string("Error", err); + assertNotEq0(a, b); + } + } +} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/lib/ds-test/src/test.t.sol b/packages/wallet/wallet-contracts/lib/forge-std/lib/ds-test/src/test.t.sol new file mode 100644 index 0000000000..d277a30945 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/lib/ds-test/src/test.t.sol @@ -0,0 +1,417 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity >=0.5.0; + +import {DSTest} from "./test.sol"; + +contract DemoTest is DSTest { + + // --- assertTrue --- + + function testAssertTrue() public { + assertTrue(true, "msg"); + assertTrue(true); + } + function testFailAssertTrue() public { + assertTrue(false); + } + function testFailAssertTrueWithMsg() public { + assertTrue(false, "msg"); + } + + // --- assertEq (Addr) --- + + function testAssertEqAddr() public { + assertEq(address(0x0), address(0x0), "msg"); + assertEq(address(0x0), address(0x0)); + } + function testFailAssertEqAddr() public { + assertEq(address(0x0), address(0x1)); + } + function testFailAssertEqAddrWithMsg() public { + assertEq(address(0x0), address(0x1), "msg"); + } + + // --- assertEq (Bytes32) --- + + function testAssertEqBytes32() public { + assertEq(bytes32("hi"), bytes32("hi"), "msg"); + assertEq(bytes32("hi"), bytes32("hi")); + } + function testFailAssertEqBytes32() public { + assertEq(bytes32("hi"), bytes32("ho")); + } + function testFailAssertEqBytes32WithMsg() public { + assertEq(bytes32("hi"), bytes32("ho"), "msg"); + } + + // --- assertEq (Int) --- + + function testAssertEqInt() public { + assertEq(-1, -1, "msg"); + assertEq(-1, -1); + } + function testFailAssertEqInt() public { + assertEq(-1, -2); + } + function testFailAssertEqIntWithMsg() public { + assertEq(-1, -2, "msg"); + } + + // --- assertEq (UInt) --- + + function testAssertEqUInt() public { + assertEq(uint(1), uint(1), "msg"); + assertEq(uint(1), uint(1)); + } + function testFailAssertEqUInt() public { + assertEq(uint(1), uint(2)); + } + function testFailAssertEqUIntWithMsg() public { + assertEq(uint(1), uint(2), "msg"); + } + + // --- assertEqDecimal (Int) --- + + function testAssertEqDecimalInt() public { + assertEqDecimal(-1, -1, 18, "msg"); + assertEqDecimal(-1, -1, 18); + } + function testFailAssertEqDecimalInt() public { + assertEqDecimal(-1, -2, 18); + } + function testFailAssertEqDecimalIntWithMsg() public { + assertEqDecimal(-1, -2, 18, "msg"); + } + + // --- assertEqDecimal (UInt) --- + + function testAssertEqDecimalUInt() public { + assertEqDecimal(uint(1), uint(1), 18, "msg"); + assertEqDecimal(uint(1), uint(1), 18); + } + function testFailAssertEqDecimalUInt() public { + assertEqDecimal(uint(1), uint(2), 18); + } + function testFailAssertEqDecimalUIntWithMsg() public { + assertEqDecimal(uint(1), uint(2), 18, "msg"); + } + + // --- assertNotEq (Addr) --- + + function testAssertNotEqAddr() public { + assertNotEq(address(0x0), address(0x1), "msg"); + assertNotEq(address(0x0), address(0x1)); + } + function testFailAssertNotEqAddr() public { + assertNotEq(address(0x0), address(0x0)); + } + function testFailAssertNotEqAddrWithMsg() public { + assertNotEq(address(0x0), address(0x0), "msg"); + } + + // --- assertNotEq (Bytes32) --- + + function testAssertNotEqBytes32() public { + assertNotEq(bytes32("hi"), bytes32("ho"), "msg"); + assertNotEq(bytes32("hi"), bytes32("ho")); + } + function testFailAssertNotEqBytes32() public { + assertNotEq(bytes32("hi"), bytes32("hi")); + } + function testFailAssertNotEqBytes32WithMsg() public { + assertNotEq(bytes32("hi"), bytes32("hi"), "msg"); + } + + // --- assertNotEq (Int) --- + + function testAssertNotEqInt() public { + assertNotEq(-1, -2, "msg"); + assertNotEq(-1, -2); + } + function testFailAssertNotEqInt() public { + assertNotEq(-1, -1); + } + function testFailAssertNotEqIntWithMsg() public { + assertNotEq(-1, -1, "msg"); + } + + // --- assertNotEq (UInt) --- + + function testAssertNotEqUInt() public { + assertNotEq(uint(1), uint(2), "msg"); + assertNotEq(uint(1), uint(2)); + } + function testFailAssertNotEqUInt() public { + assertNotEq(uint(1), uint(1)); + } + function testFailAssertNotEqUIntWithMsg() public { + assertNotEq(uint(1), uint(1), "msg"); + } + + // --- assertNotEqDecimal (Int) --- + + function testAssertNotEqDecimalInt() public { + assertNotEqDecimal(-1, -2, 18, "msg"); + assertNotEqDecimal(-1, -2, 18); + } + function testFailAssertNotEqDecimalInt() public { + assertNotEqDecimal(-1, -1, 18); + } + function testFailAssertNotEqDecimalIntWithMsg() public { + assertNotEqDecimal(-1, -1, 18, "msg"); + } + + // --- assertNotEqDecimal (UInt) --- + + function testAssertNotEqDecimalUInt() public { + assertNotEqDecimal(uint(1), uint(2), 18, "msg"); + assertNotEqDecimal(uint(1), uint(2), 18); + } + function testFailAssertNotEqDecimalUInt() public { + assertNotEqDecimal(uint(1), uint(1), 18); + } + function testFailAssertNotEqDecimalUIntWithMsg() public { + assertNotEqDecimal(uint(1), uint(1), 18, "msg"); + } + + // --- assertGt (UInt) --- + + function testAssertGtUInt() public { + assertGt(uint(2), uint(1), "msg"); + assertGt(uint(3), uint(2)); + } + function testFailAssertGtUInt() public { + assertGt(uint(1), uint(2)); + } + function testFailAssertGtUIntWithMsg() public { + assertGt(uint(1), uint(2), "msg"); + } + + // --- assertGt (Int) --- + + function testAssertGtInt() public { + assertGt(-1, -2, "msg"); + assertGt(-1, -3); + } + function testFailAssertGtInt() public { + assertGt(-2, -1); + } + function testFailAssertGtIntWithMsg() public { + assertGt(-2, -1, "msg"); + } + + // --- assertGtDecimal (UInt) --- + + function testAssertGtDecimalUInt() public { + assertGtDecimal(uint(2), uint(1), 18, "msg"); + assertGtDecimal(uint(3), uint(2), 18); + } + function testFailAssertGtDecimalUInt() public { + assertGtDecimal(uint(1), uint(2), 18); + } + function testFailAssertGtDecimalUIntWithMsg() public { + assertGtDecimal(uint(1), uint(2), 18, "msg"); + } + + // --- assertGtDecimal (Int) --- + + function testAssertGtDecimalInt() public { + assertGtDecimal(-1, -2, 18, "msg"); + assertGtDecimal(-1, -3, 18); + } + function testFailAssertGtDecimalInt() public { + assertGtDecimal(-2, -1, 18); + } + function testFailAssertGtDecimalIntWithMsg() public { + assertGtDecimal(-2, -1, 18, "msg"); + } + + // --- assertGe (UInt) --- + + function testAssertGeUInt() public { + assertGe(uint(2), uint(1), "msg"); + assertGe(uint(2), uint(2)); + } + function testFailAssertGeUInt() public { + assertGe(uint(1), uint(2)); + } + function testFailAssertGeUIntWithMsg() public { + assertGe(uint(1), uint(2), "msg"); + } + + // --- assertGe (Int) --- + + function testAssertGeInt() public { + assertGe(-1, -2, "msg"); + assertGe(-1, -1); + } + function testFailAssertGeInt() public { + assertGe(-2, -1); + } + function testFailAssertGeIntWithMsg() public { + assertGe(-2, -1, "msg"); + } + + // --- assertGeDecimal (UInt) --- + + function testAssertGeDecimalUInt() public { + assertGeDecimal(uint(2), uint(1), 18, "msg"); + assertGeDecimal(uint(2), uint(2), 18); + } + function testFailAssertGeDecimalUInt() public { + assertGeDecimal(uint(1), uint(2), 18); + } + function testFailAssertGeDecimalUIntWithMsg() public { + assertGeDecimal(uint(1), uint(2), 18, "msg"); + } + + // --- assertGeDecimal (Int) --- + + function testAssertGeDecimalInt() public { + assertGeDecimal(-1, -2, 18, "msg"); + assertGeDecimal(-1, -2, 18); + } + function testFailAssertGeDecimalInt() public { + assertGeDecimal(-2, -1, 18); + } + function testFailAssertGeDecimalIntWithMsg() public { + assertGeDecimal(-2, -1, 18, "msg"); + } + + // --- assertLt (UInt) --- + + function testAssertLtUInt() public { + assertLt(uint(1), uint(2), "msg"); + assertLt(uint(1), uint(3)); + } + function testFailAssertLtUInt() public { + assertLt(uint(2), uint(2)); + } + function testFailAssertLtUIntWithMsg() public { + assertLt(uint(3), uint(2), "msg"); + } + + // --- assertLt (Int) --- + + function testAssertLtInt() public { + assertLt(-2, -1, "msg"); + assertLt(-1, 0); + } + function testFailAssertLtInt() public { + assertLt(-1, -2); + } + function testFailAssertLtIntWithMsg() public { + assertLt(-1, -1, "msg"); + } + + // --- assertLtDecimal (UInt) --- + + function testAssertLtDecimalUInt() public { + assertLtDecimal(uint(1), uint(2), 18, "msg"); + assertLtDecimal(uint(2), uint(3), 18); + } + function testFailAssertLtDecimalUInt() public { + assertLtDecimal(uint(1), uint(1), 18); + } + function testFailAssertLtDecimalUIntWithMsg() public { + assertLtDecimal(uint(2), uint(1), 18, "msg"); + } + + // --- assertLtDecimal (Int) --- + + function testAssertLtDecimalInt() public { + assertLtDecimal(-2, -1, 18, "msg"); + assertLtDecimal(-2, -1, 18); + } + function testFailAssertLtDecimalInt() public { + assertLtDecimal(-2, -2, 18); + } + function testFailAssertLtDecimalIntWithMsg() public { + assertLtDecimal(-1, -2, 18, "msg"); + } + + // --- assertLe (UInt) --- + + function testAssertLeUInt() public { + assertLe(uint(1), uint(2), "msg"); + assertLe(uint(1), uint(1)); + } + function testFailAssertLeUInt() public { + assertLe(uint(4), uint(2)); + } + function testFailAssertLeUIntWithMsg() public { + assertLe(uint(3), uint(2), "msg"); + } + + // --- assertLe (Int) --- + + function testAssertLeInt() public { + assertLe(-2, -1, "msg"); + assertLe(-1, -1); + } + function testFailAssertLeInt() public { + assertLe(-1, -2); + } + function testFailAssertLeIntWithMsg() public { + assertLe(-1, -3, "msg"); + } + + // --- assertLeDecimal (UInt) --- + + function testAssertLeDecimalUInt() public { + assertLeDecimal(uint(1), uint(2), 18, "msg"); + assertLeDecimal(uint(2), uint(2), 18); + } + function testFailAssertLeDecimalUInt() public { + assertLeDecimal(uint(1), uint(0), 18); + } + function testFailAssertLeDecimalUIntWithMsg() public { + assertLeDecimal(uint(1), uint(0), 18, "msg"); + } + + // --- assertLeDecimal (Int) --- + + function testAssertLeDecimalInt() public { + assertLeDecimal(-2, -1, 18, "msg"); + assertLeDecimal(-2, -2, 18); + } + function testFailAssertLeDecimalInt() public { + assertLeDecimal(-2, -3, 18); + } + function testFailAssertLeDecimalIntWithMsg() public { + assertLeDecimal(-1, -2, 18, "msg"); + } + + // --- assertNotEq (String) --- + + function testAssertNotEqString() public { + assertNotEq(new string(1), new string(2), "msg"); + assertNotEq(new string(1), new string(2)); + } + function testFailAssertNotEqString() public { + assertNotEq(new string(1), new string(1)); + } + function testFailAssertNotEqStringWithMsg() public { + assertNotEq(new string(1), new string(1), "msg"); + } + + // --- assertNotEq0 (Bytes) --- + + function testAssertNotEq0Bytes() public { + assertNotEq0(bytes("hi"), bytes("ho"), "msg"); + assertNotEq0(bytes("hi"), bytes("ho")); + } + function testFailAssertNotEq0Bytes() public { + assertNotEq0(bytes("hi"), bytes("hi")); + } + function testFailAssertNotEq0BytesWithMsg() public { + assertNotEq0(bytes("hi"), bytes("hi"), "msg"); + } + + // --- fail override --- + + // ensure that fail can be overridden + function fail() internal override { + super.fail(); + } +} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/package.json b/packages/wallet/wallet-contracts/lib/forge-std/package.json new file mode 100644 index 0000000000..c98539d2dd --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/package.json @@ -0,0 +1,16 @@ +{ + "name": "forge-std", + "version": "1.5.5", + "description": "Forge Standard Library is a collection of helpful contracts and libraries for use with Forge and Foundry.", + "homepage": "https://book.getfoundry.sh/forge/forge-std", + "bugs": "https://github.com/foundry-rs/forge-std/issues", + "license": "(Apache-2.0 OR MIT)", + "author": "Contributors to Forge Standard Library", + "files": [ + "src/**/*" + ], + "repository": { + "type": "git", + "url": "https://github.com/foundry-rs/forge-std.git" + } +} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/src/Base.sol b/packages/wallet/wallet-contracts/lib/forge-std/src/Base.sol new file mode 100644 index 0000000000..83c5c1cfcb --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/src/Base.sol @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +import {StdStorage} from "./StdStorage.sol"; +import {Vm, VmSafe} from "./Vm.sol"; + +abstract contract CommonBase { + // Cheat code address, 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D. + address internal constant VM_ADDRESS = address(uint160(uint256(keccak256("hevm cheat code")))); + // console.sol and console2.sol work by executing a staticcall to this address. + address internal constant CONSOLE = 0x000000000000000000636F6e736F6c652e6c6f67; + // Default address for tx.origin and msg.sender, 0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38. + address internal constant DEFAULT_SENDER = address(uint160(uint256(keccak256("foundry default caller")))); + // Address of the test contract, deployed by the DEFAULT_SENDER. + address internal constant DEFAULT_TEST_CONTRACT = 0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f; + // Deterministic deployment address of the Multicall3 contract. + address internal constant MULTICALL3_ADDRESS = 0xcA11bde05977b3631167028862bE2a173976CA11; + + uint256 internal constant UINT256_MAX = + 115792089237316195423570985008687907853269984665640564039457584007913129639935; + + Vm internal constant vm = Vm(VM_ADDRESS); + StdStorage internal stdstore; +} + +abstract contract TestBase is CommonBase {} + +abstract contract ScriptBase is CommonBase { + // Used when deploying with create2, https://github.com/Arachnid/deterministic-deployment-proxy. + address internal constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C; + + VmSafe internal constant vmSafe = VmSafe(VM_ADDRESS); +} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/src/Script.sol b/packages/wallet/wallet-contracts/lib/forge-std/src/Script.sol new file mode 100644 index 0000000000..bffccadbe4 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/src/Script.sol @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +// šŸ’¬ ABOUT +// Standard Library's default Script. + +// 🧩 MODULES +import {ScriptBase} from "./Base.sol"; +import {console} from "./console.sol"; +import {console2} from "./console2.sol"; +import {StdChains} from "./StdChains.sol"; +import {StdCheatsSafe} from "./StdCheats.sol"; +import {stdJson} from "./StdJson.sol"; +import {stdMath} from "./StdMath.sol"; +import {StdStorage, stdStorageSafe} from "./StdStorage.sol"; +import {StdUtils} from "./StdUtils.sol"; +import {VmSafe} from "./Vm.sol"; + +// šŸ“¦ BOILERPLATE +import {ScriptBase} from "./Base.sol"; + +// ā­ļø SCRIPT +abstract contract Script is StdChains, StdCheatsSafe, StdUtils, ScriptBase { + // Note: IS_SCRIPT() must return true. + bool public IS_SCRIPT = true; +} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/src/StdAssertions.sol b/packages/wallet/wallet-contracts/lib/forge-std/src/StdAssertions.sol new file mode 100644 index 0000000000..2778b3a0e8 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/src/StdAssertions.sol @@ -0,0 +1,376 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +import {DSTest} from "ds-test/test.sol"; +import {stdMath} from "./StdMath.sol"; + +abstract contract StdAssertions is DSTest { + event log_array(uint256[] val); + event log_array(int256[] val); + event log_array(address[] val); + event log_named_array(string key, uint256[] val); + event log_named_array(string key, int256[] val); + event log_named_array(string key, address[] val); + + function fail(string memory err) internal virtual { + emit log_named_string("Error", err); + fail(); + } + + function assertFalse(bool data) internal virtual { + assertTrue(!data); + } + + function assertFalse(bool data, string memory err) internal virtual { + assertTrue(!data, err); + } + + function assertEq(bool a, bool b) internal virtual { + if (a != b) { + emit log("Error: a == b not satisfied [bool]"); + emit log_named_string(" Left", a ? "true" : "false"); + emit log_named_string(" Right", b ? "true" : "false"); + fail(); + } + } + + function assertEq(bool a, bool b, string memory err) internal virtual { + if (a != b) { + emit log_named_string("Error", err); + assertEq(a, b); + } + } + + function assertEq(bytes memory a, bytes memory b) internal virtual { + assertEq0(a, b); + } + + function assertEq(bytes memory a, bytes memory b, string memory err) internal virtual { + assertEq0(a, b, err); + } + + function assertEq(uint256[] memory a, uint256[] memory b) internal virtual { + if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { + emit log("Error: a == b not satisfied [uint[]]"); + emit log_named_array(" Left", a); + emit log_named_array(" Right", b); + fail(); + } + } + + function assertEq(int256[] memory a, int256[] memory b) internal virtual { + if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { + emit log("Error: a == b not satisfied [int[]]"); + emit log_named_array(" Left", a); + emit log_named_array(" Right", b); + fail(); + } + } + + function assertEq(address[] memory a, address[] memory b) internal virtual { + if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { + emit log("Error: a == b not satisfied [address[]]"); + emit log_named_array(" Left", a); + emit log_named_array(" Right", b); + fail(); + } + } + + function assertEq(uint256[] memory a, uint256[] memory b, string memory err) internal virtual { + if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { + emit log_named_string("Error", err); + assertEq(a, b); + } + } + + function assertEq(int256[] memory a, int256[] memory b, string memory err) internal virtual { + if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { + emit log_named_string("Error", err); + assertEq(a, b); + } + } + + function assertEq(address[] memory a, address[] memory b, string memory err) internal virtual { + if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { + emit log_named_string("Error", err); + assertEq(a, b); + } + } + + // Legacy helper + function assertEqUint(uint256 a, uint256 b) internal virtual { + assertEq(uint256(a), uint256(b)); + } + + function assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta) internal virtual { + uint256 delta = stdMath.delta(a, b); + + if (delta > maxDelta) { + emit log("Error: a ~= b not satisfied [uint]"); + emit log_named_uint(" Left", a); + emit log_named_uint(" Right", b); + emit log_named_uint(" Max Delta", maxDelta); + emit log_named_uint(" Delta", delta); + fail(); + } + } + + function assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta, string memory err) internal virtual { + uint256 delta = stdMath.delta(a, b); + + if (delta > maxDelta) { + emit log_named_string("Error", err); + assertApproxEqAbs(a, b, maxDelta); + } + } + + function assertApproxEqAbsDecimal(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals) internal virtual { + uint256 delta = stdMath.delta(a, b); + + if (delta > maxDelta) { + emit log("Error: a ~= b not satisfied [uint]"); + emit log_named_decimal_uint(" Left", a, decimals); + emit log_named_decimal_uint(" Right", b, decimals); + emit log_named_decimal_uint(" Max Delta", maxDelta, decimals); + emit log_named_decimal_uint(" Delta", delta, decimals); + fail(); + } + } + + function assertApproxEqAbsDecimal(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals, string memory err) + internal + virtual + { + uint256 delta = stdMath.delta(a, b); + + if (delta > maxDelta) { + emit log_named_string("Error", err); + assertApproxEqAbsDecimal(a, b, maxDelta, decimals); + } + } + + function assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta) internal virtual { + uint256 delta = stdMath.delta(a, b); + + if (delta > maxDelta) { + emit log("Error: a ~= b not satisfied [int]"); + emit log_named_int(" Left", a); + emit log_named_int(" Right", b); + emit log_named_uint(" Max Delta", maxDelta); + emit log_named_uint(" Delta", delta); + fail(); + } + } + + function assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta, string memory err) internal virtual { + uint256 delta = stdMath.delta(a, b); + + if (delta > maxDelta) { + emit log_named_string("Error", err); + assertApproxEqAbs(a, b, maxDelta); + } + } + + function assertApproxEqAbsDecimal(int256 a, int256 b, uint256 maxDelta, uint256 decimals) internal virtual { + uint256 delta = stdMath.delta(a, b); + + if (delta > maxDelta) { + emit log("Error: a ~= b not satisfied [int]"); + emit log_named_decimal_int(" Left", a, decimals); + emit log_named_decimal_int(" Right", b, decimals); + emit log_named_decimal_uint(" Max Delta", maxDelta, decimals); + emit log_named_decimal_uint(" Delta", delta, decimals); + fail(); + } + } + + function assertApproxEqAbsDecimal(int256 a, int256 b, uint256 maxDelta, uint256 decimals, string memory err) + internal + virtual + { + uint256 delta = stdMath.delta(a, b); + + if (delta > maxDelta) { + emit log_named_string("Error", err); + assertApproxEqAbsDecimal(a, b, maxDelta, decimals); + } + } + + function assertApproxEqRel( + uint256 a, + uint256 b, + uint256 maxPercentDelta // An 18 decimal fixed point number, where 1e18 == 100% + ) internal virtual { + if (b == 0) return assertEq(a, b); // If the left is 0, right must be too. + + uint256 percentDelta = stdMath.percentDelta(a, b); + + if (percentDelta > maxPercentDelta) { + emit log("Error: a ~= b not satisfied [uint]"); + emit log_named_uint(" Left", a); + emit log_named_uint(" Right", b); + emit log_named_decimal_uint(" Max % Delta", maxPercentDelta * 100, 18); + emit log_named_decimal_uint(" % Delta", percentDelta * 100, 18); + fail(); + } + } + + function assertApproxEqRel( + uint256 a, + uint256 b, + uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% + string memory err + ) internal virtual { + if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too. + + uint256 percentDelta = stdMath.percentDelta(a, b); + + if (percentDelta > maxPercentDelta) { + emit log_named_string("Error", err); + assertApproxEqRel(a, b, maxPercentDelta); + } + } + + function assertApproxEqRelDecimal( + uint256 a, + uint256 b, + uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% + uint256 decimals + ) internal virtual { + if (b == 0) return assertEq(a, b); // If the left is 0, right must be too. + + uint256 percentDelta = stdMath.percentDelta(a, b); + + if (percentDelta > maxPercentDelta) { + emit log("Error: a ~= b not satisfied [uint]"); + emit log_named_decimal_uint(" Left", a, decimals); + emit log_named_decimal_uint(" Right", b, decimals); + emit log_named_decimal_uint(" Max % Delta", maxPercentDelta * 100, 18); + emit log_named_decimal_uint(" % Delta", percentDelta * 100, 18); + fail(); + } + } + + function assertApproxEqRelDecimal( + uint256 a, + uint256 b, + uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% + uint256 decimals, + string memory err + ) internal virtual { + if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too. + + uint256 percentDelta = stdMath.percentDelta(a, b); + + if (percentDelta > maxPercentDelta) { + emit log_named_string("Error", err); + assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals); + } + } + + function assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta) internal virtual { + if (b == 0) return assertEq(a, b); // If the left is 0, right must be too. + + uint256 percentDelta = stdMath.percentDelta(a, b); + + if (percentDelta > maxPercentDelta) { + emit log("Error: a ~= b not satisfied [int]"); + emit log_named_int(" Left", a); + emit log_named_int(" Right", b); + emit log_named_decimal_uint(" Max % Delta", maxPercentDelta * 100, 18); + emit log_named_decimal_uint(" % Delta", percentDelta * 100, 18); + fail(); + } + } + + function assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta, string memory err) internal virtual { + if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too. + + uint256 percentDelta = stdMath.percentDelta(a, b); + + if (percentDelta > maxPercentDelta) { + emit log_named_string("Error", err); + assertApproxEqRel(a, b, maxPercentDelta); + } + } + + function assertApproxEqRelDecimal(int256 a, int256 b, uint256 maxPercentDelta, uint256 decimals) internal virtual { + if (b == 0) return assertEq(a, b); // If the left is 0, right must be too. + + uint256 percentDelta = stdMath.percentDelta(a, b); + + if (percentDelta > maxPercentDelta) { + emit log("Error: a ~= b not satisfied [int]"); + emit log_named_decimal_int(" Left", a, decimals); + emit log_named_decimal_int(" Right", b, decimals); + emit log_named_decimal_uint(" Max % Delta", maxPercentDelta * 100, 18); + emit log_named_decimal_uint(" % Delta", percentDelta * 100, 18); + fail(); + } + } + + function assertApproxEqRelDecimal(int256 a, int256 b, uint256 maxPercentDelta, uint256 decimals, string memory err) + internal + virtual + { + if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too. + + uint256 percentDelta = stdMath.percentDelta(a, b); + + if (percentDelta > maxPercentDelta) { + emit log_named_string("Error", err); + assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals); + } + } + + function assertEqCall(address target, bytes memory callDataA, bytes memory callDataB) internal virtual { + assertEqCall(target, callDataA, target, callDataB, true); + } + + function assertEqCall(address targetA, bytes memory callDataA, address targetB, bytes memory callDataB) + internal + virtual + { + assertEqCall(targetA, callDataA, targetB, callDataB, true); + } + + function assertEqCall(address target, bytes memory callDataA, bytes memory callDataB, bool strictRevertData) + internal + virtual + { + assertEqCall(target, callDataA, target, callDataB, strictRevertData); + } + + function assertEqCall( + address targetA, + bytes memory callDataA, + address targetB, + bytes memory callDataB, + bool strictRevertData + ) internal virtual { + (bool successA, bytes memory returnDataA) = address(targetA).call(callDataA); + (bool successB, bytes memory returnDataB) = address(targetB).call(callDataB); + + if (successA && successB) { + assertEq(returnDataA, returnDataB, "Call return data does not match"); + } + + if (!successA && !successB && strictRevertData) { + assertEq(returnDataA, returnDataB, "Call revert data does not match"); + } + + if (!successA && successB) { + emit log("Error: Calls were not equal"); + emit log_named_bytes(" Left call revert data", returnDataA); + emit log_named_bytes(" Right call return data", returnDataB); + fail(); + } + + if (successA && !successB) { + emit log("Error: Calls were not equal"); + emit log_named_bytes(" Left call return data", returnDataA); + emit log_named_bytes(" Right call revert data", returnDataB); + fail(); + } + } +} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/src/StdChains.sol b/packages/wallet/wallet-contracts/lib/forge-std/src/StdChains.sol new file mode 100644 index 0000000000..f97637fc45 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/src/StdChains.sol @@ -0,0 +1,231 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +import {VmSafe} from "./Vm.sol"; + +/** + * StdChains provides information about EVM compatible chains that can be used in scripts/tests. + * For each chain, the chain's name, chain ID, and a default RPC URL are provided. Chains are + * identified by their alias, which is the same as the alias in the `[rpc_endpoints]` section of + * the `foundry.toml` file. For best UX, ensure the alias in the `foundry.toml` file match the + * alias used in this contract, which can be found as the first argument to the + * `setChainWithDefaultRpcUrl` call in the `initializeStdChains` function. + * + * There are two main ways to use this contract: + * 1. Set a chain with `setChain(string memory chainAlias, ChainData memory chain)` or + * `setChain(string memory chainAlias, Chain memory chain)` + * 2. Get a chain with `getChain(string memory chainAlias)` or `getChain(uint256 chainId)`. + * + * The first time either of those are used, chains are initialized with the default set of RPC URLs. + * This is done in `initializeStdChains`, which uses `setChainWithDefaultRpcUrl`. Defaults are recorded in + * `defaultRpcUrls`. + * + * The `setChain` function is straightforward, and it simply saves off the given chain data. + * + * The `getChain` methods use `getChainWithUpdatedRpcUrl` to return a chain. For example, let's say + * we want to retrieve the RPC URL for `mainnet`: + * - If you have specified data with `setChain`, it will return that. + * - If you have configured a mainnet RPC URL in `foundry.toml`, it will return the URL, provided it + * is valid (e.g. a URL is specified, or an environment variable is given and exists). + * - If neither of the above conditions is met, the default data is returned. + * + * Summarizing the above, the prioritization hierarchy is `setChain` -> `foundry.toml` -> environment variable -> defaults. + */ +abstract contract StdChains { + VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); + + bool private stdChainsInitialized; + + struct ChainData { + string name; + uint256 chainId; + string rpcUrl; + } + + struct Chain { + // The chain name. + string name; + // The chain's Chain ID. + uint256 chainId; + // The chain's alias. (i.e. what gets specified in `foundry.toml`). + string chainAlias; + // A default RPC endpoint for this chain. + // NOTE: This default RPC URL is included for convenience to facilitate quick tests and + // experimentation. Do not use this RPC URL for production test suites, CI, or other heavy + // usage as you will be throttled and this is a disservice to others who need this endpoint. + string rpcUrl; + } + + // Maps from the chain's alias (matching the alias in the `foundry.toml` file) to chain data. + mapping(string => Chain) private chains; + // Maps from the chain's alias to it's default RPC URL. + mapping(string => string) private defaultRpcUrls; + // Maps from a chain ID to it's alias. + mapping(uint256 => string) private idToAlias; + + bool private fallbackToDefaultRpcUrls = true; + + // The RPC URL will be fetched from config or defaultRpcUrls if possible. + function getChain(string memory chainAlias) internal virtual returns (Chain memory chain) { + require(bytes(chainAlias).length != 0, "StdChains getChain(string): Chain alias cannot be the empty string."); + + initializeStdChains(); + chain = chains[chainAlias]; + require( + chain.chainId != 0, + string(abi.encodePacked("StdChains getChain(string): Chain with alias \"", chainAlias, "\" not found.")) + ); + + chain = getChainWithUpdatedRpcUrl(chainAlias, chain); + } + + function getChain(uint256 chainId) internal virtual returns (Chain memory chain) { + require(chainId != 0, "StdChains getChain(uint256): Chain ID cannot be 0."); + initializeStdChains(); + string memory chainAlias = idToAlias[chainId]; + + chain = chains[chainAlias]; + + require( + chain.chainId != 0, + string(abi.encodePacked("StdChains getChain(uint256): Chain with ID ", vm.toString(chainId), " not found.")) + ); + + chain = getChainWithUpdatedRpcUrl(chainAlias, chain); + } + + // set chain info, with priority to argument's rpcUrl field. + function setChain(string memory chainAlias, ChainData memory chain) internal virtual { + require( + bytes(chainAlias).length != 0, + "StdChains setChain(string,ChainData): Chain alias cannot be the empty string." + ); + + require(chain.chainId != 0, "StdChains setChain(string,ChainData): Chain ID cannot be 0."); + + initializeStdChains(); + string memory foundAlias = idToAlias[chain.chainId]; + + require( + bytes(foundAlias).length == 0 || keccak256(bytes(foundAlias)) == keccak256(bytes(chainAlias)), + string( + abi.encodePacked( + "StdChains setChain(string,ChainData): Chain ID ", + vm.toString(chain.chainId), + " already used by \"", + foundAlias, + "\"." + ) + ) + ); + + uint256 oldChainId = chains[chainAlias].chainId; + delete idToAlias[oldChainId]; + + chains[chainAlias] = + Chain({name: chain.name, chainId: chain.chainId, chainAlias: chainAlias, rpcUrl: chain.rpcUrl}); + idToAlias[chain.chainId] = chainAlias; + } + + // set chain info, with priority to argument's rpcUrl field. + function setChain(string memory chainAlias, Chain memory chain) internal virtual { + setChain(chainAlias, ChainData({name: chain.name, chainId: chain.chainId, rpcUrl: chain.rpcUrl})); + } + + function _toUpper(string memory str) private pure returns (string memory) { + bytes memory strb = bytes(str); + bytes memory copy = new bytes(strb.length); + for (uint256 i = 0; i < strb.length; i++) { + bytes1 b = strb[i]; + if (b >= 0x61 && b <= 0x7A) { + copy[i] = bytes1(uint8(b) - 32); + } else { + copy[i] = b; + } + } + return string(copy); + } + + // lookup rpcUrl, in descending order of priority: + // current -> config (foundry.toml) -> environment variable -> default + function getChainWithUpdatedRpcUrl(string memory chainAlias, Chain memory chain) private returns (Chain memory) { + if (bytes(chain.rpcUrl).length == 0) { + try vm.rpcUrl(chainAlias) returns (string memory configRpcUrl) { + chain.rpcUrl = configRpcUrl; + } catch (bytes memory err) { + string memory envName = string(abi.encodePacked(_toUpper(chainAlias), "_RPC_URL")); + if (fallbackToDefaultRpcUrls) { + chain.rpcUrl = vm.envOr(envName, defaultRpcUrls[chainAlias]); + } else { + chain.rpcUrl = vm.envString(envName); + } + // distinguish 'not found' from 'cannot read' + bytes memory notFoundError = + abi.encodeWithSignature("CheatCodeError", string(abi.encodePacked("invalid rpc url ", chainAlias))); + if (keccak256(notFoundError) != keccak256(err) || bytes(chain.rpcUrl).length == 0) { + /// @solidity memory-safe-assembly + assembly { + revert(add(32, err), mload(err)) + } + } + } + } + return chain; + } + + function setFallbackToDefaultRpcUrls(bool useDefault) internal { + fallbackToDefaultRpcUrls = useDefault; + } + + function initializeStdChains() private { + if (stdChainsInitialized) return; + + stdChainsInitialized = true; + + // If adding an RPC here, make sure to test the default RPC URL in `testRpcs` + setChainWithDefaultRpcUrl("anvil", ChainData("Anvil", 31337, "http://127.0.0.1:8545")); + setChainWithDefaultRpcUrl( + "mainnet", ChainData("Mainnet", 1, "https://mainnet.infura.io/v3/b9794ad1ddf84dfb8c34d6bb5dca2001") + ); + setChainWithDefaultRpcUrl( + "goerli", ChainData("Goerli", 5, "https://goerli.infura.io/v3/b9794ad1ddf84dfb8c34d6bb5dca2001") + ); + setChainWithDefaultRpcUrl( + "sepolia", ChainData("Sepolia", 11155111, "https://sepolia.infura.io/v3/b9794ad1ddf84dfb8c34d6bb5dca2001") + ); + setChainWithDefaultRpcUrl("optimism", ChainData("Optimism", 10, "https://mainnet.optimism.io")); + setChainWithDefaultRpcUrl("optimism_goerli", ChainData("Optimism Goerli", 420, "https://goerli.optimism.io")); + setChainWithDefaultRpcUrl("arbitrum_one", ChainData("Arbitrum One", 42161, "https://arb1.arbitrum.io/rpc")); + setChainWithDefaultRpcUrl( + "arbitrum_one_goerli", ChainData("Arbitrum One Goerli", 421613, "https://goerli-rollup.arbitrum.io/rpc") + ); + setChainWithDefaultRpcUrl("arbitrum_nova", ChainData("Arbitrum Nova", 42170, "https://nova.arbitrum.io/rpc")); + setChainWithDefaultRpcUrl("polygon", ChainData("Polygon", 137, "https://polygon-rpc.com")); + setChainWithDefaultRpcUrl( + "polygon_mumbai", ChainData("Polygon Mumbai", 80001, "https://rpc-mumbai.maticvigil.com") + ); + setChainWithDefaultRpcUrl("avalanche", ChainData("Avalanche", 43114, "https://api.avax.network/ext/bc/C/rpc")); + setChainWithDefaultRpcUrl( + "avalanche_fuji", ChainData("Avalanche Fuji", 43113, "https://api.avax-test.network/ext/bc/C/rpc") + ); + setChainWithDefaultRpcUrl( + "bnb_smart_chain", ChainData("BNB Smart Chain", 56, "https://bsc-dataseed1.binance.org") + ); + setChainWithDefaultRpcUrl( + "bnb_smart_chain_testnet", + ChainData("BNB Smart Chain Testnet", 97, "https://rpc.ankr.com/bsc_testnet_chapel") + ); + setChainWithDefaultRpcUrl("gnosis_chain", ChainData("Gnosis Chain", 100, "https://rpc.gnosischain.com")); + } + + // set chain info, with priority to chainAlias' rpc url in foundry.toml + function setChainWithDefaultRpcUrl(string memory chainAlias, ChainData memory chain) private { + string memory rpcUrl = chain.rpcUrl; + defaultRpcUrls[chainAlias] = rpcUrl; + chain.rpcUrl = ""; + setChain(chainAlias, chain); + chain.rpcUrl = rpcUrl; // restore argument + } +} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/src/StdCheats.sol b/packages/wallet/wallet-contracts/lib/forge-std/src/StdCheats.sol new file mode 100644 index 0000000000..d4d56701f8 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/src/StdCheats.sol @@ -0,0 +1,639 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +import {StdStorage, stdStorage} from "./StdStorage.sol"; +import {Vm} from "./Vm.sol"; + +abstract contract StdCheatsSafe { + Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + + bool private gasMeteringOff; + + // Data structures to parse Transaction objects from the broadcast artifact + // that conform to EIP1559. The Raw structs is what is parsed from the JSON + // and then converted to the one that is used by the user for better UX. + + struct RawTx1559 { + string[] arguments; + address contractAddress; + string contractName; + // json value name = function + string functionSig; + bytes32 hash; + // json value name = tx + RawTx1559Detail txDetail; + // json value name = type + string opcode; + } + + struct RawTx1559Detail { + AccessList[] accessList; + bytes data; + address from; + bytes gas; + bytes nonce; + address to; + bytes txType; + bytes value; + } + + struct Tx1559 { + string[] arguments; + address contractAddress; + string contractName; + string functionSig; + bytes32 hash; + Tx1559Detail txDetail; + string opcode; + } + + struct Tx1559Detail { + AccessList[] accessList; + bytes data; + address from; + uint256 gas; + uint256 nonce; + address to; + uint256 txType; + uint256 value; + } + + // Data structures to parse Transaction objects from the broadcast artifact + // that DO NOT conform to EIP1559. The Raw structs is what is parsed from the JSON + // and then converted to the one that is used by the user for better UX. + + struct TxLegacy { + string[] arguments; + address contractAddress; + string contractName; + string functionSig; + string hash; + string opcode; + TxDetailLegacy transaction; + } + + struct TxDetailLegacy { + AccessList[] accessList; + uint256 chainId; + bytes data; + address from; + uint256 gas; + uint256 gasPrice; + bytes32 hash; + uint256 nonce; + bytes1 opcode; + bytes32 r; + bytes32 s; + uint256 txType; + address to; + uint8 v; + uint256 value; + } + + struct AccessList { + address accessAddress; + bytes32[] storageKeys; + } + + // Data structures to parse Receipt objects from the broadcast artifact. + // The Raw structs is what is parsed from the JSON + // and then converted to the one that is used by the user for better UX. + + struct RawReceipt { + bytes32 blockHash; + bytes blockNumber; + address contractAddress; + bytes cumulativeGasUsed; + bytes effectiveGasPrice; + address from; + bytes gasUsed; + RawReceiptLog[] logs; + bytes logsBloom; + bytes status; + address to; + bytes32 transactionHash; + bytes transactionIndex; + } + + struct Receipt { + bytes32 blockHash; + uint256 blockNumber; + address contractAddress; + uint256 cumulativeGasUsed; + uint256 effectiveGasPrice; + address from; + uint256 gasUsed; + ReceiptLog[] logs; + bytes logsBloom; + uint256 status; + address to; + bytes32 transactionHash; + uint256 transactionIndex; + } + + // Data structures to parse the entire broadcast artifact, assuming the + // transactions conform to EIP1559. + + struct EIP1559ScriptArtifact { + string[] libraries; + string path; + string[] pending; + Receipt[] receipts; + uint256 timestamp; + Tx1559[] transactions; + TxReturn[] txReturns; + } + + struct RawEIP1559ScriptArtifact { + string[] libraries; + string path; + string[] pending; + RawReceipt[] receipts; + TxReturn[] txReturns; + uint256 timestamp; + RawTx1559[] transactions; + } + + struct RawReceiptLog { + // json value = address + address logAddress; + bytes32 blockHash; + bytes blockNumber; + bytes data; + bytes logIndex; + bool removed; + bytes32[] topics; + bytes32 transactionHash; + bytes transactionIndex; + bytes transactionLogIndex; + } + + struct ReceiptLog { + // json value = address + address logAddress; + bytes32 blockHash; + uint256 blockNumber; + bytes data; + uint256 logIndex; + bytes32[] topics; + uint256 transactionIndex; + uint256 transactionLogIndex; + bool removed; + } + + struct TxReturn { + string internalType; + string value; + } + + struct Account { + address addr; + uint256 key; + } + + function assumeNoPrecompiles(address addr) internal virtual { + // Assembly required since `block.chainid` was introduced in 0.8.0. + uint256 chainId; + assembly { + chainId := chainid() + } + assumeNoPrecompiles(addr, chainId); + } + + function assumeNoPrecompiles(address addr, uint256 chainId) internal pure virtual { + // Note: For some chains like Optimism these are technically predeploys (i.e. bytecode placed at a specific + // address), but the same rationale for excluding them applies so we include those too. + + // These should be present on all EVM-compatible chains. + vm.assume(addr < address(0x1) || addr > address(0x9)); + + // forgefmt: disable-start + if (chainId == 10 || chainId == 420) { + // https://github.com/ethereum-optimism/optimism/blob/eaa371a0184b56b7ca6d9eb9cb0a2b78b2ccd864/op-bindings/predeploys/addresses.go#L6-L21 + vm.assume(addr < address(0x4200000000000000000000000000000000000000) || addr > address(0x4200000000000000000000000000000000000800)); + } else if (chainId == 42161 || chainId == 421613) { + // https://developer.arbitrum.io/useful-addresses#arbitrum-precompiles-l2-same-on-all-arb-chains + vm.assume(addr < address(0x0000000000000000000000000000000000000064) || addr > address(0x0000000000000000000000000000000000000068)); + } else if (chainId == 43114 || chainId == 43113) { + // https://github.com/ava-labs/subnet-evm/blob/47c03fd007ecaa6de2c52ea081596e0a88401f58/precompile/params.go#L18-L59 + vm.assume(addr < address(0x0100000000000000000000000000000000000000) || addr > address(0x01000000000000000000000000000000000000ff)); + vm.assume(addr < address(0x0200000000000000000000000000000000000000) || addr > address(0x02000000000000000000000000000000000000FF)); + vm.assume(addr < address(0x0300000000000000000000000000000000000000) || addr > address(0x03000000000000000000000000000000000000Ff)); + } + // forgefmt: disable-end + } + + function readEIP1559ScriptArtifact(string memory path) + internal + view + virtual + returns (EIP1559ScriptArtifact memory) + { + string memory data = vm.readFile(path); + bytes memory parsedData = vm.parseJson(data); + RawEIP1559ScriptArtifact memory rawArtifact = abi.decode(parsedData, (RawEIP1559ScriptArtifact)); + EIP1559ScriptArtifact memory artifact; + artifact.libraries = rawArtifact.libraries; + artifact.path = rawArtifact.path; + artifact.timestamp = rawArtifact.timestamp; + artifact.pending = rawArtifact.pending; + artifact.txReturns = rawArtifact.txReturns; + artifact.receipts = rawToConvertedReceipts(rawArtifact.receipts); + artifact.transactions = rawToConvertedEIPTx1559s(rawArtifact.transactions); + return artifact; + } + + function rawToConvertedEIPTx1559s(RawTx1559[] memory rawTxs) internal pure virtual returns (Tx1559[] memory) { + Tx1559[] memory txs = new Tx1559[](rawTxs.length); + for (uint256 i; i < rawTxs.length; i++) { + txs[i] = rawToConvertedEIPTx1559(rawTxs[i]); + } + return txs; + } + + function rawToConvertedEIPTx1559(RawTx1559 memory rawTx) internal pure virtual returns (Tx1559 memory) { + Tx1559 memory transaction; + transaction.arguments = rawTx.arguments; + transaction.contractName = rawTx.contractName; + transaction.functionSig = rawTx.functionSig; + transaction.hash = rawTx.hash; + transaction.txDetail = rawToConvertedEIP1559Detail(rawTx.txDetail); + transaction.opcode = rawTx.opcode; + return transaction; + } + + function rawToConvertedEIP1559Detail(RawTx1559Detail memory rawDetail) + internal + pure + virtual + returns (Tx1559Detail memory) + { + Tx1559Detail memory txDetail; + txDetail.data = rawDetail.data; + txDetail.from = rawDetail.from; + txDetail.to = rawDetail.to; + txDetail.nonce = _bytesToUint(rawDetail.nonce); + txDetail.txType = _bytesToUint(rawDetail.txType); + txDetail.value = _bytesToUint(rawDetail.value); + txDetail.gas = _bytesToUint(rawDetail.gas); + txDetail.accessList = rawDetail.accessList; + return txDetail; + } + + function readTx1559s(string memory path) internal view virtual returns (Tx1559[] memory) { + string memory deployData = vm.readFile(path); + bytes memory parsedDeployData = vm.parseJson(deployData, ".transactions"); + RawTx1559[] memory rawTxs = abi.decode(parsedDeployData, (RawTx1559[])); + return rawToConvertedEIPTx1559s(rawTxs); + } + + function readTx1559(string memory path, uint256 index) internal view virtual returns (Tx1559 memory) { + string memory deployData = vm.readFile(path); + string memory key = string(abi.encodePacked(".transactions[", vm.toString(index), "]")); + bytes memory parsedDeployData = vm.parseJson(deployData, key); + RawTx1559 memory rawTx = abi.decode(parsedDeployData, (RawTx1559)); + return rawToConvertedEIPTx1559(rawTx); + } + + // Analogous to readTransactions, but for receipts. + function readReceipts(string memory path) internal view virtual returns (Receipt[] memory) { + string memory deployData = vm.readFile(path); + bytes memory parsedDeployData = vm.parseJson(deployData, ".receipts"); + RawReceipt[] memory rawReceipts = abi.decode(parsedDeployData, (RawReceipt[])); + return rawToConvertedReceipts(rawReceipts); + } + + function readReceipt(string memory path, uint256 index) internal view virtual returns (Receipt memory) { + string memory deployData = vm.readFile(path); + string memory key = string(abi.encodePacked(".receipts[", vm.toString(index), "]")); + bytes memory parsedDeployData = vm.parseJson(deployData, key); + RawReceipt memory rawReceipt = abi.decode(parsedDeployData, (RawReceipt)); + return rawToConvertedReceipt(rawReceipt); + } + + function rawToConvertedReceipts(RawReceipt[] memory rawReceipts) internal pure virtual returns (Receipt[] memory) { + Receipt[] memory receipts = new Receipt[](rawReceipts.length); + for (uint256 i; i < rawReceipts.length; i++) { + receipts[i] = rawToConvertedReceipt(rawReceipts[i]); + } + return receipts; + } + + function rawToConvertedReceipt(RawReceipt memory rawReceipt) internal pure virtual returns (Receipt memory) { + Receipt memory receipt; + receipt.blockHash = rawReceipt.blockHash; + receipt.to = rawReceipt.to; + receipt.from = rawReceipt.from; + receipt.contractAddress = rawReceipt.contractAddress; + receipt.effectiveGasPrice = _bytesToUint(rawReceipt.effectiveGasPrice); + receipt.cumulativeGasUsed = _bytesToUint(rawReceipt.cumulativeGasUsed); + receipt.gasUsed = _bytesToUint(rawReceipt.gasUsed); + receipt.status = _bytesToUint(rawReceipt.status); + receipt.transactionIndex = _bytesToUint(rawReceipt.transactionIndex); + receipt.blockNumber = _bytesToUint(rawReceipt.blockNumber); + receipt.logs = rawToConvertedReceiptLogs(rawReceipt.logs); + receipt.logsBloom = rawReceipt.logsBloom; + receipt.transactionHash = rawReceipt.transactionHash; + return receipt; + } + + function rawToConvertedReceiptLogs(RawReceiptLog[] memory rawLogs) + internal + pure + virtual + returns (ReceiptLog[] memory) + { + ReceiptLog[] memory logs = new ReceiptLog[](rawLogs.length); + for (uint256 i; i < rawLogs.length; i++) { + logs[i].logAddress = rawLogs[i].logAddress; + logs[i].blockHash = rawLogs[i].blockHash; + logs[i].blockNumber = _bytesToUint(rawLogs[i].blockNumber); + logs[i].data = rawLogs[i].data; + logs[i].logIndex = _bytesToUint(rawLogs[i].logIndex); + logs[i].topics = rawLogs[i].topics; + logs[i].transactionIndex = _bytesToUint(rawLogs[i].transactionIndex); + logs[i].transactionLogIndex = _bytesToUint(rawLogs[i].transactionLogIndex); + logs[i].removed = rawLogs[i].removed; + } + return logs; + } + + // Deploy a contract by fetching the contract bytecode from + // the artifacts directory + // e.g. `deployCode(code, abi.encode(arg1,arg2,arg3))` + function deployCode(string memory what, bytes memory args) internal virtual returns (address addr) { + bytes memory bytecode = abi.encodePacked(vm.getCode(what), args); + /// @solidity memory-safe-assembly + assembly { + addr := create(0, add(bytecode, 0x20), mload(bytecode)) + } + + require(addr != address(0), "StdCheats deployCode(string,bytes): Deployment failed."); + } + + function deployCode(string memory what) internal virtual returns (address addr) { + bytes memory bytecode = vm.getCode(what); + /// @solidity memory-safe-assembly + assembly { + addr := create(0, add(bytecode, 0x20), mload(bytecode)) + } + + require(addr != address(0), "StdCheats deployCode(string): Deployment failed."); + } + + /// @dev deploy contract with value on construction + function deployCode(string memory what, bytes memory args, uint256 val) internal virtual returns (address addr) { + bytes memory bytecode = abi.encodePacked(vm.getCode(what), args); + /// @solidity memory-safe-assembly + assembly { + addr := create(val, add(bytecode, 0x20), mload(bytecode)) + } + + require(addr != address(0), "StdCheats deployCode(string,bytes,uint256): Deployment failed."); + } + + function deployCode(string memory what, uint256 val) internal virtual returns (address addr) { + bytes memory bytecode = vm.getCode(what); + /// @solidity memory-safe-assembly + assembly { + addr := create(val, add(bytecode, 0x20), mload(bytecode)) + } + + require(addr != address(0), "StdCheats deployCode(string,uint256): Deployment failed."); + } + + // creates a labeled address and the corresponding private key + function makeAddrAndKey(string memory name) internal virtual returns (address addr, uint256 privateKey) { + privateKey = uint256(keccak256(abi.encodePacked(name))); + addr = vm.addr(privateKey); + vm.label(addr, name); + } + + // creates a labeled address + function makeAddr(string memory name) internal virtual returns (address addr) { + (addr,) = makeAddrAndKey(name); + } + + // creates a struct containing both a labeled address and the corresponding private key + function makeAccount(string memory name) internal virtual returns (Account memory account) { + (account.addr, account.key) = makeAddrAndKey(name); + } + + function deriveRememberKey(string memory mnemonic, uint32 index) + internal + virtual + returns (address who, uint256 privateKey) + { + privateKey = vm.deriveKey(mnemonic, index); + who = vm.rememberKey(privateKey); + } + + function _bytesToUint(bytes memory b) private pure returns (uint256) { + require(b.length <= 32, "StdCheats _bytesToUint(bytes): Bytes length exceeds 32."); + return abi.decode(abi.encodePacked(new bytes(32 - b.length), b), (uint256)); + } + + function isFork() internal view virtual returns (bool status) { + try vm.activeFork() { + status = true; + } catch (bytes memory) {} + } + + modifier skipWhenForking() { + if (!isFork()) { + _; + } + } + + modifier skipWhenNotForking() { + if (isFork()) { + _; + } + } + + modifier noGasMetering() { + vm.pauseGasMetering(); + // To prevent turning gas monitoring back on with nested functions that use this modifier, + // we check if gasMetering started in the off position. If it did, we don't want to turn + // it back on until we exit the top level function that used the modifier + // + // i.e. funcA() noGasMetering { funcB() }, where funcB has noGasMetering as well. + // funcA will have `gasStartedOff` as false, funcB will have it as true, + // so we only turn metering back on at the end of the funcA + bool gasStartedOff = gasMeteringOff; + gasMeteringOff = true; + + _; + + // if gas metering was on when this modifier was called, turn it back on at the end + if (!gasStartedOff) { + gasMeteringOff = false; + vm.resumeGasMetering(); + } + } + + // a cheat for fuzzing addresses that are payable only + // see https://github.com/foundry-rs/foundry/issues/3631 + function assumePayable(address addr) internal virtual { + (bool success,) = payable(addr).call{value: 0}(""); + vm.assume(success); + } +} + +// Wrappers around cheatcodes to avoid footguns +abstract contract StdCheats is StdCheatsSafe { + using stdStorage for StdStorage; + + StdStorage private stdstore; + Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + + // Skip forward or rewind time by the specified number of seconds + function skip(uint256 time) internal virtual { + vm.warp(block.timestamp + time); + } + + function rewind(uint256 time) internal virtual { + vm.warp(block.timestamp - time); + } + + // Setup a prank from an address that has some ether + function hoax(address msgSender) internal virtual { + vm.deal(msgSender, 1 << 128); + vm.prank(msgSender); + } + + function hoax(address msgSender, uint256 give) internal virtual { + vm.deal(msgSender, give); + vm.prank(msgSender); + } + + function hoax(address msgSender, address origin) internal virtual { + vm.deal(msgSender, 1 << 128); + vm.prank(msgSender, origin); + } + + function hoax(address msgSender, address origin, uint256 give) internal virtual { + vm.deal(msgSender, give); + vm.prank(msgSender, origin); + } + + // Start perpetual prank from an address that has some ether + function startHoax(address msgSender) internal virtual { + vm.deal(msgSender, 1 << 128); + vm.startPrank(msgSender); + } + + function startHoax(address msgSender, uint256 give) internal virtual { + vm.deal(msgSender, give); + vm.startPrank(msgSender); + } + + // Start perpetual prank from an address that has some ether + // tx.origin is set to the origin parameter + function startHoax(address msgSender, address origin) internal virtual { + vm.deal(msgSender, 1 << 128); + vm.startPrank(msgSender, origin); + } + + function startHoax(address msgSender, address origin, uint256 give) internal virtual { + vm.deal(msgSender, give); + vm.startPrank(msgSender, origin); + } + + function changePrank(address msgSender) internal virtual { + vm.stopPrank(); + vm.startPrank(msgSender); + } + + function changePrank(address msgSender, address txOrigin) internal virtual { + vm.stopPrank(); + vm.startPrank(msgSender, txOrigin); + } + + // The same as Vm's `deal` + // Use the alternative signature for ERC20 tokens + function deal(address to, uint256 give) internal virtual { + vm.deal(to, give); + } + + // Set the balance of an account for any ERC20 token + // Use the alternative signature to update `totalSupply` + function deal(address token, address to, uint256 give) internal virtual { + deal(token, to, give, false); + } + + // Set the balance of an account for any ERC1155 token + // Use the alternative signature to update `totalSupply` + function dealERC1155(address token, address to, uint256 id, uint256 give) internal virtual { + dealERC1155(token, to, id, give, false); + } + + function deal(address token, address to, uint256 give, bool adjust) internal virtual { + // get current balance + (, bytes memory balData) = token.call(abi.encodeWithSelector(0x70a08231, to)); + uint256 prevBal = abi.decode(balData, (uint256)); + + // update balance + stdstore.target(token).sig(0x70a08231).with_key(to).checked_write(give); + + // update total supply + if (adjust) { + (, bytes memory totSupData) = token.call(abi.encodeWithSelector(0x18160ddd)); + uint256 totSup = abi.decode(totSupData, (uint256)); + if (give < prevBal) { + totSup -= (prevBal - give); + } else { + totSup += (give - prevBal); + } + stdstore.target(token).sig(0x18160ddd).checked_write(totSup); + } + } + + function dealERC1155(address token, address to, uint256 id, uint256 give, bool adjust) internal virtual { + // get current balance + (, bytes memory balData) = token.call(abi.encodeWithSelector(0x00fdd58e, to, id)); + uint256 prevBal = abi.decode(balData, (uint256)); + + // update balance + stdstore.target(token).sig(0x00fdd58e).with_key(to).with_key(id).checked_write(give); + + // update total supply + if (adjust) { + (, bytes memory totSupData) = token.call(abi.encodeWithSelector(0xbd85b039, id)); + require( + totSupData.length != 0, + "StdCheats deal(address,address,uint,uint,bool): target contract is not ERC1155Supply." + ); + uint256 totSup = abi.decode(totSupData, (uint256)); + if (give < prevBal) { + totSup -= (prevBal - give); + } else { + totSup += (give - prevBal); + } + stdstore.target(token).sig(0xbd85b039).with_key(id).checked_write(totSup); + } + } + + function dealERC721(address token, address to, uint256 id) internal virtual { + // check if token id is already minted and the actual owner. + (bool successMinted, bytes memory ownerData) = token.staticcall(abi.encodeWithSelector(0x6352211e, id)); + require(successMinted, "StdCheats deal(address,address,uint,bool): id not minted."); + + // get owner current balance + (, bytes memory fromBalData) = token.call(abi.encodeWithSelector(0x70a08231, abi.decode(ownerData, (address)))); + uint256 fromPrevBal = abi.decode(fromBalData, (uint256)); + + // get new user current balance + (, bytes memory toBalData) = token.call(abi.encodeWithSelector(0x70a08231, to)); + uint256 toPrevBal = abi.decode(toBalData, (uint256)); + + // update balances + stdstore.target(token).sig(0x70a08231).with_key(abi.decode(ownerData, (address))).checked_write(--fromPrevBal); + stdstore.target(token).sig(0x70a08231).with_key(to).checked_write(++toPrevBal); + + // update owner + stdstore.target(token).sig(0x6352211e).with_key(id).checked_write(to); + } +} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/src/StdError.sol b/packages/wallet/wallet-contracts/lib/forge-std/src/StdError.sol new file mode 100644 index 0000000000..a302191faa --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/src/StdError.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: MIT +// Panics work for versions >=0.8.0, but we lowered the pragma to make this compatible with Test +pragma solidity >=0.6.2 <0.9.0; + +library stdError { + bytes public constant assertionError = abi.encodeWithSignature("Panic(uint256)", 0x01); + bytes public constant arithmeticError = abi.encodeWithSignature("Panic(uint256)", 0x11); + bytes public constant divisionError = abi.encodeWithSignature("Panic(uint256)", 0x12); + bytes public constant enumConversionError = abi.encodeWithSignature("Panic(uint256)", 0x21); + bytes public constant encodeStorageError = abi.encodeWithSignature("Panic(uint256)", 0x22); + bytes public constant popError = abi.encodeWithSignature("Panic(uint256)", 0x31); + bytes public constant indexOOBError = abi.encodeWithSignature("Panic(uint256)", 0x32); + bytes public constant memOverflowError = abi.encodeWithSignature("Panic(uint256)", 0x41); + bytes public constant zeroVarError = abi.encodeWithSignature("Panic(uint256)", 0x51); +} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/src/StdInvariant.sol b/packages/wallet/wallet-contracts/lib/forge-std/src/StdInvariant.sol new file mode 100644 index 0000000000..efa1129ef6 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/src/StdInvariant.sol @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +contract StdInvariant { + struct FuzzSelector { + address addr; + bytes4[] selectors; + } + + address[] private _excludedContracts; + address[] private _excludedSenders; + address[] private _targetedContracts; + address[] private _targetedSenders; + + string[] private _excludedArtifacts; + string[] private _targetedArtifacts; + + FuzzSelector[] private _targetedArtifactSelectors; + FuzzSelector[] private _targetedSelectors; + + // Functions for users: + // These are intended to be called in tests. + + function excludeContract(address newExcludedContract_) internal { + _excludedContracts.push(newExcludedContract_); + } + + function excludeSender(address newExcludedSender_) internal { + _excludedSenders.push(newExcludedSender_); + } + + function excludeArtifact(string memory newExcludedArtifact_) internal { + _excludedArtifacts.push(newExcludedArtifact_); + } + + function targetArtifact(string memory newTargetedArtifact_) internal { + _targetedArtifacts.push(newTargetedArtifact_); + } + + function targetArtifactSelector(FuzzSelector memory newTargetedArtifactSelector_) internal { + _targetedArtifactSelectors.push(newTargetedArtifactSelector_); + } + + function targetContract(address newTargetedContract_) internal { + _targetedContracts.push(newTargetedContract_); + } + + function targetSelector(FuzzSelector memory newTargetedSelector_) internal { + _targetedSelectors.push(newTargetedSelector_); + } + + function targetSender(address newTargetedSender_) internal { + _targetedSenders.push(newTargetedSender_); + } + + // Functions for forge: + // These are called by forge to run invariant tests and don't need to be called in tests. + + function excludeArtifacts() public view returns (string[] memory excludedArtifacts_) { + excludedArtifacts_ = _excludedArtifacts; + } + + function excludeContracts() public view returns (address[] memory excludedContracts_) { + excludedContracts_ = _excludedContracts; + } + + function excludeSenders() public view returns (address[] memory excludedSenders_) { + excludedSenders_ = _excludedSenders; + } + + function targetArtifacts() public view returns (string[] memory targetedArtifacts_) { + targetedArtifacts_ = _targetedArtifacts; + } + + function targetArtifactSelectors() public view returns (FuzzSelector[] memory targetedArtifactSelectors_) { + targetedArtifactSelectors_ = _targetedArtifactSelectors; + } + + function targetContracts() public view returns (address[] memory targetedContracts_) { + targetedContracts_ = _targetedContracts; + } + + function targetSelectors() public view returns (FuzzSelector[] memory targetedSelectors_) { + targetedSelectors_ = _targetedSelectors; + } + + function targetSenders() public view returns (address[] memory targetedSenders_) { + targetedSenders_ = _targetedSenders; + } +} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/src/StdJson.sol b/packages/wallet/wallet-contracts/lib/forge-std/src/StdJson.sol new file mode 100644 index 0000000000..014e6b15e5 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/src/StdJson.sol @@ -0,0 +1,179 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.0 <0.9.0; + +pragma experimental ABIEncoderV2; + +import {VmSafe} from "./Vm.sol"; + +// Helpers for parsing and writing JSON files +// To parse: +// ``` +// using stdJson for string; +// string memory json = vm.readFile("some_peth"); +// json.parseUint(""); +// ``` +// To write: +// ``` +// using stdJson for string; +// string memory json = "deploymentArtifact"; +// Contract contract = new Contract(); +// json.serialize("contractAddress", address(contract)); +// json = json.serialize("deploymentTimes", uint(1)); +// // store the stringified JSON to the 'json' variable we have been using as a key +// // as we won't need it any longer +// string memory json2 = "finalArtifact"; +// string memory final = json2.serialize("depArtifact", json); +// final.write(""); +// ``` + +library stdJson { + VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); + + function parseRaw(string memory json, string memory key) internal pure returns (bytes memory) { + return vm.parseJson(json, key); + } + + function readUint(string memory json, string memory key) internal returns (uint256) { + return vm.parseJsonUint(json, key); + } + + function readUintArray(string memory json, string memory key) internal returns (uint256[] memory) { + return vm.parseJsonUintArray(json, key); + } + + function readInt(string memory json, string memory key) internal returns (int256) { + return vm.parseJsonInt(json, key); + } + + function readIntArray(string memory json, string memory key) internal returns (int256[] memory) { + return vm.parseJsonIntArray(json, key); + } + + function readBytes32(string memory json, string memory key) internal returns (bytes32) { + return vm.parseJsonBytes32(json, key); + } + + function readBytes32Array(string memory json, string memory key) internal returns (bytes32[] memory) { + return vm.parseJsonBytes32Array(json, key); + } + + function readString(string memory json, string memory key) internal returns (string memory) { + return vm.parseJsonString(json, key); + } + + function readStringArray(string memory json, string memory key) internal returns (string[] memory) { + return vm.parseJsonStringArray(json, key); + } + + function readAddress(string memory json, string memory key) internal returns (address) { + return vm.parseJsonAddress(json, key); + } + + function readAddressArray(string memory json, string memory key) internal returns (address[] memory) { + return vm.parseJsonAddressArray(json, key); + } + + function readBool(string memory json, string memory key) internal returns (bool) { + return vm.parseJsonBool(json, key); + } + + function readBoolArray(string memory json, string memory key) internal returns (bool[] memory) { + return vm.parseJsonBoolArray(json, key); + } + + function readBytes(string memory json, string memory key) internal returns (bytes memory) { + return vm.parseJsonBytes(json, key); + } + + function readBytesArray(string memory json, string memory key) internal returns (bytes[] memory) { + return vm.parseJsonBytesArray(json, key); + } + + function serialize(string memory jsonKey, string memory key, bool value) internal returns (string memory) { + return vm.serializeBool(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, bool[] memory value) + internal + returns (string memory) + { + return vm.serializeBool(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, uint256 value) internal returns (string memory) { + return vm.serializeUint(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, uint256[] memory value) + internal + returns (string memory) + { + return vm.serializeUint(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, int256 value) internal returns (string memory) { + return vm.serializeInt(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, int256[] memory value) + internal + returns (string memory) + { + return vm.serializeInt(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, address value) internal returns (string memory) { + return vm.serializeAddress(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, address[] memory value) + internal + returns (string memory) + { + return vm.serializeAddress(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, bytes32 value) internal returns (string memory) { + return vm.serializeBytes32(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, bytes32[] memory value) + internal + returns (string memory) + { + return vm.serializeBytes32(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, bytes memory value) internal returns (string memory) { + return vm.serializeBytes(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, bytes[] memory value) + internal + returns (string memory) + { + return vm.serializeBytes(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, string memory value) + internal + returns (string memory) + { + return vm.serializeString(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, string[] memory value) + internal + returns (string memory) + { + return vm.serializeString(jsonKey, key, value); + } + + function write(string memory jsonKey, string memory path) internal { + vm.writeJson(jsonKey, path); + } + + function write(string memory jsonKey, string memory path, string memory valueKey) internal { + vm.writeJson(jsonKey, path, valueKey); + } +} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/src/StdMath.sol b/packages/wallet/wallet-contracts/lib/forge-std/src/StdMath.sol new file mode 100644 index 0000000000..459523bdac --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/src/StdMath.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +library stdMath { + int256 private constant INT256_MIN = -57896044618658097711785492504343953926634992332820282019728792003956564819968; + + function abs(int256 a) internal pure returns (uint256) { + // Required or it will fail when `a = type(int256).min` + if (a == INT256_MIN) { + return 57896044618658097711785492504343953926634992332820282019728792003956564819968; + } + + return uint256(a > 0 ? a : -a); + } + + function delta(uint256 a, uint256 b) internal pure returns (uint256) { + return a > b ? a - b : b - a; + } + + function delta(int256 a, int256 b) internal pure returns (uint256) { + // a and b are of the same sign + // this works thanks to two's complement, the left-most bit is the sign bit + if ((a ^ b) > -1) { + return delta(abs(a), abs(b)); + } + + // a and b are of opposite signs + return abs(a) + abs(b); + } + + function percentDelta(uint256 a, uint256 b) internal pure returns (uint256) { + uint256 absDelta = delta(a, b); + + return absDelta * 1e18 / b; + } + + function percentDelta(int256 a, int256 b) internal pure returns (uint256) { + uint256 absDelta = delta(a, b); + uint256 absB = abs(b); + + return absDelta * 1e18 / absB; + } +} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/src/StdStorage.sol b/packages/wallet/wallet-contracts/lib/forge-std/src/StdStorage.sol new file mode 100644 index 0000000000..73a5ceb969 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/src/StdStorage.sol @@ -0,0 +1,327 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +import {Vm} from "./Vm.sol"; + +struct StdStorage { + mapping(address => mapping(bytes4 => mapping(bytes32 => uint256))) slots; + mapping(address => mapping(bytes4 => mapping(bytes32 => bool))) finds; + bytes32[] _keys; + bytes4 _sig; + uint256 _depth; + address _target; + bytes32 _set; +} + +library stdStorageSafe { + event SlotFound(address who, bytes4 fsig, bytes32 keysHash, uint256 slot); + event WARNING_UninitedSlot(address who, uint256 slot); + + Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + + function sigs(string memory sigStr) internal pure returns (bytes4) { + return bytes4(keccak256(bytes(sigStr))); + } + + /// @notice find an arbitrary storage slot given a function sig, input data, address of the contract and a value to check against + // slot complexity: + // if flat, will be bytes32(uint256(uint)); + // if map, will be keccak256(abi.encode(key, uint(slot))); + // if deep map, will be keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot))))); + // if map struct, will be bytes32(uint256(keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot)))))) + structFieldDepth); + function find(StdStorage storage self) internal returns (uint256) { + address who = self._target; + bytes4 fsig = self._sig; + uint256 field_depth = self._depth; + bytes32[] memory ins = self._keys; + + // calldata to test against + if (self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]) { + return self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]; + } + bytes memory cald = abi.encodePacked(fsig, flatten(ins)); + vm.record(); + bytes32 fdat; + { + (, bytes memory rdat) = who.staticcall(cald); + fdat = bytesToBytes32(rdat, 32 * field_depth); + } + + (bytes32[] memory reads,) = vm.accesses(address(who)); + if (reads.length == 1) { + bytes32 curr = vm.load(who, reads[0]); + if (curr == bytes32(0)) { + emit WARNING_UninitedSlot(who, uint256(reads[0])); + } + if (fdat != curr) { + require( + false, + "stdStorage find(StdStorage): Packed slot. This would cause dangerous overwriting and currently isn't supported." + ); + } + emit SlotFound(who, fsig, keccak256(abi.encodePacked(ins, field_depth)), uint256(reads[0])); + self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = uint256(reads[0]); + self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = true; + } else if (reads.length > 1) { + for (uint256 i = 0; i < reads.length; i++) { + bytes32 prev = vm.load(who, reads[i]); + if (prev == bytes32(0)) { + emit WARNING_UninitedSlot(who, uint256(reads[i])); + } + // store + vm.store(who, reads[i], bytes32(hex"1337")); + bool success; + bytes memory rdat; + { + (success, rdat) = who.staticcall(cald); + fdat = bytesToBytes32(rdat, 32 * field_depth); + } + + if (success && fdat == bytes32(hex"1337")) { + // we found which of the slots is the actual one + emit SlotFound(who, fsig, keccak256(abi.encodePacked(ins, field_depth)), uint256(reads[i])); + self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = uint256(reads[i]); + self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = true; + vm.store(who, reads[i], prev); + break; + } + vm.store(who, reads[i], prev); + } + } else { + revert("stdStorage find(StdStorage): No storage use detected for target."); + } + + require( + self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))], + "stdStorage find(StdStorage): Slot(s) not found." + ); + + delete self._target; + delete self._sig; + delete self._keys; + delete self._depth; + + return self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]; + } + + function target(StdStorage storage self, address _target) internal returns (StdStorage storage) { + self._target = _target; + return self; + } + + function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) { + self._sig = _sig; + return self; + } + + function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) { + self._sig = sigs(_sig); + return self; + } + + function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) { + self._keys.push(bytes32(uint256(uint160(who)))); + return self; + } + + function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) { + self._keys.push(bytes32(amt)); + return self; + } + + function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) { + self._keys.push(key); + return self; + } + + function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) { + self._depth = _depth; + return self; + } + + function read(StdStorage storage self) private returns (bytes memory) { + address t = self._target; + uint256 s = find(self); + return abi.encode(vm.load(t, bytes32(s))); + } + + function read_bytes32(StdStorage storage self) internal returns (bytes32) { + return abi.decode(read(self), (bytes32)); + } + + function read_bool(StdStorage storage self) internal returns (bool) { + int256 v = read_int(self); + if (v == 0) return false; + if (v == 1) return true; + revert("stdStorage read_bool(StdStorage): Cannot decode. Make sure you are reading a bool."); + } + + function read_address(StdStorage storage self) internal returns (address) { + return abi.decode(read(self), (address)); + } + + function read_uint(StdStorage storage self) internal returns (uint256) { + return abi.decode(read(self), (uint256)); + } + + function read_int(StdStorage storage self) internal returns (int256) { + return abi.decode(read(self), (int256)); + } + + function bytesToBytes32(bytes memory b, uint256 offset) private pure returns (bytes32) { + bytes32 out; + + uint256 max = b.length > 32 ? 32 : b.length; + for (uint256 i = 0; i < max; i++) { + out |= bytes32(b[offset + i] & 0xFF) >> (i * 8); + } + return out; + } + + function flatten(bytes32[] memory b) private pure returns (bytes memory) { + bytes memory result = new bytes(b.length * 32); + for (uint256 i = 0; i < b.length; i++) { + bytes32 k = b[i]; + /// @solidity memory-safe-assembly + assembly { + mstore(add(result, add(32, mul(32, i))), k) + } + } + + return result; + } +} + +library stdStorage { + Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + + function sigs(string memory sigStr) internal pure returns (bytes4) { + return stdStorageSafe.sigs(sigStr); + } + + function find(StdStorage storage self) internal returns (uint256) { + return stdStorageSafe.find(self); + } + + function target(StdStorage storage self, address _target) internal returns (StdStorage storage) { + return stdStorageSafe.target(self, _target); + } + + function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) { + return stdStorageSafe.sig(self, _sig); + } + + function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) { + return stdStorageSafe.sig(self, _sig); + } + + function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) { + return stdStorageSafe.with_key(self, who); + } + + function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) { + return stdStorageSafe.with_key(self, amt); + } + + function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) { + return stdStorageSafe.with_key(self, key); + } + + function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) { + return stdStorageSafe.depth(self, _depth); + } + + function checked_write(StdStorage storage self, address who) internal { + checked_write(self, bytes32(uint256(uint160(who)))); + } + + function checked_write(StdStorage storage self, uint256 amt) internal { + checked_write(self, bytes32(amt)); + } + + function checked_write(StdStorage storage self, bool write) internal { + bytes32 t; + /// @solidity memory-safe-assembly + assembly { + t := write + } + checked_write(self, t); + } + + function checked_write(StdStorage storage self, bytes32 set) internal { + address who = self._target; + bytes4 fsig = self._sig; + uint256 field_depth = self._depth; + bytes32[] memory ins = self._keys; + + bytes memory cald = abi.encodePacked(fsig, flatten(ins)); + if (!self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]) { + find(self); + } + bytes32 slot = bytes32(self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]); + + bytes32 fdat; + { + (, bytes memory rdat) = who.staticcall(cald); + fdat = bytesToBytes32(rdat, 32 * field_depth); + } + bytes32 curr = vm.load(who, slot); + + if (fdat != curr) { + require( + false, + "stdStorage find(StdStorage): Packed slot. This would cause dangerous overwriting and currently isn't supported." + ); + } + vm.store(who, slot, set); + delete self._target; + delete self._sig; + delete self._keys; + delete self._depth; + } + + function read_bytes32(StdStorage storage self) internal returns (bytes32) { + return stdStorageSafe.read_bytes32(self); + } + + function read_bool(StdStorage storage self) internal returns (bool) { + return stdStorageSafe.read_bool(self); + } + + function read_address(StdStorage storage self) internal returns (address) { + return stdStorageSafe.read_address(self); + } + + function read_uint(StdStorage storage self) internal returns (uint256) { + return stdStorageSafe.read_uint(self); + } + + function read_int(StdStorage storage self) internal returns (int256) { + return stdStorageSafe.read_int(self); + } + + // Private function so needs to be copied over + function bytesToBytes32(bytes memory b, uint256 offset) private pure returns (bytes32) { + bytes32 out; + + uint256 max = b.length > 32 ? 32 : b.length; + for (uint256 i = 0; i < max; i++) { + out |= bytes32(b[offset + i] & 0xFF) >> (i * 8); + } + return out; + } + + // Private function so needs to be copied over + function flatten(bytes32[] memory b) private pure returns (bytes memory) { + bytes memory result = new bytes(b.length * 32); + for (uint256 i = 0; i < b.length; i++) { + bytes32 k = b[i]; + /// @solidity memory-safe-assembly + assembly { + mstore(add(result, add(32, mul(32, i))), k) + } + } + + return result; + } +} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/src/StdStyle.sol b/packages/wallet/wallet-contracts/lib/forge-std/src/StdStyle.sol new file mode 100644 index 0000000000..46f4e81cb4 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/src/StdStyle.sol @@ -0,0 +1,333 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.4.22 <0.9.0; + +import {Vm} from "./Vm.sol"; + +library StdStyle { + Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + + string constant RED = "\u001b[91m"; + string constant GREEN = "\u001b[92m"; + string constant YELLOW = "\u001b[93m"; + string constant BLUE = "\u001b[94m"; + string constant MAGENTA = "\u001b[95m"; + string constant CYAN = "\u001b[96m"; + string constant BOLD = "\u001b[1m"; + string constant DIM = "\u001b[2m"; + string constant ITALIC = "\u001b[3m"; + string constant UNDERLINE = "\u001b[4m"; + string constant INVERSE = "\u001b[7m"; + string constant RESET = "\u001b[0m"; + + function styleConcat(string memory style, string memory self) private pure returns (string memory) { + return string(abi.encodePacked(style, self, RESET)); + } + + function red(string memory self) internal pure returns (string memory) { + return styleConcat(RED, self); + } + + function red(uint256 self) internal pure returns (string memory) { + return red(vm.toString(self)); + } + + function red(int256 self) internal pure returns (string memory) { + return red(vm.toString(self)); + } + + function red(address self) internal pure returns (string memory) { + return red(vm.toString(self)); + } + + function red(bool self) internal pure returns (string memory) { + return red(vm.toString(self)); + } + + function redBytes(bytes memory self) internal pure returns (string memory) { + return red(vm.toString(self)); + } + + function redBytes32(bytes32 self) internal pure returns (string memory) { + return red(vm.toString(self)); + } + + function green(string memory self) internal pure returns (string memory) { + return styleConcat(GREEN, self); + } + + function green(uint256 self) internal pure returns (string memory) { + return green(vm.toString(self)); + } + + function green(int256 self) internal pure returns (string memory) { + return green(vm.toString(self)); + } + + function green(address self) internal pure returns (string memory) { + return green(vm.toString(self)); + } + + function green(bool self) internal pure returns (string memory) { + return green(vm.toString(self)); + } + + function greenBytes(bytes memory self) internal pure returns (string memory) { + return green(vm.toString(self)); + } + + function greenBytes32(bytes32 self) internal pure returns (string memory) { + return green(vm.toString(self)); + } + + function yellow(string memory self) internal pure returns (string memory) { + return styleConcat(YELLOW, self); + } + + function yellow(uint256 self) internal pure returns (string memory) { + return yellow(vm.toString(self)); + } + + function yellow(int256 self) internal pure returns (string memory) { + return yellow(vm.toString(self)); + } + + function yellow(address self) internal pure returns (string memory) { + return yellow(vm.toString(self)); + } + + function yellow(bool self) internal pure returns (string memory) { + return yellow(vm.toString(self)); + } + + function yellowBytes(bytes memory self) internal pure returns (string memory) { + return yellow(vm.toString(self)); + } + + function yellowBytes32(bytes32 self) internal pure returns (string memory) { + return yellow(vm.toString(self)); + } + + function blue(string memory self) internal pure returns (string memory) { + return styleConcat(BLUE, self); + } + + function blue(uint256 self) internal pure returns (string memory) { + return blue(vm.toString(self)); + } + + function blue(int256 self) internal pure returns (string memory) { + return blue(vm.toString(self)); + } + + function blue(address self) internal pure returns (string memory) { + return blue(vm.toString(self)); + } + + function blue(bool self) internal pure returns (string memory) { + return blue(vm.toString(self)); + } + + function blueBytes(bytes memory self) internal pure returns (string memory) { + return blue(vm.toString(self)); + } + + function blueBytes32(bytes32 self) internal pure returns (string memory) { + return blue(vm.toString(self)); + } + + function magenta(string memory self) internal pure returns (string memory) { + return styleConcat(MAGENTA, self); + } + + function magenta(uint256 self) internal pure returns (string memory) { + return magenta(vm.toString(self)); + } + + function magenta(int256 self) internal pure returns (string memory) { + return magenta(vm.toString(self)); + } + + function magenta(address self) internal pure returns (string memory) { + return magenta(vm.toString(self)); + } + + function magenta(bool self) internal pure returns (string memory) { + return magenta(vm.toString(self)); + } + + function magentaBytes(bytes memory self) internal pure returns (string memory) { + return magenta(vm.toString(self)); + } + + function magentaBytes32(bytes32 self) internal pure returns (string memory) { + return magenta(vm.toString(self)); + } + + function cyan(string memory self) internal pure returns (string memory) { + return styleConcat(CYAN, self); + } + + function cyan(uint256 self) internal pure returns (string memory) { + return cyan(vm.toString(self)); + } + + function cyan(int256 self) internal pure returns (string memory) { + return cyan(vm.toString(self)); + } + + function cyan(address self) internal pure returns (string memory) { + return cyan(vm.toString(self)); + } + + function cyan(bool self) internal pure returns (string memory) { + return cyan(vm.toString(self)); + } + + function cyanBytes(bytes memory self) internal pure returns (string memory) { + return cyan(vm.toString(self)); + } + + function cyanBytes32(bytes32 self) internal pure returns (string memory) { + return cyan(vm.toString(self)); + } + + function bold(string memory self) internal pure returns (string memory) { + return styleConcat(BOLD, self); + } + + function bold(uint256 self) internal pure returns (string memory) { + return bold(vm.toString(self)); + } + + function bold(int256 self) internal pure returns (string memory) { + return bold(vm.toString(self)); + } + + function bold(address self) internal pure returns (string memory) { + return bold(vm.toString(self)); + } + + function bold(bool self) internal pure returns (string memory) { + return bold(vm.toString(self)); + } + + function boldBytes(bytes memory self) internal pure returns (string memory) { + return bold(vm.toString(self)); + } + + function boldBytes32(bytes32 self) internal pure returns (string memory) { + return bold(vm.toString(self)); + } + + function dim(string memory self) internal pure returns (string memory) { + return styleConcat(DIM, self); + } + + function dim(uint256 self) internal pure returns (string memory) { + return dim(vm.toString(self)); + } + + function dim(int256 self) internal pure returns (string memory) { + return dim(vm.toString(self)); + } + + function dim(address self) internal pure returns (string memory) { + return dim(vm.toString(self)); + } + + function dim(bool self) internal pure returns (string memory) { + return dim(vm.toString(self)); + } + + function dimBytes(bytes memory self) internal pure returns (string memory) { + return dim(vm.toString(self)); + } + + function dimBytes32(bytes32 self) internal pure returns (string memory) { + return dim(vm.toString(self)); + } + + function italic(string memory self) internal pure returns (string memory) { + return styleConcat(ITALIC, self); + } + + function italic(uint256 self) internal pure returns (string memory) { + return italic(vm.toString(self)); + } + + function italic(int256 self) internal pure returns (string memory) { + return italic(vm.toString(self)); + } + + function italic(address self) internal pure returns (string memory) { + return italic(vm.toString(self)); + } + + function italic(bool self) internal pure returns (string memory) { + return italic(vm.toString(self)); + } + + function italicBytes(bytes memory self) internal pure returns (string memory) { + return italic(vm.toString(self)); + } + + function italicBytes32(bytes32 self) internal pure returns (string memory) { + return italic(vm.toString(self)); + } + + function underline(string memory self) internal pure returns (string memory) { + return styleConcat(UNDERLINE, self); + } + + function underline(uint256 self) internal pure returns (string memory) { + return underline(vm.toString(self)); + } + + function underline(int256 self) internal pure returns (string memory) { + return underline(vm.toString(self)); + } + + function underline(address self) internal pure returns (string memory) { + return underline(vm.toString(self)); + } + + function underline(bool self) internal pure returns (string memory) { + return underline(vm.toString(self)); + } + + function underlineBytes(bytes memory self) internal pure returns (string memory) { + return underline(vm.toString(self)); + } + + function underlineBytes32(bytes32 self) internal pure returns (string memory) { + return underline(vm.toString(self)); + } + + function inverse(string memory self) internal pure returns (string memory) { + return styleConcat(INVERSE, self); + } + + function inverse(uint256 self) internal pure returns (string memory) { + return inverse(vm.toString(self)); + } + + function inverse(int256 self) internal pure returns (string memory) { + return inverse(vm.toString(self)); + } + + function inverse(address self) internal pure returns (string memory) { + return inverse(vm.toString(self)); + } + + function inverse(bool self) internal pure returns (string memory) { + return inverse(vm.toString(self)); + } + + function inverseBytes(bytes memory self) internal pure returns (string memory) { + return inverse(vm.toString(self)); + } + + function inverseBytes32(bytes32 self) internal pure returns (string memory) { + return inverse(vm.toString(self)); + } +} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/src/StdUtils.sol b/packages/wallet/wallet-contracts/lib/forge-std/src/StdUtils.sol new file mode 100644 index 0000000000..e55b4b90c1 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/src/StdUtils.sol @@ -0,0 +1,192 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +import {IMulticall3} from "./interfaces/IMulticall3.sol"; +import {VmSafe} from "./Vm.sol"; + +abstract contract StdUtils { + /*////////////////////////////////////////////////////////////////////////// + CONSTANTS + //////////////////////////////////////////////////////////////////////////*/ + + IMulticall3 private constant multicall = IMulticall3(0xcA11bde05977b3631167028862bE2a173976CA11); + VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); + address private constant CONSOLE2_ADDRESS = 0x000000000000000000636F6e736F6c652e6c6f67; + uint256 private constant INT256_MIN_ABS = + 57896044618658097711785492504343953926634992332820282019728792003956564819968; + uint256 private constant UINT256_MAX = + 115792089237316195423570985008687907853269984665640564039457584007913129639935; + + // Used by default when deploying with create2, https://github.com/Arachnid/deterministic-deployment-proxy. + address private constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C; + + /*////////////////////////////////////////////////////////////////////////// + INTERNAL FUNCTIONS + //////////////////////////////////////////////////////////////////////////*/ + + function _bound(uint256 x, uint256 min, uint256 max) internal pure virtual returns (uint256 result) { + require(min <= max, "StdUtils bound(uint256,uint256,uint256): Max is less than min."); + // If x is between min and max, return x directly. This is to ensure that dictionary values + // do not get shifted if the min is nonzero. More info: https://github.com/foundry-rs/forge-std/issues/188 + if (x >= min && x <= max) return x; + + uint256 size = max - min + 1; + + // If the value is 0, 1, 2, 3, wrap that to min, min+1, min+2, min+3. Similarly for the UINT256_MAX side. + // This helps ensure coverage of the min/max values. + if (x <= 3 && size > x) return min + x; + if (x >= UINT256_MAX - 3 && size > UINT256_MAX - x) return max - (UINT256_MAX - x); + + // Otherwise, wrap x into the range [min, max], i.e. the range is inclusive. + if (x > max) { + uint256 diff = x - max; + uint256 rem = diff % size; + if (rem == 0) return max; + result = min + rem - 1; + } else if (x < min) { + uint256 diff = min - x; + uint256 rem = diff % size; + if (rem == 0) return min; + result = max - rem + 1; + } + } + + function bound(uint256 x, uint256 min, uint256 max) internal view virtual returns (uint256 result) { + result = _bound(x, min, max); + console2_log("Bound Result", result); + } + + function _bound(int256 x, int256 min, int256 max) internal pure virtual returns (int256 result) { + require(min <= max, "StdUtils bound(int256,int256,int256): Max is less than min."); + + // Shifting all int256 values to uint256 to use _bound function. The range of two types are: + // int256 : -(2**255) ~ (2**255 - 1) + // uint256: 0 ~ (2**256 - 1) + // So, add 2**255, INT256_MIN_ABS to the integer values. + // + // If the given integer value is -2**255, we cannot use `-uint256(-x)` because of the overflow. + // So, use `~uint256(x) + 1` instead. + uint256 _x = x < 0 ? (INT256_MIN_ABS - ~uint256(x) - 1) : (uint256(x) + INT256_MIN_ABS); + uint256 _min = min < 0 ? (INT256_MIN_ABS - ~uint256(min) - 1) : (uint256(min) + INT256_MIN_ABS); + uint256 _max = max < 0 ? (INT256_MIN_ABS - ~uint256(max) - 1) : (uint256(max) + INT256_MIN_ABS); + + uint256 y = _bound(_x, _min, _max); + + // To move it back to int256 value, subtract INT256_MIN_ABS at here. + result = y < INT256_MIN_ABS ? int256(~(INT256_MIN_ABS - y) + 1) : int256(y - INT256_MIN_ABS); + } + + function bound(int256 x, int256 min, int256 max) internal view virtual returns (int256 result) { + result = _bound(x, min, max); + console2_log("Bound result", vm.toString(result)); + } + + function bytesToUint(bytes memory b) internal pure virtual returns (uint256) { + require(b.length <= 32, "StdUtils bytesToUint(bytes): Bytes length exceeds 32."); + return abi.decode(abi.encodePacked(new bytes(32 - b.length), b), (uint256)); + } + + /// @dev Compute the address a contract will be deployed at for a given deployer address and nonce + /// @notice adapted from Solmate implementation (https://github.com/Rari-Capital/solmate/blob/main/src/utils/LibRLP.sol) + function computeCreateAddress(address deployer, uint256 nonce) internal pure virtual returns (address) { + // forgefmt: disable-start + // The integer zero is treated as an empty byte string, and as a result it only has a length prefix, 0x80, computed via 0x80 + 0. + // A one byte integer uses its own value as its length prefix, there is no additional "0x80 + length" prefix that comes before it. + if (nonce == 0x00) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, bytes1(0x80)))); + if (nonce <= 0x7f) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, uint8(nonce)))); + + // Nonces greater than 1 byte all follow a consistent encoding scheme, where each value is preceded by a prefix of 0x80 + length. + if (nonce <= 2**8 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd7), bytes1(0x94), deployer, bytes1(0x81), uint8(nonce)))); + if (nonce <= 2**16 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd8), bytes1(0x94), deployer, bytes1(0x82), uint16(nonce)))); + if (nonce <= 2**24 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd9), bytes1(0x94), deployer, bytes1(0x83), uint24(nonce)))); + // forgefmt: disable-end + + // More details about RLP encoding can be found here: https://eth.wiki/fundamentals/rlp + // 0xda = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x84 ++ nonce) + // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex) + // 0x84 = 0x80 + 0x04 (0x04 = the bytes length of the nonce, 4 bytes, in hex) + // We assume nobody can have a nonce large enough to require more than 32 bytes. + return addressFromLast20Bytes( + keccak256(abi.encodePacked(bytes1(0xda), bytes1(0x94), deployer, bytes1(0x84), uint32(nonce))) + ); + } + + function computeCreate2Address(bytes32 salt, bytes32 initcodeHash, address deployer) + internal + pure + virtual + returns (address) + { + return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xff), deployer, salt, initcodeHash))); + } + + /// @dev returns the address of a contract created with CREATE2 using the default CREATE2 deployer + function computeCreate2Address(bytes32 salt, bytes32 initCodeHash) internal pure returns (address) { + return computeCreate2Address(salt, initCodeHash, CREATE2_FACTORY); + } + + /// @dev returns the hash of the init code (creation code + no args) used in CREATE2 with no constructor arguments + /// @param creationCode the creation code of a contract C, as returned by type(C).creationCode + function hashInitCode(bytes memory creationCode) internal pure returns (bytes32) { + return hashInitCode(creationCode, ""); + } + + /// @dev returns the hash of the init code (creation code + ABI-encoded args) used in CREATE2 + /// @param creationCode the creation code of a contract C, as returned by type(C).creationCode + /// @param args the ABI-encoded arguments to the constructor of C + function hashInitCode(bytes memory creationCode, bytes memory args) internal pure returns (bytes32) { + return keccak256(abi.encodePacked(creationCode, args)); + } + + // Performs a single call with Multicall3 to query the ERC-20 token balances of the given addresses. + function getTokenBalances(address token, address[] memory addresses) + internal + virtual + returns (uint256[] memory balances) + { + uint256 tokenCodeSize; + assembly { + tokenCodeSize := extcodesize(token) + } + require(tokenCodeSize > 0, "StdUtils getTokenBalances(address,address[]): Token address is not a contract."); + + // ABI encode the aggregate call to Multicall3. + uint256 length = addresses.length; + IMulticall3.Call[] memory calls = new IMulticall3.Call[](length); + for (uint256 i = 0; i < length; ++i) { + // 0x70a08231 = bytes4("balanceOf(address)")) + calls[i] = IMulticall3.Call({target: token, callData: abi.encodeWithSelector(0x70a08231, (addresses[i]))}); + } + + // Make the aggregate call. + (, bytes[] memory returnData) = multicall.aggregate(calls); + + // ABI decode the return data and return the balances. + balances = new uint256[](length); + for (uint256 i = 0; i < length; ++i) { + balances[i] = abi.decode(returnData[i], (uint256)); + } + } + + /*////////////////////////////////////////////////////////////////////////// + PRIVATE FUNCTIONS + //////////////////////////////////////////////////////////////////////////*/ + + function addressFromLast20Bytes(bytes32 bytesValue) private pure returns (address) { + return address(uint160(uint256(bytesValue))); + } + + // Used to prevent the compilation of console, which shortens the compilation time when console is not used elsewhere. + + function console2_log(string memory p0, uint256 p1) private view { + (bool status,) = address(CONSOLE2_ADDRESS).staticcall(abi.encodeWithSignature("log(string,uint256)", p0, p1)); + status; + } + + function console2_log(string memory p0, string memory p1) private view { + (bool status,) = address(CONSOLE2_ADDRESS).staticcall(abi.encodeWithSignature("log(string,string)", p0, p1)); + status; + } +} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/src/Test.sol b/packages/wallet/wallet-contracts/lib/forge-std/src/Test.sol new file mode 100644 index 0000000000..9ff5cb8db1 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/src/Test.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +// šŸ’¬ ABOUT +// Standard Library's default Test + +// 🧩 MODULES +import {console} from "./console.sol"; +import {console2} from "./console2.sol"; +import {StdAssertions} from "./StdAssertions.sol"; +import {StdChains} from "./StdChains.sol"; +import {StdCheats} from "./StdCheats.sol"; +import {stdError} from "./StdError.sol"; +import {StdInvariant} from "./StdInvariant.sol"; +import {stdJson} from "./StdJson.sol"; +import {stdMath} from "./StdMath.sol"; +import {StdStorage, stdStorage} from "./StdStorage.sol"; +import {StdUtils} from "./StdUtils.sol"; +import {Vm} from "./Vm.sol"; +import {StdStyle} from "./StdStyle.sol"; + +// šŸ“¦ BOILERPLATE +import {TestBase} from "./Base.sol"; +import {DSTest} from "ds-test/test.sol"; + +// ā­ļø TEST +abstract contract Test is DSTest, StdAssertions, StdChains, StdCheats, StdInvariant, StdUtils, TestBase { +// Note: IS_TEST() must return true. +// Note: Must have failure system, https://github.com/dapphub/ds-test/blob/cd98eff28324bfac652e63a239a60632a761790b/src/test.sol#L39-L76. +} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/src/Vm.sol b/packages/wallet/wallet-contracts/lib/forge-std/src/Vm.sol new file mode 100644 index 0000000000..e48ebaa53c --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/src/Vm.sol @@ -0,0 +1,490 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +// Cheatcodes are marked as view/pure/none using the following rules: +// 0. A call's observable behaviour includes its return value, logs, reverts and state writes, +// 1. If you can influence a later call's observable behaviour, you're neither `view` nor `pure (you are modifying some state be it the EVM, interpreter, filesystem, etc), +// 2. Otherwise if you can be influenced by an earlier call, or if reading some state, you're `view`, +// 3. Otherwise you're `pure`. + +interface VmSafe { + struct Log { + bytes32[] topics; + bytes data; + address emitter; + } + + struct Rpc { + string key; + string url; + } + + struct DirEntry { + string errorMessage; + string path; + uint64 depth; + bool isDir; + bool isSymlink; + } + + struct FsMetadata { + bool isDir; + bool isSymlink; + uint256 length; + bool readOnly; + uint256 modified; + uint256 accessed; + uint256 created; + } + + // Loads a storage slot from an address + function load(address target, bytes32 slot) external view returns (bytes32 data); + // Signs data + function sign(uint256 privateKey, bytes32 digest) external pure returns (uint8 v, bytes32 r, bytes32 s); + // Gets the address for a given private key + function addr(uint256 privateKey) external pure returns (address keyAddr); + // Gets the nonce of an account + function getNonce(address account) external view returns (uint64 nonce); + // Performs a foreign function call via the terminal + function ffi(string[] calldata commandInput) external returns (bytes memory result); + // Sets environment variables + function setEnv(string calldata name, string calldata value) external; + // Reads environment variables, (name) => (value) + function envBool(string calldata name) external view returns (bool value); + function envUint(string calldata name) external view returns (uint256 value); + function envInt(string calldata name) external view returns (int256 value); + function envAddress(string calldata name) external view returns (address value); + function envBytes32(string calldata name) external view returns (bytes32 value); + function envString(string calldata name) external view returns (string memory value); + function envBytes(string calldata name) external view returns (bytes memory value); + // Reads environment variables as arrays + function envBool(string calldata name, string calldata delim) external view returns (bool[] memory value); + function envUint(string calldata name, string calldata delim) external view returns (uint256[] memory value); + function envInt(string calldata name, string calldata delim) external view returns (int256[] memory value); + function envAddress(string calldata name, string calldata delim) external view returns (address[] memory value); + function envBytes32(string calldata name, string calldata delim) external view returns (bytes32[] memory value); + function envString(string calldata name, string calldata delim) external view returns (string[] memory value); + function envBytes(string calldata name, string calldata delim) external view returns (bytes[] memory value); + // Read environment variables with default value + function envOr(string calldata name, bool defaultValue) external returns (bool value); + function envOr(string calldata name, uint256 defaultValue) external returns (uint256 value); + function envOr(string calldata name, int256 defaultValue) external returns (int256 value); + function envOr(string calldata name, address defaultValue) external returns (address value); + function envOr(string calldata name, bytes32 defaultValue) external returns (bytes32 value); + function envOr(string calldata name, string calldata defaultValue) external returns (string memory value); + function envOr(string calldata name, bytes calldata defaultValue) external returns (bytes memory value); + // Read environment variables as arrays with default value + function envOr(string calldata name, string calldata delim, bool[] calldata defaultValue) + external + returns (bool[] memory value); + function envOr(string calldata name, string calldata delim, uint256[] calldata defaultValue) + external + returns (uint256[] memory value); + function envOr(string calldata name, string calldata delim, int256[] calldata defaultValue) + external + returns (int256[] memory value); + function envOr(string calldata name, string calldata delim, address[] calldata defaultValue) + external + returns (address[] memory value); + function envOr(string calldata name, string calldata delim, bytes32[] calldata defaultValue) + external + returns (bytes32[] memory value); + function envOr(string calldata name, string calldata delim, string[] calldata defaultValue) + external + returns (string[] memory value); + function envOr(string calldata name, string calldata delim, bytes[] calldata defaultValue) + external + returns (bytes[] memory value); + // Records all storage reads and writes + function record() external; + // Gets all accessed reads and write slot from a recording session, for a given address + function accesses(address target) external returns (bytes32[] memory readSlots, bytes32[] memory writeSlots); + // Gets the _creation_ bytecode from an artifact file. Takes in the relative path to the json file + function getCode(string calldata artifactPath) external view returns (bytes memory creationBytecode); + // Gets the _deployed_ bytecode from an artifact file. Takes in the relative path to the json file + function getDeployedCode(string calldata artifactPath) external view returns (bytes memory runtimeBytecode); + // Labels an address in call traces + function label(address account, string calldata newLabel) external; + // Using the address that calls the test contract, has the next call (at this call depth only) create a transaction that can later be signed and sent onchain + function broadcast() external; + // Has the next call (at this call depth only) create a transaction with the address provided as the sender that can later be signed and sent onchain + function broadcast(address signer) external; + // Has the next call (at this call depth only) create a transaction with the private key provided as the sender that can later be signed and sent onchain + function broadcast(uint256 privateKey) external; + // Using the address that calls the test contract, has all subsequent calls (at this call depth only) create transactions that can later be signed and sent onchain + function startBroadcast() external; + // Has all subsequent calls (at this call depth only) create transactions with the address provided that can later be signed and sent onchain + function startBroadcast(address signer) external; + // Has all subsequent calls (at this call depth only) create transactions with the private key provided that can later be signed and sent onchain + function startBroadcast(uint256 privateKey) external; + // Stops collecting onchain transactions + function stopBroadcast() external; + + // Get the path of the current project root. + function projectRoot() external view returns (string memory path); + // Reads the entire content of file to string. `path` is relative to the project root. + function readFile(string calldata path) external view returns (string memory data); + // Reads the entire content of file as binary. `path` is relative to the project root. + function readFileBinary(string calldata path) external view returns (bytes memory data); + // Reads next line of file to string. + function readLine(string calldata path) external view returns (string memory line); + // Writes data to file, creating a file if it does not exist, and entirely replacing its contents if it does. + // `path` is relative to the project root. + function writeFile(string calldata path, string calldata data) external; + // Writes binary data to a file, creating a file if it does not exist, and entirely replacing its contents if it does. + // `path` is relative to the project root. + function writeFileBinary(string calldata path, bytes calldata data) external; + // Writes line to file, creating a file if it does not exist. + // `path` is relative to the project root. + function writeLine(string calldata path, string calldata data) external; + // Closes file for reading, resetting the offset and allowing to read it from beginning with readLine. + // `path` is relative to the project root. + function closeFile(string calldata path) external; + // Removes a file from the filesystem. + // This cheatcode will revert in the following situations, but is not limited to just these cases: + // - `path` points to a directory. + // - The file doesn't exist. + // - The user lacks permissions to remove the file. + // `path` is relative to the project root. + function removeFile(string calldata path) external; + // Creates a new, empty directory at the provided path. + // This cheatcode will revert in the following situations, but is not limited to just these cases: + // - User lacks permissions to modify `path`. + // - A parent of the given path doesn't exist and `recursive` is false. + // - `path` already exists and `recursive` is false. + // `path` is relative to the project root. + function createDir(string calldata path, bool recursive) external; + // Removes a directory at the provided path. + // This cheatcode will revert in the following situations, but is not limited to just these cases: + // - `path` doesn't exist. + // - `path` isn't a directory. + // - User lacks permissions to modify `path`. + // - The directory is not empty and `recursive` is false. + // `path` is relative to the project root. + function removeDir(string calldata path, bool recursive) external; + // Reads the directory at the given path recursively, up to `max_depth`. + // `max_depth` defaults to 1, meaning only the direct children of the given directory will be returned. + // Follows symbolic links if `follow_links` is true. + function readDir(string calldata path) external view returns (DirEntry[] memory entries); + function readDir(string calldata path, uint64 maxDepth) external view returns (DirEntry[] memory entries); + function readDir(string calldata path, uint64 maxDepth, bool followLinks) + external + view + returns (DirEntry[] memory entries); + // Reads a symbolic link, returning the path that the link points to. + // This cheatcode will revert in the following situations, but is not limited to just these cases: + // - `path` is not a symbolic link. + // - `path` does not exist. + function readLink(string calldata linkPath) external view returns (string memory targetPath); + // Given a path, query the file system to get information about a file, directory, etc. + function fsMetadata(string calldata path) external view returns (FsMetadata memory metadata); + + // Convert values to a string + function toString(address value) external pure returns (string memory stringifiedValue); + function toString(bytes calldata value) external pure returns (string memory stringifiedValue); + function toString(bytes32 value) external pure returns (string memory stringifiedValue); + function toString(bool value) external pure returns (string memory stringifiedValue); + function toString(uint256 value) external pure returns (string memory stringifiedValue); + function toString(int256 value) external pure returns (string memory stringifiedValue); + // Convert values from a string + function parseBytes(string calldata stringifiedValue) external pure returns (bytes memory parsedValue); + function parseAddress(string calldata stringifiedValue) external pure returns (address parsedValue); + function parseUint(string calldata stringifiedValue) external pure returns (uint256 parsedValue); + function parseInt(string calldata stringifiedValue) external pure returns (int256 parsedValue); + function parseBytes32(string calldata stringifiedValue) external pure returns (bytes32 parsedValue); + function parseBool(string calldata stringifiedValue) external pure returns (bool parsedValue); + // Record all the transaction logs + function recordLogs() external; + // Gets all the recorded logs + function getRecordedLogs() external returns (Log[] memory logs); + // Derive a private key from a provided mnenomic string (or mnenomic file path) at the derivation path m/44'/60'/0'/0/{index} + function deriveKey(string calldata mnemonic, uint32 index) external pure returns (uint256 privateKey); + // Derive a private key from a provided mnenomic string (or mnenomic file path) at {derivationPath}{index} + function deriveKey(string calldata mnemonic, string calldata derivationPath, uint32 index) + external + pure + returns (uint256 privateKey); + // Adds a private key to the local forge wallet and returns the address + function rememberKey(uint256 privateKey) external returns (address keyAddr); + // + // parseJson + // + // ---- + // In case the returned value is a JSON object, it's encoded as a ABI-encoded tuple. As JSON objects + // don't have the notion of ordered, but tuples do, they JSON object is encoded with it's fields ordered in + // ALPHABETICAL order. That means that in order to successfully decode the tuple, we need to define a tuple that + // encodes the fields in the same order, which is alphabetical. In the case of Solidity structs, they are encoded + // as tuples, with the attributes in the order in which they are defined. + // For example: json = { 'a': 1, 'b': 0xa4tb......3xs} + // a: uint256 + // b: address + // To decode that json, we need to define a struct or a tuple as follows: + // struct json = { uint256 a; address b; } + // If we defined a json struct with the opposite order, meaning placing the address b first, it would try to + // decode the tuple in that order, and thus fail. + // ---- + // Given a string of JSON, return it as ABI-encoded + function parseJson(string calldata json, string calldata key) external pure returns (bytes memory abiEncodedData); + function parseJson(string calldata json) external pure returns (bytes memory abiEncodedData); + + // The following parseJson cheatcodes will do type coercion, for the type that they indicate. + // For example, parseJsonUint will coerce all values to a uint256. That includes stringified numbers '12' + // and hex numbers '0xEF'. + // Type coercion works ONLY for discrete values or arrays. That means that the key must return a value or array, not + // a JSON object. + function parseJsonUint(string calldata, string calldata) external returns (uint256); + function parseJsonUintArray(string calldata, string calldata) external returns (uint256[] memory); + function parseJsonInt(string calldata, string calldata) external returns (int256); + function parseJsonIntArray(string calldata, string calldata) external returns (int256[] memory); + function parseJsonBool(string calldata, string calldata) external returns (bool); + function parseJsonBoolArray(string calldata, string calldata) external returns (bool[] memory); + function parseJsonAddress(string calldata, string calldata) external returns (address); + function parseJsonAddressArray(string calldata, string calldata) external returns (address[] memory); + function parseJsonString(string calldata, string calldata) external returns (string memory); + function parseJsonStringArray(string calldata, string calldata) external returns (string[] memory); + function parseJsonBytes(string calldata, string calldata) external returns (bytes memory); + function parseJsonBytesArray(string calldata, string calldata) external returns (bytes[] memory); + function parseJsonBytes32(string calldata, string calldata) external returns (bytes32); + function parseJsonBytes32Array(string calldata, string calldata) external returns (bytes32[] memory); + + // Serialize a key and value to a JSON object stored in-memory that can be later written to a file + // It returns the stringified version of the specific JSON file up to that moment. + function serializeBool(string calldata objectKey, string calldata valueKey, bool value) + external + returns (string memory json); + function serializeUint(string calldata objectKey, string calldata valueKey, uint256 value) + external + returns (string memory json); + function serializeInt(string calldata objectKey, string calldata valueKey, int256 value) + external + returns (string memory json); + function serializeAddress(string calldata objectKey, string calldata valueKey, address value) + external + returns (string memory json); + function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32 value) + external + returns (string memory json); + function serializeString(string calldata objectKey, string calldata valueKey, string calldata value) + external + returns (string memory json); + function serializeBytes(string calldata objectKey, string calldata valueKey, bytes calldata value) + external + returns (string memory json); + + function serializeBool(string calldata objectKey, string calldata valueKey, bool[] calldata values) + external + returns (string memory json); + function serializeUint(string calldata objectKey, string calldata valueKey, uint256[] calldata values) + external + returns (string memory json); + function serializeInt(string calldata objectKey, string calldata valueKey, int256[] calldata values) + external + returns (string memory json); + function serializeAddress(string calldata objectKey, string calldata valueKey, address[] calldata values) + external + returns (string memory json); + function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32[] calldata values) + external + returns (string memory json); + function serializeString(string calldata objectKey, string calldata valueKey, string[] calldata values) + external + returns (string memory json); + function serializeBytes(string calldata objectKey, string calldata valueKey, bytes[] calldata values) + external + returns (string memory json); + + // + // writeJson + // + // ---- + // Write a serialized JSON object to a file. If the file exists, it will be overwritten. + // Let's assume we want to write the following JSON to a file: + // + // { "boolean": true, "number": 342, "object": { "title": "finally json serialization" } } + // + // ``` + // string memory json1 = "some key"; + // vm.serializeBool(json1, "boolean", true); + // vm.serializeBool(json1, "number", uint256(342)); + // json2 = "some other key"; + // string memory output = vm.serializeString(json2, "title", "finally json serialization"); + // string memory finalJson = vm.serialize(json1, "object", output); + // vm.writeJson(finalJson, "./output/example.json"); + // ``` + // The critical insight is that every invocation of serialization will return the stringified version of the JSON + // up to that point. That means we can construct arbitrary JSON objects and then use the return stringified version + // to serialize them as values to another JSON object. + // + // json1 and json2 are simply keys used by the backend to keep track of the objects. So vm.serializeJson(json1,..) + // will find the object in-memory that is keyed by "some key". + function writeJson(string calldata json, string calldata path) external; + // Write a serialized JSON object to an **existing** JSON file, replacing a value with key = + // This is useful to replace a specific value of a JSON file, without having to parse the entire thing + function writeJson(string calldata json, string calldata path, string calldata valueKey) external; + // Returns the RPC url for the given alias + function rpcUrl(string calldata rpcAlias) external view returns (string memory json); + // Returns all rpc urls and their aliases `[alias, url][]` + function rpcUrls() external view returns (string[2][] memory urls); + // Returns all rpc urls and their aliases as structs. + function rpcUrlStructs() external view returns (Rpc[] memory urls); + // If the condition is false, discard this run's fuzz inputs and generate new ones. + function assume(bool condition) external pure; + // Pauses gas metering (i.e. gas usage is not counted). Noop if already paused. + function pauseGasMetering() external; + // Resumes gas metering (i.e. gas usage is counted again). Noop if already on. + function resumeGasMetering() external; + // Writes a breakpoint to jump to in the debugger + function breakpoint(string calldata char) external; + // Writes a conditional breakpoint to jump to in the debugger + function breakpoint(string calldata char, bool value) external; +} + +interface Vm is VmSafe { + // Sets block.timestamp + function warp(uint256 newTimestamp) external; + // Sets block.height + function roll(uint256 newHeight) external; + // Sets block.basefee + function fee(uint256 newBasefee) external; + // Sets block.difficulty + function difficulty(uint256 newDifficulty) external; + // Sets block.chainid + function chainId(uint256 newChainId) external; + // Sets tx.gasprice + function txGasPrice(uint256 newGasPrice) external; + // Stores a value to an address' storage slot. + function store(address target, bytes32 slot, bytes32 value) external; + // Sets the nonce of an account; must be higher than the current nonce of the account + function setNonce(address account, uint64 newNonce) external; + // Sets the *next* call's msg.sender to be the input address + function prank(address msgSender) external; + // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called + function startPrank(address msgSender) external; + // Sets the *next* call's msg.sender to be the input address, and the tx.origin to be the second input + function prank(address msgSender, address txOrigin) external; + // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called, and the tx.origin to be the second input + function startPrank(address msgSender, address txOrigin) external; + // Resets subsequent calls' msg.sender to be `address(this)` + function stopPrank() external; + // Sets an address' balance + function deal(address account, uint256 newBalance) external; + // Sets an address' code + function etch(address target, bytes calldata newRuntimeBytecode) external; + // Expects an error on next call + function expectRevert(bytes calldata revertData) external; + function expectRevert(bytes4 revertData) external; + function expectRevert() external; + + // Prepare an expected log with all four checks enabled. + // Call this function, then emit an event, then call a function. Internally after the call, we check if + // logs were emitted in the expected order with the expected topics and data. + // Second form also checks supplied address against emitting contract. + function expectEmit() external; + function expectEmit(address emitter) external; + + // Prepare an expected log with (bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData). + // Call this function, then emit an event, then call a function. Internally after the call, we check if + // logs were emitted in the expected order with the expected topics and data (as specified by the booleans). + // Second form also checks supplied address against emitting contract. + function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData) external; + function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData, address emitter) + external; + + // Mocks a call to an address, returning specified data. + // Calldata can either be strict or a partial match, e.g. if you only + // pass a Solidity selector to the expected calldata, then the entire Solidity + // function will be mocked. + function mockCall(address callee, bytes calldata data, bytes calldata returnData) external; + // Mocks a call to an address with a specific msg.value, returning specified data. + // Calldata match takes precedence over msg.value in case of ambiguity. + function mockCall(address callee, uint256 msgValue, bytes calldata data, bytes calldata returnData) external; + // Reverts a call to an address with specified revert data. + function mockCallRevert(address callee, bytes calldata data, bytes calldata revertData) external; + // Reverts a call to an address with a specific msg.value, with specified revert data. + function mockCallRevert(address callee, uint256 msgValue, bytes calldata data, bytes calldata revertData) + external; + // Clears all mocked calls + function clearMockedCalls() external; + // Expects a call to an address with the specified calldata. + // Calldata can either be a strict or a partial match + function expectCall(address callee, bytes calldata data) external; + // Expects given number of calls to an address with the specified calldata. + function expectCall(address callee, bytes calldata data, uint64 count) external; + // Expects a call to an address with the specified msg.value and calldata + function expectCall(address callee, uint256 msgValue, bytes calldata data) external; + // Expects given number of calls to an address with the specified msg.value and calldata + function expectCall(address callee, uint256 msgValue, bytes calldata data, uint64 count) external; + // Expect a call to an address with the specified msg.value, gas, and calldata. + function expectCall(address callee, uint256 msgValue, uint64 gas, bytes calldata data) external; + // Expects given number of calls to an address with the specified msg.value, gas, and calldata. + function expectCall(address callee, uint256 msgValue, uint64 gas, bytes calldata data, uint64 count) external; + // Expect a call to an address with the specified msg.value and calldata, and a *minimum* amount of gas. + function expectCallMinGas(address callee, uint256 msgValue, uint64 minGas, bytes calldata data) external; + // Expect given number of calls to an address with the specified msg.value and calldata, and a *minimum* amount of gas. + function expectCallMinGas(address callee, uint256 msgValue, uint64 minGas, bytes calldata data, uint64 count) + external; + // Only allows memory writes to offsets [0x00, 0x60) ∪ [min, max) in the current subcontext. If any other + // memory is written to, the test will fail. Can be called multiple times to add more ranges to the set. + function expectSafeMemory(uint64 min, uint64 max) external; + // Only allows memory writes to offsets [0x00, 0x60) ∪ [min, max) in the next created subcontext. + // If any other memory is written to, the test will fail. Can be called multiple times to add more ranges + // to the set. + function expectSafeMemoryCall(uint64 min, uint64 max) external; + // Sets block.coinbase + function coinbase(address newCoinbase) external; + // Snapshot the current state of the evm. + // Returns the id of the snapshot that was created. + // To revert a snapshot use `revertTo` + function snapshot() external returns (uint256 snapshotId); + // Revert the state of the EVM to a previous snapshot + // Takes the snapshot id to revert to. + // This deletes the snapshot and all snapshots taken after the given snapshot id. + function revertTo(uint256 snapshotId) external returns (bool success); + // Creates a new fork with the given endpoint and block and returns the identifier of the fork + function createFork(string calldata urlOrAlias, uint256 blockNumber) external returns (uint256 forkId); + // Creates a new fork with the given endpoint and the _latest_ block and returns the identifier of the fork + function createFork(string calldata urlOrAlias) external returns (uint256 forkId); + // Creates a new fork with the given endpoint and at the block the given transaction was mined in, replays all transaction mined in the block before the transaction, + // and returns the identifier of the fork + function createFork(string calldata urlOrAlias, bytes32 txHash) external returns (uint256 forkId); + // Creates _and_ also selects a new fork with the given endpoint and block and returns the identifier of the fork + function createSelectFork(string calldata urlOrAlias, uint256 blockNumber) external returns (uint256 forkId); + // Creates _and_ also selects new fork with the given endpoint and at the block the given transaction was mined in, replays all transaction mined in the block before + // the transaction, returns the identifier of the fork + function createSelectFork(string calldata urlOrAlias, bytes32 txHash) external returns (uint256 forkId); + // Creates _and_ also selects a new fork with the given endpoint and the latest block and returns the identifier of the fork + function createSelectFork(string calldata urlOrAlias) external returns (uint256 forkId); + // Takes a fork identifier created by `createFork` and sets the corresponding forked state as active. + function selectFork(uint256 forkId) external; + /// Returns the identifier of the currently active fork. Reverts if no fork is currently active. + function activeFork() external view returns (uint256 forkId); + // Updates the currently active fork to given block number + // This is similar to `roll` but for the currently active fork + function rollFork(uint256 blockNumber) external; + // Updates the currently active fork to given transaction + // this will `rollFork` with the number of the block the transaction was mined in and replays all transaction mined before it in the block + function rollFork(bytes32 txHash) external; + // Updates the given fork to given block number + function rollFork(uint256 forkId, uint256 blockNumber) external; + // Updates the given fork to block number of the given transaction and replays all transaction mined before it in the block + function rollFork(uint256 forkId, bytes32 txHash) external; + // Marks that the account(s) should use persistent storage across fork swaps in a multifork setup + // Meaning, changes made to the state of this account will be kept when switching forks + function makePersistent(address account) external; + function makePersistent(address account0, address account1) external; + function makePersistent(address account0, address account1, address account2) external; + function makePersistent(address[] calldata accounts) external; + // Revokes persistent status from the address, previously added via `makePersistent` + function revokePersistent(address account) external; + function revokePersistent(address[] calldata accounts) external; + // Returns true if the account is marked as persistent + function isPersistent(address account) external view returns (bool persistent); + // In forking mode, explicitly grant the given address cheatcode access + function allowCheatcodes(address account) external; + // Fetches the given transaction from the active fork and executes it on the current state + function transact(bytes32 txHash) external; + // Fetches the given transaction from the given fork and executes it on the current state + function transact(uint256 forkId, bytes32 txHash) external; +} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/src/console.sol b/packages/wallet/wallet-contracts/lib/forge-std/src/console.sol new file mode 100644 index 0000000000..ad57e53687 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/src/console.sol @@ -0,0 +1,1533 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.4.22 <0.9.0; + +library console { + address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67); + + function _sendLogPayload(bytes memory payload) private view { + uint256 payloadLength = payload.length; + address consoleAddress = CONSOLE_ADDRESS; + /// @solidity memory-safe-assembly + assembly { + let payloadStart := add(payload, 32) + let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0) + } + } + + function log() internal view { + _sendLogPayload(abi.encodeWithSignature("log()")); + } + + function logInt(int p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(int)", p0)); + } + + function logUint(uint p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint)", p0)); + } + + function logString(string memory p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); + } + + function logBool(bool p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); + } + + function logAddress(address p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); + } + + function logBytes(bytes memory p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes)", p0)); + } + + function logBytes1(bytes1 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0)); + } + + function logBytes2(bytes2 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0)); + } + + function logBytes3(bytes3 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0)); + } + + function logBytes4(bytes4 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0)); + } + + function logBytes5(bytes5 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0)); + } + + function logBytes6(bytes6 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0)); + } + + function logBytes7(bytes7 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0)); + } + + function logBytes8(bytes8 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0)); + } + + function logBytes9(bytes9 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0)); + } + + function logBytes10(bytes10 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0)); + } + + function logBytes11(bytes11 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0)); + } + + function logBytes12(bytes12 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0)); + } + + function logBytes13(bytes13 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0)); + } + + function logBytes14(bytes14 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0)); + } + + function logBytes15(bytes15 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0)); + } + + function logBytes16(bytes16 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0)); + } + + function logBytes17(bytes17 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0)); + } + + function logBytes18(bytes18 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0)); + } + + function logBytes19(bytes19 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0)); + } + + function logBytes20(bytes20 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0)); + } + + function logBytes21(bytes21 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0)); + } + + function logBytes22(bytes22 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0)); + } + + function logBytes23(bytes23 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0)); + } + + function logBytes24(bytes24 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0)); + } + + function logBytes25(bytes25 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0)); + } + + function logBytes26(bytes26 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0)); + } + + function logBytes27(bytes27 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0)); + } + + function logBytes28(bytes28 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0)); + } + + function logBytes29(bytes29 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0)); + } + + function logBytes30(bytes30 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0)); + } + + function logBytes31(bytes31 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0)); + } + + function logBytes32(bytes32 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0)); + } + + function log(uint p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint)", p0)); + } + + function log(string memory p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); + } + + function log(bool p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); + } + + function log(address p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); + } + + function log(uint p0, uint p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint)", p0, p1)); + } + + function log(uint p0, string memory p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string)", p0, p1)); + } + + function log(uint p0, bool p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool)", p0, p1)); + } + + function log(uint p0, address p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address)", p0, p1)); + } + + function log(string memory p0, uint p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint)", p0, p1)); + } + + function log(string memory p0, string memory p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1)); + } + + function log(string memory p0, bool p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1)); + } + + function log(string memory p0, address p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1)); + } + + function log(bool p0, uint p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint)", p0, p1)); + } + + function log(bool p0, string memory p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1)); + } + + function log(bool p0, bool p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1)); + } + + function log(bool p0, address p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1)); + } + + function log(address p0, uint p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint)", p0, p1)); + } + + function log(address p0, string memory p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1)); + } + + function log(address p0, bool p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1)); + } + + function log(address p0, address p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1)); + } + + function log(uint p0, uint p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint)", p0, p1, p2)); + } + + function log(uint p0, uint p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string)", p0, p1, p2)); + } + + function log(uint p0, uint p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool)", p0, p1, p2)); + } + + function log(uint p0, uint p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address)", p0, p1, p2)); + } + + function log(uint p0, string memory p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint)", p0, p1, p2)); + } + + function log(uint p0, string memory p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,string)", p0, p1, p2)); + } + + function log(uint p0, string memory p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool)", p0, p1, p2)); + } + + function log(uint p0, string memory p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,address)", p0, p1, p2)); + } + + function log(uint p0, bool p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint)", p0, p1, p2)); + } + + function log(uint p0, bool p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string)", p0, p1, p2)); + } + + function log(uint p0, bool p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool)", p0, p1, p2)); + } + + function log(uint p0, bool p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address)", p0, p1, p2)); + } + + function log(uint p0, address p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint)", p0, p1, p2)); + } + + function log(uint p0, address p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,string)", p0, p1, p2)); + } + + function log(uint p0, address p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool)", p0, p1, p2)); + } + + function log(uint p0, address p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,address)", p0, p1, p2)); + } + + function log(string memory p0, uint p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint)", p0, p1, p2)); + } + + function log(string memory p0, uint p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,string)", p0, p1, p2)); + } + + function log(string memory p0, uint p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool)", p0, p1, p2)); + } + + function log(string memory p0, uint p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,address)", p0, p1, p2)); + } + + function log(string memory p0, string memory p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint)", p0, p1, p2)); + } + + function log(string memory p0, string memory p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2)); + } + + function log(string memory p0, string memory p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2)); + } + + function log(string memory p0, string memory p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2)); + } + + function log(string memory p0, bool p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint)", p0, p1, p2)); + } + + function log(string memory p0, bool p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2)); + } + + function log(string memory p0, bool p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2)); + } + + function log(string memory p0, bool p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2)); + } + + function log(string memory p0, address p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint)", p0, p1, p2)); + } + + function log(string memory p0, address p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2)); + } + + function log(string memory p0, address p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2)); + } + + function log(string memory p0, address p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2)); + } + + function log(bool p0, uint p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint)", p0, p1, p2)); + } + + function log(bool p0, uint p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string)", p0, p1, p2)); + } + + function log(bool p0, uint p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool)", p0, p1, p2)); + } + + function log(bool p0, uint p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address)", p0, p1, p2)); + } + + function log(bool p0, string memory p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint)", p0, p1, p2)); + } + + function log(bool p0, string memory p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2)); + } + + function log(bool p0, string memory p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2)); + } + + function log(bool p0, string memory p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2)); + } + + function log(bool p0, bool p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint)", p0, p1, p2)); + } + + function log(bool p0, bool p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2)); + } + + function log(bool p0, bool p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2)); + } + + function log(bool p0, bool p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2)); + } + + function log(bool p0, address p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint)", p0, p1, p2)); + } + + function log(bool p0, address p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2)); + } + + function log(bool p0, address p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2)); + } + + function log(bool p0, address p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2)); + } + + function log(address p0, uint p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint)", p0, p1, p2)); + } + + function log(address p0, uint p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,string)", p0, p1, p2)); + } + + function log(address p0, uint p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool)", p0, p1, p2)); + } + + function log(address p0, uint p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,address)", p0, p1, p2)); + } + + function log(address p0, string memory p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint)", p0, p1, p2)); + } + + function log(address p0, string memory p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2)); + } + + function log(address p0, string memory p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2)); + } + + function log(address p0, string memory p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2)); + } + + function log(address p0, bool p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint)", p0, p1, p2)); + } + + function log(address p0, bool p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2)); + } + + function log(address p0, bool p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2)); + } + + function log(address p0, bool p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2)); + } + + function log(address p0, address p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint)", p0, p1, p2)); + } + + function log(address p0, address p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2)); + } + + function log(address p0, address p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2)); + } + + function log(address p0, address p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2)); + } + + function log(uint p0, uint p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,string)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,address)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,string)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,address)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,string)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,address)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,string)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,address)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,string)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,address)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,string)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,address)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,string)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,address)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,string)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,address)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,string)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,address)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,string)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,address)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,string)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,address)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,string)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,address)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,string)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,address)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,string)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,address)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,string)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,address)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,string)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,string)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,address)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,string)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,address)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,string)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,address)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,string)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,address)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,string)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,address)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,string)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,address)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,string)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,address)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,uint)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,string)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,bool)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,address)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,uint)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,string)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,bool)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,address)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,uint)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,string)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,bool)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,address)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,uint)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,string)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,bool)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,address)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,uint)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,string)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,bool)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,address)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,uint)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,string)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,bool)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,address)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,uint)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,string)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,bool)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,address)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3)); + } + +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/lib/forge-std/src/console2.sol b/packages/wallet/wallet-contracts/lib/forge-std/src/console2.sol new file mode 100644 index 0000000000..8596233d3c --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/src/console2.sol @@ -0,0 +1,1546 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.4.22 <0.9.0; + +/// @dev The original console.sol uses `int` and `uint` for computing function selectors, but it should +/// use `int256` and `uint256`. This modified version fixes that. This version is recommended +/// over `console.sol` if you don't need compatibility with Hardhat as the logs will show up in +/// forge stack traces. If you do need compatibility with Hardhat, you must use `console.sol`. +/// Reference: https://github.com/NomicFoundation/hardhat/issues/2178 +library console2 { + address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67); + + function _sendLogPayload(bytes memory payload) private view { + uint256 payloadLength = payload.length; + address consoleAddress = CONSOLE_ADDRESS; + /// @solidity memory-safe-assembly + assembly { + let payloadStart := add(payload, 32) + let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0) + } + } + + function log() internal view { + _sendLogPayload(abi.encodeWithSignature("log()")); + } + + function logInt(int256 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(int256)", p0)); + } + + function logUint(uint256 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0)); + } + + function logString(string memory p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); + } + + function logBool(bool p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); + } + + function logAddress(address p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); + } + + function logBytes(bytes memory p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes)", p0)); + } + + function logBytes1(bytes1 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0)); + } + + function logBytes2(bytes2 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0)); + } + + function logBytes3(bytes3 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0)); + } + + function logBytes4(bytes4 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0)); + } + + function logBytes5(bytes5 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0)); + } + + function logBytes6(bytes6 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0)); + } + + function logBytes7(bytes7 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0)); + } + + function logBytes8(bytes8 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0)); + } + + function logBytes9(bytes9 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0)); + } + + function logBytes10(bytes10 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0)); + } + + function logBytes11(bytes11 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0)); + } + + function logBytes12(bytes12 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0)); + } + + function logBytes13(bytes13 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0)); + } + + function logBytes14(bytes14 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0)); + } + + function logBytes15(bytes15 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0)); + } + + function logBytes16(bytes16 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0)); + } + + function logBytes17(bytes17 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0)); + } + + function logBytes18(bytes18 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0)); + } + + function logBytes19(bytes19 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0)); + } + + function logBytes20(bytes20 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0)); + } + + function logBytes21(bytes21 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0)); + } + + function logBytes22(bytes22 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0)); + } + + function logBytes23(bytes23 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0)); + } + + function logBytes24(bytes24 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0)); + } + + function logBytes25(bytes25 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0)); + } + + function logBytes26(bytes26 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0)); + } + + function logBytes27(bytes27 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0)); + } + + function logBytes28(bytes28 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0)); + } + + function logBytes29(bytes29 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0)); + } + + function logBytes30(bytes30 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0)); + } + + function logBytes31(bytes31 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0)); + } + + function logBytes32(bytes32 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0)); + } + + function log(uint256 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0)); + } + + function log(int256 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(int256)", p0)); + } + + function log(string memory p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); + } + + function log(bool p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); + } + + function log(address p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); + } + + function log(uint256 p0, uint256 p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256)", p0, p1)); + } + + function log(uint256 p0, string memory p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string)", p0, p1)); + } + + function log(uint256 p0, bool p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool)", p0, p1)); + } + + function log(uint256 p0, address p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address)", p0, p1)); + } + + function log(string memory p0, uint256 p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256)", p0, p1)); + } + + function log(string memory p0, int256 p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,int256)", p0, p1)); + } + + function log(string memory p0, string memory p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1)); + } + + function log(string memory p0, bool p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1)); + } + + function log(string memory p0, address p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1)); + } + + function log(bool p0, uint256 p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256)", p0, p1)); + } + + function log(bool p0, string memory p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1)); + } + + function log(bool p0, bool p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1)); + } + + function log(bool p0, address p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1)); + } + + function log(address p0, uint256 p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256)", p0, p1)); + } + + function log(address p0, string memory p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1)); + } + + function log(address p0, bool p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1)); + } + + function log(address p0, address p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1)); + } + + function log(uint256 p0, uint256 p1, uint256 p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256)", p0, p1, p2)); + } + + function log(uint256 p0, uint256 p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string)", p0, p1, p2)); + } + + function log(uint256 p0, uint256 p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool)", p0, p1, p2)); + } + + function log(uint256 p0, uint256 p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address)", p0, p1, p2)); + } + + function log(uint256 p0, string memory p1, uint256 p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256)", p0, p1, p2)); + } + + function log(uint256 p0, string memory p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string)", p0, p1, p2)); + } + + function log(uint256 p0, string memory p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool)", p0, p1, p2)); + } + + function log(uint256 p0, string memory p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address)", p0, p1, p2)); + } + + function log(uint256 p0, bool p1, uint256 p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256)", p0, p1, p2)); + } + + function log(uint256 p0, bool p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string)", p0, p1, p2)); + } + + function log(uint256 p0, bool p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool)", p0, p1, p2)); + } + + function log(uint256 p0, bool p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address)", p0, p1, p2)); + } + + function log(uint256 p0, address p1, uint256 p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256)", p0, p1, p2)); + } + + function log(uint256 p0, address p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string)", p0, p1, p2)); + } + + function log(uint256 p0, address p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool)", p0, p1, p2)); + } + + function log(uint256 p0, address p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address)", p0, p1, p2)); + } + + function log(string memory p0, uint256 p1, uint256 p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256)", p0, p1, p2)); + } + + function log(string memory p0, uint256 p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string)", p0, p1, p2)); + } + + function log(string memory p0, uint256 p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool)", p0, p1, p2)); + } + + function log(string memory p0, uint256 p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address)", p0, p1, p2)); + } + + function log(string memory p0, string memory p1, uint256 p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256)", p0, p1, p2)); + } + + function log(string memory p0, string memory p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2)); + } + + function log(string memory p0, string memory p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2)); + } + + function log(string memory p0, string memory p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2)); + } + + function log(string memory p0, bool p1, uint256 p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256)", p0, p1, p2)); + } + + function log(string memory p0, bool p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2)); + } + + function log(string memory p0, bool p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2)); + } + + function log(string memory p0, bool p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2)); + } + + function log(string memory p0, address p1, uint256 p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256)", p0, p1, p2)); + } + + function log(string memory p0, address p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2)); + } + + function log(string memory p0, address p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2)); + } + + function log(string memory p0, address p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2)); + } + + function log(bool p0, uint256 p1, uint256 p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256)", p0, p1, p2)); + } + + function log(bool p0, uint256 p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string)", p0, p1, p2)); + } + + function log(bool p0, uint256 p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool)", p0, p1, p2)); + } + + function log(bool p0, uint256 p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address)", p0, p1, p2)); + } + + function log(bool p0, string memory p1, uint256 p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256)", p0, p1, p2)); + } + + function log(bool p0, string memory p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2)); + } + + function log(bool p0, string memory p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2)); + } + + function log(bool p0, string memory p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2)); + } + + function log(bool p0, bool p1, uint256 p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256)", p0, p1, p2)); + } + + function log(bool p0, bool p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2)); + } + + function log(bool p0, bool p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2)); + } + + function log(bool p0, bool p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2)); + } + + function log(bool p0, address p1, uint256 p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256)", p0, p1, p2)); + } + + function log(bool p0, address p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2)); + } + + function log(bool p0, address p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2)); + } + + function log(bool p0, address p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2)); + } + + function log(address p0, uint256 p1, uint256 p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256)", p0, p1, p2)); + } + + function log(address p0, uint256 p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string)", p0, p1, p2)); + } + + function log(address p0, uint256 p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool)", p0, p1, p2)); + } + + function log(address p0, uint256 p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address)", p0, p1, p2)); + } + + function log(address p0, string memory p1, uint256 p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256)", p0, p1, p2)); + } + + function log(address p0, string memory p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2)); + } + + function log(address p0, string memory p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2)); + } + + function log(address p0, string memory p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2)); + } + + function log(address p0, bool p1, uint256 p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256)", p0, p1, p2)); + } + + function log(address p0, bool p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2)); + } + + function log(address p0, bool p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2)); + } + + function log(address p0, bool p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2)); + } + + function log(address p0, address p1, uint256 p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256)", p0, p1, p2)); + } + + function log(address p0, address p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2)); + } + + function log(address p0, address p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2)); + } + + function log(address p0, address p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2)); + } + + function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, uint256 p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, address p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, uint256 p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, uint256 p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, bool p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, address p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, uint256 p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, uint256 p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, uint256 p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, string memory p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, bool p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, address p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, uint256 p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, address p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, uint256 p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, uint256 p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, bool p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, address p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, uint256 p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, uint256 p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, uint256 p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, string memory p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, bool p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, address p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, uint256 p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, uint256 p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, uint256 p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, uint256 p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, string memory p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, bool p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, address p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,string)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, uint256 p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, uint256 p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,address)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,string)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,address)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, bool p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,string)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,address)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, address p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,string)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,address)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, uint256 p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,string)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, uint256 p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, uint256 p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,address)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, string memory p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, bool p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, address p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, uint256 p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, uint256 p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,string)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, uint256 p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, uint256 p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,address)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, string memory p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, bool p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, address p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, uint256 p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, uint256 p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,string)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, uint256 p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, uint256 p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,address)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, string memory p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, bool p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, address p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, uint256 p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,string)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, uint256 p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,bool)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, uint256 p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,address)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, string memory p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,string)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,bool)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,address)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, bool p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,string)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,bool)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,address)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, address p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,string)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,bool)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,address)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, uint256 p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, uint256 p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,string)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, uint256 p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,bool)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, uint256 p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,address)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, string memory p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, bool p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, address p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, uint256 p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, uint256 p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,string)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, uint256 p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,bool)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, uint256 p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,address)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, string memory p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, bool p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, address p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, uint256 p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, uint256 p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,string)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, uint256 p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,bool)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, uint256 p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,address)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, string memory p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, bool p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, address p2, uint256 p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3)); + } + +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/lib/forge-std/src/interfaces/IERC1155.sol b/packages/wallet/wallet-contracts/lib/forge-std/src/interfaces/IERC1155.sol new file mode 100644 index 0000000000..f7dd2b4106 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/src/interfaces/IERC1155.sol @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +import "./IERC165.sol"; + +/// @title ERC-1155 Multi Token Standard +/// @dev See https://eips.ethereum.org/EIPS/eip-1155 +/// Note: The ERC-165 identifier for this interface is 0xd9b67a26. +interface IERC1155 is IERC165 { + /// @dev + /// - Either `TransferSingle` or `TransferBatch` MUST emit when tokens are transferred, including zero value transfers as well as minting or burning (see "Safe Transfer Rules" section of the standard). + /// - The `_operator` argument MUST be the address of an account/contract that is approved to make the transfer (SHOULD be msg.sender). + /// - The `_from` argument MUST be the address of the holder whose balance is decreased. + /// - The `_to` argument MUST be the address of the recipient whose balance is increased. + /// - The `_id` argument MUST be the token type being transferred. + /// - The `_value` argument MUST be the number of tokens the holder balance is decreased by and match what the recipient balance is increased by. + /// - When minting/creating tokens, the `_from` argument MUST be set to `0x0` (i.e. zero address). + /// - When burning/destroying tokens, the `_to` argument MUST be set to `0x0` (i.e. zero address). + event TransferSingle( + address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _value + ); + + /// @dev + /// - Either `TransferSingle` or `TransferBatch` MUST emit when tokens are transferred, including zero value transfers as well as minting or burning (see "Safe Transfer Rules" section of the standard). + /// - The `_operator` argument MUST be the address of an account/contract that is approved to make the transfer (SHOULD be msg.sender). + /// - The `_from` argument MUST be the address of the holder whose balance is decreased. + /// - The `_to` argument MUST be the address of the recipient whose balance is increased. + /// - The `_ids` argument MUST be the list of tokens being transferred. + /// - The `_values` argument MUST be the list of number of tokens (matching the list and order of tokens specified in _ids) the holder balance is decreased by and match what the recipient balance is increased by. + /// - When minting/creating tokens, the `_from` argument MUST be set to `0x0` (i.e. zero address). + /// - When burning/destroying tokens, the `_to` argument MUST be set to `0x0` (i.e. zero address). + event TransferBatch( + address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _values + ); + + /// @dev MUST emit when approval for a second party/operator address to manage all tokens for an owner address is enabled or disabled (absence of an event assumes disabled). + event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); + + /// @dev MUST emit when the URI is updated for a token ID. URIs are defined in RFC 3986. + /// The URI MUST point to a JSON file that conforms to the "ERC-1155 Metadata URI JSON Schema". + event URI(string _value, uint256 indexed _id); + + /// @notice Transfers `_value` amount of an `_id` from the `_from` address to the `_to` address specified (with safety call). + /// @dev Caller must be approved to manage the tokens being transferred out of the `_from` account (see "Approval" section of the standard). + /// - MUST revert if `_to` is the zero address. + /// - MUST revert if balance of holder for token `_id` is lower than the `_value` sent. + /// - MUST revert on any other error. + /// - MUST emit the `TransferSingle` event to reflect the balance change (see "Safe Transfer Rules" section of the standard). + /// - After the above conditions are met, this function MUST check if `_to` is a smart contract (e.g. code size > 0). If so, it MUST call `onERC1155Received` on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard). + /// @param _from Source address + /// @param _to Target address + /// @param _id ID of the token type + /// @param _value Transfer amount + /// @param _data Additional data with no specified format, MUST be sent unaltered in call to `onERC1155Received` on `_to` + function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, bytes calldata _data) external; + + /// @notice Transfers `_values` amount(s) of `_ids` from the `_from` address to the `_to` address specified (with safety call). + /// @dev Caller must be approved to manage the tokens being transferred out of the `_from` account (see "Approval" section of the standard). + /// - MUST revert if `_to` is the zero address. + /// - MUST revert if length of `_ids` is not the same as length of `_values`. + /// - MUST revert if any of the balance(s) of the holder(s) for token(s) in `_ids` is lower than the respective amount(s) in `_values` sent to the recipient. + /// - MUST revert on any other error. + /// - MUST emit `TransferSingle` or `TransferBatch` event(s) such that all the balance changes are reflected (see "Safe Transfer Rules" section of the standard). + /// - Balance changes and events MUST follow the ordering of the arrays (_ids[0]/_values[0] before _ids[1]/_values[1], etc). + /// - After the above conditions for the transfer(s) in the batch are met, this function MUST check if `_to` is a smart contract (e.g. code size > 0). If so, it MUST call the relevant `ERC1155TokenReceiver` hook(s) on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard). + /// @param _from Source address + /// @param _to Target address + /// @param _ids IDs of each token type (order and length must match _values array) + /// @param _values Transfer amounts per token type (order and length must match _ids array) + /// @param _data Additional data with no specified format, MUST be sent unaltered in call to the `ERC1155TokenReceiver` hook(s) on `_to` + function safeBatchTransferFrom( + address _from, + address _to, + uint256[] calldata _ids, + uint256[] calldata _values, + bytes calldata _data + ) external; + + /// @notice Get the balance of an account's tokens. + /// @param _owner The address of the token holder + /// @param _id ID of the token + /// @return The _owner's balance of the token type requested + function balanceOf(address _owner, uint256 _id) external view returns (uint256); + + /// @notice Get the balance of multiple account/token pairs + /// @param _owners The addresses of the token holders + /// @param _ids ID of the tokens + /// @return The _owner's balance of the token types requested (i.e. balance for each (owner, id) pair) + function balanceOfBatch(address[] calldata _owners, uint256[] calldata _ids) + external + view + returns (uint256[] memory); + + /// @notice Enable or disable approval for a third party ("operator") to manage all of the caller's tokens. + /// @dev MUST emit the ApprovalForAll event on success. + /// @param _operator Address to add to the set of authorized operators + /// @param _approved True if the operator is approved, false to revoke approval + function setApprovalForAll(address _operator, bool _approved) external; + + /// @notice Queries the approval status of an operator for a given owner. + /// @param _owner The owner of the tokens + /// @param _operator Address of authorized operator + /// @return True if the operator is approved, false if not + function isApprovedForAll(address _owner, address _operator) external view returns (bool); +} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/src/interfaces/IERC165.sol b/packages/wallet/wallet-contracts/lib/forge-std/src/interfaces/IERC165.sol new file mode 100644 index 0000000000..9af4bf800f --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/src/interfaces/IERC165.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +interface IERC165 { + /// @notice Query if a contract implements an interface + /// @param interfaceID The interface identifier, as specified in ERC-165 + /// @dev Interface identification is specified in ERC-165. This function + /// uses less than 30,000 gas. + /// @return `true` if the contract implements `interfaceID` and + /// `interfaceID` is not 0xffffffff, `false` otherwise + function supportsInterface(bytes4 interfaceID) external view returns (bool); +} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/src/interfaces/IERC20.sol b/packages/wallet/wallet-contracts/lib/forge-std/src/interfaces/IERC20.sol new file mode 100644 index 0000000000..ba40806c3b --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/src/interfaces/IERC20.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +/// @dev Interface of the ERC20 standard as defined in the EIP. +/// @dev This includes the optional name, symbol, and decimals metadata. +interface IERC20 { + /// @dev Emitted when `value` tokens are moved from one account (`from`) to another (`to`). + event Transfer(address indexed from, address indexed to, uint256 value); + + /// @dev Emitted when the allowance of a `spender` for an `owner` is set, where `value` + /// is the new allowance. + event Approval(address indexed owner, address indexed spender, uint256 value); + + /// @notice Returns the amount of tokens in existence. + function totalSupply() external view returns (uint256); + + /// @notice Returns the amount of tokens owned by `account`. + function balanceOf(address account) external view returns (uint256); + + /// @notice Moves `amount` tokens from the caller's account to `to`. + function transfer(address to, uint256 amount) external returns (bool); + + /// @notice Returns the remaining number of tokens that `spender` is allowed + /// to spend on behalf of `owner` + function allowance(address owner, address spender) external view returns (uint256); + + /// @notice Sets `amount` as the allowance of `spender` over the caller's tokens. + /// @dev Be aware of front-running risks: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 + function approve(address spender, uint256 amount) external returns (bool); + + /// @notice Moves `amount` tokens from `from` to `to` using the allowance mechanism. + /// `amount` is then deducted from the caller's allowance. + function transferFrom(address from, address to, uint256 amount) external returns (bool); + + /// @notice Returns the name of the token. + function name() external view returns (string memory); + + /// @notice Returns the symbol of the token. + function symbol() external view returns (string memory); + + /// @notice Returns the decimals places of the token. + function decimals() external view returns (uint8); +} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/src/interfaces/IERC4626.sol b/packages/wallet/wallet-contracts/lib/forge-std/src/interfaces/IERC4626.sol new file mode 100644 index 0000000000..bfe3a1155e --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/src/interfaces/IERC4626.sol @@ -0,0 +1,190 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +import "./IERC20.sol"; + +/// @dev Interface of the ERC4626 "Tokenized Vault Standard", as defined in +/// https://eips.ethereum.org/EIPS/eip-4626 +interface IERC4626 is IERC20 { + event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares); + + event Withdraw( + address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares + ); + + /// @notice Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing. + /// @dev + /// - MUST be an ERC-20 token contract. + /// - MUST NOT revert. + function asset() external view returns (address assetTokenAddress); + + /// @notice Returns the total amount of the underlying asset that is ā€œmanagedā€ by Vault. + /// @dev + /// - SHOULD include any compounding that occurs from yield. + /// - MUST be inclusive of any fees that are charged against assets in the Vault. + /// - MUST NOT revert. + function totalAssets() external view returns (uint256 totalManagedAssets); + + /// @notice Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal + /// scenario where all the conditions are met. + /// @dev + /// - MUST NOT be inclusive of any fees that are charged against assets in the Vault. + /// - MUST NOT show any variations depending on the caller. + /// - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. + /// - MUST NOT revert. + /// + /// NOTE: This calculation MAY NOT reflect the ā€œper-userā€ price-per-share, and instead should reflect the + /// ā€œaverage-user’sā€ price-per-share, meaning what the average user should expect to see when exchanging to and + /// from. + function convertToShares(uint256 assets) external view returns (uint256 shares); + + /// @notice Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal + /// scenario where all the conditions are met. + /// @dev + /// - MUST NOT be inclusive of any fees that are charged against assets in the Vault. + /// - MUST NOT show any variations depending on the caller. + /// - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. + /// - MUST NOT revert. + /// + /// NOTE: This calculation MAY NOT reflect the ā€œper-userā€ price-per-share, and instead should reflect the + /// ā€œaverage-user’sā€ price-per-share, meaning what the average user should expect to see when exchanging to and + /// from. + function convertToAssets(uint256 shares) external view returns (uint256 assets); + + /// @notice Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver, + /// through a deposit call. + /// @dev + /// - MUST return a limited value if receiver is subject to some deposit limit. + /// - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited. + /// - MUST NOT revert. + function maxDeposit(address receiver) external view returns (uint256 maxAssets); + + /// @notice Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given + /// current on-chain conditions. + /// @dev + /// - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit + /// call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called + /// in the same transaction. + /// - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the + /// deposit would be accepted, regardless if the user has enough tokens approved, etc. + /// - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. + /// - MUST NOT revert. + /// + /// NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in + /// share price or some other type of condition, meaning the depositor will lose assets by depositing. + function previewDeposit(uint256 assets) external view returns (uint256 shares); + + /// @notice Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens. + /// @dev + /// - MUST emit the Deposit event. + /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the + /// deposit execution, and are accounted for during deposit. + /// - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not + /// approving enough underlying tokens to the Vault contract, etc). + /// + /// NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. + function deposit(uint256 assets, address receiver) external returns (uint256 shares); + + /// @notice Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call. + /// @dev + /// - MUST return a limited value if receiver is subject to some mint limit. + /// - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted. + /// - MUST NOT revert. + function maxMint(address receiver) external view returns (uint256 maxShares); + + /// @notice Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given + /// current on-chain conditions. + /// @dev + /// - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call + /// in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the + /// same transaction. + /// - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint + /// would be accepted, regardless if the user has enough tokens approved, etc. + /// - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. + /// - MUST NOT revert. + /// + /// NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in + /// share price or some other type of condition, meaning the depositor will lose assets by minting. + function previewMint(uint256 shares) external view returns (uint256 assets); + + /// @notice Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens. + /// @dev + /// - MUST emit the Deposit event. + /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint + /// execution, and are accounted for during mint. + /// - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not + /// approving enough underlying tokens to the Vault contract, etc). + /// + /// NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. + function mint(uint256 shares, address receiver) external returns (uint256 assets); + + /// @notice Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the + /// Vault, through a withdraw call. + /// @dev + /// - MUST return a limited value if owner is subject to some withdrawal limit or timelock. + /// - MUST NOT revert. + function maxWithdraw(address owner) external view returns (uint256 maxAssets); + + /// @notice Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block, + /// given current on-chain conditions. + /// @dev + /// - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw + /// call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if + /// called + /// in the same transaction. + /// - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though + /// the withdrawal would be accepted, regardless if the user has enough shares, etc. + /// - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. + /// - MUST NOT revert. + /// + /// NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in + /// share price or some other type of condition, meaning the depositor will lose assets by depositing. + function previewWithdraw(uint256 assets) external view returns (uint256 shares); + + /// @notice Burns shares from owner and sends exactly assets of underlying tokens to receiver. + /// @dev + /// - MUST emit the Withdraw event. + /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the + /// withdraw execution, and are accounted for during withdraw. + /// - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner + /// not having enough shares, etc). + /// + /// Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed. + /// Those methods should be performed separately. + function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares); + + /// @notice Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault, + /// through a redeem call. + /// @dev + /// - MUST return a limited value if owner is subject to some withdrawal limit or timelock. + /// - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock. + /// - MUST NOT revert. + function maxRedeem(address owner) external view returns (uint256 maxShares); + + /// @notice Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block, + /// given current on-chain conditions. + /// @dev + /// - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call + /// in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the + /// same transaction. + /// - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the + /// redemption would be accepted, regardless if the user has enough shares, etc. + /// - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. + /// - MUST NOT revert. + /// + /// NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in + /// share price or some other type of condition, meaning the depositor will lose assets by redeeming. + function previewRedeem(uint256 shares) external view returns (uint256 assets); + + /// @notice Burns exactly shares from owner and sends assets of underlying tokens to receiver. + /// @dev + /// - MUST emit the Withdraw event. + /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the + /// redeem execution, and are accounted for during redeem. + /// - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner + /// not having enough shares, etc). + /// + /// NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed. + /// Those methods should be performed separately. + function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets); +} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/src/interfaces/IERC721.sol b/packages/wallet/wallet-contracts/lib/forge-std/src/interfaces/IERC721.sol new file mode 100644 index 0000000000..0a16f45cc5 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/src/interfaces/IERC721.sol @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +import "./IERC165.sol"; + +/// @title ERC-721 Non-Fungible Token Standard +/// @dev See https://eips.ethereum.org/EIPS/eip-721 +/// Note: the ERC-165 identifier for this interface is 0x80ac58cd. +interface IERC721 is IERC165 { + /// @dev This emits when ownership of any NFT changes by any mechanism. + /// This event emits when NFTs are created (`from` == 0) and destroyed + /// (`to` == 0). Exception: during contract creation, any number of NFTs + /// may be created and assigned without emitting Transfer. At the time of + /// any transfer, the approved address for that NFT (if any) is reset to none. + event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId); + + /// @dev This emits when the approved address for an NFT is changed or + /// reaffirmed. The zero address indicates there is no approved address. + /// When a Transfer event emits, this also indicates that the approved + /// address for that NFT (if any) is reset to none. + event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId); + + /// @dev This emits when an operator is enabled or disabled for an owner. + /// The operator can manage all NFTs of the owner. + event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); + + /// @notice Count all NFTs assigned to an owner + /// @dev NFTs assigned to the zero address are considered invalid, and this + /// function throws for queries about the zero address. + /// @param _owner An address for whom to query the balance + /// @return The number of NFTs owned by `_owner`, possibly zero + function balanceOf(address _owner) external view returns (uint256); + + /// @notice Find the owner of an NFT + /// @dev NFTs assigned to zero address are considered invalid, and queries + /// about them do throw. + /// @param _tokenId The identifier for an NFT + /// @return The address of the owner of the NFT + function ownerOf(uint256 _tokenId) external view returns (address); + + /// @notice Transfers the ownership of an NFT from one address to another address + /// @dev Throws unless `msg.sender` is the current owner, an authorized + /// operator, or the approved address for this NFT. Throws if `_from` is + /// not the current owner. Throws if `_to` is the zero address. Throws if + /// `_tokenId` is not a valid NFT. When transfer is complete, this function + /// checks if `_to` is a smart contract (code size > 0). If so, it calls + /// `onERC721Received` on `_to` and throws if the return value is not + /// `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`. + /// @param _from The current owner of the NFT + /// @param _to The new owner + /// @param _tokenId The NFT to transfer + /// @param data Additional data with no specified format, sent in call to `_to` + function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes calldata data) external payable; + + /// @notice Transfers the ownership of an NFT from one address to another address + /// @dev This works identically to the other function with an extra data parameter, + /// except this function just sets data to "". + /// @param _from The current owner of the NFT + /// @param _to The new owner + /// @param _tokenId The NFT to transfer + function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable; + + /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE + /// TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE + /// THEY MAY BE PERMANENTLY LOST + /// @dev Throws unless `msg.sender` is the current owner, an authorized + /// operator, or the approved address for this NFT. Throws if `_from` is + /// not the current owner. Throws if `_to` is the zero address. Throws if + /// `_tokenId` is not a valid NFT. + /// @param _from The current owner of the NFT + /// @param _to The new owner + /// @param _tokenId The NFT to transfer + function transferFrom(address _from, address _to, uint256 _tokenId) external payable; + + /// @notice Change or reaffirm the approved address for an NFT + /// @dev The zero address indicates there is no approved address. + /// Throws unless `msg.sender` is the current NFT owner, or an authorized + /// operator of the current owner. + /// @param _approved The new approved NFT controller + /// @param _tokenId The NFT to approve + function approve(address _approved, uint256 _tokenId) external payable; + + /// @notice Enable or disable approval for a third party ("operator") to manage + /// all of `msg.sender`'s assets + /// @dev Emits the ApprovalForAll event. The contract MUST allow + /// multiple operators per owner. + /// @param _operator Address to add to the set of authorized operators + /// @param _approved True if the operator is approved, false to revoke approval + function setApprovalForAll(address _operator, bool _approved) external; + + /// @notice Get the approved address for a single NFT + /// @dev Throws if `_tokenId` is not a valid NFT. + /// @param _tokenId The NFT to find the approved address for + /// @return The approved address for this NFT, or the zero address if there is none + function getApproved(uint256 _tokenId) external view returns (address); + + /// @notice Query if an address is an authorized operator for another address + /// @param _owner The address that owns the NFTs + /// @param _operator The address that acts on behalf of the owner + /// @return True if `_operator` is an approved operator for `_owner`, false otherwise + function isApprovedForAll(address _owner, address _operator) external view returns (bool); +} + +/// @dev Note: the ERC-165 identifier for this interface is 0x150b7a02. +interface IERC721TokenReceiver { + /// @notice Handle the receipt of an NFT + /// @dev The ERC721 smart contract calls this function on the recipient + /// after a `transfer`. This function MAY throw to revert and reject the + /// transfer. Return of other than the magic value MUST result in the + /// transaction being reverted. + /// Note: the contract address is always the message sender. + /// @param _operator The address which called `safeTransferFrom` function + /// @param _from The address which previously owned the token + /// @param _tokenId The NFT identifier which is being transferred + /// @param _data Additional data with no specified format + /// @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` + /// unless throwing + function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes calldata _data) + external + returns (bytes4); +} + +/// @title ERC-721 Non-Fungible Token Standard, optional metadata extension +/// @dev See https://eips.ethereum.org/EIPS/eip-721 +/// Note: the ERC-165 identifier for this interface is 0x5b5e139f. +interface IERC721Metadata is IERC721 { + /// @notice A descriptive name for a collection of NFTs in this contract + function name() external view returns (string memory _name); + + /// @notice An abbreviated name for NFTs in this contract + function symbol() external view returns (string memory _symbol); + + /// @notice A distinct Uniform Resource Identifier (URI) for a given asset. + /// @dev Throws if `_tokenId` is not a valid NFT. URIs are defined in RFC + /// 3986. The URI may point to a JSON file that conforms to the "ERC721 + /// Metadata JSON Schema". + function tokenURI(uint256 _tokenId) external view returns (string memory); +} + +/// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension +/// @dev See https://eips.ethereum.org/EIPS/eip-721 +/// Note: the ERC-165 identifier for this interface is 0x780e9d63. +interface IERC721Enumerable is IERC721 { + /// @notice Count NFTs tracked by this contract + /// @return A count of valid NFTs tracked by this contract, where each one of + /// them has an assigned and queryable owner not equal to the zero address + function totalSupply() external view returns (uint256); + + /// @notice Enumerate valid NFTs + /// @dev Throws if `_index` >= `totalSupply()`. + /// @param _index A counter less than `totalSupply()` + /// @return The token identifier for the `_index`th NFT, + /// (sort order not specified) + function tokenByIndex(uint256 _index) external view returns (uint256); + + /// @notice Enumerate NFTs assigned to an owner + /// @dev Throws if `_index` >= `balanceOf(_owner)` or if + /// `_owner` is the zero address, representing invalid NFTs. + /// @param _owner An address where we are interested in NFTs owned by them + /// @param _index A counter less than `balanceOf(_owner)` + /// @return The token identifier for the `_index`th NFT assigned to `_owner`, + /// (sort order not specified) + function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256); +} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/src/interfaces/IMulticall3.sol b/packages/wallet/wallet-contracts/lib/forge-std/src/interfaces/IMulticall3.sol new file mode 100644 index 0000000000..0d031b71dc --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/src/interfaces/IMulticall3.sol @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +interface IMulticall3 { + struct Call { + address target; + bytes callData; + } + + struct Call3 { + address target; + bool allowFailure; + bytes callData; + } + + struct Call3Value { + address target; + bool allowFailure; + uint256 value; + bytes callData; + } + + struct Result { + bool success; + bytes returnData; + } + + function aggregate(Call[] calldata calls) + external + payable + returns (uint256 blockNumber, bytes[] memory returnData); + + function aggregate3(Call3[] calldata calls) external payable returns (Result[] memory returnData); + + function aggregate3Value(Call3Value[] calldata calls) external payable returns (Result[] memory returnData); + + function blockAndAggregate(Call[] calldata calls) + external + payable + returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData); + + function getBasefee() external view returns (uint256 basefee); + + function getBlockHash(uint256 blockNumber) external view returns (bytes32 blockHash); + + function getBlockNumber() external view returns (uint256 blockNumber); + + function getChainId() external view returns (uint256 chainid); + + function getCurrentBlockCoinbase() external view returns (address coinbase); + + function getCurrentBlockDifficulty() external view returns (uint256 difficulty); + + function getCurrentBlockGasLimit() external view returns (uint256 gaslimit); + + function getCurrentBlockTimestamp() external view returns (uint256 timestamp); + + function getEthBalance(address addr) external view returns (uint256 balance); + + function getLastBlockHash() external view returns (bytes32 blockHash); + + function tryAggregate(bool requireSuccess, Call[] calldata calls) + external + payable + returns (Result[] memory returnData); + + function tryBlockAndAggregate(bool requireSuccess, Call[] calldata calls) + external + payable + returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData); +} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/test/StdAssertions.t.sol b/packages/wallet/wallet-contracts/lib/forge-std/test/StdAssertions.t.sol new file mode 100644 index 0000000000..fcc346be66 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/test/StdAssertions.t.sol @@ -0,0 +1,999 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import "../src/Test.sol"; + +contract StdAssertionsTest is Test { + string constant CUSTOM_ERROR = "guh!"; + + bool constant EXPECT_PASS = false; + bool constant EXPECT_FAIL = true; + + bool constant SHOULD_REVERT = true; + bool constant SHOULD_RETURN = false; + + bool constant STRICT_REVERT_DATA = true; + bool constant NON_STRICT_REVERT_DATA = false; + + TestTest t = new TestTest(); + + /*////////////////////////////////////////////////////////////////////////// + FAIL(STRING) + //////////////////////////////////////////////////////////////////////////*/ + + function testShouldFail() external { + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._fail(CUSTOM_ERROR); + } + + /*////////////////////////////////////////////////////////////////////////// + ASSERT_FALSE + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertFalse_Pass() external { + t._assertFalse(false, EXPECT_PASS); + } + + function testAssertFalse_Fail() external { + vm.expectEmit(false, false, false, true); + emit log("Error: Assertion Failed"); + t._assertFalse(true, EXPECT_FAIL); + } + + function testAssertFalse_Err_Pass() external { + t._assertFalse(false, CUSTOM_ERROR, EXPECT_PASS); + } + + function testAssertFalse_Err_Fail() external { + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._assertFalse(true, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + ASSERT_EQ(BOOL) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertEq_Bool_Pass(bool a) external { + t._assertEq(a, a, EXPECT_PASS); + } + + function testAssertEq_Bool_Fail(bool a, bool b) external { + vm.assume(a != b); + + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [bool]"); + t._assertEq(a, b, EXPECT_FAIL); + } + + function testAssertEq_BoolErr_Pass(bool a) external { + t._assertEq(a, a, CUSTOM_ERROR, EXPECT_PASS); + } + + function testAssertEq_BoolErr_Fail(bool a, bool b) external { + vm.assume(a != b); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + ASSERT_EQ(BYTES) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertEq_Bytes_Pass(bytes calldata a) external { + t._assertEq(a, a, EXPECT_PASS); + } + + function testAssertEq_Bytes_Fail(bytes calldata a, bytes calldata b) external { + vm.assume(keccak256(a) != keccak256(b)); + + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [bytes]"); + t._assertEq(a, b, EXPECT_FAIL); + } + + function testAssertEq_BytesErr_Pass(bytes calldata a) external { + t._assertEq(a, a, CUSTOM_ERROR, EXPECT_PASS); + } + + function testAssertEq_BytesErr_Fail(bytes calldata a, bytes calldata b) external { + vm.assume(keccak256(a) != keccak256(b)); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + ASSERT_EQ(ARRAY) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertEq_UintArr_Pass(uint256 e0, uint256 e1, uint256 e2) public { + uint256[] memory a = new uint256[](3); + a[0] = e0; + a[1] = e1; + a[2] = e2; + uint256[] memory b = new uint256[](3); + b[0] = e0; + b[1] = e1; + b[2] = e2; + + t._assertEq(a, b, EXPECT_PASS); + } + + function testAssertEq_IntArr_Pass(int256 e0, int256 e1, int256 e2) public { + int256[] memory a = new int256[](3); + a[0] = e0; + a[1] = e1; + a[2] = e2; + int256[] memory b = new int256[](3); + b[0] = e0; + b[1] = e1; + b[2] = e2; + + t._assertEq(a, b, EXPECT_PASS); + } + + function testAssertEq_AddressArr_Pass(address e0, address e1, address e2) public { + address[] memory a = new address[](3); + a[0] = e0; + a[1] = e1; + a[2] = e2; + address[] memory b = new address[](3); + b[0] = e0; + b[1] = e1; + b[2] = e2; + + t._assertEq(a, b, EXPECT_PASS); + } + + function testAssertEq_UintArr_FailEl(uint256 e1) public { + vm.assume(e1 != 0); + uint256[] memory a = new uint256[](3); + uint256[] memory b = new uint256[](3); + b[1] = e1; + + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [uint[]]"); + t._assertEq(a, b, EXPECT_FAIL); + } + + function testAssertEq_IntArr_FailEl(int256 e1) public { + vm.assume(e1 != 0); + int256[] memory a = new int256[](3); + int256[] memory b = new int256[](3); + b[1] = e1; + + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [int[]]"); + t._assertEq(a, b, EXPECT_FAIL); + } + + function testAssertEq_AddressArr_FailEl(address e1) public { + vm.assume(e1 != address(0)); + address[] memory a = new address[](3); + address[] memory b = new address[](3); + b[1] = e1; + + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [address[]]"); + t._assertEq(a, b, EXPECT_FAIL); + } + + function testAssertEq_UintArrErr_FailEl(uint256 e1) public { + vm.assume(e1 != 0); + uint256[] memory a = new uint256[](3); + uint256[] memory b = new uint256[](3); + b[1] = e1; + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [uint[]]"); + t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); + } + + function testAssertEq_IntArrErr_FailEl(int256 e1) public { + vm.assume(e1 != 0); + int256[] memory a = new int256[](3); + int256[] memory b = new int256[](3); + b[1] = e1; + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [int[]]"); + t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); + } + + function testAssertEq_AddressArrErr_FailEl(address e1) public { + vm.assume(e1 != address(0)); + address[] memory a = new address[](3); + address[] memory b = new address[](3); + b[1] = e1; + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [address[]]"); + t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); + } + + function testAssertEq_UintArr_FailLen(uint256 lenA, uint256 lenB) public { + vm.assume(lenA != lenB); + vm.assume(lenA <= 10000); + vm.assume(lenB <= 10000); + uint256[] memory a = new uint256[](lenA); + uint256[] memory b = new uint256[](lenB); + + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [uint[]]"); + t._assertEq(a, b, EXPECT_FAIL); + } + + function testAssertEq_IntArr_FailLen(uint256 lenA, uint256 lenB) public { + vm.assume(lenA != lenB); + vm.assume(lenA <= 10000); + vm.assume(lenB <= 10000); + int256[] memory a = new int256[](lenA); + int256[] memory b = new int256[](lenB); + + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [int[]]"); + t._assertEq(a, b, EXPECT_FAIL); + } + + function testAssertEq_AddressArr_FailLen(uint256 lenA, uint256 lenB) public { + vm.assume(lenA != lenB); + vm.assume(lenA <= 10000); + vm.assume(lenB <= 10000); + address[] memory a = new address[](lenA); + address[] memory b = new address[](lenB); + + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [address[]]"); + t._assertEq(a, b, EXPECT_FAIL); + } + + function testAssertEq_UintArrErr_FailLen(uint256 lenA, uint256 lenB) public { + vm.assume(lenA != lenB); + vm.assume(lenA <= 10000); + vm.assume(lenB <= 10000); + uint256[] memory a = new uint256[](lenA); + uint256[] memory b = new uint256[](lenB); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [uint[]]"); + t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); + } + + function testAssertEq_IntArrErr_FailLen(uint256 lenA, uint256 lenB) public { + vm.assume(lenA != lenB); + vm.assume(lenA <= 10000); + vm.assume(lenB <= 10000); + int256[] memory a = new int256[](lenA); + int256[] memory b = new int256[](lenB); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [int[]]"); + t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); + } + + function testAssertEq_AddressArrErr_FailLen(uint256 lenA, uint256 lenB) public { + vm.assume(lenA != lenB); + vm.assume(lenA <= 10000); + vm.assume(lenB <= 10000); + address[] memory a = new address[](lenA); + address[] memory b = new address[](lenB); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [address[]]"); + t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + ASSERT_EQ(UINT) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertEqUint() public { + assertEqUint(uint8(1), uint128(1)); + assertEqUint(uint64(2), uint64(2)); + } + + function testFailAssertEqUint() public { + assertEqUint(uint64(1), uint96(2)); + assertEqUint(uint160(3), uint160(4)); + } + + /*////////////////////////////////////////////////////////////////////////// + APPROX_EQ_ABS(UINT) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertApproxEqAbs_Uint_Pass(uint256 a, uint256 b, uint256 maxDelta) external { + vm.assume(stdMath.delta(a, b) <= maxDelta); + + t._assertApproxEqAbs(a, b, maxDelta, EXPECT_PASS); + } + + function testAssertApproxEqAbs_Uint_Fail(uint256 a, uint256 b, uint256 maxDelta) external { + vm.assume(stdMath.delta(a, b) > maxDelta); + + vm.expectEmit(false, false, false, true); + emit log("Error: a ~= b not satisfied [uint]"); + t._assertApproxEqAbs(a, b, maxDelta, EXPECT_FAIL); + } + + function testAssertApproxEqAbs_UintErr_Pass(uint256 a, uint256 b, uint256 maxDelta) external { + vm.assume(stdMath.delta(a, b) <= maxDelta); + + t._assertApproxEqAbs(a, b, maxDelta, CUSTOM_ERROR, EXPECT_PASS); + } + + function testAssertApproxEqAbs_UintErr_Fail(uint256 a, uint256 b, uint256 maxDelta) external { + vm.assume(stdMath.delta(a, b) > maxDelta); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._assertApproxEqAbs(a, b, maxDelta, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + APPROX_EQ_ABS_DECIMAL(UINT) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertApproxEqAbsDecimal_Uint_Pass(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals) + external + { + vm.assume(stdMath.delta(a, b) <= maxDelta); + + t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, EXPECT_PASS); + } + + function testAssertApproxEqAbsDecimal_Uint_Fail(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals) + external + { + vm.assume(stdMath.delta(a, b) > maxDelta); + + vm.expectEmit(false, false, false, true); + emit log("Error: a ~= b not satisfied [uint]"); + t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, EXPECT_FAIL); + } + + function testAssertApproxEqAbsDecimal_UintErr_Pass(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals) + external + { + vm.assume(stdMath.delta(a, b) <= maxDelta); + + t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, CUSTOM_ERROR, EXPECT_PASS); + } + + function testAssertApproxEqAbsDecimal_UintErr_Fail(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals) + external + { + vm.assume(stdMath.delta(a, b) > maxDelta); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + APPROX_EQ_ABS(INT) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertApproxEqAbs_Int_Pass(int256 a, int256 b, uint256 maxDelta) external { + vm.assume(stdMath.delta(a, b) <= maxDelta); + + t._assertApproxEqAbs(a, b, maxDelta, EXPECT_PASS); + } + + function testAssertApproxEqAbs_Int_Fail(int256 a, int256 b, uint256 maxDelta) external { + vm.assume(stdMath.delta(a, b) > maxDelta); + + vm.expectEmit(false, false, false, true); + emit log("Error: a ~= b not satisfied [int]"); + t._assertApproxEqAbs(a, b, maxDelta, EXPECT_FAIL); + } + + function testAssertApproxEqAbs_IntErr_Pass(int256 a, int256 b, uint256 maxDelta) external { + vm.assume(stdMath.delta(a, b) <= maxDelta); + + t._assertApproxEqAbs(a, b, maxDelta, CUSTOM_ERROR, EXPECT_PASS); + } + + function testAssertApproxEqAbs_IntErr_Fail(int256 a, int256 b, uint256 maxDelta) external { + vm.assume(stdMath.delta(a, b) > maxDelta); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._assertApproxEqAbs(a, b, maxDelta, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + APPROX_EQ_ABS_DECIMAL(INT) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertApproxEqAbsDecimal_Int_Pass(int256 a, int256 b, uint256 maxDelta, uint256 decimals) external { + vm.assume(stdMath.delta(a, b) <= maxDelta); + + t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, EXPECT_PASS); + } + + function testAssertApproxEqAbsDecimal_Int_Fail(int256 a, int256 b, uint256 maxDelta, uint256 decimals) external { + vm.assume(stdMath.delta(a, b) > maxDelta); + + vm.expectEmit(false, false, false, true); + emit log("Error: a ~= b not satisfied [int]"); + t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, EXPECT_FAIL); + } + + function testAssertApproxEqAbsDecimal_IntErr_Pass(int256 a, int256 b, uint256 maxDelta, uint256 decimals) + external + { + vm.assume(stdMath.delta(a, b) <= maxDelta); + + t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, CUSTOM_ERROR, EXPECT_PASS); + } + + function testAssertApproxEqAbsDecimal_IntErr_Fail(int256 a, int256 b, uint256 maxDelta, uint256 decimals) + external + { + vm.assume(stdMath.delta(a, b) > maxDelta); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + APPROX_EQ_REL(UINT) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertApproxEqRel_Uint_Pass(uint256 a, uint256 b, uint256 maxPercentDelta) external { + vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); + vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); + + t._assertApproxEqRel(a, b, maxPercentDelta, EXPECT_PASS); + } + + function testAssertApproxEqRel_Uint_Fail(uint256 a, uint256 b, uint256 maxPercentDelta) external { + vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); + vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); + + vm.expectEmit(false, false, false, true); + emit log("Error: a ~= b not satisfied [uint]"); + t._assertApproxEqRel(a, b, maxPercentDelta, EXPECT_FAIL); + } + + function testAssertApproxEqRel_UintErr_Pass(uint256 a, uint256 b, uint256 maxPercentDelta) external { + vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); + vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); + + t._assertApproxEqRel(a, b, maxPercentDelta, CUSTOM_ERROR, EXPECT_PASS); + } + + function testAssertApproxEqRel_UintErr_Fail(uint256 a, uint256 b, uint256 maxPercentDelta) external { + vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); + vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._assertApproxEqRel(a, b, maxPercentDelta, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + APPROX_EQ_REL_DECIMAL(UINT) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertApproxEqRelDecimal_Uint_Pass(uint256 a, uint256 b, uint256 maxPercentDelta, uint256 decimals) + external + { + vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); + vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); + + t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, EXPECT_PASS); + } + + function testAssertApproxEqRelDecimal_Uint_Fail(uint256 a, uint256 b, uint256 maxPercentDelta, uint256 decimals) + external + { + vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); + vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); + + vm.expectEmit(false, false, false, true); + emit log("Error: a ~= b not satisfied [uint]"); + t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, EXPECT_FAIL); + } + + function testAssertApproxEqRelDecimal_UintErr_Pass(uint256 a, uint256 b, uint256 maxPercentDelta, uint256 decimals) + external + { + vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); + vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); + + t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, CUSTOM_ERROR, EXPECT_PASS); + } + + function testAssertApproxEqRelDecimal_UintErr_Fail(uint256 a, uint256 b, uint256 maxPercentDelta, uint256 decimals) + external + { + vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); + vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + APPROX_EQ_REL(INT) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertApproxEqRel_Int_Pass(int128 a, int128 b, uint128 maxPercentDelta) external { + vm.assume(b != 0); + vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); + + t._assertApproxEqRel(a, b, maxPercentDelta, EXPECT_PASS); + } + + function testAssertApproxEqRel_Int_Fail(int128 a, int128 b, uint128 maxPercentDelta) external { + vm.assume(b != 0); + vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); + + vm.expectEmit(false, false, false, true); + emit log("Error: a ~= b not satisfied [int]"); + t._assertApproxEqRel(a, b, maxPercentDelta, EXPECT_FAIL); + } + + function testAssertApproxEqRel_IntErr_Pass(int128 a, int128 b, uint128 maxPercentDelta) external { + vm.assume(b != 0); + vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); + + t._assertApproxEqRel(a, b, maxPercentDelta, CUSTOM_ERROR, EXPECT_PASS); + } + + function testAssertApproxEqRel_IntErr_Fail(int128 a, int128 b, uint128 maxPercentDelta) external { + vm.assume(b != 0); + vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._assertApproxEqRel(a, b, maxPercentDelta, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + APPROX_EQ_REL_DECIMAL(INT) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertApproxEqRelDecimal_Int_Pass(int128 a, int128 b, uint128 maxPercentDelta, uint128 decimals) + external + { + vm.assume(b != 0); + vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); + + t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, EXPECT_PASS); + } + + function testAssertApproxEqRelDecimal_Int_Fail(int128 a, int128 b, uint128 maxPercentDelta, uint128 decimals) + external + { + vm.assume(b != 0); + vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); + + vm.expectEmit(false, false, false, true); + emit log("Error: a ~= b not satisfied [int]"); + t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, EXPECT_FAIL); + } + + function testAssertApproxEqRelDecimal_IntErr_Pass(int128 a, int128 b, uint128 maxPercentDelta, uint128 decimals) + external + { + vm.assume(b != 0); + vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); + + t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, CUSTOM_ERROR, EXPECT_PASS); + } + + function testAssertApproxEqRelDecimal_IntErr_Fail(int128 a, int128 b, uint128 maxPercentDelta, uint128 decimals) + external + { + vm.assume(b != 0); + vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + ASSERT_EQ_CALL + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertEqCall_Return_Pass( + bytes memory callDataA, + bytes memory callDataB, + bytes memory returnData, + bool strictRevertData + ) external { + address targetA = address(new TestMockCall(returnData, SHOULD_RETURN)); + address targetB = address(new TestMockCall(returnData, SHOULD_RETURN)); + + t._assertEqCall(targetA, callDataA, targetB, callDataB, strictRevertData, EXPECT_PASS); + } + + function testAssertEqCall_Return_Fail( + bytes memory callDataA, + bytes memory callDataB, + bytes memory returnDataA, + bytes memory returnDataB, + bool strictRevertData + ) external { + vm.assume(keccak256(returnDataA) != keccak256(returnDataB)); + + address targetA = address(new TestMockCall(returnDataA, SHOULD_RETURN)); + address targetB = address(new TestMockCall(returnDataB, SHOULD_RETURN)); + + vm.expectEmit(true, true, true, true); + emit log_named_string("Error", "Call return data does not match"); + t._assertEqCall(targetA, callDataA, targetB, callDataB, strictRevertData, EXPECT_FAIL); + } + + function testAssertEqCall_Revert_Pass( + bytes memory callDataA, + bytes memory callDataB, + bytes memory revertDataA, + bytes memory revertDataB + ) external { + address targetA = address(new TestMockCall(revertDataA, SHOULD_REVERT)); + address targetB = address(new TestMockCall(revertDataB, SHOULD_REVERT)); + + t._assertEqCall(targetA, callDataA, targetB, callDataB, NON_STRICT_REVERT_DATA, EXPECT_PASS); + } + + function testAssertEqCall_Revert_Fail( + bytes memory callDataA, + bytes memory callDataB, + bytes memory revertDataA, + bytes memory revertDataB + ) external { + vm.assume(keccak256(revertDataA) != keccak256(revertDataB)); + + address targetA = address(new TestMockCall(revertDataA, SHOULD_REVERT)); + address targetB = address(new TestMockCall(revertDataB, SHOULD_REVERT)); + + vm.expectEmit(true, true, true, true); + emit log_named_string("Error", "Call revert data does not match"); + t._assertEqCall(targetA, callDataA, targetB, callDataB, STRICT_REVERT_DATA, EXPECT_FAIL); + } + + function testAssertEqCall_Fail( + bytes memory callDataA, + bytes memory callDataB, + bytes memory returnDataA, + bytes memory returnDataB, + bool strictRevertData + ) external { + address targetA = address(new TestMockCall(returnDataA, SHOULD_RETURN)); + address targetB = address(new TestMockCall(returnDataB, SHOULD_REVERT)); + + vm.expectEmit(true, true, true, true); + emit log_named_bytes(" Left call return data", returnDataA); + vm.expectEmit(true, true, true, true); + emit log_named_bytes(" Right call revert data", returnDataB); + t._assertEqCall(targetA, callDataA, targetB, callDataB, strictRevertData, EXPECT_FAIL); + + vm.expectEmit(true, true, true, true); + emit log_named_bytes(" Left call revert data", returnDataB); + vm.expectEmit(true, true, true, true); + emit log_named_bytes(" Right call return data", returnDataA); + t._assertEqCall(targetB, callDataB, targetA, callDataA, strictRevertData, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + ASSERT_NOT_EQ(BYTES) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertNotEq_Bytes_Pass(bytes32 a, bytes32 b) external { + vm.assume(a != b); + t._assertNotEq(a, b, EXPECT_PASS); + } + + function testAssertNotEq_Bytes_Fail(bytes32 a) external { + vm.expectEmit(false, false, false, true); + emit log("Error: a != b not satisfied [bytes32]"); + t._assertNotEq(a, a, EXPECT_FAIL); + } + + function testAssertNotEq_BytesErr_Pass(bytes32 a, bytes32 b) external { + vm.assume(a != b); + t._assertNotEq(a, b, CUSTOM_ERROR, EXPECT_PASS); + } + + function testAsserNottEq_BytesErr_Fail(bytes32 a) external { + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._assertNotEq(a, a, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + ASSERT_NOT_EQ(UINT) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertNotEqUint() public { + assertNotEq(uint8(1), uint128(2)); + assertNotEq(uint64(3), uint64(4)); + } + + function testFailAssertNotEqUint() public { + assertNotEq(uint64(1), uint96(1)); + assertNotEq(uint160(2), uint160(2)); + } +} + +contract TestTest is Test { + modifier expectFailure(bool expectFail) { + bool preState = vm.load(HEVM_ADDRESS, bytes32("failed")) != bytes32(0x00); + _; + bool postState = vm.load(HEVM_ADDRESS, bytes32("failed")) != bytes32(0x00); + + if (preState == true) { + return; + } + + if (expectFail) { + require(postState == true, "expected failure not triggered"); + + // unwind the expected failure + vm.store(HEVM_ADDRESS, bytes32("failed"), bytes32(uint256(0x00))); + } else { + require(postState == false, "unexpected failure was triggered"); + } + } + + function _fail(string memory err) external expectFailure(true) { + fail(err); + } + + function _assertFalse(bool data, bool expectFail) external expectFailure(expectFail) { + assertFalse(data); + } + + function _assertFalse(bool data, string memory err, bool expectFail) external expectFailure(expectFail) { + assertFalse(data, err); + } + + function _assertEq(bool a, bool b, bool expectFail) external expectFailure(expectFail) { + assertEq(a, b); + } + + function _assertEq(bool a, bool b, string memory err, bool expectFail) external expectFailure(expectFail) { + assertEq(a, b, err); + } + + function _assertEq(bytes memory a, bytes memory b, bool expectFail) external expectFailure(expectFail) { + assertEq(a, b); + } + + function _assertEq(bytes memory a, bytes memory b, string memory err, bool expectFail) + external + expectFailure(expectFail) + { + assertEq(a, b, err); + } + + function _assertEq(uint256[] memory a, uint256[] memory b, bool expectFail) external expectFailure(expectFail) { + assertEq(a, b); + } + + function _assertEq(int256[] memory a, int256[] memory b, bool expectFail) external expectFailure(expectFail) { + assertEq(a, b); + } + + function _assertEq(address[] memory a, address[] memory b, bool expectFail) external expectFailure(expectFail) { + assertEq(a, b); + } + + function _assertEq(uint256[] memory a, uint256[] memory b, string memory err, bool expectFail) + external + expectFailure(expectFail) + { + assertEq(a, b, err); + } + + function _assertEq(int256[] memory a, int256[] memory b, string memory err, bool expectFail) + external + expectFailure(expectFail) + { + assertEq(a, b, err); + } + + function _assertEq(address[] memory a, address[] memory b, string memory err, bool expectFail) + external + expectFailure(expectFail) + { + assertEq(a, b, err); + } + + function _assertNotEq(bytes32 a, bytes32 b, bool expectFail) external expectFailure(expectFail) { + assertNotEq32(a, b); + } + + function _assertNotEq(bytes32 a, bytes32 b, string memory err, bool expectFail) + external + expectFailure(expectFail) + { + assertNotEq32(a, b, err); + } + + function _assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta, bool expectFail) + external + expectFailure(expectFail) + { + assertApproxEqAbs(a, b, maxDelta); + } + + function _assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta, string memory err, bool expectFail) + external + expectFailure(expectFail) + { + assertApproxEqAbs(a, b, maxDelta, err); + } + + function _assertApproxEqAbsDecimal(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals, bool expectFail) + external + expectFailure(expectFail) + { + assertApproxEqAbsDecimal(a, b, maxDelta, decimals); + } + + function _assertApproxEqAbsDecimal( + uint256 a, + uint256 b, + uint256 maxDelta, + uint256 decimals, + string memory err, + bool expectFail + ) external expectFailure(expectFail) { + assertApproxEqAbsDecimal(a, b, maxDelta, decimals, err); + } + + function _assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta, bool expectFail) + external + expectFailure(expectFail) + { + assertApproxEqAbs(a, b, maxDelta); + } + + function _assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta, string memory err, bool expectFail) + external + expectFailure(expectFail) + { + assertApproxEqAbs(a, b, maxDelta, err); + } + + function _assertApproxEqAbsDecimal(int256 a, int256 b, uint256 maxDelta, uint256 decimals, bool expectFail) + external + expectFailure(expectFail) + { + assertApproxEqAbsDecimal(a, b, maxDelta, decimals); + } + + function _assertApproxEqAbsDecimal( + int256 a, + int256 b, + uint256 maxDelta, + uint256 decimals, + string memory err, + bool expectFail + ) external expectFailure(expectFail) { + assertApproxEqAbsDecimal(a, b, maxDelta, decimals, err); + } + + function _assertApproxEqRel(uint256 a, uint256 b, uint256 maxPercentDelta, bool expectFail) + external + expectFailure(expectFail) + { + assertApproxEqRel(a, b, maxPercentDelta); + } + + function _assertApproxEqRel(uint256 a, uint256 b, uint256 maxPercentDelta, string memory err, bool expectFail) + external + expectFailure(expectFail) + { + assertApproxEqRel(a, b, maxPercentDelta, err); + } + + function _assertApproxEqRelDecimal(uint256 a, uint256 b, uint256 maxPercentDelta, uint256 decimals, bool expectFail) + external + expectFailure(expectFail) + { + assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals); + } + + function _assertApproxEqRelDecimal( + uint256 a, + uint256 b, + uint256 maxPercentDelta, + uint256 decimals, + string memory err, + bool expectFail + ) external expectFailure(expectFail) { + assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, err); + } + + function _assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta, bool expectFail) + external + expectFailure(expectFail) + { + assertApproxEqRel(a, b, maxPercentDelta); + } + + function _assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta, string memory err, bool expectFail) + external + expectFailure(expectFail) + { + assertApproxEqRel(a, b, maxPercentDelta, err); + } + + function _assertApproxEqRelDecimal(int256 a, int256 b, uint256 maxPercentDelta, uint256 decimals, bool expectFail) + external + expectFailure(expectFail) + { + assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals); + } + + function _assertApproxEqRelDecimal( + int256 a, + int256 b, + uint256 maxPercentDelta, + uint256 decimals, + string memory err, + bool expectFail + ) external expectFailure(expectFail) { + assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, err); + } + + function _assertEqCall( + address targetA, + bytes memory callDataA, + address targetB, + bytes memory callDataB, + bool strictRevertData, + bool expectFail + ) external expectFailure(expectFail) { + assertEqCall(targetA, callDataA, targetB, callDataB, strictRevertData); + } +} + +contract TestMockCall { + bytes returnData; + bool shouldRevert; + + constructor(bytes memory returnData_, bool shouldRevert_) { + returnData = returnData_; + shouldRevert = shouldRevert_; + } + + fallback() external payable { + bytes memory returnData_ = returnData; + + if (shouldRevert) { + assembly { + revert(add(returnData_, 0x20), mload(returnData_)) + } + } else { + assembly { + return(add(returnData_, 0x20), mload(returnData_)) + } + } + } +} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/test/StdChains.t.sol b/packages/wallet/wallet-contracts/lib/forge-std/test/StdChains.t.sol new file mode 100644 index 0000000000..f0ede99c8d --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/test/StdChains.t.sol @@ -0,0 +1,160 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import "../src/Test.sol"; + +contract StdChainsTest is Test { + function testChainRpcInitialization() public { + // RPCs specified in `foundry.toml` should be updated. + assertEq(getChain(1).rpcUrl, "https://mainnet.infura.io/v3/b1d3925804e74152b316ca7da97060d3"); + assertEq(getChain("optimism_goerli").rpcUrl, "https://goerli.optimism.io/"); + assertEq(getChain("arbitrum_one_goerli").rpcUrl, "https://goerli-rollup.arbitrum.io/rpc/"); + + // Environment variables should be the next fallback + assertEq(getChain("arbitrum_nova").rpcUrl, "https://nova.arbitrum.io/rpc"); + vm.setEnv("ARBITRUM_NOVA_RPC_URL", "myoverride"); + assertEq(getChain("arbitrum_nova").rpcUrl, "myoverride"); + vm.setEnv("ARBITRUM_NOVA_RPC_URL", "https://nova.arbitrum.io/rpc"); + + // Cannot override RPCs defined in `foundry.toml` + vm.setEnv("MAINNET_RPC_URL", "myoverride2"); + assertEq(getChain("mainnet").rpcUrl, "https://mainnet.infura.io/v3/b1d3925804e74152b316ca7da97060d3"); + + // Other RPCs should remain unchanged. + assertEq(getChain(31337).rpcUrl, "http://127.0.0.1:8545"); + assertEq(getChain("sepolia").rpcUrl, "https://sepolia.infura.io/v3/b9794ad1ddf84dfb8c34d6bb5dca2001"); + } + + function testRpc(string memory rpcAlias) internal { + string memory rpcUrl = getChain(rpcAlias).rpcUrl; + vm.createSelectFork(rpcUrl); + } + + // Ensure we can connect to the default RPC URL for each chain. + // function testRpcs() public { + // testRpc("mainnet"); + // testRpc("goerli"); + // testRpc("sepolia"); + // testRpc("optimism"); + // testRpc("optimism_goerli"); + // testRpc("arbitrum_one"); + // testRpc("arbitrum_one_goerli"); + // testRpc("arbitrum_nova"); + // testRpc("polygon"); + // testRpc("polygon_mumbai"); + // testRpc("avalanche"); + // testRpc("avalanche_fuji"); + // testRpc("bnb_smart_chain"); + // testRpc("bnb_smart_chain_testnet"); + // testRpc("gnosis_chain"); + // } + + function testChainNoDefault() public { + vm.expectRevert("StdChains getChain(string): Chain with alias \"does_not_exist\" not found."); + getChain("does_not_exist"); + } + + function testSetChainFirstFails() public { + vm.expectRevert("StdChains setChain(string,ChainData): Chain ID 31337 already used by \"anvil\"."); + setChain("anvil2", ChainData("Anvil", 31337, "URL")); + } + + function testChainBubbleUp() public { + setChain("needs_undefined_env_var", ChainData("", 123456789, "")); + vm.expectRevert( + "Failed to resolve env var `UNDEFINED_RPC_URL_PLACEHOLDER` in `${UNDEFINED_RPC_URL_PLACEHOLDER}`: environment variable not found" + ); + getChain("needs_undefined_env_var"); + } + + function testCannotSetChain_ChainIdExists() public { + setChain("custom_chain", ChainData("Custom Chain", 123456789, "https://custom.chain/")); + + vm.expectRevert('StdChains setChain(string,ChainData): Chain ID 123456789 already used by "custom_chain".'); + + setChain("another_custom_chain", ChainData("", 123456789, "")); + } + + function testSetChain() public { + setChain("custom_chain", ChainData("Custom Chain", 123456789, "https://custom.chain/")); + Chain memory customChain = getChain("custom_chain"); + assertEq(customChain.name, "Custom Chain"); + assertEq(customChain.chainId, 123456789); + assertEq(customChain.chainAlias, "custom_chain"); + assertEq(customChain.rpcUrl, "https://custom.chain/"); + Chain memory chainById = getChain(123456789); + assertEq(chainById.name, customChain.name); + assertEq(chainById.chainId, customChain.chainId); + assertEq(chainById.chainAlias, customChain.chainAlias); + assertEq(chainById.rpcUrl, customChain.rpcUrl); + customChain.name = "Another Custom Chain"; + customChain.chainId = 987654321; + setChain("another_custom_chain", customChain); + Chain memory anotherCustomChain = getChain("another_custom_chain"); + assertEq(anotherCustomChain.name, "Another Custom Chain"); + assertEq(anotherCustomChain.chainId, 987654321); + assertEq(anotherCustomChain.chainAlias, "another_custom_chain"); + assertEq(anotherCustomChain.rpcUrl, "https://custom.chain/"); + // Verify the first chain data was not overwritten + chainById = getChain(123456789); + assertEq(chainById.name, "Custom Chain"); + assertEq(chainById.chainId, 123456789); + } + + function testSetNoEmptyAlias() public { + vm.expectRevert("StdChains setChain(string,ChainData): Chain alias cannot be the empty string."); + setChain("", ChainData("", 123456789, "")); + } + + function testSetNoChainId0() public { + vm.expectRevert("StdChains setChain(string,ChainData): Chain ID cannot be 0."); + setChain("alias", ChainData("", 0, "")); + } + + function testGetNoChainId0() public { + vm.expectRevert("StdChains getChain(uint256): Chain ID cannot be 0."); + getChain(0); + } + + function testGetNoEmptyAlias() public { + vm.expectRevert("StdChains getChain(string): Chain alias cannot be the empty string."); + getChain(""); + } + + function testChainIdNotFound() public { + vm.expectRevert("StdChains getChain(string): Chain with alias \"no_such_alias\" not found."); + getChain("no_such_alias"); + } + + function testChainAliasNotFound() public { + vm.expectRevert("StdChains getChain(uint256): Chain with ID 321 not found."); + getChain(321); + } + + function testSetChain_ExistingOne() public { + setChain("custom_chain", ChainData("Custom Chain", 123456789, "https://custom.chain/")); + assertEq(getChain(123456789).chainId, 123456789); + + setChain("custom_chain", ChainData("Modified Chain", 999999999, "https://modified.chain/")); + vm.expectRevert("StdChains getChain(uint256): Chain with ID 123456789 not found."); + getChain(123456789); + + Chain memory modifiedChain = getChain(999999999); + assertEq(modifiedChain.name, "Modified Chain"); + assertEq(modifiedChain.chainId, 999999999); + assertEq(modifiedChain.rpcUrl, "https://modified.chain/"); + } + + function testDontUseDefaultRpcUrl() public { + // Should error if default RPCs flag is set to false. + setFallbackToDefaultRpcUrls(false); + vm.expectRevert( + "Failed to get environment variable `ANVIL_RPC_URL` as type `string`: environment variable not found" + ); + getChain(31337); + vm.expectRevert( + "Failed to get environment variable `SEPOLIA_RPC_URL` as type `string`: environment variable not found" + ); + getChain("sepolia"); + } +} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/test/StdCheats.t.sol b/packages/wallet/wallet-contracts/lib/forge-std/test/StdCheats.t.sol new file mode 100644 index 0000000000..36091efa04 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/test/StdCheats.t.sol @@ -0,0 +1,418 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import "../src/StdCheats.sol"; +import "../src/Test.sol"; +import "../src/StdJson.sol"; + +contract StdCheatsTest is Test { + Bar test; + + using stdJson for string; + + function setUp() public { + test = new Bar(); + } + + function testSkip() public { + vm.warp(100); + skip(25); + assertEq(block.timestamp, 125); + } + + function testRewind() public { + vm.warp(100); + rewind(25); + assertEq(block.timestamp, 75); + } + + function testHoax() public { + hoax(address(1337)); + test.bar{value: 100}(address(1337)); + } + + function testHoaxOrigin() public { + hoax(address(1337), address(1337)); + test.origin{value: 100}(address(1337)); + } + + function testHoaxDifferentAddresses() public { + hoax(address(1337), address(7331)); + test.origin{value: 100}(address(1337), address(7331)); + } + + function testStartHoax() public { + startHoax(address(1337)); + test.bar{value: 100}(address(1337)); + test.bar{value: 100}(address(1337)); + vm.stopPrank(); + test.bar(address(this)); + } + + function testStartHoaxOrigin() public { + startHoax(address(1337), address(1337)); + test.origin{value: 100}(address(1337)); + test.origin{value: 100}(address(1337)); + vm.stopPrank(); + test.bar(address(this)); + } + + function testChangePrankMsgSender() public { + vm.startPrank(address(1337)); + test.bar(address(1337)); + changePrank(address(0xdead)); + test.bar(address(0xdead)); + changePrank(address(1337)); + test.bar(address(1337)); + vm.stopPrank(); + } + + function testChangePrankMsgSenderAndTxOrigin() public { + vm.startPrank(address(1337), address(1338)); + test.origin(address(1337), address(1338)); + changePrank(address(0xdead), address(0xbeef)); + test.origin(address(0xdead), address(0xbeef)); + changePrank(address(1337), address(1338)); + test.origin(address(1337), address(1338)); + vm.stopPrank(); + } + + function testMakeAccountEquivalence() public { + Account memory account = makeAccount("1337"); + (address addr, uint256 key) = makeAddrAndKey("1337"); + assertEq(account.addr, addr); + assertEq(account.key, key); + } + + function testMakeAddrEquivalence() public { + (address addr,) = makeAddrAndKey("1337"); + assertEq(makeAddr("1337"), addr); + } + + function testMakeAddrSigning() public { + (address addr, uint256 key) = makeAddrAndKey("1337"); + bytes32 hash = keccak256("some_message"); + + (uint8 v, bytes32 r, bytes32 s) = vm.sign(key, hash); + assertEq(ecrecover(hash, v, r, s), addr); + } + + function testDeal() public { + deal(address(this), 1 ether); + assertEq(address(this).balance, 1 ether); + } + + function testDealToken() public { + Bar barToken = new Bar(); + address bar = address(barToken); + deal(bar, address(this), 10000e18); + assertEq(barToken.balanceOf(address(this)), 10000e18); + } + + function testDealTokenAdjustTotalSupply() public { + Bar barToken = new Bar(); + address bar = address(barToken); + deal(bar, address(this), 10000e18, true); + assertEq(barToken.balanceOf(address(this)), 10000e18); + assertEq(barToken.totalSupply(), 20000e18); + deal(bar, address(this), 0, true); + assertEq(barToken.balanceOf(address(this)), 0); + assertEq(barToken.totalSupply(), 10000e18); + } + + function testDealERC1155Token() public { + BarERC1155 barToken = new BarERC1155(); + address bar = address(barToken); + dealERC1155(bar, address(this), 0, 10000e18, false); + assertEq(barToken.balanceOf(address(this), 0), 10000e18); + } + + function testDealERC1155TokenAdjustTotalSupply() public { + BarERC1155 barToken = new BarERC1155(); + address bar = address(barToken); + dealERC1155(bar, address(this), 0, 10000e18, true); + assertEq(barToken.balanceOf(address(this), 0), 10000e18); + assertEq(barToken.totalSupply(0), 20000e18); + dealERC1155(bar, address(this), 0, 0, true); + assertEq(barToken.balanceOf(address(this), 0), 0); + assertEq(barToken.totalSupply(0), 10000e18); + } + + function testDealERC721Token() public { + BarERC721 barToken = new BarERC721(); + address bar = address(barToken); + dealERC721(bar, address(2), 1); + assertEq(barToken.balanceOf(address(2)), 1); + assertEq(barToken.balanceOf(address(1)), 0); + dealERC721(bar, address(1), 2); + assertEq(barToken.balanceOf(address(1)), 1); + assertEq(barToken.balanceOf(bar), 1); + } + + function testDeployCode() public { + address deployed = deployCode("StdCheats.t.sol:Bar", bytes("")); + assertEq(string(getCode(deployed)), string(getCode(address(test)))); + } + + function testDeployCodeNoArgs() public { + address deployed = deployCode("StdCheats.t.sol:Bar"); + assertEq(string(getCode(deployed)), string(getCode(address(test)))); + } + + function testDeployCodeVal() public { + address deployed = deployCode("StdCheats.t.sol:Bar", bytes(""), 1 ether); + assertEq(string(getCode(deployed)), string(getCode(address(test)))); + assertEq(deployed.balance, 1 ether); + } + + function testDeployCodeValNoArgs() public { + address deployed = deployCode("StdCheats.t.sol:Bar", 1 ether); + assertEq(string(getCode(deployed)), string(getCode(address(test)))); + assertEq(deployed.balance, 1 ether); + } + + // We need this so we can call "this.deployCode" rather than "deployCode" directly + function deployCodeHelper(string memory what) external { + deployCode(what); + } + + function testDeployCodeFail() public { + vm.expectRevert(bytes("StdCheats deployCode(string): Deployment failed.")); + this.deployCodeHelper("StdCheats.t.sol:RevertingContract"); + } + + function getCode(address who) internal view returns (bytes memory o_code) { + /// @solidity memory-safe-assembly + assembly { + // retrieve the size of the code, this needs assembly + let size := extcodesize(who) + // allocate output byte array - this could also be done without assembly + // by using o_code = new bytes(size) + o_code := mload(0x40) + // new "memory end" including padding + mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), not(0x1f)))) + // store length in memory + mstore(o_code, size) + // actually retrieve the code, this needs assembly + extcodecopy(who, add(o_code, 0x20), 0, size) + } + } + + function testDeriveRememberKey() public { + string memory mnemonic = "test test test test test test test test test test test junk"; + + (address deployer, uint256 privateKey) = deriveRememberKey(mnemonic, 0); + assertEq(deployer, 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266); + assertEq(privateKey, 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80); + } + + function testBytesToUint() public { + assertEq(3, bytesToUint_test(hex"03")); + assertEq(2, bytesToUint_test(hex"02")); + assertEq(255, bytesToUint_test(hex"ff")); + assertEq(29625, bytesToUint_test(hex"73b9")); + } + + function testParseJsonTxDetail() public { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); + string memory json = vm.readFile(path); + bytes memory transactionDetails = json.parseRaw(".transactions[0].tx"); + RawTx1559Detail memory rawTxDetail = abi.decode(transactionDetails, (RawTx1559Detail)); + Tx1559Detail memory txDetail = rawToConvertedEIP1559Detail(rawTxDetail); + assertEq(txDetail.from, 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266); + assertEq(txDetail.to, 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512); + assertEq( + txDetail.data, + hex"23e99187000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000013370000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004" + ); + assertEq(txDetail.nonce, 3); + assertEq(txDetail.txType, 2); + assertEq(txDetail.gas, 29625); + assertEq(txDetail.value, 0); + } + + function testReadEIP1559Transaction() public view { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); + uint256 index = 0; + Tx1559 memory transaction = readTx1559(path, index); + transaction; + } + + function testReadEIP1559Transactions() public view { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); + Tx1559[] memory transactions = readTx1559s(path); + transactions; + } + + function testReadReceipt() public { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); + uint256 index = 5; + Receipt memory receipt = readReceipt(path, index); + assertEq( + receipt.logsBloom, + hex"00000000000800000000000000000010000000000000000000000000000180000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100" + ); + } + + function testReadReceipts() public view { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); + Receipt[] memory receipts = readReceipts(path); + receipts; + } + + function testGasMeteringModifier() public { + uint256 gas_start_normal = gasleft(); + addInLoop(); + uint256 gas_used_normal = gas_start_normal - gasleft(); + + uint256 gas_start_single = gasleft(); + addInLoopNoGas(); + uint256 gas_used_single = gas_start_single - gasleft(); + + uint256 gas_start_double = gasleft(); + addInLoopNoGasNoGas(); + uint256 gas_used_double = gas_start_double - gasleft(); + + emit log_named_uint("Normal gas", gas_used_normal); + emit log_named_uint("Single modifier gas", gas_used_single); + emit log_named_uint("Double modifier gas", gas_used_double); + assertTrue(gas_used_double + gas_used_single < gas_used_normal); + } + + function addInLoop() internal pure returns (uint256) { + uint256 b; + for (uint256 i; i < 10000; i++) { + b += i; + } + return b; + } + + function addInLoopNoGas() internal noGasMetering returns (uint256) { + return addInLoop(); + } + + function addInLoopNoGasNoGas() internal noGasMetering returns (uint256) { + return addInLoopNoGas(); + } + + function bytesToUint_test(bytes memory b) private pure returns (uint256) { + uint256 number; + for (uint256 i = 0; i < b.length; i++) { + number = number + uint256(uint8(b[i])) * (2 ** (8 * (b.length - (i + 1)))); + } + return number; + } + + function testAssumeNoPrecompiles(address addr) external { + assumeNoPrecompiles(addr, getChain("optimism_goerli").chainId); + assertTrue( + addr < address(1) || (addr > address(9) && addr < address(0x4200000000000000000000000000000000000000)) + || addr > address(0x4200000000000000000000000000000000000800) + ); + } + + function testAssumePayable() external { + // all should revert since these addresses are not payable + + // VM address + vm.expectRevert(); + assumePayable(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); + + // Console address + vm.expectRevert(); + assumePayable(0x000000000000000000636F6e736F6c652e6c6f67); + + // Create2Deployer + vm.expectRevert(); + assumePayable(0x4e59b44847b379578588920cA78FbF26c0B4956C); + } + + function testAssumePayable(address addr) external { + assumePayable(addr); + assertTrue( + addr != 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D && addr != 0x000000000000000000636F6e736F6c652e6c6f67 + && addr != 0x4e59b44847b379578588920cA78FbF26c0B4956C + ); + } +} + +contract Bar { + constructor() payable { + /// `DEAL` STDCHEAT + totalSupply = 10000e18; + balanceOf[address(this)] = totalSupply; + } + + /// `HOAX` and `CHANGEPRANK` STDCHEATS + function bar(address expectedSender) public payable { + require(msg.sender == expectedSender, "!prank"); + } + + function origin(address expectedSender) public payable { + require(msg.sender == expectedSender, "!prank"); + require(tx.origin == expectedSender, "!prank"); + } + + function origin(address expectedSender, address expectedOrigin) public payable { + require(msg.sender == expectedSender, "!prank"); + require(tx.origin == expectedOrigin, "!prank"); + } + + /// `DEAL` STDCHEAT + mapping(address => uint256) public balanceOf; + uint256 public totalSupply; +} + +contract BarERC1155 { + constructor() payable { + /// `DEALERC1155` STDCHEAT + _totalSupply[0] = 10000e18; + _balances[0][address(this)] = _totalSupply[0]; + } + + function balanceOf(address account, uint256 id) public view virtual returns (uint256) { + return _balances[id][account]; + } + + function totalSupply(uint256 id) public view virtual returns (uint256) { + return _totalSupply[id]; + } + + /// `DEALERC1155` STDCHEAT + mapping(uint256 => mapping(address => uint256)) private _balances; + mapping(uint256 => uint256) private _totalSupply; +} + +contract BarERC721 { + constructor() payable { + /// `DEALERC721` STDCHEAT + _owners[1] = address(1); + _balances[address(1)] = 1; + _owners[2] = address(this); + _owners[3] = address(this); + _balances[address(this)] = 2; + } + + function balanceOf(address owner) public view virtual returns (uint256) { + return _balances[owner]; + } + + function ownerOf(uint256 tokenId) public view virtual returns (address) { + address owner = _owners[tokenId]; + return owner; + } + + mapping(uint256 => address) private _owners; + mapping(address => uint256) private _balances; +} + +contract RevertingContract { + constructor() { + revert(); + } +} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/test/StdError.t.sol b/packages/wallet/wallet-contracts/lib/forge-std/test/StdError.t.sol new file mode 100644 index 0000000000..ccd3eface3 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/test/StdError.t.sol @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0 <0.9.0; + +import "../src/StdError.sol"; +import "../src/Test.sol"; + +contract StdErrorsTest is Test { + ErrorsTest test; + + function setUp() public { + test = new ErrorsTest(); + } + + function testExpectAssertion() public { + vm.expectRevert(stdError.assertionError); + test.assertionError(); + } + + function testExpectArithmetic() public { + vm.expectRevert(stdError.arithmeticError); + test.arithmeticError(10); + } + + function testExpectDiv() public { + vm.expectRevert(stdError.divisionError); + test.divError(0); + } + + function testExpectMod() public { + vm.expectRevert(stdError.divisionError); + test.modError(0); + } + + function testExpectEnum() public { + vm.expectRevert(stdError.enumConversionError); + test.enumConversion(1); + } + + function testExpectEncodeStg() public { + vm.expectRevert(stdError.encodeStorageError); + test.encodeStgError(); + } + + function testExpectPop() public { + vm.expectRevert(stdError.popError); + test.pop(); + } + + function testExpectOOB() public { + vm.expectRevert(stdError.indexOOBError); + test.indexOOBError(1); + } + + function testExpectMem() public { + vm.expectRevert(stdError.memOverflowError); + test.mem(); + } + + function testExpectIntern() public { + vm.expectRevert(stdError.zeroVarError); + test.intern(); + } +} + +contract ErrorsTest { + enum T {T1} + + uint256[] public someArr; + bytes someBytes; + + function assertionError() public pure { + assert(false); + } + + function arithmeticError(uint256 a) public pure { + a -= 100; + } + + function divError(uint256 a) public pure { + 100 / a; + } + + function modError(uint256 a) public pure { + 100 % a; + } + + function enumConversion(uint256 a) public pure { + T(a); + } + + function encodeStgError() public { + /// @solidity memory-safe-assembly + assembly { + sstore(someBytes.slot, 1) + } + keccak256(someBytes); + } + + function pop() public { + someArr.pop(); + } + + function indexOOBError(uint256 a) public pure { + uint256[] memory t = new uint256[](0); + t[a]; + } + + function mem() public pure { + uint256 l = 2 ** 256 / 32; + new uint256[](l); + } + + function intern() public returns (uint256) { + function(uint256) internal returns (uint256) x; + x(2); + return 7; + } +} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/test/StdMath.t.sol b/packages/wallet/wallet-contracts/lib/forge-std/test/StdMath.t.sol new file mode 100644 index 0000000000..95037ea5d4 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/test/StdMath.t.sol @@ -0,0 +1,197 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0 <0.9.0; + +import "../src/StdMath.sol"; +import "../src/Test.sol"; + +contract StdMathTest is Test { + function testGetAbs() external { + assertEq(stdMath.abs(-50), 50); + assertEq(stdMath.abs(50), 50); + assertEq(stdMath.abs(-1337), 1337); + assertEq(stdMath.abs(0), 0); + + assertEq(stdMath.abs(type(int256).min), (type(uint256).max >> 1) + 1); + assertEq(stdMath.abs(type(int256).max), (type(uint256).max >> 1)); + } + + function testGetAbs_Fuzz(int256 a) external { + uint256 manualAbs = getAbs(a); + + uint256 abs = stdMath.abs(a); + + assertEq(abs, manualAbs); + } + + function testGetDelta_Uint() external { + assertEq(stdMath.delta(uint256(0), uint256(0)), 0); + assertEq(stdMath.delta(uint256(0), uint256(1337)), 1337); + assertEq(stdMath.delta(uint256(0), type(uint64).max), type(uint64).max); + assertEq(stdMath.delta(uint256(0), type(uint128).max), type(uint128).max); + assertEq(stdMath.delta(uint256(0), type(uint256).max), type(uint256).max); + + assertEq(stdMath.delta(0, uint256(0)), 0); + assertEq(stdMath.delta(1337, uint256(0)), 1337); + assertEq(stdMath.delta(type(uint64).max, uint256(0)), type(uint64).max); + assertEq(stdMath.delta(type(uint128).max, uint256(0)), type(uint128).max); + assertEq(stdMath.delta(type(uint256).max, uint256(0)), type(uint256).max); + + assertEq(stdMath.delta(1337, uint256(1337)), 0); + assertEq(stdMath.delta(type(uint256).max, type(uint256).max), 0); + assertEq(stdMath.delta(5000, uint256(1250)), 3750); + } + + function testGetDelta_Uint_Fuzz(uint256 a, uint256 b) external { + uint256 manualDelta; + if (a > b) { + manualDelta = a - b; + } else { + manualDelta = b - a; + } + + uint256 delta = stdMath.delta(a, b); + + assertEq(delta, manualDelta); + } + + function testGetDelta_Int() external { + assertEq(stdMath.delta(int256(0), int256(0)), 0); + assertEq(stdMath.delta(int256(0), int256(1337)), 1337); + assertEq(stdMath.delta(int256(0), type(int64).max), type(uint64).max >> 1); + assertEq(stdMath.delta(int256(0), type(int128).max), type(uint128).max >> 1); + assertEq(stdMath.delta(int256(0), type(int256).max), type(uint256).max >> 1); + + assertEq(stdMath.delta(0, int256(0)), 0); + assertEq(stdMath.delta(1337, int256(0)), 1337); + assertEq(stdMath.delta(type(int64).max, int256(0)), type(uint64).max >> 1); + assertEq(stdMath.delta(type(int128).max, int256(0)), type(uint128).max >> 1); + assertEq(stdMath.delta(type(int256).max, int256(0)), type(uint256).max >> 1); + + assertEq(stdMath.delta(-0, int256(0)), 0); + assertEq(stdMath.delta(-1337, int256(0)), 1337); + assertEq(stdMath.delta(type(int64).min, int256(0)), (type(uint64).max >> 1) + 1); + assertEq(stdMath.delta(type(int128).min, int256(0)), (type(uint128).max >> 1) + 1); + assertEq(stdMath.delta(type(int256).min, int256(0)), (type(uint256).max >> 1) + 1); + + assertEq(stdMath.delta(int256(0), -0), 0); + assertEq(stdMath.delta(int256(0), -1337), 1337); + assertEq(stdMath.delta(int256(0), type(int64).min), (type(uint64).max >> 1) + 1); + assertEq(stdMath.delta(int256(0), type(int128).min), (type(uint128).max >> 1) + 1); + assertEq(stdMath.delta(int256(0), type(int256).min), (type(uint256).max >> 1) + 1); + + assertEq(stdMath.delta(1337, int256(1337)), 0); + assertEq(stdMath.delta(type(int256).max, type(int256).max), 0); + assertEq(stdMath.delta(type(int256).min, type(int256).min), 0); + assertEq(stdMath.delta(type(int256).min, type(int256).max), type(uint256).max); + assertEq(stdMath.delta(5000, int256(1250)), 3750); + } + + function testGetDelta_Int_Fuzz(int256 a, int256 b) external { + uint256 absA = getAbs(a); + uint256 absB = getAbs(b); + uint256 absDelta = absA > absB ? absA - absB : absB - absA; + + uint256 manualDelta; + if ((a >= 0 && b >= 0) || (a < 0 && b < 0)) { + manualDelta = absDelta; + } + // (a < 0 && b >= 0) || (a >= 0 && b < 0) + else { + manualDelta = absA + absB; + } + + uint256 delta = stdMath.delta(a, b); + + assertEq(delta, manualDelta); + } + + function testGetPercentDelta_Uint() external { + assertEq(stdMath.percentDelta(uint256(0), uint256(1337)), 1e18); + assertEq(stdMath.percentDelta(uint256(0), type(uint64).max), 1e18); + assertEq(stdMath.percentDelta(uint256(0), type(uint128).max), 1e18); + assertEq(stdMath.percentDelta(uint256(0), type(uint192).max), 1e18); + + assertEq(stdMath.percentDelta(1337, uint256(1337)), 0); + assertEq(stdMath.percentDelta(type(uint192).max, type(uint192).max), 0); + assertEq(stdMath.percentDelta(0, uint256(2500)), 1e18); + assertEq(stdMath.percentDelta(2500, uint256(2500)), 0); + assertEq(stdMath.percentDelta(5000, uint256(2500)), 1e18); + assertEq(stdMath.percentDelta(7500, uint256(2500)), 2e18); + + vm.expectRevert(stdError.divisionError); + stdMath.percentDelta(uint256(1), 0); + } + + function testGetPercentDelta_Uint_Fuzz(uint192 a, uint192 b) external { + vm.assume(b != 0); + uint256 manualDelta; + if (a > b) { + manualDelta = a - b; + } else { + manualDelta = b - a; + } + + uint256 manualPercentDelta = manualDelta * 1e18 / b; + uint256 percentDelta = stdMath.percentDelta(a, b); + + assertEq(percentDelta, manualPercentDelta); + } + + function testGetPercentDelta_Int() external { + assertEq(stdMath.percentDelta(int256(0), int256(1337)), 1e18); + assertEq(stdMath.percentDelta(int256(0), -1337), 1e18); + assertEq(stdMath.percentDelta(int256(0), type(int64).min), 1e18); + assertEq(stdMath.percentDelta(int256(0), type(int128).min), 1e18); + assertEq(stdMath.percentDelta(int256(0), type(int192).min), 1e18); + assertEq(stdMath.percentDelta(int256(0), type(int64).max), 1e18); + assertEq(stdMath.percentDelta(int256(0), type(int128).max), 1e18); + assertEq(stdMath.percentDelta(int256(0), type(int192).max), 1e18); + + assertEq(stdMath.percentDelta(1337, int256(1337)), 0); + assertEq(stdMath.percentDelta(type(int192).max, type(int192).max), 0); + assertEq(stdMath.percentDelta(type(int192).min, type(int192).min), 0); + + assertEq(stdMath.percentDelta(type(int192).min, type(int192).max), 2e18); // rounds the 1 wei diff down + assertEq(stdMath.percentDelta(type(int192).max, type(int192).min), 2e18 - 1); // rounds the 1 wei diff down + assertEq(stdMath.percentDelta(0, int256(2500)), 1e18); + assertEq(stdMath.percentDelta(2500, int256(2500)), 0); + assertEq(stdMath.percentDelta(5000, int256(2500)), 1e18); + assertEq(stdMath.percentDelta(7500, int256(2500)), 2e18); + + vm.expectRevert(stdError.divisionError); + stdMath.percentDelta(int256(1), 0); + } + + function testGetPercentDelta_Int_Fuzz(int192 a, int192 b) external { + vm.assume(b != 0); + uint256 absA = getAbs(a); + uint256 absB = getAbs(b); + uint256 absDelta = absA > absB ? absA - absB : absB - absA; + + uint256 manualDelta; + if ((a >= 0 && b >= 0) || (a < 0 && b < 0)) { + manualDelta = absDelta; + } + // (a < 0 && b >= 0) || (a >= 0 && b < 0) + else { + manualDelta = absA + absB; + } + + uint256 manualPercentDelta = manualDelta * 1e18 / absB; + uint256 percentDelta = stdMath.percentDelta(a, b); + + assertEq(percentDelta, manualPercentDelta); + } + + /*////////////////////////////////////////////////////////////////////////// + HELPERS + //////////////////////////////////////////////////////////////////////////*/ + + function getAbs(int256 a) private pure returns (uint256) { + if (a < 0) { + return a == type(int256).min ? uint256(type(int256).max) + 1 : uint256(-a); + } + + return uint256(a); + } +} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/test/StdStorage.t.sol b/packages/wallet/wallet-contracts/lib/forge-std/test/StdStorage.t.sol new file mode 100644 index 0000000000..d4c563a04b --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/test/StdStorage.t.sol @@ -0,0 +1,283 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import "../src/StdStorage.sol"; +import "../src/Test.sol"; + +contract StdStorageTest is Test { + using stdStorage for StdStorage; + + StorageTest internal test; + + function setUp() public { + test = new StorageTest(); + } + + function testStorageHidden() public { + assertEq(uint256(keccak256("my.random.var")), stdstore.target(address(test)).sig("hidden()").find()); + } + + function testStorageObvious() public { + assertEq(uint256(0), stdstore.target(address(test)).sig("exists()").find()); + } + + function testStorageCheckedWriteHidden() public { + stdstore.target(address(test)).sig(test.hidden.selector).checked_write(100); + assertEq(uint256(test.hidden()), 100); + } + + function testStorageCheckedWriteObvious() public { + stdstore.target(address(test)).sig(test.exists.selector).checked_write(100); + assertEq(test.exists(), 100); + } + + function testStorageMapStructA() public { + uint256 slot = + stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(0).find(); + assertEq(uint256(keccak256(abi.encode(address(this), 4))), slot); + } + + function testStorageMapStructB() public { + uint256 slot = + stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(1).find(); + assertEq(uint256(keccak256(abi.encode(address(this), 4))) + 1, slot); + } + + function testStorageDeepMap() public { + uint256 slot = stdstore.target(address(test)).sig(test.deep_map.selector).with_key(address(this)).with_key( + address(this) + ).find(); + assertEq(uint256(keccak256(abi.encode(address(this), keccak256(abi.encode(address(this), uint256(5)))))), slot); + } + + function testStorageCheckedWriteDeepMap() public { + stdstore.target(address(test)).sig(test.deep_map.selector).with_key(address(this)).with_key(address(this)) + .checked_write(100); + assertEq(100, test.deep_map(address(this), address(this))); + } + + function testStorageDeepMapStructA() public { + uint256 slot = stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)) + .with_key(address(this)).depth(0).find(); + assertEq( + bytes32(uint256(keccak256(abi.encode(address(this), keccak256(abi.encode(address(this), uint256(6)))))) + 0), + bytes32(slot) + ); + } + + function testStorageDeepMapStructB() public { + uint256 slot = stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)) + .with_key(address(this)).depth(1).find(); + assertEq( + bytes32(uint256(keccak256(abi.encode(address(this), keccak256(abi.encode(address(this), uint256(6)))))) + 1), + bytes32(slot) + ); + } + + function testStorageCheckedWriteDeepMapStructA() public { + stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)).with_key( + address(this) + ).depth(0).checked_write(100); + (uint256 a, uint256 b) = test.deep_map_struct(address(this), address(this)); + assertEq(100, a); + assertEq(0, b); + } + + function testStorageCheckedWriteDeepMapStructB() public { + stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)).with_key( + address(this) + ).depth(1).checked_write(100); + (uint256 a, uint256 b) = test.deep_map_struct(address(this), address(this)); + assertEq(0, a); + assertEq(100, b); + } + + function testStorageCheckedWriteMapStructA() public { + stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(0).checked_write(100); + (uint256 a, uint256 b) = test.map_struct(address(this)); + assertEq(a, 100); + assertEq(b, 0); + } + + function testStorageCheckedWriteMapStructB() public { + stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(1).checked_write(100); + (uint256 a, uint256 b) = test.map_struct(address(this)); + assertEq(a, 0); + assertEq(b, 100); + } + + function testStorageStructA() public { + uint256 slot = stdstore.target(address(test)).sig(test.basic.selector).depth(0).find(); + assertEq(uint256(7), slot); + } + + function testStorageStructB() public { + uint256 slot = stdstore.target(address(test)).sig(test.basic.selector).depth(1).find(); + assertEq(uint256(7) + 1, slot); + } + + function testStorageCheckedWriteStructA() public { + stdstore.target(address(test)).sig(test.basic.selector).depth(0).checked_write(100); + (uint256 a, uint256 b) = test.basic(); + assertEq(a, 100); + assertEq(b, 1337); + } + + function testStorageCheckedWriteStructB() public { + stdstore.target(address(test)).sig(test.basic.selector).depth(1).checked_write(100); + (uint256 a, uint256 b) = test.basic(); + assertEq(a, 1337); + assertEq(b, 100); + } + + function testStorageMapAddrFound() public { + uint256 slot = stdstore.target(address(test)).sig(test.map_addr.selector).with_key(address(this)).find(); + assertEq(uint256(keccak256(abi.encode(address(this), uint256(1)))), slot); + } + + function testStorageMapUintFound() public { + uint256 slot = stdstore.target(address(test)).sig(test.map_uint.selector).with_key(100).find(); + assertEq(uint256(keccak256(abi.encode(100, uint256(2)))), slot); + } + + function testStorageCheckedWriteMapUint() public { + stdstore.target(address(test)).sig(test.map_uint.selector).with_key(100).checked_write(100); + assertEq(100, test.map_uint(100)); + } + + function testStorageCheckedWriteMapAddr() public { + stdstore.target(address(test)).sig(test.map_addr.selector).with_key(address(this)).checked_write(100); + assertEq(100, test.map_addr(address(this))); + } + + function testStorageCheckedWriteMapBool() public { + stdstore.target(address(test)).sig(test.map_bool.selector).with_key(address(this)).checked_write(true); + assertTrue(test.map_bool(address(this))); + } + + function testFailStorageCheckedWriteMapPacked() public { + // expect PackedSlot error but not external call so cant expectRevert + stdstore.target(address(test)).sig(test.read_struct_lower.selector).with_key(address(uint160(1337))) + .checked_write(100); + } + + function testStorageCheckedWriteMapPackedSuccess() public { + uint256 full = test.map_packed(address(1337)); + // keep upper 128, set lower 128 to 1337 + full = (full & (uint256((1 << 128) - 1) << 128)) | 1337; + stdstore.target(address(test)).sig(test.map_packed.selector).with_key(address(uint160(1337))).checked_write( + full + ); + assertEq(1337, test.read_struct_lower(address(1337))); + } + + function testFailStorageConst() public { + // vm.expectRevert(abi.encodeWithSignature("NotStorage(bytes4)", bytes4(keccak256("const()")))); + stdstore.target(address(test)).sig("const()").find(); + } + + function testFailStorageNativePack() public { + stdstore.target(address(test)).sig(test.tA.selector).find(); + stdstore.target(address(test)).sig(test.tB.selector).find(); + + // these both would fail + stdstore.target(address(test)).sig(test.tC.selector).find(); + stdstore.target(address(test)).sig(test.tD.selector).find(); + } + + function testStorageReadBytes32() public { + bytes32 val = stdstore.target(address(test)).sig(test.tE.selector).read_bytes32(); + assertEq(val, hex"1337"); + } + + function testStorageReadBool_False() public { + bool val = stdstore.target(address(test)).sig(test.tB.selector).read_bool(); + assertEq(val, false); + } + + function testStorageReadBool_True() public { + bool val = stdstore.target(address(test)).sig(test.tH.selector).read_bool(); + assertEq(val, true); + } + + function testStorageReadBool_Revert() public { + vm.expectRevert("stdStorage read_bool(StdStorage): Cannot decode. Make sure you are reading a bool."); + this.readNonBoolValue(); + } + + function readNonBoolValue() public { + stdstore.target(address(test)).sig(test.tE.selector).read_bool(); + } + + function testStorageReadAddress() public { + address val = stdstore.target(address(test)).sig(test.tF.selector).read_address(); + assertEq(val, address(1337)); + } + + function testStorageReadUint() public { + uint256 val = stdstore.target(address(test)).sig(test.exists.selector).read_uint(); + assertEq(val, 1); + } + + function testStorageReadInt() public { + int256 val = stdstore.target(address(test)).sig(test.tG.selector).read_int(); + assertEq(val, type(int256).min); + } +} + +contract StorageTest { + uint256 public exists = 1; + mapping(address => uint256) public map_addr; + mapping(uint256 => uint256) public map_uint; + mapping(address => uint256) public map_packed; + mapping(address => UnpackedStruct) public map_struct; + mapping(address => mapping(address => uint256)) public deep_map; + mapping(address => mapping(address => UnpackedStruct)) public deep_map_struct; + UnpackedStruct public basic; + + uint248 public tA; + bool public tB; + + bool public tC = false; + uint248 public tD = 1; + + struct UnpackedStruct { + uint256 a; + uint256 b; + } + + mapping(address => bool) public map_bool; + + bytes32 public tE = hex"1337"; + address public tF = address(1337); + int256 public tG = type(int256).min; + bool public tH = true; + + constructor() { + basic = UnpackedStruct({a: 1337, b: 1337}); + + uint256 two = (1 << 128) | 1; + map_packed[msg.sender] = two; + map_packed[address(uint160(1337))] = 1 << 128; + } + + function read_struct_upper(address who) public view returns (uint256) { + return map_packed[who] >> 128; + } + + function read_struct_lower(address who) public view returns (uint256) { + return map_packed[who] & ((1 << 128) - 1); + } + + function hidden() public view returns (bytes32 t) { + bytes32 slot = keccak256("my.random.var"); + /// @solidity memory-safe-assembly + assembly { + t := sload(slot) + } + } + + function const() public pure returns (bytes32 t) { + t = bytes32(hex"1337"); + } +} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/test/StdStyle.t.sol b/packages/wallet/wallet-contracts/lib/forge-std/test/StdStyle.t.sol new file mode 100644 index 0000000000..e63ed68e39 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/test/StdStyle.t.sol @@ -0,0 +1,110 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import "../src/Test.sol"; + +contract StdStyleTest is Test { + function testStyleColor() public view { + console2.log(StdStyle.red("StdStyle.red String Test")); + console2.log(StdStyle.red(uint256(10e18))); + console2.log(StdStyle.red(int256(-10e18))); + console2.log(StdStyle.red(true)); + console2.log(StdStyle.red(address(0))); + console2.log(StdStyle.redBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.redBytes32("StdStyle.redBytes32")); + console2.log(StdStyle.green("StdStyle.green String Test")); + console2.log(StdStyle.green(uint256(10e18))); + console2.log(StdStyle.green(int256(-10e18))); + console2.log(StdStyle.green(true)); + console2.log(StdStyle.green(address(0))); + console2.log(StdStyle.greenBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.greenBytes32("StdStyle.greenBytes32")); + console2.log(StdStyle.yellow("StdStyle.yellow String Test")); + console2.log(StdStyle.yellow(uint256(10e18))); + console2.log(StdStyle.yellow(int256(-10e18))); + console2.log(StdStyle.yellow(true)); + console2.log(StdStyle.yellow(address(0))); + console2.log(StdStyle.yellowBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.yellowBytes32("StdStyle.yellowBytes32")); + console2.log(StdStyle.blue("StdStyle.blue String Test")); + console2.log(StdStyle.blue(uint256(10e18))); + console2.log(StdStyle.blue(int256(-10e18))); + console2.log(StdStyle.blue(true)); + console2.log(StdStyle.blue(address(0))); + console2.log(StdStyle.blueBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.blueBytes32("StdStyle.blueBytes32")); + console2.log(StdStyle.magenta("StdStyle.magenta String Test")); + console2.log(StdStyle.magenta(uint256(10e18))); + console2.log(StdStyle.magenta(int256(-10e18))); + console2.log(StdStyle.magenta(true)); + console2.log(StdStyle.magenta(address(0))); + console2.log(StdStyle.magentaBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.magentaBytes32("StdStyle.magentaBytes32")); + console2.log(StdStyle.cyan("StdStyle.cyan String Test")); + console2.log(StdStyle.cyan(uint256(10e18))); + console2.log(StdStyle.cyan(int256(-10e18))); + console2.log(StdStyle.cyan(true)); + console2.log(StdStyle.cyan(address(0))); + console2.log(StdStyle.cyanBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.cyanBytes32("StdStyle.cyanBytes32")); + } + + function testStyleFontWeight() public view { + console2.log(StdStyle.bold("StdStyle.bold String Test")); + console2.log(StdStyle.bold(uint256(10e18))); + console2.log(StdStyle.bold(int256(-10e18))); + console2.log(StdStyle.bold(address(0))); + console2.log(StdStyle.bold(true)); + console2.log(StdStyle.boldBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.boldBytes32("StdStyle.boldBytes32")); + console2.log(StdStyle.dim("StdStyle.dim String Test")); + console2.log(StdStyle.dim(uint256(10e18))); + console2.log(StdStyle.dim(int256(-10e18))); + console2.log(StdStyle.dim(address(0))); + console2.log(StdStyle.dim(true)); + console2.log(StdStyle.dimBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.dimBytes32("StdStyle.dimBytes32")); + console2.log(StdStyle.italic("StdStyle.italic String Test")); + console2.log(StdStyle.italic(uint256(10e18))); + console2.log(StdStyle.italic(int256(-10e18))); + console2.log(StdStyle.italic(address(0))); + console2.log(StdStyle.italic(true)); + console2.log(StdStyle.italicBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.italicBytes32("StdStyle.italicBytes32")); + console2.log(StdStyle.underline("StdStyle.underline String Test")); + console2.log(StdStyle.underline(uint256(10e18))); + console2.log(StdStyle.underline(int256(-10e18))); + console2.log(StdStyle.underline(address(0))); + console2.log(StdStyle.underline(true)); + console2.log(StdStyle.underlineBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.underlineBytes32("StdStyle.underlineBytes32")); + console2.log(StdStyle.inverse("StdStyle.inverse String Test")); + console2.log(StdStyle.inverse(uint256(10e18))); + console2.log(StdStyle.inverse(int256(-10e18))); + console2.log(StdStyle.inverse(address(0))); + console2.log(StdStyle.inverse(true)); + console2.log(StdStyle.inverseBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.inverseBytes32("StdStyle.inverseBytes32")); + } + + function testStyleCombined() public view { + console2.log(StdStyle.red(StdStyle.bold("Red Bold String Test"))); + console2.log(StdStyle.green(StdStyle.dim(uint256(10e18)))); + console2.log(StdStyle.yellow(StdStyle.italic(int256(-10e18)))); + console2.log(StdStyle.blue(StdStyle.underline(address(0)))); + console2.log(StdStyle.magenta(StdStyle.inverse(true))); + } + + function testStyleCustom() public view { + console2.log(h1("Custom Style 1")); + console2.log(h2("Custom Style 2")); + } + + function h1(string memory a) private pure returns (string memory) { + return StdStyle.cyan(StdStyle.inverse(StdStyle.bold(a))); + } + + function h2(string memory a) private pure returns (string memory) { + return StdStyle.magenta(StdStyle.bold(StdStyle.underline(a))); + } +} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/test/StdUtils.t.sol b/packages/wallet/wallet-contracts/lib/forge-std/test/StdUtils.t.sol new file mode 100644 index 0000000000..a085b19e65 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/test/StdUtils.t.sol @@ -0,0 +1,297 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import "../src/Test.sol"; + +contract StdUtilsMock is StdUtils { + // We deploy a mock version so we can properly test expected reverts. + function getTokenBalances_(address token, address[] memory addresses) + external + returns (uint256[] memory balances) + { + return getTokenBalances(token, addresses); + } +} + +contract StdUtilsTest is Test { + /*////////////////////////////////////////////////////////////////////////// + BOUND UINT + //////////////////////////////////////////////////////////////////////////*/ + + function testBound() public { + assertEq(bound(uint256(5), 0, 4), 0); + assertEq(bound(uint256(0), 69, 69), 69); + assertEq(bound(uint256(0), 68, 69), 68); + assertEq(bound(uint256(10), 150, 190), 174); + assertEq(bound(uint256(300), 2800, 3200), 3107); + assertEq(bound(uint256(9999), 1337, 6666), 4669); + } + + function testBound_WithinRange() public { + assertEq(bound(uint256(51), 50, 150), 51); + assertEq(bound(uint256(51), 50, 150), bound(bound(uint256(51), 50, 150), 50, 150)); + assertEq(bound(uint256(149), 50, 150), 149); + assertEq(bound(uint256(149), 50, 150), bound(bound(uint256(149), 50, 150), 50, 150)); + } + + function testBound_EdgeCoverage() public { + assertEq(bound(uint256(0), 50, 150), 50); + assertEq(bound(uint256(1), 50, 150), 51); + assertEq(bound(uint256(2), 50, 150), 52); + assertEq(bound(uint256(3), 50, 150), 53); + assertEq(bound(type(uint256).max, 50, 150), 150); + assertEq(bound(type(uint256).max - 1, 50, 150), 149); + assertEq(bound(type(uint256).max - 2, 50, 150), 148); + assertEq(bound(type(uint256).max - 3, 50, 150), 147); + } + + function testBound_DistributionIsEven(uint256 min, uint256 size) public { + size = size % 100 + 1; + min = bound(min, UINT256_MAX / 2, UINT256_MAX / 2 + size); + uint256 max = min + size - 1; + uint256 result; + + for (uint256 i = 1; i <= size * 4; ++i) { + // x > max + result = bound(max + i, min, max); + assertEq(result, min + (i - 1) % size); + // x < min + result = bound(min - i, min, max); + assertEq(result, max - (i - 1) % size); + } + } + + function testBound(uint256 num, uint256 min, uint256 max) public { + if (min > max) (min, max) = (max, min); + + uint256 result = bound(num, min, max); + + assertGe(result, min); + assertLe(result, max); + assertEq(result, bound(result, min, max)); + if (num >= min && num <= max) assertEq(result, num); + } + + function testBoundUint256Max() public { + assertEq(bound(0, type(uint256).max - 1, type(uint256).max), type(uint256).max - 1); + assertEq(bound(1, type(uint256).max - 1, type(uint256).max), type(uint256).max); + } + + function testCannotBoundMaxLessThanMin() public { + vm.expectRevert(bytes("StdUtils bound(uint256,uint256,uint256): Max is less than min.")); + bound(uint256(5), 100, 10); + } + + function testCannotBoundMaxLessThanMin(uint256 num, uint256 min, uint256 max) public { + vm.assume(min > max); + vm.expectRevert(bytes("StdUtils bound(uint256,uint256,uint256): Max is less than min.")); + bound(num, min, max); + } + + /*////////////////////////////////////////////////////////////////////////// + BOUND INT + //////////////////////////////////////////////////////////////////////////*/ + + function testBoundInt() public { + assertEq(bound(-3, 0, 4), 2); + assertEq(bound(0, -69, -69), -69); + assertEq(bound(0, -69, -68), -68); + assertEq(bound(-10, 150, 190), 154); + assertEq(bound(-300, 2800, 3200), 2908); + assertEq(bound(9999, -1337, 6666), 1995); + } + + function testBoundInt_WithinRange() public { + assertEq(bound(51, -50, 150), 51); + assertEq(bound(51, -50, 150), bound(bound(51, -50, 150), -50, 150)); + assertEq(bound(149, -50, 150), 149); + assertEq(bound(149, -50, 150), bound(bound(149, -50, 150), -50, 150)); + } + + function testBoundInt_EdgeCoverage() public { + assertEq(bound(type(int256).min, -50, 150), -50); + assertEq(bound(type(int256).min + 1, -50, 150), -49); + assertEq(bound(type(int256).min + 2, -50, 150), -48); + assertEq(bound(type(int256).min + 3, -50, 150), -47); + assertEq(bound(type(int256).min, 10, 150), 10); + assertEq(bound(type(int256).min + 1, 10, 150), 11); + assertEq(bound(type(int256).min + 2, 10, 150), 12); + assertEq(bound(type(int256).min + 3, 10, 150), 13); + + assertEq(bound(type(int256).max, -50, 150), 150); + assertEq(bound(type(int256).max - 1, -50, 150), 149); + assertEq(bound(type(int256).max - 2, -50, 150), 148); + assertEq(bound(type(int256).max - 3, -50, 150), 147); + assertEq(bound(type(int256).max, -50, -10), -10); + assertEq(bound(type(int256).max - 1, -50, -10), -11); + assertEq(bound(type(int256).max - 2, -50, -10), -12); + assertEq(bound(type(int256).max - 3, -50, -10), -13); + } + + function testBoundInt_DistributionIsEven(int256 min, uint256 size) public { + size = size % 100 + 1; + min = bound(min, -int256(size / 2), int256(size - size / 2)); + int256 max = min + int256(size) - 1; + int256 result; + + for (uint256 i = 1; i <= size * 4; ++i) { + // x > max + result = bound(max + int256(i), min, max); + assertEq(result, min + int256((i - 1) % size)); + // x < min + result = bound(min - int256(i), min, max); + assertEq(result, max - int256((i - 1) % size)); + } + } + + function testBoundInt(int256 num, int256 min, int256 max) public { + if (min > max) (min, max) = (max, min); + + int256 result = bound(num, min, max); + + assertGe(result, min); + assertLe(result, max); + assertEq(result, bound(result, min, max)); + if (num >= min && num <= max) assertEq(result, num); + } + + function testBoundIntInt256Max() public { + assertEq(bound(0, type(int256).max - 1, type(int256).max), type(int256).max - 1); + assertEq(bound(1, type(int256).max - 1, type(int256).max), type(int256).max); + } + + function testBoundIntInt256Min() public { + assertEq(bound(0, type(int256).min, type(int256).min + 1), type(int256).min); + assertEq(bound(1, type(int256).min, type(int256).min + 1), type(int256).min + 1); + } + + function testCannotBoundIntMaxLessThanMin() public { + vm.expectRevert(bytes("StdUtils bound(int256,int256,int256): Max is less than min.")); + bound(-5, 100, 10); + } + + function testCannotBoundIntMaxLessThanMin(int256 num, int256 min, int256 max) public { + vm.assume(min > max); + vm.expectRevert(bytes("StdUtils bound(int256,int256,int256): Max is less than min.")); + bound(num, min, max); + } + + /*////////////////////////////////////////////////////////////////////////// + BYTES TO UINT + //////////////////////////////////////////////////////////////////////////*/ + + function testBytesToUint() external { + bytes memory maxUint = hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; + bytes memory two = hex"02"; + bytes memory millionEther = hex"d3c21bcecceda1000000"; + + assertEq(bytesToUint(maxUint), type(uint256).max); + assertEq(bytesToUint(two), 2); + assertEq(bytesToUint(millionEther), 1_000_000 ether); + } + + function testCannotConvertGT32Bytes() external { + bytes memory thirty3Bytes = hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; + vm.expectRevert("StdUtils bytesToUint(bytes): Bytes length exceeds 32."); + bytesToUint(thirty3Bytes); + } + + /*////////////////////////////////////////////////////////////////////////// + COMPUTE CREATE ADDRESS + //////////////////////////////////////////////////////////////////////////*/ + + function testComputeCreateAddress() external { + address deployer = 0x6C9FC64A53c1b71FB3f9Af64d1ae3A4931A5f4E9; + uint256 nonce = 14; + address createAddress = computeCreateAddress(deployer, nonce); + assertEq(createAddress, 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45); + } + + /*////////////////////////////////////////////////////////////////////////// + COMPUTE CREATE2 ADDRESS + //////////////////////////////////////////////////////////////////////////*/ + + function testComputeCreate2Address() external { + bytes32 salt = bytes32(uint256(31415)); + bytes32 initcodeHash = keccak256(abi.encode(0x6080)); + address deployer = 0x6C9FC64A53c1b71FB3f9Af64d1ae3A4931A5f4E9; + address create2Address = computeCreate2Address(salt, initcodeHash, deployer); + assertEq(create2Address, 0xB147a5d25748fda14b463EB04B111027C290f4d3); + } + + function testComputeCreate2AddressWithDefaultDeployer() external { + bytes32 salt = 0xc290c670fde54e5ef686f9132cbc8711e76a98f0333a438a92daa442c71403c0; + bytes32 initcodeHash = hashInitCode(hex"6080", ""); + assertEq(initcodeHash, 0x1a578b7a4b0b5755db6d121b4118d4bc68fe170dca840c59bc922f14175a76b0); + address create2Address = computeCreate2Address(salt, initcodeHash); + assertEq(create2Address, 0xc0ffEe2198a06235aAbFffe5Db0CacF1717f5Ac6); + } +} + +contract StdUtilsForkTest is Test { + /*////////////////////////////////////////////////////////////////////////// + GET TOKEN BALANCES + //////////////////////////////////////////////////////////////////////////*/ + + address internal SHIB = 0x95aD61b0a150d79219dCF64E1E6Cc01f0B64C4cE; + address internal SHIB_HOLDER_0 = 0x855F5981e831D83e6A4b4EBFCAdAa68D92333170; + address internal SHIB_HOLDER_1 = 0x8F509A90c2e47779cA408Fe00d7A72e359229AdA; + address internal SHIB_HOLDER_2 = 0x0e3bbc0D04fF62211F71f3e4C45d82ad76224385; + + address internal USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; + address internal USDC_HOLDER_0 = 0xDa9CE944a37d218c3302F6B82a094844C6ECEb17; + address internal USDC_HOLDER_1 = 0x3e67F4721E6d1c41a015f645eFa37BEd854fcf52; + + function setUp() public { + // All tests of the `getTokenBalances` method are fork tests using live contracts. + vm.createSelectFork({urlOrAlias: "mainnet", blockNumber: 16_428_900}); + } + + function testCannotGetTokenBalances_NonTokenContract() external { + // We deploy a mock version so we can properly test the revert. + StdUtilsMock stdUtils = new StdUtilsMock(); + + // The UniswapV2Factory contract has neither a `balanceOf` function nor a fallback function, + // so the `balanceOf` call should revert. + address token = address(0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f); + address[] memory addresses = new address[](1); + addresses[0] = USDC_HOLDER_0; + + vm.expectRevert("Multicall3: call failed"); + stdUtils.getTokenBalances_(token, addresses); + } + + function testCannotGetTokenBalances_EOA() external { + address eoa = vm.addr({privateKey: 1}); + address[] memory addresses = new address[](1); + addresses[0] = USDC_HOLDER_0; + vm.expectRevert("StdUtils getTokenBalances(address,address[]): Token address is not a contract."); + getTokenBalances(eoa, addresses); + } + + function testGetTokenBalances_Empty() external { + address[] memory addresses = new address[](0); + uint256[] memory balances = getTokenBalances(USDC, addresses); + assertEq(balances.length, 0); + } + + function testGetTokenBalances_USDC() external { + address[] memory addresses = new address[](2); + addresses[0] = USDC_HOLDER_0; + addresses[1] = USDC_HOLDER_1; + uint256[] memory balances = getTokenBalances(USDC, addresses); + assertEq(balances[0], 159_000_000_000_000); + assertEq(balances[1], 131_350_000_000_000); + } + + function testGetTokenBalances_SHIB() external { + address[] memory addresses = new address[](3); + addresses[0] = SHIB_HOLDER_0; + addresses[1] = SHIB_HOLDER_1; + addresses[2] = SHIB_HOLDER_2; + uint256[] memory balances = getTokenBalances(SHIB, addresses); + assertEq(balances[0], 3_323_256_285_484.42e18); + assertEq(balances[1], 1_271_702_771_149.99999928e18); + assertEq(balances[2], 606_357_106_247e18); + } +} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/test/compilation/CompilationScript.sol b/packages/wallet/wallet-contracts/lib/forge-std/test/compilation/CompilationScript.sol new file mode 100644 index 0000000000..e205cfff3c --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/test/compilation/CompilationScript.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +import "../../src/Script.sol"; + +// The purpose of this contract is to benchmark compilation time to avoid accidentally introducing +// a change that results in very long compilation times with via-ir. See https://github.com/foundry-rs/forge-std/issues/207 +contract CompilationScript is Script {} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/test/compilation/CompilationScriptBase.sol b/packages/wallet/wallet-contracts/lib/forge-std/test/compilation/CompilationScriptBase.sol new file mode 100644 index 0000000000..ce8e0e9545 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/test/compilation/CompilationScriptBase.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +import "../../src/Script.sol"; + +// The purpose of this contract is to benchmark compilation time to avoid accidentally introducing +// a change that results in very long compilation times with via-ir. See https://github.com/foundry-rs/forge-std/issues/207 +contract CompilationScriptBase is ScriptBase {} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/test/compilation/CompilationTest.sol b/packages/wallet/wallet-contracts/lib/forge-std/test/compilation/CompilationTest.sol new file mode 100644 index 0000000000..9beeafeb7d --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/test/compilation/CompilationTest.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +import "../../src/Test.sol"; + +// The purpose of this contract is to benchmark compilation time to avoid accidentally introducing +// a change that results in very long compilation times with via-ir. See https://github.com/foundry-rs/forge-std/issues/207 +contract CompilationTest is Test {} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/test/compilation/CompilationTestBase.sol b/packages/wallet/wallet-contracts/lib/forge-std/test/compilation/CompilationTestBase.sol new file mode 100644 index 0000000000..e993535bc0 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/test/compilation/CompilationTestBase.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +import "../../src/Test.sol"; + +// The purpose of this contract is to benchmark compilation time to avoid accidentally introducing +// a change that results in very long compilation times with via-ir. See https://github.com/foundry-rs/forge-std/issues/207 +contract CompilationTestBase is TestBase {} diff --git a/packages/wallet/wallet-contracts/lib/forge-std/test/fixtures/broadcast.log.json b/packages/wallet/wallet-contracts/lib/forge-std/test/fixtures/broadcast.log.json new file mode 100644 index 0000000000..0a0200bca9 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/forge-std/test/fixtures/broadcast.log.json @@ -0,0 +1,187 @@ +{ + "transactions": [ + { + "hash": "0xc6006863c267735a11476b7f15b15bc718e117e2da114a2be815dd651e1a509f", + "type": "CALL", + "contractName": "Test", + "contractAddress": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", + "function": "multiple_arguments(uint256,address,uint256[]):(uint256)", + "arguments": ["1", "0000000000000000000000000000000000001337", "[3,4]"], + "tx": { + "type": "0x02", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", + "gas": "0x73b9", + "value": "0x0", + "data": "0x23e99187000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000013370000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004", + "nonce": "0x3", + "accessList": [] + } + }, + { + "hash": "0xedf2b38d8d896519a947a1acf720f859bb35c0c5ecb8dd7511995b67b9853298", + "type": "CALL", + "contractName": "Test", + "contractAddress": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", + "function": "inc():(uint256)", + "arguments": [], + "tx": { + "type": "0x02", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", + "gas": "0xdcb2", + "value": "0x0", + "data": "0x371303c0", + "nonce": "0x4", + "accessList": [] + } + }, + { + "hash": "0xa57e8e3981a6c861442e46c9471bd19cb3e21f9a8a6c63a72e7b5c47c6675a7c", + "type": "CALL", + "contractName": "Test", + "contractAddress": "0x7c6b4bbe207d642d98d5c537142d85209e585087", + "function": "t(uint256):(uint256)", + "arguments": ["1"], + "tx": { + "type": "0x02", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": "0x7c6b4bbe207d642d98d5c537142d85209e585087", + "gas": "0x8599", + "value": "0x0", + "data": "0xafe29f710000000000000000000000000000000000000000000000000000000000000001", + "nonce": "0x5", + "accessList": [] + } + } + ], + "receipts": [ + { + "transactionHash": "0x481dc86e40bba90403c76f8e144aa9ff04c1da2164299d0298573835f0991181", + "transactionIndex": "0x0", + "blockHash": "0xef0730448490304e5403be0fa8f8ce64f118e9adcca60c07a2ae1ab921d748af", + "blockNumber": "0x1", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": null, + "cumulativeGasUsed": "0x13f3a", + "gasUsed": "0x13f3a", + "contractAddress": "0x5fbdb2315678afecb367f032d93f642f64180aa3", + "logs": [], + "status": "0x1", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "effectiveGasPrice": "0xee6b2800" + }, + { + "transactionHash": "0x6a187183545b8a9e7f1790e847139379bf5622baff2cb43acf3f5c79470af782", + "transactionIndex": "0x0", + "blockHash": "0xf3acb96a90071640c2a8c067ae4e16aad87e634ea8d8bbbb5b352fba86ba0148", + "blockNumber": "0x2", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": null, + "cumulativeGasUsed": "0x45d80", + "gasUsed": "0x45d80", + "contractAddress": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", + "logs": [], + "status": "0x1", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "effectiveGasPrice": "0xee6b2800" + }, + { + "transactionHash": "0x064ad173b4867bdef2fb60060bbdaf01735fbf10414541ea857772974e74ea9d", + "transactionIndex": "0x0", + "blockHash": "0x8373d02109d3ee06a0225f23da4c161c656ccc48fe0fcee931d325508ae73e58", + "blockNumber": "0x3", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": "0x4e59b44847b379578588920ca78fbf26c0b4956c", + "cumulativeGasUsed": "0x45feb", + "gasUsed": "0x45feb", + "contractAddress": null, + "logs": [], + "status": "0x1", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "effectiveGasPrice": "0xee6b2800" + }, + { + "transactionHash": "0xc6006863c267735a11476b7f15b15bc718e117e2da114a2be815dd651e1a509f", + "transactionIndex": "0x0", + "blockHash": "0x16712fae5c0e18f75045f84363fb6b4d9a9fe25e660c4ce286833a533c97f629", + "blockNumber": "0x4", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", + "cumulativeGasUsed": "0x5905", + "gasUsed": "0x5905", + "contractAddress": null, + "logs": [], + "status": "0x1", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "effectiveGasPrice": "0xee6b2800" + }, + { + "transactionHash": "0xedf2b38d8d896519a947a1acf720f859bb35c0c5ecb8dd7511995b67b9853298", + "transactionIndex": "0x0", + "blockHash": "0x156b88c3eb9a1244ba00a1834f3f70de735b39e3e59006dd03af4fe7d5480c11", + "blockNumber": "0x5", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", + "cumulativeGasUsed": "0xa9c4", + "gasUsed": "0xa9c4", + "contractAddress": null, + "logs": [], + "status": "0x1", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "effectiveGasPrice": "0xee6b2800" + }, + { + "transactionHash": "0xa57e8e3981a6c861442e46c9471bd19cb3e21f9a8a6c63a72e7b5c47c6675a7c", + "transactionIndex": "0x0", + "blockHash": "0xcf61faca67dbb2c28952b0b8a379e53b1505ae0821e84779679390cb8571cadb", + "blockNumber": "0x6", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": "0x7c6b4bbe207d642d98d5c537142d85209e585087", + "cumulativeGasUsed": "0x66c5", + "gasUsed": "0x66c5", + "contractAddress": null, + "logs": [ + { + "address": "0x7c6b4bbe207d642d98d5c537142d85209e585087", + "topics": [ + "0x0b2e13ff20ac7b474198655583edf70dedd2c1dc980e329c4fbb2fc0748b796b" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000046865726500000000000000000000000000000000000000000000000000000000", + "blockHash": "0xcf61faca67dbb2c28952b0b8a379e53b1505ae0821e84779679390cb8571cadb", + "blockNumber": "0x6", + "transactionHash": "0xa57e8e3981a6c861442e46c9471bd19cb3e21f9a8a6c63a72e7b5c47c6675a7c", + "transactionIndex": "0x1", + "logIndex": "0x0", + "transactionLogIndex": "0x0", + "removed": false + } + ], + "status": "0x1", + "logsBloom": "0x00000000000800000000000000000010000000000000000000000000000180000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100", + "effectiveGasPrice": "0xee6b2800" + }, + { + "transactionHash": "0x11fbb10230c168ca1e36a7e5c69a6dbcd04fd9e64ede39d10a83e36ee8065c16", + "transactionIndex": "0x0", + "blockHash": "0xf1e0ed2eda4e923626ec74621006ed50b3fc27580dc7b4cf68a07ca77420e29c", + "blockNumber": "0x7", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": "0x0000000000000000000000000000000000001337", + "cumulativeGasUsed": "0x5208", + "gasUsed": "0x5208", + "contractAddress": null, + "logs": [], + "status": "0x1", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "effectiveGasPrice": "0xee6b2800" + } + ], + "libraries": [ + "src/Broadcast.t.sol:F:0x5fbdb2315678afecb367f032d93f642f64180aa3" + ], + "pending": [], + "path": "broadcast/Broadcast.t.sol/31337/run-latest.json", + "returns": {}, + "timestamp": 1655140035 +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/.git-blame-ignore-revs b/packages/wallet/wallet-contracts/lib/foundry-huff/.git-blame-ignore-revs new file mode 100644 index 0000000000..18678bfe43 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/.git-blame-ignore-revs @@ -0,0 +1,2 @@ +# run forge fmt +a41faeb366790c4bda74fef8b70ecda3c285641d diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/.github/workflows/tests.yaml b/packages/wallet/wallet-contracts/lib/foundry-huff/.github/workflows/tests.yaml new file mode 100644 index 0000000000..f92f508253 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/.github/workflows/tests.yaml @@ -0,0 +1,31 @@ +name: Tests + +on: [push] + +jobs: + tests: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + with: + submodules: recursive + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly + + - name: Install Huff + uses: huff-language/huff-toolchain@v2 + with: + version: nightly + + - name: Print the Bytecode for fun + run: huffc -b src/test/contracts/Number.huff + + - name: Print the Scripts + run: ls -lsa lib/foundry-huff/scripts/ + + - name: Run Tests + run: forge test -vvv diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/.gitmodules b/packages/wallet/wallet-contracts/lib/foundry-huff/.gitmodules new file mode 100644 index 0000000000..7d10038b4c --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/.gitmodules @@ -0,0 +1,6 @@ +[submodule "lib/solidity-stringutils"] + path = lib/solidity-stringutils + url = https://github.com/Arachnid/solidity-stringutils +[submodule "lib/forge-std"] + path = lib/forge-std + url = https://github.com/foundry-rs/forge-std diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/LICENSE b/packages/wallet/wallet-contracts/lib/foundry-huff/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/README.md b/packages/wallet/wallet-contracts/lib/foundry-huff/README.md new file mode 100644 index 0000000000..7a461b9119 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/README.md @@ -0,0 +1,167 @@ + + + +# Foundry x Huff + +[![ci](https://github.com/huff-language/huff-rs/actions/workflows/ci.yaml/badge.svg)](https://github.com/huff-language/huff-rs/actions/workflows/ci.yaml) [![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) ![Discord](https://img.shields.io/discord/980519274600882306) + +A [foundry](https://github.com/foundry-rs/foundry) library for working with [huff](https://github.com/huff-language/huff-rs) contracts. Take a look at our [project template](https://github.com/huff-language/huff-project-template) to see an example project that uses this library. + + +## Installing + +First, install the [huff compiler](https://github.com/huff-language/huff-rs) by running: +``` +curl -L get.huff.sh | bash +``` + +Then, install this library with [forge](https://github.com/foundry-rs/foundry): +``` +forge install huff-language/foundry-huff +``` + + +## Usage + +The HuffDeployer is a Solidity library that takes a filename and deploys the corresponding Huff contract, returning the address that the bytecode was deployed to. To use it, simply import it into your file by doing: + +```js +import {HuffDeployer} from "foundry-huff/HuffDeployer.sol"; +``` + +To compile contracts, you can use `HuffDeployer.deploy(string fileName)`, which takes in a single string representing the filename's path relative to the `src` directory. Note that the file ending, i.e. `.huff`, must be omitted. +Here is an example deployment (where the contract is located in [`src/test/contracts/Number.huff`](./src/test/contracts/Number.huff)): + +```solidity +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.7.0 <0.9.0; + +import {HuffDeployer} from "foundry-huff/HuffDeployer"; + +interface Number { + function setNumber(uint256) external; + function getNumber() external returns (uint256); +} + +contract HuffDeployerExample { + function deploy() public { + // Deploy a new instance of src/test/contracts/Number.huff + address addr = HuffDeployer.deploy("test/contracts/Number"); + + // To call a function on the deployed contract, create an interface and wrap the address like so + Number number = Number(addr); + } +} +``` + +To deploy a Huff contract with constructor arguments, you can _chain_ commands onto the HuffDeployer. + +For example, to deploy the contract [`src/test/contracts/Constructor.huff`](src/test/contracts/Constructor.huff) with arguments `(uint256(0x420), uint256(0x420))`, you are encouraged to follow the logic defined in the `deploy` function of the `HuffDeployerArguments` contract below. + +```solidity +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.7.0 <0.9.0; + +import {HuffDeployer} from "foundry-huff/HuffDeployer"; + +interface Constructor { + function getArgOne() external returns (address); + function getArgTwo() external returns (uint256); +} + +contract HuffDeployerArguments { + function deploy() public { + // Deploy the contract with arguments + address addr = HuffDeployer + .config() + .with_args(bytes.concat(abi.encode(uint256(0x420)), abi.encode(uint256(0x420)))) + .deploy("test/contracts/Constructor"); + + // To call a function on the deployed contract, create an interface and wrap the address + Constructor construct = Constructor(addr); + + // Validate we deployed the Constructor with the correct arguments + assert(construct.getArgOne() == address(0x420)); + assert(construct.getArgTwo() == uint256(0x420)); + } + + function depreciated_deploy() public { + address addr = HuffDeployer.deploy_with_args( + "test/contracts/Constructor", + bytes.concat(abi.encode(uint256(0x420)), abi.encode(uint256(0x420))) + ); + + // ... + } +} +``` + +HuffDeployer also enables you to instantiate contracts, from the test file, even if they have _no constructor macro_! + +This is possible by using [Foundry](https://github.com/foundry-rs/foundry)'s [ffi](https://book.getfoundry.sh/cheatcodes/ffi.html) cheatcode. + +_NOTE: It is highly recommended that you read the foundry book, or at least familiarize yourself with foundry, before using this library to avoid easily susceptible footguns._ + +Let's use the huff contract [`src/test/contracts/NoConstructor.huff`](./src/test/contracts/NoConstructor.huff), which has no defined constructor macro. The inline-instantiation defined in the `deploy` function of the `HuffDeployerCode` contract below is recommended. + +```solidity +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.7.0 <0.9.0; + +import {HuffDeployer} from "foundry-huff/HuffDeployer"; + +interface Constructor { + function getArgOne() external returns (address); + function getArgTwo() external returns (uint256); +} + +contract HuffDeployerCode { + + function deploy() public { + // Define a new constructor macro as a string + string memory constructor_macro = "#define macro CONSTRUCTOR() = takes(0) returns (0) {" + " // Copy the first argument into memory \n" + " 0x20 // [size] - byte size to copy \n" + " 0x40 codesize sub // [offset, size] - offset in the code to copy from\n " + " 0x00 // [mem, offset, size] - offset in memory to copy to \n" + " codecopy // [] \n" + " // Store the first argument in storage\n" + " 0x00 mload // [arg] \n" + " [CONSTRUCTOR_ARG_ONE] // [CONSTRUCTOR_ARG_ONE, arg] \n" + " sstore // [] \n" + " // Copy the second argument into memory \n" + " 0x20 // [size] - byte size to copy \n" + " 0x20 codesize sub // [offset, size] - offset in the code to copy from \n" + " 0x00 // [mem, offset, size] - offset in memory to copy to \n" + " codecopy // [] \n" + " // Store the second argument in storage \n" + " 0x00 mload // [arg] \n" + " [CONSTRUCTOR_ARG_TWO] // [CONSTRUCTOR_ARG_TWO, arg] \n" + " sstore // [] \n" + "}"; + + // Deploy the contract with arguments + address addr = HuffDeployer + .config() + .with_args(bytes.concat(abi.encode(uint256(0x420)), abi.encode(uint256(0x420)))) + .with_code(constructor_macro) + .deploy("test/contracts/NoConstructor"); + + // To call a function on the deployed contract, create an interface and wrap the address + Constructor construct = Constructor(addr); + + // Validate we deployed the Constructor with the correct arguments + assert(construct.getArgOne() == address(0x420)); + assert(construct.getArgTwo() == uint256(0x420)); + } + + function depreciated_deploy_with_code() public { + address addr = HuffDeployer.deploy_with_code( + "test/contracts/Constructor", + constructor_macro + ); + + // ... + } +} +``` diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/assets/Group 1.png b/packages/wallet/wallet-contracts/lib/foundry-huff/assets/Group 1.png new file mode 100644 index 0000000000..15a5d9ef6c Binary files /dev/null and b/packages/wallet/wallet-contracts/lib/foundry-huff/assets/Group 1.png differ diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/assets/banner.jpg b/packages/wallet/wallet-contracts/lib/foundry-huff/assets/banner.jpg new file mode 100644 index 0000000000..ce74a95da5 Binary files /dev/null and b/packages/wallet/wallet-contracts/lib/foundry-huff/assets/banner.jpg differ diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/assets/black_white_huff-removebg-preview.png b/packages/wallet/wallet-contracts/lib/foundry-huff/assets/black_white_huff-removebg-preview.png new file mode 100644 index 0000000000..4118c8edc3 Binary files /dev/null and b/packages/wallet/wallet-contracts/lib/foundry-huff/assets/black_white_huff-removebg-preview.png differ diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/assets/black_white_huff.png b/packages/wallet/wallet-contracts/lib/foundry-huff/assets/black_white_huff.png new file mode 100644 index 0000000000..89ecb96150 Binary files /dev/null and b/packages/wallet/wallet-contracts/lib/foundry-huff/assets/black_white_huff.png differ diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/assets/foundry.png b/packages/wallet/wallet-contracts/lib/foundry-huff/assets/foundry.png new file mode 100644 index 0000000000..8e24b87ef6 Binary files /dev/null and b/packages/wallet/wallet-contracts/lib/foundry-huff/assets/foundry.png differ diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/assets/foundry_huff_banner.jpg b/packages/wallet/wallet-contracts/lib/foundry-huff/assets/foundry_huff_banner.jpg new file mode 100644 index 0000000000..b2b7596485 Binary files /dev/null and b/packages/wallet/wallet-contracts/lib/foundry-huff/assets/foundry_huff_banner.jpg differ diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/assets/foundry_huff_banner.png b/packages/wallet/wallet-contracts/lib/foundry-huff/assets/foundry_huff_banner.png new file mode 100644 index 0000000000..4eb243bdf8 Binary files /dev/null and b/packages/wallet/wallet-contracts/lib/foundry-huff/assets/foundry_huff_banner.png differ diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/assets/huff.png b/packages/wallet/wallet-contracts/lib/foundry-huff/assets/huff.png new file mode 100644 index 0000000000..d572798843 Binary files /dev/null and b/packages/wallet/wallet-contracts/lib/foundry-huff/assets/huff.png differ diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/assets/inverted_huff.png b/packages/wallet/wallet-contracts/lib/foundry-huff/assets/inverted_huff.png new file mode 100644 index 0000000000..e3ed658cec Binary files /dev/null and b/packages/wallet/wallet-contracts/lib/foundry-huff/assets/inverted_huff.png differ diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/assets/x-removebg-preview.png b/packages/wallet/wallet-contracts/lib/foundry-huff/assets/x-removebg-preview.png new file mode 100644 index 0000000000..ab40629b63 Binary files /dev/null and b/packages/wallet/wallet-contracts/lib/foundry-huff/assets/x-removebg-preview.png differ diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/assets/x.jpg b/packages/wallet/wallet-contracts/lib/foundry-huff/assets/x.jpg new file mode 100644 index 0000000000..1da702c0d4 Binary files /dev/null and b/packages/wallet/wallet-contracts/lib/foundry-huff/assets/x.jpg differ diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/foundry.toml b/packages/wallet/wallet-contracts/lib/foundry-huff/foundry.toml new file mode 100644 index 0000000000..0d63687ca5 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/foundry.toml @@ -0,0 +1,10 @@ +[profile.default] +src = 'src' +out = 'out' +libs = ['lib'] +ffi = true +fuzz_runs = 2_000 +solc_version = '0.8.20' +evm_version = 'shanghai' +[fmt] +line_length = 100 diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/.github/workflows/ci.yml b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/.github/workflows/ci.yml new file mode 100644 index 0000000000..cb241ae746 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/.github/workflows/ci.yml @@ -0,0 +1,134 @@ +name: CI + +on: + workflow_dispatch: + pull_request: + push: + branches: + - master + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Install Foundry + uses: onbjerg/foundry-toolchain@v1 + with: + version: nightly + + - name: Print forge version + run: forge --version + + # Backwards compatibility checks: + # - the oldest and newest version of each supported minor version + # - versions with specific issues + - name: Check compatibility with latest + if: always() + run: | + output=$(forge build --skip test) + + if echo "$output" | grep -q "Warning"; then + echo "$output" + exit 1 + fi + + - name: Check compatibility with 0.8.0 + if: always() + run: | + output=$(forge build --skip test --use solc:0.8.0) + + if echo "$output" | grep -q "Warning"; then + echo "$output" + exit 1 + fi + + - name: Check compatibility with 0.7.6 + if: always() + run: | + output=$(forge build --skip test --use solc:0.7.6) + + if echo "$output" | grep -q "Warning"; then + echo "$output" + exit 1 + fi + + - name: Check compatibility with 0.7.0 + if: always() + run: | + output=$(forge build --skip test --use solc:0.7.0) + + if echo "$output" | grep -q "Warning"; then + echo "$output" + exit 1 + fi + + - name: Check compatibility with 0.6.12 + if: always() + run: | + output=$(forge build --skip test --use solc:0.6.12) + + if echo "$output" | grep -q "Warning"; then + echo "$output" + exit 1 + fi + + - name: Check compatibility with 0.6.2 + if: always() + run: | + output=$(forge build --skip test --use solc:0.6.2) + + if echo "$output" | grep -q "Warning"; then + echo "$output" + exit 1 + fi + + # via-ir compilation time checks. + - name: Measure compilation time of Test with 0.8.17 --via-ir + if: always() + run: forge build --skip test --contracts test/compilation/CompilationTest.sol --use solc:0.8.17 --via-ir + + - name: Measure compilation time of TestBase with 0.8.17 --via-ir + if: always() + run: forge build --skip test --contracts test/compilation/CompilationTestBase.sol --use solc:0.8.17 --via-ir + + - name: Measure compilation time of Script with 0.8.17 --via-ir + if: always() + run: forge build --skip test --contracts test/compilation/CompilationScript.sol --use solc:0.8.17 --via-ir + + - name: Measure compilation time of ScriptBase with 0.8.17 --via-ir + if: always() + run: forge build --skip test --contracts test/compilation/CompilationScriptBase.sol --use solc:0.8.17 --via-ir + + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Install Foundry + uses: onbjerg/foundry-toolchain@v1 + with: + version: nightly + + - name: Print forge version + run: forge --version + + - name: Run tests + run: forge test -vvv + + fmt: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Install Foundry + uses: onbjerg/foundry-toolchain@v1 + with: + version: nightly + + - name: Print forge version + run: forge --version + + - name: Check formatting + run: forge fmt --check diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/.github/workflows/sync.yml b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/.github/workflows/sync.yml new file mode 100644 index 0000000000..5a9e9d5913 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/.github/workflows/sync.yml @@ -0,0 +1,29 @@ +name: Sync Release Branch + +on: + release: + types: + - created + +jobs: + sync-release-branch: + runs-on: ubuntu-latest + if: startsWith(github.event.release.tag_name, 'v1') + steps: + - name: Check out the repo + uses: actions/checkout@v3 + with: + fetch-depth: 0 + ref: v1 + + - name: Configure Git + run: | + git config user.name github-actions[bot] + git config user.email 41898282+github-actions[bot]@users.noreply.github.com + + - name: Sync Release Branch + run: | + git fetch --tags + git checkout v1 + git reset --hard ${GITHUB_REF} + git push --force diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/.gitmodules b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/.gitmodules new file mode 100644 index 0000000000..e12471968b --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/.gitmodules @@ -0,0 +1,3 @@ +[submodule "lib/ds-test"] + path = lib/ds-test + url = https://github.com/dapphub/ds-test diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/LICENSE-APACHE b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/LICENSE-APACHE new file mode 100644 index 0000000000..cf01a499fb --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/LICENSE-APACHE @@ -0,0 +1,203 @@ +Copyright Contributors to Forge Standard Library + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/LICENSE-MIT b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/LICENSE-MIT new file mode 100644 index 0000000000..28f98304ac --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright Contributors to Forge Standard Library + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE O THE USE OR OTHER +DEALINGS IN THE SOFTWARE.R diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/README.md b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/README.md new file mode 100644 index 0000000000..8494a7dd5e --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/README.md @@ -0,0 +1,250 @@ +# Forge Standard Library • [![CI status](https://github.com/foundry-rs/forge-std/actions/workflows/ci.yml/badge.svg)](https://github.com/foundry-rs/forge-std/actions/workflows/ci.yml) + +Forge Standard Library is a collection of helpful contracts and libraries for use with [Forge and Foundry](https://github.com/foundry-rs/foundry). It leverages Forge's cheatcodes to make writing tests easier and faster, while improving the UX of cheatcodes. + +**Learn how to use Forge-Std with the [šŸ“– Foundry Book (Forge-Std Guide)](https://book.getfoundry.sh/forge/forge-std.html).** + +## Install + +```bash +forge install foundry-rs/forge-std +``` + +## Contracts +### stdError + +This is a helper contract for errors and reverts. In Forge, this contract is particularly helpful for the `expectRevert` cheatcode, as it provides all compiler builtin errors. + +See the contract itself for all error codes. + +#### Example usage + +```solidity + +import "forge-std/Test.sol"; + +contract TestContract is Test { + ErrorsTest test; + + function setUp() public { + test = new ErrorsTest(); + } + + function testExpectArithmetic() public { + vm.expectRevert(stdError.arithmeticError); + test.arithmeticError(10); + } +} + +contract ErrorsTest { + function arithmeticError(uint256 a) public { + uint256 a = a - 100; + } +} +``` + +### stdStorage + +This is a rather large contract due to all of the overloading to make the UX decent. Primarily, it is a wrapper around the `record` and `accesses` cheatcodes. It can *always* find and write the storage slot(s) associated with a particular variable without knowing the storage layout. The one _major_ caveat to this is while a slot can be found for packed storage variables, we can't write to that variable safely. If a user tries to write to a packed slot, the execution throws an error, unless it is uninitialized (`bytes32(0)`). + +This works by recording all `SLOAD`s and `SSTORE`s during a function call. If there is a single slot read or written to, it immediately returns the slot. Otherwise, behind the scenes, we iterate through and check each one (assuming the user passed in a `depth` parameter). If the variable is a struct, you can pass in a `depth` parameter which is basically the field depth. + +I.e.: +```solidity +struct T { + // depth 0 + uint256 a; + // depth 1 + uint256 b; +} +``` + +#### Example usage + +```solidity +import "forge-std/Test.sol"; + +contract TestContract is Test { + using stdStorage for StdStorage; + + Storage test; + + function setUp() public { + test = new Storage(); + } + + function testFindExists() public { + // Lets say we want to find the slot for the public + // variable `exists`. We just pass in the function selector + // to the `find` command + uint256 slot = stdstore.target(address(test)).sig("exists()").find(); + assertEq(slot, 0); + } + + function testWriteExists() public { + // Lets say we want to write to the slot for the public + // variable `exists`. We just pass in the function selector + // to the `checked_write` command + stdstore.target(address(test)).sig("exists()").checked_write(100); + assertEq(test.exists(), 100); + } + + // It supports arbitrary storage layouts, like assembly based storage locations + function testFindHidden() public { + // `hidden` is a random hash of a bytes, iteration through slots would + // not find it. Our mechanism does + // Also, you can use the selector instead of a string + uint256 slot = stdstore.target(address(test)).sig(test.hidden.selector).find(); + assertEq(slot, uint256(keccak256("my.random.var"))); + } + + // If targeting a mapping, you have to pass in the keys necessary to perform the find + // i.e.: + function testFindMapping() public { + uint256 slot = stdstore + .target(address(test)) + .sig(test.map_addr.selector) + .with_key(address(this)) + .find(); + // in the `Storage` constructor, we wrote that this address' value was 1 in the map + // so when we load the slot, we expect it to be 1 + assertEq(uint(vm.load(address(test), bytes32(slot))), 1); + } + + // If the target is a struct, you can specify the field depth: + function testFindStruct() public { + // NOTE: see the depth parameter - 0 means 0th field, 1 means 1st field, etc. + uint256 slot_for_a_field = stdstore + .target(address(test)) + .sig(test.basicStruct.selector) + .depth(0) + .find(); + + uint256 slot_for_b_field = stdstore + .target(address(test)) + .sig(test.basicStruct.selector) + .depth(1) + .find(); + + assertEq(uint(vm.load(address(test), bytes32(slot_for_a_field))), 1); + assertEq(uint(vm.load(address(test), bytes32(slot_for_b_field))), 2); + } +} + +// A complex storage contract +contract Storage { + struct UnpackedStruct { + uint256 a; + uint256 b; + } + + constructor() { + map_addr[msg.sender] = 1; + } + + uint256 public exists = 1; + mapping(address => uint256) public map_addr; + // mapping(address => Packed) public map_packed; + mapping(address => UnpackedStruct) public map_struct; + mapping(address => mapping(address => uint256)) public deep_map; + mapping(address => mapping(address => UnpackedStruct)) public deep_map_struct; + UnpackedStruct public basicStruct = UnpackedStruct({ + a: 1, + b: 2 + }); + + function hidden() public view returns (bytes32 t) { + // an extremely hidden storage slot + bytes32 slot = keccak256("my.random.var"); + assembly { + t := sload(slot) + } + } +} +``` + +### stdCheats + +This is a wrapper over miscellaneous cheatcodes that need wrappers to be more dev friendly. Currently there are only functions related to `prank`. In general, users may expect ETH to be put into an address on `prank`, but this is not the case for safety reasons. Explicitly this `hoax` function should only be used for address that have expected balances as it will get overwritten. If an address already has ETH, you should just use `prank`. If you want to change that balance explicitly, just use `deal`. If you want to do both, `hoax` is also right for you. + + +#### Example usage: +```solidity + +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import "forge-std/Test.sol"; + +// Inherit the stdCheats +contract StdCheatsTest is Test { + Bar test; + function setUp() public { + test = new Bar(); + } + + function testHoax() public { + // we call `hoax`, which gives the target address + // eth and then calls `prank` + hoax(address(1337)); + test.bar{value: 100}(address(1337)); + + // overloaded to allow you to specify how much eth to + // initialize the address with + hoax(address(1337), 1); + test.bar{value: 1}(address(1337)); + } + + function testStartHoax() public { + // we call `startHoax`, which gives the target address + // eth and then calls `startPrank` + // + // it is also overloaded so that you can specify an eth amount + startHoax(address(1337)); + test.bar{value: 100}(address(1337)); + test.bar{value: 100}(address(1337)); + vm.stopPrank(); + test.bar(address(this)); + } +} + +contract Bar { + function bar(address expectedSender) public payable { + require(msg.sender == expectedSender, "!prank"); + } +} +``` + +### Std Assertions + +Expand upon the assertion functions from the `DSTest` library. + +### `console.log` + +Usage follows the same format as [Hardhat](https://hardhat.org/hardhat-network/reference/#console-log). +It's recommended to use `console2.sol` as shown below, as this will show the decoded logs in Forge traces. + +```solidity +// import it indirectly via Test.sol +import "forge-std/Test.sol"; +// or directly import it +import "forge-std/console2.sol"; +... +console2.log(someValue); +``` + +If you need compatibility with Hardhat, you must use the standard `console.sol` instead. +Due to a bug in `console.sol`, logs that use `uint256` or `int256` types will not be properly decoded in Forge traces. + +```solidity +// import it indirectly via Test.sol +import "forge-std/Test.sol"; +// or directly import it +import "forge-std/console.sol"; +... +console.log(someValue); +``` + +## License + +Forge Standard Library is offered under either [MIT](LICENSE-MIT) or [Apache 2.0](LICENSE-APACHE) license. diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/foundry.toml b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/foundry.toml new file mode 100644 index 0000000000..f9679ee61a --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/foundry.toml @@ -0,0 +1,21 @@ +[profile.default] +fs_permissions = [{ access = "read-write", path = "./"}] + +[rpc_endpoints] +# The RPC URLs are modified versions of the default for testing initialization. +mainnet = "https://mainnet.infura.io/v3/b1d3925804e74152b316ca7da97060d3" # Different API key. +optimism_goerli = "https://goerli.optimism.io/" # Adds a trailing slash. +arbitrum_one_goerli = "https://goerli-rollup.arbitrum.io/rpc/" # Adds a trailing slash. +needs_undefined_env_var = "${UNDEFINED_RPC_URL_PLACEHOLDER}" + +[fmt] +# These are all the `forge fmt` defaults. +line_length = 120 +tab_width = 4 +bracket_spacing = false +int_types = 'long' +multiline_func_header = 'attributes_first' +quote_style = 'double' +number_underscore = 'preserve' +single_line_statement_blocks = 'preserve' +ignore = ["src/console.sol", "src/console2.sol"] \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/lib/ds-test/.github/workflows/build.yml b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/lib/ds-test/.github/workflows/build.yml new file mode 100644 index 0000000000..d2ff97db70 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/lib/ds-test/.github/workflows/build.yml @@ -0,0 +1,41 @@ +name: "Build" +on: + pull_request: + push: +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: cachix/install-nix-action@v20 + with: + nix_path: nixpkgs=channel:nixos-unstable + extra_nix_config: | + access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} + + - name: setup dapp binary cache + uses: cachix/cachix-action@v12 + with: + name: dapp + + - name: install dapptools + run: nix profile install github:dapphub/dapptools#dapp --accept-flake-config + + - name: install foundry + uses: foundry-rs/foundry-toolchain@v1 + + - name: test with solc-0.5.17 + run: dapp --use solc-0.5.17 test -v + + - name: test with solc-0.6.11 + run: dapp --use solc-0.6.11 test -v + + - name: test with solc-0.7.6 + run: dapp --use solc-0.7.6 test -v + + - name: test with solc-0.8.18 + run: dapp --use solc-0.8.18 test -v + + - name: Run tests with foundry + run: forge test -vvv + diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/lib/ds-test/LICENSE b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/lib/ds-test/LICENSE new file mode 100644 index 0000000000..94a9ed024d --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/lib/ds-test/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/lib/ds-test/Makefile b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/lib/ds-test/Makefile new file mode 100644 index 0000000000..661dac4868 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/lib/ds-test/Makefile @@ -0,0 +1,14 @@ +all:; dapp build + +test: + -dapp --use solc:0.4.23 build + -dapp --use solc:0.4.26 build + -dapp --use solc:0.5.17 build + -dapp --use solc:0.6.12 build + -dapp --use solc:0.7.5 build + +demo: + DAPP_SRC=demo dapp --use solc:0.7.5 build + -hevm dapp-test --verbose 3 + +.PHONY: test demo diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/lib/ds-test/default.nix b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/lib/ds-test/default.nix new file mode 100644 index 0000000000..cf65419ab4 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/lib/ds-test/default.nix @@ -0,0 +1,4 @@ +{ solidityPackage, dappsys }: solidityPackage { + name = "ds-test"; + src = ./src; +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/lib/ds-test/demo/demo.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/lib/ds-test/demo/demo.sol new file mode 100644 index 0000000000..f3bb48e701 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/lib/ds-test/demo/demo.sol @@ -0,0 +1,222 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity >=0.5.0; + +import "../src/test.sol"; + +contract DemoTest is DSTest { + function test_this() public pure { + require(true); + } + function test_logs() public { + emit log("-- log(string)"); + emit log("a string"); + + emit log("-- log_named_uint(string, uint)"); + emit log_named_uint("uint", 512); + + emit log("-- log_named_int(string, int)"); + emit log_named_int("int", -512); + + emit log("-- log_named_address(string, address)"); + emit log_named_address("address", address(this)); + + emit log("-- log_named_bytes32(string, bytes32)"); + emit log_named_bytes32("bytes32", "a string"); + + emit log("-- log_named_bytes(string, bytes)"); + emit log_named_bytes("bytes", hex"cafefe"); + + emit log("-- log_named_string(string, string)"); + emit log_named_string("string", "a string"); + + emit log("-- log_named_decimal_uint(string, uint, uint)"); + emit log_named_decimal_uint("decimal uint", 1.0e18, 18); + + emit log("-- log_named_decimal_int(string, int, uint)"); + emit log_named_decimal_int("decimal int", -1.0e18, 18); + } + event log_old_named_uint(bytes32,uint); + function test_old_logs() public { + emit log_old_named_uint("key", 500); + emit log_named_bytes32("bkey", "val"); + } + function test_trace() public view { + this.echo("string 1", "string 2"); + } + function test_multiline() public { + emit log("a multiline\\nstring"); + emit log("a multiline string"); + emit log_bytes("a string"); + emit log_bytes("a multiline\nstring"); + emit log_bytes("a multiline\\nstring"); + emit logs(hex"0000"); + emit log_named_bytes("0x0000", hex"0000"); + emit logs(hex"ff"); + } + function echo(string memory s1, string memory s2) public pure + returns (string memory, string memory) + { + return (s1, s2); + } + + function prove_this(uint x) public { + emit log_named_uint("sym x", x); + assertGt(x + 1, 0); + } + + function test_logn() public { + assembly { + log0(0x01, 0x02) + log1(0x01, 0x02, 0x03) + log2(0x01, 0x02, 0x03, 0x04) + log3(0x01, 0x02, 0x03, 0x04, 0x05) + } + } + + event MyEvent(uint, uint indexed, uint, uint indexed); + function test_events() public { + emit MyEvent(1, 2, 3, 4); + } + + function test_asserts() public { + string memory err = "this test has failed!"; + emit log("## assertTrue(bool)\n"); + assertTrue(false); + emit log("\n"); + assertTrue(false, err); + + emit log("\n## assertEq(address,address)\n"); + assertEq(address(this), msg.sender); + emit log("\n"); + assertEq(address(this), msg.sender, err); + + emit log("\n## assertEq32(bytes32,bytes32)\n"); + assertEq32("bytes 1", "bytes 2"); + emit log("\n"); + assertEq32("bytes 1", "bytes 2", err); + + emit log("\n## assertEq(bytes32,bytes32)\n"); + assertEq32("bytes 1", "bytes 2"); + emit log("\n"); + assertEq32("bytes 1", "bytes 2", err); + + emit log("\n## assertEq(uint,uint)\n"); + assertEq(uint(0), 1); + emit log("\n"); + assertEq(uint(0), 1, err); + + emit log("\n## assertEq(int,int)\n"); + assertEq(-1, -2); + emit log("\n"); + assertEq(-1, -2, err); + + emit log("\n## assertEqDecimal(int,int,uint)\n"); + assertEqDecimal(-1.0e18, -1.1e18, 18); + emit log("\n"); + assertEqDecimal(-1.0e18, -1.1e18, 18, err); + + emit log("\n## assertEqDecimal(uint,uint,uint)\n"); + assertEqDecimal(uint(1.0e18), 1.1e18, 18); + emit log("\n"); + assertEqDecimal(uint(1.0e18), 1.1e18, 18, err); + + emit log("\n## assertGt(uint,uint)\n"); + assertGt(uint(0), 0); + emit log("\n"); + assertGt(uint(0), 0, err); + + emit log("\n## assertGt(int,int)\n"); + assertGt(-1, -1); + emit log("\n"); + assertGt(-1, -1, err); + + emit log("\n## assertGtDecimal(int,int,uint)\n"); + assertGtDecimal(-2.0e18, -1.1e18, 18); + emit log("\n"); + assertGtDecimal(-2.0e18, -1.1e18, 18, err); + + emit log("\n## assertGtDecimal(uint,uint,uint)\n"); + assertGtDecimal(uint(1.0e18), 1.1e18, 18); + emit log("\n"); + assertGtDecimal(uint(1.0e18), 1.1e18, 18, err); + + emit log("\n## assertGe(uint,uint)\n"); + assertGe(uint(0), 1); + emit log("\n"); + assertGe(uint(0), 1, err); + + emit log("\n## assertGe(int,int)\n"); + assertGe(-1, 0); + emit log("\n"); + assertGe(-1, 0, err); + + emit log("\n## assertGeDecimal(int,int,uint)\n"); + assertGeDecimal(-2.0e18, -1.1e18, 18); + emit log("\n"); + assertGeDecimal(-2.0e18, -1.1e18, 18, err); + + emit log("\n## assertGeDecimal(uint,uint,uint)\n"); + assertGeDecimal(uint(1.0e18), 1.1e18, 18); + emit log("\n"); + assertGeDecimal(uint(1.0e18), 1.1e18, 18, err); + + emit log("\n## assertLt(uint,uint)\n"); + assertLt(uint(0), 0); + emit log("\n"); + assertLt(uint(0), 0, err); + + emit log("\n## assertLt(int,int)\n"); + assertLt(-1, -1); + emit log("\n"); + assertLt(-1, -1, err); + + emit log("\n## assertLtDecimal(int,int,uint)\n"); + assertLtDecimal(-1.0e18, -1.1e18, 18); + emit log("\n"); + assertLtDecimal(-1.0e18, -1.1e18, 18, err); + + emit log("\n## assertLtDecimal(uint,uint,uint)\n"); + assertLtDecimal(uint(2.0e18), 1.1e18, 18); + emit log("\n"); + assertLtDecimal(uint(2.0e18), 1.1e18, 18, err); + + emit log("\n## assertLe(uint,uint)\n"); + assertLe(uint(1), 0); + emit log("\n"); + assertLe(uint(1), 0, err); + + emit log("\n## assertLe(int,int)\n"); + assertLe(0, -1); + emit log("\n"); + assertLe(0, -1, err); + + emit log("\n## assertLeDecimal(int,int,uint)\n"); + assertLeDecimal(-1.0e18, -1.1e18, 18); + emit log("\n"); + assertLeDecimal(-1.0e18, -1.1e18, 18, err); + + emit log("\n## assertLeDecimal(uint,uint,uint)\n"); + assertLeDecimal(uint(2.0e18), 1.1e18, 18); + emit log("\n"); + assertLeDecimal(uint(2.0e18), 1.1e18, 18, err); + + emit log("\n## assertEq(string,string)\n"); + string memory s1 = "string 1"; + string memory s2 = "string 2"; + assertEq(s1, s2); + emit log("\n"); + assertEq(s1, s2, err); + + emit log("\n## assertEq0(bytes,bytes)\n"); + assertEq0(hex"abcdef01", hex"abcdef02"); + emit log("\n"); + assertEq0(hex"abcdef01", hex"abcdef02", err); + } +} + +contract DemoTestWithSetUp { + function setUp() public { + } + function test_pass() public pure { + } +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/lib/ds-test/package.json b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/lib/ds-test/package.json new file mode 100644 index 0000000000..4802adaa32 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/lib/ds-test/package.json @@ -0,0 +1,15 @@ +{ + "name": "ds-test", + "version": "1.0.0", + "description": "Assertions, equality checks and other test helpers ", + "bugs": "https://github.com/dapphub/ds-test/issues", + "license": "GPL-3.0", + "author": "Contributors to ds-test", + "files": [ + "src/*" + ], + "repository": { + "type": "git", + "url": "https://github.com/dapphub/ds-test.git" + } +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/lib/ds-test/src/test.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/lib/ds-test/src/test.sol new file mode 100644 index 0000000000..2bf337567f --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/lib/ds-test/src/test.sol @@ -0,0 +1,592 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +pragma solidity >=0.5.0; + +contract DSTest { + event log (string); + event logs (bytes); + + event log_address (address); + event log_bytes32 (bytes32); + event log_int (int); + event log_uint (uint); + event log_bytes (bytes); + event log_string (string); + + event log_named_address (string key, address val); + event log_named_bytes32 (string key, bytes32 val); + event log_named_decimal_int (string key, int val, uint decimals); + event log_named_decimal_uint (string key, uint val, uint decimals); + event log_named_int (string key, int val); + event log_named_uint (string key, uint val); + event log_named_bytes (string key, bytes val); + event log_named_string (string key, string val); + + bool public IS_TEST = true; + bool private _failed; + + address constant HEVM_ADDRESS = + address(bytes20(uint160(uint256(keccak256('hevm cheat code'))))); + + modifier mayRevert() { _; } + modifier testopts(string memory) { _; } + + function failed() public returns (bool) { + if (_failed) { + return _failed; + } else { + bool globalFailed = false; + if (hasHEVMContext()) { + (, bytes memory retdata) = HEVM_ADDRESS.call( + abi.encodePacked( + bytes4(keccak256("load(address,bytes32)")), + abi.encode(HEVM_ADDRESS, bytes32("failed")) + ) + ); + globalFailed = abi.decode(retdata, (bool)); + } + return globalFailed; + } + } + + function fail() internal virtual { + if (hasHEVMContext()) { + (bool status, ) = HEVM_ADDRESS.call( + abi.encodePacked( + bytes4(keccak256("store(address,bytes32,bytes32)")), + abi.encode(HEVM_ADDRESS, bytes32("failed"), bytes32(uint256(0x01))) + ) + ); + status; // Silence compiler warnings + } + _failed = true; + } + + function hasHEVMContext() internal view returns (bool) { + uint256 hevmCodeSize = 0; + assembly { + hevmCodeSize := extcodesize(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D) + } + return hevmCodeSize > 0; + } + + modifier logs_gas() { + uint startGas = gasleft(); + _; + uint endGas = gasleft(); + emit log_named_uint("gas", startGas - endGas); + } + + function assertTrue(bool condition) internal { + if (!condition) { + emit log("Error: Assertion Failed"); + fail(); + } + } + + function assertTrue(bool condition, string memory err) internal { + if (!condition) { + emit log_named_string("Error", err); + assertTrue(condition); + } + } + + function assertEq(address a, address b) internal { + if (a != b) { + emit log("Error: a == b not satisfied [address]"); + emit log_named_address(" Left", a); + emit log_named_address(" Right", b); + fail(); + } + } + function assertEq(address a, address b, string memory err) internal { + if (a != b) { + emit log_named_string ("Error", err); + assertEq(a, b); + } + } + + function assertEq(bytes32 a, bytes32 b) internal { + if (a != b) { + emit log("Error: a == b not satisfied [bytes32]"); + emit log_named_bytes32(" Left", a); + emit log_named_bytes32(" Right", b); + fail(); + } + } + function assertEq(bytes32 a, bytes32 b, string memory err) internal { + if (a != b) { + emit log_named_string ("Error", err); + assertEq(a, b); + } + } + function assertEq32(bytes32 a, bytes32 b) internal { + assertEq(a, b); + } + function assertEq32(bytes32 a, bytes32 b, string memory err) internal { + assertEq(a, b, err); + } + + function assertEq(int a, int b) internal { + if (a != b) { + emit log("Error: a == b not satisfied [int]"); + emit log_named_int(" Left", a); + emit log_named_int(" Right", b); + fail(); + } + } + function assertEq(int a, int b, string memory err) internal { + if (a != b) { + emit log_named_string("Error", err); + assertEq(a, b); + } + } + function assertEq(uint a, uint b) internal { + if (a != b) { + emit log("Error: a == b not satisfied [uint]"); + emit log_named_uint(" Left", a); + emit log_named_uint(" Right", b); + fail(); + } + } + function assertEq(uint a, uint b, string memory err) internal { + if (a != b) { + emit log_named_string("Error", err); + assertEq(a, b); + } + } + function assertEqDecimal(int a, int b, uint decimals) internal { + if (a != b) { + emit log("Error: a == b not satisfied [decimal int]"); + emit log_named_decimal_int(" Left", a, decimals); + emit log_named_decimal_int(" Right", b, decimals); + fail(); + } + } + function assertEqDecimal(int a, int b, uint decimals, string memory err) internal { + if (a != b) { + emit log_named_string("Error", err); + assertEqDecimal(a, b, decimals); + } + } + function assertEqDecimal(uint a, uint b, uint decimals) internal { + if (a != b) { + emit log("Error: a == b not satisfied [decimal uint]"); + emit log_named_decimal_uint(" Left", a, decimals); + emit log_named_decimal_uint(" Right", b, decimals); + fail(); + } + } + function assertEqDecimal(uint a, uint b, uint decimals, string memory err) internal { + if (a != b) { + emit log_named_string("Error", err); + assertEqDecimal(a, b, decimals); + } + } + + function assertNotEq(address a, address b) internal { + if (a == b) { + emit log("Error: a != b not satisfied [address]"); + emit log_named_address(" Left", a); + emit log_named_address(" Right", b); + fail(); + } + } + function assertNotEq(address a, address b, string memory err) internal { + if (a == b) { + emit log_named_string ("Error", err); + assertNotEq(a, b); + } + } + + function assertNotEq(bytes32 a, bytes32 b) internal { + if (a == b) { + emit log("Error: a != b not satisfied [bytes32]"); + emit log_named_bytes32(" Left", a); + emit log_named_bytes32(" Right", b); + fail(); + } + } + function assertNotEq(bytes32 a, bytes32 b, string memory err) internal { + if (a == b) { + emit log_named_string ("Error", err); + assertNotEq(a, b); + } + } + function assertNotEq32(bytes32 a, bytes32 b) internal { + assertNotEq(a, b); + } + function assertNotEq32(bytes32 a, bytes32 b, string memory err) internal { + assertNotEq(a, b, err); + } + + function assertNotEq(int a, int b) internal { + if (a == b) { + emit log("Error: a != b not satisfied [int]"); + emit log_named_int(" Left", a); + emit log_named_int(" Right", b); + fail(); + } + } + function assertNotEq(int a, int b, string memory err) internal { + if (a == b) { + emit log_named_string("Error", err); + assertNotEq(a, b); + } + } + function assertNotEq(uint a, uint b) internal { + if (a == b) { + emit log("Error: a != b not satisfied [uint]"); + emit log_named_uint(" Left", a); + emit log_named_uint(" Right", b); + fail(); + } + } + function assertNotEq(uint a, uint b, string memory err) internal { + if (a == b) { + emit log_named_string("Error", err); + assertNotEq(a, b); + } + } + function assertNotEqDecimal(int a, int b, uint decimals) internal { + if (a == b) { + emit log("Error: a != b not satisfied [decimal int]"); + emit log_named_decimal_int(" Left", a, decimals); + emit log_named_decimal_int(" Right", b, decimals); + fail(); + } + } + function assertNotEqDecimal(int a, int b, uint decimals, string memory err) internal { + if (a == b) { + emit log_named_string("Error", err); + assertNotEqDecimal(a, b, decimals); + } + } + function assertNotEqDecimal(uint a, uint b, uint decimals) internal { + if (a == b) { + emit log("Error: a != b not satisfied [decimal uint]"); + emit log_named_decimal_uint(" Left", a, decimals); + emit log_named_decimal_uint(" Right", b, decimals); + fail(); + } + } + function assertNotEqDecimal(uint a, uint b, uint decimals, string memory err) internal { + if (a == b) { + emit log_named_string("Error", err); + assertNotEqDecimal(a, b, decimals); + } + } + + function assertGt(uint a, uint b) internal { + if (a <= b) { + emit log("Error: a > b not satisfied [uint]"); + emit log_named_uint(" Value a", a); + emit log_named_uint(" Value b", b); + fail(); + } + } + function assertGt(uint a, uint b, string memory err) internal { + if (a <= b) { + emit log_named_string("Error", err); + assertGt(a, b); + } + } + function assertGt(int a, int b) internal { + if (a <= b) { + emit log("Error: a > b not satisfied [int]"); + emit log_named_int(" Value a", a); + emit log_named_int(" Value b", b); + fail(); + } + } + function assertGt(int a, int b, string memory err) internal { + if (a <= b) { + emit log_named_string("Error", err); + assertGt(a, b); + } + } + function assertGtDecimal(int a, int b, uint decimals) internal { + if (a <= b) { + emit log("Error: a > b not satisfied [decimal int]"); + emit log_named_decimal_int(" Value a", a, decimals); + emit log_named_decimal_int(" Value b", b, decimals); + fail(); + } + } + function assertGtDecimal(int a, int b, uint decimals, string memory err) internal { + if (a <= b) { + emit log_named_string("Error", err); + assertGtDecimal(a, b, decimals); + } + } + function assertGtDecimal(uint a, uint b, uint decimals) internal { + if (a <= b) { + emit log("Error: a > b not satisfied [decimal uint]"); + emit log_named_decimal_uint(" Value a", a, decimals); + emit log_named_decimal_uint(" Value b", b, decimals); + fail(); + } + } + function assertGtDecimal(uint a, uint b, uint decimals, string memory err) internal { + if (a <= b) { + emit log_named_string("Error", err); + assertGtDecimal(a, b, decimals); + } + } + + function assertGe(uint a, uint b) internal { + if (a < b) { + emit log("Error: a >= b not satisfied [uint]"); + emit log_named_uint(" Value a", a); + emit log_named_uint(" Value b", b); + fail(); + } + } + function assertGe(uint a, uint b, string memory err) internal { + if (a < b) { + emit log_named_string("Error", err); + assertGe(a, b); + } + } + function assertGe(int a, int b) internal { + if (a < b) { + emit log("Error: a >= b not satisfied [int]"); + emit log_named_int(" Value a", a); + emit log_named_int(" Value b", b); + fail(); + } + } + function assertGe(int a, int b, string memory err) internal { + if (a < b) { + emit log_named_string("Error", err); + assertGe(a, b); + } + } + function assertGeDecimal(int a, int b, uint decimals) internal { + if (a < b) { + emit log("Error: a >= b not satisfied [decimal int]"); + emit log_named_decimal_int(" Value a", a, decimals); + emit log_named_decimal_int(" Value b", b, decimals); + fail(); + } + } + function assertGeDecimal(int a, int b, uint decimals, string memory err) internal { + if (a < b) { + emit log_named_string("Error", err); + assertGeDecimal(a, b, decimals); + } + } + function assertGeDecimal(uint a, uint b, uint decimals) internal { + if (a < b) { + emit log("Error: a >= b not satisfied [decimal uint]"); + emit log_named_decimal_uint(" Value a", a, decimals); + emit log_named_decimal_uint(" Value b", b, decimals); + fail(); + } + } + function assertGeDecimal(uint a, uint b, uint decimals, string memory err) internal { + if (a < b) { + emit log_named_string("Error", err); + assertGeDecimal(a, b, decimals); + } + } + + function assertLt(uint a, uint b) internal { + if (a >= b) { + emit log("Error: a < b not satisfied [uint]"); + emit log_named_uint(" Value a", a); + emit log_named_uint(" Value b", b); + fail(); + } + } + function assertLt(uint a, uint b, string memory err) internal { + if (a >= b) { + emit log_named_string("Error", err); + assertLt(a, b); + } + } + function assertLt(int a, int b) internal { + if (a >= b) { + emit log("Error: a < b not satisfied [int]"); + emit log_named_int(" Value a", a); + emit log_named_int(" Value b", b); + fail(); + } + } + function assertLt(int a, int b, string memory err) internal { + if (a >= b) { + emit log_named_string("Error", err); + assertLt(a, b); + } + } + function assertLtDecimal(int a, int b, uint decimals) internal { + if (a >= b) { + emit log("Error: a < b not satisfied [decimal int]"); + emit log_named_decimal_int(" Value a", a, decimals); + emit log_named_decimal_int(" Value b", b, decimals); + fail(); + } + } + function assertLtDecimal(int a, int b, uint decimals, string memory err) internal { + if (a >= b) { + emit log_named_string("Error", err); + assertLtDecimal(a, b, decimals); + } + } + function assertLtDecimal(uint a, uint b, uint decimals) internal { + if (a >= b) { + emit log("Error: a < b not satisfied [decimal uint]"); + emit log_named_decimal_uint(" Value a", a, decimals); + emit log_named_decimal_uint(" Value b", b, decimals); + fail(); + } + } + function assertLtDecimal(uint a, uint b, uint decimals, string memory err) internal { + if (a >= b) { + emit log_named_string("Error", err); + assertLtDecimal(a, b, decimals); + } + } + + function assertLe(uint a, uint b) internal { + if (a > b) { + emit log("Error: a <= b not satisfied [uint]"); + emit log_named_uint(" Value a", a); + emit log_named_uint(" Value b", b); + fail(); + } + } + function assertLe(uint a, uint b, string memory err) internal { + if (a > b) { + emit log_named_string("Error", err); + assertLe(a, b); + } + } + function assertLe(int a, int b) internal { + if (a > b) { + emit log("Error: a <= b not satisfied [int]"); + emit log_named_int(" Value a", a); + emit log_named_int(" Value b", b); + fail(); + } + } + function assertLe(int a, int b, string memory err) internal { + if (a > b) { + emit log_named_string("Error", err); + assertLe(a, b); + } + } + function assertLeDecimal(int a, int b, uint decimals) internal { + if (a > b) { + emit log("Error: a <= b not satisfied [decimal int]"); + emit log_named_decimal_int(" Value a", a, decimals); + emit log_named_decimal_int(" Value b", b, decimals); + fail(); + } + } + function assertLeDecimal(int a, int b, uint decimals, string memory err) internal { + if (a > b) { + emit log_named_string("Error", err); + assertLeDecimal(a, b, decimals); + } + } + function assertLeDecimal(uint a, uint b, uint decimals) internal { + if (a > b) { + emit log("Error: a <= b not satisfied [decimal uint]"); + emit log_named_decimal_uint(" Value a", a, decimals); + emit log_named_decimal_uint(" Value b", b, decimals); + fail(); + } + } + function assertLeDecimal(uint a, uint b, uint decimals, string memory err) internal { + if (a > b) { + emit log_named_string("Error", err); + assertLeDecimal(a, b, decimals); + } + } + + function assertEq(string memory a, string memory b) internal { + if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) { + emit log("Error: a == b not satisfied [string]"); + emit log_named_string(" Left", a); + emit log_named_string(" Right", b); + fail(); + } + } + function assertEq(string memory a, string memory b, string memory err) internal { + if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) { + emit log_named_string("Error", err); + assertEq(a, b); + } + } + + function assertNotEq(string memory a, string memory b) internal { + if (keccak256(abi.encodePacked(a)) == keccak256(abi.encodePacked(b))) { + emit log("Error: a != b not satisfied [string]"); + emit log_named_string(" Left", a); + emit log_named_string(" Right", b); + fail(); + } + } + function assertNotEq(string memory a, string memory b, string memory err) internal { + if (keccak256(abi.encodePacked(a)) == keccak256(abi.encodePacked(b))) { + emit log_named_string("Error", err); + assertNotEq(a, b); + } + } + + function checkEq0(bytes memory a, bytes memory b) internal pure returns (bool ok) { + ok = true; + if (a.length == b.length) { + for (uint i = 0; i < a.length; i++) { + if (a[i] != b[i]) { + ok = false; + } + } + } else { + ok = false; + } + } + function assertEq0(bytes memory a, bytes memory b) internal { + if (!checkEq0(a, b)) { + emit log("Error: a == b not satisfied [bytes]"); + emit log_named_bytes(" Left", a); + emit log_named_bytes(" Right", b); + fail(); + } + } + function assertEq0(bytes memory a, bytes memory b, string memory err) internal { + if (!checkEq0(a, b)) { + emit log_named_string("Error", err); + assertEq0(a, b); + } + } + + function assertNotEq0(bytes memory a, bytes memory b) internal { + if (checkEq0(a, b)) { + emit log("Error: a != b not satisfied [bytes]"); + emit log_named_bytes(" Left", a); + emit log_named_bytes(" Right", b); + fail(); + } + } + function assertNotEq0(bytes memory a, bytes memory b, string memory err) internal { + if (checkEq0(a, b)) { + emit log_named_string("Error", err); + assertNotEq0(a, b); + } + } +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/lib/ds-test/src/test.t.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/lib/ds-test/src/test.t.sol new file mode 100644 index 0000000000..d277a30945 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/lib/ds-test/src/test.t.sol @@ -0,0 +1,417 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity >=0.5.0; + +import {DSTest} from "./test.sol"; + +contract DemoTest is DSTest { + + // --- assertTrue --- + + function testAssertTrue() public { + assertTrue(true, "msg"); + assertTrue(true); + } + function testFailAssertTrue() public { + assertTrue(false); + } + function testFailAssertTrueWithMsg() public { + assertTrue(false, "msg"); + } + + // --- assertEq (Addr) --- + + function testAssertEqAddr() public { + assertEq(address(0x0), address(0x0), "msg"); + assertEq(address(0x0), address(0x0)); + } + function testFailAssertEqAddr() public { + assertEq(address(0x0), address(0x1)); + } + function testFailAssertEqAddrWithMsg() public { + assertEq(address(0x0), address(0x1), "msg"); + } + + // --- assertEq (Bytes32) --- + + function testAssertEqBytes32() public { + assertEq(bytes32("hi"), bytes32("hi"), "msg"); + assertEq(bytes32("hi"), bytes32("hi")); + } + function testFailAssertEqBytes32() public { + assertEq(bytes32("hi"), bytes32("ho")); + } + function testFailAssertEqBytes32WithMsg() public { + assertEq(bytes32("hi"), bytes32("ho"), "msg"); + } + + // --- assertEq (Int) --- + + function testAssertEqInt() public { + assertEq(-1, -1, "msg"); + assertEq(-1, -1); + } + function testFailAssertEqInt() public { + assertEq(-1, -2); + } + function testFailAssertEqIntWithMsg() public { + assertEq(-1, -2, "msg"); + } + + // --- assertEq (UInt) --- + + function testAssertEqUInt() public { + assertEq(uint(1), uint(1), "msg"); + assertEq(uint(1), uint(1)); + } + function testFailAssertEqUInt() public { + assertEq(uint(1), uint(2)); + } + function testFailAssertEqUIntWithMsg() public { + assertEq(uint(1), uint(2), "msg"); + } + + // --- assertEqDecimal (Int) --- + + function testAssertEqDecimalInt() public { + assertEqDecimal(-1, -1, 18, "msg"); + assertEqDecimal(-1, -1, 18); + } + function testFailAssertEqDecimalInt() public { + assertEqDecimal(-1, -2, 18); + } + function testFailAssertEqDecimalIntWithMsg() public { + assertEqDecimal(-1, -2, 18, "msg"); + } + + // --- assertEqDecimal (UInt) --- + + function testAssertEqDecimalUInt() public { + assertEqDecimal(uint(1), uint(1), 18, "msg"); + assertEqDecimal(uint(1), uint(1), 18); + } + function testFailAssertEqDecimalUInt() public { + assertEqDecimal(uint(1), uint(2), 18); + } + function testFailAssertEqDecimalUIntWithMsg() public { + assertEqDecimal(uint(1), uint(2), 18, "msg"); + } + + // --- assertNotEq (Addr) --- + + function testAssertNotEqAddr() public { + assertNotEq(address(0x0), address(0x1), "msg"); + assertNotEq(address(0x0), address(0x1)); + } + function testFailAssertNotEqAddr() public { + assertNotEq(address(0x0), address(0x0)); + } + function testFailAssertNotEqAddrWithMsg() public { + assertNotEq(address(0x0), address(0x0), "msg"); + } + + // --- assertNotEq (Bytes32) --- + + function testAssertNotEqBytes32() public { + assertNotEq(bytes32("hi"), bytes32("ho"), "msg"); + assertNotEq(bytes32("hi"), bytes32("ho")); + } + function testFailAssertNotEqBytes32() public { + assertNotEq(bytes32("hi"), bytes32("hi")); + } + function testFailAssertNotEqBytes32WithMsg() public { + assertNotEq(bytes32("hi"), bytes32("hi"), "msg"); + } + + // --- assertNotEq (Int) --- + + function testAssertNotEqInt() public { + assertNotEq(-1, -2, "msg"); + assertNotEq(-1, -2); + } + function testFailAssertNotEqInt() public { + assertNotEq(-1, -1); + } + function testFailAssertNotEqIntWithMsg() public { + assertNotEq(-1, -1, "msg"); + } + + // --- assertNotEq (UInt) --- + + function testAssertNotEqUInt() public { + assertNotEq(uint(1), uint(2), "msg"); + assertNotEq(uint(1), uint(2)); + } + function testFailAssertNotEqUInt() public { + assertNotEq(uint(1), uint(1)); + } + function testFailAssertNotEqUIntWithMsg() public { + assertNotEq(uint(1), uint(1), "msg"); + } + + // --- assertNotEqDecimal (Int) --- + + function testAssertNotEqDecimalInt() public { + assertNotEqDecimal(-1, -2, 18, "msg"); + assertNotEqDecimal(-1, -2, 18); + } + function testFailAssertNotEqDecimalInt() public { + assertNotEqDecimal(-1, -1, 18); + } + function testFailAssertNotEqDecimalIntWithMsg() public { + assertNotEqDecimal(-1, -1, 18, "msg"); + } + + // --- assertNotEqDecimal (UInt) --- + + function testAssertNotEqDecimalUInt() public { + assertNotEqDecimal(uint(1), uint(2), 18, "msg"); + assertNotEqDecimal(uint(1), uint(2), 18); + } + function testFailAssertNotEqDecimalUInt() public { + assertNotEqDecimal(uint(1), uint(1), 18); + } + function testFailAssertNotEqDecimalUIntWithMsg() public { + assertNotEqDecimal(uint(1), uint(1), 18, "msg"); + } + + // --- assertGt (UInt) --- + + function testAssertGtUInt() public { + assertGt(uint(2), uint(1), "msg"); + assertGt(uint(3), uint(2)); + } + function testFailAssertGtUInt() public { + assertGt(uint(1), uint(2)); + } + function testFailAssertGtUIntWithMsg() public { + assertGt(uint(1), uint(2), "msg"); + } + + // --- assertGt (Int) --- + + function testAssertGtInt() public { + assertGt(-1, -2, "msg"); + assertGt(-1, -3); + } + function testFailAssertGtInt() public { + assertGt(-2, -1); + } + function testFailAssertGtIntWithMsg() public { + assertGt(-2, -1, "msg"); + } + + // --- assertGtDecimal (UInt) --- + + function testAssertGtDecimalUInt() public { + assertGtDecimal(uint(2), uint(1), 18, "msg"); + assertGtDecimal(uint(3), uint(2), 18); + } + function testFailAssertGtDecimalUInt() public { + assertGtDecimal(uint(1), uint(2), 18); + } + function testFailAssertGtDecimalUIntWithMsg() public { + assertGtDecimal(uint(1), uint(2), 18, "msg"); + } + + // --- assertGtDecimal (Int) --- + + function testAssertGtDecimalInt() public { + assertGtDecimal(-1, -2, 18, "msg"); + assertGtDecimal(-1, -3, 18); + } + function testFailAssertGtDecimalInt() public { + assertGtDecimal(-2, -1, 18); + } + function testFailAssertGtDecimalIntWithMsg() public { + assertGtDecimal(-2, -1, 18, "msg"); + } + + // --- assertGe (UInt) --- + + function testAssertGeUInt() public { + assertGe(uint(2), uint(1), "msg"); + assertGe(uint(2), uint(2)); + } + function testFailAssertGeUInt() public { + assertGe(uint(1), uint(2)); + } + function testFailAssertGeUIntWithMsg() public { + assertGe(uint(1), uint(2), "msg"); + } + + // --- assertGe (Int) --- + + function testAssertGeInt() public { + assertGe(-1, -2, "msg"); + assertGe(-1, -1); + } + function testFailAssertGeInt() public { + assertGe(-2, -1); + } + function testFailAssertGeIntWithMsg() public { + assertGe(-2, -1, "msg"); + } + + // --- assertGeDecimal (UInt) --- + + function testAssertGeDecimalUInt() public { + assertGeDecimal(uint(2), uint(1), 18, "msg"); + assertGeDecimal(uint(2), uint(2), 18); + } + function testFailAssertGeDecimalUInt() public { + assertGeDecimal(uint(1), uint(2), 18); + } + function testFailAssertGeDecimalUIntWithMsg() public { + assertGeDecimal(uint(1), uint(2), 18, "msg"); + } + + // --- assertGeDecimal (Int) --- + + function testAssertGeDecimalInt() public { + assertGeDecimal(-1, -2, 18, "msg"); + assertGeDecimal(-1, -2, 18); + } + function testFailAssertGeDecimalInt() public { + assertGeDecimal(-2, -1, 18); + } + function testFailAssertGeDecimalIntWithMsg() public { + assertGeDecimal(-2, -1, 18, "msg"); + } + + // --- assertLt (UInt) --- + + function testAssertLtUInt() public { + assertLt(uint(1), uint(2), "msg"); + assertLt(uint(1), uint(3)); + } + function testFailAssertLtUInt() public { + assertLt(uint(2), uint(2)); + } + function testFailAssertLtUIntWithMsg() public { + assertLt(uint(3), uint(2), "msg"); + } + + // --- assertLt (Int) --- + + function testAssertLtInt() public { + assertLt(-2, -1, "msg"); + assertLt(-1, 0); + } + function testFailAssertLtInt() public { + assertLt(-1, -2); + } + function testFailAssertLtIntWithMsg() public { + assertLt(-1, -1, "msg"); + } + + // --- assertLtDecimal (UInt) --- + + function testAssertLtDecimalUInt() public { + assertLtDecimal(uint(1), uint(2), 18, "msg"); + assertLtDecimal(uint(2), uint(3), 18); + } + function testFailAssertLtDecimalUInt() public { + assertLtDecimal(uint(1), uint(1), 18); + } + function testFailAssertLtDecimalUIntWithMsg() public { + assertLtDecimal(uint(2), uint(1), 18, "msg"); + } + + // --- assertLtDecimal (Int) --- + + function testAssertLtDecimalInt() public { + assertLtDecimal(-2, -1, 18, "msg"); + assertLtDecimal(-2, -1, 18); + } + function testFailAssertLtDecimalInt() public { + assertLtDecimal(-2, -2, 18); + } + function testFailAssertLtDecimalIntWithMsg() public { + assertLtDecimal(-1, -2, 18, "msg"); + } + + // --- assertLe (UInt) --- + + function testAssertLeUInt() public { + assertLe(uint(1), uint(2), "msg"); + assertLe(uint(1), uint(1)); + } + function testFailAssertLeUInt() public { + assertLe(uint(4), uint(2)); + } + function testFailAssertLeUIntWithMsg() public { + assertLe(uint(3), uint(2), "msg"); + } + + // --- assertLe (Int) --- + + function testAssertLeInt() public { + assertLe(-2, -1, "msg"); + assertLe(-1, -1); + } + function testFailAssertLeInt() public { + assertLe(-1, -2); + } + function testFailAssertLeIntWithMsg() public { + assertLe(-1, -3, "msg"); + } + + // --- assertLeDecimal (UInt) --- + + function testAssertLeDecimalUInt() public { + assertLeDecimal(uint(1), uint(2), 18, "msg"); + assertLeDecimal(uint(2), uint(2), 18); + } + function testFailAssertLeDecimalUInt() public { + assertLeDecimal(uint(1), uint(0), 18); + } + function testFailAssertLeDecimalUIntWithMsg() public { + assertLeDecimal(uint(1), uint(0), 18, "msg"); + } + + // --- assertLeDecimal (Int) --- + + function testAssertLeDecimalInt() public { + assertLeDecimal(-2, -1, 18, "msg"); + assertLeDecimal(-2, -2, 18); + } + function testFailAssertLeDecimalInt() public { + assertLeDecimal(-2, -3, 18); + } + function testFailAssertLeDecimalIntWithMsg() public { + assertLeDecimal(-1, -2, 18, "msg"); + } + + // --- assertNotEq (String) --- + + function testAssertNotEqString() public { + assertNotEq(new string(1), new string(2), "msg"); + assertNotEq(new string(1), new string(2)); + } + function testFailAssertNotEqString() public { + assertNotEq(new string(1), new string(1)); + } + function testFailAssertNotEqStringWithMsg() public { + assertNotEq(new string(1), new string(1), "msg"); + } + + // --- assertNotEq0 (Bytes) --- + + function testAssertNotEq0Bytes() public { + assertNotEq0(bytes("hi"), bytes("ho"), "msg"); + assertNotEq0(bytes("hi"), bytes("ho")); + } + function testFailAssertNotEq0Bytes() public { + assertNotEq0(bytes("hi"), bytes("hi")); + } + function testFailAssertNotEq0BytesWithMsg() public { + assertNotEq0(bytes("hi"), bytes("hi"), "msg"); + } + + // --- fail override --- + + // ensure that fail can be overridden + function fail() internal override { + super.fail(); + } +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/package.json b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/package.json new file mode 100644 index 0000000000..310d46c8c8 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/package.json @@ -0,0 +1,16 @@ +{ + "name": "forge-std", + "version": "1.6.0", + "description": "Forge Standard Library is a collection of helpful contracts and libraries for use with Forge and Foundry.", + "homepage": "https://book.getfoundry.sh/forge/forge-std", + "bugs": "https://github.com/foundry-rs/forge-std/issues", + "license": "(Apache-2.0 OR MIT)", + "author": "Contributors to Forge Standard Library", + "files": [ + "src/**/*" + ], + "repository": { + "type": "git", + "url": "https://github.com/foundry-rs/forge-std.git" + } +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/Base.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/Base.sol new file mode 100644 index 0000000000..851ac0cd2b --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/Base.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +import {StdStorage} from "./StdStorage.sol"; +import {Vm, VmSafe} from "./Vm.sol"; + +abstract contract CommonBase { + // Cheat code address, 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D. + address internal constant VM_ADDRESS = address(uint160(uint256(keccak256("hevm cheat code")))); + // console.sol and console2.sol work by executing a staticcall to this address. + address internal constant CONSOLE = 0x000000000000000000636F6e736F6c652e6c6f67; + // Used when deploying with create2, https://github.com/Arachnid/deterministic-deployment-proxy. + address internal constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C; + // Default address for tx.origin and msg.sender, 0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38. + address internal constant DEFAULT_SENDER = address(uint160(uint256(keccak256("foundry default caller")))); + // Address of the test contract, deployed by the DEFAULT_SENDER. + address internal constant DEFAULT_TEST_CONTRACT = 0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f; + // Deterministic deployment address of the Multicall3 contract. + address internal constant MULTICALL3_ADDRESS = 0xcA11bde05977b3631167028862bE2a173976CA11; + // The order of the secp256k1 curve. + uint256 internal constant SECP256K1_ORDER = + 115792089237316195423570985008687907852837564279074904382605163141518161494337; + + uint256 internal constant UINT256_MAX = + 115792089237316195423570985008687907853269984665640564039457584007913129639935; + + Vm internal constant vm = Vm(VM_ADDRESS); + StdStorage internal stdstore; +} + +abstract contract TestBase is CommonBase {} + +abstract contract ScriptBase is CommonBase { + VmSafe internal constant vmSafe = VmSafe(VM_ADDRESS); +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/Script.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/Script.sol new file mode 100644 index 0000000000..94e75f6cbc --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/Script.sol @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +// šŸ’¬ ABOUT +// Forge Std's default Script. + +// 🧩 MODULES +import {console} from "./console.sol"; +import {console2} from "./console2.sol"; +import {safeconsole} from "./safeconsole.sol"; +import {StdChains} from "./StdChains.sol"; +import {StdCheatsSafe} from "./StdCheats.sol"; +import {stdJson} from "./StdJson.sol"; +import {stdMath} from "./StdMath.sol"; +import {StdStorage, stdStorageSafe} from "./StdStorage.sol"; +import {StdStyle} from "./StdStyle.sol"; +import {StdUtils} from "./StdUtils.sol"; +import {VmSafe} from "./Vm.sol"; + +// šŸ“¦ BOILERPLATE +import {ScriptBase} from "./Base.sol"; + +// ā­ļø SCRIPT +abstract contract Script is ScriptBase, StdChains, StdCheatsSafe, StdUtils { + // Note: IS_SCRIPT() must return true. + bool public IS_SCRIPT = true; +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdAssertions.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdAssertions.sol new file mode 100644 index 0000000000..2778b3a0e8 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdAssertions.sol @@ -0,0 +1,376 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +import {DSTest} from "ds-test/test.sol"; +import {stdMath} from "./StdMath.sol"; + +abstract contract StdAssertions is DSTest { + event log_array(uint256[] val); + event log_array(int256[] val); + event log_array(address[] val); + event log_named_array(string key, uint256[] val); + event log_named_array(string key, int256[] val); + event log_named_array(string key, address[] val); + + function fail(string memory err) internal virtual { + emit log_named_string("Error", err); + fail(); + } + + function assertFalse(bool data) internal virtual { + assertTrue(!data); + } + + function assertFalse(bool data, string memory err) internal virtual { + assertTrue(!data, err); + } + + function assertEq(bool a, bool b) internal virtual { + if (a != b) { + emit log("Error: a == b not satisfied [bool]"); + emit log_named_string(" Left", a ? "true" : "false"); + emit log_named_string(" Right", b ? "true" : "false"); + fail(); + } + } + + function assertEq(bool a, bool b, string memory err) internal virtual { + if (a != b) { + emit log_named_string("Error", err); + assertEq(a, b); + } + } + + function assertEq(bytes memory a, bytes memory b) internal virtual { + assertEq0(a, b); + } + + function assertEq(bytes memory a, bytes memory b, string memory err) internal virtual { + assertEq0(a, b, err); + } + + function assertEq(uint256[] memory a, uint256[] memory b) internal virtual { + if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { + emit log("Error: a == b not satisfied [uint[]]"); + emit log_named_array(" Left", a); + emit log_named_array(" Right", b); + fail(); + } + } + + function assertEq(int256[] memory a, int256[] memory b) internal virtual { + if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { + emit log("Error: a == b not satisfied [int[]]"); + emit log_named_array(" Left", a); + emit log_named_array(" Right", b); + fail(); + } + } + + function assertEq(address[] memory a, address[] memory b) internal virtual { + if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { + emit log("Error: a == b not satisfied [address[]]"); + emit log_named_array(" Left", a); + emit log_named_array(" Right", b); + fail(); + } + } + + function assertEq(uint256[] memory a, uint256[] memory b, string memory err) internal virtual { + if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { + emit log_named_string("Error", err); + assertEq(a, b); + } + } + + function assertEq(int256[] memory a, int256[] memory b, string memory err) internal virtual { + if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { + emit log_named_string("Error", err); + assertEq(a, b); + } + } + + function assertEq(address[] memory a, address[] memory b, string memory err) internal virtual { + if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) { + emit log_named_string("Error", err); + assertEq(a, b); + } + } + + // Legacy helper + function assertEqUint(uint256 a, uint256 b) internal virtual { + assertEq(uint256(a), uint256(b)); + } + + function assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta) internal virtual { + uint256 delta = stdMath.delta(a, b); + + if (delta > maxDelta) { + emit log("Error: a ~= b not satisfied [uint]"); + emit log_named_uint(" Left", a); + emit log_named_uint(" Right", b); + emit log_named_uint(" Max Delta", maxDelta); + emit log_named_uint(" Delta", delta); + fail(); + } + } + + function assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta, string memory err) internal virtual { + uint256 delta = stdMath.delta(a, b); + + if (delta > maxDelta) { + emit log_named_string("Error", err); + assertApproxEqAbs(a, b, maxDelta); + } + } + + function assertApproxEqAbsDecimal(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals) internal virtual { + uint256 delta = stdMath.delta(a, b); + + if (delta > maxDelta) { + emit log("Error: a ~= b not satisfied [uint]"); + emit log_named_decimal_uint(" Left", a, decimals); + emit log_named_decimal_uint(" Right", b, decimals); + emit log_named_decimal_uint(" Max Delta", maxDelta, decimals); + emit log_named_decimal_uint(" Delta", delta, decimals); + fail(); + } + } + + function assertApproxEqAbsDecimal(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals, string memory err) + internal + virtual + { + uint256 delta = stdMath.delta(a, b); + + if (delta > maxDelta) { + emit log_named_string("Error", err); + assertApproxEqAbsDecimal(a, b, maxDelta, decimals); + } + } + + function assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta) internal virtual { + uint256 delta = stdMath.delta(a, b); + + if (delta > maxDelta) { + emit log("Error: a ~= b not satisfied [int]"); + emit log_named_int(" Left", a); + emit log_named_int(" Right", b); + emit log_named_uint(" Max Delta", maxDelta); + emit log_named_uint(" Delta", delta); + fail(); + } + } + + function assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta, string memory err) internal virtual { + uint256 delta = stdMath.delta(a, b); + + if (delta > maxDelta) { + emit log_named_string("Error", err); + assertApproxEqAbs(a, b, maxDelta); + } + } + + function assertApproxEqAbsDecimal(int256 a, int256 b, uint256 maxDelta, uint256 decimals) internal virtual { + uint256 delta = stdMath.delta(a, b); + + if (delta > maxDelta) { + emit log("Error: a ~= b not satisfied [int]"); + emit log_named_decimal_int(" Left", a, decimals); + emit log_named_decimal_int(" Right", b, decimals); + emit log_named_decimal_uint(" Max Delta", maxDelta, decimals); + emit log_named_decimal_uint(" Delta", delta, decimals); + fail(); + } + } + + function assertApproxEqAbsDecimal(int256 a, int256 b, uint256 maxDelta, uint256 decimals, string memory err) + internal + virtual + { + uint256 delta = stdMath.delta(a, b); + + if (delta > maxDelta) { + emit log_named_string("Error", err); + assertApproxEqAbsDecimal(a, b, maxDelta, decimals); + } + } + + function assertApproxEqRel( + uint256 a, + uint256 b, + uint256 maxPercentDelta // An 18 decimal fixed point number, where 1e18 == 100% + ) internal virtual { + if (b == 0) return assertEq(a, b); // If the left is 0, right must be too. + + uint256 percentDelta = stdMath.percentDelta(a, b); + + if (percentDelta > maxPercentDelta) { + emit log("Error: a ~= b not satisfied [uint]"); + emit log_named_uint(" Left", a); + emit log_named_uint(" Right", b); + emit log_named_decimal_uint(" Max % Delta", maxPercentDelta * 100, 18); + emit log_named_decimal_uint(" % Delta", percentDelta * 100, 18); + fail(); + } + } + + function assertApproxEqRel( + uint256 a, + uint256 b, + uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% + string memory err + ) internal virtual { + if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too. + + uint256 percentDelta = stdMath.percentDelta(a, b); + + if (percentDelta > maxPercentDelta) { + emit log_named_string("Error", err); + assertApproxEqRel(a, b, maxPercentDelta); + } + } + + function assertApproxEqRelDecimal( + uint256 a, + uint256 b, + uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% + uint256 decimals + ) internal virtual { + if (b == 0) return assertEq(a, b); // If the left is 0, right must be too. + + uint256 percentDelta = stdMath.percentDelta(a, b); + + if (percentDelta > maxPercentDelta) { + emit log("Error: a ~= b not satisfied [uint]"); + emit log_named_decimal_uint(" Left", a, decimals); + emit log_named_decimal_uint(" Right", b, decimals); + emit log_named_decimal_uint(" Max % Delta", maxPercentDelta * 100, 18); + emit log_named_decimal_uint(" % Delta", percentDelta * 100, 18); + fail(); + } + } + + function assertApproxEqRelDecimal( + uint256 a, + uint256 b, + uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% + uint256 decimals, + string memory err + ) internal virtual { + if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too. + + uint256 percentDelta = stdMath.percentDelta(a, b); + + if (percentDelta > maxPercentDelta) { + emit log_named_string("Error", err); + assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals); + } + } + + function assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta) internal virtual { + if (b == 0) return assertEq(a, b); // If the left is 0, right must be too. + + uint256 percentDelta = stdMath.percentDelta(a, b); + + if (percentDelta > maxPercentDelta) { + emit log("Error: a ~= b not satisfied [int]"); + emit log_named_int(" Left", a); + emit log_named_int(" Right", b); + emit log_named_decimal_uint(" Max % Delta", maxPercentDelta * 100, 18); + emit log_named_decimal_uint(" % Delta", percentDelta * 100, 18); + fail(); + } + } + + function assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta, string memory err) internal virtual { + if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too. + + uint256 percentDelta = stdMath.percentDelta(a, b); + + if (percentDelta > maxPercentDelta) { + emit log_named_string("Error", err); + assertApproxEqRel(a, b, maxPercentDelta); + } + } + + function assertApproxEqRelDecimal(int256 a, int256 b, uint256 maxPercentDelta, uint256 decimals) internal virtual { + if (b == 0) return assertEq(a, b); // If the left is 0, right must be too. + + uint256 percentDelta = stdMath.percentDelta(a, b); + + if (percentDelta > maxPercentDelta) { + emit log("Error: a ~= b not satisfied [int]"); + emit log_named_decimal_int(" Left", a, decimals); + emit log_named_decimal_int(" Right", b, decimals); + emit log_named_decimal_uint(" Max % Delta", maxPercentDelta * 100, 18); + emit log_named_decimal_uint(" % Delta", percentDelta * 100, 18); + fail(); + } + } + + function assertApproxEqRelDecimal(int256 a, int256 b, uint256 maxPercentDelta, uint256 decimals, string memory err) + internal + virtual + { + if (b == 0) return assertEq(a, b, err); // If the left is 0, right must be too. + + uint256 percentDelta = stdMath.percentDelta(a, b); + + if (percentDelta > maxPercentDelta) { + emit log_named_string("Error", err); + assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals); + } + } + + function assertEqCall(address target, bytes memory callDataA, bytes memory callDataB) internal virtual { + assertEqCall(target, callDataA, target, callDataB, true); + } + + function assertEqCall(address targetA, bytes memory callDataA, address targetB, bytes memory callDataB) + internal + virtual + { + assertEqCall(targetA, callDataA, targetB, callDataB, true); + } + + function assertEqCall(address target, bytes memory callDataA, bytes memory callDataB, bool strictRevertData) + internal + virtual + { + assertEqCall(target, callDataA, target, callDataB, strictRevertData); + } + + function assertEqCall( + address targetA, + bytes memory callDataA, + address targetB, + bytes memory callDataB, + bool strictRevertData + ) internal virtual { + (bool successA, bytes memory returnDataA) = address(targetA).call(callDataA); + (bool successB, bytes memory returnDataB) = address(targetB).call(callDataB); + + if (successA && successB) { + assertEq(returnDataA, returnDataB, "Call return data does not match"); + } + + if (!successA && !successB && strictRevertData) { + assertEq(returnDataA, returnDataB, "Call revert data does not match"); + } + + if (!successA && successB) { + emit log("Error: Calls were not equal"); + emit log_named_bytes(" Left call revert data", returnDataA); + emit log_named_bytes(" Right call return data", returnDataB); + fail(); + } + + if (successA && !successB) { + emit log("Error: Calls were not equal"); + emit log_named_bytes(" Left call return data", returnDataA); + emit log_named_bytes(" Right call revert data", returnDataB); + fail(); + } + } +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdChains.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdChains.sol new file mode 100644 index 0000000000..79a88d09a0 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdChains.sol @@ -0,0 +1,234 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +import {VmSafe} from "./Vm.sol"; + +/** + * StdChains provides information about EVM compatible chains that can be used in scripts/tests. + * For each chain, the chain's name, chain ID, and a default RPC URL are provided. Chains are + * identified by their alias, which is the same as the alias in the `[rpc_endpoints]` section of + * the `foundry.toml` file. For best UX, ensure the alias in the `foundry.toml` file match the + * alias used in this contract, which can be found as the first argument to the + * `setChainWithDefaultRpcUrl` call in the `initializeStdChains` function. + * + * There are two main ways to use this contract: + * 1. Set a chain with `setChain(string memory chainAlias, ChainData memory chain)` or + * `setChain(string memory chainAlias, Chain memory chain)` + * 2. Get a chain with `getChain(string memory chainAlias)` or `getChain(uint256 chainId)`. + * + * The first time either of those are used, chains are initialized with the default set of RPC URLs. + * This is done in `initializeStdChains`, which uses `setChainWithDefaultRpcUrl`. Defaults are recorded in + * `defaultRpcUrls`. + * + * The `setChain` function is straightforward, and it simply saves off the given chain data. + * + * The `getChain` methods use `getChainWithUpdatedRpcUrl` to return a chain. For example, let's say + * we want to retrieve the RPC URL for `mainnet`: + * - If you have specified data with `setChain`, it will return that. + * - If you have configured a mainnet RPC URL in `foundry.toml`, it will return the URL, provided it + * is valid (e.g. a URL is specified, or an environment variable is given and exists). + * - If neither of the above conditions is met, the default data is returned. + * + * Summarizing the above, the prioritization hierarchy is `setChain` -> `foundry.toml` -> environment variable -> defaults. + */ +abstract contract StdChains { + VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); + + bool private stdChainsInitialized; + + struct ChainData { + string name; + uint256 chainId; + string rpcUrl; + } + + struct Chain { + // The chain name. + string name; + // The chain's Chain ID. + uint256 chainId; + // The chain's alias. (i.e. what gets specified in `foundry.toml`). + string chainAlias; + // A default RPC endpoint for this chain. + // NOTE: This default RPC URL is included for convenience to facilitate quick tests and + // experimentation. Do not use this RPC URL for production test suites, CI, or other heavy + // usage as you will be throttled and this is a disservice to others who need this endpoint. + string rpcUrl; + } + + // Maps from the chain's alias (matching the alias in the `foundry.toml` file) to chain data. + mapping(string => Chain) private chains; + // Maps from the chain's alias to it's default RPC URL. + mapping(string => string) private defaultRpcUrls; + // Maps from a chain ID to it's alias. + mapping(uint256 => string) private idToAlias; + + bool private fallbackToDefaultRpcUrls = true; + + // The RPC URL will be fetched from config or defaultRpcUrls if possible. + function getChain(string memory chainAlias) internal virtual returns (Chain memory chain) { + require(bytes(chainAlias).length != 0, "StdChains getChain(string): Chain alias cannot be the empty string."); + + initializeStdChains(); + chain = chains[chainAlias]; + require( + chain.chainId != 0, + string(abi.encodePacked("StdChains getChain(string): Chain with alias \"", chainAlias, "\" not found.")) + ); + + chain = getChainWithUpdatedRpcUrl(chainAlias, chain); + } + + function getChain(uint256 chainId) internal virtual returns (Chain memory chain) { + require(chainId != 0, "StdChains getChain(uint256): Chain ID cannot be 0."); + initializeStdChains(); + string memory chainAlias = idToAlias[chainId]; + + chain = chains[chainAlias]; + + require( + chain.chainId != 0, + string(abi.encodePacked("StdChains getChain(uint256): Chain with ID ", vm.toString(chainId), " not found.")) + ); + + chain = getChainWithUpdatedRpcUrl(chainAlias, chain); + } + + // set chain info, with priority to argument's rpcUrl field. + function setChain(string memory chainAlias, ChainData memory chain) internal virtual { + require( + bytes(chainAlias).length != 0, + "StdChains setChain(string,ChainData): Chain alias cannot be the empty string." + ); + + require(chain.chainId != 0, "StdChains setChain(string,ChainData): Chain ID cannot be 0."); + + initializeStdChains(); + string memory foundAlias = idToAlias[chain.chainId]; + + require( + bytes(foundAlias).length == 0 || keccak256(bytes(foundAlias)) == keccak256(bytes(chainAlias)), + string( + abi.encodePacked( + "StdChains setChain(string,ChainData): Chain ID ", + vm.toString(chain.chainId), + " already used by \"", + foundAlias, + "\"." + ) + ) + ); + + uint256 oldChainId = chains[chainAlias].chainId; + delete idToAlias[oldChainId]; + + chains[chainAlias] = + Chain({name: chain.name, chainId: chain.chainId, chainAlias: chainAlias, rpcUrl: chain.rpcUrl}); + idToAlias[chain.chainId] = chainAlias; + } + + // set chain info, with priority to argument's rpcUrl field. + function setChain(string memory chainAlias, Chain memory chain) internal virtual { + setChain(chainAlias, ChainData({name: chain.name, chainId: chain.chainId, rpcUrl: chain.rpcUrl})); + } + + function _toUpper(string memory str) private pure returns (string memory) { + bytes memory strb = bytes(str); + bytes memory copy = new bytes(strb.length); + for (uint256 i = 0; i < strb.length; i++) { + bytes1 b = strb[i]; + if (b >= 0x61 && b <= 0x7A) { + copy[i] = bytes1(uint8(b) - 32); + } else { + copy[i] = b; + } + } + return string(copy); + } + + // lookup rpcUrl, in descending order of priority: + // current -> config (foundry.toml) -> environment variable -> default + function getChainWithUpdatedRpcUrl(string memory chainAlias, Chain memory chain) private returns (Chain memory) { + if (bytes(chain.rpcUrl).length == 0) { + try vm.rpcUrl(chainAlias) returns (string memory configRpcUrl) { + chain.rpcUrl = configRpcUrl; + } catch (bytes memory err) { + string memory envName = string(abi.encodePacked(_toUpper(chainAlias), "_RPC_URL")); + if (fallbackToDefaultRpcUrls) { + chain.rpcUrl = vm.envOr(envName, defaultRpcUrls[chainAlias]); + } else { + chain.rpcUrl = vm.envString(envName); + } + // distinguish 'not found' from 'cannot read' + bytes memory notFoundError = + abi.encodeWithSignature("CheatCodeError", string(abi.encodePacked("invalid rpc url ", chainAlias))); + if (keccak256(notFoundError) != keccak256(err) || bytes(chain.rpcUrl).length == 0) { + /// @solidity memory-safe-assembly + assembly { + revert(add(32, err), mload(err)) + } + } + } + } + return chain; + } + + function setFallbackToDefaultRpcUrls(bool useDefault) internal { + fallbackToDefaultRpcUrls = useDefault; + } + + function initializeStdChains() private { + if (stdChainsInitialized) return; + + stdChainsInitialized = true; + + // If adding an RPC here, make sure to test the default RPC URL in `testRpcs` + setChainWithDefaultRpcUrl("anvil", ChainData("Anvil", 31337, "http://127.0.0.1:8545")); + setChainWithDefaultRpcUrl( + "mainnet", ChainData("Mainnet", 1, "https://mainnet.infura.io/v3/b9794ad1ddf84dfb8c34d6bb5dca2001") + ); + setChainWithDefaultRpcUrl( + "goerli", ChainData("Goerli", 5, "https://goerli.infura.io/v3/b9794ad1ddf84dfb8c34d6bb5dca2001") + ); + setChainWithDefaultRpcUrl( + "sepolia", ChainData("Sepolia", 11155111, "https://sepolia.infura.io/v3/b9794ad1ddf84dfb8c34d6bb5dca2001") + ); + setChainWithDefaultRpcUrl("optimism", ChainData("Optimism", 10, "https://mainnet.optimism.io")); + setChainWithDefaultRpcUrl("optimism_goerli", ChainData("Optimism Goerli", 420, "https://goerli.optimism.io")); + setChainWithDefaultRpcUrl("arbitrum_one", ChainData("Arbitrum One", 42161, "https://arb1.arbitrum.io/rpc")); + setChainWithDefaultRpcUrl( + "arbitrum_one_goerli", ChainData("Arbitrum One Goerli", 421613, "https://goerli-rollup.arbitrum.io/rpc") + ); + setChainWithDefaultRpcUrl("arbitrum_nova", ChainData("Arbitrum Nova", 42170, "https://nova.arbitrum.io/rpc")); + setChainWithDefaultRpcUrl("polygon", ChainData("Polygon", 137, "https://polygon-rpc.com")); + setChainWithDefaultRpcUrl( + "polygon_mumbai", ChainData("Polygon Mumbai", 80001, "https://rpc-mumbai.maticvigil.com") + ); + setChainWithDefaultRpcUrl("avalanche", ChainData("Avalanche", 43114, "https://api.avax.network/ext/bc/C/rpc")); + setChainWithDefaultRpcUrl( + "avalanche_fuji", ChainData("Avalanche Fuji", 43113, "https://api.avax-test.network/ext/bc/C/rpc") + ); + setChainWithDefaultRpcUrl( + "bnb_smart_chain", ChainData("BNB Smart Chain", 56, "https://bsc-dataseed1.binance.org") + ); + setChainWithDefaultRpcUrl( + "bnb_smart_chain_testnet", + ChainData("BNB Smart Chain Testnet", 97, "https://rpc.ankr.com/bsc_testnet_chapel") + ); + setChainWithDefaultRpcUrl("gnosis_chain", ChainData("Gnosis Chain", 100, "https://rpc.gnosischain.com")); + setChainWithDefaultRpcUrl("moonbeam", ChainData("Moonbeam", 1284, "https://rpc.api.moonbeam.network")); + setChainWithDefaultRpcUrl( + "moonriver", ChainData("Moonriver", 1285, "https://rpc.api.moonriver.moonbeam.network") + ); + setChainWithDefaultRpcUrl("moonbase", ChainData("Moonbase", 1287, "https://rpc.testnet.moonbeam.network")); + } + + // set chain info, with priority to chainAlias' rpc url in foundry.toml + function setChainWithDefaultRpcUrl(string memory chainAlias, ChainData memory chain) private { + string memory rpcUrl = chain.rpcUrl; + defaultRpcUrls[chainAlias] = rpcUrl; + chain.rpcUrl = ""; + setChain(chainAlias, chain); + chain.rpcUrl = rpcUrl; // restore argument + } +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdCheats.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdCheats.sol new file mode 100644 index 0000000000..008b743147 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdCheats.sol @@ -0,0 +1,817 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +import {StdStorage, stdStorage} from "./StdStorage.sol"; +import {console2} from "./console2.sol"; +import {Vm} from "./Vm.sol"; + +abstract contract StdCheatsSafe { + Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + + uint256 private constant UINT256_MAX = + 115792089237316195423570985008687907853269984665640564039457584007913129639935; + + bool private gasMeteringOff; + + // Data structures to parse Transaction objects from the broadcast artifact + // that conform to EIP1559. The Raw structs is what is parsed from the JSON + // and then converted to the one that is used by the user for better UX. + + struct RawTx1559 { + string[] arguments; + address contractAddress; + string contractName; + // json value name = function + string functionSig; + bytes32 hash; + // json value name = tx + RawTx1559Detail txDetail; + // json value name = type + string opcode; + } + + struct RawTx1559Detail { + AccessList[] accessList; + bytes data; + address from; + bytes gas; + bytes nonce; + address to; + bytes txType; + bytes value; + } + + struct Tx1559 { + string[] arguments; + address contractAddress; + string contractName; + string functionSig; + bytes32 hash; + Tx1559Detail txDetail; + string opcode; + } + + struct Tx1559Detail { + AccessList[] accessList; + bytes data; + address from; + uint256 gas; + uint256 nonce; + address to; + uint256 txType; + uint256 value; + } + + // Data structures to parse Transaction objects from the broadcast artifact + // that DO NOT conform to EIP1559. The Raw structs is what is parsed from the JSON + // and then converted to the one that is used by the user for better UX. + + struct TxLegacy { + string[] arguments; + address contractAddress; + string contractName; + string functionSig; + string hash; + string opcode; + TxDetailLegacy transaction; + } + + struct TxDetailLegacy { + AccessList[] accessList; + uint256 chainId; + bytes data; + address from; + uint256 gas; + uint256 gasPrice; + bytes32 hash; + uint256 nonce; + bytes1 opcode; + bytes32 r; + bytes32 s; + uint256 txType; + address to; + uint8 v; + uint256 value; + } + + struct AccessList { + address accessAddress; + bytes32[] storageKeys; + } + + // Data structures to parse Receipt objects from the broadcast artifact. + // The Raw structs is what is parsed from the JSON + // and then converted to the one that is used by the user for better UX. + + struct RawReceipt { + bytes32 blockHash; + bytes blockNumber; + address contractAddress; + bytes cumulativeGasUsed; + bytes effectiveGasPrice; + address from; + bytes gasUsed; + RawReceiptLog[] logs; + bytes logsBloom; + bytes status; + address to; + bytes32 transactionHash; + bytes transactionIndex; + } + + struct Receipt { + bytes32 blockHash; + uint256 blockNumber; + address contractAddress; + uint256 cumulativeGasUsed; + uint256 effectiveGasPrice; + address from; + uint256 gasUsed; + ReceiptLog[] logs; + bytes logsBloom; + uint256 status; + address to; + bytes32 transactionHash; + uint256 transactionIndex; + } + + // Data structures to parse the entire broadcast artifact, assuming the + // transactions conform to EIP1559. + + struct EIP1559ScriptArtifact { + string[] libraries; + string path; + string[] pending; + Receipt[] receipts; + uint256 timestamp; + Tx1559[] transactions; + TxReturn[] txReturns; + } + + struct RawEIP1559ScriptArtifact { + string[] libraries; + string path; + string[] pending; + RawReceipt[] receipts; + TxReturn[] txReturns; + uint256 timestamp; + RawTx1559[] transactions; + } + + struct RawReceiptLog { + // json value = address + address logAddress; + bytes32 blockHash; + bytes blockNumber; + bytes data; + bytes logIndex; + bool removed; + bytes32[] topics; + bytes32 transactionHash; + bytes transactionIndex; + bytes transactionLogIndex; + } + + struct ReceiptLog { + // json value = address + address logAddress; + bytes32 blockHash; + uint256 blockNumber; + bytes data; + uint256 logIndex; + bytes32[] topics; + uint256 transactionIndex; + uint256 transactionLogIndex; + bool removed; + } + + struct TxReturn { + string internalType; + string value; + } + + struct Account { + address addr; + uint256 key; + } + + enum AddressType { + Payable, + NonPayable, + ZeroAddress, + Precompile, + ForgeAddress + } + + // Checks that `addr` is not blacklisted by token contracts that have a blacklist. + function assumeNotBlacklisted(address token, address addr) internal view virtual { + // Nothing to check if `token` is not a contract. + uint256 tokenCodeSize; + assembly { + tokenCodeSize := extcodesize(token) + } + require(tokenCodeSize > 0, "StdCheats assumeNotBlacklisted(address,address): Token address is not a contract."); + + bool success; + bytes memory returnData; + + // 4-byte selector for `isBlacklisted(address)`, used by USDC. + (success, returnData) = token.staticcall(abi.encodeWithSelector(0xfe575a87, addr)); + vm.assume(!success || abi.decode(returnData, (bool)) == false); + + // 4-byte selector for `isBlackListed(address)`, used by USDT. + (success, returnData) = token.staticcall(abi.encodeWithSelector(0xe47d6060, addr)); + vm.assume(!success || abi.decode(returnData, (bool)) == false); + } + + // Checks that `addr` is not blacklisted by token contracts that have a blacklist. + // This is identical to `assumeNotBlacklisted(address,address)` but with a different name, for + // backwards compatibility, since this name was used in the original PR which has already has + // a release. This function can be removed in a future release once we want a breaking change. + function assumeNoBlacklisted(address token, address addr) internal view virtual { + assumeNotBlacklisted(token, addr); + } + + function assumeAddressIsNot(address addr, AddressType addressType) internal virtual { + if (addressType == AddressType.Payable) { + assumeNotPayable(addr); + } else if (addressType == AddressType.NonPayable) { + assumePayable(addr); + } else if (addressType == AddressType.ZeroAddress) { + assumeNotZeroAddress(addr); + } else if (addressType == AddressType.Precompile) { + assumeNotPrecompile(addr); + } else if (addressType == AddressType.ForgeAddress) { + assumeNotForgeAddress(addr); + } + } + + function assumeAddressIsNot(address addr, AddressType addressType1, AddressType addressType2) internal virtual { + assumeAddressIsNot(addr, addressType1); + assumeAddressIsNot(addr, addressType2); + } + + function assumeAddressIsNot( + address addr, + AddressType addressType1, + AddressType addressType2, + AddressType addressType3 + ) internal virtual { + assumeAddressIsNot(addr, addressType1); + assumeAddressIsNot(addr, addressType2); + assumeAddressIsNot(addr, addressType3); + } + + function assumeAddressIsNot( + address addr, + AddressType addressType1, + AddressType addressType2, + AddressType addressType3, + AddressType addressType4 + ) internal virtual { + assumeAddressIsNot(addr, addressType1); + assumeAddressIsNot(addr, addressType2); + assumeAddressIsNot(addr, addressType3); + assumeAddressIsNot(addr, addressType4); + } + + // This function checks whether an address, `addr`, is payable. It works by sending 1 wei to + // `addr` and checking the `success` return value. + // NOTE: This function may result in state changes depending on the fallback/receive logic + // implemented by `addr`, which should be taken into account when this function is used. + function _isPayable(address addr) private returns (bool) { + require( + addr.balance < UINT256_MAX, + "StdCheats _isPayable(address): Balance equals max uint256, so it cannot receive any more funds" + ); + uint256 origBalanceTest = address(this).balance; + uint256 origBalanceAddr = address(addr).balance; + + vm.deal(address(this), 1); + (bool success,) = payable(addr).call{value: 1}(""); + + // reset balances + vm.deal(address(this), origBalanceTest); + vm.deal(addr, origBalanceAddr); + + return success; + } + + // NOTE: This function may result in state changes depending on the fallback/receive logic + // implemented by `addr`, which should be taken into account when this function is used. See the + // `_isPayable` method for more information. + function assumePayable(address addr) internal virtual { + vm.assume(_isPayable(addr)); + } + + function assumeNotPayable(address addr) internal virtual { + vm.assume(!_isPayable(addr)); + } + + function assumeNotZeroAddress(address addr) internal pure virtual { + vm.assume(addr != address(0)); + } + + function assumeNotPrecompile(address addr) internal pure virtual { + assumeNotPrecompile(addr, _pureChainId()); + } + + function assumeNotPrecompile(address addr, uint256 chainId) internal pure virtual { + // Note: For some chains like Optimism these are technically predeploys (i.e. bytecode placed at a specific + // address), but the same rationale for excluding them applies so we include those too. + + // These should be present on all EVM-compatible chains. + vm.assume(addr < address(0x1) || addr > address(0x9)); + + // forgefmt: disable-start + if (chainId == 10 || chainId == 420) { + // https://github.com/ethereum-optimism/optimism/blob/eaa371a0184b56b7ca6d9eb9cb0a2b78b2ccd864/op-bindings/predeploys/addresses.go#L6-L21 + vm.assume(addr < address(0x4200000000000000000000000000000000000000) || addr > address(0x4200000000000000000000000000000000000800)); + } else if (chainId == 42161 || chainId == 421613) { + // https://developer.arbitrum.io/useful-addresses#arbitrum-precompiles-l2-same-on-all-arb-chains + vm.assume(addr < address(0x0000000000000000000000000000000000000064) || addr > address(0x0000000000000000000000000000000000000068)); + } else if (chainId == 43114 || chainId == 43113) { + // https://github.com/ava-labs/subnet-evm/blob/47c03fd007ecaa6de2c52ea081596e0a88401f58/precompile/params.go#L18-L59 + vm.assume(addr < address(0x0100000000000000000000000000000000000000) || addr > address(0x01000000000000000000000000000000000000ff)); + vm.assume(addr < address(0x0200000000000000000000000000000000000000) || addr > address(0x02000000000000000000000000000000000000FF)); + vm.assume(addr < address(0x0300000000000000000000000000000000000000) || addr > address(0x03000000000000000000000000000000000000Ff)); + } + // forgefmt: disable-end + } + + function assumeNotForgeAddress(address addr) internal pure virtual { + // vm, console, and Create2Deployer addresses + vm.assume( + addr != address(vm) && addr != 0x000000000000000000636F6e736F6c652e6c6f67 + && addr != 0x4e59b44847b379578588920cA78FbF26c0B4956C + ); + } + + function readEIP1559ScriptArtifact(string memory path) + internal + view + virtual + returns (EIP1559ScriptArtifact memory) + { + string memory data = vm.readFile(path); + bytes memory parsedData = vm.parseJson(data); + RawEIP1559ScriptArtifact memory rawArtifact = abi.decode(parsedData, (RawEIP1559ScriptArtifact)); + EIP1559ScriptArtifact memory artifact; + artifact.libraries = rawArtifact.libraries; + artifact.path = rawArtifact.path; + artifact.timestamp = rawArtifact.timestamp; + artifact.pending = rawArtifact.pending; + artifact.txReturns = rawArtifact.txReturns; + artifact.receipts = rawToConvertedReceipts(rawArtifact.receipts); + artifact.transactions = rawToConvertedEIPTx1559s(rawArtifact.transactions); + return artifact; + } + + function rawToConvertedEIPTx1559s(RawTx1559[] memory rawTxs) internal pure virtual returns (Tx1559[] memory) { + Tx1559[] memory txs = new Tx1559[](rawTxs.length); + for (uint256 i; i < rawTxs.length; i++) { + txs[i] = rawToConvertedEIPTx1559(rawTxs[i]); + } + return txs; + } + + function rawToConvertedEIPTx1559(RawTx1559 memory rawTx) internal pure virtual returns (Tx1559 memory) { + Tx1559 memory transaction; + transaction.arguments = rawTx.arguments; + transaction.contractName = rawTx.contractName; + transaction.functionSig = rawTx.functionSig; + transaction.hash = rawTx.hash; + transaction.txDetail = rawToConvertedEIP1559Detail(rawTx.txDetail); + transaction.opcode = rawTx.opcode; + return transaction; + } + + function rawToConvertedEIP1559Detail(RawTx1559Detail memory rawDetail) + internal + pure + virtual + returns (Tx1559Detail memory) + { + Tx1559Detail memory txDetail; + txDetail.data = rawDetail.data; + txDetail.from = rawDetail.from; + txDetail.to = rawDetail.to; + txDetail.nonce = _bytesToUint(rawDetail.nonce); + txDetail.txType = _bytesToUint(rawDetail.txType); + txDetail.value = _bytesToUint(rawDetail.value); + txDetail.gas = _bytesToUint(rawDetail.gas); + txDetail.accessList = rawDetail.accessList; + return txDetail; + } + + function readTx1559s(string memory path) internal view virtual returns (Tx1559[] memory) { + string memory deployData = vm.readFile(path); + bytes memory parsedDeployData = vm.parseJson(deployData, ".transactions"); + RawTx1559[] memory rawTxs = abi.decode(parsedDeployData, (RawTx1559[])); + return rawToConvertedEIPTx1559s(rawTxs); + } + + function readTx1559(string memory path, uint256 index) internal view virtual returns (Tx1559 memory) { + string memory deployData = vm.readFile(path); + string memory key = string(abi.encodePacked(".transactions[", vm.toString(index), "]")); + bytes memory parsedDeployData = vm.parseJson(deployData, key); + RawTx1559 memory rawTx = abi.decode(parsedDeployData, (RawTx1559)); + return rawToConvertedEIPTx1559(rawTx); + } + + // Analogous to readTransactions, but for receipts. + function readReceipts(string memory path) internal view virtual returns (Receipt[] memory) { + string memory deployData = vm.readFile(path); + bytes memory parsedDeployData = vm.parseJson(deployData, ".receipts"); + RawReceipt[] memory rawReceipts = abi.decode(parsedDeployData, (RawReceipt[])); + return rawToConvertedReceipts(rawReceipts); + } + + function readReceipt(string memory path, uint256 index) internal view virtual returns (Receipt memory) { + string memory deployData = vm.readFile(path); + string memory key = string(abi.encodePacked(".receipts[", vm.toString(index), "]")); + bytes memory parsedDeployData = vm.parseJson(deployData, key); + RawReceipt memory rawReceipt = abi.decode(parsedDeployData, (RawReceipt)); + return rawToConvertedReceipt(rawReceipt); + } + + function rawToConvertedReceipts(RawReceipt[] memory rawReceipts) internal pure virtual returns (Receipt[] memory) { + Receipt[] memory receipts = new Receipt[](rawReceipts.length); + for (uint256 i; i < rawReceipts.length; i++) { + receipts[i] = rawToConvertedReceipt(rawReceipts[i]); + } + return receipts; + } + + function rawToConvertedReceipt(RawReceipt memory rawReceipt) internal pure virtual returns (Receipt memory) { + Receipt memory receipt; + receipt.blockHash = rawReceipt.blockHash; + receipt.to = rawReceipt.to; + receipt.from = rawReceipt.from; + receipt.contractAddress = rawReceipt.contractAddress; + receipt.effectiveGasPrice = _bytesToUint(rawReceipt.effectiveGasPrice); + receipt.cumulativeGasUsed = _bytesToUint(rawReceipt.cumulativeGasUsed); + receipt.gasUsed = _bytesToUint(rawReceipt.gasUsed); + receipt.status = _bytesToUint(rawReceipt.status); + receipt.transactionIndex = _bytesToUint(rawReceipt.transactionIndex); + receipt.blockNumber = _bytesToUint(rawReceipt.blockNumber); + receipt.logs = rawToConvertedReceiptLogs(rawReceipt.logs); + receipt.logsBloom = rawReceipt.logsBloom; + receipt.transactionHash = rawReceipt.transactionHash; + return receipt; + } + + function rawToConvertedReceiptLogs(RawReceiptLog[] memory rawLogs) + internal + pure + virtual + returns (ReceiptLog[] memory) + { + ReceiptLog[] memory logs = new ReceiptLog[](rawLogs.length); + for (uint256 i; i < rawLogs.length; i++) { + logs[i].logAddress = rawLogs[i].logAddress; + logs[i].blockHash = rawLogs[i].blockHash; + logs[i].blockNumber = _bytesToUint(rawLogs[i].blockNumber); + logs[i].data = rawLogs[i].data; + logs[i].logIndex = _bytesToUint(rawLogs[i].logIndex); + logs[i].topics = rawLogs[i].topics; + logs[i].transactionIndex = _bytesToUint(rawLogs[i].transactionIndex); + logs[i].transactionLogIndex = _bytesToUint(rawLogs[i].transactionLogIndex); + logs[i].removed = rawLogs[i].removed; + } + return logs; + } + + // Deploy a contract by fetching the contract bytecode from + // the artifacts directory + // e.g. `deployCode(code, abi.encode(arg1,arg2,arg3))` + function deployCode(string memory what, bytes memory args) internal virtual returns (address addr) { + bytes memory bytecode = abi.encodePacked(vm.getCode(what), args); + /// @solidity memory-safe-assembly + assembly { + addr := create(0, add(bytecode, 0x20), mload(bytecode)) + } + + require(addr != address(0), "StdCheats deployCode(string,bytes): Deployment failed."); + } + + function deployCode(string memory what) internal virtual returns (address addr) { + bytes memory bytecode = vm.getCode(what); + /// @solidity memory-safe-assembly + assembly { + addr := create(0, add(bytecode, 0x20), mload(bytecode)) + } + + require(addr != address(0), "StdCheats deployCode(string): Deployment failed."); + } + + /// @dev deploy contract with value on construction + function deployCode(string memory what, bytes memory args, uint256 val) internal virtual returns (address addr) { + bytes memory bytecode = abi.encodePacked(vm.getCode(what), args); + /// @solidity memory-safe-assembly + assembly { + addr := create(val, add(bytecode, 0x20), mload(bytecode)) + } + + require(addr != address(0), "StdCheats deployCode(string,bytes,uint256): Deployment failed."); + } + + function deployCode(string memory what, uint256 val) internal virtual returns (address addr) { + bytes memory bytecode = vm.getCode(what); + /// @solidity memory-safe-assembly + assembly { + addr := create(val, add(bytecode, 0x20), mload(bytecode)) + } + + require(addr != address(0), "StdCheats deployCode(string,uint256): Deployment failed."); + } + + // creates a labeled address and the corresponding private key + function makeAddrAndKey(string memory name) internal virtual returns (address addr, uint256 privateKey) { + privateKey = uint256(keccak256(abi.encodePacked(name))); + addr = vm.addr(privateKey); + vm.label(addr, name); + } + + // creates a labeled address + function makeAddr(string memory name) internal virtual returns (address addr) { + (addr,) = makeAddrAndKey(name); + } + + // Destroys an account immediately, sending the balance to beneficiary. + // Destroying means: balance will be zero, code will be empty, and nonce will be 0 + // This is similar to selfdestruct but not identical: selfdestruct destroys code and nonce + // only after tx ends, this will run immediately. + function destroyAccount(address who, address beneficiary) internal virtual { + uint256 currBalance = who.balance; + vm.etch(who, abi.encode()); + vm.deal(who, 0); + vm.resetNonce(who); + + uint256 beneficiaryBalance = beneficiary.balance; + vm.deal(beneficiary, currBalance + beneficiaryBalance); + } + + // creates a struct containing both a labeled address and the corresponding private key + function makeAccount(string memory name) internal virtual returns (Account memory account) { + (account.addr, account.key) = makeAddrAndKey(name); + } + + function deriveRememberKey(string memory mnemonic, uint32 index) + internal + virtual + returns (address who, uint256 privateKey) + { + privateKey = vm.deriveKey(mnemonic, index); + who = vm.rememberKey(privateKey); + } + + function _bytesToUint(bytes memory b) private pure returns (uint256) { + require(b.length <= 32, "StdCheats _bytesToUint(bytes): Bytes length exceeds 32."); + return abi.decode(abi.encodePacked(new bytes(32 - b.length), b), (uint256)); + } + + function isFork() internal view virtual returns (bool status) { + try vm.activeFork() { + status = true; + } catch (bytes memory) {} + } + + modifier skipWhenForking() { + if (!isFork()) { + _; + } + } + + modifier skipWhenNotForking() { + if (isFork()) { + _; + } + } + + modifier noGasMetering() { + vm.pauseGasMetering(); + // To prevent turning gas monitoring back on with nested functions that use this modifier, + // we check if gasMetering started in the off position. If it did, we don't want to turn + // it back on until we exit the top level function that used the modifier + // + // i.e. funcA() noGasMetering { funcB() }, where funcB has noGasMetering as well. + // funcA will have `gasStartedOff` as false, funcB will have it as true, + // so we only turn metering back on at the end of the funcA + bool gasStartedOff = gasMeteringOff; + gasMeteringOff = true; + + _; + + // if gas metering was on when this modifier was called, turn it back on at the end + if (!gasStartedOff) { + gasMeteringOff = false; + vm.resumeGasMetering(); + } + } + + // We use this complex approach of `_viewChainId` and `_pureChainId` to ensure there are no + // compiler warnings when accessing chain ID in any solidity version supported by forge-std. We + // can't simply access the chain ID in a normal view or pure function because the solc View Pure + // Checker changed `chainid` from pure to view in 0.8.0. + function _viewChainId() private view returns (uint256 chainId) { + // Assembly required since `block.chainid` was introduced in 0.8.0. + assembly { + chainId := chainid() + } + + address(this); // Silence warnings in older Solc versions. + } + + function _pureChainId() private pure returns (uint256 chainId) { + function() internal view returns (uint256) fnIn = _viewChainId; + function() internal pure returns (uint256) pureChainId; + assembly { + pureChainId := fnIn + } + chainId = pureChainId(); + } +} + +// Wrappers around cheatcodes to avoid footguns +abstract contract StdCheats is StdCheatsSafe { + using stdStorage for StdStorage; + + StdStorage private stdstore; + Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + address private constant CONSOLE2_ADDRESS = 0x000000000000000000636F6e736F6c652e6c6f67; + + // Skip forward or rewind time by the specified number of seconds + function skip(uint256 time) internal virtual { + vm.warp(block.timestamp + time); + } + + function rewind(uint256 time) internal virtual { + vm.warp(block.timestamp - time); + } + + // Setup a prank from an address that has some ether + function hoax(address msgSender) internal virtual { + vm.deal(msgSender, 1 << 128); + vm.prank(msgSender); + } + + function hoax(address msgSender, uint256 give) internal virtual { + vm.deal(msgSender, give); + vm.prank(msgSender); + } + + function hoax(address msgSender, address origin) internal virtual { + vm.deal(msgSender, 1 << 128); + vm.prank(msgSender, origin); + } + + function hoax(address msgSender, address origin, uint256 give) internal virtual { + vm.deal(msgSender, give); + vm.prank(msgSender, origin); + } + + // Start perpetual prank from an address that has some ether + function startHoax(address msgSender) internal virtual { + vm.deal(msgSender, 1 << 128); + vm.startPrank(msgSender); + } + + function startHoax(address msgSender, uint256 give) internal virtual { + vm.deal(msgSender, give); + vm.startPrank(msgSender); + } + + // Start perpetual prank from an address that has some ether + // tx.origin is set to the origin parameter + function startHoax(address msgSender, address origin) internal virtual { + vm.deal(msgSender, 1 << 128); + vm.startPrank(msgSender, origin); + } + + function startHoax(address msgSender, address origin, uint256 give) internal virtual { + vm.deal(msgSender, give); + vm.startPrank(msgSender, origin); + } + + function changePrank(address msgSender) internal virtual { + console2_log("changePrank is deprecated. Please use vm.startPrank instead."); + vm.stopPrank(); + vm.startPrank(msgSender); + } + + function changePrank(address msgSender, address txOrigin) internal virtual { + vm.stopPrank(); + vm.startPrank(msgSender, txOrigin); + } + + // The same as Vm's `deal` + // Use the alternative signature for ERC20 tokens + function deal(address to, uint256 give) internal virtual { + vm.deal(to, give); + } + + // Set the balance of an account for any ERC20 token + // Use the alternative signature to update `totalSupply` + function deal(address token, address to, uint256 give) internal virtual { + deal(token, to, give, false); + } + + // Set the balance of an account for any ERC1155 token + // Use the alternative signature to update `totalSupply` + function dealERC1155(address token, address to, uint256 id, uint256 give) internal virtual { + dealERC1155(token, to, id, give, false); + } + + function deal(address token, address to, uint256 give, bool adjust) internal virtual { + // get current balance + (, bytes memory balData) = token.staticcall(abi.encodeWithSelector(0x70a08231, to)); + uint256 prevBal = abi.decode(balData, (uint256)); + + // update balance + stdstore.target(token).sig(0x70a08231).with_key(to).checked_write(give); + + // update total supply + if (adjust) { + (, bytes memory totSupData) = token.staticcall(abi.encodeWithSelector(0x18160ddd)); + uint256 totSup = abi.decode(totSupData, (uint256)); + if (give < prevBal) { + totSup -= (prevBal - give); + } else { + totSup += (give - prevBal); + } + stdstore.target(token).sig(0x18160ddd).checked_write(totSup); + } + } + + function dealERC1155(address token, address to, uint256 id, uint256 give, bool adjust) internal virtual { + // get current balance + (, bytes memory balData) = token.staticcall(abi.encodeWithSelector(0x00fdd58e, to, id)); + uint256 prevBal = abi.decode(balData, (uint256)); + + // update balance + stdstore.target(token).sig(0x00fdd58e).with_key(to).with_key(id).checked_write(give); + + // update total supply + if (adjust) { + (, bytes memory totSupData) = token.staticcall(abi.encodeWithSelector(0xbd85b039, id)); + require( + totSupData.length != 0, + "StdCheats deal(address,address,uint,uint,bool): target contract is not ERC1155Supply." + ); + uint256 totSup = abi.decode(totSupData, (uint256)); + if (give < prevBal) { + totSup -= (prevBal - give); + } else { + totSup += (give - prevBal); + } + stdstore.target(token).sig(0xbd85b039).with_key(id).checked_write(totSup); + } + } + + function dealERC721(address token, address to, uint256 id) internal virtual { + // check if token id is already minted and the actual owner. + (bool successMinted, bytes memory ownerData) = token.staticcall(abi.encodeWithSelector(0x6352211e, id)); + require(successMinted, "StdCheats deal(address,address,uint,bool): id not minted."); + + // get owner current balance + (, bytes memory fromBalData) = + token.staticcall(abi.encodeWithSelector(0x70a08231, abi.decode(ownerData, (address)))); + uint256 fromPrevBal = abi.decode(fromBalData, (uint256)); + + // get new user current balance + (, bytes memory toBalData) = token.staticcall(abi.encodeWithSelector(0x70a08231, to)); + uint256 toPrevBal = abi.decode(toBalData, (uint256)); + + // update balances + stdstore.target(token).sig(0x70a08231).with_key(abi.decode(ownerData, (address))).checked_write(--fromPrevBal); + stdstore.target(token).sig(0x70a08231).with_key(to).checked_write(++toPrevBal); + + // update owner + stdstore.target(token).sig(0x6352211e).with_key(id).checked_write(to); + } + + function deployCodeTo(string memory what, address where) internal virtual { + deployCodeTo(what, "", 0, where); + } + + function deployCodeTo(string memory what, bytes memory args, address where) internal virtual { + deployCodeTo(what, args, 0, where); + } + + function deployCodeTo(string memory what, bytes memory args, uint256 value, address where) internal virtual { + bytes memory creationCode = vm.getCode(what); + vm.etch(where, abi.encodePacked(creationCode, args)); + (bool success, bytes memory runtimeBytecode) = where.call{value: value}(""); + require(success, "StdCheats deployCodeTo(string,bytes,uint256,address): Failed to create runtime bytecode."); + vm.etch(where, runtimeBytecode); + } + + // Used to prevent the compilation of console, which shortens the compilation time when console is not used elsewhere. + function console2_log(string memory p0) private view { + (bool status,) = address(CONSOLE2_ADDRESS).staticcall(abi.encodeWithSignature("log(string)", p0)); + status; + } +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdError.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdError.sol new file mode 100644 index 0000000000..a302191faa --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdError.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: MIT +// Panics work for versions >=0.8.0, but we lowered the pragma to make this compatible with Test +pragma solidity >=0.6.2 <0.9.0; + +library stdError { + bytes public constant assertionError = abi.encodeWithSignature("Panic(uint256)", 0x01); + bytes public constant arithmeticError = abi.encodeWithSignature("Panic(uint256)", 0x11); + bytes public constant divisionError = abi.encodeWithSignature("Panic(uint256)", 0x12); + bytes public constant enumConversionError = abi.encodeWithSignature("Panic(uint256)", 0x21); + bytes public constant encodeStorageError = abi.encodeWithSignature("Panic(uint256)", 0x22); + bytes public constant popError = abi.encodeWithSignature("Panic(uint256)", 0x31); + bytes public constant indexOOBError = abi.encodeWithSignature("Panic(uint256)", 0x32); + bytes public constant memOverflowError = abi.encodeWithSignature("Panic(uint256)", 0x41); + bytes public constant zeroVarError = abi.encodeWithSignature("Panic(uint256)", 0x51); +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdInvariant.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdInvariant.sol new file mode 100644 index 0000000000..fd9d0a1dba --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdInvariant.sol @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +abstract contract StdInvariant { + struct FuzzSelector { + address addr; + bytes4[] selectors; + } + + address[] private _excludedContracts; + address[] private _excludedSenders; + address[] private _targetedContracts; + address[] private _targetedSenders; + + string[] private _excludedArtifacts; + string[] private _targetedArtifacts; + + FuzzSelector[] private _targetedArtifactSelectors; + FuzzSelector[] private _targetedSelectors; + + // Functions for users: + // These are intended to be called in tests. + + function excludeContract(address newExcludedContract_) internal { + _excludedContracts.push(newExcludedContract_); + } + + function excludeSender(address newExcludedSender_) internal { + _excludedSenders.push(newExcludedSender_); + } + + function excludeArtifact(string memory newExcludedArtifact_) internal { + _excludedArtifacts.push(newExcludedArtifact_); + } + + function targetArtifact(string memory newTargetedArtifact_) internal { + _targetedArtifacts.push(newTargetedArtifact_); + } + + function targetArtifactSelector(FuzzSelector memory newTargetedArtifactSelector_) internal { + _targetedArtifactSelectors.push(newTargetedArtifactSelector_); + } + + function targetContract(address newTargetedContract_) internal { + _targetedContracts.push(newTargetedContract_); + } + + function targetSelector(FuzzSelector memory newTargetedSelector_) internal { + _targetedSelectors.push(newTargetedSelector_); + } + + function targetSender(address newTargetedSender_) internal { + _targetedSenders.push(newTargetedSender_); + } + + // Functions for forge: + // These are called by forge to run invariant tests and don't need to be called in tests. + + function excludeArtifacts() public view returns (string[] memory excludedArtifacts_) { + excludedArtifacts_ = _excludedArtifacts; + } + + function excludeContracts() public view returns (address[] memory excludedContracts_) { + excludedContracts_ = _excludedContracts; + } + + function excludeSenders() public view returns (address[] memory excludedSenders_) { + excludedSenders_ = _excludedSenders; + } + + function targetArtifacts() public view returns (string[] memory targetedArtifacts_) { + targetedArtifacts_ = _targetedArtifacts; + } + + function targetArtifactSelectors() public view returns (FuzzSelector[] memory targetedArtifactSelectors_) { + targetedArtifactSelectors_ = _targetedArtifactSelectors; + } + + function targetContracts() public view returns (address[] memory targetedContracts_) { + targetedContracts_ = _targetedContracts; + } + + function targetSelectors() public view returns (FuzzSelector[] memory targetedSelectors_) { + targetedSelectors_ = _targetedSelectors; + } + + function targetSenders() public view returns (address[] memory targetedSenders_) { + targetedSenders_ = _targetedSenders; + } +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdJson.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdJson.sol new file mode 100644 index 0000000000..014e6b15e5 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdJson.sol @@ -0,0 +1,179 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.0 <0.9.0; + +pragma experimental ABIEncoderV2; + +import {VmSafe} from "./Vm.sol"; + +// Helpers for parsing and writing JSON files +// To parse: +// ``` +// using stdJson for string; +// string memory json = vm.readFile("some_peth"); +// json.parseUint(""); +// ``` +// To write: +// ``` +// using stdJson for string; +// string memory json = "deploymentArtifact"; +// Contract contract = new Contract(); +// json.serialize("contractAddress", address(contract)); +// json = json.serialize("deploymentTimes", uint(1)); +// // store the stringified JSON to the 'json' variable we have been using as a key +// // as we won't need it any longer +// string memory json2 = "finalArtifact"; +// string memory final = json2.serialize("depArtifact", json); +// final.write(""); +// ``` + +library stdJson { + VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); + + function parseRaw(string memory json, string memory key) internal pure returns (bytes memory) { + return vm.parseJson(json, key); + } + + function readUint(string memory json, string memory key) internal returns (uint256) { + return vm.parseJsonUint(json, key); + } + + function readUintArray(string memory json, string memory key) internal returns (uint256[] memory) { + return vm.parseJsonUintArray(json, key); + } + + function readInt(string memory json, string memory key) internal returns (int256) { + return vm.parseJsonInt(json, key); + } + + function readIntArray(string memory json, string memory key) internal returns (int256[] memory) { + return vm.parseJsonIntArray(json, key); + } + + function readBytes32(string memory json, string memory key) internal returns (bytes32) { + return vm.parseJsonBytes32(json, key); + } + + function readBytes32Array(string memory json, string memory key) internal returns (bytes32[] memory) { + return vm.parseJsonBytes32Array(json, key); + } + + function readString(string memory json, string memory key) internal returns (string memory) { + return vm.parseJsonString(json, key); + } + + function readStringArray(string memory json, string memory key) internal returns (string[] memory) { + return vm.parseJsonStringArray(json, key); + } + + function readAddress(string memory json, string memory key) internal returns (address) { + return vm.parseJsonAddress(json, key); + } + + function readAddressArray(string memory json, string memory key) internal returns (address[] memory) { + return vm.parseJsonAddressArray(json, key); + } + + function readBool(string memory json, string memory key) internal returns (bool) { + return vm.parseJsonBool(json, key); + } + + function readBoolArray(string memory json, string memory key) internal returns (bool[] memory) { + return vm.parseJsonBoolArray(json, key); + } + + function readBytes(string memory json, string memory key) internal returns (bytes memory) { + return vm.parseJsonBytes(json, key); + } + + function readBytesArray(string memory json, string memory key) internal returns (bytes[] memory) { + return vm.parseJsonBytesArray(json, key); + } + + function serialize(string memory jsonKey, string memory key, bool value) internal returns (string memory) { + return vm.serializeBool(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, bool[] memory value) + internal + returns (string memory) + { + return vm.serializeBool(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, uint256 value) internal returns (string memory) { + return vm.serializeUint(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, uint256[] memory value) + internal + returns (string memory) + { + return vm.serializeUint(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, int256 value) internal returns (string memory) { + return vm.serializeInt(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, int256[] memory value) + internal + returns (string memory) + { + return vm.serializeInt(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, address value) internal returns (string memory) { + return vm.serializeAddress(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, address[] memory value) + internal + returns (string memory) + { + return vm.serializeAddress(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, bytes32 value) internal returns (string memory) { + return vm.serializeBytes32(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, bytes32[] memory value) + internal + returns (string memory) + { + return vm.serializeBytes32(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, bytes memory value) internal returns (string memory) { + return vm.serializeBytes(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, bytes[] memory value) + internal + returns (string memory) + { + return vm.serializeBytes(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, string memory value) + internal + returns (string memory) + { + return vm.serializeString(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, string[] memory value) + internal + returns (string memory) + { + return vm.serializeString(jsonKey, key, value); + } + + function write(string memory jsonKey, string memory path) internal { + vm.writeJson(jsonKey, path); + } + + function write(string memory jsonKey, string memory path, string memory valueKey) internal { + vm.writeJson(jsonKey, path, valueKey); + } +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdMath.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdMath.sol new file mode 100644 index 0000000000..459523bdac --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdMath.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +library stdMath { + int256 private constant INT256_MIN = -57896044618658097711785492504343953926634992332820282019728792003956564819968; + + function abs(int256 a) internal pure returns (uint256) { + // Required or it will fail when `a = type(int256).min` + if (a == INT256_MIN) { + return 57896044618658097711785492504343953926634992332820282019728792003956564819968; + } + + return uint256(a > 0 ? a : -a); + } + + function delta(uint256 a, uint256 b) internal pure returns (uint256) { + return a > b ? a - b : b - a; + } + + function delta(int256 a, int256 b) internal pure returns (uint256) { + // a and b are of the same sign + // this works thanks to two's complement, the left-most bit is the sign bit + if ((a ^ b) > -1) { + return delta(abs(a), abs(b)); + } + + // a and b are of opposite signs + return abs(a) + abs(b); + } + + function percentDelta(uint256 a, uint256 b) internal pure returns (uint256) { + uint256 absDelta = delta(a, b); + + return absDelta * 1e18 / b; + } + + function percentDelta(int256 a, int256 b) internal pure returns (uint256) { + uint256 absDelta = delta(a, b); + uint256 absB = abs(b); + + return absDelta * 1e18 / absB; + } +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdStorage.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdStorage.sol new file mode 100644 index 0000000000..708db32cdf --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdStorage.sol @@ -0,0 +1,331 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +import {Vm} from "./Vm.sol"; + +struct StdStorage { + mapping(address => mapping(bytes4 => mapping(bytes32 => uint256))) slots; + mapping(address => mapping(bytes4 => mapping(bytes32 => bool))) finds; + bytes32[] _keys; + bytes4 _sig; + uint256 _depth; + address _target; + bytes32 _set; +} + +library stdStorageSafe { + event SlotFound(address who, bytes4 fsig, bytes32 keysHash, uint256 slot); + event WARNING_UninitedSlot(address who, uint256 slot); + + Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + + function sigs(string memory sigStr) internal pure returns (bytes4) { + return bytes4(keccak256(bytes(sigStr))); + } + + /// @notice find an arbitrary storage slot given a function sig, input data, address of the contract and a value to check against + // slot complexity: + // if flat, will be bytes32(uint256(uint)); + // if map, will be keccak256(abi.encode(key, uint(slot))); + // if deep map, will be keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot))))); + // if map struct, will be bytes32(uint256(keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot)))))) + structFieldDepth); + function find(StdStorage storage self) internal returns (uint256) { + address who = self._target; + bytes4 fsig = self._sig; + uint256 field_depth = self._depth; + bytes32[] memory ins = self._keys; + + // calldata to test against + if (self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]) { + return self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]; + } + bytes memory cald = abi.encodePacked(fsig, flatten(ins)); + vm.record(); + bytes32 fdat; + { + (, bytes memory rdat) = who.staticcall(cald); + fdat = bytesToBytes32(rdat, 32 * field_depth); + } + + (bytes32[] memory reads,) = vm.accesses(address(who)); + if (reads.length == 1) { + bytes32 curr = vm.load(who, reads[0]); + if (curr == bytes32(0)) { + emit WARNING_UninitedSlot(who, uint256(reads[0])); + } + if (fdat != curr) { + require( + false, + "stdStorage find(StdStorage): Packed slot. This would cause dangerous overwriting and currently isn't supported." + ); + } + emit SlotFound(who, fsig, keccak256(abi.encodePacked(ins, field_depth)), uint256(reads[0])); + self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = uint256(reads[0]); + self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = true; + } else if (reads.length > 1) { + for (uint256 i = 0; i < reads.length; i++) { + bytes32 prev = vm.load(who, reads[i]); + if (prev == bytes32(0)) { + emit WARNING_UninitedSlot(who, uint256(reads[i])); + } + // store + vm.store(who, reads[i], bytes32(hex"1337")); + bool success; + bytes memory rdat; + { + (success, rdat) = who.staticcall(cald); + fdat = bytesToBytes32(rdat, 32 * field_depth); + } + + if (success && fdat == bytes32(hex"1337")) { + // we found which of the slots is the actual one + emit SlotFound(who, fsig, keccak256(abi.encodePacked(ins, field_depth)), uint256(reads[i])); + self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = uint256(reads[i]); + self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = true; + vm.store(who, reads[i], prev); + break; + } + vm.store(who, reads[i], prev); + } + } else { + revert("stdStorage find(StdStorage): No storage use detected for target."); + } + + require( + self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))], + "stdStorage find(StdStorage): Slot(s) not found." + ); + + delete self._target; + delete self._sig; + delete self._keys; + delete self._depth; + + return self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]; + } + + function target(StdStorage storage self, address _target) internal returns (StdStorage storage) { + self._target = _target; + return self; + } + + function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) { + self._sig = _sig; + return self; + } + + function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) { + self._sig = sigs(_sig); + return self; + } + + function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) { + self._keys.push(bytes32(uint256(uint160(who)))); + return self; + } + + function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) { + self._keys.push(bytes32(amt)); + return self; + } + + function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) { + self._keys.push(key); + return self; + } + + function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) { + self._depth = _depth; + return self; + } + + function read(StdStorage storage self) private returns (bytes memory) { + address t = self._target; + uint256 s = find(self); + return abi.encode(vm.load(t, bytes32(s))); + } + + function read_bytes32(StdStorage storage self) internal returns (bytes32) { + return abi.decode(read(self), (bytes32)); + } + + function read_bool(StdStorage storage self) internal returns (bool) { + int256 v = read_int(self); + if (v == 0) return false; + if (v == 1) return true; + revert("stdStorage read_bool(StdStorage): Cannot decode. Make sure you are reading a bool."); + } + + function read_address(StdStorage storage self) internal returns (address) { + return abi.decode(read(self), (address)); + } + + function read_uint(StdStorage storage self) internal returns (uint256) { + return abi.decode(read(self), (uint256)); + } + + function read_int(StdStorage storage self) internal returns (int256) { + return abi.decode(read(self), (int256)); + } + + function bytesToBytes32(bytes memory b, uint256 offset) private pure returns (bytes32) { + bytes32 out; + + uint256 max = b.length > 32 ? 32 : b.length; + for (uint256 i = 0; i < max; i++) { + out |= bytes32(b[offset + i] & 0xFF) >> (i * 8); + } + return out; + } + + function flatten(bytes32[] memory b) private pure returns (bytes memory) { + bytes memory result = new bytes(b.length * 32); + for (uint256 i = 0; i < b.length; i++) { + bytes32 k = b[i]; + /// @solidity memory-safe-assembly + assembly { + mstore(add(result, add(32, mul(32, i))), k) + } + } + + return result; + } +} + +library stdStorage { + Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + + function sigs(string memory sigStr) internal pure returns (bytes4) { + return stdStorageSafe.sigs(sigStr); + } + + function find(StdStorage storage self) internal returns (uint256) { + return stdStorageSafe.find(self); + } + + function target(StdStorage storage self, address _target) internal returns (StdStorage storage) { + return stdStorageSafe.target(self, _target); + } + + function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) { + return stdStorageSafe.sig(self, _sig); + } + + function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) { + return stdStorageSafe.sig(self, _sig); + } + + function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) { + return stdStorageSafe.with_key(self, who); + } + + function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) { + return stdStorageSafe.with_key(self, amt); + } + + function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) { + return stdStorageSafe.with_key(self, key); + } + + function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) { + return stdStorageSafe.depth(self, _depth); + } + + function checked_write(StdStorage storage self, address who) internal { + checked_write(self, bytes32(uint256(uint160(who)))); + } + + function checked_write(StdStorage storage self, uint256 amt) internal { + checked_write(self, bytes32(amt)); + } + + function checked_write_int(StdStorage storage self, int256 val) internal { + checked_write(self, bytes32(uint256(val))); + } + + function checked_write(StdStorage storage self, bool write) internal { + bytes32 t; + /// @solidity memory-safe-assembly + assembly { + t := write + } + checked_write(self, t); + } + + function checked_write(StdStorage storage self, bytes32 set) internal { + address who = self._target; + bytes4 fsig = self._sig; + uint256 field_depth = self._depth; + bytes32[] memory ins = self._keys; + + bytes memory cald = abi.encodePacked(fsig, flatten(ins)); + if (!self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]) { + find(self); + } + bytes32 slot = bytes32(self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]); + + bytes32 fdat; + { + (, bytes memory rdat) = who.staticcall(cald); + fdat = bytesToBytes32(rdat, 32 * field_depth); + } + bytes32 curr = vm.load(who, slot); + + if (fdat != curr) { + require( + false, + "stdStorage find(StdStorage): Packed slot. This would cause dangerous overwriting and currently isn't supported." + ); + } + vm.store(who, slot, set); + delete self._target; + delete self._sig; + delete self._keys; + delete self._depth; + } + + function read_bytes32(StdStorage storage self) internal returns (bytes32) { + return stdStorageSafe.read_bytes32(self); + } + + function read_bool(StdStorage storage self) internal returns (bool) { + return stdStorageSafe.read_bool(self); + } + + function read_address(StdStorage storage self) internal returns (address) { + return stdStorageSafe.read_address(self); + } + + function read_uint(StdStorage storage self) internal returns (uint256) { + return stdStorageSafe.read_uint(self); + } + + function read_int(StdStorage storage self) internal returns (int256) { + return stdStorageSafe.read_int(self); + } + + // Private function so needs to be copied over + function bytesToBytes32(bytes memory b, uint256 offset) private pure returns (bytes32) { + bytes32 out; + + uint256 max = b.length > 32 ? 32 : b.length; + for (uint256 i = 0; i < max; i++) { + out |= bytes32(b[offset + i] & 0xFF) >> (i * 8); + } + return out; + } + + // Private function so needs to be copied over + function flatten(bytes32[] memory b) private pure returns (bytes memory) { + bytes memory result = new bytes(b.length * 32); + for (uint256 i = 0; i < b.length; i++) { + bytes32 k = b[i]; + /// @solidity memory-safe-assembly + assembly { + mstore(add(result, add(32, mul(32, i))), k) + } + } + + return result; + } +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdStyle.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdStyle.sol new file mode 100644 index 0000000000..d371e0c60a --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdStyle.sol @@ -0,0 +1,333 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.4.22 <0.9.0; + +import {VmSafe} from "./Vm.sol"; + +library StdStyle { + VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); + + string constant RED = "\u001b[91m"; + string constant GREEN = "\u001b[92m"; + string constant YELLOW = "\u001b[93m"; + string constant BLUE = "\u001b[94m"; + string constant MAGENTA = "\u001b[95m"; + string constant CYAN = "\u001b[96m"; + string constant BOLD = "\u001b[1m"; + string constant DIM = "\u001b[2m"; + string constant ITALIC = "\u001b[3m"; + string constant UNDERLINE = "\u001b[4m"; + string constant INVERSE = "\u001b[7m"; + string constant RESET = "\u001b[0m"; + + function styleConcat(string memory style, string memory self) private pure returns (string memory) { + return string(abi.encodePacked(style, self, RESET)); + } + + function red(string memory self) internal pure returns (string memory) { + return styleConcat(RED, self); + } + + function red(uint256 self) internal pure returns (string memory) { + return red(vm.toString(self)); + } + + function red(int256 self) internal pure returns (string memory) { + return red(vm.toString(self)); + } + + function red(address self) internal pure returns (string memory) { + return red(vm.toString(self)); + } + + function red(bool self) internal pure returns (string memory) { + return red(vm.toString(self)); + } + + function redBytes(bytes memory self) internal pure returns (string memory) { + return red(vm.toString(self)); + } + + function redBytes32(bytes32 self) internal pure returns (string memory) { + return red(vm.toString(self)); + } + + function green(string memory self) internal pure returns (string memory) { + return styleConcat(GREEN, self); + } + + function green(uint256 self) internal pure returns (string memory) { + return green(vm.toString(self)); + } + + function green(int256 self) internal pure returns (string memory) { + return green(vm.toString(self)); + } + + function green(address self) internal pure returns (string memory) { + return green(vm.toString(self)); + } + + function green(bool self) internal pure returns (string memory) { + return green(vm.toString(self)); + } + + function greenBytes(bytes memory self) internal pure returns (string memory) { + return green(vm.toString(self)); + } + + function greenBytes32(bytes32 self) internal pure returns (string memory) { + return green(vm.toString(self)); + } + + function yellow(string memory self) internal pure returns (string memory) { + return styleConcat(YELLOW, self); + } + + function yellow(uint256 self) internal pure returns (string memory) { + return yellow(vm.toString(self)); + } + + function yellow(int256 self) internal pure returns (string memory) { + return yellow(vm.toString(self)); + } + + function yellow(address self) internal pure returns (string memory) { + return yellow(vm.toString(self)); + } + + function yellow(bool self) internal pure returns (string memory) { + return yellow(vm.toString(self)); + } + + function yellowBytes(bytes memory self) internal pure returns (string memory) { + return yellow(vm.toString(self)); + } + + function yellowBytes32(bytes32 self) internal pure returns (string memory) { + return yellow(vm.toString(self)); + } + + function blue(string memory self) internal pure returns (string memory) { + return styleConcat(BLUE, self); + } + + function blue(uint256 self) internal pure returns (string memory) { + return blue(vm.toString(self)); + } + + function blue(int256 self) internal pure returns (string memory) { + return blue(vm.toString(self)); + } + + function blue(address self) internal pure returns (string memory) { + return blue(vm.toString(self)); + } + + function blue(bool self) internal pure returns (string memory) { + return blue(vm.toString(self)); + } + + function blueBytes(bytes memory self) internal pure returns (string memory) { + return blue(vm.toString(self)); + } + + function blueBytes32(bytes32 self) internal pure returns (string memory) { + return blue(vm.toString(self)); + } + + function magenta(string memory self) internal pure returns (string memory) { + return styleConcat(MAGENTA, self); + } + + function magenta(uint256 self) internal pure returns (string memory) { + return magenta(vm.toString(self)); + } + + function magenta(int256 self) internal pure returns (string memory) { + return magenta(vm.toString(self)); + } + + function magenta(address self) internal pure returns (string memory) { + return magenta(vm.toString(self)); + } + + function magenta(bool self) internal pure returns (string memory) { + return magenta(vm.toString(self)); + } + + function magentaBytes(bytes memory self) internal pure returns (string memory) { + return magenta(vm.toString(self)); + } + + function magentaBytes32(bytes32 self) internal pure returns (string memory) { + return magenta(vm.toString(self)); + } + + function cyan(string memory self) internal pure returns (string memory) { + return styleConcat(CYAN, self); + } + + function cyan(uint256 self) internal pure returns (string memory) { + return cyan(vm.toString(self)); + } + + function cyan(int256 self) internal pure returns (string memory) { + return cyan(vm.toString(self)); + } + + function cyan(address self) internal pure returns (string memory) { + return cyan(vm.toString(self)); + } + + function cyan(bool self) internal pure returns (string memory) { + return cyan(vm.toString(self)); + } + + function cyanBytes(bytes memory self) internal pure returns (string memory) { + return cyan(vm.toString(self)); + } + + function cyanBytes32(bytes32 self) internal pure returns (string memory) { + return cyan(vm.toString(self)); + } + + function bold(string memory self) internal pure returns (string memory) { + return styleConcat(BOLD, self); + } + + function bold(uint256 self) internal pure returns (string memory) { + return bold(vm.toString(self)); + } + + function bold(int256 self) internal pure returns (string memory) { + return bold(vm.toString(self)); + } + + function bold(address self) internal pure returns (string memory) { + return bold(vm.toString(self)); + } + + function bold(bool self) internal pure returns (string memory) { + return bold(vm.toString(self)); + } + + function boldBytes(bytes memory self) internal pure returns (string memory) { + return bold(vm.toString(self)); + } + + function boldBytes32(bytes32 self) internal pure returns (string memory) { + return bold(vm.toString(self)); + } + + function dim(string memory self) internal pure returns (string memory) { + return styleConcat(DIM, self); + } + + function dim(uint256 self) internal pure returns (string memory) { + return dim(vm.toString(self)); + } + + function dim(int256 self) internal pure returns (string memory) { + return dim(vm.toString(self)); + } + + function dim(address self) internal pure returns (string memory) { + return dim(vm.toString(self)); + } + + function dim(bool self) internal pure returns (string memory) { + return dim(vm.toString(self)); + } + + function dimBytes(bytes memory self) internal pure returns (string memory) { + return dim(vm.toString(self)); + } + + function dimBytes32(bytes32 self) internal pure returns (string memory) { + return dim(vm.toString(self)); + } + + function italic(string memory self) internal pure returns (string memory) { + return styleConcat(ITALIC, self); + } + + function italic(uint256 self) internal pure returns (string memory) { + return italic(vm.toString(self)); + } + + function italic(int256 self) internal pure returns (string memory) { + return italic(vm.toString(self)); + } + + function italic(address self) internal pure returns (string memory) { + return italic(vm.toString(self)); + } + + function italic(bool self) internal pure returns (string memory) { + return italic(vm.toString(self)); + } + + function italicBytes(bytes memory self) internal pure returns (string memory) { + return italic(vm.toString(self)); + } + + function italicBytes32(bytes32 self) internal pure returns (string memory) { + return italic(vm.toString(self)); + } + + function underline(string memory self) internal pure returns (string memory) { + return styleConcat(UNDERLINE, self); + } + + function underline(uint256 self) internal pure returns (string memory) { + return underline(vm.toString(self)); + } + + function underline(int256 self) internal pure returns (string memory) { + return underline(vm.toString(self)); + } + + function underline(address self) internal pure returns (string memory) { + return underline(vm.toString(self)); + } + + function underline(bool self) internal pure returns (string memory) { + return underline(vm.toString(self)); + } + + function underlineBytes(bytes memory self) internal pure returns (string memory) { + return underline(vm.toString(self)); + } + + function underlineBytes32(bytes32 self) internal pure returns (string memory) { + return underline(vm.toString(self)); + } + + function inverse(string memory self) internal pure returns (string memory) { + return styleConcat(INVERSE, self); + } + + function inverse(uint256 self) internal pure returns (string memory) { + return inverse(vm.toString(self)); + } + + function inverse(int256 self) internal pure returns (string memory) { + return inverse(vm.toString(self)); + } + + function inverse(address self) internal pure returns (string memory) { + return inverse(vm.toString(self)); + } + + function inverse(bool self) internal pure returns (string memory) { + return inverse(vm.toString(self)); + } + + function inverseBytes(bytes memory self) internal pure returns (string memory) { + return inverse(vm.toString(self)); + } + + function inverseBytes32(bytes32 self) internal pure returns (string memory) { + return inverse(vm.toString(self)); + } +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdUtils.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdUtils.sol new file mode 100644 index 0000000000..ad9566ecc9 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/StdUtils.sol @@ -0,0 +1,198 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +import {IMulticall3} from "./interfaces/IMulticall3.sol"; +import {VmSafe} from "./Vm.sol"; + +abstract contract StdUtils { + /*////////////////////////////////////////////////////////////////////////// + CONSTANTS + //////////////////////////////////////////////////////////////////////////*/ + + IMulticall3 private constant multicall = IMulticall3(0xcA11bde05977b3631167028862bE2a173976CA11); + VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); + address private constant CONSOLE2_ADDRESS = 0x000000000000000000636F6e736F6c652e6c6f67; + uint256 private constant INT256_MIN_ABS = + 57896044618658097711785492504343953926634992332820282019728792003956564819968; + uint256 private constant SECP256K1_ORDER = + 115792089237316195423570985008687907852837564279074904382605163141518161494337; + uint256 private constant UINT256_MAX = + 115792089237316195423570985008687907853269984665640564039457584007913129639935; + + // Used by default when deploying with create2, https://github.com/Arachnid/deterministic-deployment-proxy. + address private constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C; + + /*////////////////////////////////////////////////////////////////////////// + INTERNAL FUNCTIONS + //////////////////////////////////////////////////////////////////////////*/ + + function _bound(uint256 x, uint256 min, uint256 max) internal pure virtual returns (uint256 result) { + require(min <= max, "StdUtils bound(uint256,uint256,uint256): Max is less than min."); + // If x is between min and max, return x directly. This is to ensure that dictionary values + // do not get shifted if the min is nonzero. More info: https://github.com/foundry-rs/forge-std/issues/188 + if (x >= min && x <= max) return x; + + uint256 size = max - min + 1; + + // If the value is 0, 1, 2, 3, wrap that to min, min+1, min+2, min+3. Similarly for the UINT256_MAX side. + // This helps ensure coverage of the min/max values. + if (x <= 3 && size > x) return min + x; + if (x >= UINT256_MAX - 3 && size > UINT256_MAX - x) return max - (UINT256_MAX - x); + + // Otherwise, wrap x into the range [min, max], i.e. the range is inclusive. + if (x > max) { + uint256 diff = x - max; + uint256 rem = diff % size; + if (rem == 0) return max; + result = min + rem - 1; + } else if (x < min) { + uint256 diff = min - x; + uint256 rem = diff % size; + if (rem == 0) return min; + result = max - rem + 1; + } + } + + function bound(uint256 x, uint256 min, uint256 max) internal view virtual returns (uint256 result) { + result = _bound(x, min, max); + console2_log("Bound Result", result); + } + + function _bound(int256 x, int256 min, int256 max) internal pure virtual returns (int256 result) { + require(min <= max, "StdUtils bound(int256,int256,int256): Max is less than min."); + + // Shifting all int256 values to uint256 to use _bound function. The range of two types are: + // int256 : -(2**255) ~ (2**255 - 1) + // uint256: 0 ~ (2**256 - 1) + // So, add 2**255, INT256_MIN_ABS to the integer values. + // + // If the given integer value is -2**255, we cannot use `-uint256(-x)` because of the overflow. + // So, use `~uint256(x) + 1` instead. + uint256 _x = x < 0 ? (INT256_MIN_ABS - ~uint256(x) - 1) : (uint256(x) + INT256_MIN_ABS); + uint256 _min = min < 0 ? (INT256_MIN_ABS - ~uint256(min) - 1) : (uint256(min) + INT256_MIN_ABS); + uint256 _max = max < 0 ? (INT256_MIN_ABS - ~uint256(max) - 1) : (uint256(max) + INT256_MIN_ABS); + + uint256 y = _bound(_x, _min, _max); + + // To move it back to int256 value, subtract INT256_MIN_ABS at here. + result = y < INT256_MIN_ABS ? int256(~(INT256_MIN_ABS - y) + 1) : int256(y - INT256_MIN_ABS); + } + + function bound(int256 x, int256 min, int256 max) internal view virtual returns (int256 result) { + result = _bound(x, min, max); + console2_log("Bound result", vm.toString(result)); + } + + function boundPrivateKey(uint256 privateKey) internal pure virtual returns (uint256 result) { + result = _bound(privateKey, 1, SECP256K1_ORDER - 1); + } + + function bytesToUint(bytes memory b) internal pure virtual returns (uint256) { + require(b.length <= 32, "StdUtils bytesToUint(bytes): Bytes length exceeds 32."); + return abi.decode(abi.encodePacked(new bytes(32 - b.length), b), (uint256)); + } + + /// @dev Compute the address a contract will be deployed at for a given deployer address and nonce + /// @notice adapted from Solmate implementation (https://github.com/Rari-Capital/solmate/blob/main/src/utils/LibRLP.sol) + function computeCreateAddress(address deployer, uint256 nonce) internal pure virtual returns (address) { + // forgefmt: disable-start + // The integer zero is treated as an empty byte string, and as a result it only has a length prefix, 0x80, computed via 0x80 + 0. + // A one byte integer uses its own value as its length prefix, there is no additional "0x80 + length" prefix that comes before it. + if (nonce == 0x00) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, bytes1(0x80)))); + if (nonce <= 0x7f) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, uint8(nonce)))); + + // Nonces greater than 1 byte all follow a consistent encoding scheme, where each value is preceded by a prefix of 0x80 + length. + if (nonce <= 2**8 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd7), bytes1(0x94), deployer, bytes1(0x81), uint8(nonce)))); + if (nonce <= 2**16 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd8), bytes1(0x94), deployer, bytes1(0x82), uint16(nonce)))); + if (nonce <= 2**24 - 1) return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xd9), bytes1(0x94), deployer, bytes1(0x83), uint24(nonce)))); + // forgefmt: disable-end + + // More details about RLP encoding can be found here: https://eth.wiki/fundamentals/rlp + // 0xda = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x84 ++ nonce) + // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex) + // 0x84 = 0x80 + 0x04 (0x04 = the bytes length of the nonce, 4 bytes, in hex) + // We assume nobody can have a nonce large enough to require more than 32 bytes. + return addressFromLast20Bytes( + keccak256(abi.encodePacked(bytes1(0xda), bytes1(0x94), deployer, bytes1(0x84), uint32(nonce))) + ); + } + + function computeCreate2Address(bytes32 salt, bytes32 initcodeHash, address deployer) + internal + pure + virtual + returns (address) + { + return addressFromLast20Bytes(keccak256(abi.encodePacked(bytes1(0xff), deployer, salt, initcodeHash))); + } + + /// @dev returns the address of a contract created with CREATE2 using the default CREATE2 deployer + function computeCreate2Address(bytes32 salt, bytes32 initCodeHash) internal pure returns (address) { + return computeCreate2Address(salt, initCodeHash, CREATE2_FACTORY); + } + + /// @dev returns the hash of the init code (creation code + no args) used in CREATE2 with no constructor arguments + /// @param creationCode the creation code of a contract C, as returned by type(C).creationCode + function hashInitCode(bytes memory creationCode) internal pure returns (bytes32) { + return hashInitCode(creationCode, ""); + } + + /// @dev returns the hash of the init code (creation code + ABI-encoded args) used in CREATE2 + /// @param creationCode the creation code of a contract C, as returned by type(C).creationCode + /// @param args the ABI-encoded arguments to the constructor of C + function hashInitCode(bytes memory creationCode, bytes memory args) internal pure returns (bytes32) { + return keccak256(abi.encodePacked(creationCode, args)); + } + + // Performs a single call with Multicall3 to query the ERC-20 token balances of the given addresses. + function getTokenBalances(address token, address[] memory addresses) + internal + virtual + returns (uint256[] memory balances) + { + uint256 tokenCodeSize; + assembly { + tokenCodeSize := extcodesize(token) + } + require(tokenCodeSize > 0, "StdUtils getTokenBalances(address,address[]): Token address is not a contract."); + + // ABI encode the aggregate call to Multicall3. + uint256 length = addresses.length; + IMulticall3.Call[] memory calls = new IMulticall3.Call[](length); + for (uint256 i = 0; i < length; ++i) { + // 0x70a08231 = bytes4("balanceOf(address)")) + calls[i] = IMulticall3.Call({target: token, callData: abi.encodeWithSelector(0x70a08231, (addresses[i]))}); + } + + // Make the aggregate call. + (, bytes[] memory returnData) = multicall.aggregate(calls); + + // ABI decode the return data and return the balances. + balances = new uint256[](length); + for (uint256 i = 0; i < length; ++i) { + balances[i] = abi.decode(returnData[i], (uint256)); + } + } + + /*////////////////////////////////////////////////////////////////////////// + PRIVATE FUNCTIONS + //////////////////////////////////////////////////////////////////////////*/ + + function addressFromLast20Bytes(bytes32 bytesValue) private pure returns (address) { + return address(uint160(uint256(bytesValue))); + } + + // Used to prevent the compilation of console, which shortens the compilation time when console is not used elsewhere. + + function console2_log(string memory p0, uint256 p1) private view { + (bool status,) = address(CONSOLE2_ADDRESS).staticcall(abi.encodeWithSignature("log(string,uint256)", p0, p1)); + status; + } + + function console2_log(string memory p0, string memory p1) private view { + (bool status,) = address(CONSOLE2_ADDRESS).staticcall(abi.encodeWithSignature("log(string,string)", p0, p1)); + status; + } +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/Test.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/Test.sol new file mode 100644 index 0000000000..743c1834dd --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/Test.sol @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +// šŸ’¬ ABOUT +// Forge Std's default Test. + +// 🧩 MODULES +import {console} from "./console.sol"; +import {console2} from "./console2.sol"; +import {safeconsole} from "./safeconsole.sol"; +import {StdAssertions} from "./StdAssertions.sol"; +import {StdChains} from "./StdChains.sol"; +import {StdCheats} from "./StdCheats.sol"; +import {stdError} from "./StdError.sol"; +import {StdInvariant} from "./StdInvariant.sol"; +import {stdJson} from "./StdJson.sol"; +import {stdMath} from "./StdMath.sol"; +import {StdStorage, stdStorage} from "./StdStorage.sol"; +import {StdStyle} from "./StdStyle.sol"; +import {StdUtils} from "./StdUtils.sol"; +import {Vm} from "./Vm.sol"; + +// šŸ“¦ BOILERPLATE +import {TestBase} from "./Base.sol"; +import {DSTest} from "ds-test/test.sol"; + +// ā­ļø TEST +abstract contract Test is TestBase, DSTest, StdAssertions, StdChains, StdCheats, StdInvariant, StdUtils { +// Note: IS_TEST() must return true. +// Note: Must have failure system, https://github.com/dapphub/ds-test/blob/cd98eff28324bfac652e63a239a60632a761790b/src/test.sol#L39-L76. +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/Vm.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/Vm.sol new file mode 100644 index 0000000000..aa173f0b8e --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/Vm.sol @@ -0,0 +1,542 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +// Cheatcodes are marked as view/pure/none using the following rules: +// 0. A call's observable behaviour includes its return value, logs, reverts and state writes, +// 1. If you can influence a later call's observable behaviour, you're neither `view` nor `pure (you are modifying some state be it the EVM, interpreter, filesystem, etc), +// 2. Otherwise if you can be influenced by an earlier call, or if reading some state, you're `view`, +// 3. Otherwise you're `pure`. + +interface VmSafe { + enum CallerMode { + None, + Broadcast, + RecurrentBroadcast, + Prank, + RecurrentPrank + } + + struct Log { + bytes32[] topics; + bytes data; + address emitter; + } + + struct Rpc { + string key; + string url; + } + + struct DirEntry { + string errorMessage; + string path; + uint64 depth; + bool isDir; + bool isSymlink; + } + + struct FsMetadata { + bool isDir; + bool isSymlink; + uint256 length; + bool readOnly; + uint256 modified; + uint256 accessed; + uint256 created; + } + + struct Wallet { + address addr; + uint256 publicKeyX; + uint256 publicKeyY; + uint256 privateKey; + } + + // Derives a private key from the name, labels the account with that name, and returns the wallet + function createWallet(string calldata walletLabel) external returns (Wallet memory wallet); + // Generates a wallet from the private key and returns the wallet + function createWallet(uint256 privateKey) external returns (Wallet memory wallet); + // Generates a wallet from the private key, labels the account with that name, and returns the wallet + function createWallet(uint256 privateKey, string calldata walletLabel) external returns (Wallet memory wallet); + // Signs data, (Wallet, digest) => (v, r, s) + function sign(Wallet calldata wallet, bytes32 digest) external returns (uint8 v, bytes32 r, bytes32 s); + // Get nonce for a Wallet + function getNonce(Wallet calldata wallet) external returns (uint64 nonce); + + // Loads a storage slot from an address + function load(address target, bytes32 slot) external view returns (bytes32 data); + // Signs data + function sign(uint256 privateKey, bytes32 digest) external pure returns (uint8 v, bytes32 r, bytes32 s); + // Gets the address for a given private key + function addr(uint256 privateKey) external pure returns (address keyAddr); + // Gets the nonce of an account + function getNonce(address account) external view returns (uint64 nonce); + // Performs a foreign function call via the terminal + function ffi(string[] calldata commandInput) external returns (bytes memory result); + // Sets environment variables + function setEnv(string calldata name, string calldata value) external; + // Reads environment variables, (name) => (value) + function envBool(string calldata name) external view returns (bool value); + function envUint(string calldata name) external view returns (uint256 value); + function envInt(string calldata name) external view returns (int256 value); + function envAddress(string calldata name) external view returns (address value); + function envBytes32(string calldata name) external view returns (bytes32 value); + function envString(string calldata name) external view returns (string memory value); + function envBytes(string calldata name) external view returns (bytes memory value); + // Reads environment variables as arrays + function envBool(string calldata name, string calldata delim) external view returns (bool[] memory value); + function envUint(string calldata name, string calldata delim) external view returns (uint256[] memory value); + function envInt(string calldata name, string calldata delim) external view returns (int256[] memory value); + function envAddress(string calldata name, string calldata delim) external view returns (address[] memory value); + function envBytes32(string calldata name, string calldata delim) external view returns (bytes32[] memory value); + function envString(string calldata name, string calldata delim) external view returns (string[] memory value); + function envBytes(string calldata name, string calldata delim) external view returns (bytes[] memory value); + // Read environment variables with default value + function envOr(string calldata name, bool defaultValue) external returns (bool value); + function envOr(string calldata name, uint256 defaultValue) external returns (uint256 value); + function envOr(string calldata name, int256 defaultValue) external returns (int256 value); + function envOr(string calldata name, address defaultValue) external returns (address value); + function envOr(string calldata name, bytes32 defaultValue) external returns (bytes32 value); + function envOr(string calldata name, string calldata defaultValue) external returns (string memory value); + function envOr(string calldata name, bytes calldata defaultValue) external returns (bytes memory value); + // Read environment variables as arrays with default value + function envOr(string calldata name, string calldata delim, bool[] calldata defaultValue) + external + returns (bool[] memory value); + function envOr(string calldata name, string calldata delim, uint256[] calldata defaultValue) + external + returns (uint256[] memory value); + function envOr(string calldata name, string calldata delim, int256[] calldata defaultValue) + external + returns (int256[] memory value); + function envOr(string calldata name, string calldata delim, address[] calldata defaultValue) + external + returns (address[] memory value); + function envOr(string calldata name, string calldata delim, bytes32[] calldata defaultValue) + external + returns (bytes32[] memory value); + function envOr(string calldata name, string calldata delim, string[] calldata defaultValue) + external + returns (string[] memory value); + function envOr(string calldata name, string calldata delim, bytes[] calldata defaultValue) + external + returns (bytes[] memory value); + // Records all storage reads and writes + function record() external; + // Gets all accessed reads and write slot from a recording session, for a given address + function accesses(address target) external returns (bytes32[] memory readSlots, bytes32[] memory writeSlots); + // Gets the _creation_ bytecode from an artifact file. Takes in the relative path to the json file + function getCode(string calldata artifactPath) external view returns (bytes memory creationBytecode); + // Gets the _deployed_ bytecode from an artifact file. Takes in the relative path to the json file + function getDeployedCode(string calldata artifactPath) external view returns (bytes memory runtimeBytecode); + // Labels an address in call traces + function label(address account, string calldata newLabel) external; + // Gets the label for the specified address + function getLabel(address account) external returns (string memory currentLabel); + // Using the address that calls the test contract, has the next call (at this call depth only) create a transaction that can later be signed and sent onchain + function broadcast() external; + // Has the next call (at this call depth only) create a transaction with the address provided as the sender that can later be signed and sent onchain + function broadcast(address signer) external; + // Has the next call (at this call depth only) create a transaction with the private key provided as the sender that can later be signed and sent onchain + function broadcast(uint256 privateKey) external; + // Using the address that calls the test contract, has all subsequent calls (at this call depth only) create transactions that can later be signed and sent onchain + function startBroadcast() external; + // Has all subsequent calls (at this call depth only) create transactions with the address provided that can later be signed and sent onchain + function startBroadcast(address signer) external; + // Has all subsequent calls (at this call depth only) create transactions with the private key provided that can later be signed and sent onchain + function startBroadcast(uint256 privateKey) external; + // Stops collecting onchain transactions + function stopBroadcast() external; + + // Get the path of the current project root. + function projectRoot() external view returns (string memory path); + // Reads the entire content of file to string. `path` is relative to the project root. + function readFile(string calldata path) external view returns (string memory data); + // Reads the entire content of file as binary. `path` is relative to the project root. + function readFileBinary(string calldata path) external view returns (bytes memory data); + // Reads next line of file to string. + function readLine(string calldata path) external view returns (string memory line); + // Writes data to file, creating a file if it does not exist, and entirely replacing its contents if it does. + // `path` is relative to the project root. + function writeFile(string calldata path, string calldata data) external; + // Writes binary data to a file, creating a file if it does not exist, and entirely replacing its contents if it does. + // `path` is relative to the project root. + function writeFileBinary(string calldata path, bytes calldata data) external; + // Writes line to file, creating a file if it does not exist. + // `path` is relative to the project root. + function writeLine(string calldata path, string calldata data) external; + // Copies the contents of one file to another. This function will **overwrite** the contents of `to`. + // On success, the total number of bytes copied is returned and it is equal to the length of the `to` file as reported by `metadata`. + // Both `from` and `to` are relative to the project root. + function copyFile(string calldata from, string calldata to) external returns (uint64 copied); + // Closes file for reading, resetting the offset and allowing to read it from beginning with readLine. + // `path` is relative to the project root. + function closeFile(string calldata path) external; + // Removes a file from the filesystem. + // This cheatcode will revert in the following situations, but is not limited to just these cases: + // - `path` points to a directory. + // - The file doesn't exist. + // - The user lacks permissions to remove the file. + // `path` is relative to the project root. + function removeFile(string calldata path) external; + // Creates a new, empty directory at the provided path. + // This cheatcode will revert in the following situations, but is not limited to just these cases: + // - User lacks permissions to modify `path`. + // - A parent of the given path doesn't exist and `recursive` is false. + // - `path` already exists and `recursive` is false. + // `path` is relative to the project root. + function createDir(string calldata path, bool recursive) external; + // Removes a directory at the provided path. + // This cheatcode will revert in the following situations, but is not limited to just these cases: + // - `path` doesn't exist. + // - `path` isn't a directory. + // - User lacks permissions to modify `path`. + // - The directory is not empty and `recursive` is false. + // `path` is relative to the project root. + function removeDir(string calldata path, bool recursive) external; + // Reads the directory at the given path recursively, up to `max_depth`. + // `max_depth` defaults to 1, meaning only the direct children of the given directory will be returned. + // Follows symbolic links if `follow_links` is true. + function readDir(string calldata path) external view returns (DirEntry[] memory entries); + function readDir(string calldata path, uint64 maxDepth) external view returns (DirEntry[] memory entries); + function readDir(string calldata path, uint64 maxDepth, bool followLinks) + external + view + returns (DirEntry[] memory entries); + // Reads a symbolic link, returning the path that the link points to. + // This cheatcode will revert in the following situations, but is not limited to just these cases: + // - `path` is not a symbolic link. + // - `path` does not exist. + function readLink(string calldata linkPath) external view returns (string memory targetPath); + // Given a path, query the file system to get information about a file, directory, etc. + function fsMetadata(string calldata path) external view returns (FsMetadata memory metadata); + + // Convert values to a string + function toString(address value) external pure returns (string memory stringifiedValue); + function toString(bytes calldata value) external pure returns (string memory stringifiedValue); + function toString(bytes32 value) external pure returns (string memory stringifiedValue); + function toString(bool value) external pure returns (string memory stringifiedValue); + function toString(uint256 value) external pure returns (string memory stringifiedValue); + function toString(int256 value) external pure returns (string memory stringifiedValue); + // Convert values from a string + function parseBytes(string calldata stringifiedValue) external pure returns (bytes memory parsedValue); + function parseAddress(string calldata stringifiedValue) external pure returns (address parsedValue); + function parseUint(string calldata stringifiedValue) external pure returns (uint256 parsedValue); + function parseInt(string calldata stringifiedValue) external pure returns (int256 parsedValue); + function parseBytes32(string calldata stringifiedValue) external pure returns (bytes32 parsedValue); + function parseBool(string calldata stringifiedValue) external pure returns (bool parsedValue); + // Record all the transaction logs + function recordLogs() external; + // Gets all the recorded logs + function getRecordedLogs() external returns (Log[] memory logs); + // Derive a private key from a provided mnenomic string (or mnenomic file path) at the derivation path m/44'/60'/0'/0/{index} + function deriveKey(string calldata mnemonic, uint32 index) external pure returns (uint256 privateKey); + // Derive a private key from a provided mnenomic string (or mnenomic file path) at {derivationPath}{index} + function deriveKey(string calldata mnemonic, string calldata derivationPath, uint32 index) + external + pure + returns (uint256 privateKey); + // Adds a private key to the local forge wallet and returns the address + function rememberKey(uint256 privateKey) external returns (address keyAddr); + // + // parseJson + // + // ---- + // In case the returned value is a JSON object, it's encoded as a ABI-encoded tuple. As JSON objects + // don't have the notion of ordered, but tuples do, they JSON object is encoded with it's fields ordered in + // ALPHABETICAL order. That means that in order to successfully decode the tuple, we need to define a tuple that + // encodes the fields in the same order, which is alphabetical. In the case of Solidity structs, they are encoded + // as tuples, with the attributes in the order in which they are defined. + // For example: json = { 'a': 1, 'b': 0xa4tb......3xs} + // a: uint256 + // b: address + // To decode that json, we need to define a struct or a tuple as follows: + // struct json = { uint256 a; address b; } + // If we defined a json struct with the opposite order, meaning placing the address b first, it would try to + // decode the tuple in that order, and thus fail. + // ---- + // Given a string of JSON, return it as ABI-encoded + function parseJson(string calldata json, string calldata key) external pure returns (bytes memory abiEncodedData); + function parseJson(string calldata json) external pure returns (bytes memory abiEncodedData); + + // The following parseJson cheatcodes will do type coercion, for the type that they indicate. + // For example, parseJsonUint will coerce all values to a uint256. That includes stringified numbers '12' + // and hex numbers '0xEF'. + // Type coercion works ONLY for discrete values or arrays. That means that the key must return a value or array, not + // a JSON object. + function parseJsonUint(string calldata json, string calldata key) external returns (uint256); + function parseJsonUintArray(string calldata json, string calldata key) external returns (uint256[] memory); + function parseJsonInt(string calldata json, string calldata key) external returns (int256); + function parseJsonIntArray(string calldata json, string calldata key) external returns (int256[] memory); + function parseJsonBool(string calldata json, string calldata key) external returns (bool); + function parseJsonBoolArray(string calldata json, string calldata key) external returns (bool[] memory); + function parseJsonAddress(string calldata json, string calldata key) external returns (address); + function parseJsonAddressArray(string calldata json, string calldata key) external returns (address[] memory); + function parseJsonString(string calldata json, string calldata key) external returns (string memory); + function parseJsonStringArray(string calldata json, string calldata key) external returns (string[] memory); + function parseJsonBytes(string calldata json, string calldata key) external returns (bytes memory); + function parseJsonBytesArray(string calldata json, string calldata key) external returns (bytes[] memory); + function parseJsonBytes32(string calldata json, string calldata key) external returns (bytes32); + function parseJsonBytes32Array(string calldata json, string calldata key) external returns (bytes32[] memory); + + // Checks if a key exists in a JSON or TOML object. + function keyExists(string calldata json, string calldata key) external view returns (bool); + + // Returns array of keys for a JSON object + function parseJsonKeys(string calldata json, string calldata key) external returns (string[] memory keys); + + // Serialize a key and value to a JSON object stored in-memory that can be later written to a file + // It returns the stringified version of the specific JSON file up to that moment. + function serializeBool(string calldata objectKey, string calldata valueKey, bool value) + external + returns (string memory json); + function serializeUint(string calldata objectKey, string calldata valueKey, uint256 value) + external + returns (string memory json); + function serializeInt(string calldata objectKey, string calldata valueKey, int256 value) + external + returns (string memory json); + function serializeAddress(string calldata objectKey, string calldata valueKey, address value) + external + returns (string memory json); + function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32 value) + external + returns (string memory json); + function serializeString(string calldata objectKey, string calldata valueKey, string calldata value) + external + returns (string memory json); + function serializeBytes(string calldata objectKey, string calldata valueKey, bytes calldata value) + external + returns (string memory json); + + function serializeBool(string calldata objectKey, string calldata valueKey, bool[] calldata values) + external + returns (string memory json); + function serializeUint(string calldata objectKey, string calldata valueKey, uint256[] calldata values) + external + returns (string memory json); + function serializeInt(string calldata objectKey, string calldata valueKey, int256[] calldata values) + external + returns (string memory json); + function serializeAddress(string calldata objectKey, string calldata valueKey, address[] calldata values) + external + returns (string memory json); + function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32[] calldata values) + external + returns (string memory json); + function serializeString(string calldata objectKey, string calldata valueKey, string[] calldata values) + external + returns (string memory json); + function serializeBytes(string calldata objectKey, string calldata valueKey, bytes[] calldata values) + external + returns (string memory json); + + // + // writeJson + // + // ---- + // Write a serialized JSON object to a file. If the file exists, it will be overwritten. + // Let's assume we want to write the following JSON to a file: + // + // { "boolean": true, "number": 342, "object": { "title": "finally json serialization" } } + // + // ``` + // string memory json1 = "some key"; + // vm.serializeBool(json1, "boolean", true); + // vm.serializeBool(json1, "number", uint256(342)); + // json2 = "some other key"; + // string memory output = vm.serializeString(json2, "title", "finally json serialization"); + // string memory finalJson = vm.serialize(json1, "object", output); + // vm.writeJson(finalJson, "./output/example.json"); + // ``` + // The critical insight is that every invocation of serialization will return the stringified version of the JSON + // up to that point. That means we can construct arbitrary JSON objects and then use the return stringified version + // to serialize them as values to another JSON object. + // + // json1 and json2 are simply keys used by the backend to keep track of the objects. So vm.serializeJson(json1,..) + // will find the object in-memory that is keyed by "some key". + function writeJson(string calldata json, string calldata path) external; + // Write a serialized JSON object to an **existing** JSON file, replacing a value with key = + // This is useful to replace a specific value of a JSON file, without having to parse the entire thing + function writeJson(string calldata json, string calldata path, string calldata valueKey) external; + // Returns the RPC url for the given alias + function rpcUrl(string calldata rpcAlias) external view returns (string memory json); + // Returns all rpc urls and their aliases `[alias, url][]` + function rpcUrls() external view returns (string[2][] memory urls); + // Returns all rpc urls and their aliases as structs. + function rpcUrlStructs() external view returns (Rpc[] memory urls); + // If the condition is false, discard this run's fuzz inputs and generate new ones. + function assume(bool condition) external pure; + // Pauses gas metering (i.e. gas usage is not counted). Noop if already paused. + function pauseGasMetering() external; + // Resumes gas metering (i.e. gas usage is counted again). Noop if already on. + function resumeGasMetering() external; + // Writes a breakpoint to jump to in the debugger + function breakpoint(string calldata char) external; + // Writes a conditional breakpoint to jump to in the debugger + function breakpoint(string calldata char, bool value) external; +} + +interface Vm is VmSafe { + // Sets block.timestamp + function warp(uint256 newTimestamp) external; + // Sets block.height + function roll(uint256 newHeight) external; + // Sets block.basefee + function fee(uint256 newBasefee) external; + // Sets block.difficulty + // Not available on EVM versions from Paris onwards. Use `prevrandao` instead. + // If used on unsupported EVM versions it will revert. + function difficulty(uint256 newDifficulty) external; + // Sets block.prevrandao + // Not available on EVM versions before Paris. Use `difficulty` instead. + // If used on unsupported EVM versions it will revert. + function prevrandao(bytes32 newPrevrandao) external; + // Sets block.chainid + function chainId(uint256 newChainId) external; + // Sets tx.gasprice + function txGasPrice(uint256 newGasPrice) external; + // Stores a value to an address' storage slot. + function store(address target, bytes32 slot, bytes32 value) external; + // Sets the nonce of an account; must be higher than the current nonce of the account + function setNonce(address account, uint64 newNonce) external; + // Sets the nonce of an account to an arbitrary value + function setNonceUnsafe(address account, uint64 newNonce) external; + // Resets the nonce of an account to 0 for EOAs and 1 for contract accounts + function resetNonce(address account) external; + // Sets the *next* call's msg.sender to be the input address + function prank(address msgSender) external; + // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called + function startPrank(address msgSender) external; + // Sets the *next* call's msg.sender to be the input address, and the tx.origin to be the second input + function prank(address msgSender, address txOrigin) external; + // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called, and the tx.origin to be the second input + function startPrank(address msgSender, address txOrigin) external; + // Resets subsequent calls' msg.sender to be `address(this)` + function stopPrank() external; + // Reads the current `msg.sender` and `tx.origin` from state and reports if there is any active caller modification + function readCallers() external returns (CallerMode callerMode, address msgSender, address txOrigin); + // Sets an address' balance + function deal(address account, uint256 newBalance) external; + // Sets an address' code + function etch(address target, bytes calldata newRuntimeBytecode) external; + // Marks a test as skipped. Must be called at the top of the test. + function skip(bool skipTest) external; + // Expects an error on next call + function expectRevert(bytes calldata revertData) external; + function expectRevert(bytes4 revertData) external; + function expectRevert() external; + + // Prepare an expected log with all four checks enabled. + // Call this function, then emit an event, then call a function. Internally after the call, we check if + // logs were emitted in the expected order with the expected topics and data. + // Second form also checks supplied address against emitting contract. + function expectEmit() external; + function expectEmit(address emitter) external; + + // Prepare an expected log with (bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData). + // Call this function, then emit an event, then call a function. Internally after the call, we check if + // logs were emitted in the expected order with the expected topics and data (as specified by the booleans). + // Second form also checks supplied address against emitting contract. + function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData) external; + function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData, address emitter) + external; + + // Mocks a call to an address, returning specified data. + // Calldata can either be strict or a partial match, e.g. if you only + // pass a Solidity selector to the expected calldata, then the entire Solidity + // function will be mocked. + function mockCall(address callee, bytes calldata data, bytes calldata returnData) external; + // Mocks a call to an address with a specific msg.value, returning specified data. + // Calldata match takes precedence over msg.value in case of ambiguity. + function mockCall(address callee, uint256 msgValue, bytes calldata data, bytes calldata returnData) external; + // Reverts a call to an address with specified revert data. + function mockCallRevert(address callee, bytes calldata data, bytes calldata revertData) external; + // Reverts a call to an address with a specific msg.value, with specified revert data. + function mockCallRevert(address callee, uint256 msgValue, bytes calldata data, bytes calldata revertData) + external; + // Clears all mocked calls + function clearMockedCalls() external; + // Expects a call to an address with the specified calldata. + // Calldata can either be a strict or a partial match + function expectCall(address callee, bytes calldata data) external; + // Expects given number of calls to an address with the specified calldata. + function expectCall(address callee, bytes calldata data, uint64 count) external; + // Expects a call to an address with the specified msg.value and calldata + function expectCall(address callee, uint256 msgValue, bytes calldata data) external; + // Expects given number of calls to an address with the specified msg.value and calldata + function expectCall(address callee, uint256 msgValue, bytes calldata data, uint64 count) external; + // Expect a call to an address with the specified msg.value, gas, and calldata. + function expectCall(address callee, uint256 msgValue, uint64 gas, bytes calldata data) external; + // Expects given number of calls to an address with the specified msg.value, gas, and calldata. + function expectCall(address callee, uint256 msgValue, uint64 gas, bytes calldata data, uint64 count) external; + // Expect a call to an address with the specified msg.value and calldata, and a *minimum* amount of gas. + function expectCallMinGas(address callee, uint256 msgValue, uint64 minGas, bytes calldata data) external; + // Expect given number of calls to an address with the specified msg.value and calldata, and a *minimum* amount of gas. + function expectCallMinGas(address callee, uint256 msgValue, uint64 minGas, bytes calldata data, uint64 count) + external; + // Only allows memory writes to offsets [0x00, 0x60) ∪ [min, max) in the current subcontext. If any other + // memory is written to, the test will fail. Can be called multiple times to add more ranges to the set. + function expectSafeMemory(uint64 min, uint64 max) external; + // Only allows memory writes to offsets [0x00, 0x60) ∪ [min, max) in the next created subcontext. + // If any other memory is written to, the test will fail. Can be called multiple times to add more ranges + // to the set. + function expectSafeMemoryCall(uint64 min, uint64 max) external; + // Sets block.coinbase + function coinbase(address newCoinbase) external; + // Snapshot the current state of the evm. + // Returns the id of the snapshot that was created. + // To revert a snapshot use `revertTo` + function snapshot() external returns (uint256 snapshotId); + // Revert the state of the EVM to a previous snapshot + // Takes the snapshot id to revert to. + // This deletes the snapshot and all snapshots taken after the given snapshot id. + function revertTo(uint256 snapshotId) external returns (bool success); + // Creates a new fork with the given endpoint and block and returns the identifier of the fork + function createFork(string calldata urlOrAlias, uint256 blockNumber) external returns (uint256 forkId); + // Creates a new fork with the given endpoint and the _latest_ block and returns the identifier of the fork + function createFork(string calldata urlOrAlias) external returns (uint256 forkId); + // Creates a new fork with the given endpoint and at the block the given transaction was mined in, replays all transaction mined in the block before the transaction, + // and returns the identifier of the fork + function createFork(string calldata urlOrAlias, bytes32 txHash) external returns (uint256 forkId); + // Creates _and_ also selects a new fork with the given endpoint and block and returns the identifier of the fork + function createSelectFork(string calldata urlOrAlias, uint256 blockNumber) external returns (uint256 forkId); + // Creates _and_ also selects new fork with the given endpoint and at the block the given transaction was mined in, replays all transaction mined in the block before + // the transaction, returns the identifier of the fork + function createSelectFork(string calldata urlOrAlias, bytes32 txHash) external returns (uint256 forkId); + // Creates _and_ also selects a new fork with the given endpoint and the latest block and returns the identifier of the fork + function createSelectFork(string calldata urlOrAlias) external returns (uint256 forkId); + // Takes a fork identifier created by `createFork` and sets the corresponding forked state as active. + function selectFork(uint256 forkId) external; + /// Returns the identifier of the currently active fork. Reverts if no fork is currently active. + function activeFork() external view returns (uint256 forkId); + // Updates the currently active fork to given block number + // This is similar to `roll` but for the currently active fork + function rollFork(uint256 blockNumber) external; + // Updates the currently active fork to given transaction + // this will `rollFork` with the number of the block the transaction was mined in and replays all transaction mined before it in the block + function rollFork(bytes32 txHash) external; + // Updates the given fork to given block number + function rollFork(uint256 forkId, uint256 blockNumber) external; + // Updates the given fork to block number of the given transaction and replays all transaction mined before it in the block + function rollFork(uint256 forkId, bytes32 txHash) external; + // Marks that the account(s) should use persistent storage across fork swaps in a multifork setup + // Meaning, changes made to the state of this account will be kept when switching forks + function makePersistent(address account) external; + function makePersistent(address account0, address account1) external; + function makePersistent(address account0, address account1, address account2) external; + function makePersistent(address[] calldata accounts) external; + // Revokes persistent status from the address, previously added via `makePersistent` + function revokePersistent(address account) external; + function revokePersistent(address[] calldata accounts) external; + // Returns true if the account is marked as persistent + function isPersistent(address account) external view returns (bool persistent); + // In forking mode, explicitly grant the given address cheatcode access + function allowCheatcodes(address account) external; + // Fetches the given transaction from the active fork and executes it on the current state + function transact(bytes32 txHash) external; + // Fetches the given transaction from the given fork and executes it on the current state + function transact(uint256 forkId, bytes32 txHash) external; +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/console.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/console.sol new file mode 100644 index 0000000000..ad57e53687 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/console.sol @@ -0,0 +1,1533 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.4.22 <0.9.0; + +library console { + address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67); + + function _sendLogPayload(bytes memory payload) private view { + uint256 payloadLength = payload.length; + address consoleAddress = CONSOLE_ADDRESS; + /// @solidity memory-safe-assembly + assembly { + let payloadStart := add(payload, 32) + let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0) + } + } + + function log() internal view { + _sendLogPayload(abi.encodeWithSignature("log()")); + } + + function logInt(int p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(int)", p0)); + } + + function logUint(uint p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint)", p0)); + } + + function logString(string memory p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); + } + + function logBool(bool p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); + } + + function logAddress(address p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); + } + + function logBytes(bytes memory p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes)", p0)); + } + + function logBytes1(bytes1 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0)); + } + + function logBytes2(bytes2 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0)); + } + + function logBytes3(bytes3 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0)); + } + + function logBytes4(bytes4 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0)); + } + + function logBytes5(bytes5 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0)); + } + + function logBytes6(bytes6 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0)); + } + + function logBytes7(bytes7 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0)); + } + + function logBytes8(bytes8 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0)); + } + + function logBytes9(bytes9 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0)); + } + + function logBytes10(bytes10 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0)); + } + + function logBytes11(bytes11 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0)); + } + + function logBytes12(bytes12 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0)); + } + + function logBytes13(bytes13 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0)); + } + + function logBytes14(bytes14 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0)); + } + + function logBytes15(bytes15 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0)); + } + + function logBytes16(bytes16 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0)); + } + + function logBytes17(bytes17 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0)); + } + + function logBytes18(bytes18 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0)); + } + + function logBytes19(bytes19 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0)); + } + + function logBytes20(bytes20 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0)); + } + + function logBytes21(bytes21 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0)); + } + + function logBytes22(bytes22 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0)); + } + + function logBytes23(bytes23 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0)); + } + + function logBytes24(bytes24 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0)); + } + + function logBytes25(bytes25 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0)); + } + + function logBytes26(bytes26 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0)); + } + + function logBytes27(bytes27 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0)); + } + + function logBytes28(bytes28 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0)); + } + + function logBytes29(bytes29 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0)); + } + + function logBytes30(bytes30 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0)); + } + + function logBytes31(bytes31 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0)); + } + + function logBytes32(bytes32 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0)); + } + + function log(uint p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint)", p0)); + } + + function log(string memory p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); + } + + function log(bool p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); + } + + function log(address p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); + } + + function log(uint p0, uint p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint)", p0, p1)); + } + + function log(uint p0, string memory p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string)", p0, p1)); + } + + function log(uint p0, bool p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool)", p0, p1)); + } + + function log(uint p0, address p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address)", p0, p1)); + } + + function log(string memory p0, uint p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint)", p0, p1)); + } + + function log(string memory p0, string memory p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1)); + } + + function log(string memory p0, bool p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1)); + } + + function log(string memory p0, address p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1)); + } + + function log(bool p0, uint p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint)", p0, p1)); + } + + function log(bool p0, string memory p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1)); + } + + function log(bool p0, bool p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1)); + } + + function log(bool p0, address p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1)); + } + + function log(address p0, uint p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint)", p0, p1)); + } + + function log(address p0, string memory p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1)); + } + + function log(address p0, bool p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1)); + } + + function log(address p0, address p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1)); + } + + function log(uint p0, uint p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint)", p0, p1, p2)); + } + + function log(uint p0, uint p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string)", p0, p1, p2)); + } + + function log(uint p0, uint p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool)", p0, p1, p2)); + } + + function log(uint p0, uint p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address)", p0, p1, p2)); + } + + function log(uint p0, string memory p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint)", p0, p1, p2)); + } + + function log(uint p0, string memory p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,string)", p0, p1, p2)); + } + + function log(uint p0, string memory p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool)", p0, p1, p2)); + } + + function log(uint p0, string memory p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,address)", p0, p1, p2)); + } + + function log(uint p0, bool p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint)", p0, p1, p2)); + } + + function log(uint p0, bool p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string)", p0, p1, p2)); + } + + function log(uint p0, bool p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool)", p0, p1, p2)); + } + + function log(uint p0, bool p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address)", p0, p1, p2)); + } + + function log(uint p0, address p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint)", p0, p1, p2)); + } + + function log(uint p0, address p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,string)", p0, p1, p2)); + } + + function log(uint p0, address p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool)", p0, p1, p2)); + } + + function log(uint p0, address p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,address)", p0, p1, p2)); + } + + function log(string memory p0, uint p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint)", p0, p1, p2)); + } + + function log(string memory p0, uint p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,string)", p0, p1, p2)); + } + + function log(string memory p0, uint p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool)", p0, p1, p2)); + } + + function log(string memory p0, uint p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,address)", p0, p1, p2)); + } + + function log(string memory p0, string memory p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint)", p0, p1, p2)); + } + + function log(string memory p0, string memory p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2)); + } + + function log(string memory p0, string memory p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2)); + } + + function log(string memory p0, string memory p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2)); + } + + function log(string memory p0, bool p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint)", p0, p1, p2)); + } + + function log(string memory p0, bool p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2)); + } + + function log(string memory p0, bool p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2)); + } + + function log(string memory p0, bool p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2)); + } + + function log(string memory p0, address p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint)", p0, p1, p2)); + } + + function log(string memory p0, address p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2)); + } + + function log(string memory p0, address p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2)); + } + + function log(string memory p0, address p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2)); + } + + function log(bool p0, uint p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint)", p0, p1, p2)); + } + + function log(bool p0, uint p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string)", p0, p1, p2)); + } + + function log(bool p0, uint p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool)", p0, p1, p2)); + } + + function log(bool p0, uint p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address)", p0, p1, p2)); + } + + function log(bool p0, string memory p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint)", p0, p1, p2)); + } + + function log(bool p0, string memory p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2)); + } + + function log(bool p0, string memory p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2)); + } + + function log(bool p0, string memory p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2)); + } + + function log(bool p0, bool p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint)", p0, p1, p2)); + } + + function log(bool p0, bool p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2)); + } + + function log(bool p0, bool p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2)); + } + + function log(bool p0, bool p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2)); + } + + function log(bool p0, address p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint)", p0, p1, p2)); + } + + function log(bool p0, address p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2)); + } + + function log(bool p0, address p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2)); + } + + function log(bool p0, address p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2)); + } + + function log(address p0, uint p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint)", p0, p1, p2)); + } + + function log(address p0, uint p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,string)", p0, p1, p2)); + } + + function log(address p0, uint p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool)", p0, p1, p2)); + } + + function log(address p0, uint p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,address)", p0, p1, p2)); + } + + function log(address p0, string memory p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint)", p0, p1, p2)); + } + + function log(address p0, string memory p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2)); + } + + function log(address p0, string memory p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2)); + } + + function log(address p0, string memory p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2)); + } + + function log(address p0, bool p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint)", p0, p1, p2)); + } + + function log(address p0, bool p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2)); + } + + function log(address p0, bool p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2)); + } + + function log(address p0, bool p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2)); + } + + function log(address p0, address p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint)", p0, p1, p2)); + } + + function log(address p0, address p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2)); + } + + function log(address p0, address p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2)); + } + + function log(address p0, address p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2)); + } + + function log(uint p0, uint p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,string)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,address)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,string)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,address)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,string)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,address)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,string)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,address)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,string)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,address)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,string)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,address)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,string)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,address)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,string)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,address)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,string)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,address)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,string)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,address)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,string)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,address)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,string)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,address)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,string)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,address)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,string)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,address)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,string)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,address)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,string)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,string)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,address)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,string)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,address)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,string)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,address)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,string)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,address)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,string)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,address)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,string)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,address)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,string)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,address)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,uint)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,string)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,bool)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,address)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,uint)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,string)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,bool)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,address)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,uint)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,string)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,bool)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,address)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,uint)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,string)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,bool)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,address)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,uint)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,string)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,bool)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,address)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,uint)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,string)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,bool)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,address)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,uint)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,string)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,bool)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,address)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3)); + } + +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/console2.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/console2.sol new file mode 100644 index 0000000000..c1e2cd7546 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/console2.sol @@ -0,0 +1,1558 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.4.22 <0.9.0; + +/// @dev The original console.sol uses `int` and `uint` for computing function selectors, but it should +/// use `int256` and `uint256`. This modified version fixes that. This version is recommended +/// over `console.sol` if you don't need compatibility with Hardhat as the logs will show up in +/// forge stack traces. If you do need compatibility with Hardhat, you must use `console.sol`. +/// Reference: https://github.com/NomicFoundation/hardhat/issues/2178 +library console2 { + address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67); + + function _castLogPayloadViewToPure( + function(bytes memory) internal view fnIn + ) internal pure returns (function(bytes memory) internal pure fnOut) { + assembly { + fnOut := fnIn + } + } + + function _sendLogPayload(bytes memory payload) internal pure { + _castLogPayloadViewToPure(_sendLogPayloadView)(payload); + } + + function _sendLogPayloadView(bytes memory payload) private view { + uint256 payloadLength = payload.length; + address consoleAddress = CONSOLE_ADDRESS; + /// @solidity memory-safe-assembly + assembly { + let payloadStart := add(payload, 32) + let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0) + } + } + + function log() internal pure { + _sendLogPayload(abi.encodeWithSignature("log()")); + } + + function logInt(int256 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(int256)", p0)); + } + + function logUint(uint256 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0)); + } + + function logString(string memory p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); + } + + function logBool(bool p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); + } + + function logAddress(address p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); + } + + function logBytes(bytes memory p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes)", p0)); + } + + function logBytes1(bytes1 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0)); + } + + function logBytes2(bytes2 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0)); + } + + function logBytes3(bytes3 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0)); + } + + function logBytes4(bytes4 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0)); + } + + function logBytes5(bytes5 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0)); + } + + function logBytes6(bytes6 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0)); + } + + function logBytes7(bytes7 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0)); + } + + function logBytes8(bytes8 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0)); + } + + function logBytes9(bytes9 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0)); + } + + function logBytes10(bytes10 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0)); + } + + function logBytes11(bytes11 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0)); + } + + function logBytes12(bytes12 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0)); + } + + function logBytes13(bytes13 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0)); + } + + function logBytes14(bytes14 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0)); + } + + function logBytes15(bytes15 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0)); + } + + function logBytes16(bytes16 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0)); + } + + function logBytes17(bytes17 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0)); + } + + function logBytes18(bytes18 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0)); + } + + function logBytes19(bytes19 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0)); + } + + function logBytes20(bytes20 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0)); + } + + function logBytes21(bytes21 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0)); + } + + function logBytes22(bytes22 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0)); + } + + function logBytes23(bytes23 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0)); + } + + function logBytes24(bytes24 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0)); + } + + function logBytes25(bytes25 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0)); + } + + function logBytes26(bytes26 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0)); + } + + function logBytes27(bytes27 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0)); + } + + function logBytes28(bytes28 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0)); + } + + function logBytes29(bytes29 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0)); + } + + function logBytes30(bytes30 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0)); + } + + function logBytes31(bytes31 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0)); + } + + function logBytes32(bytes32 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0)); + } + + function log(uint256 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0)); + } + + function log(int256 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(int256)", p0)); + } + + function log(string memory p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); + } + + function log(bool p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); + } + + function log(address p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); + } + + function log(uint256 p0, uint256 p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256)", p0, p1)); + } + + function log(uint256 p0, string memory p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string)", p0, p1)); + } + + function log(uint256 p0, bool p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool)", p0, p1)); + } + + function log(uint256 p0, address p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address)", p0, p1)); + } + + function log(string memory p0, uint256 p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256)", p0, p1)); + } + + function log(string memory p0, int256 p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,int256)", p0, p1)); + } + + function log(string memory p0, string memory p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1)); + } + + function log(string memory p0, bool p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1)); + } + + function log(string memory p0, address p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1)); + } + + function log(bool p0, uint256 p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256)", p0, p1)); + } + + function log(bool p0, string memory p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1)); + } + + function log(bool p0, bool p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1)); + } + + function log(bool p0, address p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1)); + } + + function log(address p0, uint256 p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256)", p0, p1)); + } + + function log(address p0, string memory p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1)); + } + + function log(address p0, bool p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1)); + } + + function log(address p0, address p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1)); + } + + function log(uint256 p0, uint256 p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256)", p0, p1, p2)); + } + + function log(uint256 p0, uint256 p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string)", p0, p1, p2)); + } + + function log(uint256 p0, uint256 p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool)", p0, p1, p2)); + } + + function log(uint256 p0, uint256 p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address)", p0, p1, p2)); + } + + function log(uint256 p0, string memory p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256)", p0, p1, p2)); + } + + function log(uint256 p0, string memory p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string)", p0, p1, p2)); + } + + function log(uint256 p0, string memory p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool)", p0, p1, p2)); + } + + function log(uint256 p0, string memory p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address)", p0, p1, p2)); + } + + function log(uint256 p0, bool p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256)", p0, p1, p2)); + } + + function log(uint256 p0, bool p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string)", p0, p1, p2)); + } + + function log(uint256 p0, bool p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool)", p0, p1, p2)); + } + + function log(uint256 p0, bool p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address)", p0, p1, p2)); + } + + function log(uint256 p0, address p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256)", p0, p1, p2)); + } + + function log(uint256 p0, address p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string)", p0, p1, p2)); + } + + function log(uint256 p0, address p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool)", p0, p1, p2)); + } + + function log(uint256 p0, address p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address)", p0, p1, p2)); + } + + function log(string memory p0, uint256 p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256)", p0, p1, p2)); + } + + function log(string memory p0, uint256 p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string)", p0, p1, p2)); + } + + function log(string memory p0, uint256 p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool)", p0, p1, p2)); + } + + function log(string memory p0, uint256 p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address)", p0, p1, p2)); + } + + function log(string memory p0, string memory p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256)", p0, p1, p2)); + } + + function log(string memory p0, string memory p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2)); + } + + function log(string memory p0, string memory p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2)); + } + + function log(string memory p0, string memory p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2)); + } + + function log(string memory p0, bool p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256)", p0, p1, p2)); + } + + function log(string memory p0, bool p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2)); + } + + function log(string memory p0, bool p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2)); + } + + function log(string memory p0, bool p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2)); + } + + function log(string memory p0, address p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256)", p0, p1, p2)); + } + + function log(string memory p0, address p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2)); + } + + function log(string memory p0, address p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2)); + } + + function log(string memory p0, address p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2)); + } + + function log(bool p0, uint256 p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256)", p0, p1, p2)); + } + + function log(bool p0, uint256 p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string)", p0, p1, p2)); + } + + function log(bool p0, uint256 p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool)", p0, p1, p2)); + } + + function log(bool p0, uint256 p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address)", p0, p1, p2)); + } + + function log(bool p0, string memory p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256)", p0, p1, p2)); + } + + function log(bool p0, string memory p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2)); + } + + function log(bool p0, string memory p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2)); + } + + function log(bool p0, string memory p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2)); + } + + function log(bool p0, bool p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256)", p0, p1, p2)); + } + + function log(bool p0, bool p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2)); + } + + function log(bool p0, bool p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2)); + } + + function log(bool p0, bool p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2)); + } + + function log(bool p0, address p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256)", p0, p1, p2)); + } + + function log(bool p0, address p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2)); + } + + function log(bool p0, address p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2)); + } + + function log(bool p0, address p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2)); + } + + function log(address p0, uint256 p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256)", p0, p1, p2)); + } + + function log(address p0, uint256 p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string)", p0, p1, p2)); + } + + function log(address p0, uint256 p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool)", p0, p1, p2)); + } + + function log(address p0, uint256 p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address)", p0, p1, p2)); + } + + function log(address p0, string memory p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256)", p0, p1, p2)); + } + + function log(address p0, string memory p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2)); + } + + function log(address p0, string memory p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2)); + } + + function log(address p0, string memory p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2)); + } + + function log(address p0, bool p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256)", p0, p1, p2)); + } + + function log(address p0, bool p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2)); + } + + function log(address p0, bool p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2)); + } + + function log(address p0, bool p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2)); + } + + function log(address p0, address p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256)", p0, p1, p2)); + } + + function log(address p0, address p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2)); + } + + function log(address p0, address p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2)); + } + + function log(address p0, address p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2)); + } + + function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,string)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,address)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,string)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,address)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,string)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,address)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,string)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,address)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,string)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,address)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,string)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,address)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,string)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,address)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,string)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,bool)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,address)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,string)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,bool)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,address)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,string)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,bool)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,address)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,string)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,bool)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,address)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,string)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,bool)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,address)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,string)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,bool)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,address)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,string)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,bool)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,address)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3)); + } + +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/interfaces/IERC1155.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/interfaces/IERC1155.sol new file mode 100644 index 0000000000..f7dd2b4106 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/interfaces/IERC1155.sol @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +import "./IERC165.sol"; + +/// @title ERC-1155 Multi Token Standard +/// @dev See https://eips.ethereum.org/EIPS/eip-1155 +/// Note: The ERC-165 identifier for this interface is 0xd9b67a26. +interface IERC1155 is IERC165 { + /// @dev + /// - Either `TransferSingle` or `TransferBatch` MUST emit when tokens are transferred, including zero value transfers as well as minting or burning (see "Safe Transfer Rules" section of the standard). + /// - The `_operator` argument MUST be the address of an account/contract that is approved to make the transfer (SHOULD be msg.sender). + /// - The `_from` argument MUST be the address of the holder whose balance is decreased. + /// - The `_to` argument MUST be the address of the recipient whose balance is increased. + /// - The `_id` argument MUST be the token type being transferred. + /// - The `_value` argument MUST be the number of tokens the holder balance is decreased by and match what the recipient balance is increased by. + /// - When minting/creating tokens, the `_from` argument MUST be set to `0x0` (i.e. zero address). + /// - When burning/destroying tokens, the `_to` argument MUST be set to `0x0` (i.e. zero address). + event TransferSingle( + address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _value + ); + + /// @dev + /// - Either `TransferSingle` or `TransferBatch` MUST emit when tokens are transferred, including zero value transfers as well as minting or burning (see "Safe Transfer Rules" section of the standard). + /// - The `_operator` argument MUST be the address of an account/contract that is approved to make the transfer (SHOULD be msg.sender). + /// - The `_from` argument MUST be the address of the holder whose balance is decreased. + /// - The `_to` argument MUST be the address of the recipient whose balance is increased. + /// - The `_ids` argument MUST be the list of tokens being transferred. + /// - The `_values` argument MUST be the list of number of tokens (matching the list and order of tokens specified in _ids) the holder balance is decreased by and match what the recipient balance is increased by. + /// - When minting/creating tokens, the `_from` argument MUST be set to `0x0` (i.e. zero address). + /// - When burning/destroying tokens, the `_to` argument MUST be set to `0x0` (i.e. zero address). + event TransferBatch( + address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _values + ); + + /// @dev MUST emit when approval for a second party/operator address to manage all tokens for an owner address is enabled or disabled (absence of an event assumes disabled). + event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); + + /// @dev MUST emit when the URI is updated for a token ID. URIs are defined in RFC 3986. + /// The URI MUST point to a JSON file that conforms to the "ERC-1155 Metadata URI JSON Schema". + event URI(string _value, uint256 indexed _id); + + /// @notice Transfers `_value` amount of an `_id` from the `_from` address to the `_to` address specified (with safety call). + /// @dev Caller must be approved to manage the tokens being transferred out of the `_from` account (see "Approval" section of the standard). + /// - MUST revert if `_to` is the zero address. + /// - MUST revert if balance of holder for token `_id` is lower than the `_value` sent. + /// - MUST revert on any other error. + /// - MUST emit the `TransferSingle` event to reflect the balance change (see "Safe Transfer Rules" section of the standard). + /// - After the above conditions are met, this function MUST check if `_to` is a smart contract (e.g. code size > 0). If so, it MUST call `onERC1155Received` on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard). + /// @param _from Source address + /// @param _to Target address + /// @param _id ID of the token type + /// @param _value Transfer amount + /// @param _data Additional data with no specified format, MUST be sent unaltered in call to `onERC1155Received` on `_to` + function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, bytes calldata _data) external; + + /// @notice Transfers `_values` amount(s) of `_ids` from the `_from` address to the `_to` address specified (with safety call). + /// @dev Caller must be approved to manage the tokens being transferred out of the `_from` account (see "Approval" section of the standard). + /// - MUST revert if `_to` is the zero address. + /// - MUST revert if length of `_ids` is not the same as length of `_values`. + /// - MUST revert if any of the balance(s) of the holder(s) for token(s) in `_ids` is lower than the respective amount(s) in `_values` sent to the recipient. + /// - MUST revert on any other error. + /// - MUST emit `TransferSingle` or `TransferBatch` event(s) such that all the balance changes are reflected (see "Safe Transfer Rules" section of the standard). + /// - Balance changes and events MUST follow the ordering of the arrays (_ids[0]/_values[0] before _ids[1]/_values[1], etc). + /// - After the above conditions for the transfer(s) in the batch are met, this function MUST check if `_to` is a smart contract (e.g. code size > 0). If so, it MUST call the relevant `ERC1155TokenReceiver` hook(s) on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard). + /// @param _from Source address + /// @param _to Target address + /// @param _ids IDs of each token type (order and length must match _values array) + /// @param _values Transfer amounts per token type (order and length must match _ids array) + /// @param _data Additional data with no specified format, MUST be sent unaltered in call to the `ERC1155TokenReceiver` hook(s) on `_to` + function safeBatchTransferFrom( + address _from, + address _to, + uint256[] calldata _ids, + uint256[] calldata _values, + bytes calldata _data + ) external; + + /// @notice Get the balance of an account's tokens. + /// @param _owner The address of the token holder + /// @param _id ID of the token + /// @return The _owner's balance of the token type requested + function balanceOf(address _owner, uint256 _id) external view returns (uint256); + + /// @notice Get the balance of multiple account/token pairs + /// @param _owners The addresses of the token holders + /// @param _ids ID of the tokens + /// @return The _owner's balance of the token types requested (i.e. balance for each (owner, id) pair) + function balanceOfBatch(address[] calldata _owners, uint256[] calldata _ids) + external + view + returns (uint256[] memory); + + /// @notice Enable or disable approval for a third party ("operator") to manage all of the caller's tokens. + /// @dev MUST emit the ApprovalForAll event on success. + /// @param _operator Address to add to the set of authorized operators + /// @param _approved True if the operator is approved, false to revoke approval + function setApprovalForAll(address _operator, bool _approved) external; + + /// @notice Queries the approval status of an operator for a given owner. + /// @param _owner The owner of the tokens + /// @param _operator Address of authorized operator + /// @return True if the operator is approved, false if not + function isApprovedForAll(address _owner, address _operator) external view returns (bool); +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/interfaces/IERC165.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/interfaces/IERC165.sol new file mode 100644 index 0000000000..9af4bf800f --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/interfaces/IERC165.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +interface IERC165 { + /// @notice Query if a contract implements an interface + /// @param interfaceID The interface identifier, as specified in ERC-165 + /// @dev Interface identification is specified in ERC-165. This function + /// uses less than 30,000 gas. + /// @return `true` if the contract implements `interfaceID` and + /// `interfaceID` is not 0xffffffff, `false` otherwise + function supportsInterface(bytes4 interfaceID) external view returns (bool); +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/interfaces/IERC20.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/interfaces/IERC20.sol new file mode 100644 index 0000000000..ba40806c3b --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/interfaces/IERC20.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +/// @dev Interface of the ERC20 standard as defined in the EIP. +/// @dev This includes the optional name, symbol, and decimals metadata. +interface IERC20 { + /// @dev Emitted when `value` tokens are moved from one account (`from`) to another (`to`). + event Transfer(address indexed from, address indexed to, uint256 value); + + /// @dev Emitted when the allowance of a `spender` for an `owner` is set, where `value` + /// is the new allowance. + event Approval(address indexed owner, address indexed spender, uint256 value); + + /// @notice Returns the amount of tokens in existence. + function totalSupply() external view returns (uint256); + + /// @notice Returns the amount of tokens owned by `account`. + function balanceOf(address account) external view returns (uint256); + + /// @notice Moves `amount` tokens from the caller's account to `to`. + function transfer(address to, uint256 amount) external returns (bool); + + /// @notice Returns the remaining number of tokens that `spender` is allowed + /// to spend on behalf of `owner` + function allowance(address owner, address spender) external view returns (uint256); + + /// @notice Sets `amount` as the allowance of `spender` over the caller's tokens. + /// @dev Be aware of front-running risks: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 + function approve(address spender, uint256 amount) external returns (bool); + + /// @notice Moves `amount` tokens from `from` to `to` using the allowance mechanism. + /// `amount` is then deducted from the caller's allowance. + function transferFrom(address from, address to, uint256 amount) external returns (bool); + + /// @notice Returns the name of the token. + function name() external view returns (string memory); + + /// @notice Returns the symbol of the token. + function symbol() external view returns (string memory); + + /// @notice Returns the decimals places of the token. + function decimals() external view returns (uint8); +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/interfaces/IERC4626.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/interfaces/IERC4626.sol new file mode 100644 index 0000000000..bfe3a1155e --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/interfaces/IERC4626.sol @@ -0,0 +1,190 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +import "./IERC20.sol"; + +/// @dev Interface of the ERC4626 "Tokenized Vault Standard", as defined in +/// https://eips.ethereum.org/EIPS/eip-4626 +interface IERC4626 is IERC20 { + event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares); + + event Withdraw( + address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares + ); + + /// @notice Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing. + /// @dev + /// - MUST be an ERC-20 token contract. + /// - MUST NOT revert. + function asset() external view returns (address assetTokenAddress); + + /// @notice Returns the total amount of the underlying asset that is ā€œmanagedā€ by Vault. + /// @dev + /// - SHOULD include any compounding that occurs from yield. + /// - MUST be inclusive of any fees that are charged against assets in the Vault. + /// - MUST NOT revert. + function totalAssets() external view returns (uint256 totalManagedAssets); + + /// @notice Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal + /// scenario where all the conditions are met. + /// @dev + /// - MUST NOT be inclusive of any fees that are charged against assets in the Vault. + /// - MUST NOT show any variations depending on the caller. + /// - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. + /// - MUST NOT revert. + /// + /// NOTE: This calculation MAY NOT reflect the ā€œper-userā€ price-per-share, and instead should reflect the + /// ā€œaverage-user’sā€ price-per-share, meaning what the average user should expect to see when exchanging to and + /// from. + function convertToShares(uint256 assets) external view returns (uint256 shares); + + /// @notice Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal + /// scenario where all the conditions are met. + /// @dev + /// - MUST NOT be inclusive of any fees that are charged against assets in the Vault. + /// - MUST NOT show any variations depending on the caller. + /// - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. + /// - MUST NOT revert. + /// + /// NOTE: This calculation MAY NOT reflect the ā€œper-userā€ price-per-share, and instead should reflect the + /// ā€œaverage-user’sā€ price-per-share, meaning what the average user should expect to see when exchanging to and + /// from. + function convertToAssets(uint256 shares) external view returns (uint256 assets); + + /// @notice Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver, + /// through a deposit call. + /// @dev + /// - MUST return a limited value if receiver is subject to some deposit limit. + /// - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited. + /// - MUST NOT revert. + function maxDeposit(address receiver) external view returns (uint256 maxAssets); + + /// @notice Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given + /// current on-chain conditions. + /// @dev + /// - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit + /// call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called + /// in the same transaction. + /// - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the + /// deposit would be accepted, regardless if the user has enough tokens approved, etc. + /// - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. + /// - MUST NOT revert. + /// + /// NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in + /// share price or some other type of condition, meaning the depositor will lose assets by depositing. + function previewDeposit(uint256 assets) external view returns (uint256 shares); + + /// @notice Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens. + /// @dev + /// - MUST emit the Deposit event. + /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the + /// deposit execution, and are accounted for during deposit. + /// - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not + /// approving enough underlying tokens to the Vault contract, etc). + /// + /// NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. + function deposit(uint256 assets, address receiver) external returns (uint256 shares); + + /// @notice Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call. + /// @dev + /// - MUST return a limited value if receiver is subject to some mint limit. + /// - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted. + /// - MUST NOT revert. + function maxMint(address receiver) external view returns (uint256 maxShares); + + /// @notice Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given + /// current on-chain conditions. + /// @dev + /// - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call + /// in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the + /// same transaction. + /// - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint + /// would be accepted, regardless if the user has enough tokens approved, etc. + /// - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. + /// - MUST NOT revert. + /// + /// NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in + /// share price or some other type of condition, meaning the depositor will lose assets by minting. + function previewMint(uint256 shares) external view returns (uint256 assets); + + /// @notice Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens. + /// @dev + /// - MUST emit the Deposit event. + /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint + /// execution, and are accounted for during mint. + /// - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not + /// approving enough underlying tokens to the Vault contract, etc). + /// + /// NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. + function mint(uint256 shares, address receiver) external returns (uint256 assets); + + /// @notice Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the + /// Vault, through a withdraw call. + /// @dev + /// - MUST return a limited value if owner is subject to some withdrawal limit or timelock. + /// - MUST NOT revert. + function maxWithdraw(address owner) external view returns (uint256 maxAssets); + + /// @notice Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block, + /// given current on-chain conditions. + /// @dev + /// - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw + /// call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if + /// called + /// in the same transaction. + /// - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though + /// the withdrawal would be accepted, regardless if the user has enough shares, etc. + /// - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. + /// - MUST NOT revert. + /// + /// NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in + /// share price or some other type of condition, meaning the depositor will lose assets by depositing. + function previewWithdraw(uint256 assets) external view returns (uint256 shares); + + /// @notice Burns shares from owner and sends exactly assets of underlying tokens to receiver. + /// @dev + /// - MUST emit the Withdraw event. + /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the + /// withdraw execution, and are accounted for during withdraw. + /// - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner + /// not having enough shares, etc). + /// + /// Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed. + /// Those methods should be performed separately. + function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares); + + /// @notice Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault, + /// through a redeem call. + /// @dev + /// - MUST return a limited value if owner is subject to some withdrawal limit or timelock. + /// - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock. + /// - MUST NOT revert. + function maxRedeem(address owner) external view returns (uint256 maxShares); + + /// @notice Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block, + /// given current on-chain conditions. + /// @dev + /// - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call + /// in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the + /// same transaction. + /// - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the + /// redemption would be accepted, regardless if the user has enough shares, etc. + /// - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. + /// - MUST NOT revert. + /// + /// NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in + /// share price or some other type of condition, meaning the depositor will lose assets by redeeming. + function previewRedeem(uint256 shares) external view returns (uint256 assets); + + /// @notice Burns exactly shares from owner and sends assets of underlying tokens to receiver. + /// @dev + /// - MUST emit the Withdraw event. + /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the + /// redeem execution, and are accounted for during redeem. + /// - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner + /// not having enough shares, etc). + /// + /// NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed. + /// Those methods should be performed separately. + function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets); +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/interfaces/IERC721.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/interfaces/IERC721.sol new file mode 100644 index 0000000000..0a16f45cc5 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/interfaces/IERC721.sol @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +import "./IERC165.sol"; + +/// @title ERC-721 Non-Fungible Token Standard +/// @dev See https://eips.ethereum.org/EIPS/eip-721 +/// Note: the ERC-165 identifier for this interface is 0x80ac58cd. +interface IERC721 is IERC165 { + /// @dev This emits when ownership of any NFT changes by any mechanism. + /// This event emits when NFTs are created (`from` == 0) and destroyed + /// (`to` == 0). Exception: during contract creation, any number of NFTs + /// may be created and assigned without emitting Transfer. At the time of + /// any transfer, the approved address for that NFT (if any) is reset to none. + event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId); + + /// @dev This emits when the approved address for an NFT is changed or + /// reaffirmed. The zero address indicates there is no approved address. + /// When a Transfer event emits, this also indicates that the approved + /// address for that NFT (if any) is reset to none. + event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId); + + /// @dev This emits when an operator is enabled or disabled for an owner. + /// The operator can manage all NFTs of the owner. + event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); + + /// @notice Count all NFTs assigned to an owner + /// @dev NFTs assigned to the zero address are considered invalid, and this + /// function throws for queries about the zero address. + /// @param _owner An address for whom to query the balance + /// @return The number of NFTs owned by `_owner`, possibly zero + function balanceOf(address _owner) external view returns (uint256); + + /// @notice Find the owner of an NFT + /// @dev NFTs assigned to zero address are considered invalid, and queries + /// about them do throw. + /// @param _tokenId The identifier for an NFT + /// @return The address of the owner of the NFT + function ownerOf(uint256 _tokenId) external view returns (address); + + /// @notice Transfers the ownership of an NFT from one address to another address + /// @dev Throws unless `msg.sender` is the current owner, an authorized + /// operator, or the approved address for this NFT. Throws if `_from` is + /// not the current owner. Throws if `_to` is the zero address. Throws if + /// `_tokenId` is not a valid NFT. When transfer is complete, this function + /// checks if `_to` is a smart contract (code size > 0). If so, it calls + /// `onERC721Received` on `_to` and throws if the return value is not + /// `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`. + /// @param _from The current owner of the NFT + /// @param _to The new owner + /// @param _tokenId The NFT to transfer + /// @param data Additional data with no specified format, sent in call to `_to` + function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes calldata data) external payable; + + /// @notice Transfers the ownership of an NFT from one address to another address + /// @dev This works identically to the other function with an extra data parameter, + /// except this function just sets data to "". + /// @param _from The current owner of the NFT + /// @param _to The new owner + /// @param _tokenId The NFT to transfer + function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable; + + /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE + /// TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE + /// THEY MAY BE PERMANENTLY LOST + /// @dev Throws unless `msg.sender` is the current owner, an authorized + /// operator, or the approved address for this NFT. Throws if `_from` is + /// not the current owner. Throws if `_to` is the zero address. Throws if + /// `_tokenId` is not a valid NFT. + /// @param _from The current owner of the NFT + /// @param _to The new owner + /// @param _tokenId The NFT to transfer + function transferFrom(address _from, address _to, uint256 _tokenId) external payable; + + /// @notice Change or reaffirm the approved address for an NFT + /// @dev The zero address indicates there is no approved address. + /// Throws unless `msg.sender` is the current NFT owner, or an authorized + /// operator of the current owner. + /// @param _approved The new approved NFT controller + /// @param _tokenId The NFT to approve + function approve(address _approved, uint256 _tokenId) external payable; + + /// @notice Enable or disable approval for a third party ("operator") to manage + /// all of `msg.sender`'s assets + /// @dev Emits the ApprovalForAll event. The contract MUST allow + /// multiple operators per owner. + /// @param _operator Address to add to the set of authorized operators + /// @param _approved True if the operator is approved, false to revoke approval + function setApprovalForAll(address _operator, bool _approved) external; + + /// @notice Get the approved address for a single NFT + /// @dev Throws if `_tokenId` is not a valid NFT. + /// @param _tokenId The NFT to find the approved address for + /// @return The approved address for this NFT, or the zero address if there is none + function getApproved(uint256 _tokenId) external view returns (address); + + /// @notice Query if an address is an authorized operator for another address + /// @param _owner The address that owns the NFTs + /// @param _operator The address that acts on behalf of the owner + /// @return True if `_operator` is an approved operator for `_owner`, false otherwise + function isApprovedForAll(address _owner, address _operator) external view returns (bool); +} + +/// @dev Note: the ERC-165 identifier for this interface is 0x150b7a02. +interface IERC721TokenReceiver { + /// @notice Handle the receipt of an NFT + /// @dev The ERC721 smart contract calls this function on the recipient + /// after a `transfer`. This function MAY throw to revert and reject the + /// transfer. Return of other than the magic value MUST result in the + /// transaction being reverted. + /// Note: the contract address is always the message sender. + /// @param _operator The address which called `safeTransferFrom` function + /// @param _from The address which previously owned the token + /// @param _tokenId The NFT identifier which is being transferred + /// @param _data Additional data with no specified format + /// @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` + /// unless throwing + function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes calldata _data) + external + returns (bytes4); +} + +/// @title ERC-721 Non-Fungible Token Standard, optional metadata extension +/// @dev See https://eips.ethereum.org/EIPS/eip-721 +/// Note: the ERC-165 identifier for this interface is 0x5b5e139f. +interface IERC721Metadata is IERC721 { + /// @notice A descriptive name for a collection of NFTs in this contract + function name() external view returns (string memory _name); + + /// @notice An abbreviated name for NFTs in this contract + function symbol() external view returns (string memory _symbol); + + /// @notice A distinct Uniform Resource Identifier (URI) for a given asset. + /// @dev Throws if `_tokenId` is not a valid NFT. URIs are defined in RFC + /// 3986. The URI may point to a JSON file that conforms to the "ERC721 + /// Metadata JSON Schema". + function tokenURI(uint256 _tokenId) external view returns (string memory); +} + +/// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension +/// @dev See https://eips.ethereum.org/EIPS/eip-721 +/// Note: the ERC-165 identifier for this interface is 0x780e9d63. +interface IERC721Enumerable is IERC721 { + /// @notice Count NFTs tracked by this contract + /// @return A count of valid NFTs tracked by this contract, where each one of + /// them has an assigned and queryable owner not equal to the zero address + function totalSupply() external view returns (uint256); + + /// @notice Enumerate valid NFTs + /// @dev Throws if `_index` >= `totalSupply()`. + /// @param _index A counter less than `totalSupply()` + /// @return The token identifier for the `_index`th NFT, + /// (sort order not specified) + function tokenByIndex(uint256 _index) external view returns (uint256); + + /// @notice Enumerate NFTs assigned to an owner + /// @dev Throws if `_index` >= `balanceOf(_owner)` or if + /// `_owner` is the zero address, representing invalid NFTs. + /// @param _owner An address where we are interested in NFTs owned by them + /// @param _index A counter less than `balanceOf(_owner)` + /// @return The token identifier for the `_index`th NFT assigned to `_owner`, + /// (sort order not specified) + function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256); +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/interfaces/IMulticall3.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/interfaces/IMulticall3.sol new file mode 100644 index 0000000000..0d031b71dc --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/interfaces/IMulticall3.sol @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +interface IMulticall3 { + struct Call { + address target; + bytes callData; + } + + struct Call3 { + address target; + bool allowFailure; + bytes callData; + } + + struct Call3Value { + address target; + bool allowFailure; + uint256 value; + bytes callData; + } + + struct Result { + bool success; + bytes returnData; + } + + function aggregate(Call[] calldata calls) + external + payable + returns (uint256 blockNumber, bytes[] memory returnData); + + function aggregate3(Call3[] calldata calls) external payable returns (Result[] memory returnData); + + function aggregate3Value(Call3Value[] calldata calls) external payable returns (Result[] memory returnData); + + function blockAndAggregate(Call[] calldata calls) + external + payable + returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData); + + function getBasefee() external view returns (uint256 basefee); + + function getBlockHash(uint256 blockNumber) external view returns (bytes32 blockHash); + + function getBlockNumber() external view returns (uint256 blockNumber); + + function getChainId() external view returns (uint256 chainid); + + function getCurrentBlockCoinbase() external view returns (address coinbase); + + function getCurrentBlockDifficulty() external view returns (uint256 difficulty); + + function getCurrentBlockGasLimit() external view returns (uint256 gaslimit); + + function getCurrentBlockTimestamp() external view returns (uint256 timestamp); + + function getEthBalance(address addr) external view returns (uint256 balance); + + function getLastBlockHash() external view returns (bytes32 blockHash); + + function tryAggregate(bool requireSuccess, Call[] calldata calls) + external + payable + returns (Result[] memory returnData); + + function tryBlockAndAggregate(bool requireSuccess, Call[] calldata calls) + external + payable + returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData); +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/safeconsole.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/safeconsole.sol new file mode 100644 index 0000000000..5714d0902d --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/src/safeconsole.sol @@ -0,0 +1,13248 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +/// @author philogy +/// @dev Code generated automatically by script. +library safeconsole { + uint256 constant CONSOLE_ADDR = 0x000000000000000000000000000000000000000000636F6e736F6c652e6c6f67; + + // Credit to [0age](https://twitter.com/z0age/status/1654922202930888704) and [0xdapper](https://github.com/foundry-rs/forge-std/pull/374) + // for the view-to-pure log trick. + function _sendLogPayload(uint256 offset, uint256 size) private pure { + function(uint256, uint256) internal view fnIn = _sendLogPayloadView; + function(uint256, uint256) internal pure pureSendLogPayload; + assembly { + pureSendLogPayload := fnIn + } + pureSendLogPayload(offset, size); + } + + function _sendLogPayloadView(uint256 offset, uint256 size) private view { + assembly { + pop(staticcall(gas(), CONSOLE_ADDR, offset, size, 0x0, 0x0)) + } + } + + function _memcopy(uint256 fromOffset, uint256 toOffset, uint256 length) private pure { + function(uint256, uint256, uint256) internal view fnIn = _memcopyView; + function(uint256, uint256, uint256) internal pure pureMemcopy; + assembly { + pureMemcopy := fnIn + } + pureMemcopy(fromOffset, toOffset, length); + } + + function _memcopyView(uint256 fromOffset, uint256 toOffset, uint256 length) private view { + assembly { + pop(staticcall(gas(), 0x4, fromOffset, length, toOffset, length)) + } + } + + function logMemory(uint256 offset, uint256 length) internal pure { + if (offset >= 0x60) { + // Sufficient memory before slice to prepare call header. + bytes32 m0; + bytes32 m1; + bytes32 m2; + assembly { + m0 := mload(sub(offset, 0x60)) + m1 := mload(sub(offset, 0x40)) + m2 := mload(sub(offset, 0x20)) + // Selector of `logBytes(bytes)`. + mstore(sub(offset, 0x60), 0xe17bf956) + mstore(sub(offset, 0x40), 0x20) + mstore(sub(offset, 0x20), length) + } + _sendLogPayload(offset - 0x44, length + 0x44); + assembly { + mstore(sub(offset, 0x60), m0) + mstore(sub(offset, 0x40), m1) + mstore(sub(offset, 0x20), m2) + } + } else { + // Insufficient space, so copy slice forward, add header and reverse. + bytes32 m0; + bytes32 m1; + bytes32 m2; + uint256 endOffset = offset + length; + assembly { + m0 := mload(add(endOffset, 0x00)) + m1 := mload(add(endOffset, 0x20)) + m2 := mload(add(endOffset, 0x40)) + } + _memcopy(offset, offset + 0x60, length); + assembly { + // Selector of `logBytes(bytes)`. + mstore(add(offset, 0x00), 0xe17bf956) + mstore(add(offset, 0x20), 0x20) + mstore(add(offset, 0x40), length) + } + _sendLogPayload(offset + 0x1c, length + 0x44); + _memcopy(offset + 0x60, offset, length); + assembly { + mstore(add(endOffset, 0x00), m0) + mstore(add(endOffset, 0x20), m1) + mstore(add(endOffset, 0x40), m2) + } + } + } + + function log(address p0) internal pure { + bytes32 m0; + bytes32 m1; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + // Selector of `log(address)`. + mstore(0x00, 0x2c2ecbc2) + mstore(0x20, p0) + } + _sendLogPayload(0x1c, 0x24); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + } + } + + function log(bool p0) internal pure { + bytes32 m0; + bytes32 m1; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + // Selector of `log(bool)`. + mstore(0x00, 0x32458eed) + mstore(0x20, p0) + } + _sendLogPayload(0x1c, 0x24); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + } + } + + function log(uint256 p0) internal pure { + bytes32 m0; + bytes32 m1; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + // Selector of `log(uint256)`. + mstore(0x00, 0xf82c50f1) + mstore(0x20, p0) + } + _sendLogPayload(0x1c, 0x24); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + } + } + + function log(bytes32 p0) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(string)`. + mstore(0x00, 0x41304fac) + mstore(0x20, 0x20) + writeString(0x40, p0) + } + _sendLogPayload(0x1c, 0x64); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(address p0, address p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + // Selector of `log(address,address)`. + mstore(0x00, 0xdaf0d4aa) + mstore(0x20, p0) + mstore(0x40, p1) + } + _sendLogPayload(0x1c, 0x44); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + } + } + + function log(address p0, bool p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + // Selector of `log(address,bool)`. + mstore(0x00, 0x75b605d3) + mstore(0x20, p0) + mstore(0x40, p1) + } + _sendLogPayload(0x1c, 0x44); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + } + } + + function log(address p0, uint256 p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + // Selector of `log(address,uint256)`. + mstore(0x00, 0x8309e8a8) + mstore(0x20, p0) + mstore(0x40, p1) + } + _sendLogPayload(0x1c, 0x44); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + } + } + + function log(address p0, bytes32 p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,string)`. + mstore(0x00, 0x759f86bb) + mstore(0x20, p0) + mstore(0x40, 0x40) + writeString(0x60, p1) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, address p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + // Selector of `log(bool,address)`. + mstore(0x00, 0x853c4849) + mstore(0x20, p0) + mstore(0x40, p1) + } + _sendLogPayload(0x1c, 0x44); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + } + } + + function log(bool p0, bool p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + // Selector of `log(bool,bool)`. + mstore(0x00, 0x2a110e83) + mstore(0x20, p0) + mstore(0x40, p1) + } + _sendLogPayload(0x1c, 0x44); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + } + } + + function log(bool p0, uint256 p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + // Selector of `log(bool,uint256)`. + mstore(0x00, 0x399174d3) + mstore(0x20, p0) + mstore(0x40, p1) + } + _sendLogPayload(0x1c, 0x44); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + } + } + + function log(bool p0, bytes32 p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,string)`. + mstore(0x00, 0x8feac525) + mstore(0x20, p0) + mstore(0x40, 0x40) + writeString(0x60, p1) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, address p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + // Selector of `log(uint256,address)`. + mstore(0x00, 0x69276c86) + mstore(0x20, p0) + mstore(0x40, p1) + } + _sendLogPayload(0x1c, 0x44); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + } + } + + function log(uint256 p0, bool p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + // Selector of `log(uint256,bool)`. + mstore(0x00, 0x1c9d7eb3) + mstore(0x20, p0) + mstore(0x40, p1) + } + _sendLogPayload(0x1c, 0x44); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + } + } + + function log(uint256 p0, uint256 p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + // Selector of `log(uint256,uint256)`. + mstore(0x00, 0xf666715a) + mstore(0x20, p0) + mstore(0x40, p1) + } + _sendLogPayload(0x1c, 0x44); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + } + } + + function log(uint256 p0, bytes32 p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,string)`. + mstore(0x00, 0x643fd0df) + mstore(0x20, p0) + mstore(0x40, 0x40) + writeString(0x60, p1) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bytes32 p0, address p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(string,address)`. + mstore(0x00, 0x319af333) + mstore(0x20, 0x40) + mstore(0x40, p1) + writeString(0x60, p0) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bytes32 p0, bool p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(string,bool)`. + mstore(0x00, 0xc3b55635) + mstore(0x20, 0x40) + mstore(0x40, p1) + writeString(0x60, p0) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bytes32 p0, uint256 p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(string,uint256)`. + mstore(0x00, 0xb60e72cc) + mstore(0x20, 0x40) + mstore(0x40, p1) + writeString(0x60, p0) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bytes32 p0, bytes32 p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,string)`. + mstore(0x00, 0x4b5c4277) + mstore(0x20, 0x40) + mstore(0x40, 0x80) + writeString(0x60, p0) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, address p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(address,address,address)`. + mstore(0x00, 0x018c84c2) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(address p0, address p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(address,address,bool)`. + mstore(0x00, 0xf2a66286) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(address p0, address p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(address,address,uint256)`. + mstore(0x00, 0x17fe6185) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(address p0, address p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(address,address,string)`. + mstore(0x00, 0x007150be) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x60) + writeString(0x80, p2) + } + _sendLogPayload(0x1c, 0xa4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(address p0, bool p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(address,bool,address)`. + mstore(0x00, 0xf11699ed) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(address p0, bool p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(address,bool,bool)`. + mstore(0x00, 0xeb830c92) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(address p0, bool p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(address,bool,uint256)`. + mstore(0x00, 0x9c4f99fb) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(address p0, bool p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(address,bool,string)`. + mstore(0x00, 0x212255cc) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x60) + writeString(0x80, p2) + } + _sendLogPayload(0x1c, 0xa4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(address p0, uint256 p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(address,uint256,address)`. + mstore(0x00, 0x7bc0d848) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(address p0, uint256 p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(address,uint256,bool)`. + mstore(0x00, 0x678209a8) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(address p0, uint256 p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(address,uint256,uint256)`. + mstore(0x00, 0xb69bcaf6) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(address p0, uint256 p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(address,uint256,string)`. + mstore(0x00, 0xa1f2e8aa) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x60) + writeString(0x80, p2) + } + _sendLogPayload(0x1c, 0xa4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(address p0, bytes32 p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(address,string,address)`. + mstore(0x00, 0xf08744e8) + mstore(0x20, p0) + mstore(0x40, 0x60) + mstore(0x60, p2) + writeString(0x80, p1) + } + _sendLogPayload(0x1c, 0xa4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(address p0, bytes32 p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(address,string,bool)`. + mstore(0x00, 0xcf020fb1) + mstore(0x20, p0) + mstore(0x40, 0x60) + mstore(0x60, p2) + writeString(0x80, p1) + } + _sendLogPayload(0x1c, 0xa4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(address p0, bytes32 p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(address,string,uint256)`. + mstore(0x00, 0x67dd6ff1) + mstore(0x20, p0) + mstore(0x40, 0x60) + mstore(0x60, p2) + writeString(0x80, p1) + } + _sendLogPayload(0x1c, 0xa4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(address p0, bytes32 p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + // Selector of `log(address,string,string)`. + mstore(0x00, 0xfb772265) + mstore(0x20, p0) + mstore(0x40, 0x60) + mstore(0x60, 0xa0) + writeString(0x80, p1) + writeString(0xc0, p2) + } + _sendLogPayload(0x1c, 0xe4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + } + } + + function log(bool p0, address p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(bool,address,address)`. + mstore(0x00, 0xd2763667) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(bool p0, address p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(bool,address,bool)`. + mstore(0x00, 0x18c9c746) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(bool p0, address p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(bool,address,uint256)`. + mstore(0x00, 0x5f7b9afb) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(bool p0, address p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(bool,address,string)`. + mstore(0x00, 0xde9a9270) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x60) + writeString(0x80, p2) + } + _sendLogPayload(0x1c, 0xa4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bool p0, bool p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(bool,bool,address)`. + mstore(0x00, 0x1078f68d) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(bool p0, bool p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(bool,bool,bool)`. + mstore(0x00, 0x50709698) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(bool p0, bool p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(bool,bool,uint256)`. + mstore(0x00, 0x12f21602) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(bool p0, bool p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(bool,bool,string)`. + mstore(0x00, 0x2555fa46) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x60) + writeString(0x80, p2) + } + _sendLogPayload(0x1c, 0xa4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bool p0, uint256 p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(bool,uint256,address)`. + mstore(0x00, 0x088ef9d2) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(bool p0, uint256 p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(bool,uint256,bool)`. + mstore(0x00, 0xe8defba9) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(bool p0, uint256 p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(bool,uint256,uint256)`. + mstore(0x00, 0x37103367) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(bool p0, uint256 p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(bool,uint256,string)`. + mstore(0x00, 0xc3fc3970) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x60) + writeString(0x80, p2) + } + _sendLogPayload(0x1c, 0xa4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bool p0, bytes32 p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(bool,string,address)`. + mstore(0x00, 0x9591b953) + mstore(0x20, p0) + mstore(0x40, 0x60) + mstore(0x60, p2) + writeString(0x80, p1) + } + _sendLogPayload(0x1c, 0xa4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bool p0, bytes32 p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(bool,string,bool)`. + mstore(0x00, 0xdbb4c247) + mstore(0x20, p0) + mstore(0x40, 0x60) + mstore(0x60, p2) + writeString(0x80, p1) + } + _sendLogPayload(0x1c, 0xa4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bool p0, bytes32 p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(bool,string,uint256)`. + mstore(0x00, 0x1093ee11) + mstore(0x20, p0) + mstore(0x40, 0x60) + mstore(0x60, p2) + writeString(0x80, p1) + } + _sendLogPayload(0x1c, 0xa4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bool p0, bytes32 p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + // Selector of `log(bool,string,string)`. + mstore(0x00, 0xb076847f) + mstore(0x20, p0) + mstore(0x40, 0x60) + mstore(0x60, 0xa0) + writeString(0x80, p1) + writeString(0xc0, p2) + } + _sendLogPayload(0x1c, 0xe4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + } + } + + function log(uint256 p0, address p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(uint256,address,address)`. + mstore(0x00, 0xbcfd9be0) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(uint256 p0, address p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(uint256,address,bool)`. + mstore(0x00, 0x9b6ec042) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(uint256 p0, address p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(uint256,address,uint256)`. + mstore(0x00, 0x5a9b5ed5) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(uint256 p0, address p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(uint256,address,string)`. + mstore(0x00, 0x63cb41f9) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x60) + writeString(0x80, p2) + } + _sendLogPayload(0x1c, 0xa4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(uint256 p0, bool p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(uint256,bool,address)`. + mstore(0x00, 0x35085f7b) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(uint256 p0, bool p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(uint256,bool,bool)`. + mstore(0x00, 0x20718650) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(uint256 p0, bool p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(uint256,bool,uint256)`. + mstore(0x00, 0x20098014) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(uint256 p0, bool p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(uint256,bool,string)`. + mstore(0x00, 0x85775021) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x60) + writeString(0x80, p2) + } + _sendLogPayload(0x1c, 0xa4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(uint256 p0, uint256 p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(uint256,uint256,address)`. + mstore(0x00, 0x5c96b331) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(uint256 p0, uint256 p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(uint256,uint256,bool)`. + mstore(0x00, 0x4766da72) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(uint256 p0, uint256 p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(uint256,uint256,uint256)`. + mstore(0x00, 0xd1ed7a3c) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(uint256 p0, uint256 p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(uint256,uint256,string)`. + mstore(0x00, 0x71d04af2) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x60) + writeString(0x80, p2) + } + _sendLogPayload(0x1c, 0xa4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(uint256 p0, bytes32 p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(uint256,string,address)`. + mstore(0x00, 0x7afac959) + mstore(0x20, p0) + mstore(0x40, 0x60) + mstore(0x60, p2) + writeString(0x80, p1) + } + _sendLogPayload(0x1c, 0xa4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(uint256 p0, bytes32 p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(uint256,string,bool)`. + mstore(0x00, 0x4ceda75a) + mstore(0x20, p0) + mstore(0x40, 0x60) + mstore(0x60, p2) + writeString(0x80, p1) + } + _sendLogPayload(0x1c, 0xa4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(uint256 p0, bytes32 p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(uint256,string,uint256)`. + mstore(0x00, 0x37aa7d4c) + mstore(0x20, p0) + mstore(0x40, 0x60) + mstore(0x60, p2) + writeString(0x80, p1) + } + _sendLogPayload(0x1c, 0xa4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(uint256 p0, bytes32 p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + // Selector of `log(uint256,string,string)`. + mstore(0x00, 0xb115611f) + mstore(0x20, p0) + mstore(0x40, 0x60) + mstore(0x60, 0xa0) + writeString(0x80, p1) + writeString(0xc0, p2) + } + _sendLogPayload(0x1c, 0xe4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + } + } + + function log(bytes32 p0, address p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(string,address,address)`. + mstore(0x00, 0xfcec75e0) + mstore(0x20, 0x60) + mstore(0x40, p1) + mstore(0x60, p2) + writeString(0x80, p0) + } + _sendLogPayload(0x1c, 0xa4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bytes32 p0, address p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(string,address,bool)`. + mstore(0x00, 0xc91d5ed4) + mstore(0x20, 0x60) + mstore(0x40, p1) + mstore(0x60, p2) + writeString(0x80, p0) + } + _sendLogPayload(0x1c, 0xa4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bytes32 p0, address p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(string,address,uint256)`. + mstore(0x00, 0x0d26b925) + mstore(0x20, 0x60) + mstore(0x40, p1) + mstore(0x60, p2) + writeString(0x80, p0) + } + _sendLogPayload(0x1c, 0xa4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bytes32 p0, address p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + // Selector of `log(string,address,string)`. + mstore(0x00, 0xe0e9ad4f) + mstore(0x20, 0x60) + mstore(0x40, p1) + mstore(0x60, 0xa0) + writeString(0x80, p0) + writeString(0xc0, p2) + } + _sendLogPayload(0x1c, 0xe4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + } + } + + function log(bytes32 p0, bool p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(string,bool,address)`. + mstore(0x00, 0x932bbb38) + mstore(0x20, 0x60) + mstore(0x40, p1) + mstore(0x60, p2) + writeString(0x80, p0) + } + _sendLogPayload(0x1c, 0xa4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bytes32 p0, bool p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(string,bool,bool)`. + mstore(0x00, 0x850b7ad6) + mstore(0x20, 0x60) + mstore(0x40, p1) + mstore(0x60, p2) + writeString(0x80, p0) + } + _sendLogPayload(0x1c, 0xa4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bytes32 p0, bool p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(string,bool,uint256)`. + mstore(0x00, 0xc95958d6) + mstore(0x20, 0x60) + mstore(0x40, p1) + mstore(0x60, p2) + writeString(0x80, p0) + } + _sendLogPayload(0x1c, 0xa4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bytes32 p0, bool p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + // Selector of `log(string,bool,string)`. + mstore(0x00, 0xe298f47d) + mstore(0x20, 0x60) + mstore(0x40, p1) + mstore(0x60, 0xa0) + writeString(0x80, p0) + writeString(0xc0, p2) + } + _sendLogPayload(0x1c, 0xe4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + } + } + + function log(bytes32 p0, uint256 p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(string,uint256,address)`. + mstore(0x00, 0x1c7ec448) + mstore(0x20, 0x60) + mstore(0x40, p1) + mstore(0x60, p2) + writeString(0x80, p0) + } + _sendLogPayload(0x1c, 0xa4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bytes32 p0, uint256 p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(string,uint256,bool)`. + mstore(0x00, 0xca7733b1) + mstore(0x20, 0x60) + mstore(0x40, p1) + mstore(0x60, p2) + writeString(0x80, p0) + } + _sendLogPayload(0x1c, 0xa4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bytes32 p0, uint256 p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(string,uint256,uint256)`. + mstore(0x00, 0xca47c4eb) + mstore(0x20, 0x60) + mstore(0x40, p1) + mstore(0x60, p2) + writeString(0x80, p0) + } + _sendLogPayload(0x1c, 0xa4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bytes32 p0, uint256 p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + // Selector of `log(string,uint256,string)`. + mstore(0x00, 0x5970e089) + mstore(0x20, 0x60) + mstore(0x40, p1) + mstore(0x60, 0xa0) + writeString(0x80, p0) + writeString(0xc0, p2) + } + _sendLogPayload(0x1c, 0xe4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + } + } + + function log(bytes32 p0, bytes32 p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + // Selector of `log(string,string,address)`. + mstore(0x00, 0x95ed0195) + mstore(0x20, 0x60) + mstore(0x40, 0xa0) + mstore(0x60, p2) + writeString(0x80, p0) + writeString(0xc0, p1) + } + _sendLogPayload(0x1c, 0xe4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + } + } + + function log(bytes32 p0, bytes32 p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + // Selector of `log(string,string,bool)`. + mstore(0x00, 0xb0e0f9b5) + mstore(0x20, 0x60) + mstore(0x40, 0xa0) + mstore(0x60, p2) + writeString(0x80, p0) + writeString(0xc0, p1) + } + _sendLogPayload(0x1c, 0xe4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + } + } + + function log(bytes32 p0, bytes32 p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + // Selector of `log(string,string,uint256)`. + mstore(0x00, 0x5821efa1) + mstore(0x20, 0x60) + mstore(0x40, 0xa0) + mstore(0x60, p2) + writeString(0x80, p0) + writeString(0xc0, p1) + } + _sendLogPayload(0x1c, 0xe4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + } + } + + function log(bytes32 p0, bytes32 p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + // Selector of `log(string,string,string)`. + mstore(0x00, 0x2ced7cef) + mstore(0x20, 0x60) + mstore(0x40, 0xa0) + mstore(0x60, 0xe0) + writeString(0x80, p0) + writeString(0xc0, p1) + writeString(0x100, p2) + } + _sendLogPayload(0x1c, 0x124); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + } + } + + function log(address p0, address p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,address,address,address)`. + mstore(0x00, 0x665bf134) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, address p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,address,address,bool)`. + mstore(0x00, 0x0e378994) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, address p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,address,address,uint256)`. + mstore(0x00, 0x94250d77) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, address p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,address,address,string)`. + mstore(0x00, 0xf808da20) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, address p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,address,bool,address)`. + mstore(0x00, 0x9f1bc36e) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, address p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,address,bool,bool)`. + mstore(0x00, 0x2cd4134a) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, address p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,address,bool,uint256)`. + mstore(0x00, 0x3971e78c) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, address p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,address,bool,string)`. + mstore(0x00, 0xaa6540c8) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, address p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,address,uint256,address)`. + mstore(0x00, 0x8da6def5) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, address p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,address,uint256,bool)`. + mstore(0x00, 0x9b4254e2) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, address p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,address,uint256,uint256)`. + mstore(0x00, 0xbe553481) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, address p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,address,uint256,string)`. + mstore(0x00, 0xfdb4f990) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, address p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,address,string,address)`. + mstore(0x00, 0x8f736d16) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, address p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,address,string,bool)`. + mstore(0x00, 0x6f1a594e) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, address p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,address,string,uint256)`. + mstore(0x00, 0xef1cefe7) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, address p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(address,address,string,string)`. + mstore(0x00, 0x21bdaf25) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, 0xc0) + writeString(0xa0, p2) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(address p0, bool p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,bool,address,address)`. + mstore(0x00, 0x660375dd) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, bool p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,bool,address,bool)`. + mstore(0x00, 0xa6f50b0f) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, bool p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,bool,address,uint256)`. + mstore(0x00, 0xa75c59de) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, bool p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,bool,address,string)`. + mstore(0x00, 0x2dd778e6) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bool p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,bool,bool,address)`. + mstore(0x00, 0xcf394485) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, bool p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,bool,bool,bool)`. + mstore(0x00, 0xcac43479) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, bool p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,bool,bool,uint256)`. + mstore(0x00, 0x8c4e5de6) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, bool p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,bool,bool,string)`. + mstore(0x00, 0xdfc4a2e8) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bool p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,bool,uint256,address)`. + mstore(0x00, 0xccf790a1) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, bool p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,bool,uint256,bool)`. + mstore(0x00, 0xc4643e20) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, bool p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,bool,uint256,uint256)`. + mstore(0x00, 0x386ff5f4) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, bool p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,bool,uint256,string)`. + mstore(0x00, 0x0aa6cfad) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bool p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,bool,string,address)`. + mstore(0x00, 0x19fd4956) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bool p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,bool,string,bool)`. + mstore(0x00, 0x50ad461d) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bool p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,bool,string,uint256)`. + mstore(0x00, 0x80e6a20b) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bool p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(address,bool,string,string)`. + mstore(0x00, 0x475c5c33) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, 0xc0) + writeString(0xa0, p2) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(address p0, uint256 p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,uint256,address,address)`. + mstore(0x00, 0x478d1c62) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, uint256 p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,uint256,address,bool)`. + mstore(0x00, 0xa1bcc9b3) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, uint256 p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,uint256,address,uint256)`. + mstore(0x00, 0x100f650e) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, uint256 p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,uint256,address,string)`. + mstore(0x00, 0x1da986ea) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, uint256 p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,uint256,bool,address)`. + mstore(0x00, 0xa31bfdcc) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, uint256 p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,uint256,bool,bool)`. + mstore(0x00, 0x3bf5e537) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, uint256 p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,uint256,bool,uint256)`. + mstore(0x00, 0x22f6b999) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, uint256 p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,uint256,bool,string)`. + mstore(0x00, 0xc5ad85f9) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, uint256 p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,uint256,uint256,address)`. + mstore(0x00, 0x20e3984d) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, uint256 p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,uint256,uint256,bool)`. + mstore(0x00, 0x66f1bc67) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,uint256,uint256,uint256)`. + mstore(0x00, 0x34f0e636) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, uint256 p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,uint256,uint256,string)`. + mstore(0x00, 0x4a28c017) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, uint256 p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,uint256,string,address)`. + mstore(0x00, 0x5c430d47) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, uint256 p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,uint256,string,bool)`. + mstore(0x00, 0xcf18105c) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, uint256 p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,uint256,string,uint256)`. + mstore(0x00, 0xbf01f891) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, uint256 p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(address,uint256,string,string)`. + mstore(0x00, 0x88a8c406) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, 0xc0) + writeString(0xa0, p2) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(address p0, bytes32 p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,string,address,address)`. + mstore(0x00, 0x0d36fa20) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bytes32 p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,string,address,bool)`. + mstore(0x00, 0x0df12b76) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bytes32 p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,string,address,uint256)`. + mstore(0x00, 0x457fe3cf) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bytes32 p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(address,string,address,string)`. + mstore(0x00, 0xf7e36245) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p1) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(address p0, bytes32 p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,string,bool,address)`. + mstore(0x00, 0x205871c2) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bytes32 p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,string,bool,bool)`. + mstore(0x00, 0x5f1d5c9f) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bytes32 p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,string,bool,uint256)`. + mstore(0x00, 0x515e38b6) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bytes32 p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(address,string,bool,string)`. + mstore(0x00, 0xbc0b61fe) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p1) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(address p0, bytes32 p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,string,uint256,address)`. + mstore(0x00, 0x63183678) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bytes32 p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,string,uint256,bool)`. + mstore(0x00, 0x0ef7e050) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bytes32 p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,string,uint256,uint256)`. + mstore(0x00, 0x1dc8e1b8) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bytes32 p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(address,string,uint256,string)`. + mstore(0x00, 0x448830a8) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p1) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(address p0, bytes32 p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(address,string,string,address)`. + mstore(0x00, 0xa04e2f87) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p1) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(address p0, bytes32 p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(address,string,string,bool)`. + mstore(0x00, 0x35a5071f) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p1) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(address p0, bytes32 p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(address,string,string,uint256)`. + mstore(0x00, 0x159f8927) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p1) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(address p0, bytes32 p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + // Selector of `log(address,string,string,string)`. + mstore(0x00, 0x5d02c50b) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, 0xc0) + mstore(0x80, 0x100) + writeString(0xa0, p1) + writeString(0xe0, p2) + writeString(0x120, p3) + } + _sendLogPayload(0x1c, 0x144); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + } + } + + function log(bool p0, address p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,address,address,address)`. + mstore(0x00, 0x1d14d001) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, address p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,address,address,bool)`. + mstore(0x00, 0x46600be0) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, address p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,address,address,uint256)`. + mstore(0x00, 0x0c66d1be) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, address p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,address,address,string)`. + mstore(0x00, 0xd812a167) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, address p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,address,bool,address)`. + mstore(0x00, 0x1c41a336) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, address p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,address,bool,bool)`. + mstore(0x00, 0x6a9c478b) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, address p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,address,bool,uint256)`. + mstore(0x00, 0x07831502) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, address p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,address,bool,string)`. + mstore(0x00, 0x4a66cb34) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, address p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,address,uint256,address)`. + mstore(0x00, 0x136b05dd) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, address p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,address,uint256,bool)`. + mstore(0x00, 0xd6019f1c) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, address p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,address,uint256,uint256)`. + mstore(0x00, 0x7bf181a1) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, address p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,address,uint256,string)`. + mstore(0x00, 0x51f09ff8) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, address p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,address,string,address)`. + mstore(0x00, 0x6f7c603e) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, address p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,address,string,bool)`. + mstore(0x00, 0xe2bfd60b) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, address p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,address,string,uint256)`. + mstore(0x00, 0xc21f64c7) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, address p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(bool,address,string,string)`. + mstore(0x00, 0xa73c1db6) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, 0xc0) + writeString(0xa0, p2) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bool p0, bool p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,bool,address,address)`. + mstore(0x00, 0xf4880ea4) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, bool p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,bool,address,bool)`. + mstore(0x00, 0xc0a302d8) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, bool p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,bool,address,uint256)`. + mstore(0x00, 0x4c123d57) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, bool p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,bool,address,string)`. + mstore(0x00, 0xa0a47963) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bool p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,bool,bool,address)`. + mstore(0x00, 0x8c329b1a) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, bool p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,bool,bool,bool)`. + mstore(0x00, 0x3b2a5ce0) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, bool p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,bool,bool,uint256)`. + mstore(0x00, 0x6d7045c1) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, bool p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,bool,bool,string)`. + mstore(0x00, 0x2ae408d4) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bool p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,bool,uint256,address)`. + mstore(0x00, 0x54a7a9a0) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, bool p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,bool,uint256,bool)`. + mstore(0x00, 0x619e4d0e) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, bool p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,bool,uint256,uint256)`. + mstore(0x00, 0x0bb00eab) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, bool p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,bool,uint256,string)`. + mstore(0x00, 0x7dd4d0e0) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bool p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,bool,string,address)`. + mstore(0x00, 0xf9ad2b89) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bool p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,bool,string,bool)`. + mstore(0x00, 0xb857163a) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bool p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,bool,string,uint256)`. + mstore(0x00, 0xe3a9ca2f) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bool p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(bool,bool,string,string)`. + mstore(0x00, 0x6d1e8751) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, 0xc0) + writeString(0xa0, p2) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bool p0, uint256 p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,uint256,address,address)`. + mstore(0x00, 0x26f560a8) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, uint256 p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,uint256,address,bool)`. + mstore(0x00, 0xb4c314ff) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, uint256 p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,uint256,address,uint256)`. + mstore(0x00, 0x1537dc87) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, uint256 p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,uint256,address,string)`. + mstore(0x00, 0x1bb3b09a) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, uint256 p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,uint256,bool,address)`. + mstore(0x00, 0x9acd3616) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, uint256 p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,uint256,bool,bool)`. + mstore(0x00, 0xceb5f4d7) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, uint256 p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,uint256,bool,uint256)`. + mstore(0x00, 0x7f9bbca2) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, uint256 p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,uint256,bool,string)`. + mstore(0x00, 0x9143dbb1) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, uint256 p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,uint256,uint256,address)`. + mstore(0x00, 0x00dd87b9) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, uint256 p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,uint256,uint256,bool)`. + mstore(0x00, 0xbe984353) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,uint256,uint256,uint256)`. + mstore(0x00, 0x374bb4b2) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, uint256 p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,uint256,uint256,string)`. + mstore(0x00, 0x8e69fb5d) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, uint256 p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,uint256,string,address)`. + mstore(0x00, 0xfedd1fff) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, uint256 p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,uint256,string,bool)`. + mstore(0x00, 0xe5e70b2b) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, uint256 p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,uint256,string,uint256)`. + mstore(0x00, 0x6a1199e2) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, uint256 p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(bool,uint256,string,string)`. + mstore(0x00, 0xf5bc2249) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, 0xc0) + writeString(0xa0, p2) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bool p0, bytes32 p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,string,address,address)`. + mstore(0x00, 0x2b2b18dc) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bytes32 p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,string,address,bool)`. + mstore(0x00, 0x6dd434ca) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bytes32 p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,string,address,uint256)`. + mstore(0x00, 0xa5cada94) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bytes32 p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(bool,string,address,string)`. + mstore(0x00, 0x12d6c788) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p1) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bool p0, bytes32 p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,string,bool,address)`. + mstore(0x00, 0x538e06ab) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bytes32 p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,string,bool,bool)`. + mstore(0x00, 0xdc5e935b) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bytes32 p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,string,bool,uint256)`. + mstore(0x00, 0x1606a393) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bytes32 p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(bool,string,bool,string)`. + mstore(0x00, 0x483d0416) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p1) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bool p0, bytes32 p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,string,uint256,address)`. + mstore(0x00, 0x1596a1ce) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bytes32 p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,string,uint256,bool)`. + mstore(0x00, 0x6b0e5d53) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bytes32 p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,string,uint256,uint256)`. + mstore(0x00, 0x28863fcb) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bytes32 p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(bool,string,uint256,string)`. + mstore(0x00, 0x1ad96de6) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p1) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bool p0, bytes32 p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(bool,string,string,address)`. + mstore(0x00, 0x97d394d8) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p1) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bool p0, bytes32 p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(bool,string,string,bool)`. + mstore(0x00, 0x1e4b87e5) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p1) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bool p0, bytes32 p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(bool,string,string,uint256)`. + mstore(0x00, 0x7be0c3eb) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p1) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bool p0, bytes32 p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + // Selector of `log(bool,string,string,string)`. + mstore(0x00, 0x1762e32a) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, 0xc0) + mstore(0x80, 0x100) + writeString(0xa0, p1) + writeString(0xe0, p2) + writeString(0x120, p3) + } + _sendLogPayload(0x1c, 0x144); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + } + } + + function log(uint256 p0, address p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,address,address,address)`. + mstore(0x00, 0x2488b414) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, address p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,address,address,bool)`. + mstore(0x00, 0x091ffaf5) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, address p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,address,address,uint256)`. + mstore(0x00, 0x736efbb6) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, address p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,address,address,string)`. + mstore(0x00, 0x031c6f73) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, address p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,address,bool,address)`. + mstore(0x00, 0xef72c513) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, address p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,address,bool,bool)`. + mstore(0x00, 0xe351140f) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, address p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,address,bool,uint256)`. + mstore(0x00, 0x5abd992a) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, address p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,address,bool,string)`. + mstore(0x00, 0x90fb06aa) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, address p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,address,uint256,address)`. + mstore(0x00, 0x15c127b5) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, address p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,address,uint256,bool)`. + mstore(0x00, 0x5f743a7c) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,address,uint256,uint256)`. + mstore(0x00, 0x0c9cd9c1) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, address p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,address,uint256,string)`. + mstore(0x00, 0xddb06521) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, address p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,address,string,address)`. + mstore(0x00, 0x9cba8fff) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, address p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,address,string,bool)`. + mstore(0x00, 0xcc32ab07) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, address p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,address,string,uint256)`. + mstore(0x00, 0x46826b5d) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, address p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(uint256,address,string,string)`. + mstore(0x00, 0x3e128ca3) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, 0xc0) + writeString(0xa0, p2) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(uint256 p0, bool p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,bool,address,address)`. + mstore(0x00, 0xa1ef4cbb) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, bool p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,bool,address,bool)`. + mstore(0x00, 0x454d54a5) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, bool p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,bool,address,uint256)`. + mstore(0x00, 0x078287f5) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, bool p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,bool,address,string)`. + mstore(0x00, 0xade052c7) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bool p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,bool,bool,address)`. + mstore(0x00, 0x69640b59) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, bool p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,bool,bool,bool)`. + mstore(0x00, 0xb6f577a1) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, bool p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,bool,bool,uint256)`. + mstore(0x00, 0x7464ce23) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, bool p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,bool,bool,string)`. + mstore(0x00, 0xdddb9561) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bool p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,bool,uint256,address)`. + mstore(0x00, 0x88cb6041) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, bool p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,bool,uint256,bool)`. + mstore(0x00, 0x91a02e2a) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,bool,uint256,uint256)`. + mstore(0x00, 0xc6acc7a8) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, bool p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,bool,uint256,string)`. + mstore(0x00, 0xde03e774) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bool p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,bool,string,address)`. + mstore(0x00, 0xef529018) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bool p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,bool,string,bool)`. + mstore(0x00, 0xeb928d7f) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bool p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,bool,string,uint256)`. + mstore(0x00, 0x2c1d0746) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bool p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(uint256,bool,string,string)`. + mstore(0x00, 0x68c8b8bd) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, 0xc0) + writeString(0xa0, p2) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(uint256 p0, uint256 p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,uint256,address,address)`. + mstore(0x00, 0x56a5d1b1) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, uint256 p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,uint256,address,bool)`. + mstore(0x00, 0x15cac476) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,uint256,address,uint256)`. + mstore(0x00, 0x88f6e4b2) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, uint256 p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,uint256,address,string)`. + mstore(0x00, 0x6cde40b8) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, uint256 p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,uint256,bool,address)`. + mstore(0x00, 0x9a816a83) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, uint256 p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,uint256,bool,bool)`. + mstore(0x00, 0xab085ae6) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,uint256,bool,uint256)`. + mstore(0x00, 0xeb7f6fd2) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, uint256 p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,uint256,bool,string)`. + mstore(0x00, 0xa5b4fc99) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,uint256,uint256,address)`. + mstore(0x00, 0xfa8185af) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,uint256,uint256,bool)`. + mstore(0x00, 0xc598d185) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,uint256,uint256,uint256)`. + mstore(0x00, 0x193fb800) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, uint256 p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,uint256,uint256,string)`. + mstore(0x00, 0x59cfcbe3) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, uint256 p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,uint256,string,address)`. + mstore(0x00, 0x42d21db7) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, uint256 p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,uint256,string,bool)`. + mstore(0x00, 0x7af6ab25) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, uint256 p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,uint256,string,uint256)`. + mstore(0x00, 0x5da297eb) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, uint256 p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(uint256,uint256,string,string)`. + mstore(0x00, 0x27d8afd2) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, 0xc0) + writeString(0xa0, p2) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(uint256 p0, bytes32 p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,string,address,address)`. + mstore(0x00, 0x6168ed61) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bytes32 p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,string,address,bool)`. + mstore(0x00, 0x90c30a56) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bytes32 p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,string,address,uint256)`. + mstore(0x00, 0xe8d3018d) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bytes32 p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(uint256,string,address,string)`. + mstore(0x00, 0x9c3adfa1) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p1) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(uint256 p0, bytes32 p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,string,bool,address)`. + mstore(0x00, 0xae2ec581) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bytes32 p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,string,bool,bool)`. + mstore(0x00, 0xba535d9c) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bytes32 p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,string,bool,uint256)`. + mstore(0x00, 0xcf009880) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bytes32 p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(uint256,string,bool,string)`. + mstore(0x00, 0xd2d423cd) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p1) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(uint256 p0, bytes32 p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,string,uint256,address)`. + mstore(0x00, 0x3b2279b4) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bytes32 p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,string,uint256,bool)`. + mstore(0x00, 0x691a8f74) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bytes32 p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,string,uint256,uint256)`. + mstore(0x00, 0x82c25b74) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bytes32 p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(uint256,string,uint256,string)`. + mstore(0x00, 0xb7b914ca) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p1) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(uint256 p0, bytes32 p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(uint256,string,string,address)`. + mstore(0x00, 0xd583c602) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p1) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(uint256 p0, bytes32 p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(uint256,string,string,bool)`. + mstore(0x00, 0xb3a6b6bd) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p1) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(uint256 p0, bytes32 p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(uint256,string,string,uint256)`. + mstore(0x00, 0xb028c9bd) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p1) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(uint256 p0, bytes32 p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + // Selector of `log(uint256,string,string,string)`. + mstore(0x00, 0x21ad0683) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, 0xc0) + mstore(0x80, 0x100) + writeString(0xa0, p1) + writeString(0xe0, p2) + writeString(0x120, p3) + } + _sendLogPayload(0x1c, 0x144); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + } + } + + function log(bytes32 p0, address p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,address,address,address)`. + mstore(0x00, 0xed8f28f6) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, address p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,address,address,bool)`. + mstore(0x00, 0xb59dbd60) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, address p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,address,address,uint256)`. + mstore(0x00, 0x8ef3f399) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, address p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,address,address,string)`. + mstore(0x00, 0x800a1c67) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p0) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, address p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,address,bool,address)`. + mstore(0x00, 0x223603bd) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, address p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,address,bool,bool)`. + mstore(0x00, 0x79884c2b) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, address p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,address,bool,uint256)`. + mstore(0x00, 0x3e9f866a) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, address p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,address,bool,string)`. + mstore(0x00, 0x0454c079) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p0) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, address p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,address,uint256,address)`. + mstore(0x00, 0x63fb8bc5) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, address p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,address,uint256,bool)`. + mstore(0x00, 0xfc4845f0) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, address p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,address,uint256,uint256)`. + mstore(0x00, 0xf8f51b1e) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, address p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,address,uint256,string)`. + mstore(0x00, 0x5a477632) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p0) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, address p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,address,string,address)`. + mstore(0x00, 0xaabc9a31) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, address p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,address,string,bool)`. + mstore(0x00, 0x5f15d28c) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, address p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,address,string,uint256)`. + mstore(0x00, 0x91d1112e) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, address p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + // Selector of `log(string,address,string,string)`. + mstore(0x00, 0x245986f2) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, 0xc0) + mstore(0x80, 0x100) + writeString(0xa0, p0) + writeString(0xe0, p2) + writeString(0x120, p3) + } + _sendLogPayload(0x1c, 0x144); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + } + } + + function log(bytes32 p0, bool p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,bool,address,address)`. + mstore(0x00, 0x33e9dd1d) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, bool p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,bool,address,bool)`. + mstore(0x00, 0x958c28c6) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, bool p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,bool,address,uint256)`. + mstore(0x00, 0x5d08bb05) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, bool p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,bool,address,string)`. + mstore(0x00, 0x2d8e33a4) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p0) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bool p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,bool,bool,address)`. + mstore(0x00, 0x7190a529) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, bool p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,bool,bool,bool)`. + mstore(0x00, 0x895af8c5) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, bool p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,bool,bool,uint256)`. + mstore(0x00, 0x8e3f78a9) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, bool p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,bool,bool,string)`. + mstore(0x00, 0x9d22d5dd) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p0) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bool p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,bool,uint256,address)`. + mstore(0x00, 0x935e09bf) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, bool p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,bool,uint256,bool)`. + mstore(0x00, 0x8af7cf8a) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, bool p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,bool,uint256,uint256)`. + mstore(0x00, 0x64b5bb67) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, bool p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,bool,uint256,string)`. + mstore(0x00, 0x742d6ee7) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p0) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bool p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,bool,string,address)`. + mstore(0x00, 0xe0625b29) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bool p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,bool,string,bool)`. + mstore(0x00, 0x3f8a701d) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bool p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,bool,string,uint256)`. + mstore(0x00, 0x24f91465) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bool p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + // Selector of `log(string,bool,string,string)`. + mstore(0x00, 0xa826caeb) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, 0xc0) + mstore(0x80, 0x100) + writeString(0xa0, p0) + writeString(0xe0, p2) + writeString(0x120, p3) + } + _sendLogPayload(0x1c, 0x144); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + } + } + + function log(bytes32 p0, uint256 p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,uint256,address,address)`. + mstore(0x00, 0x5ea2b7ae) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, uint256 p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,uint256,address,bool)`. + mstore(0x00, 0x82112a42) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, uint256 p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,uint256,address,uint256)`. + mstore(0x00, 0x4f04fdc6) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, uint256 p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,uint256,address,string)`. + mstore(0x00, 0x9ffb2f93) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p0) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, uint256 p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,uint256,bool,address)`. + mstore(0x00, 0xe0e95b98) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, uint256 p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,uint256,bool,bool)`. + mstore(0x00, 0x354c36d6) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, uint256 p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,uint256,bool,uint256)`. + mstore(0x00, 0xe41b6f6f) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, uint256 p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,uint256,bool,string)`. + mstore(0x00, 0xabf73a98) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p0) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, uint256 p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,uint256,uint256,address)`. + mstore(0x00, 0xe21de278) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, uint256 p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,uint256,uint256,bool)`. + mstore(0x00, 0x7626db92) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, uint256 p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,uint256,uint256,uint256)`. + mstore(0x00, 0xa7a87853) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, uint256 p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,uint256,uint256,string)`. + mstore(0x00, 0x854b3496) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p0) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, uint256 p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,uint256,string,address)`. + mstore(0x00, 0x7c4632a4) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, uint256 p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,uint256,string,bool)`. + mstore(0x00, 0x7d24491d) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, uint256 p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,uint256,string,uint256)`. + mstore(0x00, 0xc67ea9d1) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, uint256 p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + // Selector of `log(string,uint256,string,string)`. + mstore(0x00, 0x5ab84e1f) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, 0xc0) + mstore(0x80, 0x100) + writeString(0xa0, p0) + writeString(0xe0, p2) + writeString(0x120, p3) + } + _sendLogPayload(0x1c, 0x144); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + } + } + + function log(bytes32 p0, bytes32 p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,string,address,address)`. + mstore(0x00, 0x439c7bef) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p1) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bytes32 p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,string,address,bool)`. + mstore(0x00, 0x5ccd4e37) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p1) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bytes32 p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,string,address,uint256)`. + mstore(0x00, 0x7cc3c607) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p1) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bytes32 p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + // Selector of `log(string,string,address,string)`. + mstore(0x00, 0xeb1bff80) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, p2) + mstore(0x80, 0x100) + writeString(0xa0, p0) + writeString(0xe0, p1) + writeString(0x120, p3) + } + _sendLogPayload(0x1c, 0x144); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + } + } + + function log(bytes32 p0, bytes32 p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,string,bool,address)`. + mstore(0x00, 0xc371c7db) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p1) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bytes32 p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,string,bool,bool)`. + mstore(0x00, 0x40785869) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p1) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bytes32 p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,string,bool,uint256)`. + mstore(0x00, 0xd6aefad2) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p1) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bytes32 p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + // Selector of `log(string,string,bool,string)`. + mstore(0x00, 0x5e84b0ea) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, p2) + mstore(0x80, 0x100) + writeString(0xa0, p0) + writeString(0xe0, p1) + writeString(0x120, p3) + } + _sendLogPayload(0x1c, 0x144); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + } + } + + function log(bytes32 p0, bytes32 p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,string,uint256,address)`. + mstore(0x00, 0x1023f7b2) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p1) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bytes32 p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,string,uint256,bool)`. + mstore(0x00, 0xc3a8a654) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p1) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bytes32 p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,string,uint256,uint256)`. + mstore(0x00, 0xf45d7d2c) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p1) + } + _sendLogPayload(0x1c, 0x104); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bytes32 p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + // Selector of `log(string,string,uint256,string)`. + mstore(0x00, 0x5d1a971a) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, p2) + mstore(0x80, 0x100) + writeString(0xa0, p0) + writeString(0xe0, p1) + writeString(0x120, p3) + } + _sendLogPayload(0x1c, 0x144); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + } + } + + function log(bytes32 p0, bytes32 p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + // Selector of `log(string,string,string,address)`. + mstore(0x00, 0x6d572f44) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, 0x100) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p1) + writeString(0x120, p2) + } + _sendLogPayload(0x1c, 0x144); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + } + } + + function log(bytes32 p0, bytes32 p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + // Selector of `log(string,string,string,bool)`. + mstore(0x00, 0x2c1754ed) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, 0x100) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p1) + writeString(0x120, p2) + } + _sendLogPayload(0x1c, 0x144); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + } + } + + function log(bytes32 p0, bytes32 p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + // Selector of `log(string,string,string,uint256)`. + mstore(0x00, 0x8eafb02b) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, 0x100) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p1) + writeString(0x120, p2) + } + _sendLogPayload(0x1c, 0x144); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + } + } + + function log(bytes32 p0, bytes32 p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + bytes32 m11; + bytes32 m12; + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + m11 := mload(0x160) + m12 := mload(0x180) + // Selector of `log(string,string,string,string)`. + mstore(0x00, 0xde68f20a) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, 0x100) + mstore(0x80, 0x140) + writeString(0xa0, p0) + writeString(0xe0, p1) + writeString(0x120, p2) + writeString(0x160, p3) + } + _sendLogPayload(0x1c, 0x184); + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + mstore(0x160, m11) + mstore(0x180, m12) + } + } +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/StdAssertions.t.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/StdAssertions.t.sol new file mode 100644 index 0000000000..fcc346be66 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/StdAssertions.t.sol @@ -0,0 +1,999 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import "../src/Test.sol"; + +contract StdAssertionsTest is Test { + string constant CUSTOM_ERROR = "guh!"; + + bool constant EXPECT_PASS = false; + bool constant EXPECT_FAIL = true; + + bool constant SHOULD_REVERT = true; + bool constant SHOULD_RETURN = false; + + bool constant STRICT_REVERT_DATA = true; + bool constant NON_STRICT_REVERT_DATA = false; + + TestTest t = new TestTest(); + + /*////////////////////////////////////////////////////////////////////////// + FAIL(STRING) + //////////////////////////////////////////////////////////////////////////*/ + + function testShouldFail() external { + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._fail(CUSTOM_ERROR); + } + + /*////////////////////////////////////////////////////////////////////////// + ASSERT_FALSE + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertFalse_Pass() external { + t._assertFalse(false, EXPECT_PASS); + } + + function testAssertFalse_Fail() external { + vm.expectEmit(false, false, false, true); + emit log("Error: Assertion Failed"); + t._assertFalse(true, EXPECT_FAIL); + } + + function testAssertFalse_Err_Pass() external { + t._assertFalse(false, CUSTOM_ERROR, EXPECT_PASS); + } + + function testAssertFalse_Err_Fail() external { + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._assertFalse(true, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + ASSERT_EQ(BOOL) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertEq_Bool_Pass(bool a) external { + t._assertEq(a, a, EXPECT_PASS); + } + + function testAssertEq_Bool_Fail(bool a, bool b) external { + vm.assume(a != b); + + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [bool]"); + t._assertEq(a, b, EXPECT_FAIL); + } + + function testAssertEq_BoolErr_Pass(bool a) external { + t._assertEq(a, a, CUSTOM_ERROR, EXPECT_PASS); + } + + function testAssertEq_BoolErr_Fail(bool a, bool b) external { + vm.assume(a != b); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + ASSERT_EQ(BYTES) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertEq_Bytes_Pass(bytes calldata a) external { + t._assertEq(a, a, EXPECT_PASS); + } + + function testAssertEq_Bytes_Fail(bytes calldata a, bytes calldata b) external { + vm.assume(keccak256(a) != keccak256(b)); + + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [bytes]"); + t._assertEq(a, b, EXPECT_FAIL); + } + + function testAssertEq_BytesErr_Pass(bytes calldata a) external { + t._assertEq(a, a, CUSTOM_ERROR, EXPECT_PASS); + } + + function testAssertEq_BytesErr_Fail(bytes calldata a, bytes calldata b) external { + vm.assume(keccak256(a) != keccak256(b)); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + ASSERT_EQ(ARRAY) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertEq_UintArr_Pass(uint256 e0, uint256 e1, uint256 e2) public { + uint256[] memory a = new uint256[](3); + a[0] = e0; + a[1] = e1; + a[2] = e2; + uint256[] memory b = new uint256[](3); + b[0] = e0; + b[1] = e1; + b[2] = e2; + + t._assertEq(a, b, EXPECT_PASS); + } + + function testAssertEq_IntArr_Pass(int256 e0, int256 e1, int256 e2) public { + int256[] memory a = new int256[](3); + a[0] = e0; + a[1] = e1; + a[2] = e2; + int256[] memory b = new int256[](3); + b[0] = e0; + b[1] = e1; + b[2] = e2; + + t._assertEq(a, b, EXPECT_PASS); + } + + function testAssertEq_AddressArr_Pass(address e0, address e1, address e2) public { + address[] memory a = new address[](3); + a[0] = e0; + a[1] = e1; + a[2] = e2; + address[] memory b = new address[](3); + b[0] = e0; + b[1] = e1; + b[2] = e2; + + t._assertEq(a, b, EXPECT_PASS); + } + + function testAssertEq_UintArr_FailEl(uint256 e1) public { + vm.assume(e1 != 0); + uint256[] memory a = new uint256[](3); + uint256[] memory b = new uint256[](3); + b[1] = e1; + + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [uint[]]"); + t._assertEq(a, b, EXPECT_FAIL); + } + + function testAssertEq_IntArr_FailEl(int256 e1) public { + vm.assume(e1 != 0); + int256[] memory a = new int256[](3); + int256[] memory b = new int256[](3); + b[1] = e1; + + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [int[]]"); + t._assertEq(a, b, EXPECT_FAIL); + } + + function testAssertEq_AddressArr_FailEl(address e1) public { + vm.assume(e1 != address(0)); + address[] memory a = new address[](3); + address[] memory b = new address[](3); + b[1] = e1; + + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [address[]]"); + t._assertEq(a, b, EXPECT_FAIL); + } + + function testAssertEq_UintArrErr_FailEl(uint256 e1) public { + vm.assume(e1 != 0); + uint256[] memory a = new uint256[](3); + uint256[] memory b = new uint256[](3); + b[1] = e1; + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [uint[]]"); + t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); + } + + function testAssertEq_IntArrErr_FailEl(int256 e1) public { + vm.assume(e1 != 0); + int256[] memory a = new int256[](3); + int256[] memory b = new int256[](3); + b[1] = e1; + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [int[]]"); + t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); + } + + function testAssertEq_AddressArrErr_FailEl(address e1) public { + vm.assume(e1 != address(0)); + address[] memory a = new address[](3); + address[] memory b = new address[](3); + b[1] = e1; + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [address[]]"); + t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); + } + + function testAssertEq_UintArr_FailLen(uint256 lenA, uint256 lenB) public { + vm.assume(lenA != lenB); + vm.assume(lenA <= 10000); + vm.assume(lenB <= 10000); + uint256[] memory a = new uint256[](lenA); + uint256[] memory b = new uint256[](lenB); + + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [uint[]]"); + t._assertEq(a, b, EXPECT_FAIL); + } + + function testAssertEq_IntArr_FailLen(uint256 lenA, uint256 lenB) public { + vm.assume(lenA != lenB); + vm.assume(lenA <= 10000); + vm.assume(lenB <= 10000); + int256[] memory a = new int256[](lenA); + int256[] memory b = new int256[](lenB); + + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [int[]]"); + t._assertEq(a, b, EXPECT_FAIL); + } + + function testAssertEq_AddressArr_FailLen(uint256 lenA, uint256 lenB) public { + vm.assume(lenA != lenB); + vm.assume(lenA <= 10000); + vm.assume(lenB <= 10000); + address[] memory a = new address[](lenA); + address[] memory b = new address[](lenB); + + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [address[]]"); + t._assertEq(a, b, EXPECT_FAIL); + } + + function testAssertEq_UintArrErr_FailLen(uint256 lenA, uint256 lenB) public { + vm.assume(lenA != lenB); + vm.assume(lenA <= 10000); + vm.assume(lenB <= 10000); + uint256[] memory a = new uint256[](lenA); + uint256[] memory b = new uint256[](lenB); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [uint[]]"); + t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); + } + + function testAssertEq_IntArrErr_FailLen(uint256 lenA, uint256 lenB) public { + vm.assume(lenA != lenB); + vm.assume(lenA <= 10000); + vm.assume(lenB <= 10000); + int256[] memory a = new int256[](lenA); + int256[] memory b = new int256[](lenB); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [int[]]"); + t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); + } + + function testAssertEq_AddressArrErr_FailLen(uint256 lenA, uint256 lenB) public { + vm.assume(lenA != lenB); + vm.assume(lenA <= 10000); + vm.assume(lenB <= 10000); + address[] memory a = new address[](lenA); + address[] memory b = new address[](lenB); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + vm.expectEmit(false, false, false, true); + emit log("Error: a == b not satisfied [address[]]"); + t._assertEq(a, b, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + ASSERT_EQ(UINT) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertEqUint() public { + assertEqUint(uint8(1), uint128(1)); + assertEqUint(uint64(2), uint64(2)); + } + + function testFailAssertEqUint() public { + assertEqUint(uint64(1), uint96(2)); + assertEqUint(uint160(3), uint160(4)); + } + + /*////////////////////////////////////////////////////////////////////////// + APPROX_EQ_ABS(UINT) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertApproxEqAbs_Uint_Pass(uint256 a, uint256 b, uint256 maxDelta) external { + vm.assume(stdMath.delta(a, b) <= maxDelta); + + t._assertApproxEqAbs(a, b, maxDelta, EXPECT_PASS); + } + + function testAssertApproxEqAbs_Uint_Fail(uint256 a, uint256 b, uint256 maxDelta) external { + vm.assume(stdMath.delta(a, b) > maxDelta); + + vm.expectEmit(false, false, false, true); + emit log("Error: a ~= b not satisfied [uint]"); + t._assertApproxEqAbs(a, b, maxDelta, EXPECT_FAIL); + } + + function testAssertApproxEqAbs_UintErr_Pass(uint256 a, uint256 b, uint256 maxDelta) external { + vm.assume(stdMath.delta(a, b) <= maxDelta); + + t._assertApproxEqAbs(a, b, maxDelta, CUSTOM_ERROR, EXPECT_PASS); + } + + function testAssertApproxEqAbs_UintErr_Fail(uint256 a, uint256 b, uint256 maxDelta) external { + vm.assume(stdMath.delta(a, b) > maxDelta); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._assertApproxEqAbs(a, b, maxDelta, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + APPROX_EQ_ABS_DECIMAL(UINT) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertApproxEqAbsDecimal_Uint_Pass(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals) + external + { + vm.assume(stdMath.delta(a, b) <= maxDelta); + + t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, EXPECT_PASS); + } + + function testAssertApproxEqAbsDecimal_Uint_Fail(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals) + external + { + vm.assume(stdMath.delta(a, b) > maxDelta); + + vm.expectEmit(false, false, false, true); + emit log("Error: a ~= b not satisfied [uint]"); + t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, EXPECT_FAIL); + } + + function testAssertApproxEqAbsDecimal_UintErr_Pass(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals) + external + { + vm.assume(stdMath.delta(a, b) <= maxDelta); + + t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, CUSTOM_ERROR, EXPECT_PASS); + } + + function testAssertApproxEqAbsDecimal_UintErr_Fail(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals) + external + { + vm.assume(stdMath.delta(a, b) > maxDelta); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + APPROX_EQ_ABS(INT) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertApproxEqAbs_Int_Pass(int256 a, int256 b, uint256 maxDelta) external { + vm.assume(stdMath.delta(a, b) <= maxDelta); + + t._assertApproxEqAbs(a, b, maxDelta, EXPECT_PASS); + } + + function testAssertApproxEqAbs_Int_Fail(int256 a, int256 b, uint256 maxDelta) external { + vm.assume(stdMath.delta(a, b) > maxDelta); + + vm.expectEmit(false, false, false, true); + emit log("Error: a ~= b not satisfied [int]"); + t._assertApproxEqAbs(a, b, maxDelta, EXPECT_FAIL); + } + + function testAssertApproxEqAbs_IntErr_Pass(int256 a, int256 b, uint256 maxDelta) external { + vm.assume(stdMath.delta(a, b) <= maxDelta); + + t._assertApproxEqAbs(a, b, maxDelta, CUSTOM_ERROR, EXPECT_PASS); + } + + function testAssertApproxEqAbs_IntErr_Fail(int256 a, int256 b, uint256 maxDelta) external { + vm.assume(stdMath.delta(a, b) > maxDelta); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._assertApproxEqAbs(a, b, maxDelta, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + APPROX_EQ_ABS_DECIMAL(INT) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertApproxEqAbsDecimal_Int_Pass(int256 a, int256 b, uint256 maxDelta, uint256 decimals) external { + vm.assume(stdMath.delta(a, b) <= maxDelta); + + t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, EXPECT_PASS); + } + + function testAssertApproxEqAbsDecimal_Int_Fail(int256 a, int256 b, uint256 maxDelta, uint256 decimals) external { + vm.assume(stdMath.delta(a, b) > maxDelta); + + vm.expectEmit(false, false, false, true); + emit log("Error: a ~= b not satisfied [int]"); + t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, EXPECT_FAIL); + } + + function testAssertApproxEqAbsDecimal_IntErr_Pass(int256 a, int256 b, uint256 maxDelta, uint256 decimals) + external + { + vm.assume(stdMath.delta(a, b) <= maxDelta); + + t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, CUSTOM_ERROR, EXPECT_PASS); + } + + function testAssertApproxEqAbsDecimal_IntErr_Fail(int256 a, int256 b, uint256 maxDelta, uint256 decimals) + external + { + vm.assume(stdMath.delta(a, b) > maxDelta); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._assertApproxEqAbsDecimal(a, b, maxDelta, decimals, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + APPROX_EQ_REL(UINT) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertApproxEqRel_Uint_Pass(uint256 a, uint256 b, uint256 maxPercentDelta) external { + vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); + vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); + + t._assertApproxEqRel(a, b, maxPercentDelta, EXPECT_PASS); + } + + function testAssertApproxEqRel_Uint_Fail(uint256 a, uint256 b, uint256 maxPercentDelta) external { + vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); + vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); + + vm.expectEmit(false, false, false, true); + emit log("Error: a ~= b not satisfied [uint]"); + t._assertApproxEqRel(a, b, maxPercentDelta, EXPECT_FAIL); + } + + function testAssertApproxEqRel_UintErr_Pass(uint256 a, uint256 b, uint256 maxPercentDelta) external { + vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); + vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); + + t._assertApproxEqRel(a, b, maxPercentDelta, CUSTOM_ERROR, EXPECT_PASS); + } + + function testAssertApproxEqRel_UintErr_Fail(uint256 a, uint256 b, uint256 maxPercentDelta) external { + vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); + vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._assertApproxEqRel(a, b, maxPercentDelta, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + APPROX_EQ_REL_DECIMAL(UINT) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertApproxEqRelDecimal_Uint_Pass(uint256 a, uint256 b, uint256 maxPercentDelta, uint256 decimals) + external + { + vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); + vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); + + t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, EXPECT_PASS); + } + + function testAssertApproxEqRelDecimal_Uint_Fail(uint256 a, uint256 b, uint256 maxPercentDelta, uint256 decimals) + external + { + vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); + vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); + + vm.expectEmit(false, false, false, true); + emit log("Error: a ~= b not satisfied [uint]"); + t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, EXPECT_FAIL); + } + + function testAssertApproxEqRelDecimal_UintErr_Pass(uint256 a, uint256 b, uint256 maxPercentDelta, uint256 decimals) + external + { + vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); + vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); + + t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, CUSTOM_ERROR, EXPECT_PASS); + } + + function testAssertApproxEqRelDecimal_UintErr_Fail(uint256 a, uint256 b, uint256 maxPercentDelta, uint256 decimals) + external + { + vm.assume(a < type(uint128).max && b < type(uint128).max && b != 0); + vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + APPROX_EQ_REL(INT) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertApproxEqRel_Int_Pass(int128 a, int128 b, uint128 maxPercentDelta) external { + vm.assume(b != 0); + vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); + + t._assertApproxEqRel(a, b, maxPercentDelta, EXPECT_PASS); + } + + function testAssertApproxEqRel_Int_Fail(int128 a, int128 b, uint128 maxPercentDelta) external { + vm.assume(b != 0); + vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); + + vm.expectEmit(false, false, false, true); + emit log("Error: a ~= b not satisfied [int]"); + t._assertApproxEqRel(a, b, maxPercentDelta, EXPECT_FAIL); + } + + function testAssertApproxEqRel_IntErr_Pass(int128 a, int128 b, uint128 maxPercentDelta) external { + vm.assume(b != 0); + vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); + + t._assertApproxEqRel(a, b, maxPercentDelta, CUSTOM_ERROR, EXPECT_PASS); + } + + function testAssertApproxEqRel_IntErr_Fail(int128 a, int128 b, uint128 maxPercentDelta) external { + vm.assume(b != 0); + vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._assertApproxEqRel(a, b, maxPercentDelta, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + APPROX_EQ_REL_DECIMAL(INT) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertApproxEqRelDecimal_Int_Pass(int128 a, int128 b, uint128 maxPercentDelta, uint128 decimals) + external + { + vm.assume(b != 0); + vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); + + t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, EXPECT_PASS); + } + + function testAssertApproxEqRelDecimal_Int_Fail(int128 a, int128 b, uint128 maxPercentDelta, uint128 decimals) + external + { + vm.assume(b != 0); + vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); + + vm.expectEmit(false, false, false, true); + emit log("Error: a ~= b not satisfied [int]"); + t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, EXPECT_FAIL); + } + + function testAssertApproxEqRelDecimal_IntErr_Pass(int128 a, int128 b, uint128 maxPercentDelta, uint128 decimals) + external + { + vm.assume(b != 0); + vm.assume(stdMath.percentDelta(a, b) <= maxPercentDelta); + + t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, CUSTOM_ERROR, EXPECT_PASS); + } + + function testAssertApproxEqRelDecimal_IntErr_Fail(int128 a, int128 b, uint128 maxPercentDelta, uint128 decimals) + external + { + vm.assume(b != 0); + vm.assume(stdMath.percentDelta(a, b) > maxPercentDelta); + + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + ASSERT_EQ_CALL + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertEqCall_Return_Pass( + bytes memory callDataA, + bytes memory callDataB, + bytes memory returnData, + bool strictRevertData + ) external { + address targetA = address(new TestMockCall(returnData, SHOULD_RETURN)); + address targetB = address(new TestMockCall(returnData, SHOULD_RETURN)); + + t._assertEqCall(targetA, callDataA, targetB, callDataB, strictRevertData, EXPECT_PASS); + } + + function testAssertEqCall_Return_Fail( + bytes memory callDataA, + bytes memory callDataB, + bytes memory returnDataA, + bytes memory returnDataB, + bool strictRevertData + ) external { + vm.assume(keccak256(returnDataA) != keccak256(returnDataB)); + + address targetA = address(new TestMockCall(returnDataA, SHOULD_RETURN)); + address targetB = address(new TestMockCall(returnDataB, SHOULD_RETURN)); + + vm.expectEmit(true, true, true, true); + emit log_named_string("Error", "Call return data does not match"); + t._assertEqCall(targetA, callDataA, targetB, callDataB, strictRevertData, EXPECT_FAIL); + } + + function testAssertEqCall_Revert_Pass( + bytes memory callDataA, + bytes memory callDataB, + bytes memory revertDataA, + bytes memory revertDataB + ) external { + address targetA = address(new TestMockCall(revertDataA, SHOULD_REVERT)); + address targetB = address(new TestMockCall(revertDataB, SHOULD_REVERT)); + + t._assertEqCall(targetA, callDataA, targetB, callDataB, NON_STRICT_REVERT_DATA, EXPECT_PASS); + } + + function testAssertEqCall_Revert_Fail( + bytes memory callDataA, + bytes memory callDataB, + bytes memory revertDataA, + bytes memory revertDataB + ) external { + vm.assume(keccak256(revertDataA) != keccak256(revertDataB)); + + address targetA = address(new TestMockCall(revertDataA, SHOULD_REVERT)); + address targetB = address(new TestMockCall(revertDataB, SHOULD_REVERT)); + + vm.expectEmit(true, true, true, true); + emit log_named_string("Error", "Call revert data does not match"); + t._assertEqCall(targetA, callDataA, targetB, callDataB, STRICT_REVERT_DATA, EXPECT_FAIL); + } + + function testAssertEqCall_Fail( + bytes memory callDataA, + bytes memory callDataB, + bytes memory returnDataA, + bytes memory returnDataB, + bool strictRevertData + ) external { + address targetA = address(new TestMockCall(returnDataA, SHOULD_RETURN)); + address targetB = address(new TestMockCall(returnDataB, SHOULD_REVERT)); + + vm.expectEmit(true, true, true, true); + emit log_named_bytes(" Left call return data", returnDataA); + vm.expectEmit(true, true, true, true); + emit log_named_bytes(" Right call revert data", returnDataB); + t._assertEqCall(targetA, callDataA, targetB, callDataB, strictRevertData, EXPECT_FAIL); + + vm.expectEmit(true, true, true, true); + emit log_named_bytes(" Left call revert data", returnDataB); + vm.expectEmit(true, true, true, true); + emit log_named_bytes(" Right call return data", returnDataA); + t._assertEqCall(targetB, callDataB, targetA, callDataA, strictRevertData, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + ASSERT_NOT_EQ(BYTES) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertNotEq_Bytes_Pass(bytes32 a, bytes32 b) external { + vm.assume(a != b); + t._assertNotEq(a, b, EXPECT_PASS); + } + + function testAssertNotEq_Bytes_Fail(bytes32 a) external { + vm.expectEmit(false, false, false, true); + emit log("Error: a != b not satisfied [bytes32]"); + t._assertNotEq(a, a, EXPECT_FAIL); + } + + function testAssertNotEq_BytesErr_Pass(bytes32 a, bytes32 b) external { + vm.assume(a != b); + t._assertNotEq(a, b, CUSTOM_ERROR, EXPECT_PASS); + } + + function testAsserNottEq_BytesErr_Fail(bytes32 a) external { + vm.expectEmit(false, false, false, true); + emit log_named_string("Error", CUSTOM_ERROR); + t._assertNotEq(a, a, CUSTOM_ERROR, EXPECT_FAIL); + } + + /*////////////////////////////////////////////////////////////////////////// + ASSERT_NOT_EQ(UINT) + //////////////////////////////////////////////////////////////////////////*/ + + function testAssertNotEqUint() public { + assertNotEq(uint8(1), uint128(2)); + assertNotEq(uint64(3), uint64(4)); + } + + function testFailAssertNotEqUint() public { + assertNotEq(uint64(1), uint96(1)); + assertNotEq(uint160(2), uint160(2)); + } +} + +contract TestTest is Test { + modifier expectFailure(bool expectFail) { + bool preState = vm.load(HEVM_ADDRESS, bytes32("failed")) != bytes32(0x00); + _; + bool postState = vm.load(HEVM_ADDRESS, bytes32("failed")) != bytes32(0x00); + + if (preState == true) { + return; + } + + if (expectFail) { + require(postState == true, "expected failure not triggered"); + + // unwind the expected failure + vm.store(HEVM_ADDRESS, bytes32("failed"), bytes32(uint256(0x00))); + } else { + require(postState == false, "unexpected failure was triggered"); + } + } + + function _fail(string memory err) external expectFailure(true) { + fail(err); + } + + function _assertFalse(bool data, bool expectFail) external expectFailure(expectFail) { + assertFalse(data); + } + + function _assertFalse(bool data, string memory err, bool expectFail) external expectFailure(expectFail) { + assertFalse(data, err); + } + + function _assertEq(bool a, bool b, bool expectFail) external expectFailure(expectFail) { + assertEq(a, b); + } + + function _assertEq(bool a, bool b, string memory err, bool expectFail) external expectFailure(expectFail) { + assertEq(a, b, err); + } + + function _assertEq(bytes memory a, bytes memory b, bool expectFail) external expectFailure(expectFail) { + assertEq(a, b); + } + + function _assertEq(bytes memory a, bytes memory b, string memory err, bool expectFail) + external + expectFailure(expectFail) + { + assertEq(a, b, err); + } + + function _assertEq(uint256[] memory a, uint256[] memory b, bool expectFail) external expectFailure(expectFail) { + assertEq(a, b); + } + + function _assertEq(int256[] memory a, int256[] memory b, bool expectFail) external expectFailure(expectFail) { + assertEq(a, b); + } + + function _assertEq(address[] memory a, address[] memory b, bool expectFail) external expectFailure(expectFail) { + assertEq(a, b); + } + + function _assertEq(uint256[] memory a, uint256[] memory b, string memory err, bool expectFail) + external + expectFailure(expectFail) + { + assertEq(a, b, err); + } + + function _assertEq(int256[] memory a, int256[] memory b, string memory err, bool expectFail) + external + expectFailure(expectFail) + { + assertEq(a, b, err); + } + + function _assertEq(address[] memory a, address[] memory b, string memory err, bool expectFail) + external + expectFailure(expectFail) + { + assertEq(a, b, err); + } + + function _assertNotEq(bytes32 a, bytes32 b, bool expectFail) external expectFailure(expectFail) { + assertNotEq32(a, b); + } + + function _assertNotEq(bytes32 a, bytes32 b, string memory err, bool expectFail) + external + expectFailure(expectFail) + { + assertNotEq32(a, b, err); + } + + function _assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta, bool expectFail) + external + expectFailure(expectFail) + { + assertApproxEqAbs(a, b, maxDelta); + } + + function _assertApproxEqAbs(uint256 a, uint256 b, uint256 maxDelta, string memory err, bool expectFail) + external + expectFailure(expectFail) + { + assertApproxEqAbs(a, b, maxDelta, err); + } + + function _assertApproxEqAbsDecimal(uint256 a, uint256 b, uint256 maxDelta, uint256 decimals, bool expectFail) + external + expectFailure(expectFail) + { + assertApproxEqAbsDecimal(a, b, maxDelta, decimals); + } + + function _assertApproxEqAbsDecimal( + uint256 a, + uint256 b, + uint256 maxDelta, + uint256 decimals, + string memory err, + bool expectFail + ) external expectFailure(expectFail) { + assertApproxEqAbsDecimal(a, b, maxDelta, decimals, err); + } + + function _assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta, bool expectFail) + external + expectFailure(expectFail) + { + assertApproxEqAbs(a, b, maxDelta); + } + + function _assertApproxEqAbs(int256 a, int256 b, uint256 maxDelta, string memory err, bool expectFail) + external + expectFailure(expectFail) + { + assertApproxEqAbs(a, b, maxDelta, err); + } + + function _assertApproxEqAbsDecimal(int256 a, int256 b, uint256 maxDelta, uint256 decimals, bool expectFail) + external + expectFailure(expectFail) + { + assertApproxEqAbsDecimal(a, b, maxDelta, decimals); + } + + function _assertApproxEqAbsDecimal( + int256 a, + int256 b, + uint256 maxDelta, + uint256 decimals, + string memory err, + bool expectFail + ) external expectFailure(expectFail) { + assertApproxEqAbsDecimal(a, b, maxDelta, decimals, err); + } + + function _assertApproxEqRel(uint256 a, uint256 b, uint256 maxPercentDelta, bool expectFail) + external + expectFailure(expectFail) + { + assertApproxEqRel(a, b, maxPercentDelta); + } + + function _assertApproxEqRel(uint256 a, uint256 b, uint256 maxPercentDelta, string memory err, bool expectFail) + external + expectFailure(expectFail) + { + assertApproxEqRel(a, b, maxPercentDelta, err); + } + + function _assertApproxEqRelDecimal(uint256 a, uint256 b, uint256 maxPercentDelta, uint256 decimals, bool expectFail) + external + expectFailure(expectFail) + { + assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals); + } + + function _assertApproxEqRelDecimal( + uint256 a, + uint256 b, + uint256 maxPercentDelta, + uint256 decimals, + string memory err, + bool expectFail + ) external expectFailure(expectFail) { + assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, err); + } + + function _assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta, bool expectFail) + external + expectFailure(expectFail) + { + assertApproxEqRel(a, b, maxPercentDelta); + } + + function _assertApproxEqRel(int256 a, int256 b, uint256 maxPercentDelta, string memory err, bool expectFail) + external + expectFailure(expectFail) + { + assertApproxEqRel(a, b, maxPercentDelta, err); + } + + function _assertApproxEqRelDecimal(int256 a, int256 b, uint256 maxPercentDelta, uint256 decimals, bool expectFail) + external + expectFailure(expectFail) + { + assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals); + } + + function _assertApproxEqRelDecimal( + int256 a, + int256 b, + uint256 maxPercentDelta, + uint256 decimals, + string memory err, + bool expectFail + ) external expectFailure(expectFail) { + assertApproxEqRelDecimal(a, b, maxPercentDelta, decimals, err); + } + + function _assertEqCall( + address targetA, + bytes memory callDataA, + address targetB, + bytes memory callDataB, + bool strictRevertData, + bool expectFail + ) external expectFailure(expectFail) { + assertEqCall(targetA, callDataA, targetB, callDataB, strictRevertData); + } +} + +contract TestMockCall { + bytes returnData; + bool shouldRevert; + + constructor(bytes memory returnData_, bool shouldRevert_) { + returnData = returnData_; + shouldRevert = shouldRevert_; + } + + fallback() external payable { + bytes memory returnData_ = returnData; + + if (shouldRevert) { + assembly { + revert(add(returnData_, 0x20), mload(returnData_)) + } + } else { + assembly { + return(add(returnData_, 0x20), mload(returnData_)) + } + } + } +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/StdChains.t.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/StdChains.t.sol new file mode 100644 index 0000000000..7480e48dd9 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/StdChains.t.sol @@ -0,0 +1,215 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import "../src/Test.sol"; + +contract StdChainsMock is Test { + function exposed_getChain(string memory chainAlias) public returns (Chain memory) { + return getChain(chainAlias); + } + + function exposed_getChain(uint256 chainId) public returns (Chain memory) { + return getChain(chainId); + } + + function exposed_setChain(string memory chainAlias, ChainData memory chainData) public { + setChain(chainAlias, chainData); + } + + function exposed_setFallbackToDefaultRpcUrls(bool useDefault) public { + setFallbackToDefaultRpcUrls(useDefault); + } +} + +contract StdChainsTest is Test { + function testChainRpcInitialization() public { + // RPCs specified in `foundry.toml` should be updated. + assertEq(getChain(1).rpcUrl, "https://mainnet.infura.io/v3/b1d3925804e74152b316ca7da97060d3"); + assertEq(getChain("optimism_goerli").rpcUrl, "https://goerli.optimism.io/"); + assertEq(getChain("arbitrum_one_goerli").rpcUrl, "https://goerli-rollup.arbitrum.io/rpc/"); + + // Environment variables should be the next fallback + assertEq(getChain("arbitrum_nova").rpcUrl, "https://nova.arbitrum.io/rpc"); + vm.setEnv("ARBITRUM_NOVA_RPC_URL", "myoverride"); + assertEq(getChain("arbitrum_nova").rpcUrl, "myoverride"); + vm.setEnv("ARBITRUM_NOVA_RPC_URL", "https://nova.arbitrum.io/rpc"); + + // Cannot override RPCs defined in `foundry.toml` + vm.setEnv("MAINNET_RPC_URL", "myoverride2"); + assertEq(getChain("mainnet").rpcUrl, "https://mainnet.infura.io/v3/b1d3925804e74152b316ca7da97060d3"); + + // Other RPCs should remain unchanged. + assertEq(getChain(31337).rpcUrl, "http://127.0.0.1:8545"); + assertEq(getChain("sepolia").rpcUrl, "https://sepolia.infura.io/v3/b9794ad1ddf84dfb8c34d6bb5dca2001"); + } + + function testRpc(string memory rpcAlias) internal { + string memory rpcUrl = getChain(rpcAlias).rpcUrl; + vm.createSelectFork(rpcUrl); + } + + // Ensure we can connect to the default RPC URL for each chain. + // function testRpcs() public { + // testRpc("mainnet"); + // testRpc("goerli"); + // testRpc("sepolia"); + // testRpc("optimism"); + // testRpc("optimism_goerli"); + // testRpc("arbitrum_one"); + // testRpc("arbitrum_one_goerli"); + // testRpc("arbitrum_nova"); + // testRpc("polygon"); + // testRpc("polygon_mumbai"); + // testRpc("avalanche"); + // testRpc("avalanche_fuji"); + // testRpc("bnb_smart_chain"); + // testRpc("bnb_smart_chain_testnet"); + // testRpc("gnosis_chain"); + // } + + function testChainNoDefault() public { + // We deploy a mock to properly test the revert. + StdChainsMock stdChainsMock = new StdChainsMock(); + + vm.expectRevert("StdChains getChain(string): Chain with alias \"does_not_exist\" not found."); + stdChainsMock.exposed_getChain("does_not_exist"); + } + + function testSetChainFirstFails() public { + // We deploy a mock to properly test the revert. + StdChainsMock stdChainsMock = new StdChainsMock(); + + vm.expectRevert("StdChains setChain(string,ChainData): Chain ID 31337 already used by \"anvil\"."); + stdChainsMock.exposed_setChain("anvil2", ChainData("Anvil", 31337, "URL")); + } + + function testChainBubbleUp() public { + // We deploy a mock to properly test the revert. + StdChainsMock stdChainsMock = new StdChainsMock(); + + stdChainsMock.exposed_setChain("needs_undefined_env_var", ChainData("", 123456789, "")); + vm.expectRevert( + "Failed to resolve env var `UNDEFINED_RPC_URL_PLACEHOLDER` in `${UNDEFINED_RPC_URL_PLACEHOLDER}`: environment variable not found" + ); + stdChainsMock.exposed_getChain("needs_undefined_env_var"); + } + + function testCannotSetChain_ChainIdExists() public { + // We deploy a mock to properly test the revert. + StdChainsMock stdChainsMock = new StdChainsMock(); + + stdChainsMock.exposed_setChain("custom_chain", ChainData("Custom Chain", 123456789, "https://custom.chain/")); + + vm.expectRevert('StdChains setChain(string,ChainData): Chain ID 123456789 already used by "custom_chain".'); + + stdChainsMock.exposed_setChain("another_custom_chain", ChainData("", 123456789, "")); + } + + function testSetChain() public { + setChain("custom_chain", ChainData("Custom Chain", 123456789, "https://custom.chain/")); + Chain memory customChain = getChain("custom_chain"); + assertEq(customChain.name, "Custom Chain"); + assertEq(customChain.chainId, 123456789); + assertEq(customChain.chainAlias, "custom_chain"); + assertEq(customChain.rpcUrl, "https://custom.chain/"); + Chain memory chainById = getChain(123456789); + assertEq(chainById.name, customChain.name); + assertEq(chainById.chainId, customChain.chainId); + assertEq(chainById.chainAlias, customChain.chainAlias); + assertEq(chainById.rpcUrl, customChain.rpcUrl); + customChain.name = "Another Custom Chain"; + customChain.chainId = 987654321; + setChain("another_custom_chain", customChain); + Chain memory anotherCustomChain = getChain("another_custom_chain"); + assertEq(anotherCustomChain.name, "Another Custom Chain"); + assertEq(anotherCustomChain.chainId, 987654321); + assertEq(anotherCustomChain.chainAlias, "another_custom_chain"); + assertEq(anotherCustomChain.rpcUrl, "https://custom.chain/"); + // Verify the first chain data was not overwritten + chainById = getChain(123456789); + assertEq(chainById.name, "Custom Chain"); + assertEq(chainById.chainId, 123456789); + } + + function testSetNoEmptyAlias() public { + // We deploy a mock to properly test the revert. + StdChainsMock stdChainsMock = new StdChainsMock(); + + vm.expectRevert("StdChains setChain(string,ChainData): Chain alias cannot be the empty string."); + stdChainsMock.exposed_setChain("", ChainData("", 123456789, "")); + } + + function testSetNoChainId0() public { + // We deploy a mock to properly test the revert. + StdChainsMock stdChainsMock = new StdChainsMock(); + + vm.expectRevert("StdChains setChain(string,ChainData): Chain ID cannot be 0."); + stdChainsMock.exposed_setChain("alias", ChainData("", 0, "")); + } + + function testGetNoChainId0() public { + // We deploy a mock to properly test the revert. + StdChainsMock stdChainsMock = new StdChainsMock(); + + vm.expectRevert("StdChains getChain(uint256): Chain ID cannot be 0."); + stdChainsMock.exposed_getChain(0); + } + + function testGetNoEmptyAlias() public { + // We deploy a mock to properly test the revert. + StdChainsMock stdChainsMock = new StdChainsMock(); + + vm.expectRevert("StdChains getChain(string): Chain alias cannot be the empty string."); + stdChainsMock.exposed_getChain(""); + } + + function testChainIdNotFound() public { + // We deploy a mock to properly test the revert. + StdChainsMock stdChainsMock = new StdChainsMock(); + + vm.expectRevert("StdChains getChain(string): Chain with alias \"no_such_alias\" not found."); + stdChainsMock.exposed_getChain("no_such_alias"); + } + + function testChainAliasNotFound() public { + // We deploy a mock to properly test the revert. + StdChainsMock stdChainsMock = new StdChainsMock(); + + vm.expectRevert("StdChains getChain(uint256): Chain with ID 321 not found."); + + stdChainsMock.exposed_getChain(321); + } + + function testSetChain_ExistingOne() public { + // We deploy a mock to properly test the revert. + StdChainsMock stdChainsMock = new StdChainsMock(); + + setChain("custom_chain", ChainData("Custom Chain", 123456789, "https://custom.chain/")); + assertEq(getChain(123456789).chainId, 123456789); + + setChain("custom_chain", ChainData("Modified Chain", 999999999, "https://modified.chain/")); + vm.expectRevert("StdChains getChain(uint256): Chain with ID 123456789 not found."); + stdChainsMock.exposed_getChain(123456789); + + Chain memory modifiedChain = getChain(999999999); + assertEq(modifiedChain.name, "Modified Chain"); + assertEq(modifiedChain.chainId, 999999999); + assertEq(modifiedChain.rpcUrl, "https://modified.chain/"); + } + + function testDontUseDefaultRpcUrl() public { + // We deploy a mock to properly test the revert. + StdChainsMock stdChainsMock = new StdChainsMock(); + + // Should error if default RPCs flag is set to false. + stdChainsMock.exposed_setFallbackToDefaultRpcUrls(false); + vm.expectRevert( + "Failed to get environment variable `ANVIL_RPC_URL` as type `string`: environment variable not found" + ); + stdChainsMock.exposed_getChain(31337); + vm.expectRevert( + "Failed to get environment variable `SEPOLIA_RPC_URL` as type `string`: environment variable not found" + ); + stdChainsMock.exposed_getChain("sepolia"); + } +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/StdCheats.t.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/StdCheats.t.sol new file mode 100644 index 0000000000..bdc7870d68 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/StdCheats.t.sol @@ -0,0 +1,610 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import "../src/StdCheats.sol"; +import "../src/Test.sol"; +import "../src/StdJson.sol"; + +contract StdCheatsTest is Test { + Bar test; + + using stdJson for string; + + function setUp() public { + test = new Bar(); + } + + function testSkip() public { + vm.warp(100); + skip(25); + assertEq(block.timestamp, 125); + } + + function testRewind() public { + vm.warp(100); + rewind(25); + assertEq(block.timestamp, 75); + } + + function testHoax() public { + hoax(address(1337)); + test.bar{value: 100}(address(1337)); + } + + function testHoaxOrigin() public { + hoax(address(1337), address(1337)); + test.origin{value: 100}(address(1337)); + } + + function testHoaxDifferentAddresses() public { + hoax(address(1337), address(7331)); + test.origin{value: 100}(address(1337), address(7331)); + } + + function testStartHoax() public { + startHoax(address(1337)); + test.bar{value: 100}(address(1337)); + test.bar{value: 100}(address(1337)); + vm.stopPrank(); + test.bar(address(this)); + } + + function testStartHoaxOrigin() public { + startHoax(address(1337), address(1337)); + test.origin{value: 100}(address(1337)); + test.origin{value: 100}(address(1337)); + vm.stopPrank(); + test.bar(address(this)); + } + + function testChangePrankMsgSender() public { + vm.startPrank(address(1337)); + test.bar(address(1337)); + changePrank(address(0xdead)); + test.bar(address(0xdead)); + changePrank(address(1337)); + test.bar(address(1337)); + vm.stopPrank(); + } + + function testChangePrankMsgSenderAndTxOrigin() public { + vm.startPrank(address(1337), address(1338)); + test.origin(address(1337), address(1338)); + changePrank(address(0xdead), address(0xbeef)); + test.origin(address(0xdead), address(0xbeef)); + changePrank(address(1337), address(1338)); + test.origin(address(1337), address(1338)); + vm.stopPrank(); + } + + function testMakeAccountEquivalence() public { + Account memory account = makeAccount("1337"); + (address addr, uint256 key) = makeAddrAndKey("1337"); + assertEq(account.addr, addr); + assertEq(account.key, key); + } + + function testMakeAddrEquivalence() public { + (address addr,) = makeAddrAndKey("1337"); + assertEq(makeAddr("1337"), addr); + } + + function testMakeAddrSigning() public { + (address addr, uint256 key) = makeAddrAndKey("1337"); + bytes32 hash = keccak256("some_message"); + + (uint8 v, bytes32 r, bytes32 s) = vm.sign(key, hash); + assertEq(ecrecover(hash, v, r, s), addr); + } + + function testDeal() public { + deal(address(this), 1 ether); + assertEq(address(this).balance, 1 ether); + } + + function testDealToken() public { + Bar barToken = new Bar(); + address bar = address(barToken); + deal(bar, address(this), 10000e18); + assertEq(barToken.balanceOf(address(this)), 10000e18); + } + + function testDealTokenAdjustTotalSupply() public { + Bar barToken = new Bar(); + address bar = address(barToken); + deal(bar, address(this), 10000e18, true); + assertEq(barToken.balanceOf(address(this)), 10000e18); + assertEq(barToken.totalSupply(), 20000e18); + deal(bar, address(this), 0, true); + assertEq(barToken.balanceOf(address(this)), 0); + assertEq(barToken.totalSupply(), 10000e18); + } + + function testDealERC1155Token() public { + BarERC1155 barToken = new BarERC1155(); + address bar = address(barToken); + dealERC1155(bar, address(this), 0, 10000e18, false); + assertEq(barToken.balanceOf(address(this), 0), 10000e18); + } + + function testDealERC1155TokenAdjustTotalSupply() public { + BarERC1155 barToken = new BarERC1155(); + address bar = address(barToken); + dealERC1155(bar, address(this), 0, 10000e18, true); + assertEq(barToken.balanceOf(address(this), 0), 10000e18); + assertEq(barToken.totalSupply(0), 20000e18); + dealERC1155(bar, address(this), 0, 0, true); + assertEq(barToken.balanceOf(address(this), 0), 0); + assertEq(barToken.totalSupply(0), 10000e18); + } + + function testDealERC721Token() public { + BarERC721 barToken = new BarERC721(); + address bar = address(barToken); + dealERC721(bar, address(2), 1); + assertEq(barToken.balanceOf(address(2)), 1); + assertEq(barToken.balanceOf(address(1)), 0); + dealERC721(bar, address(1), 2); + assertEq(barToken.balanceOf(address(1)), 1); + assertEq(barToken.balanceOf(bar), 1); + } + + function testDeployCode() public { + address deployed = deployCode("StdCheats.t.sol:Bar", bytes("")); + assertEq(string(getCode(deployed)), string(getCode(address(test)))); + } + + function testDestroyAccount() public { + // deploy something to destroy it + BarERC721 barToken = new BarERC721(); + address bar = address(barToken); + vm.setNonce(bar, 10); + deal(bar, 100); + + uint256 prevThisBalance = address(this).balance; + uint256 size; + assembly { + size := extcodesize(bar) + } + + assertGt(size, 0); + assertEq(bar.balance, 100); + assertEq(vm.getNonce(bar), 10); + + destroyAccount(bar, address(this)); + assembly { + size := extcodesize(bar) + } + assertEq(address(this).balance, prevThisBalance + 100); + assertEq(vm.getNonce(bar), 0); + assertEq(size, 0); + assertEq(bar.balance, 0); + } + + function testDeployCodeNoArgs() public { + address deployed = deployCode("StdCheats.t.sol:Bar"); + assertEq(string(getCode(deployed)), string(getCode(address(test)))); + } + + function testDeployCodeVal() public { + address deployed = deployCode("StdCheats.t.sol:Bar", bytes(""), 1 ether); + assertEq(string(getCode(deployed)), string(getCode(address(test)))); + assertEq(deployed.balance, 1 ether); + } + + function testDeployCodeValNoArgs() public { + address deployed = deployCode("StdCheats.t.sol:Bar", 1 ether); + assertEq(string(getCode(deployed)), string(getCode(address(test)))); + assertEq(deployed.balance, 1 ether); + } + + // We need this so we can call "this.deployCode" rather than "deployCode" directly + function deployCodeHelper(string memory what) external { + deployCode(what); + } + + function testDeployCodeFail() public { + vm.expectRevert(bytes("StdCheats deployCode(string): Deployment failed.")); + this.deployCodeHelper("StdCheats.t.sol:RevertingContract"); + } + + function getCode(address who) internal view returns (bytes memory o_code) { + /// @solidity memory-safe-assembly + assembly { + // retrieve the size of the code, this needs assembly + let size := extcodesize(who) + // allocate output byte array - this could also be done without assembly + // by using o_code = new bytes(size) + o_code := mload(0x40) + // new "memory end" including padding + mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), not(0x1f)))) + // store length in memory + mstore(o_code, size) + // actually retrieve the code, this needs assembly + extcodecopy(who, add(o_code, 0x20), 0, size) + } + } + + function testDeriveRememberKey() public { + string memory mnemonic = "test test test test test test test test test test test junk"; + + (address deployer, uint256 privateKey) = deriveRememberKey(mnemonic, 0); + assertEq(deployer, 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266); + assertEq(privateKey, 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80); + } + + function testBytesToUint() public { + assertEq(3, bytesToUint_test(hex"03")); + assertEq(2, bytesToUint_test(hex"02")); + assertEq(255, bytesToUint_test(hex"ff")); + assertEq(29625, bytesToUint_test(hex"73b9")); + } + + function testParseJsonTxDetail() public { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); + string memory json = vm.readFile(path); + bytes memory transactionDetails = json.parseRaw(".transactions[0].tx"); + RawTx1559Detail memory rawTxDetail = abi.decode(transactionDetails, (RawTx1559Detail)); + Tx1559Detail memory txDetail = rawToConvertedEIP1559Detail(rawTxDetail); + assertEq(txDetail.from, 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266); + assertEq(txDetail.to, 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512); + assertEq( + txDetail.data, + hex"23e99187000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000013370000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004" + ); + assertEq(txDetail.nonce, 3); + assertEq(txDetail.txType, 2); + assertEq(txDetail.gas, 29625); + assertEq(txDetail.value, 0); + } + + function testReadEIP1559Transaction() public view { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); + uint256 index = 0; + Tx1559 memory transaction = readTx1559(path, index); + transaction; + } + + function testReadEIP1559Transactions() public view { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); + Tx1559[] memory transactions = readTx1559s(path); + transactions; + } + + function testReadReceipt() public { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); + uint256 index = 5; + Receipt memory receipt = readReceipt(path, index); + assertEq( + receipt.logsBloom, + hex"00000000000800000000000000000010000000000000000000000000000180000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100" + ); + } + + function testReadReceipts() public view { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); + Receipt[] memory receipts = readReceipts(path); + receipts; + } + + function testGasMeteringModifier() public { + uint256 gas_start_normal = gasleft(); + addInLoop(); + uint256 gas_used_normal = gas_start_normal - gasleft(); + + uint256 gas_start_single = gasleft(); + addInLoopNoGas(); + uint256 gas_used_single = gas_start_single - gasleft(); + + uint256 gas_start_double = gasleft(); + addInLoopNoGasNoGas(); + uint256 gas_used_double = gas_start_double - gasleft(); + + emit log_named_uint("Normal gas", gas_used_normal); + emit log_named_uint("Single modifier gas", gas_used_single); + emit log_named_uint("Double modifier gas", gas_used_double); + assertTrue(gas_used_double + gas_used_single < gas_used_normal); + } + + function addInLoop() internal pure returns (uint256) { + uint256 b; + for (uint256 i; i < 10000; i++) { + b += i; + } + return b; + } + + function addInLoopNoGas() internal noGasMetering returns (uint256) { + return addInLoop(); + } + + function addInLoopNoGasNoGas() internal noGasMetering returns (uint256) { + return addInLoopNoGas(); + } + + function bytesToUint_test(bytes memory b) private pure returns (uint256) { + uint256 number; + for (uint256 i = 0; i < b.length; i++) { + number = number + uint256(uint8(b[i])) * (2 ** (8 * (b.length - (i + 1)))); + } + return number; + } + + function testAssumeAddressIsNot(address addr) external { + // skip over Payable and NonPayable enums + for (uint8 i = 2; i < uint8(type(AddressType).max); i++) { + assumeAddressIsNot(addr, AddressType(i)); + } + assertTrue(addr != address(0)); + assertTrue(addr < address(1) || addr > address(9)); + assertTrue(addr != address(vm) || addr != 0x000000000000000000636F6e736F6c652e6c6f67); + } + + function testAssumePayable() external { + // We deploy a mock version so we can properly test the revert. + StdCheatsMock stdCheatsMock = new StdCheatsMock(); + + // all should revert since these addresses are not payable + + // VM address + vm.expectRevert(); + stdCheatsMock.exposed_assumePayable(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); + + // Console address + vm.expectRevert(); + stdCheatsMock.exposed_assumePayable(0x000000000000000000636F6e736F6c652e6c6f67); + + // Create2Deployer + vm.expectRevert(); + stdCheatsMock.exposed_assumePayable(0x4e59b44847b379578588920cA78FbF26c0B4956C); + + // all should pass since these addresses are payable + + // vitalik.eth + stdCheatsMock.exposed_assumePayable(0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045); + + // mock payable contract + MockContractPayable cp = new MockContractPayable(); + stdCheatsMock.exposed_assumePayable(address(cp)); + } + + function testAssumeNotPayable() external { + // We deploy a mock version so we can properly test the revert. + StdCheatsMock stdCheatsMock = new StdCheatsMock(); + + // all should pass since these addresses are not payable + + // VM address + stdCheatsMock.exposed_assumeNotPayable(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); + + // Console address + stdCheatsMock.exposed_assumeNotPayable(0x000000000000000000636F6e736F6c652e6c6f67); + + // Create2Deployer + stdCheatsMock.exposed_assumeNotPayable(0x4e59b44847b379578588920cA78FbF26c0B4956C); + + // all should revert since these addresses are payable + + // vitalik.eth + vm.expectRevert(); + stdCheatsMock.exposed_assumeNotPayable(0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045); + + // mock payable contract + MockContractPayable cp = new MockContractPayable(); + vm.expectRevert(); + stdCheatsMock.exposed_assumeNotPayable(address(cp)); + } + + function testAssumeNotPrecompile(address addr) external { + assumeNotPrecompile(addr, getChain("optimism_goerli").chainId); + assertTrue( + addr < address(1) || (addr > address(9) && addr < address(0x4200000000000000000000000000000000000000)) + || addr > address(0x4200000000000000000000000000000000000800) + ); + } + + function testAssumeNotForgeAddress(address addr) external { + assumeNotForgeAddress(addr); + assertTrue( + addr != address(vm) && addr != 0x000000000000000000636F6e736F6c652e6c6f67 + && addr != 0x4e59b44847b379578588920cA78FbF26c0B4956C + ); + } + + function testCannotDeployCodeTo() external { + vm.expectRevert("StdCheats deployCodeTo(string,bytes,uint256,address): Failed to create runtime bytecode."); + this._revertDeployCodeTo(); + } + + function _revertDeployCodeTo() external { + deployCodeTo("StdCheats.t.sol:RevertingContract", address(0)); + } + + function testDeployCodeTo() external { + address arbitraryAddress = makeAddr("arbitraryAddress"); + + deployCodeTo( + "StdCheats.t.sol:MockContractWithConstructorArgs", + abi.encode(uint256(6), true, bytes20(arbitraryAddress)), + 1 ether, + arbitraryAddress + ); + + MockContractWithConstructorArgs ct = MockContractWithConstructorArgs(arbitraryAddress); + + assertEq(arbitraryAddress.balance, 1 ether); + assertEq(ct.x(), 6); + assertTrue(ct.y()); + assertEq(ct.z(), bytes20(arbitraryAddress)); + } +} + +contract StdCheatsMock is StdCheats { + function exposed_assumePayable(address addr) external { + assumePayable(addr); + } + + function exposed_assumeNotPayable(address addr) external { + assumeNotPayable(addr); + } + + // We deploy a mock version so we can properly test expected reverts. + function exposed_assumeNotBlacklisted(address token, address addr) external view { + return assumeNotBlacklisted(token, addr); + } +} + +contract StdCheatsForkTest is Test { + address internal constant SHIB = 0x95aD61b0a150d79219dCF64E1E6Cc01f0B64C4cE; + address internal constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; + address internal constant USDC_BLACKLISTED_USER = 0x1E34A77868E19A6647b1f2F47B51ed72dEDE95DD; + address internal constant USDT = 0xdAC17F958D2ee523a2206206994597C13D831ec7; + address internal constant USDT_BLACKLISTED_USER = 0x8f8a8F4B54a2aAC7799d7bc81368aC27b852822A; + + function setUp() public { + // All tests of the `assumeNotBlacklisted` method are fork tests using live contracts. + vm.createSelectFork({urlOrAlias: "mainnet", blockNumber: 16_428_900}); + } + + function testCannotAssumeNoBlacklisted_EOA() external { + // We deploy a mock version so we can properly test the revert. + StdCheatsMock stdCheatsMock = new StdCheatsMock(); + address eoa = vm.addr({privateKey: 1}); + vm.expectRevert("StdCheats assumeNotBlacklisted(address,address): Token address is not a contract."); + stdCheatsMock.exposed_assumeNotBlacklisted(eoa, address(0)); + } + + function testAssumeNotBlacklisted_TokenWithoutBlacklist(address addr) external { + assumeNotBlacklisted(SHIB, addr); + assertTrue(true); + } + + function testAssumeNoBlacklisted_USDC() external { + // We deploy a mock version so we can properly test the revert. + StdCheatsMock stdCheatsMock = new StdCheatsMock(); + vm.expectRevert(); + stdCheatsMock.exposed_assumeNotBlacklisted(USDC, USDC_BLACKLISTED_USER); + } + + function testAssumeNotBlacklisted_USDC(address addr) external { + assumeNotBlacklisted(USDC, addr); + assertFalse(USDCLike(USDC).isBlacklisted(addr)); + } + + function testAssumeNoBlacklisted_USDT() external { + // We deploy a mock version so we can properly test the revert. + StdCheatsMock stdCheatsMock = new StdCheatsMock(); + vm.expectRevert(); + stdCheatsMock.exposed_assumeNotBlacklisted(USDT, USDT_BLACKLISTED_USER); + } + + function testAssumeNotBlacklisted_USDT(address addr) external { + assumeNotBlacklisted(USDT, addr); + assertFalse(USDTLike(USDT).isBlackListed(addr)); + } +} + +contract Bar { + constructor() payable { + /// `DEAL` STDCHEAT + totalSupply = 10000e18; + balanceOf[address(this)] = totalSupply; + } + + /// `HOAX` and `CHANGEPRANK` STDCHEATS + function bar(address expectedSender) public payable { + require(msg.sender == expectedSender, "!prank"); + } + + function origin(address expectedSender) public payable { + require(msg.sender == expectedSender, "!prank"); + require(tx.origin == expectedSender, "!prank"); + } + + function origin(address expectedSender, address expectedOrigin) public payable { + require(msg.sender == expectedSender, "!prank"); + require(tx.origin == expectedOrigin, "!prank"); + } + + /// `DEAL` STDCHEAT + mapping(address => uint256) public balanceOf; + uint256 public totalSupply; +} + +contract BarERC1155 { + constructor() payable { + /// `DEALERC1155` STDCHEAT + _totalSupply[0] = 10000e18; + _balances[0][address(this)] = _totalSupply[0]; + } + + function balanceOf(address account, uint256 id) public view virtual returns (uint256) { + return _balances[id][account]; + } + + function totalSupply(uint256 id) public view virtual returns (uint256) { + return _totalSupply[id]; + } + + /// `DEALERC1155` STDCHEAT + mapping(uint256 => mapping(address => uint256)) private _balances; + mapping(uint256 => uint256) private _totalSupply; +} + +contract BarERC721 { + constructor() payable { + /// `DEALERC721` STDCHEAT + _owners[1] = address(1); + _balances[address(1)] = 1; + _owners[2] = address(this); + _owners[3] = address(this); + _balances[address(this)] = 2; + } + + function balanceOf(address owner) public view virtual returns (uint256) { + return _balances[owner]; + } + + function ownerOf(uint256 tokenId) public view virtual returns (address) { + address owner = _owners[tokenId]; + return owner; + } + + mapping(uint256 => address) private _owners; + mapping(address => uint256) private _balances; +} + +interface USDCLike { + function isBlacklisted(address) external view returns (bool); +} + +interface USDTLike { + function isBlackListed(address) external view returns (bool); +} + +contract RevertingContract { + constructor() { + revert(); + } +} + +contract MockContractWithConstructorArgs { + uint256 public immutable x; + bool public y; + bytes20 public z; + + constructor(uint256 _x, bool _y, bytes20 _z) payable { + x = _x; + y = _y; + z = _z; + } +} + +contract MockContractPayable { + receive() external payable {} +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/StdError.t.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/StdError.t.sol new file mode 100644 index 0000000000..ccd3eface3 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/StdError.t.sol @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0 <0.9.0; + +import "../src/StdError.sol"; +import "../src/Test.sol"; + +contract StdErrorsTest is Test { + ErrorsTest test; + + function setUp() public { + test = new ErrorsTest(); + } + + function testExpectAssertion() public { + vm.expectRevert(stdError.assertionError); + test.assertionError(); + } + + function testExpectArithmetic() public { + vm.expectRevert(stdError.arithmeticError); + test.arithmeticError(10); + } + + function testExpectDiv() public { + vm.expectRevert(stdError.divisionError); + test.divError(0); + } + + function testExpectMod() public { + vm.expectRevert(stdError.divisionError); + test.modError(0); + } + + function testExpectEnum() public { + vm.expectRevert(stdError.enumConversionError); + test.enumConversion(1); + } + + function testExpectEncodeStg() public { + vm.expectRevert(stdError.encodeStorageError); + test.encodeStgError(); + } + + function testExpectPop() public { + vm.expectRevert(stdError.popError); + test.pop(); + } + + function testExpectOOB() public { + vm.expectRevert(stdError.indexOOBError); + test.indexOOBError(1); + } + + function testExpectMem() public { + vm.expectRevert(stdError.memOverflowError); + test.mem(); + } + + function testExpectIntern() public { + vm.expectRevert(stdError.zeroVarError); + test.intern(); + } +} + +contract ErrorsTest { + enum T {T1} + + uint256[] public someArr; + bytes someBytes; + + function assertionError() public pure { + assert(false); + } + + function arithmeticError(uint256 a) public pure { + a -= 100; + } + + function divError(uint256 a) public pure { + 100 / a; + } + + function modError(uint256 a) public pure { + 100 % a; + } + + function enumConversion(uint256 a) public pure { + T(a); + } + + function encodeStgError() public { + /// @solidity memory-safe-assembly + assembly { + sstore(someBytes.slot, 1) + } + keccak256(someBytes); + } + + function pop() public { + someArr.pop(); + } + + function indexOOBError(uint256 a) public pure { + uint256[] memory t = new uint256[](0); + t[a]; + } + + function mem() public pure { + uint256 l = 2 ** 256 / 32; + new uint256[](l); + } + + function intern() public returns (uint256) { + function(uint256) internal returns (uint256) x; + x(2); + return 7; + } +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/StdMath.t.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/StdMath.t.sol new file mode 100644 index 0000000000..31c8a315a9 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/StdMath.t.sol @@ -0,0 +1,212 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0 <0.9.0; + +import "../src/StdMath.sol"; +import "../src/Test.sol"; + +contract StdMathMock is Test { + function exposed_percentDelta(uint256 a, uint256 b) public pure returns (uint256) { + return stdMath.percentDelta(a, b); + } + + function exposed_percentDelta(int256 a, int256 b) public pure returns (uint256) { + return stdMath.percentDelta(a, b); + } +} + +contract StdMathTest is Test { + function testGetAbs() external { + assertEq(stdMath.abs(-50), 50); + assertEq(stdMath.abs(50), 50); + assertEq(stdMath.abs(-1337), 1337); + assertEq(stdMath.abs(0), 0); + + assertEq(stdMath.abs(type(int256).min), (type(uint256).max >> 1) + 1); + assertEq(stdMath.abs(type(int256).max), (type(uint256).max >> 1)); + } + + function testGetAbs_Fuzz(int256 a) external { + uint256 manualAbs = getAbs(a); + + uint256 abs = stdMath.abs(a); + + assertEq(abs, manualAbs); + } + + function testGetDelta_Uint() external { + assertEq(stdMath.delta(uint256(0), uint256(0)), 0); + assertEq(stdMath.delta(uint256(0), uint256(1337)), 1337); + assertEq(stdMath.delta(uint256(0), type(uint64).max), type(uint64).max); + assertEq(stdMath.delta(uint256(0), type(uint128).max), type(uint128).max); + assertEq(stdMath.delta(uint256(0), type(uint256).max), type(uint256).max); + + assertEq(stdMath.delta(0, uint256(0)), 0); + assertEq(stdMath.delta(1337, uint256(0)), 1337); + assertEq(stdMath.delta(type(uint64).max, uint256(0)), type(uint64).max); + assertEq(stdMath.delta(type(uint128).max, uint256(0)), type(uint128).max); + assertEq(stdMath.delta(type(uint256).max, uint256(0)), type(uint256).max); + + assertEq(stdMath.delta(1337, uint256(1337)), 0); + assertEq(stdMath.delta(type(uint256).max, type(uint256).max), 0); + assertEq(stdMath.delta(5000, uint256(1250)), 3750); + } + + function testGetDelta_Uint_Fuzz(uint256 a, uint256 b) external { + uint256 manualDelta; + if (a > b) { + manualDelta = a - b; + } else { + manualDelta = b - a; + } + + uint256 delta = stdMath.delta(a, b); + + assertEq(delta, manualDelta); + } + + function testGetDelta_Int() external { + assertEq(stdMath.delta(int256(0), int256(0)), 0); + assertEq(stdMath.delta(int256(0), int256(1337)), 1337); + assertEq(stdMath.delta(int256(0), type(int64).max), type(uint64).max >> 1); + assertEq(stdMath.delta(int256(0), type(int128).max), type(uint128).max >> 1); + assertEq(stdMath.delta(int256(0), type(int256).max), type(uint256).max >> 1); + + assertEq(stdMath.delta(0, int256(0)), 0); + assertEq(stdMath.delta(1337, int256(0)), 1337); + assertEq(stdMath.delta(type(int64).max, int256(0)), type(uint64).max >> 1); + assertEq(stdMath.delta(type(int128).max, int256(0)), type(uint128).max >> 1); + assertEq(stdMath.delta(type(int256).max, int256(0)), type(uint256).max >> 1); + + assertEq(stdMath.delta(-0, int256(0)), 0); + assertEq(stdMath.delta(-1337, int256(0)), 1337); + assertEq(stdMath.delta(type(int64).min, int256(0)), (type(uint64).max >> 1) + 1); + assertEq(stdMath.delta(type(int128).min, int256(0)), (type(uint128).max >> 1) + 1); + assertEq(stdMath.delta(type(int256).min, int256(0)), (type(uint256).max >> 1) + 1); + + assertEq(stdMath.delta(int256(0), -0), 0); + assertEq(stdMath.delta(int256(0), -1337), 1337); + assertEq(stdMath.delta(int256(0), type(int64).min), (type(uint64).max >> 1) + 1); + assertEq(stdMath.delta(int256(0), type(int128).min), (type(uint128).max >> 1) + 1); + assertEq(stdMath.delta(int256(0), type(int256).min), (type(uint256).max >> 1) + 1); + + assertEq(stdMath.delta(1337, int256(1337)), 0); + assertEq(stdMath.delta(type(int256).max, type(int256).max), 0); + assertEq(stdMath.delta(type(int256).min, type(int256).min), 0); + assertEq(stdMath.delta(type(int256).min, type(int256).max), type(uint256).max); + assertEq(stdMath.delta(5000, int256(1250)), 3750); + } + + function testGetDelta_Int_Fuzz(int256 a, int256 b) external { + uint256 absA = getAbs(a); + uint256 absB = getAbs(b); + uint256 absDelta = absA > absB ? absA - absB : absB - absA; + + uint256 manualDelta; + if ((a >= 0 && b >= 0) || (a < 0 && b < 0)) { + manualDelta = absDelta; + } + // (a < 0 && b >= 0) || (a >= 0 && b < 0) + else { + manualDelta = absA + absB; + } + + uint256 delta = stdMath.delta(a, b); + + assertEq(delta, manualDelta); + } + + function testGetPercentDelta_Uint() external { + StdMathMock stdMathMock = new StdMathMock(); + + assertEq(stdMath.percentDelta(uint256(0), uint256(1337)), 1e18); + assertEq(stdMath.percentDelta(uint256(0), type(uint64).max), 1e18); + assertEq(stdMath.percentDelta(uint256(0), type(uint128).max), 1e18); + assertEq(stdMath.percentDelta(uint256(0), type(uint192).max), 1e18); + + assertEq(stdMath.percentDelta(1337, uint256(1337)), 0); + assertEq(stdMath.percentDelta(type(uint192).max, type(uint192).max), 0); + assertEq(stdMath.percentDelta(0, uint256(2500)), 1e18); + assertEq(stdMath.percentDelta(2500, uint256(2500)), 0); + assertEq(stdMath.percentDelta(5000, uint256(2500)), 1e18); + assertEq(stdMath.percentDelta(7500, uint256(2500)), 2e18); + + vm.expectRevert(stdError.divisionError); + stdMathMock.exposed_percentDelta(uint256(1), 0); + } + + function testGetPercentDelta_Uint_Fuzz(uint192 a, uint192 b) external { + vm.assume(b != 0); + uint256 manualDelta; + if (a > b) { + manualDelta = a - b; + } else { + manualDelta = b - a; + } + + uint256 manualPercentDelta = manualDelta * 1e18 / b; + uint256 percentDelta = stdMath.percentDelta(a, b); + + assertEq(percentDelta, manualPercentDelta); + } + + function testGetPercentDelta_Int() external { + // We deploy a mock version so we can properly test the revert. + StdMathMock stdMathMock = new StdMathMock(); + + assertEq(stdMath.percentDelta(int256(0), int256(1337)), 1e18); + assertEq(stdMath.percentDelta(int256(0), -1337), 1e18); + assertEq(stdMath.percentDelta(int256(0), type(int64).min), 1e18); + assertEq(stdMath.percentDelta(int256(0), type(int128).min), 1e18); + assertEq(stdMath.percentDelta(int256(0), type(int192).min), 1e18); + assertEq(stdMath.percentDelta(int256(0), type(int64).max), 1e18); + assertEq(stdMath.percentDelta(int256(0), type(int128).max), 1e18); + assertEq(stdMath.percentDelta(int256(0), type(int192).max), 1e18); + + assertEq(stdMath.percentDelta(1337, int256(1337)), 0); + assertEq(stdMath.percentDelta(type(int192).max, type(int192).max), 0); + assertEq(stdMath.percentDelta(type(int192).min, type(int192).min), 0); + + assertEq(stdMath.percentDelta(type(int192).min, type(int192).max), 2e18); // rounds the 1 wei diff down + assertEq(stdMath.percentDelta(type(int192).max, type(int192).min), 2e18 - 1); // rounds the 1 wei diff down + assertEq(stdMath.percentDelta(0, int256(2500)), 1e18); + assertEq(stdMath.percentDelta(2500, int256(2500)), 0); + assertEq(stdMath.percentDelta(5000, int256(2500)), 1e18); + assertEq(stdMath.percentDelta(7500, int256(2500)), 2e18); + + vm.expectRevert(stdError.divisionError); + stdMathMock.exposed_percentDelta(int256(1), 0); + } + + function testGetPercentDelta_Int_Fuzz(int192 a, int192 b) external { + vm.assume(b != 0); + uint256 absA = getAbs(a); + uint256 absB = getAbs(b); + uint256 absDelta = absA > absB ? absA - absB : absB - absA; + + uint256 manualDelta; + if ((a >= 0 && b >= 0) || (a < 0 && b < 0)) { + manualDelta = absDelta; + } + // (a < 0 && b >= 0) || (a >= 0 && b < 0) + else { + manualDelta = absA + absB; + } + + uint256 manualPercentDelta = manualDelta * 1e18 / absB; + uint256 percentDelta = stdMath.percentDelta(a, b); + + assertEq(percentDelta, manualPercentDelta); + } + + /*////////////////////////////////////////////////////////////////////////// + HELPERS + //////////////////////////////////////////////////////////////////////////*/ + + function getAbs(int256 a) private pure returns (uint256) { + if (a < 0) { + return a == type(int256).min ? uint256(type(int256).max) + 1 : uint256(-a); + } + + return uint256(a); + } +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/StdStorage.t.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/StdStorage.t.sol new file mode 100644 index 0000000000..fbf169d9fd --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/StdStorage.t.sol @@ -0,0 +1,293 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import "../src/StdStorage.sol"; +import "../src/Test.sol"; + +contract StdStorageTest is Test { + using stdStorage for StdStorage; + + StorageTest internal test; + + function setUp() public { + test = new StorageTest(); + } + + function testStorageHidden() public { + assertEq(uint256(keccak256("my.random.var")), stdstore.target(address(test)).sig("hidden()").find()); + } + + function testStorageObvious() public { + assertEq(uint256(0), stdstore.target(address(test)).sig("exists()").find()); + } + + function testStorageCheckedWriteHidden() public { + stdstore.target(address(test)).sig(test.hidden.selector).checked_write(100); + assertEq(uint256(test.hidden()), 100); + } + + function testStorageCheckedWriteObvious() public { + stdstore.target(address(test)).sig(test.exists.selector).checked_write(100); + assertEq(test.exists(), 100); + } + + function testStorageCheckedWriteSignedIntegerHidden() public { + stdstore.target(address(test)).sig(test.hidden.selector).checked_write_int(-100); + assertEq(int256(uint256(test.hidden())), -100); + } + + function testStorageCheckedWriteSignedIntegerObvious() public { + stdstore.target(address(test)).sig(test.tG.selector).checked_write_int(-100); + assertEq(test.tG(), -100); + } + + function testStorageMapStructA() public { + uint256 slot = + stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(0).find(); + assertEq(uint256(keccak256(abi.encode(address(this), 4))), slot); + } + + function testStorageMapStructB() public { + uint256 slot = + stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(1).find(); + assertEq(uint256(keccak256(abi.encode(address(this), 4))) + 1, slot); + } + + function testStorageDeepMap() public { + uint256 slot = stdstore.target(address(test)).sig(test.deep_map.selector).with_key(address(this)).with_key( + address(this) + ).find(); + assertEq(uint256(keccak256(abi.encode(address(this), keccak256(abi.encode(address(this), uint256(5)))))), slot); + } + + function testStorageCheckedWriteDeepMap() public { + stdstore.target(address(test)).sig(test.deep_map.selector).with_key(address(this)).with_key(address(this)) + .checked_write(100); + assertEq(100, test.deep_map(address(this), address(this))); + } + + function testStorageDeepMapStructA() public { + uint256 slot = stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)) + .with_key(address(this)).depth(0).find(); + assertEq( + bytes32(uint256(keccak256(abi.encode(address(this), keccak256(abi.encode(address(this), uint256(6)))))) + 0), + bytes32(slot) + ); + } + + function testStorageDeepMapStructB() public { + uint256 slot = stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)) + .with_key(address(this)).depth(1).find(); + assertEq( + bytes32(uint256(keccak256(abi.encode(address(this), keccak256(abi.encode(address(this), uint256(6)))))) + 1), + bytes32(slot) + ); + } + + function testStorageCheckedWriteDeepMapStructA() public { + stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)).with_key( + address(this) + ).depth(0).checked_write(100); + (uint256 a, uint256 b) = test.deep_map_struct(address(this), address(this)); + assertEq(100, a); + assertEq(0, b); + } + + function testStorageCheckedWriteDeepMapStructB() public { + stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)).with_key( + address(this) + ).depth(1).checked_write(100); + (uint256 a, uint256 b) = test.deep_map_struct(address(this), address(this)); + assertEq(0, a); + assertEq(100, b); + } + + function testStorageCheckedWriteMapStructA() public { + stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(0).checked_write(100); + (uint256 a, uint256 b) = test.map_struct(address(this)); + assertEq(a, 100); + assertEq(b, 0); + } + + function testStorageCheckedWriteMapStructB() public { + stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(1).checked_write(100); + (uint256 a, uint256 b) = test.map_struct(address(this)); + assertEq(a, 0); + assertEq(b, 100); + } + + function testStorageStructA() public { + uint256 slot = stdstore.target(address(test)).sig(test.basic.selector).depth(0).find(); + assertEq(uint256(7), slot); + } + + function testStorageStructB() public { + uint256 slot = stdstore.target(address(test)).sig(test.basic.selector).depth(1).find(); + assertEq(uint256(7) + 1, slot); + } + + function testStorageCheckedWriteStructA() public { + stdstore.target(address(test)).sig(test.basic.selector).depth(0).checked_write(100); + (uint256 a, uint256 b) = test.basic(); + assertEq(a, 100); + assertEq(b, 1337); + } + + function testStorageCheckedWriteStructB() public { + stdstore.target(address(test)).sig(test.basic.selector).depth(1).checked_write(100); + (uint256 a, uint256 b) = test.basic(); + assertEq(a, 1337); + assertEq(b, 100); + } + + function testStorageMapAddrFound() public { + uint256 slot = stdstore.target(address(test)).sig(test.map_addr.selector).with_key(address(this)).find(); + assertEq(uint256(keccak256(abi.encode(address(this), uint256(1)))), slot); + } + + function testStorageMapUintFound() public { + uint256 slot = stdstore.target(address(test)).sig(test.map_uint.selector).with_key(100).find(); + assertEq(uint256(keccak256(abi.encode(100, uint256(2)))), slot); + } + + function testStorageCheckedWriteMapUint() public { + stdstore.target(address(test)).sig(test.map_uint.selector).with_key(100).checked_write(100); + assertEq(100, test.map_uint(100)); + } + + function testStorageCheckedWriteMapAddr() public { + stdstore.target(address(test)).sig(test.map_addr.selector).with_key(address(this)).checked_write(100); + assertEq(100, test.map_addr(address(this))); + } + + function testStorageCheckedWriteMapBool() public { + stdstore.target(address(test)).sig(test.map_bool.selector).with_key(address(this)).checked_write(true); + assertTrue(test.map_bool(address(this))); + } + + function testFailStorageCheckedWriteMapPacked() public { + // expect PackedSlot error but not external call so cant expectRevert + stdstore.target(address(test)).sig(test.read_struct_lower.selector).with_key(address(uint160(1337))) + .checked_write(100); + } + + function testStorageCheckedWriteMapPackedSuccess() public { + uint256 full = test.map_packed(address(1337)); + // keep upper 128, set lower 128 to 1337 + full = (full & (uint256((1 << 128) - 1) << 128)) | 1337; + stdstore.target(address(test)).sig(test.map_packed.selector).with_key(address(uint160(1337))).checked_write( + full + ); + assertEq(1337, test.read_struct_lower(address(1337))); + } + + function testFailStorageConst() public { + // vm.expectRevert(abi.encodeWithSignature("NotStorage(bytes4)", bytes4(keccak256("const()")))); + stdstore.target(address(test)).sig("const()").find(); + } + + function testFailStorageNativePack() public { + stdstore.target(address(test)).sig(test.tA.selector).find(); + stdstore.target(address(test)).sig(test.tB.selector).find(); + + // these both would fail + stdstore.target(address(test)).sig(test.tC.selector).find(); + stdstore.target(address(test)).sig(test.tD.selector).find(); + } + + function testStorageReadBytes32() public { + bytes32 val = stdstore.target(address(test)).sig(test.tE.selector).read_bytes32(); + assertEq(val, hex"1337"); + } + + function testStorageReadBool_False() public { + bool val = stdstore.target(address(test)).sig(test.tB.selector).read_bool(); + assertEq(val, false); + } + + function testStorageReadBool_True() public { + bool val = stdstore.target(address(test)).sig(test.tH.selector).read_bool(); + assertEq(val, true); + } + + function testStorageReadBool_Revert() public { + vm.expectRevert("stdStorage read_bool(StdStorage): Cannot decode. Make sure you are reading a bool."); + this.readNonBoolValue(); + } + + function readNonBoolValue() public { + stdstore.target(address(test)).sig(test.tE.selector).read_bool(); + } + + function testStorageReadAddress() public { + address val = stdstore.target(address(test)).sig(test.tF.selector).read_address(); + assertEq(val, address(1337)); + } + + function testStorageReadUint() public { + uint256 val = stdstore.target(address(test)).sig(test.exists.selector).read_uint(); + assertEq(val, 1); + } + + function testStorageReadInt() public { + int256 val = stdstore.target(address(test)).sig(test.tG.selector).read_int(); + assertEq(val, type(int256).min); + } +} + +contract StorageTest { + uint256 public exists = 1; + mapping(address => uint256) public map_addr; + mapping(uint256 => uint256) public map_uint; + mapping(address => uint256) public map_packed; + mapping(address => UnpackedStruct) public map_struct; + mapping(address => mapping(address => uint256)) public deep_map; + mapping(address => mapping(address => UnpackedStruct)) public deep_map_struct; + UnpackedStruct public basic; + + uint248 public tA; + bool public tB; + + bool public tC = false; + uint248 public tD = 1; + + struct UnpackedStruct { + uint256 a; + uint256 b; + } + + mapping(address => bool) public map_bool; + + bytes32 public tE = hex"1337"; + address public tF = address(1337); + int256 public tG = type(int256).min; + bool public tH = true; + + constructor() { + basic = UnpackedStruct({a: 1337, b: 1337}); + + uint256 two = (1 << 128) | 1; + map_packed[msg.sender] = two; + map_packed[address(uint160(1337))] = 1 << 128; + } + + function read_struct_upper(address who) public view returns (uint256) { + return map_packed[who] >> 128; + } + + function read_struct_lower(address who) public view returns (uint256) { + return map_packed[who] & ((1 << 128) - 1); + } + + function hidden() public view returns (bytes32 t) { + bytes32 slot = keccak256("my.random.var"); + /// @solidity memory-safe-assembly + assembly { + t := sload(slot) + } + } + + function const() public pure returns (bytes32 t) { + t = bytes32(hex"1337"); + } +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/StdStyle.t.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/StdStyle.t.sol new file mode 100644 index 0000000000..f6fffe7ac8 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/StdStyle.t.sol @@ -0,0 +1,110 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import "../src/Test.sol"; + +contract StdStyleTest is Test { + function testStyleColor() public pure { + console2.log(StdStyle.red("StdStyle.red String Test")); + console2.log(StdStyle.red(uint256(10e18))); + console2.log(StdStyle.red(int256(-10e18))); + console2.log(StdStyle.red(true)); + console2.log(StdStyle.red(address(0))); + console2.log(StdStyle.redBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.redBytes32("StdStyle.redBytes32")); + console2.log(StdStyle.green("StdStyle.green String Test")); + console2.log(StdStyle.green(uint256(10e18))); + console2.log(StdStyle.green(int256(-10e18))); + console2.log(StdStyle.green(true)); + console2.log(StdStyle.green(address(0))); + console2.log(StdStyle.greenBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.greenBytes32("StdStyle.greenBytes32")); + console2.log(StdStyle.yellow("StdStyle.yellow String Test")); + console2.log(StdStyle.yellow(uint256(10e18))); + console2.log(StdStyle.yellow(int256(-10e18))); + console2.log(StdStyle.yellow(true)); + console2.log(StdStyle.yellow(address(0))); + console2.log(StdStyle.yellowBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.yellowBytes32("StdStyle.yellowBytes32")); + console2.log(StdStyle.blue("StdStyle.blue String Test")); + console2.log(StdStyle.blue(uint256(10e18))); + console2.log(StdStyle.blue(int256(-10e18))); + console2.log(StdStyle.blue(true)); + console2.log(StdStyle.blue(address(0))); + console2.log(StdStyle.blueBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.blueBytes32("StdStyle.blueBytes32")); + console2.log(StdStyle.magenta("StdStyle.magenta String Test")); + console2.log(StdStyle.magenta(uint256(10e18))); + console2.log(StdStyle.magenta(int256(-10e18))); + console2.log(StdStyle.magenta(true)); + console2.log(StdStyle.magenta(address(0))); + console2.log(StdStyle.magentaBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.magentaBytes32("StdStyle.magentaBytes32")); + console2.log(StdStyle.cyan("StdStyle.cyan String Test")); + console2.log(StdStyle.cyan(uint256(10e18))); + console2.log(StdStyle.cyan(int256(-10e18))); + console2.log(StdStyle.cyan(true)); + console2.log(StdStyle.cyan(address(0))); + console2.log(StdStyle.cyanBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.cyanBytes32("StdStyle.cyanBytes32")); + } + + function testStyleFontWeight() public pure { + console2.log(StdStyle.bold("StdStyle.bold String Test")); + console2.log(StdStyle.bold(uint256(10e18))); + console2.log(StdStyle.bold(int256(-10e18))); + console2.log(StdStyle.bold(address(0))); + console2.log(StdStyle.bold(true)); + console2.log(StdStyle.boldBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.boldBytes32("StdStyle.boldBytes32")); + console2.log(StdStyle.dim("StdStyle.dim String Test")); + console2.log(StdStyle.dim(uint256(10e18))); + console2.log(StdStyle.dim(int256(-10e18))); + console2.log(StdStyle.dim(address(0))); + console2.log(StdStyle.dim(true)); + console2.log(StdStyle.dimBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.dimBytes32("StdStyle.dimBytes32")); + console2.log(StdStyle.italic("StdStyle.italic String Test")); + console2.log(StdStyle.italic(uint256(10e18))); + console2.log(StdStyle.italic(int256(-10e18))); + console2.log(StdStyle.italic(address(0))); + console2.log(StdStyle.italic(true)); + console2.log(StdStyle.italicBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.italicBytes32("StdStyle.italicBytes32")); + console2.log(StdStyle.underline("StdStyle.underline String Test")); + console2.log(StdStyle.underline(uint256(10e18))); + console2.log(StdStyle.underline(int256(-10e18))); + console2.log(StdStyle.underline(address(0))); + console2.log(StdStyle.underline(true)); + console2.log(StdStyle.underlineBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.underlineBytes32("StdStyle.underlineBytes32")); + console2.log(StdStyle.inverse("StdStyle.inverse String Test")); + console2.log(StdStyle.inverse(uint256(10e18))); + console2.log(StdStyle.inverse(int256(-10e18))); + console2.log(StdStyle.inverse(address(0))); + console2.log(StdStyle.inverse(true)); + console2.log(StdStyle.inverseBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.inverseBytes32("StdStyle.inverseBytes32")); + } + + function testStyleCombined() public pure { + console2.log(StdStyle.red(StdStyle.bold("Red Bold String Test"))); + console2.log(StdStyle.green(StdStyle.dim(uint256(10e18)))); + console2.log(StdStyle.yellow(StdStyle.italic(int256(-10e18)))); + console2.log(StdStyle.blue(StdStyle.underline(address(0)))); + console2.log(StdStyle.magenta(StdStyle.inverse(true))); + } + + function testStyleCustom() public pure { + console2.log(h1("Custom Style 1")); + console2.log(h2("Custom Style 2")); + } + + function h1(string memory a) private pure returns (string memory) { + return StdStyle.cyan(StdStyle.inverse(StdStyle.bold(a))); + } + + function h2(string memory a) private pure returns (string memory) { + return StdStyle.magenta(StdStyle.bold(StdStyle.underline(a))); + } +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/StdUtils.t.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/StdUtils.t.sol new file mode 100644 index 0000000000..d648512c8d --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/StdUtils.t.sol @@ -0,0 +1,342 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import "../src/Test.sol"; + +contract StdUtilsMock is StdUtils { + // We deploy a mock version so we can properly test expected reverts. + function exposed_getTokenBalances(address token, address[] memory addresses) + external + returns (uint256[] memory balances) + { + return getTokenBalances(token, addresses); + } + + function exposed_bound(int256 num, int256 min, int256 max) external view returns (int256) { + return bound(num, min, max); + } + + function exposed_bound(uint256 num, uint256 min, uint256 max) external view returns (uint256) { + return bound(num, min, max); + } + + function exposed_bytesToUint(bytes memory b) external pure returns (uint256) { + return bytesToUint(b); + } +} + +contract StdUtilsTest is Test { + /*////////////////////////////////////////////////////////////////////////// + BOUND UINT + //////////////////////////////////////////////////////////////////////////*/ + + function testBound() public { + assertEq(bound(uint256(5), 0, 4), 0); + assertEq(bound(uint256(0), 69, 69), 69); + assertEq(bound(uint256(0), 68, 69), 68); + assertEq(bound(uint256(10), 150, 190), 174); + assertEq(bound(uint256(300), 2800, 3200), 3107); + assertEq(bound(uint256(9999), 1337, 6666), 4669); + } + + function testBound_WithinRange() public { + assertEq(bound(uint256(51), 50, 150), 51); + assertEq(bound(uint256(51), 50, 150), bound(bound(uint256(51), 50, 150), 50, 150)); + assertEq(bound(uint256(149), 50, 150), 149); + assertEq(bound(uint256(149), 50, 150), bound(bound(uint256(149), 50, 150), 50, 150)); + } + + function testBound_EdgeCoverage() public { + assertEq(bound(uint256(0), 50, 150), 50); + assertEq(bound(uint256(1), 50, 150), 51); + assertEq(bound(uint256(2), 50, 150), 52); + assertEq(bound(uint256(3), 50, 150), 53); + assertEq(bound(type(uint256).max, 50, 150), 150); + assertEq(bound(type(uint256).max - 1, 50, 150), 149); + assertEq(bound(type(uint256).max - 2, 50, 150), 148); + assertEq(bound(type(uint256).max - 3, 50, 150), 147); + } + + function testBound_DistributionIsEven(uint256 min, uint256 size) public { + size = size % 100 + 1; + min = bound(min, UINT256_MAX / 2, UINT256_MAX / 2 + size); + uint256 max = min + size - 1; + uint256 result; + + for (uint256 i = 1; i <= size * 4; ++i) { + // x > max + result = bound(max + i, min, max); + assertEq(result, min + (i - 1) % size); + // x < min + result = bound(min - i, min, max); + assertEq(result, max - (i - 1) % size); + } + } + + function testBound(uint256 num, uint256 min, uint256 max) public { + if (min > max) (min, max) = (max, min); + + uint256 result = bound(num, min, max); + + assertGe(result, min); + assertLe(result, max); + assertEq(result, bound(result, min, max)); + if (num >= min && num <= max) assertEq(result, num); + } + + function testBoundUint256Max() public { + assertEq(bound(0, type(uint256).max - 1, type(uint256).max), type(uint256).max - 1); + assertEq(bound(1, type(uint256).max - 1, type(uint256).max), type(uint256).max); + } + + function testCannotBoundMaxLessThanMin() public { + // We deploy a mock version so we can properly test the revert. + StdUtilsMock stdUtils = new StdUtilsMock(); + + vm.expectRevert(bytes("StdUtils bound(uint256,uint256,uint256): Max is less than min.")); + stdUtils.exposed_bound(uint256(5), 100, 10); + } + + function testCannotBoundMaxLessThanMin(uint256 num, uint256 min, uint256 max) public { + // We deploy a mock version so we can properly test the revert. + StdUtilsMock stdUtils = new StdUtilsMock(); + + vm.assume(min > max); + vm.expectRevert(bytes("StdUtils bound(uint256,uint256,uint256): Max is less than min.")); + stdUtils.exposed_bound(num, min, max); + } + + /*////////////////////////////////////////////////////////////////////////// + BOUND INT + //////////////////////////////////////////////////////////////////////////*/ + + function testBoundInt() public { + assertEq(bound(-3, 0, 4), 2); + assertEq(bound(0, -69, -69), -69); + assertEq(bound(0, -69, -68), -68); + assertEq(bound(-10, 150, 190), 154); + assertEq(bound(-300, 2800, 3200), 2908); + assertEq(bound(9999, -1337, 6666), 1995); + } + + function testBoundInt_WithinRange() public { + assertEq(bound(51, -50, 150), 51); + assertEq(bound(51, -50, 150), bound(bound(51, -50, 150), -50, 150)); + assertEq(bound(149, -50, 150), 149); + assertEq(bound(149, -50, 150), bound(bound(149, -50, 150), -50, 150)); + } + + function testBoundInt_EdgeCoverage() public { + assertEq(bound(type(int256).min, -50, 150), -50); + assertEq(bound(type(int256).min + 1, -50, 150), -49); + assertEq(bound(type(int256).min + 2, -50, 150), -48); + assertEq(bound(type(int256).min + 3, -50, 150), -47); + assertEq(bound(type(int256).min, 10, 150), 10); + assertEq(bound(type(int256).min + 1, 10, 150), 11); + assertEq(bound(type(int256).min + 2, 10, 150), 12); + assertEq(bound(type(int256).min + 3, 10, 150), 13); + + assertEq(bound(type(int256).max, -50, 150), 150); + assertEq(bound(type(int256).max - 1, -50, 150), 149); + assertEq(bound(type(int256).max - 2, -50, 150), 148); + assertEq(bound(type(int256).max - 3, -50, 150), 147); + assertEq(bound(type(int256).max, -50, -10), -10); + assertEq(bound(type(int256).max - 1, -50, -10), -11); + assertEq(bound(type(int256).max - 2, -50, -10), -12); + assertEq(bound(type(int256).max - 3, -50, -10), -13); + } + + function testBoundInt_DistributionIsEven(int256 min, uint256 size) public { + size = size % 100 + 1; + min = bound(min, -int256(size / 2), int256(size - size / 2)); + int256 max = min + int256(size) - 1; + int256 result; + + for (uint256 i = 1; i <= size * 4; ++i) { + // x > max + result = bound(max + int256(i), min, max); + assertEq(result, min + int256((i - 1) % size)); + // x < min + result = bound(min - int256(i), min, max); + assertEq(result, max - int256((i - 1) % size)); + } + } + + function testBoundInt(int256 num, int256 min, int256 max) public { + if (min > max) (min, max) = (max, min); + + int256 result = bound(num, min, max); + + assertGe(result, min); + assertLe(result, max); + assertEq(result, bound(result, min, max)); + if (num >= min && num <= max) assertEq(result, num); + } + + function testBoundIntInt256Max() public { + assertEq(bound(0, type(int256).max - 1, type(int256).max), type(int256).max - 1); + assertEq(bound(1, type(int256).max - 1, type(int256).max), type(int256).max); + } + + function testBoundIntInt256Min() public { + assertEq(bound(0, type(int256).min, type(int256).min + 1), type(int256).min); + assertEq(bound(1, type(int256).min, type(int256).min + 1), type(int256).min + 1); + } + + function testCannotBoundIntMaxLessThanMin() public { + // We deploy a mock version so we can properly test the revert. + StdUtilsMock stdUtils = new StdUtilsMock(); + + vm.expectRevert(bytes("StdUtils bound(int256,int256,int256): Max is less than min.")); + stdUtils.exposed_bound(-5, 100, 10); + } + + function testCannotBoundIntMaxLessThanMin(int256 num, int256 min, int256 max) public { + // We deploy a mock version so we can properly test the revert. + StdUtilsMock stdUtils = new StdUtilsMock(); + + vm.assume(min > max); + vm.expectRevert(bytes("StdUtils bound(int256,int256,int256): Max is less than min.")); + stdUtils.exposed_bound(num, min, max); + } + + /*////////////////////////////////////////////////////////////////////////// + BOUND PRIVATE KEY + //////////////////////////////////////////////////////////////////////////*/ + + function testBoundPrivateKey() public { + assertEq(boundPrivateKey(0), 1); + assertEq(boundPrivateKey(1), 1); + assertEq(boundPrivateKey(300), 300); + assertEq(boundPrivateKey(9999), 9999); + assertEq(boundPrivateKey(SECP256K1_ORDER - 1), SECP256K1_ORDER - 1); + assertEq(boundPrivateKey(SECP256K1_ORDER), 1); + assertEq(boundPrivateKey(SECP256K1_ORDER + 1), 2); + assertEq(boundPrivateKey(UINT256_MAX), UINT256_MAX & SECP256K1_ORDER - 1); // x&y is equivalent to x-x%y + } + + /*////////////////////////////////////////////////////////////////////////// + BYTES TO UINT + //////////////////////////////////////////////////////////////////////////*/ + + function testBytesToUint() external { + bytes memory maxUint = hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; + bytes memory two = hex"02"; + bytes memory millionEther = hex"d3c21bcecceda1000000"; + + assertEq(bytesToUint(maxUint), type(uint256).max); + assertEq(bytesToUint(two), 2); + assertEq(bytesToUint(millionEther), 1_000_000 ether); + } + + function testCannotConvertGT32Bytes() external { + // We deploy a mock version so we can properly test the revert. + StdUtilsMock stdUtils = new StdUtilsMock(); + + bytes memory thirty3Bytes = hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; + vm.expectRevert("StdUtils bytesToUint(bytes): Bytes length exceeds 32."); + stdUtils.exposed_bytesToUint(thirty3Bytes); + } + + /*////////////////////////////////////////////////////////////////////////// + COMPUTE CREATE ADDRESS + //////////////////////////////////////////////////////////////////////////*/ + + function testComputeCreateAddress() external { + address deployer = 0x6C9FC64A53c1b71FB3f9Af64d1ae3A4931A5f4E9; + uint256 nonce = 14; + address createAddress = computeCreateAddress(deployer, nonce); + assertEq(createAddress, 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45); + } + + /*////////////////////////////////////////////////////////////////////////// + COMPUTE CREATE2 ADDRESS + //////////////////////////////////////////////////////////////////////////*/ + + function testComputeCreate2Address() external { + bytes32 salt = bytes32(uint256(31415)); + bytes32 initcodeHash = keccak256(abi.encode(0x6080)); + address deployer = 0x6C9FC64A53c1b71FB3f9Af64d1ae3A4931A5f4E9; + address create2Address = computeCreate2Address(salt, initcodeHash, deployer); + assertEq(create2Address, 0xB147a5d25748fda14b463EB04B111027C290f4d3); + } + + function testComputeCreate2AddressWithDefaultDeployer() external { + bytes32 salt = 0xc290c670fde54e5ef686f9132cbc8711e76a98f0333a438a92daa442c71403c0; + bytes32 initcodeHash = hashInitCode(hex"6080", ""); + assertEq(initcodeHash, 0x1a578b7a4b0b5755db6d121b4118d4bc68fe170dca840c59bc922f14175a76b0); + address create2Address = computeCreate2Address(salt, initcodeHash); + assertEq(create2Address, 0xc0ffEe2198a06235aAbFffe5Db0CacF1717f5Ac6); + } +} + +contract StdUtilsForkTest is Test { + /*////////////////////////////////////////////////////////////////////////// + GET TOKEN BALANCES + //////////////////////////////////////////////////////////////////////////*/ + + address internal SHIB = 0x95aD61b0a150d79219dCF64E1E6Cc01f0B64C4cE; + address internal SHIB_HOLDER_0 = 0x855F5981e831D83e6A4b4EBFCAdAa68D92333170; + address internal SHIB_HOLDER_1 = 0x8F509A90c2e47779cA408Fe00d7A72e359229AdA; + address internal SHIB_HOLDER_2 = 0x0e3bbc0D04fF62211F71f3e4C45d82ad76224385; + + address internal USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; + address internal USDC_HOLDER_0 = 0xDa9CE944a37d218c3302F6B82a094844C6ECEb17; + address internal USDC_HOLDER_1 = 0x3e67F4721E6d1c41a015f645eFa37BEd854fcf52; + + function setUp() public { + // All tests of the `getTokenBalances` method are fork tests using live contracts. + vm.createSelectFork({urlOrAlias: "mainnet", blockNumber: 16_428_900}); + } + + function testCannotGetTokenBalances_NonTokenContract() external { + // We deploy a mock version so we can properly test the revert. + StdUtilsMock stdUtils = new StdUtilsMock(); + + // The UniswapV2Factory contract has neither a `balanceOf` function nor a fallback function, + // so the `balanceOf` call should revert. + address token = address(0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f); + address[] memory addresses = new address[](1); + addresses[0] = USDC_HOLDER_0; + + vm.expectRevert("Multicall3: call failed"); + stdUtils.exposed_getTokenBalances(token, addresses); + } + + function testCannotGetTokenBalances_EOA() external { + // We deploy a mock version so we can properly test the revert. + StdUtilsMock stdUtils = new StdUtilsMock(); + + address eoa = vm.addr({privateKey: 1}); + address[] memory addresses = new address[](1); + addresses[0] = USDC_HOLDER_0; + vm.expectRevert("StdUtils getTokenBalances(address,address[]): Token address is not a contract."); + stdUtils.exposed_getTokenBalances(eoa, addresses); + } + + function testGetTokenBalances_Empty() external { + address[] memory addresses = new address[](0); + uint256[] memory balances = getTokenBalances(USDC, addresses); + assertEq(balances.length, 0); + } + + function testGetTokenBalances_USDC() external { + address[] memory addresses = new address[](2); + addresses[0] = USDC_HOLDER_0; + addresses[1] = USDC_HOLDER_1; + uint256[] memory balances = getTokenBalances(USDC, addresses); + assertEq(balances[0], 159_000_000_000_000); + assertEq(balances[1], 131_350_000_000_000); + } + + function testGetTokenBalances_SHIB() external { + address[] memory addresses = new address[](3); + addresses[0] = SHIB_HOLDER_0; + addresses[1] = SHIB_HOLDER_1; + addresses[2] = SHIB_HOLDER_2; + uint256[] memory balances = getTokenBalances(SHIB, addresses); + assertEq(balances[0], 3_323_256_285_484.42e18); + assertEq(balances[1], 1_271_702_771_149.99999928e18); + assertEq(balances[2], 606_357_106_247e18); + } +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/compilation/CompilationScript.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/compilation/CompilationScript.sol new file mode 100644 index 0000000000..e205cfff3c --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/compilation/CompilationScript.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +import "../../src/Script.sol"; + +// The purpose of this contract is to benchmark compilation time to avoid accidentally introducing +// a change that results in very long compilation times with via-ir. See https://github.com/foundry-rs/forge-std/issues/207 +contract CompilationScript is Script {} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/compilation/CompilationScriptBase.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/compilation/CompilationScriptBase.sol new file mode 100644 index 0000000000..ce8e0e9545 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/compilation/CompilationScriptBase.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +import "../../src/Script.sol"; + +// The purpose of this contract is to benchmark compilation time to avoid accidentally introducing +// a change that results in very long compilation times with via-ir. See https://github.com/foundry-rs/forge-std/issues/207 +contract CompilationScriptBase is ScriptBase {} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/compilation/CompilationTest.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/compilation/CompilationTest.sol new file mode 100644 index 0000000000..9beeafeb7d --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/compilation/CompilationTest.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +import "../../src/Test.sol"; + +// The purpose of this contract is to benchmark compilation time to avoid accidentally introducing +// a change that results in very long compilation times with via-ir. See https://github.com/foundry-rs/forge-std/issues/207 +contract CompilationTest is Test {} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/compilation/CompilationTestBase.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/compilation/CompilationTestBase.sol new file mode 100644 index 0000000000..e993535bc0 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/compilation/CompilationTestBase.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +import "../../src/Test.sol"; + +// The purpose of this contract is to benchmark compilation time to avoid accidentally introducing +// a change that results in very long compilation times with via-ir. See https://github.com/foundry-rs/forge-std/issues/207 +contract CompilationTestBase is TestBase {} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/fixtures/broadcast.log.json b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/fixtures/broadcast.log.json new file mode 100644 index 0000000000..0a0200bca9 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/forge-std/test/fixtures/broadcast.log.json @@ -0,0 +1,187 @@ +{ + "transactions": [ + { + "hash": "0xc6006863c267735a11476b7f15b15bc718e117e2da114a2be815dd651e1a509f", + "type": "CALL", + "contractName": "Test", + "contractAddress": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", + "function": "multiple_arguments(uint256,address,uint256[]):(uint256)", + "arguments": ["1", "0000000000000000000000000000000000001337", "[3,4]"], + "tx": { + "type": "0x02", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", + "gas": "0x73b9", + "value": "0x0", + "data": "0x23e99187000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000013370000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004", + "nonce": "0x3", + "accessList": [] + } + }, + { + "hash": "0xedf2b38d8d896519a947a1acf720f859bb35c0c5ecb8dd7511995b67b9853298", + "type": "CALL", + "contractName": "Test", + "contractAddress": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", + "function": "inc():(uint256)", + "arguments": [], + "tx": { + "type": "0x02", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", + "gas": "0xdcb2", + "value": "0x0", + "data": "0x371303c0", + "nonce": "0x4", + "accessList": [] + } + }, + { + "hash": "0xa57e8e3981a6c861442e46c9471bd19cb3e21f9a8a6c63a72e7b5c47c6675a7c", + "type": "CALL", + "contractName": "Test", + "contractAddress": "0x7c6b4bbe207d642d98d5c537142d85209e585087", + "function": "t(uint256):(uint256)", + "arguments": ["1"], + "tx": { + "type": "0x02", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": "0x7c6b4bbe207d642d98d5c537142d85209e585087", + "gas": "0x8599", + "value": "0x0", + "data": "0xafe29f710000000000000000000000000000000000000000000000000000000000000001", + "nonce": "0x5", + "accessList": [] + } + } + ], + "receipts": [ + { + "transactionHash": "0x481dc86e40bba90403c76f8e144aa9ff04c1da2164299d0298573835f0991181", + "transactionIndex": "0x0", + "blockHash": "0xef0730448490304e5403be0fa8f8ce64f118e9adcca60c07a2ae1ab921d748af", + "blockNumber": "0x1", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": null, + "cumulativeGasUsed": "0x13f3a", + "gasUsed": "0x13f3a", + "contractAddress": "0x5fbdb2315678afecb367f032d93f642f64180aa3", + "logs": [], + "status": "0x1", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "effectiveGasPrice": "0xee6b2800" + }, + { + "transactionHash": "0x6a187183545b8a9e7f1790e847139379bf5622baff2cb43acf3f5c79470af782", + "transactionIndex": "0x0", + "blockHash": "0xf3acb96a90071640c2a8c067ae4e16aad87e634ea8d8bbbb5b352fba86ba0148", + "blockNumber": "0x2", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": null, + "cumulativeGasUsed": "0x45d80", + "gasUsed": "0x45d80", + "contractAddress": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", + "logs": [], + "status": "0x1", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "effectiveGasPrice": "0xee6b2800" + }, + { + "transactionHash": "0x064ad173b4867bdef2fb60060bbdaf01735fbf10414541ea857772974e74ea9d", + "transactionIndex": "0x0", + "blockHash": "0x8373d02109d3ee06a0225f23da4c161c656ccc48fe0fcee931d325508ae73e58", + "blockNumber": "0x3", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": "0x4e59b44847b379578588920ca78fbf26c0b4956c", + "cumulativeGasUsed": "0x45feb", + "gasUsed": "0x45feb", + "contractAddress": null, + "logs": [], + "status": "0x1", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "effectiveGasPrice": "0xee6b2800" + }, + { + "transactionHash": "0xc6006863c267735a11476b7f15b15bc718e117e2da114a2be815dd651e1a509f", + "transactionIndex": "0x0", + "blockHash": "0x16712fae5c0e18f75045f84363fb6b4d9a9fe25e660c4ce286833a533c97f629", + "blockNumber": "0x4", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", + "cumulativeGasUsed": "0x5905", + "gasUsed": "0x5905", + "contractAddress": null, + "logs": [], + "status": "0x1", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "effectiveGasPrice": "0xee6b2800" + }, + { + "transactionHash": "0xedf2b38d8d896519a947a1acf720f859bb35c0c5ecb8dd7511995b67b9853298", + "transactionIndex": "0x0", + "blockHash": "0x156b88c3eb9a1244ba00a1834f3f70de735b39e3e59006dd03af4fe7d5480c11", + "blockNumber": "0x5", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", + "cumulativeGasUsed": "0xa9c4", + "gasUsed": "0xa9c4", + "contractAddress": null, + "logs": [], + "status": "0x1", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "effectiveGasPrice": "0xee6b2800" + }, + { + "transactionHash": "0xa57e8e3981a6c861442e46c9471bd19cb3e21f9a8a6c63a72e7b5c47c6675a7c", + "transactionIndex": "0x0", + "blockHash": "0xcf61faca67dbb2c28952b0b8a379e53b1505ae0821e84779679390cb8571cadb", + "blockNumber": "0x6", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": "0x7c6b4bbe207d642d98d5c537142d85209e585087", + "cumulativeGasUsed": "0x66c5", + "gasUsed": "0x66c5", + "contractAddress": null, + "logs": [ + { + "address": "0x7c6b4bbe207d642d98d5c537142d85209e585087", + "topics": [ + "0x0b2e13ff20ac7b474198655583edf70dedd2c1dc980e329c4fbb2fc0748b796b" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000046865726500000000000000000000000000000000000000000000000000000000", + "blockHash": "0xcf61faca67dbb2c28952b0b8a379e53b1505ae0821e84779679390cb8571cadb", + "blockNumber": "0x6", + "transactionHash": "0xa57e8e3981a6c861442e46c9471bd19cb3e21f9a8a6c63a72e7b5c47c6675a7c", + "transactionIndex": "0x1", + "logIndex": "0x0", + "transactionLogIndex": "0x0", + "removed": false + } + ], + "status": "0x1", + "logsBloom": "0x00000000000800000000000000000010000000000000000000000000000180000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100", + "effectiveGasPrice": "0xee6b2800" + }, + { + "transactionHash": "0x11fbb10230c168ca1e36a7e5c69a6dbcd04fd9e64ede39d10a83e36ee8065c16", + "transactionIndex": "0x0", + "blockHash": "0xf1e0ed2eda4e923626ec74621006ed50b3fc27580dc7b4cf68a07ca77420e29c", + "blockNumber": "0x7", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": "0x0000000000000000000000000000000000001337", + "cumulativeGasUsed": "0x5208", + "gasUsed": "0x5208", + "contractAddress": null, + "logs": [], + "status": "0x1", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "effectiveGasPrice": "0xee6b2800" + } + ], + "libraries": [ + "src/Broadcast.t.sol:F:0x5fbdb2315678afecb367f032d93f642f64180aa3" + ], + "pending": [], + "path": "broadcast/Broadcast.t.sol/31337/run-latest.json", + "returns": {}, + "timestamp": 1655140035 +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/foundry-huff/scripts/binary_check.sh b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/foundry-huff/scripts/binary_check.sh new file mode 100644 index 0000000000..725a058b50 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/foundry-huff/scripts/binary_check.sh @@ -0,0 +1,11 @@ +#! /bin/bash + +if ! [[ "$(npm list -g huffc)" =~ "empty" ]]; then + # huffc was installed via npm, return 0x00 + echo -n 0x00 +elif [[ "$(yarn global list)" =~ "huffc" ]]; then + # huffc was installed via yarn, return 0x00 + echo -n 0x00 +else + echo -n 0x01 +fi diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/foundry-huff/scripts/file_writer.sh b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/foundry-huff/scripts/file_writer.sh new file mode 100644 index 0000000000..93e3a8d325 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/foundry-huff/scripts/file_writer.sh @@ -0,0 +1,3 @@ +#! /bin/bash + +echo "$2" > $1 diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/foundry-huff/scripts/rand_bytes.sh b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/foundry-huff/scripts/rand_bytes.sh new file mode 100644 index 0000000000..fdd9921067 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/foundry-huff/scripts/rand_bytes.sh @@ -0,0 +1,3 @@ +#! /bin/bash + +echo -n $(hexdump -n 16 -v -e '"0x" 32/1 "%02x" "\n"' /dev/urandom) \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/foundry-huff/scripts/read_and_append.sh b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/foundry-huff/scripts/read_and_append.sh new file mode 100644 index 0000000000..a14336571e --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/foundry-huff/scripts/read_and_append.sh @@ -0,0 +1,3 @@ +#! /bin/bash + +cat $2 >> $1 diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/.gitattributes b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/.gitattributes new file mode 100644 index 0000000000..52031de51c --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/.gitattributes @@ -0,0 +1 @@ +*.sol linguist-language=Solidity diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/.github/workflows/ci.yml b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/.github/workflows/ci.yml new file mode 100644 index 0000000000..2f339b2761 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/.github/workflows/ci.yml @@ -0,0 +1,14 @@ +name: "CI" +on: "push" +jobs: + tests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2.3.4 + - uses: cachix/install-nix-action@v13 + - name: Install dapp + run: nix-env -iA dapp -f $(curl -sS https://api.github.com/repos/dapphub/dapptools/releases/latest | jq -r .tarball_url) + - name: Fetch submodules + run: git submodule update --init + - name: Run tests + run: make test diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/.gitmodules b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/.gitmodules new file mode 100644 index 0000000000..e12471968b --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/.gitmodules @@ -0,0 +1,3 @@ +[submodule "lib/ds-test"] + path = lib/ds-test + url = https://github.com/dapphub/ds-test diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/LICENSE b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/LICENSE new file mode 100644 index 0000000000..769c240957 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2016 Nick Johnson + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/Makefile b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/Makefile new file mode 100644 index 0000000000..31975ee253 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/Makefile @@ -0,0 +1,4 @@ +all :; dapp build +clean :; dapp clean +test :; dapp test +deploy :; dapp create SolidityStringutils diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/README b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/README new file mode 100644 index 0000000000..ad344af7eb --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/README @@ -0,0 +1 @@ +Basic string utilities for Solidity, optimized for low gas usage. diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/README.md b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/README.md new file mode 100644 index 0000000000..458634147f --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/README.md @@ -0,0 +1,357 @@ + +# String & slice utility library for Solidity +## Overview +Functionality in this library is largely implemented using an abstraction called a 'slice'. A slice represents a part of a string - anything from the entire string to a single character, or even no characters at all (a 0-length slice). Since a slice only has to specify an offset and a length, copying and manipulating slices is a lot less expensive than copying and manipulating the strings they reference. + +To further reduce gas costs, most functions on slice that need to return a slice modify the original one instead of allocating a new one; for instance, `s.split(".")` will return the text up to the first '.', modifying s to only contain the remainder of the string after the '.'. In situations where you do not want to modify the original slice, you can make a copy first with `.copy()`, for example: `s.copy().split(".")`. Try and avoid using this idiom in loops; since Solidity has no memory management, it will result in allocating many short-lived slices that are later discarded. + +Functions that return two slices come in two versions: a non-allocating version that takes the second slice as an argument, modifying it in place, and an allocating version that allocates and returns the second slice; see `nextRune` for example. + +Functions that have to copy string data will return strings rather than slices; these can be cast back to slices for further processing if required. + +## Examples +### Basic usage + import "github.com/Arachnid/solidity-stringutils/strings.sol"; + + contract Contract { + using strings for *; + + // ... + } + +### Getting the character length of a string + var len = "Unicode snowman ☃".toSlice().len(); // 17 + +### Splitting a string around a delimiter + var s = "foo bar baz".toSlice(); + var foo = s.split(" ".toSlice()); + +After the above code executes, `s` is now "bar baz", and `foo` is now "foo". + +### Splitting a string into an array + var s = "www.google.com".toSlice(); + var delim = ".".toSlice(); + var parts = new string[](s.count(delim) + 1); + for(uint i = 0; i < parts.length; i++) { + parts[i] = s.split(delim).toString(); + } + +### Extracting the middle part of a string + var s = "www.google.com".toSlice(); + strings.slice memory part; + s.split(".".toSlice(), part); // part and return value is "www" + s.split(".".toSlice(), part); // part and return value is "google" + +This approach uses less memory than the above, by reusing the slice `part` for each section of string extracted. + +### Converting a slice back to a string + var myString = mySlice.toString(); + +### Finding and returning the first occurrence of a substring + var s = "A B C B D".toSlice(); + s.find("B".toSlice()); // "B C B D" + +`find` modifies `s` to contain the part of the string from the first match onwards. + +### Finding and returning the last occurrence of a substring + var s = "A B C B D".toSlice(); + s.rfind("B".toSlice()); // "A B C B" + +`rfind` modifies `s` to contain the part of the string from the last match back to the start. + +### Finding without modifying the original slice. + var s = "A B C B D".toSlice(); + var substring = s.copy().rfind("B".toSlice()); // "A B C B" + +`copy` lets you cheaply duplicate a slice so you don't modify the original. + +### Prefix and suffix matching + var s = "A B C B D".toSlice(); + s.startsWith("A".toSlice()); // True + s.endsWith("D".toSlice()); // True + s.startsWith("B".toSlice()); // False + +### Removing a prefix or suffix + var s = "A B C B D".toSlice(); + s.beyond("A ".toSlice()).until(" D".toSlice()); // "B C B" + +`beyond` modifies `s` to contain the text after its argument; `until` modifies `s` to contain the text up to its argument. If the argument isn't found, `s` is unmodified. + +### Finding and returning the string up to the first match + var s = "A B C B D".toSlice(); + var needle = "B".toSlice(); + var substring = s.until(s.copy().find(needle).beyond(needle)); + +Calling `find` on a copy of `s` returns the part of the string from `needle` onwards; calling `.beyond(needle)` removes `needle` as a prefix, and finally calling `s.until()` removes the entire end of the string, leaving everything up to and including the first match. + +### Concatenating strings + var s = "abc".toSlice().concat("def".toSlice()); // "abcdef" + +## Reference + +### toSlice(string self) internal returns (slice) +Returns a slice containing the entire string. + +Arguments: + + - self The string to make a slice from. + +Returns A newly allocated slice containing the entire string. + +### copy(slice self) internal returns (slice) +Returns a new slice containing the same data as the current slice. + +Arguments: + + - self The slice to copy. + +Returns A new slice containing the same data as `self`. + +### toString(slice self) internal returns (string) + +Copies a slice to a new string. + +Arguments: + + - self The slice to copy. + +Returns A newly allocated string containing the slice's text. + +### len(slice self) internal returns (uint) + +Returns the length in runes of the slice. Note that this operation takes time proportional to the length of the slice; avoid using it in loops, and call `slice.empty()` if you only need to know whether the slice is empty or not. + +Arguments: + + - self The slice to operate on. + +Returns The length of the slice in runes. + +### empty(slice self) internal returns (bool) + +Returns true if the slice is empty (has a length of 0). + +Arguments: + + - self The slice to operate on. + +Returns True if the slice is empty, False otherwise. + +### compare(slice self, slice other) internal returns (int) + +Returns a positive number if `other` comes lexicographically after `self`, a negative number if it comes before, or zero if the contents of the two slices are equal. Comparison is done per-rune, on unicode codepoints. + +Arguments: + + - self The first slice to compare. + - other The second slice to compare. + +Returns The result of the comparison. + +### equals(slice self, slice other) internal returns (bool) + +Returns true if the two slices contain the same text. + +Arguments: + + - self The first slice to compare. + - self The second slice to compare. + +Returns True if the slices are equal, false otherwise. + +### nextRune(slice self, slice rune) internal returns (slice) + +Extracts the first rune in the slice into `rune`, advancing the slice to point to the next rune and returning `self`. + +Arguments: + + - self The slice to operate on. + - rune The slice that will contain the first rune. + +Returns `rune`. + +### nextRune(slice self) internal returns (slice ret) + +Returns the first rune in the slice, advancing the slice to point to the next rune. + +Arguments: + + - self The slice to operate on. + +Returns A slice containing only the first rune from `self`. + +### ord(slice self) internal returns (uint ret) + +Returns the number of the first codepoint in the slice. + +Arguments: + + - self The slice to operate on. + +Returns The number of the first codepoint in the slice. + +### keccak(slice self) internal returns (bytes32 ret) + +Returns the keccak-256 hash of the slice. + +Arguments: + + - self The slice to hash. + +Returns The hash of the slice. + +### startsWith(slice self, slice needle) internal returns (bool) + +Returns true if `self` starts with `needle`. + +Arguments: + + - self The slice to operate on. + - needle The slice to search for. + +Returns True if the slice starts with the provided text, false otherwise. + +### beyond(slice self, slice needle) internal returns (slice) + +If `self` starts with `needle`, `needle` is removed from the beginning of `self`. Otherwise, `self` is unmodified. + +Arguments: + + - self The slice to operate on. + - needle The slice to search for. + +Returns `self` + +### endsWith(slice self, slice needle) internal returns (bool) + +Returns true if the slice ends with `needle`. + +Arguments: + + - self The slice to operate on. + - needle The slice to search for. + +Returns True if the slice starts with the provided text, false otherwise. + +### until(slice self, slice needle) internal returns (slice) + +If `self` ends with `needle`, `needle` is removed from the end of `self`. Otherwise, `self` is unmodified. + +Arguments: + + - self The slice to operate on. + - needle The slice to search for. + +Returns `self` + +### find(slice self, slice needle) internal returns (slice) + +Modifies `self` to contain everything from the first occurrence of `needle` to the end of the slice. `self` is set to the empty slice if `needle` is not found. + +Arguments: + + - self The slice to search and modify. + - needle The text to search for. + +Returns `self`. + +### rfind(slice self, slice needle) internal returns (slice) + +Modifies `self` to contain the part of the string from the start of `self` to the end of the first occurrence of `needle`. If `needle` is not found, `self` is set to the empty slice. + +Arguments: + + - self The slice to search and modify. + - needle The text to search for. + +Returns `self`. + +### split(slice self, slice needle, slice token) internal returns (slice) + +Splits the slice, setting `self` to everything after the first occurrence of `needle`, and `token` to everything before it. If `needle` does not occur in `self`, `self` is set to the empty slice, and `token` is set to the entirety of `self`. + +Arguments: + + - self The slice to split. + - needle The text to search for in `self`. + - token An output parameter to which the first token is written. + +Returns `token`. + +### split(slice self, slice needle) internal returns (slice token) + +Splits the slice, setting `self` to everything after the first occurrence of `needle`, and returning everything before it. If `needle` does not occur in `self`, `self` is set to the empty slice, and the entirety of `self` is returned. + +Arguments: + + - self The slice to split. + - needle The text to search for in `self`. + +Returns The part of `self` up to the first occurrence of `delim`. + +### rsplit(slice self, slice needle, slice token) internal returns (slice) + +Splits the slice, setting `self` to everything before the last occurrence of `needle`, and `token` to everything after it. If `needle` does not occur in `self`, `self` is set to the empty slice, and `token` is set to the entirety of `self`. + +Arguments: + + - self The slice to split. + - needle The text to search for in `self`. + - token An output parameter to which the first token is written. + +Returns `token`. + +### rsplit(slice self, slice needle) internal returns (slice token) + +Splits the slice, setting `self` to everything before the last occurrence of `needle`, and returning everything after it. If `needle` does not occur in `self`, `self` is set to the empty slice, and the entirety of `self` is returned. + +Arguments: + + - self The slice to split. + - needle The text to search for in `self`. + +Returns The part of `self` after the last occurrence of `delim`. + +### count(slice self, slice needle) internal returns (uint count) + +Counts the number of nonoverlapping occurrences of `needle` in `self`. + +Arguments: + + - self The slice to search. + - needle The text to search for in `self`. + +Returns The number of occurrences of `needle` found in `self`. + +### contains(slice self, slice needle) internal returns (bool) + +Returns True if `self` contains `needle`. + +Arguments: + + - self The slice to search. + - needle The text to search for in `self`. + +Returns True if `needle` is found in `self`, false otherwise. + +### concat(slice self, slice other) internal returns (string) + +Returns a newly allocated string containing the concatenation of `self` and `other`. + +Arguments: + + - self The first slice to concatenate. + - other The second slice to concatenate. + +Returns The concatenation of the two strings. + +### join(slice self, slice[] parts) internal returns (string) + +Joins an array of slices, using `self` as a delimiter, returning a newly allocated string. + +Arguments: + + - self The delimiter to use. + - parts A list of slices to join. + +Returns A newly allocated string containing all the slices in `parts`, joined with `self`. diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/dappfile b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/dappfile new file mode 100644 index 0000000000..8772d97710 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/dappfile @@ -0,0 +1,8 @@ +version: 2.0.0 +tags: [] +layout: + sol_sources: . + build_dir: build +dependencies: {} +ignore: [] +name: ethereum-stringutils diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/lib/ds-test/LICENSE b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/lib/ds-test/LICENSE new file mode 100644 index 0000000000..94a9ed024d --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/lib/ds-test/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/lib/ds-test/Makefile b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/lib/ds-test/Makefile new file mode 100644 index 0000000000..661dac4868 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/lib/ds-test/Makefile @@ -0,0 +1,14 @@ +all:; dapp build + +test: + -dapp --use solc:0.4.23 build + -dapp --use solc:0.4.26 build + -dapp --use solc:0.5.17 build + -dapp --use solc:0.6.12 build + -dapp --use solc:0.7.5 build + +demo: + DAPP_SRC=demo dapp --use solc:0.7.5 build + -hevm dapp-test --verbose 3 + +.PHONY: test demo diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/lib/ds-test/default.nix b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/lib/ds-test/default.nix new file mode 100644 index 0000000000..cf65419ab4 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/lib/ds-test/default.nix @@ -0,0 +1,4 @@ +{ solidityPackage, dappsys }: solidityPackage { + name = "ds-test"; + src = ./src; +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/lib/ds-test/demo/demo.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/lib/ds-test/demo/demo.sol new file mode 100644 index 0000000000..d3a7d81fca --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/lib/ds-test/demo/demo.sol @@ -0,0 +1,223 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity >=0.4.23; + +import "../src/test.sol"; + +contract DemoTest is DSTest { + function test_this() public pure { + require(true); + } + function test_logs() public { + emit log("-- log(string)"); + emit log("a string"); + + emit log("-- log_named_uint(string, uint)"); + log_named_uint("uint", 512); + + emit log("-- log_named_int(string, int)"); + log_named_int("int", -512); + + emit log("-- log_named_address(string, address)"); + log_named_address("address", address(this)); + + emit log("-- log_named_bytes32(string, bytes32)"); + log_named_bytes32("bytes32", "a string"); + + emit log("-- log_named_bytes(string, bytes)"); + log_named_bytes("bytes", hex"cafefe"); + + emit log("-- log_named_string(string, string)"); + log_named_string("string", "a string"); + + emit log("-- log_named_decimal_uint(string, uint, uint)"); + log_named_decimal_uint("decimal uint", 1.0e18, 18); + + emit log("-- log_named_decimal_int(string, int, uint)"); + log_named_decimal_int("decimal int", -1.0e18, 18); + } + event log_old_named_uint(bytes32,uint); + function test_old_logs() public { + log_old_named_uint("key", 500); + log_named_bytes32("bkey", "val"); + } + function test_trace() public view { + this.echo("string 1", "string 2"); + } + function test_multiline() public { + emit log("a multiline\\n" "string"); + emit log("a multiline " "string"); + log_bytes("a string"); + log_bytes("a multiline\n" "string"); + log_bytes("a multiline\\n" "string"); + emit log(unicode"Ī"); + logs(hex"0000"); + log_named_bytes("0x0000", hex"0000"); + logs(hex"ff"); + } + function echo(string memory s1, string memory s2) public pure + returns (string memory, string memory) + { + return (s1, s2); + } + + function prove_this(uint x) public { + log_named_uint("sym x", x); + assertGt(x + 1, 0); + } + + function test_logn() public { + assembly { + log0(0x01, 0x02) + log1(0x01, 0x02, 0x03) + log2(0x01, 0x02, 0x03, 0x04) + log3(0x01, 0x02, 0x03, 0x04, 0x05) + } + } + + event MyEvent(uint, uint indexed, uint, uint indexed); + function test_events() public { + emit MyEvent(1, 2, 3, 4); + } + + function test_asserts() public { + string memory err = "this test has failed!"; + emit log("## assertTrue(bool)\n"); + assertTrue(false); + emit log("\n"); + assertTrue(false, err); + + emit log("\n## assertEq(address,address)\n"); + assertEq(address(this), msg.sender); + emit log("\n"); + assertEq(address(this), msg.sender, err); + + emit log("\n## assertEq32(bytes32,bytes32)\n"); + assertEq32("bytes 1", "bytes 2"); + emit log("\n"); + assertEq32("bytes 1", "bytes 2", err); + + emit log("\n## assertEq(bytes32,bytes32)\n"); + assertEq32("bytes 1", "bytes 2"); + emit log("\n"); + assertEq32("bytes 1", "bytes 2", err); + + emit log("\n## assertEq(uint,uint)\n"); + assertEq(uint(0), 1); + emit log("\n"); + assertEq(uint(0), 1, err); + + emit log("\n## assertEq(int,int)\n"); + assertEq(-1, -2); + emit log("\n"); + assertEq(-1, -2, err); + + emit log("\n## assertEqDecimal(int,int,uint)\n"); + assertEqDecimal(-1.0e18, -1.1e18, 18); + emit log("\n"); + assertEqDecimal(-1.0e18, -1.1e18, 18, err); + + emit log("\n## assertEqDecimal(uint,uint,uint)\n"); + assertEqDecimal(uint(1.0e18), 1.1e18, 18); + emit log("\n"); + assertEqDecimal(uint(1.0e18), 1.1e18, 18, err); + + emit log("\n## assertGt(uint,uint)\n"); + assertGt(uint(0), 0); + emit log("\n"); + assertGt(uint(0), 0, err); + + emit log("\n## assertGt(int,int)\n"); + assertGt(-1, -1); + emit log("\n"); + assertGt(-1, -1, err); + + emit log("\n## assertGtDecimal(int,int,uint)\n"); + assertGtDecimal(-2.0e18, -1.1e18, 18); + emit log("\n"); + assertGtDecimal(-2.0e18, -1.1e18, 18, err); + + emit log("\n## assertGtDecimal(uint,uint,uint)\n"); + assertGtDecimal(uint(1.0e18), 1.1e18, 18); + emit log("\n"); + assertGtDecimal(uint(1.0e18), 1.1e18, 18, err); + + emit log("\n## assertGe(uint,uint)\n"); + assertGe(uint(0), 1); + emit log("\n"); + assertGe(uint(0), 1, err); + + emit log("\n## assertGe(int,int)\n"); + assertGe(-1, 0); + emit log("\n"); + assertGe(-1, 0, err); + + emit log("\n## assertGeDecimal(int,int,uint)\n"); + assertGeDecimal(-2.0e18, -1.1e18, 18); + emit log("\n"); + assertGeDecimal(-2.0e18, -1.1e18, 18, err); + + emit log("\n## assertGeDecimal(uint,uint,uint)\n"); + assertGeDecimal(uint(1.0e18), 1.1e18, 18); + emit log("\n"); + assertGeDecimal(uint(1.0e18), 1.1e18, 18, err); + + emit log("\n## assertLt(uint,uint)\n"); + assertLt(uint(0), 0); + emit log("\n"); + assertLt(uint(0), 0, err); + + emit log("\n## assertLt(int,int)\n"); + assertLt(-1, -1); + emit log("\n"); + assertLt(-1, -1, err); + + emit log("\n## assertLtDecimal(int,int,uint)\n"); + assertLtDecimal(-1.0e18, -1.1e18, 18); + emit log("\n"); + assertLtDecimal(-1.0e18, -1.1e18, 18, err); + + emit log("\n## assertLtDecimal(uint,uint,uint)\n"); + assertLtDecimal(uint(2.0e18), 1.1e18, 18); + emit log("\n"); + assertLtDecimal(uint(2.0e18), 1.1e18, 18, err); + + emit log("\n## assertLe(uint,uint)\n"); + assertLe(uint(1), 0); + emit log("\n"); + assertLe(uint(1), 0, err); + + emit log("\n## assertLe(int,int)\n"); + assertLe(0, -1); + emit log("\n"); + assertLe(0, -1, err); + + emit log("\n## assertLeDecimal(int,int,uint)\n"); + assertLeDecimal(-1.0e18, -1.1e18, 18); + emit log("\n"); + assertLeDecimal(-1.0e18, -1.1e18, 18, err); + + emit log("\n## assertLeDecimal(uint,uint,uint)\n"); + assertLeDecimal(uint(2.0e18), 1.1e18, 18); + emit log("\n"); + assertLeDecimal(uint(2.0e18), 1.1e18, 18, err); + + emit log("\n## assertEq(string,string)\n"); + string memory s1 = "string 1"; + string memory s2 = "string 2"; + assertEq(s1, s2); + emit log("\n"); + assertEq(s1, s2, err); + + emit log("\n## assertEq0(bytes,bytes)\n"); + assertEq0(hex"abcdef01", hex"abcdef02"); + log("\n"); + assertEq0(hex"abcdef01", hex"abcdef02", err); + } +} + +contract DemoTestWithSetUp { + function setUp() public { + } + function test_pass() public pure { + } +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/lib/ds-test/src/test.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/lib/ds-test/src/test.sol new file mode 100644 index 0000000000..96d3c15434 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/lib/ds-test/src/test.sol @@ -0,0 +1,434 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +pragma solidity >=0.4.23; + +contract DSTest { + event log (string); + event logs (bytes); + + event log_address (address); + event log_bytes32 (bytes32); + event log_int (int); + event log_uint (uint); + event log_bytes (bytes); + event log_string (string); + + event log_named_address (string key, address val); + event log_named_bytes32 (string key, bytes32 val); + event log_named_decimal_int (string key, int val, uint decimals); + event log_named_decimal_uint (string key, uint val, uint decimals); + event log_named_int (string key, int val); + event log_named_uint (string key, uint val); + event log_named_bytes (string key, bytes val); + event log_named_string (string key, string val); + + bool public IS_TEST = true; + bool public failed; + + address constant HEVM_ADDRESS = + address(bytes20(uint160(uint256(keccak256('hevm cheat code'))))); + + modifier mayRevert() { _; } + modifier testopts(string memory) { _; } + + function fail() internal { + failed = true; + } + + modifier logs_gas() { + uint startGas = gasleft(); + _; + uint endGas = gasleft(); + emit log_named_uint("gas", startGas - endGas); + } + + function assertTrue(bool condition) internal { + if (!condition) { + emit log("Error: Assertion Failed"); + fail(); + } + } + + function assertTrue(bool condition, string memory err) internal { + if (!condition) { + emit log_named_string("Error", err); + assertTrue(condition); + } + } + + function assertEq(address a, address b) internal { + if (a != b) { + emit log("Error: a == b not satisfied [address]"); + emit log_named_address(" Expected", b); + emit log_named_address(" Actual", a); + fail(); + } + } + function assertEq(address a, address b, string memory err) internal { + if (a != b) { + emit log_named_string ("Error", err); + assertEq(a, b); + } + } + + function assertEq(bytes32 a, bytes32 b) internal { + if (a != b) { + emit log("Error: a == b not satisfied [bytes32]"); + emit log_named_bytes32(" Expected", b); + emit log_named_bytes32(" Actual", a); + fail(); + } + } + function assertEq(bytes32 a, bytes32 b, string memory err) internal { + if (a != b) { + emit log_named_string ("Error", err); + assertEq(a, b); + } + } + function assertEq32(bytes32 a, bytes32 b) internal { + assertEq(a, b); + } + function assertEq32(bytes32 a, bytes32 b, string memory err) internal { + assertEq(a, b, err); + } + + function assertEq(int a, int b) internal { + if (a != b) { + emit log("Error: a == b not satisfied [int]"); + emit log_named_int(" Expected", b); + emit log_named_int(" Actual", a); + fail(); + } + } + function assertEq(int a, int b, string memory err) internal { + if (a != b) { + emit log_named_string("Error", err); + assertEq(a, b); + } + } + function assertEq(uint a, uint b) internal { + if (a != b) { + emit log("Error: a == b not satisfied [uint]"); + emit log_named_uint(" Expected", b); + emit log_named_uint(" Actual", a); + fail(); + } + } + function assertEq(uint a, uint b, string memory err) internal { + if (a != b) { + emit log_named_string("Error", err); + assertEq(a, b); + } + } + function assertEqDecimal(int a, int b, uint decimals) internal { + if (a != b) { + emit log("Error: a == b not satisfied [decimal int]"); + emit log_named_decimal_int(" Expected", b, decimals); + emit log_named_decimal_int(" Actual", a, decimals); + fail(); + } + } + function assertEqDecimal(int a, int b, uint decimals, string memory err) internal { + if (a != b) { + emit log_named_string("Error", err); + assertEqDecimal(a, b, decimals); + } + } + function assertEqDecimal(uint a, uint b, uint decimals) internal { + if (a != b) { + emit log("Error: a == b not satisfied [decimal uint]"); + emit log_named_decimal_uint(" Expected", b, decimals); + emit log_named_decimal_uint(" Actual", a, decimals); + fail(); + } + } + function assertEqDecimal(uint a, uint b, uint decimals, string memory err) internal { + if (a != b) { + emit log_named_string("Error", err); + assertEqDecimal(a, b, decimals); + } + } + + function assertGt(uint a, uint b) internal { + if (a <= b) { + emit log("Error: a > b not satisfied [uint]"); + emit log_named_uint(" Value a", a); + emit log_named_uint(" Value b", b); + fail(); + } + } + function assertGt(uint a, uint b, string memory err) internal { + if (a <= b) { + emit log_named_string("Error", err); + assertGt(a, b); + } + } + function assertGt(int a, int b) internal { + if (a <= b) { + emit log("Error: a > b not satisfied [int]"); + emit log_named_int(" Value a", a); + emit log_named_int(" Value b", b); + fail(); + } + } + function assertGt(int a, int b, string memory err) internal { + if (a <= b) { + emit log_named_string("Error", err); + assertGt(a, b); + } + } + function assertGtDecimal(int a, int b, uint decimals) internal { + if (a <= b) { + emit log("Error: a > b not satisfied [decimal int]"); + emit log_named_decimal_int(" Value a", a, decimals); + emit log_named_decimal_int(" Value b", b, decimals); + fail(); + } + } + function assertGtDecimal(int a, int b, uint decimals, string memory err) internal { + if (a <= b) { + emit log_named_string("Error", err); + assertGtDecimal(a, b, decimals); + } + } + function assertGtDecimal(uint a, uint b, uint decimals) internal { + if (a <= b) { + emit log("Error: a > b not satisfied [decimal uint]"); + emit log_named_decimal_uint(" Value a", a, decimals); + emit log_named_decimal_uint(" Value b", b, decimals); + fail(); + } + } + function assertGtDecimal(uint a, uint b, uint decimals, string memory err) internal { + if (a <= b) { + emit log_named_string("Error", err); + assertGtDecimal(a, b, decimals); + } + } + + function assertGe(uint a, uint b) internal { + if (a < b) { + emit log("Error: a >= b not satisfied [uint]"); + emit log_named_uint(" Value a", a); + emit log_named_uint(" Value b", b); + fail(); + } + } + function assertGe(uint a, uint b, string memory err) internal { + if (a < b) { + emit log_named_string("Error", err); + assertGe(a, b); + } + } + function assertGe(int a, int b) internal { + if (a < b) { + emit log("Error: a >= b not satisfied [int]"); + emit log_named_int(" Value a", a); + emit log_named_int(" Value b", b); + fail(); + } + } + function assertGe(int a, int b, string memory err) internal { + if (a < b) { + emit log_named_string("Error", err); + assertGe(a, b); + } + } + function assertGeDecimal(int a, int b, uint decimals) internal { + if (a < b) { + emit log("Error: a >= b not satisfied [decimal int]"); + emit log_named_decimal_int(" Value a", a, decimals); + emit log_named_decimal_int(" Value b", b, decimals); + fail(); + } + } + function assertGeDecimal(int a, int b, uint decimals, string memory err) internal { + if (a < b) { + emit log_named_string("Error", err); + assertGeDecimal(a, b, decimals); + } + } + function assertGeDecimal(uint a, uint b, uint decimals) internal { + if (a < b) { + emit log("Error: a >= b not satisfied [decimal uint]"); + emit log_named_decimal_uint(" Value a", a, decimals); + emit log_named_decimal_uint(" Value b", b, decimals); + fail(); + } + } + function assertGeDecimal(uint a, uint b, uint decimals, string memory err) internal { + if (a < b) { + emit log_named_string("Error", err); + assertGeDecimal(a, b, decimals); + } + } + + function assertLt(uint a, uint b) internal { + if (a >= b) { + emit log("Error: a < b not satisfied [uint]"); + emit log_named_uint(" Value a", a); + emit log_named_uint(" Value b", b); + fail(); + } + } + function assertLt(uint a, uint b, string memory err) internal { + if (a >= b) { + emit log_named_string("Error", err); + assertLt(a, b); + } + } + function assertLt(int a, int b) internal { + if (a >= b) { + emit log("Error: a < b not satisfied [int]"); + emit log_named_int(" Value a", a); + emit log_named_int(" Value b", b); + fail(); + } + } + function assertLt(int a, int b, string memory err) internal { + if (a >= b) { + emit log_named_string("Error", err); + assertLt(a, b); + } + } + function assertLtDecimal(int a, int b, uint decimals) internal { + if (a >= b) { + emit log("Error: a < b not satisfied [decimal int]"); + emit log_named_decimal_int(" Value a", a, decimals); + emit log_named_decimal_int(" Value b", b, decimals); + fail(); + } + } + function assertLtDecimal(int a, int b, uint decimals, string memory err) internal { + if (a >= b) { + emit log_named_string("Error", err); + assertLtDecimal(a, b, decimals); + } + } + function assertLtDecimal(uint a, uint b, uint decimals) internal { + if (a >= b) { + emit log("Error: a < b not satisfied [decimal uint]"); + emit log_named_decimal_uint(" Value a", a, decimals); + emit log_named_decimal_uint(" Value b", b, decimals); + fail(); + } + } + function assertLtDecimal(uint a, uint b, uint decimals, string memory err) internal { + if (a >= b) { + emit log_named_string("Error", err); + assertLtDecimal(a, b, decimals); + } + } + + function assertLe(uint a, uint b) internal { + if (a > b) { + emit log("Error: a <= b not satisfied [uint]"); + emit log_named_uint(" Value a", a); + emit log_named_uint(" Value b", b); + fail(); + } + } + function assertLe(uint a, uint b, string memory err) internal { + if (a > b) { + emit log_named_string("Error", err); + assertLe(a, b); + } + } + function assertLe(int a, int b) internal { + if (a > b) { + emit log("Error: a <= b not satisfied [int]"); + emit log_named_int(" Value a", a); + emit log_named_int(" Value b", b); + fail(); + } + } + function assertLe(int a, int b, string memory err) internal { + if (a > b) { + emit log_named_string("Error", err); + assertLe(a, b); + } + } + function assertLeDecimal(int a, int b, uint decimals) internal { + if (a > b) { + emit log("Error: a <= b not satisfied [decimal int]"); + emit log_named_decimal_int(" Value a", a, decimals); + emit log_named_decimal_int(" Value b", b, decimals); + fail(); + } + } + function assertLeDecimal(int a, int b, uint decimals, string memory err) internal { + if (a > b) { + emit log_named_string("Error", err); + assertLeDecimal(a, b, decimals); + } + } + function assertLeDecimal(uint a, uint b, uint decimals) internal { + if (a > b) { + emit log("Error: a <= b not satisfied [decimal uint]"); + emit log_named_decimal_uint(" Value a", a, decimals); + emit log_named_decimal_uint(" Value b", b, decimals); + fail(); + } + } + function assertLeDecimal(uint a, uint b, uint decimals, string memory err) internal { + if (a > b) { + emit log_named_string("Error", err); + assertGeDecimal(a, b, decimals); + } + } + + function assertEq(string memory a, string memory b) internal { + if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) { + emit log("Error: a == b not satisfied [string]"); + emit log_named_string(" Value a", a); + emit log_named_string(" Value b", b); + fail(); + } + } + function assertEq(string memory a, string memory b, string memory err) internal { + if (keccak256(abi.encodePacked(a)) != keccak256(abi.encodePacked(b))) { + emit log_named_string("Error", err); + assertEq(a, b); + } + } + + function checkEq0(bytes memory a, bytes memory b) internal pure returns (bool ok) { + ok = true; + if (a.length == b.length) { + for (uint i = 0; i < a.length; i++) { + if (a[i] != b[i]) { + ok = false; + } + } + } else { + ok = false; + } + } + function assertEq0(bytes memory a, bytes memory b) internal { + if (!checkEq0(a, b)) { + emit log("Error: a == b not satisfied [bytes]"); + emit log_named_bytes(" Expected", a); + emit log_named_bytes(" Actual", b); + fail(); + } + } + function assertEq0(bytes memory a, bytes memory b, string memory err) internal { + if (!checkEq0(a, b)) { + emit log_named_string("Error", err); + assertEq0(a, b); + } + } +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/src/strings.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/src/strings.sol new file mode 100644 index 0000000000..c801990e8a --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/src/strings.sol @@ -0,0 +1,727 @@ +/* + * @title String & slice utility library for Solidity contracts. + * @author Nick Johnson + * + * @dev Functionality in this library is largely implemented using an + * abstraction called a 'slice'. A slice represents a part of a string - + * anything from the entire string to a single character, or even no + * characters at all (a 0-length slice). Since a slice only has to specify + * an offset and a length, copying and manipulating slices is a lot less + * expensive than copying and manipulating the strings they reference. + * + * To further reduce gas costs, most functions on slice that need to return + * a slice modify the original one instead of allocating a new one; for + * instance, `s.split(".")` will return the text up to the first '.', + * modifying s to only contain the remainder of the string after the '.'. + * In situations where you do not want to modify the original slice, you + * can make a copy first with `.copy()`, for example: + * `s.copy().split(".")`. Try and avoid using this idiom in loops; since + * Solidity has no memory management, it will result in allocating many + * short-lived slices that are later discarded. + * + * Functions that return two slices come in two versions: a non-allocating + * version that takes the second slice as an argument, modifying it in + * place, and an allocating version that allocates and returns the second + * slice; see `nextRune` for example. + * + * Functions that have to copy string data will return strings rather than + * slices; these can be cast back to slices for further processing if + * required. + * + * For convenience, some functions are provided with non-modifying + * variants that create a new slice and return both; for instance, + * `s.splitNew('.')` leaves s unmodified, and returns two values + * corresponding to the left and right parts of the string. + */ + +pragma solidity ^0.8.0; + +library strings { + struct slice { + uint _len; + uint _ptr; + } + + function memcpy(uint dest, uint src, uint length) private pure { + // Copy word-length chunks while possible + for(; length >= 32; length -= 32) { + assembly { + mstore(dest, mload(src)) + } + dest += 32; + src += 32; + } + + // Copy remaining bytes + uint mask = type(uint).max; + if (length > 0) { + mask = 256 ** (32 - length) - 1; + } + assembly { + let srcpart := and(mload(src), not(mask)) + let destpart := and(mload(dest), mask) + mstore(dest, or(destpart, srcpart)) + } + } + + /* + * @dev Returns a slice containing the entire string. + * @param self The string to make a slice from. + * @return A newly allocated slice containing the entire string. + */ + function toSlice(string memory self) internal pure returns (slice memory) { + uint ptr; + assembly { + ptr := add(self, 0x20) + } + return slice(bytes(self).length, ptr); + } + + /* + * @dev Returns the length of a null-terminated bytes32 string. + * @param self The value to find the length of. + * @return The length of the string, from 0 to 32. + */ + function len(bytes32 self) internal pure returns (uint) { + uint ret; + if (self == 0) + return 0; + if (uint(self) & type(uint128).max == 0) { + ret += 16; + self = bytes32(uint(self) / 0x100000000000000000000000000000000); + } + if (uint(self) & type(uint64).max == 0) { + ret += 8; + self = bytes32(uint(self) / 0x10000000000000000); + } + if (uint(self) & type(uint32).max == 0) { + ret += 4; + self = bytes32(uint(self) / 0x100000000); + } + if (uint(self) & type(uint16).max == 0) { + ret += 2; + self = bytes32(uint(self) / 0x10000); + } + if (uint(self) & type(uint8).max == 0) { + ret += 1; + } + return 32 - ret; + } + + /* + * @dev Returns a slice containing the entire bytes32, interpreted as a + * null-terminated utf-8 string. + * @param self The bytes32 value to convert to a slice. + * @return A new slice containing the value of the input argument up to the + * first null. + */ + function toSliceB32(bytes32 self) internal pure returns (slice memory ret) { + // Allocate space for `self` in memory, copy it there, and point ret at it + assembly { + let ptr := mload(0x40) + mstore(0x40, add(ptr, 0x20)) + mstore(ptr, self) + mstore(add(ret, 0x20), ptr) + } + ret._len = len(self); + } + + /* + * @dev Returns a new slice containing the same data as the current slice. + * @param self The slice to copy. + * @return A new slice containing the same data as `self`. + */ + function copy(slice memory self) internal pure returns (slice memory) { + return slice(self._len, self._ptr); + } + + /* + * @dev Copies a slice to a new string. + * @param self The slice to copy. + * @return A newly allocated string containing the slice's text. + */ + function toString(slice memory self) internal pure returns (string memory) { + string memory ret = new string(self._len); + uint retptr; + assembly { retptr := add(ret, 32) } + + memcpy(retptr, self._ptr, self._len); + return ret; + } + + /* + * @dev Returns the length in runes of the slice. Note that this operation + * takes time proportional to the length of the slice; avoid using it + * in loops, and call `slice.empty()` if you only need to know whether + * the slice is empty or not. + * @param self The slice to operate on. + * @return The length of the slice in runes. + */ + function len(slice memory self) internal pure returns (uint l) { + // Starting at ptr-31 means the LSB will be the byte we care about + uint ptr = self._ptr - 31; + uint end = ptr + self._len; + for (l = 0; ptr < end; l++) { + uint8 b; + assembly { b := and(mload(ptr), 0xFF) } + if (b < 0x80) { + ptr += 1; + } else if(b < 0xE0) { + ptr += 2; + } else if(b < 0xF0) { + ptr += 3; + } else if(b < 0xF8) { + ptr += 4; + } else if(b < 0xFC) { + ptr += 5; + } else { + ptr += 6; + } + } + } + + /* + * @dev Returns true if the slice is empty (has a length of 0). + * @param self The slice to operate on. + * @return True if the slice is empty, False otherwise. + */ + function empty(slice memory self) internal pure returns (bool) { + return self._len == 0; + } + + /* + * @dev Returns a positive number if `other` comes lexicographically after + * `self`, a negative number if it comes before, or zero if the + * contents of the two slices are equal. Comparison is done per-rune, + * on unicode codepoints. + * @param self The first slice to compare. + * @param other The second slice to compare. + * @return The result of the comparison. + */ + function compare(slice memory self, slice memory other) internal pure returns (int) { + uint shortest = self._len; + if (other._len < self._len) + shortest = other._len; + + uint selfptr = self._ptr; + uint otherptr = other._ptr; + for (uint idx = 0; idx < shortest; idx += 32) { + uint a; + uint b; + assembly { + a := mload(selfptr) + b := mload(otherptr) + } + if (a != b) { + // Mask out irrelevant bytes and check again + uint mask = type(uint).max; // 0xffff... + if(shortest < 32) { + mask = ~(2 ** (8 * (32 - shortest + idx)) - 1); + } + unchecked { + uint diff = (a & mask) - (b & mask); + if (diff != 0) + return int(diff); + } + } + selfptr += 32; + otherptr += 32; + } + return int(self._len) - int(other._len); + } + + /* + * @dev Returns true if the two slices contain the same text. + * @param self The first slice to compare. + * @param self The second slice to compare. + * @return True if the slices are equal, false otherwise. + */ + function equals(slice memory self, slice memory other) internal pure returns (bool) { + return compare(self, other) == 0; + } + + /* + * @dev Extracts the first rune in the slice into `rune`, advancing the + * slice to point to the next rune and returning `self`. + * @param self The slice to operate on. + * @param rune The slice that will contain the first rune. + * @return `rune`. + */ + function nextRune(slice memory self, slice memory rune) internal pure returns (slice memory) { + rune._ptr = self._ptr; + + if (self._len == 0) { + rune._len = 0; + return rune; + } + + uint l; + uint b; + // Load the first byte of the rune into the LSBs of b + assembly { b := and(mload(sub(mload(add(self, 32)), 31)), 0xFF) } + if (b < 0x80) { + l = 1; + } else if(b < 0xE0) { + l = 2; + } else if(b < 0xF0) { + l = 3; + } else { + l = 4; + } + + // Check for truncated codepoints + if (l > self._len) { + rune._len = self._len; + self._ptr += self._len; + self._len = 0; + return rune; + } + + self._ptr += l; + self._len -= l; + rune._len = l; + return rune; + } + + /* + * @dev Returns the first rune in the slice, advancing the slice to point + * to the next rune. + * @param self The slice to operate on. + * @return A slice containing only the first rune from `self`. + */ + function nextRune(slice memory self) internal pure returns (slice memory ret) { + nextRune(self, ret); + } + + /* + * @dev Returns the number of the first codepoint in the slice. + * @param self The slice to operate on. + * @return The number of the first codepoint in the slice. + */ + function ord(slice memory self) internal pure returns (uint ret) { + if (self._len == 0) { + return 0; + } + + uint word; + uint length; + uint divisor = 2 ** 248; + + // Load the rune into the MSBs of b + assembly { word:= mload(mload(add(self, 32))) } + uint b = word / divisor; + if (b < 0x80) { + ret = b; + length = 1; + } else if(b < 0xE0) { + ret = b & 0x1F; + length = 2; + } else if(b < 0xF0) { + ret = b & 0x0F; + length = 3; + } else { + ret = b & 0x07; + length = 4; + } + + // Check for truncated codepoints + if (length > self._len) { + return 0; + } + + for (uint i = 1; i < length; i++) { + divisor = divisor / 256; + b = (word / divisor) & 0xFF; + if (b & 0xC0 != 0x80) { + // Invalid UTF-8 sequence + return 0; + } + ret = (ret * 64) | (b & 0x3F); + } + + return ret; + } + + /* + * @dev Returns the keccak-256 hash of the slice. + * @param self The slice to hash. + * @return The hash of the slice. + */ + function keccak(slice memory self) internal pure returns (bytes32 ret) { + assembly { + ret := keccak256(mload(add(self, 32)), mload(self)) + } + } + + /* + * @dev Returns true if `self` starts with `needle`. + * @param self The slice to operate on. + * @param needle The slice to search for. + * @return True if the slice starts with the provided text, false otherwise. + */ + function startsWith(slice memory self, slice memory needle) internal pure returns (bool) { + if (self._len < needle._len) { + return false; + } + + if (self._ptr == needle._ptr) { + return true; + } + + bool equal; + assembly { + let length := mload(needle) + let selfptr := mload(add(self, 0x20)) + let needleptr := mload(add(needle, 0x20)) + equal := eq(keccak256(selfptr, length), keccak256(needleptr, length)) + } + return equal; + } + + /* + * @dev If `self` starts with `needle`, `needle` is removed from the + * beginning of `self`. Otherwise, `self` is unmodified. + * @param self The slice to operate on. + * @param needle The slice to search for. + * @return `self` + */ + function beyond(slice memory self, slice memory needle) internal pure returns (slice memory) { + if (self._len < needle._len) { + return self; + } + + bool equal = true; + if (self._ptr != needle._ptr) { + assembly { + let length := mload(needle) + let selfptr := mload(add(self, 0x20)) + let needleptr := mload(add(needle, 0x20)) + equal := eq(keccak256(selfptr, length), keccak256(needleptr, length)) + } + } + + if (equal) { + self._len -= needle._len; + self._ptr += needle._len; + } + + return self; + } + + /* + * @dev Returns true if the slice ends with `needle`. + * @param self The slice to operate on. + * @param needle The slice to search for. + * @return True if the slice starts with the provided text, false otherwise. + */ + function endsWith(slice memory self, slice memory needle) internal pure returns (bool) { + if (self._len < needle._len) { + return false; + } + + uint selfptr = self._ptr + self._len - needle._len; + + if (selfptr == needle._ptr) { + return true; + } + + bool equal; + assembly { + let length := mload(needle) + let needleptr := mload(add(needle, 0x20)) + equal := eq(keccak256(selfptr, length), keccak256(needleptr, length)) + } + + return equal; + } + + /* + * @dev If `self` ends with `needle`, `needle` is removed from the + * end of `self`. Otherwise, `self` is unmodified. + * @param self The slice to operate on. + * @param needle The slice to search for. + * @return `self` + */ + function until(slice memory self, slice memory needle) internal pure returns (slice memory) { + if (self._len < needle._len) { + return self; + } + + uint selfptr = self._ptr + self._len - needle._len; + bool equal = true; + if (selfptr != needle._ptr) { + assembly { + let length := mload(needle) + let needleptr := mload(add(needle, 0x20)) + equal := eq(keccak256(selfptr, length), keccak256(needleptr, length)) + } + } + + if (equal) { + self._len -= needle._len; + } + + return self; + } + + // Returns the memory address of the first byte of the first occurrence of + // `needle` in `self`, or the first byte after `self` if not found. + function findPtr(uint selflen, uint selfptr, uint needlelen, uint needleptr) private pure returns (uint) { + uint ptr = selfptr; + uint idx; + + if (needlelen <= selflen) { + if (needlelen <= 32) { + bytes32 mask; + if (needlelen > 0) { + mask = bytes32(~(2 ** (8 * (32 - needlelen)) - 1)); + } + + bytes32 needledata; + assembly { needledata := and(mload(needleptr), mask) } + + uint end = selfptr + selflen - needlelen; + bytes32 ptrdata; + assembly { ptrdata := and(mload(ptr), mask) } + + while (ptrdata != needledata) { + if (ptr >= end) + return selfptr + selflen; + ptr++; + assembly { ptrdata := and(mload(ptr), mask) } + } + return ptr; + } else { + // For long needles, use hashing + bytes32 hash; + assembly { hash := keccak256(needleptr, needlelen) } + + for (idx = 0; idx <= selflen - needlelen; idx++) { + bytes32 testHash; + assembly { testHash := keccak256(ptr, needlelen) } + if (hash == testHash) + return ptr; + ptr += 1; + } + } + } + return selfptr + selflen; + } + + // Returns the memory address of the first byte after the last occurrence of + // `needle` in `self`, or the address of `self` if not found. + function rfindPtr(uint selflen, uint selfptr, uint needlelen, uint needleptr) private pure returns (uint) { + uint ptr; + + if (needlelen <= selflen) { + if (needlelen <= 32) { + bytes32 mask; + if (needlelen > 0) { + mask = bytes32(~(2 ** (8 * (32 - needlelen)) - 1)); + } + + bytes32 needledata; + assembly { needledata := and(mload(needleptr), mask) } + + ptr = selfptr + selflen - needlelen; + bytes32 ptrdata; + assembly { ptrdata := and(mload(ptr), mask) } + + while (ptrdata != needledata) { + if (ptr <= selfptr) + return selfptr; + ptr--; + assembly { ptrdata := and(mload(ptr), mask) } + } + return ptr + needlelen; + } else { + // For long needles, use hashing + bytes32 hash; + assembly { hash := keccak256(needleptr, needlelen) } + ptr = selfptr + (selflen - needlelen); + while (ptr >= selfptr) { + bytes32 testHash; + assembly { testHash := keccak256(ptr, needlelen) } + if (hash == testHash) + return ptr + needlelen; + ptr -= 1; + } + } + } + return selfptr; + } + + /* + * @dev Modifies `self` to contain everything from the first occurrence of + * `needle` to the end of the slice. `self` is set to the empty slice + * if `needle` is not found. + * @param self The slice to search and modify. + * @param needle The text to search for. + * @return `self`. + */ + function find(slice memory self, slice memory needle) internal pure returns (slice memory) { + uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr); + self._len -= ptr - self._ptr; + self._ptr = ptr; + return self; + } + + /* + * @dev Modifies `self` to contain the part of the string from the start of + * `self` to the end of the first occurrence of `needle`. If `needle` + * is not found, `self` is set to the empty slice. + * @param self The slice to search and modify. + * @param needle The text to search for. + * @return `self`. + */ + function rfind(slice memory self, slice memory needle) internal pure returns (slice memory) { + uint ptr = rfindPtr(self._len, self._ptr, needle._len, needle._ptr); + self._len = ptr - self._ptr; + return self; + } + + /* + * @dev Splits the slice, setting `self` to everything after the first + * occurrence of `needle`, and `token` to everything before it. If + * `needle` does not occur in `self`, `self` is set to the empty slice, + * and `token` is set to the entirety of `self`. + * @param self The slice to split. + * @param needle The text to search for in `self`. + * @param token An output parameter to which the first token is written. + * @return `token`. + */ + function split(slice memory self, slice memory needle, slice memory token) internal pure returns (slice memory) { + uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr); + token._ptr = self._ptr; + token._len = ptr - self._ptr; + if (ptr == self._ptr + self._len) { + // Not found + self._len = 0; + } else { + self._len -= token._len + needle._len; + self._ptr = ptr + needle._len; + } + return token; + } + + /* + * @dev Splits the slice, setting `self` to everything after the first + * occurrence of `needle`, and returning everything before it. If + * `needle` does not occur in `self`, `self` is set to the empty slice, + * and the entirety of `self` is returned. + * @param self The slice to split. + * @param needle The text to search for in `self`. + * @return The part of `self` up to the first occurrence of `delim`. + */ + function split(slice memory self, slice memory needle) internal pure returns (slice memory token) { + split(self, needle, token); + } + + /* + * @dev Splits the slice, setting `self` to everything before the last + * occurrence of `needle`, and `token` to everything after it. If + * `needle` does not occur in `self`, `self` is set to the empty slice, + * and `token` is set to the entirety of `self`. + * @param self The slice to split. + * @param needle The text to search for in `self`. + * @param token An output parameter to which the first token is written. + * @return `token`. + */ + function rsplit(slice memory self, slice memory needle, slice memory token) internal pure returns (slice memory) { + uint ptr = rfindPtr(self._len, self._ptr, needle._len, needle._ptr); + token._ptr = ptr; + token._len = self._len - (ptr - self._ptr); + if (ptr == self._ptr) { + // Not found + self._len = 0; + } else { + self._len -= token._len + needle._len; + } + return token; + } + + /* + * @dev Splits the slice, setting `self` to everything before the last + * occurrence of `needle`, and returning everything after it. If + * `needle` does not occur in `self`, `self` is set to the empty slice, + * and the entirety of `self` is returned. + * @param self The slice to split. + * @param needle The text to search for in `self`. + * @return The part of `self` after the last occurrence of `delim`. + */ + function rsplit(slice memory self, slice memory needle) internal pure returns (slice memory token) { + rsplit(self, needle, token); + } + + /* + * @dev Counts the number of nonoverlapping occurrences of `needle` in `self`. + * @param self The slice to search. + * @param needle The text to search for in `self`. + * @return The number of occurrences of `needle` found in `self`. + */ + function count(slice memory self, slice memory needle) internal pure returns (uint cnt) { + uint ptr = findPtr(self._len, self._ptr, needle._len, needle._ptr) + needle._len; + while (ptr <= self._ptr + self._len) { + cnt++; + ptr = findPtr(self._len - (ptr - self._ptr), ptr, needle._len, needle._ptr) + needle._len; + } + } + + /* + * @dev Returns True if `self` contains `needle`. + * @param self The slice to search. + * @param needle The text to search for in `self`. + * @return True if `needle` is found in `self`, false otherwise. + */ + function contains(slice memory self, slice memory needle) internal pure returns (bool) { + return rfindPtr(self._len, self._ptr, needle._len, needle._ptr) != self._ptr; + } + + /* + * @dev Returns a newly allocated string containing the concatenation of + * `self` and `other`. + * @param self The first slice to concatenate. + * @param other The second slice to concatenate. + * @return The concatenation of the two strings. + */ + function concat(slice memory self, slice memory other) internal pure returns (string memory) { + string memory ret = new string(self._len + other._len); + uint retptr; + assembly { retptr := add(ret, 32) } + memcpy(retptr, self._ptr, self._len); + memcpy(retptr + self._len, other._ptr, other._len); + return ret; + } + + /* + * @dev Joins an array of slices, using `self` as a delimiter, returning a + * newly allocated string. + * @param self The delimiter to use. + * @param parts A list of slices to join. + * @return A newly allocated string containing all the slices in `parts`, + * joined with `self`. + */ + function join(slice memory self, slice[] memory parts) internal pure returns (string memory) { + if (parts.length == 0) + return ""; + + uint length = self._len * (parts.length - 1); + for(uint i = 0; i < parts.length; i++) + length += parts[i]._len; + + string memory ret = new string(length); + uint retptr; + assembly { retptr := add(ret, 32) } + + for(uint i = 0; i < parts.length; i++) { + memcpy(retptr, parts[i]._ptr, parts[i]._len); + retptr += parts[i]._len; + if (i < parts.length - 1) { + memcpy(retptr, self._ptr, self._len); + retptr += self._len; + } + } + + return ret; + } +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/src/strings.t.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/src/strings.t.sol new file mode 100644 index 0000000000..bc3581cc27 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/lib/solidity-stringutils/src/strings.t.sol @@ -0,0 +1,216 @@ +pragma solidity ^0.8.0; + +import 'ds-test/test.sol'; +import './strings.sol'; + +contract StringsTest is DSTest { + using strings for *; + + + function abs(int x) private pure returns (int) { + if(x < 0) + return -x; + return x; + } + + function sign(int x) private pure returns (int) { + return x == 0 ? int(0) : (x < 0 ? -1 : int(1)); + } + + function assertEq0(string memory a, string memory b) internal { + assertEq0(bytes(a), bytes(b)); + } + + function assertEq0(strings.slice memory a, strings.slice memory b) internal { + assertEq0(a.toString(), b.toString()); + } + + function assertEq0(strings.slice memory a, string memory b) internal { + assertEq0(a.toString(), b); + } + + function testSliceToString() public { + string memory test = "Hello, world!"; + assertEq0(test, test.toSlice().toString()); + } + + function testBytes32Len() public { + bytes32 test; + for(uint i = 0; i <= 32; i++) { + assertEq(i, test.len()); + test = bytes32((uint(test) / 0x100) | 0x2000000000000000000000000000000000000000000000000000000000000000); + } + } + + + function testToSliceB32() public { + assertEq0(bytes32("foobar").toSliceB32(), "foobar".toSlice()); + } + + function testCopy() public { + string memory test = "Hello, world!"; + strings.slice memory s1 = test.toSlice(); + strings.slice memory s2 = s1.copy(); + s1._len = 0; + assertEq(s2._len, bytes(test).length); + } + + function testLen() public { + assertEq("".toSlice().len(), 0); + assertEq("Hello, world!".toSlice().len(), 13); + assertEq(unicode"naĆÆve".toSlice().len(), 5); + assertEq(unicode"こんにごは".toSlice().len(), 5); + } + + function testEmpty() public { + assertTrue("".toSlice().empty()); + assertTrue(!"x".toSlice().empty()); + } + + function testEquals() public { + assertTrue("".toSlice().equals("".toSlice())); + assertTrue("foo".toSlice().equals("foo".toSlice())); + assertTrue(!"foo".toSlice().equals("bar".toSlice())); + } + + function testNextRune() public { + strings.slice memory s = unicode"a”ࠀ𐀔".toSlice(); + assertEq0(s.nextRune(), "a"); + assertEq0(s, unicode"”ࠀ𐀔"); + assertEq0(s.nextRune(), unicode"Ā”"); + assertEq0(s, unicode"ࠀ𐀔"); + assertEq0(s.nextRune(), unicode"ą €"); + assertEq0(s, unicode"𐀔"); + assertEq0(s.nextRune(), unicode"𐀔"); + assertEq0(s, ""); + assertEq0(s.nextRune(), ""); + } + + function testOrd() public { + assertEq("a".toSlice().ord(), 0x61); + assertEq(unicode"Ā”".toSlice().ord(), 0xA1); + assertEq(unicode"ą €".toSlice().ord(), 0x800); + assertEq(unicode"𐀔".toSlice().ord(), 0x10021); + } + + function testCompare() public { + + assertEq(sign("foobie".toSlice().compare("foobie".toSlice())), 0); + assertEq(sign("foobie".toSlice().compare("foobif".toSlice())), -1); + assertEq(sign("foobie".toSlice().compare("foobid".toSlice())), 1); + assertEq(sign("foobie".toSlice().compare("foobies".toSlice())), -1); + assertEq(sign("foobie".toSlice().compare("foobi".toSlice())), 1); + assertEq(sign("foobie".toSlice().compare("doobie".toSlice())), 1); + assertEq(sign("01234567890123456789012345678901".toSlice().compare("012345678901234567890123456789012".toSlice())), -1); + assertEq(sign("0123456789012345678901234567890123".toSlice().compare("1123456789012345678901234567890123".toSlice())), -1); + assertEq(sign("foo.bar".toSlice().split(".".toSlice()).compare("foo".toSlice())), 0); + } + + function testStartsWith() public { + strings.slice memory s = "foobar".toSlice(); + assertTrue(s.startsWith("foo".toSlice())); + assertTrue(!s.startsWith("oob".toSlice())); + assertTrue(s.startsWith("".toSlice())); + assertTrue(s.startsWith(s.copy().rfind("foo".toSlice()))); + } + + function testBeyond() public { + strings.slice memory s = "foobar".toSlice(); + assertEq0(s.beyond("foo".toSlice()), "bar"); + assertEq0(s, "bar"); + assertEq0(s.beyond("foo".toSlice()), "bar"); + assertEq0(s.beyond("bar".toSlice()), ""); + assertEq0(s, ""); + } + + function testEndsWith() public { + strings.slice memory s = "foobar".toSlice(); + assertTrue(s.endsWith("bar".toSlice())); + assertTrue(!s.endsWith("oba".toSlice())); + assertTrue(s.endsWith("".toSlice())); + assertTrue(s.endsWith(s.copy().find("bar".toSlice()))); + } + + function testUntil() public { + strings.slice memory s = "foobar".toSlice(); + assertEq0(s.until("bar".toSlice()), "foo"); + assertEq0(s, "foo"); + assertEq0(s.until("bar".toSlice()), "foo"); + assertEq0(s.until("foo".toSlice()), ""); + assertEq0(s, ""); + } + + function testFind() public { + assertEq0("abracadabra".toSlice().find("abracadabra".toSlice()), "abracadabra"); + assertEq0("abracadabra".toSlice().find("bra".toSlice()), "bracadabra"); + assertTrue("abracadabra".toSlice().find("rab".toSlice()).empty()); + assertTrue("12345".toSlice().find("123456".toSlice()).empty()); + assertEq0("12345".toSlice().find("".toSlice()), "12345"); + assertEq0("12345".toSlice().find("5".toSlice()), "5"); + } + + function testRfind() public { + assertEq0("abracadabra".toSlice().rfind("bra".toSlice()), "abracadabra"); + assertEq0("abracadabra".toSlice().rfind("cad".toSlice()), "abracad"); + assertTrue("12345".toSlice().rfind("123456".toSlice()).empty()); + assertEq0("12345".toSlice().rfind("".toSlice()), "12345"); + assertEq0("12345".toSlice().rfind("1".toSlice()), "1"); + } + + function testSplit() public { + strings.slice memory s = "foo->bar->baz".toSlice(); + strings.slice memory delim = "->".toSlice(); + assertEq0(s.split(delim), "foo"); + assertEq0(s, "bar->baz"); + assertEq0(s.split(delim), "bar"); + assertEq0(s.split(delim), "baz"); + assertTrue(s.empty()); + assertEq0(s.split(delim), ""); + assertEq0(".".toSlice().split(".".toSlice()), ""); + } + + function testRsplit() public { + strings.slice memory s = "foo->bar->baz".toSlice(); + strings.slice memory delim = "->".toSlice(); + assertEq0(s.rsplit(delim), "baz"); + assertEq0(s.rsplit(delim), "bar"); + assertEq0(s.rsplit(delim), "foo"); + assertTrue(s.empty()); + assertEq0(s.rsplit(delim), ""); + } + + function testCount() public { + assertEq("1121123211234321".toSlice().count("1".toSlice()), 7); + assertEq("ababababa".toSlice().count("aba".toSlice()), 2); + } + + function testContains() public { + assertTrue("foobar".toSlice().contains("f".toSlice())); + assertTrue("foobar".toSlice().contains("o".toSlice())); + assertTrue("foobar".toSlice().contains("r".toSlice())); + assertTrue("foobar".toSlice().contains("".toSlice())); + assertTrue("foobar".toSlice().contains("foobar".toSlice())); + assertTrue(!"foobar".toSlice().contains("s".toSlice())); + } + + function testConcat() public { + assertEq0("foo".toSlice().concat("bar".toSlice()), "foobar"); + assertEq0("".toSlice().concat("bar".toSlice()), "bar"); + assertEq0("foo".toSlice().concat("".toSlice()), "foo"); + } + + function testJoin() public { + strings.slice[] memory parts = new strings.slice[](4); + parts[0] = "zero".toSlice(); + parts[1] = "one".toSlice(); + parts[2] = "".toSlice(); + parts[3] = "two".toSlice(); + + assertEq0(" ".toSlice().join(parts), "zero one two"); + assertEq0("".toSlice().join(parts), "zeroonetwo"); + + parts = new strings.slice[](1); + parts[0] = "zero".toSlice(); + assertEq0(" ".toSlice().join(parts), "zero"); + } +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/remappings.txt b/packages/wallet/wallet-contracts/lib/foundry-huff/remappings.txt new file mode 100644 index 0000000000..1722d907ea --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/remappings.txt @@ -0,0 +1,2 @@ +forge-std/=lib/forge-std/src/ +stringutils/=lib/solidity-stringutils/ \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/scripts/binary_check.sh b/packages/wallet/wallet-contracts/lib/foundry-huff/scripts/binary_check.sh new file mode 100644 index 0000000000..725a058b50 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/scripts/binary_check.sh @@ -0,0 +1,11 @@ +#! /bin/bash + +if ! [[ "$(npm list -g huffc)" =~ "empty" ]]; then + # huffc was installed via npm, return 0x00 + echo -n 0x00 +elif [[ "$(yarn global list)" =~ "huffc" ]]; then + # huffc was installed via yarn, return 0x00 + echo -n 0x00 +else + echo -n 0x01 +fi diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/scripts/file_writer.sh b/packages/wallet/wallet-contracts/lib/foundry-huff/scripts/file_writer.sh new file mode 100644 index 0000000000..93e3a8d325 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/scripts/file_writer.sh @@ -0,0 +1,3 @@ +#! /bin/bash + +echo "$2" > $1 diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/scripts/rand_bytes.sh b/packages/wallet/wallet-contracts/lib/foundry-huff/scripts/rand_bytes.sh new file mode 100644 index 0000000000..fdd9921067 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/scripts/rand_bytes.sh @@ -0,0 +1,3 @@ +#! /bin/bash + +echo -n $(hexdump -n 16 -v -e '"0x" 32/1 "%02x" "\n"' /dev/urandom) \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/scripts/read_and_append.sh b/packages/wallet/wallet-contracts/lib/foundry-huff/scripts/read_and_append.sh new file mode 100644 index 0000000000..a14336571e --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/scripts/read_and_append.sh @@ -0,0 +1,3 @@ +#! /bin/bash + +cat $2 >> $1 diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/src/HuffConfig.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/src/HuffConfig.sol new file mode 100644 index 0000000000..a6f8b09a43 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/src/HuffConfig.sol @@ -0,0 +1,247 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.8.13 <0.9.0; + +import {Vm} from "forge-std/Vm.sol"; +import {strings} from "stringutils/strings.sol"; + +contract HuffConfig { + using strings for *; + + /// @notice Initializes cheat codes in order to use ffi to compile Huff contracts + Vm public constant vm = Vm(address(bytes20(uint160(uint256(keccak256("hevm cheat code")))))); + + /// @notice Struct that represents a constant to be passed to the `-c` flag + struct Constant { + string key; + string value; + } + + /// @notice additional code to append to the source file + string public code; + + /// @notice arguments to append to the bytecode + bytes public args; + + /// @notice value to deploy the contract with + uint256 public value; + + /// @notice address that will be the `msg.sender` (op: caller) in the constructor + /// @dev set to config address to ensure backwards compatibility + address public deployer = address(this); + + /// @notice whether to broadcast the deployment tx + bool public should_broadcast; + + /// @notice supported evm versions + string public evm_version; + + /// @notice constant overrides for the current compilation environment + Constant[] public const_overrides; + + /// @notice sets the code to be appended to the source file + function with_code(string memory code_) public returns (HuffConfig) { + code = code_; + return this; + } + + /// @notice sets the arguments to be appended to the bytecode + function with_args(bytes memory args_) public returns (HuffConfig) { + args = args_; + return this; + } + + /// @notice sets the amount of wei to deploy the contract with + function with_value(uint256 value_) public returns (HuffConfig) { + value = value_; + return this; + } + + /// @notice sets the caller of the next deployment + function with_deployer(address _deployer) public returns (HuffConfig) { + deployer = _deployer; + return this; + } + + /// @notice sets the evm version to compile with + function with_evm_version(string memory _evm_version) public returns (HuffConfig) { + evm_version = _evm_version; + return this; + } + + /// @notice sets a constant to a bytes memory value in the current compilation environment + /// @dev The `value` string must contain a valid hex number that is <= 32 bytes + /// i.e. "0x01", "0xa57b", "0x0de0b6b3a7640000", etc. + function with_constant(string memory key, string memory value_) public returns (HuffConfig) { + const_overrides.push(Constant(key, value_)); + return this; + } + + /// @notice sets a constant to an address value in the current compilation environment + function with_addr_constant(string memory key, address value_) public returns (HuffConfig) { + const_overrides.push(Constant(key, bytesToString(abi.encodePacked(value_)))); + return this; + } + + /// @notice sets a constant to a bytes32 value in the current compilation environment + function with_bytes32_constant(string memory key, bytes32 value_) public returns (HuffConfig) { + const_overrides.push(Constant(key, bytesToString(abi.encodePacked(value_)))); + return this; + } + + /// @notice sets a constant to a uint256 value in the current compilation environment + function with_uint_constant(string memory key, uint256 value_) public returns (HuffConfig) { + const_overrides.push(Constant(key, bytesToString(abi.encodePacked(value_)))); + return this; + } + + /// @notice sets whether to broadcast the deployment + function set_broadcast(bool broadcast) public returns (HuffConfig) { + should_broadcast = broadcast; + return this; + } + + /// @notice Checks for huffc binary conflicts + function binary_check() public { + string[] memory bincheck = new string[](1); + bincheck[0] = "./lib/foundry-huff/scripts/binary_check.sh"; + bytes memory retData = vm.ffi(bincheck); + bytes8 first_bytes = retData[0]; + bool decoded = first_bytes == bytes8(hex"01"); + require( + decoded, "Invalid huffc binary. Run `curl -L get.huff.sh | bash` and `huffup` to fix." + ); + } + + function bytes32ToString(bytes32 x) internal pure returns (string memory) { + string memory result; + for (uint256 j = 0; j < x.length; j++) { + result = string.concat(result, string(abi.encodePacked(uint8(x[j]) % 26 + 97))); + } + return result; + } + + function bytesToString(bytes memory data) public pure returns (string memory) { + bytes memory alphabet = "0123456789abcdef"; + + bytes memory str = new bytes(2 + data.length * 2); + str[0] = "0"; + str[1] = "x"; + for (uint256 i = 0; i < data.length; i++) { + str[2 + i * 2] = alphabet[uint256(uint8(data[i] >> 4))]; + str[3 + i * 2] = alphabet[uint256(uint8(data[i] & 0x0f))]; + } + return string(str); + } + + /// @notice Get the evm version string | else return default ("shanghai") + function get_evm_version() public view returns (string memory) { + bytes32 _evm_version = bytes32(bytes(abi.encodePacked(evm_version))); + if (_evm_version == bytes32(0x0)) { + return "shanghai"; + } + return evm_version; + } + + /// @notice Get the creation bytecode of a contract + function creation_code(string memory file) public payable returns (bytes memory bytecode) { + binary_check(); + + // Split the file into its parts + strings.slice memory s = file.toSlice(); + strings.slice memory delim = "/".toSlice(); + string[] memory parts = new string[](s.count(delim) + 1); + for (uint256 i = 0; i < parts.length; i++) { + parts[i] = s.split(delim).toString(); + } + + // Get the system time with our script + string[] memory time = new string[](1); + time[0] = "./lib/foundry-huff/scripts/rand_bytes.sh"; + bytes memory retData = vm.ffi(time); + string memory rand_bytes = bytes32ToString(keccak256(abi.encode(bytes32(retData)))); + + // Re-concatenate the file with a "__TEMP__" prefix + string memory tempFile = parts[0]; + if (parts.length <= 1) { + tempFile = string.concat("__TEMP__", rand_bytes, tempFile); + } else { + for (uint256 i = 1; i < parts.length - 1; i++) { + tempFile = string.concat(tempFile, "/", parts[i]); + } + tempFile = string.concat(tempFile, "/", "__TEMP__", rand_bytes, parts[parts.length - 1]); + } + + // Paste the code in a new temp file + string[] memory create_cmds = new string[](3); + // TODO: create_cmds[0] = "$(find . -name \"file_writer.sh\")"; + create_cmds[0] = "./lib/foundry-huff/scripts/file_writer.sh"; + create_cmds[1] = string.concat("src/", tempFile, ".huff"); + create_cmds[2] = string.concat(code, "\n"); + vm.ffi(create_cmds); + + // Append the real code to the temp file + string[] memory append_cmds = new string[](3); + append_cmds[0] = "./lib/foundry-huff/scripts/read_and_append.sh"; + append_cmds[1] = string.concat("src/", tempFile, ".huff"); + append_cmds[2] = string.concat("src/", file, ".huff"); + vm.ffi(append_cmds); + + /// Create a list of strings with the commands necessary to compile Huff contracts + string[] memory cmds = new string[](5); + if (const_overrides.length > 0) { + cmds = new string[](6 + const_overrides.length); + cmds[5] = "-c"; + + Constant memory cur_const; + for (uint256 i; i < const_overrides.length; i++) { + cur_const = const_overrides[i]; + cmds[6 + i] = string.concat(cur_const.key, "=", cur_const.value); + } + } + + cmds[0] = "huffc"; + cmds[1] = string(string.concat("src/", tempFile, ".huff")); + cmds[2] = "-b"; + cmds[3] = "-e"; + cmds[4] = get_evm_version(); + + /// @notice compile the Huff contract and return the bytecode + bytecode = vm.ffi(cmds); + + // Clean up temp files + string[] memory cleanup = new string[](2); + cleanup[0] = "rm"; + cleanup[1] = string.concat("src/", tempFile, ".huff"); + + // set `msg.sender` for upcoming create context + vm.prank(deployer); + + + vm.ffi(cleanup); + } + + /// @notice get creation code of a contract plus encoded arguments + function creation_code_with_args(string memory file) public payable returns (bytes memory bytecode) { + bytecode = creation_code(file); + return bytes.concat(bytecode, args); + } + + /// @notice Deploy the Contract + function deploy(string memory file) public payable returns (address) { + bytes memory concatenated = creation_code_with_args(file); + + /// @notice deploy the bytecode with the create instruction + address deployedAddress; + if (should_broadcast) vm.broadcast(); + assembly { + let val := sload(value.slot) + deployedAddress := create(val, add(concatenated, 0x20), mload(concatenated)) + } + + /// @notice check that the deployment was successful + require(deployedAddress != address(0), "HuffDeployer could not deploy contract"); + + /// @notice return the address that the contract was deployed to + return deployedAddress; + } +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/src/HuffDeployer.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/src/HuffDeployer.sol new file mode 100644 index 0000000000..1608e524e2 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/src/HuffDeployer.sol @@ -0,0 +1,134 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.8.13 <0.9.0; + +import {Vm} from "forge-std/Vm.sol"; +import {HuffConfig} from "./HuffConfig.sol"; + +library HuffDeployer { + /// @notice Create a new huff config + function config() public returns (HuffConfig) { + return new HuffConfig(); + } + + // @notice Deterministically create a new huff config using create2 and a salt + function config_with_create_2(uint256 salt) public returns (HuffConfig) { + return new HuffConfig{salt: bytes32(salt)}(); + } + + // @notice Get the address of a HuffConfig deployed with config_with_create_2 + function get_config_with_create_2(uint256 salt) public view returns (address) { + return + address( + uint160( + uint256( + keccak256( + abi.encodePacked( + bytes1(0xff), address(this), bytes32(salt), keccak256(type(HuffConfig).creationCode) + ) + ) + ) + ) + ); + } + + /// @notice Compiles a Huff contract and returns the address that the contract was deployeod to + /// @param fileName - The file name of the Huff contract. For example, the file name for "SimpleStore.huff" is "SimpleStore" + /// @return The address that the contract was deployed to + function deploy(string memory fileName) internal returns (address) { + return config().deploy(fileName); + } + + /// @notice Compiles a Huff contract and returns the address that the contract was deployeod to + /// @param fileName - The file name of the Huff contract. For example, the file name for "SimpleStore.huff" is "SimpleStore" + /// @return The address that the contract was deployed to + function broadcast(string memory fileName) internal returns (address) { + return config().set_broadcast(true).deploy(fileName); + } + + /// @notice Compiles a Huff contract and returns the address that the contract was deployeod to + /// @param fileName - The file name of the Huff contract. For example, the file name for "SimpleStore.huff" is "SimpleStore" + /// @param value - Value to deploy with + /// @return The address that the contract was deployed to + function deploy_with_value(string memory fileName, uint256 value) internal returns (address) { + return config().with_value(value).deploy(fileName); + } + + /// @notice Compiles a Huff contract and returns the address that the contract was deployeod to + /// @param fileName - The file name of the Huff contract. For example, the file name for "SimpleStore.huff" is "SimpleStore" + /// @param value - Value to deploy with + /// @return The address that the contract was deployed to + function broadcast_with_value(string memory fileName, uint256 value) + internal + returns (address) + { + return config().set_broadcast(true).with_value(value).deploy(fileName); + } + + /// @notice Compiles a Huff contract and returns the address that the contract was deployeod to + /// @param fileName - The file name of the Huff contract. For example, the file name for "SimpleStore.huff" is "SimpleStore" + /// @param args - Constructor Args to append to the bytecode + /// @return The address that the contract was deployed to + function deploy_with_args(string memory fileName, bytes memory args) + internal + returns (address) + { + return config().with_args(args).deploy(fileName); + } + + /// @notice Compiles a Huff contract and returns the address that the contract was deployeod to + /// @param fileName - The file name of the Huff contract. For example, the file name for "SimpleStore.huff" is "SimpleStore" + /// @param args - Constructor Args to append to the bytecode + /// @return The address that the contract was deployed to + function broadcast_with_args(string memory fileName, bytes memory args) + internal + returns (address) + { + return config().set_broadcast(true).with_args(args).deploy(fileName); + } + + /// @notice Compiles a Huff contract and returns the address that the contract was deployeod to + /// @param fileName - The file name of the Huff contract. For example, the file name for "SimpleStore.huff" is "SimpleStore" + /// @param code - Code to append to the file source code (e.g. a constructor macro to make the contract instantiable) + /// @return The address that the contract was deployed to + function deploy_with_code(string memory fileName, string memory code) + internal + returns (address) + { + return config().with_code(code).deploy(fileName); + } + + /// @notice Compiles a Huff contract and returns the address that the contract was deployeod to + /// @param fileName - The file name of the Huff contract. For example, the file name for "SimpleStore.huff" is "SimpleStore" + /// @param code - Code to append to the file source code (e.g. a constructor macro to make the contract instantiable) + /// @return The address that the contract was deployed to + function broadcast_with_code(string memory fileName, string memory code) + internal + returns (address) + { + return config().set_broadcast(true).with_code(code).deploy(fileName); + } + + /// @notice Compiles a Huff contract and returns the address that the contract was deployeod to + /// @param fileName - The file name of the Huff contract. For example, the file name for "SimpleStore.huff" is "SimpleStore" + /// @param code - Code to append to the file source code (e.g. a constructor macro to make the contract instantiable) + /// @param args - Constructor Args to append to the bytecode + /// @return The address that the contract was deployed to + function deploy_with_code_args(string memory fileName, string memory code, bytes memory args) + internal + returns (address) + { + return config().with_code(code).with_args(args).deploy(fileName); + } + + /// @notice Compiles a Huff contract and returns the address that the contract was deployeod to + /// @param fileName - The file name of the Huff contract. For example, the file name for "SimpleStore.huff" is "SimpleStore" + /// @param code - Code to append to the file source code (e.g. a constructor macro to make the contract instantiable) + /// @param args - Constructor Args to append to the bytecode + /// @return The address that the contract was deployed to + function broadcast_with_code_args(string memory fileName, string memory code, bytes memory args) + internal + returns (address) + { + return config().set_broadcast(true).with_code(code).with_args(args).deploy(fileName); + } +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/src/depreciated/StatefulDeployer.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/src/depreciated/StatefulDeployer.sol new file mode 100644 index 0000000000..b67b98e5d4 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/src/depreciated/StatefulDeployer.sol @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.8.13 <0.9.0; + +import {Vm} from "forge-std/Vm.sol"; +import {strings} from "stringutils/strings.sol"; +import {HuffDeployer} from "../HuffDeployer.sol"; + +contract StatefulDeployer { + using strings for *; + + /// @notice Initializes cheat codes in order to use ffi to compile Huff contracts + Vm public constant vm = Vm(address(bytes20(uint160(uint256(keccak256("hevm cheat code")))))); + + /// @notice additional code to append to the source file + string public code; + + /// @notice arguments to append to the bytecode + bytes public args; + + /// @notice sets the code to be appended to the source file + function setCode(string memory acode) public { + code = acode; + } + + /// @notice sets the arguments to be appended to the bytecode + function setArgs(bytes memory aargs) public { + args = aargs; + } + + /// @notice Deployment wrapper + function deploy(string memory file) public returns (address) { + // Split the file into it's parts + strings.slice memory s = file.toSlice(); + strings.slice memory delim = "/".toSlice(); + string[] memory parts = new string[](s.count(delim) + 1); + for (uint256 i = 0; i < parts.length; i++) { + parts[i] = s.split(delim).toString(); + } + + // Re-concatenate the file with a "__TEMP__" prefix + string memory tempFile = parts[0]; + for (uint256 i = 1; i < parts.length - 1; i++) { + tempFile = string.concat(tempFile, "/", parts[i]); + } + tempFile = string.concat(tempFile, "/", "__TEMP__", parts[parts.length - 1]); + + // Paste the code in a new temp file + string[] memory create_cmds = new string[](3); + create_cmds[0] = "./scripts/file_writer.sh"; + create_cmds[1] = string.concat("src/", tempFile, ".huff"); + create_cmds[2] = string.concat(code, "\n"); + vm.ffi(create_cmds); + + // Append the real code to the temp file + string[] memory append_cmds = new string[](3); + append_cmds[0] = "./scripts/read_and_append.sh"; + append_cmds[1] = string.concat("src/", tempFile, ".huff"); + append_cmds[2] = string.concat("src/", file, ".huff"); + vm.ffi(append_cmds); + + // Deploy with args the temp file + address deployed = HuffDeployer.deploy_with_args(tempFile, args); + + // Clean up temp files + string[] memory cleanup = new string[](2); + cleanup[0] = "rm"; + cleanup[1] = string.concat("src/", tempFile, ".huff"); + vm.ffi(cleanup); + + // Return the deployed address + return deployed; + } +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/src/depreciated/StatefulDeployer.t.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/src/depreciated/StatefulDeployer.t.sol new file mode 100644 index 0000000000..4773965524 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/src/depreciated/StatefulDeployer.t.sol @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.7.0 <0.9.0; + +import "forge-std/Test.sol"; + +import {INumber} from "../test/interfaces/INumber.sol"; +import {IConstructor} from "../test/interfaces/IConstructor.sol"; +import {StatefulDeployer} from "./StatefulDeployer.sol"; + +contract StatefulDeployerTest is Test { + StatefulDeployer public deployer; + IConstructor public construct; + + function setUp() public { + deployer = new StatefulDeployer(); + } + + function testSetArgs(bytes memory some) public { + deployer.setArgs(some); + assertEq(deployer.args(), some); + } + + function testSetCode(string memory code) public { + deployer.setCode(code); + assertEq(deployer.code(), code); + } + + function testDeployWithArgsAndCode() public { + deployer.setArgs(bytes.concat(abi.encode(uint256(0x420)), abi.encode(uint256(0x420)))); + deployer.setCode( + "" "#define macro CONSTRUCTOR() = takes(0) returns (0) { \n" + " // Copy the first argument into memory \n" + " 0x20 // [size] - byte size to copy \n" + " 0x40 codesize sub // [offset, size] - offset in the code to copy from \n" + " 0x00 // [mem, offset, size] - offset in memory to copy to \n" + " codecopy // [] \n" + " // Store the first argument in storage \n" + " 0x00 mload // [arg] \n" + " [CONSTRUCTOR_ARG_ONE] // [CONSTRUCTOR_ARG_ONE, arg] \n" + " sstore // [] \n" + " // Copy the second argument into memory \n" + " 0x20 // [size] - byte size to copy \n" + " 0x20 codesize sub // [offset, size] - offset in the code to copy from \n" + " 0x00 // [mem, offset, size] - offset in memory to copy to \n" + " codecopy // [] \n" + " // Store the second argument in storage \n" + " 0x00 mload // [arg] \n" + " [CONSTRUCTOR_ARG_TWO] // [CONSTRUCTOR_ARG_TWO, arg] \n" + " sstore // [] \n" "}" + ); + + construct = IConstructor(deployer.deploy("test/contracts/NoConstructor")); + assertEq(address(0x420), construct.getArgOne()); + assertEq(uint256(0x420), construct.getArgTwo()); + } +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/HuffConfig.t.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/HuffConfig.t.sol new file mode 100644 index 0000000000..03fdb7bebd --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/HuffConfig.t.sol @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.7.0 <0.9.0; + +import "forge-std/Test.sol"; + +import {INumber} from "./interfaces/INumber.sol"; +import {IConstructor} from "./interfaces/IConstructor.sol"; +import {HuffConfig} from "../HuffConfig.sol"; + +contract HuffConfigTest is Test { + HuffConfig public config; + INumber public number; + + function setUp() public { + config = new HuffConfig(); + } + + function testWithDeployer(address deployer) public { + config.with_deployer(deployer); + assertEq(config.deployer(), deployer); + } + + function testWithArgs(bytes memory some) public { + config.with_args(some); + assertEq(config.args(), some); + } + + function testWithValue(uint256 value) public { + config.with_value(value); + assertEq(config.value(), value); + } + + function testWithCode(string memory code) public { + config.with_code(code); + assertEq(config.code(), code); + } + + function testWithConstantOverrides(string memory key, string memory value) public { + config.with_constant(key, value); + (string memory k, string memory v) = config.const_overrides(0); + assertEq(key, k); + assertEq(value, v); + } + + function testSetBroadcast(bool broadcast) public { + config.set_broadcast(broadcast); + bool b = config.should_broadcast(); + assertEq(b, broadcast); + } + + function testWithEvmVersion() public { + config.with_evm_version("paris"); + assertEq(config.evm_version(), "paris"); + } +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/HuffDeployer.t.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/HuffDeployer.t.sol new file mode 100644 index 0000000000..c0496de141 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/HuffDeployer.t.sol @@ -0,0 +1,276 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.7.0 <0.9.0; + +import "forge-std/Test.sol"; + +import {HuffConfig} from "../HuffConfig.sol"; +import {HuffDeployer} from "../HuffDeployer.sol"; +import {INumber} from "./interfaces/INumber.sol"; +import {IConstructor} from "./interfaces/IConstructor.sol"; +import {IRememberCreator} from "./interfaces/IRememberCreator.sol"; + +contract HuffDeployerTest is Test { + INumber number; + IConstructor structor; + + event ArgumentsUpdated(address indexed one, uint256 indexed two); + + function setUp() public { + number = INumber(HuffDeployer.deploy("test/contracts/Number")); + + // Backwards-compatible Constructor creation + vm.recordLogs(); + structor = IConstructor( + HuffDeployer.deploy_with_args( + "test/contracts/Constructor", + bytes.concat(abi.encode(address(0x420)), abi.encode(uint256(0x420))) + ) + ); + Vm.Log[] memory entries = vm.getRecordedLogs(); + + assertEq(entries.length, 1); + assertEq(entries[0].topics.length, 3); + assertEq(entries[0].topics[0], bytes32(uint256(keccak256("ArgumentsUpdated(address,uint256)")))); + assertEq(entries[0].topics[1], bytes32(uint256(uint160(address(0x420))))); + assertEq(entries[0].topics[2], bytes32(uint256(0x420))); + + } + + function testChaining() public { + // Defined Constructor + string memory constructor_macro = "#define macro CONSTRUCTOR() = takes(0) returns (0) {" + " // Copy the first argument into memory \n" + " 0x20 // [size] - byte size to copy \n" + " 0x40 codesize sub // [offset, size] - offset in the code to copy from\n " + " 0x00 // [mem, offset, size] - offset in memory to copy to \n" + " codecopy // [] \n" + " // Store the first argument in storage\n" + " 0x00 mload dup1 // [arg1, arg1] \n" + " [CONSTRUCTOR_ARG_ONE] // [CONSTRUCTOR_ARG_ONE, arg1, arg1] \n" + " sstore // [arg1] \n" + " // Copy the second argument into memory \n" + " 0x20 // [size, arg1] - byte size to copy \n" + " 0x20 codesize sub // [offset, size, arg1] - offset in the code to copy from \n" + " 0x00 // [mem, offset, size, arg1] - offset in memory to copy to \n" + " codecopy // [arg1] \n" + " // Store the second argument in storage \n" + " 0x00 mload dup1 // [arg2, arg2, arg1] \n" + " [CONSTRUCTOR_ARG_TWO] // [CONSTRUCTOR_ARG_TWO, arg2, arg2, arg1] \n" + " sstore // [arg2, arg1] \n" + " // Emit the owner updated event \n" + " swap1 // [arg1, arg2] \n" + " [ARGUMENTS_TOPIC] // [sig, arg1, arg2] \n" + " 0x00 0x00 // [0, 0, sig, arg1, arg2] \n" + " log3 // [] \n" "}"; + + // New pattern + vm.recordLogs(); + IConstructor chained = IConstructor( + HuffDeployer.config().with_args( + bytes.concat(abi.encode(address(0x420)), abi.encode(uint256(0x420))) + ).with_code(constructor_macro).deploy("test/contracts/NoConstructor") + ); + + Vm.Log[] memory entries = vm.getRecordedLogs(); + assertEq(entries.length, 1); + assertEq(entries[0].topics.length, 3); + assertEq(entries[0].topics[0], bytes32(uint256(keccak256("ArgumentsUpdated(address,uint256)")))); + assertEq(entries[0].topics[1], bytes32(uint256(uint160(address(0x420))))); + assertEq(entries[0].topics[2], bytes32(uint256(0x420))); + + assertEq(address(0x420), chained.getArgOne()); + assertEq(uint256(0x420), chained.getArgTwo()); + } + + function testChaining_Create2() public { + // Defined Constructor + string memory constructor_macro = "#define macro CONSTRUCTOR() = takes(0) returns (0) {" + " // Copy the first argument into memory \n" + " 0x20 // [size] - byte size to copy \n" + " 0x40 codesize sub // [offset, size] - offset in the code to copy from\n " + " 0x00 // [mem, offset, size] - offset in memory to copy to \n" + " codecopy // [] \n" " // Store the first argument in storage\n" + " 0x00 mload dup1 // [arg1, arg1] \n" + " [CONSTRUCTOR_ARG_ONE] // [CONSTRUCTOR_ARG_ONE, arg1, arg1] \n" + " sstore // [arg1] \n" " // Copy the second argument into memory \n" + " 0x20 // [size, arg1] - byte size to copy \n" + " 0x20 codesize sub // [offset, size, arg1] - offset in the code to copy from \n" + " 0x00 // [mem, offset, size, arg1] - offset in memory to copy to \n" + " codecopy // [arg1] \n" " // Store the second argument in storage \n" + " 0x00 mload dup1 // [arg2, arg2, arg1] \n" + " [CONSTRUCTOR_ARG_TWO] // [CONSTRUCTOR_ARG_TWO, arg2, arg2, arg1] \n" + " sstore // [arg2, arg1] \n" " // Emit the owner updated event \n" + " swap1 // [arg1, arg2] \n" + " [ARGUMENTS_TOPIC] // [sig, arg1, arg2] \n" + " 0x00 0x00 // [0, 0, sig, arg1, arg2] \n" + " log3 // [] \n" "}"; + + // New pattern + vm.recordLogs(); + IConstructor chained = IConstructor( + HuffDeployer.config_with_create_2(1).with_args(bytes.concat(abi.encode(address(0x420)), abi.encode(uint256(0x420)))) + .with_code(constructor_macro).deploy("test/contracts/NoConstructor") + ); + + Vm.Log[] memory entries = vm.getRecordedLogs(); + assertEq(entries.length, 1); + assertEq(entries[0].topics.length, 3); + assertEq(entries[0].topics[0], bytes32(uint256(keccak256("ArgumentsUpdated(address,uint256)")))); + assertEq(entries[0].topics[1], bytes32(uint256(uint160(address(0x420))))); + assertEq(entries[0].topics[2], bytes32(uint256(0x420))); + + assertEq(address(0x420), chained.getArgOne()); + assertEq(uint256(0x420), chained.getArgTwo()); + } + + function testArgOne() public { + assertEq(address(0x420), structor.getArgOne()); + } + + function testArgTwo() public { + assertEq(uint256(0x420), structor.getArgTwo()); + } + + function testBytecode() public { + bytes memory b = bytes( + hex"5f3560e01c80633fb5c1cb1461001b578063f2c9ecd814610021575b6004355f555b5f545f5260205ff3" + ); + assertEq(getCode(address(number)), b); + } + + function testWithValueDeployment() public { + uint256 value = 1 ether; + HuffDeployer.config().with_value(value).deploy{value: value}( + "test/contracts/ConstructorNeedsValue" + ); + } + + function testWithValueDeployment_Create2() public { + uint256 value = 1 ether; + HuffDeployer.config_with_create_2(1).with_value(value).deploy{value: value}("test/contracts/ConstructorNeedsValue"); + } + + function testConstantOverride() public { + // Test address constant + address a = 0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF; + address deployed = HuffDeployer.config().with_addr_constant("a", a).with_constant( + "b", "0x420" + ).deploy("test/contracts/ConstOverride"); + assertEq(getCode(deployed), hex"73DeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF610420"); + + // Test uint constant + address deployed_2 = HuffDeployer.config().with_uint_constant("a", 32).with_constant( + "b", "0x420" + ).deploy("test/contracts/ConstOverride"); + assertEq(getCode(deployed_2), hex"6020610420"); + + // Test bytes32 constant + address deployed_3 = HuffDeployer.config().with_bytes32_constant("a", bytes32(hex"01")) + .with_constant("b", "0x420").deploy("test/contracts/ConstOverride"); + assertEq( + getCode(deployed_3), + hex"7f0100000000000000000000000000000000000000000000000000000000000000610420" + ); + + // Keep default "a" value and assign "b", which is unassigned in "ConstOverride.huff" + address deployed_4 = + HuffDeployer.config().with_constant("b", "0x420").deploy("test/contracts/ConstOverride"); + assertEq(getCode(deployed_4), hex"6001610420"); + } + + function testConstantOverride_Create2() public { + // Test address constant + address a = 0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF; + address deployed = HuffDeployer.config_with_create_2(1).with_addr_constant("a", a).with_constant("b", "0x420").deploy( + "test/contracts/ConstOverride" + ); + assertEq(getCode(deployed), hex"73DeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF610420"); + + // Test uint constant + address deployed_2 = HuffDeployer.config_with_create_2(2).with_uint_constant("a", 32).with_constant("b", "0x420").deploy( + "test/contracts/ConstOverride" + ); + assertEq(getCode(deployed_2), hex"6020610420"); + + // Test bytes32 constant + address deployed_3 = HuffDeployer.config_with_create_2(3).with_bytes32_constant("a", bytes32(hex"01")).with_constant( + "b", "0x420" + ).deploy("test/contracts/ConstOverride"); + assertEq(getCode(deployed_3), hex"7f0100000000000000000000000000000000000000000000000000000000000000610420"); + + // Keep default "a" value and assign "b", which is unassigned in "ConstOverride.huff" + address deployed_4 = HuffDeployer.config_with_create_2(4).with_constant("b", "0x420").deploy("test/contracts/ConstOverride"); + assertEq(getCode(deployed_4), hex"6001610420"); + } + + function getCode(address who) internal view returns (bytes memory o_code) { + /// @solidity memory-safe-assembly + assembly { + // retrieve the size of the code, this needs assembly + let size := extcodesize(who) + // allocate output byte array - this could also be done without assembly + // by using o_code = new bytes(size) + o_code := mload(0x40) + // new "memory end" including padding + mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), not(0x1f)))) + // store length in memory + mstore(o_code, size) + // actually retrieve the code, this needs assembly + extcodecopy(who, add(o_code, 0x20), 0, size) + } + } + + function testSet(uint256 num) public { + number.setNumber(num); + assertEq(num, number.getNumber()); + } + + function testConstructorDefaultCaller() public { + HuffConfig config = HuffDeployer.config(); + IRememberCreator rememberer = IRememberCreator(config.deploy("test/contracts/RememberCreator")); + assertEq(rememberer.CREATOR(), address(config)); + } + + function runTestConstructorCaller(address deployer) public { + IRememberCreator rememberer = IRememberCreator( + HuffDeployer + .config() + .with_deployer(deployer) + .deploy("test/contracts/RememberCreator") + ); + assertEq(rememberer.CREATOR(), deployer); + } + + // @dev fuzzed test too slow, random examples and address(0) chosen + function testConstructorCaller() public { + runTestConstructorCaller(address(uint160(uint256(keccak256("random addr 1"))))); + runTestConstructorCaller(address(uint160(uint256(keccak256("random addr 2"))))); + runTestConstructorCaller(address(0)); + runTestConstructorCaller(address(uint160(0x1000))); + } + + /// @dev test that compilation is different with new evm versions + function testSettingEVMVersion() public { + /// expected bytecode for EVM version "paris" + bytes memory expectedParis = hex"6000"; + HuffConfig config = HuffDeployer.config().with_evm_version("paris"); + address withParis = config.deploy("test/contracts/EVMVersionCheck"); + + bytes memory parisBytecode = withParis.code; + assertEq(parisBytecode, expectedParis); + + /// expected bytecode for EVM version "shanghai" | default + bytes memory expectedShanghai = hex"5f"; + HuffConfig shanghaiConfig = HuffDeployer.config().with_evm_version("shanghai"); + address withShanghai = shanghaiConfig.deploy("test/contracts/EVMVersionCheck"); + bytes memory shanghaiBytecode = withShanghai.code; + assertEq(shanghaiBytecode, expectedShanghai); + + /// Default should be shanghai (latest) + HuffConfig defaultConfig = HuffDeployer.config().with_evm_version(""); + address withDefault = defaultConfig.deploy("test/contracts/EVMVersionCheck"); + + bytes memory defaultBytecode = withDefault.code; + assertEq(defaultBytecode, expectedShanghai); + } +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/Logging.t.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/Logging.t.sol new file mode 100644 index 0000000000..829cc0511b --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/Logging.t.sol @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.7.0 <0.9.0; + +import "forge-std/Test.sol"; + +import {HuffConfig} from "../HuffConfig.sol"; +import {HuffDeployer} from "../HuffDeployer.sol"; +import {INumber} from "./interfaces/INumber.sol"; +import {IConstructor} from "./interfaces/IConstructor.sol"; + +contract LoggingTest is Test { + event LogOne(); + event LogTwo(address indexed a); + event LogThree(address indexed a, uint256 indexed b); + event LogFour(address indexed a, uint256 indexed b, bytes32 indexed c); + event Extended( + address indexed a, uint256 indexed b, bytes32 indexed h1, bytes32 h2, bytes32 two + ); + + function testLoggingWithArgs() public { + vm.recordLogs(); + HuffDeployer.deploy_with_args( + "test/contracts/LotsOfLogging", + bytes.concat(abi.encode(address(0x420)), abi.encode(uint256(0x420))) + ); + Vm.Log[] memory entries = vm.getRecordedLogs(); + + assertEq(entries.length, 5); + assertEq(entries[0].topics.length, 1); + assertEq(entries[0].topics[0], bytes32(uint256(keccak256("LogOne()")))); + assertEq(entries[1].topics.length, 2); + assertEq(entries[1].topics[0], bytes32(uint256(keccak256("LogTwo(address)")))); + // assertEq(entries[1].topics[1], ?); should be address from deployed config + assertEq(entries[2].topics.length, 3); + assertEq(entries[2].topics[0], bytes32(uint256(keccak256("LogThree(address,uint256)")))); + // assertEq(entries[2].topics[1], ?); should be address from deployed config + assertEq(entries[2].topics[2], bytes32(uint256(0x0))); + assertEq(entries[3].topics.length, 4); + assertEq(entries[3].topics[0], bytes32(uint256(keccak256("LogFour(address,uint256,bytes32)")))); + // assertEq(entries[3].topics[1], ?); should be address from deployed config + assertEq(entries[3].topics[2], bytes32(uint256(0x0))); + assertEq(entries[3].topics[3], bytes32(uint256(keccak256(abi.encode(1))))); + assertEq(entries[4].topics.length, 4); + assertEq(entries[4].topics[0], bytes32(uint256(keccak256("Extended(address,uint256,bytes32,bytes32,bytes32)")))); + // assertEq(entries[4].topics[1], ?); should be address from deployed config + assertEq(entries[4].topics[2], bytes32(uint256(0x0))); + assertEq(entries[4].topics[3], bytes32(uint256(keccak256(abi.encode(1))))); + assertEq(entries[4].data, abi.encode(keccak256(abi.encode(2)), keccak256(abi.encode(3)))); + } + + function testLoggingWithDeploy() public { + vm.expectEmit(false, true, true, true); + emit LogOne(); + emit LogTwo(address(0)); + emit LogThree(address(0), 0); + emit LogFour(address(0), 0, keccak256(abi.encode(1))); + emit Extended( + address(0), + 0, + keccak256(abi.encode(1)), + keccak256(abi.encode(2)), + keccak256(abi.encode(3)) + ); + HuffDeployer.deploy("test/contracts/LotsOfLogging"); + } + + function testConfigLogging() public { + HuffConfig config = HuffDeployer.config().with_args(abi.encode(address(0x420))); + vm.expectEmit(true, true, true, true); + emit LogOne(); + emit LogTwo(address(config)); + emit LogThree(address(config), 0); + emit LogFour(address(config), 0, keccak256(abi.encode(1))); + emit Extended( + address(config), + 0, + keccak256(abi.encode(1)), + keccak256(abi.encode(2)), + keccak256(abi.encode(3)) + ); + config.deploy("test/contracts/LotsOfLogging"); + } +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/contracts/ConstOverride.huff b/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/contracts/ConstOverride.huff new file mode 100644 index 0000000000..ce80a69fe2 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/contracts/ConstOverride.huff @@ -0,0 +1,6 @@ +#define constant a = 0x01 + +#define macro MAIN() = takes (0) returns (0) { + [a] + [b] +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/contracts/Constructor.huff b/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/contracts/Constructor.huff new file mode 100644 index 0000000000..ce3a0bc6d5 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/contracts/Constructor.huff @@ -0,0 +1,69 @@ +/* Interface */ +#define function getArgOne() view returns (address) +#define function getArgTwo() view returns (uint256) + +/* Storage Slots */ +#define constant CONSTRUCTOR_ARG_ONE = FREE_STORAGE_POINTER() +#define constant CONSTRUCTOR_ARG_TWO = FREE_STORAGE_POINTER() + +/* Events */ +#define event ArgumentsUpdated(address indexed one, uint256 indexed two) + +#define constant ARGUMENTS_TOPIC = 0xd0a6a6b9636b3b1e85120bfc8c36f7bc862769b48e0854deaf8780636a71ce7d + +/* Constructor */ +#define macro CONSTRUCTOR() = takes(0) returns (0) { + // Copy the first argument into memory + 0x20 // [size] - byte size to copy + 0x40 codesize sub // [offset, size] - offset in the code to copy from + 0x00 // [mem, offset, size] - offset in memory to copy to + codecopy // [] + + // Store the first argument in storage + 0x00 mload dup1 // [arg1, arg1] + [CONSTRUCTOR_ARG_ONE] // [CONSTRUCTOR_ARG_ONE, arg1, arg1] + sstore // [arg1] + + // Copy the second argument into memory + 0x20 // [size, arg1] - byte size to copy + 0x20 codesize sub // [offset, size, arg1] - offset in the code to copy from + 0x00 // [mem, offset, size, arg1] - offset in memory to copy to + codecopy // [arg1] + + // Store the second argument in storage + 0x00 mload dup1 // [arg2, arg2, arg1] + [CONSTRUCTOR_ARG_TWO] // [CONSTRUCTOR_ARG_TWO, arg2, arg2, arg1] + sstore // [arg2, arg1] + + // Emit the owner updated event + swap1 // [arg1, arg2] + [ARGUMENTS_TOPIC] // [sig, arg1, arg2] + 0x00 0x00 // [0, 0, sig, arg1, arg2] + log3 // [] +} + +/* First Argument Accessor */ +#define macro GET_ARG_ONE() = takes (0) returns (0) { + [CONSTRUCTOR_ARG_ONE] sload + 0x00 mstore + 0x20 0x00 return +} + +/* Second Argument Accessor */ +#define macro GET_ARG_TWO() = takes (0) returns (0) { + [CONSTRUCTOR_ARG_TWO] sload + 0x00 mstore + 0x20 0x00 return +} + +/* Main Macro */ +#define macro MAIN() = takes (0) returns (0) { + 0x00 calldataload 0xE0 shr + dup1 0xbb01e52d eq arg_one jumpi + dup1 0x98e45be4 eq arg_two jumpi + + arg_one: + GET_ARG_ONE() + arg_two: + GET_ARG_TWO() +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/contracts/ConstructorNeedsValue.huff b/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/contracts/ConstructorNeedsValue.huff new file mode 100644 index 0000000000..27da3e78b7 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/contracts/ConstructorNeedsValue.huff @@ -0,0 +1,16 @@ + +#define macro CONSTRUCTOR() = takes (0) returns (0) { + callvalue // [msg.value] + iszero // [is_msg_value_zero] + iszero // [is_msg_value_non_zero] + deposited // [deposited_jumpdest, is_msg_value_non_zero] + jumpi // [] + 0x00 0x00 revert + deposited: +} + +#define macro MAIN() = takes (0) returns (0) { + 0x00 calldataload 0xE0 shr + 0x00 mstore + 0x20 0x00 return +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/contracts/EVMVersionCheck.huff b/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/contracts/EVMVersionCheck.huff new file mode 100644 index 0000000000..960917a32a --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/contracts/EVMVersionCheck.huff @@ -0,0 +1,5 @@ + + +#define macro MAIN() = { + 0x00 +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/contracts/LotsOfLogging.huff b/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/contracts/LotsOfLogging.huff new file mode 100644 index 0000000000..f2bfe6cbd6 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/contracts/LotsOfLogging.huff @@ -0,0 +1,56 @@ +/* Events */ +#define event LogOne() +#define event LogTwo(address indexed a) +#define event LogThree(address indexed a, uint256 indexed b) +#define event LogFour(address indexed a, uint256 indexed b, bytes32 indexed c) +#define event Extended(address indexed a, uint256 indexed b, bytes32 indexed h1, bytes32 h2, bytes32 two) + +/* Constructor */ +#define macro CONSTRUCTOR() = takes(0) returns (0) { + // Empty Anonymous Log + // 0x00 0x00 log0 + + // LogOne + __EVENT_HASH(LogOne) // [hash] + 0x00 0x00 log1 // [] + + // LogTwo + caller // [address] + __EVENT_HASH(LogTwo) // [hash, address] + 0x00 0x00 log2 // [] + + // LogThree + selfbalance // [balance] + caller // [address, balance] + __EVENT_HASH(LogThree) // [hash, address, balance] + 0x00 0x00 log3 // [] + + // LogFour + 0x01 0x00 mstore // [] + 0x20 0x00 sha3 // [bytes32_hash] + selfbalance // [balance, bytes32_hash] + caller // [address, balance, bytes32_hash] + __EVENT_HASH(LogFour) // [hash, address, balance, bytes32_hash] + 0x00 0x00 log4 // [] + + // Evented Log + 0x01 0x00 mstore // [] + 0x20 0x00 sha3 // [hash1] + 0x02 0x00 mstore // [hash1] + 0x20 0x00 sha3 // [hash2, hash1] + 0x00 mstore // [hash1] + 0x03 0x20 mstore // [hash1] + 0x20 0x20 sha3 // [two, hash1] + 0x20 mstore // [hash1] + selfbalance // [balance, hash1] + caller // [address, balance, hash1] + __EVENT_HASH(Extended) // [hash, address, balance, hash1] + 0x40 0x00 log4 // [] +} + +/* Main Macro - Does Nothing */ +#define macro MAIN() = takes (0) returns (0) { + 0x00 calldataload 0xE0 shr + 0x00 mstore + 0x20 0x00 return +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/contracts/NoConstructor.huff b/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/contracts/NoConstructor.huff new file mode 100644 index 0000000000..4bf49c8ba5 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/contracts/NoConstructor.huff @@ -0,0 +1,38 @@ +/* Interface */ +#define function getArgOne() view returns (address) +#define function getArgTwo() view returns (uint256) + +/* Storage Slots */ +#define constant CONSTRUCTOR_ARG_ONE = FREE_STORAGE_POINTER() +#define constant CONSTRUCTOR_ARG_TWO = FREE_STORAGE_POINTER() + +/* Events */ +#define event ArgumentsUpdated(address indexed one, uint256 indexed two) + +#define constant ARGUMENTS_TOPIC = 0xd0a6a6b9636b3b1e85120bfc8c36f7bc862769b48e0854deaf8780636a71ce7d + +/* First Argument Accessor */ +#define macro GET_ARG_ONE() = takes (0) returns (0) { + [CONSTRUCTOR_ARG_ONE] sload + 0x00 mstore + 0x20 0x00 return +} + +/* Second Argument Accessor */ +#define macro GET_ARG_TWO() = takes (0) returns (0) { + [CONSTRUCTOR_ARG_TWO] sload + 0x00 mstore + 0x20 0x00 return +} + +/* Main Macro */ +#define macro MAIN() = takes (0) returns (0) { + 0x00 calldataload 0xE0 shr + dup1 0xbb01e52d eq arg_one jumpi + dup1 0x98e45be4 eq arg_two jumpi + + arg_one: + GET_ARG_ONE() + arg_two: + GET_ARG_TWO() +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/contracts/Number.huff b/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/contracts/Number.huff new file mode 100644 index 0000000000..d6813e4b18 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/contracts/Number.huff @@ -0,0 +1,38 @@ +/* Interface */ +#define function setNumber(uint256) nonpayable returns () +#define function getNumber() view returns (uint256) + +/* Storage Slots */ +#define constant NUMBER_LOCATION = FREE_STORAGE_POINTER() + +/* Methods */ +#define macro SET_NUMBER() = takes (0) returns (0) { + 0x04 calldataload // [number] + [NUMBER_LOCATION] // [ptr, number] + sstore // [] +} + +#define macro GET_NUMBER() = takes (0) returns (0) { + // Load number from storage. + [NUMBER_LOCATION] // [ptr] + sload // [number] + + // Store number in memory. + 0x00 mstore + + // Return number + 0x20 0x00 return +} + +#define macro MAIN() = takes (0) returns (0) { + // Identify which function is being called. + 0x00 calldataload 0xE0 shr + dup1 0x3fb5c1cb eq set jumpi + dup1 0xf2c9ecd8 eq get jumpi + + set: + SET_NUMBER() + get: + GET_NUMBER() + +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/contracts/RememberCreator.huff b/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/contracts/RememberCreator.huff new file mode 100644 index 0000000000..cab97c15be --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/contracts/RememberCreator.huff @@ -0,0 +1,24 @@ +#define constant CREATOR_SLOT = FREE_STORAGE_POINTER() + +#define function CREATOR() view returns (address) + +#define macro CONSTRUCTOR() = takes(0) returns(0) { + caller [CREATOR_SLOT] sstore +} + +#define macro MAIN() = takes(0) returns(0) { + 0x00 calldataload 0xE0 shr // [selector] + __FUNC_SIG(CREATOR) eq get_creator jumpi + + // no selector matched, revert + base_error: + returndatasize returndatasize revert + + get_creator: + // check no call value + callvalue base_error jumpi + // read and return creator + [CREATOR_SLOT] sload // [creator] + returndatasize mstore // [] + 0x20 returndatasize return +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/interfaces/IConstructor.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/interfaces/IConstructor.sol new file mode 100644 index 0000000000..c63d409bda --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/interfaces/IConstructor.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.7.0 <0.9.0; + +interface IConstructor { + function getArgOne() external returns (address); + function getArgTwo() external returns (uint256); +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/interfaces/INumber.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/interfaces/INumber.sol new file mode 100644 index 0000000000..5fabb79f1d --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/interfaces/INumber.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.7.0 <0.9.0; + +interface INumber { + function setNumber(uint256) external; + function getNumber() external returns (uint256); +} diff --git a/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/interfaces/IRememberCreator.sol b/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/interfaces/IRememberCreator.sol new file mode 100644 index 0000000000..a9b6ec71d6 --- /dev/null +++ b/packages/wallet/wallet-contracts/lib/foundry-huff/src/test/interfaces/IRememberCreator.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.7.0 <0.9.0; + +interface IRememberCreator { + function CREATOR() external view returns (address); +} diff --git a/packages/wallet/wallet-contracts/networks/arbitrum.json b/packages/wallet/wallet-contracts/networks/arbitrum.json new file mode 100644 index 0000000000..d927325022 --- /dev/null +++ b/packages/wallet/wallet-contracts/networks/arbitrum.json @@ -0,0 +1,22 @@ +[ + { + "contractName": "WalletFactory", + "address": "0xFaA5c0b14d1bED5C888Ca655B9a8A5911F78eF4A" + }, + { + "contractName": "MainModule", + "address": "0xfBf8f1A5E00034762D928f46d438B947f5d4065d" + }, + { + "contractName": "MainModuleUpgradable", + "address": "0x4222dcA3974E39A8b41c411FeDDE9b09Ae14b911" + }, + { + "contractName": "GuestModule", + "address": "0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE" + }, + { + "contractName": "SequenceUtils", + "address": "0xdbbFa3cB3B087B64F4ef5E3D20Dda2488AA244e6" + } +] \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/networks/arbitrumGoerli.json b/packages/wallet/wallet-contracts/networks/arbitrumGoerli.json new file mode 100644 index 0000000000..d927325022 --- /dev/null +++ b/packages/wallet/wallet-contracts/networks/arbitrumGoerli.json @@ -0,0 +1,22 @@ +[ + { + "contractName": "WalletFactory", + "address": "0xFaA5c0b14d1bED5C888Ca655B9a8A5911F78eF4A" + }, + { + "contractName": "MainModule", + "address": "0xfBf8f1A5E00034762D928f46d438B947f5d4065d" + }, + { + "contractName": "MainModuleUpgradable", + "address": "0x4222dcA3974E39A8b41c411FeDDE9b09Ae14b911" + }, + { + "contractName": "GuestModule", + "address": "0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE" + }, + { + "contractName": "SequenceUtils", + "address": "0xdbbFa3cB3B087B64F4ef5E3D20Dda2488AA244e6" + } +] \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/networks/arbitrumNova.json b/packages/wallet/wallet-contracts/networks/arbitrumNova.json new file mode 100644 index 0000000000..d927325022 --- /dev/null +++ b/packages/wallet/wallet-contracts/networks/arbitrumNova.json @@ -0,0 +1,22 @@ +[ + { + "contractName": "WalletFactory", + "address": "0xFaA5c0b14d1bED5C888Ca655B9a8A5911F78eF4A" + }, + { + "contractName": "MainModule", + "address": "0xfBf8f1A5E00034762D928f46d438B947f5d4065d" + }, + { + "contractName": "MainModuleUpgradable", + "address": "0x4222dcA3974E39A8b41c411FeDDE9b09Ae14b911" + }, + { + "contractName": "GuestModule", + "address": "0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE" + }, + { + "contractName": "SequenceUtils", + "address": "0xdbbFa3cB3B087B64F4ef5E3D20Dda2488AA244e6" + } +] \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/networks/avalanche.json b/packages/wallet/wallet-contracts/networks/avalanche.json new file mode 100644 index 0000000000..d927325022 --- /dev/null +++ b/packages/wallet/wallet-contracts/networks/avalanche.json @@ -0,0 +1,22 @@ +[ + { + "contractName": "WalletFactory", + "address": "0xFaA5c0b14d1bED5C888Ca655B9a8A5911F78eF4A" + }, + { + "contractName": "MainModule", + "address": "0xfBf8f1A5E00034762D928f46d438B947f5d4065d" + }, + { + "contractName": "MainModuleUpgradable", + "address": "0x4222dcA3974E39A8b41c411FeDDE9b09Ae14b911" + }, + { + "contractName": "GuestModule", + "address": "0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE" + }, + { + "contractName": "SequenceUtils", + "address": "0xdbbFa3cB3B087B64F4ef5E3D20Dda2488AA244e6" + } +] \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/networks/avalancheFuji.json b/packages/wallet/wallet-contracts/networks/avalancheFuji.json new file mode 100644 index 0000000000..d927325022 --- /dev/null +++ b/packages/wallet/wallet-contracts/networks/avalancheFuji.json @@ -0,0 +1,22 @@ +[ + { + "contractName": "WalletFactory", + "address": "0xFaA5c0b14d1bED5C888Ca655B9a8A5911F78eF4A" + }, + { + "contractName": "MainModule", + "address": "0xfBf8f1A5E00034762D928f46d438B947f5d4065d" + }, + { + "contractName": "MainModuleUpgradable", + "address": "0x4222dcA3974E39A8b41c411FeDDE9b09Ae14b911" + }, + { + "contractName": "GuestModule", + "address": "0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE" + }, + { + "contractName": "SequenceUtils", + "address": "0xdbbFa3cB3B087B64F4ef5E3D20Dda2488AA244e6" + } +] \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/networks/bnb.json b/packages/wallet/wallet-contracts/networks/bnb.json new file mode 100644 index 0000000000..d927325022 --- /dev/null +++ b/packages/wallet/wallet-contracts/networks/bnb.json @@ -0,0 +1,22 @@ +[ + { + "contractName": "WalletFactory", + "address": "0xFaA5c0b14d1bED5C888Ca655B9a8A5911F78eF4A" + }, + { + "contractName": "MainModule", + "address": "0xfBf8f1A5E00034762D928f46d438B947f5d4065d" + }, + { + "contractName": "MainModuleUpgradable", + "address": "0x4222dcA3974E39A8b41c411FeDDE9b09Ae14b911" + }, + { + "contractName": "GuestModule", + "address": "0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE" + }, + { + "contractName": "SequenceUtils", + "address": "0xdbbFa3cB3B087B64F4ef5E3D20Dda2488AA244e6" + } +] \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/networks/bnbTestnet.json b/packages/wallet/wallet-contracts/networks/bnbTestnet.json new file mode 100644 index 0000000000..d927325022 --- /dev/null +++ b/packages/wallet/wallet-contracts/networks/bnbTestnet.json @@ -0,0 +1,22 @@ +[ + { + "contractName": "WalletFactory", + "address": "0xFaA5c0b14d1bED5C888Ca655B9a8A5911F78eF4A" + }, + { + "contractName": "MainModule", + "address": "0xfBf8f1A5E00034762D928f46d438B947f5d4065d" + }, + { + "contractName": "MainModuleUpgradable", + "address": "0x4222dcA3974E39A8b41c411FeDDE9b09Ae14b911" + }, + { + "contractName": "GuestModule", + "address": "0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE" + }, + { + "contractName": "SequenceUtils", + "address": "0xdbbFa3cB3B087B64F4ef5E3D20Dda2488AA244e6" + } +] \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/networks/gnosis.json b/packages/wallet/wallet-contracts/networks/gnosis.json new file mode 100644 index 0000000000..d927325022 --- /dev/null +++ b/packages/wallet/wallet-contracts/networks/gnosis.json @@ -0,0 +1,22 @@ +[ + { + "contractName": "WalletFactory", + "address": "0xFaA5c0b14d1bED5C888Ca655B9a8A5911F78eF4A" + }, + { + "contractName": "MainModule", + "address": "0xfBf8f1A5E00034762D928f46d438B947f5d4065d" + }, + { + "contractName": "MainModuleUpgradable", + "address": "0x4222dcA3974E39A8b41c411FeDDE9b09Ae14b911" + }, + { + "contractName": "GuestModule", + "address": "0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE" + }, + { + "contractName": "SequenceUtils", + "address": "0xdbbFa3cB3B087B64F4ef5E3D20Dda2488AA244e6" + } +] \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/networks/goerli.json b/packages/wallet/wallet-contracts/networks/goerli.json new file mode 100644 index 0000000000..d927325022 --- /dev/null +++ b/packages/wallet/wallet-contracts/networks/goerli.json @@ -0,0 +1,22 @@ +[ + { + "contractName": "WalletFactory", + "address": "0xFaA5c0b14d1bED5C888Ca655B9a8A5911F78eF4A" + }, + { + "contractName": "MainModule", + "address": "0xfBf8f1A5E00034762D928f46d438B947f5d4065d" + }, + { + "contractName": "MainModuleUpgradable", + "address": "0x4222dcA3974E39A8b41c411FeDDE9b09Ae14b911" + }, + { + "contractName": "GuestModule", + "address": "0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE" + }, + { + "contractName": "SequenceUtils", + "address": "0xdbbFa3cB3B087B64F4ef5E3D20Dda2488AA244e6" + } +] \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/networks/hardhat.json b/packages/wallet/wallet-contracts/networks/hardhat.json new file mode 100644 index 0000000000..67df434ce5 --- /dev/null +++ b/packages/wallet/wallet-contracts/networks/hardhat.json @@ -0,0 +1,22 @@ +[ + { + "contractName": "WalletFactory", + "address": "0xFaA5c0b14d1bED5C888Ca655B9a8A5911F78eF4A" + }, + { + "contractName": "MainModule", + "address": "0xE1846F966D116B86d65481Fe81886219D698b60D" + }, + { + "contractName": "MainModuleUpgradable", + "address": "0xB39E1ed61caC9E8eE8CDD3218765cF6a7fE390db" + }, + { + "contractName": "GuestModule", + "address": "0x28Ec0675C7b40ed78EBcBBbDF39e5652c0787B18" + }, + { + "contractName": "SequenceUtils", + "address": "0x4817Fe9f2352E88991A7c84E4385708Ccff05704" + } +] \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/networks/mainnet.json b/packages/wallet/wallet-contracts/networks/mainnet.json new file mode 100644 index 0000000000..d927325022 --- /dev/null +++ b/packages/wallet/wallet-contracts/networks/mainnet.json @@ -0,0 +1,22 @@ +[ + { + "contractName": "WalletFactory", + "address": "0xFaA5c0b14d1bED5C888Ca655B9a8A5911F78eF4A" + }, + { + "contractName": "MainModule", + "address": "0xfBf8f1A5E00034762D928f46d438B947f5d4065d" + }, + { + "contractName": "MainModuleUpgradable", + "address": "0x4222dcA3974E39A8b41c411FeDDE9b09Ae14b911" + }, + { + "contractName": "GuestModule", + "address": "0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE" + }, + { + "contractName": "SequenceUtils", + "address": "0xdbbFa3cB3B087B64F4ef5E3D20Dda2488AA244e6" + } +] \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/networks/mumbai.json b/packages/wallet/wallet-contracts/networks/mumbai.json new file mode 100644 index 0000000000..d927325022 --- /dev/null +++ b/packages/wallet/wallet-contracts/networks/mumbai.json @@ -0,0 +1,22 @@ +[ + { + "contractName": "WalletFactory", + "address": "0xFaA5c0b14d1bED5C888Ca655B9a8A5911F78eF4A" + }, + { + "contractName": "MainModule", + "address": "0xfBf8f1A5E00034762D928f46d438B947f5d4065d" + }, + { + "contractName": "MainModuleUpgradable", + "address": "0x4222dcA3974E39A8b41c411FeDDE9b09Ae14b911" + }, + { + "contractName": "GuestModule", + "address": "0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE" + }, + { + "contractName": "SequenceUtils", + "address": "0xdbbFa3cB3B087B64F4ef5E3D20Dda2488AA244e6" + } +] \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/networks/optimism.json b/packages/wallet/wallet-contracts/networks/optimism.json new file mode 100644 index 0000000000..d927325022 --- /dev/null +++ b/packages/wallet/wallet-contracts/networks/optimism.json @@ -0,0 +1,22 @@ +[ + { + "contractName": "WalletFactory", + "address": "0xFaA5c0b14d1bED5C888Ca655B9a8A5911F78eF4A" + }, + { + "contractName": "MainModule", + "address": "0xfBf8f1A5E00034762D928f46d438B947f5d4065d" + }, + { + "contractName": "MainModuleUpgradable", + "address": "0x4222dcA3974E39A8b41c411FeDDE9b09Ae14b911" + }, + { + "contractName": "GuestModule", + "address": "0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE" + }, + { + "contractName": "SequenceUtils", + "address": "0xdbbFa3cB3B087B64F4ef5E3D20Dda2488AA244e6" + } +] \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/networks/polygon.json b/packages/wallet/wallet-contracts/networks/polygon.json new file mode 100644 index 0000000000..c58ed64f4f --- /dev/null +++ b/packages/wallet/wallet-contracts/networks/polygon.json @@ -0,0 +1,26 @@ +[ + { + "contractName": "WalletFactory", + "address": "0xFaA5c0b14d1bED5C888Ca655B9a8A5911F78eF4A" + }, + { + "contractName": "MainModule", + "address": "0xfBf8f1A5E00034762D928f46d438B947f5d4065d" + }, + { + "contractName": "MainModuleUpgradable", + "address": "0x4222dcA3974E39A8b41c411FeDDE9b09Ae14b911" + }, + { + "contractName": "GuestModule", + "address": "0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE" + }, + { + "contractName": "SequenceUtils", + "address": "0xdbbFa3cB3B087B64F4ef5E3D20Dda2488AA244e6" + }, + { + "contractName": "TrustFactory", + "address": "0x4483FaA9dEEDd6D6FaCFee9c686f1E394A1280f9" + } +] \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/networks/polygonZkevm.json b/packages/wallet/wallet-contracts/networks/polygonZkevm.json new file mode 100644 index 0000000000..d927325022 --- /dev/null +++ b/packages/wallet/wallet-contracts/networks/polygonZkevm.json @@ -0,0 +1,22 @@ +[ + { + "contractName": "WalletFactory", + "address": "0xFaA5c0b14d1bED5C888Ca655B9a8A5911F78eF4A" + }, + { + "contractName": "MainModule", + "address": "0xfBf8f1A5E00034762D928f46d438B947f5d4065d" + }, + { + "contractName": "MainModuleUpgradable", + "address": "0x4222dcA3974E39A8b41c411FeDDE9b09Ae14b911" + }, + { + "contractName": "GuestModule", + "address": "0xfea230Ee243f88BC698dD8f1aE93F8301B6cdfaE" + }, + { + "contractName": "SequenceUtils", + "address": "0xdbbFa3cB3B087B64F4ef5E3D20Dda2488AA244e6" + } +] \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/package-lock.json b/packages/wallet/wallet-contracts/package-lock.json new file mode 100644 index 0000000000..35b4f2d97d --- /dev/null +++ b/packages/wallet/wallet-contracts/package-lock.json @@ -0,0 +1,22438 @@ +{ + "name": "@0xsequence/wallet-contracts", + "version": "3.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@0xsequence/wallet-contracts", + "version": "3.0.1", + "license": "Apache-2.0", + "dependencies": { + "@0xsequence/wallet": "^2.3.33", + "@typechain/ethers-v6": "^0.5.1", + "0xsequence": "^1.10.15", + "ethers": "^6.15.0", + "keccak256": "^1.0.6" + }, + "devDependencies": { + "@nomicfoundation/hardhat-ethers": "^4.0.3", + "@nomicfoundation/hardhat-verify": "^3.0.7", + "@nomiclabs/hardhat-truffle5": "^3.0.0", + "@nomiclabs/hardhat-web3": "^2.1.0", + "@tenderly/hardhat-tenderly": "^2.5.2", + "@types/chai": "^4.3.20", + "@types/chai-as-promised": "^7.1.8", + "@types/chai-string": "^1.4.5", + "@types/mocha": "^8.2.3", + "@typescript-eslint/eslint-plugin": "^8.46.4", + "@typescript-eslint/parser": "^8.46.4", + "bn-chai": "^1.0.1", + "chai": "^4.5.0", + "chai-as-promised": "^7.1.2", + "chai-bignumber": "^3.1.0", + "chai-shallow-deep-equal": "^1.4.6", + "chai-string": "^1.6.0", + "child_process": "^1.0.2", + "dotenv": "^8.6.0", + "eslint": "^9.39.2", + "eslint-config-prettier": "^8.10.2", + "eslint-plugin-import": "^2.32.0", + "eslint-plugin-prettier": "^3.4.1", + "ethereum-waffle": "^4.0.10", + "ganache-cli": "6.12.2", + "hardhat": "^2.27.0", + "hardhat-gas-reporter": "1.0.10", + "husky": "^9.1.7", + "ora": "^5.4.1", + "rimraf": "^3.0.2", + "scrypt": "github:barrysteyn/node-scrypt#fb60a8d3c158fe115a624b5ffa7480f3a24b03fb", + "solhint": "^3.6.2", + "solidity-coverage": "^0.8.17", + "threads": "^1.7.0", + "ts-node": "^10.9.2", + "typechain": "^8.3.2", + "typescript": "^4.9.5", + "yesno": "^0.3.1" + } + }, + "node_modules/@0xsequence/abi": { + "version": "2.3.33", + "resolved": "https://registry.npmjs.org/@0xsequence/abi/-/abi-2.3.33.tgz", + "integrity": "sha512-SSkzgtcsludAzXAVhTRlgxjTSKtqdpnqX2uivomRN9FFEIfKjOzNtSN7LmGA+nhEF9fW6ILAAJfIhjZgmMNz9w==", + "license": "Apache-2.0" + }, + "node_modules/@0xsequence/account": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/account/-/account-1.10.15.tgz", + "integrity": "sha512-NJhnOKWSRMj5YuI58HFTf3gC2Ld0FvUw6DUTikpF8JTx3xExWjafz5PJrQkJ/SpIYvS5GQJTB0Hjx6d6j1/dSQ==", + "license": "Apache-2.0", + "dependencies": { + "@0xsequence/abi": "1.10.15", + "@0xsequence/core": "1.10.15", + "@0xsequence/migration": "1.10.15", + "@0xsequence/network": "1.10.15", + "@0xsequence/relayer": "1.10.15", + "@0xsequence/sessions": "1.10.15", + "@0xsequence/utils": "1.10.15", + "@0xsequence/wallet": "1.10.15", + "ethers": "^5.5.2" + } + }, + "node_modules/@0xsequence/account/node_modules/@0xsequence/abi": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/abi/-/abi-1.10.15.tgz", + "integrity": "sha512-nuh68P8tRDzIMIH7mnGX1Eab0jsYVGhZa7IlNIs8CfTnGoanxLS+MGk5ioZBa6+slzxb9VP8mnQ5QhAWeFySeg==", + "license": "Apache-2.0" + }, + "node_modules/@0xsequence/account/node_modules/@0xsequence/core": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/core/-/core-1.10.15.tgz", + "integrity": "sha512-wrE5soJSqrhhm7pC+NxckLR0lJSOnsHPLKdDqWeTRmyuhtZ4e0DsrcoeoD40I/3Bd77tdZ1GGbq00CryV7JfFw==", + "license": "Apache-2.0", + "dependencies": { + "@0xsequence/abi": "1.10.15" + }, + "peerDependencies": { + "ethers": ">=5.5" + } + }, + "node_modules/@0xsequence/account/node_modules/@0xsequence/indexer": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/indexer/-/indexer-1.10.15.tgz", + "integrity": "sha512-bc2gAIEplMcmWJMwLuXZZ0wifoxuV/zHyWzEdbQ5+9ruIXArxyoG0Ue9fMEzKWHfsAWyBKBJCCFbr4XJEQ5YjA==", + "license": "Apache-2.0" + }, + "node_modules/@0xsequence/account/node_modules/@0xsequence/network": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/network/-/network-1.10.15.tgz", + "integrity": "sha512-wHp8RGqFrncuoIh0ityO/jUobliargQ7SWlvZCf8Ez0T7uiXDEDokrFSN2F9FIl6i5a5NmcEpXhfhwS/L0pN2w==", + "license": "Apache-2.0", + "dependencies": { + "@0xsequence/core": "1.10.15", + "@0xsequence/indexer": "1.10.15", + "@0xsequence/relayer": "1.10.15", + "@0xsequence/utils": "1.10.15" + }, + "peerDependencies": { + "ethers": ">=5.5 < 6" + } + }, + "node_modules/@0xsequence/account/node_modules/@0xsequence/relayer": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/relayer/-/relayer-1.10.15.tgz", + "integrity": "sha512-QpNAzRjqCl9xJdXzErQA0kmv2jzEXPfVlPwutbgmrCEIj+rHdw3M+kiG0MWBnOqxoSEA98oJnxXmpBL5mkCA6g==", + "license": "Apache-2.0", + "dependencies": { + "@0xsequence/abi": "1.10.15", + "@0xsequence/core": "1.10.15", + "@0xsequence/utils": "1.10.15" + }, + "peerDependencies": { + "ethers": ">=5.5 < 6" + } + }, + "node_modules/@0xsequence/account/node_modules/@0xsequence/signhub": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/signhub/-/signhub-1.10.15.tgz", + "integrity": "sha512-9yZWb8d2aXoWOQp0XC81hkS+hLWxO/pZIyCRtNVdif0/SPA86v6e96xPmuj45KONYgiH33ROVDpeJEKhOEo0jg==", + "license": "Apache-2.0", + "dependencies": { + "@0xsequence/core": "1.10.15", + "ethers": "^5.5.2" + } + }, + "node_modules/@0xsequence/account/node_modules/@0xsequence/utils": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/utils/-/utils-1.10.15.tgz", + "integrity": "sha512-LIrQS5J+3MOER+i7ajX7fiT6ga3QoDf8wsi5KY/2eFZS39sbCXGzg1ORxjtee++c/S/h4nuRYX1IRuseGYJWPw==", + "license": "Apache-2.0", + "dependencies": { + "js-base64": "^3.7.2" + }, + "peerDependencies": { + "ethers": ">=5.5 < 6" + } + }, + "node_modules/@0xsequence/account/node_modules/@0xsequence/wallet": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/wallet/-/wallet-1.10.15.tgz", + "integrity": "sha512-UhaIaiK3IF+bv1flg/N1yuGPZXos/orJlwAd9GbPDHOIBqkBsniyraDcO+xwBKWMBHhQL6NqfSDI9j/Zxv7ocg==", + "license": "Apache-2.0", + "dependencies": { + "@0xsequence/abi": "1.10.15", + "@0xsequence/core": "1.10.15", + "@0xsequence/network": "1.10.15", + "@0xsequence/relayer": "1.10.15", + "@0xsequence/signhub": "1.10.15", + "@0xsequence/utils": "1.10.15" + }, + "peerDependencies": { + "ethers": ">=5.5 < 6" + } + }, + "node_modules/@0xsequence/account/node_modules/ethers": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.8.0.tgz", + "integrity": "sha512-DUq+7fHrCg1aPDFCHx6UIPb3nmt2XMpM7Y/g2gLhsl3lIBqeAfOJIl1qEvRf2uq3BiKxmh6Fh5pfp2ieyek7Kg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abi": "5.8.0", + "@ethersproject/abstract-provider": "5.8.0", + "@ethersproject/abstract-signer": "5.8.0", + "@ethersproject/address": "5.8.0", + "@ethersproject/base64": "5.8.0", + "@ethersproject/basex": "5.8.0", + "@ethersproject/bignumber": "5.8.0", + "@ethersproject/bytes": "5.8.0", + "@ethersproject/constants": "5.8.0", + "@ethersproject/contracts": "5.8.0", + "@ethersproject/hash": "5.8.0", + "@ethersproject/hdnode": "5.8.0", + "@ethersproject/json-wallets": "5.8.0", + "@ethersproject/keccak256": "5.8.0", + "@ethersproject/logger": "5.8.0", + "@ethersproject/networks": "5.8.0", + "@ethersproject/pbkdf2": "5.8.0", + "@ethersproject/properties": "5.8.0", + "@ethersproject/providers": "5.8.0", + "@ethersproject/random": "5.8.0", + "@ethersproject/rlp": "5.8.0", + "@ethersproject/sha2": "5.8.0", + "@ethersproject/signing-key": "5.8.0", + "@ethersproject/solidity": "5.8.0", + "@ethersproject/strings": "5.8.0", + "@ethersproject/transactions": "5.8.0", + "@ethersproject/units": "5.8.0", + "@ethersproject/wallet": "5.8.0", + "@ethersproject/web": "5.8.0", + "@ethersproject/wordlists": "5.8.0" + } + }, + "node_modules/@0xsequence/api": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/api/-/api-1.10.15.tgz", + "integrity": "sha512-FHzJLsOF/RU66pndfFP38yqLIaNiy46uv4f6DsJvnFSoHYfbkZjpx5m+M+vig0oN6RhtqU+sKL78z1IYF6JTkA==", + "license": "Apache-2.0" + }, + "node_modules/@0xsequence/core": { + "version": "2.3.33", + "resolved": "https://registry.npmjs.org/@0xsequence/core/-/core-2.3.33.tgz", + "integrity": "sha512-P0xkHk7GelGOlW6lW+d1AnnK2PbBfamiC02l2ms5M1hxYZ7LJmam1yb9zDRRiaWoPSpKJruArzQV9RlgY3W3xw==", + "license": "Apache-2.0", + "dependencies": { + "@0xsequence/abi": "2.3.33", + "@0xsequence/utils": "2.3.33" + }, + "peerDependencies": { + "ethers": ">=6" + } + }, + "node_modules/@0xsequence/ethauth": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@0xsequence/ethauth/-/ethauth-0.8.1.tgz", + "integrity": "sha512-P21cxRSS+2mDAqFVAJt0lwQFtbObX+Ewlj8DMyDELp81+QbfHFh6LCyu8dTXNdBx6UbmRFOCSBno5Txd50cJPQ==", + "license": "MIT", + "dependencies": { + "js-base64": "^3.7.2" + }, + "peerDependencies": { + "ethers": ">=5.5" + } + }, + "node_modules/@0xsequence/guard": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/guard/-/guard-1.10.15.tgz", + "integrity": "sha512-YrHIrOXDGn+xOUcA7DI+ROW42cJqiL9WVaLKGAaGwjHLz/QKLiH1MmECWJMM76JczjA6Th8G9YZUFwO99Cpzpg==", + "license": "Apache-2.0", + "dependencies": { + "@0xsequence/account": "1.10.15", + "@0xsequence/core": "1.10.15", + "@0xsequence/signhub": "1.10.15", + "@0xsequence/utils": "1.10.15", + "ethers": "^5.7.2" + } + }, + "node_modules/@0xsequence/guard/node_modules/@0xsequence/abi": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/abi/-/abi-1.10.15.tgz", + "integrity": "sha512-nuh68P8tRDzIMIH7mnGX1Eab0jsYVGhZa7IlNIs8CfTnGoanxLS+MGk5ioZBa6+slzxb9VP8mnQ5QhAWeFySeg==", + "license": "Apache-2.0" + }, + "node_modules/@0xsequence/guard/node_modules/@0xsequence/core": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/core/-/core-1.10.15.tgz", + "integrity": "sha512-wrE5soJSqrhhm7pC+NxckLR0lJSOnsHPLKdDqWeTRmyuhtZ4e0DsrcoeoD40I/3Bd77tdZ1GGbq00CryV7JfFw==", + "license": "Apache-2.0", + "dependencies": { + "@0xsequence/abi": "1.10.15" + }, + "peerDependencies": { + "ethers": ">=5.5" + } + }, + "node_modules/@0xsequence/guard/node_modules/@0xsequence/signhub": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/signhub/-/signhub-1.10.15.tgz", + "integrity": "sha512-9yZWb8d2aXoWOQp0XC81hkS+hLWxO/pZIyCRtNVdif0/SPA86v6e96xPmuj45KONYgiH33ROVDpeJEKhOEo0jg==", + "license": "Apache-2.0", + "dependencies": { + "@0xsequence/core": "1.10.15", + "ethers": "^5.5.2" + } + }, + "node_modules/@0xsequence/guard/node_modules/@0xsequence/utils": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/utils/-/utils-1.10.15.tgz", + "integrity": "sha512-LIrQS5J+3MOER+i7ajX7fiT6ga3QoDf8wsi5KY/2eFZS39sbCXGzg1ORxjtee++c/S/h4nuRYX1IRuseGYJWPw==", + "license": "Apache-2.0", + "dependencies": { + "js-base64": "^3.7.2" + }, + "peerDependencies": { + "ethers": ">=5.5 < 6" + } + }, + "node_modules/@0xsequence/guard/node_modules/ethers": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.8.0.tgz", + "integrity": "sha512-DUq+7fHrCg1aPDFCHx6UIPb3nmt2XMpM7Y/g2gLhsl3lIBqeAfOJIl1qEvRf2uq3BiKxmh6Fh5pfp2ieyek7Kg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abi": "5.8.0", + "@ethersproject/abstract-provider": "5.8.0", + "@ethersproject/abstract-signer": "5.8.0", + "@ethersproject/address": "5.8.0", + "@ethersproject/base64": "5.8.0", + "@ethersproject/basex": "5.8.0", + "@ethersproject/bignumber": "5.8.0", + "@ethersproject/bytes": "5.8.0", + "@ethersproject/constants": "5.8.0", + "@ethersproject/contracts": "5.8.0", + "@ethersproject/hash": "5.8.0", + "@ethersproject/hdnode": "5.8.0", + "@ethersproject/json-wallets": "5.8.0", + "@ethersproject/keccak256": "5.8.0", + "@ethersproject/logger": "5.8.0", + "@ethersproject/networks": "5.8.0", + "@ethersproject/pbkdf2": "5.8.0", + "@ethersproject/properties": "5.8.0", + "@ethersproject/providers": "5.8.0", + "@ethersproject/random": "5.8.0", + "@ethersproject/rlp": "5.8.0", + "@ethersproject/sha2": "5.8.0", + "@ethersproject/signing-key": "5.8.0", + "@ethersproject/solidity": "5.8.0", + "@ethersproject/strings": "5.8.0", + "@ethersproject/transactions": "5.8.0", + "@ethersproject/units": "5.8.0", + "@ethersproject/wallet": "5.8.0", + "@ethersproject/web": "5.8.0", + "@ethersproject/wordlists": "5.8.0" + } + }, + "node_modules/@0xsequence/indexer": { + "version": "2.3.33", + "resolved": "https://registry.npmjs.org/@0xsequence/indexer/-/indexer-2.3.33.tgz", + "integrity": "sha512-GjS6he4bKl3LtT9mZ/hFUVMTK3wzr54s5STf1Mi4wsfVk5nmkggJPWmnCbBJvQyAWt1uLjSDZSN00/Esl17thQ==", + "license": "Apache-2.0" + }, + "node_modules/@0xsequence/metadata": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/metadata/-/metadata-1.10.15.tgz", + "integrity": "sha512-eakkeV4ZtSkyo80JglSUdkUwOjYHAO5udCYAet6ekzHYgiF62dS9WcJdrrWkE2umAXn1sF94tQHf/OFZJGWwIg==", + "license": "Apache-2.0" + }, + "node_modules/@0xsequence/migration": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/migration/-/migration-1.10.15.tgz", + "integrity": "sha512-muZllmKQOz3yEyJULrhDpycpML2IOH+KJiBN70reKPoMm/pxx/B4v4PAFOkd3oZ1ynSqcF0TkHqGmeyf5/SZ3g==", + "license": "Apache-2.0", + "dependencies": { + "@0xsequence/abi": "1.10.15", + "@0xsequence/core": "1.10.15", + "@0xsequence/wallet": "1.10.15", + "ethers": "^5.5.2" + } + }, + "node_modules/@0xsequence/migration/node_modules/@0xsequence/abi": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/abi/-/abi-1.10.15.tgz", + "integrity": "sha512-nuh68P8tRDzIMIH7mnGX1Eab0jsYVGhZa7IlNIs8CfTnGoanxLS+MGk5ioZBa6+slzxb9VP8mnQ5QhAWeFySeg==", + "license": "Apache-2.0" + }, + "node_modules/@0xsequence/migration/node_modules/@0xsequence/core": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/core/-/core-1.10.15.tgz", + "integrity": "sha512-wrE5soJSqrhhm7pC+NxckLR0lJSOnsHPLKdDqWeTRmyuhtZ4e0DsrcoeoD40I/3Bd77tdZ1GGbq00CryV7JfFw==", + "license": "Apache-2.0", + "dependencies": { + "@0xsequence/abi": "1.10.15" + }, + "peerDependencies": { + "ethers": ">=5.5" + } + }, + "node_modules/@0xsequence/migration/node_modules/@0xsequence/indexer": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/indexer/-/indexer-1.10.15.tgz", + "integrity": "sha512-bc2gAIEplMcmWJMwLuXZZ0wifoxuV/zHyWzEdbQ5+9ruIXArxyoG0Ue9fMEzKWHfsAWyBKBJCCFbr4XJEQ5YjA==", + "license": "Apache-2.0" + }, + "node_modules/@0xsequence/migration/node_modules/@0xsequence/network": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/network/-/network-1.10.15.tgz", + "integrity": "sha512-wHp8RGqFrncuoIh0ityO/jUobliargQ7SWlvZCf8Ez0T7uiXDEDokrFSN2F9FIl6i5a5NmcEpXhfhwS/L0pN2w==", + "license": "Apache-2.0", + "dependencies": { + "@0xsequence/core": "1.10.15", + "@0xsequence/indexer": "1.10.15", + "@0xsequence/relayer": "1.10.15", + "@0xsequence/utils": "1.10.15" + }, + "peerDependencies": { + "ethers": ">=5.5 < 6" + } + }, + "node_modules/@0xsequence/migration/node_modules/@0xsequence/relayer": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/relayer/-/relayer-1.10.15.tgz", + "integrity": "sha512-QpNAzRjqCl9xJdXzErQA0kmv2jzEXPfVlPwutbgmrCEIj+rHdw3M+kiG0MWBnOqxoSEA98oJnxXmpBL5mkCA6g==", + "license": "Apache-2.0", + "dependencies": { + "@0xsequence/abi": "1.10.15", + "@0xsequence/core": "1.10.15", + "@0xsequence/utils": "1.10.15" + }, + "peerDependencies": { + "ethers": ">=5.5 < 6" + } + }, + "node_modules/@0xsequence/migration/node_modules/@0xsequence/signhub": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/signhub/-/signhub-1.10.15.tgz", + "integrity": "sha512-9yZWb8d2aXoWOQp0XC81hkS+hLWxO/pZIyCRtNVdif0/SPA86v6e96xPmuj45KONYgiH33ROVDpeJEKhOEo0jg==", + "license": "Apache-2.0", + "dependencies": { + "@0xsequence/core": "1.10.15", + "ethers": "^5.5.2" + } + }, + "node_modules/@0xsequence/migration/node_modules/@0xsequence/utils": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/utils/-/utils-1.10.15.tgz", + "integrity": "sha512-LIrQS5J+3MOER+i7ajX7fiT6ga3QoDf8wsi5KY/2eFZS39sbCXGzg1ORxjtee++c/S/h4nuRYX1IRuseGYJWPw==", + "license": "Apache-2.0", + "dependencies": { + "js-base64": "^3.7.2" + }, + "peerDependencies": { + "ethers": ">=5.5 < 6" + } + }, + "node_modules/@0xsequence/migration/node_modules/@0xsequence/wallet": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/wallet/-/wallet-1.10.15.tgz", + "integrity": "sha512-UhaIaiK3IF+bv1flg/N1yuGPZXos/orJlwAd9GbPDHOIBqkBsniyraDcO+xwBKWMBHhQL6NqfSDI9j/Zxv7ocg==", + "license": "Apache-2.0", + "dependencies": { + "@0xsequence/abi": "1.10.15", + "@0xsequence/core": "1.10.15", + "@0xsequence/network": "1.10.15", + "@0xsequence/relayer": "1.10.15", + "@0xsequence/signhub": "1.10.15", + "@0xsequence/utils": "1.10.15" + }, + "peerDependencies": { + "ethers": ">=5.5 < 6" + } + }, + "node_modules/@0xsequence/migration/node_modules/ethers": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.8.0.tgz", + "integrity": "sha512-DUq+7fHrCg1aPDFCHx6UIPb3nmt2XMpM7Y/g2gLhsl3lIBqeAfOJIl1qEvRf2uq3BiKxmh6Fh5pfp2ieyek7Kg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abi": "5.8.0", + "@ethersproject/abstract-provider": "5.8.0", + "@ethersproject/abstract-signer": "5.8.0", + "@ethersproject/address": "5.8.0", + "@ethersproject/base64": "5.8.0", + "@ethersproject/basex": "5.8.0", + "@ethersproject/bignumber": "5.8.0", + "@ethersproject/bytes": "5.8.0", + "@ethersproject/constants": "5.8.0", + "@ethersproject/contracts": "5.8.0", + "@ethersproject/hash": "5.8.0", + "@ethersproject/hdnode": "5.8.0", + "@ethersproject/json-wallets": "5.8.0", + "@ethersproject/keccak256": "5.8.0", + "@ethersproject/logger": "5.8.0", + "@ethersproject/networks": "5.8.0", + "@ethersproject/pbkdf2": "5.8.0", + "@ethersproject/properties": "5.8.0", + "@ethersproject/providers": "5.8.0", + "@ethersproject/random": "5.8.0", + "@ethersproject/rlp": "5.8.0", + "@ethersproject/sha2": "5.8.0", + "@ethersproject/signing-key": "5.8.0", + "@ethersproject/solidity": "5.8.0", + "@ethersproject/strings": "5.8.0", + "@ethersproject/transactions": "5.8.0", + "@ethersproject/units": "5.8.0", + "@ethersproject/wallet": "5.8.0", + "@ethersproject/web": "5.8.0", + "@ethersproject/wordlists": "5.8.0" + } + }, + "node_modules/@0xsequence/network": { + "version": "2.3.33", + "resolved": "https://registry.npmjs.org/@0xsequence/network/-/network-2.3.33.tgz", + "integrity": "sha512-0sTGguIitsGcjz6nlFBQBPhowC55RlO4UR8zKdFbukIfleTgAxbnyKDxp0apQhj229PeUK0BMyVeLei0b7EHjg==", + "license": "Apache-2.0", + "dependencies": { + "@0xsequence/core": "2.3.33", + "@0xsequence/indexer": "2.3.33", + "@0xsequence/relayer": "2.3.33", + "@0xsequence/utils": "2.3.33" + }, + "peerDependencies": { + "ethers": ">=6" + } + }, + "node_modules/@0xsequence/relayer": { + "version": "2.3.33", + "resolved": "https://registry.npmjs.org/@0xsequence/relayer/-/relayer-2.3.33.tgz", + "integrity": "sha512-vHHi6pSstBomaM+GZwaj0FNlIbtcLfr89gSUpIIyrsIETWA0CeWbvLs0K02TeDPUiC0z2fh3Yi0bA77yv/gZFw==", + "license": "Apache-2.0", + "dependencies": { + "@0xsequence/abi": "2.3.33", + "@0xsequence/core": "2.3.33", + "@0xsequence/utils": "2.3.33" + }, + "peerDependencies": { + "ethers": ">=6" + } + }, + "node_modules/@0xsequence/replacer": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/replacer/-/replacer-1.10.15.tgz", + "integrity": "sha512-ZV9cl/oDqCZf0cJUclGqTWY8iGuvGrXzUBT2w1AvneuQWjqYWIEzvXRBnscHVEtTEdOIV9sqBaC0MiK0TedC8Q==", + "license": "Apache-2.0", + "dependencies": { + "@0xsequence/abi": "1.10.15", + "@0xsequence/core": "1.10.15" + }, + "peerDependencies": { + "ethers": ">=5.5" + } + }, + "node_modules/@0xsequence/replacer/node_modules/@0xsequence/abi": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/abi/-/abi-1.10.15.tgz", + "integrity": "sha512-nuh68P8tRDzIMIH7mnGX1Eab0jsYVGhZa7IlNIs8CfTnGoanxLS+MGk5ioZBa6+slzxb9VP8mnQ5QhAWeFySeg==", + "license": "Apache-2.0" + }, + "node_modules/@0xsequence/replacer/node_modules/@0xsequence/core": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/core/-/core-1.10.15.tgz", + "integrity": "sha512-wrE5soJSqrhhm7pC+NxckLR0lJSOnsHPLKdDqWeTRmyuhtZ4e0DsrcoeoD40I/3Bd77tdZ1GGbq00CryV7JfFw==", + "license": "Apache-2.0", + "dependencies": { + "@0xsequence/abi": "1.10.15" + }, + "peerDependencies": { + "ethers": ">=5.5" + } + }, + "node_modules/@0xsequence/sessions": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/sessions/-/sessions-1.10.15.tgz", + "integrity": "sha512-Zack16p3p92sO3ZFfZFz9Fa9Nlkxkt3ew48xnsnN3P3XCJFLX+MM7hoNOpkS3yQFVEb5QDhYrrAfE019U5hgww==", + "license": "Apache-2.0", + "dependencies": { + "@0xsequence/core": "1.10.15", + "@0xsequence/migration": "1.10.15", + "@0xsequence/replacer": "1.10.15", + "ethers": "^5.5.2", + "idb": "^7.1.1" + } + }, + "node_modules/@0xsequence/sessions/node_modules/@0xsequence/abi": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/abi/-/abi-1.10.15.tgz", + "integrity": "sha512-nuh68P8tRDzIMIH7mnGX1Eab0jsYVGhZa7IlNIs8CfTnGoanxLS+MGk5ioZBa6+slzxb9VP8mnQ5QhAWeFySeg==", + "license": "Apache-2.0" + }, + "node_modules/@0xsequence/sessions/node_modules/@0xsequence/core": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/core/-/core-1.10.15.tgz", + "integrity": "sha512-wrE5soJSqrhhm7pC+NxckLR0lJSOnsHPLKdDqWeTRmyuhtZ4e0DsrcoeoD40I/3Bd77tdZ1GGbq00CryV7JfFw==", + "license": "Apache-2.0", + "dependencies": { + "@0xsequence/abi": "1.10.15" + }, + "peerDependencies": { + "ethers": ">=5.5" + } + }, + "node_modules/@0xsequence/sessions/node_modules/ethers": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.8.0.tgz", + "integrity": "sha512-DUq+7fHrCg1aPDFCHx6UIPb3nmt2XMpM7Y/g2gLhsl3lIBqeAfOJIl1qEvRf2uq3BiKxmh6Fh5pfp2ieyek7Kg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abi": "5.8.0", + "@ethersproject/abstract-provider": "5.8.0", + "@ethersproject/abstract-signer": "5.8.0", + "@ethersproject/address": "5.8.0", + "@ethersproject/base64": "5.8.0", + "@ethersproject/basex": "5.8.0", + "@ethersproject/bignumber": "5.8.0", + "@ethersproject/bytes": "5.8.0", + "@ethersproject/constants": "5.8.0", + "@ethersproject/contracts": "5.8.0", + "@ethersproject/hash": "5.8.0", + "@ethersproject/hdnode": "5.8.0", + "@ethersproject/json-wallets": "5.8.0", + "@ethersproject/keccak256": "5.8.0", + "@ethersproject/logger": "5.8.0", + "@ethersproject/networks": "5.8.0", + "@ethersproject/pbkdf2": "5.8.0", + "@ethersproject/properties": "5.8.0", + "@ethersproject/providers": "5.8.0", + "@ethersproject/random": "5.8.0", + "@ethersproject/rlp": "5.8.0", + "@ethersproject/sha2": "5.8.0", + "@ethersproject/signing-key": "5.8.0", + "@ethersproject/solidity": "5.8.0", + "@ethersproject/strings": "5.8.0", + "@ethersproject/transactions": "5.8.0", + "@ethersproject/units": "5.8.0", + "@ethersproject/wallet": "5.8.0", + "@ethersproject/web": "5.8.0", + "@ethersproject/wordlists": "5.8.0" + } + }, + "node_modules/@0xsequence/signhub": { + "version": "2.3.33", + "resolved": "https://registry.npmjs.org/@0xsequence/signhub/-/signhub-2.3.33.tgz", + "integrity": "sha512-Ve3gvn6dzXRVdd2eEfCoL3UvehxKbEtYcpxNnX/7CxcvGU5a61Ol7WkM4tKScz1zc6AMdX8YE2C7VDN46ew0/Q==", + "license": "Apache-2.0", + "dependencies": { + "@0xsequence/core": "2.3.33" + }, + "peerDependencies": { + "ethers": ">=6" + } + }, + "node_modules/@0xsequence/utils": { + "version": "2.3.33", + "resolved": "https://registry.npmjs.org/@0xsequence/utils/-/utils-2.3.33.tgz", + "integrity": "sha512-qaPlV5oMaJKIf1j4GVYoN2OthoL9EVgblglUJIKp3/Tgfs0B85GOxc92BCSjLRn7NYzaW9P5FIsDAcCQifQdDQ==", + "license": "Apache-2.0", + "dependencies": { + "js-base64": "^3.7.2" + }, + "peerDependencies": { + "ethers": ">=6" + } + }, + "node_modules/@0xsequence/wallet": { + "version": "2.3.33", + "resolved": "https://registry.npmjs.org/@0xsequence/wallet/-/wallet-2.3.33.tgz", + "integrity": "sha512-jl5zrnvcqr9f4pNtP7q63rf0FPe7noC6hVn0eTaO8YXDy9a/8rkkhstcTLYQFdNhii7XMY85kJcmBb4ws7EglA==", + "license": "Apache-2.0", + "dependencies": { + "@0xsequence/abi": "2.3.33", + "@0xsequence/core": "2.3.33", + "@0xsequence/network": "2.3.33", + "@0xsequence/relayer": "2.3.33", + "@0xsequence/signhub": "2.3.33", + "@0xsequence/utils": "2.3.33" + }, + "peerDependencies": { + "ethers": ">=6" + } + }, + "node_modules/@adraffy/ens-normalize": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz", + "integrity": "sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==", + "license": "MIT" + }, + "node_modules/@aws-crypto/crc32": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz", + "integrity": "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-crypto/sha256-browser": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", + "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-js": "^5.2.0", + "@aws-crypto/supports-web-crypto": "^5.2.0", + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", + "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-crypto/supports-web-crypto": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", + "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", + "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.222.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-lambda": { + "version": "3.1037.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-lambda/-/client-lambda-3.1037.0.tgz", + "integrity": "sha512-QGlFTYge89OcrCJXO2fMkqbYrASOd5Ut3V58EYcuajGONIKOxxP6UYwrZE5vDMebNJi2mPLesDKaM7aH7oqcrA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "^3.974.5", + "@aws-sdk/credential-provider-node": "^3.972.36", + "@aws-sdk/middleware-host-header": "^3.972.10", + "@aws-sdk/middleware-logger": "^3.972.10", + "@aws-sdk/middleware-recursion-detection": "^3.972.11", + "@aws-sdk/middleware-user-agent": "^3.972.35", + "@aws-sdk/region-config-resolver": "^3.972.13", + "@aws-sdk/types": "^3.973.8", + "@aws-sdk/util-endpoints": "^3.996.8", + "@aws-sdk/util-user-agent-browser": "^3.972.10", + "@aws-sdk/util-user-agent-node": "^3.973.21", + "@smithy/config-resolver": "^4.4.17", + "@smithy/core": "^3.23.17", + "@smithy/eventstream-serde-browser": "^4.2.14", + "@smithy/eventstream-serde-config-resolver": "^4.3.14", + "@smithy/eventstream-serde-node": "^4.2.14", + "@smithy/fetch-http-handler": "^5.3.17", + "@smithy/hash-node": "^4.2.14", + "@smithy/invalid-dependency": "^4.2.14", + "@smithy/middleware-content-length": "^4.2.14", + "@smithy/middleware-endpoint": "^4.4.32", + "@smithy/middleware-retry": "^4.5.5", + "@smithy/middleware-serde": "^4.2.20", + "@smithy/middleware-stack": "^4.2.14", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/node-http-handler": "^4.6.1", + "@smithy/protocol-http": "^5.3.14", + "@smithy/smithy-client": "^4.12.13", + "@smithy/types": "^4.14.1", + "@smithy/url-parser": "^4.2.14", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-body-length-browser": "^4.2.2", + "@smithy/util-body-length-node": "^4.2.3", + "@smithy/util-defaults-mode-browser": "^4.3.49", + "@smithy/util-defaults-mode-node": "^4.2.54", + "@smithy/util-endpoints": "^3.4.2", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-retry": "^4.3.4", + "@smithy/util-stream": "^4.5.25", + "@smithy/util-utf8": "^4.2.2", + "@smithy/util-waiter": "^4.2.16", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/core": { + "version": "3.974.5", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.974.5.tgz", + "integrity": "sha512-lMPlYlYfQdNZhlkJgnkmESwrY+hNh3PljmZ+37oAqLNdJ6rnILAwFSyc6B3bJeDOtMORNnMQIej0aTRuOlDyhQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.8", + "@aws-sdk/xml-builder": "^3.972.19", + "@smithy/core": "^3.23.17", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/property-provider": "^4.2.14", + "@smithy/protocol-http": "^5.3.14", + "@smithy/signature-v4": "^5.3.14", + "@smithy/smithy-client": "^4.12.13", + "@smithy/types": "^4.14.1", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-retry": "^4.3.4", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-env": { + "version": "3.972.31", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.31.tgz", + "integrity": "sha512-X/yGB73LmDW/6MdDJGCDzZBUXnM3ys4vs9l+5ZTJmiEswDdP1OjeoAFlFjVGS9o4KB2wZWQ9KOfdVNSSK6Ep3w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.974.5", + "@aws-sdk/types": "^3.973.8", + "@smithy/property-provider": "^4.2.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-http": { + "version": "3.972.33", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.33.tgz", + "integrity": "sha512-c0ZF+lwoWVvX5iCaGKL5T/4DnIw88CGqxA0BcBs3U86mIp5EZYPVg+KSPkMXOyokmADvNewiMUfSG2uFwjRp0g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.974.5", + "@aws-sdk/types": "^3.973.8", + "@smithy/fetch-http-handler": "^5.3.17", + "@smithy/node-http-handler": "^4.6.1", + "@smithy/property-provider": "^4.2.14", + "@smithy/protocol-http": "^5.3.14", + "@smithy/smithy-client": "^4.12.13", + "@smithy/types": "^4.14.1", + "@smithy/util-stream": "^4.5.25", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-ini": { + "version": "3.972.35", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.35.tgz", + "integrity": "sha512-jsU4u/cRkKFLKQS0k918FQ27fzXLG5ENiLWQMYE6581zLeI2hWh04ptlrvZMB3wJT/5d+vSzJk74X1CMFr4y8Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.974.5", + "@aws-sdk/credential-provider-env": "^3.972.31", + "@aws-sdk/credential-provider-http": "^3.972.33", + "@aws-sdk/credential-provider-login": "^3.972.35", + "@aws-sdk/credential-provider-process": "^3.972.31", + "@aws-sdk/credential-provider-sso": "^3.972.35", + "@aws-sdk/credential-provider-web-identity": "^3.972.35", + "@aws-sdk/nested-clients": "^3.997.3", + "@aws-sdk/types": "^3.973.8", + "@smithy/credential-provider-imds": "^4.2.14", + "@smithy/property-provider": "^4.2.14", + "@smithy/shared-ini-file-loader": "^4.4.9", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-login": { + "version": "3.972.35", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.35.tgz", + "integrity": "sha512-5oa3j0cA50jPqgNhZ9XdJVopuzUf1klRb28/2MfLYWWiPi9DRVvbrBWT+DidbHTT36520VuXZJahQwR+YgSjrg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.974.5", + "@aws-sdk/nested-clients": "^3.997.3", + "@aws-sdk/types": "^3.973.8", + "@smithy/property-provider": "^4.2.14", + "@smithy/protocol-http": "^5.3.14", + "@smithy/shared-ini-file-loader": "^4.4.9", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-node": { + "version": "3.972.36", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.36.tgz", + "integrity": "sha512-4nT2T8Z7vH8KE9EdjEsuIlHpZSlcaK2PrKbQBjuUGU46BCCzF3WvP0u0Uiosni3Ykmmn4rWLVawoOCLotUtCbg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/credential-provider-env": "^3.972.31", + "@aws-sdk/credential-provider-http": "^3.972.33", + "@aws-sdk/credential-provider-ini": "^3.972.35", + "@aws-sdk/credential-provider-process": "^3.972.31", + "@aws-sdk/credential-provider-sso": "^3.972.35", + "@aws-sdk/credential-provider-web-identity": "^3.972.35", + "@aws-sdk/types": "^3.973.8", + "@smithy/credential-provider-imds": "^4.2.14", + "@smithy/property-provider": "^4.2.14", + "@smithy/shared-ini-file-loader": "^4.4.9", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-process": { + "version": "3.972.31", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.31.tgz", + "integrity": "sha512-eKeT4MXumpBJsrDLCYcSzIkFPVTFn/es7It2oogp2OhU/ic7P/+xzFpQx9ZhwtXS57Mc5S42BPWi7lHmvs/nYg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.974.5", + "@aws-sdk/types": "^3.973.8", + "@smithy/property-provider": "^4.2.14", + "@smithy/shared-ini-file-loader": "^4.4.9", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-sso": { + "version": "3.972.35", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.35.tgz", + "integrity": "sha512-bCuBdfnj0KGDMdLp6utMTLiJcFN2ek9EgZinxQZZSc3FxjJ/HSqeqab2cjbnoNfy8RM6suDCsRkmVY1izp9I+A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.974.5", + "@aws-sdk/nested-clients": "^3.997.3", + "@aws-sdk/token-providers": "3.1036.0", + "@aws-sdk/types": "^3.973.8", + "@smithy/property-provider": "^4.2.14", + "@smithy/shared-ini-file-loader": "^4.4.9", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-web-identity": { + "version": "3.972.35", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.35.tgz", + "integrity": "sha512-swW6Bwvl8lanyEMtZOWE/oR6yqcRQH4HTQZUVsnDVgoXvRjRywpYpLv2BWwjUFyjPrqsdX6FeTkf4tMSe/qFTQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.974.5", + "@aws-sdk/nested-clients": "^3.997.3", + "@aws-sdk/types": "^3.973.8", + "@smithy/property-provider": "^4.2.14", + "@smithy/shared-ini-file-loader": "^4.4.9", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-host-header": { + "version": "3.972.10", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.972.10.tgz", + "integrity": "sha512-IJSsIMeVQ8MMCPbuh1AbltkFhLBLXn7aejzfX5YKT/VLDHn++Dcz8886tXckE+wQssyPUhaXrJhdakO2VilRhg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.8", + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-logger": { + "version": "3.972.10", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.972.10.tgz", + "integrity": "sha512-OOuGvvz1Dm20SjZo5oEBePFqxt5nf8AwkNDSyUHvD9/bfNASmstcYxFAHUowy4n6Io7mWUZ04JURZwSBvyQanQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.8", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-recursion-detection": { + "version": "3.972.11", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.972.11.tgz", + "integrity": "sha512-+zz6f79Kj9V5qFK2P+D8Ehjnw4AhphAlCAsPjUqEcInA9umtSSKMrHbSagEeOIsDNuvVrH98bjRHcyQukTrhaQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.8", + "@aws/lambda-invoke-store": "^0.2.2", + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-sdk-s3": { + "version": "3.972.34", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.34.tgz", + "integrity": "sha512-/UL96JKjsjdodcRRMKl99tLQvK6Oi9ptLC9iU1yiTF/ruaDX0mtBBtnLNZDxIZRJOCVOtB49ed1YaTadqygk8Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.974.5", + "@aws-sdk/types": "^3.973.8", + "@aws-sdk/util-arn-parser": "^3.972.3", + "@smithy/core": "^3.23.17", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/protocol-http": "^5.3.14", + "@smithy/signature-v4": "^5.3.14", + "@smithy/smithy-client": "^4.12.13", + "@smithy/types": "^4.14.1", + "@smithy/util-config-provider": "^4.2.2", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-stream": "^4.5.25", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-user-agent": { + "version": "3.972.35", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.35.tgz", + "integrity": "sha512-hOFWNOjVmOocpRlrU04nYxjMOeoe0Obu5AXEuhB8zblMCPl3cG1hdluQCZERRKFyhMQjwZnDbhSHjoMUjetFGw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.974.5", + "@aws-sdk/types": "^3.973.8", + "@aws-sdk/util-endpoints": "^3.996.8", + "@smithy/core": "^3.23.17", + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", + "@smithy/util-retry": "^4.3.4", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/nested-clients": { + "version": "3.997.3", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.997.3.tgz", + "integrity": "sha512-SivE6GP228IVgfsrr2c/vqTg95X0Qj39Yw4uIrcddpkUzIltNMoNOR62leHOLhODfjv9K8X2mPTwS69A5kT0nQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "^3.974.5", + "@aws-sdk/middleware-host-header": "^3.972.10", + "@aws-sdk/middleware-logger": "^3.972.10", + "@aws-sdk/middleware-recursion-detection": "^3.972.11", + "@aws-sdk/middleware-user-agent": "^3.972.35", + "@aws-sdk/region-config-resolver": "^3.972.13", + "@aws-sdk/signature-v4-multi-region": "^3.996.22", + "@aws-sdk/types": "^3.973.8", + "@aws-sdk/util-endpoints": "^3.996.8", + "@aws-sdk/util-user-agent-browser": "^3.972.10", + "@aws-sdk/util-user-agent-node": "^3.973.21", + "@smithy/config-resolver": "^4.4.17", + "@smithy/core": "^3.23.17", + "@smithy/fetch-http-handler": "^5.3.17", + "@smithy/hash-node": "^4.2.14", + "@smithy/invalid-dependency": "^4.2.14", + "@smithy/middleware-content-length": "^4.2.14", + "@smithy/middleware-endpoint": "^4.4.32", + "@smithy/middleware-retry": "^4.5.5", + "@smithy/middleware-serde": "^4.2.20", + "@smithy/middleware-stack": "^4.2.14", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/node-http-handler": "^4.6.1", + "@smithy/protocol-http": "^5.3.14", + "@smithy/smithy-client": "^4.12.13", + "@smithy/types": "^4.14.1", + "@smithy/url-parser": "^4.2.14", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-body-length-browser": "^4.2.2", + "@smithy/util-body-length-node": "^4.2.3", + "@smithy/util-defaults-mode-browser": "^4.3.49", + "@smithy/util-defaults-mode-node": "^4.2.54", + "@smithy/util-endpoints": "^3.4.2", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-retry": "^4.3.4", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/region-config-resolver": { + "version": "3.972.13", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.972.13.tgz", + "integrity": "sha512-CvJ2ZIjK/jVD/lbOpowBVElJyC1YxLTIJ13yM0AEo0t2v7swOzGjSA6lJGH+DwZXQhcjUjoYwc8bVYCX5MDr1A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.8", + "@smithy/config-resolver": "^4.4.17", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/signature-v4-multi-region": { + "version": "3.996.22", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.22.tgz", + "integrity": "sha512-/rXhMXteD+BqhFd0nYprAgcZ/KtU+963uftPqd3tiFcFfooHZINXUGtOmo2SQjRVauCTNqIEzkwuSETdZFqTTA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/middleware-sdk-s3": "^3.972.34", + "@aws-sdk/types": "^3.973.8", + "@smithy/protocol-http": "^5.3.14", + "@smithy/signature-v4": "^5.3.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/token-providers": { + "version": "3.1036.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1036.0.tgz", + "integrity": "sha512-aNSJ6jjDYayxN9ZA1JpycVScX93Lx03kKZ1EXt3DGOTahcWVLJj3oLAlop0xKP+vP2Ga2t49p1tEaMkTbCCaZA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.974.5", + "@aws-sdk/nested-clients": "^3.997.3", + "@aws-sdk/types": "^3.973.8", + "@smithy/property-provider": "^4.2.14", + "@smithy/shared-ini-file-loader": "^4.4.9", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/types": { + "version": "3.973.8", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.8.tgz", + "integrity": "sha512-gjlAdtHMbtR9X5iIhVUvbVcy55KnznpC6bkDUWW9z915bi0ckdUr5cjf16Kp6xq0bP5HBD2xzgbL9F9Quv5vUw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/util-arn-parser": { + "version": "3.972.3", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-arn-parser/-/util-arn-parser-3.972.3.tgz", + "integrity": "sha512-HzSD8PMFrvgi2Kserxuff5VitNq2sgf3w9qxmskKDiDTThWfVteJxuCS9JXiPIPtmCrp+7N9asfIaVhBFORllA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/util-endpoints": { + "version": "3.996.8", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.996.8.tgz", + "integrity": "sha512-oOZHcRDihk5iEe5V25NVWg45b3qEA8OpHWVdU/XQh8Zj4heVPAJqWvMphQnU7LkufmUo10EpvFPZuQMiFLJK3g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.8", + "@smithy/types": "^4.14.1", + "@smithy/url-parser": "^4.2.14", + "@smithy/util-endpoints": "^3.4.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/util-locate-window": { + "version": "3.965.5", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.965.5.tgz", + "integrity": "sha512-WhlJNNINQB+9qtLtZJcpQdgZw3SCDCpXdUJP7cToGwHbCWCnRckGlc6Bx/OhWwIYFNAn+FIydY8SZ0QmVu3xTQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/util-user-agent-browser": { + "version": "3.972.10", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.972.10.tgz", + "integrity": "sha512-FAzqXvfEssGdSIz8ejatan0bOdx1qefBWKF/gWmVBXIP1HkS7v/wjjaqrAGGKvyihrXTXW00/2/1nTJtxpXz7g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.8", + "@smithy/types": "^4.14.1", + "bowser": "^2.11.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-sdk/util-user-agent-node": { + "version": "3.973.21", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.973.21.tgz", + "integrity": "sha512-Av4UHTcAWgdvbN0IP9pbtf4Qa1+6LtJqQdZWj5pLn5J67w0pnJJAZZ+7JPPcj2KN3378zD2JDM9DwJKEyvyMTQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/middleware-user-agent": "^3.972.35", + "@aws-sdk/types": "^3.973.8", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/types": "^4.14.1", + "@smithy/util-config-provider": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "aws-crt": ">=1.0.0" + }, + "peerDependenciesMeta": { + "aws-crt": { + "optional": true + } + } + }, + "node_modules/@aws-sdk/util-utf8-browser": { + "version": "3.259.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz", + "integrity": "sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.3.1" + } + }, + "node_modules/@aws-sdk/xml-builder": { + "version": "3.972.19", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.19.tgz", + "integrity": "sha512-Cw8IOMdBUEIl8ZlhRC3Dc/E64D5B5/8JhV6vhPLiPfJwcRC84S6F8aBOIi/N4vR9ZyA4I5Cc0Ateb/9EHaJXeQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1", + "fast-xml-parser": "5.7.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws/lambda-invoke-store": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@aws/lambda-invoke-store/-/lambda-invoke-store-0.2.4.tgz", + "integrity": "sha512-iY8yvjE0y651BixKNPgmv1WrQc+GZ142sb0z4gYnChDDY2YqI4P/jsSopBWrKfAt7LOJAkOXt7rC/hms+WclQQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/highlight": "^7.10.4" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.9.tgz", + "integrity": "sha512-llL88JShoCsth8fF8R4SJnIn+WLvR6ccFxu1H3FlMhDontdcmZWf2HgIZ7AIqV3Xcck1idlohrN4EUBQz6klbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bytecodealliance/preview2-shim": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@bytecodealliance/preview2-shim/-/preview2-shim-0.17.0.tgz", + "integrity": "sha512-JorcEwe4ud0x5BS/Ar2aQWOQoFzjq/7jcnxYXCvSMh0oRm0dQXzOA+hqLDBnOMks1LLBA7dmiLLsEBl09Yd6iQ==", + "dev": true, + "license": "(Apache-2.0 WITH LLVM-exception)" + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@databeat/tracker": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/@databeat/tracker/-/tracker-0.9.3.tgz", + "integrity": "sha512-eGsiNU/CRFujcNtUUqvBiqveCs6S6SiAhalXPDodbk74d3FzvLqHDn5k6WfOEJIhrP3CbYgfMXL0nk51s/rQsg==", + "license": "Apache 2.0", + "dependencies": { + "@noble/hashes": "^1.5.0" + } + }, + "node_modules/@databeat/tracker/node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@ensdomains/ens": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/@ensdomains/ens/-/ens-0.4.5.tgz", + "integrity": "sha512-JSvpj1iNMFjK6K+uVl4unqMoa9rf5jopb8cya5UGBWz23Nw8hSNT7efgUx4BTlAPAgpNlEioUfeTyQ6J9ZvTVw==", + "deprecated": "Please use @ensdomains/ens-contracts", + "dev": true, + "license": "CC0-1.0", + "peer": true, + "dependencies": { + "bluebird": "^3.5.2", + "eth-ens-namehash": "^2.0.8", + "solc": "^0.4.20", + "testrpc": "0.0.1", + "web3-utils": "^1.0.0-beta.31" + } + }, + "node_modules/@ensdomains/resolver": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@ensdomains/resolver/-/resolver-0.2.4.tgz", + "integrity": "sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA==", + "deprecated": "Please use @ensdomains/ens-contracts", + "dev": true, + "peer": true + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", + "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "9.39.2", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz", + "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@ethereum-waffle/chai": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/@ethereum-waffle/chai/-/chai-4.0.10.tgz", + "integrity": "sha512-X5RepE7Dn8KQLFO7HHAAe+KeGaX/by14hn90wePGBhzL54tq4Y8JscZFu+/LCwCl6TnkAAy5ebiMoqJ37sFtWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ethereum-waffle/provider": "4.0.5", + "debug": "^4.3.4", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=10.0" + }, + "peerDependencies": { + "ethers": "*" + } + }, + "node_modules/@ethereum-waffle/compiler": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@ethereum-waffle/compiler/-/compiler-4.0.3.tgz", + "integrity": "sha512-5x5U52tSvEVJS6dpCeXXKvRKyf8GICDwiTwUvGD3/WD+DpvgvaoHOL82XqpTSUHgV3bBq6ma5/8gKUJUIAnJCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@resolver-engine/imports": "^0.3.3", + "@resolver-engine/imports-fs": "^0.3.3", + "@typechain/ethers-v5": "^10.0.0", + "@types/mkdirp": "^0.5.2", + "@types/node-fetch": "^2.6.1", + "mkdirp": "^0.5.1", + "node-fetch": "^2.6.7" + }, + "engines": { + "node": ">=10.0" + }, + "peerDependencies": { + "ethers": "*", + "solc": "*", + "typechain": "^8.0.0" + } + }, + "node_modules/@ethereum-waffle/compiler/node_modules/@typechain/ethers-v5": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/@typechain/ethers-v5/-/ethers-v5-10.2.1.tgz", + "integrity": "sha512-n3tQmCZjRE6IU4h6lqUGiQ1j866n5MTCBJreNEHHVWXa2u9GJTaeYyU1/k+1qLutkyw+sS6VAN+AbeiTqsxd/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash": "^4.17.15", + "ts-essentials": "^7.0.1" + }, + "peerDependencies": { + "@ethersproject/abi": "^5.0.0", + "@ethersproject/providers": "^5.0.0", + "ethers": "^5.1.3", + "typechain": "^8.1.1", + "typescript": ">=4.3.0" + } + }, + "node_modules/@ethereum-waffle/ens": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@ethereum-waffle/ens/-/ens-4.0.3.tgz", + "integrity": "sha512-PVLcdnTbaTfCrfSOrvtlA9Fih73EeDvFS28JQnT5M5P4JMplqmchhcZB1yg/fCtx4cvgHlZXa0+rOCAk2Jk0Jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0" + }, + "peerDependencies": { + "@ensdomains/ens": "^0.4.4", + "@ensdomains/resolver": "^0.2.4", + "ethers": "*" + } + }, + "node_modules/@ethereum-waffle/mock-contract": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@ethereum-waffle/mock-contract/-/mock-contract-4.0.4.tgz", + "integrity": "sha512-LwEj5SIuEe9/gnrXgtqIkWbk2g15imM/qcJcxpLyAkOj981tQxXmtV4XmQMZsdedEsZ/D/rbUAOtZbgwqgUwQA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0" + }, + "peerDependencies": { + "ethers": "*" + } + }, + "node_modules/@ethereum-waffle/provider": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@ethereum-waffle/provider/-/provider-4.0.5.tgz", + "integrity": "sha512-40uzfyzcrPh+Gbdzv89JJTMBlZwzya1YLDyim8mVbEqYLP5VRYWoGp0JMyaizgV3hMoUFRqJKVmIUw4v7r3hYw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ethereum-waffle/ens": "4.0.3", + "@ganache/ethereum-options": "0.1.4", + "debug": "^4.3.4", + "ganache": "7.4.3" + }, + "engines": { + "node": ">=10.0" + }, + "peerDependencies": { + "ethers": "*" + } + }, + "node_modules/@ethereumjs/block": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/@ethereumjs/block/-/block-3.6.3.tgz", + "integrity": "sha512-CegDeryc2DVKnDkg5COQrE0bJfw/p0v3GBk2W5/Dj5dOVfEmb50Ux0GLnSPypooLnfqjwFaorGuT9FokWB3GRg==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@ethereumjs/common": "^2.6.5", + "@ethereumjs/tx": "^3.5.2", + "ethereumjs-util": "^7.1.5", + "merkle-patricia-tree": "^4.2.4" + } + }, + "node_modules/@ethereumjs/blockchain": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/@ethereumjs/blockchain/-/blockchain-5.5.3.tgz", + "integrity": "sha512-bi0wuNJ1gw4ByNCV56H0Z4Q7D+SxUbwyG12Wxzbvqc89PXLRNR20LBcSUZRKpN0+YCPo6m0XZL/JLio3B52LTw==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@ethereumjs/block": "^3.6.2", + "@ethereumjs/common": "^2.6.4", + "@ethereumjs/ethash": "^1.1.0", + "debug": "^4.3.3", + "ethereumjs-util": "^7.1.5", + "level-mem": "^5.0.1", + "lru-cache": "^5.1.1", + "semaphore-async-await": "^1.5.1" + } + }, + "node_modules/@ethereumjs/common": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.5.tgz", + "integrity": "sha512-lRyVQOeCDaIVtgfbowla32pzeDv2Obr8oR8Put5RdUBNRGr1VGPGQNGP6elWIpgK3YdpzqTOh4GyUGOureVeeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "crc-32": "^1.2.0", + "ethereumjs-util": "^7.1.5" + } + }, + "node_modules/@ethereumjs/ethash": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/ethash/-/ethash-1.1.0.tgz", + "integrity": "sha512-/U7UOKW6BzpA+Vt+kISAoeDie1vAvY4Zy2KF5JJb+So7+1yKmJeJEHOGSnQIj330e9Zyl3L5Nae6VZyh2TJnAA==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@ethereumjs/block": "^3.5.0", + "@types/levelup": "^4.3.0", + "buffer-xor": "^2.0.1", + "ethereumjs-util": "^7.1.1", + "miller-rabin": "^4.0.0" + } + }, + "node_modules/@ethereumjs/ethash/node_modules/buffer-xor": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-2.0.2.tgz", + "integrity": "sha512-eHslX0bin3GB+Lx2p7lEYRShRewuNZL3fUl4qlVJGGiwoPGftmt8JQgk2Y9Ji5/01TnVDo33E5b5O3vUB1HdqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.1" + } + }, + "node_modules/@ethereumjs/rlp": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-5.0.2.tgz", + "integrity": "sha512-DziebCdg4JpGlEqEdGgXmjqcFoJi+JGulUXwEjsZGAscAQ7MyD/7LE/GVCP29vEQxKc7AAwjT3A2ywHp2xfoCA==", + "dev": true, + "license": "MPL-2.0", + "bin": { + "rlp": "bin/rlp.cjs" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@ethereumjs/tx": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.5.2.tgz", + "integrity": "sha512-gQDNJWKrSDGu2w7w0PzVXVBNMzb7wwdDOmOqczmhNjqFxFuIbhVJDwiGEnxFNC2/b8ifcZzY7MLcluizohRzNw==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@ethereumjs/common": "^2.6.4", + "ethereumjs-util": "^7.1.5" + } + }, + "node_modules/@ethereumjs/util": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/util/-/util-9.1.0.tgz", + "integrity": "sha512-XBEKsYqLGXLah9PNJbgdkigthkG7TAGvlD/sH12beMXEyHDyigfcbdvHhmLyDWgDyOJn4QwiQUaF7yeuhnjdog==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@ethereumjs/rlp": "^5.0.2", + "ethereum-cryptography": "^2.2.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@ethereumjs/util/node_modules/@noble/curves": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", + "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@ethereumjs/util/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@ethereumjs/util/node_modules/ethereum-cryptography": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", + "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/curves": "1.4.2", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.3.0" + } + }, + "node_modules/@ethereumjs/vm": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/vm/-/vm-5.6.0.tgz", + "integrity": "sha512-J2m/OgjjiGdWF2P9bj/4LnZQ1zRoZhY8mRNVw/N3tXliGI8ai1sI1mlDPkLpeUUM4vq54gH6n0ZlSpz8U/qlYQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@ethereumjs/block": "^3.6.0", + "@ethereumjs/blockchain": "^5.5.0", + "@ethereumjs/common": "^2.6.0", + "@ethereumjs/tx": "^3.4.0", + "async-eventemitter": "^0.2.4", + "core-js-pure": "^3.0.1", + "debug": "^2.2.0", + "ethereumjs-util": "^7.1.3", + "functional-red-black-tree": "^1.0.1", + "mcl-wasm": "^0.7.1", + "merkle-patricia-tree": "^4.2.2", + "rustbn.js": "~0.2.0" + } + }, + "node_modules/@ethereumjs/vm/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/@ethereumjs/vm/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@ethersproject/abi": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.8.0.tgz", + "integrity": "sha512-b9YS/43ObplgyV6SlyQsG53/vkSal0MNA1fskSC4mbnCMi8R+NkcH8K9FPYNESf6jUefBUniE4SOKms0E/KK1Q==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/address": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/hash": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" + } + }, + "node_modules/@ethersproject/abstract-provider": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.8.0.tgz", + "integrity": "sha512-wC9SFcmh4UK0oKuLJQItoQdzS/qZ51EJegK6EmAWlh+OptpQ/npECOR3QqECd8iGHC0RJb4WKbVdSfif4ammrg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/networks": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/transactions": "^5.8.0", + "@ethersproject/web": "^5.8.0" + } + }, + "node_modules/@ethersproject/abstract-signer": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.8.0.tgz", + "integrity": "sha512-N0XhZTswXcmIZQdYtUnd79VJzvEwXQw6PK0dTl9VoYrEBxxCPXqS0Eod7q5TNKRxe1/5WUMuR0u0nqTF/avdCA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-provider": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0" + } + }, + "node_modules/@ethersproject/address": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.8.0.tgz", + "integrity": "sha512-GhH/abcC46LJwshoN+uBNoKVFPxUuZm6dA257z0vZkKmU1+t8xTn8oK7B9qrj8W2rFRMch4gbJl6PmVxjxBEBA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/rlp": "^5.8.0" + } + }, + "node_modules/@ethersproject/base64": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.8.0.tgz", + "integrity": "sha512-lN0oIwfkYj9LbPx4xEkie6rAMJtySbpOAFXSDVQaBnAzYfB4X2Qr+FXJGxMoc3Bxp2Sm8OwvzMrywxyw0gLjIQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0" + } + }, + "node_modules/@ethersproject/basex": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.8.0.tgz", + "integrity": "sha512-PIgTszMlDRmNwW9nhS6iqtVfdTAKosA7llYXNmGPw4YAI1PUyMv28988wAb41/gHF/WqGdoLv0erHaRcHRKW2Q==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/properties": "^5.8.0" + } + }, + "node_modules/@ethersproject/bignumber": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.8.0.tgz", + "integrity": "sha512-ZyaT24bHaSeJon2tGPKIiHszWjD/54Sz8t57Toch475lCLljC6MgPmxk7Gtzz+ddNN5LuHea9qhAe0x3D+uYPA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "bn.js": "^5.2.1" + } + }, + "node_modules/@ethersproject/bytes": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.8.0.tgz", + "integrity": "sha512-vTkeohgJVCPVHu5c25XWaWQOZ4v+DkGoC42/TS2ond+PARCxTJvgTFUNDZovyQ/uAQ4EcpqqowKydcdmRKjg7A==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/@ethersproject/constants": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.8.0.tgz", + "integrity": "sha512-wigX4lrf5Vu+axVTIvNsuL6YrV4O5AXl5ubcURKMEME5TnWBouUh0CDTWxZ2GpnRn1kcCgE7l8O5+VbV9QTTcg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.8.0" + } + }, + "node_modules/@ethersproject/contracts": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.8.0.tgz", + "integrity": "sha512-0eFjGz9GtuAi6MZwhb4uvUM216F38xiuR0yYCjKJpNfSEy4HUM8hvqqBj9Jmm0IUz8l0xKEhWwLIhPgxNY0yvQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abi": "^5.8.0", + "@ethersproject/abstract-provider": "^5.8.0", + "@ethersproject/abstract-signer": "^5.8.0", + "@ethersproject/address": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/transactions": "^5.8.0" + } + }, + "node_modules/@ethersproject/hash": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.8.0.tgz", + "integrity": "sha512-ac/lBcTbEWW/VGJij0CNSw/wPcw9bSRgCB0AIBz8CvED/jfvDoV9hsIIiWfvWmFEi8RcXtlNwp2jv6ozWOsooA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-signer": "^5.8.0", + "@ethersproject/address": "^5.8.0", + "@ethersproject/base64": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" + } + }, + "node_modules/@ethersproject/hdnode": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.8.0.tgz", + "integrity": "sha512-4bK1VF6E83/3/Im0ERnnUeWOY3P1BZml4ZD3wcH8Ys0/d1h1xaFt6Zc+Dh9zXf9TapGro0T4wvO71UTCp3/uoA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-signer": "^5.8.0", + "@ethersproject/basex": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/pbkdf2": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/sha2": "^5.8.0", + "@ethersproject/signing-key": "^5.8.0", + "@ethersproject/strings": "^5.8.0", + "@ethersproject/transactions": "^5.8.0", + "@ethersproject/wordlists": "^5.8.0" + } + }, + "node_modules/@ethersproject/json-wallets": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.8.0.tgz", + "integrity": "sha512-HxblNck8FVUtNxS3VTEYJAcwiKYsBIF77W15HufqlBF9gGfhmYOJtYZp8fSDZtn9y5EaXTE87zDwzxRoTFk11w==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-signer": "^5.8.0", + "@ethersproject/address": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/hdnode": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/pbkdf2": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/random": "^5.8.0", + "@ethersproject/strings": "^5.8.0", + "@ethersproject/transactions": "^5.8.0", + "aes-js": "3.0.0", + "scrypt-js": "3.0.1" + } + }, + "node_modules/@ethersproject/json-wallets/node_modules/aes-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", + "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", + "license": "MIT" + }, + "node_modules/@ethersproject/keccak256": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.8.0.tgz", + "integrity": "sha512-A1pkKLZSz8pDaQ1ftutZoaN46I6+jvuqugx5KYNeQOPqq+JZ0Txm7dlWesCHB5cndJSu5vP2VKptKf7cksERng==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/@ethersproject/logger": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.8.0.tgz", + "integrity": "sha512-Qe6knGmY+zPPWTC+wQrpitodgBfH7XoceCGL5bJVejmH+yCS3R8jJm8iiWuvWbG76RUmyEG53oqv6GMVWqunjA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT" + }, + "node_modules/@ethersproject/networks": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.8.0.tgz", + "integrity": "sha512-egPJh3aPVAzbHwq8DD7Po53J4OUSsA1MjQp8Vf/OZPav5rlmWUaFLiq8cvQiGK0Z5K6LYzm29+VA/p4RL1FzNg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/@ethersproject/pbkdf2": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.8.0.tgz", + "integrity": "sha512-wuHiv97BrzCmfEaPbUFpMjlVg/IDkZThp9Ri88BpjRleg4iePJaj2SW8AIyE8cXn5V1tuAaMj6lzvsGJkGWskg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/sha2": "^5.8.0" + } + }, + "node_modules/@ethersproject/properties": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.8.0.tgz", + "integrity": "sha512-PYuiEoQ+FMaZZNGrStmN7+lWjlsoufGIHdww7454FIaGdbe/p5rnaCXTr5MtBYl3NkeoVhHZuyzChPeGeKIpQw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/@ethersproject/providers": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.8.0.tgz", + "integrity": "sha512-3Il3oTzEx3o6kzcg9ZzbE+oCZYyY+3Zh83sKkn4s1DZfTUjIegHnN2Cm0kbn9YFy45FDVcuCLLONhU7ny0SsCw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-provider": "^5.8.0", + "@ethersproject/abstract-signer": "^5.8.0", + "@ethersproject/address": "^5.8.0", + "@ethersproject/base64": "^5.8.0", + "@ethersproject/basex": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/hash": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/networks": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/random": "^5.8.0", + "@ethersproject/rlp": "^5.8.0", + "@ethersproject/sha2": "^5.8.0", + "@ethersproject/strings": "^5.8.0", + "@ethersproject/transactions": "^5.8.0", + "@ethersproject/web": "^5.8.0", + "bech32": "1.1.4", + "ws": "8.18.0" + } + }, + "node_modules/@ethersproject/providers/node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/@ethersproject/random": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.8.0.tgz", + "integrity": "sha512-E4I5TDl7SVqyg4/kkA/qTfuLWAQGXmSOgYyO01So8hLfwgKvYK5snIlzxJMk72IFdG/7oh8yuSqY2KX7MMwg+A==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/@ethersproject/rlp": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.8.0.tgz", + "integrity": "sha512-LqZgAznqDbiEunaUvykH2JAoXTT9NV0Atqk8rQN9nx9SEgThA/WMx5DnW8a9FOufo//6FZOCHZ+XiClzgbqV9Q==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/@ethersproject/sha2": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.8.0.tgz", + "integrity": "sha512-dDOUrXr9wF/YFltgTBYS0tKslPEKr6AekjqDW2dbn1L1xmjGR+9GiKu4ajxovnrDbwxAKdHjW8jNcwfz8PAz4A==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/signing-key": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.8.0.tgz", + "integrity": "sha512-LrPW2ZxoigFi6U6aVkFN/fa9Yx/+4AtIUe4/HACTvKJdhm0eeb107EVCIQcrLZkxaSIgc/eCrX8Q1GtbH+9n3w==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "bn.js": "^5.2.1", + "elliptic": "6.6.1", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/solidity": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.8.0.tgz", + "integrity": "sha512-4CxFeCgmIWamOHwYN9d+QWGxye9qQLilpgTU0XhYs1OahkclF+ewO+3V1U0mvpiuQxm5EHHmv8f7ClVII8EHsA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/sha2": "^5.8.0", + "@ethersproject/strings": "^5.8.0" + } + }, + "node_modules/@ethersproject/strings": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.8.0.tgz", + "integrity": "sha512-qWEAk0MAvl0LszjdfnZ2uC8xbR2wdv4cDabyHiBh3Cldq/T8dPH3V4BbBsAYJUeonwD+8afVXld274Ls+Y1xXg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/@ethersproject/transactions": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.8.0.tgz", + "integrity": "sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/address": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/rlp": "^5.8.0", + "@ethersproject/signing-key": "^5.8.0" + } + }, + "node_modules/@ethersproject/units": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.8.0.tgz", + "integrity": "sha512-lxq0CAnc5kMGIiWW4Mr041VT8IhNM+Pn5T3haO74XZWFulk7wH1Gv64HqE96hT4a7iiNMdOCFEBgaxWuk8ETKQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/@ethersproject/wallet": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.8.0.tgz", + "integrity": "sha512-G+jnzmgg6UxurVKRKvw27h0kvG75YKXZKdlLYmAHeF32TGUzHkOFd7Zn6QHOTYRFWnfjtSSFjBowKo7vfrXzPA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abstract-provider": "^5.8.0", + "@ethersproject/abstract-signer": "^5.8.0", + "@ethersproject/address": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/hash": "^5.8.0", + "@ethersproject/hdnode": "^5.8.0", + "@ethersproject/json-wallets": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/random": "^5.8.0", + "@ethersproject/signing-key": "^5.8.0", + "@ethersproject/transactions": "^5.8.0", + "@ethersproject/wordlists": "^5.8.0" + } + }, + "node_modules/@ethersproject/web": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.8.0.tgz", + "integrity": "sha512-j7+Ksi/9KfGviws6Qtf9Q7KCqRhpwrYKQPs+JBA/rKVFF/yaWLHJEH3zfVP2plVu+eys0d2DlFmhoQJayFewcw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/base64": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" + } + }, + "node_modules/@ethersproject/wordlists": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.8.0.tgz", + "integrity": "sha512-2df9bbXicZws2Sb5S6ET493uJ0Z84Fjr3pC4tu/qlnZERibZCeUVuqdtt+7Tv9xxhUxHoIekIA7avrKUWHrezg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/hash": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" + } + }, + "node_modules/@fastify/busboy": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", + "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/@ganache/ethereum-address": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@ganache/ethereum-address/-/ethereum-address-0.1.4.tgz", + "integrity": "sha512-sTkU0M9z2nZUzDeHRzzGlW724xhMLXo2LeX1hixbnjHWY1Zg1hkqORywVfl+g5uOO8ht8T0v+34IxNxAhmWlbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ganache/utils": "0.1.4" + } + }, + "node_modules/@ganache/ethereum-options": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@ganache/ethereum-options/-/ethereum-options-0.1.4.tgz", + "integrity": "sha512-i4l46taoK2yC41FPkcoDlEVoqHS52wcbHPqJtYETRWqpOaoj9hAg/EJIHLb1t6Nhva2CdTO84bG+qlzlTxjAHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ganache/ethereum-address": "0.1.4", + "@ganache/ethereum-utils": "0.1.4", + "@ganache/options": "0.1.4", + "@ganache/utils": "0.1.4", + "bip39": "3.0.4", + "seedrandom": "3.0.5" + } + }, + "node_modules/@ganache/ethereum-utils": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@ganache/ethereum-utils/-/ethereum-utils-0.1.4.tgz", + "integrity": "sha512-FKXF3zcdDrIoCqovJmHLKZLrJ43234Em2sde/3urUT/10gSgnwlpFmrv2LUMAmSbX3lgZhW/aSs8krGhDevDAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ethereumjs/common": "2.6.0", + "@ethereumjs/tx": "3.4.0", + "@ethereumjs/vm": "5.6.0", + "@ganache/ethereum-address": "0.1.4", + "@ganache/rlp": "0.1.4", + "@ganache/utils": "0.1.4", + "emittery": "0.10.0", + "ethereumjs-abi": "0.6.8", + "ethereumjs-util": "7.1.3" + } + }, + "node_modules/@ganache/ethereum-utils/node_modules/@ethereumjs/common": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.0.tgz", + "integrity": "sha512-Cq2qS0FTu6O2VU1sgg+WyU9Ps0M6j/BEMHN+hRaECXCV/r0aI78u4N6p52QW/BDVhwWZpCdrvG8X7NJdzlpNUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "crc-32": "^1.2.0", + "ethereumjs-util": "^7.1.3" + } + }, + "node_modules/@ganache/ethereum-utils/node_modules/@ethereumjs/tx": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.4.0.tgz", + "integrity": "sha512-WWUwg1PdjHKZZxPPo274ZuPsJCWV3SqATrEKQP1n2DrVYVP1aZIYpo/mFaA0BDoE0tIQmBeimRCEA0Lgil+yYw==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@ethereumjs/common": "^2.6.0", + "ethereumjs-util": "^7.1.3" + } + }, + "node_modules/@ganache/ethereum-utils/node_modules/ethereumjs-util": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.3.tgz", + "integrity": "sha512-y+82tEbyASO0K0X1/SRhbJJoAlfcvq8JbrG4a5cjrOks7HS/36efU/0j2flxCPOUM++HFahk33kr/ZxyC4vNuw==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@types/bn.js": "^5.1.0", + "bn.js": "^5.1.2", + "create-hash": "^1.1.2", + "ethereum-cryptography": "^0.1.3", + "rlp": "^2.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@ganache/options": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@ganache/options/-/options-0.1.4.tgz", + "integrity": "sha512-zAe/craqNuPz512XQY33MOAG6Si1Xp0hCvfzkBfj2qkuPcbJCq6W/eQ5MB6SbXHrICsHrZOaelyqjuhSEmjXRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ganache/utils": "0.1.4", + "bip39": "3.0.4", + "seedrandom": "3.0.5" + } + }, + "node_modules/@ganache/rlp": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@ganache/rlp/-/rlp-0.1.4.tgz", + "integrity": "sha512-Do3D1H6JmhikB+6rHviGqkrNywou/liVeFiKIpOBLynIpvZhRCgn3SEDxyy/JovcaozTo/BynHumfs5R085MFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ganache/utils": "0.1.4", + "rlp": "2.2.6" + } + }, + "node_modules/@ganache/rlp/node_modules/bn.js": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", + "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@ganache/rlp/node_modules/rlp": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.6.tgz", + "integrity": "sha512-HAfAmL6SDYNWPUOJNrM500x4Thn4PZsEy5pijPh40U9WfNk0z15hUYzO9xVIMAdIHdFtD8CBDHd75Td1g36Mjg==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^4.11.1" + }, + "bin": { + "rlp": "bin/rlp" + } + }, + "node_modules/@ganache/utils": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@ganache/utils/-/utils-0.1.4.tgz", + "integrity": "sha512-oatUueU3XuXbUbUlkyxeLLH3LzFZ4y5aSkNbx6tjSIhVTPeh+AuBKYt4eQ73FFcTB3nj/gZoslgAh5CN7O369w==", + "dev": true, + "license": "MIT", + "dependencies": { + "emittery": "0.10.0", + "keccak": "3.0.1", + "seedrandom": "3.0.5" + }, + "optionalDependencies": { + "@trufflesuite/bigint-buffer": "1.1.9" + } + }, + "node_modules/@ganache/utils/node_modules/keccak": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.1.tgz", + "integrity": "sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@noble/curves": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", + "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.3.2" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/secp256k1": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.7.1.tgz", + "integrity": "sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT" + }, + "node_modules/@nodable/entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-nyT7T3nbMyBI/lvr6L5TyWbFJAI9FTgVRakNoBqCD+PmID8DzFrrNdLLtHMwMszOtqZa8PAOV24ZqDnQrhQINA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/nodable" + } + ], + "license": "MIT" + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nomicfoundation/edr": { + "version": "0.12.0-next.15", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr/-/edr-0.12.0-next.15.tgz", + "integrity": "sha512-JMLvnro2cxSq1h/A2WYo018o5R4ns7ut/A6WoiBfXKDj/OSN8mRnEpDaICIrk6fopbAfMi6MmP8TQefDs+lKAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nomicfoundation/edr-darwin-arm64": "0.12.0-next.15", + "@nomicfoundation/edr-darwin-x64": "0.12.0-next.15", + "@nomicfoundation/edr-linux-arm64-gnu": "0.12.0-next.15", + "@nomicfoundation/edr-linux-arm64-musl": "0.12.0-next.15", + "@nomicfoundation/edr-linux-x64-gnu": "0.12.0-next.15", + "@nomicfoundation/edr-linux-x64-musl": "0.12.0-next.15", + "@nomicfoundation/edr-win32-x64-msvc": "0.12.0-next.15" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@nomicfoundation/edr-darwin-arm64": { + "version": "0.12.0-next.15", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.12.0-next.15.tgz", + "integrity": "sha512-y/Z7fOaPxLzYTFDwWE/s4TIxvgq2cQhs6HKKh7+aJSQ6RxKrja5iKQEWg3D71jtgwizhGQpFQHtYXxmzWAjwyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20" + } + }, + "node_modules/@nomicfoundation/edr-darwin-x64": { + "version": "0.12.0-next.15", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.12.0-next.15.tgz", + "integrity": "sha512-hLDkDmtxOyUnlf1Mem6S8TKjCZh6yiWSA8kasqq7HSDa1/QmJou5eY1zFbw2xBky3StEUx5vfn3NpgBHTOCSBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20" + } + }, + "node_modules/@nomicfoundation/edr-linux-arm64-gnu": { + "version": "0.12.0-next.15", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.12.0-next.15.tgz", + "integrity": "sha512-+cHxrjLG3ILNj4+bRQ4uRBVfeCEhYYIqteZjiyryB2UXzyUJHaEqCRVxxJpiqzpsXTpTgVAsEuwYwERgT/1a5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20" + } + }, + "node_modules/@nomicfoundation/edr-linux-arm64-musl": { + "version": "0.12.0-next.15", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.12.0-next.15.tgz", + "integrity": "sha512-ppGDxVbGofWYkiFw8NrE+JlhNE39FTCXzvE586ZBaUqV3TMDcwnTkDltxzbl5YPmhNp3Qne3pJfJ0NB330Js+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20" + } + }, + "node_modules/@nomicfoundation/edr-linux-x64-gnu": { + "version": "0.12.0-next.15", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.12.0-next.15.tgz", + "integrity": "sha512-ifOr9sAuBbnJpZtGYtFkEkwTXBsM9pT9tq7KXT3eOYBWw3TJIsP3DfnTgYF+pZObxBFyBtMJnyy0j1ItL+s9rg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20" + } + }, + "node_modules/@nomicfoundation/edr-linux-x64-musl": { + "version": "0.12.0-next.15", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.12.0-next.15.tgz", + "integrity": "sha512-Jc0HZZOJAcPjxj3FbgtWQQGe6OmI6xiblFBAmXUGothxTZ3rn1YZeHqXews9MEjL8MCvHvfAjfLRkafSyyXX2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20" + } + }, + "node_modules/@nomicfoundation/edr-win32-x64-msvc": { + "version": "0.12.0-next.15", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.12.0-next.15.tgz", + "integrity": "sha512-TFbhcY1J+IRB4nVwXAvw/a5gy3o7+AQ83vfxT3Sk/z4Kk6v3c6Xkizy6IY6vTtpSWWmiuAh998QYq8D7LHIc3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20" + } + }, + "node_modules/@nomicfoundation/hardhat-errors": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-errors/-/hardhat-errors-3.0.5.tgz", + "integrity": "sha512-8Ayqf6hFM1glmrSxrXgX6n2pn5uTlHNxEB8N5Me0DOeOGB67PRIrQdiO+RzUhrNW5YgWUNWBevOLQbW06uQ79g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nomicfoundation/hardhat-utils": "^3.0.1" + } + }, + "node_modules/@nomicfoundation/hardhat-ethers": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ethers/-/hardhat-ethers-4.0.3.tgz", + "integrity": "sha512-DtYjmHtPM1BenmNm5ZMVn5fTGD4RdDPGE/ElpaLUjDGbkQnn4ytvhqnGsY+osLaWFvDxKfhdI8fyISg53bk8Qw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nomicfoundation/hardhat-errors": "^3.0.2", + "@nomicfoundation/hardhat-utils": "^3.0.5", + "debug": "^4.3.2", + "ethereum-cryptography": "^2.2.1", + "ethers": "^6.14.0" + }, + "peerDependencies": { + "hardhat": "^3.0.7" + } + }, + "node_modules/@nomicfoundation/hardhat-ethers/node_modules/@noble/curves": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", + "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@nomicfoundation/hardhat-ethers/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@nomicfoundation/hardhat-ethers/node_modules/ethereum-cryptography": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", + "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/curves": "1.4.2", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.3.0" + } + }, + "node_modules/@nomicfoundation/hardhat-utils": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-utils/-/hardhat-utils-3.0.5.tgz", + "integrity": "sha512-5zkQSuSxkwK7fQxKswJ1GGc/3AuWBSmxA7GhczTPLx28dAXQnubRU8nA48SkCkKesJq5x4TROP+XheSE2VkLUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@streamparser/json-node": "^0.0.22", + "debug": "^4.3.2", + "env-paths": "^2.2.0", + "ethereum-cryptography": "^2.2.1", + "fast-equals": "^5.0.1", + "json-stream-stringify": "^3.1.6", + "rfdc": "^1.3.1", + "undici": "^6.16.1" + } + }, + "node_modules/@nomicfoundation/hardhat-utils/node_modules/@noble/curves": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", + "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@nomicfoundation/hardhat-utils/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@nomicfoundation/hardhat-utils/node_modules/ethereum-cryptography": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", + "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/curves": "1.4.2", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.3.0" + } + }, + "node_modules/@nomicfoundation/hardhat-utils/node_modules/undici": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.22.0.tgz", + "integrity": "sha512-hU/10obOIu62MGYjdskASR3CUAiYaFTtC9Pa6vHyf//mAipSvSQg6od2CnJswq7fvzNS3zJhxoRkgNVaHurWKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, + "node_modules/@nomicfoundation/hardhat-verify": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-verify/-/hardhat-verify-3.0.7.tgz", + "integrity": "sha512-2Px2Zldg2oRJvy7odx8hZ0lZ4yjkW8XLr6umqcKl5z36+XifKRanzd8phoLEGQ8SRBNaVsaw0EDHi9Q0QTUu3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ethersproject/abi": "^5.8.0", + "@nomicfoundation/hardhat-errors": "^3.0.3", + "@nomicfoundation/hardhat-utils": "^3.0.5", + "@nomicfoundation/hardhat-zod-utils": "^3.0.0", + "cbor2": "^1.9.0", + "chalk": "^5.3.0", + "debug": "^4.3.2", + "semver": "^7.6.3", + "zod": "^3.23.8" + }, + "peerDependencies": { + "hardhat": "^3.0.0" + } + }, + "node_modules/@nomicfoundation/hardhat-verify/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@nomicfoundation/hardhat-verify/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@nomicfoundation/hardhat-zod-utils": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-zod-utils/-/hardhat-zod-utils-3.0.1.tgz", + "integrity": "sha512-I6/pyYiS9p2lLkzQuedr1ScMocH+ew8l233xTi+LP92gjEiviJDxselpkzgU01MUM0t6BPpfP8yMO958LDEJVg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nomicfoundation/hardhat-errors": "^3.0.0", + "@nomicfoundation/hardhat-utils": "^3.0.2" + }, + "peerDependencies": { + "zod": "^3.23.8" + } + }, + "node_modules/@nomicfoundation/ignition-core": { + "version": "0.15.14", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ignition-core/-/ignition-core-0.15.14.tgz", + "integrity": "sha512-BRgNaApHTdmk0NNTVYMltRXUFQGaWKHKnaaOyp9TG/BsUUkW3mH1ds5+rM4UBUIHivIyh3fKFDCOGJIJcQG9aw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ethersproject/address": "5.6.1", + "@nomicfoundation/solidity-analyzer": "^0.1.1", + "cbor": "^9.0.0", + "debug": "^4.3.2", + "ethers": "^6.14.0", + "fs-extra": "^10.0.0", + "immer": "10.0.2", + "lodash": "4.17.21", + "ndjson": "2.0.0" + } + }, + "node_modules/@nomicfoundation/ignition-core/node_modules/@ethersproject/address": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.6.1.tgz", + "integrity": "sha512-uOgF0kS5MJv9ZvCz7x6T2EXJSzotiybApn4XlOgoTX0xdtyVIJ7pF+6cGPxiEq/dpBiTfMiw7Yc81JcwhSYA0Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/keccak256": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/rlp": "^5.6.1" + } + }, + "node_modules/@nomicfoundation/ignition-core/node_modules/cbor": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/cbor/-/cbor-9.0.2.tgz", + "integrity": "sha512-JPypkxsB10s9QOWwa6zwPzqE1Md3vqpPc+cai4sAecuCsRyAtAl/pMyhPlMbT/xtPnm2dznJZYRLui57qiRhaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "nofilter": "^3.1.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@nomicfoundation/ignition-core/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@nomicfoundation/ignition-core/node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@nomicfoundation/ignition-core/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@nomicfoundation/ignition-ui": { + "version": "0.15.13", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ignition-ui/-/ignition-ui-0.15.13.tgz", + "integrity": "sha512-HbTszdN1iDHCkUS9hLeooqnLEW2U45FaqFwFEYT8nIno2prFZhG+n68JEERjmfFCB5u0WgbuJwk3CgLoqtSL7Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@nomicfoundation/slang": { + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@nomicfoundation/slang/-/slang-0.18.3.tgz", + "integrity": "sha512-YqAWgckqbHM0/CZxi9Nlf4hjk9wUNLC9ngWCWBiqMxPIZmzsVKYuChdlrfeBPQyvQQBoOhbx+7C1005kLVQDZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@bytecodealliance/preview2-shim": "0.17.0" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.2.tgz", + "integrity": "sha512-q4n32/FNKIhQ3zQGGw5CvPF6GTvDCpYwIf7bEY/dZTZbgfDsHyjJwURxUJf3VQuuJj+fDIFl4+KkBVbw4Ef6jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + }, + "optionalDependencies": { + "@nomicfoundation/solidity-analyzer-darwin-arm64": "0.1.2", + "@nomicfoundation/solidity-analyzer-darwin-x64": "0.1.2", + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": "0.1.2", + "@nomicfoundation/solidity-analyzer-linux-arm64-musl": "0.1.2", + "@nomicfoundation/solidity-analyzer-linux-x64-gnu": "0.1.2", + "@nomicfoundation/solidity-analyzer-linux-x64-musl": "0.1.2", + "@nomicfoundation/solidity-analyzer-win32-x64-msvc": "0.1.2" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-darwin-arm64": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.2.tgz", + "integrity": "sha512-JaqcWPDZENCvm++lFFGjrDd8mxtf+CtLd2MiXvMNTBD33dContTZ9TWETwNFwg7JTJT5Q9HEecH7FA+HTSsIUw==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-darwin-x64": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.2.tgz", + "integrity": "sha512-fZNmVztrSXC03e9RONBT+CiksSeYcxI1wlzqyr0L7hsQlK1fzV+f04g2JtQ1c/Fe74ZwdV6aQBdd6Uwl1052sw==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-gnu": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.2.tgz", + "integrity": "sha512-3d54oc+9ZVBuB6nbp8wHylk4xh0N0Gc+bk+/uJae+rUgbOBwQSfuGIbAZt1wBXs5REkSmynEGcqx6DutoK0tPA==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-musl": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.2.tgz", + "integrity": "sha512-iDJfR2qf55vgsg7BtJa7iPiFAsYf2d0Tv/0B+vhtnI16+wfQeTbP7teookbGvAo0eJo7aLLm0xfS/GTkvHIucA==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-x64-gnu": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.2.tgz", + "integrity": "sha512-9dlHMAt5/2cpWyuJ9fQNOUXFB/vgSFORg1jpjX1Mh9hJ/MfZXlDdHQ+DpFCs32Zk5pxRBb07yGvSHk9/fezL+g==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-x64-musl": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.2.tgz", + "integrity": "sha512-GzzVeeJob3lfrSlDKQw2bRJ8rBf6mEYaWY+gW0JnTDHINA0s2gPR4km5RLIj1xeZZOYz4zRw+AEeYgLRqB2NXg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-win32-x64-msvc": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.2.tgz", + "integrity": "sha512-Fdjli4DCcFHb4Zgsz0uEJXZ2K7VEO+w5KVv7HmT7WO10iODdU9csC2az4jrhEsRtiR9Gfd74FlG0NYlw1BMdyA==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomiclabs/hardhat-truffle5": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-truffle5/-/hardhat-truffle5-3.0.0.tgz", + "integrity": "sha512-hisTmBBKcUye5+XzFuWWcWLhs+KEIv9+hOwKAgB9fKfQgaa/0D11+u3M5KM5t5nKNgy9IJfv7zyiy99yncgufA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@nomiclabs/hardhat-web3": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-web3/-/hardhat-web3-2.1.2.tgz", + "integrity": "sha512-ChnUInQ5AES1iJSNXq00JfWfQZkVUIkkSt2dtrB/8r+CfW/XeBTkvE5G+OTJTVSMme7lgqk9aieOI7d6GU6v1g==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "hardhat": "^2.26.0", + "web3": "^1.0.0-beta.36" + } + }, + "node_modules/@npmcli/agent": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-2.2.2.tgz", + "integrity": "sha512-OrcNPXdpSl9UX7qPVRWbmWMCSXrcDa2M9DvrbOTj7ao1S4PlqVFYv9/yLKMkrJKZ/V5A/kDBC690or307i26Og==", + "dev": true, + "license": "ISC", + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.3" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/agent/node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/@npmcli/agent/node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@npmcli/agent/node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@npmcli/agent/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/@npmcli/agent/node_modules/socks": { + "version": "2.8.7", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz", + "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ip-address": "^10.0.1", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/@npmcli/agent/node_modules/socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@npmcli/fs": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.1.tgz", + "integrity": "sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==", + "dev": true, + "license": "ISC", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/fs/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@npmcli/redact": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-2.0.1.tgz", + "integrity": "sha512-YgsR5jCQZhVmTJvjduTOIHph0L73pK8xwMVaDY0PatySqVM9AZj93jpoXYSJqfHFxFkN9dmqTw6OiqExsS3LPw==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@openzeppelin/defender-sdk-base-client": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/defender-sdk-base-client/-/defender-sdk-base-client-2.7.0.tgz", + "integrity": "sha512-J5IpvbFfdIJM4IadBcXfhCXVdX2yEpaZtRR1ecq87d8CdkmmEpniYfef/yVlG98yekvu125LaIRg0yXQOt9Bdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@aws-sdk/client-lambda": "^3.563.0", + "amazon-cognito-identity-js": "^6.3.6", + "async-retry": "^1.3.3" + } + }, + "node_modules/@openzeppelin/defender-sdk-deploy-client": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/defender-sdk-deploy-client/-/defender-sdk-deploy-client-2.7.0.tgz", + "integrity": "sha512-YOHZmnHmM1y6uSqXWGfk2/5/ae4zZJE6xG92yFEAIOy8vqh1dxznWMsoCcAXRXTCWc8RdCDpFdMfEy4SBTyYtg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@openzeppelin/defender-sdk-base-client": "^2.7.0", + "axios": "^1.7.4", + "lodash": "^4.17.21" + } + }, + "node_modules/@openzeppelin/defender-sdk-network-client": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/defender-sdk-network-client/-/defender-sdk-network-client-2.7.0.tgz", + "integrity": "sha512-4CYWPa9+kSjojE5KS7kRmP161qsBATdp97TCrzyDdGoVahj0GyqgafRL9AAjm0eHZOM1c7EIYEpbvYRtFi8vyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@openzeppelin/defender-sdk-base-client": "^2.7.0", + "axios": "^1.7.4", + "lodash": "^4.17.21" + } + }, + "node_modules/@openzeppelin/upgrades-core": { + "version": "1.44.2", + "resolved": "https://registry.npmjs.org/@openzeppelin/upgrades-core/-/upgrades-core-1.44.2.tgz", + "integrity": "sha512-m6iorjyhPK9ow5/trNs7qsBC/SOzJCO51pvvAF2W9nOiZ1t0RtCd+rlRmRmlWTv4M33V0wzIUeamJ2BPbzgUXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nomicfoundation/slang": "^0.18.3", + "bignumber.js": "^9.1.2", + "cbor": "^10.0.0", + "chalk": "^4.1.0", + "compare-versions": "^6.0.0", + "debug": "^4.1.1", + "ethereumjs-util": "^7.0.3", + "minimatch": "^9.0.5", + "minimist": "^1.2.7", + "proper-lockfile": "^4.1.1", + "solidity-ast": "^0.4.60" + }, + "bin": { + "openzeppelin-upgrades-core": "dist/cli/cli.js" + } + }, + "node_modules/@openzeppelin/upgrades-core/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@openzeppelin/upgrades-core/node_modules/bignumber.js": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", + "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/@openzeppelin/upgrades-core/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@openzeppelin/upgrades-core/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@openzeppelin/upgrades-core/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@openzeppelin/upgrades-core/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@openzeppelin/upgrades-core/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@resolver-engine/core": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@resolver-engine/core/-/core-0.3.3.tgz", + "integrity": "sha512-eB8nEbKDJJBi5p5SrvrvILn4a0h42bKtbCTri3ZxCGt6UvoQyp7HnGOfki944bUjBSHKK3RvgfViHn+kqdXtnQ==", + "dev": true, + "license": "LGPL-3.0-or-later", + "dependencies": { + "debug": "^3.1.0", + "is-url": "^1.2.4", + "request": "^2.85.0" + } + }, + "node_modules/@resolver-engine/core/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/@resolver-engine/fs": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@resolver-engine/fs/-/fs-0.3.3.tgz", + "integrity": "sha512-wQ9RhPUcny02Wm0IuJwYMyAG8fXVeKdmhm8xizNByD4ryZlx6PP6kRen+t/haF43cMfmaV7T3Cx6ChOdHEhFUQ==", + "dev": true, + "license": "LGPL-3.0-or-later", + "dependencies": { + "@resolver-engine/core": "^0.3.3", + "debug": "^3.1.0" + } + }, + "node_modules/@resolver-engine/fs/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/@resolver-engine/imports": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@resolver-engine/imports/-/imports-0.3.3.tgz", + "integrity": "sha512-anHpS4wN4sRMwsAbMXhMfOD/y4a4Oo0Cw/5+rue7hSwGWsDOQaAU1ClK1OxjUC35/peazxEl8JaSRRS+Xb8t3Q==", + "dev": true, + "license": "LGPL-3.0-or-later", + "dependencies": { + "@resolver-engine/core": "^0.3.3", + "debug": "^3.1.0", + "hosted-git-info": "^2.6.0", + "path-browserify": "^1.0.0", + "url": "^0.11.0" + } + }, + "node_modules/@resolver-engine/imports-fs": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@resolver-engine/imports-fs/-/imports-fs-0.3.3.tgz", + "integrity": "sha512-7Pjg/ZAZtxpeyCFlZR5zqYkz+Wdo84ugB5LApwriT8XFeQoLwGUj4tZFFvvCuxaNCcqZzCYbonJgmGObYBzyCA==", + "dev": true, + "license": "LGPL-3.0-or-later", + "dependencies": { + "@resolver-engine/fs": "^0.3.3", + "@resolver-engine/imports": "^0.3.3", + "debug": "^3.1.0" + } + }, + "node_modules/@resolver-engine/imports-fs/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/@resolver-engine/imports/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@scure/base": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.6.tgz", + "integrity": "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", + "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/curves": "~1.4.0", + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32/node_modules/@noble/curves": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", + "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32/node_modules/@scure/base": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", + "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip39": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz", + "integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip39/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip39/node_modules/@scure/base": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", + "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@sentry/core": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz", + "integrity": "sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sentry/hub": "5.30.0", + "@sentry/minimal": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/core/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true, + "license": "0BSD" + }, + "node_modules/@sentry/hub": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz", + "integrity": "sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/hub/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true, + "license": "0BSD" + }, + "node_modules/@sentry/minimal": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz", + "integrity": "sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sentry/hub": "5.30.0", + "@sentry/types": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/minimal/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true, + "license": "0BSD" + }, + "node_modules/@sentry/node": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.30.0.tgz", + "integrity": "sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sentry/core": "5.30.0", + "@sentry/hub": "5.30.0", + "@sentry/tracing": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "cookie": "^0.4.1", + "https-proxy-agent": "^5.0.0", + "lru_map": "^0.3.3", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/node/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true, + "license": "0BSD" + }, + "node_modules/@sentry/tracing": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz", + "integrity": "sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sentry/hub": "5.30.0", + "@sentry/minimal": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/tracing/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true, + "license": "0BSD" + }, + "node_modules/@sentry/types": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz", + "integrity": "sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/utils": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.30.0.tgz", + "integrity": "sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sentry/types": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/utils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true, + "license": "0BSD" + }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@smithy/config-resolver": { + "version": "4.4.17", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.4.17.tgz", + "integrity": "sha512-TzDZcAnhTyAHbXVxWZo7/tEcrIeFq20IBk8So3OLOetWpR8EwY/yEqBMBFaJMeyEiREDq4NfEl+qO3OAUD+vbQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^4.3.14", + "@smithy/types": "^4.14.1", + "@smithy/util-config-provider": "^4.2.2", + "@smithy/util-endpoints": "^3.4.2", + "@smithy/util-middleware": "^4.2.14", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/core": { + "version": "3.23.17", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.23.17.tgz", + "integrity": "sha512-x7BlLbUFL8NWCGjMF9C+1N5cVCxcPa7g6Tv9B4A2luWx3be3oU8hQ96wIwxe/s7OhIzvoJH73HAUSg5JXVlEtQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", + "@smithy/url-parser": "^4.2.14", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-body-length-browser": "^4.2.2", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-stream": "^4.5.25", + "@smithy/util-utf8": "^4.2.2", + "@smithy/uuid": "^1.1.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/credential-provider-imds": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.2.14.tgz", + "integrity": "sha512-Au28zBN48ZAoXdooGUHemuVBrkE+Ie6RPmGNIAJsFqj33Vhb6xAgRifUydZ2aY+M+KaMAETAlKk5NC5h1G7wpg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^4.3.14", + "@smithy/property-provider": "^4.2.14", + "@smithy/types": "^4.14.1", + "@smithy/url-parser": "^4.2.14", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-codec": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-4.2.14.tgz", + "integrity": "sha512-erZq0nOIpzfeZdCyzZjdJb4nVSKLUmSkaQUVkRGQTXs30gyUGeKnrYEg+Xe1W5gE3aReS7IgsvANwVPxSzY6Pw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/crc32": "5.2.0", + "@smithy/types": "^4.14.1", + "@smithy/util-hex-encoding": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-browser": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-4.2.14.tgz", + "integrity": "sha512-8IelTCtTctWRbb+0Dcy+C0aICh1qa0qWXqgjcXDmMuCvPJRnv26hiDZoAau2ILOniki65mCPKqOQs/BaWvO4CQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/eventstream-serde-universal": "^4.2.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-config-resolver": { + "version": "4.3.14", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-4.3.14.tgz", + "integrity": "sha512-sqHiHpYRYo3FJlaIxD1J8PhbcmJAm7IuM16mVnwSkCToD7g00IBZzKuiLNMGmftULmEUX6/UAz8/NN5uMP8bVA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-node": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-4.2.14.tgz", + "integrity": "sha512-Ht/8BuGlKfFTy0H3+8eEu0vdpwGztCnaLLXtpXNdQqiR7Hj4vFScU3T436vRAjATglOIPjJXronY+1WxxNLSiw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/eventstream-serde-universal": "^4.2.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-universal": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-4.2.14.tgz", + "integrity": "sha512-lWyt4T2XQZUZgK3tQ3Wn0w3XBvZsK/vjTuJl6bXbnGZBHH0ZUSONTYiK9TgjTTzU54xQr3DRFwpjmhp0oLm3gg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/eventstream-codec": "^4.2.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/fetch-http-handler": { + "version": "5.3.17", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.3.17.tgz", + "integrity": "sha512-bXOvQzaSm6MnmLaWA1elgfQcAtN4UP3vXqV97bHuoOrHQOJiLT3ds6o9eo5bqd0TJfRFpzdGnDQdW3FACiAVdw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^5.3.14", + "@smithy/querystring-builder": "^4.2.14", + "@smithy/types": "^4.14.1", + "@smithy/util-base64": "^4.3.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/hash-node": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.2.14.tgz", + "integrity": "sha512-8ZBDY2DD4wr+GGjTpPtiglEsqr0lUP+KHqgZcWczFf6qeZ/YRjMIOoQWVQlmwu7EtxKTd8YXD8lblmYcpBIA1g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1", + "@smithy/util-buffer-from": "^4.2.2", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/invalid-dependency": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.2.14.tgz", + "integrity": "sha512-c21qJiTSb25xvvOp+H2TNZzPCngrvl5vIPqPB8zQ/DmJF4QWXO19x1dWfMJZ6wZuuWUPPm0gV8C0cU3+ifcWuw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/is-array-buffer": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.2.2.tgz", + "integrity": "sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-content-length": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.2.14.tgz", + "integrity": "sha512-xhHq7fX4/3lv5NHxLUk3OeEvl0xZ+Ek3qIbWaCL4f9JwgDZEclPBElljaZCAItdGPQl/kSM4LPMOpy1MYgprpw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-endpoint": { + "version": "4.4.32", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.4.32.tgz", + "integrity": "sha512-ZZkgyjnJppiZbIm6Qbx92pbXYi1uzenIvGhBSCDlc7NwuAkiqSgS75j1czAD25ZLs2FjMjYy1q7gyRVWG6JA0Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.23.17", + "@smithy/middleware-serde": "^4.2.20", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/shared-ini-file-loader": "^4.4.9", + "@smithy/types": "^4.14.1", + "@smithy/url-parser": "^4.2.14", + "@smithy/util-middleware": "^4.2.14", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-retry": { + "version": "4.5.5", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.5.5.tgz", + "integrity": "sha512-wnYOpB5vATFKWrY2Z9Alb0KhjZI6AbzU6Fbz3Hq2GnURdRYWB4q+qWivQtSTwXcmWUA3MZ6krfwL6Cq5MAbxsA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.23.17", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/protocol-http": "^5.3.14", + "@smithy/service-error-classification": "^4.3.0", + "@smithy/smithy-client": "^4.12.13", + "@smithy/types": "^4.14.1", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-retry": "^4.3.4", + "@smithy/uuid": "^1.1.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-serde": { + "version": "4.2.20", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.2.20.tgz", + "integrity": "sha512-Lx9JMO9vArPtiChE3wbEZ5akMIDQpWQtlu90lhACQmNOXcGXRbaDywMHDzuDZ2OkZzP+9wQfZi3YJT9F67zTQQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.23.17", + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-stack": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.2.14.tgz", + "integrity": "sha512-2dvkUKLuFdKsCRmOE4Mn63co0Djtsm+JMh0bYZQupN1pJwMeE8FmQmRLLzzEMN0dnNi7CDCYYH8F0EVwWiPBeA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/node-config-provider": { + "version": "4.3.14", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.3.14.tgz", + "integrity": "sha512-S+gFjyo/weSVL0P1b9Ts8C/CwIfNCgUPikk3sl6QVsfE/uUuO+QsF+NsE/JkpvWqqyz1wg7HFdiaZuj5CoBMRg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/property-provider": "^4.2.14", + "@smithy/shared-ini-file-loader": "^4.4.9", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/node-http-handler": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.6.1.tgz", + "integrity": "sha512-iB+orM4x3xrr57X3YaXazfKnntl0LHlZB1kcXSGzMV1Tt0+YwEjGlbjk/44qEGtBzXAz6yFDzkYTKSV6Pj2HUg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^5.3.14", + "@smithy/querystring-builder": "^4.2.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/property-provider": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.2.14.tgz", + "integrity": "sha512-WuM31CgfsnQ/10i7NYr0PyxqknD72Y5uMfUMVSniPjbEPceiTErb4eIqJQ+pdxNEAUEWrewrGjIRjVbVHsxZiQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/protocol-http": { + "version": "5.3.14", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.14.tgz", + "integrity": "sha512-dN5F8kHx8RNU0r+pCwNmFZyz6ChjMkzShy/zup6MtkRmmix4vZzJdW+di7x//b1LiynIev88FM18ie+wwPcQtQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/querystring-builder": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.2.14.tgz", + "integrity": "sha512-XYA5Z0IqTeF+5XDdh4BBmSA0HvbgVZIyv4cmOoUheDNR57K1HgBp9ukUMx3Cr3XpDHHpLBnexPE3LAtDsZkj2A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1", + "@smithy/util-uri-escape": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/querystring-parser": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.2.14.tgz", + "integrity": "sha512-hr+YyqBD23GVvRxGGrcc/oOeNlK3PzT5Fu4dzrDXxzS1LpFiuL2PQQqKPs87M79aW7ziMs+nvB3qdw77SqE7Lw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/service-error-classification": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.3.0.tgz", + "integrity": "sha512-9jKsBYQRPR0xBLgc2415RsA5PIcP2sis4oBdN9s0D13cg1B1284mNTjx9Yc+BEERXzuPm5ObktI96OxsKh8E9A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/shared-ini-file-loader": { + "version": "4.4.9", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.9.tgz", + "integrity": "sha512-495/V2I15SHgedSJoDPD23JuSfKAp726ZI1V0wtjB07Wh7q/0tri/0e0DLefZCHgxZonrGKt/OCTpAtP1wE1kQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/signature-v4": { + "version": "5.3.14", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.3.14.tgz", + "integrity": "sha512-1D9Y/nmlVjCeSivCbhZ7hgEpmHyY1h0GvpSZt3l0xcD9JjmjVC1CHOozS6+Gh+/ldMH8JuJ6cujObQqfayAVFA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^4.2.2", + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", + "@smithy/util-hex-encoding": "^4.2.2", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-uri-escape": "^4.2.2", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/smithy-client": { + "version": "4.12.13", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.12.13.tgz", + "integrity": "sha512-y/Pcj1V9+qG98gyu1gvftHB7rDpdh+7kIBIggs55yGm3JdtBV8GT8IFF3a1qxZ79QnaJHX9GXzvBG6tAd+czJA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.23.17", + "@smithy/middleware-endpoint": "^4.4.32", + "@smithy/middleware-stack": "^4.2.14", + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", + "@smithy/util-stream": "^4.5.25", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/types": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.14.1.tgz", + "integrity": "sha512-59b5HtSVrVR/eYNei3BUj3DCPKD/G7EtDDe7OEJE7i7FtQFugYo6MxbotS8mVJkLNVf8gYaAlEBwwtJ9HzhWSg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/url-parser": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.2.14.tgz", + "integrity": "sha512-p06BiBigJ8bTA3MgnOfCtDUWnAMY0YfedO/GRpmc7p+wg3KW8vbXy1xwSu5ASy0wV7rRYtlfZOIKH4XqfhjSQQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/querystring-parser": "^4.2.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-base64": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.3.2.tgz", + "integrity": "sha512-XRH6b0H/5A3SgblmMa5ErXQ2XKhfbQB+Fm/oyLZ2O2kCUrwgg55bU0RekmzAhuwOjA9qdN5VU2BprOvGGUkOOQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^4.2.2", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-body-length-browser": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-4.2.2.tgz", + "integrity": "sha512-JKCrLNOup3OOgmzeaKQwi4ZCTWlYR5H4Gm1r2uTMVBXoemo1UEghk5vtMi1xSu2ymgKVGW631e2fp9/R610ZjQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-body-length-node": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-4.2.3.tgz", + "integrity": "sha512-ZkJGvqBzMHVHE7r/hcuCxlTY8pQr1kMtdsVPs7ex4mMU+EAbcXppfo5NmyxMYi2XU49eqaz56j2gsk4dHHPG/g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-buffer-from": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.2.2.tgz", + "integrity": "sha512-FDXD7cvUoFWwN6vtQfEta540Y/YBe5JneK3SoZg9bThSoOAC/eGeYEua6RkBgKjGa/sz6Y+DuBZj3+YEY21y4Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-config-provider": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-4.2.2.tgz", + "integrity": "sha512-dWU03V3XUprJwaUIFVv4iOnS1FC9HnMHDfUrlNDSh4315v0cWyaIErP8KiqGVbf5z+JupoVpNM7ZB3jFiTejvQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-defaults-mode-browser": { + "version": "4.3.49", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.49.tgz", + "integrity": "sha512-a5bNrdiONYB/qE2BuKegvUMd/+ZDwdg4vsNuuSzYE8qs2EYAdK9CynL+Rzn29PbPiUqoz/cbpRbcLzD5lEevHw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/property-provider": "^4.2.14", + "@smithy/smithy-client": "^4.12.13", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-defaults-mode-node": { + "version": "4.2.54", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.54.tgz", + "integrity": "sha512-g1cvrJvOnzeJgEdf7AE4luI7gp6L8weE0y9a9wQUSGtjb8QRHDbCJYuE4Sy0SD9N8RrnNPFsPltAz/OSoBR9Zw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/config-resolver": "^4.4.17", + "@smithy/credential-provider-imds": "^4.2.14", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/property-provider": "^4.2.14", + "@smithy/smithy-client": "^4.12.13", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-endpoints": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.4.2.tgz", + "integrity": "sha512-a55Tr+3OKld4TTtnT+RhKOQHyPxm3j/xL4OR83WBUhLJaKDS9dnJ7arRMOp3t31dcLhApwG9bgvrRXBHlLdIkg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^4.3.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-hex-encoding": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.2.2.tgz", + "integrity": "sha512-Qcz3W5vuHK4sLQdyT93k/rfrUwdJ8/HZ+nMUOyGdpeGA1Wxt65zYwi3oEl9kOM+RswvYq90fzkNDahPS8K0OIg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-middleware": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.2.14.tgz", + "integrity": "sha512-1Su2vj9RYNDEv/V+2E+jXkkwGsgR7dc4sfHn9Z7ruzQHJIEni9zzw5CauvRXlFJfmgcqYP8fWa0dkh2Q2YaQyw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-retry": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.3.4.tgz", + "integrity": "sha512-FY1UQQ1VFmMwiYp1GVS4MeaGD5O0blLNYK0xCRHU+mJgeoH/hSY8Ld8sJWKQ6uznkh14HveRGQJncgPyNl9J+A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/service-error-classification": "^4.3.0", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-stream": { + "version": "4.5.25", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.5.25.tgz", + "integrity": "sha512-/PFpG4k8Ze8Ei+mMKj3oiPICYekthuzePZMgZbCqMiXIHHf4n2aZ4Ps0aSRShycFTGuj/J6XldmC0x0DwednIA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/fetch-http-handler": "^5.3.17", + "@smithy/node-http-handler": "^4.6.1", + "@smithy/types": "^4.14.1", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-buffer-from": "^4.2.2", + "@smithy/util-hex-encoding": "^4.2.2", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-uri-escape": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.2.2.tgz", + "integrity": "sha512-2kAStBlvq+lTXHyAZYfJRb/DfS3rsinLiwb+69SstC9Vb0s9vNWkRwpnj918Pfi85mzi42sOqdV72OLxWAISnw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-utf8": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.2.tgz", + "integrity": "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-waiter": { + "version": "4.2.16", + "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-4.2.16.tgz", + "integrity": "sha512-GtclrKoZ3Lt7jPQ7aTIYKfjY92OgceScftVnkTsG8e1KV8rkvZgN+ny6YSRhd9hxB8rZtwVbmln7NTvE5O3GmQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/uuid": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@smithy/uuid/-/uuid-1.1.2.tgz", + "integrity": "sha512-O/IEdcCUKkubz60tFbGA7ceITTAJsty+lBjNoorP4Z6XRqaFb/OjQjZODophEcuq68nKm6/0r+6/lLQ+XVpk8g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@solidity-parser/parser": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.5.tgz", + "integrity": "sha512-6dKnHZn7fg/iQATVEzqyUOyEidbn05q7YA2mQ9hC0MMXhhV3/JrsxmFSYZAcr7j1yUP700LLhTruvJ3MiQmjJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "antlr4ts": "^0.5.0-alpha.4" + } + }, + "node_modules/@streamparser/json": { + "version": "0.0.22", + "resolved": "https://registry.npmjs.org/@streamparser/json/-/json-0.0.22.tgz", + "integrity": "sha512-b6gTSBjJ8G8SuO3Gbbj+zXbVx8NSs1EbpbMKpzGLWMdkR+98McH9bEjSz3+0mPJf68c5nxa3CrJHp5EQNXM6zQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@streamparser/json-node": { + "version": "0.0.22", + "resolved": "https://registry.npmjs.org/@streamparser/json-node/-/json-node-0.0.22.tgz", + "integrity": "sha512-sJT2ptNRwqB1lIsQrQlCoWk5rF4tif9wDh+7yluAGijJamAhrHGYpFB/Zg3hJeceoZypi74ftXk8DHzwYpbZSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@streamparser/json": "^0.0.22" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", + "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "defer-to-connect": "^2.0.1" + }, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/@tenderly/api-client": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@tenderly/api-client/-/api-client-1.1.0.tgz", + "integrity": "sha512-kyye7TQ+RbDbJ7bSUjNf/O9fTtRYNUDIEUZQSrmNonowMw5/EpNi664eWaOoC00NEzxgttVrtme/GHvIOu7rNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "axios": "^0.27.2", + "cli-table3": "^0.6.2", + "commander": "^9.4.0", + "dotenv": "^16.4.5", + "js-yaml": "^4.1.0", + "open": "^8.4.0", + "prompts": "^2.4.2", + "tslog": "^4.4.0" + }, + "peerDependencies": { + "ts-node": "*", + "typescript": "*" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/@tenderly/api-client/node_modules/axios": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + } + }, + "node_modules/@tenderly/api-client/node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/@tenderly/api-client/node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/@tenderly/api-client/node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@tenderly/hardhat-integration": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@tenderly/hardhat-integration/-/hardhat-integration-1.1.1.tgz", + "integrity": "sha512-VHa380DrKv+KA1N4vbJGLDoghbVqMZ4wEozbxRfCzlkSs5V1keNgudRSUFK6lgfKhkoAWRO+dA8MZYnJOvUOkA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tenderly/api-client": "^1.1.0", + "axios": "^1.6.7", + "dotenv": "^16.4.5", + "fs-extra": "^10.1.0", + "hardhat-deploy": "^0.11.43", + "npm-registry-fetch": "^17.1.0", + "semver": "^7.6.3", + "ts-node": "^10.9.1", + "tslog": "^4.3.1", + "typescript": "^5.5.4" + }, + "peerDependencies": { + "hardhat": "^2.22.6" + } + }, + "node_modules/@tenderly/hardhat-integration/node_modules/cacache": { + "version": "18.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-18.0.4.tgz", + "integrity": "sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@tenderly/hardhat-integration/node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/@tenderly/hardhat-integration/node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/@tenderly/hardhat-integration/node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tenderly/hardhat-integration/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@tenderly/hardhat-integration/node_modules/fs-minipass": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", + "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@tenderly/hardhat-integration/node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@tenderly/hardhat-integration/node_modules/hosted-git-info": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@tenderly/hardhat-integration/node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@tenderly/hardhat-integration/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/@tenderly/hardhat-integration/node_modules/make-fetch-happen": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-13.0.1.tgz", + "integrity": "sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/agent": "^2.0.0", + "cacache": "^18.0.0", + "http-cache-semantics": "^4.1.1", + "is-lambda": "^1.0.1", + "minipass": "^7.0.2", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "proc-log": "^4.2.0", + "promise-retry": "^2.0.1", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@tenderly/hardhat-integration/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/@tenderly/hardhat-integration/node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@tenderly/hardhat-integration/node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@tenderly/hardhat-integration/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@tenderly/hardhat-integration/node_modules/npm-package-arg": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.3.tgz", + "integrity": "sha512-sHGJy8sOC1YraBywpzQlIKBE4pBbGbiF95U6Auspzyem956E0+FtDtsx1ZxlOJkQCZ1AFXAY/yuvtFYrOxF+Bw==", + "dev": true, + "license": "ISC", + "dependencies": { + "hosted-git-info": "^7.0.0", + "proc-log": "^4.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@tenderly/hardhat-integration/node_modules/npm-registry-fetch": { + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-17.1.0.tgz", + "integrity": "sha512-5+bKQRH0J1xG1uZ1zMNvxW0VEyoNWgJpY9UDuluPFLKDfJ9u2JmmjmTJV1srBGQOROfdBMiVvnH2Zvpbm+xkVA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/redact": "^2.0.0", + "jsonparse": "^1.3.1", + "make-fetch-happen": "^13.0.0", + "minipass": "^7.0.2", + "minipass-fetch": "^3.0.0", + "minizlib": "^2.1.2", + "npm-package-arg": "^11.0.0", + "proc-log": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@tenderly/hardhat-integration/node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@tenderly/hardhat-integration/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@tenderly/hardhat-integration/node_modules/ssri": { + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", + "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@tenderly/hardhat-integration/node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "deprecated": "Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exhorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@tenderly/hardhat-integration/node_modules/tar/node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@tenderly/hardhat-integration/node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@tenderly/hardhat-integration/node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/@tenderly/hardhat-integration/node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/@tenderly/hardhat-integration/node_modules/unique-filename": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", + "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", + "dev": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@tenderly/hardhat-integration/node_modules/unique-slug": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", + "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@tenderly/hardhat-integration/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@tenderly/hardhat-integration/node_modules/validate-npm-package-name": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz", + "integrity": "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@tenderly/hardhat-integration/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/@tenderly/hardhat-tenderly": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/@tenderly/hardhat-tenderly/-/hardhat-tenderly-2.5.2.tgz", + "integrity": "sha512-JCG1UkFBRZE2fL8g4jfbKUsju7gK3Dg6CxksJO9Db9ckM1EkL4wCY9G5KTLwh/UL0cT04J8ZK1RmaZ6hG8wfKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@nomicfoundation/hardhat-ethers": "^3.0.0", + "@nomicfoundation/hardhat-ignition": "^0.15.5", + "@nomicfoundation/hardhat-verify": "^2.0.8", + "@openzeppelin/hardhat-upgrades": "^3.3.0", + "@openzeppelin/upgrades-core": "^1.32.2", + "@tenderly/hardhat-integration": "^1.1.0", + "dotenv": "^16.4.5", + "ethers": "^6.8.1" + } + }, + "node_modules/@tenderly/hardhat-tenderly/node_modules/@nomicfoundation/hardhat-ethers": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ethers/-/hardhat-ethers-3.1.2.tgz", + "integrity": "sha512-7xEaz2X8p47qWIAqtV2z03MmusheHm8bvY2mDlxo9JiT2BgSx59GSdv5+mzwOvsuKDbTij7oqDnwFyYOlHREEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.1", + "lodash.isequal": "^4.5.0" + }, + "peerDependencies": { + "ethers": "^6.14.0", + "hardhat": "^2.26.0" + } + }, + "node_modules/@tenderly/hardhat-tenderly/node_modules/@nomicfoundation/hardhat-ignition": { + "version": "0.15.15", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ignition/-/hardhat-ignition-0.15.15.tgz", + "integrity": "sha512-4uLp5MOyaW0gUYGAxiA8GikGIo8SLBijpxakFI3BpofUoeRXnnQdNtRJT9aAKD8ENfvFQrNFin0Z1VlXjXurkA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nomicfoundation/ignition-core": "^0.15.14", + "@nomicfoundation/ignition-ui": "^0.15.13", + "chalk": "^4.0.0", + "debug": "^4.3.2", + "fs-extra": "^10.0.0", + "json5": "^2.2.3", + "prompts": "^2.4.2" + }, + "peerDependencies": { + "@nomicfoundation/hardhat-verify": "^2.1.0", + "hardhat": "^2.26.0" + } + }, + "node_modules/@tenderly/hardhat-tenderly/node_modules/@nomicfoundation/hardhat-verify": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-verify/-/hardhat-verify-2.1.3.tgz", + "integrity": "sha512-danbGjPp2WBhLkJdQy9/ARM3WQIK+7vwzE0urNem1qZJjh9f54Kf5f1xuQv8DvqewUAkuPxVt/7q4Grz5WjqSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ethersproject/abi": "^5.1.2", + "@ethersproject/address": "^5.0.2", + "cbor": "^8.1.0", + "debug": "^4.1.1", + "lodash.clonedeep": "^4.5.0", + "picocolors": "^1.1.0", + "semver": "^6.3.0", + "table": "^6.8.0", + "undici": "^5.14.0" + }, + "peerDependencies": { + "hardhat": "^2.26.0" + } + }, + "node_modules/@tenderly/hardhat-tenderly/node_modules/@openzeppelin/hardhat-upgrades": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/@openzeppelin/hardhat-upgrades/-/hardhat-upgrades-3.9.1.tgz", + "integrity": "sha512-pSDjlOnIpP+PqaJVe144dK6VVKZw2v6YQusyt0OOLiCsl+WUzfo4D0kylax7zjrOxqy41EK2ipQeIF4T+cCn2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@openzeppelin/defender-sdk-base-client": "^2.1.0", + "@openzeppelin/defender-sdk-deploy-client": "^2.1.0", + "@openzeppelin/defender-sdk-network-client": "^2.1.0", + "@openzeppelin/upgrades-core": "^1.41.0", + "chalk": "^4.1.0", + "debug": "^4.1.1", + "ethereumjs-util": "^7.1.5", + "proper-lockfile": "^4.1.1", + "undici": "^6.11.1" + }, + "bin": { + "migrate-oz-cli-project": "dist/scripts/migrate-oz-cli-project.js" + }, + "peerDependencies": { + "@nomicfoundation/hardhat-ethers": "^3.0.6", + "@nomicfoundation/hardhat-verify": "^2.0.14", + "ethers": "^6.6.0", + "hardhat": "^2.24.1" + }, + "peerDependenciesMeta": { + "@nomicfoundation/hardhat-verify": { + "optional": true + } + } + }, + "node_modules/@tenderly/hardhat-tenderly/node_modules/@openzeppelin/hardhat-upgrades/node_modules/undici": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.22.0.tgz", + "integrity": "sha512-hU/10obOIu62MGYjdskASR3CUAiYaFTtC9Pa6vHyf//mAipSvSQg6od2CnJswq7fvzNS3zJhxoRkgNVaHurWKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, + "node_modules/@tenderly/hardhat-tenderly/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@tenderly/hardhat-tenderly/node_modules/cbor": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", + "integrity": "sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==", + "dev": true, + "license": "MIT", + "dependencies": { + "nofilter": "^3.1.0" + }, + "engines": { + "node": ">=12.19" + } + }, + "node_modules/@tenderly/hardhat-tenderly/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@tenderly/hardhat-tenderly/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@tenderly/hardhat-tenderly/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tenderly/hardhat-tenderly/node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/@tenderly/hardhat-tenderly/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@tenderly/hardhat-tenderly/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@tenderly/hardhat-tenderly/node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@tenderly/hardhat-tenderly/node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@tenderly/hardhat-tenderly/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@tenderly/hardhat-tenderly/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@trufflesuite/bigint-buffer": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@trufflesuite/bigint-buffer/-/bigint-buffer-1.1.9.tgz", + "integrity": "sha512-bdM5cEGCOhDSwminryHJbRmXc1x7dPKg6Pqns3qyTwFlxsqUgxE29lsERS3PlIW1HTjoIGMUqsk1zQQwST1Yxw==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "node-gyp-build": "4.3.0" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@trufflesuite/bigint-buffer/node_modules/node-gyp-build": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz", + "integrity": "sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==", + "dev": true, + "license": "MIT", + "optional": true, + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.12.tgz", + "integrity": "sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typechain/ethers-v6": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@typechain/ethers-v6/-/ethers-v6-0.5.1.tgz", + "integrity": "sha512-F+GklO8jBWlsaVV+9oHaPh5NJdd6rAKN4tklGfInX1Q7h0xPgVLP39Jl3eCulPB5qexI71ZFHwbljx4ZXNfouA==", + "license": "MIT", + "dependencies": { + "lodash": "^4.17.15", + "ts-essentials": "^7.0.1" + }, + "peerDependencies": { + "ethers": "6.x", + "typechain": "^8.3.2", + "typescript": ">=4.7.0" + } + }, + "node_modules/@types/abstract-leveldown": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/@types/abstract-leveldown/-/abstract-leveldown-7.2.5.tgz", + "integrity": "sha512-/2B0nQF4UdupuxeKTJA2+Rj1D+uDemo6P4kMwKCpbfpnzeVaWSELTsAw4Lxn3VJD6APtRrZOCuYo+4nHUQfTfg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-DLbJ1BPqxvQhIGbeu8VbUC1DiAiahHtAYvA0ZEAa4P31F7IaArc8z3C3BRQdWX4mtLQuABG4yzp76ZrS02Ui1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/cacheable-request": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", + "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/http-cache-semantics": "*", + "@types/keyv": "^3.1.4", + "@types/node": "*", + "@types/responselike": "^1.0.0" + } + }, + "node_modules/@types/chai": { + "version": "4.3.20", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.20.tgz", + "integrity": "sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/chai-as-promised": { + "version": "7.1.8", + "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.8.tgz", + "integrity": "sha512-ThlRVIJhr69FLlh6IctTXFkmhtP3NpMZ2QGq69StYLyKZFp/HOp1VdKZj7RvfNWYYcJ1xlbLGLLWj1UvP5u/Gw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "*" + } + }, + "node_modules/@types/chai-string": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/@types/chai-string/-/chai-string-1.4.5.tgz", + "integrity": "sha512-IecXRMSnpUvRnTztdpSdjcmcW7EdNme65bfDCQMi7XrSEPGmyDYYTEfc5fcactWDA6ioSm8o7NUqg9QxjBCCEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "*" + } + }, + "node_modules/@types/concat-stream": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", + "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/form-data": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", + "integrity": "sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/keyv": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/level-errors": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/level-errors/-/level-errors-3.0.2.tgz", + "integrity": "sha512-gyZHbcQ2X5hNXf/9KS2qGEmgDe9EN2WDM3rJ5Ele467C0nA1sLhtmv1bZiPMDYfAYCfPWft0uQIaTvXbASSTRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/levelup": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@types/levelup/-/levelup-4.3.3.tgz", + "integrity": "sha512-K+OTIjJcZHVlZQN1HmU64VtrC0jC3dXWQozuEIR9zVvltIk90zaGPM2AgT+fIkChpzHhFE3YnvFLCbLtzAmexA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/abstract-leveldown": "*", + "@types/level-errors": "*", + "@types/node": "*" + } + }, + "node_modules/@types/minimatch": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mkdirp": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-0.5.2.tgz", + "integrity": "sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/mocha": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.3.tgz", + "integrity": "sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "24.10.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.1.tgz", + "integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/@types/node-fetch": { + "version": "2.6.13", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.13.tgz", + "integrity": "sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "form-data": "^4.0.4" + } + }, + "node_modules/@types/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/prettier": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", + "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==", + "license": "MIT" + }, + "node_modules/@types/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/responselike": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", + "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/secp256k1": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.7.tgz", + "integrity": "sha512-Rcvjl6vARGAKRO6jHeKMatGrvOMGrR/AR11N1x2LqintPCyDZ7NBhrh238Z2VZc7aM7KIwnFpFQ7fnfK4H/9Qw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.46.4.tgz", + "integrity": "sha512-R48VhmTJqplNyDxCyqqVkFSZIx1qX6PzwqgcXn1olLrzxcSBDlOsbtcnQuQhNtnNiJ4Xe5gREI1foajYaYU2Vg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.46.4", + "@typescript-eslint/type-utils": "8.46.4", + "@typescript-eslint/utils": "8.46.4", + "@typescript-eslint/visitor-keys": "8.46.4", + "graphemer": "^1.4.0", + "ignore": "^7.0.0", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.46.4", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.46.4.tgz", + "integrity": "sha512-tK3GPFWbirvNgsNKto+UmB/cRtn6TZfyw0D6IKrW55n6Vbs7KJoZtI//kpTKzE/DUmmnAFD8/Ca46s7Obs92/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.46.4", + "@typescript-eslint/types": "8.46.4", + "@typescript-eslint/typescript-estree": "8.46.4", + "@typescript-eslint/visitor-keys": "8.46.4", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.4.tgz", + "integrity": "sha512-nPiRSKuvtTN+no/2N1kt2tUh/HoFzeEgOm9fQ6XQk4/ApGqjx0zFIIaLJ6wooR1HIoozvj2j6vTi/1fgAz7UYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.46.4", + "@typescript-eslint/types": "^8.46.4", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.4.tgz", + "integrity": "sha512-tMDbLGXb1wC+McN1M6QeDx7P7c0UWO5z9CXqp7J8E+xGcJuUuevWKxuG8j41FoweS3+L41SkyKKkia16jpX7CA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.4", + "@typescript-eslint/visitor-keys": "8.46.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.4.tgz", + "integrity": "sha512-+/XqaZPIAk6Cjg7NWgSGe27X4zMGqrFqZ8atJsX3CWxH/jACqWnrWI68h7nHQld0y+k9eTTjb9r+KU4twLoo9A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.46.4.tgz", + "integrity": "sha512-V4QC8h3fdT5Wro6vANk6eojqfbv5bpwHuMsBcJUJkqs2z5XnYhJzyz9Y02eUmF9u3PgXEUiOt4w4KHR3P+z0PQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.4", + "@typescript-eslint/typescript-estree": "8.46.4", + "@typescript-eslint/utils": "8.46.4", + "debug": "^4.3.4", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.4.tgz", + "integrity": "sha512-USjyxm3gQEePdUwJBFjjGNG18xY9A2grDVGuk7/9AkjIF1L+ZrVnwR5VAU5JXtUnBL/Nwt3H31KlRDaksnM7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.4.tgz", + "integrity": "sha512-7oV2qEOr1d4NWNmpXLR35LvCfOkTNymY9oyW+lUHkmCno7aOmIf/hMaydnJBUTBMRCOGZh8YjkFOc8dadEoNGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.46.4", + "@typescript-eslint/tsconfig-utils": "8.46.4", + "@typescript-eslint/types": "8.46.4", + "@typescript-eslint/visitor-keys": "8.46.4", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.4.tgz", + "integrity": "sha512-AbSv11fklGXV6T28dp2Me04Uw90R2iJ30g2bgLz529Koehrmkbs1r7paFqr1vPCZi7hHwYxYtxfyQMRC8QaVSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.46.4", + "@typescript-eslint/types": "8.46.4", + "@typescript-eslint/typescript-estree": "8.46.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.4.tgz", + "integrity": "sha512-/++5CYLQqsO9HFGLI7APrxBJYo+5OCMpViuhV8q5/Qa3o5mMrF//eQHks+PXcsAVaLdn817fMuS7zqoXNNZGaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.4", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/0xsequence": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/0xsequence/-/0xsequence-1.10.15.tgz", + "integrity": "sha512-HtETUgbXS35vllu5buoiH8TrlV7boNQ+Odtae3mFQPTtsd/9Px81gFzHJhtCbcivK3QV6UC6+4nmK6KOKqInlw==", + "license": "Apache-2.0", + "dependencies": { + "@0xsequence/abi": "1.10.15", + "@0xsequence/account": "1.10.15", + "@0xsequence/api": "1.10.15", + "@0xsequence/auth": "1.10.15", + "@0xsequence/core": "1.10.15", + "@0xsequence/guard": "1.10.15", + "@0xsequence/indexer": "1.10.15", + "@0xsequence/metadata": "1.10.15", + "@0xsequence/migration": "1.10.15", + "@0xsequence/multicall": "1.10.15", + "@0xsequence/network": "1.10.15", + "@0xsequence/provider": "1.10.15", + "@0xsequence/relayer": "1.10.15", + "@0xsequence/sessions": "1.10.15", + "@0xsequence/signhub": "1.10.15", + "@0xsequence/utils": "1.10.15", + "@0xsequence/wallet": "1.10.15" + }, + "peerDependencies": { + "ethers": ">=5.5 < 6" + } + }, + "node_modules/0xsequence/node_modules/@0xsequence/abi": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/abi/-/abi-1.10.15.tgz", + "integrity": "sha512-nuh68P8tRDzIMIH7mnGX1Eab0jsYVGhZa7IlNIs8CfTnGoanxLS+MGk5ioZBa6+slzxb9VP8mnQ5QhAWeFySeg==", + "license": "Apache-2.0" + }, + "node_modules/0xsequence/node_modules/@0xsequence/auth": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/auth/-/auth-1.10.15.tgz", + "integrity": "sha512-ZY8vf/l9J+1HWP4pIMNTRBDFVXgi22x8zmSLgE4xAo4JDZ6yiGAQPooJpRCs59gx1LtVI2Zt+KgvfW1qVxQDtQ==", + "license": "Apache-2.0", + "dependencies": { + "@0xsequence/abi": "1.10.15", + "@0xsequence/account": "1.10.15", + "@0xsequence/api": "1.10.15", + "@0xsequence/core": "1.10.15", + "@0xsequence/ethauth": "^0.8.1", + "@0xsequence/indexer": "1.10.15", + "@0xsequence/metadata": "1.10.15", + "@0xsequence/migration": "1.10.15", + "@0xsequence/network": "1.10.15", + "@0xsequence/sessions": "1.10.15", + "@0xsequence/signhub": "1.10.15", + "@0xsequence/utils": "1.10.15", + "@0xsequence/wallet": "1.10.15" + }, + "peerDependencies": { + "ethers": ">=5.5 < 6" + } + }, + "node_modules/0xsequence/node_modules/@0xsequence/core": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/core/-/core-1.10.15.tgz", + "integrity": "sha512-wrE5soJSqrhhm7pC+NxckLR0lJSOnsHPLKdDqWeTRmyuhtZ4e0DsrcoeoD40I/3Bd77tdZ1GGbq00CryV7JfFw==", + "license": "Apache-2.0", + "dependencies": { + "@0xsequence/abi": "1.10.15" + }, + "peerDependencies": { + "ethers": ">=5.5" + } + }, + "node_modules/0xsequence/node_modules/@0xsequence/indexer": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/indexer/-/indexer-1.10.15.tgz", + "integrity": "sha512-bc2gAIEplMcmWJMwLuXZZ0wifoxuV/zHyWzEdbQ5+9ruIXArxyoG0Ue9fMEzKWHfsAWyBKBJCCFbr4XJEQ5YjA==", + "license": "Apache-2.0" + }, + "node_modules/0xsequence/node_modules/@0xsequence/multicall": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/multicall/-/multicall-1.10.15.tgz", + "integrity": "sha512-yFTMDZR9tUvm3lefYyuxhohtx6mFzdpmn+qDFk9Bjo5TeEu0SGJLjdd6U2AK3rDIcPPw7rl7VvBXLweNJOMjfw==", + "license": "Apache-2.0", + "dependencies": { + "@0xsequence/abi": "1.10.15", + "@0xsequence/network": "1.10.15", + "@0xsequence/utils": "1.10.15" + }, + "peerDependencies": { + "ethers": ">=5.5 < 6" + } + }, + "node_modules/0xsequence/node_modules/@0xsequence/network": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/network/-/network-1.10.15.tgz", + "integrity": "sha512-wHp8RGqFrncuoIh0ityO/jUobliargQ7SWlvZCf8Ez0T7uiXDEDokrFSN2F9FIl6i5a5NmcEpXhfhwS/L0pN2w==", + "license": "Apache-2.0", + "dependencies": { + "@0xsequence/core": "1.10.15", + "@0xsequence/indexer": "1.10.15", + "@0xsequence/relayer": "1.10.15", + "@0xsequence/utils": "1.10.15" + }, + "peerDependencies": { + "ethers": ">=5.5 < 6" + } + }, + "node_modules/0xsequence/node_modules/@0xsequence/provider": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/provider/-/provider-1.10.15.tgz", + "integrity": "sha512-oPntN3xWvwEnPuZ4LoxWL50v7FLhJa8guOP27FFltm4sjxydYCZ37griBR093YW5NKtWO8mtmnnnTZChJS8Euw==", + "license": "Apache-2.0", + "dependencies": { + "@0xsequence/abi": "1.10.15", + "@0xsequence/account": "1.10.15", + "@0xsequence/auth": "1.10.15", + "@0xsequence/core": "1.10.15", + "@0xsequence/migration": "1.10.15", + "@0xsequence/network": "1.10.15", + "@0xsequence/relayer": "1.10.15", + "@0xsequence/utils": "1.10.15", + "@0xsequence/wallet": "1.10.15", + "@databeat/tracker": "^0.9.1", + "eventemitter2": "^6.4.5", + "webextension-polyfill": "^0.10.0" + }, + "peerDependencies": { + "ethers": ">=5.5 < 6" + } + }, + "node_modules/0xsequence/node_modules/@0xsequence/relayer": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/relayer/-/relayer-1.10.15.tgz", + "integrity": "sha512-QpNAzRjqCl9xJdXzErQA0kmv2jzEXPfVlPwutbgmrCEIj+rHdw3M+kiG0MWBnOqxoSEA98oJnxXmpBL5mkCA6g==", + "license": "Apache-2.0", + "dependencies": { + "@0xsequence/abi": "1.10.15", + "@0xsequence/core": "1.10.15", + "@0xsequence/utils": "1.10.15" + }, + "peerDependencies": { + "ethers": ">=5.5 < 6" + } + }, + "node_modules/0xsequence/node_modules/@0xsequence/signhub": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/signhub/-/signhub-1.10.15.tgz", + "integrity": "sha512-9yZWb8d2aXoWOQp0XC81hkS+hLWxO/pZIyCRtNVdif0/SPA86v6e96xPmuj45KONYgiH33ROVDpeJEKhOEo0jg==", + "license": "Apache-2.0", + "dependencies": { + "@0xsequence/core": "1.10.15", + "ethers": "^5.5.2" + } + }, + "node_modules/0xsequence/node_modules/@0xsequence/signhub/node_modules/ethers": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.8.0.tgz", + "integrity": "sha512-DUq+7fHrCg1aPDFCHx6UIPb3nmt2XMpM7Y/g2gLhsl3lIBqeAfOJIl1qEvRf2uq3BiKxmh6Fh5pfp2ieyek7Kg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abi": "5.8.0", + "@ethersproject/abstract-provider": "5.8.0", + "@ethersproject/abstract-signer": "5.8.0", + "@ethersproject/address": "5.8.0", + "@ethersproject/base64": "5.8.0", + "@ethersproject/basex": "5.8.0", + "@ethersproject/bignumber": "5.8.0", + "@ethersproject/bytes": "5.8.0", + "@ethersproject/constants": "5.8.0", + "@ethersproject/contracts": "5.8.0", + "@ethersproject/hash": "5.8.0", + "@ethersproject/hdnode": "5.8.0", + "@ethersproject/json-wallets": "5.8.0", + "@ethersproject/keccak256": "5.8.0", + "@ethersproject/logger": "5.8.0", + "@ethersproject/networks": "5.8.0", + "@ethersproject/pbkdf2": "5.8.0", + "@ethersproject/properties": "5.8.0", + "@ethersproject/providers": "5.8.0", + "@ethersproject/random": "5.8.0", + "@ethersproject/rlp": "5.8.0", + "@ethersproject/sha2": "5.8.0", + "@ethersproject/signing-key": "5.8.0", + "@ethersproject/solidity": "5.8.0", + "@ethersproject/strings": "5.8.0", + "@ethersproject/transactions": "5.8.0", + "@ethersproject/units": "5.8.0", + "@ethersproject/wallet": "5.8.0", + "@ethersproject/web": "5.8.0", + "@ethersproject/wordlists": "5.8.0" + } + }, + "node_modules/0xsequence/node_modules/@0xsequence/utils": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/utils/-/utils-1.10.15.tgz", + "integrity": "sha512-LIrQS5J+3MOER+i7ajX7fiT6ga3QoDf8wsi5KY/2eFZS39sbCXGzg1ORxjtee++c/S/h4nuRYX1IRuseGYJWPw==", + "license": "Apache-2.0", + "dependencies": { + "js-base64": "^3.7.2" + }, + "peerDependencies": { + "ethers": ">=5.5 < 6" + } + }, + "node_modules/0xsequence/node_modules/@0xsequence/wallet": { + "version": "1.10.15", + "resolved": "https://registry.npmjs.org/@0xsequence/wallet/-/wallet-1.10.15.tgz", + "integrity": "sha512-UhaIaiK3IF+bv1flg/N1yuGPZXos/orJlwAd9GbPDHOIBqkBsniyraDcO+xwBKWMBHhQL6NqfSDI9j/Zxv7ocg==", + "license": "Apache-2.0", + "dependencies": { + "@0xsequence/abi": "1.10.15", + "@0xsequence/core": "1.10.15", + "@0xsequence/network": "1.10.15", + "@0xsequence/relayer": "1.10.15", + "@0xsequence/signhub": "1.10.15", + "@0xsequence/utils": "1.10.15" + }, + "peerDependencies": { + "ethers": ">=5.5 < 6" + } + }, + "node_modules/abbrev": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", + "integrity": "sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==", + "dev": true, + "license": "ISC" + }, + "node_modules/abortcontroller-polyfill": { + "version": "1.7.8", + "resolved": "https://registry.npmjs.org/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.8.tgz", + "integrity": "sha512-9f1iZ2uWh92VcrU9Y8x+LdM4DLj75VE0MJB8zuF1iUnroEptStw+DQ8EQPMUdfe5k+PkB1uUfDQfWbhstH8LrQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/abstract-leveldown": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.3.0.tgz", + "integrity": "sha512-TU5nlYgta8YrBMNpc9FwQzRbiXsj49gsALsXadbGHt9CROPzX5fB0rWDR5mtdpOOKa5XqRFpbj1QroPAoPzVjQ==", + "deprecated": "Superseded by abstract-level (https://github.com/Level/community#faq)", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "immediate": "^3.2.3", + "level-concat-iterator": "~2.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/adm-zip": { + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", + "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.3.0" + } + }, + "node_modules/aes-js": { + "version": "4.0.0-beta.5", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz", + "integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==", + "license": "MIT" + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/amazon-cognito-identity-js": { + "version": "6.3.16", + "resolved": "https://registry.npmjs.org/amazon-cognito-identity-js/-/amazon-cognito-identity-js-6.3.16.tgz", + "integrity": "sha512-HPGSBGD6Q36t99puWh0LnptxO/4icnk2kqIQ9cTJ2tFQo5NMUnWQIgtrTAk8nm+caqUbjDzXzG56GBjI2tS6jQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-js": "1.2.2", + "buffer": "4.9.2", + "fast-base64-decode": "^1.0.0", + "isomorphic-unfetch": "^3.0.0", + "js-cookie": "^2.2.1" + } + }, + "node_modules/amazon-cognito-identity-js/node_modules/@aws-crypto/sha256-js": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-1.2.2.tgz", + "integrity": "sha512-Nr1QJIbW/afYYGzYvrF70LtaHrIRtd4TNAglX8BvlfxJLZ45SAmueIKYl5tWoNBPzp65ymXGFK0Bb1vZUpuc9g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^1.2.2", + "@aws-sdk/types": "^3.1.0", + "tslib": "^1.11.1" + } + }, + "node_modules/amazon-cognito-identity-js/node_modules/@aws-crypto/util": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-1.2.2.tgz", + "integrity": "sha512-H8PjG5WJ4wz0UXAFXeJjWCW1vkvIJ3qUUD+rGRwJ2/hj+xT58Qle2MTql/2MGzkU+1JLAFuR6aJpLAjHwhmwwg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.1.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + } + }, + "node_modules/amazon-cognito-identity-js/node_modules/buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "node_modules/amazon-cognito-identity-js/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/amazon-cognito-identity-js/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true, + "license": "0BSD" + }, + "node_modules/amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==", + "dev": true, + "license": "BSD-3-Clause OR MIT", + "optional": true, + "engines": { + "node": ">=0.4.2" + } + }, + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/antlr4": { + "version": "4.13.2", + "resolved": "https://registry.npmjs.org/antlr4/-/antlr4-4.13.2.tgz", + "integrity": "sha512-QiVbZhyy4xAZ17UPEuG3YTOt8ZaoeOR1CvEAqrEsDBsOqINslaB147i9xqljZqoyf5S+EUlGStaj+t22LT9MOg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=16" + } + }, + "node_modules/antlr4ts": { + "version": "0.5.0-alpha.4", + "resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz", + "integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true, + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/array-includes": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", + "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", + "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/ast-parents": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/ast-parents/-/ast-parents-0.0.1.tgz", + "integrity": "sha512-XHusKxKz3zoYk1ic8Un640joHbFMhbqneyoZfoKnEGtf2ey9Uh/IdpcQplODdO/kENaMIWsD0nJm4+wX3UNLHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", + "dev": true, + "license": "MIT" + }, + "node_modules/async-eventemitter": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/async-eventemitter/-/async-eventemitter-0.2.4.tgz", + "integrity": "sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "async": "^2.4.0" + } + }, + "node_modules/async-eventemitter/node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/async-retry": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", + "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "retry": "0.13.1" + } + }, + "node_modules/async-retry/node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz", + "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==", + "dev": true, + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz", + "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==", + "dev": true, + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/base-x": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.11.tgz", + "integrity": "sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/bech32": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", + "license": "MIT" + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bip39": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.0.4.tgz", + "integrity": "sha512-YZKQlb752TrUWqHWj7XAwCSjYEgGAk+/Aas3V7NyjQeZYsztO8JnQUaCWhcnL4T+jL8nvB8typ2jRPzTlgugNw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@types/node": "11.11.6", + "create-hash": "^1.1.0", + "pbkdf2": "^3.0.9", + "randombytes": "^2.0.1" + } + }, + "node_modules/bip39/node_modules/@types/node": { + "version": "11.11.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.6.tgz", + "integrity": "sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/blakejs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/bn-chai": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/bn-chai/-/bn-chai-1.0.1.tgz", + "integrity": "sha512-7rJXt21DwYiLLpvzLaACixBBoUGkRV1iuFD3wElEhw8Ji9IiY/QsJRtvW+c7ChRgEOyLQkGaSGFUUqBKm21SNA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "chai": ">= 2.1.2 < 5" + } + }, + "node_modules/bn.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", + "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==", + "license": "MIT" + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/body-parser/node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "dev": true, + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/bowser": { + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.14.1.tgz", + "integrity": "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==", + "dev": true, + "license": "MIT" + }, + "node_modules/boxen": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", + "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-align": "^3.0.0", + "camelcase": "^6.2.0", + "chalk": "^4.1.0", + "cli-boxes": "^2.2.1", + "string-width": "^4.2.2", + "type-fest": "^0.20.2", + "widest-line": "^3.1.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boxen/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/boxen/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boxen/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/boxen/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/boxen/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/boxen/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/brace-expansion": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", + "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", + "license": "MIT" + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true, + "license": "ISC" + }, + "node_modules/browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/buffer-to-arraybuffer": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz", + "integrity": "sha512-3dthu5CYiVB1DEJp61FtApNnNndTckcqe4pFcLdvHtrpG+kcyekCJKg4MRiDcFW7A6AODnXB9U4dwQiCW5kzJQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/bufferutil": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.9.tgz", + "integrity": "sha512-WDtdLmJvAuNNPzByAYpRo2rF1Mmradw6gvWsQKf63476DDXmomT9zUiGypLcG4ibIM67vhAj8jJRdbmEws2Aqw==", + "devOptional": true, + "hasInstallScript": true, + "license": "MIT", + "peer": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacheable-lookup": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-6.1.0.tgz", + "integrity": "sha512-KJ/Dmo1lDDhmW2XDPMo+9oiy/CeqosPguPCrgcVzKyZrL6pM1gU2GmPY/xo6OQPTUaA/c0kwHuywB4E6nmT9ww==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10.6.0" + } + }, + "node_modules/cacheable-request": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cacheable-request/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cacheable-request/node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/cbor": { + "version": "10.0.11", + "resolved": "https://registry.npmjs.org/cbor/-/cbor-10.0.11.tgz", + "integrity": "sha512-vIwORDd/WyB8Nc23o2zNN5RrtFGlR6Fca61TtjkUXueI3Jf2DOZDl1zsshvBntZ3wZHBM9ztjnkXSmzQDaq3WA==", + "dev": true, + "license": "MIT", + "dependencies": { + "nofilter": "^3.0.2" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/cbor2": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/cbor2/-/cbor2-1.12.0.tgz", + "integrity": "sha512-3Cco8XQhi27DogSp9Ri6LYNZLi/TBY/JVnDe+mj06NkBjW/ZYOtekaEU4wZ4xcRMNrFkDv8KNtOAqHyDfz3lYg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.7" + } + }, + "node_modules/chai": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", + "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chai-as-promised": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.2.tgz", + "integrity": "sha512-aBDHZxRzYnUYuIAIPBH2s511DjlKPzXNlXSGFC8CwmroWQLfrW0LtE1nK3MAwwNhJPa9raEjNCmRoFpG0Hurdw==", + "dev": true, + "license": "WTFPL", + "dependencies": { + "check-error": "^1.0.2" + }, + "peerDependencies": { + "chai": ">= 2.1.2 < 6" + } + }, + "node_modules/chai-bignumber": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/chai-bignumber/-/chai-bignumber-3.1.0.tgz", + "integrity": "sha512-omxEc80jAU+pZwRmoWr3aEzeLad4JW3iBhLRQlgISvghBdIxrMT7mVAGsDz4WSyCkKowENshH2j9OABAhld7QQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/chai-shallow-deep-equal": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/chai-shallow-deep-equal/-/chai-shallow-deep-equal-1.4.6.tgz", + "integrity": "sha512-2fBsQVRwrHdNO7IPYmoeH/V9+tuBDDg3k054NKdZ7tWeoi0URPzt8P+LNqcJioLVBTH/WiNM6a8CT5nWMebhPg==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + }, + "peerDependencies": { + "chai": ">= 1.9.0" + } + }, + "node_modules/chai-string": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/chai-string/-/chai-string-1.6.0.tgz", + "integrity": "sha512-sXV7whDmpax+8H++YaZelgin7aur1LGf9ZhjZa3ojETFJ0uPVuS4XEXuIagpZ/c8uVOtsSh4MwOjy5CBLjJSXA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "chai": "^4.1.2" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": "*" + } + }, + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/child_process": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/child_process/-/child_process-1.0.2.tgz", + "integrity": "sha512-Wmza/JzL0SiWz7kl6MhIKT5ceIlnFPJX+lwUGj7Clhy5MMldsSoJR0+uvRzOS5Kv45Mq7t1PoE8TsOA9bzvb6g==", + "dev": true, + "license": "ISC" + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true, + "license": "ISC", + "peer": true + }, + "node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cids": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/cids/-/cids-0.7.5.tgz", + "integrity": "sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA==", + "deprecated": "This module has been superseded by the multiformats module", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "buffer": "^5.5.0", + "class-is": "^1.1.0", + "multibase": "~0.6.0", + "multicodec": "^1.0.0", + "multihashes": "~0.4.15" + }, + "engines": { + "node": ">=4.0.0", + "npm": ">=3.0.0" + } + }, + "node_modules/cids/node_modules/multicodec": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-1.0.4.tgz", + "integrity": "sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg==", + "deprecated": "This module has been superseded by the multiformats module", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "buffer": "^5.6.0", + "varint": "^5.0.0" + } + }, + "node_modules/cipher-base": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.7.tgz", + "integrity": "sha512-Mz9QMT5fJe7bKI7MH31UilT5cEK5EHHRCccw/YRFsRY47AuNgaV6HY3rscp0/I4Q+tTW/5zoqpSeRRI54TkDWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.4", + "safe-buffer": "^5.2.1", + "to-buffer": "^1.2.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/class-is": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/class-is/-/class-is-1.1.0.tgz", + "integrity": "sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-table3": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-response": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", + "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "mimic-response": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" + }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/command-exists": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", + "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", + "dev": true, + "license": "MIT" + }, + "node_modules/command-line-args": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz", + "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==", + "license": "MIT", + "dependencies": { + "array-back": "^3.1.0", + "find-replace": "^3.0.0", + "lodash.camelcase": "^4.3.0", + "typical": "^4.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/command-line-usage": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-6.1.3.tgz", + "integrity": "sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw==", + "license": "MIT", + "dependencies": { + "array-back": "^4.0.2", + "chalk": "^2.4.2", + "table-layout": "^1.0.2", + "typical": "^5.2.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/command-line-usage/node_modules/array-back": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", + "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/command-line-usage/node_modules/typical": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", + "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/compare-versions": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.1.tgz", + "integrity": "sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "license": "MIT" + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "engines": [ + "node >= 0.8" + ], + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/concat-stream/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-stream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/concat-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-hash": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/content-hash/-/content-hash-2.5.2.tgz", + "integrity": "sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "cids": "^0.7.1", + "multicodec": "^0.5.5", + "multihashes": "^0.4.15" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/core-js-pure": { + "version": "3.48.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.48.0.tgz", + "integrity": "sha512-1slJgk89tWC51HQ1AEqG+s2VuwpTRr8ocu4n20QUcH1v9lAN0RXen0Q0AABa/DK1I7RrNWLucplOHMx8hfTGTw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-fetch": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.1.0.tgz", + "integrity": "sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "node-fetch": "^2.7.0" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": "*" + } + }, + "node_modules/d": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz", + "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "es5-ext": "^0.10.64", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dev": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/death": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", + "integrity": "sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w==", + "dev": true + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decode-uri-component": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-eql": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", + "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/deferred-leveldown": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz", + "integrity": "sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw==", + "deprecated": "Superseded by abstract-level (https://github.com/Level/community#faq)", + "dev": true, + "license": "MIT", + "dependencies": { + "abstract-leveldown": "~6.2.1", + "inherits": "^2.0.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/deferred-leveldown/node_modules/abstract-leveldown": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz", + "integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==", + "deprecated": "Superseded by abstract-level (https://github.com/Level/community#faq)", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "immediate": "^3.2.3", + "level-concat-iterator": "~2.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/diff": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.2.tgz", + "integrity": "sha512-vtcDfH3TOjP8UekytvnHH1o1P4FcUdt4eQ1Y+Abap1tk/OB2MWQvcwS2ClCd1zuIhc3JKOx6p3kod8Vfys3E+A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/difflib": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/difflib/-/difflib-0.2.4.tgz", + "integrity": "sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w==", + "dev": true, + "dependencies": { + "heap": ">= 0.2.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dom-walk": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", + "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", + "dev": true, + "peer": true + }, + "node_modules/dotenv": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", + "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=10" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/elliptic": { + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz", + "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==", + "license": "MIT", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", + "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", + "license": "MIT" + }, + "node_modules/emittery": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.0.tgz", + "integrity": "sha512-AGvFfs+d0JKCJQ4o01ASQLGPmSCxgfU9RFXvzPvZdjKK8oscynksuJhWrSTSw7j7Ep/sZct5b5ZhYCi8S/t0HQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/encode-utf8": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/encode-utf8/-/encode-utf8-1.0.3.tgz", + "integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==", + "dev": true, + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/encoding-down": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-6.3.0.tgz", + "integrity": "sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw==", + "deprecated": "Superseded by abstract-level (https://github.com/Level/community#faq)", + "dev": true, + "license": "MIT", + "dependencies": { + "abstract-leveldown": "^6.2.1", + "inherits": "^2.0.3", + "level-codec": "^9.0.0", + "level-errors": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/enquirer/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/enquirer/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", + "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es5-ext": { + "version": "0.10.64", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", + "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", + "dev": true, + "hasInstallScript": true, + "license": "ISC", + "peer": true, + "dependencies": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "esniff": "^2.0.1", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/es6-symbol": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz", + "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "d": "^1.0.2", + "ext": "^1.7.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/escodegen": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", + "integrity": "sha512-yhi5S+mNTOuRvyW4gWlg5W1byMaQGWWSYHXsuFZ7GBo7tpyOwi2EdzMP/QWxh9hwkD2m+wDVHJsxhRIj+v/b/A==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esprima": "^2.7.1", + "estraverse": "^1.9.1", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=0.12.0" + }, + "optionalDependencies": { + "source-map": "~0.2.0" + } + }, + "node_modules/escodegen/node_modules/estraverse": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", + "integrity": "sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/escodegen/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/eslint": { + "version": "9.39.2", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz", + "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.1", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.39.2", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-config-prettier": { + "version": "8.10.2", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.2.tgz", + "integrity": "sha512-/IGJ6+Dka158JnP5n5YFMOszjDWrXggGz1LaK/guZq9vZTmniaKlHcsscvkAhn9y4U+BU3JuUdYvtAMcv30y4A==", + "dev": true, + "license": "MIT", + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", + "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.32.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", + "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.9", + "array.prototype.findlastindex": "^1.2.6", + "array.prototype.flat": "^1.3.3", + "array.prototype.flatmap": "^1.3.3", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.1", + "hasown": "^2.0.2", + "is-core-module": "^2.16.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.1", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.9", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-import/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-prettier": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz", + "integrity": "sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "prettier-linter-helpers": "^1.0.0" + }, + "engines": { + "node": ">=6.0.0" + }, + "peerDependencies": { + "eslint": ">=5.0.0", + "prettier": ">=1.13.0" + }, + "peerDependenciesMeta": { + "eslint-config-prettier": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/esm": { + "version": "3.2.25", + "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", + "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/esniff": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", + "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.62", + "event-emitter": "^0.3.5", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eth-ens-namehash": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz", + "integrity": "sha512-VWEI1+KJfz4Km//dadyvBBoBeSQ0MHTXPvr8UIXiLW6IanxvAV+DmlZAijZwAyggqGUfwQBeHf7tc9wzc1piSw==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "idna-uts46-hx": "^2.3.1", + "js-sha3": "^0.5.7" + } + }, + "node_modules/eth-ens-namehash/node_modules/js-sha3": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", + "integrity": "sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/eth-gas-reporter": { + "version": "0.2.27", + "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.27.tgz", + "integrity": "sha512-femhvoAM7wL0GcI8ozTdxfuBtBFJ9qsyIAsmKVjlWAHUbdnnXHt+lKzz/kmldM5lA9jLuNHGwuIxorNpLbR1Zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@solidity-parser/parser": "^0.14.0", + "axios": "^1.5.1", + "cli-table3": "^0.5.0", + "colors": "1.4.0", + "ethereum-cryptography": "^1.0.3", + "ethers": "^5.7.2", + "fs-readdir-recursive": "^1.1.0", + "lodash": "^4.17.14", + "markdown-table": "^1.1.3", + "mocha": "^10.2.0", + "req-cwd": "^2.0.0", + "sha1": "^1.1.1", + "sync-request": "^6.0.0" + }, + "peerDependencies": { + "@codechecks/client": "^0.1.0" + }, + "peerDependenciesMeta": { + "@codechecks/client": { + "optional": true + } + } + }, + "node_modules/eth-gas-reporter/node_modules/@noble/hashes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", + "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT" + }, + "node_modules/eth-gas-reporter/node_modules/@scure/base": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", + "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/eth-gas-reporter/node_modules/@scure/bip32": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", + "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT", + "dependencies": { + "@noble/hashes": "~1.2.0", + "@noble/secp256k1": "~1.7.0", + "@scure/base": "~1.1.0" + } + }, + "node_modules/eth-gas-reporter/node_modules/@scure/bip39": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", + "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT", + "dependencies": { + "@noble/hashes": "~1.2.0", + "@scure/base": "~1.1.0" + } + }, + "node_modules/eth-gas-reporter/node_modules/cli-table3": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz", + "integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "object-assign": "^4.1.0", + "string-width": "^2.1.1" + }, + "engines": { + "node": ">=6" + }, + "optionalDependencies": { + "colors": "^1.1.2" + } + }, + "node_modules/eth-gas-reporter/node_modules/ethereum-cryptography": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz", + "integrity": "sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.2.0", + "@noble/secp256k1": "1.7.1", + "@scure/bip32": "1.1.5", + "@scure/bip39": "1.1.1" + } + }, + "node_modules/eth-gas-reporter/node_modules/ethers": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.8.0.tgz", + "integrity": "sha512-DUq+7fHrCg1aPDFCHx6UIPb3nmt2XMpM7Y/g2gLhsl3lIBqeAfOJIl1qEvRf2uq3BiKxmh6Fh5pfp2ieyek7Kg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abi": "5.8.0", + "@ethersproject/abstract-provider": "5.8.0", + "@ethersproject/abstract-signer": "5.8.0", + "@ethersproject/address": "5.8.0", + "@ethersproject/base64": "5.8.0", + "@ethersproject/basex": "5.8.0", + "@ethersproject/bignumber": "5.8.0", + "@ethersproject/bytes": "5.8.0", + "@ethersproject/constants": "5.8.0", + "@ethersproject/contracts": "5.8.0", + "@ethersproject/hash": "5.8.0", + "@ethersproject/hdnode": "5.8.0", + "@ethersproject/json-wallets": "5.8.0", + "@ethersproject/keccak256": "5.8.0", + "@ethersproject/logger": "5.8.0", + "@ethersproject/networks": "5.8.0", + "@ethersproject/pbkdf2": "5.8.0", + "@ethersproject/properties": "5.8.0", + "@ethersproject/providers": "5.8.0", + "@ethersproject/random": "5.8.0", + "@ethersproject/rlp": "5.8.0", + "@ethersproject/sha2": "5.8.0", + "@ethersproject/signing-key": "5.8.0", + "@ethersproject/solidity": "5.8.0", + "@ethersproject/strings": "5.8.0", + "@ethersproject/transactions": "5.8.0", + "@ethersproject/units": "5.8.0", + "@ethersproject/wallet": "5.8.0", + "@ethersproject/web": "5.8.0", + "@ethersproject/wordlists": "5.8.0" + } + }, + "node_modules/eth-gas-reporter/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/eth-gas-reporter/node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eth-lib": { + "version": "0.1.29", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.29.tgz", + "integrity": "sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "nano-json-stream-parser": "^0.1.2", + "servify": "^0.1.12", + "ws": "^3.0.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/eth-lib/node_modules/bn.js": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", + "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/eth-lib/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/eth-lib/node_modules/ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" + } + }, + "node_modules/ethereum-bloom-filters": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.2.0.tgz", + "integrity": "sha512-28hyiE7HVsWubqhpVLVmZXFd4ITeHi+BUu05o9isf0GUpMtzBUi+8/gFrGaGYzvGAJQmJ3JKj77Mk9G98T84rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/hashes": "^1.4.0" + } + }, + "node_modules/ethereum-bloom-filters/node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/ethereum-waffle": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/ethereum-waffle/-/ethereum-waffle-4.0.10.tgz", + "integrity": "sha512-iw9z1otq7qNkGDNcMoeNeLIATF9yKl1M8AIeu42ElfNBplq0e+5PeasQmm8ybY/elkZ1XyRO0JBQxQdVRb8bqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ethereum-waffle/chai": "4.0.10", + "@ethereum-waffle/compiler": "4.0.3", + "@ethereum-waffle/mock-contract": "4.0.4", + "@ethereum-waffle/provider": "4.0.5", + "solc": "0.8.15", + "typechain": "^8.0.0" + }, + "bin": { + "waffle": "bin/waffle" + }, + "engines": { + "node": ">=10.0" + }, + "peerDependencies": { + "ethers": "*" + } + }, + "node_modules/ethereum-waffle/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/ethereum-waffle/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/ethereum-waffle/node_modules/solc": { + "version": "0.8.15", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.8.15.tgz", + "integrity": "sha512-Riv0GNHNk/SddN/JyEuFKwbcWcEeho15iyupTSHw5Np6WuXA5D8kEHbyzDHi6sqmvLzu2l+8b1YmL8Ytple+8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "command-exists": "^1.2.8", + "commander": "^8.1.0", + "follow-redirects": "^1.12.1", + "js-sha3": "0.8.0", + "memorystream": "^0.3.1", + "semver": "^5.5.0", + "tmp": "0.0.33" + }, + "bin": { + "solcjs": "solc.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ethereumjs-abi": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", + "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==", + "deprecated": "This library has been deprecated and usage is discouraged.", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.11.8", + "ethereumjs-util": "^6.0.0" + } + }, + "node_modules/ethereumjs-abi/node_modules/@types/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/ethereumjs-abi/node_modules/bn.js": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", + "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/ethereumjs-abi/node_modules/ethereumjs-util": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", + "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "node_modules/ethereumjs-util": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", + "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@types/bn.js": "^5.1.0", + "bn.js": "^5.1.2", + "create-hash": "^1.1.2", + "ethereum-cryptography": "^0.1.3", + "rlp": "^2.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ethers": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.15.0.tgz", + "integrity": "sha512-Kf/3ZW54L4UT0pZtsY/rf+EkBU7Qi5nnhonjUb8yTXcxH3cdcWrV2cRyk0Xk/4jK6OoHhxxZHriyhje20If2hQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/ethers-io/" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@adraffy/ens-normalize": "1.10.1", + "@noble/curves": "1.2.0", + "@noble/hashes": "1.3.2", + "@types/node": "22.7.5", + "aes-js": "4.0.0-beta.5", + "tslib": "2.7.0", + "ws": "8.17.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/ethers/node_modules/@types/node": { + "version": "22.7.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz", + "integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/ethers/node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "license": "MIT" + }, + "node_modules/ethjs-unit": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", + "integrity": "sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "4.11.6", + "number-to-bn": "1.7.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/ethjs-unit/node_modules/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", + "dev": true, + "license": "MIT" + }, + "node_modules/ethjs-util": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", + "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-hex-prefixed": "1.0.0", + "strip-hex-prefix": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "node_modules/eventemitter2": { + "version": "6.4.9", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz", + "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==", + "license": "MIT" + }, + "node_modules/eventemitter3": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", + "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/express": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.12", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/express/node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "dev": true, + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "type": "^2.7.2" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true, + "license": "MIT" + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "license": "MIT" + }, + "node_modules/fast-base64-decode": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-base64-decode/-/fast-base64-decode-1.0.0.tgz", + "integrity": "sha512-qwaScUgUGBYeDNRnbc/KyllVU88Jk1pRHPStuF/lO7B0/RTRLj7U0lkdTAutlBblY08rwZDff6tNU9cjv6j//Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/fast-equals": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.3.3.tgz", + "integrity": "sha512-/boTcHZeIAQ2r/tL11voclBHDeP9WPxLt+tyAbVSyyXuUFyh0Tne7gJZTqGbxnvj79TjLdCXLOY7UIPhyG5MTw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fast-xml-builder": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.1.5.tgz", + "integrity": "sha512-4TJn/8FKLeslLAH3dnohXqE3QSoxkhvaMzepOIZytwJXZO69Bfz0HBdDHzOTOon6G59Zrk6VQ2bEiv1t61rfkA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "dependencies": { + "path-expression-matcher": "^1.1.3" + } + }, + "node_modules/fast-xml-parser": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.7.1.tgz", + "integrity": "sha512-8Cc3f8GUGUULg34pBch/KGyPLglS+OFs05deyOlY7fL2MTagYPKrVQNmR1fLF/yJ9PH5ZSTd3YDF6pnmeZU+zA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "dependencies": { + "@nodable/entities": "^2.1.0", + "fast-xml-builder": "^1.1.5", + "path-expression-matcher": "^1.5.0", + "strnum": "^2.2.3" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/find-replace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", + "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", + "license": "MIT", + "dependencies": { + "array-back": "^3.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, + "license": "ISC" + }, + "node_modules/fmix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/fmix/-/fmix-0.1.0.tgz", + "integrity": "sha512-Y6hyofImk9JdzU8k5INtTXX1cu8LDlePWDFU5sftm9H+zKCr5SGrVjdhkvsim646cw5zD0nADj8oHyXMZmCZ9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "imul": "^1.0.0" + } + }, + "node_modules/follow-redirects": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/form-data-encoder": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.1.tgz", + "integrity": "sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fp-ts": { + "version": "1.19.3", + "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", + "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==", + "dev": true, + "license": "MIT" + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "minipass": "^2.6.0" + } + }, + "node_modules/fs-readdir-recursive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", + "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "dev": true, + "license": "MIT" + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ganache": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/ganache/-/ganache-7.4.3.tgz", + "integrity": "sha512-RpEDUiCkqbouyE7+NMXG26ynZ+7sGiODU84Kz+FVoXUnQ4qQM4M8wif3Y4qUCt+D/eM1RVeGq0my62FPD6Y1KA==", + "bundleDependencies": [ + "@trufflesuite/bigint-buffer", + "emittery", + "keccak", + "leveldown", + "secp256k1", + "@types/bn.js", + "@types/lru-cache", + "@types/seedrandom" + ], + "dev": true, + "hasShrinkwrap": true, + "license": "MIT", + "dependencies": { + "@trufflesuite/bigint-buffer": "1.1.10", + "@types/bn.js": "^5.1.0", + "@types/lru-cache": "5.1.1", + "@types/seedrandom": "3.0.1", + "emittery": "0.10.0", + "keccak": "3.0.2", + "leveldown": "6.1.0", + "secp256k1": "4.0.3" + }, + "bin": { + "ganache": "dist/node/cli.js", + "ganache-cli": "dist/node/cli.js" + }, + "optionalDependencies": { + "bufferutil": "4.0.5", + "utf-8-validate": "5.0.7" + } + }, + "node_modules/ganache-cli": { + "version": "6.12.2", + "resolved": "https://registry.npmjs.org/ganache-cli/-/ganache-cli-6.12.2.tgz", + "integrity": "sha512-bnmwnJDBDsOWBUP8E/BExWf85TsdDEFelQSzihSJm9VChVO1SHp94YXLP5BlA4j/OTxp0wR4R1Tje9OHOuAJVw==", + "bundleDependencies": [ + "source-map-support", + "yargs", + "ethereumjs-util" + ], + "deprecated": "ganache-cli is now ganache; visit https://trfl.io/g7 for details", + "dev": true, + "license": "MIT", + "dependencies": { + "ethereumjs-util": "6.2.1", + "source-map-support": "0.5.12", + "yargs": "13.2.4" + }, + "bin": { + "ganache-cli": "cli.js" + } + }, + "node_modules/ganache-cli/node_modules/@types/bn.js": { + "version": "4.11.6", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/ganache-cli/node_modules/@types/node": { + "version": "14.11.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache-cli/node_modules/@types/pbkdf2": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/ganache-cli/node_modules/@types/secp256k1": { + "version": "4.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/ganache-cli/node_modules/ansi-regex": { + "version": "4.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-cli/node_modules/ansi-styles": { + "version": "3.2.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-cli/node_modules/base-x": { + "version": "3.0.8", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ganache-cli/node_modules/blakejs": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "CC0-1.0" + }, + "node_modules/ganache-cli/node_modules/bn.js": { + "version": "4.11.9", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache-cli/node_modules/brorand": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache-cli/node_modules/browserify-aes": { + "version": "1.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ganache-cli/node_modules/bs58": { + "version": "4.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/ganache-cli/node_modules/bs58check": { + "version": "2.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/ganache-cli/node_modules/buffer-from": { + "version": "1.1.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache-cli/node_modules/buffer-xor": { + "version": "1.0.3", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache-cli/node_modules/camelcase": { + "version": "5.3.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-cli/node_modules/cipher-base": { + "version": "1.0.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ganache-cli/node_modules/cliui": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/ganache-cli/node_modules/color-convert": { + "version": "1.9.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/ganache-cli/node_modules/color-name": { + "version": "1.1.3", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache-cli/node_modules/create-hash": { + "version": "1.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/ganache-cli/node_modules/create-hmac": { + "version": "1.1.7", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/ganache-cli/node_modules/cross-spawn": { + "version": "6.0.5", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/ganache-cli/node_modules/decamelize": { + "version": "1.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-cli/node_modules/elliptic": { + "version": "6.5.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + } + }, + "node_modules/ganache-cli/node_modules/emoji-regex": { + "version": "7.0.3", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache-cli/node_modules/end-of-stream": { + "version": "1.4.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/ganache-cli/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/ganache-cli/node_modules/ethereumjs-util": { + "version": "6.2.1", + "dev": true, + "inBundle": true, + "license": "MPL-2.0", + "dependencies": { + "@types/bn.js": "^4.11.3", + "bn.js": "^4.11.0", + "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", + "ethjs-util": "0.1.6", + "rlp": "^2.2.3" + } + }, + "node_modules/ganache-cli/node_modules/ethjs-util": { + "version": "0.1.6", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "is-hex-prefixed": "1.0.0", + "strip-hex-prefix": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/ganache-cli/node_modules/evp_bytestokey": { + "version": "1.0.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/ganache-cli/node_modules/execa": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-cli/node_modules/find-up": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-cli/node_modules/get-caller-file": { + "version": "2.0.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/ganache-cli/node_modules/get-stream": { + "version": "4.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-cli/node_modules/hash-base": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-cli/node_modules/hash.js": { + "version": "1.1.7", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/ganache-cli/node_modules/hmac-drbg": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/ganache-cli/node_modules/inherits": { + "version": "2.0.4", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/ganache-cli/node_modules/invert-kv": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-cli/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-cli/node_modules/is-hex-prefixed": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/ganache-cli/node_modules/is-stream": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-cli/node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/ganache-cli/node_modules/keccak": { + "version": "3.0.1", + "dev": true, + "hasInstallScript": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ganache-cli/node_modules/lcid": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "invert-kv": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-cli/node_modules/locate-path": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-cli/node_modules/map-age-cleaner": { + "version": "0.1.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "p-defer": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-cli/node_modules/md5.js": { + "version": "1.3.5", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/ganache-cli/node_modules/mem": { + "version": "4.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-cli/node_modules/mimic-fn": { + "version": "2.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-cli/node_modules/minimalistic-assert": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/ganache-cli/node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache-cli/node_modules/nice-try": { + "version": "1.0.5", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache-cli/node_modules/node-addon-api": { + "version": "2.0.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache-cli/node_modules/node-gyp-build": { + "version": "4.2.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/ganache-cli/node_modules/npm-run-path": { + "version": "2.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-cli/node_modules/once": { + "version": "1.4.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/ganache-cli/node_modules/os-locale": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-cli/node_modules/p-defer": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-cli/node_modules/p-finally": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-cli/node_modules/p-is-promise": { + "version": "2.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-cli/node_modules/p-limit": { + "version": "2.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ganache-cli/node_modules/p-locate": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-cli/node_modules/p-try": { + "version": "2.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-cli/node_modules/path-exists": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-cli/node_modules/path-key": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache-cli/node_modules/pbkdf2": { + "version": "3.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/ganache-cli/node_modules/pump": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/ganache-cli/node_modules/randombytes": { + "version": "2.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/ganache-cli/node_modules/readable-stream": { + "version": "3.6.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ganache-cli/node_modules/require-directory": { + "version": "2.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-cli/node_modules/require-main-filename": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/ganache-cli/node_modules/ripemd160": { + "version": "2.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/ganache-cli/node_modules/rlp": { + "version": "2.2.6", + "dev": true, + "inBundle": true, + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^4.11.1" + }, + "bin": { + "rlp": "bin/rlp" + } + }, + "node_modules/ganache-cli/node_modules/safe-buffer": { + "version": "5.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache-cli/node_modules/scrypt-js": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache-cli/node_modules/secp256k1": { + "version": "4.0.2", + "dev": true, + "hasInstallScript": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "elliptic": "^6.5.2", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ganache-cli/node_modules/semver": { + "version": "5.7.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/ganache-cli/node_modules/set-blocking": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/ganache-cli/node_modules/setimmediate": { + "version": "1.0.5", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache-cli/node_modules/sha.js": { + "version": "2.4.11", + "dev": true, + "inBundle": true, + "license": "(MIT AND BSD-3-Clause)", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/ganache-cli/node_modules/shebang-command": { + "version": "1.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-cli/node_modules/shebang-regex": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-cli/node_modules/signal-exit": { + "version": "3.0.3", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/ganache-cli/node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-cli/node_modules/source-map-support": { + "version": "0.5.12", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/ganache-cli/node_modules/string_decoder": { + "version": "1.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/ganache-cli/node_modules/string-width": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-cli/node_modules/strip-ansi": { + "version": "5.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-cli/node_modules/strip-eof": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ganache-cli/node_modules/strip-hex-prefix": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "is-hex-prefixed": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/ganache-cli/node_modules/util-deprecate": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache-cli/node_modules/which": { + "version": "1.3.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/ganache-cli/node_modules/which-module": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/ganache-cli/node_modules/wrap-ansi": { + "version": "5.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache-cli/node_modules/wrappy": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/ganache-cli/node_modules/y18n": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/ganache-cli/node_modules/yargs": { + "version": "13.2.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "os-locale": "^3.1.0", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.0" + } + }, + "node_modules/ganache-cli/node_modules/yargs-parser": { + "version": "13.1.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "node_modules/ganache/node_modules/@trufflesuite/bigint-buffer": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@trufflesuite/bigint-buffer/-/bigint-buffer-1.1.10.tgz", + "integrity": "sha512-pYIQC5EcMmID74t26GCC67946mgTJFiLXOT/BYozgrd4UEY2JHEGLhWi9cMiQCt5BSqFEvKkCHNnoj82SRjiEw==", + "dev": true, + "hasInstallScript": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "node-gyp-build": "4.4.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/ganache/node_modules/@trufflesuite/bigint-buffer/node_modules/node-gyp-build": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.4.0.tgz", + "integrity": "sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ==", + "dev": true, + "inBundle": true, + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/ganache/node_modules/@types/bn.js": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", + "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/ganache/node_modules/@types/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache/node_modules/@types/node": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.0.tgz", + "integrity": "sha512-eMhwJXc931Ihh4tkU+Y7GiLzT/y/DBNpNtr4yU9O2w3SYBsr9NaOPhQlLKRmoWtI54uNwuo0IOUFQjVOTZYRvw==", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache/node_modules/@types/seedrandom": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/seedrandom/-/seedrandom-3.0.1.tgz", + "integrity": "sha512-giB9gzDeiCeloIXDgzFBCgjj1k4WxcDrZtGl6h1IqmUPlxF+Nx8Ve+96QCyDZ/HseB/uvDsKbpib9hU5cU53pw==", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache/node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache/node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "inBundle": true, + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/ganache/node_modules/bufferutil": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.5.tgz", + "integrity": "sha512-HTm14iMQKK2FjFLRTM5lAVcyaUzOnqbPtesFIvREgXpJHdQm8bWS+GkQgIkfaBYRHuCnea7w8UVNfwiAQhlr9A==", + "dev": true, + "optional": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + } + }, + "node_modules/ganache/node_modules/catering": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/catering/-/catering-2.1.0.tgz", + "integrity": "sha512-M5imwzQn6y+ODBfgi+cfgZv2hIUI6oYU/0f35Mdb1ujGeqeoI5tOnl9Q13DTH7LW+7er+NYq8stNOKZD/Z3U/A==", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "queue-tick": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ganache/node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/ganache/node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache/node_modules/emittery": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.0.tgz", + "integrity": "sha512-AGvFfs+d0JKCJQ4o01ASQLGPmSCxgfU9RFXvzPvZdjKK8oscynksuJhWrSTSw7j7Ep/sZct5b5ZhYCi8S/t0HQ==", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/ganache/node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/ganache/node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/ganache/node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "inBundle": true, + "license": "BSD-3-Clause" + }, + "node_modules/ganache/node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/ganache/node_modules/is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ganache/node_modules/keccak": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.2.tgz", + "integrity": "sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ==", + "dev": true, + "hasInstallScript": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ganache/node_modules/leveldown": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/leveldown/-/leveldown-6.1.0.tgz", + "integrity": "sha512-8C7oJDT44JXxh04aSSsfcMI8YiaGRhOFI9/pMEL7nWJLVsWajDPTRxsSHTM2WcTVY5nXM+SuRHzPPi0GbnDX+w==", + "dev": true, + "hasInstallScript": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "abstract-leveldown": "^7.2.0", + "napi-macros": "~2.0.0", + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/ganache/node_modules/leveldown/node_modules/abstract-leveldown": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-7.2.0.tgz", + "integrity": "sha512-DnhQwcFEaYsvYDnACLZhMmCWd3rkOeEvglpa4q5i/5Jlm3UIsWaxVzuXvDLFCSCWRO3yy2/+V/G7FusFgejnfQ==", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "buffer": "^6.0.3", + "catering": "^2.0.0", + "is-buffer": "^2.0.5", + "level-concat-iterator": "^3.0.0", + "level-supports": "^2.0.1", + "queue-microtask": "^1.2.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ganache/node_modules/leveldown/node_modules/level-concat-iterator": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/level-concat-iterator/-/level-concat-iterator-3.1.0.tgz", + "integrity": "sha512-BWRCMHBxbIqPxJ8vHOvKUsaO0v1sLYZtjN3K2iZJsRBYtp+ONsY6Jfi6hy9K3+zolgQRryhIn2NRZjZnWJ9NmQ==", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "catering": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ganache/node_modules/leveldown/node_modules/level-supports": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-2.1.0.tgz", + "integrity": "sha512-E486g1NCjW5cF78KGPrMDRBYzPuueMZ6VBXHT6gC7A8UYWGiM14fGgp+s/L1oFfDWSPV/+SFkYCmZ0SiESkRKA==", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ganache/node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/ganache/node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache/node_modules/napi-macros": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.0.0.tgz", + "integrity": "sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache/node_modules/node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache/node_modules/node-gyp-build": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz", + "integrity": "sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==", + "dev": true, + "inBundle": true, + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/ganache/node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache/node_modules/queue-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.0.tgz", + "integrity": "sha512-ULWhjjE8BmiICGn3G8+1L9wFpERNxkf8ysxkAer4+TFdRefDaXOCV5m92aMB9FtBVmn/8sETXLXY6BfW7hyaWQ==", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ganache/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "inBundle": true, + "license": "MIT" + }, + "node_modules/ganache/node_modules/secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", + "dev": true, + "hasInstallScript": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "elliptic": "^6.5.4", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ganache/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/ganache/node_modules/utf-8-validate": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.7.tgz", + "integrity": "sha512-vLt1O5Pp+flcArHGIyKEQq883nBt8nN8tVBcoL0qUXj2XT1n7p70yGIq2VK98I5FdZ1YHc0wk/koOnHjnXWk1Q==", + "dev": true, + "optional": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + } + }, + "node_modules/ganache/node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/ghost-testrpc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz", + "integrity": "sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "chalk": "^2.4.2", + "node-emoji": "^1.10.0" + }, + "bin": { + "testrpc-sc": "index.js" + } + }, + "node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", + "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/global": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", + "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "min-document": "^2.19.0", + "process": "^0.11.10" + } + }, + "node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/got": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/got/-/got-12.1.0.tgz", + "integrity": "sha512-hBv2ty9QN2RdbJJMK3hesmSkFTjVIHyIDDbssCKnSmq62edGgImJWD10Eb1k77TiV1bxloxqcFAVK8+9pkhOig==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@sindresorhus/is": "^4.6.0", + "@szmarczak/http-timer": "^5.0.1", + "@types/cacheable-request": "^6.0.2", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^6.0.4", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "form-data-encoder": "1.7.1", + "get-stream": "^6.0.1", + "http2-wrapper": "^2.1.10", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^3.0.0", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/handlebars": { + "version": "4.7.9", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.9.tgz", + "integrity": "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/handlebars/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/hardhat": { + "version": "2.27.0", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.27.0.tgz", + "integrity": "sha512-du7ecjx1/ueAUjvtZhVkJvWytPCjlagG3ZktYTphfzAbc1Flc6sRolw5mhKL/Loub1EIFRaflutM4bdB/YsUUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ethereumjs/util": "^9.1.0", + "@ethersproject/abi": "^5.1.2", + "@nomicfoundation/edr": "^0.12.0-next.7", + "@nomicfoundation/solidity-analyzer": "^0.1.0", + "@sentry/node": "^5.18.1", + "adm-zip": "^0.4.16", + "aggregate-error": "^3.0.0", + "ansi-escapes": "^4.3.0", + "boxen": "^5.1.2", + "chokidar": "^4.0.0", + "ci-info": "^2.0.0", + "debug": "^4.1.1", + "enquirer": "^2.3.0", + "env-paths": "^2.2.0", + "ethereum-cryptography": "^1.0.3", + "find-up": "^5.0.0", + "fp-ts": "1.19.3", + "fs-extra": "^7.0.1", + "immutable": "^4.0.0-rc.12", + "io-ts": "1.10.4", + "json-stream-stringify": "^3.1.4", + "keccak": "^3.0.2", + "lodash": "^4.17.11", + "micro-eth-signer": "^0.14.0", + "mnemonist": "^0.38.0", + "mocha": "^10.0.0", + "p-map": "^4.0.0", + "picocolors": "^1.1.0", + "raw-body": "^2.4.1", + "resolve": "1.17.0", + "semver": "^6.3.0", + "solc": "0.8.26", + "source-map-support": "^0.5.13", + "stacktrace-parser": "^0.1.10", + "tinyglobby": "^0.2.6", + "tsort": "0.0.1", + "undici": "^5.14.0", + "uuid": "^8.3.2", + "ws": "^7.4.6" + }, + "bin": { + "hardhat": "internal/cli/bootstrap.js" + }, + "peerDependencies": { + "ts-node": "*", + "typescript": "*" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/hardhat-deploy": { + "version": "0.11.45", + "resolved": "https://registry.npmjs.org/hardhat-deploy/-/hardhat-deploy-0.11.45.tgz", + "integrity": "sha512-aC8UNaq3JcORnEUIwV945iJuvBwi65tjHVDU3v6mOcqik7WAzHVCJ7cwmkkipsHrWysrB5YvGF1q9S1vIph83w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ethersproject/abi": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/contracts": "^5.7.0", + "@ethersproject/providers": "^5.7.2", + "@ethersproject/solidity": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wallet": "^5.7.0", + "@types/qs": "^6.9.7", + "axios": "^0.21.1", + "chalk": "^4.1.2", + "chokidar": "^3.5.2", + "debug": "^4.3.2", + "enquirer": "^2.3.6", + "ethers": "^5.7.0", + "form-data": "^4.0.0", + "fs-extra": "^10.0.0", + "match-all": "^1.2.6", + "murmur-128": "^0.2.1", + "qs": "^6.9.4", + "zksync-web3": "^0.14.3" + } + }, + "node_modules/hardhat-deploy/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/hardhat-deploy/node_modules/axios": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.14.0" + } + }, + "node_modules/hardhat-deploy/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/hardhat-deploy/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/hardhat-deploy/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/hardhat-deploy/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/hardhat-deploy/node_modules/ethers": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.8.0.tgz", + "integrity": "sha512-DUq+7fHrCg1aPDFCHx6UIPb3nmt2XMpM7Y/g2gLhsl3lIBqeAfOJIl1qEvRf2uq3BiKxmh6Fh5pfp2ieyek7Kg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@ethersproject/abi": "5.8.0", + "@ethersproject/abstract-provider": "5.8.0", + "@ethersproject/abstract-signer": "5.8.0", + "@ethersproject/address": "5.8.0", + "@ethersproject/base64": "5.8.0", + "@ethersproject/basex": "5.8.0", + "@ethersproject/bignumber": "5.8.0", + "@ethersproject/bytes": "5.8.0", + "@ethersproject/constants": "5.8.0", + "@ethersproject/contracts": "5.8.0", + "@ethersproject/hash": "5.8.0", + "@ethersproject/hdnode": "5.8.0", + "@ethersproject/json-wallets": "5.8.0", + "@ethersproject/keccak256": "5.8.0", + "@ethersproject/logger": "5.8.0", + "@ethersproject/networks": "5.8.0", + "@ethersproject/pbkdf2": "5.8.0", + "@ethersproject/properties": "5.8.0", + "@ethersproject/providers": "5.8.0", + "@ethersproject/random": "5.8.0", + "@ethersproject/rlp": "5.8.0", + "@ethersproject/sha2": "5.8.0", + "@ethersproject/signing-key": "5.8.0", + "@ethersproject/solidity": "5.8.0", + "@ethersproject/strings": "5.8.0", + "@ethersproject/transactions": "5.8.0", + "@ethersproject/units": "5.8.0", + "@ethersproject/wallet": "5.8.0", + "@ethersproject/web": "5.8.0", + "@ethersproject/wordlists": "5.8.0" + } + }, + "node_modules/hardhat-deploy/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/hardhat-deploy/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/hardhat-deploy/node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/hardhat-deploy/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/hardhat-deploy/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/hardhat-deploy/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/hardhat-deploy/node_modules/zksync-web3": { + "version": "0.14.4", + "resolved": "https://registry.npmjs.org/zksync-web3/-/zksync-web3-0.14.4.tgz", + "integrity": "sha512-kYehMD/S6Uhe1g434UnaMN+sBr9nQm23Ywn0EUP5BfQCsbjcr3ORuS68PosZw8xUTu3pac7G6YMSnNHk+fwzvg==", + "deprecated": "This package has been deprecated in favor of zksync-ethers@5.0.0", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ethers": "^5.7.0" + } + }, + "node_modules/hardhat-gas-reporter": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.10.tgz", + "integrity": "sha512-02N4+So/fZrzJ88ci54GqwVA3Zrf0C9duuTyGt0CFRIh/CdNwbnTgkXkRfojOMLBQ+6t+lBIkgbsOtqMvNwikA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-uniq": "1.0.3", + "eth-gas-reporter": "^0.2.25", + "sha1": "^1.1.1" + }, + "peerDependencies": { + "hardhat": "^2.0.2" + } + }, + "node_modules/hardhat/node_modules/@noble/hashes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", + "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT" + }, + "node_modules/hardhat/node_modules/@scure/base": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", + "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/hardhat/node_modules/@scure/bip32": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", + "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT", + "dependencies": { + "@noble/hashes": "~1.2.0", + "@noble/secp256k1": "~1.7.0", + "@scure/base": "~1.1.0" + } + }, + "node_modules/hardhat/node_modules/@scure/bip39": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", + "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT", + "dependencies": { + "@noble/hashes": "~1.2.0", + "@scure/base": "~1.1.0" + } + }, + "node_modules/hardhat/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/hardhat/node_modules/ethereum-cryptography": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz", + "integrity": "sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.2.0", + "@noble/secp256k1": "1.7.1", + "@scure/bip32": "1.1.5", + "@scure/bip39": "1.1.1" + } + }, + "node_modules/hardhat/node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hardhat/node_modules/solc": { + "version": "0.8.26", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.8.26.tgz", + "integrity": "sha512-yiPQNVf5rBFHwN6SIf3TUUvVAFKcQqmSUFeq+fb6pNRCo0ZCgpYOZDi3BVoezCPIAcKrVYd/qXlBLUP9wVrZ9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "command-exists": "^1.2.8", + "commander": "^8.1.0", + "follow-redirects": "^1.12.1", + "js-sha3": "0.8.0", + "memorystream": "^0.3.1", + "semver": "^5.5.0", + "tmp": "0.0.33" + }, + "bin": { + "solcjs": "solc.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/hardhat/node_modules/solc/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/hardhat/node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hash-base": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.2.tgz", + "integrity": "sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^2.3.8", + "safe-buffer": "^5.2.1", + "to-buffer": "^1.2.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/hash-base/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/hash-base/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/hash-base/node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/hash-base/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/hash-base/node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/heap": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz", + "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==", + "dev": true, + "license": "MIT" + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "license": "MIT", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true, + "license": "ISC" + }, + "node_modules/http-basic": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", + "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "caseless": "^0.12.0", + "concat-stream": "^1.6.2", + "http-response-object": "^3.0.1", + "parse-cache-control": "^1.0.1" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-https": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz", + "integrity": "sha512-o0PWwVCSp3O0wS6FvNr6xfBCHgt0m1tvPLFOCc2iFDKTRAXhB7m8klDf7ErowFH8POa6dVdGatKU5I1YYwzUyg==", + "dev": true, + "license": "ISC", + "peer": true + }, + "node_modules/http-response-object": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", + "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "^10.0.3" + } + }, + "node_modules/http-response-object/node_modules/@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", + "dev": true, + "license": "MIT" + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/http2-wrapper": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", + "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/husky": { + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", + "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", + "dev": true, + "license": "MIT", + "bin": { + "husky": "bin.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==", + "license": "ISC" + }, + "node_modules/idna-uts46-hx": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz", + "integrity": "sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "punycode": "2.1.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/immediate": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", + "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/immer": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.0.2.tgz", + "integrity": "sha512-Rx3CqeqQ19sxUtYV9CU911Vhy8/721wRFnJv3REVGWUmoAcIwzifTsdmJte/MV+0/XpM35LZdQMBGkRIoLPwQA==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/immutable": { + "version": "4.3.8", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.8.tgz", + "integrity": "sha512-d/Ld9aLbKpNwyl0KiM2CT1WYvkitQ1TSvmRtkcV8FKStiDoA7Slzgjmb/1G2yhKM1p0XeNOieaTbFZmU1d3Xuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imul": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/imul/-/imul-1.0.1.tgz", + "integrity": "sha512-WFAgfwPLAjU66EKt6vRdTlKj4nAgIDQzh29JonLa4Bqtl6D8JrIMvWjCnx7xEjVNmP3U0fM5o8ZObk7d0f62bA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC" + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/io-ts": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz", + "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fp-ts": "^1.0.0" + } + }, + "node_modules/ip-address": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", + "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-arguments": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", + "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-function": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", + "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hex-prefixed": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", + "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-lambda": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-observable": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-2.1.0.tgz", + "integrity": "sha512-DailKdLb0WU+xX8K5w7VsJhapwHLZ9jjmazqCJq4X12CTgqq73TKnbRcnSLuXYPOoLQgV5IrD7ePiX/h1vnkBw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-url": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", + "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/isomorphic-unfetch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/isomorphic-unfetch/-/isomorphic-unfetch-3.1.0.tgz", + "integrity": "sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "node-fetch": "^2.6.1", + "unfetch": "^4.2.0" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "dev": true, + "license": "MIT" + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/js-base64": { + "version": "3.7.8", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.8.tgz", + "integrity": "sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow==", + "license": "BSD-3-Clause" + }, + "node_modules/js-cookie": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz", + "integrity": "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", + "license": "MIT" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, + "node_modules/json-bigint/node_modules/bignumber.js": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", + "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true, + "license": "(AFL-2.1 OR BSD-3-Clause)" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stream-stringify": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/json-stream-stringify/-/json-stream-stringify-3.1.6.tgz", + "integrity": "sha512-x7fpwxOkbhFCaJDJ8vb1fBY3DdSa4AlITaz+HHILQJzdPMnHEFjxPwVUi1ALIbcIxDE0PNe/0i7frnY8QnBQog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=7.10.1" + } + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true, + "license": "ISC" + }, + "node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dev": true, + "engines": [ + "node >= 0.2.0" + ], + "license": "MIT" + }, + "node_modules/jsonschema": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.5.0.tgz", + "integrity": "sha512-K+A9hhqbn0f3pJX17Q/7H6yQfD/5OXgdrR5UE12gMXCiN9D5Xq2o5mddV2QEcX/bjla99ASsAAQUyMCCRWAEhw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/keccak": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.4.tgz", + "integrity": "sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/keccak256": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/keccak256/-/keccak256-1.0.6.tgz", + "integrity": "sha512-8GLiM01PkdJVGUhR1e6M/AvWnSqYS0HaERI+K/QtStGDGlSTx2B1zTqZk4Zlqu5TxHJNTxWAdP9Y+WI50OApUw==", + "license": "MIT", + "dependencies": { + "bn.js": "^5.2.0", + "buffer": "^6.0.3", + "keccak": "^3.0.2" + } + }, + "node_modules/keccak256/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==", + "dev": true, + "license": "MIT", + "peer": true, + "optionalDependencies": { + "graceful-fs": "^4.1.9" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "invert-kv": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/level-codec": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-9.0.2.tgz", + "integrity": "sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ==", + "deprecated": "Superseded by level-transcoder (https://github.com/Level/community#faq)", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-concat-iterator": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz", + "integrity": "sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw==", + "deprecated": "Superseded by abstract-level (https://github.com/Level/community#faq)", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/level-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.1.tgz", + "integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==", + "deprecated": "Superseded by abstract-level (https://github.com/Level/community#faq)", + "dev": true, + "license": "MIT", + "dependencies": { + "errno": "~0.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-iterator-stream": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-4.0.2.tgz", + "integrity": "sha512-ZSthfEqzGSOMWoUGhTXdX9jv26d32XJuHz/5YnuHZzH6wldfWMOVwI9TBtKcya4BKTyTt3XVA0A3cF3q5CY30Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.4.0", + "xtend": "^4.0.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-mem": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/level-mem/-/level-mem-5.0.1.tgz", + "integrity": "sha512-qd+qUJHXsGSFoHTziptAKXoLX87QjR7v2KMbqncDXPxQuCdsQlzmyX+gwrEHhlzn08vkf8TyipYyMmiC6Gobzg==", + "deprecated": "Superseded by memory-level (https://github.com/Level/community#faq)", + "dev": true, + "license": "MIT", + "dependencies": { + "level-packager": "^5.0.3", + "memdown": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-packager": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/level-packager/-/level-packager-5.1.1.tgz", + "integrity": "sha512-HMwMaQPlTC1IlcwT3+swhqf/NUO+ZhXVz6TY1zZIIZlIR0YSn8GtAAWmIvKjNY16ZkEg/JcpAuQskxsXqC0yOQ==", + "deprecated": "Superseded by abstract-level (https://github.com/Level/community#faq)", + "dev": true, + "license": "MIT", + "dependencies": { + "encoding-down": "^6.3.0", + "levelup": "^4.3.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-supports": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-1.0.1.tgz", + "integrity": "sha512-rXM7GYnW8gsl1vedTJIbzOrRv85c/2uCMpiiCzO2fndd06U/kUXEEU9evYn4zFggBOg36IsBW8LzqIpETwwQzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "xtend": "^4.0.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-ws": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-2.0.0.tgz", + "integrity": "sha512-1iv7VXx0G9ec1isqQZ7y5LmoZo/ewAsyDHNA8EFDW5hqH2Kqovm33nSFkSdnLLAK+I5FlT+lo5Cw9itGe+CpQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "readable-stream": "^3.1.0", + "xtend": "^4.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/levelup": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/levelup/-/levelup-4.4.0.tgz", + "integrity": "sha512-94++VFO3qN95cM/d6eBXvd894oJE0w3cInq9USsyQzzoJxmiYzPAocNcuGCPGGjoXqDVJcr3C1jzt1TSjyaiLQ==", + "deprecated": "Superseded by abstract-level (https://github.com/Level/community#faq)", + "dev": true, + "license": "MIT", + "dependencies": { + "deferred-leveldown": "~5.3.0", + "level-errors": "~2.0.0", + "level-iterator-stream": "~4.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/load-json-file/node_modules/parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "error-ex": "^1.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/load-json-file/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/load-json-file/node_modules/strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "is-utf8": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/lodash.assign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "integrity": "sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "license": "MIT" + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", + "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/log-symbols/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-symbols/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/log-symbols/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.1" + } + }, + "node_modules/lowercase-keys": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lru_map": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", + "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/ltgt": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", + "integrity": "sha512-AI2r85+4MquTw9ZYqabu4nMwy9Oftlfa/e/52t9IjtfG+mGBbTNdAoZ3RQKLHR6r0wQnwZnPIEh/Ya6XTWAKNA==", + "dev": true, + "license": "MIT" + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true, + "license": "ISC" + }, + "node_modules/markdown-table": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", + "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/match-all": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/match-all/-/match-all-1.2.7.tgz", + "integrity": "sha512-qSpsBKarh55r9KyXzFC3xBLRf2GlGasba2em9kbpRsSlGvdTAqjx3QD0r3FKSARiW+OE4iMHYsolM3aX9n5djw==", + "dev": true, + "license": "MIT" + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mcl-wasm": { + "version": "0.7.9", + "resolved": "https://registry.npmjs.org/mcl-wasm/-/mcl-wasm-0.7.9.tgz", + "integrity": "sha512-iJIUcQWA88IJB/5L15GnJVnSQJmf/YaxxV6zRavv83HILHaJQb6y0iFyDMdDO0gN8X37tdxmAOrH/P8B6RB8sQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memdown": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/memdown/-/memdown-5.1.0.tgz", + "integrity": "sha512-B3J+UizMRAlEArDjWHTMmadet+UKwHd3UjMgGBkZcKAxAYVPS9o0Yeiha4qvz7iGiL2Sb3igUft6p7nbFWctpw==", + "deprecated": "Superseded by memory-level (https://github.com/Level/community#faq)", + "dev": true, + "license": "MIT", + "dependencies": { + "abstract-leveldown": "~6.2.1", + "functional-red-black-tree": "~1.0.1", + "immediate": "~3.2.3", + "inherits": "~2.0.1", + "ltgt": "~2.2.0", + "safe-buffer": "~5.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/memdown/node_modules/abstract-leveldown": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz", + "integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==", + "deprecated": "Superseded by abstract-level (https://github.com/Level/community#faq)", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "immediate": "^3.2.3", + "level-concat-iterator": "~2.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/memdown/node_modules/immediate": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.2.3.tgz", + "integrity": "sha512-RrGCXRm/fRVqMIhqXrGEX9rRADavPiDFSoMb/k64i9XMk8uH4r/Omi5Ctierj6XzNecwDbO4WuFbDD1zmpl3Tg==", + "dev": true, + "license": "MIT" + }, + "node_modules/memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", + "dev": true, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "dev": true, + "license": "MIT", + "peer": true, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/merkle-patricia-tree": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-4.2.4.tgz", + "integrity": "sha512-eHbf/BG6eGNsqqfbLED9rIqbsF4+sykEaBn6OLNs71tjclbMcMOk1tEPmJKcNcNCLkvbpY/lwyOlizWsqPNo8w==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@types/levelup": "^4.3.0", + "ethereumjs-util": "^7.1.4", + "level-mem": "^5.0.1", + "level-ws": "^2.0.0", + "readable-stream": "^3.6.0", + "semaphore-async-await": "^1.5.1" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micro-eth-signer": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/micro-eth-signer/-/micro-eth-signer-0.14.0.tgz", + "integrity": "sha512-5PLLzHiVYPWClEvZIXXFu5yutzpadb73rnQCpUqIHu3No3coFuWQNfE5tkBQJ7djuLYl6aRLaS0MgWJYGoqiBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/curves": "~1.8.1", + "@noble/hashes": "~1.7.1", + "micro-packed": "~0.7.2" + } + }, + "node_modules/micro-eth-signer/node_modules/@noble/curves": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.8.2.tgz", + "integrity": "sha512-vnI7V6lFNe0tLAuJMu+2sX+FcL14TaCWy1qiczg1VwRmPrpQCdq5ESXQMqUc2tluRNf6irBXrWbl1mGN8uaU/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.7.2" + }, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/micro-eth-signer/node_modules/@noble/hashes": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.2.tgz", + "integrity": "sha512-biZ0NUSxyjLLqo6KxEJ1b+C2NAx0wtDoFvCaXHGgUkeHzf3Xc1xKumFKREuT7f7DARNZ/slvYUwFG6B0f2b6hQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/micro-ftch": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/micro-ftch/-/micro-ftch-0.3.1.tgz", + "integrity": "sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==", + "dev": true, + "license": "MIT" + }, + "node_modules/micro-packed": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/micro-packed/-/micro-packed-0.7.3.tgz", + "integrity": "sha512-2Milxs+WNC00TRlem41oRswvw31146GiSaoCT7s3Xi2gMUglW5QBeqlQaZeHr5tJx9nm3i57LNXPqxOOaWtTYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@scure/base": "~1.2.5" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "bin": { + "miller-rabin": "bin/miller-rabin" + } + }, + "node_modules/miller-rabin/node_modules/bn.js": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", + "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/min-document": { + "version": "2.19.2", + "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.2.tgz", + "integrity": "sha512-8S5I8db/uZN8r9HSLFVWPdJCvYOejMcEC82VIzNUc6Zkklf/d1gg2psfE79/vyhWOj4+J8MtwmoOz3TmvaGu5A==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "dom-walk": "^0.1.0" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "license": "ISC" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", + "license": "MIT" + }, + "node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "node_modules/minipass-collect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", + "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-collect/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-fetch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz", + "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/minipass-fetch/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-fetch/node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-fetch/node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-fetch/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-flush/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "minipass": "^2.9.0" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mkdirp-promise": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz", + "integrity": "sha512-Hepn5kb1lJPtVW84RFT40YG1OddBNTOVUZR2bzQUHc+Z03en8/3uX0+060JDhcEzyO08HmipsN9DcnFMxhIL9w==", + "deprecated": "This package is broken and no longer maintained. 'mkdirp' itself supports promises now, please switch to that.", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "mkdirp": "*" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mnemonist": { + "version": "0.38.5", + "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz", + "integrity": "sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "obliterator": "^2.0.0" + } + }, + "node_modules/mocha": { + "version": "10.8.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz", + "integrity": "sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", + "chokidar": "^3.5.3", + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^8.1.0", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^6.5.1", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9", + "yargs-unparser": "^2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/mocha/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/mocha/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/mocha/node_modules/minimatch": { + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", + "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/mock-fs": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.14.0.tgz", + "integrity": "sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/multibase": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.6.1.tgz", + "integrity": "sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw==", + "deprecated": "This module has been superseded by the multiformats module", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "base-x": "^3.0.8", + "buffer": "^5.5.0" + } + }, + "node_modules/multicodec": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-0.5.7.tgz", + "integrity": "sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA==", + "deprecated": "This module has been superseded by the multiformats module", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "varint": "^5.0.0" + } + }, + "node_modules/multihashes": { + "version": "0.4.21", + "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-0.4.21.tgz", + "integrity": "sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "buffer": "^5.5.0", + "multibase": "^0.7.0", + "varint": "^5.0.0" + } + }, + "node_modules/multihashes/node_modules/multibase": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.7.0.tgz", + "integrity": "sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==", + "deprecated": "This module has been superseded by the multiformats module", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "base-x": "^3.0.8", + "buffer": "^5.5.0" + } + }, + "node_modules/murmur-128": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/murmur-128/-/murmur-128-0.2.1.tgz", + "integrity": "sha512-WseEgiRkI6aMFBbj8Cg9yBj/y+OdipwVC7zUo3W2W1JAJITwouUOtpqsmGSg67EQmwwSyod7hsVsWY5LsrfQVg==", + "dev": true, + "license": "MIT", + "dependencies": { + "encode-utf8": "^1.0.2", + "fmix": "^0.1.0", + "imul": "^1.0.0" + } + }, + "node_modules/nan": { + "version": "2.23.1", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.23.1.tgz", + "integrity": "sha512-r7bBUGKzlqk8oPBDYxt6Z0aEdF1G1rwlMcLk8LCOMbOzf0mG+JUfUzG4fIMWwHWP0iyaLWEQZJmtB7nOHEm/qw==", + "dev": true, + "license": "MIT" + }, + "node_modules/nano-json-stream-parser": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz", + "integrity": "sha512-9MqxMH/BSJC7dnLsEMPyfN5Dvoo49IsPFYMcHw3Bcfc2kN0lpHRBSzlMSVx4HGyJ7s9B31CyBTVehWJoQ8Ctew==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/ndjson": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ndjson/-/ndjson-2.0.0.tgz", + "integrity": "sha512-nGl7LRGrzugTtaFcJMhLbpzJM6XdivmbkdlaGcrk/LXg2KL/YBC6z1g70xh0/al+oFuVFP8N8kiWRucmeEH/qQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "json-stringify-safe": "^5.0.1", + "minimist": "^1.2.5", + "readable-stream": "^3.6.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + }, + "bin": { + "ndjson": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", + "dev": true, + "license": "ISC", + "peer": true + }, + "node_modules/node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==", + "license": "MIT" + }, + "node_modules/node-emoji": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", + "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash": "^4.17.21" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/nofilter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", + "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.19" + } + }, + "node_modules/nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==", + "dev": true, + "license": "ISC", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "peer": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/number-to-bn": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", + "integrity": "sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "4.11.6", + "strip-hex-prefix": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/number-to-bn/node_modules/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", + "dev": true, + "license": "MIT" + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obliterator": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.5.tgz", + "integrity": "sha512-42CPE9AhahZRsMNslczq0ctAEtqk8Eka26QofnqC346BZdHDySk3LWka23LI7ULIw11NmltpiLagIq8gBozxTw==", + "dev": true, + "license": "MIT" + }, + "node_modules/oboe": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.5.tgz", + "integrity": "sha512-zRFWiF+FoicxEs3jNI/WYUrVEgA7DeET/InK0XQuudGHRg8iIob3cNPrJTKaz4004uaA9Pbe+Dwa8iluhjLZWA==", + "dev": true, + "license": "BSD", + "peer": true, + "dependencies": { + "http-https": "^1.0.0" + } + }, + "node_modules/observable-fns": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/observable-fns/-/observable-fns-0.6.1.tgz", + "integrity": "sha512-9gRK4+sRWzeN6AOewNBTLXir7Zl/i3GB6Yl26gK4flxz8BXVpD3kt8amREmWNb0mxYOGDotvE5a4N+PtGGKdkg==", + "dev": true, + "license": "MIT" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/ora/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/ora/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/ora/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "lcid": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/p-cancelable": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", + "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12.20" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-cache-control": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", + "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==", + "dev": true + }, + "node_modules/parse-headers": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.6.tgz", + "integrity": "sha512-Tz11t3uKztEW5FEVZnj1ox8GKblWn+PvHY9TmJV5Mll2uHEwRdR/5Li1OlXoECjLYkApdhWy44ocONwXLiKO5A==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-expression-matcher": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.5.0.tgz", + "integrity": "sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/path-scurry/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/pbkdf2": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.5.tgz", + "integrity": "sha512-Q3CG/cYvCO1ye4QKkuH7EXxs3VC/rI1/trd+qX2+PolbaKG0H+bgcZzrTt96mMyRtejk+JMCiLUn3y29W8qmFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "ripemd160": "^2.0.3", + "safe-buffer": "^5.2.1", + "sha.js": "^2.4.12", + "to-buffer": "^1.2.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", + "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/proc-log": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", + "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true, + "license": "MIT" + }, + "node_modules/promise": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", + "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", + "dev": true, + "license": "MIT", + "dependencies": { + "asap": "~2.0.6" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/proper-lockfile": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", + "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "retry": "^0.12.0", + "signal-exit": "^3.0.2" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true, + "license": "MIT" + }, + "node_modules/prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", + "dev": true, + "license": "MIT" + }, + "node_modules/psl": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", + "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "funding": { + "url": "https://github.com/sponsors/lupomontero" + } + }, + "node_modules/psl/node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pump": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", + "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", + "integrity": "sha512-Yxz2kRwT90aPiWEMHVYnEf4+rhwF1tBmmZ4KepCP+Wkium9JxtWnUm1nqGwpiAHr/tnTSeHqr3wb++jgSkXjhA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/query-string": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", + "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "decode-uri-component": "^0.2.0", + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg-up/node_modules/path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg/node_modules/path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "dev": true, + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/recursive-readdir": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", + "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/recursive-readdir/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/recursive-readdir/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/reduce-flatten": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz", + "integrity": "sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/req-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-2.0.0.tgz", + "integrity": "sha512-ueoIoLo1OfB6b05COxAA9UpeoscNpYyM+BqYlA7H6LVF4hKGPXQQSSaD2YmvDVJMkk4UDpAHIeU1zG53IqjvlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "req-from": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/req-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/req-from/-/req-from-2.0.0.tgz", + "integrity": "sha512-LzTfEVDVQHBRfjOUMgNBA+V6DWsSnoeKzf42J7l0xa/B4jyPOuuF5MlNSmomLNGemWTnV2TIdjSSLnEn95fOQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/req-from/node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/request/node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/request/node_modules/qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/request/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz", + "integrity": "sha512-H7AkJWMobeskkttHyhTVtS0fxpFLjxhbfMa6Bk3wimP7sdPRGL3EyCg3sAQenFfAe+xQ+oAc85Nmtvq0ROM83Q==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==", + "dev": true, + "license": "ISC", + "peer": true + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "lowercase-keys": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/responselike/node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true, + "license": "MIT" + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ripemd160": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.3.tgz", + "integrity": "sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hash-base": "^3.1.2", + "inherits": "^2.0.4" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/rlp": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", + "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "bn.js": "^5.2.0" + }, + "bin": { + "rlp": "bin/rlp" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rustbn.js": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz", + "integrity": "sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==", + "dev": true, + "license": "(MIT OR Apache-2.0)" + }, + "node_modules/safe-array-concat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/sc-istanbul": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/sc-istanbul/-/sc-istanbul-0.4.6.tgz", + "integrity": "sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "abbrev": "1.0.x", + "async": "1.x", + "escodegen": "1.8.x", + "esprima": "2.7.x", + "glob": "^5.0.15", + "handlebars": "^4.0.1", + "js-yaml": "3.x", + "mkdirp": "0.5.x", + "nopt": "3.x", + "once": "1.x", + "resolve": "1.1.x", + "supports-color": "^3.1.0", + "which": "^1.1.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "istanbul": "lib/cli.js" + } + }, + "node_modules/sc-istanbul/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/sc-istanbul/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/sc-istanbul/node_modules/glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/sc-istanbul/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sc-istanbul/node_modules/js-yaml": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/sc-istanbul/node_modules/js-yaml/node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/sc-istanbul/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/sc-istanbul/node_modules/resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==", + "dev": true, + "license": "MIT" + }, + "node_modules/sc-istanbul/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/sc-istanbul/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/scrypt": { + "version": "6.0.3", + "resolved": "git+ssh://git@github.com/barrysteyn/node-scrypt.git#fb60a8d3c158fe115a624b5ffa7480f3a24b03fb", + "integrity": "sha512-IkT3V+hfrspn9KZBir79W1P0F4XWHIWm7QLYUhs9dvF9hBPUGypDhTOghV++XjJ2+5xS3GCqKuuE0hlLznL9tg==", + "dev": true, + "hasInstallScript": true, + "license": "zlib", + "dependencies": { + "nan": "^2.14.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", + "license": "MIT" + }, + "node_modules/secp256k1": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.4.tgz", + "integrity": "sha512-6JfvwvjUOn8F/jUoBY2Q1v5WY5XS+rj8qSe0v8Y4ezH4InLgTEeOOPQsRll9OV429Pvo6BCHGavIyJfr3TAhsw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "elliptic": "^6.5.7", + "node-addon-api": "^5.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/secp256k1/node_modules/node-addon-api": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", + "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==", + "dev": true, + "license": "MIT" + }, + "node_modules/seedrandom": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", + "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/semaphore-async-await": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/semaphore-async-await/-/semaphore-async-await-1.5.1.tgz", + "integrity": "sha512-b/ptP11hETwYWpeilHXXQiV5UJNJl7ZWWooKRE5eBIYWoom6dZ0SluCIdCtKycsMtZgKWE01/qAw6jblw1YVhg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.1" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/servify": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz", + "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "body-parser": "^1.16.0", + "cors": "^2.8.1", + "express": "^4.14.0", + "request": "^2.79.0", + "xhr": "^2.3.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true, + "license": "ISC", + "peer": true + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "dev": true, + "license": "MIT" + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true, + "license": "ISC" + }, + "node_modules/sha.js": { + "version": "2.4.12", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.12.tgz", + "integrity": "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==", + "dev": true, + "license": "(MIT AND BSD-3-Clause)", + "dependencies": { + "inherits": "^2.0.4", + "safe-buffer": "^5.2.1", + "to-buffer": "^1.2.0" + }, + "bin": { + "sha.js": "bin.js" + }, + "engines": { + "node": ">= 0.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/sha1": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/sha1/-/sha1-1.1.1.tgz", + "integrity": "sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "charenc": ">= 0.0.1", + "crypt": ">= 0.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/shelljs/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/shelljs/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/shelljs/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "peer": true + }, + "node_modules/simple-get": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.2.tgz", + "integrity": "sha512-Ijd/rV5o+mSBBs4F/x9oDPtTx9Zb6X9brmnXvMW4J7IR15ngi9q5xxqWBKU744jTZiaXtxaPL7uHG6vtN8kUkw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "decompress-response": "^3.3.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/simple-get/node_modules/decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "mimic-response": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/slice-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/solc": { + "version": "0.4.26", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.26.tgz", + "integrity": "sha512-o+c6FpkiHd+HPjmjEVpQgH7fqZ14tJpXhho+/bQXlXbliLIS/xjXb42Vxh+qQY1WCSTMQ0+a5vR9vi0MfhU6mA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "fs-extra": "^0.30.0", + "memorystream": "^0.3.1", + "require-from-string": "^1.1.0", + "semver": "^5.3.0", + "yargs": "^4.7.1" + }, + "bin": { + "solcjs": "solcjs" + } + }, + "node_modules/solc/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/solc/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/solc/node_modules/camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/solc/node_modules/cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + } + }, + "node_modules/solc/node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/solc/node_modules/fs-extra": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + }, + "node_modules/solc/node_modules/get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "dev": true, + "license": "ISC", + "peer": true + }, + "node_modules/solc/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/solc/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/solc/node_modules/jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", + "dev": true, + "license": "MIT", + "peer": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/solc/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/solc/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/solc/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "peer": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/solc/node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/solc/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/solc/node_modules/wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/solc/node_modules/y18n": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", + "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", + "dev": true, + "license": "ISC", + "peer": true + }, + "node_modules/solc/node_modules/yargs": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", + "integrity": "sha512-LqodLrnIDM3IFT+Hf/5sxBnEGECrfdC1uIbgZeJmESCSo4HoCAaKEus8MylXHAkdacGc0ye+Qa+dpkuom8uVYA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "lodash.assign": "^4.0.3", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^1.0.1", + "which-module": "^1.0.0", + "window-size": "^0.2.0", + "y18n": "^3.2.1", + "yargs-parser": "^2.4.1" + } + }, + "node_modules/solc/node_modules/yargs-parser": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", + "integrity": "sha512-9pIKIJhnI5tonzG6OnCFlz/yln8xHYcGl+pn3xR0Vzff0vzN1PbNRaelgfgRUwZ3s4i3jvxT9WhmUGL4whnasA==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "camelcase": "^3.0.0", + "lodash.assign": "^4.0.6" + } + }, + "node_modules/solhint": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/solhint/-/solhint-3.6.2.tgz", + "integrity": "sha512-85EeLbmkcPwD+3JR7aEMKsVC9YrRSxd4qkXuMzrlf7+z2Eqdfm1wHWq1ffTuo5aDhoZxp2I9yF3QkxZOxOL7aQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@solidity-parser/parser": "^0.16.0", + "ajv": "^6.12.6", + "antlr4": "^4.11.0", + "ast-parents": "^0.0.1", + "chalk": "^4.1.2", + "commander": "^10.0.0", + "cosmiconfig": "^8.0.0", + "fast-diff": "^1.2.0", + "glob": "^8.0.3", + "ignore": "^5.2.4", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "pluralize": "^8.0.0", + "semver": "^7.5.2", + "strip-ansi": "^6.0.1", + "table": "^6.8.1", + "text-table": "^0.2.0" + }, + "bin": { + "solhint": "solhint.js" + }, + "optionalDependencies": { + "prettier": "^2.8.3" + } + }, + "node_modules/solhint/node_modules/@solidity-parser/parser": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.16.2.tgz", + "integrity": "sha512-PI9NfoA3P8XK2VBkK5oIfRgKDsicwDZfkVq9ZTBCQYGOP1N2owgY2dyLGyU5/J/hQs8KRk55kdmvTLjy3Mu3vg==", + "dev": true, + "license": "MIT", + "dependencies": { + "antlr4ts": "^0.5.0-alpha.4" + } + }, + "node_modules/solhint/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/solhint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/solhint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/solhint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/solhint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/solhint/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/solhint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/solhint/node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "license": "MIT", + "optional": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/solhint/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/solhint/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/solhint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/solidity-ast": { + "version": "0.4.61", + "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.61.tgz", + "integrity": "sha512-OYBJYcYyG7gLV0VuXl9CUrvgJXjV/v0XnR4+1YomVe3q+QyENQXJJxAEASUz4vN6lMAl+C8RSRSr5MBAz09f6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/solidity-coverage": { + "version": "0.8.17", + "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.8.17.tgz", + "integrity": "sha512-5P8vnB6qVX9tt1MfuONtCTEaEGO/O4WuEidPHIAJjx4sktHHKhO3rFvnE0q8L30nWJPTrcqGQMT7jpE29B2qow==", + "dev": true, + "license": "ISC", + "dependencies": { + "@ethersproject/abi": "^5.0.9", + "@solidity-parser/parser": "^0.20.1", + "chalk": "^2.4.2", + "death": "^1.1.0", + "difflib": "^0.2.4", + "fs-extra": "^8.1.0", + "ghost-testrpc": "^0.0.2", + "global-modules": "^2.0.0", + "globby": "^10.0.1", + "jsonschema": "^1.2.4", + "lodash": "^4.17.21", + "mocha": "^10.2.0", + "node-emoji": "^1.10.0", + "pify": "^4.0.1", + "recursive-readdir": "^2.2.2", + "sc-istanbul": "^0.4.5", + "semver": "^7.3.4", + "shelljs": "^0.8.3", + "web3-utils": "^1.3.6" + }, + "bin": { + "solidity-coverage": "plugins/bin.js" + }, + "peerDependencies": { + "hardhat": "^2.11.0" + } + }, + "node_modules/solidity-coverage/node_modules/@solidity-parser/parser": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.20.2.tgz", + "integrity": "sha512-rbu0bzwNvMcwAjH86hiEAcOeRI2EeK8zCkHDrFykh/Al8mvJeFmjy3UrE7GYQjNwOgbGUUtCn5/k8CB8zIu7QA==", + "dev": true, + "license": "MIT" + }, + "node_modules/solidity-coverage/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/solidity-coverage/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/solidity-coverage/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/solidity-coverage/node_modules/globby": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", + "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/solidity-coverage/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/solidity-coverage/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/source-map": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", + "integrity": "sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA==", + "dev": true, + "optional": true, + "dependencies": { + "amdefine": ">=0.0.4" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0", + "peer": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.22", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz", + "integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==", + "dev": true, + "license": "CC0-1.0", + "peer": true + }, + "node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dev": true, + "license": "ISC", + "dependencies": { + "readable-stream": "^3.0.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/sshpk": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", + "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stacktrace-parser": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.11.tgz", + "integrity": "sha512-WjlahMgHmCJpqzU8bIBy4qtsZdU9lRlcZE3Lvyej6t4tuOuv1vk57OW3MBrj6hXBFx/nNoC9MPMTcr5YA7NQbg==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.7.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/stacktrace-parser/node_modules/type-fest": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", + "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-format": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/string-format/-/string-format-2.0.0.tgz", + "integrity": "sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA==", + "license": "WTFPL OR MIT" + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-hex-prefix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", + "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-hex-prefixed": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strnum": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.3.tgz", + "integrity": "sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT" + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/swarm-js": { + "version": "0.1.42", + "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.42.tgz", + "integrity": "sha512-BV7c/dVlA3R6ya1lMlSSNPLYrntt0LUq4YMgy3iwpCIc6rZnS5W2wUoctarZ5pXlpKtxDDf9hNziEkcfrxdhqQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "bluebird": "^3.5.0", + "buffer": "^5.0.5", + "eth-lib": "^0.1.26", + "fs-extra": "^4.0.2", + "got": "^11.8.5", + "mime-types": "^2.1.16", + "mkdirp-promise": "^5.0.1", + "mock-fs": "^4.1.0", + "setimmediate": "^1.0.5", + "tar": "^4.0.2", + "xhr-request": "^1.0.1" + } + }, + "node_modules/swarm-js/node_modules/@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/swarm-js/node_modules/cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10.6.0" + } + }, + "node_modules/swarm-js/node_modules/fs-extra": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", + "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "node_modules/swarm-js/node_modules/got": { + "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=10.19.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/swarm-js/node_modules/http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/swarm-js/node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/swarm-js/node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/sync-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", + "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "http-response-object": "^3.0.1", + "sync-rpc": "^1.2.1", + "then-request": "^6.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/sync-rpc": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", + "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-port": "^3.1.0" + } + }, + "node_modules/table": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.9.0.tgz", + "integrity": "sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table-layout": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-1.0.2.tgz", + "integrity": "sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==", + "license": "MIT", + "dependencies": { + "array-back": "^4.0.1", + "deep-extend": "~0.6.0", + "typical": "^5.2.0", + "wordwrapjs": "^4.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/table-layout/node_modules/array-back": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", + "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/table-layout/node_modules/typical": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", + "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/table/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/table/node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/table/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar": { + "version": "4.4.19", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", + "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "chownr": "^1.1.4", + "fs-minipass": "^1.2.7", + "minipass": "^2.9.0", + "minizlib": "^1.3.3", + "mkdirp": "^0.5.5", + "safe-buffer": "^5.2.1", + "yallist": "^3.1.1" + }, + "engines": { + "node": ">=4.5" + } + }, + "node_modules/testrpc": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/testrpc/-/testrpc-0.0.1.tgz", + "integrity": "sha512-afH1hO+SQ/VPlmaLUFj2636QMeDvPCeQMc/9RBMW0IfjNe9gFD9Ra3ShqYkB7py0do1ZcCna/9acHyzTJ+GcNA==", + "deprecated": "testrpc has been renamed to ganache-cli, please use this package from now on.", + "dev": true, + "peer": true + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true, + "license": "MIT" + }, + "node_modules/then-request": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", + "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/concat-stream": "^1.6.0", + "@types/form-data": "0.0.33", + "@types/node": "^8.0.0", + "@types/qs": "^6.2.31", + "caseless": "~0.12.0", + "concat-stream": "^1.6.0", + "form-data": "^2.2.0", + "http-basic": "^8.1.1", + "http-response-object": "^3.0.1", + "promise": "^8.0.0", + "qs": "^6.4.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/then-request/node_modules/@types/node": { + "version": "8.10.66", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", + "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/then-request/node_modules/form-data": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.5.tgz", + "integrity": "sha512-jqdObeR2rxZZbPSGL+3VckHMYtu+f9//KXBsVny6JSX/pa38Fy+bGjuG8eW/H6USNQWhLi8Num++cU2yOCNz4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.35", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/threads": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/threads/-/threads-1.7.0.tgz", + "integrity": "sha512-Mx5NBSHX3sQYR6iI9VYbgHKBLisyB+xROCBGjjWm1O9wb9vfLxdaGtmT/KCjUqMsSNW6nERzCW3T6H43LqjDZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.1.0", + "debug": "^4.2.0", + "is-observable": "^2.1.0", + "observable-fns": "^0.6.1" + }, + "funding": { + "url": "https://github.com/andywer/threads.js?sponsor=1" + }, + "optionalDependencies": { + "tiny-worker": ">= 2" + } + }, + "node_modules/through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "3" + } + }, + "node_modules/timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tiny-worker": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tiny-worker/-/tiny-worker-2.3.0.tgz", + "integrity": "sha512-pJ70wq5EAqTAEl9IkGzA+fN0836rycEuz2Cn6yeZ6FRzlVS5IDOkFHpIoEsksPRQV34GDqXm65+OlnZqUSyK2g==", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "esm": "^3.2.25" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-buffer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.2.tgz", + "integrity": "sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "isarray": "^2.0.5", + "safe-buffer": "^5.2.1", + "typed-array-buffer": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tough-cookie/node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true, + "license": "MIT" + }, + "node_modules/ts-api-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/ts-command-line-args": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/ts-command-line-args/-/ts-command-line-args-2.5.1.tgz", + "integrity": "sha512-H69ZwTw3rFHb5WYpQya40YAX2/w7Ut75uUECbgBIsLmM+BNuYnxsltfyyLMxy6sEeKxgijLTnQtLd0nKd6+IYw==", + "license": "ISC", + "dependencies": { + "chalk": "^4.1.0", + "command-line-args": "^5.1.1", + "command-line-usage": "^6.1.0", + "string-format": "^2.0.0" + }, + "bin": { + "write-markdown": "dist/write-markdown.js" + } + }, + "node_modules/ts-command-line-args/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ts-command-line-args/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/ts-command-line-args/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/ts-command-line-args/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/ts-command-line-args/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ts-command-line-args/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ts-essentials": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-7.0.3.tgz", + "integrity": "sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==", + "license": "MIT", + "peerDependencies": { + "typescript": ">=3.7.0" + } + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/diff": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz", + "integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tslib": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", + "license": "0BSD" + }, + "node_modules/tslog": { + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/tslog/-/tslog-4.10.2.tgz", + "integrity": "sha512-XuELoRpMR+sq8fuWwX7P0bcj+PRNiicOKDEb3fGNURhxWVyykCi9BNq7c4uVz7h7P0sj8qgBsr5SWS6yBClq3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/fullstack-build/tslog?sponsor=1" + } + }, + "node_modules/tsort": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz", + "integrity": "sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==", + "dev": true, + "license": "MIT" + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "dev": true, + "license": "Unlicense" + }, + "node_modules/type": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.3.tgz", + "integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==", + "dev": true, + "license": "ISC", + "peer": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typechain": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/typechain/-/typechain-8.3.2.tgz", + "integrity": "sha512-x/sQYr5w9K7yv3es7jo4KTX05CLxOf7TRWwoHlrjRh8H82G64g+k7VuWPJlgMo6qrjfCulOdfBjiaDtmhFYD/Q==", + "license": "MIT", + "dependencies": { + "@types/prettier": "^2.1.1", + "debug": "^4.3.1", + "fs-extra": "^7.0.0", + "glob": "7.1.7", + "js-sha3": "^0.8.0", + "lodash": "^4.17.15", + "mkdirp": "^1.0.4", + "prettier": "^2.3.1", + "ts-command-line-args": "^2.2.0", + "ts-essentials": "^7.0.1" + }, + "bin": { + "typechain": "dist/cli/cli.js" + }, + "peerDependencies": { + "typescript": ">=4.3.0" + } + }, + "node_modules/typechain/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/typechain/node_modules/glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/typechain/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/typechain/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/typechain/node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "license": "MIT", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/typical": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", + "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/ultron": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undici": { + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.29.0.tgz", + "integrity": "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@fastify/busboy": "^2.0.0" + }, + "engines": { + "node": ">=14.0" + } + }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "dev": true, + "license": "MIT" + }, + "node_modules/unfetch": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/unfetch/-/unfetch-4.2.0.tgz", + "integrity": "sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==", + "dev": true, + "license": "MIT" + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.4.tgz", + "integrity": "sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^1.4.1", + "qs": "^6.12.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/url-set-query": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz", + "integrity": "sha512-3AChu4NiXquPfeckE5R5cGdiHCMWJx1dwCWOmWIL4KHAziJNOFIYJlpGFeKDvwLPHovZRCxK3cYlwzqI9Vp+Gg==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/url/node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/utf-8-validate": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", + "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", + "devOptional": true, + "hasInstallScript": true, + "license": "MIT", + "peer": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/utf8": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", + "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true, + "license": "MIT" + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/varint": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz", + "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/web3": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3/-/web3-1.10.4.tgz", + "integrity": "sha512-kgJvQZjkmjOEKimx/tJQsqWfRDPTTcBfYPa9XletxuHLpHcXdx67w8EFn5AW3eVxCutE9dTVHgGa9VYe8vgsEA==", + "dev": true, + "hasInstallScript": true, + "license": "LGPL-3.0", + "peer": true, + "dependencies": { + "web3-bzz": "1.10.4", + "web3-core": "1.10.4", + "web3-eth": "1.10.4", + "web3-eth-personal": "1.10.4", + "web3-net": "1.10.4", + "web3-shh": "1.10.4", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-bzz": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.10.4.tgz", + "integrity": "sha512-ZZ/X4sJ0Uh2teU9lAGNS8EjveEppoHNQiKlOXAjedsrdWuaMErBPdLQjXfcrYvN6WM6Su9PMsAxf3FXXZ+HwQw==", + "dev": true, + "hasInstallScript": true, + "license": "LGPL-3.0", + "peer": true, + "dependencies": { + "@types/node": "^12.12.6", + "got": "12.1.0", + "swarm-js": "^0.1.40" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-bzz/node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/web3-core": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.10.4.tgz", + "integrity": "sha512-B6elffYm81MYZDTrat7aEhnhdtVE3lDBUZft16Z8awYMZYJDbnykEbJVS+l3mnA7AQTnSDr/1MjWofGDLBJPww==", + "dev": true, + "license": "LGPL-3.0", + "peer": true, + "dependencies": { + "@types/bn.js": "^5.1.1", + "@types/node": "^12.12.6", + "bignumber.js": "^9.0.0", + "web3-core-helpers": "1.10.4", + "web3-core-method": "1.10.4", + "web3-core-requestmanager": "1.10.4", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-helpers": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.10.4.tgz", + "integrity": "sha512-r+L5ylA17JlD1vwS8rjhWr0qg7zVoVMDvWhajWA5r5+USdh91jRUYosp19Kd1m2vE034v7Dfqe1xYRoH2zvG0g==", + "dev": true, + "license": "LGPL-3.0", + "peer": true, + "dependencies": { + "web3-eth-iban": "1.10.4", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-method": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.10.4.tgz", + "integrity": "sha512-uZTb7flr+Xl6LaDsyTeE2L1TylokCJwTDrIVfIfnrGmnwLc6bmTWCCrm71sSrQ0hqs6vp/MKbQYIYqUN0J8WyA==", + "dev": true, + "license": "LGPL-3.0", + "peer": true, + "dependencies": { + "@ethersproject/transactions": "^5.6.2", + "web3-core-helpers": "1.10.4", + "web3-core-promievent": "1.10.4", + "web3-core-subscriptions": "1.10.4", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-promievent": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.10.4.tgz", + "integrity": "sha512-2de5WnJQ72YcIhYwV/jHLc4/cWJnznuoGTJGD29ncFQHAfwW/MItHFSVKPPA5v8AhJe+r6y4Y12EKvZKjQVBvQ==", + "dev": true, + "license": "LGPL-3.0", + "peer": true, + "dependencies": { + "eventemitter3": "4.0.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-requestmanager": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.10.4.tgz", + "integrity": "sha512-vqP6pKH8RrhT/2MoaU+DY/OsYK9h7HmEBNCdoMj+4ZwujQtw/Mq2JifjwsJ7gits7Q+HWJwx8q6WmQoVZAWugg==", + "dev": true, + "license": "LGPL-3.0", + "peer": true, + "dependencies": { + "util": "^0.12.5", + "web3-core-helpers": "1.10.4", + "web3-providers-http": "1.10.4", + "web3-providers-ipc": "1.10.4", + "web3-providers-ws": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core-subscriptions": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.10.4.tgz", + "integrity": "sha512-o0lSQo/N/f7/L76C0HV63+S54loXiE9fUPfHFcTtpJRQNDBVsSDdWRdePbWwR206XlsBqD5VHApck1//jEafTw==", + "dev": true, + "license": "LGPL-3.0", + "peer": true, + "dependencies": { + "eventemitter3": "4.0.4", + "web3-core-helpers": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-core/node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/web3-core/node_modules/bignumber.js": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", + "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": "*" + } + }, + "node_modules/web3-eth": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.10.4.tgz", + "integrity": "sha512-Sql2kYKmgt+T/cgvg7b9ce24uLS7xbFrxE4kuuor1zSCGrjhTJ5rRNG8gTJUkAJGKJc7KgnWmgW+cOfMBPUDSA==", + "dev": true, + "license": "LGPL-3.0", + "peer": true, + "dependencies": { + "web3-core": "1.10.4", + "web3-core-helpers": "1.10.4", + "web3-core-method": "1.10.4", + "web3-core-subscriptions": "1.10.4", + "web3-eth-abi": "1.10.4", + "web3-eth-accounts": "1.10.4", + "web3-eth-contract": "1.10.4", + "web3-eth-ens": "1.10.4", + "web3-eth-iban": "1.10.4", + "web3-eth-personal": "1.10.4", + "web3-net": "1.10.4", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-abi": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.10.4.tgz", + "integrity": "sha512-cZ0q65eJIkd/jyOlQPDjr8X4fU6CRL1eWgdLwbWEpo++MPU/2P4PFk5ZLAdye9T5Sdp+MomePPJ/gHjLMj2VfQ==", + "dev": true, + "license": "LGPL-3.0", + "peer": true, + "dependencies": { + "@ethersproject/abi": "^5.6.3", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-accounts": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.10.4.tgz", + "integrity": "sha512-ysy5sVTg9snYS7tJjxVoQAH6DTOTkRGR8emEVCWNGLGiB9txj+qDvSeT0izjurS/g7D5xlMAgrEHLK1Vi6I3yg==", + "dev": true, + "license": "LGPL-3.0", + "peer": true, + "dependencies": { + "@ethereumjs/common": "2.6.5", + "@ethereumjs/tx": "3.5.2", + "@ethereumjs/util": "^8.1.0", + "eth-lib": "0.2.8", + "scrypt-js": "^3.0.1", + "uuid": "^9.0.0", + "web3-core": "1.10.4", + "web3-core-helpers": "1.10.4", + "web3-core-method": "1.10.4", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-accounts/node_modules/@ethereumjs/rlp": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-4.0.1.tgz", + "integrity": "sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==", + "dev": true, + "license": "MPL-2.0", + "peer": true, + "bin": { + "rlp": "bin/rlp" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/web3-eth-accounts/node_modules/@ethereumjs/util": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/util/-/util-8.1.0.tgz", + "integrity": "sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==", + "dev": true, + "license": "MPL-2.0", + "peer": true, + "dependencies": { + "@ethereumjs/rlp": "^4.0.1", + "ethereum-cryptography": "^2.0.0", + "micro-ftch": "^0.3.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/web3-eth-accounts/node_modules/@noble/curves": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", + "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-eth-accounts/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-eth-accounts/node_modules/bn.js": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", + "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/web3-eth-accounts/node_modules/eth-lib": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", + "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "xhr-request-promise": "^0.1.2" + } + }, + "node_modules/web3-eth-accounts/node_modules/ethereum-cryptography": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", + "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@noble/curves": "1.4.2", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.3.0" + } + }, + "node_modules/web3-eth-accounts/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "peer": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/web3-eth-contract": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.10.4.tgz", + "integrity": "sha512-Q8PfolOJ4eV9TvnTj1TGdZ4RarpSLmHnUnzVxZ/6/NiTfe4maJz99R0ISgwZkntLhLRtw0C7LRJuklzGYCNN3A==", + "dev": true, + "license": "LGPL-3.0", + "peer": true, + "dependencies": { + "@types/bn.js": "^5.1.1", + "web3-core": "1.10.4", + "web3-core-helpers": "1.10.4", + "web3-core-method": "1.10.4", + "web3-core-promievent": "1.10.4", + "web3-core-subscriptions": "1.10.4", + "web3-eth-abi": "1.10.4", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-ens": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.10.4.tgz", + "integrity": "sha512-LLrvxuFeVooRVZ9e5T6OWKVflHPFgrVjJ/jtisRWcmI7KN/b64+D/wJzXqgmp6CNsMQcE7rpmf4CQmJCrTdsgg==", + "dev": true, + "license": "LGPL-3.0", + "peer": true, + "dependencies": { + "content-hash": "^2.5.2", + "eth-ens-namehash": "2.0.8", + "web3-core": "1.10.4", + "web3-core-helpers": "1.10.4", + "web3-core-promievent": "1.10.4", + "web3-eth-abi": "1.10.4", + "web3-eth-contract": "1.10.4", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-iban": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.10.4.tgz", + "integrity": "sha512-0gE5iNmOkmtBmbKH2aTodeompnNE8jEyvwFJ6s/AF6jkw9ky9Op9cqfzS56AYAbrqEFuClsqB/AoRves7LDELw==", + "dev": true, + "license": "LGPL-3.0", + "peer": true, + "dependencies": { + "bn.js": "^5.2.1", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-personal": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.10.4.tgz", + "integrity": "sha512-BRa/hs6jU1hKHz+AC/YkM71RP3f0Yci1dPk4paOic53R4ZZG4MgwKRkJhgt3/GPuPliwS46f/i5A7fEGBT4F9w==", + "dev": true, + "license": "LGPL-3.0", + "peer": true, + "dependencies": { + "@types/node": "^12.12.6", + "web3-core": "1.10.4", + "web3-core-helpers": "1.10.4", + "web3-core-method": "1.10.4", + "web3-net": "1.10.4", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-eth-personal/node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/web3-net": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.10.4.tgz", + "integrity": "sha512-mKINnhOOnZ4koA+yV2OT5s5ztVjIx7IY9a03w6s+yao/BUn+Luuty0/keNemZxTr1E8Ehvtn28vbOtW7Ids+Ow==", + "dev": true, + "license": "LGPL-3.0", + "peer": true, + "dependencies": { + "web3-core": "1.10.4", + "web3-core-method": "1.10.4", + "web3-utils": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-providers-http": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.10.4.tgz", + "integrity": "sha512-m2P5Idc8hdiO0l60O6DSCPw0kw64Zgi0pMjbEFRmxKIck2Py57RQMu4bxvkxJwkF06SlGaEQF8rFZBmuX7aagQ==", + "dev": true, + "license": "LGPL-3.0", + "peer": true, + "dependencies": { + "abortcontroller-polyfill": "^1.7.5", + "cross-fetch": "^4.0.0", + "es6-promise": "^4.2.8", + "web3-core-helpers": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-providers-ipc": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.10.4.tgz", + "integrity": "sha512-YRF/bpQk9z3WwjT+A6FI/GmWRCASgd+gC0si7f9zbBWLXjwzYAKG73bQBaFRAHex1hl4CVcM5WUMaQXf3Opeuw==", + "dev": true, + "license": "LGPL-3.0", + "peer": true, + "dependencies": { + "oboe": "2.1.5", + "web3-core-helpers": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-providers-ws": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.10.4.tgz", + "integrity": "sha512-j3FBMifyuFFmUIPVQR4pj+t5ILhAexAui0opgcpu9R5LxQrLRUZxHSnU+YO25UycSOa/NAX8A+qkqZNpcFAlxA==", + "dev": true, + "license": "LGPL-3.0", + "peer": true, + "dependencies": { + "eventemitter3": "4.0.4", + "web3-core-helpers": "1.10.4", + "websocket": "^1.0.32" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-shh": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.10.4.tgz", + "integrity": "sha512-cOH6iFFM71lCNwSQrC3niqDXagMqrdfFW85hC9PFUrAr3PUrIem8TNstTc3xna2bwZeWG6OBy99xSIhBvyIACw==", + "dev": true, + "hasInstallScript": true, + "license": "LGPL-3.0", + "peer": true, + "dependencies": { + "web3-core": "1.10.4", + "web3-core-method": "1.10.4", + "web3-core-subscriptions": "1.10.4", + "web3-net": "1.10.4" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-utils": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.10.4.tgz", + "integrity": "sha512-tsu8FiKJLk2PzhDl9fXbGUWTkkVXYhtTA+SmEFkKft+9BgwLxfCRpU96sWv7ICC8zixBNd3JURVoiR3dUXgP8A==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "@ethereumjs/util": "^8.1.0", + "bn.js": "^5.2.1", + "ethereum-bloom-filters": "^1.0.6", + "ethereum-cryptography": "^2.1.2", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-utils/node_modules/@ethereumjs/rlp": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-4.0.1.tgz", + "integrity": "sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==", + "dev": true, + "license": "MPL-2.0", + "bin": { + "rlp": "bin/rlp" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/web3-utils/node_modules/@ethereumjs/util": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/util/-/util-8.1.0.tgz", + "integrity": "sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@ethereumjs/rlp": "^4.0.1", + "ethereum-cryptography": "^2.0.0", + "micro-ftch": "^0.3.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/web3-utils/node_modules/@noble/curves": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", + "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-utils/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-utils/node_modules/ethereum-cryptography": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", + "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/curves": "1.4.2", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.3.0" + } + }, + "node_modules/webextension-polyfill": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/webextension-polyfill/-/webextension-polyfill-0.10.0.tgz", + "integrity": "sha512-c5s35LgVa5tFaHhrZDnr3FpQpjj1BB+RXhLTYUxGqBVN460HkbM8TBtEqdXWbpTKfzwCcjAZVF7zXCYSKtcp9g==", + "license": "MPL-2.0" + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/websocket": { + "version": "1.0.35", + "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.35.tgz", + "integrity": "sha512-/REy6amwPZl44DDzvRCkaI1q1bIiQB0mEFQLUrhz3z2EK91cp3n72rAjUlrTP0zV22HJIUOVHQGPxhFRjxjt+Q==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "bufferutil": "^4.0.1", + "debug": "^2.2.0", + "es5-ext": "^0.10.63", + "typedarray-to-buffer": "^3.1.5", + "utf-8-validate": "^5.0.2", + "yaeti": "^0.0.6" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/websocket/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/websocket/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ==", + "dev": true, + "license": "ISC", + "peer": true + }, + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/window-size": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", + "integrity": "sha512-UD7d8HFA2+PZsbKyaOCEy8gMh1oDtHgJh1LfgjQ4zVXmYjAT/kvz3PueITKuqDiIXQe7yzpPnxX3lNc+AhQMyw==", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "window-size": "cli.js" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/wordwrapjs": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-4.0.1.tgz", + "integrity": "sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==", + "license": "MIT", + "dependencies": { + "reduce-flatten": "^2.0.0", + "typical": "^5.2.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/wordwrapjs/node_modules/typical": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", + "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/workerpool": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + }, + "node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xhr": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", + "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "global": "~4.4.0", + "is-function": "^1.0.1", + "parse-headers": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "node_modules/xhr-request": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz", + "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "buffer-to-arraybuffer": "^0.0.5", + "object-assign": "^4.1.1", + "query-string": "^5.0.1", + "simple-get": "^2.7.0", + "timed-out": "^4.0.1", + "url-set-query": "^1.0.0", + "xhr": "^2.0.4" + } + }, + "node_modules/xhr-request-promise": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz", + "integrity": "sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "xhr-request": "^1.1.0" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yaeti": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", + "integrity": "sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.32" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yesno": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/yesno/-/yesno-0.3.1.tgz", + "integrity": "sha512-7RbCXegyu6DykWPWU0YEtW8gFJH8KBL2d5l2fqB0XpkH0Y9rk59YSSWpzEv7yNJBGAouPc67h3kkq0CZkpBdFw==", + "dev": true, + "license": "BSD" + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/packages/wallet/wallet-contracts/package.json b/packages/wallet/wallet-contracts/package.json new file mode 100644 index 0000000000..fc6fd25102 --- /dev/null +++ b/packages/wallet/wallet-contracts/package.json @@ -0,0 +1,105 @@ +{ + "name": "@0xsequence/wallet-contracts", + "version": "3.0.1", + "private": true, + "license": "Apache-2.0", + "scripts": { + "build": "pnpm compile && pnpm adapter", + "compile": "hardhat --max-memory 4096 compile", + "clean": "rimraf artifacts && rimraf cache", + "typecheck": "tsc --noEmit", + "test": "hardhat test", + "benchmark": "BENCHMARK=true pnpm test", + "coverage": "COVERAGE=true NET_ID=1 hardhat coverage", + "deploy": "hardhat run utils/deploy-contracts.ts --network hardhat", + "verify": "hardhat verify --network", + "release": "pnpm publish src", + "lint": "pnpm lint:ts && pnpm lint:sol", + "lint:fix": "pnpm lint:ts:fix && pnpm lint:sol:fix", + "lint:sol": "solhint \"./contracts/**/*.sol\"", + "lint:sol:fix": "solhint \"./contracts/**/*.sol\" --fix", + "lint:ts": "eslint -c .eslintrc.js \"./**/*.ts\"", + "lint:ts:fix": "eslint -c .eslintrc.js --fix \"./**/*.ts\"", + "format": "prettier --write ./**/*.ts", + "adapter": "typechain --target ethers-v6 --out-dir gen/typechain \"./artifacts/contracts/**/*[^dbg].json\"", + "prepare": "husky" + }, + "types": "gen/typechain/index.ts", + "files": [ + "./LICENSE", + "./artifacts/contracts/**/*.json", + "./contracts/**/*.sol", + "./gen/typechain", + "./networks" + ], + "husky": { + "hooks": { + "pre-commit": "pnpm lint", + "pre-push": "pnpm lint && pnpm test" + } + }, + "devDependencies": { + "@nomicfoundation/hardhat-ethers": "^4.0.3", + "@nomicfoundation/hardhat-verify": "^3.0.7", + "@nomiclabs/hardhat-truffle5": "^3.0.0", + "@nomiclabs/hardhat-web3": "^2.1.0", + "@tenderly/hardhat-tenderly": "^2.5.2", + "@types/chai": "^4.3.20", + "@types/chai-as-promised": "^7.1.8", + "@types/chai-string": "^1.4.5", + "@types/mocha": "^8.2.3", + "@typescript-eslint/eslint-plugin": "^8.46.4", + "@typescript-eslint/parser": "^8.46.4", + "bn-chai": "^1.0.1", + "chai": "^4.5.0", + "chai-as-promised": "^7.1.2", + "chai-bignumber": "^3.1.0", + "chai-shallow-deep-equal": "^1.4.6", + "chai-string": "^1.6.0", + "child_process": "^1.0.2", + "dotenv": "^8.6.0", + "eslint": "^9.39.2", + "eslint-config-prettier": "^8.10.2", + "eslint-plugin-import": "^2.32.0", + "eslint-plugin-prettier": "^3.4.1", + "ethereum-waffle": "^4.0.10", + "ganache-cli": "6.12.2", + "hardhat": "^2.27.0", + "hardhat-gas-reporter": "1.0.10", + "husky": "^9.1.7", + "ora": "^5.4.1", + "rimraf": "^3.0.2", + "scrypt": "github:barrysteyn/node-scrypt#fb60a8d3c158fe115a624b5ffa7480f3a24b03fb", + "solhint": "^3.6.2", + "solidity-coverage": "^0.8.17", + "threads": "^1.7.0", + "ts-node": "^10.9.2", + "typechain": "^8.3.2", + "typescript": "^4.9.5", + "yesno": "^0.3.1" + }, + "config": { + "mnemonic": "test test test test test test test test test test test junk", + "ganacheChainID": 127001, + "ganachePort": 8545, + "ganacheGasLimit": "0xfffffffffff", + "ganacheGasPrice": "2", + "etherBalance": "100000", + "extra": "" + }, + "dependencies": { + "@0xsequence/wallet": "^2.3.33", + "@typechain/ethers-v6": "^0.5.1", + "0xsequence": "^1.10.15", + "ethers": "^6.15.0", + "keccak256": "^1.0.6" + }, + "description": "Ethereum contracts for the Sequence Smart Wallet at [https://sequence.app](https://sequence.app).", + "main": ".eslintrc.js", + "directories": { + "lib": "lib", + "test": "test" + }, + "keywords": [], + "author": "" +} diff --git a/packages/wallet/wallet-contracts/pnpm-lock.yaml b/packages/wallet/wallet-contracts/pnpm-lock.yaml new file mode 100644 index 0000000000..91f5002c53 --- /dev/null +++ b/packages/wallet/wallet-contracts/pnpm-lock.yaml @@ -0,0 +1,13554 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@typechain/ethers-v6': + specifier: ^0.5.1 + version: 0.5.1(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@4.7.4))(typescript@4.7.4) + ethers: + specifier: ^6.13.0 + version: 6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + keccak256: + specifier: ^1.0.6 + version: 1.0.6 + devDependencies: + '@nomicfoundation/hardhat-ethers': + specifier: ^3.0.5 + version: 3.0.6(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.20.1(bufferutil@4.0.8)(ts-node@10.9.1(@types/node@20.11.20)(typescript@4.7.4))(typescript@4.7.4)(utf-8-validate@5.0.10)) + '@nomicfoundation/hardhat-verify': + specifier: ^2.0.4 + version: 2.0.8(hardhat@2.20.1(bufferutil@4.0.8)(ts-node@10.9.1(@types/node@20.11.20)(typescript@4.7.4))(typescript@4.7.4)(utf-8-validate@5.0.10)) + '@nomiclabs/hardhat-truffle5': + specifier: ^2.0.7 + version: 2.0.7(@nomiclabs/hardhat-web3@2.0.0(hardhat@2.20.1(bufferutil@4.0.8)(ts-node@10.9.1(@types/node@20.11.20)(typescript@4.7.4))(typescript@4.7.4)(utf-8-validate@5.0.10))(web3@1.10.4(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)))(bufferutil@4.0.8)(encoding@0.1.13)(hardhat@2.20.1(bufferutil@4.0.8)(ts-node@10.9.1(@types/node@20.11.20)(typescript@4.7.4))(typescript@4.7.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)(web3-core-helpers@1.10.4)(web3-core-promievent@1.10.4)(web3-eth-abi@1.10.4)(web3-utils@1.10.4)(web3@1.10.4(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)) + '@nomiclabs/hardhat-web3': + specifier: ^2.0.0 + version: 2.0.0(hardhat@2.20.1(bufferutil@4.0.8)(ts-node@10.9.1(@types/node@20.11.20)(typescript@4.7.4))(typescript@4.7.4)(utf-8-validate@5.0.10))(web3@1.10.4(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)) + '@tenderly/hardhat-tenderly': + specifier: ^1.0.11 + version: 1.0.11(hardhat@2.20.1(bufferutil@4.0.8)(ts-node@10.9.1(@types/node@20.11.20)(typescript@4.7.4))(typescript@4.7.4)(utf-8-validate@5.0.10)) + '@types/chai': + specifier: ^4.3.16 + version: 4.3.16 + '@types/chai-as-promised': + specifier: ^7.1.0 + version: 7.1.0 + '@types/chai-string': + specifier: ^1.4.1 + version: 1.4.1 + '@types/mocha': + specifier: ^8.2.1 + version: 8.2.1 + '@typescript-eslint/eslint-plugin': + specifier: ^4.18.0 + version: 4.18.0(@typescript-eslint/parser@4.18.0(eslint@7.22.0)(typescript@4.7.4))(eslint@7.22.0)(typescript@4.7.4) + '@typescript-eslint/parser': + specifier: ^4.18.0 + version: 4.18.0(eslint@7.22.0)(typescript@4.7.4) + bn-chai: + specifier: ^1.0.1 + version: 1.0.1(chai@4.3.4) + chai: + specifier: ^4.3.4 + version: 4.3.4 + chai-as-promised: + specifier: ^7.1.1 + version: 7.1.1(chai@4.3.4) + chai-bignumber: + specifier: ^3.0.0 + version: 3.0.0 + chai-shallow-deep-equal: + specifier: ^1.4.6 + version: 1.4.6(chai@4.3.4) + chai-string: + specifier: ^1.5.0 + version: 1.5.0(chai@4.3.4) + child_process: + specifier: ^1.0.2 + version: 1.0.2 + dotenv: + specifier: ^8.2.0 + version: 8.2.0 + eslint: + specifier: ^7.22.0 + version: 7.22.0 + eslint-config-prettier: + specifier: ^8.1.0 + version: 8.1.0(eslint@7.22.0) + eslint-plugin-import: + specifier: ^2.22.0 + version: 2.22.0(@typescript-eslint/parser@4.18.0(eslint@7.22.0)(typescript@4.7.4))(eslint@7.22.0) + eslint-plugin-prettier: + specifier: ^3.3.1 + version: 3.3.1(eslint-config-prettier@8.1.0(eslint@7.22.0))(eslint@7.22.0)(prettier@3.2.5) + ethereum-waffle: + specifier: ^3.4.4 + version: 3.4.4(bufferutil@4.0.8)(encoding@0.1.13)(typescript@4.7.4)(utf-8-validate@5.0.10) + ganache-cli: + specifier: 6.12.2 + version: 6.12.2 + hardhat: + specifier: ^2.20.1 + version: 2.20.1(bufferutil@4.0.8)(ts-node@10.9.1(@types/node@20.11.20)(typescript@4.7.4))(typescript@4.7.4)(utf-8-validate@5.0.10) + hardhat-gas-reporter: + specifier: 1.0.10 + version: 1.0.10(bufferutil@4.0.8)(hardhat@2.20.1(bufferutil@4.0.8)(ts-node@10.9.1(@types/node@20.11.20)(typescript@4.7.4))(typescript@4.7.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + husky: + specifier: ^9.0.11 + version: 9.0.11 + ora: + specifier: ^5.4.1 + version: 5.4.1 + rimraf: + specifier: ^3.0.2 + version: 3.0.2 + scrypt: + specifier: github:barrysteyn/node-scrypt#fb60a8d3c158fe115a624b5ffa7480f3a24b03fb + version: https://codeload.github.com/barrysteyn/node-scrypt/tar.gz/fb60a8d3c158fe115a624b5ffa7480f3a24b03fb + solhint: + specifier: ^3.4.1 + version: 3.4.1(typescript@4.7.4) + solidity-coverage: + specifier: 0.8.3 + version: 0.8.3(hardhat@2.20.1(bufferutil@4.0.8)(ts-node@10.9.1(@types/node@20.11.20)(typescript@4.7.4))(typescript@4.7.4)(utf-8-validate@5.0.10)) + threads: + specifier: ^1.7.0 + version: 1.7.0 + ts-node: + specifier: ^10.9.1 + version: 10.9.1(@types/node@20.11.20)(typescript@4.7.4) + typechain: + specifier: ^8.3.2 + version: 8.3.2(typescript@4.7.4) + typescript: + specifier: ^4.7.4 + version: 4.7.4 + yesno: + specifier: ^0.3.1 + version: 0.3.1 + +packages: + + '@aashutoshrathi/word-wrap@1.2.6': + resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} + engines: {node: '>=0.10.0'} + + '@adraffy/ens-normalize@1.10.1': + resolution: {integrity: sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==} + + '@babel/code-frame@7.12.11': + resolution: {integrity: sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==} + + '@babel/code-frame@7.23.5': + resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.22.20': + resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} + engines: {node: '>=6.9.0'} + + '@babel/highlight@7.23.4': + resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==} + engines: {node: '>=6.9.0'} + + '@babel/runtime@7.23.9': + resolution: {integrity: sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==} + engines: {node: '>=6.9.0'} + + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + + '@ensdomains/address-encoder@0.1.9': + resolution: {integrity: sha512-E2d2gP4uxJQnDu2Kfg1tHNspefzbLT8Tyjrm5sEuim32UkU2sm5xL4VXtgc2X33fmPEw9+jUMpGs4veMbf+PYg==} + + '@ensdomains/ens@0.4.5': + resolution: {integrity: sha512-JSvpj1iNMFjK6K+uVl4unqMoa9rf5jopb8cya5UGBWz23Nw8hSNT7efgUx4BTlAPAgpNlEioUfeTyQ6J9ZvTVw==} + deprecated: Please use @ensdomains/ens-contracts + + '@ensdomains/ensjs@2.1.0': + resolution: {integrity: sha512-GRbGPT8Z/OJMDuxs75U/jUNEC0tbL0aj7/L/QQznGYKm/tiasp+ndLOaoULy9kKJFC0TBByqfFliEHDgoLhyog==} + + '@ensdomains/resolver@0.2.4': + resolution: {integrity: sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA==} + deprecated: Please use @ensdomains/ens-contracts + + '@eslint/eslintrc@0.4.3': + resolution: {integrity: sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==} + engines: {node: ^10.12.0 || >=12.0.0} + + '@ethereum-waffle/chai@3.4.4': + resolution: {integrity: sha512-/K8czydBtXXkcM9X6q29EqEkc5dN3oYenyH2a9hF7rGAApAJUpH8QBtojxOY/xQ2up5W332jqgxwp0yPiYug1g==} + engines: {node: '>=10.0'} + + '@ethereum-waffle/compiler@3.4.4': + resolution: {integrity: sha512-RUK3axJ8IkD5xpWjWoJgyHclOeEzDLQFga6gKpeGxiS/zBu+HB0W2FvsrrLalTFIaPw/CGYACRBSIxqiCqwqTQ==} + engines: {node: '>=10.0'} + + '@ethereum-waffle/ens@3.4.4': + resolution: {integrity: sha512-0m4NdwWxliy3heBYva1Wr4WbJKLnwXizmy5FfSSr5PMbjI7SIGCdCB59U7/ZzY773/hY3bLnzLwvG5mggVjJWg==} + engines: {node: '>=10.0'} + + '@ethereum-waffle/mock-contract@3.4.4': + resolution: {integrity: sha512-Mp0iB2YNWYGUV+VMl5tjPsaXKbKo8MDH9wSJ702l9EBjdxFf/vBvnMBAC1Fub1lLtmD0JHtp1pq+mWzg/xlLnA==} + engines: {node: '>=10.0'} + + '@ethereum-waffle/provider@3.4.4': + resolution: {integrity: sha512-GK8oKJAM8+PKy2nK08yDgl4A80mFuI8zBkE0C9GqTRYQqvuxIyXoLmJ5NZU9lIwyWVv5/KsoA11BgAv2jXE82g==} + engines: {node: '>=10.0'} + + '@ethereumjs/common@2.5.0': + resolution: {integrity: sha512-DEHjW6e38o+JmB/NO3GZBpW4lpaiBpkFgXF6jLcJ6gETBYpEyaA5nTimsWBUJR3Vmtm/didUEbNjajskugZORg==} + + '@ethereumjs/common@2.6.5': + resolution: {integrity: sha512-lRyVQOeCDaIVtgfbowla32pzeDv2Obr8oR8Put5RdUBNRGr1VGPGQNGP6elWIpgK3YdpzqTOh4GyUGOureVeeA==} + + '@ethereumjs/rlp@4.0.1': + resolution: {integrity: sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==} + engines: {node: '>=14'} + hasBin: true + + '@ethereumjs/tx@3.3.2': + resolution: {integrity: sha512-6AaJhwg4ucmwTvw/1qLaZUX5miWrwZ4nLOUsKyb/HtzS3BMw/CasKhdi1ims9mBKeK9sOJCH4qGKOBGyJCeeog==} + + '@ethereumjs/tx@3.5.2': + resolution: {integrity: sha512-gQDNJWKrSDGu2w7w0PzVXVBNMzb7wwdDOmOqczmhNjqFxFuIbhVJDwiGEnxFNC2/b8ifcZzY7MLcluizohRzNw==} + + '@ethereumjs/util@8.1.0': + resolution: {integrity: sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==} + engines: {node: '>=14'} + + '@ethersproject/abi@5.0.0-beta.153': + resolution: {integrity: sha512-aXweZ1Z7vMNzJdLpR1CZUAIgnwjrZeUSvN9syCwlBaEBUFJmFY+HHnfuTI5vIhVs/mRkfJVrbEyl51JZQqyjAg==} + + '@ethersproject/abi@5.7.0': + resolution: {integrity: sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==} + + '@ethersproject/abstract-provider@5.7.0': + resolution: {integrity: sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==} + + '@ethersproject/abstract-signer@5.7.0': + resolution: {integrity: sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==} + + '@ethersproject/address@5.7.0': + resolution: {integrity: sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==} + + '@ethersproject/base64@5.7.0': + resolution: {integrity: sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==} + + '@ethersproject/basex@5.7.0': + resolution: {integrity: sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==} + + '@ethersproject/bignumber@5.7.0': + resolution: {integrity: sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==} + + '@ethersproject/bytes@5.7.0': + resolution: {integrity: sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==} + + '@ethersproject/constants@5.7.0': + resolution: {integrity: sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==} + + '@ethersproject/contracts@5.7.0': + resolution: {integrity: sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==} + + '@ethersproject/hash@5.7.0': + resolution: {integrity: sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==} + + '@ethersproject/hdnode@5.7.0': + resolution: {integrity: sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==} + + '@ethersproject/json-wallets@5.7.0': + resolution: {integrity: sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==} + + '@ethersproject/keccak256@5.7.0': + resolution: {integrity: sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==} + + '@ethersproject/logger@5.7.0': + resolution: {integrity: sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==} + + '@ethersproject/networks@5.7.1': + resolution: {integrity: sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==} + + '@ethersproject/pbkdf2@5.7.0': + resolution: {integrity: sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==} + + '@ethersproject/properties@5.7.0': + resolution: {integrity: sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==} + + '@ethersproject/providers@5.7.2': + resolution: {integrity: sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==} + + '@ethersproject/random@5.7.0': + resolution: {integrity: sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==} + + '@ethersproject/rlp@5.7.0': + resolution: {integrity: sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==} + + '@ethersproject/sha2@5.7.0': + resolution: {integrity: sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==} + + '@ethersproject/signing-key@5.7.0': + resolution: {integrity: sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==} + + '@ethersproject/solidity@5.7.0': + resolution: {integrity: sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==} + + '@ethersproject/strings@5.7.0': + resolution: {integrity: sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==} + + '@ethersproject/transactions@5.7.0': + resolution: {integrity: sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==} + + '@ethersproject/units@5.7.0': + resolution: {integrity: sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==} + + '@ethersproject/wallet@5.7.0': + resolution: {integrity: sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==} + + '@ethersproject/web@5.7.1': + resolution: {integrity: sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==} + + '@ethersproject/wordlists@5.7.0': + resolution: {integrity: sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==} + + '@fastify/busboy@2.1.0': + resolution: {integrity: sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==} + engines: {node: '>=14'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.4.15': + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + + '@ljharb/resumer@0.0.1': + resolution: {integrity: sha512-skQiAOrCfO7vRTq53cxznMpks7wS1va95UCidALlOVWqvBAzwPVErwizDwoMqNVMEn1mDq0utxZd02eIrvF1lw==} + engines: {node: '>= 0.4'} + + '@ljharb/through@2.3.12': + resolution: {integrity: sha512-ajo/heTlG3QgC8EGP6APIejksVAYt4ayz4tqoP3MolFELzcH1x1fzwEYRJTPO0IELutZ5HQ0c26/GqAYy79u3g==} + engines: {node: '>= 0.4'} + + '@metamask/eth-sig-util@4.0.1': + resolution: {integrity: sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==} + engines: {node: '>=12.0.0'} + + '@noble/curves@1.2.0': + resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==} + + '@noble/curves@1.3.0': + resolution: {integrity: sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA==} + + '@noble/hashes@1.2.0': + resolution: {integrity: sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==} + + '@noble/hashes@1.3.2': + resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} + engines: {node: '>= 16'} + + '@noble/hashes@1.3.3': + resolution: {integrity: sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==} + engines: {node: '>= 16'} + + '@noble/secp256k1@1.7.1': + resolution: {integrity: sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@nomicfoundation/ethereumjs-block@5.0.4': + resolution: {integrity: sha512-AcyacJ9eX/uPEvqsPiB+WO1ymE+kyH48qGGiGV+YTojdtas8itUTW5dehDSOXEEItWGbbzEJ4PRqnQZlWaPvDw==} + engines: {node: '>=18'} + + '@nomicfoundation/ethereumjs-blockchain@7.0.4': + resolution: {integrity: sha512-jYsd/kwzbmpnxx86tXsYV8wZ5xGvFL+7/P0c6OlzpClHsbFzeF41KrYA9scON8Rg6bZu3ZTv6JOAgj3t7USUfg==} + engines: {node: '>=18'} + + '@nomicfoundation/ethereumjs-common@4.0.4': + resolution: {integrity: sha512-9Rgb658lcWsjiicr5GzNCjI1llow/7r0k50dLL95OJ+6iZJcVbi15r3Y0xh2cIO+zgX0WIHcbzIu6FeQf9KPrg==} + + '@nomicfoundation/ethereumjs-ethash@3.0.4': + resolution: {integrity: sha512-xvIrwIMl9sSaiYKRem68+O7vYdj7Q2XWv5P7JXiIkn83918QzWHvqbswTRsH7+r6X1UEvdsURRnZbvZszEjAaQ==} + engines: {node: '>=18'} + + '@nomicfoundation/ethereumjs-evm@2.0.4': + resolution: {integrity: sha512-lTyZZi1KpeMHzaO6cSVisR2tjiTTedjo7PcmhI/+GNFo9BmyY6QYzGeSti0sFttmjbEMioHgXxl5yrLNRg6+1w==} + engines: {node: '>=18'} + + '@nomicfoundation/ethereumjs-rlp@5.0.4': + resolution: {integrity: sha512-8H1S3s8F6QueOc/X92SdrA4RDenpiAEqMg5vJH99kcQaCy/a3Q6fgseo75mgWlbanGJXSlAPtnCeG9jvfTYXlw==} + engines: {node: '>=18'} + hasBin: true + + '@nomicfoundation/ethereumjs-statemanager@2.0.4': + resolution: {integrity: sha512-HPDjeFrxw6llEi+BzqXkZ+KkvFnTOPczuHBtk21hRlDiuKuZz32dPzlhpRsDBGV1b5JTmRDUVqCS1lp3Gghw4Q==} + peerDependencies: + '@nomicfoundation/ethereumjs-verkle': 0.0.2 + peerDependenciesMeta: + '@nomicfoundation/ethereumjs-verkle': + optional: true + + '@nomicfoundation/ethereumjs-trie@6.0.4': + resolution: {integrity: sha512-3nSwQiFMvr2VFe/aZUyinuohYvtytUqZCUCvIWcPJ/BwJH6oQdZRB42aNFBJ/8nAh2s3OcroWpBLskzW01mFKA==} + engines: {node: '>=18'} + + '@nomicfoundation/ethereumjs-tx@5.0.4': + resolution: {integrity: sha512-Xjv8wAKJGMrP1f0n2PeyfFCCojHd7iS3s/Ab7qzF1S64kxZ8Z22LCMynArYsVqiFx6rzYy548HNVEyI+AYN/kw==} + engines: {node: '>=18'} + peerDependencies: + c-kzg: ^2.1.2 + peerDependenciesMeta: + c-kzg: + optional: true + + '@nomicfoundation/ethereumjs-util@9.0.4': + resolution: {integrity: sha512-sLOzjnSrlx9Bb9EFNtHzK/FJFsfg2re6bsGqinFinH1gCqVfz9YYlXiMWwDM4C/L4ywuHFCYwfKTVr/QHQcU0Q==} + engines: {node: '>=18'} + peerDependencies: + c-kzg: ^2.1.2 + peerDependenciesMeta: + c-kzg: + optional: true + + '@nomicfoundation/ethereumjs-verkle@0.0.2': + resolution: {integrity: sha512-bjnfZElpYGK/XuuVRmLS3yDvr+cDs85D9oonZ0YUa5A3lgFgokWMp76zXrxX2jVQ0BfHaw12y860n1+iOi6yFQ==} + engines: {node: '>=18'} + + '@nomicfoundation/ethereumjs-vm@7.0.4': + resolution: {integrity: sha512-gsA4IhmtWHI4BofKy3kio9W+dqZQs5Ji5mLjLYxHCkat+JQBUt5szjRKra2F9nGDJ2XcI/wWb0YWUFNgln4zRQ==} + engines: {node: '>=18'} + + '@nomicfoundation/hardhat-ethers@3.0.6': + resolution: {integrity: sha512-/xzkFQAaHQhmIAYOQmvHBPwL+NkwLzT9gRZBsgWUYeV+E6pzXsBQsHfRYbAZ3XEYare+T7S+5Tg/1KDJgepSkA==} + peerDependencies: + ethers: ^6.1.0 + hardhat: ^2.0.0 + + '@nomicfoundation/hardhat-verify@2.0.8': + resolution: {integrity: sha512-x/OYya7A2Kcz+3W/J78dyDHxr0ezU23DKTrRKfy5wDPCnePqnr79vm8EXqX3gYps6IjPBYyGPZ9K6E5BnrWx5Q==} + peerDependencies: + hardhat: ^2.0.4 + + '@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.1': + resolution: {integrity: sha512-KcTodaQw8ivDZyF+D76FokN/HdpgGpfjc/gFCImdLUyqB6eSWVaZPazMbeAjmfhx3R0zm/NYVzxwAokFKgrc0w==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@nomicfoundation/solidity-analyzer-darwin-x64@0.1.1': + resolution: {integrity: sha512-XhQG4BaJE6cIbjAVtzGOGbK3sn1BO9W29uhk9J8y8fZF1DYz0Doj8QDMfpMu+A6TjPDs61lbsmeYodIDnfveSA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@nomicfoundation/solidity-analyzer-freebsd-x64@0.1.1': + resolution: {integrity: sha512-GHF1VKRdHW3G8CndkwdaeLkVBi5A9u2jwtlS7SLhBc8b5U/GcoL39Q+1CSO3hYqePNP+eV5YI7Zgm0ea6kMHoA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [freebsd] + + '@nomicfoundation/solidity-analyzer-linux-arm64-gnu@0.1.1': + resolution: {integrity: sha512-g4Cv2fO37ZsUENQ2vwPnZc2zRenHyAxHcyBjKcjaSmmkKrFr64yvzeNO8S3GBFCo90rfochLs99wFVGT/0owpg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@nomicfoundation/solidity-analyzer-linux-arm64-musl@0.1.1': + resolution: {integrity: sha512-WJ3CE5Oek25OGE3WwzK7oaopY8xMw9Lhb0mlYuJl/maZVo+WtP36XoQTb7bW/i8aAdHW5Z+BqrHMux23pvxG3w==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@nomicfoundation/solidity-analyzer-linux-x64-gnu@0.1.1': + resolution: {integrity: sha512-5WN7leSr5fkUBBjE4f3wKENUy9HQStu7HmWqbtknfXkkil+eNWiBV275IOlpXku7v3uLsXTOKpnnGHJYI2qsdA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@nomicfoundation/solidity-analyzer-linux-x64-musl@0.1.1': + resolution: {integrity: sha512-KdYMkJOq0SYPQMmErv/63CwGwMm5XHenEna9X9aB8mQmhDBrYrlAOSsIPgFCUSL0hjxE3xHP65/EPXR/InD2+w==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@nomicfoundation/solidity-analyzer-win32-arm64-msvc@0.1.1': + resolution: {integrity: sha512-VFZASBfl4qiBYwW5xeY20exWhmv6ww9sWu/krWSesv3q5hA0o1JuzmPHR4LPN6SUZj5vcqci0O6JOL8BPw+APg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@nomicfoundation/solidity-analyzer-win32-ia32-msvc@0.1.1': + resolution: {integrity: sha512-JnFkYuyCSA70j6Si6cS1A9Gh1aHTEb8kOTBApp/c7NRTFGNMH8eaInKlyuuiIbvYFhlXW4LicqyYuWNNq9hkpQ==} + engines: {node: '>= 10'} + cpu: [ia32] + os: [win32] + + '@nomicfoundation/solidity-analyzer-win32-x64-msvc@0.1.1': + resolution: {integrity: sha512-HrVJr6+WjIXGnw3Q9u6KQcbZCtk0caVWhCdFADySvRyUxJ8PnzlaP+MhwNE8oyT8OZ6ejHBRrrgjSqDCFXGirw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@nomicfoundation/solidity-analyzer@0.1.1': + resolution: {integrity: sha512-1LMtXj1puAxyFusBgUIy5pZk3073cNXYnXUpuNKFghHbIit/xZgbk0AokpUADbNm3gyD6bFWl3LRFh3dhVdREg==} + engines: {node: '>= 12'} + + '@nomiclabs/hardhat-truffle5@2.0.7': + resolution: {integrity: sha512-Pw8451IUZp1bTp0QqCHCYfCHs66sCnyxPcaorapu9mfOV9xnZsVaFdtutnhNEiXdiZwbed7LFKpRsde4BjFwig==} + peerDependencies: + '@nomiclabs/hardhat-web3': ^2.0.0 + hardhat: ^2.6.4 + web3: ^1.0.0-beta.36 + + '@nomiclabs/hardhat-web3@2.0.0': + resolution: {integrity: sha512-zt4xN+D+fKl3wW2YlTX3k9APR3XZgPkxJYf36AcliJn3oujnKEVRZaHu0PhgLjO+gR+F/kiYayo9fgd2L8970Q==} + peerDependencies: + hardhat: ^2.0.0 + web3: ^1.0.0-beta.36 + + '@nomiclabs/truffle-contract@4.5.10': + resolution: {integrity: sha512-nF/6InFV+0hUvutyFgsdOMCoYlr//2fJbRER4itxYtQtc4/O1biTwZIKRu+5l2J5Sq6LU2WX7vZHtDgQdhWxIQ==} + peerDependencies: + web3: ^1.2.1 + web3-core-helpers: ^1.2.1 + web3-core-promievent: ^1.2.1 + web3-eth-abi: ^1.2.1 + web3-utils: ^1.2.1 + + '@resolver-engine/core@0.3.3': + resolution: {integrity: sha512-eB8nEbKDJJBi5p5SrvrvILn4a0h42bKtbCTri3ZxCGt6UvoQyp7HnGOfki944bUjBSHKK3RvgfViHn+kqdXtnQ==} + + '@resolver-engine/fs@0.3.3': + resolution: {integrity: sha512-wQ9RhPUcny02Wm0IuJwYMyAG8fXVeKdmhm8xizNByD4ryZlx6PP6kRen+t/haF43cMfmaV7T3Cx6ChOdHEhFUQ==} + + '@resolver-engine/imports-fs@0.3.3': + resolution: {integrity: sha512-7Pjg/ZAZtxpeyCFlZR5zqYkz+Wdo84ugB5LApwriT8XFeQoLwGUj4tZFFvvCuxaNCcqZzCYbonJgmGObYBzyCA==} + + '@resolver-engine/imports@0.3.3': + resolution: {integrity: sha512-anHpS4wN4sRMwsAbMXhMfOD/y4a4Oo0Cw/5+rue7hSwGWsDOQaAU1ClK1OxjUC35/peazxEl8JaSRRS+Xb8t3Q==} + + '@scure/base@1.1.5': + resolution: {integrity: sha512-Brj9FiG2W1MRQSTB212YVPRrcbjkv48FoZi/u4l/zds/ieRrqsh7aUf6CLwkAq61oKXr/ZlTzlY66gLIj3TFTQ==} + + '@scure/bip32@1.1.5': + resolution: {integrity: sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==} + + '@scure/bip32@1.3.3': + resolution: {integrity: sha512-LJaN3HwRbfQK0X1xFSi0Q9amqOgzQnnDngIt+ZlsBC3Bm7/nE7K0kwshZHyaru79yIVRv/e1mQAjZyuZG6jOFQ==} + + '@scure/bip39@1.1.1': + resolution: {integrity: sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==} + + '@scure/bip39@1.2.2': + resolution: {integrity: sha512-HYf9TUXG80beW+hGAt3TRM8wU6pQoYur9iNypTROm42dorCGmLnFe3eWjz3gOq6G62H2WRh0FCzAR1PI+29zIA==} + + '@sentry/core@5.30.0': + resolution: {integrity: sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==} + engines: {node: '>=6'} + + '@sentry/hub@5.30.0': + resolution: {integrity: sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==} + engines: {node: '>=6'} + + '@sentry/minimal@5.30.0': + resolution: {integrity: sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==} + engines: {node: '>=6'} + + '@sentry/node@5.30.0': + resolution: {integrity: sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==} + engines: {node: '>=6'} + + '@sentry/tracing@5.30.0': + resolution: {integrity: sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==} + engines: {node: '>=6'} + + '@sentry/types@5.30.0': + resolution: {integrity: sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==} + engines: {node: '>=6'} + + '@sentry/utils@5.30.0': + resolution: {integrity: sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==} + engines: {node: '>=6'} + + '@sindresorhus/is@0.14.0': + resolution: {integrity: sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==} + engines: {node: '>=6'} + + '@sindresorhus/is@4.6.0': + resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} + engines: {node: '>=10'} + + '@solidity-parser/parser@0.14.5': + resolution: {integrity: sha512-6dKnHZn7fg/iQATVEzqyUOyEidbn05q7YA2mQ9hC0MMXhhV3/JrsxmFSYZAcr7j1yUP700LLhTruvJ3MiQmjJg==} + + '@solidity-parser/parser@0.16.2': + resolution: {integrity: sha512-PI9NfoA3P8XK2VBkK5oIfRgKDsicwDZfkVq9ZTBCQYGOP1N2owgY2dyLGyU5/J/hQs8KRk55kdmvTLjy3Mu3vg==} + + '@szmarczak/http-timer@1.1.2': + resolution: {integrity: sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==} + engines: {node: '>=6'} + + '@szmarczak/http-timer@4.0.6': + resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} + engines: {node: '>=10'} + + '@szmarczak/http-timer@5.0.1': + resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==} + engines: {node: '>=14.16'} + + '@tenderly/hardhat-tenderly@1.0.11': + resolution: {integrity: sha512-ZWE8NYUaCNQfzLk4psVcwRXDadDzOWT6Il8hdazzOGYo4EF6vunv6/DHJTGR1JD/FLx7ub0HOwCAHJU8wL2l2A==} + peerDependencies: + hardhat: ^2.0.3 + + '@truffle/abi-utils@1.0.3': + resolution: {integrity: sha512-AWhs01HCShaVKjml7Z4AbVREr/u4oiWxCcoR7Cktm0mEvtT04pvnxW5xB/cI4znRkrbPdFQlFt67kgrAjesYkw==} + engines: {node: ^16.20 || ^18.16 || >=20} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + + '@truffle/blockchain-utils@0.1.9': + resolution: {integrity: sha512-RHfumgbIVo68Rv9ofDYfynjnYZIfP/f1vZy4RoqkfYAO+fqfc58PDRzB1WAGq2U6GPuOnipOJxQhnqNnffORZg==} + engines: {node: ^16.20 || ^18.16 || >=20} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + + '@truffle/codec@0.17.3': + resolution: {integrity: sha512-Ko/+dsnntNyrJa57jUD9u4qx9nQby+H4GsUO6yjiCPSX0TQnEHK08XWqBSg0WdmCH2+h0y1nr2CXSx8gbZapxg==} + engines: {node: ^16.20 || ^18.16 || >=20} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + + '@truffle/compile-common@0.9.8': + resolution: {integrity: sha512-DTpiyo32t/YhLI1spn84D3MHYHrnoVqO+Gp7ZHrYNwDs86mAxtNiH5lsVzSb8cPgiqlvNsRCU9nm9R0YmKMTBQ==} + engines: {node: ^16.20 || ^18.16 || >=20} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + + '@truffle/contract-schema@3.4.16': + resolution: {integrity: sha512-g0WNYR/J327DqtJPI70ubS19K1Fth/1wxt2jFqLsPmz5cGZVjCwuhiie+LfBde4/Mc9QR8G+L3wtmT5cyoBxAg==} + engines: {node: ^16.20 || ^18.16 || >=20} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + + '@truffle/debug-utils@6.0.57': + resolution: {integrity: sha512-Q6oI7zLaeNLB69ixjwZk2UZEWBY6b2OD1sjLMGDKBGR7GaHYiw96GLR2PFgPH1uwEeLmV4N78LYaQCrDsHbNeA==} + engines: {node: ^16.20 || ^18.16 || >=20} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + + '@truffle/error@0.1.1': + resolution: {integrity: sha512-sE7c9IHIGdbK4YayH4BC8i8qMjoAOeg6nUXUDZZp8wlU21/EMpaG+CLx+KqcIPyR+GSWIW3Dm0PXkr2nlggFDA==} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + + '@truffle/error@0.2.2': + resolution: {integrity: sha512-TqbzJ0O8DHh34cu8gDujnYl4dUl6o2DE4PR6iokbybvnIm/L2xl6+Gv1VC+YJS45xfH83Yo3/Zyg/9Oq8/xZWg==} + engines: {node: ^16.20 || ^18.16 || >=20} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + + '@truffle/interface-adapter@0.5.37': + resolution: {integrity: sha512-lPH9MDgU+7sNDlJSClwyOwPCfuOimqsCx0HfGkznL3mcFRymc1pukAR1k17zn7ErHqBwJjiKAZ6Ri72KkS+IWw==} + engines: {node: ^16.20 || ^18.16 || >=20} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + + '@trufflesuite/chromafi@3.0.0': + resolution: {integrity: sha512-oqWcOqn8nT1bwlPPfidfzS55vqcIDdpfzo3HbU9EnUmcSTX+I8z0UyUFI3tZQjByVJulbzxHxUGS3ZJPwK/GPQ==} + + '@tsconfig/node10@1.0.9': + resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} + + '@tsconfig/node12@1.0.11': + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + + '@tsconfig/node14@1.0.3': + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + + '@tsconfig/node16@1.0.4': + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + + '@typechain/ethers-v5@2.0.0': + resolution: {integrity: sha512-0xdCkyGOzdqh4h5JSf+zoWx85IusEjDcPIwNEHP8mrWSnCae4rvrqB+/gtpdNfX7zjlFlZiMeePn2r63EI3Lrw==} + peerDependencies: + ethers: ^5.0.0 + typechain: ^3.0.0 + + '@typechain/ethers-v6@0.5.1': + resolution: {integrity: sha512-F+GklO8jBWlsaVV+9oHaPh5NJdd6rAKN4tklGfInX1Q7h0xPgVLP39Jl3eCulPB5qexI71ZFHwbljx4ZXNfouA==} + peerDependencies: + ethers: 6.x + typechain: ^8.3.2 + typescript: '>=4.7.0' + + '@types/bignumber.js@5.0.0': + resolution: {integrity: sha512-0DH7aPGCClywOFaxxjE6UwpN2kQYe9LwuDQMv+zYA97j5GkOMo8e66LYT+a8JYU7jfmUFRZLa9KycxHDsKXJCA==} + deprecated: This is a stub types definition for bignumber.js (https://github.com/MikeMcl/bignumber.js/). bignumber.js provides its own type definitions, so you don't need @types/bignumber.js installed! + + '@types/bn.js@4.11.6': + resolution: {integrity: sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==} + + '@types/bn.js@5.1.5': + resolution: {integrity: sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A==} + + '@types/cacheable-request@6.0.3': + resolution: {integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==} + + '@types/chai-as-promised@7.1.0': + resolution: {integrity: sha512-MFiW54UOSt+f2bRw8J7LgQeIvE/9b4oGvwU7XW30S9QGAiHGnU/fmiOprsyMkdmH2rl8xSPc0/yrQw8juXU6bQ==} + + '@types/chai-string@1.4.1': + resolution: {integrity: sha512-aRNMs6TKgjgPlCHwDfq/YNy5VtRR2hJ4AUWByddrT0TRVVD8eX4MiHW6/iHvmQHRlVuuPZcwnTUE7b4yFt7bEA==} + + '@types/chai@4.3.16': + resolution: {integrity: sha512-PatH4iOdyh3MyWtmHVFXLWCCIhUbopaltqddG9BzB+gMIzee2MJrvd+jouii9Z3wzQJruGWAm7WOMjgfG8hQlQ==} + + '@types/concat-stream@1.6.1': + resolution: {integrity: sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==} + + '@types/debug@4.1.12': + resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + + '@types/form-data@0.0.33': + resolution: {integrity: sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==} + + '@types/glob@7.2.0': + resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} + + '@types/http-cache-semantics@4.0.4': + resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/json5@0.0.29': + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + + '@types/keyv@3.1.4': + resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} + + '@types/lru-cache@5.1.1': + resolution: {integrity: sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==} + + '@types/minimatch@5.1.2': + resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==} + + '@types/mkdirp@0.5.2': + resolution: {integrity: sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==} + + '@types/mocha@8.2.1': + resolution: {integrity: sha512-NysN+bNqj6E0Hv4CTGWSlPzMW6vTKjDpOteycDkV4IWBsO+PU48JonrPzV9ODjiI2XrjmA05KInLgF5ivZ/YGQ==} + + '@types/ms@0.7.34': + resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} + + '@types/node-fetch@2.6.11': + resolution: {integrity: sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==} + + '@types/node@10.17.60': + resolution: {integrity: sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==} + + '@types/node@12.20.55': + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + + '@types/node@18.15.13': + resolution: {integrity: sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==} + + '@types/node@20.11.20': + resolution: {integrity: sha512-7/rR21OS+fq8IyHTgtLkDK949uzsa6n8BkziAKtPVpugIkO6D+/ooXMvzXxDnZrmtXVfjb1bKQafYpb8s89LOg==} + + '@types/node@8.10.66': + resolution: {integrity: sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==} + + '@types/pbkdf2@3.1.2': + resolution: {integrity: sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew==} + + '@types/prettier@2.7.3': + resolution: {integrity: sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==} + + '@types/qs@6.9.11': + resolution: {integrity: sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ==} + + '@types/readable-stream@2.3.15': + resolution: {integrity: sha512-oM5JSKQCcICF1wvGgmecmHldZ48OZamtMxcGGVICOJA8o8cahXC1zEVAif8iwoc5j8etxFaRFnf095+CDsuoFQ==} + + '@types/resolve@0.0.8': + resolution: {integrity: sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==} + + '@types/responselike@1.0.3': + resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} + + '@types/secp256k1@4.0.6': + resolution: {integrity: sha512-hHxJU6PAEUn0TP4S/ZOzuTUvJWuZ6eIKeNKb5RBpODvSl6hp1Wrw4s7ATY50rklRCScUDpHzVA/DQdSjJ3UoYQ==} + + '@typescript-eslint/eslint-plugin@4.18.0': + resolution: {integrity: sha512-Lzkc/2+7EoH7+NjIWLS2lVuKKqbEmJhtXe3rmfA8cyiKnZm3IfLf51irnBcmow8Q/AptVV0XBZmBJKuUJTe6cQ==} + engines: {node: ^10.12.0 || >=12.0.0} + peerDependencies: + '@typescript-eslint/parser': ^4.0.0 + eslint: ^5.0.0 || ^6.0.0 || ^7.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/experimental-utils@4.18.0': + resolution: {integrity: sha512-92h723Kblt9JcT2RRY3QS2xefFKar4ZQFVs3GityOKWQYgtajxt/tuXIzL7sVCUlM1hgreiV5gkGYyBpdOwO6A==} + engines: {node: ^10.12.0 || >=12.0.0} + peerDependencies: + eslint: '*' + + '@typescript-eslint/parser@4.18.0': + resolution: {integrity: sha512-W3z5S0ZbecwX3PhJEAnq4mnjK5JJXvXUDBYIYGoweCyWyuvAKfGHvzmpUzgB5L4cRBb+cTu9U/ro66dx7dIimA==} + engines: {node: ^10.12.0 || >=12.0.0} + peerDependencies: + eslint: ^5.0.0 || ^6.0.0 || ^7.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/scope-manager@4.18.0': + resolution: {integrity: sha512-olX4yN6rvHR2eyFOcb6E4vmhDPsfdMyfQ3qR+oQNkAv8emKKlfxTWUXU5Mqxs2Fwe3Pf1BoPvrwZtwngxDzYzQ==} + engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} + + '@typescript-eslint/types@4.18.0': + resolution: {integrity: sha512-/BRociARpj5E+9yQ7cwCF/SNOWwXJ3qhjurMuK2hIFUbr9vTuDeu476Zpu+ptxY2kSxUHDGLLKy+qGq2sOg37A==} + engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} + + '@typescript-eslint/typescript-estree@4.18.0': + resolution: {integrity: sha512-wt4xvF6vvJI7epz+rEqxmoNQ4ZADArGQO9gDU+cM0U5fdVv7N+IAuVoVAoZSOZxzGHBfvE3XQMLdy+scsqFfeg==} + engines: {node: ^10.12.0 || >=12.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/visitor-keys@4.18.0': + resolution: {integrity: sha512-Q9t90JCvfYaN0OfFUgaLqByOfz8yPeTAdotn/XYNm5q9eHax90gzdb+RJ6E9T5s97Kv/UHWKERTmqA0jTKAEHw==} + engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} + + '@yarnpkg/lockfile@1.1.0': + resolution: {integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==} + + abbrev@1.0.9: + resolution: {integrity: sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==} + + abortcontroller-polyfill@1.7.5: + resolution: {integrity: sha512-JMJ5soJWP18htbbxJjG7bG6yuI6pRhgJ0scHHTfkUjf6wjP912xZWvM+A4sJK3gqd9E8fcPbDnOefbA9Th/FIQ==} + + abstract-leveldown@2.6.3: + resolution: {integrity: sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==} + + abstract-leveldown@2.7.2: + resolution: {integrity: sha512-+OVvxH2rHVEhWLdbudP6p0+dNMXu8JA1CbhP19T8paTYAcX7oJ4OVjT+ZUVpv7mITxXHqDMej+GdqXBmXkw09w==} + + abstract-leveldown@3.0.0: + resolution: {integrity: sha512-KUWx9UWGQD12zsmLNj64/pndaz4iJh/Pj7nopgkfDG6RlCcbMZvT6+9l7dchK4idog2Is8VdC/PvNbFuFmalIQ==} + engines: {node: '>=4'} + + abstract-leveldown@5.0.0: + resolution: {integrity: sha512-5mU5P1gXtsMIXg65/rsYGsi93+MlogXZ9FA8JnwKurHQg64bfXwGYVdVdijNTVNOlAsuIiOwHdvFFD5JqCJQ7A==} + engines: {node: '>=6'} + + accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn-walk@8.3.2: + resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} + engines: {node: '>=0.4.0'} + + acorn@7.4.1: + resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} + engines: {node: '>=0.4.0'} + hasBin: true + + acorn@8.11.3: + resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} + engines: {node: '>=0.4.0'} + hasBin: true + + address@1.2.2: + resolution: {integrity: sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==} + engines: {node: '>= 10.0.0'} + + adm-zip@0.4.16: + resolution: {integrity: sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==} + engines: {node: '>=0.3.0'} + + aes-js@3.0.0: + resolution: {integrity: sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==} + + aes-js@3.1.2: + resolution: {integrity: sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ==} + + aes-js@4.0.0-beta.5: + resolution: {integrity: sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==} + + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + + aggregate-error@3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ajv@8.12.0: + resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==} + + amdefine@1.0.1: + resolution: {integrity: sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==} + engines: {node: '>=0.4.2'} + + ansi-align@3.0.1: + resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} + + ansi-colors@3.2.3: + resolution: {integrity: sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==} + engines: {node: '>=6'} + + ansi-colors@4.1.1: + resolution: {integrity: sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==} + engines: {node: '>=6'} + + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + + ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + + ansi-regex@2.1.1: + resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==} + engines: {node: '>=0.10.0'} + + ansi-regex@3.0.1: + resolution: {integrity: sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==} + engines: {node: '>=4'} + + ansi-regex@4.1.1: + resolution: {integrity: sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==} + engines: {node: '>=6'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-styles@2.2.1: + resolution: {integrity: sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==} + engines: {node: '>=0.10.0'} + + ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + antlr4@4.13.1: + resolution: {integrity: sha512-kiXTspaRYvnIArgE97z5YVVf/cDVQABr3abFRR6mE7yesLMkgu4ujuyV/sgxafQ8wgve0DJQUJ38Z8tkgA2izA==} + engines: {node: '>=16'} + + antlr4ts@0.5.0-alpha.4: + resolution: {integrity: sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + arr-diff@4.0.0: + resolution: {integrity: sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==} + engines: {node: '>=0.10.0'} + + arr-flatten@1.1.0: + resolution: {integrity: sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==} + engines: {node: '>=0.10.0'} + + arr-union@3.1.0: + resolution: {integrity: sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==} + engines: {node: '>=0.10.0'} + + array-back@1.0.4: + resolution: {integrity: sha512-1WxbZvrmyhkNoeYcizokbmh5oiOCIfyvGtcqbK3Ls1v1fKcquzxnQSceOx6tzq7jmai2kFLWIpGND2cLhH6TPw==} + engines: {node: '>=0.12.0'} + + array-back@2.0.0: + resolution: {integrity: sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==} + engines: {node: '>=4'} + + array-back@3.1.0: + resolution: {integrity: sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==} + engines: {node: '>=6'} + + array-back@4.0.2: + resolution: {integrity: sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==} + engines: {node: '>=8'} + + array-buffer-byte-length@1.0.1: + resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} + engines: {node: '>= 0.4'} + + array-flatten@1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + + array-includes@3.1.7: + resolution: {integrity: sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==} + engines: {node: '>= 0.4'} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + array-uniq@1.0.3: + resolution: {integrity: sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==} + engines: {node: '>=0.10.0'} + + array-unique@0.3.2: + resolution: {integrity: sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==} + engines: {node: '>=0.10.0'} + + array.prototype.flat@1.3.2: + resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} + engines: {node: '>= 0.4'} + + array.prototype.reduce@1.0.6: + resolution: {integrity: sha512-UW+Mz8LG/sPSU8jRDCjVr6J/ZKAGpHfwrZ6kWTG5qCxIEiXdVshqGnu5vEZA8S1y6X4aCSbQZ0/EEsfvEvBiSg==} + engines: {node: '>= 0.4'} + + arraybuffer.prototype.slice@1.0.3: + resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} + engines: {node: '>= 0.4'} + + asap@2.0.6: + resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} + + asn1.js@5.4.1: + resolution: {integrity: sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==} + + asn1@0.2.6: + resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} + + assert-plus@1.0.0: + resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} + engines: {node: '>=0.8'} + + assertion-error@1.1.0: + resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + + assign-symbols@1.0.0: + resolution: {integrity: sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==} + engines: {node: '>=0.10.0'} + + ast-parents@0.0.1: + resolution: {integrity: sha512-XHusKxKz3zoYk1ic8Un640joHbFMhbqneyoZfoKnEGtf2ey9Uh/IdpcQplODdO/kENaMIWsD0nJm4+wX3UNLHA==} + + astral-regex@2.0.0: + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} + engines: {node: '>=8'} + + async-eventemitter@0.2.4: + resolution: {integrity: sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==} + + async-limiter@1.0.1: + resolution: {integrity: sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==} + + async@1.5.2: + resolution: {integrity: sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==} + + async@2.6.2: + resolution: {integrity: sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + at-least-node@1.0.0: + resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} + engines: {node: '>= 4.0.0'} + + atob@2.1.2: + resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==} + engines: {node: '>= 4.5.0'} + hasBin: true + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + aws-sign2@0.7.0: + resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} + + aws4@1.12.0: + resolution: {integrity: sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==} + + axios@0.21.4: + resolution: {integrity: sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==} + + axios@1.6.7: + resolution: {integrity: sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==} + + babel-code-frame@6.26.0: + resolution: {integrity: sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==} + + babel-core@6.26.3: + resolution: {integrity: sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==} + + babel-generator@6.26.1: + resolution: {integrity: sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==} + + babel-helper-builder-binary-assignment-operator-visitor@6.24.1: + resolution: {integrity: sha512-gCtfYORSG1fUMX4kKraymq607FWgMWg+j42IFPc18kFQEsmtaibP4UrqsXt8FlEJle25HUd4tsoDR7H2wDhe9Q==} + + babel-helper-call-delegate@6.24.1: + resolution: {integrity: sha512-RL8n2NiEj+kKztlrVJM9JT1cXzzAdvWFh76xh/H1I4nKwunzE4INBXn8ieCZ+wh4zWszZk7NBS1s/8HR5jDkzQ==} + + babel-helper-define-map@6.26.0: + resolution: {integrity: sha512-bHkmjcC9lM1kmZcVpA5t2om2nzT/xiZpo6TJq7UlZ3wqKfzia4veeXbIhKvJXAMzhhEBd3cR1IElL5AenWEUpA==} + + babel-helper-explode-assignable-expression@6.24.1: + resolution: {integrity: sha512-qe5csbhbvq6ccry9G7tkXbzNtcDiH4r51rrPUbwwoTzZ18AqxWYRZT6AOmxrpxKnQBW0pYlBI/8vh73Z//78nQ==} + + babel-helper-function-name@6.24.1: + resolution: {integrity: sha512-Oo6+e2iX+o9eVvJ9Y5eKL5iryeRdsIkwRYheCuhYdVHsdEQysbc2z2QkqCLIYnNxkT5Ss3ggrHdXiDI7Dhrn4Q==} + + babel-helper-get-function-arity@6.24.1: + resolution: {integrity: sha512-WfgKFX6swFB1jS2vo+DwivRN4NB8XUdM3ij0Y1gnC21y1tdBoe6xjVnd7NSI6alv+gZXCtJqvrTeMW3fR/c0ng==} + + babel-helper-hoist-variables@6.24.1: + resolution: {integrity: sha512-zAYl3tqerLItvG5cKYw7f1SpvIxS9zi7ohyGHaI9cgDUjAT6YcY9jIEH5CstetP5wHIVSceXwNS7Z5BpJg+rOw==} + + babel-helper-optimise-call-expression@6.24.1: + resolution: {integrity: sha512-Op9IhEaxhbRT8MDXx2iNuMgciu2V8lDvYCNQbDGjdBNCjaMvyLf4wl4A3b8IgndCyQF8TwfgsQ8T3VD8aX1/pA==} + + babel-helper-regex@6.26.0: + resolution: {integrity: sha512-VlPiWmqmGJp0x0oK27Out1D+71nVVCTSdlbhIVoaBAj2lUgrNjBCRR9+llO4lTSb2O4r7PJg+RobRkhBrf6ofg==} + + babel-helper-remap-async-to-generator@6.24.1: + resolution: {integrity: sha512-RYqaPD0mQyQIFRu7Ho5wE2yvA/5jxqCIj/Lv4BXNq23mHYu/vxikOy2JueLiBxQknwapwrJeNCesvY0ZcfnlHg==} + + babel-helper-replace-supers@6.24.1: + resolution: {integrity: sha512-sLI+u7sXJh6+ToqDr57Bv973kCepItDhMou0xCP2YPVmR1jkHSCY+p1no8xErbV1Siz5QE8qKT1WIwybSWlqjw==} + + babel-helpers@6.24.1: + resolution: {integrity: sha512-n7pFrqQm44TCYvrCDb0MqabAF+JUBq+ijBvNMUxpkLjJaAu32faIexewMumrH5KLLJ1HDyT0PTEqRyAe/GwwuQ==} + + babel-messages@6.23.0: + resolution: {integrity: sha512-Bl3ZiA+LjqaMtNYopA9TYE9HP1tQ+E5dLxE0XrAzcIJeK2UqF0/EaqXwBn9esd4UmTfEab+P+UYQ1GnioFIb/w==} + + babel-plugin-check-es2015-constants@6.22.0: + resolution: {integrity: sha512-B1M5KBP29248dViEo1owyY32lk1ZSH2DaNNrXLGt8lyjjHm7pBqAdQ7VKUPR6EEDO323+OvT3MQXbCin8ooWdA==} + + babel-plugin-syntax-async-functions@6.13.0: + resolution: {integrity: sha512-4Zp4unmHgw30A1eWI5EpACji2qMocisdXhAftfhXoSV9j0Tvj6nRFE3tOmRY912E0FMRm/L5xWE7MGVT2FoLnw==} + + babel-plugin-syntax-exponentiation-operator@6.13.0: + resolution: {integrity: sha512-Z/flU+T9ta0aIEKl1tGEmN/pZiI1uXmCiGFRegKacQfEJzp7iNsKloZmyJlQr+75FCJtiFfGIK03SiCvCt9cPQ==} + + babel-plugin-syntax-trailing-function-commas@6.22.0: + resolution: {integrity: sha512-Gx9CH3Q/3GKbhs07Bszw5fPTlU+ygrOGfAhEt7W2JICwufpC4SuO0mG0+4NykPBSYPMJhqvVlDBU17qB1D+hMQ==} + + babel-plugin-transform-async-to-generator@6.24.1: + resolution: {integrity: sha512-7BgYJujNCg0Ti3x0c/DL3tStvnKS6ktIYOmo9wginv/dfZOrbSZ+qG4IRRHMBOzZ5Awb1skTiAsQXg/+IWkZYw==} + + babel-plugin-transform-es2015-arrow-functions@6.22.0: + resolution: {integrity: sha512-PCqwwzODXW7JMrzu+yZIaYbPQSKjDTAsNNlK2l5Gg9g4rz2VzLnZsStvp/3c46GfXpwkyufb3NCyG9+50FF1Vg==} + + babel-plugin-transform-es2015-block-scoped-functions@6.22.0: + resolution: {integrity: sha512-2+ujAT2UMBzYFm7tidUsYh+ZoIutxJ3pN9IYrF1/H6dCKtECfhmB8UkHVpyxDwkj0CYbQG35ykoz925TUnBc3A==} + + babel-plugin-transform-es2015-block-scoping@6.26.0: + resolution: {integrity: sha512-YiN6sFAQ5lML8JjCmr7uerS5Yc/EMbgg9G8ZNmk2E3nYX4ckHR01wrkeeMijEf5WHNK5TW0Sl0Uu3pv3EdOJWw==} + + babel-plugin-transform-es2015-classes@6.24.1: + resolution: {integrity: sha512-5Dy7ZbRinGrNtmWpquZKZ3EGY8sDgIVB4CU8Om8q8tnMLrD/m94cKglVcHps0BCTdZ0TJeeAWOq2TK9MIY6cag==} + + babel-plugin-transform-es2015-computed-properties@6.24.1: + resolution: {integrity: sha512-C/uAv4ktFP/Hmh01gMTvYvICrKze0XVX9f2PdIXuriCSvUmV9j+u+BB9f5fJK3+878yMK6dkdcq+Ymr9mrcLzw==} + + babel-plugin-transform-es2015-destructuring@6.23.0: + resolution: {integrity: sha512-aNv/GDAW0j/f4Uy1OEPZn1mqD+Nfy9viFGBfQ5bZyT35YqOiqx7/tXdyfZkJ1sC21NyEsBdfDY6PYmLHF4r5iA==} + + babel-plugin-transform-es2015-duplicate-keys@6.24.1: + resolution: {integrity: sha512-ossocTuPOssfxO2h+Z3/Ea1Vo1wWx31Uqy9vIiJusOP4TbF7tPs9U0sJ9pX9OJPf4lXRGj5+6Gkl/HHKiAP5ug==} + + babel-plugin-transform-es2015-for-of@6.23.0: + resolution: {integrity: sha512-DLuRwoygCoXx+YfxHLkVx5/NpeSbVwfoTeBykpJK7JhYWlL/O8hgAK/reforUnZDlxasOrVPPJVI/guE3dCwkw==} + + babel-plugin-transform-es2015-function-name@6.24.1: + resolution: {integrity: sha512-iFp5KIcorf11iBqu/y/a7DK3MN5di3pNCzto61FqCNnUX4qeBwcV1SLqe10oXNnCaxBUImX3SckX2/o1nsrTcg==} + + babel-plugin-transform-es2015-literals@6.22.0: + resolution: {integrity: sha512-tjFl0cwMPpDYyoqYA9li1/7mGFit39XiNX5DKC/uCNjBctMxyL1/PT/l4rSlbvBG1pOKI88STRdUsWXB3/Q9hQ==} + + babel-plugin-transform-es2015-modules-amd@6.24.1: + resolution: {integrity: sha512-LnIIdGWIKdw7zwckqx+eGjcS8/cl8D74A3BpJbGjKTFFNJSMrjN4bIh22HY1AlkUbeLG6X6OZj56BDvWD+OeFA==} + + babel-plugin-transform-es2015-modules-commonjs@6.26.2: + resolution: {integrity: sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==} + + babel-plugin-transform-es2015-modules-systemjs@6.24.1: + resolution: {integrity: sha512-ONFIPsq8y4bls5PPsAWYXH/21Hqv64TBxdje0FvU3MhIV6QM2j5YS7KvAzg/nTIVLot2D2fmFQrFWCbgHlFEjg==} + + babel-plugin-transform-es2015-modules-umd@6.24.1: + resolution: {integrity: sha512-LpVbiT9CLsuAIp3IG0tfbVo81QIhn6pE8xBJ7XSeCtFlMltuar5VuBV6y6Q45tpui9QWcy5i0vLQfCfrnF7Kiw==} + + babel-plugin-transform-es2015-object-super@6.24.1: + resolution: {integrity: sha512-8G5hpZMecb53vpD3mjs64NhI1au24TAmokQ4B+TBFBjN9cVoGoOvotdrMMRmHvVZUEvqGUPWL514woru1ChZMA==} + + babel-plugin-transform-es2015-parameters@6.24.1: + resolution: {integrity: sha512-8HxlW+BB5HqniD+nLkQ4xSAVq3bR/pcYW9IigY+2y0dI+Y7INFeTbfAQr+63T3E4UDsZGjyb+l9txUnABWxlOQ==} + + babel-plugin-transform-es2015-shorthand-properties@6.24.1: + resolution: {integrity: sha512-mDdocSfUVm1/7Jw/FIRNw9vPrBQNePy6wZJlR8HAUBLybNp1w/6lr6zZ2pjMShee65t/ybR5pT8ulkLzD1xwiw==} + + babel-plugin-transform-es2015-spread@6.22.0: + resolution: {integrity: sha512-3Ghhi26r4l3d0Js933E5+IhHwk0A1yiutj9gwvzmFbVV0sPMYk2lekhOufHBswX7NCoSeF4Xrl3sCIuSIa+zOg==} + + babel-plugin-transform-es2015-sticky-regex@6.24.1: + resolution: {integrity: sha512-CYP359ADryTo3pCsH0oxRo/0yn6UsEZLqYohHmvLQdfS9xkf+MbCzE3/Kolw9OYIY4ZMilH25z/5CbQbwDD+lQ==} + + babel-plugin-transform-es2015-template-literals@6.22.0: + resolution: {integrity: sha512-x8b9W0ngnKzDMHimVtTfn5ryimars1ByTqsfBDwAqLibmuuQY6pgBQi5z1ErIsUOWBdw1bW9FSz5RZUojM4apg==} + + babel-plugin-transform-es2015-typeof-symbol@6.23.0: + resolution: {integrity: sha512-fz6J2Sf4gYN6gWgRZaoFXmq93X+Li/8vf+fb0sGDVtdeWvxC9y5/bTD7bvfWMEq6zetGEHpWjtzRGSugt5kNqw==} + + babel-plugin-transform-es2015-unicode-regex@6.24.1: + resolution: {integrity: sha512-v61Dbbihf5XxnYjtBN04B/JBvsScY37R1cZT5r9permN1cp+b70DY3Ib3fIkgn1DI9U3tGgBJZVD8p/mE/4JbQ==} + + babel-plugin-transform-exponentiation-operator@6.24.1: + resolution: {integrity: sha512-LzXDmbMkklvNhprr20//RStKVcT8Cu+SQtX18eMHLhjHf2yFzwtQ0S2f0jQ+89rokoNdmwoSqYzAhq86FxlLSQ==} + + babel-plugin-transform-regenerator@6.26.0: + resolution: {integrity: sha512-LS+dBkUGlNR15/5WHKe/8Neawx663qttS6AGqoOUhICc9d1KciBvtrQSuc0PI+CxQ2Q/S1aKuJ+u64GtLdcEZg==} + + babel-plugin-transform-strict-mode@6.24.1: + resolution: {integrity: sha512-j3KtSpjyLSJxNoCDrhwiJad8kw0gJ9REGj8/CqL0HeRyLnvUNYV9zcqluL6QJSXh3nfsLEmSLvwRfGzrgR96Pw==} + + babel-preset-env@1.7.0: + resolution: {integrity: sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==} + + babel-register@6.26.0: + resolution: {integrity: sha512-veliHlHX06wjaeY8xNITbveXSiI+ASFnOqvne/LaIJIqOWi2Ogmj91KOugEz/hoh/fwMhXNBJPCv8Xaz5CyM4A==} + + babel-runtime@6.26.0: + resolution: {integrity: sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==} + + babel-template@6.26.0: + resolution: {integrity: sha512-PCOcLFW7/eazGUKIoqH97sO9A2UYMahsn/yRQ7uOk37iutwjq7ODtcTNF+iFDSHNfkctqsLRjLP7URnOx0T1fg==} + + babel-traverse@6.26.0: + resolution: {integrity: sha512-iSxeXx7apsjCHe9c7n8VtRXGzI2Bk1rBSOJgCCjfyXb6v1aCqE1KSEpq/8SXuVN8Ka/Rh1WDTF0MDzkvTA4MIA==} + + babel-types@6.26.0: + resolution: {integrity: sha512-zhe3V/26rCWsEZK8kZN+HaQj5yQ1CilTObixFzKW1UWjqG7618Twz6YEsCnjfg5gBcJh02DrpCkS9h98ZqDY+g==} + + babelify@7.3.0: + resolution: {integrity: sha512-vID8Fz6pPN5pJMdlUnNFSfrlcx5MUule4k9aKs/zbZPyXxMTcRrB0M4Tarw22L8afr8eYSWxDPYCob3TdrqtlA==} + + babylon@6.18.0: + resolution: {integrity: sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==} + hasBin: true + + backoff@2.5.0: + resolution: {integrity: sha512-wC5ihrnUXmR2douXmXLCe5O3zg3GKIyvRi/hi58a/XyRxVI+3/yM0PYueQOZXPXQ9pxBislYkw+sF9b7C/RuMA==} + engines: {node: '>= 0.6'} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + base-x@3.0.9: + resolution: {integrity: sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + base@0.11.2: + resolution: {integrity: sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==} + engines: {node: '>=0.10.0'} + + bcrypt-pbkdf@1.0.2: + resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} + + bech32@1.1.4: + resolution: {integrity: sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==} + + big-integer@1.6.36: + resolution: {integrity: sha512-t70bfa7HYEA1D9idDbmuv7YbsbVkQ+Hp+8KFSul4aE5e/i1bjCNIRYJZlA8Q8p0r9T8cF/RVvwUgRA//FydEyg==} + engines: {node: '>=0.6'} + + big.js@6.2.1: + resolution: {integrity: sha512-bCtHMwL9LeDIozFn+oNhhFoq+yQ3BNdnsLSASUxLciOb1vgvpHsIO1dsENiGMgbb4SkP5TrzWzRiLddn8ahVOQ==} + + bigint-crypto-utils@3.3.0: + resolution: {integrity: sha512-jOTSb+drvEDxEq6OuUybOAv/xxoh3cuYRUIPyu8sSHQNKM303UQ2R1DAo45o1AkcIXw6fzbaFI1+xGGdaXs2lg==} + engines: {node: '>=14.0.0'} + + bignumber.js@7.2.1: + resolution: {integrity: sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ==} + + bignumber.js@9.1.2: + resolution: {integrity: sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==} + + binary-extensions@2.2.0: + resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + engines: {node: '>=8'} + + bip39@2.5.0: + resolution: {integrity: sha512-xwIx/8JKoT2+IPJpFEfXoWdYwP7UVAoUxxLNfGCfVowaJE7yg1Y5B1BVPqlUNsBq5/nGwmFkwRJ8xDW4sX8OdA==} + + bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + + blakejs@1.2.1: + resolution: {integrity: sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==} + + bluebird@3.7.2: + resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + + bn-chai@1.0.1: + resolution: {integrity: sha512-7rJXt21DwYiLLpvzLaACixBBoUGkRV1iuFD3wElEhw8Ji9IiY/QsJRtvW+c7ChRgEOyLQkGaSGFUUqBKm21SNA==} + peerDependencies: + chai: '>= 2.1.2 < 5' + + bn.js@4.11.6: + resolution: {integrity: sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==} + + bn.js@4.12.0: + resolution: {integrity: sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==} + + bn.js@5.2.1: + resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} + + body-parser@1.20.1: + resolution: {integrity: sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + body-parser@1.20.2: + resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + boxen@5.1.2: + resolution: {integrity: sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==} + engines: {node: '>=10'} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@2.3.2: + resolution: {integrity: sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==} + engines: {node: '>=0.10.0'} + + braces@3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + + brorand@1.1.0: + resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==} + + browser-stdout@1.3.1: + resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} + + browserify-aes@1.2.0: + resolution: {integrity: sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==} + + browserify-cipher@1.0.1: + resolution: {integrity: sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==} + + browserify-des@1.0.2: + resolution: {integrity: sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==} + + browserify-rsa@4.1.0: + resolution: {integrity: sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==} + + browserify-sign@4.2.2: + resolution: {integrity: sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg==} + engines: {node: '>= 4'} + + browserslist@3.2.8: + resolution: {integrity: sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==} + hasBin: true + + bs58@4.0.1: + resolution: {integrity: sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==} + + bs58check@2.1.2: + resolution: {integrity: sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==} + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + buffer-to-arraybuffer@0.0.5: + resolution: {integrity: sha512-3dthu5CYiVB1DEJp61FtApNnNndTckcqe4pFcLdvHtrpG+kcyekCJKg4MRiDcFW7A6AODnXB9U4dwQiCW5kzJQ==} + + buffer-xor@1.0.3: + resolution: {integrity: sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==} + + buffer-xor@2.0.2: + resolution: {integrity: sha512-eHslX0bin3GB+Lx2p7lEYRShRewuNZL3fUl4qlVJGGiwoPGftmt8JQgk2Y9Ji5/01TnVDo33E5b5O3vUB1HdqQ==} + + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + + bufferutil@4.0.8: + resolution: {integrity: sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==} + engines: {node: '>=6.14.2'} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + bytewise-core@1.2.3: + resolution: {integrity: sha512-nZD//kc78OOxeYtRlVk8/zXqTB4gf/nlguL1ggWA8FuchMyOxcyHR4QPQZMUmA7czC+YnaBrPUCubqAWe50DaA==} + + bytewise@1.1.0: + resolution: {integrity: sha512-rHuuseJ9iQ0na6UDhnrRVDh8YnWVlU6xM3VH6q/+yHDeUH2zIhUzP+2/h3LIrhLDBtTqzWpE3p3tP/boefskKQ==} + + cache-base@1.0.1: + resolution: {integrity: sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==} + engines: {node: '>=0.10.0'} + + cacheable-lookup@5.0.4: + resolution: {integrity: sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==} + engines: {node: '>=10.6.0'} + + cacheable-lookup@6.1.0: + resolution: {integrity: sha512-KJ/Dmo1lDDhmW2XDPMo+9oiy/CeqosPguPCrgcVzKyZrL6pM1gU2GmPY/xo6OQPTUaA/c0kwHuywB4E6nmT9ww==} + engines: {node: '>=10.6.0'} + + cacheable-request@6.1.0: + resolution: {integrity: sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==} + engines: {node: '>=8'} + + cacheable-request@7.0.4: + resolution: {integrity: sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==} + engines: {node: '>=8'} + + cachedown@1.0.0: + resolution: {integrity: sha1-1D8DbkUQaWsxJG19sx6/D3rDLRU=} + + call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + camel-case@3.0.0: + resolution: {integrity: sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==} + + camelcase@3.0.0: + resolution: {integrity: sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==} + engines: {node: '>=0.10.0'} + + camelcase@4.1.0: + resolution: {integrity: sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==} + engines: {node: '>=4'} + + camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + + caniuse-lite@1.0.30001589: + resolution: {integrity: sha512-vNQWS6kI+q6sBlHbh71IIeC+sRwK2N3EDySc/updIGhIee2x5z00J4c1242/5/d6EpEMdOnk/m+6tuk4/tcsqg==} + + caseless@0.12.0: + resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} + + cbor@5.2.0: + resolution: {integrity: sha512-5IMhi9e1QU76ppa5/ajP1BmMWZ2FHkhAhjeVKQ/EFCgYSEaeVaoGtL7cxJskf9oCCk+XjzaIdc3IuU/dbA/o2A==} + engines: {node: '>=6.0.0'} + + cbor@8.1.0: + resolution: {integrity: sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==} + engines: {node: '>=12.19'} + + chai-as-promised@7.1.1: + resolution: {integrity: sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==} + peerDependencies: + chai: '>= 2.1.2 < 5' + + chai-bignumber@3.0.0: + resolution: {integrity: sha512-SubOtaSI2AILWTWe2j0c6i2yFT/f9J6UBjeVGDuwDiPLkF/U5+/eTWUE3sbCZ1KgcPF6UJsDVYbIxaYA097MQA==} + + chai-shallow-deep-equal@1.4.6: + resolution: {integrity: sha512-2fBsQVRwrHdNO7IPYmoeH/V9+tuBDDg3k054NKdZ7tWeoi0URPzt8P+LNqcJioLVBTH/WiNM6a8CT5nWMebhPg==} + engines: {node: '>= 0.6.0'} + peerDependencies: + chai: '>= 1.9.0' + + chai-string@1.5.0: + resolution: {integrity: sha512-sydDC3S3pNAQMYwJrs6dQX0oBQ6KfIPuOZ78n7rocW0eJJlsHPh2t3kwW7xfwYA/1Bf6/arGtSUo16rxR2JFlw==} + peerDependencies: + chai: ^4.1.2 + + chai@4.3.4: + resolution: {integrity: sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==} + engines: {node: '>=4'} + + chalk@1.1.3: + resolution: {integrity: sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==} + engines: {node: '>=0.10.0'} + + chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + change-case@3.0.2: + resolution: {integrity: sha512-Mww+SLF6MZ0U6kdg11algyKd5BARbyM4TbFBepwowYSR5ClfQGCGtxNXgykpN0uF/bstWeaGDT4JWaDh8zWAHA==} + + charenc@0.0.2: + resolution: {integrity: sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==} + + check-error@1.0.3: + resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + + checkpoint-store@1.1.0: + resolution: {integrity: sha512-J/NdY2WvIx654cc6LWSq/IYFFCUf75fFTgwzFnmbqyORH4MwgiQCgswLLKBGzmsyTI5V7i5bp/So6sMbDWhedg==} + + cheerio-select@2.1.0: + resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} + + cheerio@1.0.0-rc.12: + resolution: {integrity: sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==} + engines: {node: '>= 6'} + + child_process@1.0.2: + resolution: {integrity: sha512-Wmza/JzL0SiWz7kl6MhIKT5ceIlnFPJX+lwUGj7Clhy5MMldsSoJR0+uvRzOS5Kv45Mq7t1PoE8TsOA9bzvb6g==} + + chokidar@3.3.0: + resolution: {integrity: sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==} + engines: {node: '>= 8.10.0'} + + chokidar@3.5.3: + resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + engines: {node: '>= 8.10.0'} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + chownr@1.1.4: + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + + ci-info@2.0.0: + resolution: {integrity: sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==} + + cids@0.7.5: + resolution: {integrity: sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA==} + engines: {node: '>=4.0.0', npm: '>=3.0.0'} + deprecated: This module has been superseded by the multiformats module + + cipher-base@1.0.4: + resolution: {integrity: sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==} + + class-is@1.1.0: + resolution: {integrity: sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==} + + class-utils@0.3.6: + resolution: {integrity: sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==} + engines: {node: '>=0.10.0'} + + clean-stack@2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} + + cli-boxes@2.2.1: + resolution: {integrity: sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==} + engines: {node: '>=6'} + + cli-cursor@3.1.0: + resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} + engines: {node: '>=8'} + + cli-spinners@2.9.2: + resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} + engines: {node: '>=6'} + + cli-table3@0.5.1: + resolution: {integrity: sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==} + engines: {node: '>=6'} + + cliui@3.2.0: + resolution: {integrity: sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==} + + cliui@5.0.0: + resolution: {integrity: sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==} + + cliui@7.0.4: + resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + + clone-response@1.0.3: + resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==} + + clone@1.0.4: + resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} + engines: {node: '>=0.8'} + + clone@2.1.2: + resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} + engines: {node: '>=0.8'} + + code-point-at@1.1.0: + resolution: {integrity: sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==} + engines: {node: '>=0.10.0'} + + collection-visit@1.0.0: + resolution: {integrity: sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==} + engines: {node: '>=0.10.0'} + + color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + colors@1.4.0: + resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==} + engines: {node: '>=0.1.90'} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + command-exists@1.2.9: + resolution: {integrity: sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==} + + command-line-args@4.0.7: + resolution: {integrity: sha512-aUdPvQRAyBvQd2n7jXcsMDz68ckBJELXNzBybCHOibUWEg0mWTnaYCSRU8h9R+aNRSvDihJtssSRCiDRpLaezA==} + hasBin: true + + command-line-args@5.2.1: + resolution: {integrity: sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==} + engines: {node: '>=4.0.0'} + + command-line-usage@6.1.3: + resolution: {integrity: sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw==} + engines: {node: '>=8.0.0'} + + commander@10.0.1: + resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} + engines: {node: '>=14'} + + commander@3.0.2: + resolution: {integrity: sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==} + + component-emitter@1.3.1: + resolution: {integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==} + + concat-map@0.0.1: + resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} + + concat-stream@1.6.2: + resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} + engines: {'0': node >= 0.8} + + constant-case@2.0.0: + resolution: {integrity: sha512-eS0N9WwmjTqrOmR3o83F5vW8Z+9R1HnVz3xmzT2PMFug9ly+Au/fxRWlEBSb6LcZwspSsEn9Xs1uw9YgzAg1EQ==} + + contains-path@0.1.0: + resolution: {integrity: sha512-OKZnPGeMQy2RPaUIBPFFd71iNf4791H12MCRuVQDnzGRwCYNYmTDy5pdafo2SLAcEMKzTOQnLWG4QdcjeJUMEg==} + engines: {node: '>=0.10.0'} + + content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + + content-hash@2.5.2: + resolution: {integrity: sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw==} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + convert-source-map@1.9.0: + resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + + cookie-signature@1.0.6: + resolution: {integrity: sha1-4wOogrNCzD7oylE6eZmXNNqzriw=} + + cookie@0.4.2: + resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==} + engines: {node: '>= 0.6'} + + cookie@0.5.0: + resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} + engines: {node: '>= 0.6'} + + cookiejar@2.1.4: + resolution: {integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==} + + copy-descriptor@0.1.1: + resolution: {integrity: sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==} + engines: {node: '>=0.10.0'} + + core-js-pure@3.36.0: + resolution: {integrity: sha512-cN28qmhRNgbMZZMc/RFu5w8pK9VJzpb2rJVR/lHuZJKwmXnoWOpXmMkxqBB514igkp1Hu8WGROsiOAzUcKdHOQ==} + + core-js@2.6.12: + resolution: {integrity: sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==} + deprecated: core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js. + + core-util-is@1.0.2: + resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + cors@2.8.5: + resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} + engines: {node: '>= 0.10'} + + cosmiconfig@8.3.6: + resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + + crc-32@1.2.2: + resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} + engines: {node: '>=0.8'} + hasBin: true + + create-ecdh@4.0.4: + resolution: {integrity: sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==} + + create-hash@1.2.0: + resolution: {integrity: sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==} + + create-hmac@1.1.7: + resolution: {integrity: sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==} + + create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + + cross-fetch@2.2.6: + resolution: {integrity: sha512-9JZz+vXCmfKUZ68zAptS7k4Nu8e2qcibe7WVZYps7sAgk5R8GYTc+T1WR0v1rlP9HxgARmOX1UTIJZFytajpNA==} + + cross-fetch@3.1.8: + resolution: {integrity: sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==} + + cross-fetch@4.0.0: + resolution: {integrity: sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==} + + cross-spawn@6.0.5: + resolution: {integrity: sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==} + engines: {node: '>=4.8'} + + cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + + crypt@0.0.2: + resolution: {integrity: sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==} + + crypto-addr-codec@0.1.8: + resolution: {integrity: sha512-GqAK90iLLgP3FvhNmHbpT3wR6dEdaM8hZyZtLX29SPardh3OA13RFLHDR6sntGCgRWOfiHqW6sIyohpNqOtV/g==} + + crypto-browserify@3.12.0: + resolution: {integrity: sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==} + + css-select@5.1.0: + resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} + + css-what@6.1.0: + resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} + engines: {node: '>= 6'} + + d@1.0.1: + resolution: {integrity: sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==} + + dashdash@1.14.1: + resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} + engines: {node: '>=0.10'} + + death@1.1.0: + resolution: {integrity: sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w==} + + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@3.2.6: + resolution: {integrity: sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==} + deprecated: Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797) + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + + decamelize@4.0.0: + resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} + engines: {node: '>=10'} + + decode-uri-component@0.2.2: + resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} + engines: {node: '>=0.10'} + + decompress-response@3.3.0: + resolution: {integrity: sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==} + engines: {node: '>=4'} + + decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + + deep-eql@3.0.1: + resolution: {integrity: sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==} + engines: {node: '>=0.12'} + + deep-equal@1.1.2: + resolution: {integrity: sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg==} + engines: {node: '>= 0.4'} + + deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + defaults@1.0.4: + resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + + defer-to-connect@1.1.3: + resolution: {integrity: sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==} + + defer-to-connect@2.0.1: + resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} + engines: {node: '>=10'} + + deferred-leveldown@1.2.2: + resolution: {integrity: sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA==} + + deferred-leveldown@4.0.2: + resolution: {integrity: sha512-5fMC8ek8alH16QiV0lTCis610D1Zt1+LA4MS4d63JgS32lrCjTFDUFz2ao09/j2I4Bqb5jL4FZYwu7Jz0XO1ww==} + engines: {node: '>=6'} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + define-property@0.2.5: + resolution: {integrity: sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==} + engines: {node: '>=0.10.0'} + + define-property@1.0.0: + resolution: {integrity: sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==} + engines: {node: '>=0.10.0'} + + define-property@2.0.2: + resolution: {integrity: sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==} + engines: {node: '>=0.10.0'} + + defined@1.0.1: + resolution: {integrity: sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + des.js@1.1.0: + resolution: {integrity: sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==} + + destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + detect-indent@4.0.0: + resolution: {integrity: sha512-BDKtmHlOzwI7iRuEkhzsnPoi5ypEhWAJB5RvHWe1kMr06js3uK5B3734i3ui5Yd+wOJV1cpE4JnivPD283GU/A==} + engines: {node: '>=0.10.0'} + + detect-indent@5.0.0: + resolution: {integrity: sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g==} + engines: {node: '>=4'} + + detect-port@1.5.1: + resolution: {integrity: sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==} + hasBin: true + + diff@3.5.0: + resolution: {integrity: sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==} + engines: {node: '>=0.3.1'} + + diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + + diff@5.0.0: + resolution: {integrity: sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==} + engines: {node: '>=0.3.1'} + + diffie-hellman@5.0.3: + resolution: {integrity: sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==} + + difflib@0.2.4: + resolution: {integrity: sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w==} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + doctrine@1.5.0: + resolution: {integrity: sha512-lsGyRuYr4/PIB0txi+Fy2xOMI2dGaTguCaotzFGkVZuKR5usKfcRWIFKNM3QNrU7hh/+w2bwTW+ZeXPK5l8uVg==} + engines: {node: '>=0.10.0'} + + doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + dom-walk@0.1.2: + resolution: {integrity: sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + domutils@3.1.0: + resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} + + dot-case@2.1.1: + resolution: {integrity: sha512-HnM6ZlFqcajLsyudHq7LeeLDr2rFAVYtDv/hV5qchQEidSck8j9OPUsXY9KwJv/lHMtYlX4DjRQqwFYa+0r8Ug==} + + dotenv@8.2.0: + resolution: {integrity: sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==} + engines: {node: '>=8'} + + dotignore@0.1.2: + resolution: {integrity: sha512-UGGGWfSauusaVJC+8fgV+NVvBXkCTmVv7sk6nojDZZvuOUNGUy0Zk4UpHQD6EDjS0jpBwcACvH4eofvyzBcRDw==} + hasBin: true + + duplexer3@0.1.5: + resolution: {integrity: sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==} + + ecc-jsbn@0.1.2: + resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==} + + ee-first@1.1.1: + resolution: {integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=} + + electron-to-chromium@1.4.682: + resolution: {integrity: sha512-oCglfs8yYKs9RQjJFOHonSnhikPK3y+0SvSYc/YpYJV//6rqc0/hbwd0c7vgK4vrl6y2gJAwjkhkSGWK+z4KRA==} + + elliptic@6.5.4: + resolution: {integrity: sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==} + + emoji-regex@7.0.3: + resolution: {integrity: sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + encodeurl@1.0.2: + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} + engines: {node: '>= 0.8'} + + encoding-down@5.0.4: + resolution: {integrity: sha512-8CIZLDcSKxgzT+zX8ZVfgNbu8Md2wq/iqa1Y7zyVR18QBEAc0Nmzuvj/N5ykSKpfGzjM8qxbaFntLPwnVoUhZw==} + engines: {node: '>=6'} + + encoding@0.1.13: + resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} + + end-of-stream@1.4.4: + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + + enquirer@2.4.1: + resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} + engines: {node: '>=8.6'} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + + errno@0.1.8: + resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==} + hasBin: true + + error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + + es-abstract@1.22.4: + resolution: {integrity: sha512-vZYJlk2u6qHYxBOTjAeg7qUxHdNfih64Uu2J8QqWgXZ2cri0ZpJAkzDUK/q593+mvKwlxyaxr6F1Q+3LKoQRgg==} + engines: {node: '>= 0.4'} + + es-array-method-boxes-properly@1.0.0: + resolution: {integrity: sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==} + + es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.0.3: + resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} + engines: {node: '>= 0.4'} + + es-shim-unscopables@1.0.2: + resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} + + es-to-primitive@1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + + es5-ext@0.10.63: + resolution: {integrity: sha512-hUCZd2Byj/mNKjfP9jXrdVZ62B8KuA/VoK7X8nUh5qT+AxDmcbvZz041oDVZdbIN1qW6XY9VDNwzkvKnZvK2TQ==} + engines: {node: '>=0.10'} + + es6-iterator@2.0.3: + resolution: {integrity: sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==} + + es6-promise@4.2.8: + resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} + + es6-symbol@3.1.3: + resolution: {integrity: sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==} + + escalade@3.1.2: + resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} + engines: {node: '>=6'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + escodegen@1.8.1: + resolution: {integrity: sha512-yhi5S+mNTOuRvyW4gWlg5W1byMaQGWWSYHXsuFZ7GBo7tpyOwi2EdzMP/QWxh9hwkD2m+wDVHJsxhRIj+v/b/A==} + engines: {node: '>=0.12.0'} + hasBin: true + + eslint-config-prettier@8.1.0: + resolution: {integrity: sha512-oKMhGv3ihGbCIimCAjqkdzx2Q+jthoqnXSP+d86M9tptwugycmTFdVR4IpLgq2c4SHifbwO90z2fQ8/Aio73yw==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + + eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + + eslint-module-utils@2.8.0: + resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + + eslint-plugin-import@2.22.0: + resolution: {integrity: sha512-66Fpf1Ln6aIS5Gr/55ts19eUuoDhAbZgnr6UxK5hbDx6l/QgQgx61AePq+BV4PP2uXQFClgMVzep5zZ94qqsxg==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + + eslint-plugin-prettier@3.3.1: + resolution: {integrity: sha512-Rq3jkcFY8RYeQLgk2cCwuc0P7SEFwDravPhsJZOQ5N4YI4DSg50NyqJ/9gdZHzQlHf8MvafSesbNJCcP/FF6pQ==} + engines: {node: '>=6.0.0'} + peerDependencies: + eslint: '>=5.0.0' + eslint-config-prettier: '*' + prettier: '>=1.13.0' + peerDependenciesMeta: + eslint-config-prettier: + optional: true + + eslint-scope@5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} + + eslint-utils@2.1.0: + resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==} + engines: {node: '>=6'} + + eslint-visitor-keys@1.3.0: + resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==} + engines: {node: '>=4'} + + eslint-visitor-keys@2.1.0: + resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} + engines: {node: '>=10'} + + eslint@7.22.0: + resolution: {integrity: sha512-3VawOtjSJUQiiqac8MQc+w457iGLfuNGLFn8JmF051tTKbh5/x/0vlcEj8OgDCaw7Ysa2Jn8paGshV7x2abKXg==} + engines: {node: ^10.12.0 || >=12.0.0} + hasBin: true + + esm@3.2.25: + resolution: {integrity: sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==} + engines: {node: '>=6'} + + esniff@2.0.1: + resolution: {integrity: sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==} + engines: {node: '>=0.10'} + + espree@7.3.1: + resolution: {integrity: sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==} + engines: {node: ^10.12.0 || >=12.0.0} + + esprima@2.7.3: + resolution: {integrity: sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==} + engines: {node: '>=0.10.0'} + hasBin: true + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + esquery@1.5.0: + resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@1.9.3: + resolution: {integrity: sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA==} + engines: {node: '>=0.10.0'} + + estraverse@4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + eth-block-tracker@3.0.1: + resolution: {integrity: sha512-WUVxWLuhMmsfenfZvFO5sbl1qFY2IqUlw/FPVmjjdElpqLsZtSG+wPe9Dz7W/sB6e80HgFKknOmKk2eNlznHug==} + + eth-ens-namehash@2.0.8: + resolution: {integrity: sha512-VWEI1+KJfz4Km//dadyvBBoBeSQ0MHTXPvr8UIXiLW6IanxvAV+DmlZAijZwAyggqGUfwQBeHf7tc9wzc1piSw==} + + eth-gas-reporter@0.2.27: + resolution: {integrity: sha512-femhvoAM7wL0GcI8ozTdxfuBtBFJ9qsyIAsmKVjlWAHUbdnnXHt+lKzz/kmldM5lA9jLuNHGwuIxorNpLbR1Zw==} + peerDependencies: + '@codechecks/client': ^0.1.0 + peerDependenciesMeta: + '@codechecks/client': + optional: true + + eth-json-rpc-infura@3.2.1: + resolution: {integrity: sha512-W7zR4DZvyTn23Bxc0EWsq4XGDdD63+XPUCEhV2zQvQGavDVC4ZpFDK4k99qN7bd7/fjj37+rxmuBOBeIqCA5Mw==} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + + eth-json-rpc-middleware@1.6.0: + resolution: {integrity: sha512-tDVCTlrUvdqHKqivYMjtFZsdD7TtpNLBCfKAcOpaVs7orBMS/A8HWro6dIzNtTZIR05FAbJ3bioFOnZpuCew9Q==} + + eth-lib@0.1.29: + resolution: {integrity: sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==} + + eth-lib@0.2.8: + resolution: {integrity: sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==} + + eth-query@2.1.2: + resolution: {integrity: sha512-srES0ZcvwkR/wd5OQBRA1bIJMww1skfGS0s8wlwK3/oNP4+wnds60krvu5R1QbpRQjMmpG5OMIWro5s7gvDPsA==} + + eth-sig-util@1.4.2: + resolution: {integrity: sha512-iNZ576iTOGcfllftB73cPB5AN+XUQAT/T8xzsILsghXC1o8gJUqe3RHlcDqagu+biFpYQ61KQrZZJza8eRSYqw==} + deprecated: Deprecated in favor of '@metamask/eth-sig-util' + + eth-sig-util@3.0.0: + resolution: {integrity: sha512-4eFkMOhpGbTxBQ3AMzVf0haUX2uTur7DpWiHzWyTURa28BVJJtOkcb9Ok5TV0YvEPG61DODPW7ZUATbJTslioQ==} + deprecated: Deprecated in favor of '@metamask/eth-sig-util' + + eth-tx-summary@3.2.4: + resolution: {integrity: sha512-NtlDnaVZah146Rm8HMRUNMgIwG/ED4jiqk0TME9zFheMl1jOp6jL1m0NKGjJwehXQ6ZKCPr16MTr+qspKpEXNg==} + + ethashjs@0.0.8: + resolution: {integrity: sha512-/MSbf/r2/Ld8o0l15AymjOTlPqpN8Cr4ByUEA9GtR4x0yAh3TdtDzEg29zMjXCNPI7u6E5fOQdj/Cf9Tc7oVNw==} + deprecated: 'New package name format for new versions: @ethereumjs/ethash. Please update.' + + ethereum-bloom-filters@1.0.10: + resolution: {integrity: sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA==} + + ethereum-common@0.0.18: + resolution: {integrity: sha512-EoltVQTRNg2Uy4o84qpa2aXymXDJhxm7eos/ACOg0DG4baAbMjhbdAEsx9GeE8sC3XCxnYvrrzZDH8D8MtA2iQ==} + + ethereum-common@0.2.0: + resolution: {integrity: sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA==} + + ethereum-cryptography@0.1.3: + resolution: {integrity: sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==} + + ethereum-cryptography@1.2.0: + resolution: {integrity: sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==} + + ethereum-cryptography@2.1.3: + resolution: {integrity: sha512-BlwbIL7/P45W8FGW2r7LGuvoEZ+7PWsniMvQ4p5s2xCyw9tmaDlpfsN9HjAucbF+t/qpVHwZUisgfK24TCW8aA==} + + ethereum-ens@0.8.0: + resolution: {integrity: sha512-a8cBTF4AWw1Q1Y37V1LSCS9pRY4Mh3f8vCg5cbXCCEJ3eno1hbI/+Ccv9SZLISYpqQhaglP3Bxb/34lS4Qf7Bg==} + + ethereum-waffle@3.4.4: + resolution: {integrity: sha512-PA9+jCjw4WC3Oc5ocSMBj5sXvueWQeAbvCA+hUlb6oFgwwKyq5ka3bWQ7QZcjzIX+TdFkxP4IbFmoY2D8Dkj9Q==} + engines: {node: '>=10.0'} + hasBin: true + + ethereumjs-abi@0.6.5: + resolution: {integrity: sha512-rCjJZ/AE96c/AAZc6O3kaog4FhOsAViaysBxqJNy2+LHP0ttH0zkZ7nXdVHOAyt6lFwLO0nlCwWszysG/ao1+g==} + + ethereumjs-abi@0.6.8: + resolution: {integrity: sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==} + + ethereumjs-abi@https://codeload.github.com/ethereumjs/ethereumjs-abi/tar.gz/ee3994657fa7a427238e6ba92a84d0b529bbcde0: + resolution: {tarball: https://codeload.github.com/ethereumjs/ethereumjs-abi/tar.gz/ee3994657fa7a427238e6ba92a84d0b529bbcde0} + version: 0.6.8 + + ethereumjs-account@2.0.5: + resolution: {integrity: sha512-bgDojnXGjhMwo6eXQC0bY6UK2liSFUSMwwylOmQvZbSl/D7NXQ3+vrGO46ZeOgjGfxXmgIeVNDIiHw7fNZM4VA==} + + ethereumjs-account@3.0.0: + resolution: {integrity: sha512-WP6BdscjiiPkQfF9PVfMcwx/rDvfZTjFKY0Uwc09zSQr9JfIVH87dYIJu0gNhBhpmovV4yq295fdllS925fnBA==} + deprecated: Please use Util.Account class found on package ethereumjs-util@^7.0.6 https://github.com/ethereumjs/ethereumjs-util/releases/tag/v7.0.6 + + ethereumjs-block@1.7.1: + resolution: {integrity: sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg==} + deprecated: 'New package name format for new versions: @ethereumjs/block. Please update.' + + ethereumjs-block@2.2.2: + resolution: {integrity: sha512-2p49ifhek3h2zeg/+da6XpdFR3GlqY3BIEiqxGF8j9aSRIgkb7M1Ky+yULBKJOu8PAZxfhsYA+HxUk2aCQp3vg==} + deprecated: 'New package name format for new versions: @ethereumjs/block. Please update.' + + ethereumjs-blockchain@4.0.4: + resolution: {integrity: sha512-zCxaRMUOzzjvX78DTGiKjA+4h2/sF0OYL1QuPux0DHpyq8XiNoF5GYHtb++GUxVlMsMfZV7AVyzbtgcRdIcEPQ==} + deprecated: 'New package name format for new versions: @ethereumjs/blockchain. Please update.' + + ethereumjs-common@1.5.0: + resolution: {integrity: sha512-SZOjgK1356hIY7MRj3/ma5qtfr/4B5BL+G4rP/XSMYr2z1H5el4RX5GReYCKmQmYI/nSBmRnwrZ17IfHuG0viQ==} + deprecated: 'New package name format for new versions: @ethereumjs/common. Please update.' + + ethereumjs-tx@1.3.7: + resolution: {integrity: sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA==} + deprecated: 'New package name format for new versions: @ethereumjs/tx. Please update.' + + ethereumjs-tx@2.1.2: + resolution: {integrity: sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw==} + deprecated: 'New package name format for new versions: @ethereumjs/tx. Please update.' + + ethereumjs-util@4.5.1: + resolution: {integrity: sha512-WrckOZ7uBnei4+AKimpuF1B3Fv25OmoRgmYCpGsP7u8PFxXAmAgiJSYT2kRWnt6fVIlKaQlZvuwXp7PIrmn3/w==} + + ethereumjs-util@5.2.1: + resolution: {integrity: sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==} + + ethereumjs-util@6.2.1: + resolution: {integrity: sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==} + + ethereumjs-util@7.1.5: + resolution: {integrity: sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==} + engines: {node: '>=10.0.0'} + + ethereumjs-vm@2.6.0: + resolution: {integrity: sha512-r/XIUik/ynGbxS3y+mvGnbOKnuLo40V5Mj1J25+HEO63aWYREIqvWeRO/hnROlMBE5WoniQmPmhiaN0ctiHaXw==} + deprecated: 'New package name format for new versions: @ethereumjs/vm. Please update.' + + ethereumjs-vm@4.2.0: + resolution: {integrity: sha512-X6qqZbsY33p5FTuZqCnQ4+lo957iUJMM6Mpa6bL4UW0dxM6WmDSHuI4j/zOp1E2TDKImBGCJA9QPfc08PaNubA==} + deprecated: 'New package name format for new versions: @ethereumjs/vm. Please update.' + + ethereumjs-wallet@0.6.5: + resolution: {integrity: sha512-MDwjwB9VQVnpp/Dc1XzA6J1a3wgHQ4hSvA1uWNatdpOrtCbPVuQSKSyRnjLvS0a+KKMw2pvQ9Ybqpb3+eW8oNA==} + + ethers@4.0.49: + resolution: {integrity: sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==} + + ethers@5.7.2: + resolution: {integrity: sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==} + + ethers@6.13.0: + resolution: {integrity: sha512-+yyQQQWEntY5UVbCv++guA14RRVFm1rSnO1GoLFdrK7/XRWMoktNgyG9UjwxrQqGBfGyFKknNZ81YpUS2emCgg==} + engines: {node: '>=14.0.0'} + + ethjs-unit@0.1.6: + resolution: {integrity: sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=} + engines: {node: '>=6.5.0', npm: '>=3'} + + ethjs-util@0.1.6: + resolution: {integrity: sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==} + engines: {node: '>=6.5.0', npm: '>=3'} + + event-emitter@0.3.5: + resolution: {integrity: sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==} + + eventemitter3@4.0.4: + resolution: {integrity: sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + + evp_bytestokey@1.0.3: + resolution: {integrity: sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==} + + expand-brackets@2.1.4: + resolution: {integrity: sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==} + engines: {node: '>=0.10.0'} + + express@4.18.2: + resolution: {integrity: sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==} + engines: {node: '>= 0.10.0'} + + ext@1.7.0: + resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==} + + extend-shallow@2.0.1: + resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} + engines: {node: '>=0.10.0'} + + extend-shallow@3.0.2: + resolution: {integrity: sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==} + engines: {node: '>=0.10.0'} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + extglob@2.0.4: + resolution: {integrity: sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==} + engines: {node: '>=0.10.0'} + + extsprintf@1.3.0: + resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==} + engines: {'0': node >=0.6.0} + + fake-merkle-patricia-tree@1.0.1: + resolution: {integrity: sha512-Tgq37lkc9pUIgIKw5uitNUKcgcYL3R6JvXtKQbOf/ZSavXbidsksgp/pAY6p//uhw0I4yoMsvTSovvVIsk/qxA==} + + fast-check@3.1.1: + resolution: {integrity: sha512-3vtXinVyuUKCKFKYcwXhGE6NtGWkqF8Yh3rvMZNzmwz8EPrgoc/v4pDdLHyLnCyCI5MZpZZkDEwFyXyEONOxpA==} + engines: {node: '>=8.0.0'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-diff@1.3.0: + resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + + fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + + fetch-ponyfill@4.1.0: + resolution: {integrity: sha512-knK9sGskIg2T7OnYLdZ2hZXn0CtDrAIBxYQLpmEf0BqfdWnwmM1weccUl5+4EdA44tzNSFAuxITPbXtPehUB3g==} + + file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + + fill-range@4.0.0: + resolution: {integrity: sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==} + engines: {node: '>=0.10.0'} + + fill-range@7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + + finalhandler@1.2.0: + resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} + engines: {node: '>= 0.8'} + + find-replace@1.0.3: + resolution: {integrity: sha512-KrUnjzDCD9426YnCP56zGYy/eieTnhtK6Vn++j+JJzmlsWWwEkDnsyVF575spT6HJ6Ow9tlbT3TQTDsa+O4UWA==} + engines: {node: '>=4.0.0'} + + find-replace@3.0.0: + resolution: {integrity: sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==} + engines: {node: '>=4.0.0'} + + find-up@1.1.2: + resolution: {integrity: sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==} + engines: {node: '>=0.10.0'} + + find-up@2.1.0: + resolution: {integrity: sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==} + engines: {node: '>=4'} + + find-up@3.0.0: + resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==} + engines: {node: '>=6'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + find-yarn-workspace-root@1.2.1: + resolution: {integrity: sha512-dVtfb0WuQG+8Ag2uWkbG79hOUzEsRrhBzgfn86g2sJPkzmcpGdghbNTfUKGTxymFrY/tLIodDzLoW9nOJ4FY8Q==} + + find-yarn-workspace-root@2.0.0: + resolution: {integrity: sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==} + + flat-cache@3.2.0: + resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} + engines: {node: ^10.12.0 || >=12.0.0} + + flat@4.1.1: + resolution: {integrity: sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==} + hasBin: true + + flat@5.0.2: + resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} + hasBin: true + + flatted@3.3.1: + resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + + flow-stoplight@1.0.0: + resolution: {integrity: sha512-rDjbZUKpN8OYhB0IE/vY/I8UWO/602IIJEU/76Tv4LvYnwHCk0BCsvz4eRr9n+FQcri7L5cyaXOo0+/Kh4HisA==} + + follow-redirects@1.15.5: + resolution: {integrity: sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + + for-in@1.0.2: + resolution: {integrity: sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==} + engines: {node: '>=0.10.0'} + + forever-agent@0.6.1: + resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==} + + form-data-encoder@1.7.1: + resolution: {integrity: sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg==} + + form-data@2.3.3: + resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==} + engines: {node: '>= 0.12'} + + form-data@2.5.1: + resolution: {integrity: sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==} + engines: {node: '>= 0.12'} + + form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fp-ts@1.19.3: + resolution: {integrity: sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==} + + fragment-cache@0.2.1: + resolution: {integrity: sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==} + engines: {node: '>=0.10.0'} + + fresh@0.5.2: + resolution: {integrity: sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=} + engines: {node: '>= 0.6'} + + fs-extra@0.30.0: + resolution: {integrity: sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==} + + fs-extra@4.0.3: + resolution: {integrity: sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==} + + fs-extra@7.0.1: + resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} + engines: {node: '>=6 <7 || >=8'} + + fs-extra@8.1.0: + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + engines: {node: '>=6 <7 || >=8'} + + fs-extra@9.1.0: + resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} + engines: {node: '>=10'} + + fs-minipass@1.2.7: + resolution: {integrity: sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==} + + fs-readdir-recursive@1.1.0: + resolution: {integrity: sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@2.1.3: + resolution: {integrity: sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + deprecated: '"Please update to latest v2.3 or v2.2"' + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + function.prototype.name@1.1.6: + resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} + engines: {node: '>= 0.4'} + + functional-red-black-tree@1.0.1: + resolution: {integrity: sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + ganache-cli@6.12.2: + resolution: {integrity: sha512-bnmwnJDBDsOWBUP8E/BExWf85TsdDEFelQSzihSJm9VChVO1SHp94YXLP5BlA4j/OTxp0wR4R1Tje9OHOuAJVw==} + deprecated: ganache-cli is now ganache; visit https://trfl.io/g7 for details + hasBin: true + bundledDependencies: + - source-map-support + - yargs + - ethereumjs-util + + ganache-core@2.13.2: + resolution: {integrity: sha512-tIF5cR+ANQz0+3pHWxHjIwHqFXcVo0Mb+kcsNhglNFALcYo49aQpnS9dqHartqPfMFjiHh/qFoD3mYK0d/qGgw==} + engines: {node: '>=8.9.0'} + deprecated: ganache-core is now ganache; visit https://trfl.io/g7 for details + bundledDependencies: + - keccak + + get-caller-file@1.0.3: + resolution: {integrity: sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-func-name@2.0.2: + resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} + + get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + + get-port@3.2.0: + resolution: {integrity: sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==} + engines: {node: '>=4'} + + get-stream@4.1.0: + resolution: {integrity: sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==} + engines: {node: '>=6'} + + get-stream@5.2.0: + resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} + engines: {node: '>=8'} + + get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + + get-symbol-description@1.0.2: + resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} + engines: {node: '>= 0.4'} + + get-value@2.0.6: + resolution: {integrity: sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==} + engines: {node: '>=0.10.0'} + + getpass@0.1.7: + resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} + + ghost-testrpc@0.0.2: + resolution: {integrity: sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ==} + hasBin: true + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob@5.0.15: + resolution: {integrity: sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==} + + glob@7.1.3: + resolution: {integrity: sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==} + + glob@7.1.7: + resolution: {integrity: sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==} + deprecated: Glob versions prior to v9 are no longer supported + + glob@7.2.0: + resolution: {integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==} + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + + glob@8.1.0: + resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} + engines: {node: '>=12'} + + global-modules@2.0.0: + resolution: {integrity: sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==} + engines: {node: '>=6'} + + global-prefix@3.0.0: + resolution: {integrity: sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==} + engines: {node: '>=6'} + + global@4.4.0: + resolution: {integrity: sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==} + + globals@13.24.0: + resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} + engines: {node: '>=8'} + + globals@9.18.0: + resolution: {integrity: sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==} + engines: {node: '>=0.10.0'} + + globalthis@1.0.3: + resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} + engines: {node: '>= 0.4'} + + globby@10.0.2: + resolution: {integrity: sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==} + engines: {node: '>=8'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + + got@11.8.6: + resolution: {integrity: sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==} + engines: {node: '>=10.19.0'} + + got@12.1.0: + resolution: {integrity: sha512-hBv2ty9QN2RdbJJMK3hesmSkFTjVIHyIDDbssCKnSmq62edGgImJWD10Eb1k77TiV1bxloxqcFAVK8+9pkhOig==} + engines: {node: '>=14.16'} + + got@9.6.0: + resolution: {integrity: sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==} + engines: {node: '>=8.6'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + growl@1.10.5: + resolution: {integrity: sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==} + engines: {node: '>=4.x'} + + handlebars@4.7.8: + resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} + engines: {node: '>=0.4.7'} + hasBin: true + + har-schema@2.0.0: + resolution: {integrity: sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==} + engines: {node: '>=4'} + + har-validator@5.1.5: + resolution: {integrity: sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==} + engines: {node: '>=6'} + deprecated: this library is no longer supported + + hardhat-gas-reporter@1.0.10: + resolution: {integrity: sha512-02N4+So/fZrzJ88ci54GqwVA3Zrf0C9duuTyGt0CFRIh/CdNwbnTgkXkRfojOMLBQ+6t+lBIkgbsOtqMvNwikA==} + peerDependencies: + hardhat: ^2.0.2 + + hardhat@2.20.1: + resolution: {integrity: sha512-q75xDQiQtCZcTMBwjTovrXEU5ECr49baxr4/OBkIu/ULTPzlB20yk1dRWNmD2IFbAeAeXggaWvQAdpiScaHtPw==} + hasBin: true + peerDependencies: + ts-node: '*' + typescript: '*' + peerDependenciesMeta: + ts-node: + optional: true + typescript: + optional: true + + has-ansi@2.0.0: + resolution: {integrity: sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==} + engines: {node: '>=0.10.0'} + + has-bigints@1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + + has-flag@1.0.0: + resolution: {integrity: sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==} + engines: {node: '>=0.10.0'} + + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + + has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + has-value@0.3.1: + resolution: {integrity: sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==} + engines: {node: '>=0.10.0'} + + has-value@1.0.0: + resolution: {integrity: sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==} + engines: {node: '>=0.10.0'} + + has-values@0.1.4: + resolution: {integrity: sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==} + engines: {node: '>=0.10.0'} + + has-values@1.0.0: + resolution: {integrity: sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==} + engines: {node: '>=0.10.0'} + + has@1.0.4: + resolution: {integrity: sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==} + engines: {node: '>= 0.4.0'} + + hash-base@3.1.0: + resolution: {integrity: sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==} + engines: {node: '>=4'} + + hash.js@1.1.3: + resolution: {integrity: sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==} + + hash.js@1.1.7: + resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==} + + hasown@2.0.1: + resolution: {integrity: sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==} + engines: {node: '>= 0.4'} + + he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + + header-case@1.0.1: + resolution: {integrity: sha512-i0q9mkOeSuhXw6bGgiQCCBgY/jlZuV/7dZXyZ9c6LcBrqwvT8eT719E9uxE5LiZftdl+z81Ugbg/VvXV4OJOeQ==} + + heap@0.2.6: + resolution: {integrity: sha512-MzzWcnfB1e4EG2vHi3dXHoBupmuXNZzx6pY6HldVS55JKKBoq3xOyzfSaZRkJp37HIhEYC78knabHff3zc4dQQ==} + + heap@0.2.7: + resolution: {integrity: sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==} + + highlight.js@10.7.3: + resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} + + highlightjs-solidity@2.0.6: + resolution: {integrity: sha512-DySXWfQghjm2l6a/flF+cteroJqD4gI8GSdL4PtvxZSsAHie8m3yVe2JFoRg03ROKT6hp2Lc/BxXkqerNmtQYg==} + + hmac-drbg@1.0.1: + resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} + + home-or-tmp@2.0.0: + resolution: {integrity: sha512-ycURW7oUxE2sNiPVw1HVEFsW+ecOpJ5zaj7eC0RlwhibhRBod20muUN8qu/gzx956YrLolVvs1MTXwKgC2rVEg==} + engines: {node: '>=0.10.0'} + + hosted-git-info@2.8.9: + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + + htmlparser2@8.0.2: + resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} + + http-basic@8.1.3: + resolution: {integrity: sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==} + engines: {node: '>=6.0.0'} + + http-cache-semantics@4.1.1: + resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} + + http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + + http-https@1.0.0: + resolution: {integrity: sha512-o0PWwVCSp3O0wS6FvNr6xfBCHgt0m1tvPLFOCc2iFDKTRAXhB7m8klDf7ErowFH8POa6dVdGatKU5I1YYwzUyg==} + + http-response-object@3.0.2: + resolution: {integrity: sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==} + + http-signature@1.2.0: + resolution: {integrity: sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==} + engines: {node: '>=0.8', npm: '>=1.3.7'} + + http2-wrapper@1.0.3: + resolution: {integrity: sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==} + engines: {node: '>=10.19.0'} + + http2-wrapper@2.2.1: + resolution: {integrity: sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==} + engines: {node: '>=10.19.0'} + + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + + husky@9.0.11: + resolution: {integrity: sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==} + engines: {node: '>=18'} + hasBin: true + + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + idna-uts46-hx@2.3.1: + resolution: {integrity: sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==} + engines: {node: '>=4.0.0'} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + ignore@4.0.6: + resolution: {integrity: sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==} + engines: {node: '>= 4'} + + ignore@5.3.1: + resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} + engines: {node: '>= 4'} + + immediate@3.2.3: + resolution: {integrity: sha512-RrGCXRm/fRVqMIhqXrGEX9rRADavPiDFSoMb/k64i9XMk8uH4r/Omi5Ctierj6XzNecwDbO4WuFbDD1zmpl3Tg==} + + immediate@3.3.0: + resolution: {integrity: sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==} + + immutable@4.3.5: + resolution: {integrity: sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==} + + import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + + internal-slot@1.0.7: + resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} + engines: {node: '>= 0.4'} + + interpret@1.4.0: + resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==} + engines: {node: '>= 0.10'} + + invariant@2.2.4: + resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} + + invert-kv@1.0.0: + resolution: {integrity: sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==} + engines: {node: '>=0.10.0'} + + io-ts@1.10.4: + resolution: {integrity: sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + is-accessor-descriptor@1.0.1: + resolution: {integrity: sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA==} + engines: {node: '>= 0.10'} + + is-arguments@1.1.1: + resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} + engines: {node: '>= 0.4'} + + is-array-buffer@3.0.4: + resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} + engines: {node: '>= 0.4'} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-bigint@1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-boolean-object@1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + + is-buffer@1.1.6: + resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} + + is-buffer@2.0.5: + resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==} + engines: {node: '>=4'} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-ci@2.0.0: + resolution: {integrity: sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==} + hasBin: true + + is-core-module@2.13.1: + resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} + + is-data-descriptor@1.0.1: + resolution: {integrity: sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw==} + engines: {node: '>= 0.4'} + + is-date-object@1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + + is-descriptor@0.1.7: + resolution: {integrity: sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==} + engines: {node: '>= 0.4'} + + is-descriptor@1.0.3: + resolution: {integrity: sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==} + engines: {node: '>= 0.4'} + + is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + + is-extendable@0.1.1: + resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} + engines: {node: '>=0.10.0'} + + is-extendable@1.0.1: + resolution: {integrity: sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==} + engines: {node: '>=0.10.0'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-finite@1.1.0: + resolution: {integrity: sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==} + engines: {node: '>=0.10.0'} + + is-fn@1.0.0: + resolution: {integrity: sha512-XoFPJQmsAShb3jEQRfzf2rqXavq7fIqF/jOekp308JlThqrODnMpweVSGilKTCXELfLhltGP2AGgbQGVP8F1dg==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@1.0.0: + resolution: {integrity: sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@2.0.0: + resolution: {integrity: sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==} + engines: {node: '>=4'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-function@1.0.2: + resolution: {integrity: sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==} + + is-generator-function@1.0.10: + resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} + engines: {node: '>= 0.4'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-hex-prefixed@1.0.0: + resolution: {integrity: sha1-fY035q135dEnFIkTxXPggtd39VQ=} + engines: {node: '>=6.5.0', npm: '>=3'} + + is-interactive@1.0.0: + resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} + engines: {node: '>=8'} + + is-lower-case@1.1.3: + resolution: {integrity: sha512-+5A1e/WJpLLXZEDlgz4G//WYSHyQBD32qa4Jd3Lw06qQlv3fJHnp3YIHjTQSGzHMgzmVKz2ZP3rBxTHkPw/lxA==} + + is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + + is-number-object@1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + + is-number@3.0.0: + resolution: {integrity: sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-observable@2.1.0: + resolution: {integrity: sha512-DailKdLb0WU+xX8K5w7VsJhapwHLZ9jjmazqCJq4X12CTgqq73TKnbRcnSLuXYPOoLQgV5IrD7ePiX/h1vnkBw==} + engines: {node: '>=8'} + + is-plain-obj@2.1.0: + resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} + engines: {node: '>=8'} + + is-plain-object@2.0.4: + resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} + engines: {node: '>=0.10.0'} + + is-regex@1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.3: + resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} + engines: {node: '>= 0.4'} + + is-stream@1.1.0: + resolution: {integrity: sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==} + engines: {node: '>=0.10.0'} + + is-string@1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + + is-symbol@1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + + is-typed-array@1.1.13: + resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} + engines: {node: '>= 0.4'} + + is-typedarray@1.0.0: + resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} + + is-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + + is-upper-case@1.1.2: + resolution: {integrity: sha512-GQYSJMgfeAmVwh9ixyk888l7OIhNAGKtY6QA+IrWlu9MDTCaXmeozOZ2S9Knj7bQwBO/H6J2kb+pbyTUiMNbsw==} + + is-url@1.2.4: + resolution: {integrity: sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==} + + is-utf8@0.2.1: + resolution: {integrity: sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==} + + is-weakref@1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + + is-windows@1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} + + is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + + isarray@0.0.1: + resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isobject@2.1.0: + resolution: {integrity: sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==} + engines: {node: '>=0.10.0'} + + isobject@3.0.1: + resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} + engines: {node: '>=0.10.0'} + + isstream@0.1.2: + resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} + + js-sdsl@4.4.2: + resolution: {integrity: sha512-dwXFwByc/ajSV6m5bcKAPwe4yDDF6D614pxmIi5odytzxRlwqF6nwoiCek80Ixc7Cvma5awClxrzFtxCQvcM8w==} + + js-sha3@0.5.7: + resolution: {integrity: sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==} + + js-sha3@0.8.0: + resolution: {integrity: sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==} + + js-tokens@3.0.2: + resolution: {integrity: sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@3.13.1: + resolution: {integrity: sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==} + hasBin: true + + js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + jsbn@0.1.1: + resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} + + jsesc@0.5.0: + resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} + hasBin: true + + jsesc@1.3.0: + resolution: {integrity: sha512-Mke0DA0QjUWuJlhsE0ZPPhYiJkRap642SmI/4ztCFaUs6V2AiH1sfecc+57NgaryfAA2VR3v6O+CSjC1jZJKOA==} + hasBin: true + + json-buffer@3.0.0: + resolution: {integrity: sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=} + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + json-rpc-engine@3.8.0: + resolution: {integrity: sha512-6QNcvm2gFuuK4TKU1uwfH0Qd/cOSb9c1lls0gbnIhciktIUQJwz6NQNAW4B1KiGPenv7IKu97V222Yo1bNhGuA==} + + json-rpc-error@2.0.0: + resolution: {integrity: sha512-EwUeWP+KgAZ/xqFpaP6YDAXMtCJi+o/QQpCQFIYyxr01AdADi2y413eM8hSqJcoQym9WMePAJWoaODEJufC4Ug==} + + json-rpc-random-id@1.0.1: + resolution: {integrity: sha512-RJ9YYNCkhVDBuP4zN5BBtYAzEl03yq/jIIsyif0JY9qyJuQQZNeDK7anAPKKlyEtLSj2s8h6hNh2F8zO5q7ScA==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-schema@0.4.0: + resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json-stable-stringify@1.1.1: + resolution: {integrity: sha512-SU/971Kt5qVQfJpyDveVhQ/vya+5hvrjClFOcr8c0Fq5aODJjMwutrOfCU+eCnVD5gpx1Q3fEqkyom77zH1iIg==} + engines: {node: '>= 0.4'} + + json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + + json5@0.5.1: + resolution: {integrity: sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw==} + hasBin: true + + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + + jsonfile@2.4.0: + resolution: {integrity: sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==} + + jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + + jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + + jsonify@0.0.1: + resolution: {integrity: sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==} + + jsonschema@1.4.1: + resolution: {integrity: sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==} + + jsprim@1.4.2: + resolution: {integrity: sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==} + engines: {node: '>=0.6.0'} + + keccak256@1.0.6: + resolution: {integrity: sha512-8GLiM01PkdJVGUhR1e6M/AvWnSqYS0HaERI+K/QtStGDGlSTx2B1zTqZk4Zlqu5TxHJNTxWAdP9Y+WI50OApUw==} + + keccak@3.0.4: + resolution: {integrity: sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q==} + engines: {node: '>=10.0.0'} + + keyv@3.1.0: + resolution: {integrity: sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + kind-of@3.2.2: + resolution: {integrity: sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==} + engines: {node: '>=0.10.0'} + + kind-of@4.0.0: + resolution: {integrity: sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==} + engines: {node: '>=0.10.0'} + + kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + + klaw-sync@6.0.0: + resolution: {integrity: sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==} + + klaw@1.3.1: + resolution: {integrity: sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==} + + lcid@1.0.0: + resolution: {integrity: sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==} + engines: {node: '>=0.10.0'} + + level-codec@7.0.1: + resolution: {integrity: sha512-Ua/R9B9r3RasXdRmOtd+t9TCOEIIlts+TN/7XTT2unhDaL6sJn83S3rUyljbr6lVtw49N3/yA0HHjpV6Kzb2aQ==} + + level-codec@9.0.2: + resolution: {integrity: sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ==} + engines: {node: '>=6'} + + level-errors@1.0.5: + resolution: {integrity: sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==} + + level-errors@2.0.1: + resolution: {integrity: sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==} + engines: {node: '>=6'} + + level-iterator-stream@1.3.1: + resolution: {integrity: sha512-1qua0RHNtr4nrZBgYlpV0qHHeHpcRRWTxEZJ8xsemoHAXNL5tbooh4tPEEqIqsbWCAJBmUmkwYK/sW5OrFjWWw==} + + level-iterator-stream@2.0.3: + resolution: {integrity: sha512-I6Heg70nfF+e5Y3/qfthJFexhRw/Gi3bIymCoXAlijZdAcLaPuWSJs3KXyTYf23ID6g0o2QF62Yh+grOXY3Rig==} + engines: {node: '>=4'} + + level-iterator-stream@3.0.1: + resolution: {integrity: sha512-nEIQvxEED9yRThxvOrq8Aqziy4EGzrxSZK+QzEFAVuJvQ8glfyZ96GB6BoI4sBbLfjMXm2w4vu3Tkcm9obcY0g==} + engines: {node: '>=6'} + + level-mem@3.0.1: + resolution: {integrity: sha512-LbtfK9+3Ug1UmvvhR2DqLqXiPW1OJ5jEh0a3m9ZgAipiwpSxGj/qaVVy54RG5vAQN1nCuXqjvprCuKSCxcJHBg==} + engines: {node: '>=6'} + + level-packager@4.0.1: + resolution: {integrity: sha512-svCRKfYLn9/4CoFfi+d8krOtrp6RoX8+xm0Na5cgXMqSyRru0AnDYdLl+YI8u1FyS6gGZ94ILLZDE5dh2but3Q==} + engines: {node: '>=6'} + + level-post@1.0.7: + resolution: {integrity: sha512-PWYqG4Q00asOrLhX7BejSajByB4EmG2GaKHfj3h5UmmZ2duciXLPGYWIjBzLECFWUGOZWlm5B20h/n3Gs3HKew==} + + level-sublevel@6.6.4: + resolution: {integrity: sha512-pcCrTUOiO48+Kp6F1+UAzF/OtWqLcQVTVF39HLdZ3RO8XBoXt+XVPKZO1vVr1aUoxHZA9OtD2e1v7G+3S5KFDA==} + + level-ws@0.0.0: + resolution: {integrity: sha512-XUTaO/+Db51Uiyp/t7fCMGVFOTdtLS/NIACxE/GHsij15mKzxksZifKVjlXDF41JMUP/oM1Oc4YNGdKnc3dVLw==} + + level-ws@1.0.0: + resolution: {integrity: sha512-RXEfCmkd6WWFlArh3X8ONvQPm8jNpfA0s/36M4QzLqrLEIt1iJE9WBHLZ5vZJK6haMjJPJGJCQWfjMNnRcq/9Q==} + engines: {node: '>=6'} + + levelup@1.3.9: + resolution: {integrity: sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==} + + levelup@3.1.1: + resolution: {integrity: sha512-9N10xRkUU4dShSRRFTBdNaBxofz+PGaIZO962ckboJZiNmLuhVT6FZ6ZKAsICKfUBO76ySaYU6fJWX/jnj3Lcg==} + engines: {node: '>=6'} + + levn@0.3.0: + resolution: {integrity: sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==} + engines: {node: '>= 0.8.0'} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + load-json-file@1.1.0: + resolution: {integrity: sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==} + engines: {node: '>=0.10.0'} + + load-json-file@2.0.0: + resolution: {integrity: sha512-3p6ZOGNbiX4CdvEd1VcE6yi78UrGNpjHO33noGwHCnT/o2fyllJDepsm8+mFFv/DvtwFHht5HIHSyOy5a+ChVQ==} + engines: {node: '>=4'} + + locate-path@2.0.0: + resolution: {integrity: sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==} + engines: {node: '>=4'} + + locate-path@3.0.0: + resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==} + engines: {node: '>=6'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.assign@4.2.0: + resolution: {integrity: sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw==} + + lodash.camelcase@4.3.0: + resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} + + lodash.clonedeep@4.5.0: + resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==} + + lodash.isequal@4.5.0: + resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lodash.truncate@4.4.2: + resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} + + lodash@4.17.20: + resolution: {integrity: sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + log-symbols@3.0.0: + resolution: {integrity: sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==} + engines: {node: '>=8'} + + log-symbols@4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} + + looper@2.0.0: + resolution: {integrity: sha512-6DzMHJcjbQX/UPHc1rRCBfKlLwDkvuGZ715cIR36wSdYqWXFT35uLXq5P/2orl3tz+t+VOVPxw4yPinQlUDGDQ==} + + looper@3.0.0: + resolution: {integrity: sha512-LJ9wplN/uSn72oJRsXTx+snxPet5c8XiZmOKCm906NVYu+ag6SB6vUcnJcWxgnl2NfbIyeobAn7Bwv6xRj2XJg==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + lower-case-first@1.0.2: + resolution: {integrity: sha512-UuxaYakO7XeONbKrZf5FEgkantPf5DUqDayzP5VXZrtRPdH86s4kN47I8B3TW10S4QKiE3ziHNf3kRN//okHjA==} + + lower-case@1.1.4: + resolution: {integrity: sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==} + + lowercase-keys@1.0.1: + resolution: {integrity: sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==} + engines: {node: '>=0.10.0'} + + lowercase-keys@2.0.0: + resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} + engines: {node: '>=8'} + + lowercase-keys@3.0.0: + resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + lru-cache@10.2.0: + resolution: {integrity: sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==} + engines: {node: 14 || >=16.14} + + lru-cache@3.2.0: + resolution: {integrity: sha512-91gyOKTc2k66UG6kHiH4h3S2eltcPwE1STVfMYC/NG+nZwf8IIuiamfmpGZjpbbxzSyEJaLC0tNSmhjlQUTJow==} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + + lru_map@0.3.3: + resolution: {integrity: sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==} + + ltgt@2.1.3: + resolution: {integrity: sha512-5VjHC5GsENtIi5rbJd+feEpDKhfr7j0odoUR2Uh978g+2p93nd5o34cTjQWohXsPsCZeqoDnIqEf88mPCe0Pfw==} + + ltgt@2.2.1: + resolution: {integrity: sha512-AI2r85+4MquTw9ZYqabu4nMwy9Oftlfa/e/52t9IjtfG+mGBbTNdAoZ3RQKLHR6r0wQnwZnPIEh/Ya6XTWAKNA==} + + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + + map-cache@0.2.2: + resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==} + engines: {node: '>=0.10.0'} + + map-visit@1.0.0: + resolution: {integrity: sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==} + engines: {node: '>=0.10.0'} + + markdown-table@1.1.3: + resolution: {integrity: sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==} + + md5.js@1.3.5: + resolution: {integrity: sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==} + + media-typer@0.3.0: + resolution: {integrity: sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=} + engines: {node: '>= 0.6'} + + memdown@1.4.1: + resolution: {integrity: sha512-iVrGHZB8i4OQfM155xx8akvG9FIj+ht14DX5CQkCTG4EHzZ3d3sgckIf/Lm9ivZalEsFuEVnWv2B2WZvbrro2w==} + + memdown@3.0.0: + resolution: {integrity: sha512-tbV02LfZMWLcHcq4tw++NuqMO+FZX8tNJEiD2aNRm48ZZusVg5N8NART+dmBkepJVye986oixErf7jfXboMGMA==} + engines: {node: '>=6'} + + memorystream@0.3.1: + resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} + engines: {node: '>= 0.10.0'} + + merge-descriptors@1.0.1: + resolution: {integrity: sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + merkle-patricia-tree@2.3.2: + resolution: {integrity: sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g==} + + merkle-patricia-tree@3.0.0: + resolution: {integrity: sha512-soRaMuNf/ILmw3KWbybaCjhx86EYeBbD8ph0edQCTed0JN/rxDt1EBN52Ajre3VyGo+91f8+/rfPIRQnnGMqmQ==} + + methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + + micro-ftch@0.3.1: + resolution: {integrity: sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==} + + micromatch@3.1.10: + resolution: {integrity: sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==} + engines: {node: '>=0.10.0'} + + micromatch@4.0.5: + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + engines: {node: '>=8.6'} + + miller-rabin@4.0.1: + resolution: {integrity: sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==} + hasBin: true + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + mimic-response@1.0.1: + resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} + engines: {node: '>=4'} + + mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + + min-document@2.19.0: + resolution: {integrity: sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==} + + minimalistic-assert@1.0.1: + resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} + + minimalistic-crypto-utils@1.0.1: + resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} + + minimatch@3.0.4: + resolution: {integrity: sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@5.0.1: + resolution: {integrity: sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==} + engines: {node: '>=10'} + + minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass@2.9.0: + resolution: {integrity: sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==} + + minizlib@1.3.3: + resolution: {integrity: sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==} + + mixin-deep@1.3.2: + resolution: {integrity: sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==} + engines: {node: '>=0.10.0'} + + mkdirp-promise@5.0.1: + resolution: {integrity: sha512-Hepn5kb1lJPtVW84RFT40YG1OddBNTOVUZR2bzQUHc+Z03en8/3uX0+060JDhcEzyO08HmipsN9DcnFMxhIL9w==} + engines: {node: '>=4'} + deprecated: This package is broken and no longer maintained. 'mkdirp' itself supports promises now, please switch to that. + + mkdirp@0.5.5: + resolution: {integrity: sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==} + hasBin: true + + mkdirp@0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + + mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + + mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} + engines: {node: '>=10'} + hasBin: true + + mnemonist@0.38.5: + resolution: {integrity: sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==} + + mocha@10.3.0: + resolution: {integrity: sha512-uF2XJs+7xSLsrmIvn37i/wnc91nw7XjOQB8ccyx5aEgdnohr7n+rEiZP23WkCYHjilR6+EboEnbq/ZQDz4LSbg==} + engines: {node: '>= 14.0.0'} + hasBin: true + + mocha@7.1.2: + resolution: {integrity: sha512-o96kdRKMKI3E8U0bjnfqW4QMk12MwZ4mhdBTf+B5a1q9+aq2HRnj+3ZdJu0B/ZhJeK78MgYuv6L8d/rA5AeBJA==} + engines: {node: '>= 8.10.0'} + hasBin: true + + mock-fs@4.14.0: + resolution: {integrity: sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw==} + + mock-property@1.0.3: + resolution: {integrity: sha512-2emPTb1reeLLYwHxyVx993iYyCHEiRRO+y8NFXFPL5kl5q14sgTK76cXyEKkeKCHeRw35SfdkUJ10Q1KfHuiIQ==} + engines: {node: '>= 0.4'} + + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + + ms@2.1.1: + resolution: {integrity: sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==} + + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + multibase@0.6.1: + resolution: {integrity: sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw==} + deprecated: This module has been superseded by the multiformats module + + multibase@0.7.0: + resolution: {integrity: sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==} + deprecated: This module has been superseded by the multiformats module + + multicodec@0.5.7: + resolution: {integrity: sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA==} + deprecated: This module has been superseded by the multiformats module + + multicodec@1.0.4: + resolution: {integrity: sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg==} + deprecated: This module has been superseded by the multiformats module + + multihashes@0.4.21: + resolution: {integrity: sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw==} + + nan@2.18.0: + resolution: {integrity: sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==} + + nano-base32@1.0.1: + resolution: {integrity: sha512-sxEtoTqAPdjWVGv71Q17koMFGsOMSiHsIFEvzOM7cNp8BXB4AnEwmDabm5dorusJf/v1z7QxaZYxUorU9RKaAw==} + + nano-json-stream-parser@0.1.2: + resolution: {integrity: sha512-9MqxMH/BSJC7dnLsEMPyfN5Dvoo49IsPFYMcHw3Bcfc2kN0lpHRBSzlMSVx4HGyJ7s9B31CyBTVehWJoQ8Ctew==} + + nanomatch@1.2.13: + resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==} + engines: {node: '>=0.10.0'} + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + + neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + + next-tick@1.1.0: + resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==} + + nice-try@1.0.5: + resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} + + no-case@2.3.2: + resolution: {integrity: sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==} + + node-addon-api@2.0.2: + resolution: {integrity: sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==} + + node-emoji@1.11.0: + resolution: {integrity: sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==} + + node-environment-flags@1.0.6: + resolution: {integrity: sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==} + + node-fetch@1.7.3: + resolution: {integrity: sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==} + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-gyp-build@4.8.0: + resolution: {integrity: sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og==} + hasBin: true + + nofilter@1.0.4: + resolution: {integrity: sha512-N8lidFp+fCz+TD51+haYdbDGrcBWwuHX40F5+z0qkUjMJ5Tp+rdSuAkMJ9N9eoolDlEVTf6u5icM+cNKkKW2mA==} + engines: {node: '>=8'} + + nofilter@3.1.0: + resolution: {integrity: sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==} + engines: {node: '>=12.19'} + + nopt@3.0.6: + resolution: {integrity: sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==} + hasBin: true + + normalize-package-data@2.5.0: + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + normalize-url@4.5.1: + resolution: {integrity: sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==} + engines: {node: '>=8'} + + normalize-url@6.1.0: + resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} + engines: {node: '>=10'} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + number-is-nan@1.0.1: + resolution: {integrity: sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==} + engines: {node: '>=0.10.0'} + + number-to-bn@1.7.0: + resolution: {integrity: sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=} + engines: {node: '>=6.5.0', npm: '>=3'} + + oauth-sign@0.9.0: + resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-copy@0.1.0: + resolution: {integrity: sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==} + engines: {node: '>=0.10.0'} + + object-inspect@1.12.3: + resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} + + object-inspect@1.13.1: + resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} + + object-is@1.1.5: + resolution: {integrity: sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==} + engines: {node: '>= 0.4'} + + object-keys@0.4.0: + resolution: {integrity: sha512-ncrLw+X55z7bkl5PnUvHwFK9FcGuFYo9gtjws2XtSzL+aZ8tm830P60WJ0dSmFVaSalWieW5MD7kEdnXda9yJw==} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object-visit@1.0.1: + resolution: {integrity: sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==} + engines: {node: '>=0.10.0'} + + object.assign@4.1.0: + resolution: {integrity: sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==} + engines: {node: '>= 0.4'} + + object.assign@4.1.5: + resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} + engines: {node: '>= 0.4'} + + object.getownpropertydescriptors@2.1.7: + resolution: {integrity: sha512-PrJz0C2xJ58FNn11XV2lr4Jt5Gzl94qpy9Lu0JlfEj14z88sqbSBJCBEzdlNUCzY2gburhbrwOZ5BHCmuNUy0g==} + engines: {node: '>= 0.8'} + + object.pick@1.3.0: + resolution: {integrity: sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==} + engines: {node: '>=0.10.0'} + + object.values@1.1.7: + resolution: {integrity: sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==} + engines: {node: '>= 0.4'} + + obliterator@2.0.4: + resolution: {integrity: sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==} + + oboe@2.1.4: + resolution: {integrity: sha1-IMiM2wwVNxuwQRklfU/dNLCqSfY=} + + oboe@2.1.5: + resolution: {integrity: sha1-VVQoTFQ6ImbXo48X4HOCH73jk80=} + + observable-fns@0.6.1: + resolution: {integrity: sha512-9gRK4+sRWzeN6AOewNBTLXir7Zl/i3GB6Yl26gK4flxz8BXVpD3kt8amREmWNb0mxYOGDotvE5a4N+PtGGKdkg==} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + + open@7.4.2: + resolution: {integrity: sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==} + engines: {node: '>=8'} + + optionator@0.8.3: + resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==} + engines: {node: '>= 0.8.0'} + + optionator@0.9.3: + resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} + engines: {node: '>= 0.8.0'} + + ora@5.4.1: + resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} + engines: {node: '>=10'} + + os-homedir@1.0.2: + resolution: {integrity: sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==} + engines: {node: '>=0.10.0'} + + os-locale@1.4.0: + resolution: {integrity: sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==} + engines: {node: '>=0.10.0'} + + os-tmpdir@1.0.2: + resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} + engines: {node: '>=0.10.0'} + + p-cancelable@1.1.0: + resolution: {integrity: sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==} + engines: {node: '>=6'} + + p-cancelable@2.1.1: + resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==} + engines: {node: '>=8'} + + p-cancelable@3.0.0: + resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==} + engines: {node: '>=12.20'} + + p-limit@1.3.0: + resolution: {integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==} + engines: {node: '>=4'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@2.0.0: + resolution: {integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==} + engines: {node: '>=4'} + + p-locate@3.0.0: + resolution: {integrity: sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==} + engines: {node: '>=6'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + p-map@4.0.0: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + engines: {node: '>=10'} + + p-try@1.0.0: + resolution: {integrity: sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==} + engines: {node: '>=4'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + + param-case@2.1.1: + resolution: {integrity: sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-asn1@5.1.6: + resolution: {integrity: sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==} + + parse-cache-control@1.0.1: + resolution: {integrity: sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==} + + parse-headers@2.0.5: + resolution: {integrity: sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==} + + parse-json@2.2.0: + resolution: {integrity: sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==} + engines: {node: '>=0.10.0'} + + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + + parse5-htmlparser2-tree-adapter@7.0.0: + resolution: {integrity: sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==} + + parse5@7.1.2: + resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + pascal-case@2.0.1: + resolution: {integrity: sha512-qjS4s8rBOJa2Xm0jmxXiyh1+OFf6ekCWOvUaRgAQSktzlTbMotS0nmG9gyYAybCWBcuP4fsBeRCKNwGBnMe2OQ==} + + pascalcase@0.1.1: + resolution: {integrity: sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==} + engines: {node: '>=0.10.0'} + + patch-package@6.2.2: + resolution: {integrity: sha512-YqScVYkVcClUY0v8fF0kWOjDYopzIM8e3bj/RU1DPeEF14+dCGm6UeOYm4jvCyxqIEQ5/eJzmbWfDWnUleFNMg==} + engines: {npm: '>5'} + hasBin: true + + patch-package@6.5.1: + resolution: {integrity: sha512-I/4Zsalfhc6bphmJTlrLoOcAF87jcxko4q0qsv4bGcurbr8IskEOtdnt9iCmsQVGL1B+iUhSQqweyTLJfCF9rA==} + engines: {node: '>=10', npm: '>5'} + hasBin: true + + path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + + path-case@2.1.1: + resolution: {integrity: sha512-Ou0N05MioItesaLr9q8TtHVWmJ6fxWdqKB2RohFmNWVyJ+2zeKIeDNWAN6B/Pe7wpzWChhZX6nONYmOnMeJQ/Q==} + + path-exists@2.1.0: + resolution: {integrity: sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==} + engines: {node: '>=0.10.0'} + + path-exists@3.0.0: + resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} + engines: {node: '>=4'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@2.0.1: + resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} + engines: {node: '>=4'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-to-regexp@0.1.7: + resolution: {integrity: sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=} + + path-type@1.1.0: + resolution: {integrity: sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==} + engines: {node: '>=0.10.0'} + + path-type@2.0.0: + resolution: {integrity: sha512-dUnb5dXUf+kzhC/W/F4e5/SkluXIFf5VUHolW1Eg1irn1hGWjPGdsRcvYJ1nD6lhk8Ir7VM0bHJKsYTx8Jx9OQ==} + engines: {node: '>=4'} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + pathval@1.1.1: + resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + + pbkdf2@3.1.2: + resolution: {integrity: sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==} + engines: {node: '>=0.12'} + + performance-now@2.1.0: + resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + + pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + + pinkie-promise@2.0.1: + resolution: {integrity: sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==} + engines: {node: '>=0.10.0'} + + pinkie@2.0.4: + resolution: {integrity: sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==} + engines: {node: '>=0.10.0'} + + pluralize@8.0.0: + resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} + engines: {node: '>=4'} + + posix-character-classes@0.1.1: + resolution: {integrity: sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==} + engines: {node: '>=0.10.0'} + + possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} + + postinstall-postinstall@2.1.0: + resolution: {integrity: sha512-7hQX6ZlZXIoRiWNrbMQaLzUUfH+sSx39u8EJ9HYuDc1kLo9IXKWjM5RSquZN1ad5GnH8CGFM78fsAAQi3OKEEQ==} + + precond@0.2.3: + resolution: {integrity: sha512-QCYG84SgGyGzqJ/vlMsxeXd/pgL/I94ixdNFyh1PusWmTCyVfPJjZ1K1jvHtsbfnXQs2TSkEP2fR7QiMZAnKFQ==} + engines: {node: '>= 0.6'} + + prelude-ls@1.1.2: + resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==} + engines: {node: '>= 0.8.0'} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prepend-http@2.0.0: + resolution: {integrity: sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==} + engines: {node: '>=4'} + + prettier-linter-helpers@1.0.0: + resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} + engines: {node: '>=6.0.0'} + + prettier@2.8.8: + resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} + engines: {node: '>=10.13.0'} + hasBin: true + + prettier@3.2.5: + resolution: {integrity: sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==} + engines: {node: '>=14'} + hasBin: true + + private@0.1.8: + resolution: {integrity: sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==} + engines: {node: '>= 0.6'} + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + + progress@2.0.3: + resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} + engines: {node: '>=0.4.0'} + + promise-to-callback@1.0.0: + resolution: {integrity: sha512-uhMIZmKM5ZteDMfLgJnoSq9GCwsNKrYau73Awf1jIy6/eUcuuZ3P+CD9zUv0kJsIUbU+x6uLNIhXhLHDs1pNPA==} + engines: {node: '>=0.10.0'} + + promise@8.3.0: + resolution: {integrity: sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==} + + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + prr@1.0.1: + resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==} + + pseudomap@1.0.2: + resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} + + psl@1.9.0: + resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} + + public-encrypt@4.0.3: + resolution: {integrity: sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==} + + pull-cat@1.1.11: + resolution: {integrity: sha512-i3w+xZ3DCtTVz8S62hBOuNLRHqVDsHMNZmgrZsjPnsxXUgbWtXEee84lo1XswE7W2a3WHyqsNuDJTjVLAQR8xg==} + + pull-defer@0.2.3: + resolution: {integrity: sha512-/An3KE7mVjZCqNhZsr22k1Tx8MACnUnHZZNPSJ0S62td8JtYr/AiRG42Vz7Syu31SoTLUzVIe61jtT/pNdjVYA==} + + pull-level@2.0.4: + resolution: {integrity: sha512-fW6pljDeUThpq5KXwKbRG3X7Ogk3vc75d5OQU/TvXXui65ykm+Bn+fiktg+MOx2jJ85cd+sheufPL+rw9QSVZg==} + + pull-live@1.0.1: + resolution: {integrity: sha512-tkNz1QT5gId8aPhV5+dmwoIiA1nmfDOzJDlOOUpU5DNusj6neNd3EePybJ5+sITr2FwyCs/FVpx74YMCfc8YeA==} + + pull-pushable@2.2.0: + resolution: {integrity: sha512-M7dp95enQ2kaHvfCt2+DJfyzgCSpWVR2h2kWYnVsW6ZpxQBx5wOu0QWOvQPVoPnBLUZYitYP2y7HyHkLQNeGXg==} + + pull-stream@3.7.0: + resolution: {integrity: sha512-Eco+/R004UaCK2qEDE8vGklcTG2OeZSVm1kTUQNrykEjDwcFXDZhygFDsW49DbXyJMEhHeRL3z5cRVqPAhXlIw==} + + pull-window@2.1.4: + resolution: {integrity: sha512-cbDzN76BMlcGG46OImrgpkMf/VkCnupj8JhsrpBw3aWBM9ye345aYnqitmZCgauBkc0HbbRRn9hCnsa3k2FNUg==} + + pump@3.0.0: + resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} + + punycode@1.4.1: + resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} + + punycode@2.1.0: + resolution: {integrity: sha512-Yxz2kRwT90aPiWEMHVYnEf4+rhwF1tBmmZ4KepCP+Wkium9JxtWnUm1nqGwpiAHr/tnTSeHqr3wb++jgSkXjhA==} + engines: {node: '>=6'} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + pure-rand@5.0.5: + resolution: {integrity: sha512-BwQpbqxSCBJVpamI6ydzcKqyFmnd5msMWUGvzXLm1aXvusbbgkbOto/EUPM00hjveJEaJtdbhUjKSzWRhQVkaw==} + + qs@6.11.0: + resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} + engines: {node: '>=0.6'} + + qs@6.11.2: + resolution: {integrity: sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==} + engines: {node: '>=0.6'} + + qs@6.5.3: + resolution: {integrity: sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==} + engines: {node: '>=0.6'} + + query-string@5.1.1: + resolution: {integrity: sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==} + engines: {node: '>=0.10.0'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + quick-lru@5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} + + randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + + randomfill@1.0.4: + resolution: {integrity: sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==} + + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@2.5.1: + resolution: {integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==} + engines: {node: '>= 0.8'} + + raw-body@2.5.2: + resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} + engines: {node: '>= 0.8'} + + read-pkg-up@1.0.1: + resolution: {integrity: sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==} + engines: {node: '>=0.10.0'} + + read-pkg-up@2.0.0: + resolution: {integrity: sha512-1orxQfbWGUiTn9XsPlChs6rLie/AV9jwZTGmu2NZw/CUDJQchXJFYE0Fq5j7+n558T1JhDWLdhyd1Zj+wLY//w==} + engines: {node: '>=4'} + + read-pkg@1.1.0: + resolution: {integrity: sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==} + engines: {node: '>=0.10.0'} + + read-pkg@2.0.0: + resolution: {integrity: sha512-eFIBOPW7FGjzBuk3hdXEuNSiTZS/xEMlH49HxMyzb0hyPfu4EhVjT2DH32K1hSSmVq4sebAWnZuuY5auISUTGA==} + engines: {node: '>=4'} + + readable-stream@1.0.34: + resolution: {integrity: sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==} + + readable-stream@1.1.14: + resolution: {integrity: sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + readdirp@3.2.0: + resolution: {integrity: sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==} + engines: {node: '>= 8'} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + rechoir@0.6.2: + resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} + engines: {node: '>= 0.10'} + + recursive-readdir@2.2.3: + resolution: {integrity: sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==} + engines: {node: '>=6.0.0'} + + reduce-flatten@2.0.0: + resolution: {integrity: sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==} + engines: {node: '>=6'} + + regenerate@1.4.2: + resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} + + regenerator-runtime@0.11.1: + resolution: {integrity: sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==} + + regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + + regenerator-transform@0.10.1: + resolution: {integrity: sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==} + + regex-not@1.0.2: + resolution: {integrity: sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==} + engines: {node: '>=0.10.0'} + + regexp.prototype.flags@1.5.2: + resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} + engines: {node: '>= 0.4'} + + regexpp@3.2.0: + resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} + engines: {node: '>=8'} + + regexpu-core@2.0.0: + resolution: {integrity: sha512-tJ9+S4oKjxY8IZ9jmjnp/mtytu1u3iyIQAfmI51IKWH6bFf7XR1ybtaO6j7INhZKXOTYADk7V5qxaqLkmNxiZQ==} + + regjsgen@0.2.0: + resolution: {integrity: sha512-x+Y3yA24uF68m5GA+tBjbGYo64xXVJpbToBaWCoSNSc1hdk6dfctaRWrNFTVJZIIhL5GxW8zwjoixbnifnK59g==} + + regjsparser@0.1.5: + resolution: {integrity: sha512-jlQ9gYLfk2p3V5Ag5fYhA7fv7OHzd1KUH0PRP46xc3TgwjwgROIW572AfYg/X9kaNq/LJnu6oJcFRXlIrGoTRw==} + hasBin: true + + repeat-element@1.1.4: + resolution: {integrity: sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==} + engines: {node: '>=0.10.0'} + + repeat-string@1.6.1: + resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} + engines: {node: '>=0.10'} + + repeating@2.0.1: + resolution: {integrity: sha512-ZqtSMuVybkISo2OWvqvm7iHSWngvdaW3IpsT9/uP8v4gMi591LY6h35wdOfvQdWCKFWZWm2Y1Opp4kV7vQKT6A==} + engines: {node: '>=0.10.0'} + + req-cwd@2.0.0: + resolution: {integrity: sha512-ueoIoLo1OfB6b05COxAA9UpeoscNpYyM+BqYlA7H6LVF4hKGPXQQSSaD2YmvDVJMkk4UDpAHIeU1zG53IqjvlQ==} + engines: {node: '>=4'} + + req-from@2.0.0: + resolution: {integrity: sha512-LzTfEVDVQHBRfjOUMgNBA+V6DWsSnoeKzf42J7l0xa/B4jyPOuuF5MlNSmomLNGemWTnV2TIdjSSLnEn95fOQA==} + engines: {node: '>=4'} + + request@2.88.2: + resolution: {integrity: sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==} + engines: {node: '>= 6'} + deprecated: request has been deprecated, see https://github.com/request/request/issues/3142 + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-from-string@1.2.1: + resolution: {integrity: sha512-H7AkJWMobeskkttHyhTVtS0fxpFLjxhbfMa6Bk3wimP7sdPRGL3EyCg3sAQenFfAe+xQ+oAc85Nmtvq0ROM83Q==} + engines: {node: '>=0.10.0'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + require-main-filename@1.0.1: + resolution: {integrity: sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==} + + require-main-filename@2.0.0: + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + + resolve-alpn@1.2.1: + resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} + + resolve-from@3.0.0: + resolution: {integrity: sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==} + engines: {node: '>=4'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-url@0.2.1: + resolution: {integrity: sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==} + deprecated: https://github.com/lydell/resolve-url#deprecated + + resolve@1.1.7: + resolution: {integrity: sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==} + + resolve@1.17.0: + resolution: {integrity: sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==} + + resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + hasBin: true + + responselike@1.0.2: + resolution: {integrity: sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==} + + responselike@2.0.1: + resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==} + + restore-cursor@3.1.0: + resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} + engines: {node: '>=8'} + + ret@0.1.15: + resolution: {integrity: sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==} + engines: {node: '>=0.12'} + + reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rimraf@2.7.1: + resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} + hasBin: true + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + hasBin: true + + ripemd160-min@0.0.6: + resolution: {integrity: sha512-+GcJgQivhs6S9qvLogusiTcS9kQUfgR75whKuy5jIhuiOfQuJ8fjqxV6EGD5duH1Y/FawFUMtMhyeq3Fbnib8A==} + engines: {node: '>=8'} + + ripemd160@2.0.2: + resolution: {integrity: sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==} + + rlp@2.2.7: + resolution: {integrity: sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==} + hasBin: true + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + rust-verkle-wasm@0.0.1: + resolution: {integrity: sha512-BN6fiTsxcd2dCECz/cHtGTt9cdLJR925nh7iAuRcj8ymKw7OOaPmCneQZ7JePOJ/ia27TjEL91VdOi88Yf+mcA==} + + rustbn-wasm@0.2.0: + resolution: {integrity: sha512-FThvYFNTqrEKGqXuseeg0zR7yROh/6U1617mCHF68OVqrN1tNKRN7Tdwy4WayPVsCmmK+eMxtIZX1qL6JxTkMg==} + + rustbn.js@0.2.0: + resolution: {integrity: sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==} + + safe-array-concat@1.1.0: + resolution: {integrity: sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg==} + engines: {node: '>=0.4'} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safe-event-emitter@1.0.1: + resolution: {integrity: sha512-e1wFe99A91XYYxoQbcq2ZJUWurxEyP8vfz7A7vuUe1s95q8r5ebraVaA1BukYJcpM6V16ugWoD9vngi8Ccu5fg==} + deprecated: Renamed to @metamask/safe-event-emitter + + safe-regex-test@1.0.3: + resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} + engines: {node: '>= 0.4'} + + safe-regex@1.1.0: + resolution: {integrity: sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + sc-istanbul@0.4.6: + resolution: {integrity: sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g==} + hasBin: true + + scrypt-js@2.0.4: + resolution: {integrity: sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==} + + scrypt-js@3.0.1: + resolution: {integrity: sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==} + + scrypt@https://codeload.github.com/barrysteyn/node-scrypt/tar.gz/fb60a8d3c158fe115a624b5ffa7480f3a24b03fb: + resolution: {tarball: https://codeload.github.com/barrysteyn/node-scrypt/tar.gz/fb60a8d3c158fe115a624b5ffa7480f3a24b03fb} + version: 6.0.3 + engines: {node: '>= 0.10'} + + scryptsy@1.2.1: + resolution: {integrity: sha512-aldIRgMozSJ/Gl6K6qmJZysRP82lz83Wb42vl4PWN8SaLFHIaOzLPc9nUUW2jQN88CuGm5q5HefJ9jZ3nWSmTw==} + + secp256k1@4.0.3: + resolution: {integrity: sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==} + engines: {node: '>=10.0.0'} + + seedrandom@3.0.1: + resolution: {integrity: sha512-1/02Y/rUeU1CJBAGLebiC5Lbo5FnB22gQbIFFYTLkwvp1xdABZJH1sn4ZT1MzXmPpzv+Rf/Lu2NcsLJiK4rcDg==} + + semaphore@1.1.0: + resolution: {integrity: sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA==} + engines: {node: '>=0.8.0'} + + semver@5.4.1: + resolution: {integrity: sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==} + hasBin: true + + semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.6.0: + resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} + engines: {node: '>=10'} + hasBin: true + + send@0.18.0: + resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} + engines: {node: '>= 0.8.0'} + + sentence-case@2.1.1: + resolution: {integrity: sha512-ENl7cYHaK/Ktwk5OTD+aDbQ3uC8IByu/6Bkg+HDv8Mm+XnBnppVNalcfJTNsp1ibstKh030/JKQQWglDvtKwEQ==} + + serialize-javascript@6.0.0: + resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==} + + serve-static@1.15.0: + resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} + engines: {node: '>= 0.8.0'} + + servify@0.1.12: + resolution: {integrity: sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==} + engines: {node: '>=6'} + + set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + + set-function-length@1.2.1: + resolution: {integrity: sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + set-immediate-shim@1.0.1: + resolution: {integrity: sha512-Li5AOqrZWCVA2n5kryzEmqai6bKSIvpz5oUJHPVj6+dsbD3X1ixtsY5tEnsaNpH3pFAHmG8eIHUrtEtohrg+UQ==} + engines: {node: '>=0.10.0'} + + set-value@2.0.1: + resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==} + engines: {node: '>=0.10.0'} + + setimmediate@1.0.4: + resolution: {integrity: sha512-/TjEmXQVEzdod/FFskf3o7oOAsGhHf2j1dZqRFbDzq4F3mvvxflIIi4Hd3bLQE9y/CpwqfSQam5JakI/mi3Pog==} + + setimmediate@1.0.5: + resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + sha.js@2.4.11: + resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==} + hasBin: true + + sha1@1.1.1: + resolution: {integrity: sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==} + + sha3@2.1.4: + resolution: {integrity: sha512-S8cNxbyb0UGUM2VhRD4Poe5N58gJnJsLJ5vC7FYWGUmGhcsj4++WaIOBFVDxlG0W3To6xBuiRh+i0Qp2oNCOtg==} + + shebang-command@1.2.0: + resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} + engines: {node: '>=0.10.0'} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@1.0.0: + resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} + engines: {node: '>=0.10.0'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shelljs@0.8.5: + resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==} + engines: {node: '>=4'} + hasBin: true + + side-channel@1.0.5: + resolution: {integrity: sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==} + engines: {node: '>= 0.4'} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + simple-concat@1.0.1: + resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} + + simple-get@2.8.2: + resolution: {integrity: sha512-Ijd/rV5o+mSBBs4F/x9oDPtTx9Zb6X9brmnXvMW4J7IR15ngi9q5xxqWBKU744jTZiaXtxaPL7uHG6vtN8kUkw==} + + slash@1.0.0: + resolution: {integrity: sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg==} + engines: {node: '>=0.10.0'} + + slash@2.0.0: + resolution: {integrity: sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==} + engines: {node: '>=6'} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + slice-ansi@4.0.0: + resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} + engines: {node: '>=10'} + + snake-case@2.1.0: + resolution: {integrity: sha512-FMR5YoPFwOLuh4rRz92dywJjyKYZNLpMn1R5ujVpIYkbA9p01fq8RMg0FkO4M+Yobt4MjHeLTJVm5xFFBHSV2Q==} + + snapdragon-node@2.1.1: + resolution: {integrity: sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==} + engines: {node: '>=0.10.0'} + + snapdragon-util@3.0.1: + resolution: {integrity: sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==} + engines: {node: '>=0.10.0'} + + snapdragon@0.8.2: + resolution: {integrity: sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==} + engines: {node: '>=0.10.0'} + + solc@0.4.26: + resolution: {integrity: sha512-o+c6FpkiHd+HPjmjEVpQgH7fqZ14tJpXhho+/bQXlXbliLIS/xjXb42Vxh+qQY1WCSTMQ0+a5vR9vi0MfhU6mA==} + hasBin: true + + solc@0.6.12: + resolution: {integrity: sha512-Lm0Ql2G9Qc7yPP2Ba+WNmzw2jwsrd3u4PobHYlSOxaut3TtUbj9+5ZrT6f4DUpNPEoBaFUOEg9Op9C0mk7ge9g==} + engines: {node: '>=8.0.0'} + hasBin: true + + solc@0.7.3: + resolution: {integrity: sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==} + engines: {node: '>=8.0.0'} + hasBin: true + + solhint@3.4.1: + resolution: {integrity: sha512-pzZn2RlZhws1XwvLPVSsxfHrwsteFf5eySOhpAytzXwKQYbTCJV6z8EevYDiSVKMpWrvbKpEtJ055CuEmzp4Xg==} + hasBin: true + + solidity-coverage@0.8.3: + resolution: {integrity: sha512-hbcNgj5z8zzgTlnp4F0pXiqj1v5ua8P4DH5i9cWOBtFPfUuIohLoXu5WiAixexWmpKVjyxXqupnu/mPb4IGr7Q==} + hasBin: true + peerDependencies: + hardhat: ^2.11.0 + + source-map-resolve@0.5.3: + resolution: {integrity: sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==} + deprecated: See https://github.com/lydell/source-map-resolve#deprecated + + source-map-support@0.4.18: + resolution: {integrity: sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==} + + source-map-support@0.5.12: + resolution: {integrity: sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==} + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map-url@0.4.1: + resolution: {integrity: sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==} + deprecated: See https://github.com/lydell/source-map-url#deprecated + + source-map@0.2.0: + resolution: {integrity: sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA==} + engines: {node: '>=0.8.0'} + + source-map@0.5.7: + resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} + engines: {node: '>=0.10.0'} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + + spdx-exceptions@2.5.0: + resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} + + spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + + spdx-license-ids@3.0.17: + resolution: {integrity: sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==} + + split-string@3.1.0: + resolution: {integrity: sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==} + engines: {node: '>=0.10.0'} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + sshpk@1.18.0: + resolution: {integrity: sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==} + engines: {node: '>=0.10.0'} + hasBin: true + + stacktrace-parser@0.1.10: + resolution: {integrity: sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==} + engines: {node: '>=6'} + + static-extend@0.1.2: + resolution: {integrity: sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==} + engines: {node: '>=0.10.0'} + + statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + + stream-to-pull-stream@1.7.3: + resolution: {integrity: sha512-6sNyqJpr5dIOQdgNy/xcDWwDuzAsAwVzhzrWlAPAQ7Lkjx/rv0wgvxEyKwTq6FmNd5rjTrELt/CLmaSw7crMGg==} + + strict-uri-encode@1.1.0: + resolution: {integrity: sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==} + engines: {node: '>=0.10.0'} + + string-format@2.0.0: + resolution: {integrity: sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA==} + + string-width@1.0.2: + resolution: {integrity: sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==} + engines: {node: '>=0.10.0'} + + string-width@2.1.1: + resolution: {integrity: sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==} + engines: {node: '>=4'} + + string-width@3.1.0: + resolution: {integrity: sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==} + engines: {node: '>=6'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string.prototype.trim@1.2.8: + resolution: {integrity: sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.7: + resolution: {integrity: sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==} + + string.prototype.trimstart@1.0.7: + resolution: {integrity: sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==} + + string_decoder@0.10.31: + resolution: {integrity: sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + strip-ansi@3.0.1: + resolution: {integrity: sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==} + engines: {node: '>=0.10.0'} + + strip-ansi@4.0.0: + resolution: {integrity: sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==} + engines: {node: '>=4'} + + strip-ansi@5.2.0: + resolution: {integrity: sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==} + engines: {node: '>=6'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-bom@2.0.0: + resolution: {integrity: sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==} + engines: {node: '>=0.10.0'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-hex-prefix@1.0.0: + resolution: {integrity: sha1-DF8VX+8RUTczd96du1iNoFUA428=} + engines: {node: '>=6.5.0', npm: '>=3'} + + strip-indent@2.0.0: + resolution: {integrity: sha512-RsSNPLpq6YUL7QYy44RnPVTn/lcVZtb48Uof3X5JLbF4zD/Gs7ZFDv2HWol+leoQN2mT86LAzSshGfkTlSOpsA==} + engines: {node: '>=4'} + + strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + supports-color@2.0.0: + resolution: {integrity: sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==} + engines: {node: '>=0.8.0'} + + supports-color@3.2.3: + resolution: {integrity: sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==} + engines: {node: '>=0.8.0'} + + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + + supports-color@6.0.0: + resolution: {integrity: sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==} + engines: {node: '>=6'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + swap-case@1.1.2: + resolution: {integrity: sha512-BAmWG6/bx8syfc6qXPprof3Mn5vQgf5dwdUNJhsNqU9WdPt5P+ES/wQ5bxfijy8zwZgZZHslC3iAsxsuQMCzJQ==} + + swarm-js@0.1.42: + resolution: {integrity: sha512-BV7c/dVlA3R6ya1lMlSSNPLYrntt0LUq4YMgy3iwpCIc6rZnS5W2wUoctarZ5pXlpKtxDDf9hNziEkcfrxdhqQ==} + + sync-request@6.1.0: + resolution: {integrity: sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==} + engines: {node: '>=8.0.0'} + + sync-rpc@1.3.6: + resolution: {integrity: sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==} + + table-layout@1.0.2: + resolution: {integrity: sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==} + engines: {node: '>=8.0.0'} + + table@6.8.1: + resolution: {integrity: sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==} + engines: {node: '>=10.0.0'} + + tape@4.17.0: + resolution: {integrity: sha512-KCuXjYxCZ3ru40dmND+oCLsXyuA8hoseu2SS404Px5ouyS0A99v8X/mdiLqsR5MTAyamMBN7PRwt2Dv3+xGIxw==} + hasBin: true + + tar@4.4.19: + resolution: {integrity: sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==} + engines: {node: '>=4.5'} + + test-value@2.1.0: + resolution: {integrity: sha512-+1epbAxtKeXttkGFMTX9H42oqzOTufR1ceCF+GYA5aOmvaPq9wd4PUS8329fn2RRLGNeUkgRLnVpycjx8DsO2w==} + engines: {node: '>=0.10.0'} + + testrpc@0.0.1: + resolution: {integrity: sha512-afH1hO+SQ/VPlmaLUFj2636QMeDvPCeQMc/9RBMW0IfjNe9gFD9Ra3ShqYkB7py0do1ZcCna/9acHyzTJ+GcNA==} + deprecated: testrpc has been renamed to ganache-cli, please use this package from now on. + + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + + then-request@6.0.2: + resolution: {integrity: sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==} + engines: {node: '>=6.0.0'} + + threads@1.7.0: + resolution: {integrity: sha512-Mx5NBSHX3sQYR6iI9VYbgHKBLisyB+xROCBGjjWm1O9wb9vfLxdaGtmT/KCjUqMsSNW6nERzCW3T6H43LqjDZQ==} + + through2@2.0.5: + resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} + + timed-out@4.0.1: + resolution: {integrity: sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==} + engines: {node: '>=0.10.0'} + + tiny-worker@2.3.0: + resolution: {integrity: sha512-pJ70wq5EAqTAEl9IkGzA+fN0836rycEuz2Cn6yeZ6FRzlVS5IDOkFHpIoEsksPRQV34GDqXm65+OlnZqUSyK2g==} + + title-case@2.1.1: + resolution: {integrity: sha512-EkJoZ2O3zdCz3zJsYCsxyq2OC5hrxR9mfdd5I+w8h/tmFfeOxJ+vvkxsKxdmN0WtS9zLdHEgfgVOiMVgv+Po4Q==} + + tmp@0.0.33: + resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} + engines: {node: '>=0.6.0'} + + tmp@0.1.0: + resolution: {integrity: sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw==} + engines: {node: '>=6'} + + to-fast-properties@1.0.3: + resolution: {integrity: sha512-lxrWP8ejsq+7E3nNjwYmUBMAgjMTZoTI+sdBOpvNyijeDLa29LUn9QaoXAHv4+Z578hbmHHJKZknzxVtvo77og==} + engines: {node: '>=0.10.0'} + + to-object-path@0.3.0: + resolution: {integrity: sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==} + engines: {node: '>=0.10.0'} + + to-readable-stream@1.0.0: + resolution: {integrity: sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==} + engines: {node: '>=6'} + + to-regex-range@2.1.1: + resolution: {integrity: sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==} + engines: {node: '>=0.10.0'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + to-regex@3.0.2: + resolution: {integrity: sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==} + engines: {node: '>=0.10.0'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + tough-cookie@2.5.0: + resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==} + engines: {node: '>=0.8'} + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + trim-right@1.0.1: + resolution: {integrity: sha512-WZGXGstmCWgeevgTL54hrCuw1dyMQIzWy7ZfqRJfSmJZBwklI15egmQytFP6bPidmw3M8d5yEowl1niq4vmqZw==} + engines: {node: '>=0.10.0'} + + ts-command-line-args@2.5.1: + resolution: {integrity: sha512-H69ZwTw3rFHb5WYpQya40YAX2/w7Ut75uUECbgBIsLmM+BNuYnxsltfyyLMxy6sEeKxgijLTnQtLd0nKd6+IYw==} + hasBin: true + + ts-essentials@1.0.4: + resolution: {integrity: sha512-q3N1xS4vZpRouhYHDPwO0bDW3EZ6SK9CrrDHxi/D6BPReSjpVgWIOpLS2o0gSBZm+7q/wyKp6RVM1AeeW7uyfQ==} + + ts-essentials@6.0.7: + resolution: {integrity: sha512-2E4HIIj4tQJlIHuATRHayv0EfMGK3ris/GRk1E3CFnsZzeNV+hUmelbaTZHLtXaZppM5oLhHRtO04gINC4Jusw==} + peerDependencies: + typescript: '>=3.7.0' + + ts-essentials@7.0.3: + resolution: {integrity: sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==} + peerDependencies: + typescript: '>=3.7.0' + + ts-generator@0.1.1: + resolution: {integrity: sha512-N+ahhZxTLYu1HNTQetwWcx3so8hcYbkKBHTr4b4/YgObFTIKkOSSsaa+nal12w8mfrJAyzJfETXawbNjSfP2gQ==} + hasBin: true + + ts-node@10.9.1: + resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + + tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + + tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + + tslib@2.4.0: + resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} + + tsort@0.0.1: + resolution: {integrity: sha1-4igPXoF/i/QnVlf9D5rr1E9aJ4Y=} + + tsutils@3.21.0: + resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} + engines: {node: '>= 6'} + peerDependencies: + typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' + + tunnel-agent@0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + + tweetnacl-util@0.15.1: + resolution: {integrity: sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==} + + tweetnacl@0.14.5: + resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} + + tweetnacl@1.0.3: + resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==} + + type-check@0.3.2: + resolution: {integrity: sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==} + engines: {node: '>= 0.8.0'} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + + type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + + type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + + type-fest@0.7.1: + resolution: {integrity: sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==} + engines: {node: '>=8'} + + type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + + type@1.2.0: + resolution: {integrity: sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==} + + type@2.7.2: + resolution: {integrity: sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==} + + typechain@3.0.0: + resolution: {integrity: sha512-ft4KVmiN3zH4JUFu2WJBrwfHeDf772Tt2d8bssDTo/YcckKW2D+OwFrHXRC6hJvO3mHjFQTihoMV6fJOi0Hngg==} + hasBin: true + + typechain@8.3.2: + resolution: {integrity: sha512-x/sQYr5w9K7yv3es7jo4KTX05CLxOf7TRWwoHlrjRh8H82G64g+k7VuWPJlgMo6qrjfCulOdfBjiaDtmhFYD/Q==} + hasBin: true + peerDependencies: + typescript: '>=4.3.0' + + typed-array-buffer@1.0.2: + resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.1: + resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.2: + resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.5: + resolution: {integrity: sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==} + engines: {node: '>= 0.4'} + + typedarray-to-buffer@3.1.5: + resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} + + typedarray@0.0.6: + resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} + + typescript@4.7.4: + resolution: {integrity: sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==} + engines: {node: '>=4.2.0'} + hasBin: true + + typewise-core@1.2.0: + resolution: {integrity: sha512-2SCC/WLzj2SbUwzFOzqMCkz5amXLlxtJqDKTICqg30x+2DZxcfZN2MvQZmGfXWKNWaKK9pBPsvkcwv8bF/gxKg==} + + typewise@1.0.3: + resolution: {integrity: sha512-aXofE06xGhaQSPzt8hlTY+/YWQhm9P0jYUp1f2XtmW/3Bk0qzXcyFWAtPoo2uTGQj1ZwbDuSyuxicq+aDo8lCQ==} + + typewiselite@1.0.0: + resolution: {integrity: sha512-J9alhjVHupW3Wfz6qFRGgQw0N3gr8hOkw6zm7FZ6UR1Cse/oD9/JVok7DNE9TT9IbciDHX2Ex9+ksE6cRmtymw==} + + typical@2.6.1: + resolution: {integrity: sha512-ofhi8kjIje6npGozTip9Fr8iecmYfEbS06i0JnIg+rh51KakryWF4+jX8lLKZVhy6N+ID45WYSFCxPOdTWCzNg==} + + typical@4.0.0: + resolution: {integrity: sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==} + engines: {node: '>=8'} + + typical@5.2.0: + resolution: {integrity: sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==} + engines: {node: '>=8'} + + uglify-js@3.17.4: + resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==} + engines: {node: '>=0.8.0'} + hasBin: true + + ultron@1.1.1: + resolution: {integrity: sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==} + + unbox-primitive@1.0.2: + resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + + underscore@1.13.6: + resolution: {integrity: sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==} + + underscore@1.9.1: + resolution: {integrity: sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==} + + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + + undici@5.28.3: + resolution: {integrity: sha512-3ItfzbrhDlINjaP0duwnNsKpDQk3acHI3gVJ1z4fmwMK31k5G9OVIAMLSIaP6w4FaGkaAkN6zaQO9LUvZ1t7VA==} + engines: {node: '>=14.0'} + + union-value@1.0.1: + resolution: {integrity: sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==} + engines: {node: '>=0.10.0'} + + universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + unorm@1.6.0: + resolution: {integrity: sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==} + engines: {node: '>= 0.4.0'} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + unset-value@1.0.0: + resolution: {integrity: sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==} + engines: {node: '>=0.10.0'} + + upper-case-first@1.1.2: + resolution: {integrity: sha512-wINKYvI3Db8dtjikdAqoBbZoP6Q+PZUyfMR7pmwHzjC2quzSkUq5DmPrTtPEqHaz8AGtmsB4TqwapMTM1QAQOQ==} + + upper-case@1.1.3: + resolution: {integrity: sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + urix@0.1.0: + resolution: {integrity: sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==} + deprecated: Please see https://github.com/lydell/urix#deprecated + + url-parse-lax@3.0.0: + resolution: {integrity: sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==} + engines: {node: '>=4'} + + url-set-query@1.0.0: + resolution: {integrity: sha512-3AChu4NiXquPfeckE5R5cGdiHCMWJx1dwCWOmWIL4KHAziJNOFIYJlpGFeKDvwLPHovZRCxK3cYlwzqI9Vp+Gg==} + + url@0.11.3: + resolution: {integrity: sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==} + + use@3.1.1: + resolution: {integrity: sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==} + engines: {node: '>=0.10.0'} + + utf-8-validate@5.0.10: + resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} + engines: {node: '>=6.14.2'} + + utf8@3.0.0: + resolution: {integrity: sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + util.promisify@1.1.2: + resolution: {integrity: sha512-PBdZ03m1kBnQ5cjjO0ZvJMJS+QsbyIcFwi4hY4U76OQsCO9JrOYjbCFgIF76ccFg9xnJo7ZHPkqyj1GqmdS7MA==} + + util@0.12.5: + resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} + + utils-merge@1.0.1: + resolution: {integrity: sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=} + engines: {node: '>= 0.4.0'} + + uuid@2.0.1: + resolution: {integrity: sha512-nWg9+Oa3qD2CQzHIP4qKUqwNfzKn8P0LtFhotaCTFchsV7ZfDhAybeip/HZVeMIpZi9JgY1E3nUlwaCmZT1sEg==} + deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. + + uuid@3.3.2: + resolution: {integrity: sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==} + deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. + hasBin: true + + uuid@3.4.0: + resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} + deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. + hasBin: true + + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + + uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + + v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + + v8-compile-cache@2.4.0: + resolution: {integrity: sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==} + + validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + + varint@5.0.2: + resolution: {integrity: sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==} + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + verror@1.10.0: + resolution: {integrity: sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=} + engines: {'0': node >=0.6.0} + + wcwidth@1.0.1: + resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + + web3-bzz@1.10.0: + resolution: {integrity: sha512-o9IR59io3pDUsXTsps5pO5hW1D5zBmg46iNc2t4j2DkaYHNdDLwk2IP9ukoM2wg47QILfPEJYzhTfkS/CcX0KA==} + engines: {node: '>=8.0.0'} + + web3-bzz@1.10.4: + resolution: {integrity: sha512-ZZ/X4sJ0Uh2teU9lAGNS8EjveEppoHNQiKlOXAjedsrdWuaMErBPdLQjXfcrYvN6WM6Su9PMsAxf3FXXZ+HwQw==} + engines: {node: '>=8.0.0'} + + web3-bzz@1.2.11: + resolution: {integrity: sha512-XGpWUEElGypBjeFyUhTkiPXFbDVD6Nr/S5jznE3t8cWUA0FxRf1n3n/NuIZeb0H9RkN2Ctd/jNma/k8XGa3YKg==} + engines: {node: '>=8.0.0'} + + web3-core-helpers@1.10.0: + resolution: {integrity: sha512-pIxAzFDS5vnbXvfvLSpaA1tfRykAe9adw43YCKsEYQwH0gCLL0kMLkaCX3q+Q8EVmAh+e1jWL/nl9U0de1+++g==} + engines: {node: '>=8.0.0'} + + web3-core-helpers@1.10.4: + resolution: {integrity: sha512-r+L5ylA17JlD1vwS8rjhWr0qg7zVoVMDvWhajWA5r5+USdh91jRUYosp19Kd1m2vE034v7Dfqe1xYRoH2zvG0g==} + engines: {node: '>=8.0.0'} + + web3-core-helpers@1.2.11: + resolution: {integrity: sha512-PEPoAoZd5ME7UfbnCZBdzIerpe74GEvlwT4AjOmHeCVZoIFk7EqvOZDejJHt+feJA6kMVTdd0xzRNN295UhC1A==} + engines: {node: '>=8.0.0'} + + web3-core-method@1.10.0: + resolution: {integrity: sha512-4R700jTLAMKDMhQ+nsVfIXvH6IGJlJzGisIfMKWAIswH31h5AZz7uDUW2YctI+HrYd+5uOAlS4OJeeT9bIpvkA==} + engines: {node: '>=8.0.0'} + + web3-core-method@1.10.4: + resolution: {integrity: sha512-uZTb7flr+Xl6LaDsyTeE2L1TylokCJwTDrIVfIfnrGmnwLc6bmTWCCrm71sSrQ0hqs6vp/MKbQYIYqUN0J8WyA==} + engines: {node: '>=8.0.0'} + + web3-core-method@1.2.11: + resolution: {integrity: sha512-ff0q76Cde94HAxLDZ6DbdmKniYCQVtvuaYh+rtOUMB6kssa5FX0q3vPmixi7NPooFnbKmmZCM6NvXg4IreTPIw==} + engines: {node: '>=8.0.0'} + + web3-core-promievent@1.10.0: + resolution: {integrity: sha512-68N7k5LWL5R38xRaKFrTFT2pm2jBNFaM4GioS00YjAKXRQ3KjmhijOMG3TICz6Aa5+6GDWYelDNx21YAeZ4YTg==} + engines: {node: '>=8.0.0'} + + web3-core-promievent@1.10.4: + resolution: {integrity: sha512-2de5WnJQ72YcIhYwV/jHLc4/cWJnznuoGTJGD29ncFQHAfwW/MItHFSVKPPA5v8AhJe+r6y4Y12EKvZKjQVBvQ==} + engines: {node: '>=8.0.0'} + + web3-core-promievent@1.2.11: + resolution: {integrity: sha512-il4McoDa/Ox9Agh4kyfQ8Ak/9ABYpnF8poBLL33R/EnxLsJOGQG2nZhkJa3I067hocrPSjEdlPt/0bHXsln4qA==} + engines: {node: '>=8.0.0'} + + web3-core-requestmanager@1.10.0: + resolution: {integrity: sha512-3z/JKE++Os62APml4dvBM+GAuId4h3L9ckUrj7ebEtS2AR0ixyQPbrBodgL91Sv7j7cQ3Y+hllaluqjguxvSaQ==} + engines: {node: '>=8.0.0'} + + web3-core-requestmanager@1.10.4: + resolution: {integrity: sha512-vqP6pKH8RrhT/2MoaU+DY/OsYK9h7HmEBNCdoMj+4ZwujQtw/Mq2JifjwsJ7gits7Q+HWJwx8q6WmQoVZAWugg==} + engines: {node: '>=8.0.0'} + + web3-core-requestmanager@1.2.11: + resolution: {integrity: sha512-oFhBtLfOiIbmfl6T6gYjjj9igOvtyxJ+fjS+byRxiwFJyJ5BQOz4/9/17gWR1Cq74paTlI7vDGxYfuvfE/mKvA==} + engines: {node: '>=8.0.0'} + + web3-core-subscriptions@1.10.0: + resolution: {integrity: sha512-HGm1PbDqsxejI075gxBc5OSkwymilRWZufIy9zEpnWKNmfbuv5FfHgW1/chtJP6aP3Uq2vHkvTDl3smQBb8l+g==} + engines: {node: '>=8.0.0'} + + web3-core-subscriptions@1.10.4: + resolution: {integrity: sha512-o0lSQo/N/f7/L76C0HV63+S54loXiE9fUPfHFcTtpJRQNDBVsSDdWRdePbWwR206XlsBqD5VHApck1//jEafTw==} + engines: {node: '>=8.0.0'} + + web3-core-subscriptions@1.2.11: + resolution: {integrity: sha512-qEF/OVqkCvQ7MPs1JylIZCZkin0aKK9lDxpAtQ1F8niEDGFqn7DT8E/vzbIa0GsOjL2fZjDhWJsaW+BSoAW1gg==} + engines: {node: '>=8.0.0'} + + web3-core@1.10.0: + resolution: {integrity: sha512-fWySwqy2hn3TL89w5TM8wXF1Z2Q6frQTKHWmP0ppRQorEK8NcHJRfeMiv/mQlSKoTS1F6n/nv2uyZsixFycjYQ==} + engines: {node: '>=8.0.0'} + + web3-core@1.10.4: + resolution: {integrity: sha512-B6elffYm81MYZDTrat7aEhnhdtVE3lDBUZft16Z8awYMZYJDbnykEbJVS+l3mnA7AQTnSDr/1MjWofGDLBJPww==} + engines: {node: '>=8.0.0'} + + web3-core@1.2.11: + resolution: {integrity: sha512-CN7MEYOY5ryo5iVleIWRE3a3cZqVaLlIbIzDPsvQRUfzYnvzZQRZBm9Mq+ttDi2STOOzc1MKylspz/o3yq/LjQ==} + engines: {node: '>=8.0.0'} + + web3-eth-abi@1.10.0: + resolution: {integrity: sha512-cwS+qRBWpJ43aI9L3JS88QYPfFcSJJ3XapxOQ4j40v6mk7ATpA8CVK1vGTzpihNlOfMVRBkR95oAj7oL6aiDOg==} + engines: {node: '>=8.0.0'} + + web3-eth-abi@1.10.4: + resolution: {integrity: sha512-cZ0q65eJIkd/jyOlQPDjr8X4fU6CRL1eWgdLwbWEpo++MPU/2P4PFk5ZLAdye9T5Sdp+MomePPJ/gHjLMj2VfQ==} + engines: {node: '>=8.0.0'} + + web3-eth-abi@1.2.11: + resolution: {integrity: sha512-PkRYc0+MjuLSgg03QVWqWlQivJqRwKItKtEpRUaxUAeLE7i/uU39gmzm2keHGcQXo3POXAbOnMqkDvOep89Crg==} + engines: {node: '>=8.0.0'} + + web3-eth-accounts@1.10.0: + resolution: {integrity: sha512-wiq39Uc3mOI8rw24wE2n15hboLE0E9BsQLdlmsL4Zua9diDS6B5abXG0XhFcoNsXIGMWXVZz4TOq3u4EdpXF/Q==} + engines: {node: '>=8.0.0'} + + web3-eth-accounts@1.10.4: + resolution: {integrity: sha512-ysy5sVTg9snYS7tJjxVoQAH6DTOTkRGR8emEVCWNGLGiB9txj+qDvSeT0izjurS/g7D5xlMAgrEHLK1Vi6I3yg==} + engines: {node: '>=8.0.0'} + + web3-eth-accounts@1.2.11: + resolution: {integrity: sha512-6FwPqEpCfKIh3nSSGeo3uBm2iFSnFJDfwL3oS9pyegRBXNsGRVpgiW63yhNzL0796StsvjHWwQnQHsZNxWAkGw==} + engines: {node: '>=8.0.0'} + + web3-eth-contract@1.10.0: + resolution: {integrity: sha512-MIC5FOzP/+2evDksQQ/dpcXhSqa/2hFNytdl/x61IeWxhh6vlFeSjq0YVTAyIzdjwnL7nEmZpjfI6y6/Ufhy7w==} + engines: {node: '>=8.0.0'} + + web3-eth-contract@1.10.4: + resolution: {integrity: sha512-Q8PfolOJ4eV9TvnTj1TGdZ4RarpSLmHnUnzVxZ/6/NiTfe4maJz99R0ISgwZkntLhLRtw0C7LRJuklzGYCNN3A==} + engines: {node: '>=8.0.0'} + + web3-eth-contract@1.2.11: + resolution: {integrity: sha512-MzYuI/Rq2o6gn7vCGcnQgco63isPNK5lMAan2E51AJLknjSLnOxwNY3gM8BcKoy4Z+v5Dv00a03Xuk78JowFow==} + engines: {node: '>=8.0.0'} + + web3-eth-ens@1.10.0: + resolution: {integrity: sha512-3hpGgzX3qjgxNAmqdrC2YUQMTfnZbs4GeLEmy8aCWziVwogbuqQZ+Gzdfrym45eOZodk+lmXyLuAdqkNlvkc1g==} + engines: {node: '>=8.0.0'} + + web3-eth-ens@1.10.4: + resolution: {integrity: sha512-LLrvxuFeVooRVZ9e5T6OWKVflHPFgrVjJ/jtisRWcmI7KN/b64+D/wJzXqgmp6CNsMQcE7rpmf4CQmJCrTdsgg==} + engines: {node: '>=8.0.0'} + + web3-eth-ens@1.2.11: + resolution: {integrity: sha512-dbW7dXP6HqT1EAPvnniZVnmw6TmQEKF6/1KgAxbo8iBBYrVTMDGFQUUnZ+C4VETGrwwaqtX4L9d/FrQhZ6SUiA==} + engines: {node: '>=8.0.0'} + + web3-eth-iban@1.10.0: + resolution: {integrity: sha512-0l+SP3IGhInw7Q20LY3IVafYEuufo4Dn75jAHT7c2aDJsIolvf2Lc6ugHkBajlwUneGfbRQs/ccYPQ9JeMUbrg==} + engines: {node: '>=8.0.0'} + + web3-eth-iban@1.10.4: + resolution: {integrity: sha512-0gE5iNmOkmtBmbKH2aTodeompnNE8jEyvwFJ6s/AF6jkw9ky9Op9cqfzS56AYAbrqEFuClsqB/AoRves7LDELw==} + engines: {node: '>=8.0.0'} + + web3-eth-iban@1.2.11: + resolution: {integrity: sha512-ozuVlZ5jwFC2hJY4+fH9pIcuH1xP0HEFhtWsR69u9uDIANHLPQQtWYmdj7xQ3p2YT4bQLq/axKhZi7EZVetmxQ==} + engines: {node: '>=8.0.0'} + + web3-eth-personal@1.10.0: + resolution: {integrity: sha512-anseKn98w/d703eWq52uNuZi7GhQeVjTC5/svrBWEKob0WZ5kPdo+EZoFN0sp5a5ubbrk/E0xSl1/M5yORMtpg==} + engines: {node: '>=8.0.0'} + + web3-eth-personal@1.10.4: + resolution: {integrity: sha512-BRa/hs6jU1hKHz+AC/YkM71RP3f0Yci1dPk4paOic53R4ZZG4MgwKRkJhgt3/GPuPliwS46f/i5A7fEGBT4F9w==} + engines: {node: '>=8.0.0'} + + web3-eth-personal@1.2.11: + resolution: {integrity: sha512-42IzUtKq9iHZ8K9VN0vAI50iSU9tOA1V7XU2BhF/tb7We2iKBVdkley2fg26TxlOcKNEHm7o6HRtiiFsVK4Ifw==} + engines: {node: '>=8.0.0'} + + web3-eth@1.10.0: + resolution: {integrity: sha512-Z5vT6slNMLPKuwRyKGbqeGYC87OAy8bOblaqRTgg94CXcn/mmqU7iPIlG4506YdcdK3x6cfEDG7B6w+jRxypKA==} + engines: {node: '>=8.0.0'} + + web3-eth@1.10.4: + resolution: {integrity: sha512-Sql2kYKmgt+T/cgvg7b9ce24uLS7xbFrxE4kuuor1zSCGrjhTJ5rRNG8gTJUkAJGKJc7KgnWmgW+cOfMBPUDSA==} + engines: {node: '>=8.0.0'} + + web3-eth@1.2.11: + resolution: {integrity: sha512-REvxW1wJ58AgHPcXPJOL49d1K/dPmuw4LjPLBPStOVkQjzDTVmJEIsiLwn2YeuNDd4pfakBwT8L3bz1G1/wVsQ==} + engines: {node: '>=8.0.0'} + + web3-net@1.10.0: + resolution: {integrity: sha512-NLH/N3IshYWASpxk4/18Ge6n60GEvWBVeM8inx2dmZJVmRI6SJIlUxbL8jySgiTn3MMZlhbdvrGo8fpUW7a1GA==} + engines: {node: '>=8.0.0'} + + web3-net@1.10.4: + resolution: {integrity: sha512-mKINnhOOnZ4koA+yV2OT5s5ztVjIx7IY9a03w6s+yao/BUn+Luuty0/keNemZxTr1E8Ehvtn28vbOtW7Ids+Ow==} + engines: {node: '>=8.0.0'} + + web3-net@1.2.11: + resolution: {integrity: sha512-sjrSDj0pTfZouR5BSTItCuZ5K/oZPVdVciPQ6981PPPIwJJkCMeVjD7I4zO3qDPCnBjBSbWvVnLdwqUBPtHxyg==} + engines: {node: '>=8.0.0'} + + web3-provider-engine@14.2.1: + resolution: {integrity: sha512-iSv31h2qXkr9vrL6UZDm4leZMc32SjWJFGOp/D92JXfcEboCqraZyuExDkpxKw8ziTufXieNM7LSXNHzszYdJw==} + + web3-providers-http@1.10.0: + resolution: {integrity: sha512-eNr965YB8a9mLiNrkjAWNAPXgmQWfpBfkkn7tpEFlghfww0u3I0tktMZiaToJVcL2+Xq+81cxbkpeWJ5XQDwOA==} + engines: {node: '>=8.0.0'} + + web3-providers-http@1.10.4: + resolution: {integrity: sha512-m2P5Idc8hdiO0l60O6DSCPw0kw64Zgi0pMjbEFRmxKIck2Py57RQMu4bxvkxJwkF06SlGaEQF8rFZBmuX7aagQ==} + engines: {node: '>=8.0.0'} + + web3-providers-http@1.2.11: + resolution: {integrity: sha512-psh4hYGb1+ijWywfwpB2cvvOIMISlR44F/rJtYkRmQ5jMvG4FOCPlQJPiHQZo+2cc3HbktvvSJzIhkWQJdmvrA==} + engines: {node: '>=8.0.0'} + + web3-providers-ipc@1.10.0: + resolution: {integrity: sha512-OfXG1aWN8L1OUqppshzq8YISkWrYHaATW9H8eh0p89TlWMc1KZOL9vttBuaBEi96D/n0eYDn2trzt22bqHWfXA==} + engines: {node: '>=8.0.0'} + + web3-providers-ipc@1.10.4: + resolution: {integrity: sha512-YRF/bpQk9z3WwjT+A6FI/GmWRCASgd+gC0si7f9zbBWLXjwzYAKG73bQBaFRAHex1hl4CVcM5WUMaQXf3Opeuw==} + engines: {node: '>=8.0.0'} + + web3-providers-ipc@1.2.11: + resolution: {integrity: sha512-yhc7Y/k8hBV/KlELxynWjJDzmgDEDjIjBzXK+e0rHBsYEhdCNdIH5Psa456c+l0qTEU2YzycF8VAjYpWfPnBpQ==} + engines: {node: '>=8.0.0'} + + web3-providers-ws@1.10.0: + resolution: {integrity: sha512-sK0fNcglW36yD5xjnjtSGBnEtf59cbw4vZzJ+CmOWIKGIR96mP5l684g0WD0Eo+f4NQc2anWWXG74lRc9OVMCQ==} + engines: {node: '>=8.0.0'} + + web3-providers-ws@1.10.4: + resolution: {integrity: sha512-j3FBMifyuFFmUIPVQR4pj+t5ILhAexAui0opgcpu9R5LxQrLRUZxHSnU+YO25UycSOa/NAX8A+qkqZNpcFAlxA==} + engines: {node: '>=8.0.0'} + + web3-providers-ws@1.2.11: + resolution: {integrity: sha512-ZxnjIY1Er8Ty+cE4migzr43zA/+72AF1myzsLaU5eVgdsfV7Jqx7Dix1hbevNZDKFlSoEyq/3j/jYalh3So1Zg==} + engines: {node: '>=8.0.0'} + + web3-shh@1.10.0: + resolution: {integrity: sha512-uNUUuNsO2AjX41GJARV9zJibs11eq6HtOe6Wr0FtRUcj8SN6nHeYIzwstAvJ4fXA53gRqFMTxdntHEt9aXVjpg==} + engines: {node: '>=8.0.0'} + + web3-shh@1.10.4: + resolution: {integrity: sha512-cOH6iFFM71lCNwSQrC3niqDXagMqrdfFW85hC9PFUrAr3PUrIem8TNstTc3xna2bwZeWG6OBy99xSIhBvyIACw==} + engines: {node: '>=8.0.0'} + + web3-shh@1.2.11: + resolution: {integrity: sha512-B3OrO3oG1L+bv3E1sTwCx66injW1A8hhwpknDUbV+sw3fehFazA06z9SGXUefuFI1kVs4q2vRi0n4oCcI4dZDg==} + engines: {node: '>=8.0.0'} + + web3-utils@1.10.0: + resolution: {integrity: sha512-kSaCM0uMcZTNUSmn5vMEhlo02RObGNRRCkdX0V9UTAU0+lrvn0HSaudyCo6CQzuXUsnuY2ERJGCGPfeWmv19Rg==} + engines: {node: '>=8.0.0'} + + web3-utils@1.10.4: + resolution: {integrity: sha512-tsu8FiKJLk2PzhDl9fXbGUWTkkVXYhtTA+SmEFkKft+9BgwLxfCRpU96sWv7ICC8zixBNd3JURVoiR3dUXgP8A==} + engines: {node: '>=8.0.0'} + + web3-utils@1.2.11: + resolution: {integrity: sha512-3Tq09izhD+ThqHEaWYX4VOT7dNPdZiO+c/1QMA0s5X2lDFKK/xHJb7cyTRRVzN2LvlHbR7baS1tmQhSua51TcQ==} + engines: {node: '>=8.0.0'} + + web3@1.10.0: + resolution: {integrity: sha512-YfKY9wSkGcM8seO+daR89oVTcbu18NsVfvOngzqMYGUU0pPSQmE57qQDvQzUeoIOHAnXEBNzrhjQJmm8ER0rng==} + engines: {node: '>=8.0.0'} + + web3@1.10.4: + resolution: {integrity: sha512-kgJvQZjkmjOEKimx/tJQsqWfRDPTTcBfYPa9XletxuHLpHcXdx67w8EFn5AW3eVxCutE9dTVHgGa9VYe8vgsEA==} + engines: {node: '>=8.0.0'} + + web3@1.2.11: + resolution: {integrity: sha512-mjQ8HeU41G6hgOYm1pmeH0mRAeNKJGnJEUzDMoerkpw7QUQT4exVREgF1MYPvL/z6vAshOXei25LE/t/Bxl8yQ==} + engines: {node: '>=8.0.0'} + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + websocket@1.0.32: + resolution: {integrity: sha512-i4yhcllSP4wrpoPMU2N0TQ/q0O94LRG/eUQjEAamRltjQ1oT1PFFKOG4i877OlJgCG8rw6LrrowJp+TYCEWF7Q==} + engines: {node: '>=4.0.0'} + + websocket@1.0.34: + resolution: {integrity: sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==} + engines: {node: '>=4.0.0'} + + whatwg-fetch@2.0.4: + resolution: {integrity: sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + which-boxed-primitive@1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + + which-module@1.0.0: + resolution: {integrity: sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ==} + + which-module@2.0.1: + resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} + + which-typed-array@1.1.14: + resolution: {integrity: sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==} + engines: {node: '>= 0.4'} + + which@1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + wide-align@1.1.3: + resolution: {integrity: sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==} + + widest-line@3.1.0: + resolution: {integrity: sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==} + engines: {node: '>=8'} + + window-size@0.2.0: + resolution: {integrity: sha512-UD7d8HFA2+PZsbKyaOCEy8gMh1oDtHgJh1LfgjQ4zVXmYjAT/kvz3PueITKuqDiIXQe7yzpPnxX3lNc+AhQMyw==} + engines: {node: '>= 0.10.0'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wordwrap@1.0.0: + resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} + + wordwrapjs@4.0.1: + resolution: {integrity: sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==} + engines: {node: '>=8.0.0'} + + workerpool@6.2.1: + resolution: {integrity: sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==} + + wrap-ansi@2.1.0: + resolution: {integrity: sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==} + engines: {node: '>=0.10.0'} + + wrap-ansi@5.1.0: + resolution: {integrity: sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==} + engines: {node: '>=6'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + ws@3.3.3: + resolution: {integrity: sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@5.2.3: + resolution: {integrity: sha512-jZArVERrMsKUatIdnLzqvcfydI85dvd/Fp1u/VOpfdDWQ4c9qWXe+VIeAbQ5FrDwciAkr+lzofXLz3Kuf26AOA==} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@7.4.6: + resolution: {integrity: sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@7.5.9: + resolution: {integrity: sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.5.0: + resolution: {integrity: sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xhr-request-promise@0.1.3: + resolution: {integrity: sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==} + + xhr-request@1.1.0: + resolution: {integrity: sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==} + + xhr2-cookies@1.1.0: + resolution: {integrity: sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg=} + + xhr@2.6.0: + resolution: {integrity: sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==} + + xmlhttprequest@1.8.0: + resolution: {integrity: sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==} + engines: {node: '>=0.4.0'} + + xtend@2.1.2: + resolution: {integrity: sha512-vMNKzr2rHP9Dp/e1NQFnLQlwlhp9L/LfvnsVdHxN1f+uggyVI3i08uD14GPvCToPkdsRfyPqIyYGmIk58V98ZQ==} + engines: {node: '>=0.4'} + + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + + y18n@3.2.2: + resolution: {integrity: sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==} + + y18n@4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yaeti@0.0.6: + resolution: {integrity: sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==} + engines: {node: '>=0.10.32'} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + yaml@1.10.2: + resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} + engines: {node: '>= 6'} + + yargs-parser@13.1.2: + resolution: {integrity: sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==} + + yargs-parser@2.4.1: + resolution: {integrity: sha512-9pIKIJhnI5tonzG6OnCFlz/yln8xHYcGl+pn3xR0Vzff0vzN1PbNRaelgfgRUwZ3s4i3jvxT9WhmUGL4whnasA==} + + yargs-parser@20.2.4: + resolution: {integrity: sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==} + engines: {node: '>=10'} + + yargs-unparser@1.6.0: + resolution: {integrity: sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==} + engines: {node: '>=6'} + + yargs-unparser@2.0.0: + resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} + engines: {node: '>=10'} + + yargs@13.3.2: + resolution: {integrity: sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==} + + yargs@16.2.0: + resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} + engines: {node: '>=10'} + + yargs@4.8.1: + resolution: {integrity: sha512-LqodLrnIDM3IFT+Hf/5sxBnEGECrfdC1uIbgZeJmESCSo4HoCAaKEus8MylXHAkdacGc0ye+Qa+dpkuom8uVYA==} + + yesno@0.3.1: + resolution: {integrity: sha512-7RbCXegyu6DykWPWU0YEtW8gFJH8KBL2d5l2fqB0XpkH0Y9rk59YSSWpzEv7yNJBGAouPc67h3kkq0CZkpBdFw==} + + yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + +snapshots: + + '@aashutoshrathi/word-wrap@1.2.6': {} + + '@adraffy/ens-normalize@1.10.1': {} + + '@babel/code-frame@7.12.11': + dependencies: + '@babel/highlight': 7.23.4 + + '@babel/code-frame@7.23.5': + dependencies: + '@babel/highlight': 7.23.4 + chalk: 2.4.2 + + '@babel/helper-validator-identifier@7.22.20': {} + + '@babel/highlight@7.23.4': + dependencies: + '@babel/helper-validator-identifier': 7.22.20 + chalk: 2.4.2 + js-tokens: 4.0.0 + + '@babel/runtime@7.23.9': + dependencies: + regenerator-runtime: 0.14.1 + + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + + '@ensdomains/address-encoder@0.1.9': + dependencies: + bech32: 1.1.4 + blakejs: 1.2.1 + bn.js: 4.12.0 + bs58: 4.0.1 + crypto-addr-codec: 0.1.8 + nano-base32: 1.0.1 + ripemd160: 2.0.2 + + '@ensdomains/ens@0.4.5': + dependencies: + bluebird: 3.7.2 + eth-ens-namehash: 2.0.8 + solc: 0.4.26 + testrpc: 0.0.1 + web3-utils: 1.10.4 + + '@ensdomains/ensjs@2.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)': + dependencies: + '@babel/runtime': 7.23.9 + '@ensdomains/address-encoder': 0.1.9 + '@ensdomains/ens': 0.4.5 + '@ensdomains/resolver': 0.2.4 + content-hash: 2.5.2 + eth-ens-namehash: 2.0.8 + ethers: 5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) + js-sha3: 0.8.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@ensdomains/resolver@0.2.4': {} + + '@eslint/eslintrc@0.4.3': + dependencies: + ajv: 6.12.6 + debug: 4.3.4(supports-color@8.1.1) + espree: 7.3.1 + globals: 13.24.0 + ignore: 4.0.6 + import-fresh: 3.3.0 + js-yaml: 3.14.1 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@ethereum-waffle/chai@3.4.4(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)': + dependencies: + '@ethereum-waffle/provider': 3.4.4(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + ethers: 5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + + '@ethereum-waffle/compiler@3.4.4(bufferutil@4.0.8)(encoding@0.1.13)(typescript@4.7.4)(utf-8-validate@5.0.10)': + dependencies: + '@resolver-engine/imports': 0.3.3 + '@resolver-engine/imports-fs': 0.3.3 + '@typechain/ethers-v5': 2.0.0(ethers@5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typechain@3.0.0(typescript@4.7.4)) + '@types/mkdirp': 0.5.2 + '@types/node-fetch': 2.6.11 + ethers: 5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) + mkdirp: 0.5.6 + node-fetch: 2.7.0(encoding@0.1.13) + solc: 0.6.12 + ts-generator: 0.1.1 + typechain: 3.0.0(typescript@4.7.4) + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - typescript + - utf-8-validate + + '@ethereum-waffle/ens@3.4.4(bufferutil@4.0.8)(utf-8-validate@5.0.10)': + dependencies: + '@ensdomains/ens': 0.4.5 + '@ensdomains/resolver': 0.2.4 + ethers: 5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@ethereum-waffle/mock-contract@3.4.4(bufferutil@4.0.8)(utf-8-validate@5.0.10)': + dependencies: + '@ethersproject/abi': 5.7.0 + ethers: 5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@ethereum-waffle/provider@3.4.4(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)': + dependencies: + '@ethereum-waffle/ens': 3.4.4(bufferutil@4.0.8)(utf-8-validate@5.0.10) + ethers: 5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) + ganache-core: 2.13.2(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + patch-package: 6.5.1 + postinstall-postinstall: 2.1.0 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + + '@ethereumjs/common@2.5.0': + dependencies: + crc-32: 1.2.2 + ethereumjs-util: 7.1.5 + + '@ethereumjs/common@2.6.5': + dependencies: + crc-32: 1.2.2 + ethereumjs-util: 7.1.5 + + '@ethereumjs/rlp@4.0.1': {} + + '@ethereumjs/tx@3.3.2': + dependencies: + '@ethereumjs/common': 2.6.5 + ethereumjs-util: 7.1.5 + + '@ethereumjs/tx@3.5.2': + dependencies: + '@ethereumjs/common': 2.6.5 + ethereumjs-util: 7.1.5 + + '@ethereumjs/util@8.1.0': + dependencies: + '@ethereumjs/rlp': 4.0.1 + ethereum-cryptography: 2.1.3 + micro-ftch: 0.3.1 + + '@ethersproject/abi@5.0.0-beta.153': + dependencies: + '@ethersproject/address': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/hash': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/strings': 5.7.0 + optional: true + + '@ethersproject/abi@5.7.0': + dependencies: + '@ethersproject/address': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/hash': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/strings': 5.7.0 + + '@ethersproject/abstract-provider@5.7.0': + dependencies: + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/networks': 5.7.1 + '@ethersproject/properties': 5.7.0 + '@ethersproject/transactions': 5.7.0 + '@ethersproject/web': 5.7.1 + + '@ethersproject/abstract-signer@5.7.0': + dependencies: + '@ethersproject/abstract-provider': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + + '@ethersproject/address@5.7.0': + dependencies: + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/rlp': 5.7.0 + + '@ethersproject/base64@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + + '@ethersproject/basex@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/properties': 5.7.0 + + '@ethersproject/bignumber@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + bn.js: 5.2.1 + + '@ethersproject/bytes@5.7.0': + dependencies: + '@ethersproject/logger': 5.7.0 + + '@ethersproject/constants@5.7.0': + dependencies: + '@ethersproject/bignumber': 5.7.0 + + '@ethersproject/contracts@5.7.0': + dependencies: + '@ethersproject/abi': 5.7.0 + '@ethersproject/abstract-provider': 5.7.0 + '@ethersproject/abstract-signer': 5.7.0 + '@ethersproject/address': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/transactions': 5.7.0 + + '@ethersproject/hash@5.7.0': + dependencies: + '@ethersproject/abstract-signer': 5.7.0 + '@ethersproject/address': 5.7.0 + '@ethersproject/base64': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/strings': 5.7.0 + + '@ethersproject/hdnode@5.7.0': + dependencies: + '@ethersproject/abstract-signer': 5.7.0 + '@ethersproject/basex': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/pbkdf2': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/sha2': 5.7.0 + '@ethersproject/signing-key': 5.7.0 + '@ethersproject/strings': 5.7.0 + '@ethersproject/transactions': 5.7.0 + '@ethersproject/wordlists': 5.7.0 + + '@ethersproject/json-wallets@5.7.0': + dependencies: + '@ethersproject/abstract-signer': 5.7.0 + '@ethersproject/address': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/hdnode': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/pbkdf2': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/random': 5.7.0 + '@ethersproject/strings': 5.7.0 + '@ethersproject/transactions': 5.7.0 + aes-js: 3.0.0 + scrypt-js: 3.0.1 + + '@ethersproject/keccak256@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + js-sha3: 0.8.0 + + '@ethersproject/logger@5.7.0': {} + + '@ethersproject/networks@5.7.1': + dependencies: + '@ethersproject/logger': 5.7.0 + + '@ethersproject/pbkdf2@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/sha2': 5.7.0 + + '@ethersproject/properties@5.7.0': + dependencies: + '@ethersproject/logger': 5.7.0 + + '@ethersproject/providers@5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10)': + dependencies: + '@ethersproject/abstract-provider': 5.7.0 + '@ethersproject/abstract-signer': 5.7.0 + '@ethersproject/address': 5.7.0 + '@ethersproject/base64': 5.7.0 + '@ethersproject/basex': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/hash': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/networks': 5.7.1 + '@ethersproject/properties': 5.7.0 + '@ethersproject/random': 5.7.0 + '@ethersproject/rlp': 5.7.0 + '@ethersproject/sha2': 5.7.0 + '@ethersproject/strings': 5.7.0 + '@ethersproject/transactions': 5.7.0 + '@ethersproject/web': 5.7.1 + bech32: 1.1.4 + ws: 7.4.6(bufferutil@4.0.8)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@ethersproject/random@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + + '@ethersproject/rlp@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + + '@ethersproject/sha2@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + hash.js: 1.1.7 + + '@ethersproject/signing-key@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + bn.js: 5.2.1 + elliptic: 6.5.4 + hash.js: 1.1.7 + + '@ethersproject/solidity@5.7.0': + dependencies: + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/sha2': 5.7.0 + '@ethersproject/strings': 5.7.0 + + '@ethersproject/strings@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/logger': 5.7.0 + + '@ethersproject/transactions@5.7.0': + dependencies: + '@ethersproject/address': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/rlp': 5.7.0 + '@ethersproject/signing-key': 5.7.0 + + '@ethersproject/units@5.7.0': + dependencies: + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/logger': 5.7.0 + + '@ethersproject/wallet@5.7.0': + dependencies: + '@ethersproject/abstract-provider': 5.7.0 + '@ethersproject/abstract-signer': 5.7.0 + '@ethersproject/address': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/hash': 5.7.0 + '@ethersproject/hdnode': 5.7.0 + '@ethersproject/json-wallets': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/random': 5.7.0 + '@ethersproject/signing-key': 5.7.0 + '@ethersproject/transactions': 5.7.0 + '@ethersproject/wordlists': 5.7.0 + + '@ethersproject/web@5.7.1': + dependencies: + '@ethersproject/base64': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/strings': 5.7.0 + + '@ethersproject/wordlists@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/hash': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/strings': 5.7.0 + + '@fastify/busboy@2.1.0': {} + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.4.15': {} + + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + + '@ljharb/resumer@0.0.1': + dependencies: + '@ljharb/through': 2.3.12 + + '@ljharb/through@2.3.12': + dependencies: + call-bind: 1.0.7 + + '@metamask/eth-sig-util@4.0.1': + dependencies: + ethereumjs-abi: 0.6.8 + ethereumjs-util: 6.2.1 + ethjs-util: 0.1.6 + tweetnacl: 1.0.3 + tweetnacl-util: 0.15.1 + + '@noble/curves@1.2.0': + dependencies: + '@noble/hashes': 1.3.2 + + '@noble/curves@1.3.0': + dependencies: + '@noble/hashes': 1.3.3 + + '@noble/hashes@1.2.0': {} + + '@noble/hashes@1.3.2': {} + + '@noble/hashes@1.3.3': {} + + '@noble/secp256k1@1.7.1': {} + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.17.1 + + '@nomicfoundation/ethereumjs-block@5.0.4': + dependencies: + '@nomicfoundation/ethereumjs-common': 4.0.4 + '@nomicfoundation/ethereumjs-rlp': 5.0.4 + '@nomicfoundation/ethereumjs-trie': 6.0.4 + '@nomicfoundation/ethereumjs-tx': 5.0.4 + '@nomicfoundation/ethereumjs-util': 9.0.4 + ethereum-cryptography: 0.1.3 + transitivePeerDependencies: + - c-kzg + + '@nomicfoundation/ethereumjs-blockchain@7.0.4': + dependencies: + '@nomicfoundation/ethereumjs-block': 5.0.4 + '@nomicfoundation/ethereumjs-common': 4.0.4 + '@nomicfoundation/ethereumjs-ethash': 3.0.4 + '@nomicfoundation/ethereumjs-rlp': 5.0.4 + '@nomicfoundation/ethereumjs-trie': 6.0.4 + '@nomicfoundation/ethereumjs-tx': 5.0.4 + '@nomicfoundation/ethereumjs-util': 9.0.4 + debug: 4.3.4(supports-color@8.1.1) + ethereum-cryptography: 0.1.3 + lru-cache: 10.2.0 + transitivePeerDependencies: + - c-kzg + - supports-color + + '@nomicfoundation/ethereumjs-common@4.0.4': + dependencies: + '@nomicfoundation/ethereumjs-util': 9.0.4 + transitivePeerDependencies: + - c-kzg + + '@nomicfoundation/ethereumjs-ethash@3.0.4': + dependencies: + '@nomicfoundation/ethereumjs-block': 5.0.4 + '@nomicfoundation/ethereumjs-rlp': 5.0.4 + '@nomicfoundation/ethereumjs-util': 9.0.4 + bigint-crypto-utils: 3.3.0 + ethereum-cryptography: 0.1.3 + transitivePeerDependencies: + - c-kzg + + '@nomicfoundation/ethereumjs-evm@2.0.4(@nomicfoundation/ethereumjs-verkle@0.0.2)': + dependencies: + '@nomicfoundation/ethereumjs-common': 4.0.4 + '@nomicfoundation/ethereumjs-statemanager': 2.0.4(@nomicfoundation/ethereumjs-verkle@0.0.2) + '@nomicfoundation/ethereumjs-tx': 5.0.4 + '@nomicfoundation/ethereumjs-util': 9.0.4 + '@types/debug': 4.1.12 + debug: 4.3.4(supports-color@8.1.1) + ethereum-cryptography: 0.1.3 + rustbn-wasm: 0.2.0 + transitivePeerDependencies: + - '@nomicfoundation/ethereumjs-verkle' + - c-kzg + - supports-color + + '@nomicfoundation/ethereumjs-rlp@5.0.4': {} + + '@nomicfoundation/ethereumjs-statemanager@2.0.4(@nomicfoundation/ethereumjs-verkle@0.0.2)': + dependencies: + '@nomicfoundation/ethereumjs-common': 4.0.4 + '@nomicfoundation/ethereumjs-rlp': 5.0.4 + '@nomicfoundation/ethereumjs-trie': 6.0.4 + '@nomicfoundation/ethereumjs-util': 9.0.4 + debug: 4.3.4(supports-color@8.1.1) + ethereum-cryptography: 0.1.3 + js-sdsl: 4.4.2 + lru-cache: 10.2.0 + optionalDependencies: + '@nomicfoundation/ethereumjs-verkle': 0.0.2 + transitivePeerDependencies: + - c-kzg + - supports-color + + '@nomicfoundation/ethereumjs-trie@6.0.4': + dependencies: + '@nomicfoundation/ethereumjs-rlp': 5.0.4 + '@nomicfoundation/ethereumjs-util': 9.0.4 + '@types/readable-stream': 2.3.15 + ethereum-cryptography: 0.1.3 + lru-cache: 10.2.0 + readable-stream: 3.6.2 + transitivePeerDependencies: + - c-kzg + + '@nomicfoundation/ethereumjs-tx@5.0.4': + dependencies: + '@nomicfoundation/ethereumjs-common': 4.0.4 + '@nomicfoundation/ethereumjs-rlp': 5.0.4 + '@nomicfoundation/ethereumjs-util': 9.0.4 + ethereum-cryptography: 0.1.3 + + '@nomicfoundation/ethereumjs-util@9.0.4': + dependencies: + '@nomicfoundation/ethereumjs-rlp': 5.0.4 + ethereum-cryptography: 0.1.3 + + '@nomicfoundation/ethereumjs-verkle@0.0.2': + dependencies: + '@nomicfoundation/ethereumjs-rlp': 5.0.4 + '@nomicfoundation/ethereumjs-util': 9.0.4 + lru-cache: 10.2.0 + rust-verkle-wasm: 0.0.1 + transitivePeerDependencies: + - c-kzg + + '@nomicfoundation/ethereumjs-vm@7.0.4(@nomicfoundation/ethereumjs-verkle@0.0.2)': + dependencies: + '@nomicfoundation/ethereumjs-block': 5.0.4 + '@nomicfoundation/ethereumjs-blockchain': 7.0.4 + '@nomicfoundation/ethereumjs-common': 4.0.4 + '@nomicfoundation/ethereumjs-evm': 2.0.4(@nomicfoundation/ethereumjs-verkle@0.0.2) + '@nomicfoundation/ethereumjs-rlp': 5.0.4 + '@nomicfoundation/ethereumjs-statemanager': 2.0.4(@nomicfoundation/ethereumjs-verkle@0.0.2) + '@nomicfoundation/ethereumjs-trie': 6.0.4 + '@nomicfoundation/ethereumjs-tx': 5.0.4 + '@nomicfoundation/ethereumjs-util': 9.0.4 + debug: 4.3.4(supports-color@8.1.1) + ethereum-cryptography: 0.1.3 + transitivePeerDependencies: + - '@nomicfoundation/ethereumjs-verkle' + - c-kzg + - supports-color + + '@nomicfoundation/hardhat-ethers@3.0.6(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.20.1(bufferutil@4.0.8)(ts-node@10.9.1(@types/node@20.11.20)(typescript@4.7.4))(typescript@4.7.4)(utf-8-validate@5.0.10))': + dependencies: + debug: 4.3.4(supports-color@8.1.1) + ethers: 6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + hardhat: 2.20.1(bufferutil@4.0.8)(ts-node@10.9.1(@types/node@20.11.20)(typescript@4.7.4))(typescript@4.7.4)(utf-8-validate@5.0.10) + lodash.isequal: 4.5.0 + transitivePeerDependencies: + - supports-color + + '@nomicfoundation/hardhat-verify@2.0.8(hardhat@2.20.1(bufferutil@4.0.8)(ts-node@10.9.1(@types/node@20.11.20)(typescript@4.7.4))(typescript@4.7.4)(utf-8-validate@5.0.10))': + dependencies: + '@ethersproject/abi': 5.7.0 + '@ethersproject/address': 5.7.0 + cbor: 8.1.0 + chalk: 2.4.2 + debug: 4.3.4(supports-color@8.1.1) + hardhat: 2.20.1(bufferutil@4.0.8)(ts-node@10.9.1(@types/node@20.11.20)(typescript@4.7.4))(typescript@4.7.4)(utf-8-validate@5.0.10) + lodash.clonedeep: 4.5.0 + semver: 6.3.1 + table: 6.8.1 + undici: 5.28.3 + transitivePeerDependencies: + - supports-color + + '@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.1': + optional: true + + '@nomicfoundation/solidity-analyzer-darwin-x64@0.1.1': + optional: true + + '@nomicfoundation/solidity-analyzer-freebsd-x64@0.1.1': + optional: true + + '@nomicfoundation/solidity-analyzer-linux-arm64-gnu@0.1.1': + optional: true + + '@nomicfoundation/solidity-analyzer-linux-arm64-musl@0.1.1': + optional: true + + '@nomicfoundation/solidity-analyzer-linux-x64-gnu@0.1.1': + optional: true + + '@nomicfoundation/solidity-analyzer-linux-x64-musl@0.1.1': + optional: true + + '@nomicfoundation/solidity-analyzer-win32-arm64-msvc@0.1.1': + optional: true + + '@nomicfoundation/solidity-analyzer-win32-ia32-msvc@0.1.1': + optional: true + + '@nomicfoundation/solidity-analyzer-win32-x64-msvc@0.1.1': + optional: true + + '@nomicfoundation/solidity-analyzer@0.1.1': + optionalDependencies: + '@nomicfoundation/solidity-analyzer-darwin-arm64': 0.1.1 + '@nomicfoundation/solidity-analyzer-darwin-x64': 0.1.1 + '@nomicfoundation/solidity-analyzer-freebsd-x64': 0.1.1 + '@nomicfoundation/solidity-analyzer-linux-arm64-gnu': 0.1.1 + '@nomicfoundation/solidity-analyzer-linux-arm64-musl': 0.1.1 + '@nomicfoundation/solidity-analyzer-linux-x64-gnu': 0.1.1 + '@nomicfoundation/solidity-analyzer-linux-x64-musl': 0.1.1 + '@nomicfoundation/solidity-analyzer-win32-arm64-msvc': 0.1.1 + '@nomicfoundation/solidity-analyzer-win32-ia32-msvc': 0.1.1 + '@nomicfoundation/solidity-analyzer-win32-x64-msvc': 0.1.1 + + '@nomiclabs/hardhat-truffle5@2.0.7(@nomiclabs/hardhat-web3@2.0.0(hardhat@2.20.1(bufferutil@4.0.8)(ts-node@10.9.1(@types/node@20.11.20)(typescript@4.7.4))(typescript@4.7.4)(utf-8-validate@5.0.10))(web3@1.10.4(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)))(bufferutil@4.0.8)(encoding@0.1.13)(hardhat@2.20.1(bufferutil@4.0.8)(ts-node@10.9.1(@types/node@20.11.20)(typescript@4.7.4))(typescript@4.7.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)(web3-core-helpers@1.10.4)(web3-core-promievent@1.10.4)(web3-eth-abi@1.10.4)(web3-utils@1.10.4)(web3@1.10.4(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10))': + dependencies: + '@nomiclabs/hardhat-web3': 2.0.0(hardhat@2.20.1(bufferutil@4.0.8)(ts-node@10.9.1(@types/node@20.11.20)(typescript@4.7.4))(typescript@4.7.4)(utf-8-validate@5.0.10))(web3@1.10.4(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)) + '@nomiclabs/truffle-contract': 4.5.10(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)(web3-core-helpers@1.10.4)(web3-core-promievent@1.10.4)(web3-eth-abi@1.10.4)(web3-utils@1.10.4)(web3@1.10.4(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)) + '@types/chai': 4.3.16 + chai: 4.3.4 + ethereumjs-util: 7.1.5 + fs-extra: 7.0.1 + hardhat: 2.20.1(bufferutil@4.0.8)(ts-node@10.9.1(@types/node@20.11.20)(typescript@4.7.4))(typescript@4.7.4)(utf-8-validate@5.0.10) + web3: 1.10.4(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + - web3-core-helpers + - web3-core-promievent + - web3-eth-abi + - web3-utils + + '@nomiclabs/hardhat-web3@2.0.0(hardhat@2.20.1(bufferutil@4.0.8)(ts-node@10.9.1(@types/node@20.11.20)(typescript@4.7.4))(typescript@4.7.4)(utf-8-validate@5.0.10))(web3@1.10.4(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10))': + dependencies: + '@types/bignumber.js': 5.0.0 + hardhat: 2.20.1(bufferutil@4.0.8)(ts-node@10.9.1(@types/node@20.11.20)(typescript@4.7.4))(typescript@4.7.4)(utf-8-validate@5.0.10) + web3: 1.10.4(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + + '@nomiclabs/truffle-contract@4.5.10(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)(web3-core-helpers@1.10.4)(web3-core-promievent@1.10.4)(web3-eth-abi@1.10.4)(web3-utils@1.10.4)(web3@1.10.4(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10))': + dependencies: + '@ensdomains/ensjs': 2.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@truffle/blockchain-utils': 0.1.9 + '@truffle/contract-schema': 3.4.16 + '@truffle/debug-utils': 6.0.57 + '@truffle/error': 0.1.1 + '@truffle/interface-adapter': 0.5.37(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + bignumber.js: 7.2.1 + ethereum-ens: 0.8.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + ethers: 4.0.49 + source-map-support: 0.5.21 + web3: 1.10.4(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + web3-core-helpers: 1.10.4 + web3-core-promievent: 1.10.4 + web3-eth-abi: 1.10.4 + web3-utils: 1.10.4 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + + '@resolver-engine/core@0.3.3': + dependencies: + debug: 3.2.7 + is-url: 1.2.4 + request: 2.88.2 + transitivePeerDependencies: + - supports-color + + '@resolver-engine/fs@0.3.3': + dependencies: + '@resolver-engine/core': 0.3.3 + debug: 3.2.7 + transitivePeerDependencies: + - supports-color + + '@resolver-engine/imports-fs@0.3.3': + dependencies: + '@resolver-engine/fs': 0.3.3 + '@resolver-engine/imports': 0.3.3 + debug: 3.2.7 + transitivePeerDependencies: + - supports-color + + '@resolver-engine/imports@0.3.3': + dependencies: + '@resolver-engine/core': 0.3.3 + debug: 3.2.7 + hosted-git-info: 2.8.9 + path-browserify: 1.0.1 + url: 0.11.3 + transitivePeerDependencies: + - supports-color + + '@scure/base@1.1.5': {} + + '@scure/bip32@1.1.5': + dependencies: + '@noble/hashes': 1.2.0 + '@noble/secp256k1': 1.7.1 + '@scure/base': 1.1.5 + + '@scure/bip32@1.3.3': + dependencies: + '@noble/curves': 1.3.0 + '@noble/hashes': 1.3.3 + '@scure/base': 1.1.5 + + '@scure/bip39@1.1.1': + dependencies: + '@noble/hashes': 1.2.0 + '@scure/base': 1.1.5 + + '@scure/bip39@1.2.2': + dependencies: + '@noble/hashes': 1.3.3 + '@scure/base': 1.1.5 + + '@sentry/core@5.30.0': + dependencies: + '@sentry/hub': 5.30.0 + '@sentry/minimal': 5.30.0 + '@sentry/types': 5.30.0 + '@sentry/utils': 5.30.0 + tslib: 1.14.1 + + '@sentry/hub@5.30.0': + dependencies: + '@sentry/types': 5.30.0 + '@sentry/utils': 5.30.0 + tslib: 1.14.1 + + '@sentry/minimal@5.30.0': + dependencies: + '@sentry/hub': 5.30.0 + '@sentry/types': 5.30.0 + tslib: 1.14.1 + + '@sentry/node@5.30.0': + dependencies: + '@sentry/core': 5.30.0 + '@sentry/hub': 5.30.0 + '@sentry/tracing': 5.30.0 + '@sentry/types': 5.30.0 + '@sentry/utils': 5.30.0 + cookie: 0.4.2 + https-proxy-agent: 5.0.1 + lru_map: 0.3.3 + tslib: 1.14.1 + transitivePeerDependencies: + - supports-color + + '@sentry/tracing@5.30.0': + dependencies: + '@sentry/hub': 5.30.0 + '@sentry/minimal': 5.30.0 + '@sentry/types': 5.30.0 + '@sentry/utils': 5.30.0 + tslib: 1.14.1 + + '@sentry/types@5.30.0': {} + + '@sentry/utils@5.30.0': + dependencies: + '@sentry/types': 5.30.0 + tslib: 1.14.1 + + '@sindresorhus/is@0.14.0': + optional: true + + '@sindresorhus/is@4.6.0': {} + + '@solidity-parser/parser@0.14.5': + dependencies: + antlr4ts: 0.5.0-alpha.4 + + '@solidity-parser/parser@0.16.2': + dependencies: + antlr4ts: 0.5.0-alpha.4 + + '@szmarczak/http-timer@1.1.2': + dependencies: + defer-to-connect: 1.1.3 + optional: true + + '@szmarczak/http-timer@4.0.6': + dependencies: + defer-to-connect: 2.0.1 + + '@szmarczak/http-timer@5.0.1': + dependencies: + defer-to-connect: 2.0.1 + + '@tenderly/hardhat-tenderly@1.0.11(hardhat@2.20.1(bufferutil@4.0.8)(ts-node@10.9.1(@types/node@20.11.20)(typescript@4.7.4))(typescript@4.7.4)(utf-8-validate@5.0.10))': + dependencies: + axios: 0.21.4 + fs-extra: 9.1.0 + hardhat: 2.20.1(bufferutil@4.0.8)(ts-node@10.9.1(@types/node@20.11.20)(typescript@4.7.4))(typescript@4.7.4)(utf-8-validate@5.0.10) + js-yaml: 3.14.1 + transitivePeerDependencies: + - debug + + '@truffle/abi-utils@1.0.3': + dependencies: + change-case: 3.0.2 + fast-check: 3.1.1 + web3-utils: 1.10.0 + + '@truffle/blockchain-utils@0.1.9': {} + + '@truffle/codec@0.17.3': + dependencies: + '@truffle/abi-utils': 1.0.3 + '@truffle/compile-common': 0.9.8 + big.js: 6.2.1 + bn.js: 5.2.1 + cbor: 5.2.0 + debug: 4.3.4(supports-color@8.1.1) + lodash: 4.17.21 + semver: 7.6.0 + utf8: 3.0.0 + web3-utils: 1.10.0 + transitivePeerDependencies: + - supports-color + + '@truffle/compile-common@0.9.8': + dependencies: + '@truffle/error': 0.2.2 + colors: 1.4.0 + + '@truffle/contract-schema@3.4.16': + dependencies: + ajv: 6.12.6 + debug: 4.3.4(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + '@truffle/debug-utils@6.0.57': + dependencies: + '@truffle/codec': 0.17.3 + '@trufflesuite/chromafi': 3.0.0 + bn.js: 5.2.1 + chalk: 2.4.2 + debug: 4.3.4(supports-color@8.1.1) + highlightjs-solidity: 2.0.6 + transitivePeerDependencies: + - supports-color + + '@truffle/error@0.1.1': {} + + '@truffle/error@0.2.2': {} + + '@truffle/interface-adapter@0.5.37(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)': + dependencies: + bn.js: 5.2.1 + ethers: 4.0.49 + web3: 1.10.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + + '@trufflesuite/chromafi@3.0.0': + dependencies: + camelcase: 4.1.0 + chalk: 2.4.2 + cheerio: 1.0.0-rc.12 + detect-indent: 5.0.0 + highlight.js: 10.7.3 + lodash.merge: 4.6.2 + strip-ansi: 4.0.0 + strip-indent: 2.0.0 + + '@tsconfig/node10@1.0.9': {} + + '@tsconfig/node12@1.0.11': {} + + '@tsconfig/node14@1.0.3': {} + + '@tsconfig/node16@1.0.4': {} + + '@typechain/ethers-v5@2.0.0(ethers@5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typechain@3.0.0(typescript@4.7.4))': + dependencies: + ethers: 5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) + typechain: 3.0.0(typescript@4.7.4) + + '@typechain/ethers-v6@0.5.1(ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@4.7.4))(typescript@4.7.4)': + dependencies: + ethers: 6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + lodash: 4.17.21 + ts-essentials: 7.0.3(typescript@4.7.4) + typechain: 8.3.2(typescript@4.7.4) + typescript: 4.7.4 + + '@types/bignumber.js@5.0.0': + dependencies: + bignumber.js: 9.1.2 + + '@types/bn.js@4.11.6': + dependencies: + '@types/node': 20.11.20 + + '@types/bn.js@5.1.5': + dependencies: + '@types/node': 20.11.20 + + '@types/cacheable-request@6.0.3': + dependencies: + '@types/http-cache-semantics': 4.0.4 + '@types/keyv': 3.1.4 + '@types/node': 20.11.20 + '@types/responselike': 1.0.3 + + '@types/chai-as-promised@7.1.0': + dependencies: + '@types/chai': 4.3.16 + + '@types/chai-string@1.4.1': + dependencies: + '@types/chai': 4.3.16 + + '@types/chai@4.3.16': {} + + '@types/concat-stream@1.6.1': + dependencies: + '@types/node': 20.11.20 + + '@types/debug@4.1.12': + dependencies: + '@types/ms': 0.7.34 + + '@types/form-data@0.0.33': + dependencies: + '@types/node': 20.11.20 + + '@types/glob@7.2.0': + dependencies: + '@types/minimatch': 5.1.2 + '@types/node': 20.11.20 + + '@types/http-cache-semantics@4.0.4': {} + + '@types/json-schema@7.0.15': {} + + '@types/json5@0.0.29': {} + + '@types/keyv@3.1.4': + dependencies: + '@types/node': 20.11.20 + + '@types/lru-cache@5.1.1': {} + + '@types/minimatch@5.1.2': {} + + '@types/mkdirp@0.5.2': + dependencies: + '@types/node': 20.11.20 + + '@types/mocha@8.2.1': {} + + '@types/ms@0.7.34': {} + + '@types/node-fetch@2.6.11': + dependencies: + '@types/node': 20.11.20 + form-data: 4.0.0 + + '@types/node@10.17.60': {} + + '@types/node@12.20.55': {} + + '@types/node@18.15.13': {} + + '@types/node@20.11.20': + dependencies: + undici-types: 5.26.5 + + '@types/node@8.10.66': {} + + '@types/pbkdf2@3.1.2': + dependencies: + '@types/node': 20.11.20 + + '@types/prettier@2.7.3': {} + + '@types/qs@6.9.11': {} + + '@types/readable-stream@2.3.15': + dependencies: + '@types/node': 20.11.20 + safe-buffer: 5.1.2 + + '@types/resolve@0.0.8': + dependencies: + '@types/node': 20.11.20 + + '@types/responselike@1.0.3': + dependencies: + '@types/node': 20.11.20 + + '@types/secp256k1@4.0.6': + dependencies: + '@types/node': 20.11.20 + + '@typescript-eslint/eslint-plugin@4.18.0(@typescript-eslint/parser@4.18.0(eslint@7.22.0)(typescript@4.7.4))(eslint@7.22.0)(typescript@4.7.4)': + dependencies: + '@typescript-eslint/experimental-utils': 4.18.0(eslint@7.22.0)(typescript@4.7.4) + '@typescript-eslint/parser': 4.18.0(eslint@7.22.0)(typescript@4.7.4) + '@typescript-eslint/scope-manager': 4.18.0 + debug: 4.3.4(supports-color@8.1.1) + eslint: 7.22.0 + functional-red-black-tree: 1.0.1 + lodash: 4.17.21 + regexpp: 3.2.0 + semver: 7.6.0 + tsutils: 3.21.0(typescript@4.7.4) + optionalDependencies: + typescript: 4.7.4 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/experimental-utils@4.18.0(eslint@7.22.0)(typescript@4.7.4)': + dependencies: + '@types/json-schema': 7.0.15 + '@typescript-eslint/scope-manager': 4.18.0 + '@typescript-eslint/types': 4.18.0 + '@typescript-eslint/typescript-estree': 4.18.0(typescript@4.7.4) + eslint: 7.22.0 + eslint-scope: 5.1.1 + eslint-utils: 2.1.0 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/parser@4.18.0(eslint@7.22.0)(typescript@4.7.4)': + dependencies: + '@typescript-eslint/scope-manager': 4.18.0 + '@typescript-eslint/types': 4.18.0 + '@typescript-eslint/typescript-estree': 4.18.0(typescript@4.7.4) + debug: 4.3.4(supports-color@8.1.1) + eslint: 7.22.0 + optionalDependencies: + typescript: 4.7.4 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@4.18.0': + dependencies: + '@typescript-eslint/types': 4.18.0 + '@typescript-eslint/visitor-keys': 4.18.0 + + '@typescript-eslint/types@4.18.0': {} + + '@typescript-eslint/typescript-estree@4.18.0(typescript@4.7.4)': + dependencies: + '@typescript-eslint/types': 4.18.0 + '@typescript-eslint/visitor-keys': 4.18.0 + debug: 4.3.4(supports-color@8.1.1) + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.6.0 + tsutils: 3.21.0(typescript@4.7.4) + optionalDependencies: + typescript: 4.7.4 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@4.18.0': + dependencies: + '@typescript-eslint/types': 4.18.0 + eslint-visitor-keys: 2.1.0 + + '@yarnpkg/lockfile@1.1.0': {} + + abbrev@1.0.9: {} + + abortcontroller-polyfill@1.7.5: {} + + abstract-leveldown@2.6.3: + dependencies: + xtend: 4.0.2 + + abstract-leveldown@2.7.2: + dependencies: + xtend: 4.0.2 + + abstract-leveldown@3.0.0: + dependencies: + xtend: 4.0.2 + + abstract-leveldown@5.0.0: + dependencies: + xtend: 4.0.2 + + accepts@1.3.8: + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + + acorn-jsx@5.3.2(acorn@7.4.1): + dependencies: + acorn: 7.4.1 + + acorn-walk@8.3.2: {} + + acorn@7.4.1: {} + + acorn@8.11.3: {} + + address@1.2.2: {} + + adm-zip@0.4.16: {} + + aes-js@3.0.0: {} + + aes-js@3.1.2: + optional: true + + aes-js@4.0.0-beta.5: {} + + agent-base@6.0.2: + dependencies: + debug: 4.3.4(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + aggregate-error@3.1.0: + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ajv@8.12.0: + dependencies: + fast-deep-equal: 3.1.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + uri-js: 4.4.1 + + amdefine@1.0.1: + optional: true + + ansi-align@3.0.1: + dependencies: + string-width: 4.2.3 + + ansi-colors@3.2.3: {} + + ansi-colors@4.1.1: {} + + ansi-colors@4.1.3: {} + + ansi-escapes@4.3.2: + dependencies: + type-fest: 0.21.3 + + ansi-regex@2.1.1: {} + + ansi-regex@3.0.1: {} + + ansi-regex@4.1.1: {} + + ansi-regex@5.0.1: {} + + ansi-styles@2.2.1: {} + + ansi-styles@3.2.1: + dependencies: + color-convert: 1.9.3 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + antlr4@4.13.1: {} + + antlr4ts@0.5.0-alpha.4: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + arg@4.1.3: {} + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + argparse@2.0.1: {} + + arr-diff@4.0.0: {} + + arr-flatten@1.1.0: {} + + arr-union@3.1.0: {} + + array-back@1.0.4: + dependencies: + typical: 2.6.1 + + array-back@2.0.0: + dependencies: + typical: 2.6.1 + + array-back@3.1.0: {} + + array-back@4.0.2: {} + + array-buffer-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + is-array-buffer: 3.0.4 + + array-flatten@1.1.1: {} + + array-includes@3.1.7: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.22.4 + get-intrinsic: 1.2.4 + is-string: 1.0.7 + + array-union@2.1.0: {} + + array-uniq@1.0.3: {} + + array-unique@0.3.2: {} + + array.prototype.flat@1.3.2: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.22.4 + es-shim-unscopables: 1.0.2 + + array.prototype.reduce@1.0.6: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.22.4 + es-array-method-boxes-properly: 1.0.0 + is-string: 1.0.7 + + arraybuffer.prototype.slice@1.0.3: + dependencies: + array-buffer-byte-length: 1.0.1 + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.22.4 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + is-array-buffer: 3.0.4 + is-shared-array-buffer: 1.0.3 + + asap@2.0.6: {} + + asn1.js@5.4.1: + dependencies: + bn.js: 4.12.0 + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + safer-buffer: 2.1.2 + optional: true + + asn1@0.2.6: + dependencies: + safer-buffer: 2.1.2 + + assert-plus@1.0.0: {} + + assertion-error@1.1.0: {} + + assign-symbols@1.0.0: {} + + ast-parents@0.0.1: {} + + astral-regex@2.0.0: {} + + async-eventemitter@0.2.4: + dependencies: + async: 2.6.2 + + async-limiter@1.0.1: {} + + async@1.5.2: {} + + async@2.6.2: + dependencies: + lodash: 4.17.21 + + asynckit@0.4.0: {} + + at-least-node@1.0.0: {} + + atob@2.1.2: {} + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.0.0 + + aws-sign2@0.7.0: {} + + aws4@1.12.0: {} + + axios@0.21.4: + dependencies: + follow-redirects: 1.15.5(debug@4.3.4) + transitivePeerDependencies: + - debug + + axios@1.6.7: + dependencies: + follow-redirects: 1.15.5(debug@4.3.4) + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + babel-code-frame@6.26.0: + dependencies: + chalk: 1.1.3 + esutils: 2.0.3 + js-tokens: 3.0.2 + + babel-core@6.26.3: + dependencies: + babel-code-frame: 6.26.0 + babel-generator: 6.26.1 + babel-helpers: 6.24.1 + babel-messages: 6.23.0 + babel-register: 6.26.0 + babel-runtime: 6.26.0 + babel-template: 6.26.0 + babel-traverse: 6.26.0 + babel-types: 6.26.0 + babylon: 6.18.0 + convert-source-map: 1.9.0 + debug: 2.6.9 + json5: 0.5.1 + lodash: 4.17.21 + minimatch: 3.1.2 + path-is-absolute: 1.0.1 + private: 0.1.8 + slash: 1.0.0 + source-map: 0.5.7 + transitivePeerDependencies: + - supports-color + + babel-generator@6.26.1: + dependencies: + babel-messages: 6.23.0 + babel-runtime: 6.26.0 + babel-types: 6.26.0 + detect-indent: 4.0.0 + jsesc: 1.3.0 + lodash: 4.17.21 + source-map: 0.5.7 + trim-right: 1.0.1 + + babel-helper-builder-binary-assignment-operator-visitor@6.24.1: + dependencies: + babel-helper-explode-assignable-expression: 6.24.1 + babel-runtime: 6.26.0 + babel-types: 6.26.0 + transitivePeerDependencies: + - supports-color + + babel-helper-call-delegate@6.24.1: + dependencies: + babel-helper-hoist-variables: 6.24.1 + babel-runtime: 6.26.0 + babel-traverse: 6.26.0 + babel-types: 6.26.0 + transitivePeerDependencies: + - supports-color + + babel-helper-define-map@6.26.0: + dependencies: + babel-helper-function-name: 6.24.1 + babel-runtime: 6.26.0 + babel-types: 6.26.0 + lodash: 4.17.21 + transitivePeerDependencies: + - supports-color + + babel-helper-explode-assignable-expression@6.24.1: + dependencies: + babel-runtime: 6.26.0 + babel-traverse: 6.26.0 + babel-types: 6.26.0 + transitivePeerDependencies: + - supports-color + + babel-helper-function-name@6.24.1: + dependencies: + babel-helper-get-function-arity: 6.24.1 + babel-runtime: 6.26.0 + babel-template: 6.26.0 + babel-traverse: 6.26.0 + babel-types: 6.26.0 + transitivePeerDependencies: + - supports-color + + babel-helper-get-function-arity@6.24.1: + dependencies: + babel-runtime: 6.26.0 + babel-types: 6.26.0 + + babel-helper-hoist-variables@6.24.1: + dependencies: + babel-runtime: 6.26.0 + babel-types: 6.26.0 + + babel-helper-optimise-call-expression@6.24.1: + dependencies: + babel-runtime: 6.26.0 + babel-types: 6.26.0 + + babel-helper-regex@6.26.0: + dependencies: + babel-runtime: 6.26.0 + babel-types: 6.26.0 + lodash: 4.17.21 + + babel-helper-remap-async-to-generator@6.24.1: + dependencies: + babel-helper-function-name: 6.24.1 + babel-runtime: 6.26.0 + babel-template: 6.26.0 + babel-traverse: 6.26.0 + babel-types: 6.26.0 + transitivePeerDependencies: + - supports-color + + babel-helper-replace-supers@6.24.1: + dependencies: + babel-helper-optimise-call-expression: 6.24.1 + babel-messages: 6.23.0 + babel-runtime: 6.26.0 + babel-template: 6.26.0 + babel-traverse: 6.26.0 + babel-types: 6.26.0 + transitivePeerDependencies: + - supports-color + + babel-helpers@6.24.1: + dependencies: + babel-runtime: 6.26.0 + babel-template: 6.26.0 + transitivePeerDependencies: + - supports-color + + babel-messages@6.23.0: + dependencies: + babel-runtime: 6.26.0 + + babel-plugin-check-es2015-constants@6.22.0: + dependencies: + babel-runtime: 6.26.0 + + babel-plugin-syntax-async-functions@6.13.0: {} + + babel-plugin-syntax-exponentiation-operator@6.13.0: {} + + babel-plugin-syntax-trailing-function-commas@6.22.0: {} + + babel-plugin-transform-async-to-generator@6.24.1: + dependencies: + babel-helper-remap-async-to-generator: 6.24.1 + babel-plugin-syntax-async-functions: 6.13.0 + babel-runtime: 6.26.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-transform-es2015-arrow-functions@6.22.0: + dependencies: + babel-runtime: 6.26.0 + + babel-plugin-transform-es2015-block-scoped-functions@6.22.0: + dependencies: + babel-runtime: 6.26.0 + + babel-plugin-transform-es2015-block-scoping@6.26.0: + dependencies: + babel-runtime: 6.26.0 + babel-template: 6.26.0 + babel-traverse: 6.26.0 + babel-types: 6.26.0 + lodash: 4.17.21 + transitivePeerDependencies: + - supports-color + + babel-plugin-transform-es2015-classes@6.24.1: + dependencies: + babel-helper-define-map: 6.26.0 + babel-helper-function-name: 6.24.1 + babel-helper-optimise-call-expression: 6.24.1 + babel-helper-replace-supers: 6.24.1 + babel-messages: 6.23.0 + babel-runtime: 6.26.0 + babel-template: 6.26.0 + babel-traverse: 6.26.0 + babel-types: 6.26.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-transform-es2015-computed-properties@6.24.1: + dependencies: + babel-runtime: 6.26.0 + babel-template: 6.26.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-transform-es2015-destructuring@6.23.0: + dependencies: + babel-runtime: 6.26.0 + + babel-plugin-transform-es2015-duplicate-keys@6.24.1: + dependencies: + babel-runtime: 6.26.0 + babel-types: 6.26.0 + + babel-plugin-transform-es2015-for-of@6.23.0: + dependencies: + babel-runtime: 6.26.0 + + babel-plugin-transform-es2015-function-name@6.24.1: + dependencies: + babel-helper-function-name: 6.24.1 + babel-runtime: 6.26.0 + babel-types: 6.26.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-transform-es2015-literals@6.22.0: + dependencies: + babel-runtime: 6.26.0 + + babel-plugin-transform-es2015-modules-amd@6.24.1: + dependencies: + babel-plugin-transform-es2015-modules-commonjs: 6.26.2 + babel-runtime: 6.26.0 + babel-template: 6.26.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-transform-es2015-modules-commonjs@6.26.2: + dependencies: + babel-plugin-transform-strict-mode: 6.24.1 + babel-runtime: 6.26.0 + babel-template: 6.26.0 + babel-types: 6.26.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-transform-es2015-modules-systemjs@6.24.1: + dependencies: + babel-helper-hoist-variables: 6.24.1 + babel-runtime: 6.26.0 + babel-template: 6.26.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-transform-es2015-modules-umd@6.24.1: + dependencies: + babel-plugin-transform-es2015-modules-amd: 6.24.1 + babel-runtime: 6.26.0 + babel-template: 6.26.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-transform-es2015-object-super@6.24.1: + dependencies: + babel-helper-replace-supers: 6.24.1 + babel-runtime: 6.26.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-transform-es2015-parameters@6.24.1: + dependencies: + babel-helper-call-delegate: 6.24.1 + babel-helper-get-function-arity: 6.24.1 + babel-runtime: 6.26.0 + babel-template: 6.26.0 + babel-traverse: 6.26.0 + babel-types: 6.26.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-transform-es2015-shorthand-properties@6.24.1: + dependencies: + babel-runtime: 6.26.0 + babel-types: 6.26.0 + + babel-plugin-transform-es2015-spread@6.22.0: + dependencies: + babel-runtime: 6.26.0 + + babel-plugin-transform-es2015-sticky-regex@6.24.1: + dependencies: + babel-helper-regex: 6.26.0 + babel-runtime: 6.26.0 + babel-types: 6.26.0 + + babel-plugin-transform-es2015-template-literals@6.22.0: + dependencies: + babel-runtime: 6.26.0 + + babel-plugin-transform-es2015-typeof-symbol@6.23.0: + dependencies: + babel-runtime: 6.26.0 + + babel-plugin-transform-es2015-unicode-regex@6.24.1: + dependencies: + babel-helper-regex: 6.26.0 + babel-runtime: 6.26.0 + regexpu-core: 2.0.0 + + babel-plugin-transform-exponentiation-operator@6.24.1: + dependencies: + babel-helper-builder-binary-assignment-operator-visitor: 6.24.1 + babel-plugin-syntax-exponentiation-operator: 6.13.0 + babel-runtime: 6.26.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-transform-regenerator@6.26.0: + dependencies: + regenerator-transform: 0.10.1 + + babel-plugin-transform-strict-mode@6.24.1: + dependencies: + babel-runtime: 6.26.0 + babel-types: 6.26.0 + + babel-preset-env@1.7.0: + dependencies: + babel-plugin-check-es2015-constants: 6.22.0 + babel-plugin-syntax-trailing-function-commas: 6.22.0 + babel-plugin-transform-async-to-generator: 6.24.1 + babel-plugin-transform-es2015-arrow-functions: 6.22.0 + babel-plugin-transform-es2015-block-scoped-functions: 6.22.0 + babel-plugin-transform-es2015-block-scoping: 6.26.0 + babel-plugin-transform-es2015-classes: 6.24.1 + babel-plugin-transform-es2015-computed-properties: 6.24.1 + babel-plugin-transform-es2015-destructuring: 6.23.0 + babel-plugin-transform-es2015-duplicate-keys: 6.24.1 + babel-plugin-transform-es2015-for-of: 6.23.0 + babel-plugin-transform-es2015-function-name: 6.24.1 + babel-plugin-transform-es2015-literals: 6.22.0 + babel-plugin-transform-es2015-modules-amd: 6.24.1 + babel-plugin-transform-es2015-modules-commonjs: 6.26.2 + babel-plugin-transform-es2015-modules-systemjs: 6.24.1 + babel-plugin-transform-es2015-modules-umd: 6.24.1 + babel-plugin-transform-es2015-object-super: 6.24.1 + babel-plugin-transform-es2015-parameters: 6.24.1 + babel-plugin-transform-es2015-shorthand-properties: 6.24.1 + babel-plugin-transform-es2015-spread: 6.22.0 + babel-plugin-transform-es2015-sticky-regex: 6.24.1 + babel-plugin-transform-es2015-template-literals: 6.22.0 + babel-plugin-transform-es2015-typeof-symbol: 6.23.0 + babel-plugin-transform-es2015-unicode-regex: 6.24.1 + babel-plugin-transform-exponentiation-operator: 6.24.1 + babel-plugin-transform-regenerator: 6.26.0 + browserslist: 3.2.8 + invariant: 2.2.4 + semver: 5.7.2 + transitivePeerDependencies: + - supports-color + + babel-register@6.26.0: + dependencies: + babel-core: 6.26.3 + babel-runtime: 6.26.0 + core-js: 2.6.12 + home-or-tmp: 2.0.0 + lodash: 4.17.21 + mkdirp: 0.5.6 + source-map-support: 0.4.18 + transitivePeerDependencies: + - supports-color + + babel-runtime@6.26.0: + dependencies: + core-js: 2.6.12 + regenerator-runtime: 0.11.1 + + babel-template@6.26.0: + dependencies: + babel-runtime: 6.26.0 + babel-traverse: 6.26.0 + babel-types: 6.26.0 + babylon: 6.18.0 + lodash: 4.17.21 + transitivePeerDependencies: + - supports-color + + babel-traverse@6.26.0: + dependencies: + babel-code-frame: 6.26.0 + babel-messages: 6.23.0 + babel-runtime: 6.26.0 + babel-types: 6.26.0 + babylon: 6.18.0 + debug: 2.6.9 + globals: 9.18.0 + invariant: 2.2.4 + lodash: 4.17.21 + transitivePeerDependencies: + - supports-color + + babel-types@6.26.0: + dependencies: + babel-runtime: 6.26.0 + esutils: 2.0.3 + lodash: 4.17.21 + to-fast-properties: 1.0.3 + + babelify@7.3.0: + dependencies: + babel-core: 6.26.3 + object-assign: 4.1.1 + transitivePeerDependencies: + - supports-color + + babylon@6.18.0: {} + + backoff@2.5.0: + dependencies: + precond: 0.2.3 + + balanced-match@1.0.2: {} + + base-x@3.0.9: + dependencies: + safe-buffer: 5.2.1 + + base64-js@1.5.1: {} + + base@0.11.2: + dependencies: + cache-base: 1.0.1 + class-utils: 0.3.6 + component-emitter: 1.3.1 + define-property: 1.0.0 + isobject: 3.0.1 + mixin-deep: 1.3.2 + pascalcase: 0.1.1 + + bcrypt-pbkdf@1.0.2: + dependencies: + tweetnacl: 0.14.5 + + bech32@1.1.4: {} + + big-integer@1.6.36: {} + + big.js@6.2.1: {} + + bigint-crypto-utils@3.3.0: {} + + bignumber.js@7.2.1: {} + + bignumber.js@9.1.2: {} + + binary-extensions@2.2.0: {} + + bip39@2.5.0: + dependencies: + create-hash: 1.2.0 + pbkdf2: 3.1.2 + randombytes: 2.1.0 + safe-buffer: 5.2.1 + unorm: 1.6.0 + + bl@4.1.0: + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + + blakejs@1.2.1: {} + + bluebird@3.7.2: {} + + bn-chai@1.0.1(chai@4.3.4): + dependencies: + chai: 4.3.4 + + bn.js@4.11.6: {} + + bn.js@4.12.0: {} + + bn.js@5.2.1: {} + + body-parser@1.20.1: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.11.0 + raw-body: 2.5.1 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + body-parser@1.20.2: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.11.0 + raw-body: 2.5.2 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + boolbase@1.0.0: {} + + boxen@5.1.2: + dependencies: + ansi-align: 3.0.1 + camelcase: 6.3.0 + chalk: 4.1.2 + cli-boxes: 2.2.1 + string-width: 4.2.3 + type-fest: 0.20.2 + widest-line: 3.1.0 + wrap-ansi: 7.0.0 + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@2.3.2: + dependencies: + arr-flatten: 1.1.0 + array-unique: 0.3.2 + extend-shallow: 2.0.1 + fill-range: 4.0.0 + isobject: 3.0.1 + repeat-element: 1.1.4 + snapdragon: 0.8.2 + snapdragon-node: 2.1.1 + split-string: 3.1.0 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + + braces@3.0.2: + dependencies: + fill-range: 7.0.1 + + brorand@1.1.0: {} + + browser-stdout@1.3.1: {} + + browserify-aes@1.2.0: + dependencies: + buffer-xor: 1.0.3 + cipher-base: 1.0.4 + create-hash: 1.2.0 + evp_bytestokey: 1.0.3 + inherits: 2.0.4 + safe-buffer: 5.2.1 + + browserify-cipher@1.0.1: + dependencies: + browserify-aes: 1.2.0 + browserify-des: 1.0.2 + evp_bytestokey: 1.0.3 + optional: true + + browserify-des@1.0.2: + dependencies: + cipher-base: 1.0.4 + des.js: 1.1.0 + inherits: 2.0.4 + safe-buffer: 5.2.1 + optional: true + + browserify-rsa@4.1.0: + dependencies: + bn.js: 5.2.1 + randombytes: 2.1.0 + optional: true + + browserify-sign@4.2.2: + dependencies: + bn.js: 5.2.1 + browserify-rsa: 4.1.0 + create-hash: 1.2.0 + create-hmac: 1.1.7 + elliptic: 6.5.4 + inherits: 2.0.4 + parse-asn1: 5.1.6 + readable-stream: 3.6.2 + safe-buffer: 5.2.1 + optional: true + + browserslist@3.2.8: + dependencies: + caniuse-lite: 1.0.30001589 + electron-to-chromium: 1.4.682 + + bs58@4.0.1: + dependencies: + base-x: 3.0.9 + + bs58check@2.1.2: + dependencies: + bs58: 4.0.1 + create-hash: 1.2.0 + safe-buffer: 5.2.1 + + buffer-from@1.1.2: {} + + buffer-to-arraybuffer@0.0.5: {} + + buffer-xor@1.0.3: {} + + buffer-xor@2.0.2: + dependencies: + safe-buffer: 5.2.1 + + buffer@5.7.1: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + bufferutil@4.0.8: + dependencies: + node-gyp-build: 4.8.0 + + bytes@3.1.2: {} + + bytewise-core@1.2.3: + dependencies: + typewise-core: 1.2.0 + + bytewise@1.1.0: + dependencies: + bytewise-core: 1.2.3 + typewise: 1.0.3 + + cache-base@1.0.1: + dependencies: + collection-visit: 1.0.0 + component-emitter: 1.3.1 + get-value: 2.0.6 + has-value: 1.0.0 + isobject: 3.0.1 + set-value: 2.0.1 + to-object-path: 0.3.0 + union-value: 1.0.1 + unset-value: 1.0.0 + + cacheable-lookup@5.0.4: {} + + cacheable-lookup@6.1.0: {} + + cacheable-request@6.1.0: + dependencies: + clone-response: 1.0.3 + get-stream: 5.2.0 + http-cache-semantics: 4.1.1 + keyv: 3.1.0 + lowercase-keys: 2.0.0 + normalize-url: 4.5.1 + responselike: 1.0.2 + optional: true + + cacheable-request@7.0.4: + dependencies: + clone-response: 1.0.3 + get-stream: 5.2.0 + http-cache-semantics: 4.1.1 + keyv: 4.5.4 + lowercase-keys: 2.0.0 + normalize-url: 6.1.0 + responselike: 2.0.1 + + cachedown@1.0.0: + dependencies: + abstract-leveldown: 2.7.2 + lru-cache: 3.2.0 + + call-bind@1.0.7: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.1 + + callsites@3.1.0: {} + + camel-case@3.0.0: + dependencies: + no-case: 2.3.2 + upper-case: 1.1.3 + + camelcase@3.0.0: {} + + camelcase@4.1.0: {} + + camelcase@5.3.1: {} + + camelcase@6.3.0: {} + + caniuse-lite@1.0.30001589: {} + + caseless@0.12.0: {} + + cbor@5.2.0: + dependencies: + bignumber.js: 9.1.2 + nofilter: 1.0.4 + + cbor@8.1.0: + dependencies: + nofilter: 3.1.0 + + chai-as-promised@7.1.1(chai@4.3.4): + dependencies: + chai: 4.3.4 + check-error: 1.0.3 + + chai-bignumber@3.0.0: {} + + chai-shallow-deep-equal@1.4.6(chai@4.3.4): + dependencies: + chai: 4.3.4 + + chai-string@1.5.0(chai@4.3.4): + dependencies: + chai: 4.3.4 + + chai@4.3.4: + dependencies: + assertion-error: 1.1.0 + check-error: 1.0.3 + deep-eql: 3.0.1 + get-func-name: 2.0.2 + pathval: 1.1.1 + type-detect: 4.0.8 + + chalk@1.1.3: + dependencies: + ansi-styles: 2.2.1 + escape-string-regexp: 1.0.5 + has-ansi: 2.0.0 + strip-ansi: 3.0.1 + supports-color: 2.0.0 + + chalk@2.4.2: + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + change-case@3.0.2: + dependencies: + camel-case: 3.0.0 + constant-case: 2.0.0 + dot-case: 2.1.1 + header-case: 1.0.1 + is-lower-case: 1.1.3 + is-upper-case: 1.1.2 + lower-case: 1.1.4 + lower-case-first: 1.0.2 + no-case: 2.3.2 + param-case: 2.1.1 + pascal-case: 2.0.1 + path-case: 2.1.1 + sentence-case: 2.1.1 + snake-case: 2.1.0 + swap-case: 1.1.2 + title-case: 2.1.1 + upper-case: 1.1.3 + upper-case-first: 1.1.2 + + charenc@0.0.2: {} + + check-error@1.0.3: + dependencies: + get-func-name: 2.0.2 + + checkpoint-store@1.1.0: + dependencies: + functional-red-black-tree: 1.0.1 + + cheerio-select@2.1.0: + dependencies: + boolbase: 1.0.0 + css-select: 5.1.0 + css-what: 6.1.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.1.0 + + cheerio@1.0.0-rc.12: + dependencies: + cheerio-select: 2.1.0 + dom-serializer: 2.0.0 + domhandler: 5.0.3 + domutils: 3.1.0 + htmlparser2: 8.0.2 + parse5: 7.1.2 + parse5-htmlparser2-tree-adapter: 7.0.0 + + child_process@1.0.2: {} + + chokidar@3.3.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.2.0 + optionalDependencies: + fsevents: 2.1.3 + + chokidar@3.5.3: + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chownr@1.1.4: {} + + ci-info@2.0.0: {} + + cids@0.7.5: + dependencies: + buffer: 5.7.1 + class-is: 1.1.0 + multibase: 0.6.1 + multicodec: 1.0.4 + multihashes: 0.4.21 + + cipher-base@1.0.4: + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + + class-is@1.1.0: {} + + class-utils@0.3.6: + dependencies: + arr-union: 3.1.0 + define-property: 0.2.5 + isobject: 3.0.1 + static-extend: 0.1.2 + + clean-stack@2.2.0: {} + + cli-boxes@2.2.1: {} + + cli-cursor@3.1.0: + dependencies: + restore-cursor: 3.1.0 + + cli-spinners@2.9.2: {} + + cli-table3@0.5.1: + dependencies: + object-assign: 4.1.1 + string-width: 2.1.1 + optionalDependencies: + colors: 1.4.0 + + cliui@3.2.0: + dependencies: + string-width: 1.0.2 + strip-ansi: 3.0.1 + wrap-ansi: 2.1.0 + + cliui@5.0.0: + dependencies: + string-width: 3.1.0 + strip-ansi: 5.2.0 + wrap-ansi: 5.1.0 + + cliui@7.0.4: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + clone-response@1.0.3: + dependencies: + mimic-response: 1.0.1 + + clone@1.0.4: {} + + clone@2.1.2: {} + + code-point-at@1.1.0: {} + + collection-visit@1.0.0: + dependencies: + map-visit: 1.0.0 + object-visit: 1.0.1 + + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.3: {} + + color-name@1.1.4: {} + + colors@1.4.0: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + command-exists@1.2.9: {} + + command-line-args@4.0.7: + dependencies: + array-back: 2.0.0 + find-replace: 1.0.3 + typical: 2.6.1 + + command-line-args@5.2.1: + dependencies: + array-back: 3.1.0 + find-replace: 3.0.0 + lodash.camelcase: 4.3.0 + typical: 4.0.0 + + command-line-usage@6.1.3: + dependencies: + array-back: 4.0.2 + chalk: 2.4.2 + table-layout: 1.0.2 + typical: 5.2.0 + + commander@10.0.1: {} + + commander@3.0.2: {} + + component-emitter@1.3.1: {} + + concat-map@0.0.1: {} + + concat-stream@1.6.2: + dependencies: + buffer-from: 1.1.2 + inherits: 2.0.4 + readable-stream: 2.3.8 + typedarray: 0.0.6 + + constant-case@2.0.0: + dependencies: + snake-case: 2.1.0 + upper-case: 1.1.3 + + contains-path@0.1.0: {} + + content-disposition@0.5.4: + dependencies: + safe-buffer: 5.2.1 + + content-hash@2.5.2: + dependencies: + cids: 0.7.5 + multicodec: 0.5.7 + multihashes: 0.4.21 + + content-type@1.0.5: {} + + convert-source-map@1.9.0: {} + + cookie-signature@1.0.6: {} + + cookie@0.4.2: {} + + cookie@0.5.0: {} + + cookiejar@2.1.4: + optional: true + + copy-descriptor@0.1.1: {} + + core-js-pure@3.36.0: {} + + core-js@2.6.12: {} + + core-util-is@1.0.2: {} + + core-util-is@1.0.3: {} + + cors@2.8.5: + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + + cosmiconfig@8.3.6(typescript@4.7.4): + dependencies: + import-fresh: 3.3.0 + js-yaml: 4.1.0 + parse-json: 5.2.0 + path-type: 4.0.0 + optionalDependencies: + typescript: 4.7.4 + + crc-32@1.2.2: {} + + create-ecdh@4.0.4: + dependencies: + bn.js: 4.12.0 + elliptic: 6.5.4 + optional: true + + create-hash@1.2.0: + dependencies: + cipher-base: 1.0.4 + inherits: 2.0.4 + md5.js: 1.3.5 + ripemd160: 2.0.2 + sha.js: 2.4.11 + + create-hmac@1.1.7: + dependencies: + cipher-base: 1.0.4 + create-hash: 1.2.0 + inherits: 2.0.4 + ripemd160: 2.0.2 + safe-buffer: 5.2.1 + sha.js: 2.4.11 + + create-require@1.1.1: {} + + cross-fetch@2.2.6(encoding@0.1.13): + dependencies: + node-fetch: 2.7.0(encoding@0.1.13) + whatwg-fetch: 2.0.4 + transitivePeerDependencies: + - encoding + + cross-fetch@3.1.8(encoding@0.1.13): + dependencies: + node-fetch: 2.7.0(encoding@0.1.13) + transitivePeerDependencies: + - encoding + + cross-fetch@4.0.0(encoding@0.1.13): + dependencies: + node-fetch: 2.7.0(encoding@0.1.13) + transitivePeerDependencies: + - encoding + + cross-spawn@6.0.5: + dependencies: + nice-try: 1.0.5 + path-key: 2.0.1 + semver: 5.7.2 + shebang-command: 1.2.0 + which: 1.3.1 + + cross-spawn@7.0.3: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + crypt@0.0.2: {} + + crypto-addr-codec@0.1.8: + dependencies: + base-x: 3.0.9 + big-integer: 1.6.36 + blakejs: 1.2.1 + bs58: 4.0.1 + ripemd160-min: 0.0.6 + safe-buffer: 5.2.1 + sha3: 2.1.4 + + crypto-browserify@3.12.0: + dependencies: + browserify-cipher: 1.0.1 + browserify-sign: 4.2.2 + create-ecdh: 4.0.4 + create-hash: 1.2.0 + create-hmac: 1.1.7 + diffie-hellman: 5.0.3 + inherits: 2.0.4 + pbkdf2: 3.1.2 + public-encrypt: 4.0.3 + randombytes: 2.1.0 + randomfill: 1.0.4 + optional: true + + css-select@5.1.0: + dependencies: + boolbase: 1.0.0 + css-what: 6.1.0 + domhandler: 5.0.3 + domutils: 3.1.0 + nth-check: 2.1.1 + + css-what@6.1.0: {} + + d@1.0.1: + dependencies: + es5-ext: 0.10.63 + type: 1.2.0 + + dashdash@1.14.1: + dependencies: + assert-plus: 1.0.0 + + death@1.1.0: {} + + debug@2.6.9: + dependencies: + ms: 2.0.0 + + debug@3.2.6(supports-color@6.0.0): + dependencies: + ms: 2.1.1 + optionalDependencies: + supports-color: 6.0.0 + + debug@3.2.7: + dependencies: + ms: 2.1.3 + + debug@4.3.4(supports-color@8.1.1): + dependencies: + ms: 2.1.2 + optionalDependencies: + supports-color: 8.1.1 + + decamelize@1.2.0: {} + + decamelize@4.0.0: {} + + decode-uri-component@0.2.2: {} + + decompress-response@3.3.0: + dependencies: + mimic-response: 1.0.1 + + decompress-response@6.0.0: + dependencies: + mimic-response: 3.1.0 + + deep-eql@3.0.1: + dependencies: + type-detect: 4.0.8 + + deep-equal@1.1.2: + dependencies: + is-arguments: 1.1.1 + is-date-object: 1.0.5 + is-regex: 1.1.4 + object-is: 1.1.5 + object-keys: 1.1.1 + regexp.prototype.flags: 1.5.2 + + deep-extend@0.6.0: {} + + deep-is@0.1.4: {} + + defaults@1.0.4: + dependencies: + clone: 1.0.4 + + defer-to-connect@1.1.3: + optional: true + + defer-to-connect@2.0.1: {} + + deferred-leveldown@1.2.2: + dependencies: + abstract-leveldown: 2.6.3 + + deferred-leveldown@4.0.2: + dependencies: + abstract-leveldown: 5.0.0 + inherits: 2.0.4 + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + define-property@0.2.5: + dependencies: + is-descriptor: 0.1.7 + + define-property@1.0.0: + dependencies: + is-descriptor: 1.0.3 + + define-property@2.0.2: + dependencies: + is-descriptor: 1.0.3 + isobject: 3.0.1 + + defined@1.0.1: {} + + delayed-stream@1.0.0: {} + + depd@2.0.0: {} + + des.js@1.1.0: + dependencies: + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + optional: true + + destroy@1.2.0: {} + + detect-indent@4.0.0: + dependencies: + repeating: 2.0.1 + + detect-indent@5.0.0: {} + + detect-port@1.5.1: + dependencies: + address: 1.2.2 + debug: 4.3.4(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + diff@3.5.0: {} + + diff@4.0.2: {} + + diff@5.0.0: {} + + diffie-hellman@5.0.3: + dependencies: + bn.js: 4.12.0 + miller-rabin: 4.0.1 + randombytes: 2.1.0 + optional: true + + difflib@0.2.4: + dependencies: + heap: 0.2.7 + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + doctrine@1.5.0: + dependencies: + esutils: 2.0.3 + isarray: 1.0.0 + + doctrine@3.0.0: + dependencies: + esutils: 2.0.3 + + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + dom-walk@0.1.2: {} + + domelementtype@2.3.0: {} + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + domutils@3.1.0: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + + dot-case@2.1.1: + dependencies: + no-case: 2.3.2 + + dotenv@8.2.0: {} + + dotignore@0.1.2: + dependencies: + minimatch: 3.1.2 + + duplexer3@0.1.5: + optional: true + + ecc-jsbn@0.1.2: + dependencies: + jsbn: 0.1.1 + safer-buffer: 2.1.2 + + ee-first@1.1.1: {} + + electron-to-chromium@1.4.682: {} + + elliptic@6.5.4: + dependencies: + bn.js: 4.12.0 + brorand: 1.1.0 + hash.js: 1.1.7 + hmac-drbg: 1.0.1 + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + + emoji-regex@7.0.3: {} + + emoji-regex@8.0.0: {} + + encodeurl@1.0.2: {} + + encoding-down@5.0.4: + dependencies: + abstract-leveldown: 5.0.0 + inherits: 2.0.4 + level-codec: 9.0.2 + level-errors: 2.0.1 + xtend: 4.0.2 + + encoding@0.1.13: + dependencies: + iconv-lite: 0.6.3 + + end-of-stream@1.4.4: + dependencies: + once: 1.4.0 + + enquirer@2.4.1: + dependencies: + ansi-colors: 4.1.3 + strip-ansi: 6.0.1 + + entities@4.5.0: {} + + env-paths@2.2.1: {} + + errno@0.1.8: + dependencies: + prr: 1.0.1 + + error-ex@1.3.2: + dependencies: + is-arrayish: 0.2.1 + + es-abstract@1.22.4: + dependencies: + array-buffer-byte-length: 1.0.1 + arraybuffer.prototype.slice: 1.0.3 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + es-define-property: 1.0.0 + es-errors: 1.3.0 + es-set-tostringtag: 2.0.3 + es-to-primitive: 1.2.1 + function.prototype.name: 1.1.6 + get-intrinsic: 1.2.4 + get-symbol-description: 1.0.2 + globalthis: 1.0.3 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.1 + internal-slot: 1.0.7 + is-array-buffer: 3.0.4 + is-callable: 1.2.7 + is-negative-zero: 2.0.3 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.3 + is-string: 1.0.7 + is-typed-array: 1.1.13 + is-weakref: 1.0.2 + object-inspect: 1.13.1 + object-keys: 1.1.1 + object.assign: 4.1.5 + regexp.prototype.flags: 1.5.2 + safe-array-concat: 1.1.0 + safe-regex-test: 1.0.3 + string.prototype.trim: 1.2.8 + string.prototype.trimend: 1.0.7 + string.prototype.trimstart: 1.0.7 + typed-array-buffer: 1.0.2 + typed-array-byte-length: 1.0.1 + typed-array-byte-offset: 1.0.2 + typed-array-length: 1.0.5 + unbox-primitive: 1.0.2 + which-typed-array: 1.1.14 + + es-array-method-boxes-properly@1.0.0: {} + + es-define-property@1.0.0: + dependencies: + get-intrinsic: 1.2.4 + + es-errors@1.3.0: {} + + es-set-tostringtag@2.0.3: + dependencies: + get-intrinsic: 1.2.4 + has-tostringtag: 1.0.2 + hasown: 2.0.1 + + es-shim-unscopables@1.0.2: + dependencies: + hasown: 2.0.1 + + es-to-primitive@1.2.1: + dependencies: + is-callable: 1.2.7 + is-date-object: 1.0.5 + is-symbol: 1.0.4 + + es5-ext@0.10.63: + dependencies: + es6-iterator: 2.0.3 + es6-symbol: 3.1.3 + esniff: 2.0.1 + next-tick: 1.1.0 + + es6-iterator@2.0.3: + dependencies: + d: 1.0.1 + es5-ext: 0.10.63 + es6-symbol: 3.1.3 + + es6-promise@4.2.8: {} + + es6-symbol@3.1.3: + dependencies: + d: 1.0.1 + ext: 1.7.0 + + escalade@3.1.2: {} + + escape-html@1.0.3: {} + + escape-string-regexp@1.0.5: {} + + escape-string-regexp@4.0.0: {} + + escodegen@1.8.1: + dependencies: + esprima: 2.7.3 + estraverse: 1.9.3 + esutils: 2.0.3 + optionator: 0.8.3 + optionalDependencies: + source-map: 0.2.0 + + eslint-config-prettier@8.1.0(eslint@7.22.0): + dependencies: + eslint: 7.22.0 + + eslint-import-resolver-node@0.3.9: + dependencies: + debug: 3.2.7 + is-core-module: 2.13.1 + resolve: 1.22.8 + transitivePeerDependencies: + - supports-color + + eslint-module-utils@2.8.0(@typescript-eslint/parser@4.18.0(eslint@7.22.0)(typescript@4.7.4))(eslint-import-resolver-node@0.3.9)(eslint@7.22.0): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 4.18.0(eslint@7.22.0)(typescript@4.7.4) + eslint: 7.22.0 + eslint-import-resolver-node: 0.3.9 + transitivePeerDependencies: + - supports-color + + eslint-plugin-import@2.22.0(@typescript-eslint/parser@4.18.0(eslint@7.22.0)(typescript@4.7.4))(eslint@7.22.0): + dependencies: + array-includes: 3.1.7 + array.prototype.flat: 1.3.2 + contains-path: 0.1.0 + debug: 2.6.9 + doctrine: 1.5.0 + eslint: 7.22.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.8.0(@typescript-eslint/parser@4.18.0(eslint@7.22.0)(typescript@4.7.4))(eslint-import-resolver-node@0.3.9)(eslint@7.22.0) + has: 1.0.4 + minimatch: 3.1.2 + object.values: 1.1.7 + read-pkg-up: 2.0.0 + resolve: 1.22.8 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 4.18.0(eslint@7.22.0)(typescript@4.7.4) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-plugin-prettier@3.3.1(eslint-config-prettier@8.1.0(eslint@7.22.0))(eslint@7.22.0)(prettier@3.2.5): + dependencies: + eslint: 7.22.0 + prettier: 3.2.5 + prettier-linter-helpers: 1.0.0 + optionalDependencies: + eslint-config-prettier: 8.1.0(eslint@7.22.0) + + eslint-scope@5.1.1: + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + + eslint-utils@2.1.0: + dependencies: + eslint-visitor-keys: 1.3.0 + + eslint-visitor-keys@1.3.0: {} + + eslint-visitor-keys@2.1.0: {} + + eslint@7.22.0: + dependencies: + '@babel/code-frame': 7.12.11 + '@eslint/eslintrc': 0.4.3 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.4(supports-color@8.1.1) + doctrine: 3.0.0 + enquirer: 2.4.1 + eslint-scope: 5.1.1 + eslint-utils: 2.1.0 + eslint-visitor-keys: 2.1.0 + espree: 7.3.1 + esquery: 1.5.0 + esutils: 2.0.3 + file-entry-cache: 6.0.1 + functional-red-black-tree: 1.0.1 + glob-parent: 5.1.2 + globals: 13.24.0 + ignore: 4.0.6 + import-fresh: 3.3.0 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + js-yaml: 3.14.1 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash: 4.17.21 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.3 + progress: 2.0.3 + regexpp: 3.2.0 + semver: 7.6.0 + strip-ansi: 6.0.1 + strip-json-comments: 3.1.1 + table: 6.8.1 + text-table: 0.2.0 + v8-compile-cache: 2.4.0 + transitivePeerDependencies: + - supports-color + + esm@3.2.25: + optional: true + + esniff@2.0.1: + dependencies: + d: 1.0.1 + es5-ext: 0.10.63 + event-emitter: 0.3.5 + type: 2.7.2 + + espree@7.3.1: + dependencies: + acorn: 7.4.1 + acorn-jsx: 5.3.2(acorn@7.4.1) + eslint-visitor-keys: 1.3.0 + + esprima@2.7.3: {} + + esprima@4.0.1: {} + + esquery@1.5.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@1.9.3: {} + + estraverse@4.3.0: {} + + estraverse@5.3.0: {} + + esutils@2.0.3: {} + + etag@1.8.1: {} + + eth-block-tracker@3.0.1: + dependencies: + eth-query: 2.1.2 + ethereumjs-tx: 1.3.7 + ethereumjs-util: 5.2.1 + ethjs-util: 0.1.6 + json-rpc-engine: 3.8.0 + pify: 2.3.0 + tape: 4.17.0 + transitivePeerDependencies: + - supports-color + + eth-ens-namehash@2.0.8: + dependencies: + idna-uts46-hx: 2.3.1 + js-sha3: 0.5.7 + + eth-gas-reporter@0.2.27(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + '@solidity-parser/parser': 0.14.5 + axios: 1.6.7 + cli-table3: 0.5.1 + colors: 1.4.0 + ethereum-cryptography: 1.2.0 + ethers: 5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) + fs-readdir-recursive: 1.1.0 + lodash: 4.17.21 + markdown-table: 1.1.3 + mocha: 10.3.0 + req-cwd: 2.0.0 + sha1: 1.1.1 + sync-request: 6.1.0 + transitivePeerDependencies: + - bufferutil + - debug + - utf-8-validate + + eth-json-rpc-infura@3.2.1(encoding@0.1.13): + dependencies: + cross-fetch: 2.2.6(encoding@0.1.13) + eth-json-rpc-middleware: 1.6.0 + json-rpc-engine: 3.8.0 + json-rpc-error: 2.0.0 + transitivePeerDependencies: + - encoding + - supports-color + + eth-json-rpc-middleware@1.6.0: + dependencies: + async: 2.6.2 + eth-query: 2.1.2 + eth-tx-summary: 3.2.4 + ethereumjs-block: 1.7.1 + ethereumjs-tx: 1.3.7 + ethereumjs-util: 5.2.1 + ethereumjs-vm: 2.6.0 + fetch-ponyfill: 4.1.0 + json-rpc-engine: 3.8.0 + json-rpc-error: 2.0.0 + json-stable-stringify: 1.1.1 + promise-to-callback: 1.0.0 + tape: 4.17.0 + transitivePeerDependencies: + - supports-color + + eth-lib@0.1.29(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + bn.js: 4.12.0 + elliptic: 6.5.4 + nano-json-stream-parser: 0.1.2 + servify: 0.1.12 + ws: 3.3.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + xhr-request-promise: 0.1.3 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + eth-lib@0.2.8: + dependencies: + bn.js: 4.12.0 + elliptic: 6.5.4 + xhr-request-promise: 0.1.3 + + eth-query@2.1.2: + dependencies: + json-rpc-random-id: 1.0.1 + xtend: 4.0.2 + + eth-sig-util@1.4.2: + dependencies: + ethereumjs-abi: https://codeload.github.com/ethereumjs/ethereumjs-abi/tar.gz/ee3994657fa7a427238e6ba92a84d0b529bbcde0 + ethereumjs-util: 5.2.1 + + eth-sig-util@3.0.0: + dependencies: + buffer: 5.7.1 + elliptic: 6.5.4 + ethereumjs-abi: 0.6.5 + ethereumjs-util: 5.2.1 + tweetnacl: 1.0.3 + tweetnacl-util: 0.15.1 + + eth-tx-summary@3.2.4: + dependencies: + async: 2.6.2 + clone: 2.1.2 + concat-stream: 1.6.2 + end-of-stream: 1.4.4 + eth-query: 2.1.2 + ethereumjs-block: 1.7.1 + ethereumjs-tx: 1.3.7 + ethereumjs-util: 5.2.1 + ethereumjs-vm: 2.6.0 + through2: 2.0.5 + + ethashjs@0.0.8: + dependencies: + async: 2.6.2 + buffer-xor: 2.0.2 + ethereumjs-util: 7.1.5 + miller-rabin: 4.0.1 + + ethereum-bloom-filters@1.0.10: + dependencies: + js-sha3: 0.8.0 + + ethereum-common@0.0.18: {} + + ethereum-common@0.2.0: {} + + ethereum-cryptography@0.1.3: + dependencies: + '@types/pbkdf2': 3.1.2 + '@types/secp256k1': 4.0.6 + blakejs: 1.2.1 + browserify-aes: 1.2.0 + bs58check: 2.1.2 + create-hash: 1.2.0 + create-hmac: 1.1.7 + hash.js: 1.1.7 + keccak: 3.0.4 + pbkdf2: 3.1.2 + randombytes: 2.1.0 + safe-buffer: 5.2.1 + scrypt-js: 3.0.1 + secp256k1: 4.0.3 + setimmediate: 1.0.5 + + ethereum-cryptography@1.2.0: + dependencies: + '@noble/hashes': 1.2.0 + '@noble/secp256k1': 1.7.1 + '@scure/bip32': 1.1.5 + '@scure/bip39': 1.1.1 + + ethereum-cryptography@2.1.3: + dependencies: + '@noble/curves': 1.3.0 + '@noble/hashes': 1.3.3 + '@scure/bip32': 1.3.3 + '@scure/bip39': 1.2.2 + + ethereum-ens@0.8.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10): + dependencies: + bluebird: 3.7.2 + eth-ens-namehash: 2.0.8 + js-sha3: 0.5.7 + pako: 1.0.11 + underscore: 1.13.6 + web3: 1.10.4(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + + ethereum-waffle@3.4.4(bufferutil@4.0.8)(encoding@0.1.13)(typescript@4.7.4)(utf-8-validate@5.0.10): + dependencies: + '@ethereum-waffle/chai': 3.4.4(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@ethereum-waffle/compiler': 3.4.4(bufferutil@4.0.8)(encoding@0.1.13)(typescript@4.7.4)(utf-8-validate@5.0.10) + '@ethereum-waffle/mock-contract': 3.4.4(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@ethereum-waffle/provider': 3.4.4(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + ethers: 5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - typescript + - utf-8-validate + + ethereumjs-abi@0.6.5: + dependencies: + bn.js: 4.12.0 + ethereumjs-util: 4.5.1 + + ethereumjs-abi@0.6.8: + dependencies: + bn.js: 4.12.0 + ethereumjs-util: 6.2.1 + + ethereumjs-abi@https://codeload.github.com/ethereumjs/ethereumjs-abi/tar.gz/ee3994657fa7a427238e6ba92a84d0b529bbcde0: + dependencies: + bn.js: 4.12.0 + ethereumjs-util: 6.2.1 + + ethereumjs-account@2.0.5: + dependencies: + ethereumjs-util: 5.2.1 + rlp: 2.2.7 + safe-buffer: 5.2.1 + + ethereumjs-account@3.0.0: + dependencies: + ethereumjs-util: 6.2.1 + rlp: 2.2.7 + safe-buffer: 5.2.1 + + ethereumjs-block@1.7.1: + dependencies: + async: 2.6.2 + ethereum-common: 0.2.0 + ethereumjs-tx: 1.3.7 + ethereumjs-util: 5.2.1 + merkle-patricia-tree: 2.3.2 + + ethereumjs-block@2.2.2: + dependencies: + async: 2.6.2 + ethereumjs-common: 1.5.0 + ethereumjs-tx: 2.1.2 + ethereumjs-util: 5.2.1 + merkle-patricia-tree: 2.3.2 + + ethereumjs-blockchain@4.0.4: + dependencies: + async: 2.6.2 + ethashjs: 0.0.8 + ethereumjs-block: 2.2.2 + ethereumjs-common: 1.5.0 + ethereumjs-util: 6.2.1 + flow-stoplight: 1.0.0 + level-mem: 3.0.1 + lru-cache: 5.1.1 + rlp: 2.2.7 + semaphore: 1.1.0 + + ethereumjs-common@1.5.0: {} + + ethereumjs-tx@1.3.7: + dependencies: + ethereum-common: 0.0.18 + ethereumjs-util: 5.2.1 + + ethereumjs-tx@2.1.2: + dependencies: + ethereumjs-common: 1.5.0 + ethereumjs-util: 6.2.1 + + ethereumjs-util@4.5.1: + dependencies: + bn.js: 4.12.0 + create-hash: 1.2.0 + elliptic: 6.5.4 + ethereum-cryptography: 0.1.3 + rlp: 2.2.7 + + ethereumjs-util@5.2.1: + dependencies: + bn.js: 4.12.0 + create-hash: 1.2.0 + elliptic: 6.5.4 + ethereum-cryptography: 0.1.3 + ethjs-util: 0.1.6 + rlp: 2.2.7 + safe-buffer: 5.2.1 + + ethereumjs-util@6.2.1: + dependencies: + '@types/bn.js': 4.11.6 + bn.js: 4.12.0 + create-hash: 1.2.0 + elliptic: 6.5.4 + ethereum-cryptography: 0.1.3 + ethjs-util: 0.1.6 + rlp: 2.2.7 + + ethereumjs-util@7.1.5: + dependencies: + '@types/bn.js': 5.1.5 + bn.js: 5.2.1 + create-hash: 1.2.0 + ethereum-cryptography: 0.1.3 + rlp: 2.2.7 + + ethereumjs-vm@2.6.0: + dependencies: + async: 2.6.2 + async-eventemitter: 0.2.4 + ethereumjs-account: 2.0.5 + ethereumjs-block: 2.2.2 + ethereumjs-common: 1.5.0 + ethereumjs-util: 6.2.1 + fake-merkle-patricia-tree: 1.0.1 + functional-red-black-tree: 1.0.1 + merkle-patricia-tree: 2.3.2 + rustbn.js: 0.2.0 + safe-buffer: 5.2.1 + + ethereumjs-vm@4.2.0: + dependencies: + async: 2.6.2 + async-eventemitter: 0.2.4 + core-js-pure: 3.36.0 + ethereumjs-account: 3.0.0 + ethereumjs-block: 2.2.2 + ethereumjs-blockchain: 4.0.4 + ethereumjs-common: 1.5.0 + ethereumjs-tx: 2.1.2 + ethereumjs-util: 6.2.1 + fake-merkle-patricia-tree: 1.0.1 + functional-red-black-tree: 1.0.1 + merkle-patricia-tree: 2.3.2 + rustbn.js: 0.2.0 + safe-buffer: 5.2.1 + util.promisify: 1.1.2 + + ethereumjs-wallet@0.6.5: + dependencies: + aes-js: 3.1.2 + bs58check: 2.1.2 + ethereum-cryptography: 0.1.3 + ethereumjs-util: 6.2.1 + randombytes: 2.1.0 + safe-buffer: 5.2.1 + scryptsy: 1.2.1 + utf8: 3.0.0 + uuid: 3.4.0 + optional: true + + ethers@4.0.49: + dependencies: + aes-js: 3.0.0 + bn.js: 4.12.0 + elliptic: 6.5.4 + hash.js: 1.1.3 + js-sha3: 0.5.7 + scrypt-js: 2.0.4 + setimmediate: 1.0.4 + uuid: 2.0.1 + xmlhttprequest: 1.8.0 + + ethers@5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + '@ethersproject/abi': 5.7.0 + '@ethersproject/abstract-provider': 5.7.0 + '@ethersproject/abstract-signer': 5.7.0 + '@ethersproject/address': 5.7.0 + '@ethersproject/base64': 5.7.0 + '@ethersproject/basex': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/contracts': 5.7.0 + '@ethersproject/hash': 5.7.0 + '@ethersproject/hdnode': 5.7.0 + '@ethersproject/json-wallets': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/networks': 5.7.1 + '@ethersproject/pbkdf2': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/providers': 5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@ethersproject/random': 5.7.0 + '@ethersproject/rlp': 5.7.0 + '@ethersproject/sha2': 5.7.0 + '@ethersproject/signing-key': 5.7.0 + '@ethersproject/solidity': 5.7.0 + '@ethersproject/strings': 5.7.0 + '@ethersproject/transactions': 5.7.0 + '@ethersproject/units': 5.7.0 + '@ethersproject/wallet': 5.7.0 + '@ethersproject/web': 5.7.1 + '@ethersproject/wordlists': 5.7.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + ethers@6.13.0(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + '@adraffy/ens-normalize': 1.10.1 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@types/node': 18.15.13 + aes-js: 4.0.0-beta.5 + tslib: 2.4.0 + ws: 8.5.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + ethjs-unit@0.1.6: + dependencies: + bn.js: 4.11.6 + number-to-bn: 1.7.0 + + ethjs-util@0.1.6: + dependencies: + is-hex-prefixed: 1.0.0 + strip-hex-prefix: 1.0.0 + + event-emitter@0.3.5: + dependencies: + d: 1.0.1 + es5-ext: 0.10.63 + + eventemitter3@4.0.4: {} + + events@3.3.0: {} + + evp_bytestokey@1.0.3: + dependencies: + md5.js: 1.3.5 + safe-buffer: 5.2.1 + + expand-brackets@2.1.4: + dependencies: + debug: 2.6.9 + define-property: 0.2.5 + extend-shallow: 2.0.1 + posix-character-classes: 0.1.1 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + + express@4.18.2: + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.1 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.5.0 + cookie-signature: 1.0.6 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.2.0 + fresh: 0.5.2 + http-errors: 2.0.0 + merge-descriptors: 1.0.1 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.7 + proxy-addr: 2.0.7 + qs: 6.11.0 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.18.0 + serve-static: 1.15.0 + setprototypeof: 1.2.0 + statuses: 2.0.1 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + ext@1.7.0: + dependencies: + type: 2.7.2 + + extend-shallow@2.0.1: + dependencies: + is-extendable: 0.1.1 + + extend-shallow@3.0.2: + dependencies: + assign-symbols: 1.0.0 + is-extendable: 1.0.1 + + extend@3.0.2: {} + + extglob@2.0.4: + dependencies: + array-unique: 0.3.2 + define-property: 1.0.0 + expand-brackets: 2.1.4 + extend-shallow: 2.0.1 + fragment-cache: 0.2.1 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + + extsprintf@1.3.0: {} + + fake-merkle-patricia-tree@1.0.1: + dependencies: + checkpoint-store: 1.1.0 + + fast-check@3.1.1: + dependencies: + pure-rand: 5.0.5 + + fast-deep-equal@3.1.3: {} + + fast-diff@1.3.0: {} + + fast-glob@3.3.2: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.5 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fastq@1.17.1: + dependencies: + reusify: 1.0.4 + + fetch-ponyfill@4.1.0: + dependencies: + node-fetch: 1.7.3 + + file-entry-cache@6.0.1: + dependencies: + flat-cache: 3.2.0 + + fill-range@4.0.0: + dependencies: + extend-shallow: 2.0.1 + is-number: 3.0.0 + repeat-string: 1.6.1 + to-regex-range: 2.1.1 + + fill-range@7.0.1: + dependencies: + to-regex-range: 5.0.1 + + finalhandler@1.2.0: + dependencies: + debug: 2.6.9 + encodeurl: 1.0.2 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.1 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + find-replace@1.0.3: + dependencies: + array-back: 1.0.4 + test-value: 2.1.0 + + find-replace@3.0.0: + dependencies: + array-back: 3.1.0 + + find-up@1.1.2: + dependencies: + path-exists: 2.1.0 + pinkie-promise: 2.0.1 + + find-up@2.1.0: + dependencies: + locate-path: 2.0.0 + + find-up@3.0.0: + dependencies: + locate-path: 3.0.0 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + find-yarn-workspace-root@1.2.1: + dependencies: + fs-extra: 4.0.3 + micromatch: 3.1.10 + transitivePeerDependencies: + - supports-color + + find-yarn-workspace-root@2.0.0: + dependencies: + micromatch: 4.0.5 + + flat-cache@3.2.0: + dependencies: + flatted: 3.3.1 + keyv: 4.5.4 + rimraf: 3.0.2 + + flat@4.1.1: + dependencies: + is-buffer: 2.0.5 + + flat@5.0.2: {} + + flatted@3.3.1: {} + + flow-stoplight@1.0.0: {} + + follow-redirects@1.15.5(debug@4.3.4): + optionalDependencies: + debug: 4.3.4(supports-color@8.1.1) + + for-each@0.3.3: + dependencies: + is-callable: 1.2.7 + + for-in@1.0.2: {} + + forever-agent@0.6.1: {} + + form-data-encoder@1.7.1: {} + + form-data@2.3.3: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + + form-data@2.5.1: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + + form-data@4.0.0: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + + forwarded@0.2.0: {} + + fp-ts@1.19.3: {} + + fragment-cache@0.2.1: + dependencies: + map-cache: 0.2.2 + + fresh@0.5.2: {} + + fs-extra@0.30.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 2.4.0 + klaw: 1.3.1 + path-is-absolute: 1.0.1 + rimraf: 2.7.1 + + fs-extra@4.0.3: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fs-extra@7.0.1: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fs-extra@8.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fs-extra@9.1.0: + dependencies: + at-least-node: 1.0.0 + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + + fs-minipass@1.2.7: + dependencies: + minipass: 2.9.0 + + fs-readdir-recursive@1.1.0: {} + + fs.realpath@1.0.0: {} + + fsevents@2.1.3: + optional: true + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + function.prototype.name@1.1.6: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.22.4 + functions-have-names: 1.2.3 + + functional-red-black-tree@1.0.1: {} + + functions-have-names@1.2.3: {} + + ganache-cli@6.12.2: {} + + ganache-core@2.13.2(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10): + dependencies: + abstract-leveldown: 3.0.0 + async: 2.6.2 + bip39: 2.5.0 + cachedown: 1.0.0 + clone: 2.1.2 + debug: 3.2.6(supports-color@6.0.0) + encoding-down: 5.0.4 + eth-sig-util: 3.0.0 + ethereumjs-abi: 0.6.8 + ethereumjs-account: 3.0.0 + ethereumjs-block: 2.2.2 + ethereumjs-common: 1.5.0 + ethereumjs-tx: 2.1.2 + ethereumjs-util: 6.2.1 + ethereumjs-vm: 4.2.0 + heap: 0.2.6 + level-sublevel: 6.6.4 + levelup: 3.1.1 + lodash: 4.17.20 + lru-cache: 5.1.1 + merkle-patricia-tree: 3.0.0 + patch-package: 6.2.2 + seedrandom: 3.0.1 + source-map-support: 0.5.12 + tmp: 0.1.0 + web3-provider-engine: 14.2.1(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + websocket: 1.0.32 + optionalDependencies: + ethereumjs-wallet: 0.6.5 + web3: 1.2.11(bufferutil@4.0.8)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + + get-caller-file@1.0.3: {} + + get-caller-file@2.0.5: {} + + get-func-name@2.0.2: {} + + get-intrinsic@1.2.4: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.1 + + get-port@3.2.0: {} + + get-stream@4.1.0: + dependencies: + pump: 3.0.0 + optional: true + + get-stream@5.2.0: + dependencies: + pump: 3.0.0 + + get-stream@6.0.1: {} + + get-symbol-description@1.0.2: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + + get-value@2.0.6: {} + + getpass@0.1.7: + dependencies: + assert-plus: 1.0.0 + + ghost-testrpc@0.0.2: + dependencies: + chalk: 2.4.2 + node-emoji: 1.11.0 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob@5.0.15: + dependencies: + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + glob@7.1.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.0.4 + once: 1.4.0 + path-is-absolute: 1.0.1 + + glob@7.1.7: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + glob@7.2.0: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + glob@8.1.0: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 5.1.6 + once: 1.4.0 + + global-modules@2.0.0: + dependencies: + global-prefix: 3.0.0 + + global-prefix@3.0.0: + dependencies: + ini: 1.3.8 + kind-of: 6.0.3 + which: 1.3.1 + + global@4.4.0: + dependencies: + min-document: 2.19.0 + process: 0.11.10 + + globals@13.24.0: + dependencies: + type-fest: 0.20.2 + + globals@9.18.0: {} + + globalthis@1.0.3: + dependencies: + define-properties: 1.2.1 + + globby@10.0.2: + dependencies: + '@types/glob': 7.2.0 + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.2 + glob: 7.2.3 + ignore: 5.3.1 + merge2: 1.4.1 + slash: 3.0.0 + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.2 + ignore: 5.3.1 + merge2: 1.4.1 + slash: 3.0.0 + + gopd@1.0.1: + dependencies: + get-intrinsic: 1.2.4 + + got@11.8.6: + dependencies: + '@sindresorhus/is': 4.6.0 + '@szmarczak/http-timer': 4.0.6 + '@types/cacheable-request': 6.0.3 + '@types/responselike': 1.0.3 + cacheable-lookup: 5.0.4 + cacheable-request: 7.0.4 + decompress-response: 6.0.0 + http2-wrapper: 1.0.3 + lowercase-keys: 2.0.0 + p-cancelable: 2.1.1 + responselike: 2.0.1 + + got@12.1.0: + dependencies: + '@sindresorhus/is': 4.6.0 + '@szmarczak/http-timer': 5.0.1 + '@types/cacheable-request': 6.0.3 + '@types/responselike': 1.0.3 + cacheable-lookup: 6.1.0 + cacheable-request: 7.0.4 + decompress-response: 6.0.0 + form-data-encoder: 1.7.1 + get-stream: 6.0.1 + http2-wrapper: 2.2.1 + lowercase-keys: 3.0.0 + p-cancelable: 3.0.0 + responselike: 2.0.1 + + got@9.6.0: + dependencies: + '@sindresorhus/is': 0.14.0 + '@szmarczak/http-timer': 1.1.2 + '@types/keyv': 3.1.4 + '@types/responselike': 1.0.3 + cacheable-request: 6.1.0 + decompress-response: 3.3.0 + duplexer3: 0.1.5 + get-stream: 4.1.0 + lowercase-keys: 1.0.1 + mimic-response: 1.0.1 + p-cancelable: 1.1.0 + to-readable-stream: 1.0.0 + url-parse-lax: 3.0.0 + optional: true + + graceful-fs@4.2.11: {} + + growl@1.10.5: {} + + handlebars@4.7.8: + dependencies: + minimist: 1.2.8 + neo-async: 2.6.2 + source-map: 0.6.1 + wordwrap: 1.0.0 + optionalDependencies: + uglify-js: 3.17.4 + + har-schema@2.0.0: {} + + har-validator@5.1.5: + dependencies: + ajv: 6.12.6 + har-schema: 2.0.0 + + hardhat-gas-reporter@1.0.10(bufferutil@4.0.8)(hardhat@2.20.1(bufferutil@4.0.8)(ts-node@10.9.1(@types/node@20.11.20)(typescript@4.7.4))(typescript@4.7.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10): + dependencies: + array-uniq: 1.0.3 + eth-gas-reporter: 0.2.27(bufferutil@4.0.8)(utf-8-validate@5.0.10) + hardhat: 2.20.1(bufferutil@4.0.8)(ts-node@10.9.1(@types/node@20.11.20)(typescript@4.7.4))(typescript@4.7.4)(utf-8-validate@5.0.10) + sha1: 1.1.1 + transitivePeerDependencies: + - '@codechecks/client' + - bufferutil + - debug + - utf-8-validate + + hardhat@2.20.1(bufferutil@4.0.8)(ts-node@10.9.1(@types/node@20.11.20)(typescript@4.7.4))(typescript@4.7.4)(utf-8-validate@5.0.10): + dependencies: + '@ethersproject/abi': 5.7.0 + '@metamask/eth-sig-util': 4.0.1 + '@nomicfoundation/ethereumjs-block': 5.0.4 + '@nomicfoundation/ethereumjs-blockchain': 7.0.4 + '@nomicfoundation/ethereumjs-common': 4.0.4 + '@nomicfoundation/ethereumjs-evm': 2.0.4(@nomicfoundation/ethereumjs-verkle@0.0.2) + '@nomicfoundation/ethereumjs-rlp': 5.0.4 + '@nomicfoundation/ethereumjs-statemanager': 2.0.4(@nomicfoundation/ethereumjs-verkle@0.0.2) + '@nomicfoundation/ethereumjs-trie': 6.0.4 + '@nomicfoundation/ethereumjs-tx': 5.0.4 + '@nomicfoundation/ethereumjs-util': 9.0.4 + '@nomicfoundation/ethereumjs-verkle': 0.0.2 + '@nomicfoundation/ethereumjs-vm': 7.0.4(@nomicfoundation/ethereumjs-verkle@0.0.2) + '@nomicfoundation/solidity-analyzer': 0.1.1 + '@sentry/node': 5.30.0 + '@types/bn.js': 5.1.5 + '@types/lru-cache': 5.1.1 + adm-zip: 0.4.16 + aggregate-error: 3.1.0 + ansi-escapes: 4.3.2 + boxen: 5.1.2 + chalk: 2.4.2 + chokidar: 3.6.0 + ci-info: 2.0.0 + debug: 4.3.4(supports-color@8.1.1) + enquirer: 2.4.1 + env-paths: 2.2.1 + ethereum-cryptography: 1.2.0 + ethereumjs-abi: 0.6.8 + find-up: 2.1.0 + fp-ts: 1.19.3 + fs-extra: 7.0.1 + glob: 7.2.0 + immutable: 4.3.5 + io-ts: 1.10.4 + keccak: 3.0.4 + lodash: 4.17.21 + mnemonist: 0.38.5 + mocha: 10.3.0 + p-map: 4.0.0 + raw-body: 2.5.2 + resolve: 1.17.0 + semver: 6.3.1 + solc: 0.7.3(debug@4.3.4) + source-map-support: 0.5.21 + stacktrace-parser: 0.1.10 + tsort: 0.0.1 + undici: 5.28.3 + uuid: 8.3.2 + ws: 7.5.9(bufferutil@4.0.8)(utf-8-validate@5.0.10) + optionalDependencies: + ts-node: 10.9.1(@types/node@20.11.20)(typescript@4.7.4) + typescript: 4.7.4 + transitivePeerDependencies: + - bufferutil + - c-kzg + - supports-color + - utf-8-validate + + has-ansi@2.0.0: + dependencies: + ansi-regex: 2.1.1 + + has-bigints@1.0.2: {} + + has-flag@1.0.0: {} + + has-flag@3.0.0: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.0 + + has-proto@1.0.3: {} + + has-symbols@1.0.3: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.0.3 + + has-value@0.3.1: + dependencies: + get-value: 2.0.6 + has-values: 0.1.4 + isobject: 2.1.0 + + has-value@1.0.0: + dependencies: + get-value: 2.0.6 + has-values: 1.0.0 + isobject: 3.0.1 + + has-values@0.1.4: {} + + has-values@1.0.0: + dependencies: + is-number: 3.0.0 + kind-of: 4.0.0 + + has@1.0.4: {} + + hash-base@3.1.0: + dependencies: + inherits: 2.0.4 + readable-stream: 3.6.2 + safe-buffer: 5.2.1 + + hash.js@1.1.3: + dependencies: + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + + hash.js@1.1.7: + dependencies: + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + + hasown@2.0.1: + dependencies: + function-bind: 1.1.2 + + he@1.2.0: {} + + header-case@1.0.1: + dependencies: + no-case: 2.3.2 + upper-case: 1.1.3 + + heap@0.2.6: {} + + heap@0.2.7: {} + + highlight.js@10.7.3: {} + + highlightjs-solidity@2.0.6: {} + + hmac-drbg@1.0.1: + dependencies: + hash.js: 1.1.7 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + + home-or-tmp@2.0.0: + dependencies: + os-homedir: 1.0.2 + os-tmpdir: 1.0.2 + + hosted-git-info@2.8.9: {} + + htmlparser2@8.0.2: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.1.0 + entities: 4.5.0 + + http-basic@8.1.3: + dependencies: + caseless: 0.12.0 + concat-stream: 1.6.2 + http-response-object: 3.0.2 + parse-cache-control: 1.0.1 + + http-cache-semantics@4.1.1: {} + + http-errors@2.0.0: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + + http-https@1.0.0: {} + + http-response-object@3.0.2: + dependencies: + '@types/node': 10.17.60 + + http-signature@1.2.0: + dependencies: + assert-plus: 1.0.0 + jsprim: 1.4.2 + sshpk: 1.18.0 + + http2-wrapper@1.0.3: + dependencies: + quick-lru: 5.1.1 + resolve-alpn: 1.2.1 + + http2-wrapper@2.2.1: + dependencies: + quick-lru: 5.1.1 + resolve-alpn: 1.2.1 + + https-proxy-agent@5.0.1: + dependencies: + agent-base: 6.0.2 + debug: 4.3.4(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + husky@9.0.11: {} + + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + + idna-uts46-hx@2.3.1: + dependencies: + punycode: 2.1.0 + + ieee754@1.2.1: {} + + ignore@4.0.6: {} + + ignore@5.3.1: {} + + immediate@3.2.3: {} + + immediate@3.3.0: {} + + immutable@4.3.5: {} + + import-fresh@3.3.0: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + indent-string@4.0.0: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + ini@1.3.8: {} + + internal-slot@1.0.7: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.1 + side-channel: 1.0.5 + + interpret@1.4.0: {} + + invariant@2.2.4: + dependencies: + loose-envify: 1.4.0 + + invert-kv@1.0.0: {} + + io-ts@1.10.4: + dependencies: + fp-ts: 1.19.3 + + ipaddr.js@1.9.1: {} + + is-accessor-descriptor@1.0.1: + dependencies: + hasown: 2.0.1 + + is-arguments@1.1.1: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + + is-array-buffer@3.0.4: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + + is-arrayish@0.2.1: {} + + is-bigint@1.0.4: + dependencies: + has-bigints: 1.0.2 + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.2.0 + + is-boolean-object@1.1.2: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + + is-buffer@1.1.6: {} + + is-buffer@2.0.5: {} + + is-callable@1.2.7: {} + + is-ci@2.0.0: + dependencies: + ci-info: 2.0.0 + + is-core-module@2.13.1: + dependencies: + hasown: 2.0.1 + + is-data-descriptor@1.0.1: + dependencies: + hasown: 2.0.1 + + is-date-object@1.0.5: + dependencies: + has-tostringtag: 1.0.2 + + is-descriptor@0.1.7: + dependencies: + is-accessor-descriptor: 1.0.1 + is-data-descriptor: 1.0.1 + + is-descriptor@1.0.3: + dependencies: + is-accessor-descriptor: 1.0.1 + is-data-descriptor: 1.0.1 + + is-docker@2.2.1: {} + + is-extendable@0.1.1: {} + + is-extendable@1.0.1: + dependencies: + is-plain-object: 2.0.4 + + is-extglob@2.1.1: {} + + is-finite@1.1.0: {} + + is-fn@1.0.0: {} + + is-fullwidth-code-point@1.0.0: + dependencies: + number-is-nan: 1.0.1 + + is-fullwidth-code-point@2.0.0: {} + + is-fullwidth-code-point@3.0.0: {} + + is-function@1.0.2: {} + + is-generator-function@1.0.10: + dependencies: + has-tostringtag: 1.0.2 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-hex-prefixed@1.0.0: {} + + is-interactive@1.0.0: {} + + is-lower-case@1.1.3: + dependencies: + lower-case: 1.1.4 + + is-negative-zero@2.0.3: {} + + is-number-object@1.0.7: + dependencies: + has-tostringtag: 1.0.2 + + is-number@3.0.0: + dependencies: + kind-of: 3.2.2 + + is-number@7.0.0: {} + + is-observable@2.1.0: {} + + is-plain-obj@2.1.0: {} + + is-plain-object@2.0.4: + dependencies: + isobject: 3.0.1 + + is-regex@1.1.4: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + + is-shared-array-buffer@1.0.3: + dependencies: + call-bind: 1.0.7 + + is-stream@1.1.0: {} + + is-string@1.0.7: + dependencies: + has-tostringtag: 1.0.2 + + is-symbol@1.0.4: + dependencies: + has-symbols: 1.0.3 + + is-typed-array@1.1.13: + dependencies: + which-typed-array: 1.1.14 + + is-typedarray@1.0.0: {} + + is-unicode-supported@0.1.0: {} + + is-upper-case@1.1.2: + dependencies: + upper-case: 1.1.3 + + is-url@1.2.4: {} + + is-utf8@0.2.1: {} + + is-weakref@1.0.2: + dependencies: + call-bind: 1.0.7 + + is-windows@1.0.2: {} + + is-wsl@2.2.0: + dependencies: + is-docker: 2.2.1 + + isarray@0.0.1: {} + + isarray@1.0.0: {} + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + isobject@2.1.0: + dependencies: + isarray: 1.0.0 + + isobject@3.0.1: {} + + isstream@0.1.2: {} + + js-sdsl@4.4.2: {} + + js-sha3@0.5.7: {} + + js-sha3@0.8.0: {} + + js-tokens@3.0.2: {} + + js-tokens@4.0.0: {} + + js-yaml@3.13.1: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + js-yaml@3.14.1: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + jsbn@0.1.1: {} + + jsesc@0.5.0: {} + + jsesc@1.3.0: {} + + json-buffer@3.0.0: + optional: true + + json-buffer@3.0.1: {} + + json-parse-even-better-errors@2.3.1: {} + + json-rpc-engine@3.8.0: + dependencies: + async: 2.6.2 + babel-preset-env: 1.7.0 + babelify: 7.3.0 + json-rpc-error: 2.0.0 + promise-to-callback: 1.0.0 + safe-event-emitter: 1.0.1 + transitivePeerDependencies: + - supports-color + + json-rpc-error@2.0.0: + dependencies: + inherits: 2.0.4 + + json-rpc-random-id@1.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-schema-traverse@1.0.0: {} + + json-schema@0.4.0: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json-stable-stringify@1.1.1: + dependencies: + call-bind: 1.0.7 + isarray: 2.0.5 + jsonify: 0.0.1 + object-keys: 1.1.1 + + json-stringify-safe@5.0.1: {} + + json5@0.5.1: {} + + json5@1.0.2: + dependencies: + minimist: 1.2.8 + + jsonfile@2.4.0: + optionalDependencies: + graceful-fs: 4.2.11 + + jsonfile@4.0.0: + optionalDependencies: + graceful-fs: 4.2.11 + + jsonfile@6.1.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + jsonify@0.0.1: {} + + jsonschema@1.4.1: {} + + jsprim@1.4.2: + dependencies: + assert-plus: 1.0.0 + extsprintf: 1.3.0 + json-schema: 0.4.0 + verror: 1.10.0 + + keccak256@1.0.6: + dependencies: + bn.js: 5.2.1 + buffer: 6.0.3 + keccak: 3.0.4 + + keccak@3.0.4: + dependencies: + node-addon-api: 2.0.2 + node-gyp-build: 4.8.0 + readable-stream: 3.6.2 + + keyv@3.1.0: + dependencies: + json-buffer: 3.0.0 + optional: true + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + kind-of@3.2.2: + dependencies: + is-buffer: 1.1.6 + + kind-of@4.0.0: + dependencies: + is-buffer: 1.1.6 + + kind-of@6.0.3: {} + + klaw-sync@6.0.0: + dependencies: + graceful-fs: 4.2.11 + + klaw@1.3.1: + optionalDependencies: + graceful-fs: 4.2.11 + + lcid@1.0.0: + dependencies: + invert-kv: 1.0.0 + + level-codec@7.0.1: {} + + level-codec@9.0.2: + dependencies: + buffer: 5.7.1 + + level-errors@1.0.5: + dependencies: + errno: 0.1.8 + + level-errors@2.0.1: + dependencies: + errno: 0.1.8 + + level-iterator-stream@1.3.1: + dependencies: + inherits: 2.0.4 + level-errors: 1.0.5 + readable-stream: 1.1.14 + xtend: 4.0.2 + + level-iterator-stream@2.0.3: + dependencies: + inherits: 2.0.4 + readable-stream: 2.3.8 + xtend: 4.0.2 + + level-iterator-stream@3.0.1: + dependencies: + inherits: 2.0.4 + readable-stream: 2.3.8 + xtend: 4.0.2 + + level-mem@3.0.1: + dependencies: + level-packager: 4.0.1 + memdown: 3.0.0 + + level-packager@4.0.1: + dependencies: + encoding-down: 5.0.4 + levelup: 3.1.1 + + level-post@1.0.7: + dependencies: + ltgt: 2.1.3 + + level-sublevel@6.6.4: + dependencies: + bytewise: 1.1.0 + level-codec: 9.0.2 + level-errors: 2.0.1 + level-iterator-stream: 2.0.3 + ltgt: 2.1.3 + pull-defer: 0.2.3 + pull-level: 2.0.4 + pull-stream: 3.7.0 + typewiselite: 1.0.0 + xtend: 4.0.2 + + level-ws@0.0.0: + dependencies: + readable-stream: 1.0.34 + xtend: 2.1.2 + + level-ws@1.0.0: + dependencies: + inherits: 2.0.4 + readable-stream: 2.3.8 + xtend: 4.0.2 + + levelup@1.3.9: + dependencies: + deferred-leveldown: 1.2.2 + level-codec: 7.0.1 + level-errors: 1.0.5 + level-iterator-stream: 1.3.1 + prr: 1.0.1 + semver: 5.4.1 + xtend: 4.0.2 + + levelup@3.1.1: + dependencies: + deferred-leveldown: 4.0.2 + level-errors: 2.0.1 + level-iterator-stream: 3.0.1 + xtend: 4.0.2 + + levn@0.3.0: + dependencies: + prelude-ls: 1.1.2 + type-check: 0.3.2 + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lines-and-columns@1.2.4: {} + + load-json-file@1.1.0: + dependencies: + graceful-fs: 4.2.11 + parse-json: 2.2.0 + pify: 2.3.0 + pinkie-promise: 2.0.1 + strip-bom: 2.0.0 + + load-json-file@2.0.0: + dependencies: + graceful-fs: 4.2.11 + parse-json: 2.2.0 + pify: 2.3.0 + strip-bom: 3.0.0 + + locate-path@2.0.0: + dependencies: + p-locate: 2.0.0 + path-exists: 3.0.0 + + locate-path@3.0.0: + dependencies: + p-locate: 3.0.0 + path-exists: 3.0.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.assign@4.2.0: {} + + lodash.camelcase@4.3.0: {} + + lodash.clonedeep@4.5.0: {} + + lodash.isequal@4.5.0: {} + + lodash.merge@4.6.2: {} + + lodash.truncate@4.4.2: {} + + lodash@4.17.20: {} + + lodash@4.17.21: {} + + log-symbols@3.0.0: + dependencies: + chalk: 2.4.2 + + log-symbols@4.1.0: + dependencies: + chalk: 4.1.2 + is-unicode-supported: 0.1.0 + + looper@2.0.0: {} + + looper@3.0.0: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + lower-case-first@1.0.2: + dependencies: + lower-case: 1.1.4 + + lower-case@1.1.4: {} + + lowercase-keys@1.0.1: + optional: true + + lowercase-keys@2.0.0: {} + + lowercase-keys@3.0.0: {} + + lru-cache@10.2.0: {} + + lru-cache@3.2.0: + dependencies: + pseudomap: 1.0.2 + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + lru-cache@6.0.0: + dependencies: + yallist: 4.0.0 + + lru_map@0.3.3: {} + + ltgt@2.1.3: {} + + ltgt@2.2.1: {} + + make-error@1.3.6: {} + + map-cache@0.2.2: {} + + map-visit@1.0.0: + dependencies: + object-visit: 1.0.1 + + markdown-table@1.1.3: {} + + md5.js@1.3.5: + dependencies: + hash-base: 3.1.0 + inherits: 2.0.4 + safe-buffer: 5.2.1 + + media-typer@0.3.0: {} + + memdown@1.4.1: + dependencies: + abstract-leveldown: 2.7.2 + functional-red-black-tree: 1.0.1 + immediate: 3.3.0 + inherits: 2.0.4 + ltgt: 2.2.1 + safe-buffer: 5.1.2 + + memdown@3.0.0: + dependencies: + abstract-leveldown: 5.0.0 + functional-red-black-tree: 1.0.1 + immediate: 3.2.3 + inherits: 2.0.4 + ltgt: 2.2.1 + safe-buffer: 5.1.2 + + memorystream@0.3.1: {} + + merge-descriptors@1.0.1: {} + + merge2@1.4.1: {} + + merkle-patricia-tree@2.3.2: + dependencies: + async: 1.5.2 + ethereumjs-util: 5.2.1 + level-ws: 0.0.0 + levelup: 1.3.9 + memdown: 1.4.1 + readable-stream: 2.3.8 + rlp: 2.2.7 + semaphore: 1.1.0 + + merkle-patricia-tree@3.0.0: + dependencies: + async: 2.6.2 + ethereumjs-util: 5.2.1 + level-mem: 3.0.1 + level-ws: 1.0.0 + readable-stream: 3.6.2 + rlp: 2.2.7 + semaphore: 1.1.0 + + methods@1.1.2: {} + + micro-ftch@0.3.1: {} + + micromatch@3.1.10: + dependencies: + arr-diff: 4.0.0 + array-unique: 0.3.2 + braces: 2.3.2 + define-property: 2.0.2 + extend-shallow: 3.0.2 + extglob: 2.0.4 + fragment-cache: 0.2.1 + kind-of: 6.0.3 + nanomatch: 1.2.13 + object.pick: 1.3.0 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + + micromatch@4.0.5: + dependencies: + braces: 3.0.2 + picomatch: 2.3.1 + + miller-rabin@4.0.1: + dependencies: + bn.js: 4.12.0 + brorand: 1.1.0 + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mime@1.6.0: {} + + mimic-fn@2.1.0: {} + + mimic-response@1.0.1: {} + + mimic-response@3.1.0: {} + + min-document@2.19.0: + dependencies: + dom-walk: 0.1.2 + + minimalistic-assert@1.0.1: {} + + minimalistic-crypto-utils@1.0.1: {} + + minimatch@3.0.4: + dependencies: + brace-expansion: 1.1.11 + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@5.0.1: + dependencies: + brace-expansion: 2.0.1 + + minimatch@5.1.6: + dependencies: + brace-expansion: 2.0.1 + + minimist@1.2.8: {} + + minipass@2.9.0: + dependencies: + safe-buffer: 5.2.1 + yallist: 3.1.1 + + minizlib@1.3.3: + dependencies: + minipass: 2.9.0 + + mixin-deep@1.3.2: + dependencies: + for-in: 1.0.2 + is-extendable: 1.0.1 + + mkdirp-promise@5.0.1: + dependencies: + mkdirp: 3.0.1 + + mkdirp@0.5.5: + dependencies: + minimist: 1.2.8 + + mkdirp@0.5.6: + dependencies: + minimist: 1.2.8 + + mkdirp@1.0.4: {} + + mkdirp@3.0.1: {} + + mnemonist@0.38.5: + dependencies: + obliterator: 2.0.4 + + mocha@10.3.0: + dependencies: + ansi-colors: 4.1.1 + browser-stdout: 1.3.1 + chokidar: 3.5.3 + debug: 4.3.4(supports-color@8.1.1) + diff: 5.0.0 + escape-string-regexp: 4.0.0 + find-up: 5.0.0 + glob: 8.1.0 + he: 1.2.0 + js-yaml: 4.1.0 + log-symbols: 4.1.0 + minimatch: 5.0.1 + ms: 2.1.3 + serialize-javascript: 6.0.0 + strip-json-comments: 3.1.1 + supports-color: 8.1.1 + workerpool: 6.2.1 + yargs: 16.2.0 + yargs-parser: 20.2.4 + yargs-unparser: 2.0.0 + + mocha@7.1.2: + dependencies: + ansi-colors: 3.2.3 + browser-stdout: 1.3.1 + chokidar: 3.3.0 + debug: 3.2.6(supports-color@6.0.0) + diff: 3.5.0 + escape-string-regexp: 1.0.5 + find-up: 3.0.0 + glob: 7.1.3 + growl: 1.10.5 + he: 1.2.0 + js-yaml: 3.13.1 + log-symbols: 3.0.0 + minimatch: 3.0.4 + mkdirp: 0.5.5 + ms: 2.1.1 + node-environment-flags: 1.0.6 + object.assign: 4.1.0 + strip-json-comments: 2.0.1 + supports-color: 6.0.0 + which: 1.3.1 + wide-align: 1.1.3 + yargs: 13.3.2 + yargs-parser: 13.1.2 + yargs-unparser: 1.6.0 + + mock-fs@4.14.0: {} + + mock-property@1.0.3: + dependencies: + define-data-property: 1.1.4 + functions-have-names: 1.2.3 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + hasown: 2.0.1 + isarray: 2.0.5 + + ms@2.0.0: {} + + ms@2.1.1: {} + + ms@2.1.2: {} + + ms@2.1.3: {} + + multibase@0.6.1: + dependencies: + base-x: 3.0.9 + buffer: 5.7.1 + + multibase@0.7.0: + dependencies: + base-x: 3.0.9 + buffer: 5.7.1 + + multicodec@0.5.7: + dependencies: + varint: 5.0.2 + + multicodec@1.0.4: + dependencies: + buffer: 5.7.1 + varint: 5.0.2 + + multihashes@0.4.21: + dependencies: + buffer: 5.7.1 + multibase: 0.7.0 + varint: 5.0.2 + + nan@2.18.0: {} + + nano-base32@1.0.1: {} + + nano-json-stream-parser@0.1.2: {} + + nanomatch@1.2.13: + dependencies: + arr-diff: 4.0.0 + array-unique: 0.3.2 + define-property: 2.0.2 + extend-shallow: 3.0.2 + fragment-cache: 0.2.1 + is-windows: 1.0.2 + kind-of: 6.0.3 + object.pick: 1.3.0 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + + natural-compare@1.4.0: {} + + negotiator@0.6.3: {} + + neo-async@2.6.2: {} + + next-tick@1.1.0: {} + + nice-try@1.0.5: {} + + no-case@2.3.2: + dependencies: + lower-case: 1.1.4 + + node-addon-api@2.0.2: {} + + node-emoji@1.11.0: + dependencies: + lodash: 4.17.21 + + node-environment-flags@1.0.6: + dependencies: + object.getownpropertydescriptors: 2.1.7 + semver: 5.7.2 + + node-fetch@1.7.3: + dependencies: + encoding: 0.1.13 + is-stream: 1.1.0 + + node-fetch@2.7.0(encoding@0.1.13): + dependencies: + whatwg-url: 5.0.0 + optionalDependencies: + encoding: 0.1.13 + + node-gyp-build@4.8.0: {} + + nofilter@1.0.4: {} + + nofilter@3.1.0: {} + + nopt@3.0.6: + dependencies: + abbrev: 1.0.9 + + normalize-package-data@2.5.0: + dependencies: + hosted-git-info: 2.8.9 + resolve: 1.22.8 + semver: 5.7.2 + validate-npm-package-license: 3.0.4 + + normalize-path@3.0.0: {} + + normalize-url@4.5.1: + optional: true + + normalize-url@6.1.0: {} + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + number-is-nan@1.0.1: {} + + number-to-bn@1.7.0: + dependencies: + bn.js: 4.11.6 + strip-hex-prefix: 1.0.0 + + oauth-sign@0.9.0: {} + + object-assign@4.1.1: {} + + object-copy@0.1.0: + dependencies: + copy-descriptor: 0.1.1 + define-property: 0.2.5 + kind-of: 3.2.2 + + object-inspect@1.12.3: {} + + object-inspect@1.13.1: {} + + object-is@1.1.5: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + + object-keys@0.4.0: {} + + object-keys@1.1.1: {} + + object-visit@1.0.1: + dependencies: + isobject: 3.0.1 + + object.assign@4.1.0: + dependencies: + define-properties: 1.2.1 + function-bind: 1.1.2 + has-symbols: 1.0.3 + object-keys: 1.1.1 + + object.assign@4.1.5: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + has-symbols: 1.0.3 + object-keys: 1.1.1 + + object.getownpropertydescriptors@2.1.7: + dependencies: + array.prototype.reduce: 1.0.6 + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.22.4 + safe-array-concat: 1.1.0 + + object.pick@1.3.0: + dependencies: + isobject: 3.0.1 + + object.values@1.1.7: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.22.4 + + obliterator@2.0.4: {} + + oboe@2.1.4: + dependencies: + http-https: 1.0.0 + optional: true + + oboe@2.1.5: + dependencies: + http-https: 1.0.0 + + observable-fns@0.6.1: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + + open@7.4.2: + dependencies: + is-docker: 2.2.1 + is-wsl: 2.2.0 + + optionator@0.8.3: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.3.0 + prelude-ls: 1.1.2 + type-check: 0.3.2 + word-wrap: 1.2.5 + + optionator@0.9.3: + dependencies: + '@aashutoshrathi/word-wrap': 1.2.6 + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + + ora@5.4.1: + dependencies: + bl: 4.1.0 + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-spinners: 2.9.2 + is-interactive: 1.0.0 + is-unicode-supported: 0.1.0 + log-symbols: 4.1.0 + strip-ansi: 6.0.1 + wcwidth: 1.0.1 + + os-homedir@1.0.2: {} + + os-locale@1.4.0: + dependencies: + lcid: 1.0.0 + + os-tmpdir@1.0.2: {} + + p-cancelable@1.1.0: + optional: true + + p-cancelable@2.1.1: {} + + p-cancelable@3.0.0: {} + + p-limit@1.3.0: + dependencies: + p-try: 1.0.0 + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@2.0.0: + dependencies: + p-limit: 1.3.0 + + p-locate@3.0.0: + dependencies: + p-limit: 2.3.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + p-map@4.0.0: + dependencies: + aggregate-error: 3.1.0 + + p-try@1.0.0: {} + + p-try@2.2.0: {} + + pako@1.0.11: {} + + param-case@2.1.1: + dependencies: + no-case: 2.3.2 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse-asn1@5.1.6: + dependencies: + asn1.js: 5.4.1 + browserify-aes: 1.2.0 + evp_bytestokey: 1.0.3 + pbkdf2: 3.1.2 + safe-buffer: 5.2.1 + optional: true + + parse-cache-control@1.0.1: {} + + parse-headers@2.0.5: {} + + parse-json@2.2.0: + dependencies: + error-ex: 1.3.2 + + parse-json@5.2.0: + dependencies: + '@babel/code-frame': 7.23.5 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + + parse5-htmlparser2-tree-adapter@7.0.0: + dependencies: + domhandler: 5.0.3 + parse5: 7.1.2 + + parse5@7.1.2: + dependencies: + entities: 4.5.0 + + parseurl@1.3.3: {} + + pascal-case@2.0.1: + dependencies: + camel-case: 3.0.0 + upper-case-first: 1.1.2 + + pascalcase@0.1.1: {} + + patch-package@6.2.2: + dependencies: + '@yarnpkg/lockfile': 1.1.0 + chalk: 2.4.2 + cross-spawn: 6.0.5 + find-yarn-workspace-root: 1.2.1 + fs-extra: 7.0.1 + is-ci: 2.0.0 + klaw-sync: 6.0.0 + minimist: 1.2.8 + rimraf: 2.7.1 + semver: 5.7.2 + slash: 2.0.0 + tmp: 0.0.33 + transitivePeerDependencies: + - supports-color + + patch-package@6.5.1: + dependencies: + '@yarnpkg/lockfile': 1.1.0 + chalk: 4.1.2 + cross-spawn: 6.0.5 + find-yarn-workspace-root: 2.0.0 + fs-extra: 9.1.0 + is-ci: 2.0.0 + klaw-sync: 6.0.0 + minimist: 1.2.8 + open: 7.4.2 + rimraf: 2.7.1 + semver: 5.7.2 + slash: 2.0.0 + tmp: 0.0.33 + yaml: 1.10.2 + + path-browserify@1.0.1: {} + + path-case@2.1.1: + dependencies: + no-case: 2.3.2 + + path-exists@2.1.0: + dependencies: + pinkie-promise: 2.0.1 + + path-exists@3.0.0: {} + + path-exists@4.0.0: {} + + path-is-absolute@1.0.1: {} + + path-key@2.0.1: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + path-to-regexp@0.1.7: {} + + path-type@1.1.0: + dependencies: + graceful-fs: 4.2.11 + pify: 2.3.0 + pinkie-promise: 2.0.1 + + path-type@2.0.0: + dependencies: + pify: 2.3.0 + + path-type@4.0.0: {} + + pathval@1.1.1: {} + + pbkdf2@3.1.2: + dependencies: + create-hash: 1.2.0 + create-hmac: 1.1.7 + ripemd160: 2.0.2 + safe-buffer: 5.2.1 + sha.js: 2.4.11 + + performance-now@2.1.0: {} + + picomatch@2.3.1: {} + + pify@2.3.0: {} + + pify@4.0.1: {} + + pinkie-promise@2.0.1: + dependencies: + pinkie: 2.0.4 + + pinkie@2.0.4: {} + + pluralize@8.0.0: {} + + posix-character-classes@0.1.1: {} + + possible-typed-array-names@1.0.0: {} + + postinstall-postinstall@2.1.0: {} + + precond@0.2.3: {} + + prelude-ls@1.1.2: {} + + prelude-ls@1.2.1: {} + + prepend-http@2.0.0: + optional: true + + prettier-linter-helpers@1.0.0: + dependencies: + fast-diff: 1.3.0 + + prettier@2.8.8: {} + + prettier@3.2.5: {} + + private@0.1.8: {} + + process-nextick-args@2.0.1: {} + + process@0.11.10: {} + + progress@2.0.3: {} + + promise-to-callback@1.0.0: + dependencies: + is-fn: 1.0.0 + set-immediate-shim: 1.0.1 + + promise@8.3.0: + dependencies: + asap: 2.0.6 + + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + proxy-from-env@1.1.0: {} + + prr@1.0.1: {} + + pseudomap@1.0.2: {} + + psl@1.9.0: {} + + public-encrypt@4.0.3: + dependencies: + bn.js: 4.12.0 + browserify-rsa: 4.1.0 + create-hash: 1.2.0 + parse-asn1: 5.1.6 + randombytes: 2.1.0 + safe-buffer: 5.2.1 + optional: true + + pull-cat@1.1.11: {} + + pull-defer@0.2.3: {} + + pull-level@2.0.4: + dependencies: + level-post: 1.0.7 + pull-cat: 1.1.11 + pull-live: 1.0.1 + pull-pushable: 2.2.0 + pull-stream: 3.7.0 + pull-window: 2.1.4 + stream-to-pull-stream: 1.7.3 + + pull-live@1.0.1: + dependencies: + pull-cat: 1.1.11 + pull-stream: 3.7.0 + + pull-pushable@2.2.0: {} + + pull-stream@3.7.0: {} + + pull-window@2.1.4: + dependencies: + looper: 2.0.0 + + pump@3.0.0: + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + + punycode@1.4.1: {} + + punycode@2.1.0: {} + + punycode@2.3.1: {} + + pure-rand@5.0.5: {} + + qs@6.11.0: + dependencies: + side-channel: 1.0.5 + + qs@6.11.2: + dependencies: + side-channel: 1.0.5 + + qs@6.5.3: {} + + query-string@5.1.1: + dependencies: + decode-uri-component: 0.2.2 + object-assign: 4.1.1 + strict-uri-encode: 1.1.0 + + queue-microtask@1.2.3: {} + + quick-lru@5.1.1: {} + + randombytes@2.1.0: + dependencies: + safe-buffer: 5.2.1 + + randomfill@1.0.4: + dependencies: + randombytes: 2.1.0 + safe-buffer: 5.2.1 + optional: true + + range-parser@1.2.1: {} + + raw-body@2.5.1: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + + raw-body@2.5.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + + read-pkg-up@1.0.1: + dependencies: + find-up: 1.1.2 + read-pkg: 1.1.0 + + read-pkg-up@2.0.0: + dependencies: + find-up: 2.1.0 + read-pkg: 2.0.0 + + read-pkg@1.1.0: + dependencies: + load-json-file: 1.1.0 + normalize-package-data: 2.5.0 + path-type: 1.1.0 + + read-pkg@2.0.0: + dependencies: + load-json-file: 2.0.0 + normalize-package-data: 2.5.0 + path-type: 2.0.0 + + readable-stream@1.0.34: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 0.0.1 + string_decoder: 0.10.31 + + readable-stream@1.1.14: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 0.0.1 + string_decoder: 0.10.31 + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + readdirp@3.2.0: + dependencies: + picomatch: 2.3.1 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + rechoir@0.6.2: + dependencies: + resolve: 1.22.8 + + recursive-readdir@2.2.3: + dependencies: + minimatch: 3.1.2 + + reduce-flatten@2.0.0: {} + + regenerate@1.4.2: {} + + regenerator-runtime@0.11.1: {} + + regenerator-runtime@0.14.1: {} + + regenerator-transform@0.10.1: + dependencies: + babel-runtime: 6.26.0 + babel-types: 6.26.0 + private: 0.1.8 + + regex-not@1.0.2: + dependencies: + extend-shallow: 3.0.2 + safe-regex: 1.1.0 + + regexp.prototype.flags@1.5.2: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-errors: 1.3.0 + set-function-name: 2.0.2 + + regexpp@3.2.0: {} + + regexpu-core@2.0.0: + dependencies: + regenerate: 1.4.2 + regjsgen: 0.2.0 + regjsparser: 0.1.5 + + regjsgen@0.2.0: {} + + regjsparser@0.1.5: + dependencies: + jsesc: 0.5.0 + + repeat-element@1.1.4: {} + + repeat-string@1.6.1: {} + + repeating@2.0.1: + dependencies: + is-finite: 1.1.0 + + req-cwd@2.0.0: + dependencies: + req-from: 2.0.0 + + req-from@2.0.0: + dependencies: + resolve-from: 3.0.0 + + request@2.88.2: + dependencies: + aws-sign2: 0.7.0 + aws4: 1.12.0 + caseless: 0.12.0 + combined-stream: 1.0.8 + extend: 3.0.2 + forever-agent: 0.6.1 + form-data: 2.3.3 + har-validator: 5.1.5 + http-signature: 1.2.0 + is-typedarray: 1.0.0 + isstream: 0.1.2 + json-stringify-safe: 5.0.1 + mime-types: 2.1.35 + oauth-sign: 0.9.0 + performance-now: 2.1.0 + qs: 6.5.3 + safe-buffer: 5.2.1 + tough-cookie: 2.5.0 + tunnel-agent: 0.6.0 + uuid: 3.4.0 + + require-directory@2.1.1: {} + + require-from-string@1.2.1: {} + + require-from-string@2.0.2: {} + + require-main-filename@1.0.1: {} + + require-main-filename@2.0.0: {} + + resolve-alpn@1.2.1: {} + + resolve-from@3.0.0: {} + + resolve-from@4.0.0: {} + + resolve-url@0.2.1: {} + + resolve@1.1.7: {} + + resolve@1.17.0: + dependencies: + path-parse: 1.0.7 + + resolve@1.22.8: + dependencies: + is-core-module: 2.13.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + responselike@1.0.2: + dependencies: + lowercase-keys: 1.0.1 + optional: true + + responselike@2.0.1: + dependencies: + lowercase-keys: 2.0.0 + + restore-cursor@3.1.0: + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + + ret@0.1.15: {} + + reusify@1.0.4: {} + + rimraf@2.7.1: + dependencies: + glob: 7.2.3 + + rimraf@3.0.2: + dependencies: + glob: 7.2.3 + + ripemd160-min@0.0.6: {} + + ripemd160@2.0.2: + dependencies: + hash-base: 3.1.0 + inherits: 2.0.4 + + rlp@2.2.7: + dependencies: + bn.js: 5.2.1 + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + rust-verkle-wasm@0.0.1: {} + + rustbn-wasm@0.2.0: + dependencies: + '@scure/base': 1.1.5 + + rustbn.js@0.2.0: {} + + safe-array-concat@1.1.0: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + has-symbols: 1.0.3 + isarray: 2.0.5 + + safe-buffer@5.1.2: {} + + safe-buffer@5.2.1: {} + + safe-event-emitter@1.0.1: + dependencies: + events: 3.3.0 + + safe-regex-test@1.0.3: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-regex: 1.1.4 + + safe-regex@1.1.0: + dependencies: + ret: 0.1.15 + + safer-buffer@2.1.2: {} + + sc-istanbul@0.4.6: + dependencies: + abbrev: 1.0.9 + async: 1.5.2 + escodegen: 1.8.1 + esprima: 2.7.3 + glob: 5.0.15 + handlebars: 4.7.8 + js-yaml: 3.14.1 + mkdirp: 0.5.6 + nopt: 3.0.6 + once: 1.4.0 + resolve: 1.1.7 + supports-color: 3.2.3 + which: 1.3.1 + wordwrap: 1.0.0 + + scrypt-js@2.0.4: {} + + scrypt-js@3.0.1: {} + + scrypt@https://codeload.github.com/barrysteyn/node-scrypt/tar.gz/fb60a8d3c158fe115a624b5ffa7480f3a24b03fb: + dependencies: + nan: 2.18.0 + + scryptsy@1.2.1: + dependencies: + pbkdf2: 3.1.2 + optional: true + + secp256k1@4.0.3: + dependencies: + elliptic: 6.5.4 + node-addon-api: 2.0.2 + node-gyp-build: 4.8.0 + + seedrandom@3.0.1: {} + + semaphore@1.1.0: {} + + semver@5.4.1: {} + + semver@5.7.2: {} + + semver@6.3.1: {} + + semver@7.6.0: + dependencies: + lru-cache: 6.0.0 + + send@0.18.0: + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.0 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + + sentence-case@2.1.1: + dependencies: + no-case: 2.3.2 + upper-case-first: 1.1.2 + + serialize-javascript@6.0.0: + dependencies: + randombytes: 2.1.0 + + serve-static@1.15.0: + dependencies: + encodeurl: 1.0.2 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.18.0 + transitivePeerDependencies: + - supports-color + + servify@0.1.12: + dependencies: + body-parser: 1.20.2 + cors: 2.8.5 + express: 4.18.2 + request: 2.88.2 + xhr: 2.6.0 + transitivePeerDependencies: + - supports-color + + set-blocking@2.0.0: {} + + set-function-length@1.2.1: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + set-immediate-shim@1.0.1: {} + + set-value@2.0.1: + dependencies: + extend-shallow: 2.0.1 + is-extendable: 0.1.1 + is-plain-object: 2.0.4 + split-string: 3.1.0 + + setimmediate@1.0.4: {} + + setimmediate@1.0.5: {} + + setprototypeof@1.2.0: {} + + sha.js@2.4.11: + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + + sha1@1.1.1: + dependencies: + charenc: 0.0.2 + crypt: 0.0.2 + + sha3@2.1.4: + dependencies: + buffer: 6.0.3 + + shebang-command@1.2.0: + dependencies: + shebang-regex: 1.0.0 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@1.0.0: {} + + shebang-regex@3.0.0: {} + + shelljs@0.8.5: + dependencies: + glob: 7.2.3 + interpret: 1.4.0 + rechoir: 0.6.2 + + side-channel@1.0.5: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + object-inspect: 1.13.1 + + signal-exit@3.0.7: {} + + simple-concat@1.0.1: {} + + simple-get@2.8.2: + dependencies: + decompress-response: 3.3.0 + once: 1.4.0 + simple-concat: 1.0.1 + + slash@1.0.0: {} + + slash@2.0.0: {} + + slash@3.0.0: {} + + slice-ansi@4.0.0: + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + + snake-case@2.1.0: + dependencies: + no-case: 2.3.2 + + snapdragon-node@2.1.1: + dependencies: + define-property: 1.0.0 + isobject: 3.0.1 + snapdragon-util: 3.0.1 + + snapdragon-util@3.0.1: + dependencies: + kind-of: 3.2.2 + + snapdragon@0.8.2: + dependencies: + base: 0.11.2 + debug: 2.6.9 + define-property: 0.2.5 + extend-shallow: 2.0.1 + map-cache: 0.2.2 + source-map: 0.5.7 + source-map-resolve: 0.5.3 + use: 3.1.1 + transitivePeerDependencies: + - supports-color + + solc@0.4.26: + dependencies: + fs-extra: 0.30.0 + memorystream: 0.3.1 + require-from-string: 1.2.1 + semver: 5.7.2 + yargs: 4.8.1 + + solc@0.6.12: + dependencies: + command-exists: 1.2.9 + commander: 3.0.2 + fs-extra: 0.30.0 + js-sha3: 0.8.0 + memorystream: 0.3.1 + require-from-string: 2.0.2 + semver: 5.7.2 + tmp: 0.0.33 + + solc@0.7.3(debug@4.3.4): + dependencies: + command-exists: 1.2.9 + commander: 3.0.2 + follow-redirects: 1.15.5(debug@4.3.4) + fs-extra: 0.30.0 + js-sha3: 0.8.0 + memorystream: 0.3.1 + require-from-string: 2.0.2 + semver: 5.7.2 + tmp: 0.0.33 + transitivePeerDependencies: + - debug + + solhint@3.4.1(typescript@4.7.4): + dependencies: + '@solidity-parser/parser': 0.16.2 + ajv: 6.12.6 + antlr4: 4.13.1 + ast-parents: 0.0.1 + chalk: 4.1.2 + commander: 10.0.1 + cosmiconfig: 8.3.6(typescript@4.7.4) + fast-diff: 1.3.0 + glob: 8.1.0 + ignore: 5.3.1 + js-yaml: 4.1.0 + lodash: 4.17.21 + pluralize: 8.0.0 + semver: 6.3.1 + strip-ansi: 6.0.1 + table: 6.8.1 + text-table: 0.2.0 + optionalDependencies: + prettier: 2.8.8 + transitivePeerDependencies: + - typescript + + solidity-coverage@0.8.3(hardhat@2.20.1(bufferutil@4.0.8)(ts-node@10.9.1(@types/node@20.11.20)(typescript@4.7.4))(typescript@4.7.4)(utf-8-validate@5.0.10)): + dependencies: + '@ethersproject/abi': 5.7.0 + '@solidity-parser/parser': 0.14.5 + chalk: 2.4.2 + death: 1.1.0 + detect-port: 1.5.1 + difflib: 0.2.4 + fs-extra: 8.1.0 + ghost-testrpc: 0.0.2 + global-modules: 2.0.0 + globby: 10.0.2 + hardhat: 2.20.1(bufferutil@4.0.8)(ts-node@10.9.1(@types/node@20.11.20)(typescript@4.7.4))(typescript@4.7.4)(utf-8-validate@5.0.10) + jsonschema: 1.4.1 + lodash: 4.17.21 + mocha: 7.1.2 + node-emoji: 1.11.0 + pify: 4.0.1 + recursive-readdir: 2.2.3 + sc-istanbul: 0.4.6 + semver: 7.6.0 + shelljs: 0.8.5 + web3-utils: 1.10.4 + transitivePeerDependencies: + - supports-color + + source-map-resolve@0.5.3: + dependencies: + atob: 2.1.2 + decode-uri-component: 0.2.2 + resolve-url: 0.2.1 + source-map-url: 0.4.1 + urix: 0.1.0 + + source-map-support@0.4.18: + dependencies: + source-map: 0.5.7 + + source-map-support@0.5.12: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map-url@0.4.1: {} + + source-map@0.2.0: + dependencies: + amdefine: 1.0.1 + optional: true + + source-map@0.5.7: {} + + source-map@0.6.1: {} + + spdx-correct@3.2.0: + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.17 + + spdx-exceptions@2.5.0: {} + + spdx-expression-parse@3.0.1: + dependencies: + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.17 + + spdx-license-ids@3.0.17: {} + + split-string@3.1.0: + dependencies: + extend-shallow: 3.0.2 + + sprintf-js@1.0.3: {} + + sshpk@1.18.0: + dependencies: + asn1: 0.2.6 + assert-plus: 1.0.0 + bcrypt-pbkdf: 1.0.2 + dashdash: 1.14.1 + ecc-jsbn: 0.1.2 + getpass: 0.1.7 + jsbn: 0.1.1 + safer-buffer: 2.1.2 + tweetnacl: 0.14.5 + + stacktrace-parser@0.1.10: + dependencies: + type-fest: 0.7.1 + + static-extend@0.1.2: + dependencies: + define-property: 0.2.5 + object-copy: 0.1.0 + + statuses@2.0.1: {} + + stream-to-pull-stream@1.7.3: + dependencies: + looper: 3.0.0 + pull-stream: 3.7.0 + + strict-uri-encode@1.1.0: {} + + string-format@2.0.0: {} + + string-width@1.0.2: + dependencies: + code-point-at: 1.1.0 + is-fullwidth-code-point: 1.0.0 + strip-ansi: 3.0.1 + + string-width@2.1.1: + dependencies: + is-fullwidth-code-point: 2.0.0 + strip-ansi: 4.0.0 + + string-width@3.1.0: + dependencies: + emoji-regex: 7.0.3 + is-fullwidth-code-point: 2.0.0 + strip-ansi: 5.2.0 + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string.prototype.trim@1.2.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.22.4 + + string.prototype.trimend@1.0.7: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.22.4 + + string.prototype.trimstart@1.0.7: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.22.4 + + string_decoder@0.10.31: {} + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + strip-ansi@3.0.1: + dependencies: + ansi-regex: 2.1.1 + + strip-ansi@4.0.0: + dependencies: + ansi-regex: 3.0.1 + + strip-ansi@5.2.0: + dependencies: + ansi-regex: 4.1.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-bom@2.0.0: + dependencies: + is-utf8: 0.2.1 + + strip-bom@3.0.0: {} + + strip-hex-prefix@1.0.0: + dependencies: + is-hex-prefixed: 1.0.0 + + strip-indent@2.0.0: {} + + strip-json-comments@2.0.1: {} + + strip-json-comments@3.1.1: {} + + supports-color@2.0.0: {} + + supports-color@3.2.3: + dependencies: + has-flag: 1.0.0 + + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + + supports-color@6.0.0: + dependencies: + has-flag: 3.0.0 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + swap-case@1.1.2: + dependencies: + lower-case: 1.1.4 + upper-case: 1.1.3 + + swarm-js@0.1.42(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + bluebird: 3.7.2 + buffer: 5.7.1 + eth-lib: 0.1.29(bufferutil@4.0.8)(utf-8-validate@5.0.10) + fs-extra: 4.0.3 + got: 11.8.6 + mime-types: 2.1.35 + mkdirp-promise: 5.0.1 + mock-fs: 4.14.0 + setimmediate: 1.0.5 + tar: 4.4.19 + xhr-request: 1.1.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + sync-request@6.1.0: + dependencies: + http-response-object: 3.0.2 + sync-rpc: 1.3.6 + then-request: 6.0.2 + + sync-rpc@1.3.6: + dependencies: + get-port: 3.2.0 + + table-layout@1.0.2: + dependencies: + array-back: 4.0.2 + deep-extend: 0.6.0 + typical: 5.2.0 + wordwrapjs: 4.0.1 + + table@6.8.1: + dependencies: + ajv: 8.12.0 + lodash.truncate: 4.4.2 + slice-ansi: 4.0.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + tape@4.17.0: + dependencies: + '@ljharb/resumer': 0.0.1 + '@ljharb/through': 2.3.12 + call-bind: 1.0.7 + deep-equal: 1.1.2 + defined: 1.0.1 + dotignore: 0.1.2 + for-each: 0.3.3 + glob: 7.2.3 + has: 1.0.4 + inherits: 2.0.4 + is-regex: 1.1.4 + minimist: 1.2.8 + mock-property: 1.0.3 + object-inspect: 1.12.3 + resolve: 1.22.8 + string.prototype.trim: 1.2.8 + + tar@4.4.19: + dependencies: + chownr: 1.1.4 + fs-minipass: 1.2.7 + minipass: 2.9.0 + minizlib: 1.3.3 + mkdirp: 0.5.6 + safe-buffer: 5.2.1 + yallist: 3.1.1 + + test-value@2.1.0: + dependencies: + array-back: 1.0.4 + typical: 2.6.1 + + testrpc@0.0.1: {} + + text-table@0.2.0: {} + + then-request@6.0.2: + dependencies: + '@types/concat-stream': 1.6.1 + '@types/form-data': 0.0.33 + '@types/node': 8.10.66 + '@types/qs': 6.9.11 + caseless: 0.12.0 + concat-stream: 1.6.2 + form-data: 2.5.1 + http-basic: 8.1.3 + http-response-object: 3.0.2 + promise: 8.3.0 + qs: 6.11.2 + + threads@1.7.0: + dependencies: + callsites: 3.1.0 + debug: 4.3.4(supports-color@8.1.1) + is-observable: 2.1.0 + observable-fns: 0.6.1 + optionalDependencies: + tiny-worker: 2.3.0 + transitivePeerDependencies: + - supports-color + + through2@2.0.5: + dependencies: + readable-stream: 2.3.8 + xtend: 4.0.2 + + timed-out@4.0.1: {} + + tiny-worker@2.3.0: + dependencies: + esm: 3.2.25 + optional: true + + title-case@2.1.1: + dependencies: + no-case: 2.3.2 + upper-case: 1.1.3 + + tmp@0.0.33: + dependencies: + os-tmpdir: 1.0.2 + + tmp@0.1.0: + dependencies: + rimraf: 2.7.1 + + to-fast-properties@1.0.3: {} + + to-object-path@0.3.0: + dependencies: + kind-of: 3.2.2 + + to-readable-stream@1.0.0: + optional: true + + to-regex-range@2.1.1: + dependencies: + is-number: 3.0.0 + repeat-string: 1.6.1 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + to-regex@3.0.2: + dependencies: + define-property: 2.0.2 + extend-shallow: 3.0.2 + regex-not: 1.0.2 + safe-regex: 1.1.0 + + toidentifier@1.0.1: {} + + tough-cookie@2.5.0: + dependencies: + psl: 1.9.0 + punycode: 2.3.1 + + tr46@0.0.3: {} + + trim-right@1.0.1: {} + + ts-command-line-args@2.5.1: + dependencies: + chalk: 4.1.2 + command-line-args: 5.2.1 + command-line-usage: 6.1.3 + string-format: 2.0.0 + + ts-essentials@1.0.4: {} + + ts-essentials@6.0.7(typescript@4.7.4): + dependencies: + typescript: 4.7.4 + + ts-essentials@7.0.3(typescript@4.7.4): + dependencies: + typescript: 4.7.4 + + ts-generator@0.1.1: + dependencies: + '@types/mkdirp': 0.5.2 + '@types/prettier': 2.7.3 + '@types/resolve': 0.0.8 + chalk: 2.4.2 + glob: 7.2.3 + mkdirp: 0.5.6 + prettier: 2.8.8 + resolve: 1.22.8 + ts-essentials: 1.0.4 + + ts-node@10.9.1(@types/node@20.11.20)(typescript@4.7.4): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.9 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 20.11.20 + acorn: 8.11.3 + acorn-walk: 8.3.2 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 4.7.4 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + + tsconfig-paths@3.15.0: + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + + tslib@1.14.1: {} + + tslib@2.4.0: {} + + tsort@0.0.1: {} + + tsutils@3.21.0(typescript@4.7.4): + dependencies: + tslib: 1.14.1 + typescript: 4.7.4 + + tunnel-agent@0.6.0: + dependencies: + safe-buffer: 5.2.1 + + tweetnacl-util@0.15.1: {} + + tweetnacl@0.14.5: {} + + tweetnacl@1.0.3: {} + + type-check@0.3.2: + dependencies: + prelude-ls: 1.1.2 + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + type-detect@4.0.8: {} + + type-fest@0.20.2: {} + + type-fest@0.21.3: {} + + type-fest@0.7.1: {} + + type-is@1.6.18: + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + + type@1.2.0: {} + + type@2.7.2: {} + + typechain@3.0.0(typescript@4.7.4): + dependencies: + command-line-args: 4.0.7 + debug: 4.3.4(supports-color@8.1.1) + fs-extra: 7.0.1 + js-sha3: 0.8.0 + lodash: 4.17.21 + ts-essentials: 6.0.7(typescript@4.7.4) + ts-generator: 0.1.1 + transitivePeerDependencies: + - supports-color + - typescript + + typechain@8.3.2(typescript@4.7.4): + dependencies: + '@types/prettier': 2.7.3 + debug: 4.3.4(supports-color@8.1.1) + fs-extra: 7.0.1 + glob: 7.1.7 + js-sha3: 0.8.0 + lodash: 4.17.21 + mkdirp: 1.0.4 + prettier: 2.8.8 + ts-command-line-args: 2.5.1 + ts-essentials: 7.0.3(typescript@4.7.4) + typescript: 4.7.4 + transitivePeerDependencies: + - supports-color + + typed-array-buffer@1.0.2: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-typed-array: 1.1.13 + + typed-array-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + + typed-array-byte-offset@1.0.2: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + + typed-array-length@1.0.5: + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + possible-typed-array-names: 1.0.0 + + typedarray-to-buffer@3.1.5: + dependencies: + is-typedarray: 1.0.0 + + typedarray@0.0.6: {} + + typescript@4.7.4: {} + + typewise-core@1.2.0: {} + + typewise@1.0.3: + dependencies: + typewise-core: 1.2.0 + + typewiselite@1.0.0: {} + + typical@2.6.1: {} + + typical@4.0.0: {} + + typical@5.2.0: {} + + uglify-js@3.17.4: + optional: true + + ultron@1.1.1: {} + + unbox-primitive@1.0.2: + dependencies: + call-bind: 1.0.7 + has-bigints: 1.0.2 + has-symbols: 1.0.3 + which-boxed-primitive: 1.0.2 + + underscore@1.13.6: {} + + underscore@1.9.1: + optional: true + + undici-types@5.26.5: {} + + undici@5.28.3: + dependencies: + '@fastify/busboy': 2.1.0 + + union-value@1.0.1: + dependencies: + arr-union: 3.1.0 + get-value: 2.0.6 + is-extendable: 0.1.1 + set-value: 2.0.1 + + universalify@0.1.2: {} + + universalify@2.0.1: {} + + unorm@1.6.0: {} + + unpipe@1.0.0: {} + + unset-value@1.0.0: + dependencies: + has-value: 0.3.1 + isobject: 3.0.1 + + upper-case-first@1.1.2: + dependencies: + upper-case: 1.1.3 + + upper-case@1.1.3: {} + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + urix@0.1.0: {} + + url-parse-lax@3.0.0: + dependencies: + prepend-http: 2.0.0 + optional: true + + url-set-query@1.0.0: {} + + url@0.11.3: + dependencies: + punycode: 1.4.1 + qs: 6.11.2 + + use@3.1.1: {} + + utf-8-validate@5.0.10: + dependencies: + node-gyp-build: 4.8.0 + + utf8@3.0.0: {} + + util-deprecate@1.0.2: {} + + util.promisify@1.1.2: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + for-each: 0.3.3 + has-proto: 1.0.3 + has-symbols: 1.0.3 + object.getownpropertydescriptors: 2.1.7 + safe-array-concat: 1.1.0 + + util@0.12.5: + dependencies: + inherits: 2.0.4 + is-arguments: 1.1.1 + is-generator-function: 1.0.10 + is-typed-array: 1.1.13 + which-typed-array: 1.1.14 + + utils-merge@1.0.1: {} + + uuid@2.0.1: {} + + uuid@3.3.2: + optional: true + + uuid@3.4.0: {} + + uuid@8.3.2: {} + + uuid@9.0.1: {} + + v8-compile-cache-lib@3.0.1: {} + + v8-compile-cache@2.4.0: {} + + validate-npm-package-license@3.0.4: + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + + varint@5.0.2: {} + + vary@1.1.2: {} + + verror@1.10.0: + dependencies: + assert-plus: 1.0.0 + core-util-is: 1.0.2 + extsprintf: 1.3.0 + + wcwidth@1.0.1: + dependencies: + defaults: 1.0.4 + + web3-bzz@1.10.0(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + '@types/node': 12.20.55 + got: 12.1.0 + swarm-js: 0.1.42(bufferutil@4.0.8)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + web3-bzz@1.10.4(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + '@types/node': 12.20.55 + got: 12.1.0 + swarm-js: 0.1.42(bufferutil@4.0.8)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + web3-bzz@1.2.11(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + '@types/node': 12.20.55 + got: 9.6.0 + swarm-js: 0.1.42(bufferutil@4.0.8)(utf-8-validate@5.0.10) + underscore: 1.9.1 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + optional: true + + web3-core-helpers@1.10.0: + dependencies: + web3-eth-iban: 1.10.0 + web3-utils: 1.10.0 + + web3-core-helpers@1.10.4: + dependencies: + web3-eth-iban: 1.10.4 + web3-utils: 1.10.4 + + web3-core-helpers@1.2.11: + dependencies: + underscore: 1.9.1 + web3-eth-iban: 1.2.11 + web3-utils: 1.2.11 + optional: true + + web3-core-method@1.10.0: + dependencies: + '@ethersproject/transactions': 5.7.0 + web3-core-helpers: 1.10.0 + web3-core-promievent: 1.10.0 + web3-core-subscriptions: 1.10.0 + web3-utils: 1.10.0 + + web3-core-method@1.10.4: + dependencies: + '@ethersproject/transactions': 5.7.0 + web3-core-helpers: 1.10.4 + web3-core-promievent: 1.10.4 + web3-core-subscriptions: 1.10.4 + web3-utils: 1.10.4 + + web3-core-method@1.2.11: + dependencies: + '@ethersproject/transactions': 5.7.0 + underscore: 1.9.1 + web3-core-helpers: 1.2.11 + web3-core-promievent: 1.2.11 + web3-core-subscriptions: 1.2.11 + web3-utils: 1.2.11 + optional: true + + web3-core-promievent@1.10.0: + dependencies: + eventemitter3: 4.0.4 + + web3-core-promievent@1.10.4: + dependencies: + eventemitter3: 4.0.4 + + web3-core-promievent@1.2.11: + dependencies: + eventemitter3: 4.0.4 + optional: true + + web3-core-requestmanager@1.10.0(encoding@0.1.13): + dependencies: + util: 0.12.5 + web3-core-helpers: 1.10.0 + web3-providers-http: 1.10.0(encoding@0.1.13) + web3-providers-ipc: 1.10.0 + web3-providers-ws: 1.10.0 + transitivePeerDependencies: + - encoding + - supports-color + + web3-core-requestmanager@1.10.4(encoding@0.1.13): + dependencies: + util: 0.12.5 + web3-core-helpers: 1.10.4 + web3-providers-http: 1.10.4(encoding@0.1.13) + web3-providers-ipc: 1.10.4 + web3-providers-ws: 1.10.4 + transitivePeerDependencies: + - encoding + - supports-color + + web3-core-requestmanager@1.2.11: + dependencies: + underscore: 1.9.1 + web3-core-helpers: 1.2.11 + web3-providers-http: 1.2.11 + web3-providers-ipc: 1.2.11 + web3-providers-ws: 1.2.11 + transitivePeerDependencies: + - supports-color + optional: true + + web3-core-subscriptions@1.10.0: + dependencies: + eventemitter3: 4.0.4 + web3-core-helpers: 1.10.0 + + web3-core-subscriptions@1.10.4: + dependencies: + eventemitter3: 4.0.4 + web3-core-helpers: 1.10.4 + + web3-core-subscriptions@1.2.11: + dependencies: + eventemitter3: 4.0.4 + underscore: 1.9.1 + web3-core-helpers: 1.2.11 + optional: true + + web3-core@1.10.0(encoding@0.1.13): + dependencies: + '@types/bn.js': 5.1.5 + '@types/node': 12.20.55 + bignumber.js: 9.1.2 + web3-core-helpers: 1.10.0 + web3-core-method: 1.10.0 + web3-core-requestmanager: 1.10.0(encoding@0.1.13) + web3-utils: 1.10.0 + transitivePeerDependencies: + - encoding + - supports-color + + web3-core@1.10.4(encoding@0.1.13): + dependencies: + '@types/bn.js': 5.1.5 + '@types/node': 12.20.55 + bignumber.js: 9.1.2 + web3-core-helpers: 1.10.4 + web3-core-method: 1.10.4 + web3-core-requestmanager: 1.10.4(encoding@0.1.13) + web3-utils: 1.10.4 + transitivePeerDependencies: + - encoding + - supports-color + + web3-core@1.2.11: + dependencies: + '@types/bn.js': 4.11.6 + '@types/node': 12.20.55 + bignumber.js: 9.1.2 + web3-core-helpers: 1.2.11 + web3-core-method: 1.2.11 + web3-core-requestmanager: 1.2.11 + web3-utils: 1.2.11 + transitivePeerDependencies: + - supports-color + optional: true + + web3-eth-abi@1.10.0: + dependencies: + '@ethersproject/abi': 5.7.0 + web3-utils: 1.10.0 + + web3-eth-abi@1.10.4: + dependencies: + '@ethersproject/abi': 5.7.0 + web3-utils: 1.10.4 + + web3-eth-abi@1.2.11: + dependencies: + '@ethersproject/abi': 5.0.0-beta.153 + underscore: 1.9.1 + web3-utils: 1.2.11 + optional: true + + web3-eth-accounts@1.10.0(encoding@0.1.13): + dependencies: + '@ethereumjs/common': 2.5.0 + '@ethereumjs/tx': 3.3.2 + eth-lib: 0.2.8 + ethereumjs-util: 7.1.5 + scrypt-js: 3.0.1 + uuid: 9.0.1 + web3-core: 1.10.0(encoding@0.1.13) + web3-core-helpers: 1.10.0 + web3-core-method: 1.10.0 + web3-utils: 1.10.0 + transitivePeerDependencies: + - encoding + - supports-color + + web3-eth-accounts@1.10.4(encoding@0.1.13): + dependencies: + '@ethereumjs/common': 2.6.5 + '@ethereumjs/tx': 3.5.2 + '@ethereumjs/util': 8.1.0 + eth-lib: 0.2.8 + scrypt-js: 3.0.1 + uuid: 9.0.1 + web3-core: 1.10.4(encoding@0.1.13) + web3-core-helpers: 1.10.4 + web3-core-method: 1.10.4 + web3-utils: 1.10.4 + transitivePeerDependencies: + - encoding + - supports-color + + web3-eth-accounts@1.2.11: + dependencies: + crypto-browserify: 3.12.0 + eth-lib: 0.2.8 + ethereumjs-common: 1.5.0 + ethereumjs-tx: 2.1.2 + scrypt-js: 3.0.1 + underscore: 1.9.1 + uuid: 3.3.2 + web3-core: 1.2.11 + web3-core-helpers: 1.2.11 + web3-core-method: 1.2.11 + web3-utils: 1.2.11 + transitivePeerDependencies: + - supports-color + optional: true + + web3-eth-contract@1.10.0(encoding@0.1.13): + dependencies: + '@types/bn.js': 5.1.5 + web3-core: 1.10.0(encoding@0.1.13) + web3-core-helpers: 1.10.0 + web3-core-method: 1.10.0 + web3-core-promievent: 1.10.0 + web3-core-subscriptions: 1.10.0 + web3-eth-abi: 1.10.0 + web3-utils: 1.10.0 + transitivePeerDependencies: + - encoding + - supports-color + + web3-eth-contract@1.10.4(encoding@0.1.13): + dependencies: + '@types/bn.js': 5.1.5 + web3-core: 1.10.4(encoding@0.1.13) + web3-core-helpers: 1.10.4 + web3-core-method: 1.10.4 + web3-core-promievent: 1.10.4 + web3-core-subscriptions: 1.10.4 + web3-eth-abi: 1.10.4 + web3-utils: 1.10.4 + transitivePeerDependencies: + - encoding + - supports-color + + web3-eth-contract@1.2.11: + dependencies: + '@types/bn.js': 4.11.6 + underscore: 1.9.1 + web3-core: 1.2.11 + web3-core-helpers: 1.2.11 + web3-core-method: 1.2.11 + web3-core-promievent: 1.2.11 + web3-core-subscriptions: 1.2.11 + web3-eth-abi: 1.2.11 + web3-utils: 1.2.11 + transitivePeerDependencies: + - supports-color + optional: true + + web3-eth-ens@1.10.0(encoding@0.1.13): + dependencies: + content-hash: 2.5.2 + eth-ens-namehash: 2.0.8 + web3-core: 1.10.0(encoding@0.1.13) + web3-core-helpers: 1.10.0 + web3-core-promievent: 1.10.0 + web3-eth-abi: 1.10.0 + web3-eth-contract: 1.10.0(encoding@0.1.13) + web3-utils: 1.10.0 + transitivePeerDependencies: + - encoding + - supports-color + + web3-eth-ens@1.10.4(encoding@0.1.13): + dependencies: + content-hash: 2.5.2 + eth-ens-namehash: 2.0.8 + web3-core: 1.10.4(encoding@0.1.13) + web3-core-helpers: 1.10.4 + web3-core-promievent: 1.10.4 + web3-eth-abi: 1.10.4 + web3-eth-contract: 1.10.4(encoding@0.1.13) + web3-utils: 1.10.4 + transitivePeerDependencies: + - encoding + - supports-color + + web3-eth-ens@1.2.11: + dependencies: + content-hash: 2.5.2 + eth-ens-namehash: 2.0.8 + underscore: 1.9.1 + web3-core: 1.2.11 + web3-core-helpers: 1.2.11 + web3-core-promievent: 1.2.11 + web3-eth-abi: 1.2.11 + web3-eth-contract: 1.2.11 + web3-utils: 1.2.11 + transitivePeerDependencies: + - supports-color + optional: true + + web3-eth-iban@1.10.0: + dependencies: + bn.js: 5.2.1 + web3-utils: 1.10.0 + + web3-eth-iban@1.10.4: + dependencies: + bn.js: 5.2.1 + web3-utils: 1.10.4 + + web3-eth-iban@1.2.11: + dependencies: + bn.js: 4.12.0 + web3-utils: 1.2.11 + optional: true + + web3-eth-personal@1.10.0(encoding@0.1.13): + dependencies: + '@types/node': 12.20.55 + web3-core: 1.10.0(encoding@0.1.13) + web3-core-helpers: 1.10.0 + web3-core-method: 1.10.0 + web3-net: 1.10.0(encoding@0.1.13) + web3-utils: 1.10.0 + transitivePeerDependencies: + - encoding + - supports-color + + web3-eth-personal@1.10.4(encoding@0.1.13): + dependencies: + '@types/node': 12.20.55 + web3-core: 1.10.4(encoding@0.1.13) + web3-core-helpers: 1.10.4 + web3-core-method: 1.10.4 + web3-net: 1.10.4(encoding@0.1.13) + web3-utils: 1.10.4 + transitivePeerDependencies: + - encoding + - supports-color + + web3-eth-personal@1.2.11: + dependencies: + '@types/node': 12.20.55 + web3-core: 1.2.11 + web3-core-helpers: 1.2.11 + web3-core-method: 1.2.11 + web3-net: 1.2.11 + web3-utils: 1.2.11 + transitivePeerDependencies: + - supports-color + optional: true + + web3-eth@1.10.0(encoding@0.1.13): + dependencies: + web3-core: 1.10.0(encoding@0.1.13) + web3-core-helpers: 1.10.0 + web3-core-method: 1.10.0 + web3-core-subscriptions: 1.10.0 + web3-eth-abi: 1.10.0 + web3-eth-accounts: 1.10.0(encoding@0.1.13) + web3-eth-contract: 1.10.0(encoding@0.1.13) + web3-eth-ens: 1.10.0(encoding@0.1.13) + web3-eth-iban: 1.10.0 + web3-eth-personal: 1.10.0(encoding@0.1.13) + web3-net: 1.10.0(encoding@0.1.13) + web3-utils: 1.10.0 + transitivePeerDependencies: + - encoding + - supports-color + + web3-eth@1.10.4(encoding@0.1.13): + dependencies: + web3-core: 1.10.4(encoding@0.1.13) + web3-core-helpers: 1.10.4 + web3-core-method: 1.10.4 + web3-core-subscriptions: 1.10.4 + web3-eth-abi: 1.10.4 + web3-eth-accounts: 1.10.4(encoding@0.1.13) + web3-eth-contract: 1.10.4(encoding@0.1.13) + web3-eth-ens: 1.10.4(encoding@0.1.13) + web3-eth-iban: 1.10.4 + web3-eth-personal: 1.10.4(encoding@0.1.13) + web3-net: 1.10.4(encoding@0.1.13) + web3-utils: 1.10.4 + transitivePeerDependencies: + - encoding + - supports-color + + web3-eth@1.2.11: + dependencies: + underscore: 1.9.1 + web3-core: 1.2.11 + web3-core-helpers: 1.2.11 + web3-core-method: 1.2.11 + web3-core-subscriptions: 1.2.11 + web3-eth-abi: 1.2.11 + web3-eth-accounts: 1.2.11 + web3-eth-contract: 1.2.11 + web3-eth-ens: 1.2.11 + web3-eth-iban: 1.2.11 + web3-eth-personal: 1.2.11 + web3-net: 1.2.11 + web3-utils: 1.2.11 + transitivePeerDependencies: + - supports-color + optional: true + + web3-net@1.10.0(encoding@0.1.13): + dependencies: + web3-core: 1.10.0(encoding@0.1.13) + web3-core-method: 1.10.0 + web3-utils: 1.10.0 + transitivePeerDependencies: + - encoding + - supports-color + + web3-net@1.10.4(encoding@0.1.13): + dependencies: + web3-core: 1.10.4(encoding@0.1.13) + web3-core-method: 1.10.4 + web3-utils: 1.10.4 + transitivePeerDependencies: + - encoding + - supports-color + + web3-net@1.2.11: + dependencies: + web3-core: 1.2.11 + web3-core-method: 1.2.11 + web3-utils: 1.2.11 + transitivePeerDependencies: + - supports-color + optional: true + + web3-provider-engine@14.2.1(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10): + dependencies: + async: 2.6.2 + backoff: 2.5.0 + clone: 2.1.2 + cross-fetch: 2.2.6(encoding@0.1.13) + eth-block-tracker: 3.0.1 + eth-json-rpc-infura: 3.2.1(encoding@0.1.13) + eth-sig-util: 1.4.2 + ethereumjs-block: 1.7.1 + ethereumjs-tx: 1.3.7 + ethereumjs-util: 5.2.1 + ethereumjs-vm: 2.6.0 + json-rpc-error: 2.0.0 + json-stable-stringify: 1.1.1 + promise-to-callback: 1.0.0 + readable-stream: 2.3.8 + request: 2.88.2 + semaphore: 1.1.0 + ws: 5.2.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + xhr: 2.6.0 + xtend: 4.0.2 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + + web3-providers-http@1.10.0(encoding@0.1.13): + dependencies: + abortcontroller-polyfill: 1.7.5 + cross-fetch: 3.1.8(encoding@0.1.13) + es6-promise: 4.2.8 + web3-core-helpers: 1.10.0 + transitivePeerDependencies: + - encoding + + web3-providers-http@1.10.4(encoding@0.1.13): + dependencies: + abortcontroller-polyfill: 1.7.5 + cross-fetch: 4.0.0(encoding@0.1.13) + es6-promise: 4.2.8 + web3-core-helpers: 1.10.4 + transitivePeerDependencies: + - encoding + + web3-providers-http@1.2.11: + dependencies: + web3-core-helpers: 1.2.11 + xhr2-cookies: 1.1.0 + optional: true + + web3-providers-ipc@1.10.0: + dependencies: + oboe: 2.1.5 + web3-core-helpers: 1.10.0 + + web3-providers-ipc@1.10.4: + dependencies: + oboe: 2.1.5 + web3-core-helpers: 1.10.4 + + web3-providers-ipc@1.2.11: + dependencies: + oboe: 2.1.4 + underscore: 1.9.1 + web3-core-helpers: 1.2.11 + optional: true + + web3-providers-ws@1.10.0: + dependencies: + eventemitter3: 4.0.4 + web3-core-helpers: 1.10.0 + websocket: 1.0.34 + transitivePeerDependencies: + - supports-color + + web3-providers-ws@1.10.4: + dependencies: + eventemitter3: 4.0.4 + web3-core-helpers: 1.10.4 + websocket: 1.0.34 + transitivePeerDependencies: + - supports-color + + web3-providers-ws@1.2.11: + dependencies: + eventemitter3: 4.0.4 + underscore: 1.9.1 + web3-core-helpers: 1.2.11 + websocket: 1.0.32 + transitivePeerDependencies: + - supports-color + optional: true + + web3-shh@1.10.0(encoding@0.1.13): + dependencies: + web3-core: 1.10.0(encoding@0.1.13) + web3-core-method: 1.10.0 + web3-core-subscriptions: 1.10.0 + web3-net: 1.10.0(encoding@0.1.13) + transitivePeerDependencies: + - encoding + - supports-color + + web3-shh@1.10.4(encoding@0.1.13): + dependencies: + web3-core: 1.10.4(encoding@0.1.13) + web3-core-method: 1.10.4 + web3-core-subscriptions: 1.10.4 + web3-net: 1.10.4(encoding@0.1.13) + transitivePeerDependencies: + - encoding + - supports-color + + web3-shh@1.2.11: + dependencies: + web3-core: 1.2.11 + web3-core-method: 1.2.11 + web3-core-subscriptions: 1.2.11 + web3-net: 1.2.11 + transitivePeerDependencies: + - supports-color + optional: true + + web3-utils@1.10.0: + dependencies: + bn.js: 5.2.1 + ethereum-bloom-filters: 1.0.10 + ethereumjs-util: 7.1.5 + ethjs-unit: 0.1.6 + number-to-bn: 1.7.0 + randombytes: 2.1.0 + utf8: 3.0.0 + + web3-utils@1.10.4: + dependencies: + '@ethereumjs/util': 8.1.0 + bn.js: 5.2.1 + ethereum-bloom-filters: 1.0.10 + ethereum-cryptography: 2.1.3 + ethjs-unit: 0.1.6 + number-to-bn: 1.7.0 + randombytes: 2.1.0 + utf8: 3.0.0 + + web3-utils@1.2.11: + dependencies: + bn.js: 4.12.0 + eth-lib: 0.2.8 + ethereum-bloom-filters: 1.0.10 + ethjs-unit: 0.1.6 + number-to-bn: 1.7.0 + randombytes: 2.1.0 + underscore: 1.9.1 + utf8: 3.0.0 + optional: true + + web3@1.10.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10): + dependencies: + web3-bzz: 1.10.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + web3-core: 1.10.0(encoding@0.1.13) + web3-eth: 1.10.0(encoding@0.1.13) + web3-eth-personal: 1.10.0(encoding@0.1.13) + web3-net: 1.10.0(encoding@0.1.13) + web3-shh: 1.10.0(encoding@0.1.13) + web3-utils: 1.10.0 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + + web3@1.10.4(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10): + dependencies: + web3-bzz: 1.10.4(bufferutil@4.0.8)(utf-8-validate@5.0.10) + web3-core: 1.10.4(encoding@0.1.13) + web3-eth: 1.10.4(encoding@0.1.13) + web3-eth-personal: 1.10.4(encoding@0.1.13) + web3-net: 1.10.4(encoding@0.1.13) + web3-shh: 1.10.4(encoding@0.1.13) + web3-utils: 1.10.4 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + + web3@1.2.11(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + web3-bzz: 1.2.11(bufferutil@4.0.8)(utf-8-validate@5.0.10) + web3-core: 1.2.11 + web3-eth: 1.2.11 + web3-eth-personal: 1.2.11 + web3-net: 1.2.11 + web3-shh: 1.2.11 + web3-utils: 1.2.11 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + optional: true + + webidl-conversions@3.0.1: {} + + websocket@1.0.32: + dependencies: + bufferutil: 4.0.8 + debug: 2.6.9 + es5-ext: 0.10.63 + typedarray-to-buffer: 3.1.5 + utf-8-validate: 5.0.10 + yaeti: 0.0.6 + transitivePeerDependencies: + - supports-color + + websocket@1.0.34: + dependencies: + bufferutil: 4.0.8 + debug: 2.6.9 + es5-ext: 0.10.63 + typedarray-to-buffer: 3.1.5 + utf-8-validate: 5.0.10 + yaeti: 0.0.6 + transitivePeerDependencies: + - supports-color + + whatwg-fetch@2.0.4: {} + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + which-boxed-primitive@1.0.2: + dependencies: + is-bigint: 1.0.4 + is-boolean-object: 1.1.2 + is-number-object: 1.0.7 + is-string: 1.0.7 + is-symbol: 1.0.4 + + which-module@1.0.0: {} + + which-module@2.0.1: {} + + which-typed-array@1.1.14: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.2 + + which@1.3.1: + dependencies: + isexe: 2.0.0 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + wide-align@1.1.3: + dependencies: + string-width: 2.1.1 + + widest-line@3.1.0: + dependencies: + string-width: 4.2.3 + + window-size@0.2.0: {} + + word-wrap@1.2.5: {} + + wordwrap@1.0.0: {} + + wordwrapjs@4.0.1: + dependencies: + reduce-flatten: 2.0.0 + typical: 5.2.0 + + workerpool@6.2.1: {} + + wrap-ansi@2.1.0: + dependencies: + string-width: 1.0.2 + strip-ansi: 3.0.1 + + wrap-ansi@5.1.0: + dependencies: + ansi-styles: 3.2.1 + string-width: 3.1.0 + strip-ansi: 5.2.0 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrappy@1.0.2: {} + + ws@3.3.3(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + async-limiter: 1.0.1 + safe-buffer: 5.1.2 + ultron: 1.1.1 + optionalDependencies: + bufferutil: 4.0.8 + utf-8-validate: 5.0.10 + + ws@5.2.3(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + async-limiter: 1.0.1 + optionalDependencies: + bufferutil: 4.0.8 + utf-8-validate: 5.0.10 + + ws@7.4.6(bufferutil@4.0.8)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.8 + utf-8-validate: 5.0.10 + + ws@7.5.9(bufferutil@4.0.8)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.8 + utf-8-validate: 5.0.10 + + ws@8.5.0(bufferutil@4.0.8)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.8 + utf-8-validate: 5.0.10 + + xhr-request-promise@0.1.3: + dependencies: + xhr-request: 1.1.0 + + xhr-request@1.1.0: + dependencies: + buffer-to-arraybuffer: 0.0.5 + object-assign: 4.1.1 + query-string: 5.1.1 + simple-get: 2.8.2 + timed-out: 4.0.1 + url-set-query: 1.0.0 + xhr: 2.6.0 + + xhr2-cookies@1.1.0: + dependencies: + cookiejar: 2.1.4 + optional: true + + xhr@2.6.0: + dependencies: + global: 4.4.0 + is-function: 1.0.2 + parse-headers: 2.0.5 + xtend: 4.0.2 + + xmlhttprequest@1.8.0: {} + + xtend@2.1.2: + dependencies: + object-keys: 0.4.0 + + xtend@4.0.2: {} + + y18n@3.2.2: {} + + y18n@4.0.3: {} + + y18n@5.0.8: {} + + yaeti@0.0.6: {} + + yallist@3.1.1: {} + + yallist@4.0.0: {} + + yaml@1.10.2: {} + + yargs-parser@13.1.2: + dependencies: + camelcase: 5.3.1 + decamelize: 1.2.0 + + yargs-parser@2.4.1: + dependencies: + camelcase: 3.0.0 + lodash.assign: 4.2.0 + + yargs-parser@20.2.4: {} + + yargs-unparser@1.6.0: + dependencies: + flat: 4.1.1 + lodash: 4.17.21 + yargs: 13.3.2 + + yargs-unparser@2.0.0: + dependencies: + camelcase: 6.3.0 + decamelize: 4.0.0 + flat: 5.0.2 + is-plain-obj: 2.1.0 + + yargs@13.3.2: + dependencies: + cliui: 5.0.0 + find-up: 3.0.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + require-main-filename: 2.0.0 + set-blocking: 2.0.0 + string-width: 3.1.0 + which-module: 2.0.1 + y18n: 4.0.3 + yargs-parser: 13.1.2 + + yargs@16.2.0: + dependencies: + cliui: 7.0.4 + escalade: 3.1.2 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 20.2.4 + + yargs@4.8.1: + dependencies: + cliui: 3.2.0 + decamelize: 1.2.0 + get-caller-file: 1.0.3 + lodash.assign: 4.2.0 + os-locale: 1.4.0 + read-pkg-up: 1.0.1 + require-directory: 2.1.1 + require-main-filename: 1.0.1 + set-blocking: 2.0.0 + string-width: 1.0.2 + which-module: 1.0.0 + window-size: 0.2.0 + y18n: 3.2.2 + yargs-parser: 2.4.1 + + yesno@0.3.1: {} + + yn@3.1.1: {} + + yocto-queue@0.1.0: {} diff --git a/packages/wallet/wallet-contracts/remappings.txt b/packages/wallet/wallet-contracts/remappings.txt new file mode 100644 index 0000000000..a1103484db --- /dev/null +++ b/packages/wallet/wallet-contracts/remappings.txt @@ -0,0 +1,3 @@ +ds-test/=lib/forge-std/lib/ds-test/src/ +forge-std-1.11.0/=dependencies/forge-std-1.11.0/ +forge-std/=lib/forge-std/src/ diff --git a/packages/wallet/wallet-contracts/run_huff_tests.sh b/packages/wallet/wallet-contracts/run_huff_tests.sh new file mode 100644 index 0000000000..53576a9d78 --- /dev/null +++ b/packages/wallet/wallet-contracts/run_huff_tests.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +for file in $(find ./src -type f -name '*.huff'); do + echo "Testing $file..." + output=$(huffc "$file" test 2>&1) + echo "$output" + + # Check for the presence of [FAIL] that is not part of another word like [PASS] + if echo "$output" | grep -E 'FAIL' > /dev/null; then + echo "Failure detected in $file" + exit 255 + else + echo "Processed $file successfully" + fi +done + +echo "All tests completed" \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/soldeer.lock b/packages/wallet/wallet-contracts/soldeer.lock new file mode 100644 index 0000000000..2072d0284f --- /dev/null +++ b/packages/wallet/wallet-contracts/soldeer.lock @@ -0,0 +1,6 @@ +[[dependencies]] +name = "forge-std" +version = "1.11.0" +url = "https://soldeer-revisions.s3.amazonaws.com/forge-std/1_11_0_09-10-2025_06:23:22_forge-std-1.11.zip" +checksum = "0290ef84c693dc9086f98f6a9b4a69dc5c2b6aa1cfe10a989bd1def1a456c099" +integrity = "84aa7d32f8c7329468cf16f31f0f74e68072e634fdbde98f3bb00c6b136103b2" diff --git a/packages/wallet/wallet-contracts/src/Errors.huff b/packages/wallet/wallet-contracts/src/Errors.huff new file mode 100644 index 0000000000..fbc60a09f6 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/Errors.huff @@ -0,0 +1,158 @@ +/// @title Errors +/// @notice SPDX-License-Identifier: MIT +/// @author jtriley.eth +/// @author clabby +/// @notice Custom error utilities. + +// https://docs.soliditylang.org/en/latest/control-structures.html?highlight=panic#panic-via-assert-and-error-via-require + +// Errors +#define error Error(string) +#define error Panic(uint256) + +// Constants +// Solidity Panic Codes +#define constant COMPILER_PANIC = 0x00 +#define constant ASSERT_FALSE = 0x01 +#define constant ARITHMETIC_OVERFLOW = 0x11 +#define constant DIVIDE_BY_ZERO = 0x12 +#define constant INVALID_ENUM_VALUE = 0x21 +#define constant INVALID_STORAGE_BYTE_ARRAY = 0x22 +#define constant EMPTY_ARRAY_POP = 0x31 +#define constant ARRAY_OUT_OF_BOUNDS = 0x32 +#define constant MEMORY_TOO_LARGE = 0x41 +#define constant UNINITIALIZED_FUNCTION_POINTER = 0x51 + +/* + +Solidity Require. Error `string` MUST be no greater than 32 bytes. + +MEMORY LAYOUT WHEN THROWN +| sig || message offset || message length || message "revert" | +0x08c379a 0000000000000000000000000000000000000000000000000000000000000020 0000000000000000000000000000000000000000000000000000000000000006 7265766572740000000000000000000000000000000000000000000000000000 + +*/ +#define macro REQUIRE() = takes (3) returns (0) { + // takes: // [condition, message_length, message] + do_not_throw // [do_not_throw_jumpdest, condition, message_length, message] + jumpi // [message_length, message] + __ERROR(Error) // [error_sig, , message_length, message] + 0x00 // [mem_ptr, error_sig, message_length, message] + mstore // [message_length, message] + 0x20 // [message_offset, message_length, message] + 0x04 // [message_offset_ptr, message_offset, message_length, message] + mstore // [message_length, message] + 0x24 // [message_length_ptr, message_length, message] + mstore // [message] + 0x44 // [message_ptr, message] + mstore // [] + 0x80 // [size] + 0x00 // [offset, size] + revert // [] + do_not_throw: // [message_length, message] + pop // [message] + pop // [] +} + +/* + +Solidity Panic. + +MEMORY LAYOUT WHEN THROWN +| sig || panic code | +0x4e487b71 0000000000000000000000000000000000000000000000000000000000000001 + +*/ +#define macro PANIC() = takes (1) returns (0) { + // takes: // [panic_code] + __ERROR(Panic) // [panic_sig, panic_code] + 0x00 // [panic_sig_offset, panic_sig, panic_code] + mstore // [panic_code] + 0x04 // [panic_code_offset, panic_code] + mstore // [] + 0x24 // [revert_size] + 0x00 // [revert_offset, revert_size] + revert // [] +} + +/* +Solidity Assert. + +MEMORY LAYOUT WHEN THROWN +| sig || assert failed panic code | +0x4e487b71 0000000000000000000000000000000000000000000000000000000000000001 + +*/ +#define macro ASSERT() = takes (1) returns (0) { + // takes: // [condition] + do_not_panic // [do_not_panic_jumpdest, condition] + jumpi // [] + [ASSERT_FALSE] // [assert_false] + PANIC() // [] + do_not_panic: // [] +} + +// Assert that two stack elements are equal +#define macro ASSERT_EQ() = { + // takes: [a, b] + eq // [a == b] + ASSERT() // [] +} + +// Assert that two stack elements are not equal +#define macro ASSERT_NOT_EQ() = { + // takes: [a, b] + eq iszero // [a != b] + ASSERT() // [] +} + +// Assert that two memory offsets contain equal words +#define macro ASSERT_MEM_EQ(ptr_a, ptr_b) = { + // takes: [] + mload // [b] + mload // [a, b] + eq // [a == b] + ASSERT() // [] +} + +// Assert that two memory offsets do not contain equal words +#define macro ASSERT_MEM_NOT_EQ(ptr_a, ptr_b) = { + // takes: [] + mload // [b] + mload // [a, b] + eq iszero // [a != b] + ASSERT() // [] +} + +// Assert that two storage slots contain equal words +#define macro ASSERT_STORAGE_EQ(slot_a, slot_b) = { + // takes: [] + sload // [b] + sload // [a, b] + eq // [a == b] + ASSERT() // [] +} + +// Assert that two storage slots do not contain equal words +#define macro ASSERT_STORAGE_NOT_EQ(slot_a, slot_b) = { + // takes: [] + sload // [b] + sload // [a, b] + eq iszero // [a != b] + ASSERT() // [] +} + +/* Bubbles up revert data if call failed. Call directly after `call`, `staticcall`, `delegatecall`. */ +#define macro BUBBLE_UP_IF_FAILED() = takes (1) returns (0) { + // takes: // [call_succeeded] + call_succeeded // [call_succeeded_jumpdest, call_succeeded] + jumpi // [] + returndatasize // [returndatasize] + 0x00 // [memory_offset, returndatasize] + returndatasize // [returndatasize, memory_offset, returndatasize] + dup2 // [returndata_offset, returndatasize, memory_offset, returndatasize] + dup3 // [memory_offset, returndata_offset, returndatasize, memory_offset, returndatasize] + returndatacopy // [memory_offset, returndatasize] + revert // [] + call_succeeded: +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/src/L2Compressor.huff b/packages/wallet/wallet-contracts/src/L2Compressor.huff new file mode 100644 index 0000000000..b5bb044353 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/L2Compressor.huff @@ -0,0 +1,140 @@ +#include "./L2CompressorLib.huff" + + +#define jumptable SELECTORS_TABLE { + execute_transaction // 0x00 + execute_many_transactions // 0x01 + read_address // 0x02 + read_bytes32 // 0x03 + sizes // 0x04 + read_storage_slots // 0x05 + decompress_transaction // 0x06 + decompress_many_transactions // 0x07 +} + +#define macro MAIN() = takes (0) returns (0) { + // Write the jump table to 0x20 + // or else the flags jumptable won't get written + // all this memory will be reused anyway + __tablesize(SELECTORS_TABLE) // [table_size] + __tablestart(SELECTORS_TABLE) // [table_start, table_size] + 0x20 // [0x20, table_start, table_size] + codecopy // [] + + callvalue // [0x00] + calldataload // [data[0x00]] + callvalue // [0x00, data[0x00]] + byte // [method] + + 0x05 // [0x05, method] + shl // [(method << 0x05)] + 0x20 add // [method + 0x20] + mload // [mload[method]] + jump // [] + + execute_transaction: + 0x01 // [rindex] + PERFORM_EXECUTE(nrfs) // [rindex] + callvalue callvalue return + + execute_many_transactions: + 0x01 // [rindex] + PERFORM_MANY_EXECUTES(nrfs) // [rindex, size, i] + callvalue callvalue return + + read_address: + PERFORM_READ_ADDRESS() + 0x20 callvalue return + + read_bytes32: + PERFORM_READ_BYTES32() + 0x20 callvalue return + + sizes: + PERFORM_READ_SIZES() + 0x20 callvalue return + + read_storage_slots: + PERFORM_READ_SLOTS() // [size] + callvalue // [0x00, size] + return + + decompress_transaction: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_FULL_EXECUTE(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + decompress_many_transactions: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_MANY_FULL_EXECUTES(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + // This will be appended at the end + // unreachable code as all the method return first + + nrfs: + FN_READ_FLAG(nrfs) +} + + + +#define macro READ_FULL_EXECUTE(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + READ_EXECUTE() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_MANY_FULL_EXECUTES(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + + LOAD_1_BYTE() // [size, rindex, windex] + callvalue // [i, size, rindex, windex] + swap2 // [rindex, size, i, windex] + + do_another: // [rindex, size, i, windex] + swap1 // [size, rindex, i, windex] + swap2 // [i, rindex, size, windex] + swap3 // [windex, rindex, size, i] + + READ_FULL_EXECUTE() // [windex, rindex, size, i] + + swap3 // [i, rindex, size, windex] + swap2 // [size, rindex, i, windex] + swap1 // [rindex, size, i, windex] + + swap2 // [i, size, rindex, windex] + 0x01 // [0x01, i, size, rindex, windex] + add // [(0x01 + i), size, rindex, windex] + swap2 // [rindex, size, (0x01 + i), windex] + + dup2 // [size, rindex, size, (0x01 + i), windex] + dup4 // [(0x01 + i), size, rindex, size, (0x01 + i), windex] + lt // [((0x01 + i) < size), rindex, size, (0x01 + i), windex] + do_another jumpi // [rindex, size, (0x01 + i), windex] + + swap1 // [size, rindex, (0x01 + i), windex] + swap3 // [windex, rindex, (0x01 + i), size] + + // output stack: [windex, rindex, (0x01 + i), size] +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/src/L2CompressorLib.huff b/packages/wallet/wallet-contracts/src/L2CompressorLib.huff new file mode 100644 index 0000000000..a5e91956f9 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/L2CompressorLib.huff @@ -0,0 +1,2562 @@ +#include "./Errors.huff" + +#define constant ADDR_BYTES_STORAGE = 0x00 +#define constant FMS = 0xa0 + +#define constant FLAG_READ_BYTES32_2_BYTES = 0x27 +#define constant FLAG_READ_ADDRESS_2_BYTES = 0x23 + +#define constant BYTES32_SMV = 0x80 +#define constant ADDRESS_SMV = 0x01 + +#define macro PERFORM_READ_SLOTS() = takes (0) returns (1) { + // input stack: [] + + 0x01 // [0x01] + dup1 // [rindex, 0x01] + callvalue // [windex, rindex, 0x01] + + read_another: + dup2 // [rindex, windex, rindex] + calldataload // [data[rindex], windex, rindex] + sload // [sload[data[rindex]], windex, rindex] + dup2 // [windex, sload[data[rindex]], windex, rindex] + mstore // [windex, rindex] + + 0x20 // [0x20, windex, rindex] + swap2 // [rindex, windex, 0x20] + dup3 // [0x20, rindex, windex, 0x20] + add // [(0x20 + rindex), windex, 0x20] + swap2 // [0x20, windex, (0x20 + rindex)] + add // [(0x20 + windex), (0x20 + rindex)] + + calldatasize // [size, (0x20 + windex), (0x20 + rindex)] + dup3 // [(0x20 + rindex), size, (0x20 + windex), (0x20 + rindex)] + lt // [((0x20 + rindex) < size), (0x20 + windex), (0x20 + rindex)] + read_another jumpi // [windex, rindex] + + pop // [rindex, 0x01] + sub // [(rindex - 0x01)] + + // output stack: [size] +} + +#define macro PERFORM_READ_SIZES() = takes (0) returns (0) { + + callvalue // [0x00] + sload // [sload[0x00]] + callvalue // [value, sload[0x00]] + mstore // [] + +} + +#define macro PERFORM_READ_ADDRESS() = takes (0) returns (0) { + + 0x01 // [0x01] + calldataload // [data[0x01]] + + [ADDRESS_SMV] // [ADDRESS_SMV, data[0x00]] + add // [(ADDRESS_SMV + data[0x00])] + sload // [sload[(ADDRESS_SMV + data[0x00])]] + + callvalue // [0x00, sload[(ADDRESS_SMV + data[0x00])]] + mstore // [] + +} + +#define macro PERFORM_READ_BYTES32() = takes (0) returns (0) { + + 0x01 // [0x01] + calldataload // [data[0x01]] + + [BYTES32_SMV] // [BYTES32_SMV, data[0x00]] + shl // [(data[0x00] << BYTES32_SMV)] + sload // [sload[(data[0x00] << BYTES32_SMV)]] + + callvalue // [0x00, sload[(data[0x00] << BYTES32_SMV)]] + mstore // [] + +} + +#define macro PERFORM_MANY_EXECUTES(nrfs) = takes (1) returns (3) { + // input stack: [rindex] + + LOAD_1_BYTE() // [size, rindex] + callvalue // [i, size, rindex] + swap2 // [rindex, size, i] + + do_another: + PERFORM_EXECUTE() // [rindex, size, i] + swap2 // [i, size, rindex] + 0x01 // [0x01, i, size, rindex] + add // [(0x01 + i), size, rindex] + swap2 // [rindex, size, (0x01 + i)] + + dup2 // [size, rindex, size, (0x01 + i)] + dup4 // [(0x01 + i), size, rindex, size, (0x01 + i)] + lt // [((0x01 + i) < size), rindex, size, (0x01 + i)] + do_another jumpi // [rindex, size, (0x01 + i)] + + // output stack: [rindex, size, i] +} + +#define macro PERFORM_EXECUTE(nrfs) = takes (1) returns (1) { + // input stack: [rindex] + + [FMS] // [windex, rindex] + READ_EXECUTE() // [windex, rindex] + + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + BACKREAD_SINGLE_VALUE() // [address, windex, rindex] + + swap1 // [windex, address, rindex] + [FMS] // [FMS, windex, address, rindex] + swap1 // [windex, FMS, address, rindex] + sub // [size, address, rindex] + + callvalue // [0x00, size, address, rindex] + swap1 // [size, 0x00, address, rindex] + [FMS] // [FMS, size, 0x00, address, rindex] + callvalue // [0x00, FMS, size, 0x00, address, rindex] + callvalue // [0x00, 0x00, FMS, size, 0x00, address, rindex] + swap5 // [address, 0x00, FMS, size, 0x00, 0x00, rindex] + gaslimit // [gasLimit, address, 0x00, FMS, size, 0x00, 0x00, rindex] + call // [success, rindex] + + // For now, pop seems safer, since it won't revert all transactions if this is a batch + // the only thing to consider is that this could difficult the gas calculation + pop // [rindex] + + // output stack: [rindex] +} + +#define macro ADDRESSES_NUM() = takes (0) returns (1) { + [ADDR_BYTES_STORAGE] sload // [packed] + 0x80 shr // [num] + + // output stack: [num] +} + +#define macro PULL_ADDRESS() = takes(0) returns (1) { + [ADDR_BYTES_STORAGE] sload // [packed] + dup1 // [packed, packed] + 0x80 shr // [num, packed] + + 0x01 add // [num + 1, packed] + swap1 // [packed, num + 1] + + // Mask packed (only want lower 128 bits) + 0xffffffffffffffffffffffffffffffff and + + dup2 // [num + 1, packed, num + 1] + 0x80 shl // [num + 1 << 0x80, packed, num + 1] + or // [nextpacked, num + 1] + + [ADDR_BYTES_STORAGE] sstore // [num + 1] + + // output stack: [num + 1] +} + +#define macro BYTES32_STORAGE_POINTER() = takes (1) returns (1) { + // input stack: [index] + 0x80 shl + // output stack: [index << 0x80] +} + +#define macro ADDRESS_STORAGE_POINTER() = takes (1) returns (1) { + // input stack: [index] + 0x01 add + // output stack: [index + 1] +} + +#define macro BYTES32_NUM() = takes (0) returns (1) { + [ADDR_BYTES_STORAGE] sload // [packed] + 0xffffffffffffffffffffffffffffffff and // [num] + + // output stack: [num] +} + +#define macro PULL_BYTES32() = takes(0) returns (1) { + [ADDR_BYTES_STORAGE] sload // [packed] + dup1 // [packed, packed] + 0xffffffffffffffffffffffffffffffff and // [num, packed] + + 0x01 add // [num + 1, packed] + swap1 // [packed, num + 1] + + 0xffffffffffffffffffffffffffffffff00000000000000000000000000000000 and // [packed, num + 1] + + dup2 // [num + 1, packed, num + 1] + or // [nextpacked, num + 1] + + [ADDR_BYTES_STORAGE] sstore // [num + 1] + + // output stack: [num + 1] +} + +#define jumptable__packed FLAG_TABLE { + FLAG_READ_POWER_OF_10_MISC // 0x00 + FLAG_READ_BYTES32_1_BYTES // 0x01 + FLAG_READ_BYTES32_2_BYTES // 0x02 + FLAG_READ_BYTES32_3_BYTES // 0x03 + FLAG_READ_BYTES32_4_BYTES // 0x04 + FLAG_READ_BYTES32_5_BYTES // 0x05 + FLAG_READ_BYTES32_6_BYTES // 0x06 + FLAG_READ_BYTES32_7_BYTES // 0x07 + FLAG_READ_BYTES32_8_BYTES // 0x08 + FLAG_READ_BYTES32_9_BYTES // 0x09 + FLAG_READ_BYTES32_10_BYTES // 0x0a + FLAG_READ_BYTES32_11_BYTES // 0x0b + FLAG_READ_BYTES32_12_BYTES // 0x0c + FLAG_READ_BYTES32_13_BYTES // 0x0d + FLAG_READ_BYTES32_14_BYTES // 0x0e + FLAG_READ_BYTES32_15_BYTES // 0x0f + FLAG_READ_BYTES32_16_BYTES // 0x10 + FLAG_READ_BYTES32_17_BYTES // 0x11 + FLAG_READ_BYTES32_18_BYTES // 0x12 + FLAG_READ_BYTES32_19_BYTES // 0x13 + FLAG_READ_BYTES32_20_BYTES // 0x14 + FLAG_READ_BYTES32_21_BYTES // 0x15 + FLAG_READ_BYTES32_22_BYTES // 0x16 + FLAG_READ_BYTES32_23_BYTES // 0x17 + FLAG_READ_BYTES32_24_BYTES // 0x18 + FLAG_READ_BYTES32_25_BYTES // 0x19 + FLAG_READ_BYTES32_26_BYTES // 0x1a + FLAG_READ_BYTES32_27_BYTES // 0x1b + FLAG_READ_BYTES32_28_BYTES // 0x1c + FLAG_READ_BYTES32_29_BYTES // 0x1d + FLAG_READ_BYTES32_30_BYTES // 0x1e + FLAG_READ_BYTES32_31_BYTES // 0x1f + FLAG_READ_BYTES32_32_BYTES // 0x20 + FLAG_SAVE_ADDRESS // 0x21 + FLAG_SAVE_BYTES32 // 0x22 + FLAG_READ_ADDRESS_2 // 0x23 + FLAG_READ_ADDRESS_3 // 0x24 + FLAG_READ_ADDRESS_4 // 0x25 + FLAG_READ_EXECUTE // 0x26 + FLAG_READ_BYTES32_2 // 0x27 + FLAG_READ_BYTES32_3 // 0x28 + FLAG_READ_BYTES32_4 // 0x29 + FLAG_READ_POW_10_MANTISSA // 0x2a + FLAG_READ_N_BYTES // 0x2b + FLAG_READ_POWER_OF_2 // 0x2c + FLAG_ABI_0_PARAM // 0x2d + FLAG_ABI_1_PARAM // 0x2e + FLAG_ABI_2_PARAMS // 0x2f + FLAG_ABI_3_PARAMS // 0x20 + FLAG_ABI_4_PARAMS // 0x31 + FLAG_ABI_5_PARAMS // 0x32 + FLAG_ABI_6_PARAMS // 0x33 + FLAG_NESTED_N_FLAGS_8 // 0x34 + FLAG_NESTED_N_FLAGS_16 // 0x35 + // start: Signature specific methods + FLAG_SIGNATURE_W0 // 0x36 + FLAG_SIGNATURE_W1 // 0x37 + FLAG_SIGNATURE_W2 // 0x38 + FLAG_SIGNATURE_W3 // 0x39 + FLAG_SIGNATURE_W4 // 0x3a + FLAG_ADDRESS_W0 // 0x3b + FLAG_ADDRESS_W1 // 0x3c + FLAG_ADDRESS_W2 // 0x3d + FLAG_ADDRESS_W3 // 0x3e + FLAG_ADDRESS_W4 // 0x4f + FLAG_NODE // 0x40 + FLAG_BRANCH // 0x41 + FLAG_SUBDIGEST // 0x42 + FLAG_NESTED // 0x43 + FLAG_DYNAMIC_SIGNATURE // 0x44 + FLAG_S_SIG_NO_CHAIN // 0x45 + FLAG_S_SIG // 0x46 + FLAG_S_L_SIG_NO_CHAIN // 0x47 + FLAG_S_L_SIG // 0x48 + FLAG_READ_CHAINED // 0x49 + FLAG_READ_CHAINED_L // 0x4a + // end: Sequence specific methods + FLAG_READ_DYNAMIC_ABI // 0x4b + FLAG_NO_OP // 0x4c + FLAG_MIRROR_FLAG // 0x4d + FLAG_COPY_CALLDATA // 0x4e + FLAG_READ_STORE_FLAG // 0x4f +} + +#define constant HIGHEST_FLAG = 0x4f +#define constant HIGHEST_FLAG_PLUS_ONE = 0x50 + +#define macro READ_FLAG() = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + end // [end, rindex, windex] + swap2 // [windex, rindex, end] + + nrfs: + FN_READ_FLAG(nrfs) // [windex, rindex] + + end: +} + +#define macro FN_READ_FLAG(nrfs) = takes (3) returns (2) { + // input stack: [windex, rindex, jump_to] + + dup2 // [rindex, windex, rindex, jump_to] + calldataload // [cdata[rindex], windex, rindex, jump_to] + callvalue byte // [flag, windex, rindex, jump_to] + + swap2 // [rindex, windex, flag, jump_to] + 0x01 add // [rindex + 1, windex, flag, jump_to] + swap2 // [flag, windex, rindex + 1, jump_to] + + dup1 // [flag, flag, windex, rindex + 1, jump_to] + [HIGHEST_FLAG] lt // [HIGHEST_FLAG < flag, flag, windex, rindex + 1, jump_to] + default jumpi // [flag, windex, rindex + 1, jump_to] + + // Starts to become cheaper to skip the loading + // after 5 times, most real world cases will have more than + // 5 times. Notice that this assumes a single READ_FLAG instance + callvalue mload no_load jumpi + __tablesize(FLAG_TABLE) // [table_size, flag, windex, rindex + 1, jump_to] + __tablestart(FLAG_TABLE) // [table_start, table_size, flag, windex, rindex + 1, jump_to] + callvalue // [0x00, table_start, table_size, flag, windex, rindex + 1, jump_to] + codecopy // [flag, windex, rindex + 1] + no_load: + + 0x01 shl // [flag << 0x01, windex, rindex + 1, jump_to] + mload // [word, windex, rindex + 1, jump_to] + 0xf0 shr // [word >> 0xf0, windex, rindex + 1, jump_to] + jump // [windex, rindex + 1, jump_to] + + FLAG_READ_POWER_OF_10_MISC: + __tablestart(POW_10_TABLE) + READ_POW_10_AND_SELF_EXECUTE() + end jump + FLAG_READ_BYTES32_1_BYTES: + READ_BYTES32(0xf8, 0x01) + end jump + FLAG_READ_BYTES32_2_BYTES: + READ_BYTES32(0xf0, 0x02) + end jump + FLAG_READ_BYTES32_3_BYTES: + READ_BYTES32(0xe8, 0x03) + end jump + FLAG_READ_BYTES32_4_BYTES: + READ_BYTES32(0xe0, 0x04) + end jump + FLAG_READ_BYTES32_5_BYTES: + READ_BYTES32(0xd8, 0x05) + end jump + FLAG_READ_BYTES32_6_BYTES: + READ_BYTES32(0xd0, 0x06) + end jump + FLAG_READ_BYTES32_7_BYTES: + READ_BYTES32(0xc8, 0x07) + end jump + FLAG_READ_BYTES32_8_BYTES: + READ_BYTES32(0xc0, 0x08) + end jump + FLAG_READ_BYTES32_9_BYTES: + READ_BYTES32(0xb8, 0x09) + end jump + FLAG_READ_BYTES32_10_BYTES: + READ_BYTES32(0xb0, 0x0a) + end jump + FLAG_READ_BYTES32_11_BYTES: + READ_BYTES32(0xa8, 0x0b) + end jump + FLAG_READ_BYTES32_12_BYTES: + READ_BYTES32(0xa0, 0x0c) + end jump + FLAG_READ_BYTES32_13_BYTES: + READ_BYTES32(0x98, 0x0d) + end jump + FLAG_READ_BYTES32_14_BYTES: + READ_BYTES32(0x90, 0x0e) + end jump + FLAG_READ_BYTES32_15_BYTES: + READ_BYTES32(0x88, 0x0f) + end jump + FLAG_READ_BYTES32_16_BYTES: + READ_BYTES32(0x80, 0x10) + end jump + FLAG_READ_BYTES32_17_BYTES: + READ_BYTES32(0x78, 0x11) + end jump + FLAG_READ_BYTES32_18_BYTES: + READ_BYTES32(0x70, 0x12) + end jump + FLAG_READ_BYTES32_19_BYTES: + READ_BYTES32(0x68, 0x13) + end jump + FLAG_READ_BYTES32_20_BYTES: + READ_BYTES32(0x60, 0x14) + end jump + FLAG_READ_BYTES32_21_BYTES: + READ_BYTES32(0x58, 0x15) + end jump + FLAG_READ_BYTES32_22_BYTES: + READ_BYTES32(0x50, 0x16) + end jump + FLAG_READ_BYTES32_23_BYTES: + READ_BYTES32(0x48, 0x17) + end jump + FLAG_READ_BYTES32_24_BYTES: + READ_BYTES32(0x40, 0x18) + end jump + FLAG_READ_BYTES32_25_BYTES: + READ_BYTES32(0x38, 0x19) + end jump + FLAG_READ_BYTES32_26_BYTES: + READ_BYTES32(0x30, 0x1a) + end jump + FLAG_READ_BYTES32_27_BYTES: + READ_BYTES32(0x28, 0x1b) + end jump + FLAG_READ_BYTES32_28_BYTES: + READ_BYTES32(0x20, 0x1c) + end jump + FLAG_READ_BYTES32_29_BYTES: + READ_BYTES32(0x18, 0x1d) + end jump + FLAG_READ_BYTES32_30_BYTES: + READ_BYTES32(0x10, 0x1e) + end jump + FLAG_READ_BYTES32_31_BYTES: + READ_BYTES32(0x08, 0x1f) + end jump + FLAG_READ_BYTES32_32_BYTES: + READ_BYTES32_WORD() + end jump + + FLAG_SAVE_ADDRESS: + SAVE_ADDRESS() + end jump + + FLAG_SAVE_BYTES32: + SAVE_BYTES32() + end jump + + FLAG_READ_ADDRESS_2: + READ_ADDRESS_STORAGE(0x02, 0xf0) + end jump + FLAG_READ_ADDRESS_3: + READ_ADDRESS_STORAGE(0x03, 0xe8) + end jump + FLAG_READ_ADDRESS_4: + READ_ADDRESS_STORAGE(0x04, 0xe0) + end jump + + FLAG_READ_EXECUTE: + READ_EXECUTE() + end jump + + FLAG_READ_BYTES32_2: + READ_BYTES32_STORAGE(0x02, 0xf0) + end jump + FLAG_READ_BYTES32_3: + READ_BYTES32_STORAGE(0x03, 0xe8) + end jump + FLAG_READ_BYTES32_4: + READ_BYTES32_STORAGE(0x04, 0xe0) + end jump // [end jump, windex, rindex + 1, jump_to] + + FLAG_READ_POW_10_MANTISSA: + __tablestart(POW_10_TABLE) + READ_POW_10_MANTISSA(0x05, 0xd8) + end jump + + FLAG_READ_N_BYTES: + READ_N_BYTES() + end jump + + FLAG_READ_POWER_OF_2: + READ_POW_2() + end jump + + FLAG_ABI_0_PARAM: + __tablestart(COMMON_4BYTES) // [table_start, windex, rindex] + READ_ABI_0() + end jump + FLAG_ABI_1_PARAM: + __tablestart(COMMON_4BYTES) // [table_start, windex, rindex] + READ_ABI_1() + end jump + FLAG_ABI_2_PARAMS: + __tablestart(COMMON_4BYTES) // [table_start, windex, rindex] + READ_ABI_2() + end jump + FLAG_ABI_3_PARAMS: + __tablestart(COMMON_4BYTES) // [table_start, windex, rindex] + READ_ABI_3() + end jump + FLAG_ABI_4_PARAMS: + __tablestart(COMMON_4BYTES) // [table_start, windex, rindex] + READ_ABI_4() + end jump + FLAG_ABI_5_PARAMS: + __tablestart(COMMON_4BYTES) // [table_start, windex, rindex] + READ_ABI_5() + end jump + FLAG_ABI_6_PARAMS: + __tablestart(COMMON_4BYTES) // [table_start, windex, rindex] + READ_ABI_6() + end jump + + FLAG_NESTED_N_FLAGS_8: + READ_NESTED_N_FLAGS_8() + end jump + FLAG_NESTED_N_FLAGS_16: + READ_NESTED_N_FLAGS_16() + end jump + + FLAG_SIGNATURE_W0: + READ_SIGNATURE_W0() + end jump + FLAG_SIGNATURE_W1: + READ_SIGNATURE_WX(0x01) + end jump + FLAG_SIGNATURE_W2: + READ_SIGNATURE_WX(0x02) + end jump + FLAG_SIGNATURE_W3: + READ_SIGNATURE_WX(0x03) + end jump + FLAG_SIGNATURE_W4: + READ_SIGNATURE_WX(0x04) + end jump + + FLAG_ADDRESS_W0: + READ_ADDRESS_W0() + end jump + FLAG_ADDRESS_W1: + READ_ADDRESS_WX(, 0x01) + end jump + FLAG_ADDRESS_W2: + READ_ADDRESS_WX(, 0x02) + end jump + FLAG_ADDRESS_W3: + READ_ADDRESS_WX(, 0x03) + end jump + FLAG_ADDRESS_W4: + READ_ADDRESS_WX(, 0x04) + end jump + + FLAG_NODE: + READ_NODE() + end jump + FLAG_BRANCH: + READ_BRANCH() + end jump + FLAG_SUBDIGEST: + READ_SUBDIGEST() + end jump + FLAG_NESTED: + READ_NESTED() + end jump + FLAG_DYNAMIC_SIGNATURE: + READ_DYNAMIC_SIGNATURE() + end jump + + FLAG_S_SIG_NO_CHAIN: + READ_SEQUENCE_SIGNATURE(, 0x02, 0x01, 0xf8) + end jump + FLAG_S_SIG: + READ_SEQUENCE_SIGNATURE(, 0x01, 0x01, 0xf8) + end jump + FLAG_S_L_SIG_NO_CHAIN: + READ_SEQUENCE_SIGNATURE(, 0x02, 0x02, 0xf0) + end jump + FLAG_S_L_SIG: + READ_SEQUENCE_SIGNATURE(, 0x01, 0x02, 0xf0) + end jump + + FLAG_READ_CHAINED: + READ_CHAINED(, 0x01, 0xf8) + end jump + FLAG_READ_CHAINED_L: + READ_CHAINED(, 0x02, 0xf0) + end jump + + FLAG_READ_DYNAMIC_ABI: + __tablestart(COMMON_4BYTES) + READ_ABI_DYNAMIC() + end jump + + FLAG_NO_OP: + end jump + FLAG_MIRROR_FLAG: + READ_MIRROR_FLAG() + end jump + FLAG_COPY_CALLDATA: + READ_COPY_CALLDATA() + end jump + FLAG_READ_STORE_FLAG: + READ_STORE_FLAG() + end jump + + default: + // The default just pushes the flag as a byte (padded to 32 bytes) + // notice that we start at 0x01 since 0x00 can be pushed with the flag 0x00 + [HIGHEST_FLAG_PLUS_ONE] // [HIGHEST_FLAG_PLUS_ONE, flag, windex, rindex, jump_to] + swap1 sub // [flag - HIGHEST_FLAG_PLUS_ONE, windex, rindex, jump_to] + dup2 // [windex, flag - HIGHEST_FLAG_PLUS_ONE, windex, rindex, jump_to] + mstore // [windex, rindex, jump_to] + 0x20 add // [windex + 0x20, rindex, jump_to] + + end: + + swap1 // [rindex, windex, jump_to] + swap2 // [jump_to, windex, rindex] + jump // [windex, rindex] + + // output stack: // [windex, rindex] +} + +#define macro READ_POW_10_MANTISSA() = takes (3) returns (2) { + // input stack: [table_start, windex, rindex] + + // The first 6 bits are exponent + + dup3 // [rindex, table_start, windex, rindex] + calldataload // [data[rindex], table_start, windex, rindex] + + 0xfa // [0xfa, data[rindex], table_start, windex, rindex] + shr // [exp, table_start, windex, rindex] + + POW_10() // [windex, rindex] + BACKREAD_SINGLE_VALUE() // [10 ** exp, windex, rindex] + + // The next 18 bits are the mantissa + + dup3 // [rindex, 10 ** exp, windex, rindex] + calldataload // [data[rindex], 10 ** exp, windex, rindex] + + 0xe8 // [0xe8, data[rindex], 10 ** exp, windex, rindex] + shr // [(data[rindex] >> 0xe8), 10 ** exp, windex, rindex] + 0x3ffff // [0x3ffff, (data[rindex] >> 0xe8), 10 ** exp, windex, rindex] + and // [mantissa, 10 ** exp, windex, rindex] + mul // [(mantissa * 10 ** exp), windex, rindex] + + dup2 // [windex, (mantissa * 10 ** exp), windex, rindex] + mstore // [windex, rindex] + + 0x20 // [0x20, windex, rindex] + add // [(0x20 + windex), rindex] + swap1 // [rindex, (0x20 + windex)] + 0x03 // [0x03, rindex, (0x20 + windex)] + add // [(0x03 + rindex), (0x20 + windex)] + swap1 // [(0x20 + windex), (0x03 + rindex)] + + // input stack: [windex, rindex] +} + +#define macro READ_POW_10_AND_SELF_EXECUTE(nrfs) = takes (3) returns (2) { + // input stack: [table_start, windex, rindex] + + swap2 // [rindex, windex, table_start] + LOAD_1_BYTE() // [exp_word, rindex, windex, table_start] + + // We didn't had any more pleace for READ_SELF_EXECUTE without expanding + // the jumptable! so it has to live here. Sorry about that. + // 10 ** 0 * N is more expensive than just reading 1 byte, + // so this wasn't useful anyway + + dup1 // [exp_word, exp_word, rindex, windex, table_start] + normal_flow jumpi // [exp_word, rindex, windex, table_start] + + // --- WARNING UGLY CODE --- + + pop // [rindex, windex, table_start] + swap2 // [table_start, windex, rindex] + pop // [windex, rindex] + + READ_SELF_EXECUTE() // [windex, rindex] + end_pow_10 jump // [windex, rindex] + + normal_flow: + + // The first bit determines if we will multiply this by + // the next byte or not, this is fine as the maximum value that we + // can represent in a word is only 10 ** 77 + dup1 // [exp_word, exp_word, rindex, windex, table_start] + 0x80 and // [not_use_mul, exp_word, rindex, windex, table_start] + swap1 // [exp_word, not_use_mul, rindex, windex, table_start] + 0x7f and // [exp, not_use_mul, rindex, windex, table_start] + + swap2 // [rindex, not_use_mul, exp_word, windex, table_start] + swap4 // [table_start, not_use_mul, exp_word, windex, rindex] + swap1 // [not_use_mul, table_start, exp_word, windex, rindex] + swap3 // [windex, table_start, exp_word, not_use_mul, rindex] + swap2 // [exp_word, table_start, windex, not_use_mul, rindex] + + POW_10() // [windex, not_use_mul, rindex] + + swap1 // [not_use_mul, windex, rindex] + + end_pow_10 jumpi // [windex, rindex] + + BACKREAD_SINGLE_VALUE() // [pow_result, windex, rindex] + swap2 // [rindex, windex, pow_result] + LOAD_1_BYTE() // [mantissa, rindex, windex, pow_result] + swap1 // [rindex, mantissa, windex, pow_result] + swap3 // [pow_result, mantissa, windex, rindex] + mul // [(pow_result * mantissa), windex, rindex] + dup2 // [windex, (pow_result * mantissa), windex, rindex] + mstore // [windex, rindex] + 0x20 // [0x20, windex, rindex] + add // [(0x20 + windex), rindex] + + end_pow_10: // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro POW_10() = takes (3) returns (1) { + // input stack: [exp, table_start, windex] + + 0x05 // [0x05, exp, table_start, windex] + shl // [exp * 0x20, table_start, windex] + + add // [(table_start + exp * 0x20), windex] + + 0x20 // [0x20, (table_start + exp * 0x20), windex] + swap1 // [(table_start + exp * 0x20), 0x20, windex] + dup3 // [windex, (table_start + exp * 0x20), 0x20, windex] + codecopy // [windex] + + 0x20 add // [windex + 0x20] + + // output stack: [windex] +} + +#define macro READ_MIRROR_FLAG(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + LOAD_DYNAMIC_SIZE(0x02, 0xf0) // [trindex, rindex, windex] + swap1 // [rindex, trindex, windex] + swap2 // [windex, trindex, rindex] + + PERFORM_NESTED_READ_FLAG() // [windex, trindex, rindex] + swap1 // [trindex, windex, rindex] + pop // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_COPY_CALLDATA() = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + LOAD_DYNAMIC_SIZE(0x02, 0xf0) // [location, rindex, windex] + swap1 // [rindex, location, windex] + + LOAD_1_BYTE() // [size, rindex, location, windex] + + dup1 // [size, size, rindex, location, windex] + swap3 // [location, size, rindex, size, windex] + dup5 // [windex, location, size, rindex, size, windex] + calldatacopy // [rindex, size, windex] + + swap2 // [windex, size, rindex] + add // [(windex + size), rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_STORE_FLAG() = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + LOAD_DYNAMIC_SIZE(0x02, 0xf0) // [trindex, rindex, windex] + + dup1 // [trindex, trindex, rindex, windex] + calldataload // [data[trindex], trindex, rindex, windex] + callvalue byte // [flag, trindex, rindex, windex] + + swap1 // [trindex, flag, rindex, windex] + 0x01 add // [trindex + 1, flag, rindex, windex] + swap1 // [flag, trindex, rindex, windex] + + // There are only two cases, either the flag + // is storing an address or storing a bytes32 + // we are going to read the next 32 bytes or the next 20 bytes + + 0x21 // [0x21, flag, trindex, rindex, windex] + eq // [(0x21 == flag), trindex, rindex, windex] + is_addr jumpi // [trindex, rindex, windex] + + // is_not_addr: + calldataload // [word, rindex, windex] + + end_if jump + is_addr: // [trindex, rindex, windex] + calldataload // [word, rindex, windex] + 0x60 shr // [word >> 0x60, rindex, windex] + + end_if: + + dup3 // [windex, word, rindex, windex] + mstore // [rindex, windex] + swap1 // [windex, rindex] + 0x20 add // [windex + 0x20, rindex] + + // output stack: [windex, rindex] +} + +#define macro PERFORM_NESTED_READ_FLAG(nrfs) = takes(0) returns (0) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + back // [back, rindex, windex] + swap2 // [windex, rindex, back] + + jump // [windex, rindex] + + back: +} + +#define macro BACKREAD_SINGLE_VALUE() = takes (1) returns (2) { + // input stack: [windex] + + 0x20 swap1 sub // [windex - 0x20] + dup1 // [windex - 0x20, windex - 0x20] + + mload // [mem[windex - 0x20], windex - 0x20] + + // output stack: [mem[windex - 0x20], windex - 0x20] +} + +#define macro READ_NESTED_N_FLAGS_8(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + LOAD_1_BYTE() // [size, rindex, windex] + + swap2 // [windex, rindex, size] + READ_NESTED_N_FLAGS() + + // output stack: [windex, rindex] +} + +#define macro READ_NESTED_N_FLAGS_16(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + LOAD_DYNAMIC_SIZE(0x02, 0xf0) // [size, rindex, windex] + + swap2 // [windex, rindex, size] + READ_NESTED_N_FLAGS() + + // output stack: [windex, rindex] +} + +#define macro READ_NESTED_N_FLAGS(nrfs) = takes (3) returns (2) { + // input stack: [windex, rindex, n] + + callvalue // [i, windex, rindex, n] + + read_more: // [i, windex, rindex, n] + + swap2 // [rindex, windex, i, n] + swap1 // [windex, rindex, i, n] + + PERFORM_NESTED_READ_FLAG() // [windex, rindex, i, n] + + swap1 // [rindex, windex, i, n] + swap2 // [i, windex, rindex, n] + + 0x01 add // [i + 1, windex, rindex, n] + + dup4 // [n, i, windex, rindex, n] + dup2 // [i, n, i, windex, rindex, n] + lt // [(i < n), i, windex, rindex, n] + + read_more jumpi // [i, windex, rindex, n] + + pop // [windex, rindex, n] + swap2 // [n, rindex, windex] + pop // [rindex, windex] + swap1 // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_CHAINED(nrfs, s_bytes, s_offset) = takes (2) returns (2) { + // input stack: [windex, rindex] + + // First we need to write the chainId sequence prefix (0x03) + WRITE_SEQUENCE_FLAG(0x03) + + // Second we need to read the number of flags we are going to read + + callvalue // [0x00, windex, rindex] + swap2 // [rindex, windex, 0x00] + + LOAD_DYNAMIC_SIZE(, ) // [size, rindex, windex, 0x00] + + swap3 // [0x00, rindex, windex, size] + swap2 // [windex, rindex, 0x00, size] + + read_more: // [windex, rindex, i, size] + + // Reserve 3 bytes of the size, and keep a copy of the windex + // one will serve as a comparation point to determine the size + // the other will be the pointer that determines where we need to store + // the size + + // Clear the memory now, that way we don't need to make it later + callvalue // [0x00, windex, rindex, i, size] + dup2 // [windex, 0x00, windex, rindex, i, size] + mstore // [windex, rindex, i, size] + + // Create copies for windex, and advance 2 of them by 3 + dup1 // [windex, windex, rindex, i, size] + 0x03 add // [windex, size_pointer, rindex, i, size] + dup1 // [windex, windex, size_pointer, rindex, i, size] + + swap3 // [rindex, windex, size_pointer, windex, i, size] + swap1 // [windex, rindex, size_pointer, prev_windex, i, size] + + PERFORM_NESTED_READ_FLAG() // [windex, rindex, size_pointer, prev_windex, i, size] + + // Calculate the size and write it at the start + + swap1 // [rindex, windex, size_pointer, prev_windex, i, size] + swap3 // [prev_windex, windex, size_pointer, rindex, i, size] + dup2 // [windex, prev_windex, windex, size_pointer, rindex, i, size] + sub // [size, windex, size_pointer, rindex, i, size] + 0xe8 shl // [size << 0xe8, windex, size_pointer, rindex, i, size] + + dup3 // [size_pointer, size, windex, size_pointer, rindex, i, size] + mload // [mload[size_pointer], size, windex, size_pointer, rindex, i, size] + or // [(mload[size_pointer] | size), windex, size_pointer, rindex, i, size] + + swap1 // [windex, (mload[size_pointer] | size), size_pointer, rindex, i, size] + swap2 // [size_pointer, (mload[size_pointer] | size), windex, rindex, i, size] + mstore // [windex, rindex, i, size] + + swap2 // [i, rindex, windex, size] + 0x01 add // [i + 1, rindex, windex, size] + swap2 // [windex, rindex, i + 1, size] + + dup4 // [size, windex, rindex, i + 1, size] + dup4 // [i + 1, size, windex, rindex, i + 1, size] + lt // [(i + 1 < size), windex, rindex, i + 1, size] + read_more jumpi // [windex, rindex, i + 1, size] + + // [windex, rindex, i + 1, size] + + swap2 // [i, rindex, windex, size] + pop // [rindex, windex, size] + swap2 // [size, windex, rindex] + pop // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_DYNAMIC_SIGNATURE(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + WRITE_SEQUENCE_FLAG(0x02) + + swap1 // [rindex, windex] + + // Read the weight, it is always 1 byte + LOAD_1_BYTE() // [weight, rindex, windex] + + dup3 // [windex, weight, rindex, windex] + mstore8 // [rindex, windex] + swap1 // [windex, rindex] + 0x01 add // [windex, rindex] + + // Read the address, use read flag as it may use a pointer + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + BACKREAD_SINGLE_VALUE() // [word, windex, rindex] + 0x60 shl // [address, windex, rindex] + + dup2 // [windex, word, windex, rindex] + mstore // [windex, rindex] + 0x14 add // [windex, rindex] + + // Now read another nested flag, as-is, but leave + // the space to demark the size + + // Clear the memory here, that way we don't need to mask it + // when we write the size + callvalue // [0x00, windex, rindex] + dup2 mstore // [windex, rindex] + + // Reserve 3 bytes for the size + dup1 // [windex, size_pointer, rindex] + 0x03 add // [windex, size_pointer, rindex] + + swap2 // [rindex, size_pointer, windex] + dup3 // [windex, rindex, size_pointer, prev_windex] + + PERFORM_NESTED_READ_FLAG() // [windex, rindex, size_pointer, prev_windex] + + // Need to go back and write the size now + + swap3 // [prev_windex, rindex, size_pointer, windex] + dup4 // [windex, prev_windex, rindex, size_pointer, windex] + sub // [size, rindex, size_pointer, windex] + + // The size is +1 since we also need to include the suffix "03" for EIP1271 + 0x01 add // [size + 1, rindex, size_pointer, windex] + + 0xe8 shl // [size << 0xe8, rindex, size_pointer, windex] + dup3 // [size_pointer, size, rindex, size_pointer, windex] + mload // [mload[size_pointer], size, rindex, size_pointer, windex] + or // [(mload[size_pointer] | size), rindex, size_pointer, windex] + swap1 // [rindex, (mload[size_pointer] | size), size_pointer, windex] + swap2 // [size_pointer, (mload[size_pointer] | size), rindex, windex] + mstore // [rindex, windex] + swap1 // [windex, rindex] + + // Write the suffix, just 03 + 0x03 // [0x03, windex, rindex] + dup2 // [windex, 0x03, windex, rindex] + mstore8 // [windex, rindex] + 0x01 add // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_SIGNATURE_W0() = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + + LOAD_1_BYTE() // [weight, rindex, windex] + + swap2 // [windex, rindex, weight] + + READ_SIGNATURE() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_SIGNATURE_WX(weight) = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + // [weight, rindex, windex] + swap2 // [windex, rindex, weight] + + READ_SIGNATURE() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_SIGNATURE() = takes (3) returns (2) { + // input stack: [windex, rindex, weight] + + WRITE_SEQUENCE_FLAG(0x00) + + // Second thing we must write is the weight, always 1 byte + + swap2 // [weight, rindex, windex] + dup3 // [windex, weight, rindex, windex] + mstore8 // [rindex, windex] + swap1 // [windex, rindex] + 0x01 add // [windex, rindex] + + // EOA signatures are always 66 bytes long + // we can just copy them + + 0x42 // [0x42, windex, rindex] + dup1 // [0x42, 0x42, windex, rindex] + + dup4 // [rindex, 0x42, 0x42, windex, rindex] + dup4 // [windex, rindex, 0x42, 0x42, windex, rindex] + calldatacopy // [0x42, windex, rindex] + + dup1 // [0x42, 0x42, windex, rindex] + swap3 // [rindex, 0x42, windex, 0x42] + add // [rindex, windex, 0x42] + swap2 // [0x42, windex, rindex] + add // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_ADDRESS_W0(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + + LOAD_1_BYTE() // [weight, rindex, windex] + + swap2 // [windex, rindex, weight] + + READ_ADDRESS() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_ADDRESS_WX(nrfs, weight) = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + // [weight, rindex, windex] + swap2 // [windex, rindex, weight] + + READ_ADDRESS() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_ADDRESS(nrfs) = takes (3) returns (2) { + // input stack: [windex, rindex, weight] + + WRITE_SEQUENCE_FLAG(0x01) + + // Second thing we must write is the weight, always 1 byte + + swap2 // [weight, rindex, windex] + dup3 // [windex, weight, rindex, windex] + mstore8 // [rindex, windex] + swap1 // [windex, rindex] + 0x01 add // [windex, rindex] + + // Addresses are always 20 bytes long + // we use a nested read flag call, since this address + // could come from storage + + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + BACKREAD_SINGLE_VALUE() // [word, windex, rindex] + 0x60 shl // [address, windex, rindex] + + dup2 // [windex, word, windex, rindex] + mstore // [windex, rindex] + + 0x14 add // [windex + 0x14, rindex] +} + +#define macro READ_NODE(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + WRITE_SEQUENCE_FLAG(0x03) + + // Now we just proceed by reading another flag + + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_BRANCH(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + WRITE_SEQUENCE_FLAG(0x04) + + // Now we just proceed by reading the branch + // the only important part is that we need to + // measure how much is written, as the branch is + // always prefixed by the size + + // Clear the memory here, that way we don't need to mask it + // when we write the size + callvalue // [0x00, windex, rindex] + dup2 mstore // [windex, rindex] + + // Reserve 3 bytes for the size + dup1 // [windex, size_pointer, rindex] + 0x03 add // [windex, size_pointer, rindex] + + swap2 // [rindex, size_pointer, windex] + dup3 // [windex, rindex, size_pointer, prev_windex] + + PERFORM_NESTED_READ_FLAG() // [windex, rindex, size_pointer, prev_windex] + + // Need to go back and write the size now + + swap3 // [prev_windex, rindex, size_pointer, windex] + dup4 // [windex, prev_windex, rindex, size_pointer, windex] + sub // [size, rindex, size_pointer, windex] + 0xe8 shl // [size << 0xe8, rindex, size_pointer, windex] + dup3 // [size_pointer, size, rindex, size_pointer, windex] + mload // [mload[size_pointer], size, rindex, size_pointer, windex] + or // [(mload[size_pointer] | size), rindex, size_pointer, windex] + swap1 // [rindex, (mload[size_pointer] | size), size_pointer, windex] + swap2 // [size_pointer, (mload[size_pointer] | size), rindex, windex] + mstore // [rindex, windex] + swap1 // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_SUBDIGEST(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + WRITE_SEQUENCE_FLAG(0x05) + + // Now we just proceed by reading another flag + + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + + +#define macro READ_NESTED(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + WRITE_SEQUENCE_FLAG(0x06) // [windex, rindex] + + // Read the weight and the threshold + // the weight is always 1 byte, the threshold uses 2 + // but in reality most Sequence wallets use 1, so this library + // only supports 1 byte for it. If the wallet is not compatible, READ_NESTED + // can't be used, and READ_N_BYTES must be used instead + + swap1 // [rindex, windex] + LOAD_1_BYTE() // [weight, rindex, windex] + swap1 // [rindex, weight, windex] + LOAD_1_BYTE() // [threshold, rindex, weight, windex] + 0xf0 shl // [threshold << 0xf0, rindex, weight, windex] + swap2 // [weight, rindex, threshold, windex] + + dup4 // [windex, weight, rindex, threshold, windex] + mstore8 // [rindex, threshold, windex] + swap2 // [windex, threshold, rindex] + 0x01 add // [windex, threshold, rindex] + swap1 // [threshold, windex, rindex] + dup2 // [windex, threshold, windex, rindex] + mstore // [windex, rindex] + 0x02 add // [windex, rindex] + + // Now we just proceed by reading the branch + // the only important part is that we need to + // measure how much is written, as the branch is + // always prefixed by the size + + // Clear the memory here, that way we don't need to mask it + // when we write the size + callvalue // [0x00, windex, rindex] + dup2 mstore // [windex, rindex] + + // Reserve 3 bytes for the size + dup1 // [windex, size_pointer, rindex] + 0x03 add // [windex, size_pointer, rindex] + + swap2 // [rindex, size_pointer, windex] + dup3 // [windex, rindex, size_pointer, prev_windex] + + PERFORM_NESTED_READ_FLAG() // [windex, rindex, size_pointer, prev_windex] + + // Need to go back and write the size now + + swap3 // [prev_windex, rindex, size_pointer, windex] + dup4 // [windex, prev_windex, rindex, size_pointer, windex] + sub // [size, rindex, size_pointer, windex] + 0xe8 shl // [size << 0xe8, rindex, size_pointer, windex] + dup3 // [size_pointer, size, rindex, size_pointer, windex] + mload // [mload[size_pointer], size, rindex, size_pointer, windex] + or // [(mload[size_pointer] | size), rindex, size_pointer, windex] + swap1 // [rindex, (mload[size_pointer] | size), size_pointer, windex] + swap2 // [size_pointer, (mload[size_pointer] | size), rindex, windex] + mstore // [rindex, windex] + swap1 // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro WRITE_SEQUENCE_FLAG(flag) = takes (2) returns (2) { + // input stack: [windex, rindex] + + // [flag, windex, rindex] + dup2 // [windex, flag, windex, rindex] + mstore8 // [windex, rindex] + 0x01 add // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_SEQUENCE_SIGNATURE(nrfs, sig_flag, size_t, offset_t) = takes (2) returns (2) { + // input stack: [windex, rindex] + + // Write the signature flag as-is + + // [sig_flag, windex, rindex] + dup2 // [windex, sig_flag, windex, rindex] + mstore8 // [windex, rindex] + 0x01 add // [windex, rindex] + + // Now read the threshold, it may be provided as 8 or 16 bits + // but we always write it using 16 + swap1 // [rindex, windex] + LOAD_DYNAMIC_SIZE(, ) // [threshold, rindex, windex] + 0xf0 shl // [threshold << 0xf0, rindex, windex] + dup3 // [windex, threshold << 0xf0, rindex, windex] + mstore // [rindex, windex] + swap1 // [windex, rindex] + 0x02 add // [windex, rindex] + + // Next read the checkpoint, using read flag is overkill here + // but we do it for the sake of simplicity + + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + BACKREAD_SINGLE_VALUE() // [checkpoint, windex, rindex] + + // The checkpoint always uses 4 bytes + 0xe0 shl // [checkpoint << 0xe0, windex, rindex] + dup2 // [windex, checkpoint, windex, rindex] + mstore // [windex, rindex] + 0x04 add // [windex, rindex] + + // Now read the rest of the tree, this is just another read flag + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_EXECUTE_STANDALONE() = takes (2) returns (2) { + skip jump + rf: + FN_READ_FLAG(rf) + skip: + READ_EXECUTE(rf) +} + +#define macro READ_EXECUTE(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + // The execution function signature of Sequence is 0x7a9a1628 + + __RIGHTPAD(0x7a9a1628) // [0x7a9a1628, windex, rindex] + dup2 // [windex, 0x7a9a1628, windex, rindex] + mstore // [windex, rindex] + 0x04 add // [windex, rindex] + + // The first value is always where do the list of transactions starts + // this is always the same, as the list of transactions is the first + // dynamic type + + 0x60 // [0x60, windex, rindex] + dup2 // [windex, 0x60, windex, rindex] + mstore // [windex, rindex] + 0x20 add // [windex, rindex] + + // Reading the nonce is the simplest one, it is just a value + + READ_NONCE() // [windex, rindex] + + // We can't know when the signature will start, since we need to + // read the list of transactions first. So we leave a copy of the pointer + // to write it later. + + swap1 // [rindex, windex] + dup2 // [windex, rindex, prev_windex] + 0x20 add // [windex, rindex, prev_windex] + + // We start reading the transactions, the macro takes care of writting the + // internal pointers for them (and the number of transactions) + + READ_TRANSACTIONS() // [windex, rindex, prev_windex] + + // The signature starts at windex - prev_windex + 0x20 + // and the pointer needs to be written to prev_windex + + swap1 // [rindex, windex, prev_windex] + swap2 // [prev_windex, windex, rindex] + dup1 // [prev_windex, prev_windex, windex, rindex] + dup3 // [windex, prev_windex, prev_windex, windex, rindex] + sub // [(windex - prev_windex), prev_windex, windex, rindex] + 0x40 add // [sig_starts, prev_windex, windex, rindex] + swap1 // [prev_windex, sig_starts, windex, rindex] + + mstore // [windex, rindex] + + // Now we can read the signature, we just read a nested flag, it can generate + // a Sequence signature. We only need to take care of the size and the padding + + 0x20 add // [windex, rindex] + swap1 // [rindex, windex] + dup2 // [windex, rindex, prev_index] + + PERFORM_NESTED_READ_FLAG() + + swap1 // [rindex, windex, prev_windex] + swap2 // [prev_windex, windex, rindex] + dup1 // [prev_windex, prev_windex, windex, rindex] + dup3 // [windex, prev_windex, prev_windex, windex, rindex] + sub // [size, prev_windex, windex, rindex] + dup1 // [size, size, prev_windex, windex, rindex] + swap2 // [prev_windex, size, size, windex, rindex] + 0x20 swap1 sub // [size_place, size, size, windex, rindex] + mstore // [size, windex, rindex] + + // Last thing is handling the padding, bytes need to be multiple of 0x20 + + callvalue // [0x00, size, windex, rindex] + dup3 // [windex, 0x00, size, windex, rindex] + mstore // [size, windex, rindex] + + 0x1f and // [size % 32, windex, rindex] + 0x20 sub // [pad_diff, windex, rindex] + 0x1f and // [pad_diff % 32, windex, rindex] + add // [(padd_diff + windex), rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_NONCE_STANDALONE() = takes (2) returns (2) { + skip jump + rf: + FN_READ_FLAG(rf) + skip: + READ_NONCE(rf) +} + +#define macro READ_NONCE(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + BACKREAD_SINGLE_VALUE() // [val, windex, rindex] + + 0x60 shl // [space, windex, rindex] + + swap2 // [rindex, windex, space] + swap1 // [windex, rindex, space] + + PERFORM_NESTED_READ_FLAG() // [windex, rindex, space] + BACKREAD_SINGLE_VALUE() // [nonce, windex, rindex, space] + + // Assume that we are reading the nonce already masked + + swap1 // [windex, nonce, rindex, space] + swap2 // [rindex, nonce, windex, space] + swap3 // [space, nonce, windex, rindex] + or // [(space | nonce), windex, rindex] + + // Now we have the compact representation of the nonce + // we can write it to memory on windex + + dup2 // [windex, (space | nonce), windex, rindex] + mstore // [windex, rindex] + + 0x20 add // [windex + 0x20, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_TRANSACTIONS_STANDALONE() = takes (2) returns (2) { + skip jump + rf: + FN_READ_FLAG(rf) + skip: + READ_TRANSACTIONS(rf) +} + +#define macro READ_TRANSACTIONS(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + dup2 // [rindex, windex, rindex] + calldataload // [mem[rindex], windex, rindex] + callvalue byte // [tx_num, windex, rindex] + swap2 // [rindex, windex, tx_num] + 0x01 add // [rindex + 1, windex, tx_num] + callvalue // [i, rindex, windex, tx_num] + + swap3 // [tx_num, rindex, windex, i] + swap2 // [windex, rindex, tx_num, i] + + // Write the number of transactions + + dup3 // [tx_num, windex, rindex, tx_num, i] + dup2 // [windex, tx_num, windex, rindex, tx_num, i] + mstore // [windex, rindex, tx_num, i] + 0x20 add // [windex + 0x20, rindex, tx_num, i] + + // Reserve 32 bytes for each tx (excluding the first one, as we already know) + // these will be used to store start of each tx + + // The first transaction will always start at 0x20 * txs + 0x20 + + dup3 // [tx_num, windex, rindex, tx_num, i] + 0x05 shl // [r_start, windex, rindex, tx_num, i] + dup1 // [r_start, r_start, windex, rindex, tx_num, i] + + dup3 // [windex, r_start, r_start, ts_index, rindex, tx_num, i] + add // [windex, r_start, ts_index, rindex, tx_num, i] + + swap3 // [rindex, r_start, ts_index, windex, tx_num, i] + dup4 // [windex, rindex, r_start, ts_index, windex, tx_num, i] + + do_tx: // [windex, rindex, pos, ts_index, windex, tx_num, i] + + // store pos for this transaction + // but keep a copy of it as it will be used again + + swap2 // [pos, rindex, windex, ts_index, windex, tx_num, i] + dup1 // [pos, pos, rindex, windex, ts_index, windex, tx_num, i] + dup5 // [ts_index, pos, pos, rindex, windex, ts_index, windex, tx_num, i] + mstore // [pos, rindex, windex, ts_index, windex, tx_num, i] + + swap3 // [ts_index, rindex, windex, pos, windex, tx_num, i] + 0x20 add // [ts_index, rindex, windex, pos, windex, tx_num, i] + + swap3 // [pos, rindex, windex, ts_index, windex, tx_num, i] + swap2 // [windex, rindex, pos, ts_index, windex, tx_num, i] + + READ_TRANSACTION() // [windex, rindex, pos, ts_index, prev_windex, tx_num, i] + + // size = windex - prev_windex + + swap4 // [prev_windex, rindex, r_start, ts_index, windex, tx_num, i] + dup5 // [windex, prev_windex, rindex, r_start, ts_index, windex, tx_num, i] + sub // [tx_i_size, rindex, r_start, ts_index, windex, tx_num, i] + + // pos = size + r_start + + swap1 // [rindex, tx_i_size, r_start, ts_index, windex, tx_num, i] + swap2 // [r_start, tx_i_size, rindex, ts_index, windex, tx_num, i] + add // [pos, rindex, ts_index, windex, tx_num, i] + + // Re-arrange the stack, we are about to loop back + + swap1 // [rindex, pos, ts_index, windex, tx_num, i] + dup4 // [windex, rindex, pos, ts_index, windex, tx_num, i] + + // Check if we have more to read + swap6 // [i, rindex, pos, ts_index, windex, tx_num, windex] + 0x01 add // [i + 1, rindex, pos, ts_index, windex, tx_num, windex] + swap6 // [windex, rindex, pos, ts_index, windex, tx_num, i] + dup7 // [i, windex, rindex, pos, ts_index, windex, tx_num, i] + + // The ts_index contains the index of the transaction x 32, we can + // easily get the i and compare it with the len of transactions to know if we must continue or not + + dup7 // [tx_num, i, windex, rindex, pos, ts_index, windex, tx_num, i] + xor do_tx jumpi // [windex, rindex, pos, ts_index, windex, tx_num, i] + + pop // [rindex, pos, ts_index, windex, tx_num, i] + swap5 // [i, pos, ts_index, windex, tx_num, rindex] + pop // [pos, ts_index, windex, tx_num, rindex] + pop // [ts_index, windex, tx_num, rindex] + pop // [windex, tx_num, rindex] + swap1 // [tx_num, windex, rindex] + pop // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_TRANSACTION_STANDALONE() = takes (2) returns (2) { + skip jump + rf: + FN_READ_FLAG(rf) + skip: + READ_TRANSACTION(rf) +} + +#define macro READ_TRANSACTION(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + // The first byte gives us information about what the transaction contains + + dup2 // [rindex, windex, rindex] + calldataload // [cdata[rindex], windex, rindex] + callvalue byte // [tflag, windex, rindex] + swap2 // [rindex, windex, tflag] + 0x01 add // [rindex + 1, windex, tflag] + swap2 // [tflag, windex, rindex + 1] + + // First bit of the flag determines if the transaction uses delegateCall + + dup1 // [tflag, tflag, windex, rindex] + 0x07 shr // [tflag >> 0x07, tflag, windex, rindex] + dup3 // [windex, tflag >> 0x07, tflag, windex, rindex] + mstore // [tflag, windex, rindex] + + swap1 // [windex, tflag, rindex] + 0x20 add // [windex + 0x20, tflag, rindex] + + // Second bit of the flag determines if the transaction uses revertOnError + + dup2 // [tflag, windex, tflag, rindex] + 0x06 shr // [tflag >> 0x06, windex, tflag, rindex] + 0x01 and // [tflag >> 0x06 & 0x01, windex, tflag, rindex] + dup2 // [windex, tflag >> 0x06 & 0x01, windex, tflag, rindex] + mstore // [windex, tflag, rindex] + + 0x20 add // [windex + 0x20, tflag, rindex] + + // Third bit of the flag determines if the transaction has a defined gasLimit + + dup2 // [tflag, windex, tflag, rindex] + 0x05 shr // [tflag >> 0x05, windex, tflag, rindex] + 0x01 and // [has_gas_limit, windex, tflag, rindex] + has_gas_limit jumpi // [windex, tflag, rindex] + + // The transaction has no gas_limit, we still need to write 0s + // to the memory and push the write index + + callvalue dup2 mstore // [windex, tflag, rindex] + 0x20 add // [windex + 0x20, tflag, rindex] + + // Re-arrange the stack so it matches the other branch + + swap1 // [tflag, windex, rindex] + swap2 // [rindex, windex, tflag] + swap1 // [windex, rindex, tflag] + + end_gas_Limit_if jump + + has_gas_limit: + + // Read advanced; this should only increase 32 bytes + // but we don't check that, buyer beware + + swap1 // [tflag, windex, rindex] + swap2 // [rindex, windex, tflag] + swap1 // [windex, rindex, tflag] + + PERFORM_NESTED_READ_FLAG() // [windex, rindex, tflag] + + end_gas_Limit_if: + + // All transactions must define an address + // this is simple, as it is just one more flag + + PERFORM_NESTED_READ_FLAG() + + // 4th bit of the flag determines if the transaction has a defined value + + dup3 // [tflag, windex, rindex, tflag] + 0x04 shr // [tflag >> 0x04, windex, rindex, tflag] + 0x01 and // [tflag >> 0x04 & 0x01, windex, rindex, tflag] + has_value jumpi // [windex, rindex, tflag] + + // The transaction has no value, we still need to write 0s + // to the memory and push the write index + + callvalue dup2 mstore // [windex, rindex, tflag] + 0x20 add // [windex + 0x20, rindex, tflag] + end_value_if jump + + has_value: + + // Read advanced; this should only increase 32 bytes + // but we don't check that, buyer beware + + PERFORM_NESTED_READ_FLAG() // [windex, rindex, tflag] + + end_value_if: + + // 1st bit determines if the transaction has data + + swap2 // [tflag, rindex, windex] + 0x01 and // [has_data, rindex, windex] + + swap1 // [rindex, has_data, windex] + swap2 // [windex, has_data, rindex] + swap1 // [has_data, windex, rindex] + + has_data jumpi // [windex, rindex] + + // The transaction has no data, we still need to write 0s + // both for the pointer and size + + // All tx strucs have the same number of parameters, so 0xc0 is always the correct + //place for the start of the bytes data + + 0xc0 // [0xc0, windex, rindex] + dup2 // [windex, 0xc0, windex, rindex] + mstore // [windex, rindex] + + 0x20 // [0x20, windex, rindex] + add // [(0x20 + windex), rindex] + callvalue // [0x00, (0x20 + windex), rindex] + dup2 // [(0x20 + windex), 0x00, (0x20 + windex), rindex] + mstore // [windex, rindex] + + 0x20 // [0x20, windex, rindex] + add // [(0x20 + windex), rindex] + + end_data_if jump + + has_data: // [windex, rindex] + + // All tx strucs have the same number of parameters, so 0xc0 is always the correct + //place for the start of the bytes data + + 0xc0 // [0xc0, windex, rindex] + dup2 // [windex, 0xc0, windex, rindex] + mstore // [windex, rindex] + 0x20 add // [windex, rindex] + + // Leave some room to store the size of the data + 0x20 add // [windex + 0x20, rindex, prev_windex] + + swap1 // [rindex, windex] + dup2 // [windex, rindex, prev_windex] + + PERFORM_NESTED_READ_FLAG() // [windex, rindex, prev_windex] + + dup3 // [prev_windex, windex, rindex, prev_windex] + dup2 // [windex, prev_windex, windex, rindex, prev_windex] + sub // [size, windex, rindex, prev_windex] + + dup1 // [size, size, windex, rindex, prev_windex] + + 0x20 // [0x20, size, size, windex, rindex, prev_windex] + dup6 // [prev_windex, 0x20, size, size, windex, rindex, prev_windex] + sub // [(prev_windex - 0x20), size, size, windex, rindex, prev_windex] + mstore // [size, windex, rindex, prev_windex] + + // Write some zeros just in case + callvalue // [0x00, size, windex, rindex, prev_windex] + dup3 // [windex, 0x00, size, windex, rindex, prev_windex] + mstore // [size, windex, rindex, prev_windex] + + // Advance the windex enough so index becomes divisible by 32 + 0x1f and // [size % 32, windex, rindex, prev_windex] + 0x20 sub // [pad_diff, windex, rindex, prev_windex] + 0x1f and // [pad_diff % 32, windex, rindex, prev_windex] + add // [windex + pad_diff, rindex, prev_windex] + + swap2 // [prev_windex, rindex, windex + pad_diff] + pop // [rindex, windex] + swap1 // [windex, rindex] + + end_data_if: +} + +#define macro READ_SELF_EXECUTE(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + // The SELF execution function signature of Sequence is 0x61c2926c + + __RIGHTPAD(0x61c2926c) // [0x61c2926c, windex, rindex] + dup2 // [windex, 0x61c2926c, windex, rindex] + mstore // [windex, rindex] + 0x04 add // [windex, rindex] + + // We need to write a single 0x20, this marks the position + // of the list of transactions. It is always the same. + 0x20 // [0x20, windex, rindex] + dup1 // [0x20, 0x20, windex, rindex] + dup3 // [windex, 0x20, 0x20, windex, rindex] + mstore // [0x20, windex, rindex] + add // [(0x20 + windex), rindex] + + // Now we can just read the list of transactions + // the macro handles all internal pointers + + READ_TRANSACTIONS() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_ABI_4_BYTES() = takes (3) returns (2) { + // input stack: [table_start, windex, rindex] + + // Ideally we don't ask for table_start as an argument, we use it as a constant directly here + // but huff has a bug, if a table is used on a macro, and the macro is used many times, it will + // create copies of the table. This increases the file size a lot (2x) so I decided to have a single + // copy of the 4 bytes table. + + swap2 // [rindex, windex, table_start] + LOAD_1_BYTE() // [index, rindex, windex, table_start] + + // The 4 bytes may be provided either as an index (1 byte) + // of the known 4bytes table, or as 00 and the real 4 bytes + // 90% of the transactions use one of the common 4bytes + + dup1 // [index, index, rindex, windex, table_start] + is_index jumpi // [index, rindex, windex, table_start] + + // is_not_index: + pop // [rindex, windex, table_start] + swap2 // [table_start, windex, rindex] + pop // [windex, rindex] + + 0x04 // [0x04, windex, rindex] + dup1 // [0x04, 0x04, windex, rindex] + dup4 // [rindex, 0x04, 0x04, windex, rindex] + dup4 // [windex, rindex, 0x04, 0x04, windex, rindex] + calldatacopy // [0x04, windex, rindex] + + swap2 // [rindex, windex, 0x04] + dup3 // [0x04, rindex, windex, 0x04] + add // [(0x04 + rindex), windex, 0x04] + swap2 // [0x04, windex, (0x04 + rindex)] + add // [(0x04 + windex), (0x04 + rindex)] + end_if jump + + is_index: // [index, rindex, windex, table_start] + 0x04 // [0x04, index, rindex, windex, table_start] + swap1 // [index, 0x04, rindex, windex, table_start] + 0x02 // [0x02, index, 0x04, rindex, windex, table_start] + shl // [(index << 0x02), 0x04, rindex, windex, table_start] + + swap1 // [0x04, (index << 0x02), rindex, windex, table_start] + swap2 // [rindex, (index << 0x02), 0x04, windex, table_start] + swap4 // [table_start, (index << 0x02), 0x04, windex, rindex] + + add // [(table_start + (index << 0x02)), 0x04, windex, rindex] + dup3 // [windex, (table_start + (index << 0x02)), 0x04, windex, rindex] + codecopy // [windex, rindex] + + 0x04 add // [windex + 0x04, rindex] + + end_if: + + // output stack: [windex, rindex] +} + +#define macro READ_ABI_0() = takes (3) returns (2) { + // input stack: [table_start, windex, rindex] + + READ_ABI_4_BYTES() + + // output stack: [windex, rindex] +} + +#define macro READ_ABI_1(nrfs) = takes (3) returns (2) { + // input stack: [table_start, windex, rindex] + + READ_ABI_4_BYTES() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_ABI_2(nrfs) = takes (3) returns (2) { + // input stack: [table_start, windex, rindex] + + READ_ABI_4_BYTES() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_ABI_3(nrfs) = takes (3) returns (2) { + // input stack: [table_start, windex, rindex] + + READ_ABI_4_BYTES() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_ABI_4(nrfs) = takes (3) returns (2) { + // input stack: [table_start, windex, rindex] + + READ_ABI_4_BYTES() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_ABI_5(nrfs) = takes (3) returns (2) { + // input stack: [table_start, windex, rindex] + + READ_ABI_4_BYTES() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_ABI_6(nrfs) = takes (3) returns (2) { + // input stack: [table_start, windex, rindex] + + READ_ABI_4_BYTES() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_ABI_DYNAMIC(nrfs) = takes(3) returns (2) { + // input stack: [table_start, windex, rindex] + + READ_ABI_4_BYTES() // [table_start, windex, rindex] + + // First byte determines the number of parameters + + dup1 // [windex, windex, rindex] + swap2 // [rindex, windex, windex] + dup1 // [rindex, rindex, windex, windex] + calldataload // [word, rindex, windex, windex] + callvalue byte // [size, rindex, windex, windex] + swap1 // [rindex, size, windex, windex] + 0x01 add // [rindex, size, windex, windex] + + // Second is a bitmap, it determines which + // parameters are dynamic and which ones are static + // notice: this limits dynamic parameters to the first 8 ones + // all other ones are automatically considered static + + dup1 // [rindex, rindex, size, windex, windex] + calldataload // [word, rindex, size, windex, windex] + callvalue byte // [d_bitmap, rindex, size, windex, windex] + swap1 // [rindex, d_bitmap, size, windex, windex] + 0x01 add // [rindex, d_bitmap, size, windex, windex] + + callvalue // [0x00, rindex, d_bitmap, size, windex] + + // We will need to have two write indexes, one for the pointers (or values) + // and another one for the data blobs. The data blobs are the actual data + // of the dynamic parameters. It starts on (windex + size * 0x20). + + dup5 // [windex, i, rindex, d_bitmap, size, windex, windex] + dup5 // [size, windex, i, rindex, d_bitmap, size, windex, windex] + 0x05 shl // [size * 0x20, windex, i, rindex, d_bitmap, size, windex, windex] + add // [bwindex, i, rindex, d_bitmap, size, windex, windex] + + read_param: // [bwindex, i, rindex, d_bitmap, size, windex, swindex] + + // We read the bitmap and determine if the param is dynamic or not + dup4 // [d_bitmap, bwindex, i, rindex, d_bitmap, size, windex, swindex] + 0x01 // [0x01, d_bitmap, bwindex, i, rindex, d_bitmap, size, windex, swindex] + dup4 // [i, 0x01, d_bitmap, bwindex, i, rindex, d_bitmap, size, windex, swindex] + shl // [(0x01 << i), d_bitmap, bwindex, i, rindex, d_bitmap, size, windex, swindex] + and // [is_dynamic, bwindex, i, rindex, d_bitmap, size, windex, swindex] + + is_dynamic jumpi // [bwindex, i, rindex, d_bitmap, size, windex, swindex] + + // is_not_dynamic: + + // The parameter is not dynamic, we just need to read one value on windex + // and we can continue + + swap2 // [rindex, i, bwindex, d_bitmap, size, windex, swindex] + swap1 // [i, rindex, bwindex, d_bitmap, size, windex, swindex] + swap5 // [windex, rindex, bwindex, d_bitmap, size, i, swindex] + + PERFORM_NESTED_READ_FLAG() // [windex, rindex, bwindex, d_bitmap, size, i, swindex] + + // We trust that we only increased windex by 0x20, and we keep iterating + swap5 // [i, rindex, bwindex, d_bitmap, size, windex, swindex] + 0x01 add // [i + 1, rindex, bwindex, d_bitmap, size, windex, swindex] + + swap1 // [rindex, i, bwindex, d_bitmap, size, windex, swindex] + swap2 // [bwindex, i, rindex, d_bitmap, size, windex, swindex] + dup5 // [size, bwindex, i, rindex, d_bitmap, size, windex, swindex] + dup3 // [i, size, bwindex, i, rindex, d_bitmap, size, windex, swindex] + lt // [(i < size), bwindex, i, rindex, d_bitmap, size, windex, swindex] + read_param jumpi // [bwindex, i, rindex, d_bitmap, size, windex, swindex] + break jump + + is_dynamic: // [bwindex, i, rindex, d_bitmap, size, windex, swindex] + + // The parameter is dynamic, we are going to write it on bwindex + // but we need to: + // - save the pointer, since there we are going to store the size + // - keep a copy of the pointer, so we can determine the size + // - pad the end result to 32 bytes + // - store in windex a pointer to bwindex + + // The data pointer should lead to bwindex - swindex + dup7 // [swindex, bwindex, i, rindex, d_bitmap, size, windex, swindex] + dup2 // [bwindex, swindex, bwindex, i, rindex, d_bitmap, size, windex, swindex] + sub // [d_pointer, bwindex, i, rindex, d_bitmap, size, windex, swindex] + dup7 // [windex, d_pointer, bwindex, i, rindex, d_bitmap, size, windex, swindex] + mstore // [bwindex, i, rindex, d_bitmap, size, windex, swindex] + swap5 // [windex, i, rindex, d_bitmap, size, bwindex, swindex] + 0x20 add // [windex + 0x20, i, rindex, d_bitmap, size, bwindex, swindex] + + dup6 // [bwindex, windex, i, rindex, d_bitmap, size, bwindex, swindex] + 0x20 add // [bwindex + 0x20, windex, i, rindex, d_bitmap, size, bwindex, swindex] + swap3 // [rindex, windex, i, bwindex, d_bitmap, size, size_b_pointer, swindex] + dup4 // [bwindex, rindex, windex, i, bwindex, d_bitmap, size, size_b_pointer, swindex] + + PERFORM_NESTED_READ_FLAG() // [bwindex, rindex, windex, i, prev_bwindex, d_bitmap, size, size_b_pointer, swindex] + + swap4 // [prev_bwindex, rindex, windex, i, bwindex, d_bitmap, size, size_b_pointer, swindex] + dup5 // [bwindex, prev_bwindex, rindex, windex, i, bwindex, d_bitmap, size, size_b_pointer, swindex] + sub // [b_size, rindex, windex, i, bwindex, d_bitmap, size, size_b_pointer, swindex] + + dup1 // [b_size, b_size, rindex, windex, i, bwindex, d_bitmap, size, size_b_pointer, swindex] + swap8 // [size_b_pointer, b_size, rindex, windex, i, bwindex, d_bitmap, size, b_size, swindex] + mstore // [rindex, windex, i, bwindex, d_bitmap, size, b_size, swindex] + + // Last we need to pad the bwindex + callvalue // [0x00, rindex, windex, i, bwindex, d_bitmap, size, b_size] + dup5 // [bwindex, 0x00, rindex, windex, i, bwindex, d_bitmap, size, b_size, swindex] + mstore // [rindex, windex, i, bwindex, d_bitmap, size, b_size, swindex] + + swap3 // [bwindex, windex, i, rindex, d_bitmap, size, b_size, swindex] + swap1 // [windex, bwindex, i, rindex, d_bitmap, size, b_size, swindex] + swap6 // [b_size, bwindex, i, rindex, d_bitmap, size, windex, swindex] + + 0x1f and // [b_size % 32, bwindex, i, rindex, d_bitmap, size, windex, swindex] + 0x20 sub // [pad_diff, bwindex, i, rindex, d_bitmap, size, windex, swindex] + 0x1f and // [pad_diff % 32, bwindex, i, rindex, d_bitmap, size, windex, swindex] + add // [bwindex, i, rindex, d_bitmap, size, windex, swindex] + + swap1 // [i, bwindex, rindex, d_bitmap, size, windex, swindex] + 0x01 add // [i + 1, bwindex, rindex, d_bitmap, size, windex, swindex] + swap1 // [bwindex, i, rindex, d_bitmap, size, windex, swindex] + + dup5 // [size, bwindex, i, rindex, d_bitmap, size, windex, swindex] + dup3 // [i, size, bwindex, i, rindex, d_bitmap, size, windex, swindex] + lt // [(i < size), bwindex, i, rindex, d_bitmap, size, windex, swindex] + read_param jumpi // [bwindex, i, rindex, d_bitmap, size, windex, swindex] + + break: + + // We have finished! we only need to clear the stack + // notice that bwindex is the windex now + swap5 // [windex, i, rindex, d_bitmap, size, bwindex, swindex] + pop // [i, rindex, d_bitmap, size, bwindex, swindex] + pop // [rindex, d_bitmap, size, bwindex, swindex] + swap4 // [swindex, d_bitmap, size, bwindex, rindex] + pop // [d_bitmap, size, bwindex, rindex] + pop // [size, bwindex, rindex] + pop // [bwindex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_BYTES32(shift_bits, read_bytes) = takes (2) returns (2) { + // input stack: [windex, rindex] + + 0x20 // [0x20, windex, rindex] + + dup3 // [rindex, 0x20, windex, rindex] + calldataload // [word, 0x20, windex, rindex] + + // Shift to the right so we only read the first bits + shr // [word >> , 0x20, windex, rindex] + + // Store on windex + dup3 // [windex, word >> , 0x20, windex, rindex] + mstore // [0x20, windex, rindex] + + add // [windex + 0x20, rindex] + + swap1 // [rindex, windex + 0x20] + add // [rindex + , windex + 0x20] + swap1 // [windex + 0x20, rindex + ] + + // output stack: [0x20 + windex, valB + rindex] +} + +#define macro READ_BYTES32_WORD() = takes (3) returns (2) { + // input stack: [windex, rindex] + + 0x20 // [0x20, windex, rindex] + dup1 // [0x20, 0x20, windex, rindex] + + dup4 // [rindex, 0x20, 0x20, windex, rindex] + calldataload // [word, 0x20, 0x20, windex, rindex] + + // Store on windex + dup4 // [windex, word >> , 0x20, 0x20, windex, rindex] + mstore // [0x20, 0x20, windex, rindex] + + swap3 // [rindex, 0x20, 0x20, windex] + add // [rindex + 0x20, 0x20, windex] + swap2 // [windex, 0x20, rindex + 0x20] + add // [windex + 0x20, rindex + 0x20] + + // output stack: [windex + 0x20, rindex + 0x20] +} + +#define macro SAVE_ADDRESS() = takes (3) returns (2) { + // input stack: [windex, rindex] + + dup2 // [rindex, windex, rindex] + calldataload // [word, windex, rindex] + + // Clean the address before storing it + // shifting it to the right by 0x60 bits + + 0x60 shr // [addr, windex, rindex] + + dup1 // [addr, addr, windex, rindex] + dup3 // [windex, addr, addr, windex, rindex] + mstore // [addr, windex, rindex] + + PULL_ADDRESS() ADDRESS_STORAGE_POINTER() sstore // [windex, rindex] + + // Add 32 bytes to windex and 20 to rindex + 0x20 add // [windex + 0x20, rindex] + swap1 // [rindex, windex + 0x20] + 0x14 add // [rindex + 0x14, windex + 0x20] + swap1 // [windex + 0x20, rindex + 0x14] + + // output stack: [windex + 0x20, rindex + 0x14] +} + +#define macro SAVE_BYTES32() = takes (3) returns (2) { + // input stack: [windex, rindex] + + dup2 // [rindex, windex, rindex] + calldataload // [word, windex, rindex] + + dup1 // [word, word, windex, rindex] + + dup3 // [windex, word, word, windex, rindex] + mstore // [word, windex, rindex] + + PULL_BYTES32() BYTES32_STORAGE_POINTER() sstore // [windex, rindex] + + // Add 32 bytes to both indexes + + 0x20 dup1 // [0x20, 0x20, windex, rindex] + swap3 // [rindex, 0x20, windex, 0x20] + add // [rindex + 0x20, 0x20, windex] + + swap2 // [windex, 0x20, rindex + 0x20] + add // [windex + 0x20, rindex + 0x20] + + // output stack: [windex + 32, rindex + 32] +} + +// Reads a stored bytes32 using a 2 to 5 bytes pointer index +#define macro READ_BYTES32_STORAGE(read_bytes, read_bits_shift) = takes (3) returns (2) { + READ_STORAGE(BYTES32_SMV, shl, , ) +} + +#define macro READ_ADDRESS_STORAGE(read_bytes, read_bits_shift) = takes (3) returns (2) { + READ_STORAGE(ADDRESS_SMV, add, , ) +} + +#define macro READ_STORAGE(smv, smc, read_bytes, read_bits_shift) = takes (3) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + + LOAD_DYNAMIC_SIZE(, ) // [index, nrindex + size, windex] + sload // [bytes32, nrindex + size, windex] + + dup3 // [windex, bytes32, nrindex + size, windex] + mstore // [nrindex + size, windex] + + swap1 // [windex, nrindex + size] + + 0x20 add // [windex + 0x20, nrindex + size] + + // output stack: [windex + 0x20, nrindex + size] +} + +#define macro READ_POW_2() = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + + LOAD_1_BYTE() // [exp, rindex, windex] + + // an exp value 0 means that the formula will be 2 ** exp - 1 + // and we need to read a second exponent + + dup1 // [exp, exp, rindex, windex] + dont_sub_1 jumpi // [exp, rindex, windex] + + //sub_1: + pop // [rindex, windex] + + LOAD_1_BYTE() // [exp, rindex, windex] + + 0x01 // [0x01, exp, rindex, windex] + dup1 // [0x01, 0x01, exp, rindex, windex] + swap2 // [exp, 0x01, 0x01, rindex, windex] + dup3 // [0x01, exp, 0x01, 0x01, rindex, windex] + + add // [(0x01 + exp), 0x01, 0x01, rindex, windex] + shl // [(0x01 << (0x01 + exp)), 0x01, rindex, windex] + sub // [((0x01 << (0x01 + exp)) - 0x01), rindex, windex] + + end_if jump + + dont_sub_1: + 0x01 // [0x01, exp, rindex, windex] + swap1 // [exp, 0x01, rindex, windex] + shl // [(0x01 << exp), rindex, windex] + + end_if: + + dup3 // [windex, (0x01 << exp), rindex, windex] + swap2 // [rindex, (0x01 << exp), windex, windex] + swap3 // [windex, (0x01 << exp), windex, rindex] + + mstore // [windex, rindex] + 0x20 add // [windex + 0x20, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_N_BYTES(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + BACKREAD_SINGLE_VALUE() // [size, windex, rindex] + + dup2 // [windex, size, windex, rindex + 1] + dup2 add // [windex + size, size, windex, rindex + 1] + swap2 // [windex, size, windex + size, rindex + 1] + + dup4 // [rindex + 1, windex, size, windex + size, rindex + 1] + dup3 // [size, rindex + 1, windex, size, windex + size, rindex + 1] + add // [rindex + 1 + size, windex, size, windex + size, rindex + 1] + swap4 // [rindex + 1, windex, size, windex + size, rindex + 1 + size] + swap1 // [windex, rindex + 1, size, windex + size, rindex + 1 + size] + + calldatacopy // [windex, rindex + 1 + size] + + // output stack: [windex + size, rindex + size] +} + +#define macro LOAD_1_BYTE() = takes (1) returns (2) { + // input stack: [rindex] + + dup1 // [rindex, rindex] + 0x01 // [0x01, rindex, rindex] + add // [(0x01 + rindex), rindex] + swap1 // [rindex, (0x01 + rindex)] + + calldataload // [data[rindex], (0x01 + rindex)] + + callvalue // [0x00, data[rindex], (0x01 + rindex)] + byte // [byte[0x00], (0x01 + rindex)] + + // output stack: [value, rindex] +} + +#define macro LOAD_DYNAMIC_SIZE(read_bytes, read_bits_shift) = takes (1) returns (2) { + // input stack: [rindex] + + dup1 // [rindex, rindex] + + add // [rindex + size, rindex] + swap1 // [rindex, rindex + size] + + calldataload // [cdata[rindex], rindex] + + // Value needs to be shifted, so we only read + // the first "size" bytes + + // [size, cdata[rindex], rindex] + shr // [cdata[rindex] >> size bits, size + rindex] + + // output stack: [cdata[rindex] >> size bits, size + rindex] +} + +#[calldata("0xb2d10eb37ef5838bb835ea71bbd4053daf8de7bd8ecdf638451a2bc966a145a899")] +#define test TEST_SAVE_BYTES32() = { + 0x01 // [rindex] + 0x20 // [windex, rindex] + + SAVE_BYTES32() // [windex, rindex] + + 0x40 eq ASSERT() // [] + 0x21 eq ASSERT() // [rindex] + + // Validate that memory was written correctly + + 0x20 mload // [mem[0x20]] () + 0xd10eb37ef5838bb835ea71bbd4053daf8de7bd8ecdf638451a2bc966a145a899 + + eq ASSERT() // [] + + // Validate that the written address is correct + 0x01 0x80 shl sload // [addr] + 0xd10eb37ef5838bb835ea71bbd4053daf8de7bd8ecdf638451a2bc966a145a899 eq ASSERT() // [] + + // Validate that the total increased to 1 + BYTES32_NUM() 0x01 eq ASSERT() // [] +} + +#[calldata("0x0201f020c002f1e0040203")] +#define test TEST_READ_BYTES32() = { + // Save 3 different bytes32 values + + 0xfe9716a384ec3b055bb8aae87323a14412cbfceb52c95324dccf071fb3f83855 + 0x0201 0x80 shl sstore + + 0xcf85e6408b0191a7ed9970e635257854b95aa7b708f485ae667e6fd467e5f45e + 0xf020c002 0x80 shl sstore + + 0xa577e893e614c9aa4b19f2369e1c177adab9fe3156970a39afc166c0f2d905ee + 0xf1e0040203 0x80 shl sstore + + // Read the first bytes32 + 0x00 // [rindex] + 0x00 // [windex, rindex] + + READ_BYTES32_STORAGE(0x02, 0xf0) // [windex, rindex] + + 0x20 eq ASSERT() // [rindex] + 0x02 eq ASSERT() // [] + + 0x00 mload 0xfe9716a384ec3b055bb8aae87323a14412cbfceb52c95324dccf071fb3f83855 eq ASSERT() // [] + + // Read the second bytes32 + 0x02 // [rindex] + 0x20 // [windex, rindex] + + READ_BYTES32_STORAGE(0x04, 0xe0) // [windex, rindex] + + 0x40 eq ASSERT() // [rindex] + 0x06 eq ASSERT() // [] + + 0x20 mload 0xcf85e6408b0191a7ed9970e635257854b95aa7b708f485ae667e6fd467e5f45e eq ASSERT() // [] + + // Read the third bytes32 + 0x06 // [rindex] + 0x10 // [windex, rindex] + + READ_BYTES32_STORAGE(0x05, 0xd8) // [windex, rindex] + + 0x30 eq ASSERT() // [rindex] + 0x0b eq ASSERT() // [] + + 0x10 mload 0xa577e893e614c9aa4b19f2369e1c177adab9fe3156970a39afc166c0f2d905ee eq ASSERT() // [] +} + +#[calldata("0x0201f020c002f1e0040203")] +#define test TEST_READ_ADDRESS() = { + // Save 3 different bytes32 values + + 0x000000000000000000000000d789f5242a537b0584893b564a8c7a4be35b9238 + 0x0201 ADDRESS_STORAGE_POINTER() sstore + + 0x000000000000000000000000d5b5127436fd875ab7c334dffb62533ba011c2d9 + 0xf020c002 ADDRESS_STORAGE_POINTER() sstore + + 0x0000000000000000000000008a745d2b92c6e02e8ed087581c63d073f98f2479 + 0xf1e0040203 ADDRESS_STORAGE_POINTER() sstore + + // Read the first bytes32 + 0x00 // [rindex] + 0x00 // [windex, rindex] + + READ_ADDRESS_STORAGE(0x02, 0xf0) // [windex, rindex] + + 0x20 eq ASSERT() // [rindex] + 0x02 eq ASSERT() // [] + + 0x00 mload 0x000000000000000000000000d789f5242a537b0584893b564a8c7a4be35b9238 eq ASSERT() // [] + + // Read the second bytes32 + 0x02 // [rindex] + 0x20 // [windex, rindex] + + READ_ADDRESS_STORAGE(0x04, 0xe0) // [windex, rindex] + + 0x40 eq ASSERT() // [rindex] + 0x06 eq ASSERT() // [] + + 0x20 mload 0x000000000000000000000000d5b5127436fd875ab7c334dffb62533ba011c2d9 eq ASSERT() // [] + + // Read the third bytes32 + 0x06 // [rindex] + 0x10 // [windex, rindex] + + READ_ADDRESS_STORAGE(0x05, 0xd8) // [windex, rindex] + + 0x30 eq ASSERT() // [rindex] + 0x0b eq ASSERT() // [] + + 0x10 mload 0x0000000000000000000000008a745d2b92c6e02e8ed087581c63d073f98f2479 eq ASSERT() // [] +} + + +#[calldata("0x000203ff00ff")] +#define test TEST_READ_POW_2() = takes (2) returns (2) { + 0x00 // [rindex] + 0x00 // [windex, rindex] + + READ_POW_2() // [windex, rindex] + + 0x20 eq ASSERT() // [rindex] + 0x02 eq ASSERT() // [] + + 0x00 mload 0x07 eq ASSERT() // [] + + 0x01 // [rindex] + 0x20 // [windex, rindex] + + READ_POW_2() // [windex, rindex] + + 0x40 eq ASSERT() // [rindex] + 0x02 eq ASSERT() // [] + + 0x20 mload 0x04 eq ASSERT() // [] + + 0x02 // [rindex] + 0x05 // [windex, rindex] + + READ_POW_2() // [windex, rindex] + + 0x25 eq ASSERT() // [rindex] + 0x03 eq ASSERT() // [] + + 0x05 mload 0x08 eq ASSERT() // [] + + 0x03 // [rindex] + 0x00 // [windex, rindex] + + READ_POW_2() // [windex, rindex] + + 0x20 eq ASSERT() // [rindex] + 0x04 eq ASSERT() // [] + + 0x00 mload 0x8000000000000000000000000000000000000000000000000000000000000000 eq ASSERT() // [] + + 0x04 // [rindex] + 0x00 // [windex, rindex] + + READ_POW_2() // [windex, rindex] + + 0x20 eq ASSERT() // [rindex] + 0x06 eq ASSERT() // [] + + 0x00 mload 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff eq ASSERT() // [] +} + +#[calldata("0xb2d10eb37ef5838bb835ea71bbd4053daf8de7bd8ecdf638451a2bc966a145a899")] +#define test TEST_LOAD_DYNAMIC_SIZE() = { + 0x00 // [rindex] + + LOAD_DYNAMIC_SIZE(0x02, 0xf0) // [val, nrindex + size] + + 0xb2d1 eq ASSERT() // [rindex] + 0x02 eq ASSERT() // [] + + 0x04 // [rindex] + + LOAD_DYNAMIC_SIZE(0x05, 0xd8) // [val, nrindex + size] + + 0x7ef5838bb8 eq ASSERT() // [rindex] + 0x09 eq ASSERT() // [] +} + +#[calldata("0x02f1f2")] +#define test TEST_READ_FLAG_2_BYTES() = { + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_FLAG() // [windex, rindex] + + 0x20 [FMS] add eq ASSERT() // [rindex] + 0x03 eq ASSERT() // [] + + [FMS] mload 0xf1f2 eq ASSERT() // [] +} + +#define test TEST_NUMS() = { + ADDRESSES_NUM() // [num] + 0x00 eq ASSERT() // [] + + PULL_ADDRESS() // [nnum] + 0x01 eq ASSERT() // [] + + ADDRESSES_NUM() // [num] + 0x01 eq ASSERT() // [] + + PULL_ADDRESS() // [nnum] + 0x02 eq ASSERT() // [] + + ADDRESSES_NUM() // [num] + 0x02 eq ASSERT() // [] + + PULL_BYTES32() // [nnum] + 0x01 eq ASSERT() // [] + + BYTES32_NUM() // [num] + 0x01 eq ASSERT() // [] + + ADDRESSES_NUM() // [num] + 0x02 eq ASSERT() // [] + + PULL_ADDRESS() // [nnum] + 0x03 eq ASSERT() // [] + + BYTES32_NUM() // [nnum] + 0x01 eq ASSERT() // [] + + PULL_BYTES32() // [nnum] + 0x02 eq ASSERT() // [] + + BYTES32_NUM() // [num] + 0x02 eq ASSERT() // [] + + ADDRESSES_NUM() // [num] + 0x03 eq ASSERT() // [] +} + +#[calldata("0xb2d10eb37ef5838bb835ea71bbd4053daf8de7bd8ecdf638451a2bc966a145a8")] +#define test TEST_FLAG_READ_BYTES32() = { + 0x01 // [rindex] + [FMS] 0x40 add // [windex, rindex] + + READ_BYTES32(0xf0, 0x02) // [windex, rindex] + + [FMS] 0x60 add eq ASSERT() // [rindex] + 0x03 eq ASSERT() // [] + + [FMS] 0x40 add mload 0xd10e eq ASSERT() // [] + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_BYTES32(0x00, 0x20) // [windex, rindex] + + [FMS] 0x20 add eq ASSERT() // [rindex] + 0x20 eq ASSERT() // [] + + [FMS] mload 0xb2d10eb37ef5838bb835ea71bbd4053daf8de7bd8ecdf638451a2bc966a145a8 eq ASSERT() // [] + + 0x00 // [rindex] + [FMS] 0x40 add // [windex, rindex] + + READ_BYTES32_WORD() // [windex, rindex] + + [FMS] 0x60 add eq ASSERT() // [rindex] + 0x20 eq ASSERT() // [] + + [FMS] 0x40 add + mload 0xb2d10eb37ef5838bb835ea71bbd4053daf8de7bd8ecdf638451a2bc966a145a8 eq ASSERT() // [] +} + +// 0xd10eb37ef5838bb835ea71bbd4053daf8de7bd8e +#[calldata("0xb2d10eb37ef5838bb835ea71bbd4053daf8de7bd8ecdf638451a2bc966a145a8")] +#define test TEST_SAVE_ADDRESS() = { + 0x01 // [rindex] + [FMS] // [windex, rindex] + + SAVE_ADDRESS() // [windex, rindex] + + [FMS] 0x20 add eq ASSERT() // [rindex] + 0x15 eq ASSERT() // [] + + // Validate that memory was written correctly + + [FMS] mload // [mem[0x20]] () + 0x000000000000000000000000d10eb37ef5838bb835ea71bbd4053daf8de7bd8e + eq ASSERT() // [] + + // Validate that the written address is correct + 0x02 sload // [addr] + 0x000000000000000000000000d10eb37ef5838bb835ea71bbd4053daf8de7bd8e + eq ASSERT() // [] + + // Validate that the total increased to 1 + ADDRESSES_NUM() 0x01 eq ASSERT() // [] +} + +#define table POW_10_TABLE { + 0x0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000003e8000000000000000000000000000000000000000000000000000000000000271000000000000000000000000000000000000000000000000000000000000186a000000000000000000000000000000000000000000000000000000000000f424000000000000000000000000000000000000000000000000000000000009896800000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000000000000000000000000000000000003b9aca0000000000000000000000000000000000000000000000000000000002540be400000000000000000000000000000000000000000000000000000000174876e800000000000000000000000000000000000000000000000000000000e8d4a51000000000000000000000000000000000000000000000000000000009184e72a00000000000000000000000000000000000000000000000000000005af3107a400000000000000000000000000000000000000000000000000000038d7ea4c68000000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000000000000000000000000000016345785d8a00000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000008ac7230489e800000000000000000000000000000000000000000000000000056bc75e2d6310000000000000000000000000000000000000000000000000003635c9adc5dea0000000000000000000000000000000000000000000000000021e19e0c9bab240000000000000000000000000000000000000000000000000152d02c7e14af680000000000000000000000000000000000000000000000000d3c21bcecceda1000000000000000000000000000000000000000000000000084595161401484a00000000000000000000000000000000000000000000000052b7d2dcc80cd2e40000000000000000000000000000000000000000000000033b2e3c9fd0803ce80000000000000000000000000000000000000000000000204fce5e3e250261100000000000000000000000000000000000000000000001431e0fae6d7217caa0000000000000000000000000000000000000000000000c9f2c9cd04674edea40000000000000000000000000000000000000000000007e37be2022c0914b268000000000000000000000000000000000000000000004ee2d6d415b85acef8100000000000000000000000000000000000000000000314dc6448d9338c15b0a00000000000000000000000000000000000000000001ed09bead87c0378d8e6400000000000000000000000000000000000000000013426172c74d822b878fe8000000000000000000000000000000000000000000c097ce7bc90715b34b9f1000000000000000000000000000000000000000000785ee10d5da46d900f436a000000000000000000000000000000000000000004b3b4ca85a86c47a098a22400000000000000000000000000000000000000002f050fe938943acc45f655680000000000000000000000000000000000000001d6329f1c35ca4bfabb9f561000000000000000000000000000000000000000125dfa371a19e6f7cb54395ca000000000000000000000000000000000000000b7abc627050305adf14a3d9e40000000000000000000000000000000000000072cb5bd86321e38cb6ce6682e8000000000000000000000000000000000000047bf19673df52e37f2410011d100000000000000000000000000000000000002cd76fe086b93ce2f768a00b22a0000000000000000000000000000000000001c06a5ec5433c60ddaa16406f5a400000000000000000000000000000000000118427b3b4a05bc8a8a4de845986800000000000000000000000000000000000af298d050e4395d69670b12b7f41000000000000000000000000000000000006d79f82328ea3da61e066ebb2f88a0000000000000000000000000000000000446c3b15f9926687d2c40534fdb5640000000000000000000000000000000002ac3a4edbbfb8014e3ba83411e915e8000000000000000000000000000000001aba4714957d300d0e549208b31adb10000000000000000000000000000000010b46c6cdd6e3e0828f4db456ff0c8ea00000000000000000000000000000000a70c3c40a64e6c51999090b65f67d92400000000000000000000000000000006867a5a867f103b2fffa5a71fba0e7b680000000000000000000000000000004140c78940f6a24fdffc78873d4490d2100000000000000000000000000000028c87cb5c89a2571ebfdcb54864ada834a00000000000000000000000000000197d4df19d605767337e9f14d3eec8920e400000000000000000000000000000fee50b7025c36a0802f236d04753d5b48e800000000000000000000000000009f4f2726179a224501d762422c946590d91000000000000000000000000000063917877cec0556b21269d695bdcbf7a87aa0000000000000000000000000003e3aeb4ae1383562f4b82261d969f7ac94ca40000000000000000000000000026e4d30eccc3215dd8f3157d27e23acbdcfe680000000000000000000000000184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000000000000000f316271c7fc3908a8bef464e3945ef7a25360a000000000000000000000000097edd871cfda3a5697758bf0e3cbb5ac5741c640000000000000000000000005ef4a74721e864761ea977768e5f518bb6891be8000000000000000000000003b58e88c75313ec9d329eaaa18fb92f75215b1710000000000000000000000025179157c93ec73e23fa32aa4f9d3bda934d8ee6a0000000000000000000000172ebad6ddc73c86d67c5faa71c245689c107950240000000000000000000000e7d34c64a9c85d4460dbbca87196b61618a4bd216800000000000000000000090e40fbeea1d3a4abc8955e946fe31cdcf66f634e10000000000000000000005a8e89d75252446eb5d5d5b1cc5edf20a1a059e10ca000000000000000000003899162693736ac531a5a58f1fbb4b746504382ca7e40000000000000000000235fadd81c2822bb3f07877973d50f28bf22a31be8ee8000000000000000000161bcca7119915b50764b4abe86529797775a5f1719510000000000000000000dd15fe86affad91249ef0eb713f39ebeaa987b6e6fd2a0000000000000000000 +} + +#define table COMMON_4BYTES { + 0x00000000a9059cbb095ea7b37ff36ab538ed173918cbafe5202ee0edfb3bdb41e2bbb158ab834bab6ea056a923b872dda68a76cc5f5755298803dbeea22cb465c89e43612da0340990411a321cff79cd223da1ba2e1a7d4df305d71939125215d0e30db0f7654176a694fc3a1a695230b6b55f25791ac94764887334c658695c441a3e704f1d48324a25d94aa454dfa9c18a84bce2b39746178979aec9807539ddd81f82a8a41c70cf557fe33d18b9129cec63924ab0d1900dcd7a6cd9627aa49149bafe672a9400dfbe4a31c6bf3262f242432ae5ab4da240c10f192e7ba6efc23e1a211aa3a008d6b347f7ded9382a00000003e9fad8eefaebafa8ae169a50e8e3370041fe00a0fa558b712e95b6c8c48fdfca000000006a80c33f627dd56a5c11d7954946e2065e83b463ca722cdcfb90b32000000008f7c1e582a32fe0a1db006a75000000010002191ce6d66ac8a0712d685d5d442296aa7368d3392ddf0ea5812fa5d754d1d29dff129979ef457901451ca64f797659d667a500032587865a6b4f379607f57c02520082d2697fc11695488758a5f34e71d92d9ddd67ba183d4e0b8f69c188e3dec8fbedc9af952d2da8066a761202a9b1d507ca120b1ff14fcbc8961c9ae442842e0e2195995c94b918de608060405174e8532505c3d98568523a0e89439bd149d05cefef39a14ce6931a000225879bfcb236415565b0454a2ab3ce558087f7a1696342966c688b4cb0ec4faa8a26e4a76726e8eda9df1519cdeb356282bfe17376b5009952eb3d7989fe34b0793b38bcdfc0f053566e02751cecc01a8c84f463e18e3cd18ca029ada03907d6b3483805550fa59f3e0c89bbb8b2c5ebeaec4997adb6f5e54063761610fcb88a802f3ccfd60b2e2d726ca4202615b44848f51610ca95bcf64e0579b177ec22895118ed436a474d474898c0f4ed31b967cb0ca6e158f8db7fd4089120491ca415bcad8201aa3f6e5110ae5312ea8e3df02124b77d239ba67a6a45156e29f6241735bbd017e8c73f7658fd86b2ecc4c44193c39bc12042d96a094a13d98d135d4c66a3ad4451a32e17de789ec9b36be47d166cbfff3b87f884e54a0b020003ad58bdd147e7ef24bad42590c8fd6ed002032587c6427474f6162b01baa2abde1ff013f11846eac55915d806f6aa658b00024a9c564a515869328dec4454b20df5298aca853828b6f06427e5b6b4af05f3fef3a352a438b81249c58bfeab2e5af9d83bb568c2c5fb02022587d586d8e0db254e5005eec2890e7527028f4af52f6a627842508c1dbd0f694584a6417ed63049105d1e9a6950d9caed120103258748d5c7e3be389d577430e0c649b780f00af49149d508e6238e1e280cae47bea8683fa88d5db3b4df1e83409a852a12e3c2998238343009a2daa6d5560f0439589c1298a06aa1e6d24d559317 +} diff --git a/packages/wallet/wallet-contracts/src/__TEMP__csfnkjajkqagwbukjfojatjegwtjmxhdL2Compressor.huff b/packages/wallet/wallet-contracts/src/__TEMP__csfnkjajkqagwbukjfojatjegwtjmxhdL2Compressor.huff new file mode 100644 index 0000000000..da1916e7d5 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/__TEMP__csfnkjajkqagwbukjfojatjegwtjmxhdL2Compressor.huff @@ -0,0 +1,142 @@ + + +#include "./L2CompressorLib.huff" + + +#define jumptable SELECTORS_TABLE { + execute_transaction // 0x00 + execute_many_transactions // 0x01 + read_address // 0x02 + read_bytes32 // 0x03 + sizes // 0x04 + read_storage_slots // 0x05 + decompress_transaction // 0x06 + decompress_many_transactions // 0x07 +} + +#define macro MAIN() = takes (0) returns (0) { + // Write the jump table to 0x20 + // or else the flags jumptable won't get written + // all this memory will be reused anyway + __tablesize(SELECTORS_TABLE) // [table_size] + __tablestart(SELECTORS_TABLE) // [table_start, table_size] + 0x20 // [0x20, table_start, table_size] + codecopy // [] + + callvalue // [0x00] + calldataload // [data[0x00]] + callvalue // [0x00, data[0x00]] + byte // [method] + + 0x05 // [0x05, method] + shl // [(method << 0x05)] + 0x20 add // [method + 0x20] + mload // [mload[method]] + jump // [] + + execute_transaction: + 0x01 // [rindex] + PERFORM_EXECUTE(nrfs) // [rindex] + callvalue callvalue return + + execute_many_transactions: + 0x01 // [rindex] + PERFORM_MANY_EXECUTES(nrfs) // [rindex, size, i] + callvalue callvalue return + + read_address: + PERFORM_READ_ADDRESS() + 0x20 callvalue return + + read_bytes32: + PERFORM_READ_BYTES32() + 0x20 callvalue return + + sizes: + PERFORM_READ_SIZES() + 0x20 callvalue return + + read_storage_slots: + PERFORM_READ_SLOTS() // [size] + callvalue // [0x00, size] + return + + decompress_transaction: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_FULL_EXECUTE(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + decompress_many_transactions: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_MANY_FULL_EXECUTES(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + // This will be appended at the end + // unreachable code as all the method return first + + nrfs: + FN_READ_FLAG(nrfs) +} + + + +#define macro READ_FULL_EXECUTE(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + READ_EXECUTE() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_MANY_FULL_EXECUTES(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + + LOAD_1_BYTE() // [size, rindex, windex] + callvalue // [i, size, rindex, windex] + swap2 // [rindex, size, i, windex] + + do_another: // [rindex, size, i, windex] + swap1 // [size, rindex, i, windex] + swap2 // [i, rindex, size, windex] + swap3 // [windex, rindex, size, i] + + READ_FULL_EXECUTE() // [windex, rindex, size, i] + + swap3 // [i, rindex, size, windex] + swap2 // [size, rindex, i, windex] + swap1 // [rindex, size, i, windex] + + swap2 // [i, size, rindex, windex] + 0x01 // [0x01, i, size, rindex, windex] + add // [(0x01 + i), size, rindex, windex] + swap2 // [rindex, size, (0x01 + i), windex] + + dup2 // [size, rindex, size, (0x01 + i), windex] + dup4 // [(0x01 + i), size, rindex, size, (0x01 + i), windex] + lt // [((0x01 + i) < size), rindex, size, (0x01 + i), windex] + do_another jumpi // [rindex, size, (0x01 + i), windex] + + swap1 // [size, rindex, (0x01 + i), windex] + swap3 // [windex, rindex, (0x01 + i), size] + + // output stack: [windex, rindex, (0x01 + i), size] +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/src/__TEMP__cvwewezvvfcuoxtlisicumgcpzqhgavjL2Compressor.huff b/packages/wallet/wallet-contracts/src/__TEMP__cvwewezvvfcuoxtlisicumgcpzqhgavjL2Compressor.huff new file mode 100644 index 0000000000..da1916e7d5 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/__TEMP__cvwewezvvfcuoxtlisicumgcpzqhgavjL2Compressor.huff @@ -0,0 +1,142 @@ + + +#include "./L2CompressorLib.huff" + + +#define jumptable SELECTORS_TABLE { + execute_transaction // 0x00 + execute_many_transactions // 0x01 + read_address // 0x02 + read_bytes32 // 0x03 + sizes // 0x04 + read_storage_slots // 0x05 + decompress_transaction // 0x06 + decompress_many_transactions // 0x07 +} + +#define macro MAIN() = takes (0) returns (0) { + // Write the jump table to 0x20 + // or else the flags jumptable won't get written + // all this memory will be reused anyway + __tablesize(SELECTORS_TABLE) // [table_size] + __tablestart(SELECTORS_TABLE) // [table_start, table_size] + 0x20 // [0x20, table_start, table_size] + codecopy // [] + + callvalue // [0x00] + calldataload // [data[0x00]] + callvalue // [0x00, data[0x00]] + byte // [method] + + 0x05 // [0x05, method] + shl // [(method << 0x05)] + 0x20 add // [method + 0x20] + mload // [mload[method]] + jump // [] + + execute_transaction: + 0x01 // [rindex] + PERFORM_EXECUTE(nrfs) // [rindex] + callvalue callvalue return + + execute_many_transactions: + 0x01 // [rindex] + PERFORM_MANY_EXECUTES(nrfs) // [rindex, size, i] + callvalue callvalue return + + read_address: + PERFORM_READ_ADDRESS() + 0x20 callvalue return + + read_bytes32: + PERFORM_READ_BYTES32() + 0x20 callvalue return + + sizes: + PERFORM_READ_SIZES() + 0x20 callvalue return + + read_storage_slots: + PERFORM_READ_SLOTS() // [size] + callvalue // [0x00, size] + return + + decompress_transaction: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_FULL_EXECUTE(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + decompress_many_transactions: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_MANY_FULL_EXECUTES(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + // This will be appended at the end + // unreachable code as all the method return first + + nrfs: + FN_READ_FLAG(nrfs) +} + + + +#define macro READ_FULL_EXECUTE(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + READ_EXECUTE() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_MANY_FULL_EXECUTES(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + + LOAD_1_BYTE() // [size, rindex, windex] + callvalue // [i, size, rindex, windex] + swap2 // [rindex, size, i, windex] + + do_another: // [rindex, size, i, windex] + swap1 // [size, rindex, i, windex] + swap2 // [i, rindex, size, windex] + swap3 // [windex, rindex, size, i] + + READ_FULL_EXECUTE() // [windex, rindex, size, i] + + swap3 // [i, rindex, size, windex] + swap2 // [size, rindex, i, windex] + swap1 // [rindex, size, i, windex] + + swap2 // [i, size, rindex, windex] + 0x01 // [0x01, i, size, rindex, windex] + add // [(0x01 + i), size, rindex, windex] + swap2 // [rindex, size, (0x01 + i), windex] + + dup2 // [size, rindex, size, (0x01 + i), windex] + dup4 // [(0x01 + i), size, rindex, size, (0x01 + i), windex] + lt // [((0x01 + i) < size), rindex, size, (0x01 + i), windex] + do_another jumpi // [rindex, size, (0x01 + i), windex] + + swap1 // [size, rindex, (0x01 + i), windex] + swap3 // [windex, rindex, (0x01 + i), size] + + // output stack: [windex, rindex, (0x01 + i), size] +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/src/__TEMP__cvyihdgegfauooldcwyvlordhurwepivL2Compressor.huff b/packages/wallet/wallet-contracts/src/__TEMP__cvyihdgegfauooldcwyvlordhurwepivL2Compressor.huff new file mode 100644 index 0000000000..da1916e7d5 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/__TEMP__cvyihdgegfauooldcwyvlordhurwepivL2Compressor.huff @@ -0,0 +1,142 @@ + + +#include "./L2CompressorLib.huff" + + +#define jumptable SELECTORS_TABLE { + execute_transaction // 0x00 + execute_many_transactions // 0x01 + read_address // 0x02 + read_bytes32 // 0x03 + sizes // 0x04 + read_storage_slots // 0x05 + decompress_transaction // 0x06 + decompress_many_transactions // 0x07 +} + +#define macro MAIN() = takes (0) returns (0) { + // Write the jump table to 0x20 + // or else the flags jumptable won't get written + // all this memory will be reused anyway + __tablesize(SELECTORS_TABLE) // [table_size] + __tablestart(SELECTORS_TABLE) // [table_start, table_size] + 0x20 // [0x20, table_start, table_size] + codecopy // [] + + callvalue // [0x00] + calldataload // [data[0x00]] + callvalue // [0x00, data[0x00]] + byte // [method] + + 0x05 // [0x05, method] + shl // [(method << 0x05)] + 0x20 add // [method + 0x20] + mload // [mload[method]] + jump // [] + + execute_transaction: + 0x01 // [rindex] + PERFORM_EXECUTE(nrfs) // [rindex] + callvalue callvalue return + + execute_many_transactions: + 0x01 // [rindex] + PERFORM_MANY_EXECUTES(nrfs) // [rindex, size, i] + callvalue callvalue return + + read_address: + PERFORM_READ_ADDRESS() + 0x20 callvalue return + + read_bytes32: + PERFORM_READ_BYTES32() + 0x20 callvalue return + + sizes: + PERFORM_READ_SIZES() + 0x20 callvalue return + + read_storage_slots: + PERFORM_READ_SLOTS() // [size] + callvalue // [0x00, size] + return + + decompress_transaction: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_FULL_EXECUTE(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + decompress_many_transactions: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_MANY_FULL_EXECUTES(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + // This will be appended at the end + // unreachable code as all the method return first + + nrfs: + FN_READ_FLAG(nrfs) +} + + + +#define macro READ_FULL_EXECUTE(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + READ_EXECUTE() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_MANY_FULL_EXECUTES(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + + LOAD_1_BYTE() // [size, rindex, windex] + callvalue // [i, size, rindex, windex] + swap2 // [rindex, size, i, windex] + + do_another: // [rindex, size, i, windex] + swap1 // [size, rindex, i, windex] + swap2 // [i, rindex, size, windex] + swap3 // [windex, rindex, size, i] + + READ_FULL_EXECUTE() // [windex, rindex, size, i] + + swap3 // [i, rindex, size, windex] + swap2 // [size, rindex, i, windex] + swap1 // [rindex, size, i, windex] + + swap2 // [i, size, rindex, windex] + 0x01 // [0x01, i, size, rindex, windex] + add // [(0x01 + i), size, rindex, windex] + swap2 // [rindex, size, (0x01 + i), windex] + + dup2 // [size, rindex, size, (0x01 + i), windex] + dup4 // [(0x01 + i), size, rindex, size, (0x01 + i), windex] + lt // [((0x01 + i) < size), rindex, size, (0x01 + i), windex] + do_another jumpi // [rindex, size, (0x01 + i), windex] + + swap1 // [size, rindex, (0x01 + i), windex] + swap3 // [windex, rindex, (0x01 + i), size] + + // output stack: [windex, rindex, (0x01 + i), size] +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/src/__TEMP__dpdvzwushkgzisywrbnkhcrodypkvbvyL2Compressor.huff b/packages/wallet/wallet-contracts/src/__TEMP__dpdvzwushkgzisywrbnkhcrodypkvbvyL2Compressor.huff new file mode 100644 index 0000000000..da1916e7d5 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/__TEMP__dpdvzwushkgzisywrbnkhcrodypkvbvyL2Compressor.huff @@ -0,0 +1,142 @@ + + +#include "./L2CompressorLib.huff" + + +#define jumptable SELECTORS_TABLE { + execute_transaction // 0x00 + execute_many_transactions // 0x01 + read_address // 0x02 + read_bytes32 // 0x03 + sizes // 0x04 + read_storage_slots // 0x05 + decompress_transaction // 0x06 + decompress_many_transactions // 0x07 +} + +#define macro MAIN() = takes (0) returns (0) { + // Write the jump table to 0x20 + // or else the flags jumptable won't get written + // all this memory will be reused anyway + __tablesize(SELECTORS_TABLE) // [table_size] + __tablestart(SELECTORS_TABLE) // [table_start, table_size] + 0x20 // [0x20, table_start, table_size] + codecopy // [] + + callvalue // [0x00] + calldataload // [data[0x00]] + callvalue // [0x00, data[0x00]] + byte // [method] + + 0x05 // [0x05, method] + shl // [(method << 0x05)] + 0x20 add // [method + 0x20] + mload // [mload[method]] + jump // [] + + execute_transaction: + 0x01 // [rindex] + PERFORM_EXECUTE(nrfs) // [rindex] + callvalue callvalue return + + execute_many_transactions: + 0x01 // [rindex] + PERFORM_MANY_EXECUTES(nrfs) // [rindex, size, i] + callvalue callvalue return + + read_address: + PERFORM_READ_ADDRESS() + 0x20 callvalue return + + read_bytes32: + PERFORM_READ_BYTES32() + 0x20 callvalue return + + sizes: + PERFORM_READ_SIZES() + 0x20 callvalue return + + read_storage_slots: + PERFORM_READ_SLOTS() // [size] + callvalue // [0x00, size] + return + + decompress_transaction: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_FULL_EXECUTE(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + decompress_many_transactions: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_MANY_FULL_EXECUTES(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + // This will be appended at the end + // unreachable code as all the method return first + + nrfs: + FN_READ_FLAG(nrfs) +} + + + +#define macro READ_FULL_EXECUTE(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + READ_EXECUTE() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_MANY_FULL_EXECUTES(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + + LOAD_1_BYTE() // [size, rindex, windex] + callvalue // [i, size, rindex, windex] + swap2 // [rindex, size, i, windex] + + do_another: // [rindex, size, i, windex] + swap1 // [size, rindex, i, windex] + swap2 // [i, rindex, size, windex] + swap3 // [windex, rindex, size, i] + + READ_FULL_EXECUTE() // [windex, rindex, size, i] + + swap3 // [i, rindex, size, windex] + swap2 // [size, rindex, i, windex] + swap1 // [rindex, size, i, windex] + + swap2 // [i, size, rindex, windex] + 0x01 // [0x01, i, size, rindex, windex] + add // [(0x01 + i), size, rindex, windex] + swap2 // [rindex, size, (0x01 + i), windex] + + dup2 // [size, rindex, size, (0x01 + i), windex] + dup4 // [(0x01 + i), size, rindex, size, (0x01 + i), windex] + lt // [((0x01 + i) < size), rindex, size, (0x01 + i), windex] + do_another jumpi // [rindex, size, (0x01 + i), windex] + + swap1 // [size, rindex, (0x01 + i), windex] + swap3 // [windex, rindex, (0x01 + i), size] + + // output stack: [windex, rindex, (0x01 + i), size] +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/src/__TEMP__ecomtgzdrtxibkzevmerruajxffksduvL2Compressor.huff b/packages/wallet/wallet-contracts/src/__TEMP__ecomtgzdrtxibkzevmerruajxffksduvL2Compressor.huff new file mode 100644 index 0000000000..da1916e7d5 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/__TEMP__ecomtgzdrtxibkzevmerruajxffksduvL2Compressor.huff @@ -0,0 +1,142 @@ + + +#include "./L2CompressorLib.huff" + + +#define jumptable SELECTORS_TABLE { + execute_transaction // 0x00 + execute_many_transactions // 0x01 + read_address // 0x02 + read_bytes32 // 0x03 + sizes // 0x04 + read_storage_slots // 0x05 + decompress_transaction // 0x06 + decompress_many_transactions // 0x07 +} + +#define macro MAIN() = takes (0) returns (0) { + // Write the jump table to 0x20 + // or else the flags jumptable won't get written + // all this memory will be reused anyway + __tablesize(SELECTORS_TABLE) // [table_size] + __tablestart(SELECTORS_TABLE) // [table_start, table_size] + 0x20 // [0x20, table_start, table_size] + codecopy // [] + + callvalue // [0x00] + calldataload // [data[0x00]] + callvalue // [0x00, data[0x00]] + byte // [method] + + 0x05 // [0x05, method] + shl // [(method << 0x05)] + 0x20 add // [method + 0x20] + mload // [mload[method]] + jump // [] + + execute_transaction: + 0x01 // [rindex] + PERFORM_EXECUTE(nrfs) // [rindex] + callvalue callvalue return + + execute_many_transactions: + 0x01 // [rindex] + PERFORM_MANY_EXECUTES(nrfs) // [rindex, size, i] + callvalue callvalue return + + read_address: + PERFORM_READ_ADDRESS() + 0x20 callvalue return + + read_bytes32: + PERFORM_READ_BYTES32() + 0x20 callvalue return + + sizes: + PERFORM_READ_SIZES() + 0x20 callvalue return + + read_storage_slots: + PERFORM_READ_SLOTS() // [size] + callvalue // [0x00, size] + return + + decompress_transaction: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_FULL_EXECUTE(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + decompress_many_transactions: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_MANY_FULL_EXECUTES(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + // This will be appended at the end + // unreachable code as all the method return first + + nrfs: + FN_READ_FLAG(nrfs) +} + + + +#define macro READ_FULL_EXECUTE(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + READ_EXECUTE() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_MANY_FULL_EXECUTES(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + + LOAD_1_BYTE() // [size, rindex, windex] + callvalue // [i, size, rindex, windex] + swap2 // [rindex, size, i, windex] + + do_another: // [rindex, size, i, windex] + swap1 // [size, rindex, i, windex] + swap2 // [i, rindex, size, windex] + swap3 // [windex, rindex, size, i] + + READ_FULL_EXECUTE() // [windex, rindex, size, i] + + swap3 // [i, rindex, size, windex] + swap2 // [size, rindex, i, windex] + swap1 // [rindex, size, i, windex] + + swap2 // [i, size, rindex, windex] + 0x01 // [0x01, i, size, rindex, windex] + add // [(0x01 + i), size, rindex, windex] + swap2 // [rindex, size, (0x01 + i), windex] + + dup2 // [size, rindex, size, (0x01 + i), windex] + dup4 // [(0x01 + i), size, rindex, size, (0x01 + i), windex] + lt // [((0x01 + i) < size), rindex, size, (0x01 + i), windex] + do_another jumpi // [rindex, size, (0x01 + i), windex] + + swap1 // [size, rindex, (0x01 + i), windex] + swap3 // [windex, rindex, (0x01 + i), size] + + // output stack: [windex, rindex, (0x01 + i), size] +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/src/__TEMP__iacuotklnugcaogzpvcdfhvolsvzerleL2Compressor.huff b/packages/wallet/wallet-contracts/src/__TEMP__iacuotklnugcaogzpvcdfhvolsvzerleL2Compressor.huff new file mode 100644 index 0000000000..da1916e7d5 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/__TEMP__iacuotklnugcaogzpvcdfhvolsvzerleL2Compressor.huff @@ -0,0 +1,142 @@ + + +#include "./L2CompressorLib.huff" + + +#define jumptable SELECTORS_TABLE { + execute_transaction // 0x00 + execute_many_transactions // 0x01 + read_address // 0x02 + read_bytes32 // 0x03 + sizes // 0x04 + read_storage_slots // 0x05 + decompress_transaction // 0x06 + decompress_many_transactions // 0x07 +} + +#define macro MAIN() = takes (0) returns (0) { + // Write the jump table to 0x20 + // or else the flags jumptable won't get written + // all this memory will be reused anyway + __tablesize(SELECTORS_TABLE) // [table_size] + __tablestart(SELECTORS_TABLE) // [table_start, table_size] + 0x20 // [0x20, table_start, table_size] + codecopy // [] + + callvalue // [0x00] + calldataload // [data[0x00]] + callvalue // [0x00, data[0x00]] + byte // [method] + + 0x05 // [0x05, method] + shl // [(method << 0x05)] + 0x20 add // [method + 0x20] + mload // [mload[method]] + jump // [] + + execute_transaction: + 0x01 // [rindex] + PERFORM_EXECUTE(nrfs) // [rindex] + callvalue callvalue return + + execute_many_transactions: + 0x01 // [rindex] + PERFORM_MANY_EXECUTES(nrfs) // [rindex, size, i] + callvalue callvalue return + + read_address: + PERFORM_READ_ADDRESS() + 0x20 callvalue return + + read_bytes32: + PERFORM_READ_BYTES32() + 0x20 callvalue return + + sizes: + PERFORM_READ_SIZES() + 0x20 callvalue return + + read_storage_slots: + PERFORM_READ_SLOTS() // [size] + callvalue // [0x00, size] + return + + decompress_transaction: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_FULL_EXECUTE(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + decompress_many_transactions: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_MANY_FULL_EXECUTES(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + // This will be appended at the end + // unreachable code as all the method return first + + nrfs: + FN_READ_FLAG(nrfs) +} + + + +#define macro READ_FULL_EXECUTE(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + READ_EXECUTE() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_MANY_FULL_EXECUTES(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + + LOAD_1_BYTE() // [size, rindex, windex] + callvalue // [i, size, rindex, windex] + swap2 // [rindex, size, i, windex] + + do_another: // [rindex, size, i, windex] + swap1 // [size, rindex, i, windex] + swap2 // [i, rindex, size, windex] + swap3 // [windex, rindex, size, i] + + READ_FULL_EXECUTE() // [windex, rindex, size, i] + + swap3 // [i, rindex, size, windex] + swap2 // [size, rindex, i, windex] + swap1 // [rindex, size, i, windex] + + swap2 // [i, size, rindex, windex] + 0x01 // [0x01, i, size, rindex, windex] + add // [(0x01 + i), size, rindex, windex] + swap2 // [rindex, size, (0x01 + i), windex] + + dup2 // [size, rindex, size, (0x01 + i), windex] + dup4 // [(0x01 + i), size, rindex, size, (0x01 + i), windex] + lt // [((0x01 + i) < size), rindex, size, (0x01 + i), windex] + do_another jumpi // [rindex, size, (0x01 + i), windex] + + swap1 // [size, rindex, (0x01 + i), windex] + swap3 // [windex, rindex, (0x01 + i), size] + + // output stack: [windex, rindex, (0x01 + i), size] +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/src/__TEMP__jcmwhtnovsnvnyyhadlushmcopgxtlcwL2Compressor.huff b/packages/wallet/wallet-contracts/src/__TEMP__jcmwhtnovsnvnyyhadlushmcopgxtlcwL2Compressor.huff new file mode 100644 index 0000000000..da1916e7d5 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/__TEMP__jcmwhtnovsnvnyyhadlushmcopgxtlcwL2Compressor.huff @@ -0,0 +1,142 @@ + + +#include "./L2CompressorLib.huff" + + +#define jumptable SELECTORS_TABLE { + execute_transaction // 0x00 + execute_many_transactions // 0x01 + read_address // 0x02 + read_bytes32 // 0x03 + sizes // 0x04 + read_storage_slots // 0x05 + decompress_transaction // 0x06 + decompress_many_transactions // 0x07 +} + +#define macro MAIN() = takes (0) returns (0) { + // Write the jump table to 0x20 + // or else the flags jumptable won't get written + // all this memory will be reused anyway + __tablesize(SELECTORS_TABLE) // [table_size] + __tablestart(SELECTORS_TABLE) // [table_start, table_size] + 0x20 // [0x20, table_start, table_size] + codecopy // [] + + callvalue // [0x00] + calldataload // [data[0x00]] + callvalue // [0x00, data[0x00]] + byte // [method] + + 0x05 // [0x05, method] + shl // [(method << 0x05)] + 0x20 add // [method + 0x20] + mload // [mload[method]] + jump // [] + + execute_transaction: + 0x01 // [rindex] + PERFORM_EXECUTE(nrfs) // [rindex] + callvalue callvalue return + + execute_many_transactions: + 0x01 // [rindex] + PERFORM_MANY_EXECUTES(nrfs) // [rindex, size, i] + callvalue callvalue return + + read_address: + PERFORM_READ_ADDRESS() + 0x20 callvalue return + + read_bytes32: + PERFORM_READ_BYTES32() + 0x20 callvalue return + + sizes: + PERFORM_READ_SIZES() + 0x20 callvalue return + + read_storage_slots: + PERFORM_READ_SLOTS() // [size] + callvalue // [0x00, size] + return + + decompress_transaction: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_FULL_EXECUTE(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + decompress_many_transactions: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_MANY_FULL_EXECUTES(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + // This will be appended at the end + // unreachable code as all the method return first + + nrfs: + FN_READ_FLAG(nrfs) +} + + + +#define macro READ_FULL_EXECUTE(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + READ_EXECUTE() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_MANY_FULL_EXECUTES(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + + LOAD_1_BYTE() // [size, rindex, windex] + callvalue // [i, size, rindex, windex] + swap2 // [rindex, size, i, windex] + + do_another: // [rindex, size, i, windex] + swap1 // [size, rindex, i, windex] + swap2 // [i, rindex, size, windex] + swap3 // [windex, rindex, size, i] + + READ_FULL_EXECUTE() // [windex, rindex, size, i] + + swap3 // [i, rindex, size, windex] + swap2 // [size, rindex, i, windex] + swap1 // [rindex, size, i, windex] + + swap2 // [i, size, rindex, windex] + 0x01 // [0x01, i, size, rindex, windex] + add // [(0x01 + i), size, rindex, windex] + swap2 // [rindex, size, (0x01 + i), windex] + + dup2 // [size, rindex, size, (0x01 + i), windex] + dup4 // [(0x01 + i), size, rindex, size, (0x01 + i), windex] + lt // [((0x01 + i) < size), rindex, size, (0x01 + i), windex] + do_another jumpi // [rindex, size, (0x01 + i), windex] + + swap1 // [size, rindex, (0x01 + i), windex] + swap3 // [windex, rindex, (0x01 + i), size] + + // output stack: [windex, rindex, (0x01 + i), size] +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/src/__TEMP__jdfvnyqsqtnysjlyfovitokyykvxttnoL2Compressor.huff b/packages/wallet/wallet-contracts/src/__TEMP__jdfvnyqsqtnysjlyfovitokyykvxttnoL2Compressor.huff new file mode 100644 index 0000000000..da1916e7d5 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/__TEMP__jdfvnyqsqtnysjlyfovitokyykvxttnoL2Compressor.huff @@ -0,0 +1,142 @@ + + +#include "./L2CompressorLib.huff" + + +#define jumptable SELECTORS_TABLE { + execute_transaction // 0x00 + execute_many_transactions // 0x01 + read_address // 0x02 + read_bytes32 // 0x03 + sizes // 0x04 + read_storage_slots // 0x05 + decompress_transaction // 0x06 + decompress_many_transactions // 0x07 +} + +#define macro MAIN() = takes (0) returns (0) { + // Write the jump table to 0x20 + // or else the flags jumptable won't get written + // all this memory will be reused anyway + __tablesize(SELECTORS_TABLE) // [table_size] + __tablestart(SELECTORS_TABLE) // [table_start, table_size] + 0x20 // [0x20, table_start, table_size] + codecopy // [] + + callvalue // [0x00] + calldataload // [data[0x00]] + callvalue // [0x00, data[0x00]] + byte // [method] + + 0x05 // [0x05, method] + shl // [(method << 0x05)] + 0x20 add // [method + 0x20] + mload // [mload[method]] + jump // [] + + execute_transaction: + 0x01 // [rindex] + PERFORM_EXECUTE(nrfs) // [rindex] + callvalue callvalue return + + execute_many_transactions: + 0x01 // [rindex] + PERFORM_MANY_EXECUTES(nrfs) // [rindex, size, i] + callvalue callvalue return + + read_address: + PERFORM_READ_ADDRESS() + 0x20 callvalue return + + read_bytes32: + PERFORM_READ_BYTES32() + 0x20 callvalue return + + sizes: + PERFORM_READ_SIZES() + 0x20 callvalue return + + read_storage_slots: + PERFORM_READ_SLOTS() // [size] + callvalue // [0x00, size] + return + + decompress_transaction: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_FULL_EXECUTE(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + decompress_many_transactions: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_MANY_FULL_EXECUTES(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + // This will be appended at the end + // unreachable code as all the method return first + + nrfs: + FN_READ_FLAG(nrfs) +} + + + +#define macro READ_FULL_EXECUTE(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + READ_EXECUTE() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_MANY_FULL_EXECUTES(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + + LOAD_1_BYTE() // [size, rindex, windex] + callvalue // [i, size, rindex, windex] + swap2 // [rindex, size, i, windex] + + do_another: // [rindex, size, i, windex] + swap1 // [size, rindex, i, windex] + swap2 // [i, rindex, size, windex] + swap3 // [windex, rindex, size, i] + + READ_FULL_EXECUTE() // [windex, rindex, size, i] + + swap3 // [i, rindex, size, windex] + swap2 // [size, rindex, i, windex] + swap1 // [rindex, size, i, windex] + + swap2 // [i, size, rindex, windex] + 0x01 // [0x01, i, size, rindex, windex] + add // [(0x01 + i), size, rindex, windex] + swap2 // [rindex, size, (0x01 + i), windex] + + dup2 // [size, rindex, size, (0x01 + i), windex] + dup4 // [(0x01 + i), size, rindex, size, (0x01 + i), windex] + lt // [((0x01 + i) < size), rindex, size, (0x01 + i), windex] + do_another jumpi // [rindex, size, (0x01 + i), windex] + + swap1 // [size, rindex, (0x01 + i), windex] + swap3 // [windex, rindex, (0x01 + i), size] + + // output stack: [windex, rindex, (0x01 + i), size] +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/src/__TEMP__jyyzvebufexucahwkkbkfdcmuiabvbfeL2Compressor.huff b/packages/wallet/wallet-contracts/src/__TEMP__jyyzvebufexucahwkkbkfdcmuiabvbfeL2Compressor.huff new file mode 100644 index 0000000000..da1916e7d5 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/__TEMP__jyyzvebufexucahwkkbkfdcmuiabvbfeL2Compressor.huff @@ -0,0 +1,142 @@ + + +#include "./L2CompressorLib.huff" + + +#define jumptable SELECTORS_TABLE { + execute_transaction // 0x00 + execute_many_transactions // 0x01 + read_address // 0x02 + read_bytes32 // 0x03 + sizes // 0x04 + read_storage_slots // 0x05 + decompress_transaction // 0x06 + decompress_many_transactions // 0x07 +} + +#define macro MAIN() = takes (0) returns (0) { + // Write the jump table to 0x20 + // or else the flags jumptable won't get written + // all this memory will be reused anyway + __tablesize(SELECTORS_TABLE) // [table_size] + __tablestart(SELECTORS_TABLE) // [table_start, table_size] + 0x20 // [0x20, table_start, table_size] + codecopy // [] + + callvalue // [0x00] + calldataload // [data[0x00]] + callvalue // [0x00, data[0x00]] + byte // [method] + + 0x05 // [0x05, method] + shl // [(method << 0x05)] + 0x20 add // [method + 0x20] + mload // [mload[method]] + jump // [] + + execute_transaction: + 0x01 // [rindex] + PERFORM_EXECUTE(nrfs) // [rindex] + callvalue callvalue return + + execute_many_transactions: + 0x01 // [rindex] + PERFORM_MANY_EXECUTES(nrfs) // [rindex, size, i] + callvalue callvalue return + + read_address: + PERFORM_READ_ADDRESS() + 0x20 callvalue return + + read_bytes32: + PERFORM_READ_BYTES32() + 0x20 callvalue return + + sizes: + PERFORM_READ_SIZES() + 0x20 callvalue return + + read_storage_slots: + PERFORM_READ_SLOTS() // [size] + callvalue // [0x00, size] + return + + decompress_transaction: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_FULL_EXECUTE(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + decompress_many_transactions: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_MANY_FULL_EXECUTES(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + // This will be appended at the end + // unreachable code as all the method return first + + nrfs: + FN_READ_FLAG(nrfs) +} + + + +#define macro READ_FULL_EXECUTE(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + READ_EXECUTE() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_MANY_FULL_EXECUTES(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + + LOAD_1_BYTE() // [size, rindex, windex] + callvalue // [i, size, rindex, windex] + swap2 // [rindex, size, i, windex] + + do_another: // [rindex, size, i, windex] + swap1 // [size, rindex, i, windex] + swap2 // [i, rindex, size, windex] + swap3 // [windex, rindex, size, i] + + READ_FULL_EXECUTE() // [windex, rindex, size, i] + + swap3 // [i, rindex, size, windex] + swap2 // [size, rindex, i, windex] + swap1 // [rindex, size, i, windex] + + swap2 // [i, size, rindex, windex] + 0x01 // [0x01, i, size, rindex, windex] + add // [(0x01 + i), size, rindex, windex] + swap2 // [rindex, size, (0x01 + i), windex] + + dup2 // [size, rindex, size, (0x01 + i), windex] + dup4 // [(0x01 + i), size, rindex, size, (0x01 + i), windex] + lt // [((0x01 + i) < size), rindex, size, (0x01 + i), windex] + do_another jumpi // [rindex, size, (0x01 + i), windex] + + swap1 // [size, rindex, (0x01 + i), windex] + swap3 // [windex, rindex, (0x01 + i), size] + + // output stack: [windex, rindex, (0x01 + i), size] +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/src/__TEMP__kbisarygvfqaqtuxwpgejdnyqkualpwlL2Compressor.huff b/packages/wallet/wallet-contracts/src/__TEMP__kbisarygvfqaqtuxwpgejdnyqkualpwlL2Compressor.huff new file mode 100644 index 0000000000..da1916e7d5 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/__TEMP__kbisarygvfqaqtuxwpgejdnyqkualpwlL2Compressor.huff @@ -0,0 +1,142 @@ + + +#include "./L2CompressorLib.huff" + + +#define jumptable SELECTORS_TABLE { + execute_transaction // 0x00 + execute_many_transactions // 0x01 + read_address // 0x02 + read_bytes32 // 0x03 + sizes // 0x04 + read_storage_slots // 0x05 + decompress_transaction // 0x06 + decompress_many_transactions // 0x07 +} + +#define macro MAIN() = takes (0) returns (0) { + // Write the jump table to 0x20 + // or else the flags jumptable won't get written + // all this memory will be reused anyway + __tablesize(SELECTORS_TABLE) // [table_size] + __tablestart(SELECTORS_TABLE) // [table_start, table_size] + 0x20 // [0x20, table_start, table_size] + codecopy // [] + + callvalue // [0x00] + calldataload // [data[0x00]] + callvalue // [0x00, data[0x00]] + byte // [method] + + 0x05 // [0x05, method] + shl // [(method << 0x05)] + 0x20 add // [method + 0x20] + mload // [mload[method]] + jump // [] + + execute_transaction: + 0x01 // [rindex] + PERFORM_EXECUTE(nrfs) // [rindex] + callvalue callvalue return + + execute_many_transactions: + 0x01 // [rindex] + PERFORM_MANY_EXECUTES(nrfs) // [rindex, size, i] + callvalue callvalue return + + read_address: + PERFORM_READ_ADDRESS() + 0x20 callvalue return + + read_bytes32: + PERFORM_READ_BYTES32() + 0x20 callvalue return + + sizes: + PERFORM_READ_SIZES() + 0x20 callvalue return + + read_storage_slots: + PERFORM_READ_SLOTS() // [size] + callvalue // [0x00, size] + return + + decompress_transaction: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_FULL_EXECUTE(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + decompress_many_transactions: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_MANY_FULL_EXECUTES(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + // This will be appended at the end + // unreachable code as all the method return first + + nrfs: + FN_READ_FLAG(nrfs) +} + + + +#define macro READ_FULL_EXECUTE(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + READ_EXECUTE() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_MANY_FULL_EXECUTES(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + + LOAD_1_BYTE() // [size, rindex, windex] + callvalue // [i, size, rindex, windex] + swap2 // [rindex, size, i, windex] + + do_another: // [rindex, size, i, windex] + swap1 // [size, rindex, i, windex] + swap2 // [i, rindex, size, windex] + swap3 // [windex, rindex, size, i] + + READ_FULL_EXECUTE() // [windex, rindex, size, i] + + swap3 // [i, rindex, size, windex] + swap2 // [size, rindex, i, windex] + swap1 // [rindex, size, i, windex] + + swap2 // [i, size, rindex, windex] + 0x01 // [0x01, i, size, rindex, windex] + add // [(0x01 + i), size, rindex, windex] + swap2 // [rindex, size, (0x01 + i), windex] + + dup2 // [size, rindex, size, (0x01 + i), windex] + dup4 // [(0x01 + i), size, rindex, size, (0x01 + i), windex] + lt // [((0x01 + i) < size), rindex, size, (0x01 + i), windex] + do_another jumpi // [rindex, size, (0x01 + i), windex] + + swap1 // [size, rindex, (0x01 + i), windex] + swap3 // [windex, rindex, (0x01 + i), size] + + // output stack: [windex, rindex, (0x01 + i), size] +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/src/__TEMP__lszmdtforkxonmlujouewhlrvjjrmurcL2Compressor.huff b/packages/wallet/wallet-contracts/src/__TEMP__lszmdtforkxonmlujouewhlrvjjrmurcL2Compressor.huff new file mode 100644 index 0000000000..da1916e7d5 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/__TEMP__lszmdtforkxonmlujouewhlrvjjrmurcL2Compressor.huff @@ -0,0 +1,142 @@ + + +#include "./L2CompressorLib.huff" + + +#define jumptable SELECTORS_TABLE { + execute_transaction // 0x00 + execute_many_transactions // 0x01 + read_address // 0x02 + read_bytes32 // 0x03 + sizes // 0x04 + read_storage_slots // 0x05 + decompress_transaction // 0x06 + decompress_many_transactions // 0x07 +} + +#define macro MAIN() = takes (0) returns (0) { + // Write the jump table to 0x20 + // or else the flags jumptable won't get written + // all this memory will be reused anyway + __tablesize(SELECTORS_TABLE) // [table_size] + __tablestart(SELECTORS_TABLE) // [table_start, table_size] + 0x20 // [0x20, table_start, table_size] + codecopy // [] + + callvalue // [0x00] + calldataload // [data[0x00]] + callvalue // [0x00, data[0x00]] + byte // [method] + + 0x05 // [0x05, method] + shl // [(method << 0x05)] + 0x20 add // [method + 0x20] + mload // [mload[method]] + jump // [] + + execute_transaction: + 0x01 // [rindex] + PERFORM_EXECUTE(nrfs) // [rindex] + callvalue callvalue return + + execute_many_transactions: + 0x01 // [rindex] + PERFORM_MANY_EXECUTES(nrfs) // [rindex, size, i] + callvalue callvalue return + + read_address: + PERFORM_READ_ADDRESS() + 0x20 callvalue return + + read_bytes32: + PERFORM_READ_BYTES32() + 0x20 callvalue return + + sizes: + PERFORM_READ_SIZES() + 0x20 callvalue return + + read_storage_slots: + PERFORM_READ_SLOTS() // [size] + callvalue // [0x00, size] + return + + decompress_transaction: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_FULL_EXECUTE(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + decompress_many_transactions: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_MANY_FULL_EXECUTES(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + // This will be appended at the end + // unreachable code as all the method return first + + nrfs: + FN_READ_FLAG(nrfs) +} + + + +#define macro READ_FULL_EXECUTE(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + READ_EXECUTE() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_MANY_FULL_EXECUTES(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + + LOAD_1_BYTE() // [size, rindex, windex] + callvalue // [i, size, rindex, windex] + swap2 // [rindex, size, i, windex] + + do_another: // [rindex, size, i, windex] + swap1 // [size, rindex, i, windex] + swap2 // [i, rindex, size, windex] + swap3 // [windex, rindex, size, i] + + READ_FULL_EXECUTE() // [windex, rindex, size, i] + + swap3 // [i, rindex, size, windex] + swap2 // [size, rindex, i, windex] + swap1 // [rindex, size, i, windex] + + swap2 // [i, size, rindex, windex] + 0x01 // [0x01, i, size, rindex, windex] + add // [(0x01 + i), size, rindex, windex] + swap2 // [rindex, size, (0x01 + i), windex] + + dup2 // [size, rindex, size, (0x01 + i), windex] + dup4 // [(0x01 + i), size, rindex, size, (0x01 + i), windex] + lt // [((0x01 + i) < size), rindex, size, (0x01 + i), windex] + do_another jumpi // [rindex, size, (0x01 + i), windex] + + swap1 // [size, rindex, (0x01 + i), windex] + swap3 // [windex, rindex, (0x01 + i), size] + + // output stack: [windex, rindex, (0x01 + i), size] +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/src/__TEMP__mgltnswskwojupcsygtzovabokiotusaL2Compressor.huff b/packages/wallet/wallet-contracts/src/__TEMP__mgltnswskwojupcsygtzovabokiotusaL2Compressor.huff new file mode 100644 index 0000000000..da1916e7d5 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/__TEMP__mgltnswskwojupcsygtzovabokiotusaL2Compressor.huff @@ -0,0 +1,142 @@ + + +#include "./L2CompressorLib.huff" + + +#define jumptable SELECTORS_TABLE { + execute_transaction // 0x00 + execute_many_transactions // 0x01 + read_address // 0x02 + read_bytes32 // 0x03 + sizes // 0x04 + read_storage_slots // 0x05 + decompress_transaction // 0x06 + decompress_many_transactions // 0x07 +} + +#define macro MAIN() = takes (0) returns (0) { + // Write the jump table to 0x20 + // or else the flags jumptable won't get written + // all this memory will be reused anyway + __tablesize(SELECTORS_TABLE) // [table_size] + __tablestart(SELECTORS_TABLE) // [table_start, table_size] + 0x20 // [0x20, table_start, table_size] + codecopy // [] + + callvalue // [0x00] + calldataload // [data[0x00]] + callvalue // [0x00, data[0x00]] + byte // [method] + + 0x05 // [0x05, method] + shl // [(method << 0x05)] + 0x20 add // [method + 0x20] + mload // [mload[method]] + jump // [] + + execute_transaction: + 0x01 // [rindex] + PERFORM_EXECUTE(nrfs) // [rindex] + callvalue callvalue return + + execute_many_transactions: + 0x01 // [rindex] + PERFORM_MANY_EXECUTES(nrfs) // [rindex, size, i] + callvalue callvalue return + + read_address: + PERFORM_READ_ADDRESS() + 0x20 callvalue return + + read_bytes32: + PERFORM_READ_BYTES32() + 0x20 callvalue return + + sizes: + PERFORM_READ_SIZES() + 0x20 callvalue return + + read_storage_slots: + PERFORM_READ_SLOTS() // [size] + callvalue // [0x00, size] + return + + decompress_transaction: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_FULL_EXECUTE(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + decompress_many_transactions: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_MANY_FULL_EXECUTES(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + // This will be appended at the end + // unreachable code as all the method return first + + nrfs: + FN_READ_FLAG(nrfs) +} + + + +#define macro READ_FULL_EXECUTE(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + READ_EXECUTE() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_MANY_FULL_EXECUTES(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + + LOAD_1_BYTE() // [size, rindex, windex] + callvalue // [i, size, rindex, windex] + swap2 // [rindex, size, i, windex] + + do_another: // [rindex, size, i, windex] + swap1 // [size, rindex, i, windex] + swap2 // [i, rindex, size, windex] + swap3 // [windex, rindex, size, i] + + READ_FULL_EXECUTE() // [windex, rindex, size, i] + + swap3 // [i, rindex, size, windex] + swap2 // [size, rindex, i, windex] + swap1 // [rindex, size, i, windex] + + swap2 // [i, size, rindex, windex] + 0x01 // [0x01, i, size, rindex, windex] + add // [(0x01 + i), size, rindex, windex] + swap2 // [rindex, size, (0x01 + i), windex] + + dup2 // [size, rindex, size, (0x01 + i), windex] + dup4 // [(0x01 + i), size, rindex, size, (0x01 + i), windex] + lt // [((0x01 + i) < size), rindex, size, (0x01 + i), windex] + do_another jumpi // [rindex, size, (0x01 + i), windex] + + swap1 // [size, rindex, (0x01 + i), windex] + swap3 // [windex, rindex, (0x01 + i), size] + + // output stack: [windex, rindex, (0x01 + i), size] +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/src/__TEMP__mzwfsngwzygdglttftvfnbgkuxhmtqwiL2Compressor.huff b/packages/wallet/wallet-contracts/src/__TEMP__mzwfsngwzygdglttftvfnbgkuxhmtqwiL2Compressor.huff new file mode 100644 index 0000000000..da1916e7d5 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/__TEMP__mzwfsngwzygdglttftvfnbgkuxhmtqwiL2Compressor.huff @@ -0,0 +1,142 @@ + + +#include "./L2CompressorLib.huff" + + +#define jumptable SELECTORS_TABLE { + execute_transaction // 0x00 + execute_many_transactions // 0x01 + read_address // 0x02 + read_bytes32 // 0x03 + sizes // 0x04 + read_storage_slots // 0x05 + decompress_transaction // 0x06 + decompress_many_transactions // 0x07 +} + +#define macro MAIN() = takes (0) returns (0) { + // Write the jump table to 0x20 + // or else the flags jumptable won't get written + // all this memory will be reused anyway + __tablesize(SELECTORS_TABLE) // [table_size] + __tablestart(SELECTORS_TABLE) // [table_start, table_size] + 0x20 // [0x20, table_start, table_size] + codecopy // [] + + callvalue // [0x00] + calldataload // [data[0x00]] + callvalue // [0x00, data[0x00]] + byte // [method] + + 0x05 // [0x05, method] + shl // [(method << 0x05)] + 0x20 add // [method + 0x20] + mload // [mload[method]] + jump // [] + + execute_transaction: + 0x01 // [rindex] + PERFORM_EXECUTE(nrfs) // [rindex] + callvalue callvalue return + + execute_many_transactions: + 0x01 // [rindex] + PERFORM_MANY_EXECUTES(nrfs) // [rindex, size, i] + callvalue callvalue return + + read_address: + PERFORM_READ_ADDRESS() + 0x20 callvalue return + + read_bytes32: + PERFORM_READ_BYTES32() + 0x20 callvalue return + + sizes: + PERFORM_READ_SIZES() + 0x20 callvalue return + + read_storage_slots: + PERFORM_READ_SLOTS() // [size] + callvalue // [0x00, size] + return + + decompress_transaction: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_FULL_EXECUTE(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + decompress_many_transactions: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_MANY_FULL_EXECUTES(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + // This will be appended at the end + // unreachable code as all the method return first + + nrfs: + FN_READ_FLAG(nrfs) +} + + + +#define macro READ_FULL_EXECUTE(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + READ_EXECUTE() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_MANY_FULL_EXECUTES(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + + LOAD_1_BYTE() // [size, rindex, windex] + callvalue // [i, size, rindex, windex] + swap2 // [rindex, size, i, windex] + + do_another: // [rindex, size, i, windex] + swap1 // [size, rindex, i, windex] + swap2 // [i, rindex, size, windex] + swap3 // [windex, rindex, size, i] + + READ_FULL_EXECUTE() // [windex, rindex, size, i] + + swap3 // [i, rindex, size, windex] + swap2 // [size, rindex, i, windex] + swap1 // [rindex, size, i, windex] + + swap2 // [i, size, rindex, windex] + 0x01 // [0x01, i, size, rindex, windex] + add // [(0x01 + i), size, rindex, windex] + swap2 // [rindex, size, (0x01 + i), windex] + + dup2 // [size, rindex, size, (0x01 + i), windex] + dup4 // [(0x01 + i), size, rindex, size, (0x01 + i), windex] + lt // [((0x01 + i) < size), rindex, size, (0x01 + i), windex] + do_another jumpi // [rindex, size, (0x01 + i), windex] + + swap1 // [size, rindex, (0x01 + i), windex] + swap3 // [windex, rindex, (0x01 + i), size] + + // output stack: [windex, rindex, (0x01 + i), size] +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/src/__TEMP__nxqmasuaqrahclmuoszdisbtgmuppjvfL2Compressor.huff b/packages/wallet/wallet-contracts/src/__TEMP__nxqmasuaqrahclmuoszdisbtgmuppjvfL2Compressor.huff new file mode 100644 index 0000000000..da1916e7d5 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/__TEMP__nxqmasuaqrahclmuoszdisbtgmuppjvfL2Compressor.huff @@ -0,0 +1,142 @@ + + +#include "./L2CompressorLib.huff" + + +#define jumptable SELECTORS_TABLE { + execute_transaction // 0x00 + execute_many_transactions // 0x01 + read_address // 0x02 + read_bytes32 // 0x03 + sizes // 0x04 + read_storage_slots // 0x05 + decompress_transaction // 0x06 + decompress_many_transactions // 0x07 +} + +#define macro MAIN() = takes (0) returns (0) { + // Write the jump table to 0x20 + // or else the flags jumptable won't get written + // all this memory will be reused anyway + __tablesize(SELECTORS_TABLE) // [table_size] + __tablestart(SELECTORS_TABLE) // [table_start, table_size] + 0x20 // [0x20, table_start, table_size] + codecopy // [] + + callvalue // [0x00] + calldataload // [data[0x00]] + callvalue // [0x00, data[0x00]] + byte // [method] + + 0x05 // [0x05, method] + shl // [(method << 0x05)] + 0x20 add // [method + 0x20] + mload // [mload[method]] + jump // [] + + execute_transaction: + 0x01 // [rindex] + PERFORM_EXECUTE(nrfs) // [rindex] + callvalue callvalue return + + execute_many_transactions: + 0x01 // [rindex] + PERFORM_MANY_EXECUTES(nrfs) // [rindex, size, i] + callvalue callvalue return + + read_address: + PERFORM_READ_ADDRESS() + 0x20 callvalue return + + read_bytes32: + PERFORM_READ_BYTES32() + 0x20 callvalue return + + sizes: + PERFORM_READ_SIZES() + 0x20 callvalue return + + read_storage_slots: + PERFORM_READ_SLOTS() // [size] + callvalue // [0x00, size] + return + + decompress_transaction: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_FULL_EXECUTE(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + decompress_many_transactions: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_MANY_FULL_EXECUTES(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + // This will be appended at the end + // unreachable code as all the method return first + + nrfs: + FN_READ_FLAG(nrfs) +} + + + +#define macro READ_FULL_EXECUTE(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + READ_EXECUTE() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_MANY_FULL_EXECUTES(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + + LOAD_1_BYTE() // [size, rindex, windex] + callvalue // [i, size, rindex, windex] + swap2 // [rindex, size, i, windex] + + do_another: // [rindex, size, i, windex] + swap1 // [size, rindex, i, windex] + swap2 // [i, rindex, size, windex] + swap3 // [windex, rindex, size, i] + + READ_FULL_EXECUTE() // [windex, rindex, size, i] + + swap3 // [i, rindex, size, windex] + swap2 // [size, rindex, i, windex] + swap1 // [rindex, size, i, windex] + + swap2 // [i, size, rindex, windex] + 0x01 // [0x01, i, size, rindex, windex] + add // [(0x01 + i), size, rindex, windex] + swap2 // [rindex, size, (0x01 + i), windex] + + dup2 // [size, rindex, size, (0x01 + i), windex] + dup4 // [(0x01 + i), size, rindex, size, (0x01 + i), windex] + lt // [((0x01 + i) < size), rindex, size, (0x01 + i), windex] + do_another jumpi // [rindex, size, (0x01 + i), windex] + + swap1 // [size, rindex, (0x01 + i), windex] + swap3 // [windex, rindex, (0x01 + i), size] + + // output stack: [windex, rindex, (0x01 + i), size] +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/src/__TEMP__pgmagdckbktfjhzdpajytwhcpkhlmscqL2Compressor.huff b/packages/wallet/wallet-contracts/src/__TEMP__pgmagdckbktfjhzdpajytwhcpkhlmscqL2Compressor.huff new file mode 100644 index 0000000000..da1916e7d5 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/__TEMP__pgmagdckbktfjhzdpajytwhcpkhlmscqL2Compressor.huff @@ -0,0 +1,142 @@ + + +#include "./L2CompressorLib.huff" + + +#define jumptable SELECTORS_TABLE { + execute_transaction // 0x00 + execute_many_transactions // 0x01 + read_address // 0x02 + read_bytes32 // 0x03 + sizes // 0x04 + read_storage_slots // 0x05 + decompress_transaction // 0x06 + decompress_many_transactions // 0x07 +} + +#define macro MAIN() = takes (0) returns (0) { + // Write the jump table to 0x20 + // or else the flags jumptable won't get written + // all this memory will be reused anyway + __tablesize(SELECTORS_TABLE) // [table_size] + __tablestart(SELECTORS_TABLE) // [table_start, table_size] + 0x20 // [0x20, table_start, table_size] + codecopy // [] + + callvalue // [0x00] + calldataload // [data[0x00]] + callvalue // [0x00, data[0x00]] + byte // [method] + + 0x05 // [0x05, method] + shl // [(method << 0x05)] + 0x20 add // [method + 0x20] + mload // [mload[method]] + jump // [] + + execute_transaction: + 0x01 // [rindex] + PERFORM_EXECUTE(nrfs) // [rindex] + callvalue callvalue return + + execute_many_transactions: + 0x01 // [rindex] + PERFORM_MANY_EXECUTES(nrfs) // [rindex, size, i] + callvalue callvalue return + + read_address: + PERFORM_READ_ADDRESS() + 0x20 callvalue return + + read_bytes32: + PERFORM_READ_BYTES32() + 0x20 callvalue return + + sizes: + PERFORM_READ_SIZES() + 0x20 callvalue return + + read_storage_slots: + PERFORM_READ_SLOTS() // [size] + callvalue // [0x00, size] + return + + decompress_transaction: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_FULL_EXECUTE(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + decompress_many_transactions: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_MANY_FULL_EXECUTES(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + // This will be appended at the end + // unreachable code as all the method return first + + nrfs: + FN_READ_FLAG(nrfs) +} + + + +#define macro READ_FULL_EXECUTE(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + READ_EXECUTE() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_MANY_FULL_EXECUTES(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + + LOAD_1_BYTE() // [size, rindex, windex] + callvalue // [i, size, rindex, windex] + swap2 // [rindex, size, i, windex] + + do_another: // [rindex, size, i, windex] + swap1 // [size, rindex, i, windex] + swap2 // [i, rindex, size, windex] + swap3 // [windex, rindex, size, i] + + READ_FULL_EXECUTE() // [windex, rindex, size, i] + + swap3 // [i, rindex, size, windex] + swap2 // [size, rindex, i, windex] + swap1 // [rindex, size, i, windex] + + swap2 // [i, size, rindex, windex] + 0x01 // [0x01, i, size, rindex, windex] + add // [(0x01 + i), size, rindex, windex] + swap2 // [rindex, size, (0x01 + i), windex] + + dup2 // [size, rindex, size, (0x01 + i), windex] + dup4 // [(0x01 + i), size, rindex, size, (0x01 + i), windex] + lt // [((0x01 + i) < size), rindex, size, (0x01 + i), windex] + do_another jumpi // [rindex, size, (0x01 + i), windex] + + swap1 // [size, rindex, (0x01 + i), windex] + swap3 // [windex, rindex, (0x01 + i), size] + + // output stack: [windex, rindex, (0x01 + i), size] +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/src/__TEMP__pwbfbdaeweytjiloryhjilsqguaprwtwL2Compressor.huff b/packages/wallet/wallet-contracts/src/__TEMP__pwbfbdaeweytjiloryhjilsqguaprwtwL2Compressor.huff new file mode 100644 index 0000000000..da1916e7d5 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/__TEMP__pwbfbdaeweytjiloryhjilsqguaprwtwL2Compressor.huff @@ -0,0 +1,142 @@ + + +#include "./L2CompressorLib.huff" + + +#define jumptable SELECTORS_TABLE { + execute_transaction // 0x00 + execute_many_transactions // 0x01 + read_address // 0x02 + read_bytes32 // 0x03 + sizes // 0x04 + read_storage_slots // 0x05 + decompress_transaction // 0x06 + decompress_many_transactions // 0x07 +} + +#define macro MAIN() = takes (0) returns (0) { + // Write the jump table to 0x20 + // or else the flags jumptable won't get written + // all this memory will be reused anyway + __tablesize(SELECTORS_TABLE) // [table_size] + __tablestart(SELECTORS_TABLE) // [table_start, table_size] + 0x20 // [0x20, table_start, table_size] + codecopy // [] + + callvalue // [0x00] + calldataload // [data[0x00]] + callvalue // [0x00, data[0x00]] + byte // [method] + + 0x05 // [0x05, method] + shl // [(method << 0x05)] + 0x20 add // [method + 0x20] + mload // [mload[method]] + jump // [] + + execute_transaction: + 0x01 // [rindex] + PERFORM_EXECUTE(nrfs) // [rindex] + callvalue callvalue return + + execute_many_transactions: + 0x01 // [rindex] + PERFORM_MANY_EXECUTES(nrfs) // [rindex, size, i] + callvalue callvalue return + + read_address: + PERFORM_READ_ADDRESS() + 0x20 callvalue return + + read_bytes32: + PERFORM_READ_BYTES32() + 0x20 callvalue return + + sizes: + PERFORM_READ_SIZES() + 0x20 callvalue return + + read_storage_slots: + PERFORM_READ_SLOTS() // [size] + callvalue // [0x00, size] + return + + decompress_transaction: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_FULL_EXECUTE(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + decompress_many_transactions: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_MANY_FULL_EXECUTES(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + // This will be appended at the end + // unreachable code as all the method return first + + nrfs: + FN_READ_FLAG(nrfs) +} + + + +#define macro READ_FULL_EXECUTE(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + READ_EXECUTE() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_MANY_FULL_EXECUTES(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + + LOAD_1_BYTE() // [size, rindex, windex] + callvalue // [i, size, rindex, windex] + swap2 // [rindex, size, i, windex] + + do_another: // [rindex, size, i, windex] + swap1 // [size, rindex, i, windex] + swap2 // [i, rindex, size, windex] + swap3 // [windex, rindex, size, i] + + READ_FULL_EXECUTE() // [windex, rindex, size, i] + + swap3 // [i, rindex, size, windex] + swap2 // [size, rindex, i, windex] + swap1 // [rindex, size, i, windex] + + swap2 // [i, size, rindex, windex] + 0x01 // [0x01, i, size, rindex, windex] + add // [(0x01 + i), size, rindex, windex] + swap2 // [rindex, size, (0x01 + i), windex] + + dup2 // [size, rindex, size, (0x01 + i), windex] + dup4 // [(0x01 + i), size, rindex, size, (0x01 + i), windex] + lt // [((0x01 + i) < size), rindex, size, (0x01 + i), windex] + do_another jumpi // [rindex, size, (0x01 + i), windex] + + swap1 // [size, rindex, (0x01 + i), windex] + swap3 // [windex, rindex, (0x01 + i), size] + + // output stack: [windex, rindex, (0x01 + i), size] +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/src/__TEMP__pxqvpgsonlpbmziexnicojtlgsgfouyrL2Compressor.huff b/packages/wallet/wallet-contracts/src/__TEMP__pxqvpgsonlpbmziexnicojtlgsgfouyrL2Compressor.huff new file mode 100644 index 0000000000..da1916e7d5 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/__TEMP__pxqvpgsonlpbmziexnicojtlgsgfouyrL2Compressor.huff @@ -0,0 +1,142 @@ + + +#include "./L2CompressorLib.huff" + + +#define jumptable SELECTORS_TABLE { + execute_transaction // 0x00 + execute_many_transactions // 0x01 + read_address // 0x02 + read_bytes32 // 0x03 + sizes // 0x04 + read_storage_slots // 0x05 + decompress_transaction // 0x06 + decompress_many_transactions // 0x07 +} + +#define macro MAIN() = takes (0) returns (0) { + // Write the jump table to 0x20 + // or else the flags jumptable won't get written + // all this memory will be reused anyway + __tablesize(SELECTORS_TABLE) // [table_size] + __tablestart(SELECTORS_TABLE) // [table_start, table_size] + 0x20 // [0x20, table_start, table_size] + codecopy // [] + + callvalue // [0x00] + calldataload // [data[0x00]] + callvalue // [0x00, data[0x00]] + byte // [method] + + 0x05 // [0x05, method] + shl // [(method << 0x05)] + 0x20 add // [method + 0x20] + mload // [mload[method]] + jump // [] + + execute_transaction: + 0x01 // [rindex] + PERFORM_EXECUTE(nrfs) // [rindex] + callvalue callvalue return + + execute_many_transactions: + 0x01 // [rindex] + PERFORM_MANY_EXECUTES(nrfs) // [rindex, size, i] + callvalue callvalue return + + read_address: + PERFORM_READ_ADDRESS() + 0x20 callvalue return + + read_bytes32: + PERFORM_READ_BYTES32() + 0x20 callvalue return + + sizes: + PERFORM_READ_SIZES() + 0x20 callvalue return + + read_storage_slots: + PERFORM_READ_SLOTS() // [size] + callvalue // [0x00, size] + return + + decompress_transaction: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_FULL_EXECUTE(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + decompress_many_transactions: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_MANY_FULL_EXECUTES(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + // This will be appended at the end + // unreachable code as all the method return first + + nrfs: + FN_READ_FLAG(nrfs) +} + + + +#define macro READ_FULL_EXECUTE(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + READ_EXECUTE() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_MANY_FULL_EXECUTES(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + + LOAD_1_BYTE() // [size, rindex, windex] + callvalue // [i, size, rindex, windex] + swap2 // [rindex, size, i, windex] + + do_another: // [rindex, size, i, windex] + swap1 // [size, rindex, i, windex] + swap2 // [i, rindex, size, windex] + swap3 // [windex, rindex, size, i] + + READ_FULL_EXECUTE() // [windex, rindex, size, i] + + swap3 // [i, rindex, size, windex] + swap2 // [size, rindex, i, windex] + swap1 // [rindex, size, i, windex] + + swap2 // [i, size, rindex, windex] + 0x01 // [0x01, i, size, rindex, windex] + add // [(0x01 + i), size, rindex, windex] + swap2 // [rindex, size, (0x01 + i), windex] + + dup2 // [size, rindex, size, (0x01 + i), windex] + dup4 // [(0x01 + i), size, rindex, size, (0x01 + i), windex] + lt // [((0x01 + i) < size), rindex, size, (0x01 + i), windex] + do_another jumpi // [rindex, size, (0x01 + i), windex] + + swap1 // [size, rindex, (0x01 + i), windex] + swap3 // [windex, rindex, (0x01 + i), size] + + // output stack: [windex, rindex, (0x01 + i), size] +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/src/__TEMP__qcagqkszwlsndhjyagmukhxiugwadpxxL2Compressor.huff b/packages/wallet/wallet-contracts/src/__TEMP__qcagqkszwlsndhjyagmukhxiugwadpxxL2Compressor.huff new file mode 100644 index 0000000000..da1916e7d5 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/__TEMP__qcagqkszwlsndhjyagmukhxiugwadpxxL2Compressor.huff @@ -0,0 +1,142 @@ + + +#include "./L2CompressorLib.huff" + + +#define jumptable SELECTORS_TABLE { + execute_transaction // 0x00 + execute_many_transactions // 0x01 + read_address // 0x02 + read_bytes32 // 0x03 + sizes // 0x04 + read_storage_slots // 0x05 + decompress_transaction // 0x06 + decompress_many_transactions // 0x07 +} + +#define macro MAIN() = takes (0) returns (0) { + // Write the jump table to 0x20 + // or else the flags jumptable won't get written + // all this memory will be reused anyway + __tablesize(SELECTORS_TABLE) // [table_size] + __tablestart(SELECTORS_TABLE) // [table_start, table_size] + 0x20 // [0x20, table_start, table_size] + codecopy // [] + + callvalue // [0x00] + calldataload // [data[0x00]] + callvalue // [0x00, data[0x00]] + byte // [method] + + 0x05 // [0x05, method] + shl // [(method << 0x05)] + 0x20 add // [method + 0x20] + mload // [mload[method]] + jump // [] + + execute_transaction: + 0x01 // [rindex] + PERFORM_EXECUTE(nrfs) // [rindex] + callvalue callvalue return + + execute_many_transactions: + 0x01 // [rindex] + PERFORM_MANY_EXECUTES(nrfs) // [rindex, size, i] + callvalue callvalue return + + read_address: + PERFORM_READ_ADDRESS() + 0x20 callvalue return + + read_bytes32: + PERFORM_READ_BYTES32() + 0x20 callvalue return + + sizes: + PERFORM_READ_SIZES() + 0x20 callvalue return + + read_storage_slots: + PERFORM_READ_SLOTS() // [size] + callvalue // [0x00, size] + return + + decompress_transaction: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_FULL_EXECUTE(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + decompress_many_transactions: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_MANY_FULL_EXECUTES(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + // This will be appended at the end + // unreachable code as all the method return first + + nrfs: + FN_READ_FLAG(nrfs) +} + + + +#define macro READ_FULL_EXECUTE(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + READ_EXECUTE() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_MANY_FULL_EXECUTES(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + + LOAD_1_BYTE() // [size, rindex, windex] + callvalue // [i, size, rindex, windex] + swap2 // [rindex, size, i, windex] + + do_another: // [rindex, size, i, windex] + swap1 // [size, rindex, i, windex] + swap2 // [i, rindex, size, windex] + swap3 // [windex, rindex, size, i] + + READ_FULL_EXECUTE() // [windex, rindex, size, i] + + swap3 // [i, rindex, size, windex] + swap2 // [size, rindex, i, windex] + swap1 // [rindex, size, i, windex] + + swap2 // [i, size, rindex, windex] + 0x01 // [0x01, i, size, rindex, windex] + add // [(0x01 + i), size, rindex, windex] + swap2 // [rindex, size, (0x01 + i), windex] + + dup2 // [size, rindex, size, (0x01 + i), windex] + dup4 // [(0x01 + i), size, rindex, size, (0x01 + i), windex] + lt // [((0x01 + i) < size), rindex, size, (0x01 + i), windex] + do_another jumpi // [rindex, size, (0x01 + i), windex] + + swap1 // [size, rindex, (0x01 + i), windex] + swap3 // [windex, rindex, (0x01 + i), size] + + // output stack: [windex, rindex, (0x01 + i), size] +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/src/__TEMP__qymdioekngjvjjjqfpzmxlycnvbslwevL2Compressor.huff b/packages/wallet/wallet-contracts/src/__TEMP__qymdioekngjvjjjqfpzmxlycnvbslwevL2Compressor.huff new file mode 100644 index 0000000000..da1916e7d5 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/__TEMP__qymdioekngjvjjjqfpzmxlycnvbslwevL2Compressor.huff @@ -0,0 +1,142 @@ + + +#include "./L2CompressorLib.huff" + + +#define jumptable SELECTORS_TABLE { + execute_transaction // 0x00 + execute_many_transactions // 0x01 + read_address // 0x02 + read_bytes32 // 0x03 + sizes // 0x04 + read_storage_slots // 0x05 + decompress_transaction // 0x06 + decompress_many_transactions // 0x07 +} + +#define macro MAIN() = takes (0) returns (0) { + // Write the jump table to 0x20 + // or else the flags jumptable won't get written + // all this memory will be reused anyway + __tablesize(SELECTORS_TABLE) // [table_size] + __tablestart(SELECTORS_TABLE) // [table_start, table_size] + 0x20 // [0x20, table_start, table_size] + codecopy // [] + + callvalue // [0x00] + calldataload // [data[0x00]] + callvalue // [0x00, data[0x00]] + byte // [method] + + 0x05 // [0x05, method] + shl // [(method << 0x05)] + 0x20 add // [method + 0x20] + mload // [mload[method]] + jump // [] + + execute_transaction: + 0x01 // [rindex] + PERFORM_EXECUTE(nrfs) // [rindex] + callvalue callvalue return + + execute_many_transactions: + 0x01 // [rindex] + PERFORM_MANY_EXECUTES(nrfs) // [rindex, size, i] + callvalue callvalue return + + read_address: + PERFORM_READ_ADDRESS() + 0x20 callvalue return + + read_bytes32: + PERFORM_READ_BYTES32() + 0x20 callvalue return + + sizes: + PERFORM_READ_SIZES() + 0x20 callvalue return + + read_storage_slots: + PERFORM_READ_SLOTS() // [size] + callvalue // [0x00, size] + return + + decompress_transaction: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_FULL_EXECUTE(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + decompress_many_transactions: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_MANY_FULL_EXECUTES(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + // This will be appended at the end + // unreachable code as all the method return first + + nrfs: + FN_READ_FLAG(nrfs) +} + + + +#define macro READ_FULL_EXECUTE(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + READ_EXECUTE() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_MANY_FULL_EXECUTES(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + + LOAD_1_BYTE() // [size, rindex, windex] + callvalue // [i, size, rindex, windex] + swap2 // [rindex, size, i, windex] + + do_another: // [rindex, size, i, windex] + swap1 // [size, rindex, i, windex] + swap2 // [i, rindex, size, windex] + swap3 // [windex, rindex, size, i] + + READ_FULL_EXECUTE() // [windex, rindex, size, i] + + swap3 // [i, rindex, size, windex] + swap2 // [size, rindex, i, windex] + swap1 // [rindex, size, i, windex] + + swap2 // [i, size, rindex, windex] + 0x01 // [0x01, i, size, rindex, windex] + add // [(0x01 + i), size, rindex, windex] + swap2 // [rindex, size, (0x01 + i), windex] + + dup2 // [size, rindex, size, (0x01 + i), windex] + dup4 // [(0x01 + i), size, rindex, size, (0x01 + i), windex] + lt // [((0x01 + i) < size), rindex, size, (0x01 + i), windex] + do_another jumpi // [rindex, size, (0x01 + i), windex] + + swap1 // [size, rindex, (0x01 + i), windex] + swap3 // [windex, rindex, (0x01 + i), size] + + // output stack: [windex, rindex, (0x01 + i), size] +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/src/__TEMP__rpzdmcdnijxlttsivcfgzleurbgpchhzL2Compressor.huff b/packages/wallet/wallet-contracts/src/__TEMP__rpzdmcdnijxlttsivcfgzleurbgpchhzL2Compressor.huff new file mode 100644 index 0000000000..da1916e7d5 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/__TEMP__rpzdmcdnijxlttsivcfgzleurbgpchhzL2Compressor.huff @@ -0,0 +1,142 @@ + + +#include "./L2CompressorLib.huff" + + +#define jumptable SELECTORS_TABLE { + execute_transaction // 0x00 + execute_many_transactions // 0x01 + read_address // 0x02 + read_bytes32 // 0x03 + sizes // 0x04 + read_storage_slots // 0x05 + decompress_transaction // 0x06 + decompress_many_transactions // 0x07 +} + +#define macro MAIN() = takes (0) returns (0) { + // Write the jump table to 0x20 + // or else the flags jumptable won't get written + // all this memory will be reused anyway + __tablesize(SELECTORS_TABLE) // [table_size] + __tablestart(SELECTORS_TABLE) // [table_start, table_size] + 0x20 // [0x20, table_start, table_size] + codecopy // [] + + callvalue // [0x00] + calldataload // [data[0x00]] + callvalue // [0x00, data[0x00]] + byte // [method] + + 0x05 // [0x05, method] + shl // [(method << 0x05)] + 0x20 add // [method + 0x20] + mload // [mload[method]] + jump // [] + + execute_transaction: + 0x01 // [rindex] + PERFORM_EXECUTE(nrfs) // [rindex] + callvalue callvalue return + + execute_many_transactions: + 0x01 // [rindex] + PERFORM_MANY_EXECUTES(nrfs) // [rindex, size, i] + callvalue callvalue return + + read_address: + PERFORM_READ_ADDRESS() + 0x20 callvalue return + + read_bytes32: + PERFORM_READ_BYTES32() + 0x20 callvalue return + + sizes: + PERFORM_READ_SIZES() + 0x20 callvalue return + + read_storage_slots: + PERFORM_READ_SLOTS() // [size] + callvalue // [0x00, size] + return + + decompress_transaction: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_FULL_EXECUTE(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + decompress_many_transactions: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_MANY_FULL_EXECUTES(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + // This will be appended at the end + // unreachable code as all the method return first + + nrfs: + FN_READ_FLAG(nrfs) +} + + + +#define macro READ_FULL_EXECUTE(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + READ_EXECUTE() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_MANY_FULL_EXECUTES(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + + LOAD_1_BYTE() // [size, rindex, windex] + callvalue // [i, size, rindex, windex] + swap2 // [rindex, size, i, windex] + + do_another: // [rindex, size, i, windex] + swap1 // [size, rindex, i, windex] + swap2 // [i, rindex, size, windex] + swap3 // [windex, rindex, size, i] + + READ_FULL_EXECUTE() // [windex, rindex, size, i] + + swap3 // [i, rindex, size, windex] + swap2 // [size, rindex, i, windex] + swap1 // [rindex, size, i, windex] + + swap2 // [i, size, rindex, windex] + 0x01 // [0x01, i, size, rindex, windex] + add // [(0x01 + i), size, rindex, windex] + swap2 // [rindex, size, (0x01 + i), windex] + + dup2 // [size, rindex, size, (0x01 + i), windex] + dup4 // [(0x01 + i), size, rindex, size, (0x01 + i), windex] + lt // [((0x01 + i) < size), rindex, size, (0x01 + i), windex] + do_another jumpi // [rindex, size, (0x01 + i), windex] + + swap1 // [size, rindex, (0x01 + i), windex] + swap3 // [windex, rindex, (0x01 + i), size] + + // output stack: [windex, rindex, (0x01 + i), size] +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/src/__TEMP__rulclzzfmyszewnycpzlqmcopsqccarqL2Compressor.huff b/packages/wallet/wallet-contracts/src/__TEMP__rulclzzfmyszewnycpzlqmcopsqccarqL2Compressor.huff new file mode 100644 index 0000000000..da1916e7d5 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/__TEMP__rulclzzfmyszewnycpzlqmcopsqccarqL2Compressor.huff @@ -0,0 +1,142 @@ + + +#include "./L2CompressorLib.huff" + + +#define jumptable SELECTORS_TABLE { + execute_transaction // 0x00 + execute_many_transactions // 0x01 + read_address // 0x02 + read_bytes32 // 0x03 + sizes // 0x04 + read_storage_slots // 0x05 + decompress_transaction // 0x06 + decompress_many_transactions // 0x07 +} + +#define macro MAIN() = takes (0) returns (0) { + // Write the jump table to 0x20 + // or else the flags jumptable won't get written + // all this memory will be reused anyway + __tablesize(SELECTORS_TABLE) // [table_size] + __tablestart(SELECTORS_TABLE) // [table_start, table_size] + 0x20 // [0x20, table_start, table_size] + codecopy // [] + + callvalue // [0x00] + calldataload // [data[0x00]] + callvalue // [0x00, data[0x00]] + byte // [method] + + 0x05 // [0x05, method] + shl // [(method << 0x05)] + 0x20 add // [method + 0x20] + mload // [mload[method]] + jump // [] + + execute_transaction: + 0x01 // [rindex] + PERFORM_EXECUTE(nrfs) // [rindex] + callvalue callvalue return + + execute_many_transactions: + 0x01 // [rindex] + PERFORM_MANY_EXECUTES(nrfs) // [rindex, size, i] + callvalue callvalue return + + read_address: + PERFORM_READ_ADDRESS() + 0x20 callvalue return + + read_bytes32: + PERFORM_READ_BYTES32() + 0x20 callvalue return + + sizes: + PERFORM_READ_SIZES() + 0x20 callvalue return + + read_storage_slots: + PERFORM_READ_SLOTS() // [size] + callvalue // [0x00, size] + return + + decompress_transaction: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_FULL_EXECUTE(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + decompress_many_transactions: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_MANY_FULL_EXECUTES(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + // This will be appended at the end + // unreachable code as all the method return first + + nrfs: + FN_READ_FLAG(nrfs) +} + + + +#define macro READ_FULL_EXECUTE(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + READ_EXECUTE() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_MANY_FULL_EXECUTES(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + + LOAD_1_BYTE() // [size, rindex, windex] + callvalue // [i, size, rindex, windex] + swap2 // [rindex, size, i, windex] + + do_another: // [rindex, size, i, windex] + swap1 // [size, rindex, i, windex] + swap2 // [i, rindex, size, windex] + swap3 // [windex, rindex, size, i] + + READ_FULL_EXECUTE() // [windex, rindex, size, i] + + swap3 // [i, rindex, size, windex] + swap2 // [size, rindex, i, windex] + swap1 // [rindex, size, i, windex] + + swap2 // [i, size, rindex, windex] + 0x01 // [0x01, i, size, rindex, windex] + add // [(0x01 + i), size, rindex, windex] + swap2 // [rindex, size, (0x01 + i), windex] + + dup2 // [size, rindex, size, (0x01 + i), windex] + dup4 // [(0x01 + i), size, rindex, size, (0x01 + i), windex] + lt // [((0x01 + i) < size), rindex, size, (0x01 + i), windex] + do_another jumpi // [rindex, size, (0x01 + i), windex] + + swap1 // [size, rindex, (0x01 + i), windex] + swap3 // [windex, rindex, (0x01 + i), size] + + // output stack: [windex, rindex, (0x01 + i), size] +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/src/__TEMP__uexsnlcvbjyubdfmmdxzehdfcdiwufcrL2Compressor.huff b/packages/wallet/wallet-contracts/src/__TEMP__uexsnlcvbjyubdfmmdxzehdfcdiwufcrL2Compressor.huff new file mode 100644 index 0000000000..da1916e7d5 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/__TEMP__uexsnlcvbjyubdfmmdxzehdfcdiwufcrL2Compressor.huff @@ -0,0 +1,142 @@ + + +#include "./L2CompressorLib.huff" + + +#define jumptable SELECTORS_TABLE { + execute_transaction // 0x00 + execute_many_transactions // 0x01 + read_address // 0x02 + read_bytes32 // 0x03 + sizes // 0x04 + read_storage_slots // 0x05 + decompress_transaction // 0x06 + decompress_many_transactions // 0x07 +} + +#define macro MAIN() = takes (0) returns (0) { + // Write the jump table to 0x20 + // or else the flags jumptable won't get written + // all this memory will be reused anyway + __tablesize(SELECTORS_TABLE) // [table_size] + __tablestart(SELECTORS_TABLE) // [table_start, table_size] + 0x20 // [0x20, table_start, table_size] + codecopy // [] + + callvalue // [0x00] + calldataload // [data[0x00]] + callvalue // [0x00, data[0x00]] + byte // [method] + + 0x05 // [0x05, method] + shl // [(method << 0x05)] + 0x20 add // [method + 0x20] + mload // [mload[method]] + jump // [] + + execute_transaction: + 0x01 // [rindex] + PERFORM_EXECUTE(nrfs) // [rindex] + callvalue callvalue return + + execute_many_transactions: + 0x01 // [rindex] + PERFORM_MANY_EXECUTES(nrfs) // [rindex, size, i] + callvalue callvalue return + + read_address: + PERFORM_READ_ADDRESS() + 0x20 callvalue return + + read_bytes32: + PERFORM_READ_BYTES32() + 0x20 callvalue return + + sizes: + PERFORM_READ_SIZES() + 0x20 callvalue return + + read_storage_slots: + PERFORM_READ_SLOTS() // [size] + callvalue // [0x00, size] + return + + decompress_transaction: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_FULL_EXECUTE(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + decompress_many_transactions: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_MANY_FULL_EXECUTES(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + // This will be appended at the end + // unreachable code as all the method return first + + nrfs: + FN_READ_FLAG(nrfs) +} + + + +#define macro READ_FULL_EXECUTE(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + READ_EXECUTE() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_MANY_FULL_EXECUTES(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + + LOAD_1_BYTE() // [size, rindex, windex] + callvalue // [i, size, rindex, windex] + swap2 // [rindex, size, i, windex] + + do_another: // [rindex, size, i, windex] + swap1 // [size, rindex, i, windex] + swap2 // [i, rindex, size, windex] + swap3 // [windex, rindex, size, i] + + READ_FULL_EXECUTE() // [windex, rindex, size, i] + + swap3 // [i, rindex, size, windex] + swap2 // [size, rindex, i, windex] + swap1 // [rindex, size, i, windex] + + swap2 // [i, size, rindex, windex] + 0x01 // [0x01, i, size, rindex, windex] + add // [(0x01 + i), size, rindex, windex] + swap2 // [rindex, size, (0x01 + i), windex] + + dup2 // [size, rindex, size, (0x01 + i), windex] + dup4 // [(0x01 + i), size, rindex, size, (0x01 + i), windex] + lt // [((0x01 + i) < size), rindex, size, (0x01 + i), windex] + do_another jumpi // [rindex, size, (0x01 + i), windex] + + swap1 // [size, rindex, (0x01 + i), windex] + swap3 // [windex, rindex, (0x01 + i), size] + + // output stack: [windex, rindex, (0x01 + i), size] +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/src/__TEMP__ughbfnqmhbdbiuueqxutuvcxicgrmnxwL2Compressor.huff b/packages/wallet/wallet-contracts/src/__TEMP__ughbfnqmhbdbiuueqxutuvcxicgrmnxwL2Compressor.huff new file mode 100644 index 0000000000..da1916e7d5 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/__TEMP__ughbfnqmhbdbiuueqxutuvcxicgrmnxwL2Compressor.huff @@ -0,0 +1,142 @@ + + +#include "./L2CompressorLib.huff" + + +#define jumptable SELECTORS_TABLE { + execute_transaction // 0x00 + execute_many_transactions // 0x01 + read_address // 0x02 + read_bytes32 // 0x03 + sizes // 0x04 + read_storage_slots // 0x05 + decompress_transaction // 0x06 + decompress_many_transactions // 0x07 +} + +#define macro MAIN() = takes (0) returns (0) { + // Write the jump table to 0x20 + // or else the flags jumptable won't get written + // all this memory will be reused anyway + __tablesize(SELECTORS_TABLE) // [table_size] + __tablestart(SELECTORS_TABLE) // [table_start, table_size] + 0x20 // [0x20, table_start, table_size] + codecopy // [] + + callvalue // [0x00] + calldataload // [data[0x00]] + callvalue // [0x00, data[0x00]] + byte // [method] + + 0x05 // [0x05, method] + shl // [(method << 0x05)] + 0x20 add // [method + 0x20] + mload // [mload[method]] + jump // [] + + execute_transaction: + 0x01 // [rindex] + PERFORM_EXECUTE(nrfs) // [rindex] + callvalue callvalue return + + execute_many_transactions: + 0x01 // [rindex] + PERFORM_MANY_EXECUTES(nrfs) // [rindex, size, i] + callvalue callvalue return + + read_address: + PERFORM_READ_ADDRESS() + 0x20 callvalue return + + read_bytes32: + PERFORM_READ_BYTES32() + 0x20 callvalue return + + sizes: + PERFORM_READ_SIZES() + 0x20 callvalue return + + read_storage_slots: + PERFORM_READ_SLOTS() // [size] + callvalue // [0x00, size] + return + + decompress_transaction: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_FULL_EXECUTE(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + decompress_many_transactions: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_MANY_FULL_EXECUTES(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + // This will be appended at the end + // unreachable code as all the method return first + + nrfs: + FN_READ_FLAG(nrfs) +} + + + +#define macro READ_FULL_EXECUTE(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + READ_EXECUTE() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_MANY_FULL_EXECUTES(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + + LOAD_1_BYTE() // [size, rindex, windex] + callvalue // [i, size, rindex, windex] + swap2 // [rindex, size, i, windex] + + do_another: // [rindex, size, i, windex] + swap1 // [size, rindex, i, windex] + swap2 // [i, rindex, size, windex] + swap3 // [windex, rindex, size, i] + + READ_FULL_EXECUTE() // [windex, rindex, size, i] + + swap3 // [i, rindex, size, windex] + swap2 // [size, rindex, i, windex] + swap1 // [rindex, size, i, windex] + + swap2 // [i, size, rindex, windex] + 0x01 // [0x01, i, size, rindex, windex] + add // [(0x01 + i), size, rindex, windex] + swap2 // [rindex, size, (0x01 + i), windex] + + dup2 // [size, rindex, size, (0x01 + i), windex] + dup4 // [(0x01 + i), size, rindex, size, (0x01 + i), windex] + lt // [((0x01 + i) < size), rindex, size, (0x01 + i), windex] + do_another jumpi // [rindex, size, (0x01 + i), windex] + + swap1 // [size, rindex, (0x01 + i), windex] + swap3 // [windex, rindex, (0x01 + i), size] + + // output stack: [windex, rindex, (0x01 + i), size] +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/src/__TEMP__uzsvtiqnxxrhkhfelgdrwmnbwwirribaL2Compressor.huff b/packages/wallet/wallet-contracts/src/__TEMP__uzsvtiqnxxrhkhfelgdrwmnbwwirribaL2Compressor.huff new file mode 100644 index 0000000000..da1916e7d5 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/__TEMP__uzsvtiqnxxrhkhfelgdrwmnbwwirribaL2Compressor.huff @@ -0,0 +1,142 @@ + + +#include "./L2CompressorLib.huff" + + +#define jumptable SELECTORS_TABLE { + execute_transaction // 0x00 + execute_many_transactions // 0x01 + read_address // 0x02 + read_bytes32 // 0x03 + sizes // 0x04 + read_storage_slots // 0x05 + decompress_transaction // 0x06 + decompress_many_transactions // 0x07 +} + +#define macro MAIN() = takes (0) returns (0) { + // Write the jump table to 0x20 + // or else the flags jumptable won't get written + // all this memory will be reused anyway + __tablesize(SELECTORS_TABLE) // [table_size] + __tablestart(SELECTORS_TABLE) // [table_start, table_size] + 0x20 // [0x20, table_start, table_size] + codecopy // [] + + callvalue // [0x00] + calldataload // [data[0x00]] + callvalue // [0x00, data[0x00]] + byte // [method] + + 0x05 // [0x05, method] + shl // [(method << 0x05)] + 0x20 add // [method + 0x20] + mload // [mload[method]] + jump // [] + + execute_transaction: + 0x01 // [rindex] + PERFORM_EXECUTE(nrfs) // [rindex] + callvalue callvalue return + + execute_many_transactions: + 0x01 // [rindex] + PERFORM_MANY_EXECUTES(nrfs) // [rindex, size, i] + callvalue callvalue return + + read_address: + PERFORM_READ_ADDRESS() + 0x20 callvalue return + + read_bytes32: + PERFORM_READ_BYTES32() + 0x20 callvalue return + + sizes: + PERFORM_READ_SIZES() + 0x20 callvalue return + + read_storage_slots: + PERFORM_READ_SLOTS() // [size] + callvalue // [0x00, size] + return + + decompress_transaction: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_FULL_EXECUTE(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + decompress_many_transactions: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_MANY_FULL_EXECUTES(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + // This will be appended at the end + // unreachable code as all the method return first + + nrfs: + FN_READ_FLAG(nrfs) +} + + + +#define macro READ_FULL_EXECUTE(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + READ_EXECUTE() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_MANY_FULL_EXECUTES(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + + LOAD_1_BYTE() // [size, rindex, windex] + callvalue // [i, size, rindex, windex] + swap2 // [rindex, size, i, windex] + + do_another: // [rindex, size, i, windex] + swap1 // [size, rindex, i, windex] + swap2 // [i, rindex, size, windex] + swap3 // [windex, rindex, size, i] + + READ_FULL_EXECUTE() // [windex, rindex, size, i] + + swap3 // [i, rindex, size, windex] + swap2 // [size, rindex, i, windex] + swap1 // [rindex, size, i, windex] + + swap2 // [i, size, rindex, windex] + 0x01 // [0x01, i, size, rindex, windex] + add // [(0x01 + i), size, rindex, windex] + swap2 // [rindex, size, (0x01 + i), windex] + + dup2 // [size, rindex, size, (0x01 + i), windex] + dup4 // [(0x01 + i), size, rindex, size, (0x01 + i), windex] + lt // [((0x01 + i) < size), rindex, size, (0x01 + i), windex] + do_another jumpi // [rindex, size, (0x01 + i), windex] + + swap1 // [size, rindex, (0x01 + i), windex] + swap3 // [windex, rindex, (0x01 + i), size] + + // output stack: [windex, rindex, (0x01 + i), size] +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/src/__TEMP__vffsqkjyicdnumnesfhcjlgtqguwdpnpL2Compressor.huff b/packages/wallet/wallet-contracts/src/__TEMP__vffsqkjyicdnumnesfhcjlgtqguwdpnpL2Compressor.huff new file mode 100644 index 0000000000..da1916e7d5 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/__TEMP__vffsqkjyicdnumnesfhcjlgtqguwdpnpL2Compressor.huff @@ -0,0 +1,142 @@ + + +#include "./L2CompressorLib.huff" + + +#define jumptable SELECTORS_TABLE { + execute_transaction // 0x00 + execute_many_transactions // 0x01 + read_address // 0x02 + read_bytes32 // 0x03 + sizes // 0x04 + read_storage_slots // 0x05 + decompress_transaction // 0x06 + decompress_many_transactions // 0x07 +} + +#define macro MAIN() = takes (0) returns (0) { + // Write the jump table to 0x20 + // or else the flags jumptable won't get written + // all this memory will be reused anyway + __tablesize(SELECTORS_TABLE) // [table_size] + __tablestart(SELECTORS_TABLE) // [table_start, table_size] + 0x20 // [0x20, table_start, table_size] + codecopy // [] + + callvalue // [0x00] + calldataload // [data[0x00]] + callvalue // [0x00, data[0x00]] + byte // [method] + + 0x05 // [0x05, method] + shl // [(method << 0x05)] + 0x20 add // [method + 0x20] + mload // [mload[method]] + jump // [] + + execute_transaction: + 0x01 // [rindex] + PERFORM_EXECUTE(nrfs) // [rindex] + callvalue callvalue return + + execute_many_transactions: + 0x01 // [rindex] + PERFORM_MANY_EXECUTES(nrfs) // [rindex, size, i] + callvalue callvalue return + + read_address: + PERFORM_READ_ADDRESS() + 0x20 callvalue return + + read_bytes32: + PERFORM_READ_BYTES32() + 0x20 callvalue return + + sizes: + PERFORM_READ_SIZES() + 0x20 callvalue return + + read_storage_slots: + PERFORM_READ_SLOTS() // [size] + callvalue // [0x00, size] + return + + decompress_transaction: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_FULL_EXECUTE(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + decompress_many_transactions: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_MANY_FULL_EXECUTES(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + // This will be appended at the end + // unreachable code as all the method return first + + nrfs: + FN_READ_FLAG(nrfs) +} + + + +#define macro READ_FULL_EXECUTE(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + READ_EXECUTE() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_MANY_FULL_EXECUTES(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + + LOAD_1_BYTE() // [size, rindex, windex] + callvalue // [i, size, rindex, windex] + swap2 // [rindex, size, i, windex] + + do_another: // [rindex, size, i, windex] + swap1 // [size, rindex, i, windex] + swap2 // [i, rindex, size, windex] + swap3 // [windex, rindex, size, i] + + READ_FULL_EXECUTE() // [windex, rindex, size, i] + + swap3 // [i, rindex, size, windex] + swap2 // [size, rindex, i, windex] + swap1 // [rindex, size, i, windex] + + swap2 // [i, size, rindex, windex] + 0x01 // [0x01, i, size, rindex, windex] + add // [(0x01 + i), size, rindex, windex] + swap2 // [rindex, size, (0x01 + i), windex] + + dup2 // [size, rindex, size, (0x01 + i), windex] + dup4 // [(0x01 + i), size, rindex, size, (0x01 + i), windex] + lt // [((0x01 + i) < size), rindex, size, (0x01 + i), windex] + do_another jumpi // [rindex, size, (0x01 + i), windex] + + swap1 // [size, rindex, (0x01 + i), windex] + swap3 // [windex, rindex, (0x01 + i), size] + + // output stack: [windex, rindex, (0x01 + i), size] +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/src/__TEMP__vtbpzpccsyytsvygxsyhvyojjbqsghpbL2Compressor.huff b/packages/wallet/wallet-contracts/src/__TEMP__vtbpzpccsyytsvygxsyhvyojjbqsghpbL2Compressor.huff new file mode 100644 index 0000000000..da1916e7d5 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/__TEMP__vtbpzpccsyytsvygxsyhvyojjbqsghpbL2Compressor.huff @@ -0,0 +1,142 @@ + + +#include "./L2CompressorLib.huff" + + +#define jumptable SELECTORS_TABLE { + execute_transaction // 0x00 + execute_many_transactions // 0x01 + read_address // 0x02 + read_bytes32 // 0x03 + sizes // 0x04 + read_storage_slots // 0x05 + decompress_transaction // 0x06 + decompress_many_transactions // 0x07 +} + +#define macro MAIN() = takes (0) returns (0) { + // Write the jump table to 0x20 + // or else the flags jumptable won't get written + // all this memory will be reused anyway + __tablesize(SELECTORS_TABLE) // [table_size] + __tablestart(SELECTORS_TABLE) // [table_start, table_size] + 0x20 // [0x20, table_start, table_size] + codecopy // [] + + callvalue // [0x00] + calldataload // [data[0x00]] + callvalue // [0x00, data[0x00]] + byte // [method] + + 0x05 // [0x05, method] + shl // [(method << 0x05)] + 0x20 add // [method + 0x20] + mload // [mload[method]] + jump // [] + + execute_transaction: + 0x01 // [rindex] + PERFORM_EXECUTE(nrfs) // [rindex] + callvalue callvalue return + + execute_many_transactions: + 0x01 // [rindex] + PERFORM_MANY_EXECUTES(nrfs) // [rindex, size, i] + callvalue callvalue return + + read_address: + PERFORM_READ_ADDRESS() + 0x20 callvalue return + + read_bytes32: + PERFORM_READ_BYTES32() + 0x20 callvalue return + + sizes: + PERFORM_READ_SIZES() + 0x20 callvalue return + + read_storage_slots: + PERFORM_READ_SLOTS() // [size] + callvalue // [0x00, size] + return + + decompress_transaction: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_FULL_EXECUTE(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + decompress_many_transactions: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_MANY_FULL_EXECUTES(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + // This will be appended at the end + // unreachable code as all the method return first + + nrfs: + FN_READ_FLAG(nrfs) +} + + + +#define macro READ_FULL_EXECUTE(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + READ_EXECUTE() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_MANY_FULL_EXECUTES(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + + LOAD_1_BYTE() // [size, rindex, windex] + callvalue // [i, size, rindex, windex] + swap2 // [rindex, size, i, windex] + + do_another: // [rindex, size, i, windex] + swap1 // [size, rindex, i, windex] + swap2 // [i, rindex, size, windex] + swap3 // [windex, rindex, size, i] + + READ_FULL_EXECUTE() // [windex, rindex, size, i] + + swap3 // [i, rindex, size, windex] + swap2 // [size, rindex, i, windex] + swap1 // [rindex, size, i, windex] + + swap2 // [i, size, rindex, windex] + 0x01 // [0x01, i, size, rindex, windex] + add // [(0x01 + i), size, rindex, windex] + swap2 // [rindex, size, (0x01 + i), windex] + + dup2 // [size, rindex, size, (0x01 + i), windex] + dup4 // [(0x01 + i), size, rindex, size, (0x01 + i), windex] + lt // [((0x01 + i) < size), rindex, size, (0x01 + i), windex] + do_another jumpi // [rindex, size, (0x01 + i), windex] + + swap1 // [size, rindex, (0x01 + i), windex] + swap3 // [windex, rindex, (0x01 + i), size] + + // output stack: [windex, rindex, (0x01 + i), size] +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/src/__TEMP__xhuychsyvcmrjzhibkdksklxflvtfefdL2Compressor.huff b/packages/wallet/wallet-contracts/src/__TEMP__xhuychsyvcmrjzhibkdksklxflvtfefdL2Compressor.huff new file mode 100644 index 0000000000..da1916e7d5 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/__TEMP__xhuychsyvcmrjzhibkdksklxflvtfefdL2Compressor.huff @@ -0,0 +1,142 @@ + + +#include "./L2CompressorLib.huff" + + +#define jumptable SELECTORS_TABLE { + execute_transaction // 0x00 + execute_many_transactions // 0x01 + read_address // 0x02 + read_bytes32 // 0x03 + sizes // 0x04 + read_storage_slots // 0x05 + decompress_transaction // 0x06 + decompress_many_transactions // 0x07 +} + +#define macro MAIN() = takes (0) returns (0) { + // Write the jump table to 0x20 + // or else the flags jumptable won't get written + // all this memory will be reused anyway + __tablesize(SELECTORS_TABLE) // [table_size] + __tablestart(SELECTORS_TABLE) // [table_start, table_size] + 0x20 // [0x20, table_start, table_size] + codecopy // [] + + callvalue // [0x00] + calldataload // [data[0x00]] + callvalue // [0x00, data[0x00]] + byte // [method] + + 0x05 // [0x05, method] + shl // [(method << 0x05)] + 0x20 add // [method + 0x20] + mload // [mload[method]] + jump // [] + + execute_transaction: + 0x01 // [rindex] + PERFORM_EXECUTE(nrfs) // [rindex] + callvalue callvalue return + + execute_many_transactions: + 0x01 // [rindex] + PERFORM_MANY_EXECUTES(nrfs) // [rindex, size, i] + callvalue callvalue return + + read_address: + PERFORM_READ_ADDRESS() + 0x20 callvalue return + + read_bytes32: + PERFORM_READ_BYTES32() + 0x20 callvalue return + + sizes: + PERFORM_READ_SIZES() + 0x20 callvalue return + + read_storage_slots: + PERFORM_READ_SLOTS() // [size] + callvalue // [0x00, size] + return + + decompress_transaction: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_FULL_EXECUTE(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + decompress_many_transactions: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_MANY_FULL_EXECUTES(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + // This will be appended at the end + // unreachable code as all the method return first + + nrfs: + FN_READ_FLAG(nrfs) +} + + + +#define macro READ_FULL_EXECUTE(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + READ_EXECUTE() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_MANY_FULL_EXECUTES(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + + LOAD_1_BYTE() // [size, rindex, windex] + callvalue // [i, size, rindex, windex] + swap2 // [rindex, size, i, windex] + + do_another: // [rindex, size, i, windex] + swap1 // [size, rindex, i, windex] + swap2 // [i, rindex, size, windex] + swap3 // [windex, rindex, size, i] + + READ_FULL_EXECUTE() // [windex, rindex, size, i] + + swap3 // [i, rindex, size, windex] + swap2 // [size, rindex, i, windex] + swap1 // [rindex, size, i, windex] + + swap2 // [i, size, rindex, windex] + 0x01 // [0x01, i, size, rindex, windex] + add // [(0x01 + i), size, rindex, windex] + swap2 // [rindex, size, (0x01 + i), windex] + + dup2 // [size, rindex, size, (0x01 + i), windex] + dup4 // [(0x01 + i), size, rindex, size, (0x01 + i), windex] + lt // [((0x01 + i) < size), rindex, size, (0x01 + i), windex] + do_another jumpi // [rindex, size, (0x01 + i), windex] + + swap1 // [size, rindex, (0x01 + i), windex] + swap3 // [windex, rindex, (0x01 + i), size] + + // output stack: [windex, rindex, (0x01 + i), size] +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/src/__TEMP__ylxrpbrfcykqjxgggzptgdvokhmzcvamL2Compressor.huff b/packages/wallet/wallet-contracts/src/__TEMP__ylxrpbrfcykqjxgggzptgdvokhmzcvamL2Compressor.huff new file mode 100644 index 0000000000..da1916e7d5 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/__TEMP__ylxrpbrfcykqjxgggzptgdvokhmzcvamL2Compressor.huff @@ -0,0 +1,142 @@ + + +#include "./L2CompressorLib.huff" + + +#define jumptable SELECTORS_TABLE { + execute_transaction // 0x00 + execute_many_transactions // 0x01 + read_address // 0x02 + read_bytes32 // 0x03 + sizes // 0x04 + read_storage_slots // 0x05 + decompress_transaction // 0x06 + decompress_many_transactions // 0x07 +} + +#define macro MAIN() = takes (0) returns (0) { + // Write the jump table to 0x20 + // or else the flags jumptable won't get written + // all this memory will be reused anyway + __tablesize(SELECTORS_TABLE) // [table_size] + __tablestart(SELECTORS_TABLE) // [table_start, table_size] + 0x20 // [0x20, table_start, table_size] + codecopy // [] + + callvalue // [0x00] + calldataload // [data[0x00]] + callvalue // [0x00, data[0x00]] + byte // [method] + + 0x05 // [0x05, method] + shl // [(method << 0x05)] + 0x20 add // [method + 0x20] + mload // [mload[method]] + jump // [] + + execute_transaction: + 0x01 // [rindex] + PERFORM_EXECUTE(nrfs) // [rindex] + callvalue callvalue return + + execute_many_transactions: + 0x01 // [rindex] + PERFORM_MANY_EXECUTES(nrfs) // [rindex, size, i] + callvalue callvalue return + + read_address: + PERFORM_READ_ADDRESS() + 0x20 callvalue return + + read_bytes32: + PERFORM_READ_BYTES32() + 0x20 callvalue return + + sizes: + PERFORM_READ_SIZES() + 0x20 callvalue return + + read_storage_slots: + PERFORM_READ_SLOTS() // [size] + callvalue // [0x00, size] + return + + decompress_transaction: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_FULL_EXECUTE(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + decompress_many_transactions: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_MANY_FULL_EXECUTES(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + // This will be appended at the end + // unreachable code as all the method return first + + nrfs: + FN_READ_FLAG(nrfs) +} + + + +#define macro READ_FULL_EXECUTE(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + READ_EXECUTE() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_MANY_FULL_EXECUTES(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + + LOAD_1_BYTE() // [size, rindex, windex] + callvalue // [i, size, rindex, windex] + swap2 // [rindex, size, i, windex] + + do_another: // [rindex, size, i, windex] + swap1 // [size, rindex, i, windex] + swap2 // [i, rindex, size, windex] + swap3 // [windex, rindex, size, i] + + READ_FULL_EXECUTE() // [windex, rindex, size, i] + + swap3 // [i, rindex, size, windex] + swap2 // [size, rindex, i, windex] + swap1 // [rindex, size, i, windex] + + swap2 // [i, size, rindex, windex] + 0x01 // [0x01, i, size, rindex, windex] + add // [(0x01 + i), size, rindex, windex] + swap2 // [rindex, size, (0x01 + i), windex] + + dup2 // [size, rindex, size, (0x01 + i), windex] + dup4 // [(0x01 + i), size, rindex, size, (0x01 + i), windex] + lt // [((0x01 + i) < size), rindex, size, (0x01 + i), windex] + do_another jumpi // [rindex, size, (0x01 + i), windex] + + swap1 // [size, rindex, (0x01 + i), windex] + swap3 // [windex, rindex, (0x01 + i), size] + + // output stack: [windex, rindex, (0x01 + i), size] +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/src/__TEMP__zkzjzrglozoqyyfvpcdqeanjxglmtzbbL2Compressor.huff b/packages/wallet/wallet-contracts/src/__TEMP__zkzjzrglozoqyyfvpcdqeanjxglmtzbbL2Compressor.huff new file mode 100644 index 0000000000..da1916e7d5 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/__TEMP__zkzjzrglozoqyyfvpcdqeanjxglmtzbbL2Compressor.huff @@ -0,0 +1,142 @@ + + +#include "./L2CompressorLib.huff" + + +#define jumptable SELECTORS_TABLE { + execute_transaction // 0x00 + execute_many_transactions // 0x01 + read_address // 0x02 + read_bytes32 // 0x03 + sizes // 0x04 + read_storage_slots // 0x05 + decompress_transaction // 0x06 + decompress_many_transactions // 0x07 +} + +#define macro MAIN() = takes (0) returns (0) { + // Write the jump table to 0x20 + // or else the flags jumptable won't get written + // all this memory will be reused anyway + __tablesize(SELECTORS_TABLE) // [table_size] + __tablestart(SELECTORS_TABLE) // [table_start, table_size] + 0x20 // [0x20, table_start, table_size] + codecopy // [] + + callvalue // [0x00] + calldataload // [data[0x00]] + callvalue // [0x00, data[0x00]] + byte // [method] + + 0x05 // [0x05, method] + shl // [(method << 0x05)] + 0x20 add // [method + 0x20] + mload // [mload[method]] + jump // [] + + execute_transaction: + 0x01 // [rindex] + PERFORM_EXECUTE(nrfs) // [rindex] + callvalue callvalue return + + execute_many_transactions: + 0x01 // [rindex] + PERFORM_MANY_EXECUTES(nrfs) // [rindex, size, i] + callvalue callvalue return + + read_address: + PERFORM_READ_ADDRESS() + 0x20 callvalue return + + read_bytes32: + PERFORM_READ_BYTES32() + 0x20 callvalue return + + sizes: + PERFORM_READ_SIZES() + 0x20 callvalue return + + read_storage_slots: + PERFORM_READ_SLOTS() // [size] + callvalue // [0x00, size] + return + + decompress_transaction: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_FULL_EXECUTE(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + decompress_many_transactions: + 0x01 // [rindex] + [FMS] // [windex, rindex] + + READ_MANY_FULL_EXECUTES(nrfs) // [windex, rindex] + + [FMS] // [FMS, windex, rindex] + swap1 // [windex, FMS, rindex] + sub // [(windex - FMS), rindex] + + [FMS] // [FMS, (windex - FMS), rindex] + return // [rindex] + + // This will be appended at the end + // unreachable code as all the method return first + + nrfs: + FN_READ_FLAG(nrfs) +} + + + +#define macro READ_FULL_EXECUTE(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + READ_EXECUTE() // [windex, rindex] + PERFORM_NESTED_READ_FLAG() // [windex, rindex] + + // output stack: [windex, rindex] +} + +#define macro READ_MANY_FULL_EXECUTES(nrfs) = takes (2) returns (2) { + // input stack: [windex, rindex] + + swap1 // [rindex, windex] + + LOAD_1_BYTE() // [size, rindex, windex] + callvalue // [i, size, rindex, windex] + swap2 // [rindex, size, i, windex] + + do_another: // [rindex, size, i, windex] + swap1 // [size, rindex, i, windex] + swap2 // [i, rindex, size, windex] + swap3 // [windex, rindex, size, i] + + READ_FULL_EXECUTE() // [windex, rindex, size, i] + + swap3 // [i, rindex, size, windex] + swap2 // [size, rindex, i, windex] + swap1 // [rindex, size, i, windex] + + swap2 // [i, size, rindex, windex] + 0x01 // [0x01, i, size, rindex, windex] + add // [(0x01 + i), size, rindex, windex] + swap2 // [rindex, size, (0x01 + i), windex] + + dup2 // [size, rindex, size, (0x01 + i), windex] + dup4 // [(0x01 + i), size, rindex, size, (0x01 + i), windex] + lt // [((0x01 + i) < size), rindex, size, (0x01 + i), windex] + do_another jumpi // [rindex, size, (0x01 + i), windex] + + swap1 // [size, rindex, (0x01 + i), windex] + swap3 // [windex, rindex, (0x01 + i), size] + + // output stack: [windex, rindex, (0x01 + i), size] +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/src/imps/L2CompressorImps.huff b/packages/wallet/wallet-contracts/src/imps/L2CompressorImps.huff new file mode 100644 index 0000000000..6ea7dad705 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/L2CompressorImps.huff @@ -0,0 +1,52 @@ +#include "../L2CompressorLib.huff" + +#define function testLoadDynamicSize(bytes32 _a, bytes32 _b, uint256, uint256) view returns (uint256, uint256, bytes32) +#define function testReadBytes32(bytes32 _a, bytes32 _b, uint256, uint256, uint256) view returns (uint256, uint256) + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // Identify which function is being called. + 0x00 calldataload 0xE0 shr // [func_sig] + + dup1 __FUNC_SIG(testLoadDynamicSize) eq testLoadDynamicSize jumpi + dup1 __FUNC_SIG(testReadBytes32) eq testReadBytes32 jumpi + + // Revert if no match is found. + 0x00 dup1 revert + + testLoadDynamicSize: + IMP_LOAD_DYNAMIC_SIZE() + + testReadBytes32: + IMP_READ_BYTES32() +} + +#define macro IMP_LOAD_DYNAMIC_SIZE() = takes (2) returns (0) { + 0x04 0x40 add calldataload // [rindex] + 0x04 0x60 add calldataload // [size, rindex] + + LOAD_DYNAMIC_SIZE() // [size bits, rindex + size] + + 0x00 mstore // [rindex + size] + 0x20 mstore // [] + + 0x40 0x00 return +} + +#define macro IMP_READ_BYTES32() = takes (3) returns (2) { + 0x04 0x40 add calldataload // [rindex] + 0x04 0x60 add calldataload // [windex, rindex] + 0x04 0x80 add calldataload // [flag, windex, rindex] + + READ_BYTES32() // [windex, rindex] + + 0x00 mstore // [rindex] + 0x20 mstore // [] + + 0x04 0x60 add calldataload // [windex] + mload // [written] + + 0x40 mstore // [] + + 0x60 0x00 return +} \ No newline at end of file diff --git a/packages/wallet/wallet-contracts/src/imps/L2CompressorReadExecute.huff b/packages/wallet/wallet-contracts/src/imps/L2CompressorReadExecute.huff new file mode 100644 index 0000000000..b75163c894 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/L2CompressorReadExecute.huff @@ -0,0 +1,30 @@ +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_EXECUTE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/L2CompressorReadFlag.huff b/packages/wallet/wallet-contracts/src/imps/L2CompressorReadFlag.huff new file mode 100644 index 0000000000..a046df2368 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/L2CompressorReadFlag.huff @@ -0,0 +1,30 @@ +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_FLAG() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/L2CompressorReadNonce.huff b/packages/wallet/wallet-contracts/src/imps/L2CompressorReadNonce.huff new file mode 100644 index 0000000000..847b600317 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/L2CompressorReadNonce.huff @@ -0,0 +1,30 @@ +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_NONCE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/L2CompressorReadTx.huff b/packages/wallet/wallet-contracts/src/imps/L2CompressorReadTx.huff new file mode 100644 index 0000000000..113e35ba87 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/L2CompressorReadTx.huff @@ -0,0 +1,30 @@ +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTION_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/L2CompressorReadTxs.huff b/packages/wallet/wallet-contracts/src/imps/L2CompressorReadTxs.huff new file mode 100644 index 0000000000..a5042b2f4c --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/L2CompressorReadTxs.huff @@ -0,0 +1,30 @@ +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTIONS_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__aayxscdgqfgqckqcfvplniuqleqmglgpL2CompressorReadNonce.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__aayxscdgqfgqckqcfvplniuqleqmglgpL2CompressorReadNonce.huff new file mode 100644 index 0000000000..eb09bd2b6d --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__aayxscdgqfgqckqcfvplniuqleqmglgpL2CompressorReadNonce.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_NONCE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__agjsoduxivwxbunbrskpnttujfxlnsuqL2CompressorReadFlag.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__agjsoduxivwxbunbrskpnttujfxlnsuqL2CompressorReadFlag.huff new file mode 100644 index 0000000000..6bc3f6157c --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__agjsoduxivwxbunbrskpnttujfxlnsuqL2CompressorReadFlag.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_FLAG() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__aozfhsjnhfgdhkvygupcezykxnllxhooL2CompressorReadTx.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__aozfhsjnhfgdhkvygupcezykxnllxhooL2CompressorReadTx.huff new file mode 100644 index 0000000000..8c9f99fc5b --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__aozfhsjnhfgdhkvygupcezykxnllxhooL2CompressorReadTx.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTION_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__auoqqxuvhsugblxkhmuynutuutdpetfmL2CompressorReadNonce.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__auoqqxuvhsugblxkhmuynutuutdpetfmL2CompressorReadNonce.huff new file mode 100644 index 0000000000..eb09bd2b6d --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__auoqqxuvhsugblxkhmuynutuutdpetfmL2CompressorReadNonce.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_NONCE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__bgiysfzlfrqnqopegdijkxkzjebeugweL2CompressorReadExecute.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__bgiysfzlfrqnqopegdijkxkzjebeugweL2CompressorReadExecute.huff new file mode 100644 index 0000000000..7351d4df36 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__bgiysfzlfrqnqopegdijkxkzjebeugweL2CompressorReadExecute.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_EXECUTE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__bhcstacsnwaeevimfyeuyukrpkefkpjvL2CompressorReadTx.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__bhcstacsnwaeevimfyeuyukrpkefkpjvL2CompressorReadTx.huff new file mode 100644 index 0000000000..8c9f99fc5b --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__bhcstacsnwaeevimfyeuyukrpkefkpjvL2CompressorReadTx.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTION_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__bjodacjzehrzeexubslwqheqqdtpojdxL2CompressorReadTxs.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__bjodacjzehrzeexubslwqheqqdtpojdxL2CompressorReadTxs.huff new file mode 100644 index 0000000000..4a6f01a186 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__bjodacjzehrzeexubslwqheqqdtpojdxL2CompressorReadTxs.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTIONS_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__bqzqrnjvdcsevkfpbluzvxgnvfnbjbvdL2CompressorReadTxs.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__bqzqrnjvdcsevkfpbluzvxgnvfnbjbvdL2CompressorReadTxs.huff new file mode 100644 index 0000000000..4a6f01a186 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__bqzqrnjvdcsevkfpbluzvxgnvfnbjbvdL2CompressorReadTxs.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTIONS_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__bxxjqefyxrrctwjijuvxauktfiveuhazL2CompressorReadNonce.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__bxxjqefyxrrctwjijuvxauktfiveuhazL2CompressorReadNonce.huff new file mode 100644 index 0000000000..eb09bd2b6d --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__bxxjqefyxrrctwjijuvxauktfiveuhazL2CompressorReadNonce.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_NONCE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__cczbajsfeehqceablvdedlohtwcpgruiL2CompressorReadTx.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__cczbajsfeehqceablvdedlohtwcpgruiL2CompressorReadTx.huff new file mode 100644 index 0000000000..8c9f99fc5b --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__cczbajsfeehqceablvdedlohtwcpgruiL2CompressorReadTx.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTION_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__ceqwybpkmvqejmujxdddmmbuqrzcvpqlL2CompressorReadTxs.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__ceqwybpkmvqejmujxdddmmbuqrzcvpqlL2CompressorReadTxs.huff new file mode 100644 index 0000000000..4a6f01a186 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__ceqwybpkmvqejmujxdddmmbuqrzcvpqlL2CompressorReadTxs.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTIONS_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__cinzltxsvuofyvnmuiiddtfwsyytzwszL2CompressorReadFlag.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__cinzltxsvuofyvnmuiiddtfwsyytzwszL2CompressorReadFlag.huff new file mode 100644 index 0000000000..6bc3f6157c --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__cinzltxsvuofyvnmuiiddtfwsyytzwszL2CompressorReadFlag.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_FLAG() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__ckntqzzuqphqsecwtcwuiczrfadymzpwL2CompressorReadTx.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__ckntqzzuqphqsecwtcwuiczrfadymzpwL2CompressorReadTx.huff new file mode 100644 index 0000000000..8c9f99fc5b --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__ckntqzzuqphqsecwtcwuiczrfadymzpwL2CompressorReadTx.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTION_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__ctxqvslrdaagplfabzhyfjejoyhqoxvnL2CompressorReadTx.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__ctxqvslrdaagplfabzhyfjejoyhqoxvnL2CompressorReadTx.huff new file mode 100644 index 0000000000..8c9f99fc5b --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__ctxqvslrdaagplfabzhyfjejoyhqoxvnL2CompressorReadTx.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTION_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__cxyftrlslztbljuqlicrbibyyssybguhL2CompressorReadNonce.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__cxyftrlslztbljuqlicrbibyyssybguhL2CompressorReadNonce.huff new file mode 100644 index 0000000000..eb09bd2b6d --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__cxyftrlslztbljuqlicrbibyyssybguhL2CompressorReadNonce.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_NONCE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__cyxkjqcsonpojbyksbsvglcrgoqbepkaL2CompressorReadExecute.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__cyxkjqcsonpojbyksbsvglcrgoqbepkaL2CompressorReadExecute.huff new file mode 100644 index 0000000000..7351d4df36 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__cyxkjqcsonpojbyksbsvglcrgoqbepkaL2CompressorReadExecute.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_EXECUTE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__deeivxbssjzviqkksdozrardbmkofvggL2CompressorReadFlag.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__deeivxbssjzviqkksdozrardbmkofvggL2CompressorReadFlag.huff new file mode 100644 index 0000000000..6bc3f6157c --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__deeivxbssjzviqkksdozrardbmkofvggL2CompressorReadFlag.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_FLAG() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__dexeqmbbqijqudvjnczxedpzkrqkrxgpL2CompressorReadExecute.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__dexeqmbbqijqudvjnczxedpzkrqkrxgpL2CompressorReadExecute.huff new file mode 100644 index 0000000000..7351d4df36 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__dexeqmbbqijqudvjnczxedpzkrqkrxgpL2CompressorReadExecute.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_EXECUTE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__ebpduriemctxazssijauhsotgyqtayygL2CompressorReadTxs.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__ebpduriemctxazssijauhsotgyqtayygL2CompressorReadTxs.huff new file mode 100644 index 0000000000..4a6f01a186 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__ebpduriemctxazssijauhsotgyqtayygL2CompressorReadTxs.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTIONS_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__edfwesooemxojadwrkmombuemzhicuirL2CompressorReadTxs.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__edfwesooemxojadwrkmombuemzhicuirL2CompressorReadTxs.huff new file mode 100644 index 0000000000..4a6f01a186 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__edfwesooemxojadwrkmombuemzhicuirL2CompressorReadTxs.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTIONS_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__eicqyirjstlxuotvptvgszvdeemgpomnL2CompressorReadTxs.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__eicqyirjstlxuotvptvgszvdeemgpomnL2CompressorReadTxs.huff new file mode 100644 index 0000000000..4a6f01a186 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__eicqyirjstlxuotvptvgszvdeemgpomnL2CompressorReadTxs.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTIONS_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__eiovqvzojbuhtglrinqvkqirnywzkmmmL2CompressorReadTx.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__eiovqvzojbuhtglrinqvkqirnywzkmmmL2CompressorReadTx.huff new file mode 100644 index 0000000000..8c9f99fc5b --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__eiovqvzojbuhtglrinqvkqirnywzkmmmL2CompressorReadTx.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTION_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__elmwrfrphdzesjosulrygitvkhredhzhL2CompressorReadFlag.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__elmwrfrphdzesjosulrygitvkhredhzhL2CompressorReadFlag.huff new file mode 100644 index 0000000000..6bc3f6157c --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__elmwrfrphdzesjosulrygitvkhredhzhL2CompressorReadFlag.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_FLAG() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__eqatcxksiizfyaalvdegpzaqhuqqhiasL2CompressorReadTx.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__eqatcxksiizfyaalvdegpzaqhuqqhiasL2CompressorReadTx.huff new file mode 100644 index 0000000000..8c9f99fc5b --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__eqatcxksiizfyaalvdegpzaqhuqqhiasL2CompressorReadTx.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTION_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__etsleznlprfdbomdvycqormkvpykanxnL2CompressorReadTxs.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__etsleznlprfdbomdvycqormkvpykanxnL2CompressorReadTxs.huff new file mode 100644 index 0000000000..4a6f01a186 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__etsleznlprfdbomdvycqormkvpykanxnL2CompressorReadTxs.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTIONS_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__ezolvnoridtqgdaoucihkxihmonvdzfxL2CompressorReadNonce.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__ezolvnoridtqgdaoucihkxihmonvdzfxL2CompressorReadNonce.huff new file mode 100644 index 0000000000..eb09bd2b6d --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__ezolvnoridtqgdaoucihkxihmonvdzfxL2CompressorReadNonce.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_NONCE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__fjxkkzopmkrdujlfcvecckcbuhhhpvpfL2CompressorReadFlag.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__fjxkkzopmkrdujlfcvecckcbuhhhpvpfL2CompressorReadFlag.huff new file mode 100644 index 0000000000..6bc3f6157c --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__fjxkkzopmkrdujlfcvecckcbuhhhpvpfL2CompressorReadFlag.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_FLAG() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__fnqywxkjihwbqdurhcftzbzzrxvcmizbL2CompressorReadExecute.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__fnqywxkjihwbqdurhcftzbzzrxvcmizbL2CompressorReadExecute.huff new file mode 100644 index 0000000000..7351d4df36 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__fnqywxkjihwbqdurhcftzbzzrxvcmizbL2CompressorReadExecute.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_EXECUTE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__fophszhswirxqqcvcwxtmeqbuwldxifmL2CompressorReadNonce.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__fophszhswirxqqcvcwxtmeqbuwldxifmL2CompressorReadNonce.huff new file mode 100644 index 0000000000..eb09bd2b6d --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__fophszhswirxqqcvcwxtmeqbuwldxifmL2CompressorReadNonce.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_NONCE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__fvrcmlbliwfwkjwbyxrediuokmghmftbL2CompressorReadTx.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__fvrcmlbliwfwkjwbyxrediuokmghmftbL2CompressorReadTx.huff new file mode 100644 index 0000000000..8c9f99fc5b --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__fvrcmlbliwfwkjwbyxrediuokmghmftbL2CompressorReadTx.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTION_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__fzlawzzpwhflvpxtrdpemqiejqiknsfiL2CompressorReadNonce.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__fzlawzzpwhflvpxtrdpemqiejqiknsfiL2CompressorReadNonce.huff new file mode 100644 index 0000000000..eb09bd2b6d --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__fzlawzzpwhflvpxtrdpemqiejqiknsfiL2CompressorReadNonce.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_NONCE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__gllqgrsektwpyxkfoughzygdwrhxuzibL2CompressorReadFlag.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__gllqgrsektwpyxkfoughzygdwrhxuzibL2CompressorReadFlag.huff new file mode 100644 index 0000000000..6bc3f6157c --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__gllqgrsektwpyxkfoughzygdwrhxuzibL2CompressorReadFlag.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_FLAG() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__gmuxapiaoacldjbqqarixmvtxkffgwchL2CompressorReadExecute.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__gmuxapiaoacldjbqqarixmvtxkffgwchL2CompressorReadExecute.huff new file mode 100644 index 0000000000..7351d4df36 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__gmuxapiaoacldjbqqarixmvtxkffgwchL2CompressorReadExecute.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_EXECUTE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__gnbrxkaxjdmimbyepztqmujkoilcaudgL2CompressorReadExecute.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__gnbrxkaxjdmimbyepztqmujkoilcaudgL2CompressorReadExecute.huff new file mode 100644 index 0000000000..7351d4df36 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__gnbrxkaxjdmimbyepztqmujkoilcaudgL2CompressorReadExecute.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_EXECUTE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__grtgxrlusabnzjycyuqniujobcpgjuysL2CompressorReadTxs.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__grtgxrlusabnzjycyuqniujobcpgjuysL2CompressorReadTxs.huff new file mode 100644 index 0000000000..4a6f01a186 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__grtgxrlusabnzjycyuqniujobcpgjuysL2CompressorReadTxs.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTIONS_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__guymonsuywmugusjixyvzwfzordmogvuL2CompressorReadNonce.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__guymonsuywmugusjixyvzwfzordmogvuL2CompressorReadNonce.huff new file mode 100644 index 0000000000..eb09bd2b6d --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__guymonsuywmugusjixyvzwfzordmogvuL2CompressorReadNonce.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_NONCE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__gvmiqpcdvchroaxhcnyygzhjrvozrogmL2CompressorReadExecute.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__gvmiqpcdvchroaxhcnyygzhjrvozrogmL2CompressorReadExecute.huff new file mode 100644 index 0000000000..7351d4df36 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__gvmiqpcdvchroaxhcnyygzhjrvozrogmL2CompressorReadExecute.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_EXECUTE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__hahsuwlfvumxsoepdhwqsahoduwcqrrpL2CompressorReadTxs.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__hahsuwlfvumxsoepdhwqsahoduwcqrrpL2CompressorReadTxs.huff new file mode 100644 index 0000000000..4a6f01a186 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__hahsuwlfvumxsoepdhwqsahoduwcqrrpL2CompressorReadTxs.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTIONS_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__hbzqhssjozyiqufyamizmyrwtgelqlacL2CompressorReadExecute.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__hbzqhssjozyiqufyamizmyrwtgelqlacL2CompressorReadExecute.huff new file mode 100644 index 0000000000..7351d4df36 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__hbzqhssjozyiqufyamizmyrwtgelqlacL2CompressorReadExecute.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_EXECUTE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__hfunbeczbrqifdmdhdecpajexqefympmL2CompressorReadFlag.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__hfunbeczbrqifdmdhdecpajexqefympmL2CompressorReadFlag.huff new file mode 100644 index 0000000000..6bc3f6157c --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__hfunbeczbrqifdmdhdecpajexqefympmL2CompressorReadFlag.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_FLAG() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__htawaymiowrkxyrnxkesysithbtrbvqqL2CompressorReadNonce.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__htawaymiowrkxyrnxkesysithbtrbvqqL2CompressorReadNonce.huff new file mode 100644 index 0000000000..eb09bd2b6d --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__htawaymiowrkxyrnxkesysithbtrbvqqL2CompressorReadNonce.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_NONCE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__hwddxmqkngntwieovwlvozjzwlctwrzrL2CompressorReadNonce.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__hwddxmqkngntwieovwlvozjzwlctwrzrL2CompressorReadNonce.huff new file mode 100644 index 0000000000..eb09bd2b6d --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__hwddxmqkngntwieovwlvozjzwlctwrzrL2CompressorReadNonce.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_NONCE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__iepjlcxcjkjplwmrexbaruoucdulzvqvL2CompressorReadFlag.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__iepjlcxcjkjplwmrexbaruoucdulzvqvL2CompressorReadFlag.huff new file mode 100644 index 0000000000..6bc3f6157c --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__iepjlcxcjkjplwmrexbaruoucdulzvqvL2CompressorReadFlag.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_FLAG() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__igcaczanzcfoaizsmahiisgmgdjzfjxqL2CompressorReadTxs.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__igcaczanzcfoaizsmahiisgmgdjzfjxqL2CompressorReadTxs.huff new file mode 100644 index 0000000000..4a6f01a186 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__igcaczanzcfoaizsmahiisgmgdjzfjxqL2CompressorReadTxs.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTIONS_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__irlchgckchrpalaqwygxkipfvshmgystL2CompressorReadTxs.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__irlchgckchrpalaqwygxkipfvshmgystL2CompressorReadTxs.huff new file mode 100644 index 0000000000..4a6f01a186 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__irlchgckchrpalaqwygxkipfvshmgystL2CompressorReadTxs.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTIONS_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__ixvgjbblpufenoaperstvmceseoukqtcL2CompressorReadFlag.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__ixvgjbblpufenoaperstvmceseoukqtcL2CompressorReadFlag.huff new file mode 100644 index 0000000000..6bc3f6157c --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__ixvgjbblpufenoaperstvmceseoukqtcL2CompressorReadFlag.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_FLAG() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__jehdemzdnzfibjlvuclsezveuuexubagL2CompressorReadTxs.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__jehdemzdnzfibjlvuclsezveuuexubagL2CompressorReadTxs.huff new file mode 100644 index 0000000000..4a6f01a186 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__jehdemzdnzfibjlvuclsezveuuexubagL2CompressorReadTxs.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTIONS_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__jgpbsiwsniszmajdqepfceqpqhdfzbiiL2CompressorReadExecute.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__jgpbsiwsniszmajdqepfceqpqhdfzbiiL2CompressorReadExecute.huff new file mode 100644 index 0000000000..7351d4df36 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__jgpbsiwsniszmajdqepfceqpqhdfzbiiL2CompressorReadExecute.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_EXECUTE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__jowmzjwgdpwndoapfucdlmsxiuwbhxrsL2CompressorReadFlag.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__jowmzjwgdpwndoapfucdlmsxiuwbhxrsL2CompressorReadFlag.huff new file mode 100644 index 0000000000..6bc3f6157c --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__jowmzjwgdpwndoapfucdlmsxiuwbhxrsL2CompressorReadFlag.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_FLAG() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__jujqtnlfowbvuxcpetgqmymkladcanwtL2CompressorReadTx.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__jujqtnlfowbvuxcpetgqmymkladcanwtL2CompressorReadTx.huff new file mode 100644 index 0000000000..8c9f99fc5b --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__jujqtnlfowbvuxcpetgqmymkladcanwtL2CompressorReadTx.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTION_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__jvyndfqmdiikuahllmivwlrgrfhmdzslL2CompressorReadFlag.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__jvyndfqmdiikuahllmivwlrgrfhmdzslL2CompressorReadFlag.huff new file mode 100644 index 0000000000..6bc3f6157c --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__jvyndfqmdiikuahllmivwlrgrfhmdzslL2CompressorReadFlag.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_FLAG() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__kqlasykhhfirrrmebqsqsnoleofcgyciL2CompressorReadTx.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__kqlasykhhfirrrmebqsqsnoleofcgyciL2CompressorReadTx.huff new file mode 100644 index 0000000000..8c9f99fc5b --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__kqlasykhhfirrrmebqsqsnoleofcgyciL2CompressorReadTx.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTION_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__krffnjyglejvywvaqrlwcoejtxsysubcL2CompressorReadFlag.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__krffnjyglejvywvaqrlwcoejtxsysubcL2CompressorReadFlag.huff new file mode 100644 index 0000000000..6bc3f6157c --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__krffnjyglejvywvaqrlwcoejtxsysubcL2CompressorReadFlag.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_FLAG() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__lcamxsrkjvabmusmojsaspukxeydggrhL2CompressorReadExecute.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__lcamxsrkjvabmusmojsaspukxeydggrhL2CompressorReadExecute.huff new file mode 100644 index 0000000000..7351d4df36 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__lcamxsrkjvabmusmojsaspukxeydggrhL2CompressorReadExecute.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_EXECUTE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__lhhzpskainxqfqaqlpehxidlrhdvkcoyL2CompressorReadFlag.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__lhhzpskainxqfqaqlpehxidlrhdvkcoyL2CompressorReadFlag.huff new file mode 100644 index 0000000000..6bc3f6157c --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__lhhzpskainxqfqaqlpehxidlrhdvkcoyL2CompressorReadFlag.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_FLAG() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__lqfhpuhoyykhenkubqyenjlfkzsbjkxcL2CompressorReadNonce.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__lqfhpuhoyykhenkubqyenjlfkzsbjkxcL2CompressorReadNonce.huff new file mode 100644 index 0000000000..eb09bd2b6d --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__lqfhpuhoyykhenkubqyenjlfkzsbjkxcL2CompressorReadNonce.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_NONCE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__lvxixehkgptearwmufefnibyzayqaaciL2CompressorReadTx.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__lvxixehkgptearwmufefnibyzayqaaciL2CompressorReadTx.huff new file mode 100644 index 0000000000..8c9f99fc5b --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__lvxixehkgptearwmufefnibyzayqaaciL2CompressorReadTx.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTION_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__lyxapewhygradusuogqwefdorgsntvcxL2CompressorReadTxs.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__lyxapewhygradusuogqwefdorgsntvcxL2CompressorReadTxs.huff new file mode 100644 index 0000000000..4a6f01a186 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__lyxapewhygradusuogqwefdorgsntvcxL2CompressorReadTxs.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTIONS_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__mfzlovayqwfmitftdbihfqfuruuvbxqbL2CompressorReadExecute.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__mfzlovayqwfmitftdbihfqfuruuvbxqbL2CompressorReadExecute.huff new file mode 100644 index 0000000000..7351d4df36 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__mfzlovayqwfmitftdbihfqfuruuvbxqbL2CompressorReadExecute.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_EXECUTE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__mimqucgooefgrgmedlqkqqhszmvuuxioL2CompressorReadTxs.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__mimqucgooefgrgmedlqkqqhszmvuuxioL2CompressorReadTxs.huff new file mode 100644 index 0000000000..4a6f01a186 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__mimqucgooefgrgmedlqkqqhszmvuuxioL2CompressorReadTxs.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTIONS_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__mlmvtiltzqbjdwbouzrwkvkhpzncpjzsL2CompressorReadTxs.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__mlmvtiltzqbjdwbouzrwkvkhpzncpjzsL2CompressorReadTxs.huff new file mode 100644 index 0000000000..4a6f01a186 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__mlmvtiltzqbjdwbouzrwkvkhpzncpjzsL2CompressorReadTxs.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTIONS_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__mscgrvpcuajxspktkuiktwofhzwbszraL2CompressorReadNonce.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__mscgrvpcuajxspktkuiktwofhzwbszraL2CompressorReadNonce.huff new file mode 100644 index 0000000000..eb09bd2b6d --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__mscgrvpcuajxspktkuiktwofhzwbszraL2CompressorReadNonce.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_NONCE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__mscqnapvfrrvforntvdsgkeofzbhbhdsL2CompressorReadFlag.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__mscqnapvfrrvforntvdsgkeofzbhbhdsL2CompressorReadFlag.huff new file mode 100644 index 0000000000..6bc3f6157c --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__mscqnapvfrrvforntvdsgkeofzbhbhdsL2CompressorReadFlag.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_FLAG() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__nikafqmlyyfgnksobnextlfkyykzrdomL2CompressorReadFlag.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__nikafqmlyyfgnksobnextlfkyykzrdomL2CompressorReadFlag.huff new file mode 100644 index 0000000000..6bc3f6157c --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__nikafqmlyyfgnksobnextlfkyykzrdomL2CompressorReadFlag.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_FLAG() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__nmkhnrsondojimozdduewzkbcwlvsakcL2CompressorReadFlag.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__nmkhnrsondojimozdduewzkbcwlvsakcL2CompressorReadFlag.huff new file mode 100644 index 0000000000..6bc3f6157c --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__nmkhnrsondojimozdduewzkbcwlvsakcL2CompressorReadFlag.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_FLAG() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__nwvyiqgthdyhbeqefkhccrhufdhjjazeL2CompressorReadNonce.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__nwvyiqgthdyhbeqefkhccrhufdhjjazeL2CompressorReadNonce.huff new file mode 100644 index 0000000000..eb09bd2b6d --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__nwvyiqgthdyhbeqefkhccrhufdhjjazeL2CompressorReadNonce.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_NONCE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__obfmnrpwkqhjnhtlarvljeqysguhoizaL2CompressorReadTx.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__obfmnrpwkqhjnhtlarvljeqysguhoizaL2CompressorReadTx.huff new file mode 100644 index 0000000000..8c9f99fc5b --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__obfmnrpwkqhjnhtlarvljeqysguhoizaL2CompressorReadTx.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTION_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__osezdxhuqmvwkwrmogebamkqmhdvljmlL2CompressorReadTx.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__osezdxhuqmvwkwrmogebamkqmhdvljmlL2CompressorReadTx.huff new file mode 100644 index 0000000000..8c9f99fc5b --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__osezdxhuqmvwkwrmogebamkqmhdvljmlL2CompressorReadTx.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTION_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__pabiechkuxsxbofnkwdnlbnftvkuearfL2CompressorReadExecute.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__pabiechkuxsxbofnkwdnlbnftvkuearfL2CompressorReadExecute.huff new file mode 100644 index 0000000000..7351d4df36 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__pabiechkuxsxbofnkwdnlbnftvkuearfL2CompressorReadExecute.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_EXECUTE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__paowmqtaesjuestckycmjquytqlfsdxoL2CompressorReadTx.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__paowmqtaesjuestckycmjquytqlfsdxoL2CompressorReadTx.huff new file mode 100644 index 0000000000..8c9f99fc5b --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__paowmqtaesjuestckycmjquytqlfsdxoL2CompressorReadTx.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTION_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__pbsqieaiicgyhrvarrpmypzdufaanmpuL2CompressorReadNonce.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__pbsqieaiicgyhrvarrpmypzdufaanmpuL2CompressorReadNonce.huff new file mode 100644 index 0000000000..eb09bd2b6d --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__pbsqieaiicgyhrvarrpmypzdufaanmpuL2CompressorReadNonce.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_NONCE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__pdhdqmtavohyssvasdtggpxqllpajsfgL2CompressorReadFlag.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__pdhdqmtavohyssvasdtggpxqllpajsfgL2CompressorReadFlag.huff new file mode 100644 index 0000000000..6bc3f6157c --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__pdhdqmtavohyssvasdtggpxqllpajsfgL2CompressorReadFlag.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_FLAG() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__petemgomrtnkvriaaltgrrlpmnzupwinL2CompressorReadExecute.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__petemgomrtnkvriaaltgrrlpmnzupwinL2CompressorReadExecute.huff new file mode 100644 index 0000000000..7351d4df36 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__petemgomrtnkvriaaltgrrlpmnzupwinL2CompressorReadExecute.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_EXECUTE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__prsagizbgnvlqmbynuotwqkanwdlaqwpL2CompressorReadTx.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__prsagizbgnvlqmbynuotwqkanwdlaqwpL2CompressorReadTx.huff new file mode 100644 index 0000000000..8c9f99fc5b --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__prsagizbgnvlqmbynuotwqkanwdlaqwpL2CompressorReadTx.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTION_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__pwmrquntendpgjgzyejxobzrgvpizgfdL2CompressorReadTxs.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__pwmrquntendpgjgzyejxobzrgvpizgfdL2CompressorReadTxs.huff new file mode 100644 index 0000000000..4a6f01a186 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__pwmrquntendpgjgzyejxobzrgvpizgfdL2CompressorReadTxs.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTIONS_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__qcnbdgafrzidybihlkysfiliofczzxkhL2CompressorReadTxs.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__qcnbdgafrzidybihlkysfiliofczzxkhL2CompressorReadTxs.huff new file mode 100644 index 0000000000..4a6f01a186 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__qcnbdgafrzidybihlkysfiliofczzxkhL2CompressorReadTxs.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTIONS_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__qmgpovlxptxlyeikmnrgvhavunciniubL2CompressorReadTx.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__qmgpovlxptxlyeikmnrgvhavunciniubL2CompressorReadTx.huff new file mode 100644 index 0000000000..8c9f99fc5b --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__qmgpovlxptxlyeikmnrgvhavunciniubL2CompressorReadTx.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTION_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__qotscdrriksxilvopyxfsbdteqegnyogL2CompressorReadTx.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__qotscdrriksxilvopyxfsbdteqegnyogL2CompressorReadTx.huff new file mode 100644 index 0000000000..8c9f99fc5b --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__qotscdrriksxilvopyxfsbdteqegnyogL2CompressorReadTx.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTION_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__qpcuafrrwylbrmzpjfotpjfuqxtnqrznL2CompressorReadTx.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__qpcuafrrwylbrmzpjfotpjfuqxtnqrznL2CompressorReadTx.huff new file mode 100644 index 0000000000..8c9f99fc5b --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__qpcuafrrwylbrmzpjfotpjfuqxtnqrznL2CompressorReadTx.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTION_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__qrusinhmosfcvmayqquwflixlquuhfxhL2CompressorReadTx.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__qrusinhmosfcvmayqquwflixlquuhfxhL2CompressorReadTx.huff new file mode 100644 index 0000000000..8c9f99fc5b --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__qrusinhmosfcvmayqquwflixlquuhfxhL2CompressorReadTx.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTION_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__raqvmbdtosqccjiitanbofqxpeepnlpnL2CompressorReadFlag.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__raqvmbdtosqccjiitanbofqxpeepnlpnL2CompressorReadFlag.huff new file mode 100644 index 0000000000..6bc3f6157c --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__raqvmbdtosqccjiitanbofqxpeepnlpnL2CompressorReadFlag.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_FLAG() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__ruqfgeoaamevndekencowviukvlcrylcL2CompressorReadTx.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__ruqfgeoaamevndekencowviukvlcrylcL2CompressorReadTx.huff new file mode 100644 index 0000000000..8c9f99fc5b --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__ruqfgeoaamevndekencowviukvlcrylcL2CompressorReadTx.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTION_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__sccswirfbmatrvwbvymwfzttbygcbfmqL2CompressorReadTxs.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__sccswirfbmatrvwbvymwfzttbygcbfmqL2CompressorReadTxs.huff new file mode 100644 index 0000000000..4a6f01a186 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__sccswirfbmatrvwbvymwfzttbygcbfmqL2CompressorReadTxs.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTIONS_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__sgfhxhvokcpqraldrihrcqjmlolnoulkL2CompressorReadExecute.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__sgfhxhvokcpqraldrihrcqjmlolnoulkL2CompressorReadExecute.huff new file mode 100644 index 0000000000..7351d4df36 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__sgfhxhvokcpqraldrihrcqjmlolnoulkL2CompressorReadExecute.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_EXECUTE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__smnsryuyuhbbunwequckjtrcwgaqmtqrL2CompressorReadExecute.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__smnsryuyuhbbunwequckjtrcwgaqmtqrL2CompressorReadExecute.huff new file mode 100644 index 0000000000..7351d4df36 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__smnsryuyuhbbunwequckjtrcwgaqmtqrL2CompressorReadExecute.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_EXECUTE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__stxwzpcueqdwmcsxvxwzkubprcmgpexkL2CompressorReadExecute.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__stxwzpcueqdwmcsxvxwzkubprcmgpexkL2CompressorReadExecute.huff new file mode 100644 index 0000000000..7351d4df36 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__stxwzpcueqdwmcsxvxwzkubprcmgpexkL2CompressorReadExecute.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_EXECUTE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__syiwghttzfntbuucvfvlctpjeldqbrshL2CompressorReadNonce.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__syiwghttzfntbuucvfvlctpjeldqbrshL2CompressorReadNonce.huff new file mode 100644 index 0000000000..eb09bd2b6d --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__syiwghttzfntbuucvfvlctpjeldqbrshL2CompressorReadNonce.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_NONCE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__tadxtxolhcweyyokjpleorchotchzsecL2CompressorReadNonce.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__tadxtxolhcweyyokjpleorchotchzsecL2CompressorReadNonce.huff new file mode 100644 index 0000000000..eb09bd2b6d --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__tadxtxolhcweyyokjpleorchotchzsecL2CompressorReadNonce.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_NONCE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__tlpzvbklzufubgnwcvynodibgfqnidibL2CompressorReadFlag.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__tlpzvbklzufubgnwcvynodibgfqnidibL2CompressorReadFlag.huff new file mode 100644 index 0000000000..6bc3f6157c --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__tlpzvbklzufubgnwcvynodibgfqnidibL2CompressorReadFlag.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_FLAG() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__uobsemubvemlejzpjvdzyjcjrsbhplpsL2CompressorReadNonce.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__uobsemubvemlejzpjvdzyjcjrsbhplpsL2CompressorReadNonce.huff new file mode 100644 index 0000000000..eb09bd2b6d --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__uobsemubvemlejzpjvdzyjcjrsbhplpsL2CompressorReadNonce.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_NONCE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__uudbvubkefushlwgxsfgldujuphcmuueL2CompressorReadFlag.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__uudbvubkefushlwgxsfgldujuphcmuueL2CompressorReadFlag.huff new file mode 100644 index 0000000000..6bc3f6157c --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__uudbvubkefushlwgxsfgldujuphcmuueL2CompressorReadFlag.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_FLAG() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__uyprsxxzmvxmqqzffpwypehvvksjzbvnL2CompressorReadTxs.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__uyprsxxzmvxmqqzffpwypehvvksjzbvnL2CompressorReadTxs.huff new file mode 100644 index 0000000000..4a6f01a186 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__uyprsxxzmvxmqqzffpwypehvvksjzbvnL2CompressorReadTxs.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTIONS_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__vmmtlehczdflhfwnklqlujjtzpxrejpmL2CompressorReadNonce.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__vmmtlehczdflhfwnklqlujjtzpxrejpmL2CompressorReadNonce.huff new file mode 100644 index 0000000000..eb09bd2b6d --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__vmmtlehczdflhfwnklqlujjtzpxrejpmL2CompressorReadNonce.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_NONCE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__voqybenghboelsmsisgwnqqymvpjvskcL2CompressorReadFlag.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__voqybenghboelsmsisgwnqqymvpjvskcL2CompressorReadFlag.huff new file mode 100644 index 0000000000..6bc3f6157c --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__voqybenghboelsmsisgwnqqymvpjvskcL2CompressorReadFlag.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_FLAG() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__vtdvfmunyolkgcpjpzhtgjgwawtaakhwL2CompressorReadExecute.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__vtdvfmunyolkgcpjpzhtgjgwawtaakhwL2CompressorReadExecute.huff new file mode 100644 index 0000000000..7351d4df36 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__vtdvfmunyolkgcpjpzhtgjgwawtaakhwL2CompressorReadExecute.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_EXECUTE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__vtynudukibsyoxexvoiaurnusvgnrhusL2CompressorReadNonce.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__vtynudukibsyoxexvoiaurnusvgnrhusL2CompressorReadNonce.huff new file mode 100644 index 0000000000..eb09bd2b6d --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__vtynudukibsyoxexvoiaurnusvgnrhusL2CompressorReadNonce.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_NONCE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__vvictwvevvjztwupwcjsnyherfswgsgcL2CompressorReadTx.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__vvictwvevvjztwupwcjsnyherfswgsgcL2CompressorReadTx.huff new file mode 100644 index 0000000000..8c9f99fc5b --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__vvictwvevvjztwupwcjsnyherfswgsgcL2CompressorReadTx.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTION_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__vzqupagxqpkbexuaqyoulenyhrwfuvsiL2CompressorReadTxs.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__vzqupagxqpkbexuaqyoulenyhrwfuvsiL2CompressorReadTxs.huff new file mode 100644 index 0000000000..4a6f01a186 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__vzqupagxqpkbexuaqyoulenyhrwfuvsiL2CompressorReadTxs.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTIONS_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__wcgjgrxjyjenenrnolprlkfulinnjttkL2CompressorReadExecute.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__wcgjgrxjyjenenrnolprlkfulinnjttkL2CompressorReadExecute.huff new file mode 100644 index 0000000000..7351d4df36 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__wcgjgrxjyjenenrnolprlkfulinnjttkL2CompressorReadExecute.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_EXECUTE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__weeyfqxkqtokrkcwbrxerdftkvyxqwwiL2CompressorReadExecute.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__weeyfqxkqtokrkcwbrxerdftkvyxqwwiL2CompressorReadExecute.huff new file mode 100644 index 0000000000..7351d4df36 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__weeyfqxkqtokrkcwbrxerdftkvyxqwwiL2CompressorReadExecute.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_EXECUTE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__xbuxrypubsjveaucjyhkmwlwmhlgvymnL2CompressorReadExecute.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__xbuxrypubsjveaucjyhkmwlwmhlgvymnL2CompressorReadExecute.huff new file mode 100644 index 0000000000..7351d4df36 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__xbuxrypubsjveaucjyhkmwlwmhlgvymnL2CompressorReadExecute.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_EXECUTE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__xeqwdqdlujruiiyywivxsxrlsluymfdiL2CompressorReadExecute.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__xeqwdqdlujruiiyywivxsxrlsluymfdiL2CompressorReadExecute.huff new file mode 100644 index 0000000000..7351d4df36 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__xeqwdqdlujruiiyywivxsxrlsluymfdiL2CompressorReadExecute.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_EXECUTE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__xprohfjolmgvmuxskobwcqavoskmutltL2CompressorReadExecute.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__xprohfjolmgvmuxskobwcqavoskmutltL2CompressorReadExecute.huff new file mode 100644 index 0000000000..7351d4df36 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__xprohfjolmgvmuxskobwcqavoskmutltL2CompressorReadExecute.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_EXECUTE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__yhfcljsbzcghwkonkegmtbremlhrxnejL2CompressorReadExecute.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__yhfcljsbzcghwkonkegmtbremlhrxnejL2CompressorReadExecute.huff new file mode 100644 index 0000000000..7351d4df36 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__yhfcljsbzcghwkonkegmtbremlhrxnejL2CompressorReadExecute.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_EXECUTE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__yphredkigvzhxnjzbspndmkchcjaofllL2CompressorReadNonce.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__yphredkigvzhxnjzbspndmkchcjaofllL2CompressorReadNonce.huff new file mode 100644 index 0000000000..eb09bd2b6d --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__yphredkigvzhxnjzbspndmkchcjaofllL2CompressorReadNonce.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_NONCE_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__zfeyxnkrahdyldfbtyakjkbvehkjdbmgL2CompressorReadTx.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__zfeyxnkrahdyldfbtyakjkbvehkjdbmgL2CompressorReadTx.huff new file mode 100644 index 0000000000..8c9f99fc5b --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__zfeyxnkrahdyldfbtyakjkbvehkjdbmgL2CompressorReadTx.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTION_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__zmblbdmtdrpbbopekynjthxzellyhsxeL2CompressorReadTxs.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__zmblbdmtdrpbbopekynjthxzellyhsxeL2CompressorReadTxs.huff new file mode 100644 index 0000000000..4a6f01a186 --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__zmblbdmtdrpbbopekynjthxzellyhsxeL2CompressorReadTxs.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTIONS_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/src/imps/__TEMP__zvcrygcudiscauggwhjnxbrgifehtxhfL2CompressorReadTx.huff b/packages/wallet/wallet-contracts/src/imps/__TEMP__zvcrygcudiscauggwhjnxbrgifehtxhfL2CompressorReadTx.huff new file mode 100644 index 0000000000..8c9f99fc5b --- /dev/null +++ b/packages/wallet/wallet-contracts/src/imps/__TEMP__zvcrygcudiscauggwhjnxbrgifehtxhfL2CompressorReadTx.huff @@ -0,0 +1,32 @@ + + +#include "../L2CompressorLib.huff" + +#define constant FMS = 0xa0 + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // readAdvanced with whatever calldata is passed + // first 32 bytes returns the new rindex and the next 32 bytes returns the new windex + + 0x00 // [rindex] + [FMS] // [windex, rindex] + + READ_TRANSACTION_STANDALONE() // [windex, rindex] + + [FMS] // [0xa0, windex, rindex] + dup2 // [windex, 0xa0, windex, rindex] + sub // [len, windex, rindex] + + swap2 // [rindex, windex, len] + + 0x80 [FMS] sub mstore // [windex, len] + 0x60 [FMS] sub mstore // [len] + + 0x60 0x40 [FMS] sub mstore // [len] + dup1 0x20 [FMS] sub mstore // [len] + + 0x80 add // [len + 0x80] + + 0x80 [FMS] sub return +} diff --git a/packages/wallet/wallet-contracts/test/ChainedSignatures.spec.ts b/packages/wallet/wallet-contracts/test/ChainedSignatures.spec.ts new file mode 100644 index 0000000000..5aab0892f6 --- /dev/null +++ b/packages/wallet/wallet-contracts/test/ChainedSignatures.spec.ts @@ -0,0 +1,136 @@ +import { expect } from 'chai' +import { ethers } from 'ethers' +import { expectToBeRejected } from './utils' +import { deploySequenceContext, SequenceContext } from './utils/contracts' +import { SequenceWallet } from './utils/wallet' + +contract('Chained signatures', (accounts: string[]) => { + let context: SequenceContext + + let wallet: SequenceWallet + let typeHash: string + + before(async () => { + context = await deploySequenceContext() + }) + + beforeEach(async () => { + wallet = SequenceWallet.basicWallet(context) + await wallet.deploy() + typeHash = await wallet.mainModule.SET_IMAGE_HASH_TYPE_HASH() + }) + + const chain = (top: string, ...rest: { sig: string }[]) => { + const encodedRest = ethers.solidityPacked( + rest.map(() => ['uint24', 'bytes']).flat(), + rest.map(r => [ethers.getBytes(r.sig).length, r.sig]).flat() + ) + + return ethers.solidityPacked(['uint8', 'uint24', 'bytes', 'bytes'], [3, ethers.getBytes(top).length, top, encodedRest]) + } + + const hashSetImageHash = (imageHash: string) => { + return ethers.keccak256(ethers.AbiCoder.defaultAbiCoder().encode(['bytes32', 'bytes32'], [typeHash, imageHash])) + } + + it('Should accept a single chained signature', async () => { + const wallet_b = SequenceWallet.basicWallet(context, { address: wallet.address }) + + const hsih = hashSetImageHash(wallet_b.imageHash) + + const sig = await wallet.signDigest(hsih) + const topsig = await wallet_b.signTransactions([{}]) + const bundled = chain(topsig, { sig: sig }) + + await wallet_b.relayTransactions([{}], bundled) + }) + + it('Should accept two chained signatures', async () => { + let wallet_b = SequenceWallet.basicWallet(context, { address: wallet.address, signing: 2, idle: 1 }) + let wallet_c = SequenceWallet.basicWallet(context, { address: wallet_b.address, signing: 3, idle: 7 }) + + const checkpoint1 = BigInt(wallet.config.checkpoint) + 1n + const checkpoint2 = checkpoint1 + 1n + + wallet_b = wallet_b.useConfig({ ...wallet_b.config, checkpoint: checkpoint1 }) + wallet_c = wallet_c.useConfig({ ...wallet_c.config, checkpoint: checkpoint2 }) + + const hsih1 = hashSetImageHash(wallet_b.imageHash) + const hsih2 = hashSetImageHash(wallet_c.imageHash) + + const sig1 = await wallet.signDigest(hsih1) + const sig2 = await wallet_b.signDigest(hsih2) + + const topsig = await wallet_c.signTransactions([{}]) + const bundled = chain(topsig, { sig: sig2 }, { sig: sig1 }) + + await wallet_c.relayTransactions([{}], bundled) + }) + + it('Should reject chained signatures if checkpoint is wrongly ordered', async () => { + let wallet_b = SequenceWallet.basicWallet(context, { address: wallet.address, signing: 2, idle: 1 }) + let wallet_c = SequenceWallet.basicWallet(context, { address: wallet_b.address, signing: 3, idle: 7 }) + + const checkpoint1 = BigInt(wallet.config.checkpoint) + 1n + const checkpoint2 = checkpoint1 - 1n + + wallet_b = wallet_b.useConfig({ ...wallet_b.config, checkpoint: checkpoint1 }) + wallet_c = wallet_c.useConfig({ ...wallet_c.config, checkpoint: checkpoint2 }) + + const hsih1 = hashSetImageHash(wallet_b.imageHash) + const hsih2 = hashSetImageHash(wallet_c.imageHash) + + const sig1 = await wallet.signDigest(hsih1) + const sig2 = await wallet_b.signDigest(hsih2) + + const topsig = await wallet_c.signTransactions([{}]) + const bundled = chain(topsig, { sig: sig2 }, { sig: sig1 }) + + const tx = wallet_c.relayTransactions([{}], bundled) + await expectToBeRejected(tx, `WrongChainedCheckpointOrder(${checkpoint1}, ${checkpoint2})`) + }) + + it('Should accept top level signature encoded as chained', async () => { + const sig = await wallet.signTransactions([{}]) + await wallet.relayTransactions([{}], chain(sig)) + }) + + it('Should accept top level signature encoded as chained twice', async () => { + const sig = await wallet.signTransactions([{}]) + await wallet.relayTransactions([{}], chain(chain(sig))) + }) + + it('Should reject signature if current checkpoint is equal to signed checkpoint', async () => { + let wallet_b = SequenceWallet.basicWallet(context, { address: wallet.address }) + + const checkpoint = BigInt(wallet.config.checkpoint) + wallet_b = wallet_b.useConfig({ ...wallet_b.config, checkpoint: checkpoint }) + + const hsih = hashSetImageHash(wallet_b.imageHash) + const sig = await wallet.signDigest(hsih) + const topsig = await wallet_b.signTransactions([{}]) + const bundled = chain(topsig, { sig: sig }) + + await expectToBeRejected( + wallet_b.relayTransactions([{}], bundled), + `WrongChainedCheckpointOrder(${checkpoint}, ${checkpoint})` + ) + }) + + it('Should reject signature if current checkpoint is above to signed checkpoint', async () => { + let wallet_b = SequenceWallet.basicWallet(context, { address: wallet.address }) + + const checkpoint = BigInt(wallet.config.checkpoint) - 1n + wallet_b = wallet_b.useConfig({ ...wallet_b.config, checkpoint: checkpoint }) + + const hsih = hashSetImageHash(wallet_b.imageHash) + const sig = await wallet.signDigest(hsih) + const topsig = await wallet_b.signTransactions([{}]) + const bundled = chain(topsig, { sig: sig }) + + await expectToBeRejected( + wallet_b.relayTransactions([{}], bundled), + `WrongChainedCheckpointOrder(${wallet.config.checkpoint}, ${checkpoint})` + ) + }) +}) diff --git a/packages/wallet/wallet-contracts/test/ERC165.spec.ts b/packages/wallet/wallet-contracts/test/ERC165.spec.ts new file mode 100644 index 0000000000..f55cf6da2a --- /dev/null +++ b/packages/wallet/wallet-contracts/test/ERC165.spec.ts @@ -0,0 +1,73 @@ +import { ethers } from 'ethers' +import { ContractType, deploySequenceContext, ERC165CheckerMock, SequenceContext } from './utils/contracts' +import { SequenceWallet } from './utils/wallet' +import { expect, interfaceIdOf, randomHex } from './utils' + +const interfaceIds = [ + 'IERC223Receiver', + 'IERC721Receiver', + 'IERC1155Receiver', + 'IERC1271Wallet', + 'IModuleAuth', + 'IModuleCalls', + 'IModuleCreator', + 'IModuleHooks', + 'IModuleUpdate' +] + +contract('ERC165', () => { + let context: SequenceContext + let erc165checker: ContractType + let wallet: SequenceWallet + + before(async () => { + context = await deploySequenceContext() + erc165checker = await ERC165CheckerMock.deploy() + }) + + beforeEach(async () => { + wallet = SequenceWallet.basicWallet(context) + await wallet.deploy() + }) + + describe('Implement all interfaces for ERC165 on MainModule', () => { + interfaceIds.forEach(element => { + it(`Should return implements ${element} interfaceId`, async () => { + const interfaceId = interfaceIdOf(new ethers.Interface(artifacts.require(element).abi)) + expect(BigInt(interfaceId) === 0n).to.be.false + + const erc165result = await erc165checker.doesContractImplementInterface(wallet.address, interfaceId) + expect(erc165result).to.be.true + }) + }) + }) + describe('Implement all interfaces for ERC165 on MainModuleUpgradable', () => { + beforeEach(async () => { + await wallet.updateImageHash(randomHex(32)) + }) + + interfaceIds.concat('IModuleAuthUpgradable').forEach(element => { + it(`Should return implements ${element} interfaceId`, async () => { + const interfaceId = interfaceIdOf(new ethers.Interface(artifacts.require(element).abi)) + expect(BigInt(interfaceId) === 0n).to.be.false + + const erc165result = await erc165checker.doesContractImplementInterface(wallet.address, interfaceId) + expect(erc165result).to.be.true + }) + }) + }) + describe('Manually defined interfaces', () => { + const interfaces = [ + ['ERC165', '0x01ffc9a7'], + ['ERC721', '0x150b7a02'], + ['ERC1155', '0x4e2312e0'] + ] + + interfaces.forEach(i => { + it(`Should implement ${i[0]} interface`, async () => { + const erc165result = await erc165checker.doesContractImplementInterface(wallet.address, i[1]) + expect(erc165result).to.be.true + }) + }) + }) +}) diff --git a/packages/wallet/wallet-contracts/test/Factory.spec.ts b/packages/wallet/wallet-contracts/test/Factory.spec.ts new file mode 100644 index 0000000000..c498857466 --- /dev/null +++ b/packages/wallet/wallet-contracts/test/Factory.spec.ts @@ -0,0 +1,65 @@ +import { ethers } from 'ethers' + +import { ethers as hethers } from 'hardhat' +import { addressOf } from './utils/sequence' +import { expect, expectToBeRejected } from './utils' +import { ContractType, Factory, ModuleMock } from './utils/contracts' + +contract('Factory', () => { + let module: ContractType + let factory: ContractType + + beforeEach(async () => { + module = await ModuleMock.deploy() + factory = await Factory.deploy() + + await module.waitForDeployment() + await factory.waitForDeployment() + }) + + describe('Deploy wallets', () => { + it('Should deploy wallet', async () => { + await factory.deploy( + await module.getAddress(), + ethers.AbiCoder.defaultAbiCoder().encode(['address'], [ethers.Wallet.createRandom().address]) + ) + await factory.waitForDeployment() + }) + + it('Should predict wallet address', async () => { + const hash = ethers.hexlify(ethers.randomBytes(32)) + const predict = addressOf(await factory.getAddress(), await module.getAddress(), hash) + await factory.deploy(await module.getAddress(), hash) + await factory.waitForDeployment() + expect(await hethers.provider.getCode(predict)).to.not.equal('0x') + }) + + it('Should initialize with main module', async () => { + const hash = ethers.hexlify(ethers.randomBytes(32)) + await factory.deploy(await module.getAddress(), hash) + const address = addressOf(await factory.getAddress(), await module.getAddress(), hash) + const wallet = await ModuleMock.attach(address) + const receipt = await (await wallet.ping()).wait() + + if (!receipt) { + throw new Error('No receipt') + } + + expect(wallet.interface.parseLog(receipt.logs[0])?.name).to.equal('Pong') + }) + + it('Should fail to deploy twice', async () => { + const hash = ethers.hexlify(ethers.randomBytes(32)) + await factory.deploy(await module.getAddress(), hash) + + const tx2 = factory.deploy(await module.getAddress(), hash) + await expectToBeRejected(tx2, `DeployFailed("${await module.getAddress()}", "${hash}")`) + }) + + it('Should fail to deploy with not enough gas', async () => { + const hash = ethers.hexlify(ethers.randomBytes(32)) + const tx = factory.deploy(await module.getAddress(), hash, { gasLimit: 80000 }) + await expectToBeRejected(tx, `DeployFailed("${await module.getAddress()}", "${hash}")`) + }) + }) +}) diff --git a/packages/wallet/wallet-contracts/test/GasEstimation.spec.ts b/packages/wallet/wallet-contracts/test/GasEstimation.spec.ts new file mode 100644 index 0000000000..850d6499e9 --- /dev/null +++ b/packages/wallet/wallet-contracts/test/GasEstimation.spec.ts @@ -0,0 +1,353 @@ +import { ethers } from 'ethers' +import { expect } from './utils' + +import { + CallReceiverMock, + ContractType, + deploySequenceContext, + GasEstimator, + GuestModule, + ModuleMock, + SequenceContext, + MainModuleGasEstimation, + MainModule +} from './utils/contracts' +import { applyTxDefaults, toSimplifiedConfig, Transaction } from './utils/sequence' +import { SequenceWallet } from './utils/wallet' + +function txBaseCost(data: ethers.BytesLike): number { + const bytes = ethers.getBytes(data) + return Number(bytes.reduce((p, c) => (c == 0 ? p + 4n : p + 16n), 0n) + 21000n) +} + +contract('Estimate gas usage', () => { + let context: SequenceContext + + let gasEstimator: ContractType + let callReceiver: ContractType + let guestModule: ContractType + let moduleMock: ContractType + + let wallet: SequenceWallet + + const bundleWithDeploy = async (txData: string) => { + return applyTxDefaults([ + { + target: await context.factory.getAddress(), + data: context.factory.interface.encodeFunctionData('deploy', [await context.mainModule.getAddress(), wallet.imageHash]) + }, + { + target: wallet.address, + data: txData + } + ]) + } + + const estimate = (address: string, data: ethers.BytesLike) => ({ + call: async () => { + return gasEstimator.estimate.staticCall(address, data) + } + }) + + const estimateGasUsage = async ( + txs: Partial[], + wallet: SequenceWallet, + deploy: boolean = false, + nonce: ethers.BigNumberish = 0 + ) => { + const stubSignature = await SequenceWallet.detailedWallet(context, { + threshold: wallet.config.threshold, + signers: toSimplifiedConfig(wallet.config).signers.map(() => ethers.Wallet.createRandom()) + }).signMessage(ethers.randomBytes(32)) + + const txData = wallet.mainModule.interface.encodeFunctionData('execute', [applyTxDefaults(txs), nonce, stubSignature]) + if (!deploy) { + const res = await estimate(wallet.address, txData).call() + return Number(res.gas + BigInt(txBaseCost(txData))) + } + + const guestModuleData = guestModule.interface.encodeFunctionData('execute', [ + await bundleWithDeploy(txData), + 0, + new Uint8Array([]) + ]) + const res = await estimate(await guestModule.getAddress(), guestModuleData).call() + return Number(res.gas + BigInt(txBaseCost(txData))) + } + + const gasUsedFor = async (tx: ethers.ContractTransactionResponse) => { + const receipt = await tx.wait() + + if (!receipt) { + throw new Error('No receipt') + } + + return Number(BigInt(receipt.gasUsed)) + } + + before(async () => { + context = await deploySequenceContext() + + // Deploy MainModuleGasEstimation (hardhat doesn't support overwrites, so we use this as the real module) + context.mainModule = (await MainModuleGasEstimation.deploy()) as any as ContractType + + gasEstimator = await GasEstimator.deploy() + guestModule = await GuestModule.deploy() + moduleMock = await ModuleMock.deploy() + }) + + beforeEach(async () => { + wallet = SequenceWallet.basicWallet(context) + callReceiver = await CallReceiverMock.deploy() + }) + + describe('Estimate gas of transactions', () => { + describe('without wallet deployed', () => { + it('Should estimate wallet deployment', async () => { + wallet = SequenceWallet.basicWallet(context) + const factoryData = context.factory.interface.encodeFunctionData('deploy', [ + await context.mainModule.getAddress(), + wallet.imageHash + ]) + + const estimated = Number(BigInt((await estimate(await context.factory.getAddress(), factoryData).call()).gas)) + const realTx = await context.factory.deploy(await context.mainModule.getAddress(), wallet.imageHash) + expect(estimated + txBaseCost(factoryData)).to.approximately(await gasUsedFor(realTx), 5000) + }) + + it('Should estimate wallet deployment + upgrade', async () => { + const transactions = [ + { + target: wallet.address, + data: wallet.mainModule.interface.encodeFunctionData('updateImplementation', [await moduleMock.getAddress()]) + } + ] + + const estimated = await estimateGasUsage(transactions, wallet, true) + + const signature = await wallet.signTransactions(transactions, 0) + const executeTxData = await bundleWithDeploy( + wallet.mainModule.interface.encodeFunctionData('execute', [applyTxDefaults(transactions), 0, signature]) + ) + const realTx = await guestModule.execute(executeTxData, 0, new Uint8Array([])) + + expect(estimated).to.approximately(await gasUsedFor(realTx), 5000) + }) + + it('Should estimate wallet deployment + upgrade + transaction', async () => { + const transactions = [ + { + target: wallet.address, + data: wallet.mainModule.interface.encodeFunctionData('updateImplementation', [await moduleMock.getAddress()]) + }, + { + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [1, ethers.hexlify(ethers.randomBytes(299))]) + } + ] + + const estimated = await estimateGasUsage(transactions, wallet, true) + + const signature = await wallet.signTransactions(transactions, 0) + const executeTxData = await bundleWithDeploy( + wallet.mainModule.interface.encodeFunctionData('execute', [applyTxDefaults(transactions), 0, signature]) + ) + const realTx = await guestModule.execute(executeTxData, 0, new Uint8Array([])) + + expect(estimated).to.approximately(await gasUsedFor(realTx), 5000) + + expect(await callReceiver.lastValA()).to.equal(1n) + }) + + it('Should estimate wallet deployment + upgrade + failed transaction', async () => { + await callReceiver.setRevertFlag(true) + + const transactions = [ + { + target: wallet.address, + data: wallet.mainModule.interface.encodeFunctionData('updateImplementation', [await moduleMock.getAddress()]) + }, + { + revertOnError: false, + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [1, ethers.hexlify(ethers.randomBytes(299))]) + } + ] + + const estimated = await estimateGasUsage(transactions, wallet, true) + + const signature = await wallet.signTransactions(transactions, 0) + const executeTxData = await bundleWithDeploy( + wallet.mainModule.interface.encodeFunctionData('execute', [applyTxDefaults(transactions), 0, signature]) + ) + const realTx = await guestModule.execute(executeTxData, 0, new Uint8Array([])) + + expect(estimated).to.approximately(await gasUsedFor(realTx), 5000) + }) + + it('Should estimate wallet deployment + upgrade + fixed gas transaction', async () => { + const transactions = [ + { + target: wallet.address, + data: wallet.mainModule.interface.encodeFunctionData('updateImplementation', [await moduleMock.getAddress()]) + }, + { + revertOnError: false, + gasLimit: 900000, + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [1, ethers.hexlify(ethers.randomBytes(299))]) + } + ] + + const estimated = await estimateGasUsage(transactions, wallet, true) + + const signature = await wallet.signTransactions(transactions, 0) + const executeTxData = await bundleWithDeploy( + wallet.mainModule.interface.encodeFunctionData('execute', [applyTxDefaults(transactions), 0, signature]) + ) + const realTx = await guestModule.execute(executeTxData, 0, new Uint8Array([])) + + expect(estimated).to.approximately(await gasUsedFor(realTx), 5000) + }) + }) + ;[ + { + name: 'single signer', + signers: 1 + }, + { + name: 'many signers', + signers: 32 + } + ].map(o => { + describe(`with wallet deployed and ${o.name}`, () => { + beforeEach(async () => { + wallet = SequenceWallet.basicWallet(context, { signing: o.signers }) + await wallet.deploy() + }) + + it('Should estimate single transaction', async () => { + const transactions = [ + { + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [1, ethers.hexlify(ethers.randomBytes(299))]) + } + ] + + const estimated = await estimateGasUsage(transactions, wallet) + const gasUsed = await wallet + .sendTransactions(transactions) + .then(t => t.wait()) + .then(r => Number(r?.gasUsed)) + + expect(estimated).to.approximately(gasUsed, 5000) + }) + + it('Should estimate multiple transactions', async () => { + const transactions = [ + { + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [1, ethers.hexlify(ethers.randomBytes(299))]) + }, + { + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [1, ethers.hexlify(ethers.randomBytes(2299))]) + } + ] + + const estimated = await estimateGasUsage(transactions, wallet) + const gasUsed = await wallet + .sendTransactions(transactions) + .then(t => t.wait()) + .then(r => Number(r?.gasUsed)) + + // TODO: The estimator overEstimates the gas usage due to the gas refund + expect(gasUsed).to.be.below(estimated) + }) + + it('Should estimate multiple transactions with bad nonce', async () => { + const transactions = [ + { + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [1, ethers.hexlify(ethers.randomBytes(299))]) + }, + { + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [1, ethers.hexlify(ethers.randomBytes(2299))]) + } + ] + + const estimated = await estimateGasUsage(transactions, wallet, false, 999999999) + const gasUsed = await wallet + .sendTransactions(transactions) + .then(t => t.wait()) + .then(r => Number(r?.gasUsed)) + + // TODO: The estimator overEstimates the gas usage due to the gas refund + expect(gasUsed).to.be.below(estimated) + }) + + it('Should estimate multiple transactions with failing transactions', async () => { + const altCallReceiver = await CallReceiverMock.deploy() + await altCallReceiver.setRevertFlag(true) + + const transactions = [ + { + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [1, ethers.hexlify(ethers.randomBytes(299))]) + }, + { + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [1, ethers.hexlify(ethers.randomBytes(2299))]) + }, + { + revertOnError: false, + target: await altCallReceiver.getAddress(), + data: altCallReceiver.interface.encodeFunctionData('testCall', [1, ethers.hexlify(ethers.randomBytes(229))]) + } + ] + + const estimated = await estimateGasUsage(transactions, wallet) + const gasUsed = await wallet + .sendTransactions(transactions) + .then(t => t.wait()) + .then(r => Number(r?.gasUsed)) + + // TODO: The estimator overEstimates the gas usage due to the gas refund + expect(gasUsed).to.be.below(estimated) + }) + + it('Should estimate multiple transactions with failing transactions and fixed gas limits', async () => { + const altCallReceiver = await CallReceiverMock.deploy() + await altCallReceiver.setRevertFlag(true) + + const transactions = [ + { + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [1, ethers.hexlify(ethers.randomBytes(299))]) + }, + { + gasLimit: 90000, + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [1, ethers.hexlify(ethers.randomBytes(12))]) + }, + { + revertOnError: false, + target: await altCallReceiver.getAddress(), + data: altCallReceiver.interface.encodeFunctionData('testCall', [1, ethers.hexlify(ethers.randomBytes(229))]) + } + ] + + const estimated = await estimateGasUsage(transactions, wallet) + const gasUsed = await wallet + .sendTransactions(transactions) + .then(t => t.wait()) + .then(r => Number(r?.gasUsed)) + + // TODO: The estimator overEstimates the gas usage due to the gas refund + expect(gasUsed).to.be.below(estimated) + }) + }) + }) + }) +}) diff --git a/packages/wallet/wallet-contracts/test/GuestModule.spec.ts b/packages/wallet/wallet-contracts/test/GuestModule.spec.ts new file mode 100644 index 0000000000..7d466e3816 --- /dev/null +++ b/packages/wallet/wallet-contracts/test/GuestModule.spec.ts @@ -0,0 +1,98 @@ +import { expect, expectToBeRejected } from './utils' +import { ethers as hethers } from 'hardhat' +import { ethers } from 'ethers' +import { CallReceiverMock, ContractType, GuestModule, HookCallerMock, MainModule } from './utils/contracts' +import { applyTxDefaults, Transaction } from './utils/sequence' + +contract('GuestModule', () => { + let guestModule: ContractType + let callReceiver: ContractType + let hookCallerMock: ContractType + + describe('GuestModule wallet', () => { + before(async () => { + guestModule = await GuestModule.deploy() + callReceiver = await CallReceiverMock.deploy() + hookCallerMock = await HookCallerMock.deploy() + }) + + let valA: bigint + let valB: string + + let transactions: Transaction[] + + beforeEach(async () => { + valA = ethers.toBigInt(ethers.randomBytes(3)) + valB = ethers.hexlify(ethers.randomBytes(120)) + + transactions = applyTxDefaults([ + { + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [valA, valB]) + } + ]) + }) + + it('Should accept transactions without signature', async () => { + await guestModule.execute(transactions, 0, new Uint8Array([])) + + expect(await callReceiver.lastValA()).to.equal(valA) + expect(await callReceiver.lastValB()).to.equal(valB) + }) + it('Should accept transactions on selfExecute', async () => { + await guestModule.selfExecute(transactions) + + expect(await callReceiver.lastValA()).to.equal(valA) + expect(await callReceiver.lastValB()).to.equal(valB) + }) + it('Should accept transactions with random signature', async () => { + const signature = ethers.randomBytes(96) + + await guestModule.execute(transactions, 0, signature) + + expect(await callReceiver.lastValA()).to.equal(valA) + expect(await callReceiver.lastValB()).to.equal(valB) + }) + it('Should accept transactions with random nonce', async () => { + const nonce = 9123891 + + await guestModule.execute(transactions, nonce, new Uint8Array([])) + + expect(await callReceiver.lastValA()).to.equal(valA) + expect(await callReceiver.lastValB()).to.equal(valB) + }) + it('Should revert on delegateCall transactions', async () => { + const transactions = applyTxDefaults([ + { + delegateCall: true + } + ]) + + const tx = guestModule.selfExecute(transactions) + await expectToBeRejected(tx, 'DelegateCallNotAllowed(0)') + }) + it('Should not accept ETH', async () => { + const signer = await hethers.provider.getSigner() + const tx = signer.sendTransaction({ value: 1, to: await guestModule.getAddress() }) + await expect(tx).to.be.rejected + }) + it('Should not implement hooks', async () => { + const tx = hookCallerMock.callERC1155Received(await guestModule.getAddress()) + await expect(tx).to.be.rejected + }) + it('Should not be upgradeable', async () => { + const mainModule = await MainModule.attach(await guestModule.getAddress()) + const newImageHash = ethers.hexlify(ethers.randomBytes(32)) + + const migrateBundle = applyTxDefaults([ + { + target: await mainModule.getAddress(), + data: mainModule.interface.encodeFunctionData('updateImageHash', [newImageHash]) + } + ]) + + const tx = guestModule.selfExecute(migrateBundle) + await expect(tx).to.be.rejected + }) + }) +}) diff --git a/packages/wallet/wallet-contracts/test/LibBytes.spec.ts b/packages/wallet/wallet-contracts/test/LibBytes.spec.ts new file mode 100644 index 0000000000..0212ccb8ac --- /dev/null +++ b/packages/wallet/wallet-contracts/test/LibBytes.spec.ts @@ -0,0 +1,185 @@ +import { ethers } from 'ethers' + +import { expect, expectStaticToBeRejected, randomHex } from './utils' +import { ContractType, LibBytesImpl, LibBytesPointerImpl } from './utils/contracts' + +contract('LibBytes', () => { + let libBytes: ContractType + let libBytesPointer: ContractType + + before(async () => { + libBytes = await LibBytesImpl.deploy() + libBytesPointer = await LibBytesPointerImpl.deploy() + }) + + describe('readFirstUint16', () => { + it('Should read first uint16', async () => { + const res = await libBytesPointer.readFirstUint16('0x03021e4453120a') + expect(res[0]).to.equal(770n) + expect(res[1]).to.equal(2n) + }) + + it('Should read first uint16 of 2 byte array', async () => { + const res = await libBytesPointer.readFirstUint16('0xff0a') + expect(res[0]).to.equal(65290n) + expect(res[1]).to.equal(2n) + }) + + it('Should read first uint16 out of bounds', async () => { + const res = await libBytesPointer.readFirstUint16('0x') + expect(res[0]).to.equal(0n) + expect(res[1]).to.equal(2n) + }) + }) + + describe('readBytes32', () => { + let bytes32: string + beforeEach(async () => { + bytes32 = randomHex(32) + }) + it('Should read bytes32 at index zero', async () => { + const data = bytes32.concat(randomHex(16).slice(2)) + + const res = await libBytes.readBytes32(data, 0) + expect(res).to.equal(bytes32) + }) + it('Should read bytes32 at given index', async () => { + const data = randomHex(12).concat(bytes32.slice(2)).concat(randomHex(44).slice(2)) + + const res = await libBytes.readBytes32(data, 12) + expect(res).to.equal(bytes32) + }) + it('Should read bytes32 at last index', async () => { + const data = randomHex(11).concat(bytes32.slice(2)) + + const res = await libBytes.readBytes32(data, 11) + expect(res).to.equal(bytes32) + }) + it('Should read bytes32 out of bounds', async () => { + const data = randomHex(11).concat(bytes32.slice(2)) + const res = await libBytes.readBytes32(data, 12) + expect(res).to.equal('0x' + data.slice(26, 26 + 64) + '00') + }) + it('Should read bytes32 totally out of bounds', async () => { + const res = await libBytes.readBytes32('0x010203', 3145) + expect(res).to.equal(ethers.ZeroHash) + }) + }) + + describe('readUint32', () => { + it('Should read uint32 at index zero', async () => { + const res = await libBytes.readUint32('0x837fc8a10d', 0) + expect(res).to.equal(2206189729n) + }) + it('Should read uint32 at given index', async () => { + const res = await libBytes.readUint32('0x5a9c2a992a8c22199af0', 3) + expect(res).to.equal(2569702434n) + }) + it('Should read uint32 at last index', async () => { + const res = await libBytes.readUint32('0x029183af982299dfa001', 6) + expect(res).to.equal(2581569537n) + }) + it('Should read zeros uint32 out of bounds', async () => { + const res1 = await libBytes.readUint32('0x2293', 1) + const res2 = await libBytes.readUint32('0x2193000000', 1) + expect(res1).to.equal(2466250752n) + expect(res1).to.equal(res2) + }) + it('Should read all zeros uint32 fully out of bounds', async () => { + const res = await libBytes.readUint32('0xff92a09f339922', 15) + expect(res).to.equal(0n) + }) + }) + + describe('readUint16', () => { + it('Should read uint16 at index zero', async () => { + const res = await libBytesPointer.readUint16('0x5202', 0) + expect(res[0]).to.equal(20994n) + expect(res[1]).to.equal(2n) + }) + it('Should read uint16 at given index', async () => { + const res = await libBytesPointer.readUint16('0x5a9c2a1019d401d3', 3) + expect(res[0]).to.equal(4121n) + expect(res[1]).to.equal(5n) + }) + it('Should read uint16 at last index', async () => { + const res = await libBytesPointer.readUint16('0x020414', 1) + expect(res[0]).to.equal(1044n) + expect(res[1]).to.equal(3n) + }) + it('Should read zeros uint16 out of bounds', async () => { + const res1 = await libBytesPointer.readUint16('0x5a', 0) + const res2 = await libBytesPointer.readUint16('0x5a00', 0) + expect(res1[0]).to.equal(23040n) + expect(res1[0]).to.equal(res2[0]) + expect(res1[1]).to.equal(2n) + }) + it('Should read zeros uint16 fully out of bounds', async () => { + const res = await libBytesPointer.readUint16('0x5a9ca2', 12) + expect(res[0]).to.equal(0n) + expect(res[1]).to.equal(14n) + }) + }) + + describe('readUint24', () => { + it('Should read uint24 at index zero', async () => { + const res = await libBytesPointer.readUint24('0x5202fa', 0) + expect(res[0]).to.equal(5374714n) + expect(res[1]).to.equal(3n) + }) + it('Should read uint24 at given index', async () => { + const res = await libBytesPointer.readUint24('0x5202f7220c', 2) + expect(res[0]).to.equal(16196108n) + expect(res[1]).to.equal(5n) + }) + it('Should read uint24 at last index', async () => { + const res = await libBytesPointer.readUint24('0x021f2b00', 1) + expect(res[0]).to.equal(2042624n) + expect(res[1]).to.equal(4n) + }) + it('Should read zeros uint24 out of bounds', async () => { + const res1 = await libBytesPointer.readUint24('0xf598', 0) + const res2 = await libBytesPointer.readUint24('0xf59800', 0) + expect(res1[0]).to.equal(16095232n) + expect(res1[0]).to.equal(res2[0]) + expect(res1[1]).to.equal(3n) + }) + it('Should read zeros uint24 fully out of bounds', async () => { + const res = await libBytesPointer.readUint24('0x5a9ca221', 12) + expect(res[0]).to.equal(0n) + expect(res[1]).to.equal(15n) + }) + }) + + describe('readUint64', () => { + it('Should read uint64 at index zero', async () => { + const res = await libBytesPointer.readUint64('0xc1725050681dcb2a', 0) + expect(res[0]).to.equal(13939292102939495210n) + expect(res[1]).to.equal(8n) + }) + it('Should read uint64 at given index', async () => { + const res = await libBytesPointer.readUint64('0x0837acc1725050681dcb2a01cc', 3) + expect(res[0]).to.equal(13939292102939495210n) + expect(res[1]).to.equal(11n) + }) + it('Should read uint64 at last index', async () => { + const res = await libBytesPointer.readUint64('0x0837acc1725050681dcb2a', 3) + expect(res[0]).to.equal(13939292102939495210n) + expect(res[1]).to.equal(11n) + }) + it('Should read zeros uint64 out of bounds', async () => { + const res1 = await libBytesPointer.readUint64('0x5a', 0) + const res2 = await libBytesPointer.readUint64('0x5a00', 0) + const res3 = await libBytesPointer.readUint64('0x5a00000000000000', 0) + expect(res1[0]).to.equal(6485183463413514240n) + expect(res1[0]).to.equal(res2[0]) + expect(res1[0]).to.equal(res3[0]) + expect(res1[1]).to.equal(8n) + }) + it('Should read zeros uint64 fully out of bounds', async () => { + const res = await libBytesPointer.readUint64('0x5a9ca2', 12) + expect(res[0]).to.equal(0n) + expect(res[1]).to.equal(20n) + }) + }) +}) diff --git a/packages/wallet/wallet-contracts/test/LibString.spec.ts b/packages/wallet/wallet-contracts/test/LibString.spec.ts new file mode 100644 index 0000000000..7ca5f5c93c --- /dev/null +++ b/packages/wallet/wallet-contracts/test/LibString.spec.ts @@ -0,0 +1,83 @@ +import { ethers } from 'ethers' + +import { expect, expectStaticToBeRejected, randomHex } from './utils' +import { ContractType, LibStringImp } from './utils/contracts' + +contract('LibString', () => { + let libString: ContractType + + before(async () => { + libString = await LibStringImp.deploy() + }) + + describe('bytesToHexadecimal', () => { + new Array(99).fill(0).map((_, i) => { + it(`Should convert ${i} bytes to hexadecimal`, async () => { + const bytes = randomHex(i) + const expected = ethers.hexlify(bytes) + const result = await libString.bytesToHexadecimal(bytes) + expect(result).to.eq(expected.slice(2)) + + const prefixed = await libString.prefixHexadecimal(result) + expect(prefixed).to.eq(expected) + }) + }) + }) + + describe('bytesToBase32', () => { + ;[ + ['0x', 'b'], + ['0x69', 'bne'], + ['0x8775', 'bq52q'], + ['0x91e0f3', 'bshqpg'], + ['0x4867e789', 'bjbt6pci'], + ['0x456fe65b8d', 'bivx6mw4n'], + ['0xb20b0f525320', 'bwifq6ustea'], + ['0xd292f6c85f4e5a', 'b2kjpnsc7jzna'], + ['0xf78beb02b622adc7', 'b66f6wavwekw4o'], + ['0xfad9c9851352f0ae0e', 'b7lm4tbitklyk4dq'], + ['0x30b4bca5f67cc95312be', 'bgc2lzjpwptevgev6'], + ['0xebc9fd66e4ae84644d502b', 'b5pe72zxev2cgitkqfm'], + ['0x0f198dc28836e24782e8d182', 'bb4my3quig3repaxi2gba'], + ['0x50059d23099f062187e9d52d8a', 'bkacz2iyjt4dcdb7j2uwyu'], + ['0x4c0e454dc43d303c896ef5f9c449', 'bjqhektoehuydzclo6x44isi'], + ['0x1ee41f4e940e4bf14df57a4fc06dd9', 'bd3sb6tuubzf7ctpvpjh4a3oz'], + ['0x04a8d211d53b45d29fed9a624bb2d5e0', 'basuneeovhnc5fh7ntjrexmwv4a'], + ['0x0a8b878364cdd555bda61db7c67503bb5e', 'bbkfypa3ezxkvlpngdw34m5idxnpa'], + ['0x313b3c6e446ee6eb6477c0b0b01b70799cb6', 'bge5ty3sen3towzdxycylag3qpgolm'], + ['0xe8be4a44970232babf052c3e75f611df8099c5', 'b5c7eurexaizlvpyffq7hl5qr36ajtri'], + ['0x461eb18d034475a35d4084a89e0e3a47980f3408', 'biyplddidir22gxkaqsuj4dr2i6ma6nai'], + ['0x519e139092a60229fe1a4db06d26fd199af9d39680', 'bkgpbheesuybct7q2jwyg2jx5dgnptu4wqa'], + ['0x0fdd1a5696148daf6986505e2b3dc9af16ed91452720', 'bb7oruvuwcsg262mgkbpcwpojv4lo3ekfe4qa'], + ['0x63a77d886c3f6593b6c6d37c7ab1f16ca3e34bd67e1ae1', 'bmotx3cdmh5szhnwg2n6hvmprnsr6gs6wpynoc'], + ['0x1198cc96b431176fc2d5bc8a8c49ce041e184649ec3b9cbb', 'bcgmmzfvugelw7qwvxsfiysooaqpbqrsj5q5zzoy'], + ['0x6b8d9af44a31c799ef835a522f8b630435c8e77e844360ad3d', 'bnogzv5ckghdzt34dljjc7c3daq24rz36qrbwblj5'], + ['0xbb2cb7057a24b8588bafd87907ee7579b159027dc7224a3f6540', 'bxmwlobl2es4frc5p3b4qp3tvpgyvsat5y4reup3fia'], + ['0x1f64b537d0e4b0158142dfa7cbfd9af76af0931862e48df02ba35b', 'bd5slkn6q4syblakc36t4x7m265vpbeyymlsi34blunnq'], + ['0x11c5655f9d5496039fe6b1a9651014d4a19e62331d61e73b48fec776', 'bchcwkx45kslahh7gwguwkeau2sqz4yrtdvq6oo2i73dxm'], + ['0x752c3c5cb4a3f06e4feff3f543278e97c7626569994b12b0d9ba9c7c83', 'bouwdyxfuupyg4t7p6p2ugj4os7dwezljtffrfmgzxkohzay'], + ['0xb6bd83f8bba80bc8aca3706f7090cd5a0f0cc6adf4e89614bff58c149880', 'bw26yh6f3vaf4rlfdobxxbegnlihqzrvn6tujmff76wgbjgea'], + ['0x90f4b198a1a1b2d3e01c36ba3460f46249f180dfa67b152f81552266a18708', 'bsd2ldgfbugznhya4g25diyhumje7dag7uz5rkl4bkurgnimhba'], + [ + '0x24cda83efac2802425b1c35a2d21b01576e71d0e512bcc80840f85f9e0af2faa', + 'betg2qpx2ykacijnrynnc2inqcv3oohiokev4zaeeb6c7tyfpf6va' + ], + [ + '0x169dc221f4cec8756de592c3205a23177867f18c383d2251bd1a5c03cc346c3fe8', + 'bc2o4eipuz3ehk3pfslbsawrdc54gp4mmha6seun5djoahtbunq76q' + ], + [ + '0x65b13b1aef3e44180314108b7f0434ddc23ad740a0df4df7984ad0bf1fdd84edcbaf', + 'bmwytwgxphzcbqayuccfx6bbu3xbdvv2audpu354yjlil6h65qtw4xly' + ] + ].map(([bytes, base32Encoded]) => { + it(`Should convert ${ethers.getBytes(bytes).length} bytes to base32`, async () => { + const result = await libString.bytesToBase32(bytes) + expect(result).to.equal(base32Encoded.slice(1)) + + const prefixed = await libString.prefixBase32(result) + expect(prefixed).to.equal(base32Encoded) + }) + }) + }) +}) diff --git a/packages/wallet/wallet-contracts/test/MainModule.bench.ts b/packages/wallet/wallet-contracts/test/MainModule.bench.ts new file mode 100644 index 0000000000..bf192462d3 --- /dev/null +++ b/packages/wallet/wallet-contracts/test/MainModule.bench.ts @@ -0,0 +1,198 @@ +import { ethers } from 'ethers' + +import { deploySequenceContext, SequenceContext } from './utils/contracts' +import { SequenceWallet } from './utils/wallet' +import { Transaction } from './utils/sequence' + +const optimalGasLimit = 2n ** 22n +const runs = 256 + +function report2(values: ethers.BigNumberish[]) { + const bns = values.map(v => BigInt(v)) + + const min = bns.reduce((a, b) => (a < b ? a : b)) + const max = bns.reduce((a, b) => (a > b ? a : b)) + const avg = bns.reduce((p, n) => (p + n) / BigInt(values.length)) + + return { min, max, avg } +} + +function report(test: string, values: ethers.BigNumberish[]) { + const { min, max, avg } = report2(values) + console.info(` -> ${test} runs: ${values.length} cost min: ${min.toString()} max: ${max.toString()} avg: ${avg.toString()}`) +} + +contract('MainModule', () => { + let context: SequenceContext + + before(async () => { + context = await deploySequenceContext() + }) + + if (process.env.BENCHMARK) { + describe.only('Benchmark', function () { + ;(this as any).timeout(0) + + it('Deploy a wallet', async () => { + const results: ethers.BigNumberish[] = [] + + for (let i = 0; i < runs; i++) { + const tx = await SequenceWallet.basicWallet(context).deploy() + const receipt = await tx?.wait() + + if (!receipt) { + throw new Error('No receipt') + } + + results.push(receipt.gasUsed) + } + + report('deploy wallets', results) + }) + + it('Relay 1/1 transaction', async () => { + const results: ethers.BigNumberish[] = [] + + for (let i = 0; i < runs; i++) { + const wallet = SequenceWallet.basicWallet(context) + await wallet.deploy() + const tx = await wallet.sendTransactions([{}]) + const receipt = await tx.wait() + + if (!receipt) { + throw new Error('No receipt') + } + + results.push(receipt.gasUsed) + } + + report('relay 1/1 transaction', results) + }) + + const batches = [2, 3, 5, 10, 50, 100] + batches.forEach(n => { + it(`Relay 1/1 ${n} transactions`, async () => { + const results: ethers.BigNumberish[] = [] + + const transactions = new Array(n).fill(0).map(() => ({ + delegateCall: false, + revertOnError: true, + gasLimit: optimalGasLimit, + target: ethers.ZeroAddress, + value: 0n, + data: '0x0000000000000000000000007109709ecfa91a80626ff3989d68f67f5b1dd12e0000000000000000000000007109709ecfa91a80626ff3989d68f67f5b1dd12e' + })) + + for (let i = 0; i < runs; i++) { + const wallet = SequenceWallet.basicWallet(context) + await wallet.deploy() + const tx = await wallet.sendTransactions(transactions) + const receipt = await tx.wait() + + if (!receipt) { + throw new Error('No receipt') + } + + results.push(receipt.gasUsed) + } + + report(`relay 1/1 ${n} transactions`, results) + }) + }) + + batches.forEach(n => { + const ntxs = Math.floor(n / 2) + const nfailing = n - ntxs + it(`Relay 1/1 ${ntxs} transactions and ${nfailing} failing transactions`, async () => { + const results: ethers.BigNumberish[] = [] + + const transactions: Transaction[] = new Array(ntxs) + .fill(0) + .map(() => ({ + delegateCall: false, + revertOnError: true, + gasLimit: optimalGasLimit, + target: ethers.ZeroAddress, + value: 0n, + data: new Uint8Array([]) + })) + .concat( + await Promise.all( + new Array(nfailing).fill(0).map(async () => ({ + delegateCall: false, + revertOnError: false, + gasLimit: optimalGasLimit, + target: await context.factory.getAddress(), + value: 0n, + data: new Uint8Array([]) + })) + ) + ) + + for (let i = 0; i < runs; i++) { + const wallet = SequenceWallet.basicWallet(context) + await wallet.deploy() + const tx = await wallet.sendTransactions(transactions) + const receipt = await tx.wait() + + if (!receipt) { + throw new Error('No receipt') + } + + results.push(receipt.gasUsed) + } + + report(`relay 1/1 ${ntxs} transactions and ${nfailing} failing transactions`, results) + }) + }) + + const transaction: Transaction = { + delegateCall: false, + revertOnError: true, + gasLimit: optimalGasLimit, + target: ethers.ZeroAddress, + value: 0n, + data: new Uint8Array([]) + } + + it('Relay 2/5 transaction', async () => { + const results: ethers.BigNumberish[] = [] + + for (let i = 0; i < runs; i++) { + const wallet = SequenceWallet.basicWallet(context, { signing: [3, 1], idle: [1, 1, 3], threshold: 4 }) + await wallet.deploy() + const tx = await wallet.sendTransactions([transaction]) + const receipt = await tx.wait() + + if (!receipt) { + throw new Error('No receipt') + } + + results.push(receipt.gasUsed) + } + + report('relay 2/5 transaction', results) + }) + + it('Relay 255/255 transaction', async () => { + const results: ethers.BigNumberish[] = [] + + for (let i = 0; i < runs; i++) { + const wallet = SequenceWallet.basicWallet(context, { signing: 255, idle: 0, threshold: 255 }) + await wallet.deploy() + + const tx = await wallet.sendTransactions([transaction], undefined, { gasLimit: 60000000 }) + const receipt = await tx.wait() + + if (!receipt) { + throw new Error('No receipt') + } + + results.push(receipt.gasUsed) + } + + report('relay 255/255 transaction', results) + }) + }) + } +}) diff --git a/packages/wallet/wallet-contracts/test/MainModule.spec.ts b/packages/wallet/wallet-contracts/test/MainModule.spec.ts new file mode 100644 index 0000000000..b6204f9fc8 --- /dev/null +++ b/packages/wallet/wallet-contracts/test/MainModule.spec.ts @@ -0,0 +1,2247 @@ +import { ethers } from 'ethers' +import { ethers as hethers } from 'hardhat' + +import { bytes32toAddress, getChainId, expect, expectToBeRejected, randomHex, getSigHash } from './utils' + +import { + CallReceiverMock, + ContractType, + deploySequenceContext, + ModuleMock, + SequenceContext, + DelegateCallMock, + HookMock, + HookCallerMock, + GasBurnerMock, + AlwaysRevertMock +} from './utils/contracts' +import { Imposter } from './utils/imposter' +import { + applyTxDefaults, + computeStorageKey, + digestOf, + encodeNonce, + leavesOf, + legacyTopology, + merkleTopology, + optimize2SignersTopology, + printTopology, + SignatureType, + SimplifiedWalletConfig, + subdigestOf, + toSimplifiedConfig, + WalletConfig +} from './utils/sequence' +import { SequenceWallet, StaticSigner } from './utils/wallet' + +contract('MainModule', (accounts: string[]) => { + let context: SequenceContext + let callReceiver: ContractType + + let wallet: SequenceWallet + + before(async () => { + context = await deploySequenceContext() + }) + + beforeEach(async () => { + callReceiver = await CallReceiverMock.deploy() + await callReceiver.waitForDeployment() + + wallet = SequenceWallet.basicWallet(context) + await wallet.deploy() + }) + + describe('Nested signatures', () => { + it('Should accept simple nested signed ERC1271 message', async () => { + // Wallet A + const wallet_a = SequenceWallet.basicWallet(context) + await wallet_a.deploy() + + wallet = SequenceWallet.detailedWallet(context, { threshold: 1, signers: [wallet_a] }) + await wallet.deploy() + + const message = randomHex(32) + const signature = await wallet.signMessage(message) + + const hookCaller = await HookCallerMock.deploy() + await hookCaller.callERC1271isValidSignatureData(wallet.address, message, signature) + }) + + it('Should accept simple nested signer', async () => { + // Wallet A + const wallet_a = SequenceWallet.basicWallet(context) + await wallet_a.deploy() + + wallet = SequenceWallet.detailedWallet(context, { threshold: 1, signers: [wallet_a] }) + await wallet.deploy() + + const valA = 4123222n + const valB = randomHex(99) + + const transaction = { + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [valA, valB]) + } + + await wallet.sendTransactions([transaction]) + + expect(await callReceiver.lastValA()).to.equal(valA) + expect(await callReceiver.lastValB()).to.equal(valB) + }) + + it('Should accept two nested signers', async () => { + // WalletA + const wallet_a = SequenceWallet.basicWallet(context) + await wallet_a.deploy() + + // WalletB + const wallet_b = SequenceWallet.basicWallet(context) + await wallet_b.deploy() + + // Top level wallet + wallet = SequenceWallet.detailedWallet(context, { threshold: 1, signers: [wallet_a, wallet_b] }) + await wallet.deploy() + + const valA = 4123222n + const valB = randomHex(99) + + const transaction = { + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [valA, valB]) + } + + await wallet.sendTransactions([transaction]) + + expect(await callReceiver.lastValA()).to.equal(valA) + expect(await callReceiver.lastValB()).to.equal(valB) + }) + + it('Should accept mixed nested and eoa signers', async () => { + // WalletA + const wallet_a = SequenceWallet.basicWallet(context) + await wallet_a.deploy() + + // EOA (B) + const singer_b = ethers.Wallet.createRandom() + + // Top level wallet + wallet = SequenceWallet.detailedWallet(context, { threshold: 1, signers: [wallet_a, singer_b] }) + await wallet.deploy() + + const valA = 4123222n + const valB = randomHex(99) + + const transaction = { + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [valA, valB]) + } + + await wallet.sendTransactions([transaction]) + + expect(await callReceiver.lastValA()).to.equal(valA) + expect(await callReceiver.lastValB()).to.equal(valB) + }) + ;[ + { + name: '2 nested sequence wallets', + childs: 1, + depth: 2 + }, + { + name: '64 nested sequence wallets', + childs: 1, + depth: 64 + }, + { + name: '97 nested sequence wallets', + childs: 1, + depth: 97 + }, + { + name: 'binary tree of sequence wallets', + childs: 2, + depth: 5 + }, + { + name: 'ternary tree of sequence wallets', + childs: 3, + depth: 4 + }, + { + name: 'hexary tree of sequence wallets', + childs: 16, + depth: 2 + }, + { + name: 'random tree of sequence wallets (depth 1)', + depth: 1 + }, + { + name: 'random tree of sequence wallets (depth 2)', + depth: 2 + }, + { + name: 'random tree of sequence wallets (depth 3)', + depth: 3 + }, + { + name: 'random tree of sequence wallets (depth 4)', + depth: 4 + } + ].map(c => { + it(`Should handle ${c.name}`, async () => { + const genWallet = async ( + depth: number, + numChilds: number | undefined, + max: number + ): Promise => { + if (depth === max) { + return ethers.Wallet.createRandom() + } + + const nchilds = numChilds || Math.floor(Math.random() * 5) + 1 + const childs = await Promise.all(new Array(nchilds).fill(0).map(async () => genWallet(depth + 1, nchilds, max))) + const wallet = SequenceWallet.detailedWallet(context, { threshold: childs.length, signers: childs }) + await wallet.deploy() + + return wallet + } + + wallet = (await genWallet(0, c.childs, c.depth)) as SequenceWallet + + const valA = 5423n + const valB = randomHex(120) + + const transaction = { + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [valA, valB]) + } + + await wallet.sendTransactions([transaction], undefined, { gasLimit: 50000000 }) + + expect(await callReceiver.lastValA()).to.equal(valA) + expect(await callReceiver.lastValB()).to.equal(valB) + }) + }) + + it('Should reject invalid nested signature', async () => { + const wallet_a = SequenceWallet.basicWallet(context) + await wallet_a.deploy() + + let wallet_b = SequenceWallet.basicWallet(context) + await wallet_b.deploy() + + wallet = SequenceWallet.detailedWallet(context, { threshold: 1, signers: [wallet_a, wallet_b] }) + await wallet.deploy() + + const imposter = Imposter.random(wallet_b.signers[0] as StaticSigner) + wallet_b = wallet_b.useSigners([imposter]) + wallet = wallet.useSigners([wallet_a, wallet_b]) + + const transaction = { + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [5423, randomHex(32)]) + } + + const subdigest = await subdigestOf(wallet.address, digestOf([transaction], await wallet.getNonce())) + const badNestedSignature = await wallet_b.signDigest(subdigest).then(s => s + '03') + + const tx = wallet.sendTransactions([transaction]) + await expectToBeRejected(tx, `InvalidNestedSignature("${subdigest}", "${wallet_b.address}", "${badNestedSignature}")`) + }) + + it('Should enforce threshold on nested sigantures', async () => { + const wallet_a = SequenceWallet.basicWallet(context) + await wallet_a.deploy() + + let wallet_b = SequenceWallet.basicWallet(context) + await wallet_b.deploy() + + wallet = SequenceWallet.detailedWallet(context, { threshold: 3, signers: [wallet_a, wallet_b] }) + await wallet.deploy() + + const signauture = await wallet.signTransactions([{}]) + const subdigest = await subdigestOf(wallet.address, digestOf([{}], await wallet.getNonce())) + + const tx = wallet.relayTransactions([{}], signauture) + await expect(tx).to.be.rejected + }) + + it('Should read weight of nested wallets', async () => { + const wallet_a = SequenceWallet.basicWallet(context) + await wallet_a.deploy() + + const wallet_b = SequenceWallet.basicWallet(context) + await wallet_b.deploy() + + const wallet_c = SequenceWallet.basicWallet(context) + await wallet_c.deploy() + + wallet = SequenceWallet.detailedWallet(context, { + threshold: 2, + signers: [wallet_a, wallet_b, { weight: 2, value: wallet_c }] + }) + await wallet.deploy() + + const valA = 5423n + const valB = randomHex(120) + + const transaction = { + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [valA, valB]) + } + + await wallet.useSigners(wallet_c).sendTransactions([transaction]) + + expect(await callReceiver.lastValA()).to.equal(valA) + expect(await callReceiver.lastValB()).to.equal(valB) + }) + }) + + describe('Authentication', () => { + it('Should accept initial owner signature', async () => { + await wallet.sendTransactions([{}]) + }) + + it('Should reject non-owner signature', async () => { + const tx = wallet.useSigners(Imposter.random(wallet.signers[0] as StaticSigner)).sendTransactions([{}]) + await expect(tx).to.be.rejected + }) + + describe('Network ID', () => { + it('Should reject a transaction of another network id', async () => { + wallet = wallet.useChainId((await getChainId()) + 1n) + const tx = wallet.sendTransactions([{}]) + await expectToBeRejected(tx, 'InvalidSignature') + }) + + describe('Universal network signatures', async () => { + it('Should reject signature for another network id, even if encoded as universal', async () => { + wallet = wallet.useChainId((await getChainId()) + 1n) + const tx = wallet.sendTransactions([{}]) + await expectToBeRejected(tx, 'InvalidSignature') + }) + + it('Should reject signature with chainId zero if not using special encoding', async () => { + wallet = wallet.useChainId(0) + const tx = wallet.sendTransactions([{}]) + await expectToBeRejected(tx, 'InvalidSignature') + }) + + it('Should accept transaction with chainId zero if encoded with no chaind type', async () => { + wallet = wallet.useChainId(0).useEncodingOptions({ signatureType: SignatureType.NoChaindDynamic }) + await wallet.sendTransactions([{}]) + }) + }) + }) + + describe('Nonce', () => { + const spaces = [0n, 1n, 7342n, ethers.toBigInt(ethers.randomBytes(20)), 2n ** 160n - 1n] + + describe('Using non-encoded nonce', () => { + it('Should default to space zero', async () => { + await wallet.sendTransactions([{}]) + expect(await wallet.mainModule.nonce()).to.equal(1n) + }) + + it('Should work with zero as initial nonce', async () => { + await wallet.sendTransactions([{}]) + expect(await wallet.mainModule.readNonce(0)).to.equal(1n) + }) + + it('Should emit NonceChange event', async () => { + const receipt1 = await wallet.sendTransactions([{}]).then(t => t.wait()) + const receipt2 = await wallet.sendTransactions([{}]).then(t => t.wait()) + + if (!receipt1 || !receipt2) { + throw new Error('No receipt') + } + + const events1 = receipt1.logs.filter(log => log instanceof ethers.EventLog) as ethers.EventLog[] + const ev1 = events1.find(ev => ev.eventName === 'NonceChange') + expect(ev1!.eventName).to.be.eql('NonceChange') + expect(ev1!.args._space).to.equal(0n) + expect(ev1!.args._newNonce).to.equal(1n) + + const events2 = receipt2.logs.filter(log => log instanceof ethers.EventLog) as ethers.EventLog[] + const ev2 = events2.find(ev => ev.eventName === 'NonceChange') + expect(ev2!.eventName).to.be.eql('NonceChange') + expect(ev1!.args._space).to.equal(0n) + expect(ev2!.args._newNonce).to.equal(2n) + }) + + it('Should fail if nonce did not change', async () => { + await wallet.sendTransactions([{}], 0) + const tx = wallet.sendTransactions([{}], 0) + await expectToBeRejected(tx, `BadNonce(0, 0, 1)`) + }) + + it('Should fail if nonce increased by two', async () => { + await wallet.sendTransactions([{}]) + const tx = wallet.sendTransactions([{}], 2) + await expectToBeRejected(tx, `BadNonce(0, 2, 1)`) + }) + }) + + spaces.forEach(space => { + describe(`using ${ethers.toBeHex(space)} space`, () => { + it('Should work with zero as initial nonce', async () => { + await wallet.sendTransactions([{}], encodeNonce(space, 0)) + expect(await wallet.mainModule.readNonce(space)).to.equal(1n) + }) + + it('Should emit NonceChange event', async () => { + const receipt1 = await wallet.sendTransactions([{}], encodeNonce(space, 0)).then(t => t.wait()) + const receipt2 = await wallet.sendTransactions([{}], encodeNonce(space, 1)).then(t => t.wait()) + + if (!receipt1 || !receipt2) { + throw new Error('No receipt') + } + + const events1 = receipt1.logs.filter(log => log instanceof ethers.EventLog) as ethers.EventLog[] + const ev1 = events1.find(ev => ev.eventName === 'NonceChange') + expect(ev1!.eventName).to.be.eql('NonceChange') + expect(ev1!.args!._space).to.equal(space) + expect(ev1!.args!._newNonce).to.equal(1n) + + const events2 = receipt2.logs.filter(log => log instanceof ethers.EventLog) as ethers.EventLog[] + const ev2 = events2.find(ev => ev.eventName === 'NonceChange') + expect(ev2!.eventName).to.be.eql('NonceChange') + expect(ev2!.args!._space).to.equal(space) + expect(ev2!.args!._newNonce).to.equal(2n) + }) + + it('Should accept next nonce', async () => { + await wallet.sendTransactions([{}], encodeNonce(space, 0)) + await wallet.sendTransactions([{}], encodeNonce(space, 1)) + + expect(await wallet.mainModule.readNonce(space)).to.equal(2n) + }) + + it('Should fail if nonce did not change', async () => { + await wallet.sendTransactions([{}], encodeNonce(space, 0)) + const tx = wallet.sendTransactions([{}], encodeNonce(space, 0)) + + await expectToBeRejected(tx, `BadNonce(${space.toString()}, 0, 1)`) + }) + + it('Should fail if nonce increased by two', async () => { + await wallet.sendTransactions([{}], encodeNonce(space, 0)) + const tx = wallet.sendTransactions([{}], encodeNonce(space, 2)) + + await expectToBeRejected(tx, `BadNonce(${space.toString()}, 2, 1)`) + }) + + it('Should use nonces storage keys', async () => { + const subkey = ethers.AbiCoder.defaultAbiCoder().encode(['uint256'], [space]) + const storageKey = computeStorageKey('org.arcadeum.module.calls.nonce', subkey) + + await wallet.sendTransactions([{}], encodeNonce(space, 0)) + + const storageValue = await hethers.provider.getStorage(wallet.address, storageKey) + expect(BigInt(storageValue)).to.equal(1n) + }) + }) + }) + + describe('using two spaces simultaneously', () => { + it('Should keep separated nonce counts', async () => { + await wallet.sendTransactions([{}], encodeNonce(1, 0)) + + expect(await wallet.mainModule.readNonce(1)).to.equal(1n) + expect(await wallet.mainModule.readNonce(2)).to.equal(0n) + + await wallet.sendTransactions([{}], encodeNonce(2, 0)) + + expect(await wallet.mainModule.readNonce(1)).to.equal(1n) + expect(await wallet.mainModule.readNonce(2)).to.equal(1n) + await wallet.sendTransactions([{}], encodeNonce(2, 1)) + await wallet.sendTransactions([{}], encodeNonce(2, 2)) + + expect(await wallet.mainModule.readNonce(1)).to.equal(1n) + expect(await wallet.mainModule.readNonce(2)).to.equal(3n) + }) + + it('Should emit different events', async () => { + await wallet.sendTransactions([{}], encodeNonce(1, 0)) + await wallet.sendTransactions([{}], encodeNonce(1, 1)) + + const receipt1 = await wallet.sendTransactions([{}], encodeNonce(1, 2)).then(t => t.wait()) + const receipt2 = await wallet.sendTransactions([{}], encodeNonce(2, 0)).then(t => t.wait()) + + if (!receipt1 || !receipt2) { + throw new Error('No receipt') + } + + const events1 = receipt1.logs.filter(log => log instanceof ethers.EventLog) as ethers.EventLog[] + const ev1 = events1.find(ev => ev.eventName === 'NonceChange') + expect(ev1!.eventName).to.be.eql('NonceChange') + expect(ev1!.args!._space).to.equal(1n) + expect(ev1!.args!._newNonce).to.equal(3n) + + const events2 = receipt2.logs.filter(log => log instanceof ethers.EventLog) as ethers.EventLog[] + const ev2 = events2.find(ev => ev.eventName === 'NonceChange') + expect(ev2!.eventName).to.be.eql('NonceChange') + expect(ev2!.args!._space).to.equal(2n) + expect(ev2!.args!._newNonce).to.equal(1n) + }) + + it('Should not accept nonce of different space', async () => { + await wallet.sendTransactions([{}], encodeNonce(1, 0)) + const tx = wallet.sendTransactions([{}], encodeNonce(2, 1)) + await expectToBeRejected(tx, `BadNonce(2, 1, 0)`) + }) + }) + }) + + it('Should reject signature with invalid flag', async () => { + const tx = wallet.relayTransactions([{}], '0x000193812833ff01') + await expectToBeRejected(tx, 'InvalidSignatureFlag(255)') + }) + + it('Should reject signature with bad encoding type', async () => { + const tx = wallet.relayTransactions([{}], '0x2012') + const subdigest = await subdigestOf(wallet.address, digestOf([{}], 0)) + await expectToBeRejected(tx, `InvalidSignatureType("0x20")`) + }) + + it('Should reject direct calls to templates', async () => { + const tx1 = context.mainModule.execute([], 0, '0x') + await expectToBeRejected(tx1, 'OnlyDelegatecall') + + const tx2 = context.mainModuleUpgradable.execute([], 0, '0x') + await expectToBeRejected(tx2, 'OnlyDelegatecall') + }) + + it('Should reject empty dynamic signature', async () => { + const tx = wallet.relayTransactions([{}], '0x0001000000000201ABFf4013541fd79ee5b6847C9dF3C9B34183C283000000') + await expectToBeRejected(tx, 'EmptySignature()') + }) + }) + + describe('Upgradeability', () => { + it('Should update implementation', async () => { + const newImplementation = await ModuleMock.deploy() + + const transaction = { + target: wallet.address, + data: wallet.mainModule.interface.encodeFunctionData('updateImplementation', [await newImplementation.getAddress()]) + } + + await wallet.sendTransactions([transaction]) + + const mock_wallet = ModuleMock.attach(wallet.address) + const tx = await mock_wallet.ping() + const receipt = await tx.wait() + + const events = receipt!.logs.filter(log => log instanceof ethers.EventLog) as ethers.EventLog[] + + expect(events![0].eventName).to.equal('Pong') + }) + it('Should fail to set implementation to address 0', async () => { + const transaction = { + target: wallet.address, + data: wallet.mainModule.interface.encodeFunctionData('updateImplementation', [ethers.ZeroAddress]) + } + + const tx = wallet.sendTransactions([transaction]) + await expectToBeRejected(tx, `InvalidImplementation("${ethers.ZeroAddress}")`) + }) + it('Should fail to set implementation to non-contract', async () => { + const transaction = { + target: wallet.address, + data: wallet.mainModule.interface.encodeFunctionData('updateImplementation', [accounts[1]]) + } + + const tx = wallet.sendTransactions([transaction]) + await expectToBeRejected(tx, `InvalidImplementation("${accounts[1]}")`) + }) + it('Should use implementation storage key', async () => { + await wallet.updateImageHash(ethers.randomBytes(32)) + + const storageValue = await hethers.provider.getStorage(wallet.address, wallet.address) + expect(bytes32toAddress(storageValue)).to.equal(await context.mainModuleUpgradable.getAddress()) + }) + }) + + describe('Extra image hashes', () => { + ;[ + { + name: 'using MainModule', + beforeEach: () => {} + }, + { + name: 'using MainModuleUpgradable', + beforeEach: async () => { + const newConfig = SequenceWallet.basicWallet(context) + await wallet.updateImageHash(newConfig.imageHash) + wallet = wallet.useAddress().useConfig(newConfig.config).useSigners(newConfig.signers) + } + } + ].map(c => { + describe(c.name, () => { + beforeEach(c.beforeEach) + + it('Should accept signatures from multiple imageHashes', async () => { + const altWallet = SequenceWallet.basicWallet(context, { signing: 3, idle: 9 }) + + await wallet.deploy() + await wallet.addExtraImageHash(altWallet.imageHash) + + wallet.sendTransactions([{}], encodeNonce(1, 0)) + + expect(await wallet.mainModule.extraImageHash(altWallet.imageHash)).to.not.equal(0) + + wallet = wallet + .useAddress() + .useConfig({ ...altWallet.config, address: undefined }) + .useSigners(altWallet.signers) + + await wallet.sendTransactions([{}]) + }) + + it('Should reject expired extra imgeHash', async () => { + const altWallet = SequenceWallet.basicWallet(context, { signing: 3, idle: 9 }) + await wallet.deploy() + await wallet.addExtraImageHash(altWallet.imageHash, 100) + + const badWallet1 = wallet + .useAddress() + .useConfig({ ...altWallet.config, address: undefined }) + .useSigners(altWallet.signers) + + const tx = badWallet1.sendTransactions([{}]) + await expect(tx).to.be.rejected + }) + + it('Should clear multiple extra imageHashes', async () => { + const altWallet1 = SequenceWallet.basicWallet(context, { signing: 3, idle: 9 }) + const altWallet2 = SequenceWallet.basicWallet(context) + + await wallet.deploy() + await wallet.addExtraImageHash(altWallet1.imageHash) + await wallet.addExtraImageHash(altWallet2.imageHash) + + expect(await wallet.mainModule.extraImageHash(altWallet1.imageHash)).to.not.equal(0) + expect(await wallet.mainModule.extraImageHash(altWallet2.imageHash)).to.not.equal(0) + + await wallet.clearExtraImageHashes([altWallet1.imageHash, altWallet2.imageHash]) + + const badWallet1 = wallet + .useAddress() + .useConfig({ ...altWallet1.config, address: undefined }) + .useSigners(altWallet1.signers) + + const badWallet2 = wallet + .useAddress() + .useConfig({ ...altWallet1.config, address: undefined }) + .useSigners(altWallet1.signers) + + expect(await wallet.mainModule.extraImageHash(altWallet1.imageHash)).to.equal(0n) + expect(await wallet.mainModule.extraImageHash(altWallet2.imageHash)).to.equal(0n) + + await expect(badWallet1.sendTransactions([{}])).to.be.rejected + await expect(badWallet2.sendTransactions([{}])).to.be.rejected + await expect(wallet.sendTransactions([{}])).to.be.fulfilled + }) + + it('Should fail to set extra imageHashes if not from self', async () => { + const altWallet = SequenceWallet.basicWallet(context) + const tx = wallet.mainModule.setExtraImageHash(altWallet.imageHash, Math.floor(Date.now() / 1000) + 1000) + await expectToBeRejected(tx, `OnlySelfAuth("${accounts[0]}", "${wallet.address}")`) + }) + + it('Should fail to clear extra imageHashes if not from self', async () => { + const tx = wallet.mainModule.clearExtraImageHashes([]) + await expectToBeRejected(tx, `OnlySelfAuth("${accounts[0]}", "${wallet.address}")`) + }) + }) + }) + }) + + describe('Static merkle digests', () => { + ;[ + { + name: 'using MainModule', + beforeEach: () => {} + }, + { + name: 'using MainModuleUpgradable', + beforeEach: async () => { + const newConfig = SequenceWallet.basicWallet(context) + await wallet.updateImageHash(newConfig.imageHash) + wallet = wallet.useAddress().useConfig(newConfig.config).useSigners(newConfig.signers) + } + } + ].map(c => { + describe(c.name, () => { + it('Should reject proof for another subdigest', async () => { + const digests = new Array(2).fill(0).map(() => ethers.hexlify(ethers.randomBytes(32))) + const subdigests = await Promise.all(digests.map(async d => ({ subdigest: await subdigestOf(wallet.address, d, 0) }))) + const subdigestsMerkle = merkleTopology([...subdigests]) + + const prevLeaves = leavesOf(wallet.config.topology) + const newMerkle = merkleTopology([subdigestsMerkle, ...prevLeaves]) + const newConfig = { threshold: wallet.config.threshold, topology: newMerkle, checkpoint: Math.floor(Date.now() / 1000) } + + await wallet.deploy() + await wallet.updateImageHash(newConfig) + wallet = wallet.useAddress(wallet.address).useConfig(newConfig) + + await wallet.sendTransactions([]) + + const subdigest = ethers.hexlify(subdigests[0].subdigest) + const encoded = wallet.staticSubdigestSign(subdigest) + const res = await wallet.mainModule['isValidSignature(bytes32,bytes)'](digests[1], encoded) + expect(res).to.equal('0x00000000') + }) + + it('Should accept merkle proof', async () => { + wallet = SequenceWallet.basicWallet(context, { signing: 10, idle: 11 }) + + const digests = new Array(33).fill(0).map(() => ethers.hexlify(ethers.randomBytes(32))) + const subdigests = await Promise.all(digests.map(async d => ({ subdigest: await subdigestOf(wallet.address, d, 0) }))) + const subdigestsMerkle = merkleTopology([...subdigests]) + + const prevLeaves = leavesOf(wallet.config.topology) + const newMerkle = merkleTopology([subdigestsMerkle, ...prevLeaves]) + const newConfig = { threshold: wallet.config.threshold, topology: newMerkle, checkpoint: Math.floor(Date.now() / 1000) } + + await wallet.deploy() + await wallet.updateImageHash(newConfig) + wallet = wallet.useAddress(wallet.address).useConfig(newConfig) + + await wallet.sendTransactions([]) + + for (let i = 0; i < subdigests.length; i++) { + const subdigest = ethers.hexlify(subdigests[i].subdigest) + const encoded = wallet.staticSubdigestSign(subdigest) + const res = await wallet.mainModule['isValidSignature(bytes32,bytes)'](digests[i], encoded) + expect(res).to.equal('0x1626ba7e') + } + }) + }) + }) + }) + + describe('Nested configurations', async () => { + it('Should use nested configuration as a regular branch', async () => { + const nested = SequenceWallet.basicWallet(context, { signing: 1, idle: 11 }) + const simplifiedConfig = { + threshold: 1, + checkpoint: 2, + signers: [ + { + address: ethers.Wallet.createRandom().address, + weight: 1 + }, + { + ...toSimplifiedConfig(nested.config), + weight: 1 + } + ] + } + + const config = { + ...simplifiedConfig, + topology: legacyTopology(simplifiedConfig) + } + + const wallet = new SequenceWallet({ context, config, signers: nested.signers }) + await wallet.deploy() + + await wallet.sendTransactions([]) + }) + it('Should use nested configuration with independent weight and threshold', async () => { + const nested = SequenceWallet.basicWallet(context, { signing: 2, idle: 11 }) + const simplifiedConfig = { + threshold: 5, + checkpoint: 2, + signers: [ + { + ...toSimplifiedConfig(nested.config), + weight: 5 + }, + { + address: ethers.Wallet.createRandom().address, + weight: 1 + } + ] + } + + const config = { + ...simplifiedConfig, + topology: merkleTopology(simplifiedConfig) + } + + const wallet = new SequenceWallet({ context, config, signers: nested.signers }) + await wallet.deploy() + + await wallet.sendTransactions([]) + }) + it('Should reject nested configuration if not enough internal signing power', async () => { + const nested = SequenceWallet.basicWallet(context, { signing: 2, idle: 11 }) + + const simplifiedConfig = { + threshold: 1, + checkpoint: 2, + signers: [ + { + ...toSimplifiedConfig(nested.config), + weight: 5 + }, + { + address: ethers.Wallet.createRandom().address, + weight: 1 + } + ] + } + + const config = { + ...simplifiedConfig, + topology: merkleTopology(simplifiedConfig) + } + + const wallet = new SequenceWallet({ context, config, signers: [nested.signers[0]] }) + await wallet.deploy() + + const tx = wallet.sendTransactions([]) + await expectToBeRejected(tx, 'InvalidSignature') + }) + it('Should limit nested signing power', async () => { + const nested = SequenceWallet.basicWallet(context, { signing: 10 }) + + const simplifiedConfig = { + threshold: 2, + checkpoint: 2, + signers: [ + { + ...toSimplifiedConfig(nested.config), + weight: 1 + }, + { + address: ethers.Wallet.createRandom().address, + weight: 1 + } + ] + } + + const config = { + ...simplifiedConfig, + topology: merkleTopology(simplifiedConfig) + } + + const wallet = new SequenceWallet({ context, config, signers: nested.signers }) + await wallet.deploy() + + const tx = wallet.sendTransactions([]) + await expectToBeRejected(tx, 'InvalidSignature') + }) + }) + + describe('External calls', () => { + let { valA, valB } = { valA: BigInt(Math.floor(Date.now())), valB: randomHex(120) } + + it('Should perform call to contract', async () => { + const transaction = { + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [valA, valB]) + } + + await wallet.sendTransactions([transaction]) + expect(await callReceiver.lastValA()).to.equal(valA) + expect(await callReceiver.lastValB()).to.equal(valB) + }) + it('Should return error message', async () => { + await callReceiver.setRevertFlag(true) + + const transaction = { + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [0, new Uint8Array([])]) + } + + const tx = wallet.sendTransactions([transaction]) + await expect(tx).to.be.rejectedWith('CallReceiverMock#testCall: REVERT_FLAG') + }) + describe('Batch transactions', () => { + let callReceiver2: ContractType + let { val2A, val2B } = { val2A: 9422n, val2B: randomHex(31) } + + beforeEach(async () => { + callReceiver2 = await CallReceiverMock.deploy() + }) + + it('Should perform multiple calls to contracts in one tx', async () => { + const transactions = [ + { + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [valA, valB]) + }, + { + target: await callReceiver2.getAddress(), + data: callReceiver2.interface.encodeFunctionData('testCall', [val2A, val2B]) + } + ] + + await wallet.sendTransactions(transactions) + expect(await callReceiver.lastValA()).to.equal(valA) + expect(await callReceiver.lastValB()).to.equal(valB) + expect(await callReceiver2.lastValA()).to.equal(val2A) + expect(await callReceiver2.lastValB()).to.equal(val2B) + }) + + it('Should perform call a contract and transfer eth in one tx', async () => { + const signer = await hethers.provider.getSigner() + await signer.sendTransaction({ to: wallet.address, value: 100 }) + const receiver = new ethers.Wallet(ethers.hexlify(ethers.randomBytes(32))) + + const transactions = [ + { + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [valA, valB]) + }, + { + target: receiver.address, + value: 26 + } + ] + + await wallet.sendTransactions(transactions) + + expect(await callReceiver.lastValA()).to.equal(valA) + expect(await callReceiver.lastValB()).to.equal(valB) + expect(await hethers.provider.getBalance(receiver.address)).to.equal(26n) + }) + + it('Should fail if one transaction fails', async () => { + const signer = await hethers.provider.getSigner() + await signer.sendTransaction({ to: wallet.address, value: 100 }) + + await callReceiver.setRevertFlag(true) + + const transactions = [ + { + target: ethers.Wallet.createRandom().address, + value: 26 + }, + { + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [0, new Uint8Array([])]) + } + ] + + const tx = wallet.sendTransactions(transactions) + await expect(tx).to.be.rejectedWith('CallReceiverMock#testCall: REVERT_FLAG') + }) + }) + }) + + describe('Delegate calls', () => { + let delegateCallMock: ContractType + + beforeEach(async () => { + delegateCallMock = await DelegateCallMock.deploy() + }) + + it('Should delegate call to module', async () => { + const transaction1 = { + delegateCall: true, + target: await delegateCallMock.getAddress(), + data: delegateCallMock.interface.encodeFunctionData('write', [11, 45]) + } + + await wallet.sendTransactions([transaction1]) + + const transaction2 = { + delegateCall: true, + target: await delegateCallMock.getAddress(), + data: delegateCallMock.interface.encodeFunctionData('read', [11]) + } + + const tx = await wallet.sendTransactions([transaction2]) + const receipt = await tx.wait() + + if (!receipt) { + throw new Error('No receipt') + } + + const val = BigInt(receipt.logs.slice(-2)[0].data) + expect(val).to.equal(45n) + }) + + describe('on delegate call revert', () => { + beforeEach(async () => { + await wallet.sendTransactions([ + { + delegateCall: true, + target: await delegateCallMock.getAddress(), + data: delegateCallMock.interface.encodeFunctionData('setRevertFlag', [true]) + } + ]) + }) + + it('Should pass if revertOnError is false', async () => { + const transaction = { + delegateCall: true, + revertOnError: false, + target: await delegateCallMock.getAddress(), + data: delegateCallMock.interface.encodeFunctionData('write', [11, 45]) + } + + await wallet.sendTransactions([transaction]) + }) + + it('Should fail if delegate call fails', async () => { + const transaction = { + delegateCall: true, + target: await delegateCallMock.getAddress(), + data: delegateCallMock.interface.encodeFunctionData('write', [11, 45]) + } + + const tx = wallet.sendTransactions([transaction]) + await expect(tx).to.be.rejectedWith('DelegateCallMock#write: REVERT_FLAG') + }) + }) + }) + + describe('Handle ETH', () => { + it('Should receive ETH', async () => { + const signer = await hethers.provider.getSigner() + signer.sendTransaction({ to: wallet.address, value: 1 }) + }) + + it('Should transfer ETH', async () => { + const signer = await hethers.provider.getSigner() + signer.sendTransaction({ to: wallet.address, value: 100 }) + + const receiver = ethers.Wallet.createRandom().address + + const transaction = { + target: receiver, + value: 25 + } + + await wallet.sendTransactions([transaction]) + expect(await hethers.provider.getBalance(receiver)).to.equal(25n) + }) + + it('Should call payable function', async () => { + const signer = await hethers.provider.getSigner() + signer.sendTransaction({ to: wallet.address, value: 100 }) + + const valA = 63129n + const valB = randomHex(120) + const value = 33n + + const transaction = { + target: await callReceiver.getAddress(), + value: value, + data: callReceiver.interface.encodeFunctionData('testCall', [valA, valB]) + } + + await wallet.sendTransactions([transaction]) + expect(await hethers.provider.getBalance(await callReceiver.getAddress())).to.equal(value) + expect(await callReceiver.lastValA()).to.equal(valA) + expect(await callReceiver.lastValB()).to.equal(valB) + }) + }) + + describe('Optional transactions', () => { + it('Should skip a skipOnError transaction', async () => { + await callReceiver.setRevertFlag(true) + + const transaction = { + revertOnError: false, + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [0, new Uint8Array([])]) + } + + const receipt = await wallet.sendTransactions([transaction]).then(r => r.wait()) + + if (!receipt) { + throw new Error('No receipt') + } + + const events = receipt.logs.filter(log => log instanceof ethers.EventLog) as ethers.EventLog[] + const event = events.pop() + + const reason = ethers.AbiCoder.defaultAbiCoder().decode(['string'], '0x' + event!.args!._reason.slice(10))[0] + expect(reason).to.equal('CallReceiverMock#testCall: REVERT_FLAG') + }) + + describe('With multiple transactions', () => { + let callReceiver2: ContractType + const { valA, valB } = { valA: 912341n, valB: randomHex(30) } + + beforeEach(async () => { + callReceiver2 = await CallReceiverMock.deploy() + }) + + it('Should skip failing transaction within batch', async () => { + await callReceiver.setRevertFlag(true) + + const transactions = [ + { + revertOnError: false, + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [0, new Uint8Array([])]) + }, + { + revertOnError: false, + target: await callReceiver2.getAddress(), + data: callReceiver2.interface.encodeFunctionData('testCall', [valA, valB]) + } + ] + + const receipt = await wallet.sendTransactions(transactions).then(r => r.wait()) + + if (!receipt) { + throw new Error('No receipt') + } + + const events = receipt.logs.filter(log => log instanceof ethers.EventLog) as ethers.EventLog[] + const ev = events.find(ev => ev.eventName === 'TxFailed') + + const reason = ethers.AbiCoder.defaultAbiCoder().decode(['string'], '0x' + ev!.args!._reason.slice(10))[0] + expect(reason).to.equal('CallReceiverMock#testCall: REVERT_FLAG') + + expect(await callReceiver2.lastValA()).to.equal(valA) + expect(await callReceiver2.lastValB()).to.equal(valB) + }) + + it('Should skip multiple failing transactions within batch', async () => { + await callReceiver.setRevertFlag(true) + + const transactions = [ + { + revertOnError: false, + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [0, new Uint8Array([])]) + }, + { + revertOnError: false, + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [0, new Uint8Array([])]) + }, + { + target: await callReceiver2.getAddress(), + data: callReceiver2.interface.encodeFunctionData('testCall', [valA, valB]) + } + ] + + const txHash = await subdigestOf(wallet.address, digestOf(transactions, await wallet.getNonce())) + const receipt = await wallet.sendTransactions(transactions).then(r => r.wait()) + + if (!receipt) { + throw new Error('No receipt') + } + + const events = receipt.logs.filter(log => log instanceof ethers.EventLog) as ethers.EventLog[] + + const event1 = events[1] + const event2 = events[2] + + const reason1 = ethers.AbiCoder.defaultAbiCoder().decode(['string'], '0x' + event1.args!._reason.slice(10))[0] + const reason2 = ethers.AbiCoder.defaultAbiCoder().decode(['string'], '0x' + event2.args!._reason.slice(10))[0] + + expect(reason1).to.equal('CallReceiverMock#testCall: REVERT_FLAG') + expect(reason2).to.equal('CallReceiverMock#testCall: REVERT_FLAG') + + expect(event1.args!._tx).to.equal(txHash) + expect(event2.args!._tx).to.equal(txHash) + + expect(await callReceiver2.lastValA()).to.equal(valA) + expect(await callReceiver2.lastValB()).to.equal(valB) + }) + + it('Should skip all failing transactions within a batch', async () => { + await callReceiver.setRevertFlag(true) + + const transactions = [ + { + revertOnError: false, + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [0, new Uint8Array([])]) + }, + { + revertOnError: false, + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [0, new Uint8Array([])]) + } + ] + + const receipt = await wallet.sendTransactions(transactions).then(r => r.wait()) + + if (!receipt) { + throw new Error('No receipt') + } + + const events = receipt.logs.filter(log => log instanceof ethers.EventLog) as ethers.EventLog[] + + const event1 = events.pop() + const event2 = events.pop() + + const reason1 = ethers.AbiCoder.defaultAbiCoder().decode(['string'], '0x' + event1!.args!._reason.slice(10))[0] + const reason2 = ethers.AbiCoder.defaultAbiCoder().decode(['string'], '0x' + event2!.args!._reason.slice(10))[0] + + expect(reason1).to.equal('CallReceiverMock#testCall: REVERT_FLAG') + expect(reason2).to.equal('CallReceiverMock#testCall: REVERT_FLAG') + }) + }) + }) + + describe('Hooks', () => { + let hookCallerMock: ContractType + + before(async () => { + hookCallerMock = await HookCallerMock.deploy() + }) + + describe('receive tokens', () => { + it('Should implement ERC1155 single transfer hook', async () => { + await hookCallerMock.callERC1155Received(wallet.address) + }) + it('Should implement ERC1155 batch transfer hook', async () => { + await hookCallerMock.callERC1155BatchReceived(wallet.address) + }) + it('Should implement ERC721 transfer hook', async () => { + await hookCallerMock.callERC721Received(wallet.address) + }) + it('Should implement ERC223 transfer hook', async () => { + await hookCallerMock.callERC223Received(wallet.address) + }) + }) + + describe('ERC1271 Wallet', () => { + let message = randomHex(250) + let hash = ethers.keccak256(ethers.randomBytes(32)) + + it('Should validate arbitrary signed data', async () => { + const signature = await wallet.signMessage(message) + await hookCallerMock.callERC1271isValidSignatureData(wallet.address, message, signature) + }) + + it('Should validate arbitrary signed hash', async () => { + const signature = await wallet.signDigest(hash) + await hookCallerMock.callERC1271isValidSignatureHash(wallet.address, hash, signature) + }) + + it('Should reject data signed by non-owner', async () => { + const impostor = SequenceWallet.basicWallet(context) + const signature = await impostor.signMessage(message) + const tx = hookCallerMock.callERC1271isValidSignatureData(wallet.address, message, signature) + await expect(tx).to.be.rejectedWith('HookCallerMock#callERC1271isValidSignatureData: INVALID_RETURN') + }) + + it('Should reject hash signed by non-owner', async () => { + const impostor = SequenceWallet.basicWallet(context) + const signature = await impostor.signDigest(hash) + const tx = hookCallerMock.callERC1271isValidSignatureHash(wallet.address, hash, signature) + await expect(tx).to.be.rejectedWith('HookCallerMock#callERC1271isValidSignatureHash: INVALID_RETURN') + }) + }) + + describe('External hooks', () => { + let hookMock: ContractType + let hookSelector: string + + before(async () => { + hookMock = await HookMock.deploy() + const fragment = hookMock.interface.getFunction('onHookMockCall') + hookSelector = getSigHash(fragment) + }) + + it('Should return zero if hook is not registered', async () => { + expect(await wallet.mainModule.readHook(hookSelector)).to.be.equal(ethers.ZeroAddress) + }) + + describe('With registered hook', () => { + beforeEach(async () => { + const transaction = { + target: wallet.address, + data: wallet.mainModule.interface.encodeFunctionData('addHook', [hookSelector, await hookMock.getAddress()]) + } + + await wallet.sendTransactions([transaction]) + }) + + it('Should read added hook', async () => { + expect(await wallet.mainModule.readHook(hookSelector)).to.be.equal(await hookMock.getAddress()) + }) + + it('Should forward call to external hook', async () => { + const walletHook = HookMock.attach(wallet.address) + expect(await walletHook.onHookMockCall(21)).to.equal(42n) + }) + + it('Should not forward call to deregistered hook', async () => { + const transaction = { + target: wallet.address, + data: wallet.mainModule.interface.encodeFunctionData('removeHook', [hookSelector]) + } + + await wallet.sendTransactions([transaction]) + + const tx2 = HookMock.attach(wallet.address).onHookMockCall(21) + await expect(tx2).to.be.rejected + }) + + it('Should use hooks storage key', async () => { + const subkey = ethers.AbiCoder.defaultAbiCoder().encode(['bytes4'], [hookSelector]) + const storageKey = computeStorageKey('org.arcadeum.module.hooks.hooks', subkey) + + const storageValue = await hethers.provider.getStorage(wallet.address, storageKey) + + const addr = (() => { + try { + return ethers.getAddress(ethers.AbiCoder.defaultAbiCoder().decode(['address'], storageValue)[0]) + } catch { + return ethers.getAddress(storageValue) + } + })() + + expect(addr).to.equal(await hookMock.getAddress()) + }) + }) + + it('Should pass calling a non registered hook', async () => { + const data = ethers.AbiCoder.defaultAbiCoder().encode(['bytes4'], [hookSelector]) + const signer = await hethers.provider.getSigner() + await signer.sendTransaction({ to: wallet.address, data: data }) + }) + }) + + it('Should not forward msg.data with less than 4 bytes', async () => { + const alwaysRevertMock = await AlwaysRevertMock.deploy() + const paddedSelector = '0x11223300' + + const transaction = { + target: wallet.address, + data: wallet.mainModule.interface.encodeFunctionData('addHook', [paddedSelector, await alwaysRevertMock.getAddress()]) + } + + await wallet.sendTransactions([transaction]) + + const signer = await hethers.provider.getSigner() + + // Calling the wallet with '0x112233' should not forward the call to the hook + const tx = signer.sendTransaction({ to: wallet.address, data: '0x112233' }).then(t => t.wait()) + await expect(tx).to.be.fulfilled + + // Calling the wallet with '0x11223300' should forward the call to the hook (and thus revert) + const tx2 = signer.sendTransaction({ to: wallet.address, data: '0x11223300' }).then(t => t.wait()) + await expect(tx2).to.be.rejected + }) + + it('Should emit an event when adding a hook', async () => { + const selector = '0x2385ac0a' + const implementation = ethers.Wallet.createRandom().address + + const transaction = { + target: wallet.address, + data: wallet.mainModule.interface.encodeFunctionData('addHook', [selector, implementation]) + } + + const receipt = await wallet.sendTransactions([transaction]).then(t => t.wait()) + + if (!receipt) { + throw new Error('No receipt') + } + + const events = receipt.logs.filter(log => log instanceof ethers.EventLog) as ethers.EventLog[] + const event = events.find(ev => ev.eventName === 'DefinedHook') + expect(event).to.not.be.undefined + expect(event!.args._signature).to.equal(selector) + expect(event!.args._implementation).to.equal(implementation) + }) + + it('Should emit an event when removing a hook', async () => { + const selector = '0x2385ac0a' + const implementation = ethers.Wallet.createRandom().address + + const transaction1 = { + target: wallet.address, + data: wallet.mainModule.interface.encodeFunctionData('addHook', [selector, implementation]) + } + + await wallet.sendTransactions([transaction1]).then(t => t.wait()) + + const transaction2 = { + target: wallet.address, + data: wallet.mainModule.interface.encodeFunctionData('removeHook', [selector]) + } + + const receipt = await wallet.sendTransactions([transaction2]).then(t => t.wait()) + + if (!receipt) { + throw new Error('No receipt') + } + + const events = receipt.logs.filter(log => log instanceof ethers.EventLog) as ethers.EventLog[] + const event = events.find(ev => ev.eventName === 'DefinedHook') + expect(event).to.not.be.undefined + expect(event?.args._signature).to.equal(selector) + expect(event?.args._implementation).to.equal(ethers.ZeroAddress) + }) + }) + + describe('Update owners', async () => { + let walletb: SequenceWallet + + beforeEach(async () => { + walletb = SequenceWallet.basicWallet(context, { address: wallet.address }) + }) + + it('Should fail to update to invalid image hash', async () => { + const tx = wallet.updateImageHash(ethers.ZeroHash) + await expectToBeRejected(tx, 'ImageHashIsZero()') + }) + + it('Should fail to change image hash from non-self address', async () => { + const tx = wallet.mainModule.updateImageHash(ethers.randomBytes(32)) + await expectToBeRejected(tx, `OnlySelfAuth("${accounts[0]}", "${wallet.address}")`) + }) + + describe('After a migration', async () => { + beforeEach(async () => { + await wallet.updateImageHash(walletb.imageHash) + }) + + it('Should implement new upgradable module', async () => { + expect(await walletb.mainModuleUpgradable.imageHash()).to.equal(walletb.imageHash) + }) + + it('Should accept new owner signature', async () => { + await walletb.sendTransactions([{}]) + }) + + it('Should reject old owner signature', async () => { + const tx = wallet.sendTransactions([{}]) + await expect(tx).to.be.rejected + }) + + it('Should fail to update to invalid image hash', async () => { + const tx = walletb.updateImageHash(ethers.ZeroHash) + await expectToBeRejected(tx, 'ImageHashIsZero()') + }) + + it('Should fail to change image hash from non-self address', async () => { + const tx = wallet.mainModuleUpgradable.updateImageHash(ethers.randomBytes(32)) + await expectToBeRejected(tx, `OnlySelfAuth("${accounts[0]}", "${wallet.address}")`) + }) + + it('Should use image hash storage key', async () => { + const storageKey = computeStorageKey('org.arcadeum.module.auth.upgradable.image.hash') + const storageValue = await hethers.provider.getStorage(wallet.address, storageKey) + expect(ethers.AbiCoder.defaultAbiCoder().encode(['bytes32'], [storageValue])).to.equal(walletb.imageHash) + }) + + it('Should fail to execute transactions on moduleUpgradable implementation', async () => { + const tx = context.mainModuleUpgradable.execute([], 0, '0x0000') + await expect(tx).to.be.rejected + }) + + describe('After updating the image hash', () => { + let walletc: SequenceWallet + + beforeEach(async () => { + walletc = SequenceWallet.basicWallet(context, { signing: 2, address: walletb.address }) + await walletb.updateImageHash(walletc.imageHash) + }) + + it('Should have updated the image hash', async () => { + expect(await walletb.mainModuleUpgradable.imageHash()).to.equal(walletc.imageHash) + }) + + it('Should accept new owners signatures', async () => { + await walletc.sendTransactions([{}]) + }) + + it('Should reject old owner signatures', async () => { + const tx = walletb.sendTransactions([{}]) + await expect(tx).to.be.rejected + }) + + it('Should use image hash storage key', async () => { + const storageKey = computeStorageKey('org.arcadeum.module.auth.upgradable.image.hash') + const storageValue = await hethers.provider.getStorage(walletb.address, storageKey) + expect(ethers.AbiCoder.defaultAbiCoder().encode(['bytes32'], [storageValue])).to.equal(walletc.imageHash) + }) + }) + }) + }) + + describe('Multisignature', async () => { + const modes = [ + { + name: 'Forced dynamic part encoding, legacy signature type', + encodingOptions: { forceDynamicEncoding: true, signatureType: SignatureType.Legacy } + }, + { + name: 'Default part encoding, legacy signature encoding', + encodingOptions: { signatureType: SignatureType.Legacy } + }, + { + name: 'Forced dynamic part encoding, dynamic signature type', + encodingOptions: { forceDynamicEncoding: true, signatureType: SignatureType.Dynamic } + }, + { + name: 'Default part encoding, dynamic signature type', + encodingOptions: { signatureType: SignatureType.Legacy } + } + ] + + modes.map(mode => { + describe(mode.name, () => { + let encodingOptions = mode.encodingOptions + + describe('With 1/2 wallet', () => { + let signer1 = ethers.Wallet.createRandom() + let signer2 = ethers.Wallet.createRandom() + + beforeEach(async () => { + wallet = SequenceWallet.detailedWallet(context, { threshold: 1, signers: [signer1, signer2], encodingOptions }) + await wallet.deploy() + }) + + it('Should accept signed message by first owner', async () => { + await wallet.useSigners(signer1).sendTransactions([{}]) + }) + + it('Should accept signed message by second owner', async () => { + await wallet.useSigners(signer2).sendTransactions([{}]) + }) + + it('Should accept signed message by both owners', async () => { + await wallet.useSigners([signer1, signer2]).sendTransactions([{}]) + }) + + it('Should reject message without signatures', async () => { + const tx = wallet.useSigners([]).sendTransactions([{}]) + await expect(tx).to.be.rejected + }) + + it('Should reject message signed by non-owner', async () => { + const tx = wallet.useSigners(Imposter.random(signer1)).sendTransactions([{}]) + await expect(tx).to.be.rejected + }) + + it('Should reject message signed by non-owner and signer2', async () => { + const tx = wallet.useSigners([signer2, Imposter.random(signer1)]).sendTransactions([{}]) + await expect(tx).to.be.rejected + }) + + it('Should reject signature of invalid length', async () => { + const signature = await wallet.signTransactions([{}]) + const badSignature = signature.slice(0, -2) + const tx = wallet.relayTransactions([{}], badSignature) + await expect(tx).to.be.rejected + }) + }) + + describe('With 2/2 wallet', () => { + let signer1 = ethers.Wallet.createRandom() + let signer2 = ethers.Wallet.createRandom() + + beforeEach(async () => { + wallet = SequenceWallet.detailedWallet(context, { threshold: 2, signers: [signer1, signer2], encodingOptions }) + await wallet.deploy() + }) + + it('Should accept signed message by both owners', async () => { + await wallet.sendTransactions([{}]) + }) + + it('Should reject message without signatures', async () => { + const tx = wallet.useSigners([]).sendTransactions([{}]) + await expect(tx).to.be.rejected + }) + + it('Should reject message signed only by first owner', async () => { + const tx = wallet.useSigners(signer1).sendTransactions([{}]) + await expect(tx).to.be.rejected + }) + + it('Should reject message signed only by second owner', async () => { + const tx = wallet.useSigners(signer2).sendTransactions([{}]) + await expect(tx).to.be.rejected + }) + + it('Should reject message signed by non-owner', async () => { + const tx = wallet.useSigners(Imposter.random(signer1)).sendTransactions([{}]) + await expect(tx).to.be.rejected + }) + }) + + describe('With 2/3 wallet', () => { + let signer1 = ethers.Wallet.createRandom() + let signer2 = ethers.Wallet.createRandom() + let signer3 = ethers.Wallet.createRandom() + + beforeEach(async () => { + wallet = SequenceWallet.detailedWallet(context, { + threshold: 2, + signers: [signer1, signer2, signer3], + encodingOptions + }) + await wallet.deploy() + }) + + it('Should accept signed message by first and second owner', async () => { + await wallet.useSigners([signer1, signer2]).sendTransactions([{}]) + }) + + it('Should accept signed message by first and last owner', async () => { + await wallet.useSigners([signer1, signer3]).sendTransactions([{}]) + }) + + it('Should accept signed message by second and last owner', async () => { + await wallet.useSigners([signer2, signer3]).sendTransactions([{}]) + }) + + it('Should accept signed message by all owners', async () => { + await wallet.useSigners([signer1, signer2, signer3]).sendTransactions([{}]) + }) + + it('Should reject message signed only by first owner', async () => { + const tx = wallet.useSigners(signer1).sendTransactions([{}]) + await expect(tx).to.be.rejected + }) + + it('Should reject message signed only by second owner', async () => { + const tx = wallet.useSigners(signer2).sendTransactions([{}]) + await expect(tx).to.be.rejected + }) + + it('Should reject message signed only by last owner', async () => { + const tx = wallet.useSigners(signer3).sendTransactions([{}]) + await expect(tx).to.be.rejected + }) + + it('Should reject message not signed', async () => { + const tx = wallet.useSigners([]).sendTransactions([{}]) + await expect(tx).to.be.rejected + }) + + it('Should reject message signed by non-owner', async () => { + const tx = wallet.useSigners(Imposter.random(signer1)).sendTransactions([{}]) + await expect(tx).to.be.rejected + }) + + it('Should reject message signed by non-owner and signer1', async () => { + const tx = wallet.useSigners([signer1, Imposter.random(signer2)]).sendTransactions([{}]) + await expect(tx).to.be.rejected + }) + + it('Should reject message signed by two non-owners', async () => { + const tx = wallet.useSigners([Imposter.random(signer1), Imposter.random(signer2)]).sendTransactions([{}]) + await expect(tx).to.be.rejected + }) + + it('Should reject message if signed with a wrong configuration', async () => { + const tx = wallet + .useConfig(SequenceWallet.detailedWallet(context, { threshold: 3, signers: [signer1, signer2] })) + .sendTransactions([{}]) + await expect(tx).to.be.rejected + }) + }) + + describe('With 3/10 wallet', () => { + beforeEach(async () => { + wallet = SequenceWallet.basicWallet(context, { signing: 3, idle: 7 }) + await wallet.deploy() + }) + + it('Should accept message signed by 3/10 owners', async () => { + await wallet.sendTransactions([{}]) + }) + }) + + describe('With 255/255 wallet', () => { + beforeEach(async () => { + wallet = SequenceWallet.basicWallet(context, { signing: 215, encodingOptions }) + await wallet.deploy() + }) + + it('Should accept message signed by all owners', async () => { + await wallet.sendTransactions([{}], undefined, { gasLimit: 60000000 }) + }) + + it('Should reject message signed by non-owner', async () => { + const tx = wallet + .useSigners([Imposter.random(wallet.signers[0] as ethers.Wallet), ...wallet.signers.slice(1)]) + .sendTransactions([{}], undefined, { gasLimit: 60000000 }) + + await expect(tx).to.be.rejected + }) + + it('Should reject message signed by all non-owners', async () => { + const tx = wallet + .useSigners(wallet.signers.map(s => Imposter.random(s as ethers.Wallet))) + .sendTransactions([{}], undefined, { gasLimit: 60000000 }) + + await expect(tx).to.be.rejected + }) + + it('Should reject message missing a signature', async () => { + const tx = wallet.useSigners(wallet.signers.slice(1)).sendTransactions([{}], undefined, { gasLimit: 60000000 }) + await expect(tx).to.be.rejected + }) + }) + + describe('With weighted owners', () => { + let signers: ethers.BaseWallet[] + + beforeEach(async () => { + signers = new Array(5).fill(null).map(() => ethers.Wallet.createRandom()) + wallet = SequenceWallet.detailedWallet(context, { + threshold: 4, + signers: [3, 3, 1, 1, 1].map((weight, i) => ({ weight, value: signers[i] })) + }) + await wallet.deploy() + }) + + it('Should accept signed message with (3+1)/4 weight', async () => { + await wallet.useSigners([signers[0], signers[3]]).sendTransactions([{}]) + }) + + it('Should accept signed message with (3+3)/4 weight', async () => { + await wallet.useSigners([signers[0], signers[1]]).sendTransactions([{}]) + }) + + it('Should accept signed message with (3+3+1+1)/4 weight', async () => { + await wallet.useSigners(signers.slice(0, 4)).sendTransactions([{}]) + }) + + it('Should accept signed message with (3+3+1+1+1)/4 weight (all signers)', async () => { + await wallet.useSigners(signers).sendTransactions([{}]) + }) + + it('Should reject signed message with (1)/4 weight', async () => { + const tx = wallet.useSigners([signers[3]]).sendTransactions([{}]) + await expect(tx).to.be.rejected + }) + + it('Should reject signed message with (1+1)/4 weight', async () => { + const tx = wallet.useSigners([signers[2], signers[3]]).sendTransactions([{}]) + await expect(tx).to.be.rejected + }) + + it('Should reject signed message with (1+1+1)/4 weight', async () => { + const tx = wallet.useSigners([signers[2], signers[3], signers[4]]).sendTransactions([{}]) + await expect(tx).to.be.rejected + }) + + it('Should reject signed message with (3)/4 weight', async () => { + const tx = wallet.useSigners(signers[0]).sendTransactions([{}]) + await expect(tx).to.be.rejected + }) + + it('Should reject signed message with (0)/4 weight', async () => { + const tx = wallet.useSigners([]).sendTransactions([{}]) + await expect(tx).to.be.rejected + }) + + it('Should reject message signed by non-owner', async () => { + const tx = wallet.useSigners([signers[0], Imposter.random(signers[3])]).sendTransactions([{}]) + await expect(tx).to.be.rejected + }) + + describe('Reject invalid signatures', () => { + beforeEach(async () => { + wallet = SequenceWallet.basicWallet(context, { encodingOptions }) + await wallet.deploy() + }) + + it('Should reject invalid signature type', async () => { + const signature = await wallet.signTransactions([{}]) + const badSignature = signature.slice(0, -2) + 'ff' + const tx = wallet.relayTransactions([{}], badSignature) + await expect(tx).to.be.rejected + }) + + it('Should reject invalid s value', async () => { + const signature = await wallet.signTransactions([{}]) + const prefix = mode.encodingOptions.forceDynamicEncoding ? 118 : 74 + const invalidSignature = + signature.slice(0, prefix) + + '7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a1' + + signature.slice(prefix + 64) + const tx = wallet.relayTransactions([{}], invalidSignature) + await expect(tx).to.be.reverted + }) + + it('Should reject invalid v value', async () => { + const signature = await wallet.signTransactions([{}]) + const prefix = mode.encodingOptions.forceDynamicEncoding ? 182 : 138 + const invalidSignature = signature.slice(0, prefix) + '1a' + signature.slice(prefix + 2) + const tx = wallet.relayTransactions([{}], invalidSignature) + await expect(tx).to.be.reverted + }) + }) + }) + }) + }) + }) + + describe('Gas limit', () => { + let gasBurner: ContractType + + before(async () => { + gasBurner = await GasBurnerMock.deploy() + }) + + it('Should forward the defined amount of gas', async () => { + const gas = 10000 + + const transaction = { + gasLimit: gas, + target: await gasBurner.getAddress(), + data: gasBurner.interface.encodeFunctionData('burnGas', [0]) + } + + const receipt = await wallet.sendTransactions([transaction]).then(t => t.wait()) + + if (!receipt) { + throw new Error('No receipt') + } + + const reported = Number(BigInt(receipt.logs.slice(-2)[0].data)) + expect(reported).to.be.below(gas) + }) + + it('Should forward different amounts of gas', async () => { + const gasA = 10000 + const gasB = 350000 + + const transactions = [ + { + gasLimit: gasA, + target: await gasBurner.getAddress(), + data: gasBurner.interface.encodeFunctionData('burnGas', [8000]) + }, + { + gasLimit: gasB, + target: await gasBurner.getAddress(), + data: gasBurner.interface.encodeFunctionData('burnGas', [340000]) + } + ] + + const receipt = await wallet.sendTransactions(transactions).then(t => t.wait()) + + if (!receipt) { + throw new Error('No receipt') + } + + const reportedB = Number(BigInt(receipt.logs.slice(-2)[0].data)) + const reportedA = Number(BigInt(receipt.logs.slice(-4)[0].data)) + + expect(reportedA).to.be.below(gasA) + expect(reportedB).to.be.below(gasB) + expect(reportedB).to.be.above(gasA) + }) + + it('Should fail if forwarded call runs out of gas', async () => { + const gas = 10000 + + const transaction = { + gasLimit: gas, + target: await gasBurner.getAddress(), + data: gasBurner.interface.encodeFunctionData('burnGas', [11000]) + } + + const tx = wallet.sendTransactions([transaction]) + expect(tx).to.be.rejected + }) + + it('Should fail without reverting if optional call runs out of gas', async () => { + const gas = 10000 + + const transaction = { + revertOnError: false, + gasLimit: gas, + target: await gasBurner.getAddress(), + data: gasBurner.interface.encodeFunctionData('burnGas', [200000]) + } + + const receipt = await wallet.sendTransactions([transaction]).then(t => t.wait()) + + if (!receipt) { + throw new Error('No receipt') + } + const events = receipt.logs.filter(log => log instanceof ethers.EventLog) as ethers.EventLog[] + + const log = events.pop() + expect(log!.eventName).to.be.equal('TxFailed') + }) + + it('Should continue execution if optional call runs out of gas', async () => { + const gas = 10000 + + const valA = 9512358833n + const valB = randomHex(1600) + + const transactions = [ + { + revertOnError: false, + gasLimit: gas, + target: await gasBurner.getAddress(), + data: gasBurner.interface.encodeFunctionData('burnGas', [200000]) + }, + { + revertOnError: true, + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [valA, valB]) + } + ] + + const receipt = await wallet.sendTransactions(transactions).then(t => t.wait()) + + if (!receipt) { + throw new Error('No receipt') + } + + const events = receipt.logs.filter(log => log instanceof ethers.EventLog) as ethers.EventLog[] + + const log = events.slice(-2)[0] + + expect(log.eventName).to.be.equal('TxFailed') + expect(await callReceiver.lastValA()).to.equal(valA) + expect(await callReceiver.lastValB()).to.equal(valB) + }) + + it('Should fail if transaction is executed with not enough gas', async () => { + const transaction = { + gasLimit: 1000000 + } + + const tx = wallet.sendTransactions([transaction], undefined, { gasLimit: 250000 }) + await expect(tx).to.be.rejected + }) + }) + + describe('Create contracts', () => { + it('Should create a contract', async () => { + const deployCode = CallReceiverMock.factory().bytecode + + const transaction = { + target: wallet.address, + data: wallet.mainModule.interface.encodeFunctionData('createContract', [deployCode]) + } + + const receipt = await wallet.sendTransactions([transaction]).then(t => t.wait()) + + if (!receipt) { + throw new Error('No receipt') + } + + const events = receipt.logs.filter(log => log instanceof ethers.EventLog) as ethers.EventLog[] + + const log = events!.find(l => l.eventName === 'CreatedContract') + + expect(log!.eventName).to.equal('CreatedContract') + + const deployed = CallReceiverMock.attach(log!.args!._contract) + await deployed.testCall(12345, '0x552299') + + expect(await deployed.lastValA()).to.equal(12345n) + expect(await deployed.lastValB()).to.equal('0x552299') + }) + + it('Should create a contract with value', async () => { + const deployCode = CallReceiverMock.factory().bytecode + + const signer = await hethers.provider.getSigner() + await signer.sendTransaction({ to: wallet.address, value: 100 }) + + const transaction = { + target: wallet.address, + value: 99, + data: wallet.mainModule.interface.encodeFunctionData('createContract', [deployCode]) + } + + const receipt = await wallet.sendTransactions([transaction]).then(t => t.wait()) + + if (!receipt) { + throw new Error('No receipt') + } + + const events = receipt.logs.filter(log => log instanceof ethers.EventLog) as ethers.EventLog[] + + const log = events!.find(l => l.eventName === 'CreatedContract') + + expect(await hethers.provider.getBalance(log!.args!._contract)).to.equal(99n) + }) + + it('Should fail to create a contract from non-self', async () => { + const tx = wallet.mainModule.createContract(CallReceiverMock.factory().bytecode) + await expectToBeRejected(tx, `OnlySelfAuth("${accounts[0]}", "${wallet.address}")`) + }) + }) + + describe('Transaction events', () => { + it('Should emit TxExecuted event', async () => { + const txHash = await subdigestOf(wallet.address, digestOf([{}], await wallet.getNonce())) + const res = await wallet.sendTransactions([{}]) + const receipt = await res.wait() + + if (!receipt) { + throw new Error('No receipt') + } + + const events = receipt.logs.filter(log => log instanceof ethers.EventLog) as ethers.EventLog[] + + const log = events!.find(l => l.eventName === 'TxExecuted')! + + expect(log.topics.length).to.equal(2) + expect(log.topics[1]).to.be.equal(txHash) + expect(log.data).to.be.equal(ethers.solidityPacked(['uint256'], [0])) + }) + + it('Should emit multiple TxExecuted events', async () => { + const txHash = await subdigestOf(wallet.address, digestOf([{}, {}], await wallet.getNonce())) + const receipt = await wallet.sendTransactions([{}, {}]).then(t => t.wait()) + + if (!receipt) { + throw new Error('No receipt') + } + + const log1 = receipt.logs[1] + const log2 = receipt.logs[2] + + expect(log1.topics.length).to.equal(2) + expect(log1.topics[1]).to.be.equal(txHash) + expect(log1.data).to.be.equal(ethers.solidityPacked(['uint256'], [0])) + + expect(log2.topics.length).to.equal(2) + expect(log1.topics[1]).to.be.equal(txHash) + expect(log2.data).to.be.equal(ethers.solidityPacked(['uint256'], [1])) + }) + }) + + describe('Internal bundles', () => { + it('Should execute internal bundle', async () => { + const callReceiver2 = await CallReceiverMock.deploy() + + const expected1 = randomHex(552) + const expected2 = randomHex(24) + + const bundle = [ + { + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [11, expected1]) + }, + { + target: await callReceiver2.getAddress(), + data: callReceiver2.interface.encodeFunctionData('testCall', [12, expected2]) + } + ] + + const transaction = [ + { + target: wallet.address, + data: wallet.mainModule.interface.encodeFunctionData('selfExecute', [applyTxDefaults(bundle)]) + } + ] + + await wallet.sendTransactions(transaction) + + expect(await callReceiver.lastValA()).to.equal(11n) + expect(await callReceiver2.lastValA()).to.equal(12n) + + expect(await callReceiver.lastValB()).to.equal(expected1) + expect(await callReceiver2.lastValB()).to.equal(expected2) + }) + + it('Should execute multiple internal bundles', async () => { + const data = [ + [ + { i: 0, a: 142n, b: 412 }, + { i: 1, a: 123n, b: 2 } + ], + [ + { i: 2, a: 142n, b: 2 }, + { i: 3, a: 642n, b: 33 }, + { i: 4, a: 122n, b: 12 }, + { i: 5, a: 611n, b: 53 } + ], + [{ i: 6, a: 2n, b: 1 }], + [] + ] + + const contracts = await Promise.all(data.flat().map(() => CallReceiverMock.deploy())) + const expectedb = await Promise.all(data.flat().map(d => randomHex(d.b))) + + const bundles = await Promise.all( + data.map(async bundle => { + return applyTxDefaults( + await Promise.all( + bundle.map(async obj => ({ + target: await contracts[obj.i].getAddress(), + data: contracts[obj.i].interface.encodeFunctionData('testCall', [obj.a, expectedb[obj.i]]) + })) + ) + ) + }) + ) + + const transactions = bundles.map(bundle => ({ + target: wallet.address, + data: wallet.mainModule.interface.encodeFunctionData('selfExecute', [bundle]) + })) + + await wallet.sendTransactions(transactions) + + const lastValsA = await Promise.all(contracts.map(c => c.lastValA())) + const lastValsB = await Promise.all(contracts.map(c => c.lastValB())) + + lastValsA.forEach((val, i) => expect(val).to.equal(data.flat()[i].a)) + lastValsB.forEach((val, i) => expect(val).to.equal(expectedb[i])) + }) + + it('Should execute nested internal bundles', async () => { + const callReceiver2 = await CallReceiverMock.deploy() + + const expected1 = randomHex(552) + const expected2 = randomHex(24) + + const bundle = [ + { + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [11, expected1]) + }, + { + target: await callReceiver2.getAddress(), + data: callReceiver2.interface.encodeFunctionData('testCall', [12, expected2]) + } + ] + + const nestedBundle = [ + { + target: wallet.address, + data: wallet.mainModule.interface.encodeFunctionData('selfExecute', [applyTxDefaults(bundle)]) + } + ] + + const transactions = [ + { + target: wallet.address, + data: wallet.mainModule.interface.encodeFunctionData('selfExecute', [applyTxDefaults(nestedBundle)]) + } + ] + + await wallet.sendTransactions(transactions) + + expect(await callReceiver.lastValA()).to.equal(11n) + expect(await callReceiver2.lastValA()).to.equal(12n) + + expect(await callReceiver.lastValB()).to.equal(expected1) + expect(await callReceiver2.lastValB()).to.equal(expected2) + }) + + it('Should revert bundle without reverting transaction', async () => { + const callReceiver2 = await CallReceiverMock.deploy() + const callReceiver3 = await CallReceiverMock.deploy() + + const expected1 = randomHex(552) + const expected2 = randomHex(24) + const expected3 = randomHex(11) + + const bundle = [ + { + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [11, expected1]) + }, + { + target: await callReceiver2.getAddress(), + data: callReceiver2.interface.encodeFunctionData('testCall', [12, expected2]) + }, + { + // This transaction will revert + // because Factory has no fallback + revertOnError: true, + target: await context.factory.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [12, expected2]) + } + ] + + const transaction = [ + { + revertOnError: false, + target: wallet.address, + data: wallet.mainModule.interface.encodeFunctionData('selfExecute', [applyTxDefaults(bundle)]) + }, + { + revertOnError: false, + target: await callReceiver3.getAddress(), + data: callReceiver3.interface.encodeFunctionData('testCall', [51, expected3]) + } + ] + + await wallet.sendTransactions(transaction) + + expect(await callReceiver.lastValA()).to.equal(0n) + expect(await callReceiver2.lastValA()).to.equal(0n) + expect(await callReceiver3.lastValA()).to.equal(51n) + + expect(await callReceiver.lastValB()).to.equal('0x') + expect(await callReceiver2.lastValB()).to.equal('0x') + expect(await callReceiver3.lastValB()).to.equal(expected3) + }) + }) + + describe('Update imageHash and IPFS at once', () => { + ;[ + { + name: 'using MainModule', + beforeEach: () => {} + }, + { + name: 'using MainModuleUpgradable', + beforeEach: async () => { + const newConfig = SequenceWallet.basicWallet(context) + await wallet.updateImageHash(newConfig.imageHash) + wallet = wallet.useAddress().useConfig(newConfig.config).useSigners(newConfig.signers) + } + } + ].map(c => { + describe(c.name, () => { + it('Should update imageHash and IPFS at the same time', async () => { + const ipfs = randomHex(32) + const imageHash = randomHex(32) + + await wallet.sendTransactions([ + { + target: wallet.address, + data: wallet.mainModule.interface.encodeFunctionData('updateImageHashAndIPFS', [imageHash, ipfs]) + } + ]) + + expect(await wallet.mainModuleUpgradable.imageHash()).to.equal(imageHash) + expect(await wallet.mainModule.ipfsRootBytes32()).to.equal(ipfs) + }) + + it('Should fail to update imageHash and IPFS if caller is not self', async () => { + const tx = wallet.mainModule.updateImageHashAndIPFS(randomHex(32), randomHex(32)) + await expectToBeRejected(tx, 'OnlySelf') + }) + + it('Updated imageHash should be usable', async () => { + const nextWallet = SequenceWallet.basicWallet(context) + const ipfs = randomHex(32) + + await wallet.sendTransactions([ + { + target: wallet.address, + data: wallet.mainModule.interface.encodeFunctionData('updateImageHashAndIPFS', [nextWallet.imageHash, ipfs]) + } + ]) + + wallet = wallet.useAddress(wallet.address).useConfig(nextWallet.config).useSigners(nextWallet.signers) + await wallet.sendTransactions([{}]) + }) + }) + }) + }) +}) diff --git a/packages/wallet/wallet-contracts/test/MerkleSignatures.spec.ts b/packages/wallet/wallet-contracts/test/MerkleSignatures.spec.ts new file mode 100644 index 0000000000..bbcc2f8768 --- /dev/null +++ b/packages/wallet/wallet-contracts/test/MerkleSignatures.spec.ts @@ -0,0 +1,30 @@ +import { ethers } from 'ethers' +import { deploySequenceContext, SequenceContext } from './utils/contracts' +import { legacyTopology, merkleTopology, printTopology, toSimplifiedConfig } from './utils/sequence' +import { SequenceWallet } from './utils/wallet' + +contract('MerkleSignatures', () => { + let context: SequenceContext + + before(async () => { + context = await deploySequenceContext() + }) + + it('Should display config topology', async () => { + const wallet = SequenceWallet.basicWallet(context, { signing: 10 }) + const simplifiedConfig = toSimplifiedConfig(wallet.config) + const topology1 = legacyTopology(simplifiedConfig) + const topology2 = merkleTopology(simplifiedConfig) + + console.log(`Legacy topology:`) + const t = printTopology(topology1, undefined, true) + for (const line of t) { + console.log(line) + } + + const t2 = printTopology(topology2) + for (const line of t2) { + console.log(line) + } + }) +}) diff --git a/packages/wallet/wallet-contracts/test/MultiCallUtils.spec.ts b/packages/wallet/wallet-contracts/test/MultiCallUtils.spec.ts new file mode 100644 index 0000000000..085e7b789f --- /dev/null +++ b/packages/wallet/wallet-contracts/test/MultiCallUtils.spec.ts @@ -0,0 +1,282 @@ +import { ethers } from 'ethers' + +import { ethers as hethers } from 'hardhat' +import { getChainId, encodeError, expect, expectStaticToBeRejected } from './utils' +import { CallReceiverMock, ContractType, MultiCallUtils } from './utils/contracts' +import { applyTxDefault, applyTxDefaults } from './utils/sequence' + +contract('Multi call utils', (accounts: string[]) => { + let multiCall: ContractType + let callReceiver: ContractType + + before(async () => { + multiCall = await MultiCallUtils.deploy() + callReceiver = await CallReceiverMock.deploy() + }) + + beforeEach(async () => { + await callReceiver.setRevertFlag(false) + }) + + describe('Call multiple contracts', () => { + it('Should execute empty call', async () => { + const res = await multiCall.multiCall.staticCall([]) + + expect(res[0].length).to.equal(0) + expect(res[1].length).to.equal(0) + }) + it('Should execute single call', async () => { + await callReceiver.testCall(5123, new Uint8Array([])) + const res = await multiCall.multiCall.staticCall( + applyTxDefaults([ + { + revertOnError: false, + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('lastValA') + } + ]) + ) + + expect(res[0].length).to.equal(1) + expect(res[1].length).to.equal(1) + expect(res[0][0]).to.be.true + expect(res[1][0]).to.be.equal(ethers.AbiCoder.defaultAbiCoder().encode(['uint256'], [5123])) + }) + it('Should execute two calls', async () => { + const bytes = ethers.randomBytes(422) + + await callReceiver.testCall(55522, bytes) + const res = await multiCall.multiCall.staticCall( + applyTxDefaults([ + { + revertOnError: false, + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('lastValA') + }, + { + revertOnError: false, + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('lastValB') + } + ]) + ) + + expect(res[0].length).to.equal(2) + expect(res[1].length).to.equal(2) + expect(res[0][0]).to.be.true + expect(res[1][0]).to.be.equal(ethers.AbiCoder.defaultAbiCoder().encode(['uint256'], [55522])) + expect(res[0][1]).to.be.true + expect(ethers.AbiCoder.defaultAbiCoder().decode(['bytes'], res[1][1])[0]).to.be.equal(ethers.hexlify(bytes)) + }) + it('Should execute calls to multiple contracts', async () => { + const callReceiver2 = await CallReceiverMock.deploy() + const bytes = ethers.hexlify(ethers.randomBytes(21)) + + await callReceiver.testCall(55522, bytes) + await callReceiver2.testCall(66623, new Uint8Array([])) + + const res = await multiCall.multiCall.staticCall( + applyTxDefaults([ + { + revertOnError: false, + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('lastValA') + }, + { + revertOnError: false, + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('lastValB') + }, + { + revertOnError: false, + target: await callReceiver2.getAddress(), + data: callReceiver2.interface.encodeFunctionData('lastValA') + } + ]) + ) + + expect(res[0].length).to.equal(3) + expect(res[1].length).to.equal(3) + expect(res[0][0]).to.be.true + expect(res[1][0]).to.be.equal(ethers.AbiCoder.defaultAbiCoder().encode(['uint256'], [55522])) + expect(res[0][1]).to.be.true + expect(ethers.AbiCoder.defaultAbiCoder().decode(['bytes'], res[1][1])[0]).to.be.equal(bytes) + expect(res[0][2]).to.be.true + expect(res[1][2]).to.be.equal(ethers.AbiCoder.defaultAbiCoder().encode(['uint256'], [66623])) + }) + it('Return other calls even if single call fails', async () => { + const bytes = ethers.randomBytes(422) + + await callReceiver.testCall(55522, bytes) + await callReceiver.setRevertFlag(true) + + const res = await multiCall.multiCall.staticCall( + applyTxDefaults([ + { + revertOnError: false, + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('lastValA') + }, + { + revertOnError: false, + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [111, bytes]) + } + ]) + ) + + expect(res[0].length).to.equal(2) + expect(res[1].length).to.equal(2) + expect(res[0][0]).to.be.true + expect(res[1][0]).to.be.equal(ethers.AbiCoder.defaultAbiCoder().encode(['uint256'], [55522])) + expect(res[0][1]).to.be.false + }) + it('Fail if call with revert on error fails', async () => { + const bytes = ethers.randomBytes(422) + + await callReceiver.testCall(55522, bytes) + await callReceiver.setRevertFlag(true) + + const tx = multiCall.multiCall.staticCall( + applyTxDefaults([ + { + revertOnError: false, + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('lastValA') + }, + { + revertOnError: true, + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [111, bytes]) + } + ]) + ) + + await expectStaticToBeRejected(tx, `CallReverted(uint256,bytes)`, 1, encodeError('CallReceiverMock#testCall: REVERT_FLAG')) + }) + it('Fail if batch includes delegate call', async () => { + const bytes = ethers.randomBytes(422) + + await callReceiver.testCall(55522, bytes) + + const tx = multiCall.multiCall.staticCall( + applyTxDefaults([ + { + delegateCall: true, + revertOnError: false, + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('lastValA') + }, + { + revertOnError: false, + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [111, bytes]) + } + ]) + ) + + await expectStaticToBeRejected(tx, `DelegateCallNotAllowed(uint256)`, 0) + }) + it('Fail if not enough gas for call', async () => { + const bytes = ethers.randomBytes(422) + + await callReceiver.testCall(55522, bytes) + + const tx = multiCall.multiCall.staticCall( + applyTxDefaults([ + { + revertOnError: false, + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('lastValA') + }, + { + revertOnError: false, + target: await callReceiver.getAddress(), + data: callReceiver.interface.encodeFunctionData('testCall', [111, bytes]), + gasLimit: 2n ** 256n - 1n + } + ]) + ) + + await expectStaticToBeRejected(tx, `NotEnoughGas(uint256,uint256,uint256)`, 1, 2n ** 256n - 1n, '*') + }) + it('Should call globals', async () => { + const i = multiCall.interface + const emptyAccount = ethers.Wallet.createRandom().address + + await multiCall.multiCall.staticCall([]) + + const lastBlock = await hethers.provider.getBlock('latest') + + const txs = await Promise.all( + [ + i.encodeFunctionData('callBlockhash', [lastBlock!.number - 1]), + i.encodeFunctionData('callCoinbase'), + i.encodeFunctionData('callDifficulty'), + i.encodeFunctionData('callGasLimit'), + i.encodeFunctionData('callBlockNumber'), + i.encodeFunctionData('callTimestamp'), + i.encodeFunctionData('callGasLeft'), + i.encodeFunctionData('callGasPrice'), + i.encodeFunctionData('callOrigin'), + i.encodeFunctionData('callBalanceOf', [accounts[0]]), + i.encodeFunctionData('callBalanceOf', [emptyAccount]), + i.encodeFunctionData('callCodeSize', [accounts[0]]), + i.encodeFunctionData('callCodeSize', [await callReceiver.getAddress()]), + i.encodeFunctionData('callCode', [accounts[0]]), + i.encodeFunctionData('callCode', [await callReceiver.getAddress()]), + i.encodeFunctionData('callCodeHash', [accounts[0]]), + i.encodeFunctionData('callCodeHash', [await callReceiver.getAddress()]), + i.encodeFunctionData('callChainId') + ].map(async data => + applyTxDefault({ + revertOnError: false, + target: await multiCall.getAddress(), + data + }) + ) + ) + + const res = await multiCall.multiCall.staticCall(txs, { gasPrice: 1 }) + + const emptyBytes32 = ethers.AbiCoder.defaultAbiCoder().encode(['uint256'], ['0']) + + expect(res[0].length).to.equal(txs.length) + expect(res[1].length).to.equal(txs.length) + + // All calls must success + expect(res[0].reduce((a: boolean, c: boolean) => a && c)).to.be.true + + expect(res[1][0]).to.not.equal(emptyBytes32, 'return block hash') + + if (!process.env.COVERAGE) { + expect(res[1][1]).to.not.equal(emptyBytes32, 'return coinbase') + expect(res[1][2]).to.not.equal(emptyBytes32, 'return difficulty') + } + + expect(res[1][3]).to.not.equal(emptyBytes32) + expect(res[1][4]).to.not.equal(emptyBytes32, 'return block number') + expect(res[1][5]).to.not.equal(emptyBytes32, 'return timestamp') + expect(res[1][6]).to.not.equal(emptyBytes32, 'return gas left') + expect(BigInt(res[1][7])).to.equal(1n, 'return gas price') + expect(res[1][8]).to.not.equal(emptyBytes32, 'return origin') + expect(res[1][9]).to.not.equal(emptyBytes32, 'return balance of 0x') + expect(res[1][10]).to.equal(emptyBytes32, 'return balance of empty account') + expect(res[1][11]).to.equal(emptyBytes32, 'return code size of empty account') + expect(res[1][12]).to.not.equal(emptyBytes32, 'return code size of contract') + + expect(ethers.AbiCoder.defaultAbiCoder().decode(['bytes'], res[1][13])[0]).to.equal('0x') + + const codeSize = ethers.AbiCoder.defaultAbiCoder().decode(['uint256'], res[1][12])[0] + expect(ethers.AbiCoder.defaultAbiCoder().decode(['bytes'], res[1][14])[0].length).to.equal( + 2 + Number(codeSize) * 2, + 'return code of correct size' + ) + + expect(res[1][15]).to.not.equal(emptyBytes32) + expect(res[1][16]).to.not.equal(emptyBytes32) + + expect(ethers.AbiCoder.defaultAbiCoder().decode(['uint256'], res[1][17])[0]).to.equal(await getChainId(), 'return chain id') + }) + }) +}) diff --git a/packages/wallet/wallet-contracts/test/utils/contracts.ts b/packages/wallet/wallet-contracts/test/utils/contracts.ts new file mode 100644 index 0000000000..c2d6561b6e --- /dev/null +++ b/packages/wallet/wallet-contracts/test/utils/contracts.ts @@ -0,0 +1,87 @@ +import { ethers } from 'ethers' +import { ethers as hethers } from 'hardhat' +import * as t from '../../gen/typechain' + +const cachedFactories: { [name: string]: ethers.ContractFactory } = {} + +async function deploy(name: string, ...args: any[]) { + const factory = await hethers.getContractFactory(name) + cachedFactories[name] = factory + return (await factory.deploy(...args)) as unknown as Y +} + +function attach(name: string, address: string) { + return cachedFactories[name].attach(address) as Y +} + +type Adapter = { + cache: () => Promise + deploy: (...args: any[]) => Promise + attach: (address: string) => T + factory: () => ethers.ContractFactory +} + +function adapt(name: string): Adapter { + return { + cache: async () => (cachedFactories[name] = await hethers.getContractFactory(name)), + deploy: (...args: any[]) => deploy(name, ...args), + attach: (address: string) => attach(name, address), + factory: () => cachedFactories[name] + } +} + +export type ContractType> = T extends Adapter ? U : never + +export const LibBytesImpl = adapt('LibBytesImpl') +export const LibBytesPointerImpl = adapt('LibBytesPointerImpl') +export const Factory = adapt('Factory') +export const MainModule = adapt('MainModule') +export const MainModuleUpgradable = adapt('MainModuleUpgradable') +export const ERC165CheckerMock = adapt('ERC165CheckerMock') +export const ModuleMock = adapt('ModuleMock') +export const CallReceiverMock = adapt('CallReceiverMock') +export const MultiCallUtils = adapt('MultiCallUtils') +export const GuestModule = adapt('GuestModule') +export const HookMock = adapt('HookMock') +export const HookCallerMock = adapt('HookCallerMock') +export const RequireUtils = adapt('RequireUtils') +export const DelegateCallMock = adapt('DelegateCallMock') +export const GasBurnerMock = adapt('GasBurnerMock') +export const GasEstimator = adapt('GasEstimator') +export const MainModuleGasEstimation = adapt('MainModuleGasEstimation') +export const LibStringImp = adapt('LibStringImp') +export const AlwaysRevertMock = adapt('AlwaysRevertMock') +;[ + LibBytesImpl, + Factory, + MainModule, + MainModuleUpgradable, + ERC165CheckerMock, + ModuleMock, + CallReceiverMock, + MultiCallUtils, + GuestModule, + HookMock, + HookCallerMock, + RequireUtils, + DelegateCallMock, + GasEstimator +].map(c => c.cache()) + +export const deploySequenceContext = async (owner?: string) => { + const factory = await Factory.deploy() + const mainModuleUpgradable = await MainModuleUpgradable.deploy() + const mainModule = await MainModule.deploy(await factory.getAddress(), await mainModuleUpgradable.getAddress()) + + return { + factory: await factory.waitForDeployment(), + mainModule: await mainModule.waitForDeployment(), + mainModuleUpgradable: await mainModuleUpgradable.waitForDeployment() + } +} + +export type SequenceContext = { + factory: ContractType + mainModule: ContractType + mainModuleUpgradable: ContractType +} diff --git a/packages/wallet/wallet-contracts/test/utils/imposter.ts b/packages/wallet/wallet-contracts/test/utils/imposter.ts new file mode 100644 index 0000000000..f8da84b431 --- /dev/null +++ b/packages/wallet/wallet-contracts/test/utils/imposter.ts @@ -0,0 +1,43 @@ +import { ethers } from 'ethers' +import { AnyStaticSigner, StaticSigner } from './wallet' + +export class Imposter extends ethers.AbstractSigner implements StaticSigner { + static random(identity: string | AnyStaticSigner) { + return new Imposter(identity, ethers.Wallet.createRandom()) + } + + constructor( + public identity: string | AnyStaticSigner, + public signer: ethers.Signer + ) { + super() + } + + get address() { + return typeof this.identity === 'string' ? this.identity : this.identity.address + } + + async getAddress(): Promise { + return this.address + } + + signMessage(message: string | Uint8Array): Promise { + return this.signer.signMessage(message) + } + + signTypedData( + domain: ethers.TypedDataDomain, + types: Record, + value: Record + ): Promise { + return this.signer.signTypedData(domain, types, value) + } + + signTransaction(transaction: ethers.TransactionRequest): Promise { + return this.signer.signTransaction(transaction) + } + + connect(provider: ethers.Provider): ethers.Signer { + return this.signer.connect(provider) + } +} diff --git a/packages/wallet/wallet-contracts/test/utils/index.ts b/packages/wallet/wallet-contracts/test/utils/index.ts new file mode 100644 index 0000000000..86eab632e0 --- /dev/null +++ b/packages/wallet/wallet-contracts/test/utils/index.ts @@ -0,0 +1,118 @@ +import * as chai from 'chai' +import chaiAsPromised from 'chai-as-promised' +import chaiString from 'chai-string' +import { ethers } from 'ethers' +import { solidity } from 'ethereum-waffle' +import { ethers as hethers } from 'hardhat' + +export const getChainId = async (): Promise => + process.env.NET_ID ? BigInt(process.env.NET_ID) : (await hethers.provider.getNetwork()).chainId + +export const { assert, expect } = chai.use(chaiString).use(chaiAsPromised).use(solidity) + +export function bytes32toAddress(bytes32: ethers.BytesLike): string { + const paddedValue = ethers.zeroPadValue(bytes32, 32) + return ethers.getAddress(ethers.AbiCoder.defaultAbiCoder().decode(['address'], paddedValue)[0]) +} + +export function shuffle(a: T[]): T[] { + for (let i = a.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)) + ;[a[i], a[j]] = [a[j], a[i]] + } + + return a +} + +export function randomHex(length: number): string { + return ethers.hexlify(ethers.randomBytes(length)) +} + +export async function expectToBeRejected(promise: Promise, error: string) { + if (!process.env.COVERAGE) { + await expect(promise).to.be.rejectedWith(error) + } else { + await expect(promise).to.be.rejected + } +} + +export async function expectStaticToBeRejected(promise: Promise, signature: string, ...args: any[]) { + // await expectToBeRejected(promise, `errorName="${signature.split('(')[0]}"`) + // await expectToBeRejected(promise, `errorSignature="${signature}"`) + + await expectToBeRejected(promise, `${signature.split('(')[0]}`) + + const sigTypes = signature.split('(')[1].split(')')[0].split(',') + + expect(sigTypes.length).to.equal(args.length) + + const formattedArgs = args + .map((arg, i) => { + const type = sigTypes[i] + + if (arg === '*') return '*' + + switch (type) { + case 'bytes': + if (typeof arg === 'string' && arg.length === 0) { + return ethers.hexlify(new Uint8Array([])) + } + return `"${ethers.hexlify(arg).toLowerCase()}"` + case 'string': + return `"${arg.toString()}"` + } + + if (type.startsWith('uint') || type.startsWith('int')) { + //return `{"type":"BigNumber","hex":"${ethers.toBeHex(BigInt(arg))}"}` + return BigInt(arg).toString() + } + + throw new Error(`Unknown type: ${type}`) + }) + .join(', ') + + const groups = formattedArgs.split('*') + + for (let i = 0; i < groups.length; i++) { + await expectToBeRejected(promise, `${groups[i]}`) + } + + // if (groups.length === 1) { + // // await expectToBeRejected(promise, `errorArgs=[${formattedArgs}]`) + // await expectToBeRejected(promise, `${formattedArgs}`) + // } else { + // for (let i = 0; i < groups.length; i++) { + // const group = groups[i] + // if (i === 0) { + // // await expectToBeRejected(promise, `errorArgs=[${group}`) + // await expectToBeRejected(promise, `${group}`) + // } else if (i === groups.length - 1) { + // await expectToBeRejected(promise, `${group}]`) + // } else { + // await expectToBeRejected(promise, `${group}`) + // } + // } + // } +} + +export function encodeError(error: string): string { + return '0x08c379a0' + ethers.AbiCoder.defaultAbiCoder().encode(['string'], [error]).slice(2) +} + +function xor(a: any, b: any) { + if (!Buffer.isBuffer(a)) a = Buffer.from(ethers.getBytes(a)) + if (!Buffer.isBuffer(b)) b = Buffer.from(ethers.getBytes(b)) + return ethers.hexlify(a.map((v: number, i: number) => v ^ b[i])) +} + +export function interfaceIdOf(int: ethers.Interface): string { + const signatures: string[] = [] + int.forEachFunction(fragment => { + signatures.push(getSigHash(fragment)) + }) + return signatures.reduce((p, c) => xor(p, c)) +} + +export function getSigHash(fragment: ethers.FunctionFragment): string { + return ethers.dataSlice(ethers.id(fragment.format('sighash')), 0, 4) +} diff --git a/packages/wallet/wallet-contracts/test/utils/sequence.ts b/packages/wallet/wallet-contracts/test/utils/sequence.ts new file mode 100644 index 0000000000..065192ae9b --- /dev/null +++ b/packages/wallet/wallet-contracts/test/utils/sequence.ts @@ -0,0 +1,613 @@ +import { BigNumberish, BytesLike, ethers, Wallet } from 'ethers' +import { getChainId } from '.' + +export const WALLET_CODE = '0x603a600e3d39601a805130553df3363d3d373d3d3d363d30545af43d82803e903d91601857fd5bf3' + +export enum SignatureType { + Legacy = 0, + Dynamic = 1, + NoChaindDynamic = 2 +} + +export type SignerLeaf = { + address: string + weight: BigNumberish +} + +export type SubdigestLeaf = { + subdigest: string +} + +export type NestedLeaf = { + tree: ConfigTopology + internalThreshold: BigNumberish + externalWeight: BigNumberish +} + +export type ConfigLeaf = SubdigestLeaf | SignerLeaf | NestedLeaf + +export type ImageHashNode = { + left: ConfigTopology + right: ConfigTopology +} + +export type ConfigTopology = ImageHashNode | ConfigLeaf + +export type WalletConfig = { + threshold: ethers.BigNumberish + checkpoint: ethers.BigNumberish + topology: ConfigTopology +} + +export type SimplifiedNestedWalletConfig = { + threshold: ethers.BigNumberish + weight: ethers.BigNumberish + signers: SimplifiedConfigMember[] +} + +export type SimplifiedWalletConfig = { + threshold: BigNumberish + checkpoint: BigNumberish + signers: SimplifiedConfigMember[] +} + +export type SimplifiedConfigMember = SignerLeaf | SimplifiedNestedWalletConfig + +export type Transaction = { + delegateCall: boolean + revertOnError: boolean + gasLimit: BigNumberish + target: string + value: BigNumberish + data: BytesLike +} + +export enum SignaturePartType { + Signature = 0, + Address = 1, + Dynamic = 2, + Node = 3, + Branch = 4, + Subdigest = 5, + Nested = 6 +} + +export type SignaturePart = { + address: string + type: SignaturePartType + signature?: string +} + +export function applyTxDefault( + tx: Partial, + def: Transaction = { + delegateCall: false, + revertOnError: true, + gasLimit: 0, + target: '0xFb8356E7deB64034aBE2b2a8A732634f77A2DAE4', // Random address + value: 0, + data: new Uint8Array([]) + } +): Transaction { + return { + ...def, + ...tx + } +} + +export function applyTxDefaults(tx: Partial[], def?: Transaction): Transaction[] { + return tx.map(t => applyTxDefault(t, def)) +} + +export const MetaTransactionsSolidityType = `tuple( + bool delegateCall, + bool revertOnError, + uint256 gasLimit, + address target, + uint256 value, + bytes data +)[]` + +export function isConfigLeaf(node: ConfigTopology): node is ConfigLeaf { + return !('left' in node || 'right' in node) +} + +export function isSignerLeaf(node: any): node is SignerLeaf { + return isConfigLeaf(node) && 'weight' in node && 'address' in node +} + +export function isSubdigestLeaf(node: ConfigTopology): node is SubdigestLeaf { + return isConfigLeaf(node) && 'subdigest' in node +} + +export function isNestedLeaf(node: ConfigTopology): node is NestedLeaf { + return isConfigLeaf(node) && 'tree' in node +} + +export function legacyTopology(leavesOrConfig: SimplifiedWalletConfig | ConfigTopology[]): ConfigTopology { + if (!Array.isArray(leavesOrConfig)) { + return legacyTopology(toTopology(leavesOrConfig)) + } + + return leavesOrConfig.reduce((acc, leaf) => { + return { + left: acc, + right: leaf + } + }) +} + +export function toTopology(config: SimplifiedWalletConfig | SimplifiedNestedWalletConfig): ConfigTopology[] { + return config.signers.map(s => { + if (isSignerLeaf(s)) { + return { + address: s.address, + weight: s.weight + } + } + + return { + tree: merkleTopology(toTopology(s)), + internalThreshold: s.threshold, + externalWeight: s.weight + } + }) +} + +export function merkleTopology(leavesOrConfig: SimplifiedWalletConfig | ConfigTopology[]): ConfigTopology { + if (!Array.isArray(leavesOrConfig)) { + return merkleTopology(toTopology(leavesOrConfig)) + } + + const leaves = leavesOrConfig + for (let s = leaves.length; s > 1; s = s / 2) { + for (let i = 0; i < s / 2; i++) { + const j1 = i * 2 + const j2 = j1 + 1 + + if (j2 >= s) { + leaves[i] = leaves[j1] + } else { + leaves[i] = { + left: leaves[j1], + right: leaves[j2] + } + } + } + } + + return leaves[0] +} + +export function optimize2SignersTopology(config: SimplifiedWalletConfig): ConfigTopology { + if (config.signers.length > 8) { + return merkleTopology(config) + } + + return legacyTopology(config) +} + +export function leavesOf(topology: ConfigTopology): ConfigLeaf[] { + if (isConfigLeaf(topology)) { + return [topology] + } + + return [...leavesOf(topology.left), ...leavesOf(topology.right)] +} + +export function subdigestLeaves(topology: ConfigTopology): string[] { + return leavesOf(topology) + .filter(l => isSubdigestLeaf(l)) + .map((l: SubdigestLeaf) => l.subdigest) +} + +export function toSimplifiedConfig(config: WalletConfig): SimplifiedWalletConfig { + let leaves = leavesOf(config.topology).filter(isSignerLeaf) + + return { + threshold: config.threshold, + checkpoint: config.checkpoint, + signers: leaves.map(l => ({ + weight: l.weight, + address: l.address + })) + } +} + +export function hashNode(node: ConfigTopology): string { + if (isSignerLeaf(node)) { + return leafForAddressAndWeight(node.address, node.weight) + } + + if (isSubdigestLeaf(node)) { + return ethers.solidityPackedKeccak256(['string', 'bytes32'], ['Sequence static digest:\n', node.subdigest]) + } + + if (isNestedLeaf(node)) { + return ethers.solidityPackedKeccak256( + ['string', 'bytes32', 'uint256', 'uint256'], + ['Sequence nested config:\n', hashNode(node.tree), node.internalThreshold, node.externalWeight] + ) + } + + return ethers.solidityPackedKeccak256(['bytes32', 'bytes32'], [hashNode(node.left), hashNode(node.right)]) +} + +export function imageHash2(threshold: ethers.BigNumberish, topology: ConfigTopology): string { + const root = hashNode(topology) + return ethers.keccak256(ethers.solidityPacked(['bytes32', 'uint256'], [root, threshold])) +} + +export function printTopology(topology: ConfigTopology, threshold?: ethers.BigNumberish, inverse = false): string[] { + if (threshold) { + const imageHash = imageHash2(threshold, topology) + + const result: string[] = [`imageHash: ${imageHash}`] + const signers = printTopology(topology, undefined, inverse) + result.push(` ā”œā”€ threshold: ${threshold}`) + for (let i = 0; i < signers.length; i++) { + const prefix = i === 0 ? ' └─ ' : ' ' + result.push(`${prefix}${signers[i]}`) + } + + return result + } + + if (isSignerLeaf(topology)) { + return [`weight: ${topology.weight} - address: ${topology.address}`] + } + + if (isSubdigestLeaf(topology)) { + return [`subdigest: ${topology.subdigest}`] + } + + if (isNestedLeaf(topology)) { + const result: string[] = [`internalThreshold: ${topology.internalThreshold} - externalWeight: ${topology.externalWeight}`] + const signers = printTopology(topology.tree, undefined, inverse) + for (let i = 0; i < signers.length; i++) { + const prefix = i === 0 ? '└─ ' : ' ' + result.push(`${prefix}${signers[i]}`) + } + + return result + } + + const root = hashNode(topology) + let printLeft = printTopology(topology.left, undefined, inverse) + let printRight = printTopology(topology.right, undefined, inverse) + + if (inverse) { + ;[printLeft, printRight] = [printRight, printLeft] + } + + const result = [`${root}`] + for (let i = 0; i < printLeft.length; i++) { + const prefix = i === 0 ? ' ā”œā”€ ' : ' │' + result.push(`${prefix}${printLeft[i]}`) + } + + for (let i = 0; i < printRight.length; i++) { + const prefix = i === 0 ? ' └─ ' : ' ' + result.push(`${prefix}${printRight[i]}`) + } + + return result +} + +export function addressOf(factory: string, firstModule: string, imageHash: string): string { + const codeHash = ethers.keccak256( + ethers.solidityPacked(['bytes', 'bytes32'], [WALLET_CODE, ethers.zeroPadValue(firstModule, 32)]) + ) + + const hash = ethers.keccak256( + ethers.solidityPacked(['bytes1', 'address', 'bytes32', 'bytes32'], ['0xff', factory, imageHash, codeHash]) + ) + + return ethers.getAddress(ethers.dataSlice(hash, 12)) +} + +export function encodeNonce(space: BigNumberish, nonce: BigNumberish) { + return BigInt(ethers.solidityPacked(['uint160', 'uint96'], [space, nonce])) +} + +export function leafForAddressAndWeight(address: string, weight: ethers.BigNumberish) { + return ethers.solidityPacked(['uint96', 'address'], [weight, address]) +} + +export function imageHash(config: WalletConfig): string { + const signersRoot = hashNode(config.topology) + + const preImageHash = ethers.keccak256( + ethers.AbiCoder.defaultAbiCoder().encode(['bytes32', 'uint256'], [signersRoot, config.threshold]) + ) + + return ethers.keccak256(ethers.AbiCoder.defaultAbiCoder().encode(['bytes32', 'uint256'], [preImageHash, config.checkpoint])) +} + +export function digestOf(txs: Partial[], nonce: ethers.BigNumberish) { + return ethers.keccak256( + ethers.AbiCoder.defaultAbiCoder().encode(['uint256', MetaTransactionsSolidityType], [nonce, applyTxDefaults(txs)]) + ) +} + +export async function subdigestOf(wallet: string, digest: ethers.BytesLike, chainId?: ethers.BigNumberish) { + chainId = chainId ?? (await getChainId()) + return ethers.keccak256( + ethers.solidityPacked(['string', 'uint256', 'address', 'bytes32'], ['\x19\x01', chainId, wallet, digest]) + ) +} + +export function computeStorageKey(key: string, subkey?: string): string { + if (!subkey) { + return ethers.id(key) + } + + return ethers.keccak256(ethers.AbiCoder.defaultAbiCoder().encode(['bytes32', 'bytes32'], [computeStorageKey(key), subkey])) +} + +export type EncodingOptions = { + forceDynamicEncoding?: boolean + signatureType?: SignatureType + disableTrim?: boolean +} + +function leftSlice(topology: ConfigTopology): ConfigTopology[] { + // Returns left side of the tree + let stack: ConfigTopology[] = [] + + let prev = topology + while (!isConfigLeaf(prev)) { + stack.unshift(prev.right) + prev = prev.left + } + + stack.unshift(prev) + + return stack +} + +type DecodedSignatureMember = { + weight?: ethers.BigNumberish + address?: string + type: SignaturePartType + value?: string + innerThreshold?: ethers.BigNumberish +} + +export class SignatureConstructor { + private members: DecodedSignatureMember[] = [] + + constructor(public disableTrim = false) {} + + tryTrim(): void { + if (this.disableTrim) return + + // Can only trim when we have two members + if (this.members.length !== 2) return + + // There are 4 valid trim options: + // 1. Trim the first addr, second is node + // 2. Trim the first node, second is addr + // 3. Trim the first addr, second is addr + // 4. Trim the first node, second is node + + const first = this.members[0] + const second = this.members[1] + + if (first.type !== SignaturePartType.Address && first.type !== SignaturePartType.Node) return + if (second.type !== SignaturePartType.Address && second.type !== SignaturePartType.Node) return + + const firstNode = + first.type === SignaturePartType.Address ? leafForAddressAndWeight(first.address!, first.weight!) : first.value + const secondNode = + second.type === SignaturePartType.Address ? leafForAddressAndWeight(second.address!, second.weight!) : second.value + + const nextNode = ethers.keccak256(ethers.solidityPacked(['bytes32', 'bytes32'], [firstNode, secondNode])) + + this.members = [ + { + type: SignaturePartType.Node, + value: nextNode + } + ] + } + + appendPart(weight: ethers.BigNumberish, part: SignaturePart) { + switch (part.type) { + case SignaturePartType.Address: + this.members.push({ weight, address: part.address, type: SignaturePartType.Address }) + break + + case SignaturePartType.Signature: + this.members.push({ weight, address: part.address, type: SignaturePartType.Signature, value: part.signature }) + break + + case SignaturePartType.Dynamic: + this.members.push({ weight, address: part.address, type: SignaturePartType.Dynamic, value: part.signature }) + break + + default: + throw new Error(`Unknown signature part type: ${part.type}`) + } + + this.tryTrim() + } + + appendNode(node: string) { + this.members.push({ type: SignaturePartType.Node, value: node }) + this.tryTrim() + } + + appendBranch(branch: string) { + this.members.push({ type: SignaturePartType.Branch, value: branch }) + } + + appendSubdigest(subdigest: string) { + this.members.push({ type: SignaturePartType.Subdigest, value: subdigest }) + } + + appendNested(branch: string, weight: ethers.BigNumberish, innerThreshold: ethers.BigNumberish) { + this.members.push({ type: SignaturePartType.Nested, value: branch, innerThreshold, weight }) + } + + encode(): string { + let result = '0x' + + for (const member of this.members) { + switch (member.type) { + case SignaturePartType.Address: + result = ethers.solidityPacked( + ['bytes', 'uint8', 'uint8', 'address'], + [result, SignaturePartType.Address, member.weight, member.address] + ) + break + + case SignaturePartType.Signature: + result = ethers.solidityPacked( + ['bytes', 'uint8', 'uint8', 'bytes'], + [result, SignaturePartType.Signature, member.weight, member.value] + ) + break + + case SignaturePartType.Dynamic: + const signature = ethers.getBytes(member.value ?? new Uint8Array([])) + result = ethers.solidityPacked( + ['bytes', 'uint8', 'uint8', 'address', 'uint24', 'bytes'], + [result, SignaturePartType.Dynamic, member.weight, member.address, signature.length, signature] + ) + break + + case SignaturePartType.Node: + result = ethers.solidityPacked(['bytes', 'uint8', 'bytes32'], [result, SignaturePartType.Node, member.value]) + break + + case SignaturePartType.Branch: + const branch = ethers.getBytes(member.value ?? new Uint8Array([])) + result = ethers.solidityPacked( + ['bytes', 'uint8', 'uint24', 'bytes'], + [result, SignaturePartType.Branch, branch.length, branch] + ) + break + + case SignaturePartType.Subdigest: + result = ethers.solidityPacked(['bytes', 'uint8', 'bytes32'], [result, SignaturePartType.Subdigest, member.value]) + break + + case SignaturePartType.Nested: + const nestedBranch = ethers.getBytes(member.value ?? new Uint8Array([])) + result = ethers.solidityPacked( + ['bytes', 'uint8', 'uint8', 'uint16', 'uint24', 'bytes'], + [result, SignaturePartType.Nested, member.weight, member.innerThreshold, nestedBranch.length, nestedBranch] + ) + break + + default: + throw new Error(`Unknown signature part type: ${member.type}`) + } + } + + return result + } +} + +export function encodeSigners( + topology: ConfigTopology, + parts: SignaturePart[] | Map, + subdigests: string[], + options?: EncodingOptions +): { encoded: string; weight: bigint } { + // Map part to signers + if (Array.isArray(parts)) { + const partOfSigner = new Map() + for (const part of parts) { + partOfSigner.set(part.address, part) + } + return encodeSigners(topology, partOfSigner, subdigests, options) + } + + const slice = leftSlice(topology) + let weight = 0n + + const constructor = new SignatureConstructor(options?.disableTrim) + for (const node of slice) { + if (!isConfigLeaf(node)) { + // If the node opens up to another branch + // we recurse the encoding, and if the result has any weight + // we have to embed the whole branch, otherwise we just add the node + const nested = encodeSigners(node, parts, subdigests, options) + if (nested.weight === 0n && !options?.disableTrim) { + constructor.appendNode(hashNode(node)) + } else { + constructor.appendBranch(nested.encoded) + weight = weight + nested.weight + } + } else { + if (isSignerLeaf(node)) { + // If the node is a signer leaf, we can just add the member + const part = parts.get(node.address) ?? { type: SignaturePartType.Address, address: node.address } + if (part.type !== SignaturePartType.Address) { + weight = weight + BigInt(node.weight) + } + + constructor.appendPart(node.weight, part) + } else if (isNestedLeaf(node)) { + // If the node opens up to another branch + // we recurse the encoding, and if the result has any weight + // we have to embed the whole branch, otherwise we just add the node + const nested = encodeSigners(node.tree, parts, subdigests, options) + if (nested.weight === 0n && !options?.disableTrim) { + constructor.appendNode(hashNode(node)) + } else { + // Nested configs only have weight if the inner threshold is met + // and the weight is always the external weight + if (nested.weight >= BigInt(node.internalThreshold)) { + weight = weight + BigInt(node.externalWeight) + } + + constructor.appendNested(nested.encoded, node.externalWeight, node.internalThreshold) + } + } else { + // If the node is a subdigest add the node (unless it's an static subdigest signature) + if (subdigests.includes(node.subdigest)) { + weight += 2n ** 256n - 1n + constructor.appendSubdigest(node.subdigest) + } else { + constructor.appendNode(hashNode(node)) + } + } + } + } + + return { + encoded: constructor.encode(), + weight + } +} + +export function encodeSignature( + config: WalletConfig, + parts: SignaturePart[] | Map, + subdigests: string[], + options?: EncodingOptions +) { + const encodedSigners = encodeSigners(config.topology, parts, subdigests, options) + + switch (options?.signatureType || SignatureType.Legacy) { + case SignatureType.Dynamic: + return ethers.solidityPacked( + ['uint8', 'uint16', 'uint32', 'bytes'], + [SignatureType.Dynamic, config.threshold, config.checkpoint, encodedSigners.encoded] + ) + case SignatureType.NoChaindDynamic: + return ethers.solidityPacked( + ['uint8', 'uint16', 'uint32', 'bytes'], + [SignatureType.NoChaindDynamic, config.threshold, config.checkpoint, encodedSigners.encoded] + ) + default: + case SignatureType.Legacy: + return ethers.solidityPacked( + ['uint8', 'uint8', 'uint32', 'bytes'], + [SignatureType.Legacy, config.threshold, config.checkpoint, encodedSigners.encoded] + ) + } +} diff --git a/packages/wallet/wallet-contracts/test/utils/wallet.ts b/packages/wallet/wallet-contracts/test/utils/wallet.ts new file mode 100644 index 0000000000..110da55082 --- /dev/null +++ b/packages/wallet/wallet-contracts/test/utils/wallet.ts @@ -0,0 +1,329 @@ +import { ethers, Overrides } from 'ethers' +import { ethers as hethers } from 'hardhat' +import { shuffle } from '.' +import { MainModule, MainModuleUpgradable, SequenceContext } from './contracts' +import { + addressOf, + applyTxDefaults, + ConfigTopology, + digestOf, + encodeSignature, + EncodingOptions, + imageHash, + merkleTopology, + optimize2SignersTopology, + SignaturePartType, + SignatureType, + SimplifiedWalletConfig, + subdigestOf, + Transaction, + WalletConfig +} from './sequence' + +export type StaticSigner = ethers.Signer & { address: string } +export type AnyStaticSigner = StaticSigner | SequenceWallet + +export function isAnyStaticSigner(s: any): s is AnyStaticSigner { + return s.address !== undefined +} + +let LAST_CHECKPOINT = 0 + +export function getCheckpoint() { + let cand = Math.floor(Date.now() / 1000) + + if (cand === LAST_CHECKPOINT) { + cand++ + } + + LAST_CHECKPOINT = cand + return cand +} + +export type WalletOptions = { + context: SequenceContext + config: WalletConfig + address?: string + signers: (ethers.Signer | SequenceWallet)[] + encodingOptions?: EncodingOptions + chainId?: ethers.BigNumberish +} + +export type BasicWalletOptions = { + address?: string + threshold?: number + signing: number | number[] + idle: number | number[] + encodingOptions?: EncodingOptions + topologyConverter: (simple: SimplifiedWalletConfig) => ConfigTopology +} + +export type DetailedWalletOptions = { + address?: string + threshold: ethers.BigNumberish + signers: (string | AnyStaticSigner | Weighted | Weighted)[] + encodingOptions?: EncodingOptions +} + +export type Weighted = { weight: number; value: T } + +export function isWeighted(w: any): w is Weighted { + return w.weight !== undefined && w.value !== undefined +} + +export function weightedVal(w: Weighted | T): T { + return isWeighted(w) ? w.value : w +} + +export function isSequenceSigner(signer: ethers.Signer | SequenceWallet): signer is SequenceWallet { + return 'isSequence' in signer && signer.isSequence +} + +const defaultTopology = optimize2SignersTopology + +export class SequenceWallet { + public isSequence = true + _isSigner: boolean = true + + constructor(public options: WalletOptions) {} + + static basicWallet(context: SequenceContext, opts?: Partial): SequenceWallet { + const options = { ...{ signing: 1, idle: 0, topologyConverter: defaultTopology }, ...opts } + + const signersWeight = Array.isArray(options.signing) ? options.signing : new Array(options.signing).fill(0).map(() => 1) + const idleWeight = Array.isArray(options.idle) ? options.idle : new Array(options.idle).fill(0).map(() => 1) + + const signers = signersWeight.map(s => (isAnyStaticSigner(s) ? s : ethers.Wallet.createRandom())) + const idle = idleWeight.map(() => ethers.getAddress(ethers.hexlify(ethers.randomBytes(20)))) + const checkpoint = getCheckpoint() + + const simplifiedConfig = { + checkpoint, + threshold: options.threshold ? options.threshold : signers.length, + signers: shuffle( + signers + .map((s, i) => ({ + address: s.address, + weight: signersWeight[i] + })) + .concat( + idle.map((s, i) => ({ + address: s, + weight: idleWeight[i] + })) + ) + ) + } + + return new SequenceWallet({ + address: options.address, + context, + encodingOptions: options.encodingOptions, + config: { + ...simplifiedConfig, + topology: options.topologyConverter(simplifiedConfig) + }, + signers: signers + }) + } + + static detailedWallet(context: SequenceContext, opts: DetailedWalletOptions): SequenceWallet { + const simplifiedConfig = { + threshold: opts.threshold, + checkpoint: getCheckpoint(), + signers: opts.signers.map(s => ({ + weight: isWeighted(s) ? s.weight : 1, + address: (() => { + const v = weightedVal(s) + return isAnyStaticSigner(v) ? v.address : v + })() + })) + } + + return new SequenceWallet({ + context, + encodingOptions: opts.encodingOptions, + address: opts.address, + config: { + ...simplifiedConfig, + topology: defaultTopology(simplifiedConfig) + }, + signers: opts.signers.map(s => weightedVal(s)).filter(isAnyStaticSigner) + }) + } + + useAddress(address?: string) { + return new SequenceWallet({ ...this.options, address: address ? address : this.address }) + } + + useConfig(of: SequenceWallet | WalletConfig) { + const config = 'config' in of ? of.config : of + return new SequenceWallet({ ...this.options, config }) + } + + useSigners(signers: (ethers.Signer | SequenceWallet)[] | ethers.Signer | SequenceWallet) { + return new SequenceWallet({ ...this.options, signers: Array.isArray(signers) ? signers : [signers] }) + } + + useEncodingOptions(encodingOptions?: EncodingOptions) { + return new SequenceWallet({ ...this.options, encodingOptions }) + } + + useChainId(chainId?: ethers.BigNumberish) { + return new SequenceWallet({ ...this.options, chainId }) + } + + get config() { + return this.options.config + } + + get signers() { + return this.options.signers + } + + get address() { + if (this.options.address) return this.options.address + return addressOf( + this.options.context.factory.target as string, + this.options.context.mainModule.target as string, + this.imageHash + ) + } + + getAddress() { + return this.address + } + + get imageHash() { + return imageHash(this.config) + } + + get mainModule() { + return MainModule.attach(this.address) + } + + get mainModuleUpgradable() { + return MainModuleUpgradable.attach(this.address) + } + + async deploy() { + if ((await hethers.provider.getCode(this.address)) !== '0x') { + return + } + + return await this.options.context.factory.deploy(await this.options.context.mainModule.getAddress(), this.imageHash) + } + + async getNonce(space: ethers.BigNumberish = 0) { + return this.mainModule.readNonce(space) + } + + async updateImageHash(input: ethers.BytesLike | WalletConfig): Promise { + if (!ethers.isBytesLike(input)) return this.updateImageHash(imageHash(input)) + + return this.sendTransactions([ + { + target: this.address, + data: this.options.context.mainModule.interface.encodeFunctionData('updateImageHash', [input]) + } + ]) + } + + async addExtraImageHash( + input: ethers.BytesLike | WalletConfig, + expiration: ethers.BigNumberish = 2n ** 248n + ): Promise { + if (!ethers.isBytesLike(input)) return this.addExtraImageHash(imageHash(input)) + + return this.sendTransactions([ + { + target: this.address, + data: this.options.context.mainModule.interface.encodeFunctionData('setExtraImageHash', [input, expiration]) + } + ]) + } + + async clearExtraImageHashes(imageHashes: (ethers.BytesLike | WalletConfig)[]) { + return this.sendTransactions([ + { + target: this.address, + data: this.options.context.mainModule.interface.encodeFunctionData('clearExtraImageHashes', [ + imageHashes.map(h => (ethers.isBytesLike(h) ? h : imageHash(h))) + ]) + } + ]) + } + + async signMessage(message: ethers.BytesLike): Promise { + return this.signDigest(ethers.keccak256(ethers.getBytes(message))) + } + + async signDigest(digest: ethers.BytesLike): Promise { + const subdigest = ethers.getBytes(await subdigestOf(this.address, digest, this.options.chainId)) + return this.signSubdigest(subdigest) + } + + staticSubdigestSign(subdigest: ethers.BytesLike, useNoChainId = true): string { + const signatureType = useNoChainId ? SignatureType.NoChaindDynamic : this.options.encodingOptions?.signatureType + return encodeSignature(this.config, [], [ethers.hexlify(subdigest)], { ...this.options.encodingOptions, signatureType }) + } + + async signSubdigest(subdigest: ethers.BytesLike): Promise { + const sigParts = await Promise.all( + this.signers.map(async s => { + if (isSequenceSigner(s)) { + return { + address: s.address, + signature: await s.signDigest(subdigest).then(s => s + '03'), + type: SignaturePartType.Dynamic + } + } + + return { + address: await s.getAddress(), + signature: await s.signMessage(subdigest).then(s => s + '02'), + type: SignaturePartType.Signature + } + }) + ) + + return encodeSignature(this.config, sigParts, [], this.options.encodingOptions) + } + + async signTransactions(ptxs: Partial[], nonce?: ethers.BigNumberish): Promise { + if (nonce === undefined) return this.signTransactions(ptxs, await this.getNonce()) + + const txs = applyTxDefaults(ptxs) + const digest = digestOf(txs, nonce) + + return this.signDigest(digest) + } + + async relayTransactions( + ptxs: Partial[], + signature: string, + nonce?: ethers.BigNumberish, + overrides: Overrides & { from?: string | Promise } = {} + ): Promise { + if (nonce === undefined) { + return this.relayTransactions(ptxs, signature, await this.getNonce(), overrides) + } + + const txs = applyTxDefaults(ptxs) + + return this.mainModule.execute(txs, nonce, signature, overrides) + } + + async sendTransactions( + ptxs: Partial[], + nonce?: ethers.BigNumberish, + overrides?: Overrides & { from?: string | Promise } + ): Promise { + if (nonce === undefined) return this.sendTransactions(ptxs, await this.getNonce(), overrides) + + const txs = applyTxDefaults(ptxs) + const signature = await this.signTransactions(txs, nonce) + + return this.relayTransactions(txs, signature, nonce, overrides) + } +} diff --git a/packages/wallet/wallet-contracts/tsconfig.json b/packages/wallet/wallet-contracts/tsconfig.json new file mode 100644 index 0000000000..c6725543c9 --- /dev/null +++ b/packages/wallet/wallet-contracts/tsconfig.json @@ -0,0 +1,37 @@ +{ + "compilerOptions": { + "target": "es2020", + "module": "commonjs", + "moduleResolution": "node", + "sourceMap": true, + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + "downlevelIteration": true, + "removeComments": false, + "skipLibCheck": true, + + "strictNullChecks": true, + "noImplicitUseStrict": true, + "noImplicitAny": false, + "noImplicitReturns": true, + "noImplicitThis": true, + "noUnusedParameters": false, + "noErrorTruncation": true, + "esModuleInterop": true, + + "experimentalDecorators": true, + "forceConsistentCasingInFileNames": true, + "allowJs": false, + "checkJs": false, + + "baseUrl": ".", + "outDir": "build", + "lib": ["es2020", "dom"], + + "typeRoots": ["./node_modules/@types"] + }, + + "include": ["./hardhat.config.ts", "typings", "tests", "utils", "test"], + + "exclude": ["node_modules", "dist"] +} diff --git a/packages/wallet/wallet-contracts/typings/chai-bignumber.d.ts b/packages/wallet/wallet-contracts/typings/chai-bignumber.d.ts new file mode 100644 index 0000000000..8a0080c8c7 --- /dev/null +++ b/packages/wallet/wallet-contracts/typings/chai-bignumber.d.ts @@ -0,0 +1,16 @@ +/// + +declare module 'chai-bignumber' { + function chaiBignumber(bignumber: any): (chai: any, utils: any) => void + + namespace chaiBignumber {} + + export = chaiBignumber +} + +declare namespace Chai { + // For BDD API + interface Assertion extends LanguageChains, NumericComparison, TypeComparison { + bignumber: Assertion + } +} diff --git a/packages/wallet/wallet-contracts/typings/chai-bn.ts b/packages/wallet/wallet-contracts/typings/chai-bn.ts new file mode 100644 index 0000000000..fdf499cd18 --- /dev/null +++ b/packages/wallet/wallet-contracts/typings/chai-bn.ts @@ -0,0 +1,19 @@ +/* eslint-disable */ +/// + +declare module 'chai-bn' { + function chaiBN(bignumber: any): (chai: any, utils: any) => void + + namespace chaiBN {} + + export = chaiBN +} + +declare namespace Chai { + interface Equal { + BN: any + } + interface NumberComparer { + BN: any + } +} diff --git a/packages/wallet/wallet-contracts/typings/truffle.d.ts b/packages/wallet/wallet-contracts/typings/truffle.d.ts new file mode 100644 index 0000000000..360a1a7c6e --- /dev/null +++ b/packages/wallet/wallet-contracts/typings/truffle.d.ts @@ -0,0 +1,12 @@ +declare module 'truffle' { + import * as truffle from 'truffle-contract' + + interface ArtifactsGlobal { + require(name: string): truffle.TruffleContract + } + + global { + function contract(name: string, callback: (accounts: Array) => void): void + const artifacts: ArtifactsGlobal + } +} diff --git a/packages/wallet/wallet-contracts/utils/JsonBindings.sol b/packages/wallet/wallet-contracts/utils/JsonBindings.sol new file mode 100644 index 0000000000..790682614a --- /dev/null +++ b/packages/wallet/wallet-contracts/utils/JsonBindings.sol @@ -0,0 +1,193 @@ +// Automatically generated by forge bind-json. + +pragma solidity >=0.6.2 <0.9.0; +pragma experimental ABIEncoderV2; + +import {MainModuleGasEstimation} from "contracts/modules/MainModuleGasEstimation.sol"; +import {IModuleCalls} from "contracts/modules/commons/interfaces/IModuleCalls.sol"; +import {ModuleCallsTest} from "foundry_test/modules/commons/ModuleCalls.t.sol"; +import {ModuleExtraAuthTest} from "foundry_test/modules/commons/ModuleExtraAuth.t.sol"; +import {SequenceChainedSigImp, SequenceChainedSigTest} from "foundry_test/modules/commons/submodules/auth/SequenceChainedSig.t.sol"; +import {L2CompressorHuffTest} from "foundry_test/modules/utils/L2CompressorHuff.t.sol"; +import {TrustTest} from "foundry_test/trust/Trust.t.sol"; + +interface Vm { + function parseJsonTypeArray(string calldata json, string calldata key, string calldata typeDescription) external pure returns (bytes memory); + function parseJsonType(string calldata json, string calldata typeDescription) external pure returns (bytes memory); + function parseJsonType(string calldata json, string calldata key, string calldata typeDescription) external pure returns (bytes memory); + function serializeJsonType(string calldata typeDescription, bytes memory value) external pure returns (string memory json); + function serializeJsonType(string calldata objectKey, string calldata valueKey, string calldata typeDescription, bytes memory value) external returns (string memory json); +} + +library JsonBindings { + Vm constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + + string constant schema_Transaction = "Transaction(bool delegateCall,bool revertOnError,uint256 gasLimit,address target,uint256 value,bytes data)"; + string constant schema_SimulateResult = "SimulateResult(bool executed,bool succeeded,bytes result,uint256 gasUsed)"; + string constant schema_ToValAndData = "ToValAndData(address target,uint256 value,bytes data)"; + string constant schema_SetIh = "SetIh(bytes32 imageHash,uint256 expiration)"; + string constant schema_MockedSignature = "MockedSignature(bool exists,uint256 threshold,uint256 weight,bytes32 imageHash,bytes32 subdigest,uint256 checkpoint)"; + string constant schema_HashAndSignature = "HashAndSignature(bytes32 imageHash,uint256 threshold,uint256 weight,uint56 checkpointDelta,bytes signature)"; + string constant schema_BatchMember = "BatchMember(Transaction[] txs,uint160 space,uint96 nonce,bytes signature)Transaction(bool delegateCall,bool revertOnError,uint256 gasLimit,address target,uint256 value,bytes data)"; + string constant schema_MemoryStruct1 = "MemoryStruct1(bytes32 rawHash,bytes32 finalHash,uint8 v,bytes32 r,bytes32 s)"; + + function serialize(IModuleCalls.Transaction memory value) internal pure returns (string memory) { + return vm.serializeJsonType(schema_Transaction, abi.encode(value)); + } + + function serialize(IModuleCalls.Transaction memory value, string memory objectKey, string memory valueKey) internal returns (string memory) { + return vm.serializeJsonType(objectKey, valueKey, schema_Transaction, abi.encode(value)); + } + + function deserializeTransaction(string memory json) public pure returns (IModuleCalls.Transaction memory) { + return abi.decode(vm.parseJsonType(json, schema_Transaction), (IModuleCalls.Transaction)); + } + + function deserializeTransaction(string memory json, string memory path) public pure returns (IModuleCalls.Transaction memory) { + return abi.decode(vm.parseJsonType(json, path, schema_Transaction), (IModuleCalls.Transaction)); + } + + function deserializeTransactionArray(string memory json, string memory path) public pure returns (IModuleCalls.Transaction[] memory) { + return abi.decode(vm.parseJsonTypeArray(json, path, schema_Transaction), (IModuleCalls.Transaction[])); + } + + function serialize(MainModuleGasEstimation.SimulateResult memory value) internal pure returns (string memory) { + return vm.serializeJsonType(schema_SimulateResult, abi.encode(value)); + } + + function serialize(MainModuleGasEstimation.SimulateResult memory value, string memory objectKey, string memory valueKey) internal returns (string memory) { + return vm.serializeJsonType(objectKey, valueKey, schema_SimulateResult, abi.encode(value)); + } + + function deserializeSimulateResult(string memory json) public pure returns (MainModuleGasEstimation.SimulateResult memory) { + return abi.decode(vm.parseJsonType(json, schema_SimulateResult), (MainModuleGasEstimation.SimulateResult)); + } + + function deserializeSimulateResult(string memory json, string memory path) public pure returns (MainModuleGasEstimation.SimulateResult memory) { + return abi.decode(vm.parseJsonType(json, path, schema_SimulateResult), (MainModuleGasEstimation.SimulateResult)); + } + + function deserializeSimulateResultArray(string memory json, string memory path) public pure returns (MainModuleGasEstimation.SimulateResult[] memory) { + return abi.decode(vm.parseJsonTypeArray(json, path, schema_SimulateResult), (MainModuleGasEstimation.SimulateResult[])); + } + + function serialize(ModuleCallsTest.ToValAndData memory value) internal pure returns (string memory) { + return vm.serializeJsonType(schema_ToValAndData, abi.encode(value)); + } + + function serialize(ModuleCallsTest.ToValAndData memory value, string memory objectKey, string memory valueKey) internal returns (string memory) { + return vm.serializeJsonType(objectKey, valueKey, schema_ToValAndData, abi.encode(value)); + } + + function deserializeToValAndData(string memory json) public pure returns (ModuleCallsTest.ToValAndData memory) { + return abi.decode(vm.parseJsonType(json, schema_ToValAndData), (ModuleCallsTest.ToValAndData)); + } + + function deserializeToValAndData(string memory json, string memory path) public pure returns (ModuleCallsTest.ToValAndData memory) { + return abi.decode(vm.parseJsonType(json, path, schema_ToValAndData), (ModuleCallsTest.ToValAndData)); + } + + function deserializeToValAndDataArray(string memory json, string memory path) public pure returns (ModuleCallsTest.ToValAndData[] memory) { + return abi.decode(vm.parseJsonTypeArray(json, path, schema_ToValAndData), (ModuleCallsTest.ToValAndData[])); + } + + function serialize(ModuleExtraAuthTest.SetIh memory value) internal pure returns (string memory) { + return vm.serializeJsonType(schema_SetIh, abi.encode(value)); + } + + function serialize(ModuleExtraAuthTest.SetIh memory value, string memory objectKey, string memory valueKey) internal returns (string memory) { + return vm.serializeJsonType(objectKey, valueKey, schema_SetIh, abi.encode(value)); + } + + function deserializeSetIh(string memory json) public pure returns (ModuleExtraAuthTest.SetIh memory) { + return abi.decode(vm.parseJsonType(json, schema_SetIh), (ModuleExtraAuthTest.SetIh)); + } + + function deserializeSetIh(string memory json, string memory path) public pure returns (ModuleExtraAuthTest.SetIh memory) { + return abi.decode(vm.parseJsonType(json, path, schema_SetIh), (ModuleExtraAuthTest.SetIh)); + } + + function deserializeSetIhArray(string memory json, string memory path) public pure returns (ModuleExtraAuthTest.SetIh[] memory) { + return abi.decode(vm.parseJsonTypeArray(json, path, schema_SetIh), (ModuleExtraAuthTest.SetIh[])); + } + + function serialize(SequenceChainedSigImp.MockedSignature memory value) internal pure returns (string memory) { + return vm.serializeJsonType(schema_MockedSignature, abi.encode(value)); + } + + function serialize(SequenceChainedSigImp.MockedSignature memory value, string memory objectKey, string memory valueKey) internal returns (string memory) { + return vm.serializeJsonType(objectKey, valueKey, schema_MockedSignature, abi.encode(value)); + } + + function deserializeMockedSignature(string memory json) public pure returns (SequenceChainedSigImp.MockedSignature memory) { + return abi.decode(vm.parseJsonType(json, schema_MockedSignature), (SequenceChainedSigImp.MockedSignature)); + } + + function deserializeMockedSignature(string memory json, string memory path) public pure returns (SequenceChainedSigImp.MockedSignature memory) { + return abi.decode(vm.parseJsonType(json, path, schema_MockedSignature), (SequenceChainedSigImp.MockedSignature)); + } + + function deserializeMockedSignatureArray(string memory json, string memory path) public pure returns (SequenceChainedSigImp.MockedSignature[] memory) { + return abi.decode(vm.parseJsonTypeArray(json, path, schema_MockedSignature), (SequenceChainedSigImp.MockedSignature[])); + } + + function serialize(SequenceChainedSigTest.HashAndSignature memory value) internal pure returns (string memory) { + return vm.serializeJsonType(schema_HashAndSignature, abi.encode(value)); + } + + function serialize(SequenceChainedSigTest.HashAndSignature memory value, string memory objectKey, string memory valueKey) internal returns (string memory) { + return vm.serializeJsonType(objectKey, valueKey, schema_HashAndSignature, abi.encode(value)); + } + + function deserializeHashAndSignature(string memory json) public pure returns (SequenceChainedSigTest.HashAndSignature memory) { + return abi.decode(vm.parseJsonType(json, schema_HashAndSignature), (SequenceChainedSigTest.HashAndSignature)); + } + + function deserializeHashAndSignature(string memory json, string memory path) public pure returns (SequenceChainedSigTest.HashAndSignature memory) { + return abi.decode(vm.parseJsonType(json, path, schema_HashAndSignature), (SequenceChainedSigTest.HashAndSignature)); + } + + function deserializeHashAndSignatureArray(string memory json, string memory path) public pure returns (SequenceChainedSigTest.HashAndSignature[] memory) { + return abi.decode(vm.parseJsonTypeArray(json, path, schema_HashAndSignature), (SequenceChainedSigTest.HashAndSignature[])); + } + + function serialize(L2CompressorHuffTest.BatchMember memory value) internal pure returns (string memory) { + return vm.serializeJsonType(schema_BatchMember, abi.encode(value)); + } + + function serialize(L2CompressorHuffTest.BatchMember memory value, string memory objectKey, string memory valueKey) internal returns (string memory) { + return vm.serializeJsonType(objectKey, valueKey, schema_BatchMember, abi.encode(value)); + } + + function deserializeBatchMember(string memory json) public pure returns (L2CompressorHuffTest.BatchMember memory) { + return abi.decode(vm.parseJsonType(json, schema_BatchMember), (L2CompressorHuffTest.BatchMember)); + } + + function deserializeBatchMember(string memory json, string memory path) public pure returns (L2CompressorHuffTest.BatchMember memory) { + return abi.decode(vm.parseJsonType(json, path, schema_BatchMember), (L2CompressorHuffTest.BatchMember)); + } + + function deserializeBatchMemberArray(string memory json, string memory path) public pure returns (L2CompressorHuffTest.BatchMember[] memory) { + return abi.decode(vm.parseJsonTypeArray(json, path, schema_BatchMember), (L2CompressorHuffTest.BatchMember[])); + } + + function serialize(TrustTest.MemoryStruct1 memory value) internal pure returns (string memory) { + return vm.serializeJsonType(schema_MemoryStruct1, abi.encode(value)); + } + + function serialize(TrustTest.MemoryStruct1 memory value, string memory objectKey, string memory valueKey) internal returns (string memory) { + return vm.serializeJsonType(objectKey, valueKey, schema_MemoryStruct1, abi.encode(value)); + } + + function deserializeMemoryStruct1(string memory json) public pure returns (TrustTest.MemoryStruct1 memory) { + return abi.decode(vm.parseJsonType(json, schema_MemoryStruct1), (TrustTest.MemoryStruct1)); + } + + function deserializeMemoryStruct1(string memory json, string memory path) public pure returns (TrustTest.MemoryStruct1 memory) { + return abi.decode(vm.parseJsonType(json, path, schema_MemoryStruct1), (TrustTest.MemoryStruct1)); + } + + function deserializeMemoryStruct1Array(string memory json, string memory path) public pure returns (TrustTest.MemoryStruct1[] memory) { + return abi.decode(vm.parseJsonTypeArray(json, path, schema_MemoryStruct1), (TrustTest.MemoryStruct1[])); + } +} diff --git a/packages/wallet/wallet-contracts/utils/benchmarker.ts b/packages/wallet/wallet-contracts/utils/benchmarker.ts new file mode 100644 index 0000000000..5c8b586159 --- /dev/null +++ b/packages/wallet/wallet-contracts/utils/benchmarker.ts @@ -0,0 +1,106 @@ +import { spawn, Worker, Pool } from 'threads' +import { BenchWorker } from './workers/bench-worker' + +import { task } from 'hardhat/config' +import { boolean, int } from 'hardhat/internal/core/params/argumentTypes' +import fs from 'fs' + +class BufferSort { + buffer: { i: number; val: string }[] = [] + next: number = 0 + + constructor(private onValue: (val: string) => void) {} + + feed = (i: number, val: string) => { + this.buffer.push({ i, val }) + this.buffer = this.buffer.sort((a, b) => a.i - b.i) + + while (this.buffer.length > 0 && this.buffer[0].i === this.next) { + this.onValue(this.buffer[0].val) + this.buffer.shift() + this.next++ + } + } +} + +async function main(args: { + csv: string + topology: string + notrim: boolean + runs: number + minsign: number + maxsign: number + minidle: number + maxidle: number + cpus: number +}) { + let { csv, topology, notrim, runs, minsign, maxsign, minidle, maxidle, cpus } = args + + const disableTrim = notrim == true + console.log(`Doing benchmark with params:`) + console.log(` csv: ${csv}`) + console.log(` topology: ${topology}`) + console.log(` disableTrim: ${disableTrim}`) + console.log(` runs: ${runs}`) + console.log(` minSign: ${minsign}`) + console.log(` maxSign: ${maxsign}`) + console.log(` minIdle: ${minidle}`) + console.log(` maxIdle: ${maxidle}`) + console.log(` cpus: ${cpus}`) + + if (minidle > maxidle) throw new Error('minIdle must be <= maxIdle') + if (minsign > maxsign) throw new Error('minSign must be <= maxSign') + + const pool = Pool(() => spawn(new Worker('./workers/bench-worker')), { size: cpus }) + + const file = fs.createWriteStream(csv, { flags: 'a' }) + const fileSorter = new BufferSort((val: string) => file.write(val)) + const consoleSorter = new BufferSort((val: string) => console.log(val)) + + // Create CSV writter + let batched = 0 + file.write('topology,disableTrim,signing,idle,runs,min,max,avg,cmin,cmax,cavg\n') + for (let i = minsign; i < maxsign; i++) { + for (let j = minidle; j < maxidle - 1; j++) { + const absi = (i - minsign) * maxidle + j + + if (batched > cpus * 250) { + await pool.settled() + batched = 0 + } + batched++ + + pool.queue(async worker => { + await worker.setup(i, j, runs, topology as any, disableTrim) + const r = await worker.run() + + fileSorter.feed( + absi, + `${topology},${disableTrim},${r.signing},${r.idle},${runs},${r.min},${r.max},${r.avg},${r.data.min},${r.data.max},${r.data.avg}\n` + ) + consoleSorter.feed( + absi, + `${absi}: ${topology} (notrim ${disableTrim}): ${r.signing}/${r.signing + r.idle} (${runs}): min: ${r.min} max: ${r.max} avg: ${r.avg} cmin: ${r.data.min} cmax: ${r.data.max} cavg: ${r.data.avg}` + ) + }) + } + } + + await pool.completed() + await pool.terminate() + file.close() +} + +task('benchmark', 'Runs sequence benchmarks') + .addParam('csv', 'The CSV file to write to', `benchmark-${Math.floor(Date.now())}.csv`) + .addParam('topology', 'The wallet topology to use', 'legacy') + .addParam('runs', 'The number of runs to perform', 10, int) + .addParam('minsign', 'The start of the range of signature members who are going to sign', 1, int) + .addParam('maxsign', 'The end of the range of signature members who are going to sign', 255, int) + .addParam('minidle', 'The start of the range of idle members on the config', 0, int) + .addParam('maxidle', 'The end of the range of idle members on the config', 255, int) + .addParam('cpus', 'The number of CPUs to use', 1, int) + .addParam('notrim', 'Disable trimming of redudant signature parts', false, boolean) + .setAction(async args => { + return main(args) + }) diff --git a/packages/wallet/wallet-contracts/utils/config-loader.ts b/packages/wallet/wallet-contracts/utils/config-loader.ts new file mode 100644 index 0000000000..2714b430db --- /dev/null +++ b/packages/wallet/wallet-contracts/utils/config-loader.ts @@ -0,0 +1,159 @@ +import * as dotenv from 'dotenv' +import * as path from 'path' +import { HttpNetworkConfig } from 'hardhat/types' +import { ethers } from 'ethers' + +type EthereumNetworksTypes = + | 'mainnet' + | 'ropsten' + | 'kovan' + | 'goerli' + | 'polygon' + | 'polygon-zkevm' + | 'mumbai' + | 'arbitrum' + | 'arbitrum-goerli' + | 'arbitrum-nova' + | 'optimism' + | 'bnb' + | 'bnb-testnet' + | 'gnosis' + | 'avalanche' + | 'avalanche-fuji' + +export const getEnvConfig = (env: string) => { + const envFile = path.resolve(__dirname, `../config/${env}.env`) + const envLoad = dotenv.config({ path: envFile }) + + if (envLoad.error) { + return { ETH_MNEMONIC: 'client vendor advice erosion deny cute tree fatal fuel bless simple speed' } + } + + return envLoad.parsed || {} +} + +export const networkGasMultiplier = (network: EthereumNetworksTypes): number => { + switch (network) { + default: + return 1 + } +} + +export const networkRpcUrl = (network: EthereumNetworksTypes): string => { + const config = getEnvConfig('PROD') + + switch (network) { + case 'mumbai': + return 'https://endpoints.omniatech.io/v1/matic/mumbai/public' + + case 'polygon': + return 'https://nodes.sequence.app/polygon' + + case 'polygon-zkevm': + return 'https://zkevm-rpc.com' + + case 'arbitrum': + return 'https://endpoints.omniatech.io/v1/arbitrum/one/public' + + case 'arbitrum-goerli': + return 'https://goerli-rollup.arbitrum.io/rpc' + + case 'arbitrum-nova': + return 'https://nova.arbitrum.io/rpc' + + case 'optimism': + return 'https://endpoints.omniatech.io/v1/op/mainnet/public' + + case 'bnb': + return 'https://bsc-dataseed3.binance.org' + + case 'bnb-testnet': + return 'https://endpoints.omniatech.io/v1/bsc/testnet/public' + + case 'gnosis': + return 'https://gnosis-mainnet.public.blastapi.io' + + case 'avalanche': + return 'https://endpoints.omniatech.io/v1/avax/mainnet/public' + + case 'avalanche-fuji': + return 'https://endpoints.omniatech.io/v1/avax/fuji/public' + + default: + return `https://${network}.infura.io/v3/${config['INFURA_API_KEY']}` + } +} + +export const networkChainId = (network: EthereumNetworksTypes): number => { + switch (network) { + case 'mainnet': + return 1 + + case 'ropsten': + return 3 + + case 'goerli': + return 5 + + case 'kovan': + return 42 + + case 'mumbai': + return 80001 + + case 'polygon': + return 137 + + case 'polygon-zkevm': + return 1101 + + case 'arbitrum': + return 42161 + + case 'arbitrum-goerli': + return 421613 + + case 'arbitrum-nova': + return 42170 + + case 'optimism': + return 10 + + case 'bnb': + return 56 + + case 'bnb-testnet': + return 97 + + case 'gnosis': + return 100 + + case 'avalanche': + return 43114 + + case 'avalanche-fuji': + return 43113 + } +} + +export const networkConfig = (network: EthereumNetworksTypes): HttpNetworkConfig & { etherscan?: string } => { + const prodConfig = getEnvConfig('PROD') + const networkConfig = getEnvConfig(network) + return { + url: networkRpcUrl(network), + chainId: networkChainId(network), + accounts: { + mnemonic: networkConfig['ETH_MNEMONIC'] ?? prodConfig['ETH_MNEMONIC'], + initialIndex: 0, + count: 10, + path: `m/44'/60'/0'/0`, + passphrase: '' + }, + gas: 'auto', + gasPrice: 'auto', + gasMultiplier: networkGasMultiplier(network), + timeout: 20000, + httpHeaders: {}, + etherscan: networkConfig['ETHERSCAN'] ?? prodConfig['ETHERSCAN'] + } +} diff --git a/packages/wallet/wallet-contracts/utils/deploy-contracts.ts b/packages/wallet/wallet-contracts/utils/deploy-contracts.ts new file mode 100644 index 0000000000..8249398cd7 --- /dev/null +++ b/packages/wallet/wallet-contracts/utils/deploy-contracts.ts @@ -0,0 +1,207 @@ +import { network, run, tenderly, ethers as hethers } from 'hardhat' +import ora from 'ora' + +import { + MainModule__factory, + SequenceUtils__factory, + MainModuleUpgradable__factory, + GuestModule__factory, + Factory__factory, + TrustFactory__factory +} from '../gen/typechain' + +import { ContractDeployTransaction, ContractFactory, Signer, ethers } from 'ethers' +import fs from 'fs' + +const provider = hethers.provider + +const singletonFactoryFactory = { + address: '0xce0042B868300000d44A59004Da54A005ffdcf9f', + abi: [ + { + constant: false, + inputs: [ + { + internalType: 'bytes', + type: 'bytes' + }, + { + internalType: 'bytes32', + type: 'bytes32' + } + ], + name: 'deploy', + outputs: [ + { + internalType: 'address payable', + type: 'address' + } + ], + payable: false, + stateMutability: 'nonpayable', + type: 'function' + } + ] +} +const singletonFactoryDeployTx = + '0xf9016c8085174876e8008303c4d88080b90154608060405234801561001057600080fd5b50610134806100206000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c80634af63f0214602d575b600080fd5b60cf60048036036040811015604157600080fd5b810190602081018135640100000000811115605b57600080fd5b820183602082011115606c57600080fd5b80359060200191846001830284011164010000000083111715608d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550509135925060eb915050565b604080516001600160a01b039092168252519081900360200190f35b6000818351602085016000f5939250505056fea26469706673582212206b44f8a82cb6b156bfcc3dc6aadd6df4eefd204bc928a4397fd15dacf6d5320564736f6c634300060200331b83247000822470' +const singletonFactoryDeployer = '0xBb6e024b9cFFACB947A71991E386681B1Cd1477D' + +const prompt = ora() +const attempVerify = async ( + name: string, + _: new () => T, + address: string, + ...args: Parameters +) => { + try { + await run('verify:verify', { + address: address, + constructorArguments: args + }) + } catch {} + + try { + await tenderly.verify({ + name: name, + address: address + }) + } catch {} +} + +const buildNetworkJson = (...contracts: { name: string; address: string }[]) => { + return contracts.map(c => ({ + contractName: c.name, + address: c.address + })) +} + +const deploy = async ( + name: string, + contract: new (...args: [signer?: Signer]) => ContractFactory, + ...args: any[] +): Promise => { + const signer = await provider.getSigner(0) + const singletonFactory = new ethers.Contract(singletonFactoryFactory.address, singletonFactoryFactory.abi, signer) + + if (ethers.getBytes(await provider.getCode(await singletonFactory.getAddress())).length <= 2) { + // Deploy singleton deployer + const o = ora().start(`Deploying singleton factory`) + const deployerBal = 24700000000000000n + if ((await provider.getBalance(singletonFactoryDeployer)) < deployerBal) { + o.info('Funding singleton factory deployer') + const tx = await signer.sendTransaction({ + to: singletonFactoryDeployer, + value: deployerBal + }) + await tx.wait() + o.info('Funded. Deploying singleton factory') + } + const tx = await provider.broadcastTransaction(singletonFactoryDeployTx) + await tx.wait() + o.succeed(`Deployed singleton factory`) + } + + const o = ora().start(`Deploying ${name}`) + const c = new contract(signer) + const { data } = await c.getDeployTransaction(...args) + + if (!data) { + throw new Error(`no data for ${name}`) + } + + const maxGasLimit = await provider.getBlock('latest').then(b => (b!.gasLimit * 4n) / 10n) + + const address = ethers.getAddress( + ethers.dataSlice( + ethers.keccak256( + ethers.solidityPacked( + ['bytes1', 'address', 'bytes32', 'bytes32'], + ['0xff', await singletonFactory.getAddress(), ethers.ZeroHash, ethers.keccak256(data)] + ) + ), + 12 + ) + ) + + if (ethers.getBytes(await provider.getCode(address)).length > 0) { + o.succeed(`Skipping ${name} because it has been deployed at ${address}`) + return c.attach(address) + } + + await singletonFactory.deploy(data, ethers.ZeroHash, { gasLimit: maxGasLimit }).then(tx => tx.wait()) + + if (ethers.getBytes(await provider.getCode(address)).length === 0) { + throw new Error(`failed to deploy ${name}`) + } + + o.succeed(`Deployed ${name} at ${address}`) + + return c.attach(address) +} + +const main = async () => { + const signer = await provider.getSigner(0) + const address = await signer.getAddress() + prompt.info(`Network Name: ${network.name}`) + prompt.info(`Local Deployer Address: ${address}`) + prompt.info(`Local Deployer Balance: ${await provider.getBalance(address)}`) + + const walletFactory = await deploy('Factory', Factory__factory) + const mainModuleUpgradeable = await deploy('MainModuleUpgradable', MainModuleUpgradable__factory) + const mainModule = await deploy( + 'MainModule', + MainModule__factory, + await walletFactory.getAddress(), + await mainModuleUpgradeable.getAddress() + ) + const guestModule = await deploy('GuestModule', GuestModule__factory) + const sequenceUtils = await deploy('SequenceUtils', SequenceUtils__factory) + const trustFactory = await deploy('TrustFactory', TrustFactory__factory) + + prompt.start(`writing deployment information to ${network.name}.json`) + fs.writeFileSync( + `./networks/${network.name}.json`, + JSON.stringify( + buildNetworkJson( + { name: 'WalletFactory', address: await walletFactory.getAddress() }, + { name: 'MainModule', address: await mainModule.getAddress() }, + { name: 'MainModuleUpgradable', address: await mainModuleUpgradeable.getAddress() }, + { name: 'GuestModule', address: await guestModule.getAddress() }, + { name: 'SequenceUtils', address: await sequenceUtils.getAddress() }, + { name: 'TrustFactory', address: await trustFactory.getAddress() } + ), + null, + 2 + ) + ) + prompt.succeed() + + prompt.start(`verifying contracts`) + + await attempVerify('Factory', Factory__factory, await walletFactory.getAddress()) + await attempVerify('MainModuleUpgradable', MainModuleUpgradable__factory, await mainModuleUpgradeable.getAddress()) + await attempVerify( + 'MainModule', + MainModule__factory, + await mainModule.getAddress(), + await walletFactory.getAddress(), + await mainModuleUpgradeable.getAddress() + ) + await attempVerify('GuestModule', GuestModule__factory, await guestModule.getAddress()) + await attempVerify('SequenceUtils', SequenceUtils__factory, await sequenceUtils.getAddress()) + await attempVerify('TrustFactory', TrustFactory__factory, await trustFactory.getAddress()) + + prompt.succeed() +} + +// We recommend this pattern to be able to use async/await everywhere +// and properly handle errors. +main() + .then(() => { + process.exit(0) + }) + .catch(error => { + console.error(error) + process.exit(1) + }) diff --git a/packages/wallet/wallet-contracts/utils/workers/bench-worker.ts b/packages/wallet/wallet-contracts/utils/workers/bench-worker.ts new file mode 100644 index 0000000000..fc8bd1446c --- /dev/null +++ b/packages/wallet/wallet-contracts/utils/workers/bench-worker.ts @@ -0,0 +1,89 @@ +import { deploySequenceContext, SequenceContext } from '../../test/utils/contracts' +import { expose } from 'threads/worker' +import { SequenceWallet } from '../../test/utils/wallet' +import { ethers } from 'ethers' +import { legacyTopology, merkleTopology } from '../../test/utils/sequence' + +let context: SequenceContext +let wallet: SequenceWallet + +let d_runs: number +let d_idle: number +let d_signing: number +let d_disableTrim: boolean + +let topologyConverter: any + +let prevsnapshot: any + +function report2(values: ethers.BigNumberish[]) { + const bns = values.map(v => BigInt(v)) + + const min = bns.reduce((a, b) => (a < b ? a : b)) + const max = bns.reduce((a, b) => (a > b ? a : b)) + const avg = bns.reduce((p, n) => (p + n) / BigInt(values.length)) + + return { min, max, avg } +} + +const worker = { + async setup(signing: number, idle: number, runs: number, topology: 'legacy' | 'merkle', disableTrim: boolean) { + if (!context) { + context = await deploySequenceContext() + } + + d_runs = runs + d_idle = idle + d_signing = signing + d_disableTrim = disableTrim + + if (topology !== 'legacy' && topology !== 'merkle') throw new Error('Invalid topology') + topologyConverter = topology === 'legacy' ? legacyTopology : merkleTopology + }, + async run() { + const results: ethers.BigNumberish[] = [] + const calldatas: ethers.BigNumberish[] = [] + + for (let i = 0; i < d_runs; i++) { + wallet = SequenceWallet.basicWallet(context, { + signing: d_signing, + idle: d_idle, + topologyConverter, + encodingOptions: { disableTrim: d_disableTrim } + }) + await wallet.deploy() + + const signature = await wallet.signTransactions([{}]) + const tx = await wallet.relayTransactions([{}], signature) + const receipt = await tx.wait() + + if (!receipt) { + throw new Error('No receipt') + } + + results.push(receipt.gasUsed) + calldatas.push(ethers.getBytes(signature).length) + } + + const report = report2(results) + const reportCalldata = report2(calldatas) + + return { + min: Number(report.min), + max: Number(report.max), + avg: Number(report.avg), + data: { + min: Number(reportCalldata.min), + max: Number(reportCalldata.max), + avg: Number(reportCalldata.avg) + }, + idle: d_idle, + signing: d_signing, + runs: d_runs + } + } +} + +export type BenchWorker = typeof worker + +expose(worker) diff --git a/packages/wallet/wdk/.env.test b/packages/wallet/wdk/.env.test new file mode 100644 index 0000000000..84a53e8c03 --- /dev/null +++ b/packages/wallet/wdk/.env.test @@ -0,0 +1,5 @@ +PRIVATE_KEY= +# When using an RPC, use cors-anywhere. docker run -d -p 8080:8080 redocly/cors-anywhere. http://localhost:8080/https... +RPC_URL= +RELAYER_PK= + diff --git a/packages/wallet/wdk/CHANGELOG.md b/packages/wallet/wdk/CHANGELOG.md index 795eb18aea..47bc13af2c 100644 --- a/packages/wallet/wdk/CHANGELOG.md +++ b/packages/wallet/wdk/CHANGELOG.md @@ -1,5 +1,17 @@ # @0xsequence/wallet-wdk +## 3.0.10 + +### Patch Changes + +- Minor network updates, relayer interface +- Updated dependencies + - @0xsequence/guard@3.0.10 + - @0xsequence/identity-instrument@3.0.10 + - @0xsequence/relayer@3.0.10 + - @0xsequence/wallet-core@3.0.10 + - @0xsequence/wallet-primitives@3.0.10 + ## 3.0.9 ### Patch Changes diff --git a/packages/wallet/wdk/package.json b/packages/wallet/wdk/package.json index 547bc15c31..65a237c553 100644 --- a/packages/wallet/wdk/package.json +++ b/packages/wallet/wdk/package.json @@ -1,6 +1,6 @@ { "name": "@0xsequence/wallet-wdk", - "version": "3.0.9", + "version": "3.0.10", "license": "Apache-2.0", "type": "module", "publishConfig": { diff --git a/packages/wallet/wdk/src/dbs/auth-commitments.ts b/packages/wallet/wdk/src/dbs/auth-commitments.ts index 613d4bd574..a12826a0c8 100644 --- a/packages/wallet/wdk/src/dbs/auth-commitments.ts +++ b/packages/wallet/wdk/src/dbs/auth-commitments.ts @@ -10,7 +10,7 @@ export type CommitAuthArgs = export type AuthCommitment = { id: string - kind: 'google-pkce' | 'apple' | `custom-${string}` + kind: 'google-pkce' | 'apple' metadata: { [key: string]: string } verifier?: string challenge?: string diff --git a/packages/wallet/wdk/src/identity/signer.ts b/packages/wallet/wdk/src/identity/signer.ts index 0cb74bbbd6..41b4f676d2 100644 --- a/packages/wallet/wdk/src/identity/signer.ts +++ b/packages/wallet/wdk/src/identity/signer.ts @@ -22,7 +22,7 @@ export function toIdentityAuthKey(authKey: AuthKey, crypto?: CryptoLike): Identi hash: 'SHA-256', }, authKey.privateKey, - new Uint8Array(digest), + digest, ) return Hex.fromBytes(new Uint8Array(authKeySignature)) }, diff --git a/packages/wallet/wdk/src/sequence/guards.ts b/packages/wallet/wdk/src/sequence/guards.ts index a005a16190..c46f670904 100644 --- a/packages/wallet/wdk/src/sequence/guards.ts +++ b/packages/wallet/wdk/src/sequence/guards.ts @@ -1,8 +1,8 @@ -import { Address, Bytes } from 'ox' +import { Address, Secp256k1 } from 'ox' import { Shared } from './manager.js' import * as Guard from '@0xsequence/guard' import { Signers } from '@0xsequence/wallet-core' -import { Config, Constants } from '@0xsequence/wallet-primitives' +import { Config } from '@0xsequence/wallet-primitives' export type GuardRole = 'wallet' | 'sessions' @@ -28,28 +28,17 @@ export class Guards { return undefined } - topology(role: GuardRole): Config.Topology | undefined { + topology(role: GuardRole): Config.NestedLeaf | undefined { const guardAddress = this.shared.sequence.guardAddresses[role] if (!guardAddress) { return undefined } - const topology = Config.replaceAddress( - this.shared.sequence.defaultGuardTopology, - Constants.PlaceholderAddress, - guardAddress, - ) - - // If the imageHash did not change it means the replacement failed - if ( - Bytes.isEqual( - Config.hashConfiguration(topology), - Config.hashConfiguration(this.shared.sequence.defaultGuardTopology), - ) - ) { - throw new Error(`Guard address replacement failed for role ${role}`) + return { + type: 'nested', + weight: 1n, + threshold: 1n, + tree: { ...this.shared.sequence.defaultGuardTopology, address: guardAddress }, } - - return topology } } diff --git a/packages/wallet/wdk/src/sequence/handlers/guard.ts b/packages/wallet/wdk/src/sequence/handlers/guard.ts index b495c95d8b..26e56c98cc 100644 --- a/packages/wallet/wdk/src/sequence/handlers/guard.ts +++ b/packages/wallet/wdk/src/sequence/handlers/guard.ts @@ -1,30 +1,25 @@ import { Address, Hex } from 'ox' import * as Guard from '@0xsequence/guard' -import { Signers } from '@0xsequence/wallet-core' import { Handler } from './handler.js' import { BaseSignatureRequest, SignerUnavailable, SignerReady, SignerActionable, Kinds } from '../types/index.js' import { Signatures } from '../signatures.js' -import { Guards } from '../guards.js' - -type RespondFn = (token: Signers.GuardToken) => Promise - -export type PromptCodeHandler = ( - request: BaseSignatureRequest, - codeType: 'TOTP' | 'PIN', - respond: RespondFn, -) => Promise +import { GuardRole, Guards } from '../guards.js' export class GuardHandler implements Handler { kind = Kinds.Guard - private onPromptCode: undefined | PromptCodeHandler + private onPromptCode: + | undefined + | ((codeType: 'TOTP' | 'PIN', respond: (code: string) => Promise) => Promise) constructor( private readonly signatures: Signatures, private readonly guards: Guards, ) {} - public registerUI(onPromptCode: PromptCodeHandler) { + public registerUI( + onPromptCode: (codeType: 'TOTP' | 'PIN', respond: (code: string) => Promise) => Promise, + ) { this.onPromptCode = onPromptCode return () => { this.onPromptCode = undefined @@ -96,13 +91,17 @@ export class GuardHandler implements Handler { resolve(true) } catch (e) { if (e instanceof Guard.AuthRequiredError) { - const respond: RespondFn = async (token) => { - const signature = await guard.signEnvelope(request.envelope, token) - await this.signatures.addSignature(request.id, signature) - resolve(true) + const respond = async (code: string) => { + try { + const signature = await guard.signEnvelope(request.envelope, { id: e.id, code }) + await this.signatures.addSignature(request.id, signature) + resolve(true) + } catch (e) { + reject(e) + } } - await onPromptCode(request, e.id, respond) + await onPromptCode(e.id, respond) } else { reject(e) } diff --git a/packages/wallet/wdk/src/sequence/handlers/otp.ts b/packages/wallet/wdk/src/sequence/handlers/otp.ts index 42bf85c9e4..f44e7b54a9 100644 --- a/packages/wallet/wdk/src/sequence/handlers/otp.ts +++ b/packages/wallet/wdk/src/sequence/handlers/otp.ts @@ -12,18 +12,16 @@ import type { WdkEnv } from '../../env.js' type RespondFn = (otp: string) => Promise -export type PromptOtpHandler = (recipient: string, respond: RespondFn) => Promise - export class OtpHandler extends IdentityHandler implements Handler { kind = Kinds.LoginEmailOtp - private onPromptOtp: undefined | PromptOtpHandler + private onPromptOtp: undefined | ((recipient: string, respond: RespondFn) => Promise) constructor(nitro: Identity.IdentityInstrument, signatures: Signatures, authKeys: Db.AuthKeys, env?: WdkEnv) { super(nitro, authKeys, signatures, Identity.IdentityType.Email, env) } - public registerUI(onPromptOtp: PromptOtpHandler) { + public registerUI(onPromptOtp: (recipient: string, respond: RespondFn) => Promise) { this.onPromptOtp = onPromptOtp return () => { this.onPromptOtp = undefined @@ -94,14 +92,14 @@ export class OtpHandler extends IdentityHandler implements Handler { private handleAuth( challenge: Identity.OtpChallenge, - onPromptOtp: PromptOtpHandler, + onPromptOtp: (recipient: string, respond: RespondFn) => Promise, ): Promise<{ signer: Signers.Signer & Signers.Witnessable; email: string }> { // eslint-disable-next-line no-async-promise-executor return new Promise(async (resolve, reject) => { try { const { loginHint, challenge: codeChallenge } = await this.nitroCommitVerifier(challenge) - const respond: RespondFn = async (otp) => { + const respond = async (otp: string) => { try { const { signer, email: returnedEmail } = await this.nitroCompleteAuth( challenge.withAnswer(codeChallenge, otp), diff --git a/packages/wallet/wdk/src/sequence/transactions.ts b/packages/wallet/wdk/src/sequence/transactions.ts index 146d669998..948ecc720e 100644 --- a/packages/wallet/wdk/src/sequence/transactions.ts +++ b/packages/wallet/wdk/src/sequence/transactions.ts @@ -1,5 +1,4 @@ -import { Envelope, Wallet, Bundler } from '@0xsequence/wallet-core' -import { Relayer } from '@0xsequence/relayer' +import { Envelope, Relayer, Wallet } from '@0xsequence/wallet-core' import { Constants, Payload } from '@0xsequence/wallet-primitives' import { Abi, AbiFunction, Address, Hex, Provider, RpcTransport } from 'ox' import { v7 as uuidv7 } from 'uuid' @@ -180,13 +179,11 @@ export class Transactions implements TransactionsInterface { } if (tx.status === 'relayed') { - let relayer: Relayer.Relayer | Bundler.Bundler | undefined = this.shared.sequence.relayers.find( + let relayer: Relayer.Relayer | Relayer.Bundler | undefined = this.shared.sequence.relayers.find( (relayer) => relayer.id === tx.relayerId, ) if (!relayer) { - const bundler: Bundler.Bundler | undefined = this.shared.sequence.bundlers.find( - (bundler) => bundler.id === tx.relayerId, - ) + const bundler = this.shared.sequence.bundlers.find((bundler) => bundler.id === tx.relayerId) if (!bundler) { console.warn('relayer or bundler not found', tx.id, tx.relayerId) continue @@ -363,7 +360,7 @@ export class Transactions implements TransactionsInterface { ) if (feeOptions.options.length === 0) { - const { name, icon } = relayer instanceof Relayer.EIP6963.EIP6963Relayer ? relayer.info : {} + const { name, icon } = relayer instanceof Relayer.Standard.EIP6963.EIP6963Relayer ? relayer.info : {} return [ { @@ -377,7 +374,7 @@ export class Transactions implements TransactionsInterface { ] } - return feeOptions.options.map((feeOption: Relayer.FeeOption) => ({ + return feeOptions.options.map((feeOption) => ({ kind: 'standard', id: uuidv7(), feeOption, @@ -394,7 +391,7 @@ export class Transactions implements TransactionsInterface { } return Promise.all( - this.shared.sequence.bundlers.map(async (bundler: Bundler.Bundler): Promise => { + this.shared.sequence.bundlers.map(async (bundler): Promise => { const ifAvailable = await bundler.isAvailable(entrypoint, tx.envelope.chainId) if (!ifAvailable) { return [] @@ -596,7 +593,7 @@ export class Transactions implements TransactionsInterface { await this.shared.modules.signatures.complete(signature.id) } else if (isERC4337RelayerOption(tx.relayerOption)) { - if (!Bundler.isBundler(relayer)) { + if (!Relayer.isBundler(relayer)) { throw new Error(`Relayer ${tx.relayerOption.relayerId} is not a bundler`) } diff --git a/packages/wallet/wdk/src/sequence/types/module.ts b/packages/wallet/wdk/src/sequence/types/module.ts index 014a97ae69..df254a6482 100644 --- a/packages/wallet/wdk/src/sequence/types/module.ts +++ b/packages/wallet/wdk/src/sequence/types/module.ts @@ -3,5 +3,5 @@ import { Config } from '@0xsequence/wallet-primitives' export type Module = { weight: bigint sapientLeaf: Config.SapientSignerLeaf - guardLeaf?: Config.Topology + guardLeaf?: Config.NestedLeaf } diff --git a/packages/wallet/wdk/src/sequence/types/signer.ts b/packages/wallet/wdk/src/sequence/types/signer.ts index eb46db52fd..0e431c26c0 100644 --- a/packages/wallet/wdk/src/sequence/types/signer.ts +++ b/packages/wallet/wdk/src/sequence/types/signer.ts @@ -12,7 +12,7 @@ export const Kinds = { Unknown: 'unknown', } as const -export type Kind = (typeof Kinds)[keyof typeof Kinds] | `custom-${string}` +export type Kind = (typeof Kinds)[keyof typeof Kinds] export type WitnessExtraSignerKind = { signerKind: string diff --git a/packages/wallet/wdk/src/sequence/types/transaction-request.ts b/packages/wallet/wdk/src/sequence/types/transaction-request.ts index 51160a0499..289bf5b645 100644 --- a/packages/wallet/wdk/src/sequence/types/transaction-request.ts +++ b/packages/wallet/wdk/src/sequence/types/transaction-request.ts @@ -1,7 +1,6 @@ -import { Envelope } from '@0xsequence/wallet-core' +import { Envelope, Relayer } from '@0xsequence/wallet-core' import { Payload } from '@0xsequence/wallet-primitives' import { Address, Hex } from 'ox' -import { Relayer } from '@0xsequence/relayer' export type TransactionRequest = { to: Address.Address diff --git a/packages/wallet/wdk/test/identity-auth-dbs.test.ts b/packages/wallet/wdk/test/identity-auth-dbs.test.ts index bba408ef36..bfb61e4680 100644 --- a/packages/wallet/wdk/test/identity-auth-dbs.test.ts +++ b/packages/wallet/wdk/test/identity-auth-dbs.test.ts @@ -1,7 +1,9 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { Manager } from '../src/sequence/index.js' -import * as Db from '../src/dbs/index.js' -import { LOCAL_RPC_URL } from './constants.js' +import { Manager } from '../src/sequence' +import { Address, Hex, Bytes } from 'ox' +import { IdentityInstrument } from '@0xsequence/identity-instrument' +import * as Db from '../src/dbs' +import { LOCAL_RPC_URL } from './constants' import { State } from '@0xsequence/wallet-core' import { Network } from '@0xsequence/wallet-primitives' diff --git a/packages/wallet/wdk/test/messages.test.ts b/packages/wallet/wdk/test/messages.test.ts index 32d68ffe5e..9420ca0004 100644 --- a/packages/wallet/wdk/test/messages.test.ts +++ b/packages/wallet/wdk/test/messages.test.ts @@ -1,7 +1,7 @@ import { afterEach, beforeEach, describe, expect, it } from 'vitest' -import { Manager, SignerActionable } from '../src/sequence/index.js' +import { Manager, SignerActionable } from '../src/sequence' import { Mnemonic } from 'ox' -import { newManager } from './constants.js' +import { newManager } from './constants' import { Network } from '@0xsequence/wallet-primitives' describe('Messages', () => { @@ -41,13 +41,12 @@ describe('Messages', () => { // Verify message appears in list const messages = await manager.messages.list() expect(messages.length).toBe(1) - const message = messages[0]! - expect(message.wallet).toBe(wallet) - expect(message.message).toBe(testMessage) - expect(message.status).toBe('requested') - expect(message.signatureId).toBe(signatureId) - expect(message.source).toBe('unknown') - expect(message.id).toBeDefined() + expect(messages[0].wallet).toBe(wallet) + expect(messages[0].message).toBe(testMessage) + expect(messages[0].status).toBe('requested') + expect(messages[0].signatureId).toBe(signatureId) + expect(messages[0].source).toBe('unknown') + expect(messages[0].id).toBeDefined() }) it('Should create message request with custom source', async () => { @@ -64,11 +63,8 @@ describe('Messages', () => { const messages = await manager.messages.list() expect(messages.length).toBe(1) - - const message = messages[0]! - - expect(message.source).toBe(customSource) - expect(message.message).toBe(testMessage) + expect(messages[0].source).toBe(customSource) + expect(messages[0].message).toBe(testMessage) }) it('Should get message by ID', async () => { @@ -83,7 +79,7 @@ describe('Messages', () => { const messages = await manager.messages.list() expect(messages.length).toBe(1) - const messageId = messages[0]!.id + const messageId = messages[0].id // Get by message ID const retrievedMessage = await manager.messages.get(messageId) @@ -273,7 +269,7 @@ describe('Messages', () => { const signatureId = await manager.messages.request(wallet!, testMessage) const messages = await manager.messages.list() - const messageId = messages[0]!.id + const messageId = messages[0].id let updateCallCount = 0 let lastMessage: any @@ -319,7 +315,7 @@ describe('Messages', () => { await manager.messages.request(wallet!, testMessage) const messages = await manager.messages.list() - const messageId = messages[0]!.id + const messageId = messages[0].id let callCount = 0 let receivedMessage: any diff --git a/packages/wallet/wdk/test/passkeys.test.ts b/packages/wallet/wdk/test/passkeys.test.ts index e73d0f4e3a..6c21f67b84 100644 --- a/packages/wallet/wdk/test/passkeys.test.ts +++ b/packages/wallet/wdk/test/passkeys.test.ts @@ -3,10 +3,10 @@ import { Address, Hex } from 'ox' import { Network, Payload } from '@0xsequence/wallet-primitives' import { State } from '@0xsequence/wallet-core' import { Extensions } from '@0xsequence/wallet-primitives' -import { PasskeysHandler } from '../src/sequence/handlers/passkeys.js' -import { Signatures } from '../src/sequence/signatures.js' -import { BaseSignatureRequest } from '../src/sequence/types/signature-request.js' -import { Kinds } from '../src/sequence/types/signer.js' +import { PasskeysHandler } from '../src/sequence/handlers/passkeys' +import { Signatures } from '../src/sequence/signatures' +import { BaseSignatureRequest } from '../src/sequence/types/signature-request' +import { Kinds } from '../src/sequence/types/signer' // Mock dependencies with proper vi.fn() types const mockAddSignature = vi.fn() diff --git a/packages/wallet/wdk/test/recovery.test.ts b/packages/wallet/wdk/test/recovery.test.ts index ebaab9d3a5..5aae78cec2 100644 --- a/packages/wallet/wdk/test/recovery.test.ts +++ b/packages/wallet/wdk/test/recovery.test.ts @@ -1,8 +1,8 @@ import { describe, expect, it } from 'vitest' -import { QueuedRecoveryPayload, SignerReady, TransactionDefined } from '../src/sequence/index.js' +import { Manager, QueuedRecoveryPayload, SignerReady, TransactionDefined } from '../src/sequence' import { Bytes, Hex, Mnemonic, Provider, RpcTransport } from 'ox' import { Network, Payload } from '@0xsequence/wallet-primitives' -import { LOCAL_RPC_URL, newManager } from './constants.js' +import { LOCAL_RPC_URL, newManager } from './constants' describe('Recovery', () => { it('Should execute a recovery', async () => { @@ -159,7 +159,7 @@ describe('Recovery', () => { expect(tx.status).toBe('defined') expect((tx as TransactionDefined).relayerOptions.length).toBe(1) - const localRelayer = (tx as TransactionDefined).relayerOptions[0]! + const localRelayer = (tx as TransactionDefined).relayerOptions[0] expect(localRelayer).toBeDefined() expect(localRelayer.relayerId).toBe('local') @@ -332,7 +332,7 @@ describe('Recovery', () => { expect(Array.isArray(fetchedPayloads)).toBeTruthy() expect(fetchedPayloads.length).toBe(1) - const fetchedPayload = fetchedPayloads[0]! + const fetchedPayload = fetchedPayloads[0] expect(fetchedPayload).toBeDefined() expect(fetchedPayload.wallet).toBe(wallet) expect(fetchedPayload.chainId).toBe(Network.ChainId.ARBITRUM) @@ -390,8 +390,8 @@ describe('Recovery', () => { expect(updatedPayloads.length).toBe(fetchedPayloads2.length) if (updatedPayloads.length > 0 && fetchedPayloads.length > 0) { - const updated = updatedPayloads[0]! - const fetched = fetchedPayloads[0]! + const updated = updatedPayloads[0] + const fetched = fetchedPayloads[0] expect(updated.id).toBe(fetched.id) expect(updated.wallet).toBe(fetched.wallet) diff --git a/packages/wallet/wdk/test/setup.ts b/packages/wallet/wdk/test/setup.ts index 4aa336a55a..70482040c0 100644 --- a/packages/wallet/wdk/test/setup.ts +++ b/packages/wallet/wdk/test/setup.ts @@ -14,7 +14,7 @@ import { } from 'fake-indexeddb' import { Provider, RpcTransport } from 'ox' import { vi } from 'vitest' -import { LOCAL_RPC_URL } from './constants.js' +import { LOCAL_RPC_URL } from './constants' // Add IndexedDB support to the test environment using fake-indexeddb global.indexedDB = indexedDB diff --git a/packages/wallet/wdk/test/test-ssr-safety.js b/packages/wallet/wdk/test/test-ssr-safety.mjs similarity index 50% rename from packages/wallet/wdk/test/test-ssr-safety.js rename to packages/wallet/wdk/test/test-ssr-safety.mjs index 71eb361702..55ef7723db 100644 --- a/packages/wallet/wdk/test/test-ssr-safety.js +++ b/packages/wallet/wdk/test/test-ssr-safety.mjs @@ -1,13 +1,12 @@ #!/usr/bin/env node -/* global console, process */ /** * Comprehensive SSR Safety Test (Runtime Execution) - * + * * This script tests that the entire wdk package can be imported and used in a Node.js * environment (SSR context) without throwing errors about missing window. - * + * * It executes the code at runtime to catch any SSR issues. - * + * * Run with: node test-ssr-comprehensive.mjs */ @@ -53,25 +52,24 @@ try { // Use the package name from package.json const packageName = packageJson.name console.log(`Importing ${packageName}...`) - + // Try to resolve the package const packagePath = require.resolve(packageName) console.log(` Package resolved to: ${packagePath}`) - + // Import the package wdk = await import(packageName) console.log('āœ“ Successfully imported package') console.log(' Top-level exports:', Object.keys(wdk)) + } catch (error) { // Check if it's an SSR-related error - if ( - error.message.includes('window is not defined') || - error.message.includes('window') || - error.message.includes('document is not defined') || - error.message.includes('document') || - error.message.includes('localStorage') || - error.message.includes('sessionStorage') - ) { + if (error.message.includes('window is not defined') || + error.message.includes('window') || + error.message.includes('document is not defined') || + error.message.includes('document') || + error.message.includes('localStorage') || + error.message.includes('sessionStorage')) { errors.push(`SSR ERROR: Package accesses browser globals at module load time: ${error.message}`) if (error.stack) { console.error('\nError stack:') @@ -83,7 +81,7 @@ try { console.error('Stack:', error.stack) } } - + // Don't exit immediately - let the summary show the error if (errors.length > 0) { // Skip remaining tests if import failed @@ -100,84 +98,83 @@ if (!wdk) { console.log('Skipping - package import failed') } else { async function testExports(obj, path = '', depth = 0) { - if (depth > 5) return // Prevent infinite recursion - - for (const [key, value] of Object.entries(obj)) { - const currentPath = path ? `${path}.${key}` : key - - try { - // Skip if it's a circular reference or already tested - if (value === null || value === undefined) { - continue - } - - // Test accessing the value (this executes any getters) - const accessed = value - - // Test different types - if (typeof accessed === 'function') { - // Try to get function properties - try { - const props = Object.getOwnPropertyNames(accessed) - if (props.length > 0 && depth < 3) { - // Test static properties on functions - for (const prop of props.slice(0, 3)) { - try { - const propValue = accessed[prop] - if (typeof propValue === 'object' && propValue !== null && depth < 2) { - await testExports(propValue, `${currentPath}.${prop}`, depth + 1) - } - } catch (err) { - if (err.message.includes('window') || err.message.includes('document')) { - errors.push(`${currentPath}.${prop}: ${err.message}`) - } - } - } - } - } catch (err) { - if (err.message.includes('window') || err.message.includes('document')) { - errors.push(`${currentPath}: ${err.message}`) - } - } - } else if (typeof accessed === 'object' && accessed !== null) { - // Test object properties - if (Array.isArray(accessed)) { - // Test array elements - for (let i = 0; i < Math.min(accessed.length, 3); i++) { + if (depth > 5) return // Prevent infinite recursion + + for (const [key, value] of Object.entries(obj)) { + const currentPath = path ? `${path}.${key}` : key + + try { + // Skip if it's a circular reference or already tested + if (value === null || value === undefined) { + continue + } + + // Test accessing the value (this executes any getters) + const accessed = value + + // Test different types + if (typeof accessed === 'function') { + // Try to get function properties + try { + const props = Object.getOwnPropertyNames(accessed) + if (props.length > 0 && depth < 3) { + // Test static properties on functions + for (const prop of props.slice(0, 3)) { try { - const item = accessed[i] - if (typeof item === 'object' && item !== null && depth < 3) { - await testExports(item, `${currentPath}[${i}]`, depth + 1) + const propValue = accessed[prop] + if (typeof propValue === 'object' && propValue !== null && depth < 2) { + await testExports(propValue, `${currentPath}.${prop}`, depth + 1) } } catch (err) { if (err.message.includes('window') || err.message.includes('document')) { - errors.push(`${currentPath}[${i}]: ${err.message}`) + errors.push(`${currentPath}.${prop}: ${err.message}`) } } } - } else { - // Test object properties recursively - await testExports(accessed, currentPath, depth + 1) + } + } catch (err) { + if (err.message.includes('window') || err.message.includes('document')) { + errors.push(`${currentPath}: ${err.message}`) } } - } catch (error) { - // Check if it's an SSR-related error - if ( - error.message.includes('window is not defined') || + } else if (typeof accessed === 'object' && accessed !== null) { + // Test object properties + if (Array.isArray(accessed)) { + // Test array elements + for (let i = 0; i < Math.min(accessed.length, 3); i++) { + try { + const item = accessed[i] + if (typeof item === 'object' && item !== null && depth < 3) { + await testExports(item, `${currentPath}[${i}]`, depth + 1) + } + } catch (err) { + if (err.message.includes('window') || err.message.includes('document')) { + errors.push(`${currentPath}[${i}]: ${err.message}`) + } + } + } + } else { + // Test object properties recursively + await testExports(accessed, currentPath, depth + 1) + } + } + + } catch (error) { + // Check if it's an SSR-related error + if (error.message.includes('window is not defined') || error.message.includes('window') || error.message.includes('document is not defined') || error.message.includes('document') || error.message.includes('localStorage') || - error.message.includes('sessionStorage') - ) { - errors.push(`${currentPath}: ${error.message}`) - } else { - // Other errors are warnings (might be expected, like missing dependencies) - warnings.push(`${currentPath}: ${error.message}`) - } + error.message.includes('sessionStorage')) { + errors.push(`${currentPath}: ${error.message}`) + } else { + // Other errors are warnings (might be expected, like missing dependencies) + warnings.push(`${currentPath}: ${error.message}`) } } } +} // Test all top-level exports console.log('Testing all exports recursively...') @@ -194,46 +191,43 @@ if (!wdk) { } else { // Test ManagerOptionsDefaults try { - if (wdk.Sequence?.ManagerOptionsDefaults) { - console.log('Testing ManagerOptionsDefaults...') - const defaults = wdk.Sequence.ManagerOptionsDefaults - - // Access all properties - Object.keys(defaults).forEach((key) => { - try { - const value = defaults[key] - console.log(` āœ“ ${key}: ${typeof value}`) - - // If it's a function, try calling it - if (typeof value === 'function' && key === 'relayers') { - const result = value() - console.log( - ` Called ${key}(), returned:`, - Array.isArray(result) ? `${result.length} items` : typeof result, - ) - } - } catch (err) { - if (err.message.includes('window') || err.message.includes('document')) { - errors.push(`ManagerOptionsDefaults.${key}: ${err.message}`) - } + if (wdk.Sequence?.ManagerOptionsDefaults) { + console.log('Testing ManagerOptionsDefaults...') + const defaults = wdk.Sequence.ManagerOptionsDefaults + + // Access all properties + Object.keys(defaults).forEach(key => { + try { + const value = defaults[key] + console.log(` āœ“ ${key}: ${typeof value}`) + + // If it's a function, try calling it + if (typeof value === 'function' && key === 'relayers') { + const result = value() + console.log(` Called ${key}(), returned:`, Array.isArray(result) ? `${result.length} items` : typeof result) } - }) - } - } catch (err) { - if (err.message.includes('window') || err.message.includes('document')) { - errors.push(`ManagerOptionsDefaults: ${err.message}`) - } + } catch (err) { + if (err.message.includes('window') || err.message.includes('document')) { + errors.push(`ManagerOptionsDefaults.${key}: ${err.message}`) + } + } + }) } +} catch (err) { + if (err.message.includes('window') || err.message.includes('document')) { + errors.push(`ManagerOptionsDefaults: ${err.message}`) + } +} - // Test applyManagerOptionsDefaults function - try { - if (wdk.Sequence?.applyManagerOptionsDefaults) { - console.log('Testing applyManagerOptionsDefaults...') - const result = wdk.Sequence.applyManagerOptionsDefaults() - console.log(' āœ“ Function executed successfully') - console.log(' Result keys:', Object.keys(result).slice(0, 5).join(', '), '...') - } - } catch (err) { +// Test applyManagerOptionsDefaults function +try { + if (wdk.Sequence?.applyManagerOptionsDefaults) { + console.log('Testing applyManagerOptionsDefaults...') + const result = wdk.Sequence.applyManagerOptionsDefaults() + console.log(' āœ“ Function executed successfully') + console.log(' Result keys:', Object.keys(result).slice(0, 5).join(', '), '...') + } +} catch (err) { if (err.message.includes('window') || err.message.includes('document')) { errors.push(`applyManagerOptionsDefaults: ${err.message}`) } @@ -250,37 +244,37 @@ if (!wdk) { } else { // Get the package path and try importing from dist try { - const packagePath = require.resolve(packageJson.name) - const packageDir = dirname(packagePath) - - // Try to import from the exports field if available - if (packageJson.exports) { - for (const [exportPath, exportConfig] of Object.entries(packageJson.exports)) { - if (exportPath === '.') { - const modulePath = exportConfig.default || exportConfig.types - if (modulePath) { - try { - const fullPath = join(packageDir, '..', modulePath) - console.log(`Testing import from ${exportPath}...`) - const subModule = await import(fullPath) - console.log(` āœ“ Imported successfully`) - - // Test accessing exports - const subExports = Object.keys(subModule) - if (subExports.length > 0) { - console.log(` Exports: ${subExports.slice(0, 5).join(', ')}${subExports.length > 5 ? '...' : ''}`) - } - } catch (err) { - if (err.message.includes('window') || err.message.includes('document')) { - errors.push(`Import ${exportPath}: ${err.message}`) - } else if (!err.message.includes('Cannot find module')) { - warnings.push(`Import ${exportPath}: ${err.message}`) - } + const packagePath = require.resolve(packageJson.name) + const packageDir = dirname(packagePath) + + // Try to import from the exports field if available + if (packageJson.exports) { + for (const [exportPath, exportConfig] of Object.entries(packageJson.exports)) { + if (exportPath === '.') { + const modulePath = exportConfig.default || exportConfig.types + if (modulePath) { + try { + const fullPath = join(packageDir, '..', modulePath) + console.log(`Testing import from ${exportPath}...`) + const subModule = await import(fullPath) + console.log(` āœ“ Imported successfully`) + + // Test accessing exports + const subExports = Object.keys(subModule) + if (subExports.length > 0) { + console.log(` Exports: ${subExports.slice(0, 5).join(', ')}${subExports.length > 5 ? '...' : ''}`) + } + } catch (err) { + if (err.message.includes('window') || err.message.includes('document')) { + errors.push(`Import ${exportPath}: ${err.message}`) + } else if (!err.message.includes('Cannot find module')) { + warnings.push(`Import ${exportPath}: ${err.message}`) } } } } } + } } catch (err) { warnings.push(`Could not test sub-modules: ${err.message}`) } @@ -296,7 +290,7 @@ if (errors.length === 0) { console.log('The package can be safely imported and used in a Node.js/SSR environment.') if (warnings.length > 0) { console.log(`\nāš ļø ${warnings.length} warning(s) (non-SSR related):`) - warnings.slice(0, 5).forEach((warn) => console.log(` - ${warn}`)) + warnings.slice(0, 5).forEach(warn => console.log(` - ${warn}`)) if (warnings.length > 5) { console.log(` ... and ${warnings.length - 5} more`) } @@ -304,11 +298,11 @@ if (errors.length === 0) { process.exit(0) } else { console.log('\nāŒ ERRORS FOUND:') - errors.forEach((err) => console.log(` - ${err}`)) + errors.forEach(err => console.log(` - ${err}`)) console.log('\nāŒ SSR Safety Test FAILED!') if (warnings.length > 0) { console.log(`\nāš ļø ${warnings.length} warning(s):`) - warnings.slice(0, 5).forEach((warn) => console.log(` - ${warn}`)) + warnings.slice(0, 5).forEach(warn => console.log(` - ${warn}`)) } process.exit(1) } diff --git a/packages/wallet/wdk/vitest.config.ts b/packages/wallet/wdk/vitest.config.ts index 9c2092c0c4..813dc499da 100644 --- a/packages/wallet/wdk/vitest.config.ts +++ b/packages/wallet/wdk/vitest.config.ts @@ -1,3 +1,4 @@ +import { BrowserNavigationCrossOriginPolicyEnum } from 'happy-dom' import { defineConfig } from 'vitest/config' export default defineConfig({ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1306fd11f7..7a369a88a6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -39,8 +39,8 @@ importers: specifier: workspace:^ version: link:../../repo/ui next: - specifier: ^15.5.15 - version: 15.5.15(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^15.5.16 + version: 15.5.18(react-dom@19.2.3(react@19.2.3))(react@19.2.3) react: specifier: ^19.2.3 version: 19.2.3 @@ -76,8 +76,8 @@ importers: specifier: workspace:^ version: link:../../repo/ui next: - specifier: ^15.5.15 - version: 15.5.15(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + specifier: ^15.5.16 + version: 15.5.18(react-dom@19.2.3(react@19.2.3))(react@19.2.3) react: specifier: ^19.2.3 version: 19.2.3 @@ -963,89 +963,105 @@ packages: resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} cpu: [arm64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-arm@1.2.4': resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} cpu: [arm] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-ppc64@1.2.4': resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} cpu: [ppc64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-riscv64@1.2.4': resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} cpu: [riscv64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-s390x@1.2.4': resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} cpu: [s390x] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-x64@1.2.4': resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} cpu: [x64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linuxmusl-arm64@1.2.4': resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} cpu: [arm64] os: [linux] + libc: [musl] '@img/sharp-libvips-linuxmusl-x64@1.2.4': resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} cpu: [x64] os: [linux] + libc: [musl] '@img/sharp-linux-arm64@0.34.5': resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] + libc: [glibc] '@img/sharp-linux-arm@0.34.5': resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm] os: [linux] + libc: [glibc] '@img/sharp-linux-ppc64@0.34.5': resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [ppc64] os: [linux] + libc: [glibc] '@img/sharp-linux-riscv64@0.34.5': resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [riscv64] os: [linux] + libc: [glibc] '@img/sharp-linux-s390x@0.34.5': resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [s390x] os: [linux] + libc: [glibc] '@img/sharp-linux-x64@0.34.5': resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] + libc: [glibc] '@img/sharp-linuxmusl-arm64@0.34.5': resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] + libc: [musl] '@img/sharp-linuxmusl-x64@0.34.5': resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] + libc: [musl] '@img/sharp-wasm32@0.34.5': resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} @@ -1104,56 +1120,60 @@ packages: '@manypkg/get-packages@1.1.3': resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} - '@next/env@15.5.15': - resolution: {integrity: sha512-vcmyu5/MyFzN7CdqRHO3uHO44p/QPCZkuTUXroeUmhNP8bL5PHFEhik22JUazt+CDDoD6EpBYRCaS2pISL+/hg==} + '@next/env@15.5.18': + resolution: {integrity: sha512-hAV85Ckd9QR6RvH04MEKwsfLTksvFpO47j9xwtoIuvuPnlwecpSi+uZTtm8HirVbtlI2Fnz//xpcSTjFdyJk+g==} '@next/eslint-plugin-next@15.5.9': resolution: {integrity: sha512-kUzXx0iFiXw27cQAViE1yKWnz/nF8JzRmwgMRTMh8qMY90crNsdXJRh2e+R0vBpFR3kk1yvAR7wev7+fCCb79Q==} - '@next/swc-darwin-arm64@15.5.15': - resolution: {integrity: sha512-6PvFO2Tzt10GFK2Ro9tAVEtacMqRmTarYMFKAnV2vYMdwWc73xzmDQyAV7SwEdMhzmiRoo7+m88DuiXlJlGeaw==} + '@next/swc-darwin-arm64@15.5.18': + resolution: {integrity: sha512-w0WvQf1n+txiwns/9pwIQteCJpZTbxzO2SE0FLcwuD4v0WEh1JPOjdyxWL21XwJsdpx8cFRjyzxzCS/siP7HcQ==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@next/swc-darwin-x64@15.5.15': - resolution: {integrity: sha512-G+YNV+z6FDZTp/+IdGyIMFqalBTaQSnvAA+X/hrt+eaTRFSznRMz9K7rTmzvM6tDmKegNtyzgufZW0HwVzEqaQ==} + '@next/swc-darwin-x64@15.5.18': + resolution: {integrity: sha512-znn71QmDuxm+BOaglihMZfvyySMnNljkVIY5Z2TCssBmm+WqL6c19VhtH5ktFkHa8EZ2bnTUpcNcmNSQsg67og==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@next/swc-linux-arm64-gnu@15.5.15': - resolution: {integrity: sha512-eVkrMcVIBqGfXB+QUC7jjZ94Z6uX/dNStbQFabewAnk13Uy18Igd1YZ/GtPRzdhtm7QwC0e6o7zOQecul4iC1w==} + '@next/swc-linux-arm64-gnu@15.5.18': + resolution: {integrity: sha512-yPPe5MNL+igZUa+OsqQJisqSfh6oarIuA1Q0BDxljGJhRQyZeP+WRHh7rs/jZUGMh5aY0YdIjXZG0VohkKkUdw==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [glibc] - '@next/swc-linux-arm64-musl@15.5.15': - resolution: {integrity: sha512-RwSHKMQ7InLy5GfkY2/n5PcFycKA08qI1VST78n09nN36nUPqCvGSMiLXlfUmzmpQpF6XeBYP2KRWHi0UW3uNg==} + '@next/swc-linux-arm64-musl@15.5.18': + resolution: {integrity: sha512-glaCczEWIrHsokFZ3pP08U4BpKxwIdnT+txdOM32OBgpL9Yw4aqx8NejmgtZQZOdstQ5f0L3CasIZudzCuD+nw==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [musl] - '@next/swc-linux-x64-gnu@15.5.15': - resolution: {integrity: sha512-nplqvY86LakS+eeiuWsNWvfmK8pFcOEW7ZtVRt4QH70lL+0x6LG/m1OpJ/tvrbwjmR8HH9/fH2jzW1GlL03TIg==} + '@next/swc-linux-x64-gnu@15.5.18': + resolution: {integrity: sha512-oUfg2EgJmU3R0OCOWiokGFUTvZiPfXtriXiuF3YNxRoROCdgvTedHIzYoeKH34gsZxS/V7mHbfq2hpAHwhH1/A==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [glibc] - '@next/swc-linux-x64-musl@15.5.15': - resolution: {integrity: sha512-eAgl9NKQ84/sww0v81DQINl/vL2IBxD7sMybd0cWRw6wqgouVI53brVRBrggqBRP/NWeIAE1dm5cbKYoiMlqDQ==} + '@next/swc-linux-x64-musl@15.5.18': + resolution: {integrity: sha512-JLxSP3KTd9iu/bvUMQxH7RJo9xKSHf55/6RPE4a6FTSZygGn7uvZbCej0AHXydwkggQGSD9UddSjwv6Xz5ESfA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [musl] - '@next/swc-win32-arm64-msvc@15.5.15': - resolution: {integrity: sha512-GJVZC86lzSquh0MtvZT+L7G8+jMnJcldloOjA8Kf3wXvBrvb6OGe2MzPuALxFshSm/IpwUtD2mIoof39ymf52A==} + '@next/swc-win32-arm64-msvc@15.5.18': + resolution: {integrity: sha512-ir1v7enP52K2HNz3tQQvwF+x7VNxBk1ciiZ18WBPvxf4C59IqdfmHPJYK3vH7rSxpuCVw/8C712wTXNAtEp+NA==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@next/swc-win32-x64-msvc@15.5.15': - resolution: {integrity: sha512-nFucjVdwlFqxh/JG3hWSJ4p8+YJV7Ii8aPDuBQULB6DzUF4UNZETXLfEUk+oI2zEznWWULPt7MeuTE6xtK1HSA==} + '@next/swc-win32-x64-msvc@15.5.18': + resolution: {integrity: sha512-LIu5me6QTANCd25E7I5uIEfvgQ06RK7tvHAbYo3zCb3VpxQEPvMcSpd87NwUABDT6MbGPdEGR5VRiK4PPTJhQg==} engines: {node: '>= 10'} cpu: [x64] os: [win32] @@ -1220,56 +1240,67 @@ packages: resolution: {integrity: sha512-UPMMNeC4LXW7ZSHxeP3Edv09aLsFUMaD1TSVW6n1CWMECnUIJMFFB7+XC2lZTdPtvB36tYC0cJWc86mzSsaviw==} cpu: [arm] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.53.4': resolution: {integrity: sha512-H8uwlV0otHs5Q7WAMSoyvjV9DJPiy5nJ/xnHolY0QptLPjaSsuX7tw+SPIfiYH6cnVx3fe4EWFafo6gH6ekZKA==} cpu: [arm] os: [linux] + libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.53.4': resolution: {integrity: sha512-BLRwSRwICXz0TXkbIbqJ1ibK+/dSBpTJqDClF61GWIrxTXZWQE78ROeIhgl5MjVs4B4gSLPCFeD4xML9vbzvCQ==} cpu: [arm64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.53.4': resolution: {integrity: sha512-6bySEjOTbmVcPJAywjpGLckK793A0TJWSbIa0sVwtVGfe/Nz6gOWHOwkshUIAp9j7wg2WKcA4Snu7Y1nUZyQew==} cpu: [arm64] os: [linux] + libc: [musl] '@rollup/rollup-linux-loong64-gnu@4.53.4': resolution: {integrity: sha512-U0ow3bXYJZ5MIbchVusxEycBw7bO6C2u5UvD31i5IMTrnt2p4Fh4ZbHSdc/31TScIJQYHwxbj05BpevB3201ug==} cpu: [loong64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-ppc64-gnu@4.53.4': resolution: {integrity: sha512-iujDk07ZNwGLVn0YIWM80SFN039bHZHCdCCuX9nyx3Jsa2d9V/0Y32F+YadzwbvDxhSeVo9zefkoPnXEImnM5w==} cpu: [ppc64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-riscv64-gnu@4.53.4': resolution: {integrity: sha512-MUtAktiOUSu+AXBpx1fkuG/Bi5rhlorGs3lw5QeJ2X3ziEGAq7vFNdWVde6XGaVqi0LGSvugwjoxSNJfHFTC0g==} cpu: [riscv64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-riscv64-musl@4.53.4': resolution: {integrity: sha512-btm35eAbDfPtcFEgaXCI5l3c2WXyzwiE8pArhd66SDtoLWmgK5/M7CUxmUglkwtniPzwvWioBKKl6IXLbPf2sQ==} cpu: [riscv64] os: [linux] + libc: [musl] '@rollup/rollup-linux-s390x-gnu@4.53.4': resolution: {integrity: sha512-uJlhKE9ccUTCUlK+HUz/80cVtx2RayadC5ldDrrDUFaJK0SNb8/cCmC9RhBhIWuZ71Nqj4Uoa9+xljKWRogdhA==} cpu: [s390x] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.53.4': resolution: {integrity: sha512-jjEMkzvASQBbzzlzf4os7nzSBd/cvPrpqXCUOqoeCh1dQ4BP3RZCJk8XBeik4MUln3m+8LeTJcY54C/u8wb3DQ==} cpu: [x64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-musl@4.53.4': resolution: {integrity: sha512-lu90KG06NNH19shC5rBPkrh6mrTpq5kviFylPBXQVpdEu0yzb0mDgyxLr6XdcGdBIQTH/UAhDJnL+APZTBu1aQ==} cpu: [x64] os: [linux] + libc: [musl] '@rollup/rollup-openharmony-arm64@4.53.4': resolution: {integrity: sha512-dFDcmLwsUzhAm/dn0+dMOQZoONVYBtgik0VuY/d5IJUUb787L3Ko/ibvTvddqhb3RaB7vFEozYevHN4ox22R/w==} @@ -2863,8 +2894,8 @@ packages: resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==} engines: {node: '>= 0.4.0'} - next@15.5.15: - resolution: {integrity: sha512-VSqCrJwtLVGwAVE0Sb/yikrQfkwkZW9p+lL/J4+xe+G3ZA+QnWPqgcfH1tDUEuk9y+pthzzVFp4L/U8JerMfMQ==} + next@15.5.18: + resolution: {integrity: sha512-eKL8zUJkX9Y5lE+RX/2YJoItVdGlIscyVyboeD9wSpp0PaGqjoA4tTpT2qPqz9ax+5IzGESyLSeZ/RCwbSZ2uQ==} engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} hasBin: true peerDependencies: @@ -4429,34 +4460,34 @@ snapshots: globby: 11.1.0 read-yaml-file: 1.1.0 - '@next/env@15.5.15': {} + '@next/env@15.5.18': {} '@next/eslint-plugin-next@15.5.9': dependencies: fast-glob: 3.3.1 - '@next/swc-darwin-arm64@15.5.15': + '@next/swc-darwin-arm64@15.5.18': optional: true - '@next/swc-darwin-x64@15.5.15': + '@next/swc-darwin-x64@15.5.18': optional: true - '@next/swc-linux-arm64-gnu@15.5.15': + '@next/swc-linux-arm64-gnu@15.5.18': optional: true - '@next/swc-linux-arm64-musl@15.5.15': + '@next/swc-linux-arm64-musl@15.5.18': optional: true - '@next/swc-linux-x64-gnu@15.5.15': + '@next/swc-linux-x64-gnu@15.5.18': optional: true - '@next/swc-linux-x64-musl@15.5.15': + '@next/swc-linux-x64-musl@15.5.18': optional: true - '@next/swc-win32-arm64-msvc@15.5.15': + '@next/swc-win32-arm64-msvc@15.5.18': optional: true - '@next/swc-win32-x64-msvc@15.5.15': + '@next/swc-win32-x64-msvc@15.5.18': optional: true '@noble/ciphers@1.3.0': {} @@ -6337,9 +6368,9 @@ snapshots: netmask@2.0.2: {} - next@15.5.15(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + next@15.5.18(react-dom@19.2.3(react@19.2.3))(react@19.2.3): dependencies: - '@next/env': 15.5.15 + '@next/env': 15.5.18 '@swc/helpers': 0.5.15 caniuse-lite: 1.0.30001791 postcss: 8.4.31 @@ -6347,14 +6378,14 @@ snapshots: react-dom: 19.2.3(react@19.2.3) styled-jsx: 5.1.6(react@19.2.3) optionalDependencies: - '@next/swc-darwin-arm64': 15.5.15 - '@next/swc-darwin-x64': 15.5.15 - '@next/swc-linux-arm64-gnu': 15.5.15 - '@next/swc-linux-arm64-musl': 15.5.15 - '@next/swc-linux-x64-gnu': 15.5.15 - '@next/swc-linux-x64-musl': 15.5.15 - '@next/swc-win32-arm64-msvc': 15.5.15 - '@next/swc-win32-x64-msvc': 15.5.15 + '@next/swc-darwin-arm64': 15.5.18 + '@next/swc-darwin-x64': 15.5.18 + '@next/swc-linux-arm64-gnu': 15.5.18 + '@next/swc-linux-arm64-musl': 15.5.18 + '@next/swc-linux-x64-gnu': 15.5.18 + '@next/swc-linux-x64-musl': 15.5.18 + '@next/swc-win32-arm64-msvc': 15.5.18 + '@next/swc-win32-x64-msvc': 15.5.18 sharp: 0.34.5 transitivePeerDependencies: - '@babel/core' diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 8b50aefa01..00d33353c0 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,4 +1,4 @@ -minimumReleaseAge: 20160 # 60 * 24 * 7 * 2 = do not install package releases that are not at least 2 weeks old +minimumReleaseAge: 10080 # 60 * 24 * 7 = do not install package releases that are not at least 1 week old # DO NOT REMOVE OR MODIFY minimumReleaseAge without approval # list packages to be excluded from minimum release limitation @@ -11,5 +11,61 @@ packages: - repo/* - test/* +onlyBuiltDependencies: + - '@parcel/watcher' + - '@prisma/engines' + - '@tailwindcss/oxide' + - bufferutil + - core-js-pure + - esbuild + - keccak + - lefthook + - prisma + - protobufjs + - secp256k1 + - sharp + - utf-8-validate + - web3 + - web3-bzz + +overrides: + 0xsequence.js.git: link:.local/share/pnpm/global/5/node_modules/https:/github.com/Dargon789/0xsequence.js.git + Rabby.git: link:.local/share/pnpm/global/5/node_modules/git@github.com:Dargon789/Rabby.git + braces@<3.0.3: '>=3.0.3' + cookie@<0.7.0: '>=0.7.0' + diff@<4.0.4: '>=4.0.4' + diff@>=5.0.0 <5.2.2: '>=5.2.2' + esbuild@<=0.24.2: '>=0.25.0' + fast-xml-parser@>=4.3.6 <=5.3.3: '>=5.3.4' + form-data@<2.5.4: '>=2.5.4' + happy-dom@<20.0.0: '>=20.0.0' + hardhat-project.git: link:.local/share/pnpm/global/5/node_modules/git@github.com:Dargon789/hardhat-project.git + hono@<4.11.7: '>=4.11.7' + http-proxy-middleware@<2.0.7: '>=2.0.7' + lodash@>=4.0.0 <=4.17.22: '>=4.17.23' + micromatch@<4.0.8: '>=4.0.8' + next@>=15.6.0-canary.0 <16.1.5: '>=16.1.5' + next@>=16.0.0-beta.0 <16.1.5: '>=16.1.5' + next@>=16.1.0-canary.0 <16.1.5: '>=16.1.5' + node-forge@<1.0.0: '>=1.0.0' + node-forge@<1.3.0: '>=1.3.0' + node-forge@<1.3.2: '>=1.3.2' + qs@<6.14.1: '>=6.14.1' + semver@<5.7.2: '>=5.7.2' + tar@<6.2.1: '>=6.2.1' + tar@<=7.5.2: '>=7.5.3' + thirdweb-dev.git: link:.local/share/pnpm/global/5/node_modules/git@github.com:Dargon789/thirdweb-dev.git + tmp@<=0.2.3: '>=0.2.4' + tough-cookie@<4.1.3: '>=4.1.3' + undici@<5.29.0: '>=5.29.0' + undici@<6.23.0: '>=6.23.0' + undici@>=4.5.0 <5.28.5: '>=5.28.5' + wallet-contracts.git: link:.local/share/pnpm/global/5/node_modules/https:/github.com/Dargon789/wallet-contracts.git + webpack-dev-middleware@<=5.3.3: '>=5.3.4' + webpack-dev-server@<=5.2.0: '>=5.2.1' + ws@>=2.1.0 <5.2.4: '>=5.2.4' + ws@>=8.0.0 <8.17.1: '>=8.17.1' + xml2js@<0.5.0: '>=0.5.0' + publicHoistPattern: -- "eslint" + - eslint diff --git a/remappings.txt b/remappings.txt new file mode 100644 index 0000000000..75f1f18e51 --- /dev/null +++ b/remappings.txt @@ -0,0 +1,6 @@ +@openzeppelin-contracts-5.0.2/=dependencies/@openzeppelin-contracts-5.0.2/ +forge-std-1.10.0/=dependencies/forge-std-1.10.0/ +forge-std-1.11.0/=dependencies/forge-std-1.11.0/ +forge-std-1.12.0/=dependencies/forge-std-1.12.0/ +forge-std-1.14.0/=dependencies/forge-std-1.14.0/ +forge-std-1.9.2/=dependencies/forge-std-1.9.2/ diff --git a/repo/ui/eslint.config.mjs b/repo/ui/eslint.config.mjs new file mode 100644 index 0000000000..19170f88ed --- /dev/null +++ b/repo/ui/eslint.config.mjs @@ -0,0 +1,4 @@ +import { config } from "@repo/eslint-config/react-internal"; + +/** @type {import("eslint").Linter.Config} */ +export default config; diff --git a/scripts/fix-mocha-ref.js b/scripts/fix-mocha-ref.js new file mode 100644 index 0000000000..13074cf6d6 --- /dev/null +++ b/scripts/fix-mocha-ref.js @@ -0,0 +1,43 @@ +// "mocha" package registers a global type which has proven to be next to impossible +// to exclude. As a result, `` is included in some random +// declarations, causing for applications which depend on our package to require +// @types/mocha package, which is super annoying / ridiculous. This script will +// search through dist/ folder for .d.ts files and remove any references. + +const fs = require('fs') +const path = require('path') + +const root = fs.realpathSync(process.cwd()) + +const getAllFiles = function(dirPath, arrayOfFiles) { + const files = fs.readdirSync(dirPath) + + arrayOfFiles = arrayOfFiles || [] + + files.forEach(function(file) { + if (file === 'node_modules') { + return + } + + if (fs.statSync(dirPath + "/" + file).isDirectory()) { + arrayOfFiles = getAllFiles(dirPath + "/" + file, arrayOfFiles) + } else if (file.endsWith('.d.ts')) { + arrayOfFiles.push(path.join(dirPath, "/", file)) + } + }) + + return arrayOfFiles +} + +const garbage = `/// ` + +const files = getAllFiles(root) + +files.forEach(function(file) { + let data = fs.readFileSync(file, 'utf8') + if (data.indexOf(garbage) < 0) { + return + } + data = data.replace(garbage, '') + fs.writeFileSync(file, data) +}) diff --git a/scripts/pnpm-link.sh b/scripts/pnpm-link.sh new file mode 100644 index 0000000000..baee87dc25 --- /dev/null +++ b/scripts/pnpm-link.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +set -eu + +function usage() { + echo "Usage:" + echo " $0 link" + echo " $0 unlink" + exit 1 +} + +test -z "${1-}" && usage +option="$1" +shift + +case "$option" in + "link") + ;; + "unlink") + ;; + *) + echo "$option: no such option" + usage + ;; +esac + +repo_dir=$(cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && cd .. && pwd) + +packages=($repo_dir/packages/*) +for p in "${packages[@]}" +do + x=$(realpath $p) + echo "$option $x" + pnpm $option $x +done + +exit $? diff --git a/scripts/update-version.js b/scripts/update-version.js new file mode 100644 index 0000000000..0397724d1c --- /dev/null +++ b/scripts/update-version.js @@ -0,0 +1,11 @@ +const fs = require('fs') +const path = require('path') + +const rootPath = path.resolve(__dirname, '../packages/core') +const packagePath = path.join(rootPath, 'package.json') +const packageJson = JSON.parse(fs.readFileSync(packagePath, 'utf8')) +const versionPath = path.join(rootPath, 'src', 'version.ts') + +fs.writeFileSync(versionPath, `export const VERSION = '${packageJson.version}'\n`, 'utf8') + +console.log(`Updated version to ${packageJson.version}`) diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000000..5a68d38652 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "target": "es2021", + "module": "esnext", + "moduleResolution": "node", + "declaration": true, + "esModuleInterop": true, + "resolveJsonModule": true, + "allowSyntheticDefaultImports": true, + "allowJs": true, + "strictNullChecks": true, + "noImplicitAny": true, + "noImplicitReturns": true, + "isolatedModules": true, + "forceConsistentCasingInFileNames": true, + "typeRoots": [ + "node_modules/@types" + ], + "types": [ + "node" + ] + }, + "include": ["./packages/**/src/**/*.ts"] +} diff --git a/tsconfig.test.json b/tsconfig.test.json new file mode 100644 index 0000000000..0c7b3c1e49 --- /dev/null +++ b/tsconfig.test.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "es2020", + "module": "commonjs", + "declaration": true, + "sourceMap": true, + "allowSyntheticDefaultImports": true, + "strictNullChecks": false, + "esModuleInterop": true, + "lib": ["dom.iterable", "dom", "es2020"], + "types": ["node", "mocha", "puppeteer"] + }, + "include": [ + "./src/**/*", + "./tests/**/*" + ] +} diff --git a/v8-compile-cache-0/x64/11.3.244.8-node.19/zSprojectzSsequence.jszSnode_moduleszS.pnpmzS@preconstruct+cli@2.8.7zSnode_moduleszS@preconstructzSclizSbin.js.BLOB b/v8-compile-cache-0/x64/11.3.244.8-node.19/zSprojectzSsequence.jszSnode_moduleszS.pnpmzS@preconstruct+cli@2.8.7zSnode_moduleszS@preconstructzSclizSbin.js.BLOB new file mode 100644 index 0000000000..0b31b75844 Binary files /dev/null and b/v8-compile-cache-0/x64/11.3.244.8-node.19/zSprojectzSsequence.jszSnode_moduleszS.pnpmzS@preconstruct+cli@2.8.7zSnode_moduleszS@preconstructzSclizSbin.js.BLOB differ diff --git a/v8-compile-cache-0/x64/11.3.244.8-node.19/zSprojectzSsequence.jszSnode_moduleszS.pnpmzS@preconstruct+cli@2.8.7zSnode_moduleszS@preconstructzSclizSbin.js.MAP b/v8-compile-cache-0/x64/11.3.244.8-node.19/zSprojectzSsequence.jszSnode_moduleszS.pnpmzS@preconstruct+cli@2.8.7zSnode_moduleszS@preconstructzSclizSbin.js.MAP new file mode 100644 index 0000000000..7404543529 --- /dev/null +++ b/v8-compile-cache-0/x64/11.3.244.8-node.19/zSprojectzSsequence.jszSnode_moduleszS.pnpmzS@preconstruct+cli@2.8.7zSnode_moduleszS@preconstructzSclizSbin.js.MAP @@ -0,0 +1 @@ +{"/project/sequence.js/node_modules/.pnpm/@preconstruct+cli@2.8.7/node_modules/@preconstruct/cli/cli/dist/preconstruct-cli-cli.cjs.js":["8315344ea3ec2213ef0e4aaa37b41d90c77999cb",0,32424],"/project/sequence.js/node_modules/.pnpm/meow@7.1.1/node_modules/meow/index.js":["4a866f54ed797369e8e33d78cc06f5834ee7b7be",32424,34544],"/project/sequence.js/node_modules/.pnpm/minimist-options@4.1.0/node_modules/minimist-options/index.js":["0f0bff7fe31e97f7ea78636b1aca17e841e5f8e3",34544,36360],"/project/sequence.js/node_modules/.pnpm/is-plain-obj@1.1.0/node_modules/is-plain-obj/index.js":["16523ba84e3229bcd98780b380a4f4e323b8bf8b",36360,37088],"/project/sequence.js/node_modules/.pnpm/arrify@1.0.1/node_modules/arrify/index.js":["d91a789bdf6d6e7ea9014b0b1bacfef0d7621f47",37088,37760],"/project/sequence.js/node_modules/.pnpm/kind-of@6.0.3/node_modules/kind-of/index.js":["7de61d4d1e16e0c9b04660b8904d9488727a5d02",37760,39152],"/project/sequence.js/node_modules/.pnpm/yargs-parser@18.1.3/node_modules/yargs-parser/index.js":["ace83036108f3a4eb87218d76219768fee3520ed",39152,41760],"/project/sequence.js/node_modules/.pnpm/camelcase@5.3.1/node_modules/camelcase/index.js":["1d930d28c959c4323750d39d13464d7321c98058",41760,42536],"/project/sequence.js/node_modules/.pnpm/decamelize@1.2.0/node_modules/decamelize/index.js":["b2b327355fce3e54d2a2c542beb41ae803c33285",42536,43216],"/project/sequence.js/node_modules/.pnpm/yargs-parser@18.1.3/node_modules/yargs-parser/lib/tokenize-arg-string.js":["d6ba12849ef19788b046e6c733d39dc89ecca903",43216,43912],"/project/sequence.js/node_modules/.pnpm/camelcase-keys@6.2.2/node_modules/camelcase-keys/index.js":["5a26b7fde6dad796f3bd7397e7791eac3ab87aaf",43912,45152],"/project/sequence.js/node_modules/.pnpm/map-obj@4.3.0/node_modules/map-obj/index.js":["ac674b6338e4f5478f897777dfa0426f7ef08372",45152,46200],"/project/sequence.js/node_modules/.pnpm/quick-lru@4.0.1/node_modules/quick-lru/index.js":["e3a201d5356b92357346467daabe90da2e16a7db",46200,48056],"/project/sequence.js/node_modules/.pnpm/decamelize-keys@1.1.1/node_modules/decamelize-keys/index.js":["f14f033c88b7ad237428f9adfb5b0529f7ae1e64",48056,48904],"/project/sequence.js/node_modules/.pnpm/map-obj@1.0.1/node_modules/map-obj/index.js":["fa95683437abe12eed3217e281bddf5f4938d72b",48904,49576],"/project/sequence.js/node_modules/.pnpm/trim-newlines@3.0.1/node_modules/trim-newlines/index.js":["33ad59bfabca72daaaac5ce86b9a1b3a86ff862b",49576,50520],"/project/sequence.js/node_modules/.pnpm/redent@3.0.0/node_modules/redent/index.js":["d4bc13cc14753873aaaa2b18b42dac80e01a01b3",50520,51368],"/project/sequence.js/node_modules/.pnpm/strip-indent@3.0.0/node_modules/strip-indent/index.js":["354e99b30d73ccc0488c92c9b47a76d602a1a430",51368,52144],"/project/sequence.js/node_modules/.pnpm/min-indent@1.0.1/node_modules/min-indent/index.js":["37d5dc3ecc8998cb6d75b3783a762af9c1efff36",52144,52824],"/project/sequence.js/node_modules/.pnpm/indent-string@4.0.0/node_modules/indent-string/index.js":["9c4d9c2acd8fcff21a0b3be049caeb37e0db31bd",52824,53504],"/project/sequence.js/node_modules/.pnpm/read-pkg-up@7.0.1/node_modules/read-pkg-up/index.js":["df41751fdcc969bd93baf4c7d33321339af674d0",53504,54504],"/project/sequence.js/node_modules/.pnpm/find-up@4.1.0/node_modules/find-up/index.js":["94bdb702d37e75813308dfb1dd22d476b4505e46",54504,55672],"/project/sequence.js/node_modules/.pnpm/locate-path@5.0.0/node_modules/locate-path/index.js":["62506e005bad63217618acd7919ebb78fa2e210a",55672,57232],"/project/sequence.js/node_modules/.pnpm/p-locate@4.1.0/node_modules/p-locate/index.js":["dd5418f2eae9be067ba9b5041b19468c555b62fe",57232,58416],"/project/sequence.js/node_modules/.pnpm/p-limit@2.3.0/node_modules/p-limit/index.js":["a51ebba93599019f457cb181d15f65a823dd62ac",58416,59160],"/project/sequence.js/node_modules/.pnpm/p-try@2.2.0/node_modules/p-try/index.js":["885a5f2ed7229ecacb44d35396cd886fcec4e22a",59160,59816],"/project/sequence.js/node_modules/.pnpm/path-exists@4.0.0/node_modules/path-exists/index.js":["e67614299feaa6105ac0b8acff41fbad72d12215",59816,60832],"/project/sequence.js/node_modules/.pnpm/read-pkg@5.2.0/node_modules/read-pkg/index.js":["9036a71c8ec79c27e349e125db9cffc0c3ec08a3",60832,62032],"/project/sequence.js/node_modules/.pnpm/parse-json@5.2.0/node_modules/parse-json/index.js":["e858089e91151c1352634775bc2fdc50b3727f57",62032,63272],"/project/sequence.js/node_modules/.pnpm/error-ex@1.3.2/node_modules/error-ex/index.js":["2c9f804ca561680284eca33ab39c3de463428d9d",63272,64376],"/project/sequence.js/node_modules/.pnpm/is-arrayish@0.2.1/node_modules/is-arrayish/index.js":["6f9d636aff36876efe7d1cefbbdee98bfcc28c98",64376,65024],"/project/sequence.js/node_modules/.pnpm/json-parse-even-better-errors@2.3.1/node_modules/json-parse-even-better-errors/index.js":["d871279956a6953ab4aba74301e6e0dff6e5d0cf",65024,67120],"/project/sequence.js/node_modules/.pnpm/lines-and-columns@1.2.4/node_modules/lines-and-columns/build/index.js":["dfadef3f4dd9e0a529bd280d63072311d4003ae7",67120,68464],"/project/sequence.js/node_modules/.pnpm/@babel+code-frame@7.24.7/node_modules/@babel/code-frame/lib/index.js":["8f8903e03150fc590880556976c3e13bc778b741",68464,70472],"/project/sequence.js/node_modules/.pnpm/@babel+highlight@7.24.7/node_modules/@babel/highlight/lib/index.js":["5f222c37d8d679535861ff6eb8459fbebc371987",70472,73352],"/project/sequence.js/node_modules/.pnpm/js-tokens@4.0.0/node_modules/js-tokens/index.js":["0e440af0eefc12535ba7b998ca49db43f60bcda4",73352,74768],"/project/sequence.js/node_modules/.pnpm/@babel+helper-validator-identifier@7.24.7/node_modules/@babel/helper-validator-identifier/lib/index.js":["5813ad3628d945e124c7d95d0c68ba3a7243d270",74768,77312],"/project/sequence.js/node_modules/.pnpm/@babel+helper-validator-identifier@7.24.7/node_modules/@babel/helper-validator-identifier/lib/identifier.js":["cab8bd9b8c93b5cd09b51bdc0044debaaeff08b3",77312,88664],"/project/sequence.js/node_modules/.pnpm/@babel+helper-validator-identifier@7.24.7/node_modules/@babel/helper-validator-identifier/lib/keyword.js":["aaef241789a33ed11de7ca3608a030b92049763a",88664,91024],"/project/sequence.js/node_modules/.pnpm/picocolors@1.0.1/node_modules/picocolors/picocolors.js":["6ac3387abbd5230220acd0af2f617e74c57b243a",91024,92464],"/project/sequence.js/node_modules/.pnpm/hard-rejection@2.1.0/node_modules/hard-rejection/index.js":["fd2e90cbb49c0a3c0e0f70813f19994b587c2abe",92464,93256],"/project/sequence.js/node_modules/.pnpm/normalize-package-data@2.5.0/node_modules/normalize-package-data/lib/normalize.js":["e35e7e40659151ebe4d397135dfc7ae3e9aa8170",93256,94808],"/project/sequence.js/node_modules/.pnpm/normalize-package-data@2.5.0/node_modules/normalize-package-data/lib/fixer.js":["f7eebdfb540e7a39e1c006112140675045e2dfb0",94808,100184],"/project/sequence.js/node_modules/.pnpm/semver@5.7.2/node_modules/semver/semver.js":["4b85b5f963842409ab87e7714887d2d7cdd4c727",100184,114288],"/project/sequence.js/node_modules/.pnpm/validate-npm-package-license@3.0.4/node_modules/validate-npm-package-license/index.js":["f3b4c4411d93c2314997bcb06791fb22a39b0ce2",114288,115664],"/project/sequence.js/node_modules/.pnpm/spdx-expression-parse@3.0.1/node_modules/spdx-expression-parse/index.js":["7d9b17e093b4706955e0b8991ed0d48f5739a40f",115664,116488],"/project/sequence.js/node_modules/.pnpm/spdx-expression-parse@3.0.1/node_modules/spdx-expression-parse/scan.js":["6ce4f78704adba89f90f4420365a306cb1bbeee8",116488,117552],"/project/sequence.js/node_modules/.pnpm/spdx-expression-parse@3.0.1/node_modules/spdx-expression-parse/parse.js":["f86a533bd13ff24966957e11bdb506ee7a91dbaf",117552,118368],"/project/sequence.js/node_modules/.pnpm/spdx-correct@3.2.0/node_modules/spdx-correct/index.js":["bd8e631a674fd29f75548547da756954bb8253a7",118368,125976],"/project/sequence.js/node_modules/.pnpm/hosted-git-info@2.8.9/node_modules/hosted-git-info/index.js":["7d405138838d32a0444c13eb2a74beefb2a658b4",125976,127816],"/project/sequence.js/node_modules/.pnpm/hosted-git-info@2.8.9/node_modules/hosted-git-info/git-host-info.js":["f03c8e42c32672adb05b93be109daeb2585a6658",127816,132232],"/project/sequence.js/node_modules/.pnpm/hosted-git-info@2.8.9/node_modules/hosted-git-info/git-host.js":["1e81232714cc00492d5bb5a49e621d6b1d754dd4",132232,134872],"/project/sequence.js/node_modules/.pnpm/resolve@1.22.8/node_modules/resolve/index.js":["db23b5f633134f5f81380633d9b4666384e98591",134872,135680],"/project/sequence.js/node_modules/.pnpm/resolve@1.22.8/node_modules/resolve/lib/async.js":["5041f4330e1a476744145fb2469beeae1ac79d99",135680,138368],"/project/sequence.js/node_modules/.pnpm/resolve@1.22.8/node_modules/resolve/lib/homedir.js":["7c804908ed10d1aa264b880ea6e5c34b883f52ac",138368,139056],"/project/sequence.js/node_modules/.pnpm/resolve@1.22.8/node_modules/resolve/lib/caller.js":["a57f670bf054692c44ba92d17dd78274eda5d73b",139056,139760],"/project/sequence.js/node_modules/.pnpm/resolve@1.22.8/node_modules/resolve/lib/node-modules-paths.js":["9b3f1ddafeccbfacdbf36d84b1cb8d36ac631ed2",139760,140744],"/project/sequence.js/node_modules/.pnpm/resolve@1.22.8/node_modules/resolve/lib/normalize-options.js":["7e53322b0515bdbb435ab7e9623a7f5014ab2883",140744,141432],"/project/sequence.js/node_modules/.pnpm/is-core-module@2.15.0/node_modules/is-core-module/index.js":["8be68d231ccea32f9d3f5a7a2120864147079829",141432,142496],"/project/sequence.js/node_modules/.pnpm/hasown@2.0.2/node_modules/hasown/index.js":["668857f7a7f36a0f7b80c8b6992b543819ce3a82",142496,143232],"/project/sequence.js/node_modules/.pnpm/function-bind@1.1.2/node_modules/function-bind/index.js":["f761bc101bf315e6124f737d1691aaa77e507253",143232,143888],"/project/sequence.js/node_modules/.pnpm/function-bind@1.1.2/node_modules/function-bind/implementation.js":["42321136a108882e353520fff3411fbfcb798b5b",143888,145088],"/project/sequence.js/node_modules/.pnpm/resolve@1.22.8/node_modules/resolve/lib/core.js":["4f76a34a44fc8a71f77bc442edea6048f7f03cde",145088,145904],"/project/sequence.js/node_modules/.pnpm/resolve@1.22.8/node_modules/resolve/lib/is-core.js":["4d6318c847f3bc91dd1b0f647bfb98d5958d81aa",145904,146640],"/project/sequence.js/node_modules/.pnpm/resolve@1.22.8/node_modules/resolve/lib/sync.js":["f9aafa50a2ea04a14e085f1698ad17295cef2619",146640,148768],"/project/sequence.js/node_modules/.pnpm/normalize-package-data@2.5.0/node_modules/normalize-package-data/lib/extract_description.js":["1461754e50fbc41a07c9901c0134dd0fcd5d23c5",148768,149472],"/project/sequence.js/node_modules/.pnpm/normalize-package-data@2.5.0/node_modules/normalize-package-data/lib/make_warning.js":["9ab5d64a118d79b9aff4fe138d1357a1642c7d1c",149472,150400],"/project/sequence.js/node_modules/.pnpm/enquirer@2.4.1/node_modules/enquirer/index.js":["d12024026266df904fee11fb9f81da0d9e538ead",150400,153632],"/project/sequence.js/node_modules/.pnpm/enquirer@2.4.1/node_modules/enquirer/lib/utils.js":["c7ba15889c419cc86f9e8bd5713aeb7c10a6a779",153632,157960],"/project/sequence.js/node_modules/.pnpm/ansi-colors@4.1.3/node_modules/ansi-colors/index.js":["64b9e2dd7033a9c659dcbf02316ae560157e9f3c",157960,159024],"/project/sequence.js/node_modules/.pnpm/ansi-colors@4.1.3/node_modules/ansi-colors/symbols.js":["47c2659ee9c473f4453bc9ed9a715c06f790520d",159024,162120],"/project/sequence.js/node_modules/.pnpm/enquirer@2.4.1/node_modules/enquirer/lib/prompts/index.js":["07b26cee45ce2905f6031ecdbbe1ca34819e6284",162120,164408],"/project/sequence.js/node_modules/.pnpm/p-limit@3.1.0/node_modules/p-limit/index.js":["f4e1896d228ab6e93828fc6b0af02b151e100464",164408,165136],"/project/sequence.js/node_modules/.pnpm/yocto-queue@0.1.0/node_modules/yocto-queue/index.js":["ec0be6ffda71356067a94dd911e42b1ae0fd1db9",165136,166928],"/project/sequence.js/node_modules/.pnpm/dataloader@2.2.2/node_modules/dataloader/index.js":["89b95844305a89d1c23e9067a2709b2a9ef0991f",166928,169104],"/project/sequence.js/node_modules/.pnpm/chalk@4.1.2/node_modules/chalk/source/index.js":["8c580aa7500d9969056a236df949fefc3db41905",169104,173640],"/project/sequence.js/node_modules/.pnpm/ansi-styles@4.3.0/node_modules/ansi-styles/index.js":["5f96df8b074e4854c03db87ef309eb6c741f4618",173640,175096],"/project/sequence.js/node_modules/.pnpm/supports-color@7.2.0/node_modules/supports-color/index.js":["3773691818b7b49ed40595e91be318a3a98d7795",175096,177008],"/project/sequence.js/node_modules/.pnpm/has-flag@4.0.0/node_modules/has-flag/index.js":["74ec980a20fb60d8774b46096a70b7ab9246d743",177008,177680],"/project/sequence.js/node_modules/.pnpm/chalk@4.1.2/node_modules/chalk/source/util.js":["4cb1e8afae9bc10f49a678034e835399ab9c0bcd",177680,178472],"/project/sequence.js/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/index.js":["e459e2a093427ef6b495bf02eccd044848688322",178472,181296],"/project/sequence.js/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/managers/tasks.js":["bcc3b169966c3e7ece6bf4b54745016b214fa448",181296,182920],"/project/sequence.js/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/utils/index.js":["752a08e3c614cbc9ecbb1b79c75780efea89f946",182920,184072],"/project/sequence.js/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/utils/array.js":["c2a902949583d0f9f812600271cde83086d8c7e7",184072,184912],"/project/sequence.js/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/utils/errno.js":["265f68611c7a5e7ac568213260b2faf0f69464bc",184912,185680],"/project/sequence.js/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/utils/fs.js":["fde03242c8fbced0e1fffde9176db3248e76c9c7",185680,186752],"/project/sequence.js/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/utils/path.js":["95a433bd9329f461bb6323ef1b3712bf54f131df",186752,188928],"/project/sequence.js/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/utils/pattern.js":["52d53793ea40d1ba27e85c1edc26815836dd436c",188928,192888],"/project/sequence.js/node_modules/.pnpm/glob-parent@5.1.2/node_modules/glob-parent/index.js":["adc400be934bd3d9b969c3accac4bb34a566d723",192888,194232],"/project/sequence.js/node_modules/.pnpm/is-glob@4.0.3/node_modules/is-glob/index.js":["9d88806c840a6ff6661e8b62a2e4ecef20ac1bc1",194232,195216],"/project/sequence.js/node_modules/.pnpm/is-extglob@2.1.1/node_modules/is-extglob/index.js":["c9ca9e3ebf4c37b326c24dc95fb9e6983b3dc1fd",195216,195864],"/project/sequence.js/node_modules/.pnpm/micromatch@4.0.7/node_modules/micromatch/index.js":["ee8a80b6774f0ca72a8109fff9eab9fedb457918",195864,198480],"/project/sequence.js/node_modules/.pnpm/braces@3.0.3/node_modules/braces/index.js":["16c230770b5d4e51d6e73d9e72d593e76cc09521",198480,199920],"/project/sequence.js/node_modules/.pnpm/braces@3.0.3/node_modules/braces/lib/stringify.js":["4b3d950417ae2f39a7487e583e85f529236ef422",199920,200680],"/project/sequence.js/node_modules/.pnpm/braces@3.0.3/node_modules/braces/lib/utils.js":["335ac09154d707fd39d341ddaffa377c47124261",200680,202296],"/project/sequence.js/node_modules/.pnpm/braces@3.0.3/node_modules/braces/lib/compile.js":["c0c55adea947384d778a24f4f08283d506aac1eb",202296,203088],"/project/sequence.js/node_modules/.pnpm/fill-range@7.1.1/node_modules/fill-range/index.js":["f90521fa85611e26457ceaf685f459a993381d1e",203088,205296],"/project/sequence.js/node_modules/.pnpm/to-regex-range@5.0.1/node_modules/to-regex-range/index.js":["b522adef7fd77cfdda9929f8773fc7d635439dcb",205296,207336],"/project/sequence.js/node_modules/.pnpm/is-number@7.0.0/node_modules/is-number/index.js":["1ec86d46940af464d8385e8d06a6ea34956cc757",207336,208008],"/project/sequence.js/node_modules/.pnpm/braces@3.0.3/node_modules/braces/lib/expand.js":["1ba7f6969f32a48741ae584d3a6e7b1fe98a0b63",208008,208952],"/project/sequence.js/node_modules/.pnpm/braces@3.0.3/node_modules/braces/lib/parse.js":["550e4c01b40e2a9b6bcbfbfb4ecc2fc660a1147f",208952,210576],"/project/sequence.js/node_modules/.pnpm/braces@3.0.3/node_modules/braces/lib/constants.js":["421df8cc8911fd1bc575cce481980b22e8d6b4f2",210576,212768],"/project/sequence.js/node_modules/.pnpm/picomatch@2.3.1/node_modules/picomatch/index.js":["e318b5985ff7d918da503a0e9aefb106a72c963b",212768,213376],"/project/sequence.js/node_modules/.pnpm/picomatch@2.3.1/node_modules/picomatch/lib/picomatch.js":["f45463f2c399358b722530b870722abb104b5091",213376,215352],"/project/sequence.js/node_modules/.pnpm/picomatch@2.3.1/node_modules/picomatch/lib/scan.js":["b706e51f6ce0d3cd2be9f6351547c1dfcc6f3520",215352,217136],"/project/sequence.js/node_modules/.pnpm/picomatch@2.3.1/node_modules/picomatch/lib/utils.js":["a38e121509c23f130931e3df7e3fdba25ae5dc39",217136,219488],"/project/sequence.js/node_modules/.pnpm/picomatch@2.3.1/node_modules/picomatch/lib/constants.js":["fe77299a32f26e8f1c63ac2a07614f4ed7261590",219488,225336],"/project/sequence.js/node_modules/.pnpm/picomatch@2.3.1/node_modules/picomatch/lib/parse.js":["b470522cc3965d7bab5ed135e1d1b4567da5489f",225336,226776],"/project/sequence.js/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/utils/stream.js":["83ed77291806827d1bdb16227833311083a5da09",226776,227672],"/project/sequence.js/node_modules/.pnpm/merge2@1.4.1/node_modules/merge2/index.js":["ad80c35745c87c842494078cfa8da55cae9d1201",227672,228680],"/project/sequence.js/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/utils/string.js":["21f718c2bbef24ca3602de2cb9b1f5c5080dbcfd",228680,229512],"/project/sequence.js/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/providers/async.js":["540f1475cf17095a5590b87f623b4e7efc24cb00",229512,230792],"/project/sequence.js/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/readers/async.js":["a63fed54c57c8dea0aa270a756daa7f24a625082",230792,232128],"/project/sequence.js/node_modules/.pnpm/@nodelib+fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/index.js":["9a7b966c96d03e673ca4885659549a3686af2a3d",232128,233536],"/project/sequence.js/node_modules/.pnpm/@nodelib+fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/providers/async.js":["ca32b381c4bc54aea5a25767bc02ac66b49f977b",233536,234872],"/project/sequence.js/node_modules/.pnpm/@nodelib+fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/readers/async.js":["febbb01e24817ccb351997edf2888e7cf9e5656d",234872,237184],"/project/sequence.js/node_modules/.pnpm/@nodelib+fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/index.js":["71d2b5d9e9abd1d47d1e54b5c30815d3dd16b760",237184,238400],"/project/sequence.js/node_modules/.pnpm/@nodelib+fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/providers/async.js":["f9ba13340d69804ead7f16041ca7886e58f11b52",238400,240032],"/project/sequence.js/node_modules/.pnpm/@nodelib+fs.stat@2.0.5/node_modules/@nodelib/fs.stat/out/index.js":["048bb47c8f91cfd03154635590113a5e77aa5d56",240032,241240],"/project/sequence.js/node_modules/.pnpm/@nodelib+fs.stat@2.0.5/node_modules/@nodelib/fs.stat/out/providers/async.js":["69cbbe90cba363ba429223faa83438e1ec56ff71",241240,242200],"/project/sequence.js/node_modules/.pnpm/@nodelib+fs.stat@2.0.5/node_modules/@nodelib/fs.stat/out/providers/sync.js":["9ab973411ddd81c618800061019951e6b7d8dc76",242200,242968],"/project/sequence.js/node_modules/.pnpm/@nodelib+fs.stat@2.0.5/node_modules/@nodelib/fs.stat/out/settings.js":["b48a6628dc2be47a2701a2fbfced76e60f9fe413",242968,244120],"/project/sequence.js/node_modules/.pnpm/@nodelib+fs.stat@2.0.5/node_modules/@nodelib/fs.stat/out/adapters/fs.js":["fb2ccdc3491b88733ed6e8f3c1571efac4bf2922",244120,245208],"/project/sequence.js/node_modules/.pnpm/run-parallel@1.2.0/node_modules/run-parallel/index.js":["9e68d778658beb112f789fc35d3ea91122cb1c3d",245208,246088],"/project/sequence.js/node_modules/.pnpm/queue-microtask@1.2.3/node_modules/queue-microtask/index.js":["8f6d501ff6a7e34f852b3e9f04cc7cb16821baff",246088,246944],"/project/sequence.js/node_modules/.pnpm/@nodelib+fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/constants.js":["d62034ef78787932d063a3e5e7f807bfb68ed480",246944,248136],"/project/sequence.js/node_modules/.pnpm/@nodelib+fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/utils/index.js":["cf075300b99854c1007854f6a2832a47315faac7",248136,248880],"/project/sequence.js/node_modules/.pnpm/@nodelib+fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/utils/fs.js":["fde03242c8fbced0e1fffde9176db3248e76c9c7",248880,249976],"/project/sequence.js/node_modules/.pnpm/@nodelib+fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/providers/common.js":["f2fb9050a1cd10db8f4ceefae11c4e5495974d90",249976,250760],"/project/sequence.js/node_modules/.pnpm/@nodelib+fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/providers/sync.js":["fb31af2eb7ad22baffed26e90052b5ba3920aa20",250760,252040],"/project/sequence.js/node_modules/.pnpm/@nodelib+fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/settings.js":["e3045ee354afbe74ad821238dc41619daef57dc7",252040,253328],"/project/sequence.js/node_modules/.pnpm/@nodelib+fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/adapters/fs.js":["6cabb8bce0417d8cc98e1f5f770298927896331b",253328,254504],"/project/sequence.js/node_modules/.pnpm/fastq@1.17.1/node_modules/fastq/queue.js":["0e3aa14b503d0c504d2bb1384d2cbfc7a5dfaf40",254504,255880],"/project/sequence.js/node_modules/.pnpm/reusify@1.0.4/node_modules/reusify/reusify.js":["253f9c72d80869e32a2f49bc1b458dbaf453bb84",255880,256560],"/project/sequence.js/node_modules/.pnpm/@nodelib+fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/readers/common.js":["85a38c3201a80b4dd04a63cc44de7f7e4fdd62b5",256560,257632],"/project/sequence.js/node_modules/.pnpm/@nodelib+fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/readers/reader.js":["5430f71fe5a493cceeba149498a96837af343c5b",257632,258688],"/project/sequence.js/node_modules/.pnpm/@nodelib+fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/providers/stream.js":["26f2b34c349013452c47b069062d0621a93317d7",258688,259920],"/project/sequence.js/node_modules/.pnpm/@nodelib+fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/providers/sync.js":["302b2038047a50fba013ae099d123c374b91100f",259920,261080],"/project/sequence.js/node_modules/.pnpm/@nodelib+fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/readers/sync.js":["7062a53bb5549ff8246065cff5b58e3097fd2c2e",261080,262896],"/project/sequence.js/node_modules/.pnpm/@nodelib+fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/settings.js":["d71706774d784235174fcc85a1dd889df9f29f43",262896,264112],"/project/sequence.js/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/readers/reader.js":["fb048d626e8d852a631a12e4fb2ab03a74b9fa8f",264112,265568],"/project/sequence.js/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/readers/stream.js":["ffce4582bc9f79455950a7b9db8094ed69bd3d97",265568,267160],"/project/sequence.js/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/providers/provider.js":["e15e416490d6d4ccf4db4eb0bf841a19c9015166",267160,268792],"/project/sequence.js/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/providers/filters/deep.js":["c2545d906765459ab10d8617935ad32ef14b1564",268792,270816],"/project/sequence.js/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/providers/matchers/partial.js":["277c888be29835cf26d3f3f3959bf2b9d754fa2c",270816,271936],"/project/sequence.js/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/providers/matchers/matcher.js":["85b823e0a7460cacaee1b40fec036df06ca2c325",271936,273288],"/project/sequence.js/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/providers/filters/entry.js":["7186a847bc5bcacfae9bc54e1032a1be4c73eb7f",273288,275128],"/project/sequence.js/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/providers/filters/error.js":["aafc75d8e19c67e324aaa3038648476d91d78fca",275128,276376],"/project/sequence.js/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/providers/transformers/entry.js":["f22d8cfaf9fa87dc75f3ac0d6f6a9c228436af5d",276376,277632],"/project/sequence.js/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/providers/stream.js":["92fdbe24b22a3c5e0df8ee784c8b57daef062501",277632,278984],"/project/sequence.js/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/providers/sync.js":["0b0718406005523d486497e1d3fa41a048d4b7d3",278984,280264],"/project/sequence.js/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/readers/sync.js":["0267cf7fe5e9a3c15f87400f5ef46a59baa42cb8",280264,281776],"/project/sequence.js/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/settings.js":["ba6870a40cacb77f648125f1ec379224546891c1",281776,283504],"/project/sequence.js/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/index.js":["b7111abcfec63f3c14d78fa1ab083daadb2a70d0",283504,284776],"/project/sequence.js/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/fs/index.js":["5362fe9fd2c8d632b37b2602ded1a0926a273f6b",284776,287088],"/project/sequence.js/node_modules/.pnpm/universalify@2.0.1/node_modules/universalify/index.js":["b89986d9f8a85f0ed20f038ad79a69fcb68a8288",287088,287952],"/project/sequence.js/node_modules/.pnpm/graceful-fs@4.2.11/node_modules/graceful-fs/graceful-fs.js":["55efc5a24c26495d0341c7884f0de5eb36520efa",287952,291936],"/project/sequence.js/node_modules/.pnpm/graceful-fs@4.2.11/node_modules/graceful-fs/polyfills.js":["38f3028ea7d9ec6b57f56ef32128499522c87a7f",291936,294064],"/project/sequence.js/node_modules/.pnpm/graceful-fs@4.2.11/node_modules/graceful-fs/legacy-streams.js":["f4a3583d4c3e8b0c407ab8406bdafb02b4055b7f",294064,294872],"/project/sequence.js/node_modules/.pnpm/graceful-fs@4.2.11/node_modules/graceful-fs/clone.js":["c912f366fe0025ea74e0e76e58277147dc0a3167",294872,295640],"/project/sequence.js/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/copy-sync/index.js":["3cf1fca7a7d2c1aba4a508a38e31c344d7255108",295640,296320],"/project/sequence.js/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/copy-sync/copy-sync.js":["3577d8fb71b1143769781f886e5e91a28458591c",296320,298760],"/project/sequence.js/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/mkdirs/index.js":["b0d9fcf6032f19505d113a6ea1ba769600751f28",298760,299792],"/project/sequence.js/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/mkdirs/make-dir.js":["66271453d9f0bdaadba03b78c7c95a862c52e970",299792,301224],"/project/sequence.js/node_modules/.pnpm/at-least-node@1.0.0/node_modules/at-least-node/index.js":["9c002b0e9446eff8a384d0a4b1c3494bb49a1e1f",301224,301904],"/project/sequence.js/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/util/utimes.js":["dad744f8edf8218685028574c168f77f9f1d75a8",301904,302768],"/project/sequence.js/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/util/stat.js":["38d324d1535d3303f3eb12af0eccb268194d267e",302768,304640],"/project/sequence.js/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/copy/index.js":["f685df7a46989c967bf917a5632a587298e22e40",304640,305392],"/project/sequence.js/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/copy/copy.js":["7715091e1e3173e3f5375092f035992cba09b39e",305392,308216],"/project/sequence.js/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/path-exists/index.js":["6e6491c1ab3389433d1b39a33b3ac8760649a2c8",308216,309160],"/project/sequence.js/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/empty/index.js":["72cfa757c416b468768d363ece8e71b66527577e",309160,310432],"/project/sequence.js/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/remove/index.js":["43a7630664db987ce37fc634b7474b6b9428ab4e",310432,311248],"/project/sequence.js/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/remove/rimraf.js":["9aaf8a271693de5fad3f942d7ca303e10be07c40",311248,313000],"/project/sequence.js/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/ensure/index.js":["68e93d6534353e9665f5d954de79edb27297b68f",313000,314264],"/project/sequence.js/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/ensure/file.js":["80c2a847a193ab5a9732746b6f5953cb50593f33",314264,315384],"/project/sequence.js/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/ensure/link.js":["87a056a34d6f9e0afcc150c235c6b972afc8cf7f",315384,316592],"/project/sequence.js/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/ensure/symlink.js":["dfc14c66722e60dc6879221877aecf9481d96b91",316592,318144],"/project/sequence.js/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/ensure/symlink-paths.js":["50fbb32d40b697a96fde72b07259933a9a72411a",318144,319160],"/project/sequence.js/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/ensure/symlink-type.js":["60686b2062037afe9661f006a43e124441409353",319160,320032],"/project/sequence.js/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/json/index.js":["047cedb67b8047183dfded82b56969c688dc5008",320032,321248],"/project/sequence.js/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/json/jsonfile.js":["6631d5dab8ea65a104dd9113357b4f0a2ada6fcc",321248,322176],"/project/sequence.js/node_modules/.pnpm/jsonfile@6.1.0/node_modules/jsonfile/index.js":["91c9c57af8bd81ee9a62a5b25797ea32883c15b0",322176,323648],"/project/sequence.js/node_modules/.pnpm/jsonfile@6.1.0/node_modules/jsonfile/utils.js":["9fcb3c2e8d7b909360c945cd568cc32fe7cf4596",323648,324408],"/project/sequence.js/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/json/output-json.js":["7a5ab88d3e20934904d7bffb20995b852442c0bb",324408,325264],"/project/sequence.js/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/output/index.js":["1b0879db53a00bbfeddcfdc0c190901387bab7bd",325264,326432],"/project/sequence.js/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/json/output-json-sync.js":["2f46f4bf9814aea91b0f6763c5d0f07e0ea9de05",326432,327296],"/project/sequence.js/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/move-sync/index.js":["ac40f3d0062886869329d8c31810935ad7c34ff5",327296,327976],"/project/sequence.js/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/move-sync/move-sync.js":["a391900c2c6e74e81d81c4414d9ef2bea7dd8ad9",327976,329352],"/project/sequence.js/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/move/index.js":["482e376c2d37368c3c202905b93429f3d46c9914",329352,330104],"/project/sequence.js/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/move/move.js":["5f4c2db7135a3cfc04d9711474173fa4fb606c6a",330104,331544],"/project/sequence.js/node_modules/.pnpm/@babel+runtime@7.25.0/node_modules/@babel/runtime/helpers/objectSpread2.js":["f47c3a639c64b919d1099838ce6bd488211fd0a0",331544,332480],"/project/sequence.js/node_modules/.pnpm/@babel+runtime@7.25.0/node_modules/@babel/runtime/helpers/defineProperty.js":["1033ba95ff4616a295e4f849b2b7a34b931ae33f",332480,333320],"/project/sequence.js/node_modules/.pnpm/@babel+runtime@7.25.0/node_modules/@babel/runtime/helpers/toPropertyKey.js":["a2413a0eef7b66a7d1da8caa67567dfc3ba042b0",333320,334240],"/project/sequence.js/node_modules/.pnpm/@babel+runtime@7.25.0/node_modules/@babel/runtime/helpers/typeof.js":["ea88e31e0d68da436c784278c7b42f3ba928f5d7",334240,335064],"/project/sequence.js/node_modules/.pnpm/@babel+runtime@7.25.0/node_modules/@babel/runtime/helpers/toPrimitive.js":["002a87e71e7536e0c7f85c3bf97498ba4b956cdc",335064,335888],"/project/sequence.js/node_modules/.pnpm/detect-indent@6.1.0/node_modules/detect-indent/index.js":["a1c18640e5fee89596e01848e6e06f45cd34a884",335888,337216],"/project/sequence.js/node_modules/.pnpm/normalize-path@3.0.0/node_modules/normalize-path/index.js":["7af46f52994266092fb6890723ef7e1b059d1d20",337216,337904],"/project/sequence.js/node_modules/.pnpm/parse-glob@3.0.4/node_modules/parse-glob/index.js":["80de4342abc02723990d3849ef8f5710a3bfc2a0",337904,339296],"/project/sequence.js/node_modules/.pnpm/is-glob@2.0.1/node_modules/is-glob/index.js":["b3dcfb08edc51fa11b2f6a028e432f7f81c67ca8",339296,340024],"/project/sequence.js/node_modules/.pnpm/is-extglob@1.0.0/node_modules/is-extglob/index.js":["f2caa8e7efa77712cf91d0f349830dc563f1c9fa",340024,340672],"/project/sequence.js/node_modules/.pnpm/glob-base@0.3.0/node_modules/glob-base/index.js":["2f15588ede319f3f78ecb5b8be65c80f8c1570cf",340672,341568],"/project/sequence.js/node_modules/.pnpm/glob-parent@6.0.2/node_modules/glob-parent/index.js":["b59c2ce1188362fdc692963d4b287b2f3d79f90f",341568,342888],"/project/sequence.js/node_modules/.pnpm/is-dotfile@1.0.3/node_modules/is-dotfile/index.js":["01bfbcba70e3ab9c171f1053cdf5a833221fc990",342888,343568],"/project/sequence.js/node_modules/.pnpm/zod@3.23.8/node_modules/zod/lib/index.js":["e38dd5a234ca8c66d1a751b65a97806e7f54f247",343568,345640],"/project/sequence.js/node_modules/.pnpm/zod@3.23.8/node_modules/zod/lib/external.js":["f242d6d87258054f8b05e805f089ed43342608e3",345640,347440],"/project/sequence.js/node_modules/.pnpm/zod@3.23.8/node_modules/zod/lib/errors.js":["d4b049d999fe64a12780c2b7cfb11ce599044c8b",347440,348528],"/project/sequence.js/node_modules/.pnpm/zod@3.23.8/node_modules/zod/lib/locales/en.js":["060c7208a1d1040484e5710467a1f6e89d0a6524",348528,349424],"/project/sequence.js/node_modules/.pnpm/zod@3.23.8/node_modules/zod/lib/helpers/util.js":["ce2fae02571c61f6db07908470ae58060d8ea65a",349424,352576],"/project/sequence.js/node_modules/.pnpm/zod@3.23.8/node_modules/zod/lib/ZodError.js":["0ea1242578863570620d771906985661d97db604",352576,355352],"/project/sequence.js/node_modules/.pnpm/zod@3.23.8/node_modules/zod/lib/helpers/parseUtil.js":["764a5b48d07d7288bdaab33628d4eaa59af14d2f",355352,358080],"/project/sequence.js/node_modules/.pnpm/zod@3.23.8/node_modules/zod/lib/helpers/typeAliases.js":["b66edae489b6e4147ce7e1ec65a107e297219771",358080,358728],"/project/sequence.js/node_modules/.pnpm/zod@3.23.8/node_modules/zod/lib/types.js":["6820bcddccd12fecf7dbf4071c3bc96890b90efd",358728,403600],"/project/sequence.js/node_modules/.pnpm/zod@3.23.8/node_modules/zod/lib/helpers/errorUtil.js":["5dd3884a3b2637d4dac94d46dbd9342b99cb953d",403600,404696],"/project/sequence.js/node_modules/.pnpm/npm-packlist@2.2.2/node_modules/npm-packlist/index.js":["d123f52a824837376e369e3aec7507647a184883",404696,408624],"/project/sequence.js/node_modules/.pnpm/npm-bundled@1.1.2/node_modules/npm-bundled/index.js":["88712a69de7c4e83aa2d9430dc2214dfd10be5c0",408624,411936],"/project/sequence.js/node_modules/.pnpm/npm-normalize-package-bin@1.0.1/node_modules/npm-normalize-package-bin/index.js":["936296ddebc6348bed8f93e0063aa9b81e594a50",411936,413096],"/project/sequence.js/node_modules/.pnpm/ignore-walk@3.0.4/node_modules/ignore-walk/index.js":["44909c6d209ab59cd7a00c297c8f907baccb841f",413096,416352],"/project/sequence.js/node_modules/.pnpm/minimatch@3.1.2/node_modules/minimatch/minimatch.js":["f21a6b3c6d1d71bb65e4e6e0af1bf1baba3a207e",416352,420736],"/project/sequence.js/node_modules/.pnpm/brace-expansion@1.1.11/node_modules/brace-expansion/index.js":["a2f937621d39c20ce582f697c3e4273d1e14b2e0",420736,422784],"/project/sequence.js/node_modules/.pnpm/concat-map@0.0.1/node_modules/concat-map/index.js":["a3063f014cc693b320dbd64de3243a79247c1e05",422784,423568],"/project/sequence.js/node_modules/.pnpm/balanced-match@1.0.2/node_modules/balanced-match/index.js":["12161cfaa33be93568ec9a6fd3d9c357991a6a76",423568,424408],"/project/sequence.js/node_modules/.pnpm/glob@7.2.3/node_modules/glob/glob.js":["7b624669f35601648f8300b45c3b3861bd9c7ef6",424408,429480],"/project/sequence.js/node_modules/.pnpm/fs.realpath@1.0.0/node_modules/fs.realpath/index.js":["9b5cdf4ef79264959ed0a23e4c35efbe6d64b0df",429480,430944],"/project/sequence.js/node_modules/.pnpm/fs.realpath@1.0.0/node_modules/fs.realpath/old.js":["d2d656e98e4d0735902068408824f8d08aaea84c",430944,432792],"/project/sequence.js/node_modules/.pnpm/inherits@2.0.4/node_modules/inherits/inherits.js":["222da288a07d8f65b2aed9b88815948cfe0b42d9",432792,433576],"/project/sequence.js/node_modules/.pnpm/path-is-absolute@1.0.1/node_modules/path-is-absolute/index.js":["6de38a82f68960de2bd07fd9114541f02bee2f62",433576,434400],"/project/sequence.js/node_modules/.pnpm/glob@7.2.3/node_modules/glob/sync.js":["82b1c855e4bfca820ecbed219649cd174b0c2f62",434400,437480],"/project/sequence.js/node_modules/.pnpm/glob@7.2.3/node_modules/glob/common.js":["4890b7b6c34bc659a38802851951da90baad085d",437480,439232],"/project/sequence.js/node_modules/.pnpm/inflight@1.0.6/node_modules/inflight/inflight.js":["84aed0b47c15de35a85a5aa6c641342ba4dd5a88",439232,440264],"/project/sequence.js/node_modules/.pnpm/wrappy@1.0.2/node_modules/wrappy/wrappy.js":["7d5c1c908664b3df4a9b72400a126652ba0dd905",440264,440992],"/project/sequence.js/node_modules/.pnpm/once@1.4.0/node_modules/once/once.js":["f78c8cb8d754261b59d03e867f329c2ffdefae45",440992,441976],"/project/sequence.js/node_modules/.pnpm/fast-deep-equal@2.0.1/node_modules/fast-deep-equal/index.js":["7544a59317225a41d7c3b02605e87459a251ea54",441976,442832],"/project/sequence.js/node_modules/.pnpm/resolve-from@5.0.0/node_modules/resolve-from/index.js":["12204537847d8c5d27e3dbeb024c2def138bb3ae",442832,443880],"/project/sequence.js/node_modules/.pnpm/rollup@2.79.1/node_modules/rollup/dist/rollup.js":["528be32fbed11ca77d2ddc3fa5a4b83153c1a6f4",443880,445104],"/project/sequence.js/node_modules/.pnpm/rollup@2.79.1/node_modules/rollup/dist/shared/rollup.js":["1b070c5ac10253c28c8b66a3b89713db723a347e",445104,741848],"/project/sequence.js/node_modules/.pnpm/@rollup+plugin-node-resolve@11.2.1_rollup@2.79.1/node_modules/@rollup/plugin-node-resolve/dist/cjs/index.js":["4c7176cdf5a30cd0a7d1266fae5deac3a0b55858",741848,748488],"/project/sequence.js/node_modules/.pnpm/builtin-modules@3.3.0/node_modules/builtin-modules/index.js":["78b46fe2850f2a721658e7ee0494e2ac9967d969",748488,749528],"/project/sequence.js/node_modules/.pnpm/deepmerge@4.3.1/node_modules/deepmerge/dist/cjs.js":["30a374f658500f10d214d0c1b0aab81773cb6582",749528,751720],"/project/sequence.js/node_modules/.pnpm/is-module@1.0.0/node_modules/is-module/index.js":["eea7f2fb1af6df299384691d877d0cfd20060e1a",751720,752784],"/project/sequence.js/node_modules/.pnpm/@rollup+pluginutils@3.1.0_rollup@2.79.1/node_modules/@rollup/pluginutils/dist/cjs/index.js":["3f1a4e804542765b8ed26ef9c84451ad737a0e46",752784,758000],"/project/sequence.js/node_modules/.pnpm/@rollup+plugin-alias@3.1.9_rollup@2.79.1/node_modules/@rollup/plugin-alias/dist/index.js":["03c72c8b0000a9ae55e2629c7d348df1ec55d116",758000,758984],"/project/sequence.js/node_modules/.pnpm/@rollup+plugin-commonjs@15.1.0_rollup@2.79.1/node_modules/@rollup/plugin-commonjs/dist/index.js":["daa1dd2236b14ac67f24c4cac4d7ac04396b4fee",758984,771680],"/project/sequence.js/node_modules/.pnpm/commondir@1.0.1/node_modules/commondir/index.js":["62f48e7310292100f457fd315c1eaeabfb741a72",771680,772448],"/project/sequence.js/node_modules/.pnpm/estree-walker@2.0.2/node_modules/estree-walker/dist/umd/estree-walker.js":["12880a2841f321975ae59f2789d482753951bd1d",772448,775088],"/project/sequence.js/node_modules/.pnpm/magic-string@0.25.9/node_modules/magic-string/dist/magic-string.cjs.js":["f50cbc79c4a1f869984025ed5328e2da919fb6ba",775088,783208],"/project/sequence.js/node_modules/.pnpm/sourcemap-codec@1.4.8/node_modules/sourcemap-codec/dist/sourcemap-codec.umd.js":["dfa9b54ce6838473151cd191a4904db99063bcce",783208,784408],"/project/sequence.js/node_modules/.pnpm/is-reference@1.2.1/node_modules/is-reference/dist/is-reference.js":["568fec88af0aeead7c9719447c3968e506d4672b",784408,785672],"/project/sequence.js/node_modules/.pnpm/@rollup+plugin-replace@2.4.2_rollup@2.79.1/node_modules/@rollup/plugin-replace/dist/rollup-plugin-replace.cjs.js":["604d14be2deb4b6497cb252240415fac3753ec33",785672,787176],"/project/sequence.js/node_modules/.pnpm/magic-string@0.30.11/node_modules/magic-string/dist/magic-string.cjs.js":["a1b82214ad58aa225c3d8372a563a70c6df1753b",787176,797160],"/project/sequence.js/node_modules/.pnpm/@jridgewell+sourcemap-codec@1.5.0/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js":["f8c6b12bc867c6c3b76c14cd7bdab4e9c509048b",797160,801576],"/project/sequence.js/node_modules/.pnpm/@rollup+plugin-json@4.1.0_rollup@2.79.1/node_modules/@rollup/plugin-json/dist/index.js":["3adfd5d9369691483a6c1ef2087de488f2462a52",801576,802416],"/project/sequence.js/node_modules/.pnpm/jest-worker@26.6.2/node_modules/jest-worker/build/index.js":["69de41b40fe0bcb567f075c46d5c9e6221e71bbb",802416,804760],"/project/sequence.js/node_modules/.pnpm/jest-worker@26.6.2/node_modules/jest-worker/build/Farm.js":["5984ef8e7cd217ce38501bda08d5631a7e5a1d74",804760,806568],"/project/sequence.js/node_modules/.pnpm/jest-worker@26.6.2/node_modules/jest-worker/build/types.js":["6ac3d2e94b3e62de1635e2962750f77fbafc997f",806568,807664],"/project/sequence.js/node_modules/.pnpm/jest-worker@26.6.2/node_modules/jest-worker/build/WorkerPool.js":["5db5da39a2f1711c5bc5e13217a23a68d5b06860",807664,809080],"/project/sequence.js/node_modules/.pnpm/jest-worker@26.6.2/node_modules/jest-worker/build/base/BaseWorkerPool.js":["f17a88f0a0756a0e478bb4d1050f056c268639b5",809080,811496],"/project/sequence.js/node_modules/.pnpm/jest-worker@26.6.2/node_modules/jest-worker/build/workers/messageParent.js":["af373cbfef8bc3a2960cfdfcf21b056f591b75c8",811496,812512],"/project/sequence.js/node_modules/.pnpm/ci-info@3.9.0/node_modules/ci-info/index.js":["306147110a81e4d70b7952dedf1e7f2721b72866",812512,814096],"/project/sequence.js/node_modules/.pnpm/quick-lru@5.1.1/node_modules/quick-lru/index.js":["94a42747caa09e0af0d52f35c6ba68c78b9a6018",814096,815952],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/index.js":["c01f38060f8c1eea0a62ee127afc3a7601029818",815952,820192],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/internal/re.js":["4847405c77f0465eb4baebe1385b155e72b57f6a",820192,827392],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/internal/constants.js":["819a733e61b6014ca6feeb6a570304612afe2b52",827392,828624],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/internal/debug.js":["d6166e7a8eda16340619cb02ee09c19a422b8333",828624,829536],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/classes/semver.js":["209950c633d84021324a834a14dbcbf0fb3202f4",829536,831624],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/internal/parse-options.js":["19a8ad4d2c32f4386402bd9eb235df80c73a8f75",831624,832480],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/internal/identifiers.js":["510c174c5bfc993023542e3b4f699cd18e2e0559",832480,833352],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/parse.js":["1bfe17569d11f23f9a539340cee18bba0e3f4f0a",833352,834096],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/valid.js":["edc5b800b8f302ac7ce238a419a02810cdeed8f2",834096,834824],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/clean.js":["92466e73dbb620c7b0c58b16e8d39a6d0ff22bc5",834824,835552],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/inc.js":["5814d4948ca724f91f2b61213c011bf8034f112f",835552,836296],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/diff.js":["a52f6ea79cf0224fda0d44968159b8dc13e36d7c",836296,837032],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/major.js":["5e2668d635ca6c7bde9bc1b7f763f26674e83c11",837032,837776],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/minor.js":["4bc0bc3ec293449f5fea1cbcfe976c8d2a26cce5",837776,838520],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/patch.js":["a78ef0c69e82d2a7b1f4f697e620aef6ad1de458",838520,839264],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/prerelease.js":["40a72fe55e64efcc0a5c6b859a0378ab030837db",839264,840000],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/compare.js":["33ec903e117ba1fe05cddedb86a9601d94e193a7",840000,840728],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/rcompare.js":["51f8192667aa9e1320e7fe0616b583039e8042c0",840728,841448],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/compare-loose.js":["1c581d61f0ab057af7fed4ad01c66d0998d1aa03",841448,842184],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/compare-build.js":["97ac51143c3f5c2255ba09c0ec0f952a2aecd8d1",842184,842944],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/sort.js":["b7fc2bc365d5f6f9e2ad842441755e7b8b19de5c",842944,843688],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/rsort.js":["1e99dcf8aa9518558b2a6945302273ac7b8d69bc",843688,844432],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/gt.js":["d5e2d5e6294e56ee0a42e92e3a89d8cf294cb833",844432,845144],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/lt.js":["fad43ee11cd4b18e2fbaf50593ae540f27365a87",845144,845856],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/eq.js":["498639a97e5682386b94c24096f133db4fd163d0",845856,846568],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/neq.js":["dfa93428b2368cff5aefd91d812bed067cb31ad6",846568,847288],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/gte.js":["b9c50a385c8e3877108a001fb8548b122a155193",847288,848008],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/lte.js":["bd1875ed01c16e0bf753352e775cfc3d993cc228",848008,848728],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/cmp.js":["50a23a530aac08f1545e15bf6441bf031282789e",848728,849792],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/coerce.js":["c64737eb38e2f78a361af16155116dc84c2af368",849792,850728],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/classes/comparator.js":["bbb95e311cc51af3911406848972f6cc50761d8f",850728,852712],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/classes/range.js":["49ea81742058369f806770d7d1b1a73192f0ca75",852712,856504],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/internal/lrucache.js":["26ae88faff2fd3ef9fbda59267979c98a1fea511",856504,857648],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/satisfies.js":["47a3e3141433768a2ca6a03841c842d15cf419c2",857648,858392],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/ranges/to-comparators.js":["4d609454b2e81450d85be8f56109af8ba6b61b92",858392,859144],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/ranges/max-satisfying.js":["4dcef246781158eef12758041375d1bce437a383",859144,859976],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/ranges/min-satisfying.js":["2155aea4b92343159e1b803f878a47297ca9aa66",859976,860808],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/ranges/min-version.js":["04dab32f676a52ee4c81f440eb1b5d6c7511afa5",860808,861712],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/ranges/valid.js":["7a1c6afbe83e28264a384b43ab8f6765f7649114",861712,862448],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/ranges/outside.js":["c6f8b84ebd967e5479159e2f876f3ba27530eb97",862448,863808],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/ranges/gtr.js":["4f69fb02e28923fe7126531d80862dc85bf94c19",863808,864536],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/ranges/ltr.js":["d4948b6f660390895f8ac0cfe4cad97bc1f15190",864536,865248],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/ranges/intersects.js":["3763224a30a86582b56a4cdf1ebaa97b5038e1c8",865248,865992],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/ranges/simplify.js":["bc651999d477c5698289adcd2ed8773cf7a2da11",865992,866848],"/project/sequence.js/node_modules/.pnpm/semver@7.6.3/node_modules/semver/ranges/subset.js":["94dce217bb98598dad72f194de19c5e2f3246d7b",866848,868384],"/project/sequence.js/node_modules/.pnpm/ms@2.1.3/node_modules/ms/index.js":["ea869663486f513cc4d1ca8312ed52a165c417fa",868384,869520],"/project/sequence.js/node_modules/.pnpm/@babel+helpers@7.25.0/node_modules/@babel/helpers/lib/index.js":["357f5f097a45815db5a715e876269d5bfabd7dac",869520,871352],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/index.js":["b4a694814012bf73e5e969685037c929ba16bfe1",871352,892992],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/react/isReactComponent.js":["95f5d5dc4b45810514357c0380914dc58241ba24",892992,893848],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/buildMatchMemberExpression.js":["e5d43e99dde5f498e5a3a92e71f2e952b501aac3",893848,894792],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/matchesPattern.js":["8454cf4b6cbd50a08bbc3c1de9ab5c16de493b00",894792,895680],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/generated/index.js":["5397377964d899fec62d8c34ffefadcf2fc440db",895680,926856],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/utils/shallowEqual.js":["10edc2f8f2dc3288ac96e3945e4ec1c0488f6487",926856,927640],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/utils/deprecationWarning.js":["afa3da502a334e2761cdd333fd39352dc94fc835",927640,928640],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/react/isCompatTag.js":["ff2f399e3c4be990b0da48d9bcba447ac6d461a2",928640,929440],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/builders/react/buildChildren.js":["9d4954881254318ce49c25a46c0e273cc92ed501",929440,930488],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/utils/react/cleanJSXElementLiteralChild.js":["6144987d113b19878587b0e55dbc45742bc61377",930488,931520],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/builders/generated/index.js":["09d118993950e33889672839e3812c3efd3524e0",931520,961360],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/builders/validateNode.js":["9f3d5f96da42cbf270e2324816aa2715fa7b8859",961360,962344],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/validate.js":["23bcdbb590e36bbf25fc5cddd90dd95806ca36e6",962344,963408],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/definitions/index.js":["75473cc26234f822479cf98daa1deb187f85bf7e",963408,967408],"/project/sequence.js/node_modules/.pnpm/to-fast-properties@2.0.0/node_modules/to-fast-properties/index.js":["6308ff82e9bca6a67e7aa25111f0105f1fee89fc",967408,968224],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/definitions/core.js":["0c388d4068048171798d941e2e7fb357320b05ff",968224,1020112],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/is.js":["ca3a7002a5b3266c519975795feb3df111781548",1020112,1021232],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/isType.js":["c35549269452b8a2efed8d388de69e86d02446ad",1021232,1022096],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/isPlaceholderType.js":["29b3523f38b94f9a08d792cc9719bac32db78d27",1022096,1023000],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/isValidIdentifier.js":["2b54d4a54bd63122fc8ce0a01eb531972c85eebc",1023000,1023944],"/project/sequence.js/node_modules/.pnpm/@babel+helper-string-parser@7.24.8/node_modules/@babel/helper-string-parser/lib/index.js":["3208fae30d742f71f09711bad362b9f09c5a79a6",1023944,1026144],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/constants/index.js":["49f82c5373bcdc59fc1fe32267648bc6c5d9b0c2",1026144,1030376],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/definitions/utils.js":["94640118c885a5ce4b4172f1de7970677860a744",1030376,1034072],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/definitions/flow.js":["616514b741caeea6bb56cdcc38754dd10c9d1d72",1034072,1053376],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/definitions/jsx.js":["75150a8a7b5f295714f618445a43b5be5134b3df",1053376,1058928],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/definitions/misc.js":["81f57e1e1fb15e0918d7a46502025a4ab0d1f9d4",1058928,1060504],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/definitions/placeholders.js":["b2e696e21aeae96071880f487af8883f6e8be92d",1060504,1062232],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/definitions/experimental.js":["d79101cd151187ddfd0dd80c38f777759d01ae5d",1062232,1067752],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/definitions/typescript.js":["79cde51962b6d573285de195a91c6954d794ae8b",1067752,1086864],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/definitions/deprecated-aliases.js":["f29794e441858c3e2f2b1085aecb4c756d77d711",1086864,1087744],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/asserts/assertNode.js":["f1638bb583fe74ab8bb9a1bc6f454b491a348274",1087744,1088624],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/isNode.js":["17f73842d38e0825ffa9f577e40f179503ee031b",1088624,1089488],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/asserts/generated/index.js":["148205bd999ad2039159ece59f6c8ac33a33606a",1089488,1122048],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/builders/flow/createTypeAnnotationBasedOnTypeof.js":["8769a998687162bc7550dcfe98a9e81f2d74a459",1122048,1123008],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/builders/flow/createFlowUnionType.js":["3c7a20f8b066ef7f858dcf14d6afcf1698ee141c",1123008,1124048],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/modifications/flow/removeTypeDuplicates.js":["f70e4d934e2b3b696ef00b1e34fee8ff252458e6",1124048,1125072],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/builders/typescript/createTSUnionType.js":["ac99b6bbdb3ee5879edb6ba5dbb012f987ef690b",1125072,1126216],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/modifications/typescript/removeTypeDuplicates.js":["54976f3b36b1e7db28188129aa2098282846f807",1126216,1127248],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/builders/generated/uppercase.js":["01146dc1a091c09905f4d4bd51bd9befcfc6013b",1127248,1183224],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/builders/productions.js":["5bf863371b472963ae72c1e64ac1b8630367ac2b",1183224,1184112],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/clone/cloneNode.js":["f15454de0a71e53a1e42faa07ef39ba7f8747f67",1184112,1185616],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/clone/clone.js":["00c128835dc3ef60c50001bc0e1372f29b797cd4",1185616,1186472],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/clone/cloneDeep.js":["0edb67fa97425f2d4079c8c64e097d0ddd5eb0cc",1186472,1187344],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/clone/cloneDeepWithoutLoc.js":["e7719f2ecf0c0657c5b6068c09af3c3bf0592068",1187344,1188248],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/clone/cloneWithoutLoc.js":["f63ebfbdab6d34badb74fd376c38f5cc8930423c",1188248,1189136],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/comments/addComment.js":["16f2d359874230847f36cb97742de44472f84594",1189136,1190016],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/comments/addComments.js":["c62e5ffd8cb9350cf9bc0589ca476d009ac85f9a",1190016,1190808],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/comments/inheritInnerComments.js":["d040738ed2802ba9d61a8394fe6c9ee65d734a76",1190808,1191720],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/utils/inherit.js":["5896fd13c8a775e0155b7185805c9727329f6730",1191720,1192488],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/comments/inheritLeadingComments.js":["f87077b689c318c639537f4c42698ed278e4f829",1192488,1193400],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/comments/inheritsComments.js":["42f6cbab43c95c7d831a62a991f7ae449cd9b5d8",1193400,1194528],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/comments/inheritTrailingComments.js":["5bd6c9b811fbe4893a2fbef744b7374e2c1e84c7",1194528,1195440],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/comments/removeComments.js":["a6564e4d0b4893afb3d965c187c6ee3c9990ee77",1195440,1196328],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/constants/generated/index.js":["150c5b7b3b23479f3e251f6341bd26ee2c70b185",1196328,1201792],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/converters/ensureBlock.js":["9546e15b033129e9d14e953a1e431f1f9bf88824",1201792,1202672],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/converters/toBlock.js":["e42f617eb9a3d06d9e088fa1e41225b663c2bff9",1202672,1203640],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/converters/toBindingIdentifierName.js":["26959a098e207bbb2842e79e7bccdbabe8323408",1203640,1204560],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/converters/toIdentifier.js":["bb776190e90daa84973bc9941adcdd8193bd1e5e",1204560,1205632],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/converters/toComputedKey.js":["9eecc51376934654679e0386cd244a8dda5f0baf",1205632,1206624],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/converters/toExpression.js":["c6891bc3f4882d86e3e6dbff896c85ce44923cb4",1206624,1207528],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/converters/toKeyAlias.js":["5fbdc0ac8dc95b5eabec0be50d71e6c0865ce35c",1207528,1208792],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/modifications/removePropertiesDeep.js":["23860ef1d6c45e8f71b8228a1f377668e8c96f1b",1208792,1209824],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/traverse/traverseFast.js":["67af8be359598f6a3aafc7637358f7046033aeca",1209824,1210720],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/modifications/removeProperties.js":["73107880504998df7f8c5b3bd7a278383e84c8bc",1210720,1211960],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/converters/toStatement.js":["574ede0cdc26b05072b0646e7d66221fa1da6558",1211960,1212960],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/converters/valueToNode.js":["8b5b35bc076f64bd9672753d23da7ec67b106fd8",1212960,1214288],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/modifications/appendToMemberExpression.js":["27439fd3e557f640b2f818d7361fc0c12f46cb43",1214288,1215216],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/modifications/inherits.js":["746ddefd49e0fbafb0f53d49ac490d9e5a67eccf",1215216,1216200],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/modifications/prependToMemberExpression.js":["5a713459848abc5691a7b9f14ad0112175c90ae5",1216200,1217216],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/retrievers/getAssignmentIdentifiers.js":["56001c75c4a7d7d9734e6f5410d5feef3c61a3c0",1217216,1218032],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/retrievers/getBindingIdentifiers.js":["09124ac3269656d268bb5bb4745670c8961541ff",1218032,1221448],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/retrievers/getOuterBindingIdentifiers.js":["d0c30354a56b626a2a1533a68dd36f03d75f35d1",1221448,1222424],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/retrievers/getFunctionName.js":["0fb9488c606146a2e06e65a956f17c5ed503955b",1222424,1223496],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/traverse/traverse.js":["7992ab182de5d6e2635aa63d27e20ae6119fd085",1223496,1224440],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/isBinding.js":["4184b924d4bf2122e4d64d4661db34225e6ce581",1224440,1225352],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/isBlockScoped.js":["551efbe73814fbdf9b09af1a6dbd9edab8ca12c9",1225352,1226320],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/isLet.js":["3a0c0986cdca1871a5c5ed9260abcc71f3622c6d",1226320,1227272],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/isImmutable.js":["87ce8fd906f5fe6fea21757f3b96e2dbf10d45b9",1227272,1228240],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/isNodesEquivalent.js":["8de1678d5fea7521128e49da8471adb7ac189ad8",1228240,1229152],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/isReferenced.js":["8759a5583bcae62a90768a3418d106c78e08f2fe",1229152,1229944],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/isScope.js":["db0b7d08fe2f223e5bb846f2713a608d9c4d3204",1229944,1230808],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/isSpecifierDefault.js":["8c8652248a736fc000db5f45ec1d1a0570acb952",1230808,1231720],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/isValidES3Identifier.js":["49d11809665072371ec9b0d5fe83f5214001eb6f",1231720,1233200],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/isVar.js":["a8ac19b347058fbb51e9c0b9b35a838cd9c6ef14",1233200,1234152],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/converters/toSequenceExpression.js":["9384f95b71f9748d64908bdc9b4b675c12d14104",1234152,1235096],"/project/sequence.js/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/converters/gatherSequenceExpressions.js":["ba5ecf63baf8dfbe57529a29490ad381b7c8625b",1235096,1236424],"/project/sequence.js/node_modules/.pnpm/@babel+helpers@7.25.0/node_modules/@babel/helpers/lib/helpers-generated.js":["bdfe68621914607bd09d0c2a3dc4e7a2d74a3b9f",1236424,1350008],"/project/sequence.js/node_modules/.pnpm/@babel+template@7.25.0/node_modules/@babel/template/lib/index.js":["9a3926ea29ec8d546e723aa8a1353306e0bd0ad5",1350008,1351328],"/project/sequence.js/node_modules/.pnpm/@babel+template@7.25.0/node_modules/@babel/template/lib/formatters.js":["f9b9d9a37cbf61be7616b0656d92b8b79fa52b1f",1351328,1353448],"/project/sequence.js/node_modules/.pnpm/@babel+template@7.25.0/node_modules/@babel/template/lib/builder.js":["f23864c5185e593ed3929af741bf8a1ee43b4603",1353448,1354712],"/project/sequence.js/node_modules/.pnpm/@babel+template@7.25.0/node_modules/@babel/template/lib/options.js":["a2154aa8b4523eac2c1c71ebfcba32308afcd31f",1354712,1355976],"/project/sequence.js/node_modules/.pnpm/@babel+template@7.25.0/node_modules/@babel/template/lib/string.js":["d4bd2d379e5c5247bb0e825aa911836b07a7ad72",1355976,1357000],"/project/sequence.js/node_modules/.pnpm/@babel+template@7.25.0/node_modules/@babel/template/lib/parse.js":["1a725f4ba5a1fe7a4fcd95195b3d01be192b747d",1357000,1358904],"/project/sequence.js/node_modules/.pnpm/@babel+parser@7.25.3/node_modules/@babel/parser/lib/index.js":["d150d62841d0f12e7f4b42f5291013c9b1ebde79",1358904,1501792],"/project/sequence.js/node_modules/.pnpm/@babel+template@7.25.0/node_modules/@babel/template/lib/populate.js":["77692699c5cb74c059e0c9c786e2ffb59a68f434",1501792,1503200],"/project/sequence.js/node_modules/.pnpm/@babel+template@7.25.0/node_modules/@babel/template/lib/literal.js":["9f9a7059025c507617ea6303f9106ee2e53ddcb9",1503200,1504392],"/project/sequence.js/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/index.js":["c98c5ea2b11bbdb4bccf13ff70509990fad9919f",1504392,1505784],"/project/sequence.js/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/source-map.js":["5b5a15c3b2d5fec4b5c62457f3016e8aa33a46f0",1505784,1507336],"/project/sequence.js/node_modules/.pnpm/@jridgewell+gen-mapping@0.3.5/node_modules/@jridgewell/gen-mapping/dist/gen-mapping.umd.js":["f59a96193c4d0050b224b915ec09303a0b363013",1507336,1511344],"/project/sequence.js/node_modules/.pnpm/@jridgewell+set-array@1.2.1/node_modules/@jridgewell/set-array/dist/set-array.umd.js":["20be9f5c3d323c9aca346a00e62f8d7e4a1fefa0",1511344,1513408],"/project/sequence.js/node_modules/.pnpm/@jridgewell+trace-mapping@0.3.25/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.umd.js":["d14969c9417dabccd90411b4770dc55726dea41d",1513408,1519576],"/project/sequence.js/node_modules/.pnpm/@jridgewell+resolve-uri@3.1.2/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.umd.js":["3d56b7861cb317124e76dc7f2caac7d4c8cf3a86",1519576,1522248],"/project/sequence.js/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/printer.js":["87b6083bdeb088244d146ec7094b137c7d19ff47",1522248,1529232],"/project/sequence.js/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/buffer.js":["1e5f3acd7d2127345524d342f8aeecb542146a50",1529232,1532440],"/project/sequence.js/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/node/index.js":["84c5abeb85944041673e6fa57c883a880e59e2d0",1532440,1534840],"/project/sequence.js/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/node/whitespace.js":["6432f37adcbacc354300b84a879ef6e0e504341a",1534840,1538560],"/project/sequence.js/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/node/parentheses.js":["616888cbcfd6f0e0b898aff092aae10647710d25",1538560,1544136],"/project/sequence.js/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/generators/index.js":["19e79ce1eedfd872c35b815d444f6288c4050140",1544136,1547024],"/project/sequence.js/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/generators/template-literals.js":["9069eae70537e6d8145bdcd443a7322a884edbcb",1547024,1548016],"/project/sequence.js/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/generators/expressions.js":["7c7d6368f96052f5613036cd7504ffdb1fbc5c67",1548016,1551560],"/project/sequence.js/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/generators/statements.js":["bba4e7700a33a7c482fb2de6620782ce25e03a34",1551560,1554504],"/project/sequence.js/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/generators/classes.js":["95b2bae54b2cda46b6bcfcf2bfc9f455f045fcdd",1554504,1556208],"/project/sequence.js/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/generators/methods.js":["6f0304fea2d5eaa3884b09293ee074a50e0ecd45",1556208,1557984],"/project/sequence.js/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/generators/modules.js":["437038a7e68f202f78dd78b70156899cf75e6ff5",1557984,1560488],"/project/sequence.js/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/generators/types.js":["09778cd4447014d0bb8f4d6053d455da8b990f3a",1560488,1563440],"/project/sequence.js/node_modules/.pnpm/jsesc@2.5.2/node_modules/jsesc/jsesc.js":["1ddb9ef6ced291147886096f09527cb1980a5572",1563440,1565640],"/project/sequence.js/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/generators/flow.js":["5d7383206f35f019e6364dbd6930405141c3c74a",1565640,1573640],"/project/sequence.js/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/generators/base.js":["51d18e9c693ca992d7d0a779deac61c493cb0e32",1573640,1575120],"/project/sequence.js/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/generators/jsx.js":["85bf426cf47cadb0aebb50eb9f23b2c7e1b24d7c",1575120,1577248],"/project/sequence.js/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/generators/typescript.js":["9a4ed7457f46c3c1159be1b9847355edbe87c70c",1577248,1584680]} \ No newline at end of file diff --git a/v8-compile-cache-0/x64/11.3.244.8-node.19/zSprojectzSworkspacezSnode_moduleszS.pnpmzS@preconstruct+cli@2.8.7zSnode_moduleszS@preconstructzSclizSbin.js.BLOB b/v8-compile-cache-0/x64/11.3.244.8-node.19/zSprojectzSworkspacezSnode_moduleszS.pnpmzS@preconstruct+cli@2.8.7zSnode_moduleszS@preconstructzSclizSbin.js.BLOB new file mode 100644 index 0000000000..5e6ea312b8 Binary files /dev/null and b/v8-compile-cache-0/x64/11.3.244.8-node.19/zSprojectzSworkspacezSnode_moduleszS.pnpmzS@preconstruct+cli@2.8.7zSnode_moduleszS@preconstructzSclizSbin.js.BLOB differ diff --git a/v8-compile-cache-0/x64/11.3.244.8-node.19/zSprojectzSworkspacezSnode_moduleszS.pnpmzS@preconstruct+cli@2.8.7zSnode_moduleszS@preconstructzSclizSbin.js.MAP b/v8-compile-cache-0/x64/11.3.244.8-node.19/zSprojectzSworkspacezSnode_moduleszS.pnpmzS@preconstruct+cli@2.8.7zSnode_moduleszS@preconstructzSclizSbin.js.MAP new file mode 100644 index 0000000000..1d99dbbed3 --- /dev/null +++ b/v8-compile-cache-0/x64/11.3.244.8-node.19/zSprojectzSworkspacezSnode_moduleszS.pnpmzS@preconstruct+cli@2.8.7zSnode_moduleszS@preconstructzSclizSbin.js.MAP @@ -0,0 +1 @@ +{"/project/workspace/node_modules/.pnpm/@preconstruct+cli@2.8.7/node_modules/@preconstruct/cli/cli/dist/preconstruct-cli-cli.cjs.js":["8315344ea3ec2213ef0e4aaa37b41d90c77999cb",0,32424],"/project/workspace/node_modules/.pnpm/meow@7.1.1/node_modules/meow/index.js":["4a866f54ed797369e8e33d78cc06f5834ee7b7be",32424,34544],"/project/workspace/node_modules/.pnpm/minimist-options@4.1.0/node_modules/minimist-options/index.js":["0f0bff7fe31e97f7ea78636b1aca17e841e5f8e3",34544,36360],"/project/workspace/node_modules/.pnpm/is-plain-obj@1.1.0/node_modules/is-plain-obj/index.js":["16523ba84e3229bcd98780b380a4f4e323b8bf8b",36360,37088],"/project/workspace/node_modules/.pnpm/arrify@1.0.1/node_modules/arrify/index.js":["d91a789bdf6d6e7ea9014b0b1bacfef0d7621f47",37088,37752],"/project/workspace/node_modules/.pnpm/kind-of@6.0.3/node_modules/kind-of/index.js":["7de61d4d1e16e0c9b04660b8904d9488727a5d02",37752,39144],"/project/workspace/node_modules/.pnpm/yargs-parser@18.1.3/node_modules/yargs-parser/index.js":["ace83036108f3a4eb87218d76219768fee3520ed",39144,41752],"/project/workspace/node_modules/.pnpm/camelcase@5.3.1/node_modules/camelcase/index.js":["1d930d28c959c4323750d39d13464d7321c98058",41752,42528],"/project/workspace/node_modules/.pnpm/decamelize@1.2.0/node_modules/decamelize/index.js":["b2b327355fce3e54d2a2c542beb41ae803c33285",42528,43200],"/project/workspace/node_modules/.pnpm/yargs-parser@18.1.3/node_modules/yargs-parser/lib/tokenize-arg-string.js":["d6ba12849ef19788b046e6c733d39dc89ecca903",43200,43896],"/project/workspace/node_modules/.pnpm/camelcase-keys@6.2.2/node_modules/camelcase-keys/index.js":["5a26b7fde6dad796f3bd7397e7791eac3ab87aaf",43896,45128],"/project/workspace/node_modules/.pnpm/map-obj@4.3.0/node_modules/map-obj/index.js":["ac674b6338e4f5478f897777dfa0426f7ef08372",45128,46176],"/project/workspace/node_modules/.pnpm/quick-lru@4.0.1/node_modules/quick-lru/index.js":["e3a201d5356b92357346467daabe90da2e16a7db",46176,48024],"/project/workspace/node_modules/.pnpm/decamelize-keys@1.1.1/node_modules/decamelize-keys/index.js":["f14f033c88b7ad237428f9adfb5b0529f7ae1e64",48024,48872],"/project/workspace/node_modules/.pnpm/map-obj@1.0.1/node_modules/map-obj/index.js":["fa95683437abe12eed3217e281bddf5f4938d72b",48872,49544],"/project/workspace/node_modules/.pnpm/trim-newlines@3.0.1/node_modules/trim-newlines/index.js":["33ad59bfabca72daaaac5ce86b9a1b3a86ff862b",49544,50488],"/project/workspace/node_modules/.pnpm/redent@3.0.0/node_modules/redent/index.js":["d4bc13cc14753873aaaa2b18b42dac80e01a01b3",50488,51328],"/project/workspace/node_modules/.pnpm/strip-indent@3.0.0/node_modules/strip-indent/index.js":["354e99b30d73ccc0488c92c9b47a76d602a1a430",51328,52104],"/project/workspace/node_modules/.pnpm/min-indent@1.0.1/node_modules/min-indent/index.js":["37d5dc3ecc8998cb6d75b3783a762af9c1efff36",52104,52776],"/project/workspace/node_modules/.pnpm/indent-string@4.0.0/node_modules/indent-string/index.js":["9c4d9c2acd8fcff21a0b3be049caeb37e0db31bd",52776,53456],"/project/workspace/node_modules/.pnpm/read-pkg-up@7.0.1/node_modules/read-pkg-up/index.js":["df41751fdcc969bd93baf4c7d33321339af674d0",53456,54456],"/project/workspace/node_modules/.pnpm/find-up@4.1.0/node_modules/find-up/index.js":["94bdb702d37e75813308dfb1dd22d476b4505e46",54456,55624],"/project/workspace/node_modules/.pnpm/locate-path@5.0.0/node_modules/locate-path/index.js":["62506e005bad63217618acd7919ebb78fa2e210a",55624,57184],"/project/workspace/node_modules/.pnpm/p-locate@4.1.0/node_modules/p-locate/index.js":["dd5418f2eae9be067ba9b5041b19468c555b62fe",57184,58368],"/project/workspace/node_modules/.pnpm/p-limit@2.3.0/node_modules/p-limit/index.js":["a51ebba93599019f457cb181d15f65a823dd62ac",58368,59112],"/project/workspace/node_modules/.pnpm/p-try@2.2.0/node_modules/p-try/index.js":["885a5f2ed7229ecacb44d35396cd886fcec4e22a",59112,59768],"/project/workspace/node_modules/.pnpm/path-exists@4.0.0/node_modules/path-exists/index.js":["e67614299feaa6105ac0b8acff41fbad72d12215",59768,60784],"/project/workspace/node_modules/.pnpm/read-pkg@5.2.0/node_modules/read-pkg/index.js":["9036a71c8ec79c27e349e125db9cffc0c3ec08a3",60784,61984],"/project/workspace/node_modules/.pnpm/parse-json@5.2.0/node_modules/parse-json/index.js":["e858089e91151c1352634775bc2fdc50b3727f57",61984,63216],"/project/workspace/node_modules/.pnpm/error-ex@1.3.2/node_modules/error-ex/index.js":["2c9f804ca561680284eca33ab39c3de463428d9d",63216,64320],"/project/workspace/node_modules/.pnpm/is-arrayish@0.2.1/node_modules/is-arrayish/index.js":["6f9d636aff36876efe7d1cefbbdee98bfcc28c98",64320,64968],"/project/workspace/node_modules/.pnpm/json-parse-even-better-errors@2.3.1/node_modules/json-parse-even-better-errors/index.js":["d871279956a6953ab4aba74301e6e0dff6e5d0cf",64968,67064],"/project/workspace/node_modules/.pnpm/lines-and-columns@1.2.4/node_modules/lines-and-columns/build/index.js":["dfadef3f4dd9e0a529bd280d63072311d4003ae7",67064,68408],"/project/workspace/node_modules/.pnpm/@babel+code-frame@7.24.7/node_modules/@babel/code-frame/lib/index.js":["8f8903e03150fc590880556976c3e13bc778b741",68408,70416],"/project/workspace/node_modules/.pnpm/@babel+highlight@7.24.7/node_modules/@babel/highlight/lib/index.js":["5f222c37d8d679535861ff6eb8459fbebc371987",70416,73288],"/project/workspace/node_modules/.pnpm/js-tokens@4.0.0/node_modules/js-tokens/index.js":["0e440af0eefc12535ba7b998ca49db43f60bcda4",73288,74704],"/project/workspace/node_modules/.pnpm/@babel+helper-validator-identifier@7.24.7/node_modules/@babel/helper-validator-identifier/lib/index.js":["5813ad3628d945e124c7d95d0c68ba3a7243d270",74704,77248],"/project/workspace/node_modules/.pnpm/@babel+helper-validator-identifier@7.24.7/node_modules/@babel/helper-validator-identifier/lib/identifier.js":["cab8bd9b8c93b5cd09b51bdc0044debaaeff08b3",77248,88600],"/project/workspace/node_modules/.pnpm/@babel+helper-validator-identifier@7.24.7/node_modules/@babel/helper-validator-identifier/lib/keyword.js":["aaef241789a33ed11de7ca3608a030b92049763a",88600,90960],"/project/workspace/node_modules/.pnpm/picocolors@1.0.1/node_modules/picocolors/picocolors.js":["6ac3387abbd5230220acd0af2f617e74c57b243a",90960,92400],"/project/workspace/node_modules/.pnpm/hard-rejection@2.1.0/node_modules/hard-rejection/index.js":["fd2e90cbb49c0a3c0e0f70813f19994b587c2abe",92400,93184],"/project/workspace/node_modules/.pnpm/normalize-package-data@2.5.0/node_modules/normalize-package-data/lib/normalize.js":["e35e7e40659151ebe4d397135dfc7ae3e9aa8170",93184,94728],"/project/workspace/node_modules/.pnpm/normalize-package-data@2.5.0/node_modules/normalize-package-data/lib/fixer.js":["f7eebdfb540e7a39e1c006112140675045e2dfb0",94728,100104],"/project/workspace/node_modules/.pnpm/semver@5.7.2/node_modules/semver/semver.js":["4b85b5f963842409ab87e7714887d2d7cdd4c727",100104,114200],"/project/workspace/node_modules/.pnpm/validate-npm-package-license@3.0.4/node_modules/validate-npm-package-license/index.js":["f3b4c4411d93c2314997bcb06791fb22a39b0ce2",114200,115576],"/project/workspace/node_modules/.pnpm/spdx-expression-parse@3.0.1/node_modules/spdx-expression-parse/index.js":["7d9b17e093b4706955e0b8991ed0d48f5739a40f",115576,116400],"/project/workspace/node_modules/.pnpm/spdx-expression-parse@3.0.1/node_modules/spdx-expression-parse/scan.js":["6ce4f78704adba89f90f4420365a306cb1bbeee8",116400,117464],"/project/workspace/node_modules/.pnpm/spdx-expression-parse@3.0.1/node_modules/spdx-expression-parse/parse.js":["f86a533bd13ff24966957e11bdb506ee7a91dbaf",117464,118280],"/project/workspace/node_modules/.pnpm/spdx-correct@3.2.0/node_modules/spdx-correct/index.js":["bd8e631a674fd29f75548547da756954bb8253a7",118280,125888],"/project/workspace/node_modules/.pnpm/hosted-git-info@2.8.9/node_modules/hosted-git-info/index.js":["7d405138838d32a0444c13eb2a74beefb2a658b4",125888,127728],"/project/workspace/node_modules/.pnpm/hosted-git-info@2.8.9/node_modules/hosted-git-info/git-host-info.js":["f03c8e42c32672adb05b93be109daeb2585a6658",127728,132144],"/project/workspace/node_modules/.pnpm/hosted-git-info@2.8.9/node_modules/hosted-git-info/git-host.js":["1e81232714cc00492d5bb5a49e621d6b1d754dd4",132144,134784],"/project/workspace/node_modules/.pnpm/resolve@1.22.8/node_modules/resolve/index.js":["db23b5f633134f5f81380633d9b4666384e98591",134784,135592],"/project/workspace/node_modules/.pnpm/resolve@1.22.8/node_modules/resolve/lib/async.js":["5041f4330e1a476744145fb2469beeae1ac79d99",135592,138280],"/project/workspace/node_modules/.pnpm/resolve@1.22.8/node_modules/resolve/lib/homedir.js":["7c804908ed10d1aa264b880ea6e5c34b883f52ac",138280,138960],"/project/workspace/node_modules/.pnpm/resolve@1.22.8/node_modules/resolve/lib/caller.js":["a57f670bf054692c44ba92d17dd78274eda5d73b",138960,139656],"/project/workspace/node_modules/.pnpm/resolve@1.22.8/node_modules/resolve/lib/node-modules-paths.js":["9b3f1ddafeccbfacdbf36d84b1cb8d36ac631ed2",139656,140640],"/project/workspace/node_modules/.pnpm/resolve@1.22.8/node_modules/resolve/lib/normalize-options.js":["7e53322b0515bdbb435ab7e9623a7f5014ab2883",140640,141328],"/project/workspace/node_modules/.pnpm/is-core-module@2.15.0/node_modules/is-core-module/index.js":["8be68d231ccea32f9d3f5a7a2120864147079829",141328,142384],"/project/workspace/node_modules/.pnpm/hasown@2.0.2/node_modules/hasown/index.js":["668857f7a7f36a0f7b80c8b6992b543819ce3a82",142384,143112],"/project/workspace/node_modules/.pnpm/function-bind@1.1.2/node_modules/function-bind/index.js":["f761bc101bf315e6124f737d1691aaa77e507253",143112,143768],"/project/workspace/node_modules/.pnpm/function-bind@1.1.2/node_modules/function-bind/implementation.js":["42321136a108882e353520fff3411fbfcb798b5b",143768,144968],"/project/workspace/node_modules/.pnpm/resolve@1.22.8/node_modules/resolve/lib/core.js":["4f76a34a44fc8a71f77bc442edea6048f7f03cde",144968,145784],"/project/workspace/node_modules/.pnpm/resolve@1.22.8/node_modules/resolve/lib/is-core.js":["4d6318c847f3bc91dd1b0f647bfb98d5958d81aa",145784,146512],"/project/workspace/node_modules/.pnpm/resolve@1.22.8/node_modules/resolve/lib/sync.js":["f9aafa50a2ea04a14e085f1698ad17295cef2619",146512,148640],"/project/workspace/node_modules/.pnpm/normalize-package-data@2.5.0/node_modules/normalize-package-data/lib/extract_description.js":["1461754e50fbc41a07c9901c0134dd0fcd5d23c5",148640,149344],"/project/workspace/node_modules/.pnpm/normalize-package-data@2.5.0/node_modules/normalize-package-data/lib/make_warning.js":["9ab5d64a118d79b9aff4fe138d1357a1642c7d1c",149344,150272],"/project/workspace/node_modules/.pnpm/enquirer@2.4.1/node_modules/enquirer/index.js":["d12024026266df904fee11fb9f81da0d9e538ead",150272,153504],"/project/workspace/node_modules/.pnpm/enquirer@2.4.1/node_modules/enquirer/lib/utils.js":["c7ba15889c419cc86f9e8bd5713aeb7c10a6a779",153504,157824],"/project/workspace/node_modules/.pnpm/ansi-colors@4.1.3/node_modules/ansi-colors/index.js":["64b9e2dd7033a9c659dcbf02316ae560157e9f3c",157824,158888],"/project/workspace/node_modules/.pnpm/ansi-colors@4.1.3/node_modules/ansi-colors/symbols.js":["47c2659ee9c473f4453bc9ed9a715c06f790520d",158888,161984],"/project/workspace/node_modules/.pnpm/enquirer@2.4.1/node_modules/enquirer/lib/prompts/index.js":["07b26cee45ce2905f6031ecdbbe1ca34819e6284",161984,164264],"/project/workspace/node_modules/.pnpm/p-limit@3.1.0/node_modules/p-limit/index.js":["f4e1896d228ab6e93828fc6b0af02b151e100464",164264,164992],"/project/workspace/node_modules/.pnpm/yocto-queue@0.1.0/node_modules/yocto-queue/index.js":["ec0be6ffda71356067a94dd911e42b1ae0fd1db9",164992,166776],"/project/workspace/node_modules/.pnpm/dataloader@2.2.2/node_modules/dataloader/index.js":["89b95844305a89d1c23e9067a2709b2a9ef0991f",166776,168944],"/project/workspace/node_modules/.pnpm/chalk@4.1.2/node_modules/chalk/source/index.js":["8c580aa7500d9969056a236df949fefc3db41905",168944,173480],"/project/workspace/node_modules/.pnpm/ansi-styles@4.3.0/node_modules/ansi-styles/index.js":["5f96df8b074e4854c03db87ef309eb6c741f4618",173480,174936],"/project/workspace/node_modules/.pnpm/supports-color@7.2.0/node_modules/supports-color/index.js":["3773691818b7b49ed40595e91be318a3a98d7795",174936,176840],"/project/workspace/node_modules/.pnpm/has-flag@4.0.0/node_modules/has-flag/index.js":["74ec980a20fb60d8774b46096a70b7ab9246d743",176840,177512],"/project/workspace/node_modules/.pnpm/chalk@4.1.2/node_modules/chalk/source/util.js":["4cb1e8afae9bc10f49a678034e835399ab9c0bcd",177512,178304],"/project/workspace/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/index.js":["e459e2a093427ef6b495bf02eccd044848688322",178304,181128],"/project/workspace/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/managers/tasks.js":["bcc3b169966c3e7ece6bf4b54745016b214fa448",181128,182752],"/project/workspace/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/utils/index.js":["752a08e3c614cbc9ecbb1b79c75780efea89f946",182752,183896],"/project/workspace/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/utils/array.js":["c2a902949583d0f9f812600271cde83086d8c7e7",183896,184728],"/project/workspace/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/utils/errno.js":["265f68611c7a5e7ac568213260b2faf0f69464bc",184728,185488],"/project/workspace/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/utils/fs.js":["fde03242c8fbced0e1fffde9176db3248e76c9c7",185488,186560],"/project/workspace/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/utils/path.js":["95a433bd9329f461bb6323ef1b3712bf54f131df",186560,188736],"/project/workspace/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/utils/pattern.js":["52d53793ea40d1ba27e85c1edc26815836dd436c",188736,192696],"/project/workspace/node_modules/.pnpm/glob-parent@5.1.2/node_modules/glob-parent/index.js":["adc400be934bd3d9b969c3accac4bb34a566d723",192696,194040],"/project/workspace/node_modules/.pnpm/is-glob@4.0.3/node_modules/is-glob/index.js":["9d88806c840a6ff6661e8b62a2e4ecef20ac1bc1",194040,195024],"/project/workspace/node_modules/.pnpm/is-extglob@2.1.1/node_modules/is-extglob/index.js":["c9ca9e3ebf4c37b326c24dc95fb9e6983b3dc1fd",195024,195664],"/project/workspace/node_modules/.pnpm/micromatch@4.0.7/node_modules/micromatch/index.js":["ee8a80b6774f0ca72a8109fff9eab9fedb457918",195664,198272],"/project/workspace/node_modules/.pnpm/braces@3.0.3/node_modules/braces/index.js":["16c230770b5d4e51d6e73d9e72d593e76cc09521",198272,199704],"/project/workspace/node_modules/.pnpm/braces@3.0.3/node_modules/braces/lib/stringify.js":["4b3d950417ae2f39a7487e583e85f529236ef422",199704,200456],"/project/workspace/node_modules/.pnpm/braces@3.0.3/node_modules/braces/lib/utils.js":["335ac09154d707fd39d341ddaffa377c47124261",200456,202072],"/project/workspace/node_modules/.pnpm/braces@3.0.3/node_modules/braces/lib/compile.js":["c0c55adea947384d778a24f4f08283d506aac1eb",202072,202864],"/project/workspace/node_modules/.pnpm/fill-range@7.1.1/node_modules/fill-range/index.js":["f90521fa85611e26457ceaf685f459a993381d1e",202864,205064],"/project/workspace/node_modules/.pnpm/to-regex-range@5.0.1/node_modules/to-regex-range/index.js":["b522adef7fd77cfdda9929f8773fc7d635439dcb",205064,207096],"/project/workspace/node_modules/.pnpm/is-number@7.0.0/node_modules/is-number/index.js":["1ec86d46940af464d8385e8d06a6ea34956cc757",207096,207768],"/project/workspace/node_modules/.pnpm/braces@3.0.3/node_modules/braces/lib/expand.js":["1ba7f6969f32a48741ae584d3a6e7b1fe98a0b63",207768,208712],"/project/workspace/node_modules/.pnpm/braces@3.0.3/node_modules/braces/lib/parse.js":["550e4c01b40e2a9b6bcbfbfb4ecc2fc660a1147f",208712,210336],"/project/workspace/node_modules/.pnpm/braces@3.0.3/node_modules/braces/lib/constants.js":["421df8cc8911fd1bc575cce481980b22e8d6b4f2",210336,212520],"/project/workspace/node_modules/.pnpm/picomatch@2.3.1/node_modules/picomatch/index.js":["e318b5985ff7d918da503a0e9aefb106a72c963b",212520,213128],"/project/workspace/node_modules/.pnpm/picomatch@2.3.1/node_modules/picomatch/lib/picomatch.js":["f45463f2c399358b722530b870722abb104b5091",213128,215104],"/project/workspace/node_modules/.pnpm/picomatch@2.3.1/node_modules/picomatch/lib/scan.js":["b706e51f6ce0d3cd2be9f6351547c1dfcc6f3520",215104,216880],"/project/workspace/node_modules/.pnpm/picomatch@2.3.1/node_modules/picomatch/lib/utils.js":["a38e121509c23f130931e3df7e3fdba25ae5dc39",216880,219232],"/project/workspace/node_modules/.pnpm/picomatch@2.3.1/node_modules/picomatch/lib/constants.js":["fe77299a32f26e8f1c63ac2a07614f4ed7261590",219232,225080],"/project/workspace/node_modules/.pnpm/picomatch@2.3.1/node_modules/picomatch/lib/parse.js":["b470522cc3965d7bab5ed135e1d1b4567da5489f",225080,226520],"/project/workspace/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/utils/stream.js":["83ed77291806827d1bdb16227833311083a5da09",226520,227408],"/project/workspace/node_modules/.pnpm/merge2@1.4.1/node_modules/merge2/index.js":["ad80c35745c87c842494078cfa8da55cae9d1201",227408,228408],"/project/workspace/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/utils/string.js":["21f718c2bbef24ca3602de2cb9b1f5c5080dbcfd",228408,229232],"/project/workspace/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/providers/async.js":["540f1475cf17095a5590b87f623b4e7efc24cb00",229232,230512],"/project/workspace/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/readers/async.js":["a63fed54c57c8dea0aa270a756daa7f24a625082",230512,231848],"/project/workspace/node_modules/.pnpm/@nodelib+fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/index.js":["9a7b966c96d03e673ca4885659549a3686af2a3d",231848,233248],"/project/workspace/node_modules/.pnpm/@nodelib+fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/providers/async.js":["ca32b381c4bc54aea5a25767bc02ac66b49f977b",233248,234584],"/project/workspace/node_modules/.pnpm/@nodelib+fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/readers/async.js":["febbb01e24817ccb351997edf2888e7cf9e5656d",234584,236888],"/project/workspace/node_modules/.pnpm/@nodelib+fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/index.js":["71d2b5d9e9abd1d47d1e54b5c30815d3dd16b760",236888,238104],"/project/workspace/node_modules/.pnpm/@nodelib+fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/providers/async.js":["f9ba13340d69804ead7f16041ca7886e58f11b52",238104,239728],"/project/workspace/node_modules/.pnpm/@nodelib+fs.stat@2.0.5/node_modules/@nodelib/fs.stat/out/index.js":["048bb47c8f91cfd03154635590113a5e77aa5d56",239728,240928],"/project/workspace/node_modules/.pnpm/@nodelib+fs.stat@2.0.5/node_modules/@nodelib/fs.stat/out/providers/async.js":["69cbbe90cba363ba429223faa83438e1ec56ff71",240928,241888],"/project/workspace/node_modules/.pnpm/@nodelib+fs.stat@2.0.5/node_modules/@nodelib/fs.stat/out/providers/sync.js":["9ab973411ddd81c618800061019951e6b7d8dc76",241888,242648],"/project/workspace/node_modules/.pnpm/@nodelib+fs.stat@2.0.5/node_modules/@nodelib/fs.stat/out/settings.js":["b48a6628dc2be47a2701a2fbfced76e60f9fe413",242648,243800],"/project/workspace/node_modules/.pnpm/@nodelib+fs.stat@2.0.5/node_modules/@nodelib/fs.stat/out/adapters/fs.js":["fb2ccdc3491b88733ed6e8f3c1571efac4bf2922",243800,244888],"/project/workspace/node_modules/.pnpm/run-parallel@1.2.0/node_modules/run-parallel/index.js":["9e68d778658beb112f789fc35d3ea91122cb1c3d",244888,245768],"/project/workspace/node_modules/.pnpm/queue-microtask@1.2.3/node_modules/queue-microtask/index.js":["8f6d501ff6a7e34f852b3e9f04cc7cb16821baff",245768,246624],"/project/workspace/node_modules/.pnpm/@nodelib+fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/constants.js":["d62034ef78787932d063a3e5e7f807bfb68ed480",246624,247816],"/project/workspace/node_modules/.pnpm/@nodelib+fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/utils/index.js":["cf075300b99854c1007854f6a2832a47315faac7",247816,248560],"/project/workspace/node_modules/.pnpm/@nodelib+fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/utils/fs.js":["fde03242c8fbced0e1fffde9176db3248e76c9c7",248560,249648],"/project/workspace/node_modules/.pnpm/@nodelib+fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/providers/common.js":["f2fb9050a1cd10db8f4ceefae11c4e5495974d90",249648,250424],"/project/workspace/node_modules/.pnpm/@nodelib+fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/providers/sync.js":["fb31af2eb7ad22baffed26e90052b5ba3920aa20",250424,251704],"/project/workspace/node_modules/.pnpm/@nodelib+fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/settings.js":["e3045ee354afbe74ad821238dc41619daef57dc7",251704,252984],"/project/workspace/node_modules/.pnpm/@nodelib+fs.scandir@2.1.5/node_modules/@nodelib/fs.scandir/out/adapters/fs.js":["6cabb8bce0417d8cc98e1f5f770298927896331b",252984,254160],"/project/workspace/node_modules/.pnpm/fastq@1.17.1/node_modules/fastq/queue.js":["0e3aa14b503d0c504d2bb1384d2cbfc7a5dfaf40",254160,255536],"/project/workspace/node_modules/.pnpm/reusify@1.0.4/node_modules/reusify/reusify.js":["253f9c72d80869e32a2f49bc1b458dbaf453bb84",255536,256216],"/project/workspace/node_modules/.pnpm/@nodelib+fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/readers/common.js":["85a38c3201a80b4dd04a63cc44de7f7e4fdd62b5",256216,257280],"/project/workspace/node_modules/.pnpm/@nodelib+fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/readers/reader.js":["5430f71fe5a493cceeba149498a96837af343c5b",257280,258328],"/project/workspace/node_modules/.pnpm/@nodelib+fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/providers/stream.js":["26f2b34c349013452c47b069062d0621a93317d7",258328,259560],"/project/workspace/node_modules/.pnpm/@nodelib+fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/providers/sync.js":["302b2038047a50fba013ae099d123c374b91100f",259560,260712],"/project/workspace/node_modules/.pnpm/@nodelib+fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/readers/sync.js":["7062a53bb5549ff8246065cff5b58e3097fd2c2e",260712,262528],"/project/workspace/node_modules/.pnpm/@nodelib+fs.walk@1.2.8/node_modules/@nodelib/fs.walk/out/settings.js":["d71706774d784235174fcc85a1dd889df9f29f43",262528,263744],"/project/workspace/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/readers/reader.js":["fb048d626e8d852a631a12e4fb2ab03a74b9fa8f",263744,265200],"/project/workspace/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/readers/stream.js":["ffce4582bc9f79455950a7b9db8094ed69bd3d97",265200,266792],"/project/workspace/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/providers/provider.js":["e15e416490d6d4ccf4db4eb0bf841a19c9015166",266792,268424],"/project/workspace/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/providers/filters/deep.js":["c2545d906765459ab10d8617935ad32ef14b1564",268424,270448],"/project/workspace/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/providers/matchers/partial.js":["277c888be29835cf26d3f3f3959bf2b9d754fa2c",270448,271568],"/project/workspace/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/providers/matchers/matcher.js":["85b823e0a7460cacaee1b40fec036df06ca2c325",271568,272920],"/project/workspace/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/providers/filters/entry.js":["7186a847bc5bcacfae9bc54e1032a1be4c73eb7f",272920,274760],"/project/workspace/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/providers/filters/error.js":["aafc75d8e19c67e324aaa3038648476d91d78fca",274760,276008],"/project/workspace/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/providers/transformers/entry.js":["f22d8cfaf9fa87dc75f3ac0d6f6a9c228436af5d",276008,277256],"/project/workspace/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/providers/stream.js":["92fdbe24b22a3c5e0df8ee784c8b57daef062501",277256,278608],"/project/workspace/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/providers/sync.js":["0b0718406005523d486497e1d3fa41a048d4b7d3",278608,279888],"/project/workspace/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/readers/sync.js":["0267cf7fe5e9a3c15f87400f5ef46a59baa42cb8",279888,281392],"/project/workspace/node_modules/.pnpm/fast-glob@3.3.2/node_modules/fast-glob/out/settings.js":["ba6870a40cacb77f648125f1ec379224546891c1",281392,283120],"/project/workspace/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/index.js":["b7111abcfec63f3c14d78fa1ab083daadb2a70d0",283120,284384],"/project/workspace/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/fs/index.js":["5362fe9fd2c8d632b37b2602ded1a0926a273f6b",284384,286696],"/project/workspace/node_modules/.pnpm/universalify@2.0.1/node_modules/universalify/index.js":["b89986d9f8a85f0ed20f038ad79a69fcb68a8288",286696,287560],"/project/workspace/node_modules/.pnpm/graceful-fs@4.2.11/node_modules/graceful-fs/graceful-fs.js":["55efc5a24c26495d0341c7884f0de5eb36520efa",287560,291536],"/project/workspace/node_modules/.pnpm/graceful-fs@4.2.11/node_modules/graceful-fs/polyfills.js":["38f3028ea7d9ec6b57f56ef32128499522c87a7f",291536,293664],"/project/workspace/node_modules/.pnpm/graceful-fs@4.2.11/node_modules/graceful-fs/legacy-streams.js":["f4a3583d4c3e8b0c407ab8406bdafb02b4055b7f",293664,294472],"/project/workspace/node_modules/.pnpm/graceful-fs@4.2.11/node_modules/graceful-fs/clone.js":["c912f366fe0025ea74e0e76e58277147dc0a3167",294472,295240],"/project/workspace/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/copy-sync/index.js":["3cf1fca7a7d2c1aba4a508a38e31c344d7255108",295240,295920],"/project/workspace/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/copy-sync/copy-sync.js":["3577d8fb71b1143769781f886e5e91a28458591c",295920,298360],"/project/workspace/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/mkdirs/index.js":["b0d9fcf6032f19505d113a6ea1ba769600751f28",298360,299392],"/project/workspace/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/mkdirs/make-dir.js":["66271453d9f0bdaadba03b78c7c95a862c52e970",299392,300824],"/project/workspace/node_modules/.pnpm/at-least-node@1.0.0/node_modules/at-least-node/index.js":["9c002b0e9446eff8a384d0a4b1c3494bb49a1e1f",300824,301504],"/project/workspace/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/util/utimes.js":["dad744f8edf8218685028574c168f77f9f1d75a8",301504,302368],"/project/workspace/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/util/stat.js":["38d324d1535d3303f3eb12af0eccb268194d267e",302368,304240],"/project/workspace/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/copy/index.js":["f685df7a46989c967bf917a5632a587298e22e40",304240,304992],"/project/workspace/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/copy/copy.js":["7715091e1e3173e3f5375092f035992cba09b39e",304992,307816],"/project/workspace/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/path-exists/index.js":["6e6491c1ab3389433d1b39a33b3ac8760649a2c8",307816,308760],"/project/workspace/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/empty/index.js":["72cfa757c416b468768d363ece8e71b66527577e",308760,310032],"/project/workspace/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/remove/index.js":["43a7630664db987ce37fc634b7474b6b9428ab4e",310032,310848],"/project/workspace/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/remove/rimraf.js":["9aaf8a271693de5fad3f942d7ca303e10be07c40",310848,312592],"/project/workspace/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/ensure/index.js":["68e93d6534353e9665f5d954de79edb27297b68f",312592,313856],"/project/workspace/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/ensure/file.js":["80c2a847a193ab5a9732746b6f5953cb50593f33",313856,314976],"/project/workspace/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/ensure/link.js":["87a056a34d6f9e0afcc150c235c6b972afc8cf7f",314976,316184],"/project/workspace/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/ensure/symlink.js":["dfc14c66722e60dc6879221877aecf9481d96b91",316184,317728],"/project/workspace/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/ensure/symlink-paths.js":["50fbb32d40b697a96fde72b07259933a9a72411a",317728,318744],"/project/workspace/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/ensure/symlink-type.js":["60686b2062037afe9661f006a43e124441409353",318744,319616],"/project/workspace/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/json/index.js":["047cedb67b8047183dfded82b56969c688dc5008",319616,320832],"/project/workspace/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/json/jsonfile.js":["6631d5dab8ea65a104dd9113357b4f0a2ada6fcc",320832,321752],"/project/workspace/node_modules/.pnpm/jsonfile@6.1.0/node_modules/jsonfile/index.js":["91c9c57af8bd81ee9a62a5b25797ea32883c15b0",321752,323224],"/project/workspace/node_modules/.pnpm/jsonfile@6.1.0/node_modules/jsonfile/utils.js":["9fcb3c2e8d7b909360c945cd568cc32fe7cf4596",323224,323984],"/project/workspace/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/json/output-json.js":["7a5ab88d3e20934904d7bffb20995b852442c0bb",323984,324840],"/project/workspace/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/output/index.js":["1b0879db53a00bbfeddcfdc0c190901387bab7bd",324840,326008],"/project/workspace/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/json/output-json-sync.js":["2f46f4bf9814aea91b0f6763c5d0f07e0ea9de05",326008,326864],"/project/workspace/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/move-sync/index.js":["ac40f3d0062886869329d8c31810935ad7c34ff5",326864,327544],"/project/workspace/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/move-sync/move-sync.js":["a391900c2c6e74e81d81c4414d9ef2bea7dd8ad9",327544,328920],"/project/workspace/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/move/index.js":["482e376c2d37368c3c202905b93429f3d46c9914",328920,329672],"/project/workspace/node_modules/.pnpm/fs-extra@9.1.0/node_modules/fs-extra/lib/move/move.js":["5f4c2db7135a3cfc04d9711474173fa4fb606c6a",329672,331112],"/project/workspace/node_modules/.pnpm/@babel+runtime@7.25.0/node_modules/@babel/runtime/helpers/objectSpread2.js":["f47c3a639c64b919d1099838ce6bd488211fd0a0",331112,332040],"/project/workspace/node_modules/.pnpm/@babel+runtime@7.25.0/node_modules/@babel/runtime/helpers/defineProperty.js":["1033ba95ff4616a295e4f849b2b7a34b931ae33f",332040,332880],"/project/workspace/node_modules/.pnpm/@babel+runtime@7.25.0/node_modules/@babel/runtime/helpers/toPropertyKey.js":["a2413a0eef7b66a7d1da8caa67567dfc3ba042b0",332880,333792],"/project/workspace/node_modules/.pnpm/@babel+runtime@7.25.0/node_modules/@babel/runtime/helpers/typeof.js":["ea88e31e0d68da436c784278c7b42f3ba928f5d7",333792,334616],"/project/workspace/node_modules/.pnpm/@babel+runtime@7.25.0/node_modules/@babel/runtime/helpers/toPrimitive.js":["002a87e71e7536e0c7f85c3bf97498ba4b956cdc",334616,335440],"/project/workspace/node_modules/.pnpm/detect-indent@6.1.0/node_modules/detect-indent/index.js":["a1c18640e5fee89596e01848e6e06f45cd34a884",335440,336768],"/project/workspace/node_modules/.pnpm/normalize-path@3.0.0/node_modules/normalize-path/index.js":["7af46f52994266092fb6890723ef7e1b059d1d20",336768,337448],"/project/workspace/node_modules/.pnpm/parse-glob@3.0.4/node_modules/parse-glob/index.js":["80de4342abc02723990d3849ef8f5710a3bfc2a0",337448,338832],"/project/workspace/node_modules/.pnpm/is-glob@2.0.1/node_modules/is-glob/index.js":["b3dcfb08edc51fa11b2f6a028e432f7f81c67ca8",338832,339560],"/project/workspace/node_modules/.pnpm/is-extglob@1.0.0/node_modules/is-extglob/index.js":["f2caa8e7efa77712cf91d0f349830dc563f1c9fa",339560,340200],"/project/workspace/node_modules/.pnpm/glob-base@0.3.0/node_modules/glob-base/index.js":["2f15588ede319f3f78ecb5b8be65c80f8c1570cf",340200,341096],"/project/workspace/node_modules/.pnpm/glob-parent@6.0.2/node_modules/glob-parent/index.js":["b59c2ce1188362fdc692963d4b287b2f3d79f90f",341096,342416],"/project/workspace/node_modules/.pnpm/is-dotfile@1.0.3/node_modules/is-dotfile/index.js":["01bfbcba70e3ab9c171f1053cdf5a833221fc990",342416,343088],"/project/workspace/node_modules/.pnpm/zod@3.23.8/node_modules/zod/lib/index.js":["e38dd5a234ca8c66d1a751b65a97806e7f54f247",343088,345160],"/project/workspace/node_modules/.pnpm/zod@3.23.8/node_modules/zod/lib/external.js":["f242d6d87258054f8b05e805f089ed43342608e3",345160,346960],"/project/workspace/node_modules/.pnpm/zod@3.23.8/node_modules/zod/lib/errors.js":["d4b049d999fe64a12780c2b7cfb11ce599044c8b",346960,348040],"/project/workspace/node_modules/.pnpm/zod@3.23.8/node_modules/zod/lib/locales/en.js":["060c7208a1d1040484e5710467a1f6e89d0a6524",348040,348936],"/project/workspace/node_modules/.pnpm/zod@3.23.8/node_modules/zod/lib/helpers/util.js":["ce2fae02571c61f6db07908470ae58060d8ea65a",348936,352088],"/project/workspace/node_modules/.pnpm/zod@3.23.8/node_modules/zod/lib/ZodError.js":["0ea1242578863570620d771906985661d97db604",352088,354864],"/project/workspace/node_modules/.pnpm/zod@3.23.8/node_modules/zod/lib/helpers/parseUtil.js":["764a5b48d07d7288bdaab33628d4eaa59af14d2f",354864,357592],"/project/workspace/node_modules/.pnpm/zod@3.23.8/node_modules/zod/lib/helpers/typeAliases.js":["b66edae489b6e4147ce7e1ec65a107e297219771",357592,358240],"/project/workspace/node_modules/.pnpm/zod@3.23.8/node_modules/zod/lib/types.js":["6820bcddccd12fecf7dbf4071c3bc96890b90efd",358240,403112],"/project/workspace/node_modules/.pnpm/zod@3.23.8/node_modules/zod/lib/helpers/errorUtil.js":["5dd3884a3b2637d4dac94d46dbd9342b99cb953d",403112,404208],"/project/workspace/node_modules/.pnpm/npm-packlist@2.2.2/node_modules/npm-packlist/index.js":["d123f52a824837376e369e3aec7507647a184883",404208,408136],"/project/workspace/node_modules/.pnpm/npm-bundled@1.1.2/node_modules/npm-bundled/index.js":["88712a69de7c4e83aa2d9430dc2214dfd10be5c0",408136,411448],"/project/workspace/node_modules/.pnpm/npm-normalize-package-bin@1.0.1/node_modules/npm-normalize-package-bin/index.js":["936296ddebc6348bed8f93e0063aa9b81e594a50",411448,412608],"/project/workspace/node_modules/.pnpm/ignore-walk@3.0.4/node_modules/ignore-walk/index.js":["44909c6d209ab59cd7a00c297c8f907baccb841f",412608,415864],"/project/workspace/node_modules/.pnpm/minimatch@3.1.2/node_modules/minimatch/minimatch.js":["f21a6b3c6d1d71bb65e4e6e0af1bf1baba3a207e",415864,420248],"/project/workspace/node_modules/.pnpm/brace-expansion@1.1.11/node_modules/brace-expansion/index.js":["a2f937621d39c20ce582f697c3e4273d1e14b2e0",420248,422296],"/project/workspace/node_modules/.pnpm/concat-map@0.0.1/node_modules/concat-map/index.js":["a3063f014cc693b320dbd64de3243a79247c1e05",422296,423072],"/project/workspace/node_modules/.pnpm/balanced-match@1.0.2/node_modules/balanced-match/index.js":["12161cfaa33be93568ec9a6fd3d9c357991a6a76",423072,423904],"/project/workspace/node_modules/.pnpm/glob@7.2.3/node_modules/glob/glob.js":["7b624669f35601648f8300b45c3b3861bd9c7ef6",423904,428976],"/project/workspace/node_modules/.pnpm/fs.realpath@1.0.0/node_modules/fs.realpath/index.js":["9b5cdf4ef79264959ed0a23e4c35efbe6d64b0df",428976,430440],"/project/workspace/node_modules/.pnpm/fs.realpath@1.0.0/node_modules/fs.realpath/old.js":["d2d656e98e4d0735902068408824f8d08aaea84c",430440,432280],"/project/workspace/node_modules/.pnpm/inherits@2.0.4/node_modules/inherits/inherits.js":["222da288a07d8f65b2aed9b88815948cfe0b42d9",432280,433064],"/project/workspace/node_modules/.pnpm/path-is-absolute@1.0.1/node_modules/path-is-absolute/index.js":["6de38a82f68960de2bd07fd9114541f02bee2f62",433064,433888],"/project/workspace/node_modules/.pnpm/glob@7.2.3/node_modules/glob/sync.js":["82b1c855e4bfca820ecbed219649cd174b0c2f62",433888,436968],"/project/workspace/node_modules/.pnpm/glob@7.2.3/node_modules/glob/common.js":["4890b7b6c34bc659a38802851951da90baad085d",436968,438720],"/project/workspace/node_modules/.pnpm/inflight@1.0.6/node_modules/inflight/inflight.js":["84aed0b47c15de35a85a5aa6c641342ba4dd5a88",438720,439752],"/project/workspace/node_modules/.pnpm/wrappy@1.0.2/node_modules/wrappy/wrappy.js":["7d5c1c908664b3df4a9b72400a126652ba0dd905",439752,440472],"/project/workspace/node_modules/.pnpm/once@1.4.0/node_modules/once/once.js":["f78c8cb8d754261b59d03e867f329c2ffdefae45",440472,441456],"/project/workspace/node_modules/.pnpm/fast-deep-equal@2.0.1/node_modules/fast-deep-equal/index.js":["7544a59317225a41d7c3b02605e87459a251ea54",441456,442312],"/project/workspace/node_modules/.pnpm/resolve-from@5.0.0/node_modules/resolve-from/index.js":["12204537847d8c5d27e3dbeb024c2def138bb3ae",442312,443360],"/project/workspace/node_modules/.pnpm/rollup@2.79.1/node_modules/rollup/dist/rollup.js":["528be32fbed11ca77d2ddc3fa5a4b83153c1a6f4",443360,444584],"/project/workspace/node_modules/.pnpm/rollup@2.79.1/node_modules/rollup/dist/shared/rollup.js":["1b070c5ac10253c28c8b66a3b89713db723a347e",444584,741336],"/project/workspace/node_modules/.pnpm/@rollup+plugin-node-resolve@11.2.1_rollup@2.79.1/node_modules/@rollup/plugin-node-resolve/dist/cjs/index.js":["4c7176cdf5a30cd0a7d1266fae5deac3a0b55858",741336,747976],"/project/workspace/node_modules/.pnpm/builtin-modules@3.3.0/node_modules/builtin-modules/index.js":["78b46fe2850f2a721658e7ee0494e2ac9967d969",747976,749016],"/project/workspace/node_modules/.pnpm/deepmerge@4.3.1/node_modules/deepmerge/dist/cjs.js":["30a374f658500f10d214d0c1b0aab81773cb6582",749016,751200],"/project/workspace/node_modules/.pnpm/is-module@1.0.0/node_modules/is-module/index.js":["eea7f2fb1af6df299384691d877d0cfd20060e1a",751200,752264],"/project/workspace/node_modules/.pnpm/@rollup+pluginutils@3.1.0_rollup@2.79.1/node_modules/@rollup/pluginutils/dist/cjs/index.js":["3f1a4e804542765b8ed26ef9c84451ad737a0e46",752264,757472],"/project/workspace/node_modules/.pnpm/@rollup+plugin-alias@3.1.9_rollup@2.79.1/node_modules/@rollup/plugin-alias/dist/index.js":["03c72c8b0000a9ae55e2629c7d348df1ec55d116",757472,758456],"/project/workspace/node_modules/.pnpm/@rollup+plugin-commonjs@15.1.0_rollup@2.79.1/node_modules/@rollup/plugin-commonjs/dist/index.js":["daa1dd2236b14ac67f24c4cac4d7ac04396b4fee",758456,771152],"/project/workspace/node_modules/.pnpm/commondir@1.0.1/node_modules/commondir/index.js":["62f48e7310292100f457fd315c1eaeabfb741a72",771152,771920],"/project/workspace/node_modules/.pnpm/estree-walker@2.0.2/node_modules/estree-walker/dist/umd/estree-walker.js":["12880a2841f321975ae59f2789d482753951bd1d",771920,774560],"/project/workspace/node_modules/.pnpm/magic-string@0.25.9/node_modules/magic-string/dist/magic-string.cjs.js":["f50cbc79c4a1f869984025ed5328e2da919fb6ba",774560,782680],"/project/workspace/node_modules/.pnpm/sourcemap-codec@1.4.8/node_modules/sourcemap-codec/dist/sourcemap-codec.umd.js":["dfa9b54ce6838473151cd191a4904db99063bcce",782680,783880],"/project/workspace/node_modules/.pnpm/is-reference@1.2.1/node_modules/is-reference/dist/is-reference.js":["568fec88af0aeead7c9719447c3968e506d4672b",783880,785136],"/project/workspace/node_modules/.pnpm/@rollup+plugin-replace@2.4.2_rollup@2.79.1/node_modules/@rollup/plugin-replace/dist/rollup-plugin-replace.cjs.js":["604d14be2deb4b6497cb252240415fac3753ec33",785136,786640],"/project/workspace/node_modules/.pnpm/magic-string@0.30.11/node_modules/magic-string/dist/magic-string.cjs.js":["a1b82214ad58aa225c3d8372a563a70c6df1753b",786640,796624],"/project/workspace/node_modules/.pnpm/@jridgewell+sourcemap-codec@1.5.0/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js":["f8c6b12bc867c6c3b76c14cd7bdab4e9c509048b",796624,801040],"/project/workspace/node_modules/.pnpm/@rollup+plugin-json@4.1.0_rollup@2.79.1/node_modules/@rollup/plugin-json/dist/index.js":["3adfd5d9369691483a6c1ef2087de488f2462a52",801040,801880],"/project/workspace/node_modules/.pnpm/jest-worker@26.6.2/node_modules/jest-worker/build/index.js":["69de41b40fe0bcb567f075c46d5c9e6221e71bbb",801880,804216],"/project/workspace/node_modules/.pnpm/jest-worker@26.6.2/node_modules/jest-worker/build/Farm.js":["5984ef8e7cd217ce38501bda08d5631a7e5a1d74",804216,806016],"/project/workspace/node_modules/.pnpm/jest-worker@26.6.2/node_modules/jest-worker/build/types.js":["6ac3d2e94b3e62de1635e2962750f77fbafc997f",806016,807104],"/project/workspace/node_modules/.pnpm/jest-worker@26.6.2/node_modules/jest-worker/build/WorkerPool.js":["5db5da39a2f1711c5bc5e13217a23a68d5b06860",807104,808520],"/project/workspace/node_modules/.pnpm/jest-worker@26.6.2/node_modules/jest-worker/build/base/BaseWorkerPool.js":["f17a88f0a0756a0e478bb4d1050f056c268639b5",808520,810936],"/project/workspace/node_modules/.pnpm/jest-worker@26.6.2/node_modules/jest-worker/build/workers/messageParent.js":["af373cbfef8bc3a2960cfdfcf21b056f591b75c8",810936,811944],"/project/workspace/node_modules/.pnpm/ci-info@3.9.0/node_modules/ci-info/index.js":["306147110a81e4d70b7952dedf1e7f2721b72866",811944,813528],"/project/workspace/node_modules/.pnpm/quick-lru@5.1.1/node_modules/quick-lru/index.js":["94a42747caa09e0af0d52f35c6ba68c78b9a6018",813528,815376],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/index.js":["c01f38060f8c1eea0a62ee127afc3a7601029818",815376,819608],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/internal/re.js":["4847405c77f0465eb4baebe1385b155e72b57f6a",819608,826808],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/internal/constants.js":["819a733e61b6014ca6feeb6a570304612afe2b52",826808,828040],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/internal/debug.js":["d6166e7a8eda16340619cb02ee09c19a422b8333",828040,828944],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/classes/semver.js":["209950c633d84021324a834a14dbcbf0fb3202f4",828944,831024],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/internal/parse-options.js":["19a8ad4d2c32f4386402bd9eb235df80c73a8f75",831024,831872],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/internal/identifiers.js":["510c174c5bfc993023542e3b4f699cd18e2e0559",831872,832744],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/parse.js":["1bfe17569d11f23f9a539340cee18bba0e3f4f0a",832744,833488],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/valid.js":["edc5b800b8f302ac7ce238a419a02810cdeed8f2",833488,834216],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/clean.js":["92466e73dbb620c7b0c58b16e8d39a6d0ff22bc5",834216,834944],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/inc.js":["5814d4948ca724f91f2b61213c011bf8034f112f",834944,835680],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/diff.js":["a52f6ea79cf0224fda0d44968159b8dc13e36d7c",835680,836408],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/major.js":["5e2668d635ca6c7bde9bc1b7f763f26674e83c11",836408,837152],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/minor.js":["4bc0bc3ec293449f5fea1cbcfe976c8d2a26cce5",837152,837896],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/patch.js":["a78ef0c69e82d2a7b1f4f697e620aef6ad1de458",837896,838640],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/prerelease.js":["40a72fe55e64efcc0a5c6b859a0378ab030837db",838640,839376],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/compare.js":["33ec903e117ba1fe05cddedb86a9601d94e193a7",839376,840104],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/rcompare.js":["51f8192667aa9e1320e7fe0616b583039e8042c0",840104,840824],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/compare-loose.js":["1c581d61f0ab057af7fed4ad01c66d0998d1aa03",840824,841560],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/compare-build.js":["97ac51143c3f5c2255ba09c0ec0f952a2aecd8d1",841560,842320],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/sort.js":["b7fc2bc365d5f6f9e2ad842441755e7b8b19de5c",842320,843056],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/rsort.js":["1e99dcf8aa9518558b2a6945302273ac7b8d69bc",843056,843800],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/gt.js":["d5e2d5e6294e56ee0a42e92e3a89d8cf294cb833",843800,844512],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/lt.js":["fad43ee11cd4b18e2fbaf50593ae540f27365a87",844512,845224],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/eq.js":["498639a97e5682386b94c24096f133db4fd163d0",845224,845936],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/neq.js":["dfa93428b2368cff5aefd91d812bed067cb31ad6",845936,846648],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/gte.js":["b9c50a385c8e3877108a001fb8548b122a155193",846648,847360],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/lte.js":["bd1875ed01c16e0bf753352e775cfc3d993cc228",847360,848072],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/cmp.js":["50a23a530aac08f1545e15bf6441bf031282789e",848072,849128],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/coerce.js":["c64737eb38e2f78a361af16155116dc84c2af368",849128,850064],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/classes/comparator.js":["bbb95e311cc51af3911406848972f6cc50761d8f",850064,852048],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/classes/range.js":["49ea81742058369f806770d7d1b1a73192f0ca75",852048,855832],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/internal/lrucache.js":["26ae88faff2fd3ef9fbda59267979c98a1fea511",855832,856976],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/satisfies.js":["47a3e3141433768a2ca6a03841c842d15cf419c2",856976,857720],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/ranges/to-comparators.js":["4d609454b2e81450d85be8f56109af8ba6b61b92",857720,858464],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/ranges/max-satisfying.js":["4dcef246781158eef12758041375d1bce437a383",858464,859288],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/ranges/min-satisfying.js":["2155aea4b92343159e1b803f878a47297ca9aa66",859288,860112],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/ranges/min-version.js":["04dab32f676a52ee4c81f440eb1b5d6c7511afa5",860112,861016],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/ranges/valid.js":["7a1c6afbe83e28264a384b43ab8f6765f7649114",861016,861752],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/ranges/outside.js":["c6f8b84ebd967e5479159e2f876f3ba27530eb97",861752,863104],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/ranges/gtr.js":["4f69fb02e28923fe7126531d80862dc85bf94c19",863104,863832],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/ranges/ltr.js":["d4948b6f660390895f8ac0cfe4cad97bc1f15190",863832,864544],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/ranges/intersects.js":["3763224a30a86582b56a4cdf1ebaa97b5038e1c8",864544,865288],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/ranges/simplify.js":["bc651999d477c5698289adcd2ed8773cf7a2da11",865288,866144],"/project/workspace/node_modules/.pnpm/semver@7.6.3/node_modules/semver/ranges/subset.js":["94dce217bb98598dad72f194de19c5e2f3246d7b",866144,867672],"/project/workspace/node_modules/.pnpm/ms@2.1.3/node_modules/ms/index.js":["ea869663486f513cc4d1ca8312ed52a165c417fa",867672,868800],"/project/workspace/node_modules/.pnpm/@babel+helpers@7.25.0/node_modules/@babel/helpers/lib/index.js":["357f5f097a45815db5a715e876269d5bfabd7dac",868800,870632],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/index.js":["b4a694814012bf73e5e969685037c929ba16bfe1",870632,892264],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/react/isReactComponent.js":["95f5d5dc4b45810514357c0380914dc58241ba24",892264,893120],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/buildMatchMemberExpression.js":["e5d43e99dde5f498e5a3a92e71f2e952b501aac3",893120,894056],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/matchesPattern.js":["8454cf4b6cbd50a08bbc3c1de9ab5c16de493b00",894056,894944],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/generated/index.js":["5397377964d899fec62d8c34ffefadcf2fc440db",894944,926120],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/utils/shallowEqual.js":["10edc2f8f2dc3288ac96e3945e4ec1c0488f6487",926120,926904],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/utils/deprecationWarning.js":["afa3da502a334e2761cdd333fd39352dc94fc835",926904,927904],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/react/isCompatTag.js":["ff2f399e3c4be990b0da48d9bcba447ac6d461a2",927904,928696],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/builders/react/buildChildren.js":["9d4954881254318ce49c25a46c0e273cc92ed501",928696,929736],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/utils/react/cleanJSXElementLiteralChild.js":["6144987d113b19878587b0e55dbc45742bc61377",929736,930768],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/builders/generated/index.js":["09d118993950e33889672839e3812c3efd3524e0",930768,960608],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/builders/validateNode.js":["9f3d5f96da42cbf270e2324816aa2715fa7b8859",960608,961584],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/validate.js":["23bcdbb590e36bbf25fc5cddd90dd95806ca36e6",961584,962648],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/definitions/index.js":["75473cc26234f822479cf98daa1deb187f85bf7e",962648,966648],"/project/workspace/node_modules/.pnpm/to-fast-properties@2.0.0/node_modules/to-fast-properties/index.js":["6308ff82e9bca6a67e7aa25111f0105f1fee89fc",966648,967456],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/definitions/core.js":["0c388d4068048171798d941e2e7fb357320b05ff",967456,1019344],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/is.js":["ca3a7002a5b3266c519975795feb3df111781548",1019344,1020456],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/isType.js":["c35549269452b8a2efed8d388de69e86d02446ad",1020456,1021320],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/isPlaceholderType.js":["29b3523f38b94f9a08d792cc9719bac32db78d27",1021320,1022216],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/isValidIdentifier.js":["2b54d4a54bd63122fc8ce0a01eb531972c85eebc",1022216,1023152],"/project/workspace/node_modules/.pnpm/@babel+helper-string-parser@7.24.8/node_modules/@babel/helper-string-parser/lib/index.js":["3208fae30d742f71f09711bad362b9f09c5a79a6",1023152,1025352],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/constants/index.js":["49f82c5373bcdc59fc1fe32267648bc6c5d9b0c2",1025352,1029584],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/definitions/utils.js":["94640118c885a5ce4b4172f1de7970677860a744",1029584,1033280],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/definitions/flow.js":["616514b741caeea6bb56cdcc38754dd10c9d1d72",1033280,1052584],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/definitions/jsx.js":["75150a8a7b5f295714f618445a43b5be5134b3df",1052584,1058136],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/definitions/misc.js":["81f57e1e1fb15e0918d7a46502025a4ab0d1f9d4",1058136,1059712],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/definitions/placeholders.js":["b2e696e21aeae96071880f487af8883f6e8be92d",1059712,1061440],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/definitions/experimental.js":["d79101cd151187ddfd0dd80c38f777759d01ae5d",1061440,1066960],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/definitions/typescript.js":["79cde51962b6d573285de195a91c6954d794ae8b",1066960,1086072],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/definitions/deprecated-aliases.js":["f29794e441858c3e2f2b1085aecb4c756d77d711",1086072,1086952],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/asserts/assertNode.js":["f1638bb583fe74ab8bb9a1bc6f454b491a348274",1086952,1087832],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/isNode.js":["17f73842d38e0825ffa9f577e40f179503ee031b",1087832,1088696],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/asserts/generated/index.js":["148205bd999ad2039159ece59f6c8ac33a33606a",1088696,1121256],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/builders/flow/createTypeAnnotationBasedOnTypeof.js":["8769a998687162bc7550dcfe98a9e81f2d74a459",1121256,1122216],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/builders/flow/createFlowUnionType.js":["3c7a20f8b066ef7f858dcf14d6afcf1698ee141c",1122216,1123256],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/modifications/flow/removeTypeDuplicates.js":["f70e4d934e2b3b696ef00b1e34fee8ff252458e6",1123256,1124280],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/builders/typescript/createTSUnionType.js":["ac99b6bbdb3ee5879edb6ba5dbb012f987ef690b",1124280,1125416],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/modifications/typescript/removeTypeDuplicates.js":["54976f3b36b1e7db28188129aa2098282846f807",1125416,1126440],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/builders/generated/uppercase.js":["01146dc1a091c09905f4d4bd51bd9befcfc6013b",1126440,1182408],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/builders/productions.js":["5bf863371b472963ae72c1e64ac1b8630367ac2b",1182408,1183288],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/clone/cloneNode.js":["f15454de0a71e53a1e42faa07ef39ba7f8747f67",1183288,1184792],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/clone/clone.js":["00c128835dc3ef60c50001bc0e1372f29b797cd4",1184792,1185648],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/clone/cloneDeep.js":["0edb67fa97425f2d4079c8c64e097d0ddd5eb0cc",1185648,1186520],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/clone/cloneDeepWithoutLoc.js":["e7719f2ecf0c0657c5b6068c09af3c3bf0592068",1186520,1187424],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/clone/cloneWithoutLoc.js":["f63ebfbdab6d34badb74fd376c38f5cc8930423c",1187424,1188304],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/comments/addComment.js":["16f2d359874230847f36cb97742de44472f84594",1188304,1189184],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/comments/addComments.js":["c62e5ffd8cb9350cf9bc0589ca476d009ac85f9a",1189184,1189968],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/comments/inheritInnerComments.js":["d040738ed2802ba9d61a8394fe6c9ee65d734a76",1189968,1190872],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/utils/inherit.js":["5896fd13c8a775e0155b7185805c9727329f6730",1190872,1191632],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/comments/inheritLeadingComments.js":["f87077b689c318c639537f4c42698ed278e4f829",1191632,1192544],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/comments/inheritsComments.js":["42f6cbab43c95c7d831a62a991f7ae449cd9b5d8",1192544,1193672],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/comments/inheritTrailingComments.js":["5bd6c9b811fbe4893a2fbef744b7374e2c1e84c7",1193672,1194584],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/comments/removeComments.js":["a6564e4d0b4893afb3d965c187c6ee3c9990ee77",1194584,1195472],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/constants/generated/index.js":["150c5b7b3b23479f3e251f6341bd26ee2c70b185",1195472,1200936],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/converters/ensureBlock.js":["9546e15b033129e9d14e953a1e431f1f9bf88824",1200936,1201816],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/converters/toBlock.js":["e42f617eb9a3d06d9e088fa1e41225b663c2bff9",1201816,1202784],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/converters/toBindingIdentifierName.js":["26959a098e207bbb2842e79e7bccdbabe8323408",1202784,1203704],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/converters/toIdentifier.js":["bb776190e90daa84973bc9941adcdd8193bd1e5e",1203704,1204776],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/converters/toComputedKey.js":["9eecc51376934654679e0386cd244a8dda5f0baf",1204776,1205768],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/converters/toExpression.js":["c6891bc3f4882d86e3e6dbff896c85ce44923cb4",1205768,1206672],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/converters/toKeyAlias.js":["5fbdc0ac8dc95b5eabec0be50d71e6c0865ce35c",1206672,1207928],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/modifications/removePropertiesDeep.js":["23860ef1d6c45e8f71b8228a1f377668e8c96f1b",1207928,1208960],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/traverse/traverseFast.js":["67af8be359598f6a3aafc7637358f7046033aeca",1208960,1209848],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/modifications/removeProperties.js":["73107880504998df7f8c5b3bd7a278383e84c8bc",1209848,1211088],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/converters/toStatement.js":["574ede0cdc26b05072b0646e7d66221fa1da6558",1211088,1212088],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/converters/valueToNode.js":["8b5b35bc076f64bd9672753d23da7ec67b106fd8",1212088,1213416],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/modifications/appendToMemberExpression.js":["27439fd3e557f640b2f818d7361fc0c12f46cb43",1213416,1214344],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/modifications/inherits.js":["746ddefd49e0fbafb0f53d49ac490d9e5a67eccf",1214344,1215328],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/modifications/prependToMemberExpression.js":["5a713459848abc5691a7b9f14ad0112175c90ae5",1215328,1216344],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/retrievers/getAssignmentIdentifiers.js":["56001c75c4a7d7d9734e6f5410d5feef3c61a3c0",1216344,1217160],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/retrievers/getBindingIdentifiers.js":["09124ac3269656d268bb5bb4745670c8961541ff",1217160,1220576],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/retrievers/getOuterBindingIdentifiers.js":["d0c30354a56b626a2a1533a68dd36f03d75f35d1",1220576,1221544],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/retrievers/getFunctionName.js":["0fb9488c606146a2e06e65a956f17c5ed503955b",1221544,1222616],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/traverse/traverse.js":["7992ab182de5d6e2635aa63d27e20ae6119fd085",1222616,1223560],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/isBinding.js":["4184b924d4bf2122e4d64d4661db34225e6ce581",1223560,1224464],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/isBlockScoped.js":["551efbe73814fbdf9b09af1a6dbd9edab8ca12c9",1224464,1225432],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/isLet.js":["3a0c0986cdca1871a5c5ed9260abcc71f3622c6d",1225432,1226384],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/isImmutable.js":["87ce8fd906f5fe6fea21757f3b96e2dbf10d45b9",1226384,1227352],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/isNodesEquivalent.js":["8de1678d5fea7521128e49da8471adb7ac189ad8",1227352,1228256],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/isReferenced.js":["8759a5583bcae62a90768a3418d106c78e08f2fe",1228256,1229048],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/isScope.js":["db0b7d08fe2f223e5bb846f2713a608d9c4d3204",1229048,1229912],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/isSpecifierDefault.js":["8c8652248a736fc000db5f45ec1d1a0570acb952",1229912,1230816],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/isValidES3Identifier.js":["49d11809665072371ec9b0d5fe83f5214001eb6f",1230816,1232296],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/validators/isVar.js":["a8ac19b347058fbb51e9c0b9b35a838cd9c6ef14",1232296,1233248],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/converters/toSequenceExpression.js":["9384f95b71f9748d64908bdc9b4b675c12d14104",1233248,1234192],"/project/workspace/node_modules/.pnpm/@babel+types@7.25.2/node_modules/@babel/types/lib/converters/gatherSequenceExpressions.js":["ba5ecf63baf8dfbe57529a29490ad381b7c8625b",1234192,1235512],"/project/workspace/node_modules/.pnpm/@babel+helpers@7.25.0/node_modules/@babel/helpers/lib/helpers-generated.js":["bdfe68621914607bd09d0c2a3dc4e7a2d74a3b9f",1235512,1349088],"/project/workspace/node_modules/.pnpm/@babel+template@7.25.0/node_modules/@babel/template/lib/index.js":["9a3926ea29ec8d546e723aa8a1353306e0bd0ad5",1349088,1350408],"/project/workspace/node_modules/.pnpm/@babel+template@7.25.0/node_modules/@babel/template/lib/formatters.js":["f9b9d9a37cbf61be7616b0656d92b8b79fa52b1f",1350408,1352528],"/project/workspace/node_modules/.pnpm/@babel+template@7.25.0/node_modules/@babel/template/lib/builder.js":["f23864c5185e593ed3929af741bf8a1ee43b4603",1352528,1353784],"/project/workspace/node_modules/.pnpm/@babel+template@7.25.0/node_modules/@babel/template/lib/options.js":["a2154aa8b4523eac2c1c71ebfcba32308afcd31f",1353784,1355040],"/project/workspace/node_modules/.pnpm/@babel+template@7.25.0/node_modules/@babel/template/lib/string.js":["d4bd2d379e5c5247bb0e825aa911836b07a7ad72",1355040,1356056],"/project/workspace/node_modules/.pnpm/@babel+template@7.25.0/node_modules/@babel/template/lib/parse.js":["1a725f4ba5a1fe7a4fcd95195b3d01be192b747d",1356056,1357960],"/project/workspace/node_modules/.pnpm/@babel+parser@7.25.3/node_modules/@babel/parser/lib/index.js":["d150d62841d0f12e7f4b42f5291013c9b1ebde79",1357960,1500848],"/project/workspace/node_modules/.pnpm/@babel+template@7.25.0/node_modules/@babel/template/lib/populate.js":["77692699c5cb74c059e0c9c786e2ffb59a68f434",1500848,1502256],"/project/workspace/node_modules/.pnpm/@babel+template@7.25.0/node_modules/@babel/template/lib/literal.js":["9f9a7059025c507617ea6303f9106ee2e53ddcb9",1502256,1503440],"/project/workspace/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/index.js":["c98c5ea2b11bbdb4bccf13ff70509990fad9919f",1503440,1504824],"/project/workspace/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/source-map.js":["5b5a15c3b2d5fec4b5c62457f3016e8aa33a46f0",1504824,1506376],"/project/workspace/node_modules/.pnpm/@jridgewell+gen-mapping@0.3.5/node_modules/@jridgewell/gen-mapping/dist/gen-mapping.umd.js":["f59a96193c4d0050b224b915ec09303a0b363013",1506376,1510376],"/project/workspace/node_modules/.pnpm/@jridgewell+set-array@1.2.1/node_modules/@jridgewell/set-array/dist/set-array.umd.js":["20be9f5c3d323c9aca346a00e62f8d7e4a1fefa0",1510376,1512440],"/project/workspace/node_modules/.pnpm/@jridgewell+trace-mapping@0.3.25/node_modules/@jridgewell/trace-mapping/dist/trace-mapping.umd.js":["d14969c9417dabccd90411b4770dc55726dea41d",1512440,1518600],"/project/workspace/node_modules/.pnpm/@jridgewell+resolve-uri@3.1.2/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.umd.js":["3d56b7861cb317124e76dc7f2caac7d4c8cf3a86",1518600,1521264],"/project/workspace/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/printer.js":["87b6083bdeb088244d146ec7094b137c7d19ff47",1521264,1528248],"/project/workspace/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/buffer.js":["1e5f3acd7d2127345524d342f8aeecb542146a50",1528248,1531456],"/project/workspace/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/node/index.js":["84c5abeb85944041673e6fa57c883a880e59e2d0",1531456,1533856],"/project/workspace/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/node/whitespace.js":["6432f37adcbacc354300b84a879ef6e0e504341a",1533856,1537576],"/project/workspace/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/node/parentheses.js":["616888cbcfd6f0e0b898aff092aae10647710d25",1537576,1543152],"/project/workspace/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/generators/index.js":["19e79ce1eedfd872c35b815d444f6288c4050140",1543152,1546040],"/project/workspace/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/generators/template-literals.js":["9069eae70537e6d8145bdcd443a7322a884edbcb",1546040,1547024],"/project/workspace/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/generators/expressions.js":["7c7d6368f96052f5613036cd7504ffdb1fbc5c67",1547024,1550568],"/project/workspace/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/generators/statements.js":["bba4e7700a33a7c482fb2de6620782ce25e03a34",1550568,1553504],"/project/workspace/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/generators/classes.js":["95b2bae54b2cda46b6bcfcf2bfc9f455f045fcdd",1553504,1555208],"/project/workspace/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/generators/methods.js":["6f0304fea2d5eaa3884b09293ee074a50e0ecd45",1555208,1556984],"/project/workspace/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/generators/modules.js":["437038a7e68f202f78dd78b70156899cf75e6ff5",1556984,1559488],"/project/workspace/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/generators/types.js":["09778cd4447014d0bb8f4d6053d455da8b990f3a",1559488,1562440],"/project/workspace/node_modules/.pnpm/jsesc@2.5.2/node_modules/jsesc/jsesc.js":["1ddb9ef6ced291147886096f09527cb1980a5572",1562440,1564640],"/project/workspace/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/generators/flow.js":["5d7383206f35f019e6364dbd6930405141c3c74a",1564640,1572640],"/project/workspace/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/generators/base.js":["51d18e9c693ca992d7d0a779deac61c493cb0e32",1572640,1574120],"/project/workspace/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/generators/jsx.js":["85bf426cf47cadb0aebb50eb9f23b2c7e1b24d7c",1574120,1576248],"/project/workspace/node_modules/.pnpm/@babel+generator@7.25.0/node_modules/@babel/generator/lib/generators/typescript.js":["9a4ed7457f46c3c1159be1b9847355edbe87c70c",1576248,1583672]} \ No newline at end of file diff --git a/wagmi-project/.changeset/README.md b/wagmi-project/.changeset/README.md new file mode 100644 index 0000000000..e5b6d8d6a6 --- /dev/null +++ b/wagmi-project/.changeset/README.md @@ -0,0 +1,8 @@ +# Changesets + +Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works +with multi-package repos, or single-package repos to help you version and publish your code. You can +find the full documentation for it [in our repository](https://github.com/changesets/changesets) + +We have a quick list of common questions to get you started engaging with this project in +[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) diff --git a/wagmi-project/.changeset/config.json b/wagmi-project/.changeset/config.json new file mode 100644 index 0000000000..c47279e4c8 --- /dev/null +++ b/wagmi-project/.changeset/config.json @@ -0,0 +1,19 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@2.3.1/schema.json", + "access": "public", + "baseBranch": "main", + "changelog": ["@changesets/changelog-github", { "repo": "wevm/wagmi" }], + "commit": false, + "ignore": [ + "*-register", + "@wagmi/test", + "site", + "next-app", + "nuxt-app", + "vite-*" + ], + "updateInternalDependencies": "patch", + "___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": { + "onlyUpdatePeerDependentsWhenOutOfRange": true + } +} diff --git a/wagmi-project/.changeset/new-elephants-travel.md b/wagmi-project/.changeset/new-elephants-travel.md new file mode 100644 index 0000000000..ddfb37374a --- /dev/null +++ b/wagmi-project/.changeset/new-elephants-travel.md @@ -0,0 +1,5 @@ +--- +"@wagmi/cli": patch +--- + +Updated block explorer chains. diff --git a/wagmi-project/.changeset/nice-pandas-clap.md b/wagmi-project/.changeset/nice-pandas-clap.md new file mode 100644 index 0000000000..7f4af53010 --- /dev/null +++ b/wagmi-project/.changeset/nice-pandas-clap.md @@ -0,0 +1,5 @@ +--- + +--- + +Circleci project setup diff --git a/wagmi-project/.changeset/quick-hairs-scream.md b/wagmi-project/.changeset/quick-hairs-scream.md new file mode 100644 index 0000000000..206e94e246 --- /dev/null +++ b/wagmi-project/.changeset/quick-hairs-scream.md @@ -0,0 +1,6 @@ +--- +"wagmi": patch +"@wagmi/core": patch +--- + +Added `chainId` parameter to `getCapabilities`/`useCapabilities`. diff --git a/wagmi-project/.changeset/spicy-bats-juggle.md b/wagmi-project/.changeset/spicy-bats-juggle.md new file mode 100644 index 0000000000..cf7a154229 --- /dev/null +++ b/wagmi-project/.changeset/spicy-bats-juggle.md @@ -0,0 +1,6 @@ +--- +"@wagmi/cli": patch +"site": patch +--- + +Circleci project setup diff --git a/wagmi-project/.changeset/tall-fans-mate.md b/wagmi-project/.changeset/tall-fans-mate.md new file mode 100644 index 0000000000..cf7a154229 --- /dev/null +++ b/wagmi-project/.changeset/tall-fans-mate.md @@ -0,0 +1,6 @@ +--- +"@wagmi/cli": patch +"site": patch +--- + +Circleci project setup diff --git a/wagmi-project/.changeset/tiny-laws-dream.md b/wagmi-project/.changeset/tiny-laws-dream.md new file mode 100644 index 0000000000..c39a3d68b9 --- /dev/null +++ b/wagmi-project/.changeset/tiny-laws-dream.md @@ -0,0 +1,5 @@ +--- +"@fake-scope/fake-pkg": patch +--- + +Circleci project setup diff --git a/wagmi-project/.changeset/young-guests-care.md b/wagmi-project/.changeset/young-guests-care.md new file mode 100644 index 0000000000..8de2292dde --- /dev/null +++ b/wagmi-project/.changeset/young-guests-care.md @@ -0,0 +1,5 @@ +--- +"site": patch +--- + +docs(readme): fix typo diff --git a/wagmi-project/.circleci/config.yml b/wagmi-project/.circleci/config.yml new file mode 100644 index 0000000000..709c9a7474 --- /dev/null +++ b/wagmi-project/.circleci/config.yml @@ -0,0 +1,26 @@ +# Use the latest 2.1 version of CircleCI pipeline process engine. +# See: https://circleci.com/docs/configuration-reference + +version: 2.1 +executors: + my-custom-executor: + docker: + - image: cimg/base:stable + auth: + # ensure you have first added these secrets + # visit app.circleci.com/settings/project/github/Dargon789/hardhat-project/environment-variables + username: $DOCKER_HUB_USER + password: $DOCKER_HUB_PASSWORD +jobs: + web3-defi-game-project-: + + executor: my-custom-executor + steps: + - checkout + - run: | + # echo Hello, World! + +workflows: + my-custom-workflow: + jobs: + - web3-defi-game-project- diff --git a/wagmi-project/.github/CODEOWNERS b/wagmi-project/.github/CODEOWNERS new file mode 100644 index 0000000000..12451d4bc9 --- /dev/null +++ b/wagmi-project/.github/CODEOWNERS @@ -0,0 +1,5 @@ +@tmm @jxom + +/packages/connectors/src/metaMask @ecp4224 @omridan159 @abretonc7s @elefantel @BjornGunnarsson @EdouardBougon +/packages/connectors/src/safe @DaniSomoza @dasanra @mikhailxyz @yagopv +/packages/connectors/src/walletConnect @ganchoradkov @glitch-txs @ignaciosantise @tomiir diff --git a/wagmi-project/.github/CONTRIBUTING.md b/wagmi-project/.github/CONTRIBUTING.md new file mode 100644 index 0000000000..d3ab387e17 --- /dev/null +++ b/wagmi-project/.github/CONTRIBUTING.md @@ -0,0 +1 @@ +[View Contributing Guide on wagmi.sh](https://wagmi.sh/dev/contributing) \ No newline at end of file diff --git a/wagmi-project/.github/DISCUSSION_TEMPLATE/connector-request.yml b/wagmi-project/.github/DISCUSSION_TEMPLATE/connector-request.yml new file mode 100644 index 0000000000..c1e31b1b6b --- /dev/null +++ b/wagmi-project/.github/DISCUSSION_TEMPLATE/connector-request.yml @@ -0,0 +1,51 @@ +title: '[Connector Request] ' +body: + - type: markdown + attributes: + value: | + Thanks for your interest in contributing a new Connector to the Wagmi! If you haven't already, please read the [Contributing Guidelines](https://wagmi.sh/dev/contributing). Once you submit the form, the Wagmi team will follow up in the discussion thread to discuss next steps. + + Please note that in order for connector requests to be accepted, the team creating the Connector must [sponsor Wagmi](https://github.com/sponsors/wevm). It takes time and effort to maintain third-party connectors. Wagmi is an OSS project that depends on sponsors and grants to continue our work. Please get in touch via [dev@wevm.dev](mailto:dev@wevm.dev) if you have questions about sponsoring. + + - type: textarea + attributes: + label: What **novel use-case** does the Connector provide? + description: | + A novel use-case is likely one that is not already covered by or not easily extended from another Connector (such as the `injected` or `walletConnect`). + + Examples of **novel** use-cases could be a connector that integrates with: + + - the injected `window.ethereum` provider (a la `injected`) + - a series of wallets via QR Codes or Mobile Deep Links (a la `walletConnect`) + - a wallet with it's own SDK (a la `coinbaseWallet`) + - hardware wallet(s) via Web USB/Bluetooth + - an Externally Owned Account via a private key or some other method + + Examples of **nonnovel** use-cases would be a connector that: + + - extends another connector (e.g. `walletConnect`) with no significant differences in functionality other than branding, etc. + placeholder: Info on what makes this connector different. + validations: + required: true + + - type: textarea + attributes: + label: Are the Connector's integrations production-ready and generally available? + description: Connectors are intended to be used by consumers in production as part of Wagmi. As such, the Connector and all dependencies must be production-ready and generally available. This means your connector should not rely on non-production software or be restricted to a limited group of users. For example, if your connector requires a wallet that has a closed beta, it is not ready for inclusion in Wagmi. + placeholder: Info about the Connector and any dependencies (e.g. browser extension, wallet app, npm package). + validations: + required: true + + - type: checkboxes + attributes: + label: Are you committed to actively maintaining the Connector? + description: It is critical connectors are updated in a timely manner and actively maintained so that users of Wagmi can rely on them in production settings. The Wagmi core team will provide as much assistance as possible to keep connectors up-to-date with breaking changes from Wagmi, but it is your responsibility to ensure that any dependencies and issues/discussions related to the Connector are handled in a timely manner. If this is not done, the Connector could be removed from the future versions. + options: + - label: Yes, my team is or I am committed to actively maintaining the Connector. + required: true + + - type: textarea + attributes: + label: Additional comments + description: Feel free to jot down any additional info you think might be helpful. + placeholder: Additional comments, questions, feedback. diff --git a/wagmi-project/.github/ISSUE_TEMPLATE/bug_report.yml b/wagmi-project/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000000..8a561abba1 --- /dev/null +++ b/wagmi-project/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,88 @@ +name: Bug Report +description: Report bugs or issues. +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out this bug report! The more info you provide, the more we can help you. + + If you are a [Wagmi Sponsor](https://github.com/sponsors/wevm?metadata_campaign=gh_issue), your issues are prioritized. + + - type: checkboxes + attributes: + label: Check existing issues + description: By submitting this issue, you checked there isn't [already an issue](https://github.com/wevm/wagmi/issues) for this bug. + options: + - label: I checked there isn't [already an issue](https://github.com/wevm/wagmi/issues) for the bug I encountered. + required: true + + - type: textarea + attributes: + label: Describe the bug + description: Clear and concise description of the bug. If you intend to submit a PR for this issue, tell us in the description. Thanks! + placeholder: I am doing… What I expect is… What is actually happening… + validations: + required: true + + - type: input + id: reproduction + attributes: + label: Link to Minimal Reproducible Example + description: "Please provide a link that can reproduce the problem: [new.wagmi.sh](https://new.wagmi.sh) for runtime issues or [TypeScript Playground](https://www.typescriptlang.org/play) for type issues. For most issues, you will likely get asked to provide a minimal reproducible example so why not add one now :) If a report is vague (e.g. just snippets, generic error message, screenshot, etc.) and has no reproduction, it will receive a \"Needs Reproduction\" label and be auto-closed." + placeholder: https://new.wagmi.sh + validations: + required: false + + - type: textarea + attributes: + label: Steps To Reproduce + description: Steps or code snippets to reproduce the behavior. + validations: + required: false + + - type: dropdown + attributes: + label: What Wagmi package(s) are you using? + multiple: true + options: + - 'wagmi' + - '@wagmi/cli' + - '@wagmi/connectors' + - '@wagmi/core' + - '@wagmi/vue' + - 'create-wagmi' + validations: + required: true + + - type: input + attributes: + label: Wagmi Package(s) Version(s) + description: What version of the Wagmi packages you selected above are you using? If using multiple, separate with comma (e.g. `wagmi@x.y.z, @wagmi/cli@x.y.z`). + placeholder: x.y.z (do not write `latest`) + validations: + required: true + + - type: input + attributes: + label: Viem Version + description: What version of [Viem](https://viem.sh) are you using? + placeholder: x.y.z (do not write `latest`) + validations: + required: true + + - type: input + attributes: + label: TypeScript Version + description: What version of TypeScript are you using? Wagmi requires `typescript@>=5`. + placeholder: x.y.z (do not write `latest`) + validations: + required: false + + - type: textarea + attributes: + label: Anything else? + description: Anything that will give us more context about the issue you are encountering. Framework version (e.g. React, Vue), app framework (e.g. Next.js, Nuxt), bundler, etc. + validations: + required: false + + diff --git a/wagmi-project/.github/ISSUE_TEMPLATE/config.yml b/wagmi-project/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000000..fc8027c871 --- /dev/null +++ b/wagmi-project/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,14 @@ +blank_issues_enabled: false +contact_links: + - name: Get Help + url: https://github.com/wevm/wagmi/discussions/new?category=q-a + about: Ask a question and discuss with other community members. + + - name: Feature Request + url: https://github.com/wevm/wagmi/discussions/new?category=ideas + about: Request features or brainstorm ideas for new functionality. + + - name: Connector Request + url: https://github.com/wevm/wagmi/discussions/new?category=connector-request + about: Kick off a request for a new connector + diff --git a/wagmi-project/.github/ISSUE_TEMPLATE/docs_issue.yml b/wagmi-project/.github/ISSUE_TEMPLATE/docs_issue.yml new file mode 100644 index 0000000000..f2d53b8a98 --- /dev/null +++ b/wagmi-project/.github/ISSUE_TEMPLATE/docs_issue.yml @@ -0,0 +1,34 @@ +name: Documentation Issue +description: Tell us about missing or incorrect documentation. +labels: ['Area: Docs'] +body: + - type: markdown + attributes: + value: | + Thank you for submitting a documentation request. It helps make Wagmi better. + + If it's a small change, like misspelling or example that needs updating, feel free to submit a PR instead of creating this issue. + + - type: dropdown + attributes: + label: What is the type of issue? + multiple: true + options: + - Documentation is missing + - Documentation is incorrect + - Documentation is confusing + - Example code is not working + - Something else + + - type: textarea + attributes: + label: What is the issue? + validations: + required: true + + - type: textarea + attributes: + label: Where did you find it? + description: Please provide the URL(s) where you found this issue. + validations: + required: true diff --git a/wagmi-project/.github/README.md b/wagmi-project/.github/README.md new file mode 100644 index 0000000000..6b5f336419 --- /dev/null +++ b/wagmi-project/.github/README.md @@ -0,0 +1,256 @@ + + + +
+ +

+ + + + wagmi logo + + +

+ +

+ Reactive primitives for Ethereum apps +

+ +

+ + + + Version + + + + + + MIT License + + + + + + Downloads per month + + + + + + Best of JS + + + + + + Code coverage + + +

+ +--- + +## Documentation + +For documentation and guides, visit [wagmi.sh](https://wagmi.sh). + +## Community + +For help, discussion about best practices, or any other conversation that would benefit from being searchable: + +[Discuss Wagmi on GitHub](https://github.com/wevm/wagmi/discussions) + +For casual chit-chat with others using the framework: + +[Join the Wagmi Discord](https://discord.gg/SghfWBKexF) + +## Contributing + +Contributions to Wagmi are greatly appreciated! If you're interested in contributing to Wagmi, please read the [Contributing Guide](https://wagmi.sh/dev/contributing) **before submitting a pull request**. + +## Sponsors + +If you find Wagmi useful or use it for work, please consider [sponsoring Wagmi](https://github.com/sponsors/wevm?metadata_campaign=gh_readme_support). Thank you šŸ™ + +

+ + + + paradigm logo + + + + + + ithaca logo + + +

+ +

+ + + + family logo + + + + + + context logo + + + + + + WalletConnect logo + + + + + + PartyDAO logo + + + + + + Dynamic logo + + + + + + Sushi logo + + + + + + Stripe logo + + + + + + Privy logo + + + + + + pancake logo + + + + + + celo logo + + + + + + rainbow logo + + + + + + pimlico logo + + + + + + zora logo + + + + + + lattice logo + + + + + + supa logo + + + + + + zksync logo + + + + + + syndicate logo + + + + + + reservoir logo + + + + + + linea logo + + + + + + uniswap logo + + + + + + biconomy logo + + + + + + thirdweb logo + + + + + + polymarket logo + + + + + + routescan logo + + + + + + sequence logo + + +

+ +[Sponsor Wagmi](https://github.com/sponsors/wevm?metadata_campaign=gh_readme_support_bottom) + +
+
+ + + Powered by Vercel + +
+ + Powered by QuickNode + + diff --git a/wagmi-project/.github/SECURITY.md b/wagmi-project/.github/SECURITY.md new file mode 100644 index 0000000000..54f40f38df --- /dev/null +++ b/wagmi-project/.github/SECURITY.md @@ -0,0 +1,6 @@ +# Security Policy + +## Reporting a Vulnerability + +Contact [dev@wevm.dev](mailto:dev@wevm.dev). + diff --git a/wagmi-project/.github/dependabot.yml b/wagmi-project/.github/dependabot.yml new file mode 100644 index 0000000000..bc63aca35b --- /dev/null +++ b/wagmi-project/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: 'github-actions' + directory: '/' + schedule: + interval: 'monthly' diff --git a/wagmi-project/.github/logo-dark.svg b/wagmi-project/.github/logo-dark.svg new file mode 100644 index 0000000000..5d47cce337 --- /dev/null +++ b/wagmi-project/.github/logo-dark.svg @@ -0,0 +1,27 @@ + + + + + + + diff --git a/wagmi-project/.github/logo-light.svg b/wagmi-project/.github/logo-light.svg new file mode 100644 index 0000000000..4e28590c36 --- /dev/null +++ b/wagmi-project/.github/logo-light.svg @@ -0,0 +1,27 @@ + + + + + + + diff --git a/wagmi-project/.github/pull_request_template.md b/wagmi-project/.github/pull_request_template.md new file mode 100644 index 0000000000..602a32d0a8 --- /dev/null +++ b/wagmi-project/.github/pull_request_template.md @@ -0,0 +1,12 @@ + + + diff --git a/wagmi-project/.github/workflows/Vercel Preview Deployment.yml b/wagmi-project/.github/workflows/Vercel Preview Deployment.yml new file mode 100644 index 0000000000..ca7ca97005 --- /dev/null +++ b/wagmi-project/.github/workflows/Vercel Preview Deployment.yml @@ -0,0 +1,22 @@ +name: Playwright Tests + +on: + repository_dispatch: + types: + - 'vercel.deployment.success' +permissions: + contents: read +jobs: + run-e2es: + if: github.event_name == 'repository_dispatch' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.client_payload.git.sha }} + - name: Install dependencies + run: npm ci && npx playwright install --with-deps + - name: Run tests + run: npx playwright test + env: + BASE_URL: ${{ github.event.client_payload.url }} diff --git a/wagmi-project/.github/workflows/changesets.yml b/wagmi-project/.github/workflows/changesets.yml new file mode 100644 index 0000000000..745341ed97 --- /dev/null +++ b/wagmi-project/.github/workflows/changesets.yml @@ -0,0 +1,60 @@ +name: Changesets +on: + push: + branches: [main] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + verify: + name: Verify + uses: ./.github/workflows/verify.yml + secrets: inherit + + changesets: + name: Publish + needs: verify + permissions: + contents: write + id-token: write + pull-requests: write + runs-on: ubuntu-latest + timeout-minutes: 5 + + steps: + - name: Clone repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + # This makes Actions fetch all Git history so that Changesets can generate changelogs with the correct commits + fetch-depth: 0 + + - name: Install dependencies + uses: wevm/actions/.github/actions/pnpm@main + + - name: PR or publish + uses: changesets/action@e0145edc7d9d8679003495b11f87bd8ef63c0cba + with: + title: 'chore: version packages' + commit: 'chore: version packages' + createGithubReleases: ${{ github.ref == 'refs/heads/main' }} + publish: pnpm changeset:publish + version: pnpm changeset:version + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + + - name: Publish prerelease + if: steps.changesets.outputs.published != 'true' + continue-on-error: true + env: + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + npm config set "//registry.npmjs.org/:_authToken" "$NPM_TOKEN" + git reset --hard origin/main + pnpm clean + pnpm changeset version --no-git-tag --snapshot canary + pnpm changeset:prepublish + pnpm changeset publish --no-git-tag --snapshot canary --tag canary diff --git a/wagmi-project/.github/workflows/dependency-review.yml b/wagmi-project/.github/workflows/dependency-review.yml new file mode 100644 index 0000000000..d19e21b798 --- /dev/null +++ b/wagmi-project/.github/workflows/dependency-review.yml @@ -0,0 +1,39 @@ +# Dependency Review Action +# +# This Action will scan dependency manifest files that change as part of a Pull Request, +# surfacing known-vulnerable versions of the packages declared or updated in the PR. +# Once installed, if the workflow run is marked as required, PRs introducing known-vulnerable +# packages will be blocked from merging. +# +# Source repository: https://github.com/actions/dependency-review-action +# Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement +name: 'Dependency review' +on: + pull_request: + branches: [ "main" ] + +# If using a dependency submission action in this workflow this permission will need to be set to: +# +# permissions: +# contents: write +# +# https://docs.github.com/en/enterprise-cloud@latest/code-security/supply-chain-security/understanding-your-software-supply-chain/using-the-dependency-submission-api +permissions: + contents: read + # Write permissions for pull-requests are required for using the `comment-summary-in-pr` option, comment out if you aren't using this option + pull-requests: write + +jobs: + dependency-review: + runs-on: ubuntu-latest + steps: + - name: 'Checkout repository' + uses: actions/checkout@v4 + - name: 'Dependency Review' + uses: actions/dependency-review-action@v4 + # Commonly enabled options, see https://github.com/actions/dependency-review-action#configuration-options for all available options. + with: + comment-summary-in-pr: always + # fail-on-severity: moderate + # deny-licenses: GPL-1.0-or-later, LGPL-2.0-or-later + # retry-on-snapshot-warnings: true diff --git a/wagmi-project/.github/workflows/issue-labeled.yml b/wagmi-project/.github/workflows/issue-labeled.yml new file mode 100644 index 0000000000..39b98291d1 --- /dev/null +++ b/wagmi-project/.github/workflows/issue-labeled.yml @@ -0,0 +1,19 @@ +name: Issue Labeled + +on: + issues: + types: [labeled] + +jobs: + issue-labeled: + if: ${{ github.repository_owner == 'wevm' }} + uses: wevm/actions/.github/workflows/issue-labeled.yml@main + with: + needs-reproduction-body: | + Hello @${{ github.event.issue.user.login }}. + + Please provide a [minimal reproduction](https://stackoverflow.com/help/minimal-reproducible-example) using [StackBlitz](https://new.wagmi.sh), [TypeScript Playground](https://www.typescriptlang.org/play) (for type issues), or a separate minimal GitHub repository. + + [Minimal reproductions are required](https://antfu.me/posts/why-reproductions-are-required) as they save us a lot of time reproducing your config/environment and issue, and allow us to help you faster. + + Once a minimal reproduction is added, a team member will confirm it works, then re-open the issue. diff --git a/wagmi-project/.github/workflows/jekyll-docker.yml b/wagmi-project/.github/workflows/jekyll-docker.yml new file mode 100644 index 0000000000..c88a4430c3 --- /dev/null +++ b/wagmi-project/.github/workflows/jekyll-docker.yml @@ -0,0 +1,23 @@ +name: Jekyll site CI + +permissions: + contents: read + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: Build the site in the jekyll/builder container + run: | + docker run \ + -v ${{ github.workspace }}:/srv/jekyll -v ${{ github.workspace }}/_site:/srv/jekyll/_site \ + jekyll/builder:latest /bin/bash -c "chmod -R 777 /srv/jekyll && jekyll build --future" diff --git a/wagmi-project/.github/workflows/lock-issue.yml b/wagmi-project/.github/workflows/lock-issue.yml new file mode 100644 index 0000000000..279452d223 --- /dev/null +++ b/wagmi-project/.github/workflows/lock-issue.yml @@ -0,0 +1,16 @@ +name: Lock Issue + +on: + schedule: + - cron: '0 0 * * *' + +jobs: + lock-issue: + if: ${{ github.repository_owner == 'wevm' }} + uses: wevm/actions/.github/workflows/lock-issue.yml@main + with: + issue-comment: | + This issue has been locked since it has been closed for more than 14 days. + + If you found a concrete bug or regression related to it, please open a new [bug report](https://github.com/wevm/wagmi/issues/new?template=bug_report.yml) with a reproduction against the latest Wagmi version. If you have any questions or comments you can create a new [discussion thread](https://github.com/wevm/wagmi/discussions). + diff --git a/wagmi-project/.github/workflows/octopusdeploy.yml b/wagmi-project/.github/workflows/octopusdeploy.yml new file mode 100644 index 0000000000..9c4403d554 --- /dev/null +++ b/wagmi-project/.github/workflows/octopusdeploy.yml @@ -0,0 +1,112 @@ +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by separate terms of service, +# privacy policy, and support documentation. +# +# This workflow will build and publish a Docker container which is then deployed through Octopus Deploy. +# +# The build job in this workflow currently assumes that there is a Dockerfile that generates the relevant application image. +# If required, this job can be modified to generate whatever alternative build artifact is required for your deployment. +# +# This workflow assumes you have already created a Project in Octopus Deploy. +# For instructions see https://octopus.com/docs/projects/setting-up-projects +# +# To configure this workflow: +# +# 1. Decide where you are going to host your image. +# This template uses the GitHub Registry for simplicity but if required you can update the relevant DOCKER_REGISTRY variables below. +# +# 2. Create and configure an OIDC credential for a service account in Octopus. +# This allows for passwordless authentication to your Octopus instance through a trust relationship configured between Octopus, GitHub and your GitHub Repository. +# https://octopus.com/docs/octopus-rest-api/openid-connect/github-actions +# +# 3. Configure your Octopus project details below: +# OCTOPUS_URL: update to your Octopus Instance Url +# OCTOPUS_SERVICE_ACCOUNT: update to your service account Id +# OCTOPUS_SPACE: update to the name of the space your project is configured in +# OCTOPUS_PROJECT: update to the name of your Octopus project +# OCTOPUS_ENVIRONMENT: update to the name of the environment to recieve the first deployment + + +name: 'Build and Deploy to Octopus Deploy' + +on: + push: + branches: + - '"main"' + +jobs: + build: + name: Build + runs-on: ubuntu-latest + permissions: + packages: write + contents: read + env: + DOCKER_REGISTRY: ghcr.io # TODO: Update to your docker registry uri + DOCKER_REGISTRY_USERNAME: ${{ github.actor }} # TODO: Update to your docker registry username + DOCKER_REGISTRY_PASSWORD: ${{ secrets.GITHUB_TOKEN }} # TODO: Update to your docker registry password + outputs: + image_tag: ${{ steps.meta.outputs.version }} + steps: + - uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0 + + - name: Log in to the Container registry + uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 + with: + registry: ${{ env.DOCKER_REGISTRY }} + username: ${{ env.DOCKER_REGISTRY_USERNAME }} + password: ${{ env.DOCKER_REGISTRY_PASSWORD }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 + with: + images: ${{ env.DOCKER_REGISTRY }}/${{ github.repository }} + tags: type=semver,pattern={{version}},value=v1.0.0-{{sha}} + + - name: Build and push Docker image + id: push + uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + deploy: + name: Deploy + permissions: + id-token: write + runs-on: ubuntu-latest + needs: [ build ] + env: + OCTOPUS_URL: 'https://your-octopus-url' # TODO: update to your Octopus Instance url + OCTOPUS_SERVICE_ACCOUNT: 'your-service-account-id' # TODO: update to your service account Id + OCTOPUS_SPACE: 'your-space' # TODO: update to the name of the space your project is configured in + OCTOPUS_PROJECT: 'your-project' # TODO: update to the name of your Octopus project + OCTOPUS_ENVIRONMENT: 'your-environment' # TODO: update to the name of the environment to recieve the first deployment + + steps: + - name: Log in to Octopus Deploy + uses: OctopusDeploy/login@e485a40e4b47a154bdf59cc79e57894b0769a760 #v1.0.3 + with: + server: '${{ env.OCTOPUS_URL }}' + service_account_id: '${{ env.OCTOPUS_SERVICE_ACCOUNT }}' + + - name: Create Release + id: create_release + uses: OctopusDeploy/create-release-action@fea7e7b45c38c021b6bc5a14bd7eaa2ed5269214 #v3.2.2 + with: + project: '${{ env.OCTOPUS_PROJECT }}' + space: '${{ env.OCTOPUS_SPACE }}' + packages: '*:${{ needs.build.outputs.image_tag }}' + + - name: Deploy Release + uses: OctopusDeploy/deploy-release-action@b10a606c903b0a5bce24102af9d066638ab429ac #v3.2.1 + with: + project: '${{ env.OCTOPUS_PROJECT }}' + space: '${{ env.OCTOPUS_SPACE }}' + release_number: '${{ steps.create_release.outputs.release_number }}' + environments: ${{ env.OCTOPUS_ENVIRONMENT }} diff --git a/wagmi-project/.github/workflows/pull-request.yml b/wagmi-project/.github/workflows/pull-request.yml new file mode 100644 index 0000000000..9ff4c5bb76 --- /dev/null +++ b/wagmi-project/.github/workflows/pull-request.yml @@ -0,0 +1,32 @@ +name: Pull Request +on: + pull_request: + types: [opened, reopened, synchronize, ready_for_review] + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + verify: + name: Verify + uses: ./.github/workflows/verify.yml + secrets: inherit + + size: + name: Size + runs-on: ubuntu-latest + timeout-minutes: 5 + + steps: + - name: Clone repository + uses: actions/checkout@v4 + + - name: Install dependencies + uses: wevm/actions/.github/actions/pnpm@main + + - name: Report build size + uses: preactjs/compressed-size-action@v2 + with: + pattern: 'packages/**/dist/**' + repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/wagmi-project/.github/workflows/release.yml b/wagmi-project/.github/workflows/release.yml new file mode 100644 index 0000000000..297c74f635 --- /dev/null +++ b/wagmi-project/.github/workflows/release.yml @@ -0,0 +1,44 @@ +name: Release + +on: + push: + branches: + - main + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: write + +jobs: + release: + name: Release + runs-on: ubuntu-latest + steps: + - name: Checkout Repo + uses: actions/checkout@v3 + + - name: Setup Node.js 20.x + uses: actions/setup-node@v3 + with: + node-version: 20.x + + - name: Install Dependencies + run: pnpm install + + - name: Create Release Pull Request or Publish to npm + id: changesets + uses: changesets/action@v1 + with: + # This expects you to have a script called release which does a build for your packages and calls changeset publish + publish: pnpm release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + + - name: Send a Slack notification if a publish happens + if: steps.changesets.outputs.published == 'true' + # You can do something when a publish happens. + run: my-slack-bot send-notification --message "A new version of ${GITHUB_REPOSITORY} was published!" diff --git a/wagmi-project/.github/workflows/snapshot.yml b/wagmi-project/.github/workflows/snapshot.yml new file mode 100644 index 0000000000..39683bb684 --- /dev/null +++ b/wagmi-project/.github/workflows/snapshot.yml @@ -0,0 +1,32 @@ +name: Snapshot +on: + workflow_dispatch: + +jobs: + snapshot: + name: Release snapshot version + permissions: + contents: write + id-token: write + runs-on: ubuntu-latest + timeout-minutes: 5 + + steps: + - name: Clone repository + uses: actions/checkout@v4 + + - name: Install dependencies + uses: wevm/actions/.github/actions/pnpm@main + + - name: Publish Snapshots + continue-on-error: true + env: + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + snapshot=$(git branch --show-current | tr -cs '[:alnum:]-' '-' | tr '[:upper:]' '[:lower:]' | sed 's/-$//') + npm config set "//registry.npmjs.org/:_authToken" "$NPM_TOKEN" + pnpm clean + pnpm changeset version --no-git-tag --snapshot $snapshot + pnpm changeset:prepublish + pnpm changeset publish --no-git-tag --snapshot $snapshot --tag $snapshot diff --git a/wagmi-project/.github/workflows/verify.yml b/wagmi-project/.github/workflows/verify.yml new file mode 100644 index 0000000000..582eef2d55 --- /dev/null +++ b/wagmi-project/.github/workflows/verify.yml @@ -0,0 +1,127 @@ +name: Verify +on: + workflow_call: + workflow_dispatch: + +jobs: + check: + name: Check + permissions: + contents: write + runs-on: ubuntu-latest + timeout-minutes: 5 + + steps: + - name: Clone repository + uses: actions/checkout@v4 + with: + token: ${{ secrets.GH_PTOKEN }} + + - name: Install dependencies + uses: wevm/actions/.github/actions/pnpm@main + + - name: Check repo + run: pnpm check:repo + + - name: Check code + run: pnpm check + + - name: Update package versions + run: pnpm version:update + + - uses: stefanzweifel/git-auto-commit-action@v5 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + commit_message: 'chore: format' + commit_user_name: 'github-actions[bot]' + commit_user_email: 'github-actions[bot]@users.noreply.github.com' + + build: + name: Build + needs: check + runs-on: ubuntu-latest + timeout-minutes: 5 + + steps: + - name: Clone repository + uses: actions/checkout@v4 + + - name: Install dependencies + uses: wevm/actions/.github/actions/pnpm@main + + - name: Build + run: pnpm build + + - name: Publint + run: pnpm test:build + + - name: Check for unused files, dependencies, and exports + run: pnpm knip --production + + types: + name: Types + needs: check + runs-on: ubuntu-latest + timeout-minutes: 5 + strategy: + matrix: + typescript-version: ['5.7.3', '5.8.3', 'latest'] + viem-version: ['2.29.2', 'latest'] + + steps: + - name: Clone repository + uses: actions/checkout@v4 + + - name: Install dependencies + uses: wevm/actions/.github/actions/pnpm@main + + - run: pnpm add -D -w typescript@${{ matrix.typescript-version }} viem@${{ matrix.viem-version }} + + - name: Link packages + run: pnpm preconstruct + + - name: Check types + run: pnpm check:types + + # Redundant with `pnpm check:types` + # If Vitest adds special features in the future, e.g. type coverage, can add this back! + # - name: Test types + # run: pnpm test:typecheck + + test: + name: Test + runs-on: ubuntu-latest + timeout-minutes: 10 + strategy: + max-parallel: 3 + matrix: + shard: [1, 2, 3] + total-shards: [3] + + steps: + - name: Clone repository + uses: actions/checkout@v4 + + - name: Install dependencies + uses: wevm/actions/.github/actions/pnpm@main + + - name: Set up foundry + uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly + + - name: Run tests + uses: nick-fields/retry@v3 + with: + command: CI=true pnpm test:cov --shard=${{ matrix.shard }}/${{ matrix.total-shards }} --retry=3 --bail=1 + max_attempts: 3 + timeout_minutes: 5 + env: + VITE_MAINNET_FORK_URL: ${{ secrets.VITE_MAINNET_FORK_URL }} + VITE_OPTIMISM_FORK_URL: ${{ secrets.VITE_OPTIMISM_FORK_URL }} + + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v5 + with: + token: ${{ secrets.CODECOV_TOKEN }} diff --git a/wagmi-project/.gitignore b/wagmi-project/.gitignore new file mode 100644 index 0000000000..1834fe72ab --- /dev/null +++ b/wagmi-project/.gitignore @@ -0,0 +1,39 @@ +.DS_Store +.next +.nuxt +.pnpm-debug.log* +cache +coverage +dist +node_modules +tsconfig.tsbuildinfo +*.vitest-temp.json + +# local env files +.env +.env.local +.env.development.local +.env.test.local +.env.production.local +.envrc + +# proxy packages +packages/cli/config +packages/cli/plugins +packages/core/actions +packages/core/chains +packages/core/codegen +packages/core/experimental +packages/core/internal +packages/core/query +packages/react/actions +packages/react/chains +packages/react/codegen +packages/react/connectors +packages/react/experimental +packages/react/query +packages/vue/actions +packages/vue/chains +packages/vue/connectors +packages/vue/nuxt +packages/vue/query diff --git a/wagmi-project/.npmrc b/wagmi-project/.npmrc new file mode 100644 index 0000000000..47687565bf --- /dev/null +++ b/wagmi-project/.npmrc @@ -0,0 +1,5 @@ +auto-install-peers=false +enable-pre-post-scripts=true +link-workspace-packages=deep +provenance=true +strict-peer-dependencies=false diff --git a/wagmi-project/.vscode/extensions.json b/wagmi-project/.vscode/extensions.json new file mode 100644 index 0000000000..9cb435094a --- /dev/null +++ b/wagmi-project/.vscode/extensions.json @@ -0,0 +1,7 @@ +{ + "recommendations": [ + "biomejs.biome", + "orta.vscode-twoslash-queries", + "Vue.volar" + ] +} diff --git a/wagmi-project/.vscode/settings.json b/wagmi-project/.vscode/settings.json new file mode 100644 index 0000000000..c32e8fa4c3 --- /dev/null +++ b/wagmi-project/.vscode/settings.json @@ -0,0 +1,17 @@ +{ + "editor.defaultFormatter": "biomejs.biome", + "editor.formatOnSave": true, + "typescript.enablePromptUseWorkspaceTsdk": true, + "typescript.preferences.importModuleSpecifier": "shortest", + "typescript.tsdk": "node_modules/typescript/lib", + "editor.codeActionsOnSave": { + "quickfix.biome": "explicit", + "source.organizeImports.biome": "explicit" + }, + "[javascript][javascriptreact][json][typescript][typescriptreact]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[vue]": { + "editor.defaultFormatter": "Vue.volar" + } +} diff --git a/wagmi-project/.vscode/workspace.code-workspace b/wagmi-project/.vscode/workspace.code-workspace new file mode 100644 index 0000000000..0d626129da --- /dev/null +++ b/wagmi-project/.vscode/workspace.code-workspace @@ -0,0 +1,16 @@ +{ + "folders": [ + { + "name": "docs", + "path": "../docs" + }, + { + "name": "packages", + "path": "../packages" + }, + { + "name": "playgrounds", + "path": "../playgrounds" + } + ] +} diff --git a/wagmi-project/FUNDING.json b/wagmi-project/FUNDING.json new file mode 100644 index 0000000000..5e01254162 --- /dev/null +++ b/wagmi-project/FUNDING.json @@ -0,0 +1,10 @@ +{ + "drips": { + "ethereum": { + "ownedBy": "0xd2135CfB216b74109775236E36d4b433F1DF507B" + } + }, + "opRetro": { + "projectId": "0xc0615947773148cbc340b175fb9afc98dbb4e0acd31d018b1ee41a5538785abf" + } +} diff --git a/wagmi-project/LICENSE b/wagmi-project/LICENSE new file mode 100644 index 0000000000..650c3c1c00 --- /dev/null +++ b/wagmi-project/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022-present weth, LLC + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/wagmi-project/README.md b/wagmi-project/README.md new file mode 100644 index 0000000000..15f6f79541 --- /dev/null +++ b/wagmi-project/README.md @@ -0,0 +1 @@ +This is a [Vite](https://vitejs.dev) project bootstrapped with [`create-wagmi`](https://github.com/wevm/wagmi/tree/main/packages/create-wagmi). diff --git a/wagmi-project/biome.json b/wagmi-project/biome.json new file mode 100644 index 0000000000..ce99662cb0 --- /dev/null +++ b/wagmi-project/biome.json @@ -0,0 +1,89 @@ +{ + "$schema": "./node_modules/@biomejs/biome/configuration_schema.json", + "files": { + "ignore": ["CHANGELOG.md", "pnpm-lock.yaml", "tsconfig.base.json"] + }, + "formatter": { + "enabled": true, + "formatWithErrors": false, + "indentStyle": "space", + "indentWidth": 2, + "lineWidth": 80 + }, + "linter": { + "ignore": ["packages/create-wagmi/templates/*"], + "enabled": true, + "rules": { + "recommended": true, + "a11y": { + "useButtonType": "off" + }, + "correctness": { + "noUnusedVariables": "error", + "useExhaustiveDependencies": "error" + }, + "performance": { + "noBarrelFile": "error", + "noReExportAll": "error", + "noDelete": "off" + }, + "style": { + "noNonNullAssertion": "off", + "useShorthandArrayType": "error" + }, + "suspicious": { + "noArrayIndexKey": "off", + "noConfusingVoidType": "off", + "noConsoleLog": "error", + "noExplicitAny": "off" + } + } + }, + "javascript": { + "formatter": { + "quoteStyle": "single", + "trailingCommas": "all", + "semicolons": "asNeeded" + } + }, + "organizeImports": { + "enabled": true + }, + "overrides": [ + { + "include": ["*.vue"], + "linter": { + "rules": { + "correctness": { + "noUnusedVariables": "off" + } + } + } + }, + { + "include": ["./scripts/**/*.ts"], + "linter": { + "rules": { + "suspicious": { + "noConsoleLog": "off" + } + } + } + }, + { + "include": ["./playgrounds/**"], + "linter": { + "rules": { + "style": { + "useNodejsImportProtocol": "off" + } + } + } + } + ], + "vcs": { + "enabled": true, + "clientKind": "git", + "useIgnoreFile": true + } +} diff --git a/wagmi-project/index.html b/wagmi-project/index.html new file mode 100644 index 0000000000..f519ce85a7 --- /dev/null +++ b/wagmi-project/index.html @@ -0,0 +1,12 @@ + + + + + + Create Wagmi + + +
+ + + diff --git a/wagmi-project/package.json b/wagmi-project/package.json new file mode 100644 index 0000000000..5c456e7b30 --- /dev/null +++ b/wagmi-project/package.json @@ -0,0 +1,136 @@ +{ + "private": true, + "type": "module", + "scripts": { + "build": "pnpm run --r --filter \"./packages/**\" build", + "changeset:prepublish": "pnpm version:update && pnpm build && bun scripts/formatPackageJson.ts && bun scripts/generateProxyPackages.ts", + "changeset:publish": "pnpm changeset:prepublish && changeset publish", + "changeset:version": "changeset version && pnpm version:update && pnpm format", + "check": "biome check --write", + "check:repo": "sherif -i viem", + "check:types": "pnpm run --r --parallel check:types && tsc --noEmit", + "check:unused": "pnpm clean && knip", + "clean": "pnpm run --r --parallel clean && rm -rf packages/**/*.json.tmp", + "deps": "pnpx taze -r", + "dev": "pnpm dev:react", + "dev:cli": "pnpm --filter cli dev", + "dev:core": "pnpm --filter vite-core dev", + "dev:create-wagmi": "pnpm --filter create-wagmi dev", + "dev:next": "pnpm --filter next-app dev", + "dev:nuxt": "pnpm --filter nuxt-app dev", + "dev:react": "pnpm --filter vite-react dev", + "dev:vue": "pnpm --filter vite-vue dev", + "docs:dev": "pnpm --filter site dev", + "format": "biome format --write", + "postinstall": "pnpm preconstruct", + "preconstruct": "bun scripts/preconstruct.ts", + "preinstall": "pnpx only-allow pnpm", + "prepare": "pnpm simple-git-hooks", + "test": "vitest", + "test:build": "bun scripts/generateProxyPackages.ts && pnpm run --r --parallel test:build", + "test:cli": "vitest --project @wagmi/cli", + "test:connectors": "vitest --project @wagmi/connectors", + "test:core": "vitest --project @wagmi/core", + "test:create-wagmi": "vitest --project create-wagmi", + "test:cov": "vitest run --coverage", + "test:react": "vitest --project wagmi", + "test:typecheck": "vitest typecheck", + "test:update": "vitest --update", + "test:vue": "vitest --project @wagmi/vue", + "version:update": "bun scripts/updateVersion.ts", + "version:update:viem": "bun scripts/updateViemVersion.ts" + }, + "devDependencies": { + "@arethetypeswrong/cli": "^0.16.4", + "@biomejs/biome": "^1.9.4", + "@changesets/changelog-github": "0.4.6", + "@changesets/cli": "^2.27.8", + "@types/bun": "^1.1.10", + "@vitest/coverage-v8": "^3.2.4", + "@wagmi/test": "workspace:*", + "bun": "^1.1.30", + "happy-dom": "^18.0.1", + "knip": "^5.30.6", + "prool": "^0.0.23", + "publint": "^0.3.0", + "sherif": "^1.0.0", + "simple-git-hooks": "^2.11.1", + "typescript": "5.8.3", + "viem": "2.31.4", + "vitest": "^2.1.9" + }, + "packageManager": "pnpm@9.11.0", + "pnpm": { + "peerDependencyRules": { + "ignoreMissing": [ + "@algolia/client-search", + "react", + "react-native", + "search-insights" + ] + } + }, + "engines": { + "node": "22.x" + }, + "simple-git-hooks": { + "pre-commit": "pnpm check" + }, + "knip": { + "ignore": ["**/templates/**", "**/hardhat.config.js"], + "ignoreBinaries": ["only-allow"], + "ignoreWorkspaces": [ + "packages/register-tests/**", + "packages/test", + "playgrounds/**" + ], + "workspaces": { + ".": { + "project": "scripts/*.ts" + }, + "packages/cli": { + "entry": [ + "src/cli.ts!", + "src/exports/{config,index,plugins}.ts!", + "types/*.d.ts!" + ], + "ignore": ["test/{constants,setup,utils}.ts"] + }, + "packages/connectors": { + "entry": "src/exports/index.ts!" + }, + "packages/core": { + "entry": "src/exports/{actions,chains,codegen,experimental,index,internal,query}.ts!", + "ignore": ["test/setup.ts"], + "ignoreDependencies": ["@tanstack/query-core"] + }, + "packages/create-wagmi": { + "entry": "src/cli.ts!" + }, + "packages/react": { + "entry": [ + "src/exports/{actions,chains,codegen,connectors,experimental,index,query}.ts!", + "src/exports/actions/experimental.ts!" + ], + "ignore": ["test/setup.ts"] + }, + "packages/test": { + "entry": [ + "src/{globalSetup,setup}.ts!", + "src/exports/{index,react}.ts!" + ] + }, + "packages/vue": { + "entry": [ + "src/exports/{actions,chains,connectors,index,nuxt,query}.ts!", + "src/exports/actions/experimental.ts!" + ], + "ignore": ["src/nuxt/runtime/*", "test/setup.ts"], + "ignoreDependencies": ["nuxt"] + }, + "site": { + "project": ["**/*.ts", "**/*.tsx"] + } + } + } +} diff --git a/wagmi-project/packages/cli/CHANGELOG.md b/wagmi-project/packages/cli/CHANGELOG.md new file mode 100644 index 0000000000..a2911e2304 --- /dev/null +++ b/wagmi-project/packages/cli/CHANGELOG.md @@ -0,0 +1,449 @@ +# @wagmi/cli + +## 2.3.1 + +### Patch Changes + +- [#4655](https://github.com/wevm/wagmi/pull/4655) [`43241c8417f3c342036bb46ec8e507d052ae2691`](https://github.com/wevm/wagmi/commit/43241c8417f3c342036bb46ec8e507d052ae2691) Thanks [@tmm](https://github.com/tmm)! - Bumped internal deps. + +## 2.3.0 + +### Minor Changes + +- [#4629](https://github.com/wevm/wagmi/pull/4629) [`66dec7d75d580b3121ebc7e8162c1f9ae37cfd41`](https://github.com/wevm/wagmi/commit/66dec7d75d580b3121ebc7e8162c1f9ae37cfd41) Thanks [@allezxandre](https://github.com/allezxandre)! - Upgraded to Sourcify v2 API in `sourcify` plugin + +## 2.2.1 + +### Patch Changes + +- [`7b0dbe3886c1a7c6dbbdab945d7436ec20ad8f93`](https://github.com/wevm/wagmi/commit/7b0dbe3886c1a7c6dbbdab945d7436ec20ad8f93) Thanks [@tmm](https://github.com/tmm)! - Updated block explorer chains. + +## 2.2.0 + +### Minor Changes + +- [#4503](https://github.com/wevm/wagmi/pull/4503) [`8fce8a6f97aa2ee5fd1bda6a3ece422b10324b5a`](https://github.com/wevm/wagmi/commit/8fce8a6f97aa2ee5fd1bda6a3ece422b10324b5a) Thanks [@tmm](https://github.com/tmm)! - Updated Etherscan Plugin to use Etherscan API v2. + +- [#4507](https://github.com/wevm/wagmi/pull/4507) [`6f09cc57935891e1c67d6df3459f6998985c69dc`](https://github.com/wevm/wagmi/commit/6f09cc57935891e1c67d6df3459f6998985c69dc) Thanks [@tmm](https://github.com/tmm)! - Added `tryFetchProxyImplementation` flag to Etherscan Plugin to enable fetching the implementation ABI instead of the proxy ABI. + +## 2.1.22 + +### Patch Changes + +- [#4462](https://github.com/wevm/wagmi/pull/4462) [`0b2238d27cecbcd33aee64fb0e30ddc18b6ddf74`](https://github.com/wevm/wagmi/commit/0b2238d27cecbcd33aee64fb0e30ddc18b6ddf74) Thanks [@groninge01](https://github.com/groninge01)! - Added Sonic to Etherscan plugin. + +## 2.1.21 + +### Patch Changes + +- [#4457](https://github.com/wevm/wagmi/pull/4457) [`21ec74da7f93fc13e253d7b35ddeddc23422a6c1`](https://github.com/wevm/wagmi/commit/21ec74da7f93fc13e253d7b35ddeddc23422a6c1) Thanks [@tmm](https://github.com/tmm)! - Removed internal dependency. + +## 2.1.20 + +### Patch Changes + +- [#4450](https://github.com/wevm/wagmi/pull/4450) [`7b9a6bb35881b657a00bdd7ccd7edea32660f5bf`](https://github.com/wevm/wagmi/commit/7b9a6bb35881b657a00bdd7ccd7edea32660f5bf) Thanks [@tmm](https://github.com/tmm)! - Removed internal usage of `fs-extra`. + +## 2.1.19 + +### Patch Changes + +- [#4449](https://github.com/wevm/wagmi/pull/4449) [`3fa5c238baa13d948e89974b0bb8530f8fa264fd`](https://github.com/wevm/wagmi/commit/3fa5c238baa13d948e89974b0bb8530f8fa264fd) Thanks [@tmm](https://github.com/tmm)! - Removed `ora` for `nanospinner`. + +## 2.1.18 + +### Patch Changes + +- [#4399](https://github.com/wevm/wagmi/pull/4399) [`bc18673e4c272e3b60a1b6016934fe3fbeb6d93a`](https://github.com/wevm/wagmi/commit/bc18673e4c272e3b60a1b6016934fe3fbeb6d93a) Thanks [@tmm](https://github.com/tmm)! - Added Polygon Amoy to Sourcify and Etherscan plugins. + +## 2.1.17 + +### Patch Changes + +- [#4370](https://github.com/wevm/wagmi/pull/4370) [`cb58b1ea3ad40e77210f24eb598f9d2306db998c`](https://github.com/wevm/wagmi/commit/cb58b1ea3ad40e77210f24eb598f9d2306db998c) Thanks [@talentlessguy](https://github.com/talentlessguy)! - Bumped internal dependencies. + +## 2.1.16 + +### Patch Changes + +- [#4224](https://github.com/wevm/wagmi/pull/4224) [`b0eb89c2a0781bb3434996fa53ee7ceb3bb44db9`](https://github.com/wevm/wagmi/commit/b0eb89c2a0781bb3434996fa53ee7ceb3bb44db9) Thanks [@roderik](https://github.com/roderik)! - Fixed package detection for Bun. + +## 2.1.15 + +### Patch Changes + +- [`0bb8b562ae04ecfeb2d6b2f1b980ebae31dc127e`](https://github.com/wevm/wagmi/commit/0bb8b562ae04ecfeb2d6b2f1b980ebae31dc127e) Thanks [@tmm](https://github.com/tmm)! - Improved TypeScript `'exactOptionalPropertyTypes'` support. + +## 2.1.14 + +### Patch Changes + +- [#4120](https://github.com/wevm/wagmi/pull/4120) [`59407bf1276a46e6f1f22a370dde71c92524cd0f`](https://github.com/wevm/wagmi/commit/59407bf1276a46e6f1f22a370dde71c92524cd0f) Thanks [@tmm](https://github.com/tmm)! - Fixed an issue where the Foundry and Hardhat plugins' `exclude` option was ignored. + +## 2.1.13 + +### Patch Changes + +- [`7264d1f450727f6ba0cbea8aa1c7a83e22a5bf20`](https://github.com/wevm/wagmi/commit/7264d1f450727f6ba0cbea8aa1c7a83e22a5bf20) Thanks [@tmm](https://github.com/tmm)! - Fixed generate not exiting for long-running processes. + +## 2.1.12 + +### Patch Changes + +- [`ac038b29623ccb0d2fee40d9f943c8df28138dac`](https://github.com/wevm/wagmi/commit/ac038b29623ccb0d2fee40d9f943c8df28138dac) Thanks [@tmm](https://github.com/tmm)! - Updated Foundry default excludes. + +## 2.1.11 + +### Patch Changes + +- [#4084](https://github.com/wevm/wagmi/pull/4084) [`b54203bf8fa911e6f14b9675980cf38fb95d7d3e`](https://github.com/wevm/wagmi/commit/b54203bf8fa911e6f14b9675980cf38fb95d7d3e) Thanks [@tmm](https://github.com/tmm)! - Reduced internal dependencies. + +## 2.1.10 + +### Patch Changes + +- [#4051](https://github.com/wevm/wagmi/pull/4051) [`275e78b0e585f0ec9da2f9661ce9990aed18e9f4`](https://github.com/wevm/wagmi/commit/275e78b0e585f0ec9da2f9661ce9990aed18e9f4) Thanks [@tmm](https://github.com/tmm)! - Updated Sourcify plugin internals. + +## 2.1.9 + +### Patch Changes + +- [`f9346dbcffaf57a8949cb96e43df111a89d733b1`](https://github.com/wevm/wagmi/commit/f9346dbcffaf57a8949cb96e43df111a89d733b1) Thanks [@tmm](https://github.com/tmm)! - Updated Foundry plugin default excludes. + +## 2.1.8 + +### Patch Changes + +- [#3957](https://github.com/wevm/wagmi/pull/3957) [`7d00680f73b090eb34af928ae74277bec1973953`](https://github.com/wevm/wagmi/commit/7d00680f73b090eb34af928ae74277bec1973953) Thanks [@cstoneham](https://github.com/cstoneham)! - Added Blast to Etherscan plugin + +## 2.1.7 + +### Patch Changes + +- [`1122678bbad0232590bd4060a73752de2c84982d`](https://github.com/wevm/wagmi/commit/1122678bbad0232590bd4060a73752de2c84982d) Thanks [@tmm](https://github.com/tmm)! - Published unpublished changes in [#3756](https://github.com/wevm/wagmi/pull/3756). + +## 2.1.6 + +### Patch Changes + +- [#3756](https://github.com/wevm/wagmi/pull/3756) [`c7d6f467`](https://github.com/wevm/wagmi/commit/c7d6f4679125fd2f6cca5b5ef362abf47e37f934) Thanks [@jrfrantz](https://github.com/jrfrantz)! - Added basescan to etherscan cli plugin + +## 2.1.5 + +### Patch Changes + +- [`e1ca4e63`](https://github.com/wevm/wagmi/commit/e1ca4e637ae6cec7f5902b0a2c0e0efc3b751a1d) Thanks [@tmm](https://github.com/tmm)! - Added title to CLI process. + +- [#3723](https://github.com/wevm/wagmi/pull/3723) [`d6bc98ca`](https://github.com/wevm/wagmi/commit/d6bc98ca0ce9081f192f62e0b0fcfea3cb07a2bb) Thanks [@leecobaby](https://github.com/leecobaby)! - Broadened TypeScript detection. + +## 2.1.4 + +### Patch Changes + +- [#3737](https://github.com/wevm/wagmi/pull/3737) [`11020fed`](https://github.com/wevm/wagmi/commit/11020fedfc68639eace241e328331cff43bf91af) Thanks [@oskarvu](https://github.com/oskarvu)! - Added Gnosis to Etherscan plugin. + +## 2.1.3 + +### Patch Changes + +- [#3660](https://github.com/wevm/wagmi/pull/3660) [`11a22a23`](https://github.com/wevm/wagmi/commit/11a22a23d88c025cde9c91610e9ddf62cd4fa650) Thanks [@JazzBashara](https://github.com/JazzBashara)! - Replaced SnowTrace with SnowScan for the Etherscan plugin + +## 2.1.2 + +### Patch Changes + +- [#3641](https://github.com/wevm/wagmi/pull/3641) [`0a866403`](https://github.com/wevm/wagmi/commit/0a866403182ea6b8ba7f976c45be294e48fb7de8) Thanks [@cmwhited](https://github.com/cmwhited)! - Added Arbitrum Sepolia testnet to Etherscan plugin + +- [#3633](https://github.com/wevm/wagmi/pull/3633) [`a1d3d1ab`](https://github.com/wevm/wagmi/commit/a1d3d1ab2b023c61c0dbb5d7bf867a9fca673630) Thanks [@pegahcarter](https://github.com/pegahcarter)! - Added Fraxtal to Etherscan plugin + +- [#3616](https://github.com/wevm/wagmi/pull/3616) [`2a9f4473`](https://github.com/wevm/wagmi/commit/2a9f4473adc5bcdddf388389387ed5459583769e) Thanks [@petermazzocco](https://github.com/petermazzocco)! - Added Holesky Testnet to Etherscan Plugin + +## 2.1.1 + +### Patch Changes + +- [#3579](https://github.com/wevm/wagmi/pull/3579) [`a057919c`](https://github.com/wevm/wagmi/commit/a057919ca3942adeed90af2e343403dc5274e84c) Thanks [@FaisalAli19](https://github.com/FaisalAli19)! - Added Optimism Sepolia Etherscan support + +## 2.1.0 + +### Minor Changes + +- [#3506](https://github.com/wevm/wagmi/pull/3506) [`134eb4a1`](https://github.com/wevm/wagmi/commit/134eb4a1e0e29aab87bd5c7cdf05b06dfd7c4fc4) Thanks [@vmaark](https://github.com/vmaark)! - Added resolution of TypeScript Wagmi CLI config to determine if TypeScript generated output is allowed. + +## 2.0.4 + +### Patch Changes + +- [#3462](https://github.com/wevm/wagmi/pull/3462) [`d25573ea`](https://github.com/wevm/wagmi/commit/d25573ea03358f967953e37c176b220a7b341769) Thanks [@cruzdanilo](https://github.com/cruzdanilo)! - Upgraded dependencies + +## 2.0.3 + +### Patch Changes + +- [#3410](https://github.com/wevm/wagmi/pull/3410) [`55e31c3e`](https://github.com/wevm/wagmi/commit/55e31c3e96c2cbd1d9eb44e5a89f4365489c8310) Thanks [@o-az](https://github.com/o-az)! - Fixed actions plugin issue where `functionName` was used instead of `eventName` for generated contract event actions. + +## 2.0.2 + +### Patch Changes + +- [#3371](https://github.com/wevm/wagmi/pull/3371) [`8294d9e5`](https://github.com/wevm/wagmi/commit/8294d9e5b358018ba869b2018cd7ed95462e021f) Thanks [@iceanddust](https://github.com/iceanddust)! - Fixed prop name when generating contract event watch hooks + +## 2.0.1 + +### Major Changes + +- [#3333](https://github.com/wevm/wagmi/pull/3333) [`b3a0baaa`](https://github.com/wevm/wagmi/commit/b3a0baaaee7decf750d376aab2502cd33ca4825a) Thanks [@tmm](https://github.com/tmm)! - Wagmi CLI 2.0. + + [Breaking Changes & Migration Guide](https://wagmi.sh/cli/guides/migrate-from-v1-to-v2) + +## 1.5.2 + +### Patch Changes + +- [#3051](https://github.com/wagmi-dev/wagmi/pull/3051) [`4704d351`](https://github.com/wagmi-dev/wagmi/commit/4704d351164d39704a4e375c06525554fcc8340e) Thanks [@oxSaturn](https://github.com/oxSaturn)! - Fixed ESM require issue for prettier + +## 1.5.1 + +### Patch Changes + +- [#3035](https://github.com/wagmi-dev/wagmi/pull/3035) [`187bf96c`](https://github.com/wagmi-dev/wagmi/commit/187bf96c9fd31675b9d17a7cb4d4e24eea3fa777) Thanks [@cruzdanilo](https://github.com/cruzdanilo)! - ignore foundry invariant lib + +## 1.5.0 + +### Minor Changes + +- [#2956](https://github.com/wevm/wagmi/pull/2956) [`2abeb285`](https://github.com/wevm/wagmi/commit/2abeb285674af3e539cc2550b1f5027b1eb0c895) Thanks [@tmm](https://github.com/tmm)! - Replaced `@wagmi/chains` with `viem/chains`. + +## 1.4.1 + +### Patch Changes + +- [#2962](https://github.com/wevm/wagmi/pull/2962) [`8ac5b572`](https://github.com/wevm/wagmi/commit/8ac5b57254f77eeb0e07dd83f7d49f396d4581d8) Thanks [@tmm](https://github.com/tmm)! - Fixed esbuild version + +## 1.4.0 + +### Minor Changes + +- [#2946](https://github.com/wevm/wagmi/pull/2946) [`1c3228bf`](https://github.com/wevm/wagmi/commit/1c3228bf3fe99b0900b2c9a223c9b81c70bdcd90) Thanks [@tomquirk](https://github.com/tomquirk)! - Added default chain ID to generated `useContractRead` hook. + +### Patch Changes + +- [#2547](https://github.com/wevm/wagmi/pull/2547) [`8c3889fe`](https://github.com/wevm/wagmi/commit/8c3889fe82c5a1ddb29e74e3863ea6f4917b777a) Thanks [@Iamshankhadeep](https://github.com/Iamshankhadeep)! - Deterministic CLI output + +- [#2958](https://github.com/wevm/wagmi/pull/2958) [`b31f36d5`](https://github.com/wevm/wagmi/commit/b31f36d522a634f53d44349d6a9ea47f59d84d7a) Thanks [@tmm](https://github.com/tmm)! - Removed generated file header + +- [#2960](https://github.com/wevm/wagmi/pull/2960) [`5d4c4592`](https://github.com/wevm/wagmi/commit/5d4c4592009568cd0b096906a424f27469721a42) Thanks [@tmm](https://github.com/tmm)! - Updated esbuild version + +## 1.3.0 + +### Minor Changes + +- [#2616](https://github.com/wevm/wagmi/pull/2616) [`c282a8f7`](https://github.com/wevm/wagmi/commit/c282a8f786d57fec77c931fe99dc20220e843bc8) Thanks [@portdeveloper](https://github.com/portdeveloper)! - Added sepolia chain id + +## 1.2.1 + +### Patch Changes + +- [#2607](https://github.com/wevm/wagmi/pull/2607) [`79335b4c`](https://github.com/wevm/wagmi/commit/79335b4c0fcd5e8152a2a1d28314c634db9d9cbf) Thanks [@roninjin10](https://github.com/roninjin10)! - Fixed opitmism goerli chain id + +## 1.2.0 + +### Minor Changes + +- [#2536](https://github.com/wevm/wagmi/pull/2536) [`85e9760a`](https://github.com/wevm/wagmi/commit/85e9760a140cb169ac6236d9466b96e2105dd193) Thanks [@tmm](https://github.com/tmm)! - Changed `Address` type import from ABIType to viem. + +## 1.1.0 + +### Minor Changes + +- [#2482](https://github.com/wevm/wagmi/pull/2482) [`8764b54a`](https://github.com/wevm/wagmi/commit/8764b54aab68020063946112e8fe52aff650c99c) Thanks [@tmm](https://github.com/tmm)! - Bumped minimum TypeScript version to v5.0.4. + +### Patch Changes + +- [#2484](https://github.com/wevm/wagmi/pull/2484) [`3adf1f4f`](https://github.com/wevm/wagmi/commit/3adf1f4feab863cb7b5d52c81ad46f7e4eb56f09) Thanks [@jxom](https://github.com/jxom)! - Updated `abitype` to 0.8.7 + +- [#2484](https://github.com/wevm/wagmi/pull/2484) [`3adf1f4f`](https://github.com/wevm/wagmi/commit/3adf1f4feab863cb7b5d52c81ad46f7e4eb56f09) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +## 1.0.3 + +### Patch Changes + +- [#2441](https://github.com/wevm/wagmi/pull/2441) [`326edee4`](https://github.com/wevm/wagmi/commit/326edee4bc85db84a7a4e3768e33785849ab8d8e) Thanks [@tmm](https://github.com/tmm)! - Fixed internal type issue + +## 1.0.2 + +### Patch Changes + +- [#2430](https://github.com/wevm/wagmi/pull/2430) [`71d92029`](https://github.com/wevm/wagmi/commit/71d92029ee4344842cd41698858a330fee95b6e0) Thanks [@tmm](https://github.com/tmm)! - Added message when command is not found. + +## 1.0.1 + +### Patch Changes + +- [`ea651cd7`](https://github.com/wevm/wagmi/commit/ea651cd7fc75b7866272605467db11fd6e1d81af) Thanks [@jxom](https://github.com/jxom)! - Downgraded abitype. + +## 1.0.0 + +### Major Changes + +- [#2235](https://github.com/wevm/wagmi/pull/2235) [`5be0655c`](https://github.com/wevm/wagmi/commit/5be0655c8e48b25d38009022461fbf611af54349) Thanks [@jxom](https://github.com/jxom)! - Released v1. Read [Migration Guide](https://next.wagmi.sh/react/migration-guide#1xx-breaking-changes). + +## 1.0.0-next.7 + +### Patch Changes + +- Fixed react plugin generic. + +## 1.0.0-next.6 + +### Major Changes + +- Updated references. + +## 1.0.0-next.5 + +### Major Changes + +- Added `config.setConnectors` + +## 1.0.0-next.4 + +### Major Changes + +- Updated viem. + Removed `goerli` export from main entrypoint. + +## 1.0.0-next.3 + +### Major Changes + +- Updated references. + +## 1.0.0-next.2 + +### Major Changes + +- Updated dependencies + +### Patch Changes + +- Updated dependencies []: + - @wagmi/chains@1.0.0-next.0 + +## 1.0.0-next.1 + +### Major Changes + +- updated viem + +## 1.0.0-next.0 + +### Major Changes + +- [`a7dda00c`](https://github.com/wevm/wagmi/commit/a7dda00c5b546f8b2c42b527e4d9ac1b9e9ab1fb) Thanks [@jxom](https://github.com/jxom)! - Released v1. + +### Patch Changes + +- Updated dependencies [[`a7dda00c`](https://github.com/wevm/wagmi/commit/a7dda00c5b546f8b2c42b527e4d9ac1b9e9ab1fb)]: + - @wagmi/core@1.0.0-next.0 + - wagmi@1.0.0-next.0 + +## 0.1.15 + +### Patch Changes + +- [#2145](https://github.com/wevm/wagmi/pull/2145) [`2520743c`](https://github.com/wevm/wagmi/commit/2520743c417a158a00d5edca13a9aa92cefb0cfd) Thanks [@tmm](https://github.com/tmm)! - Fixed issue using Hardhat Plugin with npm. + +## 0.1.14 + +### Patch Changes + +- [#2039](https://github.com/wevm/wagmi/pull/2039) [`bac893ab`](https://github.com/wevm/wagmi/commit/bac893ab26012d4d8741c4f80e8b8813aee26f0c) Thanks [@tmm](https://github.com/tmm)! - Updated references. + +- [#2039](https://github.com/wevm/wagmi/pull/2039) [`bac893ab`](https://github.com/wevm/wagmi/commit/bac893ab26012d4d8741c4f80e8b8813aee26f0c) Thanks [@tmm](https://github.com/tmm)! - Fixed Actions plugin `overridePackageName` option. + +## 0.1.13 + +### Patch Changes + +- [#2000](https://github.com/wevm/wagmi/pull/2000) [`01254765`](https://github.com/wevm/wagmi/commit/01254765eb37b77aca26500c00c721f08a260912) Thanks [@tmm](https://github.com/tmm)! - Fixed React plugin name conflict. + +## 0.1.12 + +### Patch Changes + +- [#1992](https://github.com/wevm/wagmi/pull/1992) [`efc93cad`](https://github.com/wevm/wagmi/commit/efc93cadacdb9c9960644dabe4ae837d384df52b) Thanks [@tmm](https://github.com/tmm)! - Refactored internals from ethers to viem. + +## 0.1.11 + +### Patch Changes + +- [#1916](https://github.com/wevm/wagmi/pull/1916) [`950490fd`](https://github.com/wevm/wagmi/commit/950490fd132b3fb5b3455e77b58d70f134b8e5c9) Thanks [@technophile-04](https://github.com/technophile-04)! - Updated React plugin to use `Address` type instead of hardcoding `` `0x{string}` ``. + +## 0.1.10 + +### Patch Changes + +- [#1892](https://github.com/wevm/wagmi/pull/1892) [`d3d6973b`](https://github.com/wevm/wagmi/commit/d3d6973ba9407e490140d2434eb83aad88d6e10d) Thanks [@greg-schrammel](https://github.com/greg-schrammel)! - Fixed generated read hooks `select` type. + +## 0.1.9 + +### Patch Changes + +- [#1886](https://github.com/wevm/wagmi/pull/1886) [`36e119c6`](https://github.com/wevm/wagmi/commit/36e119c6d4bc28a7ae15c9602d0c613bc9681356) Thanks [@roninjin10](https://github.com/roninjin10)! - Fixed package detection for yarn^3 + +## 0.1.8 + +### Patch Changes + +- [#1884](https://github.com/wevm/wagmi/pull/1884) [`cc03bb44`](https://github.com/wevm/wagmi/commit/cc03bb44268874f95203de67f6d32586e34c0857) Thanks [@roninjin10](https://github.com/roninjin10)! - Added better compatibility for yarn@^3 in `@wagmi/cli`. + +## 0.1.7 + +### Patch Changes + +- [#1841](https://github.com/wevm/wagmi/pull/1841) [`cb707f01`](https://github.com/wevm/wagmi/commit/cb707f01cbdcc62a70cf5c8a162d77948d6b6a56) Thanks [@tmm](https://github.com/tmm)! - Added [Sourcify](https://sourcify.dev) CLI plugin. + +## 0.1.6 + +### Patch Changes + +- [#1803](https://github.com/wevm/wagmi/pull/1803) [`09b13538`](https://github.com/wevm/wagmi/commit/09b13538abcde879034293cae39551c30cc81445) Thanks [@shotaronowhere](https://github.com/shotaronowhere)! - Swapped deprecated Arbitrum Rinkeby for Arbitrum Goerli URL for Etherscan Plugin. + +## 0.1.5 + +### Patch Changes + +- [#1788](https://github.com/wevm/wagmi/pull/1788) [`c3e16d82`](https://github.com/wevm/wagmi/commit/c3e16d82c9c39b8b1c2f3c51037e11d642a20cd6) Thanks [@tmm](https://github.com/tmm)! - Fixed CLI import + +## 0.1.4 + +### Patch Changes + +- [#1779](https://github.com/wevm/wagmi/pull/1779) [`97346750`](https://github.com/wevm/wagmi/commit/973467505dc2bb46198a3e9fe6072306170d24c0) Thanks [@tmm](https://github.com/tmm)! - Made `project` optional for Foundry plugin + +## 0.1.3 + +### Patch Changes + +- [#1754](https://github.com/wevm/wagmi/pull/1754) [`298728b5`](https://github.com/wevm/wagmi/commit/298728b5918fa15b6b5b082597204a268d4b01f1) Thanks [@tmm](https://github.com/tmm)! - Updated project resolution for Foundry and Hardhat plugins. + +- [#1738](https://github.com/wevm/wagmi/pull/1738) [`37c221d0`](https://github.com/wevm/wagmi/commit/37c221d0f4d175084e23a6b172d72f177bfa0c81) Thanks [@roninjin10](https://github.com/roninjin10)! - Added automatic Foundry config detection for artifacts directory. + +## 0.1.2 + +### Patch Changes + +- [#1743](https://github.com/wevm/wagmi/pull/1743) [`379315fa`](https://github.com/wevm/wagmi/commit/379315fa359c3118b5d200ec50db3812b0cdd984) Thanks [@kyscott18](https://github.com/kyscott18)! - Add celoscan to `etherscan` plugin + +## 0.1.1 + +### Patch Changes + +- [#1736](https://github.com/wevm/wagmi/pull/1736) [`7c43e431`](https://github.com/wevm/wagmi/commit/7c43e431e2eb970610cc6490cee6a4093655a683) Thanks [@tmm](https://github.com/tmm)! - Fixed generated address object key type. + +## 0.1.0 + +### Minor Changes + +- [#1732](https://github.com/wevm/wagmi/pull/1732) [`01e21897`](https://github.com/wevm/wagmi/commit/01e2189747a5c22dc758c6d719b4145adc2a643c) Thanks [@tmm](https://github.com/tmm)! - Initial release diff --git a/wagmi-project/packages/cli/README.md b/wagmi-project/packages/cli/README.md new file mode 100644 index 0000000000..640acb22d2 --- /dev/null +++ b/wagmi-project/packages/cli/README.md @@ -0,0 +1,13 @@ +# @wagmi/cli + +Manage and generate code from Ethereum ABIs + +## Installation + +```bash +pnpm add @wagmi/cli +``` + +## Documentation + +For documentation and guides, visit [wagmi.sh](https://wagmi.sh). diff --git a/wagmi-project/packages/cli/package.json b/wagmi-project/packages/cli/package.json new file mode 100644 index 0000000000..1a00143c5d --- /dev/null +++ b/wagmi-project/packages/cli/package.json @@ -0,0 +1,94 @@ +{ + "name": "@wagmi/cli", + "description": "Manage and generate code from Ethereum ABIs", + "version": "2.3.1", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/wevm/wagmi.git", + "directory": "packages/cli" + }, + "scripts": { + "build": "pnpm run clean && pnpm run build:esm+types", + "build:esm+types": "tsc --project tsconfig.build.json --outDir ./dist/esm --declaration --declarationMap --declarationDir ./dist/types", + "check:types": "tsc --noEmit", + "clean": "rm -rf dist tsconfig.tsbuildinfo config plugins", + "dev": "bun src/cli.ts", + "test:build": "publint --strict && attw --pack --ignore-rules cjs-resolves-to-esm" + }, + "files": [ + "dist/**", + "!dist/**/*.tsbuildinfo", + "src/**/*.ts", + "!src/**/*.test.ts", + "!src/**/*.test-d.ts", + "/config", + "/plugins" + ], + "bin": { + "wagmi": "./dist/esm/cli.js" + }, + "sideEffects": false, + "type": "module", + "main": "./dist/esm/exports/index.js", + "types": "./dist/types/exports/index.d.ts", + "typings": "./dist/types/exports/index.d.ts", + "exports": { + ".": { + "types": "./dist/types/exports/index.d.ts", + "default": "./dist/esm/exports/index.js" + }, + "./config": { + "types": "./dist/types/exports/config.d.ts", + "default": "./dist/esm/exports/config.js" + }, + "./plugins": { + "types": "./dist/types/exports/plugins.d.ts", + "default": "./dist/esm/exports/plugins.js" + }, + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "config": ["./dist/types/exports/config.d.ts"], + "plugins": ["./dist/types/exports/plugins.d.ts"] + } + }, + "peerDependencies": { + "typescript": ">=5.0.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + }, + "dependencies": { + "abitype": "^1.0.4", + "bundle-require": "^5.1.0", + "cac": "^6.7.14", + "change-case": "^5.4.4", + "chokidar": "4.0.3", + "dedent": "^1.5.3", + "dotenv": "^16.3.1", + "dotenv-expand": "^10.0.0", + "esbuild": "~0.25.5", + "escalade": "3.2.0", + "fdir": "^6.1.1", + "nanospinner": "1.2.2", + "pathe": "^2.0.3", + "picocolors": "^1.0.0", + "picomatch": "^4.0.2", + "prettier": "^3.0.3", + "viem": "2.x", + "zod": "^3.22.3" + }, + "devDependencies": { + "@types/dedent": "^0.7.2", + "@types/node": "^22.14.0", + "fixturez": "^1.1.0", + "msw": "^2.4.9" + }, + "contributors": ["awkweb.eth ", "jxom.eth "], + "funding": "https://github.com/sponsors/wevm", + "keywords": ["wagmi", "eth", "ethereum", "dapps", "wallet", "web3", "cli"] +} diff --git a/wagmi-project/packages/cli/src/cli.ts b/wagmi-project/packages/cli/src/cli.ts new file mode 100644 index 0000000000..551543bb2b --- /dev/null +++ b/wagmi-project/packages/cli/src/cli.ts @@ -0,0 +1,53 @@ +#!/usr/bin/env node +import { cac } from 'cac' + +import { type Generate, generate } from './commands/generate.js' +import { type Init, init } from './commands/init.js' +import * as logger from './logger.js' +import { version } from './version.js' + +const cli = cac('wagmi') + +cli + .command('generate', 'generate code based on configuration') + .option('-c, --config ', '[string] path to config file') + .option('-r, --root ', '[string] root path to resolve config from') + .option('-w, --watch', '[boolean] watch for changes') + .example((name) => `${name} generate`) + .action(async (options: Generate) => { + await generate(options) + if (!options.watch) process.exit(0) + }) + +cli + .command('init', 'create configuration file') + .option('-c, --config ', '[string] path to config file') + .option('-r, --root ', '[string] root path to resolve config from') + .example((name) => `${name} init`) + .action(async (options: Init) => { + await init(options) + process.exit(0) + }) + +cli.help() +cli.version(version) + +void (async () => { + try { + process.title = 'node (wagmi)' + } catch {} + + try { + // Parse CLI args without running command + cli.parse(process.argv, { run: false }) + if (!cli.matchedCommand) { + if (cli.args.length === 0) { + if (!cli.options.help && !cli.options.version) cli.outputHelp() + } else throw new Error(`Unknown command: ${cli.args.join(' ')}`) + } + await cli.runMatchedCommand() + } catch (error) { + logger.error(`\n${(error as Error).message}`) + process.exit(1) + } +})() diff --git a/wagmi-project/packages/cli/src/commands/generate.test.ts b/wagmi-project/packages/cli/src/commands/generate.test.ts new file mode 100644 index 0000000000..91e4265216 --- /dev/null +++ b/wagmi-project/packages/cli/src/commands/generate.test.ts @@ -0,0 +1,409 @@ +import { readFile } from 'node:fs/promises' +import dedent from 'dedent' +import { resolve } from 'pathe' +import { afterEach, beforeEach, expect, test, vi } from 'vitest' + +import { createFixture, typecheck, watchConsole } from '../../test/utils.js' +import { generate } from './generate.js' + +let console: ReturnType +beforeEach(() => { + console = watchConsole() + vi.useFakeTimers() + + const date = new Date(2023, 0, 30, 12) + vi.setSystemTime(date) +}) + +afterEach(() => { + vi.restoreAllMocks() + vi.useRealTimers() +}) + +test('generates output', async () => { + const { dir } = await createFixture({ + files: { + tsconfig: true, + 'wagmi.config.js': dedent` + export default { + out: 'generated.js', + contracts: [ + { + abi: [], + name: 'Foo', + }, + ], + } + `, + }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await generate() + + expect(console.formatted).toMatchInlineSnapshot(` + "- Validating plugins + √ Validating plugins + - Resolving contracts + √ Resolving contracts + - Running plugins + √ Running plugins + - Writing to generated.js + √ Writing to generated.js" + `) +}) + +test('generates typescript output', async () => { + const { dir, paths } = await createFixture({ + files: { + tsconfig: true, + 'wagmi.config.ts': dedent` + export default { + out: 'generated.ts', + contracts: [ + { + abi: [], + name: 'Foo', + }, + ], + } + `, + }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await generate() + + expect(console.formatted).toMatchInlineSnapshot(` + "- Validating plugins + √ Validating plugins + - Resolving contracts + √ Resolving contracts + - Running plugins + √ Running plugins + - Writing to generated.ts + √ Writing to generated.ts" + `) + await expect(typecheck(paths.tsconfig)).resolves.toMatchInlineSnapshot('""') +}) + +test('generates output with plugin', async () => { + const { dir } = await createFixture({ + files: { + tsconfig: true, + 'wagmi.config.ts': dedent` + export default { + out: 'generated.ts', + contracts: [ + { + abi: [], + name: 'Foo', + }, + ], + plugins: [ + { + name: 'Test', + async run({ contracts, isTypeScript, outputs }) { + return { + imports: '/* imports test */', + prepend: '/* prepend test */', + content: '/* content test */', + } + }, + }, + ], + } + `, + }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await generate() + + expect(console.formatted).toMatchInlineSnapshot(` + "- Validating plugins + √ Validating plugins + - Resolving contracts + √ Resolving contracts + - Running plugins + √ Running plugins + - Writing to generated.ts + √ Writing to generated.ts" + `) + /* eslint-disable no-irregular-whitespace */ + await expect( + readFile(resolve(dir, 'generated.ts'), 'utf8'), + ).resolves.toMatchInlineSnapshot(` + "/* imports test */ + + /* prepend test */ + + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // Foo + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + export const fooAbi = [] as const + + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // Test + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + /* content test */ + " + `) + /* eslint-enable no-irregular-whitespace */ +}) + +test('behavior: invalid cli options', async () => { + const { dir } = await createFixture() + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await expect( + generate({ + // @ts-expect-error possible to pass untyped options through from cli + config: 1, + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [Error: Invalid option + - Expected string, received number at \`config\`] + `) +}) + +test('behavior: config not found', async () => { + const { dir } = await createFixture() + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await expect(generate()).rejects.toThrowErrorMatchingInlineSnapshot( + '[Error: Config not found]', + ) +}) + +test('behavior: config not found for path', async () => { + const { dir } = await createFixture() + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + try { + await generate({ config: 'wagmi.config.js' }) + } catch (error) { + expect( + (error as Error).message.replace(dir, 'path/to/project'), + ).toMatchInlineSnapshot('"Config not found at wagmi.config.js"') + } +}) + +test('behavior: config out not unique', async () => { + const { dir } = await createFixture({ + files: { + 'wagmi.config.js': dedent` + export default [ + { + out: 'generated.ts', + contracts: [ + { + abi: [], + name: 'Foo', + }, + ] + }, + { + out: 'generated.ts', + contracts: [ + { + abi: [], + name: 'Foo', + }, + ], + }, + ] + `, + }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await expect(generate()).rejects.toThrowErrorMatchingInlineSnapshot( + `[Error: out "generated.ts" must be unique.]`, + ) +}) + +test('behavior: config contract names not unique', async () => { + const { dir } = await createFixture({ + files: { + 'wagmi.config.js': dedent` + export default { + out: 'generated.ts', + contracts: [ + { + abi: [], + name: 'Foo', + }, + { + abi: [], + name: 'Foo', + }, + ], + } + `, + }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await expect(generate()).rejects.toThrowErrorMatchingInlineSnapshot( + `[Error: Contract name "Foo" must be unique.]`, + ) +}) + +test('behavior: displays message if no contracts found', async () => { + const { dir } = await createFixture({ + files: { + 'wagmi.config.js': "export default { out: 'generated.ts' }", + }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await generate() + + expect(console.formatted).toMatchInlineSnapshot( + ` + "- Validating plugins + √ Validating plugins + - Resolving contracts + Ɨ Resolving contracts + No contracts found." + `, + ) +}) + +test('behavior: throws when abi is invalid', async () => { + const { dir } = await createFixture({ + files: { + 'wagmi.config.js': dedent` + export default { + out: 'generated.ts', + contracts: [ + { + abi: [{ + type: 'function', + name: 'balanceOf', + stateMutability: 'view', + inputs: [{ type: 'address' }], + }], + name: 'Foo', + }, + ], + } + `, + }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await expect(generate()).rejects.toThrowErrorMatchingInlineSnapshot(` + [Error: Invalid ABI for contract "Foo" + - Invalid input at \`[0]\`] + `) +}) + +test('behavior: throws when address is invalid', async () => { + const { dir } = await createFixture({ + files: { + 'wagmi.config.js': dedent` + export default { + out: 'generated.ts', + contracts: [ + { + abi: [], + address: '0xfoo', + name: 'Foo', + }, + ], + } + `, + }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await expect(generate()).rejects.toThrowErrorMatchingInlineSnapshot(` + [Error: Invalid address for contract "Foo" + - Invalid address] + `) +}) + +test('behavior: throws when multichain address is invalid', async () => { + const { dir } = await createFixture({ + files: { + 'wagmi.config.js': dedent` + export default { + out: 'generated.ts', + contracts: [ + { + abi: [], + address: { + 1: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 5: '0xfoo', + }, + name: 'Foo', + }, + ], + } + `, + }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await expect(generate()).rejects.toThrowErrorMatchingInlineSnapshot(` + [Error: Invalid address for contract "Foo" + - Invalid address at \`5\`] + `) +}) + +test('behavior: displays message if using --watch flag without watchers configured', async () => { + const { dir } = await createFixture({ + files: { + 'wagmi.config.js': dedent` + export default { + out: 'generated.ts', + contracts: [ + { + abi: [], + name: 'Foo', + }, + ], + } + `, + }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await generate({ watch: true }) + + expect(console.formatted).toMatchInlineSnapshot(` + "- Validating plugins + √ Validating plugins + - Resolving contracts + √ Resolving contracts + - Running plugins + √ Running plugins + - Writing to generated.ts + √ Writing to generated.ts + Used --watch flag, but no plugins are watching." + `) +}) + +test.todo('behavior: save config file logs change') +test.todo('behavior: updates on add file') +test.todo('behavior: updates on change file') +test.todo('behavior: updates on unlink file') +test.todo('behavior: runs watch command') +test.todo('behavior: shuts down watch on SIGINT/SIGTERM') diff --git a/wagmi-project/packages/cli/src/commands/generate.ts b/wagmi-project/packages/cli/src/commands/generate.ts new file mode 100644 index 0000000000..992a2e2923 --- /dev/null +++ b/wagmi-project/packages/cli/src/commands/generate.ts @@ -0,0 +1,409 @@ +import { mkdir, writeFile } from 'node:fs/promises' +import { Abi as AbiSchema } from 'abitype/zod' +import { camelCase } from 'change-case' +import type { ChokidarOptions, FSWatcher } from 'chokidar' +import { watch } from 'chokidar' +import { default as dedent } from 'dedent' +import { basename, dirname, resolve } from 'pathe' +import pc from 'picocolors' +import { type Abi, type Address, getAddress } from 'viem' +import { z } from 'zod' + +import type { Contract, ContractConfig, Plugin, Watch } from '../config.js' +import { fromZodError } from '../errors.js' +import * as logger from '../logger.js' +import { findConfig } from '../utils/findConfig.js' +import { format } from '../utils/format.js' +import { getAddressDocString } from '../utils/getAddressDocString.js' +import { getIsUsingTypeScript } from '../utils/getIsUsingTypeScript.js' +import { resolveConfig } from '../utils/resolveConfig.js' + +const Generate = z.object({ + /** Path to config file */ + config: z.string().optional(), + /** Directory to search for config file */ + root: z.string().optional(), + /** Watch for file system changes to config and plugins */ + watch: z.boolean().optional(), +}) +export type Generate = z.infer + +export async function generate(options: Generate = {}) { + // Validate command line options + try { + await Generate.parseAsync(options) + } catch (error) { + if (error instanceof z.ZodError) + throw fromZodError(error, { prefix: 'Invalid option' }) + throw error + } + + // Get cli config file + const configPath = await findConfig(options) + if (!configPath) { + if (options.config) + throw new Error(`Config not found at ${pc.gray(options.config)}`) + throw new Error('Config not found') + } + + const resolvedConfigs = await resolveConfig({ configPath }) + const isTypeScript = await getIsUsingTypeScript() + + type Watcher = FSWatcher & { config?: Watch } + const watchers: Watcher[] = [] + const watchWriteDelay = 100 + const watchOptions = { + atomic: true, + // awaitWriteFinish: true, + ignoreInitial: true, + persistent: true, + } satisfies ChokidarOptions + + const outNames = new Set() + const isArrayConfig = Array.isArray(resolvedConfigs) + const configs = isArrayConfig ? resolvedConfigs : [resolvedConfigs] + for (const config of configs) { + if (isArrayConfig) + logger.log(`Using config ${pc.gray(basename(configPath))}`) + if (!config.out) throw new Error('out is required.') + if (outNames.has(config.out)) + throw new Error(`out "${config.out}" must be unique.`) + outNames.add(config.out) + + // Collect contracts and watch configs from plugins + const plugins = (config.plugins ?? []).map((x, i) => ({ + ...x, + id: `${x.name}-${i}`, + })) + const spinner = logger.spinner('Validating plugins') + spinner.start() + for (const plugin of plugins) { + await plugin.validate?.() + } + spinner.success() + + // Add plugin contracts to config contracts + const contractConfigs = config.contracts ?? [] + const watchConfigs: Watch[] = [] + spinner.start('Resolving contracts') + for (const plugin of plugins) { + if (plugin.watch) watchConfigs.push(plugin.watch) + if (plugin.contracts) { + const contracts = await plugin.contracts() + contractConfigs.push(...contracts) + } + } + + // Get contracts from config + const contractNames = new Set() + const contractMap = new Map() + for (const contractConfig of contractConfigs) { + if (contractNames.has(contractConfig.name)) + throw new Error( + `Contract name "${contractConfig.name}" must be unique.`, + ) + const contract = await getContract({ ...contractConfig, isTypeScript }) + contractMap.set(contract.name, contract) + + contractNames.add(contractConfig.name) + } + + // Sort contracts by name Ascending (low to high) as the key is `String` + const sortedAscContractMap = new Map([...contractMap].sort()) + const contracts = [...sortedAscContractMap.values()] + if (!contracts.length && !options.watch) { + spinner.error() + logger.warn('No contracts found.') + return + } + spinner.success() + + // Run plugins + const imports = [] + const prepend = [] + const content = [] + type Output = { + plugin: Pick + } & Awaited>> + const outputs: Output[] = [] + spinner.start('Running plugins') + for (const plugin of plugins) { + if (!plugin.run) continue + const result = await plugin.run({ + contracts, + isTypeScript, + outputs, + }) + outputs.push({ + plugin: { name: plugin.name }, + ...result, + }) + if (!result.imports && !result.prepend && !result.content) continue + content.push(getBannerContent({ name: plugin.name }), result.content) + result.imports && imports.push(result.imports) + result.prepend && prepend.push(result.prepend) + } + spinner.success() + + // Write output to file + spinner.start(`Writing to ${pc.gray(config.out)}`) + await writeContracts({ + content, + contracts, + imports, + prepend, + filename: config.out, + }) + spinner.success() + + if (options.watch) { + if (!watchConfigs.length) { + logger.log(pc.gray('Used --watch flag, but no plugins are watching.')) + continue + } + logger.log() + logger.log('Setting up watch process') + + // Watch for changes + let timeout: NodeJS.Timeout | null + for (const watchConfig of watchConfigs) { + const paths = + typeof watchConfig.paths === 'function' + ? await watchConfig.paths() + : watchConfig.paths + const watcher = watch(paths, watchOptions) + // Watch for changes to files, new files, and deleted files + watcher.on('all', async (event, path) => { + if (event !== 'change' && event !== 'add' && event !== 'unlink') + return + + let needsWrite = false + if (event === 'change' || event === 'add') { + const eventFn = + event === 'change' ? watchConfig.onChange : watchConfig.onAdd + const config = await eventFn?.(path) + if (!config) return + const contract = await getContract({ ...config, isTypeScript }) + contractMap.set(contract.name, contract) + needsWrite = true + } else if (event === 'unlink') { + const name = await watchConfig.onRemove?.(path) + if (!name) return + contractMap.delete(name) + needsWrite = true + } + + // Debounce writes + if (needsWrite) { + if (timeout) clearTimeout(timeout) + timeout = setTimeout(async () => { + timeout = null + // Sort contracts by name Ascending (low to high) as the key is `String` + const sortedAscContractMap = new Map([...contractMap].sort()) + const contracts = [...sortedAscContractMap.values()] + const imports = [] + const prepend = [] + const content = [] + const outputs: Output[] = [] + for (const plugin of plugins) { + if (!plugin.run) continue + const result = await plugin.run({ + contracts, + isTypeScript, + outputs, + }) + outputs.push({ + plugin: { name: plugin.name }, + ...result, + }) + if (!result.imports && !result.prepend && !result.content) + continue + content.push( + getBannerContent({ name: plugin.name }), + result.content, + ) + result.imports && imports.push(result.imports) + result.prepend && prepend.push(result.prepend) + } + + const spinner = logger.spinner( + `Writing to ${pc.gray(config.out)}`, + ) + spinner.start() + await writeContracts({ + content, + contracts, + imports, + prepend, + filename: config.out, + }) + spinner.success() + }, watchWriteDelay) + needsWrite = false + } + }) + + // Run parallel command on ready + if (watchConfig.command) + watcher.on('ready', async () => { + await watchConfig.command?.() + }) + ;(watcher as Watcher).config = watchConfig + watchers.push(watcher) + } + } + } + + if (!watchers.length) return + + // Watch `@wagmi/cli` config file for changes + const watcher = watch(configPath).on('change', async (path) => { + logger.log( + `> Found a change to config ${pc.gray( + basename(path), + )}. Restart process for changes to take effect.`, + ) + }) + watchers.push(watcher) + + // Display message and close watchers on exit + process.once('SIGINT', shutdown) + process.once('SIGTERM', shutdown) + async function shutdown() { + logger.log() + logger.log('Shutting down watch process') + const promises = [] + for (const watcher of watchers) { + if (watcher.config?.onClose) promises.push(watcher.config?.onClose?.()) + promises.push(watcher.close()) + } + await Promise.allSettled(promises) + process.exit(0) + } +} + +async function getContract({ + abi, + address, + name, + isTypeScript, +}: ContractConfig & { isTypeScript: boolean }): Promise { + const constAssertion = isTypeScript ? ' as const' : '' + const abiName = `${camelCase(name)}Abi` + try { + abi = (await AbiSchema.parseAsync(abi)) as Abi + } catch (error) { + if (error instanceof z.ZodError) + throw fromZodError(error, { + prefix: `Invalid ABI for contract "${name}"`, + }) + throw error + } + const docString = + typeof address === 'object' + ? dedent`\n + /** + ${getAddressDocString({ address })} + */ + ` + : '' + let content = dedent` + ${getBannerContent({ name })} + + ${docString} + export const ${abiName} = ${JSON.stringify(abi)}${constAssertion} + ` + + let meta: Contract['meta'] = { abiName } + if (address) { + let resolvedAddress: Address | Record + try { + const Address = z + .string() + .regex(/^0x[a-fA-F0-9]{40}$/, { message: 'Invalid address' }) + .transform((val) => getAddress(val)) as z.ZodType
+ const MultiChainAddress = z.record(z.string(), Address) + const AddressSchema = z.union([Address, MultiChainAddress]) + resolvedAddress = await AddressSchema.parseAsync(address) + } catch (error) { + if (error instanceof z.ZodError) + throw fromZodError(error, { + prefix: `Invalid address for contract "${name}"`, + }) + throw error + } + + const addressName = `${camelCase(name)}Address` + const configName = `${camelCase(name)}Config` + meta = { + ...meta, + addressName, + configName, + } + + const addressContent = + typeof resolvedAddress === 'string' + ? JSON.stringify(resolvedAddress) + : // Remove quotes from chain id key + JSON.stringify(resolvedAddress, null, 2).replace(/"(\d*)":/gm, '$1:') + content = dedent` + ${content} + + ${docString} + export const ${addressName} = ${addressContent}${constAssertion} + + ${docString} + export const ${configName} = { address: ${addressName}, abi: ${abiName} }${constAssertion} + ` + } + + return { abi, address, content, meta, name } +} + +async function writeContracts({ + content, + contracts, + imports, + prepend, + filename, +}: { + content: string[] + contracts: Contract[] + imports: string[] + prepend: string[] + filename: string +}) { + // Assemble code + let code = dedent` + ${imports.join('\n\n') ?? ''} + + ${prepend.join('\n\n') ?? ''} + ` + for (const contract of contracts) { + code = dedent` + ${code} + + ${contract.content} + ` + } + code = dedent` + ${code} + + ${content.join('\n\n') ?? ''} + ` + + // Format and write output + const cwd = process.cwd() + const outPath = resolve(cwd, filename) + await mkdir(dirname(outPath), { recursive: true }) + const formatted = await format(code) + await writeFile(outPath, formatted) +} + +function getBannerContent({ name }: { name: string }) { + return dedent` + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // ${name} + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + ` +} diff --git a/wagmi-project/packages/cli/src/commands/init.test.ts b/wagmi-project/packages/cli/src/commands/init.test.ts new file mode 100644 index 0000000000..ed4a1d1644 --- /dev/null +++ b/wagmi-project/packages/cli/src/commands/init.test.ts @@ -0,0 +1,189 @@ +import { existsSync } from 'node:fs' +import { mkdir, readFile } from 'node:fs/promises' +import { resolve } from 'pathe' +import { afterEach, beforeEach, expect, test, vi } from 'vitest' + +import { createFixture, watchConsole } from '../../test/utils.js' +import { defaultConfig } from '../config.js' +import { init } from './init.js' + +let console: ReturnType +beforeEach(() => { + console = watchConsole() +}) + +afterEach(() => { + vi.restoreAllMocks() +}) + +test('creates config file', async () => { + const { dir } = await createFixture() + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + const configFile = await init() + + expect(existsSync(configFile)).toBeTruthy() + expect(await readFile(configFile, 'utf-8')).toMatchInlineSnapshot(` + "// @ts-check + + /** @type {import('@wagmi/cli').Config} */ + export default { + out: 'src/generated.js', + contracts: [], + plugins: [], + } + " + `) + expect( + console.formatted.replaceAll(dir, 'path/to/project'), + ).toMatchInlineSnapshot(` + "- Creating config + √ Creating config + Config created at wagmi.config.js" + `) +}) + +test('parameters: config', async () => { + const { dir } = await createFixture() + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + const configFile = await init({ + config: 'foo.config.ts', + }) + + expect(existsSync(configFile)).toBeTruthy() + expect(await readFile(configFile, 'utf-8')).toMatchInlineSnapshot(` + "// @ts-check + + /** @type {import('@wagmi/cli').Config} */ + export default { + out: 'src/generated.js', + contracts: [], + plugins: [], + } + " + `) + expect( + console.formatted.replaceAll(dir, 'path/to/project'), + ).toMatchInlineSnapshot(` + "- Creating config + √ Creating config + Config created at foo.config.ts" + `) +}) + +test('parameters: content', async () => { + const { dir } = await createFixture({ + files: { + 'tsconfig.json': '{}', + }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + const configFile = await init({ + content: { + ...defaultConfig, + out: 'foo/bar/baz.ts', + }, + }) + + expect(existsSync(configFile)).toBeTruthy() + expect(await readFile(configFile, 'utf-8')).toMatchInlineSnapshot(` + "import { defineConfig } from '@wagmi/cli' + + export default defineConfig({ + out: 'foo/bar/baz.ts', + contracts: [], + plugins: [], + }) + " + `) + expect( + console.formatted.replaceAll(dir, 'path/to/project'), + ).toMatchInlineSnapshot(` + "- Creating config + √ Creating config + Config created at wagmi.config.ts" + `) +}) + +test('parameters: root', async () => { + const { dir } = await createFixture() + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + mkdir(resolve(dir, 'foo')) + + const configFile = await init({ + root: 'foo/', + }) + + expect(existsSync(configFile)).toBeTruthy() + expect(await readFile(configFile, 'utf-8')).toMatchInlineSnapshot(` + "// @ts-check + + /** @type {import('@wagmi/cli').Config} */ + export default { + out: 'src/generated.js', + contracts: [], + plugins: [], + } + " + `) + expect( + console.formatted.replaceAll(dir, 'path/to/project'), + ).toMatchInlineSnapshot(` + "- Creating config + √ Creating config + Config created at foo/wagmi.config.js" + `) +}) + +test('behavior: creates config file in TypeScript format', async () => { + const { dir } = await createFixture({ + files: { + 'tsconfig.json': '{}', + }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + const configFile = await init() + + expect(existsSync(configFile)).toBeTruthy() + expect(await readFile(configFile, 'utf-8')).toMatchInlineSnapshot(` + "import { defineConfig } from '@wagmi/cli' + + export default defineConfig({ + out: 'src/generated.ts', + contracts: [], + plugins: [], + }) + " + `) + expect( + console.formatted.replaceAll(dir, 'path/to/project'), + ).toMatchInlineSnapshot(` + "- Creating config + √ Creating config + Config created at wagmi.config.ts" + `) +}) + +test('behavior: displays config file location when config exists', async () => { + const { dir } = await createFixture({ + files: { + 'wagmi.config.ts': '', + }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + const configFile = await init() + + expect( + console.formatted.replaceAll(configFile, 'path/to/project/wagmi.config.ts'), + ).toMatchInlineSnapshot('"Config already exists at wagmi.config.ts"') +}) diff --git a/wagmi-project/packages/cli/src/commands/init.ts b/wagmi-project/packages/cli/src/commands/init.ts new file mode 100644 index 0000000000..ce4e5b32d9 --- /dev/null +++ b/wagmi-project/packages/cli/src/commands/init.ts @@ -0,0 +1,95 @@ +import { writeFile } from 'node:fs/promises' +import dedent from 'dedent' +import { relative, resolve } from 'pathe' +import pc from 'picocolors' +import { z } from 'zod' + +import { type Config, defaultConfig } from '../config.js' +import { fromZodError } from '../errors.js' +import * as logger from '../logger.js' +import { findConfig } from '../utils/findConfig.js' +import { format } from '../utils/format.js' +import { getIsUsingTypeScript } from '../utils/getIsUsingTypeScript.js' + +export type Init = { + /** Path to config file */ + config?: string + /** Watch for file system changes to config and plugins */ + content?: Config + /** Directory to init config file */ + root?: string +} + +const Init = z.object({ + config: z.string().optional(), + content: z.object({}).optional(), + root: z.string().optional(), +}) + +export async function init(options: Init = {}) { + // Validate command line options + try { + await Init.parseAsync(options) + } catch (error) { + if (error instanceof z.ZodError) + throw fromZodError(error, { prefix: 'Invalid option' }) + throw error + } + + // Check for existing config file + const configPath = await findConfig(options) + if (configPath) { + logger.info( + `Config already exists at ${pc.gray( + relative(process.cwd(), configPath), + )}`, + ) + return configPath + } + + const spinner = logger.spinner('Creating config') + spinner.start() + // Check if project is using TypeScript + const isUsingTypeScript = await getIsUsingTypeScript() + const rootDir = resolve(options.root || process.cwd()) + let outPath: string + if (options.config) { + outPath = resolve(rootDir, options.config) + } else { + const extension = isUsingTypeScript ? 'ts' : 'js' + outPath = resolve(rootDir, `wagmi.config.${extension}`) + } + + let content: string + if (isUsingTypeScript) { + const config = options.content ?? defaultConfig + content = dedent(` + import { defineConfig } from '@wagmi/cli' + + export default defineConfig(${JSON.stringify(config)}) + `) + } else { + const config = options.content ?? { + ...defaultConfig, + out: defaultConfig.out.replace('.ts', '.js'), + } + content = dedent(` + // @ts-check + + /** @type {import('@wagmi/cli').Config} */ + export default ${JSON.stringify(config, null, 2).replace( + /"(\d*)":/gm, + '$1:', + )} + `) + } + + const formatted = await format(content) + await writeFile(outPath, formatted) + spinner.success() + logger.success( + `Config created at ${pc.gray(relative(process.cwd(), outPath))}`, + ) + + return outPath +} diff --git a/wagmi-project/packages/cli/src/config.test.ts b/wagmi-project/packages/cli/src/config.test.ts new file mode 100644 index 0000000000..f95d7cb6d3 --- /dev/null +++ b/wagmi-project/packages/cli/src/config.test.ts @@ -0,0 +1,39 @@ +import { expect, test, vi } from 'vitest' + +import { type Config, defineConfig } from './config.js' + +test('object', () => { + const config: Config = { + contracts: [], + out: 'wagmi.ts', + plugins: [], + } + expect(defineConfig(config)).toEqual(config) +}) + +test('array', () => { + const config: Config = { + contracts: [], + out: 'wagmi.ts', + plugins: [], + } + expect(defineConfig([config, config])).toEqual([config, config]) +}) + +test('function', () => { + const config = vi.fn().mockImplementation(() => ({ + contracts: [], + out: 'wagmi.ts', + plugins: [], + })) + expect(defineConfig(config)).toEqual(config) +}) + +test('async function', () => { + const config = vi.fn().mockImplementation(async () => ({ + contracts: [], + out: 'wagmi.ts', + plugins: [], + })) + expect(defineConfig(config)).toEqual(config) +}) diff --git a/wagmi-project/packages/cli/src/config.ts b/wagmi-project/packages/cli/src/config.ts new file mode 100644 index 0000000000..146a1e3424 --- /dev/null +++ b/wagmi-project/packages/cli/src/config.ts @@ -0,0 +1,121 @@ +import type { Abi, Address } from 'viem' + +import type { Compute, MaybeArray, MaybePromise } from './types.js' + +export type ContractConfig< + chainId extends number = number, + requiredChainId extends number | undefined = undefined, +> = { + /** + * Contract ABI + */ + abi: Abi + /** + * Contract address or addresses. + * + * Accepts an object `{ [chainId]: address }` to support multiple chains. + * + * @example + * '0x314159265dd8dbb310642f98f50c066173c1259b' + * + * @example + * { + * 1: '0x314159265dd8dbb310642f98f50c066173c1259b', + * 5: '0x112234455c3a32fd11230c42e7bccd4a84e02010', + * } + */ + address?: + | Address + | (requiredChainId extends number + ? Record & Partial> + : Record) + | undefined + /** + * Name of contract. + */ + name: string +} + +export type Contract = Compute< + ContractConfig & { + /** Generated string content */ + content: string + /** Meta info about contract */ + meta: { + abiName: string + addressName?: string | undefined + configName?: string | undefined + } + } +> + +export type Watch = { + /** Command to run along with watch process */ + command?: (() => MaybePromise) | undefined + /** Paths to watch for changes. */ + paths: string[] | (() => MaybePromise) + /** Callback that fires when file is added */ + onAdd?: + | ((path: string) => MaybePromise) + | undefined + /** Callback that fires when file changes */ + onChange: (path: string) => MaybePromise + /** Callback that fires when watcher is shutdown */ + onClose?: (() => MaybePromise) | undefined + /** Callback that fires when file is removed */ + onRemove?: ((path: string) => MaybePromise) | undefined +} + +export type Plugin = { + /** Contracts provided by plugin */ + contracts?: (() => MaybePromise) | undefined + /** Plugin name */ + name: string + /** Run plugin logic */ + run?: + | ((config: { + /** All resolved contracts from config and plugins */ + contracts: Contract[] + /** Whether TypeScript is detected in project */ + isTypeScript: boolean + /** Previous plugin outputs */ + outputs: readonly { + plugin: Pick + imports?: string + prepend?: string + content: string + }[] + }) => MaybePromise<{ + imports?: string + prepend?: string + content: string + }>) + | undefined + /** + * Validate plugin configuration or other @wagmi/cli settings require for plugin. + */ + validate?: (() => MaybePromise) | undefined + /** File system watch config */ + watch?: Watch | undefined +} + +export type Config = { + /** Contracts to use in commands */ + contracts?: ContractConfig[] | undefined + /** Output file path */ + out: string + /** Plugins to run */ + plugins?: Plugin[] | undefined +} + +export function defineConfig( + config: MaybeArray | (() => MaybePromise>), +) { + return config +} + +export const defaultConfig = { + out: 'src/generated.ts', + contracts: [], + plugins: [], +} satisfies Config diff --git a/wagmi-project/packages/cli/src/errors.ts b/wagmi-project/packages/cli/src/errors.ts new file mode 100644 index 0000000000..6ef37093fc --- /dev/null +++ b/wagmi-project/packages/cli/src/errors.ts @@ -0,0 +1,57 @@ +import type { z } from 'zod' + +class ValidationError extends Error { + details: Zod.ZodIssue[] + + constructor( + message: string, + options: { + details: Zod.ZodIssue[] + }, + ) { + super(message) + this.details = options.details + } +} + +// From https://github.com/causaly/zod-validation-error +export function fromZodError( + zError: z.ZodError, + { + maxIssuesInMessage = 99, + issueSeparator = '\n- ', + prefixSeparator = '\n- ', + prefix = 'Validation Error', + }: { + maxIssuesInMessage?: number + issueSeparator?: string + prefixSeparator?: string + prefix?: string + } = {}, +): ValidationError { + function joinPath(arr: Array): string { + return arr.reduce((acc, value) => { + if (typeof value === 'number') return `${acc}[${value}]` + const separator = acc === '' ? '' : '.' + return acc + separator + value + }, '') + } + + const reason = zError.errors + // limit max number of issues printed in the reason section + .slice(0, maxIssuesInMessage) + // format error message + .map((issue) => { + const { message, path } = issue + if (path.length > 0) return `${message} at \`${joinPath(path)}\`` + return message + }) + // concat as string + .join(issueSeparator) + + const message = reason ? [prefix, reason].join(prefixSeparator) : prefix + + return new ValidationError(message, { + details: zError.errors, + }) +} diff --git a/wagmi-project/packages/cli/src/exports/config.test.ts b/wagmi-project/packages/cli/src/exports/config.test.ts new file mode 100644 index 0000000000..c833780ffc --- /dev/null +++ b/wagmi-project/packages/cli/src/exports/config.test.ts @@ -0,0 +1,12 @@ +import { expect, test } from 'vitest' + +import * as Exports from './config.js' + +test('exports', () => { + expect(Object.keys(Exports)).toMatchInlineSnapshot(` + [ + "defineConfig", + "defaultConfig", + ] + `) +}) diff --git a/wagmi-project/packages/cli/src/exports/config.ts b/wagmi-project/packages/cli/src/exports/config.ts new file mode 100644 index 0000000000..b3c4a83ba4 --- /dev/null +++ b/wagmi-project/packages/cli/src/exports/config.ts @@ -0,0 +1,10 @@ +// biome-ignore lint/performance/noBarrelFile: entrypoint module +export { + type ContractConfig, + type Contract, + type Watch, + type Plugin, + type Config, + defineConfig, + defaultConfig, +} from '../config.js' diff --git a/wagmi-project/packages/cli/src/exports/index.test-d.ts b/wagmi-project/packages/cli/src/exports/index.test-d.ts new file mode 100644 index 0000000000..b056d56358 --- /dev/null +++ b/wagmi-project/packages/cli/src/exports/index.test-d.ts @@ -0,0 +1,4 @@ +import { expectTypeOf } from 'vitest' + +// noop test because vitest typecheck fails unless each workspace project has type test +expectTypeOf(1).toEqualTypeOf() diff --git a/wagmi-project/packages/cli/src/exports/index.test.ts b/wagmi-project/packages/cli/src/exports/index.test.ts new file mode 100644 index 0000000000..2da78e8da1 --- /dev/null +++ b/wagmi-project/packages/cli/src/exports/index.test.ts @@ -0,0 +1,14 @@ +import { expect, test } from 'vitest' + +import * as Exports from './index.js' + +test('exports', () => { + expect(Object.keys(Exports)).toMatchInlineSnapshot(` + [ + "defineConfig", + "logger", + "loadEnv", + "version", + ] + `) +}) diff --git a/wagmi-project/packages/cli/src/exports/index.ts b/wagmi-project/packages/cli/src/exports/index.ts new file mode 100644 index 0000000000..1c5e624df6 --- /dev/null +++ b/wagmi-project/packages/cli/src/exports/index.ts @@ -0,0 +1,14 @@ +// biome-ignore lint/performance/noBarrelFile: entrypoint module +export { + defineConfig, + type Config, + type ContractConfig, + type Plugin, +} from '../config.js' + +// biome-ignore lint/performance/noReExportAll: entrypoint module +export * as logger from '../logger.js' + +export { loadEnv } from '../utils/loadEnv.js' + +export { version } from '../version.js' diff --git a/wagmi-project/packages/cli/src/exports/plugins.test.ts b/wagmi-project/packages/cli/src/exports/plugins.test.ts new file mode 100644 index 0000000000..4d7b5a97cd --- /dev/null +++ b/wagmi-project/packages/cli/src/exports/plugins.test.ts @@ -0,0 +1,20 @@ +import { expect, test } from 'vitest' + +import * as Exports from './plugins.js' + +test('exports', () => { + expect(Object.keys(Exports)).toMatchInlineSnapshot(` + [ + "actions", + "blockExplorer", + "etherscan", + "fetch", + "foundry", + "foundryDefaultExcludes", + "hardhat", + "hardhatDefaultExcludes", + "react", + "sourcify", + ] + `) +}) diff --git a/wagmi-project/packages/cli/src/exports/plugins.ts b/wagmi-project/packages/cli/src/exports/plugins.ts new file mode 100644 index 0000000000..a289b5c576 --- /dev/null +++ b/wagmi-project/packages/cli/src/exports/plugins.ts @@ -0,0 +1,27 @@ +// biome-ignore lint/performance/noBarrelFile: entrypoint module +export { actions, type ActionsConfig } from '../plugins/actions.js' + +export { + blockExplorer, + type BlockExplorerConfig, +} from '../plugins/blockExplorer.js' + +export { etherscan, type EtherscanConfig } from '../plugins/etherscan.js' + +export { fetch, type FetchConfig } from '../plugins/fetch.js' + +export { + foundry, + foundryDefaultExcludes, + type FoundryConfig, +} from '../plugins/foundry.js' + +export { + hardhat, + hardhatDefaultExcludes, + type HardhatConfig, +} from '../plugins/hardhat.js' + +export { react, type ReactConfig } from '../plugins/react.js' + +export { sourcify, type SourcifyConfig } from '../plugins/sourcify.js' diff --git a/wagmi-project/packages/cli/src/logger.test.ts b/wagmi-project/packages/cli/src/logger.test.ts new file mode 100644 index 0000000000..7338c3bb14 --- /dev/null +++ b/wagmi-project/packages/cli/src/logger.test.ts @@ -0,0 +1,32 @@ +import { afterEach, expect, test, vi } from 'vitest' + +import { watchConsole } from '../test/utils.js' + +import * as logger from './logger.js' + +const mockLog = vi.fn() + +afterEach(() => { + vi.restoreAllMocks() +}) + +test.each(['success', 'info', 'log', 'warn', 'error'])('%s()', (level) => { + const spy = vi.spyOn(logger, level as any) + spy.mockImplementation(mockLog) + const loggerFn = (logger as any)[level] + loggerFn(level) + expect(spy).toHaveBeenCalledWith(level) +}) + +test('spinner', () => { + const console = watchConsole() + const spinner = logger.spinner('start') + spinner.start() + spinner.success('success') + spinner.error('error') + expect(console.formatted).toMatchInlineSnapshot(` + "- start + √ success + Ɨ error" + `) +}) diff --git a/wagmi-project/packages/cli/src/logger.ts b/wagmi-project/packages/cli/src/logger.ts new file mode 100644 index 0000000000..b56fb9728b --- /dev/null +++ b/wagmi-project/packages/cli/src/logger.ts @@ -0,0 +1,37 @@ +import { format as utilFormat } from 'node:util' +import { createSpinner } from 'nanospinner' +import pc from 'picocolors' + +function format(args: any[]) { + return utilFormat(...args) + .split('\n') + .join('\n') +} + +export function success(...args: any[]) { + // biome-ignore lint/suspicious/noConsoleLog: console.log is used for logging + console.log(pc.green(format(args))) +} + +export function info(...args: any[]) { + console.info(pc.blue(format(args))) +} + +export function log(...args: any[]) { + // biome-ignore lint/suspicious/noConsoleLog: console.log is used for logging + console.log(pc.white(format(args))) +} + +export function warn(...args: any[]) { + console.warn(pc.yellow(format(args))) +} + +export function error(...args: any[]) { + console.error(pc.red(format(args))) +} + +export function spinner(text: string) { + return createSpinner(text, { + color: 'yellow', + }) +} diff --git a/wagmi-project/packages/cli/src/plugins/__fixtures__/foundry/.gitignore b/wagmi-project/packages/cli/src/plugins/__fixtures__/foundry/.gitignore new file mode 100644 index 0000000000..3269660cc7 --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/__fixtures__/foundry/.gitignore @@ -0,0 +1,11 @@ +# Compiler files +cache/ +out/ + +# Ignores development broadcast logs +!/broadcast +/broadcast/*/31337/ +/broadcast/**/dry-run/ + +# Dotenv file +.env diff --git a/wagmi-project/packages/cli/src/plugins/__fixtures__/foundry/foundry.toml b/wagmi-project/packages/cli/src/plugins/__fixtures__/foundry/foundry.toml new file mode 100644 index 0000000000..59374b16cf --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/__fixtures__/foundry/foundry.toml @@ -0,0 +1,7 @@ +[profile.default] +libs = ['lib'] +out = 'out' +solc = '0.8.13' +src = 'src' + +# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options diff --git a/wagmi-project/packages/cli/src/plugins/__fixtures__/foundry/src/Counter.sol b/wagmi-project/packages/cli/src/plugins/__fixtures__/foundry/src/Counter.sol new file mode 100644 index 0000000000..5242caa433 --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/__fixtures__/foundry/src/Counter.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +contract Counter { + uint256 public number; + + function setNumber(uint256 newNumber) public { + number = newNumber; + } + + function increment() public { + number++; + } +} diff --git a/wagmi-project/packages/cli/src/plugins/__fixtures__/foundry/src/Foo.sol b/wagmi-project/packages/cli/src/plugins/__fixtures__/foundry/src/Foo.sol new file mode 100644 index 0000000000..f478736520 --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/__fixtures__/foundry/src/Foo.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +contract Foo { + string public bar; + + function setFoo(string memory baz) public { + bar = baz; + } +} + diff --git a/wagmi-project/packages/cli/src/plugins/__fixtures__/hardhat/.gitignore b/wagmi-project/packages/cli/src/plugins/__fixtures__/hardhat/.gitignore new file mode 100644 index 0000000000..85d361b914 --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/__fixtures__/hardhat/.gitignore @@ -0,0 +1,10 @@ +node_modules +.env +coverage +coverage.json +typechain +typechain-types + +# Hardhat files +cache +artifacts \ No newline at end of file diff --git a/wagmi-project/packages/cli/src/plugins/__fixtures__/hardhat/contracts/Counter.sol b/wagmi-project/packages/cli/src/plugins/__fixtures__/hardhat/contracts/Counter.sol new file mode 100644 index 0000000000..5242caa433 --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/__fixtures__/hardhat/contracts/Counter.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +contract Counter { + uint256 public number; + + function setNumber(uint256 newNumber) public { + number = newNumber; + } + + function increment() public { + number++; + } +} diff --git a/wagmi-project/packages/cli/src/plugins/__fixtures__/hardhat/contracts/Foo.sol b/wagmi-project/packages/cli/src/plugins/__fixtures__/hardhat/contracts/Foo.sol new file mode 100644 index 0000000000..699a63ce0f --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/__fixtures__/hardhat/contracts/Foo.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +contract Foo { + string public bar; + + function setFoo(string memory baz) public { + bar = baz; + } +} diff --git a/wagmi-project/packages/cli/src/plugins/__fixtures__/hardhat/hardhat.config.js b/wagmi-project/packages/cli/src/plugins/__fixtures__/hardhat/hardhat.config.js new file mode 100644 index 0000000000..c8126eedfa --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/__fixtures__/hardhat/hardhat.config.js @@ -0,0 +1,3 @@ +module.exports = { + solidity: '0.8.17', +} diff --git a/wagmi-project/packages/cli/src/plugins/__fixtures__/hardhat/package.json b/wagmi-project/packages/cli/src/plugins/__fixtures__/hardhat/package.json new file mode 100644 index 0000000000..85c9ffb7bd --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/__fixtures__/hardhat/package.json @@ -0,0 +1,7 @@ +{ + "name": "hardhat-fixture", + "private": true, + "devDependencies": { + "hardhat": "^2.22.3" + } +} diff --git a/wagmi-project/packages/cli/src/plugins/__snapshots__/blockExplorer.test.ts.snap b/wagmi-project/packages/cli/src/plugins/__snapshots__/blockExplorer.test.ts.snap new file mode 100644 index 0000000000..2abd351741 --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/__snapshots__/blockExplorer.test.ts.snap @@ -0,0 +1,736 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`fetches ABI 1`] = ` +[ + { + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address", + }, + { + "indexed": true, + "internalType": "address", + "name": "approved", + "type": "address", + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "Approval", + "type": "event", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address", + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address", + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool", + }, + ], + "name": "ApprovalForAll", + "type": "event", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "Transfer", + "type": "event", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "approve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address", + }, + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "getApproved", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address", + }, + { + "internalType": "address", + "name": "operator", + "type": "address", + }, + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "ownerOf", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes", + }, + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address", + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool", + }, + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4", + }, + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "tokenURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string", + }, + ], + "stateMutability": "pure", + "type": "function", + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "transferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "address": "0xaf0326d92b97df1221759476b072abfd8084f9be", + "name": "WagmiMintExample", + }, +] +`; + +exports[`fetches ABI with multichain deployment 1`] = ` +[ + { + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address", + }, + { + "indexed": true, + "internalType": "address", + "name": "approved", + "type": "address", + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "Approval", + "type": "event", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address", + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address", + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool", + }, + ], + "name": "ApprovalForAll", + "type": "event", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "Transfer", + "type": "event", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "approve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address", + }, + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "getApproved", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address", + }, + { + "internalType": "address", + "name": "operator", + "type": "address", + }, + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "ownerOf", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes", + }, + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address", + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool", + }, + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4", + }, + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "tokenURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string", + }, + ], + "stateMutability": "pure", + "type": "function", + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "transferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "address": { + "1": "0xaf0326d92b97df1221759476b072abfd8084f9be", + "10": "0xaf0326d92b97df1221759476b072abfd8084f9be", + }, + "name": "WagmiMintExample", + }, +] +`; diff --git a/wagmi-project/packages/cli/src/plugins/__snapshots__/etherscan.test.ts.snap b/wagmi-project/packages/cli/src/plugins/__snapshots__/etherscan.test.ts.snap new file mode 100644 index 0000000000..e03ee30f81 --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/__snapshots__/etherscan.test.ts.snap @@ -0,0 +1,1238 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`fetches ABI 1`] = ` +[ + { + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address", + }, + { + "indexed": true, + "internalType": "address", + "name": "approved", + "type": "address", + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "Approval", + "type": "event", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address", + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address", + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool", + }, + ], + "name": "ApprovalForAll", + "type": "event", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "Transfer", + "type": "event", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "approve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address", + }, + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "getApproved", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address", + }, + { + "internalType": "address", + "name": "operator", + "type": "address", + }, + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "ownerOf", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes", + }, + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address", + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool", + }, + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4", + }, + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "tokenURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string", + }, + ], + "stateMutability": "pure", + "type": "function", + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "transferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "address": { + "1": "0xaf0326d92b97df1221759476b072abfd8084f9be", + }, + "name": "WagmiMintExample", + }, +] +`; + +exports[`fetches ABI with multichain deployment 1`] = ` +[ + { + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address", + }, + { + "indexed": true, + "internalType": "address", + "name": "approved", + "type": "address", + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "Approval", + "type": "event", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address", + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address", + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool", + }, + ], + "name": "ApprovalForAll", + "type": "event", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "Transfer", + "type": "event", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "approve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address", + }, + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "getApproved", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address", + }, + { + "internalType": "address", + "name": "operator", + "type": "address", + }, + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "ownerOf", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes", + }, + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address", + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool", + }, + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4", + }, + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "tokenURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string", + }, + ], + "stateMutability": "pure", + "type": "function", + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "transferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "address": { + "1": "0xaf0326d92b97df1221759476b072abfd8084f9be", + "10": "0xaf0326d92b97df1221759476b072abfd8084f9be", + }, + "name": "WagmiMintExample", + }, +] +`; + +exports[`tryFetchProxyImplementation: fetches ABI 1`] = ` +[ + { + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address", + }, + { + "indexed": true, + "internalType": "address", + "name": "approved", + "type": "address", + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "Approval", + "type": "event", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address", + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address", + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool", + }, + ], + "name": "ApprovalForAll", + "type": "event", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "Transfer", + "type": "event", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "approve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address", + }, + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "getApproved", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address", + }, + { + "internalType": "address", + "name": "operator", + "type": "address", + }, + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "ownerOf", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes", + }, + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address", + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool", + }, + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4", + }, + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "tokenURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string", + }, + ], + "stateMutability": "pure", + "type": "function", + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "transferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "address": { + "1": "0xaf0326d92b97df1221759476b072abfd8084f9be", + }, + "name": "WagmiMintExample", + }, +] +`; + +exports[`tryFetchProxyImplementation: fetches implementation ABI 1`] = ` +[ + { + "abi": [ + { + "constant": false, + "inputs": [ + { + "name": "newImplementation", + "type": "address", + }, + ], + "name": "upgradeTo", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + }, + { + "constant": false, + "inputs": [ + { + "name": "newImplementation", + "type": "address", + }, + { + "name": "data", + "type": "bytes", + }, + ], + "name": "upgradeToAndCall", + "outputs": [], + "payable": true, + "stateMutability": "payable", + "type": "function", + }, + { + "constant": true, + "inputs": [], + "name": "implementation", + "outputs": [ + { + "name": "", + "type": "address", + }, + ], + "payable": false, + "stateMutability": "view", + "type": "function", + }, + { + "constant": false, + "inputs": [ + { + "name": "newAdmin", + "type": "address", + }, + ], + "name": "changeAdmin", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + }, + { + "constant": true, + "inputs": [], + "name": "admin", + "outputs": [ + { + "name": "", + "type": "address", + }, + ], + "payable": false, + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "name": "_implementation", + "type": "address", + }, + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor", + }, + { + "payable": true, + "stateMutability": "payable", + "type": "fallback", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "previousAdmin", + "type": "address", + }, + { + "indexed": false, + "name": "newAdmin", + "type": "address", + }, + ], + "name": "AdminChanged", + "type": "event", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "name": "implementation", + "type": "address", + }, + ], + "name": "Upgraded", + "type": "event", + }, + ], + "address": { + "1": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", + }, + "name": "FiatToken", + }, +] +`; diff --git a/wagmi-project/packages/cli/src/plugins/__snapshots__/fetch.test.ts.snap b/wagmi-project/packages/cli/src/plugins/__snapshots__/fetch.test.ts.snap new file mode 100644 index 0000000000..83c4e81f53 --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/__snapshots__/fetch.test.ts.snap @@ -0,0 +1,367 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`fetches ABI 1`] = ` +[ + { + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address", + }, + { + "indexed": true, + "internalType": "address", + "name": "approved", + "type": "address", + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "Approval", + "type": "event", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address", + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address", + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool", + }, + ], + "name": "ApprovalForAll", + "type": "event", + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "Transfer", + "type": "event", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "approve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address", + }, + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "getApproved", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address", + }, + { + "internalType": "address", + "name": "operator", + "type": "address", + }, + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "ownerOf", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes", + }, + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address", + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool", + }, + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4", + }, + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "tokenURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string", + }, + ], + "stateMutability": "pure", + "type": "function", + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address", + }, + { + "internalType": "address", + "name": "to", + "type": "address", + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256", + }, + ], + "name": "transferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "address": "0xaf0326d92b97df1221759476b072abfd8084f9be", + "name": "WagmiMintExample", + }, +] +`; diff --git a/wagmi-project/packages/cli/src/plugins/__snapshots__/sourcify.test.ts.snap b/wagmi-project/packages/cli/src/plugins/__snapshots__/sourcify.test.ts.snap new file mode 100644 index 0000000000..77e82fecde --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/__snapshots__/sourcify.test.ts.snap @@ -0,0 +1,214 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`fetches ABI 1`] = ` +[ + { + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor", + }, + { + "inputs": [ + { + "name": "pubkey", + "type": "bytes", + }, + { + "name": "withdrawal_credentials", + "type": "bytes", + }, + { + "name": "amount", + "type": "bytes", + }, + { + "name": "signature", + "type": "bytes", + }, + { + "name": "index", + "type": "bytes", + }, + ], + "name": "DepositEvent", + "type": "event", + }, + { + "inputs": [ + { + "name": "pubkey", + "type": "bytes", + }, + { + "name": "withdrawal_credentials", + "type": "bytes", + }, + { + "name": "signature", + "type": "bytes", + }, + { + "name": "deposit_data_root", + "type": "bytes32", + }, + ], + "name": "deposit", + "outputs": [], + "stateMutability": "payable", + "type": "function", + }, + { + "inputs": [], + "name": "get_deposit_count", + "outputs": [ + { + "type": "bytes", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "get_deposit_root", + "outputs": [ + { + "type": "bytes32", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "name": "interfaceId", + "type": "bytes4", + }, + ], + "name": "supportsInterface", + "outputs": [ + { + "type": "bool", + }, + ], + "stateMutability": "pure", + "type": "function", + }, + ], + "address": { + "1": "0x00000000219ab540356cbb839cbe05303d7705fa", + }, + "name": "DepositContract", + }, +] +`; + +exports[`fetches ABI with multichain deployment 1`] = ` +[ + { + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor", + }, + { + "inputs": [ + { + "name": "pubkey", + "type": "bytes", + }, + { + "name": "withdrawal_credentials", + "type": "bytes", + }, + { + "name": "amount", + "type": "bytes", + }, + { + "name": "signature", + "type": "bytes", + }, + { + "name": "index", + "type": "bytes", + }, + ], + "name": "DepositEvent", + "type": "event", + }, + { + "inputs": [ + { + "name": "pubkey", + "type": "bytes", + }, + { + "name": "withdrawal_credentials", + "type": "bytes", + }, + { + "name": "signature", + "type": "bytes", + }, + { + "name": "deposit_data_root", + "type": "bytes32", + }, + ], + "name": "deposit", + "outputs": [], + "stateMutability": "payable", + "type": "function", + }, + { + "inputs": [], + "name": "get_deposit_count", + "outputs": [ + { + "type": "bytes", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [], + "name": "get_deposit_root", + "outputs": [ + { + "type": "bytes32", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "name": "interfaceId", + "type": "bytes4", + }, + ], + "name": "supportsInterface", + "outputs": [ + { + "type": "bool", + }, + ], + "stateMutability": "pure", + "type": "function", + }, + ], + "address": { + "100": "0xC4c622862a8F548997699bE24EA4bc504e5cA865", + "137": "0xC4c622862a8F548997699bE24EA4bc504e5cA865", + }, + "name": "Community", + }, +] +`; diff --git a/wagmi-project/packages/cli/src/plugins/actions.test.ts b/wagmi-project/packages/cli/src/plugins/actions.test.ts new file mode 100644 index 0000000000..51b445b616 --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/actions.test.ts @@ -0,0 +1,359 @@ +import { erc20Abi } from 'viem' +import { expect, test } from 'vitest' + +import { actions } from './actions.js' + +test('default', async () => { + const result = await actions().run?.({ + contracts: [ + { + name: 'erc20', + abi: erc20Abi, + content: '', + meta: { + abiName: 'erc20Abi', + }, + }, + ], + isTypeScript: true, + outputs: [], + }) + + expect(result?.imports).toMatchInlineSnapshot(` + "import { createReadContract, createWriteContract, createSimulateContract, createWatchContractEvent } from '@wagmi/core/codegen' + " + `) + expect(result?.content).toMatchInlineSnapshot(` + "/** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const readErc20 = /*#__PURE__*/ createReadContract({ abi: erc20Abi }) + + /** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"allowance"\` + */ + export const readErc20Allowance = /*#__PURE__*/ createReadContract({ abi: erc20Abi, functionName: 'allowance' }) + + /** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"balanceOf"\` + */ + export const readErc20BalanceOf = /*#__PURE__*/ createReadContract({ abi: erc20Abi, functionName: 'balanceOf' }) + + /** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"decimals"\` + */ + export const readErc20Decimals = /*#__PURE__*/ createReadContract({ abi: erc20Abi, functionName: 'decimals' }) + + /** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"name"\` + */ + export const readErc20Name = /*#__PURE__*/ createReadContract({ abi: erc20Abi, functionName: 'name' }) + + /** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"symbol"\` + */ + export const readErc20Symbol = /*#__PURE__*/ createReadContract({ abi: erc20Abi, functionName: 'symbol' }) + + /** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"totalSupply"\` + */ + export const readErc20TotalSupply = /*#__PURE__*/ createReadContract({ abi: erc20Abi, functionName: 'totalSupply' }) + + /** + * Wraps __{@link writeContract}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const writeErc20 = /*#__PURE__*/ createWriteContract({ abi: erc20Abi }) + + /** + * Wraps __{@link writeContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"approve"\` + */ + export const writeErc20Approve = /*#__PURE__*/ createWriteContract({ abi: erc20Abi, functionName: 'approve' }) + + /** + * Wraps __{@link writeContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transfer"\` + */ + export const writeErc20Transfer = /*#__PURE__*/ createWriteContract({ abi: erc20Abi, functionName: 'transfer' }) + + /** + * Wraps __{@link writeContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transferFrom"\` + */ + export const writeErc20TransferFrom = /*#__PURE__*/ createWriteContract({ abi: erc20Abi, functionName: 'transferFrom' }) + + /** + * Wraps __{@link simulateContract}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const simulateErc20 = /*#__PURE__*/ createSimulateContract({ abi: erc20Abi }) + + /** + * Wraps __{@link simulateContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"approve"\` + */ + export const simulateErc20Approve = /*#__PURE__*/ createSimulateContract({ abi: erc20Abi, functionName: 'approve' }) + + /** + * Wraps __{@link simulateContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transfer"\` + */ + export const simulateErc20Transfer = /*#__PURE__*/ createSimulateContract({ abi: erc20Abi, functionName: 'transfer' }) + + /** + * Wraps __{@link simulateContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transferFrom"\` + */ + export const simulateErc20TransferFrom = /*#__PURE__*/ createSimulateContract({ abi: erc20Abi, functionName: 'transferFrom' }) + + /** + * Wraps __{@link watchContractEvent}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const watchErc20Event = /*#__PURE__*/ createWatchContractEvent({ abi: erc20Abi }) + + /** + * Wraps __{@link watchContractEvent}__ with \`abi\` set to __{@link erc20Abi}__ and \`eventName\` set to \`"Approval"\` + */ + export const watchErc20ApprovalEvent = /*#__PURE__*/ createWatchContractEvent({ abi: erc20Abi, eventName: 'Approval' }) + + /** + * Wraps __{@link watchContractEvent}__ with \`abi\` set to __{@link erc20Abi}__ and \`eventName\` set to \`"Transfer"\` + */ + export const watchErc20TransferEvent = /*#__PURE__*/ createWatchContractEvent({ abi: erc20Abi, eventName: 'Transfer' })" + `) +}) + +test('address', async () => { + const result = await actions().run?.({ + contracts: [ + { + name: 'erc20', + abi: erc20Abi, + content: '', + meta: { + abiName: 'erc20Abi', + addressName: 'erc20Address', + }, + }, + ], + isTypeScript: true, + outputs: [], + }) + + expect(result?.content).toMatchInlineSnapshot(` + "/** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const readErc20 = /*#__PURE__*/ createReadContract({ abi: erc20Abi, address: erc20Address }) + + /** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"allowance"\` + */ + export const readErc20Allowance = /*#__PURE__*/ createReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'allowance' }) + + /** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"balanceOf"\` + */ + export const readErc20BalanceOf = /*#__PURE__*/ createReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'balanceOf' }) + + /** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"decimals"\` + */ + export const readErc20Decimals = /*#__PURE__*/ createReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'decimals' }) + + /** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"name"\` + */ + export const readErc20Name = /*#__PURE__*/ createReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'name' }) + + /** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"symbol"\` + */ + export const readErc20Symbol = /*#__PURE__*/ createReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'symbol' }) + + /** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"totalSupply"\` + */ + export const readErc20TotalSupply = /*#__PURE__*/ createReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'totalSupply' }) + + /** + * Wraps __{@link writeContract}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const writeErc20 = /*#__PURE__*/ createWriteContract({ abi: erc20Abi, address: erc20Address }) + + /** + * Wraps __{@link writeContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"approve"\` + */ + export const writeErc20Approve = /*#__PURE__*/ createWriteContract({ abi: erc20Abi, address: erc20Address, functionName: 'approve' }) + + /** + * Wraps __{@link writeContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transfer"\` + */ + export const writeErc20Transfer = /*#__PURE__*/ createWriteContract({ abi: erc20Abi, address: erc20Address, functionName: 'transfer' }) + + /** + * Wraps __{@link writeContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transferFrom"\` + */ + export const writeErc20TransferFrom = /*#__PURE__*/ createWriteContract({ abi: erc20Abi, address: erc20Address, functionName: 'transferFrom' }) + + /** + * Wraps __{@link simulateContract}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const simulateErc20 = /*#__PURE__*/ createSimulateContract({ abi: erc20Abi, address: erc20Address }) + + /** + * Wraps __{@link simulateContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"approve"\` + */ + export const simulateErc20Approve = /*#__PURE__*/ createSimulateContract({ abi: erc20Abi, address: erc20Address, functionName: 'approve' }) + + /** + * Wraps __{@link simulateContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transfer"\` + */ + export const simulateErc20Transfer = /*#__PURE__*/ createSimulateContract({ abi: erc20Abi, address: erc20Address, functionName: 'transfer' }) + + /** + * Wraps __{@link simulateContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transferFrom"\` + */ + export const simulateErc20TransferFrom = /*#__PURE__*/ createSimulateContract({ abi: erc20Abi, address: erc20Address, functionName: 'transferFrom' }) + + /** + * Wraps __{@link watchContractEvent}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const watchErc20Event = /*#__PURE__*/ createWatchContractEvent({ abi: erc20Abi, address: erc20Address }) + + /** + * Wraps __{@link watchContractEvent}__ with \`abi\` set to __{@link erc20Abi}__ and \`eventName\` set to \`"Approval"\` + */ + export const watchErc20ApprovalEvent = /*#__PURE__*/ createWatchContractEvent({ abi: erc20Abi, address: erc20Address, eventName: 'Approval' }) + + /** + * Wraps __{@link watchContractEvent}__ with \`abi\` set to __{@link erc20Abi}__ and \`eventName\` set to \`"Transfer"\` + */ + export const watchErc20TransferEvent = /*#__PURE__*/ createWatchContractEvent({ abi: erc20Abi, address: erc20Address, eventName: 'Transfer' })" + `) +}) + +test('legacy hook names', async () => { + const result = await actions({ getActionName: 'legacy' }).run?.({ + contracts: [ + { + name: 'erc20', + abi: erc20Abi, + content: '', + meta: { + abiName: 'erc20Abi', + addressName: 'erc20Address', + }, + }, + ], + isTypeScript: true, + outputs: [], + }) + + expect(result?.content).toMatchInlineSnapshot(` + "/** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const readErc20 = /*#__PURE__*/ createReadContract({ abi: erc20Abi, address: erc20Address }) + + /** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"allowance"\` + */ + export const readErc20Allowance = /*#__PURE__*/ createReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'allowance' }) + + /** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"balanceOf"\` + */ + export const readErc20BalanceOf = /*#__PURE__*/ createReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'balanceOf' }) + + /** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"decimals"\` + */ + export const readErc20Decimals = /*#__PURE__*/ createReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'decimals' }) + + /** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"name"\` + */ + export const readErc20Name = /*#__PURE__*/ createReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'name' }) + + /** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"symbol"\` + */ + export const readErc20Symbol = /*#__PURE__*/ createReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'symbol' }) + + /** + * Wraps __{@link readContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"totalSupply"\` + */ + export const readErc20TotalSupply = /*#__PURE__*/ createReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'totalSupply' }) + + /** + * Wraps __{@link writeContract}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const writeErc20 = /*#__PURE__*/ createWriteContract({ abi: erc20Abi, address: erc20Address }) + + /** + * Wraps __{@link writeContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"approve"\` + */ + export const writeErc20Approve = /*#__PURE__*/ createWriteContract({ abi: erc20Abi, address: erc20Address, functionName: 'approve' }) + + /** + * Wraps __{@link writeContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transfer"\` + */ + export const writeErc20Transfer = /*#__PURE__*/ createWriteContract({ abi: erc20Abi, address: erc20Address, functionName: 'transfer' }) + + /** + * Wraps __{@link writeContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transferFrom"\` + */ + export const writeErc20TransferFrom = /*#__PURE__*/ createWriteContract({ abi: erc20Abi, address: erc20Address, functionName: 'transferFrom' }) + + /** + * Wraps __{@link simulateContract}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const prepareWriteErc20 = /*#__PURE__*/ createSimulateContract({ abi: erc20Abi, address: erc20Address }) + + /** + * Wraps __{@link simulateContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"approve"\` + */ + export const prepareWriteErc20Approve = /*#__PURE__*/ createSimulateContract({ abi: erc20Abi, address: erc20Address, functionName: 'approve' }) + + /** + * Wraps __{@link simulateContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transfer"\` + */ + export const prepareWriteErc20Transfer = /*#__PURE__*/ createSimulateContract({ abi: erc20Abi, address: erc20Address, functionName: 'transfer' }) + + /** + * Wraps __{@link simulateContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transferFrom"\` + */ + export const prepareWriteErc20TransferFrom = /*#__PURE__*/ createSimulateContract({ abi: erc20Abi, address: erc20Address, functionName: 'transferFrom' }) + + /** + * Wraps __{@link watchContractEvent}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const watchErc20Event = /*#__PURE__*/ createWatchContractEvent({ abi: erc20Abi, address: erc20Address }) + + /** + * Wraps __{@link watchContractEvent}__ with \`abi\` set to __{@link erc20Abi}__ and \`eventName\` set to \`"Approval"\` + */ + export const watchErc20ApprovalEvent = /*#__PURE__*/ createWatchContractEvent({ abi: erc20Abi, address: erc20Address, eventName: 'Approval' }) + + /** + * Wraps __{@link watchContractEvent}__ with \`abi\` set to __{@link erc20Abi}__ and \`eventName\` set to \`"Transfer"\` + */ + export const watchErc20TransferEvent = /*#__PURE__*/ createWatchContractEvent({ abi: erc20Abi, address: erc20Address, eventName: 'Transfer' })" + `) +}) + +test('override package name', async () => { + const result = await actions({ overridePackageName: 'wagmi' }).run?.({ + contracts: [ + { + name: 'erc20', + abi: erc20Abi, + content: '', + meta: { + abiName: 'erc20Abi', + }, + }, + ], + isTypeScript: true, + outputs: [], + }) + + expect(result?.imports).toMatchInlineSnapshot(` + "import { createReadContract, createWriteContract, createSimulateContract, createWatchContractEvent } from 'wagmi/codegen' + " + `) +}) diff --git a/wagmi-project/packages/cli/src/plugins/actions.ts b/wagmi-project/packages/cli/src/plugins/actions.ts new file mode 100644 index 0000000000..01c804fd91 --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/actions.ts @@ -0,0 +1,321 @@ +import { pascalCase } from 'change-case' + +import type { Contract, Plugin } from '../config.js' +import type { Compute, RequiredBy } from '../types.js' +import { getAddressDocString } from '../utils/getAddressDocString.js' +import { getIsPackageInstalled } from '../utils/packages.js' + +export type ActionsConfig = { + getActionName?: + | 'legacy' // TODO: Deprecate `'legacy'` option + | ((options: { + contractName: string + itemName?: string | undefined + type: 'read' | 'simulate' | 'watch' | 'write' + }) => string) + overridePackageName?: '@wagmi/core' | 'wagmi' | undefined +} + +type ActionsResult = Compute> + +export function actions(config: ActionsConfig = {}): ActionsResult { + return { + name: 'Action', + async run({ contracts }) { + const imports = new Set([]) + const content: string[] = [] + const pure = '/*#__PURE__*/' + + const actionNames = new Set() + for (const contract of contracts) { + let hasReadFunction = false + let hasWriteFunction = false + let hasEvent = false + const readItems = [] + const writeItems = [] + const eventItems = [] + for (const item of contract.abi) { + if (item.type === 'function') + if ( + item.stateMutability === 'view' || + item.stateMutability === 'pure' + ) { + hasReadFunction = true + readItems.push(item) + } else { + hasWriteFunction = true + writeItems.push(item) + } + else if (item.type === 'event') { + hasEvent = true + eventItems.push(item) + } + } + + let innerContent: string + if (contract.meta.addressName) + innerContent = `abi: ${contract.meta.abiName}, address: ${contract.meta.addressName}` + else innerContent = `abi: ${contract.meta.abiName}` + + if (hasReadFunction) { + const actionName = getActionName( + config, + actionNames, + 'read', + contract.name, + ) + const docString = genDocString('readContract', contract) + const functionName = 'createReadContract' + imports.add(functionName) + content.push( + `${docString} +export const ${actionName} = ${pure} ${functionName}({ ${innerContent} })`, + ) + + const names = new Set() + for (const item of readItems) { + if (item.type !== 'function') continue + if ( + item.stateMutability !== 'pure' && + item.stateMutability !== 'view' + ) + continue + + // Skip overrides since they are captured by same hook + if (names.has(item.name)) continue + names.add(item.name) + + const hookName = getActionName( + config, + actionNames, + 'read', + contract.name, + item.name, + ) + const docString = genDocString('readContract', contract, { + name: 'functionName', + value: item.name, + }) + content.push( + `${docString} +export const ${hookName} = ${pure} ${functionName}({ ${innerContent}, functionName: '${item.name}' })`, + ) + } + } + + if (hasWriteFunction) { + { + const actionName = getActionName( + config, + actionNames, + 'write', + contract.name, + ) + const docString = genDocString('writeContract', contract) + const functionName = 'createWriteContract' + imports.add(functionName) + content.push( + `${docString} +export const ${actionName} = ${pure} ${functionName}({ ${innerContent} })`, + ) + + const names = new Set() + for (const item of writeItems) { + if (item.type !== 'function') continue + if ( + item.stateMutability !== 'nonpayable' && + item.stateMutability !== 'payable' + ) + continue + + // Skip overrides since they are captured by same hook + if (names.has(item.name)) continue + names.add(item.name) + + const actionName = getActionName( + config, + actionNames, + 'write', + contract.name, + item.name, + ) + const docString = genDocString('writeContract', contract, { + name: 'functionName', + value: item.name, + }) + content.push( + `${docString} +export const ${actionName} = ${pure} ${functionName}({ ${innerContent}, functionName: '${item.name}' })`, + ) + } + } + + { + const actionName = getActionName( + config, + actionNames, + 'simulate', + contract.name, + ) + const docString = genDocString('simulateContract', contract) + const functionName = 'createSimulateContract' + imports.add(functionName) + content.push( + `${docString} +export const ${actionName} = ${pure} ${functionName}({ ${innerContent} })`, + ) + + const names = new Set() + for (const item of writeItems) { + if (item.type !== 'function') continue + if ( + item.stateMutability !== 'nonpayable' && + item.stateMutability !== 'payable' + ) + continue + + // Skip overrides since they are captured by same hook + if (names.has(item.name)) continue + names.add(item.name) + + const actionName = getActionName( + config, + actionNames, + 'simulate', + contract.name, + item.name, + ) + const docString = genDocString('simulateContract', contract, { + name: 'functionName', + value: item.name, + }) + content.push( + `${docString} +export const ${actionName} = ${pure} ${functionName}({ ${innerContent}, functionName: '${item.name}' })`, + ) + } + } + } + + if (hasEvent) { + const actionName = getActionName( + config, + actionNames, + 'watch', + contract.name, + ) + const docString = genDocString('watchContractEvent', contract) + const functionName = 'createWatchContractEvent' + imports.add(functionName) + content.push( + `${docString} +export const ${actionName} = ${pure} ${functionName}({ ${innerContent} })`, + ) + + const names = new Set() + for (const item of eventItems) { + if (item.type !== 'event') continue + + // Skip overrides since they are captured by same hook + if (names.has(item.name)) continue + names.add(item.name) + + const actionName = getActionName( + config, + actionNames, + 'watch', + contract.name, + item.name, + ) + const docString = genDocString('watchContractEvent', contract, { + name: 'eventName', + value: item.name, + }) + content.push( + `${docString} +export const ${actionName} = ${pure} ${functionName}({ ${innerContent}, eventName: '${item.name}' })`, + ) + } + } + } + + const importValues = [...imports.values()] + + let packageName = '@wagmi/core/codegen' + if (config.overridePackageName) { + switch (config.overridePackageName) { + case '@wagmi/core': + packageName = '@wagmi/core/codegen' + break + case 'wagmi': + packageName = 'wagmi/codegen' + break + } + } else if (await getIsPackageInstalled({ packageName: 'wagmi' })) + packageName = 'wagmi/codegen' + else if (await getIsPackageInstalled({ packageName: '@wagmi/core' })) + packageName = '@wagmi/core/codegen' + + return { + imports: importValues.length + ? `import { ${importValues.join(', ')} } from '${packageName}'\n` + : '', + content: content.join('\n\n'), + } + }, + } +} + +function genDocString( + actionName: string, + contract: Contract, + item?: { name: string; value: string }, +) { + let description = `Wraps __{@link ${actionName}}__ with \`abi\` set to __{@link ${contract.meta.abiName}}__` + if (item) description += ` and \`${item.name}\` set to \`"${item.value}"\`` + + const docString = getAddressDocString({ address: contract.address }) + if (docString) + return `/** + * ${description} + * + ${docString} + */` + + return `/** + * ${description} + */` +} + +function getActionName( + config: ActionsConfig, + actionNames: Set, + type: 'read' | 'simulate' | 'watch' | 'write', + contractName: string, + itemName?: string | undefined, +) { + const ContractName = pascalCase(contractName) + const ItemName = itemName ? pascalCase(itemName) : undefined + + let actionName: string + if (typeof config.getActionName === 'function') + actionName = config.getActionName({ + type, + contractName: ContractName, + itemName: ItemName, + }) + else if (typeof config.getActionName === 'string' && type === 'simulate') { + actionName = `prepareWrite${ContractName}${ItemName ?? ''}` + } else { + actionName = `${type}${ContractName}${ItemName ?? ''}` + if (type === 'watch') actionName = `${actionName}Event` + } + + if (actionNames.has(actionName)) + throw new Error( + `Action name "${actionName}" must be unique for contract "${contractName}". Try using \`getActionName\` to create a unique name.`, + ) + + actionNames.add(actionName) + return actionName +} diff --git a/wagmi-project/packages/cli/src/plugins/blockExplorer.test.ts b/wagmi-project/packages/cli/src/plugins/blockExplorer.test.ts new file mode 100644 index 0000000000..13372f53ec --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/blockExplorer.test.ts @@ -0,0 +1,53 @@ +import { setupServer } from 'msw/node' +import { afterAll, afterEach, beforeAll, expect, test } from 'vitest' + +import { + address, + apiKey, + baseUrl, + handlers, + unverifiedContractAddress, +} from '../../test/utils.js' +import { blockExplorer } from './blockExplorer.js' + +const server = setupServer(...handlers) + +beforeAll(() => server.listen()) +afterEach(() => server.resetHandlers()) +afterAll(() => server.close()) + +test('fetches ABI', async () => { + await expect( + blockExplorer({ + apiKey, + baseUrl, + contracts: [{ name: 'WagmiMintExample', address }], + }).contracts!(), + ).resolves.toMatchSnapshot() +}) + +test('fetches ABI with multichain deployment', async () => { + await expect( + blockExplorer({ + apiKey, + baseUrl, + contracts: [ + { name: 'WagmiMintExample', address: { 1: address, 10: address } }, + ], + }).contracts?.(), + ).resolves.toMatchSnapshot() +}) + +test('fails to fetch for unverified contract', async () => { + await expect( + blockExplorer({ + apiKey, + baseUrl, + contracts: [ + { name: 'WagmiMintExample', address: unverifiedContractAddress }, + ], + }).contracts?.(), + ).rejects.toThrowErrorMatchingInlineSnapshot( + '[Error: Contract source code not verified]', + ) +}) diff --git a/wagmi-project/packages/cli/src/plugins/blockExplorer.ts b/wagmi-project/packages/cli/src/plugins/blockExplorer.ts new file mode 100644 index 0000000000..2518b6e936 --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/blockExplorer.ts @@ -0,0 +1,107 @@ +import { camelCase } from 'change-case' +import type { Address } from 'viem' +import { z } from 'zod' + +import type { ContractConfig } from '../config.js' +import { fromZodError } from '../errors.js' +import type { Compute } from '../types.js' +import { fetch } from './fetch.js' + +export type BlockExplorerConfig = { + /** + * API key for block explorer. Appended to the request URL as query param `&apikey=${apiKey}`. + */ + apiKey?: string | undefined + /** + * Base URL for block explorer. + */ + baseUrl: string + /** + * Duration in milliseconds to cache ABIs. + * + * @default 1_800_000 // 30m in ms + */ + cacheDuration?: number | undefined + /** + * Chain ID for block explorer. Appended to the request URL as query param `&chainId=${chainId}`. + */ + chainId?: number | undefined + /** + * Contracts to fetch ABIs for. + */ + contracts: Compute>[] + /** + * Function to get address from contract config. + */ + getAddress?: + | ((config: { + address: NonNullable + }) => Address) + | undefined + /** + * Name of source. + */ + name?: ContractConfig['name'] | undefined +} + +const BlockExplorerResponse = z.discriminatedUnion('status', [ + z.object({ + status: z.literal('1'), + message: z.literal('OK'), + result: z + .string() + .transform((val) => JSON.parse(val) as ContractConfig['abi']), + }), + z.object({ + status: z.literal('0'), + message: z.literal('NOTOK'), + result: z.string(), + }), +]) + +/** + * Fetches contract ABIs from block explorers, supporting `?module=contract&action=getabi` requests. + */ +export function blockExplorer(config: BlockExplorerConfig) { + const { + apiKey, + baseUrl, + cacheDuration, + chainId, + contracts, + getAddress = ({ address }) => { + if (typeof address === 'string') return address + return Object.values(address)[0]! + }, + name = 'Block Explorer', + } = config + + return fetch({ + cacheDuration, + contracts, + name, + getCacheKey({ contract }) { + if (typeof contract.address === 'string') + return `${camelCase(name)}:${contract.address}` + return `${camelCase(name)}:${JSON.stringify(contract.address)}` + }, + async parse({ response }) { + const json = await response.json() + const parsed = await BlockExplorerResponse.safeParseAsync(json) + if (!parsed.success) + throw fromZodError(parsed.error, { prefix: 'Invalid response' }) + if (parsed.data.status === '0') throw new Error(parsed.data.result) + return parsed.data.result + }, + request({ address }) { + if (!address) throw new Error('address is required') + return { + url: `${baseUrl}?${chainId ? `chainId=${chainId}&` : ''}module=contract&action=getabi&address=${getAddress( + { + address, + }, + )}${apiKey ? `&apikey=${apiKey}` : ''}`, + } + }, + }) +} diff --git a/wagmi-project/packages/cli/src/plugins/etherscan.test.ts b/wagmi-project/packages/cli/src/plugins/etherscan.test.ts new file mode 100644 index 0000000000..dc496f4630 --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/etherscan.test.ts @@ -0,0 +1,112 @@ +import { mkdir, rm } from 'node:fs/promises' +import { setupServer } from 'msw/node' +import { afterAll, afterEach, beforeAll, expect, test } from 'vitest' + +import { + address, + apiKey, + handlers, + invalidApiKey, + proxyAddress, + timeoutAddress, + unverifiedContractAddress, +} from '../../test/utils.js' +import { etherscan } from './etherscan.js' +import { getCacheDir } from './fetch.js' + +const server = setupServer(...handlers) + +beforeAll(() => server.listen()) +afterEach(() => server.resetHandlers()) +afterAll(() => server.close()) + +test('fetches ABI', async () => { + await expect( + etherscan({ + apiKey, + chainId: 1, + contracts: [{ name: 'WagmiMintExample', address }], + }).contracts?.(), + ).resolves.toMatchSnapshot() +}) + +test('fetches ABI with multichain deployment', async () => { + await expect( + etherscan({ + apiKey, + chainId: 1, + contracts: [ + { name: 'WagmiMintExample', address: { 1: address, 10: address } }, + ], + }).contracts?.(), + ).resolves.toMatchSnapshot() +}) + +test('fails to fetch for unverified contract', async () => { + await expect( + etherscan({ + apiKey, + chainId: 1, + contracts: [ + { name: 'WagmiMintExample', address: unverifiedContractAddress }, + ], + }).contracts?.(), + ).rejects.toThrowErrorMatchingInlineSnapshot( + '[Error: Contract source code not verified]', + ) +}) + +test('missing address for chainId', async () => { + await expect( + etherscan({ + apiKey, + chainId: 1, + // @ts-expect-error `chainId` and `keyof typeof contracts[number].address` mismatch + contracts: [{ name: 'WagmiMintExample', address: { 10: address } }], + }).contracts?.(), + ).rejects.toThrowErrorMatchingInlineSnapshot( + `[Error: No address found for chainId "1". Make sure chainId "1" is set as an address.]`, + ) +}) + +test('invalid api key', async () => { + await expect( + etherscan({ + apiKey: invalidApiKey, + chainId: 1, + contracts: [{ name: 'WagmiMintExample', address: timeoutAddress }], + }).contracts?.(), + ).rejects.toThrowErrorMatchingInlineSnapshot('[Error: Invalid API Key]') +}) + +test('tryFetchProxyImplementation: fetches ABI', async () => { + const cacheDir = getCacheDir() + await mkdir(cacheDir, { recursive: true }) + + await expect( + etherscan({ + apiKey, + chainId: 1, + contracts: [{ name: 'WagmiMintExample', address }], + tryFetchProxyImplementation: true, + }).contracts?.(), + ).resolves.toMatchSnapshot() + + await rm(cacheDir, { recursive: true }) +}) + +test('tryFetchProxyImplementation: fetches implementation ABI', async () => { + const cacheDir = getCacheDir() + await mkdir(cacheDir, { recursive: true }) + + await expect( + etherscan({ + apiKey, + chainId: 1, + contracts: [{ name: 'FiatToken', address: proxyAddress }], + tryFetchProxyImplementation: true, + }).contracts?.(), + ).resolves.toMatchSnapshot() + + await rm(cacheDir, { recursive: true }) +}) diff --git a/wagmi-project/packages/cli/src/plugins/etherscan.ts b/wagmi-project/packages/cli/src/plugins/etherscan.ts new file mode 100644 index 0000000000..fda375c240 --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/etherscan.ts @@ -0,0 +1,268 @@ +import { mkdir, writeFile } from 'node:fs/promises' +import { Address as AddressSchema } from 'abitype/zod' +import { camelCase } from 'change-case' +import { join } from 'pathe' +import type { Abi, Address } from 'viem' +import { z } from 'zod' + +import type { ContractConfig } from '../config.js' +import { fromZodError } from '../errors.js' +import type { Compute } from '../types.js' +import { fetch, getCacheDir } from './fetch.js' + +export type EtherscanConfig = { + /** + * Etherscan API key. + * + * Create or manage keys at https://etherscan.io/myapikey + */ + apiKey: string + /** + * Duration in milliseconds to cache ABIs. + * + * @default 1_800_000 // 30m in ms + */ + cacheDuration?: number | undefined + /** + * Chain ID to use for fetching ABI. + * + * If `address` is an object, `chainId` is used to select the address. + * + * View supported chains on the [Etherscan docs](https://docs.etherscan.io/etherscan-v2/getting-started/supported-chains). + */ + chainId: (chainId extends ChainId ? chainId : never) | (ChainId & {}) + /** + * Contracts to fetch ABIs for. + */ + contracts: Compute, 'abi'>>[] + /** + * Whether to try fetching proxy implementation address of the contract + * + * @default false + */ + tryFetchProxyImplementation?: boolean | undefined +} + +/** + * Fetches contract ABIs from Etherscan. + */ +export function etherscan( + config: EtherscanConfig, +) { + const { + apiKey, + cacheDuration = 1_800_000, + chainId, + tryFetchProxyImplementation = false, + } = config + + const contracts = config.contracts.map((x) => ({ + ...x, + address: + typeof x.address === 'string' ? { [chainId]: x.address } : x.address, + })) as Omit[] + + const name = 'Etherscan' + + const getCacheKey: Parameters[0]['getCacheKey'] = ({ + contract, + }) => { + if (typeof contract.address === 'string') + return `${camelCase(name)}:${contract.address}` + return `${camelCase(name)}:${JSON.stringify(contract.address)}` + } + + return fetch({ + cacheDuration, + contracts, + name, + getCacheKey, + async parse({ response }) { + const json = await response.json() + const parsed = await GetAbiResponse.safeParseAsync(json) + if (!parsed.success) + throw fromZodError(parsed.error, { prefix: 'Invalid response' }) + if (parsed.data.status === '0') throw new Error(parsed.data.result) + return parsed.data.result + }, + async request(contract) { + if (!contract.address) throw new Error('address is required') + + const resolvedAddress = (() => { + if (!contract.address) throw new Error('address is required') + if (typeof contract.address === 'string') return contract.address + const contractAddress = contract.address[chainId] + if (!contractAddress) + throw new Error( + `No address found for chainId "${chainId}". Make sure chainId "${chainId}" is set as an address.`, + ) + return contractAddress + })() + + const options = { + address: resolvedAddress, + apiKey, + chainId, + } + + let abi: Abi | undefined + const implementationAddress = await (async () => { + if (!tryFetchProxyImplementation) return + const json = await globalThis + .fetch(buildUrl({ ...options, action: 'getsourcecode' })) + .then((res) => res.json()) + const parsed = await GetSourceCodeResponse.safeParseAsync(json) + if (!parsed.success) + throw fromZodError(parsed.error, { prefix: 'Invalid response' }) + if (parsed.data.status === '0') throw new Error(parsed.data.result) + if (!parsed.data.result[0]) return + abi = parsed.data.result[0].ABI + return parsed.data.result[0].Implementation as Address + })() + + if (abi) { + const cacheDir = getCacheDir() + await mkdir(cacheDir, { recursive: true }) + const cacheKey = getCacheKey({ contract }) + const cacheFilePath = join(cacheDir, `${cacheKey}.json`) + await writeFile( + cacheFilePath, + `${JSON.stringify({ abi, timestamp: Date.now() + cacheDuration }, undefined, 2)}\n`, + ) + } + + return { + url: buildUrl({ + ...options, + action: 'getabi', + address: implementationAddress || resolvedAddress, + }), + } + }, + }) +} + +function buildUrl(options: { + action: 'getabi' | 'getsourcecode' + address: Address + apiKey: string + chainId: ChainId | undefined +}) { + const baseUrl = 'https://api.etherscan.io/v2/api' + const { action, address, apiKey, chainId } = options + return `${baseUrl}?${chainId ? `chainId=${chainId}&` : ''}module=contract&action=${action}&address=${address}${apiKey ? `&apikey=${apiKey}` : ''}` +} + +const GetAbiResponse = z.discriminatedUnion('status', [ + z.object({ + status: z.literal('1'), + message: z.literal('OK'), + result: z.string().transform((val) => JSON.parse(val) as Abi), + }), + z.object({ + status: z.literal('0'), + message: z.literal('NOTOK'), + result: z.string(), + }), +]) + +const GetSourceCodeResponse = z.discriminatedUnion('status', [ + z.object({ + status: z.literal('1'), + message: z.literal('OK'), + result: z.array( + z.discriminatedUnion('Proxy', [ + z.object({ + ABI: z.string().transform((val) => JSON.parse(val) as Abi), + Implementation: AddressSchema, + Proxy: z.literal('1'), + }), + z.object({ + ABI: z.string().transform((val) => JSON.parse(val) as Abi), + Implementation: z.string(), + Proxy: z.literal('0'), + }), + ]), + ), + }), + z.object({ + status: z.literal('0'), + message: z.literal('NOTOK'), + result: z.string(), + }), +]) + +// Supported chains +// https://docs.etherscan.io/etherscan-v2/getting-started/supported-chains +type ChainId = + | 1 // Ethereum Mainnet + | 11155111 // Sepolia Testnet + | 17000 // Holesky Testnet + | 560048 // Hoodi Testnet + | 56 // BNB Smart Chain Mainnet + | 97 // BNB Smart Chain Testnet + | 137 // Polygon Mainnet + | 80002 // Polygon Amoy Testnet + | 1101 // Polygon zkEVM Mainnet + | 2442 // Polygon zkEVM Cardona Testnet + | 8453 // Base Mainnet + | 84532 // Base Sepolia Testnet + | 42161 // Arbitrum One Mainnet + | 42170 // Arbitrum Nova Mainnet + | 421614 // Arbitrum Sepolia Testnet + | 59144 // Linea Mainnet + | 59141 // Linea Sepolia Testnet + | 250 // Fantom Opera Mainnet + | 4002 // Fantom Testnet + | 81457 // Blast Mainnet + | 168587773 // Blast Sepolia Testnet + | 10 // OP Mainnet + | 11155420 // OP Sepolia Testnet + | 43114 // Avalanche C-Chain + | 43113 // Avalanche Fuji Testnet + | 199 // BitTorrent Chain Mainnet + | 1028 // BitTorrent Chain Testnet + | 42220 // Celo Mainnet + | 44787 // Celo Alfajores Testnet + | 25 // Cronos Mainnet + | 252 // Fraxtal Mainnet + | 2522 // Fraxtal Testnet + | 100 // Gnosis + | 255 // Kroma Mainnet + | 2358 // Kroma Sepolia Testnet + | 5000 // Mantle Mainnet + | 5003 // Mantle Sepolia Testnet + | 1284 // Moonbeam Mainnet + | 1285 // Moonriver Mainnet + | 1287 // Moonbase Alpha Testnet + | 204 // opBNB Mainnet + | 5611 // opBNB Testnet + | 534352 // Scroll Mainnet + | 534351 // Scroll Sepolia Testnet + | 167000 // Taiko Mainnet + | 167009 // Taiko Hekla L2 Testnet + | 1111 // WEMIX3.0 Mainnet + | 1112 // WEMIX3.0 Testnet + | 324 // zkSync Mainnet + | 300 // zkSync Sepolia Testnet + | 660279 // Xai Mainnet + | 37714555429 // Xai Sepolia Testnet + | 50 // XDC Mainnet + | 51 // XDC Apothem Testnet + | 33139 // ApeChain Mainnet + | 33111 // ApeChain Curtis Testnet + | 480 // World Mainnet + | 4801 // World Sepolia Testnet + | 50104 // Sophon Mainnet + | 531050104 // Sophon Sepolia Testnet + | 146 // Sonic Mainnet + | 57054 // Sonic Blaze Testnet + | 130 // Unichain Mainnet + | 1301 // Unichain Sepolia Testnet + | 2741 // Abstract Mainnet + | 11124 // Abstract Sepolia Testnet + | 80094 // Berachain Mainnet + | 80069 // Berachain Bepolia Testnet + | 1923 // Swellchain Mainnet + | 1924 // Swellchain Testnet + | 10143 // Monad Testnet diff --git a/wagmi-project/packages/cli/src/plugins/fetch.test.ts b/wagmi-project/packages/cli/src/plugins/fetch.test.ts new file mode 100644 index 0000000000..600cbfeda7 --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/fetch.test.ts @@ -0,0 +1,186 @@ +import { mkdir, rm, writeFile } from 'node:fs/promises' +import { homedir } from 'node:os' +import { setupServer } from 'msw/node' +import { afterAll, afterEach, beforeAll, expect, test } from 'vitest' + +import { + address, + apiKey, + baseUrl, + handlers, + timeoutAddress, + unverifiedContractAddress, +} from '../../test/utils.js' +import { fetch, getCacheDir } from './fetch.js' + +const server = setupServer(...handlers) + +beforeAll(() => server.listen()) +afterEach(() => server.resetHandlers()) +afterAll(() => server.close()) + +type Fetch = Parameters[0] +const request: Fetch['request'] = ({ address }) => { + return { + url: `${baseUrl}?module=contract&action=getabi&address=${address}&apikey=${apiKey}`, + } +} +const parse: Fetch['parse'] = async ({ response }) => { + const data = (await response.json()) as + | { status: '1'; message: 'OK'; result: string } + | { status: '0'; message: 'NOTOK'; result: string } + if (data.status === '0') throw new Error(data.result) + return JSON.parse(data.result) +} + +test('fetches ABI', async () => { + await expect( + fetch({ + contracts: [{ name: 'WagmiMintExample', address }], + request, + parse, + }).contracts?.(), + ).resolves.toMatchSnapshot() +}) + +test('fails to fetch for unverified contract', async () => { + await expect( + fetch({ + contracts: [ + { name: 'WagmiMintExample', address: unverifiedContractAddress }, + ], + request, + parse, + }).contracts?.(), + ).rejects.toThrowErrorMatchingInlineSnapshot( + '[Error: Contract source code not verified]', + ) +}) + +test('aborts request', async () => { + await expect( + fetch({ + contracts: [{ name: 'WagmiMintExample', address: timeoutAddress }], + request, + parse, + timeoutDuration: 1_000, + }).contracts?.(), + ).rejects.toThrowErrorMatchingInlineSnapshot( + '[AbortError: This operation was aborted]', + ) +}) + +test('reads from cache', async () => { + const cacheDir = `${homedir}/.wagmi-cli/plugins/fetch/cache` + await mkdir(cacheDir, { recursive: true }) + + const contract = { + name: 'WagmiMintExample', + address: timeoutAddress, + } as const + const cacheKey = JSON.stringify(contract) + const cacheFilePath = `${cacheDir}/${cacheKey}.json` + await writeFile( + cacheFilePath, + JSON.stringify( + { + abi: [ + { + inputs: [], + name: 'mint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + ], + timestamp: Date.now() + 30_000, + }, + null, + 2, + ), + ) + + await expect( + fetch({ + contracts: [contract], + request, + parse, + }).contracts?.(), + ).resolves.toMatchInlineSnapshot(` + [ + { + "abi": [ + { + "inputs": [], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "address": "0xecb504d39723b0be0e3a9aa33d646642d1051ee1", + "name": "WagmiMintExample", + }, + ] + `) + + await rm(cacheDir, { recursive: true }) +}) + +test('fails and reads from cache', async () => { + const cacheDir = getCacheDir() + await mkdir(cacheDir, { recursive: true }) + + const contract = { + name: 'WagmiMintExample', + address: timeoutAddress, + } as const + const cacheKey = JSON.stringify(contract) + const cacheFilePath = `${cacheDir}/${cacheKey}.json` + await writeFile( + cacheFilePath, + JSON.stringify( + { + abi: [ + { + inputs: [], + name: 'mint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + ], + timestamp: Date.now() - 30_000, + }, + null, + 2, + ), + ) + + await expect( + fetch({ + contracts: [contract], + request, + parse, + timeoutDuration: 1, + }).contracts?.(), + ).resolves.toMatchInlineSnapshot(` + [ + { + "abi": [ + { + "inputs": [], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "address": "0xecb504d39723b0be0e3a9aa33d646642d1051ee1", + "name": "WagmiMintExample", + }, + ] + `) + + await rm(cacheDir, { recursive: true }) +}) diff --git a/wagmi-project/packages/cli/src/plugins/fetch.ts b/wagmi-project/packages/cli/src/plugins/fetch.ts new file mode 100644 index 0000000000..778d4a8162 --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/fetch.ts @@ -0,0 +1,127 @@ +import { mkdir, readFile, writeFile } from 'node:fs/promises' +import { homedir } from 'node:os' +import { join } from 'pathe' + +import type { Abi } from 'viem' +import type { ContractConfig, Plugin } from '../config.js' +import type { Compute, RequiredBy } from '../types.js' + +export type FetchConfig = { + /** + * Duration in milliseconds to cache ABIs from request. + * + * @default 1_800_000 // 30m in ms + */ + cacheDuration?: number | undefined + /** + * Contracts to fetch ABIs for. + */ + contracts: Compute>[] + /** + * Function for creating a cache key for contract. + */ + getCacheKey?: + | ((config: { contract: Compute> }) => string) + | undefined + /** + * Name of source. + */ + name?: ContractConfig['name'] | undefined + /** + * Function for parsing ABI from fetch response. + * + * @default ({ response }) => response.json() + */ + parse?: + | ((config: { + response: Response + }) => ContractConfig['abi'] | Promise) + | undefined + /** + * Function for returning a request to fetch ABI from. + */ + request: (config: { + address?: ContractConfig['address'] | undefined + name: ContractConfig['name'] + }) => + | { url: RequestInfo; init?: RequestInit | undefined } + | Promise<{ url: RequestInfo; init?: RequestInit | undefined }> + /** + * Duration in milliseconds before request times out. + * + * @default 5_000 // 5s in ms + */ + timeoutDuration?: number | undefined +} + +type FetchResult = Compute> + +/** Fetches and parses contract ABIs from network resource with `fetch`. */ +export function fetch(config: FetchConfig): FetchResult { + const { + cacheDuration = 1_800_000, + contracts: contractConfigs, + getCacheKey = ({ contract }) => JSON.stringify(contract), + name = 'Fetch', + parse = ({ response }) => response.json(), + request, + timeoutDuration = 5_000, + } = config + + return { + async contracts() { + const cacheDir = getCacheDir() + await mkdir(cacheDir, { recursive: true }) + + const timestamp = Date.now() + cacheDuration + const contracts = [] + for (const contract of contractConfigs) { + const cacheKey = getCacheKey({ contract }) + const cacheFilePath = join(cacheDir, `${cacheKey}.json`) + const cachedFile = JSON.parse( + await readFile(cacheFilePath, 'utf8').catch(() => 'null'), + ) + + let abi: Abi | undefined + if (cachedFile?.timestamp > Date.now()) abi = cachedFile.abi + else { + try { + const controller = new globalThis.AbortController() + const timeout = setTimeout( + () => controller.abort(), + timeoutDuration, + ) + + const { url, init } = await request(contract) + const response = await globalThis.fetch(url, { + ...init, + signal: controller.signal, + }) + clearTimeout(timeout) + + abi = await parse({ response }) + await writeFile( + cacheFilePath, + `${JSON.stringify({ abi, timestamp }, undefined, 2)}\n`, + ) + } catch (error) { + try { + // Attempt to read from cache if fetch fails. + abi = JSON.parse(await readFile(cacheFilePath, 'utf8')).abi + } catch {} + if (!abi) throw error + } + } + + if (!abi) throw Error('Failed to fetch ABI for contract.') + contracts.push({ abi, address: contract.address, name: contract.name }) + } + return contracts + }, + name, + } +} + +export function getCacheDir() { + return join(homedir(), '.wagmi-cli/plugins/fetch/cache') +} diff --git a/wagmi-project/packages/cli/src/plugins/foundry.test.ts b/wagmi-project/packages/cli/src/plugins/foundry.test.ts new file mode 100644 index 0000000000..75e5ec73ee --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/foundry.test.ts @@ -0,0 +1,153 @@ +import fixtures from 'fixturez' +import { dirname, resolve } from 'pathe' +import { afterEach, expect, test, vi } from 'vitest' + +import { foundry } from './foundry.js' + +const f = fixtures(__dirname) + +afterEach(() => { + vi.restoreAllMocks() +}) + +test('forge not installed', async () => { + const dir = f.temp() + expect( + foundry({ + project: dir, + forge: { + path: '/path/to/forge', + }, + }).validate?.(), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [Error: forge must be installed to use Foundry plugin. + To install, follow the instructions at https://book.getfoundry.sh/getting-started/installation] + `) +}) + +test('project does not exist', async () => { + const dir = f.temp() + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + try { + await foundry({ project: '../path/to/project' }).validate?.() + } catch (error) { + expect( + (error as Error).message.replace(dirname(dir), '..'), + ).toMatchInlineSnapshot('"Foundry project ../path/to/project not found."') + } +}) + +test('validates without project', async () => { + const dir = resolve(__dirname, '__fixtures__/foundry/') + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await expect(foundry().validate?.()).resolves.toBeUndefined() +}) + +test('contracts', async () => { + await expect( + foundry({ + project: resolve(__dirname, '__fixtures__/foundry/'), + exclude: ['Foo.sol/**'], + }).contracts?.(), + ).resolves.toMatchInlineSnapshot(` + [ + { + "abi": [ + { + "inputs": [], + "name": "increment", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [], + "name": "number", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newNumber", + "type": "uint256", + }, + ], + "name": "setNumber", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "address": undefined, + "name": "Counter", + }, + ] + `) +}) + +test('contracts without project', async () => { + const dir = resolve(__dirname, '__fixtures__/foundry/') + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await expect( + foundry({ + exclude: ['Foo.sol/**'], + }).contracts?.(), + ).resolves.toMatchInlineSnapshot(` + [ + { + "abi": [ + { + "inputs": [], + "name": "increment", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [], + "name": "number", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newNumber", + "type": "uint256", + }, + ], + "name": "setNumber", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "address": undefined, + "name": "Counter", + }, + ] + `) +}) diff --git a/wagmi-project/packages/cli/src/plugins/foundry.ts b/wagmi-project/packages/cli/src/plugins/foundry.ts new file mode 100644 index 0000000000..eae6bf9838 --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/foundry.ts @@ -0,0 +1,263 @@ +import { execSync, spawn, spawnSync } from 'node:child_process' +import { existsSync } from 'node:fs' +import { readFile } from 'node:fs/promises' +import dedent from 'dedent' +import { fdir } from 'fdir' +import { basename, extname, join, resolve } from 'pathe' +import pc from 'picocolors' +import { z } from 'zod' + +import type { ContractConfig, Plugin } from '../config.js' +import * as logger from '../logger.js' +import type { Compute, RequiredBy } from '../types.js' + +export const foundryDefaultExcludes = [ + 'Base.sol/**', + 'Common.sol/**', + 'Components.sol/**', + 'IERC165.sol/**', + 'IERC20.sol/**', + 'IERC721.sol/**', + 'IMulticall2.sol/**', + 'MockERC20.sol/**', + 'MockERC721.sol/**', + 'Script.sol/**', + 'StdAssertions.sol/**', + 'StdChains.sol/**', + 'StdCheats.sol/**', + 'StdError.sol/**', + 'StdInvariant.sol/**', + 'StdJson.sol/**', + 'StdMath.sol/**', + 'StdStorage.sol/**', + 'StdStyle.sol/**', + 'StdToml.sol/**', + 'StdUtils.sol/**', + 'Test.sol/**', + 'Vm.sol/**', + 'build-info/**', + 'console.sol/**', + 'console2.sol/**', + 'safeconsole.sol/**', + '**.s.sol/*.json', + '**.t.sol/*.json', +] + +export type FoundryConfig = { + /** + * Project's artifacts directory. + * + * Same as your project's `--out` (`-o`) option. + * + * @default foundry.config#out | 'out' + */ + artifacts?: string | undefined + /** Mapping of addresses to attach to artifacts. */ + deployments?: { [key: string]: ContractConfig['address'] } | undefined + /** Artifact files to exclude. */ + exclude?: string[] | undefined + /** [Forge](https://book.getfoundry.sh/forge) configuration */ + forge?: + | { + /** + * Remove build artifacts and cache directories on start up. + * + * @default false + */ + clean?: boolean | undefined + /** + * Build Foundry project before fetching artifacts. + * + * @default true + */ + build?: boolean | undefined + /** + * Path to `forge` executable command + * + * @default "forge" + */ + path?: string | undefined + /** + * Rebuild every time a watched file or directory is changed. + * + * @default true + */ + rebuild?: boolean | undefined + } + | undefined + /** Artifact files to include. */ + include?: string[] | undefined + /** Optional prefix to prepend to artifact names. */ + namePrefix?: string | undefined + /** Path to foundry project. */ + project?: string | undefined +} + +type FoundryResult = Compute< + RequiredBy +> + +const FoundryConfigSchema = z.object({ + out: z.string().default('out'), + src: z.string().default('src'), +}) + +/** Resolves ABIs from [Foundry](https://github.com/foundry-rs/foundry) project. */ +export function foundry(config: FoundryConfig = {}): FoundryResult { + const { + artifacts, + deployments = {}, + exclude = foundryDefaultExcludes, + forge: { + clean = false, + build = true, + path: forgeExecutable = 'forge', + rebuild = true, + } = {}, + include = ['*.json'], + namePrefix = '', + } = config + + function getContractName(artifactPath: string, usePrefix = true) { + const filename = basename(artifactPath) + const extension = extname(artifactPath) + return `${usePrefix ? namePrefix : ''}${filename.replace(extension, '')}` + } + + async function getContract(artifactPath: string) { + const artifact = await JSON.parse(await readFile(artifactPath, 'utf8')) + return { + abi: artifact.abi, + address: (deployments as Record)[ + getContractName(artifactPath, false) + ], + name: getContractName(artifactPath), + } + } + + function getArtifactPaths(artifactsDirectory: string) { + const crawler = new fdir().withBasePath().globWithOptions( + include.map((x) => `${artifactsDirectory}/**/${x}`), + { + dot: true, + ignore: exclude.map((x) => `${artifactsDirectory}/**/${x}`), + }, + ) + return crawler.crawl(artifactsDirectory).withPromise() + } + + const project = resolve(process.cwd(), config.project ?? '') + + let foundryConfig: z.infer = { + out: 'out', + src: 'src', + } + try { + const result = spawnSync( + forgeExecutable, + ['config', '--json', '--root', project], + { + encoding: 'utf-8', + shell: true, + }, + ) + if (result.error) throw result.error + if (result.status !== 0) + throw new Error(`Failed with code ${result.status}`) + if (result.signal) throw new Error('Process terminated by signal') + foundryConfig = FoundryConfigSchema.parse(JSON.parse(result.stdout)) + } catch { + } finally { + foundryConfig = { + ...foundryConfig, + out: artifacts ?? foundryConfig.out, + } + } + + const artifactsDirectory = join(project, foundryConfig.out) + + return { + async contracts() { + if (clean) + spawnSync(forgeExecutable, ['clean', '--root', project], { + encoding: 'utf-8', + stdio: 'pipe', + }) + if (build) + execSync(`${forgeExecutable} build --root ${project}`, { + encoding: 'utf-8', + stdio: 'pipe', + }) + if (!existsSync(artifactsDirectory)) + throw new Error('Artifacts not found.') + + const artifactPaths = await getArtifactPaths(artifactsDirectory) + const contracts = [] + for (const artifactPath of artifactPaths) { + const contract = await getContract(artifactPath) + if (!contract.abi?.length) continue + contracts.push(contract) + } + return contracts + }, + name: 'Foundry', + async validate() { + // Check that project directory exists + if (!existsSync(project)) + throw new Error(`Foundry project ${pc.gray(config.project)} not found.`) + + // Ensure forge is installed + if (clean || build || rebuild) + try { + execSync(`${forgeExecutable} --version`, { + encoding: 'utf-8', + stdio: 'pipe', + }) + } catch (_error) { + throw new Error(dedent` + forge must be installed to use Foundry plugin. + To install, follow the instructions at https://book.getfoundry.sh/getting-started/installation + `) + } + }, + watch: { + command: rebuild + ? async () => { + logger.log( + `${pc.magenta('Foundry')} Watching project at ${pc.gray( + project, + )}`, + ) + const subprocess = spawn(forgeExecutable, [ + 'build', + '--watch', + '--root', + project, + ]) + subprocess.stdout?.on('data', (data) => { + process.stdout.write(`${pc.magenta('Foundry')} ${data}`) + }) + + process.once('SIGINT', shutdown) + process.once('SIGTERM', shutdown) + function shutdown() { + subprocess?.kill() + } + } + : undefined, + paths: [ + ...include.map((x) => `${artifactsDirectory}/**/${x}`), + ...exclude.map((x) => `!${artifactsDirectory}/**/${x}`), + ], + async onAdd(path) { + return getContract(path) + }, + async onChange(path) { + return getContract(path) + }, + async onRemove(path) { + return getContractName(path) + }, + }, + } +} diff --git a/wagmi-project/packages/cli/src/plugins/hardhat.test.ts b/wagmi-project/packages/cli/src/plugins/hardhat.test.ts new file mode 100644 index 0000000000..efb416c5e6 --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/hardhat.test.ts @@ -0,0 +1,85 @@ +import fixtures from 'fixturez' +import { dirname, resolve } from 'pathe' +import { afterEach, expect, test, vi } from 'vitest' + +import { hardhat } from './hardhat.js' + +const f = fixtures(__dirname) + +afterEach(() => { + vi.restoreAllMocks() +}) + +test('validate', async () => { + const temp = f.temp() + expect( + hardhat({ project: temp }).validate?.(), + ).rejects.toThrowErrorMatchingInlineSnapshot( + '[Error: hardhat must be installed to use Hardhat plugin.]', + ) +}) + +test('project does not exist', async () => { + const dir = f.temp() + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + try { + await hardhat({ project: '../path/to/project' }).validate?.() + } catch (error) { + expect( + (error as Error).message.replace(dirname(dir), '..'), + ).toMatchInlineSnapshot('"Hardhat project ../path/to/project not found."') + } +}) + +test('contracts', async () => { + expect( + hardhat({ + project: resolve(__dirname, '__fixtures__/hardhat/'), + exclude: ['Foo.sol/**'], + }).contracts?.(), + ).resolves.toMatchInlineSnapshot(` + [ + { + "abi": [ + { + "inputs": [], + "name": "increment", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + { + "inputs": [], + "name": "number", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256", + }, + ], + "stateMutability": "view", + "type": "function", + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newNumber", + "type": "uint256", + }, + ], + "name": "setNumber", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "address": undefined, + "name": "Counter", + }, + ] + `) +}, 10_000) diff --git a/wagmi-project/packages/cli/src/plugins/hardhat.ts b/wagmi-project/packages/cli/src/plugins/hardhat.ts new file mode 100644 index 0000000000..a4feb6efdf --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/hardhat.ts @@ -0,0 +1,235 @@ +import { execSync, spawn } from 'node:child_process' +import { existsSync } from 'node:fs' +import { readFile } from 'node:fs/promises' +import { fdir } from 'fdir' +import { basename, extname, join, resolve } from 'pathe' +import pc from 'picocolors' + +import type { ContractConfig, Plugin } from '../config.js' +import * as logger from '../logger.js' +import type { Compute, RequiredBy } from '../types.js' +import { getIsPackageInstalled, getPackageManager } from '../utils/packages.js' + +export const hardhatDefaultExcludes = ['build-info/**', '*.dbg.json'] + +export type HardhatConfig = { + /** + * Project's artifacts directory. + * + * Same as your project's `artifacts` [path configuration](https://hardhat.org/hardhat-runner/docs/config#path-configuration) option. + * + * @default 'artifacts/' + */ + artifacts?: string | undefined + /** Mapping of addresses to attach to artifacts. */ + deployments?: { [key: string]: ContractConfig['address'] } | undefined + /** Artifact files to exclude. */ + exclude?: string[] | undefined + /** Commands to run */ + commands?: + | { + /** + * Remove build artifacts and cache directories on start up. + * + * @default `${packageManger} hardhat clean` + */ + clean?: string | boolean | undefined + /** + * Build Hardhat project before fetching artifacts. + * + * @default `${packageManger} hardhat compile` + */ + build?: string | boolean | undefined + /** + * Command to run when watched file or directory is changed. + * + * @default `${packageManger} hardhat compile` + */ + rebuild?: string | boolean | undefined + } + | undefined + /** Artifact files to include. */ + include?: string[] | undefined + /** Optional prefix to prepend to artifact names. */ + namePrefix?: string | undefined + /** Path to Hardhat project. */ + project: string + /** + * Project's artifacts directory. + * + * Same as your project's `sources` [path configuration](https://hardhat.org/hardhat-runner/docs/config#path-configuration) option. + * + * @default 'contracts/' + */ + sources?: string | undefined +} + +type HardhatResult = Compute< + RequiredBy +> + +/** Resolves ABIs from [Hardhat](https://github.com/NomicFoundation/hardhat) project. */ +export function hardhat(config: HardhatConfig): HardhatResult { + const { + artifacts = 'artifacts', + deployments = {}, + exclude = hardhatDefaultExcludes, + commands = {}, + include = ['*.json'], + namePrefix = '', + sources = 'contracts', + } = config + + function getContractName(artifact: { contractName: string }) { + return `${namePrefix}${artifact.contractName}` + } + + async function getContract(artifactPath: string) { + const artifact = await JSON.parse(await readFile(artifactPath, 'utf8')) + return { + abi: artifact.abi, + address: deployments[artifact.contractName], + name: getContractName(artifact), + } + } + + function getArtifactPaths(artifactsDirectory: string) { + const crawler = new fdir().withBasePath().globWithOptions( + include.map((x) => `${artifactsDirectory}/**/${x}`), + { + dot: true, + ignore: exclude.map((x) => `${artifactsDirectory}/**/${x}`), + }, + ) + return crawler.crawl(artifactsDirectory).withPromise() + } + + const project = resolve(process.cwd(), config.project) + const artifactsDirectory = join(project, artifacts) + const sourcesDirectory = join(project, sources) + + const { build = true, clean = false, rebuild = true } = commands + return { + async contracts() { + if (clean) { + const packageManager = await getPackageManager(true) + const [command, ...options] = ( + typeof clean === 'boolean' ? `${packageManager} hardhat clean` : clean + ).split(' ') + execSync(`${command!} ${options.join(' ')}`, { + cwd: project, + encoding: 'utf-8', + stdio: 'pipe', + }) + } + if (build) { + const packageManager = await getPackageManager(true) + const [command, ...options] = ( + typeof build === 'boolean' + ? `${packageManager} hardhat compile` + : build + ).split(' ') + execSync(`${command!} ${options.join(' ')}`, { + cwd: project, + encoding: 'utf-8', + stdio: 'pipe', + }) + } + if (!existsSync(artifactsDirectory)) + throw new Error('Artifacts not found.') + + const artifactPaths = await getArtifactPaths(artifactsDirectory) + const contracts = [] + for (const artifactPath of artifactPaths) { + const contract = await getContract(artifactPath) + if (!contract.abi?.length) continue + contracts.push(contract) + } + return contracts + }, + name: 'Hardhat', + async validate() { + // Check that project directory exists + if (!existsSync(project)) + throw new Error(`Hardhat project ${pc.gray(project)} not found.`) + + // Check that `hardhat` is installed + const packageName = 'hardhat' + const isPackageInstalled = await getIsPackageInstalled({ + packageName, + cwd: project, + }) + if (isPackageInstalled) return + throw new Error(`${packageName} must be installed to use Hardhat plugin.`) + }, + watch: { + command: rebuild + ? async () => { + logger.log( + `${pc.blue('Hardhat')} Watching project at ${pc.gray(project)}`, + ) + + const [command, ...options] = ( + typeof rebuild === 'boolean' + ? `${await getPackageManager(true)} hardhat compile` + : rebuild + ).split(' ') + + const { watch } = await import('chokidar') + const watcher = watch(sourcesDirectory, { + atomic: true, + awaitWriteFinish: true, + ignoreInitial: true, + persistent: true, + }) + watcher.on('all', async (event, path) => { + if (event !== 'change' && event !== 'add' && event !== 'unlink') + return + logger.log( + `${pc.blue('Hardhat')} Detected ${event} at ${basename(path)}`, + ) + const subprocess = spawn(command!, options, { + cwd: project, + }) + subprocess.stdout?.on('data', (data) => { + process.stdout.write(`${pc.blue('Hardhat')} ${data}`) + }) + }) + + process.once('SIGINT', shutdown) + process.once('SIGTERM', shutdown) + async function shutdown() { + await watcher.close() + } + } + : undefined, + paths: [ + artifactsDirectory, + ...include.map((x) => `${artifactsDirectory}/**/${x}`), + ...exclude.map((x) => `!${artifactsDirectory}/**/${x}`), + ], + async onAdd(path) { + return getContract(path) + }, + async onChange(path) { + return getContract(path) + }, + async onRemove(path) { + const filename = basename(path) + const extension = extname(path) + // Since we can't use `getContractName`, guess from path + const removedContractName = `${namePrefix}${filename.replace( + extension, + '', + )}` + const artifactPaths = await getArtifactPaths(artifactsDirectory) + for (const artifactPath of artifactPaths) { + const contract = await getContract(artifactPath) + // If contract with same name exists, don't remove + if (contract.name === removedContractName) return + } + return removedContractName + }, + }, + } +} diff --git a/wagmi-project/packages/cli/src/plugins/react.test.ts b/wagmi-project/packages/cli/src/plugins/react.test.ts new file mode 100644 index 0000000000..939a5299ae --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/react.test.ts @@ -0,0 +1,337 @@ +import { erc20Abi } from 'viem' +import { expect, test } from 'vitest' + +import { react } from './react.js' + +test('default', async () => { + const result = await react().run?.({ + contracts: [ + { + name: 'erc20', + abi: erc20Abi, + content: '', + meta: { + abiName: 'erc20Abi', + }, + }, + ], + isTypeScript: true, + outputs: [], + }) + + expect(result?.imports).toMatchInlineSnapshot(` + "import { createUseReadContract, createUseWriteContract, createUseSimulateContract, createUseWatchContractEvent } from 'wagmi/codegen' + " + `) + expect(result?.content).toMatchInlineSnapshot(` + "/** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const useReadErc20 = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi }) + + /** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"allowance"\` + */ + export const useReadErc20Allowance = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, functionName: 'allowance' }) + + /** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"balanceOf"\` + */ + export const useReadErc20BalanceOf = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, functionName: 'balanceOf' }) + + /** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"decimals"\` + */ + export const useReadErc20Decimals = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, functionName: 'decimals' }) + + /** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"name"\` + */ + export const useReadErc20Name = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, functionName: 'name' }) + + /** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"symbol"\` + */ + export const useReadErc20Symbol = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, functionName: 'symbol' }) + + /** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"totalSupply"\` + */ + export const useReadErc20TotalSupply = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, functionName: 'totalSupply' }) + + /** + * Wraps __{@link useWriteContract}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const useWriteErc20 = /*#__PURE__*/ createUseWriteContract({ abi: erc20Abi }) + + /** + * Wraps __{@link useWriteContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"approve"\` + */ + export const useWriteErc20Approve = /*#__PURE__*/ createUseWriteContract({ abi: erc20Abi, functionName: 'approve' }) + + /** + * Wraps __{@link useWriteContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transfer"\` + */ + export const useWriteErc20Transfer = /*#__PURE__*/ createUseWriteContract({ abi: erc20Abi, functionName: 'transfer' }) + + /** + * Wraps __{@link useWriteContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transferFrom"\` + */ + export const useWriteErc20TransferFrom = /*#__PURE__*/ createUseWriteContract({ abi: erc20Abi, functionName: 'transferFrom' }) + + /** + * Wraps __{@link useSimulateContract}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const useSimulateErc20 = /*#__PURE__*/ createUseSimulateContract({ abi: erc20Abi }) + + /** + * Wraps __{@link useSimulateContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"approve"\` + */ + export const useSimulateErc20Approve = /*#__PURE__*/ createUseSimulateContract({ abi: erc20Abi, functionName: 'approve' }) + + /** + * Wraps __{@link useSimulateContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transfer"\` + */ + export const useSimulateErc20Transfer = /*#__PURE__*/ createUseSimulateContract({ abi: erc20Abi, functionName: 'transfer' }) + + /** + * Wraps __{@link useSimulateContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transferFrom"\` + */ + export const useSimulateErc20TransferFrom = /*#__PURE__*/ createUseSimulateContract({ abi: erc20Abi, functionName: 'transferFrom' }) + + /** + * Wraps __{@link useWatchContractEvent}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const useWatchErc20Event = /*#__PURE__*/ createUseWatchContractEvent({ abi: erc20Abi }) + + /** + * Wraps __{@link useWatchContractEvent}__ with \`abi\` set to __{@link erc20Abi}__ and \`eventName\` set to \`"Approval"\` + */ + export const useWatchErc20ApprovalEvent = /*#__PURE__*/ createUseWatchContractEvent({ abi: erc20Abi, eventName: 'Approval' }) + + /** + * Wraps __{@link useWatchContractEvent}__ with \`abi\` set to __{@link erc20Abi}__ and \`eventName\` set to \`"Transfer"\` + */ + export const useWatchErc20TransferEvent = /*#__PURE__*/ createUseWatchContractEvent({ abi: erc20Abi, eventName: 'Transfer' })" + `) +}) + +test('address', async () => { + const result = await react().run?.({ + contracts: [ + { + name: 'erc20', + abi: erc20Abi, + content: '', + meta: { + abiName: 'erc20Abi', + addressName: 'erc20Address', + }, + }, + ], + isTypeScript: true, + outputs: [], + }) + + expect(result?.content).toMatchInlineSnapshot(` + "/** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const useReadErc20 = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, address: erc20Address }) + + /** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"allowance"\` + */ + export const useReadErc20Allowance = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'allowance' }) + + /** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"balanceOf"\` + */ + export const useReadErc20BalanceOf = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'balanceOf' }) + + /** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"decimals"\` + */ + export const useReadErc20Decimals = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'decimals' }) + + /** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"name"\` + */ + export const useReadErc20Name = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'name' }) + + /** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"symbol"\` + */ + export const useReadErc20Symbol = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'symbol' }) + + /** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"totalSupply"\` + */ + export const useReadErc20TotalSupply = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'totalSupply' }) + + /** + * Wraps __{@link useWriteContract}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const useWriteErc20 = /*#__PURE__*/ createUseWriteContract({ abi: erc20Abi, address: erc20Address }) + + /** + * Wraps __{@link useWriteContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"approve"\` + */ + export const useWriteErc20Approve = /*#__PURE__*/ createUseWriteContract({ abi: erc20Abi, address: erc20Address, functionName: 'approve' }) + + /** + * Wraps __{@link useWriteContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transfer"\` + */ + export const useWriteErc20Transfer = /*#__PURE__*/ createUseWriteContract({ abi: erc20Abi, address: erc20Address, functionName: 'transfer' }) + + /** + * Wraps __{@link useWriteContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transferFrom"\` + */ + export const useWriteErc20TransferFrom = /*#__PURE__*/ createUseWriteContract({ abi: erc20Abi, address: erc20Address, functionName: 'transferFrom' }) + + /** + * Wraps __{@link useSimulateContract}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const useSimulateErc20 = /*#__PURE__*/ createUseSimulateContract({ abi: erc20Abi, address: erc20Address }) + + /** + * Wraps __{@link useSimulateContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"approve"\` + */ + export const useSimulateErc20Approve = /*#__PURE__*/ createUseSimulateContract({ abi: erc20Abi, address: erc20Address, functionName: 'approve' }) + + /** + * Wraps __{@link useSimulateContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transfer"\` + */ + export const useSimulateErc20Transfer = /*#__PURE__*/ createUseSimulateContract({ abi: erc20Abi, address: erc20Address, functionName: 'transfer' }) + + /** + * Wraps __{@link useSimulateContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transferFrom"\` + */ + export const useSimulateErc20TransferFrom = /*#__PURE__*/ createUseSimulateContract({ abi: erc20Abi, address: erc20Address, functionName: 'transferFrom' }) + + /** + * Wraps __{@link useWatchContractEvent}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const useWatchErc20Event = /*#__PURE__*/ createUseWatchContractEvent({ abi: erc20Abi, address: erc20Address }) + + /** + * Wraps __{@link useWatchContractEvent}__ with \`abi\` set to __{@link erc20Abi}__ and \`eventName\` set to \`"Approval"\` + */ + export const useWatchErc20ApprovalEvent = /*#__PURE__*/ createUseWatchContractEvent({ abi: erc20Abi, address: erc20Address, eventName: 'Approval' }) + + /** + * Wraps __{@link useWatchContractEvent}__ with \`abi\` set to __{@link erc20Abi}__ and \`eventName\` set to \`"Transfer"\` + */ + export const useWatchErc20TransferEvent = /*#__PURE__*/ createUseWatchContractEvent({ abi: erc20Abi, address: erc20Address, eventName: 'Transfer' })" + `) +}) + +test('legacy hook names', async () => { + const result = await react({ getHookName: 'legacy' }).run?.({ + contracts: [ + { + name: 'erc20', + abi: erc20Abi, + content: '', + meta: { + abiName: 'erc20Abi', + addressName: 'erc20Address', + }, + }, + ], + isTypeScript: true, + outputs: [], + }) + + expect(result?.content).toMatchInlineSnapshot(` + "/** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const useErc20Read = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, address: erc20Address }) + + /** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"allowance"\` + */ + export const useErc20Allowance = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'allowance' }) + + /** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"balanceOf"\` + */ + export const useErc20BalanceOf = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'balanceOf' }) + + /** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"decimals"\` + */ + export const useErc20Decimals = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'decimals' }) + + /** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"name"\` + */ + export const useErc20Name = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'name' }) + + /** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"symbol"\` + */ + export const useErc20Symbol = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'symbol' }) + + /** + * Wraps __{@link useReadContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"totalSupply"\` + */ + export const useErc20TotalSupply = /*#__PURE__*/ createUseReadContract({ abi: erc20Abi, address: erc20Address, functionName: 'totalSupply' }) + + /** + * Wraps __{@link useWriteContract}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const useErc20Write = /*#__PURE__*/ createUseWriteContract({ abi: erc20Abi, address: erc20Address }) + + /** + * Wraps __{@link useWriteContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"approve"\` + */ + export const useErc20Approve = /*#__PURE__*/ createUseWriteContract({ abi: erc20Abi, address: erc20Address, functionName: 'approve' }) + + /** + * Wraps __{@link useWriteContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transfer"\` + */ + export const useErc20Transfer = /*#__PURE__*/ createUseWriteContract({ abi: erc20Abi, address: erc20Address, functionName: 'transfer' }) + + /** + * Wraps __{@link useWriteContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transferFrom"\` + */ + export const useErc20TransferFrom = /*#__PURE__*/ createUseWriteContract({ abi: erc20Abi, address: erc20Address, functionName: 'transferFrom' }) + + /** + * Wraps __{@link useSimulateContract}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const usePrepareErc20Write = /*#__PURE__*/ createUseSimulateContract({ abi: erc20Abi, address: erc20Address }) + + /** + * Wraps __{@link useSimulateContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"approve"\` + */ + export const usePrepareErc20Approve = /*#__PURE__*/ createUseSimulateContract({ abi: erc20Abi, address: erc20Address, functionName: 'approve' }) + + /** + * Wraps __{@link useSimulateContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transfer"\` + */ + export const usePrepareErc20Transfer = /*#__PURE__*/ createUseSimulateContract({ abi: erc20Abi, address: erc20Address, functionName: 'transfer' }) + + /** + * Wraps __{@link useSimulateContract}__ with \`abi\` set to __{@link erc20Abi}__ and \`functionName\` set to \`"transferFrom"\` + */ + export const usePrepareErc20TransferFrom = /*#__PURE__*/ createUseSimulateContract({ abi: erc20Abi, address: erc20Address, functionName: 'transferFrom' }) + + /** + * Wraps __{@link useWatchContractEvent}__ with \`abi\` set to __{@link erc20Abi}__ + */ + export const useErc20Event = /*#__PURE__*/ createUseWatchContractEvent({ abi: erc20Abi, address: erc20Address }) + + /** + * Wraps __{@link useWatchContractEvent}__ with \`abi\` set to __{@link erc20Abi}__ and \`eventName\` set to \`"Approval"\` + */ + export const useErc20ApprovalEvent = /*#__PURE__*/ createUseWatchContractEvent({ abi: erc20Abi, address: erc20Address, eventName: 'Approval' }) + + /** + * Wraps __{@link useWatchContractEvent}__ with \`abi\` set to __{@link erc20Abi}__ and \`eventName\` set to \`"Transfer"\` + */ + export const useErc20TransferEvent = /*#__PURE__*/ createUseWatchContractEvent({ abi: erc20Abi, address: erc20Address, eventName: 'Transfer' })" + `) +}) diff --git a/wagmi-project/packages/cli/src/plugins/react.ts b/wagmi-project/packages/cli/src/plugins/react.ts new file mode 100644 index 0000000000..b76ea006a5 --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/react.ts @@ -0,0 +1,312 @@ +import { pascalCase } from 'change-case' + +import type { Contract, Plugin } from '../config.js' +import type { Compute, RequiredBy } from '../types.js' +import { getAddressDocString } from '../utils/getAddressDocString.js' + +export type ReactConfig = { + getHookName?: + | 'legacy' // TODO: Deprecate `'legacy'` option + | ((options: { + contractName: string + itemName?: string | undefined + type: 'read' | 'simulate' | 'watch' | 'write' + }) => `use${string}`) +} + +type ReactResult = Compute> + +export function react(config: ReactConfig = {}): ReactResult { + return { + name: 'React', + async run({ contracts }) { + const imports = new Set([]) + const content: string[] = [] + const pure = '/*#__PURE__*/' + + const hookNames = new Set() + for (const contract of contracts) { + let hasReadFunction = false + let hasWriteFunction = false + let hasEvent = false + const readItems = [] + const writeItems = [] + const eventItems = [] + for (const item of contract.abi) { + if (item.type === 'function') + if ( + item.stateMutability === 'view' || + item.stateMutability === 'pure' + ) { + hasReadFunction = true + readItems.push(item) + } else { + hasWriteFunction = true + writeItems.push(item) + } + else if (item.type === 'event') { + hasEvent = true + eventItems.push(item) + } + } + + let innerContent: string + if (contract.meta.addressName) + innerContent = `abi: ${contract.meta.abiName}, address: ${contract.meta.addressName}` + else innerContent = `abi: ${contract.meta.abiName}` + + if (hasReadFunction) { + const hookName = getHookName(config, hookNames, 'read', contract.name) + const docString = genDocString('useReadContract', contract) + const functionName = 'createUseReadContract' + imports.add(functionName) + content.push( + `${docString} +export const ${hookName} = ${pure} ${functionName}({ ${innerContent} })`, + ) + + const names = new Set() + for (const item of readItems) { + if (item.type !== 'function') continue + if ( + item.stateMutability !== 'pure' && + item.stateMutability !== 'view' + ) + continue + + // Skip overrides since they are captured by same hook + if (names.has(item.name)) continue + names.add(item.name) + + const hookName = getHookName( + config, + hookNames, + 'read', + contract.name, + item.name, + ) + const docString = genDocString('useReadContract', contract, { + name: 'functionName', + value: item.name, + }) + content.push( + `${docString} +export const ${hookName} = ${pure} ${functionName}({ ${innerContent}, functionName: '${item.name}' })`, + ) + } + } + + if (hasWriteFunction) { + { + const hookName = getHookName( + config, + hookNames, + 'write', + contract.name, + ) + const docString = genDocString('useWriteContract', contract) + const functionName = 'createUseWriteContract' + imports.add(functionName) + content.push( + `${docString} +export const ${hookName} = ${pure} ${functionName}({ ${innerContent} })`, + ) + + const names = new Set() + for (const item of writeItems) { + if (item.type !== 'function') continue + if ( + item.stateMutability !== 'nonpayable' && + item.stateMutability !== 'payable' + ) + continue + + // Skip overrides since they are captured by same hook + if (names.has(item.name)) continue + names.add(item.name) + + const hookName = getHookName( + config, + hookNames, + 'write', + contract.name, + item.name, + ) + const docString = genDocString('useWriteContract', contract, { + name: 'functionName', + value: item.name, + }) + content.push( + `${docString} +export const ${hookName} = ${pure} ${functionName}({ ${innerContent}, functionName: '${item.name}' })`, + ) + } + } + + { + const hookName = getHookName( + config, + hookNames, + 'simulate', + contract.name, + ) + const docString = genDocString('useSimulateContract', contract) + const functionName = 'createUseSimulateContract' + imports.add(functionName) + content.push( + `${docString} +export const ${hookName} = ${pure} ${functionName}({ ${innerContent} })`, + ) + + const names = new Set() + for (const item of writeItems) { + if (item.type !== 'function') continue + if ( + item.stateMutability !== 'nonpayable' && + item.stateMutability !== 'payable' + ) + continue + + // Skip overrides since they are captured by same hook + if (names.has(item.name)) continue + names.add(item.name) + + const hookName = getHookName( + config, + hookNames, + 'simulate', + contract.name, + item.name, + ) + const docString = genDocString('useSimulateContract', contract, { + name: 'functionName', + value: item.name, + }) + content.push( + `${docString} +export const ${hookName} = ${pure} ${functionName}({ ${innerContent}, functionName: '${item.name}' })`, + ) + } + } + } + + if (hasEvent) { + const hookName = getHookName( + config, + hookNames, + 'watch', + contract.name, + ) + const docString = genDocString('useWatchContractEvent', contract) + const functionName = 'createUseWatchContractEvent' + imports.add(functionName) + content.push( + `${docString} +export const ${hookName} = ${pure} ${functionName}({ ${innerContent} })`, + ) + + const names = new Set() + for (const item of eventItems) { + if (item.type !== 'event') continue + + // Skip overrides since they are captured by same hook + if (names.has(item.name)) continue + names.add(item.name) + + const hookName = getHookName( + config, + hookNames, + 'watch', + contract.name, + item.name, + ) + const docString = genDocString('useWatchContractEvent', contract, { + name: 'eventName', + value: item.name, + }) + content.push( + `${docString} +export const ${hookName} = ${pure} ${functionName}({ ${innerContent}, eventName: '${item.name}' })`, + ) + } + } + } + + const importValues = [...imports.values()] + + return { + imports: importValues.length + ? `import { ${importValues.join(', ')} } from 'wagmi/codegen'\n` + : '', + content: content.join('\n\n'), + } + }, + } +} + +function genDocString( + hookName: string, + contract: Contract, + item?: { name: string; value: string }, +) { + let description = `Wraps __{@link ${hookName}}__ with \`abi\` set to __{@link ${contract.meta.abiName}}__` + if (item) description += ` and \`${item.name}\` set to \`"${item.value}"\`` + + const docString = getAddressDocString({ address: contract.address }) + if (docString) + return `/** + * ${description} + * + ${docString} + */` + + return `/** + * ${description} + */` +} + +function getHookName( + config: ReactConfig, + hookNames: Set, + type: 'read' | 'simulate' | 'watch' | 'write', + contractName: string, + itemName?: string | undefined, +) { + const ContractName = pascalCase(contractName) + const ItemName = itemName ? pascalCase(itemName) : undefined + + let hookName: string + if (typeof config.getHookName === 'function') + hookName = config.getHookName({ + type, + contractName: ContractName, + itemName: ItemName, + }) + else if (typeof config.getHookName === 'string') { + switch (type) { + case 'read': + hookName = `use${ContractName}${ItemName ?? 'Read'}` + break + case 'simulate': + hookName = `usePrepare${ContractName}${ItemName ?? 'Write'}` + break + case 'watch': + hookName = `use${ContractName}${ItemName ?? ''}Event` + break + case 'write': + hookName = `use${ContractName}${ItemName ?? 'Write'}` + break + } + } else { + hookName = `use${pascalCase(type)}${ContractName}${ItemName ?? ''}` + if (type === 'watch') hookName = `${hookName}Event` + } + + if (hookNames.has(hookName)) + throw new Error( + `Hook name "${hookName}" must be unique for contract "${contractName}". Try using \`getHookName\` to create a unique name.`, + ) + + hookNames.add(hookName) + return hookName +} diff --git a/wagmi-project/packages/cli/src/plugins/sourcify.test.ts b/wagmi-project/packages/cli/src/plugins/sourcify.test.ts new file mode 100644 index 0000000000..842a291147 --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/sourcify.test.ts @@ -0,0 +1,83 @@ +import { http, HttpResponse } from 'msw' +import { setupServer } from 'msw/node' +import { afterAll, afterEach, beforeAll, expect, test } from 'vitest' + +import { depositAbi } from '../../test/constants.js' +import { sourcify } from './sourcify.js' + +const baseUrl = 'https://sourcify.dev/server/v2/contract' +const address = '0x00000000219ab540356cbb839cbe05303d7705fa' +const chainId = 1 +const multichainAddress = '0xC4c622862a8F548997699bE24EA4bc504e5cA865' +const multichainIdGnosis = 100 +const multichainIdPolygon = 137 +const successJson = { + abi: depositAbi, +} + +const handlers = [ + http.get(`${baseUrl}/${chainId}/${address}`, () => + HttpResponse.json(successJson), + ), + http.get(`${baseUrl}/${multichainIdGnosis}/${address}`, () => + HttpResponse.json({}, { status: 404 }), + ), + http.get(`${baseUrl}/${multichainIdGnosis}/${multichainAddress}`, () => + HttpResponse.json(successJson), + ), + http.get(`${baseUrl}/${multichainIdPolygon}/${multichainAddress}`, () => + HttpResponse.json(successJson), + ), +] + +const server = setupServer(...handlers) + +beforeAll(() => server.listen()) +afterEach(() => server.resetHandlers()) +afterAll(() => server.close()) + +test('fetches ABI', () => { + expect( + sourcify({ + chainId: chainId, + contracts: [{ name: 'DepositContract', address }], + }).contracts?.(), + ).resolves.toMatchSnapshot() +}) + +test('fetches ABI with multichain deployment', () => { + expect( + sourcify({ + chainId: 100, + contracts: [ + { + name: 'Community', + address: { 100: multichainAddress, 137: multichainAddress }, + }, + ], + }).contracts?.(), + ).resolves.toMatchSnapshot() +}) + +test('fails to fetch for unverified contract', () => { + expect( + sourcify({ + chainId: 100, + contracts: [{ name: 'DepositContract', address }], + }).contracts?.(), + ).rejects.toThrowErrorMatchingInlineSnapshot( + '[Error: Contract not found in Sourcify repository.]', + ) +}) + +test('missing address for chainId', () => { + expect( + sourcify({ + chainId: 1, + // @ts-expect-error `chainId` and `keyof typeof contracts[number].address` mismatch + contracts: [{ name: 'DepositContract', address: { 10: address } }], + }).contracts?.(), + ).rejects.toThrowErrorMatchingInlineSnapshot( + `[Error: No address found for chainId "1". Make sure chainId "1" is set as an address.]`, + ) +}) diff --git a/wagmi-project/packages/cli/src/plugins/sourcify.ts b/wagmi-project/packages/cli/src/plugins/sourcify.ts new file mode 100644 index 0000000000..0d452046ca --- /dev/null +++ b/wagmi-project/packages/cli/src/plugins/sourcify.ts @@ -0,0 +1,312 @@ +import { Abi as AbiSchema } from 'abitype/zod' +import type { Address } from 'viem' +import { z } from 'zod' + +import type { ContractConfig } from '../config.js' +import { fromZodError } from '../errors.js' +import type { Compute } from '../types.js' +import { fetch } from './fetch.js' + +export type SourcifyConfig = { + /** + * Duration in milliseconds to cache ABIs. + * + * @default 1_800_000 // 30m in ms + */ + cacheDuration?: number | undefined + /** + * Chain id to use for fetching ABI. + * + * If `address` is an object, `chainId` is used to select the address. + * + * See https://docs.sourcify.dev/docs/chains for supported chains. + */ + chainId: (chainId extends ChainId ? chainId : never) | (ChainId & {}) + /** + * Contracts to fetch ABIs for. + */ + contracts: Compute, 'abi'>>[] +} + +const SourcifyResponse = z.object({ + abi: AbiSchema, +}) + +/** Fetches contract ABIs from Sourcify. */ +export function sourcify( + config: SourcifyConfig, +) { + const { cacheDuration, chainId, contracts: contracts_ } = config + + const contracts = contracts_.map((x) => ({ + ...x, + address: + typeof x.address === 'string' ? { [chainId]: x.address } : x.address, + })) as Omit[] + + return fetch({ + cacheDuration, + contracts, + async parse({ response }) { + if (response.status === 404) + throw new Error('Contract not found in Sourcify repository.') + + const json = await response.json() + const parsed = await SourcifyResponse.safeParseAsync(json) + if (!parsed.success) + throw fromZodError(parsed.error, { prefix: 'Invalid response' }) + + if (parsed.data.abi) return parsed.data.abi as ContractConfig['abi'] + throw new Error('contract not found') + }, + request({ address }) { + if (!address) throw new Error('address is required') + + let contractAddress: Address | undefined + if (typeof address === 'string') contractAddress = address + else if (typeof address === 'object') contractAddress = address[chainId] + + if (!contractAddress) + throw new Error( + `No address found for chainId "${chainId}". Make sure chainId "${chainId}" is set as an address.`, + ) + return { + url: `https://sourcify.dev/server/v2/contract/${chainId}/${contractAddress}?fields=abi`, + } + }, + }) +} + +// Supported chains +// https://docs.sourcify.dev/docs/chains +type ChainId = + | 1 // Ethereum Mainnet + | 17000 // Ethereum Testnet Holesky + | 5 // Ethereum Testnet Goerli + | 11155111 // Ethereum Testnet Sepolia + | 3 // Ethereum Testnet Ropsten + | 4 // Ethereum Testnet Rinkeby + | 10 // OP Mainnet + | 100 // Gnosis + | 100009 // VeChain + | 100010 // VeChain Testnet + | 1001 // Kaia Kairos Testnet + | 10200 // Gnosis Chiado Testnet + | 10242 // Arthera Mainnet + | 10243 // Arthera Testnet + | 1030 // Conflux eSpace + | 103090 // Crystaleum + | 105105 // Stratis Mainnet + | 106 // Velas EVM Mainnet + | 10849 // Lamina1 + | 10850 // Lamina1 Identity + | 1088 // Metis Andromeda Mainnet + | 1101 // Polygon zkEVM + | 111000 // Siberium Test Network + | 11111 // WAGMI + | 1114 // Core Blockchain Testnet2 + | 1115 // Core Blockchain Testnet + | 11155420 // OP Sepolia Testnet + | 1116 // Core Blockchain Mainnet + | 11235 // Haqq Network + | 1127469 // Tiltyard Subnet + | 11297108099 // Palm Testnet + | 11297108109 // Palm + | 1149 // Symplexia Smart Chain + | 122 // Fuse Mainnet + | 1284 // Moonbeam + | 1285 // Moonriver + | 1287 // Moonbase Alpha + | 12898 // PlayFair Testnet Subnet + | 1291 // Swisstronik Testnet + | 1313161554 // Aurora Mainnet + | 1313161555 // Aurora Testnet + | 13337 // Beam Testnet + | 13381 // Phoenix Mainnet + | 1339 // Elysium Mainnet + | 137 // Polygon Mainnet + | 14 // Flare Mainnet + | 1433 // Rikeza Network Mainnet + | 1516 // Story Odyssey Testnet + | 16180 // PLYR PHI + | 16350 // Incentiv Devnet + | 167005 // Taiko Grimsvotn L2 + | 167006 // Taiko Eldfell L3 + | 17069 // Garnet Holesky + | 180 // AME Chain Mainnet + | 1890 // Lightlink Phoenix Mainnet + | 1891 // Lightlink Pegasus Testnet + | 19 // Songbird Canary-Network + | 19011 // HOME Verse Mainnet + | 192837465 // Gather Mainnet Network + | 2000 // Dogechain Mainnet + | 200810 // Bitlayer Testnet + | 200901 // Bitlayer Mainnet + | 2017 // Adiri + | 2020 // Ronin Mainnet + | 2021 // Edgeware EdgeEVM Mainnet + | 202401 // YMTECH-BESU Testnet + | 2037 // Kiwi Subnet + | 2038 // Shrapnel Testnet + | 2044 // Shrapnel Subnet + | 2047 // Stratos Testnet + | 2048 // Stratos + | 205205 // Auroria Testnet + | 212 // MAPO Makalu + | 216 // Happychain Testnet + | 222000222 // Kanazawa + | 2221 // Kava Testnet + | 2222 // Kava + | 223 // B2 Mainnet + | 22776 // MAP Protocol + | 23294 // Oasis Sapphire + | 23295 // Oasis Sapphire Testnet + | 2358 // Kroma Sepolia + | 2442 // Polygon zkEVM Cardona Testnet + | 246 // Energy Web Chain + | 25 // Cronos Mainnet + | 250 // Fantom Opera + | 252 // Fraxtal + | 2522 // Fraxtal Testnet + | 255 // Kroma + | 25925 // KUB Testnet + | 26100 // Ferrum Quantum Portal Network + | 28 // Boba Network Rinkeby Testnet + | 28528 // Optimism Bedrock (Goerli Alpha Testnet) + | 288 // Boba Network + | 295 // Hedera Mainnet + | 30 // Rootstock Mainnet + | 300 // zkSync Sepolia Testnet + | 311752642 // OneLedger Mainnet + | 314 // Filecoin - Mainnet + | 314159 // Filecoin - Calibration testnet + | 32769 // Zilliqa EVM + | 32770 // Zilliqa 2 EVM proto-mainnet + | 33101 // Zilliqa EVM Testnet + | 33103 // Zilliqa 2 EVM proto-testnet + | 33111 // Curtis + | 333000333 // Meld + | 335 // DFK Chain Test + | 336 // Shiden + | 34443 // Mode + | 35441 // Q Mainnet + | 35443 // Q Testnet + | 356256156 // Gather Testnet Network + | 369 // PulseChain + | 3737 // Crossbell + | 37714555429 // Xai Testnet v2 + | 383414847825 // Zeniq + | 39797 // Energi Mainnet + | 40 // Telos EVM Mainnet + | 4000 // Ozone Chain Mainnet + | 41 // Telos EVM Testnet + | 4157 // CrossFi Testnet + | 420 // Optimism Goerli Testnet + | 4200 // Merlin Mainnet + | 420420 // Kekchain + | 420666 // Kekchain (kektest) + | 42161 // Arbitrum One + | 421611 // Arbitrum Rinkeby + | 421613 // Arbitrum Goerli + | 4216137055 // OneLedger Testnet Frankenstein + | 421614 // Arbitrum Sepolia + | 42170 // Arbitrum Nova + | 42220 // Celo Mainnet + | 42261 // Oasis Emerald Testnet + | 42262 // Oasis Emerald + | 42766 // ZKFair Mainnet + | 43 // Darwinia Pangolin Testnet + | 43113 // Avalanche Fuji Testnet + | 43114 // Avalanche C-Chain + | 432201 // Dexalot Subnet Testnet + | 432204 // Dexalot Subnet + | 4337 // Beam + | 44 // Crab Network + | 44787 // Celo Alfajores Testnet + | 46 // Darwinia Network + | 486217935 // Gather Devnet Network + | 48898 // Zircuit Garfield Testnet + | 48899 // Zircuit Testnet + | 48900 // Zircuit Mainnet + | 49797 // Energi Testnet + | 50 // XDC Network + | 5000 // Mantle + | 5003 // Mantle Sepolia Testnet + | 51 // XDC Apothem Network + | 5115 // Citrea Testnet + | 534 // Candle + | 534351 // Scroll Sepolia Testnet + | 534352 // Scroll + | 53935 // DFK Chain + | 54211 // Haqq Chain Testnet + | 56 // BNB Smart Chain Mainnet + | 560048 // Hoodi testnet + | 57 // Syscoin Mainnet + | 570 // Rollux Mainnet + | 5700 // Syscoin Tanenbaum Testnet + | 57000 // Rollux Testnet + | 5845 // Tangle + | 59141 // Linea Sepolia + | 59144 // Linea + | 592 // Astar + | 59902 // Metis Sepolia Testnet + | 61 // Ethereum Classic + | 6119 // UPTN + | 62320 // Celo Baklava Testnet + | 62621 // MultiVAC Mainnet + | 62831 // PLYR TAU Testnet + | 6321 // Aura Euphoria Testnet + | 6322 // Aura Mainnet + | 641230 // Bear Network Chain Mainnet + | 648 // Endurance Smart Chain Mainnet + | 660279 // Xai Mainnet + | 666666666 // Degen Chain + | 69 // Optimism Kovan + | 690 // Redstone + | 7000 // ZetaChain Mainnet + | 7001 // ZetaChain Testnet + | 7078815900 // Mekong + | 710420 // Tiltyard Mainnet Subnet + | 71401 // Godwoken Testnet v1 + | 71402 // Godwoken Mainnet + | 7171 // Bitrock Mainnet + | 7200 // exSat Mainnet + | 723107 // TixChain Testnet + | 73799 // Energy Web Volta Testnet + | 764984 // Lamina1 Testnet + | 7668 // The Root Network - Mainnet + | 7672 // The Root Network - Porcini Testnet + | 767368 // Lamina1 Identity Testnet + | 77 // POA Network Sokol + | 7700 // Canto + | 7701 // Canto Tesnet + | 7771 // Bitrock Testnet + | 7777777 // Zora + | 78430 // Amplify Subnet + | 78431 // Bulletin Subnet + | 78432 // Conduit Subnet + | 8 // Ubiq + | 80001 // Mumbai + | 80002 // Amoy + | 82 // Meter Mainnet + | 8217 // Kaia Mainnet + | 83 // Meter Testnet + | 839999 // exSat Testnet + | 841 // Taraxa Mainnet + | 842 // Taraxa Testnet + | 8453 // Base + | 84531 // Base Goerli Testnet + | 84532 // Base Sepolia Testnet + | 888 // Wanchain + | 9000 // Evmos Testnet + | 9001 // Evmos + | 919 // Mode Testnet + | 957 // Lyra Chain + | 96 // KUB Mainnet + | 97 // BNB Smart Chain Testnet + | 970 // Oort Mainnet + | 99 // POA Network Core + | 9977 // Mind Smart Chain Testnet + | 999 // Wanchain Testnet + | 9996 // Mind Smart Chain Mainnet + | 999999999 // Zora Sepolia Testnet diff --git a/wagmi-project/packages/cli/src/types.ts b/wagmi-project/packages/cli/src/types.ts new file mode 100644 index 0000000000..adb2889348 --- /dev/null +++ b/wagmi-project/packages/cli/src/types.ts @@ -0,0 +1,10 @@ +export type Compute = { [key in keyof type]: type[key] } & unknown + +export type MaybeArray = T | T[] + +export type MaybePromise = T | Promise + +export type RequiredBy = Required< + Pick +> & + Omit diff --git a/wagmi-project/packages/cli/src/utils/findConfig.test.ts b/wagmi-project/packages/cli/src/utils/findConfig.test.ts new file mode 100644 index 0000000000..52c2066773 --- /dev/null +++ b/wagmi-project/packages/cli/src/utils/findConfig.test.ts @@ -0,0 +1,42 @@ +import { afterEach, expect, test, vi } from 'vitest' + +import { createFixture } from '../../test/utils.js' +import { findConfig } from './findConfig.js' + +afterEach(() => { + vi.restoreAllMocks() +}) + +test('finds config file', async () => { + const { dir, paths } = await createFixture({ + files: { 'wagmi.config.ts': '' }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await expect(findConfig()).resolves.toBe(paths['wagmi.config.ts']) +}) + +test('finds config file at location', async () => { + const { dir, paths } = await createFixture({ + files: { 'wagmi.config.ts': '' }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await expect(findConfig({ config: paths['wagmi.config.ts'] })).resolves.toBe( + paths['wagmi.config.ts'], + ) +}) + +test('finds config file at root', async () => { + const { dir, paths } = await createFixture({ + files: { 'wagmi.config.ts': '' }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await expect(findConfig({ root: dir })).resolves.toBe( + paths['wagmi.config.ts'], + ) +}) diff --git a/wagmi-project/packages/cli/src/utils/findConfig.ts b/wagmi-project/packages/cli/src/utils/findConfig.ts new file mode 100644 index 0000000000..2e94e2d5a4 --- /dev/null +++ b/wagmi-project/packages/cli/src/utils/findConfig.ts @@ -0,0 +1,39 @@ +import { existsSync } from 'node:fs' +import escalade from 'escalade' +import { resolve } from 'pathe' + +// Do not reorder +// In order of preference files are checked +const configFiles = [ + 'wagmi.config.ts', + 'wagmi.config.js', + 'wagmi.config.mjs', + 'wagmi.config.mts', +] + +type FindConfigParameters = { + /** Config file name */ + config?: string | undefined + /** Config file directory */ + root?: string | undefined +} + +/** + * Resolves path to wagmi CLI config file. + */ +export async function findConfig(parameters: FindConfigParameters = {}) { + const { config, root } = parameters + const rootDir = resolve(root || process.cwd()) + if (config) { + const path = resolve(rootDir, config) + if (existsSync(path)) return path + return + } + const configPath = await escalade(rootDir, (_dir, names) => { + for (const name of names) { + if (configFiles.includes(name)) return name + } + return undefined + }) + return configPath +} diff --git a/wagmi-project/packages/cli/src/utils/format.test.ts b/wagmi-project/packages/cli/src/utils/format.test.ts new file mode 100644 index 0000000000..6d04eb5465 --- /dev/null +++ b/wagmi-project/packages/cli/src/utils/format.test.ts @@ -0,0 +1,12 @@ +import { expect, test } from 'vitest' + +import { format } from './format.js' + +test('formats code', async () => { + await expect( + format(`const foo = "bar"`), + ).resolves.toMatchInlineSnapshot(` + "const foo = 'bar' + " + `) +}) diff --git a/wagmi-project/packages/cli/src/utils/format.ts b/wagmi-project/packages/cli/src/utils/format.ts new file mode 100644 index 0000000000..d440e60471 --- /dev/null +++ b/wagmi-project/packages/cli/src/utils/format.ts @@ -0,0 +1,17 @@ +import prettier from 'prettier' + +export async function format(content: string) { + const config = await prettier.resolveConfig(process.cwd()) + return prettier.format(content, { + arrowParens: 'always', + endOfLine: 'lf', + parser: 'typescript', + printWidth: 80, + semi: false, + singleQuote: true, + tabWidth: 2, + trailingComma: 'all', + ...config, + plugins: [], + }) +} diff --git a/wagmi-project/packages/cli/src/utils/getAddressDocString.test.ts b/wagmi-project/packages/cli/src/utils/getAddressDocString.test.ts new file mode 100644 index 0000000000..798e6e14e5 --- /dev/null +++ b/wagmi-project/packages/cli/src/utils/getAddressDocString.test.ts @@ -0,0 +1,40 @@ +import { expect, test } from 'vitest' + +import { getAddressDocString } from './getAddressDocString.js' + +test('address', async () => { + expect( + getAddressDocString({ + address: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e', + }), + ).toMatchInlineSnapshot('""') +}) + +test('multichain address with known chain ids', async () => { + expect( + getAddressDocString({ + address: { + 1: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e', + 5: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e', + 10: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e', + }, + }), + ).toMatchInlineSnapshot(` + "* - [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e) + * - [__View Contract on Goerli Etherscan__](https://goerli.etherscan.io/address/0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e) + * - [__View Contract on Op Mainnet Optimism Explorer__](https://optimistic.etherscan.io/address/0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e)" + `) +}) + +test('multichain address with unknown chain id', async () => { + expect( + getAddressDocString({ + address: { + 1: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e', + 2: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e', + }, + }), + ).toMatchInlineSnapshot( + '"* [__View Contract on Ethereum Etherscan__](https://etherscan.io/address/0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e)"', + ) +}) diff --git a/wagmi-project/packages/cli/src/utils/getAddressDocString.ts b/wagmi-project/packages/cli/src/utils/getAddressDocString.ts new file mode 100644 index 0000000000..d0e137928c --- /dev/null +++ b/wagmi-project/packages/cli/src/utils/getAddressDocString.ts @@ -0,0 +1,53 @@ +import { capitalCase } from 'change-case' +import dedent from 'dedent' +import * as allChains from 'viem/chains' + +import type { Contract } from '../config.js' + +const chainMap: Record = {} +for (const chain of Object.values(allChains)) { + if (typeof chain !== 'object') continue + if (!('id' in chain)) continue + chainMap[chain.id] = chain +} + +export function getAddressDocString(parameters: { + address: Contract['address'] +}) { + const { address } = parameters + if (!address || typeof address === 'string') return '' + + if (Object.keys(address).length === 1) + return `* ${getLink({ + address: address[Number.parseInt(Object.keys(address)[0]!)]!, + chainId: Number.parseInt(Object.keys(address)[0]!), + })}` + + const addresses = Object.entries(address).filter( + (x) => chainMap[Number.parseInt(x[0])], + ) + if (addresses.length === 0) return '' + if (addresses.length === 1 && addresses[0]) + return `* ${getLink({ + address: addresses[0][1], + chainId: Number.parseInt(addresses[0][0])!, + })}` + + return dedent` + ${addresses.reduce((prev, curr) => { + const chainId = Number.parseInt(curr[0]) + const address = curr[1] + return `${prev}\n* - ${getLink({ address, chainId })}` + }, '')} + ` +} + +function getLink({ address, chainId }: { address: string; chainId: number }) { + const chain = chainMap[chainId] + if (!chain) return '' + const blockExplorer = chain.blockExplorers?.default + if (!blockExplorer) return '' + return `[__View Contract on ${capitalCase(chain.name)} ${capitalCase( + blockExplorer.name, + )}__](${blockExplorer.url}/address/${address})` +} diff --git a/wagmi-project/packages/cli/src/utils/getIsUsingTypeScript.test.ts b/wagmi-project/packages/cli/src/utils/getIsUsingTypeScript.test.ts new file mode 100644 index 0000000000..3ba7c86a65 --- /dev/null +++ b/wagmi-project/packages/cli/src/utils/getIsUsingTypeScript.test.ts @@ -0,0 +1,43 @@ +import { afterEach, expect, test, vi } from 'vitest' + +import { createFixture } from '../../test/utils.js' +import { getIsUsingTypeScript } from './getIsUsingTypeScript.js' + +afterEach(() => { + vi.restoreAllMocks() +}) + +test('true if has tsconfig', async () => { + const { dir } = await createFixture({ + files: { + 'tsconfig.json': '', + }, + }) + + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await expect(getIsUsingTypeScript()).resolves.toBe(true) +}) + +test('true if has wagmi.config', async () => { + const { dir } = await createFixture({ + files: { + 'wagmi.config.ts': '', + }, + }) + + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await expect(getIsUsingTypeScript()).resolves.toBe(true) +}) + +test('false', async () => { + const { dir } = await createFixture() + + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + await expect(getIsUsingTypeScript()).resolves.toBe(false) +}) diff --git a/wagmi-project/packages/cli/src/utils/getIsUsingTypeScript.ts b/wagmi-project/packages/cli/src/utils/getIsUsingTypeScript.ts new file mode 100644 index 0000000000..bd2383b0eb --- /dev/null +++ b/wagmi-project/packages/cli/src/utils/getIsUsingTypeScript.ts @@ -0,0 +1,33 @@ +import escalade from 'escalade' + +export async function getIsUsingTypeScript() { + try { + const cwd = process.cwd() + const tsconfig = await escalade(cwd, (_dir, names) => { + const files = [ + 'tsconfig.json', + 'tsconfig.base.json', + 'tsconfig.lib.json', + 'tsconfig.node.json', + ] + for (const name of names) { + if (files.includes(name)) return name + } + return undefined + }) + if (tsconfig) return true + + const wagmiConfig = await escalade(cwd, (_dir, names) => { + const files = ['wagmi.config.ts', 'wagmi.config.mts'] + for (const name of names) { + if (files.includes(name)) return name + } + return undefined + }) + if (wagmiConfig) return true + + return false + } catch { + return false + } +} diff --git a/wagmi-project/packages/cli/src/utils/loadEnv.test.ts b/wagmi-project/packages/cli/src/utils/loadEnv.test.ts new file mode 100644 index 0000000000..d577778eb0 --- /dev/null +++ b/wagmi-project/packages/cli/src/utils/loadEnv.test.ts @@ -0,0 +1,77 @@ +import { afterEach, expect, test, vi } from 'vitest' + +import { createFixture } from '../../test/utils.js' +import { loadEnv } from './loadEnv.js' + +afterEach(() => { + vi.restoreAllMocks() +}) + +test('loads env', async () => { + const { dir } = await createFixture({ + files: { + '.env': ` + FOO=bar + SOME_ENV_VAR=1 + `, + }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + expect(loadEnv()).toMatchInlineSnapshot(` + { + "FOO": "bar", + "SOME_ENV_VAR": "1", + } + `) +}) + +test('loads env from envDir', async () => { + const { dir } = await createFixture({ + files: { + '.env': ` + FOO=bar + SOME_ENV_VAR=1 + `, + }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + expect(loadEnv({ envDir: dir })).toMatchInlineSnapshot(` + { + "FOO": "bar", + "SOME_ENV_VAR": "1", + } + `) +}) + +test('loads env with mode', async () => { + const mode = 'dev' + const { dir } = await createFixture({ + files: { + [`.env.${mode}`]: ` + FOO=bar + SOME_ENV_VAR=1 + `, + }, + }) + const spy = vi.spyOn(process, 'cwd') + spy.mockImplementation(() => dir) + + expect(loadEnv({ mode })).toMatchInlineSnapshot(` + { + "FOO": "bar", + "SOME_ENV_VAR": "1", + } + `) +}) + +test('throws error when mode is "local"', async () => { + expect(() => { + loadEnv({ mode: 'local' }) + }).toThrowErrorMatchingInlineSnapshot( + `[Error: "local" cannot be used as a mode name because it conflicts with the .local postfix for .env files.]`, + ) +}) diff --git a/wagmi-project/packages/cli/src/utils/loadEnv.ts b/wagmi-project/packages/cli/src/utils/loadEnv.ts new file mode 100644 index 0000000000..d7ffa99919 --- /dev/null +++ b/wagmi-project/packages/cli/src/utils/loadEnv.ts @@ -0,0 +1,90 @@ +import { parse } from 'dotenv' +import { expand } from 'dotenv-expand' + +import { existsSync, readFileSync, statSync } from 'node:fs' +import { dirname, join } from 'node:path' + +// https://github.com/vitejs/vite/blob/main/packages/vite/src/node/env.ts#L7 +export function loadEnv( + config: { + mode?: string + envDir?: string + } = {}, +): Record { + const mode = config.mode + if (mode === 'local') { + throw new Error( + `"local" cannot be used as a mode name because it conflicts with the .local postfix for .env files.`, + ) + } + + const envFiles = [ + /** default file */ '.env', + /** local file */ '.env.local', + ...(mode + ? [ + /** mode file */ `.env.${mode}`, + /** mode local file */ `.env.${mode}.local`, + ] + : []), + ] + + const envDir = config.envDir ?? process.cwd() + const parsed = Object.fromEntries( + envFiles.flatMap((file) => { + const path = lookupFile(envDir, [file], { + pathOnly: true, + rootDir: envDir, + }) + if (!path) return [] + return Object.entries(parse(readFileSync(path))) + }), + ) + + try { + // let environment variables use each other + expand({ parsed }) + } catch (error) { + // custom error handling until https://github.com/motdotla/dotenv-expand/issues/65 is fixed upstream + // check for message "TypeError: Cannot read properties of undefined (reading 'split')" + if ((error as Error).message.includes('split')) { + throw new Error( + 'dotenv-expand failed to expand env vars. Maybe you need to escape `$`?', + ) + } + throw error + } + + return parsed +} + +function lookupFile( + dir: string, + formats: string[], + options?: { + pathOnly?: boolean + rootDir?: string + predicate?: (file: string) => boolean + }, +): string | undefined { + for (const format of formats) { + const fullPath = join(dir, format) + if (existsSync(fullPath) && statSync(fullPath).isFile()) { + const result = options?.pathOnly + ? fullPath + : readFileSync(fullPath, 'utf-8') + if (!options?.predicate || options.predicate(result)) { + return result + } + } + } + + const parentDir = dirname(dir) + if ( + parentDir !== dir && + (!options?.rootDir || parentDir.startsWith(options?.rootDir)) + ) + return lookupFile(parentDir, formats, options) + + return undefined +} diff --git a/wagmi-project/packages/cli/src/utils/packages.test.ts b/wagmi-project/packages/cli/src/utils/packages.test.ts new file mode 100644 index 0000000000..96ea2e26ef --- /dev/null +++ b/wagmi-project/packages/cli/src/utils/packages.test.ts @@ -0,0 +1,19 @@ +import { expect, test } from 'vitest' + +import { getIsPackageInstalled, getPackageManager } from './packages.js' + +test('getIsPackageInstalled: true', async () => { + await expect(getIsPackageInstalled({ packageName: 'vitest' })).resolves.toBe( + true, + ) +}) + +test('getIsPackageInstalled: false', async () => { + await expect( + getIsPackageInstalled({ packageName: 'vitest-unknown' }), + ).resolves.toBe(false) +}) + +test('getPackageManager', async () => { + await expect(getPackageManager()).resolves.toMatchInlineSnapshot('"pnpm"') +}) diff --git a/wagmi-project/packages/cli/src/utils/packages.ts b/wagmi-project/packages/cli/src/utils/packages.ts new file mode 100644 index 0000000000..e55eeaf0ea --- /dev/null +++ b/wagmi-project/packages/cli/src/utils/packages.ts @@ -0,0 +1,124 @@ +import { execSync } from 'node:child_process' +import { promises as fs } from 'node:fs' +import { resolve } from 'node:path' + +export async function getIsPackageInstalled(parameters: { + packageName: string + cwd?: string +}) { + const { packageName, cwd = process.cwd() } = parameters + try { + const packageManager = await getPackageManager() + const command = (() => { + switch (packageManager) { + case 'yarn': + return ['why', packageName] + case 'bun': + return ['pm', 'ls', '--all'] + default: + return ['ls', packageName] + } + })() + + const result = execSync(`${packageManager} ${command.join(' ')}`, { + cwd, + encoding: 'utf-8', + stdio: 'pipe', + }) + + // For Bun, we need to check if the package name is in the output + if (packageManager === 'bun') return result.includes(packageName) + + return result !== '' + } catch (_error) { + return false + } +} + +export async function getPackageManager(executable?: boolean | undefined) { + const userAgent = process.env.npm_config_user_agent + if (userAgent) { + if (userAgent.includes('pnpm')) return 'pnpm' + // The yarn@^3 user agent includes npm, so yarn must be checked first. + if (userAgent.includes('yarn')) return 'yarn' + if (userAgent.includes('npm')) return executable ? 'npx' : 'npm' + if (userAgent.includes('bun')) return executable ? 'bunx' : 'bun' + } + + const packageManager = await detect() + if (packageManager === 'npm' && executable) return 'npx' + return packageManager +} + +type PackageManager = 'npm' | 'yarn' | 'pnpm' | 'bun' + +async function detect( + parameters: { cwd?: string; includeGlobalBun?: boolean } = {}, +) { + const { cwd, includeGlobalBun } = parameters + const type = await getTypeofLockFile(cwd) + if (type) { + return type + } + const [hasYarn, hasPnpm, hasBun] = await Promise.all([ + hasGlobalInstallation('yarn'), + hasGlobalInstallation('pnpm'), + includeGlobalBun && hasGlobalInstallation('bun'), + ]) + if (hasYarn) return 'yarn' + if (hasPnpm) return 'pnpm' + if (hasBun) return 'bun' + return 'npm' +} + +const cache = new Map() + +function hasGlobalInstallation(pm: PackageManager): boolean { + const key = `has_global_${pm}` + if (cache.has(key)) return cache.get(key) + + try { + const result = execSync(`${pm} --version`, { + encoding: 'utf-8', + stdio: 'pipe', + }) + const isGlobal = /^\d+.\d+.\d+$/.test(result) + cache.set(key, isGlobal) + return isGlobal + } catch { + return false + } +} + +function getTypeofLockFile(cwd = '.'): Promise { + const key = `lockfile_${cwd}` + if (cache.has(key)) { + return Promise.resolve(cache.get(key)) + } + + return Promise.all([ + pathExists(resolve(cwd, 'yarn.lock')), + pathExists(resolve(cwd, 'package-lock.json')), + pathExists(resolve(cwd, 'pnpm-lock.yaml')), + pathExists(resolve(cwd, 'bun.lockb')), + ]).then(([isYarn, isNpm, isPnpm, isBun]) => { + let value: PackageManager | null = null + + if (isYarn) value = 'yarn' + else if (isPnpm) value = 'pnpm' + else if (isBun) value = 'bun' + else if (isNpm) value = 'npm' + + cache.set(key, value) + return value + }) +} + +async function pathExists(p: string) { + try { + await fs.access(p) + return true + } catch { + return false + } +} diff --git a/wagmi-project/packages/cli/src/utils/resolveConfig.test.ts b/wagmi-project/packages/cli/src/utils/resolveConfig.test.ts new file mode 100644 index 0000000000..6669edc9b6 --- /dev/null +++ b/wagmi-project/packages/cli/src/utils/resolveConfig.test.ts @@ -0,0 +1,83 @@ +import { expect, test } from 'vitest' + +import { createFixture } from '../../test/utils.js' +import { defaultConfig } from '../config.js' +import { findConfig } from './findConfig.js' +import { resolveConfig } from './resolveConfig.js' + +test.skip('resolves config', async () => { + const { paths } = await createFixture({ + files: { + 'wagmi.config.ts': ` + import { defineConfig } from '@wagmi/cli' + + export default defineConfig(${JSON.stringify(defaultConfig)}) + `, + }, + }) + + const configPath = await findConfig({ + config: paths['wagmi.config.ts'], + }) + await expect( + resolveConfig({ configPath: configPath! }), + ).resolves.toMatchInlineSnapshot(` + { + "contracts": [], + "out": "src/generated.ts", + "plugins": [], + } + `) +}) + +test.skip('resolves function config', async () => { + const { paths } = await createFixture({ + files: { + 'wagmi.config.ts': ` + import { defineConfig } from '@wagmi/cli' + + export default defineConfig(() => (${JSON.stringify(defaultConfig)})) + `, + }, + }) + + const configPath = await findConfig({ + config: paths['wagmi.config.ts'], + }) + await expect( + resolveConfig({ configPath: configPath! }), + ).resolves.toMatchInlineSnapshot(` + { + "contracts": [], + "out": "src/generated.ts", + "plugins": [], + } + `) +}) + +test.skip('resolves array config', async () => { + const { paths } = await createFixture({ + files: { + 'wagmi.config.ts': ` + import { defineConfig } from '@wagmi/cli' + + export default defineConfig([${JSON.stringify(defaultConfig)}]) + `, + }, + }) + + const configPath = await findConfig({ + config: paths['wagmi.config.ts'], + }) + await expect( + resolveConfig({ configPath: configPath! }), + ).resolves.toMatchInlineSnapshot(` + [ + { + "contracts": [], + "out": "src/generated.ts", + "plugins": [], + }, + ] + `) +}) diff --git a/wagmi-project/packages/cli/src/utils/resolveConfig.ts b/wagmi-project/packages/cli/src/utils/resolveConfig.ts new file mode 100644 index 0000000000..048b1c337f --- /dev/null +++ b/wagmi-project/packages/cli/src/utils/resolveConfig.ts @@ -0,0 +1,21 @@ +import { bundleRequire } from 'bundle-require' + +import type { Config } from '../config.js' +import type { MaybeArray } from '../types.js' + +type ResolveConfigParameters = { + /** Path to config file */ + configPath: string +} + +/** Bundles and returns wagmi config object from path. */ +export async function resolveConfig( + parameters: ResolveConfigParameters, +): Promise> { + const { configPath } = parameters + const res = await bundleRequire({ filepath: configPath }) + let config = res.mod.default + if (config.default) config = config.default + if (typeof config !== 'function') return config + return await config() +} diff --git a/wagmi-project/packages/cli/src/version.ts b/wagmi-project/packages/cli/src/version.ts new file mode 100644 index 0000000000..166b988ccb --- /dev/null +++ b/wagmi-project/packages/cli/src/version.ts @@ -0,0 +1 @@ +export const version = '2.3.1' diff --git a/wagmi-project/packages/cli/test/constants.ts b/wagmi-project/packages/cli/test/constants.ts new file mode 100644 index 0000000000..9b84c5bb1b --- /dev/null +++ b/wagmi-project/packages/cli/test/constants.ts @@ -0,0 +1,32 @@ +import { parseAbi } from 'viem' + +export const wagmiAbi = parseAbi([ + 'constructor()', + 'event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId)', + 'event ApprovalForAll(address indexed owner, address indexed operator, bool approved)', + 'event Transfer(address indexed from, address indexed to, uint256 indexed tokenId)', + 'function approve(address to, uint256 tokenId)', + 'function balanceOf(address owner) view returns (uint256)', + 'function getApproved(uint256 tokenId) view returns (address)', + 'function isApprovedForAll(address owner, address operator) view returns (bool)', + 'function mint()', + 'function name() view returns (string)', + 'function ownerOf(uint256 tokenId) view returns (address)', + 'function safeTransferFrom(address from, address to, uint256 tokenId)', + 'function safeTransferFrom(address from, address to, uint256 tokenId, bytes _data)', + 'function setApprovalForAll(address operator, bool approved)', + 'function supportsInterface(bytes4 interfaceId) view returns (bool)', + 'function symbol() view returns (string)', + 'function tokenURI(uint256 tokenId) pure returns (string)', + 'function totalSupply() view returns (uint256)', + 'function transferFrom(address from, address to, uint256 tokenId)', +]) + +export const depositAbi = parseAbi([ + 'constructor()', + 'event DepositEvent(bytes pubkey, bytes withdrawal_credentials, bytes amount, bytes signature, bytes index)', + 'function deposit(bytes pubkey, bytes withdrawal_credentials, bytes signature, bytes32 deposit_data_root) payable', + 'function get_deposit_count() view returns (bytes)', + 'function get_deposit_root() view returns (bytes32)', + 'function supportsInterface(bytes4 interfaceId) pure returns (bool)', +]) diff --git a/wagmi-project/packages/cli/test/setup.ts b/wagmi-project/packages/cli/test/setup.ts new file mode 100644 index 0000000000..d2eed4a5e5 --- /dev/null +++ b/wagmi-project/packages/cli/test/setup.ts @@ -0,0 +1,57 @@ +import { mkdir } from 'node:fs/promises' +import { homedir } from 'node:os' +import type { createSpinner as nanospinner_createSpinner } from 'nanospinner' +import { join } from 'pathe' +import { vi } from 'vitest' + +const cacheDir = join(homedir(), '.wagmi-cli/plugins/fetch/cache') +await mkdir(cacheDir, { recursive: true }) + +vi.mock('nanospinner', async (importOriginal) => { + const mod = await importOriginal<{ + createSpinner: typeof nanospinner_createSpinner + }>() + + function createSpinner( + initialText: string, + opts: Parameters[1], + ) { + let currentText = '' + const spinner = mod.createSpinner(initialText, opts) + return { + ...spinner, + start(text = initialText) { + // biome-ignore lint/suspicious/noConsoleLog: console.log is used for logging + console.log(`- ${text}`) + spinner.start(text) + currentText = text + }, + success(text = currentText) { + // biome-ignore lint/suspicious/noConsoleLog: console.log is used for logging + console.log(`√ ${text}`) + spinner.success(text) + }, + error(text = currentText) { + console.error(`Ɨ ${text}`) + spinner.error(text) + }, + } + } + return { createSpinner } +}) + +vi.mock('picocolors', async () => { + function pass(input: string | number | null | undefined) { + return input + } + return { + default: { + blue: pass, + gray: pass, + green: pass, + red: pass, + white: pass, + yellow: pass, + }, + } +}) diff --git a/wagmi-project/packages/cli/test/utils.ts b/wagmi-project/packages/cli/test/utils.ts new file mode 100644 index 0000000000..4ea6c6051e --- /dev/null +++ b/wagmi-project/packages/cli/test/utils.ts @@ -0,0 +1,292 @@ +import { spawnSync } from 'node:child_process' +import { cp, mkdir, symlink, writeFile } from 'node:fs/promises' +import fixtures from 'fixturez' +import { http, HttpResponse } from 'msw' +import * as path from 'pathe' +import { vi } from 'vitest' + +const f = fixtures(__dirname) + +type Json = + | string + | number + | boolean + | null + | { [property: string]: Json } + | Json[] + +export async function createFixture< + TFiles extends { [filename: string]: string | Json } & { + tsconfig?: true + }, +>( + config: { + copyNodeModules?: boolean + dir?: string + files?: TFiles + } = {}, +) { + const dir = config.dir ?? f.temp() + await mkdir(dir, { recursive: true }) + + // Create test files + const paths: { [_ in keyof TFiles]: string } = {} as any + await Promise.all( + (Object.keys(config.files ?? {}) as (keyof TFiles)[]).map( + async (filename_) => { + let file: Json | true | undefined + let filename = filename_ + if (filename === 'tsconfig') { + filename = 'tsconfig.json' + file = getTsConfig(dir) + } else file = config.files![filename] + + const filePath = path.join(dir, filename.toString()) + await mkdir(path.dirname(filePath), { recursive: true }) + + await writeFile( + filePath, + typeof file === 'string' ? file : JSON.stringify(file, null, 2), + ) + paths[filename === 'tsconfig.json' ? 'tsconfig' : filename] = filePath + }, + ), + ) + + if (config.copyNodeModules) { + await symlink( + path.join(__dirname, '../node_modules'), + path.join(dir, 'node_modules'), + 'dir', + ) + await cp( + path.join(__dirname, '../package.json'), + path.join(dir, 'package.json'), + ) + } + + return { + dir, + paths: paths, + } +} + +type TsConfig = { + compilerOptions: { [property: string]: any } + exclude: string[] + include: string[] +} +function getTsConfig(baseUrl: string) { + return { + compilerOptions: { + allowJs: true, + baseUrl: '.', + esModuleInterop: true, + forceConsistentCasingInFileNames: true, + incremental: true, + isolatedModules: true, + jsx: 'preserve', + lib: ['dom', 'dom.iterable', 'esnext'], + module: 'esnext', + moduleResolution: 'node', + noEmit: true, + paths: { + '@wagmi/cli': [path.relative(baseUrl, 'packages/cli/src')], + '@wagmi/cli/*': [path.relative(baseUrl, 'packages/cli/src/*')], + '@wagmi/connectors': [ + path.relative(baseUrl, 'packages/connectors/src'), + ], + '@wagmi/connectors/*': [ + path.relative(baseUrl, 'packages/connectors/src/*'), + ], + '@wagmi/core': [path.relative(baseUrl, 'packages/core/src')], + '@wagmi/core/*': [path.relative(baseUrl, 'packages/core/src/*')], + wagmi: [path.relative(baseUrl, 'packages/react/src')], + 'wagmi/*': [path.relative(baseUrl, 'packages/react/src/*')], + }, + resolveJsonModule: true, + skipLibCheck: true, + strict: true, + target: 'es6', + }, + include: [`${baseUrl}/**/*.ts`, `${baseUrl}/**/*.tsx`], + exclude: ['node_modules'], + } as TsConfig +} + +export function watchConsole() { + type Console = 'info' | 'log' | 'warn' | 'error' + const output: { [_ in Console | 'all']: string[] } = { + info: [], + log: [], + warn: [], + error: [], + all: [], + } + function handleOutput(method: Console) { + return (message: string) => { + output[method].push(message) + output.all.push(message) + } + } + return { + debug: console.debug, + info: vi.spyOn(console, 'info').mockImplementation(handleOutput('info')), + log: vi.spyOn(console, 'log').mockImplementation(handleOutput('log')), + warn: vi.spyOn(console, 'warn').mockImplementation(handleOutput('warn')), + error: vi.spyOn(console, 'error').mockImplementation(handleOutput('error')), + output, + get formatted() { + return output.all.join('\n') + }, + } +} + +export async function typecheck(project: string) { + try { + const result = spawnSync( + 'tsc', + ['--noEmit', '--target', 'es2021', '--pretty', 'false', '-p', project], + { + encoding: 'utf-8', + stdio: 'pipe', + }, + ) + if (result.error) throw result.error + if (result.status !== 0) + throw new Error(`Failed with code ${result.status}`) + if (result.signal) throw new Error('Process terminated by signal') + return result.stdout + } catch (error) { + throw new Error( + (error as Error).message.replaceAll( + path.dirname(project), + '/path/to/project', + ), + ) + } +} + +export const baseUrl = 'https://api.etherscan.io/v2/api' +export const apiKey = 'abc' +export const invalidApiKey = 'xyz' +export const address = '0xaf0326d92b97df1221759476b072abfd8084f9be' +export const proxyAddress = '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48' +export const implementationAddress = + '0x43506849d7c04f9138d1a2050bbf3a0c054402dd' +export const unverifiedContractAddress = + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e' +export const timeoutAddress = '0xecb504d39723b0be0e3a9aa33d646642d1051ee1' + +export const handlers = [ + http.get(baseUrl, async ({ request }) => { + const url = new URL(request.url) + const search = url.search.replace(/^\?chainId=\d&/, '?') + + if ( + search === + `?module=contract&action=getabi&address=${unverifiedContractAddress}&apikey=${apiKey}` + ) + return HttpResponse.json({ + status: '0', + message: 'NOTOK', + result: 'Contract source code not verified', + }) + + if ( + search === + `?module=contract&action=getabi&address=${timeoutAddress}&apikey=${invalidApiKey}` + ) + return HttpResponse.json({ + status: '0', + message: 'NOTOK', + result: 'Invalid API Key', + }) + + if ( + search === + `?module=contract&action=getabi&address=${address}&apikey=${apiKey}` + ) + return HttpResponse.json({ + status: '1', + message: 'OK', + result: + '[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"}]', + }) + + if ( + search === + `?module=contract&action=getabi&address=${timeoutAddress}&apikey=${apiKey}` + ) { + await new Promise((resolve) => setTimeout(resolve, 10_000)) + return HttpResponse.json({}) + } + + if ( + search === + `?module=contract&action=getabi&address=${implementationAddress}&apikey=${apiKey}` + ) + return HttpResponse.json({ + status: '1', + message: 'OK', + result: + '[{"constant":false,"inputs":[{"name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newImplementation","type":"address"},{"name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"implementation","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newAdmin","type":"address"}],"name":"changeAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"admin","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_implementation","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"previousAdmin","type":"address"},{"indexed":false,"name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"implementation","type":"address"}],"name":"Upgraded","type":"event"}]', + }) + + if ( + search === + `?module=contract&action=getsourcecode&address=${proxyAddress}&apikey=${apiKey}` + ) + return HttpResponse.json({ + status: '1', + message: 'OK', + result: [ + { + SourceCode: '...', + ABI: '[{"constant":false,"inputs":[{"name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newImplementation","type":"address"},{"name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"implementation","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newAdmin","type":"address"}],"name":"changeAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"admin","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_implementation","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"previousAdmin","type":"address"},{"indexed":false,"name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"implementation","type":"address"}],"name":"Upgraded","type":"event"}]', + ContractName: 'FiatTokenProxy', + CompilerVersion: 'v0.4.24+commit.e67f0147', + OptimizationUsed: '0', + Runs: '200', + ConstructorArguments: + '0000000000000000000000000882477e7895bdc5cea7cb1552ed914ab157fe56', + EVMVersion: 'Default', + Library: '', + LicenseType: '', + Proxy: '1', + Implementation: '0x43506849d7c04f9138d1a2050bbf3a0c054402dd', + SwarmSource: + 'bzzr://a4a547cfc7202c5acaaae74d428e988bc62ad5024eb0165532d3a8f91db4ed24', + }, + ], + }) + + if ( + search === + `?module=contract&action=getsourcecode&address=${address}&apikey=${apiKey}` + ) + return HttpResponse.json({ + status: '1', + message: 'OK', + result: [ + { + SourceCode: '...', + ABI: '[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"}]', + ContractName: 'WagmiMintExample', + CompilerVersion: 'v0.8.11+commit.d7f03943', + OptimizationUsed: '1', + Runs: '10000', + ConstructorArguments: '', + EVMVersion: 'Default', + Library: '', + LicenseType: '', + Proxy: '0', + Implementation: '', + SwarmSource: '', + }, + ], + }) + + throw new Error(`Unhandled request: ${search}`) + }), +] diff --git a/wagmi-project/packages/cli/tsconfig.build.json b/wagmi-project/packages/cli/tsconfig.build.json new file mode 100644 index 0000000000..3a046d812b --- /dev/null +++ b/wagmi-project/packages/cli/tsconfig.build.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.base.json", + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.test.ts"], + "compilerOptions": { + "sourceMap": true, + "types": ["@types/node"] + } +} diff --git a/wagmi-project/packages/cli/tsconfig.json b/wagmi-project/packages/cli/tsconfig.json new file mode 100644 index 0000000000..4054dee118 --- /dev/null +++ b/wagmi-project/packages/cli/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "./tsconfig.build.json", + "include": ["src/**/*.ts", "test/**/*.ts", "types/**/*.d.ts"], + "exclude": [] +} diff --git a/wagmi-project/packages/cli/types/fixturez.d.ts b/wagmi-project/packages/cli/types/fixturez.d.ts new file mode 100644 index 0000000000..f96282756f --- /dev/null +++ b/wagmi-project/packages/cli/types/fixturez.d.ts @@ -0,0 +1,18 @@ +declare module 'fixturez' { + interface FixturezOpts { + glob?: string + cleanup?: boolean + root?: string + } + + interface Fixturez { + find(basename: string): string + copy(basename: string): string + temp(): string + cleanup(): void + } + + function fixturez(dirname: string, opts?: FixturezOpts): Fixturez + + export = fixturez +} diff --git a/wagmi-project/packages/connectors/CHANGELOG.md b/wagmi-project/packages/connectors/CHANGELOG.md new file mode 100644 index 0000000000..c67e25dcb0 --- /dev/null +++ b/wagmi-project/packages/connectors/CHANGELOG.md @@ -0,0 +1,1640 @@ +# @wagmi/connectors + +## 5.8.3 + +### Patch Changes + +- [#4660](https://github.com/wevm/wagmi/pull/4660) [`42b1fed58e9ac09da0f8ebf3e9271f98a707aaac`](https://github.com/wevm/wagmi/commit/42b1fed58e9ac09da0f8ebf3e9271f98a707aaac) Thanks [@ganchoradkov](https://github.com/ganchoradkov)! - Updated `@walletconnect/ethereum-provider` version to `2.20.2` + +## 5.8.2 + +### Patch Changes + +- Updated dependencies [[`29297a48af72b537173d948ccd2fe37d39914c66`](https://github.com/wevm/wagmi/commit/29297a48af72b537173d948ccd2fe37d39914c66), [`07370106d5fb6b8fe300992d93abf25b3d0eaf57`](https://github.com/wevm/wagmi/commit/07370106d5fb6b8fe300992d93abf25b3d0eaf57)]: + - @wagmi/core@2.17.2 + +## 5.8.1 + +### Patch Changes + +- Updated dependencies [[`01f64e64fa4f85cdd30023903f972f4f9023681f`](https://github.com/wevm/wagmi/commit/01f64e64fa4f85cdd30023903f972f4f9023681f)]: + - @wagmi/core@2.17.1 + +## 5.8.0 + +### Minor Changes + +- [#4644](https://github.com/wevm/wagmi/pull/4644) [`cc5517ff6880bb630f1b201930acc20dd1a0b451`](https://github.com/wevm/wagmi/commit/cc5517ff6880bb630f1b201930acc20dd1a0b451) Thanks [@lukaisailovic](https://github.com/lukaisailovic)! - Updated `@walletconnect/etherereum-provider` to `2.20.0`. + +## 5.7.13 + +### Patch Changes + +- [#4622](https://github.com/wevm/wagmi/pull/4622) [`88427b2bcd13ec375ef519e9ad1ccffef9f02a7b`](https://github.com/wevm/wagmi/commit/88427b2bcd13ec375ef519e9ad1ccffef9f02a7b) Thanks [@dan1kov](https://github.com/dan1kov)! - Added `rdns` property to Coinbase Wallet v3 connector + +- [#4605](https://github.com/wevm/wagmi/pull/4605) [`3f8b2edc4f237cccff1009bcef03d51ca27a7324`](https://github.com/wevm/wagmi/commit/3f8b2edc4f237cccff1009bcef03d51ca27a7324) Thanks [@chybisov](https://github.com/chybisov)! - Bumped `@safe-global/safe-apps-provider` version to `0.18.6`. + +- Updated dependencies [[`799ee4d4b23c2ecd64e3f3668e67634e81939719`](https://github.com/wevm/wagmi/commit/799ee4d4b23c2ecd64e3f3668e67634e81939719)]: + - @wagmi/core@2.17.0 + +## 5.7.12 + +### Patch Changes + +- [#4608](https://github.com/wevm/wagmi/pull/4608) [`b59c024b23c69f5459b17390531207cfdf126ce4`](https://github.com/wevm/wagmi/commit/b59c024b23c69f5459b17390531207cfdf126ce4) Thanks [@jxom](https://github.com/jxom)! - Updated `@walletconnect/ethereum-provider`. + +## 5.7.11 + +### Patch Changes + +- Updated dependencies [[`a4bd0623eed28e3761a27295831a60ad835f0ee0`](https://github.com/wevm/wagmi/commit/a4bd0623eed28e3761a27295831a60ad835f0ee0)]: + - @wagmi/core@2.16.7 + +## 5.7.10 + +### Patch Changes + +- [#4573](https://github.com/wevm/wagmi/pull/4573) [`e944812ebc234a72c1417b77cff341166f5e0fef`](https://github.com/wevm/wagmi/commit/e944812ebc234a72c1417b77cff341166f5e0fef) Thanks [@ganchoradkov](https://github.com/ganchoradkov)! - updated `@walletconnect/ethereum-provider` to `2.19.1` + +- Updated dependencies [[`edf47477b2f6385a1c3ae01d36a8498c47f30a0b`](https://github.com/wevm/wagmi/commit/edf47477b2f6385a1c3ae01d36a8498c47f30a0b)]: + - @wagmi/core@2.16.6 + +## 5.7.9 + +### Patch Changes + +- [#4571](https://github.com/wevm/wagmi/pull/4571) [`5b7101fddb61df56e34b2e02b46bc409e496eaf9`](https://github.com/wevm/wagmi/commit/5b7101fddb61df56e34b2e02b46bc409e496eaf9) Thanks [@ganchoradkov](https://github.com/ganchoradkov)! - Updated `@walletconnect/ethereum-provider` to `2.19.0` + +## 5.7.8 + +### Patch Changes + +- Updated dependencies [[`d0c9a86921a4e939373cc6e763284e53f2a2e93c`](https://github.com/wevm/wagmi/commit/d0c9a86921a4e939373cc6e763284e53f2a2e93c)]: + - @wagmi/core@2.16.5 + +## 5.7.7 + +### Patch Changes + +- [`507f864d91238bfd423d0e36d3619eb9f6e52eec`](https://github.com/wevm/wagmi/commit/507f864d91238bfd423d0e36d3619eb9f6e52eec) Thanks [@jxom](https://github.com/jxom)! - Updated `@coinbase/wallet-sdk`. + +- Updated dependencies [[`507f864d91238bfd423d0e36d3619eb9f6e52eec`](https://github.com/wevm/wagmi/commit/507f864d91238bfd423d0e36d3619eb9f6e52eec)]: + - @wagmi/core@2.16.4 + +## 5.7.6 + +### Patch Changes + +- [#4524](https://github.com/wevm/wagmi/pull/4524) [`639952c97f0fe3927106f42d3c9f7f366cdf7f7a`](https://github.com/wevm/wagmi/commit/639952c97f0fe3927106f42d3c9f7f366cdf7f7a) Thanks [@chakra-guy](https://github.com/chakra-guy)! - Updated MetaMask SDK. + +- [#4525](https://github.com/wevm/wagmi/pull/4525) [`5aa2c095f7bfb6dfcf91c6945c3e1f9c9dd05766`](https://github.com/wevm/wagmi/commit/5aa2c095f7bfb6dfcf91c6945c3e1f9c9dd05766) Thanks [@EdouardBougon](https://github.com/EdouardBougon)! - Added Phantom flag to Injected Connector. + +## 5.7.5 + +### Patch Changes + +- [#4512](https://github.com/wevm/wagmi/pull/4512) [`a257e8d4f97431a4af872cda1817b4ae17c7bbed`](https://github.com/wevm/wagmi/commit/a257e8d4f97431a4af872cda1817b4ae17c7bbed) Thanks [@EdouardBougon](https://github.com/EdouardBougon)! - Fixed MetaMask switchChain/addChain handling. + +## 5.7.4 + +### Patch Changes + +- [#4505](https://github.com/wevm/wagmi/pull/4505) [`c8a257e0f6d2ece013b873895c35769a8a804fdc`](https://github.com/wevm/wagmi/commit/c8a257e0f6d2ece013b873895c35769a8a804fdc) Thanks [@chakra-guy](https://github.com/chakra-guy)! - Bumped Metamask SDK Version (changes include [bug fixes and minor changes](https://github.com/MetaMask/metamask-sdk/pull/1194)). + +## 5.7.3 + +### Patch Changes + +- [#4480](https://github.com/wevm/wagmi/pull/4480) [`384a1d91597622eb59e1c05dc13ce25017c5b6d8`](https://github.com/wevm/wagmi/commit/384a1d91597622eb59e1c05dc13ce25017c5b6d8) Thanks [@RodeRickIsWatching](https://github.com/RodeRickIsWatching)! - Fixed invocation of default storage. + +- Updated dependencies [[`384a1d91597622eb59e1c05dc13ce25017c5b6d8`](https://github.com/wevm/wagmi/commit/384a1d91597622eb59e1c05dc13ce25017c5b6d8)]: + - @wagmi/core@2.16.3 + +## 5.7.2 + +### Patch Changes + +- [`012907032b532a438fce48f407470250cbc8f0c6`](https://github.com/wevm/wagmi/commit/012907032b532a438fce48f407470250cbc8f0c6) Thanks [@jxom](https://github.com/jxom)! - Fixed assignment in `getDefaultStorage`. + +- Updated dependencies [[`012907032b532a438fce48f407470250cbc8f0c6`](https://github.com/wevm/wagmi/commit/012907032b532a438fce48f407470250cbc8f0c6)]: + - @wagmi/core@2.16.2 + +## 5.7.1 + +### Patch Changes + +- [#4471](https://github.com/wevm/wagmi/pull/4471) [`9c8c35a3b829f2c58edcd3a29e2dcd99974d7470`](https://github.com/wevm/wagmi/commit/9c8c35a3b829f2c58edcd3a29e2dcd99974d7470) Thanks [@EdouardBougon](https://github.com/EdouardBougon)! - Improved MetaMask chain switching behavior. + +- Updated dependencies [[`3892ebd21c06beef4b28ece4e70d2a38807bce6f`](https://github.com/wevm/wagmi/commit/3892ebd21c06beef4b28ece4e70d2a38807bce6f)]: + - @wagmi/core@2.16.1 + +## 5.7.0 + +### Minor Changes + +- [#4440](https://github.com/wevm/wagmi/pull/4440) [`e3f63a02c1f7d80481804584f262bc98dab0400d`](https://github.com/wevm/wagmi/commit/e3f63a02c1f7d80481804584f262bc98dab0400d) Thanks [@johanneskares](https://github.com/johanneskares)! - Added Coinbase Smart Wallet "Instant Onboarding" mode to `coinbaseWallet`. + +## 5.6.2 + +### Patch Changes + +- [#4437](https://github.com/wevm/wagmi/pull/4437) [`adf2253b10c6d4fc583e4bc9f01a8ef5ca267c85`](https://github.com/wevm/wagmi/commit/adf2253b10c6d4fc583e4bc9f01a8ef5ca267c85) Thanks [@chybisov](https://github.com/chybisov)! - Bumped `@safe-global/safe-apps-provider` version to `0.18.5`. + +## 5.6.1 + +### Patch Changes + +- [#4458](https://github.com/wevm/wagmi/pull/4458) [`987404f590c1d29ebb3cb68928f5e54aa032793d`](https://github.com/wevm/wagmi/commit/987404f590c1d29ebb3cb68928f5e54aa032793d) Thanks [@EdouardBougon](https://github.com/EdouardBougon)! - Fixed MetaMask internal metadata handling. + +## 5.6.0 + +### Minor Changes + +- [#4453](https://github.com/wevm/wagmi/pull/4453) [`070e48480194c8d7f45bda1d7dd1346e6f5d7227`](https://github.com/wevm/wagmi/commit/070e48480194c8d7f45bda1d7dd1346e6f5d7227) Thanks [@tmm](https://github.com/tmm)! - Added narrowing to `config.connectors`. + +### Patch Changes + +- [#4456](https://github.com/wevm/wagmi/pull/4456) [`8b0726c1106fce88b782e676498eabf0718b2619`](https://github.com/wevm/wagmi/commit/8b0726c1106fce88b782e676498eabf0718b2619) Thanks [@EdouardBougon](https://github.com/EdouardBougon)! - Bumped MetaMask SDK and fixed internal metadata handling. +- Updated dependencies [[`afea6b67822a7a2b96901ec851441d27ee0f7a52`](https://github.com/wevm/wagmi/commit/afea6b67822a7a2b96901ec851441d27ee0f7a52), [`070e48480194c8d7f45bda1d7dd1346e6f5d7227`](https://github.com/wevm/wagmi/commit/070e48480194c8d7f45bda1d7dd1346e6f5d7227)]: + - @wagmi/core@2.16.0 + +## 5.5.3 + +### Patch Changes + +- [#4433](https://github.com/wevm/wagmi/pull/4433) [`06e186cd679b27fe195309110e766fcf46d4efbc`](https://github.com/wevm/wagmi/commit/06e186cd679b27fe195309110e766fcf46d4efbc) Thanks [@Aerilym](https://github.com/Aerilym)! - Bumped Metamask SDK version to `0.31.1`. + +- Updated dependencies [[`06e186cd679b27fe195309110e766fcf46d4efbc`](https://github.com/wevm/wagmi/commit/06e186cd679b27fe195309110e766fcf46d4efbc)]: + - @wagmi/core@2.15.2 + +## 5.5.2 + +### Patch Changes + +- [#4422](https://github.com/wevm/wagmi/pull/4422) [`e563ef69130a511fd6f3f72ed4cd4fbe1390541f`](https://github.com/wevm/wagmi/commit/e563ef69130a511fd6f3f72ed4cd4fbe1390541f) Thanks [@abretonc7s](https://github.com/abretonc7s)! - Bumped MetaMask SDK. + +## 5.5.1 + +### Patch Changes + +- Updated dependencies [[`b8bbb409f4934538e3dd6cac5aaf7346292d0693`](https://github.com/wevm/wagmi/commit/b8bbb409f4934538e3dd6cac5aaf7346292d0693)]: + - @wagmi/core@2.15.1 + +## 5.5.0 + +### Minor Changes + +- [#4417](https://github.com/wevm/wagmi/pull/4417) [`42e65ea4fea99c639817088bba915e0933d17141`](https://github.com/wevm/wagmi/commit/42e65ea4fea99c639817088bba915e0933d17141) Thanks [@jxom](https://github.com/jxom)! - Removed simulation in `writeContract` & `sendTransaction`. + +### Patch Changes + +- Updated dependencies [[`42e65ea4fea99c639817088bba915e0933d17141`](https://github.com/wevm/wagmi/commit/42e65ea4fea99c639817088bba915e0933d17141)]: + - @wagmi/core@2.15.0 + +## 5.4.0 + +### Minor Changes + +- [#4409](https://github.com/wevm/wagmi/pull/4409) [`7ca62b44cd997d48f92c2b81343726a5908aa00b`](https://github.com/wevm/wagmi/commit/7ca62b44cd997d48f92c2b81343726a5908aa00b) Thanks [@fan-zhang-sv](https://github.com/fan-zhang-sv)! - Added `preference` object for Coinbase Wallet connector. + +## 5.3.10 + +### Patch Changes + +- [#4406](https://github.com/wevm/wagmi/pull/4406) [`a13aa8d7c38eb3cc8171a02d6302e6d12cf6bcb3`](https://github.com/wevm/wagmi/commit/a13aa8d7c38eb3cc8171a02d6302e6d12cf6bcb3) Thanks [@tmm](https://github.com/tmm)! - Added additional RDNS to MetaMask Connector. + +- Updated dependencies [[`a13aa8d7c38eb3cc8171a02d6302e6d12cf6bcb3`](https://github.com/wevm/wagmi/commit/a13aa8d7c38eb3cc8171a02d6302e6d12cf6bcb3)]: + - @wagmi/core@2.14.6 + +## 5.3.9 + +### Patch Changes + +- [`b12a04eeec985c48d2feac94b011d41fb29ca23e`](https://github.com/wevm/wagmi/commit/b12a04eeec985c48d2feac94b011d41fb29ca23e) Thanks [@tmm](https://github.com/tmm)! - Bumped Coinbase Wallet SDK version. + +## 5.3.8 + +### Patch Changes + +- [#4390](https://github.com/wevm/wagmi/pull/4390) [`dac62dc99a0679fa632a0fae49873d6053d06b35`](https://github.com/wevm/wagmi/commit/dac62dc99a0679fa632a0fae49873d6053d06b35) Thanks [@chybisov](https://github.com/chybisov)! - Bumped Safe Apps Provider version. + +- Updated dependencies [[`6b9bbacdc7bffd44fc2165362a5e65fd434e7646`](https://github.com/wevm/wagmi/commit/6b9bbacdc7bffd44fc2165362a5e65fd434e7646)]: + - @wagmi/core@2.14.5 + +## 5.3.7 + +### Patch Changes + +- Updated dependencies [[`e08681c81fbdf475213e2d0f4c5517d0abf4e743`](https://github.com/wevm/wagmi/commit/e08681c81fbdf475213e2d0f4c5517d0abf4e743)]: + - @wagmi/core@2.14.4 + +## 5.3.6 + +### Patch Changes + +- [#4385](https://github.com/wevm/wagmi/pull/4385) [`7558ff3133c11bc4c49473d08ee9a47eaa12df5b`](https://github.com/wevm/wagmi/commit/7558ff3133c11bc4c49473d08ee9a47eaa12df5b) Thanks [@cb-jake](https://github.com/cb-jake)! - Bumped Coinbase Wallet SDK version. + +## 5.3.5 + +### Patch Changes + +- [`7fe78f2d09778fc01fd0cffe85ba198e64999275`](https://github.com/wevm/wagmi/commit/7fe78f2d09778fc01fd0cffe85ba198e64999275) Thanks [@tmm](https://github.com/tmm)! - Fixed MetaMask connector not returning provider in some cases. + +- Updated dependencies [[`cb7dd2ebb871d0be8f1a11a8cd8ce592cd74b7c7`](https://github.com/wevm/wagmi/commit/cb7dd2ebb871d0be8f1a11a8cd8ce592cd74b7c7)]: + - @wagmi/core@2.14.3 + +## 5.3.4 + +### Patch Changes + +- [#4371](https://github.com/wevm/wagmi/pull/4371) [`b6861a4c378dab78d8751ae0ac2aa425f3c24b8f`](https://github.com/wevm/wagmi/commit/b6861a4c378dab78d8751ae0ac2aa425f3c24b8f) Thanks [@iceanddust](https://github.com/iceanddust)! - Fixed Safe connector not working in some Vite apps + +- Updated dependencies [[`d0d0963bb5904a15cf0355862d62dd141ce0c31c`](https://github.com/wevm/wagmi/commit/d0d0963bb5904a15cf0355862d62dd141ce0c31c), [`ecac0ba36243d94c9199d0bd21937104c835d9a0`](https://github.com/wevm/wagmi/commit/ecac0ba36243d94c9199d0bd21937104c835d9a0)]: + - @wagmi/core@2.14.2 + +## 5.3.3 + +### Patch Changes + +- [#4362](https://github.com/wevm/wagmi/pull/4362) [`83c6d16b7d6dddfa6bda036e04f00ec313c6248c`](https://github.com/wevm/wagmi/commit/83c6d16b7d6dddfa6bda036e04f00ec313c6248c) Thanks [@EdouardBougon](https://github.com/EdouardBougon)! - Fixed MetaMask connector internal logic. + +## 5.3.2 + +### Patch Changes + +- [#4357](https://github.com/wevm/wagmi/pull/4357) [`8970cc51398e1ac713435533096215c6d31ffdf9`](https://github.com/wevm/wagmi/commit/8970cc51398e1ac713435533096215c6d31ffdf9) Thanks [@tmm](https://github.com/tmm)! - Bumped dependencies. + +## 5.3.1 + +### Patch Changes + +- Updated dependencies [[`052e72e1f8c1c14fcbdce04a9f8fa7ec28d83702`](https://github.com/wevm/wagmi/commit/052e72e1f8c1c14fcbdce04a9f8fa7ec28d83702), [`b250fc21ee577b2a75c5a34ff684f62fb4ad771a`](https://github.com/wevm/wagmi/commit/b250fc21ee577b2a75c5a34ff684f62fb4ad771a)]: + - @wagmi/core@2.14.1 + +## 5.3.0 + +### Minor Changes + +- [#4343](https://github.com/wevm/wagmi/pull/4343) [`f43e074f473820b208a6295d7c97f847332f1a1d`](https://github.com/wevm/wagmi/commit/f43e074f473820b208a6295d7c97f847332f1a1d) Thanks [@tmm](https://github.com/tmm)! - Added `rdns` property to connector interface. This is used to filter out duplicate [EIP-6963](https://eips.ethereum.org/EIPS/eip-6963) injected providers when [`createConfig#multiInjectedProviderDiscovery`](https://wagmi.sh/core/api/createConfig#multiinjectedproviderdiscovery) is enabled and `createConfig#connectors` already matches EIP-6963 providers' `rdns` property. + +### Patch Changes + +- Updated dependencies [[`f43e074f473820b208a6295d7c97f847332f1a1d`](https://github.com/wevm/wagmi/commit/f43e074f473820b208a6295d7c97f847332f1a1d)]: + - @wagmi/core@2.14.0 + +## 5.2.2 + +### Patch Changes + +- [#4347](https://github.com/wevm/wagmi/pull/4347) [`5ae49af590ff168426c9c283d54c34ae5148fcd9`](https://github.com/wevm/wagmi/commit/5ae49af590ff168426c9c283d54c34ae5148fcd9) Thanks [@EdouardBougon](https://github.com/EdouardBougon)! - Added workaround for MetaMask mobile sometimes disconnecting. + +- [#4350](https://github.com/wevm/wagmi/pull/4350) [`f3182b22e6e454d9bd74f1b940ef34431fd9555d`](https://github.com/wevm/wagmi/commit/f3182b22e6e454d9bd74f1b940ef34431fd9555d) Thanks [@abretonc7s](https://github.com/abretonc7s)! - Updated MetaMask SDK. + +- Updated dependencies [[`c05caabc20c3ced9682cfc7ba1f3f7dcfece0703`](https://github.com/wevm/wagmi/commit/c05caabc20c3ced9682cfc7ba1f3f7dcfece0703)]: + - @wagmi/core@2.13.9 + +## 5.2.1 + +### Patch Changes + +- [#4345](https://github.com/wevm/wagmi/pull/4345) [`91a40f2db08e3a91db421b8732a5511a1e6c88fd`](https://github.com/wevm/wagmi/commit/91a40f2db08e3a91db421b8732a5511a1e6c88fd) Thanks [@tmm](https://github.com/tmm)! - Bumped MetaMask SDK. + +## 5.2.0 + +### Minor Changes + +- [#4337](https://github.com/wevm/wagmi/pull/4337) [`34a0c3b7eea778aee7c27f7ace5e4b2be4e8a0a4`](https://github.com/wevm/wagmi/commit/34a0c3b7eea778aee7c27f7ace5e4b2be4e8a0a4) Thanks [@tmm](https://github.com/tmm)! - Added "Connect and Sign" behavior to MetaMask Connector. + +## 5.1.15 + +### Patch Changes + +- [`3b2123664b7ac66848390739e855c3b9702ab60c`](https://github.com/wevm/wagmi/commit/3b2123664b7ac66848390739e855c3b9702ab60c) Thanks [@tmm](https://github.com/tmm)! - Bumped WalletConnect Provider. + +## 5.1.14 + +### Patch Changes + +- [#4207](https://github.com/wevm/wagmi/pull/4207) [`56f2482508f2ba71bd6b0295c70c6abca7101e57`](https://github.com/wevm/wagmi/commit/56f2482508f2ba71bd6b0295c70c6abca7101e57) Thanks [@Smert](https://github.com/Smert)! - Updated chain switch listener for `injected` and `metaMask` to be more robust. + +- Updated dependencies [[`56f2482508f2ba71bd6b0295c70c6abca7101e57`](https://github.com/wevm/wagmi/commit/56f2482508f2ba71bd6b0295c70c6abca7101e57)]: + - @wagmi/core@2.13.8 + +## 5.1.13 + +### Patch Changes + +- Updated dependencies [[`be75c2d4ef636d7362420ab0a106bfdf63f5d1e6`](https://github.com/wevm/wagmi/commit/be75c2d4ef636d7362420ab0a106bfdf63f5d1e6)]: + - @wagmi/core@2.13.7 + +## 5.1.12 + +### Patch Changes + +- Updated dependencies [[`edcbf5d6fbe92f639bead800502edda9e0aa39f1`](https://github.com/wevm/wagmi/commit/edcbf5d6fbe92f639bead800502edda9e0aa39f1)]: + - @wagmi/core@2.13.6 + +## 5.1.11 + +### Patch Changes + +- [#4271](https://github.com/wevm/wagmi/pull/4271) [`82404c960e04c83e0bae6e1e12459ef9debf9554`](https://github.com/wevm/wagmi/commit/82404c960e04c83e0bae6e1e12459ef9debf9554) Thanks [@omridan159](https://github.com/omridan159)! - Bumped MetaMask SDK. + +- [#4227](https://github.com/wevm/wagmi/pull/4227) [`d07ad7f63a018256908a673d078aaf79e47ac703`](https://github.com/wevm/wagmi/commit/d07ad7f63a018256908a673d078aaf79e47ac703) Thanks [@xianchenxc](https://github.com/xianchenxc)! - Fixed MetaMask Connector throwing error after switching to a chain that was just added via `'wallet_addEthereumChain'`. + +## 5.1.10 + +### Patch Changes + +- [#4255](https://github.com/wevm/wagmi/pull/4255) [`81de006e66121a18c61945c1f9b8426c83a5713c`](https://github.com/wevm/wagmi/commit/81de006e66121a18c61945c1f9b8426c83a5713c) Thanks [@tomiir](https://github.com/tomiir)! - Bumped `@walletconnect/ethereum-provider` from version `2.15.3` to version `2.16.1`. + +- Updated dependencies [[`f47ce8f6d263e49fdff90b8edb3190142d2657bb`](https://github.com/wevm/wagmi/commit/f47ce8f6d263e49fdff90b8edb3190142d2657bb)]: + - @wagmi/core@2.13.5 + +## 5.1.9 + +### Patch Changes + +- [#4243](https://github.com/wevm/wagmi/pull/4243) [`21bd0e473d374cbbd7a01bececa6022d529026ba`](https://github.com/wevm/wagmi/commit/21bd0e473d374cbbd7a01bececa6022d529026ba) Thanks [@tomiir](https://github.com/tomiir)! - Bumped `@walletconnect/ethereum-provider` from version `2.15.2` to version `2.15.3` + +- [#4251](https://github.com/wevm/wagmi/pull/4251) [`5c89c6853e616437a3be2b019db895451fecfb3c`](https://github.com/wevm/wagmi/commit/5c89c6853e616437a3be2b019db895451fecfb3c) Thanks [@tmm](https://github.com/tmm)! - Bumped MM SDK. + +## 5.1.8 + +### Patch Changes + +- [`b580ad4edff1721e0b9d138cf5ae2ec74d2374c7`](https://github.com/wevm/wagmi/commit/b580ad4edff1721e0b9d138cf5ae2ec74d2374c7) Thanks [@tmm](https://github.com/tmm)! - Bumped WalletConnect Provider. + +## 5.1.7 + +### Patch Changes + +- [#4213](https://github.com/wevm/wagmi/pull/4213) [`91fd81a068789c5020e891f539bcad8f54a7a52f`](https://github.com/wevm/wagmi/commit/91fd81a068789c5020e891f539bcad8f54a7a52f) Thanks [@tomiir](https://github.com/tomiir)! - Updated `@walletconnect/ethereum-provider` from version `2.15.0` to version `2.15.1`. + +## 5.1.6 + +### Patch Changes + +- [#4208](https://github.com/wevm/wagmi/pull/4208) [`3168616298cbb6135d0ffda771cba4126e83eba8`](https://github.com/wevm/wagmi/commit/3168616298cbb6135d0ffda771cba4126e83eba8) Thanks [@tomiir](https://github.com/tomiir)! - Updated WalletConnect Ethereum Provider version from `2.14.0` to `2.15.0`. + +- [#4211](https://github.com/wevm/wagmi/pull/4211) [`d7608ef9a79459465dc8c06a2ab740465c881907`](https://github.com/wevm/wagmi/commit/d7608ef9a79459465dc8c06a2ab740465c881907) Thanks [@tmm](https://github.com/tmm)! - Added default name for MetaMask Connector. + +## 5.1.5 + +### Patch Changes + +- Updated dependencies [[`b4c8971788c70b09479946ecfa998cff2f1b3953`](https://github.com/wevm/wagmi/commit/b4c8971788c70b09479946ecfa998cff2f1b3953)]: + - @wagmi/core@2.13.4 + +## 5.1.4 + +### Patch Changes + +- Updated dependencies [[`871dbdbfe59ac8ad01d1ec6150ea7b091b7b7de4`](https://github.com/wevm/wagmi/commit/871dbdbfe59ac8ad01d1ec6150ea7b091b7b7de4)]: + - @wagmi/core@2.13.3 + +## 5.1.3 + +### Patch Changes + +- Updated dependencies [[`1b9b523fa9b9dfe839aecdf4b40caa9547d7e594`](https://github.com/wevm/wagmi/commit/1b9b523fa9b9dfe839aecdf4b40caa9547d7e594)]: + - @wagmi/core@2.13.2 + +## 5.1.2 + +### Patch Changes + +- [`abb490dac4f0f02f46cb0878e7ca9a0db6aada56`](https://github.com/wevm/wagmi/commit/abb490dac4f0f02f46cb0878e7ca9a0db6aada56) Thanks [@tmm](https://github.com/tmm)! - Bumped MetaMask SDK version. + +- [`28e0e5c9a4f856583f9d36a807502bd51a0c6ec2`](https://github.com/wevm/wagmi/commit/28e0e5c9a4f856583f9d36a807502bd51a0c6ec2) Thanks [@tmm](https://github.com/tmm)! - Bumped WalletConnect Ethereum Provider version. + +## 5.1.1 + +### Patch Changes + +- Updated dependencies [[`07c1227f306d0efb9421d4bb77a774f92f5fcf45`](https://github.com/wevm/wagmi/commit/07c1227f306d0efb9421d4bb77a774f92f5fcf45)]: + - @wagmi/core@2.13.1 + +## 5.1.0 + +### Minor Changes + +- [#4162](https://github.com/wevm/wagmi/pull/4162) [`a73a7737b756886b388f120ae423e72cca53e8a0`](https://github.com/wevm/wagmi/commit/a73a7737b756886b388f120ae423e72cca53e8a0) Thanks [@jxom](https://github.com/jxom)! - Added functionality for consumer-defined RPC URLs (`config.transports`) to be propagated to the WalletConnect & MetaMask Connectors. + +### Patch Changes + +- Updated dependencies [[`a73a7737b756886b388f120ae423e72cca53e8a0`](https://github.com/wevm/wagmi/commit/a73a7737b756886b388f120ae423e72cca53e8a0)]: + - @wagmi/core@2.13.0 + +## 5.0.26 + +### Patch Changes + +- [`8d81df5cc884d0a210dedd3c1ea0e2e9e52b83c5`](https://github.com/wevm/wagmi/commit/8d81df5cc884d0a210dedd3c1ea0e2e9e52b83c5) Thanks [@tmm](https://github.com/tmm)! - Fixed `metaMask` connector switch chain issue. + +- Updated dependencies [[`5bc8c8877810b2eec24a829df87dce40a51e6f20`](https://github.com/wevm/wagmi/commit/5bc8c8877810b2eec24a829df87dce40a51e6f20)]: + - @wagmi/core@2.12.2 + +## 5.0.25 + +### Patch Changes + +- [#4146](https://github.com/wevm/wagmi/pull/4146) [`cc996e08e930c9e88cf753a1e874652059e81a3b`](https://github.com/wevm/wagmi/commit/cc996e08e930c9e88cf753a1e874652059e81a3b) Thanks [@jxom](https://github.com/jxom)! - Updated `@safe-global/safe-apps-sdk` + `@safe-global/safe-apps-provider` dependencies. + +- Updated dependencies [[`cc996e08e930c9e88cf753a1e874652059e81a3b`](https://github.com/wevm/wagmi/commit/cc996e08e930c9e88cf753a1e874652059e81a3b)]: + - @wagmi/core@2.12.1 + +## 5.0.24 + +### Patch Changes + +- Updated dependencies [[`5581a810ef70308e99c6f8b630cd4bca59f64afc`](https://github.com/wevm/wagmi/commit/5581a810ef70308e99c6f8b630cd4bca59f64afc)]: + - @wagmi/core@2.12.0 + +## 5.0.23 + +### Patch Changes + +- [`d3814ab4b88f9f0e052b53bc3d458df87b43f01d`](https://github.com/wevm/wagmi/commit/d3814ab4b88f9f0e052b53bc3d458df87b43f01d) Thanks [@jxom](https://github.com/jxom)! - Updated `mipd` dependency. + +- Updated dependencies [[`b08013eaa9ce97c02f8a7128ea400e3da7ef74bb`](https://github.com/wevm/wagmi/commit/b08013eaa9ce97c02f8a7128ea400e3da7ef74bb), [`d3814ab4b88f9f0e052b53bc3d458df87b43f01d`](https://github.com/wevm/wagmi/commit/d3814ab4b88f9f0e052b53bc3d458df87b43f01d)]: + - @wagmi/core@2.11.8 + +## 5.0.22 + +### Patch Changes + +- [`0bb8b562ae04ecfeb2d6b2f1b980ebae31dc127e`](https://github.com/wevm/wagmi/commit/0bb8b562ae04ecfeb2d6b2f1b980ebae31dc127e) Thanks [@tmm](https://github.com/tmm)! - Improved TypeScript `'exactOptionalPropertyTypes'` support. + +- Updated dependencies [[`0bb8b562ae04ecfeb2d6b2f1b980ebae31dc127e`](https://github.com/wevm/wagmi/commit/0bb8b562ae04ecfeb2d6b2f1b980ebae31dc127e)]: + - @wagmi/core@2.11.7 + +## 5.0.21 + +### Patch Changes + +- [#4094](https://github.com/wevm/wagmi/pull/4094) [`ff0760b5900114bcfdf420a9fba3cc278ac95afe`](https://github.com/wevm/wagmi/commit/ff0760b5900114bcfdf420a9fba3cc278ac95afe) Thanks [@omridan159](https://github.com/omridan159)! - Bumped MetaMask SDK to fix `metaMask` connector error bubbling. + +- Updated dependencies [[`95965c1f19d480b97f2b297a077a9e607dee32ad`](https://github.com/wevm/wagmi/commit/95965c1f19d480b97f2b297a077a9e607dee32ad)]: + - @wagmi/core@2.11.6 + +## 5.0.20 + +### Patch Changes + +- [`43fa971d34cac57fa5a2898ad4d839b95d7af37c`](https://github.com/wevm/wagmi/commit/43fa971d34cac57fa5a2898ad4d839b95d7af37c) Thanks [@tmm](https://github.com/tmm)! - Bumped Coinbase Wallet SDK and fixed `metaMask` connector hang on mobile. + +## 5.0.19 + +### Patch Changes + +- [#4083](https://github.com/wevm/wagmi/pull/4083) [`b7ad208030d9f2e3f89912ff76b16cdbd848feda`](https://github.com/wevm/wagmi/commit/b7ad208030d9f2e3f89912ff76b16cdbd848feda) Thanks [@omridan159](https://github.com/omridan159)! - Bumped MetaMask SDK + +## 5.0.18 + +### Patch Changes + +- [#4081](https://github.com/wevm/wagmi/pull/4081) [`44d24620c9e3957f3245d14d6a042736371df70b`](https://github.com/wevm/wagmi/commit/44d24620c9e3957f3245d14d6a042736371df70b) Thanks [@tmm](https://github.com/tmm)! - Bumped MetaMask SDK + +## 5.0.17 + +### Patch Changes + +- Updated dependencies [[`04f2b846b113f3d300d82c9fa75212f1805817c5`](https://github.com/wevm/wagmi/commit/04f2b846b113f3d300d82c9fa75212f1805817c5)]: + - @wagmi/core@2.11.5 + +## 5.0.16 + +### Patch Changes + +- [#4071](https://github.com/wevm/wagmi/pull/4071) [`02c38c28d1aa0ad7a61c33775de603ed974c5c1b`](https://github.com/wevm/wagmi/commit/02c38c28d1aa0ad7a61c33775de603ed974c5c1b) Thanks [@omridan159](https://github.com/omridan159)! - Bumped MetaMask SDK + +- Updated dependencies [[`9e8345cd56186b997b5e56deaa2cfc69b30d15f6`](https://github.com/wevm/wagmi/commit/9e8345cd56186b997b5e56deaa2cfc69b30d15f6)]: + - @wagmi/core@2.11.4 + +## 5.0.15 + +### Patch Changes + +- Updated dependencies [[`8974e6269bb5d7bfaa90db0246bc7d13e8bff798`](https://github.com/wevm/wagmi/commit/8974e6269bb5d7bfaa90db0246bc7d13e8bff798)]: + - @wagmi/core@2.11.3 + +## 5.0.14 + +### Patch Changes + +- Updated dependencies [[`b4d9ef79deb554ee20fed6666a474be5e7cdd522`](https://github.com/wevm/wagmi/commit/b4d9ef79deb554ee20fed6666a474be5e7cdd522)]: + - @wagmi/core@2.11.2 + +## 5.0.13 + +### Patch Changes + +- [`9c862d8d63e3d692a22cef2a90782b74a9103f17`](https://github.com/wevm/wagmi/commit/9c862d8d63e3d692a22cef2a90782b74a9103f17) Thanks [@tmm](https://github.com/tmm)! - Reverted internal module loading utility. + +- Updated dependencies [[`9c862d8d63e3d692a22cef2a90782b74a9103f17`](https://github.com/wevm/wagmi/commit/9c862d8d63e3d692a22cef2a90782b74a9103f17)]: + - @wagmi/core@2.11.1 + +## 5.0.12 + +### Patch Changes + +- Updated dependencies [[`06bb598a7f04c7b167f5b7ff6d46bd15886a6a14`](https://github.com/wevm/wagmi/commit/06bb598a7f04c7b167f5b7ff6d46bd15886a6a14), [`24a45b269bd0214a29d6f82a84ac66ef8c3f3822`](https://github.com/wevm/wagmi/commit/24a45b269bd0214a29d6f82a84ac66ef8c3f3822)]: + - @wagmi/core@2.11.0 + +## 5.0.11 + +### Patch Changes + +- [#4020](https://github.com/wevm/wagmi/pull/4020) [`e3b124ce414b8fd1b2214e2c5a28dc72158a13d1`](https://github.com/wevm/wagmi/commit/e3b124ce414b8fd1b2214e2c5a28dc72158a13d1) Thanks [@tmm](https://github.com/tmm)! - Added reconnection support to `metaMask` on mobile and use deeplinks by default. + +- Updated dependencies [[`f2a7cefab96691ebed8b8e45ffde071c47b58dbe`](https://github.com/wevm/wagmi/commit/f2a7cefab96691ebed8b8e45ffde071c47b58dbe), [`f0ea0b2a7fe193dadfeb49a4c8031ee451c638b5`](https://github.com/wevm/wagmi/commit/f0ea0b2a7fe193dadfeb49a4c8031ee451c638b5)]: + - @wagmi/core@2.10.6 + +## 5.0.10 + +### Patch Changes + +- [`560952acd4bfe33db6c7c07b35c613cef278677c`](https://github.com/wevm/wagmi/commit/560952acd4bfe33db6c7c07b35c613cef278677c) Thanks [@tmm](https://github.com/tmm)! - Captured Coinbase Smart Wallet error when closing window as EIP-1193 `4001` error. + +## 5.0.9 + +### Patch Changes + +- [`32cdd7b7dc5aff916c040628519562c3a99d418d`](https://github.com/wevm/wagmi/commit/32cdd7b7dc5aff916c040628519562c3a99d418d) Thanks [@tmm](https://github.com/tmm)! - Bumped `@metamask/sdk` to remove peer dependency install warning. + +## 5.0.8 + +### Patch Changes + +- [#3997](https://github.com/wevm/wagmi/pull/3997) [`c1952d1ff7f0a491dc88595a49159451b07b5621`](https://github.com/wevm/wagmi/commit/c1952d1ff7f0a491dc88595a49159451b07b5621) Thanks [@nateReiners](https://github.com/nateReiners)! - Bumped Coinbase Wallet SDK. + +## 5.0.7 + +### Patch Changes + +- Updated dependencies [[`030c7c2cb380dfd67a2182f62e2aa7a6e1601898`](https://github.com/wevm/wagmi/commit/030c7c2cb380dfd67a2182f62e2aa7a6e1601898)]: + - @wagmi/core@2.10.5 + +## 5.0.6 + +### Patch Changes + +- Updated dependencies [[`51fde8a0433b4fff357c1a8d7e08b41b4c86c968`](https://github.com/wevm/wagmi/commit/51fde8a0433b4fff357c1a8d7e08b41b4c86c968)]: + - @wagmi/core@2.10.4 + +## 5.0.5 + +### Patch Changes + +- [#3979](https://github.com/wevm/wagmi/pull/3979) [`70dd28669dd8d2ce08217cd02e29a8fbba7a08d4`](https://github.com/wevm/wagmi/commit/70dd28669dd8d2ce08217cd02e29a8fbba7a08d4) Thanks [@tmm](https://github.com/tmm)! - Fixed `walletConnect` connector. + +## 5.0.4 + +### Patch Changes + +- [#3972](https://github.com/wevm/wagmi/pull/3972) [`be9e1b8a9818b92eb0654a20d9471e9e39329e7e`](https://github.com/wevm/wagmi/commit/be9e1b8a9818b92eb0654a20d9471e9e39329e7e) Thanks [@nateReiners](https://github.com/nateReiners)! - Bumped Coinbase Wallet SDK. + +## 5.0.3 + +### Patch Changes + +- [#3962](https://github.com/wevm/wagmi/pull/3962) [`2804a8a583b1874271154898b4bae38756ef581c`](https://github.com/wevm/wagmi/commit/2804a8a583b1874271154898b4bae38756ef581c) Thanks [@tmm](https://github.com/tmm)! - Added timeout to `getInfo` called in `safe` connector since [non-Safe App iFrames cause it to not resolve](https://github.com/safe-global/safe-apps-sdk/issues/263#issuecomment-1029835840). + +- Updated dependencies [[`2804a8a583b1874271154898b4bae38756ef581c`](https://github.com/wevm/wagmi/commit/2804a8a583b1874271154898b4bae38756ef581c)]: + - @wagmi/core@2.10.3 + +## 5.0.2 + +### Patch Changes + +- [#3940](https://github.com/wevm/wagmi/pull/3940) [`a5071f581dfdfb961718873643a2fc629101c72a`](https://github.com/wevm/wagmi/commit/a5071f581dfdfb961718873643a2fc629101c72a) Thanks [@jxom](https://github.com/jxom)! - Fixed usage of `metaMask` connector in Vite environments. + +- Updated dependencies [[`a5071f581dfdfb961718873643a2fc629101c72a`](https://github.com/wevm/wagmi/commit/a5071f581dfdfb961718873643a2fc629101c72a)]: + - @wagmi/core@2.10.2 + +## 5.0.1 + +### Patch Changes + +- Bumped versions. + +- Updated dependencies []: + - @wagmi/core@2.10.1 + +## 5.0.0 + +### Major Changes + +- [#3928](https://github.com/wevm/wagmi/pull/3928) [`3117e71825f9c58a0d718f3d1686f1a191fa9cb1`](https://github.com/wevm/wagmi/commit/3117e71825f9c58a0d718f3d1686f1a191fa9cb1) Thanks [@tmm](https://github.com/tmm)! - **Breaking:** Updated default Coinbase SDK in `coinbaseWallet` Connector to v4.x. + + Added a `version` property (defaults to `'4'`) to the `coinbaseWallet` Connector to target a version of the Coinbase SDK: + + ```diff + coinbaseWallet({ + + version: '3' | '4', + }) + ``` + + If `headlessMode` property is set to `true`, then the Connector will target v3 of the Coinbase SDK. + + The following properties are removed in v4 of the `coinbaseWallet` Connector: + + - `chainId` + - `darkMode` + - `diagnosticLogger` + - `enableMobileDeepLink` + - `jsonRpcUrl` + - `linkApiUrl` + - `overrideIsCoinbaseBrowser` + - `overrideIsCoinbaseWallet` + - `overrideIsMetaMask` + - `reloadOnDisconnect` + - `uiConstructor` + + Consumers can still use the above properties in v3 by passing `version: '3'` to the Connector. However, please note that v3 of the Coinbase SDK is deprecated and will be removed in a future release. + +### Patch Changes + +- Updated dependencies [[`3117e71825f9c58a0d718f3d1686f1a191fa9cb1`](https://github.com/wevm/wagmi/commit/3117e71825f9c58a0d718f3d1686f1a191fa9cb1)]: + - @wagmi/core@2.10.0 + +## 4.3.10 + +### Patch Changes + +- [#3906](https://github.com/wevm/wagmi/pull/3906) [`32fcb4a31dde6b0206961d8ffe9c651f8a459c67`](https://github.com/wevm/wagmi/commit/32fcb4a31dde6b0206961d8ffe9c651f8a459c67) Thanks [@tmm](https://github.com/tmm)! - Added support for Vue. + +- Updated dependencies [[`32fcb4a31dde6b0206961d8ffe9c651f8a459c67`](https://github.com/wevm/wagmi/commit/32fcb4a31dde6b0206961d8ffe9c651f8a459c67)]: + - @wagmi/core@2.9.8 + +## 4.3.9 + +### Patch Changes + +- [#3924](https://github.com/wevm/wagmi/pull/3924) [`1f58734f88458e0f6adb05c99f0c90f36ab286b8`](https://github.com/wevm/wagmi/commit/1f58734f88458e0f6adb05c99f0c90f36ab286b8) Thanks [@jxom](https://github.com/jxom)! - Refactored `isChainsStale` logic in `walletConnect` connector. + +- Updated dependencies [[`1f58734f88458e0f6adb05c99f0c90f36ab286b8`](https://github.com/wevm/wagmi/commit/1f58734f88458e0f6adb05c99f0c90f36ab286b8)]: + - @wagmi/core@2.9.7 + +## 4.3.8 + +### Patch Changes + +- [#3917](https://github.com/wevm/wagmi/pull/3917) [`05948fdad5bb4a56b08916d45b3dec2cb1e5f55b`](https://github.com/wevm/wagmi/commit/05948fdad5bb4a56b08916d45b3dec2cb1e5f55b) Thanks [@jxom](https://github.com/jxom)! - Updated `@metamask/sdk`. + +- Updated dependencies [[`05948fdad5bb4a56b08916d45b3dec2cb1e5f55b`](https://github.com/wevm/wagmi/commit/05948fdad5bb4a56b08916d45b3dec2cb1e5f55b)]: + - @wagmi/core@2.9.6 + +## 4.3.7 + +### Patch Changes + +- Updated dependencies [[`4fecbbb66d0aacd03b8c62a6455d11a33cde8f85`](https://github.com/wevm/wagmi/commit/4fecbbb66d0aacd03b8c62a6455d11a33cde8f85)]: + - @wagmi/core@2.9.5 + +## 4.3.6 + +### Patch Changes + +- Updated dependencies [[`e6139a97c4b8804d734b1547b5e3921ce01fbe24`](https://github.com/wevm/wagmi/commit/e6139a97c4b8804d734b1547b5e3921ce01fbe24)]: + - @wagmi/core@2.9.4 + +## 4.3.5 + +### Patch Changes + +- [#3904](https://github.com/wevm/wagmi/pull/3904) [`addca28ebc20f1a4367c35fe9ef786decff9c87e`](https://github.com/wevm/wagmi/commit/addca28ebc20f1a4367c35fe9ef786decff9c87e) Thanks [@jxom](https://github.com/jxom)! - Updated `@walletconnect/ethereum-provider`. + +- Updated dependencies [[`addca28ebc20f1a4367c35fe9ef786decff9c87e`](https://github.com/wevm/wagmi/commit/addca28ebc20f1a4367c35fe9ef786decff9c87e)]: + - @wagmi/core@2.9.3 + +## 4.3.4 + +### Patch Changes + +- [#3902](https://github.com/wevm/wagmi/pull/3902) [`204b7b624612405500ec098fb9e35facd3f74ca4`](https://github.com/wevm/wagmi/commit/204b7b624612405500ec098fb9e35facd3f74ca4) Thanks [@jxom](https://github.com/jxom)! - Made third-party SDK imports type-only. + +- Updated dependencies [[`204b7b624612405500ec098fb9e35facd3f74ca4`](https://github.com/wevm/wagmi/commit/204b7b624612405500ec098fb9e35facd3f74ca4)]: + - @wagmi/core@2.9.2 + +## 4.3.3 + +### Patch Changes + +- Updated dependencies [[`cda6a5d5`](https://github.com/wevm/wagmi/commit/cda6a5d56328330fbde050b4ef40b01c58d2519a)]: + - @wagmi/core@2.9.1 + +## 4.3.2 + +### Patch Changes + +- Updated dependencies [[`017828fc`](https://github.com/wevm/wagmi/commit/017828fc027c7a84b54ea9d627e9389f4d60d6c2)]: + - @wagmi/core@2.9.0 + +## 4.3.1 + +### Patch Changes + +- Updated dependencies [[`d4a78eb0`](https://github.com/wevm/wagmi/commit/d4a78eb07119d2e5617e52481ac7d6c6d1583ddc)]: + - @wagmi/core@2.8.1 + +## 4.3.0 + +### Minor Changes + +- [#3868](https://github.com/wevm/wagmi/pull/3868) [`c2af20b8`](https://github.com/wevm/wagmi/commit/c2af20b88cf16970d087faaec10b463357a5836e) Thanks [@jxom](https://github.com/jxom)! - Added `supportsSimulation` property to connectors that indicates if the connector's wallet supports contract simulation. + +### Patch Changes + +- Updated dependencies [[`0d141f17`](https://github.com/wevm/wagmi/commit/0d141f171d6ec44bcbfc9c876565b5e2fb8af6de), [`c2af20b8`](https://github.com/wevm/wagmi/commit/c2af20b88cf16970d087faaec10b463357a5836e)]: + - @wagmi/core@2.8.0 + +## 4.2.0 + +### Minor Changes + +- [#3857](https://github.com/wevm/wagmi/pull/3857) [`d4274c03`](https://github.com/wevm/wagmi/commit/d4274c03a6af5f2d26d31432016ebc14950a330e) Thanks [@tmm](https://github.com/tmm)! - Added `addEthereumChainParameter` to `switchChain`-related methods. + +### Patch Changes + +- Updated dependencies [[`d4274c03`](https://github.com/wevm/wagmi/commit/d4274c03a6af5f2d26d31432016ebc14950a330e), [`4781a405`](https://github.com/wevm/wagmi/commit/4781a4056d4ffc2c74f96a75429e9b2cd2417ad8), [`400c960b`](https://github.com/wevm/wagmi/commit/400c960b30d701c134850c695ae903a382c29b5b)]: + - @wagmi/core@2.7.0 + +## 4.1.28 + +### Patch Changes + +- [`e3c832a1`](https://github.com/wevm/wagmi/commit/e3c832a12c301f9b0ee129d877b3101d220ba8b2) Thanks [@jxom](https://github.com/jxom)! - Fixed undefined `navigator` issue in MetaMask connector. + +- Updated dependencies [[`e3c832a1`](https://github.com/wevm/wagmi/commit/e3c832a12c301f9b0ee129d877b3101d220ba8b2)]: + - @wagmi/core@2.6.19 + +## 4.1.27 + +### Patch Changes + +- [#3848](https://github.com/wevm/wagmi/pull/3848) [`dd40a41c`](https://github.com/wevm/wagmi/commit/dd40a41c526ab60a288aff2250ed8dba92a27b16) Thanks [@jxom](https://github.com/jxom)! - Updated MetaMask SDK. + +- Updated dependencies [[`dd40a41c`](https://github.com/wevm/wagmi/commit/dd40a41c526ab60a288aff2250ed8dba92a27b16)]: + - @wagmi/core@2.6.18 + +## 4.1.26 + +### Patch Changes + +- Updated dependencies [[`a97bfbae`](https://github.com/wevm/wagmi/commit/a97bfbaeb615cfef04665e5e7348d85d17f960f0)]: + - @wagmi/core@2.6.17 + +## 4.1.25 + +### Patch Changes + +- [#3788](https://github.com/wevm/wagmi/pull/3788) [`42ad380d`](https://github.com/wevm/wagmi/commit/42ad380d9a5d8bc0f61d73612142dea9d098de5e) Thanks [@tmm](https://github.com/tmm)! - Refactored connectors to remove unnecessarily event listeners. + +- Updated dependencies [[`42ad380d`](https://github.com/wevm/wagmi/commit/42ad380d9a5d8bc0f61d73612142dea9d098de5e)]: + - @wagmi/core@2.6.16 + +## 4.1.24 + +### Patch Changes + +- Updated dependencies [[`b907d5ac`](https://github.com/wevm/wagmi/commit/b907d5ac3a746bcbccc06d1fe78c5bd8f9a7d685)]: + - @wagmi/core@2.6.15 + +## 4.1.23 + +### Patch Changes + +- Updated dependencies [[`b3b54ef1`](https://github.com/wevm/wagmi/commit/b3b54ef179c5fa0d1694d38d4b808549a0550409), [`3da20bb8`](https://github.com/wevm/wagmi/commit/3da20bb80e7c3efeef8227ced66ad615370fc242), [`a3d1858f`](https://github.com/wevm/wagmi/commit/a3d1858fce448d2b70e36ee692ef1589b74e9d3f)]: + - @wagmi/core@2.6.14 + +## 4.1.22 + +### Patch Changes + +- Updated dependencies [[`b80236dc`](https://github.com/wevm/wagmi/commit/b80236dc623095fe8f1e1d10957d7776fb6ab48b)]: + - @wagmi/core@2.6.13 + +## 4.1.21 + +### Patch Changes + +- Updated dependencies [[`a59069e9`](https://github.com/wevm/wagmi/commit/a59069e9fab45dd606bb89a7f829fe94c51a5494), [`0acd3132`](https://github.com/wevm/wagmi/commit/0acd31320f534993af566be5490c2978b6184f66)]: + - @wagmi/core@2.6.12 + +## 4.1.20 + +### Patch Changes + +- [`e1ca4e63`](https://github.com/wevm/wagmi/commit/e1ca4e637ae6cec7f5902b0a2c0e0efc3b751a1d) Thanks [@tmm](https://github.com/tmm)! - Deprecated `normalizeChainId`. Use `Number` instead. + +- Updated dependencies [[`e1ca4e63`](https://github.com/wevm/wagmi/commit/e1ca4e637ae6cec7f5902b0a2c0e0efc3b751a1d)]: + - @wagmi/core@2.6.11 + +## 4.1.19 + +### Patch Changes + +- Updated dependencies [[`dbdca8fd`](https://github.com/wevm/wagmi/commit/dbdca8fd14b90c166222a66a373c1b33c06ce019)]: + - @wagmi/core@2.6.10 + +## 4.1.18 + +### Patch Changes + +- Updated dependencies [[`d56edf4f`](https://github.com/wevm/wagmi/commit/d56edf4f27c52acc7a0f57114454b0d3e22cacd6)]: + - @wagmi/core@2.6.9 + +## 4.1.17 + +### Patch Changes + +- Updated dependencies [[`e46bcd47`](https://github.com/wevm/wagmi/commit/e46bcd4738a18da15b53f6612b614379c1985374)]: + - @wagmi/core@2.6.8 + +## 4.1.16 + +### Patch Changes + +- [`1c1fee6a`](https://github.com/wevm/wagmi/commit/1c1fee6ab8f01f7734ac6ce05093fa8e388beb3e) Thanks [@jxom](https://github.com/jxom)! - Updated `@walletconnect/ethereum-provider`. + +- [#3653](https://github.com/wevm/wagmi/pull/3653) [`88a2d744`](https://github.com/wevm/wagmi/commit/88a2d744a1315908c9e54156026df3ad2435ad44) Thanks [@tash-2s](https://github.com/tash-2s)! - Fixed error occurring when adding chains without explorers to MetaMask. + +- Updated dependencies [[`b479b5e8`](https://github.com/wevm/wagmi/commit/b479b5e8a5866cba792862f22e6352c4fb566137), [`f5648dd2`](https://github.com/wevm/wagmi/commit/f5648dd28b3576b628f57732b89287f55acbb1c1), [`1c1fee6a`](https://github.com/wevm/wagmi/commit/1c1fee6ab8f01f7734ac6ce05093fa8e388beb3e), [`88a2d744`](https://github.com/wevm/wagmi/commit/88a2d744a1315908c9e54156026df3ad2435ad44)]: + - @wagmi/core@2.6.7 + +## 4.1.15 + +### Patch Changes + +- Updated dependencies [[`a91c0b64`](https://github.com/wevm/wagmi/commit/a91c0b64ba8b3e6537a560e69724eb601f26af27)]: + - @wagmi/core@2.6.6 + +## 4.1.14 + +### Patch Changes + +- [#3591](https://github.com/wevm/wagmi/pull/3591) [`ca5decdb`](https://github.com/wevm/wagmi/commit/ca5decdb712f81e3f5dab933a94b967bca5b6af4) Thanks [@tmm](https://github.com/tmm)! - Fixed Coinbase Wallet import. + +- Updated dependencies [[`c677dcd2`](https://github.com/wevm/wagmi/commit/c677dcd245dccdf69289a3d66dded237b09570a2)]: + - @wagmi/core@2.6.5 + +## 4.1.13 + +### Patch Changes + +- [#3569](https://github.com/wevm/wagmi/pull/3569) [`fa25b448`](https://github.com/wevm/wagmi/commit/fa25b4482504b4d9729a5687ea6d6dc959265bc0) Thanks [@svenvoskamp](https://github.com/svenvoskamp)! - Updated dependencies. + +- [#3558](https://github.com/wevm/wagmi/pull/3558) [`895f28e8`](https://github.com/wevm/wagmi/commit/895f28e873af7c8eda5ca85734ff67c8979fd950) Thanks [@tmm](https://github.com/tmm)! - Fixed connector warnings. + +- Updated dependencies [[`7c6618e6`](https://github.com/wevm/wagmi/commit/7c6618e6a0eb1ff39cf8f66b34d3ddc14be538fe), [`895f28e8`](https://github.com/wevm/wagmi/commit/895f28e873af7c8eda5ca85734ff67c8979fd950)]: + - @wagmi/core@2.6.4 + +## 4.1.12 + +### Patch Changes + +- Updated dependencies [[`9c3b85dd`](https://github.com/wevm/wagmi/commit/9c3b85dd0a9a4a593e1d7e029345275735330e32), [`2a72214a`](https://github.com/wevm/wagmi/commit/2a72214a2901d6b6ddd39f80238aa0bd4db670a7)]: + - @wagmi/core@2.6.3 + +## 4.1.11 + +### Patch Changes + +- [#3518](https://github.com/wevm/wagmi/pull/3518) [`338e857d`](https://github.com/wevm/wagmi/commit/338e857d8cb2fe85e13d9207bef14cada1c1962d) Thanks [@tmm](https://github.com/tmm)! - Bumped dependencies. + +- Updated dependencies [[`414eb048`](https://github.com/wevm/wagmi/commit/414eb048af492caac70c0e874dfc87c30702804a), [`338e857d`](https://github.com/wevm/wagmi/commit/338e857d8cb2fe85e13d9207bef14cada1c1962d)]: + - @wagmi/core@2.6.2 + +## 4.1.10 + +### Patch Changes + +- [#3510](https://github.com/wevm/wagmi/pull/3510) [`660ff80d`](https://github.com/wevm/wagmi/commit/660ff80d5b046967a446eba43ee54b8359a37d0d) Thanks [@tmm](https://github.com/tmm)! - Fixed issue where connectors returning multiple addresses didn't checksum correctly. + +- Updated dependencies [[`660ff80d`](https://github.com/wevm/wagmi/commit/660ff80d5b046967a446eba43ee54b8359a37d0d), [`101a7dd1`](https://github.com/wevm/wagmi/commit/101a7dd131b0cae2dc25579ecab9044290efd37b)]: + - @wagmi/core@2.6.1 + +## 4.1.9 + +### Patch Changes + +- [#3496](https://github.com/wevm/wagmi/pull/3496) [`ba7f8a75`](https://github.com/wevm/wagmi/commit/ba7f8a758efb07664c6e401b5e7e325e7c62341b) Thanks [@tmm](https://github.com/tmm)! - Bumped dependencies. + +- Updated dependencies [[`ba7f8a75`](https://github.com/wevm/wagmi/commit/ba7f8a758efb07664c6e401b5e7e325e7c62341b)]: + - @wagmi/core@2.6.0 + +## 4.1.8 + +### Patch Changes + +- Updated dependencies [[`ca98041d`](https://github.com/wevm/wagmi/commit/ca98041d1b39893d90246929485f4db0d1c6f9f7)]: + - @wagmi/core@2.5.0 + +## 4.1.7 + +### Patch Changes + +- [#3427](https://github.com/wevm/wagmi/pull/3427) [`370f1b4a`](https://github.com/wevm/wagmi/commit/370f1b4a3f154d181acf381c31c2e7862e22c0e4) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Bumped dependencies. + +- Updated dependencies [[`370f1b4a`](https://github.com/wevm/wagmi/commit/370f1b4a3f154d181acf381c31c2e7862e22c0e4)]: + - @wagmi/core@2.4.0 + +## 4.1.6 + +### Patch Changes + +- Updated dependencies [[`3be5bb7b`](https://github.com/wevm/wagmi/commit/3be5bb7b0b38646e12e6da5c762ef74dff66bcc2)]: + - @wagmi/core@2.3.1 + +## 4.1.5 + +### Patch Changes + +- [#3459](https://github.com/wevm/wagmi/pull/3459) [`d950b666`](https://github.com/wevm/wagmi/commit/d950b666b56700ca039ce16cdfdf34564991e7f5) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Bumped dependencies + +- [`1cfb6e5a`](https://github.com/wevm/wagmi/commit/1cfb6e5a875e707abcee00dd5739e87da05e8c90) Thanks [@jxom](https://github.com/jxom)! - Bumped listener limit on WalletConnect connector. + +- Updated dependencies [[`d950b666`](https://github.com/wevm/wagmi/commit/d950b666b56700ca039ce16cdfdf34564991e7f5), [`90ef39bb`](https://github.com/wevm/wagmi/commit/90ef39bb0f4ecb3c914d317875348e35ba0f4524), [`1cfb6e5a`](https://github.com/wevm/wagmi/commit/1cfb6e5a875e707abcee00dd5739e87da05e8c90)]: + - @wagmi/core@2.3.0 + +## 4.1.4 + +### Patch Changes + +- [#3443](https://github.com/wevm/wagmi/pull/3443) [`007024a6`](https://github.com/wevm/wagmi/commit/007024a684ddbecf924cdc06dd6a8854fc3d5eeb) Thanks [@jmrossy](https://github.com/jmrossy)! - Bumped dependencies. + +- [#3447](https://github.com/wevm/wagmi/pull/3447) [`a02a26ad`](https://github.com/wevm/wagmi/commit/a02a26ad030d3afb78f744377d61b5c60b65d97a) Thanks [@tmm](https://github.com/tmm)! - Bumped dependencies. + +- Updated dependencies [[`a02a26ad`](https://github.com/wevm/wagmi/commit/a02a26ad030d3afb78f744377d61b5c60b65d97a), [`007024a6`](https://github.com/wevm/wagmi/commit/007024a684ddbecf924cdc06dd6a8854fc3d5eeb)]: + - @wagmi/core@2.2.1 + +## 4.1.3 + +### Patch Changes + +- Updated dependencies [[`00bf10a4`](https://github.com/wevm/wagmi/commit/00bf10a428b0d1c5dac35ebf25b19571e033ac26), [`64c073f6`](https://github.com/wevm/wagmi/commit/64c073f6c2720961e2d6aff986670b73dbfab9c3), [`fb6c4148`](https://github.com/wevm/wagmi/commit/fb6c4148d9e9e2fccfbe74c8f343b444dc68dec5)]: + - @wagmi/core@2.2.0 + +## 4.1.2 + +### Patch Changes + +- Updated dependencies [[`e00b8205`](https://github.com/wevm/wagmi/commit/e00b82058685751637edfa9a6b2d196a12549fe7)]: + - @wagmi/core@2.1.2 + +## 4.1.1 + +### Patch Changes + +- [`ec0d8b41`](https://github.com/wevm/wagmi/commit/ec0d8b4112181fefb11025e436a94a6114761d37) Thanks [@tmm](https://github.com/tmm)! - Added note to `metaMask` connector. + +- Updated dependencies [[`64b82282`](https://github.com/wevm/wagmi/commit/64b82282c1e57e77c25aa0814673780e4d11edd4), [`ec0d8b41`](https://github.com/wevm/wagmi/commit/ec0d8b4112181fefb11025e436a94a6114761d37)]: + - @wagmi/core@2.1.1 + +## 4.1.0 + +### Minor Changes + +- Updated dependencies [[`c9cd302e`](https://github.com/wevm/wagmi/commit/c9cd302e1c65c980deaee2e12567c2a8ec08b399)]: + - @wagmi/core@2.1.0 + +## 4.0.2 + +### Patch Changes + +- [#3384](https://github.com/wevm/wagmi/pull/3384) [`ee868c33`](https://github.com/wevm/wagmi/commit/ee868c3385dae511230b6ddcb5627c1293cc1844) Thanks [@tmm](https://github.com/tmm)! - Fixed connectors not bubbling error when connecting with `chainId` and subsequent user rejection. + +- Updated dependencies [[`ee868c33`](https://github.com/wevm/wagmi/commit/ee868c3385dae511230b6ddcb5627c1293cc1844)]: + - @wagmi/core@2.0.2 + +## 4.0.1 + +### Major Changes + +- [#3333](https://github.com/wevm/wagmi/pull/3333) [`b3a0baaa`](https://github.com/wevm/wagmi/commit/b3a0baaaee7decf750d376aab2502cd33ca4825a) Thanks [@tmm](https://github.com/tmm)! - Added support for Wagmi 2.0. + +### Patch Changes + +- Updated dependencies [[`b3a0baaa`](https://github.com/wevm/wagmi/commit/b3a0baaaee7decf750d376aab2502cd33ca4825a)]: + - @wagmi/core@2.0.0 + +## 3.1.11 + +### Patch Changes + +- [#3361](https://github.com/wevm/wagmi/pull/3361) [`bbbbf587`](https://github.com/wevm/wagmi/commit/bbbbf587e41bae12b072b7a7c897d580fc07cd2b) Thanks [@0xAsimetriq](https://github.com/0xAsimetriq)! - Updated WalletConnect connector dependencies + +## 3.1.10 + +### Patch Changes + +- [`53ca1f7e`](https://github.com/wevm/wagmi/commit/53ca1f7eb411d912e11fcce7e03bd61ed067959c) Thanks [@tmm](https://github.com/tmm)! - Removed LedgerConnector due to security vulnerability + +## 3.1.9 + +### Patch Changes + +- [#3114](https://github.com/wevm/wagmi/pull/3114) [`51eca0fb`](https://github.com/wevm/wagmi/commit/51eca0fbaea6932f31a5b8b4213f0252280053e2) Thanks [@akathecoder](https://github.com/akathecoder)! - Added Okto Wallet to Injected Wallets Connector + +- [#3299](https://github.com/wevm/wagmi/pull/3299) [`b02020b3`](https://github.com/wevm/wagmi/commit/b02020b3724e0228198f35817611bb063295906e) Thanks [@dasanra](https://github.com/dasanra)! - Fixed issue with [Safe SDK](https://github.com/wevm/viem/issues/579) by bumping `@safe-global/safe-apps-provider@0.18.1` + +## 3.1.8 + +### Patch Changes + +- [#3197](https://github.com/wevm/wagmi/pull/3197) [`e8f7bcbc`](https://github.com/wevm/wagmi/commit/e8f7bcbcd9c038a901c29e71769682c088efe2ac) Thanks [@ByteZhang1024](https://github.com/ByteZhang1024)! - Added OneKey Wallet to injected connector flags. + +## 3.1.7 + +### Patch Changes + +- [#3276](https://github.com/wevm/wagmi/pull/3276) [`83223a06`](https://github.com/wevm/wagmi/commit/83223a0659e2f675d897a1d3374c7af752c16abf) Thanks [@glitch-txs](https://github.com/glitch-txs)! - Removed required namespaces from WalletConnect connector + +## 3.1.6 + +### Patch Changes + +- [#3236](https://github.com/wevm/wagmi/pull/3236) [`cc7e18f2`](https://github.com/wevm/wagmi/commit/cc7e18f2e7f6b8b989f60f0b05aee70e996a9975) Thanks [@0xAsimetriq](https://github.com/0xAsimetriq)! - Updated @walletconnect/ethereum-provider + +- [#3236](https://github.com/wevm/wagmi/pull/3236) [`cc7e18f2`](https://github.com/wevm/wagmi/commit/cc7e18f2e7f6b8b989f60f0b05aee70e996a9975) Thanks [@0xAsimetriq](https://github.com/0xAsimetriq)! - Updated @walletconnect/ethereum-provider + +## 3.1.5 + +### Patch Changes + +- [#3220](https://github.com/wagmi-dev/wagmi/pull/3220) [`a1950449`](https://github.com/wagmi-dev/wagmi/commit/a1950449127ddf72fff8ecd1fc34c3690befbb05) Thanks [@rkalis](https://github.com/rkalis)! - Fixed a bug where injected walets with an empty providers array could not connect + +## 3.1.4 + +### Patch Changes + +- [#3115](https://github.com/wagmi-dev/wagmi/pull/3115) [`4e6ec415`](https://github.com/wagmi-dev/wagmi/commit/4e6ec4151baece94e940e227e0e3711c7f8534d9) Thanks [@bifot](https://github.com/bifot)! - Added SafePal injected name mapping. + +## 3.1.3 + +### Patch Changes + +- [#3141](https://github.com/wagmi-dev/wagmi/pull/3141) [`e78aa337`](https://github.com/wagmi-dev/wagmi/commit/e78aa337c454f04b41a3cbd381d25270dd4a0afd) Thanks [@einaralex](https://github.com/einaralex)! - Updated WalletConnect libraries. + +## 3.1.2 + +### Patch Changes + +- [#3009](https://github.com/wagmi-dev/wagmi/pull/3009) [`3aaba328`](https://github.com/wagmi-dev/wagmi/commit/3aaba32808ddb4035ec885f96992c91078056715) Thanks [@0xAsimetriq](https://github.com/0xAsimetriq)! - Update WalletConnect dependencies + +## 3.1.1 + +### Patch Changes + +- [#2973](https://github.com/wevm/wagmi/pull/2973) [`bf831bb3`](https://github.com/wevm/wagmi/commit/bf831bb30df8037cc4312342d0fe3c045408c2fe) Thanks [@masm](https://github.com/masm)! - Added Zeal wallet + +## 3.1.0 + +### Minor Changes + +- [#2956](https://github.com/wevm/wagmi/pull/2956) [`2abeb285`](https://github.com/wevm/wagmi/commit/2abeb285674af3e539cc2550b1f5027b1eb0c895) Thanks [@tmm](https://github.com/tmm)! - Replaced `@wagmi/chains` with `viem/chains`. + +## 3.0.0 + +### Patch Changes + +- 0306383: Updated WalletConnect dependencies +- Updated dependencies [d1ef9b4] +- Updated dependencies [484c846] + - @wagmi/chains@1.8.0 + +## 2.7.0 + +### Minor Changes + +- a270cb9: Updated WalletConnect dependencies. + +### Patch Changes + +- 06cc1b4: Add SubWallet injected flags +- 131a337: Added Desig Wallet name mapping. +- e089d7d: Added Fordefi Wallet name mapping. +- ce84d0a: Added Coin98 Wallet injected flags. +- Updated dependencies [8fdacd8] +- Updated dependencies [2e9283a] +- Updated dependencies [a432a2b] +- Updated dependencies [408740a] +- Updated dependencies [6794a61] +- Updated dependencies [0c5a32b] +- Updated dependencies [ebc85ec] +- Updated dependencies [5683df2] +- Updated dependencies [414ff36] +- Updated dependencies [4f514c6] +- Updated dependencies [1cf72bc] +- Updated dependencies [cd68471] +- Updated dependencies [baf3143] +- Updated dependencies [9737f24] +- Updated dependencies [7797238] +- Updated dependencies [3846811] +- Updated dependencies [0ea344c] + - @wagmi/chains@1.7.0 + +## 2.6.6 + +### Patch Changes + +- 56c127d: Updated WalletConnect dependencies. +- Updated dependencies [4b411d2] +- Updated dependencies [df697ac] +- Updated dependencies [186f5a7] +- Updated dependencies [a96b514] +- Updated dependencies [0a6e6da] + - @wagmi/chains@1.5.0 + +## 2.6.5 + +### Patch Changes + +- 51e346e: Updated WalletConnectConnector logic to handle individual namespaces like eip155:\* + +## 2.6.4 + +### Patch Changes + +- 0a57de2: Added conditional for WalletConnectConnector optionalChains + +## 2.6.3 + +### Patch Changes + +- f2d532d: Updated WalletConnect dependencies, exposed `relayUrl` option for `WalletConnectConnector` +- ff53857: Fixed issue importing `EthereumProvider` in Vite environments. +- Updated dependencies [d642e1d] +- Updated dependencies [3027d7b] +- Updated dependencies [97dbd44] + - @wagmi/chains@1.4.0 + +## 2.6.2 + +### Patch Changes + +- 27bb1b3: Added explicit type annotations for the `getWalletClient()` method. + +## 2.6.1 + +### Patch Changes + +- a3507a9: Updated @walletconnect/ethereum-provider dependency + +## 2.6.0 + +### Minor Changes + +- 32dc317: Updated @walletconnect/ethereum-provider and @walletconnect/modal dependencies + +## 2.5.0 + +### Minor Changes + +- 57e674e: Updated `@safe-global/safe-apps-sdk` & `@safe-global/safe-apps-provider` + +## 2.4.0 + +### Patch Changes + +- f21c8e0: Added WalletConnect v2 support to Ledger connector. +- 27482bb: Add HAQQ Wallet detection +- 7d6aa43: Exported `normalizeChainId`. +- Updated dependencies [62b8209] +- Updated dependencies [106ac13] +- Updated dependencies [8b3f5e5] + - @wagmi/chains@1.3.0 + +## 2.3.0 + +### Minor Changes + +- 28219ae: Added metadata property to WalletConnect init function +- 6fef949: Updated @walletconnect/modal and @walletconnect/ethereum-provider deps + +### Patch Changes + +- 72f6465: Added `TTWallet` to `getInjectedName` list +- Updated dependencies [a7cbd04] +- Updated dependencies [f6ee133] + - @wagmi/chains@1.2.0 + +## 2.2.0 + +### Minor Changes + +- 6c841d4: Changed `Address` type import from ABIType to viem. + +### Patch Changes + +- 09c83f8: Update @walletconnect/ethereum-provider, Replace @web3modal/standalone with @walletconnect/modal, Fix issue with wallet_addEthereumChain method in WalletConnectConnector + +## 2.1.1 + +### Patch Changes + +- c24de75: Updated `@walletconnect/ethereum-provider` and `@web3modal/standalone` dependencies. +- 605c422: Bumped `viem` peer dependency. +- dc1c546: Throw ResourceUnavailableError on -30002 errors. + +## 2.1.0 + +### Minor Changes + +- b001569: Bumped minimum TypeScript version to v5.0.4. + +### Patch Changes + +- 0f05b2b: Updated `abitype` to `0.8.7`. +- 6aea7ee: Fixed internal types. +- b187cb0: Added `isNovaWallet` injected flag. +- 5e44429: Added Edgeware mainnet and testnet +- b18b314: Updated @walletconnect/ethereum-provider and @web3modal/standalone dependencies +- Updated dependencies [b62a199] +- Updated dependencies [b001569] +- Updated dependencies [260ab59] +- Updated dependencies [6aea7ee] +- Updated dependencies [5e44429] + - @wagmi/chains@1.0.0 + +## 2.0.0 + +### Patch Changes + +- Updated dependencies [36c14b2] + - @wagmi/chains@0.3.0 + +## 1.0.5 + +### Patch Changes + +- fa61dfe: Updated viem. +- Updated dependencies [577d2a0] + - @wagmi/chains@0.2.25 + +## 1.0.4 + +### Patch Changes + +- bbbd11b: Corrected Rabby Wallet name +- Updated dependencies [0639a1f] + - @wagmi/chains@0.2.24 + +## 1.0.3 + +### Patch Changes + +- 64dfe61: Update @web3modal/standalone to v2.4.1, Update @walletconnect/ethereum-provider to 2.7.4 +- bab7ad8: Added Defiant to injected connector flags +- 44cde07: Added Talisman wallet flag + +## 1.0.2 + +### Patch Changes + +- bce5a0c: Removed chain fallback when instantiating a Wallet Client. + +## 1.0.1 + +### Patch Changes + +- [`ea651cd7`](https://github.com/wevm/wagmi/commit/ea651cd7fc75b7866272605467db11fd6e1d81af) Thanks [@jxom](https://github.com/jxom)! - Downgraded abitype. + +## 1.0.0 + +### Major Changes + +- 7e274f5: Released v1. + +### Patch Changes + +- 0966bf7: Changed Kucoin Wallet name mapping to Halo Wallet + +## 1.0.0-next.5 + +### Major Changes + +- Updated references. + +## 1.0.0-next.4 + +### Major Changes + +- Updated references. + +## 1.0.0-next.3 + +### Patch Changes + +- Updated dependencies []: + - @wagmi/chains@1.0.0-next.0 + +## 1.0.0-next.2 + +### Major Changes + +- updated viem + +## 1.0.0-next.1 + +### Major Changes + +- [`a7dda00c`](https://github.com/wevm/wagmi/commit/a7dda00c5b546f8b2c42b527e4d9ac1b9e9ab1fb) Thanks [@jxom](https://github.com/jxom)! - Released v1. + +## 1.0.0-next.0 + +### Major Changes + +- 33488cf: Released v1. + +## 0.3.19 + +### Patch Changes + +- 274eef3: - Updated @web3modal/standalone to 2.3.7 + - Updated @walletconnect/ethereum-provider to 2.7.1 +- 41697df: Updated @walletconnect/ethereum-provider version to 2.7.2 +- 82dcb72: Added Enkrypt extension detection + +## 0.3.18 + +### Patch Changes + +- f66e065: Added BlockWallet to injected connector flags. + +## 0.3.17 + +### Patch Changes + +- 12ab5d1: Updated @coinbase/wallet-sdk to 3.6.6 + +## 0.3.16 + +### Patch Changes + +- c1e3ddf: Reverted ABIType version change. + +## 0.3.15 + +### Patch Changes + +- d4825e6: Fixed ABIType version to match downstream packages. + +## 0.3.14 + +### Patch Changes + +- c25ac82: Added more flags to `MetaMaskConnector` `getProvider` check. +- b19a932: Updated @web3modal/standalone to 2.3.0, @walletconnect/ethereum-provider to 2.7.0 +- cdc387e: Added `ImToken` to `getInjectedName` list + +## 0.3.13 + +### Patch Changes + +- 2a21d27: Updated `@coinbase/wallet-sdk` to `3.6.4` + +## 0.3.12 + +### Patch Changes + +- 9bb22b6: Updated `@walletconnect/ethereum-provider` to `2.6.2`, relaxed `@web3modal/standalone` version requirement +- 0d7625b: Added Rabby to injected connector flags +- f63d7fd: Added correct error to switch network cause. + +## 0.3.11 + +### Patch Changes + +- 0778abc: Renamed `isTally` injected provider to `Taho` + +## 0.3.10 + +### Patch Changes + +- 4267020: Added `qrModalOptions` option to `WalletConnectConnector` +- e78fb0a: Pinned WalletConnect dependencies + +## 0.3.9 + +### Patch Changes + +- 5cd0afc: Added `isZerion` to `InjectedProviderFlags` and `getInjectedName` +- be4825e: Added GameStop Wallet to injected connector flags + +## 0.3.8 + +### Patch Changes + +- 11f3fe2: Fixed issue where `UNSTABLE_shimOnConnectSelectAccount` would not bubble up error for MetaMask if request to connect was already active. + +## 0.3.7 + +### Patch Changes + +- 04c0e47: Fixed issue switching chain after adding to MetaMask. + +## 0.3.6 + +### Patch Changes + +- 85330c1: Removed `InjectedConnector` `shimChainChangedDisconnect` shim (no longer necessary). + +## 0.3.5 + +### Patch Changes + +- 8b1a526: Added Dawn wallet flag + +## 0.3.4 + +### Patch Changes + +- 6b15d6f: Updated `@walletconnect/ethereum-provider` to `2.5.1`. +- 1f452e7: Added OKX Wallet to injected connector flags. +- a4d9083: Added Backpack wallet to injected connector flags. +- 6a4af48: Enabled support for programmatic chain switching on `LedgerConnector` & added `"ledger"` to the switch chain regex on `WalletConnectLegacyConnector`. + +## 0.3.3 + +### Patch Changes + +- f24ce0c: Updated @walletconnect/ethereum-provider to 2.4.8 +- e3a3fee: Added "uniswap wallet" to the regex that determines wallets allowed to switch chains in the WalletConnect legacy connector +- 641af48: Added name mapping for Bifrost Wallet +- 4d2c90a: Added name mapping for Phantom +- 3d276d0: Added Status as the name of the injected connector for the Status App + +## 0.3.2 + +### Patch Changes + +- 13a6a07: Updated `@walletconnect/ethereum-provider` to `2.4.7`. + +## 0.3.1 + +### Patch Changes + +- a23c40f: Added name mapping for [Frontier](https://frontier.xyz) Wallet +- d779fb3: Added name mapping for HyperPay. + +## 0.3.0 + +### Minor Changes + +- c4d5bb5: **Breaking:** Removed the `version` config option for `WalletConnectConnector`. + + `WalletConnectConnector` now uses WalletConnect v2 by default. WalletConnect v1 is now `WalletConnectLegacyConnector`. + + ### WalletConnect v2 + + ```diff + import { WalletConnectConnector } from '@wagmi/connectors/walletConnect' + + const connector = new WalletConnectConnector({ + options: { + - version: '2', + projectId: 'abc', + }, + }) + ``` + + ### WalletConnect v1 + + ```diff + -import { WalletConnectConnector } from '@wagmi/connectors/walletConnect' + +import { WalletConnectLegacyConnector } from '@wagmi/connectors/walletConnectLegacy' + + -const connector = new WalletConnectConnector({ + +const connector = new WalletConnectLegacyConnector({ + options: { + qrcode: true, + }, + }) + ``` + +## 0.2.7 + +### Patch Changes + +- 57f1226: Added name mapping for XDEFI + +## 0.2.6 + +### Patch Changes + +- bb1b88c: Added name mapping for Bitski injected wallet +- fcb5595: Fixed shim disconnect key to read from defined Connector ID. +- 49f8853: Fixed `SafeConnector` import type error that existed for specific build environments. + +## 0.2.5 + +### Patch Changes + +- 5d121f2: Added `isApexWallet` to injected `window.ethereum` flags. +- e3566eb: Updated `@web3modal/standalone` to `2.1.1` for WalletConnectConnector. + +## 0.2.4 + +### Patch Changes + +- a4f31bc: Added Connector for [Safe](https://safe.global) wallet +- d5e25d9: Locked ethers peer dependency version to >=5.5.1 <6 + +## 0.2.3 + +### Patch Changes + +- 6fa74dd: Updated `@walletconnect/universal-provider` + Added more signable methods to WC v2. + +## 0.2.2 + +### Patch Changes + +- 6b0725b: Fixed race condition between `switchNetwork` and mutation Hooks that use `chainId` (e.g. `sendTransaction`). + +## 0.2.1 + +### Patch Changes + +- 942fcde: Updated `@walletconnect/universal-provider` and `@web3modal/standalone` packages for WalletConnectConnector (v2). + + Improved initialization flow for `@walletconnect/universal-provider` for WalletConnectConnector (v2). + +## 0.2.0 + +### Minor Changes + +- be33c7d: Chains are now narrowed to their most specific type using the TypeScript [`satisfies`](https://devblogs.microsoft.com/typescript/announcing-typescript-4-9/#the-satisfies-operator) operator. + +## 0.1.10 + +### Patch Changes + +- d75e8d2: Fixed ABIType version mismatch between packages. + +## 0.1.9 + +### Patch Changes + +- 8c3fc00: Added public RPC URL to Connector fallback chains + +## 0.1.8 + +### Patch Changes + +- 5e6dc30: Replaced legacy qrcodemodal with web3modal for WalletConnect v2. + +## 0.1.7 + +### Patch Changes + +- be4add2: Added `isRainbow` flag to `InjectedConnector`. + +## 0.1.6 + +### Patch Changes + +- 3dfc558: Add `switchSigner` method to `MockProvider`. + +## 0.1.5 + +### Patch Changes + +- 7dce4b5: Bumped WalletConnect Universal Provider version. + +## 0.1.4 + +### Patch Changes + +- 4cec598: Added CJS escape hatch bundle under the "cjs" tag. + +## 0.1.3 + +### Patch Changes + +- 822bc88: The `WalletConnectConnector` now supports WalletConnect v2. + + It can be enabled by setting `version` to `'2'` and supplying a [WalletConnect Cloud `projectId`](https://cloud.walletconnect.com/sign-in). + +## 0.1.2 + +### Patch Changes + +- 5e5f37f: Fixed issue where connecting to MetaMask may return with a stale address + +## 0.1.1 + +### Patch Changes + +- 919790c: Updated `@ledgerhq/connect-kit-loader` to `1.0.1` + +## 0.1.0 + +### Minor Changes + +- 5db7cba: Added `LedgerConnector` +- 55a0ca2: Initial release of the `@wagmi/connectors` package – a collection of Connectors for wagmi. diff --git a/wagmi-project/packages/connectors/README.md b/wagmi-project/packages/connectors/README.md new file mode 100644 index 0000000000..05418ec15c --- /dev/null +++ b/wagmi-project/packages/connectors/README.md @@ -0,0 +1,13 @@ +# @wagmi/connectors + +Collection of connectors for Wagmi + +## Installation + +```bash +pnpm add @wagmi/connectors @wagmi/core viem +``` + +## Documentation + +For documentation and guides, visit [wagmi.sh](https://wagmi.sh). diff --git a/wagmi-project/packages/connectors/package.json b/wagmi-project/packages/connectors/package.json new file mode 100644 index 0000000000..de6d0f0dc6 --- /dev/null +++ b/wagmi-project/packages/connectors/package.json @@ -0,0 +1,71 @@ +{ + "name": "@wagmi/connectors", + "description": "Collection of connectors for Wagmi", + "version": "5.8.3", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/wevm/wagmi.git", + "directory": "packages/connectors" + }, + "scripts": { + "build": "pnpm run clean && pnpm run build:esm+types", + "build:esm+types": "tsc --project tsconfig.build.json --outDir ./dist/esm --declaration --declarationMap --declarationDir ./dist/types", + "check:types": "tsc --noEmit", + "clean": "rm -rf dist tsconfig.tsbuildinfo", + "test:build": "publint --strict && attw --pack --ignore-rules cjs-resolves-to-esm" + }, + "files": [ + "dist/**", + "!dist/**/*.tsbuildinfo", + "src/**/*.ts", + "!src/**/*.test.ts", + "!src/**/*.test-d.ts" + ], + "sideEffects": false, + "type": "module", + "main": "./dist/esm/exports/index.js", + "types": "./dist/types/exports/index.d.ts", + "typings": "./dist/types/exports/index.d.ts", + "exports": { + ".": { + "types": "./dist/types/exports/index.d.ts", + "default": "./dist/esm/exports/index.js" + }, + "./package.json": "./package.json" + }, + "peerDependencies": { + "@wagmi/core": "workspace:*", + "typescript": ">=5.0.4", + "viem": "2.x" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + }, + "dependencies": { + "@coinbase/wallet-sdk": "4.3.0", + "@metamask/sdk": "0.32.1", + "@safe-global/safe-apps-provider": "0.18.6", + "@safe-global/safe-apps-sdk": "9.1.0", + "@walletconnect/ethereum-provider": "2.20.2", + "cbw-sdk": "npm:@coinbase/wallet-sdk@3.9.3" + }, + "devDependencies": { + "@wagmi/core": "workspace:*", + "msw": "^2.4.9" + }, + "contributors": ["awkweb.eth ", "jxom.eth "], + "funding": "https://github.com/sponsors/wevm", + "keywords": [ + "react", + "hooks", + "eth", + "ethereum", + "dapps", + "wallet", + "web3", + "abi" + ] +} diff --git a/wagmi-project/packages/connectors/src/coinbaseWallet.test.ts b/wagmi-project/packages/connectors/src/coinbaseWallet.test.ts new file mode 100644 index 0000000000..99b141e49b --- /dev/null +++ b/wagmi-project/packages/connectors/src/coinbaseWallet.test.ts @@ -0,0 +1,17 @@ +import { config } from '@wagmi/test' +import { expect, expectTypeOf, test } from 'vitest' + +import { coinbaseWallet } from './coinbaseWallet.js' + +test('setup', () => { + const connectorFn = coinbaseWallet({ appName: 'wagmi', version: '4' }) + const connector = config._internal.connectors.setup(connectorFn) + expect(connector.name).toEqual('Coinbase Wallet') + + type ConnectFnParameters = NonNullable< + Parameters<(typeof connector)['connect']>[0] + > + expectTypeOf().toMatchTypeOf< + boolean | undefined + >() +}) diff --git a/wagmi-project/packages/connectors/src/coinbaseWallet.ts b/wagmi-project/packages/connectors/src/coinbaseWallet.ts new file mode 100644 index 0000000000..630c91261e --- /dev/null +++ b/wagmi-project/packages/connectors/src/coinbaseWallet.ts @@ -0,0 +1,546 @@ +import type { + Preference, + ProviderInterface, + createCoinbaseWalletSDK, +} from '@coinbase/wallet-sdk' +import { + ChainNotConfiguredError, + type Connector, + createConnector, +} from '@wagmi/core' +import type { Compute, Mutable, Omit } from '@wagmi/core/internal' +import type { + CoinbaseWalletProvider as CBW_Provider, + CoinbaseWalletSDK as CBW_SDK, +} from 'cbw-sdk' +import { + type AddEthereumChainParameter, + type Address, + type Hex, + type ProviderRpcError, + SwitchChainError, + UserRejectedRequestError, + getAddress, + numberToHex, +} from 'viem' + +type Version = '3' | '4' + +export type CoinbaseWalletParameters = + version extends '4' + ? Compute< + { + headlessMode?: false | undefined + /** Coinbase Wallet SDK version */ + version?: version | '3' | undefined + } & Version4Parameters + > + : Compute< + { + /** + * @deprecated `headlessMode` will be removed in the next major version. Upgrade to `version: '4'`. + */ + headlessMode?: true | undefined + /** + * Coinbase Wallet SDK version + * @deprecated Version 3 will be removed in the next major version. Upgrade to `version: '4'`. + * @default '4' + */ + version?: version | '4' | undefined + } & Version3Parameters + > + +coinbaseWallet.type = 'coinbaseWallet' as const +export function coinbaseWallet( + parameters: CoinbaseWalletParameters = {} as any, +): version extends '4' + ? ReturnType + : ReturnType { + if (parameters.version === '3' || parameters.headlessMode) + return version3(parameters as Version3Parameters) as any + return version4(parameters as Version4Parameters) as any +} + +type Version4Parameters = Mutable< + Omit< + Parameters[0], + | 'appChainIds' // set via wagmi config + | 'preference' + > & { + // TODO(v3): Remove `Preference['options']` + /** + * Preference for the type of wallet to display. + * @default 'all' + */ + preference?: Preference['options'] | Compute | undefined + } +> + +function version4(parameters: Version4Parameters) { + type Provider = ProviderInterface & { + // for backwards compatibility + close?(): void + } + type Properties = { + connect(parameters?: { + chainId?: number | undefined + instantOnboarding?: boolean | undefined + isReconnecting?: boolean | undefined + }): Promise<{ + accounts: readonly Address[] + chainId: number + }> + } + + let walletProvider: Provider | undefined + + let accountsChanged: Connector['onAccountsChanged'] | undefined + let chainChanged: Connector['onChainChanged'] | undefined + let disconnect: Connector['onDisconnect'] | undefined + + return createConnector((config) => ({ + id: 'coinbaseWalletSDK', + name: 'Coinbase Wallet', + rdns: 'com.coinbase.wallet', + type: coinbaseWallet.type, + async connect({ chainId, ...rest } = {}) { + try { + const provider = await this.getProvider() + const accounts = ( + (await provider.request({ + method: 'eth_requestAccounts', + params: + 'instantOnboarding' in rest && rest.instantOnboarding + ? [{ onboarding: 'instant' }] + : [], + })) as string[] + ).map((x) => getAddress(x)) + + if (!accountsChanged) { + accountsChanged = this.onAccountsChanged.bind(this) + provider.on('accountsChanged', accountsChanged) + } + if (!chainChanged) { + chainChanged = this.onChainChanged.bind(this) + provider.on('chainChanged', chainChanged) + } + if (!disconnect) { + disconnect = this.onDisconnect.bind(this) + provider.on('disconnect', disconnect) + } + + // Switch to chain if provided + let currentChainId = await this.getChainId() + if (chainId && currentChainId !== chainId) { + const chain = await this.switchChain!({ chainId }).catch((error) => { + if (error.code === UserRejectedRequestError.code) throw error + return { id: currentChainId } + }) + currentChainId = chain?.id ?? currentChainId + } + + return { accounts, chainId: currentChainId } + } catch (error) { + if ( + /(user closed modal|accounts received is empty|user denied account|request rejected)/i.test( + (error as Error).message, + ) + ) + throw new UserRejectedRequestError(error as Error) + throw error + } + }, + async disconnect() { + const provider = await this.getProvider() + + if (accountsChanged) { + provider.removeListener('accountsChanged', accountsChanged) + accountsChanged = undefined + } + if (chainChanged) { + provider.removeListener('chainChanged', chainChanged) + chainChanged = undefined + } + if (disconnect) { + provider.removeListener('disconnect', disconnect) + disconnect = undefined + } + + provider.disconnect() + provider.close?.() + }, + async getAccounts() { + const provider = await this.getProvider() + return ( + (await provider.request({ + method: 'eth_accounts', + })) as string[] + ).map((x) => getAddress(x)) + }, + async getChainId() { + const provider = await this.getProvider() + const chainId = (await provider.request({ + method: 'eth_chainId', + })) as Hex + return Number(chainId) + }, + async getProvider() { + if (!walletProvider) { + const preference = (() => { + if (typeof parameters.preference === 'string') + return { options: parameters.preference } + return { + ...parameters.preference, + options: parameters.preference?.options ?? 'all', + } + })() + + const { createCoinbaseWalletSDK } = await import('@coinbase/wallet-sdk') + const sdk = createCoinbaseWalletSDK({ + ...parameters, + appChainIds: config.chains.map((x) => x.id), + preference, + }) + + walletProvider = sdk.getProvider() + } + + return walletProvider + }, + async isAuthorized() { + try { + const accounts = await this.getAccounts() + return !!accounts.length + } catch { + return false + } + }, + async switchChain({ addEthereumChainParameter, chainId }) { + const chain = config.chains.find((chain) => chain.id === chainId) + if (!chain) throw new SwitchChainError(new ChainNotConfiguredError()) + + const provider = await this.getProvider() + + try { + await provider.request({ + method: 'wallet_switchEthereumChain', + params: [{ chainId: numberToHex(chain.id) }], + }) + return chain + } catch (error) { + // Indicates chain is not added to provider + if ((error as ProviderRpcError).code === 4902) { + try { + let blockExplorerUrls: string[] | undefined + if (addEthereumChainParameter?.blockExplorerUrls) + blockExplorerUrls = addEthereumChainParameter.blockExplorerUrls + else + blockExplorerUrls = chain.blockExplorers?.default.url + ? [chain.blockExplorers?.default.url] + : [] + + let rpcUrls: readonly string[] + if (addEthereumChainParameter?.rpcUrls?.length) + rpcUrls = addEthereumChainParameter.rpcUrls + else rpcUrls = [chain.rpcUrls.default?.http[0] ?? ''] + + const addEthereumChain = { + blockExplorerUrls, + chainId: numberToHex(chainId), + chainName: addEthereumChainParameter?.chainName ?? chain.name, + iconUrls: addEthereumChainParameter?.iconUrls, + nativeCurrency: + addEthereumChainParameter?.nativeCurrency ?? + chain.nativeCurrency, + rpcUrls, + } satisfies AddEthereumChainParameter + + await provider.request({ + method: 'wallet_addEthereumChain', + params: [addEthereumChain], + }) + + return chain + } catch (error) { + throw new UserRejectedRequestError(error as Error) + } + } + + throw new SwitchChainError(error as Error) + } + }, + onAccountsChanged(accounts) { + if (accounts.length === 0) this.onDisconnect() + else + config.emitter.emit('change', { + accounts: accounts.map((x) => getAddress(x)), + }) + }, + onChainChanged(chain) { + const chainId = Number(chain) + config.emitter.emit('change', { chainId }) + }, + async onDisconnect(_error) { + config.emitter.emit('disconnect') + + const provider = await this.getProvider() + if (accountsChanged) { + provider.removeListener('accountsChanged', accountsChanged) + accountsChanged = undefined + } + if (chainChanged) { + provider.removeListener('chainChanged', chainChanged) + chainChanged = undefined + } + if (disconnect) { + provider.removeListener('disconnect', disconnect) + disconnect = undefined + } + }, + })) +} + +type Version3Parameters = Mutable< + Omit< + ConstructorParameters[0], + 'reloadOnDisconnect' // remove property since TSDoc says default is `true` + > +> & { + /** + * Fallback Ethereum JSON RPC URL + * @default "" + */ + jsonRpcUrl?: string | undefined + /** + * Fallback Ethereum Chain ID + * @default 1 + */ + chainId?: number | undefined + /** + * Whether or not to reload dapp automatically after disconnect. + * @default false + */ + reloadOnDisconnect?: boolean | undefined +} + +function version3(parameters: Version3Parameters) { + const reloadOnDisconnect = false + + type Provider = CBW_Provider + + let sdk: CBW_SDK | undefined + let walletProvider: Provider | undefined + + let accountsChanged: Connector['onAccountsChanged'] | undefined + let chainChanged: Connector['onChainChanged'] | undefined + let disconnect: Connector['onDisconnect'] | undefined + + return createConnector((config) => ({ + id: 'coinbaseWalletSDK', + name: 'Coinbase Wallet', + rdns: 'com.coinbase.wallet', + type: coinbaseWallet.type, + async connect({ chainId } = {}) { + try { + const provider = await this.getProvider() + const accounts = ( + (await provider.request({ + method: 'eth_requestAccounts', + })) as string[] + ).map((x) => getAddress(x)) + + if (!accountsChanged) { + accountsChanged = this.onAccountsChanged.bind(this) + provider.on('accountsChanged', accountsChanged) + } + if (!chainChanged) { + chainChanged = this.onChainChanged.bind(this) + provider.on('chainChanged', chainChanged) + } + if (!disconnect) { + disconnect = this.onDisconnect.bind(this) + provider.on('disconnect', disconnect) + } + + // Switch to chain if provided + let currentChainId = await this.getChainId() + if (chainId && currentChainId !== chainId) { + const chain = await this.switchChain!({ chainId }).catch((error) => { + if (error.code === UserRejectedRequestError.code) throw error + return { id: currentChainId } + }) + currentChainId = chain?.id ?? currentChainId + } + + return { accounts, chainId: currentChainId } + } catch (error) { + if ( + /(user closed modal|accounts received is empty|user denied account)/i.test( + (error as Error).message, + ) + ) + throw new UserRejectedRequestError(error as Error) + throw error + } + }, + async disconnect() { + const provider = await this.getProvider() + + if (accountsChanged) { + provider.removeListener('accountsChanged', accountsChanged) + accountsChanged = undefined + } + if (chainChanged) { + provider.removeListener('chainChanged', chainChanged) + chainChanged = undefined + } + if (disconnect) { + provider.removeListener('disconnect', disconnect) + disconnect = undefined + } + + provider.disconnect() + provider.close() + }, + async getAccounts() { + const provider = await this.getProvider() + return ( + await provider.request({ + method: 'eth_accounts', + }) + ).map((x) => getAddress(x)) + }, + async getChainId() { + const provider = await this.getProvider() + const chainId = await provider.request({ + method: 'eth_chainId', + }) + return Number(chainId) + }, + async getProvider() { + if (!walletProvider) { + // Unwrapping import for Vite compatibility. + // See: https://github.com/vitejs/vite/issues/9703 + const CoinbaseWalletSDK = await (async () => { + const { default: SDK } = await import('cbw-sdk') + if (typeof SDK !== 'function' && typeof SDK.default === 'function') + return SDK.default + return SDK as unknown as typeof SDK.default + })() + + sdk = new CoinbaseWalletSDK({ ...parameters, reloadOnDisconnect }) + + // Force types to retrieve private `walletExtension` method from the Coinbase Wallet SDK. + const walletExtensionChainId = ( + sdk as unknown as { + get walletExtension(): { getChainId(): number } | undefined + } + ).walletExtension?.getChainId() + + const chain = + config.chains.find((chain) => + parameters.chainId + ? chain.id === parameters.chainId + : chain.id === walletExtensionChainId, + ) || config.chains[0] + const chainId = parameters.chainId || chain?.id + const jsonRpcUrl = + parameters.jsonRpcUrl || chain?.rpcUrls.default.http[0] + + walletProvider = sdk.makeWeb3Provider(jsonRpcUrl, chainId) + } + + return walletProvider + }, + async isAuthorized() { + try { + const accounts = await this.getAccounts() + return !!accounts.length + } catch { + return false + } + }, + async switchChain({ addEthereumChainParameter, chainId }) { + const chain = config.chains.find((chain) => chain.id === chainId) + if (!chain) throw new SwitchChainError(new ChainNotConfiguredError()) + + const provider = await this.getProvider() + + try { + await provider.request({ + method: 'wallet_switchEthereumChain', + params: [{ chainId: numberToHex(chain.id) }], + }) + return chain + } catch (error) { + // Indicates chain is not added to provider + if ((error as ProviderRpcError).code === 4902) { + try { + let blockExplorerUrls: string[] | undefined + if (addEthereumChainParameter?.blockExplorerUrls) + blockExplorerUrls = addEthereumChainParameter.blockExplorerUrls + else + blockExplorerUrls = chain.blockExplorers?.default.url + ? [chain.blockExplorers?.default.url] + : [] + + let rpcUrls: readonly string[] + if (addEthereumChainParameter?.rpcUrls?.length) + rpcUrls = addEthereumChainParameter.rpcUrls + else rpcUrls = [chain.rpcUrls.default?.http[0] ?? ''] + + const addEthereumChain = { + blockExplorerUrls, + chainId: numberToHex(chainId), + chainName: addEthereumChainParameter?.chainName ?? chain.name, + iconUrls: addEthereumChainParameter?.iconUrls, + nativeCurrency: + addEthereumChainParameter?.nativeCurrency ?? + chain.nativeCurrency, + rpcUrls, + } satisfies AddEthereumChainParameter + + await provider.request({ + method: 'wallet_addEthereumChain', + params: [addEthereumChain], + }) + + return chain + } catch (error) { + throw new UserRejectedRequestError(error as Error) + } + } + + throw new SwitchChainError(error as Error) + } + }, + onAccountsChanged(accounts) { + if (accounts.length === 0) this.onDisconnect() + else + config.emitter.emit('change', { + accounts: accounts.map((x) => getAddress(x)), + }) + }, + onChainChanged(chain) { + const chainId = Number(chain) + config.emitter.emit('change', { chainId }) + }, + async onDisconnect(_error) { + config.emitter.emit('disconnect') + + const provider = await this.getProvider() + if (accountsChanged) { + provider.removeListener('accountsChanged', accountsChanged) + accountsChanged = undefined + } + if (chainChanged) { + provider.removeListener('chainChanged', chainChanged) + chainChanged = undefined + } + if (disconnect) { + provider.removeListener('disconnect', disconnect) + disconnect = undefined + } + }, + })) +} diff --git a/wagmi-project/packages/connectors/src/exports/index.test.ts b/wagmi-project/packages/connectors/src/exports/index.test.ts new file mode 100644 index 0000000000..bcf100cb61 --- /dev/null +++ b/wagmi-project/packages/connectors/src/exports/index.test.ts @@ -0,0 +1,17 @@ +import { expect, test } from 'vitest' + +import * as connectors from './index.js' + +test('exports', () => { + expect(Object.keys(connectors)).toMatchInlineSnapshot(` + [ + "injected", + "mock", + "coinbaseWallet", + "metaMask", + "safe", + "walletConnect", + "version", + ] + `) +}) diff --git a/wagmi-project/packages/connectors/src/exports/index.ts b/wagmi-project/packages/connectors/src/exports/index.ts new file mode 100644 index 0000000000..bac0975956 --- /dev/null +++ b/wagmi-project/packages/connectors/src/exports/index.ts @@ -0,0 +1,23 @@ +// biome-ignore lint/performance/noBarrelFile: entrypoint module +export { + type InjectedParameters, + injected, + type MockParameters, + mock, +} from '@wagmi/core' + +export { + type CoinbaseWalletParameters, + coinbaseWallet, +} from '../coinbaseWallet.js' + +export { type MetaMaskParameters, metaMask } from '../metaMask.js' + +export { type SafeParameters, safe } from '../safe.js' + +export { + type WalletConnectParameters, + walletConnect, +} from '../walletConnect.js' + +export { version } from '../version.js' diff --git a/wagmi-project/packages/connectors/src/metaMask.test.ts b/wagmi-project/packages/connectors/src/metaMask.test.ts new file mode 100644 index 0000000000..40c3f0f7f9 --- /dev/null +++ b/wagmi-project/packages/connectors/src/metaMask.test.ts @@ -0,0 +1,10 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { metaMask } from './metaMask.js' + +test('setup', () => { + const connectorFn = metaMask() + const connector = config._internal.connectors.setup(connectorFn) + expect(connector.name).toEqual('MetaMask') +}) diff --git a/wagmi-project/packages/connectors/src/metaMask.ts b/wagmi-project/packages/connectors/src/metaMask.ts new file mode 100644 index 0000000000..02ab4c3fb3 --- /dev/null +++ b/wagmi-project/packages/connectors/src/metaMask.ts @@ -0,0 +1,505 @@ +import type { + MetaMaskSDK, + MetaMaskSDKOptions, + RPC_URLS_MAP, + SDKProvider, +} from '@metamask/sdk' +import { + ChainNotConfiguredError, + type Connector, + ProviderNotFoundError, + createConnector, + extractRpcUrls, +} from '@wagmi/core' +import type { + Compute, + ExactPartial, + OneOf, + RemoveUndefined, + UnionCompute, +} from '@wagmi/core/internal' +import { + type AddEthereumChainParameter, + type Address, + type Hex, + type ProviderConnectInfo, + type ProviderRpcError, + ResourceUnavailableRpcError, + type RpcError, + SwitchChainError, + UserRejectedRequestError, + getAddress, + hexToNumber, + numberToHex, + withRetry, + withTimeout, +} from 'viem' + +export type MetaMaskParameters = UnionCompute< + WagmiMetaMaskSDKOptions & + OneOf< + | { + /* Shortcut to connect and sign a message */ + connectAndSign?: string | undefined + } + | { + // TODO: Strongly type `method` and `params` + /* Allow `connectWith` any rpc method */ + connectWith?: { method: string; params: unknown[] } | undefined + } + > +> + +type WagmiMetaMaskSDKOptions = Compute< + ExactPartial< + Omit< + MetaMaskSDKOptions, + | '_source' + | 'forceDeleteProvider' + | 'forceInjectProvider' + | 'injectProvider' + | 'useDeeplink' + | 'readonlyRPCMap' + > + > & { + /** @deprecated */ + forceDeleteProvider?: MetaMaskSDKOptions['forceDeleteProvider'] + /** @deprecated */ + forceInjectProvider?: MetaMaskSDKOptions['forceInjectProvider'] + /** @deprecated */ + injectProvider?: MetaMaskSDKOptions['injectProvider'] + /** @deprecated */ + useDeeplink?: MetaMaskSDKOptions['useDeeplink'] + } +> + +metaMask.type = 'metaMask' as const +export function metaMask(parameters: MetaMaskParameters = {}) { + type Provider = SDKProvider + type Properties = { + onConnect(connectInfo: ProviderConnectInfo): void + onDisplayUri(uri: string): void + } + type Listener = Parameters[1] + + let sdk: MetaMaskSDK + let provider: Provider | undefined + let providerPromise: Promise + + let accountsChanged: Connector['onAccountsChanged'] | undefined + let chainChanged: Connector['onChainChanged'] | undefined + let connect: Connector['onConnect'] | undefined + let displayUri: ((uri: string) => void) | undefined + let disconnect: Connector['onDisconnect'] | undefined + + return createConnector((config) => ({ + id: 'metaMaskSDK', + name: 'MetaMask', + rdns: ['io.metamask', 'io.metamask.mobile'], + type: metaMask.type, + async setup() { + const provider = await this.getProvider() + if (provider?.on) { + if (!connect) { + connect = this.onConnect.bind(this) + provider.on('connect', connect as Listener) + } + + // We shouldn't need to listen for `'accountsChanged'` here since the `'connect'` event should suffice (and wallet shouldn't be connected yet). + // Some wallets, like MetaMask, do not implement the `'connect'` event and overload `'accountsChanged'` instead. + if (!accountsChanged) { + accountsChanged = this.onAccountsChanged.bind(this) + provider.on('accountsChanged', accountsChanged as Listener) + } + } + }, + async connect({ chainId, isReconnecting } = {}) { + const provider = await this.getProvider() + if (!displayUri) { + displayUri = this.onDisplayUri + provider.on('display_uri', displayUri as Listener) + } + + let accounts: readonly Address[] = [] + if (isReconnecting) accounts = await this.getAccounts().catch(() => []) + + try { + let signResponse: string | undefined + let connectWithResponse: unknown | undefined + if (!accounts?.length) { + if (parameters.connectAndSign || parameters.connectWith) { + if (parameters.connectAndSign) + signResponse = await sdk.connectAndSign({ + msg: parameters.connectAndSign, + }) + else if (parameters.connectWith) + connectWithResponse = await sdk.connectWith({ + method: parameters.connectWith.method, + params: parameters.connectWith.params, + }) + + accounts = await this.getAccounts() + } else { + const requestedAccounts = (await sdk.connect()) as string[] + accounts = requestedAccounts.map((x) => getAddress(x)) + } + } + // Switch to chain if provided + let currentChainId = (await this.getChainId()) as number + if (chainId && currentChainId !== chainId) { + const chain = await this.switchChain!({ chainId }).catch((error) => { + if (error.code === UserRejectedRequestError.code) throw error + return { id: currentChainId } + }) + currentChainId = chain?.id ?? currentChainId + } + + if (displayUri) { + provider.removeListener('display_uri', displayUri) + displayUri = undefined + } + + if (signResponse) + provider.emit('connectAndSign', { + accounts, + chainId: currentChainId, + signResponse, + }) + else if (connectWithResponse) + provider.emit('connectWith', { + accounts, + chainId: currentChainId, + connectWithResponse, + }) + + // Manage EIP-1193 event listeners + // https://eips.ethereum.org/EIPS/eip-1193#events + if (connect) { + provider.removeListener('connect', connect) + connect = undefined + } + if (!accountsChanged) { + accountsChanged = this.onAccountsChanged.bind(this) + provider.on('accountsChanged', accountsChanged as Listener) + } + if (!chainChanged) { + chainChanged = this.onChainChanged.bind(this) + provider.on('chainChanged', chainChanged as Listener) + } + if (!disconnect) { + disconnect = this.onDisconnect.bind(this) + provider.on('disconnect', disconnect as Listener) + } + + return { accounts, chainId: currentChainId } + } catch (err) { + const error = err as RpcError + if (error.code === UserRejectedRequestError.code) + throw new UserRejectedRequestError(error) + if (error.code === ResourceUnavailableRpcError.code) + throw new ResourceUnavailableRpcError(error) + throw error + } + }, + async disconnect() { + const provider = await this.getProvider() + + // Manage EIP-1193 event listeners + if (chainChanged) { + provider.removeListener('chainChanged', chainChanged) + chainChanged = undefined + } + if (disconnect) { + provider.removeListener('disconnect', disconnect) + disconnect = undefined + } + if (!connect) { + connect = this.onConnect.bind(this) + provider.on('connect', connect as Listener) + } + + await sdk.terminate() + }, + async getAccounts() { + const provider = await this.getProvider() + const accounts = (await provider.request({ + method: 'eth_accounts', + })) as string[] + return accounts.map((x) => getAddress(x)) + }, + async getChainId() { + const provider = await this.getProvider() + const chainId = + provider.getChainId() || + (await provider?.request({ method: 'eth_chainId' })) + return Number(chainId) + }, + async getProvider() { + async function initProvider() { + // Unwrapping import for Vite compatibility. + // See: https://github.com/vitejs/vite/issues/9703 + const MetaMaskSDK = await (async () => { + const { default: SDK } = await import('@metamask/sdk') + if (typeof SDK !== 'function' && typeof SDK.default === 'function') + return SDK.default + return SDK as unknown as typeof SDK.default + })() + + const readonlyRPCMap: RPC_URLS_MAP = {} + for (const chain of config.chains) + readonlyRPCMap[numberToHex(chain.id)] = extractRpcUrls({ + chain, + transports: config.transports, + })?.[0] + + sdk = new MetaMaskSDK({ + _source: 'wagmi', + forceDeleteProvider: false, + forceInjectProvider: false, + injectProvider: false, + // Workaround cast since MetaMask SDK does not support `'exactOptionalPropertyTypes'` + ...(parameters as RemoveUndefined), + readonlyRPCMap, + dappMetadata: { + ...parameters.dappMetadata, + // Test if name and url are set AND not empty + name: parameters.dappMetadata?.name + ? parameters.dappMetadata?.name + : 'wagmi', + url: parameters.dappMetadata?.url + ? parameters.dappMetadata?.url + : typeof window !== 'undefined' + ? window.location.origin + : 'https://wagmi.sh', + }, + useDeeplink: parameters.useDeeplink ?? true, + }) + const result = await sdk.init() + // On initial load, sometimes `sdk.getProvider` does not return provider. + // https://github.com/wevm/wagmi/issues/4367 + // Use result of `init` call if available. + const provider = (() => { + if (result?.activeProvider) return result.activeProvider + return sdk.getProvider() + })() + if (!provider) throw new ProviderNotFoundError() + return provider + } + + if (!provider) { + if (!providerPromise) providerPromise = initProvider() + provider = await providerPromise + } + return provider! + }, + async isAuthorized() { + try { + // MetaMask mobile provider sometimes fails to immediately resolve + // JSON-RPC requests on page load + const timeout = 200 + const accounts = await withRetry( + () => withTimeout(() => this.getAccounts(), { timeout }), + { + delay: timeout + 1, + retryCount: 3, + }, + ) + return !!accounts.length + } catch { + return false + } + }, + async switchChain({ addEthereumChainParameter, chainId }) { + const provider = await this.getProvider() + + const chain = config.chains.find((x) => x.id === chainId) + if (!chain) throw new SwitchChainError(new ChainNotConfiguredError()) + + try { + await provider.request({ + method: 'wallet_switchEthereumChain', + params: [{ chainId: numberToHex(chainId) }], + }) + + // During `'wallet_switchEthereumChain'`, MetaMask makes a `'net_version'` RPC call to the target chain. + // If this request fails, MetaMask does not emit the `'chainChanged'` event, but will still switch the chain. + // To counter this behavior, we request and emit the current chain ID to confirm the chain switch either via + // this callback or an externally emitted `'chainChanged'` event. + // https://github.com/MetaMask/metamask-extension/issues/24247 + await waitForChainIdToSync() + await sendAndWaitForChangeEvent(chainId) + + return chain + } catch (err) { + const error = err as RpcError + + if (error.code === UserRejectedRequestError.code) + throw new UserRejectedRequestError(error) + + // Indicates chain is not added to provider + if ( + error.code === 4902 || + // Unwrapping for MetaMask Mobile + // https://github.com/MetaMask/metamask-mobile/issues/2944#issuecomment-976988719 + (error as ProviderRpcError<{ originalError?: { code: number } }>) + ?.data?.originalError?.code === 4902 + ) { + try { + await provider.request({ + method: 'wallet_addEthereumChain', + params: [ + { + blockExplorerUrls: (() => { + const { default: blockExplorer, ...blockExplorers } = + chain.blockExplorers ?? {} + if (addEthereumChainParameter?.blockExplorerUrls) + return addEthereumChainParameter.blockExplorerUrls + if (blockExplorer) + return [ + blockExplorer.url, + ...Object.values(blockExplorers).map((x) => x.url), + ] + return + })(), + chainId: numberToHex(chainId), + chainName: addEthereumChainParameter?.chainName ?? chain.name, + iconUrls: addEthereumChainParameter?.iconUrls, + nativeCurrency: + addEthereumChainParameter?.nativeCurrency ?? + chain.nativeCurrency, + rpcUrls: (() => { + if (addEthereumChainParameter?.rpcUrls?.length) + return addEthereumChainParameter.rpcUrls + return [chain.rpcUrls.default?.http[0] ?? ''] + })(), + } satisfies AddEthereumChainParameter, + ], + }) + + await waitForChainIdToSync() + await sendAndWaitForChangeEvent(chainId) + + return chain + } catch (err) { + const error = err as RpcError + if (error.code === UserRejectedRequestError.code) + throw new UserRejectedRequestError(error) + throw new SwitchChainError(error) + } + } + + throw new SwitchChainError(error) + } + + async function waitForChainIdToSync() { + // On mobile, there is a race condition between the result of `'wallet_addEthereumChain'` and `'eth_chainId'`. + // To avoid this, we wait for `'eth_chainId'` to return the expected chain ID with a retry loop. + await withRetry( + async () => { + const value = hexToNumber( + // `'eth_chainId'` is cached by the MetaMask SDK side to avoid unnecessary deeplinks + (await provider.request({ method: 'eth_chainId' })) as Hex, + ) + // `value` doesn't match expected `chainId`, throw to trigger retry + if (value !== chainId) + throw new Error('User rejected switch after adding network.') + return value + }, + { + delay: 50, + retryCount: 20, // android device encryption is slower + }, + ) + } + + async function sendAndWaitForChangeEvent(chainId: number) { + await new Promise((resolve) => { + const listener = ((data) => { + if ('chainId' in data && data.chainId === chainId) { + config.emitter.off('change', listener) + resolve() + } + }) satisfies Parameters[1] + config.emitter.on('change', listener) + config.emitter.emit('change', { chainId }) + }) + } + }, + async onAccountsChanged(accounts) { + // Disconnect if there are no accounts + if (accounts.length === 0) { + // ... and using browser extension + if (sdk.isExtensionActive()) this.onDisconnect() + // FIXME(upstream): Mobile app sometimes emits invalid `accountsChanged` event with empty accounts array + else return + } + // Connect if emitter is listening for connect event (e.g. is disconnected and connects through wallet interface) + else if (config.emitter.listenerCount('connect')) { + const chainId = (await this.getChainId()).toString() + this.onConnect({ chainId }) + } + // Regular change event + else + config.emitter.emit('change', { + accounts: accounts.map((x) => getAddress(x)), + }) + }, + onChainChanged(chain) { + const chainId = Number(chain) + config.emitter.emit('change', { chainId }) + }, + async onConnect(connectInfo) { + const accounts = await this.getAccounts() + if (accounts.length === 0) return + + const chainId = Number(connectInfo.chainId) + config.emitter.emit('connect', { accounts, chainId }) + + const provider = await this.getProvider() + if (connect) { + provider.removeListener('connect', connect) + connect = undefined + } + if (!accountsChanged) { + accountsChanged = this.onAccountsChanged.bind(this) + provider.on('accountsChanged', accountsChanged as Listener) + } + if (!chainChanged) { + chainChanged = this.onChainChanged.bind(this) + provider.on('chainChanged', chainChanged as Listener) + } + if (!disconnect) { + disconnect = this.onDisconnect.bind(this) + provider.on('disconnect', disconnect as Listener) + } + }, + async onDisconnect(error) { + const provider = await this.getProvider() + + // If MetaMask emits a `code: 1013` error, wait for reconnection before disconnecting + // https://github.com/MetaMask/providers/pull/120 + if (error && (error as RpcError<1013>).code === 1013) { + if (provider && !!(await this.getAccounts()).length) return + } + + config.emitter.emit('disconnect') + + // Manage EIP-1193 event listeners + if (chainChanged) { + provider.removeListener('chainChanged', chainChanged) + chainChanged = undefined + } + if (disconnect) { + provider.removeListener('disconnect', disconnect) + disconnect = undefined + } + if (!connect) { + connect = this.onConnect.bind(this) + provider.on('connect', connect as Listener) + } + }, + onDisplayUri(uri) { + config.emitter.emit('message', { type: 'display_uri', data: uri }) + }, + })) +} diff --git a/wagmi-project/packages/connectors/src/safe.test.ts b/wagmi-project/packages/connectors/src/safe.test.ts new file mode 100644 index 0000000000..0571115f36 --- /dev/null +++ b/wagmi-project/packages/connectors/src/safe.test.ts @@ -0,0 +1,23 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { safe } from './safe.js' + +/* + * To manually test the Safe connector: + * + * 1. Run the wagmi playground app (`pnpm dev`) + * 2. Add a custom Safe App with App URL set to `http://localhost:5173` (make sure there is a `manifest.json` file served by the playground) + * 3. Open the playground app at `https://app.safe.global/eth:0x4557B18E779944BFE9d78A672452331C186a9f48/apps?appUrl=http%3A%2F%2Flocalhost%3A5173` + * + * See https://docs.gnosis-safe.io/learn/safe-tools/sdks/safe-apps/releasing-your-safe-app for more info. + */ + +test('setup', () => { + const connectorFn = safe({ + allowedDomains: [/gnosis-safe.io$/, /app.safe.global$/], + debug: false, + }) + const connector = config._internal.connectors.setup(connectorFn) + expect(connector.name).toEqual('Safe') +}) diff --git a/wagmi-project/packages/connectors/src/safe.ts b/wagmi-project/packages/connectors/src/safe.ts new file mode 100644 index 0000000000..13153e106f --- /dev/null +++ b/wagmi-project/packages/connectors/src/safe.ts @@ -0,0 +1,145 @@ +import type { SafeAppProvider } from '@safe-global/safe-apps-provider' +import type { Opts } from '@safe-global/safe-apps-sdk' +import { + type Connector, + ProviderNotFoundError, + createConnector, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { getAddress, withTimeout } from 'viem' + +export type SafeParameters = Compute< + Opts & { + /** + * Connector automatically connects when used as Safe App. + * + * This flag simulates the disconnect behavior by keeping track of connection status in storage + * and only autoconnecting when previously connected by user action (e.g. explicitly choosing to connect). + * + * @default false + */ + shimDisconnect?: boolean | undefined + /** + * Timeout in milliseconds for `getInfo` (from the Safe SDK) to resolve. + * + * `getInfo` does not resolve when not used in Safe App iFrame. This allows the connector to force a timeout. + * @default 10 + */ + unstable_getInfoTimeout?: number | undefined + } +> + +safe.type = 'safe' as const +export function safe(parameters: SafeParameters = {}) { + const { shimDisconnect = false } = parameters + + type Provider = SafeAppProvider | undefined + type Properties = Record + type StorageItem = { 'safe.disconnected': true } + + let provider_: Provider | undefined + + let disconnect: Connector['onDisconnect'] | undefined + + return createConnector((config) => ({ + id: 'safe', + name: 'Safe', + type: safe.type, + async connect() { + const provider = await this.getProvider() + if (!provider) throw new ProviderNotFoundError() + + const accounts = await this.getAccounts() + const chainId = await this.getChainId() + + if (!disconnect) { + disconnect = this.onDisconnect.bind(this) + provider.on('disconnect', disconnect) + } + + // Remove disconnected shim if it exists + if (shimDisconnect) await config.storage?.removeItem('safe.disconnected') + + return { accounts, chainId } + }, + async disconnect() { + const provider = await this.getProvider() + if (!provider) throw new ProviderNotFoundError() + + if (disconnect) { + provider.removeListener('disconnect', disconnect) + disconnect = undefined + } + + // Add shim signalling connector is disconnected + if (shimDisconnect) + await config.storage?.setItem('safe.disconnected', true) + }, + async getAccounts() { + const provider = await this.getProvider() + if (!provider) throw new ProviderNotFoundError() + return (await provider.request({ method: 'eth_accounts' })).map( + getAddress, + ) + }, + async getProvider() { + // Only allowed in iframe context + const isIframe = + typeof window !== 'undefined' && window?.parent !== window + if (!isIframe) return + + if (!provider_) { + const { default: SDK } = await import('@safe-global/safe-apps-sdk') + const sdk = new SDK(parameters) + + // `getInfo` hangs when not used in Safe App iFrame + // https://github.com/safe-global/safe-apps-sdk/issues/263#issuecomment-1029835840 + const safe = await withTimeout(() => sdk.safe.getInfo(), { + timeout: parameters.unstable_getInfoTimeout ?? 10, + }) + if (!safe) throw new Error('Could not load Safe information') + // Unwrapping import for Vite compatibility. + // See: https://github.com/vitejs/vite/issues/9703 + const SafeAppProvider = await (async () => { + const Provider = await import('@safe-global/safe-apps-provider') + if ( + typeof Provider.SafeAppProvider !== 'function' && + typeof Provider.default.SafeAppProvider === 'function' + ) + return Provider.default.SafeAppProvider + return Provider.SafeAppProvider + })() + provider_ = new SafeAppProvider(safe, sdk) + } + return provider_ + }, + async getChainId() { + const provider = await this.getProvider() + if (!provider) throw new ProviderNotFoundError() + return Number(provider.chainId) + }, + async isAuthorized() { + try { + const isDisconnected = + shimDisconnect && + // If shim exists in storage, connector is disconnected + (await config.storage?.getItem('safe.disconnected')) + if (isDisconnected) return false + + const accounts = await this.getAccounts() + return !!accounts.length + } catch { + return false + } + }, + onAccountsChanged() { + // Not relevant for Safe because changing account requires app reload. + }, + onChainChanged() { + // Not relevant for Safe because Safe smart contract wallets only exist on single chain. + }, + onDisconnect() { + config.emitter.emit('disconnect') + }, + })) +} diff --git a/wagmi-project/packages/connectors/src/version.ts b/wagmi-project/packages/connectors/src/version.ts new file mode 100644 index 0000000000..11f81d1c34 --- /dev/null +++ b/wagmi-project/packages/connectors/src/version.ts @@ -0,0 +1 @@ +export const version = '5.8.3' diff --git a/wagmi-project/packages/connectors/src/walletConnect.test.ts b/wagmi-project/packages/connectors/src/walletConnect.test.ts new file mode 100644 index 0000000000..4e8a74ebfe --- /dev/null +++ b/wagmi-project/packages/connectors/src/walletConnect.test.ts @@ -0,0 +1,67 @@ +import { config, walletConnectProjectId } from '@wagmi/test' +import { http, HttpResponse } from 'msw' +import { setupServer } from 'msw/node' +import { + afterAll, + afterEach, + beforeAll, + expect, + expectTypeOf, + test, + vi, +} from 'vitest' + +import { walletConnect } from './walletConnect.js' + +const handlers = [ + http.get('https://relay.walletconnect.com', async () => + HttpResponse.json( + { + topic: '222781e3-3fad-4184-acde-077796bf0d3d', + type: 'sub', + payload: '', + silent: true, + }, + { status: 200 }, + ), + ), +] + +const server = setupServer(...handlers) + +beforeAll(() => { + server.listen({ + onUnhandledRequest: 'warn', + }) + + const matchMedia = vi.fn().mockImplementation((query) => { + return { + matches: false, + media: query, + onchange: null, + addListener: vi.fn(), // deprecated + removeListener: vi.fn(), // deprecated + addEventListener: vi.fn(), + removeEventListener: vi.fn(), + dispatchEvent: vi.fn(), + } + }) + vi.stubGlobal('matchMedia', matchMedia) +}) + +afterEach(() => server.resetHandlers()) + +afterAll(() => server.close()) + +test('setup', () => { + const connectorFn = walletConnect({ projectId: walletConnectProjectId }) + const connector = config._internal.connectors.setup(connectorFn) + expect(connector.name).toEqual('WalletConnect') + + type ConnectFnParameters = NonNullable< + Parameters<(typeof connector)['connect']>[0] + > + expectTypeOf().toMatchTypeOf< + string | undefined + >() +}) diff --git a/wagmi-project/packages/connectors/src/walletConnect.ts b/wagmi-project/packages/connectors/src/walletConnect.ts new file mode 100644 index 0000000000..963377d992 --- /dev/null +++ b/wagmi-project/packages/connectors/src/walletConnect.ts @@ -0,0 +1,468 @@ +import { + ChainNotConfiguredError, + type Connector, + ProviderNotFoundError, + createConnector, + extractRpcUrls, +} from '@wagmi/core' +import type { Compute, ExactPartial, Omit } from '@wagmi/core/internal' +import type { EthereumProvider } from '@walletconnect/ethereum-provider' +import { + type AddEthereumChainParameter, + type Address, + type ProviderConnectInfo, + type ProviderRpcError, + type RpcError, + SwitchChainError, + UserRejectedRequestError, + getAddress, + numberToHex, +} from 'viem' + +type WalletConnectConnector = Connector & { + onDisplayUri(uri: string): void + onSessionDelete(data: { topic: string }): void +} + +type EthereumProviderOptions = Parameters<(typeof EthereumProvider)['init']>[0] + +export type WalletConnectParameters = Compute< + { + /** + * If a new chain is added to a previously existing configured connector `chains`, this flag + * will determine if that chain should be considered as stale. A stale chain is a chain that + * WalletConnect has yet to establish a relationship with (e.g. the user has not approved or + * rejected the chain). + * + * This flag mainly affects the behavior when a wallet does not support dynamic chain authorization + * with WalletConnect v2. + * + * If `true` (default), the new chain will be treated as a stale chain. If the user + * has yet to establish a relationship (approved/rejected) with this chain in their WalletConnect + * session, the connector will disconnect upon the dapp auto-connecting, and the user will have to + * reconnect to the dapp (revalidate the chain) in order to approve the newly added chain. + * This is the default behavior to avoid an unexpected error upon switching chains which may + * be a confusing user experience (e.g. the user will not know they have to reconnect + * unless the dapp handles these types of errors). + * + * If `false`, the new chain will be treated as a potentially valid chain. This means that if the user + * has yet to establish a relationship with the chain in their WalletConnect session, wagmi will successfully + * auto-connect the user. This comes with the trade-off that the connector will throw an error + * when attempting to switch to the unapproved chain if the wallet does not support dynamic session updates. + * This may be useful in cases where a dapp constantly + * modifies their configured chains, and they do not want to disconnect the user upon + * auto-connecting. If the user decides to switch to the unapproved chain, it is important that the + * dapp handles this error and prompts the user to reconnect to the dapp in order to approve + * the newly added chain. + * + * @default true + */ + isNewChainsStale?: boolean + } & Omit< + EthereumProviderOptions, + | 'chains' + | 'events' + | 'optionalChains' + | 'optionalEvents' + | 'optionalMethods' + | 'methods' + | 'rpcMap' + | 'showQrModal' + > & + ExactPartial> +> + +walletConnect.type = 'walletConnect' as const +export function walletConnect(parameters: WalletConnectParameters) { + const isNewChainsStale = parameters.isNewChainsStale ?? true + + type Provider = Awaited> + type Properties = { + connect(parameters?: { + chainId?: number | undefined + isReconnecting?: boolean | undefined + pairingTopic?: string | undefined + }): Promise<{ + accounts: readonly Address[] + chainId: number + }> + getNamespaceChainsIds(): number[] + getRequestedChainsIds(): Promise + isChainsStale(): Promise + onConnect(connectInfo: ProviderConnectInfo): void + onDisplayUri(uri: string): void + onSessionDelete(data: { topic: string }): void + setRequestedChainsIds(chains: number[]): void + requestedChainsStorageKey: `${string}.requestedChains` + } + type StorageItem = { + [_ in Properties['requestedChainsStorageKey']]: number[] + } + + let provider_: Provider | undefined + let providerPromise: Promise + const NAMESPACE = 'eip155' + + let accountsChanged: WalletConnectConnector['onAccountsChanged'] | undefined + let chainChanged: WalletConnectConnector['onChainChanged'] | undefined + let connect: WalletConnectConnector['onConnect'] | undefined + let displayUri: WalletConnectConnector['onDisplayUri'] | undefined + let sessionDelete: WalletConnectConnector['onSessionDelete'] | undefined + let disconnect: WalletConnectConnector['onDisconnect'] | undefined + + return createConnector((config) => ({ + id: 'walletConnect', + name: 'WalletConnect', + type: walletConnect.type, + async setup() { + const provider = await this.getProvider().catch(() => null) + if (!provider) return + if (!connect) { + connect = this.onConnect.bind(this) + provider.on('connect', connect) + } + if (!sessionDelete) { + sessionDelete = this.onSessionDelete.bind(this) + provider.on('session_delete', sessionDelete) + } + }, + async connect({ chainId, ...rest } = {}) { + try { + const provider = await this.getProvider() + if (!provider) throw new ProviderNotFoundError() + if (!displayUri) { + displayUri = this.onDisplayUri + provider.on('display_uri', displayUri) + } + + let targetChainId = chainId + if (!targetChainId) { + const state = (await config.storage?.getItem('state')) ?? {} + const isChainSupported = config.chains.some( + (x) => x.id === state.chainId, + ) + if (isChainSupported) targetChainId = state.chainId + else targetChainId = config.chains[0]?.id + } + if (!targetChainId) throw new Error('No chains found on connector.') + + const isChainsStale = await this.isChainsStale() + // If there is an active session with stale chains, disconnect current session. + if (provider.session && isChainsStale) await provider.disconnect() + + // If there isn't an active session or chains are stale, connect. + if (!provider.session || isChainsStale) { + const optionalChains = config.chains + .filter((chain) => chain.id !== targetChainId) + .map((optionalChain) => optionalChain.id) + await provider.connect({ + optionalChains: [targetChainId, ...optionalChains], + ...('pairingTopic' in rest + ? { pairingTopic: rest.pairingTopic } + : {}), + }) + + this.setRequestedChainsIds(config.chains.map((x) => x.id)) + } + + // If session exists and chains are authorized, enable provider for required chain + const accounts = (await provider.enable()).map((x) => getAddress(x)) + const currentChainId = await this.getChainId() + + if (displayUri) { + provider.removeListener('display_uri', displayUri) + displayUri = undefined + } + if (connect) { + provider.removeListener('connect', connect) + connect = undefined + } + if (!accountsChanged) { + accountsChanged = this.onAccountsChanged.bind(this) + provider.on('accountsChanged', accountsChanged) + } + if (!chainChanged) { + chainChanged = this.onChainChanged.bind(this) + provider.on('chainChanged', chainChanged) + } + if (!disconnect) { + disconnect = this.onDisconnect.bind(this) + provider.on('disconnect', disconnect) + } + if (!sessionDelete) { + sessionDelete = this.onSessionDelete.bind(this) + provider.on('session_delete', sessionDelete) + } + + return { accounts, chainId: currentChainId } + } catch (error) { + if ( + /(user rejected|connection request reset)/i.test( + (error as ProviderRpcError)?.message, + ) + ) { + throw new UserRejectedRequestError(error as Error) + } + throw error + } + }, + async disconnect() { + const provider = await this.getProvider() + try { + await provider?.disconnect() + } catch (error) { + if (!/No matching key/i.test((error as Error).message)) throw error + } finally { + if (chainChanged) { + provider?.removeListener('chainChanged', chainChanged) + chainChanged = undefined + } + if (disconnect) { + provider?.removeListener('disconnect', disconnect) + disconnect = undefined + } + if (!connect) { + connect = this.onConnect.bind(this) + provider?.on('connect', connect) + } + if (accountsChanged) { + provider?.removeListener('accountsChanged', accountsChanged) + accountsChanged = undefined + } + if (sessionDelete) { + provider?.removeListener('session_delete', sessionDelete) + sessionDelete = undefined + } + + this.setRequestedChainsIds([]) + } + }, + async getAccounts() { + const provider = await this.getProvider() + return provider.accounts.map((x) => getAddress(x)) + }, + async getProvider({ chainId } = {}) { + async function initProvider() { + const optionalChains = config.chains.map((x) => x.id) as [number] + if (!optionalChains.length) return + const { EthereumProvider } = await import( + '@walletconnect/ethereum-provider' + ) + return await EthereumProvider.init({ + ...parameters, + disableProviderPing: true, + optionalChains, + projectId: parameters.projectId, + rpcMap: Object.fromEntries( + config.chains.map((chain) => { + const [url] = extractRpcUrls({ + chain, + transports: config.transports, + }) + return [chain.id, url] + }), + ), + showQrModal: parameters.showQrModal ?? true, + }) + } + + if (!provider_) { + if (!providerPromise) providerPromise = initProvider() + provider_ = await providerPromise + provider_?.events.setMaxListeners(100) + } + if (chainId) await this.switchChain?.({ chainId }) + return provider_! + }, + async getChainId() { + const provider = await this.getProvider() + return provider.chainId + }, + async isAuthorized() { + try { + const [accounts, provider] = await Promise.all([ + this.getAccounts(), + this.getProvider(), + ]) + + // If an account does not exist on the session, then the connector is unauthorized. + if (!accounts.length) return false + + // If the chains are stale on the session, then the connector is unauthorized. + const isChainsStale = await this.isChainsStale() + if (isChainsStale && provider.session) { + await provider.disconnect().catch(() => {}) + return false + } + return true + } catch { + return false + } + }, + async switchChain({ addEthereumChainParameter, chainId }) { + const provider = await this.getProvider() + if (!provider) throw new ProviderNotFoundError() + + const chain = config.chains.find((x) => x.id === chainId) + if (!chain) throw new SwitchChainError(new ChainNotConfiguredError()) + + try { + await Promise.all([ + new Promise((resolve) => { + const listener = ({ + chainId: currentChainId, + }: { chainId?: number | undefined }) => { + if (currentChainId === chainId) { + config.emitter.off('change', listener) + resolve() + } + } + config.emitter.on('change', listener) + }), + provider.request({ + method: 'wallet_switchEthereumChain', + params: [{ chainId: numberToHex(chainId) }], + }), + ]) + + const requestedChains = await this.getRequestedChainsIds() + this.setRequestedChainsIds([...requestedChains, chainId]) + + return chain + } catch (err) { + const error = err as RpcError + + if (/(user rejected)/i.test(error.message)) + throw new UserRejectedRequestError(error) + + // Indicates chain is not added to provider + try { + let blockExplorerUrls: string[] | undefined + if (addEthereumChainParameter?.blockExplorerUrls) + blockExplorerUrls = addEthereumChainParameter.blockExplorerUrls + else + blockExplorerUrls = chain.blockExplorers?.default.url + ? [chain.blockExplorers?.default.url] + : [] + + let rpcUrls: readonly string[] + if (addEthereumChainParameter?.rpcUrls?.length) + rpcUrls = addEthereumChainParameter.rpcUrls + else rpcUrls = [...chain.rpcUrls.default.http] + + const addEthereumChain = { + blockExplorerUrls, + chainId: numberToHex(chainId), + chainName: addEthereumChainParameter?.chainName ?? chain.name, + iconUrls: addEthereumChainParameter?.iconUrls, + nativeCurrency: + addEthereumChainParameter?.nativeCurrency ?? chain.nativeCurrency, + rpcUrls, + } satisfies AddEthereumChainParameter + + await provider.request({ + method: 'wallet_addEthereumChain', + params: [addEthereumChain], + }) + + const requestedChains = await this.getRequestedChainsIds() + this.setRequestedChainsIds([...requestedChains, chainId]) + return chain + } catch (error) { + throw new UserRejectedRequestError(error as Error) + } + } + }, + onAccountsChanged(accounts) { + if (accounts.length === 0) this.onDisconnect() + else + config.emitter.emit('change', { + accounts: accounts.map((x) => getAddress(x)), + }) + }, + onChainChanged(chain) { + const chainId = Number(chain) + config.emitter.emit('change', { chainId }) + }, + async onConnect(connectInfo) { + const chainId = Number(connectInfo.chainId) + const accounts = await this.getAccounts() + config.emitter.emit('connect', { accounts, chainId }) + }, + async onDisconnect(_error) { + this.setRequestedChainsIds([]) + config.emitter.emit('disconnect') + + const provider = await this.getProvider() + if (accountsChanged) { + provider.removeListener('accountsChanged', accountsChanged) + accountsChanged = undefined + } + if (chainChanged) { + provider.removeListener('chainChanged', chainChanged) + chainChanged = undefined + } + if (disconnect) { + provider.removeListener('disconnect', disconnect) + disconnect = undefined + } + if (sessionDelete) { + provider.removeListener('session_delete', sessionDelete) + sessionDelete = undefined + } + if (!connect) { + connect = this.onConnect.bind(this) + provider.on('connect', connect) + } + }, + onDisplayUri(uri) { + config.emitter.emit('message', { type: 'display_uri', data: uri }) + }, + onSessionDelete() { + this.onDisconnect() + }, + getNamespaceChainsIds() { + if (!provider_) return [] + const chainIds = provider_.session?.namespaces[NAMESPACE]?.accounts?.map( + (account) => Number.parseInt(account.split(':')[1] || ''), + ) + return chainIds ?? [] + }, + async getRequestedChainsIds() { + return ( + (await config.storage?.getItem(this.requestedChainsStorageKey)) ?? [] + ) + }, + /** + * Checks if the target chains match the chains that were + * initially requested by the connector for the WalletConnect session. + * If there is a mismatch, this means that the chains on the connector + * are considered stale, and need to be revalidated at a later point (via + * connection). + * + * There may be a scenario where a dapp adds a chain to the + * connector later on, however, this chain will not have been approved or rejected + * by the wallet. In this case, the chain is considered stale. + */ + async isChainsStale() { + if (!isNewChainsStale) return false + + const connectorChains = config.chains.map((x) => x.id) + const namespaceChains = this.getNamespaceChainsIds() + if ( + namespaceChains.length && + !namespaceChains.some((id) => connectorChains.includes(id)) + ) + return false + + const requestedChains = await this.getRequestedChainsIds() + return !connectorChains.every((id) => requestedChains.includes(id)) + }, + async setRequestedChainsIds(chains) { + await config.storage?.setItem(this.requestedChainsStorageKey, chains) + }, + get requestedChainsStorageKey() { + return `${this.id}.requestedChains` as Properties['requestedChainsStorageKey'] + }, + })) +} diff --git a/wagmi-project/packages/connectors/tsconfig.build.json b/wagmi-project/packages/connectors/tsconfig.build.json new file mode 100644 index 0000000000..fbed2b1036 --- /dev/null +++ b/wagmi-project/packages/connectors/tsconfig.build.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.base.json", + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.test.ts", "src/**/*.test-d.ts"], + "compilerOptions": { + "sourceMap": true + } +} diff --git a/wagmi-project/packages/connectors/tsconfig.json b/wagmi-project/packages/connectors/tsconfig.json new file mode 100644 index 0000000000..bd33919ac3 --- /dev/null +++ b/wagmi-project/packages/connectors/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "./tsconfig.build.json", + "include": ["src/**/*.ts"], + "exclude": [] +} diff --git a/wagmi-project/packages/core/CHANGELOG.md b/wagmi-project/packages/core/CHANGELOG.md new file mode 100644 index 0000000000..88b541e93e --- /dev/null +++ b/wagmi-project/packages/core/CHANGELOG.md @@ -0,0 +1,3365 @@ +# @wagmi/core + +## 2.17.2 + +### Patch Changes + +- [`29297a48af72b537173d948ccd2fe37d39914c66`](https://github.com/wevm/wagmi/commit/29297a48af72b537173d948ccd2fe37d39914c66) Thanks [@jxom](https://github.com/jxom)! - Fixed `sendCalls` generics. + +- [`07370106d5fb6b8fe300992d93abf25b3d0eaf57`](https://github.com/wevm/wagmi/commit/07370106d5fb6b8fe300992d93abf25b3d0eaf57) Thanks [@jxom](https://github.com/jxom)! - Fixed propagation of `waitForCallsStatus` parameters. + +## 2.17.1 + +### Patch Changes + +- [#4649](https://github.com/wevm/wagmi/pull/4649) [`01f64e64fa4f85cdd30023903f972f4f9023681f`](https://github.com/wevm/wagmi/commit/01f64e64fa4f85cdd30023903f972f4f9023681f) Thanks [@jxom](https://github.com/jxom)! - Added `chainId` parameter to `getCapabilities`/`useCapabilities`. + +## 2.17.0 + +### Minor Changes + +- [#4638](https://github.com/wevm/wagmi/pull/4638) [`799ee4d4b23c2ecd64e3f3668e67634e81939719`](https://github.com/wevm/wagmi/commit/799ee4d4b23c2ecd64e3f3668e67634e81939719) Thanks [@jxom](https://github.com/jxom)! - Stabilized EIP-5792 Actions & Hooks. + +## 2.16.7 + +### Patch Changes + +- [`a4bd0623eed28e3761a27295831a60ad835f0ee0`](https://github.com/wevm/wagmi/commit/a4bd0623eed28e3761a27295831a60ad835f0ee0) Thanks [@jxom](https://github.com/jxom)! - **Experimental (EIP-5792):** Updated `id` parameter to be optional on `useWaitForCallsStatus`. + +## 2.16.6 + +### Patch Changes + +- [#4586](https://github.com/wevm/wagmi/pull/4586) [`edf47477b2f6385a1c3ae01d36a8498c47f30a0b`](https://github.com/wevm/wagmi/commit/edf47477b2f6385a1c3ae01d36a8498c47f30a0b) Thanks [@jxom](https://github.com/jxom)! - **Experimental (EIP-5792):** Added `waitForCallsStatus` + `useWaitForCallsStatus`. + +## 2.16.5 + +### Patch Changes + +- [`d0c9a86921a4e939373cc6e763284e53f2a2e93c`](https://github.com/wevm/wagmi/commit/d0c9a86921a4e939373cc6e763284e53f2a2e93c) Thanks [@jxom](https://github.com/jxom)! - **Experimental (ERC-5792)**: Added support for `account: null` in `sendCalls` to cater for sending calls without a connected account (account will be filled by the wallet). + +## 2.16.4 + +### Patch Changes + +- [`507f864d91238bfd423d0e36d3619eb9f6e52eec`](https://github.com/wevm/wagmi/commit/507f864d91238bfd423d0e36d3619eb9f6e52eec) Thanks [@jxom](https://github.com/jxom)! - Updated `@coinbase/wallet-sdk`. + +## 2.16.3 + +### Patch Changes + +- [#4480](https://github.com/wevm/wagmi/pull/4480) [`384a1d91597622eb59e1c05dc13ce25017c5b6d8`](https://github.com/wevm/wagmi/commit/384a1d91597622eb59e1c05dc13ce25017c5b6d8) Thanks [@RodeRickIsWatching](https://github.com/RodeRickIsWatching)! - Fixed invocation of default storage. + +## 2.16.2 + +### Patch Changes + +- [`012907032b532a438fce48f407470250cbc8f0c6`](https://github.com/wevm/wagmi/commit/012907032b532a438fce48f407470250cbc8f0c6) Thanks [@jxom](https://github.com/jxom)! - Fixed assignment in `getDefaultStorage`. + +## 2.16.1 + +### Patch Changes + +- [#4472](https://github.com/wevm/wagmi/pull/4472) [`3892ebd21c06beef4b28ece4e70d2a38807bce6f`](https://github.com/wevm/wagmi/commit/3892ebd21c06beef4b28ece4e70d2a38807bce6f) Thanks [@tmm](https://github.com/tmm)! - Added handling to default storage for `setItem` errors, like `QuotaExceededError`, `SecurityError`, etc. + +## 2.16.0 + +### Minor Changes + +- [#4453](https://github.com/wevm/wagmi/pull/4453) [`070e48480194c8d7f45bda1d7dd1346e6f5d7227`](https://github.com/wevm/wagmi/commit/070e48480194c8d7f45bda1d7dd1346e6f5d7227) Thanks [@tmm](https://github.com/tmm)! - Added narrowing to `config.connectors`. + +### Patch Changes + +- [`afea6b67822a7a2b96901ec851441d27ee0f7a52`](https://github.com/wevm/wagmi/commit/afea6b67822a7a2b96901ec851441d27ee0f7a52) Thanks [@tmm](https://github.com/tmm)! - Passed through parameters to `connector.connect` in `connect` action. + +## 2.15.2 + +### Patch Changes + +- [#4433](https://github.com/wevm/wagmi/pull/4433) [`06e186cd679b27fe195309110e766fcf46d4efbc`](https://github.com/wevm/wagmi/commit/06e186cd679b27fe195309110e766fcf46d4efbc) Thanks [@Aerilym](https://github.com/Aerilym)! - Bumped Metamask SDK version to `0.31.1`. + +## 2.15.1 + +### Patch Changes + +- [`b8bbb409f4934538e3dd6cac5aaf7346292d0693`](https://github.com/wevm/wagmi/commit/b8bbb409f4934538e3dd6cac5aaf7346292d0693) Thanks [@jxom](https://github.com/jxom)! - Fixed issue where `null` gas would accidentally pass through. + +## 2.15.0 + +### Minor Changes + +- [#4417](https://github.com/wevm/wagmi/pull/4417) [`42e65ea4fea99c639817088bba915e0933d17141`](https://github.com/wevm/wagmi/commit/42e65ea4fea99c639817088bba915e0933d17141) Thanks [@jxom](https://github.com/jxom)! - Removed simulation in `writeContract` & `sendTransaction`. + +## 2.14.6 + +### Patch Changes + +- [#4406](https://github.com/wevm/wagmi/pull/4406) [`a13aa8d7c38eb3cc8171a02d6302e6d12cf6bcb3`](https://github.com/wevm/wagmi/commit/a13aa8d7c38eb3cc8171a02d6302e6d12cf6bcb3) Thanks [@tmm](https://github.com/tmm)! - Added support for multiple connector `rdns` entries. + +## 2.14.5 + +### Patch Changes + +- [#4400](https://github.com/wevm/wagmi/pull/4400) [`6b9bbacdc7bffd44fc2165362a5e65fd434e7646`](https://github.com/wevm/wagmi/commit/6b9bbacdc7bffd44fc2165362a5e65fd434e7646) Thanks [@AzzouQ](https://github.com/AzzouQ)! - Fixed `createWatchContractEvent` internal wiring, where `eventName` was incorrectly `functionName`. + +## 2.14.4 + +### Patch Changes + +- [#4311](https://github.com/wevm/wagmi/pull/4311) [`e08681c81fbdf475213e2d0f4c5517d0abf4e743`](https://github.com/wevm/wagmi/commit/e08681c81fbdf475213e2d0f4c5517d0abf4e743) Thanks [@chybisov](https://github.com/chybisov)! - Fixed `injected` connector race condition after calling `'wallet_addEthereumChain'` in `switchChain`. + +## 2.14.3 + +### Patch Changes + +- [`cb7dd2ebb871d0be8f1a11a8cd8ce592cd74b7c7`](https://github.com/wevm/wagmi/commit/cb7dd2ebb871d0be8f1a11a8cd8ce592cd74b7c7) Thanks [@tmm](https://github.com/tmm)! - Removed unnecessary internal deep equal check in `structuralSharing`. + +## 2.14.2 + +### Patch Changes + +- [#4339](https://github.com/wevm/wagmi/pull/4339) [`d0d0963bb5904a15cf0355862d62dd141ce0c31c`](https://github.com/wevm/wagmi/commit/d0d0963bb5904a15cf0355862d62dd141ce0c31c) Thanks [@AndriyAntonenko](https://github.com/AndriyAntonenko)! - Fixed bug in `waitForTransactionReceipt`, where transaction data wasn't passed to `'eth_call'` method as part of getting the revert reason. + +- [`ecac0ba36243d94c9199d0bd21937104c835d9a0`](https://github.com/wevm/wagmi/commit/ecac0ba36243d94c9199d0bd21937104c835d9a0) Thanks [@tmm](https://github.com/tmm)! - Fixed `getBalance` symbol error handling. + +## 2.14.1 + +### Patch Changes + +- [`052e72e1f8c1c14fcbdce04a9f8fa7ec28d83702`](https://github.com/wevm/wagmi/commit/052e72e1f8c1c14fcbdce04a9f8fa7ec28d83702) Thanks [@tmm](https://github.com/tmm)! - Added `defaultConnected` feature to `mock` connector. + +- [#4349](https://github.com/wevm/wagmi/pull/4349) [`b250fc21ee577b2a75c5a34ff684f62fb4ad771a`](https://github.com/wevm/wagmi/commit/b250fc21ee577b2a75c5a34ff684f62fb4ad771a) Thanks [@tmm](https://github.com/tmm)! - Bumped internal deps. + +## 2.14.0 + +### Minor Changes + +- [#4343](https://github.com/wevm/wagmi/pull/4343) [`f43e074f473820b208a6295d7c97f847332f1a1d`](https://github.com/wevm/wagmi/commit/f43e074f473820b208a6295d7c97f847332f1a1d) Thanks [@tmm](https://github.com/tmm)! - Added `rdns` property to connector interface. This is used to filter out duplicate [EIP-6963](https://eips.ethereum.org/EIPS/eip-6963) injected providers when [`createConfig#multiInjectedProviderDiscovery`](https://wagmi.sh/core/api/createConfig#multiinjectedproviderdiscovery) is enabled and `createConfig#connectors` already matches EIP-6963 providers' `rdns` property. + +## 2.13.9 + +### Patch Changes + +- [#4336](https://github.com/wevm/wagmi/pull/4336) [`c05caabc20c3ced9682cfc7ba1f3f7dcfece0703`](https://github.com/wevm/wagmi/commit/c05caabc20c3ced9682cfc7ba1f3f7dcfece0703) Thanks [@EdouardBougon](https://github.com/EdouardBougon)! - Added deprecation notice to `injected` target flags. + +## 2.13.8 + +### Patch Changes + +- [#4207](https://github.com/wevm/wagmi/pull/4207) [`56f2482508f2ba71bd6b0295c70c6abca7101e57`](https://github.com/wevm/wagmi/commit/56f2482508f2ba71bd6b0295c70c6abca7101e57) Thanks [@Smert](https://github.com/Smert)! - Updated chain switch listener for `injected` and `metaMask` to be more robust. + +## 2.13.7 + +### Patch Changes + +- [`be75c2d4ef636d7362420ab0a106bfdf63f5d1e6`](https://github.com/wevm/wagmi/commit/be75c2d4ef636d7362420ab0a106bfdf63f5d1e6) Thanks [@tmm](https://github.com/tmm)! - Added guard for missing `provider.on` for `injected` connector. + +## 2.13.6 + +### Patch Changes + +- [#4286](https://github.com/wevm/wagmi/pull/4286) [`edcbf5d6fbe92f639bead800502edda9e0aa39f1`](https://github.com/wevm/wagmi/commit/edcbf5d6fbe92f639bead800502edda9e0aa39f1) Thanks [@holic](https://github.com/holic)! - Removed duplicate code. + +## 2.13.5 + +### Patch Changes + +- [#4259](https://github.com/wevm/wagmi/pull/4259) [`f47ce8f6d263e49fdff90b8edb3190142d2657bb`](https://github.com/wevm/wagmi/commit/f47ce8f6d263e49fdff90b8edb3190142d2657bb) Thanks [@tmm](https://github.com/tmm)! - Added guard to `getConnectorClient` when reconnecting to check if connector is fully restored. + +## 2.13.4 + +### Patch Changes + +- [`b4c8971788c70b09479946ecfa998cff2f1b3953`](https://github.com/wevm/wagmi/commit/b4c8971788c70b09479946ecfa998cff2f1b3953) Thanks [@tmm](https://github.com/tmm)! - Made `serialize` and `deserialize` types more permissive. + +## 2.13.3 + +### Patch Changes + +- [`871dbdbfe59ac8ad01d1ec6150ea7b091b7b7de4`](https://github.com/wevm/wagmi/commit/871dbdbfe59ac8ad01d1ec6150ea7b091b7b7de4) Thanks [@tmm](https://github.com/tmm)! - Added validation to internal state for persisted `chainId`. + +## 2.13.2 + +### Patch Changes + +- [`1b9b523fa9b9dfe839aecdf4b40caa9547d7e594`](https://github.com/wevm/wagmi/commit/1b9b523fa9b9dfe839aecdf4b40caa9547d7e594) Thanks [@tmm](https://github.com/tmm)! - Fixed built-in cookie storage `removeItem` working for all paths. + +## 2.13.1 + +### Patch Changes + +- [`07c1227f306d0efb9421d4bb77a774f92f5fcf45`](https://github.com/wevm/wagmi/commit/07c1227f306d0efb9421d4bb77a774f92f5fcf45) Thanks [@tmm](https://github.com/tmm)! - Fixed internal `extractRpcUrls` usage with `unstable_connector`. + +## 2.13.0 + +### Minor Changes + +- [#4162](https://github.com/wevm/wagmi/pull/4162) [`a73a7737b756886b388f120ae423e72cca53e8a0`](https://github.com/wevm/wagmi/commit/a73a7737b756886b388f120ae423e72cca53e8a0) Thanks [@jxom](https://github.com/jxom)! - Added functionality for consumer-defined RPC URLs (`config.transports`) to be propagated to the WalletConnect & MetaMask Connectors. + +## 2.12.2 + +### Patch Changes + +- [`5bc8c8877810b2eec24a829df87dce40a51e6f20`](https://github.com/wevm/wagmi/commit/5bc8c8877810b2eec24a829df87dce40a51e6f20) Thanks [@tmm](https://github.com/tmm)! - Fixed reconnection when `status` is defined. + +## 2.12.1 + +### Patch Changes + +- [#4146](https://github.com/wevm/wagmi/pull/4146) [`cc996e08e930c9e88cf753a1e874652059e81a3b`](https://github.com/wevm/wagmi/commit/cc996e08e930c9e88cf753a1e874652059e81a3b) Thanks [@jxom](https://github.com/jxom)! - Updated `@safe-global/safe-apps-sdk` + `@safe-global/safe-apps-provider` dependencies. + +## 2.12.0 + +### Minor Changes + +- [#4128](https://github.com/wevm/wagmi/pull/4128) [`5581a810ef70308e99c6f8b630cd4bca59f64afc`](https://github.com/wevm/wagmi/commit/5581a810ef70308e99c6f8b630cd4bca59f64afc) Thanks [@dalechyn](https://github.com/dalechyn)! - Added `watchAsset` action. + +## 2.11.8 + +### Patch Changes + +- [`b08013eaa9ce97c02f8a7128ea400e3da7ef74bb`](https://github.com/wevm/wagmi/commit/b08013eaa9ce97c02f8a7128ea400e3da7ef74bb) Thanks [@tmm](https://github.com/tmm)! - Fixed injected accounts ordering for `'wallet_requestPermissions'`. + +- [`d3814ab4b88f9f0e052b53bc3d458df87b43f01d`](https://github.com/wevm/wagmi/commit/d3814ab4b88f9f0e052b53bc3d458df87b43f01d) Thanks [@jxom](https://github.com/jxom)! - Updated `mipd` dependency. + +## 2.11.7 + +### Patch Changes + +- [`0bb8b562ae04ecfeb2d6b2f1b980ebae31dc127e`](https://github.com/wevm/wagmi/commit/0bb8b562ae04ecfeb2d6b2f1b980ebae31dc127e) Thanks [@tmm](https://github.com/tmm)! - Improved TypeScript `'exactOptionalPropertyTypes'` support. + +## 2.11.6 + +### Patch Changes + +- [#4060](https://github.com/wevm/wagmi/pull/4060) [`95965c1f19d480b97f2b297a077a9e607dee32ad`](https://github.com/wevm/wagmi/commit/95965c1f19d480b97f2b297a077a9e607dee32ad) Thanks [@dalechyn](https://github.com/dalechyn)! - Bumped Tanstack Query dependencies to fix typing issues between exported Wagmi query options and TanStack Query suspense query methods (due to [`direction` property in `QueryFunctionContext` being deprecated](https://github.com/TanStack/query/pull/7410)). + +## 2.11.5 + +### Patch Changes + +- [#4079](https://github.com/wevm/wagmi/pull/4079) [`04f2b846b113f3d300d82c9fa75212f1805817c5`](https://github.com/wevm/wagmi/commit/04f2b846b113f3d300d82c9fa75212f1805817c5) Thanks [@tmm](https://github.com/tmm)! - Added revalidation for config chain ID in SSR and migration. + +## 2.11.4 + +### Patch Changes + +- [`9e8345cd56186b997b5e56deaa2cfc69b30d15f6`](https://github.com/wevm/wagmi/commit/9e8345cd56186b997b5e56deaa2cfc69b30d15f6) Thanks [@tmm](https://github.com/tmm)! - Switched `Register` to `interface` to fix declaration merging. + +## 2.11.3 + +### Patch Changes + +- [#4065](https://github.com/wevm/wagmi/pull/4065) [`8974e6269bb5d7bfaa90db0246bc7d13e8bff798`](https://github.com/wevm/wagmi/commit/8974e6269bb5d7bfaa90db0246bc7d13e8bff798) Thanks [@alx-khramov](https://github.com/alx-khramov)! - Added timeout to internal call of `'wallet_revokePermissions'` request during `injected#disconnect` as some wallets that do not support this method hang. + +## 2.11.2 + +### Patch Changes + +- [#4042](https://github.com/wevm/wagmi/pull/4042) [`b4d9ef79deb554ee20fed6666a474be5e7cdd522`](https://github.com/wevm/wagmi/commit/b4d9ef79deb554ee20fed6666a474be5e7cdd522) Thanks [@tmm](https://github.com/tmm)! - Removed `injected` connector `isAuthorized` timeout. + +## 2.11.1 + +### Patch Changes + +- [`9c862d8d63e3d692a22cef2a90782b74a9103f17`](https://github.com/wevm/wagmi/commit/9c862d8d63e3d692a22cef2a90782b74a9103f17) Thanks [@tmm](https://github.com/tmm)! - Reverted internal module loading utility. + +## 2.11.0 + +### Minor Changes + +- [#3816](https://github.com/wevm/wagmi/pull/3816) [`06bb598a7f04c7b167f5b7ff6d46bd15886a6a14`](https://github.com/wevm/wagmi/commit/06bb598a7f04c7b167f5b7ff6d46bd15886a6a14) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Added `deployContract` action. + +### Patch Changes + +- [`24a45b269bd0214a29d6f82a84ac66ef8c3f3822`](https://github.com/wevm/wagmi/commit/24a45b269bd0214a29d6f82a84ac66ef8c3f3822) Thanks [@tmm](https://github.com/tmm)! - Added `SameSite` default to `cookieStorage` + +## 2.10.6 + +### Patch Changes + +- [#4009](https://github.com/wevm/wagmi/pull/4009) [`f2a7cefab96691ebed8b8e45ffde071c47b58dbe`](https://github.com/wevm/wagmi/commit/f2a7cefab96691ebed8b8e45ffde071c47b58dbe) Thanks [@roninjin10](https://github.com/roninjin10)! - Marked `to` as optional for `sendTransaction`. + +- [#4023](https://github.com/wevm/wagmi/pull/4023) [`f0ea0b2a7fe193dadfeb49a4c8031ee451c638b5`](https://github.com/wevm/wagmi/commit/f0ea0b2a7fe193dadfeb49a4c8031ee451c638b5) Thanks [@jxom](https://github.com/jxom)! - Added chain check to `getConnectorClient` since it's possible for connection state chain ID to get out of sync with the connector (e.g. [wallet bug](https://github.com/MetaMask/metamask-extension/issues/25097)). + +## 2.10.5 + +### Patch Changes + +- [#3970](https://github.com/wevm/wagmi/pull/3970) [`030c7c2cb380dfd67a2182f62e2aa7a6e1601898`](https://github.com/wevm/wagmi/commit/030c7c2cb380dfd67a2182f62e2aa7a6e1601898) Thanks [@nanxiaobei](https://github.com/nanxiaobei)! - Fixed `cookieStorage` not working across paths. + +## 2.10.4 + +### Patch Changes + +- [#3984](https://github.com/wevm/wagmi/pull/3984) [`51fde8a0433b4fff357c1a8d7e08b41b4c86c968`](https://github.com/wevm/wagmi/commit/51fde8a0433b4fff357c1a8d7e08b41b4c86c968) Thanks [@tmm](https://github.com/tmm)! - Fixed `writeContract` query types for `value` property. + +## 2.10.3 + +### Patch Changes + +- [#3962](https://github.com/wevm/wagmi/pull/3962) [`2804a8a583b1874271154898b4bae38756ef581c`](https://github.com/wevm/wagmi/commit/2804a8a583b1874271154898b4bae38756ef581c) Thanks [@tmm](https://github.com/tmm)! - Added catch to `reconnect`. + +## 2.10.2 + +### Patch Changes + +- [#3940](https://github.com/wevm/wagmi/pull/3940) [`a5071f581dfdfb961718873643a2fc629101c72a`](https://github.com/wevm/wagmi/commit/a5071f581dfdfb961718873643a2fc629101c72a) Thanks [@jxom](https://github.com/jxom)! - Fixed usage of `metaMask` connector in Vite environments. + +## 2.10.1 + +### Patch Changes + +- Bumped versions. + +## 2.10.0 + +### Minor Changes + +- [#3928](https://github.com/wevm/wagmi/pull/3928) [`3117e71825f9c58a0d718f3d1686f1a191fa9cb1`](https://github.com/wevm/wagmi/commit/3117e71825f9c58a0d718f3d1686f1a191fa9cb1) Thanks [@tmm](https://github.com/tmm)! - Updated the default Coinbase SDK in `coinbaseWallet` Connector to v4.x. + +## 2.9.8 + +### Patch Changes + +- [#3906](https://github.com/wevm/wagmi/pull/3906) [`32fcb4a31dde6b0206961d8ffe9c651f8a459c67`](https://github.com/wevm/wagmi/commit/32fcb4a31dde6b0206961d8ffe9c651f8a459c67) Thanks [@tmm](https://github.com/tmm)! - Added support for Vue. + +## 2.9.7 + +### Patch Changes + +- [#3924](https://github.com/wevm/wagmi/pull/3924) [`1f58734f88458e0f6adb05c99f0c90f36ab286b8`](https://github.com/wevm/wagmi/commit/1f58734f88458e0f6adb05c99f0c90f36ab286b8) Thanks [@jxom](https://github.com/jxom)! - Refactored `isChainsStale` logic in `walletConnect` connector. + +## 2.9.6 + +### Patch Changes + +- [#3917](https://github.com/wevm/wagmi/pull/3917) [`05948fdad5bb4a56b08916d45b3dec2cb1e5f55b`](https://github.com/wevm/wagmi/commit/05948fdad5bb4a56b08916d45b3dec2cb1e5f55b) Thanks [@jxom](https://github.com/jxom)! - Updated `@metamask/sdk`. + +## 2.9.5 + +### Patch Changes + +- [`4fecbbb66d0aacd03b8c62a6455d11a33cde8f85`](https://github.com/wevm/wagmi/commit/4fecbbb66d0aacd03b8c62a6455d11a33cde8f85) Thanks [@jxom](https://github.com/jxom)! - Fixed address comparison in `getConnectorClient`. + +## 2.9.4 + +### Patch Changes + +- [#3910](https://github.com/wevm/wagmi/pull/3910) [`e6139a97c4b8804d734b1547b5e3921ce01fbe24`](https://github.com/wevm/wagmi/commit/e6139a97c4b8804d734b1547b5e3921ce01fbe24) Thanks [@tmm](https://github.com/tmm)! - Added experimental `wallet_revokePermissions` support to `injected`. + +## 2.9.3 + +### Patch Changes + +- [#3904](https://github.com/wevm/wagmi/pull/3904) [`addca28ebc20f1a4367c35fe9ef786decff9c87e`](https://github.com/wevm/wagmi/commit/addca28ebc20f1a4367c35fe9ef786decff9c87e) Thanks [@jxom](https://github.com/jxom)! - Updated `@walletconnect/ethereum-provider`. + +## 2.9.2 + +### Patch Changes + +- [#3902](https://github.com/wevm/wagmi/pull/3902) [`204b7b624612405500ec098fb9e35facd3f74ca4`](https://github.com/wevm/wagmi/commit/204b7b624612405500ec098fb9e35facd3f74ca4) Thanks [@jxom](https://github.com/jxom)! - Made third-party SDK imports type-only. + +## 2.9.1 + +### Patch Changes + +- [`cda6a5d5`](https://github.com/wevm/wagmi/commit/cda6a5d56328330fbde050b4ef40b01c58d2519a) Thanks [@jxom](https://github.com/jxom)! - Updated packages. + +## 2.9.0 + +### Minor Changes + +- [#3878](https://github.com/wevm/wagmi/pull/3878) [`017828fc`](https://github.com/wevm/wagmi/commit/017828fc027c7a84b54ea9d627e9389f4d60d6c2) Thanks [@jxom](https://github.com/jxom)! - Added experimental EIP-5792 Actions & Hooks. + +## 2.8.1 + +### Patch Changes + +- [#3869](https://github.com/wevm/wagmi/pull/3869) [`d4a78eb0`](https://github.com/wevm/wagmi/commit/d4a78eb07119d2e5617e52481ac7d6c6d1583ddc) Thanks [@jxom](https://github.com/jxom)! - Fixed issue where `prepareTransactionRequest` would internally call unsupported wallet RPC methods. + +## 2.8.0 + +### Minor Changes + +- [#3868](https://github.com/wevm/wagmi/pull/3868) [`c2af20b8`](https://github.com/wevm/wagmi/commit/c2af20b88cf16970d087faaec10b463357a5836e) Thanks [@jxom](https://github.com/jxom)! - Added `supportsSimulation` property to connectors that indicates if the connector's wallet supports contract simulation. + +### Patch Changes + +- [#3858](https://github.com/wevm/wagmi/pull/3858) [`0d141f17`](https://github.com/wevm/wagmi/commit/0d141f171d6ec44bcbfc9c876565b5e2fb8af6de) Thanks [@yulafezmesi](https://github.com/yulafezmesi)! - Fixed accessing reverted reason property inside `waitForTransactionReceipt`. + +## 2.7.0 + +### Minor Changes + +- [#3857](https://github.com/wevm/wagmi/pull/3857) [`d4274c03`](https://github.com/wevm/wagmi/commit/d4274c03a6af5f2d26d31432016ebc14950a330e) Thanks [@tmm](https://github.com/tmm)! - Added `addEthereumChainParameter` to `switchChain`-related methods. + +### Patch Changes + +- [#3849](https://github.com/wevm/wagmi/pull/3849) [`4781a405`](https://github.com/wevm/wagmi/commit/4781a4056d4ffc2c74f96a75429e9b2cd2417ad8) Thanks [@tmm](https://github.com/tmm)! - Fixed `shimDisconnect: false` behavior. + +- [#3859](https://github.com/wevm/wagmi/pull/3859) [`400c960b`](https://github.com/wevm/wagmi/commit/400c960b30d701c134850c695ae903a382c29b5b) Thanks [@holic](https://github.com/holic)! - Added workaround to injected connector for MetaMask bug, where chain switching does not work if target chain RPC `'net_version'` request fails. + +## 2.6.19 + +### Patch Changes + +- [`e3c832a1`](https://github.com/wevm/wagmi/commit/e3c832a12c301f9b0ee129d877b3101d220ba8b2) Thanks [@jxom](https://github.com/jxom)! - Fixed undefined `navigator` issue in MetaMask connector. + +## 2.6.18 + +### Patch Changes + +- [#3848](https://github.com/wevm/wagmi/pull/3848) [`dd40a41c`](https://github.com/wevm/wagmi/commit/dd40a41c526ab60a288aff2250ed8dba92a27b16) Thanks [@jxom](https://github.com/jxom)! - Updated MetaMask SDK. + +## 2.6.17 + +### Patch Changes + +- [#3822](https://github.com/wevm/wagmi/pull/3822) [`a97bfbae`](https://github.com/wevm/wagmi/commit/a97bfbaeb615cfef04665e5e7348d85d17f960f0) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where Wagmi would not correctly rehydrate the active chain when a persisted store was being used. + +## 2.6.16 + +### Patch Changes + +- [#3788](https://github.com/wevm/wagmi/pull/3788) [`42ad380d`](https://github.com/wevm/wagmi/commit/42ad380d9a5d8bc0f61d73612142dea9d098de5e) Thanks [@tmm](https://github.com/tmm)! - Refactored connectors to remove unnecessarily event listeners. + +## 2.6.15 + +### Patch Changes + +- [#3782](https://github.com/wevm/wagmi/pull/3782) [`b907d5ac`](https://github.com/wevm/wagmi/commit/b907d5ac3a746bcbccc06d1fe78c5bd8f9a7d685) Thanks [@jxom](https://github.com/jxom)! - Refactored injected connector connection logic. + +## 2.6.14 + +### Patch Changes + +- [#3777](https://github.com/wevm/wagmi/pull/3777) [`b3b54ef1`](https://github.com/wevm/wagmi/commit/b3b54ef179c5fa0d1694d38d4b808549a0550409) Thanks [@desfero](https://github.com/desfero)! - Fixed `writeContract` to forward `chainIn` when simulating contract call + +- [#3779](https://github.com/wevm/wagmi/pull/3779) [`3da20bb8`](https://github.com/wevm/wagmi/commit/3da20bb80e7c3efeef8227ced66ad615370fc242) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where `eth_requestAccounts` would be called upon reconnect instead of `eth_accounts`. + +- [`a3d1858f`](https://github.com/wevm/wagmi/commit/a3d1858fce448d2b70e36ee692ef1589b74e9d3f) Thanks [@jxom](https://github.com/jxom)! - Fixed hydration conditional in `createConfig`. + +## 2.6.13 + +### Patch Changes + +- [`b80236dc`](https://github.com/wevm/wagmi/commit/b80236dc623095fe8f1e1d10957d7776fb6ab48b) Thanks [@jxom](https://github.com/jxom)! - Removed unneeded `uniqueBy` check on connectors state. + +## 2.6.12 + +### Patch Changes + +- [#3763](https://github.com/wevm/wagmi/pull/3763) [`a59069e9`](https://github.com/wevm/wagmi/commit/a59069e9fab45dd606bb89a7f829fe94c51a5494) Thanks [@tmm](https://github.com/tmm)! - Fixed `getConnectorClient` internal address comparison. + +- [#3608](https://github.com/wevm/wagmi/pull/3608) [`0acd3132`](https://github.com/wevm/wagmi/commit/0acd31320f534993af566be5490c2978b6184f66) Thanks [@mqklin](https://github.com/mqklin)! - Disabled `wallet_requestPermissions` prompt when `shimDisconnect` is `false`. + +## 2.6.11 + +### Patch Changes + +- [`e1ca4e63`](https://github.com/wevm/wagmi/commit/e1ca4e637ae6cec7f5902b0a2c0e0efc3b751a1d) Thanks [@tmm](https://github.com/tmm)! - Deprecated `normalizeChainId`. Use `Number` instead. + +## 2.6.10 + +### Patch Changes + +- [`dbdca8fd`](https://github.com/wevm/wagmi/commit/dbdca8fd14b90c166222a66a373c1b33c06ce019) Thanks [@jxom](https://github.com/jxom)! - Fixed issue where duplicate connectors could be instantiated if injected after page mount. + +## 2.6.9 + +### Patch Changes + +- [#3715](https://github.com/wevm/wagmi/pull/3715) [`d56edf4f`](https://github.com/wevm/wagmi/commit/d56edf4f27c52acc7a0f57114454b0d3e22cacd6) Thanks [@jxom](https://github.com/jxom)! - Fixed SSR hydration issues. + +## 2.6.8 + +### Patch Changes + +- [#3643](https://github.com/wevm/wagmi/pull/3643) [`e46bcd47`](https://github.com/wevm/wagmi/commit/e46bcd4738a18da15b53f6612b614379c1985374) Thanks [@TateB](https://github.com/TateB)! - Fixed race condition arising from `reconnect`. + +## 2.6.7 + +### Patch Changes + +- [#3642](https://github.com/wevm/wagmi/pull/3642) [`b479b5e8`](https://github.com/wevm/wagmi/commit/b479b5e8a5866cba792862f22e6352c4fb566137) Thanks [@johanneskares](https://github.com/johanneskares)! - Fixed a bug where minification caused the wrong functions to be called on the client. + +- [`f5648dd2`](https://github.com/wevm/wagmi/commit/f5648dd28b3576b628f57732b89287f55acbb1c1) Thanks [@jxom](https://github.com/jxom)! - Updated `prepareTransactionRequest` types for `viem@2.8.0`. + +- [`1c1fee6a`](https://github.com/wevm/wagmi/commit/1c1fee6ab8f01f7734ac6ce05093fa8e388beb3e) Thanks [@jxom](https://github.com/jxom)! - Updated `@walletconnect/ethereum-provider`. + +- [#3653](https://github.com/wevm/wagmi/pull/3653) [`88a2d744`](https://github.com/wevm/wagmi/commit/88a2d744a1315908c9e54156026df3ad2435ad44) Thanks [@tash-2s](https://github.com/tash-2s)! - Fixed error occurring when adding chains without explorers to MetaMask. + +## 2.6.6 + +### Patch Changes + +- [#3644](https://github.com/wevm/wagmi/pull/3644) [`a91c0b64`](https://github.com/wevm/wagmi/commit/a91c0b64ba8b3e6537a560e69724eb601f26af27) Thanks [@nishuzumi](https://github.com/nishuzumi)! - Exported types + +## 2.6.5 + +### Patch Changes + +- [#3580](https://github.com/wevm/wagmi/pull/3580) [`c677dcd2`](https://github.com/wevm/wagmi/commit/c677dcd245dccdf69289a3d66dded237b09570a2) Thanks [@tmm](https://github.com/tmm)! - Updated internals. + +## 2.6.4 + +### Patch Changes + +- [#3571](https://github.com/wevm/wagmi/pull/3571) [`7c6618e6`](https://github.com/wevm/wagmi/commit/7c6618e6a0eb1ff39cf8f66b34d3ddc14be538fe) Thanks [@tmm](https://github.com/tmm)! - Fixed `getClient` passthrough properties from `createConfig`. + +- [#3558](https://github.com/wevm/wagmi/pull/3558) [`895f28e8`](https://github.com/wevm/wagmi/commit/895f28e873af7c8eda5ca85734ff67c8979fd950) Thanks [@tmm](https://github.com/tmm)! - Fixed connector warnings. + +## 2.6.3 + +### Patch Changes + +- [#3533](https://github.com/wevm/wagmi/pull/3533) [`9c3b85dd`](https://github.com/wevm/wagmi/commit/9c3b85dd0a9a4a593e1d7e029345275735330e32) Thanks [@tmm](https://github.com/tmm)! - Fixed `account` property passthrough for actions. + +- [`2a72214a`](https://github.com/wevm/wagmi/commit/2a72214a2901d6b6ddd39f80238aa0bd4db670a7) Thanks [@tmm](https://github.com/tmm)! - Shimmed EIP-1193 `removeListener` for injected since some wallets do not follow spec. + +## 2.6.2 + +### Patch Changes + +- [#3519](https://github.com/wevm/wagmi/pull/3519) [`414eb048`](https://github.com/wevm/wagmi/commit/414eb048af492caac70c0e874dfc87c30702804a) Thanks [@tmm](https://github.com/tmm)! - Fixed multicall passing through all properties to Viem method. + +- [#3518](https://github.com/wevm/wagmi/pull/3518) [`338e857d`](https://github.com/wevm/wagmi/commit/338e857d8cb2fe85e13d9207bef14cada1c1962d) Thanks [@tmm](https://github.com/tmm)! - Fixed internal store migration between versions. + +## 2.6.1 + +### Patch Changes + +- [#3510](https://github.com/wevm/wagmi/pull/3510) [`660ff80d`](https://github.com/wevm/wagmi/commit/660ff80d5b046967a446eba43ee54b8359a37d0d) Thanks [@tmm](https://github.com/tmm)! - Fixed issue where connectors returning multiple addresses didn't checksum correctly. + +- [#3433](https://github.com/wevm/wagmi/pull/3433) [`101a7dd1`](https://github.com/wevm/wagmi/commit/101a7dd131b0cae2dc25579ecab9044290efd37b) Thanks [@tmm](https://github.com/tmm)! - Fixed `getClient` and `getPublicClient` throwing when used with unconfigured `chainId`. + +## 2.6.0 + +### Minor Changes + +- [#3496](https://github.com/wevm/wagmi/pull/3496) [`ba7f8a75`](https://github.com/wevm/wagmi/commit/ba7f8a758efb07664c6e401b5e7e325e7c62341b) Thanks [@tmm](https://github.com/tmm)! - Updated action internals to resolve Viem Client actions. + +## 2.5.0 + +### Minor Changes + +- [#3461](https://github.com/wevm/wagmi/pull/3461) [`ca98041d`](https://github.com/wevm/wagmi/commit/ca98041d1b39893d90246929485f4db0d1c6f9f7) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Added `getTransactionConfirmations` action. + +## 2.4.0 + +### Minor Changes + +- [#3427](https://github.com/wevm/wagmi/pull/3427) [`370f1b4a`](https://github.com/wevm/wagmi/commit/370f1b4a3f154d181acf381c31c2e7862e22c0e4) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Added `prepareTransactionRequest` action. + +## 2.3.1 + +### Patch Changes + +- [#3476](https://github.com/wevm/wagmi/pull/3476) [`3be5bb7b`](https://github.com/wevm/wagmi/commit/3be5bb7b0b38646e12e6da5c762ef74dff66bcc2) Thanks [@jxom](https://github.com/jxom)! - Modified persist strategy to only store "critical" properties that are needed before hydration. + +## 2.3.0 + +### Minor Changes + +- [#3459](https://github.com/wevm/wagmi/pull/3459) [`d950b666`](https://github.com/wevm/wagmi/commit/d950b666b56700ca039ce16cdfdf34564991e7f5) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Added `getEnsText` action. + +### Patch Changes + +- [#3467](https://github.com/wevm/wagmi/pull/3467) [`90ef39bb`](https://github.com/wevm/wagmi/commit/90ef39bb0f4ecb3c914d317875348e35ba0f4524) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where connectors that share the same provider instance could reconnect when they have never been connected before. + +- [`1cfb6e5a`](https://github.com/wevm/wagmi/commit/1cfb6e5a875e707abcee00dd5739e87da05e8c90) Thanks [@jxom](https://github.com/jxom)! - Bumped listener limit on WalletConnect connector. + +## 2.2.1 + +### Patch Changes + +- [#3447](https://github.com/wevm/wagmi/pull/3447) [`a02a26ad`](https://github.com/wevm/wagmi/commit/a02a26ad030d3afb78f744377d61b5c60b65d97a) Thanks [@tmm](https://github.com/tmm)! - Fixed account typing. + +- [#3443](https://github.com/wevm/wagmi/pull/3443) [`007024a6`](https://github.com/wevm/wagmi/commit/007024a684ddbecf924cdc06dd6a8854fc3d5eeb) Thanks [@jmrossy](https://github.com/jmrossy)! - Fixed invalid `chainId` parameter passed through actions to Viem. + +## 2.2.0 + +### Minor Changes + +- [#3434](https://github.com/wevm/wagmi/pull/3434) [`00bf10a4`](https://github.com/wevm/wagmi/commit/00bf10a428b0d1c5dac35ebf25b19571e033ac26) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Added `getBytecode` and `getStorageAt` actions. + +- [#3416](https://github.com/wevm/wagmi/pull/3416) [`64c073f6`](https://github.com/wevm/wagmi/commit/64c073f6c2720961e2d6aff986670b73dbfab9c3) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Added `getTransactionReceipt` action. + +- [#3408](https://github.com/wevm/wagmi/pull/3408) [`fb6c4148`](https://github.com/wevm/wagmi/commit/fb6c4148d9e9e2fccfbe74c8f343b444dc68dec5) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Added `getProof` action. + +## 2.1.2 + +### Patch Changes + +- [#3407](https://github.com/wevm/wagmi/pull/3407) [`e00b8205`](https://github.com/wevm/wagmi/commit/e00b82058685751637edfa9a6b2d196a12549fe7) Thanks [@jxom](https://github.com/jxom)! - Added a prelude gas estimate check to `sendTransaction`/`useSendTransaction`. + +## 2.1.1 + +### Patch Changes + +- [#3402](https://github.com/wevm/wagmi/pull/3402) [`64b82282`](https://github.com/wevm/wagmi/commit/64b82282c1e57e77c25aa0814673780e4d11edd4) Thanks [@Songkeys](https://github.com/Songkeys)! - Fixed SSR cookie support for cookies that have special characters, e.g. `=`. + +- [`ec0d8b41`](https://github.com/wevm/wagmi/commit/ec0d8b4112181fefb11025e436a94a6114761d37) Thanks [@tmm](https://github.com/tmm)! - Added note to `metaMask` connector. + +## 2.1.0 + +### Minor Changes + +- [#3387](https://github.com/wevm/wagmi/pull/3387) [`c9cd302e`](https://github.com/wevm/wagmi/commit/c9cd302e1c65c980deaee2e12567c2a8ec08b399) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Added `call` action. + +## 2.0.2 + +### Patch Changes + +- [#3384](https://github.com/wevm/wagmi/pull/3384) [`ee868c33`](https://github.com/wevm/wagmi/commit/ee868c3385dae511230b6ddcb5627c1293cc1844) Thanks [@tmm](https://github.com/tmm)! - Fixed connectors not bubbling error when connecting with `chainId` and subsequent user rejection. + +## 2.0.1 + +### Major Changes + +- [#3333](https://github.com/wevm/wagmi/pull/3333) [`b3a0baaa`](https://github.com/wevm/wagmi/commit/b3a0baaaee7decf750d376aab2502cd33ca4825a) Thanks [@tmm](https://github.com/tmm)! - Wagmi Core 2.0 featuring: + + - Full TanStack Query support + queryKeys + - Connect multiple connectors + - Switch chains while disconnected + - EIP-6963 enabled + - Strongly typed chainId and chain properties + - Smaller bundle size + - Miscellaneous improvements and bug fixes + + [Breaking Changes & Migration Guide](https://wagmi.sh/core/guides/migrate-from-v1-to-v2) + +## 1.4.13 + +### Patch Changes + +- Updated dependencies [[`bbbbf587`](https://github.com/wevm/wagmi/commit/bbbbf587e41bae12b072b7a7c897d580fc07cd2b)]: + - @wagmi/connectors@3.1.11 + +## 1.4.12 + +### Patch Changes + +- [`53ca1f7e`](https://github.com/wevm/wagmi/commit/53ca1f7eb411d912e11fcce7e03bd61ed067959c) Thanks [@tmm](https://github.com/tmm)! - Removed LedgerConnector due to security vulnerability + +- Updated dependencies [[`53ca1f7e`](https://github.com/wevm/wagmi/commit/53ca1f7eb411d912e11fcce7e03bd61ed067959c)]: + - @wagmi/connectors@3.1.10 + +## 1.4.11 + +### Patch Changes + +- [#3299](https://github.com/wevm/wagmi/pull/3299) [`b02020b3`](https://github.com/wevm/wagmi/commit/b02020b3724e0228198f35817611bb063295906e) Thanks [@dasanra](https://github.com/dasanra)! - Fixed issue with [Safe SDK](https://github.com/wevm/viem/issues/579) by bumping `@safe-global/safe-apps-provider@0.18.1` + +- Updated dependencies [[`51eca0fb`](https://github.com/wevm/wagmi/commit/51eca0fbaea6932f31a5b8b4213f0252280053e2), [`b02020b3`](https://github.com/wevm/wagmi/commit/b02020b3724e0228198f35817611bb063295906e)]: + - @wagmi/connectors@3.1.9 + +## 1.4.10 + +### Patch Changes + +- Updated dependencies [[`e8f7bcbc`](https://github.com/wevm/wagmi/commit/e8f7bcbcd9c038a901c29e71769682c088efe2ac)]: + - @wagmi/connectors@3.1.8 + +## 1.4.9 + +### Patch Changes + +- [#3276](https://github.com/wevm/wagmi/pull/3276) [`83223a06`](https://github.com/wevm/wagmi/commit/83223a0659e2f675d897a1d3374c7af752c16abf) Thanks [@glitch-txs](https://github.com/glitch-txs)! - Removed required namespaces from WalletConnect connector + +- Updated dependencies [[`83223a06`](https://github.com/wevm/wagmi/commit/83223a0659e2f675d897a1d3374c7af752c16abf)]: + - @wagmi/connectors@3.1.7 + +## 1.4.8 + +### Patch Changes + +- Updated dependencies [[`cc7e18f2`](https://github.com/wevm/wagmi/commit/cc7e18f2e7f6b8b989f60f0b05aee70e996a9975), [`cc7e18f2`](https://github.com/wevm/wagmi/commit/cc7e18f2e7f6b8b989f60f0b05aee70e996a9975)]: + - @wagmi/connectors@3.1.6 + +## 1.4.7 + +### Patch Changes + +- Updated dependencies [[`a1950449`](https://github.com/wagmi-dev/wagmi/commit/a1950449127ddf72fff8ecd1fc34c3690befbb05)]: + - @wagmi/connectors@3.1.5 + +## 1.4.6 + +### Patch Changes + +- Updated dependencies [[`4e6ec415`](https://github.com/wagmi-dev/wagmi/commit/4e6ec4151baece94e940e227e0e3711c7f8534d9)]: + - @wagmi/connectors@3.1.4 + +## 1.4.5 + +### Patch Changes + +- Updated dependencies [[`e78aa337`](https://github.com/wagmi-dev/wagmi/commit/e78aa337c454f04b41a3cbd381d25270dd4a0afd)]: + - @wagmi/connectors@3.1.3 + +## 1.4.4 + +### Patch Changes + +- [#3125](https://github.com/wagmi-dev/wagmi/pull/3125) [`725e73fe`](https://github.com/wagmi-dev/wagmi/commit/725e73feb9143dbaa6d540bb76d2009cef29da0b) Thanks [@lukasrosario](https://github.com/lukasrosario)! - Fixed an issue where `dataSuffix` was not being passed down into viem's `simulateContract`, causing the data to be omitted from requests. + +## 1.4.3 + +### Patch Changes + +- [#3076](https://github.com/wagmi-dev/wagmi/pull/3076) [`4c36831b`](https://github.com/wagmi-dev/wagmi/commit/4c36831b7aa44d03b5c0decf64dcd20faae28a67) Thanks [@jxom](https://github.com/jxom)! - Pass `chain` to viem `sendTransaction`/`writeContract`. + +- [#3006](https://github.com/wagmi-dev/wagmi/pull/3006) [`f2ddce23`](https://github.com/wagmi-dev/wagmi/commit/f2ddce23324aff0a91e066100918dac552dc3b4a) Thanks [@jxom](https://github.com/jxom)! - Changed `normalize` to a dynamic import. + +## 1.4.2 + +### Patch Changes + +- Updated dependencies [[`3aaba328`](https://github.com/wagmi-dev/wagmi/commit/3aaba32808ddb4035ec885f96992c91078056715)]: + - @wagmi/connectors@3.1.2 + +## 1.4.1 + +### Patch Changes + +- Updated dependencies [[`bf831bb3`](https://github.com/wagmi-dev/wagmi/commit/bf831bb30df8037cc4312342d0fe3c045408c2fe)]: + - @wagmi/connectors@3.1.1 + +## 1.4.0 + +### Minor Changes + +- [#2956](https://github.com/wagmi-dev/wagmi/pull/2956) [`2abeb285`](https://github.com/wagmi-dev/wagmi/commit/2abeb285674af3e539cc2550b1f5027b1eb0c895) Thanks [@tmm](https://github.com/tmm)! - Replaced `@wagmi/chains` with `viem/chains`. + +### Patch Changes + +- Updated dependencies [[`2abeb285`](https://github.com/wagmi-dev/wagmi/commit/2abeb285674af3e539cc2550b1f5027b1eb0c895)]: + - @wagmi/connectors@3.1.0 + +## 1.3.10 + +### Patch Changes + +- [`557e6400`](https://github.com/wagmi-dev/wagmi/commit/557e6400b9cef3b2c5131739143956c37d7c934a) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +## 1.3.9 + +### Patch Changes + +- [`247c5d11`](https://github.com/wagmi-dev/wagmi/commit/247c5d113e83acf3a6894264c00d4b125d455107) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +## 1.3.8 + +### Patch Changes + +- [#2741](https://github.com/wagmi-dev/wagmi/pull/2741) [`5b1453d9`](https://github.com/wagmi-dev/wagmi/commit/5b1453d95973ed51f1c235a919fffb707eab9b70) Thanks [@jxom](https://github.com/jxom)! - Updated references + +## 1.3.7 + +### Patch Changes + +- [#2700](https://github.com/wagmi-dev/wagmi/pull/2700) [`30118e97`](https://github.com/wagmi-dev/wagmi/commit/30118e979b1b00302e035f31f58c15d1aed911d5) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +## 1.3.6 + +### Patch Changes + +- [`7ad2fdb8`](https://github.com/wagmi-dev/wagmi/commit/7ad2fdb81c7734d0c8107670800c68390e3bad99) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +## 1.3.5 + +### Patch Changes + +- [`aab63fc1`](https://github.com/wagmi-dev/wagmi/commit/aab63fc1f8949004573978ecd8574fada3360758) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +## 1.3.4 + +### Patch Changes + +- [`22246d98`](https://github.com/wagmi-dev/wagmi/commit/22246d9884277d28ccad6ca2d9529b96b67d47fc) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +## 1.3.3 + +### Patch Changes + +- [`1946aa43`](https://github.com/wagmi-dev/wagmi/commit/1946aa43a65b684ef41b7b4c43c67bf29c13e854) Thanks [@jxom](https://github.com/jxom)! - Updated references + +## 1.3.2 + +### Patch Changes + +- [`e86d0940`](https://github.com/wagmi-dev/wagmi/commit/e86d09409bb20b64d24e1263abcf0291314f03c7) Thanks [@jxom](https://github.com/jxom)! - Updated references + +## 1.3.1 + +### Patch Changes + +- [`964042fa`](https://github.com/wagmi-dev/wagmi/commit/964042fa94d682977923c595820c58283fb9244a) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +## 1.3.0 + +### Minor Changes + +- [#2619](https://github.com/wagmi-dev/wagmi/pull/2619) [`0d79748c`](https://github.com/wagmi-dev/wagmi/commit/0d79748cec2b6ac2410ad2c9816cc662f2b70962) Thanks [@jxom](https://github.com/jxom)! - Updated references: + - Updated `@safe-global/safe-apps-sdk` to `^8.0.0` (the one with `viem` support) + +## 1.2.2 + +### Patch Changes + +- [#2611](https://github.com/wagmi-dev/wagmi/pull/2611) [`6d1ed7a1`](https://github.com/wagmi-dev/wagmi/commit/6d1ed7a156729b4df5d66fef3ae9a8b5762a2d34) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +## 1.2.1 + +### Patch Changes + +- [#2589](https://github.com/wagmi-dev/wagmi/pull/2589) [`9680c347`](https://github.com/wagmi-dev/wagmi/commit/9680c347476500d28ceca20d23eeaed7931cb6e0) Thanks [@jxom](https://github.com/jxom)! - Fixed `writeContract` parameters to be compatible with `prepareWriteContract`. + +- [#2587](https://github.com/wagmi-dev/wagmi/pull/2587) [`cfff9994`](https://github.com/wagmi-dev/wagmi/commit/cfff999459384ac644ff7e62f53a7b787cf37507) Thanks [@jxom](https://github.com/jxom)! - Updated references + +## 1.2.0 + +### Minor Changes + +- [#2536](https://github.com/wagmi-dev/wagmi/pull/2536) [`85e9760a`](https://github.com/wagmi-dev/wagmi/commit/85e9760a140cb169ac6236d9466b96e2105dd193) Thanks [@tmm](https://github.com/tmm)! - Changed `Address` type import from ABIType to viem. + +### Patch Changes + +- [#2539](https://github.com/wagmi-dev/wagmi/pull/2539) [`96319c64`](https://github.com/wagmi-dev/wagmi/commit/96319c640b9d07b375821c08a5c213355d8c290b) Thanks [@jxom](https://github.com/jxom)! - Updated references + +## 1.1.1 + +### Patch Changes + +- [`02b98a9f`](https://github.com/wagmi-dev/wagmi/commit/02b98a9f9b2c503a47af4a8967e0202b5db21787) Thanks [@jxom](https://github.com/jxom)! - Updated `viem` peer dependency. + +- [`02b98a9f`](https://github.com/wagmi-dev/wagmi/commit/02b98a9f9b2c503a47af4a8967e0202b5db21787) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +## 1.1.0 + +### Minor Changes + +- [#2482](https://github.com/wagmi-dev/wagmi/pull/2482) [`8764b54a`](https://github.com/wagmi-dev/wagmi/commit/8764b54aab68020063946112e8fe52aff650c99c) Thanks [@tmm](https://github.com/tmm)! - Bumped minimum TypeScript version to v5.0.4. + +### Patch Changes + +- [#2484](https://github.com/wagmi-dev/wagmi/pull/2484) [`3adf1f4f`](https://github.com/wagmi-dev/wagmi/commit/3adf1f4feab863cb7b5d52c81ad46f7e4eb56f09) Thanks [@jxom](https://github.com/jxom)! - Updated `abitype` to 0.8.7 + +- [#2484](https://github.com/wagmi-dev/wagmi/pull/2484) [`3adf1f4f`](https://github.com/wagmi-dev/wagmi/commit/3adf1f4feab863cb7b5d52c81ad46f7e4eb56f09) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +## 1.0.8 + +### Patch Changes + +- [#2441](https://github.com/wagmi-dev/wagmi/pull/2441) [`326edee4`](https://github.com/wagmi-dev/wagmi/commit/326edee4bc85db84a7a4e3768e33785849ab8d8e) Thanks [@tmm](https://github.com/tmm)! - Fixed internal type issue + +## 1.0.7 + +### Patch Changes + +- [#2433](https://github.com/wagmi-dev/wagmi/pull/2433) [`54fcff5f`](https://github.com/wagmi-dev/wagmi/commit/54fcff5f02f6933bbbe045ee0c83c5a78b6bba49) Thanks [@jxom](https://github.com/jxom)! - Added ability to pass an `account` to `writeContract`/`prepareWriteContract`. + +## 1.0.6 + +### Patch Changes + +- [`ca2e1e96`](https://github.com/wagmi-dev/wagmi/commit/ca2e1e96149b87a7dc42c9db07e1f1ad2bb02c4a) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +- [#2401](https://github.com/wagmi-dev/wagmi/pull/2401) [`0f9dc875`](https://github.com/wagmi-dev/wagmi/commit/0f9dc875e90cfdd7a2028e04b7204caf9ea313b2) Thanks [@jxom](https://github.com/jxom)! - Exposed `account` on `readContract`/`useContractRead`. + +## 1.0.5 + +### Patch Changes + +- [`90e2b3b3`](https://github.com/wagmi-dev/wagmi/commit/90e2b3b39efe0585fe28645ac2264109be17362a) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +## 1.0.4 + +### Patch Changes + +- [#2344](https://github.com/wagmi-dev/wagmi/pull/2344) [`8a725458`](https://github.com/wagmi-dev/wagmi/commit/8a72545853ae1024acd9efd18c06142e8c6c5750) Thanks [@jxom](https://github.com/jxom)! - Added gas estimation back into `prepareSendTransaction`. + +## 1.0.3 + +### Patch Changes + +- [#2338](https://github.com/wagmi-dev/wagmi/pull/2338) [`92bfdc2c`](https://github.com/wagmi-dev/wagmi/commit/92bfdc2c744539558ba93c95f140b46ad331cee4) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where synchronous switch chain behavior (WalletConnect v2) would encounter chain id race conditions in `watchWalletClient`. + +## 1.0.2 + +### Patch Changes + +- [#2304](https://github.com/wevm/wagmi/pull/2304) [`09a4fd38`](https://github.com/wevm/wagmi/commit/09a4fd38f44eb176797925fd85314be17b610cd4) Thanks [@jxom](https://github.com/jxom)! - Removed assert chain workaround. + +## 1.0.1 + +### Patch Changes + +- [`ea651cd7`](https://github.com/wevm/wagmi/commit/ea651cd7fc75b7866272605467db11fd6e1d81af) Thanks [@jxom](https://github.com/jxom)! - Downgraded abitype. + +- Updated dependencies [[`ea651cd7`](https://github.com/wevm/wagmi/commit/ea651cd7fc75b7866272605467db11fd6e1d81af)]: + - @wagmi/connectors@1.0.1 + +## 1.0.0 + +### Major Changes + +- [#2235](https://github.com/wevm/wagmi/pull/2235) [`5be0655c`](https://github.com/wevm/wagmi/commit/5be0655c8e48b25d38009022461fbf611af54349) Thanks [@jxom](https://github.com/jxom)! - Released v1. Read [Migration Guide](https://next.wagmi.sh/react/migration-guide#1xx-breaking-changes). + +## 1.0.0-next.7 + +### Major Changes + +- [#2235](https://github.com/wevm/wagmi/pull/2235) [`708b2ce2`](https://github.com/wevm/wagmi/commit/708b2ce26efa8d3d910806a97cea5171dabc65de) Thanks [@jxom](https://github.com/jxom)! - Added `config.setPublicClient` & `config.setWebSocketPublicClient` + +- Updated references. + +### Patch Changes + +- Updated dependencies []: + - @wagmi/connectors@1.0.0-next.5 + +## 1.0.0-next.6 + +### Major Changes + +- [#2235](https://github.com/wevm/wagmi/pull/2235) [`708b2ce2`](https://github.com/wevm/wagmi/commit/708b2ce26efa8d3d910806a97cea5171dabc65de) Thanks [@jxom](https://github.com/jxom)! - Added `config.setPublicClient` & `config.setWebSocketPublicClient` + +- Added `config.setConnectors` + +### Patch Changes + +- Updated dependencies []: + - @wagmi/connectors@1.0.0-next.6 + +## 1.0.0-next.5 + +### Major Changes + +- [#2235](https://github.com/wevm/wagmi/pull/2235) [`708b2ce2`](https://github.com/wevm/wagmi/commit/708b2ce26efa8d3d910806a97cea5171dabc65de) Thanks [@jxom](https://github.com/jxom)! - Added `config.setPublicClient` & `config.setWebSocketPublicClient` + +## 1.0.0-next.4 + +### Major Changes + +- Updated viem. + Removed `goerli` export from main entrypoint. + +### Patch Changes + +- Updated dependencies []: + - @wagmi/connectors@1.0.0-next.5 + +## 1.0.0-next.3 + +### Major Changes + +- Updated references. + +### Patch Changes + +- Updated dependencies []: + - @wagmi/connectors@1.0.0-next.4 + +## 1.0.0-next.2 + +### Major Changes + +- **Breaking:** Renamed `createClient` to `createConfig` +- **Breaking:** Renamed `getClient` to `getConfig` +- **Breaking:** Removed `request` as an argument to `prepareSendTransaction` & `sendTransaction`. Arguments now belong on the root level of the Action. + +### Patch Changes + +- Updated dependencies []: + - @wagmi/chains@1.0.0-next.0 + - @wagmi/connectors@1.0.0-next.3 + +## 1.0.0-next.1 + +### Major Changes + +- updated viem + +### Patch Changes + +- Updated dependencies []: + - @wagmi/connectors@1.0.0-next.2 + +## 1.0.0-next.0 + +### Major Changes + +- [`a7dda00c`](https://github.com/wevm/wagmi/commit/a7dda00c5b546f8b2c42b527e4d9ac1b9e9ab1fb) Thanks [@jxom](https://github.com/jxom)! - Released v1. + +### Patch Changes + +- Updated dependencies [[`a7dda00c`](https://github.com/wevm/wagmi/commit/a7dda00c5b546f8b2c42b527e4d9ac1b9e9ab1fb)]: + - @wagmi/connectors@1.0.0-next.1 + +## 0.10.11 + +### Patch Changes + +- [#2270](https://github.com/wevm/wagmi/pull/2270) [`6d1fa9df`](https://github.com/wevm/wagmi/commit/6d1fa9df790287729c3b33d4f01fd23c2f8153f1) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +- Updated dependencies []: + - @wagmi/connectors@0.3.19 + +## 0.10.10 + +### Patch Changes + +- [#2208](https://github.com/wevm/wagmi/pull/2208) [`cfc696d8`](https://github.com/wevm/wagmi/commit/cfc696d83c6f768a2e1a29c5197efeed7f1d40a1) Thanks [@bangtoven](https://github.com/bangtoven)! - Bumped references to apply coinbase wallet sdk updates + +- Updated dependencies []: + - @wagmi/connectors@0.3.16 + +## 0.10.9 + +### Patch Changes + +- [#2143](https://github.com/wevm/wagmi/pull/2143) [`26dc5326`](https://github.com/wevm/wagmi/commit/26dc53260fde1d3278018c0b20a6d48a093d9427) Thanks [@tmm](https://github.com/tmm)! - Exported Sepolia Chain. + +- [#2146](https://github.com/wevm/wagmi/pull/2146) [`21b6842e`](https://github.com/wevm/wagmi/commit/21b6842e8c296a0bbe71ebe0780d898abc4cf4a8) Thanks [@tmm](https://github.com/tmm)! - Bumped references + +- Updated dependencies []: + - @wagmi/connectors@0.3.12 + +## 0.10.8 + +### Patch Changes + +- [#2099](https://github.com/wevm/wagmi/pull/2099) [`f1fee5b3`](https://github.com/wevm/wagmi/commit/f1fee5b30a1bd13b5e66118bf9cdc44b0dc003a1) Thanks [@jxom](https://github.com/jxom)! - Added chains: + + - `nexi` + - `polygonZkEvm` + - `xdc` + - `xdcTestnet` + +- [#2085](https://github.com/wevm/wagmi/pull/2085) [`7d64e3f5`](https://github.com/wevm/wagmi/commit/7d64e3f538a6149777bfa84ea9435769b2a7db58) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where multicall would not throw if the target chain was not configured on the wagmi client. + +- Updated dependencies []: + - @wagmi/connectors@0.3.10 + +## 0.10.7 + +### Patch Changes + +- [#2082](https://github.com/wevm/wagmi/pull/2082) [`2ccc8a25`](https://github.com/wevm/wagmi/commit/2ccc8a255e93f0a2bb7b22101656b3905ec59abd) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +- Updated dependencies []: + - @wagmi/connectors@0.3.10 + +## 0.10.6 + +### Patch Changes + +- [#2056](https://github.com/wevm/wagmi/pull/2056) [`944f6513`](https://github.com/wevm/wagmi/commit/944f6513adf09a6f0b3bd34f591d3bbd1f1ffd2e) Thanks [@tmm](https://github.com/tmm)! - Bumped references. + +- Updated dependencies []: + - @wagmi/connectors@0.3.8 + +## 0.10.5 + +### Patch Changes + +- [#2053](https://github.com/wevm/wagmi/pull/2053) [`665df1bf`](https://github.com/wevm/wagmi/commit/665df1bf2afccb533102069def395e19fb7194dd) Thanks [@tmm](https://github.com/tmm)! - Fixed issue where you add a new chain to MetaMask, but the switch after is rejected. + +- Updated dependencies []: + - @wagmi/connectors@0.3.7 + +## 0.10.4 + +### Patch Changes + +- [#2046](https://github.com/wevm/wagmi/pull/2046) [`90d8e9b8`](https://github.com/wevm/wagmi/commit/90d8e9b87962b72c54311649537e91a953660f9b) Thanks [@tmm](https://github.com/tmm)! - Exported internal type. + +- Updated dependencies []: + - @wagmi/connectors@0.3.6 + +## 0.10.3 + +### Patch Changes + +- [#2039](https://github.com/wevm/wagmi/pull/2039) [`bac893ab`](https://github.com/wevm/wagmi/commit/bac893ab26012d4d8741c4f80e8b8813aee26f0c) Thanks [@tmm](https://github.com/tmm)! - Updated references. + +- [#2043](https://github.com/wevm/wagmi/pull/2043) [`49a58320`](https://github.com/wevm/wagmi/commit/49a58320ab5f1f13bc4de25abcc028c8335e98f0) Thanks [@tmm](https://github.com/tmm)! - Removed `InjectedConnector` `shimChainChangedDisconnect` shim (no longer necessary). + +- Updated dependencies []: + - @wagmi/connectors@0.3.6 + +## 0.10.2 + +### Patch Changes + +- [#2016](https://github.com/wevm/wagmi/pull/2016) [`06bf61de`](https://github.com/wevm/wagmi/commit/06bf61dee6d2920777bd9392491e6b7aedebe7ab) Thanks [@jxom](https://github.com/jxom)! - Added chains: + + - `boba` + - `chronos` + - `crossbell` + - `dfk` + - `dogechain` + - `flare` + - `flareTestnet` + - `klaytn` + - `scrollTestnet` + - `shardeumSphinx` + - `skaleCalypso` + - `skaleCalypsoTestnet` + - `skaleChaosTestnet` + - `skaleCryptoBlades` + - `skaleCryptoColosseum` + - `skaleEuropa` + - `skaleEuropaTestnet` + - `skaleExorde` + - `skaleHumanProtocol` + - `skaleNebula` + - `skaleNebulaTestnet` + - `skaleRazor` + - `skaleTitan` + - `skaleTitanTestnet` + - `songbird` + - `songbirdTestnet` + - `titan` + - `titanTestnet` + - `wanchain` + - `wanchainTestnet` + +- [#2016](https://github.com/wevm/wagmi/pull/2016) [`06bf61de`](https://github.com/wevm/wagmi/commit/06bf61dee6d2920777bd9392491e6b7aedebe7ab) Thanks [@jxom](https://github.com/jxom)! - Updated references/ submodule. + +- Updated dependencies []: + - @wagmi/connectors@0.3.4 + +## 0.10.0 + +### Minor Changes + +- [#1902](https://github.com/wevm/wagmi/pull/1902) [`0994e896`](https://github.com/wevm/wagmi/commit/0994e8966349b8811db0a5886db3831dafc99245) Thanks [@jxom](https://github.com/jxom)! - **Breaking:** Removed the `version` config option for `WalletConnectConnector`. + + `WalletConnectConnector` now uses WalletConnect v2 by default. WalletConnect v1 is now `WalletConnectLegacyConnector`. + + ### WalletConnect v2 + + ```diff + import { WalletConnectConnector } from 'wagmi/connectors/walletConnect' + + const connector = new WalletConnectConnector({ + options: { + - version: '2', + projectId: 'abc', + }, + }) + ``` + + ### WalletConnect v1 + + ```diff + -import { WalletConnectConnector } from 'wagmi/connectors/walletConnect' + +import { WalletConnectConnector } from 'wagmi/connectors/walletConnectLegacy' + + -const connector = new WalletConnectConnector({ + +const connector = new WalletConnectLegacyConnector({ + options: { + qrcode: true, + }, + }) + ``` + +### Patch Changes + +- Updated dependencies []: + - @wagmi/connectors@0.3.2 + +## 0.9.7 + +### Patch Changes + +- [#1907](https://github.com/wevm/wagmi/pull/1907) [`cc4e74ee`](https://github.com/wevm/wagmi/commit/cc4e74ee19665eccb3767052dab6ab956ff4e676) Thanks [@jxom](https://github.com/jxom)! - Added the following chains to the `wagmi/chains` entrypoint: + + - `baseGoerli` + - `harmonyOne` + - `polygonZkEvmTestnet` + +- Updated dependencies []: + - @wagmi/connectors@0.2.7 + +## 0.9.6 + +### Patch Changes + +- [#1882](https://github.com/wevm/wagmi/pull/1882) [`282cc1b0`](https://github.com/wevm/wagmi/commit/282cc1b02003684d582cea411b11792a59c26fd0) Thanks [@tmm](https://github.com/tmm)! - Updated references. + +- Updated dependencies []: + - @wagmi/connectors@0.2.6 + +## 0.9.5 + +### Patch Changes + +- [#1812](https://github.com/wevm/wagmi/pull/1812) [`c7fd7fbd`](https://github.com/wevm/wagmi/commit/c7fd7fbde6f6c69a3a9a4f89d948c4dfb1d22679) Thanks [@jxom](https://github.com/jxom)! - Added the following chains to the `wagmi/chains` entrypoint: + + - `filecoinCalibration` + - `moonbaseAlpha` + - `moonbeam` + - `moonriver` + +- Updated dependencies []: + - @wagmi/connectors@0.2.5 + +## 0.9.4 + +### Patch Changes + +- [#1786](https://github.com/wevm/wagmi/pull/1786) [`b173a431`](https://github.com/wevm/wagmi/commit/b173a43165c7925a4e56ce1e0327a31917e7edc5) Thanks [@tmm](https://github.com/tmm)! - Locked ethers peer dependency version to >=5.5.1 <6 + +- [#1787](https://github.com/wevm/wagmi/pull/1787) [`f023fd8f`](https://github.com/wevm/wagmi/commit/f023fd8f66befb78b9a4df5ca971ceaa64e37ab4) Thanks [@tmm](https://github.com/tmm)! - Added `SafeConnector` + +- Updated dependencies []: + - @wagmi/connectors@0.2.4 + +## 0.9.3 + +### Patch Changes + +- [#1773](https://github.com/wevm/wagmi/pull/1773) [`9aaf1955`](https://github.com/wevm/wagmi/commit/9aaf195514d3b5f4d085c797fc5021d42a9efb6c) Thanks [@jxom](https://github.com/jxom)! - Updated `@walletconnect/universal-provider` on `WalletConnectConnector` v2. + Added more signable methods to `WalletConnectConnector` v2. + +- [#1773](https://github.com/wevm/wagmi/pull/1773) [`9aaf1955`](https://github.com/wevm/wagmi/commit/9aaf195514d3b5f4d085c797fc5021d42a9efb6c) Thanks [@jxom](https://github.com/jxom)! - Added Telos to the `wagmi/chains` entrypoint. Thanks @donnyquixotic! + +- Updated dependencies []: + - @wagmi/connectors@0.2.3 + +## 0.9.2 + +### Patch Changes + +- [#1756](https://github.com/wevm/wagmi/pull/1756) [`31d06b8c`](https://github.com/wevm/wagmi/commit/31d06b8ce1e7af5e9d1a7ba57f1743b2dff7a53d) Thanks [@jxom](https://github.com/jxom)! - Added OKC Chain. Thanks @clark-cui! + +- [#1756](https://github.com/wevm/wagmi/pull/1756) [`31d06b8c`](https://github.com/wevm/wagmi/commit/31d06b8ce1e7af5e9d1a7ba57f1743b2dff7a53d) Thanks [@jxom](https://github.com/jxom)! - Fixed race condition between `switchNetwork` and mutation Actions that use `chainId` (e.g. `sendTransaction`). Thanks @DanInTheD4rk! + +- Updated dependencies []: + - @wagmi/connectors@0.2.2 + +## 0.9.1 + +### Patch Changes + +- [#1752](https://github.com/wevm/wagmi/pull/1752) [`144a0e76`](https://github.com/wevm/wagmi/commit/144a0e76ef4bb9ba0650b5ffb9c63f95329819a4) Thanks [@jxom](https://github.com/jxom)! - Improved `WalletConnectConnector` (v2) initialization & updated dependencies. + +- [#1752](https://github.com/wevm/wagmi/pull/1752) [`144a0e76`](https://github.com/wevm/wagmi/commit/144a0e76ef4bb9ba0650b5ffb9c63f95329819a4) Thanks [@jxom](https://github.com/jxom)! - Added the following chains to the `wagmi/chains` entrypoint: + + - Aurora – thanks @salil-naik + - Bronos – thanks @chedetinaveen + - Canto – thanks @tster + - Celo – thanks @aaronmgdr + +- Updated dependencies []: + - @wagmi/connectors@0.2.1 + +## 0.9.0 + +### Minor Changes + +- [#1732](https://github.com/wevm/wagmi/pull/1732) [`01e21897`](https://github.com/wevm/wagmi/commit/01e2189747a5c22dc758c6d719b4145adc2a643c) Thanks [@tmm](https://github.com/tmm)! - Bumped minimum TypeScript version to typescript@>=4.9.4. TypeScript 5.0 is coming soon and has some great features we are excited to bring into wagmi. To prepare for this, update your TypeScript version to 4.9.4 or higher. There are likely no [breaking changes](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-9.html#correctness-fixes-and-breaking-changes) if you are coming from typescript@4.7.x || typescript@4.8.x. + +## 0.8.19 + +### Patch Changes + +- [#1718](https://github.com/wevm/wagmi/pull/1718) [`e62b5ef8`](https://github.com/wevm/wagmi/commit/e62b5ef8aaa8063abb5264790768899ea35bbd31) Thanks [@tmm](https://github.com/tmm)! - Updated references + +## 0.8.18 + +### Patch Changes + +- [#1708](https://github.com/wevm/wagmi/pull/1708) [`07fc3801`](https://github.com/wevm/wagmi/commit/07fc3801fa13c2cb5f7cf9b86ba8320b05a6a135) Thanks [@jxom](https://github.com/jxom)! - Updated `references/` submodule. + +## 0.8.17 + +### Patch Changes + +- [#1705](https://github.com/wevm/wagmi/pull/1705) [`9ff797dc`](https://github.com/wevm/wagmi/commit/9ff797dcb979dc86b798a432b74c98598165430d) Thanks [@jxom](https://github.com/jxom)! - Added the following chains to the `@wagmi/core/chains` entrypoint: + + - `crossbell` (thanks @Songkeys) + - `filecoin` & `filecoinHyperspace` (thanks @neil0x46dc) + - `gnosisChiado` (thanks @theNvN) + - `metis` & `metisGoerli` (thanks @CookedCookee) + +## 0.8.16 + +### Patch Changes + +- [#1699](https://github.com/wevm/wagmi/pull/1699) [`2f1e7950`](https://github.com/wevm/wagmi/commit/2f1e7950e55550d9b50ef5ccb97cb609f4af39b1) Thanks [@tmm](https://github.com/tmm)! - Added public RPC URL property to Chain + +## 0.8.15 + +### Patch Changes + +- [#1685](https://github.com/wevm/wagmi/pull/1685) [`917f5bc1`](https://github.com/wevm/wagmi/commit/917f5bc1fad578e35a8c6ee787e339bfdc156bab) Thanks [@jxom](https://github.com/jxom)! - Replaced qrcodemodal with web3modal for the WalletConnect v2 Connector. + +## 0.8.14 + +### Patch Changes + +- [#1646](https://github.com/wevm/wagmi/pull/1646) [`fcdbe353`](https://github.com/wevm/wagmi/commit/fcdbe3531e6d05cda4a4a511bae1ad4c9e426d88) Thanks [@jxom](https://github.com/jxom)! - Upgraded `zustand` to v4.3.1. + +## 0.8.13 + +### Patch Changes + +- [#1639](https://github.com/wevm/wagmi/pull/1639) [`c6869f06`](https://github.com/wevm/wagmi/commit/c6869f0604fffb197752a08256f31db77f52e746) Thanks [@jxom](https://github.com/jxom)! - Added `isRainbow` flag to `InjectedConnector`. + +## 0.8.12 + +### Patch Changes + +- [#1636](https://github.com/wevm/wagmi/pull/1636) [`025f6771`](https://github.com/wevm/wagmi/commit/025f6771b32ff7eed22f527be81c5141ddaf9c3d) Thanks [@DanielSinclair](https://github.com/DanielSinclair)! - Added `isRainbow` flag to injected `window.ethereum` types. + +## 0.8.11 + +### Patch Changes + +- [#1621](https://github.com/wevm/wagmi/pull/1621) [`5812b590`](https://github.com/wevm/wagmi/commit/5812b5909277bf2862cb57a31d52465b47291410) Thanks [@tmm](https://github.com/tmm)! - Bumped @wagmi/connectors + +## 0.8.10 + +### Patch Changes + +- [#1598](https://github.com/wevm/wagmi/pull/1598) [`fc10ebe6`](https://github.com/wevm/wagmi/commit/fc10ebe659dd5f3b7a8e00581f094652280a779b) Thanks [@jxom](https://github.com/jxom)! - Fixed CJS dependency version range + +## 0.8.9 + +### Patch Changes + +- [#1593](https://github.com/wevm/wagmi/pull/1593) [`216d555c`](https://github.com/wevm/wagmi/commit/216d555c62bd95c3c7c8f8e20f7269f6c8504610) Thanks [@jxom](https://github.com/jxom)! - Added CJS escape hatch bundle under the "cjs" tag. + +## 0.8.8 + +### Patch Changes + +- [#1573](https://github.com/wevm/wagmi/pull/1573) [`ef380d9c`](https://github.com/wevm/wagmi/commit/ef380d9c6d51ae0495b9c35925d2843c75d97fd4) Thanks [@tmm](https://github.com/tmm)! - Updated internal types. + +## 0.8.7 + +### Patch Changes + +- [#1570](https://github.com/wevm/wagmi/pull/1570) [`216f585b`](https://github.com/wevm/wagmi/commit/216f585be8a9e3a56e3243f49ccd54d655b5a6dd) Thanks [@wslyvh](https://github.com/wslyvh)! - Added `watchPendingTransactions` + +- [#1470](https://github.com/wevm/wagmi/pull/1470) [`3a1a6c9f`](https://github.com/wevm/wagmi/commit/3a1a6c9fe5db5c360adfd116f9a03a1238b5720c) Thanks [@jxom](https://github.com/jxom)! - The `WalletConnectConnector` now supports WalletConnect v2. + + It can be enabled by setting `version` to `'2'` and supplying a [WalletConnect Cloud `projectId`](https://cloud.walletconnect.com/sign-in). + +## 0.8.6 + +### Patch Changes + +- [#1539](https://github.com/wevm/wagmi/pull/1539) [`732da004`](https://github.com/wevm/wagmi/commit/732da0042c7e28091b2e36a484ea8239971306f5) Thanks [@0xFlicker](https://github.com/0xFlicker)! - All Providers (ie. Alchemy, Infura, Public) now use the ENS Registry address on the wagmi `Chain` object (`chain.contracts.ensRegistry`). + +- [#1574](https://github.com/wevm/wagmi/pull/1574) [`ecde3d10`](https://github.com/wevm/wagmi/commit/ecde3d1029ccdf90e2853ba0e9ae4f5f4ebb9c4c) Thanks [@jxom](https://github.com/jxom)! - Added the following chains: + + - `iotex` + - `iotexTestnet` + - `zkSync` + - `zkSyncTestnet` + +## 0.8.5 + +### Patch Changes + +- [#1542](https://github.com/wevm/wagmi/pull/1542) [`731b3b73`](https://github.com/wevm/wagmi/commit/731b3b733c6a093d1693d49de601705b7c730549) Thanks [@jxom](https://github.com/jxom)! - Added the following chains: + + - `evmos` + - `evmosTestnet` + - `gnosis` + +- [#1542](https://github.com/wevm/wagmi/pull/1542) [`731b3b73`](https://github.com/wevm/wagmi/commit/731b3b733c6a093d1693d49de601705b7c730549) Thanks [@jxom](https://github.com/jxom)! - Updated Goerli symbol to `"ETH"`. + +- [#1542](https://github.com/wevm/wagmi/pull/1542) [`731b3b73`](https://github.com/wevm/wagmi/commit/731b3b733c6a093d1693d49de601705b7c730549) Thanks [@jxom](https://github.com/jxom)! - Updated Arbitrum Goerli RPC and Block Explorer. + +- [#1542](https://github.com/wevm/wagmi/pull/1542) [`731b3b73`](https://github.com/wevm/wagmi/commit/731b3b733c6a093d1693d49de601705b7c730549) Thanks [@jxom](https://github.com/jxom)! - Fixed issue where connecting to MetaMask may return with a stale address. + +- [#1542](https://github.com/wevm/wagmi/pull/1542) [`731b3b73`](https://github.com/wevm/wagmi/commit/731b3b733c6a093d1693d49de601705b7c730549) Thanks [@jxom](https://github.com/jxom)! - Removed ENS registry for Sepolia. + +## 0.8.4 + +### Patch Changes + +- [#1508](https://github.com/wevm/wagmi/pull/1508) [`0b50b62f`](https://github.com/wevm/wagmi/commit/0b50b62f7389619e429509a3e337e451e823b059) Thanks [@jxom](https://github.com/jxom)! - Updated `@wagmi/chains` to `0.1.3`. + +- [#1504](https://github.com/wevm/wagmi/pull/1504) [`11b8b794`](https://github.com/wevm/wagmi/commit/11b8b794fbfd4a2b40f39962e2758e9fbf48cb54) Thanks [@tmm](https://github.com/tmm)! - Converted ethers custom "ACTION_REJECTED" error to standard RPC Error. + +## 0.8.3 + +### Patch Changes + +- [#1431](https://github.com/wevm/wagmi/pull/1431) [`af28f8f9`](https://github.com/wevm/wagmi/commit/af28f8f9cfc227e7c391927fdb934183edb5c2dc) Thanks [@jxom](https://github.com/jxom)! - Re-export connectors from `@wagmi/connectors` + +- [#1431](https://github.com/wevm/wagmi/pull/1431) [`af28f8f9`](https://github.com/wevm/wagmi/commit/af28f8f9cfc227e7c391927fdb934183edb5c2dc) Thanks [@jxom](https://github.com/jxom)! - Added `LedgerConnector` connector + +## 0.8.2 + +### Patch Changes + +- [#1442](https://github.com/wevm/wagmi/pull/1442) [`cde15289`](https://github.com/wevm/wagmi/commit/cde152899c758dea10787412b0aef669ed7202b2) Thanks [@0xproflupin](https://github.com/0xproflupin)! - Added Phantom wallet support to `InjectedConnector` + +- [#1448](https://github.com/wevm/wagmi/pull/1448) [`c6075f3a`](https://github.com/wevm/wagmi/commit/c6075f3a16885d850ad2656272351f9517c9f67b) Thanks [@tmm](https://github.com/tmm)! - Updated [ABIType](https://github.com/wevm/abitype) version. + +- [#1444](https://github.com/wevm/wagmi/pull/1444) [`310a8bc4`](https://github.com/wevm/wagmi/commit/310a8bc428ce4e7f68377f581b45dcdd64381cce) Thanks [@jxom](https://github.com/jxom)! - Assert that a `connector` exists before invoking the callback in `watchSigner`. + +- [#1434](https://github.com/wevm/wagmi/pull/1434) [`100e2a3b`](https://github.com/wevm/wagmi/commit/100e2a3b22f4602716554487b1d98738e053be76) Thanks [@tmm](https://github.com/tmm)! - Updated `MockConnector` `chainId` behavior to default to first chain from `chains` if not provided in `options`. + +## 0.8.1 + +### Patch Changes + +- [#1437](https://github.com/wevm/wagmi/pull/1437) [`c34a3dc6`](https://github.com/wevm/wagmi/commit/c34a3dc6396e6473d9f0505fad88ec910f8f5275) Thanks [@jxom](https://github.com/jxom)! - Omitted `"EIP712Domain"` type from `signTypedData` `types` arg since ethers throws an [internal error](https://github.com/ethers-io/ethers.js/blob/c80fcddf50a9023486e9f9acb1848aba4c19f7b6/packages/hash/src.ts/typed-data.ts#L466) if you include it. + +- [#1445](https://github.com/wevm/wagmi/pull/1445) [`51dd53cb`](https://github.com/wevm/wagmi/commit/51dd53cba3fe0f79fa1393270b738194577ddf54) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where the wagmi client wouldn't rehydrate the store in local storage when `autoConnect` is truthy. + +## 0.8.0 + +### Minor Changes + +- [#1344](https://github.com/wevm/wagmi/pull/1344) [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: the shape of the `Chain` type has been modified. + + #### RPC URLs + + The `rpcUrls` shape has changed to include an array of URLs, and also the transport method (`http` or `webSocket`): + + ```diff + type Chain = { + ... + rpcUrls: { + - [key: string]: string + + [key: string]: { + + http: string[] + + webSocket: string[] + + } + } + ... + } + ``` + + Note that you will also need to ensure that usage is migrated: + + ```diff + - const rpcUrl = mainnet.rpcUrls.alchemy + + const rpcUrl = mainnet.rpcUrls.alchemy.http[0] + ``` + + #### Contracts + + The `multicall` and `ens` attributes have been moved into the `contracts` object: + + ```diff + type Contract = { + address: Address + blockCreated?: number + } + + type Chain = { + ... + - multicall: Contract + - ens: Contract + + contracts: { + + multicall3: Contract + + ensRegistry: Contract + + } + ... + } + ``` + + Note that you will also need to ensure that usage is migrated: + + ```diff + - const multicallContract = mainnet.multicall + + const multicallContract = mainnet.contracts.multicall3 + ``` + +- [#1344](https://github.com/wevm/wagmi/pull/1344) [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: Upgraded `@coinbase/wallet-sdk` peer dependency to `3.6.0`. + + **Migration steps**: Update `@coinbase/wallet-sdk` to `^3.6.0`. + +- [#1344](https://github.com/wevm/wagmi/pull/1344) [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: Removed the `wait` argument on `waitForTransaction`. Use the transaction `hash` instead. + + ```diff + const data = await waitForTransaction({ + - wait: transaction.wait + + hash: transaction.hash + }) + ``` + +- [#1344](https://github.com/wevm/wagmi/pull/1344) [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: With the introduction of the [`@wagmi/core/chains` entrypoint](/core/chains), `@wagmi/core` no longer exports the following: + + - `chain` + - `allChains` + - `defaultChains` + - `defaultL2Chains` + - `chainId` + - `etherscanBlockExplorers` + - `alchemyRpcUrls`, `infuraRpcUrls`, `publicRpcUrls` + + Read below for migration steps. + + #### Removed `chain` + + The `chain` export has been removed. `@wagmi/core` now only exports the `mainnet` & `goerli` chains. If you need to use an alternative chain (`polygon`, `optimism`, etc), you will need to import it from the [`@wagmi/core/chains` entrypoint](/core/chains). + + ```diff + import { + - chain + configureChains + } from '@wagmi/core' + + import { mainnet, polygon, optimism } from '@wagmi/core/chains' + + const { ... } = configureChains( + - [chain.mainnet, chain.polygon, chain.optimism], + + [mainnet, polygon, optimism], + { + ... + } + ) + ``` + + #### Removed `allChains` + + The `allChains` export has been removed. If you need a list of all chains, you can utilize [`@wagmi/core/chains` entrypoint](/core/chains). + + ```diff + - import { allChains } from '@wagmi/core' + + import * as allChains from '@wagmi/core/chains' + + const { ... } = configureChains(allChains, ...) + ``` + + #### Removed `defaultChains` & `defaultL2Chains` + + The `defaultChains` & `defaultL2Chains` exports have been removed. If you still need the `defaultChains` or `defaultL2Chains` exports, you can build them yourself: + + ```diff + - import { defaultChains } from '@wagmi/core' + + import { mainnet, goerli } from '@wagmi/core/chains' + + + const defaultChains = [mainnet, goerli] + ``` + + > The `defaultChains` export was previously populated with `mainnet` & `goerli`. + + ```diff + - import { defaultL2Chains } from '@wagmi/core' + + import { + + arbitrum, + + arbitrumGoerli, + + polygon, + + polygonMumbai, + + optimism, + + optimismGoerli + + } from '@wagmi/core/chains' + + + const defaultL2Chains = [ + + arbitrum, + + arbitrumGoerli, + + polygon, + + polygonMumbai, + + optimism + + optimismGoerli + + ] + ``` + + > The `defaultL2Chains` export was previously populated with `arbitrum` & `optimism`. + + #### Removed `chainId` + + The `chainId` export has been removed. You can extract a chain ID from the chain itself. + + ```diff + - import { chainId } from '@wagmi/core' + + import { mainnet, polygon, optimism } from '@wagmi/core/chains' + + -const mainnetChainId = chainId.mainnet + -const polygonChainId = chainId.polygon + -const optimismChainId = chainId.optimism + +const mainnetChainId = mainnet.chainId + +const polygonChainId = polygon.chainId + +const optimismChainId = optimism.chainId + ``` + + #### Removed `etherscanBlockExplorers` + + The `etherscanBlockExplorers` export has been removed. You can extract a block explorer from the chain itself. + + ```diff + - import { etherscanBlockExplorers } from '@wagmi/core' + + import { mainnet, polygon, optimism } from '@wagmi/core/chains' + + -const mainnetEtherscanBlockExplorer = etherscanBlockExplorers.mainnet + -const polygonEtherscanBlockExplorer = etherscanBlockExplorers.polygon + -const optimismEtherscanBlockExplorer = etherscanBlockExplorers.optimism + +const mainnetEtherscanBlockExplorer = mainnet.blockExplorer + +const polygonEtherscanBlockExplorer = polygon.blockExplorer + +const optimismEtherscanBlockExplorer = optimism.blockExplorer + ``` + + #### Removed `alchemyRpcUrls`, `infuraRpcUrls` & `publicRpcUrls` + + The `alchemyRpcUrls`, `infuraRpcUrls` & `publicRpcUrls` exports have been removed. You can extract a RPC URL from the chain itself. + + ```diff + - import { alchemyRpcUrls, infuraRpcUrls, publicRpcUrls } from '@wagmi/core' + + import { mainnet } from '@wagmi/core/chains' + + -const mainnetAlchemyRpcUrl = alchemyRpcUrls.mainnet + -const mainnetInfuraRpcUrl = infuraRpcUrls.mainnet + -const mainnetOptimismRpcUrl = publicRpcUrls.mainnet + +const mainnetAlchemyRpcUrl = mainnet.rpcUrls.alchemy + +const mainnetInfuraRpcUrl = mainnet.rpcUrls.infura + +const mainnetOptimismRpcUrl = mainnet.rpcUrls.optimism + ``` + +- [#1344](https://github.com/wevm/wagmi/pull/1344) [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: Changed `waitForTransaction` behavior to throw an error if the transaction reverted. + +- [#1344](https://github.com/wevm/wagmi/pull/1344) [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652) Thanks [@jxom](https://github.com/jxom)! - Updated errors to use `cause` instead of `internal` + +### Patch Changes + +- [#1344](https://github.com/wevm/wagmi/pull/1344) [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652) Thanks [@jxom](https://github.com/jxom)! - `waitForTransaction` now respects repriced (sped up) transactions. + +- [#1344](https://github.com/wevm/wagmi/pull/1344) [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652) Thanks [@jxom](https://github.com/jxom)! - Export `getClient` + +- [#1344](https://github.com/wevm/wagmi/pull/1344) [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652) Thanks [@jxom](https://github.com/jxom)! - `waitForTransaction` now throws an error for cancelled or replaced transactions. + +## 0.7.9 + +### Patch Changes + +- [#1411](https://github.com/wevm/wagmi/pull/1411) [`659be184`](https://github.com/wevm/wagmi/commit/659be1840c613ce9f7aca9ac96694c4f60da4a66) Thanks [@tmm](https://github.com/tmm)! - Fixed issue where block invalidation was not properly disabled when setting `enabled: false`. + +## 0.7.8 + +### Patch Changes + +- [#1406](https://github.com/wevm/wagmi/pull/1406) [`4f18c450`](https://github.com/wevm/wagmi/commit/4f18c450a4d7952bfcfa6c533348ffbe55893d3c) Thanks [@tmm](https://github.com/tmm)! - Function for selecting the [EIP-1193](https://eips.ethereum.org/EIPS/eip-1193) Ethereum Provider to target. Defaults to `() => typeof window !== 'undefined' ? window.ethereum : undefined`. + + ```ts + import { InjectedConnector } from "@wagmi/core/connectors/injected"; + + const connector = new InjectedConnector({ + options: { + name: "My Injected Wallet", + getProvider: () => + typeof window !== "undefined" ? window.myInjectedWallet : undefined, + }, + }); + ``` + +## 0.7.7 + +### Patch Changes + +- [#1386](https://github.com/wevm/wagmi/pull/1386) [`206a2adb`](https://github.com/wevm/wagmi/commit/206a2adbb4ee5149a364543b34612050ccf78c21) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where `persister` would still use `window.localStorage` instead of the wagmi `storage`. + +- [#1376](https://github.com/wevm/wagmi/pull/1376) [`a70a9528`](https://github.com/wevm/wagmi/commit/a70a9528f93f4d7fea28b7652751dfef2dcacf9b) Thanks [@jxom](https://github.com/jxom)! - Fixed issue where `switchChain` on `WalletConnectConnector` would not resolve. + +- [#1386](https://github.com/wevm/wagmi/pull/1386) [`206a2adb`](https://github.com/wevm/wagmi/commit/206a2adbb4ee5149a364543b34612050ccf78c21) Thanks [@jxom](https://github.com/jxom)! - Added `serialize`/`deserialize` as config options to `createStorage`. + +- [#1392](https://github.com/wevm/wagmi/pull/1392) [`88afc849`](https://github.com/wevm/wagmi/commit/88afc84978afe9689ab7364633e4422ecd7699ea) Thanks [@tmm](https://github.com/tmm)! - Added check for active connector when connecting + +## 0.7.6 + +### Patch Changes + +- [#1384](https://github.com/wevm/wagmi/pull/1384) [`027e88d6`](https://github.com/wevm/wagmi/commit/027e88d6e5f8d028d46ee78aec8500701e0173d9) Thanks [@tmm](https://github.com/tmm)! - Fixed issue reconnecting after disconnect with `MetaMaskConnector` in MetaMask mobile browser. + +## 0.7.5 + +### Patch Changes + +- [`1169914a`](https://github.com/wevm/wagmi/commit/1169914a0f0ad2810ca1c536b1f1bc6c20f2c1be) Thanks [@jxom](https://github.com/jxom)! - Use `get_accounts` for `getSigner` in InjectedConnector + +## 0.7.4 + +### Patch Changes + +- [#1309](https://github.com/wevm/wagmi/pull/1309) [`1f4a4261`](https://github.com/wevm/wagmi/commit/1f4a4261247b1d3a90e3123157bc851a35d49b9c) Thanks [@tmm](https://github.com/tmm)! - Fixed internal type + +## 0.7.3 + +### Patch Changes + +- [#1294](https://github.com/wevm/wagmi/pull/1294) [`b2f88949`](https://github.com/wevm/wagmi/commit/b2f88949f32aabaf13f318472648cd51a8b7f2e7) Thanks [@tmm](https://github.com/tmm)! - Set `abi` return type value for `prepareContractWrite` as more permissive when not inferrable as `Abi`. + +## 0.7.2 + +### Patch Changes + +- [`e9f806b6`](https://github.com/wevm/wagmi/commit/e9f806b652ba62effb3ddac464815e447fc287f6) Thanks [@tmm](https://github.com/tmm)! - Bumped abitype and zustand versions. + +## 0.7.1 + +### Patch Changes + +- [#1272](https://github.com/wevm/wagmi/pull/1272) [`1f7fc41`](https://github.com/wevm/wagmi/commit/1f7fc419f7960bbdc51dfa85c2f33b89f1ecc1bf) Thanks [@tmm](https://github.com/tmm)! - Fixed ethers import path + +## 0.7.0 + +### Minor Changes + +- [#1202](https://github.com/wevm/wagmi/pull/1202) [`9bf56af`](https://github.com/wevm/wagmi/commit/9bf56af3c30bdb80abb1e785c002e00986fadfb2) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: Removed the following deprecated chains: + + - `ropsten` + - `rinkeby` + - `kovan` + - `optimismKovan` + - `arbitrumRinkeby` + + If you feel you still need to include one of these testnets in your application, you will have to define it manually: + + ```diff + -import { rinkeby } from 'wagmi' + +import { Chain } from 'wagmi' + + +export const rinkeby: Chain = { + + id: 4, + + name: 'Rinkeby', + + network: 'rinkeby', + + nativeCurrency: { name: 'Rinkeby Ether', symbol: 'ETH', decimals: 18 }, + + rpcUrls: { + + alchemy: 'https://eth-rinkeby.alchemyapi.io/v2', + + default: 'https://rpc.ankr.com/eth_rinkeby', + + infura: 'https://rinkeby.infura.io/v3', + + public: 'https://rpc.ankr.com/eth_rinkeby', + + }, + + blockExplorers: { + + etherscan: 'https://rinkeby.etherscan.io', + + default: 'https://rinkeby.etherscan.io', + + }, + + ens: { + + address: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e', + + }, + + multicall: { + + address: '0xca11bde05977b3631167028862be2a173976ca11', + + blockCreated: 10299530, + + }, + + testnet: true, + } + ``` + + You can reference these removed chains [here](https://github.com/wevm/wagmi/blob/389765f7d9af063ab0df07389a2bbfbc10a41060/packages/core/src/constants/chains.ts). + +- [#1202](https://github.com/wevm/wagmi/pull/1202) [`9bf56af`](https://github.com/wevm/wagmi/commit/9bf56af3c30bdb80abb1e785c002e00986fadfb2) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: `addressOrName` renamed to `address` for `fetchBalance` and `fetchEnsAvatar`. + + ```diff + const result = await fetchBalance({ + - addressOrName: '0x…', + + address: '0x…', + }) + ``` + + If you were using an ENS name instead of an address, you can resolve the name to an address before passing it to the action. + + ```diff + + const { data: address } = await fetchEnsAddress({ name: 'example.eth' }) + const result = await fetchBalance({ + - addressOrName: 'example.eth', + + address, + }) + ``` + +- [#1202](https://github.com/wevm/wagmi/pull/1202) [`9bf56af`](https://github.com/wevm/wagmi/commit/9bf56af3c30bdb80abb1e785c002e00986fadfb2) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: Made `apiKey` required on `infuraProvider` and `alchemyProvider`. + + ```diff + import { configureChains } from 'wagmi' + + const config = configureChains(defaultChains, [ + - alchemyProvider(), + + alchemyProvider({ apiKey: process.env.ALCHEMY_API_KEY }) + ]) + ``` + + You can find your Alchemy API key from the [Alchemy Dashboard](https://dashboard.alchemyapi.io/), or your Infura API key from the [Infura Dashboard](https://infura.io/login). + +- [#1202](https://github.com/wevm/wagmi/pull/1202) [`9bf56af`](https://github.com/wevm/wagmi/commit/9bf56af3c30bdb80abb1e785c002e00986fadfb2) Thanks [@tmm](https://github.com/tmm)! - Removed CommonJS support + +## 0.6.12 + +### Patch Changes + +- [#1250](https://github.com/wevm/wagmi/pull/1250) [`ce2e0f4`](https://github.com/wevm/wagmi/commit/ce2e0f4a46b8fd1c509ead552012ef4c072a525b) Thanks [@tmm](https://github.com/tmm)! - Added support for Trust Wallet browser extension. + +## 0.6.11 + +### Patch Changes + +- [#1234](https://github.com/wevm/wagmi/pull/1234) [`3ff9303`](https://github.com/wevm/wagmi/commit/3ff930349250f62137cca4ca3b382522882abf8a) Thanks [@tmm](https://github.com/tmm)! - Fixed issue with adding chain to wallet without block explorer URL. + +## 0.6.10 + +### Patch Changes + +- [#1232](https://github.com/wevm/wagmi/pull/1232) [`c0ca509`](https://github.com/wevm/wagmi/commit/c0ca509506dcf6d98b058df549dc761c9a5f3d1c) Thanks [@tmm](https://github.com/tmm)! - Added validation to check that chain is configured for connector when accessing `Signer`. + +## 0.6.9 + +### Patch Changes + +- [#1207](https://github.com/wevm/wagmi/pull/1207) [`c73d463`](https://github.com/wevm/wagmi/commit/c73d463d65c9dbfcfe709187e47323a769589741) Thanks [@lvshaoping007](https://github.com/lvshaoping007)! - Added Kucoin wallet support to `InjectedConnector` + +## 0.6.8 + +### Patch Changes + +- [#1132](https://github.com/wevm/wagmi/pull/1132) [`d41c0d6`](https://github.com/wevm/wagmi/commit/d41c0d650f8c0e54145758685b7604b8909d7ae0) Thanks [@toniocodo](https://github.com/toniocodo)! - Added ERC-4626 ABI + +- [#1201](https://github.com/wevm/wagmi/pull/1201) [`9a07efa`](https://github.com/wevm/wagmi/commit/9a07efaa397d3ba03f2edbe527c359f21e22139a) Thanks [@jxom](https://github.com/jxom)! - Fixed issue where non-checksum addresses did not resolve with an ENS name + +## 0.6.7 + +### Patch Changes + +- [#1174](https://github.com/wevm/wagmi/pull/1174) [`196a458`](https://github.com/wevm/wagmi/commit/196a458f64141e8a9f39c1b1e1af5937f692cb39) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where `client.chains` (active connector chains) would be populated when there is no active connector (disconnected user). + +- [#1176](https://github.com/wevm/wagmi/pull/1176) [`389765f`](https://github.com/wevm/wagmi/commit/389765f7d9af063ab0df07389a2bbfbc10a41060) Thanks [@jxom](https://github.com/jxom)! - Migrate away from Alchemy RPC URLs in the public RPC URL list + +## 0.6.6 + +### Patch Changes + +- [`81ce9e6`](https://github.com/wevm/wagmi/commit/81ce9e64d85f7d01370324c1a529988a0919894f) Thanks [@jxom](https://github.com/jxom)! - Add `isPortal` to injected MetaMask flags. + +- [`c2c0109`](https://github.com/wevm/wagmi/commit/c2c01096ef4cd0ffadbb49062969c208604c6194) Thanks [@jxom](https://github.com/jxom)! - Add etherscan block explorer to Optimism Goerli + +## 0.6.5 + +### Patch Changes + +- [#1162](https://github.com/wevm/wagmi/pull/1162) [`30335b3`](https://github.com/wevm/wagmi/commit/30335b3199fb425e398e9c492b50c68d5e2ade7e) Thanks [@tmm](https://github.com/tmm)! - Fixed issue where non-indexed event parameter types were set to `null`. + +- [#1162](https://github.com/wevm/wagmi/pull/1162) [`30335b3`](https://github.com/wevm/wagmi/commit/30335b3199fb425e398e9c492b50c68d5e2ade7e) Thanks [@tmm](https://github.com/tmm)! - Fixed issue where `useContractReads` and `useContractInfiniteReads` types were slowing down TypeScript compiler. + +## 0.6.4 + +### Patch Changes + +- [#1103](https://github.com/wevm/wagmi/pull/1103) [`651eda0`](https://github.com/wevm/wagmi/commit/651eda06384bd0955268427f898e9337b2dc5a31) Thanks [@tmm](https://github.com/tmm)! - Bumped `abitype` dependency. + +## 0.6.3 + +### Patch Changes + +- [#1086](https://github.com/wevm/wagmi/pull/1086) [`4e28d2a`](https://github.com/wevm/wagmi/commit/4e28d2ad4c2e6b3479b728563040b9529463cbcf) Thanks [@tmm](https://github.com/tmm)! - Exposed module types. + +## 0.6.2 + +### Patch Changes + +- [#1080](https://github.com/wevm/wagmi/pull/1080) [`3be5e8b`](https://github.com/wevm/wagmi/commit/3be5e8b01e58ed40cc9dab7ef9533c0197cb74d0) Thanks [@tmm](https://github.com/tmm)! - Added `abitype` to `dependencies` so types ship correctly. + +## 0.6.1 + +### Patch Changes + +- [#1074](https://github.com/wevm/wagmi/pull/1074) [`8db807f`](https://github.com/wevm/wagmi/commit/8db807f16149aa278c2a7db9ee5245431db12173) Thanks [@IljaDaderko](https://github.com/IljaDaderko)! - Exported `EventListener` type + +## 0.6.0 + +### Minor Changes + +- [#940](https://github.com/wevm/wagmi/pull/940) [`b6cb8f4`](https://github.com/wevm/wagmi/commit/b6cb8f4cd15eb13073bc7e9ecb4bfa2c261c0663) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: `watchSigner` now requires an arguments object (that accepts an optional `chainId`) as it's first parameter. + + ```diff + import { watchSigner } from `@wagmi/core` + + -watchSigner(signer => { + +watchSigner({}, signer => { + console.log('new signer!', signer) + }) + ``` + +- [#940](https://github.com/wevm/wagmi/pull/940) [`b6cb8f4`](https://github.com/wevm/wagmi/commit/b6cb8f4cd15eb13073bc7e9ecb4bfa2c261c0663) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: `prepareSendTransaction` now throws when a `chainId` is specified and the end-user is on a different chain id (the wrong network). + +- [#941](https://github.com/wevm/wagmi/pull/941) [`0c96009`](https://github.com/wevm/wagmi/commit/0c96009398647a515a57f72ef25c32724f7c978c) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: `addressOrName` and `contractInterface` renamed to `address` and `abi` respectively for contract actions: `getContract`, `multicall`, `prepareWriteContract`, `readContract`, `readContracts`, `watchContractEvent`, `watchMulticall`, `watchReadContract`, `watchReadContracts`, `writeContract`. + + ```diff + import { readContract } from '@wagmi/core' + + const result = await readContract({ + - addressOrName: '0x…', + + address: '0x…', + - contractInterface: […] as const, + + abi: […] as const, + functionName: 'balanceOf', + args: ['0x…'], + }) + ``` + + If you were using an ENS name instead of an address, you can resolve the name to an address before passing it to the action. + + ```diff + - import { readContract } from '@wagmi/core' + + import { fetchEnsAddress, readContract } from '@wagmi/core' + + + const address = await fetchEnsAddress('example.eth') + const result = await readContract({ + - addressOrName: 'example.eth', + + address, + abi: […] as const, + functionName: 'balanceOf', + args: ['0x…'], + }) + ``` + +- [#940](https://github.com/wevm/wagmi/pull/940) [`b6cb8f4`](https://github.com/wevm/wagmi/commit/b6cb8f4cd15eb13073bc7e9ecb4bfa2c261c0663) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: `prepareWriteContract` now throws when a `chainId` is specified and the end-user is on a different chain id (the wrong network). + +- [#940](https://github.com/wevm/wagmi/pull/940) [`b6cb8f4`](https://github.com/wevm/wagmi/commit/b6cb8f4cd15eb13073bc7e9ecb4bfa2c261c0663) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: `prepareSendTransaction` now only accepts a `signer` instead of `signerOrProvider`. + + This is to reach parity with `prepareWriteContract`. + + If no `signer` is provided, wagmi will use the signer that is currently connected. If no user is connected, then `prepareWriteContract` will throw an error. + +- [#941](https://github.com/wevm/wagmi/pull/941) [`0c96009`](https://github.com/wevm/wagmi/commit/0c96009398647a515a57f72ef25c32724f7c978c) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: `args` config option must now be an array for the following actions: `readContract`, `writeContract`, `prepareWriteContract`, `multicall`, `readContracts`, `watchMulticall`, and `watchReadContracts`. + + ```diff + import { readContract } from '@wagmi/core' + + const result = await readContract({ + address: '0x…', + abi: […], + functionName: 'balanceOf', + - args: '0x…', + + args: ['0x…'], + }) + ``` + +- [#941](https://github.com/wevm/wagmi/pull/941) [`0c96009`](https://github.com/wevm/wagmi/commit/0c96009398647a515a57f72ef25c32724f7c978c) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: `watchContractEvent` now accepts a configuration object and callback instead of positional arguments. + + ```diff + import { watchContractEvent } from '@wagmi/core' + + - const unsubscribe = watchContractEvent( + - { + - address: '0x…', + - abi: […], + - }, + - 'Transfer', + - (from, to, tokenId) => { + - // ... + - }, + - { once: true }, + - ) + + const unsubscribe = watchContractEvent( + + { + + address: '0x…', + + abi: […], + + eventName: 'Transfer', + + once: true, + + }, + + (from, to, tokenId) => { + + // ... + + }, + + ) + ``` + +- [#941](https://github.com/wevm/wagmi/pull/941) [`0c96009`](https://github.com/wevm/wagmi/commit/0c96009398647a515a57f72ef25c32724f7c978c) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: Updated TypeScript version to `typescript@>=4.7.4`. + + `@wagmi/core` can now infer types based on [ABI](https://docs.soliditylang.org/en/v0.8.15/abi-spec.html#json) and [EIP-712](https://eips.ethereum.org/EIPS/eip-712) Typed Data definitions, giving you full end-to-end type-safety from your contracts to your frontend and incredible developer experience (e.g. autocomplete contract function names and catch misspellings, type contract function arguments, etc.). + + For this to work, you must upgrade to `typescript@>=4.7.4`. Why is TypeScript v4.7.4 or greater necessary? TypeScript 4.7.4 introduced the ability to [extend constraints on inferred type variables](https://devblogs.microsoft.com/typescript/announcing-typescript-4-7/#extends-constraints-on-infer-type-variables), which is used extensively to help narrow types for ABIs. Good news! When upgrading TypeScript from 4.6 to 4.7 there are likely no [breaking changes](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-7.html#breaking-changes) for your set up. + +- [#941](https://github.com/wevm/wagmi/pull/941) [`0c96009`](https://github.com/wevm/wagmi/commit/0c96009398647a515a57f72ef25c32724f7c978c) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: Updated TypeScript generics for contract interaction and typed data actions. + + Adding a [const assertion](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions) to `abi` allows TypeScript to infer `functionName`, `args`, `overrides`, and return types for functions, and `eventName` and `listener` types for events. + + ```diff + import { readContract } from '@wagmi/core' + + const result = await readContract({ + address: '0x…', + - abi: […], + + abi: […] as const, + functionName: 'balanceOf', // will autocomplete and catch typos + args: ['0x…'], // inferred based on `functionName` + }) + result // inferred based on `functionName` + ``` + + This works for the following actions: `readContract`, `writeContract`, `prepareWriteContract`, `multicall`, `readContracts`, `watchMulticall`, `watchReadContracts`, and `watchContractEvent`. + + Adding a [const assertion](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions) to `signTypedData`'s config option, `types`, allows TypeScript to infer `value`. + + ```diff + import { signTypedData } from '@wagmi/core' + + const result = await signTypedData({ + domain: { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', + }, + types: { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + - }, + + } as const, + value: { // `value` is inferred based on `types` + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + }) + ``` + +### Patch Changes + +- [#1061](https://github.com/wevm/wagmi/pull/1061) [`a4ffe8b`](https://github.com/wevm/wagmi/commit/a4ffe8b25516d5504685ae94579da4cd8c409329) Thanks [@alecananian](https://github.com/alecananian)! - Added Arbitrum Goerli Arbiscan block explorer + +- [#940](https://github.com/wevm/wagmi/pull/940) [`b6cb8f4`](https://github.com/wevm/wagmi/commit/b6cb8f4cd15eb13073bc7e9ecb4bfa2c261c0663) Thanks [@jxom](https://github.com/jxom)! - The `fetchSigner` action now accepts an optional `chainId` to use for signer initialization as an argument. + + ```tsx + import { fetchSigner } from "@wagmi/core"; + import { optimism } from "@wagmi/core/chains"; + + // ... + + fetchSigner({ chainId: optimism.id }); + ``` + +- [#1048](https://github.com/wevm/wagmi/pull/1048) [`ed13074`](https://github.com/wevm/wagmi/commit/ed130747c0f28c1d9980a1328883e4000a60455e) Thanks [@Max-3-7](https://github.com/Max-3-7)! - Added support for Avalanche core wallet + +- [#1046](https://github.com/wevm/wagmi/pull/1046) [`ab9ecaa`](https://github.com/wevm/wagmi/commit/ab9ecaa74dfa4324279e167dd7e348319ef7d35d) Thanks [@jxom](https://github.com/jxom)! - make ethers block format validator compatible with Celo + +- [#1050](https://github.com/wevm/wagmi/pull/1050) [`73d4d47`](https://github.com/wevm/wagmi/commit/73d4d47bc679f4f9a1cf46010fe2bf858c9d0b5c) Thanks [@jxom](https://github.com/jxom)! - update dependencies + + - `zustand@4.1.1` + +## 0.5.8 + +### Patch Changes + +- [`8cb07462`](https://github.com/wevm/wagmi/commit/8cb07462acc3c5637398d11d2451f8b8e330d553) Thanks [@jxom](https://github.com/jxom)! - Added `chainId` as an argument to `watchBlockNumber`. + +* [`53c1a474`](https://github.com/wevm/wagmi/commit/53c1a4747d03b685e8cfbf55361fc2a56777fb06) Thanks [@tmm](https://github.com/tmm)! - Added missing `decimals` option to `Connector` `watchAsset` + +- [`4d74dd4f`](https://github.com/wevm/wagmi/commit/4d74dd4ff827ba5c43c3546a218f38cee45ea76a) Thanks [@jxom](https://github.com/jxom)! - Support ERC20 contracts that represent strings as bytes32 + +## 0.5.7 + +### Patch Changes + +- [`aa51bc4d`](https://github.com/wevm/wagmi/commit/aa51bc4dc5683bf0178597d2fdb8f2e9d82e7970) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue in `CoinbaseWalletConnector` where the browser extension would unintendedly reset the network when the browser is refreshed. + +* [#955](https://github.com/wevm/wagmi/pull/955) [`e326cd80`](https://github.com/wevm/wagmi/commit/e326cd80fe65267db623eb6c80ccdd75572914cf) Thanks [@0xFlicker](https://github.com/0xFlicker)! - Added Infura RPC URL for Sepolia + +- [`cec14089`](https://github.com/wevm/wagmi/commit/cec14089500c86687226ab272b4c3fcb85ae3d69) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where `useProvider` & `getProvider` were not returning referentially equal providers. + +* [`cec14089`](https://github.com/wevm/wagmi/commit/cec14089500c86687226ab272b4c3fcb85ae3d69) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where the `watch` option was not respecting the neighboring `chainId` option in `useBlockNumber`. + +- [`cec14089`](https://github.com/wevm/wagmi/commit/cec14089500c86687226ab272b4c3fcb85ae3d69) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where block listeners (via `watch`) were firing excessively on L2 chains. + +## 0.5.6 + +### Patch Changes + +- [#936](https://github.com/wevm/wagmi/pull/936) [`3329d1f`](https://github.com/wevm/wagmi/commit/3329d1f5880431566e14ac1640f48d0975aec4c2) Thanks [@jxom](https://github.com/jxom)! - Added the ability to provide a custom logger to override how logs are broadcasted to the consumer in wagmi. + + A custom logger can be provided to the wagmi client via `logger`. + + ### API + + ```tsx + logger?: { + warn: typeof console.warn | null + } + ``` + + ### Examples + + **Passing in a custom logger** + + You can pass in a function to define your own custom logger. + + ```diff + + import { logWarn } from './logger'; + + const client = createClient({ + ... + + logger: { + + warn: message => logWarn(message) + + } + ... + }) + ``` + + **Disabling a logger** + + You can disable a logger by passing `null` as the value. + + ```diff + const client = createClient({ + ... + + logger: { + + warn: null + + } + ... + }) + ``` + +* [#889](https://github.com/wevm/wagmi/pull/889) [`27788ed`](https://github.com/wevm/wagmi/commit/27788ed989b5dc26849c7945fb91a92e56766018) Thanks [@jxom](https://github.com/jxom)! - Make multicall & readContracts more error robust + +## 0.5.5 + +### Patch Changes + +- [#912](https://github.com/wevm/wagmi/pull/912) [`e529e12`](https://github.com/wevm/wagmi/commit/e529e125c713ed3ef24a59c6bf226fe4deee7ac9) Thanks [@zouhangwithsweet](https://github.com/zouhangwithsweet)! - Added BitKeep to injected flags + +- [#912](https://github.com/wevm/wagmi/pull/910) Thanks [@mytangying](https://github.com/zouhangwithsweet)! - Added MathWallet to injected flags + +- [#904](https://github.com/wevm/wagmi/pull/904) [`c231058`](https://github.com/wevm/wagmi/commit/c23105850f335f8798031e14c7098b7dee8c2975) Thanks [@jxom](https://github.com/jxom)! - Minimized contract interface returned from `prepareWriteContract`. + +## 0.5.4 + +### Patch Changes + +- [#852](https://github.com/wevm/wagmi/pull/852) [`c3192d0`](https://github.com/wevm/wagmi/commit/c3192d0663aa332ae9edfd9dd49b333454013ab7) Thanks [@skeithc](https://github.com/skeithc)! - Added support for the Sepolia testnet + +## 0.5.3 + +### Patch Changes + +- [#835](https://github.com/wevm/wagmi/pull/835) [`1b85e54`](https://github.com/wevm/wagmi/commit/1b85e54ae654e2564cf5bc2dae6411fe0a25875c) Thanks [@jxom](https://github.com/jxom)! - Update `@coinbase/wallet-sdk` to `3.4.1` + +* [#834](https://github.com/wevm/wagmi/pull/834) [`9655879`](https://github.com/wevm/wagmi/commit/96558793b0319df47aefafa6b7b9c959068d491b) Thanks [@jxom](https://github.com/jxom)! - Update zustand to `4.0.0` + +## 0.5.2 + +### Patch Changes + +- [#823](https://github.com/wevm/wagmi/pull/823) [`10b8b78`](https://github.com/wevm/wagmi/commit/10b8b78605b7246b2c55b8d69f96663906e5cd20) Thanks [@tmm](https://github.com/tmm)! - Add Optimism Goerli to `chain` lookup. + +## 0.5.1 + +### Patch Changes + +- [#767](https://github.com/wevm/wagmi/pull/767) [`e9392f3`](https://github.com/wevm/wagmi/commit/e9392f396e48e928bd9d2522e3ad671c589f08cb) Thanks [@klyap](https://github.com/klyap)! - Add Optimism Goerli chain ahead of [Kovan deprecation](https://dev.optimism.io/kovan-to-goerli). + +* [#817](https://github.com/wevm/wagmi/pull/817) [`7e5cac7`](https://github.com/wevm/wagmi/commit/7e5cac75815dcd8aa563462342a4853fc5207735) Thanks [@alecananian](https://github.com/alecananian)! - Added custom name mapping for 1inch Wallet injected provider + +- [#806](https://github.com/wevm/wagmi/pull/806) [`0b34e56`](https://github.com/wevm/wagmi/commit/0b34e56db97e6dcdb71088e0149b2d55ebc604a5) Thanks [@vmichalik](https://github.com/vmichalik)! - Fix canonical testnet native asset symbols by changing them to ETH + +* [#778](https://github.com/wevm/wagmi/pull/778) [`0892908`](https://github.com/wevm/wagmi/commit/08929084eeeba1a3a55aa098fa9d92a243685ad5) Thanks [@0xcadams](https://github.com/0xcadams)! - Add Arbitrum Goerli chain. + +## 0.5.0 + +### Minor Changes + +- [#658](https://github.com/wevm/wagmi/pull/658) [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The configuration passed to the `sendTransaction` action now needs to be: + + - prepared with the `prepareSendTransaction` action **(new functionality)**, or + - recklessly unprepared **(previous functionality)** + + > Why? [Read here](https://wagmi.sh/docs/prepare-hooks) + + ### Prepared usage + + ```diff + import { prepareSendTransaction, sendTransaction } from '@wagmi/core' + + +const config = await prepareSendTransaction({ + + request: { + + to: 'moxey.eth', + + value: parseEther('1'), + + } + +}) + + const result = await sendTransaction({ + - request: { + - to: 'moxey.eth', + - value: parseEther('1') + - } + + ...config + }) + ``` + + ### Recklessly unprepared usage + + It is possible to use `sendTransaction` without preparing the configuration first by passing `mode: 'recklesslyUnprepared'`. + + ```diff + import { sendTransaction } from '@wagmi/core' + + const result = await sendTransaction({ + + mode: 'recklesslyUnprepared', + request: { + to: 'moxey.eth', + value: parseEther('1'), + } + }) + ``` + +* [#760](https://github.com/wevm/wagmi/pull/760) [`d8af6bf`](https://github.com/wevm/wagmi/commit/d8af6bf50885aec110ae4d64716642453aa27896) Thanks [@tmm](https://github.com/tmm)! - **Breaking:** `alchemyProvider` and `infuraProvider` now use a generic `apiKey` configuration option instead of `alchemyId` and `infuraId`. + + ```diff + import { alchemyProvider } from '@wagmi/core/providers/alchemy' + import { infuraProvider } from '@wagmi/core/providers/infura' + + alchemyProvider({ + - alchemyId: 'yourAlchemyApiKey', + + apiKey: 'yourAlchemyApiKey', + }) + + infuraProvider({ + - infuraId: 'yourInfuraApiKey', + + apiKey: 'yourInfuraApiKey', + }) + ``` + +- [#727](https://github.com/wevm/wagmi/pull/727) [`ac3b9b8`](https://github.com/wevm/wagmi/commit/ac3b9b87f80cb45b65d003f09d916d7d1427a62e) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: Moved the `pollingInterval` config option from the chain provider config to `configureChains` config. + + ```diff + const { chains, provider } = configureChains( + [chain.mainnet, chain.polygon], + [ + - alchemyProvider({ apiKey, pollingInterval: 5000 }), + - publicProvider({ pollingInterval: 5000 }) + + alchemyProvider({ apiKey }), + + publicProvider() + ], + + { pollingInterval: 5000 } + ) + ``` + +* [#658](https://github.com/wevm/wagmi/pull/658) [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432) Thanks [@jxom](https://github.com/jxom)! - **Breaking:** The `sendTransaction` action now returns an object only consisting of `hash` & `wait`, and not the full [`TransactionResponse`](https://docs.ethers.io/v5/api/providers/types/#providers-TransactionResponse). + + If you require the full `TransactionResponse`, you can use `fetchTransaction`: + + ```diff + import { sendTransaction, fetchTransaction } from '@wagmi/core' + + const { + hash, + wait, + - ...transaction + } = sendTransaction(...) + + +const transaction = fetchTransaction({ hash }) + ``` + + > Why? The old implementation of `sendTransaction` created a long-running async task, causing [UX pitfalls](https://wagmi.sh/docs/prepare-hooks#ux-pitfalls-without-prepare-hooks) when invoked in a click handler. + +- [#658](https://github.com/wevm/wagmi/pull/658) [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: If a `chainId` is passed to `writeContract` or `sendTransaction`, it will no longer attempt to switch chain before sending the transaction. Instead, it will throw an error if the user is on the wrong chain. + + > Why? + > + > - Eagerly prompting to switch chain in these actions created a long-running async task that that makes [iOS App Links](https://wagmi.sh/docs/prepare-hooks#ios-app-link-constraints) vulnerable. + > - Not all wallets support programmatic chain switching. + +### Patch Changes + +- [#658](https://github.com/wevm/wagmi/pull/658) [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The configuration passed to the `writeContract` action now needs to be: + + - prepared with the `prepareWriteContract` action **(new functionality)**, or + - recklessly unprepared **(previous functionality)** + + > Why? [Read here](https://wagmi.sh/docs/prepare-hooks) + + ### Prepared usage + + ```diff + import { prepareWriteContract, writeContract } from '@wagmi/core' + + const tokenId = 69 + + +const config = await prepareWriteContract({ + + addressOrName: '0x...', + + contractInterface: wagmiAbi, + + functionName: 'mint', + + args: [tokenId] + +}) + + const result = await writeContract({ + - addressOrName: '0x...', + - contractInterface: wagmiAbi, + - functionName: 'mint', + - args: [tokenId], + + ...config + }) + ``` + + ### Recklessly unprepared usage + + It is possible to use `writeContract` without preparing the configuration first by passing `mode: 'recklesslyUnprepared'`. + + ```diff + import { writeContract } from '@wagmi/core' + + const tokenId = 69 + + const result = await writeContract({ + + mode: 'recklesslyUnprepared', + addressOrName: '0x...', + contractInterface: wagmiAbi, + functionName: 'mint', + args: [tokenId], + }) + ``` + +* [#658](https://github.com/wevm/wagmi/pull/658) [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432) Thanks [@jxom](https://github.com/jxom)! - Added the `prepareSendTransaction` hook that prepares the parameters required for sending a transaction. + + It returns config to be passed through to `sendTransaction`. + + ```ts + import { prepareSendTransaction, sendTransaction } from "@wagmi/core"; + + const config = await prepareSendTransaction({ + request: { + to: "moxey.eth", + value: parseEther("1"), + }, + }); + const result = await sendTransaction(config); + ``` + +- [#658](https://github.com/wevm/wagmi/pull/658) [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432) Thanks [@jxom](https://github.com/jxom)! - Added the `prepareWriteContract` hook that prepares the parameters required for a contract write transaction. + + It returns config to be passed through to `writeContract`. + + Example: + + ```tsx + import { prepareWriteContract, writeContract } from "@wagmi/core"; + + const config = await prepareWriteContract({ + addressOrName: "0x...", + contractInterface: wagmiAbi, + functionName: "mint", + }); + const result = await writeContract(config); + ``` + +* [#739](https://github.com/wevm/wagmi/pull/739) [`c2295a5`](https://github.com/wevm/wagmi/commit/c2295a56cc86d02cc6602e2b4557b8ab9a091a3f) Thanks [@tmm](https://github.com/tmm)! - Fix balance formatting for tokens that do not have 18 decimals. + +- [#759](https://github.com/wevm/wagmi/pull/759) [`959953d`](https://github.com/wevm/wagmi/commit/959953d1f5b3e8189bac56de245c62333470d18e) Thanks [@tmm](https://github.com/tmm)! - Added `fetchTransaction` action: + + ```ts + import { fetchTransaction } from "@wagmi/core"; + + const transaction = await fetchTransaction({ + hash: "0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060", + }); + ``` + +## 0.4.9 + +### Patch Changes + +- [#721](https://github.com/tmm/wagmi/pull/721) [`abea25f`](https://github.com/tmm/wagmi/commit/abea25fd15d81d1ecaec9d3fbd687042ab29b1e6) Thanks [@tmm](https://github.com/tmm)! - Stay connected to existing `client.connector` when `connect` action fails to connect to new connector. + +* [#721](https://github.com/tmm/wagmi/pull/721) [`abea25f`](https://github.com/tmm/wagmi/commit/abea25fd15d81d1ecaec9d3fbd687042ab29b1e6) Thanks [@tmm](https://github.com/tmm)! - Switch `fetchToken` action to multicall and add `name` output property. + +## 0.4.8 + +### Patch Changes + +- [#693](https://github.com/tmm/wagmi/pull/693) [`56e468c`](https://github.com/tmm/wagmi/commit/56e468c3617ec222527bb3c02eadec3ebeff923a) Thanks [@markdalgleish](https://github.com/markdalgleish)! - Fix import errors with Coinbase Wallet SDK in Vite + +## 0.4.7 + +### Patch Changes + +- [#677](https://github.com/tmm/wagmi/pull/677) [`35e4219`](https://github.com/tmm/wagmi/commit/35e42199af9dd346549c1718e144728f55b8d7dd) Thanks [@jxom](https://github.com/jxom)! - Move `parseContractResult` to `@wagmi/core` + +## 0.4.6 + +### Patch Changes + +- [#670](https://github.com/tmm/wagmi/pull/670) [`29a0d21`](https://github.com/tmm/wagmi/commit/29a0d21ee83995559f63542778dfa805f15e7441) Thanks [@tmm](https://github.com/tmm)! - Added ethers-compatible `deepEqual` function. + +## 0.4.5 + +### Patch Changes + +- [#654](https://github.com/tmm/wagmi/pull/654) [`e66530b`](https://github.com/tmm/wagmi/commit/e66530bf4881b3533c528f8c5a5f41be0eab0a64) Thanks [@jxom](https://github.com/jxom)! - fix `multicall` returning nullish data for all calls unexpectedly + +## 0.4.4 + +### Patch Changes + +- [#616](https://github.com/tmm/wagmi/pull/616) [`7a7a17a`](https://github.com/tmm/wagmi/commit/7a7a17a46d4c9e6465cc46a111b5fe8a56109f1b) Thanks [@tmm](https://github.com/tmm)! - Adds `UNSTABLE_shimOnConnectSelectAccount` flag. With this flag and "disconnected" with `shimDisconnect` enabled, the user is prompted to select a different MetaMask account (than the currently connected account) when trying to connect (e.g. `useConnect`/`connect` action). + +## 0.4.3 + +### Patch Changes + +- [#631](https://github.com/tmm/wagmi/pull/631) [`a780e32`](https://github.com/tmm/wagmi/commit/a780e32e91a0072c795fa0b5a6111302768e2a01) Thanks [@tmm](https://github.com/tmm)! - Fix WalletConnect stale session + +## 0.4.2 + +### Patch Changes + +- [#624](https://github.com/tmm/wagmi/pull/624) [`416fa7e`](https://github.com/tmm/wagmi/commit/416fa7ee1f8019ab86e33fb93783ffddecc02c49) Thanks [@jxom](https://github.com/jxom)! - Fix broken `WebSocketProvider` type defs + +## 0.4.1 + +### Patch Changes + +- [#622](https://github.com/tmm/wagmi/pull/622) [`d171581`](https://github.com/tmm/wagmi/commit/d171581464891dd870d97b6232205da0cb152d9b) Thanks [@tmm](https://github.com/tmm)! - Use `domain.chainId` to validate and switch chain before signing in `signTypedData`. + +* [#618](https://github.com/tmm/wagmi/pull/618) [`a5138e8`](https://github.com/tmm/wagmi/commit/a5138e82a00e4d9469ad78c97b2d34200d7f1fbe) Thanks [@tmm](https://github.com/tmm)! - Fix adding chains when using MetaMask mobile app, add `publicRpcUrls` constant, and default to public endpoint when adding chain. + +## 0.4.0 + +### Minor Changes + +- [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The `provider` config option is now required on `createClient`. It is recommended to pass the [`provider` given from `configureChains`](https://wagmi.sh/docs/providers/configuring-chains). + + ```diff + import { + createClient, + + defaultChains, + + configureChains + } from 'wagmi' + +import { publicProvider } from 'wagmi/providers/publicProvider' + + +const { provider } = configureChains(defaultChains, [ + + publicProvider + +]) + + const client = createClient({ + + provider + }) + ``` + + If you previously used an ethers.js Provider, you now need to provide your `chains` on the Provider instance: + + ```diff + import { + createClient, + + defaultChains + } from 'wagmi' + import ethers from 'ethers' + + const client = createClient({ + - provider: getDefaultProvider() + + provider: Object.assign(getDefaultProvider(), { chains: defaultChains }) + }) + ``` + +* [`4f8f3c0`](https://github.com/tmm/wagmi/commit/4f8f3c0d65383bd8bbdfc3f1033adfdb11d80ebb) Thanks [@nachoiacovino](https://github.com/nachoiacovino)! - Use ethereum-lists chains symbols + +- [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4) Thanks [@jxom](https://github.com/jxom)! - **Breaking:** Removed the `chainId` parameter from `connectors` function on `createClient`. + + ```diff + const client = createClient({ + - connectors({ chainId }) { + + connectors() { + ... + } + }) + ``` + + If you previously derived RPC URLs from the `chainId` on `connectors`, you can now remove that logic as `wagmi` now handles RPC URLs internally when used with `configureChains`. + + ```diff + import { + chain, + + configureChains, + createClient + } from 'wagmi'; + + +import { publicProvider } from 'wagmi/providers/public' + + import { CoinbaseWalletConnector } from 'wagmi/connectors/coinbaseWallet' + import { InjectedConnector } from 'wagmi/connectors/injected' + import { MetaMaskConnector } from 'wagmi/connectors/metaMask' + import { WalletConnectConnector } from 'wagmi/connectors/walletConnect' + + +const { chains } = configureChains( + + [chain.mainnet], + + [publicProvider()] + +); + + const client = createClient({ + - connectors({ chainId }) { + - const chain = chains.find((x) => x.id === chainId) ?? defaultChain + - const rpcUrl = chain.rpcUrls.alchemy + - ? `${chain.rpcUrls.alchemy}/${alchemyId}` + - : chain.rpcUrls.default + - return [ + + connectors: [ + new MetaMaskConnector({ chains }), + new CoinbaseWalletConnector({ + chains, + options: { + appName: 'wagmi', + - chainId: chain.id, + - jsonRpcUrl: rpcUrl, + }, + }), + new WalletConnectConnector({ + chains, + options: { + qrcode: true, + - rpc: { [chain.id]: rpcUrl }, + }, + }), + new InjectedConnector({ + chains, + options: { name: 'Injected' }, + }), + ] + - }, + }) + ``` + +* [#611](https://github.com/tmm/wagmi/pull/611) [`3089c34`](https://github.com/tmm/wagmi/commit/3089c34196d4034acabac031e0a2f7ee63ae30cc) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: `Connector`s `getProvider` method no longer supports the `create` config parameter. Use the `chainId` config option instead. + +- [#596](https://github.com/tmm/wagmi/pull/596) [`a770af7`](https://github.com/tmm/wagmi/commit/a770af7d2cb214b6620d5341115f1e938e1e77ff) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: `TypedDataDomain` and `TypedDataField` types were removed and incorporated into `SignTypedDataArgs`. + +* [`4f8f3c0`](https://github.com/tmm/wagmi/commit/4f8f3c0d65383bd8bbdfc3f1033adfdb11d80ebb) Thanks [@nachoiacovino](https://github.com/nachoiacovino)! - Update symbols to match ethereum-lists/chains + +- [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The `writeContract` function parameters have been consolidated into a singular config parameter. + + Before: + + ```tsx + writeContract( + { + addressOrName: "0xecb504d39723b0be0e3a9aa33d646642d1051ee1", + contractInterface: wagmigotchiABI, + }, + "feed", + ); + ``` + + After: + + ```tsx + readContract({ + addressOrName: "0xecb504d39723b0be0e3a9aa33d646642d1051ee1", + contractInterface: wagmigotchiABI, + functionName: "feed", + }); + ``` + +### Patch Changes + +- [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The `readContract` & `watchReadContract` function parameters have been consolidated into a singular config parameter. + + Before: + + ```tsx + readContract( + { + addressOrName: "0xecb504d39723b0be0e3a9aa33d646642d1051ee1", + contractInterface: wagmigotchiABI, + }, + "getHunger", + { args: [0] }, + ); + + watchReadContract( + { + addressOrName: "0xecb504d39723b0be0e3a9aa33d646642d1051ee1", + contractInterface: wagmigotchiABI, + }, + "getHunger", + { args: [0] }, + (result) => {}, + ); + ``` + + After: + + ```tsx + readContract({ + addressOrName: "0xecb504d39723b0be0e3a9aa33d646642d1051ee1", + contractInterface: wagmigotchiABI, + functionName: "getHunger", + args: [0], + }); + + watchReadContract( + { + addressOrName: "0xecb504d39723b0be0e3a9aa33d646642d1051ee1", + contractInterface: wagmigotchiABI, + functionName: "getHunger", + args: [0], + }, + (result) => {}, + ); + ``` + +* [#598](https://github.com/tmm/wagmi/pull/598) [`fef26bf`](https://github.com/tmm/wagmi/commit/fef26bf8aef76fc9621e3cd54d4e0ca8f69abb38) Thanks [@markdalgleish](https://github.com/markdalgleish)! - Update `@coinbase/wallet-sdk` peer dependency to `>=3.3.0` to fix errors when connecting with older versions of the Coinbase Wallet extension and mobile app. + +- [#611](https://github.com/tmm/wagmi/pull/611) [`3089c34`](https://github.com/tmm/wagmi/commit/3089c34196d4034acabac031e0a2f7ee63ae30cc) Thanks [@tmm](https://github.com/tmm)! - Added `chainId` config parameter for `writeContract` and `sendTransaction`. + + If `chainId` is provided, the connector will validate that `chainId` is the active chain before sending a transaction (and switch to `chainId` if necessary). + +* [#582](https://github.com/tmm/wagmi/pull/582) [`b03830a`](https://github.com/tmm/wagmi/commit/b03830a54465215c2526f9509543fe2c978bfe70) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where the wagmi client's `status` would not update from `"disconnected"` to `"connecting" -> "connected"` when the `connect` action is invoked. + +- [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4) Thanks [@jxom](https://github.com/jxom)! - Added a `multicall` & `watchMulticall` action that provides multicall support. + + Internally uses the [`multicall3` contract](https://github.com/mds1/multicall). + + [See example usage](https://github.com/tmm/wagmi/blob/194866032985fdd3f49bc46bf1b14181d7cb61d1/packages/core/src/actions/contracts/multicall.test.ts) + +* [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4) Thanks [@jxom](https://github.com/jxom)! - Added a `readContracts` & `watchReadContracts` action that provides the ability to batch up multiple ethers Contract read-only methods. + +## 0.3.8 + +### Patch Changes + +- [#570](https://github.com/tmm/wagmi/pull/570) [`0e3fe15`](https://github.com/tmm/wagmi/commit/0e3fe15445377f35d6f4142b49bf1c96bfeb62cd) Thanks [@tmm](https://github.com/tmm)! - adds chain for [Foundry](https://github.com/foundry-rs) + +## 0.3.7 + +### Patch Changes + +- [#550](https://github.com/tmm/wagmi/pull/550) [`2a5313e`](https://github.com/tmm/wagmi/commit/2a5313e8cbc9ba6335e8e4b85e43862c9b711bd3) Thanks [@tmm](https://github.com/tmm)! - fix `CoinbaseWalletConnector` possible type error + +* [#548](https://github.com/tmm/wagmi/pull/548) [`0c48719`](https://github.com/tmm/wagmi/commit/0c487199f2421f042abc1f1d139468ccbbc5646a) Thanks [@dohaki](https://github.com/dohaki)! - add ensAddress to Chain type + +- [#549](https://github.com/tmm/wagmi/pull/549) [`89b3a74`](https://github.com/tmm/wagmi/commit/89b3a74ead4234daacd0dcf8506659887ebf0553) Thanks [@tmm](https://github.com/tmm)! - Turns on [`noUncheckedIndexedAccess`](https://www.typescriptlang.org/tsconfig#noUncheckedIndexedAccess=) and [`strictNullChecks`](https://www.typescriptlang.org/tsconfig#strictNullChecks=) for better runtime safety. + +## 0.3.6 + +### Patch Changes + +- [#526](https://github.com/tmm/wagmi/pull/526) [`e95c5f9`](https://github.com/tmm/wagmi/commit/e95c5f91859e57d079b962a72d06b93dce004d2f) Thanks [@jxom](https://github.com/jxom)! - Added `shimChainChangedDisconnect` option to `InjectedConnector`. Defaults to `true` for `MetaMaskConnector`. + +* [#526](https://github.com/tmm/wagmi/pull/526) [`e95c5f9`](https://github.com/tmm/wagmi/commit/e95c5f91859e57d079b962a72d06b93dce004d2f) Thanks [@jxom](https://github.com/jxom)! - Added `lastUsedChainId` property to the wagmi `Client`. + +- [#526](https://github.com/tmm/wagmi/pull/526) [`e95c5f9`](https://github.com/tmm/wagmi/commit/e95c5f91859e57d079b962a72d06b93dce004d2f) Thanks [@jxom](https://github.com/jxom)! - Added `chainId` config option to the `connect` action. + + Example: + + ```tsx + import { connect } from "@wagmi/core"; + + await connect({ chainId: 69 }); + ``` + +## 0.3.5 + +### Patch Changes + +- [#543](https://github.com/tmm/wagmi/pull/543) [`4d489fd`](https://github.com/tmm/wagmi/commit/4d489fd630dd8c00440bdaf4d646de662c41ff52) Thanks [@tmm](https://github.com/tmm)! - fix fee data formatting for null values + +## 0.3.4 + +### Patch Changes + +- [`c4deb66`](https://github.com/tmm/wagmi/commit/c4deb6655a52e4cc4e5b3fd82202db11d6106848) Thanks [@jxom](https://github.com/jxom)! - infer `options.chainId` config from `chains` on WalletConnectConnector + +## 0.3.3 + +### Patch Changes + +- [#486](https://github.com/tmm/wagmi/pull/486) [`dbfe3dd`](https://github.com/tmm/wagmi/commit/dbfe3dd320d178d6854a8096101200c1508786bb) Thanks [@tmm](https://github.com/tmm)! - add chains entrypoint + +## 0.3.2 + +### Patch Changes + +- [`17212da`](https://github.com/tmm/wagmi/commit/17212da601640110d2835300e6433d1433db212e) Thanks [@jxom](https://github.com/jxom)! - Made the `defaultChains` type generic in `configureChains`. + +## 0.3.1 + +### Patch Changes + +- [#484](https://github.com/tmm/wagmi/pull/484) [`1b9a503`](https://github.com/tmm/wagmi/commit/1b9a5033d51c6655b4f6570c490da6e0e9a29da9) Thanks [@tmm](https://github.com/tmm)! - export React Context + +## 0.3.0 + +### Minor Changes + +- [#408](https://github.com/tmm/wagmi/pull/408) [`bfcc3a5`](https://github.com/tmm/wagmi/commit/bfcc3a51bbb1551753e3ccde6af134e9fd4fec9a) Thanks [@jxom](https://github.com/jxom)! - **Breaking:** The `connectors` option on `createClient` no longer reacts to chain switching. + + **Passing a function to `connectors` has been deprecated.** + + If you previously derived an RPC URL from the `chainId` in `connectors`, you will need to migrate to use the [`configureChains` API](https://wagmi.sh/docs/providers/configuring-chains). + + ### Before + + ```tsx + import { providers } from "ethers"; + import { chain, createClient, defaultChains } from "wagmi"; + import { CoinbaseWalletConnector } from "wagmi/connectors/coinbaseWallet"; + import { InjectedConnector } from "wagmi/connectors/injected"; + import { MetaMaskConnector } from "wagmi/connectors/metaMask"; + import { WalletConnectConnector } from "wagmi/connectors/walletConnect"; + + const alchemyId = process.env.ALCHEMY_ID; + + const chains = defaultChains; + const defaultChain = chain.mainnet; + + const client = createClient({ + autoConnect: true, + connectors({ chainId }) { + const chain = chains.find((x) => x.id === chainId) ?? defaultChain; + const rpcUrl = chain.rpcUrls.alchemy + ? `${chain.rpcUrls.alchemy}/${alchemyId}` + : chain.rpcUrls.default; + return [ + new MetaMaskConnector({ chains }), + new CoinbaseWalletConnector({ + chains, + options: { + appName: "wagmi", + chainId: chain.id, + jsonRpcUrl: rpcUrl, + }, + }), + new WalletConnectConnector({ + chains, + options: { + qrcode: true, + rpc: { [chain.id]: rpcUrl }, + }, + }), + new InjectedConnector({ + chains, + options: { + name: "Injected", + shimDisconnect: true, + }, + }), + ]; + }, + }); + ``` + + ### After + + ```tsx + import { chain, createClient, defaultChains } from "wagmi"; + + import { alchemyProvider } from "wagmi/providers/alchemy"; + import { publicProvider } from "wagmi/providers/public"; + + import { CoinbaseWalletConnector } from "wagmi/connectors/coinbaseWallet"; + import { InjectedConnector } from "wagmi/connectors/injected"; + import { MetaMaskConnector } from "wagmi/connectors/metaMask"; + import { WalletConnectConnector } from "wagmi/connectors/walletConnect"; + + const alchemyId = process.env.ALCHEMY_ID; + + const { chains } = configureChains(defaultChains, [ + alchemyProvider({ alchemyId }), + publicProvider(), + ]); + + const client = createClient({ + autoConnect: true, + connectors: [ + new MetaMaskConnector({ chains }), + new CoinbaseWalletConnector({ + chains, + options: { + appName: "wagmi", + }, + }), + new WalletConnectConnector({ + chains, + options: { + qrcode: true, + }, + }), + new InjectedConnector({ + chains, + options: { + name: "Injected", + shimDisconnect: true, + }, + }), + ], + }); + ``` + +* [#468](https://github.com/tmm/wagmi/pull/468) [`44a884b`](https://github.com/tmm/wagmi/commit/44a884b84171c418f57701e80ef8de972948ef0b) Thanks [@tmm](https://github.com/tmm)! - **Breaking:** Duplicate exports with different names and the same functionality were removed to simplify the public API. In addition, confusing exports were renamed to be more descriptive. + + - `createWagmiClient` alias was removed. Use `createClient` instead. + - `useWagmiClient` alias was removed. Use `useClient` instead. + - `WagmiClient` alias was removed. Use `Client` instead. + - `createWagmiStorage` alias was removed. Use `createStorage` instead. + - `Provider` was renamed and `WagmiProvider` alias was removed. Use `WagmiConfig` instead. + +- [#408](https://github.com/tmm/wagmi/pull/408) [`bfcc3a5`](https://github.com/tmm/wagmi/commit/bfcc3a51bbb1551753e3ccde6af134e9fd4fec9a) Thanks [@jxom](https://github.com/jxom)! - Add `configureChains` API. + + The `configureChains` function allows you to configure your chains with a selected provider (Alchemy, Infura, JSON RPC, Public RPC URLs). This means you don't have to worry about deriving your own RPC URLs for each chain, or instantiating a Ethereum Provider. + + `configureChains` accepts 3 parameters: an array of chains, and an array of providers, and a config object. + + [Learn more about configuring chains & providers.](https://wagmi.sh/docs/providers/configuring-chains) + + ### Before + + ```tsx + import { providers } from "ethers"; + import { chain, createClient, defaultChains } from "wagmi"; + import { CoinbaseWalletConnector } from "wagmi/connectors/coinbaseWallet"; + import { InjectedConnector } from "wagmi/connectors/injected"; + import { MetaMaskConnector } from "wagmi/connectors/metaMask"; + import { WalletConnectConnector } from "wagmi/connectors/walletConnect"; + + const alchemyId = process.env.ALCHEMY_ID; + + const chains = defaultChains; + const defaultChain = chain.mainnet; + + const client = createClient({ + autoConnect: true, + connectors({ chainId }) { + const chain = chains.find((x) => x.id === chainId) ?? defaultChain; + const rpcUrl = chain.rpcUrls.alchemy + ? `${chain.rpcUrls.alchemy}/${alchemyId}` + : chain.rpcUrls.default; + return [ + new MetaMaskConnector({ chains }), + new CoinbaseWalletConnector({ + chains, + options: { + appName: "wagmi", + chainId: chain.id, + jsonRpcUrl: rpcUrl, + }, + }), + new WalletConnectConnector({ + chains, + options: { + qrcode: true, + rpc: { [chain.id]: rpcUrl }, + }, + }), + new InjectedConnector({ + chains, + options: { + name: "Injected", + shimDisconnect: true, + }, + }), + ]; + }, + provider: ({ chainId }) => + new providers.AlchemyProvider(chainId, alchemyId), + }); + ``` + + ### After + + ```tsx + import { chain, createClient, defaultChains } from "wagmi"; + + import { alchemyProvider } from "wagmi/providers/alchemy"; + import { publicProvider } from "wagmi/providers/public"; + + import { CoinbaseWalletConnector } from "wagmi/connectors/coinbaseWallet"; + import { InjectedConnector } from "wagmi/connectors/injected"; + import { MetaMaskConnector } from "wagmi/connectors/metaMask"; + import { WalletConnectConnector } from "wagmi/connectors/walletConnect"; + + const alchemyId = process.env.ALCHEMY_ID; + + const { chains, provider, webSocketProvider } = configureChains( + defaultChains, + [alchemyProvider({ alchemyId }), publicProvider()], + ); + + const client = createClient({ + autoConnect: true, + connectors: [ + new MetaMaskConnector({ chains }), + new CoinbaseWalletConnector({ + chains, + options: { + appName: "wagmi", + }, + }), + new WalletConnectConnector({ + chains, + options: { + qrcode: true, + }, + }), + new InjectedConnector({ + chains, + options: { + name: "Injected", + shimDisconnect: true, + }, + }), + ], + provider, + webSocketProvider, + }); + ``` + +### Patch Changes + +- [#404](https://github.com/tmm/wagmi/pull/404) [`f81c156`](https://github.com/tmm/wagmi/commit/f81c15665e2e71534f84ada3fa705f2d78627472) Thanks [@holic](https://github.com/holic)! - Add `ProviderRpcError` and `RpcError` error classes. + + Certain wagmi-standardized errors may wrap `ProviderRpcError` or `RpcError`. For these cases, you can access the original provider rpc or rpc error value using the `internal` property. + +* [#459](https://github.com/tmm/wagmi/pull/459) [`72dcf7c`](https://github.com/tmm/wagmi/commit/72dcf7c09e814261b2e43a8fa364c57675c472de) Thanks [@tmm](https://github.com/tmm)! - update dependencies + +- [#473](https://github.com/tmm/wagmi/pull/473) [`a54f3e2`](https://github.com/tmm/wagmi/commit/a54f3e23ea385ed8aa4ad188128d7089ba20f83e) Thanks [@cesargdm](https://github.com/cesargdm)! - Add workaround for CoinbaseWalletSDK import on esbuild + +* [#447](https://github.com/tmm/wagmi/pull/447) [`b9ebf78`](https://github.com/tmm/wagmi/commit/b9ebf782e0900725bcb76483686b30f09d357ebd) Thanks [@tmm](https://github.com/tmm)! - Fix case where connector disconnected while app was closed and stale data was returned when autoconnecting. For example, [MetaMask was locked](https://github.com/tmm/wagmi/issues/444) when page was closed. + +## 0.2.5 + +### Patch Changes + +- [`4e03666`](https://github.com/tmm/wagmi/commit/4e03666428d42fc9186c617001b5eb356229677e) Thanks [@tmm](https://github.com/tmm)! - bump dependencies #429 + add imToken support for WC switch chains #432 + fix MetaMask and Brave Wallet collision #436 + +## 0.2.4 + +### Patch Changes + +- [#421](https://github.com/tmm/wagmi/pull/421) [`a232b3f`](https://github.com/tmm/wagmi/commit/a232b3ff5cc41e882c4d2a34c599a8cb670edd2b) Thanks [@tmm](https://github.com/tmm)! - fix erc721 abi + +## 0.2.3 + +### Patch Changes + +- [#412](https://github.com/tmm/wagmi/pull/412) [`80bef4f`](https://github.com/tmm/wagmi/commit/80bef4ff3f714b0b8f896f1b4b658acc7266299b) Thanks [@markdalgleish](https://github.com/markdalgleish)! - Import providers from `ethers` peer dependency rather than `@ethersproject/providers` to avoid multiple conflicting versions being installed + +## 0.2.2 + +### Patch Changes + +- [`018c2a1`](https://github.com/tmm/wagmi/commit/018c2a11b22ee513571cc7f83fd63f7eb169ee70) Thanks [@tmm](https://github.com/tmm)! - - warn and fallback to default client #380 + + - remove signerOrProvider option from read contract #390 + + - MetaMaskConnector #391 + +## 0.2.1 + +### Patch Changes + +- [`afc4607`](https://github.com/tmm/wagmi/commit/afc46071e91601ab8a2b465524da796cd60b6ad4) Thanks [@tmm](https://github.com/tmm)! - - Fix time scaling e9593df + - Use fully-specified path for use-sync-external-store import 7b235c1 + - Update serialize 236fc17 + +## 0.2.0 + +### Minor Changes + +- [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - don't persist account data when `autoConnect` is falsy + +* [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - - fix(@wagmi/core): persist connector chains to local storage + +- [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - - Favour `message` event over `connecting` event to conform to EIP-1193 + - Export `useWaitForTransaction` + +* [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - Initial 0.3.0 release + +- [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - Add `cacheOnBlock` config for `useContractRead` + Update `react-query` to v4 + Fix `watchBlockNumber` listener leak + +* [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - add `connecting` event to connectors + +- [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - Fix issue where `getProvider` was not being awaited in `getSigner` + +* [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - - remove storage persistence of `connector` + - add `chains` to client state + +### Patch Changes + +- [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - add chainId to actions and hooks + +* [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - showtime + +- [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - improve type support for ethers providers + +* [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - update zustand + +- [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - update babel target + +* [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - update block explorers and rpc urls structure + +- [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - keep previous data when watching + +* [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - republish + +- [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - fix stale connectors when switching chains + +* [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - last beta + +## 0.2.0-next.18 + +### Patch Changes + +- showtime + +## 0.2.0-next.17 + +### Patch Changes + +- update block explorers and rpc urls structure + +## 0.2.0-next.16 + +### Patch Changes + +- last beta + +## 0.2.0-next.15 + +### Patch Changes + +- update zustand + +## 0.2.0-next.14 + +### Minor Changes + +- Add `cacheOnBlock` config for `useContractRead` +- Update `react-query` to v4 +- Fix `watchBlockNumber` listener leak + +## 0.2.0-next.13 + +### Patch Changes + +- keep previous data when watching + +## 0.2.0-next.12 + +### Patch Changes + +- add chainId to actions and hooks + +## 0.2.0-next.11 + +### Patch Changes + +- fix stale connectors when switching chains + +## 0.2.0-next.10 + +### Patch Changes + +- republish + +## 0.2.0-next.9 + +### Patch Changes + +- improve type support for ethers providers + +## 0.2.0-next.8 + +### Patch Changes + +- update babel target + +## 0.2.0-next.7 + +### Minor Changes + +- - Favour `message` event over `connecting` event to conform to EIP-1193 + - Export `useWaitForTransaction` + +## 0.2.0-next.6 + +### Minor Changes + +- add `connecting` event to connectors + +## 0.2.0-next.5 + +### Minor Changes + +- don't persist account data when `autoConnect` is falsy + +## 0.2.0-next.4 + +### Minor Changes + +- remove storage persistence of `connector` +- add `chains` to client state + +## 0.2.0-next.3 + +### Minor Changes + +- Fix issue where `getProvider` was not being awaited in `getSigner` + +## 0.2.0-next.2 + +### Minor Changes + +- fix: persist connector chains to local storage + +## 0.2.0-next.1 + +### Minor Changes + +- Initial 0.3.0 release + +## 0.1.22 + +### Patch Changes + +- [`747d895`](https://github.com/tmm/wagmi/commit/747d895a54b562958afde34b1d34e81ab5039e2c) Thanks [@tmm](https://github.com/tmm)! - add warning to WalletLinkConnector + +## 0.1.21 + +### Patch Changes + +- [`c858c51`](https://github.com/tmm/wagmi/commit/c858c51b44d9039f1d0db5bcf016639f47d1931f) Thanks [@tmm](https://github.com/tmm)! - update coinbase connector + +## 0.1.20 + +### Patch Changes + +- [#326](https://github.com/tmm/wagmi/pull/326) [`36e6989`](https://github.com/tmm/wagmi/commit/36e69894f4c27aaad7fb6d678476c8bb870244bb) Thanks [@0xGabi](https://github.com/0xGabi)! - Add Gnosis Chain + +## 0.1.19 + +### Patch Changes + +- [`d467df6`](https://github.com/tmm/wagmi/commit/d467df6374210dbc4b016788b4beb4fded54cb4d) Thanks [@tmm](https://github.com/tmm)! - fix global type leaking + +## 0.1.18 + +### Patch Changes + +- [#294](https://github.com/tmm/wagmi/pull/294) [`1d253f3`](https://github.com/tmm/wagmi/commit/1d253f3a59b61d24c88d25c99decd84a6c734e5d) Thanks [@tmm](https://github.com/tmm)! - change babel target + +## 0.1.17 + +### Patch Changes + +- [#292](https://github.com/tmm/wagmi/pull/292) [`53c9be1`](https://github.com/tmm/wagmi/commit/53c9be17ee0c2ae6b8f34f2351b8858257b3f5f2) Thanks [@tmm](https://github.com/tmm)! - fix private fields + +## 0.1.16 + +### Patch Changes + +- [`79a2499`](https://github.com/tmm/wagmi/commit/79a249989029f818c32c0e84c0dd2c75e8aa990a) Thanks [@tmm](https://github.com/tmm)! - update build target to es2021 + +## 0.1.15 + +### Patch Changes + +- [`f9790b5`](https://github.com/tmm/wagmi/commit/f9790b55600df09c77bb8ca349c5a3457df1b07c) Thanks [@tmm](https://github.com/tmm)! - fix WalletConnect issue + +## 0.1.14 + +### Patch Changes + +- [#236](https://github.com/tmm/wagmi/pull/236) [`53bad61`](https://github.com/tmm/wagmi/commit/53bad615788764e31121678083c382c1bd042fe8) Thanks [@markdalgleish](https://github.com/markdalgleish)! - Updated `@walletconnect/ethereum-provider` to [v1.7.4](https://github.com/WalletConnect/walletconnect-monorepo/releases/tag/1.7.4) + +## 0.1.13 + +### Patch Changes + +- [`8e9412a`](https://github.com/tmm/wagmi/commit/8e9412af71958301ae2f9748febb936e79900aa0) Thanks [@tmm](https://github.com/tmm)! - bump walletlink + +## 0.1.12 + +### Patch Changes + +- [#210](https://github.com/tmm/wagmi/pull/210) [`684468a`](https://github.com/tmm/wagmi/commit/684468aee3e42a1ce2b4b599f3f17d1819213de8) Thanks [@tmm](https://github.com/tmm)! - update chains to match chainslist.org + +## 0.1.11 + +### Patch Changes + +- [#195](https://github.com/tmm/wagmi/pull/195) [`25b6083`](https://github.com/tmm/wagmi/commit/25b6083a662a0236794d1765343467691421c14b) Thanks [@tmm](https://github.com/tmm)! - rename wagmi-private to wagmi-core + +## 0.1.10 + +### Patch Changes + +- [#192](https://github.com/tmm/wagmi/pull/192) [`428cedb`](https://github.com/tmm/wagmi/commit/428cedb3dec4e3e4b9f4559c8e65932e05f94e05) Thanks [@tmm](https://github.com/tmm)! - rename core and testing packages + +## 0.1.9 + +### Patch Changes + +- [#190](https://github.com/tmm/wagmi/pull/190) [`7034bb8`](https://github.com/tmm/wagmi/commit/7034bb868412b9f481b206371280e84c2d52706d) Thanks [@tmm](https://github.com/tmm)! - add shim for metamask chain changed to prevent disconnect + +## 0.1.8 + +### Patch Changes + +- [#137](https://github.com/tmm/wagmi/pull/137) [`dceeb43`](https://github.com/tmm/wagmi/commit/dceeb430d9021fbf98366859cb1cd0149e80c55c) Thanks [@tmm](https://github.com/tmm)! - add siwe guide + +## 0.1.7 + +### Patch Changes + +- [#127](https://github.com/tmm/wagmi/pull/127) [`f05b031`](https://github.com/tmm/wagmi/commit/f05b0310f7f7e6447e9b6c81cedbb27dcf2f3649) Thanks [@tmm](https://github.com/tmm)! - update switch chain return type + +## 0.1.6 + +### Patch Changes + +- [`1412eed`](https://github.com/tmm/wagmi/commit/1412eed0d1494bb4f8c6845a0e890f79e4e68e03) Thanks [@tmm](https://github.com/tmm)! - add frame to injected + +## 0.1.5 + +### Patch Changes + +- [`e338c3b`](https://github.com/tmm/wagmi/commit/e338c3b6cc255742be6a67593aa5da6c17e90fbd) Thanks [@tmm](https://github.com/tmm)! - checksum connector address on change events + + add shim to injected connector for simulating disconnect + +## 0.1.4 + +### Patch Changes + +- [`0176c4e`](https://github.com/tmm/wagmi/commit/0176c4e83fb0c5f159c3c802a1da3d6deb2184ae) Thanks [@tmm](https://github.com/tmm)! - added switchChain to WalletConnect and WalletLink connectors + +## 0.1.3 + +### Patch Changes + +- [`071d7fb`](https://github.com/tmm/wagmi/commit/071d7fbca35ec4832700b5343661ceb2dae20598) Thanks [@tmm](https://github.com/tmm)! - add hardhat chain + +## 0.1.2 + +### Patch Changes + +- [`78bade9`](https://github.com/tmm/wagmi/commit/78bade9d0da97ab38a7e6594c34e3841ec1c8fe6) Thanks [@tmm](https://github.com/tmm)! - add type definitions + +## 0.1.1 + +### Patch Changes + +- [#56](https://github.com/tmm/wagmi/pull/56) [`2ebfd8e`](https://github.com/tmm/wagmi/commit/2ebfd8e85b560f25cd46cff04619c84643cab297) Thanks [@tmm](https://github.com/tmm)! - add chain support status + +## 0.1.0 + +### Minor Changes + +- [#52](https://github.com/tmm/wagmi/pull/52) [`da7a3a6`](https://github.com/tmm/wagmi/commit/da7a3a615def2443f65c041999100ce35e9774cc) Thanks [@tmm](https://github.com/tmm)! - Moves connectors to their own entrypoints to reduce bundle size. + + ```ts + // old - WalletLinkConnector unused, but still in final bundle + import { InjectedConnector, WalletConnectConnector } from "wagmi"; + + // new - WalletLinkConnector not in final bundle + import { InjectedConnector } from "wagmi/connectors/injected"; + import { WalletConnectConnector } from "wagmi/connectors/walletConnect"; + ``` + +## 0.0.17 + +### Patch Changes + +- [#25](https://github.com/tmm/wagmi/pull/25) [`9a7dab7`](https://github.com/tmm/wagmi/commit/9a7dab78b3518658bc7d85dc397990f0d28da175) Thanks [@tmm](https://github.com/tmm)! - update response types + +## 0.0.16 + +### Patch Changes + +- [`d1574cf`](https://github.com/tmm/wagmi/commit/d1574cf5f7a578ccd480889c2e375134145a4aba) Thanks [@tmm](https://github.com/tmm)! - add better type information for contract results + +## 0.0.15 + +### Patch Changes + +- [`3909624`](https://github.com/tmm/wagmi/commit/39096249c1fa9516beabb11735beb67c94032879) Thanks [@tmm](https://github.com/tmm)! - make contract read and write execute overrides param optional + +## 0.0.14 + +### Patch Changes + +- [`63312e2`](https://github.com/tmm/wagmi/commit/63312e2b06b8d835abc2908cba399d941ca79408) Thanks [@tmm](https://github.com/tmm)! - add once to contract event + +## 0.0.13 + +### Patch Changes + +- [`6f890b0`](https://github.com/tmm/wagmi/commit/6f890b0dabbdbea913ec91cb8bfc970c05ed0a93) Thanks [@tmm](https://github.com/tmm)! - update readme + +## 0.0.12 + +### Patch Changes + +- [#19](https://github.com/tmm/wagmi/pull/19) [`7bc1c47`](https://github.com/tmm/wagmi/commit/7bc1c47875e9ef24e9c79cfafc6b23e7a838b5bc) Thanks [@tmm](https://github.com/tmm)! - remove console log from walletlink connector + +## 0.0.11 + +### Patch Changes + +- [#17](https://github.com/tmm/wagmi/pull/17) [`571648b`](https://github.com/tmm/wagmi/commit/571648b754f7f538536bafc9387bd3104657ea49) Thanks [@tmm](https://github.com/tmm)! - standardize connector provider + +## 0.0.10 + +### Patch Changes + +- [#15](https://github.com/tmm/wagmi/pull/15) [`5f7675c`](https://github.com/tmm/wagmi/commit/5f7675c3ffd848522d4117c07c1f62b17dfc6616) Thanks [@tmm](https://github.com/tmm)! - read and write contract functions + +## 0.0.9 + +### Patch Changes + +- [#13](https://github.com/tmm/wagmi/pull/13) [`e5545f5`](https://github.com/tmm/wagmi/commit/e5545f5565cf0bbf5e62ec7ccab3051705b1d313) Thanks [@tmm](https://github.com/tmm)! - add testing package + +## 0.0.8 + +### Patch Changes + +- [`5332500`](https://github.com/tmm/wagmi/commit/5332500918ac240d29ffe4d2aed8566a8ac001e4) Thanks [@tmm](https://github.com/tmm)! - update signing + +## 0.0.7 + +### Patch Changes + +- [`0bff89a`](https://github.com/tmm/wagmi/commit/0bff89ab2ad28b2cb9b346d1ac870e859d9278bc) Thanks [@tmm](https://github.com/tmm)! - update injected connector + +## 0.0.6 + +### Patch Changes + +- [`37d39d1`](https://github.com/tmm/wagmi/commit/37d39d174ddfa122462bbe2d02141cd61eb9db4a) Thanks [@tmm](https://github.com/tmm)! - add message signing + +## 0.0.5 + +### Patch Changes + +- [`d7d94f0`](https://github.com/tmm/wagmi/commit/d7d94f06f7d30468e5e39d64db63124c6315cf82) Thanks [@tmm](https://github.com/tmm)! - fix injected connector name + +## 0.0.4 + +### Patch Changes + +- [`29fbe29`](https://github.com/tmm/wagmi/commit/29fbe2920046b9e87a34faa04500ccf3c4f83748) Thanks [@tmm](https://github.com/tmm)! - fix external deps + +## 0.0.3 + +### Patch Changes + +- [#6](https://github.com/tmm/wagmi/pull/6) [`8dc3a5d`](https://github.com/tmm/wagmi/commit/8dc3a5d5f418813b09663534fe585d9bcf94dbeb) Thanks [@tmm](https://github.com/tmm)! - clean up deps + +## 0.0.2 + +### Patch Changes + +- [#4](https://github.com/tmm/wagmi/pull/4) [`2fbd821`](https://github.com/tmm/wagmi/commit/2fbd8216379bd03c9cc5c06b10b75637e75cb7d8) Thanks [@tmm](https://github.com/tmm)! - init changesets diff --git a/wagmi-project/packages/core/README.md b/wagmi-project/packages/core/README.md new file mode 100644 index 0000000000..b46e39c559 --- /dev/null +++ b/wagmi-project/packages/core/README.md @@ -0,0 +1,13 @@ +# @wagmi/core + +VanillaJS library for Ethereum + +## Installation + +```bash +pnpm add @wagmi/core viem +``` + +## Documentation + +For documentation and guides, visit [wagmi.sh](https://wagmi.sh). diff --git a/wagmi-project/packages/core/package.json b/wagmi-project/packages/core/package.json new file mode 100644 index 0000000000..00589ee839 --- /dev/null +++ b/wagmi-project/packages/core/package.json @@ -0,0 +1,100 @@ +{ + "name": "@wagmi/core", + "description": "VanillaJS library for Ethereum", + "version": "2.17.2", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/wevm/wagmi.git", + "directory": "packages/core" + }, + "scripts": { + "build": "pnpm run clean && pnpm run build:esm+types", + "build:esm+types": "tsc --project tsconfig.build.json --outDir ./dist/esm --declaration --declarationMap --declarationDir ./dist/types", + "check:types": "tsc --noEmit", + "clean": "rm -rf dist tsconfig.tsbuildinfo actions chains codegen experimental internal query", + "test:build": "publint --strict && attw --pack --ignore-rules cjs-resolves-to-esm" + }, + "files": [ + "dist/**", + "!dist/**/*.tsbuildinfo", + "src/**/*.ts", + "!src/**/*.test.ts", + "!src/**/*.test-d.ts", + "/actions", + "/chains", + "/experimental", + "/internal", + "/query" + ], + "sideEffects": false, + "type": "module", + "main": "./dist/esm/exports/index.js", + "types": "./dist/types/exports/index.d.ts", + "typings": "./dist/types/exports/index.d.ts", + "exports": { + ".": { + "types": "./dist/types/exports/index.d.ts", + "default": "./dist/esm/exports/index.js" + }, + "./actions": { + "types": "./dist/types/exports/actions.d.ts", + "default": "./dist/esm/exports/actions.js" + }, + "./chains": { + "types": "./dist/types/exports/chains.d.ts", + "default": "./dist/esm/exports/chains.js" + }, + "./codegen": { + "types": "./dist/types/exports/codegen.d.ts", + "default": "./dist/esm/exports/codegen.js" + }, + "./experimental": { + "types": "./dist/types/exports/experimental.d.ts", + "default": "./dist/esm/exports/experimental.js" + }, + "./internal": { + "types": "./dist/types/exports/internal.d.ts", + "default": "./dist/esm/exports/internal.js" + }, + "./query": { + "types": "./dist/types/exports/query.d.ts", + "default": "./dist/esm/exports/query.js" + }, + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "actions": ["./dist/types/exports/actions.d.ts"], + "chains": ["./dist/types/exports/chains.d.ts"], + "codegen": ["./dist/types/exports/codegen.d.ts"], + "experimental": ["./dist/types/exports/experimental.d.ts"], + "internal": ["./dist/types/exports/internal.d.ts"], + "query": ["./dist/types/exports/query.d.ts"] + } + }, + "peerDependencies": { + "@tanstack/query-core": ">=5.0.0", + "typescript": ">=5.0.4", + "viem": "2.x" + }, + "peerDependenciesMeta": { + "@tanstack/query-core": { + "optional": true + }, + "typescript": { + "optional": true + } + }, + "dependencies": { + "eventemitter3": "5.0.1", + "mipd": "0.0.7", + "zustand": "5.0.0" + }, + "devDependencies": { + "@tanstack/query-core": "catalog:" + }, + "contributors": ["awkweb.eth ", "jxom.eth "], + "funding": "https://github.com/sponsors/wevm", + "keywords": ["wagmi", "eth", "ethereum", "dapps", "wallet", "web3"] +} diff --git a/wagmi-project/packages/core/src/actions/call.test.ts b/wagmi-project/packages/core/src/actions/call.test.ts new file mode 100644 index 0000000000..2ef01160da --- /dev/null +++ b/wagmi-project/packages/core/src/actions/call.test.ts @@ -0,0 +1,149 @@ +import { accounts, address, config } from '@wagmi/test' +import { parseEther, parseGwei } from 'viem' +import { expect, test } from 'vitest' + +import { call } from './call.js' + +const name4bytes = '0x06fdde03' +const mint4bytes = '0x1249c58b' +const mintWithParams4bytes = '0xa0712d68' +const fourTwenty = + '00000000000000000000000000000000000000000000000000000000000001a4' + +const account = accounts[0] + +test('default', async () => { + await expect( + call(config, { + account, + data: name4bytes, + to: address.wagmiMintExample, + }), + ).resolves.toMatchInlineSnapshot(` + { + "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000057761676d69000000000000000000000000000000000000000000000000000000", + } + `) +}) + +test('zero data', async () => { + await expect( + call(config, { + account, + data: mint4bytes, + to: address.wagmiMintExample, + }), + ).resolves.toMatchInlineSnapshot(` + { + "data": undefined, + } + `) +}) + +// TODO: Re-enable +test.skip('parameters: blockNumber', async () => { + await expect( + call(config, { + account, + data: name4bytes, + to: address.wagmiMintExample, + blockNumber: 16280770n, + }), + ).resolves.toMatchInlineSnapshot(` + { + "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000057761676d69000000000000000000000000000000000000000000000000000000", + } + `) +}) + +test('insufficient funds', async () => { + await expect( + call(config, { + account, + to: accounts[1], + value: parseEther('100000'), + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [CallExecutionError: The total cost (gas * gas fee + value) of executing this transaction exceeds the balance of the account. + + This error could arise when the account does not have enough funds to: + - pay for the total gas fee, + - pay for the value to send. + + The cost of the transaction is calculated as \`gas * gas fee + value\`, where: + - \`gas\` is the amount of gas needed for transaction to execute, + - \`gas fee\` is the gas fee, + - \`value\` is the amount of ether to send to the recipient. + + Raw Call Arguments: + from: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 + to: 0x70997970c51812dc3a010c7d01b50e0d17dc79c8 + value: 100000 ETH + + Details: Insufficient funds for gas * price + value + Version: viem@2.29.2] + `) +}) + +test('maxFeePerGas less than maxPriorityFeePerGas', async () => { + await expect( + call(config, { + account, + data: name4bytes, + to: address.wagmiMintExample, + maxFeePerGas: parseGwei('20'), + maxPriorityFeePerGas: parseGwei('22'), + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [CallExecutionError: The provided tip (\`maxPriorityFeePerGas\` = 22 gwei) cannot be higher than the fee cap (\`maxFeePerGas\` = 20 gwei). + + Raw Call Arguments: + from: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 + to: 0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2 + data: 0x06fdde03 + maxFeePerGas: 20 gwei + maxPriorityFeePerGas: 22 gwei + + Version: viem@2.29.2] + `) +}) + +test('contract revert (contract error)', async () => { + await expect( + call(config, { + account, + data: `${mintWithParams4bytes}${fourTwenty}`, + to: address.wagmiMintExample, + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [CallExecutionError: Execution reverted with reason: Token ID is taken. + + Raw Call Arguments: + from: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 + to: 0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2 + data: 0xa0712d6800000000000000000000000000000000000000000000000000000000000001a4 + + Details: execution reverted: Token ID is taken + Version: viem@2.29.2] + `) +}) + +test('contract revert (insufficient params)', async () => { + await expect( + call(config, { + account, + data: mintWithParams4bytes, + to: address.wagmiMintExample, + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [CallExecutionError: Execution reverted for an unknown reason. + + Raw Call Arguments: + from: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 + to: 0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2 + data: 0xa0712d68 + + Details: execution reverted + Version: viem@2.29.2] + `) +}) diff --git a/wagmi-project/packages/core/src/actions/call.ts b/wagmi-project/packages/core/src/actions/call.ts new file mode 100644 index 0000000000..90e6c1ae20 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/call.ts @@ -0,0 +1,27 @@ +import type { + CallErrorType as viem_CallErrorType, + CallParameters as viem_CallParameters, + CallReturnType as viem_CallReturnType, +} from 'viem' +import { call as viem_call } from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import { getAction } from '../utils/getAction.js' + +export type CallParameters = + viem_CallParameters & ChainIdParameter + +export type CallReturnType = viem_CallReturnType + +export type CallErrorType = viem_CallErrorType + +export async function call( + config: config, + parameters: CallParameters, +): Promise { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction(client, viem_call, 'call') + return action(rest) +} diff --git a/wagmi-project/packages/core/src/actions/codegen/createReadContract.test-d.ts b/wagmi-project/packages/core/src/actions/codegen/createReadContract.test-d.ts new file mode 100644 index 0000000000..f5c9dd302b --- /dev/null +++ b/wagmi-project/packages/core/src/actions/codegen/createReadContract.test-d.ts @@ -0,0 +1,130 @@ +import { abi, config, mainnet, optimism } from '@wagmi/test' +import { assertType, expectTypeOf, test } from 'vitest' + +import { createReadContract } from './createReadContract.js' + +test('default', async () => { + const readErc20 = createReadContract({ + abi: abi.erc20, + address: '0x', + }) + + const result = await readErc20(config, { + functionName: 'balanceOf', + args: ['0x'], + chainId: 1, + }) + expectTypeOf(result).toEqualTypeOf() +}) + +test('multichain address', async () => { + const readErc20 = createReadContract({ + abi: abi.erc20, + address: { + [mainnet.id]: '0x', + [optimism.id]: '0x', + }, + }) + + const result = await readErc20(config, { + functionName: 'balanceOf', + args: ['0x'], + chainId: mainnet.id, + // ^? + }) + assertType(result) + + readErc20(config, { + functionName: 'balanceOf', + args: ['0x'], + // @ts-expect-error chain id must match address keys + chainId: 420, + }) + + readErc20(config, { + functionName: 'balanceOf', + args: ['0x'], + // @ts-expect-error address not allowed + address: '0x', + }) +}) + +test('overloads', async () => { + const readViewOverloads = createReadContract({ + abi: abi.viewOverloads, + address: '0x', + }) + + const result1 = await readViewOverloads(config, { + functionName: 'foo', + }) + assertType(result1) + + const result2 = await readViewOverloads(config, { + functionName: 'foo', + args: [], + }) + assertType(result2) + + const result3 = await readViewOverloads(config, { + functionName: 'foo', + args: ['0x'], + }) + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + assertType(result3) + + const result4 = await readViewOverloads(config, { + functionName: 'foo', + args: ['0x', '0x'], + }) + assertType<{ + foo: `0x${string}` + bar: `0x${string}` + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + }>(result4) +}) + +test('functionName', async () => { + const readErc20BalanceOf = createReadContract({ + abi: abi.erc20, + address: '0x', + functionName: 'balanceOf', + }) + + const result = await readErc20BalanceOf(config, { + args: ['0x'], + chainId: 1, + }) + expectTypeOf(result).toEqualTypeOf() +}) + +test('functionName with overloads', async () => { + const readViewOverloads = createReadContract({ + abi: abi.viewOverloads, + address: '0x', + functionName: 'foo', + }) + + const result1 = await readViewOverloads(config, {}) + assertType(result1) + + const result2 = await readViewOverloads(config, { + args: [], + }) + assertType(result2) + + const result3 = await readViewOverloads(config, { + args: ['0x'], + }) + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + assertType(result3) + + const result4 = await readViewOverloads(config, { + args: ['0x', '0x'], + }) + assertType<{ + foo: `0x${string}` + bar: `0x${string}` + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + }>(result4) +}) diff --git a/wagmi-project/packages/core/src/actions/codegen/createReadContract.test.ts b/wagmi-project/packages/core/src/actions/codegen/createReadContract.test.ts new file mode 100644 index 0000000000..9de7ae718f --- /dev/null +++ b/wagmi-project/packages/core/src/actions/codegen/createReadContract.test.ts @@ -0,0 +1,50 @@ +import { abi, address, chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { createReadContract } from './createReadContract.js' + +test('default', async () => { + const readWagmiMintExample = createReadContract({ + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + }) + + await expect( + readWagmiMintExample(config, { + functionName: 'balanceOf', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }), + ).resolves.toMatchInlineSnapshot('4n') +}) + +test('multichain', async () => { + const readWagmiMintExample = createReadContract({ + address: { + [chain.mainnet.id]: address.wagmiMintExample, + [chain.mainnet2.id]: address.wagmiMintExample, + }, + abi: abi.wagmiMintExample, + }) + + await expect( + readWagmiMintExample(config, { + functionName: 'balanceOf', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + chainId: chain.mainnet2.id, + }), + ).resolves.toMatchInlineSnapshot('4n') +}) + +test('functionName', async () => { + const readWagmiMintExampleBalanceOf = createReadContract({ + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'balanceOf', + }) + + await expect( + readWagmiMintExampleBalanceOf(config, { + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }), + ).resolves.toMatchInlineSnapshot('4n') +}) diff --git a/wagmi-project/packages/core/src/actions/codegen/createReadContract.ts b/wagmi-project/packages/core/src/actions/codegen/createReadContract.ts new file mode 100644 index 0000000000..f7dbfbed45 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/codegen/createReadContract.ts @@ -0,0 +1,100 @@ +import type { + Abi, + Address, + ContractFunctionArgs, + ContractFunctionName, +} from 'viem' + +import type { Config } from '../../createConfig.js' +import type { UnionCompute, UnionStrictOmit } from '../../types/utils.js' +import { getAccount } from '../getAccount.js' +import { getChainId } from '../getChainId.js' +import { + type ReadContractParameters, + type ReadContractReturnType, + readContract, +} from '../readContract.js' + +type stateMutability = 'pure' | 'view' + +export type CreateReadContractParameters< + abi extends Abi | readonly unknown[], + address extends Address | Record | undefined = undefined, + functionName extends + | ContractFunctionName + | undefined = undefined, +> = { + abi: abi | Abi | readonly unknown[] + address?: address | Address | Record | undefined + functionName?: + | functionName + | ContractFunctionName + | undefined +} + +export type CreateReadContractReturnType< + abi extends Abi | readonly unknown[], + address extends Address | Record | undefined, + functionName extends ContractFunctionName | undefined, + /// + omittedProperties extends 'abi' | 'address' | 'chainId' | 'functionName' = + | 'abi' + | (address extends undefined ? never : 'address') + | (address extends Record ? 'chainId' : never) + | (functionName extends undefined ? never : 'functionName'), +> = < + config extends Config, + name extends functionName extends ContractFunctionName + ? functionName + : ContractFunctionName, + args extends ContractFunctionArgs, +>( + config: config, + parameters: UnionCompute< + UnionStrictOmit< + ReadContractParameters, + omittedProperties + > + > & + (address extends Record + ? { chainId?: keyof address | undefined } + : unknown), +) => Promise> + +export function createReadContract< + const abi extends Abi | readonly unknown[], + const address extends + | Address + | Record + | undefined = undefined, + functionName extends + | ContractFunctionName + | undefined = undefined, +>( + c: CreateReadContractParameters, +): CreateReadContractReturnType { + if (c.address !== undefined && typeof c.address === 'object') + return (config, parameters) => { + const configChainId = getChainId(config) + const account = getAccount(config) + const chainId = + (parameters as { chainId?: number })?.chainId ?? + account.chainId ?? + configChainId + return readContract(config, { + ...(parameters as any), + ...(c.functionName ? { functionName: c.functionName } : {}), + address: c.address?.[chainId], + abi: c.abi, + }) + } + + return (config, parameters) => { + return readContract(config, { + ...(parameters as any), + ...(c.address ? { address: c.address } : {}), + ...(c.functionName ? { functionName: c.functionName } : {}), + abi: c.abi, + }) + } +} diff --git a/wagmi-project/packages/core/src/actions/codegen/createSimulateContract.test-d.ts b/wagmi-project/packages/core/src/actions/codegen/createSimulateContract.test-d.ts new file mode 100644 index 0000000000..91e5998977 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/codegen/createSimulateContract.test-d.ts @@ -0,0 +1,211 @@ +import { abi, config, mainnet, optimism } from '@wagmi/test' +import { http, type Address } from 'viem' +import { celo } from 'viem/chains' +import { assertType, expectTypeOf, test } from 'vitest' + +import { createConfig } from '../../createConfig.js' +import { createSimulateContract } from './createSimulateContract.js' + +test('default', async () => { + const simulateErc20 = createSimulateContract({ + abi: abi.erc20, + address: '0x', + }) + + const result = await simulateErc20(config, { + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + chainId: 1, + }) + + expectTypeOf(result).toMatchTypeOf<{ + result: boolean + request: { + chainId: 1 + abi: readonly [ + { + readonly name: 'transferFrom' + readonly type: 'function' + readonly stateMutability: 'nonpayable' + readonly inputs: readonly [ + { readonly type: 'address'; readonly name: 'sender' }, + { readonly type: 'address'; readonly name: 'recipient' }, + { readonly type: 'uint256'; readonly name: 'amount' }, + ] + readonly outputs: readonly [{ type: 'bool' }] + }, + ] + functionName: 'transferFrom' + args: readonly [Address, Address, bigint] + } + }>() +}) + +test('multichain address', async () => { + const simulateErc20 = createSimulateContract({ + abi: abi.erc20, + address: { + [mainnet.id]: '0x', + [optimism.id]: '0x', + }, + }) + + const result = await simulateErc20(config, { + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + chainId: optimism.id, + }) + expectTypeOf(result.result).toEqualTypeOf() + + simulateErc20(config, { + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + // @ts-expect-error chain id must match address keys + chainId: 420, + }) + + simulateErc20(config, { + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + // @ts-expect-error address not allowed + address: '0x', + }) +}) + +test('overloads', async () => { + const simulateWriteOverloads = createSimulateContract({ + abi: abi.writeOverloads, + address: '0x', + }) + + const result1 = await simulateWriteOverloads(config, { + functionName: 'foo', + }) + assertType(result1.result) + + const result2 = await simulateWriteOverloads(config, { + functionName: 'foo', + args: [], + }) + assertType(result2.result) + + const result3 = await simulateWriteOverloads(config, { + functionName: 'foo', + args: ['0x'], + }) + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + assertType(result3.result) + + const result4 = await simulateWriteOverloads(config, { + functionName: 'foo', + args: ['0x', '0x'], + }) + assertType< + | { + foo: `0x${string}` + bar: `0x${string}` + } + | undefined + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + >(result4.result) +}) + +test('functionName', async () => { + const simulateErc20 = createSimulateContract({ + abi: abi.erc20, + address: '0x', + functionName: 'transferFrom', + }) + + const result = await simulateErc20(config, { + args: ['0x', '0x', 123n], + chainId: 1, + }) + + expectTypeOf(result).toMatchTypeOf<{ + result: boolean + request: { + chainId: 1 + abi: readonly [ + { + readonly name: 'transferFrom' + readonly type: 'function' + readonly stateMutability: 'nonpayable' + readonly inputs: readonly [ + { readonly type: 'address'; readonly name: 'sender' }, + { readonly type: 'address'; readonly name: 'recipient' }, + { readonly type: 'uint256'; readonly name: 'amount' }, + ] + readonly outputs: readonly [{ type: 'bool' }] + }, + ] + functionName: 'transferFrom' + args: readonly [Address, Address, bigint] + } + }>() +}) + +test('functionName with overloads', async () => { + const simulateWriteOverloads = createSimulateContract({ + abi: abi.writeOverloads, + address: '0x', + functionName: 'foo', + }) + + const result1 = await simulateWriteOverloads(config, {}) + assertType(result1.result) + + const result2 = await simulateWriteOverloads(config, { + args: [], + }) + assertType(result2.result) + + const result3 = await simulateWriteOverloads(config, { + args: ['0x'], + }) + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + assertType(result3.result) + + const result4 = await simulateWriteOverloads(config, { + args: ['0x', '0x'], + }) + assertType< + | { + foo: `0x${string}` + bar: `0x${string}` + } + | undefined + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + >(result4.result) +}) + +test('chain formatters', async () => { + const simulateErc20 = createSimulateContract({ + abi: abi.erc20, + address: '0x', + }) + + const config = createConfig({ + chains: [celo, mainnet], + transports: { [celo.id]: http(), [mainnet.id]: http() }, + }) + + const response = await simulateErc20(config, { + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + }) + if (response.chainId === celo.id) { + expectTypeOf(response.request.feeCurrency).toEqualTypeOf< + `0x${string}` | undefined + >() + } + + const response2 = await simulateErc20(config, { + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + chainId: celo.id, + }) + expectTypeOf(response2.request.feeCurrency).toEqualTypeOf< + `0x${string}` | undefined + >() +}) diff --git a/wagmi-project/packages/core/src/actions/codegen/createSimulateContract.test.ts b/wagmi-project/packages/core/src/actions/codegen/createSimulateContract.test.ts new file mode 100644 index 0000000000..bd37d13770 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/codegen/createSimulateContract.test.ts @@ -0,0 +1,137 @@ +import { abi, address, chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { connect } from '../connect.js' +import { disconnect } from '../disconnect.js' +import { createSimulateContract } from './createSimulateContract.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const simulateWagmiMintExample = createSimulateContract({ + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + }) + + await expect( + simulateWagmiMintExample(config, { + functionName: 'mint', + }), + ).resolves.toMatchInlineSnapshot(` + { + "chainId": 1, + "request": { + "abi": [ + { + "inputs": [], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "account": { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "type": "json-rpc", + }, + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": undefined, + "chainId": undefined, + "dataSuffix": undefined, + "functionName": "mint", + }, + "result": undefined, + } + `) + + await disconnect(config, { connector }) +}) + +test('multichain', async () => { + await connect(config, { connector }) + + const simulateWagmiMintExample = createSimulateContract({ + address: { + [chain.mainnet.id]: address.wagmiMintExample, + [chain.mainnet2.id]: address.wagmiMintExample, + }, + abi: abi.wagmiMintExample, + }) + + await expect( + simulateWagmiMintExample(config, { + functionName: 'mint', + chainId: chain.mainnet2.id, + }), + ).resolves.toMatchInlineSnapshot(` + { + "chainId": 456, + "request": { + "abi": [ + { + "inputs": [], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "account": { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "type": "json-rpc", + }, + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": undefined, + "chainId": 456, + "dataSuffix": undefined, + "functionName": "mint", + }, + "result": undefined, + } + `) + + await disconnect(config, { connector }) +}) + +test('functionName', async () => { + await connect(config, { connector }) + + const simulateWagmiMintExample = createSimulateContract({ + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'mint', + }) + + await expect( + simulateWagmiMintExample(config, {}), + ).resolves.toMatchInlineSnapshot(` + { + "chainId": 1, + "request": { + "abi": [ + { + "inputs": [], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "account": { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "type": "json-rpc", + }, + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": undefined, + "chainId": undefined, + "dataSuffix": undefined, + "functionName": "mint", + }, + "result": undefined, + } + `) + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/core/src/actions/codegen/createSimulateContract.ts b/wagmi-project/packages/core/src/actions/codegen/createSimulateContract.ts new file mode 100644 index 0000000000..016384e245 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/codegen/createSimulateContract.ts @@ -0,0 +1,122 @@ +import type { + Abi, + Account, + Address, + Chain, + ContractFunctionArgs, + ContractFunctionName, + SimulateContractParameters as viem_SimulateContractParameters, +} from 'viem' + +import type { Config } from '../../createConfig.js' +import type { SelectChains } from '../../types/chain.js' +import type { + ChainIdParameter, + ConnectorParameter, +} from '../../types/properties.js' +import type { UnionCompute, UnionStrictOmit } from '../../types/utils.js' +import { getAccount } from '../getAccount.js' +import { getChainId } from '../getChainId.js' +import { + type SimulateContractReturnType, + simulateContract, +} from '../simulateContract.js' + +type stateMutability = 'nonpayable' | 'payable' + +export type CreateSimulateContractParameters< + abi extends Abi | readonly unknown[], + address extends Address | Record | undefined = undefined, + functionName extends + | ContractFunctionName + | undefined = undefined, +> = { + abi: abi | Abi | readonly unknown[] + address?: address | Address | Record | undefined + functionName?: + | functionName + | ContractFunctionName + | undefined +} + +export type CreateSimulateContractReturnType< + abi extends Abi | readonly unknown[], + address extends Address | Record | undefined, + functionName extends ContractFunctionName | undefined, +> = < + config extends Config, + name extends functionName extends ContractFunctionName + ? functionName + : ContractFunctionName, + args extends ContractFunctionArgs, + chainId extends config['chains'][number]['id'] | undefined = undefined, + /// + chains extends readonly Chain[] = SelectChains, +>( + config: config, + parameters: { + [key in keyof chains]: UnionCompute< + UnionStrictOmit< + viem_SimulateContractParameters< + abi, + name, + args, + chains[key], + chains[key], + Account | Address + >, + | 'abi' + | 'chain' + | (address extends undefined ? never : 'address') + | (functionName extends undefined ? never : 'functionName') + > + > & + ChainIdParameter & + ConnectorParameter & { + chainId?: address extends Record + ? + | keyof address + | (chainId extends keyof address ? chainId : never) + | undefined + : chainId | number | undefined + } + }[number], +) => Promise> + +export function createSimulateContract< + const abi extends Abi | readonly unknown[], + const address extends + | Address + | Record + | undefined = undefined, + functionName extends + | ContractFunctionName + | undefined = undefined, +>( + c: CreateSimulateContractParameters, +): CreateSimulateContractReturnType { + if (c.address !== undefined && typeof c.address === 'object') + return (config, parameters) => { + const configChainId = getChainId(config) + const account = getAccount(config) + const chainId = + (parameters as { chainId?: number })?.chainId ?? + account.chainId ?? + configChainId + return simulateContract(config, { + ...(parameters as any), + ...(c.functionName ? { functionName: c.functionName } : {}), + address: c.address?.[chainId], + abi: c.abi, + }) + } + + return (config, parameters) => { + return simulateContract(config, { + ...(parameters as any), + ...(c.address ? { address: c.address } : {}), + ...(c.functionName ? { functionName: c.functionName } : {}), + abi: c.abi, + }) + } +} diff --git a/wagmi-project/packages/core/src/actions/codegen/createWatchContractEvent.test-d.ts b/wagmi-project/packages/core/src/actions/codegen/createWatchContractEvent.test-d.ts new file mode 100644 index 0000000000..6c0485f39d --- /dev/null +++ b/wagmi-project/packages/core/src/actions/codegen/createWatchContractEvent.test-d.ts @@ -0,0 +1,123 @@ +import { abi, config, mainnet, optimism } from '@wagmi/test' +import { http, webSocket } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { createConfig } from '../../createConfig.js' +import { createWatchContractEvent } from './createWatchContractEvent.js' + +test('default', () => { + const watchErc20Event = createWatchContractEvent({ + abi: abi.erc20, + }) + + watchErc20Event(config, { + eventName: 'Transfer', + chainId: 1, + onLogs(logs) { + expectTypeOf(logs[0]!.eventName).toEqualTypeOf<'Transfer'>() + expectTypeOf(logs[0]!.args).toEqualTypeOf<{ + from?: `0x${string}` | undefined + to?: `0x${string}` | undefined + value?: bigint | undefined + }>() + }, + }) +}) + +test('multichain address', () => { + const watchErc20Event = createWatchContractEvent({ + abi: abi.erc20, + address: { + [mainnet.id]: '0x', + [optimism.id]: '0x', + }, + }) + + watchErc20Event(config, { + eventName: 'Transfer', + chainId: mainnet.id, + // ^? + onLogs() {}, + }) + + watchErc20Event(config, { + eventName: 'Transfer', + // @ts-expect-error chain id must match address keys + chainId: 420, + onLogs() {}, + }) + + watchErc20Event(config, { + eventName: 'Transfer', + // @ts-expect-error chain id must match address keys + address: '0x', + onLogs() {}, + }) +}) + +test('differing transports', () => { + const watchErc20Event = createWatchContractEvent({ + abi: abi.erc20, + }) + + const config = createConfig({ + chains: [mainnet, optimism], + transports: { + [mainnet.id]: http(), + [optimism.id]: webSocket(), + }, + }) + + watchErc20Event(config, { + poll: false, + address: '0x', + onLogs() {}, + }) + + watchErc20Event(config, { + chainId: mainnet.id, + poll: true, + address: '0x', + onLogs() {}, + }) + watchErc20Event(config, { + config, + chainId: mainnet.id, + // @ts-expect-error poll required since http transport + poll: false, + address: '0x', + onLogs() {}, + }) + + watchErc20Event(config, { + chainId: optimism.id, + poll: true, + address: '0x', + onLogs() {}, + }) + watchErc20Event(config, { + chainId: optimism.id, + poll: false, + address: '0x', + onLogs() {}, + }) +}) + +test('eventName', () => { + const watchErc20Event = createWatchContractEvent({ + abi: abi.erc20, + eventName: 'Transfer', + }) + + watchErc20Event(config, { + chainId: 1, + onLogs(logs) { + expectTypeOf(logs[0]!.eventName).toEqualTypeOf<'Transfer'>() + expectTypeOf(logs[0]!.args).toEqualTypeOf<{ + from?: `0x${string}` | undefined + to?: `0x${string}` | undefined + value?: bigint | undefined + }>() + }, + }) +}) diff --git a/wagmi-project/packages/core/src/actions/codegen/createWatchContractEvent.test.ts b/wagmi-project/packages/core/src/actions/codegen/createWatchContractEvent.test.ts new file mode 100644 index 0000000000..19ba09b2a2 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/codegen/createWatchContractEvent.test.ts @@ -0,0 +1,41 @@ +import { abi, address, chain, config } from '@wagmi/test' +import type { WatchEventOnLogsParameter } from 'viem' +import { test } from 'vitest' + +import { createWatchContractEvent } from './createWatchContractEvent.js' + +test('default', async () => { + const watchErc20Event = createWatchContractEvent({ + address: address.usdc, + abi: abi.wagmiMintExample, + }) + + let logs: WatchEventOnLogsParameter = [] + const unwatch = watchErc20Event(config, { + eventName: 'Transfer', + onLogs(next) { + logs = logs.concat(next) + }, + }) + unwatch() +}) + +test('multichain', async () => { + const watchErc20Event = createWatchContractEvent({ + address: { + [chain.mainnet.id]: address.usdc, + [chain.mainnet2.id]: address.usdc, + }, + abi: abi.wagmiMintExample, + }) + + let logs: WatchEventOnLogsParameter = [] + const unwatch = watchErc20Event(config, { + eventName: 'Transfer', + chainId: chain.mainnet2.id, + onLogs(next) { + logs = logs.concat(next) + }, + }) + unwatch() +}) diff --git a/wagmi-project/packages/core/src/actions/codegen/createWatchContractEvent.ts b/wagmi-project/packages/core/src/actions/codegen/createWatchContractEvent.ts new file mode 100644 index 0000000000..2817efc704 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/codegen/createWatchContractEvent.ts @@ -0,0 +1,88 @@ +import type { Abi, Address, ContractEventName } from 'viem' + +import type { Config } from '../../createConfig.js' +import type { UnionCompute, UnionStrictOmit } from '../../types/utils.js' +import { getAccount } from '../getAccount.js' +import { getChainId } from '../getChainId.js' +import { + type WatchContractEventParameters, + type WatchContractEventReturnType, + watchContractEvent, +} from '../watchContractEvent.js' + +export type CreateWatchContractEventParameters< + abi extends Abi | readonly unknown[], + address extends Address | Record | undefined = undefined, + eventName extends ContractEventName | undefined = undefined, +> = { + abi: abi | Abi | readonly unknown[] + address?: address | Address | Record | undefined + eventName?: eventName | ContractEventName | undefined +} + +export type CreateWatchContractEventReturnType< + abi extends Abi | readonly unknown[], + address extends Address | Record | undefined, + eventName extends ContractEventName | undefined, + /// + omittedProperties extends 'abi' | 'address' | 'chainId' | 'eventName' = + | 'abi' + | (address extends undefined ? never : 'address') + | (address extends Record ? 'chainId' : never) + | (eventName extends undefined ? never : 'eventName'), +> = < + config extends Config, + name extends eventName extends ContractEventName + ? eventName + : ContractEventName, + strict extends boolean | undefined = undefined, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +>( + config: config, + parameters: UnionCompute< + UnionStrictOmit< + WatchContractEventParameters, + omittedProperties + > + > & + (address extends Record + ? { chainId?: keyof address | undefined } + : unknown), +) => WatchContractEventReturnType + +export function createWatchContractEvent< + const abi extends Abi | readonly unknown[], + const address extends + | Address + | Record + | undefined = undefined, + eventName extends ContractEventName | undefined = undefined, +>( + c: CreateWatchContractEventParameters, +): CreateWatchContractEventReturnType { + if (c.address !== undefined && typeof c.address === 'object') + return (config, parameters) => { + const configChainId = getChainId(config) + const account = getAccount(config) + const chainId = + (parameters as { chainId?: number })?.chainId ?? + account.chainId ?? + configChainId + return watchContractEvent(config, { + ...(parameters as any), + ...(c.eventName ? { eventName: c.eventName } : {}), + address: c.address?.[chainId], + abi: c.abi, + }) + } + + return (config, parameters) => { + return watchContractEvent(config, { + ...(parameters as any), + ...(c.address ? { address: c.address } : {}), + ...(c.eventName ? { eventName: c.eventName } : {}), + abi: c.abi, + }) + } +} diff --git a/wagmi-project/packages/core/src/actions/codegen/createWriteContract.test-d.ts b/wagmi-project/packages/core/src/actions/codegen/createWriteContract.test-d.ts new file mode 100644 index 0000000000..9c69ede5bf --- /dev/null +++ b/wagmi-project/packages/core/src/actions/codegen/createWriteContract.test-d.ts @@ -0,0 +1,129 @@ +import { abi, config, mainnet, optimism } from '@wagmi/test' +import { test } from 'vitest' + +import { simulateContract } from '../simulateContract.js' +import { createWriteContract } from './createWriteContract.js' + +test('default', () => { + const writeErc20 = createWriteContract({ + abi: abi.erc20, + address: '0x', + }) + + writeErc20(config, { + functionName: 'transfer', + args: ['0x', 123n], + }) +}) + +test('multichain address', () => { + const writeErc20 = createWriteContract({ + abi: abi.erc20, + address: { + [mainnet.id]: '0x', + [optimism.id]: '0x', + }, + }) + + writeErc20(config, { + functionName: 'transfer', + args: ['0x', 123n], + chainId: mainnet.id, + // ^? + }) + + writeErc20(config, { + functionName: 'transfer', + args: ['0x', 123n], + // @ts-expect-error chain id must match address keys + chainId: 420, + }) + + writeErc20(config, { + // @ts-expect-error address not allowed + address: '0x', + functionName: 'transfer', + args: ['0x', 123n], + }) +}) + +test('overloads', () => { + const writeOverloads = createWriteContract({ + abi: abi.writeOverloads, + address: { + [mainnet.id]: '0x', + [optimism.id]: '0x', + }, + }) + + writeOverloads(config, { + functionName: 'foo', + args: [], + }) + + writeOverloads(config, { + functionName: 'foo', + args: ['0x'], + }) + + writeOverloads(config, { + functionName: 'foo', + args: ['0x', '0x'], + }) +}) + +test('useSimulateContract', async () => { + const writeErc20 = createWriteContract({ + abi: abi.erc20, + address: { + [mainnet.id]: '0x', + [optimism.id]: '0x', + }, + }) + + const { request } = await simulateContract(config, { + account: '0x', + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + chainId: 1, + }) + + writeErc20(config, request) +}) + +test('functionName', () => { + const writeErc20 = createWriteContract({ + abi: abi.erc20, + address: '0x', + functionName: 'transfer', + }) + + writeErc20(config, { + args: ['0x', 123n], + }) +}) + +test('functionName with overloads', () => { + const writeOverloads = createWriteContract({ + abi: abi.writeOverloads, + address: { + [mainnet.id]: '0x', + [optimism.id]: '0x', + }, + functionName: 'foo', + }) + + writeOverloads(config, { + args: [], + }) + + writeOverloads(config, { + args: ['0x'], + }) + + writeOverloads(config, { + args: ['0x', '0x'], + }) +}) diff --git a/wagmi-project/packages/core/src/actions/codegen/createWriteContract.test.ts b/wagmi-project/packages/core/src/actions/codegen/createWriteContract.test.ts new file mode 100644 index 0000000000..04511d13ab --- /dev/null +++ b/wagmi-project/packages/core/src/actions/codegen/createWriteContract.test.ts @@ -0,0 +1,11 @@ +import { abi } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { createWriteContract } from './createWriteContract.js' + +test('default', () => { + const writeErc20 = createWriteContract({ + abi: abi.erc20, + }) + expect(writeErc20).toBeDefined() +}) diff --git a/wagmi-project/packages/core/src/actions/codegen/createWriteContract.ts b/wagmi-project/packages/core/src/actions/codegen/createWriteContract.ts new file mode 100644 index 0000000000..6c1d891a3f --- /dev/null +++ b/wagmi-project/packages/core/src/actions/codegen/createWriteContract.ts @@ -0,0 +1,145 @@ +import type { + Abi, + Account, + Address, + Chain, + ContractFunctionArgs, + ContractFunctionName, + WriteContractParameters as viem_WriteContractParameters, +} from 'viem' + +import type { Config } from '../../createConfig.js' +import type { SelectChains } from '../../types/chain.js' +import type { + ChainIdParameter, + ConnectorParameter, +} from '../../types/properties.js' +import type { + Compute, + UnionCompute, + UnionStrictOmit, +} from '../../types/utils.js' +import { getAccount } from '../getAccount.js' +import { getChainId } from '../getChainId.js' +import { + type WriteContractReturnType, + writeContract, +} from '../writeContract.js' + +type stateMutability = 'nonpayable' | 'payable' + +export type CreateWriteContractParameters< + abi extends Abi | readonly unknown[], + address extends Address | Record | undefined = undefined, + functionName extends + | ContractFunctionName + | undefined = undefined, +> = { + abi: abi | Abi | readonly unknown[] + address?: address | Address | Record | undefined + functionName?: + | functionName + | ContractFunctionName + | undefined +} + +export type CreateWriteContractReturnType< + abi extends Abi | readonly unknown[], + address extends Address | Record | undefined, + functionName extends ContractFunctionName | undefined, +> = < + config extends Config, + name extends functionName extends ContractFunctionName + ? functionName + : ContractFunctionName, + args extends ContractFunctionArgs, + chainId extends config['chains'][number]['id'], + /// + allFunctionNames = ContractFunctionName, + chains extends readonly Chain[] = SelectChains, + omittedProperties extends 'abi' | 'address' | 'functionName' = + | 'abi' + | (address extends undefined ? never : 'address') + | (functionName extends undefined ? never : 'functionName'), +>( + config: config, + parameters: UnionCompute< + { + [key in keyof chains]: UnionStrictOmit< + viem_WriteContractParameters< + abi, + name, + args, + chains[key], + Account, + chains[key], + allFunctionNames + >, + omittedProperties | 'chain' + > + }[number] & + (address extends Record + ? { + chainId?: + | keyof address + | (chainId extends keyof address ? chainId : never) + | undefined + } + : Compute>) & + ConnectorParameter & { + /** @deprecated */ + __mode?: 'prepared' + } + >, +) => Promise + +export function createWriteContract< + const abi extends Abi | readonly unknown[], + const address extends + | Address + | Record + | undefined = undefined, + functionName extends + | ContractFunctionName + | undefined = undefined, +>( + c: CreateWriteContractParameters, +): CreateWriteContractReturnType { + if (c.address !== undefined && typeof c.address === 'object') + return (config, parameters) => { + const configChainId = getChainId(config) + const account = getAccount(config) + + let chainId: number | undefined + if (parameters.chainId) chainId = parameters.chainId + else if ( + (parameters as unknown as { account: Address | Account | undefined }) + .account && + (parameters as unknown as { account: Address | Account | undefined }) + .account === account.address + ) + chainId = account.chainId + else if ( + (parameters as unknown as { account: Address | Account | undefined }) + .account === undefined + ) + chainId = account.chainId + else chainId = configChainId + + return writeContract(config, { + ...(parameters as any), + ...(c.functionName ? { functionName: c.functionName } : {}), + address: chainId ? c.address?.[chainId] : undefined, + abi: c.abi, + }) + } + + return (config, parameters) => { + return writeContract(config, { + ...(parameters as any), + ...(c.address ? { address: c.address } : {}), + ...(c.functionName ? { functionName: c.functionName } : {}), + abi: c.abi, + }) + } +} diff --git a/wagmi-project/packages/core/src/actions/connect.test-d.ts b/wagmi-project/packages/core/src/actions/connect.test-d.ts new file mode 100644 index 0000000000..ad790b1209 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/connect.test-d.ts @@ -0,0 +1,48 @@ +import { accounts } from '@wagmi/test' +import { http } from 'viem' +import { mainnet } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import type { CreateConnectorFn } from '../connectors/createConnector.js' +import { mock } from '../connectors/mock.js' +import { type Connector, createConfig } from '../createConfig.js' +import { connect } from './connect.js' + +const config = createConfig({ + chains: [mainnet], + transports: { [mainnet.id]: http() }, +}) + +test('parameters: connector (ConnectorFn)', () => { + const connectorFn = mock({ accounts }) + + connect(config, { + connector: connectorFn, + foo: 'bar', + }) + expectTypeOf< + typeof connectorFn extends CreateConnectorFn ? true : false + >().toEqualTypeOf() + + type Result = NonNullable< + Parameters>[1] + > + expectTypeOf().toEqualTypeOf() +}) + +test('parameters: connector (Connector)', () => { + const connector = config._internal.connectors.setup(mock({ accounts })) + + connect(config, { + connector, + foo: 'bar', + }) + expectTypeOf< + typeof connector extends Connector ? true : false + >().toEqualTypeOf() + + type Result = NonNullable< + Parameters>[1] + > + expectTypeOf().toEqualTypeOf() +}) diff --git a/wagmi-project/packages/core/src/actions/connect.test.ts b/wagmi-project/packages/core/src/actions/connect.test.ts new file mode 100644 index 0000000000..eece8c3a4d --- /dev/null +++ b/wagmi-project/packages/core/src/actions/connect.test.ts @@ -0,0 +1,71 @@ +import { accounts, chain, config } from '@wagmi/test' +import { beforeEach, expect, test } from 'vitest' + +import { mock } from '../connectors/mock.js' +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' + +const connector = config._internal.connectors.setup(mock({ accounts })) + +beforeEach(async () => { + if (config.state.current === connector.uid) + await disconnect(config, { connector }) +}) + +test('default', async () => { + await expect(connect(config, { connector })).resolves.toMatchObject( + expect.objectContaining({ + accounts: expect.any(Array), + chainId: expect.any(Number), + }), + ) +}) + +test('parameters: chainId', async () => { + const chainId = chain.mainnet2.id + await expect(connect(config, { connector, chainId })).resolves.toMatchObject( + expect.objectContaining({ + accounts: expect.any(Array), + chainId, + }), + ) +}) + +test('parameters: connector', async () => { + const connector_ = config._internal.connectors.setup(mock({ accounts })) + await expect( + connect(config, { connector: connector_ }), + ).resolves.toMatchObject( + expect.objectContaining({ + accounts: expect.any(Array), + chainId: expect.any(Number), + }), + ) + await disconnect(config, { connector: connector_ }) +}) + +test('behavior: user rejected request', async () => { + const connector_ = config._internal.connectors.setup( + mock({ + accounts, + features: { connectError: true }, + }), + ) + await expect( + connect(config, { connector: connector_ }), + ).rejects.toMatchInlineSnapshot(` + [UserRejectedRequestError: User rejected the request. + + Details: Failed to connect. + Version: viem@2.29.2] + `) +}) + +test('behavior: already connected', async () => { + await connect(config, { connector }) + await expect(connect(config, { connector })).rejects.toMatchInlineSnapshot(` + [ConnectorAlreadyConnectedError: Connector already connected. + + Version: @wagmi/core@x.y.z] + `) +}) diff --git a/wagmi-project/packages/core/src/actions/connect.ts b/wagmi-project/packages/core/src/actions/connect.ts new file mode 100644 index 0000000000..f69809e504 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/connect.ts @@ -0,0 +1,110 @@ +import type { + Address, + ResourceUnavailableRpcErrorType, + UserRejectedRequestErrorType, +} from 'viem' + +import type { CreateConnectorFn } from '../connectors/createConnector.js' +import type { Config, Connector } from '../createConfig.js' +import type { BaseErrorType, ErrorType } from '../errors/base.js' +import { + ConnectorAlreadyConnectedError, + type ConnectorAlreadyConnectedErrorType, +} from '../errors/config.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute } from '../types/utils.js' + +export type ConnectParameters< + config extends Config = Config, + connector extends Connector | CreateConnectorFn = + | Connector + | CreateConnectorFn, + /// + parameters extends unknown | undefined = + | (connector extends CreateConnectorFn + ? Omit< + NonNullable['connect']>[0]>, + 'isReconnecting' + > + : never) + | (connector extends Connector + ? Omit< + NonNullable[0]>, + 'isReconnecting' + > + : never), +> = Compute< + ChainIdParameter & { + connector: connector | CreateConnectorFn + } +> & + parameters + +export type ConnectReturnType = { + accounts: readonly [Address, ...Address[]] + chainId: + | config['chains'][number]['id'] + | (number extends config['chains'][number]['id'] ? number : number & {}) +} + +export type ConnectErrorType = + | ConnectorAlreadyConnectedErrorType + // connector.connect() + | UserRejectedRequestErrorType + | ResourceUnavailableRpcErrorType + // base + | BaseErrorType + | ErrorType + +/** https://wagmi.sh/core/api/actions/connect */ +export async function connect< + config extends Config, + connector extends Connector | CreateConnectorFn, +>( + config: config, + parameters: ConnectParameters, +): Promise> { + // "Register" connector if not already created + let connector: Connector + if (typeof parameters.connector === 'function') { + connector = config._internal.connectors.setup(parameters.connector) + } else connector = parameters.connector + + // Check if connector is already connected + if (connector.uid === config.state.current) + throw new ConnectorAlreadyConnectedError() + + try { + config.setState((x) => ({ ...x, status: 'connecting' })) + connector.emitter.emit('message', { type: 'connecting' }) + + const { connector: _, ...rest } = parameters + const data = await connector.connect(rest) + const accounts = data.accounts as readonly [Address, ...Address[]] + + connector.emitter.off('connect', config._internal.events.connect) + connector.emitter.on('change', config._internal.events.change) + connector.emitter.on('disconnect', config._internal.events.disconnect) + + await config.storage?.setItem('recentConnectorId', connector.id) + config.setState((x) => ({ + ...x, + connections: new Map(x.connections).set(connector.uid, { + accounts, + chainId: data.chainId, + connector: connector, + }), + current: connector.uid, + status: 'connected', + })) + + return { accounts, chainId: data.chainId } + } catch (error) { + config.setState((x) => ({ + ...x, + // Keep existing connector connected in case of error + status: x.current ? 'connected' : 'disconnected', + })) + throw error + } +} diff --git a/wagmi-project/packages/core/src/actions/deployContract.test-d.ts b/wagmi-project/packages/core/src/actions/deployContract.test-d.ts new file mode 100644 index 0000000000..b7a6a897d3 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/deployContract.test-d.ts @@ -0,0 +1,71 @@ +import { abi, bytecode, config } from '@wagmi/test' +import { http } from 'viem' +import { celo, mainnet } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { createConfig } from '../createConfig.js' +import { + type DeployContractParameters, + deployContract, +} from './deployContract.js' + +test('default', async () => { + await deployContract(config, { + abi: abi.bayc, + bytecode: bytecode.bayc, + args: ['Bored Ape Wagmi Club', 'BAYC', 69420n, 0n], + chainId: mainnet.id, + }) +}) + +test('chain formatters', () => { + const config = createConfig({ + chains: [mainnet, celo], + transports: { [celo.id]: http(), [mainnet.id]: http() }, + }) + + type Result = DeployContractParameters + expectTypeOf().toMatchTypeOf<{ + chainId?: typeof celo.id | typeof mainnet.id | undefined + feeCurrency?: `0x${string}` | undefined + }>() + deployContract(config, { + abi: abi.bayc, + bytecode: bytecode.bayc, + args: ['Bored Ape Wagmi Club', 'BAYC', 69420n, 0n], + feeCurrency: '0x', + }) + + type Result2 = DeployContractParameters< + typeof abi.bayc, + typeof config, + typeof celo.id + > + expectTypeOf().toMatchTypeOf<{ + feeCurrency?: `0x${string}` | undefined + }>() + deployContract(config, { + chainId: celo.id, + abi: abi.bayc, + bytecode: bytecode.bayc, + args: ['Bored Ape Wagmi Club', 'BAYC', 69420n, 0n], + feeCurrency: '0x', + }) + + type Result3 = DeployContractParameters< + typeof abi.bayc, + typeof config, + typeof mainnet.id + > + expectTypeOf().not.toMatchTypeOf<{ + feeCurrency?: `0x${string}` | undefined + }>() + deployContract(config, { + chainId: mainnet.id, + abi: abi.bayc, + bytecode: bytecode.bayc, + args: ['Bored Ape Wagmi Club', 'BAYC', 69420n, 0n], + // @ts-expect-error + feeCurrency: '0x', + }) +}) diff --git a/wagmi-project/packages/core/src/actions/deployContract.test.ts b/wagmi-project/packages/core/src/actions/deployContract.test.ts new file mode 100644 index 0000000000..bebf42342e --- /dev/null +++ b/wagmi-project/packages/core/src/actions/deployContract.test.ts @@ -0,0 +1,67 @@ +import { + abi, + bytecode, + config, + testClient, + transactionHashRegex, +} from '@wagmi/test' +import { parseEther } from 'viem' +import { expect, test } from 'vitest' + +import { connect } from './connect.js' +import { deployContract } from './deployContract.js' +import { disconnect } from './disconnect.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + await expect( + deployContract(config, { + abi: abi.bayc, + bytecode: bytecode.bayc, + args: ['Bored Ape Wagmi Club', 'BAYC', 69420n, 0n], + }), + ).resolves.toMatch(transactionHashRegex) + await disconnect(config, { connector }) +}) + +test('behavior: no funds', async () => { + const data = await connect(config, { connector }) + const connectedAddress = data.accounts[0] + + await testClient.mainnet.setBalance({ + address: connectedAddress, + value: parseEther('0'), + }) + + await expect( + deployContract(config, { + chainId: testClient.mainnet.chain.id, + abi: abi.bayc, + bytecode: bytecode.bayc, + args: ['Bored Ape Wagmi Club', 'BAYC', 69420n, 0n], + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [TransactionExecutionError: The total cost (gas * gas fee + value) of executing this transaction exceeds the balance of the account. + + This error could arise when the account does not have enough funds to: + - pay for the total gas fee, + - pay for the value to send. + + The cost of the transaction is calculated as \`gas * gas fee + value\`, where: + - \`gas\` is the amount of gas needed for transaction to execute, + - \`gas fee\` is the gas fee, + - \`value\` is the amount of ether to send to the recipient. + + Request Arguments: + chain: undefined (id: 1) + from: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 + data: 0x608060405260405180602001604052806000815250600b90805190602001906200002b92919062000484565b506000600f60006101000a81548160ff0219169083151502179055503480156200005457600080fd5b50604051620046d0380380620046d0833981810160405260808110156200007a57600080fd5b81019080805160405193929190846401000000008211156200009b57600080fd5b83820191506020820185811115620000b257600080fd5b8251866001820283011164010000000082111715620000d057600080fd5b8083526020830192505050908051906020019080838360005b8381101562000106578082015181840152602081019050620000e9565b50505050905090810190601f168015620001345780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200015857600080fd5b838201915060208201858111156200016f57600080fd5b82518660018202830111640100000000821117156200018d57600080fd5b8083526020830192505050908051906020019080838360005b83811015620001c3578082015181840152602081019050620001a6565b50505050905090810190601f168015620001f15780820380516001836020036101000a031916815260200191505b5060405260200180519060200190929190805190602001909291905050508383620002296301ffc9a760e01b6200037360201b60201c565b81600690805190602001906200024192919062000484565b5080600790805190602001906200025a92919062000484565b50620002736380ac58cd60e01b6200037360201b60201c565b6200028b635b5e139f60e01b6200037360201b60201c565b620002a363780e9d6360e01b6200037360201b60201c565b50506000620002b76200047c60201b60201c565b905080600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35081600e81905550620bdd808101601081905550505050506200052a565b63ffffffff60e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141562000410576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f4552433136353a20696e76616c696420696e746572666163652069640000000081525060200191505060405180910390fd5b6001600080837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600033905090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620004c757805160ff1916838001178555620004f8565b82800160010185558215620004f8579182015b82811115620004f7578251825591602001919060010190620004da565b5b5090506200050791906200050b565b5090565b5b80821115620005265760008160009055506001016200050c565b5090565b614196806200053a6000396000f3fe60806040526004361061021a5760003560e01c80636c0360eb11610123578063b0f67427116100ab578063e36d64981161006f578063e36d649814610ddf578063e985e9c514610e0a578063e986655014610e91578063eb8d244414610ea8578063f2fde38b14610ed55761021a565b8063b0f6742714610bac578063b88d4fde14610bc3578063bb8a16bd14610cd5578063c87b56dd14610d00578063cb774d4714610db45761021a565b80637d17fcbe116100f25780637d17fcbe14610a395780638da5cb5b14610a5057806395d89b4114610a91578063a22cb46514610b21578063a723533e14610b7e5761021a565b80636c0360eb1461090257806370a0823114610992578063715018a6146109f75780637a3f451e14610a0e5761021a565b80632f745c59116101a65780634f6ccce7116101755780634f6ccce7146106cb57806355f804b31461071a578063571dff3b146107e2578063607e20e31461080d5780636352211e1461089d5761021a565b80632f745c59146105b357806334918dfd146106225780633ccfd60b1461063957806342842e0e146106505761021a565b8063095ea7b3116101ed578063095ea7b3146103bf578063109695231461041a57806318160ddd146104e257806318e20a381461050d57806323b872dd146105385761021a565b8063018a2c371461021f57806301ffc9a71461025a57806306fdde03146102ca578063081812fc1461035a575b600080fd5b34801561022b57600080fd5b506102586004803603602081101561024257600080fd5b8101908080359060200190929190505050610f26565b005b34801561026657600080fd5b506102b26004803603602081101561027d57600080fd5b8101908080357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19169060200190929190505050610fdf565b60405180821515815260200191505060405180910390f35b3480156102d657600080fd5b506102df611046565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561031f578082015181840152602081019050610304565b50505050905090810190601f16801561034c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561036657600080fd5b506103936004803603602081101561037d57600080fd5b81019080803590602001909291905050506110e8565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156103cb57600080fd5b50610418600480360360408110156103e257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611183565b005b34801561042657600080fd5b506104e06004803603602081101561043d57600080fd5b810190808035906020019064010000000081111561045a57600080fd5b82018360208201111561046c57600080fd5b8035906020019184600183028401116401000000008311171561048e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506112c7565b005b3480156104ee57600080fd5b506104f7611390565b6040518082815260200191505060405180910390f35b34801561051957600080fd5b506105226113a1565b6040518082815260200191505060405180910390f35b34801561054457600080fd5b506105b16004803603606081101561055b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506113a7565b005b3480156105bf57600080fd5b5061060c600480360360408110156105d657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061141d565b6040518082815260200191505060405180910390f35b34801561062e57600080fd5b50610637611478565b005b34801561064557600080fd5b5061064e611553565b005b34801561065c57600080fd5b506106c96004803603606081101561067357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611651565b005b3480156106d757600080fd5b50610704600480360360208110156106ee57600080fd5b8101908080359060200190929190505050611671565b6040518082815260200191505060405180910390f35b34801561072657600080fd5b506107e06004803603602081101561073d57600080fd5b810190808035906020019064010000000081111561075a57600080fd5b82018360208201111561076c57600080fd5b8035906020019184600183028401116401000000008311171561078e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050611694565b005b3480156107ee57600080fd5b506107f761174f565b6040518082815260200191505060405180910390f35b34801561081957600080fd5b50610822611754565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610862578082015181840152602081019050610847565b50505050905090810190601f16801561088f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156108a957600080fd5b506108d6600480360360208110156108c057600080fd5b81019080803590602001909291905050506117f2565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561090e57600080fd5b50610917611829565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561095757808201518184015260208101905061093c565b50505050905090810190601f1680156109845780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561099e57600080fd5b506109e1600480360360208110156109b557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506118cb565b6040518082815260200191505060405180910390f35b348015610a0357600080fd5b50610a0c6119a0565b005b348015610a1a57600080fd5b50610a23611b10565b6040518082815260200191505060405180910390f35b348015610a4557600080fd5b50610a4e611b1c565b005b348015610a5c57600080fd5b50610a65611c4c565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b348015610a9d57600080fd5b50610aa6611c76565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610ae6578082015181840152602081019050610acb565b50505050905090810190601f168015610b135780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b348015610b2d57600080fd5b50610b7c60048036036040811015610b4457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803515159060200190929190505050611d18565b005b610baa60048036036020811015610b9457600080fd5b8101908080359060200190929190505050611ece565b005b348015610bb857600080fd5b50610bc1612127565b005b348015610bcf57600080fd5b50610cd360048036036080811015610be657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190640100000000811115610c4d57600080fd5b820183602082011115610c5f57600080fd5b80359060200191846001830284011164010000000083111715610c8157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061220b565b005b348015610ce157600080fd5b50610cea612283565b6040518082815260200191505060405180910390f35b348015610d0c57600080fd5b50610d3960048036036020811015610d2357600080fd5b8101908080359060200190929190505050612289565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610d79578082015181840152602081019050610d5e565b50505050905090810190601f168015610da65780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b348015610dc057600080fd5b50610dc961255a565b6040518082815260200191505060405180910390f35b348015610deb57600080fd5b50610df4612560565b6040518082815260200191505060405180910390f35b348015610e1657600080fd5b50610e7960048036036040811015610e2d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612566565b60405180821515815260200191505060405180910390f35b348015610e9d57600080fd5b50610ea66125fa565b005b348015610eb457600080fd5b50610ebd612764565b60405180821515815260200191505060405180910390f35b348015610ee157600080fd5b50610f2460048036036020811015610ef857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612777565b005b610f2e61296c565b73ffffffffffffffffffffffffffffffffffffffff16610f4c611c4c565b73ffffffffffffffffffffffffffffffffffffffff1614610fd5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b8060108190555050565b6000806000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b606060068054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156110de5780601f106110b3576101008083540402835291602001916110de565b820191906000526020600020905b8154815290600101906020018083116110c157829003601f168201915b5050505050905090565b60006110f382612974565b611148576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c81526020018061408b602c913960400191505060405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061118e826117f2565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611215576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602181526020018061410f6021913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1661123461296c565b73ffffffffffffffffffffffffffffffffffffffff16148061126357506112628161125d61296c565b612566565b5b6112b8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526038815260200180613f956038913960400191505060405180910390fd5b6112c28383612991565b505050565b6112cf61296c565b73ffffffffffffffffffffffffffffffffffffffff166112ed611c4c565b73ffffffffffffffffffffffffffffffffffffffff1614611376576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b80600b908051906020019061138c929190613de6565b5050565b600061139c6002612a4a565b905090565b60105481565b6113b86113b261296c565b82612a5f565b61140d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260318152602001806141306031913960400191505060405180910390fd5b611418838383612b53565b505050565b600061147082600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612d9690919063ffffffff16565b905092915050565b61148061296c565b73ffffffffffffffffffffffffffffffffffffffff1661149e611c4c565b73ffffffffffffffffffffffffffffffffffffffff1614611527576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600f60009054906101000a900460ff1615600f60006101000a81548160ff021916908315150217905550565b61155b61296c565b73ffffffffffffffffffffffffffffffffffffffff16611579611c4c565b73ffffffffffffffffffffffffffffffffffffffff1614611602576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60004790503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f1935050505015801561164d573d6000803e3d6000fd5b5050565b61166c8383836040518060200160405280600081525061220b565b505050565b600080611688836002612db090919063ffffffff16565b50905080915050919050565b61169c61296c565b73ffffffffffffffffffffffffffffffffffffffff166116ba611c4c565b73ffffffffffffffffffffffffffffffffffffffff1614611743576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b61174c81612ddc565b50565b601481565b600b8054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156117ea5780601f106117bf576101008083540402835291602001916117ea565b820191906000526020600020905b8154815290600101906020018083116117cd57829003601f168201915b505050505081565b600061182282604051806060016040528060298152602001613ff7602991396002612df69092919063ffffffff16565b9050919050565b606060098054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156118c15780601f10611896576101008083540402835291602001916118c1565b820191906000526020600020905b8154815290600101906020018083116118a457829003601f168201915b5050505050905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611952576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180613fcd602a913960400191505060405180910390fd5b611999600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612e15565b9050919050565b6119a861296c565b73ffffffffffffffffffffffffffffffffffffffff166119c6611c4c565b73ffffffffffffffffffffffffffffffffffffffff1614611a4f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b67011c37937e08000081565b611b2461296c565b73ffffffffffffffffffffffffffffffffffffffff16611b42611c4c565b73ffffffffffffffffffffffffffffffffffffffff1614611bcb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6000600d5414611c43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f5374617274696e6720696e64657820697320616c72656164792073657400000081525060200191505060405180910390fd5b43600c81905550565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060078054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611d0e5780601f10611ce357610100808354040283529160200191611d0e565b820191906000526020600020905b815481529060010190602001808311611cf157829003601f168201915b5050505050905090565b611d2061296c565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611dc1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f4552433732313a20617070726f766520746f2063616c6c65720000000000000081525060200191505060405180910390fd5b8060056000611dce61296c565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611e7b61296c565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b600f60009054906101000a900460ff16611f50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f53616c65206d7573742062652061637469766520746f206d696e74204170650081525060200191505060405180910390fd5b6014811115611faa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180613f746021913960400191505060405180910390fd5b600e54611fc782611fb9611390565b612e2a90919063ffffffff16565b111561201e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260288152602001806140426028913960400191505060405180910390fd5b3461203a8267011c37937e080000612eb290919063ffffffff16565b11156120ae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45746865722076616c75652073656e74206973206e6f7420636f72726563740081525060200191505060405180910390fd5b60005b818110156120ef5760006120c3611390565b9050600e546120d0611390565b10156120e1576120e03382612f38565b5b5080806001019150506120b1565b506000600c541480156121175750600e54612108611390565b148061211657506010544210155b5b156121245743600c819055505b50565b61212f61296c565b73ffffffffffffffffffffffffffffffffffffffff1661214d611c4c565b73ffffffffffffffffffffffffffffffffffffffff16146121d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60006121e0611390565b905060005b601e811015612207576121fa33828401612f38565b80806001019150506121e5565b5050565b61221c61221661296c565b83612a5f565b612271576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260318152602001806141306031913960400191505060405180910390fd5b61227d84848484612f56565b50505050565b600e5481565b606061229482612974565b6122e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f8152602001806140e0602f913960400191505060405180910390fd5b6060600860008481526020019081526020016000208054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156123925780601f1061236757610100808354040283529160200191612392565b820191906000526020600020905b81548152906001019060200180831161237557829003601f168201915b5050505050905060606123a3611829565b90506000815114156123b9578192505050612555565b60008251111561248a5780826040516020018083805190602001908083835b602083106123fb57805182526020820191506020810190506020830392506123d8565b6001836020036101000a03801982511681845116808217855250505050505090500182805190602001908083835b6020831061244c5780518252602082019150602081019050602083039250612429565b6001836020036101000a0380198251168184511680821785525050505050509050019250505060405160208183030381529060405292505050612555565b8061249485612fc8565b6040516020018083805190602001908083835b602083106124ca57805182526020820191506020810190506020830392506124a7565b6001836020036101000a03801982511681845116808217855250505050505090500182805190602001908083835b6020831061251b57805182526020820191506020810190506020830392506124f8565b6001836020036101000a03801982511681845116808217855250505050505090500192505050604051602081830303815290604052925050505b919050565b600d5481565b600c5481565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6000600d5414612672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f5374617274696e6720696e64657820697320616c72656164792073657400000081525060200191505060405180910390fd5b6000600c5414156126eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f5374617274696e6720696e64657820626c6f636b206d7573742062652073657481525060200191505060405180910390fd5b600e54600c544060001c816126fc57fe5b06600d8190555060ff61271a600c544361310f90919063ffffffff16565b111561273a57600e54600143034060001c8161273257fe5b06600d819055505b6000600d5414156127625761275b6001600d54612e2a90919063ffffffff16565b600d819055505b565b600f60009054906101000a900460ff1681565b61277f61296c565b73ffffffffffffffffffffffffffffffffffffffff1661279d611c4c565b73ffffffffffffffffffffffffffffffffffffffff1614612826576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156128ac576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180613ed86026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600033905090565b600061298a82600261319290919063ffffffff16565b9050919050565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16612a04836117f2565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000612a58826000016131ac565b9050919050565b6000612a6a82612974565b612abf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180613f48602c913960400191505060405180910390fd5b6000612aca836117f2565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612b3957508373ffffffffffffffffffffffffffffffffffffffff16612b21846110e8565b73ffffffffffffffffffffffffffffffffffffffff16145b80612b4a5750612b498185612566565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16612b73826117f2565b73ffffffffffffffffffffffffffffffffffffffff1614612bdf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806140b76029913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612c65576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180613efe6024913960400191505060405180910390fd5b612c708383836131bd565b612c7b600082612991565b612ccc81600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206131c290919063ffffffff16565b50612d1e81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206131dc90919063ffffffff16565b50612d35818360026131f69092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6000612da5836000018361322b565b60001c905092915050565b600080600080612dc386600001866132ae565b915091508160001c8160001c9350935050509250929050565b8060099080519060200190612df2929190613de6565b5050565b6000612e09846000018460001b84613347565b60001c90509392505050565b6000612e238260000161343d565b9050919050565b600080828401905083811015612ea8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600080831415612ec55760009050612f32565b6000828402905082848281612ed657fe5b0414612f2d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602181526020018061406a6021913960400191505060405180910390fd5b809150505b92915050565b612f5282826040518060200160405280600081525061344e565b5050565b612f61848484612b53565b612f6d848484846134bf565b612fc2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526032815260200180613ea66032913960400191505060405180910390fd5b50505050565b60606000821415613010576040518060400160405280600181526020017f3000000000000000000000000000000000000000000000000000000000000000815250905061310a565b600082905060005b6000821461303a578080600101915050600a828161303257fe5b049150613018565b60608167ffffffffffffffff8111801561305357600080fd5b506040519080825280601f01601f1916602001820160405280156130865781602001600182028036833780820191505090505b50905060006001830390508593505b6000841461310257600a84816130a757fe5b0660300160f81b828280600190039350815181106130c157fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a84816130fa57fe5b049350613095565b819450505050505b919050565b600082821115613187576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060200191505060405180910390fd5b818303905092915050565b60006131a4836000018360001b6136d8565b905092915050565b600081600001805490509050919050565b505050565b60006131d4836000018360001b6136fb565b905092915050565b60006131ee836000018360001b6137e3565b905092915050565b6000613222846000018460001b8473ffffffffffffffffffffffffffffffffffffffff1660001b613853565b90509392505050565b60008183600001805490501161328c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180613e846022913960400191505060405180910390fd5b82600001828154811061329b57fe5b9060005260206000200154905092915050565b60008082846000018054905011613310576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806140206022913960400191505060405180910390fd5b600084600001848154811061332157fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b6000808460010160008581526020019081526020016000205490506000811415839061340e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156133d35780820151818401526020810190506133b8565b50505050905090810190601f1680156134005780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5084600001600182038154811061342157fe5b9060005260206000209060020201600101549150509392505050565b600081600001805490509050919050565b613458838361392f565b61346560008484846134bf565b6134ba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526032815260200180613ea66032913960400191505060405180910390fd5b505050565b60006134e08473ffffffffffffffffffffffffffffffffffffffff16613b23565b6134ed57600190506136d0565b606061365763150b7a0260e01b61350261296c565b888787604051602401808573ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff16815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561358657808201518184015260208101905061356b565b50505050905090810190601f1680156135b35780820380516001836020036101000a031916815260200191505b5095505050505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051806060016040528060328152602001613ea6603291398773ffffffffffffffffffffffffffffffffffffffff16613b369092919063ffffffff16565b9050600081806020019051602081101561367057600080fd5b8101908080519060200190929190505050905063150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614925050505b949350505050565b600080836001016000848152602001908152602001600020541415905092915050565b600080836001016000848152602001908152602001600020549050600081146137d7576000600182039050600060018660000180549050039050600086600001828154811061374657fe5b906000526020600020015490508087600001848154811061376357fe5b906000526020600020018190555060018301876001016000838152602001908152602001600020819055508660000180548061379b57fe5b600190038181906000526020600020016000905590558660010160008781526020019081526020016000206000905560019450505050506137dd565b60009150505b92915050565b60006137ef8383613b4e565b61384857826000018290806001815401808255809150506001900390600052602060002001600090919091909150558260000180549050836001016000848152602001908152602001600020819055506001905061384d565b600090505b92915050565b60008084600101600085815260200190815260200160002054905060008114156138fa57846000016040518060400160405280868152602001858152509080600181540180825580915050600190039060005260206000209060020201600090919091909150600082015181600001556020820151816001015550508460000180549050856001016000868152602001908152602001600020819055506001915050613928565b8285600001600183038154811061390d57fe5b90600052602060002090600202016001018190555060009150505b9392505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156139d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4552433732313a206d696e7420746f20746865207a65726f206164647265737381525060200191505060405180910390fd5b6139db81612974565b15613a4e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000081525060200191505060405180910390fd5b613a5a600083836131bd565b613aab81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206131dc90919063ffffffff16565b50613ac2818360026131f69092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b600080823b905060008111915050919050565b6060613b458484600085613b71565b90509392505050565b600080836001016000848152602001908152602001600020541415905092915050565b606082471015613bcc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180613f226026913960400191505060405180910390fd5b613bd585613b23565b613c47576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081525060200191505060405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b60208310613c975780518252602082019150602081019050602083039250613c74565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114613cf9576040519150601f19603f3d011682016040523d82523d6000602084013e613cfe565b606091505b5091509150613d0e828286613d1a565b92505050949350505050565b60608315613d2a57829050613ddf565b600083511115613d3d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613da4578082015181840152602081019050613d89565b50505050905090810190601f168015613dd15780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b9392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10613e2757805160ff1916838001178555613e55565b82800160010185558215613e55579182015b82811115613e54578251825591602001919060010190613e39565b5b509050613e629190613e66565b5090565b5b80821115613e7f576000816000905550600101613e67565b509056fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e64734552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734552433732313a207472616e7366657220746f20746865207a65726f2061646472657373416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c4552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e43616e206f6e6c79206d696e7420323020746f6b656e7320617420612074696d654552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c4552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e6473507572636861736520776f756c6420657863656564206d617820737570706c79206f662041706573536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e4552433732314d657461646174613a2055524920717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76616c20746f2063757272656e74206f776e65724552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564a2646970667358221220b0e64d1fa6c4dbeb9c6f54607d7e1996943fe27624a80652f57b53fda084621b64736f6c63430007000033000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000002710000000000000000000000000000000000000000000000000000000006080e6d70000000000000000000000000000000000000000000000000000000000000011426f7265644170655961636874436c756200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044241594300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000010f2c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014426f72656420417065205761676d6920436c756200000000000000000000000000000000000000000000000000000000000000000000000000000000000000044241594300000000000000000000000000000000000000000000000000000000 + + Details: Insufficient funds for gas * price + value + Version: viem@2.29.2] + `) + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/core/src/actions/deployContract.ts b/wagmi-project/packages/core/src/actions/deployContract.ts new file mode 100644 index 0000000000..a688dd7cfd --- /dev/null +++ b/wagmi-project/packages/core/src/actions/deployContract.ts @@ -0,0 +1,87 @@ +import type { Abi, Account, Chain, Client, ContractConstructorArgs } from 'viem' +import { + type DeployContractErrorType as viem_DeployContractErrorType, + type DeployContractParameters as viem_DeployContractParameters, + type DeployContractReturnType as viem_DeployContractReturnType, + deployContract as viem_deployContract, +} from 'viem/actions' +import type { Config } from '../createConfig.js' +import type { BaseErrorType, ErrorType } from '../errors/base.js' +import type { SelectChains } from '../types/chain.js' +import type { + ChainIdParameter, + ConnectorParameter, +} from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' +import { + type GetConnectorClientErrorType, + getConnectorClient, +} from './getConnectorClient.js' + +export type DeployContractParameters< + abi extends Abi | readonly unknown[] = Abi, + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + /// + allArgs = ContractConstructorArgs, + chains extends readonly Chain[] = SelectChains, +> = { + [key in keyof chains]: Compute< + Omit< + viem_DeployContractParameters< + abi, + chains[key], + Account, + chains[key], + allArgs + >, + 'chain' + > & + ChainIdParameter & + ConnectorParameter + > +}[number] + +export type DeployContractReturnType = viem_DeployContractReturnType + +export type DeployContractErrorType = + // getConnectorClient() + | GetConnectorClientErrorType + // base + | BaseErrorType + | ErrorType + // viem + | viem_DeployContractErrorType + +/** https://wagmi.sh/core/api/actions/deployContract */ +export async function deployContract< + config extends Config, + const abi extends Abi | readonly unknown[], + chainId extends config['chains'][number]['id'], +>( + config: config, + parameters: DeployContractParameters, +): Promise { + const { account, chainId, connector, ...rest } = parameters + + let client: Client + if (typeof account === 'object' && account?.type === 'local') + client = config.getClient({ chainId }) + else + client = await getConnectorClient(config, { + account: account ?? undefined, + chainId, + connector, + }) + + const action = getAction(client, viem_deployContract, 'deployContract') + const hash = await action({ + ...(rest as any), + ...(account ? { account } : {}), + chain: chainId ? { id: chainId } : null, + }) + + return hash +} diff --git a/wagmi-project/packages/core/src/actions/disconnect.test.ts b/wagmi-project/packages/core/src/actions/disconnect.test.ts new file mode 100644 index 0000000000..03d63db7de --- /dev/null +++ b/wagmi-project/packages/core/src/actions/disconnect.test.ts @@ -0,0 +1,33 @@ +import { accounts, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { mock } from '../connectors/mock.js' +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' + +const connector = config._internal.connectors.setup(mock({ accounts })) + +test('default', async () => { + await connect(config, { connector }) + expect(config.state.status).toEqual('connected') + await disconnect(config) + expect(config.state.status).toEqual('disconnected') +}) + +test('parameters: connector', async () => { + await connect(config, { connector }) + expect(config.state.status).toEqual('connected') + await disconnect(config, { connector }) + expect(config.state.status).toEqual('disconnected') +}) + +test('behavior: uses next connector on disconnect', async () => { + const connector_ = config._internal.connectors.setup(mock({ accounts })) + await connect(config, { connector: connector_ }) + await connect(config, { connector }) + + expect(config.state.status).toEqual('connected') + await disconnect(config, { connector }) + expect(config.state.status).toEqual('connected') + await disconnect(config, { connector: connector_ }) +}) diff --git a/wagmi-project/packages/core/src/actions/disconnect.ts b/wagmi-project/packages/core/src/actions/disconnect.ts new file mode 100644 index 0000000000..6efb4c790c --- /dev/null +++ b/wagmi-project/packages/core/src/actions/disconnect.ts @@ -0,0 +1,71 @@ +import type { Config, Connection, Connector } from '../createConfig.js' +import type { BaseErrorType, ErrorType } from '../errors/base.js' +import type { + ConnectorNotConnectedErrorType, + ConnectorNotFoundErrorType, +} from '../errors/config.js' +import type { ConnectorParameter } from '../types/properties.js' + +export type DisconnectParameters = ConnectorParameter + +export type DisconnectReturnType = void + +export type DisconnectErrorType = + | ConnectorNotFoundErrorType + | ConnectorNotConnectedErrorType + // base + | BaseErrorType + | ErrorType + +/** https://wagmi.sh/core/api/actions/disconnect */ +export async function disconnect( + config: Config, + parameters: DisconnectParameters = {}, +): Promise { + let connector: Connector | undefined + if (parameters.connector) connector = parameters.connector + else { + const { connections, current } = config.state + const connection = connections.get(current!) + connector = connection?.connector + } + + const connections = config.state.connections + + if (connector) { + await connector.disconnect() + connector.emitter.off('change', config._internal.events.change) + connector.emitter.off('disconnect', config._internal.events.disconnect) + connector.emitter.on('connect', config._internal.events.connect) + + connections.delete(connector.uid) + } + + config.setState((x) => { + // if no connections exist, move to disconnected state + if (connections.size === 0) + return { + ...x, + connections: new Map(), + current: null, + status: 'disconnected', + } + + // switch over to another connection + const nextConnection = connections.values().next().value as Connection + return { + ...x, + connections: new Map(connections), + current: nextConnection.connector.uid, + } + }) + + // Set recent connector if exists + { + const current = config.state.current + if (!current) return + const connector = config.state.connections.get(current)?.connector + if (!connector) return + await config.storage?.setItem('recentConnectorId', connector.id) + } +} diff --git a/wagmi-project/packages/core/src/actions/estimateFeesPerGas.test-d.ts b/wagmi-project/packages/core/src/actions/estimateFeesPerGas.test-d.ts new file mode 100644 index 0000000000..dada2ea311 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/estimateFeesPerGas.test-d.ts @@ -0,0 +1,41 @@ +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' +import { estimateFeesPerGas } from './estimateFeesPerGas.js' + +test('types', async () => { + const default_ = await estimateFeesPerGas(config) + expectTypeOf(default_).toMatchTypeOf<{ + gasPrice?: undefined + maxFeePerGas: bigint + maxPriorityFeePerGas: bigint + formatted: { + gasPrice?: undefined + maxFeePerGas: string + maxPriorityFeePerGas: string + } + }>() + + const legacy = await estimateFeesPerGas(config, { type: 'legacy' }) + expectTypeOf(legacy).toMatchTypeOf<{ + gasPrice: bigint + maxFeePerGas?: undefined + maxPriorityFeePerGas?: undefined + formatted: { + gasPrice: string + maxFeePerGas?: undefined + maxPriorityFeePerGas?: undefined + } + }>() + + const eip1559 = await estimateFeesPerGas(config, { type: 'eip1559' }) + expectTypeOf(eip1559).toMatchTypeOf<{ + gasPrice?: undefined + maxFeePerGas: bigint + maxPriorityFeePerGas: bigint + formatted: { + gasPrice?: undefined + maxFeePerGas: string + maxPriorityFeePerGas: string + } + }>() +}) diff --git a/wagmi-project/packages/core/src/actions/estimateFeesPerGas.test.ts b/wagmi-project/packages/core/src/actions/estimateFeesPerGas.test.ts new file mode 100644 index 0000000000..4c5d668b83 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/estimateFeesPerGas.test.ts @@ -0,0 +1,16 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { estimateFeesPerGas } from './estimateFeesPerGas.js' + +test('default', async () => { + const result = await estimateFeesPerGas(config) + expect(Object.keys(result)).toMatchInlineSnapshot(` + [ + "formatted", + "gasPrice", + "maxFeePerGas", + "maxPriorityFeePerGas", + ] + `) +}) diff --git a/wagmi-project/packages/core/src/actions/estimateFeesPerGas.ts b/wagmi-project/packages/core/src/actions/estimateFeesPerGas.ts new file mode 100644 index 0000000000..66915f010a --- /dev/null +++ b/wagmi-project/packages/core/src/actions/estimateFeesPerGas.ts @@ -0,0 +1,87 @@ +import { + type Chain, + type FeeValuesEIP1559, + type FeeValuesLegacy, + type FeeValuesType, + formatUnits, +} from 'viem' +import { + type EstimateFeesPerGasErrorType as viem_EstimateFeesPerGasErrorType, + type EstimateFeesPerGasParameters as viem_EstimateFeesPerGasParameters, + type EstimateFeesPerGasReturnType as viem_EstimateFeesPerGasReturnType, + estimateFeesPerGas as viem_estimateFeesPerGas, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Unit } from '../types/unit.js' +import type { Compute } from '../types/utils.js' +import type { UnionCompute, UnionLooseOmit } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' +import { getUnit } from '../utils/getUnit.js' + +export type EstimateFeesPerGasParameters< + type extends FeeValuesType = FeeValuesType, + config extends Config = Config, +> = UnionCompute< + UnionLooseOmit< + viem_EstimateFeesPerGasParameters, + 'chain' + > & + ChainIdParameter & { + /** @deprecated */ + formatUnits?: Unit | undefined + } +> + +export type EstimateFeesPerGasReturnType< + type extends FeeValuesType = FeeValuesType, +> = Compute< + viem_EstimateFeesPerGasReturnType & { + /** @deprecated */ + formatted: UnionCompute< + | (type extends 'legacy' ? FeeValuesLegacy : never) + | (type extends 'eip1559' ? FeeValuesEIP1559 : never) + > + } +> + +export type EstimateFeesPerGasErrorType = viem_EstimateFeesPerGasErrorType + +export async function estimateFeesPerGas< + config extends Config, + type extends FeeValuesType = 'eip1559', +>( + config: config, + parameters: EstimateFeesPerGasParameters = {}, +): Promise> { + const { chainId, formatUnits: units = 'gwei', ...rest } = parameters + + const client = config.getClient({ chainId }) + const action = getAction( + client, + viem_estimateFeesPerGas, + 'estimateFeesPerGas', + ) + + const { gasPrice, maxFeePerGas, maxPriorityFeePerGas } = await action({ + ...rest, + chain: client.chain, + }) + + const unit = getUnit(units) + const formatted = { + gasPrice: gasPrice ? formatUnits(gasPrice, unit) : undefined, + maxFeePerGas: maxFeePerGas ? formatUnits(maxFeePerGas, unit) : undefined, + maxPriorityFeePerGas: maxPriorityFeePerGas + ? formatUnits(maxPriorityFeePerGas, unit) + : undefined, + } + + return { + formatted, + gasPrice, + maxFeePerGas, + maxPriorityFeePerGas, + } as EstimateFeesPerGasReturnType +} diff --git a/wagmi-project/packages/core/src/actions/estimateGas.test-d.ts b/wagmi-project/packages/core/src/actions/estimateGas.test-d.ts new file mode 100644 index 0000000000..5fc66c0ec0 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/estimateGas.test-d.ts @@ -0,0 +1,47 @@ +import { http, parseEther } from 'viem' +import { celo, mainnet } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { createConfig } from '../createConfig.js' +import { type EstimateGasParameters, estimateGas } from './estimateGas.js' + +test('chain formatters', () => { + const config = createConfig({ + chains: [mainnet, celo], + transports: { [celo.id]: http(), [mainnet.id]: http() }, + }) + + type Result = EstimateGasParameters + expectTypeOf().toMatchTypeOf<{ + chainId?: typeof celo.id | typeof mainnet.id | undefined + feeCurrency?: `0x${string}` | undefined + }>() + estimateGas(config, { + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + feeCurrency: '0x', + }) + + type Result2 = EstimateGasParameters + expectTypeOf().toMatchTypeOf<{ + feeCurrency?: `0x${string}` | undefined + }>() + estimateGas(config, { + chainId: celo.id, + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + feeCurrency: '0x', + }) + + type Result3 = EstimateGasParameters + expectTypeOf().not.toMatchTypeOf<{ + feeCurrency?: `0x${string}` | undefined + }>() + estimateGas(config, { + chainId: mainnet.id, + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + // @ts-expect-error + feeCurrency: '0x', + }) +}) diff --git a/wagmi-project/packages/core/src/actions/estimateGas.test.ts b/wagmi-project/packages/core/src/actions/estimateGas.test.ts new file mode 100644 index 0000000000..f0154c55fa --- /dev/null +++ b/wagmi-project/packages/core/src/actions/estimateGas.test.ts @@ -0,0 +1,47 @@ +import { accounts, config } from '@wagmi/test' +import { parseEther } from 'viem' +import { expect, test } from 'vitest' + +import { mock } from '../connectors/mock.js' +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { estimateGas } from './estimateGas.js' + +const connector = config._internal.connectors.setup(mock({ accounts })) + +test('parameters: account', async () => { + await expect( + estimateGas(config, { + account: accounts[0], + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }), + ).resolves.toMatchInlineSnapshot('21000n') +}) + +test('parameters: connector', async () => { + await connect(config, { connector }) + + await expect( + estimateGas(config, { + connector, + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }), + ).resolves.toMatchInlineSnapshot('21000n') + + await disconnect(config, { connector }) +}) + +test('behavior: no account and not connected', async () => { + await expect( + estimateGas(config, { + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [ConnectorNotConnectedError: Connector not connected. + + Version: @wagmi/core@x.y.z] + `) +}) diff --git a/wagmi-project/packages/core/src/actions/estimateGas.ts b/wagmi-project/packages/core/src/actions/estimateGas.ts new file mode 100644 index 0000000000..c049fa42f8 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/estimateGas.ts @@ -0,0 +1,73 @@ +import type { Account, Address, Chain } from 'viem' +import { + type EstimateGasErrorType as viem_EstimateGasErrorType, + type EstimateGasParameters as viem_EstimateGasParameters, + type EstimateGasReturnType as viem_EstimateGasReturnType, + estimateGas as viem_estimateGas, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { BaseErrorType, ErrorType } from '../errors/base.js' +import type { SelectChains } from '../types/chain.js' +import type { + ChainIdParameter, + ConnectorParameter, +} from '../types/properties.js' +import type { UnionCompute, UnionLooseOmit } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' +import { + type GetConnectorClientErrorType, + getConnectorClient, +} from './getConnectorClient.js' + +export type EstimateGasParameters< + config extends Config = Config, + chainId extends + | config['chains'][number]['id'] + | undefined = config['chains'][number]['id'], + /// + chains extends readonly Chain[] = SelectChains, +> = { + [key in keyof chains]: UnionCompute< + UnionLooseOmit, 'chain'> & + ChainIdParameter & + ConnectorParameter + > +}[number] + +export type EstimateGasReturnType = viem_EstimateGasReturnType + +export type EstimateGasErrorType = + // getConnectorClient() + | GetConnectorClientErrorType + // base + | BaseErrorType + | ErrorType + // viem + | viem_EstimateGasErrorType + +/** https://wagmi.sh/core/api/actions/estimateGas */ +export async function estimateGas< + config extends Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, +>( + config: config, + parameters: EstimateGasParameters, +): Promise { + const { chainId, connector, ...rest } = parameters + + let account: Address | Account + if (parameters.account) account = parameters.account + else { + const connectorClient = await getConnectorClient(config, { + account: parameters.account, + chainId, + connector, + }) + account = connectorClient.account + } + + const client = config.getClient({ chainId }) + const action = getAction(client, viem_estimateGas, 'estimateGas') + return action({ ...(rest as viem_EstimateGasParameters), account }) +} diff --git a/wagmi-project/packages/core/src/actions/estimateMaxPriorityFeePerGas.test.ts b/wagmi-project/packages/core/src/actions/estimateMaxPriorityFeePerGas.test.ts new file mode 100644 index 0000000000..deb969ebec --- /dev/null +++ b/wagmi-project/packages/core/src/actions/estimateMaxPriorityFeePerGas.test.ts @@ -0,0 +1,16 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { estimateMaxPriorityFeePerGas } from './estimateMaxPriorityFeePerGas.js' + +test('default', async () => { + await expect(estimateMaxPriorityFeePerGas(config)).resolves.toBeDefined() +}) + +test('parameters: chainId', async () => { + await expect( + estimateMaxPriorityFeePerGas(config, { + chainId: chain.mainnet2.id, + }), + ).resolves.toBeDefined() +}) diff --git a/wagmi-project/packages/core/src/actions/estimateMaxPriorityFeePerGas.ts b/wagmi-project/packages/core/src/actions/estimateMaxPriorityFeePerGas.ts new file mode 100644 index 0000000000..06378d84fd --- /dev/null +++ b/wagmi-project/packages/core/src/actions/estimateMaxPriorityFeePerGas.ts @@ -0,0 +1,49 @@ +import type { Chain } from 'viem' +import { + type EstimateMaxPriorityFeePerGasErrorType as viem_EstimateMaxPriorityFeePerGasErrorType, + type EstimateMaxPriorityFeePerGasParameters as viem_EstimateMaxPriorityFeePerGasParameters, + type EstimateMaxPriorityFeePerGasReturnType as viem_EstimateMaxPriorityFeePerGasReturnType, + estimateMaxPriorityFeePerGas as viem_estimateMaxPriorityFeePerGas, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute, UnionLooseOmit } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type EstimateMaxPriorityFeePerGasParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = Compute< + UnionLooseOmit< + viem_EstimateMaxPriorityFeePerGasParameters & + ChainIdParameter, + 'chain' + > +> + +export type EstimateMaxPriorityFeePerGasReturnType = + viem_EstimateMaxPriorityFeePerGasReturnType + +export type EstimateMaxPriorityFeePerGasErrorType = + viem_EstimateMaxPriorityFeePerGasErrorType + +/** https://wagmi.sh/core/api/actions/estimateMaxPriorityFeePerGas */ +export async function estimateMaxPriorityFeePerGas< + config extends Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +>( + config: config, + parameters: EstimateMaxPriorityFeePerGasParameters = {}, +): Promise { + const { chainId } = parameters + const client = config.getClient({ chainId }) + const action = getAction( + client, + viem_estimateMaxPriorityFeePerGas, + 'estimateMaxPriorityFeePerGas', + ) + return action({ chain: client.chain }) +} diff --git a/wagmi-project/packages/core/src/actions/getAccount.test-d.ts b/wagmi-project/packages/core/src/actions/getAccount.test-d.ts new file mode 100644 index 0000000000..728468039b --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getAccount.test-d.ts @@ -0,0 +1,69 @@ +import { config } from '@wagmi/test' +import type { Address } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import type { Connector } from '../createConfig.js' +import { getAccount } from './getAccount.js' + +test('states', () => { + const result = getAccount(config) + + switch (result.status) { + case 'reconnecting': { + expectTypeOf(result).toMatchTypeOf<{ + address: Address | undefined + chain: (typeof config)['chains'][number] | undefined + chainId: number | undefined + connector: Connector | undefined + isConnected: boolean + isConnecting: false + isDisconnected: false + isReconnecting: true + status: 'reconnecting' + }>() + break + } + case 'connecting': { + expectTypeOf(result).toMatchTypeOf<{ + address: Address | undefined + chain: (typeof config)['chains'][number] | undefined + chainId: number | undefined + connector: Connector | undefined + isConnected: false + isReconnecting: false + isConnecting: true + isDisconnected: false + status: 'connecting' + }>() + break + } + case 'connected': { + expectTypeOf(result).toMatchTypeOf<{ + address: Address + chain: (typeof config)['chains'][number] | undefined + chainId: number + connector: Connector + isConnected: true + isConnecting: false + isDisconnected: false + isReconnecting: false + status: 'connected' + }>() + break + } + case 'disconnected': { + expectTypeOf(result).toMatchTypeOf<{ + address: undefined + chain: undefined + chainId: undefined + connector: undefined + isConnected: false + isReconnecting: false + isConnecting: false + isDisconnected: true + status: 'disconnected' + }>() + break + } + } +}) diff --git a/wagmi-project/packages/core/src/actions/getAccount.test.ts b/wagmi-project/packages/core/src/actions/getAccount.test.ts new file mode 100644 index 0000000000..a538357875 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getAccount.test.ts @@ -0,0 +1,37 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { getAccount } from './getAccount.js' + +test('default', () => { + expect(getAccount(config)).toMatchInlineSnapshot(` + { + "address": undefined, + "addresses": undefined, + "chain": undefined, + "chainId": undefined, + "connector": undefined, + "isConnected": false, + "isConnecting": false, + "isDisconnected": true, + "isReconnecting": false, + "status": "disconnected", + } + `) +}) + +test('behavior: connected', async () => { + let result = getAccount(config) + expect(result.status).toEqual('disconnected') + + await connect(config, { connector: config.connectors[0]! }) + result = getAccount(config) + expect(result.address).toBeDefined() + expect(result.status).toEqual('connected') + + await disconnect(config) + result = getAccount(config) + expect(result.status).toEqual('disconnected') +}) diff --git a/wagmi-project/packages/core/src/actions/getAccount.ts b/wagmi-project/packages/core/src/actions/getAccount.ts new file mode 100644 index 0000000000..af5daea028 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getAccount.ts @@ -0,0 +1,126 @@ +import type { Address, Chain } from 'viem' + +import type { Config, Connector } from '../createConfig.js' + +export type GetAccountReturnType< + config extends Config = Config, + /// + chain = Config extends config ? Chain : config['chains'][number], +> = + | { + address: Address + addresses: readonly [Address, ...Address[]] + chain: chain | undefined + chainId: number + connector: Connector + isConnected: true + isConnecting: false + isDisconnected: false + isReconnecting: false + status: 'connected' + } + | { + address: Address | undefined + addresses: readonly Address[] | undefined + chain: chain | undefined + chainId: number | undefined + connector: Connector | undefined + isConnected: boolean + isConnecting: false + isDisconnected: false + isReconnecting: true + status: 'reconnecting' + } + | { + address: Address | undefined + addresses: readonly Address[] | undefined + chain: chain | undefined + chainId: number | undefined + connector: Connector | undefined + isConnected: false + isReconnecting: false + isConnecting: true + isDisconnected: false + status: 'connecting' + } + | { + address: undefined + addresses: undefined + chain: undefined + chainId: undefined + connector: undefined + isConnected: false + isReconnecting: false + isConnecting: false + isDisconnected: true + status: 'disconnected' + } + +/** https://wagmi.sh/core/api/actions/getAccount */ +export function getAccount( + config: config, +): GetAccountReturnType { + const uid = config.state.current! + const connection = config.state.connections.get(uid) + const addresses = connection?.accounts + const address = addresses?.[0] + const chain = config.chains.find( + (chain) => chain.id === connection?.chainId, + ) as GetAccountReturnType['chain'] + const status = config.state.status + + switch (status) { + case 'connected': + return { + address: address!, + addresses: addresses!, + chain, + chainId: connection?.chainId!, + connector: connection?.connector!, + isConnected: true, + isConnecting: false, + isDisconnected: false, + isReconnecting: false, + status, + } + case 'reconnecting': + return { + address, + addresses, + chain, + chainId: connection?.chainId, + connector: connection?.connector, + isConnected: !!address, + isConnecting: false, + isDisconnected: false, + isReconnecting: true, + status, + } + case 'connecting': + return { + address, + addresses, + chain, + chainId: connection?.chainId, + connector: connection?.connector, + isConnected: false, + isConnecting: true, + isDisconnected: false, + isReconnecting: false, + status, + } + case 'disconnected': + return { + address: undefined, + addresses: undefined, + chain: undefined, + chainId: undefined, + connector: undefined, + isConnected: false, + isConnecting: false, + isDisconnected: true, + isReconnecting: false, + status, + } + } +} diff --git a/wagmi-project/packages/core/src/actions/getBalance.test.ts b/wagmi-project/packages/core/src/actions/getBalance.test.ts new file mode 100644 index 0000000000..954c09c2e6 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getBalance.test.ts @@ -0,0 +1,102 @@ +import { accounts, chain, config, testClient } from '@wagmi/test' +import { parseEther } from 'viem' +import { beforeEach, expect, test } from 'vitest' + +import { getBalance } from './getBalance.js' + +const address = accounts[0] + +beforeEach(async () => { + await testClient.mainnet.setBalance({ + address, + value: parseEther('10000'), + }) + await testClient.mainnet.mine({ blocks: 1 }) + await testClient.mainnet2.setBalance({ + address, + value: parseEther('420'), + }) + await testClient.mainnet2.mine({ blocks: 1 }) +}) + +test('default', async () => { + await expect(getBalance(config, { address })).resolves.toMatchInlineSnapshot(` + { + "decimals": 18, + "formatted": "10000", + "symbol": "ETH", + "value": 10000000000000000000000n, + } + `) + + await testClient.mainnet.setBalance({ + address, + value: parseEther('6969.12222215666'), + }) + await expect(getBalance(config, { address })).resolves.toMatchInlineSnapshot(` + { + "decimals": 18, + "formatted": "6969.12222215666", + "symbol": "ETH", + "value": 6969122222156660000000n, + } + `) +}) + +test('parameters: chainId', async () => { + await expect( + getBalance(config, { address, chainId: chain.mainnet2.id }), + ).resolves.toMatchInlineSnapshot(` + { + "decimals": 18, + "formatted": "420", + "symbol": "WAG", + "value": 420000000000000000000n, + } + `) +}) + +test('parameters: token', async () => { + await expect( + getBalance(config, { + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + token: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + }), + ).resolves.toMatchInlineSnapshot(` + { + "decimals": 18, + "formatted": "0.559062564299199392", + "symbol": "DAI", + "value": 559062564299199392n, + } + `) +}) + +test('parameters: token (bytes32 symbol)', async () => { + await expect( + getBalance(config, { + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + token: '0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2', + }), + ).resolves.toMatchInlineSnapshot(` + { + "decimals": 18, + "formatted": "0", + "symbol": "MKR", + "value": 0n, + } + `) +}) + +test('parameters: unit', async () => { + await expect( + getBalance(config, { address, unit: 'wei' }), + ).resolves.toMatchInlineSnapshot(` + { + "decimals": 18, + "formatted": "10000000000000000000000", + "symbol": "ETH", + "value": 10000000000000000000000n, + } + `) +}) diff --git a/wagmi-project/packages/core/src/actions/getBalance.ts b/wagmi-project/packages/core/src/actions/getBalance.ts new file mode 100644 index 0000000000..1aae5667b1 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getBalance.ts @@ -0,0 +1,149 @@ +import { type Address, type Hex, formatUnits, hexToString, trim } from 'viem' +import { + type GetBalanceErrorType as viem_GetBalanceErrorType, + type GetBalanceParameters as viem_GetBalanceParameters, + getBalance as viem_getBalance, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Unit } from '../types/unit.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' +import { getUnit } from '../utils/getUnit.js' +import { type ReadContractsErrorType, readContracts } from './readContracts.js' + +export type GetBalanceParameters = Compute< + ChainIdParameter & + viem_GetBalanceParameters & { + /** @deprecated */ + token?: Address | undefined + /** @deprecated */ + unit?: Unit | undefined + } +> + +export type GetBalanceReturnType = { + decimals: number + /** @deprecated */ + formatted: string + symbol: string + value: bigint +} + +export type GetBalanceErrorType = viem_GetBalanceErrorType + +/** https://wagmi.sh/core/api/actions/getBalance */ +export async function getBalance( + config: config, + parameters: GetBalanceParameters, +): Promise { + const { + address, + blockNumber, + blockTag, + chainId, + token: tokenAddress, + unit = 'ether', + } = parameters + + if (tokenAddress) { + try { + return await getTokenBalance(config, { + balanceAddress: address, + chainId, + symbolType: 'string', + tokenAddress, + }) + } catch (error) { + // In the chance that there is an error upon decoding the contract result, + // it could be likely that the contract data is represented as bytes32 instead + // of a string. + if ( + (error as ReadContractsErrorType).name === + 'ContractFunctionExecutionError' + ) { + const balance = await getTokenBalance(config, { + balanceAddress: address, + chainId, + symbolType: 'bytes32', + tokenAddress, + }) + const symbol = hexToString( + trim(balance.symbol as Hex, { dir: 'right' }), + ) + return { ...balance, symbol } + } + throw error + } + } + + const client = config.getClient({ chainId }) + const action = getAction(client, viem_getBalance, 'getBalance') + const value = await action( + blockNumber ? { address, blockNumber } : { address, blockTag }, + ) + const chain = config.chains.find((x) => x.id === chainId) ?? client.chain! + return { + decimals: chain.nativeCurrency.decimals, + formatted: formatUnits(value, getUnit(unit)), + symbol: chain.nativeCurrency.symbol, + value, + } +} + +type GetTokenBalanceParameters = { + balanceAddress: Address + chainId?: number | undefined + symbolType: 'bytes32' | 'string' + tokenAddress: Address + unit?: Unit | undefined +} + +async function getTokenBalance( + config: Config, + parameters: GetTokenBalanceParameters, +) { + const { balanceAddress, chainId, symbolType, tokenAddress, unit } = parameters + const contract = { + abi: [ + { + type: 'function', + name: 'balanceOf', + stateMutability: 'view', + inputs: [{ type: 'address' }], + outputs: [{ type: 'uint256' }], + }, + { + type: 'function', + name: 'decimals', + stateMutability: 'view', + inputs: [], + outputs: [{ type: 'uint8' }], + }, + { + type: 'function', + name: 'symbol', + stateMutability: 'view', + inputs: [], + outputs: [{ type: symbolType }], + }, + ], + address: tokenAddress, + } as const + const [value, decimals, symbol] = await readContracts(config, { + allowFailure: false, + contracts: [ + { + ...contract, + functionName: 'balanceOf', + args: [balanceAddress], + chainId, + }, + { ...contract, functionName: 'decimals', chainId }, + { ...contract, functionName: 'symbol', chainId }, + ] as const, + }) + const formatted = formatUnits(value ?? '0', getUnit(unit ?? decimals)) + return { decimals, formatted, symbol, value } +} diff --git a/wagmi-project/packages/core/src/actions/getBlock.test-d.ts b/wagmi-project/packages/core/src/actions/getBlock.test-d.ts new file mode 100644 index 0000000000..2344c50267 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getBlock.test-d.ts @@ -0,0 +1,35 @@ +import { http, type Hex } from 'viem' +import { celo, mainnet } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { createConfig } from '../createConfig.js' +import { getBlock } from './getBlock.js' + +test('chain formatters', async () => { + const config = createConfig({ + chains: [celo, mainnet], + transports: { [celo.id]: http(), [mainnet.id]: http() }, + }) + const result = await getBlock(config) + if (result.chainId === celo.id) { + expectTypeOf(result.difficulty).toEqualTypeOf() + expectTypeOf(result.gasLimit).toEqualTypeOf() + expectTypeOf(result.mixHash).toEqualTypeOf() + expectTypeOf(result.nonce).toEqualTypeOf<`0x${string}`>() + expectTypeOf(result.uncles).toEqualTypeOf() + } +}) + +test('chainId', async () => { + const config = createConfig({ + chains: [celo, mainnet], + transports: { [celo.id]: http(), [mainnet.id]: http() }, + }) + const result = await getBlock(config, { + chainId: celo.id, + }) + expectTypeOf(result.difficulty).toEqualTypeOf() + expectTypeOf(result.gasLimit).toEqualTypeOf() + expectTypeOf(result.mixHash).toEqualTypeOf() + expectTypeOf(result.nonce).toEqualTypeOf<`0x${string}`>() +}) diff --git a/wagmi-project/packages/core/src/actions/getBlock.test.ts b/wagmi-project/packages/core/src/actions/getBlock.test.ts new file mode 100644 index 0000000000..b1e92ba364 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getBlock.test.ts @@ -0,0 +1,153 @@ +import { config, mainnet } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getBlock } from './getBlock.js' + +test('default', async () => { + await expect(getBlock(config)).resolves.toBeDefined() +}) + +test('args: blockNumber', async () => { + const { transactions, ...block } = await getBlock(config, { + blockNumber: mainnet.fork.blockNumber, + }) + expect(transactions).toMatchObject( + expect.arrayContaining([expect.any(String)]), + ) + expect(block).toMatchInlineSnapshot(` + { + "baseFeePerGas": 24076814055n, + "blobGasUsed": undefined, + "chainId": 1, + "difficulty": 0n, + "excessBlobGas": undefined, + "extraData": "0x546974616e2028746974616e6275696c6465722e78797a29", + "gasLimit": 30000000n, + "gasUsed": 26325393n, + "hash": "0xcfa5df46abf1521f68ae72a7f7c4661949f4fb08a3d1296fe8082f6580a414e0", + "logsBloom": "0x2df3b5a24d2d57e7d73f96dbfea3577b1d5fbaacfcb9b5fb86db74d2e4ffd1e48bba050c33edada84fe477213937158c1e95d3da9f457f6f36e3ff0afdffcb667c5ee5f9e3ddffa9db1af6bbf15fcbbca5139717d5eedab4daa63cd8bb7dfa3e976b1e7023e2dc4586cef3caa0b73d6ff2ba3afb989c9f58f6b67bb4ed596c5aeb78cef51f69ad3675df70ffbd2aa6576d7c9e3debd00cccec3b69fc617b8568bfe588f7e126ef591f34ddd0d8b68c28b7ed45b46af3a7bb75c0e2fe4bec54fb772c87ae6f7efcdfb13139b758cfda4d98dffe426fef6d1c2e55f36b5bb1f0a2aef7bcbdf83d31ea646cf6ef3fe9d8b9af2ad4197f7ea2de462bd029fdef7e6f", + "miner": "0x4838b106fce9647bdf1e7877bf73ce8b0bad5f97", + "mixHash": "0x92ac9cd6e57bacd7c7d3e9b087c3907b1c085e284eec2dce7379a847cb4c9940", + "nonce": "0x0000000000000000", + "number": 19258213n, + "parentHash": "0x40cb7885ad596d0397d664a4dc9ef5c2011c09e9a62b386f838f5f5362582ebb", + "receiptsRoot": "0x910a69ba396ab4f59c2c77aa413e941fc4da97a021b8d8bbf12c125bfc42d9d3", + "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "size": 158252n, + "stateRoot": "0x6e27207d219b0251dbc2fde71f3cde8e33703261f032056453c27275500dddbc", + "timestamp": 1708302299n, + "totalDifficulty": null, + "transactionsRoot": "0x897dba26a3a940b62f86da6e5fec5f71312ad7c871a4031db79dee67442c9d1e", + "uncles": [], + "withdrawals": [ + { + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "0x112da72", + "index": "0x21ec946", + "validatorIndex": "0x5cd8e", + }, + { + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "0x1119345", + "index": "0x21ec947", + "validatorIndex": "0x5cd8f", + }, + { + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "0x110e2ca", + "index": "0x21ec948", + "validatorIndex": "0x5cd90", + }, + { + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "0x1119245", + "index": "0x21ec949", + "validatorIndex": "0x5cd91", + }, + { + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "0x1115a03", + "index": "0x21ec94a", + "validatorIndex": "0x5cd92", + }, + { + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "0x111cf3f", + "index": "0x21ec94b", + "validatorIndex": "0x5cd93", + }, + { + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "0x1106006", + "index": "0x21ec94c", + "validatorIndex": "0x5cd94", + }, + { + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "0x1115bb3", + "index": "0x21ec94d", + "validatorIndex": "0x5cd95", + }, + { + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "0x111e0d9", + "index": "0x21ec94e", + "validatorIndex": "0x5cd96", + }, + { + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "0x110829f", + "index": "0x21ec94f", + "validatorIndex": "0x5cd97", + }, + { + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "0x11029ab", + "index": "0x21ec950", + "validatorIndex": "0x5cd98", + }, + { + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "0x11140a6", + "index": "0x21ec951", + "validatorIndex": "0x5cd99", + }, + { + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "0x111396c", + "index": "0x21ec952", + "validatorIndex": "0x5cd9a", + }, + { + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "0x110de16", + "index": "0x21ec953", + "validatorIndex": "0x5cd9b", + }, + { + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "0x1121062", + "index": "0x21ec954", + "validatorIndex": "0x5cd9c", + }, + { + "address": "0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f", + "amount": "0x11188bc", + "index": "0x21ec955", + "validatorIndex": "0x5cd9d", + }, + ], + "withdrawalsRoot": "0x26638497bd55075025ac2362d92bd789ac1232fd50c4b3866565280318027950", + } + `) +}) + +test('args: includeTransactions', async () => { + const { transactions } = await getBlock(config, { + includeTransactions: true, + blockNumber: mainnet.fork.blockNumber, + }) + expect(transactions).toMatchObject( + expect.arrayContaining([expect.any(Object)]), + ) +}) diff --git a/wagmi-project/packages/core/src/actions/getBlock.ts b/wagmi-project/packages/core/src/actions/getBlock.ts new file mode 100644 index 0000000000..babb52cd41 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getBlock.ts @@ -0,0 +1,74 @@ +import type { BlockTag, Chain } from 'viem' +import { + type GetBlockErrorType as viem_GetBlockErrorType, + type GetBlockParameters as viem_GetBlockParameters, + type GetBlockReturnType as viem_GetBlockReturnType, + getBlock as viem_getBlock, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { SelectChains } from '../types/chain.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute, IsNarrowable } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type GetBlockParameters< + includeTransactions extends boolean = false, + blockTag extends BlockTag = 'latest', + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = Compute< + viem_GetBlockParameters & + ChainIdParameter +> + +export type GetBlockReturnType< + includeTransactions extends boolean = false, + blockTag extends BlockTag = 'latest', + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + /// + chains extends readonly Chain[] = SelectChains, +> = Compute< + { + [key in keyof chains]: viem_GetBlockReturnType< + IsNarrowable extends true ? chains[key] : undefined, + includeTransactions, + blockTag + > & { chainId: chains[key]['id'] } + }[number] +> + +export type GetBlockErrorType = viem_GetBlockErrorType + +/** https://wagmi.sh/core/actions/getBlock */ +export async function getBlock< + config extends Config, + chainId extends config['chains'][number]['id'], + includeTransactions extends boolean = false, + blockTag extends BlockTag = 'latest', +>( + config: config, + parameters: GetBlockParameters< + includeTransactions, + blockTag, + config, + chainId + > = {}, +): Promise> { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction(client, viem_getBlock, 'getBlock') + const block = await action(rest) + return { + ...(block as unknown as GetBlockReturnType< + includeTransactions, + blockTag, + config, + chainId + >), + chainId: client.chain.id, + } +} diff --git a/wagmi-project/packages/core/src/actions/getBlockNumber.test.ts b/wagmi-project/packages/core/src/actions/getBlockNumber.test.ts new file mode 100644 index 0000000000..7e18744e14 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getBlockNumber.test.ts @@ -0,0 +1,8 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getBlockNumber } from './getBlockNumber.js' + +test('default', async () => { + await expect(getBlockNumber(config)).resolves.toBeDefined() +}) diff --git a/wagmi-project/packages/core/src/actions/getBlockNumber.ts b/wagmi-project/packages/core/src/actions/getBlockNumber.ts new file mode 100644 index 0000000000..ecad7c0f67 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getBlockNumber.ts @@ -0,0 +1,36 @@ +import { + type GetBlockNumberErrorType as viem_GetBlockNumberErrorType, + type GetBlockNumberParameters as viem_GetBlockNumberParameters, + type GetBlockNumberReturnType as viem_GetBlockNumberReturnType, + getBlockNumber as viem_getBlockNumber, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type GetBlockNumberParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = Compute> + +export type GetBlockNumberReturnType = viem_GetBlockNumberReturnType + +export type GetBlockNumberErrorType = viem_GetBlockNumberErrorType + +/** https://wagmi.sh/core/api/actions/getBlockNumber */ +export function getBlockNumber< + config extends Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +>( + config: config, + parameters: GetBlockNumberParameters = {}, +): Promise { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction(client, viem_getBlockNumber, 'getBlockNumber') + return action(rest) +} diff --git a/wagmi-project/packages/core/src/actions/getBlockTransactionCount.test.ts b/wagmi-project/packages/core/src/actions/getBlockTransactionCount.test.ts new file mode 100644 index 0000000000..d8a593aa00 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getBlockTransactionCount.test.ts @@ -0,0 +1,61 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getBlockTransactionCount } from './getBlockTransactionCount.js' + +test('default', async () => { + await expect(getBlockTransactionCount(config)).resolves.toBeTypeOf('number') +}) + +test('parameters: chainId', async () => { + await expect( + getBlockTransactionCount(config, { chainId: chain.mainnet2.id }), + ).resolves.toBeTypeOf('number') +}) + +test('parameters: blockNumber', async () => { + await expect( + getBlockTransactionCount(config, { blockNumber: 13677382n }), + ).resolves.toBeTypeOf('number') +}) + +test('parameters: blockHash', async () => { + await expect( + getBlockTransactionCount(config, { + blockHash: + '0x6201f37a245850d1f11e4be3ac45bc51bd9d43ee4a127192cad550f351cfa575', + }), + ).resolves.toBeTypeOf('number') +}) + +test('parameters: blockTag', async () => { + await expect( + getBlockTransactionCount(config, { + blockTag: 'earliest', + }), + ).resolves.toBeTypeOf('number') + + await expect( + getBlockTransactionCount(config, { + blockTag: 'finalized', + }), + ).resolves.toBeTypeOf('number') + + await expect( + getBlockTransactionCount(config, { + blockTag: 'latest', + }), + ).resolves.toBeTypeOf('number') + + await expect( + getBlockTransactionCount(config, { + blockTag: 'pending', + }), + ).resolves.toBeTypeOf('number') + + await expect( + getBlockTransactionCount(config, { + blockTag: 'safe', + }), + ).resolves.toBeTypeOf('number') +}) diff --git a/wagmi-project/packages/core/src/actions/getBlockTransactionCount.ts b/wagmi-project/packages/core/src/actions/getBlockTransactionCount.ts new file mode 100644 index 0000000000..e30aca976a --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getBlockTransactionCount.ts @@ -0,0 +1,44 @@ +import { + type GetBlockTransactionCountErrorType as viem_GetBlockTransactionCountErrorType, + type GetBlockTransactionCountParameters as viem_GetBlockTransactionCountParameters, + type GetBlockTransactionCountReturnType as viem_GetBlockTransactionCountReturnType, + getBlockTransactionCount as viem_getBlockTransactionCount, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { UnionCompute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type GetBlockTransactionCountParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = UnionCompute< + viem_GetBlockTransactionCountParameters & ChainIdParameter +> + +export type GetBlockTransactionCountReturnType = + viem_GetBlockTransactionCountReturnType + +export type GetBlockTransactionCountErrorType = + viem_GetBlockTransactionCountErrorType + +/** https://wagmi.sh/core/api/actions/getBlockTransactionCount */ +export function getBlockTransactionCount< + config extends Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +>( + config: config, + parameters: GetBlockTransactionCountParameters = {}, +): Promise { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction( + client, + viem_getBlockTransactionCount, + 'getBlockTransactionCount', + ) + return action(rest) +} diff --git a/wagmi-project/packages/core/src/actions/getBytecode.test.ts b/wagmi-project/packages/core/src/actions/getBytecode.test.ts new file mode 100644 index 0000000000..1d5b6bdff9 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getBytecode.test.ts @@ -0,0 +1,45 @@ +import { address, chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getBytecode } from './getBytecode.js' + +test('default', async () => { + await expect( + getBytecode(config, { + address: '0x0000000000000000000000000000000000000000', + }), + ).resolves.toBe(undefined) + + await expect( + getBytecode(config, { + address: address.wagmiMintExample, + }), + ).resolves.toMatch(/^0x.*/) +}) + +test('parameters: blockNumber', async () => { + await expect( + getBytecode(config, { + address: address.wagmiMintExample, + blockNumber: 15564163n, + }), + ).resolves.toBe(undefined) +}) + +test('parameters: blockTag', async () => { + await expect( + getBytecode(config, { + address: address.wagmiMintExample, + blockTag: 'earliest', + }), + ).resolves.toBe(undefined) +}) + +test('parameters: chainId', async () => { + await expect( + getBytecode(config, { + address: address.wagmiMintExample, + chainId: chain.optimism.id, + }), + ).resolves.toBe(undefined) +}) diff --git a/wagmi-project/packages/core/src/actions/getBytecode.ts b/wagmi-project/packages/core/src/actions/getBytecode.ts new file mode 100644 index 0000000000..2ece822a86 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getBytecode.ts @@ -0,0 +1,30 @@ +import { + type GetBytecodeErrorType as viem_GetBytecodeErrorType, + type GetBytecodeParameters as viem_GetBytecodeParameters, + type GetBytecodeReturnType as viem_GetBytecodeReturnType, + getBytecode as viem_getBytecode, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type GetBytecodeParameters = Compute< + viem_GetBytecodeParameters & ChainIdParameter +> + +export type GetBytecodeReturnType = viem_GetBytecodeReturnType + +export type GetBytecodeErrorType = viem_GetBytecodeErrorType + +/** https://wagmi.sh/core/api/actions/getBytecode */ +export async function getBytecode( + config: config, + parameters: GetBytecodeParameters, +): Promise { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction(client, viem_getBytecode, 'getBytecode') + return action(rest) +} diff --git a/wagmi-project/packages/core/src/actions/getCallsStatus.test.ts b/wagmi-project/packages/core/src/actions/getCallsStatus.test.ts new file mode 100644 index 0000000000..72978a3c7f --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getCallsStatus.test.ts @@ -0,0 +1,70 @@ +import { accounts, config, testClient } from '@wagmi/test' +import { parseEther } from 'viem' +import { expect, test } from 'vitest' + +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { getCallsStatus } from './getCallsStatus.js' +import { sendCalls } from './sendCalls.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + const { id } = await sendCalls(config, { + calls: [ + { + data: '0xdeadbeef', + to: accounts[1], + value: parseEther('1'), + }, + { + to: accounts[2], + value: parseEther('2'), + }, + { + to: accounts[3], + value: parseEther('3'), + }, + ], + }) + await testClient.mainnet.mine({ blocks: 1 }) + const { receipts, status } = await getCallsStatus(config, { + id, + }) + + expect(status).toBe('success') + expect( + receipts?.map((x) => ({ ...x, blockHash: undefined })), + ).toMatchInlineSnapshot( + ` + [ + { + "blockHash": undefined, + "blockNumber": 19258214n, + "gasUsed": 21064n, + "logs": [], + "status": "success", + "transactionHash": "0x13c53b2d4d9da424835525349cd66e553330f323d6fb19458b801ae1f7989a41", + }, + { + "blockHash": undefined, + "blockNumber": 19258214n, + "gasUsed": 21000n, + "logs": [], + "status": "success", + "transactionHash": "0xd8397b3e82b061c26a0c2093f1ceca0c3662a512614f7d6370349e89d0eea007", + }, + { + "blockHash": undefined, + "blockNumber": 19258214n, + "gasUsed": 21000n, + "logs": [], + "status": "success", + "transactionHash": "0x4d26e346593d9ea265bb164b115e89aa92df43b0b8778ac75d4ad28e2a22b101", + }, + ] + `, + ) + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/core/src/actions/getCallsStatus.ts b/wagmi-project/packages/core/src/actions/getCallsStatus.ts new file mode 100644 index 0000000000..85f7a592c5 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getCallsStatus.ts @@ -0,0 +1,27 @@ +import { + type GetCallsStatusErrorType as viem_GetCallsStatusErrorType, + type GetCallsStatusParameters as viem_GetCallsStatusParameters, + type GetCallsStatusReturnType as viem_GetCallsStatusReturnType, + getCallsStatus as viem_getCallsStatus, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ConnectorParameter } from '../types/properties.js' +import { getConnectorClient } from './getConnectorClient.js' + +export type GetCallsStatusParameters = viem_GetCallsStatusParameters & + ConnectorParameter + +export type GetCallsStatusReturnType = viem_GetCallsStatusReturnType + +export type GetCallsStatusErrorType = viem_GetCallsStatusErrorType + +/** https://wagmi.sh/core/api/actions/getCallsStatus */ +export async function getCallsStatus( + config: config, + parameters: GetCallsStatusParameters, +): Promise { + const { connector, id } = parameters + const client = await getConnectorClient(config, { connector }) + return viem_getCallsStatus(client, { id }) +} diff --git a/wagmi-project/packages/core/src/actions/getCapabilities.test.ts b/wagmi-project/packages/core/src/actions/getCapabilities.test.ts new file mode 100644 index 0000000000..e7c02ec444 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getCapabilities.test.ts @@ -0,0 +1,64 @@ +import { accounts, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { getCapabilities } from './getCapabilities.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + const capabilities = await getCapabilities(config) + expect(capabilities).toMatchInlineSnapshot(` + { + "8453": { + "paymasterService": { + "supported": true, + }, + "sessionKeys": { + "supported": true, + }, + }, + "84532": { + "paymasterService": { + "supported": true, + }, + }, + } + `) + await disconnect(config, { connector }) +}) + +test('args: account', async () => { + await connect(config, { connector }) + const capabilities = await getCapabilities(config, { + account: accounts[1], + }) + expect(capabilities).toMatchInlineSnapshot(` + { + "8453": { + "paymasterService": { + "supported": false, + }, + "sessionKeys": { + "supported": true, + }, + }, + "84532": { + "paymasterService": { + "supported": false, + }, + }, + } + `) + await disconnect(config, { connector }) +}) + +test('behavior: not connected', async () => { + await expect(getCapabilities(config)).rejects.toMatchInlineSnapshot(` + [ConnectorNotConnectedError: Connector not connected. + + Version: @wagmi/core@x.y.z] + `) +}) diff --git a/wagmi-project/packages/core/src/actions/getCapabilities.ts b/wagmi-project/packages/core/src/actions/getCapabilities.ts new file mode 100644 index 0000000000..ab8ea82bfb --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getCapabilities.ts @@ -0,0 +1,39 @@ +import type { Account } from 'viem' +import { + type GetCapabilitiesErrorType as viem_GetCapabilitiesErrorType, + type GetCapabilitiesParameters as viem_GetCapabilitiesParameters, + type GetCapabilitiesReturnType as viem_GetCapabilitiesReturnType, + getCapabilities as viem_getCapabilities, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ConnectorParameter } from '../types/properties.js' +import { getConnectorClient } from './getConnectorClient.js' + +export type GetCapabilitiesParameters< + config extends Config = Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, +> = viem_GetCapabilitiesParameters & ConnectorParameter + +export type GetCapabilitiesReturnType< + config extends Config = Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, +> = viem_GetCapabilitiesReturnType + +export type GetCapabilitiesErrorType = viem_GetCapabilitiesErrorType + +/** https://wagmi.sh/core/api/actions/getCapabilities */ +export async function getCapabilities< + config extends Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, +>( + config: config, + parameters: GetCapabilitiesParameters = {}, +): Promise> { + const { account, chainId, connector } = parameters + const client = await getConnectorClient(config, { account, connector }) + return viem_getCapabilities(client as any, { + account: account as Account, + chainId, + }) +} diff --git a/wagmi-project/packages/core/src/actions/getChainId.test.ts b/wagmi-project/packages/core/src/actions/getChainId.test.ts new file mode 100644 index 0000000000..3dcedcf085 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getChainId.test.ts @@ -0,0 +1,10 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getChainId } from './getChainId.js' + +test('default', async () => { + expect(getChainId(config)).toEqual(chain.mainnet.id) + config.setState((x) => ({ ...x, chainId: chain.mainnet2.id })) + expect(getChainId(config)).toEqual(chain.mainnet2.id) +}) diff --git a/wagmi-project/packages/core/src/actions/getChainId.ts b/wagmi-project/packages/core/src/actions/getChainId.ts new file mode 100644 index 0000000000..208602e05b --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getChainId.ts @@ -0,0 +1,11 @@ +import type { Config } from '../createConfig.js' + +export type GetChainIdReturnType = + config['chains'][number]['id'] + +/** https://wagmi.sh/core/api/actions/getChainId */ +export function getChainId( + config: config, +): GetChainIdReturnType { + return config.state.chainId +} diff --git a/wagmi-project/packages/core/src/actions/getChains.test-d.ts b/wagmi-project/packages/core/src/actions/getChains.test-d.ts new file mode 100644 index 0000000000..cd5f04c9c5 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getChains.test-d.ts @@ -0,0 +1,12 @@ +import { type chain, config } from '@wagmi/test' +import type { Chain } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { getChains } from './getChains.js' + +test('default', async () => { + const chains = getChains(config) + expectTypeOf(chains[0]).toEqualTypeOf() + expectTypeOf(chains[2]).toEqualTypeOf() + expectTypeOf(chains[3]).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/core/src/actions/getChains.test.ts b/wagmi-project/packages/core/src/actions/getChains.test.ts new file mode 100644 index 0000000000..fbaeae7645 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getChains.test.ts @@ -0,0 +1,14 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getChains } from './getChains.js' + +test('default', async () => { + expect(getChains(config)).toEqual([ + chain.mainnet, + chain.mainnet2, + chain.optimism, + ]) + config._internal.chains.setState([chain.mainnet, chain.mainnet2]) + expect(getChains(config)).toEqual([chain.mainnet, chain.mainnet2]) +}) diff --git a/wagmi-project/packages/core/src/actions/getChains.ts b/wagmi-project/packages/core/src/actions/getChains.ts new file mode 100644 index 0000000000..a91e6e89b4 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getChains.ts @@ -0,0 +1,21 @@ +import type { Chain } from 'viem' +import type { Config } from '../createConfig.js' +import { deepEqual } from '../utils/deepEqual.js' + +export type GetChainsReturnType = readonly [ + ...config['chains'], + ...Chain[], +] + +let previousChains: readonly Chain[] = [] + +/** https://wagmi.sh/core/api/actions/getChains */ +export function getChains( + config: config, +): GetChainsReturnType { + const chains = config.chains + if (deepEqual(previousChains, chains)) + return previousChains as GetChainsReturnType + previousChains = chains + return chains as unknown as GetChainsReturnType +} diff --git a/wagmi-project/packages/core/src/actions/getClient.test-d.ts b/wagmi-project/packages/core/src/actions/getClient.test-d.ts new file mode 100644 index 0000000000..f64cbae2ce --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getClient.test-d.ts @@ -0,0 +1,27 @@ +import { chain, config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { getClient } from './getClient.js' + +test('default', () => { + const client = getClient(config) + expectTypeOf(client.chain).toEqualTypeOf<(typeof config)['chains'][number]>() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() +}) + +test('parameters: chainId', () => { + const client = getClient(config, { + chainId: chain.mainnet.id, + }) + expectTypeOf(client.chain).toEqualTypeOf() + expectTypeOf(client.chain).not.toEqualTypeOf() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() +}) + +test('behavior: unconfigured chain', () => { + const client = getClient(config, { + // @ts-expect-error + chainId: 123456, + }) + expectTypeOf(client).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/core/src/actions/getClient.test.ts b/wagmi-project/packages/core/src/actions/getClient.test.ts new file mode 100644 index 0000000000..9eb0fa574b --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getClient.test.ts @@ -0,0 +1,17 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getClient } from './getClient.js' + +test('default', () => { + expect(getClient(config)).toBeDefined() +}) + +test('behavior: unconfigured chain', () => { + expect( + getClient(config, { + // @ts-expect-error + chainId: 123456, + }), + ).toBeUndefined() +}) diff --git a/wagmi-project/packages/core/src/actions/getClient.ts b/wagmi-project/packages/core/src/actions/getClient.ts new file mode 100644 index 0000000000..82f1c6c171 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getClient.ts @@ -0,0 +1,52 @@ +import type { Client } from 'viem' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute, IsNarrowable } from '../types/utils.js' + +export type GetClientParameters< + config extends Config = Config, + chainId extends + | config['chains'][number]['id'] + | number + | undefined = config['chains'][number]['id'], +> = ChainIdParameter + +export type GetClientReturnType< + config extends Config = Config, + chainId extends + | config['chains'][number]['id'] + | undefined = config['chains'][number]['id'], + /// + resolvedChainId extends + | config['chains'][number]['id'] + | undefined = IsNarrowable< + config['chains'][number]['id'], + number + > extends true + ? IsNarrowable extends true + ? chainId + : config['chains'][number]['id'] + : config['chains'][number]['id'] | undefined, +> = resolvedChainId extends config['chains'][number]['id'] + ? Compute< + Client< + config['_internal']['transports'][resolvedChainId], + Extract + > + > + : undefined + +export function getClient< + config extends Config, + chainId extends config['chains'][number]['id'] | number | undefined, +>( + config: config, + parameters: GetClientParameters = {}, +): GetClientReturnType { + let client = undefined + try { + client = config.getClient(parameters) + } catch {} + return client as GetClientReturnType +} diff --git a/wagmi-project/packages/core/src/actions/getConnections.test.ts b/wagmi-project/packages/core/src/actions/getConnections.test.ts new file mode 100644 index 0000000000..22e6748cf9 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getConnections.test.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { getConnections } from './getConnections.js' + +test('default', async () => { + const connector = config.connectors[0]! + expect(getConnections(config)).toEqual([]) + await connect(config, { connector }) + expect(getConnections(config).length).toEqual(1) + await disconnect(config, { connector }) + expect(getConnections(config)).toEqual([]) +}) diff --git a/wagmi-project/packages/core/src/actions/getConnections.ts b/wagmi-project/packages/core/src/actions/getConnections.ts new file mode 100644 index 0000000000..72cdbc27d7 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getConnections.ts @@ -0,0 +1,16 @@ +import type { Config, Connection } from '../createConfig.js' +import type { Compute } from '../types/utils.js' +import { deepEqual } from '../utils/deepEqual.js' + +export type GetConnectionsReturnType = Compute[] + +let previousConnections: Connection[] = [] + +/** https://wagmi.sh/core/api/actions/getConnections */ +export function getConnections(config: Config): GetConnectionsReturnType { + const connections = [...config.state.connections.values()] + if (config.state.status === 'reconnecting') return previousConnections + if (deepEqual(previousConnections, connections)) return previousConnections + previousConnections = connections + return connections +} diff --git a/wagmi-project/packages/core/src/actions/getConnectorClient.test-d.ts b/wagmi-project/packages/core/src/actions/getConnectorClient.test-d.ts new file mode 100644 index 0000000000..c4d980a7d5 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getConnectorClient.test-d.ts @@ -0,0 +1,19 @@ +import { chain, config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { getConnectorClient } from './getConnectorClient.js' + +test('default', async () => { + const client = await getConnectorClient(config) + expectTypeOf(client.chain).toEqualTypeOf<(typeof config)['chains'][number]>() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() +}) + +test('parameters: chainId', async () => { + const client = await getConnectorClient(config, { + chainId: chain.mainnet.id, + }) + expectTypeOf(client.chain).toEqualTypeOf() + expectTypeOf(client.chain).not.toEqualTypeOf() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() +}) diff --git a/wagmi-project/packages/core/src/actions/getConnectorClient.test.ts b/wagmi-project/packages/core/src/actions/getConnectorClient.test.ts new file mode 100644 index 0000000000..a9d60f5142 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getConnectorClient.test.ts @@ -0,0 +1,106 @@ +import { address, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import type { Connector } from '../createConfig.js' +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { getConnectorClient } from './getConnectorClient.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + await expect(getConnectorClient(config)).resolves.toBeDefined() + await disconnect(config, { connector }) +}) + +test('parameters: connector', async () => { + const connector2 = config.connectors[1]! + await connect(config, { connector }) + await connect(config, { connector: connector2 }) + await expect(getConnectorClient(config, { connector })).resolves.toBeDefined() + await disconnect(config, { connector }) + await disconnect(config, { connector: connector2 }) +}) + +test.todo('custom connector client') + +test('behavior: account address is checksummed', async () => { + await connect(config, { connector }) + const account = '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266' + const client = await getConnectorClient(config, { account }) + expect(client.account.address).toMatchInlineSnapshot( + '"0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"', + ) + expect(client.account.address).not.toBe(account) + await disconnect(config, { connector }) +}) + +test('behavior: not connected', async () => { + await expect( + getConnectorClient(config), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [ConnectorNotConnectedError: Connector not connected. + + Version: @wagmi/core@x.y.z] + `) +}) + +test('behavior: connector is on different chain', async () => { + await connect(config, { chainId: 1, connector }) + config.setState((state) => { + const uid = state.current! + const connection = state.connections.get(uid)! + return { + ...state, + connections: new Map(state.connections).set(uid, { + ...connection, + chainId: 456, + }), + } + }) + await expect( + getConnectorClient(config, { account: address.usdcHolder }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [ConnectorChainMismatchError: The current chain of the connector (id: 1) does not match the connection's chain (id: 456). + + Current Chain ID: 1 + Expected Chain ID: 456 + + Version: @wagmi/core@x.y.z] + `) + await disconnect(config, { connector }) +}) + +test('behavior: account does not exist on connector', async () => { + await connect(config, { connector }) + await expect( + getConnectorClient(config, { account: address.usdcHolder }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [ConnectorAccountNotFoundError: Account "0x5414d89a8bF7E99d732BC52f3e6A3Ef461c0C078" not found for connector "Mock Connector". + + Version: @wagmi/core@x.y.z] + `) + await disconnect(config, { connector }) +}) + +test('behavior: reconnecting', async () => { + config.setState((state) => ({ ...state, status: 'reconnecting' })) + const { id, name, type, uid } = connector + await expect( + getConnectorClient(config, { + connector: { + id, + name, + type, + uid, + } as unknown as Connector, + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [ConnectorUnavailableReconnectingError: Connector "Mock Connector" unavailable while reconnecting. + + Details: During the reconnection step, the only connector methods guaranteed to be available are: \`id\`, \`name\`, \`type\`, \`uid\`. All other methods are not guaranteed to be available until reconnection completes and connectors are fully restored. This error commonly occurs for connectors that asynchronously inject after reconnection has already started. + Version: @wagmi/core@x.y.z] + `) + config.setState((state) => ({ ...state, status: 'disconnected' })) +}) diff --git a/wagmi-project/packages/core/src/actions/getConnectorClient.ts b/wagmi-project/packages/core/src/actions/getConnectorClient.ts new file mode 100644 index 0000000000..534ba76bc6 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getConnectorClient.ts @@ -0,0 +1,147 @@ +import { + type Account, + type Address, + type BaseErrorType, + type Client, + createClient, + custom, +} from 'viem' +import { getAddress, parseAccount } from 'viem/utils' + +import type { Config, Connection } from '../createConfig.js' +import type { ErrorType } from '../errors/base.js' +import { + ConnectorAccountNotFoundError, + type ConnectorAccountNotFoundErrorType, + ConnectorChainMismatchError, + type ConnectorChainMismatchErrorType, + ConnectorNotConnectedError, + type ConnectorNotConnectedErrorType, + ConnectorUnavailableReconnectingError, + type ConnectorUnavailableReconnectingErrorType, +} from '../errors/config.js' +import type { + ChainIdParameter, + ConnectorParameter, +} from '../types/properties.js' +import type { Compute } from '../types/utils.js' + +export type GetConnectorClientParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = Compute< + ChainIdParameter & + ConnectorParameter & { + /** + * Account to use for the client. + * + * - `Account | Address`: An Account MUST exist on the connector. + * - `null`: Account MAY NOT exist on the connector. This is useful for + * actions that can infer the account from the connector (e.g. sending a + * call without a connected account – the user will be prompted to select + * an account within the wallet). + */ + account?: Address | Account | null | undefined + } +> + +export type GetConnectorClientReturnType< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = Compute< + Client< + config['_internal']['transports'][chainId], + Extract, + Account + > +> + +export type GetConnectorClientErrorType = + | ConnectorAccountNotFoundErrorType + | ConnectorChainMismatchErrorType + | ConnectorNotConnectedErrorType + | ConnectorUnavailableReconnectingErrorType + // base + | BaseErrorType + | ErrorType + +/** https://wagmi.sh/core/api/actions/getConnectorClient */ +export async function getConnectorClient< + config extends Config, + chainId extends config['chains'][number]['id'], +>( + config: config, + parameters: GetConnectorClientParameters = {}, +): Promise> { + // Get connection + let connection: Connection | undefined + if (parameters.connector) { + const { connector } = parameters + if ( + config.state.status === 'reconnecting' && + !connector.getAccounts && + !connector.getChainId + ) + throw new ConnectorUnavailableReconnectingError({ connector }) + + const [accounts, chainId] = await Promise.all([ + connector.getAccounts().catch((e) => { + if (parameters.account === null) return [] + throw e + }), + connector.getChainId(), + ]) + connection = { + accounts: accounts as readonly [Address, ...Address[]], + chainId, + connector, + } + } else connection = config.state.connections.get(config.state.current!) + if (!connection) throw new ConnectorNotConnectedError() + + const chainId = parameters.chainId ?? connection.chainId + + // Check connector using same chainId as connection + const connectorChainId = await connection.connector.getChainId() + if (connectorChainId !== connection.chainId) + throw new ConnectorChainMismatchError({ + connectionChainId: connection.chainId, + connectorChainId, + }) + + // If connector has custom `getClient` implementation + type Return = GetConnectorClientReturnType + const connector = connection.connector + if (connector.getClient) + return connector.getClient({ chainId }) as unknown as Return + + // Default using `custom` transport + const account = parseAccount(parameters.account ?? connection.accounts[0]!) + if (account) account.address = getAddress(account.address) // TODO: Checksum address as part of `parseAccount`? + + // If account was provided, check that it exists on the connector + if ( + parameters.account && + !connection.accounts.some( + (x) => x.toLowerCase() === account.address.toLowerCase(), + ) + ) + throw new ConnectorAccountNotFoundError({ + address: account.address, + connector, + }) + + const chain = config.chains.find((chain) => chain.id === chainId) + const provider = (await connection.connector.getProvider({ chainId })) as { + request(...args: any): Promise + } + + return createClient({ + account, + chain, + name: 'Connector Client', + transport: (opts) => custom(provider)({ ...opts, retryCount: 0 }), + }) as Return +} diff --git a/wagmi-project/packages/core/src/actions/getConnectors.test.ts b/wagmi-project/packages/core/src/actions/getConnectors.test.ts new file mode 100644 index 0000000000..d15f5fbb08 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getConnectors.test.ts @@ -0,0 +1,8 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getConnectors } from './getConnectors.js' + +test('default', () => { + expect(getConnectors(config)).toEqual(config.connectors) +}) diff --git a/wagmi-project/packages/core/src/actions/getConnectors.ts b/wagmi-project/packages/core/src/actions/getConnectors.ts new file mode 100644 index 0000000000..439362d3f4 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getConnectors.ts @@ -0,0 +1,17 @@ +import type { Config, Connector } from '../createConfig.js' +import { deepEqual } from '../utils/deepEqual.js' + +export type GetConnectorsReturnType = + config['connectors'] + +let previousConnectors: readonly Connector[] = [] + +/** https://wagmi.sh/core/api/actions/getConnectors */ +export function getConnectors( + config: config, +): GetConnectorsReturnType { + const connectors = config.connectors + if (deepEqual(previousConnectors, connectors)) return previousConnectors + previousConnectors = connectors + return connectors +} diff --git a/wagmi-project/packages/core/src/actions/getEnsAddress.test.ts b/wagmi-project/packages/core/src/actions/getEnsAddress.test.ts new file mode 100644 index 0000000000..d120c82ef5 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getEnsAddress.test.ts @@ -0,0 +1,12 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getEnsAddress } from './getEnsAddress.js' + +test('default', async () => { + await expect( + getEnsAddress(config, { name: 'wevm.eth' }), + ).resolves.toMatchInlineSnapshot( + '"0xd2135CfB216b74109775236E36d4b433F1DF507B"', + ) +}) diff --git a/wagmi-project/packages/core/src/actions/getEnsAddress.ts b/wagmi-project/packages/core/src/actions/getEnsAddress.ts new file mode 100644 index 0000000000..5f882999be --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getEnsAddress.ts @@ -0,0 +1,30 @@ +import { + type GetEnsAddressErrorType as viem_GetEnsAddressErrorType, + type GetEnsAddressParameters as viem_GetEnsAddressParameters, + type GetEnsAddressReturnType as viem_GetEnsAddressReturnType, + getEnsAddress as viem_getEnsAddress, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type GetEnsAddressParameters = Compute< + viem_GetEnsAddressParameters & ChainIdParameter +> + +export type GetEnsAddressReturnType = viem_GetEnsAddressReturnType + +export type GetEnsAddressErrorType = viem_GetEnsAddressErrorType + +/** https://wagmi.sh/core/api/actions/getEnsAddress */ +export function getEnsAddress( + config: config, + parameters: GetEnsAddressParameters, +): Promise { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction(client, viem_getEnsAddress, 'getEnsAddress') + return action(rest) +} diff --git a/wagmi-project/packages/core/src/actions/getEnsAvatar.test.ts b/wagmi-project/packages/core/src/actions/getEnsAvatar.test.ts new file mode 100644 index 0000000000..ed1e830481 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getEnsAvatar.test.ts @@ -0,0 +1,12 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getEnsAvatar } from './getEnsAvatar.js' + +test('default', async () => { + await expect( + getEnsAvatar(config, { + name: 'wevm.eth', + }), + ).resolves.toMatchInlineSnapshot('"https://euc.li/wevm.eth"') +}) diff --git a/wagmi-project/packages/core/src/actions/getEnsAvatar.ts b/wagmi-project/packages/core/src/actions/getEnsAvatar.ts new file mode 100644 index 0000000000..e6c3855d13 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getEnsAvatar.ts @@ -0,0 +1,30 @@ +import { + type GetEnsAvatarErrorType as viem_GetEnsAvatarErrorType, + type GetEnsAvatarParameters as viem_GetEnsAvatarParameters, + type GetEnsAvatarReturnType as viem_GetEnsAvatarReturnType, + getEnsAvatar as viem_getEnsAvatar, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type GetEnsAvatarParameters = Compute< + viem_GetEnsAvatarParameters & ChainIdParameter +> + +export type GetEnsAvatarReturnType = viem_GetEnsAvatarReturnType + +export type GetEnsAvatarErrorType = viem_GetEnsAvatarErrorType + +/** https://wagmi.sh/core/api/actions/getEnsAvatar */ +export function getEnsAvatar( + config: config, + parameters: GetEnsAvatarParameters, +): Promise { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction(client, viem_getEnsAvatar, 'getEnsAvatar') + return action(rest) +} diff --git a/wagmi-project/packages/core/src/actions/getEnsName.test.ts b/wagmi-project/packages/core/src/actions/getEnsName.test.ts new file mode 100644 index 0000000000..38d1bae97b --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getEnsName.test.ts @@ -0,0 +1,12 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getEnsName } from './getEnsName.js' + +test('default', async () => { + await expect( + getEnsName(config, { + address: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + }), + ).resolves.toMatchInlineSnapshot('"wevm.eth"') +}) diff --git a/wagmi-project/packages/core/src/actions/getEnsName.ts b/wagmi-project/packages/core/src/actions/getEnsName.ts new file mode 100644 index 0000000000..e6ab338db4 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getEnsName.ts @@ -0,0 +1,30 @@ +import { + type GetEnsNameErrorType as viem_GetEnsNameErrorType, + type GetEnsNameParameters as viem_GetEnsNameParameters, + type GetEnsNameReturnType as viem_GetEnsNameReturnType, + getEnsName as viem_getEnsName, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type GetEnsNameParameters = Compute< + viem_GetEnsNameParameters & ChainIdParameter +> + +export type GetEnsNameReturnType = viem_GetEnsNameReturnType + +export type GetEnsNameErrorType = viem_GetEnsNameErrorType + +/** https://wagmi.sh/core/api/actions/getEnsName */ +export function getEnsName( + config: config, + parameters: GetEnsNameParameters, +): Promise { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction(client, viem_getEnsName, 'getEnsName') + return action(rest) +} diff --git a/wagmi-project/packages/core/src/actions/getEnsResolver.test.ts b/wagmi-project/packages/core/src/actions/getEnsResolver.test.ts new file mode 100644 index 0000000000..4bc30be55b --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getEnsResolver.test.ts @@ -0,0 +1,14 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getEnsResolver } from './getEnsResolver.js' + +test('default', async () => { + await expect( + getEnsResolver(config, { + name: 'wevm.eth', + }), + ).resolves.toMatchInlineSnapshot( + '"0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41"', + ) +}) diff --git a/wagmi-project/packages/core/src/actions/getEnsResolver.ts b/wagmi-project/packages/core/src/actions/getEnsResolver.ts new file mode 100644 index 0000000000..ab59b7d76c --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getEnsResolver.ts @@ -0,0 +1,30 @@ +import { + type GetEnsResolverErrorType as viem_GetEnsResolverErrorType, + type GetEnsResolverParameters as viem_GetEnsResolverParameters, + type GetEnsResolverReturnType as viem_GetEnsResolverReturnType, + getEnsResolver as viem_getEnsResolver, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type GetEnsResolverParameters = Compute< + viem_GetEnsResolverParameters & ChainIdParameter +> + +export type GetEnsResolverReturnType = viem_GetEnsResolverReturnType + +export type GetEnsResolverErrorType = viem_GetEnsResolverErrorType + +/** https://wagmi.sh/core/api/actions/getEnsResolver */ +export function getEnsResolver( + config: config, + parameters: GetEnsResolverParameters, +): Promise { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction(client, viem_getEnsResolver, 'getEnsResolver') + return action(rest) +} diff --git a/wagmi-project/packages/core/src/actions/getEnsText.test.ts b/wagmi-project/packages/core/src/actions/getEnsText.test.ts new file mode 100644 index 0000000000..63801747d5 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getEnsText.test.ts @@ -0,0 +1,13 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getEnsText } from './getEnsText.js' + +test('default', async () => { + await expect( + getEnsText(config, { + name: 'wevm.eth', + key: 'com.twitter', + }), + ).resolves.toMatchInlineSnapshot('"wevm_dev"') +}) diff --git a/wagmi-project/packages/core/src/actions/getEnsText.ts b/wagmi-project/packages/core/src/actions/getEnsText.ts new file mode 100644 index 0000000000..d786f72b78 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getEnsText.ts @@ -0,0 +1,30 @@ +import { + type GetEnsTextErrorType as viem_GetEnsTextErrorType, + type GetEnsTextParameters as viem_GetEnsTextParameters, + type GetEnsTextReturnType as viem_GetEnsTextReturnType, + getEnsText as viem_getEnsText, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type GetEnsTextParameters = Compute< + viem_GetEnsTextParameters & ChainIdParameter +> + +export type GetEnsTextReturnType = viem_GetEnsTextReturnType + +export type GetEnsTextErrorType = viem_GetEnsTextErrorType + +/** https://wagmi.sh/core/api/actions/getEnsText */ +export function getEnsText( + config: config, + parameters: GetEnsTextParameters, +): Promise { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction(client, viem_getEnsText, 'getEnsText') + return action(rest) +} diff --git a/wagmi-project/packages/core/src/actions/getFeeHistory.test.ts b/wagmi-project/packages/core/src/actions/getFeeHistory.test.ts new file mode 100644 index 0000000000..2630381556 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getFeeHistory.test.ts @@ -0,0 +1,63 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getFeeHistory } from './getFeeHistory.js' + +test('default', async () => { + await expect( + getFeeHistory(config, { + blockCount: 4, + rewardPercentiles: [25, 75], + }), + ).resolves.toMatchObject({ + baseFeePerGas: expect.arrayContaining([expect.any(BigInt)]), + gasUsedRatio: expect.arrayContaining([expect.any(Number)]), + oldestBlock: expect.any(BigInt), + reward: expect.any(Array), + }) +}) + +test('parameters: chainId', async () => { + await expect( + getFeeHistory(config, { + blockCount: 4, + rewardPercentiles: [25, 75], + chainId: chain.mainnet2.id, + }), + ).resolves.toMatchObject({ + baseFeePerGas: expect.arrayContaining([expect.any(BigInt)]), + gasUsedRatio: expect.arrayContaining([expect.any(Number)]), + oldestBlock: expect.any(BigInt), + reward: expect.any(Array), + }) +}) + +test('parameters: blockNumber', async () => { + await expect( + getFeeHistory(config, { + blockCount: 4, + rewardPercentiles: [25, 75], + blockNumber: 18677379n, + }), + ).resolves.toMatchObject({ + baseFeePerGas: expect.arrayContaining([expect.any(BigInt)]), + gasUsedRatio: expect.arrayContaining([expect.any(Number)]), + oldestBlock: expect.any(BigInt), + reward: expect.any(Array), + }) +}) + +test('parameters: blockTag', async () => { + await expect( + getFeeHistory(config, { + blockCount: 4, + rewardPercentiles: [25, 75], + blockTag: 'safe', + }), + ).resolves.toMatchObject({ + baseFeePerGas: expect.arrayContaining([expect.any(BigInt)]), + gasUsedRatio: expect.arrayContaining([expect.any(Number)]), + oldestBlock: expect.any(BigInt), + reward: expect.any(Array), + }) +}) diff --git a/wagmi-project/packages/core/src/actions/getFeeHistory.ts b/wagmi-project/packages/core/src/actions/getFeeHistory.ts new file mode 100644 index 0000000000..9588214139 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getFeeHistory.ts @@ -0,0 +1,36 @@ +import { + type GetFeeHistoryErrorType as viem_GetFeeHistoryErrorType, + type GetFeeHistoryParameters as viem_GetFeeHistoryParameters, + type GetFeeHistoryReturnType as viem_GetFeeHistoryReturnType, + getFeeHistory as viem_getFeeHistory, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type GetFeeHistoryParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = Compute> + +export type GetFeeHistoryReturnType = viem_GetFeeHistoryReturnType + +export type GetFeeHistoryErrorType = viem_GetFeeHistoryErrorType + +/** https://wagmi.sh/core/api/actions/getFeeHistory */ +export function getFeeHistory< + config extends Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +>( + config: config, + parameters: GetFeeHistoryParameters, +): Promise { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction(client, viem_getFeeHistory, 'getFeeHistory') + return action(rest) +} diff --git a/wagmi-project/packages/core/src/actions/getGasPrice.test.ts b/wagmi-project/packages/core/src/actions/getGasPrice.test.ts new file mode 100644 index 0000000000..64b7ba6fd5 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getGasPrice.test.ts @@ -0,0 +1,21 @@ +import { chain, config, testClient } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getGasPrice } from './getGasPrice.js' + +test('default', async () => { + await testClient.mainnet.setNextBlockBaseFeePerGas({ + baseFeePerGas: 2_000_000_000n, + }) + await expect(getGasPrice(config)).resolves.toBe(3000000000n) +}) + +test('parameters: chainId', async () => { + await testClient.mainnet2.setNextBlockBaseFeePerGas({ + baseFeePerGas: 1_000_000_000n, + }) + await testClient.mainnet2.mine({ blocks: 1 }) + await expect( + getGasPrice(config, { chainId: chain.mainnet2.id }), + ).resolves.toBe(1875000000n) +}) diff --git a/wagmi-project/packages/core/src/actions/getGasPrice.ts b/wagmi-project/packages/core/src/actions/getGasPrice.ts new file mode 100644 index 0000000000..c6482c44a2 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getGasPrice.ts @@ -0,0 +1,35 @@ +import { + type GetGasPriceErrorType as viem_GetGasPriceErrorType, + type GetGasPriceReturnType as viem_GetGasPriceReturnType, + getGasPrice as viem_getGasPrice, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type GetGasPriceParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = Compute> + +export type GetGasPriceReturnType = viem_GetGasPriceReturnType + +export type GetGasPriceErrorType = viem_GetGasPriceErrorType + +/** https://wagmi.sh/core/api/actions/getGasPrice */ +export function getGasPrice< + config extends Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +>( + config: config, + parameters: GetGasPriceParameters = {}, +): Promise { + const { chainId } = parameters + const client = config.getClient({ chainId }) + const action = getAction(client, viem_getGasPrice, 'getGasPrice') + return action({}) +} diff --git a/wagmi-project/packages/core/src/actions/getProof.test.ts b/wagmi-project/packages/core/src/actions/getProof.test.ts new file mode 100644 index 0000000000..5ff0af2828 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getProof.test.ts @@ -0,0 +1,16 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getProof } from './getProof.js' + +test('default', async () => { + await expect( + getProof(config, { + chainId: chain.optimism.id, + address: '0x4200000000000000000000000000000000000016', + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], + }), + ).resolves.toBeDefined() +}) diff --git a/wagmi-project/packages/core/src/actions/getProof.ts b/wagmi-project/packages/core/src/actions/getProof.ts new file mode 100644 index 0000000000..ee9ec218d3 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getProof.ts @@ -0,0 +1,30 @@ +import { + type GetProofErrorType as viem_GetProofErrorType, + type GetProofParameters as viem_GetProofParameters, + type GetProofReturnType as viem_GetProofReturnType, + getProof as viem_getProof, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type GetProofParameters = Compute< + viem_GetProofParameters & ChainIdParameter +> + +export type GetProofReturnType = viem_GetProofReturnType + +export type GetProofErrorType = viem_GetProofErrorType + +/** https://wagmi.sh/core/api/actions/getProof */ +export async function getProof( + config: config, + parameters: GetProofParameters, +): Promise { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction(client, viem_getProof, 'getProof') + return action(rest) +} diff --git a/wagmi-project/packages/core/src/actions/getPublicClient.test-d.ts b/wagmi-project/packages/core/src/actions/getPublicClient.test-d.ts new file mode 100644 index 0000000000..711f11a29f --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getPublicClient.test-d.ts @@ -0,0 +1,27 @@ +import { chain, config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { getPublicClient } from './getPublicClient.js' + +test('default', () => { + const client = getPublicClient(config) + expectTypeOf(client.chain).toEqualTypeOf<(typeof config)['chains'][number]>() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() +}) + +test('parameters: chainId', () => { + const client = getPublicClient(config, { + chainId: chain.mainnet.id, + }) + expectTypeOf(client.chain).toEqualTypeOf() + expectTypeOf(client.chain).not.toEqualTypeOf() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() +}) + +test('behavior: unconfigured chain', () => { + const client = getPublicClient(config, { + // @ts-expect-error + chainId: 123456, + }) + expectTypeOf(client).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/core/src/actions/getPublicClient.test.ts b/wagmi-project/packages/core/src/actions/getPublicClient.test.ts new file mode 100644 index 0000000000..c77d0bfb94 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getPublicClient.test.ts @@ -0,0 +1,17 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getPublicClient } from './getPublicClient.js' + +test('default', () => { + expect(getPublicClient(config)).toBeDefined() +}) + +test('behavior: unconfigured chain', () => { + expect( + getPublicClient(config, { + // @ts-expect-error + chainId: 123456, + }), + ).toBeUndefined() +}) diff --git a/wagmi-project/packages/core/src/actions/getPublicClient.ts b/wagmi-project/packages/core/src/actions/getPublicClient.ts new file mode 100644 index 0000000000..1fbd53ed30 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getPublicClient.ts @@ -0,0 +1,52 @@ +import { type Client, type PublicClient, publicActions } from 'viem' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute, IsNarrowable } from '../types/utils.js' +import { getClient } from './getClient.js' + +export type GetPublicClientParameters< + config extends Config = Config, + chainId extends + | config['chains'][number]['id'] + | undefined = config['chains'][number]['id'], +> = ChainIdParameter + +export type GetPublicClientReturnType< + config extends Config = Config, + chainId extends + | config['chains'][number]['id'] + | undefined = config['chains'][number]['id'], + /// + resolvedChainId extends + | config['chains'][number]['id'] + | undefined = IsNarrowable< + config['chains'][number]['id'], + number + > extends true + ? IsNarrowable extends true + ? chainId + : config['chains'][number]['id'] + : config['chains'][number]['id'] | undefined, +> = resolvedChainId extends config['chains'][number]['id'] + ? Compute< + PublicClient< + config['_internal']['transports'][resolvedChainId], + Extract + > + > + : undefined + +export function getPublicClient< + config extends Config, + chainId extends config['chains'][number]['id'] | number | undefined, +>( + config: config, + parameters: GetPublicClientParameters = {}, +): GetPublicClientReturnType { + const client = getClient(config, parameters) + return (client as Client)?.extend(publicActions) as GetPublicClientReturnType< + config, + chainId + > +} diff --git a/wagmi-project/packages/core/src/actions/getStorageAt.test.ts b/wagmi-project/packages/core/src/actions/getStorageAt.test.ts new file mode 100644 index 0000000000..bc612fe91b --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getStorageAt.test.ts @@ -0,0 +1,59 @@ +import { address, chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getStorageAt } from './getStorageAt.js' + +test('default', async () => { + await expect( + getStorageAt(config, { + address: address.wagmiMintExample, + slot: '0x0', + }), + ).resolves.toBe( + '0x7761676d6900000000000000000000000000000000000000000000000000000a', + ) + await expect( + getStorageAt(config, { + address: address.wagmiMintExample, + slot: '0x1', + }), + ).resolves.toBe( + '0x5741474d4900000000000000000000000000000000000000000000000000000a', + ) +}) + +test('parameters: blockNumber', async () => { + await expect( + getStorageAt(config, { + address: address.wagmiMintExample, + blockNumber: 16280770n, + slot: '0x0', + }), + ).resolves.toBe( + '0x7761676d6900000000000000000000000000000000000000000000000000000a', + ) +}) + +test('parameters: blockTag', async () => { + await expect( + getStorageAt(config, { + address: address.wagmiMintExample, + blockTag: 'safe', + slot: '0x0', + }), + ).resolves.toBe( + '0x7761676d6900000000000000000000000000000000000000000000000000000a', + ) +}) + +test('parameters: chainId', async () => { + await expect( + getStorageAt(config, { + address: address.wagmiMintExample, + chainId: chain.optimism.id, + slot: '0x0', + }), + ).resolves.toBe( + '0x0000000000000000000000000000000000000000000000000000000000000000', + ) +}) diff --git a/wagmi-project/packages/core/src/actions/getStorageAt.ts b/wagmi-project/packages/core/src/actions/getStorageAt.ts new file mode 100644 index 0000000000..a07ec081b7 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getStorageAt.ts @@ -0,0 +1,30 @@ +import { + type GetStorageAtErrorType as viem_GetStorageAtErrorType, + type GetStorageAtParameters as viem_GetStorageAtParameters, + type GetStorageAtReturnType as viem_GetStorageAtReturnType, + getStorageAt as viem_getStorageAt, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type GetStorageAtParameters = Compute< + viem_GetStorageAtParameters & ChainIdParameter +> + +export type GetStorageAtReturnType = viem_GetStorageAtReturnType + +export type GetStorageAtErrorType = viem_GetStorageAtErrorType + +/** https://wagmi.sh/core/api/actions/getStorageAt */ +export async function getStorageAt( + config: config, + parameters: GetStorageAtParameters, +): Promise { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction(client, viem_getStorageAt, 'getStorageAt') + return action(rest) +} diff --git a/wagmi-project/packages/core/src/actions/getToken.test.ts b/wagmi-project/packages/core/src/actions/getToken.test.ts new file mode 100644 index 0000000000..ed8903f3dd --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getToken.test.ts @@ -0,0 +1,84 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getToken } from './getToken.js' + +test('default', async () => { + await expect( + getToken(config, { + address: '0x1f9840a85d5af5bf1d1762f925bdaddc4201f984', + }), + ).resolves.toMatchInlineSnapshot(` + { + "address": "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984", + "decimals": 18, + "name": "Uniswap", + "symbol": "UNI", + "totalSupply": { + "formatted": "1000000000", + "value": 1000000000000000000000000000n, + }, + } + `) +}) + +test('parameters: formatUnits', async () => { + await expect( + getToken(config, { + address: '0x1f9840a85d5af5bf1d1762f925bdaddc4201f984', + formatUnits: 'gwei', + }), + ).resolves.toMatchInlineSnapshot(` + { + "address": "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984", + "decimals": 18, + "name": "Uniswap", + "symbol": "UNI", + "totalSupply": { + "formatted": "1000000000000000000", + "value": 1000000000000000000000000000n, + }, + } + `) +}) + +test('behavior: bytes32 token', async () => { + await expect( + getToken(config, { + address: '0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2', + }), + ).resolves.toMatchInlineSnapshot(` + { + "address": "0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2", + "decimals": 18, + "name": "Maker", + "symbol": "MKR", + "totalSupply": { + "formatted": "977631.036950888222010062", + "value": 977631036950888222010062n, + }, + } + `) +}) + +test('behavior: bogus token', async () => { + await expect( + getToken(config, { + address: '0xa0cf798816d4b9b9866b5330eea46a18382f251e', + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [ContractFunctionExecutionError: The contract function "decimals" returned no data ("0x"). + + This could be due to any of the following: + - The contract does not have the function "decimals", + - The parameters passed to the contract function may be invalid, or + - The address is not a contract. + + Contract Call: + address: 0xa0cf798816d4b9b9866b5330eea46a18382f251e + function: decimals() + + Docs: https://viem.sh/docs/contract/multicall + Version: viem@2.29.2] + `) +}) diff --git a/wagmi-project/packages/core/src/actions/getToken.ts b/wagmi-project/packages/core/src/actions/getToken.ts new file mode 100644 index 0000000000..480a742820 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getToken.ts @@ -0,0 +1,141 @@ +import type { Address, Hex } from 'viem' +import { + ContractFunctionExecutionError, + formatUnits, + hexToString, + trim, +} from 'viem' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Unit } from '../types/unit.js' +import type { Compute } from '../types/utils.js' +import { getUnit } from '../utils/getUnit.js' +import { type ReadContractsErrorType, readContracts } from './readContracts.js' + +export type GetTokenParameters = Compute< + ChainIdParameter & { + address: Address + formatUnits?: Unit | undefined + } +> + +export type GetTokenReturnType = { + address: Address + decimals: number + name: string | undefined + symbol: string | undefined + totalSupply: { + formatted: string + value: bigint + } +} + +export type GetTokenErrorType = ReadContractsErrorType + +/** @deprecated */ +export async function getToken( + config: config, + parameters: GetTokenParameters, +): Promise { + const { address, chainId, formatUnits: unit = 18 } = parameters + + function getAbi(type: type) { + return [ + { + type: 'function', + name: 'decimals', + stateMutability: 'view', + inputs: [], + outputs: [{ type: 'uint8' }], + }, + { + type: 'function', + name: 'name', + stateMutability: 'view', + inputs: [], + outputs: [{ type }], + }, + { + type: 'function', + name: 'symbol', + stateMutability: 'view', + inputs: [], + outputs: [{ type }], + }, + { + type: 'function', + name: 'totalSupply', + stateMutability: 'view', + inputs: [], + outputs: [{ type: 'uint256' }], + }, + ] as const + } + + try { + const abi = getAbi('string') + const contractConfig = { address, abi, chainId } as const + const [decimals, name, symbol, totalSupply] = await readContracts(config, { + allowFailure: true, + contracts: [ + { ...contractConfig, functionName: 'decimals' }, + { ...contractConfig, functionName: 'name' }, + { ...contractConfig, functionName: 'symbol' }, + { ...contractConfig, functionName: 'totalSupply' }, + ] as const, + }) + + // throw if `name` or `symbol` failed + if (name.error instanceof ContractFunctionExecutionError) throw name.error + if (symbol.error instanceof ContractFunctionExecutionError) + throw symbol.error + + // `decimals` and `totalSupply` are required + if (decimals.error) throw decimals.error + if (totalSupply.error) throw totalSupply.error + + return { + address, + decimals: decimals.result, + name: name.result, + symbol: symbol.result, + totalSupply: { + formatted: formatUnits(totalSupply.result!, getUnit(unit)), + value: totalSupply.result, + }, + } + } catch (error) { + // In the chance that there is an error upon decoding the contract result, + // it could be likely that the contract data is represented as bytes32 instead + // of a string. + if (error instanceof ContractFunctionExecutionError) { + const abi = getAbi('bytes32') + const contractConfig = { address, abi, chainId } as const + const [decimals, name, symbol, totalSupply] = await readContracts( + config, + { + allowFailure: false, + contracts: [ + { ...contractConfig, functionName: 'decimals' }, + { ...contractConfig, functionName: 'name' }, + { ...contractConfig, functionName: 'symbol' }, + { ...contractConfig, functionName: 'totalSupply' }, + ] as const, + }, + ) + return { + address, + decimals, + name: hexToString(trim(name as Hex, { dir: 'right' })), + symbol: hexToString(trim(symbol as Hex, { dir: 'right' })), + totalSupply: { + formatted: formatUnits(totalSupply, getUnit(unit)), + value: totalSupply, + }, + } + } + + throw error + } +} diff --git a/wagmi-project/packages/core/src/actions/getTransaction.test-d.ts b/wagmi-project/packages/core/src/actions/getTransaction.test-d.ts new file mode 100644 index 0000000000..9476b781c1 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getTransaction.test-d.ts @@ -0,0 +1,29 @@ +import { http } from 'viem' +import { celo, mainnet } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { createConfig } from '../createConfig.js' +import { getTransaction } from './getTransaction.js' + +test('chain formatters', async () => { + const config = createConfig({ + chains: [celo, mainnet], + transports: { [celo.id]: http(), [mainnet.id]: http() }, + }) + const result = await getTransaction(config, { hash: '0x123' }) + if (result.chainId === celo.id) { + expectTypeOf(result.feeCurrency).toEqualTypeOf<`0x${string}` | null>() + } +}) + +test('chainId', async () => { + const config = createConfig({ + chains: [celo, mainnet], + transports: { [celo.id]: http(), [mainnet.id]: http() }, + }) + const result = await getTransaction(config, { + hash: '0x123', + chainId: celo.id, + }) + expectTypeOf(result.feeCurrency).toEqualTypeOf<`0x${string}` | null>() +}) diff --git a/wagmi-project/packages/core/src/actions/getTransaction.test.ts b/wagmi-project/packages/core/src/actions/getTransaction.test.ts new file mode 100644 index 0000000000..3615e6a0d9 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getTransaction.test.ts @@ -0,0 +1,36 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getTransaction } from './getTransaction.js' + +test('default', async () => { + await expect( + getTransaction(config, { + hash: '0xa559259bd2d0e8372421e222ff3545f705b5da60005bd787a23c2e68d6d7fefd', + }), + ).resolves.toMatchInlineSnapshot(` + { + "accessList": [], + "blockHash": "0x61c4e868008b465addd7c0a5da03db28bb9911597c58e239a85dd14dd43fd56a", + "blockNumber": 17488642n, + "chainId": 1, + "from": "0xd2135cfb216b74109775236e36d4b433f1df507b", + "gas": 53671n, + "gasPrice": 15806335296n, + "hash": "0xa559259bd2d0e8372421e222ff3545f705b5da60005bd787a23c2e68d6d7fefd", + "input": "0xa9059cbb0000000000000000000000006acbe090725d8b1cd59fe5f3e0c9c3685ebb77af00000000000000000000000000000000000000000000000000000002540be400", + "maxFeePerGas": 19000000000n, + "maxPriorityFeePerGas": 1000000000n, + "nonce": 29, + "r": "0x60a19c4a708571d2a7c661dc5494542fa2c6ddd8e7dc218e4c4795b6ba7969f5", + "s": "0x7ef2778cc21f5c12861208d0c030e77193a234273e32a1dd5066d7d677aa1ef2", + "to": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", + "transactionIndex": 58, + "type": "eip1559", + "typeHex": "0x2", + "v": 1n, + "value": 0n, + "yParity": 1, + } + `) +}) diff --git a/wagmi-project/packages/core/src/actions/getTransaction.ts b/wagmi-project/packages/core/src/actions/getTransaction.ts new file mode 100644 index 0000000000..0148282811 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getTransaction.ts @@ -0,0 +1,51 @@ +import type { Chain } from 'viem' +import { + type GetTransactionErrorType as viem_GetTransactionErrorType, + type GetTransactionParameters as viem_GetTransactionParameters, + type GetTransactionReturnType as viem_GetTransactionReturnType, + getTransaction as viem_getTransaction, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { SelectChains } from '../types/chain.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute, IsNarrowable } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type GetTransactionParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = Compute> + +export type GetTransactionReturnType< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + /// + chains extends readonly Chain[] = SelectChains, +> = Compute< + { + [key in keyof chains]: viem_GetTransactionReturnType< + IsNarrowable extends true ? chains[key] : undefined + > & { chainId: chains[key]['id'] } + }[number] +> + +export type GetTransactionErrorType = viem_GetTransactionErrorType + +/** https://wagmi.sh/core/api/actions/getTransaction */ +export function getTransaction< + config extends Config, + chainId extends config['chains'][number]['id'], +>( + config: config, + parameters: GetTransactionParameters, +): Promise> { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction(client, viem_getTransaction, 'getTransaction') + return action(rest) as unknown as Promise< + GetTransactionReturnType + > +} diff --git a/wagmi-project/packages/core/src/actions/getTransactionConfirmations.test-d.ts b/wagmi-project/packages/core/src/actions/getTransactionConfirmations.test-d.ts new file mode 100644 index 0000000000..fd9168dfa2 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getTransactionConfirmations.test-d.ts @@ -0,0 +1,85 @@ +import { config } from '@wagmi/test' +import { mainnet, zkSync } from 'viem/chains' +import { test } from 'vitest' + +import { http } from 'viem' +import { createConfig } from '../createConfig.js' +import { getTransactionConfirmations } from './getTransactionConfirmations.js' + +test('default', async () => { + getTransactionConfirmations(config, { + transactionReceipt: { + blockHash: '0x', + blockNumber: 1n, + contractAddress: '0x', + cumulativeGasUsed: 1n, + effectiveGasPrice: 1n, + from: '0x', + gasUsed: 1n, + l1Fee: 1n, + logs: [], + logsBloom: '0x', + status: 'success', + to: '0x', + transactionHash: '0x', + transactionIndex: 1, + type: 'eip1559', + }, + }) +}) + +test('chain formatters', async () => { + const config = createConfig({ + chains: [mainnet, zkSync], + transports: { [mainnet.id]: http(), [zkSync.id]: http() }, + }) + + const transactionReceipt = { + blockHash: '0x', + blockNumber: 1n, + contractAddress: '0x', + cumulativeGasUsed: 1n, + effectiveGasPrice: 1n, + from: '0x', + gasUsed: 1n, + logsBloom: '0x', + status: 'success', + to: '0x', + transactionHash: '0x', + transactionIndex: 1, + type: 'eip1559', + } as const + + getTransactionConfirmations(config, { + transactionReceipt: { + ...transactionReceipt, + l1BatchNumber: 1n, + l1BatchTxIndex: 1n, + logs: [], + l2ToL1Logs: [], + }, + }) + + getTransactionConfirmations(config, { + chainId: zkSync.id, + transactionReceipt: { + ...transactionReceipt, + l1BatchNumber: 1n, + l1BatchTxIndex: 1n, + logs: [], + l2ToL1Logs: [], + }, + }) + + getTransactionConfirmations(config, { + chainId: mainnet.id, + transactionReceipt: { + ...transactionReceipt, + // @ts-expect-error + l1BatchNumber: 1n, + l1BatchTxIndex: 1n, + logs: [], + l2ToL1Logs: [], + }, + }) +}) diff --git a/wagmi-project/packages/core/src/actions/getTransactionConfirmations.test.ts b/wagmi-project/packages/core/src/actions/getTransactionConfirmations.test.ts new file mode 100644 index 0000000000..a2f47d6a42 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getTransactionConfirmations.test.ts @@ -0,0 +1,25 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getTransactionConfirmations } from './getTransactionConfirmations.js' +import { getTransactionReceipt } from './getTransactionReceipt.js' + +test('default', async () => { + await expect( + getTransactionConfirmations(config, { + hash: '0xa559259bd2d0e8372421e222ff3545f705b5da60005bd787a23c2e68d6d7fefd', + }), + ).resolves.toBeTypeOf('bigint') +}) + +test('parameters: transactionReceipt', async () => { + const transactionReceipt = await getTransactionReceipt(config, { + hash: '0xa559259bd2d0e8372421e222ff3545f705b5da60005bd787a23c2e68d6d7fefd', + }) + + await expect( + getTransactionConfirmations(config, { + transactionReceipt, + }), + ).resolves.toBeTypeOf('bigint') +}) diff --git a/wagmi-project/packages/core/src/actions/getTransactionConfirmations.ts b/wagmi-project/packages/core/src/actions/getTransactionConfirmations.ts new file mode 100644 index 0000000000..8baa88cf16 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getTransactionConfirmations.ts @@ -0,0 +1,52 @@ +import type { Chain } from 'viem' +import { + type GetTransactionConfirmationsErrorType as viem_GetTransactionConfirmationsErrorType, + type GetTransactionConfirmationsParameters as viem_GetTransactionConfirmationsParameters, + type GetTransactionConfirmationsReturnType as viem_GetTransactionConfirmationsReturnType, + getTransactionConfirmations as viem_getTransactionConfirmations, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { SelectChains } from '../types/chain.js' +import type { ChainIdParameter } from '../types/properties.js' +import { getAction } from '../utils/getAction.js' + +export type GetTransactionConfirmationsParameters< + config extends Config = Config, + chainId extends + | config['chains'][number]['id'] + | undefined = config['chains'][number]['id'], + /// + chains extends readonly Chain[] = SelectChains, +> = { + [key in keyof chains]: viem_GetTransactionConfirmationsParameters< + chains[key] + > & + ChainIdParameter +}[number] + +export type GetTransactionConfirmationsReturnType = + viem_GetTransactionConfirmationsReturnType + +export type GetTransactionConfirmationsErrorType = + viem_GetTransactionConfirmationsErrorType + +/** https://wagmi.sh/core/api/actions/getTransactionConfirmations */ +export function getTransactionConfirmations< + config extends Config, + chainId extends + | config['chains'][number]['id'] + | undefined = config['chains'][number]['id'], +>( + config: config, + parameters: GetTransactionConfirmationsParameters, +): Promise { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction( + client, + viem_getTransactionConfirmations, + 'getTransactionConfirmations', + ) + return action(rest as viem_GetTransactionConfirmationsParameters) +} diff --git a/wagmi-project/packages/core/src/actions/getTransactionCount.test.ts b/wagmi-project/packages/core/src/actions/getTransactionCount.test.ts new file mode 100644 index 0000000000..95f0e6ddee --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getTransactionCount.test.ts @@ -0,0 +1,50 @@ +import { accounts, chain, config, testClient } from '@wagmi/test' +import { expect, test } from 'vitest' + +import type { BlockTag } from 'viem' +import { getTransactionCount } from './getTransactionCount.js' + +const address = accounts[0] + +test('default', async () => { + await expect(getTransactionCount(config, { address })).resolves.toBeTypeOf( + 'number', + ) +}) + +test('parameters: chainId', async () => { + await testClient.mainnet2.setNonce({ + address, + nonce: 6969, + }) + await testClient.mainnet2.mine({ blocks: 1 }) + await expect( + getTransactionCount(config, { address, chainId: chain.mainnet2.id }), + ).resolves.toBeTypeOf('number') +}) + +test('parameters: blockNumber', async () => { + await expect( + getTransactionCount(config, { address, blockNumber: 13677382n }), + ).resolves.toBeTypeOf('number') +}) + +test.each([ + { blockTag: 'earliest' }, + { blockTag: 'finalized' }, + { blockTag: 'latest' }, + { blockTag: 'pending' }, + { blockTag: 'safe' }, +] as { blockTag: BlockTag; expected: number }[])( + 'parameters: blockTag $blockTag', + async ({ blockTag }) => { + await testClient.mainnet.restart() + + await expect( + getTransactionCount(config, { + address, + blockTag, + }), + ).resolves.toBeTypeOf('number') + }, +) diff --git a/wagmi-project/packages/core/src/actions/getTransactionCount.ts b/wagmi-project/packages/core/src/actions/getTransactionCount.ts new file mode 100644 index 0000000000..6872e6ede6 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getTransactionCount.ts @@ -0,0 +1,34 @@ +import { + type GetTransactionCountErrorType as viem_GetTransactionCountErrorType, + type GetTransactionCountParameters as viem_GetTransactionCountParameters, + type GetTransactionCountReturnType as viem_GetTransactionCountReturnType, + getTransactionCount as viem_getTransactionCount, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type GetTransactionCountParameters = + Compute & viem_GetTransactionCountParameters> + +export type GetTransactionCountReturnType = viem_GetTransactionCountReturnType + +export type GetTransactionCountErrorType = viem_GetTransactionCountErrorType + +/** https://wagmi.sh/core/api/actions/getTransactionCount */ +export async function getTransactionCount( + config: config, + parameters: GetTransactionCountParameters, +): Promise { + const { address, blockNumber, blockTag, chainId } = parameters + + const client = config.getClient({ chainId }) + const action = getAction( + client, + viem_getTransactionCount, + 'getTransactionCount', + ) + return action(blockNumber ? { address, blockNumber } : { address, blockTag }) +} diff --git a/wagmi-project/packages/core/src/actions/getTransactionReceipt.test-d.ts b/wagmi-project/packages/core/src/actions/getTransactionReceipt.test-d.ts new file mode 100644 index 0000000000..e9850eacc7 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getTransactionReceipt.test-d.ts @@ -0,0 +1,36 @@ +import { http } from 'viem' +import { mainnet, zkSync } from 'viem/chains' +import type { ZkSyncL2ToL1Log, ZkSyncLog } from 'viem/zksync' +import { expectTypeOf, test } from 'vitest' + +import { createConfig } from '../createConfig.js' +import { getTransactionReceipt } from './getTransactionReceipt.js' + +test('chain formatters', async () => { + const config = createConfig({ + chains: [mainnet, zkSync], + transports: { [mainnet.id]: http(), [zkSync.id]: http() }, + }) + const result = await getTransactionReceipt(config, { hash: '0x123' }) + if (result.chainId === zkSync.id) { + expectTypeOf(result.l1BatchNumber).toEqualTypeOf() + expectTypeOf(result.l1BatchTxIndex).toEqualTypeOf() + expectTypeOf(result.logs).toEqualTypeOf() + expectTypeOf(result.l2ToL1Logs).toEqualTypeOf() + } +}) + +test('chainId', async () => { + const config = createConfig({ + chains: [zkSync], + transports: { [zkSync.id]: http() }, + }) + const result = await getTransactionReceipt(config, { + hash: '0x123', + chainId: zkSync.id, + }) + expectTypeOf(result.l1BatchNumber).toEqualTypeOf() + expectTypeOf(result.l1BatchTxIndex).toEqualTypeOf() + expectTypeOf(result.logs).toEqualTypeOf() + expectTypeOf(result.l2ToL1Logs).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/core/src/actions/getTransactionReceipt.test.ts b/wagmi-project/packages/core/src/actions/getTransactionReceipt.test.ts new file mode 100644 index 0000000000..82fee0b11f --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getTransactionReceipt.test.ts @@ -0,0 +1,35 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getTransaction } from './getTransaction.js' +import { getTransactionReceipt } from './getTransactionReceipt.js' + +test('default', async () => { + const transaction = await getTransaction(config, { + blockNumber: 16280769n, + index: 0, + }) + + await expect( + getTransactionReceipt(config, { + hash: transaction.hash, + }), + ).resolves.toMatchInlineSnapshot(` + { + "blockHash": "0xb932f77cf770d1d1c8f861153eec1e990f5d56b6ffdb4ac06aef3cca51ef37d4", + "blockNumber": 16280769n, + "contractAddress": null, + "cumulativeGasUsed": 21000n, + "effectiveGasPrice": 33427926161n, + "from": "0x043022ef9fca1066024d19d681e2ccf44ff90de3", + "gasUsed": 21000n, + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "status": "success", + "to": "0x318a5fb4f1604fc46375a1db9a9018b6e423b345", + "transactionHash": "0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871", + "transactionIndex": 0, + "type": "legacy", + } + `) +}) diff --git a/wagmi-project/packages/core/src/actions/getTransactionReceipt.ts b/wagmi-project/packages/core/src/actions/getTransactionReceipt.ts new file mode 100644 index 0000000000..8c06e36ba6 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getTransactionReceipt.ts @@ -0,0 +1,57 @@ +import type { Chain } from 'viem' +import { + type GetTransactionReceiptErrorType as viem_GetTransactionReceiptErrorType, + type GetTransactionReceiptParameters as viem_GetTransactionReceiptParameters, + type GetTransactionReceiptReturnType as viem_GetTransactionReceiptReturnType, + getTransactionReceipt as viem_getTransactionReceipt, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { SelectChains } from '../types/chain.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute, IsNarrowable } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type GetTransactionReceiptParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = Compute< + viem_GetTransactionReceiptParameters & ChainIdParameter +> + +export type GetTransactionReceiptReturnType< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + /// + chains extends readonly Chain[] = SelectChains, +> = Compute< + { + [key in keyof chains]: viem_GetTransactionReceiptReturnType< + IsNarrowable extends true ? chains[key] : undefined + > & { chainId: chains[key]['id'] } + }[number] +> + +export type GetTransactionReceiptErrorType = viem_GetTransactionReceiptErrorType + +/** https://wagmi.sh/core/api/actions/getTransactionReceipt */ +export async function getTransactionReceipt< + config extends Config, + chainId extends config['chains'][number]['id'], +>( + config: config, + parameters: GetTransactionReceiptParameters, +): Promise> { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction( + client, + viem_getTransactionReceipt, + 'getTransactionReceipt', + ) + return action(rest) as unknown as Promise< + GetTransactionReceiptReturnType + > +} diff --git a/wagmi-project/packages/core/src/actions/getWalletClient.test-d.ts b/wagmi-project/packages/core/src/actions/getWalletClient.test-d.ts new file mode 100644 index 0000000000..d1d87f5e97 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getWalletClient.test-d.ts @@ -0,0 +1,22 @@ +import { chain, config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import type { Account } from 'viem' +import { getWalletClient } from './getWalletClient.js' + +test('default', async () => { + const client = await getWalletClient(config) + expectTypeOf(client.chain).toEqualTypeOf<(typeof config)['chains'][number]>() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() + expectTypeOf(client.account).toEqualTypeOf() +}) + +test('parameters: chainId', async () => { + const client = await getWalletClient(config, { + chainId: chain.mainnet.id, + }) + expectTypeOf(client.chain).toEqualTypeOf() + expectTypeOf(client.chain).not.toEqualTypeOf() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() + expectTypeOf(client.account).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/core/src/actions/getWalletClient.test.ts b/wagmi-project/packages/core/src/actions/getWalletClient.test.ts new file mode 100644 index 0000000000..2350f81b3e --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getWalletClient.test.ts @@ -0,0 +1,24 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { getWalletClient } from './getWalletClient.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + await expect(getWalletClient(config)).resolves.toBeDefined() + await disconnect(config, { connector }) +}) + +test('behavior: not connected', async () => { + await expect( + getWalletClient(config), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [ConnectorNotConnectedError: Connector not connected. + + Version: @wagmi/core@x.y.z] + `) +}) diff --git a/wagmi-project/packages/core/src/actions/getWalletClient.ts b/wagmi-project/packages/core/src/actions/getWalletClient.ts new file mode 100644 index 0000000000..bf49668701 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/getWalletClient.ts @@ -0,0 +1,50 @@ +import { type Account, type WalletClient, walletActions } from 'viem' + +import type { Config } from '../createConfig.js' +import type { BaseErrorType, ErrorType } from '../errors/base.js' +import type { Compute } from '../types/utils.js' +import { + type GetConnectorClientErrorType, + type GetConnectorClientParameters, + getConnectorClient, +} from './getConnectorClient.js' + +export type GetWalletClientParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = GetConnectorClientParameters + +export type GetWalletClientReturnType< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = Compute< + WalletClient< + config['_internal']['transports'][chainId], + Extract, + Account + > +> + +export type GetWalletClientErrorType = + // getConnectorClient() + | GetConnectorClientErrorType + // base + | BaseErrorType + | ErrorType + +export async function getWalletClient< + config extends Config, + chainId extends config['chains'][number]['id'], +>( + config: config, + parameters: GetWalletClientParameters = {}, +): Promise> { + const client = await getConnectorClient(config, parameters) + // @ts-ignore + return client.extend(walletActions) as unknown as GetWalletClientReturnType< + config, + chainId + > +} diff --git a/wagmi-project/packages/core/src/actions/multicall.test-d.ts b/wagmi-project/packages/core/src/actions/multicall.test-d.ts new file mode 100644 index 0000000000..bb70db9989 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/multicall.test-d.ts @@ -0,0 +1,106 @@ +import { abi, config } from '@wagmi/test' +import type { Address } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { multicall } from './multicall.js' + +test('default', async () => { + const result = await multicall(config, { + chainId: 1, + contracts: [ + { + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + }, + { + address: '0x', + abi: abi.wagmiMintExample, + functionName: 'tokenURI', + args: [123n], + }, + ], + }) + expectTypeOf(result).toEqualTypeOf< + [ + ( + | { error: Error; result?: undefined; status: 'failure' } + | { error?: undefined; result: bigint; status: 'success' } + ), + ( + | { error: Error; result?: undefined; status: 'failure' } + | { error?: undefined; result: string; status: 'success' } + ), + ] + >() +}) + +test('allowFailure', async () => { + const result = await multicall(config, { + allowFailure: false, + contracts: [ + { + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + }, + { + address: '0x', + abi: abi.wagmiMintExample, + functionName: 'tokenURI', + args: [123n], + }, + ], + }) + expectTypeOf(result).toEqualTypeOf<[bigint, string]>() +}) + +test('MulticallParameters', async () => { + type Result = Parameters< + typeof multicall< + typeof config, + [ + { + address: '0x' + abi: typeof abi.viewOverloads + functionName: 'foo' + }, + ] + > + >[1]['contracts'][0] + expectTypeOf().toEqualTypeOf<'foo' | 'bar'>() + expectTypeOf().toEqualTypeOf< + readonly [] | readonly [Address] | readonly [Address, Address] | undefined + >() +}) + +test('overloads', async () => { + const res = await multicall(config, { + allowFailure: false, + contracts: [ + { + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + }, + { + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: ['0x'], + }, + { + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: ['0x', '0x'], + }, + ], + }) + + expectTypeOf(res).toEqualTypeOf< + [number, string, { foo: Address; bar: Address }] + >() +}) diff --git a/wagmi-project/packages/core/src/actions/multicall.test.ts b/wagmi-project/packages/core/src/actions/multicall.test.ts new file mode 100644 index 0000000000..cf2d7c0ddf --- /dev/null +++ b/wagmi-project/packages/core/src/actions/multicall.test.ts @@ -0,0 +1,46 @@ +import { abi, address, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { multicall } from './multicall.js' + +test('default', async () => { + await expect( + multicall(config, { + contracts: [ + { + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'balanceOf', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }, + ], + }), + ).resolves.toMatchInlineSnapshot(` + [ + { + "result": 4n, + "status": "success", + }, + ] + `) +}) + +test('allowFailure', async () => { + await expect( + multicall(config, { + allowFailure: false, + contracts: [ + { + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'balanceOf', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }, + ], + }), + ).resolves.toMatchInlineSnapshot(` + [ + 4n, + ] + `) +}) diff --git a/wagmi-project/packages/core/src/actions/multicall.ts b/wagmi-project/packages/core/src/actions/multicall.ts new file mode 100644 index 0000000000..528bb0118e --- /dev/null +++ b/wagmi-project/packages/core/src/actions/multicall.ts @@ -0,0 +1,42 @@ +import type { + ContractFunctionParameters, + MulticallErrorType as viem_MulticallErrorType, + MulticallParameters as viem_MulticallParameters, + MulticallReturnType as viem_MulticallReturnType, +} from 'viem' +import { multicall as viem_multicall } from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import { getAction } from '../utils/getAction.js' + +export type MulticallParameters< + contracts extends readonly unknown[] = readonly ContractFunctionParameters[], + allowFailure extends boolean = true, + config extends Config = Config, +> = viem_MulticallParameters & ChainIdParameter + +export type MulticallReturnType< + contracts extends readonly unknown[] = readonly ContractFunctionParameters[], + allowFailure extends boolean = true, +> = viem_MulticallReturnType + +export type MulticallErrorType = viem_MulticallErrorType + +export async function multicall< + config extends Config, + const contracts extends readonly ContractFunctionParameters[], + allowFailure extends boolean = true, +>( + config: config, + parameters: MulticallParameters, +): Promise> { + const { allowFailure = true, chainId, contracts, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction(client, viem_multicall, 'multicall') + return action({ + allowFailure, + contracts, + ...rest, + }) as Promise> +} diff --git a/wagmi-project/packages/core/src/actions/prepareTransactionRequest.test-d.ts b/wagmi-project/packages/core/src/actions/prepareTransactionRequest.test-d.ts new file mode 100644 index 0000000000..a8a0091157 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/prepareTransactionRequest.test-d.ts @@ -0,0 +1,80 @@ +import { accounts, config } from '@wagmi/test' +import { http, parseEther } from 'viem' +import { celo, mainnet } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { createConfig } from '../createConfig.js' +import { + type PrepareTransactionRequestParameters, + prepareTransactionRequest, +} from './prepareTransactionRequest.js' + +const targetAccount = accounts[1] + +test('default', async () => { + const response = await prepareTransactionRequest(config, { + chainId: 1, + to: '0x', + value: parseEther('1'), + }) + const { nonce: _nonce, ...request } = response + request.to + request.chainId + + expectTypeOf(response).toMatchTypeOf<{ + chainId: 1 + }>() +}) + +test('chain formatters', async () => { + const config = createConfig({ + chains: [celo, mainnet], + transports: { [celo.id]: http(), [mainnet.id]: http() }, + }) + + type Result = PrepareTransactionRequestParameters + expectTypeOf().toMatchTypeOf<{ + chainId?: typeof celo.id | typeof mainnet.id | undefined + feeCurrency?: `0x${string}` | undefined + }>() + const request = await prepareTransactionRequest(config, { + to: targetAccount, + value: parseEther('0.01'), + feeCurrency: '0x', + }) + if (request.chainId === celo.id) { + expectTypeOf(request.chainId).toEqualTypeOf(celo.id) + expectTypeOf(request.feeCurrency).toEqualTypeOf<`0x${string}` | undefined>() + } + + type Result2 = PrepareTransactionRequestParameters< + typeof config, + typeof celo.id + > + expectTypeOf().toMatchTypeOf<{ + feeCurrency?: `0x${string}` | undefined + }>() + const request2 = await prepareTransactionRequest(config, { + chainId: celo.id, + to: targetAccount, + value: parseEther('0.01'), + feeCurrency: '0x', + }) + expectTypeOf(request2.chainId).toEqualTypeOf(celo.id) + expectTypeOf(request2.feeCurrency).toEqualTypeOf<`0x${string}` | undefined>() + + type Result3 = PrepareTransactionRequestParameters< + typeof config, + typeof mainnet.id + > + expectTypeOf().not.toMatchTypeOf<{ + feeCurrency?: `0x${string}` | undefined + }>() + prepareTransactionRequest(config, { + chainId: mainnet.id, + to: targetAccount, + value: parseEther('0.01'), + // @ts-expect-error + feeCurrency: '0x', + }) +}) diff --git a/wagmi-project/packages/core/src/actions/prepareTransactionRequest.test.ts b/wagmi-project/packages/core/src/actions/prepareTransactionRequest.test.ts new file mode 100644 index 0000000000..271037af8f --- /dev/null +++ b/wagmi-project/packages/core/src/actions/prepareTransactionRequest.test.ts @@ -0,0 +1,108 @@ +import { accounts, config, privateKey } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { parseEther } from 'viem' +import { privateKeyToAccount } from 'viem/accounts' +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { prepareTransactionRequest } from './prepareTransactionRequest.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const request = await prepareTransactionRequest(config, { + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), + }) + + const { + gas: _gas, + maxFeePerGas: _mfpg, + maxPriorityFeePerGas: _mpfpg, + nonce: _nonce, + ...rest + } = request + expect(rest).toMatchInlineSnapshot(` + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 1, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "to": "0x70997970c51812dc3a010c7d01b50e0d17dc79c8", + "type": "eip1559", + "value": 1000000000000000000n, + } + `) + + await disconnect(config, { connector }) +}) + +test('parameters: account', async () => { + await connect(config, { connector }) + + const request = await prepareTransactionRequest(config, { + account: accounts[0], + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), + }) + + const { + gas: _gas, + maxFeePerGas: _mfpg, + maxPriorityFeePerGas: _mpfpg, + nonce: _nonce, + ...rest + } = request + expect(rest).toMatchInlineSnapshot(` + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 1, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "to": "0x70997970c51812dc3a010c7d01b50e0d17dc79c8", + "type": "eip1559", + "value": 1000000000000000000n, + } + `) + + await disconnect(config, { connector }) +}) + +test('behavior: local account', async () => { + const account = privateKeyToAccount(privateKey) + + const request = await prepareTransactionRequest(config, { + account, + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), + }) + + const { + gas: _gas, + maxFeePerGas: _mfpg, + maxPriorityFeePerGas: _mpfpg, + nonce: _nonce, + ...rest + } = request + expect(rest).toMatchInlineSnapshot(` + { + "account": { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "nonceManager": undefined, + "publicKey": "0x048318535b54105d4a7aae60c08fc45f9687181b4fdfc625bd1a753fa7397fed753547f11ca8696646f2f3acb08e31016afac23e630c5d11f59f61fef57b0d2aa5", + "sign": [Function], + "signAuthorization": [Function], + "signMessage": [Function], + "signTransaction": [Function], + "signTypedData": [Function], + "source": "privateKey", + "type": "local", + }, + "chainId": 1, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "to": "0x70997970c51812dc3a010c7d01b50e0d17dc79c8", + "type": "eip1559", + "value": 1000000000000000000n, + } + `) +}) diff --git a/wagmi-project/packages/core/src/actions/prepareTransactionRequest.ts b/wagmi-project/packages/core/src/actions/prepareTransactionRequest.ts new file mode 100644 index 0000000000..36ed81f774 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/prepareTransactionRequest.ts @@ -0,0 +1,125 @@ +import type { + Account, + Address, + Chain, + PrepareTransactionRequestErrorType as viem_PrepareTransactionRequestErrorType, + PrepareTransactionRequestParameters as viem_PrepareTransactionRequestParameters, + PrepareTransactionRequestRequest as viem_PrepareTransactionRequestRequest, + PrepareTransactionRequestReturnType as viem_PrepareTransactionRequestReturnType, +} from 'viem' +import { prepareTransactionRequest as viem_prepareTransactionRequest } from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { SelectChains } from '../types/chain.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { + Compute, + IsNarrowable, + UnionCompute, + UnionStrictOmit, +} from '../types/utils.js' +import { getAction } from '../utils/getAction.js' +import { getAccount } from './getAccount.js' + +export type PrepareTransactionRequestParameters< + config extends Config = Config, + chainId extends + | config['chains'][number]['id'] + | undefined = config['chains'][number]['id'], + request extends viem_PrepareTransactionRequestRequest< + SelectChains[0], + SelectChains[0] + > = viem_PrepareTransactionRequestRequest< + SelectChains[0], + SelectChains[0] + >, + /// + chains extends readonly Chain[] = SelectChains, +> = { + [key in keyof chains]: UnionCompute< + UnionStrictOmit< + viem_PrepareTransactionRequestParameters< + chains[key], + Account, + chains[key], + Account | Address, + request extends viem_PrepareTransactionRequestRequest< + chains[key], + chains[key] + > + ? request + : never + >, + 'chain' + > & + ChainIdParameter & { + to: Address + } + > +}[number] + +export type PrepareTransactionRequestReturnType< + config extends Config = Config, + chainId extends + | config['chains'][number]['id'] + | undefined = config['chains'][number]['id'], + request extends viem_PrepareTransactionRequestRequest< + SelectChains[0], + SelectChains[0] + > = viem_PrepareTransactionRequestRequest< + SelectChains[0], + SelectChains[0] + >, + /// + chains extends readonly Chain[] = SelectChains, +> = { + [key in keyof chains]: Compute< + viem_PrepareTransactionRequestReturnType< + IsNarrowable extends true ? chains[key] : undefined, + Account, + chains[key], + Account, + request extends viem_PrepareTransactionRequestRequest< + IsNarrowable extends true ? chains[key] : undefined, + chains[key] + > + ? request + : never + > + > & { + chainId: chains[key]['id'] + } +}[number] + +export type PrepareTransactionRequestErrorType = + viem_PrepareTransactionRequestErrorType + +/** https://wagmi.sh/core/api/actions/prepareTransactionRequest */ +export async function prepareTransactionRequest< + config extends Config, + chainId extends config['chains'][number]['id'] | undefined, + const request extends viem_PrepareTransactionRequestRequest< + SelectChains['0'], + SelectChains['0'] + >, +>( + config: config, + parameters: PrepareTransactionRequestParameters, +): Promise> { + const { account: account_, chainId, ...rest } = parameters + + const account = account_ ?? getAccount(config).address + const client = config.getClient({ chainId }) + + const action = getAction( + client, + viem_prepareTransactionRequest, + 'prepareTransactionRequest', + ) + return action({ + ...rest, + ...(account ? { account } : {}), + } as unknown as viem_PrepareTransactionRequestParameters) as unknown as Promise< + PrepareTransactionRequestReturnType + > +} diff --git a/wagmi-project/packages/core/src/actions/readContract.test-d.ts b/wagmi-project/packages/core/src/actions/readContract.test-d.ts new file mode 100644 index 0000000000..a667ec03e8 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/readContract.test-d.ts @@ -0,0 +1,74 @@ +import { abi, config } from '@wagmi/test' +import { assertType, expectTypeOf, test } from 'vitest' + +import { readContract } from './readContract.js' + +test('default', async () => { + const result = await readContract(config, { + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + }) + expectTypeOf(result).toEqualTypeOf() +}) + +test('overloads', async () => { + const result1 = await readContract(config, { + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + }) + assertType(result1) + + const result2 = await readContract(config, { + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: [], + }) + assertType(result2) + + const result3 = await readContract(config, { + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: ['0x'], + }) + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + assertType(result3) + + const result4 = await readContract(config, { + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: ['0x', '0x'], + }) + assertType<{ + foo: `0x${string}` + bar: `0x${string}` + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + }>(result4) +}) + +test('deployless read (bytecode)', async () => { + const result = await readContract(config, { + code: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + }) + expectTypeOf(result).toEqualTypeOf() +}) + +test('deployless read (factory)', async () => { + const result = await readContract(config, { + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + factory: '0x', + factoryData: '0x', + }) + expectTypeOf(result).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/core/src/actions/readContract.test.ts b/wagmi-project/packages/core/src/actions/readContract.test.ts new file mode 100644 index 0000000000..37f0db7e0c --- /dev/null +++ b/wagmi-project/packages/core/src/actions/readContract.test.ts @@ -0,0 +1,37 @@ +import { abi, address, bytecode, chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { readContract } from './readContract.js' + +test('default', async () => { + await expect( + readContract(config, { + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'balanceOf', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }), + ).resolves.toMatchInlineSnapshot('4n') +}) + +test('parameters: chainId', async () => { + await expect( + readContract(config, { + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'balanceOf', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + chainId: chain.mainnet2.id, + }), + ).resolves.toMatchInlineSnapshot('4n') +}) + +test('parameters: deployless read (bytecode)', async () => { + await expect( + readContract(config, { + abi: abi.wagmiMintExample, + functionName: 'name', + code: bytecode.wagmiMintExample, + }), + ).resolves.toMatchInlineSnapshot(`"wagmi"`) +}) diff --git a/wagmi-project/packages/core/src/actions/readContract.ts b/wagmi-project/packages/core/src/actions/readContract.ts new file mode 100644 index 0000000000..e01e74e9f2 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/readContract.ts @@ -0,0 +1,58 @@ +import type { Abi } from 'viem' +import type { ContractFunctionArgs, ContractFunctionName } from 'viem' +import { + type ReadContractErrorType as viem_ReadContractErrorType, + type ReadContractParameters as viem_ReadContractParameters, + type ReadContractReturnType as viem_ReadContractReturnType, + readContract as viem_readContract, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import { getAction } from '../utils/getAction.js' + +export type ReadContractParameters< + abi extends Abi | readonly unknown[] = Abi, + functionName extends ContractFunctionName< + abi, + 'pure' | 'view' + > = ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'pure' | 'view', + functionName + > = ContractFunctionArgs, + config extends Config = Config, +> = viem_ReadContractParameters & + ChainIdParameter + +export type ReadContractReturnType< + abi extends Abi | readonly unknown[] = Abi, + functionName extends ContractFunctionName< + abi, + 'pure' | 'view' + > = ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'pure' | 'view', + functionName + > = ContractFunctionArgs, +> = viem_ReadContractReturnType + +export type ReadContractErrorType = viem_ReadContractErrorType + +/** https://wagmi.sh/core/api/actions/readContract */ +export function readContract< + config extends Config, + const abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs, +>( + config: config, + parameters: ReadContractParameters, +): Promise> { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction(client, viem_readContract, 'readContract') + return action(rest as any) +} diff --git a/wagmi-project/packages/core/src/actions/readContracts.test-d.ts b/wagmi-project/packages/core/src/actions/readContracts.test-d.ts new file mode 100644 index 0000000000..a68b2acab6 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/readContracts.test-d.ts @@ -0,0 +1,118 @@ +import { abi, config } from '@wagmi/test' +import { assertType, expectTypeOf, test } from 'vitest' + +import { readContracts } from './readContracts.js' + +test('default', async () => { + const result = await readContracts(config, { + contracts: [ + { + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + chainId: 1, + }, + { + address: '0x', + abi: abi.wagmiMintExample, + functionName: 'tokenURI', + args: [123n], + }, + ], + }) + expectTypeOf(result).toEqualTypeOf< + [ + ( + | { error: Error; result?: undefined; status: 'failure' } + | { error?: undefined; result: bigint; status: 'success' } + ), + ( + | { error: Error; result?: undefined; status: 'failure' } + | { error?: undefined; result: string; status: 'success' } + ), + ] + >() +}) + +test('allowFailure', async () => { + const result = await readContracts(config, { + allowFailure: false, + contracts: [ + { + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + }, + { + address: '0x', + abi: abi.wagmiMintExample, + functionName: 'tokenURI', + args: [123n], + }, + ], + }) + expectTypeOf(result).toEqualTypeOf<[bigint, string]>() +}) + +test('overloads', async () => { + const result1 = await readContracts(config, { + allowFailure: false, + contracts: [ + { + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + }, + ], + }) + assertType<[number] | undefined>(result1) + + const result2 = await readContracts(config, { + allowFailure: false, + contracts: [ + { + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: [], + }, + ], + }) + assertType<[number] | undefined>(result2) + + const result3 = await readContracts(config, { + allowFailure: false, + contracts: [ + { + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: ['0x'], + }, + ], + }) + assertType<[string] | undefined>(result3) + + const result4 = await readContracts(config, { + allowFailure: false, + contracts: [ + { + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: ['0x', '0x'], + }, + ], + }) + assertType< + | [ + { + foo: `0x${string}` + bar: `0x${string}` + }, + ] + | undefined + >(result4) +}) diff --git a/wagmi-project/packages/core/src/actions/readContracts.test.ts b/wagmi-project/packages/core/src/actions/readContracts.test.ts new file mode 100644 index 0000000000..4bc33f60da --- /dev/null +++ b/wagmi-project/packages/core/src/actions/readContracts.test.ts @@ -0,0 +1,678 @@ +import { abi, address, chain } from '@wagmi/test' +import { http, type MulticallResponse } from 'viem' +import { expect, expectTypeOf, test, vi } from 'vitest' + +import { createConfig } from '../createConfig.js' +import * as multicall from './multicall.js' +import * as readContract from './readContract.js' +import { readContracts } from './readContracts.js' + +const contracts = [ + { + abi: abi.wagmigotchi, + address: address.wagmigotchi, + functionName: 'love', + args: ['0x27a69ffba1e939ddcfecc8c7e0f967b872bac65c'], + }, + { + abi: abi.wagmigotchi, + address: address.wagmigotchi, + functionName: 'love', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }, + { + abi: abi.wagmigotchi, + address: address.wagmigotchi, + functionName: 'getAlive', + }, + { + abi: abi.mloot, + address: address.mloot, + functionName: 'tokenOfOwnerByIndex', + args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', 0n], + }, +] + +const { mainnet, mainnet2, optimism } = chain + +const config = createConfig({ + chains: [ + { ...mainnet, contracts: { multicall3: undefined } }, + { ...mainnet2, contracts: { multicall3: undefined } }, + ], + transports: { + [mainnet.id]: http(), + [mainnet2.id]: http(), + }, +}) + +test('default', async () => { + const spy = vi.spyOn(multicall, 'multicall') + const config = createConfig({ + chains: [mainnet, mainnet2], + transports: { + [mainnet.id]: http(), + [mainnet2.id]: http(), + }, + }) + const results = await readContracts(config, { contracts }) + + expect(spy).toHaveBeenCalledWith(config, { + allowFailure: true, + contracts, + chainId: mainnet.id, + }) + expect(results).toMatchInlineSnapshot(` + [ + { + "result": 2n, + "status": "success", + }, + { + "result": 1n, + "status": "success", + }, + { + "result": false, + "status": "success", + }, + { + "result": 370395n, + "status": "success", + }, + ] + `) +}) + +test.skip('falls back to readContract if multicall is not available', async () => { + const spy = vi.spyOn(readContract, 'readContract') + const config = createConfig({ + chains: [mainnet, { ...mainnet2, contracts: { multicall3: undefined } }], + transports: { + [mainnet.id]: http(), + [mainnet2.id]: http(), + }, + }) + const chainId = mainnet2.id + const contracts = [ + { + abi: abi.wagmigotchi, + address: address.wagmigotchi, + chainId: mainnet2.id, + functionName: 'love', + args: ['0x27a69ffba1e939ddcfecc8c7e0f967b872bac65c'], + }, + { + abi: abi.wagmigotchi, + address: address.wagmigotchi, + chainId: mainnet2.id, + functionName: 'love', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }, + { + abi: abi.wagmigotchi, + address: address.wagmigotchi, + chainId: mainnet2.id, + functionName: 'getAlive', + }, + { + abi: abi.mloot, + address: address.mloot, + chainId: mainnet2.id, + functionName: 'tokenOfOwnerByIndex', + args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', 0n], + }, + ] as const + const results = await readContracts(config, { contracts }) + expectTypeOf(results).toEqualTypeOf< + [ + MulticallResponse, + MulticallResponse, + MulticallResponse, + MulticallResponse, + ] + >() + + for (const contract of contracts) { + expect(spy).toBeCalledWith(config, { ...contract, chainId }) + } + expect(results).toMatchInlineSnapshot(` + [ + { + "result": 2n, + "status": "success", + }, + { + "result": 1n, + "status": "success", + }, + { + "result": false, + "status": "success", + }, + { + "result": 370395n, + "status": "success", + }, + ] + `) +}) + +test.skip('multichain', async () => { + const config = createConfig({ + chains: [mainnet, mainnet2, optimism], + transports: { + [mainnet.id]: http(), + [mainnet2.id]: http(), + [optimism.id]: http(), + }, + }) + + const spy = vi.spyOn(multicall, 'multicall') + const mainnetContracts = [ + { + abi: abi.wagmigotchi, + address: address.wagmigotchi, + chainId: mainnet.id, + functionName: 'love', + args: ['0x27a69ffba1e939ddcfecc8c7e0f967b872bac65c'], + }, + { + abi: abi.wagmigotchi, + address: address.wagmigotchi, + chainId: mainnet.id, + functionName: 'love', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }, + { + abi: abi.wagmigotchi, + address: address.wagmigotchi, + chainId: mainnet.id, + functionName: 'love', + args: ['0xd2135CfB216b74109775236E36d4b433F1DF507B'], + }, + ] as const + const mainnet2Contracts = [ + { + abi: abi.wagmigotchi, + address: address.wagmigotchi, + chainId: mainnet2.id, + functionName: 'getAlive', + }, + { + abi: abi.mloot, + address: address.mloot, + chainId: mainnet2.id, + functionName: 'tokenOfOwnerByIndex', + args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', 0n], + }, + ] as const + const optimismContracts = [ + { + abi: abi.erc20, + address: address.optimism.usdc, + chainId: optimism.id, + functionName: 'symbol', + }, + { + abi: abi.erc20, + address: address.optimism.usdc, + chainId: optimism.id, + functionName: 'balanceOf', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }, + ] as const + const results = await readContracts(config, { + contracts: [ + mainnetContracts[0]!, + optimismContracts[0]!, + mainnetContracts[1]!, + mainnet2Contracts[0]!, + optimismContracts[1]!, + mainnet2Contracts[1]!, + mainnetContracts[2]!, + ], + }) + expectTypeOf(results).toEqualTypeOf< + [ + MulticallResponse, + MulticallResponse, + MulticallResponse, + MulticallResponse, + MulticallResponse, + MulticallResponse, + MulticallResponse, + ] + >() + + expect(spy).toHaveBeenCalledWith(config, { + allowFailure: true, + contracts: mainnetContracts, + chainId: mainnet.id, + overrides: undefined, + }) + expect(spy).toHaveBeenCalledWith(config, { + allowFailure: true, + contracts: mainnet2Contracts, + chainId: mainnet2.id, + overrides: undefined, + }) + expect(results).toMatchInlineSnapshot(` + [ + { + "result": 2n, + "status": "success", + }, + { + "result": "USDC", + "status": "success", + }, + { + "result": 1n, + "status": "success", + }, + { + "result": false, + "status": "success", + }, + { + "result": 10959340n, + "status": "success", + }, + { + "result": 370395n, + "status": "success", + }, + { + "result": 0n, + "status": "success", + }, + ] + `) +}) + +test('multi-chain: falls back to readContract if multicall is not available', async () => { + const config = createConfig({ + chains: [mainnet, { ...optimism, contracts: { multicall3: undefined } }], + transports: { + [mainnet.id]: http(), + [optimism.id]: http(), + }, + }) + + const spy = vi.spyOn(readContract, 'readContract') + const mainnetContracts = [ + { + abi: abi.wagmigotchi, + address: address.wagmigotchi, + chainId: mainnet.id, + functionName: 'love', + args: ['0x27a69ffba1e939ddcfecc8c7e0f967b872bac65c'], + }, + { + abi: abi.wagmigotchi, + address: address.wagmigotchi, + chainId: mainnet.id, + functionName: 'love', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }, + ] as const + const optimismContracts = [ + { + abi: abi.erc20, + address: address.optimism.usdc, + chainId: optimism.id, + functionName: 'symbol', + }, + { + abi: abi.erc20, + address: address.optimism.usdc, + chainId: optimism.id, + functionName: 'balanceOf', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }, + ] as const + const results = await readContracts(config, { + contracts: [...mainnetContracts, ...optimismContracts], + }) + expectTypeOf(results).toEqualTypeOf< + [ + MulticallResponse, + MulticallResponse, + MulticallResponse, + MulticallResponse, + ] + >() + + for (const contract of mainnetContracts) { + expect(spy).toBeCalledWith(config, { ...contract, chainId: mainnet.id }) + } + for (const contract of optimismContracts) { + expect(spy).toBeCalledWith(config, { ...contract, chainId: optimism.id }) + } + expect(results).toMatchInlineSnapshot(` + [ + { + "result": 2n, + "status": "success", + }, + { + "result": 1n, + "status": "success", + }, + { + "result": "USDC", + "status": "success", + }, + { + "result": 10959340n, + "status": "success", + }, + ] + `) +}) + +test('throws if allowFailure=false & a contract method fails', async () => { + await expect( + readContracts(config, { + allowFailure: false, + contracts: [ + ...contracts, + { + abi: abi.mloot, + address: address.mloot, + functionName: 'tokenOfOwnerByIndex', + args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', 69420n], + }, + ], + }), + ).rejects.toThrowErrorMatchingInlineSnapshot( + ` + [ContractFunctionExecutionError: The contract function "tokenOfOwnerByIndex" reverted with the following reason: + ERC721Enumerable: owner index out of bounds + + Contract Call: + address: 0x1dfe7ca09e99d10835bf73044a23b73fc20623df + function: tokenOfOwnerByIndex(address owner, uint256 index) + args: (0xA0Cf798816D4b9b9866b5330EEa46a18382f251e, 69420) + + Docs: https://viem.sh/docs/contract/readContract + Version: viem@2.29.2] + `, + ) +}) + +test('allowFailure=true & a contract method fails', async () => { + expect( + await readContracts(config, { + allowFailure: true, + contracts: [ + ...contracts, + { + abi: abi.mloot, + address: address.mloot, + functionName: 'tokenOfOwnerByIndex', + args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', 69420n], + }, + { + abi: abi.mloot, + address: address.mloot, + functionName: 'tokenOfOwnerByIndex', + args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', 69421n], + }, + ], + }), + ).toMatchInlineSnapshot(` + [ + { + "result": 2n, + "status": "success", + }, + { + "result": 1n, + "status": "success", + }, + { + "result": false, + "status": "success", + }, + { + "result": 370395n, + "status": "success", + }, + { + "error": [ContractFunctionExecutionError: The contract function "tokenOfOwnerByIndex" reverted with the following reason: + ERC721Enumerable: owner index out of bounds + + Contract Call: + address: 0x1dfe7ca09e99d10835bf73044a23b73fc20623df + function: tokenOfOwnerByIndex(address owner, uint256 index) + args: (0xA0Cf798816D4b9b9866b5330EEa46a18382f251e, 69420) + + Docs: https://viem.sh/docs/contract/readContract + Version: viem@2.29.2], + "result": undefined, + "status": "failure", + }, + { + "error": [ContractFunctionExecutionError: The contract function "tokenOfOwnerByIndex" reverted with the following reason: + ERC721Enumerable: owner index out of bounds + + Contract Call: + address: 0x1dfe7ca09e99d10835bf73044a23b73fc20623df + function: tokenOfOwnerByIndex(address owner, uint256 index) + args: (0xA0Cf798816D4b9b9866b5330EEa46a18382f251e, 69421) + + Docs: https://viem.sh/docs/contract/readContract + Version: viem@2.29.2], + "result": undefined, + "status": "failure", + }, + ] + `) +}) + +test('throws if allowFailure=false & encoding contract function data fails', async () => { + await expect( + readContracts(config, { + allowFailure: false, + contracts: [ + ...contracts, + { + abi: abi.mloot, + functionName: 'ownerOf', + // address is not the mloot contract + address: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + args: [10e30], + }, + ], + }), + ).rejects.toThrowErrorMatchingInlineSnapshot( + ` + [ContractFunctionExecutionError: The contract function "ownerOf" returned no data ("0x"). + + This could be due to any of the following: + - The contract does not have the function "ownerOf", + - The parameters passed to the contract function may be invalid, or + - The address is not a contract. + + Contract Call: + address: 0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC + function: ownerOf(uint256 tokenId) + args: (1e+31) + + Docs: https://viem.sh/docs/contract/readContract + Version: viem@2.29.2] + `, + ) +}) + +test('allowFailure=true & encoding contract function data fails', async () => { + expect( + await readContracts(config, { + allowFailure: true, + contracts: [ + ...contracts, + { + abi: abi.mloot, + functionName: 'ownerOf', + // address is not the mloot contract + address: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + args: [10e30], + }, + { + abi: abi.mloot, + functionName: 'ownerOf', + // address is not the mloot contract + address: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + args: [10e30], + }, + ], + }), + ).toMatchInlineSnapshot(` + [ + { + "result": 2n, + "status": "success", + }, + { + "result": 1n, + "status": "success", + }, + { + "result": false, + "status": "success", + }, + { + "result": 370395n, + "status": "success", + }, + { + "error": [ContractFunctionExecutionError: The contract function "ownerOf" returned no data ("0x"). + + This could be due to any of the following: + - The contract does not have the function "ownerOf", + - The parameters passed to the contract function may be invalid, or + - The address is not a contract. + + Contract Call: + address: 0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC + function: ownerOf(uint256 tokenId) + args: (1e+31) + + Docs: https://viem.sh/docs/contract/readContract + Version: viem@2.29.2], + "result": undefined, + "status": "failure", + }, + { + "error": [ContractFunctionExecutionError: The contract function "ownerOf" returned no data ("0x"). + + This could be due to any of the following: + - The contract does not have the function "ownerOf", + - The parameters passed to the contract function may be invalid, or + - The address is not a contract. + + Contract Call: + address: 0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC + function: ownerOf(uint256 tokenId) + args: (1e+31) + + Docs: https://viem.sh/docs/contract/readContract + Version: viem@2.29.2], + "result": undefined, + "status": "failure", + }, + ] + `) +}) + +test('should throw if allowFailure=false & a contract has no response', async () => { + await expect( + readContracts(config, { + allowFailure: false, + contracts: [ + ...contracts, + { + abi: abi.wagmigotchi, + functionName: 'love', + // address is not the wagmigotchi contract + address: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }, + ], + }), + ).rejects.toThrowErrorMatchingInlineSnapshot( + ` + [ContractFunctionExecutionError: The contract function "love" returned no data ("0x"). + + This could be due to any of the following: + - The contract does not have the function "love", + - The parameters passed to the contract function may be invalid, or + - The address is not a contract. + + Contract Call: + address: 0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC + function: love(address) + args: (0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC) + + Docs: https://viem.sh/docs/contract/readContract + Version: viem@2.29.2] + `, + ) +}) + +test('allowFailure=true & a contract has no response', async () => { + expect( + await readContracts(config, { + allowFailure: true, + contracts: [ + ...contracts, + { + abi: abi.wagmigotchi, + functionName: 'love', + // address is not the wagmigotchi contract + address: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }, + ], + }), + ).toMatchInlineSnapshot(` + [ + { + "result": 2n, + "status": "success", + }, + { + "result": 1n, + "status": "success", + }, + { + "result": false, + "status": "success", + }, + { + "result": 370395n, + "status": "success", + }, + { + "error": [ContractFunctionExecutionError: The contract function "love" returned no data ("0x"). + + This could be due to any of the following: + - The contract does not have the function "love", + - The parameters passed to the contract function may be invalid, or + - The address is not a contract. + + Contract Call: + address: 0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC + function: love(address) + args: (0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC) + + Docs: https://viem.sh/docs/contract/readContract + Version: viem@2.29.2], + "result": undefined, + "status": "failure", + }, + ] + `) +}) diff --git a/wagmi-project/packages/core/src/actions/readContracts.ts b/wagmi-project/packages/core/src/actions/readContracts.ts new file mode 100644 index 0000000000..45f2a0cef4 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/readContracts.ts @@ -0,0 +1,96 @@ +import type { + ContractFunctionParameters, + MulticallParameters as viem_MulticallParameters, + MulticallReturnType as viem_MulticallReturnType, +} from 'viem' +import { ContractFunctionExecutionError } from 'viem' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import { type MulticallErrorType, multicall } from './multicall.js' +import { type ReadContractErrorType, readContract } from './readContract.js' + +export type ReadContractsParameters< + contracts extends readonly unknown[] = readonly ContractFunctionParameters[], + allowFailure extends boolean = true, + config extends Config = Config, +> = viem_MulticallParameters< + contracts, + allowFailure, + { properties: ChainIdParameter } +> + +export type ReadContractsReturnType< + contracts extends readonly unknown[] = readonly ContractFunctionParameters[], + allowFailure extends boolean = true, +> = viem_MulticallReturnType + +export type ReadContractsErrorType = MulticallErrorType | ReadContractErrorType + +export async function readContracts< + config extends Config, + const contracts extends readonly ContractFunctionParameters[], + allowFailure extends boolean = true, +>( + config: config, + parameters: ReadContractsParameters, +): Promise> { + const { allowFailure = true, blockNumber, blockTag, ...rest } = parameters + const contracts = parameters.contracts as (ContractFunctionParameters & { + chainId?: number | undefined + })[] + + try { + const contractsByChainId: { + [chainId: number]: { + contract: ContractFunctionParameters + index: number + }[] + } = {} + for (const [index, contract] of contracts.entries()) { + const chainId = contract.chainId ?? config.state.chainId + if (!contractsByChainId[chainId]) contractsByChainId[chainId] = [] + contractsByChainId[chainId]?.push({ contract, index }) + } + const promises = () => + Object.entries(contractsByChainId).map(([chainId, contracts]) => + multicall(config, { + ...rest, + allowFailure, + blockNumber, + blockTag, + chainId: Number.parseInt(chainId), + contracts: contracts.map(({ contract }) => contract), + }), + ) + + const multicallResults = (await Promise.all(promises())).flat() + // Reorder the contract results back to the order they were + // provided in. + const resultIndexes = Object.values(contractsByChainId).flatMap( + (contracts) => contracts.map(({ index }) => index), + ) + return multicallResults.reduce((results, result, index) => { + if (results) (results as unknown[])[resultIndexes[index]!] = result + return results + }, [] as unknown[]) as ReadContractsReturnType + } catch (error) { + if (error instanceof ContractFunctionExecutionError) throw error + + const promises = () => + contracts.map((contract) => + readContract(config, { ...contract, blockNumber, blockTag }), + ) + if (allowFailure) + return (await Promise.allSettled(promises())).map((result) => { + if (result.status === 'fulfilled') + return { result: result.value, status: 'success' } + return { error: result.reason, result: undefined, status: 'failure' } + }) as ReadContractsReturnType + + return (await Promise.all(promises())) as ReadContractsReturnType< + contracts, + allowFailure + > + } +} diff --git a/wagmi-project/packages/core/src/actions/reconnect.test.ts b/wagmi-project/packages/core/src/actions/reconnect.test.ts new file mode 100644 index 0000000000..910d16e304 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/reconnect.test.ts @@ -0,0 +1,119 @@ +import { accounts, config, mainnet } from '@wagmi/test' +import { http } from 'viem' +import { afterEach, expect, test, vi } from 'vitest' + +import { mock } from '../connectors/mock.js' +import { createConfig } from '../createConfig.js' +import { createStorage } from '../createStorage.js' +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { reconnect } from './reconnect.js' + +const connector = config._internal.connectors.setup( + mock({ + accounts, + features: { reconnect: true }, + }), +) + +afterEach(async () => { + if (config.state.current === connector.uid) + await disconnect(config, { connector }) + else if (config.state.current) await disconnect(config) +}) + +test('default', async () => { + await expect( + reconnect(config, { connectors: [connector] }), + ).resolves.toStrictEqual([]) + expect(config.state.status).toEqual('disconnected') +}) + +test('parameters: connectors (Connector)', async () => { + await connect(config, { connector }) + await expect( + reconnect(config, { connectors: [connector] }), + ).resolves.toMatchObject( + expect.arrayContaining([ + expect.objectContaining({ + accounts: expect.any(Array), + chainId: expect.any(Number), + }), + ]), + ) + expect(config.state.status).toEqual('connected') +}) + +test('parameters: connectors (CreateConnectorFn)', async () => { + const connector = mock({ + accounts, + features: { reconnect: true }, + }) + await connect(config, { connector }) + await expect( + reconnect(config, { connectors: [connector] }), + ).resolves.toMatchObject( + expect.arrayContaining([ + expect.objectContaining({ + accounts: expect.any(Array), + chainId: expect.any(Number), + }), + ]), + ) + expect(config.state.status).toEqual('connected') +}) + +test("behavior: doesn't reconnect if already reconnecting", async () => { + const previousStatus = config.state.status + config.setState((x) => ({ ...x, status: 'reconnecting' })) + await expect( + reconnect(config, { connectors: [connector] }), + ).resolves.toStrictEqual([]) + config.setState((x) => ({ ...x, status: previousStatus })) +}) + +test('behavior: recovers from invalid state', async () => { + const state = { + 'wagmi.store': JSON.stringify({ + state: { + status: 'connected', // <-- invalid - `status` should not be kept in storage + chainId: 1, + current: '983b8aca245', + }, + version: Number.NaN, // mocked version is `'x.y.z'`, which will get interpreted as `NaN` + }), + } as Record + Object.defineProperty(window, 'localStorage', { + value: { + getItem: vi.fn((key) => state[key] ?? null), + removeItem: vi.fn((key) => state.delete?.[key]), + setItem: vi.fn((key, value) => { + state[key] = value + }), + }, + writable: true, + }) + + const storage = createStorage<{ store: object }>({ + storage: window.localStorage, + }) + + const config = createConfig({ + chains: [mainnet], + storage, + transports: { + [mainnet.id]: http(), + }, + }) + + await reconnect(config, { connectors: [connector] }) + + expect(config.state).toMatchInlineSnapshot(` + { + "chainId": 1, + "connections": Map {}, + "current": null, + "status": "disconnected", + } + `) +}) diff --git a/wagmi-project/packages/core/src/actions/reconnect.ts b/wagmi-project/packages/core/src/actions/reconnect.ts new file mode 100644 index 0000000000..2234c934d4 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/reconnect.ts @@ -0,0 +1,127 @@ +import type { Address } from 'viem' + +import type { CreateConnectorFn } from '../connectors/createConnector.js' +import type { Config, Connection, Connector } from '../createConfig.js' +import type { ErrorType } from '../errors/base.js' +import type { Compute } from '../types/utils.js' + +export type ReconnectParameters = { + /** Connectors to attempt reconnect with */ + connectors?: readonly (CreateConnectorFn | Connector)[] | undefined +} + +export type ReconnectReturnType = Compute[] + +export type ReconnectErrorType = ErrorType + +let isReconnecting = false + +/** https://wagmi.sh/core/api/actions/reconnect */ +export async function reconnect( + config: Config, + parameters: ReconnectParameters = {}, +): Promise { + // If already reconnecting, do nothing + if (isReconnecting) return [] + isReconnecting = true + + config.setState((x) => ({ + ...x, + status: x.current ? 'reconnecting' : 'connecting', + })) + + const connectors: Connector[] = [] + if (parameters.connectors?.length) { + for (const connector_ of parameters.connectors) { + let connector: Connector + // "Register" connector if not already created + if (typeof connector_ === 'function') + connector = config._internal.connectors.setup(connector_) + else connector = connector_ + connectors.push(connector) + } + } else connectors.push(...config.connectors) + + // Try recently-used connectors first + let recentConnectorId: string | null | undefined + try { + recentConnectorId = await config.storage?.getItem('recentConnectorId') + } catch {} + const scores: Record = {} + for (const [, connection] of config.state.connections) { + scores[connection.connector.id] = 1 + } + if (recentConnectorId) scores[recentConnectorId] = 0 + const sorted = + Object.keys(scores).length > 0 + ? // .toSorted() + [...connectors].sort( + (a, b) => (scores[a.id] ?? 10) - (scores[b.id] ?? 10), + ) + : connectors + + // Iterate through each connector and try to connect + let connected = false + const connections: Connection[] = [] + const providers: unknown[] = [] + for (const connector of sorted) { + const provider = await connector.getProvider().catch(() => undefined) + if (!provider) continue + + // If we already have an instance of this connector's provider, + // then we have already checked it (ie. injected connectors can + // share the same `window.ethereum` instance, so we don't want to + // connect to it again). + if (providers.some((x) => x === provider)) continue + + const isAuthorized = await connector.isAuthorized() + if (!isAuthorized) continue + + const data = await connector + .connect({ isReconnecting: true }) + .catch(() => null) + if (!data) continue + + connector.emitter.off('connect', config._internal.events.connect) + connector.emitter.on('change', config._internal.events.change) + connector.emitter.on('disconnect', config._internal.events.disconnect) + + config.setState((x) => { + const connections = new Map(connected ? x.connections : new Map()).set( + connector.uid, + { accounts: data.accounts, chainId: data.chainId, connector }, + ) + return { + ...x, + current: connected ? x.current : connector.uid, + connections, + } + }) + connections.push({ + accounts: data.accounts as readonly [Address, ...Address[]], + chainId: data.chainId, + connector, + }) + providers.push(provider) + connected = true + } + + // Prevent overwriting connected status from race condition + if ( + config.state.status === 'reconnecting' || + config.state.status === 'connecting' + ) { + // If connecting didn't succeed, set to disconnected + if (!connected) + config.setState((x) => ({ + ...x, + connections: new Map(), + current: null, + status: 'disconnected', + })) + else config.setState((x) => ({ ...x, status: 'connected' })) + } + + isReconnecting = false + return connections +} diff --git a/wagmi-project/packages/core/src/actions/sendCalls.test.ts b/wagmi-project/packages/core/src/actions/sendCalls.test.ts new file mode 100644 index 0000000000..cb25e2b0ba --- /dev/null +++ b/wagmi-project/packages/core/src/actions/sendCalls.test.ts @@ -0,0 +1,121 @@ +import { accounts, config } from '@wagmi/test' +import { parseEther } from 'viem' +import { expect, test } from 'vitest' + +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { sendCalls } from './sendCalls.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + await expect( + sendCalls(config, { + calls: [ + { + data: '0xdeadbeef', + to: accounts[1], + value: parseEther('1'), + }, + { + to: accounts[2], + value: parseEther('2'), + }, + { + to: accounts[3], + value: parseEther('3'), + }, + ], + }), + ).resolves.toMatchInlineSnapshot( + ` + { + "id": "0x5dedb5a4ff8968db37459b52b83cbdc92b01c9c709c9cff26e345ef5cf27f92e", + } + `, + ) + await disconnect(config, { connector }) +}) + +test('behavior: not connected', async () => { + await expect( + sendCalls(config, { + calls: [ + { + to: accounts[1], + value: parseEther('1'), + }, + { + to: accounts[2], + value: parseEther('2'), + }, + { + to: accounts[3], + value: parseEther('3'), + }, + ], + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [ConnectorNotConnectedError: Connector not connected. + + Version: @wagmi/core@x.y.z] + `) +}) + +test('behavior: nullish account (account filled by wallet)', async () => { + await expect( + sendCalls(config, { + account: null, + connector, + calls: [ + { + to: accounts[1], + value: parseEther('1'), + }, + { + to: accounts[2], + value: parseEther('2'), + }, + { + to: accounts[3], + value: parseEther('3'), + }, + ], + }), + ).resolves.toMatchInlineSnapshot( + ` + { + "id": "0x035b56a56a5b2fea10e194bae4c846b415de48a8288c7eb704ba7880edcc29a0", + } + `, + ) +}) + +test('behavior: account does not exist on connector', async () => { + await connect(config, { connector }) + await expect( + sendCalls(config, { + account: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + calls: [ + { + to: accounts[1], + value: parseEther('1'), + }, + { + to: accounts[2], + value: parseEther('2'), + }, + { + to: accounts[3], + value: parseEther('3'), + }, + ], + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [ConnectorAccountNotFoundError: Account "0xA0Cf798816D4b9b9866b5330EEa46a18382f251e" not found for connector "Mock Connector". + + Version: @wagmi/core@x.y.z] + `) + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/core/src/actions/sendCalls.ts b/wagmi-project/packages/core/src/actions/sendCalls.ts new file mode 100644 index 0000000000..6139455d60 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/sendCalls.ts @@ -0,0 +1,74 @@ +import type { Account, Chain } from 'viem' +import { + type SendCallsErrorType as viem_SendCallsErrorType, + type SendCallsParameters as viem_SendCallsParameters, + type SendCallsReturnType as viem_SendCallsReturnType, + sendCalls as viem_sendCalls, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { BaseErrorType, ErrorType } from '../errors/base.js' +import type { SelectChains } from '../types/chain.js' +import type { + ChainIdParameter, + ConnectorParameter, +} from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { + type GetConnectorClientErrorType, + getConnectorClient, +} from './getConnectorClient.js' + +export type SendCallsParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + calls extends readonly unknown[] = readonly unknown[], + /// + chains extends readonly Chain[] = SelectChains, +> = { + [key in keyof chains]: Compute< + Omit< + viem_SendCallsParameters, + 'chain' + > & + ChainIdParameter & + ConnectorParameter + > +}[number] + +export type SendCallsReturnType = viem_SendCallsReturnType + +export type SendCallsErrorType = + // getConnectorClient() + | GetConnectorClientErrorType + // base + | BaseErrorType + | ErrorType + // viem + | viem_SendCallsErrorType + +/** https://wagmi.sh/core/api/actions/sendCalls */ +export async function sendCalls< + const calls extends readonly unknown[], + config extends Config, + chainId extends config['chains'][number]['id'], +>( + config: config, + parameters: SendCallsParameters, +): Promise { + const { account, chainId, connector, calls, ...rest } = parameters + + const client = await getConnectorClient(config, { + account, + chainId, + connector, + }) + + return viem_sendCalls(client, { + ...(rest as any), + ...(typeof account !== 'undefined' ? { account } : {}), + calls, + chain: chainId ? { id: chainId } : undefined, + }) +} diff --git a/wagmi-project/packages/core/src/actions/sendTransaction.test-d.ts b/wagmi-project/packages/core/src/actions/sendTransaction.test-d.ts new file mode 100644 index 0000000000..54ce62a947 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/sendTransaction.test-d.ts @@ -0,0 +1,50 @@ +import { http, parseEther } from 'viem' +import { celo, mainnet } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { createConfig } from '../createConfig.js' +import { + type SendTransactionParameters, + sendTransaction, +} from './sendTransaction.js' + +test('chain formatters', () => { + const config = createConfig({ + chains: [mainnet, celo], + transports: { [celo.id]: http(), [mainnet.id]: http() }, + }) + + type Result = SendTransactionParameters + expectTypeOf().toMatchTypeOf<{ + chainId?: typeof celo.id | typeof mainnet.id | undefined + feeCurrency?: `0x${string}` | undefined + }>() + sendTransaction(config, { + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + feeCurrency: '0x', + }) + + type Result2 = SendTransactionParameters + expectTypeOf().toMatchTypeOf<{ + feeCurrency?: `0x${string}` | undefined + }>() + sendTransaction(config, { + chainId: celo.id, + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + feeCurrency: '0x', + }) + + type Result3 = SendTransactionParameters + expectTypeOf().not.toMatchTypeOf<{ + feeCurrency?: `0x${string}` | undefined + }>() + sendTransaction(config, { + chainId: mainnet.id, + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + // @ts-expect-error + feeCurrency: '0x', + }) +}) diff --git a/wagmi-project/packages/core/src/actions/sendTransaction.test.ts b/wagmi-project/packages/core/src/actions/sendTransaction.test.ts new file mode 100644 index 0000000000..e263d96670 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/sendTransaction.test.ts @@ -0,0 +1,105 @@ +import { config, privateKey, transactionHashRegex } from '@wagmi/test' +import { parseEther } from 'viem' +import { beforeEach, expect, test } from 'vitest' + +import { privateKeyToAccount } from 'viem/accounts' +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { sendTransaction } from './sendTransaction.js' + +const connector = config.connectors[0]! + +beforeEach(async () => { + if (config.state.current === connector.uid) + await disconnect(config, { connector }) +}) + +test('default', async () => { + const result = await connect(config, { connector }) + config.state.connections.set(connector.uid, { + ...result, + // Switch up the current account because the default one is running out of funds somewhere + accounts: result.accounts.slice(1) as unknown as typeof result.accounts, + connector, + }) + await expect( + sendTransaction(config, { + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.0001'), + }), + ).resolves.toMatch(transactionHashRegex) + await disconnect(config, { connector }) +}) + +test('behavior: connector not connected', async () => { + await connect(config, { connector }) + await expect( + sendTransaction(config, { + connector: config.connectors[1], + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.0001'), + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [ConnectorNotConnectedError: Connector not connected. + + Version: @wagmi/core@x.y.z] + `) + await disconnect(config, { connector }) +}) + +test('behavior: account does not exist on connector', async () => { + await connect(config, { connector }) + await expect( + sendTransaction(config, { + account: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.0001'), + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [ConnectorAccountNotFoundError: Account "0xA0Cf798816D4b9b9866b5330EEa46a18382f251e" not found for connector "Mock Connector". + + Version: @wagmi/core@x.y.z] + `) + await disconnect(config, { connector }) +}) + +test('behavior: value exceeds balance', async () => { + await connect(config, { connector }) + await expect( + sendTransaction(config, { + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('99999'), + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [TransactionExecutionError: The total cost (gas * gas fee + value) of executing this transaction exceeds the balance of the account. + + This error could arise when the account does not have enough funds to: + - pay for the total gas fee, + - pay for the value to send. + + The cost of the transaction is calculated as \`gas * gas fee + value\`, where: + - \`gas\` is the amount of gas needed for transaction to execute, + - \`gas fee\` is the gas fee, + - \`value\` is the amount of ether to send to the recipient. + + Request Arguments: + from: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 + to: 0xd2135CfB216b74109775236E36d4b433F1DF507B + value: 99999 ETH + + Details: Insufficient funds for gas * price + value + Version: viem@2.29.2] + `) + await disconnect(config, { connector }) +}) + +test('behavior: local account', async () => { + const account = privateKeyToAccount(privateKey) + await expect( + sendTransaction(config, { + account, + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.000001'), + }), + ).resolves.toMatch(transactionHashRegex) +}) diff --git a/wagmi-project/packages/core/src/actions/sendTransaction.ts b/wagmi-project/packages/core/src/actions/sendTransaction.ts new file mode 100644 index 0000000000..76bc3a420a --- /dev/null +++ b/wagmi-project/packages/core/src/actions/sendTransaction.ts @@ -0,0 +1,86 @@ +import type { + Account, + Chain, + Client, + TransactionRequest, + SendTransactionErrorType as viem_SendTransactionErrorType, + SendTransactionParameters as viem_SendTransactionParameters, + SendTransactionReturnType as viem_SendTransactionReturnType, +} from 'viem' +import { sendTransaction as viem_sendTransaction } from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { BaseErrorType, ErrorType } from '../errors/base.js' +import type { SelectChains } from '../types/chain.js' +import type { + ChainIdParameter, + ConnectorParameter, +} from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' +import { + type GetConnectorClientErrorType, + getConnectorClient, +} from './getConnectorClient.js' + +export type SendTransactionParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + /// + chains extends readonly Chain[] = SelectChains, +> = { + [key in keyof chains]: Compute< + Omit< + viem_SendTransactionParameters, + 'chain' | 'gas' + > & + ChainIdParameter & + ConnectorParameter + > +}[number] & { + /** Gas provided for transaction execution. */ + gas?: TransactionRequest['gas'] | null +} + +export type SendTransactionReturnType = viem_SendTransactionReturnType + +export type SendTransactionErrorType = + // getConnectorClient() + | GetConnectorClientErrorType + // base + | BaseErrorType + | ErrorType + // viem + | viem_SendTransactionErrorType + +/** https://wagmi.sh/core/api/actions/sendTransaction */ +export async function sendTransaction< + config extends Config, + chainId extends config['chains'][number]['id'], +>( + config: config, + parameters: SendTransactionParameters, +): Promise { + const { account, chainId, connector, ...rest } = parameters + + let client: Client + if (typeof account === 'object' && account?.type === 'local') + client = config.getClient({ chainId }) + else + client = await getConnectorClient(config, { + account: account ?? undefined, + chainId, + connector, + }) + + const action = getAction(client, viem_sendTransaction, 'sendTransaction') + const hash = await action({ + ...(rest as any), + ...(account ? { account } : {}), + chain: chainId ? { id: chainId } : null, + gas: rest.gas ?? undefined, + }) + + return hash +} diff --git a/wagmi-project/packages/core/src/actions/showCallsStatus.test.ts b/wagmi-project/packages/core/src/actions/showCallsStatus.test.ts new file mode 100644 index 0000000000..5822242382 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/showCallsStatus.test.ts @@ -0,0 +1,36 @@ +import { accounts, config, testClient } from '@wagmi/test' +import { parseEther } from 'viem' +import { test } from 'vitest' + +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { sendCalls } from './sendCalls.js' +import { showCallsStatus } from './showCallsStatus.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + const { id } = await sendCalls(config, { + calls: [ + { + data: '0xdeadbeef', + to: accounts[1], + value: parseEther('1'), + }, + { + to: accounts[2], + value: parseEther('2'), + }, + { + to: accounts[3], + value: parseEther('3'), + }, + ], + }) + await testClient.mainnet.mine({ blocks: 1 }) + await showCallsStatus(config, { + id, + }) + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/core/src/actions/showCallsStatus.ts b/wagmi-project/packages/core/src/actions/showCallsStatus.ts new file mode 100644 index 0000000000..e3c6ae067d --- /dev/null +++ b/wagmi-project/packages/core/src/actions/showCallsStatus.ts @@ -0,0 +1,27 @@ +import { + type ShowCallsStatusErrorType as viem_ShowCallsStatusErrorType, + type ShowCallsStatusParameters as viem_ShowCallsStatusParameters, + type ShowCallsStatusReturnType as viem_ShowCallsStatusReturnType, + showCallsStatus as viem_showCallsStatus, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ConnectorParameter } from '../types/properties.js' +import { getConnectorClient } from './getConnectorClient.js' + +export type ShowCallsStatusParameters = viem_ShowCallsStatusParameters & + ConnectorParameter + +export type ShowCallsStatusReturnType = viem_ShowCallsStatusReturnType + +export type ShowCallsStatusErrorType = viem_ShowCallsStatusErrorType + +/** https://wagmi.sh/core/api/actions/showCallsStatus */ +export async function showCallsStatus( + config: config, + parameters: ShowCallsStatusParameters, +): Promise { + const { connector, id } = parameters + const client = await getConnectorClient(config, { connector }) + return viem_showCallsStatus(client, { id }) +} diff --git a/wagmi-project/packages/core/src/actions/signMessage.test.ts b/wagmi-project/packages/core/src/actions/signMessage.test.ts new file mode 100644 index 0000000000..5b87c7d652 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/signMessage.test.ts @@ -0,0 +1,67 @@ +import { accounts, config, privateKey } from '@wagmi/test' +import { recoverMessageAddress } from 'viem' +import { privateKeyToAccount } from 'viem/accounts' +import { expect, test } from 'vitest' + +import { mock } from '../connectors/mock.js' +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { getAccount } from './getAccount.js' +import { signMessage } from './signMessage.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + const signature = await signMessage(config, { message: 'foo bar baz' }) + await expect( + recoverMessageAddress({ + message: 'foo bar baz', + signature, + }), + ).resolves.toEqual(getAccount(config).address) + await disconnect(config, { connector }) +}) + +test('behavior: local account', async () => { + const account = privateKeyToAccount(privateKey) + const signature = await signMessage(config, { + account, + message: 'foo bar baz', + }) + await expect( + recoverMessageAddress({ + message: 'foo bar baz', + signature, + }), + ).resolves.toEqual(account.address) +}) + +test('behavior: user rejected request', async () => { + const connector_ = config._internal.connectors.setup( + mock({ + accounts, + features: { signMessageError: true }, + }), + ) + await connect(config, { connector: connector_ }) + await expect( + signMessage(config, { message: 'foo bar baz' }), + ).rejects.toMatchInlineSnapshot(` + [UserRejectedRequestError: User rejected the request. + + Details: Failed to sign message. + Version: viem@2.29.2] + `) + await disconnect(config, { connector: connector_ }) +}) + +test('behavior: not connected', async () => { + await expect( + signMessage(config, { message: 'foo bar baz' }), + ).rejects.toMatchInlineSnapshot(` + [ConnectorNotConnectedError: Connector not connected. + + Version: @wagmi/core@x.y.z] + `) +}) diff --git a/wagmi-project/packages/core/src/actions/signMessage.ts b/wagmi-project/packages/core/src/actions/signMessage.ts new file mode 100644 index 0000000000..67f0c293a6 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/signMessage.ts @@ -0,0 +1,51 @@ +import type { Account, Client } from 'viem' +import { + type SignMessageErrorType as viem_SignMessageErrorType, + type SignMessageParameters as viem_SignMessageParameters, + type SignMessageReturnType as viem_SignMessageReturnType, + signMessage as viem_signMessage, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { BaseErrorType, ErrorType } from '../errors/base.js' +import type { ConnectorParameter } from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' +import { + type GetConnectorClientErrorType, + getConnectorClient, +} from './getConnectorClient.js' + +export type SignMessageParameters = Compute< + viem_SignMessageParameters & ConnectorParameter +> + +export type SignMessageReturnType = viem_SignMessageReturnType + +export type SignMessageErrorType = + // getConnectorClient() + | GetConnectorClientErrorType + // base + | BaseErrorType + | ErrorType + // viem + | viem_SignMessageErrorType + +/** https://wagmi.sh/core/api/actions/signMessage */ +export async function signMessage( + config: Config, + parameters: SignMessageParameters, +): Promise { + const { account, connector, ...rest } = parameters + + let client: Client + if (typeof account === 'object' && account.type === 'local') + client = config.getClient() + else client = await getConnectorClient(config, { account, connector }) + + const action = getAction(client, viem_signMessage, 'signMessage') + return action({ + ...rest, + ...(account ? { account } : {}), + } as viem_SignMessageParameters) +} diff --git a/wagmi-project/packages/core/src/actions/signTypedData.test-d.ts b/wagmi-project/packages/core/src/actions/signTypedData.test-d.ts new file mode 100644 index 0000000000..a502d26e91 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/signTypedData.test-d.ts @@ -0,0 +1,31 @@ +import { config, typedData } from '@wagmi/test' +import { test } from 'vitest' + +import { signTypedData } from './signTypedData.js' + +test('default', async () => { + signTypedData(config, { + types: typedData.basic.types, + primaryType: 'Mail', + message: typedData.basic.message, + }) +}) + +test('domain', async () => { + signTypedData(config, { + primaryType: 'EIP712Domain', + domain: {}, + }) +}) + +test('custom domain', async () => { + signTypedData(config, { + types: { + EIP712Domain: [{ type: 'uint256', name: 'chainId' }], + }, + primaryType: 'EIP712Domain', + domain: { + chainId: 123n, + }, + }) +}) diff --git a/wagmi-project/packages/core/src/actions/signTypedData.test.ts b/wagmi-project/packages/core/src/actions/signTypedData.test.ts new file mode 100644 index 0000000000..b72ecab8cb --- /dev/null +++ b/wagmi-project/packages/core/src/actions/signTypedData.test.ts @@ -0,0 +1,85 @@ +import { accounts, config, privateKey, typedData } from '@wagmi/test' +import { recoverTypedDataAddress } from 'viem' +import { expect, test } from 'vitest' + +import { privateKeyToAccount } from 'viem/accounts' +import { mock } from '../connectors/mock.js' +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { getAccount } from './getAccount.js' +import { signTypedData } from './signTypedData.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + const signature = await signTypedData(config, { + types: typedData.basic.types, + primaryType: 'Mail', + message: typedData.basic.message, + }) + await expect( + recoverTypedDataAddress({ + types: typedData.basic.types, + primaryType: 'Mail', + message: typedData.basic.message, + signature, + }), + ).resolves.toBe(getAccount(config).address) + await disconnect(config, { connector }) +}) + +test('behavior: user rejected request', async () => { + const connector_ = config._internal.connectors.setup( + mock({ + accounts, + features: { signTypedDataError: true }, + }), + ) + await connect(config, { connector: connector_ }) + await expect( + signTypedData(config, { + types: typedData.basic.types, + primaryType: 'Mail', + message: typedData.basic.message, + }), + ).rejects.toMatchInlineSnapshot(` + [UserRejectedRequestError: User rejected the request. + + Details: Failed to sign typed data. + Version: viem@2.29.2] + `) + await disconnect(config, { connector: connector_ }) +}) + +test('behavior: not connected', async () => { + await expect( + signTypedData(config, { + types: typedData.basic.types, + primaryType: 'Mail', + message: typedData.basic.message, + }), + ).rejects.toMatchInlineSnapshot(` + [ConnectorNotConnectedError: Connector not connected. + + Version: @wagmi/core@x.y.z] + `) +}) + +test('behavior: local account', async () => { + const account = privateKeyToAccount(privateKey) + const signature = await signTypedData(config, { + account, + types: typedData.basic.types, + primaryType: 'Mail', + message: typedData.basic.message, + }) + await expect( + recoverTypedDataAddress({ + types: typedData.basic.types, + primaryType: 'Mail', + message: typedData.basic.message, + signature, + }), + ).resolves.toBe(account.address) +}) diff --git a/wagmi-project/packages/core/src/actions/signTypedData.ts b/wagmi-project/packages/core/src/actions/signTypedData.ts new file mode 100644 index 0000000000..22cea12662 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/signTypedData.ts @@ -0,0 +1,60 @@ +import type { Account, Client, TypedData } from 'viem' +import { + type SignMessageErrorType as viem_SignMessageErrorType, + type SignTypedDataParameters as viem_SignTypedDataParameters, + type SignTypedDataReturnType as viem_SignTypedDataReturnType, + signTypedData as viem_signTypedData, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { BaseErrorType, ErrorType } from '../errors/base.js' +import type { ConnectorParameter } from '../types/properties.js' +import type { UnionCompute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' +import { + type GetConnectorClientErrorType, + getConnectorClient, +} from './getConnectorClient.js' + +export type SignTypedDataParameters< + typedData extends TypedData | Record = TypedData, + primaryType extends keyof typedData | 'EIP712Domain' = keyof typedData, + /// + primaryTypes = typedData extends TypedData ? keyof typedData : string, +> = UnionCompute< + viem_SignTypedDataParameters & + ConnectorParameter +> + +export type SignTypedDataReturnType = viem_SignTypedDataReturnType + +export type SignTypedDataErrorType = + // getConnectorClient() + | GetConnectorClientErrorType + // base + | BaseErrorType + | ErrorType + // viem + | viem_SignMessageErrorType + +/** https://wagmi.sh/core/api/actions/signTypedData */ +export async function signTypedData< + const typedData extends TypedData | Record, + primaryType extends keyof typedData | 'EIP712Domain', +>( + config: Config, + parameters: SignTypedDataParameters, +): Promise { + const { account, connector, ...rest } = parameters + + let client: Client + if (typeof account === 'object' && account.type === 'local') + client = config.getClient() + else client = await getConnectorClient(config, { account, connector }) + + const action = getAction(client, viem_signTypedData, 'signTypedData') + return action({ + ...rest, + ...(account ? { account } : {}), + } as unknown as viem_SignTypedDataParameters) +} diff --git a/wagmi-project/packages/core/src/actions/simulateContract.test-d.ts b/wagmi-project/packages/core/src/actions/simulateContract.test-d.ts new file mode 100644 index 0000000000..3f893ff8f8 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/simulateContract.test-d.ts @@ -0,0 +1,160 @@ +import { abi, config } from '@wagmi/test' +import { http, type Address } from 'viem' +import { celo, mainnet } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { createConfig } from '../createConfig.js' +import { + type SimulateContractParameters, + type SimulateContractReturnType, + simulateContract, +} from './simulateContract.js' + +test('default', async () => { + const response = await simulateContract(config, { + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + chainId: 1, + }) + + expectTypeOf(response).toMatchTypeOf<{ + result: boolean + request: { + chainId: 1 + abi: readonly [ + { + readonly name: 'transferFrom' + readonly type: 'function' + readonly stateMutability: 'nonpayable' + readonly inputs: readonly [ + { readonly type: 'address'; readonly name: 'sender' }, + { readonly type: 'address'; readonly name: 'recipient' }, + { readonly type: 'uint256'; readonly name: 'amount' }, + ] + readonly outputs: readonly [{ type: 'bool' }] + }, + ] + functionName: 'transferFrom' + args: readonly [Address, Address, bigint] + } + }>() +}) + +test('chain formatters', async () => { + const config = createConfig({ + chains: [celo, mainnet], + transports: { [celo.id]: http(), [mainnet.id]: http() }, + }) + + type Result = SimulateContractParameters< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof config + > + expectTypeOf().toMatchTypeOf<{ + chainId?: typeof celo.id | typeof mainnet.id | undefined + feeCurrency?: `0x${string}` | undefined + }>() + const response = await simulateContract(config, { + account: '0x', + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + feeCurrency: '0x', + }) + + if (response.chainId === celo.id) { + expectTypeOf(response.chainId).toEqualTypeOf(celo.id) + expectTypeOf(response.request.feeCurrency).toEqualTypeOf< + `0x${string}` | undefined + >() + } + + type Result2 = SimulateContractParameters< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof config, + typeof celo.id + > + expectTypeOf().toMatchTypeOf<{ + functionName: 'approve' | 'transfer' | 'transferFrom' + args: readonly [Address, Address, bigint] + feeCurrency?: `0x${string}` | undefined + }>() + const response2 = await simulateContract(config, { + chainId: celo.id, + account: '0x', + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + feeCurrency: '0x', + }) + expectTypeOf(response2.chainId).toEqualTypeOf(celo.id) + expectTypeOf(response2.request.feeCurrency).toEqualTypeOf< + `0x${string}` | undefined + >() + + type Result3 = SimulateContractParameters< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof config, + typeof mainnet.id + > + expectTypeOf().toMatchTypeOf<{ + functionName: 'approve' | 'transfer' | 'transferFrom' + args: readonly [Address, Address, bigint] + }>() + expectTypeOf().not.toMatchTypeOf<{ + feeCurrency?: `0x${string}` | undefined + }>() + simulateContract(config, { + chainId: mainnet.id, + account: '0x', + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + // @ts-expect-error + feeCurrency: '0x', + }) +}) + +test('SimulateContractParameters', () => { + type Result = SimulateContractParameters< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof config, + (typeof config)['chains'][number]['id'] + > + expectTypeOf().toMatchTypeOf<{ + chainId?: (typeof config)['chains'][number]['id'] | undefined + functionName: 'approve' | 'transfer' | 'transferFrom' + args: readonly [Address, Address, bigint] + }>() +}) + +test('SimulateContractReturnType', () => { + type Result = SimulateContractReturnType< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof config, + (typeof config)['chains'][number]['id'] + > + expectTypeOf().toMatchTypeOf<{ + result: boolean + request: { + functionName: 'transferFrom' + args: readonly [Address, Address, bigint] + chainId: (typeof config)['chains'][number]['id'] + } + }>() +}) diff --git a/wagmi-project/packages/core/src/actions/simulateContract.test.ts b/wagmi-project/packages/core/src/actions/simulateContract.test.ts new file mode 100644 index 0000000000..a52cbd5568 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/simulateContract.test.ts @@ -0,0 +1,84 @@ +import { abi, accounts, address, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { simulateContract } from './simulateContract.js' + +const connector = config.connectors[0]! + +test('parameters: account', async () => { + await expect( + simulateContract(config, { + account: accounts[0], + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'mint', + }), + ).resolves.toMatchInlineSnapshot(` + { + "chainId": 1, + "request": { + "abi": [ + { + "inputs": [], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "account": { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "type": "json-rpc", + }, + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": undefined, + "chainId": undefined, + "dataSuffix": undefined, + "functionName": "mint", + }, + "result": undefined, + } + `) +}) + +test('parameters: connector', async () => { + await connect(config, { connector }) + + await expect( + simulateContract(config, { + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'mint', + connector, + }), + ).resolves.toMatchInlineSnapshot(` + { + "chainId": 1, + "request": { + "abi": [ + { + "inputs": [], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "account": { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "type": "json-rpc", + }, + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": undefined, + "chainId": undefined, + "dataSuffix": undefined, + "functionName": "mint", + }, + "result": undefined, + } + `) + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/core/src/actions/simulateContract.ts b/wagmi-project/packages/core/src/actions/simulateContract.ts new file mode 100644 index 0000000000..e5fe5655ff --- /dev/null +++ b/wagmi-project/packages/core/src/actions/simulateContract.ts @@ -0,0 +1,166 @@ +import type { + Abi, + Account, + Address, + Chain, + ContractFunctionArgs, + ContractFunctionName, +} from 'viem' +import { + type SimulateContractErrorType as viem_SimulateContractErrorType, + type SimulateContractParameters as viem_SimulateContractParameters, + type SimulateContractReturnType as viem_SimulateContractReturnType, + simulateContract as viem_simulateContract, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { BaseErrorType, ErrorType } from '../errors/base.js' +import type { SelectChains } from '../types/chain.js' +import type { + ChainIdParameter, + ConnectorParameter, +} from '../types/properties.js' +import type { + Compute, + PartialBy, + UnionCompute, + UnionStrictOmit, +} from '../types/utils.js' +import { getAction } from '../utils/getAction.js' +import { + type GetConnectorClientErrorType, + getConnectorClient, +} from './getConnectorClient.js' + +export type SimulateContractParameters< + abi extends Abi | readonly unknown[] = Abi, + functionName extends ContractFunctionName< + abi, + 'nonpayable' | 'payable' + > = ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + > = ContractFunctionArgs, + config extends Config = Config, + chainId extends + | config['chains'][number]['id'] + | undefined = config['chains'][number]['id'], + /// + chains extends readonly Chain[] = SelectChains, +> = { + [key in keyof chains]: UnionCompute< + UnionStrictOmit< + viem_SimulateContractParameters< + abi, + functionName, + args, + chains[key], + chains[key], + Account | Address + >, + 'chain' + > + > & + ChainIdParameter & + ConnectorParameter +}[number] + +export type SimulateContractReturnType< + abi extends Abi | readonly unknown[] = Abi, + functionName extends ContractFunctionName< + abi, + 'nonpayable' | 'payable' + > = ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + > = ContractFunctionArgs, + config extends Config = Config, + chainId extends + | config['chains'][number]['id'] + | undefined = config['chains'][number]['id'], + /// + chains extends readonly Chain[] = SelectChains, +> = { + [key in keyof chains]: viem_SimulateContractReturnType< + abi, + functionName, + args, + chains[key], + Account, + chains[key] + > & { + chainId: chains[key]['id'] + request: Compute< + PartialBy< + { chainId: chainId; chain: chains[key] }, + chainId extends config['chains'][number]['id'] ? never : 'chainId' + > + > + } +}[number] + +export type SimulateContractErrorType = + // getConnectorClient() + | GetConnectorClientErrorType + // base + | BaseErrorType + | ErrorType + // viem + | viem_SimulateContractErrorType + +/** https://wagmi.sh/core/api/actions/simulateContract */ +export async function simulateContract< + config extends Config, + const abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + >, + chainId extends config['chains'][number]['id'] | undefined = undefined, +>( + config: config, + parameters: SimulateContractParameters< + abi, + functionName, + args, + config, + chainId + >, +): Promise< + SimulateContractReturnType +> { + const { abi, chainId, connector, ...rest } = + parameters as SimulateContractParameters + + let account: Address | Account + if (parameters.account) account = parameters.account + else { + const connectorClient = await getConnectorClient(config, { + chainId, + connector, + }) + account = connectorClient.account + } + + const client = config.getClient({ chainId }) + const action = getAction(client, viem_simulateContract, 'simulateContract') + const { result, request } = await action({ ...rest, abi, account }) + + return { + chainId: client.chain.id, + result, + request: { ...request, chainId }, + } as unknown as SimulateContractReturnType< + abi, + functionName, + args, + config, + chainId + > +} diff --git a/wagmi-project/packages/core/src/actions/switchAccount.test.ts b/wagmi-project/packages/core/src/actions/switchAccount.test.ts new file mode 100644 index 0000000000..97d0e84b37 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/switchAccount.test.ts @@ -0,0 +1,32 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { getAccount } from './getAccount.js' +import { switchAccount } from './switchAccount.js' + +const connector1 = config.connectors[0]! +const connector2 = config.connectors[1]! + +test('default', async () => { + await connect(config, { connector: connector2 }) + await connect(config, { connector: connector1 }) + + const address1 = getAccount(config).address + + await switchAccount(config, { connector: connector2 }) + + const address2 = getAccount(config).address + expect(address2).toBeDefined() + expect(address1).not.toBe(address2) + + await switchAccount(config, { connector: connector1 }) + + const address3 = getAccount(config).address + expect(address3).toBeDefined() + expect(address1).toBe(address3) + + await disconnect(config, { connector: connector1 }) + await disconnect(config, { connector: connector2 }) +}) diff --git a/wagmi-project/packages/core/src/actions/switchAccount.ts b/wagmi-project/packages/core/src/actions/switchAccount.ts new file mode 100644 index 0000000000..ec577a57c7 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/switchAccount.ts @@ -0,0 +1,45 @@ +import type { Address } from 'viem' + +import type { Config, Connector } from '../createConfig.js' +import type { BaseError, ErrorType } from '../errors/base.js' +import { + ConnectorNotConnectedError, + type ConnectorNotConnectedErrorType, +} from '../errors/config.js' + +export type SwitchAccountParameters = { + connector: Connector +} + +export type SwitchAccountReturnType = { + accounts: readonly [Address, ...Address[]] + chainId: + | config['chains'][number]['id'] + | (number extends config['chains'][number]['id'] ? number : number & {}) +} + +export type SwitchAccountErrorType = + | ConnectorNotConnectedErrorType + | BaseError + | ErrorType + +/** https://wagmi.sh/core/api/actions/switchAccount */ +export async function switchAccount( + config: config, + parameters: SwitchAccountParameters, +): Promise> { + const { connector } = parameters + + const connection = config.state.connections.get(connector.uid) + if (!connection) throw new ConnectorNotConnectedError() + + await config.storage?.setItem('recentConnectorId', connector.id) + config.setState((x) => ({ + ...x, + current: connector.uid, + })) + return { + accounts: connection.accounts, + chainId: connection.chainId, + } +} diff --git a/wagmi-project/packages/core/src/actions/switchChain.test.ts b/wagmi-project/packages/core/src/actions/switchChain.test.ts new file mode 100644 index 0000000000..466d77824f --- /dev/null +++ b/wagmi-project/packages/core/src/actions/switchChain.test.ts @@ -0,0 +1,73 @@ +import { accounts, chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { mock } from '../connectors/mock.js' +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { getAccount } from './getAccount.js' +import { switchChain } from './switchChain.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const chainId1 = getAccount(config).chainId + + await switchChain(config, { chainId: chain.mainnet2.id }) + + const chainId2 = getAccount(config).chainId + expect(chainId2).toBeDefined() + expect(chainId1).not.toBe(chainId2) + + await switchChain(config, { chainId: chain.mainnet.id }) + + const chainId3 = getAccount(config).chainId + expect(chainId3).toBeDefined() + expect(chainId1).toBe(chainId3) + + await disconnect(config, { connector }) +}) + +test('behavior: user rejected request', async () => { + const connector_ = config._internal.connectors.setup( + mock({ + accounts, + features: { switchChainError: true }, + }), + ) + await connect(config, { connector: connector_ }) + await expect( + switchChain(config, { chainId: chain.mainnet.id }), + ).rejects.toMatchInlineSnapshot(` + [UserRejectedRequestError: User rejected the request. + + Details: Failed to switch chain. + Version: viem@2.29.2] + `) + await disconnect(config, { connector: connector_ }) +}) + +test('behavior: not supported', async () => { + const { switchChain: _, ...connector_ } = config._internal.connectors.setup( + mock({ accounts }), + ) + await connect(config, { connector: connector_ }) + await expect( + switchChain(config, { chainId: chain.mainnet.id }), + ).rejects.toMatchInlineSnapshot(` + [SwitchChainNotSupportedError: "Mock Connector" does not support programmatic chain switching. + + Version: @wagmi/core@x.y.z] + `) + await disconnect(config, { connector: connector_ }) +}) + +test('behavior: not connected', async () => { + const chainId = config.state.chainId + expect(config.state.chainId).toMatchInlineSnapshot('1') + await switchChain(config, { chainId: chain.mainnet2.id }) + expect(config.state.chainId).toMatchInlineSnapshot('456') + await switchChain(config, { chainId }) + expect(config.state.chainId).toMatchInlineSnapshot('1') +}) diff --git a/wagmi-project/packages/core/src/actions/switchChain.ts b/wagmi-project/packages/core/src/actions/switchChain.ts new file mode 100644 index 0000000000..59f337d141 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/switchChain.ts @@ -0,0 +1,83 @@ +import type { + AddEthereumChainParameter, + UserRejectedRequestErrorType, + SwitchChainErrorType as viem_SwitchChainErrorType, +} from 'viem' + +import type { Config } from '../createConfig.js' +import type { BaseErrorType, ErrorType } from '../errors/base.js' +import { + ChainNotConfiguredError, + type ChainNotConfiguredErrorType, +} from '../errors/config.js' +import { + type ProviderNotFoundErrorType, + SwitchChainNotSupportedError, + type SwitchChainNotSupportedErrorType, +} from '../errors/connector.js' +import type { ConnectorParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' + +export type SwitchChainParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = Compute< + ConnectorParameter & { + chainId: chainId | config['chains'][number]['id'] + addEthereumChainParameter?: + | Compute>> + | undefined + } +> + +export type SwitchChainReturnType< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = Extract< + config['chains'][number], + { id: Config extends config ? number : chainId } +> + +export type SwitchChainErrorType = + | SwitchChainNotSupportedErrorType + | ChainNotConfiguredErrorType + // connector.switchChain() + | ProviderNotFoundErrorType + | UserRejectedRequestErrorType + // base + | BaseErrorType + | ErrorType + // viem + | viem_SwitchChainErrorType + +/** https://wagmi.sh/core/api/actions/switchChain */ +export async function switchChain< + config extends Config, + chainId extends config['chains'][number]['id'], +>( + config: config, + parameters: SwitchChainParameters, +): Promise> { + const { addEthereumChainParameter, chainId } = parameters + + const connection = config.state.connections.get( + parameters.connector?.uid ?? config.state.current!, + ) + if (connection) { + const connector = connection.connector + if (!connector.switchChain) + throw new SwitchChainNotSupportedError({ connector }) + const chain = await connector.switchChain({ + addEthereumChainParameter, + chainId, + }) + return chain as SwitchChainReturnType + } + + const chain = config.chains.find((x) => x.id === chainId) + if (!chain) throw new ChainNotConfiguredError() + config.setState((x) => ({ ...x, chainId })) + return chain as SwitchChainReturnType +} diff --git a/wagmi-project/packages/core/src/actions/verifyMessage.test.ts b/wagmi-project/packages/core/src/actions/verifyMessage.test.ts new file mode 100644 index 0000000000..f2766cbea4 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/verifyMessage.test.ts @@ -0,0 +1,72 @@ +import { accounts, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { verifyMessage } from './verifyMessage.js' + +const eoaAddress = accounts[0] +const smartAccountAddress = '0x3FCf42e10CC70Fe75A62EB3aDD6D305Aa840d145' + +test('smart account: valid signature', async () => { + expect( + await verifyMessage(config, { + address: smartAccountAddress, + message: 'This is a test message for viem!', + signature: + '0xefd5fb29a274ea6682673d8b3caa9263e936d48d486e5df68893003e0a76496439594d12245008c6fba1c8e3ef28241cffe1bef27ff6bca487b167f261f329251c', + }), + ).toBe(true) +}) + +test('smart account: invalid signature', async () => { + expect( + await verifyMessage(config, { + address: smartAccountAddress, + message: 'This is a test message for viem!', + signature: '0xdead', + }), + ).toBe(false) +}) + +test('smart account: account not deployed', async () => { + expect( + await verifyMessage(config, { + blockNumber: 1234567890n, + address: smartAccountAddress, + message: 'This is a test message for viem!', + signature: + '0xefd5fb29a274ea6682673d8b3caa9263e936d48d486e5df68893003e0a76496439594d12245008c6fba1c8e3ef28241cffe1bef27ff6bca487b167f261f329251c', + }), + ).toBe(false) +}) + +test('eoa: valid signature', async () => { + expect( + await verifyMessage(config, { + address: eoaAddress, + message: 'This is a test message for viem!', + signature: + '0xc4c7f2820177020d66d5fd00d084cdd3f575a868c059c29a2d7f23398d04819709a14f83d98b446dda539ca5dcb87d75aa3340eb15e66d67606850622a3420f61b', + }), + ).toBe(true) +}) + +test('eoa: invalid signature', async () => { + expect( + await verifyMessage(config, { + address: eoaAddress, + message: 'This is a test message for viem!', + signature: '0xdead', + }), + ).toBe(false) +}) + +test('eoa: raw message', async () => { + expect( + await verifyMessage(config, { + address: eoaAddress, + message: { raw: '0x68656c6c6f20776f726c64' }, + signature: + '0xa461f509887bd19e312c0c58467ce8ff8e300d3c1a90b608a760c5b80318eaf15fe57c96f9175d6cd4daad4663763baa7e78836e067d0163e9a2ccf2ff753f5b1b', + }), + ).toBe(true) +}) diff --git a/wagmi-project/packages/core/src/actions/verifyMessage.ts b/wagmi-project/packages/core/src/actions/verifyMessage.ts new file mode 100644 index 0000000000..851f8589fa --- /dev/null +++ b/wagmi-project/packages/core/src/actions/verifyMessage.ts @@ -0,0 +1,30 @@ +import { + type VerifyMessageErrorType as viem_VerifyMessageErrorType, + type VerifyMessageParameters as viem_VerifyMessageParameters, + type VerifyMessageReturnType as viem_VerifyMessageReturnType, + verifyMessage as viem_verifyMessage, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type VerifyMessageParameters = Compute< + viem_VerifyMessageParameters & ChainIdParameter +> + +export type VerifyMessageReturnType = viem_VerifyMessageReturnType + +export type VerifyMessageErrorType = viem_VerifyMessageErrorType + +/** https://wagmi.sh/core/api/actions/verifyMessage */ +export async function verifyMessage( + config: config, + parameters: VerifyMessageParameters, +): Promise { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction(client, viem_verifyMessage, 'verifyMessage') + return action(rest) +} diff --git a/wagmi-project/packages/core/src/actions/verifyTypedData.test.ts b/wagmi-project/packages/core/src/actions/verifyTypedData.test.ts new file mode 100644 index 0000000000..c4b98c68dc --- /dev/null +++ b/wagmi-project/packages/core/src/actions/verifyTypedData.test.ts @@ -0,0 +1,42 @@ +import { config, typedData } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { verifyTypedData } from './verifyTypedData.js' + +const smartAccountAddress = '0x3FCf42e10CC70Fe75A62EB3aDD6D305Aa840d145' +const notDeployedAddress = '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef' + +test('valid signature', async () => { + expect( + await verifyTypedData(config, { + ...typedData.basic, + primaryType: 'Mail', + address: smartAccountAddress, + signature: + '0x79d756d805073dc97b7bc885b0d56ddf319a2599530fe1e178c2a7de5be88980068d24f20a79b318ea0a84d33ae06f93db77e4235e5d9eeb8b1d7a63922ada3e1c', + }), + ).toBe(true) +}) + +test('invalid signature', async () => { + expect( + await verifyTypedData(config, { + ...typedData.basic, + primaryType: 'Mail', + address: smartAccountAddress, + signature: '0xdead', + }), + ).toBe(false) +}) + +test('account not deployed', async () => { + expect( + await verifyTypedData(config, { + ...typedData.basic, + primaryType: 'Mail', + address: notDeployedAddress, + signature: + '0x79d756d805073dc97b7bc885b0d56ddf319a2599530fe1e178c2a7de5be88980068d24f20a79b318ea0a84d33ae06f93db77e4235e5d9eeb8b1d7a63922ada3e1c', + }), + ).toBe(false) +}) diff --git a/wagmi-project/packages/core/src/actions/verifyTypedData.ts b/wagmi-project/packages/core/src/actions/verifyTypedData.ts new file mode 100644 index 0000000000..4fac5463f5 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/verifyTypedData.ts @@ -0,0 +1,40 @@ +import type { TypedData } from 'viem' +import { + type VerifyTypedDataErrorType as viem_VerifyTypedDataErrorType, + type VerifyTypedDataParameters as viem_VerifyTypedDataParameters, + type VerifyTypedDataReturnType as viem_VerifyTypedDataReturnType, + verifyTypedData as viem_verifyTypedData, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type VerifyTypedDataParameters< + typedData extends TypedData | Record = TypedData, + primaryType extends keyof typedData | 'EIP712Domain' = keyof typedData, + config extends Config = Config, +> = Compute< + viem_VerifyTypedDataParameters & + ChainIdParameter +> + +export type VerifyTypedDataReturnType = viem_VerifyTypedDataReturnType + +export type VerifyTypedDataErrorType = viem_VerifyTypedDataErrorType + +/** https://wagmi.sh/core/api/actions/verifyTypedData */ +export async function verifyTypedData< + config extends Config, + const typedData extends TypedData | Record, + primaryType extends keyof typedData | 'EIP712Domain', +>( + config: config, + parameters: VerifyTypedDataParameters, +): Promise { + const { chainId, ...rest } = parameters + const client = config.getClient({ chainId }) + const action = getAction(client, viem_verifyTypedData, 'verifyTypedData') + return action(rest as viem_VerifyTypedDataParameters) +} diff --git a/wagmi-project/packages/core/src/actions/waitForCallsStatus.test.ts b/wagmi-project/packages/core/src/actions/waitForCallsStatus.test.ts new file mode 100644 index 0000000000..338fe02616 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/waitForCallsStatus.test.ts @@ -0,0 +1,77 @@ +import { accounts, config, testClient, wait } from '@wagmi/test' +import { parseEther } from 'viem' +import { expect, test } from 'vitest' + +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { sendCalls } from './sendCalls.js' +import { waitForCallsStatus } from './waitForCallsStatus.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const { id } = await sendCalls(config, { + calls: [ + { + data: '0xdeadbeef', + to: accounts[1], + value: parseEther('1'), + }, + { + to: accounts[2], + value: parseEther('2'), + }, + { + to: accounts[3], + value: parseEther('3'), + }, + ], + }) + + const [{ receipts, status }] = await Promise.all([ + waitForCallsStatus(config, { + id, + }), + (async () => { + await wait(100) + await testClient.mainnet.mine({ blocks: 1 }) + })(), + ]) + + expect(status).toBe('success') + expect( + receipts?.map((x) => ({ ...x, blockHash: undefined })), + ).toMatchInlineSnapshot( + ` + [ + { + "blockHash": undefined, + "blockNumber": 19258214n, + "gasUsed": 21064n, + "logs": [], + "status": "success", + "transactionHash": "0x13c53b2d4d9da424835525349cd66e553330f323d6fb19458b801ae1f7989a41", + }, + { + "blockHash": undefined, + "blockNumber": 19258214n, + "gasUsed": 21000n, + "logs": [], + "status": "success", + "transactionHash": "0xd8397b3e82b061c26a0c2093f1ceca0c3662a512614f7d6370349e89d0eea007", + }, + { + "blockHash": undefined, + "blockNumber": 19258214n, + "gasUsed": 21000n, + "logs": [], + "status": "success", + "transactionHash": "0x4d26e346593d9ea265bb164b115e89aa92df43b0b8778ac75d4ad28e2a22b101", + }, + ] + `, + ) + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/core/src/actions/waitForCallsStatus.ts b/wagmi-project/packages/core/src/actions/waitForCallsStatus.ts new file mode 100644 index 0000000000..a1c5764d32 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/waitForCallsStatus.ts @@ -0,0 +1,27 @@ +import { + type WaitForCallsStatusErrorType as viem_WaitForCallsStatusErrorType, + type WaitForCallsStatusParameters as viem_WaitForCallsStatusParameters, + type WaitForCallsStatusReturnType as viem_WaitForCallsStatusReturnType, + waitForCallsStatus as viem_waitForCallsStatus, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { ConnectorParameter } from '../types/properties.js' +import { getConnectorClient } from './getConnectorClient.js' + +export type WaitForCallsStatusParameters = viem_WaitForCallsStatusParameters & + ConnectorParameter + +export type WaitForCallsStatusReturnType = viem_WaitForCallsStatusReturnType + +export type WaitForCallsStatusErrorType = viem_WaitForCallsStatusErrorType + +/** https://wagmi.sh/core/api/actions/waitForCallsStatus */ +export async function waitForCallsStatus( + config: config, + parameters: WaitForCallsStatusParameters, +): Promise { + const { connector } = parameters + const client = await getConnectorClient(config, { connector }) + return viem_waitForCallsStatus(client, parameters) +} diff --git a/wagmi-project/packages/core/src/actions/waitForTransactionReceipt.test-d.ts b/wagmi-project/packages/core/src/actions/waitForTransactionReceipt.test-d.ts new file mode 100644 index 0000000000..0cce58d1e4 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/waitForTransactionReceipt.test-d.ts @@ -0,0 +1,36 @@ +import { http } from 'viem' +import { mainnet, zkSync } from 'viem/chains' +import type { ZkSyncL2ToL1Log, ZkSyncLog } from 'viem/zksync' +import { expectTypeOf, test } from 'vitest' + +import { createConfig } from '../createConfig.js' +import { waitForTransactionReceipt } from './waitForTransactionReceipt.js' + +test('chain formatters', async () => { + const config = createConfig({ + chains: [mainnet, zkSync], + transports: { [mainnet.id]: http(), [zkSync.id]: http() }, + }) + const result = await waitForTransactionReceipt(config, { hash: '0x123' }) + if (result.chainId === zkSync.id) { + expectTypeOf(result.l1BatchNumber).toEqualTypeOf() + expectTypeOf(result.l1BatchTxIndex).toEqualTypeOf() + expectTypeOf(result.logs).toEqualTypeOf() + expectTypeOf(result.l2ToL1Logs).toEqualTypeOf() + } +}) + +test('chainId', async () => { + const config = createConfig({ + chains: [zkSync], + transports: { [zkSync.id]: http() }, + }) + const result = await waitForTransactionReceipt(config, { + hash: '0x123', + chainId: zkSync.id, + }) + expectTypeOf(result.l1BatchNumber).toEqualTypeOf() + expectTypeOf(result.l1BatchTxIndex).toEqualTypeOf() + expectTypeOf(result.logs).toEqualTypeOf() + expectTypeOf(result.l2ToL1Logs).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/core/src/actions/waitForTransactionReceipt.test.ts b/wagmi-project/packages/core/src/actions/waitForTransactionReceipt.test.ts new file mode 100644 index 0000000000..c060e82665 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/waitForTransactionReceipt.test.ts @@ -0,0 +1,58 @@ +import { config, testClient, wait } from '@wagmi/test' +import { parseEther } from 'viem' +import { beforeEach, expect, test } from 'vitest' + +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { sendTransaction } from './sendTransaction.js' +import { waitForTransactionReceipt } from './waitForTransactionReceipt.js' + +const connector = config.connectors[0]! + +beforeEach(async () => { + if (config.state.current === connector.uid) + await disconnect(config, { connector }) +}) + +test('default', async () => { + await connect(config, { connector }) + + const hash = await sendTransaction(config, { + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }) + + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + + await expect( + waitForTransactionReceipt(config, { hash }), + ).resolves.toMatchObject({ + chainId: 1, + transactionHash: hash, + }) + + await disconnect(config, { connector }) +}) + +test('behavior: transaction reverted', async () => { + await expect( + waitForTransactionReceipt(config, { + hash: '0x745367f76807d411b7fa4c3a552a62e3e45303ef40145fff04d84b867c2575d3', + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [CallExecutionError: Execution reverted with reason: PartyBid::claim: contribution already claimed. + + Raw Call Arguments: + to: 0xf1332f21487e74612ed3a0fb36da729b73f1ae19 + value: 0 ETH + data: 0x1e83409a000000000000000000000000a0cf798816d4b9b9866b5330eea46a18382f251e + gas: 128730 + maxFeePerGas: 43.307900987 gwei + maxPriorityFeePerGas: 1.5 gwei + nonce: 43 + + Details: execution reverted: PartyBid::claim: contribution already claimed + Version: viem@2.29.2] + `) +}) diff --git a/wagmi-project/packages/core/src/actions/waitForTransactionReceipt.ts b/wagmi-project/packages/core/src/actions/waitForTransactionReceipt.ts new file mode 100644 index 0000000000..5ac8fcdb20 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/waitForTransactionReceipt.ts @@ -0,0 +1,86 @@ +import type { Chain } from 'viem' +import { hexToString } from 'viem' +import { + call, + getTransaction, + type WaitForTransactionReceiptErrorType as viem_WaitForTransactionReceiptErrorType, + type WaitForTransactionReceiptParameters as viem_WaitForTransactionReceiptParameters, + type WaitForTransactionReceiptReturnType as viem_WaitForTransactionReceiptReturnType, + waitForTransactionReceipt as viem_waitForTransactionReceipt, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { SelectChains } from '../types/chain.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { Compute, IsNarrowable } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type WaitForTransactionReceiptParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = Compute< + viem_WaitForTransactionReceiptParameters & ChainIdParameter +> + +export type WaitForTransactionReceiptReturnType< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + /// + chains extends readonly Chain[] = SelectChains, +> = Compute< + { + [key in keyof chains]: viem_WaitForTransactionReceiptReturnType< + IsNarrowable extends true ? chains[key] : undefined + > & { chainId: chains[key]['id'] } + }[number] +> + +export type WaitForTransactionReceiptErrorType = + viem_WaitForTransactionReceiptErrorType + +export async function waitForTransactionReceipt< + config extends Config, + chainId extends config['chains'][number]['id'], +>( + config: config, + parameters: WaitForTransactionReceiptParameters, +): Promise> { + const { chainId, timeout = 0, ...rest } = parameters + + const client = config.getClient({ chainId }) + const action = getAction( + client, + viem_waitForTransactionReceipt, + 'waitForTransactionReceipt', + ) + const receipt = await action({ ...rest, timeout }) + + if (receipt.status === 'reverted') { + const action_getTransaction = getAction( + client, + getTransaction, + 'getTransaction', + ) + const txn = await action_getTransaction({ hash: receipt.transactionHash }) + const action_call = getAction(client, call, 'call') + const code = await action_call({ + ...(txn as any), + data: txn.input, + gasPrice: txn.type !== 'eip1559' ? txn.gasPrice : undefined, + maxFeePerGas: txn.type === 'eip1559' ? txn.maxFeePerGas : undefined, + maxPriorityFeePerGas: + txn.type === 'eip1559' ? txn.maxPriorityFeePerGas : undefined, + }) + const reason = code?.data + ? hexToString(`0x${code.data.substring(138)}`) + : 'unknown reason' + throw new Error(reason) + } + + return { + ...receipt, + chainId: client.chain.id, + } as WaitForTransactionReceiptReturnType +} diff --git a/wagmi-project/packages/core/src/actions/watchAccount.test.ts b/wagmi-project/packages/core/src/actions/watchAccount.test.ts new file mode 100644 index 0000000000..c803165888 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchAccount.test.ts @@ -0,0 +1,38 @@ +import { config } from '@wagmi/test' +import type { Address } from 'viem' +import { expect, test } from 'vitest' + +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { watchAccount } from './watchAccount.js' + +test('default', async () => { + const accounts: { address: Address | undefined; status: string }[] = [] + const unwatch = watchAccount(config, { + onChange(data) { + accounts.push({ address: data.address, status: data.status }) + }, + }) + + await connect(config, { connector: config.connectors[0]! }) + await disconnect(config) + + expect(accounts).toMatchInlineSnapshot(` + [ + { + "address": undefined, + "status": "connecting", + }, + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "status": "connected", + }, + { + "address": undefined, + "status": "disconnected", + }, + ] + `) + + unwatch() +}) diff --git a/wagmi-project/packages/core/src/actions/watchAccount.ts b/wagmi-project/packages/core/src/actions/watchAccount.ts new file mode 100644 index 0000000000..dfa8ae4908 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchAccount.ts @@ -0,0 +1,33 @@ +import type { Config } from '../createConfig.js' +import { deepEqual } from '../utils/deepEqual.js' +import { type GetAccountReturnType, getAccount } from './getAccount.js' + +export type WatchAccountParameters = { + onChange( + account: GetAccountReturnType, + prevAccount: GetAccountReturnType, + ): void +} + +export type WatchAccountReturnType = () => void + +/** https://wagmi.sh/core/api/actions/watchAccount */ +export function watchAccount( + config: config, + parameters: WatchAccountParameters, +): WatchAccountReturnType { + const { onChange } = parameters + + return config.subscribe(() => getAccount(config), onChange, { + equalityFn(a, b) { + const { connector: aConnector, ...aRest } = a + const { connector: bConnector, ...bRest } = b + return ( + deepEqual(aRest, bRest) && + // check connector separately + aConnector?.id === bConnector?.id && + aConnector?.uid === bConnector?.uid + ) + }, + }) +} diff --git a/wagmi-project/packages/core/src/actions/watchAsset.test.ts b/wagmi-project/packages/core/src/actions/watchAsset.test.ts new file mode 100644 index 0000000000..6d4cd86b58 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchAsset.test.ts @@ -0,0 +1,23 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { watchAsset } from './watchAsset.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + await expect( + watchAsset(config, { + type: 'ERC20', + options: { + address: '0x0000000000000000000000000000000000000000', + symbol: 'NULL', + decimals: 18, + }, + }), + ).resolves.toMatchInlineSnapshot('true') + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/core/src/actions/watchAsset.ts b/wagmi-project/packages/core/src/actions/watchAsset.ts new file mode 100644 index 0000000000..cd5690bf57 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchAsset.ts @@ -0,0 +1,44 @@ +import { + type WatchAssetErrorType as viem_WatchAssetErrorType, + type WatchAssetParameters as viem_WatchAssetParameters, + type WatchAssetReturnType as viem_WatchAssetReturnType, + watchAsset as viem_watchAsset, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { BaseErrorType, ErrorType } from '../errors/base.js' +import type { ConnectorParameter } from '../types/properties.js' +import type { Compute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' +import { + type GetConnectorClientErrorType, + getConnectorClient, +} from './getConnectorClient.js' + +export type WatchAssetParameters = Compute< + viem_WatchAssetParameters & ConnectorParameter +> + +export type WatchAssetReturnType = viem_WatchAssetReturnType + +export type WatchAssetErrorType = + // getConnectorClient() + | GetConnectorClientErrorType + // base + | BaseErrorType + | ErrorType + // viem + | viem_WatchAssetErrorType + +/** https://wagmi.sh/core/api/actions/watchAsset */ +export async function watchAsset( + config: Config, + parameters: WatchAssetParameters, +): Promise { + const { connector, ...rest } = parameters + + const client = await getConnectorClient(config, { connector }) + + const action = getAction(client, viem_watchAsset, 'watchAsset') + return action(rest as viem_WatchAssetParameters) +} diff --git a/wagmi-project/packages/core/src/actions/watchBlockNumber.test-d.ts b/wagmi-project/packages/core/src/actions/watchBlockNumber.test-d.ts new file mode 100644 index 0000000000..ae63ed8af6 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchBlockNumber.test-d.ts @@ -0,0 +1,56 @@ +import { http, webSocket } from 'viem' +import { mainnet, optimism } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { createConfig } from '../createConfig.js' +import { + type WatchBlockNumberParameters, + watchBlockNumber, +} from './watchBlockNumber.js' + +test('differing transports', () => { + const config = createConfig({ + chains: [mainnet, optimism], + transports: { + [mainnet.id]: http(), + [optimism.id]: webSocket(), + }, + }) + + type Result = WatchBlockNumberParameters< + typeof config, + typeof mainnet.id | typeof optimism.id + > + expectTypeOf().toEqualTypeOf() + watchBlockNumber(config, { + poll: false, + onBlockNumber() {}, + }) + + type Result2 = WatchBlockNumberParameters + expectTypeOf().toEqualTypeOf() + watchBlockNumber(config, { + chainId: mainnet.id, + poll: true, + onBlockNumber() {}, + }) + watchBlockNumber(config, { + chainId: mainnet.id, + // @ts-expect-error + poll: false, + onBlockNumber() {}, + }) + + type Result3 = WatchBlockNumberParameters + expectTypeOf().toEqualTypeOf() + watchBlockNumber(config, { + chainId: optimism.id, + poll: true, + onBlockNumber() {}, + }) + watchBlockNumber(config, { + chainId: optimism.id, + poll: false, + onBlockNumber() {}, + }) +}) diff --git a/wagmi-project/packages/core/src/actions/watchBlockNumber.test.ts b/wagmi-project/packages/core/src/actions/watchBlockNumber.test.ts new file mode 100644 index 0000000000..0a4299db58 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchBlockNumber.test.ts @@ -0,0 +1,27 @@ +import { config, testClient, wait } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { watchBlockNumber } from './watchBlockNumber.js' + +test('default', async () => { + const blockNumbers: bigint[] = [] + const unwatch = watchBlockNumber(config, { + onBlockNumber(blockNumber) { + blockNumbers.push(blockNumber) + }, + }) + + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + + expect(blockNumbers.length).toBe(3) + expect( + blockNumbers.map((blockNumber) => blockNumber - blockNumbers[0]!), + ).toEqual([0n, 1n, 2n]) + + unwatch() +}) diff --git a/wagmi-project/packages/core/src/actions/watchBlockNumber.ts b/wagmi-project/packages/core/src/actions/watchBlockNumber.ts new file mode 100644 index 0000000000..712849080a --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchBlockNumber.ts @@ -0,0 +1,78 @@ +import { + type WatchBlockNumberParameters as viem_WatchBlockNumberParameters, + type WatchBlockNumberReturnType as viem_WatchBlockNumberReturnType, + watchBlockNumber as viem_watchBlockNumber, +} from 'viem/actions' + +import type { Chain, Transport, WebSocketTransport } from 'viem' +import type { Config } from '../createConfig.js' +import type { SelectChains } from '../types/chain.js' +import type { + ChainIdParameter, + SyncConnectedChainParameter, +} from '../types/properties.js' +import type { UnionCompute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type WatchBlockNumberParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + /// + chains extends readonly Chain[] = SelectChains, +> = { + [key in keyof chains]: UnionCompute< + viem_WatchBlockNumberParameters< + config['_internal']['transports'][chains[key]['id']] extends infer transport extends + Transport + ? Transport extends transport + ? WebSocketTransport + : transport + : WebSocketTransport + > & + ChainIdParameter & + SyncConnectedChainParameter + > +}[number] + +export type WatchBlockNumberReturnType = viem_WatchBlockNumberReturnType + +// TODO: wrap in viem's `observe` to avoid duplicate invocations. +/** https://wagmi.sh/core/api/actions/watchBlockNumber */ +export function watchBlockNumber< + config extends Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +>( + config: config, + parameters: WatchBlockNumberParameters, +): WatchBlockNumberReturnType { + const { syncConnectedChain = config._internal.syncConnectedChain, ...rest } = + parameters as WatchBlockNumberParameters + + let unwatch: WatchBlockNumberReturnType | undefined + const listener = (chainId: number | undefined) => { + if (unwatch) unwatch() + + const client = config.getClient({ chainId }) + const action = getAction(client, viem_watchBlockNumber, 'watchBlockNumber') + unwatch = action(rest as viem_WatchBlockNumberParameters) + return unwatch + } + + // set up listener for block number changes + const unlisten = listener(parameters.chainId) + + // set up subscriber for connected chain changes + let unsubscribe: (() => void) | undefined + if (syncConnectedChain && !parameters.chainId) + unsubscribe = config.subscribe( + ({ chainId }) => chainId, + async (chainId) => listener(chainId), + ) + + return () => { + unlisten?.() + unsubscribe?.() + } +} diff --git a/wagmi-project/packages/core/src/actions/watchBlocks.test-d.ts b/wagmi-project/packages/core/src/actions/watchBlocks.test-d.ts new file mode 100644 index 0000000000..1899dcb1ae --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchBlocks.test-d.ts @@ -0,0 +1,59 @@ +import { http, webSocket } from 'viem' +import { mainnet, optimism } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { createConfig } from '../createConfig.js' +import { type WatchBlocksParameters, watchBlocks } from './watchBlocks.js' + +test('differing transports', () => { + const config = createConfig({ + chains: [mainnet, optimism], + transports: { + [mainnet.id]: http(), + [optimism.id]: webSocket(), + }, + }) + + type Result = WatchBlocksParameters< + false, + 'latest', + typeof config, + typeof mainnet.id | typeof optimism.id + > + expectTypeOf().toEqualTypeOf() + watchBlocks(config, { + poll: false, + onBlock() {}, + }) + + type Result2 = WatchBlocksParameters< + false, + 'latest', + typeof config, + typeof mainnet.id + > + expectTypeOf().toEqualTypeOf() + watchBlocks(config, { + chainId: mainnet.id, + poll: true, + onBlock() {}, + }) + + type Result3 = WatchBlocksParameters< + false, + 'latest', + typeof config, + typeof optimism.id + > + expectTypeOf().toEqualTypeOf() + watchBlocks(config, { + chainId: optimism.id, + poll: true, + onBlock() {}, + }) + watchBlocks(config, { + chainId: optimism.id, + poll: false, + onBlock() {}, + }) +}) diff --git a/wagmi-project/packages/core/src/actions/watchBlocks.test.ts b/wagmi-project/packages/core/src/actions/watchBlocks.test.ts new file mode 100644 index 0000000000..caf4c0dc61 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchBlocks.test.ts @@ -0,0 +1,30 @@ +import { config, testClient, wait } from '@wagmi/test' +import { expect, test } from 'vitest' + +import type { Block } from 'viem' +import { watchBlocks } from './watchBlocks.js' + +test('default', async () => { + const blocks: Block[] = [] + const unwatch = watchBlocks(config, { + onBlock(block) { + blocks.push(block) + }, + }) + + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + + expect(blocks.length).toBe(3) + expect(blocks.map((block) => block.number! - blocks[0]?.number!)).toEqual([ + 0n, + 1n, + 2n, + ]) + + unwatch() +}) diff --git a/wagmi-project/packages/core/src/actions/watchBlocks.ts b/wagmi-project/packages/core/src/actions/watchBlocks.ts new file mode 100644 index 0000000000..c6f3225dc9 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchBlocks.ts @@ -0,0 +1,90 @@ +import { + type WatchBlocksParameters as viem_WatchBlocksParameters, + type WatchBlocksReturnType as viem_WatchBlocksReturnType, + watchBlocks as viem_watchBlocks, +} from 'viem/actions' + +import type { BlockTag, Chain, Transport, WebSocketTransport } from 'viem' +import type { Config } from '../createConfig.js' +import type { SelectChains } from '../types/chain.js' +import type { + ChainIdParameter, + SyncConnectedChainParameter, +} from '../types/properties.js' +import type { IsNarrowable, UnionCompute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type WatchBlocksParameters< + includeTransactions extends boolean = false, + blockTag extends BlockTag = 'latest', + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + /// + chains extends readonly Chain[] = SelectChains, +> = { + [key in keyof chains]: UnionCompute< + viem_WatchBlocksParameters< + config['_internal']['transports'][chains[key]['id']] extends infer transport extends + Transport + ? Transport extends transport + ? WebSocketTransport + : transport + : WebSocketTransport, + IsNarrowable extends true ? chains[key] : undefined, + includeTransactions, + blockTag + > & + ChainIdParameter & + SyncConnectedChainParameter + > +}[number] + +export type WatchBlocksReturnType = viem_WatchBlocksReturnType + +// TODO: wrap in viem's `observe` to avoid duplicate invocations. +/** https://wagmi.sh/core/actions/watchBlocks */ +export function watchBlocks< + config extends Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + includeTransactions extends boolean = false, + blockTag extends BlockTag = 'latest', +>( + config: config, + parameters: WatchBlocksParameters< + includeTransactions, + blockTag, + config, + chainId + >, +): WatchBlocksReturnType { + const { syncConnectedChain = config._internal.syncConnectedChain, ...rest } = + parameters as WatchBlocksParameters + + let unwatch: WatchBlocksReturnType | undefined + const listener = (chainId: number | undefined) => { + if (unwatch) unwatch() + + const client = config.getClient({ chainId }) + const action = getAction(client, viem_watchBlocks, 'watchBlocks') + unwatch = action(rest as viem_WatchBlocksParameters) + return unwatch + } + + // set up listener for block number changes + const unlisten = listener(parameters.chainId) + + // set up subscriber for connected chain changes + let unsubscribe: (() => void) | undefined + if (syncConnectedChain && !parameters.chainId) + unsubscribe = config.subscribe( + ({ chainId }) => chainId, + async (chainId) => listener(chainId), + ) + + return () => { + unlisten?.() + unsubscribe?.() + } +} diff --git a/wagmi-project/packages/core/src/actions/watchChainId.test.ts b/wagmi-project/packages/core/src/actions/watchChainId.test.ts new file mode 100644 index 0000000000..9e27ba7edd --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchChainId.test.ts @@ -0,0 +1,26 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { watchChainId } from './watchChainId.js' + +test('default', async () => { + const chainIds: number[] = [] + const unwatch = watchChainId(config, { + onChange(chainId) { + chainIds.push(chainId) + }, + }) + config.setState((x) => ({ ...x, chainId: chain.mainnet2.id })) + config.setState((x) => ({ ...x, chainId: chain.mainnet.id })) + config.setState((x) => ({ ...x, chainId: chain.mainnet2.id })) + + expect(chainIds).toMatchInlineSnapshot(` + [ + 456, + 1, + 456, + ] + `) + + unwatch() +}) diff --git a/wagmi-project/packages/core/src/actions/watchChainId.ts b/wagmi-project/packages/core/src/actions/watchChainId.ts new file mode 100644 index 0000000000..e3d4f010a4 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchChainId.ts @@ -0,0 +1,20 @@ +import type { Config } from '../createConfig.js' +import type { GetChainIdReturnType } from './getChainId.js' + +export type WatchChainIdParameters = { + onChange( + chainId: GetChainIdReturnType, + prevChainId: GetChainIdReturnType, + ): void +} + +export type WatchChainIdReturnType = () => void + +/** https://wagmi.sh/core/api/actions/watchChainId */ +export function watchChainId( + config: config, + parameters: WatchChainIdParameters, +): WatchChainIdReturnType { + const { onChange } = parameters + return config.subscribe((state) => state.chainId, onChange) +} diff --git a/wagmi-project/packages/core/src/actions/watchChains.test.ts b/wagmi-project/packages/core/src/actions/watchChains.test.ts new file mode 100644 index 0000000000..d7d586a833 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchChains.test.ts @@ -0,0 +1,37 @@ +import { chain, config } from '@wagmi/test' +import type { Chain } from 'viem' +import { expect, test } from 'vitest' + +import { watchChains } from './watchChains.js' + +test('default', async () => { + let chains: readonly [Chain, ...Chain[]] = config.chains + const unwatch = watchChains(config, { + onChange(nextChains) { + chains = nextChains + }, + }) + + config._internal.chains.setState([chain.mainnet, chain.mainnet2]) + expect(chains.map((x) => x.id)).toMatchInlineSnapshot(` + [ + 1, + 456, + ] + `) + + config._internal.chains.setState([ + chain.mainnet, + chain.mainnet2, + chain.optimism, + ]) + expect(chains.map((x) => x.id)).toMatchInlineSnapshot(` + [ + 1, + 456, + 10, + ] + `) + + unwatch() +}) diff --git a/wagmi-project/packages/core/src/actions/watchChains.ts b/wagmi-project/packages/core/src/actions/watchChains.ts new file mode 100644 index 0000000000..db5c496d5a --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchChains.ts @@ -0,0 +1,29 @@ +import type { Config } from '../createConfig.js' +import type { GetChainsReturnType } from './getChains.js' + +export type WatchChainsParameters = { + onChange( + chains: GetChainsReturnType, + prevChains: GetChainsReturnType, + ): void +} + +export type WatchChainsReturnType = () => void + +/** + * @internal + * We don't expose this because as far as consumers know, you can't chainge (lol) `config.chains` at runtime. + * Setting `config.chains` via `config._internal.chains.setState(...)` is an extremely advanced use case that's not worth documenting or supporting in the public API at this time. + */ +export function watchChains( + config: config, + parameters: WatchChainsParameters, +): WatchChainsReturnType { + const { onChange } = parameters + return config._internal.chains.subscribe((chains, prevChains) => { + onChange( + chains as unknown as GetChainsReturnType, + prevChains as unknown as GetChainsReturnType, + ) + }) +} diff --git a/wagmi-project/packages/core/src/actions/watchClient.test-d.ts b/wagmi-project/packages/core/src/actions/watchClient.test-d.ts new file mode 100644 index 0000000000..42830f02c3 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchClient.test-d.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { watchClient } from './watchClient.js' + +test('default', () => { + watchClient(config, { + onChange(client) { + expectTypeOf(client.chain).toEqualTypeOf< + (typeof config)['chains'][number] + >() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() + }, + }) +}) diff --git a/wagmi-project/packages/core/src/actions/watchClient.test.ts b/wagmi-project/packages/core/src/actions/watchClient.test.ts new file mode 100644 index 0000000000..9cb5f447d2 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchClient.test.ts @@ -0,0 +1,23 @@ +import { config } from '@wagmi/test' +import type { Client } from 'viem' +import { expect, test } from 'vitest' + +import { switchChain } from './switchChain.js' +import { watchClient } from './watchClient.js' + +test('default', async () => { + const clients: Client[] = [] + const unwatch = watchClient(config, { + onChange(client) { + clients.push(client) + }, + }) + + switchChain(config, { chainId: 456 }) + switchChain(config, { chainId: 10 }) + switchChain(config, { chainId: 1 }) + + expect(clients.length).toBe(3) + + unwatch() +}) diff --git a/wagmi-project/packages/core/src/actions/watchClient.ts b/wagmi-project/packages/core/src/actions/watchClient.ts new file mode 100644 index 0000000000..4247353537 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchClient.ts @@ -0,0 +1,35 @@ +import type { Config } from '../createConfig.js' +import { type GetClientReturnType, getClient } from './getClient.js' + +export type WatchClientParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = { + onChange( + publicClient: GetClientReturnType, + prevClient: GetClientReturnType, + ): void +} + +export type WatchClientReturnType = () => void + +/** https://wagmi.sh/core/api/actions/watchClient */ +export function watchClient< + config extends Config, + chainId extends config['chains'][number]['id'], +>( + config: config, + parameters: WatchClientParameters, +): WatchClientReturnType { + const { onChange } = parameters + return config.subscribe( + () => getClient(config) as GetClientReturnType, + onChange, + { + equalityFn(a, b) { + return a?.uid === b?.uid + }, + }, + ) +} diff --git a/wagmi-project/packages/core/src/actions/watchConnections.test.ts b/wagmi-project/packages/core/src/actions/watchConnections.test.ts new file mode 100644 index 0000000000..9ddf4444ab --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchConnections.test.ts @@ -0,0 +1,25 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import type { Connection } from '../createConfig.js' +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { watchConnections } from './watchConnections.js' + +test('default', async () => { + const connections: Connection[][] = [] + const unwatch = watchConnections(config, { + onChange(connection) { + connections.push(connection) + }, + }) + + const connector = config.connectors[0]! + expect(connections).toEqual([]) + await connect(config, { connector }) + expect(connections[0]?.length).toEqual(1) + await disconnect(config, { connector }) + expect(connections[1]).toEqual([]) + + unwatch() +}) diff --git a/wagmi-project/packages/core/src/actions/watchConnections.ts b/wagmi-project/packages/core/src/actions/watchConnections.ts new file mode 100644 index 0000000000..56b94fd455 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchConnections.ts @@ -0,0 +1,26 @@ +import type { Config } from '../createConfig.js' +import { deepEqual } from '../utils/deepEqual.js' +import { + type GetConnectionsReturnType, + getConnections, +} from './getConnections.js' + +export type WatchConnectionsParameters = { + onChange( + connections: GetConnectionsReturnType, + prevConnections: GetConnectionsReturnType, + ): void +} + +export type WatchConnectionsReturnType = () => void + +/** https://wagmi.sh/core/api/actions/watchConnections */ +export function watchConnections( + config: Config, + parameters: WatchConnectionsParameters, +): WatchConnectionsReturnType { + const { onChange } = parameters + return config.subscribe(() => getConnections(config), onChange, { + equalityFn: deepEqual, + }) +} diff --git a/wagmi-project/packages/core/src/actions/watchConnectors.test.ts b/wagmi-project/packages/core/src/actions/watchConnectors.test.ts new file mode 100644 index 0000000000..6e66f75f93 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchConnectors.test.ts @@ -0,0 +1,27 @@ +import { accounts, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { mock } from '../connectors/mock.js' +import type { Connector } from '../createConfig.js' +import { watchConnectors } from './watchConnectors.js' + +test('default', async () => { + const connectors: (readonly Connector[])[] = [] + const unwatch = watchConnectors(config, { + onChange(connector) { + connectors.push(connector) + }, + }) + + const count = config.connectors.length + expect(config.connectors).toEqual(config.connectors) + + config._internal.connectors.setState(() => [ + ...config.connectors, + config._internal.connectors.setup(mock({ accounts })), + ]) + + expect(config.connectors.length).toBe(count + 1) + + unwatch() +}) diff --git a/wagmi-project/packages/core/src/actions/watchConnectors.ts b/wagmi-project/packages/core/src/actions/watchConnectors.ts new file mode 100644 index 0000000000..e463ab52fa --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchConnectors.ts @@ -0,0 +1,22 @@ +import type { Config } from '../createConfig.js' +import type { GetConnectorsReturnType } from './getConnectors.js' + +export type WatchConnectorsParameters = { + onChange( + connections: GetConnectorsReturnType, + prevConnectors: GetConnectorsReturnType, + ): void +} + +export type WatchConnectorsReturnType = () => void + +/** https://wagmi.sh/core/api/actions/watchConnectors */ +export function watchConnectors( + config: config, + parameters: WatchConnectorsParameters, +): WatchConnectorsReturnType { + const { onChange } = parameters + return config._internal.connectors.subscribe((connectors, prevConnectors) => { + onChange(Object.values(connectors), prevConnectors) + }) +} diff --git a/wagmi-project/packages/core/src/actions/watchContractEvent.test-d.ts b/wagmi-project/packages/core/src/actions/watchContractEvent.test-d.ts new file mode 100644 index 0000000000..e6624fff57 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchContractEvent.test-d.ts @@ -0,0 +1,142 @@ +import { abi, config } from '@wagmi/test' +import { http, webSocket } from 'viem' +import { mainnet, optimism } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { createConfig } from '../createConfig.js' +import { + type WatchContractEventParameters, + watchContractEvent, +} from './watchContractEvent.js' + +test('default', () => { + watchContractEvent(config, { + address: '0x', + abi: abi.erc20, + eventName: 'Transfer', + args: { + from: '0x', + to: '0x', + }, + onLogs(logs) { + expectTypeOf(logs[0]!.eventName).toEqualTypeOf<'Transfer'>() + expectTypeOf(logs[0]!.args).toEqualTypeOf<{ + from?: `0x${string}` | undefined + to?: `0x${string}` | undefined + value?: bigint | undefined + }>() + }, + }) +}) + +test('behavior: no eventName', () => { + type Result = WatchContractEventParameters< + typeof abi.erc20, + undefined, + true, + typeof config + > + expectTypeOf().toEqualTypeOf< + | { + from?: `0x${string}` | `0x${string}`[] | null | undefined + to?: `0x${string}` | `0x${string}`[] | null | undefined + } + | { + owner?: `0x${string}` | `0x${string}`[] | null | undefined + spender?: `0x${string}` | `0x${string}`[] | null | undefined + } + | undefined + >() + + watchContractEvent(config, { + address: '0x', + abi: abi.erc20, + args: { + // TODO: Figure out why this is not working + // @ts-ignore + from: '0x', + to: '0x', + }, + onLogs(logs) { + expectTypeOf(logs[0]!.eventName).toEqualTypeOf<'Transfer' | 'Approval'>() + expectTypeOf(logs[0]!.args).toEqualTypeOf< + | Record + | readonly unknown[] + | { + from?: `0x${string}` | undefined + to?: `0x${string}` | undefined + value?: bigint | undefined + } + | { + owner?: `0x${string}` | undefined + spender?: `0x${string}` | undefined + value?: bigint | undefined + } + >() + }, + }) +}) + +test('differing transports', () => { + const config = createConfig({ + chains: [mainnet, optimism], + transports: { + [mainnet.id]: http(), + [optimism.id]: webSocket(), + }, + }) + + type Result = WatchContractEventParameters< + typeof abi.erc20, + 'Transfer' | 'Approval', + true, + typeof config, + typeof mainnet.id | typeof optimism.id + > + expectTypeOf().toEqualTypeOf() + watchContractEvent(config, { + poll: false, + address: '0x', + abi: abi.erc20, + onLogs() {}, + }) + + type Result2 = WatchContractEventParameters< + typeof abi.erc20, + 'Transfer' | 'Approval', + true, + typeof config, + typeof mainnet.id + > + expectTypeOf().toEqualTypeOf() + watchContractEvent(config, { + chainId: mainnet.id, + poll: true, + address: '0x', + abi: abi.erc20, + onLogs() {}, + }) + + type Result3 = WatchContractEventParameters< + typeof abi.erc20, + 'Transfer' | 'Approval', + true, + typeof config, + typeof optimism.id + > + expectTypeOf().toEqualTypeOf() + watchContractEvent(config, { + chainId: optimism.id, + poll: true, + address: '0x', + abi: abi.erc20, + onLogs() {}, + }) + watchContractEvent(config, { + chainId: optimism.id, + poll: false, + address: '0x', + abi: abi.erc20, + onLogs() {}, + }) +}) diff --git a/wagmi-project/packages/core/src/actions/watchContractEvent.test.ts b/wagmi-project/packages/core/src/actions/watchContractEvent.test.ts new file mode 100644 index 0000000000..759a21dd19 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchContractEvent.test.ts @@ -0,0 +1,96 @@ +import { + abi, + accounts, + address, + config, + testClient, + transactionHashRegex, + wait, +} from '@wagmi/test' +import { http, createWalletClient, parseEther } from 'viem' +import type { WatchEventOnLogsParameter } from 'viem/actions' +import { beforeEach, expect, test } from 'vitest' + +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { getBalance } from './getBalance.js' +import { watchContractEvent } from './watchContractEvent.js' +import { writeContract } from './writeContract.js' + +const connector = config.connectors[0]! + +// TODO: Some test does not call disconnect after finishing. Remove once fixing it. +beforeEach(async () => { + if (config.state.current) { + const connection = config.state.connections.get(config.state.current)! + const connector = connection.connector + await disconnect(config, { connector }) + } +}) + +test('default', async () => { + const data = await connect(config, { connector }) + const connectedAddress = data.accounts[0] + + // impersonate usdc holder account and transfer usdc to connected account + await testClient.mainnet.impersonateAccount({ address: address.usdcHolder }) + await testClient.mainnet.setBalance({ + address: address.usdcHolder, + value: 10000000000000000000000n, + }) + await createWalletClient({ + account: address.usdcHolder, + chain: testClient.mainnet.chain, + transport: http(), + }).writeContract({ + address: address.usdc, + abi: abi.erc20, + functionName: 'transfer', + args: [connectedAddress, parseEther('10', 'gwei')], + }) + await testClient.mainnet.mine({ blocks: 1 }) + await testClient.mainnet.stopImpersonatingAccount({ + address: address.usdcHolder, + }) + + const balance = await getBalance(config, { + address: connectedAddress, + token: address.usdc, + }) + expect(balance.value).toBeGreaterThan(0n) + + // start watching transfer events + let logs: WatchEventOnLogsParameter = [] + const unwatch = watchContractEvent(config, { + address: address.usdc, + abi: abi.erc20, + eventName: 'Transfer', + onLogs(next) { + logs = logs.concat(next) + }, + }) + + await writeContract(config, { + address: address.usdc, + abi: abi.erc20, + functionName: 'transfer', + args: [accounts[1], parseEther('1', 'gwei')], + }) + + await writeContract(config, { + address: address.usdc, + abi: abi.erc20, + functionName: 'transfer', + args: [accounts[3], parseEther('1', 'gwei')], + }) + + await testClient.mainnet.mine({ blocks: 1 }) + await testClient.mainnet.mine({ blocks: 1 }) + await wait(1000) // wait for events to be emitted + + unwatch() + expect(logs.length).toBe(2) + expect(logs[0]?.transactionHash).toMatch(transactionHashRegex) + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/core/src/actions/watchContractEvent.ts b/wagmi-project/packages/core/src/actions/watchContractEvent.ts new file mode 100644 index 0000000000..ddc15741da --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchContractEvent.ts @@ -0,0 +1,102 @@ +import type { + Abi, + Chain, + ContractEventName, + Transport, + WebSocketTransport, +} from 'viem' +import { + type WatchContractEventParameters as viem_WatchContractEventParameters, + type WatchContractEventReturnType as viem_WatchContractEventReturnType, + watchContractEvent as viem_watchContractEvent, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { SelectChains } from '../types/chain.js' +import type { + ChainIdParameter, + SyncConnectedChainParameter, +} from '../types/properties.js' +import type { UnionCompute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type WatchContractEventParameters< + abi extends Abi | readonly unknown[] = Abi, + eventName extends ContractEventName | undefined = ContractEventName, + strict extends boolean | undefined = undefined, + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + /// + chains extends readonly Chain[] = SelectChains, +> = { + [key in keyof chains]: UnionCompute< + viem_WatchContractEventParameters< + abi, + eventName, + strict, + config['_internal']['transports'][chains[key]['id']] extends infer transport extends + Transport + ? Transport extends transport + ? WebSocketTransport + : transport + : WebSocketTransport + > & + ChainIdParameter & + SyncConnectedChainParameter + > +}[number] + +export type WatchContractEventReturnType = viem_WatchContractEventReturnType + +// TODO: wrap in viem's `observe` to avoid duplicate invocations. +/** https://wagmi.sh/core/api/actions/watchContractEvent */ +export function watchContractEvent< + config extends Config, + chainId extends config['chains'][number]['id'], + const abi extends Abi | readonly unknown[], + eventName extends ContractEventName | undefined, + strict extends boolean | undefined = undefined, +>( + config: config, + parameters: WatchContractEventParameters< + abi, + eventName, + strict, + config, + chainId + >, +) { + const { syncConnectedChain = config._internal.syncConnectedChain, ...rest } = + parameters + + let unwatch: WatchContractEventReturnType | undefined + const listener = (chainId: number | undefined) => { + if (unwatch) unwatch() + + const client = config.getClient({ chainId }) + const action = getAction( + client, + viem_watchContractEvent, + 'watchContractEvent', + ) + unwatch = action(rest as unknown as viem_WatchContractEventParameters) + return unwatch + } + + // set up listener for transaction changes + const unlisten = listener(parameters.chainId) + + // set up subscriber for connected chain changes + let unsubscribe: (() => void) | undefined + if (syncConnectedChain && !parameters.chainId) + unsubscribe = config.subscribe( + ({ chainId }) => chainId, + async (chainId) => listener(chainId), + ) + + return () => { + unlisten?.() + unsubscribe?.() + } +} diff --git a/wagmi-project/packages/core/src/actions/watchPendingTransactions.test-d.ts b/wagmi-project/packages/core/src/actions/watchPendingTransactions.test-d.ts new file mode 100644 index 0000000000..0af40a24c5 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchPendingTransactions.test-d.ts @@ -0,0 +1,56 @@ +import { http, webSocket } from 'viem' +import { mainnet, optimism } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { createConfig } from '../createConfig.js' +import { + type WatchPendingTransactionsParameters, + watchPendingTransactions, +} from './watchPendingTransactions.js' + +test('differing transports', () => { + const config = createConfig({ + chains: [mainnet, optimism], + transports: { + [mainnet.id]: http(), + [optimism.id]: webSocket(), + }, + }) + + type Result = WatchPendingTransactionsParameters< + typeof config, + typeof mainnet.id | typeof optimism.id + > + expectTypeOf().toEqualTypeOf() + watchPendingTransactions(config, { + poll: false, + onTransactions() {}, + }) + + type Result2 = WatchPendingTransactionsParameters< + typeof config, + typeof mainnet.id + > + expectTypeOf().toEqualTypeOf() + watchPendingTransactions(config, { + chainId: mainnet.id, + poll: true, + onTransactions() {}, + }) + + type Result3 = WatchPendingTransactionsParameters< + typeof config, + typeof optimism.id + > + expectTypeOf().toEqualTypeOf() + watchPendingTransactions(config, { + chainId: optimism.id, + poll: true, + onTransactions() {}, + }) + watchPendingTransactions(config, { + chainId: optimism.id, + poll: false, + onTransactions() {}, + }) +}) diff --git a/wagmi-project/packages/core/src/actions/watchPendingTransactions.test.ts b/wagmi-project/packages/core/src/actions/watchPendingTransactions.test.ts new file mode 100644 index 0000000000..510b9acce3 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchPendingTransactions.test.ts @@ -0,0 +1,49 @@ +import { + accounts, + config, + testClient, + transactionHashRegex, + wait, +} from '@wagmi/test' +import { parseEther } from 'viem' +import type { OnTransactionsParameter } from 'viem/actions' +import { expect, test } from 'vitest' + +import { connect } from './connect.js' +import { disconnect } from './disconnect.js' +import { sendTransaction } from './sendTransaction.js' +import { watchPendingTransactions } from './watchPendingTransactions.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + let transactions: OnTransactionsParameter = [] + const unwatch = watchPendingTransactions(config, { + onTransactions(next) { + transactions = [...transactions, ...next] + }, + }) + await wait(500) + + await sendTransaction(config, { + to: accounts[1], + value: parseEther('1'), + }) + await wait(100) + + await sendTransaction(config, { + to: accounts[3], + value: parseEther('1'), + }) + await wait(100) + + await testClient.mainnet.mine({ blocks: 1 }) + + unwatch() + expect(transactions.length).toBe(2) + expect(transactions[0]).toMatch(transactionHashRegex) + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/core/src/actions/watchPendingTransactions.ts b/wagmi-project/packages/core/src/actions/watchPendingTransactions.ts new file mode 100644 index 0000000000..29f0354501 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchPendingTransactions.ts @@ -0,0 +1,82 @@ +import type { Chain, Transport, WebSocketTransport } from 'viem' +import { + type WatchPendingTransactionsParameters as viem_WatchPendingTransactionsParameters, + type WatchPendingTransactionsReturnType as viem_WatchPendingTransactionsReturnType, + watchPendingTransactions as viem_watchPendingTransactions, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { SelectChains } from '../types/chain.js' +import type { + ChainIdParameter, + SyncConnectedChainParameter, +} from '../types/properties.js' +import type { UnionCompute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' + +export type WatchPendingTransactionsParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + /// + chains extends readonly Chain[] = SelectChains, +> = { + [key in keyof chains]: UnionCompute< + viem_WatchPendingTransactionsParameters< + config['_internal']['transports'][chains[key]['id']] extends infer transport extends + Transport + ? Transport extends transport + ? WebSocketTransport + : transport + : WebSocketTransport + > & + ChainIdParameter & + SyncConnectedChainParameter + > +}[number] + +export type WatchPendingTransactionsReturnType = + viem_WatchPendingTransactionsReturnType + +// TODO: wrap in viem's `observe` to avoid duplicate invocations. +/** https://wagmi.sh/core/api/actions/watchPendingTransactions */ +export function watchPendingTransactions< + config extends Config, + chainId extends config['chains'][number]['id'], +>( + config: config, + parameters: WatchPendingTransactionsParameters, +) { + const { syncConnectedChain = config._internal.syncConnectedChain, ...rest } = + parameters + + let unwatch: WatchPendingTransactionsReturnType | undefined + const listener = (chainId: number | undefined) => { + if (unwatch) unwatch() + + const client = config.getClient({ chainId }) + const action = getAction( + client, + viem_watchPendingTransactions, + 'watchPendingTransactions', + ) + unwatch = action(rest as viem_WatchPendingTransactionsParameters) + return unwatch + } + + // set up listener for transaction changes + const unlisten = listener(parameters.chainId) + + // set up subscriber for connected chain changes + let unsubscribe: (() => void) | undefined + if (syncConnectedChain && !parameters.chainId) + unsubscribe = config.subscribe( + ({ chainId }) => chainId, + async (chainId) => listener(chainId), + ) + + return () => { + unlisten?.() + unsubscribe?.() + } +} diff --git a/wagmi-project/packages/core/src/actions/watchPublicClient.test-d.ts b/wagmi-project/packages/core/src/actions/watchPublicClient.test-d.ts new file mode 100644 index 0000000000..a7353636cb --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchPublicClient.test-d.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { watchPublicClient } from './watchPublicClient.js' + +test('default', () => { + watchPublicClient(config, { + onChange(client) { + expectTypeOf(client.chain).toEqualTypeOf< + (typeof config)['chains'][number] + >() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() + }, + }) +}) diff --git a/wagmi-project/packages/core/src/actions/watchPublicClient.test.ts b/wagmi-project/packages/core/src/actions/watchPublicClient.test.ts new file mode 100644 index 0000000000..3d9594002c --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchPublicClient.test.ts @@ -0,0 +1,23 @@ +import { config } from '@wagmi/test' +import type { Client } from 'viem' +import { expect, test } from 'vitest' + +import { switchChain } from './switchChain.js' +import { watchPublicClient } from './watchPublicClient.js' + +test('default', async () => { + const clients: Client[] = [] + const unwatch = watchPublicClient(config, { + onChange(client) { + clients.push(client) + }, + }) + + switchChain(config, { chainId: 456 }) + switchChain(config, { chainId: 10 }) + switchChain(config, { chainId: 1 }) + + expect(clients.length).toBe(3) + + unwatch() +}) diff --git a/wagmi-project/packages/core/src/actions/watchPublicClient.ts b/wagmi-project/packages/core/src/actions/watchPublicClient.ts new file mode 100644 index 0000000000..b7d854c2ad --- /dev/null +++ b/wagmi-project/packages/core/src/actions/watchPublicClient.ts @@ -0,0 +1,38 @@ +import type { Config } from '../createConfig.js' +import { + type GetPublicClientReturnType, + getPublicClient, +} from './getPublicClient.js' + +export type WatchPublicClientParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = { + onChange( + publicClient: GetPublicClientReturnType, + prevPublicClient: GetPublicClientReturnType, + ): void +} + +export type WatchPublicClientReturnType = () => void + +/** https://wagmi.sh/core/api/actions/watchPublicClient */ +export function watchPublicClient< + config extends Config, + chainId extends config['chains'][number]['id'], +>( + config: config, + parameters: WatchPublicClientParameters, +): WatchPublicClientReturnType { + const { onChange } = parameters + return config.subscribe( + () => getPublicClient(config) as GetPublicClientReturnType, + onChange, + { + equalityFn(a, b) { + return a?.uid === b?.uid + }, + }, + ) +} diff --git a/wagmi-project/packages/core/src/actions/writeContract.test-d.ts b/wagmi-project/packages/core/src/actions/writeContract.test-d.ts new file mode 100644 index 0000000000..68009a3773 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/writeContract.test-d.ts @@ -0,0 +1,152 @@ +import { abi, config } from '@wagmi/test' +import { http, type Address, parseAbi } from 'viem' +import { celo, mainnet } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { createConfig } from '../createConfig.js' +import { simulateContract } from './simulateContract.js' +import { type WriteContractParameters, writeContract } from './writeContract.js' + +test('default', async () => { + await writeContract(config, { + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + chainId: 1, + }) +}) + +test('simulateContract', async () => { + const { request } = await simulateContract(config, { + account: '0x', + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + chainId: 1, + }) + await writeContract(config, request) + await writeContract(config, { + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + }) +}) + +test('chain formatters', () => { + const config = createConfig({ + chains: [mainnet, celo], + transports: { [celo.id]: http(), [mainnet.id]: http() }, + }) + + type Result = WriteContractParameters< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof config + > + expectTypeOf().toMatchTypeOf<{ + chainId?: typeof celo.id | typeof mainnet.id | undefined + feeCurrency?: `0x${string}` | undefined + }>() + writeContract(config, { + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + feeCurrency: '0x', + }) + + type Result2 = WriteContractParameters< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof config, + typeof celo.id + > + expectTypeOf().toMatchTypeOf<{ + functionName: 'approve' | 'transfer' | 'transferFrom' + args: readonly [Address, Address, bigint] + feeCurrency?: `0x${string}` | undefined + }>() + writeContract(config, { + chainId: celo.id, + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + feeCurrency: '0x', + }) + + type Result3 = WriteContractParameters< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof config, + typeof mainnet.id + > + expectTypeOf().toMatchTypeOf<{ + functionName: 'approve' | 'transfer' | 'transferFrom' + args: readonly [Address, Address, bigint] + }>() + expectTypeOf().not.toMatchTypeOf<{ + feeCurrency?: `0x${string}` | undefined + }>() + writeContract(config, { + chainId: mainnet.id, + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + // @ts-expect-error + feeCurrency: '0x', + }) +}) + +test('overloads', async () => { + const abi = parseAbi([ + 'function foo() returns (int8)', + 'function foo(address) returns (string)', + 'function foo(address, address) returns ((address foo, address bar))', + 'function bar(uint256) returns (int8)', + ]) + + type Result = WriteContractParameters + expectTypeOf().toEqualTypeOf<'foo' | 'bar'>() + expectTypeOf().toEqualTypeOf< + | readonly [] + | readonly [`0x${string}`] + | readonly [`0x${string}`, `0x${string}`] + | undefined + >() + writeContract(config, { + address: '0x', + abi, + functionName: 'foo', + }) + writeContract(config, { + address: '0x', + abi, + functionName: 'foo', + args: ['0x'], + }) + writeContract(config, { + address: '0x', + abi, + functionName: 'foo', + args: ['0x', '0x'], + }) + writeContract(config, { + address: '0x', + abi, + functionName: 'foo', + // @ts-expect-error + args: ['0x', 123n], + }) + + type Result2 = WriteContractParameters + expectTypeOf().toEqualTypeOf<'foo' | 'bar'>() + expectTypeOf().toEqualTypeOf() +}) diff --git a/wagmi-project/packages/core/src/actions/writeContract.ts b/wagmi-project/packages/core/src/actions/writeContract.ts new file mode 100644 index 0000000000..5fb6d87104 --- /dev/null +++ b/wagmi-project/packages/core/src/actions/writeContract.ts @@ -0,0 +1,114 @@ +import type { + Abi, + Account, + Chain, + Client, + ContractFunctionArgs, + ContractFunctionName, +} from 'viem' +import { + type WriteContractErrorType as viem_WriteContractErrorType, + type WriteContractParameters as viem_WriteContractParameters, + type WriteContractReturnType as viem_WriteContractReturnType, + writeContract as viem_writeContract, +} from 'viem/actions' + +import type { Config } from '../createConfig.js' +import type { BaseErrorType, ErrorType } from '../errors/base.js' +import type { SelectChains } from '../types/chain.js' +import type { + ChainIdParameter, + ConnectorParameter, +} from '../types/properties.js' +import type { Compute, UnionCompute } from '../types/utils.js' +import { getAction } from '../utils/getAction.js' +import { + type GetConnectorClientErrorType, + getConnectorClient, +} from './getConnectorClient.js' + +export type WriteContractParameters< + abi extends Abi | readonly unknown[] = Abi, + functionName extends ContractFunctionName< + abi, + 'nonpayable' | 'payable' + > = ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + > = ContractFunctionArgs, + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + /// + allFunctionNames = ContractFunctionName, + chains extends readonly Chain[] = SelectChains, +> = UnionCompute< + { + // TODO: Should use `UnionStrictOmit<..., 'chain'>` on `viem_WriteContractParameters` result instead + // temp workaround that doesn't affect runtime behavior for for https://github.com/wevm/wagmi/issues/3981 + [key in keyof chains]: viem_WriteContractParameters< + abi, + functionName, + args, + chains[key], + Account, + chains[key], + allFunctionNames + > + }[number] & + Compute> & + ConnectorParameter & { + /** @deprecated */ + __mode?: 'prepared' + } +> + +export type WriteContractReturnType = viem_WriteContractReturnType + +export type WriteContractErrorType = + // getConnectorClient() + | GetConnectorClientErrorType + // base + | BaseErrorType + | ErrorType + // viem + | viem_WriteContractErrorType + +/** https://wagmi.sh/core/api/actions/writeContract */ +export async function writeContract< + config extends Config, + const abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + >, + chainId extends config['chains'][number]['id'], +>( + config: config, + parameters: WriteContractParameters, +): Promise { + const { account, chainId, connector, ...request } = parameters + + let client: Client + if (typeof account === 'object' && account?.type === 'local') + client = config.getClient({ chainId }) + else + client = await getConnectorClient(config, { + account: account ?? undefined, + chainId, + connector, + }) + + const action = getAction(client, viem_writeContract, 'writeContract') + const hash = await action({ + ...(request as any), + ...(account ? { account } : {}), + chain: chainId ? { id: chainId } : null, + }) + + return hash +} diff --git a/wagmi-project/packages/core/src/connectors/createConnector.test.ts b/wagmi-project/packages/core/src/connectors/createConnector.test.ts new file mode 100644 index 0000000000..d1ff9f20af --- /dev/null +++ b/wagmi-project/packages/core/src/connectors/createConnector.test.ts @@ -0,0 +1,31 @@ +import type { Address } from 'viem' +import { test } from 'vitest' +import { createConnector } from './createConnector.js' + +test('default', () => { + createConnector(() => { + return { + id: 'test', + name: 'Test Connector', + type: 'test', + async setup() {}, + async connect() { + return { accounts: [] as Address[], chainId: 123 } + }, + async disconnect() {}, + async getAccounts() { + return [] + }, + async getChainId() { + return 123 + }, + async isAuthorized() { + return true + }, + onAccountsChanged() {}, + onChainChanged() {}, + async onDisconnect(_error) {}, + async getProvider() {}, + } + }) +}) diff --git a/wagmi-project/packages/core/src/connectors/createConnector.ts b/wagmi-project/packages/core/src/connectors/createConnector.ts new file mode 100644 index 0000000000..54b4d9955c --- /dev/null +++ b/wagmi-project/packages/core/src/connectors/createConnector.ts @@ -0,0 +1,93 @@ +import type { + AddEthereumChainParameter, + Address, + Chain, + Client, + ProviderConnectInfo, + ProviderMessage, +} from 'viem' + +import type { Transport } from '../createConfig.js' +import type { Emitter } from '../createEmitter.js' +import type { Storage } from '../createStorage.js' +import type { Compute, ExactPartial, StrictOmit } from '../types/utils.js' + +export type ConnectorEventMap = { + change: { + accounts?: readonly Address[] | undefined + chainId?: number | undefined + } + connect: { accounts: readonly Address[]; chainId: number } + disconnect: never + error: { error: Error } + message: { type: string; data?: unknown | undefined } +} + +export type CreateConnectorFn< + provider = unknown, + properties extends Record = Record, + storageItem extends Record = Record, +> = (config: { + chains: readonly [Chain, ...Chain[]] + emitter: Emitter + storage?: Compute> | null | undefined + transports?: Record | undefined +}) => Compute< + { + readonly icon?: string | undefined + readonly id: string + readonly name: string + readonly rdns?: string | readonly string[] | undefined + /** @deprecated */ + readonly supportsSimulation?: boolean | undefined + readonly type: string + + setup?(): Promise + connect( + parameters?: + | { chainId?: number | undefined; isReconnecting?: boolean | undefined } + | undefined, + ): Promise<{ + accounts: readonly Address[] + chainId: number + }> + disconnect(): Promise + getAccounts(): Promise + getChainId(): Promise + getProvider( + parameters?: { chainId?: number | undefined } | undefined, + ): Promise + getClient?( + parameters?: { chainId?: number | undefined } | undefined, + ): Promise + isAuthorized(): Promise + switchChain?( + parameters: Compute<{ + addEthereumChainParameter?: + | ExactPartial> + | undefined + chainId: number + }>, + ): Promise + + onAccountsChanged(accounts: string[]): void + onChainChanged(chainId: string): void + onConnect?(connectInfo: ProviderConnectInfo): void + onDisconnect(error?: Error | undefined): void + onMessage?(message: ProviderMessage): void + } & properties +> + +export function createConnector< + provider, + properties extends Record = Record, + storageItem extends Record = Record, + /// + createConnectorFn extends CreateConnectorFn< + provider, + properties, + storageItem + > = CreateConnectorFn, +>(createConnectorFn: createConnectorFn) { + return createConnectorFn +} diff --git a/wagmi-project/packages/core/src/connectors/injected.test.ts b/wagmi-project/packages/core/src/connectors/injected.test.ts new file mode 100644 index 0000000000..9188a53bae --- /dev/null +++ b/wagmi-project/packages/core/src/connectors/injected.test.ts @@ -0,0 +1,25 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { injected } from './injected.js' + +test('setup', () => { + const connectorFn = injected() + const connector = config._internal.connectors.setup(connectorFn) + expect(connector.name).toEqual('Injected') +}) + +test.each([ + { wallet: undefined, expected: 'Injected' }, + { wallet: 'coinbaseWallet', expected: 'Coinbase Wallet' }, + { wallet: 'metaMask', expected: 'MetaMask' }, + { wallet: 'phantom', expected: 'Phantom' }, + { wallet: 'rainbow', expected: 'Rainbow' }, +] as const satisfies readonly { + wallet: string | undefined + expected: string +}[])('injected({ wallet: $wallet })', ({ wallet, expected }) => { + const connectorFn = injected({ target: wallet }) + const connector = config._internal.connectors.setup(connectorFn) + expect(connector.name).toEqual(expected) +}) diff --git a/wagmi-project/packages/core/src/connectors/injected.ts b/wagmi-project/packages/core/src/connectors/injected.ts new file mode 100644 index 0000000000..d686d0aa29 --- /dev/null +++ b/wagmi-project/packages/core/src/connectors/injected.ts @@ -0,0 +1,697 @@ +import { + type AddEthereumChainParameter, + type Address, + type EIP1193Provider, + type ProviderConnectInfo, + type ProviderRpcError, + ResourceUnavailableRpcError, + type RpcError, + SwitchChainError, + UserRejectedRequestError, + getAddress, + numberToHex, + withRetry, + withTimeout, +} from 'viem' + +import type { Connector } from '../createConfig.js' +import { ChainNotConfiguredError } from '../errors/config.js' +import { ProviderNotFoundError } from '../errors/connector.js' +import type { Compute } from '../types/utils.js' +import { createConnector } from './createConnector.js' + +export type InjectedParameters = { + /** + * Some injected providers do not support programmatic disconnect. + * This flag simulates the disconnect behavior by keeping track of connection status in storage. + * @default true + */ + shimDisconnect?: boolean | undefined + /** + * [EIP-1193](https://eips.ethereum.org/EIPS/eip-1193) Ethereum Provider to target + */ + target?: TargetId | Target | (() => Target | undefined) | undefined + unstable_shimAsyncInject?: boolean | number | undefined +} + +injected.type = 'injected' as const +export function injected(parameters: InjectedParameters = {}) { + const { shimDisconnect = true, unstable_shimAsyncInject } = parameters + + function getTarget(): Compute { + const target = parameters.target + if (typeof target === 'function') { + const result = target() + if (result) return result + } + + if (typeof target === 'object') return target + + if (typeof target === 'string') + return { + ...(targetMap[target as keyof typeof targetMap] ?? { + id: target, + name: `${target[0]!.toUpperCase()}${target.slice(1)}`, + provider: `is${target[0]!.toUpperCase()}${target.slice(1)}`, + }), + } + + return { + id: 'injected', + name: 'Injected', + provider(window) { + return window?.ethereum + }, + } + } + + type Provider = WalletProvider | undefined + type Properties = { + onConnect(connectInfo: ProviderConnectInfo): void + } + type StorageItem = { + [_ in 'injected.connected' | `${string}.disconnected`]: true + } + + let accountsChanged: Connector['onAccountsChanged'] | undefined + let chainChanged: Connector['onChainChanged'] | undefined + let connect: Connector['onConnect'] | undefined + let disconnect: Connector['onDisconnect'] | undefined + + return createConnector((config) => ({ + get icon() { + return getTarget().icon + }, + get id() { + return getTarget().id + }, + get name() { + return getTarget().name + }, + /** @deprecated */ + get supportsSimulation() { + return true + }, + type: injected.type, + async setup() { + const provider = await this.getProvider() + // Only start listening for events if `target` is set, otherwise `injected()` will also receive events + if (provider?.on && parameters.target) { + if (!connect) { + connect = this.onConnect.bind(this) + provider.on('connect', connect) + } + + // We shouldn't need to listen for `'accountsChanged'` here since the `'connect'` event should suffice (and wallet shouldn't be connected yet). + // Some wallets, like MetaMask, do not implement the `'connect'` event and overload `'accountsChanged'` instead. + if (!accountsChanged) { + accountsChanged = this.onAccountsChanged.bind(this) + provider.on('accountsChanged', accountsChanged) + } + } + }, + async connect({ chainId, isReconnecting } = {}) { + const provider = await this.getProvider() + if (!provider) throw new ProviderNotFoundError() + + let accounts: readonly Address[] = [] + if (isReconnecting) accounts = await this.getAccounts().catch(() => []) + else if (shimDisconnect) { + // Attempt to show another prompt for selecting account if `shimDisconnect` flag is enabled + try { + const permissions = await provider.request({ + method: 'wallet_requestPermissions', + params: [{ eth_accounts: {} }], + }) + accounts = (permissions[0]?.caveats?.[0]?.value as string[])?.map( + (x) => getAddress(x), + ) + // `'wallet_requestPermissions'` can return a different order of accounts than `'eth_accounts'` + // switch to `'eth_accounts'` ordering if more than one account is connected + // https://github.com/wevm/wagmi/issues/4140 + if (accounts.length > 0) { + const sortedAccounts = await this.getAccounts() + accounts = sortedAccounts + } + } catch (err) { + const error = err as RpcError + // Not all injected providers support `wallet_requestPermissions` (e.g. MetaMask iOS). + // Only bubble up error if user rejects request + if (error.code === UserRejectedRequestError.code) + throw new UserRejectedRequestError(error) + // Or prompt is already open + if (error.code === ResourceUnavailableRpcError.code) throw error + } + } + + try { + if (!accounts?.length && !isReconnecting) { + const requestedAccounts = await provider.request({ + method: 'eth_requestAccounts', + }) + accounts = requestedAccounts.map((x) => getAddress(x)) + } + + // Manage EIP-1193 event listeners + // https://eips.ethereum.org/EIPS/eip-1193#events + if (connect) { + provider.removeListener('connect', connect) + connect = undefined + } + if (!accountsChanged) { + accountsChanged = this.onAccountsChanged.bind(this) + provider.on('accountsChanged', accountsChanged) + } + if (!chainChanged) { + chainChanged = this.onChainChanged.bind(this) + provider.on('chainChanged', chainChanged) + } + if (!disconnect) { + disconnect = this.onDisconnect.bind(this) + provider.on('disconnect', disconnect) + } + + // Switch to chain if provided + let currentChainId = await this.getChainId() + if (chainId && currentChainId !== chainId) { + const chain = await this.switchChain!({ chainId }).catch((error) => { + if (error.code === UserRejectedRequestError.code) throw error + return { id: currentChainId } + }) + currentChainId = chain?.id ?? currentChainId + } + + // Remove disconnected shim if it exists + if (shimDisconnect) + await config.storage?.removeItem(`${this.id}.disconnected`) + + // Add connected shim if no target exists + if (!parameters.target) + await config.storage?.setItem('injected.connected', true) + + return { accounts, chainId: currentChainId } + } catch (err) { + const error = err as RpcError + if (error.code === UserRejectedRequestError.code) + throw new UserRejectedRequestError(error) + if (error.code === ResourceUnavailableRpcError.code) + throw new ResourceUnavailableRpcError(error) + throw error + } + }, + async disconnect() { + const provider = await this.getProvider() + if (!provider) throw new ProviderNotFoundError() + + // Manage EIP-1193 event listeners + if (chainChanged) { + provider.removeListener('chainChanged', chainChanged) + chainChanged = undefined + } + if (disconnect) { + provider.removeListener('disconnect', disconnect) + disconnect = undefined + } + if (!connect) { + connect = this.onConnect.bind(this) + provider.on('connect', connect) + } + + // Experimental support for MetaMask disconnect + // https://github.com/MetaMask/metamask-improvement-proposals/blob/main/MIPs/mip-2.md + try { + // Adding timeout as not all wallets support this method and can hang + // https://github.com/wevm/wagmi/issues/4064 + await withTimeout( + () => + // TODO: Remove explicit type for viem@3 + provider.request<{ + Method: 'wallet_revokePermissions' + Parameters: [permissions: { eth_accounts: Record }] + ReturnType: null + }>({ + // `'wallet_revokePermissions'` added in `viem@2.10.3` + method: 'wallet_revokePermissions', + params: [{ eth_accounts: {} }], + }), + { timeout: 100 }, + ) + } catch {} + + // Add shim signalling connector is disconnected + if (shimDisconnect) { + await config.storage?.setItem(`${this.id}.disconnected`, true) + } + + if (!parameters.target) + await config.storage?.removeItem('injected.connected') + }, + async getAccounts() { + const provider = await this.getProvider() + if (!provider) throw new ProviderNotFoundError() + const accounts = await provider.request({ method: 'eth_accounts' }) + return accounts.map((x) => getAddress(x)) + }, + async getChainId() { + const provider = await this.getProvider() + if (!provider) throw new ProviderNotFoundError() + const hexChainId = await provider.request({ method: 'eth_chainId' }) + return Number(hexChainId) + }, + async getProvider() { + if (typeof window === 'undefined') return undefined + + let provider: Provider + const target = getTarget() + if (typeof target.provider === 'function') + provider = target.provider(window as Window | undefined) + else if (typeof target.provider === 'string') + provider = findProvider(window, target.provider) + else provider = target.provider + + // Some wallets do not conform to EIP-1193 (e.g. Trust Wallet) + // https://github.com/wevm/wagmi/issues/3526#issuecomment-1912683002 + if (provider && !provider.removeListener) { + // Try using `off` handler if it exists, otherwise noop + if ('off' in provider && typeof provider.off === 'function') + provider.removeListener = + provider.off as typeof provider.removeListener + else provider.removeListener = () => {} + } + + return provider + }, + async isAuthorized() { + try { + const isDisconnected = + shimDisconnect && + // If shim exists in storage, connector is disconnected + (await config.storage?.getItem(`${this.id}.disconnected`)) + if (isDisconnected) return false + + // Don't allow injected connector to connect if no target is set and it hasn't already connected + // (e.g. flag in storage is not set). This prevents a targetless injected connector from connecting + // automatically whenever there is a targeted connector configured. + if (!parameters.target) { + const connected = await config.storage?.getItem('injected.connected') + if (!connected) return false + } + + const provider = await this.getProvider() + if (!provider) { + if ( + unstable_shimAsyncInject !== undefined && + unstable_shimAsyncInject !== false + ) { + // If no provider is found, check for async injection + // https://github.com/wevm/references/issues/167 + // https://github.com/MetaMask/detect-provider + const handleEthereum = async () => { + if (typeof window !== 'undefined') + window.removeEventListener( + 'ethereum#initialized', + handleEthereum, + ) + const provider = await this.getProvider() + return !!provider + } + const timeout = + typeof unstable_shimAsyncInject === 'number' + ? unstable_shimAsyncInject + : 1_000 + const res = await Promise.race([ + ...(typeof window !== 'undefined' + ? [ + new Promise((resolve) => + window.addEventListener( + 'ethereum#initialized', + () => resolve(handleEthereum()), + { once: true }, + ), + ), + ] + : []), + new Promise((resolve) => + setTimeout(() => resolve(handleEthereum()), timeout), + ), + ]) + if (res) return true + } + + throw new ProviderNotFoundError() + } + + // Use retry strategy as some injected wallets (e.g. MetaMask) fail to + // immediately resolve JSON-RPC requests on page load. + const accounts = await withRetry(() => this.getAccounts()) + return !!accounts.length + } catch { + return false + } + }, + async switchChain({ addEthereumChainParameter, chainId }) { + const provider = await this.getProvider() + if (!provider) throw new ProviderNotFoundError() + + const chain = config.chains.find((x) => x.id === chainId) + if (!chain) throw new SwitchChainError(new ChainNotConfiguredError()) + + const promise = new Promise((resolve) => { + const listener = ((data) => { + if ('chainId' in data && data.chainId === chainId) { + config.emitter.off('change', listener) + resolve() + } + }) satisfies Parameters[1] + config.emitter.on('change', listener) + }) + + try { + await Promise.all([ + provider + .request({ + method: 'wallet_switchEthereumChain', + params: [{ chainId: numberToHex(chainId) }], + }) + // During `'wallet_switchEthereumChain'`, MetaMask makes a `'net_version'` RPC call to the target chain. + // If this request fails, MetaMask does not emit the `'chainChanged'` event, but will still switch the chain. + // To counter this behavior, we request and emit the current chain ID to confirm the chain switch either via + // this callback or an externally emitted `'chainChanged'` event. + // https://github.com/MetaMask/metamask-extension/issues/24247 + .then(async () => { + const currentChainId = await this.getChainId() + if (currentChainId === chainId) + config.emitter.emit('change', { chainId }) + }), + promise, + ]) + return chain + } catch (err) { + const error = err as RpcError + + // Indicates chain is not added to provider + if ( + error.code === 4902 || + // Unwrapping for MetaMask Mobile + // https://github.com/MetaMask/metamask-mobile/issues/2944#issuecomment-976988719 + (error as ProviderRpcError<{ originalError?: { code: number } }>) + ?.data?.originalError?.code === 4902 + ) { + try { + const { default: blockExplorer, ...blockExplorers } = + chain.blockExplorers ?? {} + let blockExplorerUrls: string[] | undefined + if (addEthereumChainParameter?.blockExplorerUrls) + blockExplorerUrls = addEthereumChainParameter.blockExplorerUrls + else if (blockExplorer) + blockExplorerUrls = [ + blockExplorer.url, + ...Object.values(blockExplorers).map((x) => x.url), + ] + + let rpcUrls: readonly string[] + if (addEthereumChainParameter?.rpcUrls?.length) + rpcUrls = addEthereumChainParameter.rpcUrls + else rpcUrls = [chain.rpcUrls.default?.http[0] ?? ''] + + const addEthereumChain = { + blockExplorerUrls, + chainId: numberToHex(chainId), + chainName: addEthereumChainParameter?.chainName ?? chain.name, + iconUrls: addEthereumChainParameter?.iconUrls, + nativeCurrency: + addEthereumChainParameter?.nativeCurrency ?? + chain.nativeCurrency, + rpcUrls, + } satisfies AddEthereumChainParameter + + await Promise.all([ + provider + .request({ + method: 'wallet_addEthereumChain', + params: [addEthereumChain], + }) + .then(async () => { + const currentChainId = await this.getChainId() + if (currentChainId === chainId) + config.emitter.emit('change', { chainId }) + else + throw new UserRejectedRequestError( + new Error('User rejected switch after adding network.'), + ) + }), + promise, + ]) + + return chain + } catch (error) { + throw new UserRejectedRequestError(error as Error) + } + } + + if (error.code === UserRejectedRequestError.code) + throw new UserRejectedRequestError(error) + throw new SwitchChainError(error) + } + }, + async onAccountsChanged(accounts) { + // Disconnect if there are no accounts + if (accounts.length === 0) this.onDisconnect() + // Connect if emitter is listening for connect event (e.g. is disconnected and connects through wallet interface) + else if (config.emitter.listenerCount('connect')) { + const chainId = (await this.getChainId()).toString() + this.onConnect({ chainId }) + // Remove disconnected shim if it exists + if (shimDisconnect) + await config.storage?.removeItem(`${this.id}.disconnected`) + } + // Regular change event + else + config.emitter.emit('change', { + accounts: accounts.map((x) => getAddress(x)), + }) + }, + onChainChanged(chain) { + const chainId = Number(chain) + config.emitter.emit('change', { chainId }) + }, + async onConnect(connectInfo) { + const accounts = await this.getAccounts() + if (accounts.length === 0) return + + const chainId = Number(connectInfo.chainId) + config.emitter.emit('connect', { accounts, chainId }) + + // Manage EIP-1193 event listeners + const provider = await this.getProvider() + if (provider) { + if (connect) { + provider.removeListener('connect', connect) + connect = undefined + } + if (!accountsChanged) { + accountsChanged = this.onAccountsChanged.bind(this) + provider.on('accountsChanged', accountsChanged) + } + if (!chainChanged) { + chainChanged = this.onChainChanged.bind(this) + provider.on('chainChanged', chainChanged) + } + if (!disconnect) { + disconnect = this.onDisconnect.bind(this) + provider.on('disconnect', disconnect) + } + } + }, + async onDisconnect(error) { + const provider = await this.getProvider() + + // If MetaMask emits a `code: 1013` error, wait for reconnection before disconnecting + // https://github.com/MetaMask/providers/pull/120 + if (error && (error as RpcError<1013>).code === 1013) { + if (provider && !!(await this.getAccounts()).length) return + } + + // No need to remove `${this.id}.disconnected` from storage because `onDisconnect` is typically + // only called when the wallet is disconnected through the wallet's interface, meaning the wallet + // actually disconnected and we don't need to simulate it. + config.emitter.emit('disconnect') + + // Manage EIP-1193 event listeners + if (provider) { + if (chainChanged) { + provider.removeListener('chainChanged', chainChanged) + chainChanged = undefined + } + if (disconnect) { + provider.removeListener('disconnect', disconnect) + disconnect = undefined + } + if (!connect) { + connect = this.onConnect.bind(this) + provider.on('connect', connect) + } + } + }, + })) +} + +const targetMap = { + coinbaseWallet: { + id: 'coinbaseWallet', + name: 'Coinbase Wallet', + provider(window) { + if (window?.coinbaseWalletExtension) return window.coinbaseWalletExtension + return findProvider(window, 'isCoinbaseWallet') + }, + }, + metaMask: { + id: 'metaMask', + name: 'MetaMask', + provider(window) { + return findProvider(window, (provider) => { + if (!provider.isMetaMask) return false + // Brave tries to make itself look like MetaMask + // Could also try RPC `web3_clientVersion` if following is unreliable + if (provider.isBraveWallet && !provider._events && !provider._state) + return false + // Other wallets that try to look like MetaMask + const flags = [ + 'isApexWallet', + 'isAvalanche', + 'isBitKeep', + 'isBlockWallet', + 'isKuCoinWallet', + 'isMathWallet', + 'isOkxWallet', + 'isOKExWallet', + 'isOneInchIOSWallet', + 'isOneInchAndroidWallet', + 'isOpera', + 'isPhantom', + 'isPortal', + 'isRabby', + 'isTokenPocket', + 'isTokenary', + 'isUniswapWallet', + 'isZerion', + ] satisfies WalletProviderFlags[] + for (const flag of flags) if (provider[flag]) return false + return true + }) + }, + }, + phantom: { + id: 'phantom', + name: 'Phantom', + provider(window) { + if (window?.phantom?.ethereum) return window.phantom?.ethereum + return findProvider(window, 'isPhantom') + }, + }, +} as const satisfies TargetMap + +type TargetMap = { [_ in TargetId]?: Target | undefined } + +type Target = { + icon?: string | undefined + id: string + name: string + provider: + | WalletProviderFlags + | WalletProvider + | ((window?: Window | undefined) => WalletProvider | undefined) +} + +/** @deprecated */ +type TargetId = Compute extends `is${infer name}` + ? name extends `${infer char}${infer rest}` + ? `${Lowercase}${rest}` + : never + : never + +/** + * @deprecated As of 2024/10/16, we are no longer accepting new provider flags as EIP-6963 should be used instead. + */ +type WalletProviderFlags = + | 'isApexWallet' + | 'isAvalanche' + | 'isBackpack' + | 'isBifrost' + | 'isBitKeep' + | 'isBitski' + | 'isBlockWallet' + | 'isBraveWallet' + | 'isCoinbaseWallet' + | 'isDawn' + | 'isEnkrypt' + | 'isExodus' + | 'isFrame' + | 'isFrontier' + | 'isGamestop' + | 'isHyperPay' + | 'isImToken' + | 'isKuCoinWallet' + | 'isMathWallet' + | 'isMetaMask' + | 'isOkxWallet' + | 'isOKExWallet' + | 'isOneInchAndroidWallet' + | 'isOneInchIOSWallet' + | 'isOpera' + | 'isPhantom' + | 'isPortal' + | 'isRabby' + | 'isRainbow' + | 'isStatus' + | 'isTally' + | 'isTokenPocket' + | 'isTokenary' + | 'isTrust' + | 'isTrustWallet' + | 'isUniswapWallet' + | 'isXDEFI' + | 'isZerion' + +type WalletProvider = Compute< + EIP1193Provider & { + [key in WalletProviderFlags]?: true | undefined + } & { + providers?: WalletProvider[] | undefined + /** Only exists in MetaMask as of 2022/04/03 */ + _events?: { connect?: (() => void) | undefined } | undefined + /** Only exists in MetaMask as of 2022/04/03 */ + _state?: + | { + accounts?: string[] + initialized?: boolean + isConnected?: boolean + isPermanentlyDisconnected?: boolean + isUnlocked?: boolean + } + | undefined + } +> + +type Window = { + coinbaseWalletExtension?: WalletProvider | undefined + ethereum?: WalletProvider | undefined + phantom?: { ethereum: WalletProvider } | undefined +} + +function findProvider( + window: globalThis.Window | Window | undefined, + select?: WalletProviderFlags | ((provider: WalletProvider) => boolean), +) { + function isProvider(provider: WalletProvider) { + if (typeof select === 'function') return select(provider) + if (typeof select === 'string') return provider[select] + return true + } + + const ethereum = (window as Window).ethereum + if (ethereum?.providers) + return ethereum.providers.find((provider) => isProvider(provider)) + if (ethereum && isProvider(ethereum)) return ethereum + return undefined +} diff --git a/wagmi-project/packages/core/src/connectors/mock.test.ts b/wagmi-project/packages/core/src/connectors/mock.test.ts new file mode 100644 index 0000000000..d8a812a3d7 --- /dev/null +++ b/wagmi-project/packages/core/src/connectors/mock.test.ts @@ -0,0 +1,112 @@ +import { accounts, config } from '@wagmi/test' +import { expect, expectTypeOf, test } from 'vitest' + +import type { Connector } from '../createConfig.js' +import type { CreateConnectorFn } from './createConnector.js' +import { mock } from './mock.js' + +test('setup', () => { + const connectorFn = mock({ accounts }) + const connector = config._internal.connectors.setup(connectorFn) + expect(connector.name).toEqual('Mock Connector') + + expectTypeOf< + typeof connectorFn extends CreateConnectorFn ? true : false + >().toEqualTypeOf() + expectTypeOf< + typeof connector extends Connector ? true : false + >().toEqualTypeOf() + + type ConnectFnParameters = NonNullable< + Parameters<(typeof connector)['connect']>[0] + > + expectTypeOf().toMatchTypeOf() +}) + +test('behavior: features.connectError', () => { + const connectorFn = mock({ accounts, features: { connectError: true } }) + const connector = config._internal.connectors.setup(connectorFn) + expect(() => connector.connect()).rejects.toThrowErrorMatchingInlineSnapshot(` + [UserRejectedRequestError: User rejected the request. + + Details: Failed to connect. + Version: viem@2.29.2] + `) +}) + +test('behavior: connector.getProvider request errors', async () => { + const connectorFn = mock({ + accounts, + features: { + signMessageError: true, + signTypedDataError: true, + switchChainError: true, + watchAssetError: true, + }, + }) + const connector = config._internal.connectors.setup( + connectorFn, + ) as ReturnType + const provider = await connector.getProvider() + + expect( + provider.request({ + method: 'eth_signTypedData_v4', + params: [] as any, + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [UserRejectedRequestError: User rejected the request. + + Details: Failed to sign typed data. + Version: viem@2.29.2] + `) + + expect( + provider.request({ + method: 'wallet_switchEthereumChain', + params: [] as any, + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [UserRejectedRequestError: User rejected the request. + + Details: Failed to switch chain. + Version: viem@2.29.2] + `) + + expect( + provider.request({ + method: 'wallet_watchAsset', + params: [] as any, + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [UserRejectedRequestError: User rejected the request. + + Details: Failed to switch chain. + Version: viem@2.29.2] + `) + + expect( + provider.request({ + method: 'personal_sign', + params: [] as any, + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [UserRejectedRequestError: User rejected the request. + + Details: Failed to sign message. + Version: viem@2.29.2] + `) +}) + +test('behavior: reconnect', async () => { + const connectorFn = mock({ + accounts, + features: { + defaultConnected: true, + reconnect: true, + }, + }) + const connector = config._internal.connectors.setup(connectorFn) + + await expect(connector.isAuthorized()).resolves.toBeTruthy() +}) diff --git a/wagmi-project/packages/core/src/connectors/mock.ts b/wagmi-project/packages/core/src/connectors/mock.ts new file mode 100644 index 0000000000..9d4dc9d846 --- /dev/null +++ b/wagmi-project/packages/core/src/connectors/mock.ts @@ -0,0 +1,315 @@ +import { + type Address, + type EIP1193RequestFn, + type Hex, + RpcRequestError, + SwitchChainError, + type Transport, + UserRejectedRequestError, + type WalletCallReceipt, + type WalletGetCallsStatusReturnType, + type WalletRpcSchema, + custom, + fromHex, + getAddress, + keccak256, + numberToHex, + stringToHex, +} from 'viem' +import { rpc } from 'viem/utils' + +import { + ChainNotConfiguredError, + ConnectorNotConnectedError, +} from '../errors/config.js' +import { createConnector } from './createConnector.js' + +export type MockParameters = { + accounts: readonly [Address, ...Address[]] + features?: + | { + defaultConnected?: boolean | undefined + connectError?: boolean | Error | undefined + switchChainError?: boolean | Error | undefined + signMessageError?: boolean | Error | undefined + signTypedDataError?: boolean | Error | undefined + reconnect?: boolean | undefined + watchAssetError?: boolean | Error | undefined + } + | undefined +} + +mock.type = 'mock' as const +export function mock(parameters: MockParameters) { + const transactionCache = new Map() + const features = + parameters.features ?? + ({ defaultConnected: false } satisfies MockParameters['features']) + + type Provider = ReturnType< + Transport<'custom', unknown, EIP1193RequestFn> + > + type Properties = { + connect(parameters?: { + chainId?: number | undefined + isReconnecting?: boolean | undefined + foo?: string | undefined + }): Promise<{ + accounts: readonly Address[] + chainId: number + }> + } + let connected = features.defaultConnected + let connectedChainId: number + + return createConnector((config) => ({ + id: 'mock', + name: 'Mock Connector', + type: mock.type, + async setup() { + connectedChainId = config.chains[0].id + }, + async connect({ chainId } = {}) { + if (features.connectError) { + if (typeof features.connectError === 'boolean') + throw new UserRejectedRequestError(new Error('Failed to connect.')) + throw features.connectError + } + + const provider = await this.getProvider() + const accounts = await provider.request({ + method: 'eth_requestAccounts', + }) + + let currentChainId = await this.getChainId() + if (chainId && currentChainId !== chainId) { + const chain = await this.switchChain!({ chainId }) + currentChainId = chain.id + } + + connected = true + + return { + accounts: accounts.map((x) => getAddress(x)), + chainId: currentChainId, + } + }, + async disconnect() { + connected = false + }, + async getAccounts() { + if (!connected) throw new ConnectorNotConnectedError() + const provider = await this.getProvider() + const accounts = await provider.request({ method: 'eth_accounts' }) + return accounts.map((x) => getAddress(x)) + }, + async getChainId() { + const provider = await this.getProvider() + const hexChainId = await provider.request({ method: 'eth_chainId' }) + return fromHex(hexChainId, 'number') + }, + async isAuthorized() { + if (!features.reconnect) return false + if (!connected) return false + const accounts = await this.getAccounts() + return !!accounts.length + }, + async switchChain({ chainId }) { + const provider = await this.getProvider() + const chain = config.chains.find((x) => x.id === chainId) + if (!chain) throw new SwitchChainError(new ChainNotConfiguredError()) + + await provider.request({ + method: 'wallet_switchEthereumChain', + params: [{ chainId: numberToHex(chainId) }], + }) + return chain + }, + onAccountsChanged(accounts) { + if (accounts.length === 0) this.onDisconnect() + else + config.emitter.emit('change', { + accounts: accounts.map((x) => getAddress(x)), + }) + }, + onChainChanged(chain) { + const chainId = Number(chain) + config.emitter.emit('change', { chainId }) + }, + async onDisconnect(_error) { + config.emitter.emit('disconnect') + connected = false + }, + async getProvider({ chainId } = {}) { + const chain = + config.chains.find((x) => x.id === chainId) ?? config.chains[0] + const url = chain.rpcUrls.default.http[0]! + + const request: EIP1193RequestFn = async ({ method, params }) => { + // eth methods + if (method === 'eth_chainId') return numberToHex(connectedChainId) + if (method === 'eth_requestAccounts') return parameters.accounts + if (method === 'eth_signTypedData_v4') + if (features.signTypedDataError) { + if (typeof features.signTypedDataError === 'boolean') + throw new UserRejectedRequestError( + new Error('Failed to sign typed data.'), + ) + throw features.signTypedDataError + } + + // wallet methods + if (method === 'wallet_switchEthereumChain') { + if (features.switchChainError) { + if (typeof features.switchChainError === 'boolean') + throw new UserRejectedRequestError( + new Error('Failed to switch chain.'), + ) + throw features.switchChainError + } + type Params = [{ chainId: Hex }] + connectedChainId = fromHex((params as Params)[0].chainId, 'number') + this.onChainChanged(connectedChainId.toString()) + return + } + + if (method === 'wallet_watchAsset') { + if (features.watchAssetError) { + if (typeof features.watchAssetError === 'boolean') + throw new UserRejectedRequestError( + new Error('Failed to switch chain.'), + ) + throw features.watchAssetError + } + return connected + } + + if (method === 'wallet_getCapabilities') + return { + '0x2105': { + paymasterService: { + supported: + (params as [Hex])[0] === + '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + }, + sessionKeys: { + supported: true, + }, + }, + '0x14A34': { + paymasterService: { + supported: + (params as [Hex])[0] === + '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + }, + }, + } + + if (method === 'wallet_sendCalls') { + const hashes = [] + const calls = (params as any)[0].calls + for (const call of calls) { + const { result, error } = await rpc.http(url, { + body: { + method: 'eth_sendTransaction', + params: [call], + }, + }) + if (error) + throw new RpcRequestError({ + body: { method, params }, + error, + url, + }) + hashes.push(result) + } + const id = keccak256(stringToHex(JSON.stringify(calls))) + transactionCache.set(id, hashes) + return { id } + } + + if (method === 'wallet_getCallsStatus') { + const hashes = transactionCache.get((params as any)[0]) + if (!hashes) + return { + atomic: false, + chainId: '0x1', + id: (params as any)[0], + status: 100, + receipts: [], + version: '2.0.0', + } satisfies WalletGetCallsStatusReturnType + + const receipts = await Promise.all( + hashes.map(async (hash) => { + const { result, error } = await rpc.http(url, { + body: { + method: 'eth_getTransactionReceipt', + params: [hash], + id: 0, + }, + }) + if (error) + throw new RpcRequestError({ + body: { method, params }, + error, + url, + }) + if (!result) return null + return { + blockHash: result.blockHash, + blockNumber: result.blockNumber, + gasUsed: result.gasUsed, + logs: result.logs, + status: result.status, + transactionHash: result.transactionHash, + } satisfies WalletCallReceipt + }), + ) + const receipts_ = receipts.filter((x) => x !== null) + if (receipts_.length === 0) + return { + atomic: false, + chainId: '0x1', + id: (params as any)[0], + status: 100, + receipts: [], + version: '2.0.0', + } satisfies WalletGetCallsStatusReturnType + return { + atomic: false, + chainId: '0x1', + id: (params as any)[0], + status: 200, + receipts: receipts_, + version: '2.0.0', + } satisfies WalletGetCallsStatusReturnType + } + + if (method === 'wallet_showCallsStatus') return + + // other methods + if (method === 'personal_sign') { + if (features.signMessageError) { + if (typeof features.signMessageError === 'boolean') + throw new UserRejectedRequestError( + new Error('Failed to sign message.'), + ) + throw features.signMessageError + } + // Change `personal_sign` to `eth_sign` and swap params + method = 'eth_sign' + type Params = [data: Hex, address: Address] + params = [(params as Params)[1], (params as Params)[0]] + } + + const body = { method, params } + const { error, result } = await rpc.http(url, { body }) + if (error) throw new RpcRequestError({ body, error, url }) + + return result + } + return custom({ request })({ retryCount: 0 }) + }, + })) +} diff --git a/wagmi-project/packages/core/src/createConfig.test-d.ts b/wagmi-project/packages/core/src/createConfig.test-d.ts new file mode 100644 index 0000000000..3daa57bd5f --- /dev/null +++ b/wagmi-project/packages/core/src/createConfig.test-d.ts @@ -0,0 +1,110 @@ +import { accounts } from '@wagmi/test' +import { http, createClient, webSocket } from 'viem' +import { mainnet, sepolia } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { mock } from './connectors/mock.js' +import { type CreateConfigParameters, createConfig } from './createConfig.js' + +test('high-level config', () => { + // Create config without needing to import viem modules. + const config = createConfig({ + cacheTime: 100, + chains: [mainnet, sepolia], + connectors: [mock({ accounts })], + batch: { multicall: true }, + pollingInterval: { [mainnet.id]: 100 }, + transports: { + [mainnet.id]: webSocket(), + [sepolia.id]: http(), + }, + }) + const client = config.getClient({ chainId: mainnet.id }) + expectTypeOf(client.chain).toEqualTypeOf(mainnet) + expectTypeOf(client.transport.type).toEqualTypeOf<'webSocket'>() +}) + +test('low-level config', () => { + // Create a "multi chain" config using viem modules. + const config = createConfig({ + chains: [mainnet, sepolia], + connectors: [mock({ accounts })], + client({ chain }) { + return createClient({ chain, transport: http() }) + }, + }) + const client = config.getClient({ chainId: mainnet.id }) + expectTypeOf(client.chain).toEqualTypeOf(mainnet) +}) + +test('behavior: `chains` must have at least one chain', () => { + createConfig({ + // @ts-expect-error + chains: [], + connectors: [mock({ accounts })], + transports: { + [mainnet.id]: http(), + }, + }) + createConfig({ + // @ts-expect-error + chains: [], + connectors: [mock({ accounts })], + client: ({ chain }) => + createClient({ + chain, + transport: http(), + }), + }) +}) + +test('behavior: missing transport for chain', () => { + createConfig({ + chains: [mainnet, sepolia], + connectors: [mock({ accounts })], + // @ts-expect-error + transports: { + [mainnet.id]: http(), + }, + }) + createConfig({ + chains: [mainnet, sepolia], + connectors: [mock({ accounts })], + transports: { + [mainnet.id]: http(), + // @ts-expect-error + [123]: http(), + }, + }) +}) + +test('behavior: parameters should not include certain client config properties', () => { + type Result = keyof CreateConfigParameters + expectTypeOf<'account' extends Result ? true : false>().toEqualTypeOf() + expectTypeOf<'chain' extends Result ? true : false>().toEqualTypeOf() + expectTypeOf< + 'transport' extends Result ? true : false + >().toEqualTypeOf() +}) + +test('infer connectors', () => { + const connectorFn = mock({ accounts }) + const config = createConfig({ + chains: [mainnet, sepolia], + connectors: [connectorFn], + transports: { + [mainnet.id]: webSocket(), + [sepolia.id]: http(), + }, + }) + + const connector = config.connectors[0]! + expectTypeOf(connector).toEqualTypeOf( + config._internal.connectors.setup(connectorFn), + ) + + type ConnectFnParameters = NonNullable< + Parameters<(typeof connector)['connect']>[0] + > + expectTypeOf().toMatchTypeOf() +}) diff --git a/wagmi-project/packages/core/src/createConfig.test.ts b/wagmi-project/packages/core/src/createConfig.test.ts new file mode 100644 index 0000000000..a6ae41e280 --- /dev/null +++ b/wagmi-project/packages/core/src/createConfig.test.ts @@ -0,0 +1,440 @@ +import { accounts, chain, wait } from '@wagmi/test' +import { + type EIP1193Provider, + type EIP6963ProviderDetail, + announceProvider, +} from 'mipd' +import { http } from 'viem' +import { expect, test, vi } from 'vitest' + +import { connect } from './actions/connect.js' +import { disconnect } from './actions/disconnect.js' +import { switchChain } from './actions/switchChain.js' +import { createConnector } from './connectors/createConnector.js' +import { mock } from './connectors/mock.js' +import { createConfig } from './createConfig.js' +import { createStorage } from './createStorage.js' + +const { mainnet, optimism } = chain + +vi.mock(import('mipd'), async (importOriginal) => { + const mod = await importOriginal() + + let cache: typeof mod | undefined + if (!cache) + cache = { + ...mod, + createStore() { + const store = mod.createStore() + return { + ...store, + getProviders() { + return [ + getProviderDetail({ name: 'Example', rdns: 'com.example' }), + getProviderDetail({ name: 'Mock', rdns: 'com.mock' }), + ] + }, + } + }, + } + return cache +}) + +test('default', () => { + const config = createConfig({ + chains: [mainnet], + connectors: [mock({ accounts })], + transports: { + [mainnet.id]: http(), + }, + }) + expect(config).toBeDefined() +}) + +test('getClient', () => { + const config = createConfig({ + chains: [mainnet, optimism], + connectors: [mock({ accounts })], + syncConnectedChain: true, + transports: { + [mainnet.id]: http(), + [optimism.id]: http(), + }, + }) + + { + const client = config.getClient() + expect(client.chain.id).toBe(mainnet.id) + } + + { + const client = config.getClient({ chainId: mainnet.id }) + expect(client.chain.id).toBe(mainnet.id) + } + + expect(() => + config.getClient({ + // @ts-expect-error + chainId: 123456, + }), + ).toThrowErrorMatchingInlineSnapshot(` + [ChainNotConfiguredError: Chain not configured. + + Version: @wagmi/core@x.y.z] + `) + + expect(() => { + // @ts-expect-error + config.state.chainId = 123456 + config.getClient() + }).toThrowErrorMatchingInlineSnapshot(` + [ChainNotConfiguredError: Chain not configured. + + Version: @wagmi/core@x.y.z] + `) +}) + +test('behavior: syncConnectedChain', async () => { + const config = createConfig({ + chains: [mainnet, optimism], + connectors: [mock({ accounts })], + syncConnectedChain: true, + transports: { + [mainnet.id]: http(), + [optimism.id]: http(), + }, + }) + // defaults to first chain in `createConfig({ chains })` + expect(config.getClient().chain.id).toBe(mainnet.id) + + // switches to optimism + await switchChain(config, { chainId: optimism.id }) + expect(config.getClient().chain.id).toBe(optimism.id) + + // connects to mainnet + await connect(config, { + chainId: mainnet.id, + connector: config.connectors[0]!, + }) + expect(config.getClient().chain.id).toBe(mainnet.id) + + // switches to optimism + await switchChain(config, { chainId: optimism.id }) + expect(config.getClient().chain.id).toBe(optimism.id) + + // disconnects, still connected to optimism + await disconnect(config) + expect(config.getClient().chain.id).toBe(optimism.id) +}) + +test('behavior: migrate for current version', async () => { + const state = { + 'wagmi.store': JSON.stringify({ + state: { + connections: { + __type: 'Map', + value: [ + [ + '983b8aca245', + { + accounts: [ + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + ], + chainId: 1, + connector: { + id: 'io.metamask', + name: 'MetaMask', + type: 'injected', + uid: '983b8aca245', + }, + }, + ], + ], + }, + chainId: 1, + current: '983b8aca245', + }, + version: Number.NaN, // mocked version is `'x.y.z'`, which will get interpreted as `NaN` + }), + } as Record + Object.defineProperty(window, 'localStorage', { + value: { + getItem: vi.fn((key) => state[key] ?? null), + removeItem: vi.fn((key) => state.delete?.[key]), + setItem: vi.fn((key, value) => { + state[key] = value + }), + }, + writable: true, + }) + + const storage = createStorage<{ store: object }>({ + storage: window.localStorage, + }) + + const config = createConfig({ + chains: [mainnet], + storage, + transports: { [mainnet.id]: http() }, + }) + + await wait(100) + + expect(config.state).toMatchInlineSnapshot(` + { + "chainId": 1, + "connections": Map { + "983b8aca245" => { + "accounts": [ + "0xA0Cf798816D4b9b9866b5330EEa46a18382f251e", + "0xd2135CfB216b74109775236E36d4b433F1DF507B", + ], + "chainId": 1, + "connector": { + "id": "io.metamask", + "name": "MetaMask", + "type": "injected", + "uid": "983b8aca245", + }, + }, + }, + "current": "983b8aca245", + "status": "disconnected", + } + `) +}) + +test('behavior: migrate chainId', async () => { + const state = { + 'wagmi.store': JSON.stringify({ + state: { chainId: 10 }, + version: 1, + }), + } as Record + Object.defineProperty(window, 'localStorage', { + value: { + getItem: vi.fn((key) => state[key] ?? null), + removeItem: vi.fn((key) => state.delete?.[key]), + setItem: vi.fn((key, value) => { + state[key] = value + }), + }, + writable: true, + }) + + const storage = createStorage<{ store: object }>({ + storage: window.localStorage, + }) + + const config = createConfig({ + chains: [mainnet, optimism], + storage, + transports: { + [mainnet.id]: http(), + [optimism.id]: http(), + }, + }) + + await wait(100) + + expect(config.state).toMatchInlineSnapshot(` + { + "chainId": 10, + "connections": Map {}, + "current": null, + "status": "disconnected", + } + `) +}) + +test('behavior: properties passed through to Viem Client via getClient', () => { + { + const properties = { + batch: { + multicall: { + batchSize: 102_400, + }, + }, + cacheTime: 5_000, + pollingInterval: 1_000, + } + + const config = createConfig({ + chains: [mainnet, optimism], + transports: { + [mainnet.id]: http(), + [optimism.id]: http(), + }, + ...properties, + }) + + const { + account: _a, + chain: _c, + extend: _e, + key: _k, + name: _n, + request: _r, + transport: _tr, + uid: _u, + type: _ty, + ...rest + } = config.getClient() + expect(rest).toEqual(properties) + } + + { + const config = createConfig({ + chains: [mainnet, optimism], + transports: { + [mainnet.id]: http(), + [optimism.id]: http(), + }, + batch: { + [mainnet.id]: { + multicall: { + batchSize: 1024, + }, + }, + }, + }) + + const client = config.getClient() + expect(client.batch).toMatchInlineSnapshot(` + { + "multicall": { + "batchSize": 1024, + }, + } + `) + + const client2 = config.getClient({ chainId: optimism.id }) + expect(client2.batch).toMatchInlineSnapshot(` + { + "multicall": true, + } + `) + } +}) + +test('behavior: restore unconfigured chainId', () => { + const state = { + 'wagmi.store': JSON.stringify({ + state: { chainId: 10 }, + version: 1, + }), + } as Record + Object.defineProperty(window, 'localStorage', { + value: { + getItem: vi.fn((key) => state[key] ?? null), + removeItem: vi.fn((key) => state.delete?.[key]), + setItem: vi.fn((key, value) => { + state[key] = value + }), + }, + writable: true, + }) + + const storage = createStorage<{ store: object }>({ + storage: window.localStorage, + }) + + const config = createConfig({ + chains: [mainnet], + storage, + transports: { + [mainnet.id]: http(), + }, + }) + + expect(config.state).toMatchInlineSnapshot(` + { + "chainId": 1, + "connections": Map {}, + "current": null, + "status": "disconnected", + } + `) + + const client = config.getClient() + expect(client.chain.id).toBe(mainnet.id) +}) + +test('behavior: setup connector', async () => { + const config = createConfig({ + chains: [mainnet], + transports: { + [mainnet.id]: http(), + }, + }) + + const connectorFn = mock({ accounts }) + const connector = config._internal.connectors.setup(connectorFn) + config._internal.connectors.setState((x) => [...x, connector]) + + await connect(config, { + chainId: mainnet.id, + connector: config.connectors.find((x) => x.uid === connector.uid)!, + }) + + expect(config.state.current).toBe(connector.uid) + + await disconnect(config) +}) + +test('behavior: eip 6963 providers', async () => { + const detail_1 = getProviderDetail({ name: 'Foo Wallet', rdns: 'com.foo' }) + const detail_2 = getProviderDetail({ name: 'Bar Wallet', rdns: 'com.bar' }) + const detail_3 = getProviderDetail({ name: 'Mock', rdns: 'com.mock' }) + + const config = createConfig({ + chains: [mainnet], + connectors: [ + createConnector((c) => { + return { + ...mock({ accounts })(c), + rdns: ['com.mock', 'com.baz'], + } + }), + ], + transports: { + [mainnet.id]: http(), + }, + }) + + await wait(100) + announceProvider(detail_1)() + await wait(100) + announceProvider(detail_1)() + await wait(100) + announceProvider(detail_2)() + await wait(100) + announceProvider(detail_3)() + await wait(100) + + expect( + config.connectors.flatMap((x) => x.rdns ?? x.id), + ).toMatchInlineSnapshot(` + [ + "com.mock", + "com.baz", + "com.example", + "com.foo", + "com.bar", + ] + `) +}) + +function getProviderDetail( + info: Pick, +): EIP6963ProviderDetail { + return { + info: { + icon: 'data:image/svg+xml,', + uuid: crypto.randomUUID(), + ...info, + }, + provider: `` as unknown as EIP1193Provider, + } +} diff --git a/wagmi-project/packages/core/src/createConfig.ts b/wagmi-project/packages/core/src/createConfig.ts new file mode 100644 index 0000000000..154eef5f6d --- /dev/null +++ b/wagmi-project/packages/core/src/createConfig.ts @@ -0,0 +1,653 @@ +import { + type EIP6963ProviderDetail, + type Store as MipdStore, + createStore as createMipd, +} from 'mipd' +import { + type Address, + type Chain, + type Client, + type EIP1193RequestFn, + createClient, + type ClientConfig as viem_ClientConfig, + type Transport as viem_Transport, +} from 'viem' +import { persist, subscribeWithSelector } from 'zustand/middleware' +import { type Mutate, type StoreApi, createStore } from 'zustand/vanilla' + +import type { + ConnectorEventMap, + CreateConnectorFn, +} from './connectors/createConnector.js' +import { injected } from './connectors/injected.js' +import { type Emitter, type EventData, createEmitter } from './createEmitter.js' +import { + type Storage, + createStorage, + getDefaultStorage, +} from './createStorage.js' +import { ChainNotConfiguredError } from './errors/config.js' +import type { + Compute, + ExactPartial, + LooseOmit, + OneOf, + RemoveUndefined, +} from './types/utils.js' +import { uid } from './utils/uid.js' +import { version } from './version.js' + +export function createConfig< + const chains extends readonly [Chain, ...Chain[]], + transports extends Record, + const connectorFns extends readonly CreateConnectorFn[], +>( + parameters: CreateConfigParameters, +): Config { + const { + multiInjectedProviderDiscovery = true, + storage = createStorage({ + storage: getDefaultStorage(), + }), + syncConnectedChain = true, + ssr = false, + ...rest + } = parameters + + ///////////////////////////////////////////////////////////////////////////////////////////////// + // Set up connectors, clients, etc. + ///////////////////////////////////////////////////////////////////////////////////////////////// + + const mipd = + typeof window !== 'undefined' && multiInjectedProviderDiscovery + ? createMipd() + : undefined + + const chains = createStore(() => rest.chains) + const connectors = createStore(() => { + const collection = [] + const rdnsSet = new Set() + for (const connectorFns of rest.connectors ?? []) { + const connector = setup(connectorFns) + collection.push(connector) + if (!ssr && connector.rdns) { + const rdnsValues = + typeof connector.rdns === 'string' ? [connector.rdns] : connector.rdns + for (const rdns of rdnsValues) { + rdnsSet.add(rdns) + } + } + } + if (!ssr && mipd) { + const providers = mipd.getProviders() + for (const provider of providers) { + if (rdnsSet.has(provider.info.rdns)) continue + collection.push(setup(providerDetailToConnector(provider))) + } + } + return collection + }) + function setup(connectorFn: CreateConnectorFn): Connector { + // Set up emitter with uid and add to connector so they are "linked" together. + const emitter = createEmitter(uid()) + const connector = { + ...connectorFn({ + emitter, + chains: chains.getState(), + storage, + transports: rest.transports, + }), + emitter, + uid: emitter.uid, + } + + // Start listening for `connect` events on connector setup + // This allows connectors to "connect" themselves without user interaction (e.g. MetaMask's "Manually connect to current site") + emitter.on('connect', connect) + connector.setup?.() + + return connector + } + function providerDetailToConnector(providerDetail: EIP6963ProviderDetail) { + const { info } = providerDetail + const provider = providerDetail.provider as any + return injected({ target: { ...info, id: info.rdns, provider } }) + } + + const clients = new Map>() + function getClient( + config: { chainId?: chainId | chains[number]['id'] | undefined } = {}, + ): Client> { + const chainId = config.chainId ?? store.getState().chainId + const chain = chains.getState().find((x) => x.id === chainId) + + // chainId specified and not configured + if (config.chainId && !chain) throw new ChainNotConfiguredError() + + // If the target chain is not configured, use the client of the current chain. + type Return = Client> + { + const client = clients.get(store.getState().chainId) + if (client && !chain) return client as Return + if (!chain) throw new ChainNotConfiguredError() + } + + // If a memoized client exists for a chain id, use that. + { + const client = clients.get(chainId) + if (client) return client as Return + } + + let client: Client + if (rest.client) client = rest.client({ chain }) + else { + const chainId = chain.id as chains[number]['id'] + const chainIds = chains.getState().map((x) => x.id) + // Grab all properties off `rest` and resolve for use in `createClient` + const properties: Partial = {} + const entries = Object.entries(rest) as [keyof typeof rest, any][] + + for (const [key, value] of entries) { + if ( + key === 'chains' || + key === 'client' || + key === 'connectors' || + key === 'transports' + ) + continue + + if (typeof value === 'object') { + // check if value is chainId-specific since some values can be objects + // e.g. { batch: { multicall: { batchSize: 1024 } } } + if (chainId in value) properties[key] = value[chainId] + else { + // check if value is chainId-specific, but does not have value for current chainId + const hasChainSpecificValue = chainIds.some((x) => x in value) + if (hasChainSpecificValue) continue + properties[key] = value + } + } else properties[key] = value + } + + client = createClient({ + ...properties, + chain, + batch: properties.batch ?? { multicall: true }, + transport: (parameters) => + rest.transports[chainId]({ ...parameters, connectors }), + }) + } + + clients.set(chainId, client) + return client as Return + } + + ///////////////////////////////////////////////////////////////////////////////////////////////// + // Create store + ///////////////////////////////////////////////////////////////////////////////////////////////// + + function getInitialState(): State { + return { + chainId: chains.getState()[0].id, + connections: new Map(), + current: null, + status: 'disconnected', + } + } + + let currentVersion: number + const prefix = '0.0.0-canary-' + if (version.startsWith(prefix)) + currentVersion = Number.parseInt(version.replace(prefix, '')) + // use package major version to version store + else currentVersion = Number.parseInt(version.split('.')[0] ?? '0') + + const store = createStore( + subscribeWithSelector( + // only use persist middleware if storage exists + storage + ? persist(getInitialState, { + migrate(persistedState, version) { + if (version === currentVersion) return persistedState as State + + const initialState = getInitialState() + const chainId = validatePersistedChainId( + persistedState, + initialState.chainId, + ) + return { ...initialState, chainId } + }, + name: 'store', + partialize(state) { + // Only persist "critical" store properties to preserve storage size. + return { + connections: { + __type: 'Map', + value: Array.from(state.connections.entries()).map( + ([key, connection]) => { + const { id, name, type, uid } = connection.connector + const connector = { id, name, type, uid } + return [key, { ...connection, connector }] + }, + ), + } as unknown as PartializedState['connections'], + chainId: state.chainId, + current: state.current, + } satisfies PartializedState + }, + merge(persistedState, currentState) { + // `status` should not be persisted as it messes with reconnection + if ( + typeof persistedState === 'object' && + persistedState && + 'status' in persistedState + ) + delete persistedState.status + // Make sure persisted `chainId` is valid + const chainId = validatePersistedChainId( + persistedState, + currentState.chainId, + ) + return { + ...currentState, + ...(persistedState as object), + chainId, + } + }, + skipHydration: ssr, + storage: storage as Storage>, + version: currentVersion, + }) + : getInitialState, + ), + ) + store.setState(getInitialState()) + + function validatePersistedChainId( + persistedState: unknown, + defaultChainId: number, + ) { + return persistedState && + typeof persistedState === 'object' && + 'chainId' in persistedState && + typeof persistedState.chainId === 'number' && + chains.getState().some((x) => x.id === persistedState.chainId) + ? persistedState.chainId + : defaultChainId + } + + ///////////////////////////////////////////////////////////////////////////////////////////////// + // Subscribe to changes + ///////////////////////////////////////////////////////////////////////////////////////////////// + + // Update default chain when connector chain changes + if (syncConnectedChain) + store.subscribe( + ({ connections, current }) => + current ? connections.get(current)?.chainId : undefined, + (chainId) => { + // If chain is not configured, then don't switch over to it. + const isChainConfigured = chains + .getState() + .some((x) => x.id === chainId) + if (!isChainConfigured) return + + return store.setState((x) => ({ + ...x, + chainId: chainId ?? x.chainId, + })) + }, + ) + + // EIP-6963 subscribe for new wallet providers + mipd?.subscribe((providerDetails) => { + const connectorIdSet = new Set() + const connectorRdnsSet = new Set() + for (const connector of connectors.getState()) { + connectorIdSet.add(connector.id) + if (connector.rdns) { + const rdnsValues = + typeof connector.rdns === 'string' ? [connector.rdns] : connector.rdns + for (const rdns of rdnsValues) { + connectorRdnsSet.add(rdns) + } + } + } + + const newConnectors: Connector[] = [] + for (const providerDetail of providerDetails) { + if (connectorRdnsSet.has(providerDetail.info.rdns)) continue + const connector = setup(providerDetailToConnector(providerDetail)) + if (connectorIdSet.has(connector.id)) continue + newConnectors.push(connector) + } + + if (storage && !store.persist.hasHydrated()) return + connectors.setState((x) => [...x, ...newConnectors], true) + }) + + ///////////////////////////////////////////////////////////////////////////////////////////////// + // Emitter listeners + ///////////////////////////////////////////////////////////////////////////////////////////////// + + function change(data: EventData) { + store.setState((x) => { + const connection = x.connections.get(data.uid) + if (!connection) return x + return { + ...x, + connections: new Map(x.connections).set(data.uid, { + accounts: + (data.accounts as readonly [Address, ...Address[]]) ?? + connection.accounts, + chainId: data.chainId ?? connection.chainId, + connector: connection.connector, + }), + } + }) + } + function connect(data: EventData) { + // Disable handling if reconnecting/connecting + if ( + store.getState().status === 'connecting' || + store.getState().status === 'reconnecting' + ) + return + + store.setState((x) => { + const connector = connectors.getState().find((x) => x.uid === data.uid) + if (!connector) return x + + if (connector.emitter.listenerCount('connect')) + connector.emitter.off('connect', change) + if (!connector.emitter.listenerCount('change')) + connector.emitter.on('change', change) + if (!connector.emitter.listenerCount('disconnect')) + connector.emitter.on('disconnect', disconnect) + + return { + ...x, + connections: new Map(x.connections).set(data.uid, { + accounts: data.accounts as readonly [Address, ...Address[]], + chainId: data.chainId, + connector: connector, + }), + current: data.uid, + status: 'connected', + } + }) + } + function disconnect(data: EventData) { + store.setState((x) => { + const connection = x.connections.get(data.uid) + if (connection) { + const connector = connection.connector + if (connector.emitter.listenerCount('change')) + connection.connector.emitter.off('change', change) + if (connector.emitter.listenerCount('disconnect')) + connection.connector.emitter.off('disconnect', disconnect) + if (!connector.emitter.listenerCount('connect')) + connection.connector.emitter.on('connect', connect) + } + + x.connections.delete(data.uid) + + if (x.connections.size === 0) + return { + ...x, + connections: new Map(), + current: null, + status: 'disconnected', + } + + const nextConnection = x.connections.values().next().value as Connection + return { + ...x, + connections: new Map(x.connections), + current: nextConnection.connector.uid, + } + }) + } + + return { + get chains() { + return chains.getState() as chains + }, + get connectors() { + return connectors.getState() as Connector[] + }, + storage, + + getClient, + get state() { + return store.getState() as unknown as State + }, + setState(value) { + let newState: State + if (typeof value === 'function') newState = value(store.getState() as any) + else newState = value + + // Reset state if it got set to something not matching the base state + const initialState = getInitialState() + if (typeof newState !== 'object') newState = initialState + const isCorrupt = Object.keys(initialState).some((x) => !(x in newState)) + if (isCorrupt) newState = initialState + + store.setState(newState, true) + }, + subscribe(selector, listener, options) { + return store.subscribe( + selector as unknown as (state: State) => any, + listener, + options + ? ({ + ...options, + fireImmediately: options.emitImmediately, + // Workaround cast since Zustand does not support `'exactOptionalPropertyTypes'` + } as RemoveUndefined) + : undefined, + ) + }, + + _internal: { + mipd, + store, + ssr: Boolean(ssr), + syncConnectedChain, + transports: rest.transports as transports, + chains: { + setState(value) { + const nextChains = ( + typeof value === 'function' ? value(chains.getState()) : value + ) as chains + if (nextChains.length === 0) return + return chains.setState(nextChains, true) + }, + subscribe(listener) { + return chains.subscribe(listener) + }, + }, + connectors: { + providerDetailToConnector, + setup: setup as ( + connectorFn: connectorFn, + ) => Connector, + setState(value) { + return connectors.setState( + typeof value === 'function' ? value(connectors.getState()) : value, + true, + ) + }, + subscribe(listener) { + return connectors.subscribe(listener) + }, + }, + events: { change, connect, disconnect }, + }, + } +} + +///////////////////////////////////////////////////////////////////////////////////////////////// +// Types +///////////////////////////////////////////////////////////////////////////////////////////////// + +export type CreateConfigParameters< + chains extends readonly [Chain, ...Chain[]] = readonly [Chain, ...Chain[]], + transports extends Record = Record< + chains[number]['id'], + Transport + >, + connectorFns extends + readonly CreateConnectorFn[] = readonly CreateConnectorFn[], +> = Compute< + { + chains: chains + connectors?: connectorFns | undefined + multiInjectedProviderDiscovery?: boolean | undefined + storage?: Storage | null | undefined + ssr?: boolean | undefined + syncConnectedChain?: boolean | undefined + } & OneOf< + | ({ transports: transports } & { + [key in keyof ClientConfig]?: + | ClientConfig[key] + | { [_ in chains[number]['id']]?: ClientConfig[key] | undefined } + | undefined + }) + | { + client(parameters: { chain: chains[number] }): Client< + transports[chains[number]['id']], + chains[number] + > + } + > +> + +export type Config< + chains extends readonly [Chain, ...Chain[]] = readonly [Chain, ...Chain[]], + transports extends Record = Record< + chains[number]['id'], + Transport + >, + connectorFns extends + readonly CreateConnectorFn[] = readonly CreateConnectorFn[], +> = { + readonly chains: chains + readonly connectors: readonly Connector[] + readonly storage: Storage | null + + readonly state: State + setState( + value: State | ((state: State) => State), + ): void + subscribe( + selector: (state: State) => state, + listener: (state: state, previousState: state) => void, + options?: + | { + emitImmediately?: boolean | undefined + equalityFn?: ((a: state, b: state) => boolean) | undefined + } + | undefined, + ): () => void + + getClient(parameters?: { + chainId?: chainId | chains[number]['id'] | undefined + }): Client> + + /** + * Not part of versioned API, proceed with caution. + * @internal + */ + _internal: Internal +} + +type Internal< + chains extends readonly [Chain, ...Chain[]] = readonly [Chain, ...Chain[]], + transports extends Record = Record< + chains[number]['id'], + Transport + >, +> = { + readonly mipd: MipdStore | undefined + readonly store: Mutate, [['zustand/persist', any]]> + readonly ssr: boolean + readonly syncConnectedChain: boolean + readonly transports: transports + + chains: { + setState( + value: + | readonly [Chain, ...Chain[]] + | (( + state: readonly [Chain, ...Chain[]], + ) => readonly [Chain, ...Chain[]]), + ): void + subscribe( + listener: ( + state: readonly [Chain, ...Chain[]], + prevState: readonly [Chain, ...Chain[]], + ) => void, + ): () => void + } + connectors: { + providerDetailToConnector( + providerDetail: EIP6963ProviderDetail, + ): CreateConnectorFn + setup( + connectorFn: connectorFn, + ): Connector + setState(value: Connector[] | ((state: Connector[]) => Connector[])): void + subscribe( + listener: (state: Connector[], prevState: Connector[]) => void, + ): () => void + } + events: { + change(data: EventData): void + connect(data: EventData): void + disconnect(data: EventData): void + } +} + +export type State< + chains extends readonly [Chain, ...Chain[]] = readonly [Chain, ...Chain[]], +> = { + chainId: chains[number]['id'] + connections: Map + current: string | null + status: 'connected' | 'connecting' | 'disconnected' | 'reconnecting' +} + +export type PartializedState = Compute< + ExactPartial> +> + +export type Connection = { + accounts: readonly [Address, ...Address[]] + chainId: number + connector: Connector +} + +export type Connector< + createConnectorFn extends CreateConnectorFn = CreateConnectorFn, +> = ReturnType & { + emitter: Emitter + uid: string +} + +export type Transport< + type extends string = string, + rpcAttributes = Record, + eip1193RequestFn extends EIP1193RequestFn = EIP1193RequestFn, +> = ( + params: Parameters< + viem_Transport + >[0] & { + connectors?: StoreApi | undefined + }, +) => ReturnType> + +type ClientConfig = LooseOmit< + viem_ClientConfig, + 'account' | 'chain' | 'key' | 'name' | 'transport' | 'type' +> diff --git a/wagmi-project/packages/core/src/createEmitter.test.ts b/wagmi-project/packages/core/src/createEmitter.test.ts new file mode 100644 index 0000000000..5eb453bb51 --- /dev/null +++ b/wagmi-project/packages/core/src/createEmitter.test.ts @@ -0,0 +1,19 @@ +import { expect, test, vi } from 'vitest' + +import type { ConnectorEventMap } from './connectors/createConnector.js' +import { createEmitter } from './createEmitter.js' +import { uid } from './utils/uid.js' + +test('default', () => { + const emitter = createEmitter(uid()) + + const onMessage = vi.fn() + emitter.on('message', onMessage) + emitter.emit('message', { type: 'bar', data: 'baz' }) + + expect(onMessage).toHaveBeenCalledWith({ + type: 'bar', + data: 'baz', + uid: emitter.uid, + }) +}) diff --git a/wagmi-project/packages/core/src/createEmitter.ts b/wagmi-project/packages/core/src/createEmitter.ts new file mode 100644 index 0000000000..20bf4c5a88 --- /dev/null +++ b/wagmi-project/packages/core/src/createEmitter.ts @@ -0,0 +1,68 @@ +import { EventEmitter } from 'eventemitter3' + +type EventMap = Record +type EventKey = string & keyof eventMap +type EventFn = ( + ...parameters: parameters +) => void +export type EventData< + eventMap extends EventMap, + eventName extends keyof eventMap, +> = (eventMap[eventName] extends [never] ? unknown : eventMap[eventName]) & { + uid: string +} + +export class Emitter { + _emitter = new EventEmitter() + + constructor(public uid: string) {} + + on>( + eventName: key, + fn: EventFn< + eventMap[key] extends [never] + ? [{ uid: string }] + : [data: eventMap[key] & { uid: string }] + >, + ) { + this._emitter.on(eventName, fn as EventFn) + } + + once>( + eventName: key, + fn: EventFn< + eventMap[key] extends [never] + ? [{ uid: string }] + : [data: eventMap[key] & { uid: string }] + >, + ) { + this._emitter.once(eventName, fn as EventFn) + } + + off>( + eventName: key, + fn: EventFn< + eventMap[key] extends [never] + ? [{ uid: string }] + : [data: eventMap[key] & { uid: string }] + >, + ) { + this._emitter.off(eventName, fn as EventFn) + } + + emit>( + eventName: key, + ...params: eventMap[key] extends [never] ? [] : [data: eventMap[key]] + ) { + const data = params[0] + this._emitter.emit(eventName, { uid: this.uid, ...data }) + } + + listenerCount>(eventName: key) { + return this._emitter.listenerCount(eventName) + } +} + +export function createEmitter(uid: string) { + return new Emitter(uid) +} diff --git a/wagmi-project/packages/core/src/createStorage.test-d.ts b/wagmi-project/packages/core/src/createStorage.test-d.ts new file mode 100644 index 0000000000..6bb4c7f300 --- /dev/null +++ b/wagmi-project/packages/core/src/createStorage.test-d.ts @@ -0,0 +1,74 @@ +import { expectTypeOf, test } from 'vitest' +import { createStorage } from './createStorage.js' + +import type { Connection } from './createConfig.js' + +test('getItem', () => { + const storage = createStorage({ storage: localStorage }) + + expectTypeOf(storage.getItem('recentConnectorId')).toEqualTypeOf< + string | null | Promise + >() + expectTypeOf(storage.getItem('recentConnectorId', 'foo')).toEqualTypeOf< + string | Promise + >() + expectTypeOf(storage.getItem('foo')).toEqualTypeOf() + // @ts-expect-error incorrect argument type + storage.getItem('recentConnectorId', 1n) + + expectTypeOf(storage.getItem('state')).toEqualTypeOf< + | { + chainId?: number | undefined + connections?: Map | undefined + current?: string | null | undefined + status?: + | 'connected' + | 'connecting' + | 'reconnecting' + | 'disconnected' + | undefined + } + | null + | Promise<{ + chainId?: number | undefined + connections?: Map | undefined + current?: string | null | undefined + status?: + | 'connected' + | 'connecting' + | 'reconnecting' + | 'disconnected' + | undefined + } | null> + >() + + const customStorage = createStorage<{ foo: number }>({ + storage: localStorage, + }) + expectTypeOf(customStorage.getItem('foo')).toEqualTypeOf< + number | null | Promise + >() + expectTypeOf(customStorage.getItem('foo', 1)).toEqualTypeOf< + number | Promise + >() +}) + +test('setItem', () => { + const storage = createStorage({ storage: localStorage }) + + storage.setItem('recentConnectorId', 'foo') + // @ts-expect-error incorrect argument type + storage.setItem('recentConnectorId', 1n) +}) + +test('serialize/deserialize types', () => { + createStorage({ + deserialize(value) { + return value + }, + serialize(value) { + return value + }, + storage: localStorage, + }) +}) diff --git a/wagmi-project/packages/core/src/createStorage.test.ts b/wagmi-project/packages/core/src/createStorage.test.ts new file mode 100644 index 0000000000..06aa0f89d6 --- /dev/null +++ b/wagmi-project/packages/core/src/createStorage.test.ts @@ -0,0 +1,45 @@ +import { expect, test, vi } from 'vitest' + +import { createStorage } from './createStorage.js' + +Object.defineProperty(window, 'localStorage', { + value: { + getItem: vi.fn(() => null), + removeItem: vi.fn(() => null), + setItem: vi.fn(() => null), + }, + writable: true, +}) + +test('inits', () => { + const storage = createStorage({ storage: window.localStorage }) + expect(storage).toBeDefined() +}) + +test('getItem', () => { + const storage = createStorage({ storage: window.localStorage }) + storage.getItem('recentConnectorId') + expect(window.localStorage.getItem).toHaveBeenCalledTimes(1) + expect(window.localStorage.getItem).toHaveBeenCalledWith( + 'wagmi.recentConnectorId', + ) +}) + +test('setItem', () => { + const storage = createStorage({ storage: window.localStorage }) + storage.setItem('recentConnectorId', 'bar') + expect(window.localStorage.setItem).toHaveBeenCalledTimes(1) + expect(window.localStorage.setItem).toHaveBeenCalledWith( + 'wagmi.recentConnectorId', + '"bar"', + ) +}) + +test('removeItem', () => { + const storage = createStorage({ storage: window.localStorage }) + storage.removeItem('recentConnectorId') + expect(window.localStorage.removeItem).toHaveBeenCalledTimes(1) + expect(window.localStorage.removeItem).toHaveBeenCalledWith( + 'wagmi.recentConnectorId', + ) +}) diff --git a/wagmi-project/packages/core/src/createStorage.ts b/wagmi-project/packages/core/src/createStorage.ts new file mode 100644 index 0000000000..8995ca3202 --- /dev/null +++ b/wagmi-project/packages/core/src/createStorage.ts @@ -0,0 +1,112 @@ +import type { PartializedState } from './createConfig.js' +import type { Compute } from './types/utils.js' +import { deserialize as deserialize_ } from './utils/deserialize.js' +import { serialize as serialize_ } from './utils/serialize.js' + +// key-values for loose autocomplete and typing +export type StorageItemMap = { + recentConnectorId: string + state: PartializedState +} + +export type Storage< + itemMap extends Record = Record, + /// + storageItemMap extends StorageItemMap = StorageItemMap & itemMap, +> = { + key: string + getItem< + key extends keyof storageItemMap, + value extends storageItemMap[key], + defaultValue extends value | null | undefined, + >( + key: key, + defaultValue?: defaultValue | undefined, + ): + | (defaultValue extends null ? value | null : value) + | Promise + setItem< + key extends keyof storageItemMap, + value extends storageItemMap[key] | null, + >(key: key, value: value): void | Promise + removeItem(key: keyof storageItemMap): void | Promise +} + +export type BaseStorage = { + getItem( + key: string, + ): string | null | undefined | Promise + setItem(key: string, value: string): void | Promise + removeItem(key: string): void | Promise +} + +export type CreateStorageParameters = { + deserialize?: ((value: string) => type | unknown) | undefined + key?: string | undefined + serialize?: ((value: type | any) => string) | undefined + storage?: Compute | undefined +} + +export function createStorage< + itemMap extends Record = Record, + storageItemMap extends StorageItemMap = StorageItemMap & itemMap, +>(parameters: CreateStorageParameters): Compute> { + const { + deserialize = deserialize_, + key: prefix = 'wagmi', + serialize = serialize_, + storage = noopStorage, + } = parameters + + function unwrap(value: type): type | Promise { + if (value instanceof Promise) return value.then((x) => x).catch(() => null) + return value + } + + return { + ...storage, + key: prefix, + async getItem(key, defaultValue) { + const value = storage.getItem(`${prefix}.${key as string}`) + const unwrapped = await unwrap(value) + if (unwrapped) return deserialize(unwrapped) ?? null + return (defaultValue ?? null) as any + }, + async setItem(key, value) { + const storageKey = `${prefix}.${key as string}` + if (value === null) await unwrap(storage.removeItem(storageKey)) + else await unwrap(storage.setItem(storageKey, serialize(value))) + }, + async removeItem(key) { + await unwrap(storage.removeItem(`${prefix}.${key as string}`)) + }, + } +} + +export const noopStorage = { + getItem: () => null, + setItem: () => {}, + removeItem: () => {}, +} satisfies BaseStorage + +export function getDefaultStorage() { + const storage = (() => { + if (typeof window !== 'undefined' && window.localStorage) + return window.localStorage + return noopStorage + })() + return { + getItem(key) { + return storage.getItem(key) + }, + removeItem(key) { + storage.removeItem(key) + }, + setItem(key, value) { + try { + storage.setItem(key, value) + // silence errors by default (QuotaExceededError, SecurityError, etc.) + } catch {} + }, + } satisfies BaseStorage +} diff --git a/wagmi-project/packages/core/src/errors/base.test.ts b/wagmi-project/packages/core/src/errors/base.test.ts new file mode 100644 index 0000000000..443b1ea3cf --- /dev/null +++ b/wagmi-project/packages/core/src/errors/base.test.ts @@ -0,0 +1,155 @@ +import { expect, test } from 'vitest' + +import { BaseError } from './base.js' + +test('BaseError', () => { + expect(new BaseError('An error occurred.')).toMatchInlineSnapshot(` + [WagmiCoreError: An error occurred. + + Version: @wagmi/core@x.y.z] + `) + + expect( + new BaseError('An error occurred.', { details: 'details' }), + ).toMatchInlineSnapshot(` + [WagmiCoreError: An error occurred. + + Details: details + Version: @wagmi/core@x.y.z] + `) + + expect(new BaseError('', { details: 'details' })).toMatchInlineSnapshot(` + [WagmiCoreError: An error occurred. + + Details: details + Version: @wagmi/core@x.y.z] + `) +}) + +test('BaseError (w/ docsPath)', () => { + expect( + new BaseError('An error occurred.', { + details: 'details', + docsPath: '/lol', + }), + ).toMatchInlineSnapshot(` + [WagmiCoreError: An error occurred. + + Docs: https://wagmi.sh/core/lol.html + Details: details + Version: @wagmi/core@x.y.z] + `) + expect( + new BaseError('An error occurred.', { + cause: new BaseError('error', { docsPath: '/docs' }), + }), + ).toMatchInlineSnapshot(` + [WagmiCoreError: An error occurred. + + Docs: https://wagmi.sh/core/docs.html + Version: @wagmi/core@x.y.z] + `) + expect( + new BaseError('An error occurred.', { + cause: new BaseError('error'), + docsPath: '/lol', + }), + ).toMatchInlineSnapshot(` + [WagmiCoreError: An error occurred. + + Docs: https://wagmi.sh/core/lol.html + Version: @wagmi/core@x.y.z] + `) + expect( + new BaseError('An error occurred.', { + details: 'details', + docsPath: '/lol', + docsSlug: 'test', + }), + ).toMatchInlineSnapshot(` + [WagmiCoreError: An error occurred. + + Docs: https://wagmi.sh/core/lol.html#test + Details: details + Version: @wagmi/core@x.y.z] + `) +}) + +test('BaseError (w/ metaMessages)', () => { + expect( + new BaseError('An error occurred.', { + details: 'details', + metaMessages: ['Reason: idk', 'Cause: lol'], + }), + ).toMatchInlineSnapshot(` + [WagmiCoreError: An error occurred. + + Reason: idk + Cause: lol + + Details: details + Version: @wagmi/core@x.y.z] + `) +}) + +test('inherited BaseError', () => { + const err = new BaseError('An error occurred.', { + details: 'details', + docsPath: '/lol', + }) + expect( + new BaseError('An internal error occurred.', { + cause: err, + }), + ).toMatchInlineSnapshot(` + [WagmiCoreError: An internal error occurred. + + Docs: https://wagmi.sh/core/lol.html + Details: details + Version: @wagmi/core@x.y.z] + `) +}) + +test('inherited Error', () => { + const err = new Error('details') + expect( + new BaseError('An internal error occurred.', { + cause: err, + docsPath: '/lol', + }), + ).toMatchInlineSnapshot(` + [WagmiCoreError: An internal error occurred. + + Docs: https://wagmi.sh/core/lol.html + Details: details + Version: @wagmi/core@x.y.z] + `) +}) + +test('walk: no predicate fn (walks to leaf)', () => { + class FooError extends BaseError {} + class BarError extends BaseError {} + + const err = new BaseError('test1', { + cause: new FooError('test2', { cause: new BarError('test3') }), + }) + expect(err.walk()).toMatchInlineSnapshot(` + [WagmiCoreError: test3 + + Version: @wagmi/core@x.y.z] + `) +}) + +test('walk: predicate fn', () => { + class FooError extends BaseError {} + class BarError extends BaseError {} + + const err = new BaseError('test1', { + cause: new FooError('test2', { cause: new BarError('test3') }), + }) + expect(err.walk((err) => err instanceof FooError)).toMatchInlineSnapshot(` + [WagmiCoreError: test2 + + Version: @wagmi/core@x.y.z] + `) +}) diff --git a/wagmi-project/packages/core/src/errors/base.ts b/wagmi-project/packages/core/src/errors/base.ts new file mode 100644 index 0000000000..8540c1da7b --- /dev/null +++ b/wagmi-project/packages/core/src/errors/base.ts @@ -0,0 +1,74 @@ +import type { Compute, OneOf } from '../types/utils.js' +import { getVersion } from '../utils/getVersion.js' + +export type ErrorType = Error & { name: name } + +type BaseErrorOptions = Compute< + OneOf<{ details?: string | undefined } | { cause: BaseError | Error }> & { + docsPath?: string | undefined + docsSlug?: string | undefined + metaMessages?: string[] | undefined + } +> + +export type BaseErrorType = BaseError & { name: 'WagmiCoreError' } +export class BaseError extends Error { + details: string + docsPath?: string | undefined + metaMessages?: string[] | undefined + shortMessage: string + + override name = 'WagmiCoreError' + get docsBaseUrl() { + return 'https://wagmi.sh/core' + } + get version() { + return getVersion() + } + + constructor(shortMessage: string, options: BaseErrorOptions = {}) { + super() + + const details = + options.cause instanceof BaseError + ? options.cause.details + : options.cause?.message + ? options.cause.message + : options.details! + const docsPath = + options.cause instanceof BaseError + ? options.cause.docsPath || options.docsPath + : options.docsPath + + this.message = [ + shortMessage || 'An error occurred.', + '', + ...(options.metaMessages ? [...options.metaMessages, ''] : []), + ...(docsPath + ? [ + `Docs: ${this.docsBaseUrl}${docsPath}.html${ + options.docsSlug ? `#${options.docsSlug}` : '' + }`, + ] + : []), + ...(details ? [`Details: ${details}`] : []), + `Version: ${this.version}`, + ].join('\n') + + if (options.cause) this.cause = options.cause + this.details = details + this.docsPath = docsPath + this.metaMessages = options.metaMessages + this.shortMessage = shortMessage + } + + walk(fn?: (err: unknown) => boolean) { + return this.#walk(this, fn) + } + + #walk(err: unknown, fn?: (err: unknown) => boolean): unknown { + if (fn?.(err)) return err + if ((err as Error).cause) return this.#walk((err as Error).cause, fn) + return err + } +} diff --git a/wagmi-project/packages/core/src/errors/config.test.ts b/wagmi-project/packages/core/src/errors/config.test.ts new file mode 100644 index 0000000000..1ec07fd107 --- /dev/null +++ b/wagmi-project/packages/core/src/errors/config.test.ts @@ -0,0 +1,68 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { + ChainNotConfiguredError, + ConnectorAccountNotFoundError, + ConnectorAlreadyConnectedError, + ConnectorChainMismatchError, + ConnectorNotConnectedError, + ConnectorNotFoundError, + ConnectorUnavailableReconnectingError, +} from './config.js' + +test('constructors', () => { + expect(new ChainNotConfiguredError()).toMatchInlineSnapshot(` + [ChainNotConfiguredError: Chain not configured. + + Version: @wagmi/core@x.y.z] + `) + expect(new ConnectorAlreadyConnectedError()).toMatchInlineSnapshot(` + [ConnectorAlreadyConnectedError: Connector already connected. + + Version: @wagmi/core@x.y.z] + `) + expect(new ConnectorNotConnectedError()).toMatchInlineSnapshot(` + [ConnectorNotConnectedError: Connector not connected. + + Version: @wagmi/core@x.y.z] + `) + expect(new ConnectorNotFoundError()).toMatchInlineSnapshot(` + [ConnectorNotFoundError: Connector not found. + + Version: @wagmi/core@x.y.z] + `) + expect( + new ConnectorAccountNotFoundError({ + address: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + connector: config.connectors[0]!, + }), + ).toMatchInlineSnapshot(` + [ConnectorAccountNotFoundError: Account "0xA0Cf798816D4b9b9866b5330EEa46a18382f251e" not found for connector "Mock Connector". + + Version: @wagmi/core@x.y.z] + `) + expect( + new ConnectorChainMismatchError({ + connectionChainId: 1, + connectorChainId: 123, + }), + ).toMatchInlineSnapshot(` + [ConnectorChainMismatchError: The current chain of the connector (id: 123) does not match the connection's chain (id: 1). + + Current Chain ID: 123 + Expected Chain ID: 1 + + Version: @wagmi/core@x.y.z] + `) + expect( + new ConnectorUnavailableReconnectingError({ + connector: { name: 'Rabby Wallet' }, + }), + ).toMatchInlineSnapshot(` + [ConnectorUnavailableReconnectingError: Connector "Rabby Wallet" unavailable while reconnecting. + + Details: During the reconnection step, the only connector methods guaranteed to be available are: \`id\`, \`name\`, \`type\`, \`uid\`. All other methods are not guaranteed to be available until reconnection completes and connectors are fully restored. This error commonly occurs for connectors that asynchronously inject after reconnection has already started. + Version: @wagmi/core@x.y.z] + `) +}) diff --git a/wagmi-project/packages/core/src/errors/config.ts b/wagmi-project/packages/core/src/errors/config.ts new file mode 100644 index 0000000000..2956f0132c --- /dev/null +++ b/wagmi-project/packages/core/src/errors/config.ts @@ -0,0 +1,103 @@ +import type { Address } from 'viem' + +import type { Connector } from '../createConfig.js' +import { BaseError } from './base.js' + +export type ChainNotConfiguredErrorType = ChainNotConfiguredError & { + name: 'ChainNotConfiguredError' +} +export class ChainNotConfiguredError extends BaseError { + override name = 'ChainNotConfiguredError' + constructor() { + super('Chain not configured.') + } +} + +export type ConnectorAlreadyConnectedErrorType = + ConnectorAlreadyConnectedError & { + name: 'ConnectorAlreadyConnectedError' + } +export class ConnectorAlreadyConnectedError extends BaseError { + override name = 'ConnectorAlreadyConnectedError' + constructor() { + super('Connector already connected.') + } +} + +export type ConnectorNotConnectedErrorType = ConnectorNotConnectedError & { + name: 'ConnectorNotConnectedError' +} +export class ConnectorNotConnectedError extends BaseError { + override name = 'ConnectorNotConnectedError' + constructor() { + super('Connector not connected.') + } +} + +export type ConnectorNotFoundErrorType = ConnectorNotFoundError & { + name: 'ConnectorNotFoundError' +} +export class ConnectorNotFoundError extends BaseError { + override name = 'ConnectorNotFoundError' + constructor() { + super('Connector not found.') + } +} + +export type ConnectorAccountNotFoundErrorType = + ConnectorAccountNotFoundError & { + name: 'ConnectorAccountNotFoundError' + } +export class ConnectorAccountNotFoundError extends BaseError { + override name = 'ConnectorAccountNotFoundError' + constructor({ + address, + connector, + }: { + address: Address + connector: Connector + }) { + super(`Account "${address}" not found for connector "${connector.name}".`) + } +} + +export type ConnectorChainMismatchErrorType = ConnectorAccountNotFoundError & { + name: 'ConnectorChainMismatchError' +} +export class ConnectorChainMismatchError extends BaseError { + override name = 'ConnectorChainMismatchError' + constructor({ + connectionChainId, + connectorChainId, + }: { + connectionChainId: number + connectorChainId: number + }) { + super( + `The current chain of the connector (id: ${connectorChainId}) does not match the connection's chain (id: ${connectionChainId}).`, + { + metaMessages: [ + `Current Chain ID: ${connectorChainId}`, + `Expected Chain ID: ${connectionChainId}`, + ], + }, + ) + } +} + +export type ConnectorUnavailableReconnectingErrorType = + ConnectorUnavailableReconnectingError & { + name: 'ConnectorUnavailableReconnectingError' + } +export class ConnectorUnavailableReconnectingError extends BaseError { + override name = 'ConnectorUnavailableReconnectingError' + constructor({ connector }: { connector: { name: string } }) { + super(`Connector "${connector.name}" unavailable while reconnecting.`, { + details: [ + 'During the reconnection step, the only connector methods guaranteed to be available are: `id`, `name`, `type`, `uid`.', + 'All other methods are not guaranteed to be available until reconnection completes and connectors are fully restored.', + 'This error commonly occurs for connectors that asynchronously inject after reconnection has already started.', + ].join(' '), + }) + } +} diff --git a/wagmi-project/packages/core/src/errors/connector.test.ts b/wagmi-project/packages/core/src/errors/connector.test.ts new file mode 100644 index 0000000000..258ef834cd --- /dev/null +++ b/wagmi-project/packages/core/src/errors/connector.test.ts @@ -0,0 +1,24 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { + ProviderNotFoundError, + SwitchChainNotSupportedError, +} from './connector.js' + +test('constructors', () => { + expect(new ProviderNotFoundError()).toMatchInlineSnapshot(` + [ProviderNotFoundError: Provider not found. + + Version: @wagmi/core@x.y.z] + `) + expect( + new SwitchChainNotSupportedError({ + connector: config.connectors[0]!, + }), + ).toMatchInlineSnapshot(` + [SwitchChainNotSupportedError: "Mock Connector" does not support programmatic chain switching. + + Version: @wagmi/core@x.y.z] + `) +}) diff --git a/wagmi-project/packages/core/src/errors/connector.ts b/wagmi-project/packages/core/src/errors/connector.ts new file mode 100644 index 0000000000..c6c30ef1a5 --- /dev/null +++ b/wagmi-project/packages/core/src/errors/connector.ts @@ -0,0 +1,23 @@ +import type { Connector } from '../createConfig.js' +import { BaseError } from './base.js' + +export type ProviderNotFoundErrorType = ProviderNotFoundError & { + name: 'ProviderNotFoundError' +} +export class ProviderNotFoundError extends BaseError { + override name = 'ProviderNotFoundError' + constructor() { + super('Provider not found.') + } +} + +export type SwitchChainNotSupportedErrorType = SwitchChainNotSupportedError & { + name: 'SwitchChainNotSupportedError' +} +export class SwitchChainNotSupportedError extends BaseError { + override name = 'SwitchChainNotSupportedError' + + constructor({ connector }: { connector: Connector }) { + super(`"${connector.name}" does not support programmatic chain switching.`) + } +} diff --git a/wagmi-project/packages/core/src/experimental/actions/writeContracts.test.ts b/wagmi-project/packages/core/src/experimental/actions/writeContracts.test.ts new file mode 100644 index 0000000000..b74cd780ef --- /dev/null +++ b/wagmi-project/packages/core/src/experimental/actions/writeContracts.test.ts @@ -0,0 +1,99 @@ +import { abi, address, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { connect } from '../../actions/connect.js' +import { disconnect } from '../../actions/disconnect.js' +import { writeContracts } from './writeContracts.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + await expect( + writeContracts(config, { + contracts: [ + { + abi: abi.wagmiMintExample, + address: address.wagmiMintExample, + functionName: 'mint', + }, + { + abi: abi.wagmiMintExample, + address: address.wagmiMintExample, + functionName: 'mint', + }, + { + abi: abi.wagmiMintExample, + address: address.wagmiMintExample, + functionName: 'mint', + }, + ], + }), + ).resolves.toMatchInlineSnapshot( + ` + { + "id": "0x8913636bd97cf4bcc0a6343c730905a27ead0f7480ff82190072e916439eb212", + } + `, + ) + await disconnect(config, { connector }) +}) + +test('behavior: not connected', async () => { + await expect( + writeContracts(config, { + contracts: [ + { + abi: abi.wagmiMintExample, + address: address.wagmiMintExample, + functionName: 'mint', + }, + { + abi: abi.wagmiMintExample, + address: address.wagmiMintExample, + functionName: 'mint', + }, + { + abi: abi.wagmiMintExample, + address: address.wagmiMintExample, + functionName: 'mint', + }, + ], + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [ConnectorNotConnectedError: Connector not connected. + + Version: @wagmi/core@x.y.z] + `) +}) + +test('behavior: account does not exist on connector', async () => { + await connect(config, { connector }) + await expect( + writeContracts(config, { + account: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + contracts: [ + { + abi: abi.wagmiMintExample, + address: address.wagmiMintExample, + functionName: 'mint', + }, + { + abi: abi.wagmiMintExample, + address: address.wagmiMintExample, + functionName: 'mint', + }, + { + abi: abi.wagmiMintExample, + address: address.wagmiMintExample, + functionName: 'mint', + }, + ], + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [ConnectorAccountNotFoundError: Account "0xA0Cf798816D4b9b9866b5330EEa46a18382f251e" not found for connector "Mock Connector". + + Version: @wagmi/core@x.y.z] + `) + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/core/src/experimental/actions/writeContracts.ts b/wagmi-project/packages/core/src/experimental/actions/writeContracts.ts new file mode 100644 index 0000000000..06e6687592 --- /dev/null +++ b/wagmi-project/packages/core/src/experimental/actions/writeContracts.ts @@ -0,0 +1,78 @@ +import type { Account, Chain, ContractFunctionParameters } from 'viem' +import { + type WriteContractsErrorType as viem_WriteContractsErrorType, + type WriteContractsParameters as viem_WriteContractsParameters, + type WriteContractsReturnType as viem_WriteContractsReturnType, + writeContracts as viem_writeContracts, +} from 'viem/experimental' + +import { + type GetConnectorClientErrorType, + getConnectorClient, +} from '../../actions/getConnectorClient.js' +import type { Config } from '../../createConfig.js' +import type { BaseErrorType, ErrorType } from '../../errors/base.js' +import type { SelectChains } from '../../types/chain.js' +import type { + ChainIdParameter, + ConnectorParameter, +} from '../../types/properties.js' +import type { Compute } from '../../types/utils.js' + +export type WriteContractsParameters< + contracts extends readonly unknown[] = readonly ContractFunctionParameters[], + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + /// + chains extends readonly Chain[] = SelectChains, +> = { + [key in keyof chains]: Compute< + Omit< + viem_WriteContractsParameters< + contracts, + chains[key], + Account, + chains[key] + >, + 'chain' + > & + ChainIdParameter & + ConnectorParameter + > +}[number] + +export type WriteContractsReturnType = viem_WriteContractsReturnType + +export type WriteContractsErrorType = + // getConnectorClient() + | GetConnectorClientErrorType + // base + | BaseErrorType + | ErrorType + // viem + | viem_WriteContractsErrorType + +/** https://wagmi.sh/core/api/actions/writeContracts */ +export async function writeContracts< + const contracts extends readonly unknown[], + config extends Config, + chainId extends config['chains'][number]['id'], +>( + config: config, + parameters: WriteContractsParameters, +): Promise { + const { account, chainId, connector, ...rest } = parameters + + const client = await getConnectorClient(config, { + account, + chainId, + connector, + }) + + return viem_writeContracts(client, { + ...(rest as any), + ...(account ? { account } : {}), + chain: chainId ? { id: chainId } : undefined, + }) +} diff --git a/wagmi-project/packages/core/src/experimental/query/writeContracts.test.ts b/wagmi-project/packages/core/src/experimental/query/writeContracts.test.ts new file mode 100644 index 0000000000..5f4a1f28dd --- /dev/null +++ b/wagmi-project/packages/core/src/experimental/query/writeContracts.test.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { writeContractsMutationOptions } from './writeContracts.js' + +test('default', () => { + expect(writeContractsMutationOptions(config)).toMatchInlineSnapshot(` + { + "mutationFn": [Function], + "mutationKey": [ + "writeContracts", + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/experimental/query/writeContracts.ts b/wagmi-project/packages/core/src/experimental/query/writeContracts.ts new file mode 100644 index 0000000000..192a842ca0 --- /dev/null +++ b/wagmi-project/packages/core/src/experimental/query/writeContracts.ts @@ -0,0 +1,70 @@ +import type { MutateOptions, MutationOptions } from '@tanstack/query-core' + +import type { Config } from '../../createConfig.js' +import type { Compute } from '../../types/utils.js' +import { + type WriteContractsErrorType, + type WriteContractsParameters, + type WriteContractsReturnType, + writeContracts, +} from '../actions/writeContracts.js' + +export function writeContractsMutationOptions< + const contracts extends readonly unknown[], + config extends Config, +>(config: config) { + return { + mutationFn(variables) { + return writeContracts(config, variables as any) as any + }, + mutationKey: ['writeContracts'], + } as const satisfies MutationOptions< + WriteContractsData, + WriteContractsErrorType, + WriteContractsVariables + > +} + +export type WriteContractsData = Compute + +export type WriteContractsVariables< + contracts extends readonly unknown[], + config extends Config, + chainId extends config['chains'][number]['id'], +> = WriteContractsParameters + +export type WriteContractsMutate< + contracts extends readonly unknown[], + config extends Config, + context = unknown, +> = ( + variables: WriteContractsVariables, + options?: + | Compute< + MutateOptions< + WriteContractsData, + WriteContractsErrorType, + Compute>, + context + > + > + | undefined, +) => void + +export type WriteContractsMutateAsync< + contracts extends readonly unknown[], + config extends Config, + context = unknown, +> = ( + variables: WriteContractsVariables, + options?: + | Compute< + MutateOptions< + WriteContractsData, + WriteContractsErrorType, + Compute>, + context + > + > + | undefined, +) => Promise diff --git a/wagmi-project/packages/core/src/exports/actions.test.ts b/wagmi-project/packages/core/src/exports/actions.test.ts new file mode 100644 index 0000000000..eaaedba14f --- /dev/null +++ b/wagmi-project/packages/core/src/exports/actions.test.ts @@ -0,0 +1,86 @@ +import { expect, test } from 'vitest' + +import * as actions from './actions.js' + +test('exports', () => { + expect(Object.keys(actions)).toMatchInlineSnapshot(` + [ + "call", + "connect", + "deployContract", + "disconnect", + "estimateGas", + "estimateFeesPerGas", + "estimateMaxPriorityFeePerGas", + "getAccount", + "getBalance", + "fetchBalance", + "getBlock", + "getBlockNumber", + "fetchBlockNumber", + "getBlockTransactionCount", + "getBytecode", + "getCallsStatus", + "getCapabilities", + "getChainId", + "getChains", + "getClient", + "getConnections", + "getConnectors", + "getConnectorClient", + "getEnsAddress", + "fetchEnsAddress", + "getEnsAvatar", + "fetchEnsAvatar", + "getEnsName", + "fetchEnsName", + "getEnsResolver", + "fetchEnsResolver", + "getEnsText", + "getFeeHistory", + "getGasPrice", + "getProof", + "getPublicClient", + "getStorageAt", + "getToken", + "fetchToken", + "getTransaction", + "fetchTransaction", + "getTransactionConfirmations", + "getTransactionCount", + "getTransactionReceipt", + "getWalletClient", + "multicall", + "prepareTransactionRequest", + "readContract", + "readContracts", + "reconnect", + "sendCalls", + "sendTransaction", + "showCallsStatus", + "signMessage", + "signTypedData", + "simulateContract", + "switchAccount", + "switchChain", + "switchNetwork", + "verifyMessage", + "verifyTypedData", + "waitForCallsStatus", + "watchAccount", + "watchAsset", + "watchBlocks", + "watchBlockNumber", + "watchChainId", + "watchClient", + "watchConnections", + "watchConnectors", + "watchContractEvent", + "watchPendingTransactions", + "watchPublicClient", + "waitForTransactionReceipt", + "waitForTransaction", + "writeContract", + ] + `) +}) diff --git a/wagmi-project/packages/core/src/exports/actions.ts b/wagmi-project/packages/core/src/exports/actions.ts new file mode 100644 index 0000000000..d03c2adb76 --- /dev/null +++ b/wagmi-project/packages/core/src/exports/actions.ts @@ -0,0 +1,460 @@ +//////////////////////////////////////////////////////////////////////////////// +// Actions +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +export { + type CallErrorType, + type CallParameters, + type CallReturnType, + call, +} from '../actions/call.js' + +export { + type ConnectErrorType, + type ConnectParameters, + type ConnectReturnType, + connect, +} from '../actions/connect.js' + +export { + type DeployContractErrorType, + type DeployContractParameters, + type DeployContractReturnType, + deployContract, +} from '../actions/deployContract.js' + +export { + type DisconnectErrorType, + type DisconnectParameters, + type DisconnectReturnType, + disconnect, +} from '../actions/disconnect.js' + +export { + type EstimateGasErrorType, + type EstimateGasParameters, + type EstimateGasReturnType, + estimateGas, +} from '../actions/estimateGas.js' + +export { + type EstimateFeesPerGasErrorType, + type EstimateFeesPerGasParameters, + type EstimateFeesPerGasReturnType, + estimateFeesPerGas, +} from '../actions/estimateFeesPerGas.js' + +export { + type EstimateMaxPriorityFeePerGasErrorType, + type EstimateMaxPriorityFeePerGasParameters, + type EstimateMaxPriorityFeePerGasReturnType, + estimateMaxPriorityFeePerGas, +} from '../actions/estimateMaxPriorityFeePerGas.js' + +export { + type GetAccountReturnType, + getAccount, +} from '../actions/getAccount.js' + +export { + type GetBalanceParameters, + type GetBalanceReturnType, + type GetBalanceErrorType, + getBalance, + /** @deprecated use `getBalance` instead */ + getBalance as fetchBalance, +} from '../actions/getBalance.js' + +export { + type GetBlockErrorType, + type GetBlockParameters, + type GetBlockReturnType, + getBlock, +} from '../actions/getBlock.js' + +export { + type GetBlockNumberErrorType, + type GetBlockNumberParameters, + type GetBlockNumberReturnType, + getBlockNumber, + /** @deprecated use `getBlockNumber` instead */ + getBlockNumber as fetchBlockNumber, +} from '../actions/getBlockNumber.js' + +export { + type GetBlockTransactionCountErrorType, + type GetBlockTransactionCountParameters, + type GetBlockTransactionCountReturnType, + getBlockTransactionCount, +} from '../actions/getBlockTransactionCount.js' + +export { + type GetBytecodeErrorType, + type GetBytecodeParameters, + type GetBytecodeReturnType, + getBytecode, +} from '../actions/getBytecode.js' + +export { + type GetCallsStatusErrorType, + type GetCallsStatusParameters, + type GetCallsStatusReturnType, + getCallsStatus, +} from '../actions/getCallsStatus.js' + +export { + type GetCapabilitiesErrorType, + type GetCapabilitiesParameters, + type GetCapabilitiesReturnType, + getCapabilities, +} from '../actions/getCapabilities.js' + +export { + type GetChainIdReturnType, + getChainId, +} from '../actions/getChainId.js' + +export { + type GetChainsReturnType, + getChains, +} from '../actions/getChains.js' + +export { + type GetClientParameters, + type GetClientReturnType, + getClient, +} from '../actions/getClient.js' + +export { + type GetConnectionsReturnType, + getConnections, +} from '../actions/getConnections.js' + +export { + type GetConnectorsReturnType, + getConnectors, +} from '../actions/getConnectors.js' + +export { + type GetConnectorClientErrorType, + type GetConnectorClientParameters, + type GetConnectorClientReturnType, + getConnectorClient, +} from '../actions/getConnectorClient.js' + +export { + type GetEnsAddressErrorType, + type GetEnsAddressParameters, + type GetEnsAddressReturnType, + getEnsAddress, + /** @deprecated use `getEnsAddress` instead */ + getEnsAddress as fetchEnsAddress, +} from '../actions/getEnsAddress.js' + +export { + type GetEnsAvatarErrorType, + type GetEnsAvatarParameters, + type GetEnsAvatarReturnType, + getEnsAvatar, + /** @deprecated use `getEnsAvatar` instead */ + getEnsAvatar as fetchEnsAvatar, +} from '../actions/getEnsAvatar.js' + +export { + type GetEnsNameErrorType, + type GetEnsNameParameters, + type GetEnsNameReturnType, + getEnsName, + /** @deprecated */ + getEnsName as fetchEnsName, +} from '../actions/getEnsName.js' + +export { + type GetEnsResolverErrorType, + type GetEnsResolverParameters, + type GetEnsResolverReturnType, + getEnsResolver, + /** @deprecated use `getEnsResolver` instead */ + getEnsResolver as fetchEnsResolver, +} from '../actions/getEnsResolver.js' + +export { + type GetEnsTextErrorType, + type GetEnsTextParameters, + type GetEnsTextReturnType, + getEnsText, +} from '../actions/getEnsText.js' + +export { + type GetFeeHistoryErrorType, + type GetFeeHistoryParameters, + type GetFeeHistoryReturnType, + getFeeHistory, +} from '../actions/getFeeHistory.js' + +export { + type GetGasPriceErrorType, + type GetGasPriceParameters, + type GetGasPriceReturnType, + getGasPrice, +} from '../actions/getGasPrice.js' + +export { + type GetProofErrorType, + type GetProofParameters, + type GetProofReturnType, + getProof, +} from '../actions/getProof.js' + +export { + type GetPublicClientParameters, + type GetPublicClientReturnType, + getPublicClient, +} from '../actions/getPublicClient.js' + +export { + type GetStorageAtErrorType, + type GetStorageAtParameters, + type GetStorageAtReturnType, + getStorageAt, +} from '../actions/getStorageAt.js' + +export { + type GetTokenErrorType, + type GetTokenParameters, + type GetTokenReturnType, + getToken, + /** @deprecated use `getToken` instead */ + getToken as fetchToken, +} from '../actions/getToken.js' + +export { + type GetTransactionErrorType, + type GetTransactionParameters, + type GetTransactionReturnType, + getTransaction, + /** @deprecated use `getTransaction` instead */ + getTransaction as fetchTransaction, +} from '../actions/getTransaction.js' + +export { + type GetTransactionConfirmationsErrorType, + type GetTransactionConfirmationsParameters, + type GetTransactionConfirmationsReturnType, + getTransactionConfirmations, +} from '../actions/getTransactionConfirmations.js' + +export { + type GetTransactionCountErrorType, + type GetTransactionCountParameters, + type GetTransactionCountReturnType, + getTransactionCount, +} from '../actions/getTransactionCount.js' + +export { + type GetTransactionReceiptErrorType, + type GetTransactionReceiptParameters, + type GetTransactionReceiptReturnType, + getTransactionReceipt, +} from '../actions/getTransactionReceipt.js' + +export { + type GetWalletClientErrorType, + type GetWalletClientParameters, + type GetWalletClientReturnType, + getWalletClient, +} from '../actions/getWalletClient.js' + +export { + type MulticallParameters, + type MulticallReturnType, + multicall, +} from '../actions/multicall.js' + +export { + type PrepareTransactionRequestParameters, + type PrepareTransactionRequestReturnType, + type PrepareTransactionRequestErrorType, + prepareTransactionRequest, +} from '../actions/prepareTransactionRequest.js' + +export { + type ReadContractParameters, + type ReadContractReturnType, + type ReadContractErrorType, + readContract, +} from '../actions/readContract.js' + +export { + type ReadContractsParameters, + type ReadContractsReturnType, + type ReadContractsErrorType, + readContracts, +} from '../actions/readContracts.js' + +export { + type ReconnectErrorType, + type ReconnectParameters, + type ReconnectReturnType, + reconnect, +} from '../actions/reconnect.js' + +export { + type SendCallsErrorType, + type SendCallsParameters, + type SendCallsReturnType, + sendCalls, +} from '../actions/sendCalls.js' + +export { + type SendTransactionErrorType, + type SendTransactionParameters, + type SendTransactionReturnType, + sendTransaction, +} from '../actions/sendTransaction.js' + +export { + type ShowCallsStatusErrorType, + type ShowCallsStatusParameters, + type ShowCallsStatusReturnType, + showCallsStatus, +} from '../actions/showCallsStatus.js' + +export { + type SignMessageErrorType, + type SignMessageParameters, + type SignMessageReturnType, + signMessage, +} from '../actions/signMessage.js' + +export { + type SignTypedDataErrorType, + type SignTypedDataParameters, + type SignTypedDataReturnType, + signTypedData, +} from '../actions/signTypedData.js' + +export { + type SimulateContractErrorType, + type SimulateContractParameters, + type SimulateContractReturnType, + simulateContract, +} from '../actions/simulateContract.js' + +export { + type SwitchAccountErrorType, + type SwitchAccountParameters, + type SwitchAccountReturnType, + switchAccount, +} from '../actions/switchAccount.js' + +export { + type SwitchChainErrorType, + type SwitchChainParameters, + type SwitchChainReturnType, + switchChain, + /** @deprecated use `switchChain` instead */ + switchChain as switchNetwork, +} from '../actions/switchChain.js' + +export { + type VerifyMessageParameters, + type VerifyMessageReturnType, + verifyMessage, +} from '../actions/verifyMessage.js' + +export { + type VerifyTypedDataParameters, + type VerifyTypedDataReturnType, + verifyTypedData, +} from '../actions/verifyTypedData.js' + +export { + type WaitForCallsStatusErrorType, + type WaitForCallsStatusParameters, + type WaitForCallsStatusReturnType, + waitForCallsStatus, +} from '../actions/waitForCallsStatus.js' + +export { + type WatchAccountParameters, + type WatchAccountReturnType, + watchAccount, +} from '../actions/watchAccount.js' + +export { + type WatchAssetParameters, + type WatchAssetReturnType, + watchAsset, +} from '../actions/watchAsset.js' + +export { + type WatchBlocksParameters, + type WatchBlocksReturnType, + watchBlocks, +} from '../actions/watchBlocks.js' + +export { + type WatchBlockNumberParameters, + type WatchBlockNumberReturnType, + watchBlockNumber, +} from '../actions/watchBlockNumber.js' + +export { + type WatchChainIdParameters, + type WatchChainIdReturnType, + watchChainId, +} from '../actions/watchChainId.js' + +export { + type WatchClientParameters, + type WatchClientReturnType, + watchClient, +} from '../actions/watchClient.js' + +export { + type WatchConnectionsParameters, + type WatchConnectionsReturnType, + watchConnections, +} from '../actions/watchConnections.js' + +export { + type WatchConnectorsParameters, + type WatchConnectorsReturnType, + watchConnectors, +} from '../actions/watchConnectors.js' + +export { + type WatchContractEventParameters, + type WatchContractEventReturnType, + watchContractEvent, +} from '../actions/watchContractEvent.js' + +export { + type WatchPendingTransactionsParameters, + type WatchPendingTransactionsReturnType, + watchPendingTransactions, +} from '../actions/watchPendingTransactions.js' + +export { + type WatchPublicClientParameters, + type WatchPublicClientReturnType, + watchPublicClient, +} from '../actions/watchPublicClient.js' + +export { + type WaitForTransactionReceiptErrorType, + type WaitForTransactionReceiptParameters, + type WaitForTransactionReceiptReturnType, + waitForTransactionReceipt, + /** @deprecated use `waitForTransactionReceipt` instead */ + waitForTransactionReceipt as waitForTransaction, +} from '../actions/waitForTransactionReceipt.js' + +export { + type WriteContractErrorType, + type WriteContractParameters, + type WriteContractReturnType, + writeContract, +} from '../actions/writeContract.js' diff --git a/wagmi-project/packages/core/src/exports/chains.ts b/wagmi-project/packages/core/src/exports/chains.ts new file mode 100644 index 0000000000..1fca7f537f --- /dev/null +++ b/wagmi-project/packages/core/src/exports/chains.ts @@ -0,0 +1,7 @@ +//////////////////////////////////////////////////////////////////////////////// +// viem/chains +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +// biome-ignore lint/performance/noReExportAll: entrypoint module +export * from 'viem/chains' diff --git a/wagmi-project/packages/core/src/exports/codegen.test.ts b/wagmi-project/packages/core/src/exports/codegen.test.ts new file mode 100644 index 0000000000..c947b7d188 --- /dev/null +++ b/wagmi-project/packages/core/src/exports/codegen.test.ts @@ -0,0 +1,14 @@ +import { expect, test } from 'vitest' + +import * as codegen from './codegen.js' + +test('exports', () => { + expect(Object.keys(codegen)).toMatchInlineSnapshot(` + [ + "createSimulateContract", + "createReadContract", + "createWatchContractEvent", + "createWriteContract", + ] + `) +}) diff --git a/wagmi-project/packages/core/src/exports/codegen.ts b/wagmi-project/packages/core/src/exports/codegen.ts new file mode 100644 index 0000000000..bed8aa1cc7 --- /dev/null +++ b/wagmi-project/packages/core/src/exports/codegen.ts @@ -0,0 +1,24 @@ +// biome-ignore lint/performance/noBarrelFile: entrypoint module +export { + type CreateSimulateContractParameters, + type CreateSimulateContractReturnType, + createSimulateContract, +} from '../actions/codegen/createSimulateContract.js' + +export { + type CreateReadContractParameters, + type CreateReadContractReturnType, + createReadContract, +} from '../actions/codegen/createReadContract.js' + +export { + type CreateWatchContractEventParameters, + type CreateWatchContractEventReturnType, + createWatchContractEvent, +} from '../actions/codegen/createWatchContractEvent.js' + +export { + type CreateWriteContractParameters, + type CreateWriteContractReturnType, + createWriteContract, +} from '../actions/codegen/createWriteContract.js' diff --git a/wagmi-project/packages/core/src/exports/experimental.ts b/wagmi-project/packages/core/src/exports/experimental.ts new file mode 100644 index 0000000000..f74baa82cb --- /dev/null +++ b/wagmi-project/packages/core/src/exports/experimental.ts @@ -0,0 +1,158 @@ +//////////////////////////////////////////////////////////////////////////////// +// Actions +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +export { + /** @deprecated This is no longer experimental – use `import type { GetCallsStatusErrorType } from '@wagmi/core'` instead. */ + type GetCallsStatusErrorType, + /** @deprecated This is no longer experimental – use `import type { GetCallsStatusParameters } from '@wagmi/core'` instead. */ + type GetCallsStatusParameters, + /** @deprecated This is no longer experimental – use `import type { GetCallsStatusReturnType } from '@wagmi/core'` instead. */ + type GetCallsStatusReturnType, + /** @deprecated This is no longer experimental – use `import { getCallsStatus } from '@wagmi/core'` instead. */ + getCallsStatus, +} from '../actions/getCallsStatus.js' + +export { + /** @deprecated This is no longer experimental – use `import type { GetCapabilitiesErrorType } from '@wagmi/core'` instead. */ + type GetCapabilitiesErrorType, + /** @deprecated This is no longer experimental – use `import type { GetCapabilitiesParameters } from '@wagmi/core'` instead. */ + type GetCapabilitiesParameters, + /** @deprecated This is no longer experimental – use `import type { GetCapabilitiesReturnType } from '@wagmi/core'` instead. */ + type GetCapabilitiesReturnType, + /** @deprecated This is no longer experimental – use `import { getCapabilities } from '@wagmi/core'` instead. */ + getCapabilities, +} from '../actions/getCapabilities.js' + +export { + /** @deprecated This is no longer experimental – use `import type { SendCallsErrorType } from '@wagmi/core'` instead. */ + type SendCallsErrorType, + /** @deprecated This is no longer experimental – use `import type { SendCallsParameters } from '@wagmi/core'` instead. */ + type SendCallsParameters, + /** @deprecated This is no longer experimental – use `import type { SendCallsReturnType } from '@wagmi/core'` instead. */ + type SendCallsReturnType, + /** @deprecated This is no longer experimental – use `import { sendCalls } from '@wagmi/core'` instead. */ + sendCalls, +} from '../actions/sendCalls.js' + +export { + /** @deprecated This is no longer experimental – use `import type { ShowCallsStatusErrorType } from '@wagmi/core'` instead. */ + type ShowCallsStatusErrorType, + /** @deprecated This is no longer experimental – use `import type { ShowCallsStatusParameters } from '@wagmi/core'` instead. */ + type ShowCallsStatusParameters, + /** @deprecated This is no longer experimental – use `import type { ShowCallsStatusReturnType } from '@wagmi/core'` instead. */ + type ShowCallsStatusReturnType, + /** @deprecated This is no longer experimental – use `import { showCallsStatus } from '@wagmi/core'` instead. */ + showCallsStatus, +} from '../actions/showCallsStatus.js' + +export { + /** @deprecated This is no longer experimental – use `import type { WaitForCallsStatusErrorType } from '@wagmi/core'` instead. */ + type WaitForCallsStatusErrorType, + /** @deprecated This is no longer experimental – use `import type { WaitForCallsStatusParameters } from '@wagmi/core'` instead. */ + type WaitForCallsStatusParameters, + /** @deprecated This is no longer experimental – use `import type { WaitForCallsStatusReturnType } from '@wagmi/core'` instead. */ + type WaitForCallsStatusReturnType, + /** @deprecated This is no longer experimental – use `import { waitForCallsStatus } from '@wagmi/core'` instead. */ + waitForCallsStatus, +} from '../actions/waitForCallsStatus.js' + +export { + /** @deprecated Use `SendCallsErrorType` instead. */ + type WriteContractsErrorType, + /** @deprecated Use `SendCallsParameters` instead. */ + type WriteContractsParameters, + /** @deprecated Use `SendCallsReturnType` instead. */ + type WriteContractsReturnType, + /** @deprecated Use `sendCalls` instead. */ + writeContracts, +} from '../experimental/actions/writeContracts.js' + +//////////////////////////////////////////////////////////////////////////////// +// Tanstack Query +//////////////////////////////////////////////////////////////////////////////// + +export { + /** @deprecated This is no longer experimental – use `import type { GetCallsStatusData } from '@wagmi/core/query'` instead. */ + type GetCallsStatusData, + /** @deprecated This is no longer experimental – use `import type { GetCallsStatusOptions } from '@wagmi/core/query'` instead. */ + type GetCallsStatusOptions, + /** @deprecated This is no longer experimental – use `import type { GetCallsStatusQueryFnData } from '@wagmi/core/query'` instead. */ + type GetCallsStatusQueryFnData, + /** @deprecated This is no longer experimental – use `import type { GetCallsStatusQueryKey } from '@wagmi/core/query'` instead. */ + type GetCallsStatusQueryKey, + /** @deprecated This is no longer experimental – use `import { getCallsStatusQueryOptions } from '@wagmi/core/query'` instead. */ + getCallsStatusQueryOptions, + /** @deprecated This is no longer experimental – use `import { getCallsStatusQueryKey } from '@wagmi/core/query'` instead. */ + getCallsStatusQueryKey, +} from '../query/getCallsStatus.js' + +export { + /** @deprecated This is no longer experimental – use `import type { GetCapabilitiesData } from '@wagmi/core/query'` instead. */ + type GetCapabilitiesData, + /** @deprecated This is no longer experimental – use `import type { GetCapabilitiesOptions } from '@wagmi/core/query'` instead. */ + type GetCapabilitiesOptions, + /** @deprecated This is no longer experimental – use `import type { GetCapabilitiesQueryFnData } from '@wagmi/core/query'` instead. */ + type GetCapabilitiesQueryFnData, + /** @deprecated This is no longer experimental – use `import type { GetCapabilitiesQueryKey } from '@wagmi/core/query'` instead. */ + type GetCapabilitiesQueryKey, + /** @deprecated This is no longer experimental – use `import { getCapabilitiesQueryOptions } from '@wagmi/core/query'` instead. */ + getCapabilitiesQueryOptions, + /** @deprecated This is no longer experimental – use `import { getCapabilitiesQueryKey } from '@wagmi/core/query'` instead. */ + getCapabilitiesQueryKey, +} from '../query/getCapabilities.js' + +export { + /** @deprecated This is no longer experimental – use `import type { SendCallsData } from '@wagmi/core/query'` instead. */ + type SendCallsData, + /** @deprecated This is no longer experimental – use `import type { SendCallsMutate } from '@wagmi/core/query'` instead. */ + type SendCallsMutate, + /** @deprecated This is no longer experimental – use `import type { SendCallsMutateAsync } from '@wagmi/core/query'` instead. */ + type SendCallsMutateAsync, + /** @deprecated This is no longer experimental – use `import type { SendCallsVariables } from '@wagmi/core/query'` instead. */ + type SendCallsVariables, + /** @deprecated This is no longer experimental – use `import { sendCallsMutationOptions } from '@wagmi/core/query'` instead. */ + sendCallsMutationOptions, +} from '../query/sendCalls.js' + +export { + /** @deprecated This is no longer experimental – use `import type { ShowCallsStatusData } from '@wagmi/core/query'` instead. */ + type ShowCallsStatusData, + /** @deprecated This is no longer experimental – use `import type { ShowCallsStatusMutate } from '@wagmi/core/query'` instead. */ + type ShowCallsStatusMutate, + /** @deprecated This is no longer experimental – use `import type { ShowCallsStatusMutateAsync } from '@wagmi/core/query'` instead. */ + type ShowCallsStatusMutateAsync, + /** @deprecated This is no longer experimental – use `import type { ShowCallsStatusVariables } from '@wagmi/core/query'` instead. */ + type ShowCallsStatusVariables, + /** @deprecated This is no longer experimental – use `import { showCallsStatusMutationOptions } from '@wagmi/core/query'` instead. */ + showCallsStatusMutationOptions, +} from '../query/showCallsStatus.js' + +export { + /** @deprecated This is no longer experimental – use `import type { WaitForCallsStatusData } from '@wagmi/core/query'` instead. */ + type WaitForCallsStatusData, + /** @deprecated This is no longer experimental – use `import type { WaitForCallsStatusOptions } from '@wagmi/core/query'` instead. */ + type WaitForCallsStatusOptions, + /** @deprecated This is no longer experimental – use `import type { WaitForCallsStatusQueryFnData } from '@wagmi/core/query'` instead. */ + type WaitForCallsStatusQueryFnData, + /** @deprecated This is no longer experimental – use `import type { WaitForCallsStatusQueryKey } from '@wagmi/core/query'` instead. */ + type WaitForCallsStatusQueryKey, + /** @deprecated This is no longer experimental – use `import { waitForCallsStatusQueryKey } from '@wagmi/core/query'` instead. */ + waitForCallsStatusQueryKey, + /** @deprecated This is no longer experimental – use `import { waitForCallsStatusQueryOptions } from '@wagmi/core/query'` instead. */ + waitForCallsStatusQueryOptions, +} from '../query/waitForCallsStatus.js' + +export { + /** @deprecated Use `SendCallsData` instead. */ + type WriteContractsData, + /** @deprecated Use `SendCallsMutate` instead. */ + type WriteContractsMutate, + /** @deprecated Use `SendCallsMutateAsync` instead. */ + type WriteContractsMutateAsync, + /** @deprecated Use `SendCallsVariables` instead. */ + type WriteContractsVariables, + /** @deprecated Use `sendCallsMutationOptions` instead. */ + writeContractsMutationOptions, +} from '../experimental/query/writeContracts.js' diff --git a/wagmi-project/packages/core/src/exports/index.test.ts b/wagmi-project/packages/core/src/exports/index.test.ts new file mode 100644 index 0000000000..55f3885806 --- /dev/null +++ b/wagmi-project/packages/core/src/exports/index.test.ts @@ -0,0 +1,117 @@ +import { expect, test } from 'vitest' + +import * as core from './index.js' + +test('exports', () => { + expect(Object.keys(core)).toMatchInlineSnapshot(` + [ + "call", + "connect", + "deployContract", + "disconnect", + "estimateGas", + "estimateFeesPerGas", + "estimateMaxPriorityFeePerGas", + "getAccount", + "getBalance", + "fetchBalance", + "getBlock", + "getBlockNumber", + "fetchBlockNumber", + "getBlockTransactionCount", + "getBytecode", + "getCallsStatus", + "getCapabilities", + "getChainId", + "getChains", + "getClient", + "getConnections", + "getConnectors", + "getConnectorClient", + "getEnsAddress", + "fetchEnsAddress", + "getEnsAvatar", + "fetchEnsAvatar", + "getEnsName", + "fetchEnsName", + "getEnsResolver", + "fetchEnsResolver", + "getEnsText", + "getFeeHistory", + "getGasPrice", + "getProof", + "getPublicClient", + "getStorageAt", + "getToken", + "fetchToken", + "getTransaction", + "fetchTransaction", + "getTransactionConfirmations", + "getTransactionCount", + "getTransactionReceipt", + "getWalletClient", + "multicall", + "prepareTransactionRequest", + "readContract", + "readContracts", + "reconnect", + "sendCalls", + "sendTransaction", + "showCallsStatus", + "signMessage", + "signTypedData", + "simulateContract", + "switchAccount", + "switchChain", + "switchNetwork", + "verifyMessage", + "verifyTypedData", + "waitForCallsStatus", + "watchAccount", + "watchAsset", + "watchBlocks", + "watchBlockNumber", + "watchChainId", + "watchClient", + "watchConnections", + "watchConnectors", + "watchContractEvent", + "watchPendingTransactions", + "watchPublicClient", + "waitForTransactionReceipt", + "waitForTransaction", + "writeContract", + "createConnector", + "injected", + "mock", + "createConfig", + "createStorage", + "noopStorage", + "hydrate", + "BaseError", + "ChainNotConfiguredError", + "ConnectorNotConnectedError", + "ConnectorAlreadyConnectedError", + "ConnectorNotFoundError", + "ConnectorAccountNotFoundError", + "ConnectorChainMismatchError", + "ConnectorUnavailableReconnectingError", + "ProviderNotFoundError", + "SwitchChainNotSupportedError", + "custom", + "http", + "webSocket", + "unstable_connector", + "fallback", + "cookieStorage", + "cookieToInitialState", + "parseCookie", + "deepEqual", + "deserialize", + "extractRpcUrls", + "normalizeChainId", + "serialize", + "version", + ] + `) +}) diff --git a/wagmi-project/packages/core/src/exports/index.ts b/wagmi-project/packages/core/src/exports/index.ts new file mode 100644 index 0000000000..1e0e210ea2 --- /dev/null +++ b/wagmi-project/packages/core/src/exports/index.ts @@ -0,0 +1,594 @@ +//////////////////////////////////////////////////////////////////////////////// +// Actions +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +export { + type CallErrorType, + type CallParameters, + type CallReturnType, + call, +} from '../actions/call.js' + +export { + type ConnectErrorType, + type ConnectParameters, + type ConnectReturnType, + connect, +} from '../actions/connect.js' + +export { + type DeployContractErrorType, + type DeployContractParameters, + type DeployContractReturnType, + deployContract, +} from '../actions/deployContract.js' + +export { + type DisconnectErrorType, + type DisconnectParameters, + type DisconnectReturnType, + disconnect, +} from '../actions/disconnect.js' + +export { + type EstimateGasErrorType, + type EstimateGasParameters, + type EstimateGasReturnType, + estimateGas, +} from '../actions/estimateGas.js' + +export { + type EstimateFeesPerGasErrorType, + type EstimateFeesPerGasParameters, + type EstimateFeesPerGasReturnType, + estimateFeesPerGas, +} from '../actions/estimateFeesPerGas.js' + +export { + type EstimateMaxPriorityFeePerGasErrorType, + type EstimateMaxPriorityFeePerGasParameters, + type EstimateMaxPriorityFeePerGasReturnType, + estimateMaxPriorityFeePerGas, +} from '../actions/estimateMaxPriorityFeePerGas.js' + +export { + type GetAccountReturnType, + getAccount, +} from '../actions/getAccount.js' + +export { + type GetBalanceParameters, + type GetBalanceReturnType, + type GetBalanceErrorType, + getBalance, + /** @deprecated use `getBalance` instead */ + getBalance as fetchBalance, +} from '../actions/getBalance.js' + +export { + type GetBlockErrorType, + type GetBlockParameters, + type GetBlockReturnType, + getBlock, +} from '../actions/getBlock.js' + +export { + type GetBlockNumberErrorType, + type GetBlockNumberParameters, + type GetBlockNumberReturnType, + getBlockNumber, + /** @deprecated use `getBlockNumber` instead */ + getBlockNumber as fetchBlockNumber, +} from '../actions/getBlockNumber.js' + +export { + type GetBlockTransactionCountErrorType, + type GetBlockTransactionCountParameters, + type GetBlockTransactionCountReturnType, + getBlockTransactionCount, +} from '../actions/getBlockTransactionCount.js' + +export { + type GetBytecodeErrorType, + type GetBytecodeParameters, + type GetBytecodeReturnType, + getBytecode, +} from '../actions/getBytecode.js' + +export { + type GetCallsStatusErrorType, + type GetCallsStatusParameters, + type GetCallsStatusReturnType, + getCallsStatus, +} from '../actions/getCallsStatus.js' + +export { + type GetCapabilitiesErrorType, + type GetCapabilitiesParameters, + type GetCapabilitiesReturnType, + getCapabilities, +} from '../actions/getCapabilities.js' + +export { + type GetChainIdReturnType, + getChainId, +} from '../actions/getChainId.js' + +export { + type GetChainsReturnType, + getChains, +} from '../actions/getChains.js' + +export { + type GetClientParameters, + type GetClientReturnType, + getClient, +} from '../actions/getClient.js' + +export { + type GetConnectionsReturnType, + getConnections, +} from '../actions/getConnections.js' + +export { + type GetConnectorsReturnType, + getConnectors, +} from '../actions/getConnectors.js' + +export { + type GetConnectorClientErrorType, + type GetConnectorClientParameters, + type GetConnectorClientReturnType, + getConnectorClient, +} from '../actions/getConnectorClient.js' + +export { + type GetEnsAddressErrorType, + type GetEnsAddressParameters, + type GetEnsAddressReturnType, + getEnsAddress, + /** @deprecated use `getEnsAddress` instead */ + getEnsAddress as fetchEnsAddress, +} from '../actions/getEnsAddress.js' + +export { + type GetEnsAvatarErrorType, + type GetEnsAvatarParameters, + type GetEnsAvatarReturnType, + getEnsAvatar, + /** @deprecated use `getEnsAvatar` instead */ + getEnsAvatar as fetchEnsAvatar, +} from '../actions/getEnsAvatar.js' + +export { + type GetEnsNameErrorType, + type GetEnsNameParameters, + type GetEnsNameReturnType, + getEnsName, + /** @deprecated */ + getEnsName as fetchEnsName, +} from '../actions/getEnsName.js' + +export { + type GetEnsResolverErrorType, + type GetEnsResolverParameters, + type GetEnsResolverReturnType, + getEnsResolver, + /** @deprecated use `getEnsResolver` instead */ + getEnsResolver as fetchEnsResolver, +} from '../actions/getEnsResolver.js' + +export { + type GetEnsTextErrorType, + type GetEnsTextParameters, + type GetEnsTextReturnType, + getEnsText, +} from '../actions/getEnsText.js' + +export { + type GetFeeHistoryErrorType, + type GetFeeHistoryParameters, + type GetFeeHistoryReturnType, + getFeeHistory, +} from '../actions/getFeeHistory.js' + +export { + type GetGasPriceErrorType, + type GetGasPriceParameters, + type GetGasPriceReturnType, + getGasPrice, +} from '../actions/getGasPrice.js' + +export { + type GetProofErrorType, + type GetProofParameters, + type GetProofReturnType, + getProof, +} from '../actions/getProof.js' + +export { + type GetPublicClientParameters, + type GetPublicClientReturnType, + getPublicClient, +} from '../actions/getPublicClient.js' + +export { + type GetStorageAtErrorType, + type GetStorageAtParameters, + type GetStorageAtReturnType, + getStorageAt, +} from '../actions/getStorageAt.js' + +export { + type GetTokenErrorType, + type GetTokenParameters, + type GetTokenReturnType, + getToken, + /** @deprecated use `getToken` instead */ + getToken as fetchToken, +} from '../actions/getToken.js' + +export { + type GetTransactionErrorType, + type GetTransactionParameters, + type GetTransactionReturnType, + getTransaction, + /** @deprecated use `getTransaction` instead */ + getTransaction as fetchTransaction, +} from '../actions/getTransaction.js' + +export { + type GetTransactionConfirmationsErrorType, + type GetTransactionConfirmationsParameters, + type GetTransactionConfirmationsReturnType, + getTransactionConfirmations, +} from '../actions/getTransactionConfirmations.js' + +export { + type GetTransactionCountErrorType, + type GetTransactionCountParameters, + type GetTransactionCountReturnType, + getTransactionCount, +} from '../actions/getTransactionCount.js' + +export { + type GetTransactionReceiptErrorType, + type GetTransactionReceiptParameters, + type GetTransactionReceiptReturnType, + getTransactionReceipt, +} from '../actions/getTransactionReceipt.js' + +export { + type GetWalletClientErrorType, + type GetWalletClientParameters, + type GetWalletClientReturnType, + getWalletClient, +} from '../actions/getWalletClient.js' + +export { + type MulticallParameters, + type MulticallReturnType, + multicall, +} from '../actions/multicall.js' + +export { + type PrepareTransactionRequestErrorType, + type PrepareTransactionRequestParameters, + type PrepareTransactionRequestReturnType, + prepareTransactionRequest, +} from '../actions/prepareTransactionRequest.js' + +export { + type ReadContractParameters, + type ReadContractReturnType, + type ReadContractErrorType, + readContract, +} from '../actions/readContract.js' + +export { + type ReadContractsParameters, + type ReadContractsReturnType, + type ReadContractsErrorType, + readContracts, +} from '../actions/readContracts.js' + +export { + type ReconnectErrorType, + type ReconnectParameters, + type ReconnectReturnType, + reconnect, +} from '../actions/reconnect.js' + +export { + type SendCallsErrorType, + type SendCallsParameters, + type SendCallsReturnType, + sendCalls, +} from '../actions/sendCalls.js' + +export { + type SendTransactionErrorType, + type SendTransactionParameters, + type SendTransactionReturnType, + sendTransaction, +} from '../actions/sendTransaction.js' + +export { + type ShowCallsStatusErrorType, + type ShowCallsStatusParameters, + type ShowCallsStatusReturnType, + showCallsStatus, +} from '../actions/showCallsStatus.js' + +export { + type SignMessageErrorType, + type SignMessageParameters, + type SignMessageReturnType, + signMessage, +} from '../actions/signMessage.js' + +export { + type SignTypedDataErrorType, + type SignTypedDataParameters, + type SignTypedDataReturnType, + signTypedData, +} from '../actions/signTypedData.js' + +export { + type SimulateContractErrorType, + type SimulateContractParameters, + type SimulateContractReturnType, + simulateContract, +} from '../actions/simulateContract.js' + +export { + type SwitchAccountErrorType, + type SwitchAccountParameters, + type SwitchAccountReturnType, + switchAccount, +} from '../actions/switchAccount.js' + +export { + type SwitchChainErrorType, + type SwitchChainParameters, + type SwitchChainReturnType, + switchChain, + /** @deprecated use `switchChain` instead */ + switchChain as switchNetwork, +} from '../actions/switchChain.js' + +export { + type VerifyMessageErrorType, + type VerifyMessageParameters, + type VerifyMessageReturnType, + verifyMessage, +} from '../actions/verifyMessage.js' + +export { + type VerifyTypedDataErrorType, + type VerifyTypedDataParameters, + type VerifyTypedDataReturnType, + verifyTypedData, +} from '../actions/verifyTypedData.js' + +export { + type WaitForCallsStatusErrorType, + type WaitForCallsStatusParameters, + type WaitForCallsStatusReturnType, + waitForCallsStatus, +} from '../actions/waitForCallsStatus.js' + +export { + type WatchAccountParameters, + type WatchAccountReturnType, + watchAccount, +} from '../actions/watchAccount.js' + +export { + type WatchAssetParameters, + type WatchAssetErrorType, + type WatchAssetReturnType, + watchAsset, +} from '../actions/watchAsset.js' + +export { + type WatchBlocksParameters, + type WatchBlocksReturnType, + watchBlocks, +} from '../actions/watchBlocks.js' + +export { + type WatchBlockNumberParameters, + type WatchBlockNumberReturnType, + watchBlockNumber, +} from '../actions/watchBlockNumber.js' + +export { + type WatchChainIdParameters, + type WatchChainIdReturnType, + watchChainId, +} from '../actions/watchChainId.js' + +export { + type WatchClientParameters, + type WatchClientReturnType, + watchClient, +} from '../actions/watchClient.js' + +export { + type WatchConnectionsParameters, + type WatchConnectionsReturnType, + watchConnections, +} from '../actions/watchConnections.js' + +export { + type WatchConnectorsParameters, + type WatchConnectorsReturnType, + watchConnectors, +} from '../actions/watchConnectors.js' + +export { + type WatchContractEventParameters, + type WatchContractEventReturnType, + watchContractEvent, +} from '../actions/watchContractEvent.js' + +export { + type WatchPendingTransactionsParameters, + type WatchPendingTransactionsReturnType, + watchPendingTransactions, +} from '../actions/watchPendingTransactions.js' + +export { + type WatchPublicClientParameters, + type WatchPublicClientReturnType, + watchPublicClient, +} from '../actions/watchPublicClient.js' + +export { + type WaitForTransactionReceiptErrorType, + type WaitForTransactionReceiptParameters, + type WaitForTransactionReceiptReturnType, + waitForTransactionReceipt, + /** @deprecated use `waitForTransactionReceipt` instead */ + waitForTransactionReceipt as waitForTransaction, +} from '../actions/waitForTransactionReceipt.js' + +export { + type WriteContractErrorType, + type WriteContractParameters, + type WriteContractReturnType, + writeContract, +} from '../actions/writeContract.js' + +//////////////////////////////////////////////////////////////////////////////// +// Connectors +//////////////////////////////////////////////////////////////////////////////// + +export { + type ConnectorEventMap, + type CreateConnectorFn, + createConnector, +} from '../connectors/createConnector.js' + +export { + type InjectedParameters, + injected, +} from '../connectors/injected.js' + +export { + type MockParameters, + mock, +} from '../connectors/mock.js' + +//////////////////////////////////////////////////////////////////////////////// +// createConfig +//////////////////////////////////////////////////////////////////////////////// + +export { + type Connection, + type Connector, + type Config, + type CreateConfigParameters, + type PartializedState, + type State, + type Transport, + createConfig, +} from '../createConfig.js' + +//////////////////////////////////////////////////////////////////////////////// +// createStorage +//////////////////////////////////////////////////////////////////////////////// + +export { + type CreateStorageParameters, + type Storage, + type StorageItemMap, + createStorage, + noopStorage, +} from '../createStorage.js' + +//////////////////////////////////////////////////////////////////////////////// +// Hydrate +//////////////////////////////////////////////////////////////////////////////// + +export { hydrate } from '../hydrate.js' + +//////////////////////////////////////////////////////////////////////////////// +// Errors +//////////////////////////////////////////////////////////////////////////////// + +export { BaseError } from '../errors/base.js' + +export { + type ChainNotConfiguredErrorType, + ChainNotConfiguredError, + type ConnectorNotConnectedErrorType, + ConnectorNotConnectedError, + type ConnectorAlreadyConnectedErrorType, + ConnectorAlreadyConnectedError, + type ConnectorNotFoundErrorType, + ConnectorNotFoundError, + type ConnectorAccountNotFoundErrorType, + ConnectorAccountNotFoundError, + type ConnectorChainMismatchErrorType, + ConnectorChainMismatchError, + type ConnectorUnavailableReconnectingErrorType, + ConnectorUnavailableReconnectingError, +} from '../errors/config.js' + +export { + type ProviderNotFoundErrorType, + ProviderNotFoundError, + type SwitchChainNotSupportedErrorType, + SwitchChainNotSupportedError, +} from '../errors/connector.js' + +//////////////////////////////////////////////////////////////////////////////// +// Transports +//////////////////////////////////////////////////////////////////////////////// + +export { custom, http, webSocket } from 'viem' + +export { + type ConnectorTransportConfig, + type ConnectorTransport, + unstable_connector, +} from '../transports/connector.js' + +export { fallback } from '../transports/fallback.js' + +//////////////////////////////////////////////////////////////////////////////// +// Types +//////////////////////////////////////////////////////////////////////////////// + +export type { SelectChains } from '../types/chain.js' + +export type { Register, ResolvedRegister } from '../types/register.js' + +//////////////////////////////////////////////////////////////////////////////// +// Utilities +//////////////////////////////////////////////////////////////////////////////// + +export { + cookieStorage, + cookieToInitialState, + parseCookie, +} from '../utils/cookie.js' + +export { deepEqual } from '../utils/deepEqual.js' + +export { deserialize } from '../utils/deserialize.js' + +export { extractRpcUrls } from '../utils/extractRpcUrls.js' + +export { normalizeChainId } from '../utils/normalizeChainId.js' + +export { serialize } from '../utils/serialize.js' + +//////////////////////////////////////////////////////////////////////////////// +// Version +//////////////////////////////////////////////////////////////////////////////// + +export { version } from '../version.js' diff --git a/wagmi-project/packages/core/src/exports/internal.test.ts b/wagmi-project/packages/core/src/exports/internal.test.ts new file mode 100644 index 0000000000..425a1b4eba --- /dev/null +++ b/wagmi-project/packages/core/src/exports/internal.test.ts @@ -0,0 +1,15 @@ +import { expect, test } from 'vitest' + +import * as internal from './internal.js' + +test('exports', () => { + expect(Object.keys(internal)).toMatchInlineSnapshot(` + [ + "watchChains", + "Emitter", + "createEmitter", + "deepEqual", + "uid", + ] + `) +}) diff --git a/wagmi-project/packages/core/src/exports/internal.ts b/wagmi-project/packages/core/src/exports/internal.ts new file mode 100644 index 0000000000..670420d89a --- /dev/null +++ b/wagmi-project/packages/core/src/exports/internal.ts @@ -0,0 +1,52 @@ +//////////////////////////////////////////////////////////////////////////////// +// Actions +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +export { + type WatchChainsParameters, + type WatchChainsReturnType, + watchChains, +} from '../actions/watchChains.js' + +//////////////////////////////////////////////////////////////////////////////// +// Emitter +//////////////////////////////////////////////////////////////////////////////// + +export { + type EventData, + Emitter, + createEmitter, +} from '../createEmitter.js' + +//////////////////////////////////////////////////////////////////////////////// +// Types +//////////////////////////////////////////////////////////////////////////////// + +export type { SelectChains } from '../types/chain.js' + +export type { + ChainIdParameter, + ConnectorParameter, + ScopeKeyParameter, +} from '../types/properties.js' + +export type { + Compute, + ExactPartial, + Mutable, + StrictOmit as Omit, + OneOf, + RemoveUndefined, + UnionCompute, + UnionStrictOmit, + UnionExactPartial, +} from '../types/utils.js' + +//////////////////////////////////////////////////////////////////////////////// +// Utilities +//////////////////////////////////////////////////////////////////////////////// + +export { deepEqual } from '../utils/deepEqual.js' + +export { uid } from '../utils/uid.js' diff --git a/wagmi-project/packages/core/src/exports/query.test.ts b/wagmi-project/packages/core/src/exports/query.test.ts new file mode 100644 index 0000000000..cbdaf925de --- /dev/null +++ b/wagmi-project/packages/core/src/exports/query.test.ts @@ -0,0 +1,97 @@ +import { expect, test } from 'vitest' + +import * as query from './query.js' + +test('exports', () => { + expect(Object.keys(query)).toMatchInlineSnapshot(` + [ + "callQueryKey", + "callQueryOptions", + "connectMutationOptions", + "deployContractMutationOptions", + "disconnectMutationOptions", + "estimateFeesPerGasQueryKey", + "estimateFeesPerGasQueryOptions", + "estimateGasQueryKey", + "estimateGasQueryOptions", + "estimateMaxPriorityFeePerGasQueryKey", + "estimateMaxPriorityFeePerGasQueryOptions", + "getBalanceQueryKey", + "getBalanceQueryOptions", + "getBlockQueryKey", + "getBlockQueryOptions", + "getBlockNumberQueryKey", + "getBlockNumberQueryOptions", + "getBlockTransactionCountQueryKey", + "getBlockTransactionCountQueryOptions", + "getBytecodeQueryKey", + "getBytecodeQueryOptions", + "getCallsStatusQueryKey", + "getCallsStatusQueryOptions", + "getCapabilitiesQueryKey", + "getCapabilitiesQueryOptions", + "getConnectorClientQueryKey", + "getConnectorClientQueryOptions", + "getEnsAddressQueryKey", + "getEnsAddressQueryOptions", + "getEnsAvatarQueryKey", + "getEnsAvatarQueryOptions", + "getEnsNameQueryKey", + "getEnsNameQueryOptions", + "getEnsResolverQueryKey", + "getEnsResolverQueryOptions", + "getEnsTextQueryKey", + "getEnsTextQueryOptions", + "getFeeHistoryQueryKey", + "getFeeHistoryQueryOptions", + "getGasPriceQueryKey", + "getGasPriceQueryOptions", + "getProofQueryKey", + "getProofQueryOptions", + "getStorageAtQueryKey", + "getStorageAtQueryOptions", + "getTokenQueryKey", + "getTokenQueryOptions", + "getTransactionQueryKey", + "getTransactionQueryOptions", + "getTransactionConfirmationsQueryKey", + "getTransactionConfirmationsQueryOptions", + "getTransactionCountQueryKey", + "getTransactionCountQueryOptions", + "getTransactionReceiptQueryKey", + "getTransactionReceiptQueryOptions", + "getWalletClientQueryKey", + "getWalletClientQueryOptions", + "infiniteReadContractsQueryKey", + "infiniteReadContractsQueryOptions", + "prepareTransactionRequestQueryKey", + "prepareTransactionRequestQueryOptions", + "readContractQueryKey", + "readContractQueryOptions", + "readContractsQueryKey", + "readContractsQueryOptions", + "reconnectMutationOptions", + "sendCallsMutationOptions", + "showCallsStatusMutationOptions", + "sendTransactionMutationOptions", + "signMessageMutationOptions", + "signTypedDataMutationOptions", + "switchAccountMutationOptions", + "simulateContractQueryKey", + "simulateContractQueryOptions", + "switchChainMutationOptions", + "verifyMessageQueryKey", + "verifyMessageQueryOptions", + "verifyTypedDataQueryKey", + "verifyTypedDataQueryOptions", + "waitForCallsStatusQueryKey", + "waitForCallsStatusQueryOptions", + "waitForTransactionReceiptQueryKey", + "waitForTransactionReceiptQueryOptions", + "watchAssetMutationOptions", + "writeContractMutationOptions", + "hashFn", + "structuralSharing", + ] + `) +}) diff --git a/wagmi-project/packages/core/src/exports/query.ts b/wagmi-project/packages/core/src/exports/query.ts new file mode 100644 index 0000000000..d689f558d5 --- /dev/null +++ b/wagmi-project/packages/core/src/exports/query.ts @@ -0,0 +1,434 @@ +//////////////////////////////////////////////////////////////////////////////// +// Tanstack Query +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +export { + type CallData, + type CallOptions, + type CallQueryFnData, + type CallQueryKey, + callQueryKey, + callQueryOptions, +} from '../query/call.js' + +export { + type ConnectData, + type ConnectVariables, + type ConnectMutate, + type ConnectMutateAsync, + connectMutationOptions, +} from '../query/connect.js' + +export { + type DeployContractData, + type DeployContractVariables, + type DeployContractMutate, + type DeployContractMutateAsync, + deployContractMutationOptions, +} from '../query/deployContract.js' + +export { + type DisconnectData, + type DisconnectVariables, + type DisconnectMutate, + type DisconnectMutateAsync, + disconnectMutationOptions, +} from '../query/disconnect.js' + +export { + type EstimateFeesPerGasData, + type EstimateFeesPerGasOptions, + type EstimateFeesPerGasQueryFnData, + type EstimateFeesPerGasQueryKey, + estimateFeesPerGasQueryKey, + estimateFeesPerGasQueryOptions, +} from '../query/estimateFeesPerGas.js' + +export { + type EstimateGasData, + type EstimateGasOptions, + type EstimateGasQueryFnData, + type EstimateGasQueryKey, + estimateGasQueryKey, + estimateGasQueryOptions, +} from '../query/estimateGas.js' + +export { + type EstimateMaxPriorityFeePerGasData, + type EstimateMaxPriorityFeePerGasOptions, + type EstimateMaxPriorityFeePerGasQueryFnData, + type EstimateMaxPriorityFeePerGasQueryKey, + estimateMaxPriorityFeePerGasQueryKey, + estimateMaxPriorityFeePerGasQueryOptions, +} from '../query/estimateMaxPriorityFeePerGas.js' + +export { + type GetBalanceData, + type GetBalanceOptions, + type GetBalanceQueryFnData, + type GetBalanceQueryKey, + getBalanceQueryKey, + getBalanceQueryOptions, +} from '../query/getBalance.js' + +export { + type GetBlockData, + type GetBlockOptions, + type GetBlockQueryFnData, + type GetBlockQueryKey, + getBlockQueryKey, + getBlockQueryOptions, +} from '../query/getBlock.js' + +export { + type GetBlockNumberData, + type GetBlockNumberOptions, + type GetBlockNumberQueryFnData, + type GetBlockNumberQueryKey, + getBlockNumberQueryKey, + getBlockNumberQueryOptions, +} from '../query/getBlockNumber.js' + +export { + type GetBlockTransactionCountData, + type GetBlockTransactionCountOptions, + type GetBlockTransactionCountQueryFnData, + type GetBlockTransactionCountQueryKey, + getBlockTransactionCountQueryKey, + getBlockTransactionCountQueryOptions, +} from '../query/getBlockTransactionCount.js' + +export { + type GetBytecodeData, + type GetBytecodeOptions, + type GetBytecodeQueryFnData, + type GetBytecodeQueryKey, + getBytecodeQueryKey, + getBytecodeQueryOptions, +} from '../query/getBytecode.js' + +export { + type GetCallsStatusData, + type GetCallsStatusOptions, + type GetCallsStatusQueryFnData, + type GetCallsStatusQueryKey, + getCallsStatusQueryKey, + getCallsStatusQueryOptions, +} from '../query/getCallsStatus.js' + +export { + type GetCapabilitiesData, + type GetCapabilitiesOptions, + type GetCapabilitiesQueryFnData, + type GetCapabilitiesQueryKey, + getCapabilitiesQueryKey, + getCapabilitiesQueryOptions, +} from '../query/getCapabilities.js' + +export { + type GetConnectorClientData, + type GetConnectorClientOptions, + type GetConnectorClientQueryFnData, + type GetConnectorClientQueryKey, + getConnectorClientQueryKey, + getConnectorClientQueryOptions, +} from '../query/getConnectorClient.js' + +export { + type GetEnsAddressData, + type GetEnsAddressOptions, + type GetEnsAddressQueryFnData, + type GetEnsAddressQueryKey, + getEnsAddressQueryKey, + getEnsAddressQueryOptions, +} from '../query/getEnsAddress.js' + +export { + type GetEnsAvatarData, + type GetEnsAvatarOptions, + type GetEnsAvatarQueryFnData, + type GetEnsAvatarQueryKey, + getEnsAvatarQueryKey, + getEnsAvatarQueryOptions, +} from '../query/getEnsAvatar.js' + +export { + type GetEnsNameData, + type GetEnsNameOptions, + type GetEnsNameQueryFnData, + type GetEnsNameQueryKey, + getEnsNameQueryKey, + getEnsNameQueryOptions, +} from '../query/getEnsName.js' + +export { + type GetEnsResolverData, + type GetEnsResolverOptions, + type GetEnsResolverQueryFnData, + type GetEnsResolverQueryKey, + getEnsResolverQueryKey, + getEnsResolverQueryOptions, +} from '../query/getEnsResolver.js' + +export { + type GetEnsTextData, + type GetEnsTextOptions, + type GetEnsTextQueryFnData, + type GetEnsTextQueryKey, + getEnsTextQueryKey, + getEnsTextQueryOptions, +} from '../query/getEnsText.js' + +export { + type GetFeeHistoryData, + type GetFeeHistoryOptions, + type GetFeeHistoryQueryFnData, + type GetFeeHistoryQueryKey, + getFeeHistoryQueryKey, + getFeeHistoryQueryOptions, +} from '../query/getFeeHistory.js' + +export { + type GetGasPriceData, + type GetGasPriceOptions, + type GetGasPriceQueryFnData, + type GetGasPriceQueryKey, + getGasPriceQueryKey, + getGasPriceQueryOptions, +} from '../query/getGasPrice.js' + +export { + type GetProofData, + type GetProofOptions, + type GetProofQueryFnData, + type GetProofQueryKey, + getProofQueryKey, + getProofQueryOptions, +} from '../query/getProof.js' + +export { + type GetStorageAtData, + type GetStorageAtOptions, + type GetStorageAtQueryFnData, + type GetStorageAtQueryKey, + getStorageAtQueryKey, + getStorageAtQueryOptions, +} from '../query/getStorageAt.js' + +export { + type GetTokenData, + type GetTokenOptions, + type GetTokenQueryFnData, + type GetTokenQueryKey, + getTokenQueryKey, + getTokenQueryOptions, +} from '../query/getToken.js' + +export { + type GetTransactionData, + type GetTransactionOptions, + type GetTransactionQueryFnData, + type GetTransactionQueryKey, + getTransactionQueryKey, + getTransactionQueryOptions, +} from '../query/getTransaction.js' + +export { + type GetTransactionConfirmationsData, + type GetTransactionConfirmationsOptions, + type GetTransactionConfirmationsQueryFnData, + type GetTransactionConfirmationsQueryKey, + getTransactionConfirmationsQueryKey, + getTransactionConfirmationsQueryOptions, +} from '../query/getTransactionConfirmations.js' + +export { + type GetTransactionCountData, + type GetTransactionCountOptions, + type GetTransactionCountQueryFnData, + type GetTransactionCountQueryKey, + getTransactionCountQueryKey, + getTransactionCountQueryOptions, +} from '../query/getTransactionCount.js' + +export { + type GetTransactionReceiptData, + type GetTransactionReceiptOptions, + type GetTransactionReceiptQueryFnData, + type GetTransactionReceiptQueryKey, + getTransactionReceiptQueryKey, + getTransactionReceiptQueryOptions, +} from '../query/getTransactionReceipt.js' + +export { + type GetWalletClientData, + type GetWalletClientOptions, + type GetWalletClientQueryFnData, + type GetWalletClientQueryKey, + getWalletClientQueryKey, + getWalletClientQueryOptions, +} from '../query/getWalletClient.js' + +export { + type InfiniteReadContractsData, + type InfiniteReadContractsOptions, + type InfiniteReadContractsQueryFnData, + type InfiniteReadContractsQueryKey, + infiniteReadContractsQueryKey, + infiniteReadContractsQueryOptions, +} from '../query/infiniteReadContracts.js' + +export { + type PrepareTransactionRequestData, + type PrepareTransactionRequestOptions, + type PrepareTransactionRequestQueryFnData, + type PrepareTransactionRequestQueryKey, + prepareTransactionRequestQueryKey, + prepareTransactionRequestQueryOptions, +} from '../query/prepareTransactionRequest.js' + +export { + type ReadContractData, + type ReadContractOptions, + type ReadContractQueryFnData, + type ReadContractQueryKey, + readContractQueryKey, + readContractQueryOptions, +} from '../query/readContract.js' + +export { + type ReadContractsData, + type ReadContractsOptions, + type ReadContractsQueryFnData, + type ReadContractsQueryKey, + readContractsQueryKey, + readContractsQueryOptions, +} from '../query/readContracts.js' + +export { + type ReconnectData, + type ReconnectVariables, + type ReconnectMutate, + type ReconnectMutateAsync, + reconnectMutationOptions, +} from '../query/reconnect.js' + +export { + type SendCallsData, + type SendCallsVariables, + type SendCallsMutate, + type SendCallsMutateAsync, + sendCallsMutationOptions, +} from '../query/sendCalls.js' + +export { + type ShowCallsStatusData, + type ShowCallsStatusVariables, + type ShowCallsStatusMutate, + type ShowCallsStatusMutateAsync, + showCallsStatusMutationOptions, +} from '../query/showCallsStatus.js' + +export { + type SendTransactionData, + type SendTransactionVariables, + type SendTransactionMutate, + type SendTransactionMutateAsync, + sendTransactionMutationOptions, +} from '../query/sendTransaction.js' + +export { + type SignMessageData, + type SignMessageVariables, + type SignMessageMutate, + type SignMessageMutateAsync, + signMessageMutationOptions, +} from '../query/signMessage.js' + +export { + type SignTypedDataData, + type SignTypedDataVariables, + type SignTypedDataMutate, + type SignTypedDataMutateAsync, + signTypedDataMutationOptions, +} from '../query/signTypedData.js' + +export { + type SwitchAccountData, + type SwitchAccountVariables, + type SwitchAccountMutate, + type SwitchAccountMutateAsync, + switchAccountMutationOptions, +} from '../query/switchAccount.js' + +export { + type SimulateContractData, + type SimulateContractOptions, + type SimulateContractQueryFnData, + type SimulateContractQueryKey, + simulateContractQueryKey, + simulateContractQueryOptions, +} from '../query/simulateContract.js' + +export { + type SwitchChainData, + type SwitchChainVariables, + type SwitchChainMutate, + type SwitchChainMutateAsync, + switchChainMutationOptions, +} from '../query/switchChain.js' + +export { + type VerifyMessageData, + type VerifyMessageOptions, + type VerifyMessageQueryFnData, + type VerifyMessageQueryKey, + verifyMessageQueryKey, + verifyMessageQueryOptions, +} from '../query/verifyMessage.js' + +export { + type VerifyTypedDataData, + type VerifyTypedDataOptions, + type VerifyTypedDataQueryFnData, + type VerifyTypedDataQueryKey, + verifyTypedDataQueryKey, + verifyTypedDataQueryOptions, +} from '../query/verifyTypedData.js' + +export { + type WaitForCallsStatusData, + type WaitForCallsStatusOptions, + type WaitForCallsStatusQueryFnData, + type WaitForCallsStatusQueryKey, + waitForCallsStatusQueryKey, + waitForCallsStatusQueryOptions, +} from '../query/waitForCallsStatus.js' + +export { + type WaitForTransactionReceiptData, + type WaitForTransactionReceiptOptions, + type WaitForTransactionReceiptQueryFnData, + type WaitForTransactionReceiptQueryKey, + waitForTransactionReceiptQueryKey, + waitForTransactionReceiptQueryOptions, +} from '../query/waitForTransactionReceipt.js' + +export { + type WatchAssetData, + type WatchAssetVariables, + type WatchAssetMutate, + type WatchAssetMutateAsync, + watchAssetMutationOptions, +} from '../query/watchAsset.js' + +export { + type WriteContractData, + type WriteContractVariables, + type WriteContractMutate, + type WriteContractMutateAsync, + writeContractMutationOptions, +} from '../query/writeContract.js' + +export { hashFn, structuralSharing } from '../query/utils.js' diff --git a/wagmi-project/packages/core/src/hydrate.test.ts b/wagmi-project/packages/core/src/hydrate.test.ts new file mode 100644 index 0000000000..3dc6e28549 --- /dev/null +++ b/wagmi-project/packages/core/src/hydrate.test.ts @@ -0,0 +1,114 @@ +import { accounts, config, wait } from '@wagmi/test' +import type { EIP1193Provider } from 'mipd' +import { http } from 'viem' +import { mainnet } from 'viem/chains' +import { expect, test, vi } from 'vitest' + +import { createConnector } from './connectors/createConnector.js' +import { mock } from './connectors/mock.js' +import { createConfig } from './createConfig.js' +import { createStorage } from './createStorage.js' +import { hydrate } from './hydrate.js' +import { cookieStorage } from './utils/cookie.js' + +vi.mock(import('mipd'), async (importOriginal) => { + const mod = await importOriginal() + + let cache: typeof mod | undefined + if (!cache) + cache = { + ...mod, + createStore() { + const store = mod.createStore() + return { + ...store, + getProviders() { + const info = { + icon: 'data:image/svg+xml,', + uuid: crypto.randomUUID(), + } as const + const provider = '' as unknown as EIP1193Provider + return [ + { info: { ...info, name: 'Foo', rdns: 'com.foo' }, provider }, + { info: { ...info, name: 'Bar', rdns: 'com.bar' }, provider }, + { info: { ...info, name: 'Mock', rdns: 'com.mock' }, provider }, + ] + }, + } + }, + } + return cache +}) + +test('default', () => { + const { onMount } = hydrate(config, { + initialState: undefined, + reconnectOnMount: false, + }) + onMount() + + expect(onMount).toBeDefined() +}) + +test('initialState', () => { + const config = createConfig({ + chains: [mainnet], + transports: { [mainnet.id]: http() }, + ssr: true, + storage: createStorage({ storage: cookieStorage }), + }) + + const { onMount } = hydrate(config, { + initialState: { + chainId: 1, + current: null, + connections: new Map(), + status: 'disconnected', + }, + reconnectOnMount: true, + }) + onMount() + + expect(onMount).toBeDefined() +}) + +test('ssr', async () => { + const config = createConfig({ + chains: [mainnet], + connectors: [ + createConnector((c) => { + return { + ...mock({ accounts })(c), + rdns: 'com.mock', + } + }), + ], + ssr: true, + storage: createStorage({ storage: cookieStorage }), + transports: { [mainnet.id]: http() }, + }) + + const { onMount } = hydrate(config, { + initialState: { + chainId: 10, + current: null, + connections: new Map(), + status: 'disconnected', + }, + reconnectOnMount: false, + }) + onMount() + expect(onMount).toBeDefined() + expect(config.chains[0].id).toBe(1) + + await wait(100) + expect(config.connectors.map((x) => x.rdns ?? x.id)).toMatchInlineSnapshot( + ` + [ + "com.mock", + "com.foo", + "com.bar", + ] + `, + ) +}) diff --git a/wagmi-project/packages/core/src/hydrate.ts b/wagmi-project/packages/core/src/hydrate.ts new file mode 100644 index 0000000000..70bc2199e6 --- /dev/null +++ b/wagmi-project/packages/core/src/hydrate.ts @@ -0,0 +1,62 @@ +import { reconnect } from './actions/reconnect.js' +import type { Config, State } from './createConfig.js' + +type HydrateParameters = { + initialState?: State | undefined + reconnectOnMount?: boolean | undefined +} + +export function hydrate(config: Config, parameters: HydrateParameters) { + const { initialState, reconnectOnMount } = parameters + + if (initialState && !config._internal.store.persist.hasHydrated()) + config.setState({ + ...initialState, + chainId: config.chains.some((x) => x.id === initialState.chainId) + ? initialState.chainId + : config.chains[0].id, + connections: reconnectOnMount ? initialState.connections : new Map(), + status: reconnectOnMount ? 'reconnecting' : 'disconnected', + }) + + return { + async onMount() { + if (config._internal.ssr) { + await config._internal.store.persist.rehydrate() + if (config._internal.mipd) { + config._internal.connectors.setState((connectors) => { + const rdnsSet = new Set() + for (const connector of connectors ?? []) { + if (connector.rdns) { + const rdnsValues = Array.isArray(connector.rdns) + ? connector.rdns + : [connector.rdns] + for (const rdns of rdnsValues) { + rdnsSet.add(rdns) + } + } + } + const mipdConnectors = [] + const providers = config._internal.mipd?.getProviders() ?? [] + for (const provider of providers) { + if (rdnsSet.has(provider.info.rdns)) continue + const connectorFn = + config._internal.connectors.providerDetailToConnector(provider) + const connector = config._internal.connectors.setup(connectorFn) + mipdConnectors.push(connector) + } + return [...connectors, ...mipdConnectors] + }) + } + } + + if (reconnectOnMount) reconnect(config) + else if (config.storage) + // Reset connections that may have been hydrated from storage. + config.setState((x) => ({ + ...x, + connections: new Map(), + })) + }, + } +} diff --git a/wagmi-project/packages/core/src/query/call.test.ts b/wagmi-project/packages/core/src/query/call.test.ts new file mode 100644 index 0000000000..1e9ee03f7a --- /dev/null +++ b/wagmi-project/packages/core/src/query/call.test.ts @@ -0,0 +1,306 @@ +import { accounts, address, chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { parseEther, parseGwei } from 'viem' +import { callQueryOptions } from './call.js' + +const name4bytes = '0x06fdde03' +const account = accounts[0] + +test('default', () => { + expect( + callQueryOptions(config, { + account, + data: name4bytes, + to: address.wagmiMintExample, + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "call", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "data": "0x06fdde03", + "to": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + }, + ], + } + `) +}) + +test('parameters: accessList', () => { + expect( + callQueryOptions(config, { + account, + data: name4bytes, + to: address.wagmiMintExample, + accessList: [ + { + address: '0x1', + storageKeys: ['0x1'], + }, + ], + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "call", + { + "accessList": [ + { + "address": "0x1", + "storageKeys": [ + "0x1", + ], + }, + ], + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "data": "0x06fdde03", + "to": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + }, + ], + } + `) +}) + +test('parameters: blockNumber', () => { + expect( + callQueryOptions(config, { + account, + data: name4bytes, + to: address.wagmiMintExample, + blockNumber: 1234567890n, + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "call", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "blockNumber": 1234567890n, + "data": "0x06fdde03", + "to": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + }, + ], + } + `) +}) + +test('parameters: blockTag', () => { + expect( + callQueryOptions(config, { + account, + data: name4bytes, + to: address.wagmiMintExample, + blockTag: 'safe', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "call", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "blockTag": "safe", + "data": "0x06fdde03", + "to": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + }, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + callQueryOptions(config, { + account, + data: name4bytes, + to: address.wagmiMintExample, + chainId: chain.mainnet2.id, + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "call", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 456, + "data": "0x06fdde03", + "to": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + }, + ], + } + `) +}) + +test('parameters: gas', () => { + expect( + callQueryOptions(config, { + account, + data: name4bytes, + to: address.wagmiMintExample, + gas: 100000n, + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "call", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "data": "0x06fdde03", + "gas": 100000n, + "to": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + }, + ], + } + `) +}) + +test('parameters: gasPrice', () => { + expect( + callQueryOptions(config, { + account, + data: name4bytes, + to: address.wagmiMintExample, + gasPrice: parseGwei('20'), + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "call", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "data": "0x06fdde03", + "gasPrice": 20000000000n, + "to": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + }, + ], + } + `) +}) + +test('parameters: maxFeePerGas', () => { + expect( + callQueryOptions(config, { + account, + data: name4bytes, + to: address.wagmiMintExample, + maxFeePerGas: parseGwei('20'), + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "call", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "data": "0x06fdde03", + "maxFeePerGas": 20000000000n, + "to": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + }, + ], + } + `) +}) + +test('parameters: maxPriorityFeePerGas', () => { + expect( + callQueryOptions(config, { + account, + data: name4bytes, + to: address.wagmiMintExample, + maxPriorityFeePerGas: parseGwei('2'), + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "call", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "data": "0x06fdde03", + "maxPriorityFeePerGas": 2000000000n, + "to": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + }, + ], + } + `) +}) + +test('parameters: nonce', () => { + expect( + callQueryOptions(config, { + account, + data: name4bytes, + to: address.wagmiMintExample, + nonce: 123, + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "call", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "data": "0x06fdde03", + "nonce": 123, + "to": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + }, + ], + } + `) +}) + +test('parameters: type', () => { + expect( + callQueryOptions(config, { + account, + data: name4bytes, + to: address.wagmiMintExample, + type: 'eip1559', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "call", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "data": "0x06fdde03", + "to": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "type": "eip1559", + }, + ], + } + `) +}) + +test('parameters: value', () => { + expect( + callQueryOptions(config, { + account, + data: name4bytes, + to: address.wagmiMintExample, + value: parseEther('1'), + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "call", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "data": "0x06fdde03", + "to": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "value": 1000000000000000000n, + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/call.ts b/wagmi-project/packages/core/src/query/call.ts new file mode 100644 index 0000000000..2ca4491b86 --- /dev/null +++ b/wagmi-project/packages/core/src/query/call.ts @@ -0,0 +1,51 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type CallErrorType, + type CallParameters, + type CallReturnType, + call, +} from '../actions/call.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type CallOptions = Compute< + ExactPartial> & ScopeKeyParameter +> + +export function callQueryOptions( + config: config, + options: CallOptions = {}, +) { + return { + async queryFn({ queryKey }) { + const { scopeKey: _, ...parameters } = queryKey[1] + const data = await call(config, { + ...parameters, + } as CallParameters) + return data ?? null + }, + queryKey: callQueryKey(options), + } as const satisfies QueryOptions< + CallQueryFnData, + CallErrorType, + CallData, + CallQueryKey + > +} + +export type CallQueryFnData = CallReturnType + +export type CallData = CallQueryFnData + +export function callQueryKey( + options: CallOptions, +) { + return ['call', filterQueryOptions(options)] as const +} + +export type CallQueryKey = ReturnType< + typeof callQueryKey +> diff --git a/wagmi-project/packages/core/src/query/connect.test.ts b/wagmi-project/packages/core/src/query/connect.test.ts new file mode 100644 index 0000000000..b8300ee0ee --- /dev/null +++ b/wagmi-project/packages/core/src/query/connect.test.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { connectMutationOptions } from './connect.js' + +test('default', () => { + expect(connectMutationOptions(config)).toMatchInlineSnapshot(` + { + "mutationFn": [Function], + "mutationKey": [ + "connect", + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/connect.ts b/wagmi-project/packages/core/src/query/connect.ts new file mode 100644 index 0000000000..f521512789 --- /dev/null +++ b/wagmi-project/packages/core/src/query/connect.ts @@ -0,0 +1,70 @@ +import type { MutateOptions, MutationOptions } from '@tanstack/query-core' + +import { + type ConnectErrorType, + type ConnectParameters, + type ConnectReturnType, + connect, +} from '../actions/connect.js' +import type { Config, Connector } from '../createConfig.js' + +import type { CreateConnectorFn } from '../connectors/createConnector.js' +import type { Compute } from '../types/utils.js' + +export function connectMutationOptions(config: config) { + return { + mutationFn(variables) { + return connect(config, variables) + }, + mutationKey: ['connect'], + } as const satisfies MutationOptions< + ConnectData, + ConnectErrorType, + ConnectVariables + > +} + +export type ConnectData = ConnectReturnType + +export type ConnectVariables< + config extends Config, + connector extends Connector | CreateConnectorFn, +> = ConnectParameters + +export type ConnectMutate = < + connector extends + | config['connectors'][number] + | Connector + | CreateConnectorFn, +>( + variables: ConnectVariables, + options?: + | Compute< + MutateOptions< + ConnectData, + ConnectErrorType, + Compute>, + context + > + > + | undefined, +) => void + +export type ConnectMutateAsync = < + connector extends + | config['connectors'][number] + | Connector + | CreateConnectorFn, +>( + variables: ConnectVariables, + options?: + | Compute< + MutateOptions< + ConnectData, + ConnectErrorType, + Compute>, + context + > + > + | undefined, +) => Promise> diff --git a/wagmi-project/packages/core/src/query/deployContract.test.ts b/wagmi-project/packages/core/src/query/deployContract.test.ts new file mode 100644 index 0000000000..51157c03df --- /dev/null +++ b/wagmi-project/packages/core/src/query/deployContract.test.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { deployContractMutationOptions } from './deployContract.js' + +test('default', () => { + expect(deployContractMutationOptions(config)).toMatchInlineSnapshot(` + { + "mutationFn": [Function], + "mutationKey": [ + "deployContract", + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/deployContract.ts b/wagmi-project/packages/core/src/query/deployContract.ts new file mode 100644 index 0000000000..d4fac04531 --- /dev/null +++ b/wagmi-project/packages/core/src/query/deployContract.ts @@ -0,0 +1,73 @@ +import type { MutateOptions, MutationOptions } from '@tanstack/query-core' +import type { Abi, ContractConstructorArgs } from 'viem' + +import { + type DeployContractErrorType, + type DeployContractParameters, + type DeployContractReturnType, + deployContract, +} from '../actions/deployContract.js' +import type { Config } from '../createConfig.js' +import type { Compute } from '../types/utils.js' + +export function deployContractMutationOptions( + config: config, +) { + return { + mutationFn(variables) { + return deployContract(config, variables) + }, + mutationKey: ['deployContract'], + } as const satisfies MutationOptions< + DeployContractData, + DeployContractErrorType, + DeployContractVariables + > +} + +export type DeployContractData = Compute + +export type DeployContractVariables< + abi extends Abi | readonly unknown[], + config extends Config, + chainId extends config['chains'][number]['id'], + /// + allArgs = ContractConstructorArgs, +> = DeployContractParameters + +export type DeployContractMutate = < + abi extends Abi | readonly unknown[], + chainId extends config['chains'][number]['id'], +>( + variables: DeployContractVariables, + options?: + | Compute< + MutateOptions< + DeployContractData, + DeployContractErrorType, + Compute>, + context + > + > + | undefined, +) => void + +export type DeployContractMutateAsync< + config extends Config, + context = unknown, +> = < + abi extends Abi | readonly unknown[], + chainId extends config['chains'][number]['id'], +>( + variables: DeployContractVariables, + options?: + | Compute< + MutateOptions< + DeployContractData, + DeployContractErrorType, + Compute>, + context + > + > + | undefined, +) => Promise diff --git a/wagmi-project/packages/core/src/query/disconnect.test.ts b/wagmi-project/packages/core/src/query/disconnect.test.ts new file mode 100644 index 0000000000..4637c7e88f --- /dev/null +++ b/wagmi-project/packages/core/src/query/disconnect.test.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { disconnectMutationOptions } from './disconnect.js' + +test('default', () => { + expect(disconnectMutationOptions(config)).toMatchInlineSnapshot(` + { + "mutationFn": [Function], + "mutationKey": [ + "disconnect", + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/disconnect.ts b/wagmi-project/packages/core/src/query/disconnect.ts new file mode 100644 index 0000000000..018873da03 --- /dev/null +++ b/wagmi-project/packages/core/src/query/disconnect.ts @@ -0,0 +1,43 @@ +import type { MutationOptions } from '@tanstack/query-core' + +import { + type DisconnectErrorType, + type DisconnectParameters, + type DisconnectReturnType, + disconnect, +} from '../actions/disconnect.js' +import type { Config } from '../createConfig.js' +import type { Mutate, MutateAsync } from './types.js' + +export function disconnectMutationOptions( + config: config, +) { + return { + mutationFn(variables) { + return disconnect(config, variables) + }, + mutationKey: ['disconnect'], + } as const satisfies MutationOptions< + DisconnectData, + DisconnectErrorType, + DisconnectVariables + > +} + +export type DisconnectData = DisconnectReturnType + +export type DisconnectVariables = DisconnectParameters | undefined + +export type DisconnectMutate = Mutate< + DisconnectData, + DisconnectErrorType, + DisconnectVariables, + context +> + +export type DisconnectMutateAsync = MutateAsync< + DisconnectData, + DisconnectErrorType, + DisconnectVariables, + context +> diff --git a/wagmi-project/packages/core/src/query/estimateFeesPerGas.test.ts b/wagmi-project/packages/core/src/query/estimateFeesPerGas.test.ts new file mode 100644 index 0000000000..6b9965e651 --- /dev/null +++ b/wagmi-project/packages/core/src/query/estimateFeesPerGas.test.ts @@ -0,0 +1,32 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { estimateFeesPerGasQueryOptions } from './estimateFeesPerGas.js' + +test('default', () => { + expect(estimateFeesPerGasQueryOptions(config)).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "estimateFeesPerGas", + {}, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + estimateFeesPerGasQueryOptions(config, { chainId: chain.mainnet.id }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "estimateFeesPerGas", + { + "chainId": 1, + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/estimateFeesPerGas.ts b/wagmi-project/packages/core/src/query/estimateFeesPerGas.ts new file mode 100644 index 0000000000..7cf2f607c8 --- /dev/null +++ b/wagmi-project/packages/core/src/query/estimateFeesPerGas.ts @@ -0,0 +1,56 @@ +import type { QueryOptions } from '@tanstack/query-core' +import type { FeeValuesType } from 'viem' + +import { + type EstimateFeesPerGasErrorType, + type EstimateFeesPerGasParameters, + type EstimateFeesPerGasReturnType, + estimateFeesPerGas, +} from '../actions/estimateFeesPerGas.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type EstimateFeesPerGasOptions< + type extends FeeValuesType, + config extends Config, +> = Compute< + ExactPartial> & ScopeKeyParameter +> + +export function estimateFeesPerGasQueryOptions< + config extends Config, + type extends FeeValuesType = 'eip1559', +>(config: config, options: EstimateFeesPerGasOptions = {}) { + return { + async queryFn({ queryKey }) { + const { scopeKey: _, ...parameters } = queryKey[1] + return estimateFeesPerGas(config, parameters) + }, + queryKey: estimateFeesPerGasQueryKey(options), + } as const satisfies QueryOptions< + EstimateFeesPerGasQueryFnData, + EstimateFeesPerGasErrorType, + EstimateFeesPerGasData, + EstimateFeesPerGasQueryKey + > +} + +export type EstimateFeesPerGasQueryFnData = + EstimateFeesPerGasReturnType + +export type EstimateFeesPerGasData = + EstimateFeesPerGasQueryFnData + +export function estimateFeesPerGasQueryKey< + config extends Config, + type extends FeeValuesType = 'eip1559', +>(options: EstimateFeesPerGasOptions = {}) { + return ['estimateFeesPerGas', filterQueryOptions(options)] as const +} + +export type EstimateFeesPerGasQueryKey< + config extends Config, + type extends FeeValuesType, +> = ReturnType> diff --git a/wagmi-project/packages/core/src/query/estimateGas.test-d.ts b/wagmi-project/packages/core/src/query/estimateGas.test-d.ts new file mode 100644 index 0000000000..e48c4b089a --- /dev/null +++ b/wagmi-project/packages/core/src/query/estimateGas.test-d.ts @@ -0,0 +1,55 @@ +import { http, type Address, parseEther } from 'viem' +import { celo, mainnet } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { createConfig } from '../createConfig.js' +import { + type EstimateGasOptions, + estimateGasQueryOptions, +} from './estimateGas.js' + +test('chain formatters', () => { + const config = createConfig({ + chains: [mainnet, celo], + transports: { [celo.id]: http(), [mainnet.id]: http() }, + }) + + type Result = EstimateGasOptions< + typeof config, + (typeof config)['chains'][number]['id'] + > + expectTypeOf().toMatchTypeOf<{ + chainId?: typeof celo.id | typeof mainnet.id | undefined + feeCurrency?: `0x${string}` | undefined + }>() + estimateGasQueryOptions(config, { + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + feeCurrency: '0x', + }) + + type Result2 = EstimateGasOptions + expectTypeOf().toMatchTypeOf<{ + functionName?: 'approve' | 'transfer' | 'transferFrom' | undefined + args?: readonly [Address, Address, bigint] | undefined + feeCurrency?: `0x${string}` | undefined + }>() + estimateGasQueryOptions(config, { + chainId: celo.id, + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + feeCurrency: '0x', + }) + + type Result3 = EstimateGasOptions + expectTypeOf().not.toMatchTypeOf<{ + feeCurrency?: `0x${string}` | undefined + }>() + estimateGasQueryOptions(config, { + chainId: mainnet.id, + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + // @ts-expect-error + feeCurrency: '0x', + }) +}) diff --git a/wagmi-project/packages/core/src/query/estimateGas.test.ts b/wagmi-project/packages/core/src/query/estimateGas.test.ts new file mode 100644 index 0000000000..6c31cadbc1 --- /dev/null +++ b/wagmi-project/packages/core/src/query/estimateGas.test.ts @@ -0,0 +1,25 @@ +import { config } from '@wagmi/test' +import { parseEther } from 'viem' +import { expect, test } from 'vitest' + +import { estimateGasQueryOptions } from './estimateGas.js' + +test('default', () => { + expect( + estimateGasQueryOptions(config, { + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "estimateGas", + { + "to": "0xd2135CfB216b74109775236E36d4b433F1DF507B", + "value": 10000000000000000n, + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/estimateGas.ts b/wagmi-project/packages/core/src/query/estimateGas.ts new file mode 100644 index 0000000000..749002f92c --- /dev/null +++ b/wagmi-project/packages/core/src/query/estimateGas.ts @@ -0,0 +1,56 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type EstimateGasErrorType, + type EstimateGasParameters, + type EstimateGasReturnType, + estimateGas, +} from '../actions/estimateGas.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { UnionExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type EstimateGasOptions< + config extends Config, + chainId extends config['chains'][number]['id'] | undefined, +> = UnionExactPartial> & + ScopeKeyParameter + +export function estimateGasQueryOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +>(config: config, options: EstimateGasOptions = {} as any) { + return { + async queryFn({ queryKey }) { + const { connector } = options + const { account, scopeKey: _, ...parameters } = queryKey[1] + if (!account && !connector) + throw new Error('account or connector is required') + return estimateGas(config, { account, connector, ...(parameters as any) }) + }, + queryKey: estimateGasQueryKey(options), + } as const satisfies QueryOptions< + EstimateGasQueryFnData, + EstimateGasErrorType, + EstimateGasData, + EstimateGasQueryKey + > +} + +export type EstimateGasQueryFnData = EstimateGasReturnType + +export type EstimateGasData = EstimateGasQueryFnData + +export function estimateGasQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'] | undefined, +>(options: EstimateGasOptions = {} as any) { + const { connector: _, ...rest } = options + return ['estimateGas', filterQueryOptions(rest)] as const +} + +export type EstimateGasQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'] | undefined, +> = ReturnType> diff --git a/wagmi-project/packages/core/src/query/estimateMaxPriorityFeePerGas.test.ts b/wagmi-project/packages/core/src/query/estimateMaxPriorityFeePerGas.test.ts new file mode 100644 index 0000000000..38bcde076d --- /dev/null +++ b/wagmi-project/packages/core/src/query/estimateMaxPriorityFeePerGas.test.ts @@ -0,0 +1,36 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { estimateMaxPriorityFeePerGasQueryOptions } from './estimateMaxPriorityFeePerGas.js' + +test('default', () => { + expect( + estimateMaxPriorityFeePerGasQueryOptions(config), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "estimateMaxPriorityFeePerGas", + {}, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + estimateMaxPriorityFeePerGasQueryOptions(config, { + chainId: chain.mainnet.id, + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "estimateMaxPriorityFeePerGas", + { + "chainId": 1, + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/estimateMaxPriorityFeePerGas.ts b/wagmi-project/packages/core/src/query/estimateMaxPriorityFeePerGas.ts new file mode 100644 index 0000000000..cb58e65a79 --- /dev/null +++ b/wagmi-project/packages/core/src/query/estimateMaxPriorityFeePerGas.ts @@ -0,0 +1,51 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type EstimateMaxPriorityFeePerGasErrorType, + type EstimateMaxPriorityFeePerGasParameters, + type EstimateMaxPriorityFeePerGasReturnType, + estimateMaxPriorityFeePerGas, +} from '../actions/estimateMaxPriorityFeePerGas.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type EstimateMaxPriorityFeePerGasOptions = + Compute< + ExactPartial> & + ScopeKeyParameter + > + +export function estimateMaxPriorityFeePerGasQueryOptions( + config: config, + options: EstimateMaxPriorityFeePerGasOptions = {}, +) { + return { + async queryFn({ queryKey }) { + const { scopeKey: _, ...parameters } = queryKey[1] + return estimateMaxPriorityFeePerGas(config, parameters) + }, + queryKey: estimateMaxPriorityFeePerGasQueryKey(options), + } as const satisfies QueryOptions< + EstimateMaxPriorityFeePerGasQueryFnData, + EstimateMaxPriorityFeePerGasErrorType, + EstimateMaxPriorityFeePerGasData, + EstimateMaxPriorityFeePerGasQueryKey + > +} + +export type EstimateMaxPriorityFeePerGasQueryFnData = + EstimateMaxPriorityFeePerGasReturnType + +export type EstimateMaxPriorityFeePerGasData = + EstimateMaxPriorityFeePerGasQueryFnData + +export function estimateMaxPriorityFeePerGasQueryKey( + options: EstimateMaxPriorityFeePerGasOptions = {}, +) { + return ['estimateMaxPriorityFeePerGas', filterQueryOptions(options)] as const +} + +export type EstimateMaxPriorityFeePerGasQueryKey = + ReturnType> diff --git a/wagmi-project/packages/core/src/query/getBalance.test.ts b/wagmi-project/packages/core/src/query/getBalance.test.ts new file mode 100644 index 0000000000..1f9e1ecda9 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getBalance.test.ts @@ -0,0 +1,63 @@ +import { accounts, chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getBalanceQueryOptions } from './getBalance.js' + +const address = accounts[0] + +test('default', () => { + expect(getBalanceQueryOptions(config, { address })).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "balance", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + }, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getBalanceQueryOptions(config, { address, chainId: chain.mainnet.id }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "balance", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 1, + }, + ], + } + `) +}) + +test.todo('parameters: token') + +test('parameters: unit', () => { + expect( + getBalanceQueryOptions(config, { + address, + chainId: chain.mainnet.id, + token: '0x0000000000000000000000000000000000000000', + unit: 'gwei', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "balance", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 1, + "token": "0x0000000000000000000000000000000000000000", + "unit": "gwei", + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getBalance.ts b/wagmi-project/packages/core/src/query/getBalance.ts new file mode 100644 index 0000000000..e1dd287633 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getBalance.ts @@ -0,0 +1,53 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetBalanceErrorType, + type GetBalanceParameters, + type GetBalanceReturnType, + getBalance, +} from '../actions/getBalance.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, PartialBy } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetBalanceOptions = Compute< + PartialBy, 'address'> & ScopeKeyParameter +> + +export function getBalanceQueryOptions( + config: config, + options: GetBalanceOptions = {}, +) { + return { + async queryFn({ queryKey }) { + const { address, scopeKey: _, ...parameters } = queryKey[1] + if (!address) throw new Error('address is required') + const balance = await getBalance(config, { + ...(parameters as GetBalanceParameters), + address, + }) + return balance ?? null + }, + queryKey: getBalanceQueryKey(options), + } as const satisfies QueryOptions< + GetBalanceQueryFnData, + GetBalanceErrorType, + GetBalanceData, + GetBalanceQueryKey + > +} + +export type GetBalanceQueryFnData = Compute + +export type GetBalanceData = GetBalanceQueryFnData + +export function getBalanceQueryKey( + options: GetBalanceOptions = {}, +) { + return ['balance', filterQueryOptions(options)] as const +} + +export type GetBalanceQueryKey = ReturnType< + typeof getBalanceQueryKey +> diff --git a/wagmi-project/packages/core/src/query/getBlock.test.ts b/wagmi-project/packages/core/src/query/getBlock.test.ts new file mode 100644 index 0000000000..f31fb8c26e --- /dev/null +++ b/wagmi-project/packages/core/src/query/getBlock.test.ts @@ -0,0 +1,32 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getBlockQueryOptions } from './getBlock.js' + +test('default', () => { + expect(getBlockQueryOptions(config)).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "block", + {}, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getBlockQueryOptions(config, { chainId: chain.mainnet.id }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "block", + { + "chainId": 1, + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getBlock.ts b/wagmi-project/packages/core/src/query/getBlock.ts new file mode 100644 index 0000000000..f8f4db8417 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getBlock.ts @@ -0,0 +1,84 @@ +import type { QueryOptions } from '@tanstack/query-core' +import type { BlockTag } from 'viem' + +import { + type GetBlockErrorType, + type GetBlockParameters, + type GetBlockReturnType, + getBlock, +} from '../actions/getBlock.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetBlockOptions< + includeTransactions extends boolean, + blockTag extends BlockTag, + config extends Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = Compute< + ExactPartial< + GetBlockParameters + > & + ScopeKeyParameter +> + +export function getBlockQueryOptions< + config extends Config, + chainId extends config['chains'][number]['id'], + includeTransactions extends boolean, + blockTag extends BlockTag, +>( + config: config, + options: GetBlockOptions = {}, +) { + return { + async queryFn({ queryKey }) { + const { scopeKey: _, ...parameters } = queryKey[1] + const block = await getBlock(config, parameters) + return (block ?? null) as any + }, + queryKey: getBlockQueryKey(options), + } as const satisfies QueryOptions< + GetBlockQueryFnData, + GetBlockErrorType, + GetBlockData, + GetBlockQueryKey + > +} + +export type GetBlockQueryFnData< + includeTransactions extends boolean, + blockTag extends BlockTag, + config extends Config, + chainId extends config['chains'][number]['id'], +> = GetBlockReturnType + +export type GetBlockData< + includeTransactions extends boolean, + blockTag extends BlockTag, + config extends Config, + chainId extends config['chains'][number]['id'], +> = GetBlockQueryFnData + +export function getBlockQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], + includeTransactions extends boolean = false, + blockTag extends BlockTag = 'latest', +>( + options: GetBlockOptions = {}, +) { + return ['block', filterQueryOptions(options)] as const +} + +export type GetBlockQueryKey< + includeTransactions extends boolean, + blockTag extends BlockTag, + config extends Config, + chainId extends config['chains'][number]['id'], +> = ReturnType< + typeof getBlockQueryKey +> diff --git a/wagmi-project/packages/core/src/query/getBlockNumber.test.ts b/wagmi-project/packages/core/src/query/getBlockNumber.test.ts new file mode 100644 index 0000000000..b2ff0c2d14 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getBlockNumber.test.ts @@ -0,0 +1,34 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getBlockNumberQueryOptions } from './getBlockNumber.js' + +test('default', () => { + expect(getBlockNumberQueryOptions(config)).toMatchInlineSnapshot(` + { + "gcTime": 0, + "queryFn": [Function], + "queryKey": [ + "blockNumber", + {}, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getBlockNumberQueryOptions(config, { chainId: chain.mainnet.id }), + ).toMatchInlineSnapshot(` + { + "gcTime": 0, + "queryFn": [Function], + "queryKey": [ + "blockNumber", + { + "chainId": 1, + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getBlockNumber.ts b/wagmi-project/packages/core/src/query/getBlockNumber.ts new file mode 100644 index 0000000000..9585068a92 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getBlockNumber.ts @@ -0,0 +1,55 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetBlockNumberErrorType, + type GetBlockNumberParameters, + type GetBlockNumberReturnType, + getBlockNumber, +} from '../actions/getBlockNumber.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetBlockNumberOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +> = Compute< + ExactPartial> & ScopeKeyParameter +> + +export function getBlockNumberQueryOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +>(config: config, options: GetBlockNumberOptions = {}) { + return { + gcTime: 0, + async queryFn({ queryKey }) { + const { scopeKey: _, ...parameters } = queryKey[1] + const blockNumber = await getBlockNumber(config, parameters) + return blockNumber ?? null + }, + queryKey: getBlockNumberQueryKey(options), + } as const satisfies QueryOptions< + GetBlockNumberQueryFnData, + GetBlockNumberErrorType, + GetBlockNumberData, + GetBlockNumberQueryKey + > +} + +export type GetBlockNumberQueryFnData = GetBlockNumberReturnType + +export type GetBlockNumberData = GetBlockNumberQueryFnData + +export function getBlockNumberQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], +>(options: GetBlockNumberOptions = {}) { + return ['blockNumber', filterQueryOptions(options)] as const +} + +export type GetBlockNumberQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], +> = ReturnType> diff --git a/wagmi-project/packages/core/src/query/getBlockTransactionCount.test.ts b/wagmi-project/packages/core/src/query/getBlockTransactionCount.test.ts new file mode 100644 index 0000000000..d6c45ee09b --- /dev/null +++ b/wagmi-project/packages/core/src/query/getBlockTransactionCount.test.ts @@ -0,0 +1,50 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getBlockTransactionCountQueryOptions } from './getBlockTransactionCount.js' + +test('default', () => { + expect(getBlockTransactionCountQueryOptions(config)).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "blockTransactionCount", + {}, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getBlockTransactionCountQueryOptions(config, { chainId: chain.mainnet.id }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "blockTransactionCount", + { + "chainId": 1, + }, + ], + } + `) +}) + +test('parameters: blockTag', () => { + expect( + getBlockTransactionCountQueryOptions(config, { + blockTag: 'earliest', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "blockTransactionCount", + { + "blockTag": "earliest", + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getBlockTransactionCount.ts b/wagmi-project/packages/core/src/query/getBlockTransactionCount.ts new file mode 100644 index 0000000000..453e95e001 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getBlockTransactionCount.ts @@ -0,0 +1,62 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetBlockTransactionCountErrorType, + type GetBlockTransactionCountParameters, + type GetBlockTransactionCountReturnType, + getBlockTransactionCount, +} from '../actions/getBlockTransactionCount.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { ExactPartial, UnionCompute } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetBlockTransactionCountOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +> = UnionCompute< + ExactPartial> & + ScopeKeyParameter +> + +export function getBlockTransactionCountQueryOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +>( + config: config, + options: GetBlockTransactionCountOptions = {}, +) { + return { + async queryFn({ queryKey }) { + const { scopeKey: _, ...parameters } = queryKey[1] + const blockTransactionCount = await getBlockTransactionCount( + config, + parameters, + ) + return blockTransactionCount ?? null + }, + queryKey: getBlockTransactionCountQueryKey(options), + } as const satisfies QueryOptions< + GetBlockTransactionCountQueryFnData, + GetBlockTransactionCountErrorType, + GetBlockTransactionCountData, + GetBlockTransactionCountQueryKey + > +} + +export type GetBlockTransactionCountQueryFnData = + GetBlockTransactionCountReturnType + +export type GetBlockTransactionCountData = GetBlockTransactionCountQueryFnData + +export function getBlockTransactionCountQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], +>(options: GetBlockTransactionCountOptions = {}) { + return ['blockTransactionCount', filterQueryOptions(options)] as const +} + +export type GetBlockTransactionCountQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], +> = ReturnType> diff --git a/wagmi-project/packages/core/src/query/getBytecode.test.ts b/wagmi-project/packages/core/src/query/getBytecode.test.ts new file mode 100644 index 0000000000..83f22ebf2e --- /dev/null +++ b/wagmi-project/packages/core/src/query/getBytecode.test.ts @@ -0,0 +1,82 @@ +import { address, chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getBytecodeQueryOptions } from './getBytecode.js' + +test('default', () => { + expect( + getBytecodeQueryOptions(config, { + address: address.wagmiMintExample, + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "getBytecode", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + }, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getBytecodeQueryOptions(config, { + address: address.wagmiMintExample, + chainId: chain.mainnet2.id, + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "getBytecode", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "chainId": 456, + }, + ], + } + `) +}) + +test('parameters: blockNumber', () => { + expect( + getBytecodeQueryOptions(config, { + address: address.wagmiMintExample, + blockNumber: 1234567890n, + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "getBytecode", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "blockNumber": 1234567890n, + }, + ], + } + `) +}) + +test('parameters: blockTag', () => { + expect( + getBytecodeQueryOptions(config, { + address: address.wagmiMintExample, + blockTag: 'safe', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "getBytecode", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "blockTag": "safe", + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getBytecode.ts b/wagmi-project/packages/core/src/query/getBytecode.ts new file mode 100644 index 0000000000..7000c50eaa --- /dev/null +++ b/wagmi-project/packages/core/src/query/getBytecode.ts @@ -0,0 +1,49 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetBytecodeErrorType, + type GetBytecodeParameters, + type GetBytecodeReturnType, + getBytecode, +} from '../actions/getBytecode.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetBytecodeOptions = Compute< + ExactPartial> & ScopeKeyParameter +> + +export function getBytecodeQueryOptions( + config: config, + options: GetBytecodeOptions = {}, +) { + return { + async queryFn({ queryKey }) { + const { address, scopeKey: _, ...parameters } = queryKey[1] + if (!address) throw new Error('address is required') + const bytecode = await getBytecode(config, { ...parameters, address }) + return (bytecode ?? null) as any + }, + queryKey: getBytecodeQueryKey(options), + } as const satisfies QueryOptions< + GetBytecodeQueryFnData, + GetBytecodeErrorType, + GetBytecodeData, + GetBytecodeQueryKey + > +} +export type GetBytecodeQueryFnData = GetBytecodeReturnType + +export type GetBytecodeData = GetBytecodeQueryFnData + +export function getBytecodeQueryKey( + options: GetBytecodeOptions, +) { + return ['getBytecode', filterQueryOptions(options)] as const +} + +export type GetBytecodeQueryKey = ReturnType< + typeof getBytecodeQueryKey +> diff --git a/wagmi-project/packages/core/src/query/getCallsStatus.test.ts b/wagmi-project/packages/core/src/query/getCallsStatus.test.ts new file mode 100644 index 0000000000..fe834ecc79 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getCallsStatus.test.ts @@ -0,0 +1,23 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getCallsStatusQueryOptions } from './getCallsStatus.js' + +test('default', () => { + expect( + getCallsStatusQueryOptions(config, { + id: '0x0000000000000000000000000000000000000000', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "callsStatus", + { + "id": "0x0000000000000000000000000000000000000000", + }, + ], + "retry": [Function], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getCallsStatus.ts b/wagmi-project/packages/core/src/query/getCallsStatus.ts new file mode 100644 index 0000000000..869263eef0 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getCallsStatus.ts @@ -0,0 +1,50 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetCallsStatusErrorType, + type GetCallsStatusParameters, + type GetCallsStatusReturnType, + getCallsStatus, +} from '../actions/getCallsStatus.js' +import type { Config } from '../createConfig.js' +import { ConnectorNotConnectedError } from '../errors/config.js' +import { filterQueryOptions } from '../query/utils.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute } from '../types/utils.js' + +export type GetCallsStatusOptions = Compute< + GetCallsStatusParameters & ScopeKeyParameter +> + +export function getCallsStatusQueryOptions( + config: config, + options: GetCallsStatusOptions, +) { + return { + async queryFn({ queryKey }) { + const { scopeKey: _, ...parameters } = queryKey[1] + const status = await getCallsStatus(config, parameters) + return status + }, + queryKey: getCallsStatusQueryKey(options), + retry(failureCount, error) { + if (error instanceof ConnectorNotConnectedError) return false + return failureCount < 3 + }, + } as const satisfies QueryOptions< + GetCallsStatusQueryFnData, + GetCallsStatusErrorType, + GetCallsStatusData, + GetCallsStatusQueryKey + > +} + +export type GetCallsStatusQueryFnData = GetCallsStatusReturnType + +export type GetCallsStatusData = GetCallsStatusQueryFnData + +export function getCallsStatusQueryKey(options: GetCallsStatusOptions) { + return ['callsStatus', filterQueryOptions(options)] as const +} + +export type GetCallsStatusQueryKey = ReturnType diff --git a/wagmi-project/packages/core/src/query/getCapabilities.test.ts b/wagmi-project/packages/core/src/query/getCapabilities.test.ts new file mode 100644 index 0000000000..942eb37e04 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getCapabilities.test.ts @@ -0,0 +1,36 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getCapabilitiesQueryOptions } from './getCapabilities.js' + +test('default', () => { + expect(getCapabilitiesQueryOptions(config)).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "capabilities", + {}, + ], + "retry": [Function], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getCapabilitiesQueryOptions(config, { + account: '0x0000000000000000000000000000000000000000', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "capabilities", + { + "account": "0x0000000000000000000000000000000000000000", + }, + ], + "retry": [Function], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getCapabilities.ts b/wagmi-project/packages/core/src/query/getCapabilities.ts new file mode 100644 index 0000000000..754b77b551 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getCapabilities.ts @@ -0,0 +1,65 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetCapabilitiesErrorType, + type GetCapabilitiesParameters, + type GetCapabilitiesReturnType, + getCapabilities, +} from '../actions/getCapabilities.js' +import type { Config } from '../createConfig.js' +import { ConnectorNotConnectedError } from '../errors/config.js' +import { filterQueryOptions } from '../query/utils.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' + +export type GetCapabilitiesOptions< + config extends Config = Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, +> = Compute< + ExactPartial> & ScopeKeyParameter +> + +export function getCapabilitiesQueryOptions< + config extends Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, +>(config: config, options: GetCapabilitiesOptions = {}) { + return { + async queryFn({ queryKey }) { + const { scopeKey: _, ...parameters } = queryKey[1] + const capabilities = await getCapabilities(config, parameters) + return capabilities + }, + queryKey: getCapabilitiesQueryKey(options), + retry(failureCount, error) { + if (error instanceof ConnectorNotConnectedError) return false + return failureCount < 3 + }, + } as const satisfies QueryOptions< + GetCapabilitiesQueryFnData, + GetCapabilitiesErrorType, + GetCapabilitiesData, + GetCapabilitiesQueryKey + > +} + +export type GetCapabilitiesQueryFnData< + config extends Config = Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, +> = GetCapabilitiesReturnType + +export type GetCapabilitiesData< + config extends Config = Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, +> = GetCapabilitiesQueryFnData + +export function getCapabilitiesQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, +>(options: GetCapabilitiesOptions = {}) { + return ['capabilities', filterQueryOptions(options)] as const +} + +export type GetCapabilitiesQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, +> = ReturnType> diff --git a/wagmi-project/packages/core/src/query/getConnectorClient.test.ts b/wagmi-project/packages/core/src/query/getConnectorClient.test.ts new file mode 100644 index 0000000000..fdec57969d --- /dev/null +++ b/wagmi-project/packages/core/src/query/getConnectorClient.test.ts @@ -0,0 +1,37 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getConnectorClientQueryOptions } from './getConnectorClient.js' + +test('default', () => { + expect(getConnectorClientQueryOptions(config)).toMatchInlineSnapshot(` + { + "gcTime": 0, + "queryFn": [Function], + "queryKey": [ + "connectorClient", + { + "connectorUid": undefined, + }, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getConnectorClientQueryOptions(config, { chainId: chain.mainnet.id }), + ).toMatchInlineSnapshot(` + { + "gcTime": 0, + "queryFn": [Function], + "queryKey": [ + "connectorClient", + { + "chainId": 1, + "connectorUid": undefined, + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getConnectorClient.ts b/wagmi-project/packages/core/src/query/getConnectorClient.ts new file mode 100644 index 0000000000..7bc65029f0 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getConnectorClient.ts @@ -0,0 +1,69 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetConnectorClientErrorType, + type GetConnectorClientParameters, + type GetConnectorClientReturnType, + getConnectorClient, +} from '../actions/getConnectorClient.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetConnectorClientOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +> = Compute< + ExactPartial> & + ScopeKeyParameter +> + +export function getConnectorClientQueryOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +>(config: config, options: GetConnectorClientOptions = {}) { + return { + gcTime: 0, + async queryFn({ queryKey }) { + const { connector } = options + const { connectorUid: _, scopeKey: _s, ...parameters } = queryKey[1] + return getConnectorClient(config, { + ...parameters, + connector, + }) as unknown as Promise> + }, + queryKey: getConnectorClientQueryKey(options), + } as const satisfies QueryOptions< + GetConnectorClientQueryFnData, + GetConnectorClientErrorType, + GetConnectorClientData, + GetConnectorClientQueryKey + > +} + +export type GetConnectorClientQueryFnData< + config extends Config, + chainId extends config['chains'][number]['id'], +> = GetConnectorClientReturnType + +export type GetConnectorClientData< + config extends Config, + chainId extends config['chains'][number]['id'], +> = GetConnectorClientQueryFnData + +export function getConnectorClientQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], +>(options: GetConnectorClientOptions = {}) { + const { connector, ...parameters } = options + return [ + 'connectorClient', + { ...filterQueryOptions(parameters), connectorUid: connector?.uid }, + ] as const +} + +export type GetConnectorClientQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], +> = ReturnType> diff --git a/wagmi-project/packages/core/src/query/getEnsAddress.test.ts b/wagmi-project/packages/core/src/query/getEnsAddress.test.ts new file mode 100644 index 0000000000..0e88461e61 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getEnsAddress.test.ts @@ -0,0 +1,32 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getEnsAddressQueryOptions } from './getEnsAddress.js' + +test('default', () => { + expect(getEnsAddressQueryOptions(config)).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "ensAddress", + {}, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getEnsAddressQueryOptions(config, { chainId: chain.mainnet.id }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "ensAddress", + { + "chainId": 1, + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getEnsAddress.ts b/wagmi-project/packages/core/src/query/getEnsAddress.ts new file mode 100644 index 0000000000..7f18c9dd63 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getEnsAddress.ts @@ -0,0 +1,49 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetEnsAddressErrorType, + type GetEnsAddressParameters, + type GetEnsAddressReturnType, + getEnsAddress, +} from '../actions/getEnsAddress.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetEnsAddressOptions = Compute< + ExactPartial> & ScopeKeyParameter +> + +export function getEnsAddressQueryOptions( + config: config, + options: GetEnsAddressOptions = {}, +) { + return { + async queryFn({ queryKey }) { + const { name, scopeKey: _, ...parameters } = queryKey[1] + if (!name) throw new Error('name is required') + return getEnsAddress(config, { ...parameters, name }) + }, + queryKey: getEnsAddressQueryKey(options), + } as const satisfies QueryOptions< + GetEnsAddressQueryFnData, + GetEnsAddressErrorType, + GetEnsAddressData, + GetEnsAddressQueryKey + > +} + +export type GetEnsAddressQueryFnData = GetEnsAddressReturnType + +export type GetEnsAddressData = GetEnsAddressQueryFnData + +export function getEnsAddressQueryKey( + options: GetEnsAddressOptions = {}, +) { + return ['ensAddress', filterQueryOptions(options)] as const +} + +export type GetEnsAddressQueryKey = ReturnType< + typeof getEnsAddressQueryKey +> diff --git a/wagmi-project/packages/core/src/query/getEnsAvatar.test.ts b/wagmi-project/packages/core/src/query/getEnsAvatar.test.ts new file mode 100644 index 0000000000..8b62526426 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getEnsAvatar.test.ts @@ -0,0 +1,32 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getEnsAvatarQueryOptions } from './getEnsAvatar.js' + +test('default', () => { + expect(getEnsAvatarQueryOptions(config)).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "ensAvatar", + {}, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getEnsAvatarQueryOptions(config, { chainId: chain.mainnet.id }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "ensAvatar", + { + "chainId": 1, + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getEnsAvatar.ts b/wagmi-project/packages/core/src/query/getEnsAvatar.ts new file mode 100644 index 0000000000..f399736e08 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getEnsAvatar.ts @@ -0,0 +1,49 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetEnsAvatarErrorType, + type GetEnsAvatarParameters, + type GetEnsAvatarReturnType, + getEnsAvatar, +} from '../actions/getEnsAvatar.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetEnsAvatarOptions = Compute< + ExactPartial> & ScopeKeyParameter +> + +export function getEnsAvatarQueryOptions( + config: config, + options: GetEnsAvatarOptions = {}, +) { + return { + async queryFn({ queryKey }) { + const { name, scopeKey: _, ...parameters } = queryKey[1] + if (!name) throw new Error('name is required') + return getEnsAvatar(config, { ...parameters, name }) + }, + queryKey: getEnsAvatarQueryKey(options), + } as const satisfies QueryOptions< + GetEnsAvatarQueryFnData, + GetEnsAvatarErrorType, + GetEnsAvatarData, + GetEnsAvatarQueryKey + > +} + +export type GetEnsAvatarQueryFnData = GetEnsAvatarReturnType + +export type GetEnsAvatarData = GetEnsAvatarQueryFnData + +export function getEnsAvatarQueryKey( + options: GetEnsAvatarOptions = {}, +) { + return ['ensAvatar', filterQueryOptions(options)] as const +} + +export type GetEnsAvatarQueryKey = ReturnType< + typeof getEnsAvatarQueryKey +> diff --git a/wagmi-project/packages/core/src/query/getEnsName.test.ts b/wagmi-project/packages/core/src/query/getEnsName.test.ts new file mode 100644 index 0000000000..006c76a12d --- /dev/null +++ b/wagmi-project/packages/core/src/query/getEnsName.test.ts @@ -0,0 +1,32 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getEnsNameQueryOptions } from './getEnsName.js' + +test('default', () => { + expect(getEnsNameQueryOptions(config)).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "ensName", + {}, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getEnsNameQueryOptions(config, { chainId: chain.mainnet.id }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "ensName", + { + "chainId": 1, + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getEnsName.ts b/wagmi-project/packages/core/src/query/getEnsName.ts new file mode 100644 index 0000000000..cff1534e07 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getEnsName.ts @@ -0,0 +1,49 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetEnsNameErrorType, + type GetEnsNameParameters, + type GetEnsNameReturnType, + getEnsName, +} from '../actions/getEnsName.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetEnsNameOptions = Compute< + ExactPartial> & ScopeKeyParameter +> + +export function getEnsNameQueryOptions( + config: config, + options: GetEnsNameOptions = {}, +) { + return { + async queryFn({ queryKey }) { + const { address, scopeKey: _, ...parameters } = queryKey[1] + if (!address) throw new Error('address is required') + return getEnsName(config, { ...parameters, address }) + }, + queryKey: getEnsNameQueryKey(options), + } as const satisfies QueryOptions< + GetEnsNameQueryFnData, + GetEnsNameErrorType, + GetEnsNameData, + GetEnsNameQueryKey + > +} + +export type GetEnsNameQueryFnData = GetEnsNameReturnType + +export type GetEnsNameData = GetEnsNameQueryFnData + +export function getEnsNameQueryKey( + options: GetEnsNameOptions = {}, +) { + return ['ensName', filterQueryOptions(options)] as const +} + +export type GetEnsNameQueryKey = ReturnType< + typeof getEnsNameQueryKey +> diff --git a/wagmi-project/packages/core/src/query/getEnsResolver.test.ts b/wagmi-project/packages/core/src/query/getEnsResolver.test.ts new file mode 100644 index 0000000000..36baf9ba90 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getEnsResolver.test.ts @@ -0,0 +1,32 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getEnsResolverQueryOptions } from './getEnsResolver.js' + +test('default', () => { + expect(getEnsResolverQueryOptions(config)).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "ensResolver", + {}, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getEnsResolverQueryOptions(config, { chainId: chain.mainnet.id }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "ensResolver", + { + "chainId": 1, + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getEnsResolver.ts b/wagmi-project/packages/core/src/query/getEnsResolver.ts new file mode 100644 index 0000000000..124499325d --- /dev/null +++ b/wagmi-project/packages/core/src/query/getEnsResolver.ts @@ -0,0 +1,49 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetEnsResolverErrorType, + type GetEnsResolverParameters, + type GetEnsResolverReturnType, + getEnsResolver, +} from '../actions/getEnsResolver.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetEnsResolverOptions = Compute< + ExactPartial> & ScopeKeyParameter +> + +export function getEnsResolverQueryOptions( + config: config, + options: GetEnsResolverOptions = {}, +) { + return { + async queryFn({ queryKey }) { + const { name, scopeKey: _, ...parameters } = queryKey[1] + if (!name) throw new Error('name is required') + return getEnsResolver(config, { ...parameters, name }) + }, + queryKey: getEnsResolverQueryKey(options), + } as const satisfies QueryOptions< + GetEnsResolverQueryFnData, + GetEnsResolverErrorType, + GetEnsResolverData, + GetEnsResolverQueryKey + > +} + +export type GetEnsResolverQueryFnData = GetEnsResolverReturnType + +export type GetEnsResolverData = GetEnsResolverQueryFnData + +export function getEnsResolverQueryKey( + options: GetEnsResolverOptions = {}, +) { + return ['ensResolver', filterQueryOptions(options)] as const +} + +export type GetEnsResolverQueryKey = ReturnType< + typeof getEnsResolverQueryKey +> diff --git a/wagmi-project/packages/core/src/query/getEnsText.test.ts b/wagmi-project/packages/core/src/query/getEnsText.test.ts new file mode 100644 index 0000000000..1370410633 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getEnsText.test.ts @@ -0,0 +1,46 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getEnsTextQueryOptions } from './getEnsText.js' + +test('default', () => { + expect( + getEnsTextQueryOptions(config, { + name: 'wevm.eth', + key: 'com.twitter', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "ensText", + { + "key": "com.twitter", + "name": "wevm.eth", + }, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getEnsTextQueryOptions(config, { + chainId: chain.mainnet.id, + name: 'wevm.eth', + key: 'com.twitter', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "ensText", + { + "chainId": 1, + "key": "com.twitter", + "name": "wevm.eth", + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getEnsText.ts b/wagmi-project/packages/core/src/query/getEnsText.ts new file mode 100644 index 0000000000..2f1c464dea --- /dev/null +++ b/wagmi-project/packages/core/src/query/getEnsText.ts @@ -0,0 +1,49 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetEnsTextErrorType, + type GetEnsTextParameters, + type GetEnsTextReturnType, + getEnsText, +} from '../actions/getEnsText.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetEnsTextOptions = Compute< + ExactPartial> & ScopeKeyParameter +> + +export function getEnsTextQueryOptions( + config: config, + options: GetEnsTextOptions = {}, +) { + return { + async queryFn({ queryKey }) { + const { key, name, scopeKey: _, ...parameters } = queryKey[1] + if (!key || !name) throw new Error('key and name are required') + return getEnsText(config, { ...parameters, key, name }) + }, + queryKey: getEnsTextQueryKey(options), + } as const satisfies QueryOptions< + GetEnsTextQueryFnData, + GetEnsTextErrorType, + GetEnsTextData, + GetEnsTextQueryKey + > +} + +export type GetEnsTextQueryFnData = GetEnsTextReturnType + +export type GetEnsTextData = GetEnsTextQueryFnData + +export function getEnsTextQueryKey( + options: GetEnsTextOptions = {}, +) { + return ['ensText', filterQueryOptions(options)] as const +} + +export type GetEnsTextQueryKey = ReturnType< + typeof getEnsTextQueryKey +> diff --git a/wagmi-project/packages/core/src/query/getFeeHistory.test.ts b/wagmi-project/packages/core/src/query/getFeeHistory.test.ts new file mode 100644 index 0000000000..aa40793235 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getFeeHistory.test.ts @@ -0,0 +1,128 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getFeeHistoryQueryOptions } from './getFeeHistory.js' + +test('default', async () => { + expect( + getFeeHistoryQueryOptions(config, { + blockCount: 4, + rewardPercentiles: [25, 75], + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "feeHistory", + { + "blockCount": 4, + "rewardPercentiles": [ + 25, + 75, + ], + }, + ], + } + `) +}) + +test('parameters: chainId', async () => { + expect( + getFeeHistoryQueryOptions(config, { + blockCount: 4, + rewardPercentiles: [25, 75], + chainId: chain.mainnet2.id, + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "feeHistory", + { + "blockCount": 4, + "chainId": 456, + "rewardPercentiles": [ + 25, + 75, + ], + }, + ], + } + `) +}) + +test('parameters: blockNumber', async () => { + expect( + getFeeHistoryQueryOptions(config, { + blockCount: 4, + rewardPercentiles: [25, 75], + blockNumber: 18677379n, + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "feeHistory", + { + "blockCount": 4, + "blockNumber": 18677379n, + "rewardPercentiles": [ + 25, + 75, + ], + }, + ], + } + `) +}) + +test('parameters: blockTag', async () => { + expect( + getFeeHistoryQueryOptions(config, { + blockCount: 4, + rewardPercentiles: [25, 75], + blockTag: 'safe', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "feeHistory", + { + "blockCount": 4, + "blockTag": "safe", + "rewardPercentiles": [ + 25, + 75, + ], + }, + ], + } + `) +}) + +test('behavior: blockCount is required', async () => { + const options = getFeeHistoryQueryOptions(config, {}) + expect( + options.queryFn({ + queryKey: options.queryKey, + signal: new AbortSignal(), + meta: undefined, + }), + ).rejects.toThrowErrorMatchingInlineSnapshot( + '[Error: blockCount is required]', + ) +}) + +test('behavior: rewardPercentiles is required', async () => { + const options = getFeeHistoryQueryOptions(config, { blockCount: 4 }) + expect( + options.queryFn({ + queryKey: options.queryKey, + signal: new AbortSignal(), + meta: undefined, + }), + ).rejects.toThrowErrorMatchingInlineSnapshot( + '[Error: rewardPercentiles is required]', + ) +}) diff --git a/wagmi-project/packages/core/src/query/getFeeHistory.ts b/wagmi-project/packages/core/src/query/getFeeHistory.ts new file mode 100644 index 0000000000..6eeef0d681 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getFeeHistory.ts @@ -0,0 +1,69 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetFeeHistoryErrorType, + type GetFeeHistoryParameters, + type GetFeeHistoryReturnType, + getFeeHistory, +} from '../actions/getFeeHistory.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, PartialBy } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetFeeHistoryOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +> = Compute< + PartialBy< + GetFeeHistoryParameters, + 'blockCount' | 'rewardPercentiles' + > & + ScopeKeyParameter +> + +export function getFeeHistoryQueryOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +>(config: config, options: GetFeeHistoryOptions = {}) { + return { + async queryFn({ queryKey }) { + const { + blockCount, + rewardPercentiles, + scopeKey: _, + ...parameters + } = queryKey[1] + if (!blockCount) throw new Error('blockCount is required') + if (!rewardPercentiles) throw new Error('rewardPercentiles is required') + const feeHistory = await getFeeHistory(config, { + ...(parameters as GetFeeHistoryParameters), + blockCount, + rewardPercentiles, + }) + return feeHistory ?? null + }, + queryKey: getFeeHistoryQueryKey(options), + } as const satisfies QueryOptions< + GetFeeHistoryQueryFnData, + GetFeeHistoryErrorType, + GetFeeHistoryData, + GetFeeHistoryQueryKey + > +} + +export type GetFeeHistoryQueryFnData = GetFeeHistoryReturnType + +export type GetFeeHistoryData = GetFeeHistoryQueryFnData + +export function getFeeHistoryQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], +>(options: GetFeeHistoryOptions = {}) { + return ['feeHistory', filterQueryOptions(options)] as const +} + +export type GetFeeHistoryQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], +> = ReturnType> diff --git a/wagmi-project/packages/core/src/query/getGasPrice.test.ts b/wagmi-project/packages/core/src/query/getGasPrice.test.ts new file mode 100644 index 0000000000..2b90303669 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getGasPrice.test.ts @@ -0,0 +1,32 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getGasPriceQueryOptions } from './getGasPrice.js' + +test('default', () => { + expect(getGasPriceQueryOptions(config)).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "gasPrice", + {}, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getGasPriceQueryOptions(config, { chainId: chain.mainnet.id }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "gasPrice", + { + "chainId": 1, + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getGasPrice.ts b/wagmi-project/packages/core/src/query/getGasPrice.ts new file mode 100644 index 0000000000..153d4a102d --- /dev/null +++ b/wagmi-project/packages/core/src/query/getGasPrice.ts @@ -0,0 +1,54 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetGasPriceErrorType, + type GetGasPriceParameters, + type GetGasPriceReturnType, + getGasPrice, +} from '../actions/getGasPrice.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetGasPriceOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +> = Compute< + ExactPartial> & ScopeKeyParameter +> + +export function getGasPriceQueryOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +>(config: config, options: GetGasPriceOptions = {}) { + return { + async queryFn({ queryKey }) { + const { scopeKey: _, ...parameters } = queryKey[1] + const gasPrice = await getGasPrice(config, parameters) + return gasPrice ?? null + }, + queryKey: getGasPriceQueryKey(options), + } as const satisfies QueryOptions< + GetGasPriceQueryFnData, + GetGasPriceErrorType, + GetGasPriceData, + GetGasPriceQueryKey + > +} + +export type GetGasPriceQueryFnData = GetGasPriceReturnType + +export type GetGasPriceData = GetGasPriceQueryFnData + +export function getGasPriceQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], +>(options: GetGasPriceOptions = {}) { + return ['gasPrice', filterQueryOptions(options)] as const +} + +export type GetGasPriceQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], +> = ReturnType> diff --git a/wagmi-project/packages/core/src/query/getProof.test.ts b/wagmi-project/packages/core/src/query/getProof.test.ts new file mode 100644 index 0000000000..30c02256c7 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getProof.test.ts @@ -0,0 +1,106 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getProofQueryOptions } from './getProof.js' + +test('default', () => { + expect( + getProofQueryOptions(config, { + address: '0x4200000000000000000000000000000000000016', + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "getProof", + { + "address": "0x4200000000000000000000000000000000000016", + "storageKeys": [ + "0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99", + ], + }, + ], + } + `) +}) + +test('parameters: blockNumber', () => { + expect( + getProofQueryOptions(config, { + address: '0x4200000000000000000000000000000000000016', + blockNumber: 1234567890n, + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "getProof", + { + "address": "0x4200000000000000000000000000000000000016", + "blockNumber": 1234567890n, + "storageKeys": [ + "0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99", + ], + }, + ], + } + `) +}) + +test('parameters: blockTag', () => { + expect( + getProofQueryOptions(config, { + address: '0x4200000000000000000000000000000000000016', + blockTag: 'safe', + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "getProof", + { + "address": "0x4200000000000000000000000000000000000016", + "blockTag": "safe", + "storageKeys": [ + "0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99", + ], + }, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getProofQueryOptions(config, { + address: '0x4200000000000000000000000000000000000016', + chainId: chain.mainnet2.id, + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "getProof", + { + "address": "0x4200000000000000000000000000000000000016", + "chainId": 456, + "storageKeys": [ + "0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99", + ], + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getProof.ts b/wagmi-project/packages/core/src/query/getProof.ts new file mode 100644 index 0000000000..8da0b42b17 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getProof.ts @@ -0,0 +1,50 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetProofErrorType, + type GetProofParameters, + type GetProofReturnType, + getProof, +} from '../actions/getProof.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetProofOptions = Compute< + ExactPartial> & ScopeKeyParameter +> + +export function getProofQueryOptions( + config: config, + options: GetProofOptions = {}, +) { + return { + async queryFn({ queryKey }) { + const { address, scopeKey: _, storageKeys, ...parameters } = queryKey[1] + if (!address || !storageKeys) + throw new Error('address and storageKeys are required') + return getProof(config, { ...parameters, address, storageKeys }) + }, + queryKey: getProofQueryKey(options), + } as const satisfies QueryOptions< + GetProofQueryFnData, + GetProofErrorType, + GetProofData, + GetProofQueryKey + > +} + +export type GetProofQueryFnData = GetProofReturnType + +export type GetProofData = GetProofQueryFnData + +export function getProofQueryKey( + options: GetProofOptions, +) { + return ['getProof', filterQueryOptions(options)] as const +} + +export type GetProofQueryKey = ReturnType< + typeof getProofQueryKey +> diff --git a/wagmi-project/packages/core/src/query/getStorageAt.test.ts b/wagmi-project/packages/core/src/query/getStorageAt.test.ts new file mode 100644 index 0000000000..87193c1e6f --- /dev/null +++ b/wagmi-project/packages/core/src/query/getStorageAt.test.ts @@ -0,0 +1,90 @@ +import { address, chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getStorageAtQueryOptions } from './getStorageAt.js' + +test('default', () => { + expect( + getStorageAtQueryOptions(config, { + address: address.wagmiMintExample, + slot: '0x0', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "getStorageAt", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "slot": "0x0", + }, + ], + } + `) +}) + +test('parameters: blockNumber', () => { + expect( + getStorageAtQueryOptions(config, { + address: address.wagmiMintExample, + blockNumber: 16280770n, + slot: '0x0', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "getStorageAt", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "blockNumber": 16280770n, + "slot": "0x0", + }, + ], + } + `) +}) + +test('parameters: blockTag', () => { + expect( + getStorageAtQueryOptions(config, { + address: address.wagmiMintExample, + blockTag: 'safe', + slot: '0x0', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "getStorageAt", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "blockTag": "safe", + "slot": "0x0", + }, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getStorageAtQueryOptions(config, { + address: address.wagmiMintExample, + chainId: chain.mainnet2.id, + slot: '0x0', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "getStorageAt", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "chainId": 456, + "slot": "0x0", + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getStorageAt.ts b/wagmi-project/packages/core/src/query/getStorageAt.ts new file mode 100644 index 0000000000..c2ed90c927 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getStorageAt.ts @@ -0,0 +1,49 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetStorageAtErrorType, + type GetStorageAtParameters, + type GetStorageAtReturnType, + getStorageAt, +} from '../actions/getStorageAt.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetStorageAtOptions = Compute< + ExactPartial> & ScopeKeyParameter +> + +export function getStorageAtQueryOptions( + config: config, + options: GetStorageAtOptions = {}, +) { + return { + queryFn({ queryKey }) { + const { address, slot, scopeKey: _, ...parameters } = queryKey[1] + if (!address || !slot) throw new Error('address and slot are required') + return getStorageAt(config, { ...parameters, address, slot }) + }, + queryKey: getStorageAtQueryKey(options), + } as const satisfies QueryOptions< + GetStorageAtQueryFnData, + GetStorageAtErrorType, + GetStorageAtData, + GetStorageAtQueryKey + > +} + +export type GetStorageAtQueryFnData = GetStorageAtReturnType + +export type GetStorageAtData = GetStorageAtQueryFnData + +export function getStorageAtQueryKey( + options: GetStorageAtOptions, +) { + return ['getStorageAt', filterQueryOptions(options)] as const +} + +export type GetStorageAtQueryKey = ReturnType< + typeof getStorageAtQueryKey +> diff --git a/wagmi-project/packages/core/src/query/getToken.test.ts b/wagmi-project/packages/core/src/query/getToken.test.ts new file mode 100644 index 0000000000..87ec1731c9 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getToken.test.ts @@ -0,0 +1,32 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getTokenQueryOptions } from './getToken.js' + +test('default', () => { + expect(getTokenQueryOptions(config)).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "token", + {}, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getTokenQueryOptions(config, { chainId: chain.mainnet.id }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "token", + { + "chainId": 1, + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getToken.ts b/wagmi-project/packages/core/src/query/getToken.ts new file mode 100644 index 0000000000..8e4a2b866a --- /dev/null +++ b/wagmi-project/packages/core/src/query/getToken.ts @@ -0,0 +1,49 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetTokenErrorType, + type GetTokenParameters, + type GetTokenReturnType, + getToken, +} from '../actions/getToken.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetTokenOptions = Compute< + ExactPartial> & ScopeKeyParameter +> + +export function getTokenQueryOptions( + config: config, + options: GetTokenOptions = {}, +) { + return { + async queryFn({ queryKey }) { + const { address, scopeKey: _, ...parameters } = queryKey[1] + if (!address) throw new Error('address is required') + return getToken(config, { ...parameters, address }) + }, + queryKey: getTokenQueryKey(options), + } as const satisfies QueryOptions< + GetTokenQueryFnData, + GetTokenErrorType, + GetTokenData, + GetTokenQueryKey + > +} + +export type GetTokenQueryFnData = GetTokenReturnType + +export type GetTokenData = GetTokenQueryFnData + +export function getTokenQueryKey( + options: GetTokenOptions = {}, +) { + return ['token', filterQueryOptions(options)] as const +} + +export type GetTokenQueryKey = ReturnType< + typeof getTokenQueryKey +> diff --git a/wagmi-project/packages/core/src/query/getTransaction.test.ts b/wagmi-project/packages/core/src/query/getTransaction.test.ts new file mode 100644 index 0000000000..e1db72b325 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getTransaction.test.ts @@ -0,0 +1,32 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getTransactionQueryOptions } from './getTransaction.js' + +test('default', () => { + expect(getTransactionQueryOptions(config)).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "transaction", + {}, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getTransactionQueryOptions(config, { chainId: chain.mainnet.id }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "transaction", + { + "chainId": 1, + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getTransaction.ts b/wagmi-project/packages/core/src/query/getTransaction.ts new file mode 100644 index 0000000000..8564854774 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getTransaction.ts @@ -0,0 +1,69 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetTransactionErrorType, + type GetTransactionParameters, + type GetTransactionReturnType, + getTransaction, +} from '../actions/getTransaction.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetTransactionOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +> = Compute< + ExactPartial> & ScopeKeyParameter +> + +export function getTransactionQueryOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +>(config: config, options: GetTransactionOptions = {}) { + return { + async queryFn({ queryKey }) { + const { blockHash, blockNumber, blockTag, hash, index } = queryKey[1] + if (!blockHash && !blockNumber && !blockTag && !hash) + throw new Error('blockHash, blockNumber, blockTag, or hash is required') + if (!hash && !index) + throw new Error( + 'index is required for blockHash, blockNumber, or blockTag', + ) + const { scopeKey: _, ...rest } = queryKey[1] + return getTransaction( + config, + rest as GetTransactionParameters, + ) as unknown as Promise> + }, + queryKey: getTransactionQueryKey(options), + } as const satisfies QueryOptions< + GetTransactionQueryFnData, + GetTransactionErrorType, + GetTransactionData, + GetTransactionQueryKey + > +} + +export type GetTransactionQueryFnData< + config extends Config, + chainId extends config['chains'][number]['id'], +> = GetTransactionReturnType + +export type GetTransactionData< + config extends Config, + chainId extends config['chains'][number]['id'], +> = GetTransactionQueryFnData + +export function getTransactionQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], +>(options: GetTransactionOptions = {}) { + return ['transaction', filterQueryOptions(options)] as const +} + +export type GetTransactionQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], +> = ReturnType> diff --git a/wagmi-project/packages/core/src/query/getTransactionConfirmations.test.ts b/wagmi-project/packages/core/src/query/getTransactionConfirmations.test.ts new file mode 100644 index 0000000000..ac4d6d4f4a --- /dev/null +++ b/wagmi-project/packages/core/src/query/getTransactionConfirmations.test.ts @@ -0,0 +1,42 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getTransactionConfirmationsQueryOptions } from './getTransactionConfirmations.js' + +test('default', () => { + expect( + getTransactionConfirmationsQueryOptions(config, { + hash: '0xa559259bd2d0e8372421e222ff3545f705b5da60005bd787a23c2e68d6d7fefd', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "transactionConfirmations", + { + "hash": "0xa559259bd2d0e8372421e222ff3545f705b5da60005bd787a23c2e68d6d7fefd", + }, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getTransactionConfirmationsQueryOptions(config, { + chainId: chain.mainnet.id, + hash: '0xa559259bd2d0e8372421e222ff3545f705b5da60005bd787a23c2e68d6d7fefd', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "transactionConfirmations", + { + "chainId": 1, + "hash": "0xa559259bd2d0e8372421e222ff3545f705b5da60005bd787a23c2e68d6d7fefd", + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getTransactionConfirmations.ts b/wagmi-project/packages/core/src/query/getTransactionConfirmations.ts new file mode 100644 index 0000000000..5c34decf37 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getTransactionConfirmations.ts @@ -0,0 +1,78 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetTransactionConfirmationsErrorType, + type GetTransactionConfirmationsParameters, + type GetTransactionConfirmationsReturnType, + getTransactionConfirmations, +} from '../actions/getTransactionConfirmations.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { UnionExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetTransactionConfirmationsOptions< + config extends Config, + chainId extends + | config['chains'][number]['id'] + | undefined = config['chains'][number]['id'], +> = UnionExactPartial> & + ScopeKeyParameter + +export function getTransactionConfirmationsQueryOptions< + config extends Config, + chainId extends + | config['chains'][number]['id'] + | undefined = config['chains'][number]['id'], +>( + config: config, + options: GetTransactionConfirmationsOptions = {} as any, +) { + return { + async queryFn({ queryKey }) { + const { + hash, + transactionReceipt, + scopeKey: _, + ...parameters + } = queryKey[1] + if (!hash && !transactionReceipt) + throw new Error('hash or transactionReceipt is required') + + const confirmations = await getTransactionConfirmations(config, { + hash, + transactionReceipt, + ...(parameters as any), + }) + return confirmations ?? null + }, + queryKey: getTransactionConfirmationsQueryKey(options), + } as const satisfies QueryOptions< + GetTransactionConfirmationsQueryFnData, + GetTransactionConfirmationsErrorType, + GetTransactionConfirmationsData, + GetTransactionConfirmationsQueryKey + > +} + +export type GetTransactionConfirmationsQueryFnData = + GetTransactionConfirmationsReturnType + +export type GetTransactionConfirmationsData = + GetTransactionConfirmationsQueryFnData + +export function getTransactionConfirmationsQueryKey< + config extends Config, + chainId extends + | config['chains'][number]['id'] + | undefined = config['chains'][number]['id'], +>(options: GetTransactionConfirmationsOptions = {} as any) { + return ['transactionConfirmations', filterQueryOptions(options)] as const +} + +export type GetTransactionConfirmationsQueryKey< + config extends Config, + chainId extends + | config['chains'][number]['id'] + | undefined = config['chains'][number]['id'], +> = ReturnType> diff --git a/wagmi-project/packages/core/src/query/getTransactionCount.test.ts b/wagmi-project/packages/core/src/query/getTransactionCount.test.ts new file mode 100644 index 0000000000..666953629b --- /dev/null +++ b/wagmi-project/packages/core/src/query/getTransactionCount.test.ts @@ -0,0 +1,82 @@ +import { accounts, chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getTransactionCountQueryOptions } from './getTransactionCount.js' + +const address = accounts[0] + +test('default', () => { + expect( + getTransactionCountQueryOptions(config, { address }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "transactionCount", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + }, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getTransactionCountQueryOptions(config, { + address, + chainId: chain.mainnet.id, + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "transactionCount", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 1, + }, + ], + } + `) +}) + +test('parameters: blockNumber', () => { + expect( + getTransactionCountQueryOptions(config, { + address, + blockNumber: 13677382n, + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "transactionCount", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "blockNumber": 13677382n, + }, + ], + } + `) +}) + +test('parameters: blockTag', () => { + expect( + getTransactionCountQueryOptions(config, { + address, + blockTag: 'earliest', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "transactionCount", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "blockTag": "earliest", + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getTransactionCount.ts b/wagmi-project/packages/core/src/query/getTransactionCount.ts new file mode 100644 index 0000000000..31fd2c1d8f --- /dev/null +++ b/wagmi-project/packages/core/src/query/getTransactionCount.ts @@ -0,0 +1,55 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetTransactionCountErrorType, + type GetTransactionCountParameters, + type GetTransactionCountReturnType, + getTransactionCount, +} from '../actions/getTransactionCount.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, PartialBy } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetTransactionCountOptions = Compute< + PartialBy, 'address'> & + ScopeKeyParameter +> + +export function getTransactionCountQueryOptions( + config: config, + options: GetTransactionCountOptions = {}, +) { + return { + async queryFn({ queryKey }) { + const { address, scopeKey: _, ...parameters } = queryKey[1] + if (!address) throw new Error('address is required') + const transactionCount = await getTransactionCount(config, { + ...(parameters as GetTransactionCountParameters), + address, + }) + return transactionCount ?? null + }, + queryKey: getTransactionCountQueryKey(options), + } as const satisfies QueryOptions< + GetTransactionCountQueryFnData, + GetTransactionCountErrorType, + GetTransactionCountData, + GetTransactionCountQueryKey + > +} + +export type GetTransactionCountQueryFnData = + Compute + +export type GetTransactionCountData = GetTransactionCountQueryFnData + +export function getTransactionCountQueryKey( + options: GetTransactionCountOptions = {}, +) { + return ['transactionCount', filterQueryOptions(options)] as const +} + +export type GetTransactionCountQueryKey = ReturnType< + typeof getTransactionCountQueryKey +> diff --git a/wagmi-project/packages/core/src/query/getTransactionReceipt.test.ts b/wagmi-project/packages/core/src/query/getTransactionReceipt.test.ts new file mode 100644 index 0000000000..7c719b8d87 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getTransactionReceipt.test.ts @@ -0,0 +1,42 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getTransactionReceiptQueryOptions } from './getTransactionReceipt.js' + +test('default', () => { + expect( + getTransactionReceiptQueryOptions(config, { + hash: '0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "getTransactionReceipt", + { + "hash": "0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871", + }, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getTransactionReceiptQueryOptions(config, { + chainId: chain.mainnet2.id, + hash: '0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "getTransactionReceipt", + { + "chainId": 456, + "hash": "0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871", + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getTransactionReceipt.ts b/wagmi-project/packages/core/src/query/getTransactionReceipt.ts new file mode 100644 index 0000000000..0d7d559d49 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getTransactionReceipt.ts @@ -0,0 +1,60 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetTransactionReceiptErrorType, + type GetTransactionReceiptParameters, + getTransactionReceipt, +} from '../actions/getTransactionReceipt.js' +import type { GetTransactionReceiptReturnType } from '../actions/getTransactionReceipt.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetTransactionReceiptOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +> = Compute< + ExactPartial> & + ScopeKeyParameter +> + +export function getTransactionReceiptQueryOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +>(config: config, options: GetTransactionReceiptOptions = {}) { + return { + queryFn({ queryKey }) { + const { hash, scopeKey: _, ...parameters } = queryKey[1] + if (!hash) throw new Error('hash is required') + return getTransactionReceipt(config, { ...parameters, hash }) + }, + queryKey: getTransactionReceiptQueryKey(options), + } as const satisfies QueryOptions< + GetTransactionReceiptQueryFnData, + GetTransactionReceiptErrorType, + GetTransactionReceiptData, + GetTransactionReceiptQueryKey + > +} +export type GetTransactionReceiptQueryFnData< + config extends Config, + chainId extends config['chains'][number]['id'], +> = GetTransactionReceiptReturnType + +export type GetTransactionReceiptData< + config extends Config, + chainId extends config['chains'][number]['id'], +> = GetTransactionReceiptQueryFnData + +export function getTransactionReceiptQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], +>(options: GetTransactionReceiptOptions) { + return ['getTransactionReceipt', filterQueryOptions(options)] as const +} + +export type GetTransactionReceiptQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], +> = ReturnType> diff --git a/wagmi-project/packages/core/src/query/getWalletClient.test.ts b/wagmi-project/packages/core/src/query/getWalletClient.test.ts new file mode 100644 index 0000000000..899b480882 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getWalletClient.test.ts @@ -0,0 +1,37 @@ +import { chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { getWalletClientQueryOptions } from './getWalletClient.js' + +test('default', () => { + expect(getWalletClientQueryOptions(config)).toMatchInlineSnapshot(` + { + "gcTime": 0, + "queryFn": [Function], + "queryKey": [ + "walletClient", + { + "connectorUid": undefined, + }, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + getWalletClientQueryOptions(config, { chainId: chain.mainnet.id }), + ).toMatchInlineSnapshot(` + { + "gcTime": 0, + "queryFn": [Function], + "queryKey": [ + "walletClient", + { + "chainId": 1, + "connectorUid": undefined, + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/getWalletClient.ts b/wagmi-project/packages/core/src/query/getWalletClient.ts new file mode 100644 index 0000000000..3c64b39a07 --- /dev/null +++ b/wagmi-project/packages/core/src/query/getWalletClient.ts @@ -0,0 +1,65 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type GetWalletClientErrorType, + type GetWalletClientParameters, + type GetWalletClientReturnType, + getWalletClient, +} from '../actions/getWalletClient.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type GetWalletClientOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +> = Compute< + ExactPartial> & ScopeKeyParameter +> + +export function getWalletClientQueryOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +>(config: config, options: GetWalletClientOptions = {}) { + return { + gcTime: 0, + async queryFn({ queryKey }) { + const { connector } = options + const { connectorUid: _, scopeKey: _s, ...parameters } = queryKey[1] + return getWalletClient(config, { ...parameters, connector }) + }, + queryKey: getWalletClientQueryKey(options), + } as const satisfies QueryOptions< + GetWalletClientQueryFnData, + GetWalletClientErrorType, + GetWalletClientData, + GetWalletClientQueryKey + > +} + +export type GetWalletClientQueryFnData< + config extends Config, + chainId extends config['chains'][number]['id'], +> = GetWalletClientReturnType + +export type GetWalletClientData< + config extends Config, + chainId extends config['chains'][number]['id'], +> = GetWalletClientQueryFnData + +export function getWalletClientQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], +>(options: GetWalletClientOptions = {}) { + const { connector, ...parameters } = options + return [ + 'walletClient', + { ...filterQueryOptions(parameters), connectorUid: connector?.uid }, + ] as const +} + +export type GetWalletClientQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], +> = ReturnType> diff --git a/wagmi-project/packages/core/src/query/infiniteReadContracts.test-d.ts b/wagmi-project/packages/core/src/query/infiniteReadContracts.test-d.ts new file mode 100644 index 0000000000..c76dd3bccc --- /dev/null +++ b/wagmi-project/packages/core/src/query/infiniteReadContracts.test-d.ts @@ -0,0 +1,201 @@ +import { abi, config } from '@wagmi/test' +import type { MulticallResponse } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { infiniteReadContractsQueryOptions } from './infiniteReadContracts.js' + +test('default', async () => { + const options = infiniteReadContractsQueryOptions(config, { + cacheKey: 'foo', + contracts(pageParam) { + expectTypeOf(pageParam).toEqualTypeOf(options.initialPageParam) + return [ + { + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + }, + { + address: '0x', + abi: abi.wagmiMintExample, + functionName: 'tokenURI', + args: [123n], + }, + ] + }, + query: { + initialPageParam: 0, + getNextPageParam(lastPage, allPages, lastPageParam, allPageParams) { + expectTypeOf(lastPage).toEqualTypeOf< + [MulticallResponse, MulticallResponse] + >() + expectTypeOf(allPages).toEqualTypeOf< + [MulticallResponse, MulticallResponse][] + >() + expectTypeOf(lastPageParam).toEqualTypeOf(options.initialPageParam) + expectTypeOf(allPageParams).toEqualTypeOf([options.initialPageParam]) + return lastPageParam + 1 + }, + }, + }) + const result = await options.queryFn({} as any) + expectTypeOf(result).toEqualTypeOf< + [MulticallResponse, MulticallResponse] + >() +}) + +test('allowFailure: false', async () => { + const options = infiniteReadContractsQueryOptions(config, { + allowFailure: false, + cacheKey: 'foo', + contracts(pageParam) { + expectTypeOf(pageParam).toEqualTypeOf(options.initialPageParam) + return [ + { + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + }, + { + address: '0x', + abi: abi.wagmiMintExample, + functionName: 'tokenURI', + args: [123n], + }, + ] + }, + query: { + initialPageParam: 0, + getNextPageParam(lastPage, allPages, lastPageParam, allPageParams) { + expectTypeOf(lastPage).toEqualTypeOf<[bigint, string]>() + expectTypeOf(allPages).toEqualTypeOf<[bigint, string][]>() + expectTypeOf(lastPageParam).toEqualTypeOf(options.initialPageParam) + expectTypeOf(allPageParams).toEqualTypeOf([options.initialPageParam]) + return lastPageParam + 1 + }, + }, + }) + const result = await options.queryFn({} as any) + expectTypeOf(result).toEqualTypeOf<[bigint, string]>() +}) + +test('initialPageParam', async () => { + const options = infiniteReadContractsQueryOptions(config, { + allowFailure: false, + cacheKey: 'foo', + contracts(pageParam) { + expectTypeOf(pageParam).toEqualTypeOf(options.initialPageParam) + return [ + { + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + }, + { + address: '0x', + abi: abi.wagmiMintExample, + functionName: 'tokenURI', + args: [123n], + }, + ] + }, + query: { + initialPageParam: 'bar', + getNextPageParam(lastPage, allPages, lastPageParam, allPageParams) { + expectTypeOf(lastPage).toEqualTypeOf<[bigint, string]>() + expectTypeOf(allPages).toEqualTypeOf<[bigint, string][]>() + expectTypeOf(lastPageParam).toEqualTypeOf(options.initialPageParam) + expectTypeOf(allPageParams).toEqualTypeOf([options.initialPageParam]) + return lastPageParam + 1 + }, + }, + }) + const result = await options.queryFn({} as any) + expectTypeOf(result).toEqualTypeOf<[bigint, string]>() +}) + +test('behavior: `contracts` after `getNextPageParam`', async () => { + const options = infiniteReadContractsQueryOptions(config, { + allowFailure: false, + cacheKey: 'foo', + query: { + initialPageParam: 0, + getNextPageParam(lastPage, allPages, lastPageParam, allPageParams) { + expectTypeOf(lastPage).toEqualTypeOf() + expectTypeOf(allPages).toEqualTypeOf() + expectTypeOf(lastPageParam).toEqualTypeOf(options.initialPageParam) + expectTypeOf(allPageParams).toEqualTypeOf([options.initialPageParam]) + return lastPageParam + 1 + }, + }, + contracts(pageParam) { + expectTypeOf(pageParam).toEqualTypeOf(options.initialPageParam) + return [ + { + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + }, + { + address: '0x', + abi: abi.wagmiMintExample, + functionName: 'tokenURI', + args: [123n], + }, + ] + }, + }) + const result = await options.queryFn({} as any) + expectTypeOf(result).toEqualTypeOf() +}) + +test('overloads', async () => { + const options = infiniteReadContractsQueryOptions(config, { + allowFailure: false, + cacheKey: 'foo', + contracts(pageParam) { + expectTypeOf(pageParam).toEqualTypeOf() + return [ + { + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + }, + { + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: ['0x'], + }, + { + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: ['0x', '0x'], + }, + ] + }, + query: { + initialPageParam: 0, + getNextPageParam(_, allPages) { + return allPages.length + 1 + }, + }, + }) + + const result = await options.queryFn({} as any) + expectTypeOf(result).toEqualTypeOf< + [ + number, + string, + { + foo: `0x${string}` + bar: `0x${string}` + }, + ] + >() +}) diff --git a/wagmi-project/packages/core/src/query/infiniteReadContracts.test.ts b/wagmi-project/packages/core/src/query/infiniteReadContracts.test.ts new file mode 100644 index 0000000000..509e984838 --- /dev/null +++ b/wagmi-project/packages/core/src/query/infiniteReadContracts.test.ts @@ -0,0 +1,60 @@ +import { abi, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { infiniteReadContractsQueryOptions } from './infiniteReadContracts.js' + +test('default', () => { + expect( + infiniteReadContractsQueryOptions(config, { + allowFailure: true, + batchSize: 1024, + blockNumber: 123n, + blockTag: 'latest', + cacheKey: 'foo', + chainId: 1, + multicallAddress: '0x', + scopeKey: 'bar', + contracts(_pageParam) { + return [ + { + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + }, + { + address: '0x', + abi: abi.wagmiMintExample, + functionName: 'tokenURI', + args: [123n], + }, + ] + }, + query: { + initialPageParam: 0, + getNextPageParam(_lastPage, _allPages, lastPageParam, _allPageParams) { + return lastPageParam + 1 + }, + }, + }), + ).toMatchInlineSnapshot(` + { + "getNextPageParam": [Function], + "initialPageParam": 0, + "queryFn": [Function], + "queryKey": [ + "infiniteReadContracts", + { + "allowFailure": true, + "batchSize": 1024, + "blockNumber": 123n, + "blockTag": "latest", + "cacheKey": "foo", + "chainId": 1, + "multicallAddress": "0x", + "scopeKey": "bar", + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/infiniteReadContracts.ts b/wagmi-project/packages/core/src/query/infiniteReadContracts.ts new file mode 100644 index 0000000000..28a8d3f52a --- /dev/null +++ b/wagmi-project/packages/core/src/query/infiniteReadContracts.ts @@ -0,0 +1,127 @@ +import type { ContractFunctionParameters } from 'viem' +import { + type ReadContractsErrorType, + type ReadContractsParameters, + type ReadContractsReturnType, + readContracts, +} from '../actions/readContracts.js' +import type { Config } from '../createConfig.js' +import type { + ChainIdParameter, + ScopeKeyParameter, +} from '../types/properties.js' +import type { StrictOmit } from '../types/utils.js' +import type { InfiniteQueryOptions } from './types.js' +import { filterQueryOptions } from './utils.js' + +export type InfiniteReadContractsOptions< + contracts extends readonly unknown[], + allowFailure extends boolean, + pageParam, + config extends Config, +> = { + cacheKey: string + contracts( + pageParam: pageParam, + ): ReadContractsParameters['contracts'] +} & StrictOmit< + ReadContractsParameters, + 'contracts' +> & + ScopeKeyParameter + +export function infiniteReadContractsQueryOptions< + config extends Config, + const contracts extends readonly ContractFunctionParameters[], + allowFailure extends boolean = true, + pageParam = unknown, +>( + config: config, + options: InfiniteReadContractsOptions< + contracts, + allowFailure, + pageParam, + config + > & + ChainIdParameter & + RequiredPageParamsParameters, +) { + return { + ...options.query, + async queryFn({ pageParam, queryKey }) { + const { contracts } = options + const { cacheKey: _, scopeKey: _s, ...parameters } = queryKey[1] + return (await readContracts(config, { + ...parameters, + contracts: contracts(pageParam as any), + })) as ReadContractsReturnType + }, + queryKey: infiniteReadContractsQueryKey(options), + } as const satisfies InfiniteQueryOptions< + InfiniteReadContractsQueryFnData, + ReadContractsErrorType, + InfiniteReadContractsData, + InfiniteReadContractsData, + InfiniteReadContractsQueryKey, + pageParam + > +} + +type RequiredPageParamsParameters< + contracts extends readonly unknown[], + allowFailure extends boolean, + pageParam, +> = { + query: { + initialPageParam: pageParam + getNextPageParam( + lastPage: InfiniteReadContractsQueryFnData, + allPages: InfiniteReadContractsQueryFnData[], + lastPageParam: pageParam, + allPageParams: pageParam[], + ): pageParam | undefined | null + } +} + +export type InfiniteReadContractsQueryFnData< + contracts extends readonly unknown[], + allowFailure extends boolean, +> = ReadContractsReturnType + +export type InfiniteReadContractsData< + contracts extends readonly unknown[], + allowFailure extends boolean, +> = InfiniteReadContractsQueryFnData + +export function infiniteReadContractsQueryKey< + config extends Config, + const contracts extends readonly unknown[], + allowFailure extends boolean, + pageParam, +>( + options: InfiniteReadContractsOptions< + contracts, + allowFailure, + pageParam, + config + > & + ChainIdParameter & + RequiredPageParamsParameters, +) { + const { contracts: _, query: _q, ...parameters } = options + return ['infiniteReadContracts', filterQueryOptions(parameters)] as const +} + +export type InfiniteReadContractsQueryKey< + contracts extends readonly unknown[], + allowFailure extends boolean, + pageParam, + config extends Config, +> = ReturnType< + typeof infiniteReadContractsQueryKey< + config, + contracts, + allowFailure, + pageParam + > +> diff --git a/wagmi-project/packages/core/src/query/prepareTransactionRequest.test.ts b/wagmi-project/packages/core/src/query/prepareTransactionRequest.test.ts new file mode 100644 index 0000000000..d33c156be4 --- /dev/null +++ b/wagmi-project/packages/core/src/query/prepareTransactionRequest.test.ts @@ -0,0 +1,241 @@ +import { accounts, chain, config } from '@wagmi/test' +import { parseEther, parseGwei } from 'viem' +import { privateKeyToAccount } from 'viem/accounts' +import { expect, test } from 'vitest' + +import { prepareTransactionRequestQueryOptions } from './prepareTransactionRequest.js' + +const targetAccount = accounts[0] + +test('default', () => { + expect( + prepareTransactionRequestQueryOptions(config, { + to: targetAccount, + value: parseEther('1'), + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "prepareTransactionRequest", + { + "to": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "value": 1000000000000000000n, + }, + ], + } + `) +}) + +test('parameters: account', () => { + expect( + prepareTransactionRequestQueryOptions(config, { + account: privateKeyToAccount( + '0x0123456789012345678901234567890123456789012345678901234567890123', + ), + to: targetAccount, + value: parseEther('1'), + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "prepareTransactionRequest", + { + "account": { + "address": "0x14791697260E4c9A71f18484C9f997B308e59325", + "nonceManager": undefined, + "publicKey": "0x046655feed4d214c261e0a6b554395596f1f1476a77d999560e5a8df9b8a1a3515217e88dd05e938efdd71b2cce322bf01da96cd42087b236e8f5043157a9c068e", + "sign": [Function], + "signAuthorization": [Function], + "signMessage": [Function], + "signTransaction": [Function], + "signTypedData": [Function], + "source": "privateKey", + "type": "local", + }, + "to": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "value": 1000000000000000000n, + }, + ], + } + `) +}) + +test('parameters: data', () => { + expect( + prepareTransactionRequestQueryOptions(config, { + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: targetAccount, + value: parseEther('1'), + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "prepareTransactionRequest", + { + "data": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", + "to": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "value": 1000000000000000000n, + }, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + prepareTransactionRequestQueryOptions(config, { + chainId: chain.mainnet2.id, + to: targetAccount, + value: parseEther('1'), + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "prepareTransactionRequest", + { + "chainId": 456, + "to": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "value": 1000000000000000000n, + }, + ], + } + `) +}) + +test('parameters: nonce', () => { + expect( + prepareTransactionRequestQueryOptions(config, { + nonce: 5, + to: targetAccount, + value: parseEther('1'), + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "prepareTransactionRequest", + { + "nonce": 5, + "to": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "value": 1000000000000000000n, + }, + ], + } + `) +}) + +test('parameters: gasPrice', () => { + expect( + prepareTransactionRequestQueryOptions(config, { + gasPrice: parseGwei('10'), + to: targetAccount, + value: parseEther('1'), + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "prepareTransactionRequest", + { + "gasPrice": 10000000000n, + "to": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "value": 1000000000000000000n, + }, + ], + } + `) +}) + +test('parameters: maxFeePerGas', () => { + expect( + prepareTransactionRequestQueryOptions(config, { + maxFeePerGas: parseGwei('100'), + to: targetAccount, + value: parseEther('1'), + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "prepareTransactionRequest", + { + "maxFeePerGas": 100000000000n, + "to": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "value": 1000000000000000000n, + }, + ], + } + `) +}) + +test('parameters: maxPriorityFeePerGas', () => { + expect( + prepareTransactionRequestQueryOptions(config, { + maxPriorityFeePerGas: parseGwei('5'), + to: targetAccount, + value: parseEther('1'), + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "prepareTransactionRequest", + { + "maxPriorityFeePerGas": 5000000000n, + "to": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "value": 1000000000000000000n, + }, + ], + } + `) +}) + +test('parameters: type', () => { + expect( + prepareTransactionRequestQueryOptions(config, { + type: 'eip1559', + to: targetAccount, + value: parseEther('1'), + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "prepareTransactionRequest", + { + "to": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "type": "eip1559", + "value": 1000000000000000000n, + }, + ], + } + `) +}) + +test('parameters: parameters', () => { + expect( + prepareTransactionRequestQueryOptions(config, { + parameters: ['gas'], + to: targetAccount, + value: parseEther('1'), + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "prepareTransactionRequest", + { + "parameters": [ + "gas", + ], + "to": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "value": 1000000000000000000n, + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/prepareTransactionRequest.ts b/wagmi-project/packages/core/src/query/prepareTransactionRequest.ts new file mode 100644 index 0000000000..5ed4b419fa --- /dev/null +++ b/wagmi-project/packages/core/src/query/prepareTransactionRequest.ts @@ -0,0 +1,101 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import type { PrepareTransactionRequestRequest as viem_PrepareTransactionRequestRequest } from 'viem' + +import { + type PrepareTransactionRequestErrorType, + type PrepareTransactionRequestParameters, + type PrepareTransactionRequestReturnType, + prepareTransactionRequest, +} from '../actions/prepareTransactionRequest.js' +import type { Config } from '../createConfig.js' +import type { SelectChains } from '../types/chain.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { UnionExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type PrepareTransactionRequestOptions< + config extends Config, + chainId extends config['chains'][number]['id'] | undefined, + request extends viem_PrepareTransactionRequestRequest< + SelectChains[0], + SelectChains[0] + >, +> = UnionExactPartial< + PrepareTransactionRequestParameters +> & + ScopeKeyParameter + +export function prepareTransactionRequestQueryOptions< + config extends Config, + chainId extends config['chains'][number]['id'] | undefined, + request extends viem_PrepareTransactionRequestRequest< + SelectChains[0], + SelectChains[0] + >, +>( + config: config, + options: PrepareTransactionRequestOptions< + config, + chainId, + request + > = {} as any, +) { + return { + queryFn({ queryKey }) { + const { scopeKey: _, to, ...parameters } = queryKey[1] + if (!to) throw new Error('to is required') + return prepareTransactionRequest(config, { + to, + ...(parameters as any), + }) as unknown as Promise< + PrepareTransactionRequestQueryFnData + > + }, + queryKey: prepareTransactionRequestQueryKey(options), + } as const satisfies QueryOptions< + PrepareTransactionRequestQueryFnData, + PrepareTransactionRequestErrorType, + PrepareTransactionRequestData, + PrepareTransactionRequestQueryKey + > +} +export type PrepareTransactionRequestQueryFnData< + config extends Config, + chainId extends config['chains'][number]['id'] | undefined, + request extends viem_PrepareTransactionRequestRequest< + SelectChains[0], + SelectChains[0] + >, +> = PrepareTransactionRequestReturnType + +export type PrepareTransactionRequestData< + config extends Config, + chainId extends config['chains'][number]['id'] | undefined, + request extends viem_PrepareTransactionRequestRequest< + SelectChains[0], + SelectChains[0] + >, +> = PrepareTransactionRequestQueryFnData + +export function prepareTransactionRequestQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'] | undefined, + request extends viem_PrepareTransactionRequestRequest< + SelectChains[0], + SelectChains[0] + >, +>(options: PrepareTransactionRequestOptions) { + return ['prepareTransactionRequest', filterQueryOptions(options)] as const +} + +export type PrepareTransactionRequestQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'] | undefined, + request extends viem_PrepareTransactionRequestRequest< + SelectChains[0], + SelectChains[0] + >, +> = ReturnType< + typeof prepareTransactionRequestQueryKey +> diff --git a/wagmi-project/packages/core/src/query/readContract.test-d.ts b/wagmi-project/packages/core/src/query/readContract.test-d.ts new file mode 100644 index 0000000000..286b8819c7 --- /dev/null +++ b/wagmi-project/packages/core/src/query/readContract.test-d.ts @@ -0,0 +1,15 @@ +import { abi, config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { readContractQueryOptions } from './readContract.js' + +test('default', async () => { + const options = readContractQueryOptions(config, { + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + }) + const result = await options.queryFn({} as any) + expectTypeOf(result).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/core/src/query/readContract.test.ts b/wagmi-project/packages/core/src/query/readContract.test.ts new file mode 100644 index 0000000000..6c17b849ab --- /dev/null +++ b/wagmi-project/packages/core/src/query/readContract.test.ts @@ -0,0 +1,29 @@ +import { abi, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { readContractQueryOptions } from './readContract.js' + +test('default', () => { + expect( + readContractQueryOptions(config, { + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "readContract", + { + "address": "0x", + "args": [ + "0x", + ], + "functionName": "balanceOf", + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/readContract.ts b/wagmi-project/packages/core/src/query/readContract.ts new file mode 100644 index 0000000000..52c586665f --- /dev/null +++ b/wagmi-project/packages/core/src/query/readContract.ts @@ -0,0 +1,93 @@ +import type { QueryOptions } from '@tanstack/query-core' +import type { Abi, ContractFunctionArgs, ContractFunctionName } from 'viem' + +import { + type ReadContractErrorType, + type ReadContractParameters, + type ReadContractReturnType, + readContract, +} from '../actions/readContract.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { UnionExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type ReadContractOptions< + abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs, + config extends Config, +> = UnionExactPartial> & + ScopeKeyParameter + +export function readContractQueryOptions< + config extends Config, + const abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs, +>( + config: config, + options: ReadContractOptions = {} as any, +) { + return { + // TODO: Support `signal` once Viem actions allow passthrough + // https://tkdodo.eu/blog/why-you-want-react-query#bonus-cancellation + async queryFn({ queryKey }) { + const abi = options.abi as Abi + if (!abi) throw new Error('abi is required') + + const { functionName, scopeKey: _, ...parameters } = queryKey[1] + const addressOrCodeParams = (() => { + const params = queryKey[1] as unknown as ReadContractParameters + if (params.address) return { address: params.address } + if (params.code) return { code: params.code } + throw new Error('address or code is required') + })() + + if (!functionName) throw new Error('functionName is required') + + return readContract(config, { + abi, + functionName, + args: parameters.args as readonly unknown[], + ...addressOrCodeParams, + ...parameters, + }) as Promise> + }, + queryKey: readContractQueryKey(options as any) as any, + } as const satisfies QueryOptions< + ReadContractQueryFnData, + ReadContractErrorType, + ReadContractData, + ReadContractQueryKey + > +} + +export type ReadContractQueryFnData< + abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs, +> = ReadContractReturnType + +export type ReadContractData< + abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs, +> = ReadContractQueryFnData + +export function readContractQueryKey< + config extends Config, + const abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs, +>(options: ReadContractOptions = {} as any) { + const { abi: _, ...rest } = options + return ['readContract', filterQueryOptions(rest)] as const +} + +export type ReadContractQueryKey< + abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs, + config extends Config, +> = ReturnType> diff --git a/wagmi-project/packages/core/src/query/readContracts.test-d.ts b/wagmi-project/packages/core/src/query/readContracts.test-d.ts new file mode 100644 index 0000000000..b6236e191b --- /dev/null +++ b/wagmi-project/packages/core/src/query/readContracts.test-d.ts @@ -0,0 +1,58 @@ +import { abi, config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { readContractsQueryOptions } from './readContracts.js' + +test('default', async () => { + const options = readContractsQueryOptions(config, { + contracts: [ + { + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + }, + { + address: '0x', + abi: abi.wagmiMintExample, + functionName: 'tokenURI', + args: [123n], + }, + ], + }) + const result = await options.queryFn({} as any) + expectTypeOf(result).toEqualTypeOf< + [ + ( + | { error: Error; result?: undefined; status: 'failure' } + | { error?: undefined; result: bigint; status: 'success' } + ), + ( + | { error: Error; result?: undefined; status: 'failure' } + | { error?: undefined; result: string; status: 'success' } + ), + ] + >() +}) + +test('allowFailure: false', async () => { + const options = readContractsQueryOptions(config, { + allowFailure: false, + contracts: [ + { + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + }, + { + address: '0x', + abi: abi.wagmiMintExample, + functionName: 'tokenURI', + args: [123n], + }, + ], + }) + const result = await options.queryFn({} as any) + expectTypeOf(result).toEqualTypeOf<[bigint, string]>() +}) diff --git a/wagmi-project/packages/core/src/query/readContracts.test.ts b/wagmi-project/packages/core/src/query/readContracts.test.ts new file mode 100644 index 0000000000..755b80c202 --- /dev/null +++ b/wagmi-project/packages/core/src/query/readContracts.test.ts @@ -0,0 +1,38 @@ +import { abi, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { readContractsQueryOptions } from './readContracts.js' + +test('default', () => { + expect( + readContractsQueryOptions(config, { + contracts: [ + { + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + }, + ], + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "readContracts", + { + "contracts": [ + { + "address": "0x", + "args": [ + "0x", + ], + "chainId": undefined, + "functionName": "balanceOf", + }, + ], + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/readContracts.ts b/wagmi-project/packages/core/src/query/readContracts.ts new file mode 100644 index 0000000000..96bb2163cd --- /dev/null +++ b/wagmi-project/packages/core/src/query/readContracts.ts @@ -0,0 +1,98 @@ +import type { QueryOptions } from '@tanstack/query-core' +import type { + ContractFunctionParameters, + MulticallParameters as viem_MulticallParameters, +} from 'viem' + +import { + type ReadContractsErrorType, + type ReadContractsReturnType, + readContracts, +} from '../actions/readContracts.js' +import type { Config } from '../createConfig.js' +import type { ChainIdParameter } from '../types/properties.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type ReadContractsOptions< + contracts extends readonly unknown[], + allowFailure extends boolean, + config extends Config, +> = ExactPartial< + viem_MulticallParameters< + contracts, + allowFailure, + { optional: true; properties: ChainIdParameter } + > +> & + ScopeKeyParameter + +export function readContractsQueryOptions< + config extends Config, + const contracts extends readonly unknown[], + allowFailure extends boolean = true, +>( + config: config, + options: ReadContractsOptions & + ChainIdParameter = {}, +) { + return { + async queryFn({ queryKey }) { + const contracts: ContractFunctionParameters[] = [] + const length = queryKey[1].contracts.length + for (let i = 0; i < length; i++) { + const contract = queryKey[1].contracts[i]! + const abi = (options.contracts?.[i] as ContractFunctionParameters).abi + contracts.push({ ...contract, abi }) + } + const { scopeKey: _, ...parameters } = queryKey[1] + return readContracts(config, { + ...parameters, + contracts, + }) as Promise> + }, + queryKey: readContractsQueryKey(options), + } as const satisfies QueryOptions< + ReadContractsQueryFnData, + ReadContractsErrorType, + ReadContractsData, + ReadContractsQueryKey + > +} + +export type ReadContractsQueryFnData< + contracts extends readonly unknown[], + allowFailure extends boolean, +> = ReadContractsReturnType + +export type ReadContractsData< + contracts extends readonly unknown[], + allowFailure extends boolean, +> = ReadContractsQueryFnData + +export function readContractsQueryKey< + config extends Config, + const contracts extends readonly unknown[], + allowFailure extends boolean, +>( + options: ReadContractsOptions & + ChainIdParameter = {}, +) { + const contracts = [] + for (const contract of (options.contracts ?? + []) as (ContractFunctionParameters & { chainId: number })[]) { + const { abi: _, ...rest } = contract + contracts.push({ ...rest, chainId: rest.chainId ?? options.chainId }) + } + return [ + 'readContracts', + filterQueryOptions({ ...options, contracts }), + ] as const +} + +export type ReadContractsQueryKey< + contracts extends readonly unknown[], + allowFailure extends boolean, + config extends Config, +> = ReturnType> diff --git a/wagmi-project/packages/core/src/query/reconnect.test.ts b/wagmi-project/packages/core/src/query/reconnect.test.ts new file mode 100644 index 0000000000..fbcb56c3fc --- /dev/null +++ b/wagmi-project/packages/core/src/query/reconnect.test.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { reconnectMutationOptions } from './reconnect.js' + +test('default', () => { + expect(reconnectMutationOptions(config)).toMatchInlineSnapshot(` + { + "mutationFn": [Function], + "mutationKey": [ + "reconnect", + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/reconnect.ts b/wagmi-project/packages/core/src/query/reconnect.ts new file mode 100644 index 0000000000..13126cdd34 --- /dev/null +++ b/wagmi-project/packages/core/src/query/reconnect.ts @@ -0,0 +1,42 @@ +import type { MutationOptions } from '@tanstack/query-core' + +import { + type ReconnectErrorType, + type ReconnectParameters, + type ReconnectReturnType, + reconnect, +} from '../actions/reconnect.js' +import type { Config } from '../createConfig.js' +import type { Compute } from '../types/utils.js' +import type { Mutate, MutateAsync } from './types.js' + +export function reconnectMutationOptions(config: Config) { + return { + mutationFn(variables) { + return reconnect(config, variables) + }, + mutationKey: ['reconnect'], + } as const satisfies MutationOptions< + ReconnectData, + ReconnectErrorType, + ReconnectVariables + > +} + +export type ReconnectData = Compute + +export type ReconnectVariables = ReconnectParameters | undefined + +export type ReconnectMutate = Mutate< + ReconnectData, + ReconnectErrorType, + ReconnectVariables, + context +> + +export type ReconnectMutateAsync = MutateAsync< + ReconnectData, + ReconnectErrorType, + ReconnectVariables, + context +> diff --git a/wagmi-project/packages/core/src/query/sendCalls.test.ts b/wagmi-project/packages/core/src/query/sendCalls.test.ts new file mode 100644 index 0000000000..9892aa43e3 --- /dev/null +++ b/wagmi-project/packages/core/src/query/sendCalls.test.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { sendCallsMutationOptions } from './sendCalls.js' + +test('default', () => { + expect(sendCallsMutationOptions(config)).toMatchInlineSnapshot(` + { + "mutationFn": [Function], + "mutationKey": [ + "sendCalls", + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/sendCalls.ts b/wagmi-project/packages/core/src/query/sendCalls.ts new file mode 100644 index 0000000000..5d07b89b8f --- /dev/null +++ b/wagmi-project/packages/core/src/query/sendCalls.ts @@ -0,0 +1,67 @@ +import type { MutateOptions, MutationOptions } from '@tanstack/query-core' + +import { + type SendCallsErrorType, + type SendCallsParameters, + type SendCallsReturnType, + sendCalls, +} from '../actions/sendCalls.js' +import type { Config } from '../createConfig.js' +import type { Compute } from '../types/utils.js' + +export function sendCallsMutationOptions( + config: config, +) { + return { + mutationFn(variables) { + return sendCalls(config, variables) + }, + mutationKey: ['sendCalls'], + } as const satisfies MutationOptions< + SendCallsData, + SendCallsErrorType, + SendCallsVariables + > +} + +export type SendCallsData = Compute + +export type SendCallsVariables< + config extends Config, + chainId extends config['chains'][number]['id'], + calls extends readonly unknown[] = readonly unknown[], +> = SendCallsParameters + +export type SendCallsMutate = < + const calls extends readonly unknown[], + chainId extends config['chains'][number]['id'], +>( + variables: SendCallsVariables, + options?: + | Compute< + MutateOptions< + SendCallsData, + SendCallsErrorType, + Compute>, + context + > + > + | undefined, +) => void + +export type SendCallsMutateAsync = < + const calls extends readonly unknown[], + chainId extends config['chains'][number]['id'], +>( + variables: SendCallsVariables, + options?: + | Compute< + MutateOptions< + SendCallsData, + SendCallsErrorType, + Compute>, + context + > + > + | undefined, +) => Promise diff --git a/wagmi-project/packages/core/src/query/sendTransaction.test.ts b/wagmi-project/packages/core/src/query/sendTransaction.test.ts new file mode 100644 index 0000000000..4cda333e71 --- /dev/null +++ b/wagmi-project/packages/core/src/query/sendTransaction.test.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { sendTransactionMutationOptions } from './sendTransaction.js' + +test('default', () => { + expect(sendTransactionMutationOptions(config)).toMatchInlineSnapshot(` + { + "mutationFn": [Function], + "mutationKey": [ + "sendTransaction", + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/sendTransaction.ts b/wagmi-project/packages/core/src/query/sendTransaction.ts new file mode 100644 index 0000000000..e6df10fef7 --- /dev/null +++ b/wagmi-project/packages/core/src/query/sendTransaction.ts @@ -0,0 +1,65 @@ +import type { MutateOptions, MutationOptions } from '@tanstack/query-core' + +import { + type SendTransactionErrorType, + type SendTransactionParameters, + type SendTransactionReturnType, + sendTransaction, +} from '../actions/sendTransaction.js' +import type { Config } from '../createConfig.js' +import type { Compute } from '../types/utils.js' + +export function sendTransactionMutationOptions( + config: config, +) { + return { + mutationFn(variables) { + return sendTransaction(config, variables) + }, + mutationKey: ['sendTransaction'], + } as const satisfies MutationOptions< + SendTransactionData, + SendTransactionErrorType, + SendTransactionVariables + > +} + +export type SendTransactionData = Compute + +export type SendTransactionVariables< + config extends Config, + chainId extends config['chains'][number]['id'], +> = SendTransactionParameters + +export type SendTransactionMutate = < + chainId extends config['chains'][number]['id'], +>( + variables: SendTransactionVariables, + options?: + | Compute< + MutateOptions< + SendTransactionData, + SendTransactionErrorType, + Compute>, + context + > + > + | undefined, +) => void + +export type SendTransactionMutateAsync< + config extends Config, + context = unknown, +> = ( + variables: SendTransactionVariables, + options?: + | Compute< + MutateOptions< + SendTransactionData, + SendTransactionErrorType, + Compute>, + context + > + > + | undefined, +) => Promise diff --git a/wagmi-project/packages/core/src/query/showCallsStatus.test.ts b/wagmi-project/packages/core/src/query/showCallsStatus.test.ts new file mode 100644 index 0000000000..ad26ab6171 --- /dev/null +++ b/wagmi-project/packages/core/src/query/showCallsStatus.test.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { showCallsStatusMutationOptions } from './showCallsStatus.js' + +test('default', () => { + expect(showCallsStatusMutationOptions(config)).toMatchInlineSnapshot(` + { + "mutationFn": [Function], + "mutationKey": [ + "showCallsStatus", + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/showCallsStatus.ts b/wagmi-project/packages/core/src/query/showCallsStatus.ts new file mode 100644 index 0000000000..86a703cbc8 --- /dev/null +++ b/wagmi-project/packages/core/src/query/showCallsStatus.ts @@ -0,0 +1,57 @@ +import type { MutateOptions, MutationOptions } from '@tanstack/query-core' + +import { + type ShowCallsStatusErrorType, + type ShowCallsStatusParameters, + type ShowCallsStatusReturnType, + showCallsStatus, +} from '../actions/showCallsStatus.js' +import type { Config } from '../createConfig.js' +import type { Compute } from '../types/utils.js' + +export function showCallsStatusMutationOptions( + config: config, +) { + return { + mutationFn(variables) { + return showCallsStatus(config, variables) + }, + mutationKey: ['showCallsStatus'], + } as const satisfies MutationOptions< + ShowCallsStatusData, + ShowCallsStatusErrorType, + ShowCallsStatusVariables + > +} + +export type ShowCallsStatusData = Compute + +export type ShowCallsStatusVariables = ShowCallsStatusParameters + +export type ShowCallsStatusMutate = ( + variables: ShowCallsStatusVariables, + options?: + | Compute< + MutateOptions< + ShowCallsStatusData, + ShowCallsStatusErrorType, + Compute, + context + > + > + | undefined, +) => void + +export type ShowCallsStatusMutateAsync = ( + variables: ShowCallsStatusVariables, + options?: + | Compute< + MutateOptions< + ShowCallsStatusData, + ShowCallsStatusErrorType, + Compute, + context + > + > + | undefined, +) => Promise diff --git a/wagmi-project/packages/core/src/query/signMessage.test.ts b/wagmi-project/packages/core/src/query/signMessage.test.ts new file mode 100644 index 0000000000..b8ad84d0af --- /dev/null +++ b/wagmi-project/packages/core/src/query/signMessage.test.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { signMessageMutationOptions } from './signMessage.js' + +test('default', () => { + expect(signMessageMutationOptions(config)).toMatchInlineSnapshot(` + { + "mutationFn": [Function], + "mutationKey": [ + "signMessage", + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/signMessage.ts b/wagmi-project/packages/core/src/query/signMessage.ts new file mode 100644 index 0000000000..d2a4d8156a --- /dev/null +++ b/wagmi-project/packages/core/src/query/signMessage.ts @@ -0,0 +1,42 @@ +import type { MutationOptions } from '@tanstack/query-core' + +import { + type SignMessageErrorType, + type SignMessageParameters, + type SignMessageReturnType, + signMessage, +} from '../actions/signMessage.js' +import type { Config } from '../createConfig.js' +import type { Compute } from '../types/utils.js' +import type { Mutate, MutateAsync } from './types.js' + +export function signMessageMutationOptions(config: Config) { + return { + mutationFn(variables) { + return signMessage(config, variables) + }, + mutationKey: ['signMessage'], + } as const satisfies MutationOptions< + SignMessageData, + SignMessageErrorType, + SignMessageVariables + > +} + +export type SignMessageData = SignMessageReturnType + +export type SignMessageVariables = Compute + +export type SignMessageMutate = Mutate< + SignMessageData, + SignMessageErrorType, + SignMessageVariables, + context +> + +export type SignMessageMutateAsync = MutateAsync< + SignMessageData, + SignMessageErrorType, + SignMessageVariables, + context +> diff --git a/wagmi-project/packages/core/src/query/signTypedData.test.ts b/wagmi-project/packages/core/src/query/signTypedData.test.ts new file mode 100644 index 0000000000..02cbb66480 --- /dev/null +++ b/wagmi-project/packages/core/src/query/signTypedData.test.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { signTypedDataMutationOptions } from './signTypedData.js' + +test('default', () => { + expect(signTypedDataMutationOptions(config)).toMatchInlineSnapshot(` + { + "mutationFn": [Function], + "mutationKey": [ + "signTypedData", + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/signTypedData.ts b/wagmi-project/packages/core/src/query/signTypedData.ts new file mode 100644 index 0000000000..fe8eeb0268 --- /dev/null +++ b/wagmi-project/packages/core/src/query/signTypedData.ts @@ -0,0 +1,75 @@ +import type { MutateOptions, MutationOptions } from '@tanstack/query-core' + +import type { TypedData } from 'viem' +import { + type SignTypedDataErrorType, + type SignTypedDataParameters, + type SignTypedDataReturnType, + signTypedData, +} from '../actions/signTypedData.js' +import type { Config } from '../createConfig.js' +import type { Compute } from '../types/utils.js' + +export function signTypedDataMutationOptions( + config: config, +) { + return { + mutationFn(variables) { + return signTypedData(config, variables) + }, + mutationKey: ['signTypedData'], + } as const satisfies MutationOptions< + SignTypedDataData, + SignTypedDataErrorType, + SignTypedDataVariables + > +} + +export type SignTypedDataData = Compute + +export type SignTypedDataVariables< + typedData extends TypedData | Record = TypedData, + primaryType extends keyof typedData | 'EIP712Domain' = keyof typedData, + /// + primaryTypes = typedData extends TypedData ? keyof typedData : string, +> = SignTypedDataParameters + +export type SignTypedDataMutate = < + const typedData extends TypedData | Record, + primaryType extends keyof typedData | 'EIP712Domain', +>( + variables: SignTypedDataVariables, + options?: + | MutateOptions< + SignTypedDataData, + SignTypedDataErrorType, + SignTypedDataVariables< + typedData, + primaryType, + // use `primaryType` to make sure it's not union of all possible primary types + primaryType + >, + context + > + | undefined, +) => void + +export type SignTypedDataMutateAsync = < + const typedData extends TypedData | Record, + primaryType extends keyof typedData | 'EIP712Domain', +>( + variables: SignTypedDataVariables, + options?: + | MutateOptions< + SignTypedDataData, + SignTypedDataErrorType, + SignTypedDataVariables< + typedData, + primaryType, + // use `primaryType` to make sure it's not union of all possible primary types + primaryType + >, + context + > + | undefined, +) => Promise diff --git a/wagmi-project/packages/core/src/query/simulateContract.test-d.ts b/wagmi-project/packages/core/src/query/simulateContract.test-d.ts new file mode 100644 index 0000000000..11023e7297 --- /dev/null +++ b/wagmi-project/packages/core/src/query/simulateContract.test-d.ts @@ -0,0 +1,81 @@ +import { abi } from '@wagmi/test' +import { http, type Address } from 'viem' +import { celo, mainnet } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { createConfig } from '../createConfig.js' +import { + type SimulateContractOptions, + simulateContractQueryOptions, +} from './simulateContract.js' + +test('chain formatters', () => { + const config = createConfig({ + chains: [mainnet, celo], + transports: { [celo.id]: http(), [mainnet.id]: http() }, + }) + + type Result = SimulateContractOptions< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof config, + (typeof config)['chains'][number]['id'] + > + expectTypeOf().toMatchTypeOf<{ + chainId?: typeof celo.id | typeof mainnet.id | undefined + feeCurrency?: `0x${string}` | undefined + }>() + simulateContractQueryOptions(config, { + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + feeCurrency: '0x', + }) + + type Result2 = SimulateContractOptions< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof config, + typeof celo.id + > + expectTypeOf().toMatchTypeOf<{ + functionName?: 'approve' | 'transfer' | 'transferFrom' | undefined + args?: readonly [Address, Address, bigint] | undefined + feeCurrency?: `0x${string}` | undefined + }>() + simulateContractQueryOptions(config, { + chainId: celo.id, + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + feeCurrency: '0x', + }) + + type Result3 = SimulateContractOptions< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof config, + typeof mainnet.id + > + expectTypeOf().toMatchTypeOf<{ + functionName?: 'approve' | 'transfer' | 'transferFrom' | undefined + args?: readonly [Address, Address, bigint] | undefined + }>() + expectTypeOf().not.toMatchTypeOf<{ + feeCurrency?: `0x${string}` | undefined + }>() + simulateContractQueryOptions(config, { + chainId: mainnet.id, + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + // @ts-expect-error + feeCurrency: '0x', + }) +}) diff --git a/wagmi-project/packages/core/src/query/simulateContract.test.ts b/wagmi-project/packages/core/src/query/simulateContract.test.ts new file mode 100644 index 0000000000..354e4b0f02 --- /dev/null +++ b/wagmi-project/packages/core/src/query/simulateContract.test.ts @@ -0,0 +1,31 @@ +import { abi, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { simulateContractQueryOptions } from './simulateContract.js' + +test('default', () => { + expect( + simulateContractQueryOptions(config, { + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "simulateContract", + { + "address": "0x", + "args": [ + "0x", + "0x", + 123n, + ], + "functionName": "transferFrom", + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/simulateContract.ts b/wagmi-project/packages/core/src/query/simulateContract.ts new file mode 100644 index 0000000000..c3970999d4 --- /dev/null +++ b/wagmi-project/packages/core/src/query/simulateContract.ts @@ -0,0 +1,132 @@ +import type { QueryOptions } from '@tanstack/query-core' +import type { Abi, ContractFunctionArgs, ContractFunctionName } from 'viem' + +import { + type SimulateContractErrorType, + type SimulateContractParameters, + type SimulateContractReturnType, + simulateContract, +} from '../actions/simulateContract.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { UnionExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type SimulateContractOptions< + abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + >, + config extends Config, + chainId extends config['chains'][number]['id'] | undefined, +> = UnionExactPartial< + SimulateContractParameters +> & + ScopeKeyParameter + +export function simulateContractQueryOptions< + config extends Config, + const abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + >, + chainId extends config['chains'][number]['id'] | undefined, +>( + config: config, + options: SimulateContractOptions< + abi, + functionName, + args, + config, + chainId + > = {} as any, +) { + return { + async queryFn({ queryKey }) { + const { abi, connector } = options + if (!abi) throw new Error('abi is required') + const { scopeKey: _, ...parameters } = queryKey[1] + const { address, functionName } = parameters + if (!address) throw new Error('address is required') + if (!functionName) throw new Error('functionName is required') + return simulateContract(config, { + abi, + connector, + ...(parameters as any), + }) + }, + queryKey: simulateContractQueryKey(options), + } as const satisfies QueryOptions< + SimulateContractQueryFnData, + SimulateContractErrorType, + SimulateContractData, + SimulateContractQueryKey + > +} + +export type SimulateContractQueryFnData< + abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + >, + config extends Config, + chainId extends config['chains'][number]['id'] | undefined, +> = SimulateContractReturnType + +export type SimulateContractData< + abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + >, + config extends Config, + chainId extends config['chains'][number]['id'] | undefined, +> = SimulateContractQueryFnData + +export function simulateContractQueryKey< + config extends Config, + abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + >, + chainId extends config['chains'][number]['id'] | undefined, +>( + options: SimulateContractOptions< + abi, + functionName, + args, + config, + chainId + > = {} as any, +) { + const { abi: _, connector: _c, ...rest } = options + return ['simulateContract', filterQueryOptions(rest)] as const +} + +export type SimulateContractQueryKey< + abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + >, + config extends Config, + chainId extends config['chains'][number]['id'] | undefined, +> = ReturnType< + typeof simulateContractQueryKey +> diff --git a/wagmi-project/packages/core/src/query/switchAccount.test.ts b/wagmi-project/packages/core/src/query/switchAccount.test.ts new file mode 100644 index 0000000000..25a7066c61 --- /dev/null +++ b/wagmi-project/packages/core/src/query/switchAccount.test.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { switchAccountMutationOptions } from './switchAccount.js' + +test('default', () => { + expect(switchAccountMutationOptions(config)).toMatchInlineSnapshot(` + { + "mutationFn": [Function], + "mutationKey": [ + "switchAccount", + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/switchAccount.ts b/wagmi-project/packages/core/src/query/switchAccount.ts new file mode 100644 index 0000000000..29a10b2ce8 --- /dev/null +++ b/wagmi-project/packages/core/src/query/switchAccount.ts @@ -0,0 +1,52 @@ +import type { MutationOptions } from '@tanstack/query-core' + +import { + type SwitchAccountErrorType, + type SwitchAccountParameters, + type SwitchAccountReturnType, + switchAccount, +} from '../actions/switchAccount.js' +import type { Config } from '../createConfig.js' +import type { Compute } from '../types/utils.js' +import type { Mutate, MutateAsync } from './types.js' + +export function switchAccountMutationOptions( + config: config, +) { + return { + mutationFn(variables) { + return switchAccount(config, variables) + }, + mutationKey: ['switchAccount'], + } as const satisfies MutationOptions< + SwitchAccountData, + SwitchAccountErrorType, + SwitchAccountVariables + > +} + +export type SwitchAccountData = Compute< + SwitchAccountReturnType +> + +export type SwitchAccountVariables = Compute + +export type SwitchAccountMutate< + config extends Config, + context = unknown, +> = Mutate< + SwitchAccountData, + SwitchAccountErrorType, + SwitchAccountVariables, + context +> + +export type SwitchAccountMutateAsync< + config extends Config, + context = unknown, +> = MutateAsync< + SwitchAccountData, + SwitchAccountErrorType, + SwitchAccountVariables, + context +> diff --git a/wagmi-project/packages/core/src/query/switchChain.test.ts b/wagmi-project/packages/core/src/query/switchChain.test.ts new file mode 100644 index 0000000000..09a4277c20 --- /dev/null +++ b/wagmi-project/packages/core/src/query/switchChain.test.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { switchChainMutationOptions } from './switchChain.js' + +test('default', () => { + expect(switchChainMutationOptions(config)).toMatchInlineSnapshot(` + { + "mutationFn": [Function], + "mutationKey": [ + "switchChain", + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/switchChain.ts b/wagmi-project/packages/core/src/query/switchChain.ts new file mode 100644 index 0000000000..1924ca8429 --- /dev/null +++ b/wagmi-project/packages/core/src/query/switchChain.ts @@ -0,0 +1,67 @@ +import type { MutateOptions, MutationOptions } from '@tanstack/query-core' + +import { + type SwitchChainErrorType, + type SwitchChainParameters, + type SwitchChainReturnType, + switchChain, +} from '../actions/switchChain.js' +import type { Config } from '../createConfig.js' +import type { Compute } from '../types/utils.js' + +export function switchChainMutationOptions( + config: config, +) { + return { + mutationFn(variables) { + return switchChain(config, variables) + }, + mutationKey: ['switchChain'], + } as const satisfies MutationOptions< + SwitchChainData, + SwitchChainErrorType, + SwitchChainVariables + > +} + +export type SwitchChainData< + config extends Config, + chainId extends config['chains'][number]['id'], +> = Compute> + +export type SwitchChainVariables< + config extends Config, + chainId extends config['chains'][number]['id'], +> = Compute> + +export type SwitchChainMutate = < + chainId extends config['chains'][number]['id'], +>( + variables: SwitchChainVariables, + options?: + | Compute< + MutateOptions< + SwitchChainData, + SwitchChainErrorType, + Compute>, + context + > + > + | undefined, +) => void + +export type SwitchChainMutateAsync = < + chainId extends config['chains'][number]['id'], +>( + variables: SwitchChainVariables, + options?: + | Compute< + MutateOptions< + SwitchChainData, + SwitchChainErrorType, + Compute>, + context + > + > + | undefined, +) => Promise> diff --git a/wagmi-project/packages/core/src/query/types.ts b/wagmi-project/packages/core/src/query/types.ts new file mode 100644 index 0000000000..6a279d52d5 --- /dev/null +++ b/wagmi-project/packages/core/src/query/types.ts @@ -0,0 +1,84 @@ +import type { + DefaultError, + InfiniteQueryObserverOptions, + MutateOptions, + QueryFunction, + QueryKey, +} from '@tanstack/query-core' + +import type { Compute, StrictOmit } from '../types/utils.js' + +export type InfiniteQueryOptions< + queryFnData = unknown, + error = DefaultError, + data = queryFnData, + queryData = queryFnData, + queryKey extends QueryKey = QueryKey, + pageParam = unknown, + /// + options extends InfiniteQueryObserverOptions< + queryFnData, + error, + data, + queryData, + queryKey, + pageParam + > = InfiniteQueryObserverOptions< + queryFnData, + error, + data, + queryData, + queryKey, + pageParam + >, +> = Compute< + // `queryFn` doesn't pass through `pageParam` correctly + StrictOmit & { + queryFn?( + context: QueryFunctionContext, + ): options['queryFn'] extends (...args: any) => any + ? ReturnType> + : unknown + } +> + +// `QueryFunctionContext` not exported resulting in TS2742 error so grabbing from `QueryFunction` +type QueryFunctionContext< + TQueryKey extends QueryKey = QueryKey, + TPageParam = never, +> = Parameters>[0] + +export type Mutate< + data = unknown, + error = unknown, + variables = void, + context = unknown, +> = ( + ...args: Parameters, context>> +) => void + +export type MutateAsync< + data = unknown, + error = unknown, + variables = void, + context = unknown, +> = MutateFn, context> + +type MutateFn< + data = unknown, + error = unknown, + variables = void, + context = unknown, +> = undefined extends variables + ? ( + variables?: variables, + options?: + | Compute> + | undefined, + ) => Promise + : ( + variables: variables, + options?: + | Compute> + | undefined, + ) => Promise diff --git a/wagmi-project/packages/core/src/query/utils.test.ts b/wagmi-project/packages/core/src/query/utils.test.ts new file mode 100644 index 0000000000..920b2e5f37 --- /dev/null +++ b/wagmi-project/packages/core/src/query/utils.test.ts @@ -0,0 +1,20 @@ +import { expect, test } from 'vitest' + +import { structuralSharing } from './utils.js' + +test('structuralSharing', () => { + expect( + structuralSharing({ foo: 'bar' }, { foo: 'bar' }), + ).toMatchInlineSnapshot(` + { + "foo": "bar", + } + `) + expect( + structuralSharing({ foo: 'bar' }, { foo: 'baz' }), + ).toMatchInlineSnapshot(` + { + "foo": "baz", + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/utils.ts b/wagmi-project/packages/core/src/query/utils.ts new file mode 100644 index 0000000000..ab4ea3b989 --- /dev/null +++ b/wagmi-project/packages/core/src/query/utils.ts @@ -0,0 +1,73 @@ +import { type QueryKey, replaceEqualDeep } from '@tanstack/query-core' + +export function structuralSharing( + oldData: data | undefined, + newData: data, +): data { + return replaceEqualDeep(oldData, newData) +} + +export function hashFn(queryKey: QueryKey): string { + return JSON.stringify(queryKey, (_, value) => { + if (isPlainObject(value)) + return Object.keys(value) + .sort() + .reduce((result, key) => { + result[key] = value[key] + return result + }, {} as any) + if (typeof value === 'bigint') return value.toString() + return value + }) +} + +// biome-ignore lint/complexity/noBannedTypes: +function isPlainObject(value: any): value is Object { + if (!hasObjectPrototype(value)) { + return false + } + + // If has modified constructor + const ctor = value.constructor + if (typeof ctor === 'undefined') return true + + // If has modified prototype + const prot = ctor.prototype + if (!hasObjectPrototype(prot)) return false + + // If constructor does not have an Object-specific method + // biome-ignore lint/suspicious/noPrototypeBuiltins: + if (!prot.hasOwnProperty('isPrototypeOf')) return false + + // Most likely a plain Object + return true +} + +function hasObjectPrototype(o: any): boolean { + return Object.prototype.toString.call(o) === '[object Object]' +} + +export function filterQueryOptions>( + options: type, +): type { + // destructuring is super fast + // biome-ignore format: no formatting + const { + // import('@tanstack/query-core').QueryOptions + _defaulted, behavior, gcTime, initialData, initialDataUpdatedAt, maxPages, meta, networkMode, queryFn, queryHash, queryKey, queryKeyHashFn, retry, retryDelay, structuralSharing, + + // import('@tanstack/query-core').InfiniteQueryObserverOptions + getPreviousPageParam, getNextPageParam, initialPageParam, + + // import('@tanstack/react-query').UseQueryOptions + _optimisticResults, enabled, notifyOnChangeProps, placeholderData, refetchInterval, refetchIntervalInBackground, refetchOnMount, refetchOnReconnect, refetchOnWindowFocus, retryOnMount, select, staleTime, suspense, throwOnError, + + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // wagmi + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + config, connector, query, + ...rest + } = options + + return rest as type +} diff --git a/wagmi-project/packages/core/src/query/verifyMessage.test.ts b/wagmi-project/packages/core/src/query/verifyMessage.test.ts new file mode 100644 index 0000000000..ae43f6b07f --- /dev/null +++ b/wagmi-project/packages/core/src/query/verifyMessage.test.ts @@ -0,0 +1,104 @@ +import { accounts, chain, config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { verifyMessageQueryOptions } from './verifyMessage.js' + +const address = accounts[0] + +test('default', () => { + expect( + verifyMessageQueryOptions(config, { + address, + message: 'This is a test message for viem!', + signature: + '0xefd5fb29a274ea6682673d8b3caa9263e936d48d486e5df68893003e0a76496439594d12245008c6fba1c8e3ef28241cffe1bef27ff6bca487b167f261f329251c', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "verifyMessage", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "message": "This is a test message for viem!", + "signature": "0xefd5fb29a274ea6682673d8b3caa9263e936d48d486e5df68893003e0a76496439594d12245008c6fba1c8e3ef28241cffe1bef27ff6bca487b167f261f329251c", + }, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + verifyMessageQueryOptions(config, { + chainId: chain.mainnet2.id, + address, + message: 'This is a test message for viem!', + signature: + '0xefd5fb29a274ea6682673d8b3caa9263e936d48d486e5df68893003e0a76496439594d12245008c6fba1c8e3ef28241cffe1bef27ff6bca487b167f261f329251c', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "verifyMessage", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 456, + "message": "This is a test message for viem!", + "signature": "0xefd5fb29a274ea6682673d8b3caa9263e936d48d486e5df68893003e0a76496439594d12245008c6fba1c8e3ef28241cffe1bef27ff6bca487b167f261f329251c", + }, + ], + } + `) +}) + +test('parameters: blockNumber', () => { + expect( + verifyMessageQueryOptions(config, { + blockNumber: 1234567890n, + address, + message: 'This is a test message for viem!', + signature: + '0xefd5fb29a274ea6682673d8b3caa9263e936d48d486e5df68893003e0a76496439594d12245008c6fba1c8e3ef28241cffe1bef27ff6bca487b167f261f329251c', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "verifyMessage", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "blockNumber": 1234567890n, + "message": "This is a test message for viem!", + "signature": "0xefd5fb29a274ea6682673d8b3caa9263e936d48d486e5df68893003e0a76496439594d12245008c6fba1c8e3ef28241cffe1bef27ff6bca487b167f261f329251c", + }, + ], + } + `) +}) + +test('parameters: blockTag', () => { + expect( + verifyMessageQueryOptions(config, { + blockTag: 'safe', + address, + message: 'This is a test message for viem!', + signature: + '0xefd5fb29a274ea6682673d8b3caa9263e936d48d486e5df68893003e0a76496439594d12245008c6fba1c8e3ef28241cffe1bef27ff6bca487b167f261f329251c', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "verifyMessage", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "blockTag": "safe", + "message": "This is a test message for viem!", + "signature": "0xefd5fb29a274ea6682673d8b3caa9263e936d48d486e5df68893003e0a76496439594d12245008c6fba1c8e3ef28241cffe1bef27ff6bca487b167f261f329251c", + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/verifyMessage.ts b/wagmi-project/packages/core/src/query/verifyMessage.ts new file mode 100644 index 0000000000..d827e64b2b --- /dev/null +++ b/wagmi-project/packages/core/src/query/verifyMessage.ts @@ -0,0 +1,56 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type VerifyMessageErrorType, + type VerifyMessageParameters, + type VerifyMessageReturnType, + verifyMessage, +} from '../actions/verifyMessage.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type VerifyMessageOptions = Compute< + ExactPartial> & ScopeKeyParameter +> + +export function verifyMessageQueryOptions( + config: config, + options: VerifyMessageOptions = {}, +) { + return { + async queryFn({ queryKey }) { + const { address, message, signature } = queryKey[1] + if (!address || !message || !signature) + throw new Error('address, message, and signature are required') + + const { scopeKey: _, ...parameters } = queryKey[1] + + const verified = await verifyMessage( + config, + parameters as VerifyMessageParameters, + ) + return verified ?? null + }, + queryKey: verifyMessageQueryKey(options), + } as const satisfies QueryOptions< + VerifyMessageQueryFnData, + VerifyMessageErrorType, + VerifyMessageData, + VerifyMessageQueryKey + > +} +export type VerifyMessageQueryFnData = VerifyMessageReturnType + +export type VerifyMessageData = VerifyMessageQueryFnData + +export function verifyMessageQueryKey( + options: VerifyMessageOptions, +) { + return ['verifyMessage', filterQueryOptions(options)] as const +} + +export type VerifyMessageQueryKey = ReturnType< + typeof verifyMessageQueryKey +> diff --git a/wagmi-project/packages/core/src/query/verifyTypedData.test.ts b/wagmi-project/packages/core/src/query/verifyTypedData.test.ts new file mode 100644 index 0000000000..f4145099ce --- /dev/null +++ b/wagmi-project/packages/core/src/query/verifyTypedData.test.ts @@ -0,0 +1,284 @@ +import { accounts, chain, config, typedData } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { verifyTypedDataQueryOptions } from './verifyTypedData.js' + +const address = accounts[0] + +test('default', () => { + expect( + verifyTypedDataQueryOptions(config, { + address, + ...typedData.basic, + primaryType: 'Mail', + signature: + '0xefd5fb29a274ea6682673d8b3caa9263e936d48d486e5df68893003e0a76496439594d12245008c6fba1c8e3ef28241cffe1bef27ff6bca487b167f261f329251c', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "verifyTypedData", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "domain": { + "chainId": 1, + "name": "Ether Mail", + "verifyingContract": "0x0000000000000000000000000000000000000000", + "version": "1", + }, + "message": { + "contents": "Hello, Bob!", + "from": { + "name": "Cow", + "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826", + }, + "to": { + "name": "Bob", + "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB", + }, + }, + "primaryType": "Mail", + "signature": "0xefd5fb29a274ea6682673d8b3caa9263e936d48d486e5df68893003e0a76496439594d12245008c6fba1c8e3ef28241cffe1bef27ff6bca487b167f261f329251c", + "types": { + "Mail": [ + { + "name": "from", + "type": "Person", + }, + { + "name": "to", + "type": "Person", + }, + { + "name": "contents", + "type": "string", + }, + ], + "Person": [ + { + "name": "name", + "type": "string", + }, + { + "name": "wallet", + "type": "address", + }, + ], + }, + }, + ], + } + `) +}) + +test('parameters: chainId', () => { + expect( + verifyTypedDataQueryOptions(config, { + ...typedData.basic, + domain: { + ...typedData.basic.domain, + chainId: chain.mainnet2.id, + }, + chainId: chain.mainnet2.id, + address, + primaryType: 'Mail', + signature: + '0xefd5fb29a274ea6682673d8b3caa9263e936d48d486e5df68893003e0a76496439594d12245008c6fba1c8e3ef28241cffe1bef27ff6bca487b167f261f329251c', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "verifyTypedData", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 456, + "domain": { + "chainId": 456, + "name": "Ether Mail", + "verifyingContract": "0x0000000000000000000000000000000000000000", + "version": "1", + }, + "message": { + "contents": "Hello, Bob!", + "from": { + "name": "Cow", + "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826", + }, + "to": { + "name": "Bob", + "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB", + }, + }, + "primaryType": "Mail", + "signature": "0xefd5fb29a274ea6682673d8b3caa9263e936d48d486e5df68893003e0a76496439594d12245008c6fba1c8e3ef28241cffe1bef27ff6bca487b167f261f329251c", + "types": { + "Mail": [ + { + "name": "from", + "type": "Person", + }, + { + "name": "to", + "type": "Person", + }, + { + "name": "contents", + "type": "string", + }, + ], + "Person": [ + { + "name": "name", + "type": "string", + }, + { + "name": "wallet", + "type": "address", + }, + ], + }, + }, + ], + } + `) +}) + +test('parameters: blockNumber', () => { + expect( + verifyTypedDataQueryOptions(config, { + blockNumber: 1234567890n, + address, + ...typedData.basic, + primaryType: 'Mail', + signature: + '0xefd5fb29a274ea6682673d8b3caa9263e936d48d486e5df68893003e0a76496439594d12245008c6fba1c8e3ef28241cffe1bef27ff6bca487b167f261f329251c', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "verifyTypedData", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "blockNumber": 1234567890n, + "domain": { + "chainId": 1, + "name": "Ether Mail", + "verifyingContract": "0x0000000000000000000000000000000000000000", + "version": "1", + }, + "message": { + "contents": "Hello, Bob!", + "from": { + "name": "Cow", + "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826", + }, + "to": { + "name": "Bob", + "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB", + }, + }, + "primaryType": "Mail", + "signature": "0xefd5fb29a274ea6682673d8b3caa9263e936d48d486e5df68893003e0a76496439594d12245008c6fba1c8e3ef28241cffe1bef27ff6bca487b167f261f329251c", + "types": { + "Mail": [ + { + "name": "from", + "type": "Person", + }, + { + "name": "to", + "type": "Person", + }, + { + "name": "contents", + "type": "string", + }, + ], + "Person": [ + { + "name": "name", + "type": "string", + }, + { + "name": "wallet", + "type": "address", + }, + ], + }, + }, + ], + } + `) +}) + +test('parameters: blockTag', () => { + expect( + verifyTypedDataQueryOptions(config, { + blockTag: 'pending', + address, + ...typedData.basic, + primaryType: 'Mail', + signature: + '0xefd5fb29a274ea6682673d8b3caa9263e936d48d486e5df68893003e0a76496439594d12245008c6fba1c8e3ef28241cffe1bef27ff6bca487b167f261f329251c', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "verifyTypedData", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "blockTag": "pending", + "domain": { + "chainId": 1, + "name": "Ether Mail", + "verifyingContract": "0x0000000000000000000000000000000000000000", + "version": "1", + }, + "message": { + "contents": "Hello, Bob!", + "from": { + "name": "Cow", + "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826", + }, + "to": { + "name": "Bob", + "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB", + }, + }, + "primaryType": "Mail", + "signature": "0xefd5fb29a274ea6682673d8b3caa9263e936d48d486e5df68893003e0a76496439594d12245008c6fba1c8e3ef28241cffe1bef27ff6bca487b167f261f329251c", + "types": { + "Mail": [ + { + "name": "from", + "type": "Person", + }, + { + "name": "to", + "type": "Person", + }, + { + "name": "contents", + "type": "string", + }, + ], + "Person": [ + { + "name": "name", + "type": "string", + }, + { + "name": "wallet", + "type": "address", + }, + ], + }, + }, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/verifyTypedData.ts b/wagmi-project/packages/core/src/query/verifyTypedData.ts new file mode 100644 index 0000000000..d7d3970b7e --- /dev/null +++ b/wagmi-project/packages/core/src/query/verifyTypedData.ts @@ -0,0 +1,82 @@ +import type { QueryOptions } from '@tanstack/query-core' +import type { TypedData } from 'viem' + +import { + type VerifyTypedDataErrorType, + type VerifyTypedDataParameters, + type VerifyTypedDataReturnType, + verifyTypedData, +} from '../actions/verifyTypedData.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type VerifyTypedDataOptions< + typedData extends TypedData | Record, + primaryType extends keyof typedData | 'EIP712Domain', + config extends Config, +> = ExactPartial> & + ScopeKeyParameter + +export function verifyTypedDataQueryOptions< + config extends Config, + const typedData extends TypedData | Record, + primaryType extends keyof typedData | 'EIP712Domain', +>( + config: config, + options: VerifyTypedDataOptions = {} as any, +) { + return { + async queryFn({ queryKey }) { + const { + address, + message, + primaryType, + signature, + types, + scopeKey: _, + ...parameters + } = queryKey[1] + if (!address) throw new Error('address is required') + if (!message) throw new Error('message is required') + if (!primaryType) throw new Error('primaryType is required') + if (!signature) throw new Error('signature is required') + if (!types) throw new Error('types is required') + + const verified = await verifyTypedData(config, { + ...parameters, + address, + message, + primaryType, + signature, + types, + } as VerifyTypedDataParameters) + return verified ?? null + }, + queryKey: verifyTypedDataQueryKey(options), + } as const satisfies QueryOptions< + VerifyTypedDataQueryFnData, + VerifyTypedDataErrorType, + VerifyTypedDataData, + VerifyTypedDataQueryKey + > +} + +export type VerifyTypedDataQueryFnData = VerifyTypedDataReturnType + +export type VerifyTypedDataData = VerifyTypedDataQueryFnData + +export function verifyTypedDataQueryKey< + config extends Config, + const typedData extends TypedData | Record, + primaryType extends keyof typedData | 'EIP712Domain', +>(options: VerifyTypedDataOptions) { + return ['verifyTypedData', filterQueryOptions(options)] as const +} + +export type VerifyTypedDataQueryKey< + typedData extends TypedData | Record, + primaryType extends keyof typedData | 'EIP712Domain', + config extends Config, +> = ReturnType> diff --git a/wagmi-project/packages/core/src/query/waitForCallsStatus.test.ts b/wagmi-project/packages/core/src/query/waitForCallsStatus.test.ts new file mode 100644 index 0000000000..215ec72759 --- /dev/null +++ b/wagmi-project/packages/core/src/query/waitForCallsStatus.test.ts @@ -0,0 +1,23 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { waitForCallsStatusQueryOptions } from './waitForCallsStatus.js' + +test('default', () => { + expect( + waitForCallsStatusQueryOptions(config, { + id: '0x0000000000000000000000000000000000000000', + }), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "callsStatus", + { + "id": "0x0000000000000000000000000000000000000000", + }, + ], + "retry": [Function], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/waitForCallsStatus.ts b/wagmi-project/packages/core/src/query/waitForCallsStatus.ts new file mode 100644 index 0000000000..197c279e93 --- /dev/null +++ b/wagmi-project/packages/core/src/query/waitForCallsStatus.ts @@ -0,0 +1,53 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type WaitForCallsStatusErrorType, + type WaitForCallsStatusParameters, + type WaitForCallsStatusReturnType, + waitForCallsStatus, +} from '../actions/waitForCallsStatus.js' +import type { Config } from '../createConfig.js' +import { ConnectorNotConnectedError } from '../errors/config.js' +import { filterQueryOptions } from '../query/utils.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, PartialBy } from '../types/utils.js' + +export type WaitForCallsStatusOptions = Compute< + PartialBy & ScopeKeyParameter +> + +export function waitForCallsStatusQueryOptions( + config: config, + options: WaitForCallsStatusOptions, +) { + return { + async queryFn({ queryKey }) { + const { scopeKey: _, id, ...parameters } = queryKey[1] + if (!id) throw new Error('id is required') + const status = await waitForCallsStatus(config, { ...parameters, id }) + return status + }, + queryKey: waitForCallsStatusQueryKey(options), + retry(failureCount, error) { + if (error instanceof ConnectorNotConnectedError) return false + return failureCount < 3 + }, + } as const satisfies QueryOptions< + WaitForCallsStatusQueryFnData, + WaitForCallsStatusErrorType, + WaitForCallsStatusData, + WaitForCallsStatusQueryKey + > +} + +export type WaitForCallsStatusQueryFnData = WaitForCallsStatusReturnType + +export type WaitForCallsStatusData = WaitForCallsStatusQueryFnData + +export function waitForCallsStatusQueryKey(options: WaitForCallsStatusOptions) { + return ['callsStatus', filterQueryOptions(options)] as const +} + +export type WaitForCallsStatusQueryKey = ReturnType< + typeof waitForCallsStatusQueryKey +> diff --git a/wagmi-project/packages/core/src/query/waitForTransactionReceipt.test.ts b/wagmi-project/packages/core/src/query/waitForTransactionReceipt.test.ts new file mode 100644 index 0000000000..1877e1bfeb --- /dev/null +++ b/wagmi-project/packages/core/src/query/waitForTransactionReceipt.test.ts @@ -0,0 +1,18 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { waitForTransactionReceiptQueryOptions } from './waitForTransactionReceipt.js' + +test('default', () => { + expect( + waitForTransactionReceiptQueryOptions(config, {}), + ).toMatchInlineSnapshot(` + { + "queryFn": [Function], + "queryKey": [ + "waitForTransactionReceipt", + {}, + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/waitForTransactionReceipt.ts b/wagmi-project/packages/core/src/query/waitForTransactionReceipt.ts new file mode 100644 index 0000000000..3507dabeb8 --- /dev/null +++ b/wagmi-project/packages/core/src/query/waitForTransactionReceipt.ts @@ -0,0 +1,71 @@ +import type { QueryOptions } from '@tanstack/query-core' + +import { + type WaitForTransactionReceiptErrorType, + type WaitForTransactionReceiptParameters, + type WaitForTransactionReceiptReturnType, + waitForTransactionReceipt, +} from '../actions/waitForTransactionReceipt.js' +import type { Config } from '../createConfig.js' +import type { ScopeKeyParameter } from '../types/properties.js' +import type { Compute, ExactPartial } from '../types/utils.js' +import { filterQueryOptions } from './utils.js' + +export type WaitForTransactionReceiptOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +> = Compute< + ExactPartial> & + ScopeKeyParameter +> + +export function waitForTransactionReceiptQueryOptions< + config extends Config, + chainId extends config['chains'][number]['id'], +>( + config: config, + options: WaitForTransactionReceiptOptions = {}, +) { + return { + async queryFn({ queryKey }) { + const { hash, ...parameters } = queryKey[1] + if (!hash) throw new Error('hash is required') + return waitForTransactionReceipt(config, { + ...parameters, + onReplaced: options.onReplaced, + hash, + }) as unknown as Promise< + WaitForTransactionReceiptReturnType + > + }, + queryKey: waitForTransactionReceiptQueryKey(options), + } as const satisfies QueryOptions< + WaitForTransactionReceiptQueryFnData, + WaitForTransactionReceiptErrorType, + WaitForTransactionReceiptData, + WaitForTransactionReceiptQueryKey + > +} + +export type WaitForTransactionReceiptQueryFnData< + config extends Config, + chainId extends config['chains'][number]['id'], +> = WaitForTransactionReceiptReturnType + +export type WaitForTransactionReceiptData< + config extends Config, + chainId extends config['chains'][number]['id'], +> = WaitForTransactionReceiptQueryFnData + +export function waitForTransactionReceiptQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], +>(options: WaitForTransactionReceiptOptions = {}) { + const { onReplaced: _, ...rest } = options + return ['waitForTransactionReceipt', filterQueryOptions(rest)] as const +} + +export type WaitForTransactionReceiptQueryKey< + config extends Config, + chainId extends config['chains'][number]['id'], +> = ReturnType> diff --git a/wagmi-project/packages/core/src/query/watchAsset.test.ts b/wagmi-project/packages/core/src/query/watchAsset.test.ts new file mode 100644 index 0000000000..b580beadba --- /dev/null +++ b/wagmi-project/packages/core/src/query/watchAsset.test.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { watchAssetMutationOptions } from './watchAsset.js' + +test('default', () => { + expect(watchAssetMutationOptions(config)).toMatchInlineSnapshot(` + { + "mutationFn": [Function], + "mutationKey": [ + "watchAsset", + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/watchAsset.ts b/wagmi-project/packages/core/src/query/watchAsset.ts new file mode 100644 index 0000000000..52ab82be60 --- /dev/null +++ b/wagmi-project/packages/core/src/query/watchAsset.ts @@ -0,0 +1,42 @@ +import type { MutationOptions } from '@tanstack/query-core' + +import { + type WatchAssetErrorType, + type WatchAssetParameters, + type WatchAssetReturnType, + watchAsset, +} from '../actions/watchAsset.js' +import type { Config } from '../createConfig.js' +import type { Compute } from '../types/utils.js' +import type { Mutate, MutateAsync } from './types.js' + +export function watchAssetMutationOptions(config: Config) { + return { + mutationFn(variables) { + return watchAsset(config, variables) + }, + mutationKey: ['watchAsset'], + } as const satisfies MutationOptions< + WatchAssetData, + WatchAssetErrorType, + WatchAssetVariables + > +} + +export type WatchAssetData = WatchAssetReturnType + +export type WatchAssetVariables = Compute + +export type WatchAssetMutate = Mutate< + WatchAssetData, + WatchAssetErrorType, + WatchAssetVariables, + context +> + +export type WatchAssetMutateAsync = MutateAsync< + WatchAssetData, + WatchAssetErrorType, + WatchAssetVariables, + context +> diff --git a/wagmi-project/packages/core/src/query/writeContract.test-d.ts b/wagmi-project/packages/core/src/query/writeContract.test-d.ts new file mode 100644 index 0000000000..3c80a83132 --- /dev/null +++ b/wagmi-project/packages/core/src/query/writeContract.test-d.ts @@ -0,0 +1,145 @@ +import { http } from 'viem' +import { writeContract } from 'viem/actions' +import { base } from 'viem/chains' +import { test } from 'vitest' + +import { createConfig } from '../createConfig.js' +import type { WriteContractMutate } from './writeContract.js' + +// https://github.com/wevm/wagmi/issues/3981 +test('gh#3981', () => { + const config = createConfig({ + chains: [base], + transports: { + [base.id]: http(), + }, + }) + + const abi = [ + { + type: 'function', + name: 'example1', + inputs: [ + { name: 'exampleName', type: 'address', internalType: 'address' }, + ], + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + name: 'example2', + inputs: [ + { name: 'exampleName', type: 'address', internalType: 'address' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + ] as const + + const write: WriteContractMutate = () => {} + write({ + abi, + address: '0x...', + functionName: 'example1', + args: ['0x...'], + value: 123n, + }) + write({ + abi: [ + { + type: 'function', + name: 'example1', + inputs: [ + { name: 'exampleName', type: 'address', internalType: 'address' }, + ], + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + name: 'example2', + inputs: [ + { name: 'exampleName', type: 'address', internalType: 'address' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + ] as const, + address: '0x...', + functionName: 'example1', + args: ['0x...'], + value: 123n, + }) + + write({ + abi, + address: '0x...', + functionName: 'example2', + args: ['0x...'], + // @ts-expect-error + value: 123n, + }) + write({ + abi: [ + { + type: 'function', + name: 'example1', + inputs: [ + { name: 'exampleName', type: 'address', internalType: 'address' }, + ], + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + name: 'example2', + inputs: [ + { name: 'exampleName', type: 'address', internalType: 'address' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + ], + address: '0x...', + functionName: 'example1', + args: ['0x...'], + value: 123n, + }) + + const client = config.getClient({ chainId: base.id }) + writeContract(client, { + abi, + address: '0x...', + account: '0x...', + functionName: 'example1', + args: ['0x...'], + value: 123n, + }) + writeContract(client, { + abi: [ + { + type: 'function', + name: 'example1', + inputs: [ + { name: 'exampleName', type: 'address', internalType: 'address' }, + ], + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + name: 'example2', + inputs: [ + { name: 'exampleName', type: 'address', internalType: 'address' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + ] as const, + address: '0x...', + account: '0x...', + functionName: 'example1', + args: ['0x...'], + value: 123n, + }) +}) diff --git a/wagmi-project/packages/core/src/query/writeContract.test.ts b/wagmi-project/packages/core/src/query/writeContract.test.ts new file mode 100644 index 0000000000..04cde53c76 --- /dev/null +++ b/wagmi-project/packages/core/src/query/writeContract.test.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expect, test } from 'vitest' + +import { writeContractMutationOptions } from './writeContract.js' + +test('default', () => { + expect(writeContractMutationOptions(config)).toMatchInlineSnapshot(` + { + "mutationFn": [Function], + "mutationKey": [ + "writeContract", + ], + } + `) +}) diff --git a/wagmi-project/packages/core/src/query/writeContract.ts b/wagmi-project/packages/core/src/query/writeContract.ts new file mode 100644 index 0000000000..0e368fe40b --- /dev/null +++ b/wagmi-project/packages/core/src/query/writeContract.ts @@ -0,0 +1,116 @@ +import type { MutateOptions, MutationOptions } from '@tanstack/query-core' +import type { Abi, ContractFunctionArgs, ContractFunctionName } from 'viem' + +import { + type WriteContractErrorType, + type WriteContractParameters, + type WriteContractReturnType, + writeContract, +} from '../actions/writeContract.js' +import type { Config } from '../createConfig.js' +import type { Compute } from '../types/utils.js' + +export function writeContractMutationOptions( + config: config, +) { + return { + mutationFn(variables) { + return writeContract(config, variables) + }, + mutationKey: ['writeContract'], + } as const satisfies MutationOptions< + WriteContractData, + WriteContractErrorType, + WriteContractVariables< + Abi, + string, + readonly unknown[], + config, + config['chains'][number]['id'] + > + > +} + +export type WriteContractData = Compute + +export type WriteContractVariables< + abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + >, + config extends Config, + chainId extends config['chains'][number]['id'], + /// + allFunctionNames = ContractFunctionName, +> = WriteContractParameters< + abi, + functionName, + args, + config, + chainId, + allFunctionNames +> + +export type WriteContractMutate = < + const abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + >, + chainId extends config['chains'][number]['id'], +>( + variables: WriteContractVariables, + options?: + | MutateOptions< + WriteContractData, + WriteContractErrorType, + WriteContractVariables< + abi, + functionName, + args, + config, + chainId, + // use `functionName` to make sure it's not union of all possible function names + functionName + >, + context + > + | undefined, +) => void + +export type WriteContractMutateAsync< + config extends Config, + context = unknown, +> = < + const abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + >, + chainId extends config['chains'][number]['id'], +>( + variables: WriteContractVariables, + options?: + | MutateOptions< + WriteContractData, + WriteContractErrorType, + WriteContractVariables< + abi, + functionName, + args, + config, + chainId, + // use `functionName` to make sure it's not union of all possible function names + functionName + >, + context + > + | undefined, +) => Promise diff --git a/wagmi-project/packages/core/src/transports/connector.test.ts b/wagmi-project/packages/core/src/transports/connector.test.ts new file mode 100644 index 0000000000..4b71c2b46b --- /dev/null +++ b/wagmi-project/packages/core/src/transports/connector.test.ts @@ -0,0 +1,97 @@ +import { config } from '@wagmi/test' +import { optimism } from 'viem/chains' +import { expect, test } from 'vitest' +import { createStore } from 'zustand' + +import { injected } from '../connectors/injected.js' +import { mock } from '../connectors/mock.js' +import { unstable_connector } from './connector.js' + +const connector = config.connectors[0]! + +test('setup', () => { + expect(unstable_connector(injected)({})).toMatchInlineSnapshot(` + { + "config": { + "key": "connector", + "methods": undefined, + "name": "Connector", + "request": [Function], + "retryCount": 3, + "retryDelay": 150, + "timeout": undefined, + "type": "connector", + }, + "request": [Function], + "value": undefined, + } + `) +}) + +test('behavior: connector type not found', () => { + const transport = unstable_connector({ type: 'foo' })({}) + expect(() => + transport.request({ method: 'eth_chainId' }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [ProviderDisconnectedError: The Provider is disconnected from all chains. + + Details: Could not find connector of type "foo" in \`connectors\` passed to \`createConfig\`. + Version: viem@2.29.2] + `) +}) + +test('behavior: provider is disconnected', () => { + const transport = unstable_connector(mock)({ + connectors: createStore(() => [ + { + ...connector, + async getProvider() { + return undefined + }, + }, + ]), + }) + + expect(() => + transport.request({ method: 'eth_chainId' }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [ProviderDisconnectedError: The Provider is disconnected from all chains. + + Details: Provider is disconnected. + Version: viem@2.29.2] + `) +}) + +test('behavior: chainId mismatch', () => { + const transport = unstable_connector(mock)({ + chain: optimism, + connectors: createStore(() => [ + { + ...connector, + async getProvider(options = {}) { + if (options.chainId === optimism.id) return connector.getProvider() + return undefined + }, + }, + ]), + }) + + expect(() => + transport.request({ method: 'eth_chainId' }), + ).rejects.toThrowErrorMatchingInlineSnapshot(` + [ChainDisconnectedError: The Provider is not connected to the requested chain. + + Details: The current chain of the connector (id: 1) does not match the target chain for the request (id: 10 – OP Mainnet). + Version: viem@2.29.2] + `) +}) + +test('behavior: request', () => { + const transport = unstable_connector(mock)({ + connectors: createStore(() => [connector]), + }) + + expect( + transport.request({ method: 'eth_chainId' }), + ).resolves.toThrowErrorMatchingInlineSnapshot(`"0x1"`) +}) diff --git a/wagmi-project/packages/core/src/transports/connector.ts b/wagmi-project/packages/core/src/transports/connector.ts new file mode 100644 index 0000000000..0f03d43188 --- /dev/null +++ b/wagmi-project/packages/core/src/transports/connector.ts @@ -0,0 +1,87 @@ +import { + ChainDisconnectedError, + type EIP1193Parameters, + type EIP1193Provider, + type EIP1193RequestFn, + ProviderDisconnectedError, + type TransportConfig, + type WalletRpcSchema, + createTransport, + hexToNumber, + withRetry, + withTimeout, +} from 'viem' + +import type { Connector, Transport } from '../createConfig.js' + +export type ConnectorTransportConfig = { + /** The key of the transport. */ + key?: TransportConfig['key'] | undefined + /** The name of the transport. */ + name?: TransportConfig['name'] | undefined + /** The max number of times to retry. */ + retryCount?: TransportConfig['retryCount'] | undefined + /** The base delay (in ms) between retries. */ + retryDelay?: TransportConfig['retryDelay'] | undefined +} + +export type ConnectorTransport = Transport + +export function unstable_connector( + connector: Pick, + config: ConnectorTransportConfig = {}, +): Transport<'connector'> { + const { type } = connector + const { key = 'connector', name = 'Connector', retryDelay } = config + + return (parameters) => { + const { chain, connectors } = parameters + const retryCount = config.retryCount ?? parameters.retryCount + + const request: EIP1193RequestFn = async ({ method, params }) => { + const connector = connectors?.getState().find((c) => c.type === type) + if (!connector) + throw new ProviderDisconnectedError( + new Error( + `Could not find connector of type "${type}" in \`connectors\` passed to \`createConfig\`.`, + ), + ) + + const provider = (await connector.getProvider({ + chainId: chain?.id, + })) as EIP1193Provider | undefined + if (!provider) + throw new ProviderDisconnectedError( + new Error('Provider is disconnected.'), + ) + + // We are applying a retry & timeout strategy here as some injected wallets (e.g. MetaMask) fail to + // immediately resolve a JSON-RPC request on page load. + const chainId = hexToNumber( + await withRetry(() => + withTimeout(() => provider.request({ method: 'eth_chainId' }), { + timeout: 100, + }), + ), + ) + if (chain && chainId !== chain.id) + throw new ChainDisconnectedError( + new Error( + `The current chain of the connector (id: ${chainId}) does not match the target chain for the request (id: ${chain.id} – ${chain.name}).`, + ), + ) + + const body = { method, params } as EIP1193Parameters + return provider.request(body) + } + + return createTransport({ + key, + name, + request, + retryCount, + retryDelay, + type: 'connector', + }) + } +} diff --git a/wagmi-project/packages/core/src/transports/fallback.test.ts b/wagmi-project/packages/core/src/transports/fallback.test.ts new file mode 100644 index 0000000000..dcae23cb79 --- /dev/null +++ b/wagmi-project/packages/core/src/transports/fallback.test.ts @@ -0,0 +1,63 @@ +import { http } from 'viem' +import { expect, test } from 'vitest' +import { unstable_connector } from './connector.js' +import { fallback } from './fallback.js' + +test('setup', () => { + expect( + fallback([ + unstable_connector({ type: 'injected' }), + http('https://example.com'), + ])({}), + ).toMatchInlineSnapshot(` + { + "config": { + "key": "fallback", + "methods": undefined, + "name": "Fallback", + "request": [Function], + "retryCount": 3, + "retryDelay": 150, + "timeout": undefined, + "type": "fallback", + }, + "request": [Function], + "value": { + "onResponse": [Function], + "transports": [ + { + "config": { + "key": "connector", + "methods": undefined, + "name": "Connector", + "request": [Function], + "retryCount": 0, + "retryDelay": 150, + "timeout": undefined, + "type": "connector", + }, + "request": [Function], + "value": undefined, + }, + { + "config": { + "key": "http", + "methods": undefined, + "name": "HTTP JSON-RPC", + "request": [Function], + "retryCount": 0, + "retryDelay": 150, + "timeout": 10000, + "type": "http", + }, + "request": [Function], + "value": { + "fetchOptions": undefined, + "url": "https://example.com", + }, + }, + ], + }, + } + `) +}) diff --git a/wagmi-project/packages/core/src/transports/fallback.ts b/wagmi-project/packages/core/src/transports/fallback.ts new file mode 100644 index 0000000000..67069f5de1 --- /dev/null +++ b/wagmi-project/packages/core/src/transports/fallback.ts @@ -0,0 +1,10 @@ +import { fallback as viem_fallback } from 'viem' + +import type { Transport } from '../createConfig.js' + +export function fallback( + transports: Transport[], + config?: Parameters[1], +) { + return viem_fallback(transports, config) +} diff --git a/wagmi-project/packages/core/src/types/chain.test-d.ts b/wagmi-project/packages/core/src/types/chain.test-d.ts new file mode 100644 index 0000000000..65632709e1 --- /dev/null +++ b/wagmi-project/packages/core/src/types/chain.test-d.ts @@ -0,0 +1,33 @@ +import type { Chain, mainnet, optimism, sepolia } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import type { Config } from '../createConfig.js' +import type { SelectChains } from './chain.js' +import type { Merge } from './utils.js' + +test('not narrowable', () => { + type Result = SelectChains + expectTypeOf().toEqualTypeOf() +}) + +test('chainId', () => { + type Result = SelectChains< + Config, + 1 + > + expectTypeOf().toEqualTypeOf() +}) + +test('at least one chain has formatters', () => { + type Result = SelectChains> + expectTypeOf().toEqualTypeOf< + readonly [typeof mainnet, typeof optimism] + >() +}) + +test('no formatters', () => { + type Result = SelectChains> + expectTypeOf().toEqualTypeOf< + readonly [Merge] + >() +}) diff --git a/wagmi-project/packages/core/src/types/chain.ts b/wagmi-project/packages/core/src/types/chain.ts new file mode 100644 index 0000000000..5f81783171 --- /dev/null +++ b/wagmi-project/packages/core/src/types/chain.ts @@ -0,0 +1,26 @@ +import type { Chain, ChainFormatters } from 'viem' + +import type { Config } from '../createConfig.js' +import type { IsNarrowable, Merge } from './utils.js' + +/** Filters {@link Config} chains by {@link chainId} or simplifies if no `ChainFormatters` are present. */ +export type SelectChains< + config extends Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, +> = Config extends config + ? readonly [Chain] // chains not inferrable, return default + : IsNarrowable extends true + ? readonly [Extract] // select specific chain + : HasFormatter extends true + ? config['chains'] // return all chains since one has formatter + : // return default chain with ID set to union (allows for more simple type since the only thing that is different is the chain ID for each chain) + readonly [Merge] + +type HasFormatter = chains extends readonly [ + infer head extends Chain, + ...infer tail extends readonly Chain[], +] + ? IsNarrowable extends true + ? true + : HasFormatter + : false diff --git a/wagmi-project/packages/core/src/types/properties.ts b/wagmi-project/packages/core/src/types/properties.ts new file mode 100644 index 0000000000..760cc46bd2 --- /dev/null +++ b/wagmi-project/packages/core/src/types/properties.ts @@ -0,0 +1,23 @@ +import type { Config, Connector } from '../createConfig.js' + +export type ChainIdParameter< + config extends Config, + chainId extends + | config['chains'][number]['id'] + | undefined = config['chains'][number]['id'], +> = { + chainId?: + | (chainId extends config['chains'][number]['id'] ? chainId : undefined) + | config['chains'][number]['id'] + | undefined +} + +export type ConnectorParameter = { + connector?: Connector | undefined +} + +export type ScopeKeyParameter = { scopeKey?: string | undefined } + +export type SyncConnectedChainParameter = { + syncConnectedChain?: boolean | undefined +} diff --git a/wagmi-project/packages/core/src/types/register.ts b/wagmi-project/packages/core/src/types/register.ts new file mode 100644 index 0000000000..db420adfdc --- /dev/null +++ b/wagmi-project/packages/core/src/types/register.ts @@ -0,0 +1,9 @@ +import type { Config } from '../createConfig.js' + +// biome-ignore lint/suspicious/noEmptyInterface: +export interface Register {} +export type ResolvedRegister = { + config: Register extends { config: infer config extends Config } + ? config + : Config +} diff --git a/wagmi-project/packages/core/src/types/unit.ts b/wagmi-project/packages/core/src/types/unit.ts new file mode 100644 index 0000000000..a64f794a87 --- /dev/null +++ b/wagmi-project/packages/core/src/types/unit.ts @@ -0,0 +1 @@ +export type Unit = 'ether' | 'gwei' | 'wei' | number diff --git a/wagmi-project/packages/core/src/types/utils.test-d.ts b/wagmi-project/packages/core/src/types/utils.test-d.ts new file mode 100644 index 0000000000..523f9f2e36 --- /dev/null +++ b/wagmi-project/packages/core/src/types/utils.test-d.ts @@ -0,0 +1,40 @@ +import { assertType, expectTypeOf, test } from 'vitest' + +import type { + Compute, + ExactPartial, + IsNever, + Mutable, + OneOf, + PartialBy, +} from './utils.js' + +test('ExactPartial', () => { + expectTypeOf>().toEqualTypeOf<{ + foo?: boolean | undefined + bar?: boolean | undefined + }>() +}) + +test('IsNever', () => { + expectTypeOf>().toEqualTypeOf() +}) + +test('Mutable', () => { + expectTypeOf< + Mutable<{ foo: boolean; readonly bar: boolean }> + >().toEqualTypeOf<{ foo: boolean; bar: boolean }>() +}) + +test('OneOf', () => { + assertType>({ foo: false }) + assertType>({ bar: false }) +}) + +test('PartialBy', () => { + type Result = Compute> + expectTypeOf().toEqualTypeOf<{ + foo?: string | undefined + bar: number + }>() +}) diff --git a/wagmi-project/packages/core/src/types/utils.ts b/wagmi-project/packages/core/src/types/utils.ts new file mode 100644 index 0000000000..aecd58a142 --- /dev/null +++ b/wagmi-project/packages/core/src/types/utils.ts @@ -0,0 +1,101 @@ +/** Combines members of an intersection into a readable type. */ +// https://twitter.com/mattpocockuk/status/1622730173446557697?s=20&t=NdpAcmEFXY01xkqU3KO0Mg +export type Compute = { [key in keyof type]: type[key] } & unknown + +/** + * Makes all properties of an object optional. + * + * Compatible with [`exactOptionalPropertyTypes`](https://www.typescriptlang.org/tsconfig#exactOptionalPropertyTypes). + */ +export type ExactPartial = { + [key in keyof type]?: type[key] | undefined +} + +/** Checks if {@link type} can be narrowed further than {@link type2} */ +export type IsNarrowable = IsUnknown extends true + ? false + : undefined extends type + ? false + : IsNever< + (type extends type2 ? true : false) & + (type2 extends type ? false : true) + > extends true + ? false + : true + +/** + * @internal + * Checks if {@link type} is `never` + */ +export type IsNever = [type] extends [never] ? true : false + +/** + * @internal + * Checks if {@link type} is `unknown` + */ +export type IsUnknown = unknown extends type ? true : false + +/** Merges two object types into new type */ +export type Merge = Compute< + LooseOmit & + obj2 +> + +/** Removes `readonly` from all properties of an object. */ +export type Mutable = { + -readonly [key in keyof type]: type[key] +} + +/** Strict version of built-in Omit type */ +export type StrictOmit = Pick< + type, + Exclude +> + +/** Makes objects destructurable. */ +export type OneOf< + union extends object, + /// + keys extends KeyofUnion = KeyofUnion, +> = union extends infer Item + ? Compute]?: undefined }> + : never +type KeyofUnion = type extends type ? keyof type : never + +/** Makes {@link key} optional in {@link type} while preserving type inference. */ +// s/o trpc (https://github.com/trpc/trpc/blob/main/packages/server/src/types.ts#L6) +export type PartialBy = ExactPartial< + Pick +> & + StrictOmit + +/* Removes `undefined` from object property */ +export type RemoveUndefined = { + [key in keyof type]: NonNullable +} + +/////////////////////////////////////////////////////////////////////////// +// Loose types + +/** Loose version of {@link StrictOmit} */ +export type LooseOmit = Pick< + type, + Exclude +> + +/////////////////////////////////////////////////////////////////////////// +// Union types + +export type UnionCompute = type extends object ? Compute : type + +export type UnionLooseOmit = type extends any + ? LooseOmit + : never + +export type UnionStrictOmit = type extends any + ? StrictOmit + : never + +export type UnionExactPartial = type extends object + ? ExactPartial + : type diff --git a/wagmi-project/packages/core/src/utils/cookie.test.ts b/wagmi-project/packages/core/src/utils/cookie.test.ts new file mode 100644 index 0000000000..f21f5ccee1 --- /dev/null +++ b/wagmi-project/packages/core/src/utils/cookie.test.ts @@ -0,0 +1,69 @@ +import { http } from 'viem' +import { mainnet } from 'viem/chains' +import { expect, test } from 'vitest' + +import { createConfig } from '../createConfig.js' +import { createStorage } from '../createStorage.js' +import { cookieStorage, cookieToInitialState, parseCookie } from './cookie.js' + +test('cookieStorage', () => { + expect(cookieStorage.getItem('recentConnectorId')).toMatchInlineSnapshot( + 'null', + ) + cookieStorage.setItem('recentConnectorId', 'foo') + expect(cookieStorage.getItem('recentConnectorId')).toMatchInlineSnapshot( + `"foo"`, + ) + cookieStorage.removeItem('recentConnectorId') + expect(cookieStorage.getItem('recentConnectorId')).toMatchInlineSnapshot( + 'null', + ) +}) + +test('cookieToInitialState', () => { + const config = createConfig({ + chains: [mainnet], + transports: { [mainnet.id]: http() }, + storage: createStorage({ storage: cookieStorage }), + }) + + expect( + cookieToInitialState( + config, + 'wagmi.store={"state":{"connections":{"__type":"Map","value":[]},"chainId":1,"current":null},"version":2}; ', + ), + ).toMatchInlineSnapshot(` + { + "chainId": 1, + "connections": Map {}, + "current": null, + } + `) + + expect(cookieToInitialState(config)).toMatchInlineSnapshot('undefined') + expect(cookieToInitialState(config), 'foo').toMatchInlineSnapshot('undefined') +}) + +test('parseCookie', () => { + expect( + parseCookie( + 'wagmi.store={"state":{"connections":{"__type":"Map","value":[]},"chainId":1,"current":null},"version":2}; ', + 'wagmi.store', + ), + ).toMatchInlineSnapshot( + `"{"state":{"connections":{"__type":"Map","value":[]},"chainId":1,"current":null},"version":2}"`, + ) + + expect( + parseCookie( + 'foo="bar"; wagmi.store={"state":{"connections":{"__type":"Map","value":[]},"chainId":1,"current":null},"version":2}; ', + 'wagmi.store', + ), + ).toMatchInlineSnapshot( + `"{"state":{"connections":{"__type":"Map","value":[]},"chainId":1,"current":null},"version":2}"`, + ) + + expect(parseCookie('foo="bar"; ', 'wagmi.store')).toMatchInlineSnapshot( + 'undefined', + ) +}) diff --git a/wagmi-project/packages/core/src/utils/cookie.ts b/wagmi-project/packages/core/src/utils/cookie.ts new file mode 100644 index 0000000000..ccd07bc7b7 --- /dev/null +++ b/wagmi-project/packages/core/src/utils/cookie.ts @@ -0,0 +1,33 @@ +import type { Config, State } from '../createConfig.js' +import type { BaseStorage } from '../createStorage.js' +import { deserialize } from './deserialize.js' + +export const cookieStorage = { + getItem(key) { + if (typeof window === 'undefined') return null + const value = parseCookie(document.cookie, key) + return value ?? null + }, + setItem(key, value) { + if (typeof window === 'undefined') return + document.cookie = `${key}=${value};path=/;samesite=Lax` + }, + removeItem(key) { + if (typeof window === 'undefined') return + document.cookie = `${key}=;max-age=-1;path=/` + }, +} satisfies BaseStorage + +export function cookieToInitialState(config: Config, cookie?: string | null) { + if (!cookie) return undefined + const key = `${config.storage?.key}.store` + const parsed = parseCookie(cookie, key) + if (!parsed) return undefined + return deserialize<{ state: State }>(parsed).state +} + +export function parseCookie(cookie: string, key: string) { + const keyValue = cookie.split('; ').find((x) => x.startsWith(`${key}=`)) + if (!keyValue) return undefined + return keyValue.substring(key.length + 1) +} diff --git a/wagmi-project/packages/core/src/utils/deepEqual.test.ts b/wagmi-project/packages/core/src/utils/deepEqual.test.ts new file mode 100644 index 0000000000..6105fe496f --- /dev/null +++ b/wagmi-project/packages/core/src/utils/deepEqual.test.ts @@ -0,0 +1,40 @@ +import { expect, test } from 'vitest' + +import { deepEqual } from './deepEqual.js' + +test('compares primitive values', () => { + expect(deepEqual(true, true)).toBe(true) + expect(deepEqual(true, false)).toBe(false) + + expect(deepEqual(1, 1)).toBe(true) + expect(deepEqual(1, 2)).toBe(false) + + expect(deepEqual('zustand', 'zustand')).toBe(true) + expect(deepEqual('zustand', 'redux')).toBe(false) +}) + +test('compares objects', () => { + expect(deepEqual({ foo: 'bar', asd: 123 }, { foo: 'bar', asd: 123 })).toBe( + true, + ) + + expect( + deepEqual({ foo: 'bar', asd: 123 }, { foo: 'bar', foobar: true }), + ).toBe(false) + + expect( + deepEqual({ foo: 'bar', asd: 123 }, { foo: 'bar', asd: 123, foobar: true }), + ).toBe(false) +}) + +test('compares arrays', () => { + expect(deepEqual([1, 2, 3], [1, 2, 3])).toBe(true) + + expect(deepEqual([1, 2, 3], [2, 3, 4])).toBe(false) + + expect( + deepEqual([{ foo: 'bar' }, { asd: 123 }], [{ foo: 'bar' }, { asd: 123 }]), + ).toBe(true) + + expect(deepEqual([{ foo: 'bar' }], [{ foo: 'bar', asd: 123 }])).toBe(false) +}) diff --git a/wagmi-project/packages/core/src/utils/deepEqual.ts b/wagmi-project/packages/core/src/utils/deepEqual.ts new file mode 100644 index 0000000000..89b47a6bdd --- /dev/null +++ b/wagmi-project/packages/core/src/utils/deepEqual.ts @@ -0,0 +1,43 @@ +/** Forked from https://github.com/epoberezkin/fast-deep-equal */ + +export function deepEqual(a: any, b: any) { + if (a === b) return true + + if (a && b && typeof a === 'object' && typeof b === 'object') { + if (a.constructor !== b.constructor) return false + + let length: number + let i: number + + if (Array.isArray(a) && Array.isArray(b)) { + length = a.length + if (length !== b.length) return false + for (i = length; i-- !== 0; ) if (!deepEqual(a[i], b[i])) return false + return true + } + + if (a.valueOf !== Object.prototype.valueOf) + return a.valueOf() === b.valueOf() + if (a.toString !== Object.prototype.toString) + return a.toString() === b.toString() + + const keys = Object.keys(a) + length = keys.length + if (length !== Object.keys(b).length) return false + + for (i = length; i-- !== 0; ) + if (!Object.prototype.hasOwnProperty.call(b, keys[i]!)) return false + + for (i = length; i-- !== 0; ) { + const key = keys[i] + + if (key && !deepEqual(a[key], b[key])) return false + } + + return true + } + + // true if both NaN, false otherwise + // biome-ignore lint/suspicious/noSelfCompare: + return a !== a && b !== b +} diff --git a/wagmi-project/packages/core/src/utils/deserialize.test.ts b/wagmi-project/packages/core/src/utils/deserialize.test.ts new file mode 100644 index 0000000000..11f73ff79b --- /dev/null +++ b/wagmi-project/packages/core/src/utils/deserialize.test.ts @@ -0,0 +1,114 @@ +import { expect, test } from 'vitest' + +import { deserialize } from './deserialize.js' +import { serialize } from './serialize.js' + +test('deserializes', () => { + const deserializedCache = deserialize( + serialize({ + some: 'complex', + object: { + that: 'has', + many: [ + { many: 'many', manymany: 'many' }, + { many: 'many' }, + { many: 'many' }, + { + many: { + properties: { + ones: { + that: { + have: { + functions: () => null, + }, + }, + }, + }, + }, + }, + ], + }, + and: { + ones: { + that: { + have: { + bigints: 123456789012345678901234567890n, + }, + }, + }, + }, + also: { + ones: { + that: { + have: { + proxies: new Proxy({ lol: 'nice' }, {}), + }, + }, + }, + }, + }), + ) + expect(deserializedCache).toMatchInlineSnapshot(` + { + "also": { + "ones": { + "that": { + "have": { + "proxies": { + "lol": "nice", + }, + }, + }, + }, + }, + "and": { + "ones": { + "that": { + "have": { + "bigints": 123456789012345678901234567890n, + }, + }, + }, + }, + "object": { + "many": [ + { + "many": "many", + "manymany": "many", + }, + { + "many": "many", + }, + { + "many": "many", + }, + { + "many": { + "properties": { + "ones": { + "that": { + "have": {}, + }, + }, + }, + }, + }, + ], + "that": "has", + }, + "some": "complex", + } + `) +}) + +test('Map', () => { + const map = new Map().set('foo', { bar: 'baz' }) + const deserializedCache = deserialize(serialize({ map })) + expect(deserializedCache).toEqual({ map }) +}) + +test('bigint', () => { + const bigint = 123n + const deserializedCache = deserialize(serialize({ bigint })) + expect(deserializedCache).toEqual({ bigint }) +}) diff --git a/wagmi-project/packages/core/src/utils/deserialize.ts b/wagmi-project/packages/core/src/utils/deserialize.ts new file mode 100644 index 0000000000..36fe30dab8 --- /dev/null +++ b/wagmi-project/packages/core/src/utils/deserialize.ts @@ -0,0 +1,10 @@ +type Reviver = (key: string, value: any) => any + +export function deserialize(value: string, reviver?: Reviver): type { + return JSON.parse(value, (key, value_) => { + let value = value_ + if (value?.__type === 'bigint') value = BigInt(value.value) + if (value?.__type === 'Map') value = new Map(value.value) + return reviver?.(key, value) ?? value + }) +} diff --git a/wagmi-project/packages/core/src/utils/extractRpcUrls.test.ts b/wagmi-project/packages/core/src/utils/extractRpcUrls.test.ts new file mode 100644 index 0000000000..6d2c21e26e --- /dev/null +++ b/wagmi-project/packages/core/src/utils/extractRpcUrls.test.ts @@ -0,0 +1,92 @@ +import { http } from 'viem' +import { mainnet, optimism, sepolia } from 'viem/chains' +import { expect, test } from 'vitest' + +import { injected } from '../connectors/injected.js' +import { unstable_connector } from '../transports/connector.js' +import { fallback } from '../transports/fallback.js' +import { extractRpcUrls } from './extractRpcUrls.js' + +test('default', () => { + expect( + extractRpcUrls({ + chain: mainnet, + transports: { + [mainnet.id]: fallback([ + http('https://wagmi.com'), + http('https://lol.com'), + ]), + [sepolia.id]: http('https://sepoliarocks.com'), + [optimism.id]: http(), + }, + }), + ).toMatchInlineSnapshot(` + [ + "https://wagmi.com", + "https://lol.com", + ] + `) + + expect( + extractRpcUrls({ + chain: sepolia, + transports: { + [mainnet.id]: fallback([ + http('https://wagmi.com'), + http('https://lol.com'), + ]), + [sepolia.id]: http('https://sepoliarocks.com'), + [optimism.id]: http(), + }, + }), + ).toMatchInlineSnapshot(` + [ + "https://sepoliarocks.com", + ] + `) + + expect( + extractRpcUrls({ + chain: optimism, + transports: { + [mainnet.id]: fallback([ + http('https://wagmi.com'), + http('https://lol.com'), + ]), + [sepolia.id]: http('https://sepoliarocks.com'), + [optimism.id]: http(), + }, + }), + ).toMatchInlineSnapshot(` + [ + "https://mainnet.optimism.io", + ] + `) + + expect( + extractRpcUrls({ + chain: mainnet, + }), + ).toMatchInlineSnapshot(` + [ + "https://eth.merkle.io", + ] + `) + + expect( + extractRpcUrls({ + chain: mainnet, + transports: { + [mainnet.id]: fallback([ + unstable_connector(injected), + http('https://lol.com'), + ]), + }, + }), + ).toMatchInlineSnapshot(` + [ + "https://eth.merkle.io", + "https://lol.com", + ] + `) +}) diff --git a/wagmi-project/packages/core/src/utils/extractRpcUrls.ts b/wagmi-project/packages/core/src/utils/extractRpcUrls.ts new file mode 100644 index 0000000000..a617eac13c --- /dev/null +++ b/wagmi-project/packages/core/src/utils/extractRpcUrls.ts @@ -0,0 +1,19 @@ +import type { Chain, Transport } from 'viem' + +type ExtractRpcUrlsParameters = { + transports?: Record | undefined + chain: Chain +} + +export function extractRpcUrls(parameters: ExtractRpcUrlsParameters) { + const { chain } = parameters + const fallbackUrl = chain.rpcUrls.default.http[0] + + if (!parameters.transports) return [fallbackUrl] + + const transport = parameters.transports?.[chain.id]?.({ chain }) + const transports = (transport?.value?.transports as NonNullable< + typeof transport + >[]) || [transport] + return transports.map(({ value }) => value?.url || fallbackUrl) +} diff --git a/wagmi-project/packages/core/src/utils/getAction.test.ts b/wagmi-project/packages/core/src/utils/getAction.test.ts new file mode 100644 index 0000000000..7173852947 --- /dev/null +++ b/wagmi-project/packages/core/src/utils/getAction.test.ts @@ -0,0 +1,49 @@ +import { abi, address, config } from '@wagmi/test' +import * as viem_actions from 'viem/actions' +import { expect, test, vi } from 'vitest' + +import { getAction } from './getAction.js' + +test('uses tree-shakable action', async () => { + const client = config.getClient({ chainId: 1 }) + + const name = 'getBlockNumber' + const actions = { ...viem_actions } + const spy = vi.spyOn(actions, name) + const action = getAction(client, actions[name], name) + + await action({}) + expect(spy).toBeCalledWith(client, {}) +}) + +test('uses client action', async () => { + const client = config + .getClient({ chainId: 1 }) + .extend(() => ({ getBlockNumber: async () => 69n })) + + const name = 'getBlockNumber' + const spy = vi.spyOn(client, name) + const action = getAction(client, client[name], name) + + await action({}) + expect(spy).toBeCalledWith({}) +}) + +test('internal call', async () => { + const client = config.getClient({ chainId: 1 }).extend(() => ({ + async call() { + return { + data: '0x0000000000000000000000000000000000000000000000000000000000000045', + } + }, + })) + + await expect( + viem_actions.readContract(client, { + address: address.wagmiMintExample, + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }), + ).resolves.toEqual(69n) +}) diff --git a/wagmi-project/packages/core/src/utils/getAction.ts b/wagmi-project/packages/core/src/utils/getAction.ts new file mode 100644 index 0000000000..514ceb5d50 --- /dev/null +++ b/wagmi-project/packages/core/src/utils/getAction.ts @@ -0,0 +1,44 @@ +import type { + Account, + Chain, + Client, + PublicActions, + RpcSchema, + Transport, + WalletActions, +} from 'viem' + +/** + * Retrieves and returns an action from the client (if exists), and falls + * back to the tree-shakable action. + * + * Useful for extracting overridden actions from a client (ie. if a consumer + * wants to override the `sendTransaction` implementation). + */ +export function getAction< + transport extends Transport, + chain extends Chain | undefined, + account extends Account | undefined, + rpcSchema extends RpcSchema | undefined, + extended extends { [key: string]: unknown }, + client extends Client, + parameters, + returnType, +>( + client: client, + actionFn: (_: any, parameters: parameters) => returnType, + // Some minifiers drop `Function.prototype.name`, or replace it with short letters, + // meaning that `actionFn.name` will not always work. For that case, the consumer + // needs to pass the name explicitly. + name: keyof PublicActions | keyof WalletActions, +): (parameters: parameters) => returnType { + const action_implicit = client[actionFn.name] + if (typeof action_implicit === 'function') + return action_implicit as (params: parameters) => returnType + + const action_explicit = client[name] + if (typeof action_explicit === 'function') + return action_explicit as (params: parameters) => returnType + + return (params) => actionFn(client, params) +} diff --git a/wagmi-project/packages/core/src/utils/getUnit.test.ts b/wagmi-project/packages/core/src/utils/getUnit.test.ts new file mode 100644 index 0000000000..1054303def --- /dev/null +++ b/wagmi-project/packages/core/src/utils/getUnit.test.ts @@ -0,0 +1,9 @@ +import { expect, test } from 'vitest' + +import { getUnit } from './getUnit.js' + +test('default', () => { + expect(getUnit(1)).toMatchInlineSnapshot('1') + expect(getUnit('wei')).toMatchInlineSnapshot('0') + expect(getUnit('ether')).toMatchInlineSnapshot('18') +}) diff --git a/wagmi-project/packages/core/src/utils/getUnit.ts b/wagmi-project/packages/core/src/utils/getUnit.ts new file mode 100644 index 0000000000..084f45b622 --- /dev/null +++ b/wagmi-project/packages/core/src/utils/getUnit.ts @@ -0,0 +1,9 @@ +import { weiUnits } from 'viem' + +import type { Unit } from '../types/unit.js' + +export function getUnit(unit: Unit) { + if (typeof unit === 'number') return unit + if (unit === 'wei') return 0 + return Math.abs(weiUnits[unit]) +} diff --git a/wagmi-project/packages/core/src/utils/getVersion.test.ts b/wagmi-project/packages/core/src/utils/getVersion.test.ts new file mode 100644 index 0000000000..29fa256178 --- /dev/null +++ b/wagmi-project/packages/core/src/utils/getVersion.test.ts @@ -0,0 +1,7 @@ +import { expect, test } from 'vitest' + +import { getVersion } from './getVersion.js' + +test('default', () => { + expect(getVersion()).toMatchInlineSnapshot(`"@wagmi/core@x.y.z"`) +}) diff --git a/wagmi-project/packages/core/src/utils/getVersion.ts b/wagmi-project/packages/core/src/utils/getVersion.ts new file mode 100644 index 0000000000..3506365267 --- /dev/null +++ b/wagmi-project/packages/core/src/utils/getVersion.ts @@ -0,0 +1,3 @@ +import { version } from '../version.js' + +export const getVersion = () => `@wagmi/core@${version}` diff --git a/wagmi-project/packages/core/src/utils/normalizeChainId.test.ts b/wagmi-project/packages/core/src/utils/normalizeChainId.test.ts new file mode 100644 index 0000000000..de9d1882e3 --- /dev/null +++ b/wagmi-project/packages/core/src/utils/normalizeChainId.test.ts @@ -0,0 +1,24 @@ +import { expect, test } from 'vitest' + +import { normalizeChainId } from './normalizeChainId.js' + +test.each([ + { chainId: 1, expected: 1 }, + { chainId: '1', expected: 1 }, + { chainId: '0x1', expected: 1 }, + { chainId: '0x4', expected: 4 }, + { chainId: 42, expected: 42 }, + { chainId: '42', expected: 42 }, + { chainId: '0x2a', expected: 42 }, + { chainId: ' 0x2a', expected: 42 }, + { chainId: BigInt(1), expected: 1 }, + { chainId: BigInt(10), expected: 10 }, +])('normalizeChainId($chainId)', ({ chainId, expected }) => { + expect(normalizeChainId(chainId)).toEqual(expected) +}) + +test('unknown type', () => { + expect(() => normalizeChainId({})).toThrow( + 'Cannot normalize chainId "[object Object]" of type "object"', + ) +}) diff --git a/wagmi-project/packages/core/src/utils/normalizeChainId.ts b/wagmi-project/packages/core/src/utils/normalizeChainId.ts new file mode 100644 index 0000000000..a1017c0953 --- /dev/null +++ b/wagmi-project/packages/core/src/utils/normalizeChainId.ts @@ -0,0 +1,13 @@ +/** @deprecated use `Number` instead */ +export function normalizeChainId(chainId: bigint | number | string | unknown) { + if (typeof chainId === 'string') + return Number.parseInt( + chainId, + chainId.trim().substring(0, 2) === '0x' ? 16 : 10, + ) + if (typeof chainId === 'bigint') return Number(chainId) + if (typeof chainId === 'number') return chainId + throw new Error( + `Cannot normalize chainId "${chainId}" of type "${typeof chainId}"`, + ) +} diff --git a/wagmi-project/packages/core/src/utils/serialize.test.ts b/wagmi-project/packages/core/src/utils/serialize.test.ts new file mode 100644 index 0000000000..e182101130 --- /dev/null +++ b/wagmi-project/packages/core/src/utils/serialize.test.ts @@ -0,0 +1,241 @@ +import { describe, expect, it } from 'vitest' + +import { serialize } from './serialize.js' + +class Foo { + value: string + + constructor(value: string) { + this.value = value + } +} + +const simpleObject = { + boolean: true, + fn() { + return 'foo' + }, + nan: Number.NaN, + nil: null, + number: 123, + string: 'foo', + undef: undefined, + [Symbol('key')]: 'value', +} + +const bigintObject = Object.assign({}, simpleObject, { + bigint: 123n, + nested: { + bigint: { + value: 69n, + }, + }, +}) + +const bufferString = 'this is a test buffer' +const complexObject = Object.assign({}, simpleObject, { + array: ['foo', { bar: 'baz' }], + buffer: Buffer.alloc(bufferString.length, bufferString), + error: new Error('boom'), + foo: new Foo('value'), + map: new Map().set('foo', { bar: 'baz' }), + object: { foo: { bar: 'baz' } }, + promise: Promise.resolve('foo'), + regexp: /foo/, + set: new Set().add('foo').add({ bar: 'baz' }), + weakmap: new WeakMap([ + [{}, 'foo'], + [{}, 'bar'], + ]), + weakset: new WeakSet([{}, {}]), +}) + +const circularObject = Object.assign( + {}, + complexObject, + { + map: { __type: 'Map', value: [['foo', { bar: 'baz' }]] }, + }, + { + deeply: { + nested: { + reference: {}, + }, + }, + }, +) + +circularObject.deeply.nested.reference = circularObject + +describe('stringify', () => { + describe('handling of object types', () => { + it('should handle simple objects', () => { + const result = serialize(simpleObject) + + expect(result).toMatchInlineSnapshot( + `"{"boolean":true,"nan":null,"nil":null,"number":123,"string":"foo"}"`, + ) + }) + + it('should handle objects with bigints', () => { + const result = serialize(bigintObject) + + expect(result).toMatchInlineSnapshot( + `"{"boolean":true,"nan":null,"nil":null,"number":123,"string":"foo","bigint":{"__type":"bigint","value":"123"},"nested":{"bigint":{"value":{"__type":"bigint","value":"69"}}}}"`, + ) + }) + + it('should handle simple objects with a custom replacer', () => { + const replacer = (_key: string, value: any) => + value && typeof value === 'object' ? value : `primitive-${value}` + + const result = serialize(simpleObject, replacer) + + expect(result).toMatchInlineSnapshot( + `"{"boolean":"primitive-true","fn":"primitive-fn() {\\n return \\"foo\\";\\n }","nan":"primitive-NaN","nil":"primitive-null","number":"primitive-123","string":"primitive-foo","undef":"primitive-undefined"}"`, + ) + }) + + it('should handle simple objects with indentation', () => { + const result = serialize(simpleObject, null, 2) + + expect(result).toMatchInlineSnapshot(` + "{ + "boolean": true, + "nan": null, + "nil": null, + "number": 123, + "string": "foo" + }" + `) + }) + + it('should handle bigint objects with indentation', () => { + const result = serialize(bigintObject, null, 2) + + expect(result).toMatchInlineSnapshot(` + "{ + "boolean": true, + "nan": null, + "nil": null, + "number": 123, + "string": "foo", + "bigint": { + "__type": "bigint", + "value": "123" + }, + "nested": { + "bigint": { + "value": { + "__type": "bigint", + "value": "69" + } + } + } + }" + `) + }) + + it('should handle complex objects', () => { + const result = serialize(complexObject) + + expect(result).toMatchInlineSnapshot( + `"{"boolean":true,"nan":null,"nil":null,"number":123,"string":"foo","array":["foo",{"bar":"baz"}],"buffer":{"type":"Buffer","data":[116,104,105,115,32,105,115,32,97,32,116,101,115,116,32,98,117,102,102,101,114]},"error":{},"foo":{"value":"value"},"map":{"__type":"Map","value":[["foo",{"bar":"baz"}]]},"object":{"foo":{"bar":"baz"}},"promise":{},"regexp":{},"set":{},"weakmap":{},"weakset":{}}"`, + ) + }) + + it('should handle complex objects with a custom replacer', () => { + const replacer = (_key: string, value: any) => + value && typeof value === 'object' ? value : `primitive-${value}` + + const result = serialize(complexObject, replacer) + + expect(result).toMatchInlineSnapshot( + `"{"boolean":"primitive-true","fn":"primitive-fn() {\\n return \\"foo\\";\\n }","nan":"primitive-NaN","nil":"primitive-null","number":"primitive-123","string":"primitive-foo","undef":"primitive-undefined","array":["primitive-foo",{"bar":"primitive-baz"}],"buffer":{"type":"primitive-Buffer","data":["primitive-116","primitive-104","primitive-105","primitive-115","primitive-32","primitive-105","primitive-115","primitive-32","primitive-97","primitive-32","primitive-116","primitive-101","primitive-115","primitive-116","primitive-32","primitive-98","primitive-117","primitive-102","primitive-102","primitive-101","primitive-114"]},"error":{},"foo":{"value":"primitive-value"},"map":{"__type":"primitive-Map","value":[["primitive-foo",{"bar":"primitive-baz"}]]},"object":{"foo":{"bar":"primitive-baz"}},"promise":{},"regexp":{},"set":{},"weakmap":{},"weakset":{}}"`, + ) + }) + + it('should handle circular objects', () => { + const result = serialize(circularObject) + + expect(result).toEqual( + JSON.stringify( + circularObject, + (() => { + const cache: any[] = [] + + return (_key, value) => { + if (value && typeof value === 'object' && ~cache.indexOf(value)) { + return '[ref=.]' + } + + cache.push(value) + + return value + } + })(), + ), + ) + }) + + it('should handle circular objects with a custom circular replacer', () => { + const result = serialize( + circularObject, + null, + null, + (_key: string, _value: string, referenceKey: string) => referenceKey, + ) + const circularReplacer = (() => { + const cache: any[] = [] + + return (_key: string, value: any) => { + if (value && typeof value === 'object' && ~cache.indexOf(value)) { + return '.' + } + + cache.push(value) + + return value + } + })() + + expect(result).toEqual(JSON.stringify(circularObject, circularReplacer)) + }) + }) + + describe('key references', () => { + it('should point to the top level object when it is referenced', () => { + const object = { + foo: 'bar', + deeply: { + recursive: { + object: {}, + }, + }, + } + + object.deeply.recursive.object = object + + expect(serialize(object)).toEqual( + `{"foo":"bar","deeply":{"recursive":{"object":"[ref=.]"}}}`, + ) + }) + + it('should point to the nested object when it is referenced', () => { + const object = { + foo: 'bar', + deeply: { + recursive: { + object: {}, + }, + }, + } + + object.deeply.recursive.object = object.deeply.recursive + + expect(serialize(object)).toEqual( + `{"foo":"bar","deeply":{"recursive":{"object":"[ref=.deeply.recursive]"}}}`, + ) + }) + }) +}) diff --git a/wagmi-project/packages/core/src/utils/serialize.ts b/wagmi-project/packages/core/src/utils/serialize.ts new file mode 100644 index 0000000000..3f538c7b87 --- /dev/null +++ b/wagmi-project/packages/core/src/utils/serialize.ts @@ -0,0 +1,116 @@ +/** + * Get the reference key for the circular value + * + * @param keys the keys to build the reference key from + * @param cutoff the maximum number of keys to include + * @returns the reference key + */ +function getReferenceKey(keys: string[], cutoff: number) { + return keys.slice(0, cutoff).join('.') || '.' +} + +/** + * Faster `Array.prototype.indexOf` implementation build for slicing / splicing + * + * @param array the array to match the value in + * @param value the value to match + * @returns the matching index, or -1 + */ +function getCutoff(array: any[], value: any) { + const { length } = array + + for (let index = 0; index < length; ++index) { + if (array[index] === value) { + return index + 1 + } + } + + return 0 +} + +type StandardReplacer = (key: string, value: any) => any +type CircularReplacer = (key: string, value: any, referenceKey: string) => any + +/** + * Create a replacer method that handles circular values + * + * @param [replacer] a custom replacer to use for non-circular values + * @param [circularReplacer] a custom replacer to use for circular methods + * @returns the value to stringify + */ +function createReplacer( + replacer?: StandardReplacer | null | undefined, + circularReplacer?: CircularReplacer | null | undefined, +): StandardReplacer { + const hasReplacer = typeof replacer === 'function' + const hasCircularReplacer = typeof circularReplacer === 'function' + + const cache: any[] = [] + const keys: string[] = [] + + return function replace(this: any, key: string, value: any) { + if (typeof value === 'object') { + if (cache.length) { + const thisCutoff = getCutoff(cache, this) + + if (thisCutoff === 0) { + cache[cache.length] = this + } else { + cache.splice(thisCutoff) + keys.splice(thisCutoff) + } + + keys[keys.length] = key + + const valueCutoff = getCutoff(cache, value) + + if (valueCutoff !== 0) { + return hasCircularReplacer + ? circularReplacer.call( + this, + key, + value, + getReferenceKey(keys, valueCutoff), + ) + : `[ref=${getReferenceKey(keys, valueCutoff)}]` + } + } else { + cache[0] = value + keys[0] = key + } + } + + return hasReplacer ? replacer.call(this, key, value) : value + } +} + +/** + * Stringifier that handles circular values + * + * Forked from https://github.com/planttheidea/fast-stringify + * + * @param value to stringify + * @param [replacer] a custom replacer function for handling standard values + * @param [indent] the number of spaces to indent the output by + * @param [circularReplacer] a custom replacer function for handling circular values + * @returns the stringified output + */ +export function serialize( + value: any, + replacer?: StandardReplacer | null | undefined, + indent?: number | null | undefined, + circularReplacer?: CircularReplacer | null | undefined, +) { + return JSON.stringify( + value, + createReplacer((key, value_) => { + let value = value_ + if (typeof value === 'bigint') + value = { __type: 'bigint', value: value_.toString() } + if (value instanceof Map) + value = { __type: 'Map', value: Array.from(value_.entries()) } + return replacer?.(key, value) ?? value + }, circularReplacer), + indent ?? undefined, + ) +} diff --git a/wagmi-project/packages/core/src/utils/uid.ts b/wagmi-project/packages/core/src/utils/uid.ts new file mode 100644 index 0000000000..532c899b19 --- /dev/null +++ b/wagmi-project/packages/core/src/utils/uid.ts @@ -0,0 +1,6 @@ +import { randomBytes } from 'node:crypto' + +export function uid(length = 11) { + const byteLength = Math.ceil(length / 2) + return randomBytes(byteLength).toString('hex').slice(0, length) +} diff --git a/wagmi-project/packages/core/src/version.ts b/wagmi-project/packages/core/src/version.ts new file mode 100644 index 0000000000..e291f4b23c --- /dev/null +++ b/wagmi-project/packages/core/src/version.ts @@ -0,0 +1 @@ +export const version = '2.17.2' diff --git a/wagmi-project/packages/core/test/setup.ts b/wagmi-project/packages/core/test/setup.ts new file mode 100644 index 0000000000..f59a0488fe --- /dev/null +++ b/wagmi-project/packages/core/test/setup.ts @@ -0,0 +1,5 @@ +import { vi } from 'vitest' + +vi.mock('../src/version.ts', () => { + return { version: 'x.y.z' } +}) diff --git a/wagmi-project/packages/core/tsconfig.build.json b/wagmi-project/packages/core/tsconfig.build.json new file mode 100644 index 0000000000..fbed2b1036 --- /dev/null +++ b/wagmi-project/packages/core/tsconfig.build.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.base.json", + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.test.ts", "src/**/*.test-d.ts"], + "compilerOptions": { + "sourceMap": true + } +} diff --git a/wagmi-project/packages/core/tsconfig.json b/wagmi-project/packages/core/tsconfig.json new file mode 100644 index 0000000000..bacbc9228c --- /dev/null +++ b/wagmi-project/packages/core/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "./tsconfig.build.json", + "include": ["src/**/*.ts", "test/**/*.ts"], + "exclude": [] +} diff --git a/wagmi-project/packages/create-wagmi/CHANGELOG.md b/wagmi-project/packages/create-wagmi/CHANGELOG.md new file mode 100644 index 0000000000..7ab58fe7e1 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/CHANGELOG.md @@ -0,0 +1,278 @@ +# create-wagmi + +## 2.0.14 + +### Patch Changes + +- [#4450](https://github.com/wevm/wagmi/pull/4450) [`7b9a6bb35881b657a00bdd7ccd7edea32660f5bf`](https://github.com/wevm/wagmi/commit/7b9a6bb35881b657a00bdd7ccd7edea32660f5bf) Thanks [@tmm](https://github.com/tmm)! - Removed internal usage of `fs-extra`. + +## 2.0.13 + +### Patch Changes + +- [#4060](https://github.com/wevm/wagmi/pull/4060) [`95965c1f19d480b97f2b297a077a9e607dee32ad`](https://github.com/wevm/wagmi/commit/95965c1f19d480b97f2b297a077a9e607dee32ad) Thanks [@dalechyn](https://github.com/dalechyn)! - Bumped Tanstack Query dependencies to fix typing issues between exported Wagmi query options and TanStack Query suspense query methods (due to [`direction` property in `QueryFunctionContext` being deprecated](https://github.com/TanStack/query/pull/7410)). + +## 2.0.12 + +### Patch Changes + +- [`c00303d0c5909680b3124f92c0a2d2f31ea30405`](https://github.com/wevm/wagmi/commit/c00303d0c5909680b3124f92c0a2d2f31ea30405) Thanks [@tmm](https://github.com/tmm)! - Bumped Next.js version + +## 2.0.11 + +### Patch Changes + +- [#3871](https://github.com/wevm/wagmi/pull/3871) [`0e6bd286`](https://github.com/wevm/wagmi/commit/0e6bd286ca2572d2bfbe206db460528b7c2ebc63) Thanks [@jxom](https://github.com/jxom)! - Added `.npmrc` with `legacy-peer-deps = true` to templates. + +## 2.0.10 + +### Patch Changes + +- [`3f8203bd`](https://github.com/wevm/wagmi/commit/3f8203bd77fcf6b6756640b5971d09741ae3853d) Thanks [@tmm](https://github.com/tmm)! - Set Wagmi-related package versions to latest. + +## 2.0.9 + +### Patch Changes + +- [#3518](https://github.com/wevm/wagmi/pull/3518) [`338e857d`](https://github.com/wevm/wagmi/commit/338e857d8cb2fe85e13d9207bef14cada1c1962d) Thanks [@tmm](https://github.com/tmm)! - Bumped dependencies. + +## 2.0.8 + +### Patch Changes + +- [#3510](https://github.com/wevm/wagmi/pull/3510) [`660ff80d`](https://github.com/wevm/wagmi/commit/660ff80d5b046967a446eba43ee54b8359a37d0d) Thanks [@tmm](https://github.com/tmm)! - Fixed issue where connectors returning multiple addresses didn't checksum correctly. + +## 2.0.7 + +### Patch Changes + +- [#3496](https://github.com/wevm/wagmi/pull/3496) [`ba7f8a75`](https://github.com/wevm/wagmi/commit/ba7f8a758efb07664c6e401b5e7e325e7c62341b) Thanks [@tmm](https://github.com/tmm)! - Bumped dependencies. + +## 2.0.6 + +### Patch Changes + +- [#3427](https://github.com/wevm/wagmi/pull/3427) [`370f1b4a`](https://github.com/wevm/wagmi/commit/370f1b4a3f154d181acf381c31c2e7862e22c0e4) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Bumped dependencies. + +## 2.0.5 + +### Patch Changes + +- [#3459](https://github.com/wevm/wagmi/pull/3459) [`d950b666`](https://github.com/wevm/wagmi/commit/d950b666b56700ca039ce16cdfdf34564991e7f5) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Bumped dependencies + +## 2.0.4 + +### Patch Changes + +- [#3443](https://github.com/wevm/wagmi/pull/3443) [`007024a6`](https://github.com/wevm/wagmi/commit/007024a684ddbecf924cdc06dd6a8854fc3d5eeb) Thanks [@jmrossy](https://github.com/jmrossy)! - Bumped dependencies. + +- [#3447](https://github.com/wevm/wagmi/pull/3447) [`a02a26ad`](https://github.com/wevm/wagmi/commit/a02a26ad030d3afb78f744377d61b5c60b65d97a) Thanks [@tmm](https://github.com/tmm)! - Bumped dependencies. + +## 2.0.3 + +### Patch Changes + +- [`ec0d8b41`](https://github.com/wevm/wagmi/commit/ec0d8b4112181fefb11025e436a94a6114761d37) Thanks [@tmm](https://github.com/tmm)! - Added note to `metaMask` connector. + +## 2.0.2 + +### Patch Changes + +- [#3384](https://github.com/wevm/wagmi/pull/3384) [`ee868c33`](https://github.com/wevm/wagmi/commit/ee868c3385dae511230b6ddcb5627c1293cc1844) Thanks [@tmm](https://github.com/tmm)! - Fixed connectors not bubbling error when connecting with `chainId` and subsequent user rejection. + +## 2.0.1 + +### Major Changes + +- [#3333](https://github.com/wevm/wagmi/pull/3333) [`b3a0baaa`](https://github.com/wevm/wagmi/commit/b3a0baaaee7decf750d376aab2502cd33ca4825a) Thanks [@tmm](https://github.com/tmm)! - Added support for Wagmi 2.0. + +## 1.0.5 + +### Patch Changes + +- 6ba996f: Fixed optional WalletConnect Cloud Project ID prompt + +## 1.0.4 + +### Patch Changes + +- eb8dd9d: Updated wagmi & viem. Added ConnectKit template back in. + +## 1.0.3 + +### Patch Changes + +- 00d9080: Added RainbowKit & Web3Modal wagmi v1 templates + +## 1.0.2 + +### Patch Changes + +- 3c65f77: Fixed Next.js default template title + +## 1.0.0 + +### Major Changes + +- affc13e: Updated to wagmi v1. + +## 0.1.19 + +### Patch Changes + +- 1282f0e: Updated templates to use WalletConnect v2 by default + +## 0.1.18 + +### Patch Changes + +- 12dcfe0: Updated wagmi to 0.12 in ConnectKit templates. + +## 0.1.17 + +### Patch Changes + +- 6eba01a: Updated wagmi to 0.12. +- 3a0ab8c: Added .env to .gitignore in templates. + +## 0.1.16 + +### Patch Changes + +- 7ad50f1: Upgraded `@wagmi/cli` + +## 0.1.15 + +### Patch Changes + +- 6e30599: Added `test` config to `foundry.toml` on the Foundry templates. + +## 0.1.14 + +### Patch Changes + +- 19f3675: Bumped `wagmi` to `~0.11.0`. + +## 0.1.13 + +### Patch Changes + +- c1ab75c: Bump @wagmi/cli + +## 0.1.12 + +### Patch Changes + +- af6e551: Added templates for `@wagmi/cli`: + + - `@wagmi/cli (Mint NFT Example)` + - `@wagmi/cli + ERC20` + - `@wagmi/cli + Etherscan (Mint NFT Example)` + - `@wagmi/cli + Foundry (Counter.sol Example)` + +## 0.1.11 + +### Patch Changes + +- cc638dd: Fixed an issue where Vite projects used `process.env` instead of `import.meta.env`. +- 75d1c2d: Updated `wagmi` to `~0.10.0`. + +## 0.1.10 + +### Patch Changes + +- 9cd7140: Amend gitignore files for Vite templates + +## 0.1.9 + +### Patch Changes + +- 904a2e1: Fixed import env variables in Vite (React) templates + +## 0.1.8 + +### Patch Changes + +- 65cc841: Update RainbowKit & ConnectKit templates to `wagmi@~0.9.0` + +## 0.1.7 + +### Patch Changes + +- a59d9c5: Upgrade `default` & `web3modal` templates to `wagmi@0.9` + +## 0.1.6 + +### Patch Changes + +- b544457: Updated `connectkit` to `1.1.0` in the ConnectKit templates + +## 0.1.5 + +### Patch Changes + +- 6bd6c74: Updated repo link in package.json + +## 0.1.4 + +### Patch Changes + +- c39666b: Added ability to select providers +- 37708ed: **Added ability to select frameworks.** + + Each directory in `templates/` now mirrors a "framework", where its child directories mirror a "template" for that framework. + + Example: + + ``` + templates/ + next/ + connectkit/ + default/ + rainbowkit/ + web3modal + vite-react/ + connectkit/ + default/ + rainbowkit/ + web3modal/ + ``` + +- 399d2b9: Moved template configuration to the template level + added hooks + +## 0.1.3 + +### Patch Changes + +- 353332a: Added Web3Modal template +- dd95b14: **next-with-connectkit**: Update `connectkit` to `^1.0.0` + +## 0.1.2 + +### Patch Changes + +- 34f666b: Fixed issue where package manager install process would not log error + +## 0.1.1 + +### Patch Changes + +- 900cbdc: Updated `@rainbow-me/rainbowkit` dependency in Next + RainbowKit template + +## 0.1.0 + +### Minor Changes + +- 23993d2: ## šŸŽ‰ Initial release šŸŽ‰ + + Get up and running quickly with wagmi by using the `create-wagmi` CLI. This tool interactively scaffolds a new wagmi project for you so you can start building instantly without the hassle of setting up `git`, installing packages, worrying about TypeScript configuration, etc. + + To get started, `create-wagmi` can be instantiated with one of your favorite package managers: + + ```bash + npm init wagmi + # or + pnpm create wagmi + # or + yarn create wagmi + ``` diff --git a/wagmi-project/packages/create-wagmi/README.md b/wagmi-project/packages/create-wagmi/README.md new file mode 100644 index 0000000000..f923127ca2 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/README.md @@ -0,0 +1,17 @@ +# create-wagmi + +Get up and running quickly with [Wagmi](https://wagmi.sh) by using the `create-wagmi` CLI. + +## Installation + +```bash +npm create wagmi +# or +pnpm create wagmi +# or +yarn create wagmi +``` + +## Documentation + +For documentation and guides, visit [wagmi.sh](https://wagmi.sh/cli/create-wagmi). diff --git a/wagmi-project/packages/create-wagmi/package.json b/wagmi-project/packages/create-wagmi/package.json new file mode 100644 index 0000000000..7b6798c628 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/package.json @@ -0,0 +1,49 @@ +{ + "name": "create-wagmi", + "description": "Create Wagmi apps with one command", + "version": "2.0.14", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/wevm/wagmi.git", + "directory": "packages/create-wagmi" + }, + "scripts": { + "build": "pnpm run clean && pnpm run build:esm+types", + "build:esm+types": "tsc --project tsconfig.build.json --outDir ./dist/esm --declaration --declarationMap --declarationDir ./dist/types", + "check:types": "tsc --noEmit", + "clean": "rm -rf dist tsconfig.tsbuildinfo", + "dev": "bun src/cli.ts", + "test:build": "publint --strict" + }, + "files": [ + "dist/**", + "!dist/**/*.tsbuildinfo", + "src/**/*.ts", + "!src/**/*.test.ts", + "!src/**/*.test-d.ts", + "templates/**" + ], + "bin": { + "wagmi": "./dist/esm/cli.js" + }, + "sideEffects": false, + "type": "module", + "exports": { + "./package.json": "./package.json" + }, + "dependencies": { + "cac": "^6.7.14", + "cross-spawn": "^7.0.5", + "picocolors": "^1.0.0", + "prompts": "^2.4.2" + }, + "devDependencies": { + "@types/cross-spawn": "^6.0.6", + "@types/node": "^20.12.10", + "@types/prompts": "^2.4.9" + }, + "contributors": ["awkweb.eth ", "jxom.eth "], + "funding": "https://github.com/sponsors/wevm", + "keywords": ["wagmi", "eth", "ethereum", "dapps", "wallet", "web3", "cli"] +} diff --git a/wagmi-project/packages/create-wagmi/src/cli.test.ts b/wagmi-project/packages/create-wagmi/src/cli.test.ts new file mode 100644 index 0000000000..4d6915a6f3 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/src/cli.test.ts @@ -0,0 +1,151 @@ +import { + type ExecSyncOptionsWithStringEncoding, + execSync, +} from 'node:child_process' +import { mkdirSync, readdirSync, writeFileSync } from 'node:fs' +import { rm } from 'node:fs/promises' +import { join } from 'node:path' +import pc from 'picocolors' +import { afterEach, beforeAll, expect, test } from 'vitest' + +import { version } from './version.js' + +const cliPath = join(__dirname, '../dist/esm/cli.js') + +const projectName = 'test-app' +const genPath = join(__dirname, projectName) + +function run( + args: string[], + options: ExecSyncOptionsWithStringEncoding = { encoding: 'utf8' }, +): string { + return execSync(`node ${cliPath} ${args.join(' ')}`, options) +} + +function createNonEmptyDir() { + mkdirSync(genPath, { recursive: true }) + const file = join(genPath, 'foo') + writeFileSync(file, 'bar') +} + +beforeAll(async () => { + execSync('pnpm --filter create-wagmi build') + await rm(genPath, { recursive: true, force: true }) +}) +afterEach(async () => { + await rm(genPath, { recursive: true, force: true }) +}) + +test('prompts for the project name if none supplied', () => { + const stdout = run([]) + expect(stdout).toContain('Project name:') +}) + +test('prompts for the framework if none supplied when target dir is current directory', () => { + mkdirSync(genPath) + const stdout = run(['.'], { cwd: genPath, encoding: 'utf8' }) + expect(stdout).toContain('Select a framework:') +}) + +test('prompts for the framework if none supplied', () => { + const stdout = run([projectName]) + expect(stdout).toContain('Select a framework:') +}) + +test('prompts for the framework on not supplying a value for --template', () => { + const stdout = run([projectName, '--template']) + expect(stdout).toContain('Select a framework:') +}) + +test('prompts for the framework on supplying an invalid template', () => { + const stdout = run([projectName, '--template', 'unknown']) + expect(stdout).toContain( + `"unknown" isn't a valid template. Please choose from below:`, + ) +}) + +test('asks to overwrite non-empty target directory', () => { + createNonEmptyDir() + const stdout = run([projectName], { cwd: __dirname, encoding: 'utf8' }) + expect(stdout).toContain(`Target directory "${projectName}" is not empty.`) +}) + +test('asks to overwrite non-empty current directory', () => { + createNonEmptyDir() + const stdout = run(['.'], { cwd: genPath, encoding: 'utf8' }) + expect(stdout).toContain('Current directory is not empty.') +}) + +const templateFiles = readdirSync( + join(cliPath, '../../../templates/vite-react'), +) + .map((filePath) => { + if (filePath === '_gitignore') return '.gitignore' + if (filePath === '_env.local') return '.env.local' + if (filePath === '_npmrc') return '.npmrc' + return filePath + }) + .sort() + +test('successfully scaffolds a project based on vite-react starter template', () => { + mkdirSync(genPath, { recursive: true }) + const stdout = run([projectName, '--template', 'vite-react'], { + cwd: __dirname, + encoding: 'utf8', + }) + const generatedFiles = readdirSync(genPath).sort() + + expect(stdout).toContain(`Scaffolding project in ${genPath}`) + expect(templateFiles).toEqual(generatedFiles) +}) + +test('works with the -t alias', () => { + mkdirSync(genPath, { recursive: true }) + const stdout = run([projectName, '-t', 'vite-react'], { + cwd: __dirname, + encoding: 'utf8', + }) + const generatedFiles = readdirSync(genPath).sort() + + expect(stdout).toContain(`Scaffolding project in ${genPath}`) + expect(templateFiles).toEqual(generatedFiles) +}) + +test('uses different package manager', () => { + mkdirSync(genPath, { recursive: true }) + const stdout = run([projectName, '--bun', '-t', 'vite-react'], { + cwd: __dirname, + encoding: 'utf8', + }) + + expect(stdout).toContain('bun install') +}) + +test('shows help', () => { + const stdout = run(['--help']) + expect( + stdout + .replace(version, 'x.y.z') + .replace(pc.green(''), ''), + ).toMatchInlineSnapshot(` + "create-wagmi/x.y.z + + Usage: + $ create-wagmi [options] + + Options: + -t, --template [name] Template to bootstrap with. Available: vite-react, next, vite-vue, nuxt, vite-vanilla + --bun Use bun as your package manager + --npm Use npm as your package manager + --pnpm Use pnpm as your package manager + --yarn Use yarn as your package manager + -h, --help Display this message + -v, --version Display version number + " + `) +}) + +test('shows version', () => { + const stdout = run(['--version']) + expect(stdout).toContain(`create-wagmi/${version} `) +}) diff --git a/wagmi-project/packages/create-wagmi/src/cli.ts b/wagmi-project/packages/create-wagmi/src/cli.ts new file mode 100644 index 0000000000..ecb6a25a4c --- /dev/null +++ b/wagmi-project/packages/create-wagmi/src/cli.ts @@ -0,0 +1,284 @@ +#!/usr/bin/env node +import * as fs from 'node:fs' +import * as path from 'node:path' +import { fileURLToPath } from 'node:url' +import { cac } from 'cac' +import spawn from 'cross-spawn' +import pc from 'picocolors' +import prompts from 'prompts' + +import { type Framework, frameworks } from './frameworks.js' +import { + copy, + emptyDir, + formatTargetDir, + isEmpty, + isValidPackageName, + pkgFromUserAgent, + toValidPackageName, +} from './utils.js' +import { version } from './version.js' + +const templates = frameworks + .map((f) => f.variants?.map((v) => v.name) || [f.name]) + .reduce((a, b) => a.concat(b), []) + +const cli = cac('create-wagmi') + +cli + .usage(`${pc.green('')} [options]`) + .option( + '-t, --template [name]', + `Template to bootstrap with. Available: ${templates + .sort((a, b) => (a && !b ? -1 : 1)) + .join(', ')}`, + ) + .option('--bun', 'Use bun as your package manager') + .option('--npm', 'Use npm as your package manager') + .option('--pnpm', 'Use pnpm as your package manager') + .option('--yarn', 'Use yarn as your package manager') + +cli.help() +cli.version(version) + +const cwd = process.cwd() + +const renameFiles: Record = { + '_env.local': '.env.local', + // https://github.com/npm/npm/issues/1862 + _gitignore: '.gitignore', + _npmrc: '.npmrc', +} + +const defaultTargetDir = 'wagmi-project' + +async function init() { + const { args, options } = cli.parse(process.argv) + if (options.help) return + if (options.version) return + + const argTargetDir = formatTargetDir(args[0]) + const argTemplate = options.template || options.t + + let targetDir = argTargetDir || defaultTargetDir + function getProjectName() { + return targetDir === '.' ? path.basename(path.resolve()) : targetDir + } + + let result: prompts.Answers< + 'framework' | 'overwrite' | 'packageName' | 'projectName' | 'variant' + > + try { + result = await prompts( + [ + { + type: argTargetDir ? null : 'text', + name: 'projectName', + message: pc.reset('Project name:'), + initial: defaultTargetDir, + onState(state) { + targetDir = formatTargetDir(state.value) || defaultTargetDir + }, + }, + { + type() { + return !fs.existsSync(targetDir) || isEmpty(targetDir) + ? null + : 'confirm' + }, + name: 'overwrite', + message() { + return `${ + targetDir === '.' + ? 'Current directory' + : `Target directory "${targetDir}"` + } is not empty. Remove existing files and continue?` + }, + }, + { + type(_, { overwrite }: { overwrite?: boolean }) { + if (overwrite === false) + throw new Error(`${pc.red('āœ–')} Operation cancelled`) + return null + }, + name: 'overwriteChecker', + }, + { + type() { + return isValidPackageName(getProjectName()) ? null : 'text' + }, + name: 'packageName', + message: pc.reset('Package name:'), + initial() { + return toValidPackageName(getProjectName()) + }, + validate(dir) { + return isValidPackageName(dir) || 'Invalid package.json name' + }, + }, + { + type: + argTemplate && templates.includes(argTemplate) ? null : 'select', + name: 'framework', + message: + typeof argTemplate === 'string' && !templates.includes(argTemplate) + ? pc.reset( + `"${argTemplate}" isn't a valid template. Please choose from below: `, + ) + : pc.reset('Select a framework:'), + initial: 0, + choices: frameworks.map((framework) => { + const frameworkColor = framework.color + return { + title: frameworkColor(framework.display || framework.name), + value: framework, + } + }), + }, + { + type(framework: Framework) { + return framework?.variants?.length > 1 ? 'select' : null + }, + name: 'variant', + message: pc.reset('Select a variant:'), + choices(framework: Framework) { + return framework.variants.map((variant) => { + const variantColor = variant.color + return { + title: variantColor(variant.display || variant.name), + value: variant.name, + } + }) + }, + }, + ], + { + onCancel() { + throw new Error(`${pc.red('āœ–')} Operation cancelled`) + }, + }, + ) + } catch (error) { + // biome-ignore lint/suspicious/noConsoleLog: + console.log((error as Error).message) + return + } + + // user choice associated with prompts + const { + framework, + overwrite, + packageName, + variant = framework?.variants[0]?.name, + } = result + + const root = path.join(cwd, targetDir) + + if (overwrite) emptyDir(root) + else if (!fs.existsSync(root)) fs.mkdirSync(root, { recursive: true }) + + // determine template + const template: string = variant || framework?.name || argTemplate + + const pkgInfo = pkgFromUserAgent(process.env.npm_config_user_agent) + type PkgManager = 'bun' | 'npm' | 'pnpm' | 'yarn' + let pkgManager: PkgManager + if (options.bun) pkgManager = 'bun' + else if (options.npm) pkgManager = 'npm' + else if (options.pnpm) pkgManager = 'pnpm' + else if (options.yarn) pkgManager = 'yarn' + else pkgManager = pkgInfo ? (pkgInfo.name as PkgManager) : 'npm' + const isYarn1 = pkgManager === 'yarn' && pkgInfo?.version?.startsWith('1.') + + const { customCommand } = + frameworks.flatMap((f) => f.variants).find((v) => v.name === template) ?? {} + + if (customCommand) { + const fullCustomCommand = customCommand + .replace(/^npm create /, () => { + // `bun create` uses it's own set of templates, + // the closest alternative is using `bun x` directly on the package + if (pkgManager === 'bun') return 'bun x create-' + return `${pkgManager} create ` + }) + // Only Yarn 1.x doesn't support `@version` in the `create` command + .replace('@latest', () => (isYarn1 ? '' : '@latest')) + .replace(/^npm exec/, () => { + // Prefer `pnpm dlx`, `yarn dlx`, or `bun x` + if (pkgManager === 'pnpm') return 'pnpm dlx' + if (pkgManager === 'yarn' && !isYarn1) return 'yarn dlx' + if (pkgManager === 'bun') return 'bun x' + // Use `npm exec` in all other cases, + // including Yarn 1.x and other custom npm clients. + return 'npm exec' + }) + + const [command, ...args] = fullCustomCommand.split(' ') + // we replace TARGET_DIR here because targetDir may include a space + const replacedArgs = args.map((arg) => arg.replace('TARGET_DIR', targetDir)) + const { status } = spawn.sync(command!, replacedArgs, { + stdio: 'inherit', + }) + process.exit(status ?? 0) + } + + // biome-ignore lint/suspicious/noConsoleLog: + console.log(`\nScaffolding project in ${root}...`) + + const templateDir = path.resolve( + fileURLToPath(import.meta.url), + '../../../templates', + template, + ) + + function write(file: string, content?: string) { + const targetPath = path.join(root, renameFiles[file] ?? file) + if (content) fs.writeFileSync(targetPath, content) + else copy(path.join(templateDir, file), targetPath) + } + + const files = fs.readdirSync(templateDir) + for (const file of files.filter((f) => f !== 'package.json')) { + write(file) + } + + const pkg = JSON.parse( + fs.readFileSync(path.join(templateDir, 'package.json'), 'utf-8'), + ) + + pkg.name = packageName || getProjectName() + + write('package.json', `${JSON.stringify(pkg, null, 2)}\n`) + + const cdProjectName = path.relative(cwd, root) + // biome-ignore lint/suspicious/noConsoleLog: + console.log('\nDone. Now run:\n') + if (root !== cwd) + // biome-ignore lint/suspicious/noConsoleLog: + console.log( + ` cd ${ + cdProjectName.includes(' ') ? `"${cdProjectName}"` : cdProjectName + }`, + ) + + switch (pkgManager) { + case 'yarn': + // biome-ignore lint/suspicious/noConsoleLog: + console.log(' yarn') + // biome-ignore lint/suspicious/noConsoleLog: + console.log(' yarn dev') + break + default: + // biome-ignore lint/suspicious/noConsoleLog: + console.log(` ${pkgManager} install`) + // biome-ignore lint/suspicious/noConsoleLog: + console.log(` ${pkgManager} run dev`) + break + } + // biome-ignore lint/suspicious/noConsoleLog: + console.log() +} + +init().catch((e) => { + console.error(e) +}) diff --git a/wagmi-project/packages/create-wagmi/src/frameworks.ts b/wagmi-project/packages/create-wagmi/src/frameworks.ts new file mode 100644 index 0000000000..1b414bafc8 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/src/frameworks.ts @@ -0,0 +1,66 @@ +import pc from 'picocolors' + +type ColorFunc = (str: string | number) => string + +type FrameworkVariant = { + name: string + display: string + color: ColorFunc + customCommand?: string +} + +export type Framework = { + name: string + display: string + color: ColorFunc + variants: readonly FrameworkVariant[] +} + +export const frameworks: readonly Framework[] = [ + { + name: 'react', + display: 'React', + color: pc.cyan, + variants: [ + { + name: 'vite-react', + display: 'Vite', + color: pc.blue, + }, + { + name: 'next', + display: 'Next', + color: pc.yellow, + }, + ], + }, + { + name: 'vue', + display: 'Vue', + color: pc.green, + variants: [ + { + name: 'vite-vue', + display: 'Vite', + color: pc.blue, + }, + { + name: 'nuxt', + display: 'Nuxt', + color: pc.yellow, + }, + ], + }, + { + name: 'vanilla', + display: 'Vanilla', + color: pc.magenta, + variants: [ + { + name: 'vite-vanilla', + display: 'Vite', + color: pc.blue, + }, + ], + }, +] diff --git a/wagmi-project/packages/create-wagmi/src/index.test-d.ts b/wagmi-project/packages/create-wagmi/src/index.test-d.ts new file mode 100644 index 0000000000..b056d56358 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/src/index.test-d.ts @@ -0,0 +1,4 @@ +import { expectTypeOf } from 'vitest' + +// noop test because vitest typecheck fails unless each workspace project has type test +expectTypeOf(1).toEqualTypeOf() diff --git a/wagmi-project/packages/create-wagmi/src/utils.ts b/wagmi-project/packages/create-wagmi/src/utils.ts new file mode 100644 index 0000000000..d04f60ed93 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/src/utils.ts @@ -0,0 +1,79 @@ +import * as fs from 'node:fs' +import * as path from 'node:path' + +export function formatTargetDir(targetDir: string | undefined) { + return targetDir?.trim().replace(/\/+$/g, '') +} + +export function copy(src: string, dest: string) { + const stat = fs.statSync(src) + if (stat.isDirectory()) copyDir(src, dest) + else fs.copyFileSync(src, dest) +} + +function copyDir(srcDir: string, destDir: string) { + fs.mkdirSync(destDir, { recursive: true }) + for (const file of fs.readdirSync(srcDir)) { + const srcFile = path.resolve(srcDir, file) + const destFile = path.resolve(destDir, file) + copy(srcFile, destFile) + } +} + +export function isValidPackageName(projectName: string) { + return /^(?:@[a-z\d\-*~][a-z\d\-*._~]*\/)?[a-z\d\-~][a-z\d\-._~]*$/.test( + projectName, + ) +} + +export function toValidPackageName(projectName: string) { + return projectName + .trim() + .toLowerCase() + .replace(/\s+/g, '-') + .replace(/^[._]/, '') + .replace(/[^a-z\d\-~]+/g, '-') +} + +export function isEmpty(path: string) { + const files = fs.readdirSync(path) + return files.length === 0 || (files.length === 1 && files[0] === '.git') +} + +export function emptyDir(dir: string) { + if (!fs.existsSync(dir)) return + for (const file of fs.readdirSync(dir)) { + if (file === '.git') continue + fs.rmSync(path.resolve(dir, file), { recursive: true, force: true }) + } +} + +export function pkgFromUserAgent(userAgent: string | undefined) { + if (!userAgent) return undefined + const pkgSpec = userAgent.split(' ')[0]! + const pkgSpecArr = pkgSpec.split('/') + return { + name: pkgSpecArr[0], + version: pkgSpecArr[1], + } +} + +// function setupReactSwc(root: string, isTs: boolean) { +// editFile(path.resolve(root, 'package.json'), (content) => { +// return content.replace( +// /"@vitejs\/plugin-react": ".+?"/, +// `"@vitejs/plugin-react-swc": "^3.3.2"`, +// ) +// }) +// editFile( +// path.resolve(root, `vite.config.${isTs ? 'ts' : 'js'}`), +// (content) => { +// return content.replace('@vitejs/plugin-react', '@vitejs/plugin-react-swc') +// }, +// ) +// } + +// function editFile(file: string, callback: (content: string) => string) { +// const content = fs.readFileSync(file, 'utf-8') +// fs.writeFileSync(file, callback(content), 'utf-8') +// } diff --git a/wagmi-project/packages/create-wagmi/src/version.ts b/wagmi-project/packages/create-wagmi/src/version.ts new file mode 100644 index 0000000000..5556800c0d --- /dev/null +++ b/wagmi-project/packages/create-wagmi/src/version.ts @@ -0,0 +1 @@ +export const version = '2.0.14' diff --git a/wagmi-project/packages/create-wagmi/templates/next/README.md b/wagmi-project/packages/create-wagmi/templates/next/README.md new file mode 100644 index 0000000000..bd3aa7b7f0 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/next/README.md @@ -0,0 +1 @@ +This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-wagmi`](https://github.com/wevm/wagmi/tree/main/packages/create-wagmi). diff --git a/wagmi-project/packages/create-wagmi/templates/next/_env.local b/wagmi-project/packages/create-wagmi/templates/next/_env.local new file mode 100644 index 0000000000..9a11dba16a --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/next/_env.local @@ -0,0 +1,2 @@ +NEXT_PUBLIC_WC_PROJECT_ID= +NEXT_TELEMETRY_DISABLED=1 \ No newline at end of file diff --git a/wagmi-project/packages/create-wagmi/templates/next/_gitignore b/wagmi-project/packages/create-wagmi/templates/next/_gitignore new file mode 100644 index 0000000000..8f322f0d8f --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/next/_gitignore @@ -0,0 +1,35 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/wagmi-project/packages/create-wagmi/templates/next/_npmrc b/wagmi-project/packages/create-wagmi/templates/next/_npmrc new file mode 100644 index 0000000000..ca1e9d98b5 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/next/_npmrc @@ -0,0 +1 @@ +legacy-peer-deps = true \ No newline at end of file diff --git a/wagmi-project/packages/create-wagmi/templates/next/next-env.d.ts b/wagmi-project/packages/create-wagmi/templates/next/next-env.d.ts new file mode 100644 index 0000000000..4f11a03dc6 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/next/next-env.d.ts @@ -0,0 +1,5 @@ +/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/basic-features/typescript for more information. diff --git a/wagmi-project/packages/create-wagmi/templates/next/next.config.js b/wagmi-project/packages/create-wagmi/templates/next/next.config.js new file mode 100644 index 0000000000..767719fc4f --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/next/next.config.js @@ -0,0 +1,4 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = {} + +module.exports = nextConfig diff --git a/wagmi-project/packages/create-wagmi/templates/next/package.json b/wagmi-project/packages/create-wagmi/templates/next/package.json new file mode 100644 index 0000000000..d3867228f9 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/next/package.json @@ -0,0 +1,32 @@ +{ + "name": "wagmi-next-starter", + "private": true, + "version": "0.0.0", + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "next lint" + }, + "dependencies": { + "@tanstack/react-query": "5.45.1", + "next": "15.2.4", + "react": "^19.1.0", + "react-dom": "^18.3.1", + "viem": "latest", + "wagmi": "latest" + }, + "devDependencies": { + "@types/node": "^20.12.10", + "@types/react": "^18.3.1", + "@types/react-dom": "^18.3.0", + "@wagmi/cli": "latest", + "bufferutil": "^4.0.8", + "encoding": "^0.1.13", + "lokijs": "^1.5.12", + "pino-pretty": "^10.3.1", + "supports-color": "^9.4.0", + "typescript": "^5.4.5", + "utf-8-validate": "^5.0.2" + } +} diff --git a/wagmi-project/packages/create-wagmi/templates/next/src/app/globals.css b/wagmi-project/packages/create-wagmi/templates/next/src/app/globals.css new file mode 100644 index 0000000000..0733a7ee6b --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/next/src/app/globals.css @@ -0,0 +1,21 @@ +:root { + background-color: #181818; + color: rgba(255, 255, 255, 0.87); + color-scheme: light dark; + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + font-synthesis: none; + font-weight: 400; + line-height: 1.5; + text-rendering: optimizeLegibility; + + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-text-size-adjust: 100%; +} + +@media (prefers-color-scheme: light) { + :root { + background-color: #f8f8f8; + color: #181818; + } +} diff --git a/wagmi-project/packages/create-wagmi/templates/next/src/app/layout.tsx b/wagmi-project/packages/create-wagmi/templates/next/src/app/layout.tsx new file mode 100644 index 0000000000..da5b293bf0 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/next/src/app/layout.tsx @@ -0,0 +1,30 @@ +import './globals.css' +import type { Metadata } from 'next' +import { Inter } from 'next/font/google' +import { headers } from 'next/headers' +import { type ReactNode } from 'react' +import { cookieToInitialState } from 'wagmi' + +import { getConfig } from '../wagmi' +import { Providers } from './providers' + +const inter = Inter({ subsets: ['latin'] }) + +export const metadata: Metadata = { + title: 'Create Wagmi', + description: 'Generated by create-wagmi', +} + +export default async function RootLayout(props: { children: ReactNode }) { + const initialState = cookieToInitialState( + getConfig(), + (await headers()).get('cookie'), + ) + return ( + + + {props.children} + + + ) +} diff --git a/wagmi-project/packages/create-wagmi/templates/next/src/app/page.tsx b/wagmi-project/packages/create-wagmi/templates/next/src/app/page.tsx new file mode 100644 index 0000000000..f5dcbdf812 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/next/src/app/page.tsx @@ -0,0 +1,48 @@ +'use client' + +import { useAccount, useConnect, useDisconnect } from 'wagmi' + +function App() { + const account = useAccount() + const { connectors, connect, status, error } = useConnect() + const { disconnect } = useDisconnect() + + return ( + <> +
+

Account

+ +
+ status: {account.status} +
+ addresses: {JSON.stringify(account.addresses)} +
+ chainId: {account.chainId} +
+ + {account.status === 'connected' && ( + + )} +
+ +
+

Connect

+ {connectors.map((connector) => ( + + ))} +
{status}
+
{error?.message}
+
+ + ) +} + +export default App diff --git a/wagmi-project/packages/create-wagmi/templates/next/src/app/providers.tsx b/wagmi-project/packages/create-wagmi/templates/next/src/app/providers.tsx new file mode 100644 index 0000000000..b4086cf531 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/next/src/app/providers.tsx @@ -0,0 +1,23 @@ +'use client' + +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { type ReactNode, useState } from 'react' +import { type State, WagmiProvider } from 'wagmi' + +import { getConfig } from '@/wagmi' + +export function Providers(props: { + children: ReactNode + initialState?: State +}) { + const [config] = useState(() => getConfig()) + const [queryClient] = useState(() => new QueryClient()) + + return ( + + + {props.children} + + + ) +} diff --git a/wagmi-project/packages/create-wagmi/templates/next/src/wagmi.ts b/wagmi-project/packages/create-wagmi/templates/next/src/wagmi.ts new file mode 100644 index 0000000000..b34f4c0079 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/next/src/wagmi.ts @@ -0,0 +1,28 @@ +import { http, cookieStorage, createConfig, createStorage } from 'wagmi' +import { mainnet, sepolia } from 'wagmi/chains' +import { coinbaseWallet, injected, walletConnect } from 'wagmi/connectors' + +export function getConfig() { + return createConfig({ + chains: [mainnet, sepolia], + connectors: [ + injected(), + coinbaseWallet(), + walletConnect({ projectId: process.env.NEXT_PUBLIC_WC_PROJECT_ID }), + ], + storage: createStorage({ + storage: cookieStorage, + }), + ssr: true, + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, + }) +} + +declare module 'wagmi' { + interface Register { + config: ReturnType + } +} diff --git a/wagmi-project/packages/create-wagmi/templates/next/tsconfig.json b/wagmi-project/packages/create-wagmi/templates/next/tsconfig.json new file mode 100644 index 0000000000..e59724b283 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/next/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": ["./src/*"] + } + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + "exclude": ["node_modules"] +} diff --git a/wagmi-project/packages/create-wagmi/templates/nuxt/_env.local b/wagmi-project/packages/create-wagmi/templates/nuxt/_env.local new file mode 100644 index 0000000000..437e9e3e7b --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/nuxt/_env.local @@ -0,0 +1,3 @@ +NUXT_PUBLIC_WC_PROJECT_ID= +NUXT_TELEMETRY_DISABLED=1 + diff --git a/wagmi-project/packages/create-wagmi/templates/nuxt/_gitignore b/wagmi-project/packages/create-wagmi/templates/nuxt/_gitignore new file mode 100644 index 0000000000..4a7f73a2ed --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/nuxt/_gitignore @@ -0,0 +1,24 @@ +# Nuxt dev/build outputs +.output +.data +.nuxt +.nitro +.cache +dist + +# Node dependencies +node_modules + +# Logs +logs +*.log + +# Misc +.DS_Store +.fleet +.idea + +# Local env files +.env +.env.* +!.env.example diff --git a/wagmi-project/packages/create-wagmi/templates/nuxt/_npmrc b/wagmi-project/packages/create-wagmi/templates/nuxt/_npmrc new file mode 100644 index 0000000000..057cc841f2 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/nuxt/_npmrc @@ -0,0 +1,2 @@ +legacy-peer-deps = true + diff --git a/wagmi-project/packages/create-wagmi/templates/nuxt/app.vue b/wagmi-project/packages/create-wagmi/templates/nuxt/app.vue new file mode 100644 index 0000000000..98b46bf528 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/nuxt/app.vue @@ -0,0 +1,28 @@ + + + diff --git a/wagmi-project/packages/create-wagmi/templates/nuxt/components/Account.vue b/wagmi-project/packages/create-wagmi/templates/nuxt/components/Account.vue new file mode 100644 index 0000000000..33f1491dac --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/nuxt/components/Account.vue @@ -0,0 +1,22 @@ + + + diff --git a/wagmi-project/packages/create-wagmi/templates/nuxt/components/Connect.vue b/wagmi-project/packages/create-wagmi/templates/nuxt/components/Connect.vue new file mode 100644 index 0000000000..93320448c0 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/nuxt/components/Connect.vue @@ -0,0 +1,19 @@ + + + diff --git a/wagmi-project/packages/create-wagmi/templates/nuxt/nuxt.config.ts b/wagmi-project/packages/create-wagmi/templates/nuxt/nuxt.config.ts new file mode 100644 index 0000000000..adfe7fd2d8 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/nuxt/nuxt.config.ts @@ -0,0 +1,7 @@ +import { defineNuxtConfig } from 'nuxt/config' + +// https://nuxt.com/docs/api/configuration/nuxt-config +export default defineNuxtConfig({ + devtools: { enabled: true }, + modules: ['@wagmi/vue/nuxt'], +}) diff --git a/wagmi-project/packages/create-wagmi/templates/nuxt/package.json b/wagmi-project/packages/create-wagmi/templates/nuxt/package.json new file mode 100644 index 0000000000..65ff657528 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/nuxt/package.json @@ -0,0 +1,21 @@ +{ + "name": "nuxt-app", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "build": "nuxt build", + "dev": "nuxt dev", + "generate": "nuxt generate", + "preview": "nuxt preview", + "postinstall": "nuxt prepare" + }, + "dependencies": { + "@tanstack/vue-query": ">=5.45.0", + "@wagmi/vue": "latest", + "nuxt": "^3.11.2", + "viem": "latest", + "vue": ">=3.4.21", + "vue-router": "^4.3.2" + } +} diff --git a/wagmi-project/packages/create-wagmi/templates/nuxt/plugins/wagmi.ts b/wagmi-project/packages/create-wagmi/templates/nuxt/plugins/wagmi.ts new file mode 100644 index 0000000000..b6abe5bcd2 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/nuxt/plugins/wagmi.ts @@ -0,0 +1,10 @@ +import { VueQueryPlugin } from '@tanstack/vue-query' +import { WagmiPlugin } from '@wagmi/vue' +import { defineNuxtPlugin } from 'nuxt/app' + +import { config } from '../wagmi' + +// TODO: Move to @wagmi/vue/nuxt nitro plugin +export default defineNuxtPlugin((nuxtApp) => { + nuxtApp.vueApp.use(WagmiPlugin, { config }).use(VueQueryPlugin, {}) +}) diff --git a/wagmi-project/packages/create-wagmi/templates/nuxt/server/tsconfig.json b/wagmi-project/packages/create-wagmi/templates/nuxt/server/tsconfig.json new file mode 100644 index 0000000000..b9ed69c19e --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/nuxt/server/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../.nuxt/tsconfig.server.json" +} diff --git a/wagmi-project/packages/create-wagmi/templates/nuxt/tsconfig.json b/wagmi-project/packages/create-wagmi/templates/nuxt/tsconfig.json new file mode 100644 index 0000000000..a746f2a70c --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/nuxt/tsconfig.json @@ -0,0 +1,4 @@ +{ + // https://nuxt.com/docs/guide/concepts/typescript + "extends": "./.nuxt/tsconfig.json" +} diff --git a/wagmi-project/packages/create-wagmi/templates/nuxt/wagmi.ts b/wagmi-project/packages/create-wagmi/templates/nuxt/wagmi.ts new file mode 100644 index 0000000000..83e8569ea8 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/nuxt/wagmi.ts @@ -0,0 +1,29 @@ +import { http, cookieStorage, createConfig, createStorage } from '@wagmi/vue' +import { mainnet, optimism, sepolia } from '@wagmi/vue/chains' +import { injected, metaMask, walletConnect } from '@wagmi/vue/connectors' + +export const config = createConfig({ + chains: [mainnet, sepolia, optimism], + connectors: [ + injected(), + walletConnect({ + projectId: process.env.NUXT_PUBLIC_WC_PROJECT_ID!, + }), + metaMask(), + ], + storage: createStorage({ + storage: cookieStorage, + }), + ssr: true, + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + [optimism.id]: http(), + }, +}) + +declare module '@wagmi/vue' { + interface Register { + config: typeof config + } +} diff --git a/wagmi-project/packages/create-wagmi/templates/vite-react/README.md b/wagmi-project/packages/create-wagmi/templates/vite-react/README.md new file mode 100644 index 0000000000..15f6f79541 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-react/README.md @@ -0,0 +1 @@ +This is a [Vite](https://vitejs.dev) project bootstrapped with [`create-wagmi`](https://github.com/wevm/wagmi/tree/main/packages/create-wagmi). diff --git a/wagmi-project/packages/create-wagmi/templates/vite-react/_env.local b/wagmi-project/packages/create-wagmi/templates/vite-react/_env.local new file mode 100644 index 0000000000..936f763762 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-react/_env.local @@ -0,0 +1 @@ +VITE_WC_PROJECT_ID= \ No newline at end of file diff --git a/wagmi-project/packages/create-wagmi/templates/vite-react/_gitignore b/wagmi-project/packages/create-wagmi/templates/vite-react/_gitignore new file mode 100644 index 0000000000..a547bf36d8 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-react/_gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/wagmi-project/packages/create-wagmi/templates/vite-react/_npmrc b/wagmi-project/packages/create-wagmi/templates/vite-react/_npmrc new file mode 100644 index 0000000000..ca1e9d98b5 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-react/_npmrc @@ -0,0 +1 @@ +legacy-peer-deps = true \ No newline at end of file diff --git a/wagmi-project/packages/create-wagmi/templates/vite-react/biome.json b/wagmi-project/packages/create-wagmi/templates/vite-react/biome.json new file mode 100644 index 0000000000..08eb8a26ab --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-react/biome.json @@ -0,0 +1,13 @@ +{ + "formatter": { + "enabled": true, + "indentStyle": "space", + "lineWidth": 120 + }, + "linter": { + "enabled": true + }, + "organizeImports": { + "enabled": true + } +} diff --git a/wagmi-project/packages/create-wagmi/templates/vite-react/index.html b/wagmi-project/packages/create-wagmi/templates/vite-react/index.html new file mode 100644 index 0000000000..f519ce85a7 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-react/index.html @@ -0,0 +1,12 @@ + + + + + + Create Wagmi + + +
+ + + diff --git a/wagmi-project/packages/create-wagmi/templates/vite-react/package.json b/wagmi-project/packages/create-wagmi/templates/vite-react/package.json new file mode 100644 index 0000000000..0eeaab9a10 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-react/package.json @@ -0,0 +1,29 @@ +{ + "name": "wagmi-vite-starter", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc && vite build", + "lint": "biome check .", + "preview": "vite preview" + }, + "dependencies": { + "@tanstack/react-query": "5.45.1", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "viem": "latest", + "wagmi": "latest" + }, + "devDependencies": { + "@biomejs/biome": "^1.8.0", + "@types/react": "^18.3.1", + "@types/react-dom": "^18.3.0", + "@vitejs/plugin-react": "^4.2.1", + "@wagmi/cli": "latest", + "buffer": "^6.0.3", + "typescript": "^5.8.3", + "vite": "^5.2.11" + } +} diff --git a/wagmi-project/packages/create-wagmi/templates/vite-react/src/App.tsx b/wagmi-project/packages/create-wagmi/templates/vite-react/src/App.tsx new file mode 100644 index 0000000000..faa8ce1c79 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-react/src/App.tsx @@ -0,0 +1,46 @@ +import { useAccount, useConnect, useDisconnect } from 'wagmi' + +function App() { + const account = useAccount() + const { connectors, connect, status, error } = useConnect() + const { disconnect } = useDisconnect() + + return ( + <> +
+

Account

+ +
+ status: {account.status} +
+ addresses: {JSON.stringify(account.addresses)} +
+ chainId: {account.chainId} +
+ + {account.status === 'connected' && ( + + )} +
+ +
+

Connect

+ {connectors.map((connector) => ( + + ))} +
{status}
+
{error?.message}
+
+ + ) +} + +export default App diff --git a/wagmi-project/packages/create-wagmi/templates/vite-react/src/index.css b/wagmi-project/packages/create-wagmi/templates/vite-react/src/index.css new file mode 100644 index 0000000000..0733a7ee6b --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-react/src/index.css @@ -0,0 +1,21 @@ +:root { + background-color: #181818; + color: rgba(255, 255, 255, 0.87); + color-scheme: light dark; + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + font-synthesis: none; + font-weight: 400; + line-height: 1.5; + text-rendering: optimizeLegibility; + + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-text-size-adjust: 100%; +} + +@media (prefers-color-scheme: light) { + :root { + background-color: #f8f8f8; + color: #181818; + } +} diff --git a/wagmi-project/packages/create-wagmi/templates/vite-react/src/main.tsx b/wagmi-project/packages/create-wagmi/templates/vite-react/src/main.tsx new file mode 100644 index 0000000000..d999e1a932 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-react/src/main.tsx @@ -0,0 +1,24 @@ +import { Buffer } from 'buffer' +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import React from 'react' +import ReactDOM from 'react-dom/client' +import { WagmiProvider } from 'wagmi' + +import App from './App.tsx' +import { config } from './wagmi.ts' + +import './index.css' + +globalThis.Buffer = Buffer + +const queryClient = new QueryClient() + +ReactDOM.createRoot(document.getElementById('root')!).render( + + + + + + + , +) diff --git a/wagmi-project/packages/create-wagmi/templates/vite-react/src/vite-env.d.ts b/wagmi-project/packages/create-wagmi/templates/vite-react/src/vite-env.d.ts new file mode 100644 index 0000000000..11f02fe2a0 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-react/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/wagmi-project/packages/create-wagmi/templates/vite-react/src/wagmi.ts b/wagmi-project/packages/create-wagmi/templates/vite-react/src/wagmi.ts new file mode 100644 index 0000000000..43cf231934 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-react/src/wagmi.ts @@ -0,0 +1,22 @@ +import { http, createConfig } from 'wagmi' +import { mainnet, sepolia } from 'wagmi/chains' +import { coinbaseWallet, injected, walletConnect } from 'wagmi/connectors' + +export const config = createConfig({ + chains: [mainnet, sepolia], + connectors: [ + injected(), + coinbaseWallet(), + walletConnect({ projectId: import.meta.env.VITE_WC_PROJECT_ID }), + ], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) + +declare module 'wagmi' { + interface Register { + config: typeof config + } +} diff --git a/wagmi-project/packages/create-wagmi/templates/vite-react/tsconfig.json b/wagmi-project/packages/create-wagmi/templates/vite-react/tsconfig.json new file mode 100644 index 0000000000..a7fc6fbf23 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-react/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/wagmi-project/packages/create-wagmi/templates/vite-react/tsconfig.node.json b/wagmi-project/packages/create-wagmi/templates/vite-react/tsconfig.node.json new file mode 100644 index 0000000000..42872c59f5 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-react/tsconfig.node.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/wagmi-project/packages/create-wagmi/templates/vite-react/vite.config.ts b/wagmi-project/packages/create-wagmi/templates/vite-react/vite.config.ts new file mode 100644 index 0000000000..36f7f4e1bc --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-react/vite.config.ts @@ -0,0 +1,7 @@ +import react from '@vitejs/plugin-react' +import { defineConfig } from 'vite' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [react()], +}) diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vanilla/_env.local b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/_env.local new file mode 100644 index 0000000000..936f763762 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/_env.local @@ -0,0 +1 @@ +VITE_WC_PROJECT_ID= \ No newline at end of file diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vanilla/_gitignore b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/_gitignore new file mode 100644 index 0000000000..a547bf36d8 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/_gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vanilla/_npmrc b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/_npmrc new file mode 100644 index 0000000000..ca1e9d98b5 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/_npmrc @@ -0,0 +1 @@ +legacy-peer-deps = true \ No newline at end of file diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vanilla/index.html b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/index.html new file mode 100644 index 0000000000..e2028cc129 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/index.html @@ -0,0 +1,12 @@ + + + + + + Create Wagmi + + +
+ + + diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vanilla/package.json b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/package.json new file mode 100644 index 0000000000..e48954313c --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/package.json @@ -0,0 +1,24 @@ +{ + "name": "wagmi-core-vanilla-starter", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc && vite build", + "preview": "vite preview" + }, + "dependencies": { + "@wagmi/connectors": "latest", + "@wagmi/core": "latest", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "viem": "latest" + }, + "devDependencies": { + "@wagmi/cli": "latest", + "buffer": "^6.0.3", + "typescript": "^5.8.3", + "vite": "^5.2.11" + } +} diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vanilla/src/main.ts b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/src/main.ts new file mode 100644 index 0000000000..f2b80f3459 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/src/main.ts @@ -0,0 +1,89 @@ +import { Buffer } from 'buffer' +import { connect, disconnect, reconnect, watchAccount } from '@wagmi/core' + +import './style.css' +import { config } from './wagmi' + +globalThis.Buffer = Buffer + +document.querySelector('#app')!.innerHTML = ` +
+
+

Account

+ +
+ status: +
+ addresses: +
+ chainId: +
+
+ +
+

Connect

+ ${config.connectors + .map( + (connector) => + ``, + ) + .join('')} +
+
+` + +setupApp(document.querySelector('#app')!) + +function setupApp(element: HTMLDivElement) { + const connectElement = element.querySelector('#connect') + const buttons = element.querySelectorAll('.connect') + for (const button of buttons) { + const connector = config.connectors.find( + (connector) => connector.uid === button.id, + )! + button.addEventListener('click', async () => { + try { + const errorElement = element.querySelector('#error') + if (errorElement) errorElement.remove() + await connect(config, { connector }) + } catch (error) { + const errorElement = document.createElement('div') + errorElement.id = 'error' + errorElement.innerText = (error as Error).message + connectElement?.appendChild(errorElement) + } + }) + } + + watchAccount(config, { + onChange(account) { + const accountElement = element.querySelector('#account')! + accountElement.innerHTML = ` +

Account

+
+ status: ${account.status} +
+ addresses: ${ + account.addresses ? JSON.stringify(account.addresses) : '' + } +
+ chainId: ${account.chainId ?? ''} +
+ ${ + account.status === 'connected' + ? `` + : '' + } + ` + + const disconnectButton = + element.querySelector('#disconnect') + if (disconnectButton) + disconnectButton.addEventListener('click', () => disconnect(config)) + }, + }) + + reconnect(config) + .then(() => {}) + .catch(() => {}) +} diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vanilla/src/style.css b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/src/style.css new file mode 100644 index 0000000000..0733a7ee6b --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/src/style.css @@ -0,0 +1,21 @@ +:root { + background-color: #181818; + color: rgba(255, 255, 255, 0.87); + color-scheme: light dark; + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + font-synthesis: none; + font-weight: 400; + line-height: 1.5; + text-rendering: optimizeLegibility; + + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-text-size-adjust: 100%; +} + +@media (prefers-color-scheme: light) { + :root { + background-color: #f8f8f8; + color: #181818; + } +} diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vanilla/src/vite-env.d.ts b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/src/vite-env.d.ts new file mode 100644 index 0000000000..11f02fe2a0 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vanilla/src/wagmi.ts b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/src/wagmi.ts new file mode 100644 index 0000000000..6baeff5293 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/src/wagmi.ts @@ -0,0 +1,16 @@ +import { coinbaseWallet, injected, walletConnect } from '@wagmi/connectors' +import { http, createConfig } from '@wagmi/core' +import { mainnet, sepolia } from '@wagmi/core/chains' + +export const config = createConfig({ + chains: [mainnet, sepolia], + connectors: [ + injected(), + coinbaseWallet(), + walletConnect({ projectId: import.meta.env.VITE_WC_PROJECT_ID }), + ], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vanilla/tsconfig.json b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/tsconfig.json new file mode 100644 index 0000000000..75abdef265 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vanilla/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "module": "ESNext", + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src"] +} diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vue/README.md b/wagmi-project/packages/create-wagmi/templates/vite-vue/README.md new file mode 100644 index 0000000000..15f6f79541 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vue/README.md @@ -0,0 +1 @@ +This is a [Vite](https://vitejs.dev) project bootstrapped with [`create-wagmi`](https://github.com/wevm/wagmi/tree/main/packages/create-wagmi). diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vue/_env.local b/wagmi-project/packages/create-wagmi/templates/vite-vue/_env.local new file mode 100644 index 0000000000..936f763762 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vue/_env.local @@ -0,0 +1 @@ +VITE_WC_PROJECT_ID= \ No newline at end of file diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vue/_gitignore b/wagmi-project/packages/create-wagmi/templates/vite-vue/_gitignore new file mode 100644 index 0000000000..a547bf36d8 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vue/_gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vue/_npmrc b/wagmi-project/packages/create-wagmi/templates/vite-vue/_npmrc new file mode 100644 index 0000000000..ca1e9d98b5 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vue/_npmrc @@ -0,0 +1 @@ +legacy-peer-deps = true \ No newline at end of file diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vue/biome.json b/wagmi-project/packages/create-wagmi/templates/vite-vue/biome.json new file mode 100644 index 0000000000..08eb8a26ab --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vue/biome.json @@ -0,0 +1,13 @@ +{ + "formatter": { + "enabled": true, + "indentStyle": "space", + "lineWidth": 120 + }, + "linter": { + "enabled": true + }, + "organizeImports": { + "enabled": true + } +} diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vue/index.html b/wagmi-project/packages/create-wagmi/templates/vite-vue/index.html new file mode 100644 index 0000000000..e2028cc129 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vue/index.html @@ -0,0 +1,12 @@ + + + + + + Create Wagmi + + +
+ + + diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vue/package.json b/wagmi-project/packages/create-wagmi/templates/vite-vue/package.json new file mode 100644 index 0000000000..8d306e620c --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vue/package.json @@ -0,0 +1,24 @@ +{ + "name": "wagmi-vue-vite-starter", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vue-tsc && vite build", + "lint": "biome check .", + "preview": "vite preview" + }, + "dependencies": { + "@tanstack/vue-query": ">=5.45.0", + "@wagmi/vue": "latest", + "viem": "latest", + "vue": ">=3.4.21" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^5.0.4", + "buffer": "^6.0.3", + "vite": "^5.2.11", + "vue-tsc": "^2.0.6" + } +} diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vue/src/App.vue b/wagmi-project/packages/create-wagmi/templates/vite-vue/src/App.vue new file mode 100644 index 0000000000..421aeb9a7b --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vue/src/App.vue @@ -0,0 +1,19 @@ + + + diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vue/src/components/Account.vue b/wagmi-project/packages/create-wagmi/templates/vite-vue/src/components/Account.vue new file mode 100644 index 0000000000..33f1491dac --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vue/src/components/Account.vue @@ -0,0 +1,22 @@ + + + diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vue/src/components/Connect.vue b/wagmi-project/packages/create-wagmi/templates/vite-vue/src/components/Connect.vue new file mode 100644 index 0000000000..93320448c0 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vue/src/components/Connect.vue @@ -0,0 +1,19 @@ + + + diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vue/src/main.ts b/wagmi-project/packages/create-wagmi/templates/vite-vue/src/main.ts new file mode 100644 index 0000000000..820eed3722 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vue/src/main.ts @@ -0,0 +1,17 @@ +import { Buffer } from 'buffer' +import { VueQueryPlugin } from '@tanstack/vue-query' +import { WagmiPlugin } from '@wagmi/vue' +import { createApp } from 'vue' + +// `@coinbase-wallet/sdk` uses `Buffer` +globalThis.Buffer = Buffer + +import App from './App.vue' +import './style.css' +import { config } from './wagmi' + +const app = createApp(App) + +app.use(WagmiPlugin, { config }).use(VueQueryPlugin, {}) + +app.mount('#app') diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vue/src/style.css b/wagmi-project/packages/create-wagmi/templates/vite-vue/src/style.css new file mode 100644 index 0000000000..0733a7ee6b --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vue/src/style.css @@ -0,0 +1,21 @@ +:root { + background-color: #181818; + color: rgba(255, 255, 255, 0.87); + color-scheme: light dark; + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + font-synthesis: none; + font-weight: 400; + line-height: 1.5; + text-rendering: optimizeLegibility; + + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-text-size-adjust: 100%; +} + +@media (prefers-color-scheme: light) { + :root { + background-color: #f8f8f8; + color: #181818; + } +} diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vue/src/vite-env.d.ts b/wagmi-project/packages/create-wagmi/templates/vite-vue/src/vite-env.d.ts new file mode 100644 index 0000000000..11f02fe2a0 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vue/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vue/src/wagmi.ts b/wagmi-project/packages/create-wagmi/templates/vite-vue/src/wagmi.ts new file mode 100644 index 0000000000..f0282e9490 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vue/src/wagmi.ts @@ -0,0 +1,25 @@ +import { http, createConfig, createStorage } from '@wagmi/vue' +import { mainnet, optimism, sepolia } from '@wagmi/vue/chains' +import { coinbaseWallet, walletConnect } from '@wagmi/vue/connectors' + +export const config = createConfig({ + chains: [mainnet, sepolia, optimism], + connectors: [ + walletConnect({ + projectId: import.meta.env.VITE_WC_PROJECT_ID, + }), + coinbaseWallet({ appName: 'Vite Vue Playground', darkMode: true }), + ], + storage: createStorage({ storage: localStorage, key: 'vite-vue' }), + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + [optimism.id]: http(), + }, +}) + +declare module '@wagmi/vue' { + interface Register { + config: typeof config + } +} diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vue/tsconfig.json b/wagmi-project/packages/create-wagmi/templates/vite-vue/tsconfig.json new file mode 100644 index 0000000000..9e03e60496 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vue/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "module": "ESNext", + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "preserve", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vue/tsconfig.node.json b/wagmi-project/packages/create-wagmi/templates/vite-vue/tsconfig.node.json new file mode 100644 index 0000000000..97ede7ee6f --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vue/tsconfig.node.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true, + "strict": true + }, + "include": ["vite.config.ts"] +} diff --git a/wagmi-project/packages/create-wagmi/templates/vite-vue/vite.config.ts b/wagmi-project/packages/create-wagmi/templates/vite-vue/vite.config.ts new file mode 100644 index 0000000000..c3fa62d865 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/templates/vite-vue/vite.config.ts @@ -0,0 +1,7 @@ +import vue from '@vitejs/plugin-vue' +import { defineConfig } from 'vite' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [vue()], +}) diff --git a/wagmi-project/packages/create-wagmi/tsconfig.build.json b/wagmi-project/packages/create-wagmi/tsconfig.build.json new file mode 100644 index 0000000000..45ae2069ef --- /dev/null +++ b/wagmi-project/packages/create-wagmi/tsconfig.build.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.base.json", + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.test.ts"], + "compilerOptions": { + "sourceMap": true + } +} diff --git a/wagmi-project/packages/create-wagmi/tsconfig.json b/wagmi-project/packages/create-wagmi/tsconfig.json new file mode 100644 index 0000000000..bd33919ac3 --- /dev/null +++ b/wagmi-project/packages/create-wagmi/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "./tsconfig.build.json", + "include": ["src/**/*.ts"], + "exclude": [] +} diff --git a/wagmi-project/packages/react/CHANGELOG.md b/wagmi-project/packages/react/CHANGELOG.md new file mode 100644 index 0000000000..7dfc14098a --- /dev/null +++ b/wagmi-project/packages/react/CHANGELOG.md @@ -0,0 +1,5037 @@ +# wagmi + +## 2.15.4 + +### Patch Changes + +- Updated dependencies [[`42b1fed58e9ac09da0f8ebf3e9271f98a707aaac`](https://github.com/wevm/wagmi/commit/42b1fed58e9ac09da0f8ebf3e9271f98a707aaac)]: + - @wagmi/connectors@5.8.3 + +## 2.15.3 + +### Patch Changes + +- Updated dependencies [[`29297a48af72b537173d948ccd2fe37d39914c66`](https://github.com/wevm/wagmi/commit/29297a48af72b537173d948ccd2fe37d39914c66), [`07370106d5fb6b8fe300992d93abf25b3d0eaf57`](https://github.com/wevm/wagmi/commit/07370106d5fb6b8fe300992d93abf25b3d0eaf57)]: + - @wagmi/core@2.17.2 + - @wagmi/connectors@5.8.2 + +## 2.15.2 + +### Patch Changes + +- [#4649](https://github.com/wevm/wagmi/pull/4649) [`01f64e64fa4f85cdd30023903f972f4f9023681f`](https://github.com/wevm/wagmi/commit/01f64e64fa4f85cdd30023903f972f4f9023681f) Thanks [@jxom](https://github.com/jxom)! - Added `chainId` parameter to `getCapabilities`/`useCapabilities`. + +- Updated dependencies [[`01f64e64fa4f85cdd30023903f972f4f9023681f`](https://github.com/wevm/wagmi/commit/01f64e64fa4f85cdd30023903f972f4f9023681f)]: + - @wagmi/core@2.17.1 + - @wagmi/connectors@5.8.1 + +## 2.15.1 + +### Patch Changes + +- Updated dependencies [[`cc5517ff6880bb630f1b201930acc20dd1a0b451`](https://github.com/wevm/wagmi/commit/cc5517ff6880bb630f1b201930acc20dd1a0b451)]: + - @wagmi/connectors@5.8.0 + +## 2.15.0 + +### Minor Changes + +- [#4638](https://github.com/wevm/wagmi/pull/4638) [`799ee4d4b23c2ecd64e3f3668e67634e81939719`](https://github.com/wevm/wagmi/commit/799ee4d4b23c2ecd64e3f3668e67634e81939719) Thanks [@jxom](https://github.com/jxom)! - Stabilized EIP-5792 Actions & Hooks. + +### Patch Changes + +- Updated dependencies [[`88427b2bcd13ec375ef519e9ad1ccffef9f02a7b`](https://github.com/wevm/wagmi/commit/88427b2bcd13ec375ef519e9ad1ccffef9f02a7b), [`799ee4d4b23c2ecd64e3f3668e67634e81939719`](https://github.com/wevm/wagmi/commit/799ee4d4b23c2ecd64e3f3668e67634e81939719), [`3f8b2edc4f237cccff1009bcef03d51ca27a7324`](https://github.com/wevm/wagmi/commit/3f8b2edc4f237cccff1009bcef03d51ca27a7324)]: + - @wagmi/connectors@6.0.0 + - @wagmi/core@2.17.0 + +## 2.14.16 + +### Patch Changes + +- Updated dependencies [[`b59c024b23c69f5459b17390531207cfdf126ce4`](https://github.com/wevm/wagmi/commit/b59c024b23c69f5459b17390531207cfdf126ce4)]: + - @wagmi/connectors@5.7.12 + +## 2.14.15 + +### Patch Changes + +- [`a4bd0623eed28e3761a27295831a60ad835f0ee0`](https://github.com/wevm/wagmi/commit/a4bd0623eed28e3761a27295831a60ad835f0ee0) Thanks [@jxom](https://github.com/jxom)! - **Experimental (EIP-5792):** Updated `id` parameter to be optional on `useWaitForCallsStatus`. + +- Updated dependencies [[`a4bd0623eed28e3761a27295831a60ad835f0ee0`](https://github.com/wevm/wagmi/commit/a4bd0623eed28e3761a27295831a60ad835f0ee0)]: + - @wagmi/core@2.16.7 + - @wagmi/connectors@5.7.11 + +## 2.14.14 + +### Patch Changes + +- [#4586](https://github.com/wevm/wagmi/pull/4586) [`edf47477b2f6385a1c3ae01d36a8498c47f30a0b`](https://github.com/wevm/wagmi/commit/edf47477b2f6385a1c3ae01d36a8498c47f30a0b) Thanks [@jxom](https://github.com/jxom)! - **Experimental (EIP-5792):** Added `waitForCallsStatus` + `useWaitForCallsStatus`. + +- Updated dependencies [[`edf47477b2f6385a1c3ae01d36a8498c47f30a0b`](https://github.com/wevm/wagmi/commit/edf47477b2f6385a1c3ae01d36a8498c47f30a0b), [`e944812ebc234a72c1417b77cff341166f5e0fef`](https://github.com/wevm/wagmi/commit/e944812ebc234a72c1417b77cff341166f5e0fef)]: + - @wagmi/core@2.16.6 + - @wagmi/connectors@5.7.10 + +## 2.14.13 + +### Patch Changes + +- Updated dependencies [[`5b7101fddb61df56e34b2e02b46bc409e496eaf9`](https://github.com/wevm/wagmi/commit/5b7101fddb61df56e34b2e02b46bc409e496eaf9)]: + - @wagmi/connectors@5.7.9 + +## 2.14.12 + +### Patch Changes + +- [`d0c9a86921a4e939373cc6e763284e53f2a2e93c`](https://github.com/wevm/wagmi/commit/d0c9a86921a4e939373cc6e763284e53f2a2e93c) Thanks [@jxom](https://github.com/jxom)! - **Experimental (ERC-5792)**: Added support for `account: null` in `sendCalls` to cater for sending calls without a connected account (account will be filled by the wallet). + +- Updated dependencies [[`d0c9a86921a4e939373cc6e763284e53f2a2e93c`](https://github.com/wevm/wagmi/commit/d0c9a86921a4e939373cc6e763284e53f2a2e93c)]: + - @wagmi/core@2.16.5 + - @wagmi/connectors@5.7.8 + +## 2.14.11 + +### Patch Changes + +- [`507f864d91238bfd423d0e36d3619eb9f6e52eec`](https://github.com/wevm/wagmi/commit/507f864d91238bfd423d0e36d3619eb9f6e52eec) Thanks [@jxom](https://github.com/jxom)! - Updated `@coinbase/wallet-sdk`. + +- Updated dependencies [[`507f864d91238bfd423d0e36d3619eb9f6e52eec`](https://github.com/wevm/wagmi/commit/507f864d91238bfd423d0e36d3619eb9f6e52eec)]: + - @wagmi/connectors@5.7.7 + - @wagmi/core@2.16.4 + +## 2.14.10 + +### Patch Changes + +- Updated dependencies [[`639952c97f0fe3927106f42d3c9f7f366cdf7f7a`](https://github.com/wevm/wagmi/commit/639952c97f0fe3927106f42d3c9f7f366cdf7f7a), [`5aa2c095f7bfb6dfcf91c6945c3e1f9c9dd05766`](https://github.com/wevm/wagmi/commit/5aa2c095f7bfb6dfcf91c6945c3e1f9c9dd05766)]: + - @wagmi/connectors@5.7.6 + +## 2.14.9 + +### Patch Changes + +- Updated dependencies [[`a257e8d4f97431a4af872cda1817b4ae17c7bbed`](https://github.com/wevm/wagmi/commit/a257e8d4f97431a4af872cda1817b4ae17c7bbed)]: + - @wagmi/connectors@5.7.5 + +## 2.14.8 + +### Patch Changes + +- Updated dependencies [[`c8a257e0f6d2ece013b873895c35769a8a804fdc`](https://github.com/wevm/wagmi/commit/c8a257e0f6d2ece013b873895c35769a8a804fdc)]: + - @wagmi/connectors@5.7.4 + +## 2.14.7 + +### Patch Changes + +- [#4497](https://github.com/wevm/wagmi/pull/4497) [`00c144b21bac3f0797b683d8a4a81f7399c6e042`](https://github.com/wevm/wagmi/commit/00c144b21bac3f0797b683d8a4a81f7399c6e042) Thanks [@tmm](https://github.com/tmm)! - Bumped `use-sync-external-store` version for React 19. + +## 2.14.6 + +### Patch Changes + +- [#4480](https://github.com/wevm/wagmi/pull/4480) [`384a1d91597622eb59e1c05dc13ce25017c5b6d8`](https://github.com/wevm/wagmi/commit/384a1d91597622eb59e1c05dc13ce25017c5b6d8) Thanks [@RodeRickIsWatching](https://github.com/RodeRickIsWatching)! - Fixed invocation of default storage. + +- Updated dependencies [[`384a1d91597622eb59e1c05dc13ce25017c5b6d8`](https://github.com/wevm/wagmi/commit/384a1d91597622eb59e1c05dc13ce25017c5b6d8)]: + - @wagmi/core@2.16.3 + - @wagmi/connectors@5.7.3 + +## 2.14.5 + +### Patch Changes + +- [`012907032b532a438fce48f407470250cbc8f0c6`](https://github.com/wevm/wagmi/commit/012907032b532a438fce48f407470250cbc8f0c6) Thanks [@jxom](https://github.com/jxom)! - Fixed assignment in `getDefaultStorage`. + +- Updated dependencies [[`012907032b532a438fce48f407470250cbc8f0c6`](https://github.com/wevm/wagmi/commit/012907032b532a438fce48f407470250cbc8f0c6)]: + - @wagmi/core@2.16.2 + - @wagmi/connectors@5.7.2 + +## 2.14.4 + +### Patch Changes + +- Updated dependencies [[`9c8c35a3b829f2c58edcd3a29e2dcd99974d7470`](https://github.com/wevm/wagmi/commit/9c8c35a3b829f2c58edcd3a29e2dcd99974d7470), [`3892ebd21c06beef4b28ece4e70d2a38807bce6f`](https://github.com/wevm/wagmi/commit/3892ebd21c06beef4b28ece4e70d2a38807bce6f)]: + - @wagmi/connectors@5.7.1 + - @wagmi/core@2.16.1 + +## 2.14.3 + +### Patch Changes + +- Updated dependencies [[`e3f63a02c1f7d80481804584f262bc98dab0400d`](https://github.com/wevm/wagmi/commit/e3f63a02c1f7d80481804584f262bc98dab0400d)]: + - @wagmi/connectors@5.7.0 + +## 2.14.2 + +### Patch Changes + +- Updated dependencies [[`adf2253b10c6d4fc583e4bc9f01a8ef5ca267c85`](https://github.com/wevm/wagmi/commit/adf2253b10c6d4fc583e4bc9f01a8ef5ca267c85)]: + - @wagmi/connectors@5.6.2 + +## 2.14.1 + +### Patch Changes + +- Updated dependencies [[`987404f590c1d29ebb3cb68928f5e54aa032793d`](https://github.com/wevm/wagmi/commit/987404f590c1d29ebb3cb68928f5e54aa032793d)]: + - @wagmi/connectors@5.6.1 + +## 2.14.0 + +### Minor Changes + +- [#4453](https://github.com/wevm/wagmi/pull/4453) [`070e48480194c8d7f45bda1d7dd1346e6f5d7227`](https://github.com/wevm/wagmi/commit/070e48480194c8d7f45bda1d7dd1346e6f5d7227) Thanks [@tmm](https://github.com/tmm)! - Added support to `useConnect` for custom `connector.connect` parameters. + +### Patch Changes + +- Updated dependencies [[`afea6b67822a7a2b96901ec851441d27ee0f7a52`](https://github.com/wevm/wagmi/commit/afea6b67822a7a2b96901ec851441d27ee0f7a52), [`070e48480194c8d7f45bda1d7dd1346e6f5d7227`](https://github.com/wevm/wagmi/commit/070e48480194c8d7f45bda1d7dd1346e6f5d7227), [`8b0726c1106fce88b782e676498eabf0718b2619`](https://github.com/wevm/wagmi/commit/8b0726c1106fce88b782e676498eabf0718b2619)]: + - @wagmi/connectors@5.6.0 + - @wagmi/core@2.16.0 + +## 2.13.5 + +### Patch Changes + +- [#4447](https://github.com/wevm/wagmi/pull/4447) [`244f7777d9d227b3134d4cb9b9dda64f50cbddd3`](https://github.com/wevm/wagmi/commit/244f7777d9d227b3134d4cb9b9dda64f50cbddd3) Thanks [@Aerilym](https://github.com/Aerilym)! - Fixed config parameter passing in useSimulateContract and useEstimateGas + +## 2.13.4 + +### Patch Changes + +- [`2f79a3da4872d6158569017b1927a07a1ff5e7ba`](https://github.com/wevm/wagmi/commit/2f79a3da4872d6158569017b1927a07a1ff5e7ba) Thanks [@tmm](https://github.com/tmm)! - Exported `injected` and `mock`. + +## 2.13.3 + +### Patch Changes + +- [#4433](https://github.com/wevm/wagmi/pull/4433) [`06e186cd679b27fe195309110e766fcf46d4efbc`](https://github.com/wevm/wagmi/commit/06e186cd679b27fe195309110e766fcf46d4efbc) Thanks [@Aerilym](https://github.com/Aerilym)! - Bumped Metamask SDK version to `0.31.1`. + +- Updated dependencies [[`06e186cd679b27fe195309110e766fcf46d4efbc`](https://github.com/wevm/wagmi/commit/06e186cd679b27fe195309110e766fcf46d4efbc)]: + - @wagmi/connectors@5.5.3 + - @wagmi/core@2.15.2 + +## 2.13.2 + +### Patch Changes + +- Updated dependencies [[`e563ef69130a511fd6f3f72ed4cd4fbe1390541f`](https://github.com/wevm/wagmi/commit/e563ef69130a511fd6f3f72ed4cd4fbe1390541f)]: + - @wagmi/connectors@5.5.2 + +## 2.13.1 + +### Patch Changes + +- [`b8bbb409f4934538e3dd6cac5aaf7346292d0693`](https://github.com/wevm/wagmi/commit/b8bbb409f4934538e3dd6cac5aaf7346292d0693) Thanks [@jxom](https://github.com/jxom)! - Fixed issue where `null` gas would accidentally pass through. + +- Updated dependencies [[`b8bbb409f4934538e3dd6cac5aaf7346292d0693`](https://github.com/wevm/wagmi/commit/b8bbb409f4934538e3dd6cac5aaf7346292d0693)]: + - @wagmi/core@2.15.1 + - @wagmi/connectors@5.5.1 + +## 2.13.0 + +### Minor Changes + +- [#4417](https://github.com/wevm/wagmi/pull/4417) [`42e65ea4fea99c639817088bba915e0933d17141`](https://github.com/wevm/wagmi/commit/42e65ea4fea99c639817088bba915e0933d17141) Thanks [@jxom](https://github.com/jxom)! - Removed simulation in `writeContract` & `sendTransaction`. + +### Patch Changes + +- Updated dependencies [[`42e65ea4fea99c639817088bba915e0933d17141`](https://github.com/wevm/wagmi/commit/42e65ea4fea99c639817088bba915e0933d17141)]: + - @wagmi/connectors@6.0.0 + - @wagmi/core@2.15.0 + +## 2.12.33 + +### Patch Changes + +- Updated dependencies [[`7ca62b44cd997d48f92c2b81343726a5908aa00b`](https://github.com/wevm/wagmi/commit/7ca62b44cd997d48f92c2b81343726a5908aa00b)]: + - @wagmi/connectors@5.4.0 + +## 2.12.32 + +### Patch Changes + +- Updated dependencies [[`a13aa8d7c38eb3cc8171a02d6302e6d12cf6bcb3`](https://github.com/wevm/wagmi/commit/a13aa8d7c38eb3cc8171a02d6302e6d12cf6bcb3), [`a13aa8d7c38eb3cc8171a02d6302e6d12cf6bcb3`](https://github.com/wevm/wagmi/commit/a13aa8d7c38eb3cc8171a02d6302e6d12cf6bcb3)]: + - @wagmi/core@2.14.6 + - @wagmi/connectors@5.3.10 + +## 2.12.31 + +### Patch Changes + +- Updated dependencies [[`b12a04eeec985c48d2feac94b011d41fb29ca23e`](https://github.com/wevm/wagmi/commit/b12a04eeec985c48d2feac94b011d41fb29ca23e)]: + - @wagmi/connectors@5.3.9 + +## 2.12.30 + +### Patch Changes + +- Updated dependencies [[`6b9bbacdc7bffd44fc2165362a5e65fd434e7646`](https://github.com/wevm/wagmi/commit/6b9bbacdc7bffd44fc2165362a5e65fd434e7646), [`dac62dc99a0679fa632a0fae49873d6053d06b35`](https://github.com/wevm/wagmi/commit/dac62dc99a0679fa632a0fae49873d6053d06b35)]: + - @wagmi/core@2.14.5 + - @wagmi/connectors@5.3.8 + +## 2.12.29 + +### Patch Changes + +- Updated dependencies [[`e08681c81fbdf475213e2d0f4c5517d0abf4e743`](https://github.com/wevm/wagmi/commit/e08681c81fbdf475213e2d0f4c5517d0abf4e743)]: + - @wagmi/core@2.14.4 + - @wagmi/connectors@5.3.7 + +## 2.12.28 + +### Patch Changes + +- Updated dependencies [[`7558ff3133c11bc4c49473d08ee9a47eaa12df5b`](https://github.com/wevm/wagmi/commit/7558ff3133c11bc4c49473d08ee9a47eaa12df5b)]: + - @wagmi/connectors@5.3.6 + +## 2.12.27 + +### Patch Changes + +- Updated dependencies [[`cb7dd2ebb871d0be8f1a11a8cd8ce592cd74b7c7`](https://github.com/wevm/wagmi/commit/cb7dd2ebb871d0be8f1a11a8cd8ce592cd74b7c7), [`7fe78f2d09778fc01fd0cffe85ba198e64999275`](https://github.com/wevm/wagmi/commit/7fe78f2d09778fc01fd0cffe85ba198e64999275)]: + - @wagmi/core@2.14.3 + - @wagmi/connectors@5.3.5 + +## 2.12.26 + +### Patch Changes + +- Updated dependencies [[`b6861a4c378dab78d8751ae0ac2aa425f3c24b8f`](https://github.com/wevm/wagmi/commit/b6861a4c378dab78d8751ae0ac2aa425f3c24b8f), [`d0d0963bb5904a15cf0355862d62dd141ce0c31c`](https://github.com/wevm/wagmi/commit/d0d0963bb5904a15cf0355862d62dd141ce0c31c), [`ecac0ba36243d94c9199d0bd21937104c835d9a0`](https://github.com/wevm/wagmi/commit/ecac0ba36243d94c9199d0bd21937104c835d9a0)]: + - @wagmi/connectors@5.3.4 + - @wagmi/core@2.14.2 + +## 2.12.25 + +### Patch Changes + +- Updated dependencies [[`83c6d16b7d6dddfa6bda036e04f00ec313c6248c`](https://github.com/wevm/wagmi/commit/83c6d16b7d6dddfa6bda036e04f00ec313c6248c)]: + - @wagmi/connectors@5.3.3 + +## 2.12.24 + +### Patch Changes + +- [`a4c5389c1a299bd7acf9df4a0d607e2ced709280`](https://github.com/wevm/wagmi/commit/a4c5389c1a299bd7acf9df4a0d607e2ced709280) Thanks [@jxom](https://github.com/jxom)! - Exported `Transport` type (for inference). + +## 2.12.23 + +### Patch Changes + +- Updated dependencies [[`8970cc51398e1ac713435533096215c6d31ffdf9`](https://github.com/wevm/wagmi/commit/8970cc51398e1ac713435533096215c6d31ffdf9)]: + - @wagmi/connectors@5.3.2 + +## 2.12.22 + +### Patch Changes + +- Updated dependencies [[`052e72e1f8c1c14fcbdce04a9f8fa7ec28d83702`](https://github.com/wevm/wagmi/commit/052e72e1f8c1c14fcbdce04a9f8fa7ec28d83702), [`b250fc21ee577b2a75c5a34ff684f62fb4ad771a`](https://github.com/wevm/wagmi/commit/b250fc21ee577b2a75c5a34ff684f62fb4ad771a)]: + - @wagmi/core@2.14.1 + - @wagmi/connectors@5.3.1 + +## 2.12.21 + +### Patch Changes + +- Updated dependencies [[`f43e074f473820b208a6295d7c97f847332f1a1d`](https://github.com/wevm/wagmi/commit/f43e074f473820b208a6295d7c97f847332f1a1d)]: + - @wagmi/connectors@6.0.0 + - @wagmi/core@2.14.0 + +## 2.12.20 + +### Patch Changes + +- Updated dependencies [[`c05caabc20c3ced9682cfc7ba1f3f7dcfece0703`](https://github.com/wevm/wagmi/commit/c05caabc20c3ced9682cfc7ba1f3f7dcfece0703), [`5ae49af590ff168426c9c283d54c34ae5148fcd9`](https://github.com/wevm/wagmi/commit/5ae49af590ff168426c9c283d54c34ae5148fcd9), [`f3182b22e6e454d9bd74f1b940ef34431fd9555d`](https://github.com/wevm/wagmi/commit/f3182b22e6e454d9bd74f1b940ef34431fd9555d)]: + - @wagmi/core@2.13.9 + - @wagmi/connectors@5.2.2 + +## 2.12.19 + +### Patch Changes + +- Updated dependencies [[`91a40f2db08e3a91db421b8732a5511a1e6c88fd`](https://github.com/wevm/wagmi/commit/91a40f2db08e3a91db421b8732a5511a1e6c88fd)]: + - @wagmi/connectors@5.2.1 + +## 2.12.18 + +### Patch Changes + +- Updated dependencies [[`34a0c3b7eea778aee7c27f7ace5e4b2be4e8a0a4`](https://github.com/wevm/wagmi/commit/34a0c3b7eea778aee7c27f7ace5e4b2be4e8a0a4)]: + - @wagmi/connectors@5.2.0 + +## 2.12.17 + +### Patch Changes + +- Updated dependencies [[`3b2123664b7ac66848390739e855c3b9702ab60c`](https://github.com/wevm/wagmi/commit/3b2123664b7ac66848390739e855c3b9702ab60c)]: + - @wagmi/connectors@5.1.15 + +## 2.12.16 + +### Patch Changes + +- Updated dependencies [[`56f2482508f2ba71bd6b0295c70c6abca7101e57`](https://github.com/wevm/wagmi/commit/56f2482508f2ba71bd6b0295c70c6abca7101e57)]: + - @wagmi/connectors@5.1.14 + - @wagmi/core@2.13.8 + +## 2.12.15 + +### Patch Changes + +- [#4229](https://github.com/wevm/wagmi/pull/4229) [`c6b8efd26254c8e692b2b67286ed538fc183b992`](https://github.com/wevm/wagmi/commit/c6b8efd26254c8e692b2b67286ed538fc183b992) Thanks [@weilliao05621](https://github.com/weilliao05621)! - Stabilized `useAccount` return type object reference. + +## 2.12.14 + +### Patch Changes + +- Updated dependencies [[`be75c2d4ef636d7362420ab0a106bfdf63f5d1e6`](https://github.com/wevm/wagmi/commit/be75c2d4ef636d7362420ab0a106bfdf63f5d1e6)]: + - @wagmi/core@2.13.7 + - @wagmi/connectors@5.1.13 + +## 2.12.13 + +### Patch Changes + +- Updated dependencies [[`edcbf5d6fbe92f639bead800502edda9e0aa39f1`](https://github.com/wevm/wagmi/commit/edcbf5d6fbe92f639bead800502edda9e0aa39f1)]: + - @wagmi/core@2.13.6 + - @wagmi/connectors@5.1.12 + +## 2.12.12 + +### Patch Changes + +- Updated dependencies [[`82404c960e04c83e0bae6e1e12459ef9debf9554`](https://github.com/wevm/wagmi/commit/82404c960e04c83e0bae6e1e12459ef9debf9554), [`d07ad7f63a018256908a673d078aaf79e47ac703`](https://github.com/wevm/wagmi/commit/d07ad7f63a018256908a673d078aaf79e47ac703)]: + - @wagmi/connectors@5.1.11 + +## 2.12.11 + +### Patch Changes + +- [#4262](https://github.com/wevm/wagmi/pull/4262) [`8531f83db3a1fbb8202c3e426b7f85679f587a52`](https://github.com/wevm/wagmi/commit/8531f83db3a1fbb8202c3e426b7f85679f587a52) Thanks [@nezouse](https://github.com/nezouse)! - Added experimental actions entrypoint. + +## 2.12.10 + +### Patch Changes + +- [#4260](https://github.com/wevm/wagmi/pull/4260) [`969a208a110b760a13fd7263360320f52440a9b6`](https://github.com/wevm/wagmi/commit/969a208a110b760a13fd7263360320f52440a9b6) Thanks [@tmm](https://github.com/tmm)! - Fixed `useReadContract` deployless reads support. + +- [#4259](https://github.com/wevm/wagmi/pull/4259) [`f47ce8f6d263e49fdff90b8edb3190142d2657bb`](https://github.com/wevm/wagmi/commit/f47ce8f6d263e49fdff90b8edb3190142d2657bb) Thanks [@tmm](https://github.com/tmm)! - Disabled `useConnectorClient` and `useWalletClient` during reconnection if connector is not fully restored. + +- Updated dependencies [[`81de006e66121a18c61945c1f9b8426c83a5713c`](https://github.com/wevm/wagmi/commit/81de006e66121a18c61945c1f9b8426c83a5713c), [`f47ce8f6d263e49fdff90b8edb3190142d2657bb`](https://github.com/wevm/wagmi/commit/f47ce8f6d263e49fdff90b8edb3190142d2657bb)]: + - @wagmi/connectors@5.1.10 + - @wagmi/core@2.13.5 + +## 2.12.9 + +### Patch Changes + +- Updated dependencies [[`21bd0e473d374cbbd7a01bececa6022d529026ba`](https://github.com/wevm/wagmi/commit/21bd0e473d374cbbd7a01bececa6022d529026ba), [`5c89c6853e616437a3be2b019db895451fecfb3c`](https://github.com/wevm/wagmi/commit/5c89c6853e616437a3be2b019db895451fecfb3c)]: + - @wagmi/connectors@5.1.9 + +## 2.12.8 + +### Patch Changes + +- Updated dependencies [[`b580ad4edff1721e0b9d138cf5ae2ec74d2374c7`](https://github.com/wevm/wagmi/commit/b580ad4edff1721e0b9d138cf5ae2ec74d2374c7)]: + - @wagmi/connectors@5.1.8 + +## 2.12.7 + +### Patch Changes + +- Updated dependencies [[`91fd81a068789c5020e891f539bcad8f54a7a52f`](https://github.com/wevm/wagmi/commit/91fd81a068789c5020e891f539bcad8f54a7a52f)]: + - @wagmi/connectors@5.1.7 + +## 2.12.6 + +### Patch Changes + +- Updated dependencies [[`3168616298cbb6135d0ffda771cba4126e83eba8`](https://github.com/wevm/wagmi/commit/3168616298cbb6135d0ffda771cba4126e83eba8), [`d7608ef9a79459465dc8c06a2ab740465c881907`](https://github.com/wevm/wagmi/commit/d7608ef9a79459465dc8c06a2ab740465c881907)]: + - @wagmi/connectors@5.1.6 + +## 2.12.5 + +### Patch Changes + +- Updated dependencies [[`b4c8971788c70b09479946ecfa998cff2f1b3953`](https://github.com/wevm/wagmi/commit/b4c8971788c70b09479946ecfa998cff2f1b3953)]: + - @wagmi/core@2.13.4 + - @wagmi/connectors@5.1.5 + +## 2.12.4 + +### Patch Changes + +- Updated dependencies [[`871dbdbfe59ac8ad01d1ec6150ea7b091b7b7de4`](https://github.com/wevm/wagmi/commit/871dbdbfe59ac8ad01d1ec6150ea7b091b7b7de4)]: + - @wagmi/core@2.13.3 + - @wagmi/connectors@5.1.4 + +## 2.12.3 + +### Patch Changes + +- Updated dependencies [[`1b9b523fa9b9dfe839aecdf4b40caa9547d7e594`](https://github.com/wevm/wagmi/commit/1b9b523fa9b9dfe839aecdf4b40caa9547d7e594)]: + - @wagmi/core@2.13.2 + - @wagmi/connectors@5.1.3 + +## 2.12.2 + +### Patch Changes + +- Updated dependencies [[`abb490dac4f0f02f46cb0878e7ca9a0db6aada56`](https://github.com/wevm/wagmi/commit/abb490dac4f0f02f46cb0878e7ca9a0db6aada56), [`28e0e5c9a4f856583f9d36a807502bd51a0c6ec2`](https://github.com/wevm/wagmi/commit/28e0e5c9a4f856583f9d36a807502bd51a0c6ec2)]: + - @wagmi/connectors@5.1.2 + +## 2.12.1 + +### Patch Changes + +- Updated dependencies [[`07c1227f306d0efb9421d4bb77a774f92f5fcf45`](https://github.com/wevm/wagmi/commit/07c1227f306d0efb9421d4bb77a774f92f5fcf45)]: + - @wagmi/core@2.13.1 + - @wagmi/connectors@5.1.1 + +## 2.12.0 + +### Minor Changes + +- [#4162](https://github.com/wevm/wagmi/pull/4162) [`a73a7737b756886b388f120ae423e72cca53e8a0`](https://github.com/wevm/wagmi/commit/a73a7737b756886b388f120ae423e72cca53e8a0) Thanks [@jxom](https://github.com/jxom)! - Added functionality for consumer-defined RPC URLs (`config.transports`) to be propagated to the WalletConnect & MetaMask Connectors. + +### Patch Changes + +- Updated dependencies [[`a73a7737b756886b388f120ae423e72cca53e8a0`](https://github.com/wevm/wagmi/commit/a73a7737b756886b388f120ae423e72cca53e8a0)]: + - @wagmi/connectors@6.0.0 + - @wagmi/core@2.13.0 + +## 2.11.3 + +### Patch Changes + +- [#4124](https://github.com/wevm/wagmi/pull/4124) [`26616462db2e0140025f22c505c4541cfecb9308`](https://github.com/wevm/wagmi/commit/26616462db2e0140025f22c505c4541cfecb9308) Thanks [@t0rbik](https://github.com/t0rbik)! - Updated `useConnectorClient` to be enabled when status is `'reconnecting'` or `'connected'` (previously was also enabled when status was `'connecting'`). + +## 2.11.2 + +### Patch Changes + +- Updated dependencies [[`5bc8c8877810b2eec24a829df87dce40a51e6f20`](https://github.com/wevm/wagmi/commit/5bc8c8877810b2eec24a829df87dce40a51e6f20), [`8d81df5cc884d0a210dedd3c1ea0e2e9e52b83c5`](https://github.com/wevm/wagmi/commit/8d81df5cc884d0a210dedd3c1ea0e2e9e52b83c5)]: + - @wagmi/core@2.12.2 + - @wagmi/connectors@5.0.26 + +## 2.11.1 + +### Patch Changes + +- [#4146](https://github.com/wevm/wagmi/pull/4146) [`cc996e08e930c9e88cf753a1e874652059e81a3b`](https://github.com/wevm/wagmi/commit/cc996e08e930c9e88cf753a1e874652059e81a3b) Thanks [@jxom](https://github.com/jxom)! - Updated `@safe-global/safe-apps-sdk` + `@safe-global/safe-apps-provider` dependencies. + +- Updated dependencies [[`cc996e08e930c9e88cf753a1e874652059e81a3b`](https://github.com/wevm/wagmi/commit/cc996e08e930c9e88cf753a1e874652059e81a3b)]: + - @wagmi/connectors@5.0.25 + - @wagmi/core@2.12.1 + +## 2.11.0 + +### Minor Changes + +- [#4128](https://github.com/wevm/wagmi/pull/4128) [`5581a810ef70308e99c6f8b630cd4bca59f64afc`](https://github.com/wevm/wagmi/commit/5581a810ef70308e99c6f8b630cd4bca59f64afc) Thanks [@dalechyn](https://github.com/dalechyn)! - Added `useWatchAsset` hook. + +### Patch Changes + +- Updated dependencies [[`5581a810ef70308e99c6f8b630cd4bca59f64afc`](https://github.com/wevm/wagmi/commit/5581a810ef70308e99c6f8b630cd4bca59f64afc)]: + - @wagmi/core@2.12.0 + - @wagmi/connectors@6.0.0 + +## 2.10.11 + +### Patch Changes + +- [`d3814ab4b88f9f0e052b53bc3d458df87b43f01d`](https://github.com/wevm/wagmi/commit/d3814ab4b88f9f0e052b53bc3d458df87b43f01d) Thanks [@jxom](https://github.com/jxom)! - Updated `mipd` dependency. + +- Updated dependencies [[`b08013eaa9ce97c02f8a7128ea400e3da7ef74bb`](https://github.com/wevm/wagmi/commit/b08013eaa9ce97c02f8a7128ea400e3da7ef74bb), [`d3814ab4b88f9f0e052b53bc3d458df87b43f01d`](https://github.com/wevm/wagmi/commit/d3814ab4b88f9f0e052b53bc3d458df87b43f01d)]: + - @wagmi/core@2.11.8 + - @wagmi/connectors@5.0.23 + +## 2.10.10 + +### Patch Changes + +- Updated dependencies [[`0bb8b562ae04ecfeb2d6b2f1b980ebae31dc127e`](https://github.com/wevm/wagmi/commit/0bb8b562ae04ecfeb2d6b2f1b980ebae31dc127e)]: + - @wagmi/connectors@5.0.22 + - @wagmi/core@2.11.7 + +## 2.10.9 + +### Patch Changes + +- [#4060](https://github.com/wevm/wagmi/pull/4060) [`95965c1f19d480b97f2b297a077a9e607dee32ad`](https://github.com/wevm/wagmi/commit/95965c1f19d480b97f2b297a077a9e607dee32ad) Thanks [@dalechyn](https://github.com/dalechyn)! - Bumped Tanstack Query dependencies to fix typing issues between exported Wagmi query options and TanStack Query suspense query methods (due to [`direction` property in `QueryFunctionContext` being deprecated](https://github.com/TanStack/query/pull/7410)). + +- Updated dependencies [[`ff0760b5900114bcfdf420a9fba3cc278ac95afe`](https://github.com/wevm/wagmi/commit/ff0760b5900114bcfdf420a9fba3cc278ac95afe), [`95965c1f19d480b97f2b297a077a9e607dee32ad`](https://github.com/wevm/wagmi/commit/95965c1f19d480b97f2b297a077a9e607dee32ad)]: + - @wagmi/connectors@5.0.21 + - @wagmi/core@2.11.6 + +## 2.10.8 + +### Patch Changes + +- Updated dependencies [[`43fa971d34cac57fa5a2898ad4d839b95d7af37c`](https://github.com/wevm/wagmi/commit/43fa971d34cac57fa5a2898ad4d839b95d7af37c)]: + - @wagmi/connectors@5.0.20 + +## 2.10.7 + +### Patch Changes + +- Updated dependencies [[`b7ad208030d9f2e3f89912ff76b16cdbd848feda`](https://github.com/wevm/wagmi/commit/b7ad208030d9f2e3f89912ff76b16cdbd848feda)]: + - @wagmi/connectors@5.0.19 + +## 2.10.6 + +### Patch Changes + +- Updated dependencies [[`44d24620c9e3957f3245d14d6a042736371df70b`](https://github.com/wevm/wagmi/commit/44d24620c9e3957f3245d14d6a042736371df70b)]: + - @wagmi/connectors@5.0.18 + +## 2.10.5 + +### Patch Changes + +- Updated dependencies [[`04f2b846b113f3d300d82c9fa75212f1805817c5`](https://github.com/wevm/wagmi/commit/04f2b846b113f3d300d82c9fa75212f1805817c5)]: + - @wagmi/core@2.11.5 + - @wagmi/connectors@5.0.17 + +## 2.10.4 + +### Patch Changes + +- Updated dependencies [[`9e8345cd56186b997b5e56deaa2cfc69b30d15f6`](https://github.com/wevm/wagmi/commit/9e8345cd56186b997b5e56deaa2cfc69b30d15f6), [`02c38c28d1aa0ad7a61c33775de603ed974c5c1b`](https://github.com/wevm/wagmi/commit/02c38c28d1aa0ad7a61c33775de603ed974c5c1b)]: + - @wagmi/core@2.11.4 + - @wagmi/connectors@5.0.16 + +## 2.10.3 + +### Patch Changes + +- Updated dependencies [[`8974e6269bb5d7bfaa90db0246bc7d13e8bff798`](https://github.com/wevm/wagmi/commit/8974e6269bb5d7bfaa90db0246bc7d13e8bff798)]: + - @wagmi/core@2.11.3 + - @wagmi/connectors@5.0.15 + +## 2.10.2 + +### Patch Changes + +- Updated dependencies [[`b4d9ef79deb554ee20fed6666a474be5e7cdd522`](https://github.com/wevm/wagmi/commit/b4d9ef79deb554ee20fed6666a474be5e7cdd522)]: + - @wagmi/core@2.11.2 + - @wagmi/connectors@5.0.14 + +## 2.10.1 + +### Patch Changes + +- Updated dependencies [[`9c862d8d63e3d692a22cef2a90782b74a9103f17`](https://github.com/wevm/wagmi/commit/9c862d8d63e3d692a22cef2a90782b74a9103f17)]: + - @wagmi/connectors@5.0.13 + - @wagmi/core@2.11.1 + +## 2.10.0 + +### Minor Changes + +- [#3816](https://github.com/wevm/wagmi/pull/3816) [`06bb598a7f04c7b167f5b7ff6d46bd15886a6a14`](https://github.com/wevm/wagmi/commit/06bb598a7f04c7b167f5b7ff6d46bd15886a6a14) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Added `useDeployContract` hook. + +### Patch Changes + +- Updated dependencies [[`06bb598a7f04c7b167f5b7ff6d46bd15886a6a14`](https://github.com/wevm/wagmi/commit/06bb598a7f04c7b167f5b7ff6d46bd15886a6a14), [`24a45b269bd0214a29d6f82a84ac66ef8c3f3822`](https://github.com/wevm/wagmi/commit/24a45b269bd0214a29d6f82a84ac66ef8c3f3822)]: + - @wagmi/core@2.11.0 + - @wagmi/connectors@6.0.0 + +## 2.9.12 + +### Patch Changes + +- Updated dependencies [[`f2a7cefab96691ebed8b8e45ffde071c47b58dbe`](https://github.com/wevm/wagmi/commit/f2a7cefab96691ebed8b8e45ffde071c47b58dbe), [`f0ea0b2a7fe193dadfeb49a4c8031ee451c638b5`](https://github.com/wevm/wagmi/commit/f0ea0b2a7fe193dadfeb49a4c8031ee451c638b5), [`e3b124ce414b8fd1b2214e2c5a28dc72158a13d1`](https://github.com/wevm/wagmi/commit/e3b124ce414b8fd1b2214e2c5a28dc72158a13d1)]: + - @wagmi/core@2.10.6 + - @wagmi/connectors@5.0.11 + +## 2.9.11 + +### Patch Changes + +- Updated dependencies [[`560952acd4bfe33db6c7c07b35c613cef278677c`](https://github.com/wevm/wagmi/commit/560952acd4bfe33db6c7c07b35c613cef278677c)]: + - @wagmi/connectors@5.0.10 + +## 2.9.10 + +### Patch Changes + +- Updated dependencies [[`32cdd7b7dc5aff916c040628519562c3a99d418d`](https://github.com/wevm/wagmi/commit/32cdd7b7dc5aff916c040628519562c3a99d418d)]: + - @wagmi/connectors@5.0.9 + +## 2.9.9 + +### Patch Changes + +- Updated dependencies [[`c1952d1ff7f0a491dc88595a49159451b07b5621`](https://github.com/wevm/wagmi/commit/c1952d1ff7f0a491dc88595a49159451b07b5621)]: + - @wagmi/connectors@5.0.8 + +## 2.9.8 + +### Patch Changes + +- Updated dependencies [[`030c7c2cb380dfd67a2182f62e2aa7a6e1601898`](https://github.com/wevm/wagmi/commit/030c7c2cb380dfd67a2182f62e2aa7a6e1601898)]: + - @wagmi/core@2.10.5 + - @wagmi/connectors@5.0.7 + +## 2.9.7 + +### Patch Changes + +- Updated dependencies [[`51fde8a0433b4fff357c1a8d7e08b41b4c86c968`](https://github.com/wevm/wagmi/commit/51fde8a0433b4fff357c1a8d7e08b41b4c86c968)]: + - @wagmi/core@2.10.4 + - @wagmi/connectors@5.0.6 + +## 2.9.6 + +### Patch Changes + +- Updated dependencies [[`70dd28669dd8d2ce08217cd02e29a8fbba7a08d4`](https://github.com/wevm/wagmi/commit/70dd28669dd8d2ce08217cd02e29a8fbba7a08d4)]: + - @wagmi/connectors@5.0.5 + +## 2.9.5 + +### Patch Changes + +- Updated dependencies [[`be9e1b8a9818b92eb0654a20d9471e9e39329e7e`](https://github.com/wevm/wagmi/commit/be9e1b8a9818b92eb0654a20d9471e9e39329e7e)]: + - @wagmi/connectors@5.0.4 + +## 2.9.4 + +### Patch Changes + +- Updated dependencies [[`2804a8a583b1874271154898b4bae38756ef581c`](https://github.com/wevm/wagmi/commit/2804a8a583b1874271154898b4bae38756ef581c), [`2804a8a583b1874271154898b4bae38756ef581c`](https://github.com/wevm/wagmi/commit/2804a8a583b1874271154898b4bae38756ef581c)]: + - @wagmi/connectors@5.0.3 + - @wagmi/core@2.10.3 + +## 2.9.3 + +### Patch Changes + +- [`ec2f63f106fd468f28b43d3b88ab3e89aaf5e81a`](https://github.com/wevm/wagmi/commit/ec2f63f106fd468f28b43d3b88ab3e89aaf5e81a) Thanks [@tmm](https://github.com/tmm)! - Fixed `useSwitchChain` `chains` typing. + +## 2.9.2 + +### Patch Changes + +- [#3940](https://github.com/wevm/wagmi/pull/3940) [`a5071f581dfdfb961718873643a2fc629101c72a`](https://github.com/wevm/wagmi/commit/a5071f581dfdfb961718873643a2fc629101c72a) Thanks [@jxom](https://github.com/jxom)! - Fixed usage of `metaMask` connector in Vite environments. + +- Updated dependencies [[`a5071f581dfdfb961718873643a2fc629101c72a`](https://github.com/wevm/wagmi/commit/a5071f581dfdfb961718873643a2fc629101c72a)]: + - @wagmi/connectors@5.0.2 + - @wagmi/core@2.10.2 + +## 2.9.1 + +### Patch Changes + +- Bumped versions. + +- Updated dependencies []: + - @wagmi/connectors@5.0.1 + - @wagmi/core@2.10.1 + +## 2.9.0 + +### Minor Changes + +- [#3928](https://github.com/wevm/wagmi/pull/3928) [`3117e71825f9c58a0d718f3d1686f1a191fa9cb1`](https://github.com/wevm/wagmi/commit/3117e71825f9c58a0d718f3d1686f1a191fa9cb1) Thanks [@tmm](https://github.com/tmm)! - Updated the default Coinbase SDK in `coinbaseWallet` Connector to v4.x. + +### Patch Changes + +- Updated dependencies [[`3117e71825f9c58a0d718f3d1686f1a191fa9cb1`](https://github.com/wevm/wagmi/commit/3117e71825f9c58a0d718f3d1686f1a191fa9cb1), [`3117e71825f9c58a0d718f3d1686f1a191fa9cb1`](https://github.com/wevm/wagmi/commit/3117e71825f9c58a0d718f3d1686f1a191fa9cb1)]: + - @wagmi/connectors@5.0.0 + - @wagmi/core@2.10.0 + +## 2.8.8 + +### Patch Changes + +- [#3906](https://github.com/wevm/wagmi/pull/3906) [`32fcb4a31dde6b0206961d8ffe9c651f8a459c67`](https://github.com/wevm/wagmi/commit/32fcb4a31dde6b0206961d8ffe9c651f8a459c67) Thanks [@tmm](https://github.com/tmm)! - Added support for Vue. + +- Updated dependencies [[`32fcb4a31dde6b0206961d8ffe9c651f8a459c67`](https://github.com/wevm/wagmi/commit/32fcb4a31dde6b0206961d8ffe9c651f8a459c67)]: + - @wagmi/connectors@4.3.10 + - @wagmi/core@2.9.8 + +## 2.8.7 + +### Patch Changes + +- [#3924](https://github.com/wevm/wagmi/pull/3924) [`1f58734f88458e0f6adb05c99f0c90f36ab286b8`](https://github.com/wevm/wagmi/commit/1f58734f88458e0f6adb05c99f0c90f36ab286b8) Thanks [@jxom](https://github.com/jxom)! - Refactored `isChainsStale` logic in `walletConnect` connector. + +- Updated dependencies [[`1f58734f88458e0f6adb05c99f0c90f36ab286b8`](https://github.com/wevm/wagmi/commit/1f58734f88458e0f6adb05c99f0c90f36ab286b8)]: + - @wagmi/connectors@4.3.9 + - @wagmi/core@2.9.7 + +## 2.8.6 + +### Patch Changes + +- [#3917](https://github.com/wevm/wagmi/pull/3917) [`05948fdad5bb4a56b08916d45b3dec2cb1e5f55b`](https://github.com/wevm/wagmi/commit/05948fdad5bb4a56b08916d45b3dec2cb1e5f55b) Thanks [@jxom](https://github.com/jxom)! - Updated `@metamask/sdk`. + +- Updated dependencies [[`05948fdad5bb4a56b08916d45b3dec2cb1e5f55b`](https://github.com/wevm/wagmi/commit/05948fdad5bb4a56b08916d45b3dec2cb1e5f55b)]: + - @wagmi/connectors@4.3.8 + - @wagmi/core@2.9.6 + +## 2.8.5 + +### Patch Changes + +- [`4fecbbb66d0aacd03b8c62a6455d11a33cde8f85`](https://github.com/wevm/wagmi/commit/4fecbbb66d0aacd03b8c62a6455d11a33cde8f85) Thanks [@jxom](https://github.com/jxom)! - Fixed address comparison in `getConnectorClient`. + +- Updated dependencies [[`4fecbbb66d0aacd03b8c62a6455d11a33cde8f85`](https://github.com/wevm/wagmi/commit/4fecbbb66d0aacd03b8c62a6455d11a33cde8f85)]: + - @wagmi/core@2.9.5 + - @wagmi/connectors@4.3.7 + +## 2.8.4 + +### Patch Changes + +- Updated dependencies [[`e6139a97c4b8804d734b1547b5e3921ce01fbe24`](https://github.com/wevm/wagmi/commit/e6139a97c4b8804d734b1547b5e3921ce01fbe24)]: + - @wagmi/core@2.9.4 + - @wagmi/connectors@4.3.6 + +## 2.8.3 + +### Patch Changes + +- [#3904](https://github.com/wevm/wagmi/pull/3904) [`addca28ebc20f1a4367c35fe9ef786decff9c87e`](https://github.com/wevm/wagmi/commit/addca28ebc20f1a4367c35fe9ef786decff9c87e) Thanks [@jxom](https://github.com/jxom)! - Updated `@walletconnect/ethereum-provider`. + +- Updated dependencies [[`addca28ebc20f1a4367c35fe9ef786decff9c87e`](https://github.com/wevm/wagmi/commit/addca28ebc20f1a4367c35fe9ef786decff9c87e)]: + - @wagmi/connectors@4.3.5 + - @wagmi/core@2.9.3 + +## 2.8.2 + +### Patch Changes + +- [#3902](https://github.com/wevm/wagmi/pull/3902) [`204b7b624612405500ec098fb9e35facd3f74ca4`](https://github.com/wevm/wagmi/commit/204b7b624612405500ec098fb9e35facd3f74ca4) Thanks [@jxom](https://github.com/jxom)! - Made third-party SDK imports type-only. + +- Updated dependencies [[`204b7b624612405500ec098fb9e35facd3f74ca4`](https://github.com/wevm/wagmi/commit/204b7b624612405500ec098fb9e35facd3f74ca4)]: + - @wagmi/connectors@4.3.4 + - @wagmi/core@2.9.2 + +## 2.8.1 + +### Patch Changes + +- [`cda6a5d5`](https://github.com/wevm/wagmi/commit/cda6a5d56328330fbde050b4ef40b01c58d2519a) Thanks [@jxom](https://github.com/jxom)! - Updated packages. + +- Updated dependencies [[`cda6a5d5`](https://github.com/wevm/wagmi/commit/cda6a5d56328330fbde050b4ef40b01c58d2519a)]: + - @wagmi/core@2.9.1 + - @wagmi/connectors@4.3.3 + +## 2.8.0 + +### Minor Changes + +- [#3878](https://github.com/wevm/wagmi/pull/3878) [`017828fc`](https://github.com/wevm/wagmi/commit/017828fc027c7a84b54ea9d627e9389f4d60d6c2) Thanks [@jxom](https://github.com/jxom)! - Added experimental EIP-5792 Actions & Hooks. + +### Patch Changes + +- Updated dependencies [[`017828fc`](https://github.com/wevm/wagmi/commit/017828fc027c7a84b54ea9d627e9389f4d60d6c2)]: + - @wagmi/core@2.9.0 + - @wagmi/connectors@4.3.2 + +## 2.7.1 + +### Patch Changes + +- [#3869](https://github.com/wevm/wagmi/pull/3869) [`d4a78eb0`](https://github.com/wevm/wagmi/commit/d4a78eb07119d2e5617e52481ac7d6c6d1583ddc) Thanks [@jxom](https://github.com/jxom)! - Fixed issue where `prepareTransactionRequest` would internally call unsupported wallet RPC methods. + +- Updated dependencies [[`d4a78eb0`](https://github.com/wevm/wagmi/commit/d4a78eb07119d2e5617e52481ac7d6c6d1583ddc)]: + - @wagmi/core@2.8.1 + - @wagmi/connectors@4.3.1 + +## 2.7.0 + +### Minor Changes + +- [#3868](https://github.com/wevm/wagmi/pull/3868) [`c2af20b8`](https://github.com/wevm/wagmi/commit/c2af20b88cf16970d087faaec10b463357a5836e) Thanks [@jxom](https://github.com/jxom)! - Added `supportsSimulation` property to connectors that indicates if the connector's wallet supports contract simulation. + +### Patch Changes + +- [#3858](https://github.com/wevm/wagmi/pull/3858) [`0d141f17`](https://github.com/wevm/wagmi/commit/0d141f171d6ec44bcbfc9c876565b5e2fb8af6de) Thanks [@yulafezmesi](https://github.com/yulafezmesi)! - Fixed accessing reverted reason property inside `waitForTransactionReceipt`. + +- Updated dependencies [[`0d141f17`](https://github.com/wevm/wagmi/commit/0d141f171d6ec44bcbfc9c876565b5e2fb8af6de), [`c2af20b8`](https://github.com/wevm/wagmi/commit/c2af20b88cf16970d087faaec10b463357a5836e)]: + - @wagmi/core@2.8.0 + - @wagmi/connectors@5.0.0 + +## 2.6.0 + +### Minor Changes + +- [#3857](https://github.com/wevm/wagmi/pull/3857) [`d4274c03`](https://github.com/wevm/wagmi/commit/d4274c03a6af5f2d26d31432016ebc14950a330e) Thanks [@tmm](https://github.com/tmm)! - Added `addEthereumChainParameter` to `switchChain`-related methods. + +### Patch Changes + +- Updated dependencies [[`d4274c03`](https://github.com/wevm/wagmi/commit/d4274c03a6af5f2d26d31432016ebc14950a330e), [`4781a405`](https://github.com/wevm/wagmi/commit/4781a4056d4ffc2c74f96a75429e9b2cd2417ad8), [`400c960b`](https://github.com/wevm/wagmi/commit/400c960b30d701c134850c695ae903a382c29b5b)]: + - @wagmi/connectors@5.0.0 + - @wagmi/core@2.7.0 + +## 2.5.22 + +### Patch Changes + +- [`e3c832a1`](https://github.com/wevm/wagmi/commit/e3c832a12c301f9b0ee129d877b3101d220ba8b2) Thanks [@jxom](https://github.com/jxom)! - Fixed undefined `navigator` issue in MetaMask connector. + +- Updated dependencies [[`e3c832a1`](https://github.com/wevm/wagmi/commit/e3c832a12c301f9b0ee129d877b3101d220ba8b2)]: + - @wagmi/connectors@4.1.28 + - @wagmi/core@2.6.19 + +## 2.5.21 + +### Patch Changes + +- [#3848](https://github.com/wevm/wagmi/pull/3848) [`dd40a41c`](https://github.com/wevm/wagmi/commit/dd40a41c526ab60a288aff2250ed8dba92a27b16) Thanks [@jxom](https://github.com/jxom)! - Updated MetaMask SDK. + +- Updated dependencies [[`dd40a41c`](https://github.com/wevm/wagmi/commit/dd40a41c526ab60a288aff2250ed8dba92a27b16)]: + - @wagmi/connectors@4.1.27 + - @wagmi/core@2.6.18 + +## 2.5.20 + +### Patch Changes + +- [#3822](https://github.com/wevm/wagmi/pull/3822) [`a97bfbae`](https://github.com/wevm/wagmi/commit/a97bfbaeb615cfef04665e5e7348d85d17f960f0) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where Wagmi would not correctly rehydrate the active chain when a persisted store was being used. + +- Updated dependencies [[`a97bfbae`](https://github.com/wevm/wagmi/commit/a97bfbaeb615cfef04665e5e7348d85d17f960f0)]: + - @wagmi/core@2.6.17 + - @wagmi/connectors@4.1.26 + +## 2.5.19 + +### Patch Changes + +- [#3793](https://github.com/wevm/wagmi/pull/3793) [`f85b83ae`](https://github.com/wevm/wagmi/commit/f85b83ae95dd0bb73ffbdb49afa174e7c68298e1) Thanks [@tmm](https://github.com/tmm)! - Wired up `config` inside hooks so you can pass it explicitly and not use the `WagmiProvider`. + +- Updated dependencies [[`42ad380d`](https://github.com/wevm/wagmi/commit/42ad380d9a5d8bc0f61d73612142dea9d098de5e)]: + - @wagmi/connectors@4.1.25 + - @wagmi/core@2.6.16 + +## 2.5.18 + +### Patch Changes + +- Updated dependencies [[`b907d5ac`](https://github.com/wevm/wagmi/commit/b907d5ac3a746bcbccc06d1fe78c5bd8f9a7d685)]: + - @wagmi/core@2.6.15 + - @wagmi/connectors@4.1.24 + +## 2.5.17 + +### Patch Changes + +- [#3779](https://github.com/wevm/wagmi/pull/3779) [`3da20bb8`](https://github.com/wevm/wagmi/commit/3da20bb80e7c3efeef8227ced66ad615370fc242) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where `eth_requestAccounts` would be called upon reconnect instead of `eth_accounts`. + +- [`a3d1858f`](https://github.com/wevm/wagmi/commit/a3d1858fce448d2b70e36ee692ef1589b74e9d3f) Thanks [@jxom](https://github.com/jxom)! - Fixed hydration conditional in `createConfig`. + +- Updated dependencies [[`b3b54ef1`](https://github.com/wevm/wagmi/commit/b3b54ef179c5fa0d1694d38d4b808549a0550409), [`3da20bb8`](https://github.com/wevm/wagmi/commit/3da20bb80e7c3efeef8227ced66ad615370fc242), [`a3d1858f`](https://github.com/wevm/wagmi/commit/a3d1858fce448d2b70e36ee692ef1589b74e9d3f)]: + - @wagmi/core@2.6.14 + - @wagmi/connectors@4.1.23 + +## 2.5.16 + +### Patch Changes + +- [`b80236dc`](https://github.com/wevm/wagmi/commit/b80236dc623095fe8f1e1d10957d7776fb6ab48b) Thanks [@jxom](https://github.com/jxom)! - Removed unneeded `uniqueBy` check on connectors state. + +- Updated dependencies [[`b80236dc`](https://github.com/wevm/wagmi/commit/b80236dc623095fe8f1e1d10957d7776fb6ab48b)]: + - @wagmi/core@2.6.13 + - @wagmi/connectors@4.1.22 + +## 2.5.15 + +### Patch Changes + +- [#3740](https://github.com/wevm/wagmi/pull/3740) [`3373c644`](https://github.com/wevm/wagmi/commit/3373c6444c38ef16532d18cfc351b3fe2bf2d351) Thanks [@BrickheadJohnny](https://github.com/BrickheadJohnny)! - Removed unnecessary re-renders from `useConnectorClient` and `useWalletClient`. + +- Updated dependencies [[`a59069e9`](https://github.com/wevm/wagmi/commit/a59069e9fab45dd606bb89a7f829fe94c51a5494), [`0acd3132`](https://github.com/wevm/wagmi/commit/0acd31320f534993af566be5490c2978b6184f66)]: + - @wagmi/core@2.6.12 + - @wagmi/connectors@4.1.21 + +## 2.5.14 + +### Patch Changes + +- [`e1ca4e63`](https://github.com/wevm/wagmi/commit/e1ca4e637ae6cec7f5902b0a2c0e0efc3b751a1d) Thanks [@tmm](https://github.com/tmm)! - Deprecated `normalizeChainId`. Use `Number` instead. + +- Updated dependencies [[`e1ca4e63`](https://github.com/wevm/wagmi/commit/e1ca4e637ae6cec7f5902b0a2c0e0efc3b751a1d)]: + - @wagmi/connectors@4.1.20 + - @wagmi/core@2.6.11 + +## 2.5.13 + +### Patch Changes + +- [`dbdca8fd`](https://github.com/wevm/wagmi/commit/dbdca8fd14b90c166222a66a373c1b33c06ce019) Thanks [@jxom](https://github.com/jxom)! - Fixed issue where duplicate connectors could be instantiated if injected after page mount. + +- Updated dependencies [[`dbdca8fd`](https://github.com/wevm/wagmi/commit/dbdca8fd14b90c166222a66a373c1b33c06ce019)]: + - @wagmi/core@2.6.10 + - @wagmi/connectors@4.1.19 + +## 2.5.12 + +### Patch Changes + +- [#3612](https://github.com/wevm/wagmi/pull/3612) [`97237bb0`](https://github.com/wevm/wagmi/commit/97237bb05c30860b9b12c094e82a38ce59d9bedf) Thanks [@m1heng](https://github.com/m1heng)! - Added missing `functionName` parameter to `useWriteContract` codegen helper. + +## 2.5.11 + +### Patch Changes + +- [#3714](https://github.com/wevm/wagmi/pull/3714) [`f1628d65`](https://github.com/wevm/wagmi/commit/f1628d65f06e9ef18e6c4e2eb4f6e3ab2e700924) Thanks [@dalechyn](https://github.com/dalechyn)! - Replaced `Omit` with `UnionOmit` for `UseMutationReturnType`. + +- [#3715](https://github.com/wevm/wagmi/pull/3715) [`d56edf4f`](https://github.com/wevm/wagmi/commit/d56edf4f27c52acc7a0f57114454b0d3e22cacd6) Thanks [@jxom](https://github.com/jxom)! - Fixed SSR hydration issues. + +- Updated dependencies [[`d56edf4f`](https://github.com/wevm/wagmi/commit/d56edf4f27c52acc7a0f57114454b0d3e22cacd6)]: + - @wagmi/core@2.6.9 + - @wagmi/connectors@4.1.18 + +## 2.5.10 + +### Patch Changes + +- [#3643](https://github.com/wevm/wagmi/pull/3643) [`e46bcd47`](https://github.com/wevm/wagmi/commit/e46bcd4738a18da15b53f6612b614379c1985374) Thanks [@TateB](https://github.com/TateB)! - Fixed race condition arising from `reconnect`. + +- Updated dependencies [[`e46bcd47`](https://github.com/wevm/wagmi/commit/e46bcd4738a18da15b53f6612b614379c1985374)]: + - @wagmi/core@2.6.8 + - @wagmi/connectors@4.1.17 + +## 2.5.9 + +### Patch Changes + +- [`f5648dd2`](https://github.com/wevm/wagmi/commit/f5648dd28b3576b628f57732b89287f55acbb1c1) Thanks [@jxom](https://github.com/jxom)! - Updated `prepareTransactionRequest` types for `viem@2.8.0`. + +- [`1c1fee6a`](https://github.com/wevm/wagmi/commit/1c1fee6ab8f01f7734ac6ce05093fa8e388beb3e) Thanks [@jxom](https://github.com/jxom)! - Updated `@walletconnect/ethereum-provider`. + +- Updated dependencies [[`b479b5e8`](https://github.com/wevm/wagmi/commit/b479b5e8a5866cba792862f22e6352c4fb566137), [`f5648dd2`](https://github.com/wevm/wagmi/commit/f5648dd28b3576b628f57732b89287f55acbb1c1), [`1c1fee6a`](https://github.com/wevm/wagmi/commit/1c1fee6ab8f01f7734ac6ce05093fa8e388beb3e), [`88a2d744`](https://github.com/wevm/wagmi/commit/88a2d744a1315908c9e54156026df3ad2435ad44)]: + - @wagmi/core@2.6.7 + - @wagmi/connectors@4.1.16 + +## 2.5.8 + +### Patch Changes + +- Updated dependencies [[`a91c0b64`](https://github.com/wevm/wagmi/commit/a91c0b64ba8b3e6537a560e69724eb601f26af27)]: + - @wagmi/core@2.6.6 + - @wagmi/connectors@4.1.15 + +## 2.5.7 + +### Patch Changes + +- [#3580](https://github.com/wevm/wagmi/pull/3580) [`c677dcd2`](https://github.com/wevm/wagmi/commit/c677dcd245dccdf69289a3d66dded237b09570a2) Thanks [@tmm](https://github.com/tmm)! - Made `useSwitchChain().chains` reactive. + +- Updated dependencies [[`ca5decdb`](https://github.com/wevm/wagmi/commit/ca5decdb712f81e3f5dab933a94b967bca5b6af4), [`c677dcd2`](https://github.com/wevm/wagmi/commit/c677dcd245dccdf69289a3d66dded237b09570a2)]: + - @wagmi/connectors@4.1.14 + - @wagmi/core@2.6.5 + +## 2.5.6 + +### Patch Changes + +- Updated dependencies [[`7c6618e6`](https://github.com/wevm/wagmi/commit/7c6618e6a0eb1ff39cf8f66b34d3ddc14be538fe), [`fa25b448`](https://github.com/wevm/wagmi/commit/fa25b4482504b4d9729a5687ea6d6dc959265bc0), [`895f28e8`](https://github.com/wevm/wagmi/commit/895f28e873af7c8eda5ca85734ff67c8979fd950)]: + - @wagmi/core@2.6.4 + - @wagmi/connectors@4.1.13 + +## 2.5.5 + +### Patch Changes + +- Updated dependencies [[`9c3b85dd`](https://github.com/wevm/wagmi/commit/9c3b85dd0a9a4a593e1d7e029345275735330e32), [`2a72214a`](https://github.com/wevm/wagmi/commit/2a72214a2901d6b6ddd39f80238aa0bd4db670a7)]: + - @wagmi/core@2.6.3 + - @wagmi/connectors@4.1.12 + +## 2.5.4 + +### Patch Changes + +- [`3f8203bd`](https://github.com/wevm/wagmi/commit/3f8203bd77fcf6b6756640b5971d09741ae3853d) Thanks [@tmm](https://github.com/tmm)! - Fixed `useBlock` parameters passthrough to Viem. + +## 2.5.3 + +### Patch Changes + +- [#3518](https://github.com/wevm/wagmi/pull/3518) [`338e857d`](https://github.com/wevm/wagmi/commit/338e857d8cb2fe85e13d9207bef14cada1c1962d) Thanks [@tmm](https://github.com/tmm)! - Bumped dependencies. + +- Updated dependencies [[`414eb048`](https://github.com/wevm/wagmi/commit/414eb048af492caac70c0e874dfc87c30702804a), [`338e857d`](https://github.com/wevm/wagmi/commit/338e857d8cb2fe85e13d9207bef14cada1c1962d), [`338e857d`](https://github.com/wevm/wagmi/commit/338e857d8cb2fe85e13d9207bef14cada1c1962d)]: + - @wagmi/core@2.6.2 + - @wagmi/connectors@4.1.11 + +## 2.5.2 + +### Patch Changes + +- [#3433](https://github.com/wevm/wagmi/pull/3433) [`101a7dd1`](https://github.com/wevm/wagmi/commit/101a7dd131b0cae2dc25579ecab9044290efd37b) Thanks [@tmm](https://github.com/tmm)! - Fixed `useClient` and `usePublicClient` throwing when used with unconfigured `chainId`. + +- [#3510](https://github.com/wevm/wagmi/pull/3510) [`660ff80d`](https://github.com/wevm/wagmi/commit/660ff80d5b046967a446eba43ee54b8359a37d0d) Thanks [@tmm](https://github.com/tmm)! - Fixed issue where connectors returning multiple addresses didn't checksum correctly. + +- Updated dependencies [[`660ff80d`](https://github.com/wevm/wagmi/commit/660ff80d5b046967a446eba43ee54b8359a37d0d), [`101a7dd1`](https://github.com/wevm/wagmi/commit/101a7dd131b0cae2dc25579ecab9044290efd37b)]: + - @wagmi/connectors@4.1.10 + - @wagmi/core@2.6.1 + +## 2.5.1 + +### Patch Changes + +- [#3496](https://github.com/wevm/wagmi/pull/3496) [`ba7f8a75`](https://github.com/wevm/wagmi/commit/ba7f8a758efb07664c6e401b5e7e325e7c62341b) Thanks [@tmm](https://github.com/tmm)! - Bumped dependencies. + +- Updated dependencies [[`ba7f8a75`](https://github.com/wevm/wagmi/commit/ba7f8a758efb07664c6e401b5e7e325e7c62341b), [`ba7f8a75`](https://github.com/wevm/wagmi/commit/ba7f8a758efb07664c6e401b5e7e325e7c62341b)]: + - @wagmi/connectors@4.1.9 + - @wagmi/core@2.6.0 + +## 2.5.0 + +### Minor Changes + +- [#3461](https://github.com/wevm/wagmi/pull/3461) [`ca98041d`](https://github.com/wevm/wagmi/commit/ca98041d1b39893d90246929485f4db0d1c6f9f7) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Added `useTransactionConfirmations` hook. + +### Patch Changes + +- Updated dependencies [[`ca98041d`](https://github.com/wevm/wagmi/commit/ca98041d1b39893d90246929485f4db0d1c6f9f7)]: + - @wagmi/core@2.5.0 + - @wagmi/connectors@4.1.8 + +## 2.4.0 + +### Minor Changes + +- [#3427](https://github.com/wevm/wagmi/pull/3427) [`370f1b4a`](https://github.com/wevm/wagmi/commit/370f1b4a3f154d181acf381c31c2e7862e22c0e4) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Added `usePrepareTransactionRequest` hook. + +### Patch Changes + +- Updated dependencies [[`370f1b4a`](https://github.com/wevm/wagmi/commit/370f1b4a3f154d181acf381c31c2e7862e22c0e4), [`370f1b4a`](https://github.com/wevm/wagmi/commit/370f1b4a3f154d181acf381c31c2e7862e22c0e4)]: + - @wagmi/connectors@4.1.7 + - @wagmi/core@2.4.0 + +## 2.3.1 + +### Patch Changes + +- [#3476](https://github.com/wevm/wagmi/pull/3476) [`3be5bb7b`](https://github.com/wevm/wagmi/commit/3be5bb7b0b38646e12e6da5c762ef74dff66bcc2) Thanks [@jxom](https://github.com/jxom)! - Modified persist strategy to only store "critical" properties that are needed before hydration. + +- Updated dependencies [[`3be5bb7b`](https://github.com/wevm/wagmi/commit/3be5bb7b0b38646e12e6da5c762ef74dff66bcc2)]: + - @wagmi/core@2.3.1 + - @wagmi/connectors@4.1.6 + +## 2.3.0 + +### Minor Changes + +- [#3459](https://github.com/wevm/wagmi/pull/3459) [`d950b666`](https://github.com/wevm/wagmi/commit/d950b666b56700ca039ce16cdfdf34564991e7f5) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Added `useEnsText` action. + +### Patch Changes + +- [#3467](https://github.com/wevm/wagmi/pull/3467) [`90ef39bb`](https://github.com/wevm/wagmi/commit/90ef39bb0f4ecb3c914d317875348e35ba0f4524) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where connectors that share the same provider instance could reconnect when they have never been connected before. + +- [`1cfb6e5a`](https://github.com/wevm/wagmi/commit/1cfb6e5a875e707abcee00dd5739e87da05e8c90) Thanks [@jxom](https://github.com/jxom)! - Bumped listener limit on WalletConnect connector. + +- Updated dependencies [[`d950b666`](https://github.com/wevm/wagmi/commit/d950b666b56700ca039ce16cdfdf34564991e7f5), [`d950b666`](https://github.com/wevm/wagmi/commit/d950b666b56700ca039ce16cdfdf34564991e7f5), [`90ef39bb`](https://github.com/wevm/wagmi/commit/90ef39bb0f4ecb3c914d317875348e35ba0f4524), [`1cfb6e5a`](https://github.com/wevm/wagmi/commit/1cfb6e5a875e707abcee00dd5739e87da05e8c90)]: + - @wagmi/core@2.3.0 + - @wagmi/connectors@5.0.0 + +## 2.2.1 + +### Patch Changes + +- [#3443](https://github.com/wevm/wagmi/pull/3443) [`007024a6`](https://github.com/wevm/wagmi/commit/007024a684ddbecf924cdc06dd6a8854fc3d5eeb) Thanks [@jmrossy](https://github.com/jmrossy)! - Bumped dependencies. + +- [#3447](https://github.com/wevm/wagmi/pull/3447) [`a02a26ad`](https://github.com/wevm/wagmi/commit/a02a26ad030d3afb78f744377d61b5c60b65d97a) Thanks [@tmm](https://github.com/tmm)! - Fixed account typing. + +- Updated dependencies [[`007024a6`](https://github.com/wevm/wagmi/commit/007024a684ddbecf924cdc06dd6a8854fc3d5eeb), [`a02a26ad`](https://github.com/wevm/wagmi/commit/a02a26ad030d3afb78f744377d61b5c60b65d97a), [`a02a26ad`](https://github.com/wevm/wagmi/commit/a02a26ad030d3afb78f744377d61b5c60b65d97a), [`007024a6`](https://github.com/wevm/wagmi/commit/007024a684ddbecf924cdc06dd6a8854fc3d5eeb)]: + - @wagmi/connectors@4.1.4 + - @wagmi/core@2.2.1 + +## 2.2.0 + +### Minor Changes + +- [#3434](https://github.com/wevm/wagmi/pull/3434) [`00bf10a4`](https://github.com/wevm/wagmi/commit/00bf10a428b0d1c5dac35ebf25b19571e033ac26) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Added `useBytecode` and `useStorageAt` hooks. + +- [#3408](https://github.com/wevm/wagmi/pull/3408) [`fb6c4148`](https://github.com/wevm/wagmi/commit/fb6c4148d9e9e2fccfbe74c8f343b444dc68dec5) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Added `useProof` hook. + +- [#3416](https://github.com/wevm/wagmi/pull/3416) [`64c073f6`](https://github.com/wevm/wagmi/commit/64c073f6c2720961e2d6aff986670b73dbfab9c3) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Added `useTransactionReceipt` hook. + +### Patch Changes + +- Updated dependencies [[`00bf10a4`](https://github.com/wevm/wagmi/commit/00bf10a428b0d1c5dac35ebf25b19571e033ac26), [`64c073f6`](https://github.com/wevm/wagmi/commit/64c073f6c2720961e2d6aff986670b73dbfab9c3), [`fb6c4148`](https://github.com/wevm/wagmi/commit/fb6c4148d9e9e2fccfbe74c8f343b444dc68dec5)]: + - @wagmi/core@2.2.0 + - @wagmi/connectors@5.0.0 + +## 2.1.2 + +### Patch Changes + +- [#3407](https://github.com/wevm/wagmi/pull/3407) [`e00b8205`](https://github.com/wevm/wagmi/commit/e00b82058685751637edfa9a6b2d196a12549fe7) Thanks [@jxom](https://github.com/jxom)! - Added a prelude gas estimate check to `sendTransaction`/`useSendTransaction`. + +- Updated dependencies [[`e00b8205`](https://github.com/wevm/wagmi/commit/e00b82058685751637edfa9a6b2d196a12549fe7)]: + - @wagmi/core@2.1.2 + - @wagmi/connectors@4.1.2 + +## 2.1.1 + +### Patch Changes + +- [#3402](https://github.com/wevm/wagmi/pull/3402) [`64b82282`](https://github.com/wevm/wagmi/commit/64b82282c1e57e77c25aa0814673780e4d11edd4) Thanks [@Songkeys](https://github.com/Songkeys)! - Fixed SSR cookie support for cookies that have special characters, e.g. `=`. + +- [`ec0d8b41`](https://github.com/wevm/wagmi/commit/ec0d8b4112181fefb11025e436a94a6114761d37) Thanks [@tmm](https://github.com/tmm)! - Added note to `metaMask` connector. + +- Updated dependencies [[`64b82282`](https://github.com/wevm/wagmi/commit/64b82282c1e57e77c25aa0814673780e4d11edd4), [`ec0d8b41`](https://github.com/wevm/wagmi/commit/ec0d8b4112181fefb11025e436a94a6114761d37)]: + - @wagmi/core@2.1.1 + - @wagmi/connectors@4.1.1 + +## 2.1.0 + +### Minor Changes + +- [#3387](https://github.com/wevm/wagmi/pull/3387) [`c9cd302e`](https://github.com/wevm/wagmi/commit/c9cd302e1c65c980deaee2e12567c2a8ec08b399) Thanks [@marthendalnunes](https://github.com/marthendalnunes)! - Added `useCall` hook. + +### Patch Changes + +- Updated dependencies [[`c9cd302e`](https://github.com/wevm/wagmi/commit/c9cd302e1c65c980deaee2e12567c2a8ec08b399)]: + - @wagmi/core@2.1.0 + - @wagmi/connectors@5.0.0 + +## 2.0.3 + +### Patch Changes + +- [#3384](https://github.com/wevm/wagmi/pull/3384) [`ee868c33`](https://github.com/wevm/wagmi/commit/ee868c3385dae511230b6ddcb5627c1293cc1844) Thanks [@tmm](https://github.com/tmm)! - Fixed connectors not bubbling error when connecting with `chainId` and subsequent user rejection. + +- Updated dependencies [[`ee868c33`](https://github.com/wevm/wagmi/commit/ee868c3385dae511230b6ddcb5627c1293cc1844)]: + - @wagmi/connectors@4.0.2 + - @wagmi/core@2.0.2 + +## 2.0.2 + +### Patch Changes + +- [#3379](https://github.com/wevm/wagmi/pull/3379) [`30a186e5`](https://github.com/wevm/wagmi/commit/30a186e53d1135657d04f72f40d1c27186025370) Thanks [@tmm](https://github.com/tmm)! - Fixed `useConnect` error getting unset. + +## 2.0.1 + +### Major Changes + +- [#3333](https://github.com/wevm/wagmi/pull/3333) [`b3a0baaa`](https://github.com/wevm/wagmi/commit/b3a0baaaee7decf750d376aab2502cd33ca4825a) Thanks [@tmm](https://github.com/tmm)! - Wagmi 2.0 featuring: + + - Full TanStack Query support + queryKeys + - Connect multiple connectors + - Switch chains while disconnected + - EIP-6963 enabled + - Strongly typed chainId and chain properties + - Smaller bundle size + - Miscellaneous improvements and bug fixes + + [Breaking Changes & Migration Guide](https://wagmi.sh/react/guides/migrate-from-v1-to-v2) + +### Patch Changes + +- Updated dependencies [[`b3a0baaa`](https://github.com/wevm/wagmi/commit/b3a0baaaee7decf750d376aab2502cd33ca4825a), [`b3a0baaa`](https://github.com/wevm/wagmi/commit/b3a0baaaee7decf750d376aab2502cd33ca4825a)]: + - @wagmi/connectors@4.0.0 + - @wagmi/core@2.0.0 + +## 1.4.13 + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@1.4.13 + +## 1.4.12 + +### Patch Changes + +- [`53ca1f7e`](https://github.com/wevm/wagmi/commit/53ca1f7eb411d912e11fcce7e03bd61ed067959c) Thanks [@tmm](https://github.com/tmm)! - Removed LedgerConnector due to security vulnerability + +- Updated dependencies [[`53ca1f7e`](https://github.com/wevm/wagmi/commit/53ca1f7eb411d912e11fcce7e03bd61ed067959c)]: + - @wagmi/core@1.4.12 + +## 1.4.11 + +### Patch Changes + +- [#3299](https://github.com/wevm/wagmi/pull/3299) [`b02020b3`](https://github.com/wevm/wagmi/commit/b02020b3724e0228198f35817611bb063295906e) Thanks [@dasanra](https://github.com/dasanra)! - Fixed issue with [Safe SDK](https://github.com/wevm/viem/issues/579) by bumping `@safe-global/safe-apps-provider@0.18.1` + +- Updated dependencies [[`b02020b3`](https://github.com/wevm/wagmi/commit/b02020b3724e0228198f35817611bb063295906e)]: + - @wagmi/core@1.4.11 + +## 1.4.10 + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@1.4.10 + +## 1.4.9 + +### Patch Changes + +- [#3276](https://github.com/wevm/wagmi/pull/3276) [`83223a06`](https://github.com/wevm/wagmi/commit/83223a0659e2f675d897a1d3374c7af752c16abf) Thanks [@glitch-txs](https://github.com/glitch-txs)! - Removed required namespaces from WalletConnect connector + +- Updated dependencies [[`83223a06`](https://github.com/wevm/wagmi/commit/83223a0659e2f675d897a1d3374c7af752c16abf)]: + - @wagmi/core@1.4.9 + +## 1.4.8 + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@1.4.8 + +## 1.4.7 + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@1.4.7 + +## 1.4.6 + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@1.4.6 + +## 1.4.5 + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@1.4.5 + +## 1.4.4 + +### Patch Changes + +- [#3125](https://github.com/wagmi-dev/wagmi/pull/3125) [`725e73fe`](https://github.com/wagmi-dev/wagmi/commit/725e73feb9143dbaa6d540bb76d2009cef29da0b) Thanks [@lukasrosario](https://github.com/lukasrosario)! - Fixed an issue where `dataSuffix` was not being passed down into viem's `simulateContract`, causing the data to be omitted from requests. + +- Updated dependencies [[`725e73fe`](https://github.com/wagmi-dev/wagmi/commit/725e73feb9143dbaa6d540bb76d2009cef29da0b)]: + - @wagmi/core@1.4.4 + +## 1.4.3 + +### Patch Changes + +- [#3076](https://github.com/wagmi-dev/wagmi/pull/3076) [`4c36831b`](https://github.com/wagmi-dev/wagmi/commit/4c36831b7aa44d03b5c0decf64dcd20faae28a67) Thanks [@jxom](https://github.com/jxom)! - Pass `chain` to viem `sendTransaction`/`writeContract`. + +- [#3006](https://github.com/wagmi-dev/wagmi/pull/3006) [`f2ddce23`](https://github.com/wagmi-dev/wagmi/commit/f2ddce23324aff0a91e066100918dac552dc3b4a) Thanks [@jxom](https://github.com/jxom)! - Changed `normalize` to a dynamic import. + +- Updated dependencies [[`4c36831b`](https://github.com/wagmi-dev/wagmi/commit/4c36831b7aa44d03b5c0decf64dcd20faae28a67), [`f2ddce23`](https://github.com/wagmi-dev/wagmi/commit/f2ddce23324aff0a91e066100918dac552dc3b4a)]: + - @wagmi/core@1.4.3 + +## 1.4.2 + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@1.4.2 + +## 1.4.1 + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@1.4.1 + +## 1.4.0 + +### Minor Changes + +- [#2956](https://github.com/wagmi-dev/wagmi/pull/2956) [`2abeb285`](https://github.com/wagmi-dev/wagmi/commit/2abeb285674af3e539cc2550b1f5027b1eb0c895) Thanks [@tmm](https://github.com/tmm)! - Replaced `@wagmi/chains` with `viem/chains`. + +### Patch Changes + +- Updated dependencies [[`2abeb285`](https://github.com/wagmi-dev/wagmi/commit/2abeb285674af3e539cc2550b1f5027b1eb0c895)]: + - @wagmi/core@1.4.0 + +## 1.3.11 + +### Patch Changes + +- [`557e6400`](https://github.com/wagmi-dev/wagmi/commit/557e6400b9cef3b2c5131739143956c37d7c934a) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +- Updated dependencies [[`557e6400`](https://github.com/wagmi-dev/wagmi/commit/557e6400b9cef3b2c5131739143956c37d7c934a)]: + - @wagmi/core@1.3.10 + +## 1.3.10 + +### Patch Changes + +- [`247c5d11`](https://github.com/wagmi-dev/wagmi/commit/247c5d113e83acf3a6894264c00d4b125d455107) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +- Updated dependencies [[`247c5d11`](https://github.com/wagmi-dev/wagmi/commit/247c5d113e83acf3a6894264c00d4b125d455107)]: + - @wagmi/core@1.3.9 + +## 1.3.9 + +### Patch Changes + +- [#2741](https://github.com/wagmi-dev/wagmi/pull/2741) [`5b1453d9`](https://github.com/wagmi-dev/wagmi/commit/5b1453d95973ed51f1c235a919fffb707eab9b70) Thanks [@jxom](https://github.com/jxom)! - Updated references + +- Updated dependencies [[`5b1453d9`](https://github.com/wagmi-dev/wagmi/commit/5b1453d95973ed51f1c235a919fffb707eab9b70)]: + - @wagmi/core@1.3.8 + +## 1.3.8 + +### Patch Changes + +- [#2700](https://github.com/wagmi-dev/wagmi/pull/2700) [`30118e97`](https://github.com/wagmi-dev/wagmi/commit/30118e979b1b00302e035f31f58c15d1aed911d5) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +- Updated dependencies [[`30118e97`](https://github.com/wagmi-dev/wagmi/commit/30118e979b1b00302e035f31f58c15d1aed911d5)]: + - @wagmi/core@1.3.7 + +## 1.3.7 + +### Patch Changes + +- [`7ad2fdb8`](https://github.com/wagmi-dev/wagmi/commit/7ad2fdb81c7734d0c8107670800c68390e3bad99) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +- Updated dependencies [[`7ad2fdb8`](https://github.com/wagmi-dev/wagmi/commit/7ad2fdb81c7734d0c8107670800c68390e3bad99)]: + - @wagmi/core@1.3.6 + +## 1.3.6 + +### Patch Changes + +- [`aab63fc1`](https://github.com/wagmi-dev/wagmi/commit/aab63fc1f8949004573978ecd8574fada3360758) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +- Updated dependencies [[`aab63fc1`](https://github.com/wagmi-dev/wagmi/commit/aab63fc1f8949004573978ecd8574fada3360758)]: + - @wagmi/core@1.3.5 + +## 1.3.5 + +### Patch Changes + +- [#2669](https://github.com/wagmi-dev/wagmi/pull/2669) [`db75c459`](https://github.com/wagmi-dev/wagmi/commit/db75c4593b9c46970dc9d3c96d7adafc76878fc3) Thanks [@llllvvuu](https://github.com/llllvvuu)! - Modified `useAccount` and `useNetwork` to be reactive of wagmi Config (`config`). + +## 1.3.4 + +### Patch Changes + +- [`b056f809`](https://github.com/wagmi-dev/wagmi/commit/b056f8095674d4addc6ecd09adf6001fe52e2b15) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where `onConnect` was not being called when multiple instances of `useAccount` existed. + +- [`22246d98`](https://github.com/wagmi-dev/wagmi/commit/22246d9884277d28ccad6ca2d9529b96b67d47fc) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +- Updated dependencies [[`22246d98`](https://github.com/wagmi-dev/wagmi/commit/22246d9884277d28ccad6ca2d9529b96b67d47fc)]: + - @wagmi/core@1.3.4 + +## 1.3.3 + +### Patch Changes + +- [`1946aa43`](https://github.com/wagmi-dev/wagmi/commit/1946aa43a65b684ef41b7b4c43c67bf29c13e854) Thanks [@jxom](https://github.com/jxom)! - Updated references + +- Updated dependencies [[`1946aa43`](https://github.com/wagmi-dev/wagmi/commit/1946aa43a65b684ef41b7b4c43c67bf29c13e854)]: + - @wagmi/core@1.3.3 + +## 1.3.2 + +### Patch Changes + +- [`e86d0940`](https://github.com/wagmi-dev/wagmi/commit/e86d09409bb20b64d24e1263abcf0291314f03c7) Thanks [@jxom](https://github.com/jxom)! - Updated references + +- Updated dependencies [[`e86d0940`](https://github.com/wagmi-dev/wagmi/commit/e86d09409bb20b64d24e1263abcf0291314f03c7)]: + - @wagmi/core@1.3.2 + +## 1.3.1 + +### Patch Changes + +- [`964042fa`](https://github.com/wagmi-dev/wagmi/commit/964042fa94d682977923c595820c58283fb9244a) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +- Updated dependencies [[`964042fa`](https://github.com/wagmi-dev/wagmi/commit/964042fa94d682977923c595820c58283fb9244a)]: + - @wagmi/core@1.3.1 + +## 1.3.0 + +### Minor Changes + +- [#2619](https://github.com/wagmi-dev/wagmi/pull/2619) [`0d79748c`](https://github.com/wagmi-dev/wagmi/commit/0d79748cec2b6ac2410ad2c9816cc662f2b70962) Thanks [@jxom](https://github.com/jxom)! - Updated references: + - Updated `@safe-global/safe-apps-sdk` to `^8.0.0` (the one with `viem` support) + +### Patch Changes + +- Updated dependencies [[`0d79748c`](https://github.com/wagmi-dev/wagmi/commit/0d79748cec2b6ac2410ad2c9816cc662f2b70962)]: + - @wagmi/core@1.3.0 + +## 1.2.2 + +### Patch Changes + +- [#2611](https://github.com/wagmi-dev/wagmi/pull/2611) [`6d1ed7a1`](https://github.com/wagmi-dev/wagmi/commit/6d1ed7a156729b4df5d66fef3ae9a8b5762a2d34) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +- Updated dependencies [[`6d1ed7a1`](https://github.com/wagmi-dev/wagmi/commit/6d1ed7a156729b4df5d66fef3ae9a8b5762a2d34)]: + - @wagmi/core@1.2.2 + +## 1.2.1 + +### Patch Changes + +- [#2589](https://github.com/wagmi-dev/wagmi/pull/2589) [`9680c347`](https://github.com/wagmi-dev/wagmi/commit/9680c347476500d28ceca20d23eeaed7931cb6e0) Thanks [@jxom](https://github.com/jxom)! - Fixed `writeContract` parameters to be compatible with `prepareWriteContract`. + +- [#2587](https://github.com/wagmi-dev/wagmi/pull/2587) [`cfff9994`](https://github.com/wagmi-dev/wagmi/commit/cfff999459384ac644ff7e62f53a7b787cf37507) Thanks [@jxom](https://github.com/jxom)! - Updated references + +- Updated dependencies [[`9680c347`](https://github.com/wagmi-dev/wagmi/commit/9680c347476500d28ceca20d23eeaed7931cb6e0), [`cfff9994`](https://github.com/wagmi-dev/wagmi/commit/cfff999459384ac644ff7e62f53a7b787cf37507)]: + - @wagmi/core@1.2.1 + +## 1.2.0 + +### Minor Changes + +- [#2536](https://github.com/wagmi-dev/wagmi/pull/2536) [`85e9760a`](https://github.com/wagmi-dev/wagmi/commit/85e9760a140cb169ac6236d9466b96e2105dd193) Thanks [@tmm](https://github.com/tmm)! - Changed `Address` type import from ABIType to viem. + +### Patch Changes + +- [#2539](https://github.com/wagmi-dev/wagmi/pull/2539) [`96319c64`](https://github.com/wagmi-dev/wagmi/commit/96319c640b9d07b375821c08a5c213355d8c290b) Thanks [@jxom](https://github.com/jxom)! - Updated references + +- Updated dependencies [[`85e9760a`](https://github.com/wagmi-dev/wagmi/commit/85e9760a140cb169ac6236d9466b96e2105dd193), [`96319c64`](https://github.com/wagmi-dev/wagmi/commit/96319c640b9d07b375821c08a5c213355d8c290b)]: + - @wagmi/core@1.2.0 + +## 1.1.1 + +### Patch Changes + +- [`02b98a9f`](https://github.com/wagmi-dev/wagmi/commit/02b98a9f9b2c503a47af4a8967e0202b5db21787) Thanks [@jxom](https://github.com/jxom)! - Updated `viem` peer dependency. + +- [`02b98a9f`](https://github.com/wagmi-dev/wagmi/commit/02b98a9f9b2c503a47af4a8967e0202b5db21787) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +- Updated dependencies [[`02b98a9f`](https://github.com/wagmi-dev/wagmi/commit/02b98a9f9b2c503a47af4a8967e0202b5db21787), [`02b98a9f`](https://github.com/wagmi-dev/wagmi/commit/02b98a9f9b2c503a47af4a8967e0202b5db21787)]: + - @wagmi/core@1.1.1 + +## 1.1.0 + +### Minor Changes + +- [#2482](https://github.com/wagmi-dev/wagmi/pull/2482) [`8764b54a`](https://github.com/wagmi-dev/wagmi/commit/8764b54aab68020063946112e8fe52aff650c99c) Thanks [@tmm](https://github.com/tmm)! - Bumped minimum TypeScript version to v5.0.4. + +### Patch Changes + +- [#2471](https://github.com/wagmi-dev/wagmi/pull/2471) [`74099cef`](https://github.com/wagmi-dev/wagmi/commit/74099cefd922317641529f7881a4c8a740d62cbe) Thanks [@iuriiiurevich](https://github.com/iuriiiurevich)! - Added `keepPreviousData` prop to `useContractRead`. + +- [#2484](https://github.com/wagmi-dev/wagmi/pull/2484) [`3adf1f4f`](https://github.com/wagmi-dev/wagmi/commit/3adf1f4feab863cb7b5d52c81ad46f7e4eb56f09) Thanks [@jxom](https://github.com/jxom)! - Updated `abitype` to 0.8.7 + +- [#2484](https://github.com/wagmi-dev/wagmi/pull/2484) [`3adf1f4f`](https://github.com/wagmi-dev/wagmi/commit/3adf1f4feab863cb7b5d52c81ad46f7e4eb56f09) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +- [`01d4a6ed`](https://github.com/wagmi-dev/wagmi/commit/01d4a6ed53110712692599095d94f04dfb5b6e38) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where `useInvalidateOnBlock`'s `onBlock` was being called on every render. + +- Updated dependencies [[`8764b54a`](https://github.com/wagmi-dev/wagmi/commit/8764b54aab68020063946112e8fe52aff650c99c), [`3adf1f4f`](https://github.com/wagmi-dev/wagmi/commit/3adf1f4feab863cb7b5d52c81ad46f7e4eb56f09), [`3adf1f4f`](https://github.com/wagmi-dev/wagmi/commit/3adf1f4feab863cb7b5d52c81ad46f7e4eb56f09)]: + - @wagmi/core@1.1.0 + +## 1.0.9 + +### Patch Changes + +- [#2446](https://github.com/wagmi-dev/wagmi/pull/2446) [`899d8c06`](https://github.com/wagmi-dev/wagmi/commit/899d8c0698e6cc958ca8ad9ec586883edf20516e) Thanks [@iuriiiurevich](https://github.com/iuriiiurevich)! - Added `cancelRefetch: false` to `useInvalidateOnBlock`. + +## 1.0.8 + +### Patch Changes + +- [#2441](https://github.com/wagmi-dev/wagmi/pull/2441) [`326edee4`](https://github.com/wagmi-dev/wagmi/commit/326edee4bc85db84a7a4e3768e33785849ab8d8e) Thanks [@tmm](https://github.com/tmm)! - Fixed internal type issue + +- Updated dependencies [[`326edee4`](https://github.com/wagmi-dev/wagmi/commit/326edee4bc85db84a7a4e3768e33785849ab8d8e)]: + - @wagmi/core@1.0.8 + +## 1.0.7 + +### Patch Changes + +- [#2433](https://github.com/wagmi-dev/wagmi/pull/2433) [`54fcff5f`](https://github.com/wagmi-dev/wagmi/commit/54fcff5f02f6933bbbe045ee0c83c5a78b6bba49) Thanks [@jxom](https://github.com/jxom)! - Added ability to pass an `account` to `useContractWrite`/`usePrepareContractWrite`. + +- Updated dependencies [[`54fcff5f`](https://github.com/wagmi-dev/wagmi/commit/54fcff5f02f6933bbbe045ee0c83c5a78b6bba49)]: + - @wagmi/core@1.0.7 + +## 1.0.6 + +### Patch Changes + +- [`ca2e1e96`](https://github.com/wagmi-dev/wagmi/commit/ca2e1e96149b87a7dc42c9db07e1f1ad2bb02c4a) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +- [#2401](https://github.com/wagmi-dev/wagmi/pull/2401) [`0f9dc875`](https://github.com/wagmi-dev/wagmi/commit/0f9dc875e90cfdd7a2028e04b7204caf9ea313b2) Thanks [@jxom](https://github.com/jxom)! - Exposed `account` on `readContract`/`useContractRead`. + +- Updated dependencies [[`ca2e1e96`](https://github.com/wagmi-dev/wagmi/commit/ca2e1e96149b87a7dc42c9db07e1f1ad2bb02c4a), [`0f9dc875`](https://github.com/wagmi-dev/wagmi/commit/0f9dc875e90cfdd7a2028e04b7204caf9ea313b2)]: + - @wagmi/core@1.0.6 + +## 1.0.5 + +### Patch Changes + +- [`90e2b3b3`](https://github.com/wagmi-dev/wagmi/commit/90e2b3b39efe0585fe28645ac2264109be17362a) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +- Updated dependencies [[`90e2b3b3`](https://github.com/wagmi-dev/wagmi/commit/90e2b3b39efe0585fe28645ac2264109be17362a)]: + - @wagmi/core@1.0.5 + +## 1.0.4 + +### Patch Changes + +- [#2344](https://github.com/wagmi-dev/wagmi/pull/2344) [`8a725458`](https://github.com/wagmi-dev/wagmi/commit/8a72545853ae1024acd9efd18c06142e8c6c5750) Thanks [@jxom](https://github.com/jxom)! - Added gas estimation back into `prepareSendTransaction`. + +- Updated dependencies [[`8a725458`](https://github.com/wagmi-dev/wagmi/commit/8a72545853ae1024acd9efd18c06142e8c6c5750)]: + - @wagmi/core@1.0.4 + +## 1.0.3 + +### Patch Changes + +- [#2338](https://github.com/wagmi-dev/wagmi/pull/2338) [`92bfdc2c`](https://github.com/wagmi-dev/wagmi/commit/92bfdc2c744539558ba93c95f140b46ad331cee4) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where synchronous switch chain behavior (WalletConnect v2) would encounter chain id race conditions in `watchWalletClient`. + +- Updated dependencies [[`92bfdc2c`](https://github.com/wagmi-dev/wagmi/commit/92bfdc2c744539558ba93c95f140b46ad331cee4)]: + - @wagmi/core@1.0.3 + +## 1.0.2 + +### Patch Changes + +- Updated dependencies [[`09a4fd38`](https://github.com/wevm/wagmi/commit/09a4fd38f44eb176797925fd85314be17b610cd4)]: + - @wagmi/core@1.0.2 + +## 1.0.1 + +### Patch Changes + +- [`ea651cd7`](https://github.com/wevm/wagmi/commit/ea651cd7fc75b7866272605467db11fd6e1d81af) Thanks [@jxom](https://github.com/jxom)! - Downgraded abitype. + +- Updated dependencies [[`ea651cd7`](https://github.com/wevm/wagmi/commit/ea651cd7fc75b7866272605467db11fd6e1d81af)]: + - @wagmi/core@1.0.1 + +## 1.0.0 + +### Major Changes + +- [#2235](https://github.com/wevm/wagmi/pull/2235) [`5be0655c`](https://github.com/wevm/wagmi/commit/5be0655c8e48b25d38009022461fbf611af54349) Thanks [@jxom](https://github.com/jxom)! - Released v1. Read [Migration Guide](https://next.wagmi.sh/react/migration-guide#1xx-breaking-changes). + +### Patch Changes + +- Updated dependencies [[`5be0655c`](https://github.com/wevm/wagmi/commit/5be0655c8e48b25d38009022461fbf611af54349)]: + - @wagmi/core@1.0.0 + +## 1.0.0-next.9 + +### Patch Changes + +- Fixed `useContractEvent` effect dependencies. + +## 1.0.0-next.8 + +### Patch Changes + +- Added "use client" banner + +## 1.0.0-next.7 + +### Major Changes + +- [#2235](https://github.com/wevm/wagmi/pull/2235) [`708b2ce2`](https://github.com/wevm/wagmi/commit/708b2ce26efa8d3d910806a97cea5171dabc65de) Thanks [@jxom](https://github.com/jxom)! - Added `config.setPublicClient` & `config.setWebSocketPublicClient` + +- Updated references. + +### Patch Changes + +- Updated dependencies [[`708b2ce2`](https://github.com/wevm/wagmi/commit/708b2ce26efa8d3d910806a97cea5171dabc65de)]: + - @wagmi/core@1.0.0-next.7 + +## 1.0.0-next.6 + +### Major Changes + +- Added `config.setConnectors` + +### Patch Changes + +- Updated dependencies [[`708b2ce2`](https://github.com/wevm/wagmi/commit/708b2ce26efa8d3d910806a97cea5171dabc65de)]: + - @wagmi/core@1.0.0-next.6 + +## 1.0.0-next.5 + +### Major Changes + +- [#2235](https://github.com/wevm/wagmi/pull/2235) [`708b2ce2`](https://github.com/wevm/wagmi/commit/708b2ce26efa8d3d910806a97cea5171dabc65de) Thanks [@jxom](https://github.com/jxom)! - Added `config.setPublicClient` & `config.setWebSocketPublicClient` + +### Patch Changes + +- Updated dependencies [[`708b2ce2`](https://github.com/wevm/wagmi/commit/708b2ce26efa8d3d910806a97cea5171dabc65de)]: + - @wagmi/core@1.0.0-next.5 + +## 1.0.0-next.4 + +### Major Changes + +- Updated viem. + Removed `goerli` export from main entrypoint. + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@1.0.0-next.4 + +## 1.0.0-next.3 + +### Major Changes + +- Updated references. + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@1.0.0-next.3 + +## 1.0.0-next.2 + +### Major Changes + +- **Breaking:** Renamed `createClient` to `createConfig` +- **Breaking:** Renamed `useClient` to `useConfig` +- **Breaking:** Removed `request` as an argument to `usePrepareSendTransaction` & `useSendTransaction`. Arguments now belong on the root level of the Hook. + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@1.0.0-next.2 + +## 1.0.0-next.1 + +### Major Changes + +- updated viem + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@1.0.0-next.1 + +## 1.0.0-next.0 + +### Major Changes + +- [`a7dda00c`](https://github.com/wevm/wagmi/commit/a7dda00c5b546f8b2c42b527e4d9ac1b9e9ab1fb) Thanks [@jxom](https://github.com/jxom)! - Released v1. + +### Patch Changes + +- Updated dependencies [[`a7dda00c`](https://github.com/wevm/wagmi/commit/a7dda00c5b546f8b2c42b527e4d9ac1b9e9ab1fb)]: + - @wagmi/core@1.0.0-next.0 + +## 0.12.13 + +### Patch Changes + +- [#2270](https://github.com/wevm/wagmi/pull/2270) [`6d1fa9df`](https://github.com/wevm/wagmi/commit/6d1fa9df790287729c3b33d4f01fd23c2f8153f1) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +- Updated dependencies [[`6d1fa9df`](https://github.com/wevm/wagmi/commit/6d1fa9df790287729c3b33d4f01fd23c2f8153f1)]: + - @wagmi/core@0.10.11 + +## 0.12.12 + +### Patch Changes + +- [#2208](https://github.com/wevm/wagmi/pull/2208) [`cfc696d8`](https://github.com/wevm/wagmi/commit/cfc696d83c6f768a2e1a29c5197efeed7f1d40a1) Thanks [@bangtoven](https://github.com/bangtoven)! - Bumped references to apply coinbase wallet sdk updates + +- Updated dependencies [[`cfc696d8`](https://github.com/wevm/wagmi/commit/cfc696d83c6f768a2e1a29c5197efeed7f1d40a1)]: + - @wagmi/core@0.10.10 + +## 0.12.11 + +### Patch Changes + +- [#2203](https://github.com/wevm/wagmi/pull/2203) [`a4ca4b05`](https://github.com/wevm/wagmi/commit/a4ca4b05c5bd20c20c5d0741bfb18f2c798b9529) Thanks [@tmm](https://github.com/tmm)! - Downgraded abitype. + +## 0.12.10 + +### Patch Changes + +- [#2143](https://github.com/wevm/wagmi/pull/2143) [`26dc5326`](https://github.com/wevm/wagmi/commit/26dc53260fde1d3278018c0b20a6d48a093d9427) Thanks [@tmm](https://github.com/tmm)! - Exported Sepolia Chain. + +- [#2146](https://github.com/wevm/wagmi/pull/2146) [`21b6842e`](https://github.com/wevm/wagmi/commit/21b6842e8c296a0bbe71ebe0780d898abc4cf4a8) Thanks [@tmm](https://github.com/tmm)! - Bumped references + +- Updated dependencies [[`26dc5326`](https://github.com/wevm/wagmi/commit/26dc53260fde1d3278018c0b20a6d48a093d9427), [`21b6842e`](https://github.com/wevm/wagmi/commit/21b6842e8c296a0bbe71ebe0780d898abc4cf4a8)]: + - @wagmi/core@0.10.9 + +## 0.12.9 + +### Patch Changes + +- [#2120](https://github.com/wevm/wagmi/pull/2120) [`664c2b16`](https://github.com/wevm/wagmi/commit/664c2b1690bdce1ad7a619ac8f673c168dec6529) Thanks [@jxom](https://github.com/jxom)! - Bumped React Query & ABIType dependencies + +## 0.12.8 + +### Patch Changes + +- [#2099](https://github.com/wevm/wagmi/pull/2099) [`f1fee5b3`](https://github.com/wevm/wagmi/commit/f1fee5b30a1bd13b5e66118bf9cdc44b0dc003a1) Thanks [@jxom](https://github.com/jxom)! - Added chains: + + - `nexi` + - `polygonZkEvm` + - `xdc` + - `xdcTestnet` + +- [#2085](https://github.com/wevm/wagmi/pull/2085) [`7d64e3f5`](https://github.com/wevm/wagmi/commit/7d64e3f538a6149777bfa84ea9435769b2a7db58) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where multicall would not throw if the target chain was not configured on the wagmi client. + +- Updated dependencies [[`f1fee5b3`](https://github.com/wevm/wagmi/commit/f1fee5b30a1bd13b5e66118bf9cdc44b0dc003a1), [`7d64e3f5`](https://github.com/wevm/wagmi/commit/7d64e3f538a6149777bfa84ea9435769b2a7db58)]: + - @wagmi/core@0.10.8 + +## 0.12.7 + +### Patch Changes + +- [#2082](https://github.com/wevm/wagmi/pull/2082) [`2ccc8a25`](https://github.com/wevm/wagmi/commit/2ccc8a255e93f0a2bb7b22101656b3905ec59abd) Thanks [@jxom](https://github.com/jxom)! - Updated references. + +- Updated dependencies [[`2ccc8a25`](https://github.com/wevm/wagmi/commit/2ccc8a255e93f0a2bb7b22101656b3905ec59abd)]: + - @wagmi/core@0.10.7 + +## 0.12.6 + +### Patch Changes + +- [#2056](https://github.com/wevm/wagmi/pull/2056) [`944f6513`](https://github.com/wevm/wagmi/commit/944f6513adf09a6f0b3bd34f591d3bbd1f1ffd2e) Thanks [@tmm](https://github.com/tmm)! - Bumped references. + +- Updated dependencies [[`944f6513`](https://github.com/wevm/wagmi/commit/944f6513adf09a6f0b3bd34f591d3bbd1f1ffd2e)]: + - @wagmi/core@0.10.6 + +## 0.12.5 + +### Patch Changes + +- [#2053](https://github.com/wevm/wagmi/pull/2053) [`665df1bf`](https://github.com/wevm/wagmi/commit/665df1bf2afccb533102069def395e19fb7194dd) Thanks [@tmm](https://github.com/tmm)! - Fixed issue where you add a new chain to MetaMask, but the switch after is rejected. + +- Updated dependencies [[`665df1bf`](https://github.com/wevm/wagmi/commit/665df1bf2afccb533102069def395e19fb7194dd)]: + - @wagmi/core@0.10.5 + +## 0.12.4 + +### Patch Changes + +- [#2046](https://github.com/wevm/wagmi/pull/2046) [`90d8e9b8`](https://github.com/wevm/wagmi/commit/90d8e9b87962b72c54311649537e91a953660f9b) Thanks [@tmm](https://github.com/tmm)! - Exported internal type. + +- Updated dependencies [[`90d8e9b8`](https://github.com/wevm/wagmi/commit/90d8e9b87962b72c54311649537e91a953660f9b)]: + - @wagmi/core@0.10.4 + +## 0.12.3 + +### Patch Changes + +- [#2039](https://github.com/wevm/wagmi/pull/2039) [`bac893ab`](https://github.com/wevm/wagmi/commit/bac893ab26012d4d8741c4f80e8b8813aee26f0c) Thanks [@tmm](https://github.com/tmm)! - Updated references. + +- [#2043](https://github.com/wevm/wagmi/pull/2043) [`49a58320`](https://github.com/wevm/wagmi/commit/49a58320ab5f1f13bc4de25abcc028c8335e98f0) Thanks [@tmm](https://github.com/tmm)! - Removed `InjectedConnector` `shimChainChangedDisconnect` shim (no longer necessary). + +- [#2042](https://github.com/wevm/wagmi/pull/2042) [`e7ac7afc`](https://github.com/wevm/wagmi/commit/e7ac7afccb005e8d208c78d55b1fec979b8522a6) Thanks [@tmm](https://github.com/tmm)! - Fixed exposed types that weren't passed down. + +- Updated dependencies [[`bac893ab`](https://github.com/wevm/wagmi/commit/bac893ab26012d4d8741c4f80e8b8813aee26f0c), [`49a58320`](https://github.com/wevm/wagmi/commit/49a58320ab5f1f13bc4de25abcc028c8335e98f0)]: + - @wagmi/core@0.10.3 + +## 0.12.2 + +### Patch Changes + +- [#2016](https://github.com/wevm/wagmi/pull/2016) [`06bf61de`](https://github.com/wevm/wagmi/commit/06bf61dee6d2920777bd9392491e6b7aedebe7ab) Thanks [@jxom](https://github.com/jxom)! - Added chains: + + - `boba` + - `chronos` + - `crossbell` + - `dfk` + - `dogechain` + - `flare` + - `flareTestnet` + - `klaytn` + - `scrollTestnet` + - `shardeumSphinx` + - `skaleCalypso` + - `skaleCalypsoTestnet` + - `skaleChaosTestnet` + - `skaleCryptoBlades` + - `skaleCryptoColosseum` + - `skaleEuropa` + - `skaleEuropaTestnet` + - `skaleExorde` + - `skaleHumanProtocol` + - `skaleNebula` + - `skaleNebulaTestnet` + - `skaleRazor` + - `skaleTitan` + - `skaleTitanTestnet` + - `songbird` + - `songbirdTestnet` + - `titan` + - `titanTestnet` + - `wanchain` + - `wanchainTestnet` + +- [#2016](https://github.com/wevm/wagmi/pull/2016) [`06bf61de`](https://github.com/wevm/wagmi/commit/06bf61dee6d2920777bd9392491e6b7aedebe7ab) Thanks [@jxom](https://github.com/jxom)! - Updated references/ submodule. + +- Updated dependencies [[`06bf61de`](https://github.com/wevm/wagmi/commit/06bf61dee6d2920777bd9392491e6b7aedebe7ab), [`06bf61de`](https://github.com/wevm/wagmi/commit/06bf61dee6d2920777bd9392491e6b7aedebe7ab)]: + - @wagmi/core@0.10.2 + +## 0.12.0 + +### Minor Changes + +- [#1902](https://github.com/wevm/wagmi/pull/1902) [`0994e896`](https://github.com/wevm/wagmi/commit/0994e8966349b8811db0a5886db3831dafc99245) Thanks [@jxom](https://github.com/jxom)! - **Breaking:** Removed the `version` config option for `WalletConnectConnector`. + + `WalletConnectConnector` now uses WalletConnect v2 by default. WalletConnect v1 is now `WalletConnectLegacyConnector`. + + ### WalletConnect v2 + + ```diff + import { WalletConnectConnector } from 'wagmi/connectors/walletConnect' + + const connector = new WalletConnectConnector({ + options: { + - version: '2', + projectId: 'abc', + }, + }) + ``` + + ### WalletConnect v1 + + ```diff + -import { WalletConnectConnector } from 'wagmi/connectors/walletConnect' + +import { WalletConnectConnector } from 'wagmi/connectors/walletConnectLegacy' + + -const connector = new WalletConnectConnector({ + +const connector = new WalletConnectLegacyConnector({ + options: { + qrcode: true, + }, + }) + ``` + +### Patch Changes + +- Updated dependencies [[`0994e896`](https://github.com/wevm/wagmi/commit/0994e8966349b8811db0a5886db3831dafc99245)]: + - @wagmi/core@0.10.0 + +## 0.11.7 + +### Patch Changes + +- [#1907](https://github.com/wevm/wagmi/pull/1907) [`cc4e74ee`](https://github.com/wevm/wagmi/commit/cc4e74ee19665eccb3767052dab6ab956ff4e676) Thanks [@jxom](https://github.com/jxom)! - Added the following chains to the `wagmi/chains` entrypoint: + + - `baseGoerli` + - `harmonyOne` + - `polygonZkEvmTestnet` + +- Updated dependencies [[`cc4e74ee`](https://github.com/wevm/wagmi/commit/cc4e74ee19665eccb3767052dab6ab956ff4e676)]: + - @wagmi/core@0.9.7 + +## 0.11.6 + +### Patch Changes + +- [#1882](https://github.com/wevm/wagmi/pull/1882) [`282cc1b0`](https://github.com/wevm/wagmi/commit/282cc1b02003684d582cea411b11792a59c26fd0) Thanks [@tmm](https://github.com/tmm)! - Updated references. + +- Updated dependencies [[`282cc1b0`](https://github.com/wevm/wagmi/commit/282cc1b02003684d582cea411b11792a59c26fd0)]: + - @wagmi/core@0.9.6 + +## 0.11.5 + +### Patch Changes + +- [#1812](https://github.com/wevm/wagmi/pull/1812) [`c7fd7fbd`](https://github.com/wevm/wagmi/commit/c7fd7fbde6f6c69a3a9a4f89d948c4dfb1d22679) Thanks [@jxom](https://github.com/jxom)! - Added the following chains to the `wagmi/chains` entrypoint: + + - `filecoinCalibration` + - `moonbaseAlpha` + - `moonbeam` + - `moonriver` + +- Updated dependencies [[`c7fd7fbd`](https://github.com/wevm/wagmi/commit/c7fd7fbde6f6c69a3a9a4f89d948c4dfb1d22679)]: + - @wagmi/core@0.9.5 + +## 0.11.4 + +### Patch Changes + +- [#1679](https://github.com/wevm/wagmi/pull/1679) [`3cef111b`](https://github.com/wevm/wagmi/commit/3cef111b1e30120233d8754b33587cdf94aedd8f) Thanks [@aj-may](https://github.com/aj-may)! - Fixed `useAccount` `onConnect` and `onDisconnect` callbacks for React Strict Mode. + +- [#1786](https://github.com/wevm/wagmi/pull/1786) [`b173a431`](https://github.com/wevm/wagmi/commit/b173a43165c7925a4e56ce1e0327a31917e7edc5) Thanks [@tmm](https://github.com/tmm)! - Locked ethers peer dependency version to >=5.5.1 <6 + +- [#1787](https://github.com/wevm/wagmi/pull/1787) [`f023fd8f`](https://github.com/wevm/wagmi/commit/f023fd8f66befb78b9a4df5ca971ceaa64e37ab4) Thanks [@tmm](https://github.com/tmm)! - Added `SafeConnector` + +- Updated dependencies [[`b173a431`](https://github.com/wevm/wagmi/commit/b173a43165c7925a4e56ce1e0327a31917e7edc5), [`f023fd8f`](https://github.com/wevm/wagmi/commit/f023fd8f66befb78b9a4df5ca971ceaa64e37ab4)]: + - @wagmi/core@0.9.4 + +## 0.11.3 + +### Patch Changes + +- [#1773](https://github.com/wevm/wagmi/pull/1773) [`9aaf1955`](https://github.com/wevm/wagmi/commit/9aaf195514d3b5f4d085c797fc5021d42a9efb6c) Thanks [@jxom](https://github.com/jxom)! - Updated `@walletconnect/universal-provider` on `WalletConnectConnector` v2. + Added more signable methods to `WalletConnectConnector` v2. + +- [#1773](https://github.com/wevm/wagmi/pull/1773) [`9aaf1955`](https://github.com/wevm/wagmi/commit/9aaf195514d3b5f4d085c797fc5021d42a9efb6c) Thanks [@jxom](https://github.com/jxom)! - Added Telos to the `wagmi/chains` entrypoint. Thanks @donnyquixotic! + +- Updated dependencies [[`9aaf1955`](https://github.com/wevm/wagmi/commit/9aaf195514d3b5f4d085c797fc5021d42a9efb6c), [`9aaf1955`](https://github.com/wevm/wagmi/commit/9aaf195514d3b5f4d085c797fc5021d42a9efb6c)]: + - @wagmi/core@0.9.3 + +## 0.11.2 + +### Patch Changes + +- [#1756](https://github.com/wevm/wagmi/pull/1756) [`31d06b8c`](https://github.com/wevm/wagmi/commit/31d06b8ce1e7af5e9d1a7ba57f1743b2dff7a53d) Thanks [@jxom](https://github.com/jxom)! - Added OKC Chain. Thanks @clark-cui! + +- [#1756](https://github.com/wevm/wagmi/pull/1756) [`31d06b8c`](https://github.com/wevm/wagmi/commit/31d06b8ce1e7af5e9d1a7ba57f1743b2dff7a53d) Thanks [@jxom](https://github.com/jxom)! - Fixed race condition between `switchNetwork` and mutation Actions that use `chainId` (e.g. `sendTransaction`). Thanks @DanInTheD4rk! + +- Updated dependencies [[`31d06b8c`](https://github.com/wevm/wagmi/commit/31d06b8ce1e7af5e9d1a7ba57f1743b2dff7a53d), [`31d06b8c`](https://github.com/wevm/wagmi/commit/31d06b8ce1e7af5e9d1a7ba57f1743b2dff7a53d)]: + - @wagmi/core@0.9.2 + +## 0.11.1 + +### Patch Changes + +- [#1752](https://github.com/wevm/wagmi/pull/1752) [`144a0e76`](https://github.com/wevm/wagmi/commit/144a0e76ef4bb9ba0650b5ffb9c63f95329819a4) Thanks [@jxom](https://github.com/jxom)! - Improved `WalletConnectConnector` (v2) initialization & updated dependencies. + +- [#1752](https://github.com/wevm/wagmi/pull/1752) [`144a0e76`](https://github.com/wevm/wagmi/commit/144a0e76ef4bb9ba0650b5ffb9c63f95329819a4) Thanks [@jxom](https://github.com/jxom)! - Added the following chains to the `wagmi/chains` entrypoint: + + - Aurora – thanks @salil-naik + - Bronos – thanks @chedetinaveen + - Canto – thanks @tster + - Celo – thanks @aaronmgdr + +- Updated dependencies [[`144a0e76`](https://github.com/wevm/wagmi/commit/144a0e76ef4bb9ba0650b5ffb9c63f95329819a4), [`144a0e76`](https://github.com/wevm/wagmi/commit/144a0e76ef4bb9ba0650b5ffb9c63f95329819a4)]: + - @wagmi/core@0.9.1 + +## 0.11.0 + +### Minor Changes + +- [#1732](https://github.com/wevm/wagmi/pull/1732) [`01e21897`](https://github.com/wevm/wagmi/commit/01e2189747a5c22dc758c6d719b4145adc2a643c) Thanks [@tmm](https://github.com/tmm)! - Bumped minimum TypeScript version to typescript@>=4.9.4. TypeScript 5.0 is coming soon and has some great features we are excited to bring into wagmi. To prepare for this, update your TypeScript version to 4.9.4 or higher. There are likely no [breaking changes](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-9.html#correctness-fixes-and-breaking-changes) if you are coming from typescript@4.7.x || typescript@4.8.x. + +### Patch Changes + +- Updated dependencies [[`01e21897`](https://github.com/wevm/wagmi/commit/01e2189747a5c22dc758c6d719b4145adc2a643c)]: + - @wagmi/core@0.9.0 + +## 0.10.15 + +### Patch Changes + +- [#1718](https://github.com/wevm/wagmi/pull/1718) [`e62b5ef8`](https://github.com/wevm/wagmi/commit/e62b5ef8aaa8063abb5264790768899ea35bbd31) Thanks [@tmm](https://github.com/tmm)! - Updated references + +- Updated dependencies [[`e62b5ef8`](https://github.com/wevm/wagmi/commit/e62b5ef8aaa8063abb5264790768899ea35bbd31)]: + - @wagmi/core@0.8.19 + +## 0.10.14 + +### Patch Changes + +- [#1708](https://github.com/wevm/wagmi/pull/1708) [`07fc3801`](https://github.com/wevm/wagmi/commit/07fc3801fa13c2cb5f7cf9b86ba8320b05a6a135) Thanks [@jxom](https://github.com/jxom)! - Updated `references/` submodule. + +- Updated dependencies [[`07fc3801`](https://github.com/wevm/wagmi/commit/07fc3801fa13c2cb5f7cf9b86ba8320b05a6a135)]: + - @wagmi/core@0.8.18 + +## 0.10.13 + +### Patch Changes + +- [#1705](https://github.com/wevm/wagmi/pull/1705) [`9ff797dc`](https://github.com/wevm/wagmi/commit/9ff797dcb979dc86b798a432b74c98598165430d) Thanks [@jxom](https://github.com/jxom)! - Added the following chains to the `wagmi/chains` entrypoint: + + - `crossbell` (thanks @Songkeys) + - `filecoin` & `filecoinHyperspace` (thanks @neil0x46dc) + - `gnosisChiado` (thanks @theNvN) + - `metis` & `metisGoerli` (thanks @CookedCookee) + +- Updated dependencies [[`9ff797dc`](https://github.com/wevm/wagmi/commit/9ff797dcb979dc86b798a432b74c98598165430d)]: + - @wagmi/core@0.8.17 + +## 0.10.12 + +### Patch Changes + +- [#1699](https://github.com/wevm/wagmi/pull/1699) [`2f1e7950`](https://github.com/wevm/wagmi/commit/2f1e7950e55550d9b50ef5ccb97cb609f4af39b1) Thanks [@tmm](https://github.com/tmm)! - Added public RPC URL property to Chain + +- Updated dependencies [[`2f1e7950`](https://github.com/wevm/wagmi/commit/2f1e7950e55550d9b50ef5ccb97cb609f4af39b1)]: + - @wagmi/core@0.8.16 + +## 0.10.11 + +### Patch Changes + +- [#1685](https://github.com/wevm/wagmi/pull/1685) [`917f5bc1`](https://github.com/wevm/wagmi/commit/917f5bc1fad578e35a8c6ee787e339bfdc156bab) Thanks [@jxom](https://github.com/jxom)! - Replaced qrcodemodal with web3modal for the WalletConnect v2 Connector. + +- Updated dependencies [[`917f5bc1`](https://github.com/wevm/wagmi/commit/917f5bc1fad578e35a8c6ee787e339bfdc156bab)]: + - @wagmi/core@0.8.15 + +## 0.10.10 + +### Patch Changes + +- [#1648](https://github.com/wevm/wagmi/pull/1648) [`a2db9170`](https://github.com/wevm/wagmi/commit/a2db91709720161cd70eeb5e84dd78433264f0a3) Thanks [@tmm](https://github.com/tmm)! - Exported internal type. + +## 0.10.9 + +### Patch Changes + +- [#1646](https://github.com/wevm/wagmi/pull/1646) [`fcdbe353`](https://github.com/wevm/wagmi/commit/fcdbe3531e6d05cda4a4a511bae1ad4c9e426d88) Thanks [@jxom](https://github.com/jxom)! - Upgraded `zustand` to v4.3.1. + +- Updated dependencies [[`fcdbe353`](https://github.com/wevm/wagmi/commit/fcdbe3531e6d05cda4a4a511bae1ad4c9e426d88)]: + - @wagmi/core@0.8.14 + +## 0.10.8 + +### Patch Changes + +- [#1639](https://github.com/wevm/wagmi/pull/1639) [`c6869f06`](https://github.com/wevm/wagmi/commit/c6869f0604fffb197752a08256f31db77f52e746) Thanks [@jxom](https://github.com/jxom)! - Added `isRainbow` flag to `InjectedConnector`. + +- Updated dependencies [[`c6869f06`](https://github.com/wevm/wagmi/commit/c6869f0604fffb197752a08256f31db77f52e746)]: + - @wagmi/core@0.8.13 + +## 0.10.7 + +### Patch Changes + +- [#1636](https://github.com/wevm/wagmi/pull/1636) [`025f6771`](https://github.com/wevm/wagmi/commit/025f6771b32ff7eed22f527be81c5141ddaf9c3d) Thanks [@DanielSinclair](https://github.com/DanielSinclair)! - Added `isRainbow` flag to injected `window.ethereum` types. + +- Updated dependencies [[`025f6771`](https://github.com/wevm/wagmi/commit/025f6771b32ff7eed22f527be81c5141ddaf9c3d)]: + - @wagmi/core@0.8.12 + +## 0.10.6 + +### Patch Changes + +- [#1623](https://github.com/wevm/wagmi/pull/1623) [`c97a4bc5`](https://github.com/wevm/wagmi/commit/c97a4bc5df422dc9a9d3d8bac0261ec6933ce15b) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where `useSigner` would not update on account change. + +## 0.10.5 + +### Patch Changes + +- [#1621](https://github.com/wevm/wagmi/pull/1621) [`5812b590`](https://github.com/wevm/wagmi/commit/5812b5909277bf2862cb57a31d52465b47291410) Thanks [@tmm](https://github.com/tmm)! - Bumped @wagmi/connectors + +- Updated dependencies [[`5812b590`](https://github.com/wevm/wagmi/commit/5812b5909277bf2862cb57a31d52465b47291410)]: + - @wagmi/core@0.8.11 + +## 0.10.4 + +### Patch Changes + +- [#1607](https://github.com/wevm/wagmi/pull/1607) [`49a41357`](https://github.com/wevm/wagmi/commit/49a41357f9ca39479bdf759f5998bc169a91ac87) Thanks [@tmm](https://github.com/tmm)! - Exported hook types. + +## 0.10.3 + +### Patch Changes + +- [#1598](https://github.com/wevm/wagmi/pull/1598) [`fc10ebe6`](https://github.com/wevm/wagmi/commit/fc10ebe659dd5f3b7a8e00581f094652280a779b) Thanks [@jxom](https://github.com/jxom)! - Fixed CJS dependency version range + +- Updated dependencies [[`fc10ebe6`](https://github.com/wevm/wagmi/commit/fc10ebe659dd5f3b7a8e00581f094652280a779b)]: + - @wagmi/core@0.8.10 + +## 0.10.2 + +### Patch Changes + +- [#1593](https://github.com/wevm/wagmi/pull/1593) [`216d555c`](https://github.com/wevm/wagmi/commit/216d555c62bd95c3c7c8f8e20f7269f6c8504610) Thanks [@jxom](https://github.com/jxom)! - Added CJS escape hatch bundle under the "cjs" tag. + +- Updated dependencies [[`216d555c`](https://github.com/wevm/wagmi/commit/216d555c62bd95c3c7c8f8e20f7269f6c8504610)]: + - @wagmi/core@0.8.9 + +## 0.10.1 + +### Patch Changes + +- [#1573](https://github.com/wevm/wagmi/pull/1573) [`ef380d9c`](https://github.com/wevm/wagmi/commit/ef380d9c6d51ae0495b9c35925d2843c75d97fd4) Thanks [@tmm](https://github.com/tmm)! - Updated internal types. + +- Updated dependencies [[`ef380d9c`](https://github.com/wevm/wagmi/commit/ef380d9c6d51ae0495b9c35925d2843c75d97fd4)]: + - @wagmi/core@0.8.8 + +## 0.10.0 + +### Minor Changes + +- [#1470](https://github.com/wevm/wagmi/pull/1470) [`3a1a6c9f`](https://github.com/wevm/wagmi/commit/3a1a6c9fe5db5c360adfd116f9a03a1238b5720c) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The `useSigner` hook now always returns `undefined` when no signer is present. Previously, it returned `null`. + + When no signer is present, the hook will be in an `"idle"` status. + +### Patch Changes + +- [#1470](https://github.com/wevm/wagmi/pull/1470) [`3a1a6c9f`](https://github.com/wevm/wagmi/commit/3a1a6c9fe5db5c360adfd116f9a03a1238b5720c) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where `useSigner` would broadcast to other `useSigner`s unnecessarily. + +- [#1470](https://github.com/wevm/wagmi/pull/1470) [`3a1a6c9f`](https://github.com/wevm/wagmi/commit/3a1a6c9fe5db5c360adfd116f9a03a1238b5720c) Thanks [@jxom](https://github.com/jxom)! - The `WalletConnectConnector` now supports WalletConnect v2. + + It can be enabled by setting `version` to `'2'` and supplying a [WalletConnect Cloud `projectId`](https://cloud.walletconnect.com/sign-in). + +- [#1570](https://github.com/wevm/wagmi/pull/1570) [`216f585b`](https://github.com/wevm/wagmi/commit/216f585be8a9e3a56e3243f49ccd54d655b5a6dd) Thanks [@jxom](https://github.com/jxom)! - Added `useWatchPendingTransactions` + +- Updated dependencies [[`216f585b`](https://github.com/wevm/wagmi/commit/216f585be8a9e3a56e3243f49ccd54d655b5a6dd), [`3a1a6c9f`](https://github.com/wevm/wagmi/commit/3a1a6c9fe5db5c360adfd116f9a03a1238b5720c)]: + - @wagmi/core@0.8.7 + +## 0.9.6 + +### Patch Changes + +- [#1539](https://github.com/wevm/wagmi/pull/1539) [`732da004`](https://github.com/wevm/wagmi/commit/732da0042c7e28091b2e36a484ea8239971306f5) Thanks [@0xFlicker](https://github.com/0xFlicker)! - All Providers (ie. Alchemy, Infura, Public) now use the ENS Registry address on the wagmi `Chain` object (`chain.contracts.ensRegistry`). + +- [#1574](https://github.com/wevm/wagmi/pull/1574) [`ecde3d10`](https://github.com/wevm/wagmi/commit/ecde3d1029ccdf90e2853ba0e9ae4f5f4ebb9c4c) Thanks [@jxom](https://github.com/jxom)! - Added the following chains: + + - `iotex` + - `iotexTestnet` + - `zkSync` + - `zkSyncTestnet` + +- Updated dependencies [[`732da004`](https://github.com/wevm/wagmi/commit/732da0042c7e28091b2e36a484ea8239971306f5), [`ecde3d10`](https://github.com/wevm/wagmi/commit/ecde3d1029ccdf90e2853ba0e9ae4f5f4ebb9c4c)]: + - @wagmi/core@0.8.6 + +## 0.9.5 + +### Patch Changes + +- [#1542](https://github.com/wevm/wagmi/pull/1542) [`731b3b73`](https://github.com/wevm/wagmi/commit/731b3b733c6a093d1693d49de601705b7c730549) Thanks [@jxom](https://github.com/jxom)! - Added the following chains: + + - `evmos` + - `evmosTestnet` + - `gnosis` + +- [#1542](https://github.com/wevm/wagmi/pull/1542) [`731b3b73`](https://github.com/wevm/wagmi/commit/731b3b733c6a093d1693d49de601705b7c730549) Thanks [@jxom](https://github.com/jxom)! - Updated Goerli symbol to `"ETH"`. + +- [#1542](https://github.com/wevm/wagmi/pull/1542) [`731b3b73`](https://github.com/wevm/wagmi/commit/731b3b733c6a093d1693d49de601705b7c730549) Thanks [@jxom](https://github.com/jxom)! - Updated Arbitrum Goerli RPC and Block Explorer. + +- [#1542](https://github.com/wevm/wagmi/pull/1542) [`731b3b73`](https://github.com/wevm/wagmi/commit/731b3b733c6a093d1693d49de601705b7c730549) Thanks [@jxom](https://github.com/jxom)! - Fixed issue where connecting to MetaMask may return with a stale address. + +- [#1542](https://github.com/wevm/wagmi/pull/1542) [`731b3b73`](https://github.com/wevm/wagmi/commit/731b3b733c6a093d1693d49de601705b7c730549) Thanks [@jxom](https://github.com/jxom)! - Removed ENS registry for Sepolia. + +- Updated dependencies [[`731b3b73`](https://github.com/wevm/wagmi/commit/731b3b733c6a093d1693d49de601705b7c730549), [`731b3b73`](https://github.com/wevm/wagmi/commit/731b3b733c6a093d1693d49de601705b7c730549), [`731b3b73`](https://github.com/wevm/wagmi/commit/731b3b733c6a093d1693d49de601705b7c730549), [`731b3b73`](https://github.com/wevm/wagmi/commit/731b3b733c6a093d1693d49de601705b7c730549), [`731b3b73`](https://github.com/wevm/wagmi/commit/731b3b733c6a093d1693d49de601705b7c730549)]: + - @wagmi/core@0.8.5 + +## 0.9.4 + +### Patch Changes + +- [#1508](https://github.com/wevm/wagmi/pull/1508) [`0b50b62f`](https://github.com/wevm/wagmi/commit/0b50b62f7389619e429509a3e337e451e823b059) Thanks [@jxom](https://github.com/jxom)! - Updated `@wagmi/chains` to `0.1.3`. + +- [#1507](https://github.com/wevm/wagmi/pull/1507) [`7a083bcf`](https://github.com/wevm/wagmi/commit/7a083bcf31d671817a4da2f40fb2160a1ba9d7b7) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where `useBlockNumber` would return data when `watch` is enabled and `enabled` is falsy. + +- [#1504](https://github.com/wevm/wagmi/pull/1504) [`11b8b794`](https://github.com/wevm/wagmi/commit/11b8b794fbfd4a2b40f39962e2758e9fbf48cb54) Thanks [@tmm](https://github.com/tmm)! - Converted ethers custom "ACTION_REJECTED" error to standard RPC Error. + +- Updated dependencies [[`0b50b62f`](https://github.com/wevm/wagmi/commit/0b50b62f7389619e429509a3e337e451e823b059), [`11b8b794`](https://github.com/wevm/wagmi/commit/11b8b794fbfd4a2b40f39962e2758e9fbf48cb54)]: + - @wagmi/core@0.8.4 + +## 0.9.3 + +### Patch Changes + +- [#1431](https://github.com/wevm/wagmi/pull/1431) [`af28f8f9`](https://github.com/wevm/wagmi/commit/af28f8f9cfc227e7c391927fdb934183edb5c2dc) Thanks [@jxom](https://github.com/jxom)! - Re-export connectors from `@wagmi/connectors` + +- [#1431](https://github.com/wevm/wagmi/pull/1431) [`af28f8f9`](https://github.com/wevm/wagmi/commit/af28f8f9cfc227e7c391927fdb934183edb5c2dc) Thanks [@jxom](https://github.com/jxom)! - Added `LedgerConnector` connector + +- Updated dependencies [[`af28f8f9`](https://github.com/wevm/wagmi/commit/af28f8f9cfc227e7c391927fdb934183edb5c2dc), [`af28f8f9`](https://github.com/wevm/wagmi/commit/af28f8f9cfc227e7c391927fdb934183edb5c2dc)]: + - @wagmi/core@0.8.3 + +## 0.9.2 + +### Patch Changes + +- [#1442](https://github.com/wevm/wagmi/pull/1442) [`cde15289`](https://github.com/wevm/wagmi/commit/cde152899c758dea10787412b0aef669ed7202b2) Thanks [@0xproflupin](https://github.com/0xproflupin)! - Added Phantom wallet support to `InjectedConnector` + +- [#1448](https://github.com/wevm/wagmi/pull/1448) [`c6075f3a`](https://github.com/wevm/wagmi/commit/c6075f3a16885d850ad2656272351f9517c9f67b) Thanks [@tmm](https://github.com/tmm)! - Updated [ABIType](https://github.com/wevm/abitype) version. + +- [#1444](https://github.com/wevm/wagmi/pull/1444) [`310a8bc4`](https://github.com/wevm/wagmi/commit/310a8bc428ce4e7f68377f581b45dcdd64381cce) Thanks [@jxom](https://github.com/jxom)! - Assert that a `connector` exists before invoking the callback in `watchSigner`. + +- [#1434](https://github.com/wevm/wagmi/pull/1434) [`100e2a3b`](https://github.com/wevm/wagmi/commit/100e2a3b22f4602716554487b1d98738e053be76) Thanks [@tmm](https://github.com/tmm)! - Updated `MockConnector` `chainId` behavior to default to first chain from `chains` if not provided in `options`. + +- Updated dependencies [[`cde15289`](https://github.com/wevm/wagmi/commit/cde152899c758dea10787412b0aef669ed7202b2), [`c6075f3a`](https://github.com/wevm/wagmi/commit/c6075f3a16885d850ad2656272351f9517c9f67b), [`310a8bc4`](https://github.com/wevm/wagmi/commit/310a8bc428ce4e7f68377f581b45dcdd64381cce), [`100e2a3b`](https://github.com/wevm/wagmi/commit/100e2a3b22f4602716554487b1d98738e053be76)]: + - @wagmi/core@0.8.2 + +## 0.9.1 + +### Patch Changes + +- [#1437](https://github.com/wevm/wagmi/pull/1437) [`c34a3dc6`](https://github.com/wevm/wagmi/commit/c34a3dc6396e6473d9f0505fad88ec910f8f5275) Thanks [@jxom](https://github.com/jxom)! - Omitted `"EIP712Domain"` type from `signTypedData` `types` arg since ethers throws an [internal error](https://github.com/ethers-io/ethers.js/blob/c80fcddf50a9023486e9f9acb1848aba4c19f7b6/packages/hash/src.ts/typed-data.ts#L466) if you include it. + +- [#1445](https://github.com/wevm/wagmi/pull/1445) [`51dd53cb`](https://github.com/wevm/wagmi/commit/51dd53cba3fe0f79fa1393270b738194577ddf54) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where the wagmi client wouldn't rehydrate the store in local storage when `autoConnect` is truthy. + +- Updated dependencies [[`c34a3dc6`](https://github.com/wevm/wagmi/commit/c34a3dc6396e6473d9f0505fad88ec910f8f5275), [`51dd53cb`](https://github.com/wevm/wagmi/commit/51dd53cba3fe0f79fa1393270b738194577ddf54)]: + - @wagmi/core@0.8.1 + +## 0.9.0 + +### Minor Changes + +- [#1344](https://github.com/wevm/wagmi/pull/1344) [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: With the introduction of the [`wagmi/chains` entrypoint](/react/chains#wagmichains), `wagmi` no longer exports the following: + + - `chain` + - `allChains` + - `defaultChains` + - `defaultL2Chains` + - `chainId` + - `etherscanBlockExplorers` + - `alchemyRpcUrls`, `infuraRpcUrls`, `publicRpcUrls` + + Read below for migration steps. + + #### Removed `chain` + + The `chain` export has been removed. `wagmi` now only exports the `mainnet` & `goerli` chains. If you need to use an alternative chain (`polygon`, `optimism`, etc), you will need to import it from the [`wagmi/chains` entrypoint](/react/chains#wagmichains). + + ```diff + import { + - chain + configureChains + } from 'wagmi' + + import { mainnet, polygon, optimism } from 'wagmi/chains' + + const { ... } = configureChains( + - [chain.mainnet, chain.polygon, chain.optimism], + + [mainnet, polygon, optimism], + { + ... + } + ) + ``` + + #### Removed `allChains` + + The `allChains` export has been removed. If you need a list of all chains, you can utilize [`wagmi/chains` entrypoint](/react/chains#wagmichains). + + ```diff + - import { allChains } from 'wagmi' + + import * as allChains from 'wagmi/chains' + + const { ... } = configureChains(allChains, ...) + ``` + + #### Removed `defaultChains` & `defaultL2Chains` + + The `defaultChains` & `defaultL2Chains` exports have been removed. If you still need the `defaultChains` or `defaultL2Chains` exports, you can build them yourself: + + ```diff + - import { defaultChains } from 'wagmi' + + import { mainnet, goerli } from 'wagmi/chains' + + + const defaultChains = [mainnet, goerli] + ``` + + > The `defaultChains` export was previously populated with `mainnet` & `goerli`. + + ```diff + - import { defaultL2Chains } from 'wagmi' + + import { + + arbitrum, + + arbitrumGoerli, + + polygon, + + polygonMumbai, + + optimism, + + optimismGoerli + + } from 'wagmi/chains' + + + const defaultL2Chains = [ + + arbitrum, + + arbitrumGoerli, + + polygon, + + polygonMumbai, + + optimism + + optimismGoerli + + ] + ``` + + > The `defaultL2Chains` export was previously populated with `arbitrum` & `optimism`. + + #### Removed `chainId` + + The `chainId` export has been removed. You can extract a chain ID from the chain itself. + + ```diff + - import { chainId } from 'wagmi' + + import { mainnet, polygon, optimism } from 'wagmi/chains' + + -const mainnetChainId = chainId.mainnet + -const polygonChainId = chainId.polygon + -const optimismChainId = chainId.optimism + +const mainnetChainId = mainnet.chainId + +const polygonChainId = polygon.chainId + +const optimismChainId = optimism.chainId + ``` + + #### Removed `etherscanBlockExplorers` + + The `etherscanBlockExplorers` export has been removed. You can extract a block explorer from the chain itself. + + ```diff + - import { etherscanBlockExplorers } from 'wagmi' + + import { mainnet, polygon, optimism } from 'wagmi/chains' + + -const mainnetEtherscanBlockExplorer = etherscanBlockExplorers.mainnet + -const polygonEtherscanBlockExplorer = etherscanBlockExplorers.polygon + -const optimismEtherscanBlockExplorer = etherscanBlockExplorers.optimism + +const mainnetEtherscanBlockExplorer = mainnet.blockExplorer + +const polygonEtherscanBlockExplorer = polygon.blockExplorer + +const optimismEtherscanBlockExplorer = optimism.blockExplorer + ``` + + #### Removed `alchemyRpcUrls`, `infuraRpcUrls` & `publicRpcUrls` + + The `alchemyRpcUrls`, `infuraRpcUrls` & `publicRpcUrls` exports have been removed. You can extract a RPC URL from the chain itself. + + ```diff + - import { alchemyRpcUrls, infuraRpcUrls, publicRpcUrls } from 'wagmi' + + import { mainnet } from 'wagmi/chains' + + -const mainnetAlchemyRpcUrl = alchemyRpcUrls.mainnet + -const mainnetInfuraRpcUrl = infuraRpcUrls.mainnet + -const mainnetOptimismRpcUrl = publicRpcUrls.mainnet + +const mainnetAlchemyRpcUrl = mainnet.rpcUrls.alchemy + +const mainnetInfuraRpcUrl = mainnet.rpcUrls.infura + +const mainnetOptimismRpcUrl = mainnet.rpcUrls.optimism + ``` + +- [#1344](https://github.com/wevm/wagmi/pull/1344) [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: the shape of the `Chain` type has been modified. + + #### RPC URLs + + The `rpcUrls` shape has changed to include an array of URLs, and also the transport method (`http` or `webSocket`): + + ```diff + type Chain = { + ... + rpcUrls: { + - [key: string]: string + + [key: string]: { + + http: string[] + + webSocket: string[] + + } + } + ... + } + ``` + + Note that you will also need to ensure that usage is migrated: + + ```diff + - const rpcUrl = mainnet.rpcUrls.alchemy + + const rpcUrl = mainnet.rpcUrls.alchemy.http[0] + ``` + + #### Contracts + + The `multicall` and `ens` attributes have been moved into the `contracts` object: + + ```diff + type Contract = { + address: Address + blockCreated?: number + } + + type Chain = { + ... + - multicall: Contract + - ens: Contract + + contracts: { + + multicall3: Contract + + ensRegistry: Contract + + } + ... + } + ``` + + Note that you will also need to ensure that usage is migrated: + + ```diff + - const multicallContract = mainnet.multicall + + const multicallContract = mainnet.contracts.multicall3 + ``` + +- [#1344](https://github.com/wevm/wagmi/pull/1344) [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: Removed the `wait` config option on `useWaitForTransaction`. Use the transaction `hash` instead. + + ```diff + const { data } = useWaitForTransaction({ + - wait: transaction.wait + + hash: transaction.hash + }) + ``` + +- [#1344](https://github.com/wevm/wagmi/pull/1344) [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652) Thanks [@jxom](https://github.com/jxom)! - Updated errors to use `cause` instead of `internal` + +- [#1344](https://github.com/wevm/wagmi/pull/1344) [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652) Thanks [@jxom](https://github.com/jxom)! - `useEnsResolver`'s result is no longer persisted by the query client since it cannot serialize its prototype methods. + +- [#1344](https://github.com/wevm/wagmi/pull/1344) [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: Changed `useWaitForTransaction` behavior to return an error if the transaction reverted. + +### Patch Changes + +- [#1344](https://github.com/wevm/wagmi/pull/1344) [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652) Thanks [@jxom](https://github.com/jxom)! - `useWaitForTransaction` now throws an error for cancelled or replaced transactions. + +- [#1344](https://github.com/wevm/wagmi/pull/1344) [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652) Thanks [@jxom](https://github.com/jxom)! - `useWaitForTransaction` now respects repriced (sped up) transactions. + +- [#1344](https://github.com/wevm/wagmi/pull/1344) [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652) Thanks [@jxom](https://github.com/jxom)! - Updated `@coinbase/wallet-sdk` to `^3.6.0`. + +- Updated dependencies [[`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652), [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652), [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652), [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652), [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652), [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652), [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652), [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652), [`57a19374`](https://github.com/wevm/wagmi/commit/57a1937464a4ccf72719fc86c38d1734f6306652)]: + - @wagmi/core@0.8.0 + +## 0.8.10 + +### Patch Changes + +- [#1411](https://github.com/wevm/wagmi/pull/1411) [`659be184`](https://github.com/wevm/wagmi/commit/659be1840c613ce9f7aca9ac96694c4f60da4a66) Thanks [@tmm](https://github.com/tmm)! - Fixed issue where block invalidation was not properly disabled when setting `enabled: false`. + +- [#1409](https://github.com/wevm/wagmi/pull/1409) [`b557b3ee`](https://github.com/wevm/wagmi/commit/b557b3ee4fc58217e61d860fc3d1109d2abc813e) Thanks [@jxom](https://github.com/jxom)! - Ensure that `useSyncExternalStoreWithTracked` rerenders when no values are being tracked. + +- Updated dependencies [[`659be184`](https://github.com/wevm/wagmi/commit/659be1840c613ce9f7aca9ac96694c4f60da4a66)]: + - @wagmi/core@0.7.9 + +## 0.8.9 + +### Patch Changes + +- [#1406](https://github.com/wevm/wagmi/pull/1406) [`4f18c450`](https://github.com/wevm/wagmi/commit/4f18c450a4d7952bfcfa6c533348ffbe55893d3c) Thanks [@tmm](https://github.com/tmm)! - Function for selecting the [EIP-1193](https://eips.ethereum.org/EIPS/eip-1193) Ethereum Provider to target. Defaults to `() => typeof window !== 'undefined' ? window.ethereum : undefined`. + + ```ts + import { InjectedConnector } from "wagmi/connectors/injected"; + + const connector = new InjectedConnector({ + options: { + name: "My Injected Wallet", + getProvider: () => + typeof window !== "undefined" ? window.myInjectedWallet : undefined, + }, + }); + ``` + +- Updated dependencies [[`4f18c450`](https://github.com/wevm/wagmi/commit/4f18c450a4d7952bfcfa6c533348ffbe55893d3c)]: + - @wagmi/core@0.7.8 + +## 0.8.8 + +### Patch Changes + +- [#1386](https://github.com/wevm/wagmi/pull/1386) [`206a2adb`](https://github.com/wevm/wagmi/commit/206a2adbb4ee5149a364543b34612050ccf78c21) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where `persister` would still use `window.localStorage` instead of the wagmi `storage`. + +- [#1376](https://github.com/wevm/wagmi/pull/1376) [`a70a9528`](https://github.com/wevm/wagmi/commit/a70a9528f93f4d7fea28b7652751dfef2dcacf9b) Thanks [@jxom](https://github.com/jxom)! - Fixed issue where `switchChain` on `WalletConnectConnector` would not resolve. + +- [#1392](https://github.com/wevm/wagmi/pull/1392) [`88afc849`](https://github.com/wevm/wagmi/commit/88afc84978afe9689ab7364633e4422ecd7699ea) Thanks [@tmm](https://github.com/tmm)! - Added check for active connector when connecting + +- Updated dependencies [[`206a2adb`](https://github.com/wevm/wagmi/commit/206a2adbb4ee5149a364543b34612050ccf78c21), [`a70a9528`](https://github.com/wevm/wagmi/commit/a70a9528f93f4d7fea28b7652751dfef2dcacf9b), [`206a2adb`](https://github.com/wevm/wagmi/commit/206a2adbb4ee5149a364543b34612050ccf78c21), [`88afc849`](https://github.com/wevm/wagmi/commit/88afc84978afe9689ab7364633e4422ecd7699ea)]: + - @wagmi/core@0.7.7 + +## 0.8.7 + +### Patch Changes + +- [#1384](https://github.com/wevm/wagmi/pull/1384) [`027e88d6`](https://github.com/wevm/wagmi/commit/027e88d6e5f8d028d46ee78aec8500701e0173d9) Thanks [@tmm](https://github.com/tmm)! - Fixed issue reconnecting after disconnect with `MetaMaskConnector` in MetaMask mobile browser. + +- [#1377](https://github.com/wevm/wagmi/pull/1377) [`089c4f3b`](https://github.com/wevm/wagmi/commit/089c4f3b3b8ce5cf7807f144410e2f64b72e0580) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where transforming `useContractRead`, `useContractReads` or `useContractInfiniteReads`'s return data via `select` wasn't inferring the type. + +- Updated dependencies [[`027e88d6`](https://github.com/wevm/wagmi/commit/027e88d6e5f8d028d46ee78aec8500701e0173d9)]: + - @wagmi/core@0.7.6 + +## 0.8.6 + +### Patch Changes + +- [`1169914a`](https://github.com/wevm/wagmi/commit/1169914a0f0ad2810ca1c536b1f1bc6c20f2c1be) Thanks [@jxom](https://github.com/jxom)! - Use `get_accounts` for `getSigner` in InjectedConnector + +- Updated dependencies [[`1169914a`](https://github.com/wevm/wagmi/commit/1169914a0f0ad2810ca1c536b1f1bc6c20f2c1be)]: + - @wagmi/core@0.7.5 + +## 0.8.5 + +### Patch Changes + +- [#1282](https://github.com/wevm/wagmi/pull/1282) [`6d286c9e`](https://github.com/wevm/wagmi/commit/6d286c9ed6f64a9872352904d4d171a6bc1c7a96) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where `useContractRead` would perform an unnecessary rerender if another hook had `watch` enabled. + +## 0.8.4 + +### Patch Changes + +- [#1309](https://github.com/wevm/wagmi/pull/1309) [`1f4a4261`](https://github.com/wevm/wagmi/commit/1f4a4261247b1d3a90e3123157bc851a35d49b9c) Thanks [@tmm](https://github.com/tmm)! - Fixed internal type + +- Updated dependencies [[`1f4a4261`](https://github.com/wevm/wagmi/commit/1f4a4261247b1d3a90e3123157bc851a35d49b9c)]: + - @wagmi/core@0.7.4 + +## 0.8.3 + +### Patch Changes + +- [#1294](https://github.com/wevm/wagmi/pull/1294) [`b2f88949`](https://github.com/wevm/wagmi/commit/b2f88949f32aabaf13f318472648cd51a8b7f2e7) Thanks [@tmm](https://github.com/tmm)! - Set `abi` return type value for `usePrepareContractWrite` as more permissive when not inferrable as `Abi`. + +- Updated dependencies [[`b2f88949`](https://github.com/wevm/wagmi/commit/b2f88949f32aabaf13f318472648cd51a8b7f2e7)]: + - @wagmi/core@0.7.3 + +## 0.8.2 + +### Patch Changes + +- [`e9f806b6`](https://github.com/wevm/wagmi/commit/e9f806b652ba62effb3ddac464815e447fc287f6) Thanks [@tmm](https://github.com/tmm)! - Bumped abitype and zustand versions. + +- [#1290](https://github.com/wevm/wagmi/pull/1290) [`88450052`](https://github.com/wevm/wagmi/commit/88450052b9f070fe53e18d84f72918c410b961f0) Thanks [@tmm](https://github.com/tmm)! - Fixed `useAccount`'s' `onConnect` callback `isReconnected` flag. + +- Updated dependencies [[`e9f806b6`](https://github.com/wevm/wagmi/commit/e9f806b652ba62effb3ddac464815e447fc287f6)]: + - @wagmi/core@0.7.2 + +## 0.8.1 + +### Patch Changes + +- [#1272](https://github.com/wevm/wagmi/pull/1272) [`1f7fc41`](https://github.com/wevm/wagmi/commit/1f7fc419f7960bbdc51dfa85c2f33b89f1ecc1bf) Thanks [@tmm](https://github.com/tmm)! - Fixed ethers import path + +- Updated dependencies [[`1f7fc41`](https://github.com/wevm/wagmi/commit/1f7fc419f7960bbdc51dfa85c2f33b89f1ecc1bf)]: + - @wagmi/core@0.7.1 + +## 0.8.0 + +### Minor Changes + +- [#1202](https://github.com/wevm/wagmi/pull/1202) [`9bf56af`](https://github.com/wevm/wagmi/commit/9bf56af3c30bdb80abb1e785c002e00986fadfb2) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: Removed the following deprecated chains: + + - `ropsten` + - `rinkeby` + - `kovan` + - `optimismKovan` + - `arbitrumRinkeby` + + If you feel you still need to include one of these testnets in your application, you will have to define it manually: + + ```diff + -import { rinkeby } from 'wagmi' + +import { Chain } from 'wagmi' + + +export const rinkeby: Chain = { + + id: 4, + + name: 'Rinkeby', + + network: 'rinkeby', + + nativeCurrency: { name: 'Rinkeby Ether', symbol: 'ETH', decimals: 18 }, + + rpcUrls: { + + alchemy: 'https://eth-rinkeby.alchemyapi.io/v2', + + default: 'https://rpc.ankr.com/eth_rinkeby', + + infura: 'https://rinkeby.infura.io/v3', + + public: 'https://rpc.ankr.com/eth_rinkeby', + + }, + + blockExplorers: { + + etherscan: 'https://rinkeby.etherscan.io', + + default: 'https://rinkeby.etherscan.io', + + }, + + ens: { + + address: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e', + + }, + + multicall: { + + address: '0xca11bde05977b3631167028862be2a173976ca11', + + blockCreated: 10299530, + + }, + + testnet: true, + } + ``` + + You can reference these removed chains [here](https://github.com/wevm/wagmi/blob/389765f7d9af063ab0df07389a2bbfbc10a41060/packages/core/src/constants/chains.ts). + +- [#1202](https://github.com/wevm/wagmi/pull/1202) [`9bf56af`](https://github.com/wevm/wagmi/commit/9bf56af3c30bdb80abb1e785c002e00986fadfb2) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: Made `apiKey` required on `infuraProvider` and `alchemyProvider`. + + ```diff + import { configureChains } from 'wagmi' + + const config = configureChains(defaultChains, [ + - alchemyProvider(), + + alchemyProvider({ apiKey: process.env.ALCHEMY_API_KEY }) + ]) + ``` + + You can find your Alchemy API key from the [Alchemy Dashboard](https://dashboard.alchemyapi.io/), or your Infura API key from the [Infura Dashboard](https://infura.io/login). + +- [#1202](https://github.com/wevm/wagmi/pull/1202) [`9bf56af`](https://github.com/wevm/wagmi/commit/9bf56af3c30bdb80abb1e785c002e00986fadfb2) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: `addressOrName` renamed to `address` for `useBalance` and `useEnsAvatar`. + + ```diff + const result = useBalance({ + - addressOrName: '0x…', + + address: '0x…', + }) + ``` + + If you were using an ENS name instead of an address, you can resolve the name to an address before passing it to the action. + + ```diff + + const { data: address } = useEnsAddress({ name: 'example.eth' }) + const result = useBalance({ + - addressOrName: 'example.eth', + + address, + }) + ``` + +- [#1202](https://github.com/wevm/wagmi/pull/1202) [`9bf56af`](https://github.com/wevm/wagmi/commit/9bf56af3c30bdb80abb1e785c002e00986fadfb2) Thanks [@tmm](https://github.com/tmm)! - Removed CommonJS support + +### Patch Changes + +- Updated dependencies [[`9bf56af`](https://github.com/wevm/wagmi/commit/9bf56af3c30bdb80abb1e785c002e00986fadfb2), [`9bf56af`](https://github.com/wevm/wagmi/commit/9bf56af3c30bdb80abb1e785c002e00986fadfb2), [`9bf56af`](https://github.com/wevm/wagmi/commit/9bf56af3c30bdb80abb1e785c002e00986fadfb2), [`9bf56af`](https://github.com/wevm/wagmi/commit/9bf56af3c30bdb80abb1e785c002e00986fadfb2)]: + - @wagmi/core@0.7.0 + +## 0.7.15 + +### Patch Changes + +- [#1262](https://github.com/wevm/wagmi/pull/1262) [`45e2ca4`](https://github.com/wevm/wagmi/commit/45e2ca4d1f33a7b1165c387d420b8d47f4f66935) Thanks [@tmm](https://github.com/tmm)! - Added default for `structuralSharing` for `useContractRead`, `useContractReads`, and `useContractInfiniteReads`. + +## 0.7.14 + +### Patch Changes + +- [#1260](https://github.com/wevm/wagmi/pull/1260) [`0e12f03`](https://github.com/wevm/wagmi/commit/0e12f0380442bccca9ed18991e783819778032fe) Thanks [@ilmpc](https://github.com/ilmpc)! - Deprecated `isDataEqual` option from and added `structuralSharing` option to `useContractRead`, `useContractReads`, and `useContractInfiniteReads`. + +## 0.7.13 + +### Patch Changes + +- [#1250](https://github.com/wevm/wagmi/pull/1250) [`ce2e0f4`](https://github.com/wevm/wagmi/commit/ce2e0f4a46b8fd1c509ead552012ef4c072a525b) Thanks [@tmm](https://github.com/tmm)! - Added support for Trust Wallet browser extension. + +- Updated dependencies [[`ce2e0f4`](https://github.com/wevm/wagmi/commit/ce2e0f4a46b8fd1c509ead552012ef4c072a525b)]: + - @wagmi/core@0.6.12 + +## 0.7.12 + +### Patch Changes + +- [#1234](https://github.com/wevm/wagmi/pull/1234) [`3ff9303`](https://github.com/wevm/wagmi/commit/3ff930349250f62137cca4ca3b382522882abf8a) Thanks [@tmm](https://github.com/tmm)! - Fixed issue with adding chain to wallet without block explorer URL. + +- Updated dependencies [[`3ff9303`](https://github.com/wevm/wagmi/commit/3ff930349250f62137cca4ca3b382522882abf8a)]: + - @wagmi/core@0.6.11 + +## 0.7.11 + +### Patch Changes + +- [#1232](https://github.com/wevm/wagmi/pull/1232) [`c0ca509`](https://github.com/wevm/wagmi/commit/c0ca509506dcf6d98b058df549dc761c9a5f3d1c) Thanks [@tmm](https://github.com/tmm)! - Added validation to check that chain is configured for connector when accessing `Signer`. + +- Updated dependencies [[`c0ca509`](https://github.com/wevm/wagmi/commit/c0ca509506dcf6d98b058df549dc761c9a5f3d1c)]: + - @wagmi/core@0.6.10 + +## 0.7.10 + +### Patch Changes + +- [#1206](https://github.com/wevm/wagmi/pull/1206) [`15ff089`](https://github.com/wevm/wagmi/commit/15ff0896216abecf5967294ae5aeb26ea7fb480b) Thanks [@jxom](https://github.com/jxom)! - Added `scopeKey` as a configuration option to the Hooks which scope its cache to a given context. Hooks that have identical scope will share the same cache. + +- [#1207](https://github.com/wevm/wagmi/pull/1207) [`c73d463`](https://github.com/wevm/wagmi/commit/c73d463d65c9dbfcfe709187e47323a769589741) Thanks [@lvshaoping007](https://github.com/lvshaoping007)! - Added Kucoin wallet support to `InjectedConnector` + +- Updated dependencies [[`c73d463`](https://github.com/wevm/wagmi/commit/c73d463d65c9dbfcfe709187e47323a769589741)]: + - @wagmi/core@0.6.9 + +## 0.7.9 + +### Patch Changes + +- [#1201](https://github.com/wevm/wagmi/pull/1201) [`9a07efa`](https://github.com/wevm/wagmi/commit/9a07efaa397d3ba03f2edbe527c359f21e22139a) Thanks [@jxom](https://github.com/jxom)! - Fixed issue where non-checksum addresses did not resolve with an ENS name + +- [#1132](https://github.com/wevm/wagmi/pull/1132) [`d41c0d6`](https://github.com/wevm/wagmi/commit/d41c0d650f8c0e54145758685b7604b8909d7ae0) Thanks [@toniocodo](https://github.com/toniocodo)! - Added ERC-4626 ABI + +- Updated dependencies [[`d41c0d6`](https://github.com/wevm/wagmi/commit/d41c0d650f8c0e54145758685b7604b8909d7ae0), [`9a07efa`](https://github.com/wevm/wagmi/commit/9a07efaa397d3ba03f2edbe527c359f21e22139a)]: + - @wagmi/core@0.6.8 + +## 0.7.8 + +### Patch Changes + +- [#1174](https://github.com/wevm/wagmi/pull/1174) [`196a458`](https://github.com/wevm/wagmi/commit/196a458f64141e8a9f39c1b1e1af5937f692cb39) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where `client.chains` (active connector chains) would be populated when there is no active connector (disconnected user). + +- [#1176](https://github.com/wevm/wagmi/pull/1176) [`389765f`](https://github.com/wevm/wagmi/commit/389765f7d9af063ab0df07389a2bbfbc10a41060) Thanks [@jxom](https://github.com/jxom)! - Migrate away from Alchemy RPC URLs in the public RPC URL list + +- Updated dependencies [[`196a458`](https://github.com/wevm/wagmi/commit/196a458f64141e8a9f39c1b1e1af5937f692cb39), [`389765f`](https://github.com/wevm/wagmi/commit/389765f7d9af063ab0df07389a2bbfbc10a41060)]: + - @wagmi/core@0.6.7 + +## 0.7.7 + +### Patch Changes + +- [#1166](https://github.com/wevm/wagmi/pull/1166) [`6fbe910`](https://github.com/wevm/wagmi/commit/6fbe91080b54e33e8543e9638ff5089e749ada3f) Thanks [@jxom](https://github.com/jxom)! - Export the React entrypoint `Client` type instead of `@wagmi/core`'s `Client`. + +- [`81ce9e6`](https://github.com/wevm/wagmi/commit/81ce9e64d85f7d01370324c1a529988a0919894f) Thanks [@jxom](https://github.com/jxom)! - Add `isPortal` to injected MetaMask flags. + +- [`c2c0109`](https://github.com/wevm/wagmi/commit/c2c01096ef4cd0ffadbb49062969c208604c6194) Thanks [@jxom](https://github.com/jxom)! - Add etherscan block explorer to Optimism Goerli + +- Updated dependencies [[`81ce9e6`](https://github.com/wevm/wagmi/commit/81ce9e64d85f7d01370324c1a529988a0919894f), [`c2c0109`](https://github.com/wevm/wagmi/commit/c2c01096ef4cd0ffadbb49062969c208604c6194)]: + - @wagmi/core@0.6.6 + +## 0.7.6 + +### Patch Changes + +- [#1162](https://github.com/wevm/wagmi/pull/1162) [`30335b3`](https://github.com/wevm/wagmi/commit/30335b3199fb425e398e9c492b50c68d5e2ade7e) Thanks [@tmm](https://github.com/tmm)! - Fixed issue where non-indexed event parameter types were set to `null`. + +- [#1162](https://github.com/wevm/wagmi/pull/1162) [`30335b3`](https://github.com/wevm/wagmi/commit/30335b3199fb425e398e9c492b50c68d5e2ade7e) Thanks [@tmm](https://github.com/tmm)! - Fixed issue where `useContractReads` and `useContractInfiniteReads` types were slowing down TypeScript compiler. + +- Updated dependencies [[`30335b3`](https://github.com/wevm/wagmi/commit/30335b3199fb425e398e9c492b50c68d5e2ade7e), [`30335b3`](https://github.com/wevm/wagmi/commit/30335b3199fb425e398e9c492b50c68d5e2ade7e)]: + - @wagmi/core@0.6.5 + +## 0.7.5 + +### Patch Changes + +- [#1103](https://github.com/wevm/wagmi/pull/1103) [`651eda0`](https://github.com/wevm/wagmi/commit/651eda06384bd0955268427f898e9337b2dc5a31) Thanks [@tmm](https://github.com/tmm)! - Bumped `abitype` dependency. + +- Updated dependencies [[`651eda0`](https://github.com/wevm/wagmi/commit/651eda06384bd0955268427f898e9337b2dc5a31)]: + - @wagmi/core@0.6.4 + +## 0.7.4 + +### Patch Changes + +- [#1099](https://github.com/wevm/wagmi/pull/1099) [`748e617`](https://github.com/wevm/wagmi/commit/748e61719ad706acae057be903321ebe0c2e817e) Thanks [@jxom](https://github.com/jxom)! - Added `isFetchedAfterMount` to the return value of hooks. + + The `isFetchedAfterMount` will be truthy if the hook has fetched after the component has been mounted. This value can be utilized to not show the result if it has previously been cached. + +- [#1091](https://github.com/wevm/wagmi/pull/1091) [`a3aaf59`](https://github.com/wevm/wagmi/commit/a3aaf590e8e993017baa9a1ac50ecd63dd287caf) Thanks [@tmm](https://github.com/tmm)! - Fixed `useAccount` `onConnect`/`onDisconnect` from not firing when the account was already connected/disconnected. + +## 0.7.3 + +### Patch Changes + +- [#1086](https://github.com/wevm/wagmi/pull/1086) [`4e28d2a`](https://github.com/wevm/wagmi/commit/4e28d2ad4c2e6b3479b728563040b9529463cbcf) Thanks [@tmm](https://github.com/tmm)! - Exposed module types. + +- Updated dependencies [[`4e28d2a`](https://github.com/wevm/wagmi/commit/4e28d2ad4c2e6b3479b728563040b9529463cbcf)]: + - @wagmi/core@0.6.3 + +## 0.7.2 + +### Patch Changes + +- [#1080](https://github.com/wevm/wagmi/pull/1080) [`3be5e8b`](https://github.com/wevm/wagmi/commit/3be5e8b01e58ed40cc9dab7ef9533c0197cb74d0) Thanks [@tmm](https://github.com/tmm)! - Added `abitype` to `dependencies` so types ship correctly. + +- Updated dependencies [[`3be5e8b`](https://github.com/wevm/wagmi/commit/3be5e8b01e58ed40cc9dab7ef9533c0197cb74d0)]: + - @wagmi/core@0.6.2 + +## 0.7.1 + +### Patch Changes + +- [#1074](https://github.com/wevm/wagmi/pull/1074) [`8db807f`](https://github.com/wevm/wagmi/commit/8db807f16149aa278c2a7db9ee5245431db12173) Thanks [@IljaDaderko](https://github.com/IljaDaderko)! - Exported `EventListener` type + +- Updated dependencies [[`8db807f`](https://github.com/wevm/wagmi/commit/8db807f16149aa278c2a7db9ee5245431db12173)]: + - @wagmi/core@0.6.1 + +## 0.7.0 + +### Minor Changes + +- [#940](https://github.com/wevm/wagmi/pull/940) [`b6cb8f4`](https://github.com/wevm/wagmi/commit/b6cb8f4cd15eb13073bc7e9ecb4bfa2c261c0663) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: `usePrepareContractWrite` now throws when a `chainId` is specified and the end-user is on a different chain id (the wrong network). + + If you wish to defer this check until the click handler is pressed, you can place `chainId` in `useContractWrite` instead: + + ```diff + import { usePrepareContractWrite, useContractWrite } from 'wagmi' + import { optimism } from 'wagmi/chains' + + // ... + + const { config } = usePrepareContractWrite({ + addressOrName: '0xaf0326d92b97df1221759476b072abfd8084f9be', + contractInterface: ['function mint()'], + functionName: 'mint', + }) + const { write } = useContractWrite({ + ...config, + + chainId: optimism.id + }) + + ``` + +- [#940](https://github.com/wevm/wagmi/pull/940) [`b6cb8f4`](https://github.com/wevm/wagmi/commit/b6cb8f4cd15eb13073bc7e9ecb4bfa2c261c0663) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The `usePrepareSendTransaction` hook will now only run when the end-user is connected to their wallet. + + This is to reach parity with `usePrepareContractWrite`. + + If the end-user is not connected, then the `usePrepareSendTransaction` hook will remain idle. + +- [#940](https://github.com/wevm/wagmi/pull/940) [`b6cb8f4`](https://github.com/wevm/wagmi/commit/b6cb8f4cd15eb13073bc7e9ecb4bfa2c261c0663) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: `usePrepareSendTransaction` now throws when a `chainId` is specified and the end-user is on a different chain id (the wrong network). + + If you wish to defer this check until the click handler is pressed, you can place `chainId` in `useContractWrite` instead: + + ```diff + import { usePrepareSendTransaction, useContractWrite } from 'wagmi' + import { optimism } from 'wagmi/chains' + + // ... + + const { config } = usePrepareSendTransaction({ + request: { + to: 'moxey.eth', + value: parseEther('1'), + }, + }) + const { sendTransaction } = useSendTransaction({ + ...config, + + chainId: optimism.id + }) + + ``` + +- [#941](https://github.com/wevm/wagmi/pull/941) [`0c96009`](https://github.com/wevm/wagmi/commit/0c96009398647a515a57f72ef25c32724f7c978c) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: `useContractEvent` no longer accepts a `signerOrProvider` configuration option. + +- [#941](https://github.com/wevm/wagmi/pull/941) [`0c96009`](https://github.com/wevm/wagmi/commit/0c96009398647a515a57f72ef25c32724f7c978c) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: `addressOrName` and `contractInterface` renamed to `address` and `abi` respectively for contract hooks: `useContract`, `useContractEvent`, `useContractRead`, `useContractReads`, `useContractInfiniteReads`, `useContractWrite`, `usePrepareContractWrite`. + + ```diff + import { useContractRead } from 'wagmi' + + const result = useContractRead({ + - addressOrName: '0x…', + + address: '0x…', + - contractInterface: […] as const, + + abi: […] as const, + functionName: 'balanceOf', + args: ['0x…'], + }) + ``` + + If you were using an ENS name instead of an address, you can resolve the name to an address before passing it to the action. + + ```diff + - import { useContractRead } from 'wagmi' + + import { useContractRead, useEnsAddress } from 'wagmi' + + + const { data: address} = useEnsAddress({ name: 'example.eth'}) + const result = useContractRead({ + - addressOrName: 'example.eth', + + address, + abi: […], + functionName: 'balanceOf', + args: ['0x…'], + }) + ``` + +- [#941](https://github.com/wevm/wagmi/pull/941) [`0c96009`](https://github.com/wevm/wagmi/commit/0c96009398647a515a57f72ef25c32724f7c978c) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: Updated TypeScript generics for contract and typed data hooks. + + Adding a [const assertion](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions) to `abi` allows TypeScript to infer `functionName`, `args`, `overrides`, and return types for functions, and `eventName` and `listener` types for events. + + ```diff + import { useContractRead } from 'wagmi' + + const result = useContractRead({ + address: '0x…', + - abi: […], + + abi: […] as const, + functionName: 'balanceOf', // will autocomplete and catch typos + args: ['0x…'], // inferred based on `abi`, `functionName`, `args` + }) + result.data // inferred based on `functionName` + ``` + + This works for the following actions: `useContractRead`, `useContractWrite`, `usePrepareContractWrite`, `useContractReads`, `useContractInfiniteReads`, and `useContractEvent`. + + Adding a [const assertion](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions) to `useSignTypedData`'s config option, `types`, allows TypeScript to infer `value`. + + ```diff + import { useSignTypedData } from 'wagmi' + + const result = useSignTypedData({ + domain: { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', + }, + types: { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + - }, + + } as const, + value: { // `value` is inferred based on `types` + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + }) + ``` + +- [#941](https://github.com/wevm/wagmi/pull/941) [`0c96009`](https://github.com/wevm/wagmi/commit/0c96009398647a515a57f72ef25c32724f7c978c) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: Updated TypeScript version to `typescript@>=4.7.4`. + + `@wagmi/core` can now infer types based on [ABI](https://docs.soliditylang.org/en/v0.8.15/abi-spec.html#json) and [EIP-712](https://eips.ethereum.org/EIPS/eip-712) Typed Data definitions, giving you full end-to-end type-safety from your contracts to your frontend and incredible developer experience (e.g. autocomplete contract function names and catch misspellings, type contract function arguments, etc.). + + For this to work, you must upgrade to `typescript@>=4.7.4`. Why is TypeScript v4.7.4 or greater necessary? TypeScript 4.7.4 introduced the ability to [extend constraints on inferred type variables](https://devblogs.microsoft.com/typescript/announcing-typescript-4-7/#extends-constraints-on-infer-type-variables), which is used extensively to help narrow types for ABIs. Good news! When upgrading TypeScript from 4.6 to 4.7 there are likely no [breaking changes](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-7.html#breaking-changes) for your set up. + +- [#941](https://github.com/wevm/wagmi/pull/941) [`0c96009`](https://github.com/wevm/wagmi/commit/0c96009398647a515a57f72ef25c32724f7c978c) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: Updated `paginatedIndexesConfig` `fn` parameter return type. `fn` now returns an array instead of a single object. + + ```diff + import { BigNumber } from 'ethers' + import { paginatedIndexesConfig, useContractInfiniteReads } from 'wagmi' + + useContractInfiniteReads({ + cacheKey: 'contracts', + ...paginatedIndexesConfig( + - (index) => ({ + + (index) => [{ + ...mlootContractConfig, + functionName: 'tokenURI', + args: [BigNumber.from(index)] as const, + - }), + + }], + { start: 0, perPage: 10, direction: 'increment' }, + ), + }) + ``` + +- [#941](https://github.com/wevm/wagmi/pull/941) [`0c96009`](https://github.com/wevm/wagmi/commit/0c96009398647a515a57f72ef25c32724f7c978c) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: `args` config option must now be an array for the following hooks: `useContractRead`, `useContractWrite`, `usePrepareContractWrite`, `useContractReads`, and `useContractInfiniteReads`. + + ```diff + import { useContractRead } from 'wagmi' + + const { data } = useContractRead({ + address: '0x…', + abi: […], + functionName: 'balanceOf', + - args: '0x…', + + args: ['0x…'], + }) + ``` + +### Patch Changes + +- [#940](https://github.com/wevm/wagmi/pull/940) [`b6cb8f4`](https://github.com/wevm/wagmi/commit/b6cb8f4cd15eb13073bc7e9ecb4bfa2c261c0663) Thanks [@jxom](https://github.com/jxom)! - The `useSigner` hook now accepts an optional `chainId` to use for signer initialization as an argument. + + ```tsx + import { useSigner } from "wagmi"; + import { optimism } from "wagmi/core"; + + // ... + + useSigner({ chainId: optimism.id }); + ``` + +- [#1061](https://github.com/wevm/wagmi/pull/1061) [`a4ffe8b`](https://github.com/wevm/wagmi/commit/a4ffe8b25516d5504685ae94579da4cd8c409329) Thanks [@alecananian](https://github.com/alecananian)! - Added Arbitrum Goerli Arbiscan block explorer + +- [#1050](https://github.com/wevm/wagmi/pull/1050) [`73d4d47`](https://github.com/wevm/wagmi/commit/73d4d47bc679f4f9a1cf46010fe2bf858c9d0b5c) Thanks [@jxom](https://github.com/jxom)! - update dependencies + + - `@coinbase/wallet-sdk@3.5.3` + - `@tanstack/query-sync-storage-persister@4.10.1` + - `@tanstack/react-query@4.10.1` + - `@tanstack/react-query-persist-client@4.10.1` + - `@walletconnect/ethereum-provider@1.8.0` + +- [#1048](https://github.com/wevm/wagmi/pull/1048) [`ed13074`](https://github.com/wevm/wagmi/commit/ed130747c0f28c1d9980a1328883e4000a60455e) Thanks [@Max-3-7](https://github.com/Max-3-7)! - Added support for Avalanche core wallet + +- [#1046](https://github.com/wevm/wagmi/pull/1046) [`ab9ecaa`](https://github.com/wevm/wagmi/commit/ab9ecaa74dfa4324279e167dd7e348319ef7d35d) Thanks [@jxom](https://github.com/jxom)! - make ethers block format validator compatible with Celo + +- Updated dependencies [[`b6cb8f4`](https://github.com/wevm/wagmi/commit/b6cb8f4cd15eb13073bc7e9ecb4bfa2c261c0663), [`b6cb8f4`](https://github.com/wevm/wagmi/commit/b6cb8f4cd15eb13073bc7e9ecb4bfa2c261c0663), [`a4ffe8b`](https://github.com/wevm/wagmi/commit/a4ffe8b25516d5504685ae94579da4cd8c409329), [`b6cb8f4`](https://github.com/wevm/wagmi/commit/b6cb8f4cd15eb13073bc7e9ecb4bfa2c261c0663), [`0c96009`](https://github.com/wevm/wagmi/commit/0c96009398647a515a57f72ef25c32724f7c978c), [`b6cb8f4`](https://github.com/wevm/wagmi/commit/b6cb8f4cd15eb13073bc7e9ecb4bfa2c261c0663), [`ed13074`](https://github.com/wevm/wagmi/commit/ed130747c0f28c1d9980a1328883e4000a60455e), [`b6cb8f4`](https://github.com/wevm/wagmi/commit/b6cb8f4cd15eb13073bc7e9ecb4bfa2c261c0663), [`ab9ecaa`](https://github.com/wevm/wagmi/commit/ab9ecaa74dfa4324279e167dd7e348319ef7d35d), [`0c96009`](https://github.com/wevm/wagmi/commit/0c96009398647a515a57f72ef25c32724f7c978c), [`0c96009`](https://github.com/wevm/wagmi/commit/0c96009398647a515a57f72ef25c32724f7c978c), [`73d4d47`](https://github.com/wevm/wagmi/commit/73d4d47bc679f4f9a1cf46010fe2bf858c9d0b5c), [`0c96009`](https://github.com/wevm/wagmi/commit/0c96009398647a515a57f72ef25c32724f7c978c), [`0c96009`](https://github.com/wevm/wagmi/commit/0c96009398647a515a57f72ef25c32724f7c978c)]: + - @wagmi/core@0.6.0 + +## 0.6.8 + +### Patch Changes + +- [`0b77286b`](https://github.com/wevm/wagmi/commit/0b77286b89cb8603426cf5081872416c291a6531) Thanks [@jxom](https://github.com/jxom)! - Isolate wagmi's React Query `queryClient` instance. + +* [`8cb07462`](https://github.com/wevm/wagmi/commit/8cb07462acc3c5637398d11d2451f8b8e330d553) Thanks [@jxom](https://github.com/jxom)! - Added `chainId` as an argument to `watchBlockNumber`. + +- [`53c1a474`](https://github.com/wevm/wagmi/commit/53c1a4747d03b685e8cfbf55361fc2a56777fb06) Thanks [@tmm](https://github.com/tmm)! - Added missing `decimals` option to `Connector` `watchAsset` + +* [`4d74dd4f`](https://github.com/wevm/wagmi/commit/4d74dd4ff827ba5c43c3546a218f38cee45ea76a) Thanks [@jxom](https://github.com/jxom)! - Support ERC20 contracts that represent strings as bytes32 + +* Updated dependencies [[`8cb07462`](https://github.com/wevm/wagmi/commit/8cb07462acc3c5637398d11d2451f8b8e330d553), [`53c1a474`](https://github.com/wevm/wagmi/commit/53c1a4747d03b685e8cfbf55361fc2a56777fb06), [`4d74dd4f`](https://github.com/wevm/wagmi/commit/4d74dd4ff827ba5c43c3546a218f38cee45ea76a)]: + - @wagmi/core@0.5.8 + +## 0.6.7 + +### Patch Changes + +- [`aa51bc4d`](https://github.com/wevm/wagmi/commit/aa51bc4dc5683bf0178597d2fdb8f2e9d82e7970) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue in `CoinbaseWalletConnector` where the browser extension would unintendedly reset the network when the browser is refreshed. + +* [#955](https://github.com/wevm/wagmi/pull/955) [`e326cd80`](https://github.com/wevm/wagmi/commit/e326cd80fe65267db623eb6c80ccdd75572914cf) Thanks [@0xFlicker](https://github.com/0xFlicker)! - Added Infura RPC URL for Sepolia + +- [`cec14089`](https://github.com/wevm/wagmi/commit/cec14089500c86687226ab272b4c3fcb85ae3d69) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where `useProvider` & `getProvider` were not returning referentially equal providers. + +* [`cec14089`](https://github.com/wevm/wagmi/commit/cec14089500c86687226ab272b4c3fcb85ae3d69) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where the `watch` option was not respecting the neighboring `chainId` option in `useBlockNumber`. + +- [`cec14089`](https://github.com/wevm/wagmi/commit/cec14089500c86687226ab272b4c3fcb85ae3d69) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where block listeners (via `watch`) were firing excessively on L2 chains. + +- Updated dependencies [[`aa51bc4d`](https://github.com/wevm/wagmi/commit/aa51bc4dc5683bf0178597d2fdb8f2e9d82e7970), [`e326cd80`](https://github.com/wevm/wagmi/commit/e326cd80fe65267db623eb6c80ccdd75572914cf), [`cec14089`](https://github.com/wevm/wagmi/commit/cec14089500c86687226ab272b4c3fcb85ae3d69), [`cec14089`](https://github.com/wevm/wagmi/commit/cec14089500c86687226ab272b4c3fcb85ae3d69), [`cec14089`](https://github.com/wevm/wagmi/commit/cec14089500c86687226ab272b4c3fcb85ae3d69)]: + - @wagmi/core@0.5.7 + +## 0.6.6 + +### Patch Changes + +- [#936](https://github.com/wevm/wagmi/pull/936) [`3329d1f`](https://github.com/wevm/wagmi/commit/3329d1f5880431566e14ac1640f48d0975aec4c2) Thanks [@jxom](https://github.com/jxom)! - Added the ability to provide a custom logger to override how logs are broadcasted to the consumer in wagmi. + + A custom logger can be provided to the wagmi client via `logger`. + + ### API + + ```tsx + logger?: { + warn: typeof console.warn | null + } + ``` + + ### Examples + + **Passing in a custom logger** + + You can pass in a function to define your own custom logger. + + ```diff + + import { logWarn } from './logger'; + + const client = createClient({ + ... + + logger: { + + warn: message => logWarn(message) + + } + ... + }) + ``` + + **Disabling a logger** + + You can disable a logger by passing `null` as the value. + + ```diff + const client = createClient({ + ... + + logger: { + + warn: null + + } + ... + }) + ``` + +* [#889](https://github.com/wevm/wagmi/pull/889) [`27788ed`](https://github.com/wevm/wagmi/commit/27788ed989b5dc26849c7945fb91a92e56766018) Thanks [@jxom](https://github.com/jxom)! - Make multicall & readContracts more error robust + +* Updated dependencies [[`3329d1f`](https://github.com/wevm/wagmi/commit/3329d1f5880431566e14ac1640f48d0975aec4c2), [`27788ed`](https://github.com/wevm/wagmi/commit/27788ed989b5dc26849c7945fb91a92e56766018)]: + - @wagmi/core@0.5.6 + +## 0.6.5 + +### Patch Changes + +- [#912](https://github.com/wevm/wagmi/pull/912) [`e529e12`](https://github.com/wevm/wagmi/commit/e529e125c713ed3ef24a59c6bf226fe4deee7ac9) Thanks [@zouhangwithsweet](https://github.com/zouhangwithsweet)! - Added BitKeep to injected flags + +- [#912](https://github.com/wevm/wagmi/pull/910) Thanks [@mytangying](https://github.com/zouhangwithsweet)! - Added MathWallet to injected flags + +- [#904](https://github.com/wevm/wagmi/pull/904) [`c231058`](https://github.com/wevm/wagmi/commit/c23105850f335f8798031e14c7098b7dee8c2975) Thanks [@jxom](https://github.com/jxom)! - Removed `contractInterface` & `signer` from persisted query keys. + +- Updated dependencies [[`e529e12`](https://github.com/wevm/wagmi/commit/e529e125c713ed3ef24a59c6bf226fe4deee7ac9), [`c231058`](https://github.com/wevm/wagmi/commit/c23105850f335f8798031e14c7098b7dee8c2975)]: + - @wagmi/core@0.5.5 + +## 0.6.4 + +### Patch Changes + +- [#852](https://github.com/wevm/wagmi/pull/852) [`c3192d0`](https://github.com/wevm/wagmi/commit/c3192d0663aa332ae9edfd9dd49b333454013ab7) Thanks [@skeithc](https://github.com/skeithc)! - Added support for the Sepolia testnet + +- Updated dependencies [[`c3192d0`](https://github.com/wevm/wagmi/commit/c3192d0663aa332ae9edfd9dd49b333454013ab7)]: + - @wagmi/core@0.5.4 + +## 0.6.3 + +### Patch Changes + +- [#835](https://github.com/wevm/wagmi/pull/835) [`1b85e54`](https://github.com/wevm/wagmi/commit/1b85e54ae654e2564cf5bc2dae6411fe0a25875c) Thanks [@jxom](https://github.com/jxom)! - Update `@coinbase/wallet-sdk` to `3.4.1` + +* [#843](https://github.com/wevm/wagmi/pull/843) [`e77dee6`](https://github.com/wevm/wagmi/commit/e77dee6a606b8aac4279569c54cec8902476fee9) Thanks [@tmm](https://github.com/tmm)! - Fix `MockConnector` entrypoint path + +- [#834](https://github.com/wevm/wagmi/pull/834) [`9655879`](https://github.com/wevm/wagmi/commit/96558793b0319df47aefafa6b7b9c959068d491b) Thanks [@jxom](https://github.com/jxom)! - Update zustand to `4.0.0` + +* [#833](https://github.com/wevm/wagmi/pull/833) [`3ae6d0f`](https://github.com/wevm/wagmi/commit/3ae6d0f5e2d65432024272b43afe68a8f63bb7ea) Thanks [@jxom](https://github.com/jxom)! - Updated `react-query@4.0.0-beta.23` to `@tanstack/react-query@^4.0.10` + +* Updated dependencies [[`1b85e54`](https://github.com/wevm/wagmi/commit/1b85e54ae654e2564cf5bc2dae6411fe0a25875c), [`9655879`](https://github.com/wevm/wagmi/commit/96558793b0319df47aefafa6b7b9c959068d491b)]: + - @wagmi/core@0.5.3 + +## 0.6.2 + +### Patch Changes + +- [#823](https://github.com/wevm/wagmi/pull/823) [`10b8b78`](https://github.com/wevm/wagmi/commit/10b8b78605b7246b2c55b8d69f96663906e5cd20) Thanks [@tmm](https://github.com/tmm)! - Add Optimism Goerli to `chain` lookup. + +- Updated dependencies [[`10b8b78`](https://github.com/wevm/wagmi/commit/10b8b78605b7246b2c55b8d69f96663906e5cd20)]: + - @wagmi/core@0.5.2 + +## 0.6.1 + +### Patch Changes + +- [#767](https://github.com/wevm/wagmi/pull/767) [`e9392f3`](https://github.com/wevm/wagmi/commit/e9392f396e48e928bd9d2522e3ad671c589f08cb) Thanks [@klyap](https://github.com/klyap)! - Add Optimism Goerli chain ahead of [Kovan deprecation](https://dev.optimism.io/kovan-to-goerli). + +* [#817](https://github.com/wevm/wagmi/pull/817) [`7e5cac7`](https://github.com/wevm/wagmi/commit/7e5cac75815dcd8aa563462342a4853fc5207735) Thanks [@alecananian](https://github.com/alecananian)! - Added custom name mapping for 1inch Wallet injected provider + +- [#806](https://github.com/wevm/wagmi/pull/806) [`0b34e56`](https://github.com/wevm/wagmi/commit/0b34e56db97e6dcdb71088e0149b2d55ebc604a5) Thanks [@vmichalik](https://github.com/vmichalik)! - Fix canonical testnet native asset symbols by changing them to ETH + +* [#778](https://github.com/wevm/wagmi/pull/778) [`0892908`](https://github.com/wevm/wagmi/commit/08929084eeeba1a3a55aa098fa9d92a243685ad5) Thanks [@0xcadams](https://github.com/0xcadams)! - Add Arbitrum Goerli chain. + +* Updated dependencies [[`e9392f3`](https://github.com/wevm/wagmi/commit/e9392f396e48e928bd9d2522e3ad671c589f08cb), [`7e5cac7`](https://github.com/wevm/wagmi/commit/7e5cac75815dcd8aa563462342a4853fc5207735), [`0b34e56`](https://github.com/wevm/wagmi/commit/0b34e56db97e6dcdb71088e0149b2d55ebc604a5), [`0892908`](https://github.com/wevm/wagmi/commit/08929084eeeba1a3a55aa098fa9d92a243685ad5)]: + - @wagmi/core@0.5.1 + +## 0.6.0 + +### Minor Changes + +- [#658](https://github.com/wevm/wagmi/pull/658) [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432) Thanks [@jxom](https://github.com/jxom)! - **Breaking:** The `useSendTransaction` hook's `data` now returns an object only consisting of `hash` & `wait`, and not the full [`TransactionResponse`](https://docs.ethers.io/v5/api/providers/types/#providers-TransactionResponse). + + If you require the full `TransactionResponse`, you can use `useTransaction`: + + ```diff + import { useSendTransaction, useTransaction } from 'wagmi' + + const { + data: { + hash, + wait, + - ...transaction + } + } = useSendTransaction(...) + + +const { data: transaction } = useTransaction({ hash }) + ``` + + > Why? The old implementation of `useSendTransaction` created a long-running async task, causing [UX pitfalls](https://wagmi.sh/docs/prepare-hooks#ux-pitfalls-without-prepare-hooks) when invoked in a click handler. + +* [#658](https://github.com/wevm/wagmi/pull/658) [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The configuration passed to the `useSendTransaction` hook now needs to be either: + + - prepared with the `usePrepareSendTransaction` hook **(new)**, or + - recklessly unprepared **(previous functionality)** + + > Why? [Read here](https://wagmi.sh/docs/prepare-hooks) + + ### Prepared usage + + ```diff + import { usePrepareSendTransaction, useSendTransaction } from 'wagmi' + + +const { config } = usePrepareSendTransaction({ + + request: { + + to: 'moxey.eth', + + value: parseEther('1'), + + } + +}) + + const { data } = useSendTransaction({ + - request: { + - to: 'moxey.eth', + - value: parseEther('1') + - } + + ...config + }) + ``` + + ### Recklessly unprepared usage + + If you are not ready to upgrade to `usePrepareSendTransaction`, it is possible to use `useSendTransaction` without preparing the configuration first by passing `mode: 'recklesslyUnprepared'`. + + ```diff + import { useSendTransaction } from 'wagmi' + + const { data } = useSendTransaction({ + + mode: 'recklesslyUnprepared', + request: { + to: 'moxey.eth', + value: parseEther('1'), + } + }) + ``` + +- [#658](https://github.com/wevm/wagmi/pull/658) [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: If a `chainId` is passed to `useContractWrite` or `useSendTransaction`, it will no longer attempt to switch chain before sending the transaction. Instead, it will throw an error if the user is on the wrong chain. + + > Why? Eagerly prompting to switch chain in these actions created a long-running async task that that makes [iOS App Links](https://wagmi.sh/docs/prepare-hooks#ios-app-link-constraints) vulnerable. + +* [#760](https://github.com/wevm/wagmi/pull/760) [`d8af6bf`](https://github.com/wevm/wagmi/commit/d8af6bf50885aec110ae4d64716642453aa27896) Thanks [@tmm](https://github.com/tmm)! - **Breaking:** `alchemyProvider` and `infuraProvider` now use a generic `apiKey` configuration option instead of `alchemyId` and `infuraId`. + + ```diff + import { alchemyProvider } from '@wagmi/core/providers/alchemy' + import { infuraProvider } from '@wagmi/core/providers/infura' + + alchemyProvider({ + - alchemyId: 'yourAlchemyApiKey', + + apiKey: 'yourAlchemyApiKey', + }) + + infuraProvider({ + - infuraId: 'yourInfuraApiKey', + + apiKey: 'yourInfuraApiKey', + }) + ``` + +- [#658](https://github.com/wevm/wagmi/pull/658) [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432) Thanks [@jxom](https://github.com/jxom)! - Added the `usePrepareContractWrite` hook that eagerly fetches the parameters required for sending a contract write transaction such as the gas estimate. + + It returns config to be passed through to `useContractWrite`. + + ```ts + const { config } = usePrepareContractWrite({ + addressOrName: "0xecb504d39723b0be0e3a9aa33d646642d1051ee1", + contractInterface: wagmigotchiABI, + functionName: "feed", + }); + const { write } = useContractWrite(config); + ``` + +* [#658](https://github.com/wevm/wagmi/pull/658) [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432) Thanks [@jxom](https://github.com/jxom)! - **Breaking:** When `useSendTransaction` is in "prepare mode" (used with `usePrepareSendTransaction`), `sendTransaction`/`sendTransactionAsync` will be `undefined` until the configuration has been prepared. Ensure that your usage reflects this. + + ```tsx + const { config } = usePrepareSendTransaction({ ... }) + const { sendTransaction } = useSendTransaction(config) + + + ``` + +- [#658](https://github.com/wevm/wagmi/pull/658) [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432) Thanks [@jxom](https://github.com/jxom)! - Added the `usePrepareSendTransaction` hook that eagerly fetches the parameters required for sending a transaction such as the gas estimate and resolving an ENS address (if required). + + It returns config to be passed through to `useSendTransaction`. + + ```ts + import { usePrepareSendTransaction, useSendTransaction } from "@wagmi/core"; + + const { config } = usePrepareSendTransaction({ + request: { + to: "moxey.eth", + value: parseEther("1"), + }, + }); + const { sendTransaction } = useSendTransaction(config); + ``` + +* [#658](https://github.com/wevm/wagmi/pull/658) [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432) Thanks [@jxom](https://github.com/jxom)! - **Breaking:** The `sendTransaction`/`sendTransactionAsync` configuration object has now been altered to only accept "reckless" configuration. If one or more of these values are set, it can lead to [UX pitfalls](https://wagmi.sh/docs/prepare-hooks#ux-pitfalls-without-prepare-hooks). + + ```diff + + ``` + +- [#727](https://github.com/wevm/wagmi/pull/727) [`ac3b9b8`](https://github.com/wevm/wagmi/commit/ac3b9b87f80cb45b65d003f09d916d7d1427a62e) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: Moved the `pollingInterval` config option from the chain provider config to `configureChains` config. + + ```diff + const { chains, provider } = configureChains( + [chain.mainnet, chain.polygon], + [ + - alchemyProvider({ apiKey, pollingInterval: 5000 }), + - publicProvider({ pollingInterval: 5000 }) + + alchemyProvider({ apiKey }), + + publicProvider() + ], + + { pollingInterval: 5000 } + ) + ``` + +* [#658](https://github.com/wevm/wagmi/pull/658) [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432) Thanks [@jxom](https://github.com/jxom)! - **Breaking:** When `useContractWrite` is in "prepare mode" (used with `usePrepareContractWrite`), `write`/`writeAsync` will be `undefined` until the configuration has been prepared. Ensure that your usage reflects this. + + ```tsx + const { config } = usePrepareContractWrite({ ... }) + const { write } = useContractWrite(config) + + + ``` + +- [#658](https://github.com/wevm/wagmi/pull/658) [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The configuration passed to the `useContractWrite` hook now needs to be either: + + - prepared with the `usePrepareContractWrite` hook **(new)**, or + - recklessly unprepared **(previous functionality)** + + > Why? [Read here](https://wagmi.sh/docs/prepare-hooks) + + ### Prepared usage + + ```diff + import { usePrepareContractWrite, useContractWrite } from 'wagmi' + + +const { config } = usePrepareContractWrite({ + + addressOrName: '0x...', + + contractInterface: wagmiAbi, + + functionName: 'mint', + + args: [tokenId] + +}) + + const { data } = useContractWrite({ + - addressOrName: '0x...', + - contractInterface: wagmiAbi, + - functionName: 'mint', + - args: [tokenId], + + ...config + }) + ``` + + ### Recklessly unprepared usage + + If you are not ready to upgrade to `usePrepareContractWrite`, it is possible to use `useContractWrite` without preparing the configuration first by passing `mode: 'recklesslyUnprepared'`. + + ```diff + import { useContractWrite } from 'wagmi' + + const { data } = useContractWrite({ + + mode: 'recklesslyUnprepared', + addressOrName: '0x...', + contractInterface: wagmiAbi, + functionName: 'mint', + args: [tokenId], + }) + ``` + +### Patch Changes + +- [#733](https://github.com/wevm/wagmi/pull/733) [`6232487`](https://github.com/wevm/wagmi/commit/623248703bc728d539e28bf8a89b8ab22f0a5703) Thanks [@tmm](https://github.com/tmm)! - Add mock connector entrypoint + +* [#762](https://github.com/wevm/wagmi/pull/762) [`ccaeed5`](https://github.com/wevm/wagmi/commit/ccaeed53d731f51879e0cdd5648797a32f7d7a31) Thanks [@jxom](https://github.com/jxom)! - Fix `useContractRead` return value unexpectedly returning null for falsy values + +- [#734](https://github.com/wevm/wagmi/pull/734) [`7c2fa04`](https://github.com/wevm/wagmi/commit/7c2fa04e9b695840d6fa088e1f8d069f3c916551) Thanks [@jxom](https://github.com/jxom)! - Fix issue where `useProvider` & `useWebSocketProvider` would not update when `chainId` config changes + +* [#739](https://github.com/wevm/wagmi/pull/739) [`c2295a5`](https://github.com/wevm/wagmi/commit/c2295a56cc86d02cc6602e2b4557b8ab9a091a3f) Thanks [@tmm](https://github.com/tmm)! - Fix balance formatting for tokens that do not have 18 decimals. + +- [#759](https://github.com/wevm/wagmi/pull/759) [`959953d`](https://github.com/wevm/wagmi/commit/959953d1f5b3e8189bac56de245c62333470d18e) Thanks [@tmm](https://github.com/tmm)! - Added `useTransaction` hook: + + ```ts + import { useTransaction } from "wagmi"; + + const result = useTransaction({ + hash: "0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060", + }); + ``` + +- Updated dependencies [[`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432), [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432), [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432), [`d8af6bf`](https://github.com/wevm/wagmi/commit/d8af6bf50885aec110ae4d64716642453aa27896), [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432), [`c2295a5`](https://github.com/wevm/wagmi/commit/c2295a56cc86d02cc6602e2b4557b8ab9a091a3f), [`ac3b9b8`](https://github.com/wevm/wagmi/commit/ac3b9b87f80cb45b65d003f09d916d7d1427a62e), [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432), [`d70c115`](https://github.com/wevm/wagmi/commit/d70c115131f299fb61f87867b6ac4218e0bcf432), [`959953d`](https://github.com/wevm/wagmi/commit/959953d1f5b3e8189bac56de245c62333470d18e)]: + - @wagmi/core@0.5.0 + +## 0.5.11 + +### Patch Changes + +- [`4c7d123`](https://github.com/wevm/wagmi/commit/4c7d123c8e74f93e770096857eb8c40ce0a47681) Thanks [@jxom](https://github.com/jxom)! - Fix issue where `useProvider` & `useWebSocketProvider` would not update when `chainId` config changes + +## 0.5.10 + +### Patch Changes + +- [#713](https://github.com/tmm/wagmi/pull/713) [`08b0113`](https://github.com/tmm/wagmi/commit/08b0113bef9f32dceab2ecd823b1ee00f9bdc45d) Thanks [@jxom](https://github.com/jxom)! - Fix an issue where the `useContractRead` query function could return `undefined` instead of a serializable `null`. + +* [#725](https://github.com/tmm/wagmi/pull/725) [`b976920`](https://github.com/tmm/wagmi/commit/b97692051d778d7e112872663832c97963a8029a) Thanks [@tmm](https://github.com/tmm)! - Lock `react-query` version + +- [#721](https://github.com/tmm/wagmi/pull/721) [`abea25f`](https://github.com/tmm/wagmi/commit/abea25fd15d81d1ecaec9d3fbd687042ab29b1e6) Thanks [@tmm](https://github.com/tmm)! - Add `name` to `useToken` `data` value. + +- Updated dependencies [[`abea25f`](https://github.com/tmm/wagmi/commit/abea25fd15d81d1ecaec9d3fbd687042ab29b1e6), [`abea25f`](https://github.com/tmm/wagmi/commit/abea25fd15d81d1ecaec9d3fbd687042ab29b1e6)]: + - @wagmi/core@0.4.9 + +## 0.5.9 + +### Patch Changes + +- [#677](https://github.com/tmm/wagmi/pull/677) [`35e4219`](https://github.com/tmm/wagmi/commit/35e42199af9dd346549c1718e144728f55b8d7dd) Thanks [@jxom](https://github.com/jxom)! - Move `parseContractResult` to `@wagmi/core` + +* [#677](https://github.com/tmm/wagmi/pull/677) [`35e4219`](https://github.com/tmm/wagmi/commit/35e42199af9dd346549c1718e144728f55b8d7dd) Thanks [@jxom](https://github.com/jxom)! - Parse tuples correctly in `parseContractResult` + +* Updated dependencies [[`35e4219`](https://github.com/tmm/wagmi/commit/35e42199af9dd346549c1718e144728f55b8d7dd)]: + - @wagmi/core@0.4.7 + +## 0.5.8 + +### Patch Changes + +- [#670](https://github.com/tmm/wagmi/pull/670) [`29a0d21`](https://github.com/tmm/wagmi/commit/29a0d21ee83995559f63542778dfa805f15e7441) Thanks [@tmm](https://github.com/tmm)! - Fix broken release not containing `deepEqual` from `@wagmi/core`. + +- Updated dependencies [[`29a0d21`](https://github.com/tmm/wagmi/commit/29a0d21ee83995559f63542778dfa805f15e7441)]: + - @wagmi/core@0.4.6 + +## 0.5.7 + +### Patch Changes + +- [#659](https://github.com/tmm/wagmi/pull/659) [`be76586`](https://github.com/tmm/wagmi/commit/be76586431238dc5a0970a6f10a3dff9faa8ca2d) Thanks [@jxom](https://github.com/jxom)! - Added an `isDataEqual` config option to `useContractRead`, `useContractReads` & `useContractInfiniteReads` to define whether or not that data has changed. Defaults to `deepEqual`. + +* [#659](https://github.com/tmm/wagmi/pull/659) [`be76586`](https://github.com/tmm/wagmi/commit/be76586431238dc5a0970a6f10a3dff9faa8ca2d) Thanks [@jxom](https://github.com/jxom)! - Added `onBlock` config to `useBlockNumber` + +- [#659](https://github.com/tmm/wagmi/pull/659) [`be76586`](https://github.com/tmm/wagmi/commit/be76586431238dc5a0970a6f10a3dff9faa8ca2d) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue where `useContractRead` & `useContractReads` would return unstable data. + +## 0.5.6 + +### Patch Changes + +- [#654](https://github.com/tmm/wagmi/pull/654) [`e66530b`](https://github.com/tmm/wagmi/commit/e66530bf4881b3533c528f8c5a5f41be0eab0a64) Thanks [@jxom](https://github.com/jxom)! - omit `contractInterface` from `useContractRead` & `useContractReads` query key hash + +* [#654](https://github.com/tmm/wagmi/pull/654) [`e66530b`](https://github.com/tmm/wagmi/commit/e66530bf4881b3533c528f8c5a5f41be0eab0a64) Thanks [@jxom](https://github.com/jxom)! - fix `multicall` returning nullish data for all calls unexpectedly + +* Updated dependencies [[`e66530b`](https://github.com/tmm/wagmi/commit/e66530bf4881b3533c528f8c5a5f41be0eab0a64)]: + - @wagmi/core@0.4.5 + +## 0.5.5 + +### Patch Changes + +- [#629](https://github.com/tmm/wagmi/pull/629) [`199db71`](https://github.com/tmm/wagmi/commit/199db7165eed43d36cb882d373f95e7c49212f23) Thanks [@jxom](https://github.com/jxom)! - Add `wagmi/actions` entrypoint that exports imperative `@wagmi/core` actions + +* [#616](https://github.com/tmm/wagmi/pull/616) [`7a7a17a`](https://github.com/tmm/wagmi/commit/7a7a17a46d4c9e6465cc46a111b5fe8a56109f1b) Thanks [@tmm](https://github.com/tmm)! - Adds `UNSTABLE_shimOnConnectSelectAccount` flag. With this flag and "disconnected" with `shimDisconnect` enabled, the user is prompted to select a different MetaMask account (than the currently connected account) when trying to connect (e.g. `useConnect`/`connect` action). + +* Updated dependencies [[`7a7a17a`](https://github.com/tmm/wagmi/commit/7a7a17a46d4c9e6465cc46a111b5fe8a56109f1b)]: + - @wagmi/core@0.4.4 + +## 0.5.4 + +### Patch Changes + +- [#631](https://github.com/tmm/wagmi/pull/631) [`a780e32`](https://github.com/tmm/wagmi/commit/a780e32e91a0072c795fa0b5a6111302768e2a01) Thanks [@tmm](https://github.com/tmm)! - Fix WalletConnect stale session + +- Updated dependencies [[`a780e32`](https://github.com/tmm/wagmi/commit/a780e32e91a0072c795fa0b5a6111302768e2a01)]: + - @wagmi/core@0.4.3 + +## 0.5.3 + +### Patch Changes + +- [#627](https://github.com/tmm/wagmi/pull/627) [`5985530`](https://github.com/tmm/wagmi/commit/59855301d138313e83a607b3f05053e9f46a78a8) Thanks [@jxom](https://github.com/jxom)! - equalityFn in `useSyncExternalStoreWithTracked` should return truthy when there are no tracked keys. + +## 0.5.2 + +### Patch Changes + +- [#624](https://github.com/tmm/wagmi/pull/624) [`416fa7e`](https://github.com/tmm/wagmi/commit/416fa7ee1f8019ab86e33fb93783ffddecc02c49) Thanks [@jxom](https://github.com/jxom)! - Fix broken `WebSocketProvider` type defs + +- Updated dependencies [[`416fa7e`](https://github.com/tmm/wagmi/commit/416fa7ee1f8019ab86e33fb93783ffddecc02c49)]: + - @wagmi/core@0.4.2 + +## 0.5.1 + +### Patch Changes + +- [#622](https://github.com/tmm/wagmi/pull/622) [`d171581`](https://github.com/tmm/wagmi/commit/d171581464891dd870d97b6232205da0cb152d9b) Thanks [@tmm](https://github.com/tmm)! - Use `domain.chainId` to validate and switch chain before signing in `useSignTypedData`. + +* [#618](https://github.com/tmm/wagmi/pull/618) [`a5138e8`](https://github.com/tmm/wagmi/commit/a5138e82a00e4d9469ad78c97b2d34200d7f1fbe) Thanks [@tmm](https://github.com/tmm)! - Fix adding chains when using MetaMask mobile app, add `publicRpcUrls` constant, and default to public endpoint when adding chain. + +* Updated dependencies [[`d171581`](https://github.com/tmm/wagmi/commit/d171581464891dd870d97b6232205da0cb152d9b), [`a5138e8`](https://github.com/tmm/wagmi/commit/a5138e82a00e4d9469ad78c97b2d34200d7f1fbe)]: + - @wagmi/core@0.4.1 + +## 0.5.0 + +### Minor Changes + +- [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The `useContractWrite` hook parameters have been consolidated into a singular config parameter. + + Before: + + ```tsx + useContractWrite( + { + addressOrName: mlootContractAddress, + contractInterface: mlootABI, + }, + "claim", + ); + ``` + + After: + + ```tsx + useContractWrite({ + addressOrName: mlootContractAddress, + contractInterface: mlootABI, + functionName: "claim", + }); + ``` + +* [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The `useContractEvent` hook parameters have been consolidated into a singular config parameter. + + Before: + + ```tsx + useContractEvent( + { + addressOrName: uniContractAddress, + contractInterface: erc20ABI, + }, + 'Transfer', + listener, + ), + ``` + + After: + + ```tsx + useContractEvent({ + addressOrName: uniContractAddress, + contractInterface: erc20ABI, + eventName: "Transfer", + listener, + }); + ``` + +- [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The `client` prop is now required on `WagmiConfig`. + + ````diff + ```tsx + import { + createClient, + + configureChains, + + defaultChains + } from 'wagmi' + +import { publicProvider } from 'wagmi/providers/public' + + +const { provider, webSocketProvider } = configureChains(defaultChains, [ + + publicProvider(), + +]) + + +const client = createClient({ + + provider, + + webSocketProvider, + +}) + + function App() { + return ( + + + + ) + } + ```` + +* [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The `provider` config option is now required on `createClient`. It is recommended to pass the [`provider` given from `configureChains`](https://wagmi.sh/docs/providers/configuring-chains). + + ```diff + import { + createClient, + + defaultChains, + + configureChains + } from 'wagmi' + +import { publicProvider } from 'wagmi/providers/publicProvider' + + +const { provider } = configureChains(defaultChains, [ + + publicProvider + +]) + + const client = createClient({ + + provider + }) + ``` + + If you previously used an ethers.js Provider, you now need to provide your `chains` on the Provider instance: + + ```diff + import { + createClient, + + defaultChains + } from 'wagmi' + import ethers from 'ethers' + + const client = createClient({ + - provider: getDefaultProvider() + + provider: Object.assign(getDefaultProvider(), { chains: defaultChains }) + }) + ``` + +- [`4f8f3c0`](https://github.com/tmm/wagmi/commit/4f8f3c0d65383bd8bbdfc3f1033adfdb11d80ebb) Thanks [@nachoiacovino](https://github.com/nachoiacovino)! - Use ethereum-lists chains symbols + +* [#582](https://github.com/tmm/wagmi/pull/582) [`b03830a`](https://github.com/tmm/wagmi/commit/b03830a54465215c2526f9509543fe2c978bfe70) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The following changes were made to the `useAccount` return value: + + ### The `data` value is now `address` & `connector` + + ```diff + { + - data?: { + - address: string + - connector: Connector + - } + + address?: string + + connector?: Connector + } + ``` + + ### Global connection status values have been added + + The following global connection status values have been added: + + ```diff + { + + isConnecting: boolean + + isReconnecting: boolean + + isConnected: boolean + + isDisconnected: boolean + + status: 'connecting' | 'reconnecting' | 'connected' | 'disconnected' + } + ``` + + The `useAccount` hook is now aware of any connection event in your application, so now you can use these connection status values to determine if your user is connected, disconnected or connecting to a wallet on a global scope. + + ### `error`, states & `refetch` values have been removed + + Since the `useAccount` hook never dealt with asynchronous data, all of these values were + redundant & unused. + + ```diff + { + - error?: Error + - isIdle: boolean + - isLoading: boolean + - isFetching: boolean + - isSuccess: boolean + - isError: boolean + - isFetched: boolean + - isRefetching: boolean + - refetch: (options: { + - throwOnError: boolean + - cancelRefetch: boolean + - }) => Promise<{ + - address: string + - connector: Connector + - }> + - status: 'idle' | 'error' | 'loading' | 'success' + } + ``` + + ### Summary of changes + + Below is the whole diff of changes to the `useAccount` return value. + + ```diff + { + - data?: { + - address: string + - connector: Connector + - } + + address?: string + + connector?: Connector + - error?: Error + - isIdle: boolean + - isLoading: boolean + - isFetching: boolean + - isSuccess: boolean + - isError: boolean + - isFetched: boolean + - isRefetching: boolean + + isConnecting: boolean + + isReconnecting: boolean + + isConnected: boolean + + isDisconnected: boolean + - refetch: (options: { + - throwOnError: boolean + - cancelRefetch: boolean + - }) => Promise<{ + - address: string + - connector: Connector + - }> + - status: 'idle' | 'error' | 'loading' | 'success' + + status: 'connecting' | 'reconnecting' | 'connected' | 'disconnected' + } + ``` + +- [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4) Thanks [@jxom](https://github.com/jxom)! - **Breaking:** Removed the `chainId` parameter from `connectors` function on `createClient`. + + ```diff + const client = createClient({ + - connectors({ chainId }) { + + connectors() { + ... + } + }) + ``` + + If you previously derived RPC URLs from the `chainId` on `connectors`, you can now remove that logic as `wagmi` now handles RPC URLs internally when used with `configureChains`. + + ```diff + import { + chain, + + configureChains, + createClient + } from 'wagmi'; + + +import { publicProvider } from 'wagmi/providers/public' + + import { CoinbaseWalletConnector } from 'wagmi/connectors/coinbaseWallet' + import { InjectedConnector } from 'wagmi/connectors/injected' + import { MetaMaskConnector } from 'wagmi/connectors/metaMask' + import { WalletConnectConnector } from 'wagmi/connectors/walletConnect' + + +const { chains } = configureChains( + + [chain.mainnet], + + [publicProvider()] + +); + + const client = createClient({ + - connectors({ chainId }) { + - const chain = chains.find((x) => x.id === chainId) ?? defaultChain + - const rpcUrl = chain.rpcUrls.alchemy + - ? `${chain.rpcUrls.alchemy}/${alchemyId}` + - : chain.rpcUrls.default + - return [ + + connectors: [ + new MetaMaskConnector({ chains }), + new CoinbaseWalletConnector({ + chains, + options: { + appName: 'wagmi', + - chainId: chain.id, + - jsonRpcUrl: rpcUrl, + }, + }), + new WalletConnectConnector({ + chains, + options: { + qrcode: true, + - rpc: { [chain.id]: rpcUrl }, + }, + }), + new InjectedConnector({ + chains, + options: { name: 'Injected' }, + }), + ] + - }, + }) + ``` + +* [#596](https://github.com/tmm/wagmi/pull/596) [`a770af7`](https://github.com/tmm/wagmi/commit/a770af7d2cb214b6620d5341115f1e938e1e77ff) Thanks [@tmm](https://github.com/tmm)! - **Breaking**: `TypedDataDomain` and `TypedDataField` types were removed and incorporated into `SignTypedDataArgs`. + +- [#582](https://github.com/tmm/wagmi/pull/582) [`b03830a`](https://github.com/tmm/wagmi/commit/b03830a54465215c2526f9509543fe2c978bfe70) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The following changes were made to the `useAccount` configuration: + + ## `onConnect` has been added + + The `onConnect` callback is invoked when the account connects. + + It provides the connected address & connector, as well as a `isReconnected` flag for if the user reconnected via `autoConnect`. + + ```tsx + const account = useAccount({ + onConnect({ address, connector, isReconnected }) { + console.log("Connected"); + }, + }); + ``` + + ## `onDisconnect` has been added + + The `onDisconnect` callback is invoked when the account disconnected. + + ```tsx + const account = useAccount({ + onDisconnect() { + console.log("Disconnected"); + }, + }); + ``` + + ## `suspense` has been removed + + The `useAccount` hook is a synchronous hook – so `suspense` never worked. + + ```diff + const account = useAccount({ + - suspense: true, + }) + ``` + + ## `onError` has been removed + + The `useAccount` hook never had any error definitions – so `onError` was never invoked. + + ```diff + const account = useAccount({ + - onError(error) { + - console.log('Error', error) + - }, + }) + ``` + + ## `onSettled` has been removed + + The `useAccount` hook is a synchronous hook. `onSettled` was always invoked immediately. + + ```diff + const account = useAccount({ + - onSettled(data) { + - console.log('Settled', data) + - }, + }) + ``` + + If you used `onSettled`, you can move the code beneath the `useAccount` hook: + + ```diff + const account = useAccount({ + - onSettled(data) { + - console.log('Address:', data.address) + - }, + }) + + console.log('Address:', account.address) + ``` + + ## `onSuccess` has been removed + + The `useAccount` hook is a synchronous hook. `onSuccess` was always invoked immediately. + + ```diff + const account = useAccount({ + - onSuccess(data) { + - console.log('Success', data) + - }, + }) + ``` + + If you used `onSuccess`, you can move the code beneath the `useAccount` hook: + + ```diff + const account = useAccount({ + - onSuccess(data) { + - console.log('Address:', data.address) + - }, + }) + + console.log('Address:', account.address) + ``` + +* [#582](https://github.com/tmm/wagmi/pull/582) [`b03830a`](https://github.com/tmm/wagmi/commit/b03830a54465215c2526f9509543fe2c978bfe70) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The following changes were made to the `useConnect` return value: + + ### Connection status flags have been moved + + The `isConnected`, `isConnecting`, `isReconnecting` & `isDisconnected` flags have been moved to the `useAccount` hook. + + ```diff + -import { useConnect } from 'wagmi' + +import { useAccount } from 'wagmi' + + function App() { + const { + isConnected, + isConnecting, + isConnecting, + isDisconnected + - } = useConnect() + + } = useAccount() + } + ``` + + ### New `connect` mutation status flags have been added + + The `isLoading`, `isSuccess` and `isError` flags have been added to `useConnect`. + + These flags represent the **local** async state of `useConnect`. + + ### `activeConnector` has been removed + + The `activeConnector` value has been removed. You can find the active connector on `useAccount`. + + ```diff + -import { useConnect } from 'wagmi' + +import { useAccount } from 'wagmi' + + function App() { + - const { activeConnector } = useConnect() + + const { connector } = useAccount() + } + ``` + +- [#582](https://github.com/tmm/wagmi/pull/582) [`b03830a`](https://github.com/tmm/wagmi/commit/b03830a54465215c2526f9509543fe2c978bfe70) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The following changes were made to the `useConnect` configuration: + + ### `onBeforeConnect` has been renamed + + The `onBeforeConnect` callback has been renamed to `onMutate` + + ### `onConnect` has been renamed + + The `onConnect` callback has been renamed to `onSuccess` + +* [#582](https://github.com/tmm/wagmi/pull/582) [`b03830a`](https://github.com/tmm/wagmi/commit/b03830a54465215c2526f9509543fe2c978bfe70) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The `connector` parameter to `connect` & `connectAsync` now has to be in the config object parameter shape. + + ```diff + import { useConnect } from 'wagmi' + + function App() { + const { connect, connectors } = useConnect() + + return ( + + ) + } + ``` + +- [#582](https://github.com/tmm/wagmi/pull/582) [`b03830a`](https://github.com/tmm/wagmi/commit/b03830a54465215c2526f9509543fe2c978bfe70) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The "switch network" functionality has been moved out of `useNetwork` into a new `useSwitchNetwork` hook. + + The `useNetwork` hook now accepts no configuration and only returns `chain` (renamed from `activeChain`) and `chains`. + + ```diff + import { + useNetwork + + useSwitchNetwork + } from 'wagmi' + + const { + - activeChain + + chain, + chains, + - data, + - error, + - isError, + - isIdle, + - isLoading, + - isSuccess, + - pendingChainId, + - switchNetwork, + - switchNetworkAsync, + - status, + - reset, + -} = useNetwork({ + - chainId: 69, + - onError(error) {}, + - onMutate(args) {}, + - onSettled(data, error) {}, + - onSuccess(data) {} + -}) + +} = useNetwork() + + +const { + + data, + + error, + + isError, + + isIdle, + + isLoading, + + isSuccess, + + pendingChainId, + + switchNetwork, + + switchNetworkAsync, + + status, + + reset, + +} = useSwitchNetwork({ + + chainId: 69, + + onError(error) {}, + + onMutate(args) {}, + + onSettled(data, error) {}, + + onSuccess(data) {} + +}) + ``` + +* [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4) Thanks [@jxom](https://github.com/jxom)! - **Breaking**: The `useContractRead` hook parameters have been consolidated into a singular config parameter. + + Before: + + ```tsx + useContractRead( + { + addressOrName: wagmigotchiContractAddress, + contractInterface: wagmigotchiABI, + }, + "love", + { args: "0x27a69ffba1e939ddcfecc8c7e0f967b872bac65c" }, + ); + ``` + + After: + + ```tsx + useContractRead({ + addressOrName: wagmigotchiContractAddress, + contractInterface: wagmigotchiABI, + functionName: "love", + args: "0x27a69ffba1e939ddcfecc8c7e0f967b872bac65c", + }); + ``` + +### Patch Changes + +- [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4) Thanks [@jxom](https://github.com/jxom)! - Added a `useContractInfiniteReads` hook that provides the ability to call multiple ethers Contract read-only methods with "infinite scrolling" ("fetch more") support. Useful for rendering a dynamic list of contract data. + + [Learn more](https://wagmi.sh/docs/hooks/useContractInfiniteReads) + +* [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4) Thanks [@jxom](https://github.com/jxom)! - Added a `useContractReads` hook that provides the ability to batch up multiple ethers Contract read-only methods. + + [Learn more](https://wagmi.sh/docs/hooks/useContractReads) + +- [#598](https://github.com/tmm/wagmi/pull/598) [`fef26bf`](https://github.com/tmm/wagmi/commit/fef26bf8aef76fc9621e3cd54d4e0ca8f69abb38) Thanks [@markdalgleish](https://github.com/markdalgleish)! - Update `@coinbase/wallet-sdk` to fix errors when connecting with older versions of the Coinbase Wallet extension and mobile app. + +* [#611](https://github.com/tmm/wagmi/pull/611) [`3089c34`](https://github.com/tmm/wagmi/commit/3089c34196d4034acabac031e0a2f7ee63ae30cc) Thanks [@tmm](https://github.com/tmm)! - Added `chainId` config parameter for `useContractWrite` and `useSendTransaction`. + + If `chainId` is provided, the connector will validate that `chainId` is the active chain before sending a transaction (and switch to `chainId` if necessary). + +* Updated dependencies [[`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4), [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4), [`4f8f3c0`](https://github.com/tmm/wagmi/commit/4f8f3c0d65383bd8bbdfc3f1033adfdb11d80ebb), [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4), [`3089c34`](https://github.com/tmm/wagmi/commit/3089c34196d4034acabac031e0a2f7ee63ae30cc), [`a770af7`](https://github.com/tmm/wagmi/commit/a770af7d2cb214b6620d5341115f1e938e1e77ff), [`4f8f3c0`](https://github.com/tmm/wagmi/commit/4f8f3c0d65383bd8bbdfc3f1033adfdb11d80ebb), [`fef26bf`](https://github.com/tmm/wagmi/commit/fef26bf8aef76fc9621e3cd54d4e0ca8f69abb38), [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4), [`3089c34`](https://github.com/tmm/wagmi/commit/3089c34196d4034acabac031e0a2f7ee63ae30cc), [`b03830a`](https://github.com/tmm/wagmi/commit/b03830a54465215c2526f9509543fe2c978bfe70), [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4), [`fc94210`](https://github.com/tmm/wagmi/commit/fc94210b67daa91aa164625dfe189d5b6c2f92d4)]: + - @wagmi/core@0.4.0 + +## 0.4.12 + +### Patch Changes + +- [#570](https://github.com/tmm/wagmi/pull/570) [`0e3fe15`](https://github.com/tmm/wagmi/commit/0e3fe15445377f35d6f4142b49bf1c96bfeb62cd) Thanks [@tmm](https://github.com/tmm)! - adds chain for [Foundry](https://github.com/foundry-rs) + +- Updated dependencies [[`0e3fe15`](https://github.com/tmm/wagmi/commit/0e3fe15445377f35d6f4142b49bf1c96bfeb62cd)]: + - @wagmi/core@0.3.8 + +## 0.4.11 + +### Patch Changes + +- [#566](https://github.com/tmm/wagmi/pull/566) [`8713c00`](https://github.com/tmm/wagmi/commit/8713c00f70fcac3afef4ba183e3c87c6d3cbbf65) Thanks [@jxom](https://github.com/jxom)! - Fixed `parseContractResult` breaking `useContractRead` for more complex contract types + +## 0.4.10 + +### Patch Changes + +- [`20a1ab7`](https://github.com/tmm/wagmi/commit/20a1ab7bd02a24c4f1ea02be1bc3ecfbe4abc584) Thanks [@jxom](https://github.com/jxom)! - Updated to `react-query@4.0.0-beta.23` + +* [`20a1ab7`](https://github.com/tmm/wagmi/commit/20a1ab7bd02a24c4f1ea02be1bc3ecfbe4abc584) Thanks [@jxom](https://github.com/jxom)! - Fixed an issue in `useContractRead` where contract structs wouldn't be parsed back to an ethers `Result` correctly. + +## 0.4.9 + +### Patch Changes + +- [#555](https://github.com/tmm/wagmi/pull/555) [`8bf014d`](https://github.com/tmm/wagmi/commit/8bf014d8167e9f9feb1fd91488aab42dd51c92af) Thanks [@tmm](https://github.com/tmm)! - wire up `useEnsName` `chainId` + +## 0.4.8 + +### Patch Changes + +- [#550](https://github.com/tmm/wagmi/pull/550) [`2a5313e`](https://github.com/tmm/wagmi/commit/2a5313e8cbc9ba6335e8e4b85e43862c9b711bd3) Thanks [@tmm](https://github.com/tmm)! - fix `CoinbaseWalletConnector` possible type error + +* [#548](https://github.com/tmm/wagmi/pull/548) [`0c48719`](https://github.com/tmm/wagmi/commit/0c487199f2421f042abc1f1d139468ccbbc5646a) Thanks [@dohaki](https://github.com/dohaki)! - add ensAddress to Chain type + +- [#549](https://github.com/tmm/wagmi/pull/549) [`89b3a74`](https://github.com/tmm/wagmi/commit/89b3a74ead4234daacd0dcf8506659887ebf0553) Thanks [@tmm](https://github.com/tmm)! - Turns on [`noUncheckedIndexedAccess`](https://www.typescriptlang.org/tsconfig#noUncheckedIndexedAccess=) and [`strictNullChecks`](https://www.typescriptlang.org/tsconfig#strictNullChecks=) for better runtime safety. + +- Updated dependencies [[`2a5313e`](https://github.com/tmm/wagmi/commit/2a5313e8cbc9ba6335e8e4b85e43862c9b711bd3), [`0c48719`](https://github.com/tmm/wagmi/commit/0c487199f2421f042abc1f1d139468ccbbc5646a), [`89b3a74`](https://github.com/tmm/wagmi/commit/89b3a74ead4234daacd0dcf8506659887ebf0553)]: + - @wagmi/core@0.3.7 + +## 0.4.7 + +### Patch Changes + +- [#526](https://github.com/tmm/wagmi/pull/526) [`e95c5f9`](https://github.com/tmm/wagmi/commit/e95c5f91859e57d079b962a72d06b93dce004d2f) Thanks [@jxom](https://github.com/jxom)! - Added `shimChainChangedDisconnect` option to `InjectedConnector`. Defaults to `true` for `MetaMaskConnector`. + +* [#526](https://github.com/tmm/wagmi/pull/526) [`e95c5f9`](https://github.com/tmm/wagmi/commit/e95c5f91859e57d079b962a72d06b93dce004d2f) Thanks [@jxom](https://github.com/jxom)! - Added `chainId` config option to `useConnect()` & `connect()`. Consumers can now pick what chain they want their user to be connected to. + + Examples: + + ```tsx + import { useConnect, chain } from "wagmi"; + import { InjectedConnector } from "wagmi/connectors/injected"; + + function App() { + const connect = useConnect({ + chainId: chain.polygon.id, + }); + } + ``` + + ```tsx + import { useConnect, chain } from "wagmi"; + import { InjectedConnector } from "wagmi/connectors/injected"; + + function App() { + const connect = useConnect(); + + return ( + + ); + } + ``` + +* Updated dependencies [[`e95c5f9`](https://github.com/tmm/wagmi/commit/e95c5f91859e57d079b962a72d06b93dce004d2f), [`e95c5f9`](https://github.com/tmm/wagmi/commit/e95c5f91859e57d079b962a72d06b93dce004d2f), [`e95c5f9`](https://github.com/tmm/wagmi/commit/e95c5f91859e57d079b962a72d06b93dce004d2f)]: + - @wagmi/core@0.3.6 + +## 0.4.6 + +### Patch Changes + +- [#543](https://github.com/tmm/wagmi/pull/543) [`4d489fd`](https://github.com/tmm/wagmi/commit/4d489fd630dd8c00440bdaf4d646de662c41ff52) Thanks [@tmm](https://github.com/tmm)! - fix fee data formatting for null values + +- Updated dependencies [[`4d489fd`](https://github.com/tmm/wagmi/commit/4d489fd630dd8c00440bdaf4d646de662c41ff52)]: + - @wagmi/core@0.3.5 + +## 0.4.5 + +### Patch Changes + +- [`01cc47b`](https://github.com/tmm/wagmi/commit/01cc47b2385c78d82bc799c2dedacb2a42457e2f) Thanks [@jxom](https://github.com/jxom)! - Update `react-query` to `4.0.0-beta.19` + +## 0.4.4 + +### Patch Changes + +- [`c4deb66`](https://github.com/tmm/wagmi/commit/c4deb6655a52e4cc4e5b3fd82202db11d6106848) Thanks [@jxom](https://github.com/jxom)! - infer `options.chainId` config from `chains` on WalletConnectConnector + +- Updated dependencies [[`c4deb66`](https://github.com/tmm/wagmi/commit/c4deb6655a52e4cc4e5b3fd82202db11d6106848)]: + - @wagmi/core@0.3.4 + +## 0.4.3 + +### Patch Changes + +- [#486](https://github.com/tmm/wagmi/pull/486) [`dbfe3dd`](https://github.com/tmm/wagmi/commit/dbfe3dd320d178d6854a8096101200c1508786bb) Thanks [@tmm](https://github.com/tmm)! - add chains entrypoint + +- Updated dependencies [[`dbfe3dd`](https://github.com/tmm/wagmi/commit/dbfe3dd320d178d6854a8096101200c1508786bb)]: + - @wagmi/core@0.3.3 + +## 0.4.2 + +### Patch Changes + +- [`b1a2e58`](https://github.com/tmm/wagmi/commit/b1a2e5830e325be448bf865aeccda60217fc8d75) Thanks [@jxom](https://github.com/jxom)! - Made the `defaultChains` type generic in `configureChains`. + +## 0.4.1 + +### Patch Changes + +- [#484](https://github.com/tmm/wagmi/pull/484) [`1b9a503`](https://github.com/tmm/wagmi/commit/1b9a5033d51c6655b4f6570c490da6e0e9a29da9) Thanks [@tmm](https://github.com/tmm)! - export React Context + +- Updated dependencies [[`1b9a503`](https://github.com/tmm/wagmi/commit/1b9a5033d51c6655b4f6570c490da6e0e9a29da9)]: + - @wagmi/core@0.3.1 + +## 0.4.0 + +### Minor Changes + +- [#468](https://github.com/tmm/wagmi/pull/468) [`44a884b`](https://github.com/tmm/wagmi/commit/44a884b84171c418f57701e80ef8de972948ef0b) Thanks [@tmm](https://github.com/tmm)! - **Breaking:** Duplicate exports with different names and the same functionality were removed to simplify the public API. In addition, confusing exports were renamed to be more descriptive. + + - `createWagmiClient` alias was removed. Use `createClient` instead. + - `useWagmiClient` alias was removed. Use `useClient` instead. + - `WagmiClient` alias was removed. Use `Client` instead. + - `createWagmiStorage` alias was removed. Use `createStorage` instead. + - `Provider` was renamed and `WagmiProvider` alias was removed. Use `WagmiConfig` instead. + +* [#408](https://github.com/tmm/wagmi/pull/408) [`bfcc3a5`](https://github.com/tmm/wagmi/commit/bfcc3a51bbb1551753e3ccde6af134e9fd4fec9a) Thanks [@jxom](https://github.com/jxom)! - Add `configureChains` API. + + The `configureChains` function allows you to configure your chains with a selected provider (Alchemy, Infura, JSON RPC, Public RPC URLs). This means you don't have to worry about deriving your own RPC URLs for each chain, or instantiating a Ethereum Provider. + + `configureChains` accepts 3 parameters: an array of chains, and an array of providers, and a config object. + + [Learn more about configuring chains & providers.](https://wagmi.sh/docs/providers/configuring-chains) + + ### Before + + ```tsx + import { providers } from "ethers"; + import { chain, createClient, defaultChains } from "wagmi"; + import { CoinbaseWalletConnector } from "wagmi/connectors/coinbaseWallet"; + import { InjectedConnector } from "wagmi/connectors/injected"; + import { MetaMaskConnector } from "wagmi/connectors/metaMask"; + import { WalletConnectConnector } from "wagmi/connectors/walletConnect"; + + const alchemyId = process.env.ALCHEMY_ID; + + const chains = defaultChains; + const defaultChain = chain.mainnet; + + const client = createClient({ + autoConnect: true, + connectors({ chainId }) { + const chain = chains.find((x) => x.id === chainId) ?? defaultChain; + const rpcUrl = chain.rpcUrls.alchemy + ? `${chain.rpcUrls.alchemy}/${alchemyId}` + : chain.rpcUrls.default; + return [ + new MetaMaskConnector({ chains }), + new CoinbaseWalletConnector({ + chains, + options: { + appName: "wagmi", + chainId: chain.id, + jsonRpcUrl: rpcUrl, + }, + }), + new WalletConnectConnector({ + chains, + options: { + qrcode: true, + rpc: { [chain.id]: rpcUrl }, + }, + }), + new InjectedConnector({ + chains, + options: { + name: "Injected", + shimDisconnect: true, + }, + }), + ]; + }, + provider: ({ chainId }) => + new providers.AlchemyProvider(chainId, alchemyId), + }); + ``` + + ### After + + ```tsx + import { chain, createClient, defaultChains } from "wagmi"; + + import { alchemyProvider } from "wagmi/providers/alchemy"; + import { publicProvider } from "wagmi/providers/public"; + + import { CoinbaseWalletConnector } from "wagmi/connectors/coinbaseWallet"; + import { InjectedConnector } from "wagmi/connectors/injected"; + import { MetaMaskConnector } from "wagmi/connectors/metaMask"; + import { WalletConnectConnector } from "wagmi/connectors/walletConnect"; + + const alchemyId = process.env.ALCHEMY_ID; + + const { chains, provider, webSocketProvider } = configureChains( + defaultChains, + [alchemyProvider({ alchemyId }), publicProvider()], + ); + + const client = createClient({ + autoConnect: true, + connectors: [ + new MetaMaskConnector({ chains }), + new CoinbaseWalletConnector({ + chains, + options: { + appName: "wagmi", + }, + }), + new WalletConnectConnector({ + chains, + options: { + qrcode: true, + }, + }), + new InjectedConnector({ + chains, + options: { + name: "Injected", + shimDisconnect: true, + }, + }), + ], + provider, + webSocketProvider, + }); + ``` + +### Patch Changes + +- [#404](https://github.com/tmm/wagmi/pull/404) [`f81c156`](https://github.com/tmm/wagmi/commit/f81c15665e2e71534f84ada3fa705f2d78627472) Thanks [@holic](https://github.com/holic)! - Add `ProviderRpcError` and `RpcError` error classes. + + Certain wagmi-standardized errors may wrap `ProviderRpcError` or `RpcError`. For these cases, you can access the original provider rpc or rpc error value using the `internal` property. + +* [#459](https://github.com/tmm/wagmi/pull/459) [`72dcf7c`](https://github.com/tmm/wagmi/commit/72dcf7c09e814261b2e43a8fa364c57675c472de) Thanks [@tmm](https://github.com/tmm)! - update dependencies + +- [#447](https://github.com/tmm/wagmi/pull/447) [`b9ebf78`](https://github.com/tmm/wagmi/commit/b9ebf782e0900725bcb76483686b30f09d357ebd) Thanks [@tmm](https://github.com/tmm)! - Fix case where connector disconnected while app was closed and stale data was returned when autoconnecting. For example, [MetaMask was locked](https://github.com/tmm/wagmi/issues/444) when page was closed. + +- Updated dependencies [[`f81c156`](https://github.com/tmm/wagmi/commit/f81c15665e2e71534f84ada3fa705f2d78627472), [`bfcc3a5`](https://github.com/tmm/wagmi/commit/bfcc3a51bbb1551753e3ccde6af134e9fd4fec9a), [`44a884b`](https://github.com/tmm/wagmi/commit/44a884b84171c418f57701e80ef8de972948ef0b), [`72dcf7c`](https://github.com/tmm/wagmi/commit/72dcf7c09e814261b2e43a8fa364c57675c472de), [`a54f3e2`](https://github.com/tmm/wagmi/commit/a54f3e23ea385ed8aa4ad188128d7089ba20f83e), [`b9ebf78`](https://github.com/tmm/wagmi/commit/b9ebf782e0900725bcb76483686b30f09d357ebd), [`bfcc3a5`](https://github.com/tmm/wagmi/commit/bfcc3a51bbb1551753e3ccde6af134e9fd4fec9a)]: + - @wagmi/core@0.3.0 + +## 0.3.5 + +### Patch Changes + +- [`4e03666`](https://github.com/tmm/wagmi/commit/4e03666428d42fc9186c617001b5eb356229677e) Thanks [@tmm](https://github.com/tmm)! - bump dependencies #429 + add imToken support for WC switch chains #432 + fix MetaMask and Brave Wallet collision #436 +- Updated dependencies [[`4e03666`](https://github.com/tmm/wagmi/commit/4e03666428d42fc9186c617001b5eb356229677e)]: + - @wagmi/core@0.2.5 + +## 0.3.4 + +### Patch Changes + +- [#421](https://github.com/tmm/wagmi/pull/421) [`a232b3f`](https://github.com/tmm/wagmi/commit/a232b3ff5cc41e882c4d2a34c599a8cb670edd2b) Thanks [@tmm](https://github.com/tmm)! - fix erc721 abi + +- Updated dependencies [[`a232b3f`](https://github.com/tmm/wagmi/commit/a232b3ff5cc41e882c4d2a34c599a8cb670edd2b)]: + - @wagmi/core@0.2.4 + +## 0.3.3 + +### Patch Changes + +- [#412](https://github.com/tmm/wagmi/pull/412) [`80bef4f`](https://github.com/tmm/wagmi/commit/80bef4ff3f714b0b8f896f1b4b658acc7266299b) Thanks [@markdalgleish](https://github.com/markdalgleish)! - Import providers from `ethers` peer dependency rather than `@ethersproject/providers` to avoid multiple conflicting versions being installed + +- Updated dependencies [[`80bef4f`](https://github.com/tmm/wagmi/commit/80bef4ff3f714b0b8f896f1b4b658acc7266299b)]: + - @wagmi/core@0.2.3 + +## 0.3.2 + +### Patch Changes + +- [`018c2a1`](https://github.com/tmm/wagmi/commit/018c2a11b22ee513571cc7f83fd63f7eb169ee70) Thanks [@tmm](https://github.com/tmm)! - - warn and fallback to default client #380 + + - remove signerOrProvider option from read contract #390 + + - MetaMaskConnector #391 + +- Updated dependencies [[`018c2a1`](https://github.com/tmm/wagmi/commit/018c2a11b22ee513571cc7f83fd63f7eb169ee70)]: + - @wagmi/core@0.2.2 + +## 0.3.1 + +### Patch Changes + +- [`afc4607`](https://github.com/tmm/wagmi/commit/afc46071e91601ab8a2b465524da796cd60b6ad4) Thanks [@tmm](https://github.com/tmm)! - - Fix time scaling e9593df + - Use fully-specified path for use-sync-external-store import 7b235c1 + - Update serialize 236fc17 +- Updated dependencies [[`afc4607`](https://github.com/tmm/wagmi/commit/afc46071e91601ab8a2b465524da796cd60b6ad4)]: + - @wagmi/core@0.2.1 + +## 0.3.0 + +### Minor Changes + +- [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - don't persist account data when `autoConnect` is falsy + +* [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - - fix(@wagmi/core): persist connector chains to local storage + +- [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - - Favour `message` event over `connecting` event to conform to EIP-1193 + - Export `useWaitForTransaction` + +* [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - force address to be required in `useAccount` + +- [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - Initial 0.3.0 release + +* [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - Add `cacheOnBlock` config for `useContractRead` + Update `react-query` to v4 + Fix `watchBlockNumber` listener leak + +- [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - - fix `useContractWrite` mutation fn arguments + +* [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - Update react-query to 4.0.0-beta.5 + +### Patch Changes + +- [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - add chainId to actions and hooks + +* [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - showtime + +- [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - improve type support for ethers providers + +* [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - update zustand + +- [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - update babel target + +* [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - update block explorers and rpc urls structure + +- [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - keep previous data when watching + +* [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - republish + +- [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - fix stale connectors when switching chains + +* [#311](https://github.com/tmm/wagmi/pull/311) [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d) Thanks [@tmm](https://github.com/tmm)! - last beta + +* Updated dependencies [[`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d), [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d), [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d), [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d), [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d), [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d), [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d), [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d), [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d), [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d), [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d), [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d), [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d), [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d), [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d), [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d), [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d), [`24ce011`](https://github.com/tmm/wagmi/commit/24ce0113022b890e9582c6cc24035926e0d2b32d)]: + - @wagmi/core@0.2.0 + +## 0.3.0-next.21 + +### Patch Changes + +- showtime + +- Updated dependencies []: + - @wagmi/core@0.2.0-next.18 + +## 0.3.0-next.20 + +### Patch Changes + +- update block explorers and rpc urls structure + +- Updated dependencies []: + - @wagmi/core@0.2.0-next.17 + +## 0.3.0-next.19 + +### Minor Changes + +- Update react-query to 4.0.0-beta.5 + +## 0.3.0-next.18 + +### Patch Changes + +- last beta + +- Updated dependencies []: + - @wagmi/core@0.2.0-next.16 + +## 0.3.0-next.17 + +### Patch Changes + +- update zustand + +- Updated dependencies []: + - @wagmi/core@0.2.0-next.15 + +## 0.3.0-next.16 + +### Minor Changes + +- Add `cacheOnBlock` config for `useContractRead` +- Update `react-query` to v4 +- Fix `watchBlockNumber` listener leak + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@0.2.0-next.14 + +## 0.3.0-next.15 + +### Patch Changes + +- keep previous data when watching + +- Updated dependencies []: + - @wagmi/core@0.2.0-next.13 + +## 0.3.0-next.14 + +### Patch Changes + +- add chainId to actions and hooks + +- Updated dependencies []: + - @wagmi/core@0.2.0-next.12 + +## 0.3.0-next.13 + +### Patch Changes + +- fix stale connectors when switching chains + +- Updated dependencies []: + - @wagmi/core@0.2.0-next.11 + +## 0.3.0-next.12 + +### Patch Changes + +- republish + +- Updated dependencies []: + - @wagmi/core@0.2.0-next.10 + +## 0.3.0-next.11 + +### Patch Changes + +- improve type support for ethers providers + +- Updated dependencies []: + - @wagmi/core@0.2.0-next.9 + +## 0.3.0-next.10 + +### Patch Changes + +- update babel target + +- Updated dependencies []: + - @wagmi/core@0.2.0-next.8 + +## 0.3.0-next.9 + +### Minor Changes + +- - Favour `message` event over `connecting` event to conform to EIP-1193 + - Export `useWaitForTransaction` + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@0.2.0-next.7 + +## 0.3.0-next.8 + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@0.2.0-next.6 + +## 0.3.0-next.7 + +### Minor Changes + +- don't persist account data when `autoConnect` is falsy + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@0.2.0-next.5 + +## 0.3.0-next.6 + +### Minor Changes + +- fix `useContractWrite` mutation fn arguments + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@0.2.0-next.4 + +## 0.3.0-next.5 + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@0.2.0-next.3 + +## 0.3.0-next.4 + +### Minor Changes + +- force address to be required in `useAccount` + +## 0.3.0-next.3 + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@0.2.0-next.2 + +## 0.3.0-next.2 + +### Minor Changes + +- Initial 0.3.0 release + +### Patch Changes + +- Updated dependencies []: + - @wagmi/core@0.2.0-next.1 + +## 0.2.28 + +### Patch Changes + +- [`747d895`](https://github.com/tmm/wagmi/commit/747d895a54b562958afde34b1d34e81ab5039e2c) Thanks [@tmm](https://github.com/tmm)! - add warning to WalletLinkConnector + +- Updated dependencies [[`747d895`](https://github.com/tmm/wagmi/commit/747d895a54b562958afde34b1d34e81ab5039e2c)]: + - wagmi-core@0.1.22 + +## 0.2.27 + +### Patch Changes + +- [`c858c51`](https://github.com/tmm/wagmi/commit/c858c51b44d9039f1d0db5bcf016639f47d1931f) Thanks [@tmm](https://github.com/tmm)! - update coinbase connector + +- Updated dependencies [[`c858c51`](https://github.com/tmm/wagmi/commit/c858c51b44d9039f1d0db5bcf016639f47d1931f)]: + - wagmi-core@0.1.21 + +## 0.2.26 + +### Patch Changes + +- Updated dependencies [[`36e6989`](https://github.com/tmm/wagmi/commit/36e69894f4c27aaad7fb6d678476c8bb870244bb)]: + - wagmi-core@0.1.20 + +## 0.2.25 + +### Patch Changes + +- [`d467df6`](https://github.com/tmm/wagmi/commit/d467df6374210dbc4b016788b4beb4fded54cb4d) Thanks [@tmm](https://github.com/tmm)! - fix global type leaking + +- Updated dependencies [[`d467df6`](https://github.com/tmm/wagmi/commit/d467df6374210dbc4b016788b4beb4fded54cb4d)]: + - wagmi-core@0.1.19 + +## 0.2.24 + +### Patch Changes + +- [#294](https://github.com/tmm/wagmi/pull/294) [`1d253f3`](https://github.com/tmm/wagmi/commit/1d253f3a59b61d24c88d25c99decd84a6c734e5d) Thanks [@tmm](https://github.com/tmm)! - change babel target + +- Updated dependencies [[`1d253f3`](https://github.com/tmm/wagmi/commit/1d253f3a59b61d24c88d25c99decd84a6c734e5d)]: + - wagmi-core@0.1.18 + +## 0.2.23 + +### Patch Changes + +- [#292](https://github.com/tmm/wagmi/pull/292) [`53c9be1`](https://github.com/tmm/wagmi/commit/53c9be17ee0c2ae6b8f34f2351b8858257b3f5f2) Thanks [@tmm](https://github.com/tmm)! - fix private fields + +- Updated dependencies [[`53c9be1`](https://github.com/tmm/wagmi/commit/53c9be17ee0c2ae6b8f34f2351b8858257b3f5f2)]: + - wagmi-core@0.1.17 + +## 0.2.22 + +### Patch Changes + +- [`79a2499`](https://github.com/tmm/wagmi/commit/79a249989029f818c32c0e84c0dd2c75e8aa990a) Thanks [@tmm](https://github.com/tmm)! - update build target to es2021 + +- Updated dependencies [[`79a2499`](https://github.com/tmm/wagmi/commit/79a249989029f818c32c0e84c0dd2c75e8aa990a)]: + - wagmi-core@0.1.16 + +## 0.2.21 + +### Patch Changes + +- [`f9790b5`](https://github.com/tmm/wagmi/commit/f9790b55600df09c77bb8ca349c5a3457df1b07c) Thanks [@tmm](https://github.com/tmm)! - fix WalletConnect issue + +- Updated dependencies [[`f9790b5`](https://github.com/tmm/wagmi/commit/f9790b55600df09c77bb8ca349c5a3457df1b07c)]: + - wagmi-core@0.1.15 + +## 0.2.20 + +### Patch Changes + +- [`fed29fb`](https://github.com/tmm/wagmi/commit/fed29fb4714abe234e2dabb63782cfc4439a10cf) Thanks [@tmm](https://github.com/tmm)! - export useSignTypedData + +## 0.2.19 + +### Patch Changes + +- [`6987278`](https://github.com/tmm/wagmi/commit/69872786e0b54b89a20945cc5471c1f4675b0a68) Thanks [@tmm](https://github.com/tmm)! - add useSignedTypeData + +## 0.2.18 + +### Patch Changes + +- [#236](https://github.com/tmm/wagmi/pull/236) [`53bad61`](https://github.com/tmm/wagmi/commit/53bad615788764e31121678083c382c1bd042fe8) Thanks [@markdalgleish](https://github.com/markdalgleish)! - Updated `@walletconnect/ethereum-provider` to [v1.7.4](https://github.com/WalletConnect/walletconnect-monorepo/releases/tag/1.7.4) + +- Updated dependencies [[`53bad61`](https://github.com/tmm/wagmi/commit/53bad615788764e31121678083c382c1bd042fe8)]: + - wagmi-core@0.1.14 + +## 0.2.17 + +### Patch Changes + +- [`8e9412a`](https://github.com/tmm/wagmi/commit/8e9412af71958301ae2f9748febb936e79900aa0) Thanks [@tmm](https://github.com/tmm)! - bump walletlink + +- Updated dependencies [[`8e9412a`](https://github.com/tmm/wagmi/commit/8e9412af71958301ae2f9748febb936e79900aa0)]: + - wagmi-core@0.1.13 + +## 0.2.16 + +### Patch Changes + +- [#210](https://github.com/tmm/wagmi/pull/210) [`684468a`](https://github.com/tmm/wagmi/commit/684468aee3e42a1ce2b4b599f3f17d1819213de8) Thanks [@tmm](https://github.com/tmm)! - update chains to match chainslist.org + +- Updated dependencies [[`684468a`](https://github.com/tmm/wagmi/commit/684468aee3e42a1ce2b4b599f3f17d1819213de8)]: + - wagmi-core@0.1.12 + +## 0.2.15 + +### Patch Changes + +- [#195](https://github.com/tmm/wagmi/pull/195) [`25b6083`](https://github.com/tmm/wagmi/commit/25b6083a662a0236794d1765343467691421c14b) Thanks [@tmm](https://github.com/tmm)! - rename wagmi-private to wagmi-core + +- Updated dependencies [[`25b6083`](https://github.com/tmm/wagmi/commit/25b6083a662a0236794d1765343467691421c14b)]: + - wagmi-core@0.1.11 + +## 0.2.14 + +### Patch Changes + +- [#192](https://github.com/tmm/wagmi/pull/192) [`428cedb`](https://github.com/tmm/wagmi/commit/428cedb3dec4e3e4b9f4559c8e65932e05f94e05) Thanks [@tmm](https://github.com/tmm)! - rename core and testing packages + +- Updated dependencies [[`428cedb`](https://github.com/tmm/wagmi/commit/428cedb3dec4e3e4b9f4559c8e65932e05f94e05)]: + - wagmi-core@0.1.10 + +## 0.2.13 + +### Patch Changes + +- [#190](https://github.com/tmm/wagmi/pull/190) [`7034bb8`](https://github.com/tmm/wagmi/commit/7034bb868412b9f481b206371280e84c2d52706d) Thanks [@tmm](https://github.com/tmm)! - add shim for metamask chain changed to prevent disconnect + +- Updated dependencies [[`7034bb8`](https://github.com/tmm/wagmi/commit/7034bb868412b9f481b206371280e84c2d52706d)]: + - wagmi-private@0.1.9 + +## 0.2.12 + +### Patch Changes + +- [`566b47f`](https://github.com/tmm/wagmi/commit/566b47f53c80e1cdcc368d43c53b1772eeb5be20) Thanks [@tmm](https://github.com/tmm)! - fix contract read skip option + +## 0.2.11 + +### Patch Changes + +- [`09f0719`](https://github.com/tmm/wagmi/commit/09f071947012e3133362a7eb80c0f39356899190) Thanks [@tmm](https://github.com/tmm)! - - safe state updates h/t @bpierre + - add useEnsResolveName hook h/t @shunkakinoki + +## 0.2.10 + +### Patch Changes + +- [#159](https://github.com/tmm/wagmi/pull/159) [`981438d`](https://github.com/tmm/wagmi/commit/981438d527fb6b5f025dd9bb405fa9e7a2751597) Thanks [@markdalgleish](https://github.com/markdalgleish)! - add `WagmiProvider` alias for `Provider` + +## 0.2.9 + +### Patch Changes + +- [#137](https://github.com/tmm/wagmi/pull/137) [`dceeb43`](https://github.com/tmm/wagmi/commit/dceeb430d9021fbf98366859cb1cd0149e80c55c) Thanks [@tmm](https://github.com/tmm)! - add siwe guide + +- Updated dependencies [[`dceeb43`](https://github.com/tmm/wagmi/commit/dceeb430d9021fbf98366859cb1cd0149e80c55c)]: + - wagmi-private@0.1.8 + +## 0.2.8 + +### Patch Changes + +- [`b49cb89`](https://github.com/tmm/wagmi/commit/b49cb89ef59289ee1185eafab427d3ab55c17c25) Thanks [@tmm](https://github.com/tmm)! - refactor contract read/write hook state + +## 0.2.7 + +### Patch Changes + +- [`7132631`](https://github.com/tmm/wagmi/commit/713263159899feb257c11614716f0af4f6b06a14) Thanks [@tmm](https://github.com/tmm)! - update contract read and write state + +## 0.2.6 + +### Patch Changes + +- [#127](https://github.com/tmm/wagmi/pull/127) [`f05b031`](https://github.com/tmm/wagmi/commit/f05b0310f7f7e6447e9b6c81cedbb27dcf2f3649) Thanks [@tmm](https://github.com/tmm)! - update switch chain return type + +- Updated dependencies [[`f05b031`](https://github.com/tmm/wagmi/commit/f05b0310f7f7e6447e9b6c81cedbb27dcf2f3649)]: + - wagmi-private@0.1.7 + +## 0.2.5 + +### Patch Changes + +- [`1412eed`](https://github.com/tmm/wagmi/commit/1412eed0d1494bb4f8c6845a0e890f79e4e68e03) Thanks [@tmm](https://github.com/tmm)! - add frame to injected + +- Updated dependencies [[`1412eed`](https://github.com/tmm/wagmi/commit/1412eed0d1494bb4f8c6845a0e890f79e4e68e03)]: + - wagmi-private@0.1.6 + +## 0.2.4 + +### Patch Changes + +- [#122](https://github.com/tmm/wagmi/pull/122) [`94f599c`](https://github.com/tmm/wagmi/commit/94f599cc1de74a977956d4118d85ab0d36915471) Thanks [@tmm](https://github.com/tmm)! - add decimals to useBalance + +## 0.2.3 + +### Patch Changes + +- [`e338c3b`](https://github.com/tmm/wagmi/commit/e338c3b6cc255742be6a67593aa5da6c17e90fbd) Thanks [@tmm](https://github.com/tmm)! - checksum connector address on change events + + add shim to injected connector for simulating disconnect + +- Updated dependencies [[`e338c3b`](https://github.com/tmm/wagmi/commit/e338c3b6cc255742be6a67593aa5da6c17e90fbd)]: + - wagmi-private@0.1.5 + +## 0.2.2 + +### Patch Changes + +- [`0176c4e`](https://github.com/tmm/wagmi/commit/0176c4e83fb0c5f159c3c802a1da3d6deb2184ae) Thanks [@tmm](https://github.com/tmm)! - added switchChain to WalletConnect and WalletLink connectors + +- Updated dependencies [[`0176c4e`](https://github.com/tmm/wagmi/commit/0176c4e83fb0c5f159c3c802a1da3d6deb2184ae)]: + - wagmi-private@0.1.4 + +## 0.2.1 + +### Patch Changes + +- [`f12d9cc`](https://github.com/tmm/wagmi/commit/f12d9ccfdf87a2f75299b53a7dd6b1ad046a49d8) Thanks [@tmm](https://github.com/tmm)! - fixes overrides type + +## 0.2.0 + +### Minor Changes + +- [#98](https://github.com/tmm/wagmi/pull/98) [`b2ec758`](https://github.com/tmm/wagmi/commit/b2ec7580436f52fd35005c6dd3f4472650a14d02) Thanks [@oveddan](https://github.com/oveddan)! - Exported Context + +## 0.1.7 + +### Patch Changes + +- [`d965757`](https://github.com/tmm/wagmi/commit/d9657578bc17648716c4671b8cc35ad295bc71d2) Thanks [@tmm](https://github.com/tmm)! - use balance eth symbol + +## 0.1.6 + +### Patch Changes + +- [`071d7fb`](https://github.com/tmm/wagmi/commit/071d7fbca35ec4832700b5343661ceb2dae20598) Thanks [@tmm](https://github.com/tmm)! - add hardhat chain + +- Updated dependencies [[`071d7fb`](https://github.com/tmm/wagmi/commit/071d7fbca35ec4832700b5343661ceb2dae20598)]: + - wagmi-private@0.1.3 + +## 0.1.5 + +### Patch Changes + +- [`db4d869`](https://github.com/tmm/wagmi/commit/db4d869fd9380b26a1f3f96ab34abd14ca73d068) Thanks [@tmm](https://github.com/tmm)! - - add global connecting property for `Provider` `autoConnect` (h/t @sammdec) + - fix `useContractEvent` error (h/t @math-marcellino) + +## 0.1.4 + +### Patch Changes + +- [#73](https://github.com/tmm/wagmi/pull/73) [`0c78ccc`](https://github.com/tmm/wagmi/commit/0c78ccc4e7f311525d4ea712b79cf532899e2006) Thanks [@tmm](https://github.com/tmm)! - fix module exports + +## 0.1.3 + +### Patch Changes + +- [`78bade9`](https://github.com/tmm/wagmi/commit/78bade9d0da97ab38a7e6594c34e3841ec1c8fe6) Thanks [@tmm](https://github.com/tmm)! - add type definitions + +- Updated dependencies [[`78bade9`](https://github.com/tmm/wagmi/commit/78bade9d0da97ab38a7e6594c34e3841ec1c8fe6)]: + - wagmi-private@0.1.2 + +## 0.1.2 + +### Patch Changes + +- [#56](https://github.com/tmm/wagmi/pull/56) [`2ebfd8e`](https://github.com/tmm/wagmi/commit/2ebfd8e85b560f25cd46cff04619c84643cab297) Thanks [@tmm](https://github.com/tmm)! - add chain support status + +- Updated dependencies [[`2ebfd8e`](https://github.com/tmm/wagmi/commit/2ebfd8e85b560f25cd46cff04619c84643cab297)]: + - wagmi-private@0.1.1 + +## 0.1.1 + +### Patch Changes + +- [#54](https://github.com/tmm/wagmi/pull/54) [`25acd3d`](https://github.com/tmm/wagmi/commit/25acd3dfbb4498af5e1139ae9c892f5013404cbc) Thanks [@tmm](https://github.com/tmm)! - Stale contract object when useContract hook arguments change @zakangelle + +## 0.1.0 + +### Minor Changes + +- [#52](https://github.com/tmm/wagmi/pull/52) [`da7a3a6`](https://github.com/tmm/wagmi/commit/da7a3a615def2443f65c041999100ce35e9774cc) Thanks [@tmm](https://github.com/tmm)! - Moves connectors to their own entrypoints to reduce bundle size. + + ```ts + // old - WalletLinkConnector unused, but still in final bundle + import { InjectedConnector, WalletConnectConnector } from "wagmi"; + + // new - WalletLinkConnector not in final bundle + import { InjectedConnector } from "wagmi/connectors/injected"; + import { WalletConnectConnector } from "wagmi/connectors/walletConnect"; + ``` + +### Patch Changes + +- Updated dependencies [[`da7a3a6`](https://github.com/tmm/wagmi/commit/da7a3a615def2443f65c041999100ce35e9774cc)]: + - wagmi-private@0.1.0 + +## 0.0.17 + +### Patch Changes + +- [#25](https://github.com/tmm/wagmi/pull/25) [`9a7dab7`](https://github.com/tmm/wagmi/commit/9a7dab78b3518658bc7d85dc397990f0d28da175) Thanks [@tmm](https://github.com/tmm)! - update response types + +- Updated dependencies [[`9a7dab7`](https://github.com/tmm/wagmi/commit/9a7dab78b3518658bc7d85dc397990f0d28da175)]: + - wagmi-private@0.0.17 + +## 0.0.16 + +### Patch Changes + +- [`d1574cf`](https://github.com/tmm/wagmi/commit/d1574cf5f7a578ccd480889c2e375134145a4aba) Thanks [@tmm](https://github.com/tmm)! - add better type information for contract results + +- Updated dependencies [[`d1574cf`](https://github.com/tmm/wagmi/commit/d1574cf5f7a578ccd480889c2e375134145a4aba)]: + - wagmi-private@0.0.16 + +## 0.0.15 + +### Patch Changes + +- [`3909624`](https://github.com/tmm/wagmi/commit/39096249c1fa9516beabb11735beb67c94032879) Thanks [@tmm](https://github.com/tmm)! - make contract read and write execute overrides param optional + +- Updated dependencies [[`3909624`](https://github.com/tmm/wagmi/commit/39096249c1fa9516beabb11735beb67c94032879)]: + - wagmi-private@0.0.15 + +## 0.0.14 + +### Patch Changes + +- [`63312e2`](https://github.com/tmm/wagmi/commit/63312e2b06b8d835abc2908cba399d941ca79408) Thanks [@tmm](https://github.com/tmm)! - add once to contract event + +- Updated dependencies [[`63312e2`](https://github.com/tmm/wagmi/commit/63312e2b06b8d835abc2908cba399d941ca79408)]: + - wagmi-private@0.0.14 + +## 0.0.13 + +### Patch Changes + +- [`6f890b0`](https://github.com/tmm/wagmi/commit/6f890b0dabbdbea913ec91cb8bfc970c05ed0a93) Thanks [@tmm](https://github.com/tmm)! - update readme + +- Updated dependencies [[`6f890b0`](https://github.com/tmm/wagmi/commit/6f890b0dabbdbea913ec91cb8bfc970c05ed0a93)]: + - wagmi-private@0.0.13 + +## 0.0.12 + +### Patch Changes + +- [#19](https://github.com/tmm/wagmi/pull/19) [`7bc1c47`](https://github.com/tmm/wagmi/commit/7bc1c47875e9ef24e9c79cfafc6b23e7a838b5bc) Thanks [@tmm](https://github.com/tmm)! - remove console log from walletlink connector + +- Updated dependencies [[`7bc1c47`](https://github.com/tmm/wagmi/commit/7bc1c47875e9ef24e9c79cfafc6b23e7a838b5bc)]: + - wagmi-private@0.0.12 + +## 0.0.11 + +### Patch Changes + +- [#17](https://github.com/tmm/wagmi/pull/17) [`571648b`](https://github.com/tmm/wagmi/commit/571648b754f7f538536bafc9387bd3104657ea49) Thanks [@tmm](https://github.com/tmm)! - standardize connector provider + +- Updated dependencies [[`571648b`](https://github.com/tmm/wagmi/commit/571648b754f7f538536bafc9387bd3104657ea49)]: + - wagmi-private@0.0.11 + +## 0.0.10 + +### Patch Changes + +- [#15](https://github.com/tmm/wagmi/pull/15) [`5f7675c`](https://github.com/tmm/wagmi/commit/5f7675c3ffd848522d4117c07c1f62b17dfc6616) Thanks [@tmm](https://github.com/tmm)! - read and write contract functions + +- Updated dependencies [[`5f7675c`](https://github.com/tmm/wagmi/commit/5f7675c3ffd848522d4117c07c1f62b17dfc6616)]: + - wagmi-private@0.0.10 + +## 0.0.9 + +### Patch Changes + +- [#13](https://github.com/tmm/wagmi/pull/13) [`e5545f5`](https://github.com/tmm/wagmi/commit/e5545f5565cf0bbf5e62ec7ccab3051705b1d313) Thanks [@tmm](https://github.com/tmm)! - add testing package + +- Updated dependencies [[`e5545f5`](https://github.com/tmm/wagmi/commit/e5545f5565cf0bbf5e62ec7ccab3051705b1d313)]: + - wagmi-private@0.0.9 + +## 0.0.8 + +### Patch Changes + +- [`5332500`](https://github.com/tmm/wagmi/commit/5332500918ac240d29ffe4d2aed8566a8ac001e4) Thanks [@tmm](https://github.com/tmm)! - update signing + +- Updated dependencies [[`5332500`](https://github.com/tmm/wagmi/commit/5332500918ac240d29ffe4d2aed8566a8ac001e4)]: + - wagmi-private@0.0.8 + +## 0.0.7 + +### Patch Changes + +- [`0bff89a`](https://github.com/tmm/wagmi/commit/0bff89ab2ad28b2cb9b346d1ac870e859d9278bc) Thanks [@tmm](https://github.com/tmm)! - update injected connector + +- Updated dependencies [[`0bff89a`](https://github.com/tmm/wagmi/commit/0bff89ab2ad28b2cb9b346d1ac870e859d9278bc)]: + - wagmi-private@0.0.7 + +## 0.0.6 + +### Patch Changes + +- [`37d39d1`](https://github.com/tmm/wagmi/commit/37d39d174ddfa122462bbe2d02141cd61eb9db4a) Thanks [@tmm](https://github.com/tmm)! - add message signing + +- Updated dependencies [[`37d39d1`](https://github.com/tmm/wagmi/commit/37d39d174ddfa122462bbe2d02141cd61eb9db4a)]: + - wagmi-private@0.0.6 + +## 0.0.5 + +### Patch Changes + +- [`d7d94f0`](https://github.com/tmm/wagmi/commit/d7d94f06f7d30468e5e39d64db63124c6315cf82) Thanks [@tmm](https://github.com/tmm)! - fix injected connector name + +- Updated dependencies [[`d7d94f0`](https://github.com/tmm/wagmi/commit/d7d94f06f7d30468e5e39d64db63124c6315cf82)]: + - wagmi-private@0.0.5 + +## 0.0.4 + +### Patch Changes + +- [`29fbe29`](https://github.com/tmm/wagmi/commit/29fbe2920046b9e87a34faa04500ccf3c4f83748) Thanks [@tmm](https://github.com/tmm)! - fix external deps + +- Updated dependencies [[`29fbe29`](https://github.com/tmm/wagmi/commit/29fbe2920046b9e87a34faa04500ccf3c4f83748)]: + - wagmi-private@0.0.4 + +## 0.0.3 + +### Patch Changes + +- [#6](https://github.com/tmm/wagmi/pull/6) [`8dc3a5d`](https://github.com/tmm/wagmi/commit/8dc3a5d5f418813b09663534fe585d9bcf94dbeb) Thanks [@tmm](https://github.com/tmm)! - clean up deps + +- Updated dependencies [[`8dc3a5d`](https://github.com/tmm/wagmi/commit/8dc3a5d5f418813b09663534fe585d9bcf94dbeb)]: + - wagmi-private@0.0.3 + +## 0.0.2 + +### Patch Changes + +- [#4](https://github.com/tmm/wagmi/pull/4) [`2fbd821`](https://github.com/tmm/wagmi/commit/2fbd8216379bd03c9cc5c06b10b75637e75cb7d8) Thanks [@tmm](https://github.com/tmm)! - init changesets + +- Updated dependencies [[`2fbd821`](https://github.com/tmm/wagmi/commit/2fbd8216379bd03c9cc5c06b10b75637e75cb7d8)]: + - wagmi-private@0.0.2 diff --git a/wagmi-project/packages/react/README.md b/wagmi-project/packages/react/README.md new file mode 100644 index 0000000000..4c87fd5e67 --- /dev/null +++ b/wagmi-project/packages/react/README.md @@ -0,0 +1,13 @@ +# wagmi + +React Hooks for Ethereum + +## Installation + +```bash +pnpm add wagmi viem @tanstack/react-query +``` + +## Documentation + +For documentation and guides, visit [wagmi.sh](https://wagmi.sh). diff --git a/wagmi-project/packages/react/package.json b/wagmi-project/packages/react/package.json new file mode 100644 index 0000000000..79311aa5ce --- /dev/null +++ b/wagmi-project/packages/react/package.json @@ -0,0 +1,119 @@ +{ + "name": "wagmi", + "description": "React Hooks for Ethereum", + "version": "2.15.4", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/wevm/wagmi.git", + "directory": "packages/react" + }, + "scripts": { + "build": "pnpm run clean && pnpm run build:esm+types", + "build:esm+types": "tsc --project tsconfig.build.json --outDir ./dist/esm --declaration --declarationMap --declarationDir ./dist/types", + "check:types": "tsc --noEmit", + "clean": "rm -rf dist tsconfig.tsbuildinfo actions chains codegen connectors experimental query", + "test:build": "publint --strict && attw --pack --ignore-rules cjs-resolves-to-esm" + }, + "files": [ + "dist/**", + "!dist/**/*.tsbuildinfo", + "src/**/*.ts", + "!src/**/*.test.ts", + "!src/**/*.test-d.ts", + "/actions", + "/chains", + "/codegen", + "/connectors", + "/experimental", + "/query" + ], + "sideEffects": false, + "type": "module", + "main": "./dist/esm/exports/index.js", + "types": "./dist/types/exports/index.d.ts", + "typings": "./dist/types/exports/index.d.ts", + "exports": { + ".": { + "types": "./dist/types/exports/index.d.ts", + "default": "./dist/esm/exports/index.js" + }, + "./actions": { + "types": "./dist/types/exports/actions.d.ts", + "default": "./dist/esm/exports/actions.js" + }, + "./actions/experimental": { + "types": "./dist/types/exports/actions/experimental.d.ts", + "default": "./dist/esm/exports/actions/experimental.js" + }, + "./chains": { + "types": "./dist/types/exports/chains.d.ts", + "default": "./dist/esm/exports/chains.js" + }, + "./codegen": { + "types": "./dist/types/exports/codegen.d.ts", + "default": "./dist/esm/exports/codegen.js" + }, + "./connectors": { + "types": "./dist/types/exports/connectors.d.ts", + "default": "./dist/esm/exports/connectors.js" + }, + "./experimental": { + "types": "./dist/types/exports/experimental.d.ts", + "default": "./dist/esm/exports/experimental.js" + }, + "./query": { + "types": "./dist/types/exports/query.d.ts", + "default": "./dist/esm/exports/query.js" + }, + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "actions": ["./dist/types/exports/actions.d.ts"], + "chains": ["./dist/types/exports/chains.d.ts"], + "codegen": ["./dist/types/exports/codegen.d.ts"], + "connectors": ["./dist/types/exports/connectors.d.ts"], + "experimental": ["./dist/types/exports/experimental.d.ts"], + "query": ["./dist/types/exports/query.d.ts"] + } + }, + "peerDependencies": { + "@tanstack/react-query": ">=5.0.0", + "react": ">=18", + "typescript": ">=5.0.4", + "viem": "2.x" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + }, + "dependencies": { + "@wagmi/connectors": "workspace:*", + "@wagmi/core": "workspace:*", + "use-sync-external-store": "1.4.0" + }, + "devDependencies": { + "@tanstack/react-query": "catalog:", + "@testing-library/dom": "catalog:", + "@testing-library/react": "catalog:", + "@types/react": "catalog:", + "@types/react-dom": "catalog:", + "@types/use-sync-external-store": "^0.0.6", + "react": "catalog:", + "react-dom": "catalog:" + }, + "contributors": ["awkweb.eth ", "jxom.eth "], + "funding": "https://github.com/sponsors/wevm", + "keywords": [ + "wagmi", + "react", + "hooks", + "eth", + "ethereum", + "dapps", + "wallet", + "web3" + ] +} diff --git a/wagmi-project/packages/react/src/context.test.tsx b/wagmi-project/packages/react/src/context.test.tsx new file mode 100644 index 0000000000..7a716ac685 --- /dev/null +++ b/wagmi-project/packages/react/src/context.test.tsx @@ -0,0 +1,101 @@ +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { render, waitFor } from '@testing-library/react' +import { http, connect, createConfig, mock } from '@wagmi/core' +import { accounts, addressRegex, config, mainnet } from '@wagmi/test' +import React from 'react' +import { expect, test } from 'vitest' + +import { WagmiProvider } from './context.js' +import { useAccount } from './hooks/useAccount.js' +import { useConnectorClient } from './hooks/useConnectorClient.js' + +test('default', () => { + function Component() { + const { address } = useAccount() + const { data } = useConnectorClient() + return ( +
+

wevm

+
useAccount: {address}
+
useConnectorClient: {data?.account?.address}
+
+ ) + } + + const queryClient = new QueryClient() + const result = render( + + + + + , + ) + expect(result.getByRole('heading').innerText).toMatchInlineSnapshot(`"wevm"`) + result.unmount() +}) + +test('fake ssr config', () => { + const config = createConfig({ + chains: [mainnet], + pollingInterval: 100, + ssr: true, + transports: { + [mainnet.id]: http(), + }, + }) + const queryClient = new QueryClient() + + const result = render( + + +

wevm

+
+
, + ) + expect(result.getAllByRole('heading')).toMatchInlineSnapshot(` + [ +

+ wevm +

, + ] + `) + result.unmount() +}) + +test('mock reconnect', async () => { + function Component() { + const { address } = useAccount() + return ( +
+

{address}

+
+ ) + } + + const connector = mock({ + accounts, + features: { reconnect: true }, + }) + const config = createConfig({ + chains: [mainnet], + connectors: [connector], + storage: null, + transports: { + [mainnet.id]: http(), + }, + }) + await connect(config, { connector }) + + const queryClient = new QueryClient() + const result = render( + + + + + , + ) + await waitFor(() => + expect(result.getByRole('heading').innerText).toMatch(addressRegex), + ) + result.unmount() +}) diff --git a/wagmi-project/packages/react/src/context.ts b/wagmi-project/packages/react/src/context.ts new file mode 100644 index 0000000000..ec484ccd74 --- /dev/null +++ b/wagmi-project/packages/react/src/context.ts @@ -0,0 +1,28 @@ +'use client' + +import type { ResolvedRegister, State } from '@wagmi/core' +import { createContext, createElement } from 'react' +import { Hydrate } from './hydrate.js' + +export const WagmiContext = createContext< + ResolvedRegister['config'] | undefined +>(undefined) + +export type WagmiProviderProps = { + config: ResolvedRegister['config'] + initialState?: State | undefined + reconnectOnMount?: boolean | undefined +} + +export function WagmiProvider( + parameters: React.PropsWithChildren, +) { + const { children, config } = parameters + + const props = { value: config } + return createElement( + Hydrate, + parameters, + createElement(WagmiContext.Provider, props, children), + ) +} diff --git a/wagmi-project/packages/react/src/errors/base.test.ts b/wagmi-project/packages/react/src/errors/base.test.ts new file mode 100644 index 0000000000..2980541ed8 --- /dev/null +++ b/wagmi-project/packages/react/src/errors/base.test.ts @@ -0,0 +1,155 @@ +import { expect, test } from 'vitest' + +import { BaseError } from './base.js' + +test('BaseError', () => { + expect(new BaseError('An error occurred.')).toMatchInlineSnapshot(` + [WagmiError: An error occurred. + + Version: wagmi@x.y.z] + `) + + expect( + new BaseError('An error occurred.', { details: 'details' }), + ).toMatchInlineSnapshot(` + [WagmiError: An error occurred. + + Details: details + Version: wagmi@x.y.z] + `) + + expect(new BaseError('', { details: 'details' })).toMatchInlineSnapshot(` + [WagmiError: An error occurred. + + Details: details + Version: wagmi@x.y.z] + `) +}) + +test('BaseError (w/ docsPath)', () => { + expect( + new BaseError('An error occurred.', { + details: 'details', + docsPath: '/lol', + }), + ).toMatchInlineSnapshot(` + [WagmiError: An error occurred. + + Docs: https://wagmi.sh/react/lol.html + Details: details + Version: wagmi@x.y.z] + `) + expect( + new BaseError('An error occurred.', { + cause: new BaseError('error', { docsPath: '/docs' }), + }), + ).toMatchInlineSnapshot(` + [WagmiError: An error occurred. + + Docs: https://wagmi.sh/react/docs.html + Version: wagmi@x.y.z] + `) + expect( + new BaseError('An error occurred.', { + cause: new BaseError('error'), + docsPath: '/lol', + }), + ).toMatchInlineSnapshot(` + [WagmiError: An error occurred. + + Docs: https://wagmi.sh/react/lol.html + Version: wagmi@x.y.z] + `) + expect( + new BaseError('An error occurred.', { + details: 'details', + docsPath: '/lol', + docsSlug: 'test', + }), + ).toMatchInlineSnapshot(` + [WagmiError: An error occurred. + + Docs: https://wagmi.sh/react/lol.html#test + Details: details + Version: wagmi@x.y.z] + `) +}) + +test('BaseError (w/ metaMessages)', () => { + expect( + new BaseError('An error occurred.', { + details: 'details', + metaMessages: ['Reason: idk', 'Cause: lol'], + }), + ).toMatchInlineSnapshot(` + [WagmiError: An error occurred. + + Reason: idk + Cause: lol + + Details: details + Version: wagmi@x.y.z] + `) +}) + +test('inherited BaseError', () => { + const err = new BaseError('An error occurred.', { + details: 'details', + docsPath: '/lol', + }) + expect( + new BaseError('An internal error occurred.', { + cause: err, + }), + ).toMatchInlineSnapshot(` + [WagmiError: An internal error occurred. + + Docs: https://wagmi.sh/react/lol.html + Details: details + Version: wagmi@x.y.z] + `) +}) + +test('inherited Error', () => { + const err = new Error('details') + expect( + new BaseError('An internal error occurred.', { + cause: err, + docsPath: '/lol', + }), + ).toMatchInlineSnapshot(` + [WagmiError: An internal error occurred. + + Docs: https://wagmi.sh/react/lol.html + Details: details + Version: wagmi@x.y.z] + `) +}) + +test('walk: no predicate fn (walks to leaf)', () => { + class FooError extends BaseError {} + class BarError extends BaseError {} + + const err = new BaseError('test1', { + cause: new FooError('test2', { cause: new BarError('test3') }), + }) + expect(err.walk()).toMatchInlineSnapshot(` + [WagmiError: test3 + + Version: wagmi@x.y.z] + `) +}) + +test('walk: predicate fn', () => { + class FooError extends BaseError {} + class BarError extends BaseError {} + + const err = new BaseError('test1', { + cause: new FooError('test2', { cause: new BarError('test3') }), + }) + expect(err.walk((err) => err instanceof FooError)).toMatchInlineSnapshot(` + [WagmiError: test2 + + Version: wagmi@x.y.z] + `) +}) diff --git a/wagmi-project/packages/react/src/errors/base.ts b/wagmi-project/packages/react/src/errors/base.ts new file mode 100644 index 0000000000..b2ee83c86e --- /dev/null +++ b/wagmi-project/packages/react/src/errors/base.ts @@ -0,0 +1,14 @@ +import { BaseError as CoreError } from '@wagmi/core' + +import { getVersion } from '../utils/getVersion.js' + +export type BaseErrorType = BaseError & { name: 'WagmiError' } +export class BaseError extends CoreError { + override name = 'WagmiError' + override get docsBaseUrl() { + return 'https://wagmi.sh/react' + } + override get version() { + return getVersion() + } +} diff --git a/wagmi-project/packages/react/src/errors/context.test.ts b/wagmi-project/packages/react/src/errors/context.test.ts new file mode 100644 index 0000000000..8dc5a16c4a --- /dev/null +++ b/wagmi-project/packages/react/src/errors/context.test.ts @@ -0,0 +1,12 @@ +import { expect, test } from 'vitest' + +import { WagmiProviderNotFoundError } from './context.js' + +test('WagmiProviderNotFoundError', () => { + expect(new WagmiProviderNotFoundError()).toMatchInlineSnapshot(` + [WagmiProviderNotFoundError: \`useConfig\` must be used within \`WagmiProvider\`. + + Docs: https://wagmi.sh/react/api/WagmiProvider.html + Version: wagmi@x.y.z] + `) +}) diff --git a/wagmi-project/packages/react/src/errors/context.ts b/wagmi-project/packages/react/src/errors/context.ts new file mode 100644 index 0000000000..0ea5cadaaa --- /dev/null +++ b/wagmi-project/packages/react/src/errors/context.ts @@ -0,0 +1,13 @@ +import { BaseError } from './base.js' + +export type WagmiProviderNotFoundErrorType = WagmiProviderNotFoundError & { + name: 'WagmiProviderNotFoundError' +} +export class WagmiProviderNotFoundError extends BaseError { + override name = 'WagmiProviderNotFoundError' + constructor() { + super('`useConfig` must be used within `WagmiProvider`.', { + docsPath: '/api/WagmiProvider', + }) + } +} diff --git a/wagmi-project/packages/react/src/experimental/hooks/useWriteContracts.test.ts b/wagmi-project/packages/react/src/experimental/hooks/useWriteContracts.test.ts new file mode 100644 index 0000000000..ea6d4815de --- /dev/null +++ b/wagmi-project/packages/react/src/experimental/hooks/useWriteContracts.test.ts @@ -0,0 +1,45 @@ +import { connect, disconnect } from '@wagmi/core' +import { abi, address, config } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useWriteContracts } from './useWriteContracts.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const { result } = renderHook(() => useWriteContracts()) + + result.current.writeContracts({ + contracts: [ + { + abi: abi.wagmiMintExample, + address: address.wagmiMintExample, + functionName: 'mint', + }, + { + abi: abi.wagmiMintExample, + address: address.wagmiMintExample, + functionName: 'mint', + }, + { + abi: abi.wagmiMintExample, + address: address.wagmiMintExample, + functionName: 'mint', + }, + ], + }) + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current.data).toMatchInlineSnapshot( + ` + { + "id": "0x8913636bd97cf4bcc0a6343c730905a27ead0f7480ff82190072e916439eb212", + } + `, + ) + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/react/src/experimental/hooks/useWriteContracts.ts b/wagmi-project/packages/react/src/experimental/hooks/useWriteContracts.ts new file mode 100644 index 0000000000..8d0d32aefb --- /dev/null +++ b/wagmi-project/packages/react/src/experimental/hooks/useWriteContracts.ts @@ -0,0 +1,85 @@ +'use client' + +import { useMutation } from '@tanstack/react-query' +import type { Config, ResolvedRegister } from '@wagmi/core' +import { + type WriteContractsData, + type WriteContractsErrorType, + type WriteContractsMutate, + type WriteContractsMutateAsync, + type WriteContractsVariables, + writeContractsMutationOptions, +} from '@wagmi/core/experimental' +import type { Compute } from '@wagmi/core/internal' +import type { ContractFunctionParameters } from 'viem' + +import { useConfig } from '../../hooks/useConfig.js' +import type { ConfigParameter } from '../../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../../utils/query.js' + +export type UseWriteContractsParameters< + contracts extends readonly unknown[] = readonly ContractFunctionParameters[], + config extends Config = Config, + context = unknown, +> = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + WriteContractsData, + WriteContractsErrorType, + WriteContractsVariables< + contracts, + config, + config['chains'][number]['id'] + >, + context + > + | undefined + } +> + +export type UseWriteContractsReturnType< + contracts extends readonly unknown[] = readonly ContractFunctionParameters[], + config extends Config = Config, + context = unknown, +> = Compute< + UseMutationReturnType< + WriteContractsData, + WriteContractsErrorType, + WriteContractsVariables, + context + > & { + writeContracts: WriteContractsMutate + writeContractsAsync: WriteContractsMutateAsync + } +> + +/** https://wagmi.sh/react/api/hooks/useWriteContracts */ +export function useWriteContracts< + const contracts extends + readonly unknown[] = readonly ContractFunctionParameters[], + config extends Config = ResolvedRegister['config'], + context = unknown, +>( + parameters: UseWriteContractsParameters = {}, +): UseWriteContractsReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = writeContractsMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + type Return = UseWriteContractsReturnType + return { + ...result, + writeContracts: mutate as Return['writeContracts'], + writeContractsAsync: mutateAsync as Return['writeContractsAsync'], + } +} diff --git a/wagmi-project/packages/react/src/exports/actions.test.ts b/wagmi-project/packages/react/src/exports/actions.test.ts new file mode 100644 index 0000000000..eaaedba14f --- /dev/null +++ b/wagmi-project/packages/react/src/exports/actions.test.ts @@ -0,0 +1,86 @@ +import { expect, test } from 'vitest' + +import * as actions from './actions.js' + +test('exports', () => { + expect(Object.keys(actions)).toMatchInlineSnapshot(` + [ + "call", + "connect", + "deployContract", + "disconnect", + "estimateGas", + "estimateFeesPerGas", + "estimateMaxPriorityFeePerGas", + "getAccount", + "getBalance", + "fetchBalance", + "getBlock", + "getBlockNumber", + "fetchBlockNumber", + "getBlockTransactionCount", + "getBytecode", + "getCallsStatus", + "getCapabilities", + "getChainId", + "getChains", + "getClient", + "getConnections", + "getConnectors", + "getConnectorClient", + "getEnsAddress", + "fetchEnsAddress", + "getEnsAvatar", + "fetchEnsAvatar", + "getEnsName", + "fetchEnsName", + "getEnsResolver", + "fetchEnsResolver", + "getEnsText", + "getFeeHistory", + "getGasPrice", + "getProof", + "getPublicClient", + "getStorageAt", + "getToken", + "fetchToken", + "getTransaction", + "fetchTransaction", + "getTransactionConfirmations", + "getTransactionCount", + "getTransactionReceipt", + "getWalletClient", + "multicall", + "prepareTransactionRequest", + "readContract", + "readContracts", + "reconnect", + "sendCalls", + "sendTransaction", + "showCallsStatus", + "signMessage", + "signTypedData", + "simulateContract", + "switchAccount", + "switchChain", + "switchNetwork", + "verifyMessage", + "verifyTypedData", + "waitForCallsStatus", + "watchAccount", + "watchAsset", + "watchBlocks", + "watchBlockNumber", + "watchChainId", + "watchClient", + "watchConnections", + "watchConnectors", + "watchContractEvent", + "watchPendingTransactions", + "watchPublicClient", + "waitForTransactionReceipt", + "waitForTransaction", + "writeContract", + ] + `) +}) diff --git a/wagmi-project/packages/react/src/exports/actions.ts b/wagmi-project/packages/react/src/exports/actions.ts new file mode 100644 index 0000000000..3ff9c743c5 --- /dev/null +++ b/wagmi-project/packages/react/src/exports/actions.ts @@ -0,0 +1,7 @@ +//////////////////////////////////////////////////////////////////////////////// +// @wagmi/core/actions +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +// biome-ignore lint/performance/noReExportAll: entrypoint module +export * from '@wagmi/core/actions' diff --git a/wagmi-project/packages/react/src/exports/actions/experimental.test.ts b/wagmi-project/packages/react/src/exports/actions/experimental.test.ts new file mode 100644 index 0000000000..7c4b92df8c --- /dev/null +++ b/wagmi-project/packages/react/src/exports/actions/experimental.test.ts @@ -0,0 +1,25 @@ +import { expect, test } from 'vitest' + +import * as experimentalActions from './experimental.js' + +test('exports', () => { + expect(Object.keys(experimentalActions)).toMatchInlineSnapshot(` + [ + "getCallsStatus", + "getCapabilities", + "sendCalls", + "showCallsStatus", + "waitForCallsStatus", + "writeContracts", + "getCallsStatusQueryOptions", + "getCallsStatusQueryKey", + "getCapabilitiesQueryOptions", + "getCapabilitiesQueryKey", + "sendCallsMutationOptions", + "showCallsStatusMutationOptions", + "waitForCallsStatusQueryKey", + "waitForCallsStatusQueryOptions", + "writeContractsMutationOptions", + ] + `) +}) diff --git a/wagmi-project/packages/react/src/exports/actions/experimental.ts b/wagmi-project/packages/react/src/exports/actions/experimental.ts new file mode 100644 index 0000000000..6ee0334af5 --- /dev/null +++ b/wagmi-project/packages/react/src/exports/actions/experimental.ts @@ -0,0 +1,7 @@ +//////////////////////////////////////////////////////////////////////////////// +// @wagmi/core/experimental +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +// biome-ignore lint/performance/noReExportAll: entrypoint module +export * from '@wagmi/core/experimental' diff --git a/wagmi-project/packages/react/src/exports/chains.ts b/wagmi-project/packages/react/src/exports/chains.ts new file mode 100644 index 0000000000..1fca7f537f --- /dev/null +++ b/wagmi-project/packages/react/src/exports/chains.ts @@ -0,0 +1,7 @@ +//////////////////////////////////////////////////////////////////////////////// +// viem/chains +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +// biome-ignore lint/performance/noReExportAll: entrypoint module +export * from 'viem/chains' diff --git a/wagmi-project/packages/react/src/exports/codegen.test.ts b/wagmi-project/packages/react/src/exports/codegen.test.ts new file mode 100644 index 0000000000..19697cc9a9 --- /dev/null +++ b/wagmi-project/packages/react/src/exports/codegen.test.ts @@ -0,0 +1,18 @@ +import { expect, test } from 'vitest' + +import * as codegen from './codegen.js' + +test('exports', () => { + expect(Object.keys(codegen)).toMatchInlineSnapshot(` + [ + "createSimulateContract", + "createReadContract", + "createWatchContractEvent", + "createWriteContract", + "createUseSimulateContract", + "createUseReadContract", + "createUseWatchContractEvent", + "createUseWriteContract", + ] + `) +}) diff --git a/wagmi-project/packages/react/src/exports/codegen.ts b/wagmi-project/packages/react/src/exports/codegen.ts new file mode 100644 index 0000000000..c642f63bcb --- /dev/null +++ b/wagmi-project/packages/react/src/exports/codegen.ts @@ -0,0 +1,35 @@ +//////////////////////////////////////////////////////////////////////////////// +// @wagmi/core/codegen +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +// biome-ignore lint/performance/noReExportAll: entrypoint module +export * from '@wagmi/core/codegen' + +//////////////////////////////////////////////////////////////////////////////// +// Hooks +//////////////////////////////////////////////////////////////////////////////// + +export { + type CreateUseSimulateContractParameters, + type CreateUseSimulateContractReturnType, + createUseSimulateContract, +} from '../hooks/codegen/createUseSimulateContract.js' + +export { + type CreateUseReadContractParameters, + type CreateUseReadContractReturnType, + createUseReadContract, +} from '../hooks/codegen/createUseReadContract.js' + +export { + type CreateUseWatchContractEventParameters, + type CreateUseWatchContractEventReturnType, + createUseWatchContractEvent, +} from '../hooks/codegen/createUseWatchContractEvent.js' + +export { + type CreateUseWriteContractParameters, + type CreateUseWriteContractReturnType, + createUseWriteContract, +} from '../hooks/codegen/createUseWriteContract.js' diff --git a/wagmi-project/packages/react/src/exports/connectors.test.ts b/wagmi-project/packages/react/src/exports/connectors.test.ts new file mode 100644 index 0000000000..068db8227c --- /dev/null +++ b/wagmi-project/packages/react/src/exports/connectors.test.ts @@ -0,0 +1,17 @@ +import { expect, test } from 'vitest' + +import * as connectors from './connectors.js' + +test('exports', () => { + expect(Object.keys(connectors)).toMatchInlineSnapshot(` + [ + "injected", + "mock", + "coinbaseWallet", + "metaMask", + "safe", + "walletConnect", + "version", + ] + `) +}) diff --git a/wagmi-project/packages/react/src/exports/connectors.ts b/wagmi-project/packages/react/src/exports/connectors.ts new file mode 100644 index 0000000000..e10367e318 --- /dev/null +++ b/wagmi-project/packages/react/src/exports/connectors.ts @@ -0,0 +1,7 @@ +//////////////////////////////////////////////////////////////////////////////// +// @wagmi/connectors +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +// biome-ignore lint/performance/noReExportAll: entrypoint module +export * from '@wagmi/connectors' diff --git a/wagmi-project/packages/react/src/exports/experimental.ts b/wagmi-project/packages/react/src/exports/experimental.ts new file mode 100644 index 0000000000..996eb56a73 --- /dev/null +++ b/wagmi-project/packages/react/src/exports/experimental.ts @@ -0,0 +1,58 @@ +//////////////////////////////////////////////////////////////////////////////// +// Hooks +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +export { + /** @deprecated This is no longer experimental – use `import type { UseCallsStatusParameters } from 'wagmi'` instead. */ + type UseCallsStatusParameters, + /** @deprecated This is no longer experimental – use `import type { UseCallsStatusReturnType } from 'wagmi'` instead. */ + type UseCallsStatusReturnType, + /** @deprecated This is no longer experimental – use `import { useCallsStatus } from 'wagmi'` instead. */ + useCallsStatus, +} from '../hooks/useCallsStatus.js' + +export { + /** @deprecated This is no longer experimental – use `import type { UseCapabilitiesParameters } from 'wagmi'` instead. */ + type UseCapabilitiesParameters, + /** @deprecated This is no longer experimental – use `import type { UseCapabilitiesReturnType } from 'wagmi'` instead. */ + type UseCapabilitiesReturnType, + /** @deprecated This is no longer experimental – use `import { useCapabilities } from 'wagmi'` instead. */ + useCapabilities, +} from '../hooks/useCapabilities.js' + +export { + /** @deprecated This is no longer experimental – use `import type { UseSendCallsParameters } from 'wagmi'` instead. */ + type UseSendCallsParameters, + /** @deprecated This is no longer experimental – use `import type { UseSendCallsReturnType } from 'wagmi'` instead. */ + type UseSendCallsReturnType, + /** @deprecated This is no longer experimental – use `import { useSendCalls } from 'wagmi'` instead. */ + useSendCalls, +} from '../hooks/useSendCalls.js' + +export { + /** @deprecated This is no longer experimental – use `import type { UseShowCallsStatusParameters } from 'wagmi'` instead. */ + type UseShowCallsStatusParameters, + /** @deprecated This is no longer experimental – use `import type { UseShowCallsStatusReturnType } from 'wagmi'` instead. */ + type UseShowCallsStatusReturnType, + /** @deprecated This is no longer experimental – use `import { useShowCallsStatus } from 'wagmi'` instead. */ + useShowCallsStatus, +} from '../hooks/useShowCallsStatus.js' + +export { + /** @deprecated This is no longer experimental – use `import type { UseWaitForCallsStatusParameters } from 'wagmi'` instead. */ + type UseWaitForCallsStatusParameters, + /** @deprecated This is no longer experimental – use `import type { UseWaitForCallsStatusReturnType } from 'wagmi'` instead. */ + type UseWaitForCallsStatusReturnType, + /** @deprecated This is no longer experimental – use `import { useWaitForCallsStatus } from 'wagmi'` instead. */ + useWaitForCallsStatus, +} from '../hooks/useWaitForCallsStatus.js' + +export { + /** @deprecated Use `UseSendCallsParameters` instead. */ + type UseWriteContractsParameters, + /** @deprecated Use `UseSendCallsReturnType` instead. */ + type UseWriteContractsReturnType, + /** @deprecated Use `useSendCalls` instead. */ + useWriteContracts, +} from '../experimental/hooks/useWriteContracts.js' diff --git a/wagmi-project/packages/react/src/exports/index.test.ts b/wagmi-project/packages/react/src/exports/index.test.ts new file mode 100644 index 0000000000..d8d6f7c6d5 --- /dev/null +++ b/wagmi-project/packages/react/src/exports/index.test.ts @@ -0,0 +1,111 @@ +import { expect, test } from 'vitest' + +import * as react from './index.js' + +test('exports', () => { + expect(Object.keys(react)).toMatchInlineSnapshot(` + [ + "WagmiContext", + "WagmiProvider", + "Context", + "WagmiConfig", + "BaseError", + "WagmiProviderNotFoundError", + "useAccount", + "useAccountEffect", + "useBalance", + "useBlock", + "useBlockNumber", + "useBlockTransactionCount", + "useBytecode", + "useCallsStatus", + "useCapabilities", + "useCall", + "useChainId", + "useChains", + "useClient", + "useConfig", + "useConnect", + "useConnections", + "useConnectors", + "useConnectorClient", + "useDeployContract", + "useDisconnect", + "useEnsAddress", + "useEnsAvatar", + "useEnsName", + "useEnsResolver", + "useEnsText", + "useEstimateFeesPerGas", + "useFeeData", + "useEstimateGas", + "useEstimateMaxPriorityFeePerGas", + "useFeeHistory", + "useGasPrice", + "useInfiniteReadContracts", + "useContractInfiniteReads", + "usePrepareTransactionRequest", + "useProof", + "usePublicClient", + "useReadContract", + "useContractRead", + "useReadContracts", + "useContractReads", + "useReconnect", + "useSendCalls", + "useSendTransaction", + "useShowCallsStatus", + "useSignMessage", + "useSignTypedData", + "useSimulateContract", + "useStorageAt", + "useSwitchAccount", + "useSwitchChain", + "useToken", + "useTransaction", + "useTransactionConfirmations", + "useTransactionCount", + "useTransactionReceipt", + "useVerifyMessage", + "useVerifyTypedData", + "useWalletClient", + "useWaitForCallsStatus", + "useWaitForTransactionReceipt", + "useWatchAsset", + "useWatchBlocks", + "useWatchBlockNumber", + "useWatchContractEvent", + "useWatchPendingTransactions", + "useWriteContract", + "useContractWrite", + "Hydrate", + "createConfig", + "createConnector", + "injected", + "mock", + "ChainNotConfiguredError", + "ConnectorAlreadyConnectedError", + "ConnectorNotFoundError", + "ConnectorAccountNotFoundError", + "ConnectorChainMismatchError", + "ConnectorUnavailableReconnectingError", + "ProviderNotFoundError", + "SwitchChainNotSupportedError", + "createStorage", + "noopStorage", + "custom", + "fallback", + "http", + "webSocket", + "unstable_connector", + "cookieStorage", + "cookieToInitialState", + "deepEqual", + "deserialize", + "normalizeChainId", + "parseCookie", + "serialize", + "version", + ] + `) +}) diff --git a/wagmi-project/packages/react/src/exports/index.ts b/wagmi-project/packages/react/src/exports/index.ts new file mode 100644 index 0000000000..a4b8502982 --- /dev/null +++ b/wagmi-project/packages/react/src/exports/index.ts @@ -0,0 +1,487 @@ +//////////////////////////////////////////////////////////////////////////////// +// Context +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +export { + type WagmiProviderProps, + WagmiContext, + WagmiProvider, + /** @deprecated Use `WagmiContext` instead */ + WagmiContext as Context, + /** @deprecated Use `WagmiProvider` instead */ + WagmiProvider as WagmiConfig, +} from '../context.js' + +//////////////////////////////////////////////////////////////////////////////// +// Errors +//////////////////////////////////////////////////////////////////////////////// + +export { type BaseErrorType, BaseError } from '../errors/base.js' + +export { + type WagmiProviderNotFoundErrorType, + WagmiProviderNotFoundError, +} from '../errors/context.js' + +//////////////////////////////////////////////////////////////////////////////// +// Hooks +//////////////////////////////////////////////////////////////////////////////// + +export { + type UseAccountParameters, + type UseAccountReturnType, + useAccount, +} from '../hooks/useAccount.js' + +export { + type UseAccountEffectParameters, + useAccountEffect, +} from '../hooks/useAccountEffect.js' + +export { + type UseBalanceParameters, + type UseBalanceReturnType, + useBalance, +} from '../hooks/useBalance.js' + +export { + type UseBlockParameters, + type UseBlockReturnType, + useBlock, +} from '../hooks/useBlock.js' + +export { + type UseBlockNumberParameters, + type UseBlockNumberReturnType, + useBlockNumber, +} from '../hooks/useBlockNumber.js' + +export { + type UseBlockTransactionCountParameters, + type UseBlockTransactionCountReturnType, + useBlockTransactionCount, +} from '../hooks/useBlockTransactionCount.js' + +export { + type UseBytecodeParameters, + type UseBytecodeReturnType, + useBytecode, +} from '../hooks/useBytecode.js' + +export { + type UseCallsStatusParameters, + type UseCallsStatusReturnType, + useCallsStatus, +} from '../hooks/useCallsStatus.js' + +export { + type UseCapabilitiesParameters, + type UseCapabilitiesReturnType, + useCapabilities, +} from '../hooks/useCapabilities.js' + +export { + type UseCallParameters, + type UseCallReturnType, + useCall, +} from '../hooks/useCall.js' + +export { + type UseChainIdParameters, + type UseChainIdReturnType, + useChainId, +} from '../hooks/useChainId.js' + +export { + type UseChainsParameters, + type UseChainsReturnType, + useChains, +} from '../hooks/useChains.js' + +export { + type UseClientParameters, + type UseClientReturnType, + useClient, +} from '../hooks/useClient.js' + +export { + type UseConfigParameters, + type UseConfigReturnType, + useConfig, +} from '../hooks/useConfig.js' + +export { + type UseConnectParameters, + type UseConnectReturnType, + useConnect, +} from '../hooks/useConnect.js' + +export { + type UseConnectionsParameters, + type UseConnectionsReturnType, + useConnections, +} from '../hooks/useConnections.js' + +export { + type UseConnectorsParameters, + type UseConnectorsReturnType, + useConnectors, +} from '../hooks/useConnectors.js' + +export { + type UseConnectorClientParameters, + type UseConnectorClientReturnType, + useConnectorClient, +} from '../hooks/useConnectorClient.js' + +export { + type UseDeployContractParameters, + type UseDeployContractReturnType, + useDeployContract, +} from '../hooks/useDeployContract.js' + +export { + type UseDisconnectParameters, + type UseDisconnectReturnType, + useDisconnect, +} from '../hooks/useDisconnect.js' + +export { + type UseEnsAddressParameters, + type UseEnsAddressReturnType, + useEnsAddress, +} from '../hooks/useEnsAddress.js' + +export { + type UseEnsAvatarParameters, + type UseEnsAvatarReturnType, + useEnsAvatar, +} from '../hooks/useEnsAvatar.js' + +export { + type UseEnsNameParameters, + type UseEnsNameReturnType, + useEnsName, +} from '../hooks/useEnsName.js' + +export { + type UseEnsResolverParameters, + type UseEnsResolverReturnType, + useEnsResolver, +} from '../hooks/useEnsResolver.js' + +export { + type UseEnsTextParameters, + type UseEnsTextReturnType, + useEnsText, +} from '../hooks/useEnsText.js' + +export { + type UseEstimateFeesPerGasParameters, + type UseEstimateFeesPerGasReturnType, + useEstimateFeesPerGas, + /** @deprecated Use `useEstimateFeesPerGas` instead */ + useEstimateFeesPerGas as useFeeData, +} from '../hooks/useEstimateFeesPerGas.js' + +export { + type UseEstimateGasParameters, + type UseEstimateGasReturnType, + useEstimateGas, +} from '../hooks/useEstimateGas.js' + +export { + type UseEstimateMaxPriorityFeePerGasParameters, + type UseEstimateMaxPriorityFeePerGasReturnType, + useEstimateMaxPriorityFeePerGas, +} from '../hooks/useEstimateMaxPriorityFeePerGas.js' + +export { + type UseFeeHistoryParameters, + type UseFeeHistoryReturnType, + useFeeHistory, +} from '../hooks/useFeeHistory.js' + +export { + type UseGasPriceParameters, + type UseGasPriceReturnType, + useGasPrice, +} from '../hooks/useGasPrice.js' + +export { + type UseInfiniteContractReadsParameters, + type UseInfiniteContractReadsReturnType, + useInfiniteReadContracts, + /** @deprecated Use `useInfiniteReadContracts` instead */ + useInfiniteReadContracts as useContractInfiniteReads, +} from '../hooks/useInfiniteReadContracts.js' + +export { + type UsePrepareTransactionRequestParameters, + type UsePrepareTransactionRequestReturnType, + usePrepareTransactionRequest, +} from '../hooks/usePrepareTransactionRequest.js' + +export { + type UseProofParameters, + type UseProofReturnType, + useProof, +} from '../hooks/useProof.js' + +export { + type UsePublicClientParameters, + type UsePublicClientReturnType, + usePublicClient, +} from '../hooks/usePublicClient.js' + +export { + type UseReadContractParameters, + type UseReadContractReturnType, + useReadContract, + /** @deprecated Use `useWriteContract` instead */ + useReadContract as useContractRead, +} from '../hooks/useReadContract.js' + +export { + type UseReadContractsParameters, + type UseReadContractsReturnType, + useReadContracts, + /** @deprecated Use `useWriteContract` instead */ + useReadContracts as useContractReads, +} from '../hooks/useReadContracts.js' + +export { + type UseReconnectParameters, + type UseReconnectReturnType, + useReconnect, +} from '../hooks/useReconnect.js' + +export { + type UseSendCallsParameters, + type UseSendCallsReturnType, + useSendCalls, +} from '../hooks/useSendCalls.js' + +export { + type UseSendTransactionParameters, + type UseSendTransactionReturnType, + useSendTransaction, +} from '../hooks/useSendTransaction.js' + +export { + type UseShowCallsStatusParameters, + type UseShowCallsStatusReturnType, + useShowCallsStatus, +} from '../hooks/useShowCallsStatus.js' + +export { + type UseSignMessageParameters, + type UseSignMessageReturnType, + useSignMessage, +} from '../hooks/useSignMessage.js' + +export { + type UseSignTypedDataParameters, + type UseSignTypedDataReturnType, + useSignTypedData, +} from '../hooks/useSignTypedData.js' + +export { + type UseSimulateContractParameters, + type UseSimulateContractReturnType, + useSimulateContract, +} from '../hooks/useSimulateContract.js' + +export { + type UseStorageAtParameters, + type UseStorageAtReturnType, + useStorageAt, +} from '../hooks/useStorageAt.js' + +export { + type UseSwitchAccountParameters, + type UseSwitchAccountReturnType, + useSwitchAccount, +} from '../hooks/useSwitchAccount.js' + +export { + type UseSwitchChainParameters, + type UseSwitchChainReturnType, + useSwitchChain, +} from '../hooks/useSwitchChain.js' + +export { + type UseTokenParameters, + type UseTokenReturnType, + /** @deprecated Use `useReadContracts` instead */ + useToken, +} from '../hooks/useToken.js' + +export { + type UseTransactionParameters, + type UseTransactionReturnType, + useTransaction, +} from '../hooks/useTransaction.js' + +export { + type UseTransactionConfirmationsParameters, + type UseTransactionConfirmationsReturnType, + useTransactionConfirmations, +} from '../hooks/useTransactionConfirmations.js' + +export { + type UseTransactionCountParameters, + type UseTransactionCountReturnType, + useTransactionCount, +} from '../hooks/useTransactionCount.js' + +export { + type UseTransactionReceiptParameters, + type UseTransactionReceiptReturnType, + useTransactionReceipt, +} from '../hooks/useTransactionReceipt.js' + +export { + type UseVerifyMessageParameters, + type UseVerifyMessageReturnType, + useVerifyMessage, +} from '../hooks/useVerifyMessage.js' + +export { + type UseVerifyTypedDataParameters, + type UseVerifyTypedDataReturnType, + useVerifyTypedData, +} from '../hooks/useVerifyTypedData.js' + +export { + type UseWalletClientParameters, + type UseWalletClientReturnType, + useWalletClient, +} from '../hooks/useWalletClient.js' + +export { + type UseWaitForCallsStatusParameters, + type UseWaitForCallsStatusReturnType, + useWaitForCallsStatus, +} from '../hooks/useWaitForCallsStatus.js' + +export { + type UseWaitForTransactionReceiptParameters, + type UseWaitForTransactionReceiptReturnType, + useWaitForTransactionReceipt, +} from '../hooks/useWaitForTransactionReceipt.js' + +export { + type UseWatchAssetParameters, + type UseWatchAssetReturnType, + useWatchAsset, +} from '../hooks/useWatchAsset.js' + +export { + type UseWatchBlocksParameters, + type UseWatchBlocksReturnType, + useWatchBlocks, +} from '../hooks/useWatchBlocks.js' + +export { + type UseWatchBlockNumberParameters, + type UseWatchBlockNumberReturnType, + useWatchBlockNumber, +} from '../hooks/useWatchBlockNumber.js' + +export { + type UseWatchContractEventParameters, + type UseWatchContractEventReturnType, + useWatchContractEvent, +} from '../hooks/useWatchContractEvent.js' + +export { + type UseWatchPendingTransactionsParameters, + type UseWatchPendingTransactionsReturnType, + useWatchPendingTransactions, +} from '../hooks/useWatchPendingTransactions.js' + +export { + type UseWriteContractParameters, + type UseWriteContractReturnType, + useWriteContract, + /** @deprecated Use `useWriteContract` instead */ + useWriteContract as useContractWrite, +} from '../hooks/useWriteContract.js' + +//////////////////////////////////////////////////////////////////////////////// +// Hydrate +//////////////////////////////////////////////////////////////////////////////// + +export { + type HydrateProps, + Hydrate, +} from '../hydrate.js' + +//////////////////////////////////////////////////////////////////////////////// +// @wagmi/core +//////////////////////////////////////////////////////////////////////////////// + +export { + // Config + type Connection, + type Connector, + type Config, + type CreateConfigParameters, + type PartializedState, + type State, + createConfig, + // Connector + type ConnectorEventMap, + type CreateConnectorFn, + createConnector, + injected, + mock, + // Errors + type ChainNotConfiguredErrorType, + ChainNotConfiguredError, + type ConnectorAlreadyConnectedErrorType, + ConnectorAlreadyConnectedError, + type ConnectorNotFoundErrorType, + ConnectorNotFoundError, + type ConnectorAccountNotFoundErrorType, + ConnectorAccountNotFoundError, + type ConnectorChainMismatchErrorType, + ConnectorChainMismatchError, + type ConnectorUnavailableReconnectingErrorType, + ConnectorUnavailableReconnectingError, + type ProviderNotFoundErrorType, + ProviderNotFoundError, + type SwitchChainNotSupportedErrorType, + SwitchChainNotSupportedError, + // Storage + type CreateStorageParameters, + type Storage, + createStorage, + noopStorage, + // Transports + custom, + fallback, + http, + webSocket, + unstable_connector, + type Transport, + // Types + type Register, + type ResolvedRegister, + // Utilities + cookieStorage, + cookieToInitialState, + deepEqual, + deserialize, + normalizeChainId, + parseCookie, + serialize, +} from '@wagmi/core' + +//////////////////////////////////////////////////////////////////////////////// +// Version +//////////////////////////////////////////////////////////////////////////////// + +export { version } from '../version.js' diff --git a/wagmi-project/packages/react/src/exports/query.test.ts b/wagmi-project/packages/react/src/exports/query.test.ts new file mode 100644 index 0000000000..002b6abaab --- /dev/null +++ b/wagmi-project/packages/react/src/exports/query.test.ts @@ -0,0 +1,100 @@ +import { expect, test } from 'vitest' + +import * as query from './query.js' + +test('exports', () => { + expect(Object.keys(query)).toMatchInlineSnapshot(` + [ + "callQueryKey", + "callQueryOptions", + "connectMutationOptions", + "deployContractMutationOptions", + "disconnectMutationOptions", + "estimateFeesPerGasQueryKey", + "estimateFeesPerGasQueryOptions", + "estimateGasQueryKey", + "estimateGasQueryOptions", + "estimateMaxPriorityFeePerGasQueryKey", + "estimateMaxPriorityFeePerGasQueryOptions", + "getBalanceQueryKey", + "getBalanceQueryOptions", + "getBlockQueryKey", + "getBlockQueryOptions", + "getBlockNumberQueryKey", + "getBlockNumberQueryOptions", + "getBlockTransactionCountQueryKey", + "getBlockTransactionCountQueryOptions", + "getBytecodeQueryKey", + "getBytecodeQueryOptions", + "getCallsStatusQueryKey", + "getCallsStatusQueryOptions", + "getCapabilitiesQueryKey", + "getCapabilitiesQueryOptions", + "getConnectorClientQueryKey", + "getConnectorClientQueryOptions", + "getEnsAddressQueryKey", + "getEnsAddressQueryOptions", + "getEnsAvatarQueryKey", + "getEnsAvatarQueryOptions", + "getEnsNameQueryKey", + "getEnsNameQueryOptions", + "getEnsResolverQueryKey", + "getEnsResolverQueryOptions", + "getEnsTextQueryKey", + "getEnsTextQueryOptions", + "getFeeHistoryQueryKey", + "getFeeHistoryQueryOptions", + "getGasPriceQueryKey", + "getGasPriceQueryOptions", + "getProofQueryKey", + "getProofQueryOptions", + "getStorageAtQueryKey", + "getStorageAtQueryOptions", + "getTokenQueryKey", + "getTokenQueryOptions", + "getTransactionQueryKey", + "getTransactionQueryOptions", + "getTransactionConfirmationsQueryKey", + "getTransactionConfirmationsQueryOptions", + "getTransactionCountQueryKey", + "getTransactionCountQueryOptions", + "getTransactionReceiptQueryKey", + "getTransactionReceiptQueryOptions", + "getWalletClientQueryKey", + "getWalletClientQueryOptions", + "infiniteReadContractsQueryKey", + "infiniteReadContractsQueryOptions", + "prepareTransactionRequestQueryKey", + "prepareTransactionRequestQueryOptions", + "readContractQueryKey", + "readContractQueryOptions", + "readContractsQueryKey", + "readContractsQueryOptions", + "reconnectMutationOptions", + "sendCallsMutationOptions", + "showCallsStatusMutationOptions", + "sendTransactionMutationOptions", + "signMessageMutationOptions", + "signTypedDataMutationOptions", + "switchAccountMutationOptions", + "simulateContractQueryKey", + "simulateContractQueryOptions", + "switchChainMutationOptions", + "verifyMessageQueryKey", + "verifyMessageQueryOptions", + "verifyTypedDataQueryKey", + "verifyTypedDataQueryOptions", + "waitForCallsStatusQueryKey", + "waitForCallsStatusQueryOptions", + "waitForTransactionReceiptQueryKey", + "waitForTransactionReceiptQueryOptions", + "watchAssetMutationOptions", + "writeContractMutationOptions", + "hashFn", + "structuralSharing", + "useInfiniteQuery", + "useMutation", + "useQuery", + ] + `) +}) diff --git a/wagmi-project/packages/react/src/exports/query.ts b/wagmi-project/packages/react/src/exports/query.ts new file mode 100644 index 0000000000..ff91fee2d9 --- /dev/null +++ b/wagmi-project/packages/react/src/exports/query.ts @@ -0,0 +1,19 @@ +//////////////////////////////////////////////////////////////////////////////// +// @wagmi/core/query +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +// biome-ignore lint/performance/noReExportAll: entrypoint module +export * from '@wagmi/core/query' + +export { + type UseInfiniteQueryParameters, + type UseInfiniteQueryReturnType, + type UseMutationParameters, + type UseMutationReturnType, + type UseQueryParameters, + type UseQueryReturnType, + useInfiniteQuery, + useMutation, + useQuery, +} from '../utils/query.js' diff --git a/wagmi-project/packages/react/src/hooks/codegen/createUseReadContract.test-d.ts b/wagmi-project/packages/react/src/hooks/codegen/createUseReadContract.test-d.ts new file mode 100644 index 0000000000..f0331efed2 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/codegen/createUseReadContract.test-d.ts @@ -0,0 +1,152 @@ +import { abi, mainnet, optimism } from '@wagmi/test' +import { assertType, expectTypeOf, test } from 'vitest' + +import { createUseReadContract } from './createUseReadContract.js' + +test('default', () => { + const useReadErc20 = createUseReadContract({ + abi: abi.erc20, + }) + + const result = useReadErc20({ + functionName: 'balanceOf', + args: ['0x'], + chainId: 123, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) + +test('select data', () => { + const useReadErc20 = createUseReadContract({ + abi: abi.erc20, + }) + + const result = useReadErc20({ + address: '0x', + functionName: 'balanceOf', + args: ['0x'], + query: { + select(data) { + expectTypeOf(data).toEqualTypeOf() + return data?.toString() + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) + +test('multichain address', () => { + const useReadErc20 = createUseReadContract({ + abi: abi.erc20, + address: { + [mainnet.id]: '0x', + [optimism.id]: '0x', + }, + }) + + const result = useReadErc20({ + functionName: 'balanceOf', + args: ['0x'], + chainId: mainnet.id, + // ^? + }) + assertType(result.data) + + useReadErc20({ + functionName: 'balanceOf', + args: ['0x'], + // @ts-expect-error chain id must match address keys + chainId: 420, + }) + + useReadErc20({ + functionName: 'balanceOf', + args: ['0x'], + // @ts-expect-error address not allowed + address: '0x', + }) +}) + +test('overloads', () => { + const useReadViewOverloads = createUseReadContract({ + abi: abi.viewOverloads, + }) + + const result1 = useReadViewOverloads({ + functionName: 'foo', + }) + assertType(result1.data) + + const result2 = useReadViewOverloads({ + functionName: 'foo', + args: [], + }) + assertType(result2.data) + + const result3 = useReadViewOverloads({ + functionName: 'foo', + args: ['0x'], + }) + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + assertType(result3.data) + + const result4 = useReadViewOverloads({ + functionName: 'foo', + args: ['0x', '0x'], + }) + assertType< + | { + foo: `0x${string}` + bar: `0x${string}` + } + | undefined + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + >(result4.data) +}) + +test('functionName', () => { + const useReadErc20BalanceOf = createUseReadContract({ + abi: abi.erc20, + address: '0x', + functionName: 'balanceOf', + }) + + const result = useReadErc20BalanceOf({ + args: ['0x'], + chainId: 1, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) + +test('functionName with overloads', () => { + const useReadViewOverloads = createUseReadContract({ + abi: abi.viewOverloads, + functionName: 'foo', + }) + + const result1 = useReadViewOverloads() + assertType(result1.data) + + const result2 = useReadViewOverloads({ + args: [], + }) + assertType(result2.data) + + const result3 = useReadViewOverloads({ + args: ['0x'], + }) + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + assertType(result3.data) + + const result4 = useReadViewOverloads({ + args: ['0x', '0x'], + }) + assertType< + | { + foo: `0x${string}` + bar: `0x${string}` + } + | undefined + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + >(result4.data) +}) diff --git a/wagmi-project/packages/react/src/hooks/codegen/createUseReadContract.test.ts b/wagmi-project/packages/react/src/hooks/codegen/createUseReadContract.test.ts new file mode 100644 index 0000000000..4419c030c5 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/codegen/createUseReadContract.test.ts @@ -0,0 +1,177 @@ +import { abi, address, chain } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { createUseReadContract } from './createUseReadContract.js' + +test('default', async () => { + const useReadWagmiMintExample = createUseReadContract({ + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + }) + + const { result } = renderHook(() => + useReadWagmiMintExample({ + functionName: 'balanceOf', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": 4n, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "readContract", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": [ + "0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC", + ], + "chainId": 1, + "functionName": "balanceOf", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('multichain', async () => { + const useReadWagmiMintExample = createUseReadContract({ + address: { + [chain.mainnet.id]: address.wagmiMintExample, + [chain.mainnet2.id]: address.wagmiMintExample, + }, + abi: abi.wagmiMintExample, + }) + + const { result } = renderHook(() => + useReadWagmiMintExample({ + functionName: 'balanceOf', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + chainId: chain.mainnet2.id, + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": 4n, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "readContract", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": [ + "0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC", + ], + "chainId": 456, + "functionName": "balanceOf", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('functionName', async () => { + const useReadWagmiMintExampleBalanceOf = createUseReadContract({ + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'balanceOf', + }) + + const { result } = renderHook(() => + useReadWagmiMintExampleBalanceOf({ + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": 4n, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "readContract", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": [ + "0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC", + ], + "chainId": 1, + "functionName": "balanceOf", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) diff --git a/wagmi-project/packages/react/src/hooks/codegen/createUseReadContract.ts b/wagmi-project/packages/react/src/hooks/codegen/createUseReadContract.ts new file mode 100644 index 0000000000..1c5f509e58 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/codegen/createUseReadContract.ts @@ -0,0 +1,127 @@ +import type { + Config, + ReadContractErrorType, + ReadContractParameters, + ResolvedRegister, +} from '@wagmi/core' +import type { + ScopeKeyParameter, + UnionCompute, + UnionExactPartial, + UnionStrictOmit, +} from '@wagmi/core/internal' +import type { + ReadContractData, + ReadContractQueryFnData, + ReadContractQueryKey, +} from '@wagmi/core/query' +import type { + Abi, + Address, + ContractFunctionArgs, + ContractFunctionName, +} from 'viem' + +import type { ConfigParameter, QueryParameter } from '../../types/properties.js' +import { useAccount } from '../useAccount.js' +import { useChainId } from '../useChainId.js' +import { useConfig } from '../useConfig.js' +import { + type UseReadContractReturnType, + useReadContract, +} from '../useReadContract.js' + +type stateMutability = 'pure' | 'view' + +export type CreateUseReadContractParameters< + abi extends Abi | readonly unknown[], + address extends Address | Record | undefined = undefined, + functionName extends + | ContractFunctionName + | undefined = undefined, +> = { + abi: abi | Abi | readonly unknown[] + address?: address | Address | Record | undefined + functionName?: + | functionName + | ContractFunctionName + | undefined +} + +export type CreateUseReadContractReturnType< + abi extends Abi | readonly unknown[], + address extends Address | Record | undefined, + functionName extends ContractFunctionName | undefined, + /// + omittedProperties extends 'abi' | 'address' | 'chainId' | 'functionName' = + | 'abi' + | (address extends undefined ? never : 'address') + | (address extends Record ? 'chainId' : never) + | (functionName extends undefined ? never : 'functionName'), +> = < + name extends functionName extends ContractFunctionName + ? functionName + : ContractFunctionName, + args extends ContractFunctionArgs, + config extends Config = ResolvedRegister['config'], + selectData = ReadContractData, +>( + parameters?: UnionCompute< + UnionExactPartial< + UnionStrictOmit< + ReadContractParameters, + omittedProperties + > + > & + ScopeKeyParameter & + ConfigParameter & + QueryParameter< + ReadContractQueryFnData, + ReadContractErrorType, + selectData, + ReadContractQueryKey + > + > & + (address extends Record + ? { chainId?: keyof address | undefined } + : unknown), +) => UseReadContractReturnType + +export function createUseReadContract< + const abi extends Abi | readonly unknown[], + const address extends + | Address + | Record + | undefined = undefined, + functionName extends + | ContractFunctionName + | undefined = undefined, +>( + props: CreateUseReadContractParameters, +): CreateUseReadContractReturnType { + if (props.address !== undefined && typeof props.address === 'object') + return (parameters) => { + const config = useConfig(parameters) + const configChainId = useChainId({ config }) + const account = useAccount({ config }) + const chainId = + (parameters as { chainId?: number })?.chainId ?? + account.chainId ?? + configChainId + return useReadContract({ + ...(parameters as any), + ...(props.functionName ? { functionName: props.functionName } : {}), + address: props.address?.[chainId], + abi: props.abi, + }) + } + + return (parameters) => { + return useReadContract({ + ...(parameters as any), + ...(props.address ? { address: props.address } : {}), + ...(props.functionName ? { functionName: props.functionName } : {}), + abi: props.abi, + }) + } +} diff --git a/wagmi-project/packages/react/src/hooks/codegen/createUseSimulateContract.test-d.ts b/wagmi-project/packages/react/src/hooks/codegen/createUseSimulateContract.test-d.ts new file mode 100644 index 0000000000..5388e69109 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/codegen/createUseSimulateContract.test-d.ts @@ -0,0 +1,199 @@ +import { abi, mainnet, optimism } from '@wagmi/test' +import type { Address } from 'viem' +import { assertType, expectTypeOf, test } from 'vitest' + +import { createUseSimulateContract } from './createUseSimulateContract.js' + +test('default', () => { + const useSimulateErc20 = createUseSimulateContract({ + abi: abi.erc20, + }) + + const result = useSimulateErc20({ + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + chainId: 123, + }) + result.data?.request.chainId + expectTypeOf(result.data).toMatchTypeOf< + | { + result: boolean + request: { + chainId: 123 + abi: readonly [ + { + readonly name: 'transferFrom' + readonly type: 'function' + readonly stateMutability: 'nonpayable' + readonly inputs: readonly [ + { readonly type: 'address'; readonly name: 'sender' }, + { readonly type: 'address'; readonly name: 'recipient' }, + { readonly type: 'uint256'; readonly name: 'amount' }, + ] + readonly outputs: readonly [{ type: 'bool' }] + }, + ] + functionName: 'transferFrom' + args: readonly [Address, Address, bigint] + } + } + | undefined + >() +}) + +test('select data', () => { + const useSimulateErc20 = createUseSimulateContract({ + abi: abi.erc20, + }) + + const result = useSimulateErc20({ + address: '0x', + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + query: { + select(data) { + expectTypeOf(data.result).toEqualTypeOf() + return data?.toString() + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) + +test('multichain address', () => { + const useSimulateErc20 = createUseSimulateContract({ + abi: abi.erc20, + address: { + [mainnet.id]: '0x', + [optimism.id]: '0x', + }, + }) + + const result = useSimulateErc20({ + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + chainId: optimism.id, + }) + expectTypeOf(result.data?.result).toEqualTypeOf() + + useSimulateErc20({ + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + // @ts-expect-error chain id must match address keys + chainId: 420, + }) + + useSimulateErc20({ + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + // @ts-expect-error address not allowed + address: '0x', + }) +}) + +test('overloads', () => { + const useSimulateWriteOverloads = createUseSimulateContract({ + abi: abi.writeOverloads, + }) + + const result1 = useSimulateWriteOverloads({ + functionName: 'foo', + }) + assertType(result1.data?.result) + + const result2 = useSimulateWriteOverloads({ + functionName: 'foo', + args: [], + }) + assertType(result2.data?.result) + + const result3 = useSimulateWriteOverloads({ + functionName: 'foo', + args: ['0x'], + }) + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + assertType(result3.data?.result) + + const result4 = useSimulateWriteOverloads({ + functionName: 'foo', + args: ['0x', '0x'], + }) + assertType< + | { + foo: `0x${string}` + bar: `0x${string}` + } + | undefined + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + >(result4.data?.result) +}) + +test('functionName', () => { + const useSimulateErc20 = createUseSimulateContract({ + abi: abi.erc20, + functionName: 'transferFrom', + }) + + const result = useSimulateErc20({ + args: ['0x', '0x', 123n], + chainId: 123, + }) + result.data?.request.chainId + expectTypeOf(result.data).toMatchTypeOf< + | { + result: boolean + request: { + chainId: 123 + abi: readonly [ + { + readonly name: 'transferFrom' + readonly type: 'function' + readonly stateMutability: 'nonpayable' + readonly inputs: readonly [ + { readonly type: 'address'; readonly name: 'sender' }, + { readonly type: 'address'; readonly name: 'recipient' }, + { readonly type: 'uint256'; readonly name: 'amount' }, + ] + readonly outputs: readonly [{ type: 'bool' }] + }, + ] + functionName: 'transferFrom' + args: readonly [Address, Address, bigint] + } + } + | undefined + >() +}) + +test('functionName with overloads', () => { + const useSimulateWriteOverloads = createUseSimulateContract({ + abi: abi.writeOverloads, + functionName: 'foo', + }) + + const result1 = useSimulateWriteOverloads({}) + assertType(result1.data?.result) + + const result2 = useSimulateWriteOverloads({ + args: [], + }) + assertType(result2.data?.result) + + const result3 = useSimulateWriteOverloads({ + args: ['0x'], + }) + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + assertType(result3.data?.result) + + const result4 = useSimulateWriteOverloads({ + args: ['0x', '0x'], + }) + assertType< + | { + foo: `0x${string}` + bar: `0x${string}` + } + | undefined + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + >(result4.data?.result) +}) diff --git a/wagmi-project/packages/react/src/hooks/codegen/createUseSimulateContract.test.ts b/wagmi-project/packages/react/src/hooks/codegen/createUseSimulateContract.test.ts new file mode 100644 index 0000000000..c6e70b90ca --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/codegen/createUseSimulateContract.test.ts @@ -0,0 +1,258 @@ +import { connect, disconnect } from '@wagmi/core' +import { abi, address, chain, config } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { createUseSimulateContract } from './createUseSimulateContract.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const useSimulateWagmiMintExample = createUseSimulateContract({ + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + }) + + const { result } = renderHook(() => + useSimulateWagmiMintExample({ + functionName: 'mint', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "chainId": 1, + "request": { + "abi": [ + { + "inputs": [], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "account": { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "type": "json-rpc", + }, + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": undefined, + "chainId": 1, + "dataSuffix": undefined, + "functionName": "mint", + }, + "result": undefined, + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "simulateContract", + { + "account": { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "type": "json-rpc", + }, + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "chainId": 1, + "functionName": "mint", + }, + ], + "refetch": [Function], + "status": "success", + } + `) + + await disconnect(config, { connector }) +}) + +test('multichain', async () => { + await connect(config, { connector }) + + const useReadWagmiMintExample = createUseSimulateContract({ + address: { + [chain.mainnet.id]: address.wagmiMintExample, + [chain.mainnet2.id]: address.wagmiMintExample, + }, + abi: abi.wagmiMintExample, + }) + + const { result } = renderHook(() => + useReadWagmiMintExample({ + functionName: 'mint', + chainId: chain.mainnet2.id, + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "chainId": 456, + "request": { + "abi": [ + { + "inputs": [], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "account": { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "type": "json-rpc", + }, + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": undefined, + "chainId": 456, + "dataSuffix": undefined, + "functionName": "mint", + }, + "result": undefined, + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "simulateContract", + { + "account": { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "type": "json-rpc", + }, + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "chainId": 456, + "functionName": "mint", + }, + ], + "refetch": [Function], + "status": "success", + } + `) + + await disconnect(config, { connector }) +}) + +test('functionName', async () => { + await connect(config, { connector }) + + const useSimulateWagmiMintExample = createUseSimulateContract({ + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'mint', + }) + + const { result } = renderHook(() => useSimulateWagmiMintExample({})) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "chainId": 1, + "request": { + "abi": [ + { + "inputs": [], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "account": { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "type": "json-rpc", + }, + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": undefined, + "chainId": 1, + "dataSuffix": undefined, + "functionName": "mint", + }, + "result": undefined, + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "simulateContract", + { + "account": { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "type": "json-rpc", + }, + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "chainId": 1, + "functionName": "mint", + }, + ], + "refetch": [Function], + "status": "success", + } + `) + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/react/src/hooks/codegen/createUseSimulateContract.ts b/wagmi-project/packages/react/src/hooks/codegen/createUseSimulateContract.ts new file mode 100644 index 0000000000..51758b995a --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/codegen/createUseSimulateContract.ts @@ -0,0 +1,120 @@ +import type { + Config, + ResolvedRegister, + SimulateContractErrorType, + SimulateContractParameters, +} from '@wagmi/core' +import type { ScopeKeyParameter, UnionExactPartial } from '@wagmi/core/internal' +import type { + SimulateContractData, + SimulateContractQueryFnData, + SimulateContractQueryKey, +} from '@wagmi/core/query' +import type { + Abi, + Address, + ContractFunctionArgs, + ContractFunctionName, +} from 'viem' + +import type { ConfigParameter, QueryParameter } from '../../types/properties.js' +import { useAccount } from '../useAccount.js' +import { useChainId } from '../useChainId.js' +import { useConfig } from '../useConfig.js' +import { + type UseSimulateContractReturnType, + useSimulateContract, +} from '../useSimulateContract.js' + +type stateMutability = 'nonpayable' | 'payable' + +export type CreateUseSimulateContractParameters< + abi extends Abi | readonly unknown[], + address extends Address | Record | undefined = undefined, + functionName extends + | ContractFunctionName + | undefined = undefined, +> = { + abi: abi | Abi | readonly unknown[] + address?: address | Address | Record | undefined + functionName?: + | functionName + | ContractFunctionName + | undefined +} + +export type CreateUseSimulateContractReturnType< + abi extends Abi | readonly unknown[], + address extends Address | Record | undefined, + functionName extends ContractFunctionName | undefined, +> = < + name extends functionName extends ContractFunctionName + ? functionName + : ContractFunctionName, + args extends ContractFunctionArgs, + config extends Config = ResolvedRegister['config'], + chainId extends config['chains'][number]['id'] | undefined = undefined, + selectData = SimulateContractData, +>( + parameters?: { + abi?: undefined + address?: address extends undefined ? Address : undefined + functionName?: functionName extends undefined ? name : undefined + chainId?: address extends Record + ? + | keyof address + | (chainId extends keyof address ? chainId : never) + | undefined + : chainId | number | undefined + } & UnionExactPartial< + // TODO: Take `abi` and `address` from above and omit from below (currently breaks inference) + SimulateContractParameters + > & + ScopeKeyParameter & + ConfigParameter & + QueryParameter< + SimulateContractQueryFnData, + SimulateContractErrorType, + selectData, + SimulateContractQueryKey + >, +) => UseSimulateContractReturnType + +export function createUseSimulateContract< + const abi extends Abi | readonly unknown[], + const address extends + | Address + | Record + | undefined = undefined, + functionName extends + | ContractFunctionName + | undefined = undefined, +>( + props: CreateUseSimulateContractParameters, +): CreateUseSimulateContractReturnType { + if (props.address !== undefined && typeof props.address === 'object') + return (parameters) => { + const config = useConfig(parameters) + const configChainId = useChainId({ config }) + const account = useAccount({ config }) + const chainId = + (parameters as { chainId?: number })?.chainId ?? + account.chainId ?? + configChainId + return useSimulateContract({ + ...(parameters as any), + ...(props.functionName ? { functionName: props.functionName } : {}), + address: props.address?.[chainId], + abi: props.abi, + }) + } + + return (parameters) => { + return useSimulateContract({ + ...(parameters as any), + ...(props.address ? { address: props.address } : {}), + ...(props.functionName ? { functionName: props.functionName } : {}), + abi: props.abi, + }) + } +} diff --git a/wagmi-project/packages/react/src/hooks/codegen/createUseWatchContractEvent.test-d.ts b/wagmi-project/packages/react/src/hooks/codegen/createUseWatchContractEvent.test-d.ts new file mode 100644 index 0000000000..b3a69775b8 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/codegen/createUseWatchContractEvent.test-d.ts @@ -0,0 +1,123 @@ +import { http, createConfig, webSocket } from '@wagmi/core' +import { abi, mainnet, optimism } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { createUseWatchContractEvent } from './createUseWatchContractEvent.js' + +test('default', () => { + const useWatchErc20Event = createUseWatchContractEvent({ + abi: abi.erc20, + }) + + useWatchErc20Event({ + eventName: 'Transfer', + chainId: 123, + onLogs(logs) { + expectTypeOf(logs[0]!.eventName).toEqualTypeOf<'Transfer'>() + expectTypeOf(logs[0]!.args).toEqualTypeOf<{ + from?: `0x${string}` | undefined + to?: `0x${string}` | undefined + value?: bigint | undefined + }>() + }, + }) +}) + +test('multichain address', () => { + const useWatchErc20Event = createUseWatchContractEvent({ + abi: abi.erc20, + address: { + [mainnet.id]: '0x', + [optimism.id]: '0x', + }, + }) + + useWatchErc20Event({ + eventName: 'Transfer', + chainId: mainnet.id, + // ^? + }) + + useWatchErc20Event({ + eventName: 'Transfer', + // @ts-expect-error chain id must match address keys + chainId: 420, + }) + + useWatchErc20Event({ + eventName: 'Transfer', + // @ts-expect-error chain id must match address keys + address: '0x', + }) +}) + +test('differing transports', () => { + const useWatchErc20Event = createUseWatchContractEvent({ + abi: abi.erc20, + }) + + const config = createConfig({ + chains: [mainnet, optimism], + transports: { + [mainnet.id]: http(), + [optimism.id]: webSocket(), + }, + }) + + useWatchErc20Event({ + config, + poll: false, + address: '0x', + onLogs() {}, + }) + + useWatchErc20Event({ + config, + chainId: mainnet.id, + poll: true, + address: '0x', + onLogs() {}, + }) + useWatchErc20Event({ + config, + chainId: mainnet.id, + // @ts-expect-error poll required since http transport + poll: false, + address: '0x', + onLogs() {}, + }) + + useWatchErc20Event({ + config, + chainId: optimism.id, + poll: true, + address: '0x', + onLogs() {}, + }) + useWatchErc20Event({ + config, + chainId: optimism.id, + poll: false, + address: '0x', + onLogs() {}, + }) +}) + +test('eventName', () => { + const useWatchErc20Event = createUseWatchContractEvent({ + abi: abi.erc20, + eventName: 'Transfer', + }) + + useWatchErc20Event({ + chainId: 123, + onLogs(logs) { + expectTypeOf(logs[0]!.eventName).toEqualTypeOf<'Transfer'>() + expectTypeOf(logs[0]!.args).toEqualTypeOf<{ + from?: `0x${string}` | undefined + to?: `0x${string}` | undefined + value?: bigint | undefined + }>() + }, + }) +}) diff --git a/wagmi-project/packages/react/src/hooks/codegen/createUseWatchContractEvent.test.ts b/wagmi-project/packages/react/src/hooks/codegen/createUseWatchContractEvent.test.ts new file mode 100644 index 0000000000..61464fe3d2 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/codegen/createUseWatchContractEvent.test.ts @@ -0,0 +1,44 @@ +import { abi, address, chain } from '@wagmi/test' +import { renderHook } from '@wagmi/test/react' +import type { WatchEventOnLogsParameter } from 'viem' +import { test } from 'vitest' + +import { createUseWatchContractEvent } from './createUseWatchContractEvent.js' + +test('default', async () => { + const useWatchErc20Event = createUseWatchContractEvent({ + address: address.usdc, + abi: abi.wagmiMintExample, + }) + + let logs: WatchEventOnLogsParameter = [] + renderHook(() => + useWatchErc20Event({ + eventName: 'Transfer', + onLogs(next) { + logs = logs.concat(next) + }, + }), + ) +}) + +test('multichain', async () => { + const useWatchErc20Event = createUseWatchContractEvent({ + address: { + [chain.mainnet.id]: address.usdc, + [chain.mainnet2.id]: address.usdc, + }, + abi: abi.wagmiMintExample, + }) + + let logs: WatchEventOnLogsParameter = [] + renderHook(() => + useWatchErc20Event({ + eventName: 'Transfer', + chainId: chain.mainnet2.id, + onLogs(next) { + logs = logs.concat(next) + }, + }), + ) +}) diff --git a/wagmi-project/packages/react/src/hooks/codegen/createUseWatchContractEvent.ts b/wagmi-project/packages/react/src/hooks/codegen/createUseWatchContractEvent.ts new file mode 100644 index 0000000000..e453b9442b --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/codegen/createUseWatchContractEvent.ts @@ -0,0 +1,101 @@ +import type { + Config, + ResolvedRegister, + WatchContractEventParameters, +} from '@wagmi/core' +import type { + UnionCompute, + UnionExactPartial, + UnionStrictOmit, +} from '@wagmi/core/internal' +import type { Abi, Address, ContractEventName } from 'viem' + +import type { + ConfigParameter, + EnabledParameter, +} from '../../types/properties.js' +import { useAccount } from '../useAccount.js' +import { useChainId } from '../useChainId.js' +import { useConfig } from '../useConfig.js' +import { useWatchContractEvent } from '../useWatchContractEvent.js' + +export type CreateUseWatchContractEventParameters< + abi extends Abi | readonly unknown[], + address extends Address | Record | undefined = undefined, + eventName extends ContractEventName | undefined = undefined, +> = { + abi: abi | Abi | readonly unknown[] + address?: address | Address | Record | undefined + eventName?: eventName | ContractEventName | undefined +} + +export type CreateUseWatchContractEventReturnType< + abi extends Abi | readonly unknown[], + address extends Address | Record | undefined, + eventName extends ContractEventName | undefined, + /// + omittedProperties extends 'abi' | 'address' | 'chainId' | 'eventName' = + | 'abi' + | (address extends undefined ? never : 'address') + | (address extends Record ? 'chainId' : never) + | (eventName extends undefined ? never : 'eventName'), +> = < + name extends eventName extends ContractEventName + ? eventName + : ContractEventName, + strict extends boolean | undefined = undefined, + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +>( + parameters?: UnionCompute< + UnionExactPartial< + UnionStrictOmit< + WatchContractEventParameters, + omittedProperties + > + > & + ConfigParameter & + EnabledParameter + > & + (address extends Record + ? { chainId?: keyof address | undefined } + : unknown), +) => void + +export function createUseWatchContractEvent< + const abi extends Abi | readonly unknown[], + const address extends + | Address + | Record + | undefined = undefined, + eventName extends ContractEventName | undefined = undefined, +>( + props: CreateUseWatchContractEventParameters, +): CreateUseWatchContractEventReturnType { + if (props.address !== undefined && typeof props.address === 'object') + return (parameters) => { + const config = useConfig(parameters) + const configChainId = useChainId({ config }) + const account = useAccount({ config }) + const chainId = + (parameters as { chainId?: number })?.chainId ?? + account.chainId ?? + configChainId + return useWatchContractEvent({ + ...(parameters as any), + ...(props.eventName ? { eventName: props.eventName } : {}), + address: props.address?.[chainId], + abi: props.abi, + }) + } + + return (parameters) => { + return useWatchContractEvent({ + ...(parameters as any), + ...(props.address ? { address: props.address } : {}), + ...(props.eventName ? { eventName: props.eventName } : {}), + abi: props.abi, + }) + } +} diff --git a/wagmi-project/packages/react/src/hooks/codegen/createUseWriteContract.test-d.ts b/wagmi-project/packages/react/src/hooks/codegen/createUseWriteContract.test-d.ts new file mode 100644 index 0000000000..14906fda41 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/codegen/createUseWriteContract.test-d.ts @@ -0,0 +1,153 @@ +import { abi } from '@wagmi/test' +import type { Address, Hash } from 'viem' +import { mainnet, optimism } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { useSimulateContract } from '../useSimulateContract.js' +import { createUseWriteContract } from './createUseWriteContract.js' + +const contextValue = { foo: 'bar' } as const + +test('default', () => { + const useWriteErc20 = createUseWriteContract({ + abi: abi.erc20, + }) + + const { writeContract } = useWriteErc20() + writeContract({ + address: '0x', + functionName: 'transfer', + args: ['0x', 123n], + }) +}) + +test('context', () => { + const useWriteErc20 = createUseWriteContract({ + abi: abi.erc20, + }) + + const { writeContract } = useWriteErc20({ + mutation: { + onMutate() { + return contextValue + }, + onSuccess(data, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(variables.functionName).toEqualTypeOf() + expectTypeOf(variables.args).toEqualTypeOf< + readonly unknown[] | undefined + >() + expectTypeOf(context).toEqualTypeOf() + }, + }, + }) + + writeContract( + { + address: '0x', + functionName: 'transfer', + args: ['0x', 123n], + }, + { + onSuccess(data, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(variables.functionName).toEqualTypeOf<'transfer'>() + expectTypeOf(variables.args).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + }, + ) +}) + +test('multichain address', () => { + const useWriteErc20 = createUseWriteContract({ + abi: abi.erc20, + address: { + [mainnet.id]: '0x', + [optimism.id]: '0x', + }, + }) + + const { writeContract } = useWriteErc20() + writeContract({ + functionName: 'transfer', + args: ['0x', 123n], + chainId: mainnet.id, + // ^? + }) + + writeContract({ + functionName: 'transfer', + args: ['0x', 123n], + // @ts-expect-error chain id must match address keys + chainId: 420, + }) + + writeContract({ + // @ts-expect-error address not allowed + address: '0x', + functionName: 'transfer', + args: ['0x', 123n], + }) +}) + +test('overloads', () => { + const useWriteOverloads = createUseWriteContract({ + abi: abi.writeOverloads, + address: { + [mainnet.id]: '0x', + [optimism.id]: '0x', + }, + }) + + const { writeContract } = useWriteOverloads() + writeContract({ + functionName: 'foo', + args: [], + }) + + writeContract({ + functionName: 'foo', + args: ['0x'], + }) + + writeContract({ + functionName: 'foo', + args: ['0x', '0x'], + }) +}) + +test('useSimulateContract', () => { + const useWriteErc20 = createUseWriteContract({ + abi: abi.erc20, + address: { + [mainnet.id]: '0x', + [optimism.id]: '0x', + }, + }) + + const { data } = useSimulateContract({ + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + chainId: 1, + }) + const { writeContract } = useWriteErc20() + + const request = data?.request + if (request) writeContract(request) +}) + +test('functionName', () => { + const useWriteErc20 = createUseWriteContract({ + abi: abi.erc20, + functionName: 'transfer', + }) + + const { writeContract } = useWriteErc20() + writeContract({ + address: '0x', + args: ['0x', 123n], + }) +}) diff --git a/wagmi-project/packages/react/src/hooks/codegen/createUseWriteContract.test.ts b/wagmi-project/packages/react/src/hooks/codegen/createUseWriteContract.test.ts new file mode 100644 index 0000000000..e89dc62141 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/codegen/createUseWriteContract.test.ts @@ -0,0 +1,13 @@ +import { abi } from '@wagmi/test' +import { renderHook } from '@wagmi/test/react' +import { test } from 'vitest' + +import { createUseWriteContract } from './createUseWriteContract.js' + +test('default', () => { + const useWriteErc20 = createUseWriteContract({ + abi: abi.erc20, + }) + + renderHook(() => useWriteErc20()) +}) diff --git a/wagmi-project/packages/react/src/hooks/codegen/createUseWriteContract.ts b/wagmi-project/packages/react/src/hooks/codegen/createUseWriteContract.ts new file mode 100644 index 0000000000..9e58fd973b --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/codegen/createUseWriteContract.ts @@ -0,0 +1,297 @@ +import type { MutateOptions } from '@tanstack/react-query' +import type { + Config, + ResolvedRegister, + WriteContractErrorType, +} from '@wagmi/core' +import type { + ChainIdParameter, + Compute, + ConnectorParameter, + SelectChains, + UnionCompute, + UnionStrictOmit, +} from '@wagmi/core/internal' +import type { + WriteContractData, + WriteContractVariables, +} from '@wagmi/core/query' +import { useCallback } from 'react' +import type { + Abi, + Account, + Address, + Chain, + ContractFunctionArgs, + ContractFunctionName, +} from 'viem' +import type { WriteContractParameters as viem_WriteContractParameters } from 'viem/actions' + +import { useAccount } from '../useAccount.js' +import { useChainId } from '../useChainId.js' +import { useConfig } from '../useConfig.js' +import { + type UseWriteContractParameters, + useWriteContract, + type UseWriteContractReturnType as wagmi_UseWriteContractReturnType, +} from '../useWriteContract.js' + +type stateMutability = 'nonpayable' | 'payable' + +export type CreateUseWriteContractParameters< + abi extends Abi | readonly unknown[], + address extends Address | Record | undefined = undefined, + functionName extends + | ContractFunctionName + | undefined = undefined, +> = { + abi: abi | Abi | readonly unknown[] + address?: address | Address | Record | undefined + functionName?: + | functionName + | ContractFunctionName + | undefined +} + +export type CreateUseWriteContractReturnType< + abi extends Abi | readonly unknown[], + address extends Address | Record | undefined, + functionName extends ContractFunctionName | undefined, +> = ( + parameters?: UseWriteContractParameters, +) => Compute< + Omit< + wagmi_UseWriteContractReturnType, + 'writeContract' | 'writeContractAsync' + > & { + writeContract: < + const abi2 extends abi, + name extends functionName extends ContractFunctionName< + abi, + stateMutability + > + ? functionName + : ContractFunctionName, + args extends ContractFunctionArgs, + chainId extends config['chains'][number]['id'], + >( + variables: Variables< + abi2, + functionName, + name, + args, + config, + chainId, + address + >, + options?: + | MutateOptions< + WriteContractData, + WriteContractErrorType, + WriteContractVariables< + abi2, + name, + args, + config, + chainId, + // use `functionName` to make sure it's not union of all possible function names + name + >, + context + > + | undefined, + ) => void + writeContractAsync: < + const abi2 extends abi, + name extends functionName extends ContractFunctionName< + abi, + stateMutability + > + ? functionName + : ContractFunctionName, + args extends ContractFunctionArgs, + chainId extends config['chains'][number]['id'], + >( + variables: Variables< + abi2, + functionName, + name, + args, + config, + chainId, + address + >, + options?: + | MutateOptions< + WriteContractData, + WriteContractErrorType, + WriteContractVariables< + abi2, + name, + args, + config, + chainId, + // use `functionName` to make sure it's not union of all possible function names + name + >, + context + > + | undefined, + ) => Promise + } +> + +export function createUseWriteContract< + const abi extends Abi | readonly unknown[], + const address extends + | Address + | Record + | undefined = undefined, + functionName extends + | ContractFunctionName + | undefined = undefined, +>( + props: CreateUseWriteContractParameters, +): CreateUseWriteContractReturnType { + if (props.address !== undefined && typeof props.address === 'object') + return (parameters) => { + const config = useConfig(parameters) + const result = useWriteContract(parameters) + const configChainId = useChainId({ config }) + const account = useAccount({ config }) + type Args = Parameters + return { + ...(result as any), + writeContract: useCallback( + (...args: Args) => { + let chainId: number | undefined + if (args[0].chainId) chainId = args[0].chainId + else if (args[0].account && args[0].account === account.address) + chainId = account.chainId + else if (args[0].account === undefined) chainId = account.chainId + else chainId = configChainId + + const variables = { + ...(args[0] as any), + address: chainId ? props.address?.[chainId] : undefined, + ...(props.functionName + ? { functionName: props.functionName } + : {}), + abi: props.abi, + } + result.writeContract(variables, args[1] as any) + }, + [ + account.address, + account.chainId, + props, + configChainId, + result.writeContract, + ], + ), + writeContractAsync: useCallback( + (...args: Args) => { + let chainId: number | undefined + if (args[0].chainId) chainId = args[0].chainId + else if (args[0].account && args[0].account === account.address) + chainId = account.chainId + else if (args[0].account === undefined) chainId = account.chainId + else chainId = configChainId + + const variables = { + ...(args[0] as any), + address: chainId ? props.address?.[chainId] : undefined, + ...(props.functionName + ? { functionName: props.functionName } + : {}), + abi: props.abi, + } + return result.writeContractAsync(variables, args[1] as any) + }, + [ + account.address, + account.chainId, + props, + configChainId, + result.writeContractAsync, + ], + ), + } + } + + return (parameters) => { + const result = useWriteContract(parameters) + type Args = Parameters + return { + ...(result as any), + writeContract: useCallback( + (...args: Args) => { + const variables = { + ...(args[0] as any), + ...(props.address ? { address: props.address } : {}), + ...(props.functionName ? { functionName: props.functionName } : {}), + abi: props.abi, + } + result.writeContract(variables, args[1] as any) + }, + [props, result.writeContract], + ), + writeContractAsync: useCallback( + (...args: Args) => { + const variables = { + ...(args[0] as any), + ...(props.address ? { address: props.address } : {}), + ...(props.functionName ? { functionName: props.functionName } : {}), + abi: props.abi, + } + return result.writeContractAsync(variables, args[1] as any) + }, + [props, result.writeContractAsync], + ), + } + } +} + +type Variables< + abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName | undefined, + name extends ContractFunctionName, + args extends ContractFunctionArgs, + config extends Config, + chainId extends config['chains'][number]['id'], + address extends Address | Record | undefined, + /// + allFunctionNames = ContractFunctionName, + chains extends readonly Chain[] = SelectChains, + omittedProperties extends 'abi' | 'address' | 'functionName' = + | 'abi' + | (address extends undefined ? never : 'address') + | (functionName extends undefined ? never : 'functionName'), +> = UnionCompute< + { + [key in keyof chains]: UnionStrictOmit< + viem_WriteContractParameters< + abi, + name, + args, + chains[key], + Account, + chains[key], + allFunctionNames + >, + omittedProperties | 'chain' + > + }[number] & + (address extends Record + ? { + chainId?: + | keyof address + | (chainId extends keyof address ? chainId : never) + | undefined + } + : Compute>) & + ConnectorParameter & { + /** @deprecated */ + __mode?: 'prepared' + } +> diff --git a/wagmi-project/packages/react/src/hooks/useAccount.test-d.ts b/wagmi-project/packages/react/src/hooks/useAccount.test-d.ts new file mode 100644 index 0000000000..a22d816d6a --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useAccount.test-d.ts @@ -0,0 +1,68 @@ +import type { Connector } from '@wagmi/core' +import type { Address, Chain } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { useAccount } from './useAccount.js' + +test('states', () => { + const result = useAccount() + + switch (result.status) { + case 'reconnecting': { + expectTypeOf(result).toMatchTypeOf<{ + address: Address | undefined + chain: Chain | undefined + chainId: number | undefined + connector: Connector | undefined + isConnected: boolean + isConnecting: false + isDisconnected: false + isReconnecting: true + status: 'reconnecting' + }>() + break + } + case 'connecting': { + expectTypeOf(result).toMatchTypeOf<{ + address: Address | undefined + chain: Chain | undefined + chainId: number | undefined + connector: Connector | undefined + isConnected: false + isReconnecting: false + isConnecting: true + isDisconnected: false + status: 'connecting' + }>() + break + } + case 'connected': { + expectTypeOf(result).toMatchTypeOf<{ + address: Address + chain: Chain | undefined + chainId: number + connector: Connector + isConnected: true + isConnecting: false + isDisconnected: false + isReconnecting: false + status: 'connected' + }>() + break + } + case 'disconnected': { + expectTypeOf(result).toMatchTypeOf<{ + address: undefined + chain: undefined + chainId: undefined + connector: undefined + isConnected: false + isReconnecting: false + isConnecting: false + isDisconnected: true + status: 'disconnected' + }>() + break + } + } +}) diff --git a/wagmi-project/packages/react/src/hooks/useAccount.test.ts b/wagmi-project/packages/react/src/hooks/useAccount.test.ts new file mode 100644 index 0000000000..3c4af3c3f9 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useAccount.test.ts @@ -0,0 +1,29 @@ +import { connect, disconnect } from '@wagmi/core' +import { config } from '@wagmi/test' +import { renderHook } from '@wagmi/test/react' +import { Fragment, createElement } from 'react' +import { expect, test } from 'vitest' + +import { useAccount } from './useAccount.js' + +test('default', async () => { + const { result, rerender } = renderHook(() => useAccount()) + + expect(result.current.address).not.toBeDefined() + expect(result.current.status).toEqual('disconnected') + + await connect(config, { connector: config.connectors[0]! }) + rerender() + + expect(result.current.address).toBeDefined() + expect(result.current.status).toEqual('connected') + + await disconnect(config) +}) + +test('parameters: config', () => { + const { result } = renderHook(() => useAccount({ config }), { + wrapper: ({ children }) => createElement(Fragment, { children }), + }) + expect(result.current).toBeDefined() +}) diff --git a/wagmi-project/packages/react/src/hooks/useAccount.ts b/wagmi-project/packages/react/src/hooks/useAccount.ts new file mode 100644 index 0000000000..c7c1779469 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useAccount.ts @@ -0,0 +1,31 @@ +'use client' + +import { + type Config, + type GetAccountReturnType, + type ResolvedRegister, + getAccount, + watchAccount, +} from '@wagmi/core' + +import type { ConfigParameter } from '../types/properties.js' +import { useConfig } from './useConfig.js' +import { useSyncExternalStoreWithTracked } from './useSyncExternalStoreWithTracked.js' + +export type UseAccountParameters = + ConfigParameter + +export type UseAccountReturnType = + GetAccountReturnType + +/** https://wagmi.sh/react/api/hooks/useAccount */ +export function useAccount( + parameters: UseAccountParameters = {}, +): UseAccountReturnType { + const config = useConfig(parameters) + + return useSyncExternalStoreWithTracked( + (onChange) => watchAccount(config, { onChange }), + () => getAccount(config), + ) +} diff --git a/wagmi-project/packages/react/src/hooks/useAccountEffect.test.ts b/wagmi-project/packages/react/src/hooks/useAccountEffect.test.ts new file mode 100644 index 0000000000..b252ee0f98 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useAccountEffect.test.ts @@ -0,0 +1,77 @@ +import { mock } from '@wagmi/connectors' +import { http, connect, createConfig, disconnect } from '@wagmi/core' +import { accounts, chain, config } from '@wagmi/test' +import { createWrapper, renderHook, waitFor } from '@wagmi/test/react' +import { Fragment, createElement } from 'react' +import { expect, test, vi } from 'vitest' + +import { WagmiProvider } from '../context.js' +import { useAccountEffect } from './useAccountEffect.js' +import { useConnect } from './useConnect.js' +import { useDisconnect } from './useDisconnect.js' + +test('parameters: config', () => { + const { result } = renderHook(() => useAccountEffect({ config }), { + wrapper: ({ children }) => createElement(Fragment, { children }), + }) + expect(result.current).toBeUndefined() +}) + +test('behavior: connect and disconnect called once', async () => { + const onConnect = vi.fn() + const onDisconnect = vi.fn() + + const { result } = renderHook(() => ({ + useAccountEffect: useAccountEffect({ onConnect, onDisconnect }), + useConnect: useConnect(), + useDisconnect: useDisconnect(), + })) + + result.current.useConnect.connect({ + connector: result.current.useConnect.connectors[0]!, + }) + await waitFor(() => expect(result.current.useConnect.isSuccess).toBeTruthy()) + + result.current.useConnect.connect({ + connector: result.current.useConnect.connectors[0]!, + }) + await waitFor(() => expect(result.current.useConnect.isSuccess).toBeTruthy()) + + result.current.useDisconnect.disconnect() + await waitFor(() => + expect(result.current.useDisconnect.isSuccess).toBeTruthy(), + ) + result.current.useDisconnect.disconnect() + await waitFor(() => + expect(result.current.useDisconnect.isSuccess).toBeTruthy(), + ) + + expect(onConnect).toBeCalledTimes(1) + expect(onDisconnect).toBeCalledTimes(1) +}) + +test('behavior: connect called on reconnect', async () => { + const config = createConfig({ + chains: [chain.mainnet], + connectors: [ + mock({ + accounts, + features: { reconnect: true }, + }), + ], + transports: { [chain.mainnet.id]: http() }, + }) + + await connect(config, { connector: config.connectors[0]! }) + const onConnect = vi.fn((data) => { + expect(data.isReconnected).toBeTruthy() + }) + + renderHook(() => useAccountEffect({ onConnect }), { + wrapper: createWrapper(WagmiProvider, { config, reconnectOnMount: true }), + }) + + await waitFor(() => expect(onConnect).toBeCalledTimes(1)) + + await disconnect(config) +}) diff --git a/wagmi-project/packages/react/src/hooks/useAccountEffect.ts b/wagmi-project/packages/react/src/hooks/useAccountEffect.ts new file mode 100644 index 0000000000..5c77585e35 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useAccountEffect.ts @@ -0,0 +1,62 @@ +'use client' + +import { type GetAccountReturnType, watchAccount } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { useEffect } from 'react' + +import type { ConfigParameter } from '../types/properties.js' +import { useConfig } from './useConfig.js' + +export type UseAccountEffectParameters = Compute< + { + onConnect?( + data: Compute< + Pick< + Extract, + 'address' | 'addresses' | 'chain' | 'chainId' | 'connector' + > & { + isReconnected: boolean + } + >, + ): void + onDisconnect?(): void + } & ConfigParameter +> + +/** https://wagmi.sh/react/api/hooks/useAccountEffect */ +export function useAccountEffect(parameters: UseAccountEffectParameters = {}) { + const { onConnect, onDisconnect } = parameters + + const config = useConfig(parameters) + + useEffect(() => { + return watchAccount(config, { + onChange(data, prevData) { + if ( + (prevData.status === 'reconnecting' || + (prevData.status === 'connecting' && + prevData.address === undefined)) && + data.status === 'connected' + ) { + const { address, addresses, chain, chainId, connector } = data + const isReconnected = + prevData.status === 'reconnecting' || + // if `previousAccount.status` is `undefined`, the connector connected immediately. + prevData.status === undefined + onConnect?.({ + address, + addresses, + chain, + chainId, + connector, + isReconnected, + }) + } else if ( + prevData.status === 'connected' && + data.status === 'disconnected' + ) + onDisconnect?.() + }, + }) + }, [config, onConnect, onDisconnect]) +} diff --git a/wagmi-project/packages/react/src/hooks/useBalance.test-d.ts b/wagmi-project/packages/react/src/hooks/useBalance.test-d.ts new file mode 100644 index 0000000000..74630d50c7 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useBalance.test-d.ts @@ -0,0 +1,14 @@ +import { expectTypeOf, test } from 'vitest' + +import { useBalance } from './useBalance.js' + +test('select data', () => { + const result = useBalance({ + query: { + select(data) { + return data?.value + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useBalance.test.ts b/wagmi-project/packages/react/src/hooks/useBalance.test.ts new file mode 100644 index 0000000000..ba7f857808 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useBalance.test.ts @@ -0,0 +1,312 @@ +import { accounts, chain, testClient, wait } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { type Address, parseEther } from 'viem' +import { beforeEach, expect, test } from 'vitest' + +import { useBalance } from './useBalance.js' + +const address = accounts[0] + +beforeEach(async () => { + await testClient.mainnet.setBalance({ address, value: parseEther('10000') }) + await testClient.mainnet.mine({ blocks: 1 }) + await testClient.mainnet2.setBalance({ address, value: parseEther('69') }) + await testClient.mainnet2.mine({ blocks: 1 }) +}) + +test('default', async () => { + const { result } = renderHook(() => useBalance({ address })) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toMatchObject( + expect.objectContaining({ + decimals: expect.any(Number), + formatted: expect.any(String), + symbol: expect.any(String), + value: expect.any(BigInt), + }), + ) + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "balance", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: chainId', async () => { + const { result } = renderHook(() => + useBalance({ address, chainId: chain.mainnet2.id }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "decimals": 18, + "formatted": "69", + "symbol": "WAG", + "value": 69000000000000000000n, + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "balance", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 456, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: token', async () => { + const { result } = renderHook(() => + useBalance({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + token: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "decimals": 18, + "formatted": "0.559062564299199392", + "symbol": "DAI", + "value": 559062564299199392n, + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "balance", + { + "address": "0x4557B18E779944BFE9d78A672452331C186a9f48", + "chainId": 1, + "token": "0x6B175474E89094C44Da98b954EedeAC495271d0F", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: unit', async () => { + const { result } = renderHook(() => + useBalance({ address, chainId: chain.mainnet2.id, unit: 'wei' }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "decimals": 18, + "formatted": "69000000000000000000", + "symbol": "WAG", + "value": 69000000000000000000n, + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "balance", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 456, + "unit": "wei", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: address: undefined -> defined', async () => { + let address: Address | undefined = undefined + + const { result, rerender } = renderHook(() => useBalance({ address })) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": undefined, + "dataUpdatedAt": 0, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": false, + "isFetchedAfterMount": false, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": true, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": false, + "queryKey": [ + "balance", + { + "address": undefined, + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "pending", + } + `) + + address = accounts[0] + rerender() + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "decimals": 18, + "formatted": "10000", + "symbol": "ETH", + "value": 10000000000000000000000n, + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "balance", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: disabled when properties missing', async () => { + const { result } = renderHook(() => useBalance()) + + await wait(100) + await waitFor(() => expect(result.current.isPending).toBeTruthy()) +}) diff --git a/wagmi-project/packages/react/src/hooks/useBalance.ts b/wagmi-project/packages/react/src/hooks/useBalance.ts new file mode 100644 index 0000000000..93568089f7 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useBalance.ts @@ -0,0 +1,54 @@ +'use client' + +import type { Config, GetBalanceErrorType, ResolvedRegister } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetBalanceData, + type GetBalanceOptions, + type GetBalanceQueryKey, + getBalanceQueryOptions, +} from '@wagmi/core/query' +import type { GetBalanceQueryFnData } from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseBalanceParameters< + config extends Config = Config, + selectData = GetBalanceData, +> = Compute< + GetBalanceOptions & + ConfigParameter & + QueryParameter< + GetBalanceQueryFnData, + GetBalanceErrorType, + selectData, + GetBalanceQueryKey + > +> + +export type UseBalanceReturnType = + UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useBalance */ +export function useBalance< + config extends Config = ResolvedRegister['config'], + selectData = GetBalanceData, +>( + parameters: UseBalanceParameters = {}, +): UseBalanceReturnType { + const { address, query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = getBalanceQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + const enabled = Boolean(address && (query.enabled ?? true)) + + return useQuery({ ...query, ...options, enabled }) +} diff --git a/wagmi-project/packages/react/src/hooks/useBlock.test-d.ts b/wagmi-project/packages/react/src/hooks/useBlock.test-d.ts new file mode 100644 index 0000000000..04aae75076 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useBlock.test-d.ts @@ -0,0 +1,64 @@ +import { http, createConfig, webSocket } from '@wagmi/core' +import { mainnet, optimism } from '@wagmi/core/chains' +import { expectTypeOf, test } from 'vitest' + +import { useBlock } from './useBlock.js' + +test('select data', () => { + const result = useBlock({ + query: { + select(data) { + return data?.number + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) + +test('differing transports', () => { + const config = createConfig({ + chains: [mainnet, optimism], + transports: { + [mainnet.id]: http(), + [optimism.id]: webSocket(), + }, + }) + + useBlock({ + config, + watch: { + poll: false, + }, + }) + + useBlock({ + config, + chainId: mainnet.id, + watch: { + poll: true, + }, + }) + useBlock({ + config, + chainId: mainnet.id, + watch: { + // @ts-expect-error + poll: false, + }, + }) + + useBlock({ + config, + chainId: optimism.id, + watch: { + poll: true, + }, + }) + useBlock({ + config, + chainId: optimism.id, + watch: { + poll: false, + }, + }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useBlock.test.ts b/wagmi-project/packages/react/src/hooks/useBlock.test.ts new file mode 100644 index 0000000000..0d2095ec61 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useBlock.test.ts @@ -0,0 +1,67 @@ +import { testClient } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useBlock } from './useBlock.js' + +test('mounts', async () => { + const { result } = renderHook(() => useBlock()) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toBeDefined() + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "block", + { + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: watch', async () => { + await testClient.mainnet.restart() + + const { result } = renderHook(() => useBlock({ watch: true })) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + const block = result.current.data! + expect(block).toBeDefined() + + await testClient.mainnet.mine({ blocks: 1 }) + await waitFor(() => { + expect(result.current.data?.number).toEqual(block.number + 1n) + }) + + await testClient.mainnet.mine({ blocks: 1 }) + await waitFor(() => { + expect(result.current.data?.number).toEqual(block.number + 2n) + }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useBlock.ts b/wagmi-project/packages/react/src/hooks/useBlock.ts new file mode 100644 index 0000000000..1a16a5bd9e --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useBlock.ts @@ -0,0 +1,131 @@ +'use client' + +import { useQueryClient } from '@tanstack/react-query' +import type { Config, GetBlockErrorType, ResolvedRegister } from '@wagmi/core' +import type { + Compute, + UnionCompute, + UnionStrictOmit, +} from '@wagmi/core/internal' +import { + type GetBlockData, + type GetBlockOptions, + type GetBlockQueryFnData, + type GetBlockQueryKey, + getBlockQueryOptions, +} from '@wagmi/core/query' +import type { BlockTag } from 'viem' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' +import { + type UseWatchBlocksParameters, + useWatchBlocks, +} from './useWatchBlocks.js' + +export type UseBlockParameters< + includeTransactions extends boolean = false, + blockTag extends BlockTag = 'latest', + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetBlockData, +> = Compute< + GetBlockOptions & + ConfigParameter & + QueryParameter< + GetBlockQueryFnData, + GetBlockErrorType, + selectData, + GetBlockQueryKey + > & { + watch?: + | boolean + | UnionCompute< + UnionStrictOmit< + UseWatchBlocksParameters< + includeTransactions, + blockTag, + config, + chainId + >, + 'chainId' | 'config' | 'onBlock' | 'onError' + > + > + | undefined + } +> + +export type UseBlockReturnType< + includeTransactions extends boolean = false, + blockTag extends BlockTag = 'latest', + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetBlockData, +> = UseQueryReturnType + +/** https://wagmi.sh/react/hooks/useBlock */ +export function useBlock< + includeTransactions extends boolean = false, + blockTag extends BlockTag = 'latest', + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetBlockData, +>( + parameters: UseBlockParameters< + includeTransactions, + blockTag, + config, + chainId, + selectData + > = {}, +): UseBlockReturnType< + includeTransactions, + blockTag, + config, + chainId, + selectData +> { + const { query = {}, watch } = parameters + + const config = useConfig(parameters) + const queryClient = useQueryClient() + const configChainId = useChainId({ config }) + const chainId = parameters.chainId ?? configChainId + + const options = getBlockQueryOptions(config, { + ...parameters, + chainId, + }) + const enabled = Boolean(query.enabled ?? true) + + useWatchBlocks({ + ...({ + config: parameters.config, + chainId: parameters.chainId!, + ...(typeof watch === 'object' ? watch : {}), + } as UseWatchBlocksParameters), + enabled: Boolean( + enabled && (typeof watch === 'object' ? watch.enabled : watch), + ), + onBlock(block) { + queryClient.setQueryData(options.queryKey, block) + }, + }) + + return useQuery({ + ...(query as any), + ...options, + enabled, + }) as UseBlockReturnType< + includeTransactions, + blockTag, + config, + chainId, + selectData + > +} diff --git a/wagmi-project/packages/react/src/hooks/useBlockNumber.test-d.ts b/wagmi-project/packages/react/src/hooks/useBlockNumber.test-d.ts new file mode 100644 index 0000000000..dfb4ca4dbe --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useBlockNumber.test-d.ts @@ -0,0 +1,65 @@ +import { http, createConfig, webSocket } from '@wagmi/core' +import { mainnet, optimism } from '@wagmi/core/chains' +import { expectTypeOf, test } from 'vitest' + +import { useBlockNumber } from './useBlockNumber.js' + +test('select data', () => { + const result = useBlockNumber({ + query: { + select(data) { + expectTypeOf(data).toEqualTypeOf() + return data?.toString() + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) + +test('differing transports', () => { + const config = createConfig({ + chains: [mainnet, optimism], + transports: { + [mainnet.id]: http(), + [optimism.id]: webSocket(), + }, + }) + + useBlockNumber({ + config, + watch: { + poll: false, + }, + }) + + useBlockNumber({ + config, + chainId: mainnet.id, + watch: { + poll: true, + }, + }) + useBlockNumber({ + config, + chainId: mainnet.id, + watch: { + // @ts-expect-error + poll: false, + }, + }) + + useBlockNumber({ + config, + chainId: optimism.id, + watch: { + poll: true, + }, + }) + useBlockNumber({ + config, + chainId: optimism.id, + watch: { + poll: false, + }, + }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useBlockNumber.test.ts b/wagmi-project/packages/react/src/hooks/useBlockNumber.test.ts new file mode 100644 index 0000000000..93006a6663 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useBlockNumber.test.ts @@ -0,0 +1,68 @@ +import { testClient } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useBlockNumber } from './useBlockNumber.js' + +test('mounts', async () => { + await testClient.mainnet.resetFork() + + const { result } = renderHook(() => useBlockNumber()) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": 19258213n, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "blockNumber", + { + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: watch', async () => { + await testClient.mainnet.restart() + + const { result } = renderHook(() => useBlockNumber({ watch: true })) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + const blockNumber = result.current.data! + expect(result.current.data).toMatchInlineSnapshot('19258213n') + + await testClient.mainnet.mine({ blocks: 1 }) + await waitFor(() => { + expect(result.current.data).toEqual(blockNumber + 1n) + }) + + await testClient.mainnet.mine({ blocks: 1 }) + await waitFor(() => { + expect(result.current.data).toEqual(blockNumber + 2n) + }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useBlockNumber.ts b/wagmi-project/packages/react/src/hooks/useBlockNumber.ts new file mode 100644 index 0000000000..f91d8466e3 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useBlockNumber.ts @@ -0,0 +1,97 @@ +'use client' + +import { useQueryClient } from '@tanstack/react-query' +import type { + Config, + GetBlockNumberErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { + Compute, + UnionCompute, + UnionStrictOmit, +} from '@wagmi/core/internal' +import { + type GetBlockNumberData, + type GetBlockNumberOptions, + type GetBlockNumberQueryFnData, + type GetBlockNumberQueryKey, + getBlockNumberQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' +import { + type UseWatchBlockNumberParameters, + useWatchBlockNumber, +} from './useWatchBlockNumber.js' + +export type UseBlockNumberParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetBlockNumberData, +> = Compute< + GetBlockNumberOptions & + ConfigParameter & + QueryParameter< + GetBlockNumberQueryFnData, + GetBlockNumberErrorType, + selectData, + GetBlockNumberQueryKey + > & { + watch?: + | boolean + | UnionCompute< + UnionStrictOmit< + UseWatchBlockNumberParameters, + 'chainId' | 'config' | 'onBlockNumber' | 'onError' + > + > + | undefined + } +> + +export type UseBlockNumberReturnType = + UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useBlockNumber */ +export function useBlockNumber< + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetBlockNumberData, +>( + parameters: UseBlockNumberParameters = {}, +): UseBlockNumberReturnType { + const { query = {}, watch } = parameters + + const config = useConfig(parameters) + const queryClient = useQueryClient() + const configChainId = useChainId({ config }) + const chainId = parameters.chainId ?? configChainId + + const options = getBlockNumberQueryOptions(config, { + ...parameters, + chainId, + }) + + useWatchBlockNumber({ + ...({ + config: parameters.config, + chainId: parameters.chainId, + ...(typeof watch === 'object' ? watch : {}), + } as UseWatchBlockNumberParameters), + enabled: Boolean( + (query.enabled ?? true) && + (typeof watch === 'object' ? watch.enabled : watch), + ), + onBlockNumber(blockNumber) { + queryClient.setQueryData(options.queryKey, blockNumber) + }, + }) + + return useQuery({ ...query, ...options }) +} diff --git a/wagmi-project/packages/react/src/hooks/useBlockTransactionCount.test-d.ts b/wagmi-project/packages/react/src/hooks/useBlockTransactionCount.test-d.ts new file mode 100644 index 0000000000..ff23fcfe95 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useBlockTransactionCount.test-d.ts @@ -0,0 +1,14 @@ +import { expectTypeOf, test } from 'vitest' + +import { useBlockTransactionCount } from './useBlockTransactionCount.js' + +test('select data', () => { + const result = useBlockTransactionCount({ + query: { + select(data) { + return data + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useBlockTransactionCount.test.ts b/wagmi-project/packages/react/src/hooks/useBlockTransactionCount.test.ts new file mode 100644 index 0000000000..dad6c95506 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useBlockTransactionCount.test.ts @@ -0,0 +1,231 @@ +import { chain } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useBlockTransactionCount } from './useBlockTransactionCount.js' + +test('default', async () => { + const { result } = renderHook(() => useBlockTransactionCount({})) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toBeTypeOf('number') + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "blockTransactionCount", + { + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: chainId', async () => { + const { result } = renderHook(() => + useBlockTransactionCount({ chainId: chain.mainnet2.id }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toBeTypeOf('number') + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "blockTransactionCount", + { + "chainId": 456, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: blockNumber', async () => { + const { result } = renderHook(() => + useBlockTransactionCount({ blockNumber: 13677382n }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toBeTypeOf('number') + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "blockTransactionCount", + { + "blockNumber": 13677382n, + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: blockHash', async () => { + const { result } = renderHook(() => + useBlockTransactionCount({ + blockHash: + '0x6201f37a245850d1f11e4be3ac45bc51bd9d43ee4a127192cad550f351cfa575', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toBeTypeOf('number') + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "blockTransactionCount", + { + "blockHash": "0x6201f37a245850d1f11e4be3ac45bc51bd9d43ee4a127192cad550f351cfa575", + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: blockTag', async () => { + const { result } = renderHook(() => + useBlockTransactionCount({ + blockTag: 'safe', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toBeTypeOf('number') + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "blockTransactionCount", + { + "blockTag": "safe", + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) diff --git a/wagmi-project/packages/react/src/hooks/useBlockTransactionCount.ts b/wagmi-project/packages/react/src/hooks/useBlockTransactionCount.ts new file mode 100644 index 0000000000..edbd6e8ddf --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useBlockTransactionCount.ts @@ -0,0 +1,67 @@ +'use client' + +import type { + Config, + GetBlockTransactionCountErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { UnionCompute } from '@wagmi/core/internal' +import { + type GetBlockTransactionCountData, + type GetBlockTransactionCountOptions, + type GetBlockTransactionCountQueryFnData, + type GetBlockTransactionCountQueryKey, + getBlockTransactionCountQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseBlockTransactionCountParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetBlockTransactionCountData, +> = UnionCompute< + GetBlockTransactionCountOptions & + ConfigParameter & + QueryParameter< + GetBlockTransactionCountQueryFnData, + GetBlockTransactionCountErrorType, + selectData, + GetBlockTransactionCountQueryKey + > +> + +export type UseBlockTransactionCountReturnType< + selectData = GetBlockTransactionCountData, +> = UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useBlockTransactionCount */ +export function useBlockTransactionCount< + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetBlockTransactionCountData, +>( + parameters: UseBlockTransactionCountParameters< + config, + chainId, + selectData + > = {}, +): UseBlockTransactionCountReturnType { + const { query = {} } = parameters + + const config = useConfig(parameters) + const configChainId = useChainId({ config }) + const chainId = parameters.chainId ?? configChainId + + const options = getBlockTransactionCountQueryOptions(config, { + ...parameters, + chainId, + }) + + return useQuery({ ...query, ...options }) +} diff --git a/wagmi-project/packages/react/src/hooks/useBytecode.test-d.ts b/wagmi-project/packages/react/src/hooks/useBytecode.test-d.ts new file mode 100644 index 0000000000..eff094e710 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useBytecode.test-d.ts @@ -0,0 +1,15 @@ +import { expectTypeOf, test } from 'vitest' + +import type { Hex } from 'viem' +import { useBytecode } from './useBytecode.js' + +test('select data', () => { + const result = useBytecode({ + query: { + select(data) { + return data + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useBytecode.test.ts b/wagmi-project/packages/react/src/hooks/useBytecode.test.ts new file mode 100644 index 0000000000..4c25fa9558 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useBytecode.test.ts @@ -0,0 +1,291 @@ +import { address, chain, wait } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import type { Address } from 'viem' +import { useBytecode } from './useBytecode.js' + +test('default', async () => { + const { result } = renderHook(() => + useBytecode({ + address: address.wagmiMintExample, + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getBytecode", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) + expect(data).toMatch(/^0x.*/) +}) + +test('parameters: blockNumber', async () => { + const { result } = renderHook(() => + useBytecode({ + address: address.wagmiMintExample, + blockNumber: 15564163n, + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": null, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getBytecode", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "blockNumber": 15564163n, + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: blockTag', async () => { + const { result } = renderHook(() => + useBytecode({ + address: address.wagmiMintExample, + blockTag: 'earliest', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": null, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getBytecode", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "blockTag": "earliest", + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: chainId', async () => { + const { result } = renderHook(() => + useBytecode({ + address: address.wagmiMintExample, + chainId: chain.optimism.id, + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": null, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getBytecode", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "chainId": 10, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: address: undefined -> defined', async () => { + let contractAddress: Address | undefined = undefined + + const { result, rerender } = renderHook(() => + useBytecode({ + address: contractAddress, + }), + ) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": undefined, + "dataUpdatedAt": 0, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": false, + "isFetchedAfterMount": false, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": true, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": false, + "queryKey": [ + "getBytecode", + { + "address": undefined, + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "pending", + } + `) + + contractAddress = address.wagmiMintExample + rerender() + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getBytecode", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) + expect(data).toMatch(/^0x.*/) +}) + +test('behavior: disabled when properties missing', async () => { + const { result } = renderHook(() => useBytecode()) + + await wait(100) + await waitFor(() => expect(result.current.isPending).toBeTruthy()) +}) diff --git a/wagmi-project/packages/react/src/hooks/useBytecode.ts b/wagmi-project/packages/react/src/hooks/useBytecode.ts new file mode 100644 index 0000000000..3dd01d438a --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useBytecode.ts @@ -0,0 +1,57 @@ +'use client' + +import type { + Config, + GetBytecodeErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetBytecodeData, + type GetBytecodeOptions, + type GetBytecodeQueryKey, + getBytecodeQueryOptions, +} from '@wagmi/core/query' +import type { GetBytecodeQueryFnData } from '@wagmi/core/query' +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseBytecodeParameters< + config extends Config = Config, + selectData = GetBytecodeData, +> = Compute< + GetBytecodeOptions & + ConfigParameter & + QueryParameter< + GetBytecodeQueryFnData, + GetBytecodeErrorType, + selectData, + GetBytecodeQueryKey + > +> + +export type UseBytecodeReturnType = + UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useBytecode */ +export function useBytecode< + config extends Config = ResolvedRegister['config'], + selectData = GetBytecodeData, +>( + parameters: UseBytecodeParameters = {}, +): UseBytecodeReturnType { + const { address, query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = getBytecodeQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + const enabled = Boolean(address && (query.enabled ?? true)) + + return useQuery({ ...query, ...options, enabled }) +} diff --git a/wagmi-project/packages/react/src/hooks/useCall.test-d.ts b/wagmi-project/packages/react/src/hooks/useCall.test-d.ts new file mode 100644 index 0000000000..5c47b096c7 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useCall.test-d.ts @@ -0,0 +1,14 @@ +import type { CallReturnType } from 'viem' +import { expectTypeOf, test } from 'vitest' +import { useCall } from './useCall.js' + +test('select data', () => { + const result = useCall({ + query: { + select(data) { + return data + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useCall.test.ts b/wagmi-project/packages/react/src/hooks/useCall.test.ts new file mode 100644 index 0000000000..ee8ce813c4 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useCall.test.ts @@ -0,0 +1,224 @@ +import { accounts, address, chain } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useCall } from './useCall.js' + +const name4bytes = '0x06fdde03' + +const account = accounts[0] + +test('default', async () => { + const { result } = renderHook(() => + useCall({ + account, + data: name4bytes, + to: address.wagmiMintExample, + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000057761676d69000000000000000000000000000000000000000000000000000000", + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "call", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 1, + "data": "0x06fdde03", + "to": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +// TODO: Re-enable +test.skip('parameters: blockTag', async () => { + const { result } = renderHook(() => + useCall({ + account, + data: name4bytes, + to: address.wagmiMintExample, + blockTag: 'safe', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000057761676d69000000000000000000000000000000000000000000000000000000", + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "call", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "blockTag": "safe", + "chainId": 1, + "data": "0x06fdde03", + "to": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +// TODO: Re-enable +test.skip('parameters: blockNumber', async () => { + const { result } = renderHook(() => + useCall({ + account, + data: name4bytes, + to: address.wagmiMintExample, + blockNumber: 16280770n, + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000057761676d69000000000000000000000000000000000000000000000000000000", + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "call", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "blockNumber": 16280770n, + "chainId": 1, + "data": "0x06fdde03", + "to": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: chainId', async () => { + const { result } = renderHook(() => + useCall({ + account, + data: name4bytes, + to: address.wagmiMintExample, + chainId: chain.mainnet2.id, + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000057761676d69000000000000000000000000000000000000000000000000000000", + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "call", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 456, + "data": "0x06fdde03", + "to": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) diff --git a/wagmi-project/packages/react/src/hooks/useCall.ts b/wagmi-project/packages/react/src/hooks/useCall.ts new file mode 100644 index 0000000000..423e04fbff --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useCall.ts @@ -0,0 +1,55 @@ +'use client' + +import type { CallErrorType, Config, ResolvedRegister } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type CallData, + type CallOptions, + type CallQueryKey, + callQueryOptions, +} from '@wagmi/core/query' +import type { CallQueryFnData } from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseCallParameters< + config extends Config = Config, + selectData = CallData, +> = Compute< + CallOptions & + ConfigParameter & + QueryParameter< + CallQueryFnData, + CallErrorType, + selectData, + CallQueryKey + > +> + +export type UseCallReturnType = UseQueryReturnType< + selectData, + CallErrorType +> + +/** https://wagmi.sh/react/api/hooks/useCall */ +export function useCall< + config extends Config = ResolvedRegister['config'], + selectData = CallData, +>( + parameters: UseCallParameters = {}, +): UseCallReturnType { + const { query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = callQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + + return useQuery({ ...query, ...options }) +} diff --git a/wagmi-project/packages/react/src/hooks/useCallsStatus.test.ts b/wagmi-project/packages/react/src/hooks/useCallsStatus.test.ts new file mode 100644 index 0000000000..f3af1c24bc --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useCallsStatus.test.ts @@ -0,0 +1,101 @@ +import { connect, disconnect } from '@wagmi/core' +import { accounts, config, testClient } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { parseEther } from 'viem' +import { expect, test } from 'vitest' + +import { useCallsStatus } from './useCallsStatus.js' +import { useSendCalls } from './useSendCalls.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const { result } = renderHook(() => useSendCalls()) + + result.current.sendCalls({ + calls: [ + { + data: '0xdeadbeef', + to: accounts[1], + value: parseEther('1'), + }, + { + to: accounts[2], + value: parseEther('2'), + }, + { + to: accounts[3], + value: parseEther('3'), + }, + ], + }) + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { result: result_2 } = renderHook(() => + useCallsStatus({ id: result.current.data?.id! }), + ) + await waitFor(() => expect(result_2.current.isSuccess).toBeTruthy()) + + expect(result_2.current.data).toMatchInlineSnapshot( + ` + { + "atomic": false, + "chainId": 1, + "id": "0x5dedb5a4ff8968db37459b52b83cbdc92b01c9c709c9cff26e345ef5cf27f92e", + "receipts": [], + "status": "pending", + "statusCode": 100, + "version": "2.0.0", + } + `, + ) + + await testClient.mainnet.mine({ blocks: 1 }) + + const { result: result_3 } = renderHook(() => + useCallsStatus({ id: result.current.data?.id! }), + ) + await waitFor(() => expect(result_3.current.isSuccess).toBeTruthy()) + + expect(result_3.current.data?.status).toBe('success') + expect(result_3.current.data?.statusCode).toBe(200) + expect( + result_3.current.data?.receipts?.map((x) => ({ + ...x, + blockHash: undefined, + })), + ).toMatchInlineSnapshot( + ` + [ + { + "blockHash": undefined, + "blockNumber": 19258214n, + "gasUsed": 21064n, + "logs": [], + "status": "success", + "transactionHash": "0x13c53b2d4d9da424835525349cd66e553330f323d6fb19458b801ae1f7989a41", + }, + { + "blockHash": undefined, + "blockNumber": 19258214n, + "gasUsed": 21000n, + "logs": [], + "status": "success", + "transactionHash": "0xd8397b3e82b061c26a0c2093f1ceca0c3662a512614f7d6370349e89d0eea007", + }, + { + "blockHash": undefined, + "blockNumber": 19258214n, + "gasUsed": 21000n, + "logs": [], + "status": "success", + "transactionHash": "0x4d26e346593d9ea265bb164b115e89aa92df43b0b8778ac75d4ad28e2a22b101", + }, + ] + `, + ) + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useCallsStatus.ts b/wagmi-project/packages/react/src/hooks/useCallsStatus.ts new file mode 100644 index 0000000000..ab4c90c1f2 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useCallsStatus.ts @@ -0,0 +1,52 @@ +'use client' + +import type { + Config, + GetCallsStatusErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetCallsStatusData, + type GetCallsStatusOptions, + type GetCallsStatusQueryFnData, + type GetCallsStatusQueryKey, + getCallsStatusQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useConfig } from './useConfig.js' + +export type UseCallsStatusParameters< + config extends Config = Config, + selectData = GetCallsStatusData, +> = Compute< + GetCallsStatusOptions & + ConfigParameter & + QueryParameter< + GetCallsStatusQueryFnData, + GetCallsStatusErrorType, + selectData, + GetCallsStatusQueryKey + > +> + +export type UseCallsStatusReturnType = + UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useCallsStatus */ +export function useCallsStatus< + config extends Config = ResolvedRegister['config'], + selectData = GetCallsStatusData, +>( + parameters: UseCallsStatusParameters, +): UseCallsStatusReturnType { + const { query = {} } = parameters + + const config = useConfig(parameters) + + const options = getCallsStatusQueryOptions(config, parameters) + + return useQuery({ ...query, ...options }) +} diff --git a/wagmi-project/packages/react/src/hooks/useCapabilities.test.ts b/wagmi-project/packages/react/src/hooks/useCapabilities.test.ts new file mode 100644 index 0000000000..65dcf171b5 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useCapabilities.test.ts @@ -0,0 +1,167 @@ +import { connect, disconnect } from '@wagmi/core' +import { accounts, config } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useCapabilities } from './useCapabilities.js' + +const connector = config.connectors[0]! + +test('mounts', async () => { + await connect(config, { connector }) + + const { result } = renderHook(() => useCapabilities()) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "8453": { + "paymasterService": { + "supported": true, + }, + "sessionKeys": { + "supported": true, + }, + }, + "84532": { + "paymasterService": { + "supported": true, + }, + }, + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "capabilities", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + }, + ], + "refetch": [Function], + "status": "success", + } + `) + + await disconnect(config, { connector }) +}) + +test('args: account', async () => { + await connect(config, { connector }) + + const { result } = renderHook(() => useCapabilities({ account: accounts[1] })) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "8453": { + "paymasterService": { + "supported": false, + }, + "sessionKeys": { + "supported": true, + }, + }, + "84532": { + "paymasterService": { + "supported": false, + }, + }, + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "capabilities", + { + "account": "0x70997970c51812dc3a010c7d01b50e0d17dc79c8", + }, + ], + "refetch": [Function], + "status": "success", + } + `) + + await disconnect(config, { connector }) +}) + +test('behavior: not connected', async () => { + const { result } = renderHook(() => useCapabilities()) + + await waitFor(() => expect(result.current.isError).toBeTruthy()) + + const { error, failureReason: _, ...rest } = result.current + expect(error?.message.includes('Connector not connected.')).toBeTruthy() + expect(rest).toMatchInlineSnapshot(` + { + "data": undefined, + "dataUpdatedAt": 0, + "errorUpdateCount": 2, + "errorUpdatedAt": 1675209600000, + "failureCount": 1, + "fetchStatus": "idle", + "isError": true, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": true, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": false, + "queryKey": [ + "capabilities", + { + "account": undefined, + }, + ], + "refetch": [Function], + "status": "error", + } + `) +}) diff --git a/wagmi-project/packages/react/src/hooks/useCapabilities.ts b/wagmi-project/packages/react/src/hooks/useCapabilities.ts new file mode 100644 index 0000000000..399a56cd38 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useCapabilities.ts @@ -0,0 +1,62 @@ +'use client' + +import type { + Config, + GetCapabilitiesErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetCapabilitiesData, + type GetCapabilitiesOptions, + type GetCapabilitiesQueryFnData, + type GetCapabilitiesQueryKey, + getCapabilitiesQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useAccount } from './useAccount.js' +import { useConfig } from './useConfig.js' + +export type UseCapabilitiesParameters< + config extends Config = Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, + selectData = GetCapabilitiesData, +> = Compute< + GetCapabilitiesOptions & + ConfigParameter & + QueryParameter< + GetCapabilitiesQueryFnData, + GetCapabilitiesErrorType, + selectData, + GetCapabilitiesQueryKey + > +> + +export type UseCapabilitiesReturnType< + config extends Config = Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, + selectData = GetCapabilitiesData, +> = UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useCapabilities */ +export function useCapabilities< + config extends Config = ResolvedRegister['config'], + chainId extends config['chains'][number]['id'] | undefined = undefined, + selectData = GetCapabilitiesData, +>( + parameters: UseCapabilitiesParameters = {}, +): UseCapabilitiesReturnType { + const { account, query = {} } = parameters + + const { address } = useAccount() + const config = useConfig(parameters) + + const options = getCapabilitiesQueryOptions(config, { + ...parameters, + account: account ?? address, + }) + + return useQuery({ ...query, ...options }) +} diff --git a/wagmi-project/packages/react/src/hooks/useChainId.test-d.ts b/wagmi-project/packages/react/src/hooks/useChainId.test-d.ts new file mode 100644 index 0000000000..682b5fab7a --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useChainId.test-d.ts @@ -0,0 +1,14 @@ +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { useChainId } from './useChainId.js' + +test('default', () => { + const chainId = useChainId() + expectTypeOf(chainId).toEqualTypeOf() +}) + +test('parameters: config', () => { + const chainId = useChainId({ config }) + expectTypeOf(chainId).toEqualTypeOf<1 | 456 | 10>() +}) diff --git a/wagmi-project/packages/react/src/hooks/useChainId.test.ts b/wagmi-project/packages/react/src/hooks/useChainId.test.ts new file mode 100644 index 0000000000..e4745b46e3 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useChainId.test.ts @@ -0,0 +1,24 @@ +import { config } from '@wagmi/test' +import { renderHook } from '@wagmi/test/react' +import { Fragment, createElement } from 'react' +import { expect, test } from 'vitest' + +import { useChainId } from './useChainId.js' + +test('default', async () => { + const { result, rerender } = renderHook(() => useChainId()) + + expect(result.current).toMatchInlineSnapshot('1') + + config.setState((x) => ({ ...x, chainId: 456 })) + rerender() + + expect(result.current).toMatchInlineSnapshot('456') +}) + +test('parameters: config', () => { + const { result } = renderHook(() => useChainId({ config }), { + wrapper: ({ children }) => createElement(Fragment, { children }), + }) + expect(result.current).toBeDefined() +}) diff --git a/wagmi-project/packages/react/src/hooks/useChainId.ts b/wagmi-project/packages/react/src/hooks/useChainId.ts new file mode 100644 index 0000000000..ce7cb208dd --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useChainId.ts @@ -0,0 +1,32 @@ +'use client' + +import { + type Config, + type GetChainIdReturnType, + type ResolvedRegister, + getChainId, + watchChainId, +} from '@wagmi/core' +import { useSyncExternalStore } from 'react' + +import type { ConfigParameter } from '../types/properties.js' +import { useConfig } from './useConfig.js' + +export type UseChainIdParameters = + ConfigParameter + +export type UseChainIdReturnType = + GetChainIdReturnType + +/** https://wagmi.sh/react/api/hooks/useChainId */ +export function useChainId( + parameters: UseChainIdParameters = {}, +): UseChainIdReturnType { + const config = useConfig(parameters) + + return useSyncExternalStore( + (onChange) => watchChainId(config, { onChange }), + () => getChainId(config), + () => getChainId(config), + ) +} diff --git a/wagmi-project/packages/react/src/hooks/useChains.test.ts b/wagmi-project/packages/react/src/hooks/useChains.test.ts new file mode 100644 index 0000000000..1d9d6fca4f --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useChains.test.ts @@ -0,0 +1,31 @@ +import { config } from '@wagmi/test' +import { renderHook } from '@wagmi/test/react' +import { Fragment, createElement } from 'react' +import { expect, test } from 'vitest' + +import { useChains } from './useChains.js' + +test('default', async () => { + const { result } = renderHook(() => useChains()) + + expect(result.current.map((x) => x.id)).toMatchInlineSnapshot(` + [ + 1, + 456, + 10, + ] + `) +}) + +test('parameters: config', () => { + const { result } = renderHook(() => useChains({ config }), { + wrapper: ({ children }) => createElement(Fragment, { children }), + }) + expect(result.current.map((x) => x.id)).toMatchInlineSnapshot(` + [ + 1, + 456, + 10, + ] + `) +}) diff --git a/wagmi-project/packages/react/src/hooks/useChains.ts b/wagmi-project/packages/react/src/hooks/useChains.ts new file mode 100644 index 0000000000..b3e93b417a --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useChains.ts @@ -0,0 +1,32 @@ +'use client' + +import { + type Config, + type GetChainsReturnType, + type ResolvedRegister, + getChains, +} from '@wagmi/core' +import { watchChains } from '@wagmi/core/internal' +import { useSyncExternalStore } from 'react' + +import type { ConfigParameter } from '../types/properties.js' +import { useConfig } from './useConfig.js' + +export type UseChainsParameters = + ConfigParameter + +export type UseChainsReturnType = + GetChainsReturnType + +/** https://wagmi.sh/react/api/hooks/useChains */ +export function useChains( + parameters: UseChainsParameters = {}, +): UseChainsReturnType { + const config = useConfig(parameters) + + return useSyncExternalStore( + (onChange) => watchChains(config, { onChange }), + () => getChains(config), + () => getChains(config), + ) +} diff --git a/wagmi-project/packages/react/src/hooks/useClient.test-d.ts b/wagmi-project/packages/react/src/hooks/useClient.test-d.ts new file mode 100644 index 0000000000..80ee4ec48d --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useClient.test-d.ts @@ -0,0 +1,40 @@ +import { chain, config } from '@wagmi/test' +import type { Chain } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { useClient } from './useClient.js' + +test('default', () => { + const client = useClient({ config }) + expectTypeOf(client.chain).toEqualTypeOf<(typeof config)['chains'][number]>() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() +}) + +test('parameters: chainId', () => { + const client = useClient({ + config, + chainId: chain.mainnet.id, + }) + expectTypeOf(client.chain).toEqualTypeOf() + expectTypeOf(client.chain).not.toEqualTypeOf() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() +}) + +test('behavior: unconfigured chain', () => { + { + const client = useClient({ chainId: 123456 }) + if (client) { + expectTypeOf(client.chain).toEqualTypeOf() + expectTypeOf(client.transport.type).toEqualTypeOf() + } else { + expectTypeOf(client).toEqualTypeOf() + } + } + + const client = useClient({ + config, + // @ts-expect-error + chainId: 123456, + }) + expectTypeOf(client).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useClient.test.ts b/wagmi-project/packages/react/src/hooks/useClient.test.ts new file mode 100644 index 0000000000..93ef8d9fa9 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useClient.test.ts @@ -0,0 +1,30 @@ +import { switchChain } from '@wagmi/core' +import { config } from '@wagmi/test' +import { renderHook } from '@wagmi/test/react' +import { Fragment, createElement } from 'react' +import { expect, test } from 'vitest' + +import { useClient } from './useClient.js' + +test('default', async () => { + const { result, rerender } = renderHook(() => useClient()) + + expect(result.current?.chain.id).toEqual(1) + + await switchChain(config, { chainId: 456 }) + rerender() + + expect(result.current?.chain.id).toEqual(456) +}) + +test('parameters: config', () => { + const { result } = renderHook(() => useClient({ config }), { + wrapper: ({ children }) => createElement(Fragment, { children }), + }) + expect(result.current).toBeDefined() +}) + +test('behavior: unconfigured chain', () => { + const { result } = renderHook(() => useClient({ chainId: 123456 })) + expect(result.current).toBeUndefined() +}) diff --git a/wagmi-project/packages/react/src/hooks/useClient.ts b/wagmi-project/packages/react/src/hooks/useClient.ts new file mode 100644 index 0000000000..abfee745b3 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useClient.ts @@ -0,0 +1,49 @@ +'use client' + +import { + type Config, + type GetClientParameters, + type GetClientReturnType, + type ResolvedRegister, + getClient, + watchClient, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/shim/with-selector.js' + +import type { ConfigParameter } from '../types/properties.js' +import { useConfig } from './useConfig.js' + +export type UseClientParameters< + config extends Config = Config, + chainId extends config['chains'][number]['id'] | number | undefined = + | config['chains'][number]['id'] + | undefined, +> = Compute & ConfigParameter> + +export type UseClientReturnType< + config extends Config = Config, + chainId extends config['chains'][number]['id'] | number | undefined = + | config['chains'][number]['id'] + | undefined, +> = GetClientReturnType + +/** https://wagmi.sh/react/api/hooks/useClient */ +export function useClient< + config extends Config = ResolvedRegister['config'], + chainId extends config['chains'][number]['id'] | number | undefined = + | config['chains'][number]['id'] + | undefined, +>( + parameters: UseClientParameters = {}, +): UseClientReturnType { + const config = useConfig(parameters) + + return useSyncExternalStoreWithSelector( + (onChange) => watchClient(config, { onChange }), + () => getClient(config, parameters), + () => getClient(config, parameters), + (x) => x, + (a, b) => a?.uid === b?.uid, + ) as any +} diff --git a/wagmi-project/packages/react/src/hooks/useConfig.test-d.ts b/wagmi-project/packages/react/src/hooks/useConfig.test-d.ts new file mode 100644 index 0000000000..f2b9d2bb31 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useConfig.test-d.ts @@ -0,0 +1,16 @@ +import type { Config } from '@wagmi/core' +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { useConfig } from './useConfig.js' + +test('default', async () => { + const result = useConfig() + expectTypeOf(result).toEqualTypeOf() +}) + +test('parameters: config', async () => { + const result = useConfig({ config }) + expectTypeOf(result).not.toEqualTypeOf() + expectTypeOf(result).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useConfig.test.ts b/wagmi-project/packages/react/src/hooks/useConfig.test.ts new file mode 100644 index 0000000000..e0fc9c40ce --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useConfig.test.ts @@ -0,0 +1,23 @@ +import { createWrapper, renderHook } from '@wagmi/test/react' +import { expect, test, vi } from 'vitest' + +import { useConfig } from './useConfig.js' + +test('mounts', () => { + const { result } = renderHook(() => useConfig()) + expect(result.current).toBeDefined() +}) + +test('behavior: throws when not inside Provider', () => { + vi.spyOn(console, 'error').mockImplementation(() => {}) + + try { + renderHook(() => useConfig(), { + wrapper: createWrapper(() => null, undefined), + }) + } catch (error) { + expect(error).toMatchInlineSnapshot( + '[Error: `useConfig` must be used within `WagmiProvider`.]', + ) + } +}) diff --git a/wagmi-project/packages/react/src/hooks/useConfig.ts b/wagmi-project/packages/react/src/hooks/useConfig.ts new file mode 100644 index 0000000000..af9ea5b9c0 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useConfig.ts @@ -0,0 +1,22 @@ +'use client' + +import type { Config, ResolvedRegister } from '@wagmi/core' +import { useContext } from 'react' + +import { WagmiContext } from '../context.js' +import { WagmiProviderNotFoundError } from '../errors/context.js' +import type { ConfigParameter } from '../types/properties.js' + +export type UseConfigParameters = + ConfigParameter + +export type UseConfigReturnType = config + +/** https://wagmi.sh/react/api/hooks/useConfig */ +export function useConfig( + parameters: UseConfigParameters = {}, +): UseConfigReturnType { + const config = parameters.config ?? useContext(WagmiContext) + if (!config) throw new WagmiProviderNotFoundError() + return config as UseConfigReturnType +} diff --git a/wagmi-project/packages/react/src/hooks/useConnect.test-d.ts b/wagmi-project/packages/react/src/hooks/useConnect.test-d.ts new file mode 100644 index 0000000000..e678d2edd8 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useConnect.test-d.ts @@ -0,0 +1,124 @@ +import type { + ConnectErrorType, + Connector, + CreateConnectorFn, +} from '@wagmi/core' +import { config } from '@wagmi/test' +import type { Address } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { useConnect } from './useConnect.js' + +const connector = config.connectors[0]! +const contextValue = { foo: 'bar' } as const + +test('context', () => { + const { connect, context, data, error, variables } = useConnect({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toEqualTypeOf<{ + chainId?: number | undefined + connector: Connector | CreateConnectorFn + }>() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ + chainId?: number | undefined + connector: Connector | CreateConnectorFn + }>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ + chainId?: number | undefined + connector: Connector | CreateConnectorFn + }>() + expectTypeOf(data).toEqualTypeOf<{ + accounts: readonly [Address, ...Address[]] + chainId: number + }>() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf< + | { + accounts: readonly [Address, ...Address[]] + chainId: number + } + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf<{ + chainId?: number | undefined + connector: Connector | CreateConnectorFn + }>() + expectTypeOf(context).toEqualTypeOf() + }, + }, + }) + + expectTypeOf(data).toEqualTypeOf< + | { + accounts: readonly [Address, ...Address[]] + chainId: number + } + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toMatchTypeOf< + | { + chainId?: number | undefined + connector: CreateConnectorFn | Connector + } + | undefined + >() + expectTypeOf(context).toEqualTypeOf() + + connect( + { + connector, + foo: 'bar', + }, + { + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ + chainId?: number | undefined + connector: typeof connector | CreateConnectorFn + foo?: string | undefined + }>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ + chainId?: number | undefined + connector: typeof connector | CreateConnectorFn + foo?: string | undefined + }>() + expectTypeOf(data).toEqualTypeOf<{ + accounts: readonly [Address, ...Address[]] + chainId: number + }>() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf< + | { + accounts: readonly [Address, ...Address[]] + chainId: number + } + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf<{ + chainId?: number | undefined + connector: typeof connector | CreateConnectorFn + foo?: string | undefined + }>() + expectTypeOf(context).toEqualTypeOf() + }, + }, + ) +}) diff --git a/wagmi-project/packages/react/src/hooks/useConnect.test.ts b/wagmi-project/packages/react/src/hooks/useConnect.test.ts new file mode 100644 index 0000000000..d80ff30509 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useConnect.test.ts @@ -0,0 +1,35 @@ +import { disconnect } from '@wagmi/core' +import { config } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { afterEach, expect, test } from 'vitest' + +import { useAccount } from './useAccount.js' +import { useConnect } from './useConnect.js' + +const connector = config.connectors[0]! + +afterEach(async () => { + if (config.state.current === connector.uid) + await disconnect(config, { connector }) +}) + +test('default', async () => { + const { result } = renderHook(() => ({ + useAccount: useAccount(), + useConnect: useConnect(), + })) + + expect(result.current.useAccount.address).not.toBeDefined() + expect(result.current.useAccount.status).toEqual('disconnected') + + result.current.useConnect.connect({ + connector: result.current.useConnect.connectors[0]!, + }) + + await waitFor(() => + expect(result.current.useAccount.isConnected).toBeTruthy(), + ) + + expect(result.current.useAccount.address).toBeDefined() + expect(result.current.useAccount.status).toEqual('connected') +}) diff --git a/wagmi-project/packages/react/src/hooks/useConnect.ts b/wagmi-project/packages/react/src/hooks/useConnect.ts new file mode 100644 index 0000000000..acfe69234d --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useConnect.ts @@ -0,0 +1,90 @@ +'use client' + +import { useMutation } from '@tanstack/react-query' +import type { Config, ConnectErrorType, ResolvedRegister } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type ConnectData, + type ConnectMutate, + type ConnectMutateAsync, + type ConnectVariables, + connectMutationOptions, +} from '@wagmi/core/query' +import { useEffect } from 'react' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' +import { type UseConnectorsReturnType, useConnectors } from './useConnectors.js' + +export type UseConnectParameters< + config extends Config = Config, + context = unknown, +> = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + ConnectData, + ConnectErrorType, + ConnectVariables, + context + > + | undefined + } +> + +export type UseConnectReturnType< + config extends Config = Config, + context = unknown, +> = Compute< + UseMutationReturnType< + ConnectData, + ConnectErrorType, + ConnectVariables, + context + > & { + connect: ConnectMutate + connectAsync: ConnectMutateAsync + connectors: Compute | config['connectors'] + } +> + +/** https://wagmi.sh/react/api/hooks/useConnect */ +export function useConnect< + config extends Config = ResolvedRegister['config'], + context = unknown, +>( + parameters: UseConnectParameters = {}, +): UseConnectReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = connectMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + // Reset mutation back to an idle state when the connector disconnects. + useEffect(() => { + return config.subscribe( + ({ status }) => status, + (status, previousStatus) => { + if (previousStatus === 'connected' && status === 'disconnected') + result.reset() + }, + ) + }, [config, result.reset]) + + type Return = UseConnectReturnType + return { + ...(result as Return), + connect: mutate as Return['connect'], + connectAsync: mutateAsync as Return['connectAsync'], + connectors: useConnectors({ config }), + } +} diff --git a/wagmi-project/packages/react/src/hooks/useConnections.test.ts b/wagmi-project/packages/react/src/hooks/useConnections.test.ts new file mode 100644 index 0000000000..1eb4febcdb --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useConnections.test.ts @@ -0,0 +1,25 @@ +import { connect } from '@wagmi/core' +import { config } from '@wagmi/test' +import { renderHook } from '@wagmi/test/react' +import { Fragment, createElement } from 'react' +import { expect, test } from 'vitest' + +import { useConnections } from './useConnections.js' + +test('default', async () => { + const { result, rerender } = renderHook(() => useConnections()) + + expect(result.current).toEqual([]) + + await connect(config, { connector: config.connectors[0]! }) + rerender() + + expect(result.current.length).toBe(1) +}) + +test('parameters: config', () => { + const { result } = renderHook(() => useConnections({ config }), { + wrapper: ({ children }) => createElement(Fragment, { children }), + }) + expect(result.current).toBeDefined() +}) diff --git a/wagmi-project/packages/react/src/hooks/useConnections.ts b/wagmi-project/packages/react/src/hooks/useConnections.ts new file mode 100644 index 0000000000..db53db7227 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useConnections.ts @@ -0,0 +1,28 @@ +'use client' + +import { + type GetConnectionsReturnType, + getConnections, + watchConnections, +} from '@wagmi/core' +import { useSyncExternalStore } from 'react' + +import type { ConfigParameter } from '../types/properties.js' +import { useConfig } from './useConfig.js' + +export type UseConnectionsParameters = ConfigParameter + +export type UseConnectionsReturnType = GetConnectionsReturnType + +/** https://wagmi.sh/react/api/hooks/useConnections */ +export function useConnections( + parameters: UseConnectionsParameters = {}, +): UseConnectionsReturnType { + const config = useConfig(parameters) + + return useSyncExternalStore( + (onChange) => watchConnections(config, { onChange }), + () => getConnections(config), + () => getConnections(config), + ) +} diff --git a/wagmi-project/packages/react/src/hooks/useConnectorClient.test-d.ts b/wagmi-project/packages/react/src/hooks/useConnectorClient.test-d.ts new file mode 100644 index 0000000000..b919e6a904 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useConnectorClient.test-d.ts @@ -0,0 +1,12 @@ +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { useConnectorClient } from './useConnectorClient.js' + +test('parameters: config', async () => { + const client = useConnectorClient({ config }) + expectTypeOf(client.data?.chain?.id!).toEqualTypeOf<1 | 456 | 10>() + + const client2 = useConnectorClient({ config, chainId: 1 }) + expectTypeOf(client2.data?.chain?.id!).toEqualTypeOf<1>() +}) diff --git a/wagmi-project/packages/react/src/hooks/useConnectorClient.test.tsx b/wagmi-project/packages/react/src/hooks/useConnectorClient.test.tsx new file mode 100644 index 0000000000..f8737c53ec --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useConnectorClient.test.tsx @@ -0,0 +1,239 @@ +import { connect, disconnect } from '@wagmi/core' +import { config, wait } from '@wagmi/test' +import { render, renderHook, waitFor } from '@wagmi/test/react' +import * as React from 'react' +import { expect, test } from 'vitest' + +import { useAccount } from './useAccount.js' +import { useConnect } from './useConnect.js' +import { useConnectorClient } from './useConnectorClient.js' +import { useDisconnect } from './useDisconnect.js' +import { useSwitchChain } from './useSwitchChain.js' + +const connector = config.connectors[0]! + +test('default', async () => { + const { result } = renderHook(() => useConnectorClient()) + + await waitFor(() => expect(result.current.isPending).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": undefined, + "dataUpdatedAt": 0, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": false, + "isFetchedAfterMount": false, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": true, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": false, + "queryKey": [ + "connectorClient", + { + "chainId": 1, + "connectorUid": undefined, + }, + ], + "refetch": [Function], + "status": "pending", + } + `) +}) + +test('behavior: connected on mount', async () => { + await connect(config, { connector }) + + const { result } = renderHook(() => useConnectorClient()) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, queryKey: _, ...rest } = result.current + expect(data).toMatchObject( + expect.objectContaining({ + account: expect.any(Object), + chain: expect.any(Object), + }), + ) + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": true, + "refetch": [Function], + "status": "success", + } + `) + + await disconnect(config, { connector }) +}) + +test('behavior: connect and disconnect', async () => { + const { result } = renderHook(() => ({ + useConnect: useConnect(), + useConnectorClient: useConnectorClient(), + useDisconnect: useDisconnect(), + })) + + expect(result.current.useConnectorClient.data).not.toBeDefined() + + result.current.useConnect.connect({ + connector: result.current.useConnect.connectors[0]!, + }) + + await waitFor(() => + expect(result.current.useConnectorClient.data).toBeDefined(), + ) + + result.current.useDisconnect.disconnect() + + await waitFor(() => + expect(result.current.useConnectorClient.data).not.toBeDefined(), + ) +}) + +test('behavior: switch chains', async () => { + await connect(config, { connector }) + + const { result } = renderHook(() => ({ + useConnectorClient: useConnectorClient(), + useSwitchChain: useSwitchChain(), + })) + + expect(result.current.useConnectorClient.data).not.toBeDefined() + + await waitFor(() => + expect(result.current.useConnectorClient.data).toBeDefined(), + ) + + result.current.useSwitchChain.switchChain({ chainId: 456 }) + await waitFor(() => { + expect(result.current.useSwitchChain.isSuccess).toBeTruthy() + result.current.useSwitchChain.reset() + }) + expect(result.current.useConnectorClient.data?.chain.id).toEqual(456) + + result.current.useSwitchChain.switchChain({ chainId: 1 }) + await waitFor(() => + expect(result.current.useSwitchChain.isSuccess).toBeTruthy(), + ) + expect(result.current.useConnectorClient.data?.chain.id).toEqual(1) + + await disconnect(config, { connector }) +}) + +test('behavior: disabled when properties missing', async () => { + const { result } = renderHook(() => useConnectorClient()) + + await wait(100) + await waitFor(() => expect(result.current.isPending).toBeTruthy()) +}) + +test('behavior: disabled when connecting', async () => { + const { result } = renderHook(() => useConnectorClient()) + + config.setState((x) => ({ ...x, status: 'connecting' })) + + await wait(100) + expect(result.current.isLoading).not.toBeTruthy() +}) + +test('behavior: re-render does not invalidate query', async () => { + const { getByTestId } = render() + + getByTestId('connect').click() + await waitFor(() => { + expect(getByTestId('address').innerText).toContain( + '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + ) + expect(getByTestId('client').innerText).toBeTruthy() + + expect(getByTestId('child-client').innerText).toBeTruthy() + expect(getByTestId('render-count').innerText).toEqual('1') + }) + + const initialClient = getByTestId('child-client').innerText + + getByTestId('rerender').click() + await waitFor(() => { + expect(getByTestId('render-count').innerText).toEqual('2') + }) + await wait(200) + + expect(getByTestId('child-client').innerText).toEqual(initialClient) +}) + +function Parent() { + const [renderCount, setRenderCount] = React.useState(1) + + const { connectors, connect } = useConnect() + const { address } = useAccount() + const { data } = useConnectorClient() + + return ( + <> +
{address}
+
{data?.uid}
+ + + + + + ) +} + +function Child(props: { + renderCount: number +}) { + const { renderCount } = props + const { data } = useConnectorClient() + return ( +
+ {data?.uid} + {renderCount} +
+ ) +} diff --git a/wagmi-project/packages/react/src/hooks/useConnectorClient.ts b/wagmi-project/packages/react/src/hooks/useConnectorClient.ts new file mode 100644 index 0000000000..16bbf33ae0 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useConnectorClient.ts @@ -0,0 +1,113 @@ +'use client' + +import { useQueryClient } from '@tanstack/react-query' +import type { + Config, + GetConnectorClientErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute, Omit } from '@wagmi/core/internal' +import { + type GetConnectorClientData, + type GetConnectorClientOptions, + type GetConnectorClientQueryFnData, + type GetConnectorClientQueryKey, + getConnectorClientQueryOptions, +} from '@wagmi/core/query' +import { useEffect, useRef } from 'react' + +import type { ConfigParameter } from '../types/properties.js' +import { + type UseQueryParameters, + type UseQueryReturnType, + useQuery, +} from '../utils/query.js' +import { useAccount } from './useAccount.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseConnectorClientParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetConnectorClientData, +> = Compute< + GetConnectorClientOptions & + ConfigParameter & { + query?: + | Compute< + Omit< + UseQueryParameters< + GetConnectorClientQueryFnData, + GetConnectorClientErrorType, + selectData, + GetConnectorClientQueryKey + >, + 'gcTime' | 'staleTime' + > + > + | undefined + } +> + +export type UseConnectorClientReturnType< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetConnectorClientData, +> = UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useConnectorClient */ +export function useConnectorClient< + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetConnectorClientData, +>( + parameters: UseConnectorClientParameters = {}, +): UseConnectorClientReturnType { + const { query = {}, ...rest } = parameters + + const config = useConfig(rest) + const queryClient = useQueryClient() + const { address, connector, status } = useAccount({ config }) + const chainId = useChainId({ config }) + const activeConnector = parameters.connector ?? connector + + const { queryKey, ...options } = getConnectorClientQueryOptions< + config, + chainId + >(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + connector: activeConnector, + }) + const enabled = Boolean( + (status === 'connected' || + (status === 'reconnecting' && activeConnector?.getProvider)) && + (query.enabled ?? true), + ) + + const addressRef = useRef(address) + // biome-ignore lint/correctness/useExhaustiveDependencies: `queryKey` not required + useEffect(() => { + const previousAddress = addressRef.current + if (!address && previousAddress) { + // remove when account is disconnected + queryClient.removeQueries({ queryKey }) + addressRef.current = undefined + } else if (address !== previousAddress) { + // invalidate when address changes + queryClient.invalidateQueries({ queryKey }) + addressRef.current = address + } + }, [address, queryClient]) + + return useQuery({ + ...query, + ...options, + queryKey, + enabled, + staleTime: Number.POSITIVE_INFINITY, + }) +} diff --git a/wagmi-project/packages/react/src/hooks/useConnectors.test.ts b/wagmi-project/packages/react/src/hooks/useConnectors.test.ts new file mode 100644 index 0000000000..f287cceb32 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useConnectors.test.ts @@ -0,0 +1,30 @@ +import { mock } from '@wagmi/connectors' +import { accounts, config } from '@wagmi/test' +import { renderHook } from '@wagmi/test/react' +import { Fragment, createElement } from 'react' +import { expect, test } from 'vitest' + +import { useConnectors } from './useConnectors.js' + +test('default', async () => { + const { result, rerender } = renderHook(() => useConnectors()) + + const count = config.connectors.length + expect(result.current.length).toBe(count) + expect(result.current).toEqual(config.connectors) + + config._internal.connectors.setState(() => [ + ...config.connectors, + config._internal.connectors.setup(mock({ accounts })), + ]) + rerender() + + expect(result.current.length).toBe(count + 1) +}) + +test('parameters: config', () => { + const { result } = renderHook(() => useConnectors({ config }), { + wrapper: ({ children }) => createElement(Fragment, { children }), + }) + expect(result.current).toBeDefined() +}) diff --git a/wagmi-project/packages/react/src/hooks/useConnectors.ts b/wagmi-project/packages/react/src/hooks/useConnectors.ts new file mode 100644 index 0000000000..40a681689d --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useConnectors.ts @@ -0,0 +1,34 @@ +'use client' + +import { + type Config, + type GetConnectorsReturnType, + type ResolvedRegister, + getConnectors, + watchConnectors, +} from '@wagmi/core' +import { useSyncExternalStore } from 'react' + +import type { ConfigParameter } from '../types/properties.js' +import { useConfig } from './useConfig.js' + +export type UseConnectorsParameters = + ConfigParameter + +export type UseConnectorsReturnType = + GetConnectorsReturnType + +/** https://wagmi.sh/react/api/hooks/useConnectors */ +export function useConnectors< + config extends Config = ResolvedRegister['config'], +>( + parameters: UseConnectorsParameters = {}, +): UseConnectorsReturnType { + const config = useConfig(parameters) + + return useSyncExternalStore( + (onChange) => watchConnectors(config, { onChange }), + () => getConnectors(config), + () => getConnectors(config), + ) +} diff --git a/wagmi-project/packages/react/src/hooks/useDeployContract.test-d.ts b/wagmi-project/packages/react/src/hooks/useDeployContract.test-d.ts new file mode 100644 index 0000000000..93e53c472f --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useDeployContract.test-d.ts @@ -0,0 +1,105 @@ +import type { DeployContractErrorType } from '@wagmi/core' +import { abi, bytecode } from '@wagmi/test' +import type { Abi, Hash } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { useDeployContract } from './useDeployContract.js' + +const contextValue = { foo: 'bar' } as const + +test('context', () => { + const { context, data, error, deployContract, variables } = useDeployContract( + { + mutation: { + onMutate(variables) { + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: Abi + args?: readonly unknown[] | undefined + }>() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: Abi + args?: readonly unknown[] | undefined + }>() + }, + onSuccess(data, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: Abi + args?: readonly unknown[] | undefined + }>() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: Abi + args?: readonly unknown[] | undefined + }>() + }, + }, + }, + ) + + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toMatchTypeOf< + { chainId?: number | undefined } | undefined + >() + expectTypeOf(context).toEqualTypeOf() + + deployContract( + { + abi: abi.bayc, + bytecode: bytecode.bayc, + args: ['Bored Ape Wagmi Club', 'BAYC', 69420n, 0n], + chainId: 1, + }, + { + onError(error, variables, context) { + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: typeof abi.bayc + args: readonly [string, string, bigint, bigint] + }>() + }, + onSuccess(data, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: typeof abi.bayc + args: readonly [string, string, bigint, bigint] + }>() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: typeof abi.bayc + args: readonly [string, string, bigint, bigint] + }>() + }, + }, + ) +}) diff --git a/wagmi-project/packages/react/src/hooks/useDeployContract.test.ts b/wagmi-project/packages/react/src/hooks/useDeployContract.test.ts new file mode 100644 index 0000000000..561129bdbc --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useDeployContract.test.ts @@ -0,0 +1,24 @@ +import { connect, disconnect } from '@wagmi/core' +import { abi, bytecode, config, transactionHashRegex } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useDeployContract } from './useDeployContract.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + const { result } = renderHook(() => useDeployContract()) + + result.current.deployContract({ + abi: abi.bayc, + bytecode: bytecode.bayc, + args: ['Bored Ape Wagmi Club', 'BAYC', 69420n, 0n], + }) + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current.data).toMatch(transactionHashRegex) + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useDeployContract.ts b/wagmi-project/packages/react/src/hooks/useDeployContract.ts new file mode 100644 index 0000000000..d37f3206d4 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useDeployContract.ts @@ -0,0 +1,78 @@ +'use client' + +import { useMutation } from '@tanstack/react-query' +import type { + Config, + DeployContractErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type DeployContractData, + type DeployContractMutate, + type DeployContractMutateAsync, + type DeployContractVariables, + deployContractMutationOptions, +} from '@wagmi/core/query' +import type { Abi } from 'viem' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' + +export type UseDeployContractParameters< + config extends Config = Config, + context = unknown, +> = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + DeployContractData, + DeployContractErrorType, + DeployContractVariables, + context + > + | undefined + } +> + +export type UseDeployContractReturnType< + config extends Config = Config, + context = unknown, +> = UseMutationReturnType< + DeployContractData, + DeployContractErrorType, + DeployContractVariables, + context +> & { + deployContract: DeployContractMutate + deployContractAsync: DeployContractMutateAsync +} + +/** https://wagmi.sh/react/api/hooks/useDeployContract */ +export function useDeployContract< + config extends Config = ResolvedRegister['config'], + context = unknown, +>( + parameters: UseDeployContractParameters = {}, +): UseDeployContractReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = deployContractMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + type Return = UseDeployContractReturnType + return { + ...result, + deployContract: mutate as Return['deployContract'], + deployContractAsync: mutateAsync as Return['deployContractAsync'], + } +} diff --git a/wagmi-project/packages/react/src/hooks/useDisconnect.test-d.ts b/wagmi-project/packages/react/src/hooks/useDisconnect.test-d.ts new file mode 100644 index 0000000000..7bf3689450 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useDisconnect.test-d.ts @@ -0,0 +1,87 @@ +import type { Connector, DisconnectErrorType } from '@wagmi/core' +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { useDisconnect } from './useDisconnect.js' + +const connector = config.connectors[0]! +const contextValue = { foo: 'bar' } as const + +test('parameter', () => { + expectTypeOf(useDisconnect().disconnect) + .parameter(0) + .toEqualTypeOf<{ connector?: Connector | undefined } | undefined>() + expectTypeOf(useDisconnect().disconnect) + .parameter(0) + .toEqualTypeOf<{ connector?: Connector | undefined } | undefined>() +}) + +test('context', () => { + const { context, data, disconnect, error, variables } = useDisconnect({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toEqualTypeOf< + { connector?: Connector | undefined } | undefined + >() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf< + { connector?: Connector | undefined } | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf< + { connector?: Connector | undefined } | undefined + >() + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf< + { connector?: Connector | undefined } | undefined + >() + expectTypeOf(context).toEqualTypeOf() + }, + }, + }) + + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf< + { connector?: Connector | undefined } | undefined + >() + expectTypeOf(context).toEqualTypeOf() + + disconnect( + { connector }, + { + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf< + { connector?: Connector | undefined } | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf< + { connector?: Connector | undefined } | undefined + >() + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf< + { connector?: Connector | undefined } | undefined + >() + expectTypeOf(context).toEqualTypeOf() + }, + }, + ) +}) diff --git a/wagmi-project/packages/react/src/hooks/useDisconnect.test.ts b/wagmi-project/packages/react/src/hooks/useDisconnect.test.ts new file mode 100644 index 0000000000..26c7787d98 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useDisconnect.test.ts @@ -0,0 +1,32 @@ +import { connect } from '@wagmi/core' +import { config } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { beforeEach, expect, test } from 'vitest' + +import { useAccount } from './useAccount.js' +import { useDisconnect } from './useDisconnect.js' + +const connector = config.connectors[0]! + +beforeEach(async () => { + await connect(config, { connector }) +}) + +test('default', async () => { + const { result } = renderHook(() => ({ + useAccount: useAccount(), + useDisconnect: useDisconnect(), + })) + + expect(result.current.useAccount.address).toBeDefined() + expect(result.current.useAccount.status).toEqual('connected') + + result.current.useDisconnect.disconnect() + + await waitFor(() => + expect(result.current.useAccount.isDisconnected).toBeTruthy(), + ) + + expect(result.current.useAccount.address).not.toBeDefined() + expect(result.current.useAccount.status).toEqual('disconnected') +}) diff --git a/wagmi-project/packages/react/src/hooks/useDisconnect.ts b/wagmi-project/packages/react/src/hooks/useDisconnect.ts new file mode 100644 index 0000000000..b5bff5bfe3 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useDisconnect.ts @@ -0,0 +1,70 @@ +'use client' + +import { useMutation } from '@tanstack/react-query' +import type { Connector, DisconnectErrorType } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type DisconnectData, + type DisconnectMutate, + type DisconnectMutateAsync, + type DisconnectVariables, + disconnectMutationOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' +import { useConnections } from './useConnections.js' + +export type UseDisconnectParameters = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + DisconnectData, + DisconnectErrorType, + DisconnectVariables, + context + > + | undefined + } +> + +export type UseDisconnectReturnType = Compute< + UseMutationReturnType< + DisconnectData, + DisconnectErrorType, + DisconnectVariables, + context + > & { + connectors: readonly Connector[] + disconnect: DisconnectMutate + disconnectAsync: DisconnectMutateAsync + } +> + +/** https://wagmi.sh/react/api/hooks/useDisconnect */ +export function useDisconnect( + parameters: UseDisconnectParameters = {}, +): UseDisconnectReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = disconnectMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + return { + ...result, + connectors: useConnections({ config }).map( + (connection) => connection.connector, + ), + disconnect: mutate, + disconnectAsync: mutateAsync, + } +} diff --git a/wagmi-project/packages/react/src/hooks/useEnsAddress.test.ts b/wagmi-project/packages/react/src/hooks/useEnsAddress.test.ts new file mode 100644 index 0000000000..ff73c45f9d --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEnsAddress.test.ts @@ -0,0 +1,50 @@ +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useEnsAddress } from './useEnsAddress.js' + +test('default', async () => { + const { result } = renderHook(() => + useEnsAddress({ + name: 'wevm.eth', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": "0xd2135CfB216b74109775236E36d4b433F1DF507B", + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "ensAddress", + { + "chainId": 1, + "name": "wevm.eth", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) diff --git a/wagmi-project/packages/react/src/hooks/useEnsAddress.ts b/wagmi-project/packages/react/src/hooks/useEnsAddress.ts new file mode 100644 index 0000000000..999e07d999 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEnsAddress.ts @@ -0,0 +1,58 @@ +'use client' + +import type { + Config, + GetEnsAddressErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetEnsAddressData, + type GetEnsAddressOptions, + type GetEnsAddressQueryFnData, + type GetEnsAddressQueryKey, + getEnsAddressQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseEnsAddressParameters< + config extends Config = Config, + selectData = GetEnsAddressData, +> = Compute< + GetEnsAddressOptions & + ConfigParameter & + QueryParameter< + GetEnsAddressQueryFnData, + GetEnsAddressErrorType, + selectData, + GetEnsAddressQueryKey + > +> + +export type UseEnsAddressReturnType = + UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useEnsAddress */ +export function useEnsAddress< + config extends Config = ResolvedRegister['config'], + selectData = GetEnsAddressData, +>( + parameters: UseEnsAddressParameters = {}, +): UseEnsAddressReturnType { + const { name, query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = getEnsAddressQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + const enabled = Boolean(name && (query.enabled ?? true)) + + return useQuery({ ...query, ...options, enabled }) +} diff --git a/wagmi-project/packages/react/src/hooks/useEnsAvatar.test.ts b/wagmi-project/packages/react/src/hooks/useEnsAvatar.test.ts new file mode 100644 index 0000000000..d1f558be13 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEnsAvatar.test.ts @@ -0,0 +1,50 @@ +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useEnsAvatar } from './useEnsAvatar.js' + +test('default', async () => { + const { result } = renderHook(() => + useEnsAvatar({ + name: 'wevm.eth', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": "https://euc.li/wevm.eth", + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "ensAvatar", + { + "chainId": 1, + "name": "wevm.eth", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) diff --git a/wagmi-project/packages/react/src/hooks/useEnsAvatar.ts b/wagmi-project/packages/react/src/hooks/useEnsAvatar.ts new file mode 100644 index 0000000000..721653bf07 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEnsAvatar.ts @@ -0,0 +1,58 @@ +'use client' + +import type { + Config, + GetEnsAvatarErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetEnsAvatarData, + type GetEnsAvatarOptions, + type GetEnsAvatarQueryFnData, + type GetEnsAvatarQueryKey, + getEnsAvatarQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseEnsAvatarParameters< + config extends Config = Config, + selectData = GetEnsAvatarData, +> = Compute< + GetEnsAvatarOptions & + ConfigParameter & + QueryParameter< + GetEnsAvatarQueryFnData, + GetEnsAvatarErrorType, + selectData, + GetEnsAvatarQueryKey + > +> + +export type UseEnsAvatarReturnType = + UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useEnsAvatar */ +export function useEnsAvatar< + config extends Config = ResolvedRegister['config'], + selectData = GetEnsAvatarData, +>( + parameters: UseEnsAvatarParameters = {}, +): UseEnsAvatarReturnType { + const { name, query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = getEnsAvatarQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + const enabled = Boolean(name && (query.enabled ?? true)) + + return useQuery({ ...query, ...options, enabled }) +} diff --git a/wagmi-project/packages/react/src/hooks/useEnsName.test.ts b/wagmi-project/packages/react/src/hooks/useEnsName.test.ts new file mode 100644 index 0000000000..8a069b076d --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEnsName.test.ts @@ -0,0 +1,50 @@ +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useEnsName } from './useEnsName.js' + +test('default', async () => { + const { result } = renderHook(() => + useEnsName({ + address: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": "wevm.eth", + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "ensName", + { + "address": "0xd2135CfB216b74109775236E36d4b433F1DF507B", + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) diff --git a/wagmi-project/packages/react/src/hooks/useEnsName.ts b/wagmi-project/packages/react/src/hooks/useEnsName.ts new file mode 100644 index 0000000000..ddf88fed9d --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEnsName.ts @@ -0,0 +1,54 @@ +'use client' + +import type { Config, GetEnsNameErrorType, ResolvedRegister } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetEnsNameData, + type GetEnsNameOptions, + type GetEnsNameQueryFnData, + type GetEnsNameQueryKey, + getEnsNameQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseEnsNameParameters< + config extends Config = Config, + selectData = GetEnsNameData, +> = Compute< + GetEnsNameOptions & + ConfigParameter & + QueryParameter< + GetEnsNameQueryFnData, + GetEnsNameErrorType, + selectData, + GetEnsNameQueryKey + > +> + +export type UseEnsNameReturnType = + UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useEnsName */ +export function useEnsName< + config extends Config = ResolvedRegister['config'], + selectData = GetEnsNameData, +>( + parameters: UseEnsNameParameters = {}, +): UseEnsNameReturnType { + const { address, query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = getEnsNameQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + const enabled = Boolean(address && (query.enabled ?? true)) + + return useQuery({ ...query, ...options, enabled }) +} diff --git a/wagmi-project/packages/react/src/hooks/useEnsResolver.test.ts b/wagmi-project/packages/react/src/hooks/useEnsResolver.test.ts new file mode 100644 index 0000000000..f5b89d8f63 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEnsResolver.test.ts @@ -0,0 +1,50 @@ +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useEnsResolver } from './useEnsResolver.js' + +test('default', async () => { + const { result } = renderHook(() => + useEnsResolver({ + name: 'wevm.eth', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": "0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41", + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "ensResolver", + { + "chainId": 1, + "name": "wevm.eth", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) diff --git a/wagmi-project/packages/react/src/hooks/useEnsResolver.ts b/wagmi-project/packages/react/src/hooks/useEnsResolver.ts new file mode 100644 index 0000000000..e883debfa6 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEnsResolver.ts @@ -0,0 +1,58 @@ +'use client' + +import type { + Config, + GetEnsResolverErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetEnsResolverData, + type GetEnsResolverOptions, + type GetEnsResolverQueryFnData, + type GetEnsResolverQueryKey, + getEnsResolverQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseEnsResolverParameters< + config extends Config = Config, + selectData = GetEnsResolverData, +> = Compute< + GetEnsResolverOptions & + ConfigParameter & + QueryParameter< + GetEnsResolverQueryFnData, + GetEnsResolverErrorType, + selectData, + GetEnsResolverQueryKey + > +> + +export type UseEnsResolverReturnType = + UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useEnsResolver */ +export function useEnsResolver< + config extends Config = ResolvedRegister['config'], + selectData = GetEnsResolverData, +>( + parameters: UseEnsResolverParameters = {}, +): UseEnsResolverReturnType { + const { name, query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = getEnsResolverQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + const enabled = Boolean(name && (query.enabled ?? true)) + + return useQuery({ ...query, ...options, enabled }) +} diff --git a/wagmi-project/packages/react/src/hooks/useEnsText.test.ts b/wagmi-project/packages/react/src/hooks/useEnsText.test.ts new file mode 100644 index 0000000000..5e1c4b1d8c --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEnsText.test.ts @@ -0,0 +1,150 @@ +import { wait } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useEnsText } from './useEnsText.js' + +test('default', async () => { + const { result } = renderHook(() => + useEnsText({ + key: 'com.twitter', + name: 'wevm.eth', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": "wevm_dev", + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "ensText", + { + "chainId": 1, + "key": "com.twitter", + "name": "wevm.eth", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: name: undefined -> defined', async () => { + let name: string | undefined = undefined + + const { result, rerender } = renderHook(() => + useEnsText({ + key: 'com.twitter', + name, + }), + ) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": undefined, + "dataUpdatedAt": 0, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": false, + "isFetchedAfterMount": false, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": true, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": false, + "queryKey": [ + "ensText", + { + "chainId": 1, + "key": "com.twitter", + "name": undefined, + }, + ], + "refetch": [Function], + "status": "pending", + } + `) + + name = 'wevm.eth' + rerender() + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": "wevm_dev", + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "ensText", + { + "chainId": 1, + "key": "com.twitter", + "name": "wevm.eth", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: disabled when properties missing', async () => { + const { result } = renderHook(() => useEnsText()) + + await wait(100) + await waitFor(() => expect(result.current.isPending).toBeTruthy()) +}) diff --git a/wagmi-project/packages/react/src/hooks/useEnsText.ts b/wagmi-project/packages/react/src/hooks/useEnsText.ts new file mode 100644 index 0000000000..2e65238c4f --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEnsText.ts @@ -0,0 +1,54 @@ +'use client' + +import type { Config, GetEnsTextErrorType, ResolvedRegister } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetEnsTextData, + type GetEnsTextOptions, + type GetEnsTextQueryFnData, + type GetEnsTextQueryKey, + getEnsTextQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseEnsTextParameters< + config extends Config = Config, + selectData = GetEnsTextData, +> = Compute< + GetEnsTextOptions & + ConfigParameter & + QueryParameter< + GetEnsTextQueryFnData, + GetEnsTextErrorType, + selectData, + GetEnsTextQueryKey + > +> + +export type UseEnsTextReturnType = + UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useEnsText */ +export function useEnsText< + config extends Config = ResolvedRegister['config'], + selectData = GetEnsTextData, +>( + parameters: UseEnsTextParameters = {}, +): UseEnsTextReturnType { + const { key, name, query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = getEnsTextQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + const enabled = Boolean(key && name && (query.enabled ?? true)) + + return useQuery({ ...query, ...options, enabled }) +} diff --git a/wagmi-project/packages/react/src/hooks/useEstimateFeesPerGas.test-d.ts b/wagmi-project/packages/react/src/hooks/useEstimateFeesPerGas.test-d.ts new file mode 100644 index 0000000000..679def0fd6 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEstimateFeesPerGas.test-d.ts @@ -0,0 +1,49 @@ +import { expectTypeOf, test } from 'vitest' +import { useEstimateFeesPerGas } from './useEstimateFeesPerGas.js' + +test('types', () => { + const result = useEstimateFeesPerGas() + expectTypeOf(result.data).toMatchTypeOf< + | { + gasPrice?: undefined + maxFeePerGas: bigint + maxPriorityFeePerGas: bigint + formatted: { + gasPrice?: undefined + maxFeePerGas: string + maxPriorityFeePerGas: string + } + } + | undefined + >() + + const result2 = useEstimateFeesPerGas({ type: 'legacy' }) + expectTypeOf(result2.data).toMatchTypeOf< + | { + gasPrice: bigint + maxFeePerGas?: undefined + maxPriorityFeePerGas?: undefined + formatted: { + gasPrice: string + maxFeePerGas?: undefined + maxPriorityFeePerGas?: undefined + } + } + | undefined + >() + + const result3 = useEstimateFeesPerGas({ type: 'eip1559' }) + expectTypeOf(result3.data).toMatchTypeOf< + | { + gasPrice?: undefined + maxFeePerGas: bigint + maxPriorityFeePerGas: bigint + formatted: { + gasPrice?: undefined + maxFeePerGas: string + maxPriorityFeePerGas: string + } + } + | undefined + >() +}) diff --git a/wagmi-project/packages/react/src/hooks/useEstimateFeesPerGas.test.ts b/wagmi-project/packages/react/src/hooks/useEstimateFeesPerGas.test.ts new file mode 100644 index 0000000000..5d1859eda9 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEstimateFeesPerGas.test.ts @@ -0,0 +1,19 @@ +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useEstimateFeesPerGas } from './useEstimateFeesPerGas.js' + +test('default', async () => { + const { result } = renderHook(() => useEstimateFeesPerGas()) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(Object.keys(result.current.data!)).toMatchInlineSnapshot(` + [ + "formatted", + "gasPrice", + "maxFeePerGas", + "maxPriorityFeePerGas", + ] + `) +}) diff --git a/wagmi-project/packages/react/src/hooks/useEstimateFeesPerGas.ts b/wagmi-project/packages/react/src/hooks/useEstimateFeesPerGas.ts new file mode 100644 index 0000000000..59dc2aa910 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEstimateFeesPerGas.ts @@ -0,0 +1,62 @@ +'use client' + +import type { + Config, + EstimateFeesPerGasErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type EstimateFeesPerGasData, + type EstimateFeesPerGasOptions, + type EstimateFeesPerGasQueryFnData, + type EstimateFeesPerGasQueryKey, + estimateFeesPerGasQueryOptions, +} from '@wagmi/core/query' +import type { FeeValuesType } from 'viem' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseEstimateFeesPerGasParameters< + type extends FeeValuesType = FeeValuesType, + config extends Config = Config, + selectData = EstimateFeesPerGasData, +> = Compute< + EstimateFeesPerGasOptions & + ConfigParameter & + QueryParameter< + EstimateFeesPerGasQueryFnData, + EstimateFeesPerGasErrorType, + selectData, + EstimateFeesPerGasQueryKey + > +> + +export type UseEstimateFeesPerGasReturnType< + type extends FeeValuesType = FeeValuesType, + selectData = EstimateFeesPerGasData, +> = UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useEstimateFeesPerGas */ +export function useEstimateFeesPerGas< + config extends Config = ResolvedRegister['config'], + type extends FeeValuesType = 'eip1559', + selectData = EstimateFeesPerGasData, +>( + parameters: UseEstimateFeesPerGasParameters = {}, +): UseEstimateFeesPerGasReturnType { + const { query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = estimateFeesPerGasQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + + return useQuery({ ...query, ...options }) +} diff --git a/wagmi-project/packages/react/src/hooks/useEstimateGas.test-d.ts b/wagmi-project/packages/react/src/hooks/useEstimateGas.test-d.ts new file mode 100644 index 0000000000..d50618aad2 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEstimateGas.test-d.ts @@ -0,0 +1,14 @@ +import { expectTypeOf, test } from 'vitest' + +import { useEstimateGas } from './useEstimateGas.js' + +test('select data', () => { + const result = useEstimateGas({ + query: { + select(data) { + return data.toString() + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useEstimateGas.test.ts b/wagmi-project/packages/react/src/hooks/useEstimateGas.test.ts new file mode 100644 index 0000000000..0c3ab08324 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEstimateGas.test.ts @@ -0,0 +1,139 @@ +import { accounts } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { type Address, parseEther } from 'viem' +import { expect, test } from 'vitest' + +import { useEstimateGas } from './useEstimateGas.js' + +test('default', async () => { + const { result } = renderHook(() => + useEstimateGas({ + account: accounts[0], + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": 21000n, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "estimateGas", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 1, + "to": "0xd2135CfB216b74109775236E36d4b433F1DF507B", + "value": 10000000000000000n, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: address: undefined -> defined', async () => { + let account: Address | undefined = undefined + + const { result, rerender } = renderHook(() => useEstimateGas({ account })) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": undefined, + "dataUpdatedAt": 0, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": false, + "isFetchedAfterMount": false, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": true, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": false, + "queryKey": [ + "estimateGas", + { + "account": undefined, + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "pending", + } + `) + + account = accounts[0] + rerender() + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": 53001n, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "estimateGas", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) diff --git a/wagmi-project/packages/react/src/hooks/useEstimateGas.ts b/wagmi-project/packages/react/src/hooks/useEstimateGas.ts new file mode 100644 index 0000000000..87c0e19e44 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEstimateGas.ts @@ -0,0 +1,70 @@ +'use client' + +import type { + Config, + EstimateGasErrorType, + ResolvedRegister, +} from '@wagmi/core' +import { + type EstimateGasData, + type EstimateGasOptions, + type EstimateGasQueryFnData, + type EstimateGasQueryKey, + estimateGasQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' +import { useConnectorClient } from './useConnectorClient.js' + +export type UseEstimateGasParameters< + config extends Config = Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, + selectData = EstimateGasData, +> = EstimateGasOptions & + ConfigParameter & + QueryParameter< + EstimateGasQueryFnData, + EstimateGasErrorType, + selectData, + EstimateGasQueryKey + > + +export type UseEstimateGasReturnType = + UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useEstimateGas */ +export function useEstimateGas< + config extends Config = ResolvedRegister['config'], + chainId extends config['chains'][number]['id'] | undefined = undefined, + selectData = EstimateGasData, +>( + parameters?: UseEstimateGasParameters, +): UseEstimateGasReturnType + +export function useEstimateGas( + parameters: UseEstimateGasParameters = {}, +): UseEstimateGasReturnType { + const { connector, query = {} } = parameters + + const config = useConfig(parameters) + const { data: connectorClient } = useConnectorClient({ + config, + connector, + query: { enabled: parameters.account === undefined }, + }) + const account = parameters.account ?? connectorClient?.account + const chainId = useChainId({ config }) + + const options = estimateGasQueryOptions(config, { + ...parameters, + account, + chainId: parameters.chainId ?? chainId, + connector, + }) + const enabled = Boolean((account || connector) && (query.enabled ?? true)) + + return useQuery({ ...query, ...options, enabled }) +} diff --git a/wagmi-project/packages/react/src/hooks/useEstimateMaxPriorityFeePerGas.test-d.ts b/wagmi-project/packages/react/src/hooks/useEstimateMaxPriorityFeePerGas.test-d.ts new file mode 100644 index 0000000000..c4b1be1c8b --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEstimateMaxPriorityFeePerGas.test-d.ts @@ -0,0 +1,13 @@ +import { expectTypeOf, test } from 'vitest' +import { useEstimateMaxPriorityFeePerGas } from './useEstimateMaxPriorityFeePerGas.js' + +test('select data', () => { + const result = useEstimateMaxPriorityFeePerGas({ + query: { + select(data) { + return data.toString() + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useEstimateMaxPriorityFeePerGas.test.ts b/wagmi-project/packages/react/src/hooks/useEstimateMaxPriorityFeePerGas.test.ts new file mode 100644 index 0000000000..21c09188e3 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEstimateMaxPriorityFeePerGas.test.ts @@ -0,0 +1,96 @@ +import { chain, testClient } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useEstimateMaxPriorityFeePerGas } from './useEstimateMaxPriorityFeePerGas.js' + +test('default', async () => { + await testClient.mainnet.restart() + + const { result } = renderHook(() => useEstimateMaxPriorityFeePerGas()) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toBeTypeOf('bigint') + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "estimateMaxPriorityFeePerGas", + { + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: chainId', async () => { + await testClient.mainnet2.restart() + await testClient.mainnet2.mine({ blocks: 1 }) + + const { result } = renderHook(() => + useEstimateMaxPriorityFeePerGas({ chainId: chain.mainnet2.id }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toBeTypeOf('bigint') + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "estimateMaxPriorityFeePerGas", + { + "chainId": 456, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) diff --git a/wagmi-project/packages/react/src/hooks/useEstimateMaxPriorityFeePerGas.ts b/wagmi-project/packages/react/src/hooks/useEstimateMaxPriorityFeePerGas.ts new file mode 100644 index 0000000000..0f884dba75 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useEstimateMaxPriorityFeePerGas.ts @@ -0,0 +1,61 @@ +'use client' + +import type { + Config, + EstimateMaxPriorityFeePerGasErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type EstimateMaxPriorityFeePerGasData, + type EstimateMaxPriorityFeePerGasOptions, + type EstimateMaxPriorityFeePerGasQueryFnData, + type EstimateMaxPriorityFeePerGasQueryKey, + estimateMaxPriorityFeePerGasQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseEstimateMaxPriorityFeePerGasParameters< + config extends Config = Config, + selectData = EstimateMaxPriorityFeePerGasData, +> = Compute< + EstimateMaxPriorityFeePerGasOptions & + ConfigParameter & + QueryParameter< + EstimateMaxPriorityFeePerGasQueryFnData, + EstimateMaxPriorityFeePerGasErrorType, + selectData, + EstimateMaxPriorityFeePerGasQueryKey + > +> + +export type UseEstimateMaxPriorityFeePerGasReturnType< + selectData = EstimateMaxPriorityFeePerGasData, +> = UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useEstimateMaxPriorityFeePerGas */ +export function useEstimateMaxPriorityFeePerGas< + config extends Config = ResolvedRegister['config'], + selectData = EstimateMaxPriorityFeePerGasData, +>( + parameters: UseEstimateMaxPriorityFeePerGasParameters< + config, + selectData + > = {}, +): UseEstimateMaxPriorityFeePerGasReturnType { + const { query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = estimateMaxPriorityFeePerGasQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + + return useQuery({ ...query, ...options }) +} diff --git a/wagmi-project/packages/react/src/hooks/useFeeHistory.test-d.ts b/wagmi-project/packages/react/src/hooks/useFeeHistory.test-d.ts new file mode 100644 index 0000000000..855fa893ae --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useFeeHistory.test-d.ts @@ -0,0 +1,14 @@ +import { expectTypeOf, test } from 'vitest' + +import { useFeeHistory } from './useFeeHistory.js' + +test('select data', () => { + const result = useFeeHistory({ + query: { + select(data) { + return data.gasUsedRatio + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useFeeHistory.test.ts b/wagmi-project/packages/react/src/hooks/useFeeHistory.test.ts new file mode 100644 index 0000000000..53b6a8c55b --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useFeeHistory.test.ts @@ -0,0 +1,452 @@ +import { chain, wait } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useFeeHistory } from './useFeeHistory.js' + +test('default', async () => { + const { result } = renderHook(() => + useFeeHistory({ + blockCount: 4, + rewardPercentiles: [25, 75], + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toMatchObject({ + baseFeePerGas: expect.arrayContaining([expect.any(BigInt)]), + gasUsedRatio: expect.arrayContaining([expect.any(Number)]), + oldestBlock: expect.any(BigInt), + reward: expect.any(Array), + }) + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "feeHistory", + { + "blockCount": 4, + "chainId": 1, + "rewardPercentiles": [ + 25, + 75, + ], + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: chainId', async () => { + const { result } = renderHook(() => + useFeeHistory({ + blockCount: 4, + rewardPercentiles: [25, 75], + chainId: chain.mainnet2.id, + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toMatchObject({ + baseFeePerGas: expect.arrayContaining([expect.any(BigInt)]), + gasUsedRatio: expect.arrayContaining([expect.any(Number)]), + oldestBlock: expect.any(BigInt), + reward: expect.any(Array), + }) + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "feeHistory", + { + "blockCount": 4, + "chainId": 456, + "rewardPercentiles": [ + 25, + 75, + ], + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: blockNumber', async () => { + const { result } = renderHook(() => + useFeeHistory({ + blockCount: 4, + rewardPercentiles: [25, 75], + blockNumber: 18677379n, + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toMatchObject({ + baseFeePerGas: expect.arrayContaining([expect.any(BigInt)]), + gasUsedRatio: expect.arrayContaining([expect.any(Number)]), + oldestBlock: expect.any(BigInt), + reward: expect.any(Array), + }) + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "feeHistory", + { + "blockCount": 4, + "blockNumber": 18677379n, + "chainId": 1, + "rewardPercentiles": [ + 25, + 75, + ], + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: blockTag', async () => { + const { result } = renderHook(() => + useFeeHistory({ + blockCount: 4, + rewardPercentiles: [25, 75], + blockTag: 'safe', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toMatchObject({ + baseFeePerGas: expect.arrayContaining([expect.any(BigInt)]), + gasUsedRatio: expect.arrayContaining([expect.any(Number)]), + oldestBlock: expect.any(BigInt), + reward: expect.any(Array), + }) + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "feeHistory", + { + "blockCount": 4, + "blockTag": "safe", + "chainId": 1, + "rewardPercentiles": [ + 25, + 75, + ], + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: blockCount: undefined -> defined', async () => { + let blockCount: number | undefined = undefined + + const { result, rerender } = renderHook(() => + useFeeHistory({ + blockCount, + rewardPercentiles: [25, 75], + }), + ) + + { + const { data, ...rest } = result.current + expect(data).toBeTypeOf('undefined') + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 0, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": false, + "isFetchedAfterMount": false, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": true, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": false, + "queryKey": [ + "feeHistory", + { + "blockCount": undefined, + "chainId": 1, + "rewardPercentiles": [ + 25, + 75, + ], + }, + ], + "refetch": [Function], + "status": "pending", + } + `) + } + + blockCount = 4 + rerender() + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toMatchObject({ + baseFeePerGas: expect.arrayContaining([expect.any(BigInt)]), + gasUsedRatio: expect.arrayContaining([expect.any(Number)]), + oldestBlock: expect.any(BigInt), + reward: expect.any(Array), + }) + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "feeHistory", + { + "blockCount": 4, + "chainId": 1, + "rewardPercentiles": [ + 25, + 75, + ], + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: rewardPercentiles: undefined -> defined', async () => { + let rewardPercentiles: number[] | undefined = undefined + + const { result, rerender } = renderHook(() => + useFeeHistory({ + blockCount: 4, + rewardPercentiles, + }), + ) + + { + const { data, ...rest } = result.current + expect(data).toBeTypeOf('undefined') + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 0, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": false, + "isFetchedAfterMount": false, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": true, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": false, + "queryKey": [ + "feeHistory", + { + "blockCount": 4, + "chainId": 1, + "rewardPercentiles": undefined, + }, + ], + "refetch": [Function], + "status": "pending", + } + `) + } + + rewardPercentiles = [25, 75] + rerender() + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toMatchObject({ + baseFeePerGas: expect.arrayContaining([expect.any(BigInt)]), + gasUsedRatio: expect.arrayContaining([expect.any(Number)]), + oldestBlock: expect.any(BigInt), + reward: expect.any(Array), + }) + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "feeHistory", + { + "blockCount": 4, + "chainId": 1, + "rewardPercentiles": [ + 25, + 75, + ], + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: disabled when properties missing', async () => { + const { result } = renderHook(() => useFeeHistory()) + + await wait(100) + await waitFor(() => expect(result.current.isPending).toBeTruthy()) +}) diff --git a/wagmi-project/packages/react/src/hooks/useFeeHistory.ts b/wagmi-project/packages/react/src/hooks/useFeeHistory.ts new file mode 100644 index 0000000000..0754757b31 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useFeeHistory.ts @@ -0,0 +1,64 @@ +'use client' + +import type { + Config, + GetFeeHistoryErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetFeeHistoryData, + type GetFeeHistoryOptions, + type GetFeeHistoryQueryFnData, + type GetFeeHistoryQueryKey, + getFeeHistoryQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseFeeHistoryParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetFeeHistoryData, +> = Compute< + GetFeeHistoryOptions & + ConfigParameter & + QueryParameter< + GetFeeHistoryQueryFnData, + GetFeeHistoryErrorType, + selectData, + GetFeeHistoryQueryKey + > +> + +export type UseFeeHistoryReturnType = + UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useFeeHistory */ +export function useFeeHistory< + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetFeeHistoryData, +>( + parameters: UseFeeHistoryParameters = {}, +): UseFeeHistoryReturnType { + const { blockCount, rewardPercentiles, query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = getFeeHistoryQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + const enabled = Boolean( + blockCount && rewardPercentiles && (query.enabled ?? true), + ) + + return useQuery({ ...query, ...options, enabled }) +} diff --git a/wagmi-project/packages/react/src/hooks/useGasPrice.test-d.ts b/wagmi-project/packages/react/src/hooks/useGasPrice.test-d.ts new file mode 100644 index 0000000000..7108993a20 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useGasPrice.test-d.ts @@ -0,0 +1,14 @@ +import { expectTypeOf, test } from 'vitest' + +import { useGasPrice } from './useGasPrice.js' + +test('select data', () => { + const result = useGasPrice({ + query: { + select(data) { + return data?.toString() + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useGasPrice.test.ts b/wagmi-project/packages/react/src/hooks/useGasPrice.test.ts new file mode 100644 index 0000000000..5dd97cc96c --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useGasPrice.test.ts @@ -0,0 +1,103 @@ +import { chain, testClient } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useGasPrice } from './useGasPrice.js' + +test('default', async () => { + await testClient.mainnet.restart() + + await testClient.mainnet.setNextBlockBaseFeePerGas({ + baseFeePerGas: 2_000_000_000n, + }) + await testClient.mainnet.mine({ blocks: 1 }) + + const { result } = renderHook(() => useGasPrice()) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": 2750000000n, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "gasPrice", + { + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: chainId', async () => { + await testClient.mainnet2.restart() + + await testClient.mainnet2.setNextBlockBaseFeePerGas({ + baseFeePerGas: 1_000_000_000n, + }) + await testClient.mainnet2.mine({ blocks: 1 }) + + const { result } = renderHook(() => + useGasPrice({ chainId: chain.mainnet2.id }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": 1875000000n, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "gasPrice", + { + "chainId": 456, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) diff --git a/wagmi-project/packages/react/src/hooks/useGasPrice.ts b/wagmi-project/packages/react/src/hooks/useGasPrice.ts new file mode 100644 index 0000000000..dc823dcf64 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useGasPrice.ts @@ -0,0 +1,62 @@ +'use client' + +import type { + Config, + GetGasPriceErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetGasPriceData, + type GetGasPriceOptions, + type GetGasPriceQueryFnData, + type GetGasPriceQueryKey, + getGasPriceQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseGasPriceParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetGasPriceData, +> = Compute< + GetGasPriceOptions & + ConfigParameter & + QueryParameter< + GetGasPriceQueryFnData, + GetGasPriceErrorType, + selectData, + GetGasPriceQueryKey + > +> + +export type UseGasPriceReturnType = + UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useGasPrice */ +export function useGasPrice< + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetGasPriceData, +>( + parameters: UseGasPriceParameters = {}, +): UseGasPriceReturnType { + const { query = {} } = parameters + + const config = useConfig(parameters) + const configChainId = useChainId({ config }) + const chainId = parameters.chainId ?? configChainId + + const options = getGasPriceQueryOptions(config, { + ...parameters, + chainId, + }) + + return useQuery({ ...query, ...options }) +} diff --git a/wagmi-project/packages/react/src/hooks/useInfiniteReadContracts.test-d.ts b/wagmi-project/packages/react/src/hooks/useInfiniteReadContracts.test-d.ts new file mode 100644 index 0000000000..60b3a2cddd --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useInfiniteReadContracts.test-d.ts @@ -0,0 +1,44 @@ +import { abi } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { useInfiniteReadContracts } from './useInfiniteReadContracts.js' + +test('select data', () => { + const result = useInfiniteReadContracts({ + allowFailure: false, + cacheKey: 'foo', + contracts(pageParam) { + expectTypeOf(pageParam).toEqualTypeOf() + return [ + { + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + }, + { + address: '0x', + abi: abi.wagmiMintExample, + functionName: 'tokenURI', + args: [123n], + }, + ] + }, + query: { + initialPageParam: '0', + getNextPageParam(lastPage, allPages, lastPageParam, allPageParams) { + expectTypeOf(lastPage).toEqualTypeOf<[bigint, string]>() + expectTypeOf(allPages).toEqualTypeOf<[bigint, string][]>() + expectTypeOf(lastPageParam).toEqualTypeOf() + expectTypeOf(allPageParams).toEqualTypeOf() + return lastPageParam + 1 + }, + select(data) { + expectTypeOf(data.pageParams[0]!).toEqualTypeOf() + expectTypeOf(data.pages[0]!).toEqualTypeOf<[bigint, string]>() + return data.pages[0]?.[0]! + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useInfiniteReadContracts.test.ts b/wagmi-project/packages/react/src/hooks/useInfiniteReadContracts.test.ts new file mode 100644 index 0000000000..0feb1e0e98 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useInfiniteReadContracts.test.ts @@ -0,0 +1,91 @@ +import { abi, address } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useInfiniteReadContracts } from './useInfiniteReadContracts.js' + +test( + 'default', + async () => { + const limit = 3 + + const { result } = renderHook(() => + useInfiniteReadContracts({ + cacheKey: 'foo', + contracts(pageParam) { + return [...new Array(limit)].map( + (_, i) => + ({ + address: address.shields, + abi: abi.shields, + functionName: 'tokenURI', + args: [BigInt(pageParam + i + 1)], + }) as const, + ) + }, + query: { + initialPageParam: 0, + getNextPageParam(_lastPage, _allPages, lastPageParam) { + return lastPageParam + limit + }, + select(data) { + const results = [] + for (const page of data.pages) { + for (const response of page) { + if (response.status === 'success') { + const decoded = atob( + response.result.replace(/(^.*base64,)/, ''), + ) + const json = JSON.parse(decoded) as { name: string } + results.push(json.name) + } else results.push('Error fetching shield') + } + } + return results + }, + }, + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + expect(result.current.data).toMatchInlineSnapshot(` + [ + "Three Shields on Pink Perfect", + "Three Shields on Sky Perfect", + "Three Shields on Evergreen Perfect", + ] + `) + + await result.current.fetchNextPage() + + await waitFor(() => expect(result.current.hasNextPage).toBeTruthy()) + expect(result.current.data).toMatchInlineSnapshot(` + [ + "Three Shields on Pink Perfect", + "Three Shields on Sky Perfect", + "Three Shields on Evergreen Perfect", + "Three Shields on Hi-Vis Perfect", + "Three Shields on Gray Perfect", + "Everlasting: Tracery on Onyx and Pink Razor Bordure", + ] + `) + + await result.current.fetchNextPage() + + await waitFor(() => expect(result.current.hasNextPage).toBeTruthy()) + expect(result.current.data).toMatchInlineSnapshot(` + [ + "Three Shields on Pink Perfect", + "Three Shields on Sky Perfect", + "Three Shields on Evergreen Perfect", + "Three Shields on Hi-Vis Perfect", + "Three Shields on Gray Perfect", + "Everlasting: Tracery on Onyx and Pink Razor Bordure", + "The Book of Shields on Pink Perfect", + "Menacing: Necklace on Evergreen and Hi-Vis Chief Indented", + "Secured: Telescope and Stars on Ultraviolet and Sky Doppler", + ] + `) + }, + { timeout: 20_000 }, +) diff --git a/wagmi-project/packages/react/src/hooks/useInfiniteReadContracts.ts b/wagmi-project/packages/react/src/hooks/useInfiniteReadContracts.ts new file mode 100644 index 0000000000..2622f434a6 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useInfiniteReadContracts.ts @@ -0,0 +1,89 @@ +'use client' + +import type { + Config, + ReadContractsErrorType, + ResolvedRegister, +} from '@wagmi/core' +import { + type InfiniteReadContractsQueryFnData, + type InfiniteReadContractsQueryKey, + infiniteReadContractsQueryOptions, + structuralSharing, +} from '@wagmi/core/query' +import type { ContractFunctionParameters } from 'viem' + +import type { + InfiniteReadContractsData, + InfiniteReadContractsOptions, +} from '../exports/query.js' +import type { + ConfigParameter, + InfiniteQueryParameter, +} from '../types/properties.js' +import { + type UseInfiniteQueryParameters, + type UseInfiniteQueryReturnType, + useInfiniteQuery, +} from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseInfiniteContractReadsParameters< + contracts extends readonly unknown[] = readonly ContractFunctionParameters[], + allowFailure extends boolean = true, + config extends Config = Config, + pageParam = unknown, + selectData = InfiniteReadContractsData, +> = InfiniteReadContractsOptions & + ConfigParameter & + InfiniteQueryParameter< + InfiniteReadContractsQueryFnData, + ReadContractsErrorType, + selectData, + InfiniteReadContractsData, + InfiniteReadContractsQueryKey, + pageParam + > + +export type UseInfiniteContractReadsReturnType< + contracts extends readonly unknown[] = readonly ContractFunctionParameters[], + allowFailure extends boolean = true, + selectData = InfiniteReadContractsData, +> = UseInfiniteQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useInfiniteReadContracts */ +export function useInfiniteReadContracts< + const contracts extends readonly unknown[], + allowFailure extends boolean = true, + config extends Config = ResolvedRegister['config'], + pageParam = unknown, + selectData = InfiniteReadContractsData, +>( + parameters: UseInfiniteContractReadsParameters< + contracts, + allowFailure, + config, + pageParam, + selectData + >, +): UseInfiniteContractReadsReturnType { + const { contracts = [], query } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = infiniteReadContractsQueryOptions(config, { + ...parameters, + chainId, + contracts: contracts as UseInfiniteContractReadsParameters['contracts'], + query: query as UseInfiniteQueryParameters, + }) + + return useInfiniteQuery({ + ...(query as any), + ...options, + initialPageParam: options.initialPageParam, + structuralSharing: query.structuralSharing ?? structuralSharing, + }) +} diff --git a/wagmi-project/packages/react/src/hooks/usePrepareTransactionRequest.test-d.ts b/wagmi-project/packages/react/src/hooks/usePrepareTransactionRequest.test-d.ts new file mode 100644 index 0000000000..9c39595ab4 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/usePrepareTransactionRequest.test-d.ts @@ -0,0 +1,27 @@ +import { config } from '@wagmi/test' +import type { PrepareTransactionRequestReturnType } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { usePrepareTransactionRequest } from './usePrepareTransactionRequest.js' + +test('select data', () => { + const result = usePrepareTransactionRequest({ + query: { + select(data) { + return data + }, + }, + }) + + expectTypeOf(result.data).toMatchTypeOf< + PrepareTransactionRequestReturnType | undefined + >() +}) + +test('parameters: config', () => { + const result = usePrepareTransactionRequest({ + config, + chainId: 456, + }) + if (result.data) expectTypeOf(result.data.chainId).toEqualTypeOf<456>() +}) diff --git a/wagmi-project/packages/react/src/hooks/usePrepareTransactionRequest.test.ts b/wagmi-project/packages/react/src/hooks/usePrepareTransactionRequest.test.ts new file mode 100644 index 0000000000..7b90729dbf --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/usePrepareTransactionRequest.test.ts @@ -0,0 +1,81 @@ +import { connect, disconnect } from '@wagmi/core' +import { config } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { parseEther } from 'viem' +import { expect, test } from 'vitest' + +import { usePrepareTransactionRequest } from './usePrepareTransactionRequest.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const { result } = renderHook(() => + usePrepareTransactionRequest({ + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { + data: { + gas: _gas, + maxFeePerGas: _mfpg, + maxPriorityFeePerGas: _mpfpg, + nonce: _nonce, + ...data + } = {}, + ...rest + } = result.current + + expect(data).toMatchInlineSnapshot(` + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 1, + "from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "to": "0x70997970c51812dc3a010c7d01b50e0d17dc79c8", + "type": "eip1559", + "value": 1000000000000000000n, + } + `) + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "prepareTransactionRequest", + { + "chainId": 1, + "to": "0x70997970c51812dc3a010c7d01b50e0d17dc79c8", + "value": 1000000000000000000n, + }, + ], + "refetch": [Function], + "status": "success", + } + `) + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/react/src/hooks/usePrepareTransactionRequest.ts b/wagmi-project/packages/react/src/hooks/usePrepareTransactionRequest.ts new file mode 100644 index 0000000000..509d85eb08 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/usePrepareTransactionRequest.ts @@ -0,0 +1,102 @@ +'use client' + +import type { + Config, + PrepareTransactionRequestErrorType, + ResolvedRegister, + SelectChains, +} from '@wagmi/core' +import { + type PrepareTransactionRequestData, + type PrepareTransactionRequestOptions, + type PrepareTransactionRequestQueryKey, + prepareTransactionRequestQueryOptions, +} from '@wagmi/core/query' +import type { PrepareTransactionRequestQueryFnData } from '@wagmi/core/query' +import type { PrepareTransactionRequestRequest as viem_PrepareTransactionRequestRequest } from 'viem' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UsePrepareTransactionRequestParameters< + config extends Config = Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, + request extends viem_PrepareTransactionRequestRequest< + SelectChains[0], + SelectChains[0] + > = viem_PrepareTransactionRequestRequest< + SelectChains[0], + SelectChains[0] + >, + selectData = PrepareTransactionRequestData, +> = PrepareTransactionRequestOptions & + ConfigParameter & + QueryParameter< + PrepareTransactionRequestQueryFnData, + PrepareTransactionRequestErrorType, + selectData, + PrepareTransactionRequestQueryKey + > + +export type UsePrepareTransactionRequestReturnType< + config extends Config = Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, + request extends viem_PrepareTransactionRequestRequest< + SelectChains[0], + SelectChains[0] + > = viem_PrepareTransactionRequestRequest< + SelectChains[0], + SelectChains[0] + >, + selectData = PrepareTransactionRequestData, +> = UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/usePrepareTransactionRequest */ +export function usePrepareTransactionRequest< + config extends Config = ResolvedRegister['config'], + chainId extends config['chains'][number]['id'] | undefined = undefined, + request extends viem_PrepareTransactionRequestRequest< + SelectChains[0], + SelectChains[0] + > = viem_PrepareTransactionRequestRequest< + SelectChains[0], + SelectChains[0] + >, + selectData = PrepareTransactionRequestData, +>( + parameters: UsePrepareTransactionRequestParameters< + config, + chainId, + request, + selectData + > = {} as any, +): UsePrepareTransactionRequestReturnType< + config, + chainId, + request, + selectData +> { + const { to, query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = prepareTransactionRequestQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + } as PrepareTransactionRequestOptions) + const enabled = Boolean(to && (query.enabled ?? true)) + + return useQuery({ + ...(query as any), + ...options, + enabled, + }) as UsePrepareTransactionRequestReturnType< + config, + chainId, + request, + selectData + > +} diff --git a/wagmi-project/packages/react/src/hooks/useProof.test-d.ts b/wagmi-project/packages/react/src/hooks/useProof.test-d.ts new file mode 100644 index 0000000000..55f8b15330 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useProof.test-d.ts @@ -0,0 +1,14 @@ +import type { GetProofReturnType } from 'viem' +import { expectTypeOf, test } from 'vitest' +import { useProof } from './useProof.js' + +test('select data', () => { + const result = useProof({ + query: { + select(data) { + return data + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useProof.test.ts b/wagmi-project/packages/react/src/hooks/useProof.test.ts new file mode 100644 index 0000000000..3c3cb51945 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useProof.test.ts @@ -0,0 +1,163 @@ +import { chain, wait } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import type { Address } from 'viem' +import { useProof } from './useProof.js' + +test('default', async () => { + const { result } = renderHook(() => + useProof({ + address: '0x4200000000000000000000000000000000000016', + chainId: chain.optimism.id, + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect({ ...result.current, data: null }).toMatchInlineSnapshot(` + { + "data": null, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getProof", + { + "address": "0x4200000000000000000000000000000000000016", + "chainId": 10, + "storageKeys": [ + "0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99", + ], + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: address: undefined -> defined', async () => { + let address: Address | undefined = undefined + + const { result, rerender } = renderHook(() => + useProof({ + address, + chainId: chain.optimism.id, + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], + }), + ) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": undefined, + "dataUpdatedAt": 0, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": false, + "isFetchedAfterMount": false, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": true, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": false, + "queryKey": [ + "getProof", + { + "address": undefined, + "chainId": 10, + "storageKeys": [ + "0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99", + ], + }, + ], + "refetch": [Function], + "status": "pending", + } + `) + + address = '0x4200000000000000000000000000000000000016' + rerender() + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect({ ...result.current, data: null }).toMatchInlineSnapshot(` + { + "data": null, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getProof", + { + "address": "0x4200000000000000000000000000000000000016", + "chainId": 10, + "storageKeys": [ + "0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99", + ], + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: disabled when properties missing', async () => { + const { result } = renderHook(() => useProof()) + + await wait(100) + await waitFor(() => expect(result.current.isPending).toBeTruthy()) +}) diff --git a/wagmi-project/packages/react/src/hooks/useProof.ts b/wagmi-project/packages/react/src/hooks/useProof.ts new file mode 100644 index 0000000000..f473d509aa --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useProof.ts @@ -0,0 +1,56 @@ +'use client' + +import type { Config, GetProofErrorType, ResolvedRegister } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetProofData, + type GetProofOptions, + type GetProofQueryKey, + getProofQueryOptions, +} from '@wagmi/core/query' +import type { GetProofQueryFnData } from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseProofParameters< + config extends Config = Config, + selectData = GetProofData, +> = Compute< + GetProofOptions & + ConfigParameter & + QueryParameter< + GetProofQueryFnData, + GetProofErrorType, + selectData, + GetProofQueryKey + > +> + +export type UseProofReturnType = UseQueryReturnType< + selectData, + GetProofErrorType +> + +/** https://wagmi.sh/react/api/hooks/useProof */ +export function useProof< + config extends Config = ResolvedRegister['config'], + selectData = GetProofData, +>( + parameters: UseProofParameters = {}, +): UseProofReturnType { + const { address, storageKeys, query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = getProofQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + const enabled = Boolean(address && storageKeys && (query.enabled ?? true)) + + return useQuery({ ...query, ...options, enabled }) +} diff --git a/wagmi-project/packages/react/src/hooks/usePublicClient.test-d.ts b/wagmi-project/packages/react/src/hooks/usePublicClient.test-d.ts new file mode 100644 index 0000000000..5d259e5c4e --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/usePublicClient.test-d.ts @@ -0,0 +1,40 @@ +import { chain, config } from '@wagmi/test' +import type { Chain } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { usePublicClient } from './usePublicClient.js' + +test('default', () => { + const client = usePublicClient({ config }) + expectTypeOf(client.chain).toEqualTypeOf<(typeof config)['chains'][number]>() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() +}) + +test('parameters: chainId', () => { + const client = usePublicClient({ + config, + chainId: chain.mainnet.id, + }) + expectTypeOf(client.chain).toEqualTypeOf() + expectTypeOf(client.chain).not.toEqualTypeOf() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() +}) + +test('behavior: unconfigured chain', () => { + { + const client = usePublicClient({ chainId: 123456 }) + if (client) { + expectTypeOf(client.chain).toEqualTypeOf() + expectTypeOf(client.transport.type).toEqualTypeOf() + } else { + expectTypeOf(client).toEqualTypeOf() + } + } + + const client = usePublicClient({ + config, + // @ts-expect-error + chainId: 123456, + }) + expectTypeOf(client).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/usePublicClient.test.ts b/wagmi-project/packages/react/src/hooks/usePublicClient.test.ts new file mode 100644 index 0000000000..93602746bb --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/usePublicClient.test.ts @@ -0,0 +1,30 @@ +import { switchChain } from '@wagmi/core' +import { config } from '@wagmi/test' +import { renderHook } from '@wagmi/test/react' +import { Fragment, createElement } from 'react' +import { expect, test } from 'vitest' + +import { usePublicClient } from './usePublicClient.js' + +test('default', async () => { + const { result, rerender } = renderHook(() => usePublicClient()) + + expect(result.current?.chain.id).toEqual(1) + + await switchChain(config, { chainId: 456 }) + rerender() + + expect(result.current?.chain.id).toEqual(456) +}) + +test('parameters: config', () => { + const { result } = renderHook(() => usePublicClient({ config }), { + wrapper: ({ children }) => createElement(Fragment, { children }), + }) + expect(result.current).toBeDefined() +}) + +test('behavior: unconfigured chain', () => { + const { result } = renderHook(() => usePublicClient({ chainId: 123456 })) + expect(result.current).toBeUndefined() +}) diff --git a/wagmi-project/packages/react/src/hooks/usePublicClient.ts b/wagmi-project/packages/react/src/hooks/usePublicClient.ts new file mode 100644 index 0000000000..5193f170b6 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/usePublicClient.ts @@ -0,0 +1,51 @@ +'use client' + +import { + type Config, + type GetPublicClientParameters, + type GetPublicClientReturnType, + type ResolvedRegister, + getPublicClient, + watchPublicClient, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/shim/with-selector.js' + +import type { ConfigParameter } from '../types/properties.js' +import { useConfig } from './useConfig.js' + +export type UsePublicClientParameters< + config extends Config = Config, + chainId extends config['chains'][number]['id'] | number | undefined = + | config['chains'][number]['id'] + | undefined, +> = Compute< + GetPublicClientParameters & ConfigParameter +> + +export type UsePublicClientReturnType< + config extends Config = Config, + chainId extends config['chains'][number]['id'] | number | undefined = + | config['chains'][number]['id'] + | undefined, +> = GetPublicClientReturnType + +/** https://wagmi.sh/react/api/hooks/usePublicClient */ +export function usePublicClient< + config extends Config = ResolvedRegister['config'], + chainId extends config['chains'][number]['id'] | number | undefined = + | config['chains'][number]['id'] + | undefined, +>( + parameters: UsePublicClientParameters = {}, +): UsePublicClientReturnType { + const config = useConfig(parameters) + + return useSyncExternalStoreWithSelector( + (onChange) => watchPublicClient(config, { onChange }), + () => getPublicClient(config, parameters), + () => getPublicClient(config, parameters), + (x) => x, + (a, b) => a?.uid === b?.uid, + ) as any +} diff --git a/wagmi-project/packages/react/src/hooks/useReadContract.test-d.ts b/wagmi-project/packages/react/src/hooks/useReadContract.test-d.ts new file mode 100644 index 0000000000..3b57d49a9e --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useReadContract.test-d.ts @@ -0,0 +1,96 @@ +import { abi } from '@wagmi/test' +import type { Address } from 'viem' +import { assertType, expectTypeOf, test } from 'vitest' + +import { + type UseReadContractParameters, + type UseReadContractReturnType, + useReadContract, +} from './useReadContract.js' + +test('select data', () => { + const result = useReadContract({ + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + query: { + select(data) { + expectTypeOf(data).toEqualTypeOf() + return data?.toString() + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) + +test('UseReadContractParameters', () => { + type Result = UseReadContractParameters + expectTypeOf>().toEqualTypeOf<{ + functionName?: + | 'symbol' + | 'name' + | 'allowance' + | 'balanceOf' + | 'decimals' + | 'totalSupply' + | undefined + args?: readonly [Address] | undefined + }>() +}) + +test('UseReadContractReturnType', () => { + type Result = UseReadContractReturnType + expectTypeOf().toEqualTypeOf() +}) + +test('overloads', () => { + const result1 = useReadContract({ + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + }) + assertType(result1.data) + + const result2 = useReadContract({ + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: [], + }) + assertType(result2.data) + + const result3 = useReadContract({ + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: ['0x'], + }) + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + assertType(result3.data) + + const result4 = useReadContract({ + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: ['0x', '0x'], + }) + assertType< + | { + foo: `0x${string}` + bar: `0x${string}` + } + | undefined + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + >(result4.data) +}) + +test('deployless read (bytecode)', () => { + const result = useReadContract({ + code: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useReadContract.test.ts b/wagmi-project/packages/react/src/hooks/useReadContract.test.ts new file mode 100644 index 0000000000..c94ca996ce --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useReadContract.test.ts @@ -0,0 +1,194 @@ +import { QueryClientProvider } from '@tanstack/react-query' +import { abi, address, bytecode, chain, config, wait } from '@wagmi/test' +import { queryClient, renderHook, waitFor } from '@wagmi/test/react' +import { createElement } from 'react' +import { expect, test } from 'vitest' + +import { useReadContract } from './useReadContract.js' + +test('default', async () => { + const { result } = renderHook(() => + useReadContract({ + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'balanceOf', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": 4n, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "readContract", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": [ + "0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC", + ], + "chainId": 1, + "functionName": "balanceOf", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: chainId', async () => { + const { result } = renderHook(() => + useReadContract({ + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'balanceOf', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + chainId: chain.mainnet2.id, + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": 4n, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "readContract", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": [ + "0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC", + ], + "chainId": 456, + "functionName": "balanceOf", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: config', async () => { + const { result } = renderHook( + () => + useReadContract({ + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'balanceOf', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + config, + }), + { + wrapper: ({ children }) => + createElement(QueryClientProvider, { client: queryClient }, children), + }, + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": 4n, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "readContract", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": [ + "0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC", + ], + "chainId": 1, + "functionName": "balanceOf", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: deployless read (bytecode)', async () => { + const { result } = renderHook(() => + useReadContract({ + abi: abi.wagmiMintExample, + functionName: 'name', + code: bytecode.wagmiMintExample, + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current.data).toMatchInlineSnapshot(`"wagmi"`) +}) + +test('behavior: disabled when properties missing', async () => { + const { result } = renderHook(() => useReadContract()) + + await wait(100) + await waitFor(() => expect(result.current.isPending).toBeTruthy()) +}) diff --git a/wagmi-project/packages/react/src/hooks/useReadContract.ts b/wagmi-project/packages/react/src/hooks/useReadContract.ts new file mode 100644 index 0000000000..6eb6d6d64f --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useReadContract.ts @@ -0,0 +1,99 @@ +'use client' + +import type { + Config, + ReadContractErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { UnionCompute } from '@wagmi/core/internal' +import { + type ReadContractData, + type ReadContractOptions, + type ReadContractQueryFnData, + type ReadContractQueryKey, + readContractQueryOptions, + structuralSharing, +} from '@wagmi/core/query' +import type { Abi, ContractFunctionArgs, ContractFunctionName, Hex } from 'viem' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseReadContractParameters< + abi extends Abi | readonly unknown[] = Abi, + functionName extends ContractFunctionName< + abi, + 'pure' | 'view' + > = ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'pure' | 'view', + functionName + > = ContractFunctionArgs, + config extends Config = Config, + selectData = ReadContractData, +> = UnionCompute< + ReadContractOptions & + ConfigParameter & + QueryParameter< + ReadContractQueryFnData, + ReadContractErrorType, + selectData, + ReadContractQueryKey + > +> + +export type UseReadContractReturnType< + abi extends Abi | readonly unknown[] = Abi, + functionName extends ContractFunctionName< + abi, + 'pure' | 'view' + > = ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'pure' | 'view', + functionName + > = ContractFunctionArgs, + selectData = ReadContractData, +> = UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useReadContract */ +export function useReadContract< + const abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs, + config extends Config = ResolvedRegister['config'], + selectData = ReadContractData, +>( + parameters: UseReadContractParameters< + abi, + functionName, + args, + config, + selectData + > = {} as any, +): UseReadContractReturnType { + const { abi, address, functionName, query = {} } = parameters + // @ts-ignore + const code = parameters.code as Hex | undefined + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = readContractQueryOptions( + config, + { ...(parameters as any), chainId: parameters.chainId ?? chainId }, + ) + const enabled = Boolean( + (address || code) && abi && functionName && (query.enabled ?? true), + ) + + return useQuery({ + ...query, + ...options, + enabled, + structuralSharing: query.structuralSharing ?? structuralSharing, + }) +} diff --git a/wagmi-project/packages/react/src/hooks/useReadContracts.test-d.ts b/wagmi-project/packages/react/src/hooks/useReadContracts.test-d.ts new file mode 100644 index 0000000000..8aa786436a --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useReadContracts.test-d.ts @@ -0,0 +1,93 @@ +import { abi } from '@wagmi/test' +import { assertType, expectTypeOf, test } from 'vitest' + +import { useReadContracts } from './useReadContracts.js' + +test('select data', () => { + const result = useReadContracts({ + allowFailure: false, + contracts: [ + { + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + chainId: 1, + args: ['0x'], + }, + { + address: '0x', + abi: abi.wagmiMintExample, + functionName: 'tokenURI', + args: [123n], + }, + ], + query: { + select(data) { + expectTypeOf(data).toEqualTypeOf<[bigint, string]>() + return data[0] + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) + +test('overloads', async () => { + const result1 = useReadContracts({ + allowFailure: false, + contracts: [ + { + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + }, + ], + }) + assertType<[number] | undefined>(result1.data) + + const result2 = useReadContracts({ + allowFailure: false, + contracts: [ + { + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: [], + }, + ], + }) + assertType<[number] | undefined>(result2.data) + + const result3 = useReadContracts({ + allowFailure: false, + contracts: [ + { + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: ['0x'], + }, + ], + }) + assertType<[string] | undefined>(result3.data) + + const result4 = useReadContracts({ + allowFailure: false, + contracts: [ + { + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: ['0x', '0x'], + }, + ], + }) + assertType< + | [ + { + foo: `0x${string}` + bar: `0x${string}` + }, + ] + | undefined + >(result4.data) +}) diff --git a/wagmi-project/packages/react/src/hooks/useReadContracts.test.ts b/wagmi-project/packages/react/src/hooks/useReadContracts.test.ts new file mode 100644 index 0000000000..e7636b254e --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useReadContracts.test.ts @@ -0,0 +1,262 @@ +import { abi, address, chain } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useReadContracts } from './useReadContracts.js' + +test('default', async () => { + const { result } = renderHook(() => + useReadContracts({ + contracts: [ + { + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'balanceOf', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }, + { + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'symbol', + }, + ], + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": [ + { + "result": 4n, + "status": "success", + }, + { + "result": "WAGMI", + "status": "success", + }, + ], + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "readContracts", + { + "chainId": 1, + "contracts": [ + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": [ + "0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC", + ], + "chainId": 1, + "functionName": "balanceOf", + }, + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "chainId": 1, + "functionName": "symbol", + }, + ], + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test.skip('multichain', async () => { + const { mainnet, mainnet2, optimism } = chain + const { result } = renderHook(() => + useReadContracts({ + contracts: [ + { + abi: abi.wagmigotchi, + address: address.wagmigotchi, + chainId: mainnet.id, + functionName: 'love', + args: ['0x27a69ffba1e939ddcfecc8c7e0f967b872bac65c'], + }, + { + abi: abi.wagmigotchi, + address: address.wagmigotchi, + chainId: mainnet.id, + functionName: 'love', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }, + { + abi: abi.wagmigotchi, + address: address.wagmigotchi, + chainId: mainnet.id, + functionName: 'love', + args: ['0xd2135CfB216b74109775236E36d4b433F1DF507B'], + }, + { + abi: abi.wagmigotchi, + address: address.wagmigotchi, + chainId: mainnet2.id, + functionName: 'getAlive', + }, + { + abi: abi.mloot, + address: address.mloot, + chainId: mainnet2.id, + functionName: 'tokenOfOwnerByIndex', + args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', 0n], + }, + { + abi: abi.erc20, + address: address.optimism.usdc, + chainId: optimism.id, + functionName: 'symbol', + }, + { + abi: abi.erc20, + address: address.optimism.usdc, + chainId: optimism.id, + functionName: 'balanceOf', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }, + ], + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": [ + { + "result": 2n, + "status": "success", + }, + { + "result": 1n, + "status": "success", + }, + { + "result": 0n, + "status": "success", + }, + { + "result": false, + "status": "success", + }, + { + "result": 370395n, + "status": "success", + }, + { + "result": "USDC", + "status": "success", + }, + { + "result": 10959340n, + "status": "success", + }, + ], + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "readContracts", + { + "chainId": 1, + "contracts": [ + { + "address": "0xecb504d39723b0be0e3a9aa33d646642d1051ee1", + "args": [ + "0x27a69ffba1e939ddcfecc8c7e0f967b872bac65c", + ], + "chainId": 1, + "functionName": "love", + }, + { + "address": "0xecb504d39723b0be0e3a9aa33d646642d1051ee1", + "args": [ + "0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC", + ], + "chainId": 1, + "functionName": "love", + }, + { + "address": "0xecb504d39723b0be0e3a9aa33d646642d1051ee1", + "args": [ + "0xd2135CfB216b74109775236E36d4b433F1DF507B", + ], + "chainId": 1, + "functionName": "love", + }, + { + "address": "0xecb504d39723b0be0e3a9aa33d646642d1051ee1", + "chainId": 456, + "functionName": "getAlive", + }, + { + "address": "0x1dfe7ca09e99d10835bf73044a23b73fc20623df", + "args": [ + "0xA0Cf798816D4b9b9866b5330EEa46a18382f251e", + 0n, + ], + "chainId": 456, + "functionName": "tokenOfOwnerByIndex", + }, + { + "address": "0x7f5c764cbc14f9669b88837ca1490cca17c31607", + "chainId": 10, + "functionName": "symbol", + }, + { + "address": "0x7f5c764cbc14f9669b88837ca1490cca17c31607", + "args": [ + "0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC", + ], + "chainId": 10, + "functionName": "balanceOf", + }, + ], + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) diff --git a/wagmi-project/packages/react/src/hooks/useReadContracts.ts b/wagmi-project/packages/react/src/hooks/useReadContracts.ts new file mode 100644 index 0000000000..7be786c4a8 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useReadContracts.ts @@ -0,0 +1,91 @@ +'use client' + +import type { + Config, + ReadContractsErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type ReadContractsData, + type ReadContractsOptions, + type ReadContractsQueryFnData, + type ReadContractsQueryKey, + readContractsQueryOptions, + structuralSharing, +} from '@wagmi/core/query' +import { useMemo } from 'react' +import type { ContractFunctionParameters } from 'viem' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseReadContractsParameters< + contracts extends readonly unknown[] = readonly ContractFunctionParameters[], + allowFailure extends boolean = true, + config extends Config = Config, + selectData = ReadContractsData, +> = Compute< + ReadContractsOptions & + ConfigParameter & + QueryParameter< + ReadContractsQueryFnData, + ReadContractsErrorType, + selectData, + ReadContractsQueryKey + > +> + +export type UseReadContractsReturnType< + contracts extends readonly unknown[] = readonly ContractFunctionParameters[], + allowFailure extends boolean = true, + selectData = ReadContractsData, +> = UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useReadContracts */ +export function useReadContracts< + const contracts extends readonly unknown[], + allowFailure extends boolean = true, + config extends Config = ResolvedRegister['config'], + selectData = ReadContractsData, +>( + parameters: UseReadContractsParameters< + contracts, + allowFailure, + config, + selectData + > = {}, +): UseReadContractsReturnType { + const { contracts = [], query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = readContractsQueryOptions( + config, + { ...parameters, chainId }, + ) + + const enabled = useMemo(() => { + let isContractsValid = false + for (const contract of contracts) { + const { abi, address, functionName } = + contract as ContractFunctionParameters + if (!abi || !address || !functionName) { + isContractsValid = false + break + } + isContractsValid = true + } + return Boolean(isContractsValid && (query.enabled ?? true)) + }, [contracts, query.enabled]) + + return useQuery({ + ...options, + ...query, + enabled, + structuralSharing: query.structuralSharing ?? structuralSharing, + }) +} diff --git a/wagmi-project/packages/react/src/hooks/useReconnect.test-d.ts b/wagmi-project/packages/react/src/hooks/useReconnect.test-d.ts new file mode 100644 index 0000000000..424159e469 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useReconnect.test-d.ts @@ -0,0 +1,154 @@ +import type { + Connector, + CreateConnectorFn, + ReconnectErrorType, +} from '@wagmi/core' +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import type { Address } from 'viem' +import { useReconnect } from './useReconnect.js' + +const connectors = [config.connectors[0]!] +const contextValue = { foo: 'bar' } as const + +test('context', () => { + const { context, data, error, reconnect, variables } = useReconnect({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toEqualTypeOf< + | { + connectors?: + | readonly (CreateConnectorFn | Connector)[] + | undefined + } + | undefined + >() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf< + | { + connectors?: + | readonly (CreateConnectorFn | Connector)[] + | undefined + } + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf< + | { + connectors?: + | readonly (CreateConnectorFn | Connector)[] + | undefined + } + | undefined + >() + expectTypeOf(data).toEqualTypeOf< + { + accounts: readonly [Address, ...Address[]] + chainId: number + connector: Connector + }[] + >() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf< + | { + accounts: readonly [Address, ...Address[]] + chainId: number + connector: Connector + }[] + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf< + | { + connectors?: + | readonly (CreateConnectorFn | Connector)[] + | undefined + } + | undefined + >() + expectTypeOf(context).toEqualTypeOf() + }, + }, + }) + + expectTypeOf(data).toEqualTypeOf< + | { + accounts: readonly [Address, ...Address[]] + chainId: number + connector: Connector + }[] + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf< + | { + connectors?: readonly (CreateConnectorFn | Connector)[] | undefined + } + | undefined + >() + expectTypeOf(context).toEqualTypeOf() + + reconnect( + { connectors }, + { + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf< + | { + connectors?: + | readonly (CreateConnectorFn | Connector)[] + | undefined + } + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf< + | { + connectors?: + | readonly (CreateConnectorFn | Connector)[] + | undefined + } + | undefined + >() + expectTypeOf(data).toEqualTypeOf< + { + accounts: readonly [Address, ...Address[]] + chainId: number + connector: Connector + }[] + >() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf< + | { + accounts: readonly [Address, ...Address[]] + chainId: number + connector: Connector + }[] + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf< + | { + connectors?: + | readonly (CreateConnectorFn | Connector)[] + | undefined + } + | undefined + >() + expectTypeOf(context).toEqualTypeOf() + }, + }, + ) +}) diff --git a/wagmi-project/packages/react/src/hooks/useReconnect.test.ts b/wagmi-project/packages/react/src/hooks/useReconnect.test.ts new file mode 100644 index 0000000000..be783b2440 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useReconnect.test.ts @@ -0,0 +1,83 @@ +import { mock } from '@wagmi/connectors' +import { connect, disconnect } from '@wagmi/core' +import { accounts, config } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { afterEach, expect, test } from 'vitest' + +import { useReconnect } from './useReconnect.js' + +const connector = config._internal.connectors.setup( + mock({ + accounts, + features: { reconnect: true }, + }), +) + +afterEach(async () => { + if (config.state.current) await disconnect(config) +}) + +test('default', async () => { + const { result } = renderHook(() => useReconnect()) + + expect(result.current.connectors).toBeDefined() + + result.current.reconnect() + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current.data).toStrictEqual([]) +}) + +test('parameters: connectors (Connector)', async () => { + await connect(config, { connector }) + + const { result } = renderHook(() => useReconnect()) + + expect(result.current.connectors).toBeDefined() + + result.current.reconnect({ connectors: [connector] }) + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current.data).toMatchObject( + expect.arrayContaining([ + expect.objectContaining({ + accounts: expect.any(Array), + chainId: expect.any(Number), + }), + ]), + ) +}) + +test('parameters: connectors (CreateConnectorFn)', async () => { + const connector = mock({ + accounts, + features: { reconnect: true }, + }) + await connect(config, { connector }) + + const { result } = renderHook(() => useReconnect()) + + expect(result.current.connectors).toBeDefined() + + result.current.reconnect({ connectors: [connector] }) + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current.data).toMatchObject( + expect.arrayContaining([ + expect.objectContaining({ + accounts: expect.any(Array), + chainId: expect.any(Number), + }), + ]), + ) +}) + +test("behavior: doesn't reconnect if already reconnecting", async () => { + const previousStatus = config.state.status + config.setState((x) => ({ ...x, status: 'reconnecting' })) + const { result } = renderHook(() => useReconnect()) + await expect( + result.current.reconnectAsync({ connectors: [connector] }), + ).resolves.toStrictEqual([]) + config.setState((x) => ({ ...x, status: previousStatus })) +}) diff --git a/wagmi-project/packages/react/src/hooks/useReconnect.ts b/wagmi-project/packages/react/src/hooks/useReconnect.ts new file mode 100644 index 0000000000..23e6d365e4 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useReconnect.ts @@ -0,0 +1,67 @@ +'use client' + +import { useMutation } from '@tanstack/react-query' +import type { Connector, ReconnectErrorType } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type ReconnectData, + type ReconnectMutate, + type ReconnectMutateAsync, + type ReconnectVariables, + reconnectMutationOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' + +export type UseReconnectParameters = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + ReconnectData, + ReconnectErrorType, + ReconnectVariables, + context + > + | undefined + } +> + +export type UseReconnectReturnType = Compute< + UseMutationReturnType< + ReconnectData, + ReconnectErrorType, + ReconnectVariables, + context + > & { + connectors: readonly Connector[] + reconnect: ReconnectMutate + reconnectAsync: ReconnectMutateAsync + } +> + +/** https://wagmi.sh/react/api/hooks/useReconnect */ +export function useReconnect( + parameters: UseReconnectParameters = {}, +): UseReconnectReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = reconnectMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + return { + ...result, + connectors: config.connectors, + reconnect: mutate, + reconnectAsync: mutateAsync, + } +} diff --git a/wagmi-project/packages/react/src/hooks/useSendCalls.test.ts b/wagmi-project/packages/react/src/hooks/useSendCalls.test.ts new file mode 100644 index 0000000000..a088dcf221 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSendCalls.test.ts @@ -0,0 +1,44 @@ +import { connect, disconnect } from '@wagmi/core' +import { accounts, config } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { parseEther } from 'viem' +import { expect, test } from 'vitest' + +import { useSendCalls } from './useSendCalls.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const { result } = renderHook(() => useSendCalls()) + + result.current.sendCalls({ + calls: [ + { + data: '0xdeadbeef', + to: accounts[1], + value: parseEther('1'), + }, + { + to: accounts[2], + value: parseEther('2'), + }, + { + to: accounts[3], + value: parseEther('3'), + }, + ], + }) + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current.data).toMatchInlineSnapshot( + ` + { + "id": "0x5dedb5a4ff8968db37459b52b83cbdc92b01c9c709c9cff26e345ef5cf27f92e", + } + `, + ) + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useSendCalls.ts b/wagmi-project/packages/react/src/hooks/useSendCalls.ts new file mode 100644 index 0000000000..49366cb218 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSendCalls.ts @@ -0,0 +1,75 @@ +'use client' + +import { useMutation } from '@tanstack/react-query' +import type { Config, ResolvedRegister, SendCallsErrorType } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type SendCallsData, + type SendCallsMutate, + type SendCallsMutateAsync, + type SendCallsVariables, + sendCallsMutationOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' + +export type UseSendCallsParameters< + config extends Config = Config, + context = unknown, +> = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + SendCallsData, + SendCallsErrorType, + SendCallsVariables, + context + > + | undefined + } +> + +export type UseSendCallsReturnType< + config extends Config = Config, + context = unknown, +> = Compute< + UseMutationReturnType< + SendCallsData, + SendCallsErrorType, + SendCallsVariables, + context + > & { + sendCalls: SendCallsMutate + sendCallsAsync: SendCallsMutateAsync + } +> + +/** https://wagmi.sh/react/api/hooks/useSendCalls */ +export function useSendCalls< + config extends Config = ResolvedRegister['config'], + context = unknown, +>( + parameters: UseSendCallsParameters = {}, +): UseSendCallsReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = sendCallsMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + type Return = UseSendCallsReturnType + return { + ...result, + sendCalls: mutate as Return['sendCalls'], + sendCallsAsync: mutateAsync as Return['sendCallsAsync'], + } +} diff --git a/wagmi-project/packages/react/src/hooks/useSendTransaction.test-d.ts b/wagmi-project/packages/react/src/hooks/useSendTransaction.test-d.ts new file mode 100644 index 0000000000..170c1e61e3 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSendTransaction.test-d.ts @@ -0,0 +1,78 @@ +import type { SendTransactionErrorType } from '@wagmi/core' +import type { Hash } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { useSendTransaction } from './useSendTransaction.js' + +const contextValue = { foo: 'bar' } as const + +test('context', () => { + const { context, data, error, sendTransaction, variables } = + useSendTransaction({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toMatchTypeOf< + { chainId?: number | undefined } | undefined + >() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + }>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + }>() + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + }>() + expectTypeOf(context).toEqualTypeOf() + }, + }, + }) + + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toMatchTypeOf< + { chainId?: number | undefined } | undefined + >() + expectTypeOf(context).toEqualTypeOf() + + sendTransaction( + { to: '0x' }, + { + onError(error, variables, context) { + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + }>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + }>() + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + }>() + expectTypeOf(context).toEqualTypeOf() + }, + }, + ) +}) diff --git a/wagmi-project/packages/react/src/hooks/useSendTransaction.test.ts b/wagmi-project/packages/react/src/hooks/useSendTransaction.test.ts new file mode 100644 index 0000000000..a2e8977e2f --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSendTransaction.test.ts @@ -0,0 +1,25 @@ +import { connect, disconnect } from '@wagmi/core' +import { config, transactionHashRegex } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { parseEther } from 'viem' +import { expect, test } from 'vitest' + +import { useSendTransaction } from './useSendTransaction.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const { result } = renderHook(() => useSendTransaction()) + + result.current.sendTransaction({ + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }) + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current.data).toMatch(transactionHashRegex) + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useSendTransaction.ts b/wagmi-project/packages/react/src/hooks/useSendTransaction.ts new file mode 100644 index 0000000000..8f57b1509c --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSendTransaction.ts @@ -0,0 +1,79 @@ +'use client' + +import { useMutation } from '@tanstack/react-query' +import type { + Config, + ResolvedRegister, + SendTransactionErrorType, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type SendTransactionData, + type SendTransactionMutate, + type SendTransactionMutateAsync, + type SendTransactionVariables, + sendTransactionMutationOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' + +export type UseSendTransactionParameters< + config extends Config = Config, + context = unknown, +> = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + SendTransactionData, + SendTransactionErrorType, + SendTransactionVariables, + context + > + | undefined + } +> + +export type UseSendTransactionReturnType< + config extends Config = Config, + context = unknown, +> = Compute< + UseMutationReturnType< + SendTransactionData, + SendTransactionErrorType, + SendTransactionVariables, + context + > & { + sendTransaction: SendTransactionMutate + sendTransactionAsync: SendTransactionMutateAsync + } +> + +/** https://wagmi.sh/react/api/hooks/useSendTransaction */ +export function useSendTransaction< + config extends Config = ResolvedRegister['config'], + context = unknown, +>( + parameters: UseSendTransactionParameters = {}, +): UseSendTransactionReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = sendTransactionMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + type Return = UseSendTransactionReturnType + return { + ...result, + sendTransaction: mutate as Return['sendTransaction'], + sendTransactionAsync: mutateAsync as Return['sendTransactionAsync'], + } +} diff --git a/wagmi-project/packages/react/src/hooks/useShowCallsStatus.ts b/wagmi-project/packages/react/src/hooks/useShowCallsStatus.ts new file mode 100644 index 0000000000..82a4dd3909 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useShowCallsStatus.ts @@ -0,0 +1,76 @@ +'use client' + +import { useMutation } from '@tanstack/react-query' +import type { + Config, + ResolvedRegister, + ShowCallsStatusErrorType, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type ShowCallsStatusData, + type ShowCallsStatusMutate, + type ShowCallsStatusMutateAsync, + type ShowCallsStatusVariables, + showCallsStatusMutationOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' + +export type UseShowCallsStatusParameters< + config extends Config = Config, + context = unknown, +> = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + ShowCallsStatusData, + ShowCallsStatusErrorType, + ShowCallsStatusVariables, + context + > + | undefined + } +> + +export type UseShowCallsStatusReturnType = Compute< + UseMutationReturnType< + ShowCallsStatusData, + ShowCallsStatusErrorType, + ShowCallsStatusVariables, + context + > & { + showCallsStatus: ShowCallsStatusMutate + showCallsStatusAsync: ShowCallsStatusMutateAsync + } +> + +/** https://wagmi.sh/react/api/hooks/useShowCallsStatus */ +export function useShowCallsStatus< + config extends Config = ResolvedRegister['config'], + context = unknown, +>( + parameters: UseShowCallsStatusParameters = {}, +): UseShowCallsStatusReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = showCallsStatusMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + type Return = UseShowCallsStatusReturnType + return { + ...result, + showCallsStatus: mutate as Return['showCallsStatus'], + showCallsStatusAsync: mutateAsync as Return['showCallsStatusAsync'], + } +} diff --git a/wagmi-project/packages/react/src/hooks/useSignMessage.test-d.ts b/wagmi-project/packages/react/src/hooks/useSignMessage.test-d.ts new file mode 100644 index 0000000000..706c4a51fe --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSignMessage.test-d.ts @@ -0,0 +1,62 @@ +import type { SignMessageErrorType } from '@wagmi/core' +import type { SignMessageVariables } from '@wagmi/core/query' +import { expectTypeOf, test } from 'vitest' + +import { useSignMessage } from './useSignMessage.js' + +const message = 'hello world' +const contextValue = { foo: 'bar' } as const + +test('context', () => { + const { context, data, error, signMessage, variables } = useSignMessage({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toEqualTypeOf() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(data).toEqualTypeOf<`0x${string}`>() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf<`0x${string}` | undefined>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + }, + }) + + expectTypeOf(data).toEqualTypeOf<`0x${string}` | undefined>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + signMessage( + { message }, + { + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(data).toEqualTypeOf<`0x${string}`>() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf<`0x${string}` | undefined>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + }, + ) +}) diff --git a/wagmi-project/packages/react/src/hooks/useSignMessage.test.ts b/wagmi-project/packages/react/src/hooks/useSignMessage.test.ts new file mode 100644 index 0000000000..aa6dd4a184 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSignMessage.test.ts @@ -0,0 +1,43 @@ +import { connect, disconnect, getAccount } from '@wagmi/core' +import { config, privateKey } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { recoverMessageAddress } from 'viem' +import { expect, test } from 'vitest' + +import { privateKeyToAccount } from 'viem/accounts' +import { useSignMessage } from './useSignMessage.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const { result } = renderHook(() => useSignMessage()) + + result.current.signMessage({ message: 'foo bar baz' }) + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + await expect( + recoverMessageAddress({ + message: 'foo bar baz', + signature: result.current.data!, + }), + ).resolves.toEqual(getAccount(config).address) + + await disconnect(config, { connector }) +}) + +test('behavior: local account', async () => { + const { result } = renderHook(() => useSignMessage()) + + const account = privateKeyToAccount(privateKey) + result.current.signMessage({ account, message: 'foo bar baz' }) + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + await expect( + recoverMessageAddress({ + message: 'foo bar baz', + signature: result.current.data!, + }), + ).resolves.toEqual(account.address) +}) diff --git a/wagmi-project/packages/react/src/hooks/useSignMessage.ts b/wagmi-project/packages/react/src/hooks/useSignMessage.ts new file mode 100644 index 0000000000..0bea4bb65f --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSignMessage.ts @@ -0,0 +1,65 @@ +'use client' + +import { useMutation } from '@tanstack/react-query' +import type { SignMessageErrorType } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type SignMessageData, + type SignMessageMutate, + type SignMessageMutateAsync, + type SignMessageVariables, + signMessageMutationOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' + +export type UseSignMessageParameters = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + SignMessageData, + SignMessageErrorType, + SignMessageVariables, + context + > + | undefined + } +> + +export type UseSignMessageReturnType = Compute< + UseMutationReturnType< + SignMessageData, + SignMessageErrorType, + SignMessageVariables, + context + > & { + signMessage: SignMessageMutate + signMessageAsync: SignMessageMutateAsync + } +> + +/** https://wagmi.sh/react/api/hooks/useSignMessage */ +export function useSignMessage( + parameters: UseSignMessageParameters = {}, +): UseSignMessageReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = signMessageMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + return { + ...result, + signMessage: mutate, + signMessageAsync: mutateAsync, + } +} diff --git a/wagmi-project/packages/react/src/hooks/useSignTypedData.test-d.ts b/wagmi-project/packages/react/src/hooks/useSignTypedData.test-d.ts new file mode 100644 index 0000000000..a51f77cfbb --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSignTypedData.test-d.ts @@ -0,0 +1,93 @@ +import type { + SignTypedDataErrorType, + SignTypedDataReturnType, +} from '@wagmi/core' +import type { SignTypedDataVariables } from '@wagmi/core/query' +import { typedData } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { useSignTypedData } from './useSignTypedData.js' + +const contextValue = { foo: 'bar' } as const + +test('context', () => { + const { context, data, error, signTypedData, variables } = useSignTypedData({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toMatchTypeOf() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(variables).toMatchTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toMatchTypeOf() + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toMatchTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + }, + }) + + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toMatchTypeOf() + expectTypeOf(context).toEqualTypeOf() + + signTypedData( + { + types: typedData.basic.types, + primaryType: 'Person', + message: { + name: 'Bob', + wallet: '0x', + }, + }, + { + onError(error, variables, context) { + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toMatchTypeOf<{ + types: typeof typedData.basic.types + primaryType: 'Person' + message: { + name: string + wallet: `0x${string}` + } + }>() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(variables).toMatchTypeOf<{ + types: typeof typedData.basic.types + primaryType: 'Person' + message: { + name: string + wallet: `0x${string}` + } + }>() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toMatchTypeOf<{ + types: typeof typedData.basic.types + primaryType: 'Person' + message: { + name: string + wallet: `0x${string}` + } + }>() + expectTypeOf(context).toEqualTypeOf() + }, + }, + ) +}) diff --git a/wagmi-project/packages/react/src/hooks/useSignTypedData.test.ts b/wagmi-project/packages/react/src/hooks/useSignTypedData.test.ts new file mode 100644 index 0000000000..3a38daa0da --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSignTypedData.test.ts @@ -0,0 +1,56 @@ +import { connect, disconnect, getAccount } from '@wagmi/core' +import { config, privateKey, typedData } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { recoverTypedDataAddress } from 'viem' +import { expect, test } from 'vitest' + +import { privateKeyToAccount } from 'viem/accounts' +import { useSignTypedData } from './useSignTypedData.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const { result } = renderHook(() => useSignTypedData()) + + result.current.signTypedData({ + types: typedData.basic.types, + primaryType: 'Mail', + message: typedData.basic.message, + }) + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + await expect( + recoverTypedDataAddress({ + types: typedData.basic.types, + primaryType: 'Mail', + message: typedData.basic.message, + signature: result.current.data!, + }), + ).resolves.toEqual(getAccount(config).address) + + await disconnect(config, { connector }) +}) + +test('behavior: local account', async () => { + const { result } = renderHook(() => useSignTypedData()) + + const account = privateKeyToAccount(privateKey) + result.current.signTypedData({ + account, + types: typedData.basic.types, + primaryType: 'Mail', + message: typedData.basic.message, + }) + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + await expect( + recoverTypedDataAddress({ + types: typedData.basic.types, + primaryType: 'Mail', + message: typedData.basic.message, + signature: result.current.data!, + }), + ).resolves.toEqual(account.address) +}) diff --git a/wagmi-project/packages/react/src/hooks/useSignTypedData.ts b/wagmi-project/packages/react/src/hooks/useSignTypedData.ts new file mode 100644 index 0000000000..080cd04405 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSignTypedData.ts @@ -0,0 +1,66 @@ +'use client' + +import { useMutation } from '@tanstack/react-query' +import type { SignTypedDataErrorType } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type SignTypedDataData, + type SignTypedDataMutate, + type SignTypedDataMutateAsync, + type SignTypedDataVariables, + signTypedDataMutationOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' + +export type UseSignTypedDataParameters = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + SignTypedDataData, + SignTypedDataErrorType, + SignTypedDataVariables, + context + > + | undefined + } +> + +export type UseSignTypedDataReturnType = Compute< + UseMutationReturnType< + SignTypedDataData, + SignTypedDataErrorType, + SignTypedDataVariables, + context + > & { + signTypedData: SignTypedDataMutate + signTypedDataAsync: SignTypedDataMutateAsync + } +> + +/** https://wagmi.sh/react/api/hooks/useSignTypedData */ +export function useSignTypedData( + parameters: UseSignTypedDataParameters = {}, +): UseSignTypedDataReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = signTypedDataMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + type Return = UseSignTypedDataReturnType + return { + ...result, + signTypedData: mutate as Return['signTypedData'], + signTypedDataAsync: mutateAsync as Return['signTypedDataAsync'], + } +} diff --git a/wagmi-project/packages/react/src/hooks/useSimulateContract.test-d.ts b/wagmi-project/packages/react/src/hooks/useSimulateContract.test-d.ts new file mode 100644 index 0000000000..8159cdfccf --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSimulateContract.test-d.ts @@ -0,0 +1,104 @@ +import { abi, type config } from '@wagmi/test' +import type { Address } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { + type UseSimulateContractParameters, + type UseSimulateContractReturnType, + useSimulateContract, +} from './useSimulateContract.js' + +test('default', () => { + const result = useSimulateContract({ + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + }) + + expectTypeOf(result.data).toMatchTypeOf< + | { + result: boolean + request: { + chainId?: undefined + abi: readonly [ + { + readonly name: 'transferFrom' + readonly type: 'function' + readonly stateMutability: 'nonpayable' + readonly inputs: readonly [ + { readonly type: 'address'; readonly name: 'sender' }, + { readonly type: 'address'; readonly name: 'recipient' }, + { readonly type: 'uint256'; readonly name: 'amount' }, + ] + readonly outputs: readonly [{ type: 'bool' }] + }, + ] + functionName: 'transferFrom' + args: readonly [Address, Address, bigint] + } + } + | undefined + >() +}) + +test('select data', () => { + const result = useSimulateContract({ + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + chainId: 1, + query: { + select(data) { + expectTypeOf(data.result).toEqualTypeOf() + return data.request.args + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf< + readonly [Address, Address, bigint] | undefined + >() +}) + +test('UseSimulateContractParameters', () => { + type Result = UseSimulateContractParameters + expectTypeOf().toMatchTypeOf<{ + functionName?: 'approve' | 'transfer' | 'transferFrom' | undefined + args?: readonly [Address, Address, bigint] | undefined + }>() +}) + +test('UseSimulateContractReturnType', () => { + type Result = UseSimulateContractReturnType< + typeof abi.erc20, + 'transferFrom', + ['0x', '0x', 123n], + typeof config, + 1 + > + expectTypeOf().toMatchTypeOf< + | { + result: boolean + request: { + chainId: number + abi: readonly [ + { + readonly name: 'transferFrom' + readonly type: 'function' + readonly stateMutability: 'nonpayable' + readonly inputs: readonly [ + { readonly type: 'address'; readonly name: 'sender' }, + { readonly type: 'address'; readonly name: 'recipient' }, + { readonly type: 'uint256'; readonly name: 'amount' }, + ] + readonly outputs: readonly [{ type: 'bool' }] + }, + ] + functionName: 'approve' | 'transfer' | 'transferFrom' + args: readonly [Address, Address, bigint] + } + } + | undefined + >() +}) diff --git a/wagmi-project/packages/react/src/hooks/useSimulateContract.test.ts b/wagmi-project/packages/react/src/hooks/useSimulateContract.test.ts new file mode 100644 index 0000000000..3c785133c9 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSimulateContract.test.ts @@ -0,0 +1,95 @@ +import { connect, disconnect } from '@wagmi/core' +import { abi, address, config, wait } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useSimulateContract } from './useSimulateContract.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const { result } = renderHook(() => + useSimulateContract({ + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'mint', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "chainId": 1, + "request": { + "abi": [ + { + "inputs": [], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "account": { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "type": "json-rpc", + }, + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": undefined, + "chainId": 1, + "dataSuffix": undefined, + "functionName": "mint", + }, + "result": undefined, + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "simulateContract", + { + "account": { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "type": "json-rpc", + }, + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "chainId": 1, + "functionName": "mint", + }, + ], + "refetch": [Function], + "status": "success", + } + `) + + await disconnect(config, { connector }) +}) + +test('behavior: disabled when properties missing', async () => { + const { result } = renderHook(() => useSimulateContract()) + + await wait(100) + await waitFor(() => expect(result.current.isPending).toBeTruthy()) +}) diff --git a/wagmi-project/packages/react/src/hooks/useSimulateContract.ts b/wagmi-project/packages/react/src/hooks/useSimulateContract.ts new file mode 100644 index 0000000000..e17913fb4f --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSimulateContract.ts @@ -0,0 +1,117 @@ +'use client' + +import type { + Config, + ResolvedRegister, + SimulateContractErrorType, +} from '@wagmi/core' +import { + type SimulateContractData, + type SimulateContractOptions, + type SimulateContractQueryFnData, + type SimulateContractQueryKey, + simulateContractQueryOptions, +} from '@wagmi/core/query' +import type { Abi, ContractFunctionArgs, ContractFunctionName } from 'viem' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' +import { useConnectorClient } from './useConnectorClient.js' + +export type UseSimulateContractParameters< + abi extends Abi | readonly unknown[] = Abi, + functionName extends ContractFunctionName< + abi, + 'nonpayable' | 'payable' + > = ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + > = ContractFunctionArgs, + config extends Config = Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, + selectData = SimulateContractData, +> = SimulateContractOptions & + ConfigParameter & + QueryParameter< + SimulateContractQueryFnData, + SimulateContractErrorType, + selectData, + SimulateContractQueryKey + > + +export type UseSimulateContractReturnType< + abi extends Abi | readonly unknown[] = Abi, + functionName extends ContractFunctionName< + abi, + 'nonpayable' | 'payable' + > = ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + > = ContractFunctionArgs, + config extends Config = Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, + selectData = SimulateContractData, +> = UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useSimulateContract */ +export function useSimulateContract< + const abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + >, + config extends Config = ResolvedRegister['config'], + chainId extends config['chains'][number]['id'] | undefined = undefined, + selectData = SimulateContractData, +>( + parameters: UseSimulateContractParameters< + abi, + functionName, + args, + config, + chainId, + selectData + > = {} as any, +): UseSimulateContractReturnType< + abi, + functionName, + args, + config, + chainId, + selectData +> { + const { abi, address, connector, functionName, query = {} } = parameters + + const config = useConfig(parameters) + const { data: connectorClient } = useConnectorClient({ + config, + connector, + query: { enabled: parameters.account === undefined }, + }) + const chainId = useChainId({ config }) + + const options = simulateContractQueryOptions< + config, + abi, + functionName, + args, + chainId + >(config, { + ...parameters, + account: parameters.account ?? connectorClient?.account, + chainId: parameters.chainId ?? chainId, + }) + const enabled = Boolean( + abi && address && functionName && (query.enabled ?? true), + ) + + return useQuery({ ...query, ...options, enabled }) +} diff --git a/wagmi-project/packages/react/src/hooks/useStorageAt.test-d.ts b/wagmi-project/packages/react/src/hooks/useStorageAt.test-d.ts new file mode 100644 index 0000000000..bbc37fa03d --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useStorageAt.test-d.ts @@ -0,0 +1,15 @@ +import { expectTypeOf, test } from 'vitest' + +import type { Hex } from 'viem' +import { useStorageAt } from './useStorageAt.js' + +test('select data', () => { + const result = useStorageAt({ + query: { + select(data) { + return data + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useStorageAt.test.ts b/wagmi-project/packages/react/src/hooks/useStorageAt.test.ts new file mode 100644 index 0000000000..9386480c93 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useStorageAt.test.ts @@ -0,0 +1,299 @@ +import { address, chain, wait } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import type { Address } from 'viem' +import { useStorageAt } from './useStorageAt.js' + +test('default', async () => { + const { result } = renderHook(() => + useStorageAt({ + address: address.wagmiMintExample, + slot: '0x0', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": "0x7761676d6900000000000000000000000000000000000000000000000000000a", + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getStorageAt", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "chainId": 1, + "slot": "0x0", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: blockNumber', async () => { + const { result } = renderHook(() => + useStorageAt({ + address: address.wagmiMintExample, + blockNumber: 16280770n, + slot: '0x0', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": "0x7761676d6900000000000000000000000000000000000000000000000000000a", + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getStorageAt", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "blockNumber": 16280770n, + "chainId": 1, + "slot": "0x0", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: blockTag', async () => { + const { result } = renderHook(() => + useStorageAt({ + address: address.wagmiMintExample, + blockTag: 'safe', + slot: '0x0', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": "0x7761676d6900000000000000000000000000000000000000000000000000000a", + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getStorageAt", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "blockTag": "safe", + "chainId": 1, + "slot": "0x0", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: chainId', async () => { + const { result } = renderHook(() => + useStorageAt({ + address: address.wagmiMintExample, + chainId: chain.optimism.id, + slot: '0x0', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": "0x0000000000000000000000000000000000000000000000000000000000000000", + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getStorageAt", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "chainId": 10, + "slot": "0x0", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: address: undefined -> defined', async () => { + let contractAddress: Address | undefined = undefined + + const { result, rerender } = renderHook(() => + useStorageAt({ + address: contractAddress, + slot: '0x0', + }), + ) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": undefined, + "dataUpdatedAt": 0, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": false, + "isFetchedAfterMount": false, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": true, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": false, + "queryKey": [ + "getStorageAt", + { + "address": undefined, + "chainId": 1, + "slot": "0x0", + }, + ], + "refetch": [Function], + "status": "pending", + } + `) + + contractAddress = address.wagmiMintExample + rerender() + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + expect(result.current).toMatchInlineSnapshot(` + { + "data": "0x7761676d6900000000000000000000000000000000000000000000000000000a", + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getStorageAt", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "chainId": 1, + "slot": "0x0", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: disabled when properties missing', async () => { + const { result } = renderHook(() => useStorageAt()) + + await wait(100) + await waitFor(() => expect(result.current.isPending).toBeTruthy()) +}) diff --git a/wagmi-project/packages/react/src/hooks/useStorageAt.ts b/wagmi-project/packages/react/src/hooks/useStorageAt.ts new file mode 100644 index 0000000000..3a58376fd4 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useStorageAt.ts @@ -0,0 +1,57 @@ +'use client' + +import type { + Config, + GetStorageAtErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetStorageAtData, + type GetStorageAtOptions, + type GetStorageAtQueryKey, + getStorageAtQueryOptions, +} from '@wagmi/core/query' +import type { GetStorageAtQueryFnData } from '@wagmi/core/query' +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseStorageAtParameters< + config extends Config = Config, + selectData = GetStorageAtData, +> = Compute< + GetStorageAtOptions & + ConfigParameter & + QueryParameter< + GetStorageAtQueryFnData, + GetStorageAtErrorType, + selectData, + GetStorageAtQueryKey + > +> + +export type UseStorageAtReturnType = + UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useStorageAt */ +export function useStorageAt< + config extends Config = ResolvedRegister['config'], + selectData = GetStorageAtData, +>( + parameters: UseStorageAtParameters = {}, +): UseStorageAtReturnType { + const { address, slot, query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = getStorageAtQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + const enabled = Boolean(address && slot && (query.enabled ?? true)) + + return useQuery({ ...query, ...options, enabled }) +} diff --git a/wagmi-project/packages/react/src/hooks/useSwitchAccount.test-d.ts b/wagmi-project/packages/react/src/hooks/useSwitchAccount.test-d.ts new file mode 100644 index 0000000000..f7d97355a3 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSwitchAccount.test-d.ts @@ -0,0 +1,87 @@ +import type { Connector, SwitchAccountErrorType } from '@wagmi/core' +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import type { Address } from 'viem' +import { useSwitchAccount } from './useSwitchAccount.js' + +const connector = config.connectors[0]! +const contextValue = { foo: 'bar' } as const + +test('context', () => { + const { context, data, error, switchAccount, variables } = useSwitchAccount({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toEqualTypeOf<{ connector: Connector }>() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ connector: Connector }>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ connector: Connector }>() + expectTypeOf(data).toEqualTypeOf<{ + accounts: readonly [Address, ...Address[]] + chainId: number + }>() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf< + | { + accounts: readonly [Address, ...Address[]] + chainId: number + } + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf<{ connector: Connector }>() + expectTypeOf(context).toEqualTypeOf() + }, + }, + }) + + expectTypeOf(data).toEqualTypeOf< + | { + accounts: readonly [Address, ...Address[]] + chainId: number + } + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf<{ connector: Connector } | undefined>() + expectTypeOf(context).toEqualTypeOf() + + switchAccount( + { connector }, + { + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ connector: Connector }>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ connector: Connector }>() + expectTypeOf(data).toEqualTypeOf<{ + accounts: readonly [Address, ...Address[]] + chainId: number + }>() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf< + | { + accounts: readonly [Address, ...Address[]] + chainId: number + } + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf<{ connector: Connector }>() + expectTypeOf(context).toEqualTypeOf() + }, + }, + ) +}) diff --git a/wagmi-project/packages/react/src/hooks/useSwitchAccount.test.ts b/wagmi-project/packages/react/src/hooks/useSwitchAccount.test.ts new file mode 100644 index 0000000000..5461d08213 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSwitchAccount.test.ts @@ -0,0 +1,44 @@ +import { connect, disconnect } from '@wagmi/core' +import { config } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useAccount } from './useAccount.js' +import { useSwitchAccount } from './useSwitchAccount.js' + +const connector1 = config.connectors[0]! +const connector2 = config.connectors[1]! + +test('default', async () => { + await connect(config, { connector: connector2 }) + await connect(config, { connector: connector1 }) + + const { result } = renderHook(() => ({ + useAccount: useAccount(), + useSwitchAccount: useSwitchAccount(), + })) + + const address1 = result.current.useAccount.address + expect(address1).toBeDefined() + + result.current.useSwitchAccount.switchAccount({ connector: connector2 }) + await waitFor(() => + expect(result.current.useSwitchAccount.isSuccess).toBeTruthy(), + ) + + const address2 = result.current.useAccount.address + expect(address2).toBeDefined() + expect(address1).not.toBe(address2) + + result.current.useSwitchAccount.switchAccount({ connector: connector1 }) + await waitFor(() => + expect(result.current.useSwitchAccount.isSuccess).toBeTruthy(), + ) + + const address3 = result.current.useAccount.address + expect(address3).toBeDefined() + expect(address1).toBe(address3) + + await disconnect(config, { connector: connector1 }) + await disconnect(config, { connector: connector2 }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useSwitchAccount.ts b/wagmi-project/packages/react/src/hooks/useSwitchAccount.ts new file mode 100644 index 0000000000..e9dc305545 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSwitchAccount.ts @@ -0,0 +1,84 @@ +'use client' + +import { useMutation } from '@tanstack/react-query' +import type { + Config, + Connector, + ResolvedRegister, + SwitchAccountErrorType, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type SwitchAccountData, + type SwitchAccountMutate, + type SwitchAccountMutateAsync, + type SwitchAccountVariables, + switchAccountMutationOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' +import { useConnections } from './useConnections.js' + +export type UseSwitchAccountParameters< + config extends Config = Config, + context = unknown, +> = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + SwitchAccountData, + SwitchAccountErrorType, + SwitchAccountVariables, + context + > + | undefined + } +> + +export type UseSwitchAccountReturnType< + config extends Config = Config, + context = unknown, +> = Compute< + UseMutationReturnType< + SwitchAccountData, + SwitchAccountErrorType, + SwitchAccountVariables, + context + > & { + connectors: readonly Connector[] + switchAccount: SwitchAccountMutate + switchAccountAsync: SwitchAccountMutateAsync + } +> + +/** https://wagmi.sh/react/api/hooks/useSwitchAccount */ +export function useSwitchAccount< + config extends Config = ResolvedRegister['config'], + context = unknown, +>( + parameters: UseSwitchAccountParameters = {}, +): UseSwitchAccountReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = switchAccountMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + return { + ...result, + connectors: useConnections({ config }).map( + (connection) => connection.connector, + ), + switchAccount: mutate, + switchAccountAsync: mutateAsync, + } +} diff --git a/wagmi-project/packages/react/src/hooks/useSwitchChain.test-d.ts b/wagmi-project/packages/react/src/hooks/useSwitchChain.test-d.ts new file mode 100644 index 0000000000..07098c7724 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSwitchChain.test-d.ts @@ -0,0 +1,118 @@ +import type { Connector, SwitchChainErrorType } from '@wagmi/core' +import type { Chain } from '@wagmi/core/chains' +import type { Compute, ExactPartial } from '@wagmi/core/internal' +import { chain } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import type { AddEthereumChainParameter } from 'viem' +import { useSwitchChain } from './useSwitchChain.js' + +const chainId = chain.mainnet.id +const contextValue = { foo: 'bar' } as const + +test('context', () => { + const { chains, context, data, error, switchChain, variables } = + useSwitchChain({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toEqualTypeOf<{ + addEthereumChainParameter?: + | ExactPartial> + | undefined + chainId: number + connector?: Connector | undefined + }>() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ + addEthereumChainParameter?: + | ExactPartial> + | undefined + chainId: number + connector?: Connector | undefined + }>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ + addEthereumChainParameter?: + | ExactPartial> + | undefined + chainId: number + connector?: Connector | undefined + }>() + expectTypeOf(data).toEqualTypeOf>() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf | undefined>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf<{ + addEthereumChainParameter?: + | ExactPartial> + | undefined + chainId: number + connector?: Connector | undefined + }>() + expectTypeOf(context).toEqualTypeOf() + }, + }, + }) + + expectTypeOf(chains).toEqualTypeOf() + expectTypeOf(data).toEqualTypeOf | undefined>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf< + | { + addEthereumChainParameter?: + | ExactPartial> + | undefined + chainId: number + connector?: Connector | undefined + } + | undefined + >() + expectTypeOf(context).toEqualTypeOf() + + switchChain( + { chainId }, + { + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ + addEthereumChainParameter?: + | ExactPartial> + | undefined + chainId: number + connector?: Connector | undefined + }>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ + addEthereumChainParameter?: + | ExactPartial> + | undefined + chainId: number + connector?: Connector | undefined + }>() + expectTypeOf(data).toEqualTypeOf>() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf | undefined>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf<{ + addEthereumChainParameter?: + | ExactPartial> + | undefined + chainId: number + connector?: Connector | undefined + }>() + expectTypeOf(context).toEqualTypeOf() + }, + }, + ) +}) diff --git a/wagmi-project/packages/react/src/hooks/useSwitchChain.test.ts b/wagmi-project/packages/react/src/hooks/useSwitchChain.test.ts new file mode 100644 index 0000000000..1fe0ca46b2 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSwitchChain.test.ts @@ -0,0 +1,114 @@ +import { connect, disconnect } from '@wagmi/core' +import { chain, config } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useAccount } from './useAccount.js' +import { useSwitchChain } from './useSwitchChain.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const { result } = renderHook(() => ({ + useAccount: useAccount(), + useSwitchChain: useSwitchChain(), + })) + + const chainId1 = result.current.useAccount.chainId + expect(chainId1).toBeDefined() + + result.current.useSwitchChain.switchChain({ chainId: chain.mainnet2.id }) + await waitFor(() => + expect(result.current.useSwitchChain.isSuccess).toBeTruthy(), + ) + + const chainId2 = result.current.useAccount.chainId + expect(chainId2).toBeDefined() + expect(chainId1).not.toBe(chainId2) + + result.current.useSwitchChain.switchChain({ chainId: chain.mainnet.id }) + await waitFor(() => + expect(result.current.useSwitchChain.isSuccess).toBeTruthy(), + ) + + const chainId3 = result.current.useAccount.chainId + expect(chainId3).toBeDefined() + expect(chainId1).toBe(chainId3) + + await disconnect(config, { connector }) +}) + +test('behavior: chains updates', () => { + const { result, rerender } = renderHook(() => useSwitchChain()) + + const chains = result.current.chains + expect( + result.current.chains.map(({ id, name }) => ({ + id, + name, + })), + ).toMatchInlineSnapshot(` + [ + { + "id": 1, + "name": "Ethereum", + }, + { + "id": 456, + "name": "Ethereum", + }, + { + "id": 10, + "name": "OP Mainnet", + }, + ] + `) + + config._internal.chains.setState([chain.mainnet, chain.mainnet2]) + rerender() + + expect( + result.current.chains.map(({ id, name }) => ({ + id, + name, + })), + ).toMatchInlineSnapshot(` + [ + { + "id": 1, + "name": "Ethereum", + }, + { + "id": 456, + "name": "Ethereum", + }, + ] + `) + + config._internal.chains.setState(chains) + rerender() + + expect( + result.current.chains.map(({ id, name }) => ({ + id, + name, + })), + ).toMatchInlineSnapshot(` + [ + { + "id": 1, + "name": "Ethereum", + }, + { + "id": 456, + "name": "Ethereum", + }, + { + "id": 10, + "name": "OP Mainnet", + }, + ] + `) +}) diff --git a/wagmi-project/packages/react/src/hooks/useSwitchChain.ts b/wagmi-project/packages/react/src/hooks/useSwitchChain.ts new file mode 100644 index 0000000000..97ecf4ce9e --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSwitchChain.ts @@ -0,0 +1,82 @@ +'use client' + +import { useMutation } from '@tanstack/react-query' +import type { + Config, + ResolvedRegister, + SwitchChainErrorType, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type SwitchChainData, + type SwitchChainMutate, + type SwitchChainMutateAsync, + type SwitchChainVariables, + switchChainMutationOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useChains } from './useChains.js' +import { useConfig } from './useConfig.js' + +export type UseSwitchChainParameters< + config extends Config = Config, + context = unknown, +> = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + SwitchChainData, + SwitchChainErrorType, + SwitchChainVariables, + context + > + | undefined + } +> + +export type UseSwitchChainReturnType< + config extends Config = Config, + context = unknown, +> = Compute< + UseMutationReturnType< + SwitchChainData, + SwitchChainErrorType, + SwitchChainVariables, + context + > & { + chains: config['chains'] + switchChain: SwitchChainMutate + switchChainAsync: SwitchChainMutateAsync + } +> + +/** https://wagmi.sh/react/api/hooks/useSwitchChain */ +export function useSwitchChain< + config extends Config = ResolvedRegister['config'], + context = unknown, +>( + parameters: UseSwitchChainParameters = {}, +): UseSwitchChainReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = switchChainMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + type Return = UseSwitchChainReturnType + return { + ...result, + chains: useChains({ config }) as unknown as config['chains'], + switchChain: mutate as Return['switchChain'], + switchChainAsync: mutateAsync as Return['switchChainAsync'], + } +} diff --git a/wagmi-project/packages/react/src/hooks/useSyncExternalStoreWithTracked.test.tsx b/wagmi-project/packages/react/src/hooks/useSyncExternalStoreWithTracked.test.tsx new file mode 100644 index 0000000000..e0b1e71a94 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSyncExternalStoreWithTracked.test.tsx @@ -0,0 +1,275 @@ +import { fireEvent, screen } from '@testing-library/react' +import { act, cleanup, render, renderHook } from '@wagmi/test/react' +import React from 'react' +import * as ReactDOM from 'react-dom' +import { afterEach, expect, test } from 'vitest' + +import { useSyncExternalStoreWithTracked } from './useSyncExternalStoreWithTracked.js' + +function createExternalStore(initialState: state) { + const listeners = new Set<() => void>() + let currentState = initialState + return { + set(updater: (state: state) => state) { + currentState = updater(currentState) + ReactDOM.unstable_batchedUpdates(() => { + for (const listener of listeners) { + listener() + } + }) + }, + subscribe(listener: () => void) { + listeners.add(listener) + return () => listeners.delete(listener) + }, + getState() { + return currentState + }, + } +} + +function useExternalStore( + store: ReturnType, + cb: (state: any) => void, +) { + const state = useSyncExternalStoreWithTracked( + store.subscribe, + store.getState, + store.getState, + ) + cb(state) + return state as any +} + +afterEach(() => { + cleanup() +}) + +test('rerenders only when the tracked value changes', async () => { + const externalStore = createExternalStore({ + foo: 'bar', + gm: 'wagmi', + isGonnaMakeIt: false, + }) + + const renders: any[] = [] + + renderHook(() => { + const { gm } = useExternalStore(externalStore, (state) => { + renders.push(state) + }) + + return gm + }) + + act(() => { + externalStore.set((x) => ({ ...x, foo: 'baz', isGonnaMakeIt: true })) + }) + + expect(renders).toMatchInlineSnapshot(` + [ + { + "foo": "bar", + "gm": "wagmi", + "isGonnaMakeIt": false, + }, + ] + `) + + act(() => { + externalStore.set((x) => ({ ...x, gm: 'ngmi' })) + }) + + expect(renders).toMatchInlineSnapshot(` + [ + { + "foo": "bar", + "gm": "wagmi", + "isGonnaMakeIt": false, + }, + { + "foo": "baz", + "gm": "ngmi", + "isGonnaMakeIt": true, + }, + ] + `) +}) + +test('rerenders when all values are being tracked', async () => { + const externalStore = createExternalStore({ + foo: 'bar', + gm: 'wagmi', + isGonnaMakeIt: false, + }) + + const renders: any[] = [] + + renderHook(() => { + const { foo, gm, isGonnaMakeIt } = useExternalStore( + externalStore, + (state) => { + renders.push(state) + }, + ) + + return { + foo, + gm, + isGonnaMakeIt, + } + }) + + act(() => { + externalStore.set((x) => ({ ...x, isGonnaMakeIt: true })) + }) + + expect(renders).toMatchInlineSnapshot(` + [ + { + "foo": "bar", + "gm": "wagmi", + "isGonnaMakeIt": false, + }, + { + "foo": "bar", + "gm": "wagmi", + "isGonnaMakeIt": true, + }, + ] + `) +}) + +test('rerenders when no values are being tracked', async () => { + const externalStore = createExternalStore({ + foo: 'bar', + gm: 'wagmi', + isGonnaMakeIt: false, + }) + + const renders: any[] = [] + + renderHook(() => { + useExternalStore(externalStore, (state) => { + renders.push(state) + }) + }) + + act(() => { + externalStore.set((x) => ({ ...x, isGonnaMakeIt: true })) + }) + + expect(renders).toMatchInlineSnapshot(` + [ + { + "foo": "bar", + "gm": "wagmi", + "isGonnaMakeIt": false, + }, + { + "foo": "bar", + "gm": "wagmi", + "isGonnaMakeIt": true, + }, + ] + `) +}) + +test('store object reference is stable across rerenders', async () => { + const externalStore = createExternalStore({ + foo: 'bar', + gm: 'wagmi', + isGonnaMakeIt: false, + }) + + let childRenderCount = 0 + const MemoComponent = React.memo((props: { store: any }) => { + childRenderCount++ + return
{props.store.isGonnaMakeIt}
+ }) + + const renders: any[] = [] + + function Test() { + const store = useExternalStore(externalStore, (state) => { + renders.push(state) + }) + const [, rerender] = React.useState(0) + + return ( + <> + + + + ) + } + + render() + + const forceRerenderBtn = screen.getByRole('button') + expect(childRenderCount).toBe(1) + expect(renders.length).toBe(1) + + // updating parent state, child should not rerender + fireEvent.click(forceRerenderBtn) + expect(childRenderCount).toBe(1) + expect(renders.length).toBe(2) + + // child and parent both rerender when store changes + act(() => { + externalStore.set((x) => ({ ...x, isGonnaMakeIt: true })) + }) + expect(childRenderCount).toBe(2) + expect(renders.length).toBe(3) +}) + +test('array', async () => { + const externalStore = createExternalStore(['foo']) + + const renders: any[] = [] + + renderHook(() => { + const array = useExternalStore(externalStore, (state) => { + renders.push(state) + }) + + return array + }) + + act(() => { + externalStore.set((x) => [...x, 'bar']) + }) + + expect(renders).toMatchInlineSnapshot(` + [ + [ + "foo", + ], + [ + "foo", + "bar", + ], + ] + `) + + act(() => { + externalStore.set((x) => [...x, 'baz']) + }) + + expect(renders).toMatchInlineSnapshot(` + [ + [ + "foo", + ], + [ + "foo", + "bar", + ], + [ + "foo", + "bar", + "baz", + ], + ] + `) +}) diff --git a/wagmi-project/packages/react/src/hooks/useSyncExternalStoreWithTracked.ts b/wagmi-project/packages/react/src/hooks/useSyncExternalStoreWithTracked.ts new file mode 100644 index 0000000000..4e372a556d --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useSyncExternalStoreWithTracked.ts @@ -0,0 +1,67 @@ +'use client' + +import { deepEqual } from '@wagmi/core/internal' +import { useMemo, useRef } from 'react' +import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/shim/with-selector.js' + +const isPlainObject = (obj: unknown) => + typeof obj === 'object' && !Array.isArray(obj) + +export function useSyncExternalStoreWithTracked< + snapshot extends selection, + selection = snapshot, +>( + subscribe: (onStoreChange: () => void) => () => void, + getSnapshot: () => snapshot, + getServerSnapshot: undefined | null | (() => snapshot) = getSnapshot, + isEqual: (a: selection, b: selection) => boolean = deepEqual, +) { + const trackedKeys = useRef([]) + const result = useSyncExternalStoreWithSelector( + subscribe, + getSnapshot, + getServerSnapshot, + (x) => x, + (a, b) => { + if (isPlainObject(a) && isPlainObject(b) && trackedKeys.current.length) { + for (const key of trackedKeys.current) { + const equal = isEqual( + (a as { [_a: string]: any })[key], + (b as { [_b: string]: any })[key], + ) + if (!equal) return false + } + return true + } + return isEqual(a, b) + }, + ) + + return useMemo(() => { + if (isPlainObject(result)) { + const trackedResult = { ...result } + let properties = {} + for (const [key, value] of Object.entries( + trackedResult as { [key: string]: any }, + )) { + properties = { + ...properties, + [key]: { + configurable: false, + enumerable: true, + get: () => { + if (!trackedKeys.current.includes(key)) { + trackedKeys.current.push(key) + } + return value + }, + }, + } + } + Object.defineProperties(trackedResult, properties) + return trackedResult + } + + return result + }, [result]) +} diff --git a/wagmi-project/packages/react/src/hooks/useToken.test-d.ts b/wagmi-project/packages/react/src/hooks/useToken.test-d.ts new file mode 100644 index 0000000000..2018951919 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useToken.test-d.ts @@ -0,0 +1,14 @@ +import { expectTypeOf, test } from 'vitest' + +import { useToken } from './useToken.js' + +test('select data', () => { + const result = useToken({ + query: { + select(data) { + return data?.name + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useToken.test.ts b/wagmi-project/packages/react/src/hooks/useToken.test.ts new file mode 100644 index 0000000000..6023797532 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useToken.test.ts @@ -0,0 +1,59 @@ +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useToken } from './useToken.js' + +test('default', async () => { + const { result } = renderHook(() => + useToken({ + address: '0x1f9840a85d5af5bf1d1762f925bdaddc4201f984', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "address": "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984", + "decimals": 18, + "name": "Uniswap", + "symbol": "UNI", + "totalSupply": { + "formatted": "1000000000", + "value": 1000000000000000000000000000n, + }, + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "token", + { + "address": "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984", + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) diff --git a/wagmi-project/packages/react/src/hooks/useToken.ts b/wagmi-project/packages/react/src/hooks/useToken.ts new file mode 100644 index 0000000000..1d43912f72 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useToken.ts @@ -0,0 +1,60 @@ +'use client' + +import type { Config, GetTokenErrorType, ResolvedRegister } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetTokenData, + type GetTokenOptions, + type GetTokenQueryFnData, + type GetTokenQueryKey, + getTokenQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseTokenParameters< + config extends Config = Config, + selectData = GetTokenData, +> = Compute< + GetTokenOptions & + ConfigParameter & + QueryParameter< + GetTokenQueryFnData, + GetTokenErrorType, + selectData, + GetTokenQueryKey + > +> + +export type UseTokenReturnType = UseQueryReturnType< + selectData, + GetTokenErrorType +> + +/** + * @deprecated + * + * https://wagmi.sh/react/api/hooks/useToken + */ +export function useToken< + config extends Config = ResolvedRegister['config'], + selectData = GetTokenData, +>( + parameters: UseTokenParameters = {}, +): UseTokenReturnType { + const { address, query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = getTokenQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + const enabled = Boolean(address && (query.enabled ?? true)) + + return useQuery({ ...query, ...options, enabled }) +} diff --git a/wagmi-project/packages/react/src/hooks/useTransaction.test-d.ts b/wagmi-project/packages/react/src/hooks/useTransaction.test-d.ts new file mode 100644 index 0000000000..211efa7f6c --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useTransaction.test-d.ts @@ -0,0 +1,14 @@ +import { expectTypeOf, test } from 'vitest' + +import { useTransaction } from './useTransaction.js' + +test('select data', () => { + const result = useTransaction({ + query: { + select(data) { + return data?.nonce + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useTransaction.test.ts b/wagmi-project/packages/react/src/hooks/useTransaction.test.ts new file mode 100644 index 0000000000..190cffb1fe --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useTransaction.test.ts @@ -0,0 +1,72 @@ +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useTransaction } from './useTransaction.js' + +test('default', async () => { + const { result } = renderHook(() => + useTransaction({ + hash: '0x60668ed8c2dc110d61d945a936fcd45b8f13654e5c78481c8c825d1148c7ef30', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "accessList": [], + "blockHash": "0xd725a38b51e5ceec8c5f6c9ccfdb2cc423af993bb650af5eedca5e4be7156ba7", + "blockNumber": 15189204n, + "chainId": 1, + "from": "0xa0cf798816d4b9b9866b5330eea46a18382f251e", + "gas": 21000n, + "gasPrice": 9371645552n, + "hash": "0x60668ed8c2dc110d61d945a936fcd45b8f13654e5c78481c8c825d1148c7ef30", + "input": "0x", + "maxFeePerGas": 13644824566n, + "maxPriorityFeePerGas": 1500000000n, + "nonce": 86, + "r": "0x40174f9a38df876c1a7ce2587848819d4082ccd6d67a88aa5cabe59bf594e14f", + "s": "0x7c0c82f62a8a5a9b0e9cf30a54a72fdae8fc54b5b79ddafef0acd30e94e83872", + "to": "0xd2135cfb216b74109775236e36d4b433f1df507b", + "transactionIndex": 144, + "type": "eip1559", + "typeHex": "0x2", + "v": 0n, + "value": 100000000000000000n, + "yParity": 0, + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "transaction", + { + "chainId": 1, + "hash": "0x60668ed8c2dc110d61d945a936fcd45b8f13654e5c78481c8c825d1148c7ef30", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) diff --git a/wagmi-project/packages/react/src/hooks/useTransaction.ts b/wagmi-project/packages/react/src/hooks/useTransaction.ts new file mode 100644 index 0000000000..6cc920e873 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useTransaction.ts @@ -0,0 +1,72 @@ +'use client' + +import type { + Config, + GetTransactionErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetTransactionData, + type GetTransactionOptions, + type GetTransactionQueryFnData, + type GetTransactionQueryKey, + getTransactionQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseTransactionParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetTransactionData, +> = Compute< + GetTransactionOptions & + ConfigParameter & + QueryParameter< + GetTransactionQueryFnData, + GetTransactionErrorType, + selectData, + GetTransactionQueryKey + > +> + +export type UseTransactionReturnType< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetTransactionData, +> = UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useTransaction */ +export function useTransaction< + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetTransactionData, +>( + parameters: UseTransactionParameters = {}, +): UseTransactionReturnType { + const { blockHash, blockNumber, blockTag, hash, query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = getTransactionQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + const enabled = Boolean( + !(blockHash && blockNumber && blockTag && hash) && (query.enabled ?? true), + ) + + return useQuery({ + ...(query as any), + ...options, + enabled, + }) as UseTransactionReturnType +} diff --git a/wagmi-project/packages/react/src/hooks/useTransactionConfirmations.test-d.ts b/wagmi-project/packages/react/src/hooks/useTransactionConfirmations.test-d.ts new file mode 100644 index 0000000000..e2bbcb4266 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useTransactionConfirmations.test-d.ts @@ -0,0 +1,14 @@ +import { expectTypeOf, test } from 'vitest' + +import { useTransactionConfirmations } from './useTransactionConfirmations.js' + +test('select data', () => { + const result = useTransactionConfirmations({ + query: { + select(data) { + return data + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useTransactionConfirmations.test.ts b/wagmi-project/packages/react/src/hooks/useTransactionConfirmations.test.ts new file mode 100644 index 0000000000..4f4a79c251 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useTransactionConfirmations.test.ts @@ -0,0 +1,215 @@ +import { config, wait } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import type { Hash } from 'viem' +import { expect, test } from 'vitest' + +import { getTransactionReceipt } from '@wagmi/core' +import { useTransactionConfirmations } from './useTransactionConfirmations.js' + +test('default', async () => { + const { result } = renderHook(() => + useTransactionConfirmations({ + hash: '0x60668ed8c2dc110d61d945a936fcd45b8f13654e5c78481c8c825d1148c7ef30', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toBeTypeOf('bigint') + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "transactionConfirmations", + { + "chainId": 1, + "hash": "0x60668ed8c2dc110d61d945a936fcd45b8f13654e5c78481c8c825d1148c7ef30", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: transactionReceipt', async () => { + const transactionReceipt = await getTransactionReceipt(config, { + hash: '0x60668ed8c2dc110d61d945a936fcd45b8f13654e5c78481c8c825d1148c7ef30', + }) + + const { result } = renderHook(() => + useTransactionConfirmations({ + transactionReceipt, + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toBeTypeOf('bigint') + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "transactionConfirmations", + { + "chainId": 1, + "transactionReceipt": { + "blockHash": "0xd725a38b51e5ceec8c5f6c9ccfdb2cc423af993bb650af5eedca5e4be7156ba7", + "blockNumber": 15189204n, + "contractAddress": null, + "cumulativeGasUsed": 12949744n, + "effectiveGasPrice": 9371645552n, + "from": "0xa0cf798816d4b9b9866b5330eea46a18382f251e", + "gasUsed": 21000n, + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "status": "success", + "to": "0xd2135cfb216b74109775236e36d4b433f1df507b", + "transactionHash": "0x60668ed8c2dc110d61d945a936fcd45b8f13654e5c78481c8c825d1148c7ef30", + "transactionIndex": 144, + "type": "eip1559", + }, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: hash: undefined -> defined', async () => { + let hash: Hash | undefined = undefined + + const { result, rerender } = renderHook(() => + useTransactionConfirmations({ + hash, + }), + ) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": undefined, + "dataUpdatedAt": 0, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": false, + "isFetchedAfterMount": false, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": true, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": false, + "queryKey": [ + "transactionConfirmations", + { + "chainId": 1, + "hash": undefined, + }, + ], + "refetch": [Function], + "status": "pending", + } + `) + + hash = '0x60668ed8c2dc110d61d945a936fcd45b8f13654e5c78481c8c825d1148c7ef30' + rerender() + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toBeTypeOf('bigint') + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "transactionConfirmations", + { + "chainId": 1, + "hash": "0x60668ed8c2dc110d61d945a936fcd45b8f13654e5c78481c8c825d1148c7ef30", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: disabled when properties missing', async () => { + const { result } = renderHook(() => useTransactionConfirmations()) + + await wait(100) + await waitFor(() => expect(result.current.isPending).toBeTruthy()) +}) diff --git a/wagmi-project/packages/react/src/hooks/useTransactionConfirmations.ts b/wagmi-project/packages/react/src/hooks/useTransactionConfirmations.ts new file mode 100644 index 0000000000..c8e9ddec3f --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useTransactionConfirmations.ts @@ -0,0 +1,66 @@ +'use client' + +import type { + Config, + GetTransactionConfirmationsErrorType, + ResolvedRegister, +} from '@wagmi/core' +import { + type GetTransactionConfirmationsData, + type GetTransactionConfirmationsOptions, + type GetTransactionConfirmationsQueryFnData, + type GetTransactionConfirmationsQueryKey, + getTransactionConfirmationsQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseTransactionConfirmationsParameters< + config extends Config = Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, + selectData = GetTransactionConfirmationsData, +> = GetTransactionConfirmationsOptions & + ConfigParameter & + QueryParameter< + GetTransactionConfirmationsQueryFnData, + GetTransactionConfirmationsErrorType, + selectData, + GetTransactionConfirmationsQueryKey + > + +export type UseTransactionConfirmationsReturnType< + selectData = GetTransactionConfirmationsData, +> = UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useTransactionConfirmations */ +export function useTransactionConfirmations< + config extends Config = ResolvedRegister['config'], + chainId extends config['chains'][number]['id'] | undefined = undefined, + selectData = GetTransactionConfirmationsData, +>( + parameters: UseTransactionConfirmationsParameters< + config, + chainId, + selectData + > = {} as any, +): UseTransactionConfirmationsReturnType { + const { hash, transactionReceipt, query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = getTransactionConfirmationsQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + const enabled = Boolean( + !(hash && transactionReceipt) && + (hash || transactionReceipt) && + (query.enabled ?? true), + ) + + return useQuery({ ...query, ...options, enabled }) +} diff --git a/wagmi-project/packages/react/src/hooks/useTransactionCount.test-d.ts b/wagmi-project/packages/react/src/hooks/useTransactionCount.test-d.ts new file mode 100644 index 0000000000..069d10b9cd --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useTransactionCount.test-d.ts @@ -0,0 +1,14 @@ +import { expectTypeOf, test } from 'vitest' + +import { useTransactionCount } from './useTransactionCount.js' + +test('select data', () => { + const result = useTransactionCount({ + query: { + select(data) { + return data + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useTransactionCount.test.ts b/wagmi-project/packages/react/src/hooks/useTransactionCount.test.ts new file mode 100644 index 0000000000..13a241ea88 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useTransactionCount.test.ts @@ -0,0 +1,238 @@ +import { accounts, chain, wait } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import type { Address } from 'viem' +import { expect, test } from 'vitest' + +import { useTransactionCount } from './useTransactionCount.js' + +const address = accounts[0] + +test('default', async () => { + const { result } = renderHook(() => useTransactionCount({ address })) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toBeTypeOf('number') + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "transactionCount", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: chainId', async () => { + const { result } = renderHook(() => + useTransactionCount({ address, chainId: chain.mainnet2.id }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toBeTypeOf('number') + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "transactionCount", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 456, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: blockNumber', async () => { + const { result } = renderHook(() => + useTransactionCount({ address, blockNumber: 13677382n }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toBeTypeOf('number') + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "transactionCount", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "blockNumber": 13677382n, + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: address: undefined -> defined', async () => { + let address: Address | undefined = undefined + + const { result, rerender } = renderHook(() => + useTransactionCount({ address }), + ) + + { + const { data, ...rest } = result.current + expect(data).toBeTypeOf('undefined') + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 0, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": false, + "isFetchedAfterMount": false, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": true, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": false, + "queryKey": [ + "transactionCount", + { + "address": undefined, + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "pending", + } + `) + } + + address = accounts[0] + rerender() + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, ...rest } = result.current + expect(data).toBeTypeOf('number') + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "transactionCount", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: disabled when properties missing', async () => { + const { result } = renderHook(() => useTransactionCount()) + + await wait(100) + await waitFor(() => expect(result.current.isPending).toBeTruthy()) +}) diff --git a/wagmi-project/packages/react/src/hooks/useTransactionCount.ts b/wagmi-project/packages/react/src/hooks/useTransactionCount.ts new file mode 100644 index 0000000000..341536aea7 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useTransactionCount.ts @@ -0,0 +1,59 @@ +'use client' + +import type { + Config, + GetTransactionCountErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import type { GetTransactionCountQueryFnData } from '@wagmi/core/query' +import { + type GetTransactionCountData, + type GetTransactionCountOptions, + type GetTransactionCountQueryKey, + getTransactionCountQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseTransactionCountParameters< + config extends Config = Config, + selectData = GetTransactionCountData, +> = Compute< + GetTransactionCountOptions & + ConfigParameter & + QueryParameter< + GetTransactionCountQueryFnData, + GetTransactionCountErrorType, + selectData, + GetTransactionCountQueryKey + > +> + +export type UseTransactionCountReturnType< + selectData = GetTransactionCountData, +> = UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useTransactionCount */ +export function useTransactionCount< + config extends Config = ResolvedRegister['config'], + selectData = GetTransactionCountData, +>( + parameters: UseTransactionCountParameters = {}, +): UseTransactionCountReturnType { + const { address, query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = getTransactionCountQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + const enabled = Boolean(address && (query.enabled ?? true)) + + return useQuery({ ...query, ...options, enabled }) +} diff --git a/wagmi-project/packages/react/src/hooks/useTransactionReceipt.test-d.ts b/wagmi-project/packages/react/src/hooks/useTransactionReceipt.test-d.ts new file mode 100644 index 0000000000..af2785934a --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useTransactionReceipt.test-d.ts @@ -0,0 +1,14 @@ +import { expectTypeOf, test } from 'vitest' + +import { useTransactionReceipt } from './useTransactionReceipt.js' + +test('select data', () => { + const result = useTransactionReceipt({ + query: { + select(data) { + return data?.blockNumber + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useTransactionReceipt.test.ts b/wagmi-project/packages/react/src/hooks/useTransactionReceipt.test.ts new file mode 100644 index 0000000000..fd2e24d76b --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useTransactionReceipt.test.ts @@ -0,0 +1,237 @@ +import { chain, wait } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import type { Hash } from 'viem' +import { expect, test } from 'vitest' +import { useTransactionReceipt } from './useTransactionReceipt.js' + +test('default', async () => { + const { result } = renderHook(() => + useTransactionReceipt({ + hash: '0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "blockHash": "0xb932f77cf770d1d1c8f861153eec1e990f5d56b6ffdb4ac06aef3cca51ef37d4", + "blockNumber": 16280769n, + "contractAddress": null, + "cumulativeGasUsed": 21000n, + "effectiveGasPrice": 33427926161n, + "from": "0x043022ef9fca1066024d19d681e2ccf44ff90de3", + "gasUsed": 21000n, + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "status": "success", + "to": "0x318a5fb4f1604fc46375a1db9a9018b6e423b345", + "transactionHash": "0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871", + "transactionIndex": 0, + "type": "legacy", + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getTransactionReceipt", + { + "chainId": 1, + "hash": "0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: chainId', async () => { + const { result } = renderHook(() => + useTransactionReceipt({ + chainId: chain.mainnet2.id, + hash: '0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "blockHash": "0xb932f77cf770d1d1c8f861153eec1e990f5d56b6ffdb4ac06aef3cca51ef37d4", + "blockNumber": 16280769n, + "contractAddress": null, + "cumulativeGasUsed": 21000n, + "effectiveGasPrice": 33427926161n, + "from": "0x043022ef9fca1066024d19d681e2ccf44ff90de3", + "gasUsed": 21000n, + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "status": "success", + "to": "0x318a5fb4f1604fc46375a1db9a9018b6e423b345", + "transactionHash": "0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871", + "transactionIndex": 0, + "type": "legacy", + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getTransactionReceipt", + { + "chainId": 456, + "hash": "0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: hash: undefined -> defined', async () => { + let hash: Hash | undefined = undefined + + const { result, rerender } = renderHook(() => + useTransactionReceipt({ + hash, + }), + ) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": undefined, + "dataUpdatedAt": 0, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": false, + "isFetchedAfterMount": false, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": true, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": false, + "queryKey": [ + "getTransactionReceipt", + { + "chainId": 1, + "hash": undefined, + }, + ], + "refetch": [Function], + "status": "pending", + } + `) + + hash = '0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871' + rerender() + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": { + "blockHash": "0xb932f77cf770d1d1c8f861153eec1e990f5d56b6ffdb4ac06aef3cca51ef37d4", + "blockNumber": 16280769n, + "contractAddress": null, + "cumulativeGasUsed": 21000n, + "effectiveGasPrice": 33427926161n, + "from": "0x043022ef9fca1066024d19d681e2ccf44ff90de3", + "gasUsed": 21000n, + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "status": "success", + "to": "0x318a5fb4f1604fc46375a1db9a9018b6e423b345", + "transactionHash": "0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871", + "transactionIndex": 0, + "type": "legacy", + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getTransactionReceipt", + { + "chainId": 1, + "hash": "0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: disabled when properties missing', async () => { + const { result } = renderHook(() => useTransactionReceipt()) + + await wait(100) + await waitFor(() => expect(result.current.isPending).toBeTruthy()) +}) diff --git a/wagmi-project/packages/react/src/hooks/useTransactionReceipt.ts b/wagmi-project/packages/react/src/hooks/useTransactionReceipt.ts new file mode 100644 index 0000000000..f29ab6204e --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useTransactionReceipt.ts @@ -0,0 +1,69 @@ +'use client' + +import type { + Config, + GetTransactionReceiptErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetTransactionReceiptData, + type GetTransactionReceiptOptions, + type GetTransactionReceiptQueryKey, + getTransactionReceiptQueryOptions, +} from '@wagmi/core/query' +import type { GetTransactionReceiptQueryFnData } from '@wagmi/core/query' +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseTransactionReceiptParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetTransactionReceiptData, +> = Compute< + GetTransactionReceiptOptions & + ConfigParameter & + QueryParameter< + GetTransactionReceiptQueryFnData, + GetTransactionReceiptErrorType, + selectData, + GetTransactionReceiptQueryKey + > +> + +export type UseTransactionReceiptReturnType< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetTransactionReceiptData, +> = UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useTransactionReceipt */ +export function useTransactionReceipt< + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetTransactionReceiptData, +>( + parameters: UseTransactionReceiptParameters = {}, +): UseTransactionReceiptReturnType { + const { hash, query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = getTransactionReceiptQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + const enabled = Boolean(hash && (query.enabled ?? true)) + + return useQuery({ + ...(query as any), + ...options, + enabled, + }) as UseTransactionReceiptReturnType +} diff --git a/wagmi-project/packages/react/src/hooks/useVerifyMessage.test-d.ts b/wagmi-project/packages/react/src/hooks/useVerifyMessage.test-d.ts new file mode 100644 index 0000000000..5a9ad7e257 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useVerifyMessage.test-d.ts @@ -0,0 +1,14 @@ +import { expectTypeOf, test } from 'vitest' + +import { useVerifyMessage } from './useVerifyMessage.js' + +test('select data', () => { + const result = useVerifyMessage({ + query: { + select(data) { + return data + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useVerifyMessage.test.ts b/wagmi-project/packages/react/src/hooks/useVerifyMessage.test.ts new file mode 100644 index 0000000000..244b6331f7 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useVerifyMessage.test.ts @@ -0,0 +1,318 @@ +import { accounts, chain, wait } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import type { Hex } from 'viem' +import { useVerifyMessage } from './useVerifyMessage.js' + +const address = accounts[0] + +test('default', async () => { + const { result } = renderHook(() => + useVerifyMessage({ + address, + message: 'This is a test message for viem!', + signature: + '0xc4c7f2820177020d66d5fd00d084cdd3f575a868c059c29a2d7f23398d04819709a14f83d98b446dda539ca5dcb87d75aa3340eb15e66d67606850622a3420f61b', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": true, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "verifyMessage", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 1, + "message": "This is a test message for viem!", + "signature": "0xc4c7f2820177020d66d5fd00d084cdd3f575a868c059c29a2d7f23398d04819709a14f83d98b446dda539ca5dcb87d75aa3340eb15e66d67606850622a3420f61b", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: chainId', async () => { + const { result } = renderHook(() => + useVerifyMessage({ + chainId: chain.mainnet2.id, + address, + message: 'This is a test message for viem!', + signature: + '0xc4c7f2820177020d66d5fd00d084cdd3f575a868c059c29a2d7f23398d04819709a14f83d98b446dda539ca5dcb87d75aa3340eb15e66d67606850622a3420f61b', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": true, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "verifyMessage", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 456, + "message": "This is a test message for viem!", + "signature": "0xc4c7f2820177020d66d5fd00d084cdd3f575a868c059c29a2d7f23398d04819709a14f83d98b446dda539ca5dcb87d75aa3340eb15e66d67606850622a3420f61b", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: blockNumber', async () => { + const { result } = renderHook(() => + useVerifyMessage({ + blockNumber: 12345678n, + address, + message: 'This is a test message for viem!', + signature: + '0xc4c7f2820177020d66d5fd00d084cdd3f575a868c059c29a2d7f23398d04819709a14f83d98b446dda539ca5dcb87d75aa3340eb15e66d67606850622a3420f61b', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": true, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "verifyMessage", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "blockNumber": 12345678n, + "chainId": 1, + "message": "This is a test message for viem!", + "signature": "0xc4c7f2820177020d66d5fd00d084cdd3f575a868c059c29a2d7f23398d04819709a14f83d98b446dda539ca5dcb87d75aa3340eb15e66d67606850622a3420f61b", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('parameters: blockTag', async () => { + const { result } = renderHook(() => + useVerifyMessage({ + blockTag: 'pending', + address, + message: 'This is a test message for viem!', + signature: + '0xc4c7f2820177020d66d5fd00d084cdd3f575a868c059c29a2d7f23398d04819709a14f83d98b446dda539ca5dcb87d75aa3340eb15e66d67606850622a3420f61b', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": true, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "verifyMessage", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "blockTag": "pending", + "chainId": 1, + "message": "This is a test message for viem!", + "signature": "0xc4c7f2820177020d66d5fd00d084cdd3f575a868c059c29a2d7f23398d04819709a14f83d98b446dda539ca5dcb87d75aa3340eb15e66d67606850622a3420f61b", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: signature: undefined -> defined', async () => { + let signature: Hex | undefined = undefined + + const { result, rerender } = renderHook(() => + useVerifyMessage({ + address, + message: 'This is a test message for viem!', + signature, + }), + ) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": undefined, + "dataUpdatedAt": 0, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": false, + "isFetchedAfterMount": false, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": true, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": false, + "queryKey": [ + "verifyMessage", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 1, + "message": "This is a test message for viem!", + "signature": undefined, + }, + ], + "refetch": [Function], + "status": "pending", + } + `) + + signature = + '0xc4c7f2820177020d66d5fd00d084cdd3f575a868c059c29a2d7f23398d04819709a14f83d98b446dda539ca5dcb87d75aa3340eb15e66d67606850622a3420f61b' + rerender() + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": true, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "verifyMessage", + { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 1, + "message": "This is a test message for viem!", + "signature": "0xc4c7f2820177020d66d5fd00d084cdd3f575a868c059c29a2d7f23398d04819709a14f83d98b446dda539ca5dcb87d75aa3340eb15e66d67606850622a3420f61b", + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: disabled when properties missing', async () => { + const { result } = renderHook(() => useVerifyMessage()) + + await wait(100) + await waitFor(() => expect(result.current.isPending).toBeTruthy()) +}) diff --git a/wagmi-project/packages/react/src/hooks/useVerifyMessage.ts b/wagmi-project/packages/react/src/hooks/useVerifyMessage.ts new file mode 100644 index 0000000000..ae8bb6df21 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useVerifyMessage.ts @@ -0,0 +1,59 @@ +'use client' + +import type { + Config, + ResolvedRegister, + VerifyMessageErrorType, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type VerifyMessageData, + type VerifyMessageOptions, + type VerifyMessageQueryKey, + verifyMessageQueryOptions, +} from '@wagmi/core/query' +import type { VerifyMessageQueryFnData } from '@wagmi/core/query' +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseVerifyMessageParameters< + config extends Config = Config, + selectData = VerifyMessageData, +> = Compute< + VerifyMessageOptions & + ConfigParameter & + QueryParameter< + VerifyMessageQueryFnData, + VerifyMessageErrorType, + selectData, + VerifyMessageQueryKey + > +> + +export type UseVerifyMessageReturnType = + UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useVerifyMessage */ +export function useVerifyMessage< + config extends Config = ResolvedRegister['config'], + selectData = VerifyMessageData, +>( + parameters: UseVerifyMessageParameters = {}, +): UseVerifyMessageReturnType { + const { address, message, signature, query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = verifyMessageQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + const enabled = Boolean( + address && message && signature && (query.enabled ?? true), + ) + + return useQuery({ ...query, ...options, enabled }) +} diff --git a/wagmi-project/packages/react/src/hooks/useVerifyTypedData.test-d.ts b/wagmi-project/packages/react/src/hooks/useVerifyTypedData.test-d.ts new file mode 100644 index 0000000000..91f875e0b6 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useVerifyTypedData.test-d.ts @@ -0,0 +1,40 @@ +import type { typedData } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import type { Address } from 'viem' +import { + type UseVerifyTypedDataParameters, + useVerifyTypedData, +} from './useVerifyTypedData.js' + +test('select data', () => { + const result = useVerifyTypedData({ + query: { + select(data) { + return data + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) + +test('UseReadContractParameters', () => { + type Result = UseVerifyTypedDataParameters< + typeof typedData.basic.types, + 'Mail' + > + expectTypeOf>().toEqualTypeOf<{ + primaryType?: 'Mail' | 'Person' + message?: { + from: { + name: string + wallet: Address + } + to: { + name: string + wallet: Address + } + contents: string + } + }>() +}) diff --git a/wagmi-project/packages/react/src/hooks/useVerifyTypedData.test.ts b/wagmi-project/packages/react/src/hooks/useVerifyTypedData.test.ts new file mode 100644 index 0000000000..d57331743f --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useVerifyTypedData.test.ts @@ -0,0 +1,481 @@ +import { typedData, wait } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import type { Hex } from 'viem' +import { expect, test } from 'vitest' + +import { useVerifyTypedData } from './useVerifyTypedData.js' + +const smartAccountAddress = '0x3FCf42e10CC70Fe75A62EB3aDD6D305Aa840d145' +const notDeployedAddress = '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef' + +test('valid signature', async () => { + const { result } = renderHook(() => + useVerifyTypedData({ + ...typedData.basic, + primaryType: 'Mail', + address: smartAccountAddress, + signature: + '0x79d756d805073dc97b7bc885b0d56ddf319a2599530fe1e178c2a7de5be88980068d24f20a79b318ea0a84d33ae06f93db77e4235e5d9eeb8b1d7a63922ada3e1c', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": true, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "verifyTypedData", + { + "address": "0x3FCf42e10CC70Fe75A62EB3aDD6D305Aa840d145", + "chainId": 1, + "domain": { + "chainId": 1, + "name": "Ether Mail", + "verifyingContract": "0x0000000000000000000000000000000000000000", + "version": "1", + }, + "message": { + "contents": "Hello, Bob!", + "from": { + "name": "Cow", + "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826", + }, + "to": { + "name": "Bob", + "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB", + }, + }, + "primaryType": "Mail", + "signature": "0x79d756d805073dc97b7bc885b0d56ddf319a2599530fe1e178c2a7de5be88980068d24f20a79b318ea0a84d33ae06f93db77e4235e5d9eeb8b1d7a63922ada3e1c", + "types": { + "Mail": [ + { + "name": "from", + "type": "Person", + }, + { + "name": "to", + "type": "Person", + }, + { + "name": "contents", + "type": "string", + }, + ], + "Person": [ + { + "name": "name", + "type": "string", + }, + { + "name": "wallet", + "type": "address", + }, + ], + }, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('invalid signature', async () => { + const { result } = renderHook(() => + useVerifyTypedData({ + ...typedData.basic, + primaryType: 'Mail', + address: smartAccountAddress, + signature: '0xdead', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": false, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "verifyTypedData", + { + "address": "0x3FCf42e10CC70Fe75A62EB3aDD6D305Aa840d145", + "chainId": 1, + "domain": { + "chainId": 1, + "name": "Ether Mail", + "verifyingContract": "0x0000000000000000000000000000000000000000", + "version": "1", + }, + "message": { + "contents": "Hello, Bob!", + "from": { + "name": "Cow", + "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826", + }, + "to": { + "name": "Bob", + "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB", + }, + }, + "primaryType": "Mail", + "signature": "0xdead", + "types": { + "Mail": [ + { + "name": "from", + "type": "Person", + }, + { + "name": "to", + "type": "Person", + }, + { + "name": "contents", + "type": "string", + }, + ], + "Person": [ + { + "name": "name", + "type": "string", + }, + { + "name": "wallet", + "type": "address", + }, + ], + }, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('account not deployed', async () => { + const { result } = renderHook(() => + useVerifyTypedData({ + ...typedData.basic, + primaryType: 'Mail', + address: notDeployedAddress, + signature: + '0x79d756d805073dc97b7bc885b0d56ddf319a2599530fe1e178c2a7de5be88980068d24f20a79b318ea0a84d33ae06f93db77e4235e5d9eeb8b1d7a63922ada3e1c', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": false, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "verifyTypedData", + { + "address": "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef", + "chainId": 1, + "domain": { + "chainId": 1, + "name": "Ether Mail", + "verifyingContract": "0x0000000000000000000000000000000000000000", + "version": "1", + }, + "message": { + "contents": "Hello, Bob!", + "from": { + "name": "Cow", + "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826", + }, + "to": { + "name": "Bob", + "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB", + }, + }, + "primaryType": "Mail", + "signature": "0x79d756d805073dc97b7bc885b0d56ddf319a2599530fe1e178c2a7de5be88980068d24f20a79b318ea0a84d33ae06f93db77e4235e5d9eeb8b1d7a63922ada3e1c", + "types": { + "Mail": [ + { + "name": "from", + "type": "Person", + }, + { + "name": "to", + "type": "Person", + }, + { + "name": "contents", + "type": "string", + }, + ], + "Person": [ + { + "name": "name", + "type": "string", + }, + { + "name": "wallet", + "type": "address", + }, + ], + }, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: signature: undefined -> defined', async () => { + let signature: Hex | undefined = undefined + + const { result, rerender } = renderHook(() => + useVerifyTypedData({ + ...typedData.basic, + primaryType: 'Mail', + address: smartAccountAddress, + signature, + }), + ) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": undefined, + "dataUpdatedAt": 0, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": false, + "isFetchedAfterMount": false, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": true, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": false, + "queryKey": [ + "verifyTypedData", + { + "address": "0x3FCf42e10CC70Fe75A62EB3aDD6D305Aa840d145", + "chainId": 1, + "domain": { + "chainId": 1, + "name": "Ether Mail", + "verifyingContract": "0x0000000000000000000000000000000000000000", + "version": "1", + }, + "message": { + "contents": "Hello, Bob!", + "from": { + "name": "Cow", + "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826", + }, + "to": { + "name": "Bob", + "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB", + }, + }, + "primaryType": "Mail", + "signature": undefined, + "types": { + "Mail": [ + { + "name": "from", + "type": "Person", + }, + { + "name": "to", + "type": "Person", + }, + { + "name": "contents", + "type": "string", + }, + ], + "Person": [ + { + "name": "name", + "type": "string", + }, + { + "name": "wallet", + "type": "address", + }, + ], + }, + }, + ], + "refetch": [Function], + "status": "pending", + } + `) + + signature = + '0x79d756d805073dc97b7bc885b0d56ddf319a2599530fe1e178c2a7de5be88980068d24f20a79b318ea0a84d33ae06f93db77e4235e5d9eeb8b1d7a63922ada3e1c' + rerender() + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": true, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "verifyTypedData", + { + "address": "0x3FCf42e10CC70Fe75A62EB3aDD6D305Aa840d145", + "chainId": 1, + "domain": { + "chainId": 1, + "name": "Ether Mail", + "verifyingContract": "0x0000000000000000000000000000000000000000", + "version": "1", + }, + "message": { + "contents": "Hello, Bob!", + "from": { + "name": "Cow", + "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826", + }, + "to": { + "name": "Bob", + "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB", + }, + }, + "primaryType": "Mail", + "signature": "0x79d756d805073dc97b7bc885b0d56ddf319a2599530fe1e178c2a7de5be88980068d24f20a79b318ea0a84d33ae06f93db77e4235e5d9eeb8b1d7a63922ada3e1c", + "types": { + "Mail": [ + { + "name": "from", + "type": "Person", + }, + { + "name": "to", + "type": "Person", + }, + { + "name": "contents", + "type": "string", + }, + ], + "Person": [ + { + "name": "name", + "type": "string", + }, + { + "name": "wallet", + "type": "address", + }, + ], + }, + }, + ], + "refetch": [Function], + "status": "success", + } + `) +}) + +test('behavior: disabled when properties missing', async () => { + const { result } = renderHook(() => useVerifyTypedData()) + + await wait(100) + await waitFor(() => expect(result.current.isPending).toBeTruthy()) +}) diff --git a/wagmi-project/packages/react/src/hooks/useVerifyTypedData.ts b/wagmi-project/packages/react/src/hooks/useVerifyTypedData.ts new file mode 100644 index 0000000000..b02d1a8510 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useVerifyTypedData.ts @@ -0,0 +1,81 @@ +'use client' + +import type { + Config, + ResolvedRegister, + VerifyTypedDataErrorType, +} from '@wagmi/core' +import { + type VerifyTypedDataData, + type VerifyTypedDataOptions, + type VerifyTypedDataQueryKey, + verifyTypedDataQueryOptions, +} from '@wagmi/core/query' +import type { VerifyTypedDataQueryFnData } from '@wagmi/core/query' +import type { TypedData } from 'viem' +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseVerifyTypedDataParameters< + typedData extends TypedData | Record = TypedData, + primaryType extends keyof typedData | 'EIP712Domain' = keyof typedData, + config extends Config = Config, + selectData = VerifyTypedDataData, +> = VerifyTypedDataOptions & + ConfigParameter & + QueryParameter< + VerifyTypedDataQueryFnData, + VerifyTypedDataErrorType, + selectData, + VerifyTypedDataQueryKey + > + +export type UseVerifyTypedDataReturnType = + UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useVerifyTypedData */ +export function useVerifyTypedData< + const typedData extends TypedData | Record, + primaryType extends keyof typedData | 'EIP712Domain', + config extends Config = ResolvedRegister['config'], + selectData = VerifyTypedDataData, +>( + parameters: UseVerifyTypedDataParameters< + typedData, + primaryType, + config, + selectData + > = {} as any, +): UseVerifyTypedDataReturnType { + const { + address, + message, + primaryType, + signature, + types, + query = {}, + } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = verifyTypedDataQueryOptions( + config, + { + ...parameters, + chainId: parameters.chainId ?? chainId, + }, + ) + const enabled = Boolean( + address && + message && + primaryType && + signature && + types && + (query.enabled ?? true), + ) + + return useQuery({ ...query, ...options, enabled }) +} diff --git a/wagmi-project/packages/react/src/hooks/useWaitForCallsStatus.test.ts b/wagmi-project/packages/react/src/hooks/useWaitForCallsStatus.test.ts new file mode 100644 index 0000000000..96f5a2a7e4 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWaitForCallsStatus.test.ts @@ -0,0 +1,101 @@ +import { connect, disconnect } from '@wagmi/core' +import { accounts, config, testClient, wait } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { parseEther } from 'viem' +import { expect, test } from 'vitest' + +import { useSendCalls } from './useSendCalls.js' +import { useWaitForCallsStatus } from './useWaitForCallsStatus.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const useSendCalls_render = renderHook(() => useSendCalls()) + const useWaitForCallsStatus_render = renderHook(() => + useWaitForCallsStatus({ id: useSendCalls_render.result.current.data?.id }), + ) + + useSendCalls_render.result.current.sendCalls({ + calls: [ + { + data: '0xdeadbeef', + to: accounts[1], + value: parseEther('1'), + }, + { + to: accounts[2], + value: parseEther('2'), + }, + { + to: accounts[3], + value: parseEther('3'), + }, + ], + }) + await waitFor(() => + expect(useSendCalls_render.result.current.isSuccess).toBeTruthy(), + ) + + expect(useWaitForCallsStatus_render.result.current.fetchStatus).toBe('idle') + useWaitForCallsStatus_render.rerender() + expect(useWaitForCallsStatus_render.result.current.fetchStatus).toBe( + 'fetching', + ) + + await Promise.all([ + waitFor(() => + expect( + useWaitForCallsStatus_render.result.current.isSuccess, + ).toBeTruthy(), + ), + (async () => { + await wait(100) + await testClient.mainnet.mine({ blocks: 1 }) + })(), + ]) + + expect(useWaitForCallsStatus_render.result.current.data?.status).toBe( + 'success', + ) + expect( + useWaitForCallsStatus_render.result.current.data?.receipts?.map((x) => ({ + ...x, + blockHash: undefined, + })), + ).toMatchInlineSnapshot( + ` + [ + { + "blockHash": undefined, + "blockNumber": 19258214n, + "gasUsed": 21064n, + "logs": [], + "status": "success", + "transactionHash": "0x13c53b2d4d9da424835525349cd66e553330f323d6fb19458b801ae1f7989a41", + }, + { + "blockHash": undefined, + "blockNumber": 19258214n, + "gasUsed": 21000n, + "logs": [], + "status": "success", + "transactionHash": "0xd8397b3e82b061c26a0c2093f1ceca0c3662a512614f7d6370349e89d0eea007", + }, + { + "blockHash": undefined, + "blockNumber": 19258214n, + "gasUsed": 21000n, + "logs": [], + "status": "success", + "transactionHash": "0x4d26e346593d9ea265bb164b115e89aa92df43b0b8778ac75d4ad28e2a22b101", + }, + ] + `, + ) + + await testClient.mainnet.mine({ blocks: 1 }) + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useWaitForCallsStatus.ts b/wagmi-project/packages/react/src/hooks/useWaitForCallsStatus.ts new file mode 100644 index 0000000000..7c428c9405 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWaitForCallsStatus.ts @@ -0,0 +1,54 @@ +'use client' + +import type { + Config, + ResolvedRegister, + WaitForCallsStatusErrorType, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type WaitForCallsStatusData, + type WaitForCallsStatusOptions, + type WaitForCallsStatusQueryFnData, + type WaitForCallsStatusQueryKey, + waitForCallsStatusQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useConfig } from './useConfig.js' + +export type UseWaitForCallsStatusParameters< + config extends Config = Config, + selectData = WaitForCallsStatusData, +> = Compute< + WaitForCallsStatusOptions & + ConfigParameter & + QueryParameter< + WaitForCallsStatusQueryFnData, + WaitForCallsStatusErrorType, + selectData, + WaitForCallsStatusQueryKey + > +> + +export type UseWaitForCallsStatusReturnType< + selectData = WaitForCallsStatusData, +> = UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useWaitForCallsStatus */ +export function useWaitForCallsStatus< + config extends Config = ResolvedRegister['config'], + selectData = WaitForCallsStatusData, +>( + parameters: UseWaitForCallsStatusParameters, +): UseWaitForCallsStatusReturnType { + const { id, query = {} } = parameters + + const config = useConfig(parameters) + + const options = waitForCallsStatusQueryOptions(config, parameters) + const enabled = Boolean(id && (query.enabled ?? true)) + + return useQuery({ ...query, ...options, enabled }) +} diff --git a/wagmi-project/packages/react/src/hooks/useWaitForTransactionReceipt.test-d.ts b/wagmi-project/packages/react/src/hooks/useWaitForTransactionReceipt.test-d.ts new file mode 100644 index 0000000000..2d3bd28445 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWaitForTransactionReceipt.test-d.ts @@ -0,0 +1,14 @@ +import { expectTypeOf, test } from 'vitest' + +import { useWaitForTransactionReceipt } from './useWaitForTransactionReceipt.js' + +test('select data', () => { + const result = useWaitForTransactionReceipt({ + query: { + select(data) { + return data?.blockNumber + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/react/src/hooks/useWaitForTransactionReceipt.test.ts b/wagmi-project/packages/react/src/hooks/useWaitForTransactionReceipt.test.ts new file mode 100644 index 0000000000..484d25087f --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWaitForTransactionReceipt.test.ts @@ -0,0 +1,77 @@ +import { wait } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' +import { useWaitForTransactionReceipt } from './useWaitForTransactionReceipt.js' + +test('default', async () => { + const { result } = renderHook(() => + useWaitForTransactionReceipt({ + hash: '0x60668ed8c2dc110d61d945a936fcd45b8f13654e5c78481c8c825d1148c7ef30', + }), + ) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result).toMatchInlineSnapshot(` + { + "current": { + "data": { + "blockHash": "0xd725a38b51e5ceec8c5f6c9ccfdb2cc423af993bb650af5eedca5e4be7156ba7", + "blockNumber": 15189204n, + "chainId": 1, + "contractAddress": null, + "cumulativeGasUsed": 12949744n, + "effectiveGasPrice": 9371645552n, + "from": "0xa0cf798816d4b9b9866b5330eea46a18382f251e", + "gasUsed": 21000n, + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "status": "success", + "to": "0xd2135cfb216b74109775236e36d4b433f1df507b", + "transactionHash": "0x60668ed8c2dc110d61d945a936fcd45b8f13654e5c78481c8c825d1148c7ef30", + "transactionIndex": 144, + "type": "eip1559", + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "waitForTransactionReceipt", + { + "chainId": 1, + "hash": "0x60668ed8c2dc110d61d945a936fcd45b8f13654e5c78481c8c825d1148c7ef30", + }, + ], + "refetch": [Function], + "status": "success", + }, + } + `) +}) + +test('disabled when hash is undefined', async () => { + const { result } = renderHook(() => + useWaitForTransactionReceipt({ hash: undefined }), + ) + + await wait(100) + await waitFor(() => expect(result.current.isPending).toBeTruthy()) +}) diff --git a/wagmi-project/packages/react/src/hooks/useWaitForTransactionReceipt.ts b/wagmi-project/packages/react/src/hooks/useWaitForTransactionReceipt.ts new file mode 100644 index 0000000000..c07d1639bc --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWaitForTransactionReceipt.ts @@ -0,0 +1,74 @@ +'use client' + +import type { + Config, + ResolvedRegister, + WaitForTransactionReceiptErrorType, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type WaitForTransactionReceiptData, + type WaitForTransactionReceiptOptions, + type WaitForTransactionReceiptQueryFnData, + type WaitForTransactionReceiptQueryKey, + waitForTransactionReceiptQueryOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseWaitForTransactionReceiptParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = WaitForTransactionReceiptData, +> = Compute< + WaitForTransactionReceiptOptions & + ConfigParameter & + QueryParameter< + WaitForTransactionReceiptQueryFnData, + WaitForTransactionReceiptErrorType, + selectData, + WaitForTransactionReceiptQueryKey + > +> + +export type UseWaitForTransactionReceiptReturnType< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = WaitForTransactionReceiptData, +> = UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useWaitForTransactionReceipt */ +export function useWaitForTransactionReceipt< + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = WaitForTransactionReceiptData, +>( + parameters: UseWaitForTransactionReceiptParameters< + config, + chainId, + selectData + > = {}, +): UseWaitForTransactionReceiptReturnType { + const { hash, query = {} } = parameters + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const options = waitForTransactionReceiptQueryOptions(config, { + ...parameters, + chainId: parameters.chainId ?? chainId, + }) + const enabled = Boolean(hash && (query.enabled ?? true)) + + return useQuery({ + ...(query as any), + ...options, + enabled, + }) as UseWaitForTransactionReceiptReturnType +} diff --git a/wagmi-project/packages/react/src/hooks/useWalletClient.test-d.ts b/wagmi-project/packages/react/src/hooks/useWalletClient.test-d.ts new file mode 100644 index 0000000000..c2ea48bcb1 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWalletClient.test-d.ts @@ -0,0 +1,12 @@ +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { useWalletClient } from './useWalletClient.js' + +test('parameters: config', async () => { + const client = useWalletClient({ config }) + expectTypeOf(client.data?.chain?.id!).toEqualTypeOf<1 | 456 | 10>() + + const client2 = useWalletClient({ config, chainId: 1 }) + expectTypeOf(client2.data?.chain?.id!).toEqualTypeOf<1>() +}) diff --git a/wagmi-project/packages/react/src/hooks/useWalletClient.test.tsx b/wagmi-project/packages/react/src/hooks/useWalletClient.test.tsx new file mode 100644 index 0000000000..40fdd5850a --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWalletClient.test.tsx @@ -0,0 +1,222 @@ +import { connect, disconnect } from '@wagmi/core' +import { config, wait } from '@wagmi/test' +import { render, renderHook, waitFor } from '@wagmi/test/react' +import * as React from 'react' +import { expect, test } from 'vitest' + +import { useAccount } from './useAccount.js' +import { useConnect } from './useConnect.js' +import { useDisconnect } from './useDisconnect.js' +import { useSwitchChain } from './useSwitchChain.js' +import { useWalletClient } from './useWalletClient.js' + +// Almost identical implementation to `useConnectorClient` (except for return type) +// Should update both in tandem + +const connector = config.connectors[0]! + +test('default', async () => { + const { result } = renderHook(() => useWalletClient()) + + await waitFor(() => expect(result.current.isPending).toBeTruthy()) + + expect(result.current).toMatchInlineSnapshot(` + { + "data": undefined, + "dataUpdatedAt": 0, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": false, + "isFetchedAfterMount": false, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": true, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": false, + "queryKey": [ + "walletClient", + { + "chainId": 1, + "connectorUid": undefined, + }, + ], + "refetch": [Function], + "status": "pending", + } + `) +}) + +test('behavior: connected on mount', async () => { + await connect(config, { connector }) + + const { result } = renderHook(() => useWalletClient()) + + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + const { data, queryKey: _, ...rest } = result.current + expect(data).toMatchObject( + expect.objectContaining({ + account: expect.any(Object), + chain: expect.any(Object), + }), + ) + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": true, + "refetch": [Function], + "status": "success", + } + `) + + await disconnect(config, { connector }) +}) + +test('behavior: connect and disconnect', async () => { + const { result } = renderHook(() => ({ + useConnect: useConnect(), + useWalletClient: useWalletClient(), + useDisconnect: useDisconnect(), + })) + + expect(result.current.useWalletClient.data).not.toBeDefined() + + result.current.useConnect.connect({ + connector: result.current.useConnect.connectors[0]!, + }) + + await waitFor(() => expect(result.current.useWalletClient.data).toBeDefined()) + + result.current.useDisconnect.disconnect() + + await waitFor(() => + expect(result.current.useWalletClient.data).not.toBeDefined(), + ) +}) + +test('behavior: switch chains', async () => { + await connect(config, { connector }) + + const { result } = renderHook(() => ({ + useWalletClient: useWalletClient(), + useSwitchChain: useSwitchChain(), + })) + + expect(result.current.useWalletClient.data).not.toBeDefined() + + await waitFor(() => expect(result.current.useWalletClient.data).toBeDefined()) + + result.current.useSwitchChain.switchChain({ chainId: 456 }) + await waitFor(() => { + expect(result.current.useSwitchChain.isSuccess).toBeTruthy() + result.current.useSwitchChain.reset() + }) + expect(result.current.useWalletClient.data?.chain.id).toEqual(456) + + result.current.useSwitchChain.switchChain({ chainId: 1 }) + await waitFor(() => + expect(result.current.useSwitchChain.isSuccess).toBeTruthy(), + ) + expect(result.current.useWalletClient.data?.chain.id).toEqual(1) + + await disconnect(config, { connector }) +}) + +test('behavior: re-render does not invalidate query', async () => { + const { getByTestId } = render() + + getByTestId('connect').click() + await waitFor(() => { + expect(getByTestId('address').innerText).toContain( + '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + ) + expect(getByTestId('client').innerText).toBeTruthy() + + expect(getByTestId('child-client').innerText).toBeTruthy() + expect(getByTestId('render-count').innerText).toEqual('1') + }) + + const initialClient = getByTestId('child-client').innerText + + getByTestId('rerender').click() + await waitFor(() => { + expect(getByTestId('render-count').innerText).toEqual('2') + }) + await wait(200) + + expect(getByTestId('child-client').innerText).toEqual(initialClient) +}) + +function Parent() { + const [renderCount, setRenderCount] = React.useState(1) + + const { connectors, connect } = useConnect() + const { address } = useAccount() + const { data } = useWalletClient() + + return ( + <> +
{address}
+
{data?.uid}
+ + + + + + ) +} + +function Child(props: { + renderCount: number +}) { + const { renderCount } = props + const { data } = useWalletClient() + return ( +
+ {data?.uid} + {renderCount} +
+ ) +} diff --git a/wagmi-project/packages/react/src/hooks/useWalletClient.ts b/wagmi-project/packages/react/src/hooks/useWalletClient.ts new file mode 100644 index 0000000000..24a3bccdda --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWalletClient.ts @@ -0,0 +1,116 @@ +'use client' + +// Almost identical implementation to `useConnectorClient` (except for return type) +// Should update both in tandem + +import { useQueryClient } from '@tanstack/react-query' +import type { + Config, + GetWalletClientErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute, Omit } from '@wagmi/core/internal' +import { + type GetWalletClientData, + type GetWalletClientOptions, + type GetWalletClientQueryFnData, + type GetWalletClientQueryKey, + getWalletClientQueryOptions, +} from '@wagmi/core/query' +import { useEffect, useRef } from 'react' + +import type { ConfigParameter } from '../types/properties.js' +import { + type UseQueryParameters, + type UseQueryReturnType, + useQuery, +} from '../utils/query.js' +import { useAccount } from './useAccount.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseWalletClientParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetWalletClientData, +> = Compute< + GetWalletClientOptions & + ConfigParameter & { + query?: + | Compute< + Omit< + UseQueryParameters< + GetWalletClientQueryFnData, + GetWalletClientErrorType, + selectData, + GetWalletClientQueryKey + >, + 'gcTime' | 'staleTime' + > + > + | undefined + } +> + +export type UseWalletClientReturnType< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetWalletClientData, +> = UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useWalletClient */ +export function useWalletClient< + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetWalletClientData, +>( + parameters: UseWalletClientParameters = {}, +): UseWalletClientReturnType { + const { query = {}, ...rest } = parameters + + const config = useConfig(rest) + const queryClient = useQueryClient() + const { address, connector, status } = useAccount({ config }) + const chainId = useChainId({ config }) + const activeConnector = parameters.connector ?? connector + + const { queryKey, ...options } = getWalletClientQueryOptions( + config, + { + ...parameters, + chainId: parameters.chainId ?? chainId, + connector: parameters.connector ?? connector, + }, + ) + const enabled = Boolean( + (status === 'connected' || + (status === 'reconnecting' && activeConnector?.getProvider)) && + (query.enabled ?? true), + ) + + const addressRef = useRef(address) + // biome-ignore lint/correctness/useExhaustiveDependencies: `queryKey` not required + useEffect(() => { + const previousAddress = addressRef.current + if (!address && previousAddress) { + // remove when account is disconnected + queryClient.removeQueries({ queryKey }) + addressRef.current = undefined + } else if (address !== previousAddress) { + // invalidate when address changes + queryClient.invalidateQueries({ queryKey }) + addressRef.current = address + } + }, [address, queryClient]) + + return useQuery({ + ...query, + ...options, + queryKey, + enabled, + staleTime: Number.POSITIVE_INFINITY, + } as any) as UseWalletClientReturnType +} diff --git a/wagmi-project/packages/react/src/hooks/useWatchAsset.test-d.ts b/wagmi-project/packages/react/src/hooks/useWatchAsset.test-d.ts new file mode 100644 index 0000000000..0b7258c583 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWatchAsset.test-d.ts @@ -0,0 +1,66 @@ +import type { WatchAssetErrorType } from '@wagmi/core' +import type { WatchAssetVariables } from '@wagmi/core/query' +import { expectTypeOf, test } from 'vitest' + +import { useWatchAsset } from './useWatchAsset.js' + +const tokenInfo = { + address: '0x0000000000000000000000000000000000000000', + symbol: 'NULL', + decimals: 18, +} +const contextValue = { foo: 'bar' } as const + +test('context', () => { + const { context, data, error, watchAsset, variables } = useWatchAsset({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toEqualTypeOf() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + }, + }) + + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + watchAsset( + { type: 'ERC20', options: tokenInfo }, + { + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + }, + ) +}) diff --git a/wagmi-project/packages/react/src/hooks/useWatchAsset.test.ts b/wagmi-project/packages/react/src/hooks/useWatchAsset.test.ts new file mode 100644 index 0000000000..989b0323c8 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWatchAsset.test.ts @@ -0,0 +1,27 @@ +import { connect, disconnect } from '@wagmi/core' +import { config } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useWatchAsset } from './useWatchAsset.js' + +const connector = config.connectors[0]! + +const tokenInfo = { + address: '0x0000000000000000000000000000000000000000', + symbol: 'NULL', + decimals: 18, +} + +test('default', async () => { + await connect(config, { connector }) + + const { result } = renderHook(() => useWatchAsset()) + + result.current.watchAsset({ type: 'ERC20', options: tokenInfo }) + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current.data).toEqual(true) + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useWatchAsset.ts b/wagmi-project/packages/react/src/hooks/useWatchAsset.ts new file mode 100644 index 0000000000..cda4d6b0be --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWatchAsset.ts @@ -0,0 +1,65 @@ +'use client' + +import { useMutation } from '@tanstack/react-query' +import type { WatchAssetErrorType } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type WatchAssetData, + type WatchAssetMutate, + type WatchAssetMutateAsync, + type WatchAssetVariables, + watchAssetMutationOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' + +export type UseWatchAssetParameters = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + WatchAssetData, + WatchAssetErrorType, + WatchAssetVariables, + context + > + | undefined + } +> + +export type UseWatchAssetReturnType = Compute< + UseMutationReturnType< + WatchAssetData, + WatchAssetErrorType, + WatchAssetVariables, + context + > & { + watchAsset: WatchAssetMutate + watchAssetAsync: WatchAssetMutateAsync + } +> + +/** https://wagmi.sh/react/api/hooks/useWatchAsset */ +export function useWatchAsset( + parameters: UseWatchAssetParameters = {}, +): UseWatchAssetReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = watchAssetMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + return { + ...result, + watchAsset: mutate, + watchAssetAsync: mutateAsync, + } +} diff --git a/wagmi-project/packages/react/src/hooks/useWatchBlockNumber.test-d.ts b/wagmi-project/packages/react/src/hooks/useWatchBlockNumber.test-d.ts new file mode 100644 index 0000000000..0d669725bc --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWatchBlockNumber.test-d.ts @@ -0,0 +1,71 @@ +import { createConfig } from '@wagmi/core' +import { http, webSocket } from 'viem' +import { mainnet, optimism } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { + type UseWatchBlockNumberParameters, + useWatchBlockNumber, +} from './useWatchBlockNumber.js' + +test('default', () => { + useWatchBlockNumber({ + poll: false, + onBlockNumber() {}, + }) +}) + +test('differing transports', () => { + const config = createConfig({ + chains: [mainnet, optimism], + transports: { + [mainnet.id]: http(), + [optimism.id]: webSocket(), + }, + }) + + type Result = UseWatchBlockNumberParameters< + typeof config, + typeof mainnet.id | typeof optimism.id + > + expectTypeOf().toEqualTypeOf() + useWatchBlockNumber({ + config, + poll: false, + onBlockNumber() {}, + }) + + type Result2 = UseWatchBlockNumberParameters + expectTypeOf().toEqualTypeOf() + useWatchBlockNumber({ + config, + chainId: mainnet.id, + poll: true, + onBlockNumber() {}, + }) + useWatchBlockNumber({ + config, + chainId: mainnet.id, + // @ts-expect-error + poll: false, + onBlockNumber() {}, + }) + + type Result3 = UseWatchBlockNumberParameters< + typeof config, + typeof optimism.id + > + expectTypeOf().toEqualTypeOf() + useWatchBlockNumber({ + config, + chainId: optimism.id, + poll: true, + onBlockNumber() {}, + }) + useWatchBlockNumber({ + config, + chainId: optimism.id, + poll: false, + onBlockNumber() {}, + }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useWatchBlockNumber.test.ts b/wagmi-project/packages/react/src/hooks/useWatchBlockNumber.test.ts new file mode 100644 index 0000000000..ecb900b357 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWatchBlockNumber.test.ts @@ -0,0 +1,28 @@ +import { testClient, wait } from '@wagmi/test' +import { renderHook } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useWatchBlockNumber } from './useWatchBlockNumber.js' + +test('default', async () => { + const blockNumbers: bigint[] = [] + renderHook(() => + useWatchBlockNumber({ + onBlockNumber(blockNumber) { + blockNumbers.push(blockNumber) + }, + }), + ) + + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + + expect(blockNumbers.length).toBe(3) + expect( + blockNumbers.map((blockNumber) => blockNumber - blockNumbers[0]!), + ).toEqual([0n, 1n, 2n]) +}) diff --git a/wagmi-project/packages/react/src/hooks/useWatchBlockNumber.ts b/wagmi-project/packages/react/src/hooks/useWatchBlockNumber.ts new file mode 100644 index 0000000000..33ddac48a6 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWatchBlockNumber.ts @@ -0,0 +1,65 @@ +'use client' + +import { + type Config, + type ResolvedRegister, + type WatchBlockNumberParameters, + watchBlockNumber, +} from '@wagmi/core' +import type { UnionCompute, UnionExactPartial } from '@wagmi/core/internal' +import { useEffect } from 'react' + +import type { ConfigParameter, EnabledParameter } from '../types/properties.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseWatchBlockNumberParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = UnionCompute< + UnionExactPartial> & + ConfigParameter & + EnabledParameter +> + +export type UseWatchBlockNumberReturnType = void + +/** https://wagmi.sh/react/api/hooks/useWatchBlockNumber */ +export function useWatchBlockNumber< + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +>( + parameters: UseWatchBlockNumberParameters = {} as any, +): UseWatchBlockNumberReturnType { + const { enabled = true, onBlockNumber, config: _, ...rest } = parameters + + const config = useConfig(parameters) + const configChainId = useChainId({ config }) + const chainId = parameters.chainId ?? configChainId + + // TODO(react@19): cleanup + // biome-ignore lint/correctness/useExhaustiveDependencies: `rest` changes every render so only including properties in dependency array + useEffect(() => { + if (!enabled) return + if (!onBlockNumber) return + return watchBlockNumber(config, { + ...(rest as any), + chainId, + onBlockNumber, + }) + }, [ + chainId, + config, + enabled, + onBlockNumber, + /// + rest.onError, + rest.emitMissed, + rest.emitOnBegin, + rest.poll, + rest.pollingInterval, + rest.syncConnectedChain, + ]) +} diff --git a/wagmi-project/packages/react/src/hooks/useWatchBlocks.test-d.ts b/wagmi-project/packages/react/src/hooks/useWatchBlocks.test-d.ts new file mode 100644 index 0000000000..2051bfb66f --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWatchBlocks.test-d.ts @@ -0,0 +1,73 @@ +import { createConfig } from '@wagmi/core' +import { http, webSocket } from 'viem' +import { mainnet, optimism } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { + type UseWatchBlocksParameters, + useWatchBlocks, +} from './useWatchBlocks.js' + +test('default', () => { + useWatchBlocks({ + poll: false, + onBlock() {}, + }) +}) + +test('differing transports', () => { + const config = createConfig({ + chains: [mainnet, optimism], + transports: { + [mainnet.id]: http(), + [optimism.id]: webSocket(), + }, + }) + + type Result = UseWatchBlocksParameters< + false, + 'latest', + typeof config, + typeof mainnet.id | typeof optimism.id + > + expectTypeOf().toEqualTypeOf() + useWatchBlocks({ + config, + poll: false, + onBlock() {}, + }) + + type Result2 = UseWatchBlocksParameters< + false, + 'latest', + typeof config, + typeof mainnet.id + > + expectTypeOf().toEqualTypeOf() + useWatchBlocks({ + config, + chainId: mainnet.id, + poll: true, + onBlock() {}, + }) + + type Result3 = UseWatchBlocksParameters< + false, + 'latest', + typeof config, + typeof optimism.id + > + expectTypeOf().toEqualTypeOf() + useWatchBlocks({ + config, + chainId: optimism.id, + poll: true, + onBlock() {}, + }) + useWatchBlocks({ + config, + chainId: optimism.id, + poll: false, + onBlock() {}, + }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useWatchBlocks.test.ts b/wagmi-project/packages/react/src/hooks/useWatchBlocks.test.ts new file mode 100644 index 0000000000..039c718834 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWatchBlocks.test.ts @@ -0,0 +1,31 @@ +import { testClient, wait } from '@wagmi/test' +import { renderHook } from '@wagmi/test/react' +import type { Block } from 'viem' +import { expect, test } from 'vitest' + +import { useWatchBlocks } from './useWatchBlocks.js' + +test('default', async () => { + const blocks: Block[] = [] + renderHook(() => + useWatchBlocks({ + onBlock(block) { + blocks.push(block) + }, + }), + ) + + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + + expect(blocks.length).toBe(3) + expect(blocks.map((block) => block.number! - blocks[0]!.number!)).toEqual([ + 0n, + 1n, + 2n, + ]) +}) diff --git a/wagmi-project/packages/react/src/hooks/useWatchBlocks.ts b/wagmi-project/packages/react/src/hooks/useWatchBlocks.ts new file mode 100644 index 0000000000..466929c841 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWatchBlocks.ts @@ -0,0 +1,79 @@ +'use client' + +import { + type Config, + type ResolvedRegister, + type WatchBlocksParameters, + watchBlocks, +} from '@wagmi/core' +import type { UnionCompute, UnionExactPartial } from '@wagmi/core/internal' +import { useEffect } from 'react' +import type { BlockTag } from 'viem' + +import type { ConfigParameter, EnabledParameter } from '../types/properties.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseWatchBlocksParameters< + includeTransactions extends boolean = false, + blockTag extends BlockTag = 'latest', + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = UnionCompute< + UnionExactPartial< + WatchBlocksParameters + > & + ConfigParameter & + EnabledParameter +> + +export type UseWatchBlocksReturnType = void + +/** https://wagmi.sh/react/hooks/useWatchBlocks */ +export function useWatchBlocks< + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + includeTransactions extends boolean = false, + blockTag extends BlockTag = 'latest', +>( + parameters: UseWatchBlocksParameters< + includeTransactions, + blockTag, + config, + chainId + > = {} as any, +): UseWatchBlocksReturnType { + const { enabled = true, onBlock, config: _, ...rest } = parameters + + const config = useConfig(parameters) + const configChainId = useChainId({ config }) + const chainId = parameters.chainId ?? configChainId + + // TODO(react@19): cleanup + // biome-ignore lint/correctness/useExhaustiveDependencies: `rest` changes every render so only including properties in dependency array + useEffect(() => { + if (!enabled) return + if (!onBlock) return + return watchBlocks(config, { + ...(rest as any), + chainId, + onBlock, + }) + }, [ + chainId, + config, + enabled, + onBlock, + /// + rest.blockTag, + rest.emitMissed, + rest.emitOnBegin, + rest.includeTransactions, + rest.onError, + rest.poll, + rest.pollingInterval, + rest.syncConnectedChain, + ]) +} diff --git a/wagmi-project/packages/react/src/hooks/useWatchContractEvent.test-d.ts b/wagmi-project/packages/react/src/hooks/useWatchContractEvent.test-d.ts new file mode 100644 index 0000000000..b1d74de450 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWatchContractEvent.test-d.ts @@ -0,0 +1,128 @@ +import { http, createConfig, webSocket } from '@wagmi/core' +import { mainnet, optimism } from '@wagmi/core/chains' +import { abi } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { + type UseWatchContractEventParameters, + useWatchContractEvent, +} from './useWatchContractEvent.js' + +test('default', () => { + useWatchContractEvent({ + address: '0x', + abi: abi.erc20, + eventName: 'Transfer', + poll: false, + args: { + from: '0x', + to: '0x', + }, + onLogs(logs) { + expectTypeOf(logs[0]!.eventName).toEqualTypeOf<'Transfer'>() + expectTypeOf(logs[0]!.args).toEqualTypeOf<{ + from?: `0x${string}` | undefined + to?: `0x${string}` | undefined + value?: bigint | undefined + }>() + }, + }) +}) + +test('behavior: no eventName', () => { + useWatchContractEvent({ + address: '0x', + abi: abi.erc20, + args: { + // TODO: Figure out why this is not working + // @ts-ignore + from: '0x', + to: '0x', + }, + onLogs(logs) { + expectTypeOf(logs[0]!.eventName).toEqualTypeOf<'Transfer' | 'Approval'>() + expectTypeOf(logs[0]!.args).toEqualTypeOf< + | Record + | readonly unknown[] + | { + from?: `0x${string}` | undefined + to?: `0x${string}` | undefined + value?: bigint | undefined + } + | { + owner?: `0x${string}` | undefined + spender?: `0x${string}` | undefined + value?: bigint | undefined + } + >() + }, + }) +}) + +test('differing transports', () => { + const config = createConfig({ + chains: [mainnet, optimism], + transports: { + [mainnet.id]: http(), + [optimism.id]: webSocket(), + }, + }) + + type Result = UseWatchContractEventParameters< + typeof abi.erc20, + 'Transfer' | 'Approval', + true, + typeof config, + typeof mainnet.id | typeof optimism.id + > + expectTypeOf().toEqualTypeOf() + useWatchContractEvent({ + config, + poll: false, + address: '0x', + abi: abi.erc20, + onLogs() {}, + }) + + type Result2 = UseWatchContractEventParameters< + typeof abi.erc20, + 'Transfer' | 'Approval', + true, + typeof config, + typeof mainnet.id + > + expectTypeOf().toEqualTypeOf() + useWatchContractEvent({ + config, + chainId: mainnet.id, + poll: true, + address: '0x', + abi: abi.erc20, + onLogs() {}, + }) + + type Result3 = UseWatchContractEventParameters< + typeof abi.erc20, + 'Transfer' | 'Approval', + true, + typeof config, + typeof optimism.id + > + expectTypeOf().toEqualTypeOf() + useWatchContractEvent({ + config, + chainId: optimism.id, + poll: true, + address: '0x', + abi: abi.erc20, + onLogs() {}, + }) + useWatchContractEvent({ + config, + chainId: optimism.id, + poll: false, + address: '0x', + abi: abi.erc20, + onLogs() {}, + }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useWatchContractEvent.test.ts b/wagmi-project/packages/react/src/hooks/useWatchContractEvent.test.ts new file mode 100644 index 0000000000..e6ad2aa1dc --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWatchContractEvent.test.ts @@ -0,0 +1,86 @@ +import { connect, disconnect, getBalance, writeContract } from '@wagmi/core' +import { + abi, + accounts, + address, + config, + testClient, + transactionHashRegex, + wait, +} from '@wagmi/test' +import { renderHook } from '@wagmi/test/react' +import { http, createWalletClient, parseEther } from 'viem' +import type { WatchEventOnLogsParameter } from 'viem/actions' +import { expect, test } from 'vitest' + +import { useWatchContractEvent } from './useWatchContractEvent.js' + +const connector = config.connectors[0]! + +test('default', async () => { + const data = await connect(config, { connector }) + const connectedAddress = data.accounts[0] + + // impersonate usdc holder account and transfer usdc to connected account + await testClient.mainnet.impersonateAccount({ address: address.usdcHolder }) + await testClient.mainnet.setBalance({ + address: address.usdcHolder, + value: 10000000000000000000000n, + }) + await createWalletClient({ + account: address.usdcHolder, + chain: testClient.mainnet.chain, + transport: http(), + }).writeContract({ + address: address.usdc, + abi: abi.erc20, + functionName: 'transfer', + args: [connectedAddress, parseEther('10', 'gwei')], + }) + await testClient.mainnet.mine({ blocks: 1 }) + await testClient.mainnet.stopImpersonatingAccount({ + address: address.usdcHolder, + }) + + const balance = await getBalance(config, { + address: connectedAddress, + token: address.usdc, + }) + expect(balance.value).toBeGreaterThan(0n) + + // start watching transfer events + let logs: WatchEventOnLogsParameter = [] + renderHook(() => + useWatchContractEvent({ + address: address.usdc, + abi: abi.erc20, + eventName: 'Transfer', + onLogs(next) { + logs = logs.concat(next) + }, + }), + ) + + await writeContract(config, { + address: address.usdc, + abi: abi.erc20, + functionName: 'transfer', + args: [accounts[1], parseEther('1', 'gwei')], + }) + + await writeContract(config, { + address: address.usdc, + abi: abi.erc20, + functionName: 'transfer', + args: [accounts[3], parseEther('1', 'gwei')], + }) + + await testClient.mainnet.mine({ blocks: 1 }) + await testClient.mainnet.mine({ blocks: 1 }) + await wait(1000) // wait for events to be emitted + + expect(logs.length).toBe(2) + expect(logs[0]?.transactionHash).toMatch(transactionHashRegex) + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useWatchContractEvent.ts b/wagmi-project/packages/react/src/hooks/useWatchContractEvent.ts new file mode 100644 index 0000000000..0d7710df2a --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWatchContractEvent.ts @@ -0,0 +1,85 @@ +'use client' + +import { + type Config, + type ResolvedRegister, + type WatchContractEventParameters, + watchContractEvent, +} from '@wagmi/core' +import type { UnionCompute, UnionExactPartial } from '@wagmi/core/internal' +import { useEffect } from 'react' +import type { Abi, ContractEventName } from 'viem' + +import type { ConfigParameter, EnabledParameter } from '../types/properties.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseWatchContractEventParameters< + abi extends Abi | readonly unknown[] = Abi, + eventName extends ContractEventName = ContractEventName, + strict extends boolean | undefined = undefined, + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = UnionCompute< + UnionExactPartial< + WatchContractEventParameters + > & + ConfigParameter & + EnabledParameter +> + +export type UseWatchContractEventReturnType = void + +/** https://wagmi.sh/react/api/hooks/useWatchContractEvent */ +export function useWatchContractEvent< + const abi extends Abi | readonly unknown[], + eventName extends ContractEventName, + strict extends boolean | undefined = undefined, + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +>( + parameters: UseWatchContractEventParameters< + abi, + eventName, + strict, + config, + chainId + > = {} as any, +): UseWatchContractEventReturnType { + const { enabled = true, onLogs, config: _, ...rest } = parameters + + const config = useConfig(parameters) + const configChainId = useChainId({ config }) + const chainId = parameters.chainId ?? configChainId + + // TODO(react@19): cleanup + // biome-ignore lint/correctness/useExhaustiveDependencies: `rest` changes every render so only including properties in dependency array + useEffect(() => { + if (!enabled) return + if (!onLogs) return + return watchContractEvent(config, { + ...(rest as any), + chainId, + onLogs, + }) + }, [ + chainId, + config, + enabled, + onLogs, + /// + rest.abi, + rest.address, + rest.args, + rest.batch, + rest.eventName, + rest.fromBlock, + rest.onError, + rest.poll, + rest.pollingInterval, + rest.strict, + rest.syncConnectedChain, + ]) +} diff --git a/wagmi-project/packages/react/src/hooks/useWatchPendingTransactions.test-d.ts b/wagmi-project/packages/react/src/hooks/useWatchPendingTransactions.test-d.ts new file mode 100644 index 0000000000..56ccc49cbf --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWatchPendingTransactions.test-d.ts @@ -0,0 +1,67 @@ +import { createConfig } from '@wagmi/core' +import { http, webSocket } from 'viem' +import { mainnet, optimism } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import { + type UseWatchPendingTransactionsParameters, + useWatchPendingTransactions, +} from './useWatchPendingTransactions.js' + +test('default', () => { + useWatchPendingTransactions({ + poll: false, + onTransactions() {}, + }) +}) + +test('differing transports', () => { + const config = createConfig({ + chains: [mainnet, optimism], + transports: { + [mainnet.id]: http(), + [optimism.id]: webSocket(), + }, + }) + + type Result = UseWatchPendingTransactionsParameters< + typeof config, + typeof mainnet.id | typeof optimism.id + > + expectTypeOf().toEqualTypeOf() + useWatchPendingTransactions({ + config, + poll: false, + onTransactions() {}, + }) + + type Result2 = UseWatchPendingTransactionsParameters< + typeof config, + typeof mainnet.id + > + expectTypeOf().toEqualTypeOf() + useWatchPendingTransactions({ + config, + chainId: mainnet.id, + poll: true, + onTransactions() {}, + }) + + type Result3 = UseWatchPendingTransactionsParameters< + typeof config, + typeof optimism.id + > + expectTypeOf().toEqualTypeOf() + useWatchPendingTransactions({ + config, + chainId: optimism.id, + poll: true, + onTransactions() {}, + }) + useWatchPendingTransactions({ + config, + chainId: optimism.id, + poll: false, + onTransactions() {}, + }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useWatchPendingTransactions.test.ts b/wagmi-project/packages/react/src/hooks/useWatchPendingTransactions.test.ts new file mode 100644 index 0000000000..e1981f3fa1 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWatchPendingTransactions.test.ts @@ -0,0 +1,49 @@ +import { connect, disconnect, sendTransaction } from '@wagmi/core' +import { + accounts, + config, + testClient, + transactionHashRegex, + wait, +} from '@wagmi/test' +import { renderHook } from '@wagmi/test/react' +import { parseEther } from 'viem' +import type { OnTransactionsParameter } from 'viem/actions' +import { expect, test } from 'vitest' + +import { useWatchPendingTransactions } from './useWatchPendingTransactions.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + let transactions: OnTransactionsParameter = [] + renderHook(() => + useWatchPendingTransactions({ + onTransactions(next) { + transactions = [...transactions, ...next] + }, + }), + ) + await wait(1000) + + await sendTransaction(config, { + to: accounts[1], + value: parseEther('1'), + }) + await wait(200) + + await sendTransaction(config, { + to: accounts[3], + value: parseEther('1'), + }) + await wait(200) + + await testClient.mainnet.mine({ blocks: 1 }) + + expect(transactions.length).toBe(2) + expect(transactions[0]).toMatch(transactionHashRegex) + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useWatchPendingTransactions.ts b/wagmi-project/packages/react/src/hooks/useWatchPendingTransactions.ts new file mode 100644 index 0000000000..7461ffcfb4 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWatchPendingTransactions.ts @@ -0,0 +1,67 @@ +'use client' + +import { + type Config, + type ResolvedRegister, + type WatchPendingTransactionsParameters, + watchPendingTransactions, +} from '@wagmi/core' +import type { UnionCompute, UnionExactPartial } from '@wagmi/core/internal' +import { useEffect } from 'react' + +import type { ConfigParameter, EnabledParameter } from '../types/properties.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseWatchPendingTransactionsParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = UnionCompute< + UnionExactPartial> & + ConfigParameter & + EnabledParameter +> + +export type UseWatchPendingTransactionsReturnType = void + +/** https://wagmi.sh/react/api/hooks/useWatchPendingTransactions */ +export function useWatchPendingTransactions< + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +>( + parameters: UseWatchPendingTransactionsParameters< + config, + chainId + > = {} as any, +): UseWatchPendingTransactionsReturnType { + const { enabled = true, onTransactions, config: _, ...rest } = parameters + + const config = useConfig(parameters) + const configChainId = useChainId({ config }) + const chainId = parameters.chainId ?? configChainId + + // TODO(react@19): cleanup + // biome-ignore lint/correctness/useExhaustiveDependencies: `rest` changes every render so only including properties in dependency array + useEffect(() => { + if (!enabled) return + if (!onTransactions) return + return watchPendingTransactions(config, { + ...(rest as any), + chainId, + onTransactions, + }) + }, [ + chainId, + config, + enabled, + onTransactions, + /// + rest.batch, + rest.onError, + rest.poll, + rest.pollingInterval, + rest.syncConnectedChain, + ]) +} diff --git a/wagmi-project/packages/react/src/hooks/useWriteContract.test-d.ts b/wagmi-project/packages/react/src/hooks/useWriteContract.test-d.ts new file mode 100644 index 0000000000..344c11255b --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWriteContract.test-d.ts @@ -0,0 +1,185 @@ +import { http, type WriteContractErrorType, createConfig } from '@wagmi/core' +import { base } from '@wagmi/core/chains' +import { abi } from '@wagmi/test' +import type { Abi, Address, Hash } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { useSimulateContract } from './useSimulateContract.js' +import { useWriteContract } from './useWriteContract.js' + +const contextValue = { foo: 'bar' } as const + +test('context', () => { + const { + context, + data, + error, + writeContract: write, + variables, + } = useWriteContract({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: Abi + functionName: string + args?: readonly unknown[] | undefined + }>() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: Abi + functionName: string + args?: readonly unknown[] | undefined + }>() + }, + onSuccess(data, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: Abi + functionName: string + args?: readonly unknown[] | undefined + }>() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: Abi + functionName: string + args?: readonly unknown[] | undefined + }>() + }, + }, + }) + + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toMatchTypeOf< + { chainId?: number | undefined } | undefined + >() + expectTypeOf(context).toEqualTypeOf() + + write( + { + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + chainId: 1, + }, + { + onError(error, variables, context) { + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: typeof abi.erc20 + functionName: 'transferFrom' + args: readonly [Address, Address, bigint] + }>() + }, + onSuccess(data, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + expectTypeOf(variables.functionName).toEqualTypeOf<'transferFrom'>() + expectTypeOf(variables.args).toEqualTypeOf< + readonly [Address, Address, bigint] + >() + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: typeof abi.erc20 + functionName: 'transferFrom' + args: readonly [Address, Address, bigint] + }>() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: typeof abi.erc20 + functionName: 'transferFrom' + args: readonly [Address, Address, bigint] + }>() + }, + }, + ) +}) + +test('useSimulateContract', () => { + const { data } = useSimulateContract({ + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + chainId: 1, + }) + const { writeContract } = useWriteContract() + + const request = data?.request + if (request) writeContract(request) +}) + +// https://github.com/wevm/wagmi/issues/3981 +test('gh#3981', () => { + const config = createConfig({ + chains: [base], + transports: { + [base.id]: http(), + }, + }) + + const abi = [ + { + type: 'function', + name: 'example1', + inputs: [ + { name: 'exampleName', type: 'address', internalType: 'address' }, + ], + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + name: 'example2', + inputs: [ + { name: 'exampleName', type: 'address', internalType: 'address' }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + ] as const + + const { writeContract } = useWriteContract({ config }) + writeContract({ + abi, + address: '0x...', + functionName: 'example1', + args: ['0x...'], + value: 123n, + }) + writeContract({ + abi, + address: '0x...', + functionName: 'example2', + args: ['0x...'], + // @ts-expect-error + value: 123n, + }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useWriteContract.test.ts b/wagmi-project/packages/react/src/hooks/useWriteContract.test.ts new file mode 100644 index 0000000000..16ef870c2b --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWriteContract.test.ts @@ -0,0 +1,25 @@ +import { connect, disconnect } from '@wagmi/core' +import { abi, address, config } from '@wagmi/test' +import { renderHook, waitFor } from '@wagmi/test/react' +import { expect, test } from 'vitest' + +import { useWriteContract } from './useWriteContract.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const { result } = renderHook(() => useWriteContract()) + + result.current.writeContract({ + abi: abi.wagmiMintExample, + address: address.wagmiMintExample, + functionName: 'mint', + }) + await waitFor(() => expect(result.current.isSuccess).toBeTruthy()) + + expect(result.current.data).toBeDefined() + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/react/src/hooks/useWriteContract.ts b/wagmi-project/packages/react/src/hooks/useWriteContract.ts new file mode 100644 index 0000000000..b07e856c93 --- /dev/null +++ b/wagmi-project/packages/react/src/hooks/useWriteContract.ts @@ -0,0 +1,87 @@ +'use client' + +import { useMutation } from '@tanstack/react-query' +import type { + Config, + ResolvedRegister, + WriteContractErrorType, +} from '@wagmi/core' +import { + type WriteContractData, + type WriteContractMutate, + type WriteContractMutateAsync, + type WriteContractVariables, + writeContractMutationOptions, +} from '@wagmi/core/query' +import type { Abi } from 'viem' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' + +export type UseWriteContractParameters< + config extends Config = Config, + context = unknown, +> = ConfigParameter & { + mutation?: + | UseMutationParameters< + WriteContractData, + WriteContractErrorType, + WriteContractVariables< + Abi, + string, + readonly unknown[], + config, + config['chains'][number]['id'] + >, + context + > + | undefined +} + +export type UseWriteContractReturnType< + config extends Config = Config, + context = unknown, +> = UseMutationReturnType< + WriteContractData, + WriteContractErrorType, + WriteContractVariables< + Abi, + string, + readonly unknown[], + config, + config['chains'][number]['id'] + >, + context +> & { + writeContract: WriteContractMutate + writeContractAsync: WriteContractMutateAsync +} + +/** https://wagmi.sh/react/api/hooks/useWriteContract */ +export function useWriteContract< + config extends Config = ResolvedRegister['config'], + context = unknown, +>( + parameters: UseWriteContractParameters = {}, +): UseWriteContractReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = writeContractMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + type Return = UseWriteContractReturnType + return { + ...result, + writeContract: mutate as Return['writeContract'], + writeContractAsync: mutateAsync as Return['writeContractAsync'], + } +} diff --git a/wagmi-project/packages/react/src/hydrate.ts b/wagmi-project/packages/react/src/hydrate.ts new file mode 100644 index 0000000000..b185929c22 --- /dev/null +++ b/wagmi-project/packages/react/src/hydrate.ts @@ -0,0 +1,36 @@ +'use client' + +import { type ResolvedRegister, type State, hydrate } from '@wagmi/core' +import { type ReactElement, useEffect, useRef } from 'react' + +export type HydrateProps = { + config: ResolvedRegister['config'] + initialState?: State | undefined + reconnectOnMount?: boolean | undefined +} + +export function Hydrate(parameters: React.PropsWithChildren) { + const { children, config, initialState, reconnectOnMount = true } = parameters + + const { onMount } = hydrate(config, { + initialState, + reconnectOnMount, + }) + + // Hydrate for non-SSR + if (!config._internal.ssr) onMount() + + // Hydrate for SSR + const active = useRef(true) + // biome-ignore lint/correctness/useExhaustiveDependencies: `queryKey` not required + useEffect(() => { + if (!active.current) return + if (!config._internal.ssr) return + onMount() + return () => { + active.current = false + } + }, []) + + return children as ReactElement +} diff --git a/wagmi-project/packages/react/src/types/properties.ts b/wagmi-project/packages/react/src/types/properties.ts new file mode 100644 index 0000000000..7d903faf0a --- /dev/null +++ b/wagmi-project/packages/react/src/types/properties.ts @@ -0,0 +1,51 @@ +import type { DefaultError, QueryKey } from '@tanstack/react-query' +import type { Config } from '@wagmi/core' +import type { Omit } from '@wagmi/core/internal' + +import type { + UseInfiniteQueryParameters, + UseQueryParameters, +} from '../utils/query.js' + +export type EnabledParameter = { + enabled?: boolean | undefined +} + +export type ConfigParameter = { + config?: Config | config | undefined +} + +export type QueryParameter< + queryFnData = unknown, + error = DefaultError, + data = queryFnData, + queryKey extends QueryKey = QueryKey, +> = { + query?: + | Omit< + UseQueryParameters, + 'queryFn' | 'queryHash' | 'queryKey' | 'queryKeyHashFn' | 'throwOnError' + > + | undefined +} + +export type InfiniteQueryParameter< + queryFnData = unknown, + error = DefaultError, + data = queryFnData, + queryData = queryFnData, + queryKey extends QueryKey = QueryKey, + pageParam = unknown, +> = { + query: Omit< + UseInfiniteQueryParameters< + queryFnData, + error, + data, + queryData, + queryKey, + pageParam + >, + 'queryFn' | 'queryHash' | 'queryKey' | 'queryKeyHashFn' | 'throwOnError' + > +} diff --git a/wagmi-project/packages/react/src/utils/getVersion.test.ts b/wagmi-project/packages/react/src/utils/getVersion.test.ts new file mode 100644 index 0000000000..e8368facea --- /dev/null +++ b/wagmi-project/packages/react/src/utils/getVersion.test.ts @@ -0,0 +1,7 @@ +import { expect, test } from 'vitest' + +import { getVersion } from './getVersion.js' + +test('default', () => { + expect(getVersion()).toMatchInlineSnapshot(`"wagmi@x.y.z"`) +}) diff --git a/wagmi-project/packages/react/src/utils/getVersion.ts b/wagmi-project/packages/react/src/utils/getVersion.ts new file mode 100644 index 0000000000..1a8a9437b3 --- /dev/null +++ b/wagmi-project/packages/react/src/utils/getVersion.ts @@ -0,0 +1,3 @@ +import { version } from '../version.js' + +export const getVersion = () => `wagmi@${version}` diff --git a/wagmi-project/packages/react/src/utils/query.ts b/wagmi-project/packages/react/src/utils/query.ts new file mode 100644 index 0000000000..3aafb16123 --- /dev/null +++ b/wagmi-project/packages/react/src/utils/query.ts @@ -0,0 +1,145 @@ +import { + type DefaultError, + type QueryKey, + type UseInfiniteQueryOptions, + type UseInfiniteQueryResult, + type UseMutationOptions, + type UseMutationResult, + type UseQueryOptions, + type UseQueryResult, + useInfiniteQuery as tanstack_useInfiniteQuery, + useQuery as tanstack_useQuery, + useMutation, +} from '@tanstack/react-query' +import type { + Compute, + ExactPartial, + Omit, + UnionStrictOmit, +} from '@wagmi/core/internal' +import { hashFn } from '@wagmi/core/query' + +export type UseMutationParameters< + data = unknown, + error = Error, + variables = void, + context = unknown, +> = Compute< + Omit< + UseMutationOptions, context>, + 'mutationFn' | 'mutationKey' | 'throwOnError' + > +> + +export type UseMutationReturnType< + data = unknown, + error = Error, + variables = void, + context = unknown, +> = Compute< + UnionStrictOmit< + UseMutationResult, + 'mutate' | 'mutateAsync' + > +> + +export { useMutation } + +//////////////////////////////////////////////////////////////////////////////// + +export type UseQueryParameters< + queryFnData = unknown, + error = DefaultError, + data = queryFnData, + queryKey extends QueryKey = QueryKey, +> = Compute< + ExactPartial< + Omit, 'initialData'> + > & { + // Fix `initialData` type + initialData?: + | UseQueryOptions['initialData'] + | undefined + } +> + +export type UseQueryReturnType = Compute< + UseQueryResult & { + queryKey: QueryKey + } +> + +// Adding some basic customization. +// Ideally we don't have this function, but `import('@tanstack/react-query').useQuery` currently has some quirks where it is super hard to +// pass down the inferred `initialData` type because of it's discriminated overload in the on `useQuery`. +export function useQuery( + parameters: UseQueryParameters & { + queryKey: QueryKey + }, +): UseQueryReturnType { + const result = tanstack_useQuery({ + ...(parameters as any), + queryKeyHashFn: hashFn, // for bigint support + }) as UseQueryReturnType + result.queryKey = parameters.queryKey + return result +} + +//////////////////////////////////////////////////////////////////////////////// + +export type UseInfiniteQueryParameters< + queryFnData = unknown, + error = DefaultError, + data = queryFnData, + queryData = queryFnData, + queryKey extends QueryKey = QueryKey, + pageParam = unknown, +> = Compute< + Omit< + UseInfiniteQueryOptions< + queryFnData, + error, + data, + queryData, + queryKey, + pageParam + >, + 'initialData' + > & { + // Fix `initialData` type + initialData?: + | UseInfiniteQueryOptions< + queryFnData, + error, + data, + queryKey + >['initialData'] + | undefined + } +> + +export type UseInfiniteQueryReturnType< + data = unknown, + error = DefaultError, +> = UseInfiniteQueryResult & { + queryKey: QueryKey +} + +// Adding some basic customization. +export function useInfiniteQuery< + queryFnData, + error, + data, + queryKey extends QueryKey, +>( + parameters: UseInfiniteQueryParameters & { + queryKey: QueryKey + }, +): UseInfiniteQueryReturnType { + const result = tanstack_useInfiniteQuery({ + ...(parameters as any), + queryKeyHashFn: hashFn, // for bigint support + }) as UseInfiniteQueryReturnType + result.queryKey = parameters.queryKey + return result +} diff --git a/wagmi-project/packages/react/src/version.ts b/wagmi-project/packages/react/src/version.ts new file mode 100644 index 0000000000..0ec209c466 --- /dev/null +++ b/wagmi-project/packages/react/src/version.ts @@ -0,0 +1 @@ +export const version = '2.15.4' diff --git a/wagmi-project/packages/react/test/setup.ts b/wagmi-project/packages/react/test/setup.ts new file mode 100644 index 0000000000..5c0dcc071d --- /dev/null +++ b/wagmi-project/packages/react/test/setup.ts @@ -0,0 +1,8 @@ +import { vi } from 'vitest' + +// Make dates stable across runs +Date.now = vi.fn(() => new Date(Date.UTC(2023, 1, 1)).valueOf()) + +vi.mock('../src/version.ts', () => { + return { version: 'x.y.z' } +}) diff --git a/wagmi-project/packages/react/tsconfig.build.json b/wagmi-project/packages/react/tsconfig.build.json new file mode 100644 index 0000000000..fbed2b1036 --- /dev/null +++ b/wagmi-project/packages/react/tsconfig.build.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.base.json", + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.test.ts", "src/**/*.test-d.ts"], + "compilerOptions": { + "sourceMap": true + } +} diff --git a/wagmi-project/packages/react/tsconfig.json b/wagmi-project/packages/react/tsconfig.json new file mode 100644 index 0000000000..1b247fdd49 --- /dev/null +++ b/wagmi-project/packages/react/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.build.json", + "compilerOptions": { + "jsx": "preserve" + }, + "include": ["src/**/*.ts", "src/**/*.tsx", "test/**/*.ts", "test/**/*.tsx"], + "exclude": [] +} diff --git a/wagmi-project/packages/register-tests/react/package.json b/wagmi-project/packages/register-tests/react/package.json new file mode 100644 index 0000000000..769092f959 --- /dev/null +++ b/wagmi-project/packages/register-tests/react/package.json @@ -0,0 +1,16 @@ +{ + "name": "react-register", + "private": true, + "type": "module", + "scripts": { + "check:types": "tsc --noEmit" + }, + "dependencies": { + "@tanstack/react-query": "catalog:", + "react": "catalog:", + "wagmi": "workspace:*" + }, + "devDependencies": { + "@types/react": "catalog:" + } +} diff --git a/wagmi-project/packages/register-tests/react/src/config.ts b/wagmi-project/packages/register-tests/react/src/config.ts new file mode 100644 index 0000000000..5772212c1b --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/config.ts @@ -0,0 +1,26 @@ +import { http } from 'viem' +import { createConfig, mock } from 'wagmi' +import { celo, mainnet, optimism, zkSync } from 'wagmi/chains' + +export const config = createConfig({ + chains: [celo, mainnet, optimism, zkSync], + connectors: [mock({ accounts: ['0x'] })], + transports: { + [celo.id]: http(), + [mainnet.id]: http(), + [optimism.id]: http(), + [zkSync.id]: http(), + }, +}) + +export type ChainId = + | typeof celo.id + | typeof mainnet.id + | typeof optimism.id + | typeof zkSync.id + +declare module 'wagmi' { + interface Register { + config: typeof config + } +} diff --git a/wagmi-project/packages/register-tests/react/src/createUseSimulateContract.test-d.ts b/wagmi-project/packages/register-tests/react/src/createUseSimulateContract.test-d.ts new file mode 100644 index 0000000000..b469ccd024 --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/createUseSimulateContract.test-d.ts @@ -0,0 +1,39 @@ +import { abi, config as testConfig } from '@wagmi/test' +import { test } from 'vitest' +import { celo, mainnet, optimism } from 'wagmi/chains' +import { createUseSimulateContract } from 'wagmi/codegen' + +const useSimulateErc20 = createUseSimulateContract({ + abi: abi.erc20, +}) + +test('chain formatters', () => { + useSimulateErc20({ + feeCurrency: '0x', + }) + + useSimulateErc20({ + chainId: celo.id, + feeCurrency: '0x', + }) + + useSimulateErc20({ + chainId: mainnet.id, + // @ts-expect-error + feeCurrency: '0x', + }) + + useSimulateErc20({ + chainId: optimism.id, + // @ts-expect-error + feeCurrency: '0x', + }) +}) + +test('parameters: config', async () => { + useSimulateErc20({ + config: testConfig, + // @ts-expect-error + feeCurrency: '0x', + }) +}) diff --git a/wagmi-project/packages/register-tests/react/src/createUseWriteContract.test-d.ts b/wagmi-project/packages/register-tests/react/src/createUseWriteContract.test-d.ts new file mode 100644 index 0000000000..0b6c538130 --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/createUseWriteContract.test-d.ts @@ -0,0 +1,66 @@ +import { abi, config } from '@wagmi/test' +import type { Address } from 'viem' +import { expectTypeOf, test } from 'vitest' +import { celo, mainnet, optimism } from 'wagmi/chains' +import { createUseWriteContract } from 'wagmi/codegen' + +const useWriteErc20 = createUseWriteContract({ + abi: abi.erc20, +}) + +test('chain formatters', () => { + const { writeContract } = useWriteErc20() + const shared = { + address: '0x', + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + } as const + + writeContract({ + ...shared, + feeCurrency: '0x', + }) + + type Result = Parameters< + typeof writeContract< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof celo.id + > + >[0] + expectTypeOf().toEqualTypeOf< + `0x${string}` | undefined + >() + writeContract({ + ...shared, + chainId: celo.id, + feeCurrency: '0x', + }) + + writeContract({ + ...shared, + chainId: mainnet.id, + // @ts-expect-error + feeCurrency: '0x', + }) + + writeContract({ + ...shared, + chainId: optimism.id, + // @ts-expect-error + feeCurrency: '0x', + }) +}) + +test('parameters: config', async () => { + const { writeContract } = useWriteErc20({ config }) + + writeContract({ + address: '0x', + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + // @ts-expect-error + feeCurrency: '0x', + }) +}) diff --git a/wagmi-project/packages/register-tests/react/src/useAccount.test-d.ts b/wagmi-project/packages/register-tests/react/src/useAccount.test-d.ts new file mode 100644 index 0000000000..be563933a6 --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/useAccount.test-d.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' +import { useAccount } from 'wagmi' + +import type { ChainId } from './config.js' + +test('default', () => { + const result = useAccount() + if (result.chain) expectTypeOf(result.chain.id).toEqualTypeOf() +}) + +test('parameters: config', async () => { + const result = useAccount({ config }) + if (result.chain) expectTypeOf(result.chain.id).toEqualTypeOf<1 | 10 | 456>() +}) diff --git a/wagmi-project/packages/register-tests/react/src/useBlock.test-d.ts b/wagmi-project/packages/register-tests/react/src/useBlock.test-d.ts new file mode 100644 index 0000000000..5f583a63e6 --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/useBlock.test-d.ts @@ -0,0 +1,27 @@ +import type { Hex } from 'viem' +import { expectTypeOf, test } from 'vitest' +import { useBlock } from 'wagmi' +import { celo } from 'wagmi/chains' + +test('chain formatters', () => { + const result = useBlock() + + if (result.data) expectTypeOf(result.data.difficulty).toEqualTypeOf() + + if (result.data?.chainId === celo.id) { + expectTypeOf(result.data.difficulty).toEqualTypeOf() + expectTypeOf(result.data.gasLimit).toEqualTypeOf() + expectTypeOf(result.data.mixHash).toEqualTypeOf() + expectTypeOf(result.data.nonce).toEqualTypeOf<`0x${string}`>() + expectTypeOf(result.data.uncles).toEqualTypeOf() + } + + const result2 = useBlock({ chainId: celo.id }) + if (result2.data) { + expectTypeOf(result2.data.difficulty).toEqualTypeOf() + expectTypeOf(result2.data.gasLimit).toEqualTypeOf() + expectTypeOf(result2.data.mixHash).toEqualTypeOf() + expectTypeOf(result2.data.nonce).toEqualTypeOf<`0x${string}`>() + expectTypeOf(result2.data.uncles).toEqualTypeOf() + } +}) diff --git a/wagmi-project/packages/register-tests/react/src/useChainId.test-d.ts b/wagmi-project/packages/register-tests/react/src/useChainId.test-d.ts new file mode 100644 index 0000000000..d1a8e035d6 --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/useChainId.test-d.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' +import { useChainId } from 'wagmi' + +import type { ChainId } from './config.js' + +test('default', async () => { + const chainId = useChainId() + expectTypeOf(chainId).toEqualTypeOf() +}) + +test('parameters: config', async () => { + const chainId = useChainId({ config }) + expectTypeOf(chainId).toEqualTypeOf<1 | 456 | 10>() +}) diff --git a/wagmi-project/packages/register-tests/react/src/useChains.test-d.ts b/wagmi-project/packages/register-tests/react/src/useChains.test-d.ts new file mode 100644 index 0000000000..c40fd5e1d2 --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/useChains.test-d.ts @@ -0,0 +1,11 @@ +import { expectTypeOf, test } from 'vitest' +import { useChains } from 'wagmi' +import type { Chain, celo, optimism } from 'wagmi/chains' + +test('default', () => { + const chains = useChains() + + expectTypeOf(chains[0]).toEqualTypeOf() + expectTypeOf(chains[2]).toEqualTypeOf() + expectTypeOf(chains[5]).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/register-tests/react/src/useClient.test-d.ts b/wagmi-project/packages/register-tests/react/src/useClient.test-d.ts new file mode 100644 index 0000000000..0ce810b31c --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/useClient.test-d.ts @@ -0,0 +1,38 @@ +import { type chain, config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' +import { useClient } from 'wagmi' +import { mainnet } from 'wagmi/chains' + +import type { ChainId } from './config.js' + +test('default', () => { + const client = useClient() + expectTypeOf(client.chain.id).toEqualTypeOf() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() +}) + +test('parameters: config', () => { + const client = useClient({ config }) + expectTypeOf(client.chain.id).toEqualTypeOf< + (typeof config)['chains'][number]['id'] + >() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() +}) + +test('parameters: chainId', () => { + const client = useClient({ + config, + chainId: mainnet.id, + }) + expectTypeOf(client.chain).toEqualTypeOf() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() +}) + +test('behavior: unconfigured chain', () => { + const client = useClient({ + config, + // @ts-expect-error + chainId: 123456, + }) + expectTypeOf(client).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/register-tests/react/src/useConfig.test-d.ts b/wagmi-project/packages/register-tests/react/src/useConfig.test-d.ts new file mode 100644 index 0000000000..25eb5246de --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/useConfig.test-d.ts @@ -0,0 +1,17 @@ +import { config as testConfig } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' +import { type Config, useConfig } from 'wagmi' + +import type { config } from './config.js' + +test('default', async () => { + const result = useConfig() + expectTypeOf(result).not.toEqualTypeOf() + expectTypeOf(result).toEqualTypeOf() +}) + +test('parameters: config', async () => { + const result = useConfig({ config: testConfig }) + expectTypeOf(result).not.toEqualTypeOf() + expectTypeOf(result).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/register-tests/react/src/useConnect.test-d.ts b/wagmi-project/packages/register-tests/react/src/useConnect.test-d.ts new file mode 100644 index 0000000000..2386dca7e9 --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/useConnect.test-d.ts @@ -0,0 +1,13 @@ +import { expectTypeOf, test } from 'vitest' +import { useConnect } from 'wagmi' + +test('infers connect parameters', () => { + const { connect, connectors, variables } = useConnect() + const connector = connectors[0]! + + expectTypeOf(variables?.foo).toEqualTypeOf() + connect({ + connector, + foo: 'bar', + }) +}) diff --git a/wagmi-project/packages/register-tests/react/src/usePrepareTransactionRequest.test-d.ts b/wagmi-project/packages/register-tests/react/src/usePrepareTransactionRequest.test-d.ts new file mode 100644 index 0000000000..460408515c --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/usePrepareTransactionRequest.test-d.ts @@ -0,0 +1,42 @@ +import { config as testConfig } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' +import { usePrepareTransactionRequest } from 'wagmi' +import { celo, mainnet, optimism } from 'wagmi/chains' + +test('chain formatters', () => { + const { data } = usePrepareTransactionRequest({ + feeCurrency: '0x', + }) + if (data && data.chainId === celo.id) { + expectTypeOf(data.feeCurrency).toEqualTypeOf<`0x${string}` | undefined>() + } + + const { data: data2 } = usePrepareTransactionRequest({ + chainId: celo.id, + feeCurrency: '0x', + }) + if (data2) { + expectTypeOf(data2.chainId).toEqualTypeOf(celo.id) + expectTypeOf(data2.feeCurrency).toEqualTypeOf<`0x${string}` | undefined>() + } + + usePrepareTransactionRequest({ + chainId: mainnet.id, + // @ts-expect-error + feeCurrency: '0x', + }) + + usePrepareTransactionRequest({ + chainId: optimism.id, + // @ts-expect-error + feeCurrency: '0x', + }) +}) + +test('parameters: config', async () => { + usePrepareTransactionRequest({ + config: testConfig, + // @ts-expect-error + feeCurrency: '0x', + }) +}) diff --git a/wagmi-project/packages/register-tests/react/src/usePublicClient.ts b/wagmi-project/packages/register-tests/react/src/usePublicClient.ts new file mode 100644 index 0000000000..55c6967ab2 --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/usePublicClient.ts @@ -0,0 +1,38 @@ +import { type chain, config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' +import { usePublicClient } from 'wagmi' +import { mainnet } from 'wagmi/chains' + +import type { ChainId } from './config.js' + +test('default', () => { + const client = usePublicClient() + expectTypeOf(client.chain.id).toEqualTypeOf() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() +}) + +test('parameters: config', () => { + const client = usePublicClient({ config }) + expectTypeOf(client.chain.id).toEqualTypeOf< + (typeof config)['chains'][number]['id'] + >() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() +}) + +test('parameters: chainId', () => { + const client = usePublicClient({ + config, + chainId: mainnet.id, + }) + expectTypeOf(client.chain).toEqualTypeOf() + expectTypeOf(client.transport.type).toEqualTypeOf<'http'>() +}) + +test('behavior: unconfigured chain', () => { + const client = usePublicClient({ + config, + // @ts-expect-error + chainId: 123456, + }) + expectTypeOf(client).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/register-tests/react/src/useReadContract.test-d.ts b/wagmi-project/packages/register-tests/react/src/useReadContract.test-d.ts new file mode 100644 index 0000000000..02ca83ed64 --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/useReadContract.test-d.ts @@ -0,0 +1,24 @@ +import type { abi } from '@wagmi/test' +import type { Address } from 'viem' +import { expectTypeOf, test } from 'vitest' +import type { useReadContract } from 'wagmi' + +import type { ChainId } from './config.js' + +test('UseReadContractParameters', () => { + type Result = NonNullable< + Parameters>[0] + > + expectTypeOf().toMatchTypeOf<{ + functionName?: + | 'symbol' + | 'name' + | 'allowance' + | 'balanceOf' + | 'decimals' + | 'totalSupply' + | undefined + args?: readonly [Address] | undefined + chainId?: ChainId | undefined + }>() +}) diff --git a/wagmi-project/packages/register-tests/react/src/useReadContracts.test-d.ts b/wagmi-project/packages/register-tests/react/src/useReadContracts.test-d.ts new file mode 100644 index 0000000000..bb719b7c49 --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/useReadContracts.test-d.ts @@ -0,0 +1,45 @@ +import type { abi } from '@wagmi/test' +import type { Address } from 'viem' +import { expectTypeOf, test } from 'vitest' +import type { useReadContracts } from 'wagmi' + +import type { ChainId } from './config.js' + +test('UseReadContractsParameters', () => { + type Result = NonNullable< + Parameters< + typeof useReadContracts< + [ + { + abi: typeof abi.erc20 + functionName: 'balanceOf' + address: Address + args: readonly [Address] + }, + ] + > + >[0] + >['contracts'] + expectTypeOf().toMatchTypeOf< + | readonly [ + { + abi?: typeof abi.erc20 | undefined + functionName?: + | 'approve' + | 'symbol' + | 'name' + | 'allowance' + | 'balanceOf' + | 'decimals' + | 'totalSupply' + | 'transfer' + | 'transferFrom' + | undefined + address?: Address | undefined + args?: readonly [Address] | undefined + chainId?: ChainId | undefined + }, + ] + | undefined + >() +}) diff --git a/wagmi-project/packages/register-tests/react/src/useSendTransaction.test-d.ts b/wagmi-project/packages/register-tests/react/src/useSendTransaction.test-d.ts new file mode 100644 index 0000000000..60839f5023 --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/useSendTransaction.test-d.ts @@ -0,0 +1,55 @@ +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' +import { useSendTransaction } from 'wagmi' +import { celo, mainnet, optimism } from 'wagmi/chains' +import type { ChainId } from './config.js' + +test('chain formatters', () => { + const { sendTransaction } = useSendTransaction() + + sendTransaction( + { + to: '0x', + feeCurrency: '0x', + }, + { + onSuccess(_data, variables) { + expectTypeOf(variables.chainId).toEqualTypeOf() + }, + }, + ) + + type Result = Parameters>[0] + expectTypeOf().toEqualTypeOf< + `0x${string}` | undefined + >() + sendTransaction({ + chainId: celo.id, + to: '0x', + feeCurrency: '0x', + }) + + sendTransaction({ + chainId: mainnet.id, + to: '0x', + // @ts-expect-error + feeCurrency: '0x', + }) + + sendTransaction({ + chainId: optimism.id, + to: '0x', + // @ts-expect-error + feeCurrency: '0x', + }) +}) + +test('parameters: config', async () => { + const { sendTransaction } = useSendTransaction({ config }) + + sendTransaction({ + to: '0x', + // @ts-expect-error + feeCurrency: '0x', + }) +}) diff --git a/wagmi-project/packages/register-tests/react/src/useSimulateContract.test-d.ts b/wagmi-project/packages/register-tests/react/src/useSimulateContract.test-d.ts new file mode 100644 index 0000000000..96c75d76e8 --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/useSimulateContract.test-d.ts @@ -0,0 +1,94 @@ +import { type abi, config as testConfig } from '@wagmi/test' +import type { Address } from 'viem' +import { expectTypeOf, test } from 'vitest' +import { type UseSimulateContractParameters, useSimulateContract } from 'wagmi' +import type { SimulateContractParameters } from 'wagmi/actions' +import { celo, mainnet, optimism } from 'wagmi/chains' +import type { SimulateContractOptions } from 'wagmi/query' + +import type { ChainId, config } from './config.js' + +test('chain formatters', () => { + const { data } = useSimulateContract({ + feeCurrency: '0x', + }) + if (data && data.chainId === celo.id) { + expectTypeOf(data.request.feeCurrency).toEqualTypeOf< + `0x${string}` | undefined + >() + } + + const { data: data2 } = useSimulateContract({ + chainId: celo.id, + feeCurrency: '0x', + }) + if (data2) { + expectTypeOf(data2.request.feeCurrency).toEqualTypeOf< + `0x${string}` | undefined + >() + } + + useSimulateContract({ + chainId: mainnet.id, + // @ts-expect-error + feeCurrency: '0x', + }) + + useSimulateContract({ + chainId: optimism.id, + // @ts-expect-error + feeCurrency: '0x', + }) +}) + +test('UseSimulateContractParameters', () => { + type Result = UseSimulateContractParameters< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof config + > + + expectTypeOf<{ + functionName?: 'approve' | 'transfer' | 'transferFrom' | undefined + args?: readonly [Address, Address, bigint] | undefined + chainId?: ChainId | undefined + }>().toMatchTypeOf() + + type Result2 = UseSimulateContractParameters< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof config, + typeof celo.id + > + expectTypeOf().toEqualTypeOf() + expectTypeOf().toEqualTypeOf< + `0x${string}` | undefined + >() + + type Result3 = SimulateContractParameters< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof config, + typeof celo.id + > + expectTypeOf().toEqualTypeOf() + type Result4 = SimulateContractOptions< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof config, + typeof celo.id + > + expectTypeOf().toEqualTypeOf() +}) + +test('parameters: config', async () => { + useSimulateContract({ + config: testConfig, + // @ts-expect-error + feeCurrency: '0x', + }) +}) diff --git a/wagmi-project/packages/register-tests/react/src/useSwitchChain.test-d.ts b/wagmi-project/packages/register-tests/react/src/useSwitchChain.test-d.ts new file mode 100644 index 0000000000..2d02557b85 --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/useSwitchChain.test-d.ts @@ -0,0 +1,25 @@ +import { expectTypeOf, test } from 'vitest' +import { useSwitchChain } from 'wagmi' +import { type celo, mainnet, type optimism } from 'wagmi/chains' + +import type { ChainId, config } from './config.js' + +test('default', () => { + const { chains, switchChain } = useSwitchChain() + + expectTypeOf(chains).toEqualTypeOf<(typeof config)['chains']>() + expectTypeOf(chains[0]).toEqualTypeOf() + expectTypeOf(chains[2]).toEqualTypeOf() + + switchChain( + { chainId: 1 }, + { + onSuccess(data) { + expectTypeOf(data).toEqualTypeOf(mainnet) + }, + }, + ) + + type Result = Parameters[0] + expectTypeOf().toEqualTypeOf() +}) diff --git a/wagmi-project/packages/register-tests/react/src/useTransaction.test-d.ts b/wagmi-project/packages/register-tests/react/src/useTransaction.test-d.ts new file mode 100644 index 0000000000..135b99bb2d --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/useTransaction.test-d.ts @@ -0,0 +1,23 @@ +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' +import { useTransaction } from 'wagmi' +import { celo } from 'wagmi/chains' + +test('chain formatters', () => { + const result = useTransaction() + if (result.data?.chainId === celo.id) { + expectTypeOf(result.data.feeCurrency).toEqualTypeOf<`0x${string}` | null>() + } + + const result2 = useTransaction({ chainId: celo.id }) + expectTypeOf(result2.data?.feeCurrency).toEqualTypeOf< + `0x${string}` | null | undefined + >() +}) + +test('parameters: config', async () => { + const result = useTransaction({ config }) + + if (result.data && 'feeCurrency' in result.data) + expectTypeOf(result.data.feeCurrency).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/register-tests/react/src/useTransactionConfirmations.test-d.ts b/wagmi-project/packages/register-tests/react/src/useTransactionConfirmations.test-d.ts new file mode 100644 index 0000000000..fe2445db21 --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/useTransactionConfirmations.test-d.ts @@ -0,0 +1,66 @@ +import { config as testConfig } from '@wagmi/test' +import { test } from 'vitest' +import { useTransactionConfirmations } from 'wagmi' +import { mainnet, zkSync } from 'wagmi/chains' + +const transactionReceipt = { + blockHash: '0x', + blockNumber: 1n, + contractAddress: '0x', + cumulativeGasUsed: 1n, + effectiveGasPrice: 1n, + from: '0x', + gasUsed: 1n, + logsBloom: '0x', + status: 'success', + to: '0x', + transactionHash: '0x', + transactionIndex: 1, + type: 'eip1559', +} as const + +test('chain formatters', async () => { + useTransactionConfirmations({ + transactionReceipt: { + ...transactionReceipt, + l1BatchNumber: 1n, + l1BatchTxIndex: 1n, + logs: [], + l2ToL1Logs: [], + }, + }) + + useTransactionConfirmations({ + chainId: zkSync.id, + transactionReceipt: { + ...transactionReceipt, + l1BatchNumber: 1n, + l1BatchTxIndex: 1n, + logs: [], + l2ToL1Logs: [], + }, + }) + + useTransactionConfirmations({ + chainId: mainnet.id, + transactionReceipt: { + ...transactionReceipt, + // @ts-expect-error + l1BatchNumber: 1n, + l1BatchTxIndex: 1n, + logs: [], + l2ToL1Logs: [], + }, + }) +}) + +test('parameters: config', async () => { + useTransactionConfirmations({ + config: testConfig, + transactionReceipt: { + ...transactionReceipt, + // @ts-expect-error + l1BatchNumber: 1n, + }, + }) +}) diff --git a/wagmi-project/packages/register-tests/react/src/useTransactionReceipt.test-d.ts b/wagmi-project/packages/register-tests/react/src/useTransactionReceipt.test-d.ts new file mode 100644 index 0000000000..1bbd8183da --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/useTransactionReceipt.test-d.ts @@ -0,0 +1,31 @@ +import { config } from '@wagmi/test' +import type { ZkSyncL2ToL1Log, ZkSyncLog } from 'viem/zksync' +import { expectTypeOf, test } from 'vitest' +import { useTransactionReceipt } from 'wagmi' +import { zkSync } from 'wagmi/chains' + +test('chain formatters', () => { + const result = useTransactionReceipt() + + if (result.data?.chainId === zkSync.id) { + expectTypeOf(result.data.l1BatchNumber).toEqualTypeOf() + expectTypeOf(result.data.l1BatchTxIndex).toEqualTypeOf() + expectTypeOf(result.data.logs).toEqualTypeOf() + expectTypeOf(result.data.l2ToL1Logs).toEqualTypeOf() + } + + const result2 = useTransactionReceipt({ chainId: zkSync.id }) + if (result2.data) { + expectTypeOf(result2.data.l1BatchNumber).toEqualTypeOf() + expectTypeOf(result2.data.l1BatchTxIndex).toEqualTypeOf() + expectTypeOf(result2.data.logs).toEqualTypeOf() + expectTypeOf(result2.data.l2ToL1Logs).toEqualTypeOf() + } +}) + +test('parameters: config', async () => { + const result = useTransactionReceipt({ config }) + + if (result.data && 'l1BatchNumber' in result.data) + expectTypeOf(result.data.l1BatchNumber).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/register-tests/react/src/useWaitForTransactionReceipt.ts b/wagmi-project/packages/register-tests/react/src/useWaitForTransactionReceipt.ts new file mode 100644 index 0000000000..0d2501f500 --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/useWaitForTransactionReceipt.ts @@ -0,0 +1,31 @@ +import { config } from '@wagmi/test' +import type { ZkSyncL2ToL1Log, ZkSyncLog } from 'viem/zksync' +import { expectTypeOf, test } from 'vitest' +import { useWaitForTransactionReceipt } from 'wagmi' +import { zkSync } from 'wagmi/chains' + +test('chain formatters', () => { + const result = useWaitForTransactionReceipt() + + if (result.data?.chainId === zkSync.id) { + expectTypeOf(result.data.l1BatchNumber).toEqualTypeOf() + expectTypeOf(result.data.l1BatchTxIndex).toEqualTypeOf() + expectTypeOf(result.data.logs).toEqualTypeOf() + expectTypeOf(result.data.l2ToL1Logs).toEqualTypeOf() + } + + const result2 = useWaitForTransactionReceipt({ chainId: zkSync.id }) + if (result2.data) { + expectTypeOf(result2.data.l1BatchNumber).toEqualTypeOf() + expectTypeOf(result2.data.l1BatchTxIndex).toEqualTypeOf() + expectTypeOf(result2.data.logs).toEqualTypeOf() + expectTypeOf(result2.data.l2ToL1Logs).toEqualTypeOf() + } +}) + +test('parameters: config', async () => { + const result = useWaitForTransactionReceipt({ config }) + + if (result.data && 'l1BatchNumber' in result.data) + expectTypeOf(result.data.l1BatchNumber).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/register-tests/react/src/useWriteContract.test-d.ts b/wagmi-project/packages/register-tests/react/src/useWriteContract.test-d.ts new file mode 100644 index 0000000000..c499ff8f37 --- /dev/null +++ b/wagmi-project/packages/register-tests/react/src/useWriteContract.test-d.ts @@ -0,0 +1,65 @@ +import { abi, config } from '@wagmi/test' +import type { Address } from 'viem' +import { expectTypeOf, test } from 'vitest' +import { useWriteContract } from 'wagmi' +import { celo, mainnet, optimism } from 'wagmi/chains' + +test('chain formatters', () => { + const { writeContract } = useWriteContract() + + const shared = { + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + } as const + + writeContract({ + ...shared, + feeCurrency: '0x', + }) + + type Result = Parameters< + typeof writeContract< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof celo.id + > + >[0] + expectTypeOf().toEqualTypeOf< + `0x${string}` | undefined + >() + writeContract({ + ...shared, + chainId: celo.id, + feeCurrency: '0x', + }) + + writeContract({ + ...shared, + chainId: mainnet.id, + // @ts-expect-error + feeCurrency: '0x', + }) + + writeContract({ + ...shared, + chainId: optimism.id, + // @ts-expect-error + feeCurrency: '0x', + }) +}) + +test('parameters: config', async () => { + const { writeContract } = useWriteContract({ config }) + + writeContract({ + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + // @ts-expect-error + feeCurrency: '0x', + }) +}) diff --git a/wagmi-project/packages/register-tests/react/tsconfig.json b/wagmi-project/packages/register-tests/react/tsconfig.json new file mode 100644 index 0000000000..77a211dbbb --- /dev/null +++ b/wagmi-project/packages/register-tests/react/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "../../../tsconfig.base.json", + "include": ["src/**/*.ts"], + "exclude": [] +} diff --git a/wagmi-project/packages/register-tests/vue/package.json b/wagmi-project/packages/register-tests/vue/package.json new file mode 100644 index 0000000000..fc41697d7f --- /dev/null +++ b/wagmi-project/packages/register-tests/vue/package.json @@ -0,0 +1,13 @@ +{ + "name": "vue-register", + "private": true, + "type": "module", + "scripts": { + "check:types": "tsc --noEmit" + }, + "dependencies": { + "@tanstack/vue-query": "catalog:", + "@wagmi/vue": "workspace:*", + "vue": "catalog:" + } +} diff --git a/wagmi-project/packages/register-tests/vue/src/config.ts b/wagmi-project/packages/register-tests/vue/src/config.ts new file mode 100644 index 0000000000..fd13c5a6be --- /dev/null +++ b/wagmi-project/packages/register-tests/vue/src/config.ts @@ -0,0 +1,26 @@ +import { createConfig, mock } from '@wagmi/vue' +import { celo, mainnet, optimism, zkSync } from '@wagmi/vue/chains' +import { http } from 'viem' + +export const config = createConfig({ + chains: [celo, mainnet, optimism, zkSync], + connectors: [mock({ accounts: ['0x'] })], + transports: { + [celo.id]: http(), + [mainnet.id]: http(), + [optimism.id]: http(), + [zkSync.id]: http(), + }, +}) + +export type ChainId = + | typeof celo.id + | typeof mainnet.id + | typeof optimism.id + | typeof zkSync.id + +declare module '@wagmi/vue' { + interface Register { + config: typeof config + } +} diff --git a/wagmi-project/packages/register-tests/vue/src/useAccount.test-d.ts b/wagmi-project/packages/register-tests/vue/src/useAccount.test-d.ts new file mode 100644 index 0000000000..6471bf4550 --- /dev/null +++ b/wagmi-project/packages/register-tests/vue/src/useAccount.test-d.ts @@ -0,0 +1,17 @@ +import { config } from '@wagmi/test' +import { useAccount } from '@wagmi/vue' +import { expectTypeOf, test } from 'vitest' + +import type { ChainId } from './config.js' + +test('default', () => { + const result = useAccount() + if (result.chain.value) + expectTypeOf(result.chain.value.id).toEqualTypeOf() +}) + +test('parameters: config', async () => { + const result = useAccount({ config }) + if (result.chain.value) + expectTypeOf(result.chain.value.id).toEqualTypeOf<1 | 10 | 456>() +}) diff --git a/wagmi-project/packages/register-tests/vue/src/useChainId.test-d.ts b/wagmi-project/packages/register-tests/vue/src/useChainId.test-d.ts new file mode 100644 index 0000000000..ffeddcb6ba --- /dev/null +++ b/wagmi-project/packages/register-tests/vue/src/useChainId.test-d.ts @@ -0,0 +1,15 @@ +import { config } from '@wagmi/test' +import { useChainId } from '@wagmi/vue' +import { expectTypeOf, test } from 'vitest' + +import type { ChainId } from './config.js' + +test('default', async () => { + const chainId = useChainId() + expectTypeOf(chainId.value).toEqualTypeOf() +}) + +test('parameters: config', async () => { + const chainId = useChainId({ config }) + expectTypeOf(chainId.value).toEqualTypeOf<1 | 456 | 10>() +}) diff --git a/wagmi-project/packages/register-tests/vue/src/useChains.test-d.ts b/wagmi-project/packages/register-tests/vue/src/useChains.test-d.ts new file mode 100644 index 0000000000..d1bf0eb151 --- /dev/null +++ b/wagmi-project/packages/register-tests/vue/src/useChains.test-d.ts @@ -0,0 +1,11 @@ +import { useChains } from '@wagmi/vue' +import type { Chain, celo, optimism } from '@wagmi/vue/chains' +import { expectTypeOf, test } from 'vitest' + +test('default', () => { + const chains = useChains() + + expectTypeOf(chains.value[0]).toEqualTypeOf() + expectTypeOf(chains.value[2]).toEqualTypeOf() + expectTypeOf(chains.value[5]).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/register-tests/vue/src/useClient.test-d.ts b/wagmi-project/packages/register-tests/vue/src/useClient.test-d.ts new file mode 100644 index 0000000000..99cea8d3f2 --- /dev/null +++ b/wagmi-project/packages/register-tests/vue/src/useClient.test-d.ts @@ -0,0 +1,38 @@ +import { type chain, config } from '@wagmi/test' +import { useClient } from '@wagmi/vue' +import { mainnet } from '@wagmi/vue/chains' +import { expectTypeOf, test } from 'vitest' + +import type { ChainId } from './config.js' + +test('default', () => { + const client = useClient() + expectTypeOf(client.value.chain.id).toEqualTypeOf() + expectTypeOf(client.value.transport.type).toEqualTypeOf<'http'>() +}) + +test('parameters: config', () => { + const client = useClient({ config }) + expectTypeOf(client.value.chain.id).toEqualTypeOf< + (typeof config)['chains'][number]['id'] + >() + expectTypeOf(client.value.transport.type).toEqualTypeOf<'http'>() +}) + +test('parameters: chainId', () => { + const client = useClient({ + config, + chainId: mainnet.id, + }) + expectTypeOf(client.value.chain).toEqualTypeOf() + expectTypeOf(client.value.transport.type).toEqualTypeOf<'http'>() +}) + +test('behavior: unconfigured chain', () => { + const client = useClient({ + config, + // @ts-expect-error + chainId: 123456, + }) + expectTypeOf(client.value).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/register-tests/vue/src/useConfig.test-d.ts b/wagmi-project/packages/register-tests/vue/src/useConfig.test-d.ts new file mode 100644 index 0000000000..c65f70c214 --- /dev/null +++ b/wagmi-project/packages/register-tests/vue/src/useConfig.test-d.ts @@ -0,0 +1,17 @@ +import { config as testConfig } from '@wagmi/test' +import { type Config, useConfig } from '@wagmi/vue' +import { expectTypeOf, test } from 'vitest' + +import type { config } from './config.js' + +test('default', async () => { + const result = useConfig() + expectTypeOf(result).not.toEqualTypeOf() + expectTypeOf(result).toEqualTypeOf() +}) + +test('parameters: config', async () => { + const result = useConfig({ config: testConfig }) + expectTypeOf(result).not.toEqualTypeOf() + expectTypeOf(result).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/register-tests/vue/src/useConnect.test-d.ts b/wagmi-project/packages/register-tests/vue/src/useConnect.test-d.ts new file mode 100644 index 0000000000..128834ff6d --- /dev/null +++ b/wagmi-project/packages/register-tests/vue/src/useConnect.test-d.ts @@ -0,0 +1,13 @@ +import { useConnect } from '@wagmi/vue' +import { expectTypeOf, test } from 'vitest' + +test('infers connect parameters', () => { + const { connect, connectors, variables } = useConnect() + const connector = connectors[0]! + + expectTypeOf(variables.value?.foo).toEqualTypeOf() + connect({ + connector, + foo: 'bar', + }) +}) diff --git a/wagmi-project/packages/register-tests/vue/src/useReadContract.test-d.ts b/wagmi-project/packages/register-tests/vue/src/useReadContract.test-d.ts new file mode 100644 index 0000000000..c2a1a6386a --- /dev/null +++ b/wagmi-project/packages/register-tests/vue/src/useReadContract.test-d.ts @@ -0,0 +1,30 @@ +import type { abi } from '@wagmi/test' +import type { useReadContract } from '@wagmi/vue' +import type { Address } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import type { DeepUnwrapRef } from '../../../vue/src/types/ref.js' +import type { ChainId } from './config.js' + +test('UseReadContractParameters', () => { + type Result = DeepUnwrapRef< + NonNullable< + Parameters< + typeof useReadContract + >[0] + > + > + + expectTypeOf().toMatchTypeOf<{ + functionName?: + | 'symbol' + | 'name' + | 'allowance' + | 'balanceOf' + | 'decimals' + | 'totalSupply' + | undefined + args?: readonly [Address] | undefined + chainId?: ChainId | undefined + }>() +}) diff --git a/wagmi-project/packages/register-tests/vue/src/useSendTransaction.test-d.ts b/wagmi-project/packages/register-tests/vue/src/useSendTransaction.test-d.ts new file mode 100644 index 0000000000..c49a8ef386 --- /dev/null +++ b/wagmi-project/packages/register-tests/vue/src/useSendTransaction.test-d.ts @@ -0,0 +1,55 @@ +import { config } from '@wagmi/test' +import { useSendTransaction } from '@wagmi/vue' +import { celo, mainnet, optimism } from '@wagmi/vue/chains' +import { expectTypeOf, test } from 'vitest' +import type { ChainId } from './config.js' + +test('chain formatters', () => { + const { sendTransaction } = useSendTransaction() + + sendTransaction( + { + to: '0x', + feeCurrency: '0x', + }, + { + onSuccess(_data, variables) { + expectTypeOf(variables.chainId).toEqualTypeOf() + }, + }, + ) + + type Result = Parameters>[0] + expectTypeOf().toEqualTypeOf< + `0x${string}` | undefined + >() + sendTransaction({ + chainId: celo.id, + to: '0x', + feeCurrency: '0x', + }) + + sendTransaction({ + chainId: mainnet.id, + to: '0x', + // @ts-expect-error + feeCurrency: '0x', + }) + + sendTransaction({ + chainId: optimism.id, + to: '0x', + // @ts-expect-error + feeCurrency: '0x', + }) +}) + +test('parameters: config', async () => { + const { sendTransaction } = useSendTransaction({ config }) + + sendTransaction({ + to: '0x', + // @ts-expect-error + feeCurrency: '0x', + }) +}) diff --git a/wagmi-project/packages/register-tests/vue/src/useSimulateContract.test-d.ts b/wagmi-project/packages/register-tests/vue/src/useSimulateContract.test-d.ts new file mode 100644 index 0000000000..2a2b65c4d5 --- /dev/null +++ b/wagmi-project/packages/register-tests/vue/src/useSimulateContract.test-d.ts @@ -0,0 +1,86 @@ +import { type abi, config as testConfig } from '@wagmi/test' +import { + type UseSimulateContractParameters, + useSimulateContract, +} from '@wagmi/vue' +import type { SimulateContractParameters } from '@wagmi/vue/actions' +import { celo, mainnet, optimism } from '@wagmi/vue/chains' +import type { SimulateContractOptions } from '@wagmi/vue/query' +import type { Address } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import type { ChainId, config } from './config.js' + +test('chain formatters', () => { + const { data } = useSimulateContract({ + feeCurrency: '0x', + }) + if (data.value && data.value.chainId === celo.id) { + expectTypeOf(data.value.request.feeCurrency).toEqualTypeOf< + `0x${string}` | undefined + >() + } + + const { data: data2 } = useSimulateContract({ + chainId: celo.id, + feeCurrency: '0x', + }) + if (data2.value) { + expectTypeOf(data2.value.request.feeCurrency).toEqualTypeOf< + `0x${string}` | undefined + >() + } + + useSimulateContract({ + chainId: mainnet.id, + // @ts-expect-error + feeCurrency: '0x', + }) + + useSimulateContract({ + chainId: optimism.id, + // @ts-expect-error + feeCurrency: '0x', + }) +}) + +test('UseSimulateContractParameters', () => { + type Result = UseSimulateContractParameters< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof config + > + + expectTypeOf<{ + functionName?: 'approve' | 'transfer' | 'transferFrom' | undefined + args?: readonly [Address, Address, bigint] | undefined + chainId?: ChainId | undefined + }>().toMatchTypeOf() + + type Result2 = SimulateContractParameters< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof config, + typeof celo.id + > + expectTypeOf().toEqualTypeOf() + + type Result3 = SimulateContractOptions< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof config, + typeof celo.id + > + expectTypeOf().toEqualTypeOf() +}) + +test('parameters: config', async () => { + useSimulateContract({ + config: testConfig, + // @ts-expect-error + feeCurrency: '0x', + }) +}) diff --git a/wagmi-project/packages/register-tests/vue/src/useSwitchChain.test-d.ts b/wagmi-project/packages/register-tests/vue/src/useSwitchChain.test-d.ts new file mode 100644 index 0000000000..cf0153b3b7 --- /dev/null +++ b/wagmi-project/packages/register-tests/vue/src/useSwitchChain.test-d.ts @@ -0,0 +1,27 @@ +import { useSwitchChain } from '@wagmi/vue' +import { type celo, mainnet, type optimism } from '@wagmi/vue/chains' +import { expectTypeOf, test } from 'vitest' + +import type { ChainId, config } from './config.js' + +test('default', () => { + const switchChain = useSwitchChain() + + const chains = switchChain.chains.value + + expectTypeOf(chains).toEqualTypeOf<(typeof config)['chains']>() + expectTypeOf(chains[0]).toEqualTypeOf() + expectTypeOf(chains[2]).toEqualTypeOf() + + switchChain.switchChain( + { chainId: 1 }, + { + onSuccess(data) { + expectTypeOf(data).toEqualTypeOf(mainnet) + }, + }, + ) + + type Result = Parameters<(typeof switchChain)['switchChain']>[0] + expectTypeOf().toEqualTypeOf() +}) diff --git a/wagmi-project/packages/register-tests/vue/src/useTransaction.test-d.ts b/wagmi-project/packages/register-tests/vue/src/useTransaction.test-d.ts new file mode 100644 index 0000000000..7bc262c38f --- /dev/null +++ b/wagmi-project/packages/register-tests/vue/src/useTransaction.test-d.ts @@ -0,0 +1,25 @@ +import { config } from '@wagmi/test' +import { useTransaction } from '@wagmi/vue' +import { celo } from '@wagmi/vue/chains' +import { expectTypeOf, test } from 'vitest' + +test('chain formatters', () => { + const result = useTransaction() + if (result.data?.value?.chainId === celo.id) { + expectTypeOf(result.data.value.feeCurrency).toEqualTypeOf< + `0x${string}` | null + >() + } + + const result2 = useTransaction({ chainId: celo.id }) + expectTypeOf(result2.data?.value?.feeCurrency).toEqualTypeOf< + `0x${string}` | null | undefined + >() +}) + +test('parameters: config', async () => { + const result = useTransaction({ config }) + + if (result.data && 'feeCurrency' in result.data) + expectTypeOf(result.data.feeCurrency).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/register-tests/vue/src/useTransactionReceipt.test-d.ts b/wagmi-project/packages/register-tests/vue/src/useTransactionReceipt.test-d.ts new file mode 100644 index 0000000000..c202d82dbb --- /dev/null +++ b/wagmi-project/packages/register-tests/vue/src/useTransactionReceipt.test-d.ts @@ -0,0 +1,41 @@ +import { config } from '@wagmi/test' +import { useTransactionReceipt } from '@wagmi/vue' +import { zkSync } from '@wagmi/vue/chains' +import type { ZkSyncL2ToL1Log, ZkSyncLog } from 'viem/zksync' +import { expectTypeOf, test } from 'vitest' + +test('chain formatters', () => { + const result = useTransactionReceipt() + + if (result.data?.value?.chainId === zkSync.id) { + expectTypeOf(result.data.value.l1BatchNumber).toEqualTypeOf() + expectTypeOf(result.data.value.l1BatchTxIndex).toEqualTypeOf< + bigint | null + >() + expectTypeOf(result.data.value.logs).toEqualTypeOf() + expectTypeOf(result.data.value.l2ToL1Logs).toEqualTypeOf< + ZkSyncL2ToL1Log[] + >() + } + + const result2 = useTransactionReceipt({ chainId: zkSync.id }) + if (result2.data.value) { + expectTypeOf(result2.data.value.l1BatchNumber).toEqualTypeOf< + bigint | null + >() + expectTypeOf(result2.data.value.l1BatchTxIndex).toEqualTypeOf< + bigint | null + >() + expectTypeOf(result2.data.value.logs).toEqualTypeOf() + expectTypeOf(result2.data.value.l2ToL1Logs).toEqualTypeOf< + ZkSyncL2ToL1Log[] + >() + } +}) + +test('parameters: config', async () => { + const result = useTransactionReceipt({ config }) + + if (result.data && 'l1BatchNumber' in result.data) + expectTypeOf(result.data.l1BatchNumber).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/register-tests/vue/src/useWaitForTransaction.test-d.ts b/wagmi-project/packages/register-tests/vue/src/useWaitForTransaction.test-d.ts new file mode 100644 index 0000000000..e0286617c1 --- /dev/null +++ b/wagmi-project/packages/register-tests/vue/src/useWaitForTransaction.test-d.ts @@ -0,0 +1,41 @@ +import { config } from '@wagmi/test' +import { useWaitForTransactionReceipt } from '@wagmi/vue' +import { zkSync } from '@wagmi/vue/chains' +import type { ZkSyncL2ToL1Log, ZkSyncLog } from 'viem/zksync' +import { expectTypeOf, test } from 'vitest' + +test('chain formatters', () => { + const result = useWaitForTransactionReceipt() + + if (result.data?.value?.chainId === zkSync.id) { + expectTypeOf(result.data.value.l1BatchNumber).toEqualTypeOf() + expectTypeOf(result.data.value.l1BatchTxIndex).toEqualTypeOf< + bigint | null + >() + expectTypeOf(result.data.value.logs).toEqualTypeOf() + expectTypeOf(result.data.value.l2ToL1Logs).toEqualTypeOf< + ZkSyncL2ToL1Log[] + >() + } + + const result2 = useWaitForTransactionReceipt({ chainId: zkSync.id }) + if (result2.data.value) { + expectTypeOf(result2.data.value.l1BatchNumber).toEqualTypeOf< + bigint | null + >() + expectTypeOf(result2.data.value.l1BatchTxIndex).toEqualTypeOf< + bigint | null + >() + expectTypeOf(result2.data.value.logs).toEqualTypeOf() + expectTypeOf(result2.data.value.l2ToL1Logs).toEqualTypeOf< + ZkSyncL2ToL1Log[] + >() + } +}) + +test('parameters: config', async () => { + const result = useWaitForTransactionReceipt({ config }) + + if (result.data && 'l1BatchNumber' in result.data) + expectTypeOf(result.data.l1BatchNumber).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/register-tests/vue/src/useWriteContract.test-d.ts b/wagmi-project/packages/register-tests/vue/src/useWriteContract.test-d.ts new file mode 100644 index 0000000000..ec4f38430c --- /dev/null +++ b/wagmi-project/packages/register-tests/vue/src/useWriteContract.test-d.ts @@ -0,0 +1,65 @@ +import { abi, config } from '@wagmi/test' +import { useWriteContract } from '@wagmi/vue' +import { celo, mainnet, optimism } from '@wagmi/vue/chains' +import type { Address } from 'viem' +import { expectTypeOf, test } from 'vitest' + +test('chain formatters', () => { + const { writeContract } = useWriteContract() + + const shared = { + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + } as const + + writeContract({ + ...shared, + feeCurrency: '0x', + }) + + type Result = Parameters< + typeof writeContract< + typeof abi.erc20, + 'transferFrom', + [Address, Address, bigint], + typeof celo.id + > + >[0] + expectTypeOf().toEqualTypeOf< + `0x${string}` | undefined + >() + writeContract({ + ...shared, + chainId: celo.id, + feeCurrency: '0x', + }) + + writeContract({ + ...shared, + chainId: mainnet.id, + // @ts-expect-error + feeCurrency: '0x', + }) + + writeContract({ + ...shared, + chainId: optimism.id, + // @ts-expect-error + feeCurrency: '0x', + }) +}) + +test('parameters: config', async () => { + const { writeContract } = useWriteContract({ config }) + + writeContract({ + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + // @ts-expect-error + feeCurrency: '0x', + }) +}) diff --git a/wagmi-project/packages/register-tests/vue/tsconfig.json b/wagmi-project/packages/register-tests/vue/tsconfig.json new file mode 100644 index 0000000000..77a211dbbb --- /dev/null +++ b/wagmi-project/packages/register-tests/vue/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "../../../tsconfig.base.json", + "include": ["src/**/*.ts"], + "exclude": [] +} diff --git a/wagmi-project/packages/test/package.json b/wagmi-project/packages/test/package.json new file mode 100644 index 0000000000..d1c6fb9c19 --- /dev/null +++ b/wagmi-project/packages/test/package.json @@ -0,0 +1,118 @@ +{ + "name": "@wagmi/test", + "description": "Test utils for wagmi", + "private": true, + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/wevm/wagmi.git", + "directory": "packages/test" + }, + "scripts": { + "build": "pnpm run clean && pnpm run build:esm+types", + "build:esm+types": "tsc --project tsconfig.build.json --outDir ./dist/esm --declaration --declarationMap --declarationDir ./dist/types", + "check:types": "tsc --noEmit", + "clean": "rm -rf dist tsconfig.tsbuildinfo", + "test:build": "publint --strict" + }, + "files": [ + "dist/**", + "!dist/**/*.tsbuildinfo", + "src/**/*.ts", + "!src/**/*.test.ts", + "!src/**/*.test-d.ts", + "react/**", + "vue/**" + ], + "sideEffects": false, + "type": "module", + "main": "./dist/esm/exports/index.js", + "types": "./dist/types/exports/index.d.ts", + "typings": "./dist/types/exports/index.d.ts", + "exports": { + ".": { + "types": "./dist/types/exports/index.d.ts", + "default": "./dist/esm/exports/index.js" + }, + "./react": { + "types": "./dist/types/exports/react.d.ts", + "default": "./dist/esm/exports/react.js" + }, + "./vue": { + "types": "./dist/types/exports/vue.d.ts", + "default": "./dist/esm/exports/vue.js" + }, + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "react": ["./dist/types/exports/react.d.ts"], + "vue": ["./dist/types/exports/vue.d.ts"] + } + }, + "peerDependencies": { + "@tanstack/react-query": ">=5.0.0", + "@tanstack/vue-query": ">=5.0.0", + "@testing-library/react": ">=14.0.0", + "@types/react": ">=18", + "@types/react-dom": ">=18", + "@wagmi/core": "workspace:*", + "@wagmi/vue": "workspace:*", + "prool": "^0.0.23", + "react": ">=18", + "react-dom": ">=18", + "typescript": ">=5.0.4", + "viem": "2.x", + "vue": ">=3", + "wagmi": "workspace:*" + }, + "peerDependenciesMeta": { + "@tanstack/react-query": { + "optional": true + }, + "@tanstack/vue-query": { + "optional": true + }, + "@testing-library/react": { + "optional": true + }, + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "typescript": { + "optional": true + }, + "vue": { + "optional": true + }, + "wagmi": { + "optional": true + } + }, + "devDependencies": { + "@tanstack/react-query": "catalog:", + "@tanstack/vue-query": "catalog:", + "@testing-library/dom": "catalog:", + "@testing-library/react": "catalog:", + "@types/react": "catalog:", + "@types/react-dom": "catalog:", + "@wagmi/core": "workspace:*", + "@wagmi/vue": "workspace:*", + "react": "catalog:", + "react-dom": "catalog:", + "vue": "catalog:", + "wagmi": "workspace:*" + }, + "contributors": ["awkweb.eth ", "jxom.eth "], + "funding": "https://github.com/sponsors/wevm", + "keywords": ["eth", "ethereum", "dapps", "wallet", "web3"] +} diff --git a/wagmi-project/packages/test/src/chains.ts b/wagmi-project/packages/test/src/chains.ts new file mode 100644 index 0000000000..af9bdc5d99 --- /dev/null +++ b/wagmi-project/packages/test/src/chains.ts @@ -0,0 +1,51 @@ +import type { Compute } from '@wagmi/core/internal' +import { + type Chain as viem_Chain, + mainnet as viem_mainnet, + optimism as viem_optimism, +} from 'viem/chains' + +import { getRpcUrls } from './utils.js' + +type Fork = { blockNumber: bigint; url: string } + +export type Chain = Compute< + viem_Chain & { + fork: Fork + port: number + } +> + +const mainnetFork = { + blockNumber: 19_258_213n, + url: process.env.VITE_MAINNET_FORK_URL ?? 'https://eth.merkle.io', +} as const satisfies Fork + +export const mainnet = { + ...viem_mainnet, + ...getRpcUrls({ port: 8545 }), + fork: mainnetFork, +} as const satisfies Chain + +export const mainnet2 = { + ...viem_mainnet, + ...getRpcUrls({ port: 8546 }), + id: 456, + nativeCurrency: { decimals: 18, name: 'wagmi', symbol: 'WAG' }, + fork: mainnetFork, +} as const satisfies Chain + +export const optimism = { + ...getRpcUrls({ port: 8547 }), + ...viem_optimism, + fork: { + blockNumber: 107_317_577n, + url: process.env.VITE_OPTIMISM_FORK_URL ?? 'https://mainnet.optimism.io', + }, +} as const satisfies Chain + +export const chain = { + mainnet, + mainnet2, + optimism, +} diff --git a/wagmi-project/packages/test/src/clients.ts b/wagmi-project/packages/test/src/clients.ts new file mode 100644 index 0000000000..5a2d86005a --- /dev/null +++ b/wagmi-project/packages/test/src/clients.ts @@ -0,0 +1,62 @@ +import { + http, + type Account, + type Client, + type TestActions, + type TestRpcSchema, + type Transport, + createTestClient, +} from 'viem' + +import { type Chain, mainnet, mainnet2, optimism } from './chains.js' + +export const mainnetTestClient = createTestClient({ + mode: 'anvil', + cacheTime: 0, + chain: mainnet, + transport: http(), +}).extend(wagmiTestMethods) + +export const mainnet2TestClient = createTestClient({ + mode: 'anvil', + cacheTime: 0, + chain: mainnet2, + transport: http(), +}).extend(wagmiTestMethods) + +export const optimismTestClient = createTestClient({ + mode: 'anvil', + cacheTime: 0, + chain: optimism, + transport: http(), +}).extend(wagmiTestMethods) + +export const testClient = { + mainnet: mainnetTestClient, + mainnet2: mainnet2TestClient, + optimism: optimismTestClient, +} + +function wagmiTestMethods( + client: Client< + Transport, + Chain, + Account | undefined, + TestRpcSchema<'anvil'>, + TestActions + >, +) { + return { + /** Resets instance attached to chain. */ + async restart() { + return await fetch(`${client.chain.rpcUrls.default.http[0]}/restart`) + }, + /** Resets fork attached to chain at starting block number. */ + resetFork() { + return client.reset({ + jsonRpcUrl: client.chain.fork.url, + blockNumber: client.chain.fork.blockNumber, + }) + }, + } +} diff --git a/wagmi-project/packages/test/src/config.ts b/wagmi-project/packages/test/src/config.ts new file mode 100644 index 0000000000..a94cdf45de --- /dev/null +++ b/wagmi-project/packages/test/src/config.ts @@ -0,0 +1,29 @@ +import { createConfig, mock } from '@wagmi/core' +import { http } from 'viem' + +import { mainnet, mainnet2, optimism } from './chains.js' +import { accounts } from './constants.js' + +export const config = createConfig({ + chains: [mainnet, mainnet2, optimism], + connectors: [mock({ accounts }), mock({ accounts: reverse(accounts) })], + pollingInterval: 100, + storage: null, + transports: { + [mainnet.id]: http(), + [mainnet2.id]: http(), + [optimism.id]: http(), + }, +}) + +type Reverse< + list extends readonly unknown[], + /// + result extends readonly unknown[] = [], +> = list extends readonly [infer head, ...infer tail] + ? Reverse + : result + +function reverse(list: list): Reverse { + return [...list].reverse() as Reverse +} diff --git a/wagmi-project/packages/test/src/constants.ts b/wagmi-project/packages/test/src/constants.ts new file mode 100644 index 0000000000..96ca5a9efa --- /dev/null +++ b/wagmi-project/packages/test/src/constants.ts @@ -0,0 +1,318 @@ +import { type Address, parseAbi } from 'viem' + +import type { chain } from './chains.js' + +/** + * The id of the current test worker. + * + * This is used by the anvil proxy to route requests to the correct anvil instance. + */ +export const pool = Number(process.env.VITEST_POOL_ID ?? 1) + +// Test accounts +export const accounts = [ + '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + '0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC', + '0x90F79bf6EB2c4f870365E785982E1f101E93b906', + '0x15d34aaf54267db7d7c367839aaf71a00a2c6a65', + '0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc', + '0x976EA74026E726554dB657fA54763abd0C3a0aa9', + '0x14dC79964da2C08b23698B3D3cc7Ca32193d9955', + '0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f', + '0xa0Ee7A142d267C1f36714E4a8F75612F20a79720', +] as const + +// for `'0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266'` +export const privateKey = + '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80' + +export let walletConnectProjectId: string +if (process.env.VITE_WC_PROJECT_ID) + walletConnectProjectId = process.env.VITE_WC_PROJECT_ID +else walletConnectProjectId = 'foobarbaz' + +export const typedData = { + basic: { + domain: { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0x0000000000000000000000000000000000000000', + }, + types: { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + }, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + }, + complex: { + domain: { + name: 'Ether Mail 🄵', + version: '1.1.1', + chainId: 1, + verifyingContract: '0x0000000000000000000000000000000000000000', + }, + types: { + Name: [ + { name: 'first', type: 'string' }, + { name: 'last', type: 'string' }, + ], + Person: [ + { name: 'name', type: 'Name' }, + { name: 'wallet', type: 'address' }, + { name: 'favoriteColors', type: 'string[3]' }, + { name: 'foo', type: 'uint256' }, + { name: 'age', type: 'uint8' }, + { name: 'isCool', type: 'bool' }, + ], + Mail: [ + { name: 'timestamp', type: 'uint256' }, + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + { name: 'hash', type: 'bytes' }, + ], + }, + message: { + timestamp: 1234567890n, + contents: 'Hello, Bob! šŸ–¤', + hash: '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef', + from: { + name: { + first: 'Cow', + last: 'Burns', + }, + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + age: 69, + foo: 123123123123123123n, + favoriteColors: ['red', 'green', 'blue'], + isCool: false, + }, + to: { + name: { first: 'Bob', last: 'Builder' }, + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + age: 70, + foo: 123123123123123123n, + favoriteColors: ['orange', 'yellow', 'green'], + isCool: true, + }, + }, + }, +} as const + +export const abi = { + erc20: parseAbi([ + 'event Approval(address indexed owner, address indexed spender, uint256 value)', + 'event Transfer(address indexed from, address indexed to, uint256 value)', + 'function allowance(address owner, address spender) view returns (uint256)', + 'function approve(address spender, uint256 amount) returns (bool)', + 'function balanceOf(address account) view returns (uint256)', + 'function decimals() view returns (uint8)', + 'function name() view returns (string)', + 'function symbol() view returns (string)', + 'function totalSupply() view returns (uint256)', + 'function transfer(address recipient, uint256 amount) returns (bool)', + 'function transferFrom(address sender, address recipient, uint256 amount) returns (bool)', + ]), + mloot: parseAbi([ + 'constructor()', + 'event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId)', + 'event ApprovalForAll(address indexed owner, address indexed operator, bool approved)', + 'event OwnershipTransferred(address indexed previousOwner, address indexed newOwner)', + 'event Transfer(address indexed from, address indexed to, uint256 indexed tokenId)', + 'function approve(address to, uint256 tokenId)', + 'function balanceOf(address owner) view returns (uint256)', + 'function claim(uint256 tokenId)', + 'function getApproved(uint256 tokenId) view returns (address)', + 'function getChest(uint256 tokenId) view returns (string)', + 'function getFoot(uint256 tokenId) view returns (string)', + 'function getHand(uint256 tokenId) view returns (string)', + 'function getHead(uint256 tokenId) view returns (string)', + 'function getNeck(uint256 tokenId) view returns (string)', + 'function getRing(uint256 tokenId) view returns (string)', + 'function getWaist(uint256 tokenId) view returns (string)', + 'function getWeapon(uint256 tokenId) view returns (string)', + 'function isApprovedForAll(address owner, address operator) view returns (bool)', + 'function name() view returns (string)', + 'function owner() view returns (address)', + 'function ownerOf(uint256 tokenId) view returns (address)', + 'function renounceOwnership()', + 'function safeTransferFrom(address from, address to, uint256 tokenId)', + 'function safeTransferFrom(address from, address to, uint256 tokenId, bytes _data)', + 'function setApprovalForAll(address operator, bool approved)', + 'function supportsInterface(bytes4 interfaceId) view returns (bool)', + 'function symbol() view returns (string)', + 'function tokenByIndex(uint256 index) view returns (uint256)', + 'function tokenOfOwnerByIndex(address owner, uint256 index) view returns (uint256)', + 'function tokenURI(uint256 tokenId) view returns (string)', + 'function totalSupply() view returns (uint256)', + 'function transferFrom(address from, address to, uint256 tokenId)', + 'function transferOwnership(address newOwner)', + ]), + shields: parseAbi([ + 'constructor(string name_, string symbol_, address _emblemWeaver, address makerBadgeRecipient, address granteeBadgeRecipient)', + 'event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId)', + 'event ApprovalForAll(address indexed owner, address indexed operator, bool approved)', + 'event OwnershipTransferred(address indexed previousOwner, address indexed newOwner)', + 'event ShieldBuilt(uint256 tokenId, uint16 field, uint16 hardware, uint16 frame, uint24[4] colors, uint8 shieldBadge)', + 'event Transfer(address indexed from, address indexed to, uint256 indexed tokenId)', + 'function approve(address to, uint256 tokenId)', + 'function balanceOf(address owner) view returns (uint256)', + 'function build(uint16 field, uint16 hardware, uint16 frame, uint24[4] colors, uint256 tokenId) payable', + 'function collectFees()', + 'function emblemWeaver() view returns (address)', + 'function getApproved(uint256 tokenId) view returns (address)', + 'function isApprovedForAll(address owner, address operator) view returns (bool)', + 'function mint(address to, uint8 count) payable', + 'function mythicFee() view returns (uint256)', + 'function name() view returns (string)', + 'function owner() view returns (address)', + 'function ownerOf(uint256 tokenId) view returns (address)', + 'function publicMintActive() view returns (bool)', + 'function publicMintPrice() view returns (uint256)', + 'function renounceOwnership()', + 'function safeTransferFrom(address from, address to, uint256 tokenId)', + 'function safeTransferFrom(address from, address to, uint256 tokenId, bytes _data)', + 'function setApprovalForAll(address operator, bool approved)', + 'function setPublicMintActive()', + 'function setPublicMintPrice(uint256 _publicMintPrice)', + 'function shieldHashes(bytes32) view returns (bool)', + 'function shields(uint256 tokenId) view returns (uint16 field, uint16 hardware, uint16 frame, uint24 color1, uint24 color2, uint24 color3, uint24 color4, uint8 shieldBadge)', + 'function specialFee() view returns (uint256)', + 'function supportsInterface(bytes4 interfaceId) view returns (bool)', + 'function symbol() view returns (string)', + 'function tokenURI(uint256 tokenId) view returns (string)', + 'function totalSupply() view returns (uint256)', + 'function transferFrom(address from, address to, uint256 tokenId)', + 'function transferOwnership(address newOwner)', + ]), + wagmigotchi: parseAbi([ + 'constructor()', + 'event CaretakerLoved(address indexed caretaker, uint256 indexed amount)', + 'function clean()', + 'function feed()', + 'function getAlive() view returns (bool)', + 'function getBoredom() view returns (uint256)', + 'function getHunger() view returns (uint256)', + 'function getSleepiness() view returns (uint256)', + 'function getStatus() view returns (string)', + 'function getUncleanliness() view returns (uint256)', + 'function love(address) view returns (uint256)', + 'function play()', + 'function sleep()', + ]), + wagmiMintExample: parseAbi([ + 'constructor()', + 'event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId)', + 'event ApprovalForAll(address indexed owner, address indexed operator, bool approved)', + 'event Transfer(address indexed from, address indexed to, uint256 indexed tokenId)', + 'function approve(address to, uint256 tokenId)', + 'function balanceOf(address owner) view returns (uint256)', + 'function getApproved(uint256 tokenId) view returns (address)', + 'function isApprovedForAll(address owner, address operator) view returns (bool)', + 'function mint()', + 'function name() view returns (string)', + 'function ownerOf(uint256 tokenId) view returns (address)', + 'function safeTransferFrom(address from, address to, uint256 tokenId)', + 'function safeTransferFrom(address from, address to, uint256 tokenId, bytes _data)', + 'function setApprovalForAll(address operator, bool approved)', + 'function supportsInterface(bytes4 interfaceId) view returns (bool)', + 'function symbol() view returns (string)', + 'function tokenURI(uint256 tokenId) pure returns (string)', + 'function totalSupply() view returns (uint256)', + 'function transferFrom(address from, address to, uint256 tokenId)', + ]), + viewOverloads: parseAbi([ + 'function foo() view returns (int8)', + 'function foo(address) view returns (string)', + 'function foo(address, address) view returns ((address foo, address bar))', + 'function bar() view returns (int8)', + ]), + writeOverloads: parseAbi([ + 'function foo() payable returns (int8)', + 'function foo(address) returns (string)', + 'function foo(address, address) returns ((address foo, address bar))', + 'function bar() payable returns (int8)', + ]), + bayc: parseAbi([ + 'constructor(string name, string symbol, uint256 maxNftSupply, uint256 saleStart)', + 'function mintApe(uint256 numberOfTokens) payable', + 'function reserveApes()', + 'function flipSaleState()', + 'function emergencySetStartingIndexBlock()', + 'function setStartingIndex()', + 'function setRevealTimestamp(uint256 revealTimeStamp)', + 'function setProvenanceHash(string provenanceHash)', + 'function setBaseURI(string baseURI)', + 'function startingIndex() view returns (uint256)', + 'function startingIndexBlock() view returns (uint256)', + 'function saleIsActive() view returns (bool)', + 'function maxApePurchase() view returns (uint256)', + 'function apePrice() view returns (uint256)', + 'function REVEAL_TIMESTAMP() view returns (uint256)', + 'function MAX_APES() view returns (uint256)', + 'function BAYC_PROVENANCE() view returns (string)', + 'function name() view returns (string)', + 'function symbol() view returns (string)', + 'function totalSupply() view returns (uint256)', + 'function balanceOf(address owner) view returns (uint256)', + 'function ownerOf(uint256 tokenId) view returns (address)', + 'function getApproved(uint256 tokenId) view returns (address)', + 'function isApprovedForAll(address owner, address operator) view returns (bool)', + 'function approve(address to, uint256 tokenId)', + 'function setApprovalForAll(address operator, bool approved)', + 'function safeTransferFrom(address from, address to, uint256 tokenId)', + 'function safeTransferFrom(address from, address to, uint256 tokenId, bytes _data)', + 'function tokenOfOwnerByIndex(address owner, uint256 index) view returns (uint256)', + 'function tokenByIndex(uint256 index) view returns (uint256)', + 'function tokenURI(uint256 tokenId) view returns (string)', + 'function supportsInterface(bytes4 interfaceId) view returns (bool)', + 'function transferFrom(address from, address to, uint256 tokenId)', + 'function renounceOwnership()', + 'function transferOwnership(address newOwner)', + 'function withdraw()', + ]), +} as const + +const mainnetAddress = { + mloot: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + shields: '0x0747118c9f44c7a23365b2476dcd05e03114c747', + usdc: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + usdcHolder: '0x5414d89a8bf7e99d732bc52f3e6a3ef461c0c078', + wagmigotchi: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + wagmiMintExample: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', +} as const + +export const address = { + ...mainnetAddress, + mainnet: mainnetAddress, + mainnet2: mainnetAddress, + optimism: { + usdc: '0x7f5c764cbc14f9669b88837ca1490cca17c31607', + }, +} as const satisfies Record & + Record> + +export const bytecode = { + bayc: '0x608060405260405180602001604052806000815250600b90805190602001906200002b92919062000484565b506000600f60006101000a81548160ff0219169083151502179055503480156200005457600080fd5b50604051620046d0380380620046d0833981810160405260808110156200007a57600080fd5b81019080805160405193929190846401000000008211156200009b57600080fd5b83820191506020820185811115620000b257600080fd5b8251866001820283011164010000000082111715620000d057600080fd5b8083526020830192505050908051906020019080838360005b8381101562000106578082015181840152602081019050620000e9565b50505050905090810190601f168015620001345780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200015857600080fd5b838201915060208201858111156200016f57600080fd5b82518660018202830111640100000000821117156200018d57600080fd5b8083526020830192505050908051906020019080838360005b83811015620001c3578082015181840152602081019050620001a6565b50505050905090810190601f168015620001f15780820380516001836020036101000a031916815260200191505b5060405260200180519060200190929190805190602001909291905050508383620002296301ffc9a760e01b6200037360201b60201c565b81600690805190602001906200024192919062000484565b5080600790805190602001906200025a92919062000484565b50620002736380ac58cd60e01b6200037360201b60201c565b6200028b635b5e139f60e01b6200037360201b60201c565b620002a363780e9d6360e01b6200037360201b60201c565b50506000620002b76200047c60201b60201c565b905080600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35081600e81905550620bdd808101601081905550505050506200052a565b63ffffffff60e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141562000410576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f4552433136353a20696e76616c696420696e746572666163652069640000000081525060200191505060405180910390fd5b6001600080837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600033905090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620004c757805160ff1916838001178555620004f8565b82800160010185558215620004f8579182015b82811115620004f7578251825591602001919060010190620004da565b5b5090506200050791906200050b565b5090565b5b80821115620005265760008160009055506001016200050c565b5090565b614196806200053a6000396000f3fe60806040526004361061021a5760003560e01c80636c0360eb11610123578063b0f67427116100ab578063e36d64981161006f578063e36d649814610ddf578063e985e9c514610e0a578063e986655014610e91578063eb8d244414610ea8578063f2fde38b14610ed55761021a565b8063b0f6742714610bac578063b88d4fde14610bc3578063bb8a16bd14610cd5578063c87b56dd14610d00578063cb774d4714610db45761021a565b80637d17fcbe116100f25780637d17fcbe14610a395780638da5cb5b14610a5057806395d89b4114610a91578063a22cb46514610b21578063a723533e14610b7e5761021a565b80636c0360eb1461090257806370a0823114610992578063715018a6146109f75780637a3f451e14610a0e5761021a565b80632f745c59116101a65780634f6ccce7116101755780634f6ccce7146106cb57806355f804b31461071a578063571dff3b146107e2578063607e20e31461080d5780636352211e1461089d5761021a565b80632f745c59146105b357806334918dfd146106225780633ccfd60b1461063957806342842e0e146106505761021a565b8063095ea7b3116101ed578063095ea7b3146103bf578063109695231461041a57806318160ddd146104e257806318e20a381461050d57806323b872dd146105385761021a565b8063018a2c371461021f57806301ffc9a71461025a57806306fdde03146102ca578063081812fc1461035a575b600080fd5b34801561022b57600080fd5b506102586004803603602081101561024257600080fd5b8101908080359060200190929190505050610f26565b005b34801561026657600080fd5b506102b26004803603602081101561027d57600080fd5b8101908080357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19169060200190929190505050610fdf565b60405180821515815260200191505060405180910390f35b3480156102d657600080fd5b506102df611046565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561031f578082015181840152602081019050610304565b50505050905090810190601f16801561034c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561036657600080fd5b506103936004803603602081101561037d57600080fd5b81019080803590602001909291905050506110e8565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156103cb57600080fd5b50610418600480360360408110156103e257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611183565b005b34801561042657600080fd5b506104e06004803603602081101561043d57600080fd5b810190808035906020019064010000000081111561045a57600080fd5b82018360208201111561046c57600080fd5b8035906020019184600183028401116401000000008311171561048e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506112c7565b005b3480156104ee57600080fd5b506104f7611390565b6040518082815260200191505060405180910390f35b34801561051957600080fd5b506105226113a1565b6040518082815260200191505060405180910390f35b34801561054457600080fd5b506105b16004803603606081101561055b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506113a7565b005b3480156105bf57600080fd5b5061060c600480360360408110156105d657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061141d565b6040518082815260200191505060405180910390f35b34801561062e57600080fd5b50610637611478565b005b34801561064557600080fd5b5061064e611553565b005b34801561065c57600080fd5b506106c96004803603606081101561067357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611651565b005b3480156106d757600080fd5b50610704600480360360208110156106ee57600080fd5b8101908080359060200190929190505050611671565b6040518082815260200191505060405180910390f35b34801561072657600080fd5b506107e06004803603602081101561073d57600080fd5b810190808035906020019064010000000081111561075a57600080fd5b82018360208201111561076c57600080fd5b8035906020019184600183028401116401000000008311171561078e57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050611694565b005b3480156107ee57600080fd5b506107f761174f565b6040518082815260200191505060405180910390f35b34801561081957600080fd5b50610822611754565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610862578082015181840152602081019050610847565b50505050905090810190601f16801561088f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156108a957600080fd5b506108d6600480360360208110156108c057600080fd5b81019080803590602001909291905050506117f2565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561090e57600080fd5b50610917611829565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561095757808201518184015260208101905061093c565b50505050905090810190601f1680156109845780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561099e57600080fd5b506109e1600480360360208110156109b557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506118cb565b6040518082815260200191505060405180910390f35b348015610a0357600080fd5b50610a0c6119a0565b005b348015610a1a57600080fd5b50610a23611b10565b6040518082815260200191505060405180910390f35b348015610a4557600080fd5b50610a4e611b1c565b005b348015610a5c57600080fd5b50610a65611c4c565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b348015610a9d57600080fd5b50610aa6611c76565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610ae6578082015181840152602081019050610acb565b50505050905090810190601f168015610b135780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b348015610b2d57600080fd5b50610b7c60048036036040811015610b4457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803515159060200190929190505050611d18565b005b610baa60048036036020811015610b9457600080fd5b8101908080359060200190929190505050611ece565b005b348015610bb857600080fd5b50610bc1612127565b005b348015610bcf57600080fd5b50610cd360048036036080811015610be657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190640100000000811115610c4d57600080fd5b820183602082011115610c5f57600080fd5b80359060200191846001830284011164010000000083111715610c8157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061220b565b005b348015610ce157600080fd5b50610cea612283565b6040518082815260200191505060405180910390f35b348015610d0c57600080fd5b50610d3960048036036020811015610d2357600080fd5b8101908080359060200190929190505050612289565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610d79578082015181840152602081019050610d5e565b50505050905090810190601f168015610da65780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b348015610dc057600080fd5b50610dc961255a565b6040518082815260200191505060405180910390f35b348015610deb57600080fd5b50610df4612560565b6040518082815260200191505060405180910390f35b348015610e1657600080fd5b50610e7960048036036040811015610e2d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612566565b60405180821515815260200191505060405180910390f35b348015610e9d57600080fd5b50610ea66125fa565b005b348015610eb457600080fd5b50610ebd612764565b60405180821515815260200191505060405180910390f35b348015610ee157600080fd5b50610f2460048036036020811015610ef857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612777565b005b610f2e61296c565b73ffffffffffffffffffffffffffffffffffffffff16610f4c611c4c565b73ffffffffffffffffffffffffffffffffffffffff1614610fd5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b8060108190555050565b6000806000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b606060068054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156110de5780601f106110b3576101008083540402835291602001916110de565b820191906000526020600020905b8154815290600101906020018083116110c157829003601f168201915b5050505050905090565b60006110f382612974565b611148576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c81526020018061408b602c913960400191505060405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061118e826117f2565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611215576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602181526020018061410f6021913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1661123461296c565b73ffffffffffffffffffffffffffffffffffffffff16148061126357506112628161125d61296c565b612566565b5b6112b8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526038815260200180613f956038913960400191505060405180910390fd5b6112c28383612991565b505050565b6112cf61296c565b73ffffffffffffffffffffffffffffffffffffffff166112ed611c4c565b73ffffffffffffffffffffffffffffffffffffffff1614611376576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b80600b908051906020019061138c929190613de6565b5050565b600061139c6002612a4a565b905090565b60105481565b6113b86113b261296c565b82612a5f565b61140d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260318152602001806141306031913960400191505060405180910390fd5b611418838383612b53565b505050565b600061147082600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612d9690919063ffffffff16565b905092915050565b61148061296c565b73ffffffffffffffffffffffffffffffffffffffff1661149e611c4c565b73ffffffffffffffffffffffffffffffffffffffff1614611527576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600f60009054906101000a900460ff1615600f60006101000a81548160ff021916908315150217905550565b61155b61296c565b73ffffffffffffffffffffffffffffffffffffffff16611579611c4c565b73ffffffffffffffffffffffffffffffffffffffff1614611602576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60004790503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f1935050505015801561164d573d6000803e3d6000fd5b5050565b61166c8383836040518060200160405280600081525061220b565b505050565b600080611688836002612db090919063ffffffff16565b50905080915050919050565b61169c61296c565b73ffffffffffffffffffffffffffffffffffffffff166116ba611c4c565b73ffffffffffffffffffffffffffffffffffffffff1614611743576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b61174c81612ddc565b50565b601481565b600b8054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156117ea5780601f106117bf576101008083540402835291602001916117ea565b820191906000526020600020905b8154815290600101906020018083116117cd57829003601f168201915b505050505081565b600061182282604051806060016040528060298152602001613ff7602991396002612df69092919063ffffffff16565b9050919050565b606060098054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156118c15780601f10611896576101008083540402835291602001916118c1565b820191906000526020600020905b8154815290600101906020018083116118a457829003601f168201915b5050505050905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611952576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180613fcd602a913960400191505060405180910390fd5b611999600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020612e15565b9050919050565b6119a861296c565b73ffffffffffffffffffffffffffffffffffffffff166119c6611c4c565b73ffffffffffffffffffffffffffffffffffffffff1614611a4f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b67011c37937e08000081565b611b2461296c565b73ffffffffffffffffffffffffffffffffffffffff16611b42611c4c565b73ffffffffffffffffffffffffffffffffffffffff1614611bcb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6000600d5414611c43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f5374617274696e6720696e64657820697320616c72656164792073657400000081525060200191505060405180910390fd5b43600c81905550565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060078054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611d0e5780601f10611ce357610100808354040283529160200191611d0e565b820191906000526020600020905b815481529060010190602001808311611cf157829003601f168201915b5050505050905090565b611d2061296c565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611dc1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f4552433732313a20617070726f766520746f2063616c6c65720000000000000081525060200191505060405180910390fd5b8060056000611dce61296c565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16611e7b61296c565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405180821515815260200191505060405180910390a35050565b600f60009054906101000a900460ff16611f50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f53616c65206d7573742062652061637469766520746f206d696e74204170650081525060200191505060405180910390fd5b6014811115611faa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180613f746021913960400191505060405180910390fd5b600e54611fc782611fb9611390565b612e2a90919063ffffffff16565b111561201e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260288152602001806140426028913960400191505060405180910390fd5b3461203a8267011c37937e080000612eb290919063ffffffff16565b11156120ae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45746865722076616c75652073656e74206973206e6f7420636f72726563740081525060200191505060405180910390fd5b60005b818110156120ef5760006120c3611390565b9050600e546120d0611390565b10156120e1576120e03382612f38565b5b5080806001019150506120b1565b506000600c541480156121175750600e54612108611390565b148061211657506010544210155b5b156121245743600c819055505b50565b61212f61296c565b73ffffffffffffffffffffffffffffffffffffffff1661214d611c4c565b73ffffffffffffffffffffffffffffffffffffffff16146121d6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60006121e0611390565b905060005b601e811015612207576121fa33828401612f38565b80806001019150506121e5565b5050565b61221c61221661296c565b83612a5f565b612271576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260318152602001806141306031913960400191505060405180910390fd5b61227d84848484612f56565b50505050565b600e5481565b606061229482612974565b6122e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f8152602001806140e0602f913960400191505060405180910390fd5b6060600860008481526020019081526020016000208054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156123925780601f1061236757610100808354040283529160200191612392565b820191906000526020600020905b81548152906001019060200180831161237557829003601f168201915b5050505050905060606123a3611829565b90506000815114156123b9578192505050612555565b60008251111561248a5780826040516020018083805190602001908083835b602083106123fb57805182526020820191506020810190506020830392506123d8565b6001836020036101000a03801982511681845116808217855250505050505090500182805190602001908083835b6020831061244c5780518252602082019150602081019050602083039250612429565b6001836020036101000a0380198251168184511680821785525050505050509050019250505060405160208183030381529060405292505050612555565b8061249485612fc8565b6040516020018083805190602001908083835b602083106124ca57805182526020820191506020810190506020830392506124a7565b6001836020036101000a03801982511681845116808217855250505050505090500182805190602001908083835b6020831061251b57805182526020820191506020810190506020830392506124f8565b6001836020036101000a03801982511681845116808217855250505050505090500192505050604051602081830303815290604052925050505b919050565b600d5481565b600c5481565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6000600d5414612672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f5374617274696e6720696e64657820697320616c72656164792073657400000081525060200191505060405180910390fd5b6000600c5414156126eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f5374617274696e6720696e64657820626c6f636b206d7573742062652073657481525060200191505060405180910390fd5b600e54600c544060001c816126fc57fe5b06600d8190555060ff61271a600c544361310f90919063ffffffff16565b111561273a57600e54600143034060001c8161273257fe5b06600d819055505b6000600d5414156127625761275b6001600d54612e2a90919063ffffffff16565b600d819055505b565b600f60009054906101000a900460ff1681565b61277f61296c565b73ffffffffffffffffffffffffffffffffffffffff1661279d611c4c565b73ffffffffffffffffffffffffffffffffffffffff1614612826576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156128ac576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180613ed86026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600033905090565b600061298a82600261319290919063ffffffff16565b9050919050565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16612a04836117f2565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000612a58826000016131ac565b9050919050565b6000612a6a82612974565b612abf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180613f48602c913960400191505060405180910390fd5b6000612aca836117f2565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612b3957508373ffffffffffffffffffffffffffffffffffffffff16612b21846110e8565b73ffffffffffffffffffffffffffffffffffffffff16145b80612b4a5750612b498185612566565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16612b73826117f2565b73ffffffffffffffffffffffffffffffffffffffff1614612bdf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260298152602001806140b76029913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612c65576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180613efe6024913960400191505060405180910390fd5b612c708383836131bd565b612c7b600082612991565b612ccc81600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206131c290919063ffffffff16565b50612d1e81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206131dc90919063ffffffff16565b50612d35818360026131f69092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6000612da5836000018361322b565b60001c905092915050565b600080600080612dc386600001866132ae565b915091508160001c8160001c9350935050509250929050565b8060099080519060200190612df2929190613de6565b5050565b6000612e09846000018460001b84613347565b60001c90509392505050565b6000612e238260000161343d565b9050919050565b600080828401905083811015612ea8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600080831415612ec55760009050612f32565b6000828402905082848281612ed657fe5b0414612f2d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602181526020018061406a6021913960400191505060405180910390fd5b809150505b92915050565b612f5282826040518060200160405280600081525061344e565b5050565b612f61848484612b53565b612f6d848484846134bf565b612fc2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526032815260200180613ea66032913960400191505060405180910390fd5b50505050565b60606000821415613010576040518060400160405280600181526020017f3000000000000000000000000000000000000000000000000000000000000000815250905061310a565b600082905060005b6000821461303a578080600101915050600a828161303257fe5b049150613018565b60608167ffffffffffffffff8111801561305357600080fd5b506040519080825280601f01601f1916602001820160405280156130865781602001600182028036833780820191505090505b50905060006001830390508593505b6000841461310257600a84816130a757fe5b0660300160f81b828280600190039350815181106130c157fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a84816130fa57fe5b049350613095565b819450505050505b919050565b600082821115613187576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060200191505060405180910390fd5b818303905092915050565b60006131a4836000018360001b6136d8565b905092915050565b600081600001805490509050919050565b505050565b60006131d4836000018360001b6136fb565b905092915050565b60006131ee836000018360001b6137e3565b905092915050565b6000613222846000018460001b8473ffffffffffffffffffffffffffffffffffffffff1660001b613853565b90509392505050565b60008183600001805490501161328c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180613e846022913960400191505060405180910390fd5b82600001828154811061329b57fe5b9060005260206000200154905092915050565b60008082846000018054905011613310576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806140206022913960400191505060405180910390fd5b600084600001848154811061332157fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b6000808460010160008581526020019081526020016000205490506000811415839061340e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156133d35780820151818401526020810190506133b8565b50505050905090810190601f1680156134005780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5084600001600182038154811061342157fe5b9060005260206000209060020201600101549150509392505050565b600081600001805490509050919050565b613458838361392f565b61346560008484846134bf565b6134ba576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526032815260200180613ea66032913960400191505060405180910390fd5b505050565b60006134e08473ffffffffffffffffffffffffffffffffffffffff16613b23565b6134ed57600190506136d0565b606061365763150b7a0260e01b61350261296c565b888787604051602401808573ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff16815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561358657808201518184015260208101905061356b565b50505050905090810190601f1680156135b35780820380516001836020036101000a031916815260200191505b5095505050505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051806060016040528060328152602001613ea6603291398773ffffffffffffffffffffffffffffffffffffffff16613b369092919063ffffffff16565b9050600081806020019051602081101561367057600080fd5b8101908080519060200190929190505050905063150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614925050505b949350505050565b600080836001016000848152602001908152602001600020541415905092915050565b600080836001016000848152602001908152602001600020549050600081146137d7576000600182039050600060018660000180549050039050600086600001828154811061374657fe5b906000526020600020015490508087600001848154811061376357fe5b906000526020600020018190555060018301876001016000838152602001908152602001600020819055508660000180548061379b57fe5b600190038181906000526020600020016000905590558660010160008781526020019081526020016000206000905560019450505050506137dd565b60009150505b92915050565b60006137ef8383613b4e565b61384857826000018290806001815401808255809150506001900390600052602060002001600090919091909150558260000180549050836001016000848152602001908152602001600020819055506001905061384d565b600090505b92915050565b60008084600101600085815260200190815260200160002054905060008114156138fa57846000016040518060400160405280868152602001858152509080600181540180825580915050600190039060005260206000209060020201600090919091909150600082015181600001556020820151816001015550508460000180549050856001016000868152602001908152602001600020819055506001915050613928565b8285600001600183038154811061390d57fe5b90600052602060002090600202016001018190555060009150505b9392505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156139d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4552433732313a206d696e7420746f20746865207a65726f206164647265737381525060200191505060405180910390fd5b6139db81612974565b15613a4e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000081525060200191505060405180910390fd5b613a5a600083836131bd565b613aab81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206131dc90919063ffffffff16565b50613ac2818360026131f69092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b600080823b905060008111915050919050565b6060613b458484600085613b71565b90509392505050565b600080836001016000848152602001908152602001600020541415905092915050565b606082471015613bcc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180613f226026913960400191505060405180910390fd5b613bd585613b23565b613c47576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081525060200191505060405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b60208310613c975780518252602082019150602081019050602083039250613c74565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114613cf9576040519150601f19603f3d011682016040523d82523d6000602084013e613cfe565b606091505b5091509150613d0e828286613d1a565b92505050949350505050565b60608315613d2a57829050613ddf565b600083511115613d3d5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613da4578082015181840152602081019050613d89565b50505050905090810190601f168015613dd15780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b9392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10613e2757805160ff1916838001178555613e55565b82800160010185558215613e55579182015b82811115613e54578251825591602001919060010190613e39565b5b509050613e629190613e66565b5090565b5b80821115613e7f576000816000905550600101613e67565b509056fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e64734552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734552433732313a207472616e7366657220746f20746865207a65726f2061646472657373416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c4552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e43616e206f6e6c79206d696e7420323020746f6b656e7320617420612074696d654552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c4552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e6473507572636861736520776f756c6420657863656564206d617820737570706c79206f662041706573536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e4552433732314d657461646174613a2055524920717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76616c20746f2063757272656e74206f776e65724552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564a2646970667358221220b0e64d1fa6c4dbeb9c6f54607d7e1996943fe27624a80652f57b53fda084621b64736f6c63430007000033000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000002710000000000000000000000000000000000000000000000000000000006080e6d70000000000000000000000000000000000000000000000000000000000000011426f7265644170655961636874436c756200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044241594300000000000000000000000000000000000000000000000000000000', + wagmiMintExample: + '0x608060405260006007553480156200001657600080fd5b50604051806040016040528060058152602001647761676d6960d81b815250604051806040016040528060058152602001645741474d4960d81b81525081600090805190602001906200006b9291906200008a565b508051620000819060019060208401906200008a565b5050506200016c565b828054620000989062000130565b90600052602060002090601f016020900481019282620000bc576000855562000107565b82601f10620000d757805160ff191683800117855562000107565b8280016001018555821562000107579182015b8281111562000107578251825591602001919060010190620000ea565b506200011592915062000119565b5090565b5b808211156200011557600081556001016200011a565b600181811c908216806200014557607f821691505b6020821081036200016657634e487b7160e01b600052602260045260246000fd5b50919050565b6128c2806200017c6000396000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c80636352211e11610097578063a22cb46511610066578063a22cb46514610215578063b88d4fde14610228578063c87b56dd1461023b578063e985e9c51461024e57600080fd5b80636352211e146101d457806370a08231146101e757806395d89b41146101fa578063a0712d681461020257600080fd5b80631249c58b116100d35780631249c58b1461018f57806318160ddd1461019757806323b872dd146101ae57806342842e0e146101c157600080fd5b806301ffc9a71461010557806306fdde031461012d578063081812fc14610142578063095ea7b31461017a575b600080fd5b61011861011336600461178f565b610297565b60405190151581526020015b60405180910390f35b61013561037c565b6040516101249190611829565b61015561015036600461183c565b61040e565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610124565b61018d61018836600461187e565b6104d3565b005b61018d61062b565b6101a060065481565b604051908152602001610124565b61018d6101bc3660046118a8565b61067d565b61018d6101cf3660046118a8565b610704565b6101556101e236600461183c565b61071f565b6101a06101f53660046118e4565b6107b7565b61013561086b565b61018d61021036600461183c565b61087a565b61018d6102233660046118ff565b610902565b61018d61023636600461196a565b610911565b61013561024936600461183c565b61099f565b61011861025c366004611a64565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260056020908152604080832093909416825291909152205460ff1690565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd00000000000000000000000000000000000000000000000000000000148061032a57507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b8061037657507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b60606000805461038b90611a97565b80601f01602080910402602001604051908101604052809291908181526020018280546103b790611a97565b80156104045780601f106103d957610100808354040283529160200191610404565b820191906000526020600020905b8154815290600101906020018083116103e757829003601f168201915b5050505050905090565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff166104aa5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e000000000000000000000000000000000000000060648201526084015b60405180910390fd5b5060009081526004602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60006104de8261071f565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036105815760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f720000000000000000000000000000000000000000000000000000000000000060648201526084016104a1565b3373ffffffffffffffffffffffffffffffffffffffff821614806105aa57506105aa813361025c565b61061c5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c000000000000000060648201526084016104a1565b6106268383610b07565b505050565b6007545b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff16156106615760010161062f565b61066b3382610ba7565b60068054600190810190915501600755565b6106873382610bc1565b6106f95760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656400000000000000000000000000000060648201526084016104a1565b610626838383610d17565b61062683838360405180602001604052806000815250610911565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff16806103765760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201527f656e7420746f6b656e000000000000000000000000000000000000000000000060648201526084016104a1565b600073ffffffffffffffffffffffffffffffffffffffff82166108425760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a6560448201527f726f20616464726573730000000000000000000000000000000000000000000060648201526084016104a1565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205490565b60606001805461038b90611a97565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff16156108ec5760405162461bcd60e51b815260206004820152601160248201527f546f6b656e2049442069732074616b656e00000000000000000000000000000060448201526064016104a1565b6108f63382610ba7565b50600680546001019055565b61090d338383610f4a565b5050565b61091b3383610bc1565b61098d5760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656400000000000000000000000000000060648201526084016104a1565b6109998484848461105d565b50505050565b6040517f666f726567726f756e64000000000000000000000000000000000000000000006020820152602a810182905260609060009061016890604a016040516020818303038152906040528051906020012060001c6109ff9190611b19565b6040517f6261636b67726f756e64000000000000000000000000000000000000000000006020820152602a810185905290915060009061016890604a016040516020818303038152906040528051906020012060001c610a5f9190611b19565b90506000610aba610a6f866110e6565b610aa9610a7b866110e6565b610a84866110e6565b604051602001610a95929190611b2d565b60405160208183030381529060405261121b565b604051602001610a959291906125ba565b9050600081604051602001610acf919061268b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529695505050505050565b600081815260046020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091558190610b618261071f565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b61090d82826040518060200160405280600081525061136e565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff16610c585760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e000000000000000000000000000000000000000060648201526084016104a1565b6000610c638361071f565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480610cd1575073ffffffffffffffffffffffffffffffffffffffff80821660009081526005602090815260408083209388168352929052205460ff165b80610d0f57508373ffffffffffffffffffffffffffffffffffffffff16610cf78461040e565b73ffffffffffffffffffffffffffffffffffffffff16145b949350505050565b8273ffffffffffffffffffffffffffffffffffffffff16610d378261071f565b73ffffffffffffffffffffffffffffffffffffffff1614610dc05760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201527f6f776e657200000000000000000000000000000000000000000000000000000060648201526084016104a1565b73ffffffffffffffffffffffffffffffffffffffff8216610e485760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016104a1565b610e53600082610b07565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120805460019290610e899084906126ff565b909155505073ffffffffffffffffffffffffffffffffffffffff82166000908152600360205260408120805460019290610ec4908490612716565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610fc55760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016104a1565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526005602090815260408083209487168084529482529182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b611068848484610d17565b611074848484846113f7565b6109995760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016104a1565b60608160000361112957505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611153578061113d8161272e565b915061114c9050600a83612766565b915061112d565b60008167ffffffffffffffff81111561116e5761116e61193b565b6040519080825280601f01601f191660200182016040528015611198576020820181803683370190505b5090505b8415610d0f576111ad6001836126ff565b91506111ba600a86611b19565b6111c5906030612716565b60f81b8183815181106111da576111da61277a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611214600a86612766565b945061119c565b6060815160000361123a57505060408051602081019091526000815290565b600060405180606001604052806040815260200161284d60409139905060006003845160026112699190612716565b6112739190612766565b61127e9060046127a9565b67ffffffffffffffff8111156112965761129661193b565b6040519080825280601f01601f1916602001820160405280156112c0576020820181803683370190505b509050600182016020820185865187015b8082101561132c576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f81168501518453506001830192506112d1565b5050600386510660018114611348576002811461135b57611363565b603d6001830353603d6002830353611363565b603d60018303535b509195945050505050565b61137883836115d0565b61138560008484846113f7565b6106265760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016104a1565b600073ffffffffffffffffffffffffffffffffffffffff84163b156115c5576040517f150b7a0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063150b7a029061146e9033908990889088906004016127e6565b6020604051808303816000875af19250505080156114c7575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526114c49181019061282f565b60015b61157a573d8080156114f5576040519150601f19603f3d011682016040523d82523d6000602084013e6114fa565b606091505b5080516000036115725760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016104a1565b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a0200000000000000000000000000000000000000000000000000000000149050610d0f565b506001949350505050565b73ffffffffffffffffffffffffffffffffffffffff82166116335760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016104a1565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff16156116a55760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016104a1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526003602052604081208054600192906116db908490612716565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b7fffffffff000000000000000000000000000000000000000000000000000000008116811461178c57600080fd5b50565b6000602082840312156117a157600080fd5b81356117ac8161175e565b9392505050565b60005b838110156117ce5781810151838201526020016117b6565b838111156109995750506000910152565b600081518084526117f78160208601602086016117b3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006117ac60208301846117df565b60006020828403121561184e57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461187957600080fd5b919050565b6000806040838503121561189157600080fd5b61189a83611855565b946020939093013593505050565b6000806000606084860312156118bd57600080fd5b6118c684611855565b92506118d460208501611855565b9150604084013590509250925092565b6000602082840312156118f657600080fd5b6117ac82611855565b6000806040838503121561191257600080fd5b61191b83611855565b91506020830135801515811461193057600080fd5b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000806080858703121561198057600080fd5b61198985611855565b935061199760208601611855565b925060408501359150606085013567ffffffffffffffff808211156119bb57600080fd5b818701915087601f8301126119cf57600080fd5b8135818111156119e1576119e161193b565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715611a2757611a2761193b565b816040528281528a6020848701011115611a4057600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b60008060408385031215611a7757600080fd5b611a8083611855565b9150611a8e60208401611855565b90509250929050565b600181811c90821680611aab57607f821691505b602082108103611ae4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611b2857611b28611aea565b500690565b7f3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323081527f30302f737667222077696474683d223130323422206865696768743d2231303260208201527f34222066696c6c3d226e6f6e65223e3c706174682066696c6c3d2268736c2800604082015260008351611bb181605f8501602088016117b3565b7f2c20313030252c20313025292220643d224d3020306831303234763130323448605f918401918201527f307a22202f3e3c672066696c6c3d2268736c2800000000000000000000000000607f8201528351611c148160928401602088016117b3565b7f2c20313030252c2039302529223e3c7061746820643d224d393033203433372e609292909101918201527f35633020392e3131332d372e3338382031362e352d31362e352031362e35732d60b28201527f31362e352d372e3338372d31362e352d31362e3520372e3338382d31362e352060d28201527f31362e352d31362e352031362e3520372e3338372031362e352031362e357a4d60f28201527f3639382e3532392035363663362e39323120302031322e35332d352e353936206101128201527f31322e35332d31322e35762d353063302d362e39303420352e3630392d31322e6101328201527f352031322e3532392d31322e356832352e30353963362e393220302031322e356101528201527f323920352e3539362031322e3532392031322e35763530633020362e393034206101728201527f352e3630392031322e352031322e35332031322e357331322e3532392d352e356101928201527f39362031322e3532392d31322e35762d353063302d362e39303420352e3630396101b28201527f2d31322e352031322e35332d31322e356832352e30353963362e3932203020316101d28201527f322e35323920352e3539362031322e3532392031322e35763530633020362e396101f28201527f303420352e3630392031322e352031322e3532392031322e356833372e3538396102128201527f63362e393220302031322e3532392d352e3539362031322e3532392d31322e356102328201527f762d373563302d362e3930342d352e3630392d31322e352d31322e3532392d316102528201527f322e35732d31322e353320352e3539362d31322e35332031322e357635362e326102728201527f3561362e32363420362e3236342030203120312d31322e3532392030563437386102928201527f2e3563302d362e3930342d352e3630392d31322e352d31322e35332d31322e356102b28201527f483639382e353239632d362e393220302d31322e35323920352e3539362d31326102d28201527f2e3532392031322e35763735633020362e39303420352e3630392031322e35206102f28201527f31322e3532392031322e357a22202f3e3c7061746820643d224d3135372e36356103128201527f3520353431632d362e39333220302d31322e3535322d352e3539362d31322e356103328201527f35322d31322e35762d353063302d362e3930342d352e3631392d31322e352d316103528201527f322e3535312d31322e3553313230203437312e35393620313230203437382e356103728201527f763735633020362e39303420352e36322031322e352031322e3535322031322e6103928201527f35683135302e363263362e39333320302031322e3535322d352e3539362031326103b28201527f2e3535322d31322e35762d353063302d362e39303420352e3631392d31322e356103d28201527f2031322e3535322d31322e35683134342e33343563332e343635203020362e326103f28201527f373620322e37393820362e32373620362e3235732d322e38313120362e32352d6104128201527f362e32373620362e3235483332302e383238632d362e39333320302d31322e356104328201527f353220352e3539362d31322e3535322031322e357633372e35633020362e39306104528201527f3420352e3631392031322e352031322e3535322031322e35683135302e3632636104728201527f362e39333320302031322e3535322d352e3539362031322e3535322d31322e356104928201527f762d373563302d362e3930342d352e3631392d31322e352d31322e3535322d316104b28201527f322e35483238332e313732632d362e39333220302d31322e35353120352e35396104d28201527f362d31322e3535312031322e35763530633020362e3930342d352e36313920316104f28201527f322e352d31322e3535322031322e35682d32352e313033632d362e39333320306105128201527f2d31322e3535322d352e3539362d31322e3535322d31322e35762d353063302d6105328201527f362e3930342d352e36322d31322e352d31322e3535322d31322e35732d31322e6105528201527f35353220352e3539362d31322e3535322031322e35763530633020362e3930346105728201527f2d352e3631392031322e352d31322e3535312031322e35682d32352e3130347a6105928201527f6d3330312e3234322d362e3235633020332e3435322d322e38313120362e32356105b28201527f2d362e32373620362e3235483333392e363535632d332e34363520302d362e326105d28201527f37362d322e3739382d362e3237362d362e323573322e3831312d362e323520366105f28201527f2e3237362d362e3235683131322e39363663332e343635203020362e323736206106128201527f322e37393820362e32373620362e32357a4d343937203535332e3831386330206106328201527f362e39323920352e3632382031322e3534362031322e3537312031322e3534366106528201527f6831333261362e323820362e323820302030203120362e32383620362e3237326106728201527f20362e323820362e32382030203020312d362e32383620362e323733682d31336106928201527f32632d362e39343320302d31322e35373120352e3631362d31322e35373120316106b28201527f322e3534364131322e35362031322e3536203020302030203530392e353731206106d28201527f363034683135302e38353863362e39343320302031322e3537312d352e3631366106f28201527f2031322e3537312d31322e353435762d3131322e393163302d362e3932382d356107128201527f2e3632382d31322e3534352d31322e3537312d31322e353435483530392e35376107328201527f31632d362e39343320302d31322e35373120352e3631372d31322e35373120316107528201527f322e3534357637352e3237337a6d33372e3731342d36322e373237632d362e396107728201527f343320302d31322e35373120352e3631372d31322e3537312031322e353435766107928201527f32352e303931633020362e39323920352e3632382031322e3534362031322e356107b28201527f37312031322e353436683130302e35373263362e39343320302031322e3537316107d28201527f2d352e3631372031322e3537312d31322e353436762d32352e30393163302d366107f28201527f2e3932382d352e3632382d31322e3534352d31322e3537312d31322e353435486108128201527f3533342e3731347a222066696c6c2d72756c653d226576656e6f646422202f3e6108328201527f3c2f673e3c2f7376673e0000000000000000000000000000000000000000000061085282015261085c01949350505050565b7f7b226e616d65223a20227761676d6920230000000000000000000000000000008152600083516125f28160118501602088016117b3565b7f222c2022696d616765223a2022646174613a696d6167652f7376672b786d6c3b6011918401918201527f6261736536342c00000000000000000000000000000000000000000000000000603182015283516126558160388401602088016117b3565b7f227d00000000000000000000000000000000000000000000000000000000000060389290910191820152603a01949350505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c0000008152600082516126c381601d8501602087016117b3565b91909101601d0192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015612711576127116126d0565b500390565b60008219821115612729576127296126d0565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361275f5761275f6126d0565b5060010190565b60008261277557612775611aea565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156127e1576127e16126d0565b500290565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261282560808301846117df565b9695505050505050565b60006020828403121561284157600080fd5b81516117ac8161175e56fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa26469706673582212201665a4f9111990d7529375848d3fd02c0121091a940da59e763eba826e7b077064736f6c634300080d0033', +} as const diff --git a/wagmi-project/packages/test/src/exports/index.test-d.ts b/wagmi-project/packages/test/src/exports/index.test-d.ts new file mode 100644 index 0000000000..b056d56358 --- /dev/null +++ b/wagmi-project/packages/test/src/exports/index.test-d.ts @@ -0,0 +1,4 @@ +import { expectTypeOf } from 'vitest' + +// noop test because vitest typecheck fails unless each workspace project has type test +expectTypeOf(1).toEqualTypeOf() diff --git a/wagmi-project/packages/test/src/exports/index.test.ts b/wagmi-project/packages/test/src/exports/index.test.ts new file mode 100644 index 0000000000..2a44ddbf8f --- /dev/null +++ b/wagmi-project/packages/test/src/exports/index.test.ts @@ -0,0 +1,29 @@ +import { expect, test } from 'vitest' + +import * as react from './index.js' + +test('exports', () => { + expect(Object.keys(react)).toMatchInlineSnapshot(` + [ + "chain", + "mainnet", + "mainnet2", + "optimism", + "abi", + "accounts", + "address", + "bytecode", + "privateKey", + "typedData", + "walletConnectProjectId", + "testClient", + "mainnetTestClient", + "mainnet2TestClient", + "optimismTestClient", + "config", + "addressRegex", + "transactionHashRegex", + "wait", + ] + `) +}) diff --git a/wagmi-project/packages/test/src/exports/index.ts b/wagmi-project/packages/test/src/exports/index.ts new file mode 100644 index 0000000000..5844aeac01 --- /dev/null +++ b/wagmi-project/packages/test/src/exports/index.ts @@ -0,0 +1,25 @@ +// biome-ignore lint/performance/noBarrelFile: entrypoint module +export { chain, mainnet, mainnet2, optimism } from '../chains.js' + +export { + abi, + accounts, + address, + bytecode, + privateKey, + typedData, + walletConnectProjectId, +} from '../constants.js' + +export { + testClient, + mainnetTestClient, + mainnet2TestClient, + optimismTestClient, +} from '../clients.js' + +export { config } from '../config.js' + +export { addressRegex, transactionHashRegex } from '../regex.js' + +export { wait } from '../utils.js' diff --git a/wagmi-project/packages/test/src/exports/react.ts b/wagmi-project/packages/test/src/exports/react.ts new file mode 100644 index 0000000000..f9dfe5c4b4 --- /dev/null +++ b/wagmi-project/packages/test/src/exports/react.ts @@ -0,0 +1,63 @@ +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { + type RenderHookOptions, + type RenderHookResult, + type RenderOptions, + type RenderResult, + render as rtl_render, + renderHook as rtl_renderHook, + waitFor as rtl_waitFor, + type waitForOptions, +} from '@testing-library/react' +import { type ReactElement, createElement } from 'react' +import { WagmiProvider } from 'wagmi' + +import { config } from '../config.js' + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +export { act, cleanup } from '@testing-library/react' + +export const queryClient = new QueryClient() + +export function createWrapper>( + Wrapper: TComponent, + props: Parameters[0], +) { + type Props = { children?: React.ReactNode | undefined } + return function CreatedWrapper({ children }: Props) { + return createElement( + Wrapper, + props, + createElement(QueryClientProvider, { client: queryClient }, children), + ) + } +} + +export function renderHook( + render: (props: Props) => Result, + options?: RenderHookOptions | undefined, +): RenderHookResult { + queryClient.clear() + return rtl_renderHook(render, { + wrapper: createWrapper(WagmiProvider, { config, reconnectOnMount: false }), + ...options, + }) +} + +export function render( + element: ReactElement, + options?: RenderOptions | undefined, +): RenderResult { + queryClient.clear() + return rtl_render(element, { + wrapper: createWrapper(WagmiProvider, { config, reconnectOnMount: false }), + ...options, + }) +} + +export function waitFor( + callback: () => Promise | T, + options?: waitForOptions | undefined, +): Promise { + return rtl_waitFor(callback, { timeout: 10_000, ...options }) +} diff --git a/wagmi-project/packages/test/src/exports/vue.ts b/wagmi-project/packages/test/src/exports/vue.ts new file mode 100644 index 0000000000..ac49b17a31 --- /dev/null +++ b/wagmi-project/packages/test/src/exports/vue.ts @@ -0,0 +1,66 @@ +import { VueQueryPlugin } from '@tanstack/vue-query' +import { WagmiPlugin } from '@wagmi/vue' +import { type App, type Ref, createApp, watch } from 'vue' + +import { config } from '../config.js' + +export type RenderComposableReturnType unknown> = [ + ReturnType, + App, +] + +export function renderComposable unknown>( + composable: composable, + options: { attach?: (app: App) => void } | undefined = { + attach(app) { + app + .use(WagmiPlugin, { + config, + reconnectOnMount: false, + }) + .use(VueQueryPlugin, {}) + }, + }, +): RenderComposableReturnType { + let result = undefined + const app = createApp({ + setup() { + result = composable() + return () => {} + }, + }) + + options.attach?.(app) + app.mount(document.createElement('div')) + + return [result, app] as unknown as RenderComposableReturnType +} + +export type WaitForOptions = { + timeout?: number +} + +export function waitFor( + ref: ref, + predicate: (value: ref['value']) => boolean = (value) => value, + options: WaitForOptions = {}, +) { + const { timeout = 10_000 } = options + return new Promise((resolve, reject) => { + const timer = timeout + ? setTimeout(() => { + _unwatch() + if (predicate(ref.value)) resolve() + else reject(new Error(`\`waitFor\` timed out in ${timeout}ms.`)) + }, timeout) + : undefined + + const _unwatch = watch(ref, (value) => { + if (predicate(value)) { + if (timer) clearTimeout(timer) + _unwatch() + resolve() + } + }) + }) +} diff --git a/wagmi-project/packages/test/src/globalSetup.ts b/wagmi-project/packages/test/src/globalSetup.ts new file mode 100644 index 0000000000..f8248e8390 --- /dev/null +++ b/wagmi-project/packages/test/src/globalSetup.ts @@ -0,0 +1,26 @@ +import { createServer } from 'prool' +import { anvil } from 'prool/instances' + +import { chain as chainLookup } from './chains.js' + +export default async function () { + const promises = [] + for (const chain of Object.values(chainLookup)) { + promises.push( + createServer({ + instance: anvil({ + chainId: chain.id, + forkUrl: chain.fork.url, + forkBlockNumber: chain.fork.blockNumber, + noMining: true, + }), + port: chain.port, + }).start(), + ) + } + const results = await Promise.all(promises) + + return async () => { + await Promise.all(results.map((stop) => stop())) + } +} diff --git a/wagmi-project/packages/test/src/regex.ts b/wagmi-project/packages/test/src/regex.ts new file mode 100644 index 0000000000..5998ea513e --- /dev/null +++ b/wagmi-project/packages/test/src/regex.ts @@ -0,0 +1,3 @@ +export const addressRegex = /^0x([A-Fa-f0-9]{40})$/ + +export const transactionHashRegex = /^0x([A-Fa-f0-9]{64})$/ diff --git a/wagmi-project/packages/test/src/setup.ts b/wagmi-project/packages/test/src/setup.ts new file mode 100644 index 0000000000..1a41b7a6ed --- /dev/null +++ b/wagmi-project/packages/test/src/setup.ts @@ -0,0 +1,8 @@ +import { afterAll } from 'vitest' + +import { testClient } from './clients.js' + +afterAll(async () => { + // If you are using a fork, you can reset your anvil instance to the initial fork block. + await Promise.all(Object.values(testClient).map((client) => client.restart())) +}) diff --git a/wagmi-project/packages/test/src/utils.ts b/wagmi-project/packages/test/src/utils.ts new file mode 100644 index 0000000000..85afe15c4b --- /dev/null +++ b/wagmi-project/packages/test/src/utils.ts @@ -0,0 +1,25 @@ +const pool = + Number(process.env.VITEST_POOL_ID ?? 1) + Math.floor(Math.random() * 10000) + +export function getRpcUrls({ port }: { port: number }) { + return { + port, + rpcUrls: { + // These rpc urls are automatically used in the transports. + default: { + // Note how we append the worker id to the local rpc urls. + http: [`http://127.0.0.1:${port}/${pool}`], + webSocket: [`ws://127.0.0.1:${port}/${pool}`], + }, + public: { + // Note how we append the worker id to the local rpc urls. + http: [`http://127.0.0.1:${port}/${pool}`], + webSocket: [`ws://127.0.0.1:${port}/${pool}`], + }, + }, + } as const +} + +export async function wait(time: number) { + return new Promise((res) => setTimeout(res, time)) +} diff --git a/wagmi-project/packages/test/tsconfig.build.json b/wagmi-project/packages/test/tsconfig.build.json new file mode 100644 index 0000000000..fbed2b1036 --- /dev/null +++ b/wagmi-project/packages/test/tsconfig.build.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.base.json", + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.test.ts", "src/**/*.test-d.ts"], + "compilerOptions": { + "sourceMap": true + } +} diff --git a/wagmi-project/packages/test/tsconfig.json b/wagmi-project/packages/test/tsconfig.json new file mode 100644 index 0000000000..bd33919ac3 --- /dev/null +++ b/wagmi-project/packages/test/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "./tsconfig.build.json", + "include": ["src/**/*.ts"], + "exclude": [] +} diff --git a/wagmi-project/packages/vue/CHANGELOG.md b/wagmi-project/packages/vue/CHANGELOG.md new file mode 100644 index 0000000000..324b962b29 --- /dev/null +++ b/wagmi-project/packages/vue/CHANGELOG.md @@ -0,0 +1,706 @@ +# @wagmi/vue + +## 0.1.20 + +### Patch Changes + +- Updated dependencies [[`42b1fed58e9ac09da0f8ebf3e9271f98a707aaac`](https://github.com/wevm/wagmi/commit/42b1fed58e9ac09da0f8ebf3e9271f98a707aaac)]: + - @wagmi/connectors@5.8.3 + +## 0.1.19 + +### Patch Changes + +- Updated dependencies [[`29297a48af72b537173d948ccd2fe37d39914c66`](https://github.com/wevm/wagmi/commit/29297a48af72b537173d948ccd2fe37d39914c66), [`07370106d5fb6b8fe300992d93abf25b3d0eaf57`](https://github.com/wevm/wagmi/commit/07370106d5fb6b8fe300992d93abf25b3d0eaf57)]: + - @wagmi/core@2.17.2 + - @wagmi/connectors@5.8.2 + +## 0.1.18 + +### Patch Changes + +- Updated dependencies [[`01f64e64fa4f85cdd30023903f972f4f9023681f`](https://github.com/wevm/wagmi/commit/01f64e64fa4f85cdd30023903f972f4f9023681f)]: + - @wagmi/core@2.17.1 + - @wagmi/connectors@5.8.1 + +## 0.1.17 + +### Patch Changes + +- Updated dependencies [[`cc5517ff6880bb630f1b201930acc20dd1a0b451`](https://github.com/wevm/wagmi/commit/cc5517ff6880bb630f1b201930acc20dd1a0b451)]: + - @wagmi/connectors@5.8.0 + +## 0.1.16 + +### Patch Changes + +- Updated dependencies [[`88427b2bcd13ec375ef519e9ad1ccffef9f02a7b`](https://github.com/wevm/wagmi/commit/88427b2bcd13ec375ef519e9ad1ccffef9f02a7b), [`799ee4d4b23c2ecd64e3f3668e67634e81939719`](https://github.com/wevm/wagmi/commit/799ee4d4b23c2ecd64e3f3668e67634e81939719), [`3f8b2edc4f237cccff1009bcef03d51ca27a7324`](https://github.com/wevm/wagmi/commit/3f8b2edc4f237cccff1009bcef03d51ca27a7324)]: + - @wagmi/connectors@6.0.0 + - @wagmi/core@2.17.0 + +## 0.1.15 + +### Patch Changes + +- Updated dependencies [[`b59c024b23c69f5459b17390531207cfdf126ce4`](https://github.com/wevm/wagmi/commit/b59c024b23c69f5459b17390531207cfdf126ce4)]: + - @wagmi/connectors@5.7.12 + +## 0.1.14 + +### Patch Changes + +- Updated dependencies [[`a4bd0623eed28e3761a27295831a60ad835f0ee0`](https://github.com/wevm/wagmi/commit/a4bd0623eed28e3761a27295831a60ad835f0ee0)]: + - @wagmi/core@2.16.7 + - @wagmi/connectors@5.7.11 + +## 0.1.13 + +### Patch Changes + +- Updated dependencies [[`edf47477b2f6385a1c3ae01d36a8498c47f30a0b`](https://github.com/wevm/wagmi/commit/edf47477b2f6385a1c3ae01d36a8498c47f30a0b), [`e944812ebc234a72c1417b77cff341166f5e0fef`](https://github.com/wevm/wagmi/commit/e944812ebc234a72c1417b77cff341166f5e0fef)]: + - @wagmi/core@2.16.6 + - @wagmi/connectors@5.7.10 + +## 0.1.12 + +### Patch Changes + +- Updated dependencies [[`5b7101fddb61df56e34b2e02b46bc409e496eaf9`](https://github.com/wevm/wagmi/commit/5b7101fddb61df56e34b2e02b46bc409e496eaf9)]: + - @wagmi/connectors@5.7.9 + +## 0.1.11 + +### Patch Changes + +- Updated dependencies [[`d0c9a86921a4e939373cc6e763284e53f2a2e93c`](https://github.com/wevm/wagmi/commit/d0c9a86921a4e939373cc6e763284e53f2a2e93c)]: + - @wagmi/core@2.16.5 + - @wagmi/connectors@5.7.8 + +## 0.1.10 + +### Patch Changes + +- [`507f864d91238bfd423d0e36d3619eb9f6e52eec`](https://github.com/wevm/wagmi/commit/507f864d91238bfd423d0e36d3619eb9f6e52eec) Thanks [@jxom](https://github.com/jxom)! - Updated `@coinbase/wallet-sdk`. + +- Updated dependencies [[`507f864d91238bfd423d0e36d3619eb9f6e52eec`](https://github.com/wevm/wagmi/commit/507f864d91238bfd423d0e36d3619eb9f6e52eec)]: + - @wagmi/connectors@5.7.7 + - @wagmi/core@2.16.4 + +## 0.1.9 + +### Patch Changes + +- Updated dependencies [[`639952c97f0fe3927106f42d3c9f7f366cdf7f7a`](https://github.com/wevm/wagmi/commit/639952c97f0fe3927106f42d3c9f7f366cdf7f7a), [`5aa2c095f7bfb6dfcf91c6945c3e1f9c9dd05766`](https://github.com/wevm/wagmi/commit/5aa2c095f7bfb6dfcf91c6945c3e1f9c9dd05766)]: + - @wagmi/connectors@5.7.6 + +## 0.1.8 + +### Patch Changes + +- Updated dependencies [[`a257e8d4f97431a4af872cda1817b4ae17c7bbed`](https://github.com/wevm/wagmi/commit/a257e8d4f97431a4af872cda1817b4ae17c7bbed)]: + - @wagmi/connectors@5.7.5 + +## 0.1.7 + +### Patch Changes + +- Updated dependencies [[`c8a257e0f6d2ece013b873895c35769a8a804fdc`](https://github.com/wevm/wagmi/commit/c8a257e0f6d2ece013b873895c35769a8a804fdc)]: + - @wagmi/connectors@5.7.4 + +## 0.1.6 + +### Patch Changes + +- [#4480](https://github.com/wevm/wagmi/pull/4480) [`384a1d91597622eb59e1c05dc13ce25017c5b6d8`](https://github.com/wevm/wagmi/commit/384a1d91597622eb59e1c05dc13ce25017c5b6d8) Thanks [@RodeRickIsWatching](https://github.com/RodeRickIsWatching)! - Fixed invocation of default storage. + +- Updated dependencies [[`384a1d91597622eb59e1c05dc13ce25017c5b6d8`](https://github.com/wevm/wagmi/commit/384a1d91597622eb59e1c05dc13ce25017c5b6d8)]: + - @wagmi/core@2.16.3 + - @wagmi/connectors@5.7.3 + +## 0.1.5 + +### Patch Changes + +- [`012907032b532a438fce48f407470250cbc8f0c6`](https://github.com/wevm/wagmi/commit/012907032b532a438fce48f407470250cbc8f0c6) Thanks [@jxom](https://github.com/jxom)! - Fixed assignment in `getDefaultStorage`. + +- Updated dependencies [[`012907032b532a438fce48f407470250cbc8f0c6`](https://github.com/wevm/wagmi/commit/012907032b532a438fce48f407470250cbc8f0c6)]: + - @wagmi/core@2.16.2 + - @wagmi/connectors@5.7.2 + +## 0.1.4 + +### Patch Changes + +- Updated dependencies [[`9c8c35a3b829f2c58edcd3a29e2dcd99974d7470`](https://github.com/wevm/wagmi/commit/9c8c35a3b829f2c58edcd3a29e2dcd99974d7470), [`3892ebd21c06beef4b28ece4e70d2a38807bce6f`](https://github.com/wevm/wagmi/commit/3892ebd21c06beef4b28ece4e70d2a38807bce6f)]: + - @wagmi/connectors@5.7.1 + - @wagmi/core@2.16.1 + +## 0.1.3 + +### Patch Changes + +- Updated dependencies [[`e3f63a02c1f7d80481804584f262bc98dab0400d`](https://github.com/wevm/wagmi/commit/e3f63a02c1f7d80481804584f262bc98dab0400d)]: + - @wagmi/connectors@5.7.0 + +## 0.1.2 + +### Patch Changes + +- Updated dependencies [[`adf2253b10c6d4fc583e4bc9f01a8ef5ca267c85`](https://github.com/wevm/wagmi/commit/adf2253b10c6d4fc583e4bc9f01a8ef5ca267c85)]: + - @wagmi/connectors@5.6.2 + +## 0.1.1 + +### Patch Changes + +- Updated dependencies [[`987404f590c1d29ebb3cb68928f5e54aa032793d`](https://github.com/wevm/wagmi/commit/987404f590c1d29ebb3cb68928f5e54aa032793d)]: + - @wagmi/connectors@5.6.1 + +## 0.1.0 + +### Minor Changes + +- [#4453](https://github.com/wevm/wagmi/pull/4453) [`070e48480194c8d7f45bda1d7dd1346e6f5d7227`](https://github.com/wevm/wagmi/commit/070e48480194c8d7f45bda1d7dd1346e6f5d7227) Thanks [@tmm](https://github.com/tmm)! - Added support to `useConnect` for custom `connector.connect` parameters. + +### Patch Changes + +- Updated dependencies [[`afea6b67822a7a2b96901ec851441d27ee0f7a52`](https://github.com/wevm/wagmi/commit/afea6b67822a7a2b96901ec851441d27ee0f7a52), [`070e48480194c8d7f45bda1d7dd1346e6f5d7227`](https://github.com/wevm/wagmi/commit/070e48480194c8d7f45bda1d7dd1346e6f5d7227), [`8b0726c1106fce88b782e676498eabf0718b2619`](https://github.com/wevm/wagmi/commit/8b0726c1106fce88b782e676498eabf0718b2619)]: + - @wagmi/core@2.16.0 + - @wagmi/connectors@5.6.0 + +## 0.0.69 + +### Patch Changes + +- [`2f79a3da4872d6158569017b1927a07a1ff5e7ba`](https://github.com/wevm/wagmi/commit/2f79a3da4872d6158569017b1927a07a1ff5e7ba) Thanks [@tmm](https://github.com/tmm)! - Exported `injected` and `mock`. + +## 0.0.68 + +### Patch Changes + +- [#4433](https://github.com/wevm/wagmi/pull/4433) [`06e186cd679b27fe195309110e766fcf46d4efbc`](https://github.com/wevm/wagmi/commit/06e186cd679b27fe195309110e766fcf46d4efbc) Thanks [@Aerilym](https://github.com/Aerilym)! - Bumped Metamask SDK version to `0.31.1`. + +- Updated dependencies [[`06e186cd679b27fe195309110e766fcf46d4efbc`](https://github.com/wevm/wagmi/commit/06e186cd679b27fe195309110e766fcf46d4efbc)]: + - @wagmi/connectors@5.5.3 + - @wagmi/core@2.15.2 + +## 0.0.67 + +### Patch Changes + +- Updated dependencies [[`e563ef69130a511fd6f3f72ed4cd4fbe1390541f`](https://github.com/wevm/wagmi/commit/e563ef69130a511fd6f3f72ed4cd4fbe1390541f)]: + - @wagmi/connectors@5.5.2 + +## 0.0.66 + +### Patch Changes + +- [`b8bbb409f4934538e3dd6cac5aaf7346292d0693`](https://github.com/wevm/wagmi/commit/b8bbb409f4934538e3dd6cac5aaf7346292d0693) Thanks [@jxom](https://github.com/jxom)! - Fixed issue where `null` gas would accidentally pass through. + +- Updated dependencies [[`b8bbb409f4934538e3dd6cac5aaf7346292d0693`](https://github.com/wevm/wagmi/commit/b8bbb409f4934538e3dd6cac5aaf7346292d0693)]: + - @wagmi/core@2.15.1 + - @wagmi/connectors@5.5.1 + +## 0.0.65 + +### Minor Changes + +- [#4417](https://github.com/wevm/wagmi/pull/4417) [`42e65ea4fea99c639817088bba915e0933d17141`](https://github.com/wevm/wagmi/commit/42e65ea4fea99c639817088bba915e0933d17141) Thanks [@jxom](https://github.com/jxom)! - Removed simulation in `writeContract` & `sendTransaction`. + +### Patch Changes + +- Updated dependencies [[`42e65ea4fea99c639817088bba915e0933d17141`](https://github.com/wevm/wagmi/commit/42e65ea4fea99c639817088bba915e0933d17141)]: + - @wagmi/connectors@6.0.0 + - @wagmi/core@2.15.0 + +## 0.0.64 + +### Patch Changes + +- Updated dependencies [[`7ca62b44cd997d48f92c2b81343726a5908aa00b`](https://github.com/wevm/wagmi/commit/7ca62b44cd997d48f92c2b81343726a5908aa00b)]: + - @wagmi/connectors@5.4.0 + +## 0.0.63 + +### Patch Changes + +- Updated dependencies [[`a13aa8d7c38eb3cc8171a02d6302e6d12cf6bcb3`](https://github.com/wevm/wagmi/commit/a13aa8d7c38eb3cc8171a02d6302e6d12cf6bcb3), [`a13aa8d7c38eb3cc8171a02d6302e6d12cf6bcb3`](https://github.com/wevm/wagmi/commit/a13aa8d7c38eb3cc8171a02d6302e6d12cf6bcb3)]: + - @wagmi/core@2.14.6 + - @wagmi/connectors@5.3.10 + +## 0.0.62 + +### Patch Changes + +- Updated dependencies [[`b12a04eeec985c48d2feac94b011d41fb29ca23e`](https://github.com/wevm/wagmi/commit/b12a04eeec985c48d2feac94b011d41fb29ca23e)]: + - @wagmi/connectors@5.3.9 + +## 0.0.61 + +### Patch Changes + +- Updated dependencies [[`6b9bbacdc7bffd44fc2165362a5e65fd434e7646`](https://github.com/wevm/wagmi/commit/6b9bbacdc7bffd44fc2165362a5e65fd434e7646), [`dac62dc99a0679fa632a0fae49873d6053d06b35`](https://github.com/wevm/wagmi/commit/dac62dc99a0679fa632a0fae49873d6053d06b35)]: + - @wagmi/core@2.14.5 + - @wagmi/connectors@5.3.8 + +## 0.0.60 + +### Patch Changes + +- Updated dependencies [[`e08681c81fbdf475213e2d0f4c5517d0abf4e743`](https://github.com/wevm/wagmi/commit/e08681c81fbdf475213e2d0f4c5517d0abf4e743)]: + - @wagmi/core@2.14.4 + - @wagmi/connectors@5.3.7 + +## 0.0.59 + +### Patch Changes + +- Updated dependencies [[`7558ff3133c11bc4c49473d08ee9a47eaa12df5b`](https://github.com/wevm/wagmi/commit/7558ff3133c11bc4c49473d08ee9a47eaa12df5b)]: + - @wagmi/connectors@5.3.6 + +## 0.0.58 + +### Patch Changes + +- Updated dependencies [[`cb7dd2ebb871d0be8f1a11a8cd8ce592cd74b7c7`](https://github.com/wevm/wagmi/commit/cb7dd2ebb871d0be8f1a11a8cd8ce592cd74b7c7), [`7fe78f2d09778fc01fd0cffe85ba198e64999275`](https://github.com/wevm/wagmi/commit/7fe78f2d09778fc01fd0cffe85ba198e64999275)]: + - @wagmi/core@2.14.3 + - @wagmi/connectors@5.3.5 + +## 0.0.57 + +### Patch Changes + +- Updated dependencies [[`b6861a4c378dab78d8751ae0ac2aa425f3c24b8f`](https://github.com/wevm/wagmi/commit/b6861a4c378dab78d8751ae0ac2aa425f3c24b8f), [`d0d0963bb5904a15cf0355862d62dd141ce0c31c`](https://github.com/wevm/wagmi/commit/d0d0963bb5904a15cf0355862d62dd141ce0c31c), [`ecac0ba36243d94c9199d0bd21937104c835d9a0`](https://github.com/wevm/wagmi/commit/ecac0ba36243d94c9199d0bd21937104c835d9a0)]: + - @wagmi/connectors@5.3.4 + - @wagmi/core@2.14.2 + +## 0.0.56 + +### Patch Changes + +- Updated dependencies [[`83c6d16b7d6dddfa6bda036e04f00ec313c6248c`](https://github.com/wevm/wagmi/commit/83c6d16b7d6dddfa6bda036e04f00ec313c6248c)]: + - @wagmi/connectors@5.3.3 + +## 0.0.55 + +### Patch Changes + +- Updated dependencies [[`8970cc51398e1ac713435533096215c6d31ffdf9`](https://github.com/wevm/wagmi/commit/8970cc51398e1ac713435533096215c6d31ffdf9)]: + - @wagmi/connectors@5.3.2 + +## 0.0.54 + +### Patch Changes + +- Updated dependencies [[`052e72e1f8c1c14fcbdce04a9f8fa7ec28d83702`](https://github.com/wevm/wagmi/commit/052e72e1f8c1c14fcbdce04a9f8fa7ec28d83702), [`b250fc21ee577b2a75c5a34ff684f62fb4ad771a`](https://github.com/wevm/wagmi/commit/b250fc21ee577b2a75c5a34ff684f62fb4ad771a)]: + - @wagmi/core@2.14.1 + - @wagmi/connectors@5.3.1 + +## 0.0.53 + +### Patch Changes + +- Updated dependencies [[`f43e074f473820b208a6295d7c97f847332f1a1d`](https://github.com/wevm/wagmi/commit/f43e074f473820b208a6295d7c97f847332f1a1d)]: + - @wagmi/connectors@6.0.0 + - @wagmi/core@2.14.0 + +## 0.0.52 + +### Patch Changes + +- Updated dependencies [[`c05caabc20c3ced9682cfc7ba1f3f7dcfece0703`](https://github.com/wevm/wagmi/commit/c05caabc20c3ced9682cfc7ba1f3f7dcfece0703), [`5ae49af590ff168426c9c283d54c34ae5148fcd9`](https://github.com/wevm/wagmi/commit/5ae49af590ff168426c9c283d54c34ae5148fcd9), [`f3182b22e6e454d9bd74f1b940ef34431fd9555d`](https://github.com/wevm/wagmi/commit/f3182b22e6e454d9bd74f1b940ef34431fd9555d)]: + - @wagmi/core@2.13.9 + - @wagmi/connectors@5.2.2 + +## 0.0.51 + +### Patch Changes + +- Updated dependencies [[`91a40f2db08e3a91db421b8732a5511a1e6c88fd`](https://github.com/wevm/wagmi/commit/91a40f2db08e3a91db421b8732a5511a1e6c88fd)]: + - @wagmi/connectors@5.2.1 + +## 0.0.50 + +### Patch Changes + +- Updated dependencies [[`34a0c3b7eea778aee7c27f7ace5e4b2be4e8a0a4`](https://github.com/wevm/wagmi/commit/34a0c3b7eea778aee7c27f7ace5e4b2be4e8a0a4)]: + - @wagmi/connectors@5.2.0 + +## 0.0.49 + +### Patch Changes + +- Updated dependencies [[`3b2123664b7ac66848390739e855c3b9702ab60c`](https://github.com/wevm/wagmi/commit/3b2123664b7ac66848390739e855c3b9702ab60c)]: + - @wagmi/connectors@5.1.15 + +## 0.0.48 + +### Patch Changes + +- Updated dependencies [[`56f2482508f2ba71bd6b0295c70c6abca7101e57`](https://github.com/wevm/wagmi/commit/56f2482508f2ba71bd6b0295c70c6abca7101e57)]: + - @wagmi/connectors@5.1.14 + - @wagmi/core@2.13.8 + +## 0.0.47 + +### Patch Changes + +- Updated dependencies [[`be75c2d4ef636d7362420ab0a106bfdf63f5d1e6`](https://github.com/wevm/wagmi/commit/be75c2d4ef636d7362420ab0a106bfdf63f5d1e6)]: + - @wagmi/core@2.13.7 + - @wagmi/connectors@5.1.13 + +## 0.0.46 + +### Patch Changes + +- Updated dependencies [[`edcbf5d6fbe92f639bead800502edda9e0aa39f1`](https://github.com/wevm/wagmi/commit/edcbf5d6fbe92f639bead800502edda9e0aa39f1)]: + - @wagmi/core@2.13.6 + - @wagmi/connectors@5.1.12 + +## 0.0.45 + +### Patch Changes + +- Updated dependencies [[`82404c960e04c83e0bae6e1e12459ef9debf9554`](https://github.com/wevm/wagmi/commit/82404c960e04c83e0bae6e1e12459ef9debf9554), [`d07ad7f63a018256908a673d078aaf79e47ac703`](https://github.com/wevm/wagmi/commit/d07ad7f63a018256908a673d078aaf79e47ac703)]: + - @wagmi/connectors@5.1.11 + +## 0.0.44 + +### Patch Changes + +- [#4262](https://github.com/wevm/wagmi/pull/4262) [`8531f83db3a1fbb8202c3e426b7f85679f587a52`](https://github.com/wevm/wagmi/commit/8531f83db3a1fbb8202c3e426b7f85679f587a52) Thanks [@nezouse](https://github.com/nezouse)! - Added experimental actions entrypoint. + +## 0.0.43 + +### Patch Changes + +- [#4260](https://github.com/wevm/wagmi/pull/4260) [`969a208a110b760a13fd7263360320f52440a9b6`](https://github.com/wevm/wagmi/commit/969a208a110b760a13fd7263360320f52440a9b6) Thanks [@tmm](https://github.com/tmm)! - Fixed `useReadContract` deployless reads support. + +- [#4259](https://github.com/wevm/wagmi/pull/4259) [`f47ce8f6d263e49fdff90b8edb3190142d2657bb`](https://github.com/wevm/wagmi/commit/f47ce8f6d263e49fdff90b8edb3190142d2657bb) Thanks [@tmm](https://github.com/tmm)! - Disabled `useConnectorClient` during reconnection if connector is not fully restored. + +- Updated dependencies [[`81de006e66121a18c61945c1f9b8426c83a5713c`](https://github.com/wevm/wagmi/commit/81de006e66121a18c61945c1f9b8426c83a5713c), [`f47ce8f6d263e49fdff90b8edb3190142d2657bb`](https://github.com/wevm/wagmi/commit/f47ce8f6d263e49fdff90b8edb3190142d2657bb)]: + - @wagmi/connectors@5.1.10 + - @wagmi/core@2.13.5 + +## 0.0.42 + +### Patch Changes + +- [#4252](https://github.com/wevm/wagmi/pull/4252) [`67defb516bbd9b2c7b03e376ecd3aca8a001d065`](https://github.com/wevm/wagmi/commit/67defb516bbd9b2c7b03e376ecd3aca8a001d065) Thanks [@tmm](https://github.com/tmm)! - Added `useWatchContractEvent`. + +## 0.0.41 + +### Patch Changes + +- Updated dependencies [[`21bd0e473d374cbbd7a01bececa6022d529026ba`](https://github.com/wevm/wagmi/commit/21bd0e473d374cbbd7a01bececa6022d529026ba), [`5c89c6853e616437a3be2b019db895451fecfb3c`](https://github.com/wevm/wagmi/commit/5c89c6853e616437a3be2b019db895451fecfb3c)]: + - @wagmi/connectors@5.1.9 + +## 0.0.40 + +### Patch Changes + +- Updated dependencies [[`b580ad4edff1721e0b9d138cf5ae2ec74d2374c7`](https://github.com/wevm/wagmi/commit/b580ad4edff1721e0b9d138cf5ae2ec74d2374c7)]: + - @wagmi/connectors@5.1.8 + +## 0.0.39 + +### Patch Changes + +- Updated dependencies [[`91fd81a068789c5020e891f539bcad8f54a7a52f`](https://github.com/wevm/wagmi/commit/91fd81a068789c5020e891f539bcad8f54a7a52f)]: + - @wagmi/connectors@5.1.7 + +## 0.0.38 + +### Patch Changes + +- Updated dependencies [[`3168616298cbb6135d0ffda771cba4126e83eba8`](https://github.com/wevm/wagmi/commit/3168616298cbb6135d0ffda771cba4126e83eba8), [`d7608ef9a79459465dc8c06a2ab740465c881907`](https://github.com/wevm/wagmi/commit/d7608ef9a79459465dc8c06a2ab740465c881907)]: + - @wagmi/connectors@5.1.6 + +## 0.0.37 + +### Patch Changes + +- Updated dependencies [[`b4c8971788c70b09479946ecfa998cff2f1b3953`](https://github.com/wevm/wagmi/commit/b4c8971788c70b09479946ecfa998cff2f1b3953)]: + - @wagmi/core@2.13.4 + - @wagmi/connectors@5.1.5 + +## 0.0.36 + +### Patch Changes + +- Updated dependencies [[`871dbdbfe59ac8ad01d1ec6150ea7b091b7b7de4`](https://github.com/wevm/wagmi/commit/871dbdbfe59ac8ad01d1ec6150ea7b091b7b7de4)]: + - @wagmi/core@2.13.3 + - @wagmi/connectors@5.1.4 + +## 0.0.35 + +### Patch Changes + +- Updated dependencies [[`1b9b523fa9b9dfe839aecdf4b40caa9547d7e594`](https://github.com/wevm/wagmi/commit/1b9b523fa9b9dfe839aecdf4b40caa9547d7e594)]: + - @wagmi/core@2.13.2 + - @wagmi/connectors@5.1.3 + +## 0.0.34 + +### Patch Changes + +- Updated dependencies [[`abb490dac4f0f02f46cb0878e7ca9a0db6aada56`](https://github.com/wevm/wagmi/commit/abb490dac4f0f02f46cb0878e7ca9a0db6aada56), [`28e0e5c9a4f856583f9d36a807502bd51a0c6ec2`](https://github.com/wevm/wagmi/commit/28e0e5c9a4f856583f9d36a807502bd51a0c6ec2)]: + - @wagmi/connectors@5.1.2 + +## 0.0.33 + +### Patch Changes + +- Updated dependencies [[`07c1227f306d0efb9421d4bb77a774f92f5fcf45`](https://github.com/wevm/wagmi/commit/07c1227f306d0efb9421d4bb77a774f92f5fcf45)]: + - @wagmi/core@2.13.1 + - @wagmi/connectors@5.1.1 + +## 0.0.32 + +### Patch Changes + +- [#4162](https://github.com/wevm/wagmi/pull/4162) [`a73a7737b756886b388f120ae423e72cca53e8a0`](https://github.com/wevm/wagmi/commit/a73a7737b756886b388f120ae423e72cca53e8a0) Thanks [@jxom](https://github.com/jxom)! - Added functionality for consumer-defined RPC URLs (`config.transports`) to be propagated to the WalletConnect & MetaMask Connectors. + +- Updated dependencies [[`a73a7737b756886b388f120ae423e72cca53e8a0`](https://github.com/wevm/wagmi/commit/a73a7737b756886b388f120ae423e72cca53e8a0)]: + - @wagmi/connectors@6.0.0 + - @wagmi/core@2.13.0 + +## 0.0.31 + +### Patch Changes + +- [#4124](https://github.com/wevm/wagmi/pull/4124) [`26616462db2e0140025f22c505c4541cfecb9308`](https://github.com/wevm/wagmi/commit/26616462db2e0140025f22c505c4541cfecb9308) Thanks [@t0rbik](https://github.com/t0rbik)! - Updated `useConnectorClient` to be enabled when status is `'reconnecting'` or `'connected'` (previously was also enabled when status was `'connecting'`). + +## 0.0.30 + +### Patch Changes + +- Updated dependencies [[`5bc8c8877810b2eec24a829df87dce40a51e6f20`](https://github.com/wevm/wagmi/commit/5bc8c8877810b2eec24a829df87dce40a51e6f20), [`8d81df5cc884d0a210dedd3c1ea0e2e9e52b83c5`](https://github.com/wevm/wagmi/commit/8d81df5cc884d0a210dedd3c1ea0e2e9e52b83c5)]: + - @wagmi/core@2.12.2 + - @wagmi/connectors@5.0.26 + +## 0.0.29 + +### Patch Changes + +- [#4146](https://github.com/wevm/wagmi/pull/4146) [`cc996e08e930c9e88cf753a1e874652059e81a3b`](https://github.com/wevm/wagmi/commit/cc996e08e930c9e88cf753a1e874652059e81a3b) Thanks [@jxom](https://github.com/jxom)! - Updated `@safe-global/safe-apps-sdk` + `@safe-global/safe-apps-provider` dependencies. + +- Updated dependencies [[`cc996e08e930c9e88cf753a1e874652059e81a3b`](https://github.com/wevm/wagmi/commit/cc996e08e930c9e88cf753a1e874652059e81a3b)]: + - @wagmi/connectors@5.0.25 + - @wagmi/core@2.12.1 + +## 0.0.28 + +### Patch Changes + +- [`b6cb1477e3e87984917b172a909f1968e0d77dc9`](https://github.com/wevm/wagmi/commit/b6cb1477e3e87984917b172a909f1968e0d77dc9) Thanks [@tmm](https://github.com/tmm)! - Added `useBytecode` composable. + +- Updated dependencies [[`5581a810ef70308e99c6f8b630cd4bca59f64afc`](https://github.com/wevm/wagmi/commit/5581a810ef70308e99c6f8b630cd4bca59f64afc)]: + - @wagmi/core@2.12.0 + - @wagmi/connectors@6.0.0 + +## 0.0.27 + +### Patch Changes + +- [`d3814ab4b88f9f0e052b53bc3d458df87b43f01d`](https://github.com/wevm/wagmi/commit/d3814ab4b88f9f0e052b53bc3d458df87b43f01d) Thanks [@jxom](https://github.com/jxom)! - Updated `mipd` dependency. + +- Updated dependencies [[`b08013eaa9ce97c02f8a7128ea400e3da7ef74bb`](https://github.com/wevm/wagmi/commit/b08013eaa9ce97c02f8a7128ea400e3da7ef74bb), [`d3814ab4b88f9f0e052b53bc3d458df87b43f01d`](https://github.com/wevm/wagmi/commit/d3814ab4b88f9f0e052b53bc3d458df87b43f01d)]: + - @wagmi/core@2.11.8 + - @wagmi/connectors@5.0.23 + +## 0.0.26 + +### Patch Changes + +- Updated dependencies [[`0bb8b562ae04ecfeb2d6b2f1b980ebae31dc127e`](https://github.com/wevm/wagmi/commit/0bb8b562ae04ecfeb2d6b2f1b980ebae31dc127e)]: + - @wagmi/connectors@5.0.22 + - @wagmi/core@2.11.7 + +## 0.0.25 + +### Patch Changes + +- [#4060](https://github.com/wevm/wagmi/pull/4060) [`95965c1f19d480b97f2b297a077a9e607dee32ad`](https://github.com/wevm/wagmi/commit/95965c1f19d480b97f2b297a077a9e607dee32ad) Thanks [@dalechyn](https://github.com/dalechyn)! - Bumped Tanstack Query dependencies to fix typing issues between exported Wagmi query options and TanStack Query suspense query methods (due to [`direction` property in `QueryFunctionContext` being deprecated](https://github.com/TanStack/query/pull/7410)). + +- Updated dependencies [[`ff0760b5900114bcfdf420a9fba3cc278ac95afe`](https://github.com/wevm/wagmi/commit/ff0760b5900114bcfdf420a9fba3cc278ac95afe), [`95965c1f19d480b97f2b297a077a9e607dee32ad`](https://github.com/wevm/wagmi/commit/95965c1f19d480b97f2b297a077a9e607dee32ad)]: + - @wagmi/connectors@5.0.21 + - @wagmi/core@2.11.6 + +## 0.0.24 + +### Patch Changes + +- Updated dependencies [[`43fa971d34cac57fa5a2898ad4d839b95d7af37c`](https://github.com/wevm/wagmi/commit/43fa971d34cac57fa5a2898ad4d839b95d7af37c)]: + - @wagmi/connectors@5.0.20 + +## 0.0.23 + +### Patch Changes + +- Updated dependencies [[`b7ad208030d9f2e3f89912ff76b16cdbd848feda`](https://github.com/wevm/wagmi/commit/b7ad208030d9f2e3f89912ff76b16cdbd848feda)]: + - @wagmi/connectors@5.0.19 + +## 0.0.22 + +### Patch Changes + +- Updated dependencies [[`44d24620c9e3957f3245d14d6a042736371df70b`](https://github.com/wevm/wagmi/commit/44d24620c9e3957f3245d14d6a042736371df70b)]: + - @wagmi/connectors@5.0.18 + +## 0.0.21 + +### Patch Changes + +- Updated dependencies [[`04f2b846b113f3d300d82c9fa75212f1805817c5`](https://github.com/wevm/wagmi/commit/04f2b846b113f3d300d82c9fa75212f1805817c5)]: + - @wagmi/core@2.11.5 + - @wagmi/connectors@5.0.17 + +## 0.0.20 + +### Patch Changes + +- Updated dependencies [[`9e8345cd56186b997b5e56deaa2cfc69b30d15f6`](https://github.com/wevm/wagmi/commit/9e8345cd56186b997b5e56deaa2cfc69b30d15f6), [`02c38c28d1aa0ad7a61c33775de603ed974c5c1b`](https://github.com/wevm/wagmi/commit/02c38c28d1aa0ad7a61c33775de603ed974c5c1b)]: + - @wagmi/core@2.11.4 + - @wagmi/connectors@5.0.16 + +## 0.0.19 + +### Patch Changes + +- Updated dependencies [[`8974e6269bb5d7bfaa90db0246bc7d13e8bff798`](https://github.com/wevm/wagmi/commit/8974e6269bb5d7bfaa90db0246bc7d13e8bff798)]: + - @wagmi/core@2.11.3 + - @wagmi/connectors@5.0.15 + +## 0.0.18 + +### Patch Changes + +- Updated dependencies [[`b4d9ef79deb554ee20fed6666a474be5e7cdd522`](https://github.com/wevm/wagmi/commit/b4d9ef79deb554ee20fed6666a474be5e7cdd522)]: + - @wagmi/core@2.11.2 + - @wagmi/connectors@5.0.14 + +## 0.0.17 + +### Patch Changes + +- Updated dependencies [[`9c862d8d63e3d692a22cef2a90782b74a9103f17`](https://github.com/wevm/wagmi/commit/9c862d8d63e3d692a22cef2a90782b74a9103f17)]: + - @wagmi/connectors@5.0.13 + - @wagmi/core@2.11.1 + +## 0.0.16 + +### Patch Changes + +- Updated dependencies [[`06bb598a7f04c7b167f5b7ff6d46bd15886a6a14`](https://github.com/wevm/wagmi/commit/06bb598a7f04c7b167f5b7ff6d46bd15886a6a14), [`24a45b269bd0214a29d6f82a84ac66ef8c3f3822`](https://github.com/wevm/wagmi/commit/24a45b269bd0214a29d6f82a84ac66ef8c3f3822)]: + - @wagmi/core@2.11.0 + - @wagmi/connectors@6.0.0 + +## 0.0.15 + +### Patch Changes + +- Updated dependencies [[`f2a7cefab96691ebed8b8e45ffde071c47b58dbe`](https://github.com/wevm/wagmi/commit/f2a7cefab96691ebed8b8e45ffde071c47b58dbe), [`f0ea0b2a7fe193dadfeb49a4c8031ee451c638b5`](https://github.com/wevm/wagmi/commit/f0ea0b2a7fe193dadfeb49a4c8031ee451c638b5), [`e3b124ce414b8fd1b2214e2c5a28dc72158a13d1`](https://github.com/wevm/wagmi/commit/e3b124ce414b8fd1b2214e2c5a28dc72158a13d1)]: + - @wagmi/core@2.10.6 + - @wagmi/connectors@5.0.11 + +## 0.0.14 + +### Patch Changes + +- Updated dependencies [[`560952acd4bfe33db6c7c07b35c613cef278677c`](https://github.com/wevm/wagmi/commit/560952acd4bfe33db6c7c07b35c613cef278677c)]: + - @wagmi/connectors@5.0.10 + +## 0.0.13 + +### Patch Changes + +- Updated dependencies [[`32cdd7b7dc5aff916c040628519562c3a99d418d`](https://github.com/wevm/wagmi/commit/32cdd7b7dc5aff916c040628519562c3a99d418d)]: + - @wagmi/connectors@5.0.9 + +## 0.0.12 + +### Patch Changes + +- Updated dependencies [[`c1952d1ff7f0a491dc88595a49159451b07b5621`](https://github.com/wevm/wagmi/commit/c1952d1ff7f0a491dc88595a49159451b07b5621)]: + - @wagmi/connectors@5.0.8 + +## 0.0.11 + +### Patch Changes + +- Updated dependencies [[`030c7c2cb380dfd67a2182f62e2aa7a6e1601898`](https://github.com/wevm/wagmi/commit/030c7c2cb380dfd67a2182f62e2aa7a6e1601898)]: + - @wagmi/core@2.10.5 + - @wagmi/connectors@5.0.7 + +## 0.0.10 + +### Patch Changes + +- Updated dependencies [[`51fde8a0433b4fff357c1a8d7e08b41b4c86c968`](https://github.com/wevm/wagmi/commit/51fde8a0433b4fff357c1a8d7e08b41b4c86c968)]: + - @wagmi/core@2.10.4 + - @wagmi/connectors@5.0.6 + +## 0.0.9 + +### Patch Changes + +- Updated dependencies [[`70dd28669dd8d2ce08217cd02e29a8fbba7a08d4`](https://github.com/wevm/wagmi/commit/70dd28669dd8d2ce08217cd02e29a8fbba7a08d4)]: + - @wagmi/connectors@5.0.5 + +## 0.0.8 + +### Patch Changes + +- Updated dependencies [[`be9e1b8a9818b92eb0654a20d9471e9e39329e7e`](https://github.com/wevm/wagmi/commit/be9e1b8a9818b92eb0654a20d9471e9e39329e7e)]: + - @wagmi/connectors@5.0.4 + +## 0.0.7 + +### Patch Changes + +- Updated dependencies [[`2804a8a583b1874271154898b4bae38756ef581c`](https://github.com/wevm/wagmi/commit/2804a8a583b1874271154898b4bae38756ef581c), [`2804a8a583b1874271154898b4bae38756ef581c`](https://github.com/wevm/wagmi/commit/2804a8a583b1874271154898b4bae38756ef581c)]: + - @wagmi/connectors@5.0.3 + - @wagmi/core@2.10.3 + +## 0.0.6 + +### Patch Changes + +- [`ec2f63f106fd468f28b43d3b88ab3e89aaf5e81a`](https://github.com/wevm/wagmi/commit/ec2f63f106fd468f28b43d3b88ab3e89aaf5e81a) Thanks [@tmm](https://github.com/tmm)! - Fixed `useSwitchChain` `chains` typing. + +## 0.0.5 + +### Patch Changes + +- [#3940](https://github.com/wevm/wagmi/pull/3940) [`a5071f581dfdfb961718873643a2fc629101c72a`](https://github.com/wevm/wagmi/commit/a5071f581dfdfb961718873643a2fc629101c72a) Thanks [@jxom](https://github.com/jxom)! - Fixed usage of `metaMask` connector in Vite environments. + +- Updated dependencies [[`a5071f581dfdfb961718873643a2fc629101c72a`](https://github.com/wevm/wagmi/commit/a5071f581dfdfb961718873643a2fc629101c72a)]: + - @wagmi/connectors@5.0.2 + - @wagmi/core@2.10.2 + +## 0.0.4 + +### Patch Changes + +- Updated dependencies []: + - @wagmi/connectors@5.0.1 + - @wagmi/core@2.10.1 + +## 0.0.3 + +### Patch Changes + +- Updated dependencies [[`3117e71825f9c58a0d718f3d1686f1a191fa9cb1`](https://github.com/wevm/wagmi/commit/3117e71825f9c58a0d718f3d1686f1a191fa9cb1), [`3117e71825f9c58a0d718f3d1686f1a191fa9cb1`](https://github.com/wevm/wagmi/commit/3117e71825f9c58a0d718f3d1686f1a191fa9cb1)]: + - @wagmi/connectors@5.0.0 + - @wagmi/core@2.10.0 + +## 0.0.2 + +### Patch Changes + +- [#3906](https://github.com/wevm/wagmi/pull/3906) [`32fcb4a31dde6b0206961d8ffe9c651f8a459c67`](https://github.com/wevm/wagmi/commit/32fcb4a31dde6b0206961d8ffe9c651f8a459c67) Thanks [@tmm](https://github.com/tmm)! - Added support for Vue. + +- Updated dependencies [[`32fcb4a31dde6b0206961d8ffe9c651f8a459c67`](https://github.com/wevm/wagmi/commit/32fcb4a31dde6b0206961d8ffe9c651f8a459c67)]: + - @wagmi/connectors@4.3.10 + - @wagmi/core@2.9.8 diff --git a/wagmi-project/packages/vue/README.md b/wagmi-project/packages/vue/README.md new file mode 100644 index 0000000000..10a4b805d5 --- /dev/null +++ b/wagmi-project/packages/vue/README.md @@ -0,0 +1,14 @@ +# @wagmi/vue + +Vue Composables for Ethereum + +## Installation + +```bash +pnpm add @wagmi/vue viem @tanstack/vue-query +``` + +## Documentation + +For documentation and guides, visit [wagmi.sh](https://wagmi.sh). + diff --git a/wagmi-project/packages/vue/package.json b/wagmi-project/packages/vue/package.json new file mode 100644 index 0000000000..5d299133a8 --- /dev/null +++ b/wagmi-project/packages/vue/package.json @@ -0,0 +1,113 @@ +{ + "name": "@wagmi/vue", + "description": "Vue Composables for Ethereum", + "version": "0.1.20", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/wevm/wagmi.git", + "directory": "packages/vue" + }, + "scripts": { + "build": "pnpm run clean && pnpm run build:esm+types", + "build:esm+types": "tsc --project tsconfig.build.json --outDir ./dist/esm --declaration --declarationMap --declarationDir ./dist/types", + "check:types": "tsc --noEmit", + "clean": "rm -rf dist tsconfig.tsbuildinfo actions chains connectors nuxt query", + "test:build": "publint --strict && attw --pack --ignore-rules cjs-resolves-to-esm" + }, + "files": [ + "dist/**", + "!dist/**/*.tsbuildinfo", + "src/**/*.ts", + "!src/**/*.test.ts", + "!src/**/*.test-d.ts", + "/actions", + "/chains", + "/connectors", + "/nuxt", + "/query" + ], + "sideEffects": false, + "type": "module", + "main": "./dist/esm/exports/index.js", + "types": "./dist/types/exports/index.d.ts", + "typings": "./dist/types/exports/index.d.ts", + "exports": { + ".": { + "types": "./dist/types/exports/index.d.ts", + "default": "./dist/esm/exports/index.js" + }, + "./actions": { + "types": "./dist/types/exports/actions.d.ts", + "default": "./dist/esm/exports/actions.js" + }, + "./actions/experimental": { + "types": "./dist/types/exports/actions/experimental.d.ts", + "default": "./dist/esm/exports/actions/experimental.js" + }, + "./chains": { + "types": "./dist/types/exports/chains.d.ts", + "default": "./dist/esm/exports/chains.js" + }, + "./connectors": { + "types": "./dist/types/exports/connectors.d.ts", + "default": "./dist/esm/exports/connectors.js" + }, + "./nuxt": { + "types": "./dist/types/exports/nuxt.d.ts", + "default": "./dist/esm/exports/nuxt.js" + }, + "./query": { + "types": "./dist/types/exports/query.d.ts", + "default": "./dist/esm/exports/query.js" + }, + "./package.json": "./package.json" + }, + "typesVersions": { + "*": { + "actions": ["./dist/types/exports/actions.d.ts"], + "chains": ["./dist/types/exports/chains.d.ts"], + "connectors": ["./dist/types/exports/connectors.d.ts"], + "nuxt": ["./dist/types/exports/nuxt.d.ts"], + "query": ["./dist/types/exports/query.d.ts"] + } + }, + "peerDependencies": { + "@tanstack/vue-query": ">=5.0.0", + "nuxt": ">=3.0.0", + "typescript": ">=5.0.4", + "viem": "2.x", + "vue": ">=3" + }, + "peerDependenciesMeta": { + "nuxt": { + "optional": true + }, + "typescript": { + "optional": true + } + }, + "dependencies": { + "@wagmi/connectors": "workspace:*", + "@wagmi/core": "workspace:*" + }, + "devDependencies": { + "@nuxt/schema": "^3.11.2", + "@tanstack/vue-query": "catalog:", + "@vue/test-utils": "^2.4.6", + "nuxt": "^3.16.0", + "vue": "catalog:" + }, + "contributors": ["awkweb.eth ", "jxom.eth "], + "funding": "https://github.com/sponsors/wevm", + "keywords": [ + "wagmi", + "vue", + "composables", + "eth", + "ethereum", + "dapps", + "wallet", + "web3" + ] +} diff --git a/wagmi-project/packages/vue/src/composables/useAccount.test-d.ts b/wagmi-project/packages/vue/src/composables/useAccount.test-d.ts new file mode 100644 index 0000000000..cc0ef07dcc --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useAccount.test-d.ts @@ -0,0 +1,69 @@ +import type { Connector } from '@wagmi/core' +import type { Address, Chain } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { deepUnref } from '../utils/cloneDeep.js' +import { useAccount } from './useAccount.js' + +test('states', () => { + const result = deepUnref(useAccount()) + + switch (result.status) { + case 'reconnecting': { + expectTypeOf(result).toMatchTypeOf<{ + address: Address | undefined + chain: Chain | undefined + chainId: number | undefined + connector: Connector | undefined + isConnected: boolean + isConnecting: false + isDisconnected: false + isReconnecting: true + status: 'reconnecting' + }>() + break + } + case 'connecting': { + expectTypeOf(result).toMatchTypeOf<{ + address: Address | undefined + chain: Chain | undefined + chainId: number | undefined + connector: Connector | undefined + isConnected: false + isReconnecting: false + isConnecting: true + isDisconnected: false + status: 'connecting' + }>() + break + } + case 'connected': { + expectTypeOf(result).toMatchTypeOf<{ + address: Address + chain: Chain | undefined + chainId: number + connector: Connector + isConnected: true + isConnecting: false + isDisconnected: false + isReconnecting: false + status: 'connected' + }>() + break + } + case 'disconnected': { + expectTypeOf(result).toMatchTypeOf<{ + address: undefined + chain: undefined + chainId: undefined + connector: undefined + isConnected: false + isReconnecting: false + isConnecting: false + isDisconnected: true + status: 'disconnected' + }>() + break + } + } +}) diff --git a/wagmi-project/packages/vue/src/composables/useAccount.test.ts b/wagmi-project/packages/vue/src/composables/useAccount.test.ts new file mode 100644 index 0000000000..773532857d --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useAccount.test.ts @@ -0,0 +1,20 @@ +import { connect, disconnect } from '@wagmi/core' +import { config } from '@wagmi/test' +import { renderComposable } from '@wagmi/test/vue' +import { expect, test } from 'vitest' + +import { useAccount } from './useAccount.js' + +test('default', async () => { + const [account] = renderComposable(() => useAccount()) + + expect(account.address.value).not.toBeDefined() + expect(account.status.value).toEqual('disconnected') + + await connect(config, { connector: config.connectors[0]! }) + + expect(account.address.value).toBeDefined() + expect(account.status.value).toEqual('connected') + + await disconnect(config) +}) diff --git a/wagmi-project/packages/vue/src/composables/useAccount.ts b/wagmi-project/packages/vue/src/composables/useAccount.ts new file mode 100644 index 0000000000..136595fb20 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useAccount.ts @@ -0,0 +1,37 @@ +import { + type Config, + type GetAccountReturnType, + type ResolvedRegister, + getAccount, + watchAccount, +} from '@wagmi/core' +import { type ToRefs, onScopeDispose, reactive, readonly, toRefs } from 'vue' + +import type { ConfigParameter } from '../types/properties.js' +import { updateState } from '../utils/updateState.js' +import { useConfig } from './useConfig.js' + +export type UseAccountParameters = + ConfigParameter + +export type UseAccountReturnType = ToRefs< + GetAccountReturnType +> + +/** https://wagmi.sh/vue/api/composables/useAccount */ +export function useAccount( + parameters: UseAccountParameters = {}, +): UseAccountReturnType { + const config = useConfig(parameters) + + const account = reactive(getAccount(config)) + + const unsubscribe = watchAccount(config, { + onChange(data) { + updateState(account, data) + }, + }) + onScopeDispose(() => unsubscribe()) + + return toRefs(readonly(account)) as UseAccountReturnType +} diff --git a/wagmi-project/packages/vue/src/composables/useAccountEffect.test.ts b/wagmi-project/packages/vue/src/composables/useAccountEffect.test.ts new file mode 100644 index 0000000000..10ed7a3e37 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useAccountEffect.test.ts @@ -0,0 +1,75 @@ +import { VueQueryPlugin } from '@tanstack/vue-query' +import { mock } from '@wagmi/connectors' +import { http, connect, createConfig, disconnect } from '@wagmi/core' +import { accounts, chain } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { expect, test, vi } from 'vitest' +import type { App } from 'vue' + +import { WagmiPlugin } from '../plugin.js' +import { useAccount } from './useAccount.js' +import { useAccountEffect } from './useAccountEffect.js' +import { useConnect } from './useConnect.js' +import { useDisconnect } from './useDisconnect.js' + +test('behavior: connect and disconnect called once', async () => { + const onConnect = vi.fn() + const onDisconnect = vi.fn() + + renderComposable(() => useAccountEffect({ onConnect, onDisconnect })) + const [connect] = renderComposable(() => useConnect()) + const [disconnect] = renderComposable(() => useDisconnect()) + + connect.connect({ + connector: connect.connectors[0]!, + }) + await waitFor(connect.isSuccess) + connect.connect({ + connector: connect.connectors[0]!, + }) + + disconnect.disconnect() + await waitFor(disconnect.isSuccess) + disconnect.disconnect() + + expect(onConnect).toBeCalledTimes(1) + expect(onDisconnect).toBeCalledTimes(1) +}) + +test('behavior: connect called on reconnect', async () => { + const config = createConfig({ + chains: [chain.mainnet], + connectors: [ + mock({ + accounts, + features: { reconnect: true }, + }), + ], + transports: { [chain.mainnet.id]: http() }, + }) + + function attach(app: App) { + app + .use(WagmiPlugin, { + config, + reconnectOnMount: true, + }) + .use(VueQueryPlugin, {}) + } + + await connect(config, { connector: config.connectors[0]! }) + const onConnect = vi.fn((data) => { + expect(data.isReconnected).toBeTruthy() + }) + + renderComposable(() => useAccountEffect({ onConnect }), { + attach, + }) + const [account] = renderComposable(() => useAccount(), { attach }) + + await waitFor(account.status, (status) => status === 'connected') + + expect(onConnect).toBeCalledTimes(1) + + await disconnect(config) +}) diff --git a/wagmi-project/packages/vue/src/composables/useAccountEffect.ts b/wagmi-project/packages/vue/src/composables/useAccountEffect.ts new file mode 100644 index 0000000000..021624cea8 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useAccountEffect.ts @@ -0,0 +1,66 @@ +import { type GetAccountReturnType, watchAccount } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { watchEffect } from 'vue' + +import type { ConfigParameter } from '../types/properties.js' +import type { DeepMaybeRef } from '../types/ref.js' +import { deepUnref } from '../utils/cloneDeep.js' +import { useConfig } from './useConfig.js' + +export type UseAccountEffectParameters = Compute< + DeepMaybeRef< + { + onConnect?( + data: Compute< + Pick< + Extract, + 'address' | 'addresses' | 'chain' | 'chainId' | 'connector' + > & { + isReconnected: boolean + } + >, + ): void + onDisconnect?(): void + } & ConfigParameter + > +> + +/** https://wagmi.sh/vue/api/composables/useAccountEffect */ +export function useAccountEffect(parameters: UseAccountEffectParameters = {}) { + const config = useConfig(parameters) + + watchEffect((onCleanup) => { + const { onConnect, onDisconnect } = deepUnref(parameters) + + const unwatch = watchAccount(config, { + onChange(data, prevData) { + if ( + (prevData.status === 'reconnecting' || + (prevData.status === 'connecting' && + prevData.address === undefined)) && + data.status === 'connected' + ) { + const { address, addresses, chain, chainId, connector } = data + const isReconnected = + prevData.status === 'reconnecting' || + // if `previousAccount.status` is `undefined`, the connector connected immediately. + prevData.status === undefined + onConnect?.({ + address, + addresses, + chain, + chainId, + connector, + isReconnected, + }) + } else if ( + prevData.status === 'connected' && + data.status === 'disconnected' + ) + onDisconnect?.() + }, + }) + + onCleanup(() => unwatch()) + }) +} diff --git a/wagmi-project/packages/vue/src/composables/useBalance.test-d.ts b/wagmi-project/packages/vue/src/composables/useBalance.test-d.ts new file mode 100644 index 0000000000..44ba34ea48 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useBalance.test-d.ts @@ -0,0 +1,15 @@ +import { expectTypeOf, test } from 'vitest' +import type { Ref } from 'vue' + +import { useBalance } from './useBalance.js' + +test('select data', () => { + const result = useBalance({ + query: { + select(data) { + return data?.value + }, + }, + }) + expectTypeOf(result.data).toEqualTypeOf | Ref>() +}) diff --git a/wagmi-project/packages/vue/src/composables/useBalance.test.ts b/wagmi-project/packages/vue/src/composables/useBalance.test.ts new file mode 100644 index 0000000000..cf2662d302 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useBalance.test.ts @@ -0,0 +1,119 @@ +import { accounts, chain, testClient, wait } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { parseEther } from 'viem' +import { beforeEach, expect, test } from 'vitest' + +import { ref } from 'vue' +import { useBalance } from './useBalance.js' + +const address = accounts[0] + +beforeEach(async () => { + await testClient.mainnet.setBalance({ address, value: parseEther('10000') }) + await testClient.mainnet.mine({ blocks: 1 }) + await testClient.mainnet2.setBalance({ address, value: parseEther('69') }) + await testClient.mainnet2.mine({ blocks: 1 }) +}) + +test('default', async () => { + const [query] = renderComposable(() => useBalance({ address })) + + await waitFor(query.isSuccess) + + expect(query.data.value).toMatchObject( + expect.objectContaining({ + decimals: expect.any(Number), + formatted: expect.any(String), + symbol: expect.any(String), + value: expect.any(BigInt), + }), + ) +}) + +test('parameters: chainId', async () => { + const [query] = renderComposable(() => + useBalance({ address, chainId: chain.mainnet2.id }), + ) + + await waitFor(query.isSuccess) + + expect(query.data.value).toMatchInlineSnapshot(` + { + "decimals": 18, + "formatted": "69", + "symbol": "WAG", + "value": 69000000000000000000n, + } + `) +}) + +test('parameters: token', async () => { + const [query] = renderComposable(() => + useBalance({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + token: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + }), + ) + + await waitFor(query.isSuccess) + + expect(query.data.value).toMatchInlineSnapshot(` + { + "decimals": 18, + "formatted": "0.559062564299199392", + "symbol": "DAI", + "value": 559062564299199392n, + } + `) +}) + +test('parameters: unit', async () => { + const [query] = renderComposable(() => + useBalance({ + address, + chainId: chain.mainnet2.id, + unit: 'wei', + }), + ) + + await waitFor(query.isSuccess) + + expect(query.data.value).toMatchInlineSnapshot(` + { + "decimals": 18, + "formatted": "69000000000000000000", + "symbol": "WAG", + "value": 69000000000000000000n, + } + `) +}) + +test('behavior: address: undefined -> defined', async () => { + const address = ref() + + const [query] = renderComposable(() => useBalance({ address })) + + await wait(100) + expect(query.fetchStatus.value).toMatchInlineSnapshot(`"idle"`) + + address.value = accounts[0] + + await waitFor(query.isSuccess) + + expect(query.data.value).toMatchInlineSnapshot(` + { + "decimals": 18, + "formatted": "10000", + "symbol": "ETH", + "value": 10000000000000000000000n, + } + `) +}) + +test('behavior: disabled when properties missing', async () => { + const [query] = renderComposable(() => useBalance({ address })) + + await wait(100) + + expect(query.fetchStatus.value).toMatchInlineSnapshot(`"idle"`) +}) diff --git a/wagmi-project/packages/vue/src/composables/useBalance.ts b/wagmi-project/packages/vue/src/composables/useBalance.ts new file mode 100644 index 0000000000..1fdcdc9450 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useBalance.ts @@ -0,0 +1,65 @@ +import type { Config, GetBalanceErrorType, ResolvedRegister } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetBalanceData, + type GetBalanceOptions, + type GetBalanceQueryKey, + getBalanceQueryOptions, +} from '@wagmi/core/query' +import type { GetBalanceQueryFnData } from '@wagmi/core/query' + +import { computed } from 'vue' +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import type { DeepMaybeRef } from '../types/ref.js' +import { deepUnref } from '../utils/cloneDeep.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseBalanceParameters< + config extends Config = Config, + selectData = GetBalanceData, +> = Compute< + DeepMaybeRef< + GetBalanceOptions & + ConfigParameter & + QueryParameter< + GetBalanceQueryFnData, + GetBalanceErrorType, + selectData, + GetBalanceQueryKey + > + > +> + +export type UseBalanceReturnType = + UseQueryReturnType + +/** https://wagmi.sh/vue/api/composables/useBalance */ +export function useBalance< + config extends Config = ResolvedRegister['config'], + selectData = GetBalanceData, +>( + parameters_: UseBalanceParameters = {}, +): UseBalanceReturnType { + const parameters = computed(() => deepUnref(parameters_)) + + const config = useConfig(parameters) + const configChainId = useChainId({ config }) + + const queryOptions = computed(() => { + const { + address, + chainId = configChainId.value, + query = {}, + } = parameters.value + const options = getBalanceQueryOptions(config, { + ...parameters.value, + chainId, + }) + const enabled = Boolean(address && (query.enabled ?? true)) + return { ...query, ...options, enabled } + }) + + return useQuery(queryOptions as any) as UseBalanceReturnType +} diff --git a/wagmi-project/packages/vue/src/composables/useBlockNumber.test-d.ts b/wagmi-project/packages/vue/src/composables/useBlockNumber.test-d.ts new file mode 100644 index 0000000000..255a1e02e8 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useBlockNumber.test-d.ts @@ -0,0 +1,65 @@ +import { http, createConfig, webSocket } from '@wagmi/core' +import { mainnet, optimism } from '@wagmi/core/chains' +import { expectTypeOf, test } from 'vitest' + +import { useBlockNumber } from './useBlockNumber.js' + +test('select data', () => { + const result = useBlockNumber({ + query: { + select(data) { + expectTypeOf(data).toEqualTypeOf() + return data?.toString() + }, + }, + }) + expectTypeOf(result.data.value).toEqualTypeOf() +}) + +test('differing transports', () => { + const config = createConfig({ + chains: [mainnet, optimism], + transports: { + [mainnet.id]: http(), + [optimism.id]: webSocket(), + }, + }) + + useBlockNumber({ + config, + watch: { + poll: false, + }, + }) + + useBlockNumber({ + config, + chainId: mainnet.id, + watch: { + poll: true, + }, + }) + useBlockNumber({ + config, + chainId: mainnet.id, + watch: { + // @ts-expect-error + poll: false, + }, + }) + + useBlockNumber({ + config, + chainId: optimism.id, + watch: { + poll: true, + }, + }) + useBlockNumber({ + config, + chainId: optimism.id, + watch: { + poll: false, + }, + }) +}) diff --git a/wagmi-project/packages/vue/src/composables/useBlockNumber.test.ts b/wagmi-project/packages/vue/src/composables/useBlockNumber.test.ts new file mode 100644 index 0000000000..68e7e6241c --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useBlockNumber.test.ts @@ -0,0 +1,65 @@ +import { config, testClient } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { expect, test } from 'vitest' +import { ref } from 'vue' +import { useBlockNumber } from './useBlockNumber.js' + +test('default', async () => { + await testClient.mainnet.resetFork() + + const [blockNumberQuery] = renderComposable(() => useBlockNumber()) + + await waitFor(blockNumberQuery.status, (status) => status === 'success') + + expect(blockNumberQuery.data.value).toMatchInlineSnapshot('19258213n') +}) + +test('parameters: chainId', async () => { + config.setState((state) => ({ ...state, chainId: config.chains[0].id })) + + const [blockNumberQuery] = renderComposable(() => useBlockNumber()) + + await waitFor(blockNumberQuery.status, (status) => status === 'success') + expect(blockNumberQuery.data.value).toBeTypeOf('bigint') + + config.setState((state) => ({ ...state, chainId: config.chains[2].id })) + + await waitFor(blockNumberQuery.status, (status) => status === 'success') + expect(blockNumberQuery.data.value).toBeTypeOf('bigint') +}) + +test('parameters: watch', async () => { + const [blockNumberQuery] = renderComposable(() => + useBlockNumber({ watch: true }), + ) + + await waitFor(blockNumberQuery.status, (status) => status === 'success') + + const blockNumber = blockNumberQuery.data.value! + await testClient.mainnet.mine({ blocks: 1 }) + + await waitFor(blockNumberQuery.data, (data) => data === blockNumber + 1n) +}) + +test('parameters: watch (reactive)', async () => { + const watch = ref(true) + + const [blockNumberQuery] = renderComposable(() => useBlockNumber({ watch })) + + await waitFor(blockNumberQuery.status, (status) => status === 'success') + + const blockNumber = blockNumberQuery.data.value! + + await testClient.mainnet.mine({ blocks: 1 }) + await waitFor(blockNumberQuery.data, (data) => data === blockNumber + 1n) + + await testClient.mainnet.mine({ blocks: 1 }) + await waitFor(blockNumberQuery.data, (data) => data === blockNumber + 2n) + + watch.value = false + + await testClient.mainnet.mine({ blocks: 1 }) + await waitFor(blockNumberQuery.data, (data) => data === blockNumber + 2n, { + timeout: 1_000, + }) +}) diff --git a/wagmi-project/packages/vue/src/composables/useBlockNumber.ts b/wagmi-project/packages/vue/src/composables/useBlockNumber.ts new file mode 100644 index 0000000000..aadf04fb25 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useBlockNumber.ts @@ -0,0 +1,120 @@ +import { useQueryClient } from '@tanstack/vue-query' +import type { + Config, + GetBlockNumberErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { + Compute, + UnionCompute, + UnionStrictOmit, +} from '@wagmi/core/internal' +import { + type GetBlockNumberData, + type GetBlockNumberOptions, + type GetBlockNumberQueryFnData, + type GetBlockNumberQueryKey, + getBlockNumberQueryOptions, +} from '@wagmi/core/query' +import { computed } from 'vue' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import type { DeepMaybeRef, DeepUnwrapRef } from '../types/ref.js' +import { deepUnref } from '../utils/cloneDeep.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' +import { + type UseWatchBlockNumberParameters, + useWatchBlockNumber, +} from './useWatchBlockNumber.js' + +export type UseBlockNumberParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetBlockNumberData, +> = Compute< + DeepMaybeRef< + GetBlockNumberOptions & + ConfigParameter & + QueryParameter< + GetBlockNumberQueryFnData, + GetBlockNumberErrorType, + selectData, + GetBlockNumberQueryKey + > & { + watch?: + | boolean + | UnionCompute< + UnionStrictOmit< + DeepUnwrapRef>, + 'chainId' | 'config' | 'onBlockNumber' | 'onError' + > + > + | undefined + } + > +> + +export type UseBlockNumberReturnType = + UseQueryReturnType + +/** https://wagmi.sh/vue/api/composables/useBlockNumber */ +export function useBlockNumber< + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetBlockNumberData, +>( + parameters_: UseBlockNumberParameters = {}, +): UseBlockNumberReturnType { + const parameters = computed(() => deepUnref(parameters_)) + + const config = useConfig(parameters) + const queryClient = useQueryClient() + const configChainId = useChainId({ config }) + + const queryOptions = computed(() => { + const { + chainId = configChainId.value, + query = {}, + watch: _, + ...rest + } = parameters.value + const options = getBlockNumberQueryOptions(config, { + ...deepUnref(rest), + chainId, + }) + return { + ...query, + ...options, + } + }) + + const watchBlockNumberArgs = computed(() => { + const { + config, + chainId = configChainId.value, + query, + watch, + } = parameters.value + return { + ...({ + config, + chainId, + ...(typeof watch === 'object' ? watch : {}), + } as UseWatchBlockNumberParameters), + enabled: + (query?.enabled ?? true) && + (typeof watch === 'object' ? watch.enabled : watch), + onBlockNumber(blockNumber) { + queryClient.setQueryData(queryOptions.value.queryKey, blockNumber) + }, + } satisfies UseWatchBlockNumberParameters + }) + + useWatchBlockNumber(watchBlockNumberArgs) + + return useQuery(queryOptions as any) as UseBlockNumberReturnType +} diff --git a/wagmi-project/packages/vue/src/composables/useBytecode.test-d.ts b/wagmi-project/packages/vue/src/composables/useBytecode.test-d.ts new file mode 100644 index 0000000000..16fb3a36ff --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useBytecode.test-d.ts @@ -0,0 +1,16 @@ +import type { Hex } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { useBytecode } from './useBytecode.js' + +test('select data', () => { + const result = useBytecode({ + query: { + select(data) { + expectTypeOf(data).toEqualTypeOf() + return data + }, + }, + }) + expectTypeOf(result.data.value).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/vue/src/composables/useBytecode.test.ts b/wagmi-project/packages/vue/src/composables/useBytecode.test.ts new file mode 100644 index 0000000000..f98eccc8db --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useBytecode.test.ts @@ -0,0 +1,296 @@ +import { address, chain, wait } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { expect, test } from 'vitest' + +import { ref } from 'vue' +import { deepUnref } from '../utils/cloneDeep.js' +import { useBytecode } from './useBytecode.js' + +test('default', async () => { + const [result] = renderComposable(() => + useBytecode({ + address: address.wagmiMintExample, + }), + ) + + await waitFor(result.isSuccess) + + expect(deepUnref(result)).toMatchInlineSnapshot(` + { + "data": "0x608060405234801561001057600080fd5b50600436106101005760003560e01c80636352211e11610097578063a22cb46511610066578063a22cb46514610215578063b88d4fde14610228578063c87b56dd1461023b578063e985e9c51461024e57600080fd5b80636352211e146101d457806370a08231146101e757806395d89b41146101fa578063a0712d681461020257600080fd5b80631249c58b116100d35780631249c58b1461018f57806318160ddd1461019757806323b872dd146101ae57806342842e0e146101c157600080fd5b806301ffc9a71461010557806306fdde031461012d578063081812fc14610142578063095ea7b31461017a575b600080fd5b61011861011336600461178f565b610297565b60405190151581526020015b60405180910390f35b61013561037c565b6040516101249190611829565b61015561015036600461183c565b61040e565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610124565b61018d61018836600461187e565b6104d3565b005b61018d61062b565b6101a060065481565b604051908152602001610124565b61018d6101bc3660046118a8565b61067d565b61018d6101cf3660046118a8565b610704565b6101556101e236600461183c565b61071f565b6101a06101f53660046118e4565b6107b7565b61013561086b565b61018d61021036600461183c565b61087a565b61018d6102233660046118ff565b610902565b61018d61023636600461196a565b610911565b61013561024936600461183c565b61099f565b61011861025c366004611a64565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260056020908152604080832093909416825291909152205460ff1690565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd00000000000000000000000000000000000000000000000000000000148061032a57507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b8061037657507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b60606000805461038b90611a97565b80601f01602080910402602001604051908101604052809291908181526020018280546103b790611a97565b80156104045780601f106103d957610100808354040283529160200191610404565b820191906000526020600020905b8154815290600101906020018083116103e757829003601f168201915b5050505050905090565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff166104aa5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e000000000000000000000000000000000000000060648201526084015b60405180910390fd5b5060009081526004602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60006104de8261071f565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036105815760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f720000000000000000000000000000000000000000000000000000000000000060648201526084016104a1565b3373ffffffffffffffffffffffffffffffffffffffff821614806105aa57506105aa813361025c565b61061c5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c000000000000000060648201526084016104a1565b6106268383610b07565b505050565b6007545b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff16156106615760010161062f565b61066b3382610ba7565b60068054600190810190915501600755565b6106873382610bc1565b6106f95760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656400000000000000000000000000000060648201526084016104a1565b610626838383610d17565b61062683838360405180602001604052806000815250610911565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff16806103765760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201527f656e7420746f6b656e000000000000000000000000000000000000000000000060648201526084016104a1565b600073ffffffffffffffffffffffffffffffffffffffff82166108425760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a6560448201527f726f20616464726573730000000000000000000000000000000000000000000060648201526084016104a1565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205490565b60606001805461038b90611a97565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff16156108ec5760405162461bcd60e51b815260206004820152601160248201527f546f6b656e2049442069732074616b656e00000000000000000000000000000060448201526064016104a1565b6108f63382610ba7565b50600680546001019055565b61090d338383610f4a565b5050565b61091b3383610bc1565b61098d5760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656400000000000000000000000000000060648201526084016104a1565b6109998484848461105d565b50505050565b6040517f666f726567726f756e64000000000000000000000000000000000000000000006020820152602a810182905260609060009061016890604a016040516020818303038152906040528051906020012060001c6109ff9190611b19565b6040517f6261636b67726f756e64000000000000000000000000000000000000000000006020820152602a810185905290915060009061016890604a016040516020818303038152906040528051906020012060001c610a5f9190611b19565b90506000610aba610a6f866110e6565b610aa9610a7b866110e6565b610a84866110e6565b604051602001610a95929190611b2d565b60405160208183030381529060405261121b565b604051602001610a959291906125ba565b9050600081604051602001610acf919061268b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529695505050505050565b600081815260046020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091558190610b618261071f565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b61090d82826040518060200160405280600081525061136e565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff16610c585760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e000000000000000000000000000000000000000060648201526084016104a1565b6000610c638361071f565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480610cd1575073ffffffffffffffffffffffffffffffffffffffff80821660009081526005602090815260408083209388168352929052205460ff165b80610d0f57508373ffffffffffffffffffffffffffffffffffffffff16610cf78461040e565b73ffffffffffffffffffffffffffffffffffffffff16145b949350505050565b8273ffffffffffffffffffffffffffffffffffffffff16610d378261071f565b73ffffffffffffffffffffffffffffffffffffffff1614610dc05760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201527f6f776e657200000000000000000000000000000000000000000000000000000060648201526084016104a1565b73ffffffffffffffffffffffffffffffffffffffff8216610e485760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016104a1565b610e53600082610b07565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120805460019290610e899084906126ff565b909155505073ffffffffffffffffffffffffffffffffffffffff82166000908152600360205260408120805460019290610ec4908490612716565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610fc55760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016104a1565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526005602090815260408083209487168084529482529182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b611068848484610d17565b611074848484846113f7565b6109995760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016104a1565b60608160000361112957505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611153578061113d8161272e565b915061114c9050600a83612766565b915061112d565b60008167ffffffffffffffff81111561116e5761116e61193b565b6040519080825280601f01601f191660200182016040528015611198576020820181803683370190505b5090505b8415610d0f576111ad6001836126ff565b91506111ba600a86611b19565b6111c5906030612716565b60f81b8183815181106111da576111da61277a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611214600a86612766565b945061119c565b6060815160000361123a57505060408051602081019091526000815290565b600060405180606001604052806040815260200161284d60409139905060006003845160026112699190612716565b6112739190612766565b61127e9060046127a9565b67ffffffffffffffff8111156112965761129661193b565b6040519080825280601f01601f1916602001820160405280156112c0576020820181803683370190505b509050600182016020820185865187015b8082101561132c576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f81168501518453506001830192506112d1565b5050600386510660018114611348576002811461135b57611363565b603d6001830353603d6002830353611363565b603d60018303535b509195945050505050565b61137883836115d0565b61138560008484846113f7565b6106265760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016104a1565b600073ffffffffffffffffffffffffffffffffffffffff84163b156115c5576040517f150b7a0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063150b7a029061146e9033908990889088906004016127e6565b6020604051808303816000875af19250505080156114c7575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526114c49181019061282f565b60015b61157a573d8080156114f5576040519150601f19603f3d011682016040523d82523d6000602084013e6114fa565b606091505b5080516000036115725760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016104a1565b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a0200000000000000000000000000000000000000000000000000000000149050610d0f565b506001949350505050565b73ffffffffffffffffffffffffffffffffffffffff82166116335760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016104a1565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff16156116a55760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016104a1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526003602052604081208054600192906116db908490612716565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b7fffffffff000000000000000000000000000000000000000000000000000000008116811461178c57600080fd5b50565b6000602082840312156117a157600080fd5b81356117ac8161175e565b9392505050565b60005b838110156117ce5781810151838201526020016117b6565b838111156109995750506000910152565b600081518084526117f78160208601602086016117b3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006117ac60208301846117df565b60006020828403121561184e57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461187957600080fd5b919050565b6000806040838503121561189157600080fd5b61189a83611855565b946020939093013593505050565b6000806000606084860312156118bd57600080fd5b6118c684611855565b92506118d460208501611855565b9150604084013590509250925092565b6000602082840312156118f657600080fd5b6117ac82611855565b6000806040838503121561191257600080fd5b61191b83611855565b91506020830135801515811461193057600080fd5b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000806080858703121561198057600080fd5b61198985611855565b935061199760208601611855565b925060408501359150606085013567ffffffffffffffff808211156119bb57600080fd5b818701915087601f8301126119cf57600080fd5b8135818111156119e1576119e161193b565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715611a2757611a2761193b565b816040528281528a6020848701011115611a4057600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b60008060408385031215611a7757600080fd5b611a8083611855565b9150611a8e60208401611855565b90509250929050565b600181811c90821680611aab57607f821691505b602082108103611ae4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611b2857611b28611aea565b500690565b7f3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323081527f30302f737667222077696474683d223130323422206865696768743d2231303260208201527f34222066696c6c3d226e6f6e65223e3c706174682066696c6c3d2268736c2800604082015260008351611bb181605f8501602088016117b3565b7f2c20313030252c20313025292220643d224d3020306831303234763130323448605f918401918201527f307a22202f3e3c672066696c6c3d2268736c2800000000000000000000000000607f8201528351611c148160928401602088016117b3565b7f2c20313030252c2039302529223e3c7061746820643d224d393033203433372e609292909101918201527f35633020392e3131332d372e3338382031362e352d31362e352031362e35732d60b28201527f31362e352d372e3338372d31362e352d31362e3520372e3338382d31362e352060d28201527f31362e352d31362e352031362e3520372e3338372031362e352031362e357a4d60f28201527f3639382e3532392035363663362e39323120302031322e35332d352e353936206101128201527f31322e35332d31322e35762d353063302d362e39303420352e3630392d31322e6101328201527f352031322e3532392d31322e356832352e30353963362e393220302031322e356101528201527f323920352e3539362031322e3532392031322e35763530633020362e393034206101728201527f352e3630392031322e352031322e35332031322e357331322e3532392d352e356101928201527f39362031322e3532392d31322e35762d353063302d362e39303420352e3630396101b28201527f2d31322e352031322e35332d31322e356832352e30353963362e3932203020316101d28201527f322e35323920352e3539362031322e3532392031322e35763530633020362e396101f28201527f303420352e3630392031322e352031322e3532392031322e356833372e3538396102128201527f63362e393220302031322e3532392d352e3539362031322e3532392d31322e356102328201527f762d373563302d362e3930342d352e3630392d31322e352d31322e3532392d316102528201527f322e35732d31322e353320352e3539362d31322e35332031322e357635362e326102728201527f3561362e32363420362e3236342030203120312d31322e3532392030563437386102928201527f2e3563302d362e3930342d352e3630392d31322e352d31322e35332d31322e356102b28201527f483639382e353239632d362e393220302d31322e35323920352e3539362d31326102d28201527f2e3532392031322e35763735633020362e39303420352e3630392031322e35206102f28201527f31322e3532392031322e357a22202f3e3c7061746820643d224d3135372e36356103128201527f3520353431632d362e39333220302d31322e3535322d352e3539362d31322e356103328201527f35322d31322e35762d353063302d362e3930342d352e3631392d31322e352d316103528201527f322e3535312d31322e3553313230203437312e35393620313230203437382e356103728201527f763735633020362e39303420352e36322031322e352031322e3535322031322e6103928201527f35683135302e363263362e39333320302031322e3535322d352e3539362031326103b28201527f2e3535322d31322e35762d353063302d362e39303420352e3631392d31322e356103d28201527f2031322e3535322d31322e35683134342e33343563332e343635203020362e326103f28201527f373620322e37393820362e32373620362e3235732d322e38313120362e32352d6104128201527f362e32373620362e3235483332302e383238632d362e39333320302d31322e356104328201527f353220352e3539362d31322e3535322031322e357633372e35633020362e39306104528201527f3420352e3631392031322e352031322e3535322031322e35683135302e3632636104728201527f362e39333320302031322e3535322d352e3539362031322e3535322d31322e356104928201527f762d373563302d362e3930342d352e3631392d31322e352d31322e3535322d316104b28201527f322e35483238332e313732632d362e39333220302d31322e35353120352e35396104d28201527f362d31322e3535312031322e35763530633020362e3930342d352e36313920316104f28201527f322e352d31322e3535322031322e35682d32352e313033632d362e39333320306105128201527f2d31322e3535322d352e3539362d31322e3535322d31322e35762d353063302d6105328201527f362e3930342d352e36322d31322e352d31322e3535322d31322e35732d31322e6105528201527f35353220352e3539362d31322e3535322031322e35763530633020362e3930346105728201527f2d352e3631392031322e352d31322e3535312031322e35682d32352e3130347a6105928201527f6d3330312e3234322d362e3235633020332e3435322d322e38313120362e32356105b28201527f2d362e32373620362e3235483333392e363535632d332e34363520302d362e326105d28201527f37362d322e3739382d362e3237362d362e323573322e3831312d362e323520366105f28201527f2e3237362d362e3235683131322e39363663332e343635203020362e323736206106128201527f322e37393820362e32373620362e32357a4d343937203535332e3831386330206106328201527f362e39323920352e3632382031322e3534362031322e3537312031322e3534366106528201527f6831333261362e323820362e323820302030203120362e32383620362e3237326106728201527f20362e323820362e32382030203020312d362e32383620362e323733682d31336106928201527f32632d362e39343320302d31322e35373120352e3631362d31322e35373120316106b28201527f322e3534364131322e35362031322e3536203020302030203530392e353731206106d28201527f363034683135302e38353863362e39343320302031322e3537312d352e3631366106f28201527f2031322e3537312d31322e353435762d3131322e393163302d362e3932382d356107128201527f2e3632382d31322e3534352d31322e3537312d31322e353435483530392e35376107328201527f31632d362e39343320302d31322e35373120352e3631372d31322e35373120316107528201527f322e3534357637352e3237337a6d33372e3731342d36322e373237632d362e396107728201527f343320302d31322e35373120352e3631372d31322e3537312031322e353435766107928201527f32352e303931633020362e39323920352e3632382031322e3534362031322e356107b28201527f37312031322e353436683130302e35373263362e39343320302031322e3537316107d28201527f2d352e3631372031322e3537312d31322e353436762d32352e30393163302d366107f28201527f2e3932382d352e3632382d31322e3534352d31322e3537312d31322e353435486108128201527f3533342e3731347a222066696c6c2d72756c653d226576656e6f646422202f3e6108328201527f3c2f673e3c2f7376673e0000000000000000000000000000000000000000000061085282015261085c01949350505050565b7f7b226e616d65223a20227761676d6920230000000000000000000000000000008152600083516125f28160118501602088016117b3565b7f222c2022696d616765223a2022646174613a696d6167652f7376672b786d6c3b6011918401918201527f6261736536342c00000000000000000000000000000000000000000000000000603182015283516126558160388401602088016117b3565b7f227d00000000000000000000000000000000000000000000000000000000000060389290910191820152603a01949350505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c0000008152600082516126c381601d8501602087016117b3565b91909101601d0192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015612711576127116126d0565b500390565b60008219821115612729576127296126d0565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361275f5761275f6126d0565b5060010190565b60008261277557612775611aea565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156127e1576127e16126d0565b500290565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261282560808301846117df565b9695505050505050565b60006020828403121561284157600080fd5b81516117ac8161175e56fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa26469706673582212201665a4f9111990d7529375848d3fd02c0121091a940da59e763eba826e7b077064736f6c634300080d0033", + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getBytecode", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + "suspense": [Function], + } + `) +}) + +test('parameters: blockNumber', async () => { + const [result] = renderComposable(() => + useBytecode({ + address: address.wagmiMintExample, + blockNumber: 15564163n, + }), + ) + + await waitFor(result.isSuccess) + + expect(deepUnref(result)).toMatchInlineSnapshot(` + { + "data": null, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getBytecode", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "blockNumber": 15564163n, + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + "suspense": [Function], + } + `) +}) + +test('parameters: blockTag', async () => { + const [result] = renderComposable(() => + useBytecode({ + address: address.wagmiMintExample, + blockTag: 'earliest', + }), + ) + + await waitFor(result.isSuccess) + + expect(deepUnref(result)).toMatchInlineSnapshot(` + { + "data": null, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getBytecode", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "blockTag": "earliest", + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + "suspense": [Function], + } + `) +}) + +test('parameters: chainId', async () => { + const [result] = renderComposable(() => + useBytecode({ + address: address.wagmiMintExample, + chainId: chain.optimism.id, + }), + ) + + await waitFor(result.isSuccess) + + expect(deepUnref(result)).toMatchInlineSnapshot(` + { + "data": null, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getBytecode", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "chainId": 10, + }, + ], + "refetch": [Function], + "status": "success", + "suspense": [Function], + } + `) +}) + +test('behavior: address: undefined -> defined', async () => { + const contractAddress = ref() + + const [result] = renderComposable(() => + useBytecode({ address: contractAddress }), + ) + + await wait(100) + expect(result.fetchStatus.value).toBe('idle') + + expect(deepUnref(result)).toMatchInlineSnapshot(` + { + "data": undefined, + "dataUpdatedAt": 0, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": false, + "isFetchedAfterMount": false, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": true, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": false, + "queryKey": [ + "getBytecode", + { + "address": undefined, + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "pending", + "suspense": [Function], + } + `) + + contractAddress.value = address.wagmiMintExample + + await waitFor(result.isSuccess) + + expect(deepUnref(result)).toMatchInlineSnapshot(` + { + "data": "0x608060405234801561001057600080fd5b50600436106101005760003560e01c80636352211e11610097578063a22cb46511610066578063a22cb46514610215578063b88d4fde14610228578063c87b56dd1461023b578063e985e9c51461024e57600080fd5b80636352211e146101d457806370a08231146101e757806395d89b41146101fa578063a0712d681461020257600080fd5b80631249c58b116100d35780631249c58b1461018f57806318160ddd1461019757806323b872dd146101ae57806342842e0e146101c157600080fd5b806301ffc9a71461010557806306fdde031461012d578063081812fc14610142578063095ea7b31461017a575b600080fd5b61011861011336600461178f565b610297565b60405190151581526020015b60405180910390f35b61013561037c565b6040516101249190611829565b61015561015036600461183c565b61040e565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610124565b61018d61018836600461187e565b6104d3565b005b61018d61062b565b6101a060065481565b604051908152602001610124565b61018d6101bc3660046118a8565b61067d565b61018d6101cf3660046118a8565b610704565b6101556101e236600461183c565b61071f565b6101a06101f53660046118e4565b6107b7565b61013561086b565b61018d61021036600461183c565b61087a565b61018d6102233660046118ff565b610902565b61018d61023636600461196a565b610911565b61013561024936600461183c565b61099f565b61011861025c366004611a64565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260056020908152604080832093909416825291909152205460ff1690565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd00000000000000000000000000000000000000000000000000000000148061032a57507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b8061037657507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b60606000805461038b90611a97565b80601f01602080910402602001604051908101604052809291908181526020018280546103b790611a97565b80156104045780601f106103d957610100808354040283529160200191610404565b820191906000526020600020905b8154815290600101906020018083116103e757829003601f168201915b5050505050905090565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff166104aa5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e000000000000000000000000000000000000000060648201526084015b60405180910390fd5b5060009081526004602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60006104de8261071f565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036105815760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f720000000000000000000000000000000000000000000000000000000000000060648201526084016104a1565b3373ffffffffffffffffffffffffffffffffffffffff821614806105aa57506105aa813361025c565b61061c5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c000000000000000060648201526084016104a1565b6106268383610b07565b505050565b6007545b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff16156106615760010161062f565b61066b3382610ba7565b60068054600190810190915501600755565b6106873382610bc1565b6106f95760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656400000000000000000000000000000060648201526084016104a1565b610626838383610d17565b61062683838360405180602001604052806000815250610911565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff16806103765760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201527f656e7420746f6b656e000000000000000000000000000000000000000000000060648201526084016104a1565b600073ffffffffffffffffffffffffffffffffffffffff82166108425760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a6560448201527f726f20616464726573730000000000000000000000000000000000000000000060648201526084016104a1565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205490565b60606001805461038b90611a97565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff16156108ec5760405162461bcd60e51b815260206004820152601160248201527f546f6b656e2049442069732074616b656e00000000000000000000000000000060448201526064016104a1565b6108f63382610ba7565b50600680546001019055565b61090d338383610f4a565b5050565b61091b3383610bc1565b61098d5760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656400000000000000000000000000000060648201526084016104a1565b6109998484848461105d565b50505050565b6040517f666f726567726f756e64000000000000000000000000000000000000000000006020820152602a810182905260609060009061016890604a016040516020818303038152906040528051906020012060001c6109ff9190611b19565b6040517f6261636b67726f756e64000000000000000000000000000000000000000000006020820152602a810185905290915060009061016890604a016040516020818303038152906040528051906020012060001c610a5f9190611b19565b90506000610aba610a6f866110e6565b610aa9610a7b866110e6565b610a84866110e6565b604051602001610a95929190611b2d565b60405160208183030381529060405261121b565b604051602001610a959291906125ba565b9050600081604051602001610acf919061268b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529695505050505050565b600081815260046020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091558190610b618261071f565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b61090d82826040518060200160405280600081525061136e565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff16610c585760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e000000000000000000000000000000000000000060648201526084016104a1565b6000610c638361071f565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480610cd1575073ffffffffffffffffffffffffffffffffffffffff80821660009081526005602090815260408083209388168352929052205460ff165b80610d0f57508373ffffffffffffffffffffffffffffffffffffffff16610cf78461040e565b73ffffffffffffffffffffffffffffffffffffffff16145b949350505050565b8273ffffffffffffffffffffffffffffffffffffffff16610d378261071f565b73ffffffffffffffffffffffffffffffffffffffff1614610dc05760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201527f6f776e657200000000000000000000000000000000000000000000000000000060648201526084016104a1565b73ffffffffffffffffffffffffffffffffffffffff8216610e485760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016104a1565b610e53600082610b07565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120805460019290610e899084906126ff565b909155505073ffffffffffffffffffffffffffffffffffffffff82166000908152600360205260408120805460019290610ec4908490612716565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610fc55760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016104a1565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526005602090815260408083209487168084529482529182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b611068848484610d17565b611074848484846113f7565b6109995760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016104a1565b60608160000361112957505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611153578061113d8161272e565b915061114c9050600a83612766565b915061112d565b60008167ffffffffffffffff81111561116e5761116e61193b565b6040519080825280601f01601f191660200182016040528015611198576020820181803683370190505b5090505b8415610d0f576111ad6001836126ff565b91506111ba600a86611b19565b6111c5906030612716565b60f81b8183815181106111da576111da61277a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611214600a86612766565b945061119c565b6060815160000361123a57505060408051602081019091526000815290565b600060405180606001604052806040815260200161284d60409139905060006003845160026112699190612716565b6112739190612766565b61127e9060046127a9565b67ffffffffffffffff8111156112965761129661193b565b6040519080825280601f01601f1916602001820160405280156112c0576020820181803683370190505b509050600182016020820185865187015b8082101561132c576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f81168501518453506001830192506112d1565b5050600386510660018114611348576002811461135b57611363565b603d6001830353603d6002830353611363565b603d60018303535b509195945050505050565b61137883836115d0565b61138560008484846113f7565b6106265760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016104a1565b600073ffffffffffffffffffffffffffffffffffffffff84163b156115c5576040517f150b7a0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063150b7a029061146e9033908990889088906004016127e6565b6020604051808303816000875af19250505080156114c7575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526114c49181019061282f565b60015b61157a573d8080156114f5576040519150601f19603f3d011682016040523d82523d6000602084013e6114fa565b606091505b5080516000036115725760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016104a1565b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a0200000000000000000000000000000000000000000000000000000000149050610d0f565b506001949350505050565b73ffffffffffffffffffffffffffffffffffffffff82166116335760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016104a1565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff16156116a55760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016104a1565b73ffffffffffffffffffffffffffffffffffffffff821660009081526003602052604081208054600192906116db908490612716565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b7fffffffff000000000000000000000000000000000000000000000000000000008116811461178c57600080fd5b50565b6000602082840312156117a157600080fd5b81356117ac8161175e565b9392505050565b60005b838110156117ce5781810151838201526020016117b6565b838111156109995750506000910152565b600081518084526117f78160208601602086016117b3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006117ac60208301846117df565b60006020828403121561184e57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461187957600080fd5b919050565b6000806040838503121561189157600080fd5b61189a83611855565b946020939093013593505050565b6000806000606084860312156118bd57600080fd5b6118c684611855565b92506118d460208501611855565b9150604084013590509250925092565b6000602082840312156118f657600080fd5b6117ac82611855565b6000806040838503121561191257600080fd5b61191b83611855565b91506020830135801515811461193057600080fd5b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000806080858703121561198057600080fd5b61198985611855565b935061199760208601611855565b925060408501359150606085013567ffffffffffffffff808211156119bb57600080fd5b818701915087601f8301126119cf57600080fd5b8135818111156119e1576119e161193b565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715611a2757611a2761193b565b816040528281528a6020848701011115611a4057600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b60008060408385031215611a7757600080fd5b611a8083611855565b9150611a8e60208401611855565b90509250929050565b600181811c90821680611aab57607f821691505b602082108103611ae4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611b2857611b28611aea565b500690565b7f3c73766720786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323081527f30302f737667222077696474683d223130323422206865696768743d2231303260208201527f34222066696c6c3d226e6f6e65223e3c706174682066696c6c3d2268736c2800604082015260008351611bb181605f8501602088016117b3565b7f2c20313030252c20313025292220643d224d3020306831303234763130323448605f918401918201527f307a22202f3e3c672066696c6c3d2268736c2800000000000000000000000000607f8201528351611c148160928401602088016117b3565b7f2c20313030252c2039302529223e3c7061746820643d224d393033203433372e609292909101918201527f35633020392e3131332d372e3338382031362e352d31362e352031362e35732d60b28201527f31362e352d372e3338372d31362e352d31362e3520372e3338382d31362e352060d28201527f31362e352d31362e352031362e3520372e3338372031362e352031362e357a4d60f28201527f3639382e3532392035363663362e39323120302031322e35332d352e353936206101128201527f31322e35332d31322e35762d353063302d362e39303420352e3630392d31322e6101328201527f352031322e3532392d31322e356832352e30353963362e393220302031322e356101528201527f323920352e3539362031322e3532392031322e35763530633020362e393034206101728201527f352e3630392031322e352031322e35332031322e357331322e3532392d352e356101928201527f39362031322e3532392d31322e35762d353063302d362e39303420352e3630396101b28201527f2d31322e352031322e35332d31322e356832352e30353963362e3932203020316101d28201527f322e35323920352e3539362031322e3532392031322e35763530633020362e396101f28201527f303420352e3630392031322e352031322e3532392031322e356833372e3538396102128201527f63362e393220302031322e3532392d352e3539362031322e3532392d31322e356102328201527f762d373563302d362e3930342d352e3630392d31322e352d31322e3532392d316102528201527f322e35732d31322e353320352e3539362d31322e35332031322e357635362e326102728201527f3561362e32363420362e3236342030203120312d31322e3532392030563437386102928201527f2e3563302d362e3930342d352e3630392d31322e352d31322e35332d31322e356102b28201527f483639382e353239632d362e393220302d31322e35323920352e3539362d31326102d28201527f2e3532392031322e35763735633020362e39303420352e3630392031322e35206102f28201527f31322e3532392031322e357a22202f3e3c7061746820643d224d3135372e36356103128201527f3520353431632d362e39333220302d31322e3535322d352e3539362d31322e356103328201527f35322d31322e35762d353063302d362e3930342d352e3631392d31322e352d316103528201527f322e3535312d31322e3553313230203437312e35393620313230203437382e356103728201527f763735633020362e39303420352e36322031322e352031322e3535322031322e6103928201527f35683135302e363263362e39333320302031322e3535322d352e3539362031326103b28201527f2e3535322d31322e35762d353063302d362e39303420352e3631392d31322e356103d28201527f2031322e3535322d31322e35683134342e33343563332e343635203020362e326103f28201527f373620322e37393820362e32373620362e3235732d322e38313120362e32352d6104128201527f362e32373620362e3235483332302e383238632d362e39333320302d31322e356104328201527f353220352e3539362d31322e3535322031322e357633372e35633020362e39306104528201527f3420352e3631392031322e352031322e3535322031322e35683135302e3632636104728201527f362e39333320302031322e3535322d352e3539362031322e3535322d31322e356104928201527f762d373563302d362e3930342d352e3631392d31322e352d31322e3535322d316104b28201527f322e35483238332e313732632d362e39333220302d31322e35353120352e35396104d28201527f362d31322e3535312031322e35763530633020362e3930342d352e36313920316104f28201527f322e352d31322e3535322031322e35682d32352e313033632d362e39333320306105128201527f2d31322e3535322d352e3539362d31322e3535322d31322e35762d353063302d6105328201527f362e3930342d352e36322d31322e352d31322e3535322d31322e35732d31322e6105528201527f35353220352e3539362d31322e3535322031322e35763530633020362e3930346105728201527f2d352e3631392031322e352d31322e3535312031322e35682d32352e3130347a6105928201527f6d3330312e3234322d362e3235633020332e3435322d322e38313120362e32356105b28201527f2d362e32373620362e3235483333392e363535632d332e34363520302d362e326105d28201527f37362d322e3739382d362e3237362d362e323573322e3831312d362e323520366105f28201527f2e3237362d362e3235683131322e39363663332e343635203020362e323736206106128201527f322e37393820362e32373620362e32357a4d343937203535332e3831386330206106328201527f362e39323920352e3632382031322e3534362031322e3537312031322e3534366106528201527f6831333261362e323820362e323820302030203120362e32383620362e3237326106728201527f20362e323820362e32382030203020312d362e32383620362e323733682d31336106928201527f32632d362e39343320302d31322e35373120352e3631362d31322e35373120316106b28201527f322e3534364131322e35362031322e3536203020302030203530392e353731206106d28201527f363034683135302e38353863362e39343320302031322e3537312d352e3631366106f28201527f2031322e3537312d31322e353435762d3131322e393163302d362e3932382d356107128201527f2e3632382d31322e3534352d31322e3537312d31322e353435483530392e35376107328201527f31632d362e39343320302d31322e35373120352e3631372d31322e35373120316107528201527f322e3534357637352e3237337a6d33372e3731342d36322e373237632d362e396107728201527f343320302d31322e35373120352e3631372d31322e3537312031322e353435766107928201527f32352e303931633020362e39323920352e3632382031322e3534362031322e356107b28201527f37312031322e353436683130302e35373263362e39343320302031322e3537316107d28201527f2d352e3631372031322e3537312d31322e353436762d32352e30393163302d366107f28201527f2e3932382d352e3632382d31322e3534352d31322e3537312d31322e353435486108128201527f3533342e3731347a222066696c6c2d72756c653d226576656e6f646422202f3e6108328201527f3c2f673e3c2f7376673e0000000000000000000000000000000000000000000061085282015261085c01949350505050565b7f7b226e616d65223a20227761676d6920230000000000000000000000000000008152600083516125f28160118501602088016117b3565b7f222c2022696d616765223a2022646174613a696d6167652f7376672b786d6c3b6011918401918201527f6261736536342c00000000000000000000000000000000000000000000000000603182015283516126558160388401602088016117b3565b7f227d00000000000000000000000000000000000000000000000000000000000060389290910191820152603a01949350505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c0000008152600082516126c381601d8501602087016117b3565b91909101601d0192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082821015612711576127116126d0565b500390565b60008219821115612729576127296126d0565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361275f5761275f6126d0565b5060010190565b60008261277557612775611aea565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156127e1576127e16126d0565b500290565b600073ffffffffffffffffffffffffffffffffffffffff80871683528086166020840152508360408301526080606083015261282560808301846117df565b9695505050505050565b60006020828403121561284157600080fd5b81516117ac8161175e56fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa26469706673582212201665a4f9111990d7529375848d3fd02c0121091a940da59e763eba826e7b077064736f6c634300080d0033", + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getBytecode", + { + "address": undefined, + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + "suspense": [Function], + } + `) +}) + +test('behavior: disabled when properties missing', async () => { + const [result] = renderComposable(() => useBytecode()) + + await wait(100) + expect(result.isPending.value).toBe(true) +}) diff --git a/wagmi-project/packages/vue/src/composables/useBytecode.ts b/wagmi-project/packages/vue/src/composables/useBytecode.ts new file mode 100644 index 0000000000..a697ff1a92 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useBytecode.ts @@ -0,0 +1,72 @@ +import type { + Config, + GetBytecodeErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetBytecodeData, + type GetBytecodeOptions, + type GetBytecodeQueryKey, + getBytecodeQueryOptions, +} from '@wagmi/core/query' +import type { GetBytecodeQueryFnData } from '@wagmi/core/query' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' + +import { computed } from 'vue' +import type { DeepMaybeRef } from '../types/ref.js' +import { deepUnref } from '../utils/cloneDeep.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseBytecodeParameters< + config extends Config = Config, + selectData = GetBytecodeData, +> = Compute< + DeepMaybeRef< + GetBytecodeOptions & + ConfigParameter & + QueryParameter< + GetBytecodeQueryFnData, + GetBytecodeErrorType, + selectData, + GetBytecodeQueryKey + > + > +> + +export type UseBytecodeReturnType = + UseQueryReturnType + +/** https://wagmi.sh/vue/api/hooks/useBytecode */ +export function useBytecode< + config extends Config = ResolvedRegister['config'], + selectData = GetBytecodeData, +>( + parameters_: UseBytecodeParameters = {}, +): UseBytecodeReturnType { + const parameters = computed(() => deepUnref(parameters_)) + + const config = useConfig(parameters) + const chainId = useChainId({ config }) + + const queryOptions = computed(() => { + const { + address: contractAddress, + chainId: parametersChainId, + query = {}, + } = parameters.value + + const options = getBytecodeQueryOptions(config, { + ...parameters.value, + address: contractAddress, + chainId: parametersChainId ?? chainId.value, + }) + const enabled = Boolean(contractAddress && (query.enabled ?? true)) + return { ...query, ...options, enabled } + }) + + return useQuery(queryOptions as any) as UseBytecodeReturnType +} diff --git a/wagmi-project/packages/vue/src/composables/useChainId.test-d.ts b/wagmi-project/packages/vue/src/composables/useChainId.test-d.ts new file mode 100644 index 0000000000..9f7d060c57 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useChainId.test-d.ts @@ -0,0 +1,14 @@ +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { useChainId } from './useChainId.js' + +test('default', () => { + const chainId = useChainId() + expectTypeOf(chainId.value).toEqualTypeOf() +}) + +test('parameters: config', () => { + const chainId = useChainId({ config }) + expectTypeOf(chainId.value).toEqualTypeOf<1 | 456 | 10>() +}) diff --git a/wagmi-project/packages/vue/src/composables/useChainId.test.ts b/wagmi-project/packages/vue/src/composables/useChainId.test.ts new file mode 100644 index 0000000000..0a14370fc2 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useChainId.test.ts @@ -0,0 +1,22 @@ +import { config } from '@wagmi/test' +import { renderComposable } from '@wagmi/test/vue' +import { expect, test } from 'vitest' + +import { useChainId } from './useChainId.js' + +test('default', () => { + const [chainId] = renderComposable(() => useChainId()) + + expect(chainId.value).toMatchInlineSnapshot('1') + + config.setState((x) => ({ ...x, chainId: 456 })) + + expect(chainId.value).toMatchInlineSnapshot('456') +}) + +test('parameters: config', () => { + const [chainId] = renderComposable(() => useChainId({ config }), { + attach() {}, + }) + expect(chainId.value).toBeDefined() +}) diff --git a/wagmi-project/packages/vue/src/composables/useChainId.ts b/wagmi-project/packages/vue/src/composables/useChainId.ts new file mode 100644 index 0000000000..f459857ca9 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useChainId.ts @@ -0,0 +1,35 @@ +import { + type Config, + type GetChainIdReturnType, + type ResolvedRegister, + getChainId, + watchChainId, +} from '@wagmi/core' +import { type Ref, onScopeDispose, readonly, ref } from 'vue' + +import type { ConfigParameter } from '../types/properties.js' +import { useConfig } from './useConfig.js' + +export type UseChainIdParameters = + ConfigParameter + +export type UseChainIdReturnType = Ref< + GetChainIdReturnType +> + +/** https://wagmi.sh/vue/api/composables/useChainId */ +export function useChainId( + parameters: UseChainIdParameters = {}, +): UseChainIdReturnType { + const config = useConfig(parameters) + + const chainId = ref(getChainId(config)) + const unsubscribe = watchChainId(config, { + onChange(data) { + chainId.value = data + }, + }) + onScopeDispose(() => unsubscribe()) + + return readonly(chainId) +} diff --git a/wagmi-project/packages/vue/src/composables/useChains.test.ts b/wagmi-project/packages/vue/src/composables/useChains.test.ts new file mode 100644 index 0000000000..4ef51405a9 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useChains.test.ts @@ -0,0 +1,16 @@ +import { config } from '@wagmi/test' +import { renderComposable } from '@wagmi/test/vue' +import { celo } from 'viem/chains' +import { expect, test } from 'vitest' + +import { useChains } from './useChains.js' + +test('default', async () => { + const [chains] = renderComposable(() => useChains()) + + expect(chains.value.length).toBe(3) + + config._internal.chains.setState((x) => [...x, celo]) + + expect(chains.value.length).toBe(4) +}) diff --git a/wagmi-project/packages/vue/src/composables/useChains.ts b/wagmi-project/packages/vue/src/composables/useChains.ts new file mode 100644 index 0000000000..6cbada538b --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useChains.ts @@ -0,0 +1,35 @@ +import { + type Config, + type GetChainsReturnType, + type ResolvedRegister, + getChains, +} from '@wagmi/core' +import { watchChains } from '@wagmi/core/internal' + +import { type Ref, onScopeDispose, readonly, ref } from 'vue' +import type { ConfigParameter } from '../types/properties.js' +import { useConfig } from './useConfig.js' + +export type UseChainsParameters = + ConfigParameter + +export type UseChainsReturnType = Ref< + GetChainsReturnType +> + +/** https://wagmi.sh/vue/api/composables/useChains */ +export function useChains( + parameters: UseChainsParameters = {}, +): UseChainsReturnType { + const config = useConfig(parameters) + + const chains = ref>(getChains(config)) + const unsubscribe = watchChains(config, { + onChange(data) { + chains.value = data as any + }, + }) + onScopeDispose(() => unsubscribe()) + + return readonly(chains) as UseChainsReturnType +} diff --git a/wagmi-project/packages/vue/src/composables/useClient.test-d.ts b/wagmi-project/packages/vue/src/composables/useClient.test-d.ts new file mode 100644 index 0000000000..3500f2a404 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useClient.test-d.ts @@ -0,0 +1,42 @@ +import { chain, config } from '@wagmi/test' +import type { Chain } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { useClient } from './useClient.js' + +test('default', () => { + const client = useClient({ config }) + expectTypeOf(client.value.chain).toEqualTypeOf< + (typeof config)['chains'][number] + >() + expectTypeOf(client.value.transport.type).toEqualTypeOf<'http'>() +}) + +test('parameters: chainId', () => { + const client = useClient({ + config, + chainId: chain.mainnet.id, + }) + expectTypeOf(client.value.chain).toEqualTypeOf() + expectTypeOf(client.value.chain).not.toEqualTypeOf() + expectTypeOf(client.value.transport.type).toEqualTypeOf<'http'>() +}) + +test('behavior: unconfigured chain', () => { + { + const client = useClient({ chainId: 123456 }) + if (client.value) { + expectTypeOf(client.value.chain).toEqualTypeOf() + expectTypeOf(client.value.transport.type).toEqualTypeOf() + } else { + expectTypeOf(client.value).toEqualTypeOf() + } + } + + const client = useClient({ + config, + // @ts-expect-error + chainId: 123456, + }) + expectTypeOf(client.value).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/vue/src/composables/useClient.test.ts b/wagmi-project/packages/vue/src/composables/useClient.test.ts new file mode 100644 index 0000000000..0d9d2325b2 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useClient.test.ts @@ -0,0 +1,41 @@ +import { switchChain } from '@wagmi/core' +import { config } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { expect, test } from 'vitest' +import { ref } from 'vue' + +import { useClient } from './useClient.js' + +test('default', async () => { + const [client] = renderComposable(() => useClient()) + + expect(client?.value?.chain.id).toEqual(1) + + await switchChain(config, { chainId: 456 }) + + expect(client.value?.chain?.id).toEqual(456) +}) + +test('parameters: config', () => { + const [chainId] = renderComposable(() => useClient({ config }), { + attach() {}, + }) + expect(chainId.value).toBeDefined() +}) + +test('behavior: controlled chainId', async () => { + const chainId = ref(456) + + const [client] = renderComposable(() => useClient({ chainId })) + + expect(client?.value?.chain.id).toEqual(456) + + chainId.value = 1 + + await waitFor(client, (client) => client?.chain.id === 1) +}) + +test('behavior: unconfigured chain', () => { + const [client] = renderComposable(() => useClient({ chainId: 123456 })) + expect(client.value).toBeUndefined() +}) diff --git a/wagmi-project/packages/vue/src/composables/useClient.ts b/wagmi-project/packages/vue/src/composables/useClient.ts new file mode 100644 index 0000000000..e29b38826b --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useClient.ts @@ -0,0 +1,66 @@ +import { + type Config, + type GetClientParameters, + type GetClientReturnType, + type ResolvedRegister, + getClient, + watchClient, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type Ref, + computed, + onScopeDispose, + readonly, + ref, + watchEffect, +} from 'vue' + +import type { ConfigParameter } from '../types/properties.js' +import type { DeepMaybeRef } from '../types/ref.js' +import { deepUnref } from '../utils/cloneDeep.js' +import { useConfig } from './useConfig.js' + +export type UseClientParameters< + config extends Config = Config, + chainId extends config['chains'][number]['id'] | number | undefined = + | config['chains'][number]['id'] + | undefined, +> = Compute< + DeepMaybeRef & ConfigParameter> +> + +export type UseClientReturnType< + config extends Config = Config, + chainId extends config['chains'][number]['id'] | number | undefined = + | config['chains'][number]['id'] + | undefined, +> = Ref> + +/** https://wagmi.sh/vue/api/composables/useClient */ +export function useClient< + config extends Config = ResolvedRegister['config'], + chainId extends config['chains'][number]['id'] | number | undefined = + | config['chains'][number]['id'] + | undefined, +>( + parameters: UseClientParameters = {}, +): UseClientReturnType { + const params = computed(() => deepUnref(parameters)) + + const config = useConfig(params) + + const client = ref(getClient(config, params.value as GetClientParameters)) + watchEffect(() => { + client.value = getClient(config, params.value as GetClientParameters) + }) + const unsubscribe = watchClient(config, { + onChange(data) { + if (client.value?.uid === data?.uid) return + client.value = data + }, + }) + onScopeDispose(() => unsubscribe()) + + return readonly(client) as UseClientReturnType +} diff --git a/wagmi-project/packages/vue/src/composables/useConfig.test-d.ts b/wagmi-project/packages/vue/src/composables/useConfig.test-d.ts new file mode 100644 index 0000000000..f2b9d2bb31 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useConfig.test-d.ts @@ -0,0 +1,16 @@ +import type { Config } from '@wagmi/core' +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { useConfig } from './useConfig.js' + +test('default', async () => { + const result = useConfig() + expectTypeOf(result).toEqualTypeOf() +}) + +test('parameters: config', async () => { + const result = useConfig({ config }) + expectTypeOf(result).not.toEqualTypeOf() + expectTypeOf(result).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/vue/src/composables/useConfig.test.ts b/wagmi-project/packages/vue/src/composables/useConfig.test.ts new file mode 100644 index 0000000000..a7036b65e8 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useConfig.test.ts @@ -0,0 +1,24 @@ +import { renderComposable } from '@wagmi/test/vue' +import { expect, test, vi } from 'vitest' + +import { useConfig } from './useConfig.js' + +test('default', () => { + const [config] = renderComposable(() => useConfig()) + expect(config).toBeDefined() +}) + +test('behavior: throws when not provided via WagmiPlugin', () => { + vi.spyOn(console, 'error').mockImplementation(() => {}) + + try { + renderComposable(() => useConfig(), { attach() {} }) + } catch (error) { + expect(error).toMatchInlineSnapshot(` + [WagmiPluginNotFoundError: No \`config\` found in Vue context, use \`WagmiPlugin\` to properly initialize the library. + + Docs: https://wagmi.sh/vue/api/TODO.html + Version: @wagmi/vue@x.y.z] + `) + } +}) diff --git a/wagmi-project/packages/vue/src/composables/useConfig.ts b/wagmi-project/packages/vue/src/composables/useConfig.ts new file mode 100644 index 0000000000..a827f818a5 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useConfig.ts @@ -0,0 +1,34 @@ +import type { Config, ResolvedRegister } from '@wagmi/core' +import { hasInjectionContext, inject, unref } from 'vue' + +import { + WagmiInjectionContextError, + WagmiPluginNotFoundError, +} from '../errors/plugin.js' +import { configKey } from '../plugin.js' +import type { ConfigParameter } from '../types/properties.js' +import type { DeepMaybeRef } from '../types/ref.js' + +export type UseConfigParameters = DeepMaybeRef< + ConfigParameter +> + +export type UseConfigReturnType = config + +/** https://wagmi.sh/vue/api/composables/useConfig */ +export function useConfig( + parameters_: UseConfigParameters = {}, +): UseConfigReturnType { + const parameters = unref(parameters_) + + // passthrough config if provided + if (parameters.config) return parameters.config as UseConfigReturnType + + // ensures that `inject()` can be used + if (!hasInjectionContext()) throw new WagmiInjectionContextError() + + const config = inject(configKey) + if (!config) throw new WagmiPluginNotFoundError() + + return config as UseConfigReturnType +} diff --git a/wagmi-project/packages/vue/src/composables/useConnect.test-d.ts b/wagmi-project/packages/vue/src/composables/useConnect.test-d.ts new file mode 100644 index 0000000000..44c7b6fdac --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useConnect.test-d.ts @@ -0,0 +1,121 @@ +import type { + ConnectErrorType, + Connector, + CreateConnectorFn, +} from '@wagmi/core' +import { config } from '@wagmi/test' +import type { Address } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { useConnect } from './useConnect.js' + +const connector = config.connectors[0]! +const contextValue = { foo: 'bar' } as const + +test('context', () => { + const { connect, context, data, error, variables } = useConnect({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toEqualTypeOf<{ + chainId?: number | undefined + connector: Connector | CreateConnectorFn + }>() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ + chainId?: number | undefined + connector: Connector | CreateConnectorFn + }>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ + chainId?: number | undefined + connector: Connector | CreateConnectorFn + }>() + expectTypeOf(data).toEqualTypeOf<{ + accounts: readonly [Address, ...Address[]] + chainId: number + }>() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf< + | { + accounts: readonly [Address, ...Address[]] + chainId: number + } + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf<{ + chainId?: number | undefined + connector: Connector | CreateConnectorFn + }>() + expectTypeOf(context).toEqualTypeOf() + }, + }, + }) + + expectTypeOf(data.value).toEqualTypeOf< + | { + accounts: readonly [Address, ...Address[]] + chainId: number + } + | undefined + >() + expectTypeOf(error.value).toEqualTypeOf() + expectTypeOf(variables.value).toMatchTypeOf< + | { + chainId?: number | undefined + connector: Connector | CreateConnectorFn + } + | undefined + >() + expectTypeOf(context.value).toEqualTypeOf() + + connect( + { connector }, + { + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ + chainId?: number | undefined + connector: typeof connector | CreateConnectorFn + foo?: string | undefined + }>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ + chainId?: number | undefined + connector: typeof connector | CreateConnectorFn + foo?: string | undefined + }>() + expectTypeOf(data).toEqualTypeOf<{ + accounts: readonly [Address, ...Address[]] + chainId: number + }>() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf< + | { + accounts: readonly [Address, ...Address[]] + chainId: number + } + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf<{ + chainId?: number | undefined + connector: typeof connector | CreateConnectorFn + foo?: string | undefined + }>() + expectTypeOf(context).toEqualTypeOf() + }, + }, + ) +}) diff --git a/wagmi-project/packages/vue/src/composables/useConnect.test.ts b/wagmi-project/packages/vue/src/composables/useConnect.test.ts new file mode 100644 index 0000000000..206abd41ee --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useConnect.test.ts @@ -0,0 +1,31 @@ +import { disconnect } from '@wagmi/core' +import { config } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { afterEach, expect, test } from 'vitest' + +import { useAccount } from './useAccount.js' +import { useConnect } from './useConnect.js' + +const connector = config.connectors[0]! + +afterEach(async () => { + if (config.state.current === connector.uid) + await disconnect(config, { connector }) +}) + +test('default', async () => { + const [account] = renderComposable(() => useAccount()) + const [connect] = renderComposable(() => useConnect()) + + expect(account.address.value).not.toBeDefined() + expect(account.status.value).toEqual('disconnected') + + connect.connect({ + connector: connect.connectors[0]!, + }) + + await waitFor(account.isConnected, (isConnected) => Boolean(isConnected)) + + expect(account.address.value).toBeDefined() + expect(account.status.value).toEqual('connected') +}) diff --git a/wagmi-project/packages/vue/src/composables/useConnect.ts b/wagmi-project/packages/vue/src/composables/useConnect.ts new file mode 100644 index 0000000000..7659dc3411 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useConnect.ts @@ -0,0 +1,92 @@ +import { useMutation } from '@tanstack/vue-query' +import type { + Config, + ConnectErrorType, + GetConnectorsReturnType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type ConnectData, + type ConnectMutate, + type ConnectMutateAsync, + type ConnectVariables, + connectMutationOptions, +} from '@wagmi/core/query' +import { onScopeDispose } from 'vue' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' +import { useConnectors } from './useConnectors.js' + +export type UseConnectParameters< + config extends Config = Config, + context = unknown, +> = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + ConnectData, + ConnectErrorType, + ConnectVariables, + context + > + | undefined + } +> + +export type UseConnectReturnType< + config extends Config = Config, + context = unknown, +> = Compute< + UseMutationReturnType< + ConnectData, + ConnectErrorType, + ConnectVariables, + context + > & { + connect: ConnectMutate + connectAsync: ConnectMutateAsync + connectors: Compute | config['connectors'] + } +> + +/** https://wagmi.sh/vue/api/composables/useConnect */ +export function useConnect< + config extends Config = ResolvedRegister['config'], + context = unknown, +>( + parameters: UseConnectParameters = {}, +): UseConnectReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = connectMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + // Reset mutation back to an idle state when the connector disconnects. + const unsubscribe = config.subscribe( + ({ status }) => status, + (status, previousStatus) => { + if (previousStatus === 'connected' && status === 'disconnected') + result.reset() + }, + ) + onScopeDispose(() => unsubscribe()) + + type Return = UseConnectReturnType + return { + ...(result as Return), + connect: mutate as Return['connect'], + connectAsync: mutateAsync as Return['connectAsync'], + connectors: useConnectors({ config }).value, + } +} diff --git a/wagmi-project/packages/vue/src/composables/useConnections.test.ts b/wagmi-project/packages/vue/src/composables/useConnections.test.ts new file mode 100644 index 0000000000..d51401b427 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useConnections.test.ts @@ -0,0 +1,16 @@ +import { connect } from '@wagmi/core' +import { config } from '@wagmi/test' +import { renderComposable } from '@wagmi/test/vue' +import { expect, test } from 'vitest' + +import { useConnections } from './useConnections.js' + +test('default', async () => { + const [connections] = renderComposable(() => useConnections()) + + expect(connections.value).toEqual([]) + + await connect(config, { connector: config.connectors[0]! }) + + expect(connections.value.length).toBe(1) +}) diff --git a/wagmi-project/packages/vue/src/composables/useConnections.ts b/wagmi-project/packages/vue/src/composables/useConnections.ts new file mode 100644 index 0000000000..7bcc499498 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useConnections.ts @@ -0,0 +1,30 @@ +import { + type GetConnectionsReturnType, + getConnections, + watchConnections, +} from '@wagmi/core' +import { type Ref, onScopeDispose, readonly, ref } from 'vue' + +import type { ConfigParameter } from '../types/properties.js' +import { useConfig } from './useConfig.js' + +export type UseConnectionsParameters = ConfigParameter + +export type UseConnectionsReturnType = Ref + +/** https://wagmi.sh/vue/api/composables/useConnections */ +export function useConnections( + parameters: UseConnectionsParameters = {}, +): UseConnectionsReturnType { + const config = useConfig(parameters) + + const connections = ref(getConnections(config)) + const unsubscribe = watchConnections(config, { + onChange(data) { + connections.value = data + }, + }) + onScopeDispose(() => unsubscribe()) + + return readonly(connections) as UseConnectionsReturnType +} diff --git a/wagmi-project/packages/vue/src/composables/useConnectorClient.test-d.ts b/wagmi-project/packages/vue/src/composables/useConnectorClient.test-d.ts new file mode 100644 index 0000000000..710d8260d4 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useConnectorClient.test-d.ts @@ -0,0 +1,12 @@ +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { useConnectorClient } from './useConnectorClient.js' + +test('parameters: config', async () => { + const client = useConnectorClient({ config }) + expectTypeOf(client.data?.value?.chain?.id!).toEqualTypeOf<1 | 456 | 10>() + + const client2 = useConnectorClient({ config, chainId: 1 }) + expectTypeOf(client2.data?.value?.chain?.id!).toEqualTypeOf<1>() +}) diff --git a/wagmi-project/packages/vue/src/composables/useConnectorClient.test.ts b/wagmi-project/packages/vue/src/composables/useConnectorClient.test.ts new file mode 100644 index 0000000000..7a361702ac --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useConnectorClient.test.ts @@ -0,0 +1,156 @@ +import { connect, disconnect } from '@wagmi/core' +import { config, wait } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { expect, test } from 'vitest' + +import { deepUnref } from '../utils/cloneDeep.js' +import { useConnect } from './useConnect.js' +import { useConnectorClient } from './useConnectorClient.js' +import { useDisconnect } from './useDisconnect.js' +import { useSwitchChain } from './useSwitchChain.js' + +const connector = config.connectors[0]! + +test('default', async () => { + const [client] = renderComposable(() => useConnectorClient()) + + expect(deepUnref(client)).toMatchInlineSnapshot(` + { + "data": undefined, + "dataUpdatedAt": 0, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": false, + "isFetchedAfterMount": false, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": true, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": false, + "queryKey": [ + "connectorClient", + { + "chainId": 1, + "connectorUid": undefined, + }, + ], + "refetch": [Function], + "status": "pending", + "suspense": [Function], + } + `) +}) + +test('behavior: connected on mount', async () => { + await connect(config, { connector }) + + const [client] = renderComposable(() => useConnectorClient()) + + await waitFor(client.isSuccess, (isSuccess) => isSuccess === true) + + const { data, queryKey: _, ...rest } = deepUnref(client) + expect(data).toMatchObject( + expect.objectContaining({ + account: expect.any(Object), + chain: expect.any(Object), + }), + ) + expect(rest).toMatchInlineSnapshot(` + { + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": false, + "isSuccess": true, + "refetch": [Function], + "status": "success", + "suspense": [Function], + } + `) + + await disconnect(config, { connector }) +}) + +test('behavior: connect and disconnect', async () => { + const [connect] = renderComposable(() => useConnect()) + const [client] = renderComposable(() => useConnectorClient()) + const [disconnect] = renderComposable(() => useDisconnect()) + + expect(client.data.value).not.toBeDefined() + + connect.connect({ + connector: connect.connectors[0]!, + }) + + await waitFor(client.data, (data) => data !== undefined) + + disconnect.disconnect() + + await waitFor(client.data, (data) => data === undefined) +}) + +test('behavior: switch chains', async () => { + await connect(config, { connector }) + + const [connectorClient] = renderComposable(() => useConnectorClient()) + const [switchChain] = renderComposable(() => useSwitchChain()) + + expect(connectorClient.data.value).not.toBeDefined() + + await waitFor(connectorClient.data, (data) => data !== undefined) + + switchChain.switchChain({ chainId: 456 }) + await waitFor(switchChain.isSuccess, (isSuccess) => isSuccess === true) + await waitFor(connectorClient.data, (data) => data !== undefined) + expect(connectorClient.data?.value?.chain.id).toEqual(456) + + switchChain.switchChain({ chainId: 1 }) + await waitFor(switchChain.isSuccess, (isSuccess) => isSuccess === true) + await waitFor(connectorClient.data, (data) => data !== undefined) + expect(connectorClient.data?.value?.chain.id).toEqual(1) + + await disconnect(config, { connector }) +}) + +test('behavior: disabled when properties missing', async () => { + const [connectorClient] = renderComposable(() => useConnectorClient()) + + await wait(100) + expect(connectorClient.isPending.value).toBe(true) +}) + +test('behavior: disabled when connecting', async () => { + const [connectorClient] = renderComposable(() => useConnectorClient()) + + config.setState((x) => ({ ...x, status: 'connecting' })) + + await wait(100) + expect(connectorClient.isLoading.value).not.toBeTruthy() +}) diff --git a/wagmi-project/packages/vue/src/composables/useConnectorClient.ts b/wagmi-project/packages/vue/src/composables/useConnectorClient.ts new file mode 100644 index 0000000000..08735718bf --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useConnectorClient.ts @@ -0,0 +1,132 @@ +import { useQueryClient } from '@tanstack/vue-query' +import type { + Config, + Connector, + GetConnectorClientErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute, Omit } from '@wagmi/core/internal' +import { + type GetConnectorClientData, + type GetConnectorClientOptions, + type GetConnectorClientQueryFnData, + type GetConnectorClientQueryKey, + getConnectorClientQueryOptions, +} from '@wagmi/core/query' +import { computed, ref, watchEffect } from 'vue' + +import type { ConfigParameter } from '../types/properties.js' +import type { DeepMaybeRef, DeepUnwrapRef } from '../types/ref.js' +import { deepUnref } from '../utils/cloneDeep.js' +import { + type UseQueryParameters, + type UseQueryReturnType, + useQuery, +} from '../utils/query.js' +import { useAccount } from './useAccount.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseConnectorClientParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetConnectorClientData, +> = Compute< + DeepMaybeRef< + GetConnectorClientOptions & + ConfigParameter & { + query?: + | Compute< + Omit< + DeepUnwrapRef< + UseQueryParameters< + GetConnectorClientQueryFnData, + GetConnectorClientErrorType, + selectData, + GetConnectorClientQueryKey + > + >, + 'gcTime' | 'staleTime' + > + > + | undefined + } + > +> + +export type UseConnectorClientReturnType< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetConnectorClientData, +> = UseQueryReturnType + +/** https://wagmi.sh/vue/api/composables/useConnectorClient */ +export function useConnectorClient< + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetConnectorClientData, +>( + parameters_: UseConnectorClientParameters = {}, +): UseConnectorClientReturnType { + const parameters = computed(() => deepUnref(parameters_)) + + const config = useConfig(parameters) + const queryClient = useQueryClient() + const { + address, + connector: accountConnector, + status, + } = useAccount({ config }) + const configChainId = useChainId({ config }) + + const queryOptions = computed(() => { + const { + chainId = configChainId.value, + connector = accountConnector.value, + query = {}, + } = parameters.value + const { queryKey, ...options } = getConnectorClientQueryOptions< + config, + chainId + >(config as config, { + ...deepUnref(parameters), + chainId: chainId as chainId, + connector: connector as Connector, + }) + const enabled = Boolean( + (status.value === 'connected' || + (status.value === 'reconnecting' && connector?.getProvider)) && + (query.enabled ?? true), + ) + return { + ...query, + ...options, + queryKey, + enabled, + staleTime: Number.POSITIVE_INFINITY, + } + }) + + const addressRef = ref(address) + watchEffect(() => { + const previousAddress = addressRef.value + if (!address && previousAddress) { + // remove when account is disconnected + queryClient.removeQueries({ queryKey: queryOptions.value.queryKey }) + addressRef.value = undefined + } else if (address.value !== previousAddress) { + // invalidate when address changes + queryClient.invalidateQueries({ queryKey: queryOptions.value.queryKey }) + addressRef.value = address.value + } + }) + + return useQuery(queryOptions as any) as UseConnectorClientReturnType< + config, + chainId, + selectData + > +} diff --git a/wagmi-project/packages/vue/src/composables/useConnectors.test.ts b/wagmi-project/packages/vue/src/composables/useConnectors.test.ts new file mode 100644 index 0000000000..16fec78dfe --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useConnectors.test.ts @@ -0,0 +1,21 @@ +import { mock } from '@wagmi/connectors' +import { accounts, config } from '@wagmi/test' +import { renderComposable } from '@wagmi/test/vue' +import { expect, test } from 'vitest' + +import { useConnectors } from './useConnectors.js' + +test('default', async () => { + const [connectors] = renderComposable(() => useConnectors()) + + const count = config.connectors.length + expect(connectors.value.length).toBe(count) + expect(connectors.value).toEqual(config.connectors) + + config._internal.connectors.setState(() => [ + ...config.connectors, + config._internal.connectors.setup(mock({ accounts })), + ]) + + expect(connectors.value.length).toBe(count + 1) +}) diff --git a/wagmi-project/packages/vue/src/composables/useConnectors.ts b/wagmi-project/packages/vue/src/composables/useConnectors.ts new file mode 100644 index 0000000000..4d12d81806 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useConnectors.ts @@ -0,0 +1,37 @@ +import { + type Config, + type GetConnectorsReturnType, + type ResolvedRegister, + getConnectors, + watchConnectors, +} from '@wagmi/core' +import { type Ref, onScopeDispose, ref } from 'vue' + +import type { ConfigParameter } from '../types/properties.js' +import { useConfig } from './useConfig.js' + +export type UseConnectorsParameters = + ConfigParameter + +export type UseConnectorsReturnType = Ref< + GetConnectorsReturnType +> + +/** https://wagmi.sh/vue/api/composables/useConnectors */ +export function useConnectors< + config extends Config = ResolvedRegister['config'], +>( + parameters: UseConnectorsParameters = {}, +): UseConnectorsReturnType { + const config = useConfig(parameters) + + const connectors = ref(getConnectors(config)) + const unsubscribe = watchConnectors(config, { + onChange(data) { + connectors.value = data as never + }, + }) + onScopeDispose(() => unsubscribe()) + + return connectors +} diff --git a/wagmi-project/packages/vue/src/composables/useDisconnect.test-d.ts b/wagmi-project/packages/vue/src/composables/useDisconnect.test-d.ts new file mode 100644 index 0000000000..3be3fe9488 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useDisconnect.test-d.ts @@ -0,0 +1,87 @@ +import type { Connector, DisconnectErrorType } from '@wagmi/core' +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { useDisconnect } from './useDisconnect.js' + +const connector = config.connectors[0]! +const contextValue = { foo: 'bar' } as const + +test('parameter', () => { + expectTypeOf(useDisconnect().disconnect) + .parameter(0) + .toEqualTypeOf<{ connector?: Connector | undefined } | undefined>() + expectTypeOf(useDisconnect().disconnect) + .parameter(0) + .toEqualTypeOf<{ connector?: Connector | undefined } | undefined>() +}) + +test('context', () => { + const { context, data, disconnect, error, variables } = useDisconnect({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toEqualTypeOf< + { connector?: Connector | undefined } | undefined + >() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf< + { connector?: Connector | undefined } | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf< + { connector?: Connector | undefined } | undefined + >() + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf< + { connector?: Connector | undefined } | undefined + >() + expectTypeOf(context).toEqualTypeOf() + }, + }, + }) + + expectTypeOf(data.value).toEqualTypeOf() + expectTypeOf(error.value).toEqualTypeOf() + expectTypeOf(variables.value).toEqualTypeOf< + { connector?: Connector | undefined } | undefined + >() + expectTypeOf(context.value).toEqualTypeOf() + + disconnect( + { connector }, + { + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf< + { connector?: Connector | undefined } | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf< + { connector?: Connector | undefined } | undefined + >() + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf< + { connector?: Connector | undefined } | undefined + >() + expectTypeOf(context).toEqualTypeOf() + }, + }, + ) +}) diff --git a/wagmi-project/packages/vue/src/composables/useDisconnect.test.ts b/wagmi-project/packages/vue/src/composables/useDisconnect.test.ts new file mode 100644 index 0000000000..935c75827d --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useDisconnect.test.ts @@ -0,0 +1,30 @@ +import { connect } from '@wagmi/core' +import { config } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { beforeEach, expect, test } from 'vitest' + +import { useAccount } from './useAccount.js' +import { useDisconnect } from './useDisconnect.js' + +const connector = config.connectors[0]! + +beforeEach(async () => { + await connect(config, { connector }) +}) + +test('default', async () => { + const [account] = renderComposable(() => useAccount()) + const [disconnect] = renderComposable(() => useDisconnect()) + + expect(account.address.value).toBeDefined() + expect(account.status.value).toEqual('connected') + + disconnect.disconnect() + + await waitFor(account.isDisconnected, (isDisconnected) => + Boolean(isDisconnected), + ) + + expect(account.address.value).not.toBeDefined() + expect(account.status.value).toEqual('disconnected') +}) diff --git a/wagmi-project/packages/vue/src/composables/useDisconnect.ts b/wagmi-project/packages/vue/src/composables/useDisconnect.ts new file mode 100644 index 0000000000..540e588124 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useDisconnect.ts @@ -0,0 +1,70 @@ +import { useMutation } from '@tanstack/vue-query' +import type { Connector, DisconnectErrorType } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type DisconnectData, + type DisconnectMutate, + type DisconnectMutateAsync, + type DisconnectVariables, + disconnectMutationOptions, +} from '@wagmi/core/query' +import { type Ref, computed } from 'vue' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' +import { useConnections } from './useConnections.js' + +export type UseDisconnectParameters = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + DisconnectData, + DisconnectErrorType, + DisconnectVariables, + context + > + | undefined + } +> + +export type UseDisconnectReturnType = Compute< + UseMutationReturnType< + DisconnectData, + DisconnectErrorType, + DisconnectVariables, + context + > & { + connectors: Ref + disconnect: DisconnectMutate + disconnectAsync: DisconnectMutateAsync + } +> + +/** https://wagmi.sh/vue/api/composables/useDisconnect */ +export function useDisconnect( + parameters: UseDisconnectParameters = {}, +): UseDisconnectReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + const connections = useConnections({ config }) + + const mutationOptions = disconnectMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + return { + ...result, + connectors: computed(() => + connections.value.map((connection) => connection.connector), + ), + disconnect: mutate, + disconnectAsync: mutateAsync, + } +} diff --git a/wagmi-project/packages/vue/src/composables/useEnsAddress.test.ts b/wagmi-project/packages/vue/src/composables/useEnsAddress.test.ts new file mode 100644 index 0000000000..01d35769b7 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useEnsAddress.test.ts @@ -0,0 +1,52 @@ +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { expect, test } from 'vitest' + +import { deepUnref } from '../utils/cloneDeep.js' +import { useEnsAddress } from './useEnsAddress.js' + +test('default', async () => { + const [result] = renderComposable(() => + useEnsAddress({ + name: 'wevm.eth', + }), + ) + + await waitFor(result.isSuccess) + + expect(deepUnref(result)).toMatchInlineSnapshot(` + { + "data": "0xd2135CfB216b74109775236E36d4b433F1DF507B", + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "ensAddress", + { + "chainId": 1, + "name": "wevm.eth", + }, + ], + "refetch": [Function], + "status": "success", + "suspense": [Function], + } + `) +}) diff --git a/wagmi-project/packages/vue/src/composables/useEnsAddress.ts b/wagmi-project/packages/vue/src/composables/useEnsAddress.ts new file mode 100644 index 0000000000..ecb27ac143 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useEnsAddress.ts @@ -0,0 +1,65 @@ +import type { + Config, + GetEnsAddressErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetEnsAddressData, + type GetEnsAddressOptions, + type GetEnsAddressQueryFnData, + type GetEnsAddressQueryKey, + getEnsAddressQueryOptions, +} from '@wagmi/core/query' +import { computed } from 'vue' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import type { DeepMaybeRef } from '../types/ref.js' +import { deepUnref } from '../utils/cloneDeep.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseEnsAddressParameters< + config extends Config = Config, + selectData = GetEnsAddressData, +> = Compute< + DeepMaybeRef< + GetEnsAddressOptions & + ConfigParameter & + QueryParameter< + GetEnsAddressQueryFnData, + GetEnsAddressErrorType, + selectData, + GetEnsAddressQueryKey + > + > +> + +export type UseEnsAddressReturnType = + UseQueryReturnType + +/** https://wagmi.sh/vue/api/composables/useEnsAddress */ +export function useEnsAddress< + config extends Config = ResolvedRegister['config'], + selectData = GetEnsAddressData, +>( + parameters_: UseEnsAddressParameters = {}, +): UseEnsAddressReturnType { + const parameters = computed(() => deepUnref(parameters_)) + + const config = useConfig(parameters) + const configChainId = useChainId({ config }) + + const queryOptions = computed(() => { + const { chainId = configChainId.value, name, query = {} } = parameters.value + const options = getEnsAddressQueryOptions(config, { + ...parameters.value, + chainId, + }) + const enabled = Boolean(name && (query.enabled ?? true)) + return { ...query, ...options, enabled } + }) + + return useQuery(queryOptions as any) as UseEnsAddressReturnType +} diff --git a/wagmi-project/packages/vue/src/composables/useEnsAvatar.test.ts b/wagmi-project/packages/vue/src/composables/useEnsAvatar.test.ts new file mode 100644 index 0000000000..ab024c89b5 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useEnsAvatar.test.ts @@ -0,0 +1,52 @@ +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { expect, test } from 'vitest' + +import { deepUnref } from '../utils/cloneDeep.js' +import { useEnsAvatar } from './useEnsAvatar.js' + +test('default', async () => { + const [result] = renderComposable(() => + useEnsAvatar({ + name: 'wevm.eth', + }), + ) + + await waitFor(result.isSuccess) + + expect(deepUnref(result)).toMatchInlineSnapshot(` + { + "data": "https://euc.li/wevm.eth", + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "ensAvatar", + { + "chainId": 1, + "name": "wevm.eth", + }, + ], + "refetch": [Function], + "status": "success", + "suspense": [Function], + } + `) +}) diff --git a/wagmi-project/packages/vue/src/composables/useEnsAvatar.ts b/wagmi-project/packages/vue/src/composables/useEnsAvatar.ts new file mode 100644 index 0000000000..ff328ad87c --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useEnsAvatar.ts @@ -0,0 +1,65 @@ +import type { + Config, + GetEnsAvatarErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetEnsAvatarData, + type GetEnsAvatarOptions, + type GetEnsAvatarQueryFnData, + type GetEnsAvatarQueryKey, + getEnsAvatarQueryOptions, +} from '@wagmi/core/query' +import { computed } from 'vue' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import type { DeepMaybeRef } from '../types/ref.js' +import { deepUnref } from '../utils/cloneDeep.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseEnsAvatarParameters< + config extends Config = Config, + selectData = GetEnsAvatarData, +> = Compute< + DeepMaybeRef< + GetEnsAvatarOptions & + ConfigParameter & + QueryParameter< + GetEnsAvatarQueryFnData, + GetEnsAvatarErrorType, + selectData, + GetEnsAvatarQueryKey + > + > +> + +export type UseEnsAvatarReturnType = + UseQueryReturnType + +/** https://wagmi.sh/vue/api/composables/useEnsAvatar */ +export function useEnsAvatar< + config extends Config = ResolvedRegister['config'], + selectData = GetEnsAvatarData, +>( + parameters_: UseEnsAvatarParameters = {}, +): UseEnsAvatarReturnType { + const parameters = computed(() => deepUnref(parameters_)) + + const config = useConfig(parameters) + const configChainId = useChainId({ config }) + + const queryOptions = computed(() => { + const { chainId = configChainId.value, name, query = {} } = parameters.value + const options = getEnsAvatarQueryOptions(config, { + ...parameters.value, + chainId, + }) + const enabled = Boolean(name && (query.enabled ?? true)) + return { ...query, ...options, enabled } + }) + + return useQuery(queryOptions as any) as UseEnsAvatarReturnType +} diff --git a/wagmi-project/packages/vue/src/composables/useEnsName.test.ts b/wagmi-project/packages/vue/src/composables/useEnsName.test.ts new file mode 100644 index 0000000000..ee5b8cfab6 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useEnsName.test.ts @@ -0,0 +1,52 @@ +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { expect, test } from 'vitest' + +import { deepUnref } from '../utils/cloneDeep.js' +import { useEnsName } from './useEnsName.js' + +test('default', async () => { + const [result] = renderComposable(() => + useEnsName({ + address: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + }), + ) + + await waitFor(result.isSuccess) + + expect(deepUnref(result)).toMatchInlineSnapshot(` + { + "data": "wevm.eth", + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "ensName", + { + "address": "0xd2135CfB216b74109775236E36d4b433F1DF507B", + "chainId": 1, + }, + ], + "refetch": [Function], + "status": "success", + "suspense": [Function], + } + `) +}) diff --git a/wagmi-project/packages/vue/src/composables/useEnsName.ts b/wagmi-project/packages/vue/src/composables/useEnsName.ts new file mode 100644 index 0000000000..ba251aa5a3 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useEnsName.ts @@ -0,0 +1,65 @@ +import type { Config, GetEnsNameErrorType, ResolvedRegister } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetEnsNameData, + type GetEnsNameOptions, + type GetEnsNameQueryFnData, + type GetEnsNameQueryKey, + getEnsNameQueryOptions, +} from '@wagmi/core/query' + +import { computed } from 'vue' +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import type { DeepMaybeRef } from '../types/ref.js' +import { deepUnref } from '../utils/cloneDeep.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseEnsNameParameters< + config extends Config = Config, + selectData = GetEnsNameData, +> = Compute< + DeepMaybeRef< + GetEnsNameOptions & + ConfigParameter & + QueryParameter< + GetEnsNameQueryFnData, + GetEnsNameErrorType, + selectData, + GetEnsNameQueryKey + > + > +> + +export type UseEnsNameReturnType = + UseQueryReturnType + +/** https://wagmi.sh/vue/api/composables/useEnsName */ +export function useEnsName< + config extends Config = ResolvedRegister['config'], + selectData = GetEnsNameData, +>( + parameters_: UseEnsNameParameters = {}, +): UseEnsNameReturnType { + const parameters = computed(() => deepUnref(parameters_)) + + const config = useConfig(parameters) + const configChainId = useChainId({ config }) + + const queryOptions = computed(() => { + const { + address, + chainId = configChainId.value, + query = {}, + } = parameters.value + const options = getEnsNameQueryOptions(config, { + ...parameters.value, + chainId, + }) + const enabled = Boolean(address && (query.enabled ?? true)) + return { ...query, ...options, enabled } + }) + + return useQuery(queryOptions as any) as UseEnsNameReturnType +} diff --git a/wagmi-project/packages/vue/src/composables/useEstimateGas.test-d.ts b/wagmi-project/packages/vue/src/composables/useEstimateGas.test-d.ts new file mode 100644 index 0000000000..ba084419d4 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useEstimateGas.test-d.ts @@ -0,0 +1,14 @@ +import { expectTypeOf, test } from 'vitest' + +import { useEstimateGas } from './useEstimateGas.js' + +test('select data', () => { + const result = useEstimateGas({ + query: { + select(data) { + return data.toString() + }, + }, + }) + expectTypeOf(result.data.value).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/vue/src/composables/useEstimateGas.test.ts b/wagmi-project/packages/vue/src/composables/useEstimateGas.test.ts new file mode 100644 index 0000000000..f8212f11da --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useEstimateGas.test.ts @@ -0,0 +1,117 @@ +import { accounts, wait } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { parseEther } from 'viem' +import { expect, test } from 'vitest' + +import { ref } from 'vue' +import { deepUnref } from '../utils/cloneDeep.js' +import { useEstimateGas } from './useEstimateGas.js' + +test('default', async () => { + const [result] = renderComposable(() => + useEstimateGas({ + account: accounts[0], + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }), + ) + + await waitFor(result.isSuccess) + + expect(deepUnref(result)).toMatchInlineSnapshot(` + { + "data": 21000n, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "estimateGas", + { + "account": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "chainId": 1, + "to": "0xd2135CfB216b74109775236E36d4b433F1DF507B", + "value": 10000000000000000n, + }, + ], + "refetch": [Function], + "status": "success", + "suspense": [Function], + } + `) +}) + +test('behavior: address: undefined -> defined', async () => { + const address = ref() + + const [result] = renderComposable(() => + useEstimateGas({ + account: address, + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }), + ) + + await wait(100) + expect(result.fetchStatus.value).toBe('idle') + + address.value = accounts[0] + + await waitFor(result.isSuccess) + + expect(deepUnref(result)).toMatchInlineSnapshot(` + { + "data": 21000n, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "estimateGas", + { + "account": undefined, + "chainId": 1, + "to": "0xd2135CfB216b74109775236E36d4b433F1DF507B", + "value": 10000000000000000n, + }, + ], + "refetch": [Function], + "status": "success", + "suspense": [Function], + } + `) +}) diff --git a/wagmi-project/packages/vue/src/composables/useEstimateGas.ts b/wagmi-project/packages/vue/src/composables/useEstimateGas.ts new file mode 100644 index 0000000000..fd885ec712 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useEstimateGas.ts @@ -0,0 +1,83 @@ +import type { + Config, + EstimateGasErrorType, + ResolvedRegister, +} from '@wagmi/core' +import { + type EstimateGasData, + type EstimateGasOptions, + type EstimateGasQueryFnData, + type EstimateGasQueryKey, + estimateGasQueryOptions, +} from '@wagmi/core/query' +import { computed } from 'vue' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import type { DeepMaybeRef } from '../types/ref.js' +import { deepUnref } from '../utils/cloneDeep.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' +import { useConnectorClient } from './useConnectorClient.js' + +export type UseEstimateGasParameters< + config extends Config = Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, + selectData = EstimateGasData, +> = DeepMaybeRef< + EstimateGasOptions & + ConfigParameter & + QueryParameter< + EstimateGasQueryFnData, + EstimateGasErrorType, + selectData, + EstimateGasQueryKey + > +> + +export type UseEstimateGasReturnType = + UseQueryReturnType + +/** https://wagmi.sh/react/api/hooks/useEstimateGas */ +export function useEstimateGas< + config extends Config = ResolvedRegister['config'], + chainId extends config['chains'][number]['id'] | undefined = undefined, + selectData = EstimateGasData, +>( + parameters?: UseEstimateGasParameters, +): UseEstimateGasReturnType + +export function useEstimateGas( + parameters_: UseEstimateGasParameters = {}, +): UseEstimateGasReturnType { + const parameters = computed(() => deepUnref(parameters_)) + + const config = useConfig(parameters) + const { data: connectorClient } = useConnectorClient( + computed(() => ({ + connector: parameters.value.connector, + query: { enabled: parameters.value.account === undefined }, + })), + ) + + const configChainId = useChainId({ config }) + + const queryOptions = computed(() => { + const { + account = connectorClient?.value?.account, + chainId = configChainId.value, + connector, + query = {}, + } = parameters.value + const options = estimateGasQueryOptions(config, { + ...parameters.value, + account, + chainId, + connector, + }) + const enabled = Boolean((account || connector) && (query.enabled ?? true)) + return { ...query, ...options, enabled } + }) + + return useQuery(queryOptions) +} diff --git a/wagmi-project/packages/vue/src/composables/useReadContract.test-d.ts b/wagmi-project/packages/vue/src/composables/useReadContract.test-d.ts new file mode 100644 index 0000000000..0685dde8f4 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useReadContract.test-d.ts @@ -0,0 +1,99 @@ +import { abi } from '@wagmi/test' +import type { Address } from 'viem' +import { assertType, expectTypeOf, test } from 'vitest' + +import type { DeepUnwrapRef } from '../types/ref.js' +import { + type UseReadContractParameters, + type UseReadContractReturnType, + useReadContract, +} from './useReadContract.js' + +test('select data', () => { + const result = useReadContract({ + address: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + query: { + select(data) { + expectTypeOf(data).toEqualTypeOf() + return data?.toString() + }, + }, + }) + expectTypeOf(result.data.value).toEqualTypeOf() +}) + +test('UseReadContractParameters', () => { + type Result = DeepUnwrapRef< + UseReadContractParameters + > + expectTypeOf<{ + functionName?: + | 'symbol' + | 'name' + | 'allowance' + | 'balanceOf' + | 'decimals' + | 'totalSupply' + | undefined + args?: readonly [Address] | undefined + }>().toEqualTypeOf>() +}) + +test('UseReadContractReturnType', () => { + type Result = UseReadContractReturnType + expectTypeOf().toEqualTypeOf() +}) + +test('overloads', () => { + const result1 = useReadContract({ + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + }) + assertType(result1.data.value) + + const result2 = useReadContract({ + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: [], + }) + assertType(result2.data.value) + + const result3 = useReadContract({ + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: ['0x'], + }) + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + assertType(result3.data) + + const result4 = useReadContract({ + address: '0x', + abi: abi.viewOverloads, + functionName: 'foo', + args: ['0x', '0x'], + }) + assertType< + | { + foo: `0x${string}` + bar: `0x${string}` + } + | undefined + // @ts-ignore – TODO: Fix https://github.com/wevm/viem/issues/1916 + >(result4.data) +}) + +test('deployless read (bytecode)', () => { + const result = useReadContract({ + code: '0x', + abi: abi.erc20, + functionName: 'balanceOf', + args: ['0x'], + }) + expectTypeOf(result.data.value).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/vue/src/composables/useReadContract.test.ts b/wagmi-project/packages/vue/src/composables/useReadContract.test.ts new file mode 100644 index 0000000000..2fe2fb7033 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useReadContract.test.ts @@ -0,0 +1,105 @@ +import { abi, address, bytecode, chain, wait } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { expect, test } from 'vitest' +import { ref } from 'vue' + +import { useReadContract } from './useReadContract.js' + +test('default', async () => { + const [result] = renderComposable(() => + useReadContract({ + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'balanceOf', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + }), + ) + + await waitFor(result.isSuccess) + + expect(result.data.value).toBe(4n) + expect(result.queryKey).toMatchInlineSnapshot(` + [ + "readContract", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": [ + "0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC", + ], + "chainId": 1, + "functionName": "balanceOf", + }, + ] + `) +}) + +test('parameters: chainId', async () => { + const [result] = renderComposable(() => + useReadContract({ + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'balanceOf', + args: ['0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC'], + chainId: chain.mainnet2.id, + }), + ) + + await waitFor(result.isSuccess) + + expect(result.data.value).toBe(4n) + expect(result.queryKey).toMatchInlineSnapshot(` + [ + "readContract", + { + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": [ + "0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC", + ], + "chainId": 456, + "functionName": "balanceOf", + }, + ] + `) +}) + +test('parameters: deployless read (bytecode)', async () => { + const [result] = renderComposable(() => + useReadContract({ + abi: abi.wagmiMintExample, + functionName: 'name', + code: bytecode.wagmiMintExample, + }), + ) + + await waitFor(result.isSuccess) + + expect(result.data.value).toMatchInlineSnapshot(`"wagmi"`) +}) + +test.skip('behavior: disabled when missing properties', async () => { + const addressRef = ref() + const abiRef = ref() + const functionNameRef = ref() + + const [result] = renderComposable(() => + useReadContract({ + abi: abiRef, + address: addressRef, + functionName: functionNameRef, + }), + ) + + await wait(100) + expect(result.fetchStatus.value).toBe('idle') + + addressRef.value = '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2' + + await wait(100) + expect(result.fetchStatus.value).toBe('idle') + + abiRef.value = abi.wagmiMintExample + functionNameRef.value = 'totalSupply' + + await wait(100) + expect(result.fetchStatus.value).toBe('fetching') +}) diff --git a/wagmi-project/packages/vue/src/composables/useReadContract.ts b/wagmi-project/packages/vue/src/composables/useReadContract.ts new file mode 100644 index 0000000000..10ecc859ff --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useReadContract.ts @@ -0,0 +1,116 @@ +import type { + Config, + ReadContractErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { UnionCompute } from '@wagmi/core/internal' +import { + type ReadContractData, + type ReadContractOptions, + type ReadContractQueryFnData, + type ReadContractQueryKey, + readContractQueryOptions, + structuralSharing, +} from '@wagmi/core/query' +import type { Abi, ContractFunctionArgs, ContractFunctionName } from 'viem' +import { computed } from 'vue' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import type { DeepMaybeRef } from '../types/ref.js' +import { deepUnref } from '../utils/cloneDeep.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseReadContractParameters< + abi extends Abi | readonly unknown[] = Abi, + functionName extends ContractFunctionName< + abi, + 'pure' | 'view' + > = ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'pure' | 'view', + functionName + > = ContractFunctionArgs, + config extends Config = Config, + selectData = ReadContractData, +> = UnionCompute< + DeepMaybeRef< + ReadContractOptions & + ConfigParameter & + QueryParameter< + ReadContractQueryFnData, + ReadContractErrorType, + selectData, + ReadContractQueryKey + > + > +> + +export type UseReadContractReturnType< + abi extends Abi | readonly unknown[] = Abi, + functionName extends ContractFunctionName< + abi, + 'pure' | 'view' + > = ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'pure' | 'view', + functionName + > = ContractFunctionArgs, + selectData = ReadContractData, +> = UseQueryReturnType + +/** https://wagmi.sh/vue/api/hooks/useReadContract */ +export function useReadContract< + const abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs, + config extends Config = ResolvedRegister['config'], + selectData = ReadContractData, +>( + parameters_: UseReadContractParameters< + abi, + functionName, + args, + config, + selectData + > = {} as any, +): UseReadContractReturnType { + const parameters = computed(() => deepUnref(parameters_)) as any + + const config = useConfig(parameters) + const configChainId = useChainId({ config }) + + const queryOptions = computed(() => { + const { + abi, + address, + chainId = configChainId.value, + code, + functionName, + query = {}, + } = parameters.value + const options = readContractQueryOptions( + config as any, + { ...parameters.value, chainId }, + ) + const enabled = Boolean( + (address || code) && abi && functionName && (query.enabled ?? true), + ) + return { + ...query, + ...options, + enabled, + structuralSharing: query.structuralSharing ?? structuralSharing, + } + }) + + return useQuery(queryOptions) as UseReadContractReturnType< + abi, + functionName, + args, + selectData + > +} diff --git a/wagmi-project/packages/vue/src/composables/useReconnect.test-d.ts b/wagmi-project/packages/vue/src/composables/useReconnect.test-d.ts new file mode 100644 index 0000000000..bc4ecd8d8a --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useReconnect.test-d.ts @@ -0,0 +1,154 @@ +import type { + Connector, + CreateConnectorFn, + ReconnectErrorType, +} from '@wagmi/core' +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import type { Address } from 'viem' +import { useReconnect } from './useReconnect.js' + +const connectors = [config.connectors[0]!] +const contextValue = { foo: 'bar' } as const + +test('context', () => { + const { context, data, error, reconnect, variables } = useReconnect({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toEqualTypeOf< + | { + connectors?: + | readonly (CreateConnectorFn | Connector)[] + | undefined + } + | undefined + >() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf< + | { + connectors?: + | readonly (CreateConnectorFn | Connector)[] + | undefined + } + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf< + | { + connectors?: + | readonly (CreateConnectorFn | Connector)[] + | undefined + } + | undefined + >() + expectTypeOf(data).toEqualTypeOf< + { + accounts: readonly [Address, ...Address[]] + chainId: number + connector: Connector + }[] + >() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf< + | { + accounts: readonly [Address, ...Address[]] + chainId: number + connector: Connector + }[] + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf< + | { + connectors?: + | readonly (CreateConnectorFn | Connector)[] + | undefined + } + | undefined + >() + expectTypeOf(context).toEqualTypeOf() + }, + }, + }) + + expectTypeOf(data.value).toEqualTypeOf< + | { + accounts: readonly [Address, ...Address[]] + chainId: number + connector: Connector + }[] + | undefined + >() + expectTypeOf(error.value).toEqualTypeOf() + expectTypeOf(variables.value).toEqualTypeOf< + | { + connectors?: readonly (CreateConnectorFn | Connector)[] | undefined + } + | undefined + >() + expectTypeOf(context.value).toEqualTypeOf() + + reconnect( + { connectors }, + { + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf< + | { + connectors?: + | readonly (CreateConnectorFn | Connector)[] + | undefined + } + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf< + | { + connectors?: + | readonly (CreateConnectorFn | Connector)[] + | undefined + } + | undefined + >() + expectTypeOf(data).toEqualTypeOf< + { + accounts: readonly [Address, ...Address[]] + chainId: number + connector: Connector + }[] + >() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf< + | { + accounts: readonly [Address, ...Address[]] + chainId: number + connector: Connector + }[] + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf< + | { + connectors?: + | readonly (CreateConnectorFn | Connector)[] + | undefined + } + | undefined + >() + expectTypeOf(context).toEqualTypeOf() + }, + }, + ) +}) diff --git a/wagmi-project/packages/vue/src/composables/useReconnect.test.ts b/wagmi-project/packages/vue/src/composables/useReconnect.test.ts new file mode 100644 index 0000000000..49cf7f73e5 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useReconnect.test.ts @@ -0,0 +1,81 @@ +import { mock } from '@wagmi/connectors' +import { connect, disconnect } from '@wagmi/core' +import { accounts, config } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { afterEach, expect, test } from 'vitest' + +import { useReconnect } from './useReconnect.js' + +const connector = config._internal.connectors.setup( + mock({ + accounts, + features: { reconnect: true }, + }), +) + +afterEach(async () => { + if (config.state.current) await disconnect(config) +}) + +test('default', async () => { + await connect(config, { connector }) + + const [reconnect] = renderComposable(() => useReconnect()) + + reconnect.reconnect() + await waitFor(reconnect.isSuccess) + + expect(reconnect.data.value).toStrictEqual([]) +}) + +test('parameters: connectors (Connector)', async () => { + await connect(config, { connector }) + + const [reconnect] = renderComposable(() => useReconnect()) + + reconnect.reconnect({ connectors: [connector] }) + await waitFor(reconnect.isSuccess) + + expect(reconnect.data.value).toMatchObject( + expect.arrayContaining([ + expect.objectContaining({ + accounts: expect.any(Array), + chainId: expect.any(Number), + }), + ]), + ) +}) + +test('parameters: connectors (CreateConnectorFn)', async () => { + const connector = mock({ + accounts, + features: { reconnect: true }, + }) + await connect(config, { connector }) + + const [reconnect] = renderComposable(() => useReconnect()) + + reconnect.reconnect({ connectors: [connector] }) + await waitFor(reconnect.isSuccess) + + expect(reconnect.data.value).toMatchObject( + expect.arrayContaining([ + expect.objectContaining({ + accounts: expect.any(Array), + chainId: expect.any(Number), + }), + ]), + ) +}) + +test("behavior: doesn't reconnect if already reconnecting", async () => { + const previousStatus = config.state.status + config.setState((x) => ({ ...x, status: 'reconnecting' })) + + const [reconnect] = renderComposable(() => useReconnect()) + + await expect( + reconnect.reconnectAsync({ connectors: [connector] }), + ).resolves.toStrictEqual([]) + config.setState((x) => ({ ...x, status: previousStatus })) +}) diff --git a/wagmi-project/packages/vue/src/composables/useReconnect.ts b/wagmi-project/packages/vue/src/composables/useReconnect.ts new file mode 100644 index 0000000000..cfab97d858 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useReconnect.ts @@ -0,0 +1,65 @@ +import { useMutation } from '@tanstack/vue-query' +import type { Connector, ReconnectErrorType } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type ReconnectData, + type ReconnectMutate, + type ReconnectMutateAsync, + type ReconnectVariables, + reconnectMutationOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' + +export type UseReconnectParameters = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + ReconnectData, + ReconnectErrorType, + ReconnectVariables, + context + > + | undefined + } +> + +export type UseReconnectReturnType = Compute< + UseMutationReturnType< + ReconnectData, + ReconnectErrorType, + ReconnectVariables, + context + > & { + connectors: readonly Connector[] + reconnect: ReconnectMutate + reconnectAsync: ReconnectMutateAsync + } +> + +/** https://wagmi.sh/vue/api/composables/useReconnect */ +export function useReconnect( + parameters: UseReconnectParameters = {}, +): UseReconnectReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = reconnectMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + return { + ...result, + connectors: config.connectors, + reconnect: mutate, + reconnectAsync: mutateAsync, + } +} diff --git a/wagmi-project/packages/vue/src/composables/useSendTransaction.test-d.ts b/wagmi-project/packages/vue/src/composables/useSendTransaction.test-d.ts new file mode 100644 index 0000000000..4670e879cf --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useSendTransaction.test-d.ts @@ -0,0 +1,78 @@ +import type { SendTransactionErrorType } from '@wagmi/core' +import type { Hash } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { useSendTransaction } from './useSendTransaction.js' + +const contextValue = { foo: 'bar' } as const + +test('context', () => { + const { context, data, error, sendTransaction, variables } = + useSendTransaction({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toMatchTypeOf< + { chainId?: number | undefined } | undefined + >() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + }>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + }>() + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + }>() + expectTypeOf(context).toEqualTypeOf() + }, + }, + }) + + expectTypeOf(data.value).toEqualTypeOf() + expectTypeOf(error.value).toEqualTypeOf() + expectTypeOf(variables.value).toMatchTypeOf< + { chainId?: number | undefined } | undefined + >() + expectTypeOf(context.value).toEqualTypeOf() + + sendTransaction( + { to: '0x' }, + { + onError(error, variables, context) { + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + }>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + }>() + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + }>() + expectTypeOf(context).toEqualTypeOf() + }, + }, + ) +}) diff --git a/wagmi-project/packages/vue/src/composables/useSendTransaction.test.ts b/wagmi-project/packages/vue/src/composables/useSendTransaction.test.ts new file mode 100644 index 0000000000..ae069766ee --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useSendTransaction.test.ts @@ -0,0 +1,25 @@ +import { connect, disconnect } from '@wagmi/core' +import { config, transactionHashRegex } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { parseEther } from 'viem' +import { expect, test } from 'vitest' + +import { useSendTransaction } from './useSendTransaction.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const [result] = renderComposable(() => useSendTransaction()) + + result.sendTransaction({ + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }) + await waitFor(result.isSuccess) + + expect(result.data.value).toMatch(transactionHashRegex) + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/vue/src/composables/useSendTransaction.ts b/wagmi-project/packages/vue/src/composables/useSendTransaction.ts new file mode 100644 index 0000000000..d5bc718337 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useSendTransaction.ts @@ -0,0 +1,76 @@ +import { useMutation } from '@tanstack/vue-query' +import type { + Config, + ResolvedRegister, + SendTransactionErrorType, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type SendTransactionData, + type SendTransactionMutate, + type SendTransactionMutateAsync, + type SendTransactionVariables, + sendTransactionMutationOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' + +export type UseSendTransactionParameters< + config extends Config = Config, + context = unknown, +> = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + SendTransactionData, + SendTransactionErrorType, + SendTransactionVariables, + context + > + | undefined + } +> + +export type UseSendTransactionReturnType< + config extends Config = Config, + context = unknown, +> = Compute< + UseMutationReturnType< + SendTransactionData, + SendTransactionErrorType, + SendTransactionVariables, + context + > & { + sendTransaction: SendTransactionMutate + sendTransactionAsync: SendTransactionMutateAsync + } +> + +/** https://wagmi.sh/vue/api/composables/useSendTransaction */ +export function useSendTransaction< + config extends Config = ResolvedRegister['config'], + context = unknown, +>( + parameters: UseSendTransactionParameters = {}, +): UseSendTransactionReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = sendTransactionMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + return { + ...result, + sendTransaction: mutate, + sendTransactionAsync: mutateAsync, + } as UseSendTransactionReturnType +} diff --git a/wagmi-project/packages/vue/src/composables/useSignMessage.test-d.ts b/wagmi-project/packages/vue/src/composables/useSignMessage.test-d.ts new file mode 100644 index 0000000000..5c8da53bba --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useSignMessage.test-d.ts @@ -0,0 +1,64 @@ +import type { SignMessageErrorType } from '@wagmi/core' +import type { SignMessageVariables } from '@wagmi/core/query' +import { expectTypeOf, test } from 'vitest' + +import { useSignMessage } from './useSignMessage.js' + +const message = 'hello world' +const contextValue = { foo: 'bar' } as const + +test('context', () => { + const { context, data, error, signMessage, variables } = useSignMessage({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toEqualTypeOf() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(data).toEqualTypeOf<`0x${string}`>() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf<`0x${string}` | undefined>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + }, + }) + + expectTypeOf(data.value).toEqualTypeOf<`0x${string}` | undefined>() + expectTypeOf(error.value).toEqualTypeOf() + expectTypeOf(variables.value).toEqualTypeOf< + SignMessageVariables | undefined + >() + expectTypeOf(context.value).toEqualTypeOf() + + signMessage( + { message }, + { + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(data).toEqualTypeOf<`0x${string}`>() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf<`0x${string}` | undefined>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + }, + ) +}) diff --git a/wagmi-project/packages/vue/src/composables/useSignMessage.test.ts b/wagmi-project/packages/vue/src/composables/useSignMessage.test.ts new file mode 100644 index 0000000000..a00691fb7f --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useSignMessage.test.ts @@ -0,0 +1,43 @@ +import { connect, disconnect, getAccount } from '@wagmi/core' +import { config, privateKey } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { recoverMessageAddress } from 'viem' +import { expect, test } from 'vitest' + +import { privateKeyToAccount } from 'viem/accounts' +import { useSignMessage } from './useSignMessage.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const [result] = renderComposable(() => useSignMessage()) + + result.signMessage({ message: 'foo bar baz' }) + await waitFor(result.isSuccess) + + await expect( + recoverMessageAddress({ + message: 'foo bar baz', + signature: result.data.value!, + }), + ).resolves.toEqual(getAccount(config).address) + + await disconnect(config, { connector }) +}) + +test('behavior: local account', async () => { + const [result] = renderComposable(() => useSignMessage()) + + const account = privateKeyToAccount(privateKey) + result.signMessage({ account, message: 'foo bar baz' }) + await waitFor(result.isSuccess) + + await expect( + recoverMessageAddress({ + message: 'foo bar baz', + signature: result.data.value!, + }), + ).resolves.toEqual(account.address) +}) diff --git a/wagmi-project/packages/vue/src/composables/useSignMessage.ts b/wagmi-project/packages/vue/src/composables/useSignMessage.ts new file mode 100644 index 0000000000..2f7222b6a4 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useSignMessage.ts @@ -0,0 +1,63 @@ +import type { SignMessageErrorType } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type SignMessageData, + type SignMessageMutate, + type SignMessageMutateAsync, + type SignMessageVariables, + signMessageMutationOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter } from '../types/properties.js' +import { + type UseMutationParameters, + type UseMutationReturnType, + useMutation, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' + +export type UseSignMessageParameters = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + SignMessageData, + SignMessageErrorType, + SignMessageVariables, + context + > + | undefined + } +> + +export type UseSignMessageReturnType = Compute< + UseMutationReturnType< + SignMessageData, + SignMessageErrorType, + SignMessageVariables, + context + > & { + signMessage: SignMessageMutate + signMessageAsync: SignMessageMutateAsync + } +> + +/** https://wagmi.sh/vue/api/composables/useSignMessage */ +export function useSignMessage( + parameters: UseSignMessageParameters = {}, +): UseSignMessageReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = signMessageMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + return { + ...result, + signMessage: mutate, + signMessageAsync: mutateAsync, + } +} diff --git a/wagmi-project/packages/vue/src/composables/useSignTypedData.test-d.ts b/wagmi-project/packages/vue/src/composables/useSignTypedData.test-d.ts new file mode 100644 index 0000000000..ba5c253a8f --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useSignTypedData.test-d.ts @@ -0,0 +1,95 @@ +import type { + SignTypedDataErrorType, + SignTypedDataReturnType, +} from '@wagmi/core' +import type { SignTypedDataVariables } from '@wagmi/core/query' +import { typedData } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { useSignTypedData } from './useSignTypedData.js' + +const contextValue = { foo: 'bar' } as const + +test('context', () => { + const { context, data, error, signTypedData, variables } = useSignTypedData({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toMatchTypeOf() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(variables).toMatchTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toMatchTypeOf() + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toMatchTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + }, + }) + + expectTypeOf(data.value).toEqualTypeOf() + expectTypeOf(error.value).toEqualTypeOf() + expectTypeOf(variables.value).toMatchTypeOf< + SignTypedDataVariables | undefined + >() + expectTypeOf(context.value).toEqualTypeOf() + + signTypedData( + { + types: typedData.basic.types, + primaryType: 'Person', + message: { + name: 'Bob', + wallet: '0x', + }, + }, + { + onError(error, variables, context) { + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toMatchTypeOf<{ + types: typeof typedData.basic.types + primaryType: 'Person' + message: { + name: string + wallet: `0x${string}` + } + }>() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(variables).toMatchTypeOf<{ + types: typeof typedData.basic.types + primaryType: 'Person' + message: { + name: string + wallet: `0x${string}` + } + }>() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toMatchTypeOf<{ + types: typeof typedData.basic.types + primaryType: 'Person' + message: { + name: string + wallet: `0x${string}` + } + }>() + expectTypeOf(context).toEqualTypeOf() + }, + }, + ) +}) diff --git a/wagmi-project/packages/vue/src/composables/useSignTypedData.test.ts b/wagmi-project/packages/vue/src/composables/useSignTypedData.test.ts new file mode 100644 index 0000000000..e3636d21eb --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useSignTypedData.test.ts @@ -0,0 +1,56 @@ +import { connect, disconnect, getAccount } from '@wagmi/core' +import { config, privateKey, typedData } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { recoverTypedDataAddress } from 'viem' +import { expect, test } from 'vitest' + +import { privateKeyToAccount } from 'viem/accounts' +import { useSignTypedData } from './useSignTypedData.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const [result] = renderComposable(() => useSignTypedData()) + + result.signTypedData({ + types: typedData.basic.types, + primaryType: 'Mail', + message: typedData.basic.message, + }) + await waitFor(result.isSuccess) + + await expect( + recoverTypedDataAddress({ + types: typedData.basic.types, + primaryType: 'Mail', + message: typedData.basic.message, + signature: result.data.value!, + }), + ).resolves.toEqual(getAccount(config).address) + + await disconnect(config, { connector }) +}) + +test('behavior: local account', async () => { + const [result] = renderComposable(() => useSignTypedData()) + + const account = privateKeyToAccount(privateKey) + result.signTypedData({ + account, + types: typedData.basic.types, + primaryType: 'Mail', + message: typedData.basic.message, + }) + await waitFor(result.isSuccess) + + await expect( + recoverTypedDataAddress({ + types: typedData.basic.types, + primaryType: 'Mail', + message: typedData.basic.message, + signature: result.data.value!, + }), + ).resolves.toEqual(account.address) +}) diff --git a/wagmi-project/packages/vue/src/composables/useSignTypedData.ts b/wagmi-project/packages/vue/src/composables/useSignTypedData.ts new file mode 100644 index 0000000000..f0bdbf6c64 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useSignTypedData.ts @@ -0,0 +1,64 @@ +import type { SignTypedDataErrorType } from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type SignTypedDataData, + type SignTypedDataMutate, + type SignTypedDataMutateAsync, + type SignTypedDataVariables, + signTypedDataMutationOptions, +} from '@wagmi/core/query' + +import type { ConfigParameter } from '../types/properties.js' +import { + type UseMutationParameters, + type UseMutationReturnType, + useMutation, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' + +export type UseSignTypedDataParameters = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + SignTypedDataData, + SignTypedDataErrorType, + SignTypedDataVariables, + context + > + | undefined + } +> + +export type UseSignTypedDataReturnType = Compute< + UseMutationReturnType< + SignTypedDataData, + SignTypedDataErrorType, + SignTypedDataVariables, + context + > & { + signTypedData: SignTypedDataMutate + signTypedDataAsync: SignTypedDataMutateAsync + } +> + +/** https://wagmi.sh/vue/api/composables/useSignTypedData */ +export function useSignTypedData( + parameters: UseSignTypedDataParameters = {}, +): UseSignTypedDataReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = signTypedDataMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + type Return = UseSignTypedDataReturnType + return { + ...result, + signTypedData: mutate as Return['signTypedData'], + signTypedDataAsync: mutateAsync as Return['signTypedDataAsync'], + } +} diff --git a/wagmi-project/packages/vue/src/composables/useSimulateContract.test-d.ts b/wagmi-project/packages/vue/src/composables/useSimulateContract.test-d.ts new file mode 100644 index 0000000000..e8d2451caa --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useSimulateContract.test-d.ts @@ -0,0 +1,96 @@ +import { abi, type config } from '@wagmi/test' +import type { Address } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { + type UseSimulateContractReturnType, + useSimulateContract, +} from './useSimulateContract.js' + +test('default', () => { + const result = useSimulateContract({ + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + }) + + expectTypeOf(result.data.value).toMatchTypeOf< + | { + result: boolean + request: { + chainId?: undefined + abi: readonly [ + { + readonly name: 'transferFrom' + readonly type: 'function' + readonly stateMutability: 'nonpayable' + readonly inputs: readonly [ + { readonly type: 'address'; readonly name: 'sender' }, + { readonly type: 'address'; readonly name: 'recipient' }, + { readonly type: 'uint256'; readonly name: 'amount' }, + ] + readonly outputs: readonly [{ type: 'bool' }] + }, + ] + functionName: 'transferFrom' + args: readonly [Address, Address, bigint] + } + } + | undefined + >() +}) + +test('select data', () => { + // @ts-ignore TODO: Type instantiation is excessively deep and possibly infinite. + const result = useSimulateContract({ + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + chainId: 1, + query: { + select(data) { + expectTypeOf(data.result).toEqualTypeOf() + return data.request.args + }, + }, + }) + expectTypeOf(result.data.value).toEqualTypeOf< + readonly [Address, Address, bigint] | undefined + >() +}) + +test('UseSimulateContractReturnType', () => { + type Result = UseSimulateContractReturnType< + typeof abi.erc20, + 'transferFrom', + ['0x', '0x', 123n], + typeof config, + 1 + > + expectTypeOf().toMatchTypeOf< + | { + result: boolean + request: { + chainId: number + abi: readonly [ + { + readonly name: 'transferFrom' + readonly type: 'function' + readonly stateMutability: 'nonpayable' + readonly inputs: readonly [ + { readonly type: 'address'; readonly name: 'sender' }, + { readonly type: 'address'; readonly name: 'recipient' }, + { readonly type: 'uint256'; readonly name: 'amount' }, + ] + readonly outputs: readonly [{ type: 'bool' }] + }, + ] + functionName: 'approve' | 'transfer' | 'transferFrom' + args: readonly [Address, Address, bigint] + } + } + | undefined + >() +}) diff --git a/wagmi-project/packages/vue/src/composables/useSimulateContract.test.ts b/wagmi-project/packages/vue/src/composables/useSimulateContract.test.ts new file mode 100644 index 0000000000..1118a51d68 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useSimulateContract.test.ts @@ -0,0 +1,59 @@ +import { connect, disconnect } from '@wagmi/core' +import { abi, address, config, wait } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { expect, test } from 'vitest' + +import { useSimulateContract } from './useSimulateContract.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const [result] = renderComposable(() => + useSimulateContract({ + address: address.wagmiMintExample, + abi: abi.wagmiMintExample, + functionName: 'mint', + }), + ) + + await waitFor(result.isSuccess) + + expect(result.data.value).toMatchInlineSnapshot(` + { + "chainId": 1, + "request": { + "abi": [ + { + "inputs": [], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function", + }, + ], + "account": { + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "type": "json-rpc", + }, + "address": "0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2", + "args": undefined, + "chainId": 1, + "dataSuffix": undefined, + "functionName": "mint", + }, + "result": undefined, + } + `) + + await disconnect(config, { connector }) +}) + +test('behavior: disabled when properties missing', async () => { + const [result] = renderComposable(() => useSimulateContract()) + + await wait(100) + + expect(result.fetchStatus.value).toBe('idle') +}) diff --git a/wagmi-project/packages/vue/src/composables/useSimulateContract.ts b/wagmi-project/packages/vue/src/composables/useSimulateContract.ts new file mode 100644 index 0000000000..7ffce57b8e --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useSimulateContract.ts @@ -0,0 +1,145 @@ +import type { + Config, + ResolvedRegister, + SimulateContractErrorType, +} from '@wagmi/core' +import { + type SimulateContractData, + type SimulateContractOptions, + type SimulateContractQueryFnData, + type SimulateContractQueryKey, + simulateContractQueryOptions, +} from '@wagmi/core/query' +import type { Abi, ContractFunctionArgs, ContractFunctionName } from 'viem' +import { type MaybeRef, computed } from 'vue' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import type { DeepMaybeRef } from '../types/ref.js' +import { deepUnref } from '../utils/cloneDeep.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' +import { useConnectorClient } from './useConnectorClient.js' + +export type UseSimulateContractParameters< + abi extends Abi | readonly unknown[] = Abi, + functionName extends ContractFunctionName< + abi, + 'nonpayable' | 'payable' + > = ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + > = ContractFunctionArgs, + config extends Config = Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, + selectData = SimulateContractData, +> = MaybeRef< + DeepMaybeRef< + SimulateContractOptions + > & + ConfigParameter & + QueryParameter< + SimulateContractQueryFnData, + SimulateContractErrorType, + selectData, + SimulateContractQueryKey + > +> + +export type UseSimulateContractReturnType< + abi extends Abi | readonly unknown[] = Abi, + functionName extends ContractFunctionName< + abi, + 'nonpayable' | 'payable' + > = ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + > = ContractFunctionArgs, + config extends Config = Config, + chainId extends config['chains'][number]['id'] | undefined = undefined, + selectData = SimulateContractData, +> = UseQueryReturnType + +/** https://wagmi.sh/vue/api/composables/useSimulateContract */ +export function useSimulateContract< + const abi extends Abi | readonly unknown[], + functionName extends ContractFunctionName, + args extends ContractFunctionArgs< + abi, + 'nonpayable' | 'payable', + functionName + >, + config extends Config = ResolvedRegister['config'], + chainId extends config['chains'][number]['id'] | undefined = undefined, + selectData = SimulateContractData, +>( + parameters_: UseSimulateContractParameters< + abi, + functionName, + args, + config, + chainId, + selectData + > = {} as any, +): UseSimulateContractReturnType< + abi, + functionName, + args, + config, + chainId, + selectData +> { + const parameters = computed(() => deepUnref(parameters_)) as any + + const config = useConfig(parameters) + const { data: connectorClient } = useConnectorClient( + computed(() => ({ + connector: parameters.value.connector, + query: { enabled: parameters.value.account === undefined }, + })), + ) + const configChainId = useChainId({ config }) + + const queryOptions = computed(() => { + const { + abi, + account = connectorClient?.value?.account, + address, + chainId = configChainId.value, + functionName, + query = {}, + } = parameters.value + const options = simulateContractQueryOptions< + config, + abi, + functionName, + args, + chainId + >(config as any, { + ...parameters.value, + account, + chainId, + }) + const enabled = Boolean( + abi && address && functionName && (query.enabled ?? true), + ) + return { + ...query, + ...options, + enabled, + } + }) + + return useQuery(queryOptions as any) as UseSimulateContractReturnType< + abi, + functionName, + args, + config, + chainId, + selectData + > +} diff --git a/wagmi-project/packages/vue/src/composables/useSwitchAccount.test-d.ts b/wagmi-project/packages/vue/src/composables/useSwitchAccount.test-d.ts new file mode 100644 index 0000000000..d55e4b9d5e --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useSwitchAccount.test-d.ts @@ -0,0 +1,89 @@ +import type { Connector, SwitchAccountErrorType } from '@wagmi/core' +import { config } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import type { Address } from 'viem' +import { useSwitchAccount } from './useSwitchAccount.js' + +const connector = config.connectors[0]! +const contextValue = { foo: 'bar' } as const + +test('context', () => { + const { context, data, error, switchAccount, variables } = useSwitchAccount({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toEqualTypeOf<{ connector: Connector }>() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ connector: Connector }>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ connector: Connector }>() + expectTypeOf(data).toEqualTypeOf<{ + accounts: readonly [Address, ...Address[]] + chainId: number + }>() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf< + | { + accounts: readonly [Address, ...Address[]] + chainId: number + } + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf<{ connector: Connector }>() + expectTypeOf(context).toEqualTypeOf() + }, + }, + }) + + expectTypeOf(data.value).toEqualTypeOf< + | { + accounts: readonly [Address, ...Address[]] + chainId: number + } + | undefined + >() + expectTypeOf(error.value).toEqualTypeOf() + expectTypeOf(variables.value).toEqualTypeOf< + { connector: Connector } | undefined + >() + expectTypeOf(context.value).toEqualTypeOf() + + switchAccount( + { connector }, + { + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ connector: Connector }>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ connector: Connector }>() + expectTypeOf(data).toEqualTypeOf<{ + accounts: readonly [Address, ...Address[]] + chainId: number + }>() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf< + | { + accounts: readonly [Address, ...Address[]] + chainId: number + } + | undefined + >() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf<{ connector: Connector }>() + expectTypeOf(context).toEqualTypeOf() + }, + }, + ) +}) diff --git a/wagmi-project/packages/vue/src/composables/useSwitchAccount.test.ts b/wagmi-project/packages/vue/src/composables/useSwitchAccount.test.ts new file mode 100644 index 0000000000..aade28e3d2 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useSwitchAccount.test.ts @@ -0,0 +1,42 @@ +import { connect, disconnect } from '@wagmi/core' +import { config } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { expect, test } from 'vitest' + +import { useAccount } from './useAccount.js' +import { useSwitchAccount } from './useSwitchAccount.js' + +const connector1 = config.connectors[0]! +const connector2 = config.connectors[1]! + +test('default', async () => { + const [account] = renderComposable(() => useAccount()) + const [switchAccount] = renderComposable(() => useSwitchAccount()) + + expect(switchAccount.connectors.value).toEqual([]) + + await connect(config, { connector: connector2 }) + await connect(config, { connector: connector1 }) + + expect(switchAccount.connectors.value.length).toEqual(2) + + const address1 = account.address.value + expect(address1).toBeDefined() + + switchAccount.switchAccount({ connector: connector2 }) + await waitFor(switchAccount.isSuccess) + + const address2 = account.address.value + expect(address2).toBeDefined() + expect(address1).not.toBe(address2) + + switchAccount.switchAccount({ connector: connector1 }) + await waitFor(switchAccount.isSuccess) + + const address3 = account.address.value + expect(address3).toBeDefined() + expect(address1).toBe(address3) + + await disconnect(config, { connector: connector1 }) + await disconnect(config, { connector: connector2 }) +}) diff --git a/wagmi-project/packages/vue/src/composables/useSwitchAccount.ts b/wagmi-project/packages/vue/src/composables/useSwitchAccount.ts new file mode 100644 index 0000000000..0c8f76a486 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useSwitchAccount.ts @@ -0,0 +1,84 @@ +import { useMutation } from '@tanstack/vue-query' +import type { + Config, + Connector, + ResolvedRegister, + SwitchAccountErrorType, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type SwitchAccountData, + type SwitchAccountMutate, + type SwitchAccountMutateAsync, + type SwitchAccountVariables, + switchAccountMutationOptions, +} from '@wagmi/core/query' +import { type Ref, computed } from 'vue' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' +import { useConnections } from './useConnections.js' + +export type UseSwitchAccountParameters< + config extends Config = Config, + context = unknown, +> = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + SwitchAccountData, + SwitchAccountErrorType, + SwitchAccountVariables, + context + > + | undefined + } +> + +export type UseSwitchAccountReturnType< + config extends Config = Config, + context = unknown, +> = Compute< + UseMutationReturnType< + SwitchAccountData, + SwitchAccountErrorType, + SwitchAccountVariables, + context + > & { + connectors: Ref + switchAccount: SwitchAccountMutate + switchAccountAsync: SwitchAccountMutateAsync + } +> + +/** https://wagmi.sh/vue/api/composables/useSwitchAccount */ +export function useSwitchAccount< + config extends Config = ResolvedRegister['config'], + context = unknown, +>( + parameters: UseSwitchAccountParameters = {}, +): UseSwitchAccountReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + const connections = useConnections({ config }) + + const mutationOptions = switchAccountMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + return { + ...result, + connectors: computed(() => + connections.value.map((connection) => connection.connector), + ), + switchAccount: mutate, + switchAccountAsync: mutateAsync, + } +} diff --git a/wagmi-project/packages/vue/src/composables/useSwitchChain.test-d.ts b/wagmi-project/packages/vue/src/composables/useSwitchChain.test-d.ts new file mode 100644 index 0000000000..e770460946 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useSwitchChain.test-d.ts @@ -0,0 +1,118 @@ +import type { Connector, SwitchChainErrorType } from '@wagmi/core' +import type { Chain } from '@wagmi/core/chains' +import type { Compute, ExactPartial } from '@wagmi/core/internal' +import { chain } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import type { AddEthereumChainParameter } from 'viem' +import { useSwitchChain } from './useSwitchChain.js' + +const chainId = chain.mainnet.id +const contextValue = { foo: 'bar' } as const + +test('context', () => { + const { chains, context, data, error, switchChain, variables } = + useSwitchChain({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toEqualTypeOf<{ + addEthereumChainParameter?: + | ExactPartial> + | undefined + chainId: number + connector?: Connector | undefined + }>() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ + addEthereumChainParameter?: + | ExactPartial> + | undefined + chainId: number + connector?: Connector | undefined + }>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ + addEthereumChainParameter?: + | ExactPartial> + | undefined + chainId: number + connector?: Connector | undefined + }>() + expectTypeOf(data).toEqualTypeOf>() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf | undefined>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf<{ + addEthereumChainParameter?: + | ExactPartial> + | undefined + chainId: number + connector?: Connector | undefined + }>() + expectTypeOf(context).toEqualTypeOf() + }, + }, + }) + + expectTypeOf(chains.value).toEqualTypeOf() + expectTypeOf(data.value).toEqualTypeOf | undefined>() + expectTypeOf(error.value).toEqualTypeOf() + expectTypeOf(variables.value).toEqualTypeOf< + | { + addEthereumChainParameter?: + | ExactPartial> + | undefined + chainId: number + connector?: Connector | undefined + } + | undefined + >() + expectTypeOf(context.value).toEqualTypeOf() + + switchChain( + { chainId }, + { + onError(error, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ + addEthereumChainParameter?: + | ExactPartial> + | undefined + chainId: number + connector?: Connector | undefined + }>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + }, + onSuccess(data, variables, context) { + expectTypeOf(variables).toEqualTypeOf<{ + addEthereumChainParameter?: + | ExactPartial> + | undefined + chainId: number + connector?: Connector | undefined + }>() + expectTypeOf(data).toEqualTypeOf>() + expectTypeOf(context).toEqualTypeOf() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf | undefined>() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(variables).toEqualTypeOf<{ + addEthereumChainParameter?: + | ExactPartial> + | undefined + chainId: number + connector?: Connector | undefined + }>() + expectTypeOf(context).toEqualTypeOf() + }, + }, + ) +}) diff --git a/wagmi-project/packages/vue/src/composables/useSwitchChain.test.ts b/wagmi-project/packages/vue/src/composables/useSwitchChain.test.ts new file mode 100644 index 0000000000..12e7c21c2e --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useSwitchChain.test.ts @@ -0,0 +1,35 @@ +import { connect, disconnect } from '@wagmi/core' +import { chain, config } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { expect, test } from 'vitest' + +import { useAccount } from './useAccount.js' +import { useSwitchChain } from './useSwitchChain.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const [account] = renderComposable(() => useAccount()) + const [switchChain] = renderComposable(() => useSwitchChain()) + + const chainId1 = account.chainId.value + expect(chainId1).toBeDefined() + + switchChain.switchChain({ chainId: chain.mainnet2.id }) + await waitFor(switchChain.isSuccess) + + const chainId2 = account.chainId.value + expect(chainId2).toBeDefined() + expect(chainId1).not.toBe(chainId2) + + switchChain.switchChain({ chainId: chain.mainnet.id }) + await waitFor(switchChain.isSuccess) + + const chainId3 = account.chainId.value + expect(chainId3).toBeDefined() + expect(chainId1).toBe(chainId3) + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/vue/src/composables/useSwitchChain.ts b/wagmi-project/packages/vue/src/composables/useSwitchChain.ts new file mode 100644 index 0000000000..8ff43c0fa9 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useSwitchChain.ts @@ -0,0 +1,81 @@ +import { useMutation } from '@tanstack/vue-query' +import type { + Config, + ResolvedRegister, + SwitchChainErrorType, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type SwitchChainData, + type SwitchChainMutate, + type SwitchChainMutateAsync, + type SwitchChainVariables, + switchChainMutationOptions, +} from '@wagmi/core/query' +import type { Ref } from 'vue' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useChains } from './useChains.js' +import { useConfig } from './useConfig.js' + +export type UseSwitchChainParameters< + config extends Config = Config, + context = unknown, +> = Compute< + ConfigParameter & { + mutation?: + | UseMutationParameters< + SwitchChainData, + SwitchChainErrorType, + SwitchChainVariables, + context + > + | undefined + } +> + +export type UseSwitchChainReturnType< + config extends Config = Config, + context = unknown, +> = Compute< + UseMutationReturnType< + SwitchChainData, + SwitchChainErrorType, + SwitchChainVariables, + context + > & { + chains: Ref + switchChain: SwitchChainMutate + switchChainAsync: SwitchChainMutateAsync + } +> + +/** https://wagmi.sh/vue/api/composables/useSwitchChain */ +export function useSwitchChain< + config extends Config = ResolvedRegister['config'], + context = unknown, +>( + parameters: UseSwitchChainParameters = {}, +): UseSwitchChainReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = switchChainMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + type Return = UseSwitchChainReturnType + return { + ...result, + chains: useChains({ config }) as unknown as Ref, + switchChain: mutate as Return['switchChain'], + switchChainAsync: mutateAsync as Return['switchChainAsync'], + } as Return +} diff --git a/wagmi-project/packages/vue/src/composables/useTransaction.test-d.ts b/wagmi-project/packages/vue/src/composables/useTransaction.test-d.ts new file mode 100644 index 0000000000..bb795814e8 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useTransaction.test-d.ts @@ -0,0 +1,14 @@ +import { expectTypeOf, test } from 'vitest' + +import { useTransaction } from './useTransaction.js' + +test('select data', () => { + const result = useTransaction({ + query: { + select(data) { + return data?.nonce + }, + }, + }) + expectTypeOf(result.data.value).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/vue/src/composables/useTransaction.test.ts b/wagmi-project/packages/vue/src/composables/useTransaction.test.ts new file mode 100644 index 0000000000..06659958f2 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useTransaction.test.ts @@ -0,0 +1,74 @@ +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { expect, test } from 'vitest' + +import { deepUnref } from '../utils/cloneDeep.js' +import { useTransaction } from './useTransaction.js' + +test('default', async () => { + const [result] = renderComposable(() => + useTransaction({ + hash: '0x60668ed8c2dc110d61d945a936fcd45b8f13654e5c78481c8c825d1148c7ef30', + }), + ) + + await waitFor(result.isSuccess) + + expect(deepUnref(result)).toMatchInlineSnapshot(` + { + "data": { + "accessList": [], + "blockHash": "0xd725a38b51e5ceec8c5f6c9ccfdb2cc423af993bb650af5eedca5e4be7156ba7", + "blockNumber": 15189204n, + "chainId": 1, + "from": "0xa0cf798816d4b9b9866b5330eea46a18382f251e", + "gas": 21000n, + "gasPrice": 9371645552n, + "hash": "0x60668ed8c2dc110d61d945a936fcd45b8f13654e5c78481c8c825d1148c7ef30", + "input": "0x", + "maxFeePerGas": 13644824566n, + "maxPriorityFeePerGas": 1500000000n, + "nonce": 86, + "r": "0x40174f9a38df876c1a7ce2587848819d4082ccd6d67a88aa5cabe59bf594e14f", + "s": "0x7c0c82f62a8a5a9b0e9cf30a54a72fdae8fc54b5b79ddafef0acd30e94e83872", + "to": "0xd2135cfb216b74109775236e36d4b433f1df507b", + "transactionIndex": 144, + "type": "eip1559", + "typeHex": "0x2", + "v": 0n, + "value": 100000000000000000n, + "yParity": 0, + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "transaction", + { + "chainId": 1, + "hash": "0x60668ed8c2dc110d61d945a936fcd45b8f13654e5c78481c8c825d1148c7ef30", + }, + ], + "refetch": [Function], + "status": "success", + "suspense": [Function], + } + `) +}) diff --git a/wagmi-project/packages/vue/src/composables/useTransaction.ts b/wagmi-project/packages/vue/src/composables/useTransaction.ts new file mode 100644 index 0000000000..eea49e68c1 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useTransaction.ts @@ -0,0 +1,91 @@ +import type { + Config, + GetTransactionErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetTransactionData, + type GetTransactionOptions, + type GetTransactionQueryFnData, + type GetTransactionQueryKey, + getTransactionQueryOptions, +} from '@wagmi/core/query' + +import { computed } from 'vue' +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import type { DeepMaybeRef } from '../types/ref.js' +import { deepUnref } from '../utils/cloneDeep.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseTransactionParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetTransactionData, +> = Compute< + DeepMaybeRef< + GetTransactionOptions & + ConfigParameter & + QueryParameter< + GetTransactionQueryFnData, + GetTransactionErrorType, + selectData, + GetTransactionQueryKey + > + > +> + +export type UseTransactionReturnType< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetTransactionData, +> = UseQueryReturnType + +/** https://wagmi.sh/vue/api/composables/useTransaction */ +export function useTransaction< + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetTransactionData, +>( + parameters_: UseTransactionParameters = {}, +): UseTransactionReturnType { + const parameters = computed(() => deepUnref(parameters_)) + + const config = useConfig(parameters) + const configChainId = useChainId({ config }) + + const queryOptions = computed(() => { + const { + blockHash, + blockNumber, + blockTag, + chainId = configChainId.value, + hash, + query = {}, + } = parameters.value + const options = getTransactionQueryOptions(config, { + ...parameters.value, + chainId, + }) + const enabled = Boolean( + !(blockHash && blockNumber && blockTag && hash) && + (query.enabled ?? true), + ) + return { + ...query, + ...options, + enabled, + } + }) + + return useQuery(queryOptions as any) as UseTransactionReturnType< + config, + chainId, + selectData + > +} diff --git a/wagmi-project/packages/vue/src/composables/useTransactionReceipt.test-d.ts b/wagmi-project/packages/vue/src/composables/useTransactionReceipt.test-d.ts new file mode 100644 index 0000000000..180d8354d8 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useTransactionReceipt.test-d.ts @@ -0,0 +1,14 @@ +import { expectTypeOf, test } from 'vitest' + +import { useTransactionReceipt } from './useTransactionReceipt.js' + +test('select data', () => { + const result = useTransactionReceipt({ + query: { + select(data) { + return data?.blockNumber + }, + }, + }) + expectTypeOf(result.data.value).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/vue/src/composables/useTransactionReceipt.test.ts b/wagmi-project/packages/vue/src/composables/useTransactionReceipt.test.ts new file mode 100644 index 0000000000..0092671427 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useTransactionReceipt.test.ts @@ -0,0 +1,208 @@ +import { chain, wait } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { expect, test } from 'vitest' +import { ref } from 'vue' +import { deepUnref } from '../utils/cloneDeep.js' +import { useTransactionReceipt } from './useTransactionReceipt.js' + +test('default', async () => { + const [result] = renderComposable(() => + useTransactionReceipt({ + hash: '0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871', + }), + ) + + await waitFor(result.isSuccess) + + expect(deepUnref(result)).toMatchInlineSnapshot(` + { + "data": { + "blockHash": "0xb932f77cf770d1d1c8f861153eec1e990f5d56b6ffdb4ac06aef3cca51ef37d4", + "blockNumber": 16280769n, + "contractAddress": null, + "cumulativeGasUsed": 21000n, + "effectiveGasPrice": 33427926161n, + "from": "0x043022ef9fca1066024d19d681e2ccf44ff90de3", + "gasUsed": 21000n, + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "status": "success", + "to": "0x318a5fb4f1604fc46375a1db9a9018b6e423b345", + "transactionHash": "0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871", + "transactionIndex": 0, + "type": "legacy", + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getTransactionReceipt", + { + "chainId": 1, + "hash": "0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871", + }, + ], + "refetch": [Function], + "status": "success", + "suspense": [Function], + } + `) +}) + +test('parameters: chainId', async () => { + const [result] = renderComposable(() => + useTransactionReceipt({ + chainId: chain.mainnet2.id, + hash: '0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871', + }), + ) + + await waitFor(result.isSuccess) + + expect(deepUnref(result)).toMatchInlineSnapshot(` + { + "data": { + "blockHash": "0xb932f77cf770d1d1c8f861153eec1e990f5d56b6ffdb4ac06aef3cca51ef37d4", + "blockNumber": 16280769n, + "contractAddress": null, + "cumulativeGasUsed": 21000n, + "effectiveGasPrice": 33427926161n, + "from": "0x043022ef9fca1066024d19d681e2ccf44ff90de3", + "gasUsed": 21000n, + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "status": "success", + "to": "0x318a5fb4f1604fc46375a1db9a9018b6e423b345", + "transactionHash": "0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871", + "transactionIndex": 0, + "type": "legacy", + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getTransactionReceipt", + { + "chainId": 456, + "hash": "0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871", + }, + ], + "refetch": [Function], + "status": "success", + "suspense": [Function], + } + `) +}) + +test('behavior: hash: undefined -> defined', async () => { + const hash = ref() + + const [result] = renderComposable(() => + useTransactionReceipt({ + hash, + }), + ) + + await wait(100) + expect(result.fetchStatus.value).toBe('idle') + + hash.value = + '0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871' + + await waitFor(result.isSuccess) + + expect(deepUnref(result)).toMatchInlineSnapshot(` + { + "data": { + "blockHash": "0xb932f77cf770d1d1c8f861153eec1e990f5d56b6ffdb4ac06aef3cca51ef37d4", + "blockNumber": 16280769n, + "contractAddress": null, + "cumulativeGasUsed": 21000n, + "effectiveGasPrice": 33427926161n, + "from": "0x043022ef9fca1066024d19d681e2ccf44ff90de3", + "gasUsed": 21000n, + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "status": "success", + "to": "0x318a5fb4f1604fc46375a1db9a9018b6e423b345", + "transactionHash": "0xbf7d27700d053765c9638d3b9d39eb3c56bfc48377583e8be483d61f9f18a871", + "transactionIndex": 0, + "type": "legacy", + }, + "dataUpdatedAt": 1675209600000, + "error": null, + "errorUpdateCount": 0, + "errorUpdatedAt": 0, + "failureCount": 0, + "failureReason": null, + "fetchStatus": "idle", + "isError": false, + "isFetched": true, + "isFetchedAfterMount": true, + "isFetching": false, + "isInitialLoading": false, + "isLoading": false, + "isLoadingError": false, + "isPaused": false, + "isPending": false, + "isPlaceholderData": false, + "isRefetchError": false, + "isRefetching": false, + "isStale": true, + "isSuccess": true, + "queryKey": [ + "getTransactionReceipt", + { + "chainId": 1, + "hash": undefined, + }, + ], + "refetch": [Function], + "status": "success", + "suspense": [Function], + } + `) +}) + +test('behavior: disabled when properties missing', async () => { + const [result] = renderComposable(() => useTransactionReceipt()) + + await wait(100) + expect(result.fetchStatus.value).toBe('idle') +}) diff --git a/wagmi-project/packages/vue/src/composables/useTransactionReceipt.ts b/wagmi-project/packages/vue/src/composables/useTransactionReceipt.ts new file mode 100644 index 0000000000..cba5c232ae --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useTransactionReceipt.ts @@ -0,0 +1,85 @@ +import type { + Config, + GetTransactionReceiptErrorType, + ResolvedRegister, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type GetTransactionReceiptData, + type GetTransactionReceiptOptions, + type GetTransactionReceiptQueryKey, + getTransactionReceiptQueryOptions, +} from '@wagmi/core/query' +import type { GetTransactionReceiptQueryFnData } from '@wagmi/core/query' + +import { computed } from 'vue' +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import type { DeepMaybeRef } from '../types/ref.js' +import { deepUnref } from '../utils/cloneDeep.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseTransactionReceiptParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetTransactionReceiptData, +> = Compute< + DeepMaybeRef< + GetTransactionReceiptOptions & + ConfigParameter & + QueryParameter< + GetTransactionReceiptQueryFnData, + GetTransactionReceiptErrorType, + selectData, + GetTransactionReceiptQueryKey + > + > +> + +export type UseTransactionReceiptReturnType< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetTransactionReceiptData, +> = UseQueryReturnType + +/** https://wagmi.sh/vue/api/composables/useTransactionReceipt */ +export function useTransactionReceipt< + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = GetTransactionReceiptData, +>( + parameters_: UseTransactionReceiptParameters< + config, + chainId, + selectData + > = {}, +): UseTransactionReceiptReturnType { + const parameters = computed(() => deepUnref(parameters_)) + + const config = useConfig(parameters) + const configChainId = useChainId({ config }) + + const queryOptions = computed(() => { + const { chainId = configChainId.value, hash, query = {} } = parameters.value + const options = getTransactionReceiptQueryOptions(config, { + ...parameters.value, + chainId, + }) + const enabled = Boolean(hash && (query.enabled ?? true)) + return { + ...(query as any), + ...options, + enabled, + } + }) + + return useQuery(queryOptions) as UseTransactionReceiptReturnType< + config, + chainId, + selectData + > +} diff --git a/wagmi-project/packages/vue/src/composables/useWaitForTransactionReceipt.test-d.ts b/wagmi-project/packages/vue/src/composables/useWaitForTransactionReceipt.test-d.ts new file mode 100644 index 0000000000..aa5dcad64f --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useWaitForTransactionReceipt.test-d.ts @@ -0,0 +1,14 @@ +import { expectTypeOf, test } from 'vitest' + +import { useWaitForTransactionReceipt } from './useWaitForTransactionReceipt.js' + +test('select data', () => { + const result = useWaitForTransactionReceipt({ + query: { + select(data) { + return data?.blockNumber + }, + }, + }) + expectTypeOf(result.data.value).toEqualTypeOf() +}) diff --git a/wagmi-project/packages/vue/src/composables/useWaitForTransactionReceipt.test.ts b/wagmi-project/packages/vue/src/composables/useWaitForTransactionReceipt.test.ts new file mode 100644 index 0000000000..3cfcbe0feb --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useWaitForTransactionReceipt.test.ts @@ -0,0 +1,46 @@ +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { expect, test } from 'vitest' +import { wait } from '../../../test/src/utils.js' +import { useWaitForTransactionReceipt } from './useWaitForTransactionReceipt.js' + +test('default', async () => { + const [result] = renderComposable(() => + useWaitForTransactionReceipt({ + hash: '0x60668ed8c2dc110d61d945a936fcd45b8f13654e5c78481c8c825d1148c7ef30', + }), + ) + + await waitFor(result.isSuccess) + + expect(result.data.value).toMatchInlineSnapshot(` + { + "blockHash": "0xd725a38b51e5ceec8c5f6c9ccfdb2cc423af993bb650af5eedca5e4be7156ba7", + "blockNumber": 15189204n, + "chainId": 1, + "contractAddress": null, + "cumulativeGasUsed": 12949744n, + "effectiveGasPrice": 9371645552n, + "from": "0xa0cf798816d4b9b9866b5330eea46a18382f251e", + "gasUsed": 21000n, + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "status": "success", + "to": "0xd2135cfb216b74109775236e36d4b433f1df507b", + "transactionHash": "0x60668ed8c2dc110d61d945a936fcd45b8f13654e5c78481c8c825d1148c7ef30", + "transactionIndex": 144, + "type": "eip1559", + } + `) +}) + +test('disabled when hash is undefined', async () => { + const [result] = renderComposable(() => + useWaitForTransactionReceipt({ + hash: undefined, + }), + ) + + await wait(100) + + expect(result.isPending.value).toBe(true) +}) diff --git a/wagmi-project/packages/vue/src/composables/useWaitForTransactionReceipt.ts b/wagmi-project/packages/vue/src/composables/useWaitForTransactionReceipt.ts new file mode 100644 index 0000000000..6aea7d8e06 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useWaitForTransactionReceipt.ts @@ -0,0 +1,84 @@ +import type { + Config, + ResolvedRegister, + WaitForTransactionReceiptErrorType, +} from '@wagmi/core' +import type { Compute } from '@wagmi/core/internal' +import { + type WaitForTransactionReceiptData, + type WaitForTransactionReceiptOptions, + type WaitForTransactionReceiptQueryFnData, + type WaitForTransactionReceiptQueryKey, + waitForTransactionReceiptQueryOptions, +} from '@wagmi/core/query' +import { computed } from 'vue' + +import type { ConfigParameter, QueryParameter } from '../types/properties.js' +import type { DeepMaybeRef } from '../types/ref.js' +import { deepUnref } from '../utils/cloneDeep.js' +import { type UseQueryReturnType, useQuery } from '../utils/query.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseWaitForTransactionReceiptParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = WaitForTransactionReceiptData, +> = Compute< + DeepMaybeRef< + WaitForTransactionReceiptOptions & + ConfigParameter & + QueryParameter< + WaitForTransactionReceiptQueryFnData, + WaitForTransactionReceiptErrorType, + selectData, + WaitForTransactionReceiptQueryKey + > + > +> + +export type UseWaitForTransactionReceiptReturnType< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = WaitForTransactionReceiptData, +> = UseQueryReturnType + +/** https://wagmi.sh/vue/api/composables/useWaitForTransactionReceipt */ +export function useWaitForTransactionReceipt< + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], + selectData = WaitForTransactionReceiptData, +>( + parameters_: UseWaitForTransactionReceiptParameters< + config, + chainId, + selectData + > = {}, +): UseWaitForTransactionReceiptReturnType { + const parameters = computed(() => deepUnref(parameters_)) + const config = useConfig(parameters_) + const configChainId = useChainId() + + const queryOptions = computed(() => { + const { chainId = configChainId.value, hash, query = {} } = parameters.value + + const options = waitForTransactionReceiptQueryOptions(config, { + ...parameters.value, + chainId, + }) + const enabled = Boolean(hash && (query.enabled ?? true)) + + return { + ...query, + ...options, + enabled, + } + }) + + return useQuery( + queryOptions as any, + ) as UseWaitForTransactionReceiptReturnType +} diff --git a/wagmi-project/packages/vue/src/composables/useWatchBlockNumber.test-d.ts b/wagmi-project/packages/vue/src/composables/useWatchBlockNumber.test-d.ts new file mode 100644 index 0000000000..6ab0347168 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useWatchBlockNumber.test-d.ts @@ -0,0 +1,75 @@ +import { createConfig } from '@wagmi/core' +import { http, webSocket } from 'viem' +import { mainnet, optimism } from 'viem/chains' +import { expectTypeOf, test } from 'vitest' + +import type { DeepUnwrapRef } from '../types/ref.js' +import { + type UseWatchBlockNumberParameters, + useWatchBlockNumber, +} from './useWatchBlockNumber.js' + +test('default', () => { + useWatchBlockNumber({ + poll: false, + onBlockNumber() {}, + }) +}) + +test('differing transports', () => { + const config = createConfig({ + chains: [mainnet, optimism], + transports: { + [mainnet.id]: http(), + [optimism.id]: webSocket(), + }, + }) + + type Result = DeepUnwrapRef< + UseWatchBlockNumberParameters< + typeof config, + typeof mainnet.id | typeof optimism.id + > + > + expectTypeOf().toEqualTypeOf() + useWatchBlockNumber({ + config, + poll: false, + onBlockNumber() {}, + }) + + type Result2 = DeepUnwrapRef< + UseWatchBlockNumberParameters + > + expectTypeOf().toEqualTypeOf() + useWatchBlockNumber({ + config, + chainId: mainnet.id, + poll: true, + onBlockNumber() {}, + }) + useWatchBlockNumber({ + config, + chainId: mainnet.id, + // @ts-expect-error + poll: false, + onBlockNumber() {}, + }) + + type Result3 = DeepUnwrapRef< + UseWatchBlockNumberParameters + > + expectTypeOf().toEqualTypeOf() + useWatchBlockNumber({ + config, + chainId: optimism.id, + poll: true, + onBlockNumber() {}, + }) + useWatchBlockNumber({ + config, + chainId: optimism.id, + poll: false, + onBlockNumber() {}, + }) +}) diff --git a/wagmi-project/packages/vue/src/composables/useWatchBlockNumber.test.ts b/wagmi-project/packages/vue/src/composables/useWatchBlockNumber.test.ts new file mode 100644 index 0000000000..1b074d766c --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useWatchBlockNumber.test.ts @@ -0,0 +1,67 @@ +import { testClient, wait } from '@wagmi/test' +import { renderComposable } from '@wagmi/test/vue' +import { expect, test } from 'vitest' +import { ref } from 'vue' +import { useWatchBlockNumber } from './useWatchBlockNumber.js' + +test('default', async () => { + const blockNumbers: bigint[] = [] + renderComposable(() => + useWatchBlockNumber({ + onBlockNumber(blockNumber) { + blockNumbers.push(blockNumber) + }, + }), + ) + + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + + expect(blockNumbers.length).toBe(3) + expect( + blockNumbers.map((blockNumber) => blockNumber - blockNumbers[0]!), + ).toEqual([0n, 1n, 2n]) +}) + +test('parameters: enabled', async () => { + const enabled = ref(true) + + const blockNumbers: bigint[] = [] + renderComposable(() => + useWatchBlockNumber({ + enabled, + onBlockNumber(blockNumber) { + blockNumbers.push(blockNumber) + }, + }), + ) + + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + + expect(blockNumbers.length).toBe(3) + expect( + blockNumbers.map((blockNumber) => blockNumber - blockNumbers[0]!), + ).toEqual([0n, 1n, 2n]) + + enabled.value = false + + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + + expect( + blockNumbers.map((blockNumber) => blockNumber - blockNumbers[0]!), + ).toEqual([0n, 1n, 2n]) +}) diff --git a/wagmi-project/packages/vue/src/composables/useWatchBlockNumber.ts b/wagmi-project/packages/vue/src/composables/useWatchBlockNumber.ts new file mode 100644 index 0000000000..96dd437ec1 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useWatchBlockNumber.ts @@ -0,0 +1,63 @@ +import { + type Config, + type ResolvedRegister, + type WatchBlockNumberParameters, + watchBlockNumber, +} from '@wagmi/core' +import type { UnionCompute, UnionExactPartial } from '@wagmi/core/internal' +import { computed, watchEffect } from 'vue' + +import type { ConfigParameter, EnabledParameter } from '../types/properties.js' +import type { DeepMaybeRef } from '../types/ref.js' +import { deepUnref } from '../utils/cloneDeep.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseWatchBlockNumberParameters< + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = DeepMaybeRef< + UnionCompute< + UnionExactPartial> & + ConfigParameter & + EnabledParameter + > +> + +export type UseWatchBlockNumberReturnType = void + +/** https://wagmi.sh/vue/api/composables/useWatchBlockNumber */ +export function useWatchBlockNumber< + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +>( + parameters_: UseWatchBlockNumberParameters = {} as any, +): UseWatchBlockNumberReturnType { + const parameters = computed(() => deepUnref(parameters_)) + + const config = useConfig(parameters) + const configChainId = useChainId({ config }) + + watchEffect((onCleanup) => { + const { + chainId = configChainId.value, + enabled = true, + onBlockNumber, + config: _, + ...rest + } = parameters.value + + if (!enabled) return + if (!onBlockNumber) return + + const unwatch = watchBlockNumber(config, { + ...(rest as any), + chainId, + onBlockNumber, + emitOnBegin: true, + }) + onCleanup(unwatch) + }) +} diff --git a/wagmi-project/packages/vue/src/composables/useWatchContractEvent.test-d.ts b/wagmi-project/packages/vue/src/composables/useWatchContractEvent.test-d.ts new file mode 100644 index 0000000000..17568222dd --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useWatchContractEvent.test-d.ts @@ -0,0 +1,126 @@ +import { http, createConfig, webSocket } from '@wagmi/core' +import { mainnet, optimism } from '@wagmi/core/chains' +import { abi } from '@wagmi/test' +import { expectTypeOf, test } from 'vitest' + +import { useWatchContractEvent } from './useWatchContractEvent.js' + +test('default', () => { + useWatchContractEvent({ + address: '0x', + abi: abi.erc20, + eventName: 'Transfer', + poll: false, + args: { + from: '0x', + to: '0x', + }, + onLogs(logs) { + expectTypeOf(logs[0]!.eventName).toEqualTypeOf<'Transfer'>() + expectTypeOf(logs[0]!.args).toEqualTypeOf<{ + from?: `0x${string}` | undefined + to?: `0x${string}` | undefined + value?: bigint | undefined + }>() + }, + }) +}) + +test('behavior: no eventName', () => { + useWatchContractEvent({ + address: '0x', + abi: abi.erc20, + args: { + // TODO: Figure out why this is not working + // @ts-ignore + from: '0x', + to: '0x', + }, + onLogs(logs) { + expectTypeOf(logs[0]!.eventName).toEqualTypeOf<'Transfer' | 'Approval'>() + expectTypeOf(logs[0]!.args).toEqualTypeOf< + | Record + | readonly unknown[] + | { + from?: `0x${string}` | undefined + to?: `0x${string}` | undefined + value?: bigint | undefined + } + | { + owner?: `0x${string}` | undefined + spender?: `0x${string}` | undefined + value?: bigint | undefined + } + >() + }, + }) +}) + +test('differing transports', () => { + const config = createConfig({ + chains: [mainnet, optimism], + transports: { + [mainnet.id]: http(), + [optimism.id]: webSocket(), + }, + }) + + // TODO: Fix inference for `poll` (`DeepMaybeRef` wrapping `UseWatchContractEventParameters` not working as expected) + // type Result = UseWatchContractEventParameters< + // typeof abi.erc20, + // 'Transfer' | 'Approval', + // true, + // typeof config, + // typeof mainnet.id | typeof optimism.id + // > + // expectTypeOf().toEqualTypeOf() + useWatchContractEvent({ + config, + poll: false, + address: '0x', + abi: abi.erc20, + onLogs() {}, + }) + + // type Result2 = UseWatchContractEventParameters< + // typeof abi.erc20, + // 'Transfer' | 'Approval', + // true, + // typeof config, + // typeof mainnet.id + // > + // expectTypeOf().toEqualTypeOf() + useWatchContractEvent({ + config, + chainId: mainnet.id, + poll: true, + address: '0x', + abi: abi.erc20, + onLogs() {}, + }) + + // type Result3 = UseWatchContractEventParameters< + // typeof abi.erc20, + // 'Transfer' | 'Approval', + // true, + // typeof config, + // typeof optimism.id + // > + // expectTypeOf().toEqualTypeOf() + useWatchContractEvent({ + config, + chainId: optimism.id, + poll: true, + address: '0x', + abi: abi.erc20, + onLogs() {}, + }) + useWatchContractEvent({ + config, + chainId: optimism.id, + poll: false, + address: '0x', + abi: abi.erc20, + onLogs() {}, + }) +}) diff --git a/wagmi-project/packages/vue/src/composables/useWatchContractEvent.test.ts b/wagmi-project/packages/vue/src/composables/useWatchContractEvent.test.ts new file mode 100644 index 0000000000..968c46d0cd --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useWatchContractEvent.test.ts @@ -0,0 +1,106 @@ +import { connect, disconnect, getBalance, writeContract } from '@wagmi/core' +import { + abi, + accounts, + address, + config, + testClient, + transactionHashRegex, + wait, +} from '@wagmi/test' +import { renderComposable } from '@wagmi/test/vue' +import { http, createWalletClient, parseEther } from 'viem' +import type { WatchEventOnLogsParameter } from 'viem/actions' +import { expect, test } from 'vitest' + +import { ref } from 'vue' +import { useWatchContractEvent } from './useWatchContractEvent.js' + +const connector = config.connectors[0]! + +test('default', async () => { + const data = await connect(config, { connector }) + const connectedAddress = data.accounts[0] + + // impersonate usdc holder account and transfer usdc to connected account + await testClient.mainnet.impersonateAccount({ address: address.usdcHolder }) + await testClient.mainnet.setBalance({ + address: address.usdcHolder, + value: 10000000000000000000000n, + }) + await createWalletClient({ + account: address.usdcHolder, + chain: testClient.mainnet.chain, + transport: http(), + }).writeContract({ + address: address.usdc, + abi: abi.erc20, + functionName: 'transfer', + args: [connectedAddress, parseEther('10', 'gwei')], + }) + await testClient.mainnet.mine({ blocks: 1 }) + await testClient.mainnet.stopImpersonatingAccount({ + address: address.usdcHolder, + }) + + const balance = await getBalance(config, { + address: connectedAddress, + token: address.usdc, + }) + expect(balance.value).toBeGreaterThan(0n) + + // start watching transfer events + let logs: WatchEventOnLogsParameter = [] + renderComposable(() => + useWatchContractEvent({ + address: address.usdc, + abi: abi.erc20, + eventName: 'Transfer', + onLogs(next) { + logs = logs.concat(next) + }, + }), + ) + + await writeContract(config, { + address: address.usdc, + abi: abi.erc20, + functionName: 'transfer', + args: [accounts[1], parseEther('1', 'gwei')], + }) + + await writeContract(config, { + address: address.usdc, + abi: abi.erc20, + functionName: 'transfer', + args: [accounts[3], parseEther('1', 'gwei')], + }) + + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + await testClient.mainnet.mine({ blocks: 1 }) + await wait(100) + + expect(logs.length).toBe(2) + expect(logs[0]?.transactionHash).toMatch(transactionHashRegex) + + await disconnect(config, { connector }) +}) + +test('parameters: enabled', async () => { + const enabled = ref(true) + + renderComposable(() => + useWatchContractEvent({ + address: address.usdc, + abi: abi.erc20, + eventName: 'Transfer', + }), + ) + + renderComposable(() => + useWatchContractEvent({ + enabled, + }), + ) +}) diff --git a/wagmi-project/packages/vue/src/composables/useWatchContractEvent.ts b/wagmi-project/packages/vue/src/composables/useWatchContractEvent.ts new file mode 100644 index 0000000000..ffd988b40b --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useWatchContractEvent.ts @@ -0,0 +1,77 @@ +import { + type Config, + type ResolvedRegister, + type WatchContractEventParameters, + watchContractEvent, +} from '@wagmi/core' +import type { UnionCompute, UnionExactPartial } from '@wagmi/core/internal' +import type { Abi, ContractEventName } from 'viem' +import { computed, watchEffect } from 'vue' + +import type { ConfigParameter, EnabledParameter } from '../types/properties.js' +import type { DeepMaybeRef } from '../types/ref.js' +import { deepUnref } from '../utils/cloneDeep.js' +import { useChainId } from './useChainId.js' +import { useConfig } from './useConfig.js' + +export type UseWatchContractEventParameters< + abi extends Abi | readonly unknown[] = Abi, + eventName extends ContractEventName = ContractEventName, + strict extends boolean | undefined = undefined, + config extends Config = Config, + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +> = DeepMaybeRef< + UnionCompute< + UnionExactPartial< + WatchContractEventParameters + > & + ConfigParameter & + EnabledParameter + > +> + +export type UseWatchContractEventReturnType = void + +/** https://wagmi.sh/vue/api/composables/useWatchContractEvent */ +export function useWatchContractEvent< + const abi extends Abi | readonly unknown[], + eventName extends ContractEventName, + strict extends boolean | undefined = undefined, + config extends Config = ResolvedRegister['config'], + chainId extends + config['chains'][number]['id'] = config['chains'][number]['id'], +>( + parameters: UseWatchContractEventParameters< + abi, + eventName, + strict, + config, + chainId + > = {} as any, +): UseWatchContractEventReturnType { + const parameters_ = computed(() => deepUnref(parameters)) + + const config = useConfig(parameters_) + const configChainId = useChainId({ config }) + + watchEffect((onCleanup) => { + const { + chainId = configChainId.value, + enabled = true, + onLogs, + config: _, + ...rest + } = parameters_.value + + if (!enabled) return + if (!onLogs) return + + const unwatch = watchContractEvent(config, { + ...(rest as any), + chainId, + onLogs, + }) + onCleanup(unwatch) + }) +} diff --git a/wagmi-project/packages/vue/src/composables/useWriteContract.test-d.ts b/wagmi-project/packages/vue/src/composables/useWriteContract.test-d.ts new file mode 100644 index 0000000000..33a9b14342 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useWriteContract.test-d.ts @@ -0,0 +1,136 @@ +import type { WriteContractErrorType } from '@wagmi/core' +import { abi } from '@wagmi/test' +import type { Abi, Address, Hash } from 'viem' +import { expectTypeOf, test } from 'vitest' + +import { useSimulateContract } from './useSimulateContract.js' +import { useWriteContract } from './useWriteContract.js' + +const contextValue = { foo: 'bar' } as const + +test('context', () => { + const { + context, + data, + error, + writeContract: write, + variables, + } = useWriteContract({ + mutation: { + onMutate(variables) { + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: Abi + functionName: string + args?: readonly unknown[] | undefined + }>() + return contextValue + }, + onError(error, variables, context) { + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: Abi + functionName: string + args?: readonly unknown[] | undefined + }>() + }, + onSuccess(data, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: Abi + functionName: string + args?: readonly unknown[] | undefined + }>() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: Abi + functionName: string + args?: readonly unknown[] | undefined + }>() + }, + }, + }) + + expectTypeOf(data.value).toEqualTypeOf() + expectTypeOf(error.value).toEqualTypeOf() + expectTypeOf(variables.value).toMatchTypeOf< + { chainId?: number | undefined } | undefined + >() + expectTypeOf(context.value).toEqualTypeOf() + + write( + { + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + chainId: 1, + }, + { + onError(error, variables, context) { + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: typeof abi.erc20 + functionName: 'transferFrom' + args: readonly [Address, Address, bigint] + }>() + }, + onSuccess(data, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + expectTypeOf(variables.functionName).toEqualTypeOf<'transferFrom'>() + expectTypeOf(variables.args).toEqualTypeOf< + readonly [Address, Address, bigint] + >() + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: typeof abi.erc20 + functionName: 'transferFrom' + args: readonly [Address, Address, bigint] + }>() + }, + onSettled(data, error, variables, context) { + expectTypeOf(data).toEqualTypeOf() + expectTypeOf(error).toEqualTypeOf() + expectTypeOf(context).toEqualTypeOf() + + expectTypeOf(variables).toMatchTypeOf<{ + chainId?: number | undefined + abi: typeof abi.erc20 + functionName: 'transferFrom' + args: readonly [Address, Address, bigint] + }>() + }, + }, + ) +}) + +test('useSimulateContract', () => { + const { data } = useSimulateContract({ + address: '0x', + abi: abi.erc20, + functionName: 'transferFrom', + args: ['0x', '0x', 123n], + chainId: 1, + }) + const { writeContract } = useWriteContract() + + const request = data?.value?.request + if (request) writeContract(request) +}) diff --git a/wagmi-project/packages/vue/src/composables/useWriteContract.test.ts b/wagmi-project/packages/vue/src/composables/useWriteContract.test.ts new file mode 100644 index 0000000000..ba7c8cb4cb --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useWriteContract.test.ts @@ -0,0 +1,25 @@ +import { connect, disconnect } from '@wagmi/core' +import { abi, address, config } from '@wagmi/test' +import { renderComposable, waitFor } from '@wagmi/test/vue' +import { expect, test } from 'vitest' + +import { useWriteContract } from './useWriteContract.js' + +const connector = config.connectors[0]! + +test('default', async () => { + await connect(config, { connector }) + + const [result] = renderComposable(() => useWriteContract()) + + result.writeContract({ + abi: abi.wagmiMintExample, + address: address.wagmiMintExample, + functionName: 'mint', + }) + await waitFor(result.isSuccess) + + expect(result.data.value).toBeDefined() + + await disconnect(config, { connector }) +}) diff --git a/wagmi-project/packages/vue/src/composables/useWriteContract.ts b/wagmi-project/packages/vue/src/composables/useWriteContract.ts new file mode 100644 index 0000000000..21ac3a82d4 --- /dev/null +++ b/wagmi-project/packages/vue/src/composables/useWriteContract.ts @@ -0,0 +1,85 @@ +import { useMutation } from '@tanstack/vue-query' +import type { + Config, + ResolvedRegister, + WriteContractErrorType, +} from '@wagmi/core' +import { + type WriteContractData, + type WriteContractMutate, + type WriteContractMutateAsync, + type WriteContractVariables, + writeContractMutationOptions, +} from '@wagmi/core/query' +import type { Abi } from 'viem' + +import type { ConfigParameter } from '../types/properties.js' +import type { + UseMutationParameters, + UseMutationReturnType, +} from '../utils/query.js' +import { useConfig } from './useConfig.js' + +export type UseWriteContractParameters< + config extends Config = Config, + context = unknown, +> = ConfigParameter & { + mutation?: + | UseMutationParameters< + WriteContractData, + WriteContractErrorType, + WriteContractVariables< + Abi, + string, + readonly unknown[], + config, + config['chains'][number]['id'] + >, + context + > + | undefined +} + +export type UseWriteContractReturnType< + config extends Config = Config, + context = unknown, +> = UseMutationReturnType< + WriteContractData, + WriteContractErrorType, + WriteContractVariables< + Abi, + string, + readonly unknown[], + config, + config['chains'][number]['id'] + >, + context +> & { + writeContract: WriteContractMutate + writeContractAsync: WriteContractMutateAsync +} + +/** https://wagmi.sh/vue/api/composables/useWriteContract */ +export function useWriteContract< + config extends Config = ResolvedRegister['config'], + context = unknown, +>( + parameters: UseWriteContractParameters = {}, +): UseWriteContractReturnType { + const { mutation } = parameters + + const config = useConfig(parameters) + + const mutationOptions = writeContractMutationOptions(config) + const { mutate, mutateAsync, ...result } = useMutation({ + ...mutation, + ...mutationOptions, + }) + + type Return = UseWriteContractReturnType + return { + ...result, + writeContract: mutate as Return['writeContract'], + writeContractAsync: mutateAsync as Return['writeContractAsync'], + } +} diff --git a/wagmi-project/packages/vue/src/errors/base.test.ts b/wagmi-project/packages/vue/src/errors/base.test.ts new file mode 100644 index 0000000000..3457d4be1a --- /dev/null +++ b/wagmi-project/packages/vue/src/errors/base.test.ts @@ -0,0 +1,155 @@ +import { expect, test } from 'vitest' + +import { BaseError } from './base.js' + +test('BaseError', () => { + expect(new BaseError('An error occurred.')).toMatchInlineSnapshot(` + [WagmiError: An error occurred. + + Version: @wagmi/vue@x.y.z] + `) + + expect( + new BaseError('An error occurred.', { details: 'details' }), + ).toMatchInlineSnapshot(` + [WagmiError: An error occurred. + + Details: details + Version: @wagmi/vue@x.y.z] + `) + + expect(new BaseError('', { details: 'details' })).toMatchInlineSnapshot(` + [WagmiError: An error occurred. + + Details: details + Version: @wagmi/vue@x.y.z] + `) +}) + +test('BaseError (w/ docsPath)', () => { + expect( + new BaseError('An error occurred.', { + details: 'details', + docsPath: '/lol', + }), + ).toMatchInlineSnapshot(` + [WagmiError: An error occurred. + + Docs: https://wagmi.sh/vue/lol.html + Details: details + Version: @wagmi/vue@x.y.z] + `) + expect( + new BaseError('An error occurred.', { + cause: new BaseError('error', { docsPath: '/docs' }), + }), + ).toMatchInlineSnapshot(` + [WagmiError: An error occurred. + + Docs: https://wagmi.sh/vue/docs.html + Version: @wagmi/vue@x.y.z] + `) + expect( + new BaseError('An error occurred.', { + cause: new BaseError('error'), + docsPath: '/lol', + }), + ).toMatchInlineSnapshot(` + [WagmiError: An error occurred. + + Docs: https://wagmi.sh/vue/lol.html + Version: @wagmi/vue@x.y.z] + `) + expect( + new BaseError('An error occurred.', { + details: 'details', + docsPath: '/lol', + docsSlug: 'test', + }), + ).toMatchInlineSnapshot(` + [WagmiError: An error occurred. + + Docs: https://wagmi.sh/vue/lol.html#test + Details: details + Version: @wagmi/vue@x.y.z] + `) +}) + +test('BaseError (w/ metaMessages)', () => { + expect( + new BaseError('An error occurred.', { + details: 'details', + metaMessages: ['Reason: idk', 'Cause: lol'], + }), + ).toMatchInlineSnapshot(` + [WagmiError: An error occurred. + + Reason: idk + Cause: lol + + Details: details + Version: @wagmi/vue@x.y.z] + `) +}) + +test('inherited BaseError', () => { + const err = new BaseError('An error occurred.', { + details: 'details', + docsPath: '/lol', + }) + expect( + new BaseError('An internal error occurred.', { + cause: err, + }), + ).toMatchInlineSnapshot(` + [WagmiError: An internal error occurred. + + Docs: https://wagmi.sh/vue/lol.html + Details: details + Version: @wagmi/vue@x.y.z] + `) +}) + +test('inherited Error', () => { + const err = new Error('details') + expect( + new BaseError('An internal error occurred.', { + cause: err, + docsPath: '/lol', + }), + ).toMatchInlineSnapshot(` + [WagmiError: An internal error occurred. + + Docs: https://wagmi.sh/vue/lol.html + Details: details + Version: @wagmi/vue@x.y.z] + `) +}) + +test('walk: no predicate fn (walks to leaf)', () => { + class FooError extends BaseError {} + class BarError extends BaseError {} + + const err = new BaseError('test1', { + cause: new FooError('test2', { cause: new BarError('test3') }), + }) + expect(err.walk()).toMatchInlineSnapshot(` + [WagmiError: test3 + + Version: @wagmi/vue@x.y.z] + `) +}) + +test('walk: predicate fn', () => { + class FooError extends BaseError {} + class BarError extends BaseError {} + + const err = new BaseError('test1', { + cause: new FooError('test2', { cause: new BarError('test3') }), + }) + expect(err.walk((err) => err instanceof FooError)).toMatchInlineSnapshot(` + [WagmiError: test2 + + Version: @wagmi/vue@x.y.z] + `) +}) diff --git a/wagmi-project/packages/vue/src/errors/base.ts b/wagmi-project/packages/vue/src/errors/base.ts new file mode 100644 index 0000000000..bb65ac5fef --- /dev/null +++ b/wagmi-project/packages/vue/src/errors/base.ts @@ -0,0 +1,14 @@ +import { BaseError as CoreError } from '@wagmi/core' + +import { getVersion } from '../utils/getVersion.js' + +export type BaseErrorType = BaseError & { name: 'WagmiError' } +export class BaseError extends CoreError { + override name = 'WagmiError' + override get docsBaseUrl() { + return 'https://wagmi.sh/vue' + } + override get version() { + return getVersion() + } +} diff --git a/wagmi-project/packages/vue/src/errors/plugin.test.ts b/wagmi-project/packages/vue/src/errors/plugin.test.ts new file mode 100644 index 0000000000..64ff3acda8 --- /dev/null +++ b/wagmi-project/packages/vue/src/errors/plugin.test.ts @@ -0,0 +1,24 @@ +import { expect, test } from 'vitest' + +import { + WagmiInjectionContextError, + WagmiPluginNotFoundError, +} from './plugin.js' + +test('WagmiPluginNotFoundError', () => { + expect(new WagmiPluginNotFoundError()).toMatchInlineSnapshot(` + [WagmiPluginNotFoundError: No \`config\` found in Vue context, use \`WagmiPlugin\` to properly initialize the library. + + Docs: https://wagmi.sh/vue/api/TODO.html + Version: @wagmi/vue@x.y.z] + `) +}) + +test('WagmiInjectionContextError', () => { + expect(new WagmiInjectionContextError()).toMatchInlineSnapshot(` + [WagmiInjectionContextError: Wagmi composables can only be used inside \`setup()\` function or functions that support injection context. + + Docs: https://wagmi.sh/vue/api/TODO.html + Version: @wagmi/vue@x.y.z] + `) +}) diff --git a/wagmi-project/packages/vue/src/errors/plugin.ts b/wagmi-project/packages/vue/src/errors/plugin.ts new file mode 100644 index 0000000000..bed7cda47e --- /dev/null +++ b/wagmi-project/packages/vue/src/errors/plugin.ts @@ -0,0 +1,31 @@ +import { BaseError } from './base.js' + +export type WagmiPluginNotFoundErrorType = WagmiPluginNotFoundError & { + name: 'WagmiPluginNotFoundError' +} +export class WagmiPluginNotFoundError extends BaseError { + override name = 'WagmiPluginNotFoundError' + constructor() { + super( + 'No `config` found in Vue context, use `WagmiPlugin` to properly initialize the library.', + { + docsPath: '/api/TODO', + }, + ) + } +} + +export type WagmiInjectionContextErrorType = WagmiInjectionContextError & { + name: 'WagmiInjectionContextError' +} +export class WagmiInjectionContextError extends BaseError { + override name = 'WagmiInjectionContextError' + constructor() { + super( + 'Wagmi composables can only be used inside `setup()` function or functions that support injection context.', + { + docsPath: '/api/TODO', + }, + ) + } +} diff --git a/wagmi-project/packages/vue/src/exports/actions.test.ts b/wagmi-project/packages/vue/src/exports/actions.test.ts new file mode 100644 index 0000000000..eaaedba14f --- /dev/null +++ b/wagmi-project/packages/vue/src/exports/actions.test.ts @@ -0,0 +1,86 @@ +import { expect, test } from 'vitest' + +import * as actions from './actions.js' + +test('exports', () => { + expect(Object.keys(actions)).toMatchInlineSnapshot(` + [ + "call", + "connect", + "deployContract", + "disconnect", + "estimateGas", + "estimateFeesPerGas", + "estimateMaxPriorityFeePerGas", + "getAccount", + "getBalance", + "fetchBalance", + "getBlock", + "getBlockNumber", + "fetchBlockNumber", + "getBlockTransactionCount", + "getBytecode", + "getCallsStatus", + "getCapabilities", + "getChainId", + "getChains", + "getClient", + "getConnections", + "getConnectors", + "getConnectorClient", + "getEnsAddress", + "fetchEnsAddress", + "getEnsAvatar", + "fetchEnsAvatar", + "getEnsName", + "fetchEnsName", + "getEnsResolver", + "fetchEnsResolver", + "getEnsText", + "getFeeHistory", + "getGasPrice", + "getProof", + "getPublicClient", + "getStorageAt", + "getToken", + "fetchToken", + "getTransaction", + "fetchTransaction", + "getTransactionConfirmations", + "getTransactionCount", + "getTransactionReceipt", + "getWalletClient", + "multicall", + "prepareTransactionRequest", + "readContract", + "readContracts", + "reconnect", + "sendCalls", + "sendTransaction", + "showCallsStatus", + "signMessage", + "signTypedData", + "simulateContract", + "switchAccount", + "switchChain", + "switchNetwork", + "verifyMessage", + "verifyTypedData", + "waitForCallsStatus", + "watchAccount", + "watchAsset", + "watchBlocks", + "watchBlockNumber", + "watchChainId", + "watchClient", + "watchConnections", + "watchConnectors", + "watchContractEvent", + "watchPendingTransactions", + "watchPublicClient", + "waitForTransactionReceipt", + "waitForTransaction", + "writeContract", + ] + `) +}) diff --git a/wagmi-project/packages/vue/src/exports/actions.ts b/wagmi-project/packages/vue/src/exports/actions.ts new file mode 100644 index 0000000000..3ff9c743c5 --- /dev/null +++ b/wagmi-project/packages/vue/src/exports/actions.ts @@ -0,0 +1,7 @@ +//////////////////////////////////////////////////////////////////////////////// +// @wagmi/core/actions +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +// biome-ignore lint/performance/noReExportAll: entrypoint module +export * from '@wagmi/core/actions' diff --git a/wagmi-project/packages/vue/src/exports/actions/experimental.test.ts b/wagmi-project/packages/vue/src/exports/actions/experimental.test.ts new file mode 100644 index 0000000000..7c4b92df8c --- /dev/null +++ b/wagmi-project/packages/vue/src/exports/actions/experimental.test.ts @@ -0,0 +1,25 @@ +import { expect, test } from 'vitest' + +import * as experimentalActions from './experimental.js' + +test('exports', () => { + expect(Object.keys(experimentalActions)).toMatchInlineSnapshot(` + [ + "getCallsStatus", + "getCapabilities", + "sendCalls", + "showCallsStatus", + "waitForCallsStatus", + "writeContracts", + "getCallsStatusQueryOptions", + "getCallsStatusQueryKey", + "getCapabilitiesQueryOptions", + "getCapabilitiesQueryKey", + "sendCallsMutationOptions", + "showCallsStatusMutationOptions", + "waitForCallsStatusQueryKey", + "waitForCallsStatusQueryOptions", + "writeContractsMutationOptions", + ] + `) +}) diff --git a/wagmi-project/packages/vue/src/exports/actions/experimental.ts b/wagmi-project/packages/vue/src/exports/actions/experimental.ts new file mode 100644 index 0000000000..6ee0334af5 --- /dev/null +++ b/wagmi-project/packages/vue/src/exports/actions/experimental.ts @@ -0,0 +1,7 @@ +//////////////////////////////////////////////////////////////////////////////// +// @wagmi/core/experimental +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +// biome-ignore lint/performance/noReExportAll: entrypoint module +export * from '@wagmi/core/experimental' diff --git a/wagmi-project/packages/vue/src/exports/chains.ts b/wagmi-project/packages/vue/src/exports/chains.ts new file mode 100644 index 0000000000..1fca7f537f --- /dev/null +++ b/wagmi-project/packages/vue/src/exports/chains.ts @@ -0,0 +1,7 @@ +//////////////////////////////////////////////////////////////////////////////// +// viem/chains +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +// biome-ignore lint/performance/noReExportAll: entrypoint module +export * from 'viem/chains' diff --git a/wagmi-project/packages/vue/src/exports/connectors.test.ts b/wagmi-project/packages/vue/src/exports/connectors.test.ts new file mode 100644 index 0000000000..068db8227c --- /dev/null +++ b/wagmi-project/packages/vue/src/exports/connectors.test.ts @@ -0,0 +1,17 @@ +import { expect, test } from 'vitest' + +import * as connectors from './connectors.js' + +test('exports', () => { + expect(Object.keys(connectors)).toMatchInlineSnapshot(` + [ + "injected", + "mock", + "coinbaseWallet", + "metaMask", + "safe", + "walletConnect", + "version", + ] + `) +}) diff --git a/wagmi-project/packages/vue/src/exports/connectors.ts b/wagmi-project/packages/vue/src/exports/connectors.ts new file mode 100644 index 0000000000..e10367e318 --- /dev/null +++ b/wagmi-project/packages/vue/src/exports/connectors.ts @@ -0,0 +1,7 @@ +//////////////////////////////////////////////////////////////////////////////// +// @wagmi/connectors +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +// biome-ignore lint/performance/noReExportAll: entrypoint module +export * from '@wagmi/connectors' diff --git a/wagmi-project/packages/vue/src/exports/index.test.ts b/wagmi-project/packages/vue/src/exports/index.test.ts new file mode 100644 index 0000000000..bb8fb0a1bd --- /dev/null +++ b/wagmi-project/packages/vue/src/exports/index.test.ts @@ -0,0 +1,74 @@ +import { expect, test } from 'vitest' + +import * as vue from './index.js' + +test('exports', () => { + expect(Object.keys(vue)).toMatchInlineSnapshot(` + [ + "configKey", + "WagmiPlugin", + "BaseError", + "WagmiPluginNotFoundError", + "WagmiInjectionContextError", + "useAccount", + "useAccountEffect", + "useBalance", + "useBlockNumber", + "useBytecode", + "useChainId", + "useClient", + "useConnectorClient", + "useChains", + "useConfig", + "useConnect", + "useConnections", + "useConnectors", + "useDisconnect", + "useEnsAddress", + "useEnsAvatar", + "useEnsName", + "useEstimateGas", + "useReadContract", + "useReconnect", + "useSendTransaction", + "useSignMessage", + "useSignTypedData", + "useSimulateContract", + "useSwitchAccount", + "useSwitchChain", + "useTransaction", + "useTransactionReceipt", + "useWatchBlockNumber", + "useWatchContractEvent", + "useWaitForTransactionReceipt", + "useWriteContract", + "createConfig", + "createConnector", + "injected", + "mock", + "ChainNotConfiguredError", + "ConnectorAlreadyConnectedError", + "ConnectorNotFoundError", + "ConnectorAccountNotFoundError", + "ConnectorChainMismatchError", + "ConnectorUnavailableReconnectingError", + "ProviderNotFoundError", + "SwitchChainNotSupportedError", + "createStorage", + "noopStorage", + "custom", + "fallback", + "http", + "webSocket", + "unstable_connector", + "cookieStorage", + "cookieToInitialState", + "deepEqual", + "deserialize", + "normalizeChainId", + "parseCookie", + "serialize", + "version", + ] + `) +}) diff --git a/wagmi-project/packages/vue/src/exports/index.ts b/wagmi-project/packages/vue/src/exports/index.ts new file mode 100644 index 0000000000..e7267878cf --- /dev/null +++ b/wagmi-project/packages/vue/src/exports/index.ts @@ -0,0 +1,280 @@ +//////////////////////////////////////////////////////////////////////////////// +// Plugin +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +export { configKey, type WagmiPluginOptions, WagmiPlugin } from '../plugin.js' + +//////////////////////////////////////////////////////////////////////////////// +// Errors +//////////////////////////////////////////////////////////////////////////////// + +export { type BaseErrorType, BaseError } from '../errors/base.js' + +export { + type WagmiPluginNotFoundErrorType, + WagmiPluginNotFoundError, + type WagmiInjectionContextErrorType, + WagmiInjectionContextError, +} from '../errors/plugin.js' + +//////////////////////////////////////////////////////////////////////////////// +// Composables +//////////////////////////////////////////////////////////////////////////////// + +export { + type UseAccountParameters, + type UseAccountReturnType, + useAccount, +} from '../composables/useAccount.js' + +export { + type UseAccountEffectParameters, + useAccountEffect, +} from '../composables/useAccountEffect.js' + +export { + type UseBalanceParameters, + type UseBalanceReturnType, + useBalance, +} from '../composables/useBalance.js' + +export { + type UseBlockNumberParameters, + type UseBlockNumberReturnType, + useBlockNumber, +} from '../composables/useBlockNumber.js' + +export { + type UseBytecodeParameters, + type UseBytecodeReturnType, + useBytecode, +} from '../composables/useBytecode.js' + +export { + type UseChainIdParameters, + type UseChainIdReturnType, + useChainId, +} from '../composables/useChainId.js' + +export { + type UseClientParameters, + type UseClientReturnType, + useClient, +} from '../composables/useClient.js' + +export { + type UseConnectorClientParameters, + type UseConnectorClientReturnType, + useConnectorClient, +} from '../composables/useConnectorClient.js' + +export { + type UseChainsParameters, + type UseChainsReturnType, + useChains, +} from '../composables/useChains.js' + +export { + type UseConfigParameters, + type UseConfigReturnType, + useConfig, +} from '../composables/useConfig.js' + +export { + type UseConnectParameters, + type UseConnectReturnType, + useConnect, +} from '../composables/useConnect.js' + +export { + type UseConnectionsParameters, + type UseConnectionsReturnType, + useConnections, +} from '../composables/useConnections.js' + +export { + type UseConnectorsParameters, + type UseConnectorsReturnType, + useConnectors, +} from '../composables/useConnectors.js' + +export { + type UseDisconnectParameters, + type UseDisconnectReturnType, + useDisconnect, +} from '../composables/useDisconnect.js' + +export { + type UseEnsAddressParameters, + type UseEnsAddressReturnType, + useEnsAddress, +} from '../composables/useEnsAddress.js' + +export { + type UseEnsAvatarParameters, + type UseEnsAvatarReturnType, + useEnsAvatar, +} from '../composables/useEnsAvatar.js' + +export { + type UseEnsNameParameters, + type UseEnsNameReturnType, + useEnsName, +} from '../composables/useEnsName.js' + +export { + type UseEstimateGasParameters, + type UseEstimateGasReturnType, + useEstimateGas, +} from '../composables/useEstimateGas.js' + +export { + type UseReadContractParameters, + type UseReadContractReturnType, + useReadContract, +} from '../composables/useReadContract.js' + +export { + type UseReconnectParameters, + type UseReconnectReturnType, + useReconnect, +} from '../composables/useReconnect.js' + +export { + type UseSendTransactionParameters, + type UseSendTransactionReturnType, + useSendTransaction, +} from '../composables/useSendTransaction.js' + +export { + type UseSignMessageParameters, + type UseSignMessageReturnType, + useSignMessage, +} from '../composables/useSignMessage.js' + +export { + type UseSignTypedDataParameters, + type UseSignTypedDataReturnType, + useSignTypedData, +} from '../composables/useSignTypedData.js' + +export { + type UseSimulateContractParameters, + type UseSimulateContractReturnType, + useSimulateContract, +} from '../composables/useSimulateContract.js' + +export { + type UseSwitchAccountParameters, + type UseSwitchAccountReturnType, + useSwitchAccount, +} from '../composables/useSwitchAccount.js' + +export { + type UseSwitchChainParameters, + type UseSwitchChainReturnType, + useSwitchChain, +} from '../composables/useSwitchChain.js' + +export { + type UseTransactionParameters, + type UseTransactionReturnType, + useTransaction, +} from '../composables/useTransaction.js' + +export { + type UseTransactionReceiptParameters, + type UseTransactionReceiptReturnType, + useTransactionReceipt, +} from '../composables/useTransactionReceipt.js' + +export { + type UseWatchBlockNumberParameters, + type UseWatchBlockNumberReturnType, + useWatchBlockNumber, +} from '../composables/useWatchBlockNumber.js' + +export { + type UseWatchContractEventParameters, + type UseWatchContractEventReturnType, + useWatchContractEvent, +} from '../composables/useWatchContractEvent.js' + +export { + type UseWaitForTransactionReceiptParameters, + type UseWaitForTransactionReceiptReturnType, + useWaitForTransactionReceipt, +} from '../composables/useWaitForTransactionReceipt.js' + +export { + type UseWriteContractParameters, + type UseWriteContractReturnType, + useWriteContract, +} from '../composables/useWriteContract.js' + +//////////////////////////////////////////////////////////////////////////////// +// @wagmi/core +//////////////////////////////////////////////////////////////////////////////// + +export { + // Config + type Connection, + type Connector, + type Config, + type CreateConfigParameters, + type PartializedState, + type State, + createConfig, + // Connector + type ConnectorEventMap, + type CreateConnectorFn, + createConnector, + injected, + mock, + // Errors + type ChainNotConfiguredErrorType, + ChainNotConfiguredError, + type ConnectorAlreadyConnectedErrorType, + ConnectorAlreadyConnectedError, + type ConnectorNotFoundErrorType, + ConnectorNotFoundError, + type ConnectorAccountNotFoundErrorType, + ConnectorAccountNotFoundError, + type ConnectorChainMismatchErrorType, + ConnectorChainMismatchError, + type ConnectorUnavailableReconnectingErrorType, + ConnectorUnavailableReconnectingError, + type ProviderNotFoundErrorType, + ProviderNotFoundError, + type SwitchChainNotSupportedErrorType, + SwitchChainNotSupportedError, + // Storage + type CreateStorageParameters, + type Storage, + createStorage, + noopStorage, + // Transports + custom, + fallback, + http, + webSocket, + unstable_connector, + // Types + type Register, + type ResolvedRegister, + // Utilities + cookieStorage, + cookieToInitialState, + deepEqual, + deserialize, + normalizeChainId, + parseCookie, + serialize, +} from '@wagmi/core' + +//////////////////////////////////////////////////////////////////////////////// +// Version +//////////////////////////////////////////////////////////////////////////////// + +export { version } from '../version.js' diff --git a/wagmi-project/packages/vue/src/exports/nuxt.test.ts b/wagmi-project/packages/vue/src/exports/nuxt.test.ts new file mode 100644 index 0000000000..7e5ecf9588 --- /dev/null +++ b/wagmi-project/packages/vue/src/exports/nuxt.test.ts @@ -0,0 +1,11 @@ +import { expect, test } from 'vitest' + +import * as nuxt from './nuxt.js' + +test('exports', () => { + expect(Object.keys(nuxt)).toMatchInlineSnapshot(` + [ + "default", + ] + `) +}) diff --git a/wagmi-project/packages/vue/src/exports/nuxt.ts b/wagmi-project/packages/vue/src/exports/nuxt.ts new file mode 100644 index 0000000000..e3e2e184a3 --- /dev/null +++ b/wagmi-project/packages/vue/src/exports/nuxt.ts @@ -0,0 +1,4 @@ +import { wagmiModule } from '../nuxt/module.js' + +export type { WagmiModuleOptions } from '../nuxt/module.js' +export default wagmiModule diff --git a/wagmi-project/packages/vue/src/exports/query.test.ts b/wagmi-project/packages/vue/src/exports/query.test.ts new file mode 100644 index 0000000000..758d45c907 --- /dev/null +++ b/wagmi-project/packages/vue/src/exports/query.test.ts @@ -0,0 +1,99 @@ +import { expect, test } from 'vitest' + +import * as query from './query.js' + +test('exports', () => { + expect(Object.keys(query)).toMatchInlineSnapshot(` + [ + "callQueryKey", + "callQueryOptions", + "connectMutationOptions", + "deployContractMutationOptions", + "disconnectMutationOptions", + "estimateFeesPerGasQueryKey", + "estimateFeesPerGasQueryOptions", + "estimateGasQueryKey", + "estimateGasQueryOptions", + "estimateMaxPriorityFeePerGasQueryKey", + "estimateMaxPriorityFeePerGasQueryOptions", + "getBalanceQueryKey", + "getBalanceQueryOptions", + "getBlockQueryKey", + "getBlockQueryOptions", + "getBlockNumberQueryKey", + "getBlockNumberQueryOptions", + "getBlockTransactionCountQueryKey", + "getBlockTransactionCountQueryOptions", + "getBytecodeQueryKey", + "getBytecodeQueryOptions", + "getCallsStatusQueryKey", + "getCallsStatusQueryOptions", + "getCapabilitiesQueryKey", + "getCapabilitiesQueryOptions", + "getConnectorClientQueryKey", + "getConnectorClientQueryOptions", + "getEnsAddressQueryKey", + "getEnsAddressQueryOptions", + "getEnsAvatarQueryKey", + "getEnsAvatarQueryOptions", + "getEnsNameQueryKey", + "getEnsNameQueryOptions", + "getEnsResolverQueryKey", + "getEnsResolverQueryOptions", + "getEnsTextQueryKey", + "getEnsTextQueryOptions", + "getFeeHistoryQueryKey", + "getFeeHistoryQueryOptions", + "getGasPriceQueryKey", + "getGasPriceQueryOptions", + "getProofQueryKey", + "getProofQueryOptions", + "getStorageAtQueryKey", + "getStorageAtQueryOptions", + "getTokenQueryKey", + "getTokenQueryOptions", + "getTransactionQueryKey", + "getTransactionQueryOptions", + "getTransactionConfirmationsQueryKey", + "getTransactionConfirmationsQueryOptions", + "getTransactionCountQueryKey", + "getTransactionCountQueryOptions", + "getTransactionReceiptQueryKey", + "getTransactionReceiptQueryOptions", + "getWalletClientQueryKey", + "getWalletClientQueryOptions", + "infiniteReadContractsQueryKey", + "infiniteReadContractsQueryOptions", + "prepareTransactionRequestQueryKey", + "prepareTransactionRequestQueryOptions", + "readContractQueryKey", + "readContractQueryOptions", + "readContractsQueryKey", + "readContractsQueryOptions", + "reconnectMutationOptions", + "sendCallsMutationOptions", + "showCallsStatusMutationOptions", + "sendTransactionMutationOptions", + "signMessageMutationOptions", + "signTypedDataMutationOptions", + "switchAccountMutationOptions", + "simulateContractQueryKey", + "simulateContractQueryOptions", + "switchChainMutationOptions", + "verifyMessageQueryKey", + "verifyMessageQueryOptions", + "verifyTypedDataQueryKey", + "verifyTypedDataQueryOptions", + "waitForCallsStatusQueryKey", + "waitForCallsStatusQueryOptions", + "waitForTransactionReceiptQueryKey", + "waitForTransactionReceiptQueryOptions", + "watchAssetMutationOptions", + "writeContractMutationOptions", + "hashFn", + "structuralSharing", + "useMutation", + "useQuery", + ] + `) +}) diff --git a/wagmi-project/packages/vue/src/exports/query.ts b/wagmi-project/packages/vue/src/exports/query.ts new file mode 100644 index 0000000000..cd9169c0e7 --- /dev/null +++ b/wagmi-project/packages/vue/src/exports/query.ts @@ -0,0 +1,19 @@ +//////////////////////////////////////////////////////////////////////////////// +// @wagmi/core/query +//////////////////////////////////////////////////////////////////////////////// + +// biome-ignore lint/performance/noBarrelFile: entrypoint module +// biome-ignore lint/performance/noReExportAll: entrypoint module +export * from '@wagmi/core/query' + +export { + type UseMutationParameters, + type UseMutationReturnType, + useMutation, +} from '../utils/query.js' + +export { + type UseQueryParameters, + type UseQueryReturnType, + useQuery, +} from '../utils/query.js' diff --git a/wagmi-project/packages/vue/src/nuxt/module.ts b/wagmi-project/packages/vue/src/nuxt/module.ts new file mode 100644 index 0000000000..452dcefac4 --- /dev/null +++ b/wagmi-project/packages/vue/src/nuxt/module.ts @@ -0,0 +1,60 @@ +import type { NuxtModule } from '@nuxt/schema' +import { addImports, createResolver, defineNuxtModule } from 'nuxt/kit' + +// biome-ignore lint/complexity/noBannedTypes: +export type WagmiModuleOptions = {} + +export const wagmiModule: NuxtModule = + defineNuxtModule({ + meta: { + name: '@wagmi/vue', + configKey: 'wagmi', + compatibility: { + nuxt: '^3.0.0', + }, + }, + setup(_options, nuxt) { + const { resolve } = createResolver(import.meta.url) + + // Add types + nuxt.hook('prepare:types', ({ references }) => { + references.push({ types: '@wagmi/vue/nuxt' }) + }) + + // Add auto imports + const composables = resolve('./runtime/composables') + const names = [ + 'useAccount', + 'useAccountEffect', + 'useBalance', + 'useBlockNumber', + 'useChainId', + 'useChains', + 'useClient', + 'useConfig', + 'useConnect', + 'useConnections', + 'useConnectorClient', + 'useConnectors', + 'useDisconnect', + 'useEnsAddress', + 'useEnsAvatar', + 'useEnsName', + 'useEstimateGas', + 'useReadContract', + 'useReconnect', + 'useSendTransaction', + 'useSignMessage', + 'useSignTypedData', + 'useSimulateContract', + 'useSwitchAccount', + 'useSwitchChain', + 'useTransaction', + 'useTransactionReceipt', + 'useWaitForTransactionReceipt', + 'useWatchBlockNumber', + 'useWriteContract', + ] + addImports(names.map((name) => ({ from: composables, name }))) + }, + }) diff --git a/wagmi-project/packages/vue/src/nuxt/runtime/composables.ts b/wagmi-project/packages/vue/src/nuxt/runtime/composables.ts new file mode 100644 index 0000000000..2340689357 --- /dev/null +++ b/wagmi-project/packages/vue/src/nuxt/runtime/composables.ts @@ -0,0 +1,3 @@ +// biome-ignore lint/performance/noBarrelFile: entrypoint module +// biome-ignore lint/performance/noReExportAll: entrypoint module +export * from '../../exports/index.js' diff --git a/wagmi-project/packages/vue/src/plugin.ts b/wagmi-project/packages/vue/src/plugin.ts new file mode 100644 index 0000000000..ae0d7f919a --- /dev/null +++ b/wagmi-project/packages/vue/src/plugin.ts @@ -0,0 +1,22 @@ +import { type ResolvedRegister, type State, hydrate } from '@wagmi/core' +import type { Plugin } from 'vue' + +export const configKey = Symbol() + +export type WagmiPluginOptions = { + config: ResolvedRegister['config'] + initialState?: State | undefined + reconnectOnMount?: boolean | undefined +} + +export const WagmiPlugin = { + install(app, options) { + const { config, reconnectOnMount = true } = options + app.provide(configKey, config) + // TODO: check this works in SSR env. + // - reconnect on mount. + // - hydrate initial state. + const { onMount } = hydrate(config, { ...options, reconnectOnMount }) + onMount() + }, +} satisfies Plugin diff --git a/wagmi-project/packages/vue/src/types/properties.ts b/wagmi-project/packages/vue/src/types/properties.ts new file mode 100644 index 0000000000..e09fdb0158 --- /dev/null +++ b/wagmi-project/packages/vue/src/types/properties.ts @@ -0,0 +1,27 @@ +import type { DefaultError, QueryKey } from '@tanstack/vue-query' +import type { Config } from '@wagmi/core' +import type { MaybeRef } from 'vue' +import type { UseQueryParameters } from '../utils/query.js' +import type { DeepUnwrapRef } from './ref.js' + +export type ConfigParameter = { + config?: Config | config | undefined +} + +export type EnabledParameter = { + enabled?: MaybeRef | undefined +} + +export type QueryParameter< + queryFnData = unknown, + error = DefaultError, + data = queryFnData, + queryKey extends QueryKey = QueryKey, +> = { + query?: + | Omit< + DeepUnwrapRef>, + 'queryFn' | 'queryHash' | 'queryKey' | 'queryKeyHashFn' | 'throwOnError' + > + | undefined +} diff --git a/wagmi-project/packages/vue/src/types/ref.ts b/wagmi-project/packages/vue/src/types/ref.ts new file mode 100644 index 0000000000..d9cd8120ec --- /dev/null +++ b/wagmi-project/packages/vue/src/types/ref.ts @@ -0,0 +1,39 @@ +// Credit: https://github.com/TanStack/query/blob/01ce023826b81e6c41e354f27691f65c9725af67/packages/vue-query/src/types.ts + +import type { Config, Connector } from '@wagmi/core' +import type { MaybeRef, Ref, UnwrapRef } from 'vue' + +type Primitive = string | number | boolean | bigint | symbol | undefined | null +type UnwrapLeaf = + | Primitive + // biome-ignore lint/complexity/noBannedTypes: we need to support all types + | Function + | Date + | Error + | RegExp + | Map + | WeakMap + | Set + | WeakSet + +export type DeepMaybeRef = MaybeRef< + // biome-ignore lint/complexity/noBannedTypes: + value extends Function | Config | Connector + ? value + : value extends object | any[] + ? { + [key in keyof value]: DeepMaybeRef + } + : value +> + +export type DeepUnwrapRef = T extends UnwrapLeaf + ? T + : T extends Ref + ? DeepUnwrapRef + : // biome-ignore lint/complexity/noBannedTypes: + T extends {} + ? { + [Property in keyof T]: DeepUnwrapRef + } + : UnwrapRef diff --git a/wagmi-project/packages/vue/src/utils/cloneDeep.ts b/wagmi-project/packages/vue/src/utils/cloneDeep.ts new file mode 100644 index 0000000000..0bbf48deb8 --- /dev/null +++ b/wagmi-project/packages/vue/src/utils/cloneDeep.ts @@ -0,0 +1,44 @@ +// Credit: https://github.com/TanStack/query/blob/01ce023826b81e6c41e354f27691f65c9725af67/packages/vue-query/src/utils.ts + +import { isRef, unref } from 'vue' + +import type { DeepMaybeRef, DeepUnwrapRef } from '../types/ref.js' + +function cloneDeep( + value: DeepMaybeRef, + customize?: (val: DeepMaybeRef) => value | undefined, +): value { + if (customize) { + const result = customize(value) + // If it's a ref of undefined, return undefined + if (result === undefined && isRef(value)) return result as value + if (result !== undefined) return result + } + + if (Array.isArray(value)) + return value.map((val) => cloneDeep(val, customize)) as unknown as value + + if (typeof value === 'object' && isPlainObject(value)) { + const entries = Object.entries(value).map(([key, val]) => [ + key, + cloneDeep(val, customize), + ]) + return Object.fromEntries(entries) + } + + return value as value +} + +export function deepUnref(value: value): DeepUnwrapRef { + return cloneDeep(value as any, (val) => { + if (isRef(val)) return deepUnref(unref(val)) + return undefined + }) +} + +// biome-ignore lint/complexity/noBannedTypes: +function isPlainObject(value: unknown): value is Object { + if (Object.prototype.toString.call(value) !== '[object Object]') return false + const prototype = Object.getPrototypeOf(value) + return prototype === null || prototype === Object.prototype +} diff --git a/wagmi-project/packages/vue/src/utils/getVersion.test.ts b/wagmi-project/packages/vue/src/utils/getVersion.test.ts new file mode 100644 index 0000000000..a2ae6fb1c2 --- /dev/null +++ b/wagmi-project/packages/vue/src/utils/getVersion.test.ts @@ -0,0 +1,7 @@ +import { expect, test } from 'vitest' + +import { getVersion } from './getVersion.js' + +test('default', () => { + expect(getVersion()).toMatchInlineSnapshot(`"@wagmi/vue@x.y.z"`) +}) diff --git a/wagmi-project/packages/vue/src/utils/getVersion.ts b/wagmi-project/packages/vue/src/utils/getVersion.ts new file mode 100644 index 0000000000..1c33c5302a --- /dev/null +++ b/wagmi-project/packages/vue/src/utils/getVersion.ts @@ -0,0 +1,3 @@ +import { version } from '../version.js' + +export const getVersion = () => `@wagmi/vue@${version}` diff --git a/wagmi-project/packages/vue/src/utils/query.ts b/wagmi-project/packages/vue/src/utils/query.ts new file mode 100644 index 0000000000..0ea82af9b7 --- /dev/null +++ b/wagmi-project/packages/vue/src/utils/query.ts @@ -0,0 +1,161 @@ +import { + type DefaultError, + type MutationObserverOptions, + type QueryKey, + type UseQueryOptions, + type UseMutationReturnType as tanstack_UseMutationReturnType, + type UseQueryReturnType as tanstack_UseQueryReturnType, + useQuery as tanstack_useQuery, + useMutation, +} from '@tanstack/vue-query' +import type { + Compute, + ExactPartial, + Omit, + UnionStrictOmit, +} from '@wagmi/core/internal' +import { hashFn } from '@wagmi/core/query' +import { type MaybeRef, computed, unref } from 'vue' + +import type { DeepMaybeRef, DeepUnwrapRef } from '../types/ref.js' + +export type UseMutationParameters< + data = unknown, + error = Error, + variables = void, + context = unknown, +> = Compute< + DeepMaybeRef< + Omit< + DeepUnwrapRef< + MutationObserverOptions, context> + >, + 'mutationFn' | 'mutationKey' | 'throwOnError' + > + > +> + +export type UseMutationReturnType< + data = unknown, + error = Error, + variables = void, + context = unknown, +> = Compute< + UnionStrictOmit< + tanstack_UseMutationReturnType, + 'mutate' | 'mutateAsync' + > +> + +export { useMutation } + +//////////////////////////////////////////////////////////////////////////////// + +export type UseQueryParameters< + queryFnData = unknown, + error = DefaultError, + data = queryFnData, + queryKey extends QueryKey = QueryKey, +> = Compute< + DeepMaybeRef< + ExactPartial< + Omit< + DeepUnwrapRef< + UseQueryOptions + >, + 'initialData' + > + > & { + // Fix `initialData` type + initialData?: + | DeepUnwrapRef< + UseQueryOptions + >['initialData'] + | undefined + } + > +> + +export type UseQueryReturnType = Compute< + tanstack_UseQueryReturnType & { + queryKey: QueryKey + } +> + +// Adding some basic customization. +// Ideally we don't have this function, but `import('@tanstack/vue-query').useQuery` currently has some quirks where it is super hard to +// pass down the inferred `initialData` type because of it's discriminated overload in the on `useQuery`. +export function useQuery( + parameters: MaybeRef< + UseQueryParameters & { + queryKey: QueryKey + } + >, +): UseQueryReturnType { + const options = computed(() => ({ + ...(unref(parameters) as any), + queryKeyHashFn: hashFn, + })) + const result = tanstack_useQuery(options) as UseQueryReturnType + result.queryKey = unref(options).queryKey as QueryKey + return result +} + +//////////////////////////////////////////////////////////////////////////////// + +// export type UseInfiniteQueryParameters< +// queryFnData = unknown, +// error = DefaultError, +// data = queryFnData, +// queryData = queryFnData, +// queryKey extends QueryKey = QueryKey, +// pageParam = unknown, +// > = Compute< +// Omit< +// UseInfiniteQueryOptions< +// queryFnData, +// error, +// data, +// queryData, +// queryKey, +// pageParam +// >, +// 'initialData' +// > & { +// // Fix `initialData` type +// initialData?: +// | UseInfiniteQueryOptions< +// queryFnData, +// error, +// data, +// queryKey +// >['initialData'] +// | undefined +// } +// > + +// export type UseInfiniteQueryReturnType< +// data = unknown, +// error = DefaultError, +// > = import('@tanstack/vue-query').UseInfiniteQueryReturnType & { +// queryKey: QueryKey +// } + +// // Adding some basic customization. +// export function useInfiniteQuery< +// queryFnData, +// error, +// data, +// queryKey extends QueryKey, +// >( +// parameters: UseInfiniteQueryParameters & { +// queryKey: QueryKey +// }, +// ): UseInfiniteQueryReturnType { +// const result = tanstack_useInfiniteQuery({ +// ...(parameters as any), +// queryKeyHashFn: hashFn, // for bigint support +// }) as UseInfiniteQueryReturnType +// result.queryKey = parameters.queryKey +// return result +// } diff --git a/wagmi-project/packages/vue/src/utils/updateState.ts b/wagmi-project/packages/vue/src/utils/updateState.ts new file mode 100644 index 0000000000..bcd53872d5 --- /dev/null +++ b/wagmi-project/packages/vue/src/utils/updateState.ts @@ -0,0 +1,10 @@ +// Credit: https://github.com/TanStack/query/blob/01ce023826b81e6c41e354f27691f65c9725af67/packages/vue-query/src/utils.ts#L11-L18 + +export function updateState( + state: Record, + update: Record, +): void { + for (const key of Object.keys(state)) { + state[key] = update[key] + } +} diff --git a/wagmi-project/packages/vue/src/version.ts b/wagmi-project/packages/vue/src/version.ts new file mode 100644 index 0000000000..4a292eed46 --- /dev/null +++ b/wagmi-project/packages/vue/src/version.ts @@ -0,0 +1 @@ +export const version = '0.1.20' diff --git a/wagmi-project/packages/vue/test/setup.ts b/wagmi-project/packages/vue/test/setup.ts new file mode 100644 index 0000000000..5c0dcc071d --- /dev/null +++ b/wagmi-project/packages/vue/test/setup.ts @@ -0,0 +1,8 @@ +import { vi } from 'vitest' + +// Make dates stable across runs +Date.now = vi.fn(() => new Date(Date.UTC(2023, 1, 1)).valueOf()) + +vi.mock('../src/version.ts', () => { + return { version: 'x.y.z' } +}) diff --git a/wagmi-project/packages/vue/tsconfig.build.json b/wagmi-project/packages/vue/tsconfig.build.json new file mode 100644 index 0000000000..fbed2b1036 --- /dev/null +++ b/wagmi-project/packages/vue/tsconfig.build.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.base.json", + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.test.ts", "src/**/*.test-d.ts"], + "compilerOptions": { + "sourceMap": true + } +} diff --git a/wagmi-project/packages/vue/tsconfig.json b/wagmi-project/packages/vue/tsconfig.json new file mode 100644 index 0000000000..bacbc9228c --- /dev/null +++ b/wagmi-project/packages/vue/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "./tsconfig.build.json", + "include": ["src/**/*.ts", "test/**/*.ts"], + "exclude": [] +} diff --git a/wagmi-project/playgrounds/next/.gitignore b/wagmi-project/playgrounds/next/.gitignore new file mode 100644 index 0000000000..8f322f0d8f --- /dev/null +++ b/wagmi-project/playgrounds/next/.gitignore @@ -0,0 +1,35 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/wagmi-project/playgrounds/next/next.config.mjs b/wagmi-project/playgrounds/next/next.config.mjs new file mode 100644 index 0000000000..8831ff653a --- /dev/null +++ b/wagmi-project/playgrounds/next/next.config.mjs @@ -0,0 +1,20 @@ +import bundleAnalyzer from '@next/bundle-analyzer' + +const withBundleAnalyzer = bundleAnalyzer({ + enabled: process.env.ANALYZE === 'true', +}) + +/** @type {import('next').NextConfig} */ +const nextConfig = { + experimental: { + externalDir: true, + }, + webpack(config) { + config.resolve.extensionAlias = { + '.js': ['.js', '.ts'], + } + return config + }, +} + +export default withBundleAnalyzer(nextConfig) diff --git a/wagmi-project/playgrounds/next/package.json b/wagmi-project/playgrounds/next/package.json new file mode 100644 index 0000000000..0afbe99d38 --- /dev/null +++ b/wagmi-project/playgrounds/next/package.json @@ -0,0 +1,31 @@ +{ + "name": "next-app", + "private": true, + "scripts": { + "analyze": "ANALYZE=true next build", + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "next lint" + }, + "dependencies": { + "@next/bundle-analyzer": "^15.2.4", + "@tanstack/react-query": ">=5.45.1", + "next": "15.3.3", + "react": ">=18.3.1", + "react-dom": ">=18.3.1", + "viem": "2.*", + "wagmi": "workspace:*" + }, + "devDependencies": { + "@types/node": "^22.14.1", + "@types/react": ">=18.3.1", + "@types/react-dom": ">=18.3.0", + "bufferutil": "^4.0.8", + "encoding": "^0.1.13", + "lokijs": "^1.5.12", + "pino-pretty": "^13.0.0", + "supports-color": "^9.4.0", + "utf-8-validate": "^6.0.5" + } +} diff --git a/wagmi-project/playgrounds/next/src/app/contracts.ts b/wagmi-project/playgrounds/next/src/app/contracts.ts new file mode 100644 index 0000000000..d7d66754a2 --- /dev/null +++ b/wagmi-project/playgrounds/next/src/app/contracts.ts @@ -0,0 +1,202 @@ +export const wagmiContractConfig = { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi: [ + { inputs: [], stateMutability: 'nonpayable', type: 'constructor' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: 'owner', + type: 'address', + }, + { + indexed: true, + name: 'approved', + type: 'address', + }, + { + indexed: true, + name: 'tokenId', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: 'owner', + type: 'address', + }, + { + indexed: true, + name: 'operator', + type: 'address', + }, + { + indexed: false, + name: 'approved', + type: 'bool', + }, + ], + name: 'ApprovalForAll', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: 'from', + type: 'address', + }, + { indexed: true, name: 'to', type: 'address' }, + { + indexed: true, + name: 'tokenId', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + inputs: [ + { name: 'to', type: 'address' }, + { name: 'tokenId', type: 'uint256' }, + ], + name: 'approve', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ name: 'owner', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ name: 'tokenId', type: 'uint256' }], + name: 'getApproved', + outputs: [{ name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { name: 'owner', type: 'address' }, + { name: 'operator', type: 'address' }, + ], + name: 'isApprovedForAll', + outputs: [{ name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'mint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'tokenId', type: 'uint256' }], + name: 'mint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [{ name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ name: 'tokenId', type: 'uint256' }], + name: 'ownerOf', + outputs: [{ name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { name: 'from', type: 'address' }, + { name: 'to', type: 'address' }, + { name: 'tokenId', type: 'uint256' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { name: 'from', type: 'address' }, + { name: 'to', type: 'address' }, + { name: 'tokenId', type: 'uint256' }, + { name: '_data', type: 'bytes' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { name: 'operator', type: 'address' }, + { name: 'approved', type: 'bool' }, + ], + name: 'setApprovalForAll', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ name: 'interfaceId', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [{ name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ name: 'tokenId', type: 'uint256' }], + name: 'tokenURI', + outputs: [{ name: '', type: 'string' }], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { name: 'from', type: 'address' }, + { name: 'to', type: 'address' }, + { name: 'tokenId', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + ], +} as const diff --git a/wagmi-project/playgrounds/next/src/app/globals.css b/wagmi-project/playgrounds/next/src/app/globals.css new file mode 100644 index 0000000000..0733a7ee6b --- /dev/null +++ b/wagmi-project/playgrounds/next/src/app/globals.css @@ -0,0 +1,21 @@ +:root { + background-color: #181818; + color: rgba(255, 255, 255, 0.87); + color-scheme: light dark; + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + font-synthesis: none; + font-weight: 400; + line-height: 1.5; + text-rendering: optimizeLegibility; + + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-text-size-adjust: 100%; +} + +@media (prefers-color-scheme: light) { + :root { + background-color: #f8f8f8; + color: #181818; + } +} diff --git a/wagmi-project/playgrounds/next/src/app/layout.tsx b/wagmi-project/playgrounds/next/src/app/layout.tsx new file mode 100644 index 0000000000..72ec934a03 --- /dev/null +++ b/wagmi-project/playgrounds/next/src/app/layout.tsx @@ -0,0 +1,30 @@ +import type { Metadata } from 'next' +import { Inter } from 'next/font/google' +import { headers } from 'next/headers' +import type { ReactNode } from 'react' +import { cookieToInitialState } from 'wagmi' +import './globals.css' + +import { getConfig } from '../wagmi' +import { Providers } from './providers' + +const inter = Inter({ subsets: ['latin'] }) + +export const metadata: Metadata = { + title: 'Create Wagmi', + description: 'Generated by create-wagmi', +} + +export default async function RootLayout(props: { children: ReactNode }) { + const initialState = cookieToInitialState( + getConfig(), + (await headers()).get('cookie'), + ) + return ( + + + {props.children} + + + ) +} diff --git a/wagmi-project/playgrounds/next/src/app/page.tsx b/wagmi-project/playgrounds/next/src/app/page.tsx new file mode 100644 index 0000000000..33c1bf0abb --- /dev/null +++ b/wagmi-project/playgrounds/next/src/app/page.tsx @@ -0,0 +1,412 @@ +'use client' + +import type { FormEvent } from 'react' +import { type Hex, formatEther, parseAbi, parseEther } from 'viem' +import { + type BaseError, + useAccount, + useAccountEffect, + useBalance, + useBlockNumber, + useChainId, + useConfig, + useConnect, + useConnections, + useConnectorClient, + useDisconnect, + useEnsName, + useReadContract, + useReadContracts, + useSendTransaction, + useSignMessage, + useSwitchAccount, + useSwitchChain, + useWaitForTransactionReceipt, + useWriteContract, +} from 'wagmi' +import { switchChain } from 'wagmi/actions' +import { optimism, sepolia } from 'wagmi/chains' + +import { wagmiContractConfig } from './contracts' + +export default function App() { + useAccountEffect({ + onConnect(_data) { + // console.log('onConnect', data) + }, + onDisconnect() { + // console.log('onDisconnect') + }, + }) + + return ( + <> + + + + + + + + + + + + + + + + ) +} + +function Account() { + const account = useAccount() + const { disconnect } = useDisconnect() + const { data: ensName } = useEnsName({ + address: account.address, + }) + + return ( +
+

Account

+ +
+ account: {account.address} {ensName} +
+ chainId: {account.chainId} +
+ status: {account.status} +
+ + {account.status === 'connected' && ( + + )} +
+ ) +} + +function Connect() { + const chainId = useChainId() + const { connectors, connect, status, error } = useConnect() + + return ( +
+

Connect

+ {connectors.map((connector) => ( + + ))} +
{status}
+
{error?.message}
+
+ ) +} + +function SwitchAccount() { + const account = useAccount() + const { connectors, switchAccount } = useSwitchAccount() + + return ( +
+

Switch Account

+ + {connectors.map((connector) => ( + + ))} +
+ ) +} + +function SwitchChain() { + const chainId = useChainId() + const { chains, switchChain, error } = useSwitchChain() + + return ( +
+

Switch Chain

+ + {chains.map((chain) => ( + + ))} + + {error?.message} +
+ ) +} + +function SignMessage() { + const { data, signMessage } = useSignMessage() + + return ( +
+

Sign Message

+ +
{ + event.preventDefault() + const formData = new FormData(event.target as HTMLFormElement) + signMessage({ message: formData.get('message') as string }) + }} + > + + +
+ + {data} +
+ ) +} + +function Connections() { + const connections = useConnections() + + return ( +
+

Connections

+ + {connections.map((connection) => ( +
+
connector {connection.connector.name}
+
accounts: {JSON.stringify(connection.accounts)}
+
chainId: {connection.chainId}
+
+ ))} +
+ ) +} + +function Balance() { + const { address } = useAccount() + + const { data: default_ } = useBalance({ address }) + const { data: account_ } = useBalance({ address }) + const { data: optimism_ } = useBalance({ + address, + chainId: optimism.id, + }) + + return ( +
+

Balance

+ +
+ Balance (Default Chain):{' '} + {!!default_?.value && formatEther(default_.value)} +
+
+ Balance (Account Chain):{' '} + {!!account_?.value && formatEther(account_.value)} +
+
+ Balance (Optimism Chain):{' '} + {!!optimism_?.value && formatEther(optimism_.value)} +
+
+ ) +} + +function BlockNumber() { + const { data: default_ } = useBlockNumber({ watch: true }) + const { data: account_ } = useBlockNumber({ + watch: true, + }) + const { data: optimism_ } = useBlockNumber({ + chainId: optimism.id, + watch: true, + }) + + return ( +
+

Block Number

+ +
Block Number (Default Chain): {default_?.toString()}
+
Block Number (Account Chain): {account_?.toString()}
+
Block Number (Optimism): {optimism_?.toString()}
+
+ ) +} + +function ConnectorClient() { + const { data, error } = useConnectorClient() + return ( +
+

Connector Client

+ client {data?.account?.address} {data?.chain?.id} + {error?.message} +
+ ) +} + +function SendTransaction() { + const { data: hash, error, isPending, sendTransaction } = useSendTransaction() + + async function submit(e: FormEvent) { + e.preventDefault() + const formData = new FormData(e.target as HTMLFormElement) + const to = formData.get('address') as Hex + const value = formData.get('value') as string + sendTransaction({ to, value: parseEther(value) }) + } + + const { isLoading: isConfirming, isSuccess: isConfirmed } = + useWaitForTransactionReceipt({ + hash, + }) + + return ( +
+

Send Transaction

+
+ + + +
+ {hash &&
Transaction Hash: {hash}
} + {isConfirming && 'Waiting for confirmation...'} + {isConfirmed && 'Transaction confirmed.'} + {error && ( +
Error: {(error as BaseError).shortMessage || error.message}
+ )} +
+ ) +} + +function ReadContract() { + const { data: balance } = useReadContract({ + ...wagmiContractConfig, + functionName: 'balanceOf', + args: ['0x03A71968491d55603FFe1b11A9e23eF013f75bCF'], + }) + + return ( +
+

Read Contract

+
Balance: {balance?.toString()}
+
+ ) +} + +function ReadContracts() { + const { data } = useReadContracts({ + allowFailure: false, + contracts: [ + { + ...wagmiContractConfig, + functionName: 'balanceOf', + args: ['0x03A71968491d55603FFe1b11A9e23eF013f75bCF'], + }, + { + ...wagmiContractConfig, + functionName: 'ownerOf', + args: [69n], + }, + { + ...wagmiContractConfig, + functionName: 'totalSupply', + }, + ], + }) + const [balance, ownerOf, totalSupply] = data || [] + + return ( +
+

Read Contract

+
Balance: {balance?.toString()}
+
Owner of Token 69: {ownerOf?.toString()}
+
Total Supply: {totalSupply?.toString()}
+
+ ) +} + +function WriteContract() { + const { data: hash, error, isPending, writeContract } = useWriteContract() + + async function submit(e: FormEvent) { + e.preventDefault() + const formData = new FormData(e.target as HTMLFormElement) + const tokenId = formData.get('tokenId') as string + writeContract({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi: parseAbi(['function mint(uint256 tokenId)']), + functionName: 'mint', + args: [BigInt(tokenId)], + }) + } + + const { isLoading: isConfirming, isSuccess: isConfirmed } = + useWaitForTransactionReceipt({ + hash, + }) + + return ( +
+

Write Contract

+
+ + +
+ {hash &&
Transaction Hash: {hash}
} + {isConfirming && 'Waiting for confirmation...'} + {isConfirmed && 'Transaction confirmed.'} + {error && ( +
Error: {(error as BaseError).shortMessage || error.message}
+ )} +
+ ) +} + +function Repro() { + const config = useConfig() + const chainId = useChainId() + + // biome-ignore lint/suspicious/noConsoleLog: + console.log('chainId from useChainId is', chainId) + return ( +
+ Current Chain Id: {chainId} + + +
+ ) +} diff --git a/wagmi-project/playgrounds/next/src/app/providers.tsx b/wagmi-project/playgrounds/next/src/app/providers.tsx new file mode 100644 index 0000000000..3f0082dd22 --- /dev/null +++ b/wagmi-project/playgrounds/next/src/app/providers.tsx @@ -0,0 +1,23 @@ +'use client' + +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { type ReactNode, useState } from 'react' +import { type State, WagmiProvider } from 'wagmi' + +import { getConfig } from '../wagmi' + +export function Providers(props: { + children: ReactNode + initialState?: State +}) { + const [config] = useState(() => getConfig()) + const [queryClient] = useState(() => new QueryClient()) + + return ( + + + {props.children} + + + ) +} diff --git a/wagmi-project/playgrounds/next/src/wagmi.ts b/wagmi-project/playgrounds/next/src/wagmi.ts new file mode 100644 index 0000000000..0c9db90a5d --- /dev/null +++ b/wagmi-project/playgrounds/next/src/wagmi.ts @@ -0,0 +1,31 @@ +import { http, cookieStorage, createConfig, createStorage } from 'wagmi' +import { mainnet, optimism, sepolia } from 'wagmi/chains' +import { injected, metaMask, walletConnect } from 'wagmi/connectors' + +export function getConfig() { + return createConfig({ + chains: [mainnet, sepolia, optimism], + connectors: [ + injected(), + walletConnect({ + projectId: process.env.NEXT_PUBLIC_WC_PROJECT_ID!, + }), + metaMask(), + ], + storage: createStorage({ + storage: cookieStorage, + }), + ssr: true, + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + [optimism.id]: http(), + }, + }) +} + +declare module 'wagmi' { + interface Register { + config: ReturnType + } +} diff --git a/wagmi-project/playgrounds/next/tsconfig.json b/wagmi-project/playgrounds/next/tsconfig.json new file mode 100644 index 0000000000..9eb40a20d5 --- /dev/null +++ b/wagmi-project/playgrounds/next/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "target": "ESNext", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ] + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + "exclude": ["node_modules"] +} diff --git a/wagmi-project/playgrounds/nuxt/.gitignore b/wagmi-project/playgrounds/nuxt/.gitignore new file mode 100644 index 0000000000..4a7f73a2ed --- /dev/null +++ b/wagmi-project/playgrounds/nuxt/.gitignore @@ -0,0 +1,24 @@ +# Nuxt dev/build outputs +.output +.data +.nuxt +.nitro +.cache +dist + +# Node dependencies +node_modules + +# Logs +logs +*.log + +# Misc +.DS_Store +.fleet +.idea + +# Local env files +.env +.env.* +!.env.example diff --git a/wagmi-project/playgrounds/nuxt/app.vue b/wagmi-project/playgrounds/nuxt/app.vue new file mode 100644 index 0000000000..98b46bf528 --- /dev/null +++ b/wagmi-project/playgrounds/nuxt/app.vue @@ -0,0 +1,28 @@ + + + diff --git a/wagmi-project/playgrounds/nuxt/components/Account.vue b/wagmi-project/playgrounds/nuxt/components/Account.vue new file mode 100644 index 0000000000..33f1491dac --- /dev/null +++ b/wagmi-project/playgrounds/nuxt/components/Account.vue @@ -0,0 +1,22 @@ + + + diff --git a/wagmi-project/playgrounds/nuxt/components/Connect.vue b/wagmi-project/playgrounds/nuxt/components/Connect.vue new file mode 100644 index 0000000000..93320448c0 --- /dev/null +++ b/wagmi-project/playgrounds/nuxt/components/Connect.vue @@ -0,0 +1,19 @@ + + + diff --git a/wagmi-project/playgrounds/nuxt/nuxt.config.ts b/wagmi-project/playgrounds/nuxt/nuxt.config.ts new file mode 100644 index 0000000000..adfe7fd2d8 --- /dev/null +++ b/wagmi-project/playgrounds/nuxt/nuxt.config.ts @@ -0,0 +1,7 @@ +import { defineNuxtConfig } from 'nuxt/config' + +// https://nuxt.com/docs/api/configuration/nuxt-config +export default defineNuxtConfig({ + devtools: { enabled: true }, + modules: ['@wagmi/vue/nuxt'], +}) diff --git a/wagmi-project/playgrounds/nuxt/package.json b/wagmi-project/playgrounds/nuxt/package.json new file mode 100644 index 0000000000..512a1be279 --- /dev/null +++ b/wagmi-project/playgrounds/nuxt/package.json @@ -0,0 +1,20 @@ +{ + "name": "nuxt-app", + "private": true, + "type": "module", + "scripts": { + "build": "nuxt build", + "dev": "nuxt dev", + "generate": "nuxt generate", + "preview": "nuxt preview", + "_postinstall": "nuxt prepare" + }, + "dependencies": { + "@tanstack/vue-query": ">=5.45.0", + "@wagmi/vue": "workspace:*", + "nuxt": "^3.16.0", + "viem": "2.*", + "vue": ">=3.4.21", + "vue-router": "^4.3.2" + } +} diff --git a/wagmi-project/playgrounds/nuxt/plugins/wagmi.ts b/wagmi-project/playgrounds/nuxt/plugins/wagmi.ts new file mode 100644 index 0000000000..b6abe5bcd2 --- /dev/null +++ b/wagmi-project/playgrounds/nuxt/plugins/wagmi.ts @@ -0,0 +1,10 @@ +import { VueQueryPlugin } from '@tanstack/vue-query' +import { WagmiPlugin } from '@wagmi/vue' +import { defineNuxtPlugin } from 'nuxt/app' + +import { config } from '../wagmi' + +// TODO: Move to @wagmi/vue/nuxt nitro plugin +export default defineNuxtPlugin((nuxtApp) => { + nuxtApp.vueApp.use(WagmiPlugin, { config }).use(VueQueryPlugin, {}) +}) diff --git a/wagmi-project/playgrounds/nuxt/public/favicon.ico b/wagmi-project/playgrounds/nuxt/public/favicon.ico new file mode 100644 index 0000000000..18993ad91c Binary files /dev/null and b/wagmi-project/playgrounds/nuxt/public/favicon.ico differ diff --git a/wagmi-project/playgrounds/nuxt/server/tsconfig.json b/wagmi-project/playgrounds/nuxt/server/tsconfig.json new file mode 100644 index 0000000000..b9ed69c19e --- /dev/null +++ b/wagmi-project/playgrounds/nuxt/server/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../.nuxt/tsconfig.server.json" +} diff --git a/wagmi-project/playgrounds/nuxt/tsconfig.json b/wagmi-project/playgrounds/nuxt/tsconfig.json new file mode 100644 index 0000000000..4b34df1571 --- /dev/null +++ b/wagmi-project/playgrounds/nuxt/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "./.nuxt/tsconfig.json" +} diff --git a/wagmi-project/playgrounds/nuxt/wagmi.ts b/wagmi-project/playgrounds/nuxt/wagmi.ts new file mode 100644 index 0000000000..83e8569ea8 --- /dev/null +++ b/wagmi-project/playgrounds/nuxt/wagmi.ts @@ -0,0 +1,29 @@ +import { http, cookieStorage, createConfig, createStorage } from '@wagmi/vue' +import { mainnet, optimism, sepolia } from '@wagmi/vue/chains' +import { injected, metaMask, walletConnect } from '@wagmi/vue/connectors' + +export const config = createConfig({ + chains: [mainnet, sepolia, optimism], + connectors: [ + injected(), + walletConnect({ + projectId: process.env.NUXT_PUBLIC_WC_PROJECT_ID!, + }), + metaMask(), + ], + storage: createStorage({ + storage: cookieStorage, + }), + ssr: true, + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + [optimism.id]: http(), + }, +}) + +declare module '@wagmi/vue' { + interface Register { + config: typeof config + } +} diff --git a/wagmi-project/playgrounds/vite-core/.gitignore b/wagmi-project/playgrounds/vite-core/.gitignore new file mode 100644 index 0000000000..a547bf36d8 --- /dev/null +++ b/wagmi-project/playgrounds/vite-core/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/wagmi-project/playgrounds/vite-core/index.html b/wagmi-project/playgrounds/vite-core/index.html new file mode 100644 index 0000000000..0e8cfb2692 --- /dev/null +++ b/wagmi-project/playgrounds/vite-core/index.html @@ -0,0 +1,12 @@ + + + + + + Vite Core + + +
+ + + diff --git a/wagmi-project/playgrounds/vite-core/package.json b/wagmi-project/playgrounds/vite-core/package.json new file mode 100644 index 0000000000..07a606dc35 --- /dev/null +++ b/wagmi-project/playgrounds/vite-core/package.json @@ -0,0 +1,24 @@ +{ + "name": "vite-core", + "private": true, + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc && vite build", + "preview": "vite preview" + }, + "dependencies": { + "@wagmi/connectors": "workspace:*", + "@wagmi/core": "workspace:*", + "react": ">=18.3.1", + "react-dom": ">=18.3.1", + "viem": "2.*" + }, + "devDependencies": { + "@types/react": ">=18.3.1", + "@types/react-dom": ">=18.3.0", + "@vitejs/plugin-react": "^4.2.1", + "buffer": "^6.0.3", + "vite": "^5.4.19" + } +} diff --git a/wagmi-project/playgrounds/vite-core/src/App.tsx b/wagmi-project/playgrounds/vite-core/src/App.tsx new file mode 100644 index 0000000000..3c8646be39 --- /dev/null +++ b/wagmi-project/playgrounds/vite-core/src/App.tsx @@ -0,0 +1,186 @@ +import { + type GetBalanceReturnType, + type GetBlockNumberReturnType, + connect, + disconnect, + getAccount, + getBalance, + getBlockNumber, + reconnect, + switchAccount, + watchAccount, + watchBlockNumber, +} from '@wagmi/core' +import { useEffect, useReducer, useState } from 'react' + +import { formatEther } from 'viem' +import { config } from './wagmi' + +function App() { + useEffect(() => { + reconnect(config) + }, []) + + return ( + <> + + + + + + + ) +} + +function Account() { + const [account, setAccount] = useState(getAccount(config)) + + useEffect(() => { + return watchAccount(config, { + onChange(data) { + setAccount(data) + }, + }) + }, []) + + return ( +
+

Account

+ +
+ account: {account.address} +
+ chainId: {account.chainId} +
+ status: {account.status} +
+ + {account.status === 'connected' && ( + + )} +
+ ) +} + +function Connect() { + const [, rerender] = useReducer((count) => count + 1, 0) + + useEffect(() => { + return config.subscribe(({ connections }) => connections, rerender) + }, []) + + return ( +
+

Connect

+ + {config.connectors.map((connector) => ( + + ))} +
+ ) +} + +function SwitchAccount() { + const [, rerender] = useReducer((count) => count + 1, 0) + + useEffect(() => { + return config.subscribe( + ({ connections, current }) => ({ connections, current }), + rerender, + ) + }, []) + + return ( +
+

SwitchAccount

+ + {config.connectors + .filter((connector) => config.state.connections.has(connector.uid)) + .map((connector) => ( + + ))} +
+ ) +} + +function Balance() { + const [account, setAccount] = useState(getAccount(config)) + + useEffect(() => { + return watchAccount(config, { + onChange(data) { + setAccount(data) + }, + }) + }, []) + + ///////////////////////////////////////////////////////// + + const [balance, setBalance] = useState() + + useEffect(() => { + if (!account.address) return + return watchBlockNumber(config, { + async onBlockNumber() { + try { + const balance = await getBalance(config, { + address: account.address!, + }) + setBalance(balance) + } catch (error) { + console.error('Error fetching balance', error) + } + }, + }) + }, [account.address]) + + return ( +
+

Balance

+ +
Balance: {!!balance?.value && formatEther(balance.value)}
+
+ ) +} + +function BlockNumber() { + const [blockNumber, setBlockNumber] = useState< + GetBlockNumberReturnType | undefined + >() + + useEffect(() => { + ;(async () => { + setBlockNumber(await getBlockNumber(config)) + + watchBlockNumber(config, { onBlockNumber: setBlockNumber }) + })() + }, []) + + return ( +
+

Block Number

+ +
Block Number (Default Chain): {blockNumber?.toString()}
+
+ ) +} + +export default App diff --git a/wagmi-project/playgrounds/vite-core/src/index.css b/wagmi-project/playgrounds/vite-core/src/index.css new file mode 100644 index 0000000000..0733a7ee6b --- /dev/null +++ b/wagmi-project/playgrounds/vite-core/src/index.css @@ -0,0 +1,21 @@ +:root { + background-color: #181818; + color: rgba(255, 255, 255, 0.87); + color-scheme: light dark; + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + font-synthesis: none; + font-weight: 400; + line-height: 1.5; + text-rendering: optimizeLegibility; + + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-text-size-adjust: 100%; +} + +@media (prefers-color-scheme: light) { + :root { + background-color: #f8f8f8; + color: #181818; + } +} diff --git a/wagmi-project/playgrounds/vite-core/src/main.tsx b/wagmi-project/playgrounds/vite-core/src/main.tsx new file mode 100644 index 0000000000..180d9e1fc0 --- /dev/null +++ b/wagmi-project/playgrounds/vite-core/src/main.tsx @@ -0,0 +1,16 @@ +import React from 'react' +import ReactDOM from 'react-dom/client' +import './index.css' + +import { Buffer } from 'buffer' + +// `@coinbase-wallet/sdk` uses `Buffer` +globalThis.Buffer = Buffer + +import App from './App.tsx' + +ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( + + + , +) diff --git a/wagmi-project/playgrounds/vite-core/src/vite-env.d.ts b/wagmi-project/playgrounds/vite-core/src/vite-env.d.ts new file mode 100644 index 0000000000..11f02fe2a0 --- /dev/null +++ b/wagmi-project/playgrounds/vite-core/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/wagmi-project/playgrounds/vite-core/src/wagmi.ts b/wagmi-project/playgrounds/vite-core/src/wagmi.ts new file mode 100644 index 0000000000..d6152f9d24 --- /dev/null +++ b/wagmi-project/playgrounds/vite-core/src/wagmi.ts @@ -0,0 +1,22 @@ +import { coinbaseWallet, metaMask, walletConnect } from '@wagmi/connectors' +import { http, createConfig, createStorage } from '@wagmi/core' +import { mainnet, optimism, sepolia } from '@wagmi/core/chains' + +export const config = createConfig({ + chains: [mainnet, sepolia, optimism], + connectors: [ + walletConnect({ projectId: import.meta.env.VITE_WC_PROJECT_ID }), + coinbaseWallet(), + metaMask(), + ], + storage: createStorage({ storage: localStorage, key: 'vite-core' }), + transports: { + [mainnet.id]: http( + 'https://eth-mainnet.g.alchemy.com/v2/StF61Ht3J9nXAojZX-b21LVt9l0qDL38', + ), + [sepolia.id]: http( + 'https://eth-sepolia.g.alchemy.com/v2/roJyEHxkj7XWg1T9wmYnxvktDodQrFAS', + ), + [optimism.id]: http(), + }, +}) diff --git a/wagmi-project/playgrounds/vite-core/tsconfig.json b/wagmi-project/playgrounds/vite-core/tsconfig.json new file mode 100644 index 0000000000..36d04ef376 --- /dev/null +++ b/wagmi-project/playgrounds/vite-core/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "target": "ESNext", + "lib": ["DOM", "DOM.Iterable", "ESNext"], + "module": "ESNext", + "skipLibCheck": true, + + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + + "paths": { + "@wagmi/connectors": ["../../packages/connectors/src/exports"], + "@wagmi/core": ["../../packages/core/src/exports"], + "@wagmi/core/*": ["../../packages/core/src/exports/*"] + } + }, + "include": ["src"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/wagmi-project/playgrounds/vite-core/tsconfig.node.json b/wagmi-project/playgrounds/vite-core/tsconfig.node.json new file mode 100644 index 0000000000..42872c59f5 --- /dev/null +++ b/wagmi-project/playgrounds/vite-core/tsconfig.node.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/wagmi-project/playgrounds/vite-core/vite.config.ts b/wagmi-project/playgrounds/vite-core/vite.config.ts new file mode 100644 index 0000000000..36f7f4e1bc --- /dev/null +++ b/wagmi-project/playgrounds/vite-core/vite.config.ts @@ -0,0 +1,7 @@ +import react from '@vitejs/plugin-react' +import { defineConfig } from 'vite' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [react()], +}) diff --git a/wagmi-project/playgrounds/vite-react/.gitignore b/wagmi-project/playgrounds/vite-react/.gitignore new file mode 100644 index 0000000000..1b226cc615 --- /dev/null +++ b/wagmi-project/playgrounds/vite-react/.gitignore @@ -0,0 +1,26 @@ +src/generated.ts + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/wagmi-project/playgrounds/vite-react/index.html b/wagmi-project/playgrounds/vite-react/index.html new file mode 100644 index 0000000000..c29681356c --- /dev/null +++ b/wagmi-project/playgrounds/vite-react/index.html @@ -0,0 +1,12 @@ + + + + + + Vite React + + +
+ + + diff --git a/wagmi-project/playgrounds/vite-react/package.json b/wagmi-project/playgrounds/vite-react/package.json new file mode 100644 index 0000000000..8b09e075f6 --- /dev/null +++ b/wagmi-project/playgrounds/vite-react/package.json @@ -0,0 +1,29 @@ +{ + "name": "vite-react", + "private": true, + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc && vite build", + "preview": "vite preview" + }, + "dependencies": { + "@tanstack/query-sync-storage-persister": "5.0.5", + "@tanstack/react-query": ">=5.45.1", + "@tanstack/react-query-persist-client": "5.0.5", + "idb-keyval": "^6.2.1", + "react": ">=18.3.1", + "react-dom": ">=18.3.1", + "viem": "2.*", + "wagmi": "workspace:*" + }, + "devDependencies": { + "@tanstack/react-query-devtools": "5.0.5", + "@types/react": ">=18.3.1", + "@types/react-dom": ">=18.3.0", + "@vitejs/plugin-react": "^4.2.1", + "@wagmi/cli": "workspace:*", + "buffer": "^6.0.3", + "vite": "^5.4.19" + } +} diff --git a/wagmi-project/playgrounds/vite-react/public/manifest.json b/wagmi-project/playgrounds/vite-react/public/manifest.json new file mode 100644 index 0000000000..c5d4517110 --- /dev/null +++ b/wagmi-project/playgrounds/vite-react/public/manifest.json @@ -0,0 +1,5 @@ +{ + "name": "vite-react", + "description": "vite-react playground", + "iconPath": "favicon.ico" +} diff --git a/wagmi-project/playgrounds/vite-react/src/App.tsx b/wagmi-project/playgrounds/vite-react/src/App.tsx new file mode 100644 index 0000000000..ad2e36b06f --- /dev/null +++ b/wagmi-project/playgrounds/vite-react/src/App.tsx @@ -0,0 +1,389 @@ +import type { FormEvent } from 'react' +import { type Hex, formatEther, parseAbi, parseEther } from 'viem' +import { + type BaseError, + useAccount, + useAccountEffect, + useBalance, + useBlockNumber, + useChainId, + useConnect, + useConnections, + useConnectorClient, + useDisconnect, + useEnsName, + useReadContract, + useReadContracts, + useSendTransaction, + useSignMessage, + useSwitchAccount, + useSwitchChain, + useWaitForTransactionReceipt, + useWriteContract, +} from 'wagmi' +import { optimism } from 'wagmi/chains' + +import { wagmiContractConfig } from './contracts' + +function App() { + useAccountEffect({ + onConnect(_data) { + // console.log('onConnect', data) + }, + onDisconnect() { + // console.log('onDisconnect') + }, + }) + + return ( + <> + + + + + + + + + + + + + + + ) +} + +function Account() { + const account = useAccount() + const { disconnect } = useDisconnect() + const { data: ensName } = useEnsName({ + address: account.address, + }) + + return ( +
+

Account

+ +
+ account: {account.address} {ensName} +
+ chainId: {account.chainId} +
+ status: {account.status} +
+ + {account.status !== 'disconnected' && ( + + )} +
+ ) +} + +function Connect() { + const chainId = useChainId() + const { connectors, connect, status, error } = useConnect() + + return ( +
+

Connect

+ {connectors.map((connector) => ( + + ))} +
{status}
+
{error?.message}
+
+ ) +} + +function SwitchAccount() { + const account = useAccount() + const { connectors, switchAccount } = useSwitchAccount() + + return ( +
+

Switch Account

+ + {connectors.map((connector) => ( + + ))} +
+ ) +} + +function SwitchChain() { + const chainId = useChainId() + const { chains, switchChain, error } = useSwitchChain() + + return ( +
+

Switch Chain

+ + {chains.map((chain) => ( + + ))} + + {error?.message} +
+ ) +} + +function SignMessage() { + const { data, signMessage } = useSignMessage() + + return ( +
+

Sign Message

+ +
{ + event.preventDefault() + const formData = new FormData(event.target as HTMLFormElement) + signMessage({ message: formData.get('message') as string }) + }} + > + + +
+ + {data} +
+ ) +} + +function Connections() { + const connections = useConnections() + + return ( +
+

Connections

+ + {connections.map((connection) => ( +
+
connector {connection.connector.name}
+
accounts: {JSON.stringify(connection.accounts)}
+
chainId: {connection.chainId}
+
+ ))} +
+ ) +} + +function Balance() { + const { address } = useAccount() + + const { data: default_ } = useBalance({ address }) + const { data: account_ } = useBalance({ address }) + const { data: optimism_ } = useBalance({ + address, + chainId: optimism.id, + }) + + return ( +
+

Balance

+ +
+ Balance (Default Chain):{' '} + {!!default_?.value && formatEther(default_.value)} +
+
+ Balance (Account Chain):{' '} + {!!account_?.value && formatEther(account_.value)} +
+
+ Balance (Optimism Chain):{' '} + {!!optimism_?.value && formatEther(optimism_.value)} +
+
+ ) +} + +function BlockNumber() { + const { data: default_ } = useBlockNumber({ watch: true }) + const { data: account_ } = useBlockNumber({ + watch: true, + }) + const { data: optimism_ } = useBlockNumber({ + chainId: optimism.id, + watch: true, + }) + + return ( +
+

Block Number

+ +
Block Number (Default Chain): {default_?.toString()}
+
Block Number (Account Chain): {account_?.toString()}
+
Block Number (Optimism): {optimism_?.toString()}
+
+ ) +} + +function ConnectorClient() { + const { data, error } = useConnectorClient() + return ( +
+

Connector Client

+ client {data?.account?.address} {data?.chain?.id} + {error?.message} +
+ ) +} + +function SendTransaction() { + const { data: hash, error, isPending, sendTransaction } = useSendTransaction() + + async function submit(e: FormEvent) { + e.preventDefault() + const formData = new FormData(e.target as HTMLFormElement) + const to = formData.get('address') as Hex + const value = formData.get('value') as string + sendTransaction({ to, value: parseEther(value) }) + } + + const { isLoading: isConfirming, isSuccess: isConfirmed } = + useWaitForTransactionReceipt({ + hash, + }) + + return ( +
+

Send Transaction

+
+ + + +
+ {hash &&
Transaction Hash: {hash}
} + {isConfirming && 'Waiting for confirmation...'} + {isConfirmed && 'Transaction confirmed.'} + {error && ( +
Error: {(error as BaseError).shortMessage || error.message}
+ )} +
+ ) +} + +function ReadContract() { + const { data: balance } = useReadContract({ + ...wagmiContractConfig, + functionName: 'balanceOf', + args: ['0x03A71968491d55603FFe1b11A9e23eF013f75bCF'], + }) + + return ( +
+

Read Contract

+
Balance: {balance?.toString()}
+
+ ) +} + +function ReadContracts() { + const { data } = useReadContracts({ + allowFailure: false, + contracts: [ + { + ...wagmiContractConfig, + functionName: 'balanceOf', + args: ['0x03A71968491d55603FFe1b11A9e23eF013f75bCF'], + }, + { + ...wagmiContractConfig, + functionName: 'ownerOf', + args: [69n], + }, + { + ...wagmiContractConfig, + functionName: 'totalSupply', + }, + ], + }) + const [balance, ownerOf, totalSupply] = data || [] + + return ( +
+

Read Contract

+
Balance: {balance?.toString()}
+
Owner of Token 69: {ownerOf?.toString()}
+
Total Supply: {totalSupply?.toString()}
+
+ ) +} + +function WriteContract() { + const { data: hash, error, isPending, writeContract } = useWriteContract() + + async function submit(e: FormEvent) { + e.preventDefault() + const formData = new FormData(e.target as HTMLFormElement) + const tokenId = formData.get('tokenId') as string + writeContract({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi: parseAbi(['function mint(uint256 tokenId)']), + functionName: 'mint', + args: [BigInt(tokenId)], + }) + } + + const { isLoading: isConfirming, isSuccess: isConfirmed } = + useWaitForTransactionReceipt({ + hash, + }) + + return ( +
+

Write Contract

+
+ + +
+ {hash &&
Transaction Hash: {hash}
} + {isConfirming && 'Waiting for confirmation...'} + {isConfirmed && 'Transaction confirmed.'} + {error && ( +
Error: {(error as BaseError).shortMessage || error.message}
+ )} +
+ ) +} + +export default App diff --git a/wagmi-project/playgrounds/vite-react/src/contracts.ts b/wagmi-project/playgrounds/vite-react/src/contracts.ts new file mode 100644 index 0000000000..d7d66754a2 --- /dev/null +++ b/wagmi-project/playgrounds/vite-react/src/contracts.ts @@ -0,0 +1,202 @@ +export const wagmiContractConfig = { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi: [ + { inputs: [], stateMutability: 'nonpayable', type: 'constructor' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: 'owner', + type: 'address', + }, + { + indexed: true, + name: 'approved', + type: 'address', + }, + { + indexed: true, + name: 'tokenId', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: 'owner', + type: 'address', + }, + { + indexed: true, + name: 'operator', + type: 'address', + }, + { + indexed: false, + name: 'approved', + type: 'bool', + }, + ], + name: 'ApprovalForAll', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: 'from', + type: 'address', + }, + { indexed: true, name: 'to', type: 'address' }, + { + indexed: true, + name: 'tokenId', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + inputs: [ + { name: 'to', type: 'address' }, + { name: 'tokenId', type: 'uint256' }, + ], + name: 'approve', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ name: 'owner', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ name: 'tokenId', type: 'uint256' }], + name: 'getApproved', + outputs: [{ name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { name: 'owner', type: 'address' }, + { name: 'operator', type: 'address' }, + ], + name: 'isApprovedForAll', + outputs: [{ name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'mint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'tokenId', type: 'uint256' }], + name: 'mint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [{ name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ name: 'tokenId', type: 'uint256' }], + name: 'ownerOf', + outputs: [{ name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { name: 'from', type: 'address' }, + { name: 'to', type: 'address' }, + { name: 'tokenId', type: 'uint256' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { name: 'from', type: 'address' }, + { name: 'to', type: 'address' }, + { name: 'tokenId', type: 'uint256' }, + { name: '_data', type: 'bytes' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { name: 'operator', type: 'address' }, + { name: 'approved', type: 'bool' }, + ], + name: 'setApprovalForAll', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ name: 'interfaceId', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [{ name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ name: 'tokenId', type: 'uint256' }], + name: 'tokenURI', + outputs: [{ name: '', type: 'string' }], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { name: 'from', type: 'address' }, + { name: 'to', type: 'address' }, + { name: 'tokenId', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + ], +} as const diff --git a/wagmi-project/playgrounds/vite-react/src/index.css b/wagmi-project/playgrounds/vite-react/src/index.css new file mode 100644 index 0000000000..0733a7ee6b --- /dev/null +++ b/wagmi-project/playgrounds/vite-react/src/index.css @@ -0,0 +1,21 @@ +:root { + background-color: #181818; + color: rgba(255, 255, 255, 0.87); + color-scheme: light dark; + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + font-synthesis: none; + font-weight: 400; + line-height: 1.5; + text-rendering: optimizeLegibility; + + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-text-size-adjust: 100%; +} + +@media (prefers-color-scheme: light) { + :root { + background-color: #f8f8f8; + color: #181818; + } +} diff --git a/wagmi-project/playgrounds/vite-react/src/main.tsx b/wagmi-project/playgrounds/vite-react/src/main.tsx new file mode 100644 index 0000000000..ad801a958d --- /dev/null +++ b/wagmi-project/playgrounds/vite-react/src/main.tsx @@ -0,0 +1,49 @@ +import { Buffer } from 'buffer' +import { createSyncStoragePersister } from '@tanstack/query-sync-storage-persister' +import { QueryClient } from '@tanstack/react-query' +import { ReactQueryDevtools } from '@tanstack/react-query-devtools' +import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client' +import React from 'react' +import ReactDOM from 'react-dom/client' +import { WagmiProvider, deserialize, serialize } from 'wagmi' + +import './index.css' + +// `@coinbase-wallet/sdk` uses `Buffer` +globalThis.Buffer = Buffer + +import App from './App.tsx' +import { config } from './wagmi.ts' + +const queryClient = new QueryClient({ + defaultOptions: { + queries: { + gcTime: 1_000 * 60 * 60 * 24, // 24 hours + networkMode: 'offlineFirst', + refetchOnWindowFocus: false, + retry: 0, + }, + mutations: { networkMode: 'offlineFirst' }, + }, +}) + +const persister = createSyncStoragePersister({ + key: 'vite-react.cache', + serialize, + storage: window.localStorage, + deserialize, +}) + +ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( + + + + + + + + , +) diff --git a/wagmi-project/playgrounds/vite-react/src/vite-env.d.ts b/wagmi-project/playgrounds/vite-react/src/vite-env.d.ts new file mode 100644 index 0000000000..11f02fe2a0 --- /dev/null +++ b/wagmi-project/playgrounds/vite-react/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/wagmi-project/playgrounds/vite-react/src/wagmi.ts b/wagmi-project/playgrounds/vite-react/src/wagmi.ts new file mode 100644 index 0000000000..94b86f6fd7 --- /dev/null +++ b/wagmi-project/playgrounds/vite-react/src/wagmi.ts @@ -0,0 +1,40 @@ +import { del, get, set } from 'idb-keyval' +import { http, createConfig } from 'wagmi' +import { celo, mainnet, optimism, sepolia } from 'wagmi/chains' +import { coinbaseWallet, metaMask, walletConnect } from 'wagmi/connectors' + +// biome-ignore lint/correctness/noUnusedVariables: +const indexedDBStorage = { + async getItem(name: string) { + return get(name) + }, + async setItem(name: string, value: string) { + await set(name, value) + }, + async removeItem(name: string) { + await del(name) + }, +} + +export const config = createConfig({ + chains: [mainnet, sepolia, optimism, celo], + connectors: [ + walletConnect({ + projectId: import.meta.env.VITE_WC_PROJECT_ID, + }), + coinbaseWallet(), + metaMask(), + ], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + [optimism.id]: http(), + [celo.id]: http(), + }, +}) + +declare module 'wagmi' { + interface Register { + config: typeof config + } +} diff --git a/wagmi-project/playgrounds/vite-react/tsconfig.json b/wagmi-project/playgrounds/vite-react/tsconfig.json new file mode 100644 index 0000000000..2a91e18f44 --- /dev/null +++ b/wagmi-project/playgrounds/vite-react/tsconfig.json @@ -0,0 +1,30 @@ +{ + "compilerOptions": { + "target": "ESNext", + "lib": ["DOM", "DOM.Iterable", "ESNext"], + "module": "ESNext", + "skipLibCheck": true, + + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + + "paths": { + "@wagmi/connectors": ["../../packages/connectors/src/exports"], + "@wagmi/core": ["../../packages/core/src/exports"], + "@wagmi/core/*": ["../../packages/core/src/exports/*"], + "wagmi": ["../../packages/react/src/exports"], + "wagmi/*": ["../../packages/react/src/exports/*"] + } + }, + "include": ["src"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/wagmi-project/playgrounds/vite-react/tsconfig.node.json b/wagmi-project/playgrounds/vite-react/tsconfig.node.json new file mode 100644 index 0000000000..42872c59f5 --- /dev/null +++ b/wagmi-project/playgrounds/vite-react/tsconfig.node.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/wagmi-project/playgrounds/vite-react/vite.config.ts b/wagmi-project/playgrounds/vite-react/vite.config.ts new file mode 100644 index 0000000000..36f7f4e1bc --- /dev/null +++ b/wagmi-project/playgrounds/vite-react/vite.config.ts @@ -0,0 +1,7 @@ +import react from '@vitejs/plugin-react' +import { defineConfig } from 'vite' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [react()], +}) diff --git a/wagmi-project/playgrounds/vite-react/wagmi.config.ts b/wagmi-project/playgrounds/vite-react/wagmi.config.ts new file mode 100644 index 0000000000..d524220b09 --- /dev/null +++ b/wagmi-project/playgrounds/vite-react/wagmi.config.ts @@ -0,0 +1,17 @@ +import { defineConfig } from '@wagmi/cli' +import { foundry, hardhat } from '@wagmi/cli/plugins' + +export default defineConfig({ + out: 'src/generated.ts', + contracts: [], + plugins: [ + foundry({ + namePrefix: 'foundry', + project: '../../packages/cli/src/plugins/__fixtures__/foundry', + }), + hardhat({ + namePrefix: 'hardhat', + project: '../../packages/cli/src/plugins/__fixtures__/hardhat', + }), + ], +}) diff --git a/wagmi-project/playgrounds/vite-vue/.gitignore b/wagmi-project/playgrounds/vite-vue/.gitignore new file mode 100644 index 0000000000..a547bf36d8 --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/wagmi-project/playgrounds/vite-vue/index.html b/wagmi-project/playgrounds/vite-vue/index.html new file mode 100644 index 0000000000..3f59f59114 --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/index.html @@ -0,0 +1,13 @@ + + + + + + + Vite Vue + + +
+ + + diff --git a/wagmi-project/playgrounds/vite-vue/package.json b/wagmi-project/playgrounds/vite-vue/package.json new file mode 100644 index 0000000000..bd4b1938a3 --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/package.json @@ -0,0 +1,22 @@ +{ + "name": "vite-vue", + "private": true, + "type": "module", + "scripts": { + "dev": "vite", + "build": "vue-tsc && vite build", + "preview": "vite preview" + }, + "dependencies": { + "@tanstack/vue-query": ">=5.45.0", + "@wagmi/vue": "workspace:*", + "viem": "2.*", + "vue": ">=3.4.21" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^5.0.4", + "buffer": "^6.0.3", + "vite": "^5.4.19", + "vue-tsc": "^2.0.6" + } +} diff --git a/wagmi-project/playgrounds/vite-vue/public/vite.svg b/wagmi-project/playgrounds/vite-vue/public/vite.svg new file mode 100644 index 0000000000..e7b8dfb1b2 --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/wagmi-project/playgrounds/vite-vue/src/App.vue b/wagmi-project/playgrounds/vite-vue/src/App.vue new file mode 100644 index 0000000000..5a7f194a02 --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/src/App.vue @@ -0,0 +1,29 @@ + + + diff --git a/wagmi-project/playgrounds/vite-vue/src/components/Account.vue b/wagmi-project/playgrounds/vite-vue/src/components/Account.vue new file mode 100644 index 0000000000..33f1491dac --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/src/components/Account.vue @@ -0,0 +1,22 @@ + + + diff --git a/wagmi-project/playgrounds/vite-vue/src/components/Balance.vue b/wagmi-project/playgrounds/vite-vue/src/components/Balance.vue new file mode 100644 index 0000000000..b064d45e9a --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/src/components/Balance.vue @@ -0,0 +1,12 @@ + + + diff --git a/wagmi-project/playgrounds/vite-vue/src/components/BlockNumber.vue b/wagmi-project/playgrounds/vite-vue/src/components/BlockNumber.vue new file mode 100644 index 0000000000..25f8744a71 --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/src/components/BlockNumber.vue @@ -0,0 +1,17 @@ + + + diff --git a/wagmi-project/playgrounds/vite-vue/src/components/Client.vue b/wagmi-project/playgrounds/vite-vue/src/components/Client.vue new file mode 100644 index 0000000000..52e7f12f7b --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/src/components/Client.vue @@ -0,0 +1,14 @@ + + + diff --git a/wagmi-project/playgrounds/vite-vue/src/components/Connect.vue b/wagmi-project/playgrounds/vite-vue/src/components/Connect.vue new file mode 100644 index 0000000000..93320448c0 --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/src/components/Connect.vue @@ -0,0 +1,19 @@ + + + diff --git a/wagmi-project/playgrounds/vite-vue/src/components/Connections.vue b/wagmi-project/playgrounds/vite-vue/src/components/Connections.vue new file mode 100644 index 0000000000..21405f2483 --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/src/components/Connections.vue @@ -0,0 +1,15 @@ + + + diff --git a/wagmi-project/playgrounds/vite-vue/src/components/ConnectorClient.vue b/wagmi-project/playgrounds/vite-vue/src/components/ConnectorClient.vue new file mode 100644 index 0000000000..157156d3ee --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/src/components/ConnectorClient.vue @@ -0,0 +1,14 @@ + + + diff --git a/wagmi-project/playgrounds/vite-vue/src/components/ReadContract.vue b/wagmi-project/playgrounds/vite-vue/src/components/ReadContract.vue new file mode 100644 index 0000000000..2f236ac9ed --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/src/components/ReadContract.vue @@ -0,0 +1,16 @@ + + + diff --git a/wagmi-project/playgrounds/vite-vue/src/components/SendTransaction.vue b/wagmi-project/playgrounds/vite-vue/src/components/SendTransaction.vue new file mode 100644 index 0000000000..8a509b5e5f --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/src/components/SendTransaction.vue @@ -0,0 +1,35 @@ + + + diff --git a/wagmi-project/playgrounds/vite-vue/src/components/SwitchAccount.vue b/wagmi-project/playgrounds/vite-vue/src/components/SwitchAccount.vue new file mode 100644 index 0000000000..bc1814bfa7 --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/src/components/SwitchAccount.vue @@ -0,0 +1,20 @@ + + + diff --git a/wagmi-project/playgrounds/vite-vue/src/components/SwitchChain.vue b/wagmi-project/playgrounds/vite-vue/src/components/SwitchChain.vue new file mode 100644 index 0000000000..b385052049 --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/src/components/SwitchChain.vue @@ -0,0 +1,22 @@ + + + diff --git a/wagmi-project/playgrounds/vite-vue/src/components/WriteContract.vue b/wagmi-project/playgrounds/vite-vue/src/components/WriteContract.vue new file mode 100644 index 0000000000..aa3102b3f1 --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/src/components/WriteContract.vue @@ -0,0 +1,28 @@ + + + diff --git a/wagmi-project/playgrounds/vite-vue/src/contracts.ts b/wagmi-project/playgrounds/vite-vue/src/contracts.ts new file mode 100644 index 0000000000..d7d66754a2 --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/src/contracts.ts @@ -0,0 +1,202 @@ +export const wagmiContractConfig = { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi: [ + { inputs: [], stateMutability: 'nonpayable', type: 'constructor' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: 'owner', + type: 'address', + }, + { + indexed: true, + name: 'approved', + type: 'address', + }, + { + indexed: true, + name: 'tokenId', + type: 'uint256', + }, + ], + name: 'Approval', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: 'owner', + type: 'address', + }, + { + indexed: true, + name: 'operator', + type: 'address', + }, + { + indexed: false, + name: 'approved', + type: 'bool', + }, + ], + name: 'ApprovalForAll', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: 'from', + type: 'address', + }, + { indexed: true, name: 'to', type: 'address' }, + { + indexed: true, + name: 'tokenId', + type: 'uint256', + }, + ], + name: 'Transfer', + type: 'event', + }, + { + inputs: [ + { name: 'to', type: 'address' }, + { name: 'tokenId', type: 'uint256' }, + ], + name: 'approve', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ name: 'owner', type: 'address' }], + name: 'balanceOf', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ name: 'tokenId', type: 'uint256' }], + name: 'getApproved', + outputs: [{ name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { name: 'owner', type: 'address' }, + { name: 'operator', type: 'address' }, + ], + name: 'isApprovedForAll', + outputs: [{ name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'mint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'tokenId', type: 'uint256' }], + name: 'mint', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'name', + outputs: [{ name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ name: 'tokenId', type: 'uint256' }], + name: 'ownerOf', + outputs: [{ name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { name: 'from', type: 'address' }, + { name: 'to', type: 'address' }, + { name: 'tokenId', type: 'uint256' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { name: 'from', type: 'address' }, + { name: 'to', type: 'address' }, + { name: 'tokenId', type: 'uint256' }, + { name: '_data', type: 'bytes' }, + ], + name: 'safeTransferFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { name: 'operator', type: 'address' }, + { name: 'approved', type: 'bool' }, + ], + name: 'setApprovalForAll', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ name: 'interfaceId', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'symbol', + outputs: [{ name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ name: 'tokenId', type: 'uint256' }], + name: 'tokenURI', + outputs: [{ name: '', type: 'string' }], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [], + name: 'totalSupply', + outputs: [{ name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { name: 'from', type: 'address' }, + { name: 'to', type: 'address' }, + { name: 'tokenId', type: 'uint256' }, + ], + name: 'transferFrom', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + ], +} as const diff --git a/wagmi-project/playgrounds/vite-vue/src/main.ts b/wagmi-project/playgrounds/vite-vue/src/main.ts new file mode 100644 index 0000000000..820eed3722 --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/src/main.ts @@ -0,0 +1,17 @@ +import { Buffer } from 'buffer' +import { VueQueryPlugin } from '@tanstack/vue-query' +import { WagmiPlugin } from '@wagmi/vue' +import { createApp } from 'vue' + +// `@coinbase-wallet/sdk` uses `Buffer` +globalThis.Buffer = Buffer + +import App from './App.vue' +import './style.css' +import { config } from './wagmi' + +const app = createApp(App) + +app.use(WagmiPlugin, { config }).use(VueQueryPlugin, {}) + +app.mount('#app') diff --git a/wagmi-project/playgrounds/vite-vue/src/style.css b/wagmi-project/playgrounds/vite-vue/src/style.css new file mode 100644 index 0000000000..0733a7ee6b --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/src/style.css @@ -0,0 +1,21 @@ +:root { + background-color: #181818; + color: rgba(255, 255, 255, 0.87); + color-scheme: light dark; + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + font-synthesis: none; + font-weight: 400; + line-height: 1.5; + text-rendering: optimizeLegibility; + + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-text-size-adjust: 100%; +} + +@media (prefers-color-scheme: light) { + :root { + background-color: #f8f8f8; + color: #181818; + } +} diff --git a/wagmi-project/playgrounds/vite-vue/src/vite-env.d.ts b/wagmi-project/playgrounds/vite-vue/src/vite-env.d.ts new file mode 100644 index 0000000000..11f02fe2a0 --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/wagmi-project/playgrounds/vite-vue/src/wagmi.ts b/wagmi-project/playgrounds/vite-vue/src/wagmi.ts new file mode 100644 index 0000000000..f5b3f286cc --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/src/wagmi.ts @@ -0,0 +1,26 @@ +import { http, createConfig, createStorage } from '@wagmi/vue' +import { mainnet, optimism, sepolia } from '@wagmi/vue/chains' +import { coinbaseWallet, metaMask, walletConnect } from '@wagmi/vue/connectors' + +export const config = createConfig({ + chains: [mainnet, sepolia, optimism], + connectors: [ + walletConnect({ + projectId: import.meta.env.VITE_WC_PROJECT_ID, + }), + coinbaseWallet({ appName: 'Vite Vue Playground', darkMode: true }), + metaMask(), + ], + storage: createStorage({ storage: localStorage, key: 'vite-vue' }), + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + [optimism.id]: http(), + }, +}) + +declare module '@wagmi/vue' { + interface Register { + config: typeof config + } +} diff --git a/wagmi-project/playgrounds/vite-vue/tsconfig.json b/wagmi-project/playgrounds/vite-vue/tsconfig.json new file mode 100644 index 0000000000..18f095cd22 --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "module": "ESNext", + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "skipLibCheck": true, + + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "preserve", + + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/wagmi-project/playgrounds/vite-vue/tsconfig.node.json b/wagmi-project/playgrounds/vite-vue/tsconfig.node.json new file mode 100644 index 0000000000..97ede7ee6f --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/tsconfig.node.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true, + "strict": true + }, + "include": ["vite.config.ts"] +} diff --git a/wagmi-project/playgrounds/vite-vue/vite.config.ts b/wagmi-project/playgrounds/vite-vue/vite.config.ts new file mode 100644 index 0000000000..c3fa62d865 --- /dev/null +++ b/wagmi-project/playgrounds/vite-vue/vite.config.ts @@ -0,0 +1,7 @@ +import vue from '@vitejs/plugin-vue' +import { defineConfig } from 'vite' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [vue()], +}) diff --git a/wagmi-project/pnpm-lock.yaml b/wagmi-project/pnpm-lock.yaml new file mode 100644 index 0000000000..161a4d5905 --- /dev/null +++ b/wagmi-project/pnpm-lock.yaml @@ -0,0 +1,19645 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: false + excludeLinksFromLockfile: false + +catalogs: + default: + '@tanstack/query-core': + specifier: 5.49.1 + version: 5.49.1 + '@tanstack/react-query': + specifier: 5.49.2 + version: 5.49.2 + '@tanstack/vue-query': + specifier: 5.49.1 + version: 5.49.1 + '@testing-library/dom': + specifier: 10.4.0 + version: 10.4.0 + '@testing-library/react': + specifier: 16.0.1 + version: 16.0.1 + '@types/react': + specifier: 18.3.1 + version: 18.3.1 + '@types/react-dom': + specifier: 18.3.0 + version: 18.3.0 + react: + specifier: 18.3.1 + version: 18.3.1 + react-dom: + specifier: 18.3.1 + version: 18.3.1 + vue: + specifier: 3.4.27 + version: 3.4.27 + +importers: + + .: + devDependencies: + '@arethetypeswrong/cli': + specifier: ^0.16.4 + version: 0.16.4 + '@biomejs/biome': + specifier: ^1.9.4 + version: 1.9.4 + '@changesets/changelog-github': + specifier: 0.4.6 + version: 0.4.6(encoding@0.1.13) + '@changesets/cli': + specifier: ^2.27.8 + version: 2.27.8 + '@types/bun': + specifier: ^1.1.10 + version: 1.1.10 + '@vitest/coverage-v8': + specifier: ^2.1.1 + version: 2.1.1(vitest@2.1.9(@types/node@24.0.1)(happy-dom@15.10.2)(msw@2.4.9(typescript@5.8.3))(terser@5.39.2)) + '@wagmi/test': + specifier: workspace:* + version: link:packages/test + bun: + specifier: ^1.1.30 + version: 1.1.30 + happy-dom: + specifier: ^15.10.2 + version: 15.10.2 + knip: + specifier: ^5.30.6 + version: 5.30.6(@types/node@24.0.1)(typescript@5.8.3) + prool: + specifier: ^0.0.23 + version: 0.0.23 + publint: + specifier: ^0.3.0 + version: 0.3.12 + sherif: + specifier: ^1.0.0 + version: 1.0.0 + simple-git-hooks: + specifier: ^2.11.1 + version: 2.11.1 + typescript: + specifier: 5.8.3 + version: 5.8.3 + viem: + specifier: 2.29.2 + version: 2.29.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@6.0.5)(zod@3.25.20) + vitest: + specifier: ^2.1.9 + version: 2.1.9(@types/node@24.0.1)(happy-dom@15.10.2)(msw@2.4.9(typescript@5.8.3))(terser@5.39.2) + + packages/cli: + dependencies: + abitype: + specifier: ^1.0.4 + version: 1.0.4(typescript@5.8.3)(zod@3.25.20) + bundle-require: + specifier: ^5.1.0 + version: 5.1.0(esbuild@0.25.5) + cac: + specifier: ^6.7.14 + version: 6.7.14 + change-case: + specifier: ^5.4.4 + version: 5.4.4 + chokidar: + specifier: 4.0.3 + version: 4.0.3 + dedent: + specifier: ^1.5.3 + version: 1.6.0 + dotenv: + specifier: ^16.3.1 + version: 16.3.1 + dotenv-expand: + specifier: ^10.0.0 + version: 10.0.0 + esbuild: + specifier: ~0.25.5 + version: 0.25.5 + escalade: + specifier: 3.2.0 + version: 3.2.0 + fdir: + specifier: ^6.1.1 + version: 6.1.1(picomatch@4.0.2) + nanospinner: + specifier: 1.2.2 + version: 1.2.2 + pathe: + specifier: ^2.0.3 + version: 2.0.3 + picocolors: + specifier: ^1.0.0 + version: 1.0.0 + picomatch: + specifier: ^4.0.2 + version: 4.0.2 + prettier: + specifier: ^3.0.3 + version: 3.0.3 + viem: + specifier: 2.x + version: 2.10.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@6.0.5)(zod@3.25.20) + zod: + specifier: ^3.22.3 + version: 3.25.20 + devDependencies: + '@types/dedent': + specifier: ^0.7.2 + version: 0.7.2 + '@types/node': + specifier: ^22.14.0 + version: 22.15.31 + fixturez: + specifier: ^1.1.0 + version: 1.1.0 + msw: + specifier: ^2.4.9 + version: 2.4.9(typescript@5.8.3) + + packages/cli/src/plugins/__fixtures__/hardhat: + devDependencies: + hardhat: + specifier: ^2.22.3 + version: 2.22.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) + + packages/connectors: + dependencies: + '@coinbase/wallet-sdk': + specifier: 4.3.0 + version: 4.3.0 + '@metamask/sdk': + specifier: 0.32.1 + version: 0.32.1(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@safe-global/safe-apps-provider': + specifier: 0.18.6 + version: 0.18.6(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@safe-global/safe-apps-sdk': + specifier: 9.1.0 + version: 9.1.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@walletconnect/ethereum-provider': + specifier: 2.20.2 + version: 2.20.2(@types/react@18.3.1)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + cbw-sdk: + specifier: npm:@coinbase/wallet-sdk@3.9.3 + version: '@coinbase/wallet-sdk@3.9.3' + devDependencies: + '@wagmi/core': + specifier: workspace:* + version: link:../core + msw: + specifier: ^2.4.9 + version: 2.4.9(typescript@5.8.3) + + packages/core: + dependencies: + eventemitter3: + specifier: 5.0.1 + version: 5.0.1 + mipd: + specifier: 0.0.7 + version: 0.0.7(typescript@5.8.3) + zustand: + specifier: 5.0.0 + version: 5.0.0(@types/react@18.3.1)(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)) + devDependencies: + '@tanstack/query-core': + specifier: 'catalog:' + version: 5.49.1 + + packages/create-wagmi: + dependencies: + cac: + specifier: ^6.7.14 + version: 6.7.14 + cross-spawn: + specifier: ^7.0.5 + version: 7.0.6 + picocolors: + specifier: ^1.0.0 + version: 1.0.0 + prompts: + specifier: ^2.4.2 + version: 2.4.2 + devDependencies: + '@types/cross-spawn': + specifier: ^6.0.6 + version: 6.0.6 + '@types/node': + specifier: ^20.12.10 + version: 20.12.10 + '@types/prompts': + specifier: ^2.4.9 + version: 2.4.9 + + packages/react: + dependencies: + '@wagmi/connectors': + specifier: workspace:* + version: link:../connectors + '@wagmi/core': + specifier: workspace:* + version: link:../core + use-sync-external-store: + specifier: 1.4.0 + version: 1.4.0(react@18.3.1) + devDependencies: + '@tanstack/react-query': + specifier: 'catalog:' + version: 5.49.2(react@18.3.1) + '@testing-library/dom': + specifier: 'catalog:' + version: 10.4.0 + '@testing-library/react': + specifier: 'catalog:' + version: 16.0.1(@testing-library/dom@10.4.0)(@types/react-dom@18.3.0)(@types/react@18.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@types/react': + specifier: 'catalog:' + version: 18.3.1 + '@types/react-dom': + specifier: 'catalog:' + version: 18.3.0 + '@types/use-sync-external-store': + specifier: ^0.0.6 + version: 0.0.6 + react: + specifier: 'catalog:' + version: 18.3.1 + react-dom: + specifier: 'catalog:' + version: 18.3.1(react@18.3.1) + + packages/register-tests/react: + dependencies: + '@tanstack/react-query': + specifier: 'catalog:' + version: 5.49.2(react@18.3.1) + react: + specifier: 'catalog:' + version: 18.3.1 + wagmi: + specifier: workspace:* + version: link:../../react + devDependencies: + '@types/react': + specifier: 'catalog:' + version: 18.3.1 + + packages/register-tests/vue: + dependencies: + '@tanstack/vue-query': + specifier: 'catalog:' + version: 5.49.1(vue@3.4.27(typescript@5.8.3)) + '@wagmi/vue': + specifier: workspace:* + version: link:../../vue + vue: + specifier: 'catalog:' + version: 3.4.27(typescript@5.8.3) + + packages/test: + devDependencies: + '@tanstack/react-query': + specifier: 'catalog:' + version: 5.49.2(react@18.3.1) + '@tanstack/vue-query': + specifier: 'catalog:' + version: 5.49.1(vue@3.4.27(typescript@5.8.3)) + '@testing-library/dom': + specifier: 'catalog:' + version: 10.4.0 + '@testing-library/react': + specifier: 'catalog:' + version: 16.0.1(@testing-library/dom@10.4.0)(@types/react-dom@18.3.0)(@types/react@18.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@types/react': + specifier: 'catalog:' + version: 18.3.1 + '@types/react-dom': + specifier: 'catalog:' + version: 18.3.0 + '@wagmi/core': + specifier: workspace:* + version: link:../core + '@wagmi/vue': + specifier: workspace:* + version: link:../vue + react: + specifier: 'catalog:' + version: 18.3.1 + react-dom: + specifier: 'catalog:' + version: 18.3.1(react@18.3.1) + vue: + specifier: 'catalog:' + version: 3.4.27(typescript@5.8.3) + wagmi: + specifier: workspace:* + version: link:../react + + packages/vue: + dependencies: + '@wagmi/connectors': + specifier: workspace:* + version: link:../connectors + '@wagmi/core': + specifier: workspace:* + version: link:../core + devDependencies: + '@nuxt/schema': + specifier: ^3.11.2 + version: 3.11.2(rollup@4.41.0) + '@tanstack/vue-query': + specifier: 'catalog:' + version: 5.49.1(vue@3.4.27(typescript@5.8.3)) + '@vue/test-utils': + specifier: ^2.4.6 + version: 2.4.6 + nuxt: + specifier: ^3.16.0 + version: 3.16.0(@biomejs/biome@1.9.4)(@parcel/watcher@2.5.1)(@types/node@24.0.1)(bufferutil@4.0.9)(db0@0.3.2)(encoding@0.1.13)(idb-keyval@6.2.1)(ioredis@5.6.1)(magicast@0.3.5)(rollup@4.41.0)(terser@5.39.2)(typescript@5.8.3)(utf-8-validate@6.0.5)(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0))(yaml@2.8.0) + vue: + specifier: 'catalog:' + version: 3.4.27(typescript@5.8.3) + + playgrounds/next: + dependencies: + '@next/bundle-analyzer': + specifier: ^15.2.4 + version: 15.3.3(bufferutil@4.0.8)(utf-8-validate@6.0.5) + '@tanstack/react-query': + specifier: '>=5.45.1' + version: 5.49.2(react@18.3.1) + next: + specifier: 15.3.3 + version: 15.3.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: + specifier: '>=18.3.1' + version: 18.3.1 + react-dom: + specifier: '>=18.3.1' + version: 18.3.1(react@18.3.1) + viem: + specifier: 2.* + version: 2.10.8(bufferutil@4.0.8)(typescript@5.8.3)(utf-8-validate@6.0.5)(zod@3.25.20) + wagmi: + specifier: workspace:* + version: link:../../packages/react + devDependencies: + '@types/node': + specifier: ^22.14.1 + version: 22.15.31 + '@types/react': + specifier: '>=18.3.1' + version: 18.3.1 + '@types/react-dom': + specifier: '>=18.3.0' + version: 18.3.0 + bufferutil: + specifier: ^4.0.8 + version: 4.0.8 + encoding: + specifier: ^0.1.13 + version: 0.1.13 + lokijs: + specifier: ^1.5.12 + version: 1.5.12 + pino-pretty: + specifier: ^13.0.0 + version: 13.0.0 + supports-color: + specifier: ^9.4.0 + version: 9.4.0 + utf-8-validate: + specifier: ^6.0.5 + version: 6.0.5 + + playgrounds/nuxt: + dependencies: + '@tanstack/vue-query': + specifier: '>=5.45.0' + version: 5.49.1(vue@3.4.27(typescript@5.8.3)) + '@wagmi/vue': + specifier: workspace:* + version: link:../../packages/vue + nuxt: + specifier: ^3.16.0 + version: 3.16.0(@biomejs/biome@1.9.4)(@parcel/watcher@2.5.1)(@types/node@24.0.1)(bufferutil@4.0.9)(db0@0.3.2)(encoding@0.1.13)(idb-keyval@6.2.1)(ioredis@5.6.1)(magicast@0.3.5)(rollup@4.41.0)(terser@5.39.2)(typescript@5.8.3)(utf-8-validate@6.0.5)(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0))(yaml@2.8.0) + viem: + specifier: 2.* + version: 2.10.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@6.0.5)(zod@3.25.20) + vue: + specifier: '>=3.4.21' + version: 3.4.27(typescript@5.8.3) + vue-router: + specifier: ^4.3.2 + version: 4.3.2(vue@3.4.27(typescript@5.8.3)) + + playgrounds/vite-core: + dependencies: + '@wagmi/connectors': + specifier: workspace:* + version: link:../../packages/connectors + '@wagmi/core': + specifier: workspace:* + version: link:../../packages/core + react: + specifier: '>=18.3.1' + version: 18.3.1 + react-dom: + specifier: '>=18.3.1' + version: 18.3.1(react@18.3.1) + viem: + specifier: 2.* + version: 2.10.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@6.0.5)(zod@3.25.20) + devDependencies: + '@types/react': + specifier: '>=18.3.1' + version: 18.3.1 + '@types/react-dom': + specifier: '>=18.3.0' + version: 18.3.0 + '@vitejs/plugin-react': + specifier: ^4.2.1 + version: 4.2.1(vite@5.4.19(@types/node@24.0.1)(terser@5.39.2)) + buffer: + specifier: ^6.0.3 + version: 6.0.3 + vite: + specifier: ^5.4.19 + version: 5.4.19(@types/node@24.0.1)(terser@5.39.2) + + playgrounds/vite-react: + dependencies: + '@tanstack/query-sync-storage-persister': + specifier: 5.0.5 + version: 5.0.5 + '@tanstack/react-query': + specifier: '>=5.45.1' + version: 5.49.2(react@18.3.1) + '@tanstack/react-query-persist-client': + specifier: 5.0.5 + version: 5.0.5(@tanstack/react-query@5.49.2(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + idb-keyval: + specifier: ^6.2.1 + version: 6.2.1 + react: + specifier: '>=18.3.1' + version: 18.3.1 + react-dom: + specifier: '>=18.3.1' + version: 18.3.1(react@18.3.1) + viem: + specifier: 2.* + version: 2.10.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@6.0.5)(zod@3.25.20) + wagmi: + specifier: workspace:* + version: link:../../packages/react + devDependencies: + '@tanstack/react-query-devtools': + specifier: 5.0.5 + version: 5.0.5(@tanstack/react-query@5.49.2(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@types/react': + specifier: '>=18.3.1' + version: 18.3.1 + '@types/react-dom': + specifier: '>=18.3.0' + version: 18.3.0 + '@vitejs/plugin-react': + specifier: ^4.2.1 + version: 4.2.1(vite@5.4.19(@types/node@24.0.1)(terser@5.39.2)) + '@wagmi/cli': + specifier: workspace:* + version: link:../../packages/cli + buffer: + specifier: ^6.0.3 + version: 6.0.3 + vite: + specifier: ^5.4.19 + version: 5.4.19(@types/node@24.0.1)(terser@5.39.2) + + playgrounds/vite-vue: + dependencies: + '@tanstack/vue-query': + specifier: '>=5.45.0' + version: 5.49.1(vue@3.4.27(typescript@5.8.3)) + '@wagmi/vue': + specifier: workspace:* + version: link:../../packages/vue + viem: + specifier: 2.* + version: 2.10.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@6.0.5)(zod@3.25.20) + vue: + specifier: '>=3.4.21' + version: 3.4.27(typescript@5.8.3) + devDependencies: + '@vitejs/plugin-vue': + specifier: ^5.0.4 + version: 5.0.4(vite@5.4.19(@types/node@24.0.1)(terser@5.39.2))(vue@3.4.27(typescript@5.8.3)) + buffer: + specifier: ^6.0.3 + version: 6.0.3 + vite: + specifier: ^5.4.19 + version: 5.4.19(@types/node@24.0.1)(terser@5.39.2) + vue-tsc: + specifier: ^2.0.6 + version: 2.0.16(typescript@5.8.3) + + site: + devDependencies: + '@shikijs/vitepress-twoslash': + specifier: 1.22.2 + version: 1.22.2(@nuxt/kit@3.17.4(magicast@0.3.5))(typescript@5.8.3) + '@tanstack/query-core': + specifier: 'catalog:' + version: 5.49.1 + '@tanstack/react-query': + specifier: 'catalog:' + version: 5.49.2(react@18.3.1) + '@tanstack/vue-query': + specifier: 'catalog:' + version: 5.49.1(vue@3.4.27(typescript@5.8.3)) + '@types/react': + specifier: 'catalog:' + version: 18.3.1 + '@wagmi/connectors': + specifier: workspace:* + version: link:../packages/connectors + '@wagmi/core': + specifier: workspace:* + version: link:../packages/core + '@wagmi/vue': + specifier: workspace:* + version: link:../packages/vue + abitype: + specifier: '*' + version: 1.0.2(typescript@5.8.3)(zod@3.25.20) + nuxt: + specifier: ^3.16.0 + version: 3.16.0(@biomejs/biome@1.9.4)(@parcel/watcher@2.5.1)(@types/node@24.0.1)(bufferutil@4.0.9)(db0@0.3.2)(encoding@0.1.13)(idb-keyval@6.2.1)(ioredis@5.6.1)(magicast@0.3.5)(rollup@4.41.0)(terser@5.39.2)(typescript@5.8.3)(utf-8-validate@6.0.5)(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0))(yaml@2.8.0) + react: + specifier: 'catalog:' + version: 18.3.1 + unocss: + specifier: ^0.59.4 + version: 0.59.4(rollup@4.41.0) + viem: + specifier: 2.* + version: 2.10.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@6.0.5)(zod@3.25.20) + vitepress: + specifier: 1.5.0 + version: 1.5.0(@algolia/client-search@5.12.0)(@types/node@24.0.1)(@types/react@18.3.1)(change-case@5.4.4)(fuse.js@7.1.0)(idb-keyval@6.2.1)(jwt-decode@4.0.0)(postcss@8.5.5)(qrcode@1.5.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(terser@5.39.2)(typescript@5.8.3) + vue: + specifier: 'catalog:' + version: 3.4.27(typescript@5.8.3) + wagmi: + specifier: workspace:* + version: link:../packages/react + +packages: + + '@adraffy/ens-normalize@1.10.0': + resolution: {integrity: sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==} + + '@adraffy/ens-normalize@1.11.0': + resolution: {integrity: sha512-/3DDPKHqqIqxUULp8yP4zODUY1i+2xvVWsv8A79xGWdCAG+8sb0hRh0Rk2QyOJUnnbyPUAZYcpBuRe3nS2OIUg==} + + '@algolia/autocomplete-core@1.9.3': + resolution: {integrity: sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==} + + '@algolia/autocomplete-plugin-algolia-insights@1.9.3': + resolution: {integrity: sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==} + peerDependencies: + search-insights: '>= 1 < 3' + + '@algolia/autocomplete-preset-algolia@1.17.6': + resolution: {integrity: sha512-Cvg5JENdSCMuClwhJ1ON1/jSuojaYMiUW2KePm18IkdCzPJj/NXojaOxw58RFtQFpJgfVW8h2E8mEoDtLlMdeA==} + peerDependencies: + '@algolia/client-search': '>= 4.9.1 < 6' + algoliasearch: '>= 4.9.1 < 6' + + '@algolia/autocomplete-shared@1.17.6': + resolution: {integrity: sha512-aq/3V9E00Tw2GC/PqgyPGXtqJUlVc17v4cn1EUhSc+O/4zd04Uwb3UmPm8KDaYQQOrkt1lwvCj2vG2wRE5IKhw==} + peerDependencies: + '@algolia/client-search': '>= 4.9.1 < 6' + algoliasearch: '>= 4.9.1 < 6' + + '@algolia/autocomplete-shared@1.9.3': + resolution: {integrity: sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==} + peerDependencies: + '@algolia/client-search': '>= 4.9.1 < 6' + algoliasearch: '>= 4.9.1 < 6' + + '@algolia/client-abtesting@5.12.0': + resolution: {integrity: sha512-hx4eVydkm3yrFCFxmcBtSzI/ykt0cZ6sDWch+v3JTgKpD2WtosMJU3Upv1AjQ4B6COSHCOWEX3vfFxW6OoH6aA==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-analytics@5.12.0': + resolution: {integrity: sha512-EpTsSv6IW8maCfXCDIptgT7+mQJj7pImEkcNUnxR8yUKAHzTogTXv9yGm2WXOZFVuwstd2i0sImhQ1Vz8RH/hA==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-common@5.12.0': + resolution: {integrity: sha512-od3WmO8qxyfNhKc+K3D17tvun3IMs/xMNmxCG9MiElAkYVbPPTRUYMkRneCpmJyQI0hNx2/EA4kZgzVfQjO86Q==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-insights@5.12.0': + resolution: {integrity: sha512-8alajmsYUd+7vfX5lpRNdxqv3Xx9clIHLUItyQK0Z6gwGMbVEFe6YYhgDtwslMAP0y6b0WeJEIZJMLgT7VYpRw==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-personalization@5.12.0': + resolution: {integrity: sha512-bUV9HtfkTBgpoVhxFrMkmVPG03ZN1Rtn51kiaEtukucdk3ggjR9Qu1YUfRSU2lFgxr9qJc8lTxwfvhjCeJRcqw==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-query-suggestions@5.12.0': + resolution: {integrity: sha512-Q5CszzGWfxbIDs9DJ/QJsL7bP6h+lJMg27KxieEnI9KGCu0Jt5iFA3GkREkgRZxRdzlHbZKkrIzhtHVbSHw/rg==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-search@5.12.0': + resolution: {integrity: sha512-R3qzEytgVLHOGNri+bpta6NtTt7YtkvUe/QBcAmMDjW4Jk1P0eBYIPfvnzIPbINRsLxIq9fZs9uAYBgsrts4Zg==} + engines: {node: '>= 14.0.0'} + + '@algolia/ingestion@1.12.0': + resolution: {integrity: sha512-zpHo6qhR22tL8FsdSI4DvEraPDi/019HmMrCFB/TUX98yzh5ooAU7sNW0qPL1I7+S++VbBmNzJOEU9VI8tEC8A==} + engines: {node: '>= 14.0.0'} + + '@algolia/monitoring@1.12.0': + resolution: {integrity: sha512-i2AJZED/zf4uhxezAJUhMKoL5QoepCBp2ynOYol0N76+TSoohaMADdPnWCqOULF4RzOwrG8wWynAwBlXsAI1RQ==} + engines: {node: '>= 14.0.0'} + + '@algolia/recommend@5.12.0': + resolution: {integrity: sha512-0jmZyKvYnB/Bj5c7WKsKedOUjnr0UtXm0LVFUdQrxXfqOqvWv9n6Vpr65UjdYG4Q49kRQxhlwtal9WJYrYymXg==} + engines: {node: '>= 14.0.0'} + + '@algolia/requester-browser-xhr@5.12.0': + resolution: {integrity: sha512-KxwleraFuVoEGCoeW6Y1RAEbgBMS7SavqeyzWdtkJc6mXeCOJXn1iZitb8Tyn2FcpMNUKlSm0adrUTt7G47+Ow==} + engines: {node: '>= 14.0.0'} + + '@algolia/requester-fetch@5.12.0': + resolution: {integrity: sha512-FuDZXUGU1pAg2HCnrt8+q1VGHKChV/LhvjvZlLOT7e56GJie6p+EuLu4/hMKPOVuQQ8XXtrTHKIU3Lw+7O5/bQ==} + engines: {node: '>= 14.0.0'} + + '@algolia/requester-node-http@5.12.0': + resolution: {integrity: sha512-ncDDY7CxZhMs6LIoPl+vHFQceIBhYPY5EfuGF1V7beO0U38xfsCYEyutEFB2kRzf4D9Gqppn3iWX71sNtrKcuw==} + engines: {node: '>= 14.0.0'} + + '@ampproject/remapping@2.2.1': + resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} + engines: {node: '>=6.0.0'} + + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + + '@andrewbranch/untar.js@1.0.3': + resolution: {integrity: sha512-Jh15/qVmrLGhkKJBdXlK1+9tY4lZruYjsgkDFj08ZmDiWVBLJcqkok7Z0/R0In+i1rScBpJlSvrTS2Lm41Pbnw==} + + '@antfu/install-pkg@0.1.1': + resolution: {integrity: sha512-LyB/8+bSfa0DFGC06zpCEfs89/XoWZwws5ygEa5D+Xsm3OfI+aXQ86VgVG7Acyef+rSZ5HE7J8rrxzrQeM3PjQ==} + + '@antfu/utils@0.7.7': + resolution: {integrity: sha512-gFPqTG7otEJ8uP6wrhDv6mqwGWYZKNvAcCq6u9hOj0c+IKCEsY4L1oC9trPq2SaWIzAfHvqfBDxF591JkMf+kg==} + + '@arethetypeswrong/cli@0.16.4': + resolution: {integrity: sha512-qMmdVlJon5FtA+ahn0c1oAVNxiq4xW5lqFiTZ21XHIeVwAVIQ+uRz4UEivqRMsjVV1grzRgJSKqaOrq1MvlVyQ==} + engines: {node: '>=18'} + hasBin: true + + '@arethetypeswrong/core@0.16.4': + resolution: {integrity: sha512-RI3HXgSuKTfcBf1hSEg1P9/cOvmI0flsMm6/QL3L3wju4AlHDqd55JFPfXs4pzgEAgy5L9pul4/HPPz99x2GvA==} + engines: {node: '>=18'} + + '@babel/code-frame@7.24.2': + resolution: {integrity: sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==} + engines: {node: '>=6.9.0'} + + '@babel/code-frame@7.27.1': + resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.24.4': + resolution: {integrity: sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.27.2': + resolution: {integrity: sha512-TUtMJYRPyUb/9aU8f3K0mjmjf6M9N5Woshn2CS6nqJSeJtTtQcpLUXjGt9vbF8ZGff0El99sWkLgzwW3VXnxZQ==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.24.5': + resolution: {integrity: sha512-tVQRucExLQ02Boi4vdPp49svNGcfL2GhdTCT9aldhXgCJVAI21EtRfBettiuLUwce/7r6bFdgs6JFkcdTiFttA==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.27.1': + resolution: {integrity: sha512-IaaGWsQqfsQWVLqMn9OB92MNN7zukfVA4s7KKAI0KfrrDsZ0yhi5uV4baBuLuN7n3vsZpwP8asPPcVwApxvjBQ==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.24.5': + resolution: {integrity: sha512-x32i4hEXvr+iI0NEoEfDKzlemF8AmtOP8CcrRaEcpzysWuoEb1KknpcvMsHKPONoKZiDuItklgWhB18xEhr9PA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.27.1': + resolution: {integrity: sha512-UnJfnIpc/+JO0/+KRVQNGU+y5taA5vCbwN8+azkX6beii/ZF+enZJSOKo11ZSzGJjlNfJHfQtmQT8H+9TXPG2w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-annotate-as-pure@7.22.5': + resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-annotate-as-pure@7.27.1': + resolution: {integrity: sha512-WnuuDILl9oOBbKnb4L+DyODx7iC47XfzmNCpTttFsSp6hTG7XZxu60+4IO+2/hPfcGOoKbFiwoI/+zwARbNQow==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.23.6': + resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.27.2': + resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-create-class-features-plugin@7.24.5': + resolution: {integrity: sha512-uRc4Cv8UQWnE4NXlYTIIdM7wfFkOqlFztcC/gVXDKohKoVB3OyonfelUBaJzSwpBntZ2KYGF/9S7asCHsXwW6g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-create-class-features-plugin@7.27.1': + resolution: {integrity: sha512-QwGAmuvM17btKU5VqXfb+Giw4JcN0hjuufz3DYnpeVDvZLAObloM77bhMXiqry3Iio+Ai4phVRDwl6WU10+r5A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-environment-visitor@7.22.20': + resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-function-name@7.23.0': + resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-hoist-variables@7.22.5': + resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-member-expression-to-functions@7.24.5': + resolution: {integrity: sha512-4owRteeihKWKamtqg4JmWSsEZU445xpFRXPEwp44HbgbxdWlUV1b4Agg4lkA806Lil5XM/e+FJyS0vj5T6vmcA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-member-expression-to-functions@7.27.1': + resolution: {integrity: sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.24.3': + resolution: {integrity: sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.27.1': + resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.24.5': + resolution: {integrity: sha512-9GxeY8c2d2mdQUP1Dye0ks3VDyIMS98kt/llQ2nUId8IsWqTF0l1LkSX0/uP7l7MCDrzXS009Hyhe2gzTiGW8A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-module-transforms@7.27.1': + resolution: {integrity: sha512-9yHn519/8KvTU5BjTVEEeIM3w9/2yXNKoD82JifINImhpKkARMJKPP59kLo+BafpdN5zgNeIcS4jsGDmd3l58g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-optimise-call-expression@7.22.5': + resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-optimise-call-expression@7.27.1': + resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-plugin-utils@7.24.5': + resolution: {integrity: sha512-xjNLDopRzW2o6ba0gKbkZq5YWEBaK3PCyTOY1K2P/O07LGMhMqlMXPxwN4S5/RhWuCobT8z0jrlKGlYmeR1OhQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-plugin-utils@7.27.1': + resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-replace-supers@7.24.1': + resolution: {integrity: sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-replace-supers@7.27.1': + resolution: {integrity: sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-simple-access@7.24.5': + resolution: {integrity: sha512-uH3Hmf5q5n7n8mz7arjUlDOCbttY/DW4DYhE6FUsjKJ/oYC1kQQUvwEQWxRwUpX9qQKRXeqLwWxrqilMrf32sQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-split-export-declaration@7.24.5': + resolution: {integrity: sha512-5CHncttXohrHk8GWOFCcCl4oRD9fKosWlIRgWm4ql9VYioKm52Mk2xsmoohvm7f3JoiLSM5ZgJuRaf5QZZYd3Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.24.1': + resolution: {integrity: sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.25.9': + resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.24.5': + resolution: {integrity: sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.25.9': + resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.27.1': + resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.23.5': + resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.24.5': + resolution: {integrity: sha512-CiQmBMMpMQHwM5m01YnrM6imUG1ebgYJ+fAIW4FZe6m4qHTPaRHti+R8cggAwkdz4oXhtO4/K9JWlh+8hIfR2Q==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.27.1': + resolution: {integrity: sha512-FCvFTm0sWV8Fxhpp2McP5/W53GPllQ9QeQ7SiqGWjMf/LVG07lFa5+pgK05IRhVwtvafT22KF+ZSnM9I545CvQ==} + engines: {node: '>=6.9.0'} + + '@babel/highlight@7.24.5': + resolution: {integrity: sha512-8lLmua6AVh/8SLJRRVD6V8p73Hir9w5mJrhE+IPpILG31KKlI9iz5zmBYKcWPS59qSfgP9RaSBQSHHE81WKuEw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.24.5': + resolution: {integrity: sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/parser@7.26.2': + resolution: {integrity: sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/parser@7.27.2': + resolution: {integrity: sha512-QYLs8299NA7WM/bZAdp+CviYYkVoYXlDW2rzliy3chxd1PQjej7JORuMJDJXJUb9g0TT+B99EwaVLKmX+sPXWw==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-syntax-jsx@7.24.1': + resolution: {integrity: sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-jsx@7.27.1': + resolution: {integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.24.1': + resolution: {integrity: sha512-Yhnmvy5HZEnHUty6i++gcfH1/l68AHnItFHnaCv6hn9dNh0hQvvQJsxpi4BMBFN5DLeHBuucT/0DgzXif/OyRw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.27.1': + resolution: {integrity: sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-commonjs@7.24.1': + resolution: {integrity: sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-self@7.24.5': + resolution: {integrity: sha512-RtCJoUO2oYrYwFPtR1/jkoBEcFuI1ae9a9IMxeyAVa3a1Ap4AnxmyIKG2b2FaJKqkidw/0cxRbWN+HOs6ZWd1w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-source@7.24.1': + resolution: {integrity: sha512-1v202n7aUq4uXAieRTKcwPzNyphlCuqHHDcdSNc+vdhoTEZcFMh+L5yZuCmGaIO7bs1nJUNfHB89TZyoL48xNA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typescript@7.24.5': + resolution: {integrity: sha512-E0VWu/hk83BIFUWnsKZ4D81KXjN5L3MobvevOHErASk9IPwKHOkTgvqzvNo1yP/ePJWqqK2SpUR5z+KQbl6NVw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typescript@7.27.1': + resolution: {integrity: sha512-Q5sT5+O4QUebHdbwKedFBEwRLb02zJ7r4A5Gg2hUoLuU3FjdMcyqcywqUrLCaDsFCxzokf7u9kuy7qz51YUuAg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/preset-typescript@7.24.1': + resolution: {integrity: sha512-1DBaMmRDpuYQBPWD8Pf/WEwCrtgRHxsZnP4mIy9G/X+hFfbI47Q2G4t1Paakld84+qsk2fSsUPMKg71jkoOOaQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/runtime@7.26.0': + resolution: {integrity: sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==} + engines: {node: '>=6.9.0'} + + '@babel/runtime@7.27.6': + resolution: {integrity: sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==} + engines: {node: '>=6.9.0'} + + '@babel/standalone@7.24.5': + resolution: {integrity: sha512-Sl8oN9bGfRlNUA2jzfzoHEZxFBDliBlwi5mPVCAWKSlBNkXXJOHpu7SDOqjF6mRoTa6GNX/1kAWG3Tr+YQ3N7A==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.24.0': + resolution: {integrity: sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.27.2': + resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.24.5': + resolution: {integrity: sha512-7aaBLeDQ4zYcUFDUD41lJc1fG8+5IU9DaNSJAgal866FGvmD5EbWQgnEC6kO1gGLsX0esNkfnJSndbTXA3r7UA==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.27.1': + resolution: {integrity: sha512-ZCYtZciz1IWJB4U61UPu4KEaqyfj+r5T1Q5mqPo+IBpcG9kHv30Z0aD8LXPgC1trYa6rK0orRyAhqUgk4MjmEg==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.24.5': + resolution: {integrity: sha512-6mQNsaLeXTw0nxYUYu+NSa4Hx4BlF1x1x8/PMFbiR+GBSr+2DkECc69b8hgy2frEodNcvPffeH8YfWd3LI6jhQ==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.26.0': + resolution: {integrity: sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.27.1': + resolution: {integrity: sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q==} + engines: {node: '>=6.9.0'} + + '@bcoe/v8-coverage@0.2.3': + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + + '@biomejs/biome@1.9.4': + resolution: {integrity: sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog==} + engines: {node: '>=14.21.3'} + hasBin: true + + '@biomejs/cli-darwin-arm64@1.9.4': + resolution: {integrity: sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [darwin] + + '@biomejs/cli-darwin-x64@1.9.4': + resolution: {integrity: sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [darwin] + + '@biomejs/cli-linux-arm64-musl@1.9.4': + resolution: {integrity: sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-arm64@1.9.4': + resolution: {integrity: sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-x64-musl@1.9.4': + resolution: {integrity: sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-linux-x64@1.9.4': + resolution: {integrity: sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-win32-arm64@1.9.4': + resolution: {integrity: sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [win32] + + '@biomejs/cli-win32-x64@1.9.4': + resolution: {integrity: sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [win32] + + '@bundled-es-modules/cookie@2.0.0': + resolution: {integrity: sha512-Or6YHg/kamKHpxULAdSqhGqnWFneIXu1NKvvfBBzKGwpVsYuFIQ5aBPHDnnoR3ghW1nvSkALd+EF9iMtY7Vjxw==} + + '@bundled-es-modules/statuses@1.0.1': + resolution: {integrity: sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==} + + '@bundled-es-modules/tough-cookie@0.1.6': + resolution: {integrity: sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw==} + + '@changesets/apply-release-plan@7.0.5': + resolution: {integrity: sha512-1cWCk+ZshEkSVEZrm2fSj1Gz8sYvxgUL4Q78+1ZZqeqfuevPTPk033/yUZ3df8BKMohkqqHfzj0HOOrG0KtXTw==} + + '@changesets/assemble-release-plan@6.0.4': + resolution: {integrity: sha512-nqICnvmrwWj4w2x0fOhVj2QEGdlUuwVAwESrUo5HLzWMI1rE5SWfsr9ln+rDqWB6RQ2ZyaMZHUcU7/IRaUJS+Q==} + + '@changesets/changelog-git@0.2.0': + resolution: {integrity: sha512-bHOx97iFI4OClIT35Lok3sJAwM31VbUM++gnMBV16fdbtBhgYu4dxsphBF/0AZZsyAHMrnM0yFcj5gZM1py6uQ==} + + '@changesets/changelog-github@0.4.6': + resolution: {integrity: sha512-ahR/+o3OPodzfG9kucEMU/tEtBgwy6QoJiWi1sDBPme8n3WjT6pBlbhqNYpWAJKilomwfjBGY0MTUTs6r9d1RQ==} + + '@changesets/cli@2.27.8': + resolution: {integrity: sha512-gZNyh+LdSsI82wBSHLQ3QN5J30P4uHKJ4fXgoGwQxfXwYFTJzDdvIJasZn8rYQtmKhyQuiBj4SSnLuKlxKWq4w==} + hasBin: true + + '@changesets/config@3.0.3': + resolution: {integrity: sha512-vqgQZMyIcuIpw9nqFIpTSNyc/wgm/Lu1zKN5vECy74u95Qx/Wa9g27HdgO4NkVAaq+BGA8wUc/qvbvVNs93n6A==} + + '@changesets/errors@0.2.0': + resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==} + + '@changesets/get-dependents-graph@2.1.2': + resolution: {integrity: sha512-sgcHRkiBY9i4zWYBwlVyAjEM9sAzs4wYVwJUdnbDLnVG3QwAaia1Mk5P8M7kraTOZN+vBET7n8KyB0YXCbFRLQ==} + + '@changesets/get-github-info@0.5.2': + resolution: {integrity: sha512-JppheLu7S114aEs157fOZDjFqUDpm7eHdq5E8SSR0gUBTEK0cNSHsrSR5a66xs0z3RWuo46QvA3vawp8BxDHvg==} + + '@changesets/get-release-plan@4.0.4': + resolution: {integrity: sha512-SicG/S67JmPTrdcc9Vpu0wSQt7IiuN0dc8iR5VScnnTVPfIaLvKmEGRvIaF0kcn8u5ZqLbormZNTO77bCEvyWw==} + + '@changesets/get-version-range-type@0.4.0': + resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==} + + '@changesets/git@3.0.1': + resolution: {integrity: sha512-pdgHcYBLCPcLd82aRcuO0kxCDbw/yISlOtkmwmE8Odo1L6hSiZrBOsRl84eYG7DRCab/iHnOkWqExqc4wxk2LQ==} + + '@changesets/logger@0.1.1': + resolution: {integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==} + + '@changesets/parse@0.4.0': + resolution: {integrity: sha512-TS/9KG2CdGXS27S+QxbZXgr8uPsP4yNJYb4BC2/NeFUj80Rni3TeD2qwWmabymxmrLo7JEsytXH1FbpKTbvivw==} + + '@changesets/pre@2.0.1': + resolution: {integrity: sha512-vvBJ/If4jKM4tPz9JdY2kGOgWmCowUYOi5Ycv8dyLnEE8FgpYYUo1mgJZxcdtGGP3aG8rAQulGLyyXGSLkIMTQ==} + + '@changesets/read@0.6.1': + resolution: {integrity: sha512-jYMbyXQk3nwP25nRzQQGa1nKLY0KfoOV7VLgwucI0bUO8t8ZLCr6LZmgjXsiKuRDc+5A6doKPr9w2d+FEJ55zQ==} + + '@changesets/should-skip-package@0.1.1': + resolution: {integrity: sha512-H9LjLbF6mMHLtJIc/eHR9Na+MifJ3VxtgP/Y+XLn4BF7tDTEN1HNYtH6QMcjP1uxp9sjaFYmW8xqloaCi/ckTg==} + + '@changesets/types@4.1.0': + resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} + + '@changesets/types@5.2.1': + resolution: {integrity: sha512-myLfHbVOqaq9UtUKqR/nZA/OY7xFjQMdfgfqeZIBK4d0hA6pgxArvdv8M+6NUzzBsjWLOtvApv8YHr4qM+Kpfg==} + + '@changesets/types@6.0.0': + resolution: {integrity: sha512-b1UkfNulgKoWfqyHtzKS5fOZYSJO+77adgL7DLRDr+/7jhChN+QcHnbjiQVOz/U+Ts3PGNySq7diAItzDgugfQ==} + + '@changesets/write@0.3.2': + resolution: {integrity: sha512-kDxDrPNpUgsjDbWBvUo27PzKX4gqeKOlhibaOXDJA6kuBisGqNHv/HwGJrAu8U/dSf8ZEFIeHIPtvSlZI1kULw==} + + '@cloudflare/kv-asset-handler@0.4.0': + resolution: {integrity: sha512-+tv3z+SPp+gqTIcImN9o0hqE9xyfQjI1XD9pL6NuKjua9B1y7mNYv0S9cP+QEbA4ppVgGZEmKOvHX5G5Ei1CVA==} + engines: {node: '>=18.0.0'} + + '@coinbase/wallet-sdk@3.9.3': + resolution: {integrity: sha512-N/A2DRIf0Y3PHc1XAMvbBUu4zisna6qAdqABMZwBMNEfWrXpAwx16pZGkYCLGE+Rvv1edbcB2LYDRnACNcmCiw==} + + '@coinbase/wallet-sdk@4.3.0': + resolution: {integrity: sha512-T3+SNmiCw4HzDm4we9wCHCxlP0pqCiwKe4sOwPH3YAK2KSKjxPRydKu6UQJrdONFVLG7ujXvbd/6ZqmvJb8rkw==} + + '@colors/colors@1.5.0': + resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} + engines: {node: '>=0.1.90'} + + '@colors/colors@1.6.0': + resolution: {integrity: sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==} + engines: {node: '>=0.1.90'} + + '@dabh/diagnostics@2.0.3': + resolution: {integrity: sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==} + + '@dependents/detective-less@4.1.0': + resolution: {integrity: sha512-KrkT6qO5NxqNfy68sBl6CTSoJ4SNDIS5iQArkibhlbGU4LaDukZ3q2HIkh8aUKDio6o4itU4xDR7t82Y2eP1Bg==} + engines: {node: '>=14'} + + '@discoveryjs/json-ext@0.5.7': + resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==} + engines: {node: '>=10.0.0'} + + '@docsearch/css@3.6.3': + resolution: {integrity: sha512-3uvbg8E7rhqE1C4oBAK3tGlS2qfhi9zpfZgH/yjDPF73vd9B41urVIKujF4rczcF4E3qs34SedhehiDJ4UdNBA==} + + '@docsearch/js@3.6.3': + resolution: {integrity: sha512-2mBFomaN6VijyQQGwieERDu9GeE0hlv9TQRZBTOYsPQW7/vqtd4hnHEkbBbaBRiS4PYcy+UhikbMuDExJs63UA==} + + '@docsearch/react@3.6.3': + resolution: {integrity: sha512-2munr4uBuZq1PG+Ge+F+ldIdxb3Wi8OmEIv2tQQb4RvEvvph+xtQkxwHzVIEnt5s+HecwucuXwB+3JhcZboFLg==} + peerDependencies: + '@types/react': '>= 16.8.0 < 19.0.0' + react: '>= 16.8.0 < 19.0.0' + react-dom: '>= 16.8.0 < 19.0.0' + search-insights: '>= 1 < 3' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + react-dom: + optional: true + search-insights: + optional: true + + '@ecies/ciphers@0.2.3': + resolution: {integrity: sha512-tapn6XhOueMwht3E2UzY0ZZjYokdaw9XtL9kEyjhQ/Fb9vL9xTFbOaI+fV0AWvTpYu4BNloC6getKW6NtSg4mA==} + engines: {bun: '>=1', deno: '>=2', node: '>=16'} + peerDependencies: + '@noble/ciphers': ^1.0.0 + + '@emnapi/core@1.4.3': + resolution: {integrity: sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g==} + + '@emnapi/runtime@1.4.3': + resolution: {integrity: sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==} + + '@emnapi/wasi-threads@1.0.2': + resolution: {integrity: sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA==} + + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/aix-ppc64@0.25.4': + resolution: {integrity: sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/aix-ppc64@0.25.5': + resolution: {integrity: sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm64@0.25.4': + resolution: {integrity: sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm64@0.25.5': + resolution: {integrity: sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-arm@0.25.4': + resolution: {integrity: sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-arm@0.25.5': + resolution: {integrity: sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/android-x64@0.25.4': + resolution: {integrity: sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/android-x64@0.25.5': + resolution: {integrity: sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-arm64@0.25.4': + resolution: {integrity: sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-arm64@0.25.5': + resolution: {integrity: sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/darwin-x64@0.25.4': + resolution: {integrity: sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/darwin-x64@0.25.5': + resolution: {integrity: sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-arm64@0.25.4': + resolution: {integrity: sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-arm64@0.25.5': + resolution: {integrity: sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.25.4': + resolution: {integrity: sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.25.5': + resolution: {integrity: sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm64@0.25.4': + resolution: {integrity: sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm64@0.25.5': + resolution: {integrity: sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-arm@0.25.4': + resolution: {integrity: sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-arm@0.25.5': + resolution: {integrity: sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-ia32@0.25.4': + resolution: {integrity: sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-ia32@0.25.5': + resolution: {integrity: sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-loong64@0.25.4': + resolution: {integrity: sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-loong64@0.25.5': + resolution: {integrity: sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-mips64el@0.25.4': + resolution: {integrity: sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-mips64el@0.25.5': + resolution: {integrity: sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-ppc64@0.25.4': + resolution: {integrity: sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-ppc64@0.25.5': + resolution: {integrity: sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-riscv64@0.25.4': + resolution: {integrity: sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-riscv64@0.25.5': + resolution: {integrity: sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-s390x@0.25.4': + resolution: {integrity: sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-s390x@0.25.5': + resolution: {integrity: sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/linux-x64@0.25.4': + resolution: {integrity: sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/linux-x64@0.25.5': + resolution: {integrity: sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.25.4': + resolution: {integrity: sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-arm64@0.25.5': + resolution: {integrity: sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.25.4': + resolution: {integrity: sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.25.5': + resolution: {integrity: sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.25.4': + resolution: {integrity: sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-arm64@0.25.5': + resolution: {integrity: sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.25.4': + resolution: {integrity: sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.25.5': + resolution: {integrity: sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/sunos-x64@0.25.4': + resolution: {integrity: sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/sunos-x64@0.25.5': + resolution: {integrity: sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-arm64@0.25.4': + resolution: {integrity: sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-arm64@0.25.5': + resolution: {integrity: sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-ia32@0.25.4': + resolution: {integrity: sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-ia32@0.25.5': + resolution: {integrity: sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@esbuild/win32-x64@0.25.4': + resolution: {integrity: sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@esbuild/win32-x64@0.25.5': + resolution: {integrity: sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@ethereumjs/common@3.2.0': + resolution: {integrity: sha512-pksvzI0VyLgmuEF2FA/JR/4/y6hcPq8OUail3/AvycBaW1d5VSauOZzqGvJ3RTmR4MU35lWE8KseKOsEhrFRBA==} + + '@ethereumjs/rlp@4.0.1': + resolution: {integrity: sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==} + engines: {node: '>=14'} + hasBin: true + + '@ethereumjs/tx@4.2.0': + resolution: {integrity: sha512-1nc6VO4jtFd172BbSnTnDQVr9IYBFl1y4xPzZdtkrkKIncBCkdbgfdRV+MiTkJYAtTxvV12GRZLqBFT1PNK6Yw==} + engines: {node: '>=14'} + + '@ethereumjs/util@8.1.0': + resolution: {integrity: sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==} + engines: {node: '>=14'} + + '@ethersproject/abi@5.7.0': + resolution: {integrity: sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==} + + '@ethersproject/abstract-provider@5.7.0': + resolution: {integrity: sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==} + + '@ethersproject/abstract-signer@5.7.0': + resolution: {integrity: sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==} + + '@ethersproject/address@5.7.0': + resolution: {integrity: sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==} + + '@ethersproject/base64@5.7.0': + resolution: {integrity: sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==} + + '@ethersproject/bignumber@5.7.0': + resolution: {integrity: sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==} + + '@ethersproject/bytes@5.7.0': + resolution: {integrity: sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==} + + '@ethersproject/constants@5.7.0': + resolution: {integrity: sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==} + + '@ethersproject/hash@5.7.0': + resolution: {integrity: sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==} + + '@ethersproject/keccak256@5.7.0': + resolution: {integrity: sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==} + + '@ethersproject/logger@5.7.0': + resolution: {integrity: sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==} + + '@ethersproject/networks@5.7.1': + resolution: {integrity: sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==} + + '@ethersproject/properties@5.7.0': + resolution: {integrity: sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==} + + '@ethersproject/rlp@5.7.0': + resolution: {integrity: sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==} + + '@ethersproject/signing-key@5.7.0': + resolution: {integrity: sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==} + + '@ethersproject/strings@5.7.0': + resolution: {integrity: sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==} + + '@ethersproject/transactions@5.7.0': + resolution: {integrity: sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==} + + '@ethersproject/web@5.7.1': + resolution: {integrity: sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==} + + '@fastify/busboy@2.1.0': + resolution: {integrity: sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==} + engines: {node: '>=14'} + + '@fastify/busboy@3.1.1': + resolution: {integrity: sha512-5DGmA8FTdB2XbDeEwc/5ZXBl6UbBAyBOOLlPuBnZ/N1SwdH9Ii+cOX3tBROlDgcTXxjOYnLMVoKk9+FXAw0CJw==} + + '@floating-ui/core@1.6.1': + resolution: {integrity: sha512-42UH54oPZHPdRHdw6BgoBD6cg/eVTmVrFcgeRDM3jbO7uxSoipVcmcIGFcA5jmOHO5apcyvBhkSKES3fQJnu7A==} + + '@floating-ui/dom@1.1.1': + resolution: {integrity: sha512-TpIO93+DIujg3g7SykEAGZMDtbJRrmnYRCNYSjJlvIbGhBjRSNTLVbNeDQBrzy9qDgUbiWdc7KA0uZHZ2tJmiw==} + + '@floating-ui/utils@0.2.2': + resolution: {integrity: sha512-J4yDIIthosAsRZ5CPYP/jQvUAQtlZTTD/4suA08/FEnlxqW3sKS9iAhgsa9VYLZ6vDHn/ixJgIqRQPotoBjxIw==} + + '@iconify-json/simple-icons@1.2.10': + resolution: {integrity: sha512-9OK1dsSjXlH36lhu5n+BlSoXuqFjHUErGLtNdzHpq0vHq4YFBuGYWtZ+vZTHLreRQ8ijPRv/6EsgkV+nf6AReQ==} + + '@iconify/types@2.0.0': + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} + + '@iconify/utils@2.1.23': + resolution: {integrity: sha512-YGNbHKM5tyDvdWZ92y2mIkrfvm5Fvhe6WJSkWu7vvOFhMtYDP0casZpoRz0XEHZCrYsR4stdGT3cZ52yp5qZdQ==} + + '@img/sharp-darwin-arm64@0.34.2': + resolution: {integrity: sha512-OfXHZPppddivUJnqyKoi5YVeHRkkNE2zUFT2gbpKxp/JZCFYEYubnMg+gOp6lWfasPrTS+KPosKqdI+ELYVDtg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.34.2': + resolution: {integrity: sha512-dYvWqmjU9VxqXmjEtjmvHnGqF8GrVjM2Epj9rJ6BUIXvk8slvNDJbhGFvIoXzkDhrJC2jUxNLz/GUjjvSzfw+g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.1.0': + resolution: {integrity: sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.1.0': + resolution: {integrity: sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.1.0': + resolution: {integrity: sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linux-arm@1.1.0': + resolution: {integrity: sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA==} + cpu: [arm] + os: [linux] + + '@img/sharp-libvips-linux-ppc64@1.1.0': + resolution: {integrity: sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ==} + cpu: [ppc64] + os: [linux] + + '@img/sharp-libvips-linux-s390x@1.1.0': + resolution: {integrity: sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA==} + cpu: [s390x] + os: [linux] + + '@img/sharp-libvips-linux-x64@1.1.0': + resolution: {integrity: sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q==} + cpu: [x64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-arm64@1.1.0': + resolution: {integrity: sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-x64@1.1.0': + resolution: {integrity: sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A==} + cpu: [x64] + os: [linux] + + '@img/sharp-linux-arm64@0.34.2': + resolution: {integrity: sha512-D8n8wgWmPDakc83LORcfJepdOSN6MvWNzzz2ux0MnIbOqdieRZwVYY32zxVx+IFUT8er5KPcyU3XXsn+GzG/0Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linux-arm@0.34.2': + resolution: {integrity: sha512-0DZzkvuEOqQUP9mo2kjjKNok5AmnOr1jB2XYjkaoNRwpAYMDzRmAqUIa1nRi58S2WswqSfPOWLNOr0FDT3H5RQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + + '@img/sharp-linux-s390x@0.34.2': + resolution: {integrity: sha512-EGZ1xwhBI7dNISwxjChqBGELCWMGDvmxZXKjQRuqMrakhO8QoMgqCrdjnAqJq/CScxfRn+Bb7suXBElKQpPDiw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + + '@img/sharp-linux-x64@0.34.2': + resolution: {integrity: sha512-sD7J+h5nFLMMmOXYH4DD9UtSNBD05tWSSdWAcEyzqW8Cn5UxXvsHAxmxSesYUsTOBmUnjtxghKDl15EvfqLFbQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-linuxmusl-arm64@0.34.2': + resolution: {integrity: sha512-NEE2vQ6wcxYav1/A22OOxoSOGiKnNmDzCYFOZ949xFmrWZOVII1Bp3NqVVpvj+3UeHMFyN5eP/V5hzViQ5CZNA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linuxmusl-x64@0.34.2': + resolution: {integrity: sha512-DOYMrDm5E6/8bm/yQLCWyuDJwUnlevR8xtF8bs+gjZ7cyUNYXiSf/E8Kp0Ss5xasIaXSHzb888V1BE4i1hFhAA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-wasm32@0.34.2': + resolution: {integrity: sha512-/VI4mdlJ9zkaq53MbIG6rZY+QRN3MLbR6usYlgITEzi4Rpx5S6LFKsycOQjkOGmqTNmkIdLjEvooFKwww6OpdQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-arm64@0.34.2': + resolution: {integrity: sha512-cfP/r9FdS63VA5k0xiqaNaEoGxBg9k7uE+RQGzuK9fHt7jib4zAVVseR9LsE4gJcNWgT6APKMNnCcnyOtmSEUQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [win32] + + '@img/sharp-win32-ia32@0.34.2': + resolution: {integrity: sha512-QLjGGvAbj0X/FXl8n1WbtQ6iVBpWU7JO94u/P2M4a8CFYsvQi4GW2mRy/JqkRx0qpBzaOdKJKw8uc930EX2AHw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.34.2': + resolution: {integrity: sha512-aUdT6zEYtDKCaxkofmmJDJYGCf0+pJg3eU9/oBuqvEeoB9dKI6ZLc/1iLJCTuJQDO4ptntAlkUmHgGjyuobZbw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + + '@inquirer/confirm@3.1.6': + resolution: {integrity: sha512-Mj4TU29g6Uy+37UtpA8UpEOI2icBfpCwSW1QDtfx60wRhUy90s/kHPif2OXSSvuwDQT1lhAYRWUfkNf9Tecxvg==} + engines: {node: '>=18'} + + '@inquirer/core@8.1.0': + resolution: {integrity: sha512-kfx0SU9nWgGe1f03ao/uXc85SFH1v2w3vQVH7QDGjKxdtJz+7vPitFtG++BTyJMYyYgH8MpXigutcXJeiQwVRw==} + engines: {node: '>=18'} + + '@inquirer/figures@1.0.1': + resolution: {integrity: sha512-mtup3wVKia3ZwULPHcbs4Mor8Voi+iIXEWD7wCNbIO6lYR62oPCTQyrddi5OMYVXHzeCSoneZwJuS8sBvlEwDw==} + engines: {node: '>=18'} + + '@inquirer/type@1.3.1': + resolution: {integrity: sha512-Pe3PFccjPVJV1vtlfVvm9OnlbxqdnP5QcscFEFEnK5quChf1ufZtM0r8mR5ToWHMxZOh0s8o/qp9ANGRTo/DAw==} + engines: {node: '>=18'} + + '@ioredis/commands@1.2.0': + resolution: {integrity: sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==} + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + + '@istanbuljs/schema@0.1.3': + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + + '@jridgewell/gen-mapping@0.3.3': + resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} + engines: {node: '>=6.0.0'} + + '@jridgewell/gen-mapping@0.3.5': + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + + '@jridgewell/gen-mapping@0.3.8': + resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.0': + resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.1.2': + resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/source-map@0.3.6': + resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==} + + '@jridgewell/sourcemap-codec@1.4.14': + resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} + + '@jridgewell/sourcemap-codec@1.4.15': + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.17': + resolution: {integrity: sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@kwsites/file-exists@1.1.1': + resolution: {integrity: sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==} + + '@kwsites/promise-deferred@1.1.1': + resolution: {integrity: sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==} + + '@lit-labs/ssr-dom-shim@1.3.0': + resolution: {integrity: sha512-nQIWonJ6eFAvUUrSlwyHDm/aE8PBDu5kRpL0vHMg6K8fK3Diq1xdPjTnsJSwxABhaZ+5eBi1btQB5ShUTKo4nQ==} + + '@lit/reactive-element@2.1.0': + resolution: {integrity: sha512-L2qyoZSQClcBmq0qajBVbhYEcG6iK0XfLn66ifLe/RfC0/ihpc+pl0Wdn8bJ8o+hj38cG0fGXRgSS20MuXn7qA==} + + '@manypkg/find-root@1.1.0': + resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} + + '@manypkg/get-packages@1.1.3': + resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} + + '@mapbox/node-pre-gyp@1.0.11': + resolution: {integrity: sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==} + hasBin: true + + '@mapbox/node-pre-gyp@2.0.0': + resolution: {integrity: sha512-llMXd39jtP0HpQLVI37Bf1m2ADlEb35GYSh1SDSLsBhR+5iCxiNGlT31yqbNtVHygHAtMy6dWFERpU2JgufhPg==} + engines: {node: '>=18'} + hasBin: true + + '@metamask/eth-json-rpc-provider@1.0.1': + resolution: {integrity: sha512-whiUMPlAOrVGmX8aKYVPvlKyG4CpQXiNNyt74vE1xb5sPvmx5oA7B/kOi/JdBvhGQq97U1/AVdXEdk2zkP8qyA==} + engines: {node: '>=14.0.0'} + + '@metamask/eth-sig-util@4.0.1': + resolution: {integrity: sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==} + engines: {node: '>=12.0.0'} + + '@metamask/json-rpc-engine@7.3.3': + resolution: {integrity: sha512-dwZPq8wx9yV3IX2caLi9q9xZBw2XeIoYqdyihDDDpuHVCEiqadJLwqM3zy+uwf6F1QYQ65A8aOMQg1Uw7LMLNg==} + engines: {node: '>=16.0.0'} + + '@metamask/json-rpc-engine@8.0.2': + resolution: {integrity: sha512-IoQPmql8q7ABLruW7i4EYVHWUbF74yrp63bRuXV5Zf9BQwcn5H9Ww1eLtROYvI1bUXwOiHZ6qT5CWTrDc/t/AA==} + engines: {node: '>=16.0.0'} + + '@metamask/json-rpc-middleware-stream@7.0.2': + resolution: {integrity: sha512-yUdzsJK04Ev98Ck4D7lmRNQ8FPioXYhEUZOMS01LXW8qTvPGiRVXmVltj2p4wrLkh0vW7u6nv0mNl5xzC5Qmfg==} + engines: {node: '>=16.0.0'} + + '@metamask/object-multiplex@2.1.0': + resolution: {integrity: sha512-4vKIiv0DQxljcXwfpnbsXcfa5glMj5Zg9mqn4xpIWqkv6uJ2ma5/GtUfLFSxhlxnR8asRMv8dDmWya1Tc1sDFA==} + engines: {node: ^16.20 || ^18.16 || >=20} + + '@metamask/onboarding@1.0.1': + resolution: {integrity: sha512-FqHhAsCI+Vacx2qa5mAFcWNSrTcVGMNjzxVgaX8ECSny/BJ9/vgXP9V7WF/8vb9DltPeQkxr+Fnfmm6GHfmdTQ==} + + '@metamask/providers@16.1.0': + resolution: {integrity: sha512-znVCvux30+3SaUwcUGaSf+pUckzT5ukPRpcBmy+muBLC0yaWnBcvDqGfcsw6CBIenUdFrVoAFa8B6jsuCY/a+g==} + engines: {node: ^18.18 || >=20} + + '@metamask/rpc-errors@6.4.0': + resolution: {integrity: sha512-1ugFO1UoirU2esS3juZanS/Fo8C8XYocCuBpfZI5N7ECtoG+zu0wF+uWZASik6CkO6w9n/Iebt4iI4pT0vptpg==} + engines: {node: '>=16.0.0'} + + '@metamask/safe-event-emitter@2.0.0': + resolution: {integrity: sha512-/kSXhY692qiV1MXu6EeOZvg5nECLclxNXcKCxJ3cXQgYuRymRHpdx/t7JXfsK+JLjwA1e1c1/SBrlQYpusC29Q==} + + '@metamask/safe-event-emitter@3.0.0': + resolution: {integrity: sha512-j6Z47VOmVyGMlnKXZmL0fyvWfEYtKWCA9yGZkU3FCsGZUT5lHGmvaV9JA5F2Y+010y7+ROtR3WMXIkvl/nVzqQ==} + engines: {node: '>=12.0.0'} + + '@metamask/safe-event-emitter@3.1.2': + resolution: {integrity: sha512-5yb2gMI1BDm0JybZezeoX/3XhPDOtTbcFvpTXM9kxsoZjPZFh4XciqRbpD6N86HYZqWDhEaKUDuOyR0sQHEjMA==} + engines: {node: '>=12.0.0'} + + '@metamask/sdk-communication-layer@0.32.0': + resolution: {integrity: sha512-dmj/KFjMi1fsdZGIOtbhxdg3amxhKL/A5BqSU4uh/SyDKPub/OT+x5pX8bGjpTL1WPWY/Q0OIlvFyX3VWnT06Q==} + peerDependencies: + cross-fetch: ^4.0.0 + eciesjs: '*' + eventemitter2: ^6.4.9 + readable-stream: ^3.6.2 + socket.io-client: ^4.5.1 + + '@metamask/sdk-install-modal-web@0.32.1': + resolution: {integrity: sha512-MGmAo6qSjf1tuYXhCu2EZLftq+DSt5Z7fsIKr2P+lDgdTPWgLfZB1tJKzNcwKKOdf6q9Qmmxn7lJuI/gq5LrKw==} + + '@metamask/sdk@0.32.1': + resolution: {integrity: sha512-ulvScxyuX+A8VYgQ9FGugtpH5l2U8AF0lOjaw6XyqwnL7I/U0Lk9yyz9pns4Zyq356Z4+nIBzxmb6czWLzp8UQ==} + + '@metamask/superstruct@3.2.1': + resolution: {integrity: sha512-fLgJnDOXFmuVlB38rUN5SmU7hAFQcCjrg3Vrxz67KTY7YHFnSNEKvX4avmEBdOI0yTCxZjwMCFEqsC8k2+Wd3g==} + engines: {node: '>=16.0.0'} + + '@metamask/utils@5.0.2': + resolution: {integrity: sha512-yfmE79bRQtnMzarnKfX7AEJBwFTxvTyw3nBQlu/5rmGXrjAeAMltoGxO62TFurxrQAFMNa/fEjIHNvungZp0+g==} + engines: {node: '>=14.0.0'} + + '@metamask/utils@8.5.0': + resolution: {integrity: sha512-I6bkduevXb72TIM9q2LRO63JSsF9EXduh3sBr9oybNX2hNNpr/j1tEjXrsG0Uabm4MJ1xkGAQEMwifvKZIkyxQ==} + engines: {node: '>=16.0.0'} + + '@metamask/utils@9.3.0': + resolution: {integrity: sha512-w8CVbdkDrVXFJbfBSlDfafDR6BAkpDmv1bC1UJVCoVny5tW2RKAdn9i68Xf7asYT4TnUhl/hN4zfUiKQq9II4g==} + engines: {node: '>=16.0.0'} + + '@mswjs/interceptors@0.35.9': + resolution: {integrity: sha512-SSnyl/4ni/2ViHKkiZb8eajA/eN1DNFaHjhGiLUdZvDz6PKF4COSf/17xqSz64nOo2Ia29SA6B2KNCsyCbVmaQ==} + engines: {node: '>=18'} + + '@napi-rs/wasm-runtime@0.2.10': + resolution: {integrity: sha512-bCsCyeZEwVErsGmyPNSzwfwFn4OdxBj0mmv6hOFucB/k81Ojdu68RbZdxYsRQUPc9l6SU5F/cG+bXgWs3oUgsQ==} + + '@netlify/binary-info@1.0.0': + resolution: {integrity: sha512-4wMPu9iN3/HL97QblBsBay3E1etIciR84izI3U+4iALY+JHCrI+a2jO0qbAZ/nxKoegypYEaiiqWXylm+/zfrw==} + + '@netlify/blobs@9.1.1': + resolution: {integrity: sha512-hOrWBMOvdh9oa+8Z6ocvkY92q9YtfD+Vbh2i+Qs14cHsl9SYxRzPRQnBxU/H6PNtj6gtEJ7tv8RbBN8z7jH2jA==} + engines: {node: ^14.16.0 || >=16.0.0} + + '@netlify/dev-utils@2.1.1': + resolution: {integrity: sha512-0O4/eEcmZCNUkpSuN/yYRkX6BAcK/sbnH0YYNuK3HX193QXaSBT60TUpvTpiRxI6zvIfYCDRl3rz63w8m/lEMg==} + engines: {node: ^14.16.0 || >=16.0.0} + + '@netlify/functions@3.1.8': + resolution: {integrity: sha512-oAHPyybBx4oH8+3RfgihrTVhv6gseQw1pt0k4kZ/NDmGbEsgrr3gw+3ajzM5+fW5UnWiNuR5c+d7JgtRqjyMkw==} + engines: {node: '>=14.0.0'} + + '@netlify/open-api@2.37.0': + resolution: {integrity: sha512-zXnRFkxgNsalSgU8/vwTWnav3R+8KG8SsqHxqaoJdjjJtnZR7wo3f+qqu4z+WtZ/4V7fly91HFUwZ6Uz2OdW7w==} + engines: {node: '>=14.8.0'} + + '@netlify/runtime-utils@1.3.1': + resolution: {integrity: sha512-7/vIJlMYrPJPlEW84V2yeRuG3QBu66dmlv9neTmZ5nXzwylhBEOhy11ai+34A8mHCSZI4mKns25w3HM9kaDdJg==} + engines: {node: '>=16.0.0'} + + '@netlify/serverless-functions-api@1.41.1': + resolution: {integrity: sha512-swjyZEd8U1QVp01rZdHxpwWie7GkP1kS4+4n8kuNKA8+3G5tD0JXXf3a5d4tdwVvrU9k7a4GP1Bn792UPwecmw==} + engines: {node: '>=18.0.0'} + + '@netlify/zip-it-and-ship-it@10.1.1': + resolution: {integrity: sha512-MMXrty1NADxyMPgd7qZvDUYunhcPhxIA/jWP2joceOoPcAxOno/aS4jFuIHf2Dbb4HdhR+BlvgvDCy7QTXXyLQ==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + + '@next/bundle-analyzer@15.3.3': + resolution: {integrity: sha512-9gddnjACK6yOa5IkmeFyzcwZh2rscsb6ZspTd7tymPYKQM96fJuKjn9HrRtPNKiMm7ExKNadAJqREmHdBgHZ9A==} + + '@next/env@15.3.3': + resolution: {integrity: sha512-OdiMrzCl2Xi0VTjiQQUK0Xh7bJHnOuET2s+3V+Y40WJBAXrJeGA3f+I8MZJ/YQ3mVGi5XGR1L66oFlgqXhQ4Vw==} + + '@next/swc-darwin-arm64@15.3.3': + resolution: {integrity: sha512-WRJERLuH+O3oYB4yZNVahSVFmtxRNjNF1I1c34tYMoJb0Pve+7/RaLAJJizyYiFhjYNGHRAE1Ri2Fd23zgDqhg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@next/swc-darwin-x64@15.3.3': + resolution: {integrity: sha512-XHdzH/yBc55lu78k/XwtuFR/ZXUTcflpRXcsu0nKmF45U96jt1tsOZhVrn5YH+paw66zOANpOnFQ9i6/j+UYvw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@next/swc-linux-arm64-gnu@15.3.3': + resolution: {integrity: sha512-VZ3sYL2LXB8znNGcjhocikEkag/8xiLgnvQts41tq6i+wql63SMS1Q6N8RVXHw5pEUjiof+II3HkDd7GFcgkzw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@next/swc-linux-arm64-musl@15.3.3': + resolution: {integrity: sha512-h6Y1fLU4RWAp1HPNJWDYBQ+e3G7sLckyBXhmH9ajn8l/RSMnhbuPBV/fXmy3muMcVwoJdHL+UtzRzs0nXOf9SA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@next/swc-linux-x64-gnu@15.3.3': + resolution: {integrity: sha512-jJ8HRiF3N8Zw6hGlytCj5BiHyG/K+fnTKVDEKvUCyiQ/0r5tgwO7OgaRiOjjRoIx2vwLR+Rz8hQoPrnmFbJdfw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@next/swc-linux-x64-musl@15.3.3': + resolution: {integrity: sha512-HrUcTr4N+RgiiGn3jjeT6Oo208UT/7BuTr7K0mdKRBtTbT4v9zJqCDKO97DUqqoBK1qyzP1RwvrWTvU6EPh/Cw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@next/swc-win32-arm64-msvc@15.3.3': + resolution: {integrity: sha512-SxorONgi6K7ZUysMtRF3mIeHC5aA3IQLmKFQzU0OuhuUYwpOBc1ypaLJLP5Bf3M9k53KUUUj4vTPwzGvl/NwlQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@next/swc-win32-x64-msvc@15.3.3': + resolution: {integrity: sha512-4QZG6F8enl9/S2+yIiOiju0iCTFd93d8VC1q9LZS4p/Xuk81W2QDjCFeoogmrWWkAD59z8ZxepBQap2dKS5ruw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@noble/ciphers@1.2.1': + resolution: {integrity: sha512-rONPWMC7PeExE077uLE4oqWrZ1IvAfz3oH9LibVAcVCopJiA9R62uavnbEzdkVmJYI6M6Zgkbeb07+tWjlq2XA==} + engines: {node: ^14.21.3 || >=16} + + '@noble/ciphers@1.3.0': + resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.2.0': + resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==} + + '@noble/curves@1.4.0': + resolution: {integrity: sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg==} + + '@noble/curves@1.4.2': + resolution: {integrity: sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==} + + '@noble/curves@1.8.0': + resolution: {integrity: sha512-j84kjAbzEnQHaSIhRPUmB3/eVXu2k3dKPl2LOrR8fSOIL+89U+7lV117EWHtq/GHM3ReGHM46iRBdZfpc4HRUQ==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.8.1': + resolution: {integrity: sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.8.2': + resolution: {integrity: sha512-vnI7V6lFNe0tLAuJMu+2sX+FcL14TaCWy1qiczg1VwRmPrpQCdq5ESXQMqUc2tluRNf6irBXrWbl1mGN8uaU/g==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.9.2': + resolution: {integrity: sha512-HxngEd2XUcg9xi20JkwlLCtYwfoFw4JGkuZpT+WlsPD4gB/cxkvTD8fSsoAnphGZhFdZYKeQIPCuFlWPm1uE0g==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.2.0': + resolution: {integrity: sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==} + + '@noble/hashes@1.3.2': + resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} + engines: {node: '>= 16'} + + '@noble/hashes@1.4.0': + resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} + engines: {node: '>= 16'} + + '@noble/hashes@1.5.0': + resolution: {integrity: sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.7.0': + resolution: {integrity: sha512-HXydb0DgzTpDPwbVeDGCG1gIu7X6+AuU6Zl6av/E/KG8LMsvPntvq+w17CHRpKBmN6Ybdrt1eP3k4cj8DJa78w==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.7.1': + resolution: {integrity: sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.7.2': + resolution: {integrity: sha512-biZ0NUSxyjLLqo6KxEJ1b+C2NAx0wtDoFvCaXHGgUkeHzf3Xc1xKumFKREuT7f7DARNZ/slvYUwFG6B0f2b6hQ==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.8.0': + resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} + engines: {node: ^14.21.3 || >=16} + + '@noble/secp256k1@1.7.1': + resolution: {integrity: sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@nomicfoundation/edr-darwin-arm64@0.3.7': + resolution: {integrity: sha512-6tK9Lv/lSfyBvpEQ4nsTfgxyDT1y1Uv/x8Wa+aB+E8qGo3ToexQ1BMVjxJk6PChXCDOWxB3B4KhqaZFjdhl3Ow==} + engines: {node: '>= 18'} + cpu: [arm64] + os: [darwin] + + '@nomicfoundation/edr-darwin-x64@0.3.7': + resolution: {integrity: sha512-1RrQ/1JPwxrYO69e0tglFv5H+ggour5Ii3bb727+yBpBShrxtOTQ7fZyfxA5h62LCN+0Z9wYOPeQ7XFcVurMaQ==} + engines: {node: '>= 18'} + cpu: [x64] + os: [darwin] + + '@nomicfoundation/edr-linux-arm64-gnu@0.3.7': + resolution: {integrity: sha512-ds/CKlBoVXIihjhflhgPn13EdKWed6r5bgvMs/YwRqT5wldQAQJZWAfA2+nYm0Yi2gMGh1RUpBcfkyl4pq7G+g==} + engines: {node: '>= 18'} + cpu: [arm64] + os: [linux] + + '@nomicfoundation/edr-linux-arm64-musl@0.3.7': + resolution: {integrity: sha512-e29udiRaPujhLkM3+R6ju7QISrcyOqpcaxb2FsDWBkuD7H8uU9JPZEyyUIpEp5uIY0Jh1eEJPKZKIXQmQAEAuw==} + engines: {node: '>= 18'} + cpu: [arm64] + os: [linux] + + '@nomicfoundation/edr-linux-x64-gnu@0.3.7': + resolution: {integrity: sha512-/xkjmTyv+bbJ4akBCW0qzFKxPOV4AqLOmqurov+s9umHb16oOv72osSa3SdzJED2gHDaKmpMITT4crxbar4Axg==} + engines: {node: '>= 18'} + cpu: [x64] + os: [linux] + + '@nomicfoundation/edr-linux-x64-musl@0.3.7': + resolution: {integrity: sha512-QwBP9xlmsbf/ldZDGLcE4QiAb8Zt46E/+WLpxHBATFhGa7MrpJh6Zse+h2VlrT/SYLPbh2cpHgSmoSlqVxWG9g==} + engines: {node: '>= 18'} + cpu: [x64] + os: [linux] + + '@nomicfoundation/edr-win32-x64-msvc@0.3.7': + resolution: {integrity: sha512-j/80DEnkxrF2ewdbk/gQ2EOPvgF0XSsg8D0o4+6cKhUVAW6XwtWKzIphNL6dyD2YaWEPgIrNvqiJK/aln0ww4Q==} + engines: {node: '>= 18'} + cpu: [x64] + os: [win32] + + '@nomicfoundation/edr@0.3.7': + resolution: {integrity: sha512-v2JFWnFKRsnOa6PDUrD+sr8amcdhxnG/YbL7LzmgRGU1odWEyOF4/EwNeUajQr4ZNKVWrYnJ6XjydXtUge5OBQ==} + engines: {node: '>= 18'} + + '@nomicfoundation/ethereumjs-common@4.0.4': + resolution: {integrity: sha512-9Rgb658lcWsjiicr5GzNCjI1llow/7r0k50dLL95OJ+6iZJcVbi15r3Y0xh2cIO+zgX0WIHcbzIu6FeQf9KPrg==} + + '@nomicfoundation/ethereumjs-rlp@5.0.4': + resolution: {integrity: sha512-8H1S3s8F6QueOc/X92SdrA4RDenpiAEqMg5vJH99kcQaCy/a3Q6fgseo75mgWlbanGJXSlAPtnCeG9jvfTYXlw==} + engines: {node: '>=18'} + hasBin: true + + '@nomicfoundation/ethereumjs-tx@5.0.4': + resolution: {integrity: sha512-Xjv8wAKJGMrP1f0n2PeyfFCCojHd7iS3s/Ab7qzF1S64kxZ8Z22LCMynArYsVqiFx6rzYy548HNVEyI+AYN/kw==} + engines: {node: '>=18'} + peerDependencies: + c-kzg: ^2.1.2 + peerDependenciesMeta: + c-kzg: + optional: true + + '@nomicfoundation/ethereumjs-util@9.0.4': + resolution: {integrity: sha512-sLOzjnSrlx9Bb9EFNtHzK/FJFsfg2re6bsGqinFinH1gCqVfz9YYlXiMWwDM4C/L4ywuHFCYwfKTVr/QHQcU0Q==} + engines: {node: '>=18'} + peerDependencies: + c-kzg: ^2.1.2 + peerDependenciesMeta: + c-kzg: + optional: true + + '@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.1': + resolution: {integrity: sha512-KcTodaQw8ivDZyF+D76FokN/HdpgGpfjc/gFCImdLUyqB6eSWVaZPazMbeAjmfhx3R0zm/NYVzxwAokFKgrc0w==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@nomicfoundation/solidity-analyzer-darwin-x64@0.1.1': + resolution: {integrity: sha512-XhQG4BaJE6cIbjAVtzGOGbK3sn1BO9W29uhk9J8y8fZF1DYz0Doj8QDMfpMu+A6TjPDs61lbsmeYodIDnfveSA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@nomicfoundation/solidity-analyzer-freebsd-x64@0.1.1': + resolution: {integrity: sha512-GHF1VKRdHW3G8CndkwdaeLkVBi5A9u2jwtlS7SLhBc8b5U/GcoL39Q+1CSO3hYqePNP+eV5YI7Zgm0ea6kMHoA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [freebsd] + + '@nomicfoundation/solidity-analyzer-linux-arm64-gnu@0.1.1': + resolution: {integrity: sha512-g4Cv2fO37ZsUENQ2vwPnZc2zRenHyAxHcyBjKcjaSmmkKrFr64yvzeNO8S3GBFCo90rfochLs99wFVGT/0owpg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@nomicfoundation/solidity-analyzer-linux-arm64-musl@0.1.1': + resolution: {integrity: sha512-WJ3CE5Oek25OGE3WwzK7oaopY8xMw9Lhb0mlYuJl/maZVo+WtP36XoQTb7bW/i8aAdHW5Z+BqrHMux23pvxG3w==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@nomicfoundation/solidity-analyzer-linux-x64-gnu@0.1.1': + resolution: {integrity: sha512-5WN7leSr5fkUBBjE4f3wKENUy9HQStu7HmWqbtknfXkkil+eNWiBV275IOlpXku7v3uLsXTOKpnnGHJYI2qsdA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@nomicfoundation/solidity-analyzer-linux-x64-musl@0.1.1': + resolution: {integrity: sha512-KdYMkJOq0SYPQMmErv/63CwGwMm5XHenEna9X9aB8mQmhDBrYrlAOSsIPgFCUSL0hjxE3xHP65/EPXR/InD2+w==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@nomicfoundation/solidity-analyzer-win32-arm64-msvc@0.1.1': + resolution: {integrity: sha512-VFZASBfl4qiBYwW5xeY20exWhmv6ww9sWu/krWSesv3q5hA0o1JuzmPHR4LPN6SUZj5vcqci0O6JOL8BPw+APg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@nomicfoundation/solidity-analyzer-win32-ia32-msvc@0.1.1': + resolution: {integrity: sha512-JnFkYuyCSA70j6Si6cS1A9Gh1aHTEb8kOTBApp/c7NRTFGNMH8eaInKlyuuiIbvYFhlXW4LicqyYuWNNq9hkpQ==} + engines: {node: '>= 10'} + cpu: [ia32] + os: [win32] + + '@nomicfoundation/solidity-analyzer-win32-x64-msvc@0.1.1': + resolution: {integrity: sha512-HrVJr6+WjIXGnw3Q9u6KQcbZCtk0caVWhCdFADySvRyUxJ8PnzlaP+MhwNE8oyT8OZ6ejHBRrrgjSqDCFXGirw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@nomicfoundation/solidity-analyzer@0.1.1': + resolution: {integrity: sha512-1LMtXj1puAxyFusBgUIy5pZk3073cNXYnXUpuNKFghHbIit/xZgbk0AokpUADbNm3gyD6bFWl3LRFh3dhVdREg==} + engines: {node: '>= 12'} + + '@nuxt/cli@3.25.1': + resolution: {integrity: sha512-7+Ut7IvAD4b5piikJFSgIqSPbHKFT5gq05JvCsEHRM0MPA5QR9QHkicklyMqSj0D/oEkDohen8qRgdxRie3oUA==} + engines: {node: ^16.10.0 || >=18.0.0} + hasBin: true + + '@nuxt/devalue@2.0.2': + resolution: {integrity: sha512-GBzP8zOc7CGWyFQS6dv1lQz8VVpz5C2yRszbXufwG/9zhStTIH50EtD87NmWbTMwXDvZLNg8GIpb1UFdH93JCA==} + + '@nuxt/devtools-kit@2.4.1': + resolution: {integrity: sha512-taA2Nm03JiV3I+SEYS/u1AfjvLm3V9PO8lh0xLsUk/2mlUnL6GZ9xLXrp8VRg11HHt7EPXERGQh8h4iSPU2bSQ==} + peerDependencies: + vite: '>=6.0' + + '@nuxt/devtools-wizard@2.4.1': + resolution: {integrity: sha512-2BaryhfribzQ95UxR7vLLV17Pk1Otxg9ryqH71M1Yp0mybBFs6Z3b0v+RXfCb4BwA10s/tXBhfF13DHSSJF1+A==} + hasBin: true + + '@nuxt/devtools@2.4.1': + resolution: {integrity: sha512-2gwjUF1J1Bp/V9ZTsYJe8sS9O3eg80gdf01fT8aEBcilR3wf0PSIxjEyYk+YENtrHPLXcnnUko89jHGq23MHPQ==} + hasBin: true + peerDependencies: + vite: '>=6.0' + + '@nuxt/kit@3.16.0': + resolution: {integrity: sha512-yPfhk58BG6wJhELkGOTCOlkMDbZkizk3IaINcyTKm+hBKiK3SheLt7S9HStNL+qZSfH2Cf7A8sYp6M72lOIEtA==} + engines: {node: '>=18.12.0'} + + '@nuxt/kit@3.17.4': + resolution: {integrity: sha512-l+hY8sy2XFfg3PigZj+PTu6+KIJzmbACTRimn1ew/gtCz+F38f6KTF4sMRTN5CUxiB8TRENgEonASmkAWfpO9Q==} + engines: {node: '>=18.12.0'} + + '@nuxt/schema@3.11.2': + resolution: {integrity: sha512-Z0bx7N08itD5edtpkstImLctWMNvxTArsKXzS35ZuqyAyKBPcRjO1CU01slH0ahO30Gg9kbck3/RKNZPwfOjJg==} + engines: {node: ^14.18.0 || >=16.10.0} + + '@nuxt/schema@3.16.0': + resolution: {integrity: sha512-uCpcqWO6C4P5c4vi1/sq5GyajO0EOp+ZWFtPrnKaJ1pXAhA+W1aMVxAjfi2f18QMJHuRXBz1TouFg1RmWA6FuA==} + engines: {node: ^14.18.0 || >=16.10.0} + + '@nuxt/schema@3.17.4': + resolution: {integrity: sha512-bsfJdWjKNYLkVQt7Ykr9YsAql1u8Tuo6iecSUOltTIhsvAIYsknRFPHoNKNmaiv/L6FgCQgUgQppPTPUAXiJQQ==} + engines: {node: ^14.18.0 || >=16.10.0} + + '@nuxt/telemetry@2.6.6': + resolution: {integrity: sha512-Zh4HJLjzvm3Cq9w6sfzIFyH9ozK5ePYVfCUzzUQNiZojFsI2k1QkSBrVI9BGc6ArKXj/O6rkI6w7qQ+ouL8Cag==} + engines: {node: '>=18.12.0'} + hasBin: true + + '@nuxt/ui-templates@1.3.3': + resolution: {integrity: sha512-3BG5doAREcD50dbKyXgmjD4b1GzY8CUy3T41jMhHZXNDdaNwOd31IBq+D6dV00OSrDVhzrTVj0IxsUsnMyHvIQ==} + + '@nuxt/vite-builder@3.16.0': + resolution: {integrity: sha512-H/mRrDmpWWLIiF1J9jguCKITF0ydFxmgcBcbveQac6vVhaOZunBAv9SsKHZgnH8CDM1v5BnuRNyIQ9y4Y9wW8g==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0.0} + peerDependencies: + vue: ^3.3.4 + + '@one-ini/wasm@0.1.1': + resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==} + + '@open-draft/deferred-promise@2.2.0': + resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} + + '@open-draft/logger@0.3.0': + resolution: {integrity: sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==} + + '@open-draft/until@2.1.0': + resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} + + '@oven/bun-darwin-aarch64@1.1.30': + resolution: {integrity: sha512-D07QioP+QXlouvIqQIS+7r2zq4lTNd6he79rhKsRQRZGFf9i3NPu87zspUpCaFEu//DZ35DYTt+5anQpAzpoxA==} + cpu: [arm64] + os: [darwin] + + '@oven/bun-darwin-x64-baseline@1.1.30': + resolution: {integrity: sha512-1kFUCxHx7WuEbLDmqm0m2UKBd3S4Ln6qKQ4gxU4umMLFkmvDJn6PszDruFInxGKFLoTAmbXNYNVWkkG/ekt/Lg==} + cpu: [x64] + os: [darwin] + + '@oven/bun-darwin-x64@1.1.30': + resolution: {integrity: sha512-xZ4gTehS6QwN6bsJfDycCNneKoUMaFUQhQg24bJzXS4JPDxeKg1W7PS5AE+U9apz5Dx6//+D4RwVpAPG2LXt0w==} + cpu: [x64] + os: [darwin] + + '@oven/bun-linux-aarch64@1.1.30': + resolution: {integrity: sha512-SfHHLlph6fptDXyyChcUkeDbEZr2ww1p2BucV6OrvzwTOPi8pVmXA4360YT8ggR/3AHPp4GO36VaD+FU2Ocbxw==} + cpu: [arm64] + os: [linux] + + '@oven/bun-linux-x64-baseline@1.1.30': + resolution: {integrity: sha512-/b/VuNOaAYmsVk9MvfwKcCYARJPUg78hebxNyD5DSajAf3dqtUSnf7QYcq/3mxWH++N+gM7uRTrGksGS63+ZUw==} + cpu: [x64] + os: [linux] + + '@oven/bun-linux-x64@1.1.30': + resolution: {integrity: sha512-1mC39jQSaECytEKAZdCZmv3ZreMsp7aoxnBwmJtVd2Z7urnw17PKi4dKkZd/R+AubsNYtXtW4jeM8SEa5sUJRw==} + cpu: [x64] + os: [linux] + + '@oven/bun-windows-x64-baseline@1.1.30': + resolution: {integrity: sha512-ERQ4/ogzbFvHjpyHcnruc8bnryvDvUoiWi6vczfQ4M/idJc+Kg5VSEJiF5k7946rIZGamG6QWgRxtpIglD4/Zw==} + cpu: [x64] + os: [win32] + + '@oven/bun-windows-x64@1.1.30': + resolution: {integrity: sha512-mdRjNtD9NIA8CiH6N1zrIVE6oAtDko/c29H1s00UA+5O/WhXhg95G8IyInD8hN3vAEz8H2lGBgLG2EGfSFxnGg==} + cpu: [x64] + os: [win32] + + '@oxc-parser/binding-darwin-arm64@0.56.5': + resolution: {integrity: sha512-rj4WZqQVJQgLnGnDu2ciIOC5SqcBPc4x11RN0NwuedSGzny5mtBdNVLwt0+8iB15lIjrOKg5pjYJ8GQVPca5HA==} + engines: {node: '>=14.0.0'} + cpu: [arm64] + os: [darwin] + + '@oxc-parser/binding-darwin-x64@0.56.5': + resolution: {integrity: sha512-Rr7aMkqcxGIM6fgkpaj9SJj0u1O1g+AT7mJwmdi5PLSQRPR4CkDKfztEnAj5k+d2blWvh9nPZH8G0OCwxIHk1Q==} + engines: {node: '>=14.0.0'} + cpu: [x64] + os: [darwin] + + '@oxc-parser/binding-linux-arm-gnueabihf@0.56.5': + resolution: {integrity: sha512-jcFCThrWUt5k1GM43tdmI1m2dEnWUPPHHTWKBJbZBXzXLrJJzkqv5OU87Spf1004rYj9swwpa13kIldFwMzglA==} + engines: {node: '>=14.0.0'} + cpu: [arm] + os: [linux] + + '@oxc-parser/binding-linux-arm64-gnu@0.56.5': + resolution: {integrity: sha512-zo/9RDgWvugKxCpHHcAC5EW0AqoEvODJ4Iv4aT1Xonv6kcydbyPSXJBQhhZUvTXTAFIlQKl6INHl+Xki9Qs3fw==} + engines: {node: '>=14.0.0'} + cpu: [arm64] + os: [linux] + + '@oxc-parser/binding-linux-arm64-musl@0.56.5': + resolution: {integrity: sha512-SCIqrL5apVbrtMoqOpKX/Ez+c46WmW0Tyhtu+Xby281biH+wYu70m+fux9ZsGmbHc2ojd4FxUcaUdCZtb5uTOQ==} + engines: {node: '>=14.0.0'} + cpu: [arm64] + os: [linux] + + '@oxc-parser/binding-linux-x64-gnu@0.56.5': + resolution: {integrity: sha512-I2mpX35NWo83hay4wrnzFLk3VuGK1BBwHaqvEdqsCode8iG8slYJRJPICVbCEWlkR3rotlTQ+608JcRU0VqZ5Q==} + engines: {node: '>=14.0.0'} + cpu: [x64] + os: [linux] + + '@oxc-parser/binding-linux-x64-musl@0.56.5': + resolution: {integrity: sha512-xfzUHGYOh3PGWZdBuY5r1czvE8EGWPAmhTWHqkw3/uAfUVWN/qrrLjMojiaiWyUgl/9XIFg05m5CJH9dnngh5Q==} + engines: {node: '>=14.0.0'} + cpu: [x64] + os: [linux] + + '@oxc-parser/binding-wasm32-wasi@0.56.5': + resolution: {integrity: sha512-+z3Ofmc1v5kcu8fXgG5vn7T1f52P47ceTTmTXsm5HPY7rq5EMYRUaBnxH6cesXwY1OVVCwYlIZbCiy8Pm1w8zQ==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@oxc-parser/binding-win32-arm64-msvc@0.56.5': + resolution: {integrity: sha512-pRg8QrbMh8PgnXBreiONoJBR306u+JN19BXQC7oKIaG4Zxt9Mn8XIyuhUv3ytqjLudSiG2ERWQUoCGLs+yfW0A==} + engines: {node: '>=14.0.0'} + cpu: [arm64] + os: [win32] + + '@oxc-parser/binding-win32-x64-msvc@0.56.5': + resolution: {integrity: sha512-VALZNcuyw/6rwsxOACQ2YS6rey2d/ym4cNfXqJrHB/MZduAPj4xvij72gHGu3Ywm31KVGLVWk/mrMRiM9CINcA==} + engines: {node: '>=14.0.0'} + cpu: [x64] + os: [win32] + + '@oxc-parser/wasm@0.56.5': + resolution: {integrity: sha512-9vtn56ok7PHS0elihFP+Q+alveQuGR0vnF6OeZesxkKWLJr8mCk0kZJx5ZxLjibaPA/sxWTmOyn31UMM9jg9fg==} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + + '@oxc-project/types@0.56.5': + resolution: {integrity: sha512-skY3kOJwp22W4RkaadH1hZ3hqFHjkRrIIE0uQ4VUg+/Chvbl+2pF+B55IrIk2dgsKXS57YEUsJuN6I6s4rgFjA==} + + '@parcel/watcher-android-arm64@2.4.1': + resolution: {integrity: sha512-LOi/WTbbh3aTn2RYddrO8pnapixAziFl6SMxHM69r3tvdSm94JtCenaKgk1GRg5FJ5wpMCpHeW+7yqPlvZv7kg==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [android] + + '@parcel/watcher-android-arm64@2.5.1': + resolution: {integrity: sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [android] + + '@parcel/watcher-darwin-arm64@2.4.1': + resolution: {integrity: sha512-ln41eihm5YXIY043vBrrHfn94SIBlqOWmoROhsMVTSXGh0QahKGy77tfEywQ7v3NywyxBBkGIfrWRHm0hsKtzA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [darwin] + + '@parcel/watcher-darwin-arm64@2.5.1': + resolution: {integrity: sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [darwin] + + '@parcel/watcher-darwin-x64@2.4.1': + resolution: {integrity: sha512-yrw81BRLjjtHyDu7J61oPuSoeYWR3lDElcPGJyOvIXmor6DEo7/G2u1o7I38cwlcoBHQFULqF6nesIX3tsEXMg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [darwin] + + '@parcel/watcher-darwin-x64@2.5.1': + resolution: {integrity: sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [darwin] + + '@parcel/watcher-freebsd-x64@2.4.1': + resolution: {integrity: sha512-TJa3Pex/gX3CWIx/Co8k+ykNdDCLx+TuZj3f3h7eOjgpdKM+Mnix37RYsYU4LHhiYJz3DK5nFCCra81p6g050w==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [freebsd] + + '@parcel/watcher-freebsd-x64@2.5.1': + resolution: {integrity: sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [freebsd] + + '@parcel/watcher-linux-arm-glibc@2.4.1': + resolution: {integrity: sha512-4rVYDlsMEYfa537BRXxJ5UF4ddNwnr2/1O4MHM5PjI9cvV2qymvhwZSFgXqbS8YoTk5i/JR0L0JDs69BUn45YA==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + + '@parcel/watcher-linux-arm-glibc@2.5.1': + resolution: {integrity: sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + + '@parcel/watcher-linux-arm-musl@2.5.1': + resolution: {integrity: sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + + '@parcel/watcher-linux-arm64-glibc@2.4.1': + resolution: {integrity: sha512-BJ7mH985OADVLpbrzCLgrJ3TOpiZggE9FMblfO65PlOCdG++xJpKUJ0Aol74ZUIYfb8WsRlUdgrZxKkz3zXWYA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + + '@parcel/watcher-linux-arm64-glibc@2.5.1': + resolution: {integrity: sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + + '@parcel/watcher-linux-arm64-musl@2.4.1': + resolution: {integrity: sha512-p4Xb7JGq3MLgAfYhslU2SjoV9G0kI0Xry0kuxeG/41UfpjHGOhv7UoUDAz/jb1u2elbhazy4rRBL8PegPJFBhA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + + '@parcel/watcher-linux-arm64-musl@2.5.1': + resolution: {integrity: sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + + '@parcel/watcher-linux-x64-glibc@2.4.1': + resolution: {integrity: sha512-s9O3fByZ/2pyYDPoLM6zt92yu6P4E39a03zvO0qCHOTjxmt3GHRMLuRZEWhWLASTMSrrnVNWdVI/+pUElJBBBg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + + '@parcel/watcher-linux-x64-glibc@2.5.1': + resolution: {integrity: sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + + '@parcel/watcher-linux-x64-musl@2.4.1': + resolution: {integrity: sha512-L2nZTYR1myLNST0O632g0Dx9LyMNHrn6TOt76sYxWLdff3cB22/GZX2UPtJnaqQPdCRoszoY5rcOj4oMTtp5fQ==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + + '@parcel/watcher-linux-x64-musl@2.5.1': + resolution: {integrity: sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + + '@parcel/watcher-wasm@2.4.1': + resolution: {integrity: sha512-/ZR0RxqxU/xxDGzbzosMjh4W6NdYFMqq2nvo2b8SLi7rsl/4jkL8S5stIikorNkdR50oVDvqb/3JT05WM+CRRA==} + engines: {node: '>= 10.0.0'} + bundledDependencies: + - napi-wasm + + '@parcel/watcher-wasm@2.5.1': + resolution: {integrity: sha512-RJxlQQLkaMMIuWRozy+z2vEqbaQlCuaCgVZIUCzQLYggY22LZbP5Y1+ia+FD724Ids9e+XIyOLXLrLgQSHIthw==} + engines: {node: '>= 10.0.0'} + bundledDependencies: + - napi-wasm + + '@parcel/watcher-win32-arm64@2.4.1': + resolution: {integrity: sha512-Uq2BPp5GWhrq/lcuItCHoqxjULU1QYEcyjSO5jqqOK8RNFDBQnenMMx4gAl3v8GiWa59E9+uDM7yZ6LxwUIfRg==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [win32] + + '@parcel/watcher-win32-arm64@2.5.1': + resolution: {integrity: sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [win32] + + '@parcel/watcher-win32-ia32@2.4.1': + resolution: {integrity: sha512-maNRit5QQV2kgHFSYwftmPBxiuK5u4DXjbXx7q6eKjq5dsLXZ4FJiVvlcw35QXzk0KrUecJmuVFbj4uV9oYrcw==} + engines: {node: '>= 10.0.0'} + cpu: [ia32] + os: [win32] + + '@parcel/watcher-win32-ia32@2.5.1': + resolution: {integrity: sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==} + engines: {node: '>= 10.0.0'} + cpu: [ia32] + os: [win32] + + '@parcel/watcher-win32-x64@2.4.1': + resolution: {integrity: sha512-+DvS92F9ezicfswqrvIRM2njcYJbd5mb9CUgtrHCHmvn7pPPa+nMDRu1o1bYYz/l5IB2NVGNJWiH7h1E58IF2A==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [win32] + + '@parcel/watcher-win32-x64@2.5.1': + resolution: {integrity: sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [win32] + + '@parcel/watcher@2.4.1': + resolution: {integrity: sha512-HNjmfLQEVRZmHRET336f20H/8kOozUGwk7yajvsonjNxbj2wBTK1WsQuHkD5yYh9RxFGL2EyDHryOihOwUoKDA==} + engines: {node: '>= 10.0.0'} + + '@parcel/watcher@2.5.1': + resolution: {integrity: sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==} + engines: {node: '>= 10.0.0'} + + '@paulmillr/qr@0.2.1': + resolution: {integrity: sha512-IHnV6A+zxU7XwmKFinmYjUcwlyK9+xkG3/s9KcQhI9BjQKycrJ1JRO+FbNYPwZiPKW3je/DR0k7w8/gLa5eaxQ==} + deprecated: 'The package is now available as "qr": npm install qr' + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@polka/url@1.0.0-next.29': + resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} + + '@poppinss/colors@4.1.4': + resolution: {integrity: sha512-FA+nTU8p6OcSH4tLDY5JilGYr1bVWHpNmcLr7xmMEdbWmKHa+3QZ+DqefrXKmdjO/brHTnQZo20lLSjaO7ydog==} + engines: {node: '>=18.16.0'} + + '@poppinss/dumper@0.6.3': + resolution: {integrity: sha512-iombbn8ckOixMtuV1p3f8jN6vqhXefNjJttoPaJDMeIk/yIGhkkL3OrHkEjE9SRsgoAx1vBUU2GtgggjvA5hCA==} + + '@poppinss/exception@1.2.1': + resolution: {integrity: sha512-aQypoot0HPSJa6gDPEPTntc1GT6QINrSbgRlRhadGW2WaYqUK3tK4Bw9SBMZXhmxd3GeAlZjVcODHgiu+THY7A==} + engines: {node: '>=18'} + + '@publint/pack@0.1.2': + resolution: {integrity: sha512-S+9ANAvUmjutrshV4jZjaiG8XQyuJIZ8a4utWmN/vW1sgQ9IfBnPndwkmQYw53QmouOIytT874u65HEmu6H5jw==} + engines: {node: '>=18'} + + '@reown/appkit-common@1.7.3': + resolution: {integrity: sha512-wKTr6N3z8ly17cc51xBEVkZK4zAd8J1m7RubgsdQ1olFY9YJGe61RYoNv9yFjt6tUVeYT+z7iMUwPhX2PziefQ==} + + '@reown/appkit-controllers@1.7.3': + resolution: {integrity: sha512-aqAcX/nZe0gwqjncyCkVrAk3lEw0qZ9xGrdLOmA207RreO4J0Vxu8OJXCBn4C2AUI2OpBxCPah+vyuKTUJTeHQ==} + + '@reown/appkit-polyfills@1.7.3': + resolution: {integrity: sha512-vQUiAyI7WiNTUV4iNwv27iigdeg8JJTEo6ftUowIrKZ2/gtE2YdMtGpavuztT/qrXhrIlTjDGp5CIyv9WOTu4g==} + + '@reown/appkit-scaffold-ui@1.7.3': + resolution: {integrity: sha512-ssB15fcjmoKQ+VfoCo7JIIK66a4SXFpCH8uK1CsMmXmKIKqPN54ohLo291fniV6mKtnJxh5Xm68slGtGrO3bmA==} + + '@reown/appkit-ui@1.7.3': + resolution: {integrity: sha512-zKmFIjLp0X24pF9KtPtSHmdsh/RjEWIvz+faIbPGm4tQbwcxdg9A35HeoP0rMgKYx49SX51LgPwVXne2gYacqQ==} + + '@reown/appkit-utils@1.7.3': + resolution: {integrity: sha512-8/MNhmfri+2uu8WzBhZ5jm5llofOIa1dyXDXRC/hfrmGmCFJdrQKPpuqOFYoimo2s2g70pK4PYefvOKgZOWzgg==} + + '@reown/appkit-wallet@1.7.3': + resolution: {integrity: sha512-D0pExd0QUE71ursQPp3pq/0iFrz2oz87tOyFifrPANvH5X0RQCYn/34/kXr+BFVQzNFfCBDlYP+CniNA/S0KiQ==} + + '@reown/appkit@1.7.3': + resolution: {integrity: sha512-aA/UIwi/dVzxEB62xlw3qxHa3RK1YcPMjNxoGj/fHNCqL2qWmbcOXT7coCUa9RG7/Bh26FZ3vdVT2v71j6hebQ==} + + '@rolldown/pluginutils@1.0.0-beta.9': + resolution: {integrity: sha512-e9MeMtVWo186sgvFFJOPGy7/d2j2mZhLJIdVW0C/xDluuOvymEATqz6zKsP0ZmXGzQtqlyjz5sC1sYQUoJG98w==} + + '@rollup/plugin-alias@5.1.1': + resolution: {integrity: sha512-PR9zDb+rOzkRb2VD+EuKB7UC41vU5DIwZ5qqCpk0KJudcWAyi8rvYOhS7+L5aZCspw1stTViLgN5v6FF1p5cgQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-commonjs@28.0.3': + resolution: {integrity: sha512-pyltgilam1QPdn+Zd9gaCfOLcnjMEJ9gV+bTw6/r73INdvzf1ah9zLIJBm+kW7R6IUFIQ1YO+VqZtYxZNWFPEQ==} + engines: {node: '>=16.0.0 || 14 >= 14.17'} + peerDependencies: + rollup: ^2.68.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-inject@5.0.5': + resolution: {integrity: sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-json@6.1.0': + resolution: {integrity: sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-node-resolve@16.0.1': + resolution: {integrity: sha512-tk5YCxJWIG81umIvNkSod2qK5KyQW19qcBF/B78n1bjtOON6gzKoVeSzAE8yHCZEDmqkHKkxplExA8KzdJLJpA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.78.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-replace@6.0.2': + resolution: {integrity: sha512-7QaYCf8bqF04dOy7w/eHmJeNExxTYwvKAmlSAH/EaWWUzbT0h5sbF6bktFoX/0F/0qwng5/dWFMyf3gzaM8DsQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-terser@0.4.4': + resolution: {integrity: sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/pluginutils@5.1.0': + resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/pluginutils@5.1.4': + resolution: {integrity: sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/rollup-android-arm-eabi@4.41.0': + resolution: {integrity: sha512-KxN+zCjOYHGwCl4UCtSfZ6jrq/qi88JDUtiEFk8LELEHq2Egfc/FgW+jItZiOLRuQfb/3xJSgFuNPC9jzggX+A==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.41.0': + resolution: {integrity: sha512-yDvqx3lWlcugozax3DItKJI5j05B0d4Kvnjx+5mwiUpWramVvmAByYigMplaoAQ3pvdprGCTCE03eduqE/8mPQ==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.41.0': + resolution: {integrity: sha512-2KOU574vD3gzcPSjxO0eyR5iWlnxxtmW1F5CkNOHmMlueKNCQkxR6+ekgWyVnz6zaZihpUNkGxjsYrkTJKhkaw==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.41.0': + resolution: {integrity: sha512-gE5ACNSxHcEZyP2BA9TuTakfZvULEW4YAOtxl/A/YDbIir/wPKukde0BNPlnBiP88ecaN4BJI2TtAd+HKuZPQQ==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.41.0': + resolution: {integrity: sha512-GSxU6r5HnWij7FoSo7cZg3l5GPg4HFLkzsFFh0N/b16q5buW1NAWuCJ+HMtIdUEi6XF0qH+hN0TEd78laRp7Dg==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.41.0': + resolution: {integrity: sha512-KGiGKGDg8qLRyOWmk6IeiHJzsN/OYxO6nSbT0Vj4MwjS2XQy/5emsmtoqLAabqrohbgLWJ5GV3s/ljdrIr8Qjg==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.41.0': + resolution: {integrity: sha512-46OzWeqEVQyX3N2/QdiU/CMXYDH/lSHpgfBkuhl3igpZiaB3ZIfSjKuOnybFVBQzjsLwkus2mjaESy8H41SzvA==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.41.0': + resolution: {integrity: sha512-lfgW3KtQP4YauqdPpcUZHPcqQXmTmH4nYU0cplNeW583CMkAGjtImw4PKli09NFi2iQgChk4e9erkwlfYem6Lg==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.41.0': + resolution: {integrity: sha512-nn8mEyzMbdEJzT7cwxgObuwviMx6kPRxzYiOl6o/o+ChQq23gfdlZcUNnt89lPhhz3BYsZ72rp0rxNqBSfqlqw==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.41.0': + resolution: {integrity: sha512-l+QK99je2zUKGd31Gh+45c4pGDAqZSuWQiuRFCdHYC2CSiO47qUWsCcenrI6p22hvHZrDje9QjwSMAFL3iwXwQ==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loongarch64-gnu@4.41.0': + resolution: {integrity: sha512-WbnJaxPv1gPIm6S8O/Wg+wfE/OzGSXlBMbOe4ie+zMyykMOeqmgD1BhPxZQuDqwUN+0T/xOFtL2RUWBspnZj3w==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.41.0': + resolution: {integrity: sha512-eRDWR5t67/b2g8Q/S8XPi0YdbKcCs4WQ8vklNnUYLaSWF+Cbv2axZsp4jni6/j7eKvMLYCYdcsv8dcU+a6QNFg==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.41.0': + resolution: {integrity: sha512-TWrZb6GF5jsEKG7T1IHwlLMDRy2f3DPqYldmIhnA2DVqvvhY2Ai184vZGgahRrg8k9UBWoSlHv+suRfTN7Ua4A==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.41.0': + resolution: {integrity: sha512-ieQljaZKuJpmWvd8gW87ZmSFwid6AxMDk5bhONJ57U8zT77zpZ/TPKkU9HpnnFrM4zsgr4kiGuzbIbZTGi7u9A==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.41.0': + resolution: {integrity: sha512-/L3pW48SxrWAlVsKCN0dGLB2bi8Nv8pr5S5ocSM+S0XCn5RCVCXqi8GVtHFsOBBCSeR+u9brV2zno5+mg3S4Aw==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.41.0': + resolution: {integrity: sha512-XMLeKjyH8NsEDCRptf6LO8lJk23o9wvB+dJwcXMaH6ZQbbkHu2dbGIUindbMtRN6ux1xKi16iXWu6q9mu7gDhQ==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.41.0': + resolution: {integrity: sha512-m/P7LycHZTvSQeXhFmgmdqEiTqSV80zn6xHaQ1JSqwCtD1YGtwEK515Qmy9DcB2HK4dOUVypQxvhVSy06cJPEg==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.41.0': + resolution: {integrity: sha512-4yodtcOrFHpbomJGVEqZ8fzD4kfBeCbpsUy5Pqk4RluXOdsWdjLnjhiKy2w3qzcASWd04fp52Xz7JKarVJ5BTg==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.41.0': + resolution: {integrity: sha512-tmazCrAsKzdkXssEc65zIE1oC6xPHwfy9d5Ta25SRCDOZS+I6RypVVShWALNuU9bxIfGA0aqrmzlzoM5wO5SPQ==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.41.0': + resolution: {integrity: sha512-h1J+Yzjo/X+0EAvR2kIXJDuTuyT7drc+t2ALY0nIcGPbTatNOf0VWdhEA2Z4AAjv6X1NJV7SYo5oCTYRJhSlVA==} + cpu: [x64] + os: [win32] + + '@safe-global/safe-apps-provider@0.18.6': + resolution: {integrity: sha512-4LhMmjPWlIO8TTDC2AwLk44XKXaK6hfBTWyljDm0HQ6TWlOEijVWNrt2s3OCVMSxlXAcEzYfqyu1daHZooTC2Q==} + + '@safe-global/safe-apps-sdk@9.1.0': + resolution: {integrity: sha512-N5p/ulfnnA2Pi2M3YeWjULeWbjo7ei22JwU/IXnhoHzKq3pYCN6ynL9mJBOlvDVv892EgLPCWCOwQk/uBT2v0Q==} + + '@safe-global/safe-gateway-typescript-sdk@3.8.0': + resolution: {integrity: sha512-CiGWIHgIaOdICpDxp05Jw3OPslWTu8AnL0PhrCT1xZgIO86NlMMLzkGbeycJ4FHpTjA999O791Oxp4bZPIjgHA==} + + '@scure/base@1.1.3': + resolution: {integrity: sha512-/+SgoRjLq7Xlf0CWuLHq2LUZeL/w65kfzAPG5NH9pcmBhs+nunQTn4gvdwgMTIXnt9b2C/1SeL2XiysZEyIC9Q==} + + '@scure/base@1.1.9': + resolution: {integrity: sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==} + + '@scure/base@1.2.4': + resolution: {integrity: sha512-5Yy9czTO47mqz+/J8GM6GIId4umdCk1wc1q8rKERQulIoc8VP9pzDcghv10Tl2E7R96ZUx/PhND3ESYUQX8NuQ==} + + '@scure/base@1.2.6': + resolution: {integrity: sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==} + + '@scure/bip32@1.1.5': + resolution: {integrity: sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==} + + '@scure/bip32@1.3.2': + resolution: {integrity: sha512-N1ZhksgwD3OBlwTv3R6KFEcPojl/W4ElJOeCZdi+vuI5QmTFwLq3OFf2zd2ROpKvxFdgZ6hUpb0dx9bVNEwYCA==} + + '@scure/bip32@1.4.0': + resolution: {integrity: sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==} + + '@scure/bip32@1.6.2': + resolution: {integrity: sha512-t96EPDMbtGgtb7onKKqxRLfE5g05k7uHnHRM2xdE6BP/ZmxaLtPek4J4KfVn/90IQNrU1IOAqMgiDtUdtbe3nw==} + + '@scure/bip39@1.1.1': + resolution: {integrity: sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==} + + '@scure/bip39@1.2.1': + resolution: {integrity: sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==} + + '@scure/bip39@1.3.0': + resolution: {integrity: sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==} + + '@scure/bip39@1.5.4': + resolution: {integrity: sha512-TFM4ni0vKvCfBpohoh+/lY05i9gRbSwXWngAsF4CABQxoaOHijxuaZ2R6cStDQ5CHtHO9aGJTr4ksVJASRRyMA==} + + '@sec-ant/readable-stream@0.4.1': + resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} + + '@sentry/core@5.30.0': + resolution: {integrity: sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==} + engines: {node: '>=6'} + + '@sentry/hub@5.30.0': + resolution: {integrity: sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==} + engines: {node: '>=6'} + + '@sentry/minimal@5.30.0': + resolution: {integrity: sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==} + engines: {node: '>=6'} + + '@sentry/node@5.30.0': + resolution: {integrity: sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==} + engines: {node: '>=6'} + + '@sentry/tracing@5.30.0': + resolution: {integrity: sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==} + engines: {node: '>=6'} + + '@sentry/types@5.30.0': + resolution: {integrity: sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==} + engines: {node: '>=6'} + + '@sentry/utils@5.30.0': + resolution: {integrity: sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==} + engines: {node: '>=6'} + + '@shikijs/core@1.22.2': + resolution: {integrity: sha512-bvIQcd8BEeR1yFvOYv6HDiyta2FFVePbzeowf5pPS1avczrPK+cjmaxxh0nx5QzbON7+Sv0sQfQVciO7bN72sg==} + + '@shikijs/engine-javascript@1.22.2': + resolution: {integrity: sha512-iOvql09ql6m+3d1vtvP8fLCVCK7BQD1pJFmHIECsujB0V32BJ0Ab6hxk1ewVSMFA58FI0pR2Had9BKZdyQrxTw==} + + '@shikijs/engine-oniguruma@1.22.2': + resolution: {integrity: sha512-GIZPAGzQOy56mGvWMoZRPggn0dTlBf1gutV5TdceLCZlFNqWmuc7u+CzD0Gd9vQUTgLbrt0KLzz6FNprqYAxlA==} + + '@shikijs/transformers@1.22.2': + resolution: {integrity: sha512-8f78OiBa6pZDoZ53lYTmuvpFPlWtevn23bzG+azpPVvZg7ITax57o/K3TC91eYL3OMJOO0onPbgnQyZjRos8XQ==} + + '@shikijs/twoslash@1.22.2': + resolution: {integrity: sha512-4R3A7aH/toZgtlveXHKk01nIsvn8hjAfPJ1aT550zcV4qK6vK/tfaEyYtaljOaY1wig2l5+8sKjNSEz3PcSiEw==} + + '@shikijs/types@1.22.2': + resolution: {integrity: sha512-NCWDa6LGZqTuzjsGfXOBWfjS/fDIbDdmVDug+7ykVe1IKT4c1gakrvlfFYp5NhAXH/lyqLM8wsAPo5wNy73Feg==} + + '@shikijs/vitepress-twoslash@1.22.2': + resolution: {integrity: sha512-F4cS9l6QTt/ILlz+S871bOido2CK8Xwdnl4q9gHdnTuZlN1PHAMRZbAOvYAtokvouPp9aZ2W7NtNa+CNCn3yPQ==} + + '@shikijs/vscode-textmate@9.3.0': + resolution: {integrity: sha512-jn7/7ky30idSkd/O5yDBfAnVt+JJpepofP/POZ1iMOxK59cOfqIgg/Dj0eFsjOTMw+4ycJN0uhZH/Eb0bs/EUA==} + + '@sindresorhus/is@4.6.0': + resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} + engines: {node: '>=10'} + + '@sindresorhus/is@7.0.1': + resolution: {integrity: sha512-QWLl2P+rsCJeofkDNIT3WFmb6NrRud1SUYW8dIhXK/46XFV8Q/g7Bsvib0Askb0reRLe+WYPeeE+l5cH7SlkuQ==} + engines: {node: '>=18'} + + '@sindresorhus/merge-streams@2.3.0': + resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==} + engines: {node: '>=18'} + + '@sindresorhus/merge-streams@4.0.0': + resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} + engines: {node: '>=18'} + + '@snyk/github-codeowners@1.1.0': + resolution: {integrity: sha512-lGFf08pbkEac0NYgVf4hdANpAgApRjNByLXB+WBip3qj1iendOIyAwP2GKkKbQMNVy2r1xxDf0ssfWscoiC+Vw==} + engines: {node: '>=8.10'} + hasBin: true + + '@socket.io/component-emitter@3.1.2': + resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==} + + '@speed-highlight/core@1.2.7': + resolution: {integrity: sha512-0dxmVj4gxg3Jg879kvFS/msl4s9F3T9UXC1InxgOf7t5NvcPD97u/WTA5vL/IxWHMn7qSxBozqrnnE2wvl1m8g==} + + '@swc/counter@0.1.3': + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + + '@swc/helpers@0.5.15': + resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} + + '@tanstack/match-sorter-utils@8.15.1': + resolution: {integrity: sha512-PnVV3d2poenUM31ZbZi/yXkBu3J7kd5k2u51CGwwNojag451AjTH9N6n41yjXz2fpLeewleyLBmNS6+HcGDlXw==} + engines: {node: '>=12'} + + '@tanstack/query-core@5.0.5': + resolution: {integrity: sha512-MThCETMkHDHTnFZHp71L+SqTtD5d6XHftFCVR1xRJdWM3qGrlQ2VCXaj0SKVcyJej2e1Opa2c7iknu1llxCDNQ==} + + '@tanstack/query-core@5.49.1': + resolution: {integrity: sha512-JnC9ndmD1KKS01Rt/ovRUB1tmwO7zkyXAyIxN9mznuJrcNtOrkmOnQqdJF2ib9oHzc2VxHomnEG7xyfo54Npkw==} + + '@tanstack/query-devtools@5.0.5': + resolution: {integrity: sha512-xjuOhOrrO50sPoJ4WG9yPe3imQ0Ds/nutnmwdTqjM2ZTIkflh//p7q2iB6IxFBY9sB106h+PULlma8sgTuOKAQ==} + + '@tanstack/query-persist-client-core@5.0.5': + resolution: {integrity: sha512-xdxDiSN/gBG1QJBiyNZPv2y1DOBMrILvhrEd9PgtOzE1AswmgVUh96KENiD7QiABKCVVIihDtSDvJGj0ukbudg==} + + '@tanstack/query-sync-storage-persister@5.0.5': + resolution: {integrity: sha512-uk2/mcNf+YYVza3XaU61RSPCcIi/p+0DfsZWMyIim1yCxF7hzZ17zWheM/2v3zZbeTY/C6m1NIO9KIRiPAM9Mg==} + + '@tanstack/react-query-devtools@5.0.5': + resolution: {integrity: sha512-vJyS7HXx2zw43TQjm3m4uyaNUgGizOpK2SZL9Lc+DZSuhFbuZ55UEYJTz8yudCbHdLXlkuVZwo6TWWOhXWJFeA==} + peerDependencies: + '@tanstack/react-query': ^5.0.5 + react: ^18.0.0 + react-dom: ^18.0.0 + + '@tanstack/react-query-persist-client@5.0.5': + resolution: {integrity: sha512-V/jIKdiw0WyJYpnzwnKS+O19jgJPWSBDzvx9qFaXAm98Jnt+lGWFBZdUR0MgY2ufM1fbeejXTjcorgwqjc3kaA==} + peerDependencies: + '@tanstack/react-query': ^5.0.5 + react: ^18.0.0 + react-dom: ^18.0.0 + + '@tanstack/react-query@5.49.2': + resolution: {integrity: sha512-6rfwXDK9BvmHISbNFuGd+wY3P44lyW7lWiA9vIFGT/T0P9aHD1VkjTvcM4SDAIbAQ9ygEZZoLt7dlU1o3NjMVA==} + peerDependencies: + react: ^18.0.0 + + '@tanstack/vue-query@5.49.1': + resolution: {integrity: sha512-/nTqP8PNCRzMcqTGEuFQE3ntUD3A+K05r6Dw/0hNwNS3PLEaKUKlxytmAhIoaoloQwbbAghjLyKRQZ+CMWv90A==} + peerDependencies: + '@vue/composition-api': ^1.1.2 + vue: ^2.6.0 || ^3.3.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + + '@testing-library/dom@10.4.0': + resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==} + engines: {node: '>=18'} + + '@testing-library/react@16.0.1': + resolution: {integrity: sha512-dSmwJVtJXmku+iocRhWOUFbrERC76TX2Mnf0ATODz8brzAZrMBbzLwQixlBSanZxR6LddK3eiwpSFZgDET1URg==} + engines: {node: '>=18'} + peerDependencies: + '@testing-library/dom': ^10.0.0 + '@types/react': ^18.0.0 + '@types/react-dom': ^18.0.0 + react: ^18.0.0 + react-dom: ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@trysound/sax@0.2.0': + resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} + engines: {node: '>=10.13.0'} + + '@tybys/wasm-util@0.9.0': + resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==} + + '@types/aria-query@5.0.4': + resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} + + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.6.5': + resolution: {integrity: sha512-h9yIuWbJKdOPLJTbmSpPzkF67e659PbQDba7ifWm5BJ8xTv+sDmS7rFmywkWOvXedGTivCdeGSIIX8WLcRTz8w==} + + '@types/babel__template@7.4.2': + resolution: {integrity: sha512-/AVzPICMhMOMYoSx9MoKpGDKdBRsIXMNByh1PXSZoa+v6ZoLa8xxtsT/uLQ/NJm0XVAWl/BvId4MlDeXJaeIZQ==} + + '@types/babel__traverse@7.20.2': + resolution: {integrity: sha512-ojlGK1Hsfce93J0+kn3H5R73elidKUaZonirN33GSmgTUMpzI/MIFfSpF3haANe3G1bEBS9/9/QEqwTzwqFsKw==} + + '@types/bn.js@4.11.6': + resolution: {integrity: sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==} + + '@types/bn.js@5.1.5': + resolution: {integrity: sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A==} + + '@types/bun@1.1.10': + resolution: {integrity: sha512-76KYVSwrHwr9zsnk6oLXOGs9KvyBg3U066GLO4rk6JZk1ypEPGCUDZ5yOiESyIHWs9cx9iC8r01utYN32XdmgA==} + + '@types/cookie@0.6.0': + resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} + + '@types/cross-spawn@6.0.6': + resolution: {integrity: sha512-fXRhhUkG4H3TQk5dBhQ7m/JDdSNHKwR2BBia62lhwEIq9xGiQKLxd6LymNhn47SjXhsUEPmxi+PKw2OkW4LLjA==} + + '@types/debug@4.1.12': + resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + + '@types/debug@4.1.7': + resolution: {integrity: sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==} + + '@types/dedent@0.7.2': + resolution: {integrity: sha512-kRiitIeUg1mPV9yH4VUJ/1uk2XjyANfeL8/7rH1tsjvHeO9PJLBHJIYsFWmAvmGj5u8rj+1TZx7PZzW2qLw3Lw==} + + '@types/estree@1.0.5': + resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + + '@types/estree@1.0.7': + resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} + + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + + '@types/linkify-it@5.0.0': + resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} + + '@types/lru-cache@5.1.1': + resolution: {integrity: sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==} + + '@types/markdown-it@14.1.2': + resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==} + + '@types/mdast@4.0.3': + resolution: {integrity: sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==} + + '@types/mdurl@2.0.0': + resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} + + '@types/ms@0.7.31': + resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + + '@types/mute-stream@0.0.4': + resolution: {integrity: sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==} + + '@types/node@12.20.55': + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + + '@types/node@20.12.10': + resolution: {integrity: sha512-Eem5pH9pmWBHoGAT8Dr5fdc5rYA+4NAovdM4EktRPVAAiJhmWWfQrA0cFhAbOsQdSfIHjAud6YdkbL69+zSKjw==} + + '@types/node@20.12.14': + resolution: {integrity: sha512-scnD59RpYD91xngrQQLGkE+6UrHUPzeKZWhhjBSa3HSkwjbQc38+q3RoIVEwxQGRw3M+j5hpNAM+lgV3cVormg==} + + '@types/node@20.19.0': + resolution: {integrity: sha512-hfrc+1tud1xcdVTABC2JiomZJEklMcXYNTVtZLAeqTVWD+qL5jkHKT+1lOtqDdGxt+mB53DTtiz673vfjU8D1Q==} + + '@types/node@22.15.31': + resolution: {integrity: sha512-jnVe5ULKl6tijxUhvQeNbQG/84fHfg+yMak02cT8QVhBx/F05rAVxCGBYYTh2EKz22D6JF5ktXuNwdx7b9iEGw==} + + '@types/node@24.0.1': + resolution: {integrity: sha512-MX4Zioh39chHlDJbKmEgydJDS3tspMP/lnQC67G3SWsTnb9NeYVWOjkxpOSy4oMfPs4StcWHwBrvUb4ybfnuaw==} + + '@types/normalize-package-data@2.4.4': + resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + + '@types/parse-path@7.1.0': + resolution: {integrity: sha512-EULJ8LApcVEPbrfND0cRQqutIOdiIgJ1Mgrhpy755r14xMohPTEpkV/k28SJvuOs9bHRFW8x+KeDAEPiGQPB9Q==} + deprecated: This is a stub types definition. parse-path provides its own type definitions, so you do not need this installed. + + '@types/pbkdf2@3.1.2': + resolution: {integrity: sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew==} + + '@types/prompts@2.4.9': + resolution: {integrity: sha512-qTxFi6Buiu8+50/+3DGIWLHM6QuWsEKugJnnP6iv2Mc4ncxE4A/OJkjuVOA+5X0X1S/nq5VJRa8Lu+nwcvbrKA==} + + '@types/prop-types@15.7.5': + resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} + + '@types/react-dom@18.3.0': + resolution: {integrity: sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==} + + '@types/react@18.3.1': + resolution: {integrity: sha512-V0kuGBX3+prX+DQ/7r2qsv1NsdfnCLnTgnRJ1pYnxykBhGMz+qj+box5lq7XsO5mtZsBqpjwwTu/7wszPfMBcw==} + + '@types/resolve@1.20.2': + resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} + + '@types/secp256k1@4.0.3': + resolution: {integrity: sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==} + + '@types/semver@7.5.3': + resolution: {integrity: sha512-OxepLK9EuNEIPxWNME+C6WwbRAOOI2o2BaQEGzz5Lu2e4Z5eDnEo+/aVEDMIXywoJitJ7xWd641wrGLZdtwRyw==} + + '@types/statuses@2.0.4': + resolution: {integrity: sha512-eqNDvZsCNY49OAXB0Firg/Sc2BgoWsntsLUdybGFOhAfCD6QJ2n9HXUIHGqt5qjrxmMv4wS8WLAw43ZkKcJ8Pw==} + + '@types/tough-cookie@4.0.5': + resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} + + '@types/triple-beam@1.3.5': + resolution: {integrity: sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==} + + '@types/trusted-types@2.0.3': + resolution: {integrity: sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==} + + '@types/unist@3.0.2': + resolution: {integrity: sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==} + + '@types/use-sync-external-store@0.0.6': + resolution: {integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==} + + '@types/web-bluetooth@0.0.20': + resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==} + + '@types/wrap-ansi@3.0.0': + resolution: {integrity: sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==} + + '@types/ws@8.5.10': + resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==} + + '@types/yauzl@2.10.3': + resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} + + '@typescript-eslint/types@5.62.0': + resolution: {integrity: sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@typescript-eslint/typescript-estree@5.62.0': + resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/visitor-keys@5.62.0': + resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@typescript/vfs@1.6.0': + resolution: {integrity: sha512-hvJUjNVeBMp77qPINuUvYXj4FyWeeMMKZkxEATEU3hqBAQ7qdTBCUFT7Sp0Zu0faeEtFf+ldXxMEDr/bk73ISg==} + peerDependencies: + typescript: '*' + + '@ungap/structured-clone@1.2.0': + resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + + '@unhead/vue@2.0.9': + resolution: {integrity: sha512-0t8YXVXvEgXkXhCb22hqPrsgun3Jqul/ZvydgBY0SlEfEbC1ioL15/1QuJwBFG3us6OnSewjbDagg4Jh478g8g==} + peerDependencies: + vue: '>=3.5.13' + + '@unocss/astro@0.59.4': + resolution: {integrity: sha512-DU3OR5MMR1Uvvec4/wB9EetDASHRg19Moy6z/MiIhn8JWJ0QzWYgSeJcfUX8exomMYv6WUEQJL+CyLI34Wmn8w==} + peerDependencies: + vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 + peerDependenciesMeta: + vite: + optional: true + + '@unocss/cli@0.59.4': + resolution: {integrity: sha512-TT+WKedSifhsRqnpoYD2LfyYipVzEbzIU4DDGIaDNeDxGXYOGpb876zzkPDcvZSpI37IJ/efkkV7PGYpPBcQBQ==} + engines: {node: '>=14'} + hasBin: true + + '@unocss/config@0.59.4': + resolution: {integrity: sha512-h3yhj+D5Ygn5R7gbK4wMrtXZX6FF5DF6YD517sSSb0XB3lxHD9PhhT4HaV1hpHknvu0cMFU3460M45+TN1TI0Q==} + engines: {node: '>=14'} + + '@unocss/core@0.59.4': + resolution: {integrity: sha512-bBZ1sgcAtezQVZ1BST9IS3jqcsTLyqKNjiIf7FTnX3DHpfpYuMDFzSOtmkZDzBleOLO/CtcRWjT0HwTSQAmV0A==} + + '@unocss/extractor-arbitrary-variants@0.59.4': + resolution: {integrity: sha512-RDe4FgMGJQ+tp9GLvhPHni7Cc2O0lHBRMElVlN8LoXJAdODMICdbrEPGJlEfrc+7x/QgVFoR895KpYJh3hIgGA==} + + '@unocss/inspector@0.59.4': + resolution: {integrity: sha512-QczJFNDiggmekkJyNcbcZIUVwlhvxz7ZwjnSf0w7K4znxfjKkZ1hNUbqLviM1HumkTKOdT27VISW7saN/ysO4w==} + + '@unocss/postcss@0.59.4': + resolution: {integrity: sha512-KVz+AD7McHKp7VEWHbFahhyyVEo0oP/e1vnuNSuPlHthe+1V2zfH6lps+iJcvfL2072r5J+0PvD/1kOp5ryUSg==} + engines: {node: '>=14'} + + '@unocss/preset-attributify@0.59.4': + resolution: {integrity: sha512-BeogWuYaIakC1gmOZFFCjFVWmu/m3AqEX8UYQS6tY6lAaK2L4Qf4AstYBlT2zAMxy9LNxPDxFQrvfSfFk5Klsg==} + + '@unocss/preset-icons@0.59.4': + resolution: {integrity: sha512-Afjwh5oC4KRE8TNZDUkRK6hvvV1wKLrS1e5trniE0B0AM9HK3PBolQaIU7QmzPv6WQrog+MZgIwafg1eqsPUCA==} + + '@unocss/preset-mini@0.59.4': + resolution: {integrity: sha512-ZLywGrXi1OCr4My5vX2rLUb5Xgx6ufR9WTQOvpQJGBdIV/jnZn/pyE5avCs476SnOq2K172lnd8mFmTK7/zArA==} + + '@unocss/preset-tagify@0.59.4': + resolution: {integrity: sha512-vWMdTUoghOSmTbdmZtERssffmdUdOuhh4vUdl0R8Kv6KxB0PkvEFCu2FItn97nRJdSPlZSFxxDkaOIg9w+STNQ==} + + '@unocss/preset-typography@0.59.4': + resolution: {integrity: sha512-ZX9bxZUqlXK1qEDzO5lkK96ICt9itR/oNyn/7mMc1JPqwj263LumQMn5silocgzoLSUXEeq//L6GylqYjkL8GA==} + + '@unocss/preset-uno@0.59.4': + resolution: {integrity: sha512-G1f8ZluplvXZ3bERj+sM/8zzY//XD++nNOlAQNKOANSVht3qEoJebrfEiMClNpA5qW5VWOZhEhPkh0M7GsXtnA==} + + '@unocss/preset-web-fonts@0.59.4': + resolution: {integrity: sha512-ehutTjKHnf2KPmdatN42N9a8+y+glKSU3UlcBRNsVIIXVIlaBQuPVGZSPhnMtrKD17IgWylXq2K6RJK+ab0hZA==} + + '@unocss/preset-wind@0.59.4': + resolution: {integrity: sha512-CNX6w0ZpSQg/i1oF0/WKWzto8PtLqoknC5h8JmmcGb7VsyBQeV0oNnhbURxpbuMEhbv1MWVIGvk8a+P6y0rFkQ==} + + '@unocss/reset@0.59.4': + resolution: {integrity: sha512-Upy4xzdWl4RChbLAXBq1BoR4WqxXMoIfjvtcwSZcZK2sylXCFAseSWnyzJFdSiXPqNfmMuNgPXgiSxiQB+cmNA==} + + '@unocss/rule-utils@0.59.4': + resolution: {integrity: sha512-1qoLJlBWAkS4D4sg73990S1MT7E8E5md/YhopKjTQuEC9SyeVmEg+5pR/Xd8xhPKMqbcuBPl/DS8b6l/GQO56A==} + engines: {node: '>=14'} + + '@unocss/scope@0.59.4': + resolution: {integrity: sha512-wBQJ39kw4Tfj4km7AoGvSIobPKVnRZVsgc0bema5Y0PL3g1NeVQ/LopBI2zEJWdpxGXUWxSDsXm7BZo6qVlD/A==} + + '@unocss/transformer-attributify-jsx-babel@0.59.4': + resolution: {integrity: sha512-xtCRSgeTaDBiNJLVX7oOSFe63JiFB5nrdK23PHn3IlZM9O7Bxx4ZxI3MQJtFZFQNE+INFko+DVyY1WiFEm1p/Q==} + + '@unocss/transformer-attributify-jsx@0.59.4': + resolution: {integrity: sha512-m4b83utzKMfUQH/45V2QkjJoXd8Tu2pRP1nic91Xf7QRceyKDD+BxoTneo2JNC2K274cQu7HqqotnCm2aFfEGw==} + + '@unocss/transformer-compile-class@0.59.4': + resolution: {integrity: sha512-Vgk2OCLPW0pU+Uzr1IgDtHVspSBb+gPrQFkV+5gxHk9ZdKi3oYKxLuufVWYDSwv7o9yfQGbYrMH9YLsjRsnA7Q==} + + '@unocss/transformer-directives@0.59.4': + resolution: {integrity: sha512-nXUTEclUbs0vQ4KfLhKt4J/5SLSEq1az2FNlJmiXMmqmn75X89OrtCu2OJu9sGXhn+YyBApxgcSSdxmtpqMi1Q==} + + '@unocss/transformer-variant-group@0.59.4': + resolution: {integrity: sha512-9XLixxn1NRgP62Kj4R/NC/rpqhql5F2s6ulJ8CAMTEbd/NylVhEANluPGDVUGcLJ4cj6E02hFa8C1PLGSm7/xw==} + + '@unocss/vite@0.59.4': + resolution: {integrity: sha512-q7GN7vkQYn79n7vYIUlaa7gXGwc7pk0Qo3z3ZFwWGE43/DtZnn2Hwl5UjgBAgi9McA+xqHJEHRsJnI7HJPHUYA==} + peerDependencies: + vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 + + '@vercel/nft@0.27.7': + resolution: {integrity: sha512-FG6H5YkP4bdw9Ll1qhmbxuE8KwW2E/g8fJpM183fWQLeVDGqzeywMIeJ9h2txdWZ03psgWMn6QymTxaDLmdwUg==} + engines: {node: '>=16'} + hasBin: true + + '@vercel/nft@0.29.3': + resolution: {integrity: sha512-aVV0E6vJpuvImiMwU1/5QKkw2N96BRFE7mBYGS7FhXUoS6V7SarQ+8tuj33o7ofECz8JtHpmQ9JW+oVzOoB7MA==} + engines: {node: '>=18'} + hasBin: true + + '@vitejs/plugin-react@4.2.1': + resolution: {integrity: sha512-oojO9IDc4nCUUi8qIR11KoQm0XFFLIwsRBwHRR4d/88IWghn1y6ckz/bJ8GHDCsYEJee8mDzqtJxh15/cisJNQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.2.0 || ^5.0.0 + + '@vitejs/plugin-vue-jsx@4.2.0': + resolution: {integrity: sha512-DSTrmrdLp+0LDNF77fqrKfx7X0ErRbOcUAgJL/HbSesqQwoUvUQ4uYQqaex+rovqgGcoPqVk+AwUh3v9CuiYIw==} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + vite: ^5.0.0 || ^6.0.0 + vue: ^3.0.0 + + '@vitejs/plugin-vue@5.0.4': + resolution: {integrity: sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ==} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + vite: ^5.0.0 + vue: ^3.2.25 + + '@vitejs/plugin-vue@5.1.4': + resolution: {integrity: sha512-N2XSI2n3sQqp5w7Y/AN/L2XDjBIRGqXko+eDp42sydYSBeJuSm5a1sLf8zakmo8u7tA8NmBgoDLA1HeOESjp9A==} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + vite: ^5.0.0 + vue: ^3.2.25 + + '@vitejs/plugin-vue@5.2.4': + resolution: {integrity: sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + vite: ^5.0.0 || ^6.0.0 + vue: ^3.2.25 + + '@vitest/coverage-v8@2.1.1': + resolution: {integrity: sha512-md/A7A3c42oTT8JUHSqjP5uKTWJejzUW4jalpvs+rZ27gsURsMU8DEb+8Jf8C6Kj2gwfSHJqobDNBuoqlm0cFw==} + peerDependencies: + '@vitest/browser': 2.1.1 + vitest: 2.1.1 + peerDependenciesMeta: + '@vitest/browser': + optional: true + + '@vitest/expect@2.1.9': + resolution: {integrity: sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==} + + '@vitest/mocker@2.1.9': + resolution: {integrity: sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg==} + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@2.1.9': + resolution: {integrity: sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==} + + '@vitest/runner@2.1.9': + resolution: {integrity: sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==} + + '@vitest/snapshot@2.1.9': + resolution: {integrity: sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==} + + '@vitest/spy@2.1.9': + resolution: {integrity: sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ==} + + '@vitest/utils@2.1.9': + resolution: {integrity: sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==} + + '@volar/language-core@2.2.1': + resolution: {integrity: sha512-iHJAZKcYldZgyS8gx6DfIZApViVBeqbf6iPhqoZpG5A6F4zsZiFldKfwaKaBA3/wnOTWE2i8VUbXywI1WywCPg==} + + '@volar/language-core@2.4.8': + resolution: {integrity: sha512-K/GxMOXGq997bO00cdFhTNuR85xPxj0BEEAy+BaqqayTmy9Tmhfgmq2wpJcVspRhcwfgPoE2/mEJa26emUhG/g==} + + '@volar/source-map@2.2.1': + resolution: {integrity: sha512-w1Bgpguhbp7YTr7VUFu6gb4iAZjeEPsOX4zpgiuvlldbzvIWDWy4t0jVifsIsxZ99HAu+c3swiME7wt+GeNqhA==} + + '@volar/source-map@2.4.8': + resolution: {integrity: sha512-jeWJBkC/WivdelMwxKkpFL811uH/jJ1kVxa+c7OvG48DXc3VrP7pplSWPP2W1dLMqBxD+awRlg55FQQfiup4cA==} + + '@volar/typescript@2.2.1': + resolution: {integrity: sha512-Z/tqluR7Hz5/5dCqQp7wo9C/6tSv/IYl+tTzgzUt2NjTq95bKSsuO4E+V06D0c+3aP9x5S9jggLqw451hpnc6Q==} + + '@vue-macros/common@1.16.1': + resolution: {integrity: sha512-Pn/AWMTjoMYuquepLZP813BIcq8DTZiNCoaceuNlvaYuOTd8DqBZWc5u0uOMQZMInwME1mdSmmBAcTluiV9Jtg==} + engines: {node: '>=16.14.0'} + peerDependencies: + vue: ^2.7.0 || ^3.2.25 + peerDependenciesMeta: + vue: + optional: true + + '@vue/babel-helper-vue-transform-on@1.4.0': + resolution: {integrity: sha512-mCokbouEQ/ocRce/FpKCRItGo+013tHg7tixg3DUNS+6bmIchPt66012kBMm476vyEIJPafrvOf4E5OYj3shSw==} + + '@vue/babel-plugin-jsx@1.4.0': + resolution: {integrity: sha512-9zAHmwgMWlaN6qRKdrg1uKsBKHvnUU+Py+MOCTuYZBoZsopa90Di10QRjB+YPnVss0BZbG/H5XFwJY1fTxJWhA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + peerDependenciesMeta: + '@babel/core': + optional: true + + '@vue/babel-plugin-resolve-type@1.4.0': + resolution: {integrity: sha512-4xqDRRbQQEWHQyjlYSgZsWj44KfiF6D+ktCuXyZ8EnVDYV3pztmXJDf1HveAjUAXxAnR8daCQT51RneWWxtTyQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@vue/compiler-core@3.4.27': + resolution: {integrity: sha512-E+RyqY24KnyDXsCuQrI+mlcdW3ALND6U7Gqa/+bVwbcpcR3BRRIckFoz7Qyd4TTlnugtwuI7YgjbvsLmxb+yvg==} + + '@vue/compiler-core@3.5.12': + resolution: {integrity: sha512-ISyBTRMmMYagUxhcpyEH0hpXRd/KqDU4ymofPgl2XAkY9ZhQ+h0ovEZJIiPop13UmR/54oA2cgMDjgroRelaEw==} + + '@vue/compiler-core@3.5.14': + resolution: {integrity: sha512-k7qMHMbKvoCXIxPhquKQVw3Twid3Kg4s7+oYURxLGRd56LiuHJVrvFKI4fm2AM3c8apqODPfVJGoh8nePbXMRA==} + + '@vue/compiler-dom@3.4.27': + resolution: {integrity: sha512-kUTvochG/oVgE1w5ViSr3KUBh9X7CWirebA3bezTbB5ZKBQZwR2Mwj9uoSKRMFcz4gSMzzLXBPD6KpCLb9nvWw==} + + '@vue/compiler-dom@3.5.12': + resolution: {integrity: sha512-9G6PbJ03uwxLHKQ3P42cMTi85lDRvGLB2rSGOiQqtXELat6uI4n8cNz9yjfVHRPIu+MsK6TE418Giruvgptckg==} + + '@vue/compiler-dom@3.5.14': + resolution: {integrity: sha512-1aOCSqxGOea5I80U2hQJvXYpPm/aXo95xL/m/mMhgyPUsKe9jhjwWpziNAw7tYRnbz1I61rd9Mld4W9KmmRoug==} + + '@vue/compiler-sfc@3.4.27': + resolution: {integrity: sha512-nDwntUEADssW8e0rrmE0+OrONwmRlegDA1pD6QhVeXxjIytV03yDqTey9SBDiALsvAd5U4ZrEKbMyVXhX6mCGA==} + + '@vue/compiler-sfc@3.5.12': + resolution: {integrity: sha512-2k973OGo2JuAa5+ZlekuQJtitI5CgLMOwgl94BzMCsKZCX/xiqzJYzapl4opFogKHqwJk34vfsaKpfEhd1k5nw==} + + '@vue/compiler-sfc@3.5.14': + resolution: {integrity: sha512-9T6m/9mMr81Lj58JpzsiSIjBgv2LiVoWjIVa7kuXHICUi8LiDSIotMpPRXYJsXKqyARrzjT24NAwttrMnMaCXA==} + + '@vue/compiler-ssr@3.4.27': + resolution: {integrity: sha512-CVRzSJIltzMG5FcidsW0jKNQnNRYC8bT21VegyMMtHmhW3UOI7knmUehzswXLrExDLE6lQCZdrhD4ogI7c+vuw==} + + '@vue/compiler-ssr@3.5.12': + resolution: {integrity: sha512-eLwc7v6bfGBSM7wZOGPmRavSWzNFF6+PdRhE+VFJhNCgHiF8AM7ccoqcv5kBXA2eWUfigD7byekvf/JsOfKvPA==} + + '@vue/compiler-ssr@3.5.14': + resolution: {integrity: sha512-Y0G7PcBxr1yllnHuS/NxNCSPWnRGH4Ogrp0tsLA5QemDZuJLs99YjAKQ7KqkHE0vCg4QTKlQzXLKCMF7WPSl7Q==} + + '@vue/compiler-vue2@2.7.16': + resolution: {integrity: sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==} + + '@vue/devtools-api@6.6.1': + resolution: {integrity: sha512-LgPscpE3Vs0x96PzSSB4IGVSZXZBZHpfxs+ZA1d+VEPwHdOXowy/Y2CsvCAIFrf+ssVU1pD1jidj505EpUnfbA==} + + '@vue/devtools-api@6.6.4': + resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==} + + '@vue/devtools-api@7.6.2': + resolution: {integrity: sha512-NCT0ujqlwAhoFvCsAG7G5qS8w/A/dhvFSt2BhmNxyqgpYDrf9CG1zYyWLQkE3dsZ+5lCT6ULUic2VKNaE07Vzg==} + + '@vue/devtools-core@7.7.6': + resolution: {integrity: sha512-ghVX3zjKPtSHu94Xs03giRIeIWlb9M+gvDRVpIZ/cRIxKHdW6HE/sm1PT3rUYS3aV92CazirT93ne+7IOvGUWg==} + peerDependencies: + vue: ^3.0.0 + + '@vue/devtools-kit@7.6.2': + resolution: {integrity: sha512-k61BxHRmcTtIQZFouF9QWt9nCCNtSdw12lhg8VNtHq5/XOBGD+ewiK27a40UJ8UPYoCJvi80hbvbYr5E/Zeu1g==} + + '@vue/devtools-kit@7.7.6': + resolution: {integrity: sha512-geu7ds7tem2Y7Wz+WgbnbZ6T5eadOvozHZ23Atk/8tksHMFOFylKi1xgGlQlVn0wlkEf4hu+vd5ctj1G4kFtwA==} + + '@vue/devtools-shared@7.6.2': + resolution: {integrity: sha512-lcjyJ7hCC0W0kNwnCGMLVTMvDLoZgjcq9BvboPgS+6jQyDul7fpzRSKTGtGhCHoxrDox7qBAKGbAl2Rcf7GE1A==} + + '@vue/devtools-shared@7.7.6': + resolution: {integrity: sha512-yFEgJZ/WblEsojQQceuyK6FzpFDx4kqrz2ohInxNj5/DnhoX023upTv4OD6lNPLAA5LLkbwPVb10o/7b+Y4FVA==} + + '@vue/language-core@2.0.16': + resolution: {integrity: sha512-Bc2sexRH99pznOph8mLw2BlRZ9edm7tW51kcBXgx8adAoOcZUWJj3UNSsdQ6H9Y8meGz7BoazVrVo/jUukIsPw==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@vue/language-core@2.1.10': + resolution: {integrity: sha512-DAI289d0K3AB5TUG3xDp9OuQ71CnrujQwJrQnfuZDwo6eGNf0UoRlPuaVNO+Zrn65PC3j0oB2i7mNmVPggeGeQ==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@vue/reactivity@3.4.27': + resolution: {integrity: sha512-kK0g4NknW6JX2yySLpsm2jlunZJl2/RJGZ0H9ddHdfBVHcNzxmQ0sS0b09ipmBoQpY8JM2KmUw+a6sO8Zo+zIA==} + + '@vue/reactivity@3.5.12': + resolution: {integrity: sha512-UzaN3Da7xnJXdz4Okb/BGbAaomRHc3RdoWqTzlvd9+WBR5m3J39J1fGcHes7U3za0ruYn/iYy/a1euhMEHvTAg==} + + '@vue/reactivity@3.5.14': + resolution: {integrity: sha512-7cK1Hp343Fu/SUCCO52vCabjvsYu7ZkOqyYu7bXV9P2yyfjUMUXHZafEbq244sP7gf+EZEz+77QixBTuEqkQQw==} + + '@vue/runtime-core@3.4.27': + resolution: {integrity: sha512-7aYA9GEbOOdviqVvcuweTLe5Za4qBZkUY7SvET6vE8kyypxVgaT1ixHLg4urtOlrApdgcdgHoTZCUuTGap/5WA==} + + '@vue/runtime-core@3.5.12': + resolution: {integrity: sha512-hrMUYV6tpocr3TL3Ad8DqxOdpDe4zuQY4HPY3X/VRh+L2myQO8MFXPAMarIOSGNu0bFAjh1yBkMPXZBqCk62Uw==} + + '@vue/runtime-core@3.5.14': + resolution: {integrity: sha512-w9JWEANwHXNgieAhxPpEpJa+0V5G0hz3NmjAZwlOebtfKyp2hKxKF0+qSh0Xs6/PhfGihuSdqMprMVcQU/E6ag==} + + '@vue/runtime-dom@3.4.27': + resolution: {integrity: sha512-ScOmP70/3NPM+TW9hvVAz6VWWtZJqkbdf7w6ySsws+EsqtHvkhxaWLecrTorFxsawelM5Ys9FnDEMt6BPBDS0Q==} + + '@vue/runtime-dom@3.5.12': + resolution: {integrity: sha512-q8VFxR9A2MRfBr6/55Q3umyoN7ya836FzRXajPB6/Vvuv0zOPL+qltd9rIMzG/DbRLAIlREmnLsplEF/kotXKA==} + + '@vue/runtime-dom@3.5.14': + resolution: {integrity: sha512-lCfR++IakeI35TVR80QgOelsUIdcKjd65rWAMfdSlCYnaEY5t3hYwru7vvcWaqmrK+LpI7ZDDYiGU5V3xjMacw==} + + '@vue/server-renderer@3.4.27': + resolution: {integrity: sha512-dlAMEuvmeA3rJsOMJ2J1kXU7o7pOxgsNHVr9K8hB3ImIkSuBrIdy0vF66h8gf8Tuinf1TK3mPAz2+2sqyf3KzA==} + peerDependencies: + vue: 3.4.27 + + '@vue/server-renderer@3.5.12': + resolution: {integrity: sha512-I3QoeDDeEPZm8yR28JtY+rk880Oqmj43hreIBVTicisFTx/Dl7JpG72g/X7YF8hnQD3IFhkky5i2bPonwrTVPg==} + peerDependencies: + vue: 3.5.12 + + '@vue/server-renderer@3.5.14': + resolution: {integrity: sha512-Rf/ISLqokIvcySIYnv3tNWq40PLpNLDLSJwwVWzG6MNtyIhfbcrAxo5ZL9nARJhqjZyWWa40oRb2IDuejeuv6w==} + peerDependencies: + vue: 3.5.14 + + '@vue/shared@3.4.27': + resolution: {integrity: sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA==} + + '@vue/shared@3.5.12': + resolution: {integrity: sha512-L2RPSAwUFbgZH20etwrXyVyCBu9OxRSi8T/38QsvnkJyvq2LufW2lDCOzm7t/U9C1mkhJGWYfCuFBCmIuNivrg==} + + '@vue/shared@3.5.14': + resolution: {integrity: sha512-oXTwNxVfc9EtP1zzXAlSlgARLXNC84frFYkS0HHz0h3E4WZSP9sywqjqzGCP9Y34M8ipNmd380pVgmMuwELDyQ==} + + '@vue/test-utils@2.4.6': + resolution: {integrity: sha512-FMxEjOpYNYiFe0GkaHsnJPXFHxQ6m4t8vI/ElPGpMWxZKpmRvQ33OIrvRXemy6yha03RxhOlQuy+gZMC3CQSow==} + + '@vueuse/core@11.2.0': + resolution: {integrity: sha512-JIUwRcOqOWzcdu1dGlfW04kaJhW3EXnnjJJfLTtddJanymTL7lF1C0+dVVZ/siLfc73mWn+cGP1PE1PKPruRSA==} + + '@vueuse/integrations@11.2.0': + resolution: {integrity: sha512-zGXz3dsxNHKwiD9jPMvR3DAxQEOV6VWIEYTGVSB9PNpk4pTWR+pXrHz9gvXWcP2sTk3W2oqqS6KwWDdntUvNVA==} + peerDependencies: + async-validator: ^4 + axios: ^1 + change-case: ^5 + drauu: ^0.4 + focus-trap: ^7 + fuse.js: ^7 + idb-keyval: ^6 + jwt-decode: ^4 + nprogress: ^0.2 + qrcode: ^1.5 + sortablejs: ^1 + universal-cookie: ^7 + peerDependenciesMeta: + async-validator: + optional: true + axios: + optional: true + change-case: + optional: true + drauu: + optional: true + focus-trap: + optional: true + fuse.js: + optional: true + idb-keyval: + optional: true + jwt-decode: + optional: true + nprogress: + optional: true + qrcode: + optional: true + sortablejs: + optional: true + universal-cookie: + optional: true + + '@vueuse/metadata@11.2.0': + resolution: {integrity: sha512-L0ZmtRmNx+ZW95DmrgD6vn484gSpVeRbgpWevFKXwqqQxW9hnSi2Ppuh2BzMjnbv4aJRiIw8tQatXT9uOB23dQ==} + + '@vueuse/shared@11.2.0': + resolution: {integrity: sha512-VxFjie0EanOudYSgMErxXfq6fo8vhr5ICI+BuE3I9FnX7ePllEsVrRQ7O6Q1TLgApeLuPKcHQxAXpP+KnlrJsg==} + + '@walletconnect/core@2.19.2': + resolution: {integrity: sha512-iu0mgLj51AXcKpdNj8+4EdNNBd/mkNjLEhZn6UMc/r7BM9WbmpPMEydA39WeRLbdLO4kbpmq4wTbiskI1rg+HA==} + engines: {node: '>=18'} + + '@walletconnect/core@2.20.2': + resolution: {integrity: sha512-48XnarxQQrpJ0KZJOjit56DxuzfVRYUdL8XVMvUh/ZNUiX2FB5w6YuljUUeTLfYOf04Et6qhVGEUkmX3W+9/8w==} + engines: {node: '>=18'} + + '@walletconnect/environment@1.0.1': + resolution: {integrity: sha512-T426LLZtHj8e8rYnKfzsw1aG6+M0BT1ZxayMdv/p8yM0MU+eJDISqNY3/bccxRr4LrF9csq02Rhqt08Ibl0VRg==} + + '@walletconnect/ethereum-provider@2.20.2': + resolution: {integrity: sha512-fGNJtytHuBWZcmMXRIG1djlfEiPMvPJ0R3JlfJjAx2VfVN+O+1xdF6QSWcZxFizviIUFJV+f1zWt0V2VVD61Rg==} + + '@walletconnect/events@1.0.1': + resolution: {integrity: sha512-NPTqaoi0oPBVNuLv7qPaJazmGHs5JGyO8eEAk5VGKmJzDR7AHzD4k6ilox5kxk1iwiOnFopBOOMLs86Oa76HpQ==} + + '@walletconnect/heartbeat@1.2.2': + resolution: {integrity: sha512-uASiRmC5MwhuRuf05vq4AT48Pq8RMi876zV8rr8cV969uTOzWdB/k+Lj5yI2PBtB1bGQisGen7MM1GcZlQTBXw==} + + '@walletconnect/jsonrpc-http-connection@1.0.8': + resolution: {integrity: sha512-+B7cRuaxijLeFDJUq5hAzNyef3e3tBDIxyaCNmFtjwnod5AGis3RToNqzFU33vpVcxFhofkpE7Cx+5MYejbMGw==} + + '@walletconnect/jsonrpc-provider@1.0.14': + resolution: {integrity: sha512-rtsNY1XqHvWj0EtITNeuf8PHMvlCLiS3EjQL+WOkxEOA4KPxsohFnBDeyPYiNm4ZvkQdLnece36opYidmtbmow==} + + '@walletconnect/jsonrpc-types@1.0.4': + resolution: {integrity: sha512-P6679fG/M+wuWg9TY8mh6xFSdYnFyFjwFelxyISxMDrlbXokorEVXYOxiqEbrU3x1BmBoCAJJ+vtEaEoMlpCBQ==} + + '@walletconnect/jsonrpc-utils@1.0.8': + resolution: {integrity: sha512-vdeb03bD8VzJUL6ZtzRYsFMq1eZQcM3EAzT0a3st59dyLfJ0wq+tKMpmGH7HlB7waD858UWgfIcudbPFsbzVdw==} + + '@walletconnect/jsonrpc-ws-connection@1.0.16': + resolution: {integrity: sha512-G81JmsMqh5nJheE1mPst1W0WfVv0SG3N7JggwLLGnI7iuDZJq8cRJvQwLGKHn5H1WTW7DEPCo00zz5w62AbL3Q==} + + '@walletconnect/keyvaluestorage@1.1.1': + resolution: {integrity: sha512-V7ZQq2+mSxAq7MrRqDxanTzu2RcElfK1PfNYiaVnJgJ7Q7G7hTVwF8voIBx92qsRyGHZihrwNPHuZd1aKkd0rA==} + peerDependencies: + '@react-native-async-storage/async-storage': 1.x + peerDependenciesMeta: + '@react-native-async-storage/async-storage': + optional: true + + '@walletconnect/logger@2.1.2': + resolution: {integrity: sha512-aAb28I3S6pYXZHQm5ESB+V6rDqIYfsnHaQyzFbwUUBFY4H0OXx/YtTl8lvhUNhMMfb9UxbwEBS253TlXUYJWSw==} + + '@walletconnect/relay-api@1.0.11': + resolution: {integrity: sha512-tLPErkze/HmC9aCmdZOhtVmYZq1wKfWTJtygQHoWtgg722Jd4homo54Cs4ak2RUFUZIGO2RsOpIcWipaua5D5Q==} + + '@walletconnect/relay-auth@1.1.0': + resolution: {integrity: sha512-qFw+a9uRz26jRCDgL7Q5TA9qYIgcNY8jpJzI1zAWNZ8i7mQjaijRnWFKsCHAU9CyGjvt6RKrRXyFtFOpWTVmCQ==} + + '@walletconnect/safe-json@1.0.2': + resolution: {integrity: sha512-Ogb7I27kZ3LPC3ibn8ldyUr5544t3/STow9+lzz7Sfo808YD7SBWk7SAsdBFlYgP2zDRy2hS3sKRcuSRM0OTmA==} + + '@walletconnect/sign-client@2.19.2': + resolution: {integrity: sha512-a/K5PRIFPCjfHq5xx3WYKHAAF8Ft2I1LtxloyibqiQOoUtNLfKgFB1r8sdMvXM7/PADNPe4iAw4uSE6PrARrfg==} + + '@walletconnect/sign-client@2.20.2': + resolution: {integrity: sha512-KyeDToypZ1OjCbij4Jx0cAg46bMwZ6zCKt0HzCkqENcex3Zchs7xBp9r8GtfEMGw+PUnXwqrhzmLBH0x/43oIQ==} + + '@walletconnect/time@1.0.2': + resolution: {integrity: sha512-uzdd9woDcJ1AaBZRhqy5rNC9laqWGErfc4dxA9a87mPdKOgWMD85mcFo9dIYIts/Jwocfwn07EC6EzclKubk/g==} + + '@walletconnect/types@2.19.2': + resolution: {integrity: sha512-/LZWhkVCUN+fcTgQUxArxhn2R8DF+LSd/6Wh9FnpjeK/Sdupx1EPS8okWG6WPAqq2f404PRoNAfQytQ82Xdl3g==} + + '@walletconnect/types@2.20.2': + resolution: {integrity: sha512-XPPbJM/mGU05i6jUxhC3yI/YvhSF6TYJQ5SXTWM53lVe6hs6ukvlEhPctu9ZBTGwGFhwPXIjtK/eWx+v4WY5iw==} + + '@walletconnect/universal-provider@2.19.2': + resolution: {integrity: sha512-LkKg+EjcSUpPUhhvRANgkjPL38wJPIWumAYD8OK/g4OFuJ4W3lS/XTCKthABQfFqmiNbNbVllmywiyE44KdpQg==} + + '@walletconnect/universal-provider@2.20.2': + resolution: {integrity: sha512-6uVu1E88tioaXEEJCbJKwCIQlOHif1nmfY092BznZEnBn2lli5ICzQh2bxtUDNmNNLKsMDI3FV1fODFeWMVJTQ==} + + '@walletconnect/utils@2.19.2': + resolution: {integrity: sha512-VU5CcUF4sZDg8a2/ov29OJzT3KfLuZqJUM0GemW30dlipI5fkpb0VPenZK7TcdLPXc1LN+Q+7eyTqHRoAu/BIA==} + + '@walletconnect/utils@2.20.2': + resolution: {integrity: sha512-2uRUDvpYSIJFYcr1WIuiFy6CEszLF030o6W8aDMkGk9/MfAZYEJQHMJcjWyaNMPHLJT0POR5lPaqkYOpuyPIQQ==} + + '@walletconnect/window-getters@1.0.1': + resolution: {integrity: sha512-vHp+HqzGxORPAN8gY03qnbTMnhqIwjeRJNOMOAzePRg4xVEEE2WvYsI9G2NMjOknA8hnuYbU3/hwLcKbjhc8+Q==} + + '@walletconnect/window-metadata@1.0.1': + resolution: {integrity: sha512-9koTqyGrM2cqFRW517BPY/iEtUDx2r1+Pwwu5m7sJ7ka79wi3EyqhqcICk/yDmv6jAS1rjKgTKXlEhanYjijcA==} + + '@whatwg-node/disposablestack@0.0.6': + resolution: {integrity: sha512-LOtTn+JgJvX8WfBVJtF08TGrdjuFzGJc4mkP8EdDI8ADbvO7kiexYep1o8dwnt0okb0jYclCDXF13xU7Ge4zSw==} + engines: {node: '>=18.0.0'} + + '@whatwg-node/fetch@0.10.8': + resolution: {integrity: sha512-Rw9z3ctmeEj8QIB9MavkNJqekiu9usBCSMZa+uuAvM0lF3v70oQVCXNppMIqaV6OTZbdaHF1M2HLow58DEw+wg==} + engines: {node: '>=18.0.0'} + + '@whatwg-node/node-fetch@0.7.21': + resolution: {integrity: sha512-QC16IdsEyIW7kZd77aodrMO7zAoDyyqRCTLg+qG4wqtP4JV9AA+p7/lgqMdD29XyiYdVvIdFrfI9yh7B1QvRvw==} + engines: {node: '>=18.0.0'} + + '@whatwg-node/promise-helpers@1.3.2': + resolution: {integrity: sha512-Nst5JdK47VIl9UcGwtv2Rcgyn5lWtZ0/mhRQ4G8NN2isxpq2TO30iqHzmwoJycjWuyUfg3GFXqP/gFHXeV57IA==} + engines: {node: '>=16.0.0'} + + '@whatwg-node/server@0.9.71': + resolution: {integrity: sha512-ueFCcIPaMgtuYDS9u0qlUoEvj6GiSsKrwnOLPp9SshqjtcRaR1IEHRjoReq3sXNydsF5i0ZnmuYgXq9dV53t0g==} + engines: {node: '>=18.0.0'} + + abbrev@1.1.1: + resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} + + abbrev@2.0.0: + resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + abbrev@3.0.1: + resolution: {integrity: sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==} + engines: {node: ^18.17.0 || >=20.5.0} + + abitype@1.0.0: + resolution: {integrity: sha512-NMeMah//6bJ56H5XRj8QCV4AwuW6hB6zqz2LnhhLdcWVQOsXki6/Pn3APeqxCma62nXIcmZWdu1DlHWS74umVQ==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + + abitype@1.0.2: + resolution: {integrity: sha512-aFt4k2H+eiAKy/zxtnORa9iIb10BMBeWL18l8v4+QuwYEBXPxxjSB1bFZCzQmKPoj8m7j68K705l3uY+E2gAjg==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + + abitype@1.0.4: + resolution: {integrity: sha512-UivtYZOGJGE8rsrM/N5vdRkUpqEZVmuTumfTuolm7m/6O09wprd958rx8kUBwVAAAhQDveGAgD0GJdBuR8s6tw==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + + abitype@1.0.5: + resolution: {integrity: sha512-YzDhti7cjlfaBhHutMaboYB21Ha3rXR9QTkNJFzYC4kC8YclaiwPBBBJY8ejFdu2wnJeZCVZSMlQJ7fi8S6hsw==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + + abitype@1.0.8: + resolution: {integrity: sha512-ZeiI6h3GnW06uYDLx0etQtX/p8E24UaHHBj57RSjK7YBFe7iuVn07EDpOeP451D06sF27VOz9JJPlIKJmXgkEg==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + + abort-controller@3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} + + acorn-import-attributes@1.9.5: + resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==} + peerDependencies: + acorn: ^8 + + acorn-walk@8.3.4: + resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} + engines: {node: '>=0.4.0'} + + acorn@8.11.3: + resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} + engines: {node: '>=0.4.0'} + hasBin: true + + acorn@8.14.1: + resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==} + engines: {node: '>=0.4.0'} + hasBin: true + + acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + engines: {node: '>=0.4.0'} + hasBin: true + + adm-zip@0.4.16: + resolution: {integrity: sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==} + engines: {node: '>=0.3.0'} + + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + + agent-base@7.1.3: + resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==} + engines: {node: '>= 14'} + + aggregate-error@3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} + + algoliasearch@5.12.0: + resolution: {integrity: sha512-psGBRYdGgik8I6m28iAB8xpubvjEt7UQU+w5MAJUA2324WHiGoHap5BPkkjB14rMaXeRts6pmOsrVIglGyOVwg==} + engines: {node: '>= 14.0.0'} + + alien-signals@0.2.0: + resolution: {integrity: sha512-StlonZhBBrsPPwrDjiPAiVTf/rolxffLxVPT60Qv/t88BZ81BvUVzHgGqEFvJ1ii8HXtm1+zU2Icr59tfWEcag==} + + ansi-align@3.0.1: + resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} + + ansi-colors@4.1.1: + resolution: {integrity: sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==} + engines: {node: '>=6'} + + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + + ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + + ansi-escapes@7.0.0: + resolution: {integrity: sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==} + engines: {node: '>=18'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + engines: {node: '>=12'} + + ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + ansis@3.17.0: + resolution: {integrity: sha512-0qWUglt9JEqLFr3w1I1pbrChn1grhaiAR2ocX1PP/flRmxgtwTzPFFFnfIlD6aMOLQZgSuCRlidD70lvx8yhzg==} + engines: {node: '>=14'} + + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + aproba@2.0.0: + resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} + + archiver-utils@2.1.0: + resolution: {integrity: sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==} + engines: {node: '>= 6'} + + archiver-utils@3.0.4: + resolution: {integrity: sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==} + engines: {node: '>= 10'} + + archiver-utils@5.0.2: + resolution: {integrity: sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==} + engines: {node: '>= 14'} + + archiver@5.3.2: + resolution: {integrity: sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==} + engines: {node: '>= 10'} + + archiver@7.0.1: + resolution: {integrity: sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==} + engines: {node: '>= 14'} + + are-we-there-yet@2.0.0: + resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==} + engines: {node: '>=10'} + deprecated: This package is no longer supported. + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aria-query@5.3.0: + resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + + array-union@1.0.2: + resolution: {integrity: sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==} + engines: {node: '>=0.10.0'} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + array-uniq@1.0.3: + resolution: {integrity: sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==} + engines: {node: '>=0.10.0'} + + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + + ast-kit@1.4.3: + resolution: {integrity: sha512-MdJqjpodkS5J149zN0Po+HPshkTdUyrvF7CKTafUgv69vBSPtncrj+3IiUgqdd7ElIEkbeXCsEouBUwLrw9Ilg==} + engines: {node: '>=16.14.0'} + + ast-module-types@5.0.0: + resolution: {integrity: sha512-JvqziE0Wc0rXQfma0HZC/aY7URXHFuZV84fJRtP8u+lhp0JYCNd5wJzVXP45t0PH0Mej3ynlzvdyITYIu0G4LQ==} + engines: {node: '>=14'} + + ast-walker-scope@0.6.2: + resolution: {integrity: sha512-1UWOyC50xI3QZkRuDj6PqDtpm1oHWtYs+NQGwqL/2R11eN3Q81PHAHPM0SWW3BNQm53UDwS//Jv8L4CCVLM1bQ==} + engines: {node: '>=16.14.0'} + + async-mutex@0.2.6: + resolution: {integrity: sha512-Hs4R+4SPgamu6rSGW8C7cV9gaWUKEHykfzCCvIRuaVv636Ju10ZdeUbvb4TBEW0INuq2DHZqXbK4Nd3yG4RaRw==} + + async-sema@3.1.1: + resolution: {integrity: sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==} + + async@3.2.6: + resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + + atomic-sleep@1.0.0: + resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} + engines: {node: '>=8.0.0'} + + autoprefixer@10.4.21: + resolution: {integrity: sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + b4a@1.6.7: + resolution: {integrity: sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + bare-events@2.5.4: + resolution: {integrity: sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA==} + + base-x@3.0.9: + resolution: {integrity: sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==} + + base-x@5.0.1: + resolution: {integrity: sha512-M7uio8Zt++eg3jPj+rHMfCC+IuygQHHCOU+IYsVtik6FWjuYpVt/+MRKcgsAMHh8mMFAwnB+Bs+mTrFiXjMzKg==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + better-path-resolve@1.0.0: + resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} + engines: {node: '>=4'} + + big.js@6.2.2: + resolution: {integrity: sha512-y/ie+Faknx7sZA5MfGA2xKlu0GDv8RWrXGsmlteyJQ2lvoKv9GBK/fpRMc2qlSoBAgNxrixICFCBefIq8WCQpQ==} + + binary-extensions@2.2.0: + resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + engines: {node: '>=8'} + + bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + + birpc@0.2.19: + resolution: {integrity: sha512-5WeXXAvTmitV1RqJFppT5QtUiz2p1mRSYU000Jkft5ZUCLJIk4uQriYNO50HknxKwM6jd8utNc66K1qGIwwWBQ==} + + birpc@2.3.0: + resolution: {integrity: sha512-ijbtkn/F3Pvzb6jHypHRyve2QApOCZDR25D/VnkY2G/lBNcXCTsnsCxgY4k4PkVB7zfwzYbY3O9Lcqe3xufS5g==} + + bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + + blakejs@1.2.1: + resolution: {integrity: sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==} + + bn.js@4.12.0: + resolution: {integrity: sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==} + + bn.js@5.2.1: + resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + bowser@2.11.0: + resolution: {integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==} + + boxen@5.1.2: + resolution: {integrity: sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==} + engines: {node: '>=10'} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + brorand@1.1.0: + resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==} + + browser-stdout@1.3.1: + resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} + + browserify-aes@1.2.0: + resolution: {integrity: sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==} + + browserslist@4.23.0: + resolution: {integrity: sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + browserslist@4.24.5: + resolution: {integrity: sha512-FDToo4Wo82hIdgc1CQ+NQD0hEhmpPjrZ3hiUgwgOG6IuTdlpr8jdjyG24P6cNP1yJpTLzS5OcGgSw0xmDU1/Tw==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + bs58@4.0.1: + resolution: {integrity: sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==} + + bs58@6.0.0: + resolution: {integrity: sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==} + + bs58check@2.1.2: + resolution: {integrity: sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==} + + buffer-crc32@0.2.13: + resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + + buffer-crc32@1.0.0: + resolution: {integrity: sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==} + engines: {node: '>=8.0.0'} + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + buffer-xor@1.0.3: + resolution: {integrity: sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==} + + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + + bufferutil@4.0.8: + resolution: {integrity: sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==} + engines: {node: '>=6.14.2'} + + bufferutil@4.0.9: + resolution: {integrity: sha512-WDtdLmJvAuNNPzByAYpRo2rF1Mmradw6gvWsQKf63476DDXmomT9zUiGypLcG4ibIM67vhAj8jJRdbmEws2Aqw==} + engines: {node: '>=6.14.2'} + + builtin-modules@3.3.0: + resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} + engines: {node: '>=6'} + + bun-types@1.1.29: + resolution: {integrity: sha512-En3/TzSPMPyl5UlUB1MHzHpcrZDakTm7mS203eLoX1fBoEa3PW+aSS8GAqVJ7Is/m34Z5ogL+ECniLY0uDaCPw==} + + bun@1.1.30: + resolution: {integrity: sha512-ysRL1pq10Xba0jqVLPrKU3YIv0ohfp3cTajCPtpjCyppbn3lfiAVNpGoHfyaxS17OlPmWmR67UZRPw/EueQuug==} + cpu: [arm64, x64] + os: [darwin, linux, win32] + hasBin: true + + bundle-name@4.1.0: + resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} + engines: {node: '>=18'} + + bundle-require@5.1.0: + resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + peerDependencies: + esbuild: '>=0.18' + + busboy@1.6.0: + resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} + engines: {node: '>=10.16.0'} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + c12@3.0.4: + resolution: {integrity: sha512-t5FaZTYbbCtvxuZq9xxIruYydrAGsJ+8UdP0pZzMiK2xl/gNiSOy0OxhLzHUEEb0m1QXYqfzfvyIFEmz/g9lqg==} + peerDependencies: + magicast: ^0.3.5 + peerDependenciesMeta: + magicast: + optional: true + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + callsite@1.0.0: + resolution: {integrity: sha512-0vdNRFXn5q+dtOqjfFtmtlI9N2eVZ7LMyEV2iKC5mEEFvSg/69Ml6b/WU2qF8W1nLRa0wiSrDT3Y5jOHZCwKPQ==} + + camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + + caniuse-api@3.0.0: + resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} + + caniuse-lite@1.0.30001723: + resolution: {integrity: sha512-1R/elMjtehrFejxwmexeXAtae5UO9iSyFn6G/I806CYC/BLyyBk1EPhrKBkWhy6wM6Xnm47dSJQec+tLJ39WHw==} + + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + + chai@5.2.0: + resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==} + engines: {node: '>=12'} + + chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chalk@5.3.0: + resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + change-case@5.4.4: + resolution: {integrity: sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==} + + char-regex@1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} + + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + + chardet@0.7.0: + resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + + check-error@2.1.1: + resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} + engines: {node: '>= 16'} + + chokidar@3.5.3: + resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + engines: {node: '>= 8.10.0'} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + chownr@2.0.0: + resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} + engines: {node: '>=10'} + + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} + + ci-info@2.0.0: + resolution: {integrity: sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==} + + ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} + + cipher-base@1.0.4: + resolution: {integrity: sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==} + + citty@0.1.6: + resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} + + cjs-module-lexer@1.4.1: + resolution: {integrity: sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==} + + clean-stack@2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} + + cli-boxes@2.2.1: + resolution: {integrity: sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==} + engines: {node: '>=6'} + + cli-highlight@2.1.11: + resolution: {integrity: sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==} + engines: {node: '>=8.0.0', npm: '>=5.0.0'} + hasBin: true + + cli-spinners@2.9.2: + resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} + engines: {node: '>=6'} + + cli-table3@0.6.5: + resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==} + engines: {node: 10.* || >= 12.*} + + cli-width@4.1.0: + resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} + engines: {node: '>= 12'} + + client-only@0.0.1: + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + + clipboardy@4.0.0: + resolution: {integrity: sha512-5mOlNS0mhX0707P2I0aZ2V/cmHUEO/fL7VFLqszkhUsxt7RwnmrInf/eEQKlf5GzvYeHIjT+Ov1HRfNmymlG0w==} + engines: {node: '>=18'} + + cliui@6.0.0: + resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + + cliui@7.0.4: + resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + clone@1.0.4: + resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} + engines: {node: '>=0.8'} + + clsx@1.2.1: + resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==} + engines: {node: '>=6'} + + cluster-key-slot@1.1.2: + resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==} + engines: {node: '>=0.10.0'} + + color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + + color-support@1.1.3: + resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} + hasBin: true + + color@3.2.1: + resolution: {integrity: sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==} + + color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + + colord@2.9.3: + resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} + + colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + + colorspace@1.1.4: + resolution: {integrity: sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==} + + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + + command-exists@1.2.9: + resolution: {integrity: sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==} + + commander@10.0.1: + resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} + engines: {node: '>=14'} + + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + + commander@3.0.2: + resolution: {integrity: sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==} + + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + + commander@7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + + common-path-prefix@3.0.0: + resolution: {integrity: sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==} + + commondir@1.0.1: + resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + + compatx@0.1.8: + resolution: {integrity: sha512-jcbsEAR81Bt5s1qOFymBufmCbXCXbk0Ql+K5ouj6gCyx2yHlu6AgmGIi9HxfKixpUDO5bCFJUHQ5uM6ecbTebw==} + + compatx@0.2.0: + resolution: {integrity: sha512-6gLRNt4ygsi5NyMVhceOCFv14CIdDFN7fQjX1U4+47qVE/+kjPoXMK65KWK+dWxmFzMTuKazoQ9sch6pM0p5oA==} + + compress-commons@4.1.2: + resolution: {integrity: sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==} + engines: {node: '>= 10'} + + compress-commons@6.0.2: + resolution: {integrity: sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==} + engines: {node: '>= 14'} + + computeds@0.0.1: + resolution: {integrity: sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + confbox@0.1.7: + resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==} + + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + + confbox@0.2.2: + resolution: {integrity: sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==} + + config-chain@1.1.13: + resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} + + consola@3.2.3: + resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} + engines: {node: ^14.18.0 || >=16.10.0} + + consola@3.4.2: + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} + engines: {node: ^14.18.0 || >=16.10.0} + + console-control-strings@1.1.0: + resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cookie-es@1.2.2: + resolution: {integrity: sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==} + + cookie-es@2.0.0: + resolution: {integrity: sha512-RAj4E421UYRgqokKUmotqAwuplYw15qtdXfY+hGzgCJ/MBjCVZcSoHK/kH9kocfjRjcDME7IiDWR/1WX1TM2Pg==} + + cookie@0.4.2: + resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==} + engines: {node: '>= 0.6'} + + cookie@0.5.0: + resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} + engines: {node: '>= 0.6'} + + cookie@1.0.2: + resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==} + engines: {node: '>=18'} + + copy-anything@3.0.5: + resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==} + engines: {node: '>=12.13'} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + cp-file@10.0.0: + resolution: {integrity: sha512-vy2Vi1r2epK5WqxOLnskeKeZkdZvTKfFZQCplE3XWsP+SUJyd5XAUFC9lFgTjjXJF2GMne/UML14iEmkAaDfFg==} + engines: {node: '>=14.16'} + + crc-32@1.2.2: + resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} + engines: {node: '>=0.8'} + hasBin: true + + crc32-stream@4.0.3: + resolution: {integrity: sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==} + engines: {node: '>= 10'} + + crc32-stream@6.0.0: + resolution: {integrity: sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==} + engines: {node: '>= 14'} + + create-hash@1.2.0: + resolution: {integrity: sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==} + + create-hmac@1.1.7: + resolution: {integrity: sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==} + + cron-parser@4.9.0: + resolution: {integrity: sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==} + engines: {node: '>=12.0.0'} + + croner@9.0.0: + resolution: {integrity: sha512-onMB0OkDjkXunhdW9htFjEhqrD54+M94i6ackoUkjHKbRnXdyEyKRelp4nJ1kAz32+s27jP1FsebpJCVl0BsvA==} + engines: {node: '>=18.0'} + + cross-fetch@3.1.5: + resolution: {integrity: sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==} + + cross-fetch@3.2.0: + resolution: {integrity: sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==} + + cross-fetch@4.1.0: + resolution: {integrity: sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==} + + cross-spawn@5.1.0: + resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + crossws@0.2.4: + resolution: {integrity: sha512-DAxroI2uSOgUKLz00NX6A8U/8EE3SZHmIND+10jkVSaypvyt57J5JEOxAQOL6lQxyzi/wZbTIwssU1uy69h5Vg==} + peerDependencies: + uWebSockets.js: '*' + peerDependenciesMeta: + uWebSockets.js: + optional: true + + crossws@0.3.5: + resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==} + + crypto-random-string@1.0.0: + resolution: {integrity: sha512-GsVpkFPlycH7/fRR7Dhcmnoii54gV1nz7y4CWyeFS14N+JVBBhY+r8amRHE4BwSYal7BPTDp8isvAlCxyFt3Hg==} + engines: {node: '>=4'} + + css-declaration-sorter@7.2.0: + resolution: {integrity: sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.0.9 + + css-select@5.1.0: + resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} + + css-tree@2.2.1: + resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + + css-tree@2.3.1: + resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + + css-what@6.1.0: + resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} + engines: {node: '>= 6'} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + cssnano-preset-default@7.0.7: + resolution: {integrity: sha512-jW6CG/7PNB6MufOrlovs1TvBTEVmhY45yz+bd0h6nw3h6d+1e+/TX+0fflZ+LzvZombbT5f+KC063w9VoHeHow==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + cssnano-utils@5.0.1: + resolution: {integrity: sha512-ZIP71eQgG9JwjVZsTPSqhc6GHgEr53uJ7tK5///VfyWj6Xp2DBmixWHqJgPno+PqATzn48pL42ww9x5SSGmhZg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + cssnano@7.0.7: + resolution: {integrity: sha512-evKu7yiDIF7oS+EIpwFlMF730ijRyLFaM2o5cTxRGJR9OKHKkc+qP443ZEVR9kZG0syaAJJCPJyfv5pbrxlSng==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + csso@5.0.5: + resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + data-uri-to-buffer@4.0.1: + resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} + engines: {node: '>= 12'} + + dataloader@1.4.0: + resolution: {integrity: sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==} + + date-fns@2.30.0: + resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==} + engines: {node: '>=0.11'} + + dateformat@4.6.3: + resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==} + + dayjs@1.11.13: + resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} + + db0@0.3.2: + resolution: {integrity: sha512-xzWNQ6jk/+NtdfLyXEipbX55dmDSeteLFt/ayF+wZUU5bzKgmrDOxmInUTbyVRp46YwnJdkDA1KhB7WIXFofJw==} + peerDependencies: + '@electric-sql/pglite': '*' + '@libsql/client': '*' + better-sqlite3: '*' + drizzle-orm: '*' + mysql2: '*' + sqlite3: '*' + peerDependenciesMeta: + '@electric-sql/pglite': + optional: true + '@libsql/client': + optional: true + better-sqlite3: + optional: true + drizzle-orm: + optional: true + mysql2: + optional: true + sqlite3: + optional: true + + de-indent@1.0.2: + resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} + + debounce@1.2.1: + resolution: {integrity: sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==} + + debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.1: + resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decache@4.6.2: + resolution: {integrity: sha512-2LPqkLeu8XWHU8qNCS3kcF6sCcb5zIzvWaAHYSvPfwhdd7mHuah29NssMzrTYyHN4F5oFy2ko9OBYxegtU0FEw==} + + decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + + decamelize@4.0.0: + resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} + engines: {node: '>=10'} + + decode-named-character-reference@1.0.2: + resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==} + + decode-uri-component@0.2.2: + resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} + engines: {node: '>=0.10'} + + dedent@1.6.0: + resolution: {integrity: sha512-F1Z+5UCFpmQUzJa11agbyPVMbpgT/qA3/SKyJ1jyBgm7dUcUEa8v9JwDkerSQXfakBwFljIxhOJqGkjUwZ9FSA==} + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} + engines: {node: '>=6'} + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + default-browser-id@5.0.0: + resolution: {integrity: sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==} + engines: {node: '>=18'} + + default-browser@5.2.1: + resolution: {integrity: sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==} + engines: {node: '>=18'} + + defaults@1.0.4: + resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-lazy-prop@2.0.0: + resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} + engines: {node: '>=8'} + + define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} + + defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + + delegates@1.0.0: + resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} + + denque@2.1.0: + resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} + engines: {node: '>=0.10'} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + derive-valtio@0.1.0: + resolution: {integrity: sha512-OCg2UsLbXK7GmmpzMXhYkdO64vhJ1ROUUGaTFyHjVwEdMEcTTRj7W1TxLbSBxdY8QLBPCcp66MTyaSy0RpO17A==} + peerDependencies: + valtio: '*' + + destr@2.0.5: + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} + + detect-browser@5.3.0: + resolution: {integrity: sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w==} + + detect-indent@6.1.0: + resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} + engines: {node: '>=8'} + + detect-libc@1.0.3: + resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==} + engines: {node: '>=0.10'} + hasBin: true + + detect-libc@2.0.4: + resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} + engines: {node: '>=8'} + + detective-amd@5.0.2: + resolution: {integrity: sha512-XFd/VEQ76HSpym80zxM68ieB77unNuoMwopU2TFT/ErUk5n4KvUTwW4beafAVUugrjV48l4BmmR0rh2MglBaiA==} + engines: {node: '>=14'} + hasBin: true + + detective-cjs@5.0.1: + resolution: {integrity: sha512-6nTvAZtpomyz/2pmEmGX1sXNjaqgMplhQkskq2MLrar0ZAIkHMrDhLXkRiK2mvbu9wSWr0V5/IfiTrZqAQMrmQ==} + engines: {node: '>=14'} + + detective-es6@4.0.1: + resolution: {integrity: sha512-k3Z5tB4LQ8UVHkuMrFOlvb3GgFWdJ9NqAa2YLUU/jTaWJIm+JJnEh4PsMc+6dfT223Y8ACKOaC0qcj7diIhBKw==} + engines: {node: '>=14'} + + detective-postcss@6.1.3: + resolution: {integrity: sha512-7BRVvE5pPEvk2ukUWNQ+H2XOq43xENWbH0LcdCE14mwgTBEAMoAx+Fc1rdp76SmyZ4Sp48HlV7VedUnP6GA1Tw==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + detective-sass@5.0.3: + resolution: {integrity: sha512-YsYT2WuA8YIafp2RVF5CEfGhhyIVdPzlwQgxSjK+TUm3JoHP+Tcorbk3SfG0cNZ7D7+cYWa0ZBcvOaR0O8+LlA==} + engines: {node: '>=14'} + + detective-scss@4.0.3: + resolution: {integrity: sha512-VYI6cHcD0fLokwqqPFFtDQhhSnlFWvU614J42eY6G0s8c+MBhi9QAWycLwIOGxlmD8I/XvGSOUV1kIDhJ70ZPg==} + engines: {node: '>=14'} + + detective-stylus@4.0.0: + resolution: {integrity: sha512-TfPotjhszKLgFBzBhTOxNHDsutIxx9GTWjrL5Wh7Qx/ydxKhwUrlSFeLIn+ZaHPF+h0siVBkAQSuy6CADyTxgQ==} + engines: {node: '>=14'} + + detective-typescript@11.2.0: + resolution: {integrity: sha512-ARFxjzizOhPqs1fYC/2NMC3N4jrQ6HvVflnXBTRqNEqJuXwyKLRr9CrJwkRcV/SnZt1sNXgsF6FPm0x57Tq0rw==} + engines: {node: ^14.14.0 || >=16.0.0} + + devalue@5.1.1: + resolution: {integrity: sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + diff@5.0.0: + resolution: {integrity: sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==} + engines: {node: '>=0.3.1'} + + diff@7.0.0: + resolution: {integrity: sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==} + engines: {node: '>=0.3.1'} + + dijkstrajs@1.0.2: + resolution: {integrity: sha512-QV6PMaHTCNmKSeP6QoXhVTw9snc9VD8MulTT0Bd99Pacp4SS1cjcrYPgBPmibqKVtMJJfqC6XvOXgPMEEPH/fg==} + + dir-glob@2.2.2: + resolution: {integrity: sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==} + engines: {node: '>=4'} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + dom-accessibility-api@0.5.16: + resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} + + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + + dot-prop@9.0.0: + resolution: {integrity: sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ==} + engines: {node: '>=18'} + + dotenv-expand@10.0.0: + resolution: {integrity: sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==} + engines: {node: '>=12'} + + dotenv@16.3.1: + resolution: {integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==} + engines: {node: '>=12'} + + dotenv@16.5.0: + resolution: {integrity: sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==} + engines: {node: '>=12'} + + dotenv@8.6.0: + resolution: {integrity: sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==} + engines: {node: '>=10'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + duplexer@0.1.2: + resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + + duplexify@4.1.2: + resolution: {integrity: sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + easy-table@1.2.0: + resolution: {integrity: sha512-OFzVOv03YpvtcWGe5AayU5G2hgybsg3iqA6drU8UaoZyB9jLGMTrz9+asnLp/E+6qPh88yEI1gvyZFZ41dmgww==} + + eciesjs@0.4.15: + resolution: {integrity: sha512-r6kEJXDKecVOCj2nLMuXK/FCPeurW33+3JRpfXVbjLja3XUYFfD9I/JBreH6sUyzcm3G/YQboBjMla6poKeSdA==} + engines: {bun: '>=1', deno: '>=2', node: '>=16'} + + editorconfig@1.0.4: + resolution: {integrity: sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==} + engines: {node: '>=14'} + hasBin: true + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + electron-to-chromium@1.4.757: + resolution: {integrity: sha512-jftDaCknYSSt/+KKeXzH3LX5E2CvRLm75P3Hj+J/dv3CL0qUYcOt13d5FN1NiL5IJbbhzHrb3BomeG2tkSlZmw==} + + electron-to-chromium@1.5.155: + resolution: {integrity: sha512-ps5KcGGmwL8VaeJlvlDlu4fORQpv3+GIcF5I3f9tUKUlJ/wsysh6HU8P5L1XWRYeXfA0oJd4PyM8ds8zTFf6Ng==} + + elliptic@6.5.4: + resolution: {integrity: sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==} + + elliptic@6.6.0: + resolution: {integrity: sha512-dpwoQcLc/2WLQvJvLRHKZ+f9FgOdjnq11rurqwekGQygGPsYSK29OMMD2WalatiqQ+XGFDglTNixpPfI+lpaAA==} + + elliptic@6.6.1: + resolution: {integrity: sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + emojilib@2.4.0: + resolution: {integrity: sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==} + + enabled@2.0.0: + resolution: {integrity: sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==} + + encode-utf8@1.0.3: + resolution: {integrity: sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==} + + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + + encoding@0.1.13: + resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} + + end-of-stream@1.4.4: + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + + engine.io-client@6.6.3: + resolution: {integrity: sha512-T0iLjnyNWahNyv/lcjS2y4oE358tVS/SYQNxYXGAJ9/GLgH4VCvOQ/mhTjqU88mLZCQgiG8RIegFHYCdVC+j5w==} + + engine.io-parser@5.2.3: + resolution: {integrity: sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==} + engines: {node: '>=10.0.0'} + + enhanced-resolve@5.17.1: + resolution: {integrity: sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==} + engines: {node: '>=10.13.0'} + + enhanced-resolve@5.18.1: + resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} + engines: {node: '>=10.13.0'} + + enquirer@2.3.6: + resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} + engines: {node: '>=8.6'} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + + env-paths@3.0.0: + resolution: {integrity: sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + environment@1.1.0: + resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} + engines: {node: '>=18'} + + error-stack-parser-es@1.0.5: + resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==} + + errx@0.1.0: + resolution: {integrity: sha512-fZmsRiDNv07K6s2KkKFTiD2aIvECa7++PKyD5NC32tpRw46qZA3sOz+aM+/V9V0GDHxVTKLziveV4JhzBHDp9Q==} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-module-lexer@1.7.0: + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-toolkit@1.33.0: + resolution: {integrity: sha512-X13Q/ZSc+vsO1q600bvNK4bxgXMkHcf//RxCmYDaRY5DAcT+eoXjY5hoAPGMdRnWQjvyLEcyauG3b6hz76LNqg==} + + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + + esbuild@0.25.4: + resolution: {integrity: sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==} + engines: {node: '>=18'} + hasBin: true + + esbuild@0.25.5: + resolution: {integrity: sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + + escodegen@2.1.0: + resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} + engines: {node: '>=6.0'} + hasBin: true + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + eth-block-tracker@7.1.0: + resolution: {integrity: sha512-8YdplnuE1IK4xfqpf4iU7oBxnOYAc35934o083G8ao+8WM8QQtt/mVlAY6yIAdY1eMeLqg4Z//PZjJGmWGPMRg==} + engines: {node: '>=14.0.0'} + + eth-json-rpc-filters@6.0.1: + resolution: {integrity: sha512-ITJTvqoCw6OVMLs7pI8f4gG92n/St6x80ACtHodeS+IXmO0w+t1T5OOzfSt7KLSMLRkVUoexV7tztLgDxg+iig==} + engines: {node: '>=14.0.0'} + + eth-query@2.1.2: + resolution: {integrity: sha512-srES0ZcvwkR/wd5OQBRA1bIJMww1skfGS0s8wlwK3/oNP4+wnds60krvu5R1QbpRQjMmpG5OMIWro5s7gvDPsA==} + + eth-rpc-errors@4.0.3: + resolution: {integrity: sha512-Z3ymjopaoft7JDoxZcEb3pwdGh7yiYMhOwm2doUt6ASXlMavpNlK6Cre0+IMl2VSGyEU9rkiperQhp5iRxn5Pg==} + + ethereum-cryptography@0.1.3: + resolution: {integrity: sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==} + + ethereum-cryptography@1.2.0: + resolution: {integrity: sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==} + + ethereum-cryptography@2.2.1: + resolution: {integrity: sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==} + + ethereumjs-abi@0.6.8: + resolution: {integrity: sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==} + deprecated: This library has been deprecated and usage is discouraged. + + ethereumjs-util@6.2.1: + resolution: {integrity: sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==} + + ethjs-util@0.1.6: + resolution: {integrity: sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==} + engines: {node: '>=6.5.0', npm: '>=3'} + + event-target-shim@5.0.1: + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} + engines: {node: '>=6'} + + eventemitter2@6.4.9: + resolution: {integrity: sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==} + + eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + + eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + + evp_bytestokey@1.0.3: + resolution: {integrity: sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==} + + execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + + execa@7.2.0: + resolution: {integrity: sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==} + engines: {node: ^14.18.0 || ^16.14.0 || >=18.0.0} + + execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + + execa@9.1.0: + resolution: {integrity: sha512-lSgHc4Elo2m6bUDhc3Hl/VxvUDJdQWI40RZ4KMY9bKRc+hgMOT7II/JjbNDhI8VnMtrCb7U/fhpJIkLORZozWw==} + engines: {node: '>=18'} + + expect-type@1.2.1: + resolution: {integrity: sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==} + engines: {node: '>=12.0.0'} + + exsolve@1.0.5: + resolution: {integrity: sha512-pz5dvkYYKQ1AHVrgOzBKWeP4u4FRb3a6DNK2ucr0OoNwYIU4QWsJ+NM36LLzORT+z845MzKHHhpXiUF5nvQoJg==} + + extendable-error@0.1.7: + resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} + + extension-port-stream@3.0.0: + resolution: {integrity: sha512-an2S5quJMiy5bnZKEf6AkfH/7r8CzHvhchU40gxN+OM6HPhe7Z9T1FUychcf2M9PpPOO0Hf7BAEfJkw2TDIBDw==} + engines: {node: '>=12.0.0'} + + external-editor@3.1.0: + resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} + engines: {node: '>=4'} + + externality@1.0.2: + resolution: {integrity: sha512-LyExtJWKxtgVzmgtEHyQtLFpw1KFhQphF9nTG8TpAIVkiI/xQ3FJh75tRFLYl4hkn7BNIIdLJInuDAavX35pMw==} + + extract-zip@2.0.1: + resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} + engines: {node: '>= 10.17.0'} + hasBin: true + + fast-copy@3.0.2: + resolution: {integrity: sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-fifo@1.3.2: + resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} + + fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fast-npm-meta@0.4.3: + resolution: {integrity: sha512-eUzR/uVx61fqlHBjG/eQx5mQs7SQObehMTTdq8FAkdCB4KuZSQ6DiZMIrAq4kcibB3WFLQ9c4dT26Vwkix1RKg==} + + fast-redact@3.1.2: + resolution: {integrity: sha512-+0em+Iya9fKGfEQGcd62Yv6onjBmmhV1uh86XVfOU8VwAe6kaFdQCWI9s0/Nnugx5Vd9tdbZ7e6gE2tR9dzXdw==} + engines: {node: '>=6'} + + fast-safe-stringify@2.1.1: + resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} + + fastq@1.15.0: + resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} + + fd-slicer@1.1.0: + resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} + + fdir@6.1.1: + resolution: {integrity: sha512-QfKBVg453Dyn3mr0Q0O+Tkr1r79lOTAKSi9f/Ot4+qVEwxWhav2Z+SudrG9vQjM2aYRMQQZ2/Q1zdA8ACM1pDg==} + peerDependencies: + picomatch: 3.x + peerDependenciesMeta: + picomatch: + optional: true + + fdir@6.4.4: + resolution: {integrity: sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + fecha@4.2.3: + resolution: {integrity: sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==} + + fetch-blob@3.2.0: + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} + engines: {node: ^12.20 || >= 14.13} + + fflate@0.8.2: + resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} + + figures@6.1.0: + resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} + engines: {node: '>=18'} + + file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + + fill-range@7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + filter-obj@1.1.0: + resolution: {integrity: sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==} + engines: {node: '>=0.10.0'} + + filter-obj@5.1.0: + resolution: {integrity: sha512-qWeTREPoT7I0bifpPUXtxkZJ1XJzxWtfoWWkdVGqa+eCr3SHW/Ocp89o8vLvbUuQnadybJpjOKu4V+RwO6sGng==} + engines: {node: '>=14.16'} + + find-up-simple@1.0.1: + resolution: {integrity: sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==} + engines: {node: '>=18'} + + find-up@2.1.0: + resolution: {integrity: sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==} + engines: {node: '>=4'} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + find-up@6.3.0: + resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + find-up@7.0.0: + resolution: {integrity: sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==} + engines: {node: '>=18'} + + fixturez@1.1.0: + resolution: {integrity: sha512-c4q9eZsAmCzj9gkrEO/YwIRlrHWt/TXQiX9jR9WeLFOqeeV6EyzdiiV28CpSzF6Ip+gyYrSv5UeOHqyzfcNTVA==} + + flat@5.0.2: + resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} + hasBin: true + + floating-vue@5.2.2: + resolution: {integrity: sha512-afW+h2CFafo+7Y9Lvw/xsqjaQlKLdJV7h1fCHfcYQ1C4SVMlu7OAekqWgu5d4SgvkBVU0pVpLlVsrSTBURFRkg==} + peerDependencies: + '@nuxt/kit': ^3.2.0 + vue: ^3.2.0 + peerDependenciesMeta: + '@nuxt/kit': + optional: true + + fn.name@1.1.0: + resolution: {integrity: sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==} + + focus-trap@7.6.0: + resolution: {integrity: sha512-1td0l3pMkWJLFipobUcGaf+5DTY4PLDDrcqoSaKP8ediO/CoWCCYk/fT/Y2A4e6TNB+Sh6clRJCjOPPnKoNHnQ==} + + follow-redirects@1.15.2: + resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + + foreground-child@3.1.1: + resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} + engines: {node: '>=14'} + + formdata-polyfill@4.0.10: + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} + engines: {node: '>=12.20.0'} + + fp-ts@1.19.3: + resolution: {integrity: sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==} + + fraction.js@4.3.7: + resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + + fresh@2.0.0: + resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} + engines: {node: '>= 0.8'} + + fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + + fs-extra@0.30.0: + resolution: {integrity: sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==} + + fs-extra@5.0.0: + resolution: {integrity: sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==} + + fs-extra@7.0.1: + resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} + engines: {node: '>=6 <7 || >=8'} + + fs-extra@8.1.0: + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + engines: {node: '>=6 <7 || >=8'} + + fs-minipass@2.1.0: + resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} + engines: {node: '>= 8'} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + fuse.js@7.1.0: + resolution: {integrity: sha512-trLf4SzuuUxfusZADLINj+dE8clK1frKdmqiJNb1Es75fmI5oY6X2mxLVUciLLjxqw/xr72Dhy+lER6dGd02FQ==} + engines: {node: '>=10'} + + gauge@3.0.2: + resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==} + engines: {node: '>=10'} + deprecated: This package is no longer supported. + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-amd-module-type@5.0.1: + resolution: {integrity: sha512-jb65zDeHyDjFR1loOVk0HQGM5WNwoGB8aLWy3LKCieMKol0/ProHkhO2X1JxojuN10vbz1qNn09MJ7tNp7qMzw==} + engines: {node: '>=14'} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-port-please@3.1.2: + resolution: {integrity: sha512-Gxc29eLs1fbn6LQ4jSU4vXjlwyZhF5HsGuMAa7gqBP4Rw4yxxltyDUuF5MBclFzDTXO+ACchGQoeela4DSfzdQ==} + + get-port@7.1.0: + resolution: {integrity: sha512-QB9NKEeDg3xxVwCCwJQ9+xycaz6pBB6iQ76wiWMl1927n0Kir6alPiP+yuiICLLU4jpMe08dXfpebuQppFA2zw==} + engines: {node: '>=16'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-stream@5.2.0: + resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} + engines: {node: '>=8'} + + get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + + get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + + get-stream@9.0.1: + resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} + engines: {node: '>=18'} + + giget@2.0.0: + resolution: {integrity: sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==} + hasBin: true + + git-up@8.1.1: + resolution: {integrity: sha512-FDenSF3fVqBYSaJoYy1KSc2wosx0gCvKP+c+PRBht7cAaiCeQlBtfBDX9vgnNOHmdePlSFITVcn4pFfcgNvx3g==} + + git-url-parse@16.1.0: + resolution: {integrity: sha512-cPLz4HuK86wClEW7iDdeAKcCVlWXmrLpb2L+G9goW0Z1dtpNS6BXXSOckUTlJT/LDQViE1QZKstNORzHsLnobw==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + + glob@7.2.0: + resolution: {integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==} + deprecated: Glob versions prior to v9 are no longer supported + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + + glob@8.1.0: + resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} + engines: {node: '>=12'} + deprecated: Glob versions prior to v9 are no longer supported + + global-directory@4.0.1: + resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} + engines: {node: '>=18'} + + globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + globby@14.1.0: + resolution: {integrity: sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==} + engines: {node: '>=18'} + + globby@7.1.1: + resolution: {integrity: sha512-yANWAN2DUcBtuus5Cpd+SKROzXHs2iVXFZt/Ykrfz6SAXqacLX25NZpltE+39ceMexYF4TtEadjuSTw8+3wX4g==} + engines: {node: '>=4'} + + gonzales-pe@4.3.0: + resolution: {integrity: sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==} + engines: {node: '>=0.6.0'} + hasBin: true + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + graphql@16.8.1: + resolution: {integrity: sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==} + engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} + + gzip-size@6.0.0: + resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==} + engines: {node: '>=10'} + + gzip-size@7.0.0: + resolution: {integrity: sha512-O1Ld7Dr+nqPnmGpdhzLmMTQ4vAsD+rHwMm1NLUmoUFFymBOMKxCCrtDxqdBRYXdeEPEi3SyoR4TizJLQrnKBNA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + h3@1.15.3: + resolution: {integrity: sha512-z6GknHqyX0h9aQaTx22VZDf6QyZn+0Nh+Ym8O/u0SGSkyF5cuTJYKlc8MkzW3Nzf9LE1ivcpmYC3FUGpywhuUQ==} + + happy-dom@15.10.2: + resolution: {integrity: sha512-NbA5XrSovenJIIcfixCREX3ZnV7yHP4phhbfuxxf4CPn+LZpz/jIM9EqJ2DrPwgVDSMoAKH3pZwQvkbsSiCrUw==} + engines: {node: '>=18.0.0'} + + hardhat@2.22.3: + resolution: {integrity: sha512-k8JV2ECWNchD6ahkg2BR5wKVxY0OiKot7fuxiIpRK0frRqyOljcR2vKwgWSLw6YIeDcNNA4xybj7Og7NSxr2hA==} + hasBin: true + peerDependencies: + ts-node: '*' + typescript: '*' + peerDependenciesMeta: + ts-node: + optional: true + typescript: + optional: true + + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + has-unicode@2.0.1: + resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} + + hash-base@3.1.0: + resolution: {integrity: sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==} + engines: {node: '>=4'} + + hash.js@1.1.7: + resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + hast-util-to-html@9.0.3: + resolution: {integrity: sha512-M17uBDzMJ9RPCqLMO92gNNUDuBSq10a25SDBI08iCCxmorf4Yy6sYHK57n9WAbRAAaU+DuR4W6GN9K4DFZesYg==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + + he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + + headers-polyfill@4.0.2: + resolution: {integrity: sha512-EWGTfnTqAO2L/j5HZgoM/3z82L7necsJ0pO9Tp0X1wil3PDLrkypTBRgVO2ExehEEvUycejZD3FuRaXpZZc3kw==} + + help-me@5.0.0: + resolution: {integrity: sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==} + + highlight.js@10.7.3: + resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} + + hmac-drbg@1.0.1: + resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} + + hookable@5.5.3: + resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} + + hosted-git-info@7.0.2: + resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==} + engines: {node: ^16.14.0 || >=18.0.0} + + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + + html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + + http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + + http-proxy@1.18.1: + resolution: {integrity: sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==} + engines: {node: '>=8.0.0'} + + http-shutdown@1.2.2: + resolution: {integrity: sha512-S9wWkJ/VSY9/k4qcjG318bqJNruzE4HySUhFYknwmu6LBP97KLLfwNf+n4V1BHurvFNkSKLFnK/RsuUnRTf9Vw==} + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + + httpxy@0.1.7: + resolution: {integrity: sha512-pXNx8gnANKAndgga5ahefxc++tJvNL87CXoRwxn1cJE2ZkWEojF3tNfQIEhZX/vfpt+wzeAzpUI4qkediX1MLQ==} + + human-id@1.0.2: + resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} + + human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + + human-signals@4.3.1: + resolution: {integrity: sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==} + engines: {node: '>=14.18.0'} + + human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + + human-signals@7.0.0: + resolution: {integrity: sha512-74kytxOUSvNbjrT9KisAbaTZ/eJwD/LrbM/kh5j0IhPuJzwuA19dWvniFGwBzN9rVjg+O/e+F310PjObDXS+9Q==} + engines: {node: '>=18.18.0'} + + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + idb-keyval@6.2.1: + resolution: {integrity: sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg==} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + ignore@3.3.10: + resolution: {integrity: sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + ignore@7.0.4: + resolution: {integrity: sha512-gJzzk+PQNznz8ysRrC0aOkBNVRBDtE1n53IqyqEf3PXrYwomFs5q4pGMizBMJF+ykh03insJ27hB8gSrD2Hn8A==} + engines: {node: '>= 4'} + + image-meta@0.2.1: + resolution: {integrity: sha512-K6acvFaelNxx8wc2VjbIzXKDVB0Khs0QT35U6NkGfTdCmjLNcO2945m7RFNR9/RPVFm48hq7QPzK8uGH18HCGw==} + + immutable@4.3.5: + resolution: {integrity: sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==} + + impound@0.2.2: + resolution: {integrity: sha512-9CNg+Ly8QjH4FwCUoE9nl1zeqY1NPK1s1P6Btp4L8lJxn8oZLN/0p6RZhitnyEL0BnVWrcVPfbs0Q3x+O/ucHg==} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + + index-to-position@1.1.0: + resolution: {integrity: sha512-XPdx9Dq4t9Qk1mTMbWONJqU7boCoumEH7fRET37HX5+khDUl3J2W6PdALxhILYlIYx2amlwYcRPp28p0tSiojg==} + engines: {node: '>=18'} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + + ini@4.1.1: + resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + io-ts@1.10.4: + resolution: {integrity: sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==} + + ioredis@5.6.1: + resolution: {integrity: sha512-UxC0Yv1Y4WRJiGQxQkP0hfdL0/5/6YvdfOOClRgJ0qppSarkhneSa6UvkMkms0AkdGimSH3Ikqm+6mkMmX7vGA==} + engines: {node: '>=12.22.0'} + + iron-webcrypto@1.2.1: + resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} + + is-arguments@1.2.0: + resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} + engines: {node: '>= 0.4'} + + is-arrayish@0.3.2: + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-builtin-module@3.2.1: + resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==} + engines: {node: '>=6'} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-generator-function@1.1.0: + resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} + engines: {node: '>= 0.4'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-hex-prefixed@1.0.0: + resolution: {integrity: sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==} + engines: {node: '>=6.5.0', npm: '>=3'} + + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + + is-installed-globally@1.0.0: + resolution: {integrity: sha512-K55T22lfpQ63N4KEN57jZUAaAYqYHEe8veb/TycJRk9DdSCLLcovXz/mL6mOnhQaZsQGwPhuFopdQIlqGSEjiQ==} + engines: {node: '>=18'} + + is-module@1.0.0: + resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} + + is-node-process@1.2.0: + resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-path-inside@4.0.0: + resolution: {integrity: sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==} + engines: {node: '>=12'} + + is-plain-obj@2.1.0: + resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} + engines: {node: '>=8'} + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + is-plain-object@5.0.0: + resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} + engines: {node: '>=0.10.0'} + + is-reference@1.2.1: + resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} + + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + is-ssh@1.4.1: + resolution: {integrity: sha512-JNeu1wQsHjyHgn9NcWTaXq6zWSR6hqE0++zhfZlkFBbScNkyvxCdeV8sRkSBaeLKxmbpR21brail63ACNxJ0Tg==} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + is-stream@4.0.1: + resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} + engines: {node: '>=18'} + + is-subdir@1.2.0: + resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} + engines: {node: '>=4'} + + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + + is-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + + is-unicode-supported@2.0.0: + resolution: {integrity: sha512-FRdAyx5lusK1iHG0TWpVtk9+1i+GjrzRffhDg4ovQ7mcidMQ6mj+MhKPmvh7Xwyv5gIS06ns49CA7Sqg7lC22Q==} + engines: {node: '>=18'} + + is-url-superb@4.0.0: + resolution: {integrity: sha512-GI+WjezhPPcbM+tqE9LnmsY5qqjwHzTvjJ36wxYX5ujNXefSUJ/T17r5bqDV8yLhcgB59KTPNOc9O9cmHTPWsA==} + engines: {node: '>=10'} + + is-url@1.2.4: + resolution: {integrity: sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==} + + is-what@4.1.16: + resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} + engines: {node: '>=12.13'} + + is-windows@1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} + + is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + + is-wsl@3.1.0: + resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} + engines: {node: '>=16'} + + is64bit@2.0.0: + resolution: {integrity: sha512-jv+8jaWCl0g2lSBkNSVXdzfBA0npK1HGC2KtWM9FumFRoGS94g3NbCCLVnCYHLjp4GrW2KZeeSTMo5ddtznmGw==} + engines: {node: '>=18'} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isexe@3.1.1: + resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==} + engines: {node: '>=16'} + + isows@1.0.4: + resolution: {integrity: sha512-hEzjY+x9u9hPmBom9IIAqdJCwNLax+xrPb51vEPpERoFlIxgmZcHzsT5jKG06nvInKOBGvReAVz80Umed5CczQ==} + peerDependencies: + ws: '*' + + isows@1.0.6: + resolution: {integrity: sha512-lPHCayd40oW98/I0uvgaHKWCSvkzY27LjWLbtzOm64yQ+G3Q5npjjbdppU65iZXkK1Zt+kH9pfegli0AYfwYYw==} + peerDependencies: + ws: '*' + + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + + istanbul-lib-source-maps@5.0.6: + resolution: {integrity: sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==} + engines: {node: '>=10'} + + istanbul-reports@3.1.7: + resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} + engines: {node: '>=8'} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + jiti@1.21.0: + resolution: {integrity: sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==} + hasBin: true + + jiti@1.21.6: + resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==} + hasBin: true + + jiti@1.21.7: + resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} + hasBin: true + + jiti@2.4.2: + resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} + hasBin: true + + joycon@3.1.1: + resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} + engines: {node: '>=10'} + + js-beautify@1.15.1: + resolution: {integrity: sha512-ESjNzSlt/sWE8sciZH8kBF8BPlwXPwhR6pWKAw8bw4Bwj+iZcnKW6ONWUutJ7eObuBZQpiIb8S7OYspWrKt7rA==} + engines: {node: '>=14'} + hasBin: true + + js-cookie@3.0.5: + resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==} + engines: {node: '>=14'} + + js-sha3@0.8.0: + resolution: {integrity: sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-tokens@9.0.1: + resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} + + js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + jsesc@2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-rpc-engine@6.1.0: + resolution: {integrity: sha512-NEdLrtrq1jUZyfjkr9OCz9EzCNhnRyWtt1PAnvnhwy6e8XETS0Dtc+ZNCO2gvuAoKsIn2+vCSowXTYE4CkgnAQ==} + engines: {node: '>=10.0.0'} + + json-rpc-random-id@1.0.1: + resolution: {integrity: sha512-RJ9YYNCkhVDBuP4zN5BBtYAzEl03yq/jIIsyif0JY9qyJuQQZNeDK7anAPKKlyEtLSj2s8h6hNh2F8zO5q7ScA==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonfile@2.4.0: + resolution: {integrity: sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==} + + jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + + junk@4.0.1: + resolution: {integrity: sha512-Qush0uP+G8ZScpGMZvHUiRfI0YBWuB3gVBYlI0v0vvOJt5FLicco+IkP0a50LqTTQhmts/m6tP5SWE+USyIvcQ==} + engines: {node: '>=12.20'} + + jwt-decode@4.0.0: + resolution: {integrity: sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==} + engines: {node: '>=18'} + + keccak@3.0.3: + resolution: {integrity: sha512-JZrLIAJWuZxKbCilMpNz5Vj7Vtb4scDG3dMXLOsbzBmQGyjwE61BbW7bJkfKKCShXiQZt3T6sBgALRtmd+nZaQ==} + engines: {node: '>=10.0.0'} + + keyvaluestorage-interface@1.0.0: + resolution: {integrity: sha512-8t6Q3TclQ4uZynJY9IGr2+SsIGwK9JHcO6ootkHCGA0CrQCRy+VkouYNO2xicET6b9al7QKzpebNow+gkpCL8g==} + + klaw@1.3.1: + resolution: {integrity: sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==} + + kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + + kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + + klona@2.0.6: + resolution: {integrity: sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==} + engines: {node: '>= 8'} + + knip@5.30.6: + resolution: {integrity: sha512-YkcnRVl0N99xZ7eaXE7KlH/4cPTCn6BGuk9KxINEdCMFN3yita2vGBizApy97ZOHgghy8tb589gQ3xvLMFIO4w==} + engines: {node: '>=18.6.0'} + hasBin: true + peerDependencies: + '@types/node': '>=18' + typescript: '>=5.0.4' + + knitwork@1.2.0: + resolution: {integrity: sha512-xYSH7AvuQ6nXkq42x0v5S8/Iry+cfulBz/DJQzhIyESdLD7425jXsPy4vn5cCXU+HhRN2kVw51Vd1K6/By4BQg==} + + kolorist@1.8.0: + resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} + + kuler@2.0.0: + resolution: {integrity: sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==} + + lambda-local@2.2.0: + resolution: {integrity: sha512-bPcgpIXbHnVGfI/omZIlgucDqlf4LrsunwoKue5JdZeGybt8L6KyJz2Zu19ffuZwIwLj2NAI2ZyaqNT6/cetcg==} + engines: {node: '>=8'} + hasBin: true + + launch-editor@2.10.0: + resolution: {integrity: sha512-D7dBRJo/qcGX9xlvt/6wUYzQxjh5G1RvZPgPv8vi4KRU99DVQL/oW7tnVOCCTm2HGeo3C5HvGE5Yrh6UBoZ0vA==} + + lazystream@1.0.1: + resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} + engines: {node: '>= 0.6.3'} + + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + + listhen@1.7.2: + resolution: {integrity: sha512-7/HamOm5YD9Wb7CFgAZkKgVPA96WwhcTQoqtm2VTZGVbVVn3IWKRBTgrU7cchA3Q8k9iCsG8Osoi9GX4JsGM9g==} + hasBin: true + + listhen@1.9.0: + resolution: {integrity: sha512-I8oW2+QL5KJo8zXNWX046M134WchxsXC7SawLPvRQpogCbkyQIaFxPE89A2HiwR7vAK2Dm2ERBAmyjTYGYEpBg==} + hasBin: true + + lit-element@4.2.0: + resolution: {integrity: sha512-MGrXJVAI5x+Bfth/pU9Kst1iWID6GHDLEzFEnyULB/sFiRLgkd8NPK/PeeXxktA3T6EIIaq8U3KcbTU5XFcP2Q==} + + lit-html@3.3.0: + resolution: {integrity: sha512-RHoswrFAxY2d8Cf2mm4OZ1DgzCoBKUKSPvA1fhtSELxUERq2aQQ2h05pO9j81gS1o7RIRJ+CePLogfyahwmynw==} + + lit@3.1.0: + resolution: {integrity: sha512-rzo/hmUqX8zmOdamDAeydfjsGXbbdtAFqMhmocnh2j9aDYqbu0fjXygjCa0T99Od9VQ/2itwaGrjZz/ZELVl7w==} + + load-tsconfig@0.2.5: + resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + local-pkg@0.5.0: + resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} + engines: {node: '>=14'} + + local-pkg@0.5.1: + resolution: {integrity: sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==} + engines: {node: '>=14'} + + local-pkg@1.1.1: + resolution: {integrity: sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==} + engines: {node: '>=14'} + + locate-path@2.0.0: + resolution: {integrity: sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==} + engines: {node: '>=4'} + + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + locate-path@7.2.0: + resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + lodash-es@4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + + lodash.debounce@4.0.8: + resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + + lodash.defaults@4.2.0: + resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==} + + lodash.difference@4.5.0: + resolution: {integrity: sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==} + + lodash.flatten@4.4.0: + resolution: {integrity: sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==} + + lodash.isarguments@3.1.0: + resolution: {integrity: sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==} + + lodash.isplainobject@4.0.6: + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + + lodash.memoize@4.1.2: + resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} + + lodash.startcase@4.4.0: + resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + + lodash.union@4.6.0: + resolution: {integrity: sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==} + + lodash.uniq@4.5.0: + resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + log-symbols@4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} + + logform@2.7.0: + resolution: {integrity: sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==} + engines: {node: '>= 12.0.0'} + + lokijs@1.5.12: + resolution: {integrity: sha512-Q5ALD6JiS6xAUWCwX3taQmgwxyveCtIIuL08+ml0nHwT3k0S/GIFJN+Hd38b1qYIMaE5X++iqsqWVksz7SYW+Q==} + + longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + loupe@3.1.3: + resolution: {integrity: sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==} + + lru-cache@10.2.2: + resolution: {integrity: sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==} + engines: {node: 14 || >=16.14} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + lru-cache@4.1.5: + resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + + lru_map@0.3.3: + resolution: {integrity: sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==} + + luxon@3.6.1: + resolution: {integrity: sha512-tJLxrKJhO2ukZ5z0gyjY1zPh3Rh88Ej9P7jNrZiHMUXHae1yvI2imgOZtL1TO8TW6biMMKfTtAOoEJANgtWBMQ==} + engines: {node: '>=12'} + + lz-string@1.5.0: + resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} + hasBin: true + + magic-string-ast@0.7.1: + resolution: {integrity: sha512-ub9iytsEbT7Yw/Pd29mSo/cNQpaEu67zR1VVcXDiYjSFwzeBxNdTd0FMnSslLQXiRj8uGPzwsaoefrMD5XAmdw==} + engines: {node: '>=16.14.0'} + + magic-string@0.30.10: + resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} + + magic-string@0.30.11: + resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==} + + magic-string@0.30.12: + resolution: {integrity: sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==} + + magic-string@0.30.17: + resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + + magicast@0.3.4: + resolution: {integrity: sha512-TyDF/Pn36bBji9rWKHlZe+PZb6Mx5V8IHCSxk7X4aljM4e/vyDvZZYwHewdVaqiA0nb3ghfHU/6AUpDxWoER2Q==} + + magicast@0.3.5: + resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} + + make-dir@3.1.0: + resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} + engines: {node: '>=8'} + + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + + mark.js@8.11.1: + resolution: {integrity: sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==} + + markdown-table@3.0.3: + resolution: {integrity: sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==} + + marked-terminal@7.1.0: + resolution: {integrity: sha512-+pvwa14KZL74MVXjYdPR3nSInhGhNvPce/3mqLVZT2oUvt654sL1XImFuLZ1pkA866IYZ3ikDTOFUIC7XzpZZg==} + engines: {node: '>=16.0.0'} + peerDependencies: + marked: '>=1 <14' + + marked@9.1.6: + resolution: {integrity: sha512-jcByLnIFkd5gSXZmjNvS1TlmRhCXZjIzHYlaGkPlLIekG55JDR2Z4va9tZwCiP+/RDERiNhMOFu01xd6O5ct1Q==} + engines: {node: '>= 16'} + hasBin: true + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + md5.js@1.3.5: + resolution: {integrity: sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==} + + mdast-util-find-and-replace@3.0.1: + resolution: {integrity: sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==} + + mdast-util-from-markdown@2.0.2: + resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==} + + mdast-util-gfm-autolink-literal@2.0.0: + resolution: {integrity: sha512-FyzMsduZZHSc3i0Px3PQcBT4WJY/X/RCtEJKuybiC6sjPqLv7h1yqAkmILZtuxMSsUyaLUWNp71+vQH2zqp5cg==} + + mdast-util-gfm-footnote@2.0.0: + resolution: {integrity: sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==} + + mdast-util-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} + + mdast-util-gfm-table@2.0.0: + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + + mdast-util-gfm-task-list-item@2.0.0: + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + + mdast-util-gfm@3.0.0: + resolution: {integrity: sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==} + + mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + + mdast-util-to-hast@13.1.0: + resolution: {integrity: sha512-/e2l/6+OdGp/FB+ctrJ9Avz71AN/GRH3oi/3KAx/kMnoUsD6q0woXlDT8lLEeViVKE7oZxE7RXzvO3T8kF2/sA==} + + mdast-util-to-hast@13.2.0: + resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==} + + mdast-util-to-markdown@2.1.0: + resolution: {integrity: sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==} + + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + + mdn-data@2.0.28: + resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} + + mdn-data@2.0.30: + resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} + + memorystream@0.3.1: + resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} + engines: {node: '>= 0.10.0'} + + merge-options@3.0.4: + resolution: {integrity: sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==} + engines: {node: '>=10'} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micro-api-client@3.3.0: + resolution: {integrity: sha512-y0y6CUB9RLVsy3kfgayU28746QrNMpSm9O/AYGNsBgOkJr/X/Jk0VLGoO8Ude7Bpa8adywzF+MzXNZRFRsNPhg==} + + micro-ftch@0.3.1: + resolution: {integrity: sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==} + + micromark-core-commonmark@2.0.1: + resolution: {integrity: sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==} + + micromark-factory-destination@2.0.0: + resolution: {integrity: sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==} + + micromark-factory-label@2.0.0: + resolution: {integrity: sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==} + + micromark-factory-space@2.0.0: + resolution: {integrity: sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==} + + micromark-factory-title@2.0.0: + resolution: {integrity: sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==} + + micromark-factory-whitespace@2.0.0: + resolution: {integrity: sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==} + + micromark-util-character@2.1.0: + resolution: {integrity: sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==} + + micromark-util-chunked@2.0.0: + resolution: {integrity: sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==} + + micromark-util-classify-character@2.0.0: + resolution: {integrity: sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==} + + micromark-util-combine-extensions@2.0.0: + resolution: {integrity: sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==} + + micromark-util-decode-numeric-character-reference@2.0.1: + resolution: {integrity: sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==} + + micromark-util-decode-string@2.0.0: + resolution: {integrity: sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==} + + micromark-util-encode@2.0.0: + resolution: {integrity: sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==} + + micromark-util-html-tag-name@2.0.0: + resolution: {integrity: sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==} + + micromark-util-normalize-identifier@2.0.0: + resolution: {integrity: sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==} + + micromark-util-resolve-all@2.0.0: + resolution: {integrity: sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==} + + micromark-util-sanitize-uri@2.0.0: + resolution: {integrity: sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==} + + micromark-util-subtokenize@2.0.1: + resolution: {integrity: sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==} + + micromark-util-symbol@2.0.0: + resolution: {integrity: sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==} + + micromark-util-types@2.0.0: + resolution: {integrity: sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==} + + micromark@4.0.0: + resolution: {integrity: sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==} + + micromatch@4.0.5: + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + engines: {node: '>=8.6'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} + + mime-types@3.0.1: + resolution: {integrity: sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==} + engines: {node: '>= 0.6'} + + mime@3.0.0: + resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} + engines: {node: '>=10.0.0'} + hasBin: true + + mime@4.0.7: + resolution: {integrity: sha512-2OfDPL+e03E0LrXaGYOtTFIYhiuzep94NSsuhrNULq+stylcJedcHdzHtz0atMUuGwJfFYs0YL5xeC/Ca2x0eQ==} + engines: {node: '>=16'} + hasBin: true + + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + + minimalistic-assert@1.0.1: + resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} + + minimalistic-crypto-utils@1.0.1: + resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@5.0.1: + resolution: {integrity: sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==} + engines: {node: '>=10'} + + minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} + + minimatch@9.0.1: + resolution: {integrity: sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==} + engines: {node: '>=16 || 14 >=14.17'} + + minimatch@9.0.4: + resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} + engines: {node: '>=16 || 14 >=14.17'} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass@3.3.6: + resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} + engines: {node: '>=8'} + + minipass@5.0.0: + resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} + engines: {node: '>=8'} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + minisearch@7.1.0: + resolution: {integrity: sha512-tv7c/uefWdEhcu6hvrfTihflgeEi2tN6VV7HJnCjK6VxM75QQJh4t9FwJCsA2EsRS8LCnu3W87CuGPWMocOLCA==} + + minizlib@2.1.2: + resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} + engines: {node: '>= 8'} + + minizlib@3.0.1: + resolution: {integrity: sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==} + engines: {node: '>= 18'} + + minizlib@3.0.2: + resolution: {integrity: sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==} + engines: {node: '>= 18'} + + mipd@0.0.7: + resolution: {integrity: sha512-aAPZPNDQ3uMTdKbuO2YmAw2TxLHO0moa4YKAyETM/DTj5FloZo+a+8tU+iv4GmW+sOxKLSRwcSFuczk+Cpt6fg==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + + mitt@3.0.1: + resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + + mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + + mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} + engines: {node: '>=10'} + hasBin: true + + mlly@1.7.0: + resolution: {integrity: sha512-U9SDaXGEREBYQgfejV97coK0UL1r+qnF2SyO9A3qcI8MzKnsIFKHNVEkrDyNncQTKQQumsasmeq84eNMdBfsNQ==} + + mlly@1.7.4: + resolution: {integrity: sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==} + + mnemonist@0.38.5: + resolution: {integrity: sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==} + + mocha@10.2.0: + resolution: {integrity: sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==} + engines: {node: '>= 14.0.0'} + hasBin: true + + mocked-exports@0.1.1: + resolution: {integrity: sha512-aF7yRQr/Q0O2/4pIXm6PZ5G+jAd7QS4Yu8m+WEeEHGnbo+7mE36CbLSDQiXYV8bVL3NfmdeqPJct0tUlnjVSnA==} + + module-definition@5.0.1: + resolution: {integrity: sha512-kvw3B4G19IXk+BOXnYq/D/VeO9qfHaapMeuS7w7sNUqmGaA6hywdFHMi+VWeR9wUScXM7XjoryTffCZ5B0/8IA==} + engines: {node: '>=14'} + hasBin: true + + mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + + mrmime@2.0.1: + resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} + engines: {node: '>=10'} + + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + msw@2.4.9: + resolution: {integrity: sha512-1m8xccT6ipN4PTqLinPwmzhxQREuxaEJYdx4nIbggxP8aM7r1e71vE7RtOUSQoAm1LydjGfZKy7370XD/tsuYg==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + typescript: '>= 4.8.x' + peerDependenciesMeta: + typescript: + optional: true + + muggle-string@0.4.1: + resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} + + multiformats@9.9.0: + resolution: {integrity: sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==} + + mute-stream@1.0.0: + resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + nanoid@3.3.3: + resolution: {integrity: sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + nanoid@5.1.5: + resolution: {integrity: sha512-Ir/+ZpE9fDsNH0hQ3C68uyThDXzYcim2EqcZ8zn8Chtt1iylPT9xXJB0kPCnqzgcEGikO9RxSrh63MsmVCU7Fw==} + engines: {node: ^18 || >=20} + hasBin: true + + nanospinner@1.2.2: + resolution: {integrity: sha512-Zt/AmG6qRU3e+WnzGGLuMCEAO/dAu45stNbHY223tUxldaDAeE+FxSPsd9Q+j+paejmm0ZbrNVs5Sraqy3dRxA==} + + nanotar@0.2.0: + resolution: {integrity: sha512-9ca1h0Xjvo9bEkE4UOxgAzLV0jHKe6LMaxo37ND2DAhhAtd0j8pR1Wxz+/goMrZO8AEZTWCmyaOsFI/W5AdpCQ==} + + nested-error-stacks@2.1.1: + resolution: {integrity: sha512-9iN1ka/9zmX1ZvLV9ewJYEk9h7RyRRtqdK0woXcqohu8EWIerfPUjYJPg0ULy0UqP7cslmdGc8xKDJcojlKiaw==} + + netlify@13.3.5: + resolution: {integrity: sha512-Nc3loyVASW59W+8fLDZT1lncpG7llffyZ2o0UQLx/Fr20i7P8oP+lE7+TEcFvXj9IUWU6LjB9P3BH+iFGyp+mg==} + engines: {node: ^14.16.0 || >=16.0.0} + + next@15.3.3: + resolution: {integrity: sha512-JqNj29hHNmCLtNvd090SyRbXJiivQ+58XjCcrC50Crb5g5u2zi7Y2YivbsEfzk6AtVI80akdOQbaMZwWB1Hthw==} + engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.41.2 + babel-plugin-react-compiler: '*' + react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + babel-plugin-react-compiler: + optional: true + sass: + optional: true + + nitropack@2.11.12: + resolution: {integrity: sha512-e2AdQrEY1IVoNTdyjfEQV93xkqz4SQxAMR0xWF8mZUUHxMLm6S4nPzpscjksmT4OdUxl0N8/DCaGjKQ9ghdodA==} + engines: {node: ^16.11.0 || >=17.0.0} + hasBin: true + peerDependencies: + xml2js: ^0.6.2 + peerDependenciesMeta: + xml2js: + optional: true + + node-addon-api@2.0.2: + resolution: {integrity: sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==} + + node-addon-api@7.0.0: + resolution: {integrity: sha512-vgbBJTS4m5/KkE16t5Ly0WW9hz46swAstv0hYYwMtbG7AznRhNyfLRe8HZAiWIpcHzoO7HxhLuBQj9rJ/Ho0ZA==} + + node-addon-api@7.1.1: + resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} + + node-domexception@1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} + deprecated: Use your platform's native DOMException instead + + node-emoji@2.1.3: + resolution: {integrity: sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==} + engines: {node: '>=18'} + + node-fetch-native@1.6.4: + resolution: {integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==} + + node-fetch-native@1.6.6: + resolution: {integrity: sha512-8Mc2HhqPdlIfedsuZoc3yioPuzp6b+L5jRCRY1QzuWZh2EGJVQrGppC6V6cF0bLdbW0+O2YpqCA25aF/1lvipQ==} + + node-fetch@2.6.7: + resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-fetch@2.6.9: + resolution: {integrity: sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-fetch@3.3.2: + resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + node-forge@1.3.1: + resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} + engines: {node: '>= 6.13.0'} + + node-gyp-build@4.6.0: + resolution: {integrity: sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==} + hasBin: true + + node-gyp-build@4.8.4: + resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} + hasBin: true + + node-mock-http@1.0.0: + resolution: {integrity: sha512-0uGYQ1WQL1M5kKvGRXWQ3uZCHtLTO8hln3oBjIusM75WoesZ909uQJs/Hb946i2SS+Gsrhkaa6iAO17jRIv6DQ==} + + node-releases@2.0.14: + resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} + + node-releases@2.0.19: + resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} + + node-source-walk@6.0.2: + resolution: {integrity: sha512-jn9vOIK/nfqoFCcpK89/VCVaLg1IHE6UVfDOzvqmANaJ/rWCTEdH8RZ1V278nv2jr36BJdyQXIAavBLXpzdlag==} + engines: {node: '>=14'} + + nopt@5.0.0: + resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==} + engines: {node: '>=6'} + hasBin: true + + nopt@7.2.1: + resolution: {integrity: sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true + + nopt@8.1.0: + resolution: {integrity: sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==} + engines: {node: ^18.17.0 || >=20.5.0} + hasBin: true + + normalize-package-data@6.0.2: + resolution: {integrity: sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==} + engines: {node: ^16.14.0 || >=18.0.0} + + normalize-path@2.1.1: + resolution: {integrity: sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==} + engines: {node: '>=0.10.0'} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + normalize-range@0.1.2: + resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} + engines: {node: '>=0.10.0'} + + npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + + npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + npm-run-path@6.0.0: + resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==} + engines: {node: '>=18'} + + npmlog@5.0.1: + resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==} + deprecated: This package is no longer supported. + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + nuxt@3.16.0: + resolution: {integrity: sha512-4j2tuHo+kcComQ1WrCD+i1w3UFOHrcnNH30cwiEY/WZZlBZOlC6DtUm6aBjhfpBFaMYsF4PbyKsNW+7FHwckHA==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@parcel/watcher': ^2.1.0 + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + peerDependenciesMeta: + '@parcel/watcher': + optional: true + '@types/node': + optional: true + + nypm@0.6.0: + resolution: {integrity: sha512-mn8wBFV9G9+UFHIrq+pZ2r2zL4aPau/by3kJb3cM7+5tQHMt6HGQB8FDIeKFYp8o0D2pnH6nVsO88N4AmUxIWg==} + engines: {node: ^14.16.0 || >=16.10.0} + hasBin: true + + obj-multiplex@1.0.0: + resolution: {integrity: sha512-0GNJAOsHoBHeNTvl5Vt6IWnpUEcc3uSRxzBri7EDyIcMgYvnY2JL2qdeV5zTMjWQX5OHcD5amcW2HFfDh0gjIA==} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + obliterator@2.0.4: + resolution: {integrity: sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==} + + ofetch@1.4.1: + resolution: {integrity: sha512-QZj2DfGplQAr2oj9KzceK9Hwz6Whxazmn85yYeVuS3u9XTMOGMRx0kO95MQ+vLsj/S/NwBDMMLU5hpxvI6Tklw==} + + ohash@2.0.11: + resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} + + on-change@5.0.1: + resolution: {integrity: sha512-n7THCP7RkyReRSLkJb8kUWoNsxUIBxTkIp3JKno+sEz6o/9AJ3w3P9fzQkITEkMwyTKJjZciF3v/pVoouxZZMg==} + engines: {node: '>=18'} + + on-exit-leak-free@0.2.0: + resolution: {integrity: sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg==} + + on-exit-leak-free@2.1.2: + resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} + engines: {node: '>=14.0.0'} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + one-time@1.0.0: + resolution: {integrity: sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==} + + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + + onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + + oniguruma-to-js@0.4.3: + resolution: {integrity: sha512-X0jWUcAlxORhOqqBREgPMgnshB7ZGYszBNspP+tS9hPD3l13CdaXcHbgImoHUHlrvGx/7AvFEkTRhAGYh+jzjQ==} + + open@10.1.2: + resolution: {integrity: sha512-cxN6aIDPz6rm8hbebcP7vrQNhvRcveZoJU72Y7vskh4oIm+BZwBECnx5nTmrlres1Qapvx27Qo1Auukpf8PKXw==} + engines: {node: '>=18'} + + open@8.4.2: + resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} + engines: {node: '>=12'} + + opener@1.5.2: + resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==} + hasBin: true + + os-tmpdir@1.0.2: + resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} + engines: {node: '>=0.10.0'} + + outdent@0.5.0: + resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} + + outvariant@1.4.2: + resolution: {integrity: sha512-Ou3dJ6bA/UJ5GVHxah4LnqDwZRwAmWxrG3wtrHrbGnP4RnLCtA64A4F+ae7Y8ww660JaddSoArUR5HjipWSHAQ==} + + outvariant@1.4.3: + resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==} + + ox@0.6.7: + resolution: {integrity: sha512-17Gk/eFsFRAZ80p5eKqv89a57uXjd3NgIf1CaXojATPBuujVc/fQSVhBeAU9JCRB+k7J50WQAyWTxK19T9GgbA==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + ox@0.6.9: + resolution: {integrity: sha512-wi5ShvzE4eOcTwQVsIPdFr+8ycyX+5le/96iAJutaZAvCes1J0+RvpEPg5QDPDiaR0XQQAvZVl7AwqQcINuUug==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + oxc-parser@0.56.5: + resolution: {integrity: sha512-MNT32sqiTFeSbQZP2WZIRQ/mlIpNNq4sua+/4hBG4qT5aef2iQe+1/BjezZURPlvucZeSfN1Y6b60l7OgBdyUA==} + engines: {node: '>=14.0.0'} + + p-event@5.0.1: + resolution: {integrity: sha512-dd589iCQ7m1L0bmC5NLlVYfy3TbBEsMUfWx9PyAgPeIcFZ/E2yaTZ4Rz4MiBmmJShviiftHVXOqfnfzJ6kyMrQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + p-filter@2.1.0: + resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} + engines: {node: '>=8'} + + p-limit@1.3.0: + resolution: {integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==} + engines: {node: '>=4'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-limit@4.0.0: + resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + p-locate@2.0.0: + resolution: {integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==} + engines: {node: '>=4'} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + p-locate@6.0.0: + resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + p-map@2.1.0: + resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} + engines: {node: '>=6'} + + p-map@4.0.0: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + engines: {node: '>=10'} + + p-map@7.0.3: + resolution: {integrity: sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==} + engines: {node: '>=18'} + + p-timeout@5.1.0: + resolution: {integrity: sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==} + engines: {node: '>=12'} + + p-timeout@6.1.4: + resolution: {integrity: sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==} + engines: {node: '>=14.16'} + + p-try@1.0.0: + resolution: {integrity: sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==} + engines: {node: '>=4'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + p-wait-for@5.0.2: + resolution: {integrity: sha512-lwx6u1CotQYPVju77R+D0vFomni/AqRfqLmqQ8hekklqZ6gAY9rONh7lBQ0uxWMkC2AuX9b2DVAl8To0NyP1JA==} + engines: {node: '>=12'} + + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + + package-manager-detector@0.2.0: + resolution: {integrity: sha512-E385OSk9qDcXhcM9LNSe4sdhx8a9mAPrZ4sMLW+tmxl5ZuGtPUcdFu+MPP2jbgiWAZ6Pfe5soGFMd+0Db5Vrog==} + + package-manager-detector@1.3.0: + resolution: {integrity: sha512-ZsEbbZORsyHuO00lY1kV3/t72yp6Ysay6Pd17ZAlNGuGwmWDLCJxFpRs0IzfXfj1o4icJOkUEioexFHzyPurSQ==} + + parse-gitignore@2.0.0: + resolution: {integrity: sha512-RmVuCHWsfu0QPNW+mraxh/xjQVw/lhUCUru8Zni3Ctq3AoMhpDTq0OVdKS6iesd6Kqb7viCV3isAL43dciOSog==} + engines: {node: '>=14'} + + parse-json@8.3.0: + resolution: {integrity: sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==} + engines: {node: '>=18'} + + parse-ms@4.0.0: + resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} + engines: {node: '>=18'} + + parse-path@7.1.0: + resolution: {integrity: sha512-EuCycjZtfPcjWk7KTksnJ5xPMvWGA/6i4zrLYhRG0hGvC3GPU/jGUj3Cy+ZR0v30duV3e23R95T1lE2+lsndSw==} + + parse-url@9.2.0: + resolution: {integrity: sha512-bCgsFI+GeGWPAvAiUv63ZorMeif3/U0zaXABGJbOWt5OH2KCaPHF6S+0ok4aqM9RuIPGyZdx9tR9l13PsW4AYQ==} + engines: {node: '>=14.13.0'} + + parse5-htmlparser2-tree-adapter@6.0.1: + resolution: {integrity: sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==} + + parse5@5.1.1: + resolution: {integrity: sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==} + + parse5@6.0.1: + resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + + path-exists@3.0.0: + resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} + engines: {node: '>=4'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-exists@5.0.0: + resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + path-to-regexp@6.3.0: + resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} + + path-type@3.0.0: + resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} + engines: {node: '>=4'} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + path-type@6.0.0: + resolution: {integrity: sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==} + engines: {node: '>=18'} + + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + pathval@2.0.0: + resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} + engines: {node: '>= 14.16'} + + pbkdf2@3.1.2: + resolution: {integrity: sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==} + engines: {node: '>=0.12'} + + pend@1.2.0: + resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} + + perfect-debounce@1.0.0: + resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} + + picocolors@1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + + picocolors@1.1.0: + resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + engines: {node: '>=12'} + + pify@3.0.0: + resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} + engines: {node: '>=4'} + + pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + + pify@5.0.0: + resolution: {integrity: sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==} + engines: {node: '>=10'} + + pino-abstract-transport@0.5.0: + resolution: {integrity: sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ==} + + pino-abstract-transport@2.0.0: + resolution: {integrity: sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==} + + pino-pretty@13.0.0: + resolution: {integrity: sha512-cQBBIVG3YajgoUjo1FdKVRX6t9XPxwB9lcNJVD5GCnNM4Y6T12YYx8c6zEejxQsU0wrg9TwmDulcE9LR7qcJqA==} + hasBin: true + + pino-std-serializers@4.0.0: + resolution: {integrity: sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q==} + + pino@7.11.0: + resolution: {integrity: sha512-dMACeu63HtRLmCG8VKdy4cShCPKaYDR4youZqoSWLxl5Gu99HUw8bw75thbPv9Nip+H+QYX8o3ZJbTdVZZ2TVg==} + hasBin: true + + pkg-types@1.1.0: + resolution: {integrity: sha512-/RpmvKdxKf8uILTtoOhAgf30wYbP2Qw+L9p3Rvshx1JZVX+XQNZQFjlbmGHEGIm4CkVPlSn+NXmIM8+9oWQaSA==} + + pkg-types@1.1.1: + resolution: {integrity: sha512-ko14TjmDuQJ14zsotODv7dBlwxKhUKQEhuhmbqo1uCi9BB0Z2alo/wAXg6q1dTR5TyuqYyWhjtfe/Tsh+X28jQ==} + + pkg-types@1.3.1: + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + + pkg-types@2.1.0: + resolution: {integrity: sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==} + + pngjs@5.0.0: + resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==} + engines: {node: '>=10.13.0'} + + pony-cause@2.1.11: + resolution: {integrity: sha512-M7LhCsdNbNgiLYiP4WjsfLUuFmCfnjdF6jKe2R9NKl4WFN+HZPGHJZ9lnLP7f9ZnKe3U9nuWD0szirmj+migUg==} + engines: {node: '>=12.0.0'} + + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + + postcss-calc@10.1.1: + resolution: {integrity: sha512-NYEsLHh8DgG/PRH2+G9BTuUdtf9ViS+vdoQ0YA5OQdGsfN4ztiwtDWNtBl9EKeqNMFnIu8IKZ0cLxEQ5r5KVMw==} + engines: {node: ^18.12 || ^20.9 || >=22.0} + peerDependencies: + postcss: ^8.4.38 + + postcss-colormin@7.0.3: + resolution: {integrity: sha512-xZxQcSyIVZbSsl1vjoqZAcMYYdnJsIyG8OvqShuuqf12S88qQboxxEy0ohNCOLwVPXTU+hFHvJPACRL2B5ohTA==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-convert-values@7.0.5: + resolution: {integrity: sha512-0VFhH8nElpIs3uXKnVtotDJJNX0OGYSZmdt4XfSfvOMrFw1jKfpwpZxfC4iN73CTM/MWakDEmsHQXkISYj4BXw==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-discard-comments@7.0.4: + resolution: {integrity: sha512-6tCUoql/ipWwKtVP/xYiFf1U9QgJ0PUvxN7pTcsQ8Ns3Fnwq1pU5D5s1MhT/XySeLq6GXNvn37U46Ded0TckWg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-discard-duplicates@7.0.2: + resolution: {integrity: sha512-eTonaQvPZ/3i1ASDHOKkYwAybiM45zFIc7KXils4mQmHLqIswXD9XNOKEVxtTFnsmwYzF66u4LMgSr0abDlh5w==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-discard-empty@7.0.1: + resolution: {integrity: sha512-cFrJKZvcg/uxB6Ijr4l6qmn3pXQBna9zyrPC+sK0zjbkDUZew+6xDltSF7OeB7rAtzaaMVYSdbod+sZOCWnMOg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-discard-overridden@7.0.1: + resolution: {integrity: sha512-7c3MMjjSZ/qYrx3uc1940GSOzN1Iqjtlqe8uoSg+qdVPYyRb0TILSqqmtlSFuE4mTDECwsm397Ya7iXGzfF7lg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-merge-longhand@7.0.5: + resolution: {integrity: sha512-Kpu5v4Ys6QI59FxmxtNB/iHUVDn9Y9sYw66D6+SZoIk4QTz1prC4aYkhIESu+ieG1iylod1f8MILMs1Em3mmIw==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-merge-rules@7.0.5: + resolution: {integrity: sha512-ZonhuSwEaWA3+xYbOdJoEReKIBs5eDiBVLAGpYZpNFPzXZcEE5VKR7/qBEQvTZpiwjqhhqEQ+ax5O3VShBj9Wg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-minify-font-values@7.0.1: + resolution: {integrity: sha512-2m1uiuJeTplll+tq4ENOQSzB8LRnSUChBv7oSyFLsJRtUgAAJGP6LLz0/8lkinTgxrmJSPOEhgY1bMXOQ4ZXhQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-minify-gradients@7.0.1: + resolution: {integrity: sha512-X9JjaysZJwlqNkJbUDgOclyG3jZEpAMOfof6PUZjPnPrePnPG62pS17CjdM32uT1Uq1jFvNSff9l7kNbmMSL2A==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-minify-params@7.0.3: + resolution: {integrity: sha512-vUKV2+f5mtjewYieanLX0xemxIp1t0W0H/D11u+kQV/MWdygOO7xPMkbK+r9P6Lhms8MgzKARF/g5OPXhb8tgg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-minify-selectors@7.0.5: + resolution: {integrity: sha512-x2/IvofHcdIrAm9Q+p06ZD1h6FPcQ32WtCRVodJLDR+WMn8EVHI1kvLxZuGKz/9EY5nAmI6lIQIrpo4tBy5+ug==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-normalize-charset@7.0.1: + resolution: {integrity: sha512-sn413ofhSQHlZFae//m9FTOfkmiZ+YQXsbosqOWRiVQncU2BA3daX3n0VF3cG6rGLSFVc5Di/yns0dFfh8NFgQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-normalize-display-values@7.0.1: + resolution: {integrity: sha512-E5nnB26XjSYz/mGITm6JgiDpAbVuAkzXwLzRZtts19jHDUBFxZ0BkXAehy0uimrOjYJbocby4FVswA/5noOxrQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-normalize-positions@7.0.1: + resolution: {integrity: sha512-pB/SzrIP2l50ZIYu+yQZyMNmnAcwyYb9R1fVWPRxm4zcUFCY2ign7rcntGFuMXDdd9L2pPNUgoODDk91PzRZuQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-normalize-repeat-style@7.0.1: + resolution: {integrity: sha512-NsSQJ8zj8TIDiF0ig44Byo3Jk9e4gNt9x2VIlJudnQQ5DhWAHJPF4Tr1ITwyHio2BUi/I6Iv0HRO7beHYOloYQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-normalize-string@7.0.1: + resolution: {integrity: sha512-QByrI7hAhsoze992kpbMlJSbZ8FuCEc1OT9EFbZ6HldXNpsdpZr+YXC5di3UEv0+jeZlHbZcoCADgb7a+lPmmQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-normalize-timing-functions@7.0.1: + resolution: {integrity: sha512-bHifyuuSNdKKsnNJ0s8fmfLMlvsQwYVxIoUBnowIVl2ZAdrkYQNGVB4RxjfpvkMjipqvbz0u7feBZybkl/6NJg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-normalize-unicode@7.0.3: + resolution: {integrity: sha512-EcoA29LvG3F+EpOh03iqu+tJY3uYYKzArqKJHxDhUYLa2u58aqGq16K6/AOsXD9yqLN8O6y9mmePKN5cx6krOw==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-normalize-url@7.0.1: + resolution: {integrity: sha512-sUcD2cWtyK1AOL/82Fwy1aIVm/wwj5SdZkgZ3QiUzSzQQofrbq15jWJ3BA7Z+yVRwamCjJgZJN0I9IS7c6tgeQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-normalize-whitespace@7.0.1: + resolution: {integrity: sha512-vsbgFHMFQrJBJKrUFJNZ2pgBeBkC2IvvoHjz1to0/0Xk7sII24T0qFOiJzG6Fu3zJoq/0yI4rKWi7WhApW+EFA==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-ordered-values@7.0.2: + resolution: {integrity: sha512-AMJjt1ECBffF7CEON/Y0rekRLS6KsePU6PRP08UqYW4UGFRnTXNrByUzYK1h8AC7UWTZdQ9O3Oq9kFIhm0SFEw==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-reduce-initial@7.0.3: + resolution: {integrity: sha512-RFvkZaqiWtGMlVjlUHpaxGqEL27lgt+Q2Ixjf83CRAzqdo+TsDyGPtJUbPx2MuYIJ+sCQc2TrOvRnhcXQfgIVA==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-reduce-transforms@7.0.1: + resolution: {integrity: sha512-MhyEbfrm+Mlp/36hvZ9mT9DaO7dbncU0CvWI8V93LRkY6IYlu38OPg3FObnuKTUxJ4qA8HpurdQOo5CyqqO76g==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-selector-parser@7.1.0: + resolution: {integrity: sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==} + engines: {node: '>=4'} + + postcss-svgo@7.0.2: + resolution: {integrity: sha512-5Dzy66JlnRM6pkdOTF8+cGsB1fnERTE8Nc+Eed++fOWo1hdsBptCsbG8UuJkgtZt75bRtMJIrPeZmtfANixdFA==} + engines: {node: ^18.12.0 || ^20.9.0 || >= 18} + peerDependencies: + postcss: ^8.4.32 + + postcss-unique-selectors@7.0.4: + resolution: {integrity: sha512-pmlZjsmEAG7cHd7uK3ZiNSW6otSZ13RHuZ/4cDN/bVglS5EpF2r2oxY99SuOHa8m7AWoBCelTS3JPpzsIs8skQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + postcss-values-parser@6.0.2: + resolution: {integrity: sha512-YLJpK0N1brcNJrs9WatuJFtHaV9q5aAOj+S4DI5S7jgHlRfm0PIbDCAFRYMQD5SHq7Fy6xsDhyutgS0QOAs0qw==} + engines: {node: '>=10'} + peerDependencies: + postcss: ^8.2.9 + + postcss@8.4.31: + resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} + engines: {node: ^10 || ^12 || >=14} + + postcss@8.4.47: + resolution: {integrity: sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==} + engines: {node: ^10 || ^12 || >=14} + + postcss@8.5.3: + resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} + engines: {node: ^10 || ^12 || >=14} + + postcss@8.5.5: + resolution: {integrity: sha512-d/jtm+rdNT8tpXuHY5MMtcbJFBkhXE6593XVR9UoGCH8jSFGci7jGvMGH5RYd5PBJW+00NZQt6gf7CbagJCrhg==} + engines: {node: ^10 || ^12 || >=14} + + preact@10.17.1: + resolution: {integrity: sha512-X9BODrvQ4Ekwv9GURm9AKAGaomqXmip7NQTZgY7gcNmr7XE83adOMJvd3N42id1tMFU7ojiynRsYnY6/BRFxLA==} + + preact@10.24.3: + resolution: {integrity: sha512-Z2dPnBnMUfyQfSQ+GBdsGa16hz35YmLmtTLhM169uW944hYL6xzTYkJjC07j+Wosz733pMWx0fgON3JNw1jJQA==} + + precinct@11.0.5: + resolution: {integrity: sha512-oHSWLC8cL/0znFhvln26D14KfCQFFn4KOLSw6hmLhd+LQ2SKt9Ljm89but76Pc7flM9Ty1TnXyrA2u16MfRV3w==} + engines: {node: ^14.14.0 || >=16.0.0} + hasBin: true + + prettier@2.8.8: + resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} + engines: {node: '>=10.13.0'} + hasBin: true + + prettier@3.0.3: + resolution: {integrity: sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==} + engines: {node: '>=14'} + hasBin: true + + pretty-bytes@6.1.1: + resolution: {integrity: sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==} + engines: {node: ^14.13.1 || >=16.0.0} + + pretty-format@27.5.1: + resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + pretty-ms@9.0.0: + resolution: {integrity: sha512-E9e9HJ9R9NasGOgPaPE8VMeiPKAyWR5jcFpNnwIejslIhWqdqOrb2wShBsncMPUb+BcCd2OPYfh7p2W6oemTng==} + engines: {node: '>=18'} + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + process-warning@1.0.0: + resolution: {integrity: sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q==} + + process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + + prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + + prool@0.0.23: + resolution: {integrity: sha512-r1d0DIiVsp7aXqGiNGKmgrqJZa8GjMGEjsgjQO22DEClYYvK+HMPZTQ9diBqleGuwfiRk3lnsWRMbFTRmFbk9g==} + engines: {node: '>=22'} + peerDependencies: + '@pimlico/alto': '*' + peerDependenciesMeta: + '@pimlico/alto': + optional: true + + property-information@6.5.0: + resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==} + + proto-list@1.2.4: + resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} + + protocols@2.0.2: + resolution: {integrity: sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ==} + + proxy-compare@2.6.0: + resolution: {integrity: sha512-8xuCeM3l8yqdmbPoYeLbrAXCBWu19XEYc5/F28f5qOaoAIMyfmBUkl5axiK+x9olUvRlcekvnm98AP9RDngOIw==} + + pseudomap@1.0.2: + resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} + + psl@1.9.0: + resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} + + publint@0.3.12: + resolution: {integrity: sha512-1w3MMtL9iotBjm1mmXtG3Nk06wnq9UhGNRpQ2j6n1Zq7YAD6gnxMMZMIxlRPAydVjVbjSm+n0lhwqsD1m4LD5w==} + engines: {node: '>=18'} + hasBin: true + + pump@3.0.2: + resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + qrcode@1.5.3: + resolution: {integrity: sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==} + engines: {node: '>=10.13.0'} + hasBin: true + + qs@6.14.0: + resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} + engines: {node: '>=0.6'} + + quansync@0.2.10: + resolution: {integrity: sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==} + + query-string@7.1.3: + resolution: {integrity: sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==} + engines: {node: '>=6'} + + querystringify@2.2.0: + resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + quick-format-unescaped@4.0.4: + resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + + quote-unquote@1.0.0: + resolution: {integrity: sha512-twwRO/ilhlG/FIgYeKGFqyHhoEhqgnKVkcmqMKi2r524gz3ZbDTcyFt38E9xjJI2vT+KbRNHVbnJ/e0I25Azwg==} + + radix3@1.1.2: + resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} + + randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@2.5.1: + resolution: {integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==} + engines: {node: '>= 0.8'} + + rc9@2.1.2: + resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==} + + react-dom@18.3.1: + resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} + peerDependencies: + react: ^18.3.1 + + react-is@17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + + react-refresh@0.14.0: + resolution: {integrity: sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==} + engines: {node: '>=0.10.0'} + + react@18.3.1: + resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + engines: {node: '>=0.10.0'} + + read-package-up@11.0.0: + resolution: {integrity: sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ==} + engines: {node: '>=18'} + + read-pkg@9.0.1: + resolution: {integrity: sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==} + engines: {node: '>=18'} + + read-yaml-file@1.1.0: + resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} + engines: {node: '>=6'} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + readable-stream@4.7.0: + resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + readdir-glob@1.1.3: + resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + real-require@0.1.0: + resolution: {integrity: sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg==} + engines: {node: '>= 12.13.0'} + + redis-errors@1.2.0: + resolution: {integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==} + engines: {node: '>=4'} + + redis-parser@3.0.0: + resolution: {integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==} + engines: {node: '>=4'} + + regenerator-runtime@0.14.0: + resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==} + + regex@4.4.0: + resolution: {integrity: sha512-uCUSuobNVeqUupowbdZub6ggI5/JZkYyJdDogddJr60L764oxC2pMZov1fQ3wM9bdyzUILDG+Sqx6NAKAz9rKQ==} + + remove-accents@0.5.0: + resolution: {integrity: sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A==} + + remove-trailing-separator@1.1.0: + resolution: {integrity: sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + require-main-filename@2.0.0: + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + + require-package-name@2.0.1: + resolution: {integrity: sha512-uuoJ1hU/k6M0779t3VMVIYpb2VMJk05cehCaABFhXaibcbvfgR8wKiozLjVFSzJPmQMRqIcO0HMyTFqfV09V6Q==} + + requires-port@1.0.0: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + resolve@1.17.0: + resolution: {integrity: sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==} + + resolve@1.22.10: + resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} + engines: {node: '>= 0.4'} + hasBin: true + + resolve@2.0.0-next.5: + resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} + hasBin: true + + reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rfdc@1.4.1: + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + + rimraf@2.7.1: + resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + rimraf@5.0.10: + resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} + hasBin: true + + ripemd160@2.0.2: + resolution: {integrity: sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==} + + rlp@2.2.7: + resolution: {integrity: sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==} + hasBin: true + + rollup-plugin-visualizer@5.14.0: + resolution: {integrity: sha512-VlDXneTDaKsHIw8yzJAFWtrzguoJ/LnQ+lMpoVfYJ3jJF4Ihe5oYLAqLklIK/35lgUY+1yEzCkHyZ1j4A5w5fA==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + rolldown: 1.x + rollup: 2.x || 3.x || 4.x + peerDependenciesMeta: + rolldown: + optional: true + rollup: + optional: true + + rollup@4.41.0: + resolution: {integrity: sha512-HqMFpUbWlf/tvcxBFNKnJyzc7Lk+XO3FGc3pbNBLqEbOz0gPLRgcrlS3UF4MfUrVlstOaP/q0kM6GVvi+LrLRg==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + run-applescript@7.0.0: + resolution: {integrity: sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==} + engines: {node: '>=18'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + sade@1.8.1: + resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} + engines: {node: '>=6'} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} + engines: {node: '>= 0.4'} + + safe-stable-stringify@2.4.3: + resolution: {integrity: sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==} + engines: {node: '>=10'} + + safe-stable-stringify@2.5.0: + resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} + engines: {node: '>=10'} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + scheduler@0.23.2: + resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + + scrypt-js@3.0.1: + resolution: {integrity: sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==} + + scule@1.3.0: + resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} + + secp256k1@4.0.3: + resolution: {integrity: sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==} + engines: {node: '>=10.0.0'} + + secure-json-parse@2.7.0: + resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==} + + semver@5.7.1: + resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} + hasBin: true + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.5.4: + resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + engines: {node: '>=10'} + hasBin: true + + semver@7.6.2: + resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==} + engines: {node: '>=10'} + hasBin: true + + semver@7.7.2: + resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} + engines: {node: '>=10'} + hasBin: true + + send@1.2.0: + resolution: {integrity: sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==} + engines: {node: '>= 18'} + + serialize-javascript@6.0.0: + resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==} + + serialize-javascript@6.0.2: + resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + + serve-placeholder@2.0.2: + resolution: {integrity: sha512-/TMG8SboeiQbZJWRlfTCqMs2DD3SZgWp0kDQePz9yUuCnDfDh/92gf7/PxGhzXTKBIPASIHxFcZndoNbp6QOLQ==} + + serve-static@2.2.0: + resolution: {integrity: sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==} + engines: {node: '>= 18'} + + set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + setimmediate@1.0.5: + resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + sha.js@2.4.11: + resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==} + hasBin: true + + sharp@0.34.2: + resolution: {integrity: sha512-lszvBmB9QURERtyKT2bNmsgxXK0ShJrL/fvqlonCo7e6xBF8nT8xU6pW+PMIbLsz0RxQk3rgH9kd8UmvOzlMJg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + + shebang-command@1.2.0: + resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} + engines: {node: '>=0.10.0'} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@1.0.0: + resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} + engines: {node: '>=0.10.0'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shell-quote@1.8.2: + resolution: {integrity: sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==} + engines: {node: '>= 0.4'} + + sherif-darwin-arm64@1.0.0: + resolution: {integrity: sha512-BRzDsWGjdZ6JqaDQ0HdcpapfHcnZyN24wUWpnFkljZOH78N+vB4qr+wwhmM7oyePJiO4pZWEoIBvzVT4cn1+3g==} + cpu: [arm64] + os: [darwin] + + sherif-darwin-x64@1.0.0: + resolution: {integrity: sha512-forkTw6v2N2sjvDdHGL+MqSPdLc0e7Z0v9BsmSdIKv5kdCPncVn6tRv/4xfAE7q+Xqa2a2bH9EEXppGb4gR3Tw==} + cpu: [x64] + os: [darwin] + + sherif-linux-arm64@1.0.0: + resolution: {integrity: sha512-psjD3YupFQtphWbwptM8EnU2jRkS6cnhxdxqJhMG9/yJpGsk99JD4tEmrDq0j/+T9UXZ5g7kXvQZXzocl3J62A==} + cpu: [arm64] + os: [linux] + + sherif-linux-x64@1.0.0: + resolution: {integrity: sha512-4VM2Z0xfKOEEkZ2bZppq4PAxP4RYC2eWyUq23Jl/nQFeoPMQpA9IkF51UGzxZT4WZ2kZDFftgyJeB09yPvd1CA==} + cpu: [x64] + os: [linux] + + sherif-windows-arm64@1.0.0: + resolution: {integrity: sha512-tSEzytTz3guhKLtdMCKWWru6UtmuCXD+0RsUWcqOMpzPBZZwvSr7OrTc83z8Oabmo8k6SJ5fvQeg33JSthgTqw==} + cpu: [arm64] + os: [win32] + + sherif-windows-x64@1.0.0: + resolution: {integrity: sha512-R/KXUHBWVPU9hSlWS+Gea/ogP1h/3q/Dm/quqGrVq+MN/F+fiRsJlU52EAjAJ6G5r/4RsvQddD1ova8MKsffdw==} + cpu: [x64] + os: [win32] + + sherif@1.0.0: + resolution: {integrity: sha512-x5gZqXmBT0G6Xnr2N63FwbMjaOikk/mPszl2bl3pnDMMyRi89w1ynAfcdIJpOyqZXW445418zkMIXAkQEfEtHw==} + hasBin: true + + shiki@1.22.2: + resolution: {integrity: sha512-3IZau0NdGKXhH2bBlUk4w1IHNxPh6A5B2sUpyY+8utLu2j/h1QpFkAaUA1bAMxOWWGtTWcAh531vnS4NJKS/lA==} + + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + simple-git-hooks@2.11.1: + resolution: {integrity: sha512-tgqwPUMDcNDhuf1Xf6KTUsyeqGdgKMhzaH4PAZZuzguOgTl5uuyeYe/8mWgAr6IBxB5V06uqEf6Dy37gIWDtDg==} + hasBin: true + + simple-git@3.27.0: + resolution: {integrity: sha512-ivHoFS9Yi9GY49ogc6/YAi3Fl9ROnF4VyubNylgCkA+RVqLaKWnDSzXOVzya8csELIaWaYNutsEuAhZrtOjozA==} + + simple-swizzle@0.2.2: + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + + sirv@2.0.4: + resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==} + engines: {node: '>= 10'} + + sirv@3.0.1: + resolution: {integrity: sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==} + engines: {node: '>=18'} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + skin-tone@2.0.0: + resolution: {integrity: sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==} + engines: {node: '>=8'} + + slash@1.0.0: + resolution: {integrity: sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg==} + engines: {node: '>=0.10.0'} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + slash@5.1.0: + resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} + engines: {node: '>=14.16'} + + smob@1.5.0: + resolution: {integrity: sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==} + + smol-toml@1.3.0: + resolution: {integrity: sha512-tWpi2TsODPScmi48b/OQZGi2lgUmBCHy6SZrhi/FdnnHiU1GwebbCfuQuxsC3nHaLwtYeJGPrDZDIeodDOc4pA==} + engines: {node: '>= 18'} + + socket.io-client@4.8.1: + resolution: {integrity: sha512-hJVXfu3E28NmzGk8o1sHhN3om52tRvwYeidbj7xKy2eIIse5IoKX3USlS6Tqt3BHAtflLIkCQBkzVrEEfWUyYQ==} + engines: {node: '>=10.0.0'} + + socket.io-parser@4.2.4: + resolution: {integrity: sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==} + engines: {node: '>=10.0.0'} + + solc@0.7.3: + resolution: {integrity: sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==} + engines: {node: '>=8.0.0'} + hasBin: true + + sonic-boom@2.8.0: + resolution: {integrity: sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg==} + + sonic-boom@4.2.0: + resolution: {integrity: sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==} + + source-map-js@1.2.0: + resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + engines: {node: '>=0.10.0'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + source-map@0.7.4: + resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} + engines: {node: '>= 8'} + + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + + spawndamnit@2.0.0: + resolution: {integrity: sha512-j4JKEcncSjFlqIwU5L/rp2N5SIPsdxaRsIv678+TZxZ0SRDJTm8JrxJMjE/XuiEZNEir3S8l0Fa3Ke339WI4qA==} + + spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + + spdx-exceptions@2.5.0: + resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} + + spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + + spdx-license-ids@3.0.21: + resolution: {integrity: sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==} + + speakingurl@14.0.1: + resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==} + engines: {node: '>=0.10.0'} + + split-on-first@1.1.0: + resolution: {integrity: sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==} + engines: {node: '>=6'} + + split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + stack-trace@0.0.10: + resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==} + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + stacktrace-parser@0.1.10: + resolution: {integrity: sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==} + engines: {node: '>=6'} + + standard-as-callback@2.1.0: + resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} + + statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + + std-env@3.7.0: + resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} + + std-env@3.9.0: + resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} + + stream-shift@1.0.1: + resolution: {integrity: sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==} + + streamsearch@1.1.0: + resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} + engines: {node: '>=10.0.0'} + + streamx@2.22.0: + resolution: {integrity: sha512-sLh1evHOzBy/iWRiR6d1zRcLao4gGZr3C1kzNz4fopCOKJb6xD9ub8Mpi9Mr1R6id5o43S+d93fI48UC5uM9aw==} + + strict-event-emitter@0.5.1: + resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} + + strict-uri-encode@2.0.0: + resolution: {integrity: sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==} + engines: {node: '>=4'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + + strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + + strip-final-newline@4.0.0: + resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==} + engines: {node: '>=18'} + + strip-hex-prefix@1.0.0: + resolution: {integrity: sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==} + engines: {node: '>=6.5.0', npm: '>=3'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + strip-json-comments@5.0.1: + resolution: {integrity: sha512-0fk9zBqO67Nq5M/m45qHCJxylV/DhBlIOVExqgOMiCCrzrhU6tCibRXNqE3jwJLftzE9SNuZtYbpzcO+i9FiKw==} + engines: {node: '>=14.16'} + + strip-literal@1.3.0: + resolution: {integrity: sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==} + + strip-literal@3.0.0: + resolution: {integrity: sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==} + + structured-clone-es@1.0.0: + resolution: {integrity: sha512-FL8EeKFFyNQv5cMnXI31CIMCsFarSVI2bF0U0ImeNE3g/F1IvJQyqzOXxPBRXiwQfyBTlbNe88jh1jFW0O/jiQ==} + + styled-jsx@5.1.6: + resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@babel/core': '*' + babel-plugin-macros: '*' + react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0' + peerDependenciesMeta: + '@babel/core': + optional: true + babel-plugin-macros: + optional: true + + stylehacks@7.0.5: + resolution: {integrity: sha512-5kNb7V37BNf0Q3w+1pxfa+oiNPS++/b4Jil9e/kPDgrk1zjEd6uR7SZeJiYaLYH6RRSC1XX2/37OTeU/4FvuIA==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.32 + + summary@2.1.0: + resolution: {integrity: sha512-nMIjMrd5Z2nuB2RZCKJfFMjgS3fygbeyGk9PxPPaJR1RIcyN9yn4A63Isovzm3ZtQuEkLBVgMdPup8UeLH7aQw==} + + superjson@2.2.1: + resolution: {integrity: sha512-8iGv75BYOa0xRJHK5vRLEjE2H/i4lulTjzpUXic3Eg8akftYjkmQDa8JARQ42rlczXyFR3IeRoeFCc7RxHsYZA==} + engines: {node: '>=16'} + + superjson@2.2.2: + resolution: {integrity: sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==} + engines: {node: '>=16'} + + superstruct@1.0.3: + resolution: {integrity: sha512-8iTn3oSS8nRGn+C2pgXSKPI3jmpm6FExNazNpjvqS6ZUJQCej3PUXEKM8NjHBOs54ExM+LPW/FBRhymrdcCiSg==} + engines: {node: '>=14.0.0'} + + supports-color@10.0.0: + resolution: {integrity: sha512-HRVVSbCCMbj7/kdWF9Q+bbckjBHLtHMEoJWlkmYzzdwhYMkjkOwubLM6t7NbWKjgKamGDrWL1++KrjUO1t9oAQ==} + engines: {node: '>=18'} + + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + supports-color@9.4.0: + resolution: {integrity: sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw==} + engines: {node: '>=12'} + + supports-hyperlinks@3.0.0: + resolution: {integrity: sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==} + engines: {node: '>=14.18'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + svgo@3.3.2: + resolution: {integrity: sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==} + engines: {node: '>=14.0.0'} + hasBin: true + + system-architecture@0.1.0: + resolution: {integrity: sha512-ulAk51I9UVUyJgxlv9M6lFot2WP3e7t8Kz9+IS6D4rVba1tR9kON+Ey69f+1R4Q8cd45Lod6a4IcJIxnzGc/zA==} + engines: {node: '>=18'} + + tabbable@6.2.0: + resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} + + tapable@2.2.1: + resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + engines: {node: '>=6'} + + tapable@2.2.2: + resolution: {integrity: sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==} + engines: {node: '>=6'} + + tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + + tar-stream@3.1.7: + resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==} + + tar@6.2.1: + resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} + engines: {node: '>=10'} + + tar@7.2.0: + resolution: {integrity: sha512-hctwP0Nb4AB60bj8WQgRYaMOuJYRAPMGiQUAotms5igN8ppfQM+IvjQ5HcKu1MaZh2Wy2KWVTe563Yj8dfc14w==} + engines: {node: '>=18'} + + tar@7.4.3: + resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} + engines: {node: '>=18'} + + temp-dir@1.0.0: + resolution: {integrity: sha512-xZFXEGbG7SNC3itwBzI3RYjq/cEhBkx2hJuKGIUOcEULmkQExXiHat2z/qkISYsuR+IKumhEfKKbV5qXmhICFQ==} + engines: {node: '>=4'} + + tempy@0.2.1: + resolution: {integrity: sha512-LB83o9bfZGrntdqPuRdanIVCPReam9SOZKW0fOy5I9X3A854GGWi0tjCqoXEk84XIEYBc/x9Hq3EFop/H5wJaw==} + engines: {node: '>=4'} + + term-size@2.2.1: + resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} + engines: {node: '>=8'} + + terser@5.39.2: + resolution: {integrity: sha512-yEPUmWve+VA78bI71BW70Dh0TuV4HHd+I5SHOAfS1+QBOmvmCiiffgjR8ryyEd3KIfvPGFqoADt8LdQ6XpXIvg==} + engines: {node: '>=10'} + hasBin: true + + test-exclude@7.0.1: + resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==} + engines: {node: '>=18'} + + text-decoder@1.2.3: + resolution: {integrity: sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==} + + text-hex@1.0.0: + resolution: {integrity: sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==} + + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + + thread-stream@0.15.2: + resolution: {integrity: sha512-UkEhKIg2pD+fjkHQKyJO3yoIvAP3N6RlNFt2dUhcS1FGvCD1cQa1M/PGknCLFIyZdtJOWQjejp7bdNqmN7zwdA==} + + tiny-invariant@1.3.3: + resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@0.3.2: + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + + tinyexec@1.0.1: + resolution: {integrity: sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==} + + tinyglobby@0.2.12: + resolution: {integrity: sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==} + engines: {node: '>=12.0.0'} + + tinyglobby@0.2.13: + resolution: {integrity: sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==} + engines: {node: '>=12.0.0'} + + tinypool@1.0.2: + resolution: {integrity: sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==} + engines: {node: ^18.0.0 || >=20.0.0} + + tinyrainbow@1.2.0: + resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} + engines: {node: '>=14.0.0'} + + tinyspy@3.0.2: + resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} + engines: {node: '>=14.0.0'} + + tmp-promise@3.0.3: + resolution: {integrity: sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==} + + tmp@0.0.33: + resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} + engines: {node: '>=0.6.0'} + + tmp@0.2.3: + resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} + engines: {node: '>=14.14'} + + to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + toml@3.0.0: + resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==} + + totalist@3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} + engines: {node: '>=6'} + + tough-cookie@4.1.4: + resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} + engines: {node: '>=6'} + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + + triple-beam@1.4.1: + resolution: {integrity: sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==} + engines: {node: '>= 14.0.0'} + + tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tsort@0.0.1: + resolution: {integrity: sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==} + + tsutils@3.21.0: + resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} + engines: {node: '>= 6'} + peerDependencies: + typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' + + tweetnacl-util@0.15.1: + resolution: {integrity: sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==} + + tweetnacl@1.0.3: + resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==} + + twoslash-protocol@0.2.12: + resolution: {integrity: sha512-5qZLXVYfZ9ABdjqbvPc4RWMr7PrpPaaDSeaYY55vl/w1j6H6kzsWK/urAEIXlzYlyrFmyz1UbwIt+AA0ck+wbg==} + + twoslash-vue@0.2.12: + resolution: {integrity: sha512-kxH60DLn2QBcN2wjqxgMDkyRgmPXsytv7fJIlsyFMDPSkm1/lMrI/UMrNAshNaRHcI+hv8x3h/WBgcvlb2RNAQ==} + peerDependencies: + typescript: '*' + + twoslash@0.2.12: + resolution: {integrity: sha512-tEHPASMqi7kqwfJbkk7hc/4EhlrKCSLcur+TcvYki3vhIfaRMXnXjaYFgXpoZRbT6GdprD4tGuVBEmTpUgLBsw==} + peerDependencies: + typescript: '*' + + type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + + type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + + type-fest@0.7.1: + resolution: {integrity: sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==} + engines: {node: '>=8'} + + type-fest@4.18.2: + resolution: {integrity: sha512-+suCYpfJLAe4OXS6+PPXjW3urOS4IoP9waSiLuXfLgqZODKw/aWwASvzqE886wA0kQgGy0mIWyhd87VpqIy6Xg==} + engines: {node: '>=16'} + + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} + engines: {node: '>=16'} + + typescript@5.6.1-rc: + resolution: {integrity: sha512-E3b2+1zEFu84jB0YQi9BORDjz9+jGbwwy1Zi3G0LUNw7a7cePUrHMRNy8aPh53nXpkFGVHSxIZo5vKTfYaFiBQ==} + engines: {node: '>=14.17'} + hasBin: true + + typescript@5.8.3: + resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} + engines: {node: '>=14.17'} + hasBin: true + + ufo@1.5.3: + resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==} + + ufo@1.6.1: + resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} + + uint8arrays@3.1.0: + resolution: {integrity: sha512-ei5rfKtoRO8OyOIor2Rz5fhzjThwIHJZ3uyDPnDHTXbP0aMQ1RN/6AI5B5d9dBxJOU+BvOAk7ZQ1xphsX8Lrog==} + + uint8arrays@3.1.1: + resolution: {integrity: sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg==} + + ultrahtml@1.6.0: + resolution: {integrity: sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw==} + + unconfig@0.3.13: + resolution: {integrity: sha512-N9Ph5NC4+sqtcOjPfHrRcHekBCadCXWTBzp2VYYbySOHW0PfD9XLCeXshTXjkPYwLrBr9AtSeU0CZmkYECJhng==} + + uncrypto@0.1.3: + resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} + + unctx@2.4.1: + resolution: {integrity: sha512-AbaYw0Nm4mK4qjhns67C+kgxR2YWiwlDBPzxrN8h8C6VtAdCgditAY5Dezu3IJy4XVqAnbrXt9oQJvsn3fyozg==} + + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + undici-types@7.8.0: + resolution: {integrity: sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==} + + undici@5.28.3: + resolution: {integrity: sha512-3ItfzbrhDlINjaP0duwnNsKpDQk3acHI3gVJ1z4fmwMK31k5G9OVIAMLSIaP6w4FaGkaAkN6zaQO9LUvZ1t7VA==} + engines: {node: '>=14.0'} + + unenv@2.0.0-rc.17: + resolution: {integrity: sha512-B06u0wXkEd+o5gOCMl/ZHl5cfpYbDZKAT+HWTL+Hws6jWu7dCiqBBXXXzMFcFVJb8D4ytAnYmxJA83uwOQRSsg==} + + unhead@2.0.9: + resolution: {integrity: sha512-ZLTNJ51PZPO4/3keW7FHiTMb6K+JmhhVApJA52qWNw7NMYPD8fM2eA+hUEaCA2L5bZtbRg43TT7n/lJ+/9o6pw==} + + unicode-emoji-modifier-base@1.0.0: + resolution: {integrity: sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==} + engines: {node: '>=4'} + + unicorn-magic@0.1.0: + resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} + engines: {node: '>=18'} + + unicorn-magic@0.3.0: + resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} + engines: {node: '>=18'} + + unimport@3.7.1: + resolution: {integrity: sha512-V9HpXYfsZye5bPPYUgs0Otn3ODS1mDUciaBlXljI4C2fTwfFpvFZRywmlOu943puN9sncxROMZhsZCjNXEpzEQ==} + + unimport@4.2.0: + resolution: {integrity: sha512-mYVtA0nmzrysnYnyb3ALMbByJ+Maosee2+WyE0puXl+Xm2bUwPorPaaeZt0ETfuroPOtG8jj1g/qeFZ6buFnag==} + engines: {node: '>=18.12.0'} + + unimport@5.0.1: + resolution: {integrity: sha512-1YWzPj6wYhtwHE+9LxRlyqP4DiRrhGfJxdtH475im8ktyZXO3jHj/3PZ97zDdvkYoovFdi0K4SKl3a7l92v3sQ==} + engines: {node: '>=18.12.0'} + + unique-string@1.0.0: + resolution: {integrity: sha512-ODgiYu03y5g76A1I9Gt0/chLCzQjvzDy7DsZGsLOE/1MrF6wriEskSncj1+/C58Xk/kPZDppSctDybCwOSaGAg==} + engines: {node: '>=4'} + + unist-util-is@6.0.0: + resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@6.0.1: + resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==} + + unist-util-visit@5.0.0: + resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + + universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + + universalify@0.2.0: + resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} + engines: {node: '>= 4.0.0'} + + unixify@1.0.0: + resolution: {integrity: sha512-6bc58dPYhCMHHuwxldQxO3RRNZ4eCogZ/st++0+fcC1nr0jiGUtAdBJ2qzmLQWSxbtz42pWt4QQMiZ9HvZf5cg==} + engines: {node: '>=0.10.0'} + + unocss@0.59.4: + resolution: {integrity: sha512-QmCVjRObvVu/gsGrJGVt0NnrdhFFn314BUZn2WQyXV9rIvHLRmG5bIu0j5vibJkj7ZhFchTrnTM1pTFXP1xt5g==} + engines: {node: '>=14'} + peerDependencies: + '@unocss/webpack': 0.59.4 + vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 + peerDependenciesMeta: + '@unocss/webpack': + optional: true + vite: + optional: true + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + unplugin-utils@0.2.4: + resolution: {integrity: sha512-8U/MtpkPkkk3Atewj1+RcKIjb5WBimZ/WSLhhR3w6SsIj8XJuKTacSP8g+2JhfSGw0Cb125Y+2zA/IzJZDVbhA==} + engines: {node: '>=18.12.0'} + + unplugin-vue-router@0.12.0: + resolution: {integrity: sha512-xjgheKU0MegvXQcy62GVea0LjyOdMxN0/QH+ijN29W62ZlMhG7o7K+0AYqfpprvPwpWtuRjiyC5jnV2SxWye2w==} + peerDependencies: + vue-router: ^4.4.0 + peerDependenciesMeta: + vue-router: + optional: true + + unplugin@1.10.1: + resolution: {integrity: sha512-d6Mhq8RJeGA8UfKCu54Um4lFA0eSaRa3XxdAJg8tIdxbu1ubW0hBCZUL7yI2uGyYCRndvbK8FLHzqy2XKfeMsg==} + engines: {node: '>=14.0.0'} + + unplugin@1.16.1: + resolution: {integrity: sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==} + engines: {node: '>=14.0.0'} + + unplugin@2.3.4: + resolution: {integrity: sha512-m4PjxTurwpWfpMomp8AptjD5yj8qEZN5uQjjGM3TAs9MWWD2tXSSNNj6jGR2FoVGod4293ytyV6SwBbertfyJg==} + engines: {node: '>=18.12.0'} + + unstorage@1.10.2: + resolution: {integrity: sha512-cULBcwDqrS8UhlIysUJs2Dk0Mmt8h7B0E6mtR+relW9nZvsf/u4SkAYyNliPiPW7XtFNb5u3IUMkxGxFTTRTgQ==} + peerDependencies: + '@azure/app-configuration': ^1.5.0 + '@azure/cosmos': ^4.0.0 + '@azure/data-tables': ^13.2.2 + '@azure/identity': ^4.0.1 + '@azure/keyvault-secrets': ^4.8.0 + '@azure/storage-blob': ^12.17.0 + '@capacitor/preferences': ^5.0.7 + '@netlify/blobs': ^6.5.0 || ^7.0.0 + '@planetscale/database': ^1.16.0 + '@upstash/redis': ^1.28.4 + '@vercel/kv': ^1.0.1 + idb-keyval: ^6.2.1 + ioredis: ^5.3.2 + peerDependenciesMeta: + '@azure/app-configuration': + optional: true + '@azure/cosmos': + optional: true + '@azure/data-tables': + optional: true + '@azure/identity': + optional: true + '@azure/keyvault-secrets': + optional: true + '@azure/storage-blob': + optional: true + '@capacitor/preferences': + optional: true + '@netlify/blobs': + optional: true + '@planetscale/database': + optional: true + '@upstash/redis': + optional: true + '@vercel/kv': + optional: true + idb-keyval: + optional: true + ioredis: + optional: true + + unstorage@1.16.0: + resolution: {integrity: sha512-WQ37/H5A7LcRPWfYOrDa1Ys02xAbpPJq6q5GkO88FBXVSQzHd7+BjEwfRqyaSWCv9MbsJy058GWjjPjcJ16GGA==} + peerDependencies: + '@azure/app-configuration': ^1.8.0 + '@azure/cosmos': ^4.2.0 + '@azure/data-tables': ^13.3.0 + '@azure/identity': ^4.6.0 + '@azure/keyvault-secrets': ^4.9.0 + '@azure/storage-blob': ^12.26.0 + '@capacitor/preferences': ^6.0.3 || ^7.0.0 + '@deno/kv': '>=0.9.0' + '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 + '@planetscale/database': ^1.19.0 + '@upstash/redis': ^1.34.3 + '@vercel/blob': '>=0.27.1' + '@vercel/kv': ^1.0.1 + aws4fetch: ^1.0.20 + db0: '>=0.2.1' + idb-keyval: ^6.2.1 + ioredis: ^5.4.2 + uploadthing: ^7.4.4 + peerDependenciesMeta: + '@azure/app-configuration': + optional: true + '@azure/cosmos': + optional: true + '@azure/data-tables': + optional: true + '@azure/identity': + optional: true + '@azure/keyvault-secrets': + optional: true + '@azure/storage-blob': + optional: true + '@capacitor/preferences': + optional: true + '@deno/kv': + optional: true + '@netlify/blobs': + optional: true + '@planetscale/database': + optional: true + '@upstash/redis': + optional: true + '@vercel/blob': + optional: true + '@vercel/kv': + optional: true + aws4fetch: + optional: true + db0: + optional: true + idb-keyval: + optional: true + ioredis: + optional: true + uploadthing: + optional: true + + untun@0.1.3: + resolution: {integrity: sha512-4luGP9LMYszMRZwsvyUd9MrxgEGZdZuZgpVQHEEX0lCYFESasVRvZd0EYpCkOIbJKHMuv0LskpXc/8Un+MJzEQ==} + hasBin: true + + untyped@1.4.2: + resolution: {integrity: sha512-nC5q0DnPEPVURPhfPQLahhSTnemVtPzdx7ofiRxXpOB2SYnb3MfdU3DVGyJdS8Lx+tBWeAePO8BfU/3EgksM7Q==} + hasBin: true + + untyped@2.0.0: + resolution: {integrity: sha512-nwNCjxJTjNuLCgFr42fEak5OcLuB3ecca+9ksPFNvtfYSLpjf+iJqSIaSnIile6ZPbKYxI5k2AfXqeopGudK/g==} + hasBin: true + + unwasm@0.3.9: + resolution: {integrity: sha512-LDxTx/2DkFURUd+BU1vUsF/moj0JsoTvl+2tcg2AUOiEzVturhGGx17/IMgGvKUYdZwr33EJHtChCJuhu9Ouvg==} + + update-browserslist-db@1.0.15: + resolution: {integrity: sha512-K9HWH62x3/EalU1U6sjSZiylm9C8tgq2mSvshZpqc7QE69RaA2qjhkW2HlNA0tFpEbtyFz7HTqbSdN4MSwUodA==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + update-browserslist-db@1.1.3: + resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uqr@0.1.2: + resolution: {integrity: sha512-MJu7ypHq6QasgF5YRTjqscSzQp/W11zoUk6kvmlH+fmWEs63Y0Eib13hYFwAzagRJcVY8WVnlV+eBDUGMJ5IbA==} + + url-parse@1.5.10: + resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + + urlpattern-polyfill@10.1.0: + resolution: {integrity: sha512-IGjKp/o0NL3Bso1PymYURCJxMPNAf/ILOpendP9f5B6e1rTJgdgiOvgfoT8VxCAdY+Wisb9uhGaJJf3yZ2V9nw==} + + urlpattern-polyfill@8.0.2: + resolution: {integrity: sha512-Qp95D4TPJl1kC9SKigDcqgyM2VDVO4RiJc2d4qe5GrYm+zbIQCWWKAFaJNQ4BhdFeDGwBmAxqJBwWSJDb9T3BQ==} + + use-sync-external-store@1.2.0: + resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + + use-sync-external-store@1.4.0: + resolution: {integrity: sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + utf-8-validate@5.0.10: + resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} + engines: {node: '>=6.14.2'} + + utf-8-validate@6.0.5: + resolution: {integrity: sha512-EYZR+OpIXp9Y1eG1iueg8KRsY8TuT8VNgnanZ0uA3STqhHQTLwbl+WX76/9X5OY12yQubymBpaBSmMPkSTQcKA==} + engines: {node: '>=6.14.2'} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + util@0.12.5: + resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} + + uuid@11.1.0: + resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} + hasBin: true + + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + + uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + + validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + + validate-npm-package-name@5.0.1: + resolution: {integrity: sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + valtio@1.13.2: + resolution: {integrity: sha512-Qik0o+DSy741TmkqmRfjq+0xpZBXi/Y6+fXZLn0xNF1z/waFMbE3rkivv5Zcf9RrMUp6zswf2J7sbh2KBlba5A==} + engines: {node: '>=12.20.0'} + peerDependencies: + '@types/react': '>=16.8' + react: '>=16.8' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + + vfile-message@4.0.2: + resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==} + + vfile@6.0.1: + resolution: {integrity: sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==} + + viem@2.10.8: + resolution: {integrity: sha512-ttCXlDmjjcZ8M/eJezXFzDtHj+RFOjEQ3elmXnCC7suXo/y8CuIM1LrIoyUFk7LKIE5E+bzmWUErS4u/MQBtpQ==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + + viem@2.17.0: + resolution: {integrity: sha512-+gaVlsfDsHL1oYdjpatdRxW1WK/slLYVvpOws3fEdLfQFUToezKI6YLC9l1g2uKm4Hg3OdGX1KQy/G7/58tTKQ==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + + viem@2.23.2: + resolution: {integrity: sha512-NVmW/E0c5crMOtbEAqMF0e3NmvQykFXhLOc/CkLIXOlzHSA6KXVz3CYVmaKqBF8/xtjsjHAGjdJN3Ru1kFJLaA==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + + viem@2.29.2: + resolution: {integrity: sha512-cukRxab90jvQ+TDD84sU3qB3UmejYqgCw4cX8SfWzvh7JPfZXI3kAMUaT5OSR2As1Mgvx1EJawccwPjGqkSSwA==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + + vite-dev-rpc@1.0.7: + resolution: {integrity: sha512-FxSTEofDbUi2XXujCA+hdzCDkXFG1PXktMjSk1efq9Qb5lOYaaM9zNSvKvPPF7645Bak79kSp1PTooMW2wktcA==} + peerDependencies: + vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.1 + + vite-hot-client@2.0.4: + resolution: {integrity: sha512-W9LOGAyGMrbGArYJN4LBCdOC5+Zwh7dHvOHC0KmGKkJhsOzaKbpo/jEjpPKVHIW0/jBWj8RZG0NUxfgA8BxgAg==} + peerDependencies: + vite: ^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 + + vite-node@2.1.9: + resolution: {integrity: sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + + vite-node@3.1.4: + resolution: {integrity: sha512-6enNwYnpyDo4hEgytbmc6mYWHXDHYEn0D1/rw4Q+tnHUGtKTJsn8T1YkX6Q18wI5LCrS8CTYlBaiCqxOy2kvUA==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + + vite-plugin-checker@0.9.3: + resolution: {integrity: sha512-Tf7QBjeBtG7q11zG0lvoF38/2AVUzzhMNu+Wk+mcsJ00Rk/FpJ4rmUviVJpzWkagbU13cGXvKpt7CMiqtxVTbQ==} + engines: {node: '>=14.16'} + peerDependencies: + '@biomejs/biome': '>=1.7' + eslint: '>=7' + meow: ^13.2.0 + optionator: ^0.9.4 + stylelint: '>=16' + typescript: '*' + vite: '>=2.0.0' + vls: '*' + vti: '*' + vue-tsc: ~2.2.10 + peerDependenciesMeta: + '@biomejs/biome': + optional: true + eslint: + optional: true + meow: + optional: true + optionator: + optional: true + stylelint: + optional: true + typescript: + optional: true + vls: + optional: true + vti: + optional: true + vue-tsc: + optional: true + + vite-plugin-inspect@11.1.0: + resolution: {integrity: sha512-r3Nx8xGQ08bSoNu7gJGfP5H/wNOROHtv0z3tWspplyHZJlABwNoPOdFEmcVh+lVMDyk/Be4yt8oS596ZHoYhOg==} + engines: {node: '>=14'} + peerDependencies: + '@nuxt/kit': '*' + vite: ^6.0.0 + peerDependenciesMeta: + '@nuxt/kit': + optional: true + + vite-plugin-vue-tracer@0.1.3: + resolution: {integrity: sha512-+fN6oo0//dwZP9Ax9gRKeUroCqpQ43P57qlWgL0ljCIxAs+Rpqn/L4anIPZPgjDPga5dZH+ZJsshbF0PNJbm3Q==} + peerDependencies: + vite: ^6.0.0 + vue: ^3.5.0 + + vite@5.4.19: + resolution: {integrity: sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vite@6.3.5: + resolution: {integrity: sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + jiti: '>=1.21.0' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vitepress@1.5.0: + resolution: {integrity: sha512-q4Q/G2zjvynvizdB3/bupdYkCJe2umSAMv9Ju4d92E6/NXJ59z70xB0q5p/4lpRyAwflDsbwy1mLV9Q5+nlB+g==} + hasBin: true + peerDependencies: + markdown-it-mathjax3: ^4 + postcss: ^8 + peerDependenciesMeta: + markdown-it-mathjax3: + optional: true + postcss: + optional: true + + vitest@2.1.9: + resolution: {integrity: sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 2.1.9 + '@vitest/ui': 2.1.9 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + vscode-uri@3.1.0: + resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} + + vue-bundle-renderer@2.1.1: + resolution: {integrity: sha512-+qALLI5cQncuetYOXp4yScwYvqh8c6SMXee3B+M7oTZxOgtESP0l4j/fXdEJoZ+EdMxkGWIj+aSEyjXkOdmd7g==} + + vue-component-type-helpers@2.0.16: + resolution: {integrity: sha512-qisL/iAfdO++7w+SsfYQJVPj6QKvxp4i1MMxvsNO41z/8zu3KuAw9LkhKUfP/kcOWGDxESp+pQObWppXusejCA==} + + vue-demi@0.14.10: + resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==} + engines: {node: '>=12'} + hasBin: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + + vue-devtools-stub@0.1.0: + resolution: {integrity: sha512-RutnB7X8c5hjq39NceArgXg28WZtZpGc3+J16ljMiYnFhKvd8hITxSWQSQ5bvldxMDU6gG5mkxl1MTQLXckVSQ==} + + vue-resize@2.0.0-alpha.1: + resolution: {integrity: sha512-7+iqOueLU7uc9NrMfrzbG8hwMqchfVfSzpVlCMeJQe4pyibqyoifDNbKTZvwxZKDvGkB+PdFeKvnGZMoEb8esg==} + peerDependencies: + vue: ^3.0.0 + + vue-router@4.3.2: + resolution: {integrity: sha512-hKQJ1vDAZ5LVkKEnHhmm1f9pMiWIBNGF5AwU67PdH7TyXCj/a4hTccuUuYCAMgJK6rO/NVYtQIEN3yL8CECa7Q==} + peerDependencies: + vue: ^3.2.0 + + vue-router@4.5.1: + resolution: {integrity: sha512-ogAF3P97NPm8fJsE4by9dwSYtDwXIY1nFY9T6DyQnGHd1E2Da94w9JIolpe42LJGIl0DwOHBi8TcRPlPGwbTtw==} + peerDependencies: + vue: ^3.2.0 + + vue-template-compiler@2.7.16: + resolution: {integrity: sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==} + + vue-tsc@2.0.16: + resolution: {integrity: sha512-/gHAWJa216PeEhfxtAToIbxdWgw01wuQzo48ZUqMYVEyNqDp+OYV9xMO5HaPS2P3Ls0+EsjguMZLY4cGobX4Ew==} + hasBin: true + peerDependencies: + typescript: '*' + + vue@3.4.27: + resolution: {integrity: sha512-8s/56uK6r01r1icG/aEOHqyMVxd1bkYcSe9j8HcKtr/xTOFWvnzIVTehNW+5Yt89f+DLBe4A569pnZLS5HzAMA==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + vue@3.5.12: + resolution: {integrity: sha512-CLVZtXtn2ItBIi/zHZ0Sg1Xkb7+PU32bJJ8Bmy7ts3jxXTcbfsEfBivFYYWz1Hur+lalqGAh65Coin0r+HRUfg==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + vue@3.5.14: + resolution: {integrity: sha512-LbOm50/vZFG6Mhy6KscQYXZMQ0LMCC/y40HDJPPvGFQ+i/lUH+PJHR6C3assgOQiXdl6tAfsXHbXYVBZZu65ew==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + wcwidth@1.0.1: + resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + + web-streams-polyfill@3.3.3: + resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} + engines: {node: '>= 8'} + + webextension-polyfill@0.10.0: + resolution: {integrity: sha512-c5s35LgVa5tFaHhrZDnr3FpQpjj1BB+RXhLTYUxGqBVN460HkbM8TBtEqdXWbpTKfzwCcjAZVF7zXCYSKtcp9g==} + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + webidl-conversions@7.0.0: + resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} + engines: {node: '>=12'} + + webpack-bundle-analyzer@4.10.1: + resolution: {integrity: sha512-s3P7pgexgT/HTUSYgxJyn28A+99mmLq4HsJepMPzu0R8ImJc52QNqaFYW1Z2z2uIb1/J3eYgaAWVpaC+v/1aAQ==} + engines: {node: '>= 10.13.0'} + hasBin: true + + webpack-sources@3.2.3: + resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} + engines: {node: '>=10.13.0'} + + webpack-virtual-modules@0.6.1: + resolution: {integrity: sha512-poXpCylU7ExuvZK8z+On3kX+S8o/2dQ/SVYueKA0D4WEMXROXgY8Ez50/bQEUmvoSMMrWcrJqCHuhAbsiwg7Dg==} + + webpack-virtual-modules@0.6.2: + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + + whatwg-mimetype@3.0.0: + resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} + engines: {node: '>=12'} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + which-module@2.0.0: + resolution: {integrity: sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==} + + which-typed-array@1.1.19: + resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} + engines: {node: '>= 0.4'} + + which@1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + which@5.0.0: + resolution: {integrity: sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==} + engines: {node: ^18.17.0 || >=20.5.0} + hasBin: true + + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + + wide-align@1.1.5: + resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} + + widest-line@3.1.0: + resolution: {integrity: sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==} + engines: {node: '>=8'} + + winston-transport@4.9.0: + resolution: {integrity: sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==} + engines: {node: '>= 12.0.0'} + + winston@3.17.0: + resolution: {integrity: sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw==} + engines: {node: '>= 12.0.0'} + + workerpool@6.2.1: + resolution: {integrity: sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==} + + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + write-file-atomic@6.0.0: + resolution: {integrity: sha512-GmqrO8WJ1NuzJ2DrziEI2o57jKAVIQNf8a18W3nCYU3H7PNWqCCVTeH6/NQE93CIllIgQS98rrmVkYgTX9fFJQ==} + engines: {node: ^18.17.0 || >=20.5.0} + + ws@7.5.10: + resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@7.5.9: + resolution: {integrity: sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.13.0: + resolution: {integrity: sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.17.1: + resolution: {integrity: sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.18.1: + resolution: {integrity: sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.18.2: + resolution: {integrity: sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xmlhttprequest-ssl@2.1.2: + resolution: {integrity: sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==} + engines: {node: '>=0.4.0'} + + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + + y18n@4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yallist@2.1.2: + resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + + yaml@2.8.0: + resolution: {integrity: sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==} + engines: {node: '>= 14.6'} + hasBin: true + + yargs-parser@18.1.3: + resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} + engines: {node: '>=6'} + + yargs-parser@20.2.4: + resolution: {integrity: sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==} + engines: {node: '>=10'} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs-unparser@2.0.0: + resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} + engines: {node: '>=10'} + + yargs@15.4.1: + resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} + engines: {node: '>=8'} + + yargs@16.2.0: + resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} + engines: {node: '>=10'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yauzl@2.10.0: + resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + yocto-queue@1.2.1: + resolution: {integrity: sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==} + engines: {node: '>=12.20'} + + yoctocolors@2.0.2: + resolution: {integrity: sha512-Ct97huExsu7cWeEjmrXlofevF8CvzUglJ4iGUet5B8xn1oumtAZBpHU4GzYuoE6PVqcZ5hghtBrSlhwHuR1Jmw==} + engines: {node: '>=18'} + + youch-core@0.3.2: + resolution: {integrity: sha512-fusrlIMLeRvTFYLUjJ9KzlGC3N+6MOPJ68HNj/yJv2nz7zq8t4HEviLms2gkdRPUS7F5rZ5n+pYx9r88m6IE1g==} + engines: {node: '>=18'} + + youch@4.1.0-beta.7: + resolution: {integrity: sha512-HUn0M24AUTMvjdkoMtH8fJz2FEd+k1xvtR9EoTrDUoVUi6o7xl5X+pST/vjk4T3GEQo2mJ9FlAvhWBm8dIdD4g==} + engines: {node: '>=18'} + + zip-stream@4.1.1: + resolution: {integrity: sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==} + engines: {node: '>= 10'} + + zip-stream@6.0.1: + resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==} + engines: {node: '>= 14'} + + zod-validation-error@3.2.0: + resolution: {integrity: sha512-cYlPR6zuyrgmu2wRTdumEAJGuwI7eHVHGT+VyneAQxmRAKtGRL1/7pjz4wfLhz4J05f5qoSZc3rGacswgyTjjw==} + engines: {node: '>=18.0.0'} + peerDependencies: + zod: ^3.18.0 + + zod@3.22.4: + resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} + + zod@3.25.20: + resolution: {integrity: sha512-z03fqpTMDF1G02VLKUMt6vyACE7rNWkh3gpXVHgPTw28NPtDFRGvcpTtPwn2kMKtQ0idtYJUTxchytmnqYswcw==} + + zustand@5.0.0: + resolution: {integrity: sha512-LE+VcmbartOPM+auOjCCLQOsQ05zUTp8RkgwRzefUk+2jISdMMFnxvyTjA4YNWr5ZGXYbVsEMZosttuxUBkojQ==} + engines: {node: '>=12.20.0'} + peerDependencies: + '@types/react': '>=18.0.0' + immer: '>=9.0.6' + react: '>=18.0.0' + use-sync-external-store: '>=1.2.0' + peerDependenciesMeta: + '@types/react': + optional: true + immer: + optional: true + react: + optional: true + use-sync-external-store: + optional: true + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + +snapshots: + + '@adraffy/ens-normalize@1.10.0': {} + + '@adraffy/ens-normalize@1.11.0': {} + + '@algolia/autocomplete-core@1.9.3(@algolia/client-search@5.12.0)(algoliasearch@5.12.0)': + dependencies: + '@algolia/autocomplete-plugin-algolia-insights': 1.9.3(@algolia/client-search@5.12.0)(algoliasearch@5.12.0) + '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@5.12.0)(algoliasearch@5.12.0) + transitivePeerDependencies: + - '@algolia/client-search' + - algoliasearch + - search-insights + + '@algolia/autocomplete-plugin-algolia-insights@1.9.3(@algolia/client-search@5.12.0)(algoliasearch@5.12.0)': + dependencies: + '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@5.12.0)(algoliasearch@5.12.0) + transitivePeerDependencies: + - '@algolia/client-search' + - algoliasearch + + '@algolia/autocomplete-preset-algolia@1.17.6(@algolia/client-search@5.12.0)(algoliasearch@5.12.0)': + dependencies: + '@algolia/autocomplete-shared': 1.17.6(@algolia/client-search@5.12.0)(algoliasearch@5.12.0) + '@algolia/client-search': 5.12.0 + algoliasearch: 5.12.0 + + '@algolia/autocomplete-shared@1.17.6(@algolia/client-search@5.12.0)(algoliasearch@5.12.0)': + dependencies: + '@algolia/client-search': 5.12.0 + algoliasearch: 5.12.0 + + '@algolia/autocomplete-shared@1.9.3(@algolia/client-search@5.12.0)(algoliasearch@5.12.0)': + dependencies: + '@algolia/client-search': 5.12.0 + algoliasearch: 5.12.0 + + '@algolia/client-abtesting@5.12.0': + dependencies: + '@algolia/client-common': 5.12.0 + '@algolia/requester-browser-xhr': 5.12.0 + '@algolia/requester-fetch': 5.12.0 + '@algolia/requester-node-http': 5.12.0 + + '@algolia/client-analytics@5.12.0': + dependencies: + '@algolia/client-common': 5.12.0 + '@algolia/requester-browser-xhr': 5.12.0 + '@algolia/requester-fetch': 5.12.0 + '@algolia/requester-node-http': 5.12.0 + + '@algolia/client-common@5.12.0': {} + + '@algolia/client-insights@5.12.0': + dependencies: + '@algolia/client-common': 5.12.0 + '@algolia/requester-browser-xhr': 5.12.0 + '@algolia/requester-fetch': 5.12.0 + '@algolia/requester-node-http': 5.12.0 + + '@algolia/client-personalization@5.12.0': + dependencies: + '@algolia/client-common': 5.12.0 + '@algolia/requester-browser-xhr': 5.12.0 + '@algolia/requester-fetch': 5.12.0 + '@algolia/requester-node-http': 5.12.0 + + '@algolia/client-query-suggestions@5.12.0': + dependencies: + '@algolia/client-common': 5.12.0 + '@algolia/requester-browser-xhr': 5.12.0 + '@algolia/requester-fetch': 5.12.0 + '@algolia/requester-node-http': 5.12.0 + + '@algolia/client-search@5.12.0': + dependencies: + '@algolia/client-common': 5.12.0 + '@algolia/requester-browser-xhr': 5.12.0 + '@algolia/requester-fetch': 5.12.0 + '@algolia/requester-node-http': 5.12.0 + + '@algolia/ingestion@1.12.0': + dependencies: + '@algolia/client-common': 5.12.0 + '@algolia/requester-browser-xhr': 5.12.0 + '@algolia/requester-fetch': 5.12.0 + '@algolia/requester-node-http': 5.12.0 + + '@algolia/monitoring@1.12.0': + dependencies: + '@algolia/client-common': 5.12.0 + '@algolia/requester-browser-xhr': 5.12.0 + '@algolia/requester-fetch': 5.12.0 + '@algolia/requester-node-http': 5.12.0 + + '@algolia/recommend@5.12.0': + dependencies: + '@algolia/client-common': 5.12.0 + '@algolia/requester-browser-xhr': 5.12.0 + '@algolia/requester-fetch': 5.12.0 + '@algolia/requester-node-http': 5.12.0 + + '@algolia/requester-browser-xhr@5.12.0': + dependencies: + '@algolia/client-common': 5.12.0 + + '@algolia/requester-fetch@5.12.0': + dependencies: + '@algolia/client-common': 5.12.0 + + '@algolia/requester-node-http@5.12.0': + dependencies: + '@algolia/client-common': 5.12.0 + + '@ampproject/remapping@2.2.1': + dependencies: + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.17 + + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + + '@andrewbranch/untar.js@1.0.3': {} + + '@antfu/install-pkg@0.1.1': + dependencies: + execa: 5.1.1 + find-up: 5.0.0 + + '@antfu/utils@0.7.7': {} + + '@arethetypeswrong/cli@0.16.4': + dependencies: + '@arethetypeswrong/core': 0.16.4 + chalk: 4.1.2 + cli-table3: 0.6.5 + commander: 10.0.1 + marked: 9.1.6 + marked-terminal: 7.1.0(marked@9.1.6) + semver: 7.6.2 + + '@arethetypeswrong/core@0.16.4': + dependencies: + '@andrewbranch/untar.js': 1.0.3 + cjs-module-lexer: 1.4.1 + fflate: 0.8.2 + lru-cache: 10.4.3 + semver: 7.7.2 + typescript: 5.6.1-rc + validate-npm-package-name: 5.0.1 + + '@babel/code-frame@7.24.2': + dependencies: + '@babel/highlight': 7.24.5 + picocolors: 1.1.1 + + '@babel/code-frame@7.27.1': + dependencies: + '@babel/helper-validator-identifier': 7.27.1 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.24.4': {} + + '@babel/compat-data@7.27.2': {} + + '@babel/core@7.24.5': + dependencies: + '@ampproject/remapping': 2.2.1 + '@babel/code-frame': 7.24.2 + '@babel/generator': 7.24.5 + '@babel/helper-compilation-targets': 7.23.6 + '@babel/helper-module-transforms': 7.24.5(@babel/core@7.24.5) + '@babel/helpers': 7.24.5 + '@babel/parser': 7.24.5 + '@babel/template': 7.24.0 + '@babel/traverse': 7.24.5 + '@babel/types': 7.24.5 + convert-source-map: 2.0.0 + debug: 4.4.1 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/core@7.27.1': + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.27.1 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-module-transforms': 7.27.1(@babel/core@7.27.1) + '@babel/helpers': 7.27.1 + '@babel/parser': 7.27.2 + '@babel/template': 7.27.2 + '@babel/traverse': 7.27.1 + '@babel/types': 7.27.1 + convert-source-map: 2.0.0 + debug: 4.4.1 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.24.5': + dependencies: + '@babel/types': 7.27.1 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 2.5.2 + + '@babel/generator@7.27.1': + dependencies: + '@babel/parser': 7.27.2 + '@babel/types': 7.27.1 + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 3.1.0 + + '@babel/helper-annotate-as-pure@7.22.5': + dependencies: + '@babel/types': 7.27.1 + + '@babel/helper-annotate-as-pure@7.27.1': + dependencies: + '@babel/types': 7.27.1 + + '@babel/helper-compilation-targets@7.23.6': + dependencies: + '@babel/compat-data': 7.24.4 + '@babel/helper-validator-option': 7.23.5 + browserslist: 4.23.0 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-compilation-targets@7.27.2': + dependencies: + '@babel/compat-data': 7.27.2 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.24.5 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-create-class-features-plugin@7.24.5(@babel/core@7.24.5)': + dependencies: + '@babel/core': 7.24.5 + '@babel/helper-annotate-as-pure': 7.27.1 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-member-expression-to-functions': 7.24.5 + '@babel/helper-optimise-call-expression': 7.22.5 + '@babel/helper-replace-supers': 7.24.1(@babel/core@7.24.5) + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/helper-split-export-declaration': 7.24.5 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-create-class-features-plugin@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-annotate-as-pure': 7.27.1 + '@babel/helper-member-expression-to-functions': 7.27.1 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.27.1) + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/traverse': 7.27.1 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-environment-visitor@7.22.20': {} + + '@babel/helper-function-name@7.23.0': + dependencies: + '@babel/template': 7.24.0 + '@babel/types': 7.27.1 + + '@babel/helper-hoist-variables@7.22.5': + dependencies: + '@babel/types': 7.27.1 + + '@babel/helper-member-expression-to-functions@7.24.5': + dependencies: + '@babel/types': 7.27.1 + + '@babel/helper-member-expression-to-functions@7.27.1': + dependencies: + '@babel/traverse': 7.27.1 + '@babel/types': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-imports@7.24.3': + dependencies: + '@babel/types': 7.27.1 + + '@babel/helper-module-imports@7.27.1': + dependencies: + '@babel/traverse': 7.27.1 + '@babel/types': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.24.5(@babel/core@7.24.5)': + dependencies: + '@babel/core': 7.24.5 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-module-imports': 7.24.3 + '@babel/helper-simple-access': 7.24.5 + '@babel/helper-split-export-declaration': 7.24.5 + '@babel/helper-validator-identifier': 7.24.5 + + '@babel/helper-module-transforms@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@babel/traverse': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-optimise-call-expression@7.22.5': + dependencies: + '@babel/types': 7.27.1 + + '@babel/helper-optimise-call-expression@7.27.1': + dependencies: + '@babel/types': 7.27.1 + + '@babel/helper-plugin-utils@7.24.5': {} + + '@babel/helper-plugin-utils@7.27.1': {} + + '@babel/helper-replace-supers@7.24.1(@babel/core@7.24.5)': + dependencies: + '@babel/core': 7.24.5 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-member-expression-to-functions': 7.27.1 + '@babel/helper-optimise-call-expression': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-replace-supers@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-member-expression-to-functions': 7.27.1 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/traverse': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-simple-access@7.24.5': + dependencies: + '@babel/types': 7.27.1 + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + dependencies: + '@babel/traverse': 7.27.1 + '@babel/types': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-split-export-declaration@7.24.5': + dependencies: + '@babel/types': 7.27.1 + + '@babel/helper-string-parser@7.24.1': {} + + '@babel/helper-string-parser@7.25.9': {} + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.24.5': {} + + '@babel/helper-validator-identifier@7.25.9': {} + + '@babel/helper-validator-identifier@7.27.1': {} + + '@babel/helper-validator-option@7.23.5': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helpers@7.24.5': + dependencies: + '@babel/template': 7.24.0 + '@babel/traverse': 7.24.5 + '@babel/types': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/helpers@7.27.1': + dependencies: + '@babel/template': 7.27.2 + '@babel/types': 7.27.1 + + '@babel/highlight@7.24.5': + dependencies: + '@babel/helper-validator-identifier': 7.25.9 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/parser@7.24.5': + dependencies: + '@babel/types': 7.27.1 + + '@babel/parser@7.26.2': + dependencies: + '@babel/types': 7.26.0 + + '@babel/parser@7.27.2': + dependencies: + '@babel/types': 7.27.1 + + '@babel/plugin-syntax-jsx@7.24.1(@babel/core@7.24.5)': + dependencies: + '@babel/core': 7.24.5 + '@babel/helper-plugin-utils': 7.24.5 + + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-typescript@7.24.1(@babel/core@7.24.5)': + dependencies: + '@babel/core': 7.24.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-modules-commonjs@7.24.1(@babel/core@7.24.5)': + dependencies: + '@babel/core': 7.24.5 + '@babel/helper-module-transforms': 7.24.5(@babel/core@7.24.5) + '@babel/helper-plugin-utils': 7.24.5 + '@babel/helper-simple-access': 7.24.5 + + '@babel/plugin-transform-react-jsx-self@7.24.5(@babel/core@7.24.5)': + dependencies: + '@babel/core': 7.24.5 + '@babel/helper-plugin-utils': 7.24.5 + + '@babel/plugin-transform-react-jsx-source@7.24.1(@babel/core@7.24.5)': + dependencies: + '@babel/core': 7.24.5 + '@babel/helper-plugin-utils': 7.24.5 + + '@babel/plugin-transform-typescript@7.24.5(@babel/core@7.24.5)': + dependencies: + '@babel/core': 7.24.5 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-create-class-features-plugin': 7.24.5(@babel/core@7.24.5) + '@babel/helper-plugin-utils': 7.24.5 + '@babel/plugin-syntax-typescript': 7.24.1(@babel/core@7.24.5) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-typescript@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-annotate-as-pure': 7.27.1 + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.27.1) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.27.1) + transitivePeerDependencies: + - supports-color + + '@babel/preset-typescript@7.24.1(@babel/core@7.24.5)': + dependencies: + '@babel/core': 7.24.5 + '@babel/helper-plugin-utils': 7.24.5 + '@babel/helper-validator-option': 7.23.5 + '@babel/plugin-syntax-jsx': 7.24.1(@babel/core@7.24.5) + '@babel/plugin-transform-modules-commonjs': 7.24.1(@babel/core@7.24.5) + '@babel/plugin-transform-typescript': 7.24.5(@babel/core@7.24.5) + transitivePeerDependencies: + - supports-color + + '@babel/runtime@7.26.0': + dependencies: + regenerator-runtime: 0.14.0 + + '@babel/runtime@7.27.6': {} + + '@babel/standalone@7.24.5': {} + + '@babel/template@7.24.0': + dependencies: + '@babel/code-frame': 7.24.2 + '@babel/parser': 7.26.2 + '@babel/types': 7.27.1 + + '@babel/template@7.27.2': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/parser': 7.27.2 + '@babel/types': 7.27.1 + + '@babel/traverse@7.24.5': + dependencies: + '@babel/code-frame': 7.24.2 + '@babel/generator': 7.24.5 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-split-export-declaration': 7.24.5 + '@babel/parser': 7.26.2 + '@babel/types': 7.27.1 + debug: 4.4.1 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/traverse@7.27.1': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.27.1 + '@babel/parser': 7.27.2 + '@babel/template': 7.27.2 + '@babel/types': 7.27.1 + debug: 4.4.1 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.24.5': + dependencies: + '@babel/helper-string-parser': 7.24.1 + '@babel/helper-validator-identifier': 7.24.5 + to-fast-properties: 2.0.0 + + '@babel/types@7.26.0': + dependencies: + '@babel/helper-string-parser': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + + '@babel/types@7.27.1': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + + '@bcoe/v8-coverage@0.2.3': {} + + '@biomejs/biome@1.9.4': + optionalDependencies: + '@biomejs/cli-darwin-arm64': 1.9.4 + '@biomejs/cli-darwin-x64': 1.9.4 + '@biomejs/cli-linux-arm64': 1.9.4 + '@biomejs/cli-linux-arm64-musl': 1.9.4 + '@biomejs/cli-linux-x64': 1.9.4 + '@biomejs/cli-linux-x64-musl': 1.9.4 + '@biomejs/cli-win32-arm64': 1.9.4 + '@biomejs/cli-win32-x64': 1.9.4 + + '@biomejs/cli-darwin-arm64@1.9.4': + optional: true + + '@biomejs/cli-darwin-x64@1.9.4': + optional: true + + '@biomejs/cli-linux-arm64-musl@1.9.4': + optional: true + + '@biomejs/cli-linux-arm64@1.9.4': + optional: true + + '@biomejs/cli-linux-x64-musl@1.9.4': + optional: true + + '@biomejs/cli-linux-x64@1.9.4': + optional: true + + '@biomejs/cli-win32-arm64@1.9.4': + optional: true + + '@biomejs/cli-win32-x64@1.9.4': + optional: true + + '@bundled-es-modules/cookie@2.0.0': + dependencies: + cookie: 0.5.0 + + '@bundled-es-modules/statuses@1.0.1': + dependencies: + statuses: 2.0.1 + + '@bundled-es-modules/tough-cookie@0.1.6': + dependencies: + '@types/tough-cookie': 4.0.5 + tough-cookie: 4.1.4 + + '@changesets/apply-release-plan@7.0.5': + dependencies: + '@changesets/config': 3.0.3 + '@changesets/get-version-range-type': 0.4.0 + '@changesets/git': 3.0.1 + '@changesets/should-skip-package': 0.1.1 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + detect-indent: 6.1.0 + fs-extra: 7.0.1 + lodash.startcase: 4.4.0 + outdent: 0.5.0 + prettier: 2.8.8 + resolve-from: 5.0.0 + semver: 7.7.2 + + '@changesets/assemble-release-plan@6.0.4': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.2 + '@changesets/should-skip-package': 0.1.1 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + semver: 7.7.2 + + '@changesets/changelog-git@0.2.0': + dependencies: + '@changesets/types': 6.0.0 + + '@changesets/changelog-github@0.4.6(encoding@0.1.13)': + dependencies: + '@changesets/get-github-info': 0.5.2(encoding@0.1.13) + '@changesets/types': 5.2.1 + dotenv: 8.6.0 + transitivePeerDependencies: + - encoding + + '@changesets/cli@2.27.8': + dependencies: + '@changesets/apply-release-plan': 7.0.5 + '@changesets/assemble-release-plan': 6.0.4 + '@changesets/changelog-git': 0.2.0 + '@changesets/config': 3.0.3 + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.2 + '@changesets/get-release-plan': 4.0.4 + '@changesets/git': 3.0.1 + '@changesets/logger': 0.1.1 + '@changesets/pre': 2.0.1 + '@changesets/read': 0.6.1 + '@changesets/should-skip-package': 0.1.1 + '@changesets/types': 6.0.0 + '@changesets/write': 0.3.2 + '@manypkg/get-packages': 1.1.3 + '@types/semver': 7.5.3 + ansi-colors: 4.1.3 + ci-info: 3.9.0 + enquirer: 2.3.6 + external-editor: 3.1.0 + fs-extra: 7.0.1 + mri: 1.2.0 + outdent: 0.5.0 + p-limit: 2.3.0 + package-manager-detector: 0.2.0 + picocolors: 1.1.0 + resolve-from: 5.0.0 + semver: 7.6.2 + spawndamnit: 2.0.0 + term-size: 2.2.1 + + '@changesets/config@3.0.3': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.2 + '@changesets/logger': 0.1.1 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + micromatch: 4.0.5 + + '@changesets/errors@0.2.0': + dependencies: + extendable-error: 0.1.7 + + '@changesets/get-dependents-graph@2.1.2': + dependencies: + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + picocolors: 1.1.0 + semver: 7.7.2 + + '@changesets/get-github-info@0.5.2(encoding@0.1.13)': + dependencies: + dataloader: 1.4.0 + node-fetch: 2.6.9(encoding@0.1.13) + transitivePeerDependencies: + - encoding + + '@changesets/get-release-plan@4.0.4': + dependencies: + '@changesets/assemble-release-plan': 6.0.4 + '@changesets/config': 3.0.3 + '@changesets/pre': 2.0.1 + '@changesets/read': 0.6.1 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + + '@changesets/get-version-range-type@0.4.0': {} + + '@changesets/git@3.0.1': + dependencies: + '@changesets/errors': 0.2.0 + '@manypkg/get-packages': 1.1.3 + is-subdir: 1.2.0 + micromatch: 4.0.5 + spawndamnit: 2.0.0 + + '@changesets/logger@0.1.1': + dependencies: + picocolors: 1.1.0 + + '@changesets/parse@0.4.0': + dependencies: + '@changesets/types': 6.0.0 + js-yaml: 3.14.1 + + '@changesets/pre@2.0.1': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + + '@changesets/read@0.6.1': + dependencies: + '@changesets/git': 3.0.1 + '@changesets/logger': 0.1.1 + '@changesets/parse': 0.4.0 + '@changesets/types': 6.0.0 + fs-extra: 7.0.1 + p-filter: 2.1.0 + picocolors: 1.1.0 + + '@changesets/should-skip-package@0.1.1': + dependencies: + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + + '@changesets/types@4.1.0': {} + + '@changesets/types@5.2.1': {} + + '@changesets/types@6.0.0': {} + + '@changesets/write@0.3.2': + dependencies: + '@changesets/types': 6.0.0 + fs-extra: 7.0.1 + human-id: 1.0.2 + prettier: 2.8.8 + + '@cloudflare/kv-asset-handler@0.4.0': + dependencies: + mime: 3.0.0 + + '@coinbase/wallet-sdk@3.9.3': + dependencies: + bn.js: 5.2.1 + buffer: 6.0.3 + clsx: 1.2.1 + eth-block-tracker: 7.1.0 + eth-json-rpc-filters: 6.0.1 + eventemitter3: 5.0.1 + keccak: 3.0.3 + preact: 10.17.1 + sha.js: 2.4.11 + transitivePeerDependencies: + - supports-color + + '@coinbase/wallet-sdk@4.3.0': + dependencies: + '@noble/hashes': 1.5.0 + clsx: 1.2.1 + eventemitter3: 5.0.1 + preact: 10.24.3 + + '@colors/colors@1.5.0': + optional: true + + '@colors/colors@1.6.0': {} + + '@dabh/diagnostics@2.0.3': + dependencies: + colorspace: 1.1.4 + enabled: 2.0.0 + kuler: 2.0.0 + + '@dependents/detective-less@4.1.0': + dependencies: + gonzales-pe: 4.3.0 + node-source-walk: 6.0.2 + + '@discoveryjs/json-ext@0.5.7': {} + + '@docsearch/css@3.6.3': {} + + '@docsearch/js@3.6.3(@algolia/client-search@5.12.0)(@types/react@18.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@docsearch/react': 3.6.3(@algolia/client-search@5.12.0)(@types/react@18.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + preact: 10.24.3 + transitivePeerDependencies: + - '@algolia/client-search' + - '@types/react' + - react + - react-dom + - search-insights + + '@docsearch/react@3.6.3(@algolia/client-search@5.12.0)(@types/react@18.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@algolia/autocomplete-core': 1.9.3(@algolia/client-search@5.12.0)(algoliasearch@5.12.0) + '@algolia/autocomplete-preset-algolia': 1.17.6(@algolia/client-search@5.12.0)(algoliasearch@5.12.0) + '@docsearch/css': 3.6.3 + algoliasearch: 5.12.0 + optionalDependencies: + '@types/react': 18.3.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + transitivePeerDependencies: + - '@algolia/client-search' + + '@ecies/ciphers@0.2.3(@noble/ciphers@1.3.0)': + dependencies: + '@noble/ciphers': 1.3.0 + + '@emnapi/core@1.4.3': + dependencies: + '@emnapi/wasi-threads': 1.0.2 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.4.3': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.0.2': + dependencies: + tslib: 2.8.1 + optional: true + + '@esbuild/aix-ppc64@0.21.5': + optional: true + + '@esbuild/aix-ppc64@0.25.4': + optional: true + + '@esbuild/aix-ppc64@0.25.5': + optional: true + + '@esbuild/android-arm64@0.21.5': + optional: true + + '@esbuild/android-arm64@0.25.4': + optional: true + + '@esbuild/android-arm64@0.25.5': + optional: true + + '@esbuild/android-arm@0.21.5': + optional: true + + '@esbuild/android-arm@0.25.4': + optional: true + + '@esbuild/android-arm@0.25.5': + optional: true + + '@esbuild/android-x64@0.21.5': + optional: true + + '@esbuild/android-x64@0.25.4': + optional: true + + '@esbuild/android-x64@0.25.5': + optional: true + + '@esbuild/darwin-arm64@0.21.5': + optional: true + + '@esbuild/darwin-arm64@0.25.4': + optional: true + + '@esbuild/darwin-arm64@0.25.5': + optional: true + + '@esbuild/darwin-x64@0.21.5': + optional: true + + '@esbuild/darwin-x64@0.25.4': + optional: true + + '@esbuild/darwin-x64@0.25.5': + optional: true + + '@esbuild/freebsd-arm64@0.21.5': + optional: true + + '@esbuild/freebsd-arm64@0.25.4': + optional: true + + '@esbuild/freebsd-arm64@0.25.5': + optional: true + + '@esbuild/freebsd-x64@0.21.5': + optional: true + + '@esbuild/freebsd-x64@0.25.4': + optional: true + + '@esbuild/freebsd-x64@0.25.5': + optional: true + + '@esbuild/linux-arm64@0.21.5': + optional: true + + '@esbuild/linux-arm64@0.25.4': + optional: true + + '@esbuild/linux-arm64@0.25.5': + optional: true + + '@esbuild/linux-arm@0.21.5': + optional: true + + '@esbuild/linux-arm@0.25.4': + optional: true + + '@esbuild/linux-arm@0.25.5': + optional: true + + '@esbuild/linux-ia32@0.21.5': + optional: true + + '@esbuild/linux-ia32@0.25.4': + optional: true + + '@esbuild/linux-ia32@0.25.5': + optional: true + + '@esbuild/linux-loong64@0.21.5': + optional: true + + '@esbuild/linux-loong64@0.25.4': + optional: true + + '@esbuild/linux-loong64@0.25.5': + optional: true + + '@esbuild/linux-mips64el@0.21.5': + optional: true + + '@esbuild/linux-mips64el@0.25.4': + optional: true + + '@esbuild/linux-mips64el@0.25.5': + optional: true + + '@esbuild/linux-ppc64@0.21.5': + optional: true + + '@esbuild/linux-ppc64@0.25.4': + optional: true + + '@esbuild/linux-ppc64@0.25.5': + optional: true + + '@esbuild/linux-riscv64@0.21.5': + optional: true + + '@esbuild/linux-riscv64@0.25.4': + optional: true + + '@esbuild/linux-riscv64@0.25.5': + optional: true + + '@esbuild/linux-s390x@0.21.5': + optional: true + + '@esbuild/linux-s390x@0.25.4': + optional: true + + '@esbuild/linux-s390x@0.25.5': + optional: true + + '@esbuild/linux-x64@0.21.5': + optional: true + + '@esbuild/linux-x64@0.25.4': + optional: true + + '@esbuild/linux-x64@0.25.5': + optional: true + + '@esbuild/netbsd-arm64@0.25.4': + optional: true + + '@esbuild/netbsd-arm64@0.25.5': + optional: true + + '@esbuild/netbsd-x64@0.21.5': + optional: true + + '@esbuild/netbsd-x64@0.25.4': + optional: true + + '@esbuild/netbsd-x64@0.25.5': + optional: true + + '@esbuild/openbsd-arm64@0.25.4': + optional: true + + '@esbuild/openbsd-arm64@0.25.5': + optional: true + + '@esbuild/openbsd-x64@0.21.5': + optional: true + + '@esbuild/openbsd-x64@0.25.4': + optional: true + + '@esbuild/openbsd-x64@0.25.5': + optional: true + + '@esbuild/sunos-x64@0.21.5': + optional: true + + '@esbuild/sunos-x64@0.25.4': + optional: true + + '@esbuild/sunos-x64@0.25.5': + optional: true + + '@esbuild/win32-arm64@0.21.5': + optional: true + + '@esbuild/win32-arm64@0.25.4': + optional: true + + '@esbuild/win32-arm64@0.25.5': + optional: true + + '@esbuild/win32-ia32@0.21.5': + optional: true + + '@esbuild/win32-ia32@0.25.4': + optional: true + + '@esbuild/win32-ia32@0.25.5': + optional: true + + '@esbuild/win32-x64@0.21.5': + optional: true + + '@esbuild/win32-x64@0.25.4': + optional: true + + '@esbuild/win32-x64@0.25.5': + optional: true + + '@ethereumjs/common@3.2.0': + dependencies: + '@ethereumjs/util': 8.1.0 + crc-32: 1.2.2 + + '@ethereumjs/rlp@4.0.1': {} + + '@ethereumjs/tx@4.2.0': + dependencies: + '@ethereumjs/common': 3.2.0 + '@ethereumjs/rlp': 4.0.1 + '@ethereumjs/util': 8.1.0 + ethereum-cryptography: 2.2.1 + + '@ethereumjs/util@8.1.0': + dependencies: + '@ethereumjs/rlp': 4.0.1 + ethereum-cryptography: 2.2.1 + micro-ftch: 0.3.1 + + '@ethersproject/abi@5.7.0': + dependencies: + '@ethersproject/address': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/hash': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/strings': 5.7.0 + + '@ethersproject/abstract-provider@5.7.0': + dependencies: + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/networks': 5.7.1 + '@ethersproject/properties': 5.7.0 + '@ethersproject/transactions': 5.7.0 + '@ethersproject/web': 5.7.1 + + '@ethersproject/abstract-signer@5.7.0': + dependencies: + '@ethersproject/abstract-provider': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + + '@ethersproject/address@5.7.0': + dependencies: + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/rlp': 5.7.0 + + '@ethersproject/base64@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + + '@ethersproject/bignumber@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + bn.js: 5.2.1 + + '@ethersproject/bytes@5.7.0': + dependencies: + '@ethersproject/logger': 5.7.0 + + '@ethersproject/constants@5.7.0': + dependencies: + '@ethersproject/bignumber': 5.7.0 + + '@ethersproject/hash@5.7.0': + dependencies: + '@ethersproject/abstract-signer': 5.7.0 + '@ethersproject/address': 5.7.0 + '@ethersproject/base64': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/strings': 5.7.0 + + '@ethersproject/keccak256@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + js-sha3: 0.8.0 + + '@ethersproject/logger@5.7.0': {} + + '@ethersproject/networks@5.7.1': + dependencies: + '@ethersproject/logger': 5.7.0 + + '@ethersproject/properties@5.7.0': + dependencies: + '@ethersproject/logger': 5.7.0 + + '@ethersproject/rlp@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + + '@ethersproject/signing-key@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + bn.js: 5.2.1 + elliptic: 6.5.4 + hash.js: 1.1.7 + + '@ethersproject/strings@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/logger': 5.7.0 + + '@ethersproject/transactions@5.7.0': + dependencies: + '@ethersproject/address': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/rlp': 5.7.0 + '@ethersproject/signing-key': 5.7.0 + + '@ethersproject/web@5.7.1': + dependencies: + '@ethersproject/base64': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/strings': 5.7.0 + + '@fastify/busboy@2.1.0': {} + + '@fastify/busboy@3.1.1': {} + + '@floating-ui/core@1.6.1': + dependencies: + '@floating-ui/utils': 0.2.2 + + '@floating-ui/dom@1.1.1': + dependencies: + '@floating-ui/core': 1.6.1 + + '@floating-ui/utils@0.2.2': {} + + '@iconify-json/simple-icons@1.2.10': + dependencies: + '@iconify/types': 2.0.0 + + '@iconify/types@2.0.0': {} + + '@iconify/utils@2.1.23': + dependencies: + '@antfu/install-pkg': 0.1.1 + '@antfu/utils': 0.7.7 + '@iconify/types': 2.0.0 + debug: 4.4.1 + kolorist: 1.8.0 + local-pkg: 0.5.1 + mlly: 1.7.4 + transitivePeerDependencies: + - supports-color + + '@img/sharp-darwin-arm64@0.34.2': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.1.0 + optional: true + + '@img/sharp-darwin-x64@0.34.2': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.1.0 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.1.0': + optional: true + + '@img/sharp-libvips-darwin-x64@1.1.0': + optional: true + + '@img/sharp-libvips-linux-arm64@1.1.0': + optional: true + + '@img/sharp-libvips-linux-arm@1.1.0': + optional: true + + '@img/sharp-libvips-linux-ppc64@1.1.0': + optional: true + + '@img/sharp-libvips-linux-s390x@1.1.0': + optional: true + + '@img/sharp-libvips-linux-x64@1.1.0': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.1.0': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.1.0': + optional: true + + '@img/sharp-linux-arm64@0.34.2': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.1.0 + optional: true + + '@img/sharp-linux-arm@0.34.2': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.1.0 + optional: true + + '@img/sharp-linux-s390x@0.34.2': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.1.0 + optional: true + + '@img/sharp-linux-x64@0.34.2': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.1.0 + optional: true + + '@img/sharp-linuxmusl-arm64@0.34.2': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.1.0 + optional: true + + '@img/sharp-linuxmusl-x64@0.34.2': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.1.0 + optional: true + + '@img/sharp-wasm32@0.34.2': + dependencies: + '@emnapi/runtime': 1.4.3 + optional: true + + '@img/sharp-win32-arm64@0.34.2': + optional: true + + '@img/sharp-win32-ia32@0.34.2': + optional: true + + '@img/sharp-win32-x64@0.34.2': + optional: true + + '@inquirer/confirm@3.1.6': + dependencies: + '@inquirer/core': 8.1.0 + '@inquirer/type': 1.3.1 + + '@inquirer/core@8.1.0': + dependencies: + '@inquirer/figures': 1.0.1 + '@inquirer/type': 1.3.1 + '@types/mute-stream': 0.0.4 + '@types/node': 20.19.0 + '@types/wrap-ansi': 3.0.0 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + cli-spinners: 2.9.2 + cli-width: 4.1.0 + mute-stream: 1.0.0 + signal-exit: 4.1.0 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + + '@inquirer/figures@1.0.1': {} + + '@inquirer/type@1.3.1': {} + + '@ioredis/commands@1.2.0': {} + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@isaacs/fs-minipass@4.0.1': + dependencies: + minipass: 7.1.2 + + '@istanbuljs/schema@0.1.3': {} + + '@jridgewell/gen-mapping@0.3.3': + dependencies: + '@jridgewell/set-array': 1.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.17 + + '@jridgewell/gen-mapping@0.3.5': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/gen-mapping@0.3.8': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.0': {} + + '@jridgewell/set-array@1.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/source-map@0.3.6': + dependencies: + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/sourcemap-codec@1.4.14': {} + + '@jridgewell/sourcemap-codec@1.4.15': {} + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.17': + dependencies: + '@jridgewell/resolve-uri': 3.1.0 + '@jridgewell/sourcemap-codec': 1.4.14 + + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.0 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@kwsites/file-exists@1.1.1': + dependencies: + debug: 4.4.1 + transitivePeerDependencies: + - supports-color + + '@kwsites/promise-deferred@1.1.1': {} + + '@lit-labs/ssr-dom-shim@1.3.0': {} + + '@lit/reactive-element@2.1.0': + dependencies: + '@lit-labs/ssr-dom-shim': 1.3.0 + + '@manypkg/find-root@1.1.0': + dependencies: + '@babel/runtime': 7.26.0 + '@types/node': 12.20.55 + find-up: 4.1.0 + fs-extra: 8.1.0 + + '@manypkg/get-packages@1.1.3': + dependencies: + '@babel/runtime': 7.26.0 + '@changesets/types': 4.1.0 + '@manypkg/find-root': 1.1.0 + fs-extra: 8.1.0 + globby: 11.1.0 + read-yaml-file: 1.1.0 + + '@mapbox/node-pre-gyp@1.0.11(encoding@0.1.13)': + dependencies: + detect-libc: 2.0.4 + https-proxy-agent: 5.0.1 + make-dir: 3.1.0 + node-fetch: 2.7.0(encoding@0.1.13) + nopt: 5.0.0 + npmlog: 5.0.1 + rimraf: 3.0.2 + semver: 7.7.2 + tar: 6.2.1 + transitivePeerDependencies: + - encoding + - supports-color + + '@mapbox/node-pre-gyp@2.0.0(encoding@0.1.13)': + dependencies: + consola: 3.4.2 + detect-libc: 2.0.4 + https-proxy-agent: 7.0.6 + node-fetch: 2.7.0(encoding@0.1.13) + nopt: 8.1.0 + semver: 7.7.2 + tar: 7.4.3 + transitivePeerDependencies: + - encoding + - supports-color + + '@metamask/eth-json-rpc-provider@1.0.1': + dependencies: + '@metamask/json-rpc-engine': 7.3.3 + '@metamask/safe-event-emitter': 3.0.0 + '@metamask/utils': 5.0.2 + transitivePeerDependencies: + - supports-color + + '@metamask/eth-sig-util@4.0.1': + dependencies: + ethereumjs-abi: 0.6.8 + ethereumjs-util: 6.2.1 + ethjs-util: 0.1.6 + tweetnacl: 1.0.3 + tweetnacl-util: 0.15.1 + + '@metamask/json-rpc-engine@7.3.3': + dependencies: + '@metamask/rpc-errors': 6.4.0 + '@metamask/safe-event-emitter': 3.0.0 + '@metamask/utils': 8.5.0 + transitivePeerDependencies: + - supports-color + + '@metamask/json-rpc-engine@8.0.2': + dependencies: + '@metamask/rpc-errors': 6.4.0 + '@metamask/safe-event-emitter': 3.1.2 + '@metamask/utils': 8.5.0 + transitivePeerDependencies: + - supports-color + + '@metamask/json-rpc-middleware-stream@7.0.2': + dependencies: + '@metamask/json-rpc-engine': 8.0.2 + '@metamask/safe-event-emitter': 3.1.2 + '@metamask/utils': 8.5.0 + readable-stream: 3.6.2 + transitivePeerDependencies: + - supports-color + + '@metamask/object-multiplex@2.1.0': + dependencies: + once: 1.4.0 + readable-stream: 3.6.2 + + '@metamask/onboarding@1.0.1': + dependencies: + bowser: 2.11.0 + + '@metamask/providers@16.1.0': + dependencies: + '@metamask/json-rpc-engine': 8.0.2 + '@metamask/json-rpc-middleware-stream': 7.0.2 + '@metamask/object-multiplex': 2.1.0 + '@metamask/rpc-errors': 6.4.0 + '@metamask/safe-event-emitter': 3.1.2 + '@metamask/utils': 8.5.0 + detect-browser: 5.3.0 + extension-port-stream: 3.0.0 + fast-deep-equal: 3.1.3 + is-stream: 2.0.1 + readable-stream: 3.6.2 + webextension-polyfill: 0.10.0 + transitivePeerDependencies: + - supports-color + + '@metamask/rpc-errors@6.4.0': + dependencies: + '@metamask/utils': 9.3.0 + fast-safe-stringify: 2.1.1 + transitivePeerDependencies: + - supports-color + + '@metamask/safe-event-emitter@2.0.0': {} + + '@metamask/safe-event-emitter@3.0.0': {} + + '@metamask/safe-event-emitter@3.1.2': {} + + '@metamask/sdk-communication-layer@0.32.0(cross-fetch@4.1.0(encoding@0.1.13))(eciesjs@0.4.15)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + bufferutil: 4.0.9 + cross-fetch: 4.1.0(encoding@0.1.13) + date-fns: 2.30.0 + debug: 4.4.1 + eciesjs: 0.4.15 + eventemitter2: 6.4.9 + readable-stream: 3.6.2 + socket.io-client: 4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + utf-8-validate: 5.0.10 + uuid: 8.3.2 + transitivePeerDependencies: + - supports-color + + '@metamask/sdk-install-modal-web@0.32.1': + dependencies: + '@paulmillr/qr': 0.2.1 + + '@metamask/sdk@0.32.1(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)': + dependencies: + '@babel/runtime': 7.27.6 + '@metamask/onboarding': 1.0.1 + '@metamask/providers': 16.1.0 + '@metamask/sdk-communication-layer': 0.32.0(cross-fetch@4.1.0(encoding@0.1.13))(eciesjs@0.4.15)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@metamask/sdk-install-modal-web': 0.32.1 + '@paulmillr/qr': 0.2.1 + bowser: 2.11.0 + cross-fetch: 4.1.0(encoding@0.1.13) + debug: 4.4.1 + eciesjs: 0.4.15 + eth-rpc-errors: 4.0.3 + eventemitter2: 6.4.9 + obj-multiplex: 1.0.0 + pump: 3.0.2 + readable-stream: 3.6.2 + socket.io-client: 4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + tslib: 2.8.1 + util: 0.12.5 + uuid: 8.3.2 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + + '@metamask/superstruct@3.2.1': {} + + '@metamask/utils@5.0.2': + dependencies: + '@ethereumjs/tx': 4.2.0 + '@types/debug': 4.1.7 + debug: 4.4.1 + semver: 7.7.2 + superstruct: 1.0.3 + transitivePeerDependencies: + - supports-color + + '@metamask/utils@8.5.0': + dependencies: + '@ethereumjs/tx': 4.2.0 + '@metamask/superstruct': 3.2.1 + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + '@types/debug': 4.1.12 + debug: 4.4.1 + pony-cause: 2.1.11 + semver: 7.7.2 + uuid: 9.0.1 + transitivePeerDependencies: + - supports-color + + '@metamask/utils@9.3.0': + dependencies: + '@ethereumjs/tx': 4.2.0 + '@metamask/superstruct': 3.2.1 + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + '@types/debug': 4.1.12 + debug: 4.4.1 + pony-cause: 2.1.11 + semver: 7.7.2 + uuid: 9.0.1 + transitivePeerDependencies: + - supports-color + + '@mswjs/interceptors@0.35.9': + dependencies: + '@open-draft/deferred-promise': 2.2.0 + '@open-draft/logger': 0.3.0 + '@open-draft/until': 2.1.0 + is-node-process: 1.2.0 + outvariant: 1.4.3 + strict-event-emitter: 0.5.1 + + '@napi-rs/wasm-runtime@0.2.10': + dependencies: + '@emnapi/core': 1.4.3 + '@emnapi/runtime': 1.4.3 + '@tybys/wasm-util': 0.9.0 + optional: true + + '@netlify/binary-info@1.0.0': {} + + '@netlify/blobs@9.1.1': + dependencies: + '@netlify/dev-utils': 2.1.1 + '@netlify/runtime-utils': 1.3.1 + + '@netlify/dev-utils@2.1.1': + dependencies: + '@whatwg-node/server': 0.9.71 + chokidar: 4.0.3 + decache: 4.6.2 + dot-prop: 9.0.0 + env-paths: 3.0.0 + find-up: 7.0.0 + lodash.debounce: 4.0.8 + netlify: 13.3.5 + parse-gitignore: 2.0.0 + uuid: 11.1.0 + write-file-atomic: 6.0.0 + + '@netlify/functions@3.1.8(encoding@0.1.13)(rollup@4.41.0)': + dependencies: + '@netlify/blobs': 9.1.1 + '@netlify/dev-utils': 2.1.1 + '@netlify/serverless-functions-api': 1.41.1 + '@netlify/zip-it-and-ship-it': 10.1.1(encoding@0.1.13)(rollup@4.41.0) + cron-parser: 4.9.0 + decache: 4.6.2 + extract-zip: 2.0.1 + is-stream: 4.0.1 + jwt-decode: 4.0.0 + lambda-local: 2.2.0 + read-package-up: 11.0.0 + source-map-support: 0.5.21 + transitivePeerDependencies: + - encoding + - rollup + - supports-color + + '@netlify/open-api@2.37.0': {} + + '@netlify/runtime-utils@1.3.1': {} + + '@netlify/serverless-functions-api@1.41.1': {} + + '@netlify/zip-it-and-ship-it@10.1.1(encoding@0.1.13)(rollup@4.41.0)': + dependencies: + '@babel/parser': 7.27.2 + '@babel/types': 7.27.1 + '@netlify/binary-info': 1.0.0 + '@netlify/serverless-functions-api': 1.41.1 + '@vercel/nft': 0.27.7(encoding@0.1.13)(rollup@4.41.0) + archiver: 5.3.2 + common-path-prefix: 3.0.0 + cp-file: 10.0.0 + es-module-lexer: 1.7.0 + esbuild: 0.25.4 + execa: 7.2.0 + fast-glob: 3.3.3 + filter-obj: 5.1.0 + find-up: 6.3.0 + glob: 8.1.0 + is-builtin-module: 3.2.1 + is-path-inside: 4.0.0 + junk: 4.0.1 + locate-path: 7.2.0 + merge-options: 3.0.4 + minimatch: 9.0.5 + normalize-path: 3.0.0 + p-map: 7.0.3 + path-exists: 5.0.0 + precinct: 11.0.5 + require-package-name: 2.0.1 + resolve: 2.0.0-next.5 + semver: 7.7.2 + tmp-promise: 3.0.3 + toml: 3.0.0 + unixify: 1.0.0 + urlpattern-polyfill: 8.0.2 + yargs: 17.7.2 + zod: 3.25.20 + transitivePeerDependencies: + - encoding + - rollup + - supports-color + + '@next/bundle-analyzer@15.3.3(bufferutil@4.0.8)(utf-8-validate@6.0.5)': + dependencies: + webpack-bundle-analyzer: 4.10.1(bufferutil@4.0.8)(utf-8-validate@6.0.5) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@next/env@15.3.3': {} + + '@next/swc-darwin-arm64@15.3.3': + optional: true + + '@next/swc-darwin-x64@15.3.3': + optional: true + + '@next/swc-linux-arm64-gnu@15.3.3': + optional: true + + '@next/swc-linux-arm64-musl@15.3.3': + optional: true + + '@next/swc-linux-x64-gnu@15.3.3': + optional: true + + '@next/swc-linux-x64-musl@15.3.3': + optional: true + + '@next/swc-win32-arm64-msvc@15.3.3': + optional: true + + '@next/swc-win32-x64-msvc@15.3.3': + optional: true + + '@noble/ciphers@1.2.1': {} + + '@noble/ciphers@1.3.0': {} + + '@noble/curves@1.2.0': + dependencies: + '@noble/hashes': 1.3.2 + + '@noble/curves@1.4.0': + dependencies: + '@noble/hashes': 1.4.0 + + '@noble/curves@1.4.2': + dependencies: + '@noble/hashes': 1.4.0 + + '@noble/curves@1.8.0': + dependencies: + '@noble/hashes': 1.7.0 + + '@noble/curves@1.8.1': + dependencies: + '@noble/hashes': 1.7.1 + + '@noble/curves@1.8.2': + dependencies: + '@noble/hashes': 1.7.2 + + '@noble/curves@1.9.2': + dependencies: + '@noble/hashes': 1.8.0 + + '@noble/hashes@1.2.0': {} + + '@noble/hashes@1.3.2': {} + + '@noble/hashes@1.4.0': {} + + '@noble/hashes@1.5.0': {} + + '@noble/hashes@1.7.0': {} + + '@noble/hashes@1.7.1': {} + + '@noble/hashes@1.7.2': {} + + '@noble/hashes@1.8.0': {} + + '@noble/secp256k1@1.7.1': {} + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.15.0 + + '@nomicfoundation/edr-darwin-arm64@0.3.7': + optional: true + + '@nomicfoundation/edr-darwin-x64@0.3.7': + optional: true + + '@nomicfoundation/edr-linux-arm64-gnu@0.3.7': + optional: true + + '@nomicfoundation/edr-linux-arm64-musl@0.3.7': + optional: true + + '@nomicfoundation/edr-linux-x64-gnu@0.3.7': + optional: true + + '@nomicfoundation/edr-linux-x64-musl@0.3.7': + optional: true + + '@nomicfoundation/edr-win32-x64-msvc@0.3.7': + optional: true + + '@nomicfoundation/edr@0.3.7': + optionalDependencies: + '@nomicfoundation/edr-darwin-arm64': 0.3.7 + '@nomicfoundation/edr-darwin-x64': 0.3.7 + '@nomicfoundation/edr-linux-arm64-gnu': 0.3.7 + '@nomicfoundation/edr-linux-arm64-musl': 0.3.7 + '@nomicfoundation/edr-linux-x64-gnu': 0.3.7 + '@nomicfoundation/edr-linux-x64-musl': 0.3.7 + '@nomicfoundation/edr-win32-x64-msvc': 0.3.7 + + '@nomicfoundation/ethereumjs-common@4.0.4': + dependencies: + '@nomicfoundation/ethereumjs-util': 9.0.4 + transitivePeerDependencies: + - c-kzg + + '@nomicfoundation/ethereumjs-rlp@5.0.4': {} + + '@nomicfoundation/ethereumjs-tx@5.0.4': + dependencies: + '@nomicfoundation/ethereumjs-common': 4.0.4 + '@nomicfoundation/ethereumjs-rlp': 5.0.4 + '@nomicfoundation/ethereumjs-util': 9.0.4 + ethereum-cryptography: 0.1.3 + + '@nomicfoundation/ethereumjs-util@9.0.4': + dependencies: + '@nomicfoundation/ethereumjs-rlp': 5.0.4 + ethereum-cryptography: 0.1.3 + + '@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.1': + optional: true + + '@nomicfoundation/solidity-analyzer-darwin-x64@0.1.1': + optional: true + + '@nomicfoundation/solidity-analyzer-freebsd-x64@0.1.1': + optional: true + + '@nomicfoundation/solidity-analyzer-linux-arm64-gnu@0.1.1': + optional: true + + '@nomicfoundation/solidity-analyzer-linux-arm64-musl@0.1.1': + optional: true + + '@nomicfoundation/solidity-analyzer-linux-x64-gnu@0.1.1': + optional: true + + '@nomicfoundation/solidity-analyzer-linux-x64-musl@0.1.1': + optional: true + + '@nomicfoundation/solidity-analyzer-win32-arm64-msvc@0.1.1': + optional: true + + '@nomicfoundation/solidity-analyzer-win32-ia32-msvc@0.1.1': + optional: true + + '@nomicfoundation/solidity-analyzer-win32-x64-msvc@0.1.1': + optional: true + + '@nomicfoundation/solidity-analyzer@0.1.1': + optionalDependencies: + '@nomicfoundation/solidity-analyzer-darwin-arm64': 0.1.1 + '@nomicfoundation/solidity-analyzer-darwin-x64': 0.1.1 + '@nomicfoundation/solidity-analyzer-freebsd-x64': 0.1.1 + '@nomicfoundation/solidity-analyzer-linux-arm64-gnu': 0.1.1 + '@nomicfoundation/solidity-analyzer-linux-arm64-musl': 0.1.1 + '@nomicfoundation/solidity-analyzer-linux-x64-gnu': 0.1.1 + '@nomicfoundation/solidity-analyzer-linux-x64-musl': 0.1.1 + '@nomicfoundation/solidity-analyzer-win32-arm64-msvc': 0.1.1 + '@nomicfoundation/solidity-analyzer-win32-ia32-msvc': 0.1.1 + '@nomicfoundation/solidity-analyzer-win32-x64-msvc': 0.1.1 + + '@nuxt/cli@3.25.1(magicast@0.3.5)': + dependencies: + c12: 3.0.4(magicast@0.3.5) + chokidar: 4.0.3 + citty: 0.1.6 + clipboardy: 4.0.0 + consola: 3.4.2 + defu: 6.1.4 + fuse.js: 7.1.0 + giget: 2.0.0 + h3: 1.15.3 + httpxy: 0.1.7 + jiti: 2.4.2 + listhen: 1.9.0 + nypm: 0.6.0 + ofetch: 1.4.1 + ohash: 2.0.11 + pathe: 2.0.3 + perfect-debounce: 1.0.0 + pkg-types: 2.1.0 + scule: 1.3.0 + semver: 7.7.2 + std-env: 3.9.0 + tinyexec: 1.0.1 + ufo: 1.6.1 + youch: 4.1.0-beta.7 + transitivePeerDependencies: + - magicast + + '@nuxt/devalue@2.0.2': {} + + '@nuxt/devtools-kit@2.4.1(magicast@0.3.5)(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0))': + dependencies: + '@nuxt/kit': 3.17.4(magicast@0.3.5) + '@nuxt/schema': 3.17.4 + execa: 8.0.1 + vite: 6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0) + transitivePeerDependencies: + - magicast + + '@nuxt/devtools-wizard@2.4.1': + dependencies: + consola: 3.4.2 + diff: 7.0.0 + execa: 8.0.1 + magicast: 0.3.5 + pathe: 2.0.3 + pkg-types: 2.1.0 + prompts: 2.4.2 + semver: 7.7.2 + + '@nuxt/devtools@2.4.1(bufferutil@4.0.9)(utf-8-validate@6.0.5)(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.8.3))': + dependencies: + '@nuxt/devtools-kit': 2.4.1(magicast@0.3.5)(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0)) + '@nuxt/devtools-wizard': 2.4.1 + '@nuxt/kit': 3.17.4(magicast@0.3.5) + '@vue/devtools-core': 7.7.6(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.8.3)) + '@vue/devtools-kit': 7.7.6 + birpc: 2.3.0 + consola: 3.4.2 + destr: 2.0.5 + error-stack-parser-es: 1.0.5 + execa: 8.0.1 + fast-npm-meta: 0.4.3 + get-port-please: 3.1.2 + hookable: 5.5.3 + image-meta: 0.2.1 + is-installed-globally: 1.0.0 + launch-editor: 2.10.0 + local-pkg: 1.1.1 + magicast: 0.3.5 + nypm: 0.6.0 + ohash: 2.0.11 + pathe: 2.0.3 + perfect-debounce: 1.0.0 + pkg-types: 2.1.0 + semver: 7.7.2 + simple-git: 3.27.0 + sirv: 3.0.1 + structured-clone-es: 1.0.0 + tinyglobby: 0.2.13 + vite: 6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0) + vite-plugin-inspect: 11.1.0(@nuxt/kit@3.17.4(magicast@0.3.5))(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0)) + vite-plugin-vue-tracer: 0.1.3(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.8.3)) + which: 5.0.0 + ws: 8.18.2(bufferutil@4.0.9)(utf-8-validate@6.0.5) + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + - vue + + '@nuxt/kit@3.16.0(magicast@0.3.5)': + dependencies: + c12: 3.0.4(magicast@0.3.5) + consola: 3.4.2 + defu: 6.1.4 + destr: 2.0.5 + errx: 0.1.0 + exsolve: 1.0.5 + globby: 14.1.0 + ignore: 7.0.4 + jiti: 2.4.2 + klona: 2.0.6 + knitwork: 1.2.0 + mlly: 1.7.4 + ohash: 2.0.11 + pathe: 2.0.3 + pkg-types: 2.1.0 + scule: 1.3.0 + semver: 7.7.2 + std-env: 3.9.0 + ufo: 1.6.1 + unctx: 2.4.1 + unimport: 4.2.0 + untyped: 2.0.0 + transitivePeerDependencies: + - magicast + + '@nuxt/kit@3.17.4(magicast@0.3.5)': + dependencies: + c12: 3.0.4(magicast@0.3.5) + consola: 3.4.2 + defu: 6.1.4 + destr: 2.0.5 + errx: 0.1.0 + exsolve: 1.0.5 + ignore: 7.0.4 + jiti: 2.4.2 + klona: 2.0.6 + knitwork: 1.2.0 + mlly: 1.7.4 + ohash: 2.0.11 + pathe: 2.0.3 + pkg-types: 2.1.0 + scule: 1.3.0 + semver: 7.7.2 + std-env: 3.9.0 + tinyglobby: 0.2.13 + ufo: 1.6.1 + unctx: 2.4.1 + unimport: 5.0.1 + untyped: 2.0.0 + transitivePeerDependencies: + - magicast + + '@nuxt/schema@3.11.2(rollup@4.41.0)': + dependencies: + '@nuxt/ui-templates': 1.3.3 + consola: 3.2.3 + defu: 6.1.4 + hookable: 5.5.3 + pathe: 1.1.2 + pkg-types: 1.1.1 + scule: 1.3.0 + std-env: 3.7.0 + ufo: 1.5.3 + unimport: 3.7.1(rollup@4.41.0) + untyped: 1.4.2 + transitivePeerDependencies: + - rollup + - supports-color + + '@nuxt/schema@3.16.0': + dependencies: + consola: 3.4.2 + defu: 6.1.4 + pathe: 2.0.3 + std-env: 3.9.0 + + '@nuxt/schema@3.17.4': + dependencies: + '@vue/shared': 3.5.14 + consola: 3.4.2 + defu: 6.1.4 + pathe: 2.0.3 + std-env: 3.9.0 + + '@nuxt/telemetry@2.6.6(magicast@0.3.5)': + dependencies: + '@nuxt/kit': 3.17.4(magicast@0.3.5) + citty: 0.1.6 + consola: 3.4.2 + destr: 2.0.5 + dotenv: 16.5.0 + git-url-parse: 16.1.0 + is-docker: 3.0.0 + ofetch: 1.4.1 + package-manager-detector: 1.3.0 + pathe: 2.0.3 + rc9: 2.1.2 + std-env: 3.9.0 + transitivePeerDependencies: + - magicast + + '@nuxt/ui-templates@1.3.3': {} + + '@nuxt/vite-builder@3.16.0(@biomejs/biome@1.9.4)(@types/node@24.0.1)(magicast@0.3.5)(rollup@4.41.0)(terser@5.39.2)(typescript@5.8.3)(vue@3.5.14(typescript@5.8.3))(yaml@2.8.0)': + dependencies: + '@nuxt/kit': 3.16.0(magicast@0.3.5) + '@rollup/plugin-replace': 6.0.2(rollup@4.41.0) + '@vitejs/plugin-vue': 5.2.4(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.8.3)) + '@vitejs/plugin-vue-jsx': 4.2.0(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.8.3)) + autoprefixer: 10.4.21(postcss@8.5.3) + consola: 3.4.2 + cssnano: 7.0.7(postcss@8.5.3) + defu: 6.1.4 + esbuild: 0.25.5 + escape-string-regexp: 5.0.0 + exsolve: 1.0.5 + externality: 1.0.2 + get-port-please: 3.1.2 + h3: 1.15.3 + jiti: 2.4.2 + knitwork: 1.2.0 + magic-string: 0.30.17 + mlly: 1.7.4 + ohash: 2.0.11 + pathe: 2.0.3 + perfect-debounce: 1.0.0 + pkg-types: 2.1.0 + postcss: 8.5.3 + rollup-plugin-visualizer: 5.14.0(rollup@4.41.0) + std-env: 3.9.0 + ufo: 1.6.1 + unenv: 2.0.0-rc.17 + unplugin: 2.3.4 + vite: 6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0) + vite-node: 3.1.4(@types/node@24.0.1)(terser@5.39.2) + vite-plugin-checker: 0.9.3(@biomejs/biome@1.9.4)(typescript@5.8.3)(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0)) + vue: 3.5.14(typescript@5.8.3) + vue-bundle-renderer: 2.1.1 + transitivePeerDependencies: + - '@biomejs/biome' + - '@types/node' + - eslint + - less + - lightningcss + - magicast + - meow + - optionator + - rolldown + - rollup + - sass + - sass-embedded + - stylelint + - stylus + - sugarss + - supports-color + - terser + - tsx + - typescript + - vls + - vti + - vue-tsc + - yaml + + '@one-ini/wasm@0.1.1': {} + + '@open-draft/deferred-promise@2.2.0': {} + + '@open-draft/logger@0.3.0': + dependencies: + is-node-process: 1.2.0 + outvariant: 1.4.3 + + '@open-draft/until@2.1.0': {} + + '@oven/bun-darwin-aarch64@1.1.30': + optional: true + + '@oven/bun-darwin-x64-baseline@1.1.30': + optional: true + + '@oven/bun-darwin-x64@1.1.30': + optional: true + + '@oven/bun-linux-aarch64@1.1.30': + optional: true + + '@oven/bun-linux-x64-baseline@1.1.30': + optional: true + + '@oven/bun-linux-x64@1.1.30': + optional: true + + '@oven/bun-windows-x64-baseline@1.1.30': + optional: true + + '@oven/bun-windows-x64@1.1.30': + optional: true + + '@oxc-parser/binding-darwin-arm64@0.56.5': + optional: true + + '@oxc-parser/binding-darwin-x64@0.56.5': + optional: true + + '@oxc-parser/binding-linux-arm-gnueabihf@0.56.5': + optional: true + + '@oxc-parser/binding-linux-arm64-gnu@0.56.5': + optional: true + + '@oxc-parser/binding-linux-arm64-musl@0.56.5': + optional: true + + '@oxc-parser/binding-linux-x64-gnu@0.56.5': + optional: true + + '@oxc-parser/binding-linux-x64-musl@0.56.5': + optional: true + + '@oxc-parser/binding-wasm32-wasi@0.56.5': + dependencies: + '@napi-rs/wasm-runtime': 0.2.10 + optional: true + + '@oxc-parser/binding-win32-arm64-msvc@0.56.5': + optional: true + + '@oxc-parser/binding-win32-x64-msvc@0.56.5': + optional: true + + '@oxc-parser/wasm@0.56.5': + dependencies: + '@oxc-project/types': 0.56.5 + + '@oxc-project/types@0.56.5': {} + + '@parcel/watcher-android-arm64@2.4.1': + optional: true + + '@parcel/watcher-android-arm64@2.5.1': + optional: true + + '@parcel/watcher-darwin-arm64@2.4.1': + optional: true + + '@parcel/watcher-darwin-arm64@2.5.1': + optional: true + + '@parcel/watcher-darwin-x64@2.4.1': + optional: true + + '@parcel/watcher-darwin-x64@2.5.1': + optional: true + + '@parcel/watcher-freebsd-x64@2.4.1': + optional: true + + '@parcel/watcher-freebsd-x64@2.5.1': + optional: true + + '@parcel/watcher-linux-arm-glibc@2.4.1': + optional: true + + '@parcel/watcher-linux-arm-glibc@2.5.1': + optional: true + + '@parcel/watcher-linux-arm-musl@2.5.1': + optional: true + + '@parcel/watcher-linux-arm64-glibc@2.4.1': + optional: true + + '@parcel/watcher-linux-arm64-glibc@2.5.1': + optional: true + + '@parcel/watcher-linux-arm64-musl@2.4.1': + optional: true + + '@parcel/watcher-linux-arm64-musl@2.5.1': + optional: true + + '@parcel/watcher-linux-x64-glibc@2.4.1': + optional: true + + '@parcel/watcher-linux-x64-glibc@2.5.1': + optional: true + + '@parcel/watcher-linux-x64-musl@2.4.1': + optional: true + + '@parcel/watcher-linux-x64-musl@2.5.1': + optional: true + + '@parcel/watcher-wasm@2.4.1': + dependencies: + is-glob: 4.0.3 + micromatch: 4.0.8 + + '@parcel/watcher-wasm@2.5.1': + dependencies: + is-glob: 4.0.3 + micromatch: 4.0.8 + + '@parcel/watcher-win32-arm64@2.4.1': + optional: true + + '@parcel/watcher-win32-arm64@2.5.1': + optional: true + + '@parcel/watcher-win32-ia32@2.4.1': + optional: true + + '@parcel/watcher-win32-ia32@2.5.1': + optional: true + + '@parcel/watcher-win32-x64@2.4.1': + optional: true + + '@parcel/watcher-win32-x64@2.5.1': + optional: true + + '@parcel/watcher@2.4.1': + dependencies: + detect-libc: 1.0.3 + is-glob: 4.0.3 + micromatch: 4.0.8 + node-addon-api: 7.0.0 + optionalDependencies: + '@parcel/watcher-android-arm64': 2.4.1 + '@parcel/watcher-darwin-arm64': 2.4.1 + '@parcel/watcher-darwin-x64': 2.4.1 + '@parcel/watcher-freebsd-x64': 2.4.1 + '@parcel/watcher-linux-arm-glibc': 2.4.1 + '@parcel/watcher-linux-arm64-glibc': 2.4.1 + '@parcel/watcher-linux-arm64-musl': 2.4.1 + '@parcel/watcher-linux-x64-glibc': 2.4.1 + '@parcel/watcher-linux-x64-musl': 2.4.1 + '@parcel/watcher-win32-arm64': 2.4.1 + '@parcel/watcher-win32-ia32': 2.4.1 + '@parcel/watcher-win32-x64': 2.4.1 + + '@parcel/watcher@2.5.1': + dependencies: + detect-libc: 1.0.3 + is-glob: 4.0.3 + micromatch: 4.0.8 + node-addon-api: 7.1.1 + optionalDependencies: + '@parcel/watcher-android-arm64': 2.5.1 + '@parcel/watcher-darwin-arm64': 2.5.1 + '@parcel/watcher-darwin-x64': 2.5.1 + '@parcel/watcher-freebsd-x64': 2.5.1 + '@parcel/watcher-linux-arm-glibc': 2.5.1 + '@parcel/watcher-linux-arm-musl': 2.5.1 + '@parcel/watcher-linux-arm64-glibc': 2.5.1 + '@parcel/watcher-linux-arm64-musl': 2.5.1 + '@parcel/watcher-linux-x64-glibc': 2.5.1 + '@parcel/watcher-linux-x64-musl': 2.5.1 + '@parcel/watcher-win32-arm64': 2.5.1 + '@parcel/watcher-win32-ia32': 2.5.1 + '@parcel/watcher-win32-x64': 2.5.1 + + '@paulmillr/qr@0.2.1': {} + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@polka/url@1.0.0-next.29': {} + + '@poppinss/colors@4.1.4': + dependencies: + kleur: 4.1.5 + + '@poppinss/dumper@0.6.3': + dependencies: + '@poppinss/colors': 4.1.4 + '@sindresorhus/is': 7.0.1 + supports-color: 10.0.0 + + '@poppinss/exception@1.2.1': {} + + '@publint/pack@0.1.2': {} + + '@reown/appkit-common@1.7.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + dependencies: + big.js: 6.2.2 + dayjs: 1.11.13 + viem: 2.29.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + + '@reown/appkit-common@1.7.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20)': + dependencies: + big.js: 6.2.2 + dayjs: 1.11.13 + viem: 2.29.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + + '@reown/appkit-controllers@1.7.3(@types/react@18.3.1)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20)': + dependencies: + '@reown/appkit-common': 1.7.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@reown/appkit-wallet': 1.7.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) + '@walletconnect/universal-provider': 2.19.2(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + valtio: 1.13.2(@types/react@18.3.1)(react@18.3.1) + viem: 2.29.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/kv' + - bufferutil + - encoding + - ioredis + - react + - typescript + - uWebSockets.js + - utf-8-validate + - zod + + '@reown/appkit-polyfills@1.7.3': + dependencies: + buffer: 6.0.3 + + '@reown/appkit-scaffold-ui@1.7.3(@types/react@18.3.1)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20)': + dependencies: + '@reown/appkit-common': 1.7.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@reown/appkit-controllers': 1.7.3(@types/react@18.3.1)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@reown/appkit-ui': 1.7.3(@types/react@18.3.1)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@reown/appkit-utils': 1.7.3(@types/react@18.3.1)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@reown/appkit-wallet': 1.7.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) + lit: 3.1.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/kv' + - bufferutil + - encoding + - ioredis + - react + - typescript + - uWebSockets.js + - utf-8-validate + - zod + + '@reown/appkit-ui@1.7.3(@types/react@18.3.1)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20)': + dependencies: + '@reown/appkit-common': 1.7.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@reown/appkit-controllers': 1.7.3(@types/react@18.3.1)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@reown/appkit-wallet': 1.7.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) + lit: 3.1.0 + qrcode: 1.5.3 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/kv' + - bufferutil + - encoding + - ioredis + - react + - typescript + - uWebSockets.js + - utf-8-validate + - zod + + '@reown/appkit-utils@1.7.3(@types/react@18.3.1)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20)': + dependencies: + '@reown/appkit-common': 1.7.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@reown/appkit-controllers': 1.7.3(@types/react@18.3.1)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@reown/appkit-polyfills': 1.7.3 + '@reown/appkit-wallet': 1.7.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) + '@walletconnect/logger': 2.1.2 + '@walletconnect/universal-provider': 2.19.2(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + valtio: 1.13.2(@types/react@18.3.1)(react@18.3.1) + viem: 2.29.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/kv' + - bufferutil + - encoding + - ioredis + - react + - typescript + - uWebSockets.js + - utf-8-validate + - zod + + '@reown/appkit-wallet@1.7.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)': + dependencies: + '@reown/appkit-common': 1.7.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@reown/appkit-polyfills': 1.7.3 + '@walletconnect/logger': 2.1.2 + zod: 3.22.4 + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + + '@reown/appkit@1.7.3(@types/react@18.3.1)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20)': + dependencies: + '@reown/appkit-common': 1.7.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@reown/appkit-controllers': 1.7.3(@types/react@18.3.1)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@reown/appkit-polyfills': 1.7.3 + '@reown/appkit-scaffold-ui': 1.7.3(@types/react@18.3.1)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@reown/appkit-ui': 1.7.3(@types/react@18.3.1)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@reown/appkit-utils': 1.7.3(@types/react@18.3.1)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@reown/appkit-wallet': 1.7.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) + '@walletconnect/types': 2.19.2(ioredis@5.6.1) + '@walletconnect/universal-provider': 2.19.2(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + bs58: 6.0.0 + valtio: 1.13.2(@types/react@18.3.1)(react@18.3.1) + viem: 2.29.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/kv' + - bufferutil + - encoding + - ioredis + - react + - typescript + - uWebSockets.js + - utf-8-validate + - zod + + '@rolldown/pluginutils@1.0.0-beta.9': {} + + '@rollup/plugin-alias@5.1.1(rollup@4.41.0)': + optionalDependencies: + rollup: 4.41.0 + + '@rollup/plugin-commonjs@28.0.3(rollup@4.41.0)': + dependencies: + '@rollup/pluginutils': 5.1.4(rollup@4.41.0) + commondir: 1.0.1 + estree-walker: 2.0.2 + fdir: 6.4.4(picomatch@4.0.2) + is-reference: 1.2.1 + magic-string: 0.30.17 + picomatch: 4.0.2 + optionalDependencies: + rollup: 4.41.0 + + '@rollup/plugin-inject@5.0.5(rollup@4.41.0)': + dependencies: + '@rollup/pluginutils': 5.1.4(rollup@4.41.0) + estree-walker: 2.0.2 + magic-string: 0.30.17 + optionalDependencies: + rollup: 4.41.0 + + '@rollup/plugin-json@6.1.0(rollup@4.41.0)': + dependencies: + '@rollup/pluginutils': 5.1.4(rollup@4.41.0) + optionalDependencies: + rollup: 4.41.0 + + '@rollup/plugin-node-resolve@16.0.1(rollup@4.41.0)': + dependencies: + '@rollup/pluginutils': 5.1.4(rollup@4.41.0) + '@types/resolve': 1.20.2 + deepmerge: 4.3.1 + is-module: 1.0.0 + resolve: 1.22.10 + optionalDependencies: + rollup: 4.41.0 + + '@rollup/plugin-replace@6.0.2(rollup@4.41.0)': + dependencies: + '@rollup/pluginutils': 5.1.4(rollup@4.41.0) + magic-string: 0.30.17 + optionalDependencies: + rollup: 4.41.0 + + '@rollup/plugin-terser@0.4.4(rollup@4.41.0)': + dependencies: + serialize-javascript: 6.0.2 + smob: 1.5.0 + terser: 5.39.2 + optionalDependencies: + rollup: 4.41.0 + + '@rollup/pluginutils@5.1.0(rollup@4.41.0)': + dependencies: + '@types/estree': 1.0.5 + estree-walker: 2.0.2 + picomatch: 2.3.1 + optionalDependencies: + rollup: 4.41.0 + + '@rollup/pluginutils@5.1.4(rollup@4.41.0)': + dependencies: + '@types/estree': 1.0.7 + estree-walker: 2.0.2 + picomatch: 4.0.2 + optionalDependencies: + rollup: 4.41.0 + + '@rollup/rollup-android-arm-eabi@4.41.0': + optional: true + + '@rollup/rollup-android-arm64@4.41.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.41.0': + optional: true + + '@rollup/rollup-darwin-x64@4.41.0': + optional: true + + '@rollup/rollup-freebsd-arm64@4.41.0': + optional: true + + '@rollup/rollup-freebsd-x64@4.41.0': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.41.0': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.41.0': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.41.0': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.41.0': + optional: true + + '@rollup/rollup-linux-loongarch64-gnu@4.41.0': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.41.0': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.41.0': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.41.0': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.41.0': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.41.0': + optional: true + + '@rollup/rollup-linux-x64-musl@4.41.0': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.41.0': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.41.0': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.41.0': + optional: true + + '@safe-global/safe-apps-provider@0.18.6(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20)': + dependencies: + '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + events: 3.3.0 + transitivePeerDependencies: + - bufferutil + - encoding + - typescript + - utf-8-validate + - zod + + '@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20)': + dependencies: + '@safe-global/safe-gateway-typescript-sdk': 3.8.0(encoding@0.1.13) + viem: 2.17.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + transitivePeerDependencies: + - bufferutil + - encoding + - typescript + - utf-8-validate + - zod + + '@safe-global/safe-gateway-typescript-sdk@3.8.0(encoding@0.1.13)': + dependencies: + cross-fetch: 3.2.0(encoding@0.1.13) + transitivePeerDependencies: + - encoding + + '@scure/base@1.1.3': {} + + '@scure/base@1.1.9': {} + + '@scure/base@1.2.4': {} + + '@scure/base@1.2.6': {} + + '@scure/bip32@1.1.5': + dependencies: + '@noble/hashes': 1.2.0 + '@noble/secp256k1': 1.7.1 + '@scure/base': 1.1.9 + + '@scure/bip32@1.3.2': + dependencies: + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@scure/base': 1.1.3 + + '@scure/bip32@1.4.0': + dependencies: + '@noble/curves': 1.4.0 + '@noble/hashes': 1.4.0 + '@scure/base': 1.1.9 + + '@scure/bip32@1.6.2': + dependencies: + '@noble/curves': 1.8.2 + '@noble/hashes': 1.7.2 + '@scure/base': 1.2.4 + + '@scure/bip39@1.1.1': + dependencies: + '@noble/hashes': 1.2.0 + '@scure/base': 1.1.9 + + '@scure/bip39@1.2.1': + dependencies: + '@noble/hashes': 1.3.2 + '@scure/base': 1.1.3 + + '@scure/bip39@1.3.0': + dependencies: + '@noble/hashes': 1.4.0 + '@scure/base': 1.1.9 + + '@scure/bip39@1.5.4': + dependencies: + '@noble/hashes': 1.7.2 + '@scure/base': 1.2.4 + + '@sec-ant/readable-stream@0.4.1': {} + + '@sentry/core@5.30.0': + dependencies: + '@sentry/hub': 5.30.0 + '@sentry/minimal': 5.30.0 + '@sentry/types': 5.30.0 + '@sentry/utils': 5.30.0 + tslib: 1.14.1 + + '@sentry/hub@5.30.0': + dependencies: + '@sentry/types': 5.30.0 + '@sentry/utils': 5.30.0 + tslib: 1.14.1 + + '@sentry/minimal@5.30.0': + dependencies: + '@sentry/hub': 5.30.0 + '@sentry/types': 5.30.0 + tslib: 1.14.1 + + '@sentry/node@5.30.0': + dependencies: + '@sentry/core': 5.30.0 + '@sentry/hub': 5.30.0 + '@sentry/tracing': 5.30.0 + '@sentry/types': 5.30.0 + '@sentry/utils': 5.30.0 + cookie: 0.4.2 + https-proxy-agent: 5.0.1 + lru_map: 0.3.3 + tslib: 1.14.1 + transitivePeerDependencies: + - supports-color + + '@sentry/tracing@5.30.0': + dependencies: + '@sentry/hub': 5.30.0 + '@sentry/minimal': 5.30.0 + '@sentry/types': 5.30.0 + '@sentry/utils': 5.30.0 + tslib: 1.14.1 + + '@sentry/types@5.30.0': {} + + '@sentry/utils@5.30.0': + dependencies: + '@sentry/types': 5.30.0 + tslib: 1.14.1 + + '@shikijs/core@1.22.2': + dependencies: + '@shikijs/engine-javascript': 1.22.2 + '@shikijs/engine-oniguruma': 1.22.2 + '@shikijs/types': 1.22.2 + '@shikijs/vscode-textmate': 9.3.0 + '@types/hast': 3.0.4 + hast-util-to-html: 9.0.3 + + '@shikijs/engine-javascript@1.22.2': + dependencies: + '@shikijs/types': 1.22.2 + '@shikijs/vscode-textmate': 9.3.0 + oniguruma-to-js: 0.4.3 + + '@shikijs/engine-oniguruma@1.22.2': + dependencies: + '@shikijs/types': 1.22.2 + '@shikijs/vscode-textmate': 9.3.0 + + '@shikijs/transformers@1.22.2': + dependencies: + shiki: 1.22.2 + + '@shikijs/twoslash@1.22.2(typescript@5.8.3)': + dependencies: + '@shikijs/core': 1.22.2 + '@shikijs/types': 1.22.2 + twoslash: 0.2.12(typescript@5.8.3) + transitivePeerDependencies: + - supports-color + - typescript + + '@shikijs/types@1.22.2': + dependencies: + '@shikijs/vscode-textmate': 9.3.0 + '@types/hast': 3.0.4 + + '@shikijs/vitepress-twoslash@1.22.2(@nuxt/kit@3.17.4(magicast@0.3.5))(typescript@5.8.3)': + dependencies: + '@shikijs/twoslash': 1.22.2(typescript@5.8.3) + floating-vue: 5.2.2(@nuxt/kit@3.17.4(magicast@0.3.5))(vue@3.5.12(typescript@5.8.3)) + mdast-util-from-markdown: 2.0.2 + mdast-util-gfm: 3.0.0 + mdast-util-to-hast: 13.2.0 + shiki: 1.22.2 + twoslash: 0.2.12(typescript@5.8.3) + twoslash-vue: 0.2.12(typescript@5.8.3) + vue: 3.5.12(typescript@5.8.3) + transitivePeerDependencies: + - '@nuxt/kit' + - supports-color + - typescript + + '@shikijs/vscode-textmate@9.3.0': {} + + '@sindresorhus/is@4.6.0': {} + + '@sindresorhus/is@7.0.1': {} + + '@sindresorhus/merge-streams@2.3.0': {} + + '@sindresorhus/merge-streams@4.0.0': {} + + '@snyk/github-codeowners@1.1.0': + dependencies: + commander: 4.1.1 + ignore: 5.3.2 + p-map: 4.0.0 + + '@socket.io/component-emitter@3.1.2': {} + + '@speed-highlight/core@1.2.7': {} + + '@swc/counter@0.1.3': {} + + '@swc/helpers@0.5.15': + dependencies: + tslib: 2.8.1 + + '@tanstack/match-sorter-utils@8.15.1': + dependencies: + remove-accents: 0.5.0 + + '@tanstack/query-core@5.0.5': {} + + '@tanstack/query-core@5.49.1': {} + + '@tanstack/query-devtools@5.0.5': {} + + '@tanstack/query-persist-client-core@5.0.5': + dependencies: + '@tanstack/query-core': 5.0.5 + + '@tanstack/query-sync-storage-persister@5.0.5': + dependencies: + '@tanstack/query-core': 5.0.5 + '@tanstack/query-persist-client-core': 5.0.5 + + '@tanstack/react-query-devtools@5.0.5(@tanstack/react-query@5.49.2(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@tanstack/query-devtools': 5.0.5 + '@tanstack/react-query': 5.49.2(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@tanstack/react-query-persist-client@5.0.5(@tanstack/react-query@5.49.2(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@tanstack/query-persist-client-core': 5.0.5 + '@tanstack/react-query': 5.49.2(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@tanstack/react-query@5.49.2(react@18.3.1)': + dependencies: + '@tanstack/query-core': 5.49.1 + react: 18.3.1 + + '@tanstack/vue-query@5.49.1(vue@3.4.27(typescript@5.8.3))': + dependencies: + '@tanstack/match-sorter-utils': 8.15.1 + '@tanstack/query-core': 5.49.1 + '@vue/devtools-api': 6.6.1 + vue: 3.4.27(typescript@5.8.3) + vue-demi: 0.14.10(vue@3.4.27(typescript@5.8.3)) + + '@testing-library/dom@10.4.0': + dependencies: + '@babel/code-frame': 7.24.2 + '@babel/runtime': 7.26.0 + '@types/aria-query': 5.0.4 + aria-query: 5.3.0 + chalk: 4.1.2 + dom-accessibility-api: 0.5.16 + lz-string: 1.5.0 + pretty-format: 27.5.1 + + '@testing-library/react@16.0.1(@testing-library/dom@10.4.0)(@types/react-dom@18.3.0)(@types/react@18.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.26.0 + '@testing-library/dom': 10.4.0 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.1 + '@types/react-dom': 18.3.0 + + '@trysound/sax@0.2.0': {} + + '@tybys/wasm-util@0.9.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/aria-query@5.0.4': {} + + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.24.5 + '@babel/types': 7.24.5 + '@types/babel__generator': 7.6.5 + '@types/babel__template': 7.4.2 + '@types/babel__traverse': 7.20.2 + + '@types/babel__generator@7.6.5': + dependencies: + '@babel/types': 7.27.1 + + '@types/babel__template@7.4.2': + dependencies: + '@babel/parser': 7.26.2 + '@babel/types': 7.27.1 + + '@types/babel__traverse@7.20.2': + dependencies: + '@babel/types': 7.27.1 + + '@types/bn.js@4.11.6': + dependencies: + '@types/node': 24.0.1 + + '@types/bn.js@5.1.5': + dependencies: + '@types/node': 24.0.1 + + '@types/bun@1.1.10': + dependencies: + bun-types: 1.1.29 + + '@types/cookie@0.6.0': {} + + '@types/cross-spawn@6.0.6': + dependencies: + '@types/node': 20.12.10 + + '@types/debug@4.1.12': + dependencies: + '@types/ms': 2.1.0 + + '@types/debug@4.1.7': + dependencies: + '@types/ms': 0.7.31 + + '@types/dedent@0.7.2': {} + + '@types/estree@1.0.5': {} + + '@types/estree@1.0.7': {} + + '@types/hast@3.0.4': + dependencies: + '@types/unist': 3.0.2 + + '@types/linkify-it@5.0.0': {} + + '@types/lru-cache@5.1.1': {} + + '@types/markdown-it@14.1.2': + dependencies: + '@types/linkify-it': 5.0.0 + '@types/mdurl': 2.0.0 + + '@types/mdast@4.0.3': + dependencies: + '@types/unist': 3.0.2 + + '@types/mdurl@2.0.0': {} + + '@types/ms@0.7.31': {} + + '@types/ms@2.1.0': {} + + '@types/mute-stream@0.0.4': + dependencies: + '@types/node': 22.15.31 + + '@types/node@12.20.55': {} + + '@types/node@20.12.10': + dependencies: + undici-types: 5.26.5 + + '@types/node@20.12.14': + dependencies: + undici-types: 5.26.5 + + '@types/node@20.19.0': + dependencies: + undici-types: 6.21.0 + + '@types/node@22.15.31': + dependencies: + undici-types: 6.21.0 + + '@types/node@24.0.1': + dependencies: + undici-types: 7.8.0 + + '@types/normalize-package-data@2.4.4': {} + + '@types/parse-path@7.1.0': + dependencies: + parse-path: 7.1.0 + + '@types/pbkdf2@3.1.2': + dependencies: + '@types/node': 24.0.1 + + '@types/prompts@2.4.9': + dependencies: + '@types/node': 20.12.10 + kleur: 3.0.3 + + '@types/prop-types@15.7.5': {} + + '@types/react-dom@18.3.0': + dependencies: + '@types/react': 18.3.1 + + '@types/react@18.3.1': + dependencies: + '@types/prop-types': 15.7.5 + csstype: 3.1.3 + + '@types/resolve@1.20.2': {} + + '@types/secp256k1@4.0.3': + dependencies: + '@types/node': 24.0.1 + + '@types/semver@7.5.3': {} + + '@types/statuses@2.0.4': {} + + '@types/tough-cookie@4.0.5': {} + + '@types/triple-beam@1.3.5': {} + + '@types/trusted-types@2.0.3': {} + + '@types/unist@3.0.2': {} + + '@types/use-sync-external-store@0.0.6': {} + + '@types/web-bluetooth@0.0.20': {} + + '@types/wrap-ansi@3.0.0': {} + + '@types/ws@8.5.10': + dependencies: + '@types/node': 20.12.14 + + '@types/yauzl@2.10.3': + dependencies: + '@types/node': 24.0.1 + optional: true + + '@typescript-eslint/types@5.62.0': {} + + '@typescript-eslint/typescript-estree@5.62.0(typescript@5.8.3)': + dependencies: + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/visitor-keys': 5.62.0 + debug: 4.4.1 + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.7.2 + tsutils: 3.21.0(typescript@5.8.3) + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@5.62.0': + dependencies: + '@typescript-eslint/types': 5.62.0 + eslint-visitor-keys: 3.4.3 + + '@typescript/vfs@1.6.0(typescript@5.8.3)': + dependencies: + debug: 4.4.1 + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@ungap/structured-clone@1.2.0': {} + + '@unhead/vue@2.0.9(vue@3.5.14(typescript@5.8.3))': + dependencies: + hookable: 5.5.3 + unhead: 2.0.9 + vue: 3.5.14(typescript@5.8.3) + + '@unocss/astro@0.59.4(rollup@4.41.0)': + dependencies: + '@unocss/core': 0.59.4 + '@unocss/reset': 0.59.4 + '@unocss/vite': 0.59.4(rollup@4.41.0) + transitivePeerDependencies: + - rollup + + '@unocss/cli@0.59.4(rollup@4.41.0)': + dependencies: + '@ampproject/remapping': 2.3.0 + '@rollup/pluginutils': 5.1.0(rollup@4.41.0) + '@unocss/config': 0.59.4 + '@unocss/core': 0.59.4 + '@unocss/preset-uno': 0.59.4 + cac: 6.7.14 + chokidar: 3.6.0 + colorette: 2.0.20 + consola: 3.4.2 + fast-glob: 3.3.2 + magic-string: 0.30.17 + pathe: 1.1.2 + perfect-debounce: 1.0.0 + transitivePeerDependencies: + - rollup + + '@unocss/config@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + unconfig: 0.3.13 + + '@unocss/core@0.59.4': {} + + '@unocss/extractor-arbitrary-variants@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + + '@unocss/inspector@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + '@unocss/rule-utils': 0.59.4 + gzip-size: 6.0.0 + sirv: 2.0.4 + + '@unocss/postcss@0.59.4': + dependencies: + '@unocss/config': 0.59.4 + '@unocss/core': 0.59.4 + '@unocss/rule-utils': 0.59.4 + css-tree: 2.3.1 + fast-glob: 3.3.2 + magic-string: 0.30.17 + postcss: 8.5.5 + + '@unocss/preset-attributify@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + + '@unocss/preset-icons@0.59.4': + dependencies: + '@iconify/utils': 2.1.23 + '@unocss/core': 0.59.4 + ofetch: 1.4.1 + transitivePeerDependencies: + - supports-color + + '@unocss/preset-mini@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + '@unocss/extractor-arbitrary-variants': 0.59.4 + '@unocss/rule-utils': 0.59.4 + + '@unocss/preset-tagify@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + + '@unocss/preset-typography@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + '@unocss/preset-mini': 0.59.4 + + '@unocss/preset-uno@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + '@unocss/preset-mini': 0.59.4 + '@unocss/preset-wind': 0.59.4 + '@unocss/rule-utils': 0.59.4 + + '@unocss/preset-web-fonts@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + ofetch: 1.4.1 + + '@unocss/preset-wind@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + '@unocss/preset-mini': 0.59.4 + '@unocss/rule-utils': 0.59.4 + + '@unocss/reset@0.59.4': {} + + '@unocss/rule-utils@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + magic-string: 0.30.17 + + '@unocss/scope@0.59.4': {} + + '@unocss/transformer-attributify-jsx-babel@0.59.4': + dependencies: + '@babel/core': 7.24.5 + '@babel/plugin-syntax-jsx': 7.24.1(@babel/core@7.24.5) + '@babel/preset-typescript': 7.24.1(@babel/core@7.24.5) + '@unocss/core': 0.59.4 + transitivePeerDependencies: + - supports-color + + '@unocss/transformer-attributify-jsx@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + + '@unocss/transformer-compile-class@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + + '@unocss/transformer-directives@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + '@unocss/rule-utils': 0.59.4 + css-tree: 2.3.1 + + '@unocss/transformer-variant-group@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + + '@unocss/vite@0.59.4(rollup@4.41.0)': + dependencies: + '@ampproject/remapping': 2.3.0 + '@rollup/pluginutils': 5.1.0(rollup@4.41.0) + '@unocss/config': 0.59.4 + '@unocss/core': 0.59.4 + '@unocss/inspector': 0.59.4 + '@unocss/scope': 0.59.4 + '@unocss/transformer-directives': 0.59.4 + chokidar: 3.6.0 + fast-glob: 3.3.2 + magic-string: 0.30.17 + transitivePeerDependencies: + - rollup + + '@vercel/nft@0.27.7(encoding@0.1.13)(rollup@4.41.0)': + dependencies: + '@mapbox/node-pre-gyp': 1.0.11(encoding@0.1.13) + '@rollup/pluginutils': 5.1.4(rollup@4.41.0) + acorn: 8.15.0 + acorn-import-attributes: 1.9.5(acorn@8.15.0) + async-sema: 3.1.1 + bindings: 1.5.0 + estree-walker: 2.0.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + micromatch: 4.0.8 + node-gyp-build: 4.8.4 + resolve-from: 5.0.0 + transitivePeerDependencies: + - encoding + - rollup + - supports-color + + '@vercel/nft@0.29.3(encoding@0.1.13)(rollup@4.41.0)': + dependencies: + '@mapbox/node-pre-gyp': 2.0.0(encoding@0.1.13) + '@rollup/pluginutils': 5.1.4(rollup@4.41.0) + acorn: 8.14.1 + acorn-import-attributes: 1.9.5(acorn@8.14.1) + async-sema: 3.1.1 + bindings: 1.5.0 + estree-walker: 2.0.2 + glob: 10.4.5 + graceful-fs: 4.2.11 + node-gyp-build: 4.8.4 + picomatch: 4.0.2 + resolve-from: 5.0.0 + transitivePeerDependencies: + - encoding + - rollup + - supports-color + + '@vitejs/plugin-react@4.2.1(vite@5.4.19(@types/node@24.0.1)(terser@5.39.2))': + dependencies: + '@babel/core': 7.24.5 + '@babel/plugin-transform-react-jsx-self': 7.24.5(@babel/core@7.24.5) + '@babel/plugin-transform-react-jsx-source': 7.24.1(@babel/core@7.24.5) + '@types/babel__core': 7.20.5 + react-refresh: 0.14.0 + vite: 5.4.19(@types/node@24.0.1)(terser@5.39.2) + transitivePeerDependencies: + - supports-color + + '@vitejs/plugin-vue-jsx@4.2.0(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.8.3))': + dependencies: + '@babel/core': 7.27.1 + '@babel/plugin-transform-typescript': 7.27.1(@babel/core@7.27.1) + '@rolldown/pluginutils': 1.0.0-beta.9 + '@vue/babel-plugin-jsx': 1.4.0(@babel/core@7.27.1) + vite: 6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0) + vue: 3.5.14(typescript@5.8.3) + transitivePeerDependencies: + - supports-color + + '@vitejs/plugin-vue@5.0.4(vite@5.4.19(@types/node@24.0.1)(terser@5.39.2))(vue@3.4.27(typescript@5.8.3))': + dependencies: + vite: 5.4.19(@types/node@24.0.1)(terser@5.39.2) + vue: 3.4.27(typescript@5.8.3) + + '@vitejs/plugin-vue@5.1.4(vite@5.4.19(@types/node@24.0.1)(terser@5.39.2))(vue@3.5.12(typescript@5.8.3))': + dependencies: + vite: 5.4.19(@types/node@24.0.1)(terser@5.39.2) + vue: 3.5.12(typescript@5.8.3) + + '@vitejs/plugin-vue@5.2.4(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.8.3))': + dependencies: + vite: 6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0) + vue: 3.5.14(typescript@5.8.3) + + '@vitest/coverage-v8@2.1.1(vitest@2.1.9(@types/node@24.0.1)(happy-dom@15.10.2)(msw@2.4.9(typescript@5.8.3))(terser@5.39.2))': + dependencies: + '@ampproject/remapping': 2.3.0 + '@bcoe/v8-coverage': 0.2.3 + debug: 4.3.7 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 5.0.6 + istanbul-reports: 3.1.7 + magic-string: 0.30.11 + magicast: 0.3.4 + std-env: 3.7.0 + test-exclude: 7.0.1 + tinyrainbow: 1.2.0 + vitest: 2.1.9(@types/node@24.0.1)(happy-dom@15.10.2)(msw@2.4.9(typescript@5.8.3))(terser@5.39.2) + transitivePeerDependencies: + - supports-color + + '@vitest/expect@2.1.9': + dependencies: + '@vitest/spy': 2.1.9 + '@vitest/utils': 2.1.9 + chai: 5.2.0 + tinyrainbow: 1.2.0 + + '@vitest/mocker@2.1.9(msw@2.4.9(typescript@5.8.3))(vite@5.4.19(@types/node@24.0.1)(terser@5.39.2))': + dependencies: + '@vitest/spy': 2.1.9 + estree-walker: 3.0.3 + magic-string: 0.30.17 + optionalDependencies: + msw: 2.4.9(typescript@5.8.3) + vite: 5.4.19(@types/node@24.0.1)(terser@5.39.2) + + '@vitest/pretty-format@2.1.9': + dependencies: + tinyrainbow: 1.2.0 + + '@vitest/runner@2.1.9': + dependencies: + '@vitest/utils': 2.1.9 + pathe: 1.1.2 + + '@vitest/snapshot@2.1.9': + dependencies: + '@vitest/pretty-format': 2.1.9 + magic-string: 0.30.17 + pathe: 1.1.2 + + '@vitest/spy@2.1.9': + dependencies: + tinyspy: 3.0.2 + + '@vitest/utils@2.1.9': + dependencies: + '@vitest/pretty-format': 2.1.9 + loupe: 3.1.3 + tinyrainbow: 1.2.0 + + '@volar/language-core@2.2.1': + dependencies: + '@volar/source-map': 2.2.1 + + '@volar/language-core@2.4.8': + dependencies: + '@volar/source-map': 2.4.8 + + '@volar/source-map@2.2.1': + dependencies: + muggle-string: 0.4.1 + + '@volar/source-map@2.4.8': {} + + '@volar/typescript@2.2.1': + dependencies: + '@volar/language-core': 2.2.1 + path-browserify: 1.0.1 + + '@vue-macros/common@1.16.1(vue@3.5.14(typescript@5.8.3))': + dependencies: + '@vue/compiler-sfc': 3.5.14 + ast-kit: 1.4.3 + local-pkg: 1.1.1 + magic-string-ast: 0.7.1 + pathe: 2.0.3 + picomatch: 4.0.2 + optionalDependencies: + vue: 3.5.14(typescript@5.8.3) + + '@vue/babel-helper-vue-transform-on@1.4.0': {} + + '@vue/babel-plugin-jsx@1.4.0(@babel/core@7.27.1)': + dependencies: + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.27.1) + '@babel/template': 7.27.2 + '@babel/traverse': 7.27.1 + '@babel/types': 7.27.1 + '@vue/babel-helper-vue-transform-on': 1.4.0 + '@vue/babel-plugin-resolve-type': 1.4.0(@babel/core@7.27.1) + '@vue/shared': 3.5.14 + optionalDependencies: + '@babel/core': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@vue/babel-plugin-resolve-type@1.4.0(@babel/core@7.27.1)': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/core': 7.27.1 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/parser': 7.27.2 + '@vue/compiler-sfc': 3.5.14 + transitivePeerDependencies: + - supports-color + + '@vue/compiler-core@3.4.27': + dependencies: + '@babel/parser': 7.26.2 + '@vue/shared': 3.4.27 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + + '@vue/compiler-core@3.5.12': + dependencies: + '@babel/parser': 7.27.2 + '@vue/shared': 3.5.12 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + + '@vue/compiler-core@3.5.14': + dependencies: + '@babel/parser': 7.27.2 + '@vue/shared': 3.5.14 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + + '@vue/compiler-dom@3.4.27': + dependencies: + '@vue/compiler-core': 3.4.27 + '@vue/shared': 3.4.27 + + '@vue/compiler-dom@3.5.12': + dependencies: + '@vue/compiler-core': 3.5.12 + '@vue/shared': 3.5.12 + + '@vue/compiler-dom@3.5.14': + dependencies: + '@vue/compiler-core': 3.5.14 + '@vue/shared': 3.5.14 + + '@vue/compiler-sfc@3.4.27': + dependencies: + '@babel/parser': 7.26.2 + '@vue/compiler-core': 3.4.27 + '@vue/compiler-dom': 3.4.27 + '@vue/compiler-ssr': 3.4.27 + '@vue/shared': 3.4.27 + estree-walker: 2.0.2 + magic-string: 0.30.12 + postcss: 8.4.47 + source-map-js: 1.2.1 + + '@vue/compiler-sfc@3.5.12': + dependencies: + '@babel/parser': 7.26.2 + '@vue/compiler-core': 3.5.12 + '@vue/compiler-dom': 3.5.12 + '@vue/compiler-ssr': 3.5.12 + '@vue/shared': 3.5.12 + estree-walker: 2.0.2 + magic-string: 0.30.17 + postcss: 8.5.5 + source-map-js: 1.2.1 + + '@vue/compiler-sfc@3.5.14': + dependencies: + '@babel/parser': 7.27.2 + '@vue/compiler-core': 3.5.14 + '@vue/compiler-dom': 3.5.14 + '@vue/compiler-ssr': 3.5.14 + '@vue/shared': 3.5.14 + estree-walker: 2.0.2 + magic-string: 0.30.17 + postcss: 8.5.5 + source-map-js: 1.2.1 + + '@vue/compiler-ssr@3.4.27': + dependencies: + '@vue/compiler-dom': 3.4.27 + '@vue/shared': 3.4.27 + + '@vue/compiler-ssr@3.5.12': + dependencies: + '@vue/compiler-dom': 3.5.12 + '@vue/shared': 3.5.12 + + '@vue/compiler-ssr@3.5.14': + dependencies: + '@vue/compiler-dom': 3.5.14 + '@vue/shared': 3.5.14 + + '@vue/compiler-vue2@2.7.16': + dependencies: + de-indent: 1.0.2 + he: 1.2.0 + + '@vue/devtools-api@6.6.1': {} + + '@vue/devtools-api@6.6.4': {} + + '@vue/devtools-api@7.6.2': + dependencies: + '@vue/devtools-kit': 7.6.2 + + '@vue/devtools-core@7.7.6(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.8.3))': + dependencies: + '@vue/devtools-kit': 7.7.6 + '@vue/devtools-shared': 7.7.6 + mitt: 3.0.1 + nanoid: 5.1.5 + pathe: 2.0.3 + vite-hot-client: 2.0.4(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0)) + vue: 3.5.14(typescript@5.8.3) + transitivePeerDependencies: + - vite + + '@vue/devtools-kit@7.6.2': + dependencies: + '@vue/devtools-shared': 7.6.2 + birpc: 0.2.19 + hookable: 5.5.3 + mitt: 3.0.1 + perfect-debounce: 1.0.0 + speakingurl: 14.0.1 + superjson: 2.2.1 + + '@vue/devtools-kit@7.7.6': + dependencies: + '@vue/devtools-shared': 7.7.6 + birpc: 2.3.0 + hookable: 5.5.3 + mitt: 3.0.1 + perfect-debounce: 1.0.0 + speakingurl: 14.0.1 + superjson: 2.2.2 + + '@vue/devtools-shared@7.6.2': + dependencies: + rfdc: 1.4.1 + + '@vue/devtools-shared@7.7.6': + dependencies: + rfdc: 1.4.1 + + '@vue/language-core@2.0.16(typescript@5.8.3)': + dependencies: + '@volar/language-core': 2.2.1 + '@vue/compiler-dom': 3.5.12 + '@vue/shared': 3.5.14 + computeds: 0.0.1 + minimatch: 9.0.4 + path-browserify: 1.0.1 + vue-template-compiler: 2.7.16 + optionalDependencies: + typescript: 5.8.3 + + '@vue/language-core@2.1.10(typescript@5.8.3)': + dependencies: + '@volar/language-core': 2.4.8 + '@vue/compiler-dom': 3.5.14 + '@vue/compiler-vue2': 2.7.16 + '@vue/shared': 3.5.14 + alien-signals: 0.2.0 + minimatch: 9.0.4 + muggle-string: 0.4.1 + path-browserify: 1.0.1 + optionalDependencies: + typescript: 5.8.3 + + '@vue/reactivity@3.4.27': + dependencies: + '@vue/shared': 3.4.27 + + '@vue/reactivity@3.5.12': + dependencies: + '@vue/shared': 3.5.12 + + '@vue/reactivity@3.5.14': + dependencies: + '@vue/shared': 3.5.14 + + '@vue/runtime-core@3.4.27': + dependencies: + '@vue/reactivity': 3.4.27 + '@vue/shared': 3.4.27 + + '@vue/runtime-core@3.5.12': + dependencies: + '@vue/reactivity': 3.5.12 + '@vue/shared': 3.5.12 + + '@vue/runtime-core@3.5.14': + dependencies: + '@vue/reactivity': 3.5.14 + '@vue/shared': 3.5.14 + + '@vue/runtime-dom@3.4.27': + dependencies: + '@vue/runtime-core': 3.4.27 + '@vue/shared': 3.4.27 + csstype: 3.1.3 + + '@vue/runtime-dom@3.5.12': + dependencies: + '@vue/reactivity': 3.5.12 + '@vue/runtime-core': 3.5.12 + '@vue/shared': 3.5.12 + csstype: 3.1.3 + + '@vue/runtime-dom@3.5.14': + dependencies: + '@vue/reactivity': 3.5.14 + '@vue/runtime-core': 3.5.14 + '@vue/shared': 3.5.14 + csstype: 3.1.3 + + '@vue/server-renderer@3.4.27(vue@3.4.27(typescript@5.8.3))': + dependencies: + '@vue/compiler-ssr': 3.4.27 + '@vue/shared': 3.4.27 + vue: 3.4.27(typescript@5.8.3) + + '@vue/server-renderer@3.5.12(vue@3.5.12(typescript@5.8.3))': + dependencies: + '@vue/compiler-ssr': 3.5.12 + '@vue/shared': 3.5.12 + vue: 3.5.12(typescript@5.8.3) + + '@vue/server-renderer@3.5.14(vue@3.5.14(typescript@5.8.3))': + dependencies: + '@vue/compiler-ssr': 3.5.14 + '@vue/shared': 3.5.14 + vue: 3.5.14(typescript@5.8.3) + + '@vue/shared@3.4.27': {} + + '@vue/shared@3.5.12': {} + + '@vue/shared@3.5.14': {} + + '@vue/test-utils@2.4.6': + dependencies: + js-beautify: 1.15.1 + vue-component-type-helpers: 2.0.16 + + '@vueuse/core@11.2.0(vue@3.5.12(typescript@5.8.3))': + dependencies: + '@types/web-bluetooth': 0.0.20 + '@vueuse/metadata': 11.2.0 + '@vueuse/shared': 11.2.0(vue@3.5.12(typescript@5.8.3)) + vue-demi: 0.14.10(vue@3.5.12(typescript@5.8.3)) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@vueuse/integrations@11.2.0(change-case@5.4.4)(focus-trap@7.6.0)(fuse.js@7.1.0)(idb-keyval@6.2.1)(jwt-decode@4.0.0)(qrcode@1.5.3)(vue@3.5.12(typescript@5.8.3))': + dependencies: + '@vueuse/core': 11.2.0(vue@3.5.12(typescript@5.8.3)) + '@vueuse/shared': 11.2.0(vue@3.5.12(typescript@5.8.3)) + vue-demi: 0.14.10(vue@3.5.12(typescript@5.8.3)) + optionalDependencies: + change-case: 5.4.4 + focus-trap: 7.6.0 + fuse.js: 7.1.0 + idb-keyval: 6.2.1 + jwt-decode: 4.0.0 + qrcode: 1.5.3 + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@vueuse/metadata@11.2.0': {} + + '@vueuse/shared@11.2.0(vue@3.5.12(typescript@5.8.3))': + dependencies: + vue-demi: 0.14.10(vue@3.5.12(typescript@5.8.3)) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@walletconnect/core@2.19.2(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20)': + dependencies: + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/jsonrpc-ws-connection': 1.0.16(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@walletconnect/keyvaluestorage': 1.1.1(ioredis@5.6.1) + '@walletconnect/logger': 2.1.2 + '@walletconnect/relay-api': 1.0.11 + '@walletconnect/relay-auth': 1.1.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.19.2(ioredis@5.6.1) + '@walletconnect/utils': 2.19.2(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@walletconnect/window-getters': 1.0.1 + es-toolkit: 1.33.0 + events: 3.3.0 + uint8arrays: 3.1.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/kv' + - bufferutil + - ioredis + - typescript + - uWebSockets.js + - utf-8-validate + - zod + + '@walletconnect/core@2.20.2(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20)': + dependencies: + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/jsonrpc-ws-connection': 1.0.16(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@walletconnect/keyvaluestorage': 1.1.1(ioredis@5.6.1) + '@walletconnect/logger': 2.1.2 + '@walletconnect/relay-api': 1.0.11 + '@walletconnect/relay-auth': 1.1.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.20.2(ioredis@5.6.1) + '@walletconnect/utils': 2.20.2(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@walletconnect/window-getters': 1.0.1 + es-toolkit: 1.33.0 + events: 3.3.0 + uint8arrays: 3.1.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/kv' + - bufferutil + - ioredis + - typescript + - uWebSockets.js + - utf-8-validate + - zod + + '@walletconnect/environment@1.0.1': + dependencies: + tslib: 1.14.1 + + '@walletconnect/ethereum-provider@2.20.2(@types/react@18.3.1)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20)': + dependencies: + '@reown/appkit': 1.7.3(@types/react@18.3.1)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(react@18.3.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@walletconnect/jsonrpc-http-connection': 1.0.8(encoding@0.1.13) + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1(ioredis@5.6.1) + '@walletconnect/sign-client': 2.20.2(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@walletconnect/types': 2.20.2(ioredis@5.6.1) + '@walletconnect/universal-provider': 2.20.2(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@walletconnect/utils': 2.20.2(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/kv' + - bufferutil + - encoding + - ioredis + - react + - typescript + - uWebSockets.js + - utf-8-validate + - zod + + '@walletconnect/events@1.0.1': + dependencies: + keyvaluestorage-interface: 1.0.0 + tslib: 1.14.1 + + '@walletconnect/heartbeat@1.2.2': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/time': 1.0.2 + events: 3.3.0 + + '@walletconnect/jsonrpc-http-connection@1.0.8(encoding@0.1.13)': + dependencies: + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/safe-json': 1.0.2 + cross-fetch: 3.1.5(encoding@0.1.13) + events: 3.3.0 + transitivePeerDependencies: + - encoding + + '@walletconnect/jsonrpc-provider@1.0.14': + dependencies: + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/safe-json': 1.0.2 + events: 3.3.0 + + '@walletconnect/jsonrpc-types@1.0.4': + dependencies: + events: 3.3.0 + keyvaluestorage-interface: 1.0.0 + + '@walletconnect/jsonrpc-utils@1.0.8': + dependencies: + '@walletconnect/environment': 1.0.1 + '@walletconnect/jsonrpc-types': 1.0.4 + tslib: 1.14.1 + + '@walletconnect/jsonrpc-ws-connection@1.0.16(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/safe-json': 1.0.2 + events: 3.3.0 + ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@walletconnect/keyvaluestorage@1.1.1(ioredis@5.6.1)': + dependencies: + '@walletconnect/safe-json': 1.0.2 + idb-keyval: 6.2.1 + unstorage: 1.10.2(idb-keyval@6.2.1)(ioredis@5.6.1) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@upstash/redis' + - '@vercel/kv' + - ioredis + - uWebSockets.js + + '@walletconnect/logger@2.1.2': + dependencies: + '@walletconnect/safe-json': 1.0.2 + pino: 7.11.0 + + '@walletconnect/relay-api@1.0.11': + dependencies: + '@walletconnect/jsonrpc-types': 1.0.4 + + '@walletconnect/relay-auth@1.1.0': + dependencies: + '@noble/curves': 1.8.0 + '@noble/hashes': 1.7.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + uint8arrays: 3.1.1 + + '@walletconnect/safe-json@1.0.2': + dependencies: + tslib: 1.14.1 + + '@walletconnect/sign-client@2.19.2(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20)': + dependencies: + '@walletconnect/core': 2.19.2(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/logger': 2.1.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.19.2(ioredis@5.6.1) + '@walletconnect/utils': 2.19.2(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/kv' + - bufferutil + - ioredis + - typescript + - uWebSockets.js + - utf-8-validate + - zod + + '@walletconnect/sign-client@2.20.2(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20)': + dependencies: + '@walletconnect/core': 2.20.2(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/logger': 2.1.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.20.2(ioredis@5.6.1) + '@walletconnect/utils': 2.20.2(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/kv' + - bufferutil + - ioredis + - typescript + - uWebSockets.js + - utf-8-validate + - zod + + '@walletconnect/time@1.0.2': + dependencies: + tslib: 1.14.1 + + '@walletconnect/types@2.19.2(ioredis@5.6.1)': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/keyvaluestorage': 1.1.1(ioredis@5.6.1) + '@walletconnect/logger': 2.1.2 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/kv' + - ioredis + - uWebSockets.js + + '@walletconnect/types@2.20.2(ioredis@5.6.1)': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/keyvaluestorage': 1.1.1(ioredis@5.6.1) + '@walletconnect/logger': 2.1.2 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/kv' + - ioredis + - uWebSockets.js + + '@walletconnect/universal-provider@2.19.2(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20)': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/jsonrpc-http-connection': 1.0.8(encoding@0.1.13) + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1(ioredis@5.6.1) + '@walletconnect/logger': 2.1.2 + '@walletconnect/sign-client': 2.19.2(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@walletconnect/types': 2.19.2(ioredis@5.6.1) + '@walletconnect/utils': 2.19.2(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + es-toolkit: 1.33.0 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/kv' + - bufferutil + - encoding + - ioredis + - typescript + - uWebSockets.js + - utf-8-validate + - zod + + '@walletconnect/universal-provider@2.20.2(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20)': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/jsonrpc-http-connection': 1.0.8(encoding@0.1.13) + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1(ioredis@5.6.1) + '@walletconnect/logger': 2.1.2 + '@walletconnect/sign-client': 2.20.2(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + '@walletconnect/types': 2.20.2(ioredis@5.6.1) + '@walletconnect/utils': 2.20.2(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + es-toolkit: 1.33.0 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/kv' + - bufferutil + - encoding + - ioredis + - typescript + - uWebSockets.js + - utf-8-validate + - zod + + '@walletconnect/utils@2.19.2(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20)': + dependencies: + '@noble/ciphers': 1.2.1 + '@noble/curves': 1.8.1 + '@noble/hashes': 1.7.1 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1(ioredis@5.6.1) + '@walletconnect/relay-api': 1.0.11 + '@walletconnect/relay-auth': 1.1.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.19.2(ioredis@5.6.1) + '@walletconnect/window-getters': 1.0.1 + '@walletconnect/window-metadata': 1.0.1 + bs58: 6.0.0 + detect-browser: 5.3.0 + query-string: 7.1.3 + uint8arrays: 3.1.0 + viem: 2.23.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/kv' + - bufferutil + - ioredis + - typescript + - uWebSockets.js + - utf-8-validate + - zod + + '@walletconnect/utils@2.20.2(bufferutil@4.0.9)(ioredis@5.6.1)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20)': + dependencies: + '@noble/ciphers': 1.2.1 + '@noble/curves': 1.8.1 + '@noble/hashes': 1.7.1 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1(ioredis@5.6.1) + '@walletconnect/relay-api': 1.0.11 + '@walletconnect/relay-auth': 1.1.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.20.2(ioredis@5.6.1) + '@walletconnect/window-getters': 1.0.1 + '@walletconnect/window-metadata': 1.0.1 + bs58: 6.0.0 + detect-browser: 5.3.0 + query-string: 7.1.3 + uint8arrays: 3.1.0 + viem: 2.23.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/kv' + - bufferutil + - ioredis + - typescript + - uWebSockets.js + - utf-8-validate + - zod + + '@walletconnect/window-getters@1.0.1': + dependencies: + tslib: 1.14.1 + + '@walletconnect/window-metadata@1.0.1': + dependencies: + '@walletconnect/window-getters': 1.0.1 + tslib: 1.14.1 + + '@whatwg-node/disposablestack@0.0.6': + dependencies: + '@whatwg-node/promise-helpers': 1.3.2 + tslib: 2.8.1 + + '@whatwg-node/fetch@0.10.8': + dependencies: + '@whatwg-node/node-fetch': 0.7.21 + urlpattern-polyfill: 10.1.0 + + '@whatwg-node/node-fetch@0.7.21': + dependencies: + '@fastify/busboy': 3.1.1 + '@whatwg-node/disposablestack': 0.0.6 + '@whatwg-node/promise-helpers': 1.3.2 + tslib: 2.8.1 + + '@whatwg-node/promise-helpers@1.3.2': + dependencies: + tslib: 2.8.1 + + '@whatwg-node/server@0.9.71': + dependencies: + '@whatwg-node/disposablestack': 0.0.6 + '@whatwg-node/fetch': 0.10.8 + '@whatwg-node/promise-helpers': 1.3.2 + tslib: 2.8.1 + + abbrev@1.1.1: {} + + abbrev@2.0.0: {} + + abbrev@3.0.1: {} + + abitype@1.0.0(typescript@5.8.3)(zod@3.25.20): + optionalDependencies: + typescript: 5.8.3 + zod: 3.25.20 + + abitype@1.0.2(typescript@5.8.3)(zod@3.25.20): + optionalDependencies: + typescript: 5.8.3 + zod: 3.25.20 + + abitype@1.0.4(typescript@5.8.3)(zod@3.25.20): + optionalDependencies: + typescript: 5.8.3 + zod: 3.25.20 + + abitype@1.0.5(typescript@5.8.3)(zod@3.25.20): + optionalDependencies: + typescript: 5.8.3 + zod: 3.25.20 + + abitype@1.0.8(typescript@5.8.3)(zod@3.22.4): + optionalDependencies: + typescript: 5.8.3 + zod: 3.22.4 + + abitype@1.0.8(typescript@5.8.3)(zod@3.25.20): + optionalDependencies: + typescript: 5.8.3 + zod: 3.25.20 + + abort-controller@3.0.0: + dependencies: + event-target-shim: 5.0.1 + + acorn-import-attributes@1.9.5(acorn@8.14.1): + dependencies: + acorn: 8.14.1 + + acorn-import-attributes@1.9.5(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + + acorn-walk@8.3.4: + dependencies: + acorn: 8.15.0 + + acorn@8.11.3: {} + + acorn@8.14.1: {} + + acorn@8.15.0: {} + + adm-zip@0.4.16: {} + + agent-base@6.0.2: + dependencies: + debug: 4.3.4(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + agent-base@7.1.3: {} + + aggregate-error@3.1.0: + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + + algoliasearch@5.12.0: + dependencies: + '@algolia/client-abtesting': 5.12.0 + '@algolia/client-analytics': 5.12.0 + '@algolia/client-common': 5.12.0 + '@algolia/client-insights': 5.12.0 + '@algolia/client-personalization': 5.12.0 + '@algolia/client-query-suggestions': 5.12.0 + '@algolia/client-search': 5.12.0 + '@algolia/ingestion': 1.12.0 + '@algolia/monitoring': 1.12.0 + '@algolia/recommend': 5.12.0 + '@algolia/requester-browser-xhr': 5.12.0 + '@algolia/requester-fetch': 5.12.0 + '@algolia/requester-node-http': 5.12.0 + + alien-signals@0.2.0: {} + + ansi-align@3.0.1: + dependencies: + string-width: 4.2.3 + + ansi-colors@4.1.1: {} + + ansi-colors@4.1.3: {} + + ansi-escapes@4.3.2: + dependencies: + type-fest: 0.21.3 + + ansi-escapes@7.0.0: + dependencies: + environment: 1.1.0 + + ansi-regex@5.0.1: {} + + ansi-regex@6.1.0: {} + + ansi-styles@3.2.1: + dependencies: + color-convert: 1.9.3 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@5.2.0: {} + + ansi-styles@6.2.1: {} + + ansis@3.17.0: {} + + any-promise@1.3.0: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + aproba@2.0.0: {} + + archiver-utils@2.1.0: + dependencies: + glob: 7.2.3 + graceful-fs: 4.2.11 + lazystream: 1.0.1 + lodash.defaults: 4.2.0 + lodash.difference: 4.5.0 + lodash.flatten: 4.4.0 + lodash.isplainobject: 4.0.6 + lodash.union: 4.6.0 + normalize-path: 3.0.0 + readable-stream: 2.3.8 + + archiver-utils@3.0.4: + dependencies: + glob: 7.2.3 + graceful-fs: 4.2.11 + lazystream: 1.0.1 + lodash.defaults: 4.2.0 + lodash.difference: 4.5.0 + lodash.flatten: 4.4.0 + lodash.isplainobject: 4.0.6 + lodash.union: 4.6.0 + normalize-path: 3.0.0 + readable-stream: 3.6.2 + + archiver-utils@5.0.2: + dependencies: + glob: 10.4.5 + graceful-fs: 4.2.11 + is-stream: 2.0.1 + lazystream: 1.0.1 + lodash: 4.17.21 + normalize-path: 3.0.0 + readable-stream: 4.7.0 + + archiver@5.3.2: + dependencies: + archiver-utils: 2.1.0 + async: 3.2.6 + buffer-crc32: 0.2.13 + readable-stream: 3.6.2 + readdir-glob: 1.1.3 + tar-stream: 2.2.0 + zip-stream: 4.1.1 + + archiver@7.0.1: + dependencies: + archiver-utils: 5.0.2 + async: 3.2.6 + buffer-crc32: 1.0.0 + readable-stream: 4.7.0 + readdir-glob: 1.1.3 + tar-stream: 3.1.7 + zip-stream: 6.0.1 + + are-we-there-yet@2.0.0: + dependencies: + delegates: 1.0.0 + readable-stream: 3.6.2 + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + argparse@2.0.1: {} + + aria-query@5.3.0: + dependencies: + dequal: 2.0.3 + + array-union@1.0.2: + dependencies: + array-uniq: 1.0.3 + + array-union@2.1.0: {} + + array-uniq@1.0.3: {} + + assertion-error@2.0.1: {} + + ast-kit@1.4.3: + dependencies: + '@babel/parser': 7.27.2 + pathe: 2.0.3 + + ast-module-types@5.0.0: {} + + ast-walker-scope@0.6.2: + dependencies: + '@babel/parser': 7.27.2 + ast-kit: 1.4.3 + + async-mutex@0.2.6: + dependencies: + tslib: 2.8.1 + + async-sema@3.1.1: {} + + async@3.2.6: {} + + atomic-sleep@1.0.0: {} + + autoprefixer@10.4.21(postcss@8.5.3): + dependencies: + browserslist: 4.24.5 + caniuse-lite: 1.0.30001723 + fraction.js: 4.3.7 + normalize-range: 0.1.2 + picocolors: 1.1.1 + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.1.0 + + b4a@1.6.7: {} + + balanced-match@1.0.2: {} + + bare-events@2.5.4: + optional: true + + base-x@3.0.9: + dependencies: + safe-buffer: 5.2.1 + + base-x@5.0.1: {} + + base64-js@1.5.1: {} + + better-path-resolve@1.0.0: + dependencies: + is-windows: 1.0.2 + + big.js@6.2.2: {} + + binary-extensions@2.2.0: {} + + bindings@1.5.0: + dependencies: + file-uri-to-path: 1.0.0 + + birpc@0.2.19: {} + + birpc@2.3.0: {} + + bl@4.1.0: + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + + blakejs@1.2.1: {} + + bn.js@4.12.0: {} + + bn.js@5.2.1: {} + + boolbase@1.0.0: {} + + bowser@2.11.0: {} + + boxen@5.1.2: + dependencies: + ansi-align: 3.0.1 + camelcase: 6.3.0 + chalk: 4.1.2 + cli-boxes: 2.2.1 + string-width: 4.2.3 + type-fest: 0.20.2 + widest-line: 3.1.0 + wrap-ansi: 7.0.0 + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.2: + dependencies: + fill-range: 7.0.1 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + brorand@1.1.0: {} + + browser-stdout@1.3.1: {} + + browserify-aes@1.2.0: + dependencies: + buffer-xor: 1.0.3 + cipher-base: 1.0.4 + create-hash: 1.2.0 + evp_bytestokey: 1.0.3 + inherits: 2.0.4 + safe-buffer: 5.2.1 + + browserslist@4.23.0: + dependencies: + caniuse-lite: 1.0.30001723 + electron-to-chromium: 1.4.757 + node-releases: 2.0.14 + update-browserslist-db: 1.0.15(browserslist@4.23.0) + + browserslist@4.24.5: + dependencies: + caniuse-lite: 1.0.30001723 + electron-to-chromium: 1.5.155 + node-releases: 2.0.19 + update-browserslist-db: 1.1.3(browserslist@4.24.5) + + bs58@4.0.1: + dependencies: + base-x: 3.0.9 + + bs58@6.0.0: + dependencies: + base-x: 5.0.1 + + bs58check@2.1.2: + dependencies: + bs58: 4.0.1 + create-hash: 1.2.0 + safe-buffer: 5.2.1 + + buffer-crc32@0.2.13: {} + + buffer-crc32@1.0.0: {} + + buffer-from@1.1.2: {} + + buffer-xor@1.0.3: {} + + buffer@5.7.1: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + bufferutil@4.0.8: + dependencies: + node-gyp-build: 4.6.0 + + bufferutil@4.0.9: + dependencies: + node-gyp-build: 4.8.4 + + builtin-modules@3.3.0: {} + + bun-types@1.1.29: + dependencies: + '@types/node': 20.12.14 + '@types/ws': 8.5.10 + + bun@1.1.30: + optionalDependencies: + '@oven/bun-darwin-aarch64': 1.1.30 + '@oven/bun-darwin-x64': 1.1.30 + '@oven/bun-darwin-x64-baseline': 1.1.30 + '@oven/bun-linux-aarch64': 1.1.30 + '@oven/bun-linux-x64': 1.1.30 + '@oven/bun-linux-x64-baseline': 1.1.30 + '@oven/bun-windows-x64': 1.1.30 + '@oven/bun-windows-x64-baseline': 1.1.30 + + bundle-name@4.1.0: + dependencies: + run-applescript: 7.0.0 + + bundle-require@5.1.0(esbuild@0.25.5): + dependencies: + esbuild: 0.25.5 + load-tsconfig: 0.2.5 + + busboy@1.6.0: + dependencies: + streamsearch: 1.1.0 + + bytes@3.1.2: {} + + c12@3.0.4(magicast@0.3.5): + dependencies: + chokidar: 4.0.3 + confbox: 0.2.2 + defu: 6.1.4 + dotenv: 16.5.0 + exsolve: 1.0.5 + giget: 2.0.0 + jiti: 2.4.2 + ohash: 2.0.11 + pathe: 2.0.3 + perfect-debounce: 1.0.0 + pkg-types: 2.1.0 + rc9: 2.1.2 + optionalDependencies: + magicast: 0.3.5 + + cac@6.7.14: {} + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.8: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + callsite@1.0.0: {} + + camelcase@5.3.1: {} + + camelcase@6.3.0: {} + + caniuse-api@3.0.0: + dependencies: + browserslist: 4.24.5 + caniuse-lite: 1.0.30001723 + lodash.memoize: 4.1.2 + lodash.uniq: 4.5.0 + + caniuse-lite@1.0.30001723: {} + + ccount@2.0.1: {} + + chai@5.2.0: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.1 + deep-eql: 5.0.2 + loupe: 3.1.3 + pathval: 2.0.0 + + chalk@2.4.2: + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chalk@5.3.0: {} + + change-case@5.4.4: {} + + char-regex@1.0.2: {} + + character-entities-html4@2.1.0: {} + + character-entities-legacy@3.0.0: {} + + character-entities@2.0.2: {} + + chardet@0.7.0: {} + + check-error@2.1.1: {} + + chokidar@3.5.3: + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + chownr@2.0.0: {} + + chownr@3.0.0: {} + + ci-info@2.0.0: {} + + ci-info@3.9.0: {} + + cipher-base@1.0.4: + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + + citty@0.1.6: + dependencies: + consola: 3.4.2 + + cjs-module-lexer@1.4.1: {} + + clean-stack@2.2.0: {} + + cli-boxes@2.2.1: {} + + cli-highlight@2.1.11: + dependencies: + chalk: 4.1.2 + highlight.js: 10.7.3 + mz: 2.7.0 + parse5: 5.1.1 + parse5-htmlparser2-tree-adapter: 6.0.1 + yargs: 16.2.0 + + cli-spinners@2.9.2: {} + + cli-table3@0.6.5: + dependencies: + string-width: 4.2.3 + optionalDependencies: + '@colors/colors': 1.5.0 + + cli-width@4.1.0: {} + + client-only@0.0.1: {} + + clipboardy@4.0.0: + dependencies: + execa: 8.0.1 + is-wsl: 3.1.0 + is64bit: 2.0.0 + + cliui@6.0.0: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + + cliui@7.0.4: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + clone@1.0.4: + optional: true + + clsx@1.2.1: {} + + cluster-key-slot@1.1.2: {} + + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.3: {} + + color-name@1.1.4: {} + + color-string@1.9.1: + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.2 + + color-support@1.1.3: {} + + color@3.2.1: + dependencies: + color-convert: 1.9.3 + color-string: 1.9.1 + + color@4.2.3: + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + optional: true + + colord@2.9.3: {} + + colorette@2.0.20: {} + + colorspace@1.1.4: + dependencies: + color: 3.2.1 + text-hex: 1.0.0 + + comma-separated-tokens@2.0.3: {} + + command-exists@1.2.9: {} + + commander@10.0.1: {} + + commander@2.20.3: {} + + commander@3.0.2: {} + + commander@4.1.1: {} + + commander@7.2.0: {} + + common-path-prefix@3.0.0: {} + + commondir@1.0.1: {} + + compatx@0.1.8: {} + + compatx@0.2.0: {} + + compress-commons@4.1.2: + dependencies: + buffer-crc32: 0.2.13 + crc32-stream: 4.0.3 + normalize-path: 3.0.0 + readable-stream: 3.6.2 + + compress-commons@6.0.2: + dependencies: + crc-32: 1.2.2 + crc32-stream: 6.0.0 + is-stream: 2.0.1 + normalize-path: 3.0.0 + readable-stream: 4.7.0 + + computeds@0.0.1: {} + + concat-map@0.0.1: {} + + confbox@0.1.7: {} + + confbox@0.1.8: {} + + confbox@0.2.2: {} + + config-chain@1.1.13: + dependencies: + ini: 1.3.8 + proto-list: 1.2.4 + + consola@3.2.3: {} + + consola@3.4.2: {} + + console-control-strings@1.1.0: {} + + convert-source-map@2.0.0: {} + + cookie-es@1.2.2: {} + + cookie-es@2.0.0: {} + + cookie@0.4.2: {} + + cookie@0.5.0: {} + + cookie@1.0.2: {} + + copy-anything@3.0.5: + dependencies: + is-what: 4.1.16 + + core-util-is@1.0.3: {} + + cp-file@10.0.0: + dependencies: + graceful-fs: 4.2.11 + nested-error-stacks: 2.1.1 + p-event: 5.0.1 + + crc-32@1.2.2: {} + + crc32-stream@4.0.3: + dependencies: + crc-32: 1.2.2 + readable-stream: 3.6.2 + + crc32-stream@6.0.0: + dependencies: + crc-32: 1.2.2 + readable-stream: 4.7.0 + + create-hash@1.2.0: + dependencies: + cipher-base: 1.0.4 + inherits: 2.0.4 + md5.js: 1.3.5 + ripemd160: 2.0.2 + sha.js: 2.4.11 + + create-hmac@1.1.7: + dependencies: + cipher-base: 1.0.4 + create-hash: 1.2.0 + inherits: 2.0.4 + ripemd160: 2.0.2 + safe-buffer: 5.2.1 + sha.js: 2.4.11 + + cron-parser@4.9.0: + dependencies: + luxon: 3.6.1 + + croner@9.0.0: {} + + cross-fetch@3.1.5(encoding@0.1.13): + dependencies: + node-fetch: 2.6.7(encoding@0.1.13) + transitivePeerDependencies: + - encoding + + cross-fetch@3.2.0(encoding@0.1.13): + dependencies: + node-fetch: 2.7.0(encoding@0.1.13) + transitivePeerDependencies: + - encoding + + cross-fetch@4.1.0(encoding@0.1.13): + dependencies: + node-fetch: 2.7.0(encoding@0.1.13) + transitivePeerDependencies: + - encoding + + cross-spawn@5.1.0: + dependencies: + lru-cache: 4.1.5 + shebang-command: 1.2.0 + which: 1.3.1 + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + crossws@0.2.4: {} + + crossws@0.3.5: + dependencies: + uncrypto: 0.1.3 + + crypto-random-string@1.0.0: {} + + css-declaration-sorter@7.2.0(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + + css-select@5.1.0: + dependencies: + boolbase: 1.0.0 + css-what: 6.1.0 + domhandler: 5.0.3 + domutils: 3.2.2 + nth-check: 2.1.1 + + css-tree@2.2.1: + dependencies: + mdn-data: 2.0.28 + source-map-js: 1.2.1 + + css-tree@2.3.1: + dependencies: + mdn-data: 2.0.30 + source-map-js: 1.2.1 + + css-what@6.1.0: {} + + cssesc@3.0.0: {} + + cssnano-preset-default@7.0.7(postcss@8.5.3): + dependencies: + browserslist: 4.24.5 + css-declaration-sorter: 7.2.0(postcss@8.5.3) + cssnano-utils: 5.0.1(postcss@8.5.3) + postcss: 8.5.3 + postcss-calc: 10.1.1(postcss@8.5.3) + postcss-colormin: 7.0.3(postcss@8.5.3) + postcss-convert-values: 7.0.5(postcss@8.5.3) + postcss-discard-comments: 7.0.4(postcss@8.5.3) + postcss-discard-duplicates: 7.0.2(postcss@8.5.3) + postcss-discard-empty: 7.0.1(postcss@8.5.3) + postcss-discard-overridden: 7.0.1(postcss@8.5.3) + postcss-merge-longhand: 7.0.5(postcss@8.5.3) + postcss-merge-rules: 7.0.5(postcss@8.5.3) + postcss-minify-font-values: 7.0.1(postcss@8.5.3) + postcss-minify-gradients: 7.0.1(postcss@8.5.3) + postcss-minify-params: 7.0.3(postcss@8.5.3) + postcss-minify-selectors: 7.0.5(postcss@8.5.3) + postcss-normalize-charset: 7.0.1(postcss@8.5.3) + postcss-normalize-display-values: 7.0.1(postcss@8.5.3) + postcss-normalize-positions: 7.0.1(postcss@8.5.3) + postcss-normalize-repeat-style: 7.0.1(postcss@8.5.3) + postcss-normalize-string: 7.0.1(postcss@8.5.3) + postcss-normalize-timing-functions: 7.0.1(postcss@8.5.3) + postcss-normalize-unicode: 7.0.3(postcss@8.5.3) + postcss-normalize-url: 7.0.1(postcss@8.5.3) + postcss-normalize-whitespace: 7.0.1(postcss@8.5.3) + postcss-ordered-values: 7.0.2(postcss@8.5.3) + postcss-reduce-initial: 7.0.3(postcss@8.5.3) + postcss-reduce-transforms: 7.0.1(postcss@8.5.3) + postcss-svgo: 7.0.2(postcss@8.5.3) + postcss-unique-selectors: 7.0.4(postcss@8.5.3) + + cssnano-utils@5.0.1(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + + cssnano@7.0.7(postcss@8.5.3): + dependencies: + cssnano-preset-default: 7.0.7(postcss@8.5.3) + lilconfig: 3.1.3 + postcss: 8.5.3 + + csso@5.0.5: + dependencies: + css-tree: 2.2.1 + + csstype@3.1.3: {} + + data-uri-to-buffer@4.0.1: {} + + dataloader@1.4.0: {} + + date-fns@2.30.0: + dependencies: + '@babel/runtime': 7.27.6 + + dateformat@4.6.3: {} + + dayjs@1.11.13: {} + + db0@0.3.2: {} + + de-indent@1.0.2: {} + + debounce@1.2.1: {} + + debug@4.3.4(supports-color@8.1.1): + dependencies: + ms: 2.1.2 + optionalDependencies: + supports-color: 8.1.1 + + debug@4.3.7: + dependencies: + ms: 2.1.3 + + debug@4.4.1: + dependencies: + ms: 2.1.3 + + decache@4.6.2: + dependencies: + callsite: 1.0.0 + + decamelize@1.2.0: {} + + decamelize@4.0.0: {} + + decode-named-character-reference@1.0.2: + dependencies: + character-entities: 2.0.2 + + decode-uri-component@0.2.2: {} + + dedent@1.6.0: {} + + deep-eql@5.0.2: {} + + deepmerge@4.3.1: {} + + default-browser-id@5.0.0: {} + + default-browser@5.2.1: + dependencies: + bundle-name: 4.1.0 + default-browser-id: 5.0.0 + + defaults@1.0.4: + dependencies: + clone: 1.0.4 + optional: true + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + define-lazy-prop@2.0.0: {} + + define-lazy-prop@3.0.0: {} + + defu@6.1.4: {} + + delegates@1.0.0: {} + + denque@2.1.0: {} + + depd@2.0.0: {} + + dequal@2.0.3: {} + + derive-valtio@0.1.0(valtio@1.13.2(@types/react@18.3.1)(react@18.3.1)): + dependencies: + valtio: 1.13.2(@types/react@18.3.1)(react@18.3.1) + + destr@2.0.5: {} + + detect-browser@5.3.0: {} + + detect-indent@6.1.0: {} + + detect-libc@1.0.3: {} + + detect-libc@2.0.4: {} + + detective-amd@5.0.2: + dependencies: + ast-module-types: 5.0.0 + escodegen: 2.1.0 + get-amd-module-type: 5.0.1 + node-source-walk: 6.0.2 + + detective-cjs@5.0.1: + dependencies: + ast-module-types: 5.0.0 + node-source-walk: 6.0.2 + + detective-es6@4.0.1: + dependencies: + node-source-walk: 6.0.2 + + detective-postcss@6.1.3: + dependencies: + is-url: 1.2.4 + postcss: 8.5.5 + postcss-values-parser: 6.0.2(postcss@8.5.5) + + detective-sass@5.0.3: + dependencies: + gonzales-pe: 4.3.0 + node-source-walk: 6.0.2 + + detective-scss@4.0.3: + dependencies: + gonzales-pe: 4.3.0 + node-source-walk: 6.0.2 + + detective-stylus@4.0.0: {} + + detective-typescript@11.2.0: + dependencies: + '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.8.3) + ast-module-types: 5.0.0 + node-source-walk: 6.0.2 + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + devalue@5.1.1: {} + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + diff@5.0.0: {} + + diff@7.0.0: {} + + dijkstrajs@1.0.2: {} + + dir-glob@2.2.2: + dependencies: + path-type: 3.0.0 + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + dom-accessibility-api@0.5.16: {} + + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + domutils@3.2.2: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + + dot-prop@9.0.0: + dependencies: + type-fest: 4.41.0 + + dotenv-expand@10.0.0: {} + + dotenv@16.3.1: {} + + dotenv@16.5.0: {} + + dotenv@8.6.0: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + duplexer@0.1.2: {} + + duplexify@4.1.2: + dependencies: + end-of-stream: 1.4.4 + inherits: 2.0.4 + readable-stream: 3.6.2 + stream-shift: 1.0.1 + + eastasianwidth@0.2.0: {} + + easy-table@1.2.0: + dependencies: + ansi-regex: 5.0.1 + optionalDependencies: + wcwidth: 1.0.1 + + eciesjs@0.4.15: + dependencies: + '@ecies/ciphers': 0.2.3(@noble/ciphers@1.3.0) + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.2 + '@noble/hashes': 1.8.0 + + editorconfig@1.0.4: + dependencies: + '@one-ini/wasm': 0.1.1 + commander: 10.0.1 + minimatch: 9.0.1 + semver: 7.7.2 + + ee-first@1.1.1: {} + + electron-to-chromium@1.4.757: {} + + electron-to-chromium@1.5.155: {} + + elliptic@6.5.4: + dependencies: + bn.js: 4.12.0 + brorand: 1.1.0 + hash.js: 1.1.7 + hmac-drbg: 1.0.1 + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + + elliptic@6.6.0: + dependencies: + bn.js: 4.12.0 + brorand: 1.1.0 + hash.js: 1.1.7 + hmac-drbg: 1.0.1 + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + + elliptic@6.6.1: + dependencies: + bn.js: 4.12.0 + brorand: 1.1.0 + hash.js: 1.1.7 + hmac-drbg: 1.0.1 + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + emojilib@2.4.0: {} + + enabled@2.0.0: {} + + encode-utf8@1.0.3: {} + + encodeurl@2.0.0: {} + + encoding@0.1.13: + dependencies: + iconv-lite: 0.6.3 + + end-of-stream@1.4.4: + dependencies: + once: 1.4.0 + + engine.io-client@6.6.3(bufferutil@4.0.9)(utf-8-validate@5.0.10): + dependencies: + '@socket.io/component-emitter': 3.1.2 + debug: 4.3.7 + engine.io-parser: 5.2.3 + ws: 8.17.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + xmlhttprequest-ssl: 2.1.2 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + engine.io-parser@5.2.3: {} + + enhanced-resolve@5.17.1: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.1 + + enhanced-resolve@5.18.1: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.2 + + enquirer@2.3.6: + dependencies: + ansi-colors: 4.1.3 + + entities@4.5.0: {} + + env-paths@2.2.1: {} + + env-paths@3.0.0: {} + + environment@1.1.0: {} + + error-stack-parser-es@1.0.5: {} + + errx@0.1.0: {} + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-module-lexer@1.7.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-toolkit@1.33.0: {} + + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + + esbuild@0.25.4: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.4 + '@esbuild/android-arm': 0.25.4 + '@esbuild/android-arm64': 0.25.4 + '@esbuild/android-x64': 0.25.4 + '@esbuild/darwin-arm64': 0.25.4 + '@esbuild/darwin-x64': 0.25.4 + '@esbuild/freebsd-arm64': 0.25.4 + '@esbuild/freebsd-x64': 0.25.4 + '@esbuild/linux-arm': 0.25.4 + '@esbuild/linux-arm64': 0.25.4 + '@esbuild/linux-ia32': 0.25.4 + '@esbuild/linux-loong64': 0.25.4 + '@esbuild/linux-mips64el': 0.25.4 + '@esbuild/linux-ppc64': 0.25.4 + '@esbuild/linux-riscv64': 0.25.4 + '@esbuild/linux-s390x': 0.25.4 + '@esbuild/linux-x64': 0.25.4 + '@esbuild/netbsd-arm64': 0.25.4 + '@esbuild/netbsd-x64': 0.25.4 + '@esbuild/openbsd-arm64': 0.25.4 + '@esbuild/openbsd-x64': 0.25.4 + '@esbuild/sunos-x64': 0.25.4 + '@esbuild/win32-arm64': 0.25.4 + '@esbuild/win32-ia32': 0.25.4 + '@esbuild/win32-x64': 0.25.4 + + esbuild@0.25.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.5 + '@esbuild/android-arm': 0.25.5 + '@esbuild/android-arm64': 0.25.5 + '@esbuild/android-x64': 0.25.5 + '@esbuild/darwin-arm64': 0.25.5 + '@esbuild/darwin-x64': 0.25.5 + '@esbuild/freebsd-arm64': 0.25.5 + '@esbuild/freebsd-x64': 0.25.5 + '@esbuild/linux-arm': 0.25.5 + '@esbuild/linux-arm64': 0.25.5 + '@esbuild/linux-ia32': 0.25.5 + '@esbuild/linux-loong64': 0.25.5 + '@esbuild/linux-mips64el': 0.25.5 + '@esbuild/linux-ppc64': 0.25.5 + '@esbuild/linux-riscv64': 0.25.5 + '@esbuild/linux-s390x': 0.25.5 + '@esbuild/linux-x64': 0.25.5 + '@esbuild/netbsd-arm64': 0.25.5 + '@esbuild/netbsd-x64': 0.25.5 + '@esbuild/openbsd-arm64': 0.25.5 + '@esbuild/openbsd-x64': 0.25.5 + '@esbuild/sunos-x64': 0.25.5 + '@esbuild/win32-arm64': 0.25.5 + '@esbuild/win32-ia32': 0.25.5 + '@esbuild/win32-x64': 0.25.5 + + escalade@3.2.0: {} + + escape-html@1.0.3: {} + + escape-string-regexp@1.0.5: {} + + escape-string-regexp@4.0.0: {} + + escape-string-regexp@5.0.0: {} + + escodegen@2.1.0: + dependencies: + esprima: 4.0.1 + estraverse: 5.3.0 + esutils: 2.0.3 + optionalDependencies: + source-map: 0.6.1 + + eslint-visitor-keys@3.4.3: {} + + esprima@4.0.1: {} + + estraverse@5.3.0: {} + + estree-walker@2.0.2: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.7 + + esutils@2.0.3: {} + + etag@1.8.1: {} + + eth-block-tracker@7.1.0: + dependencies: + '@metamask/eth-json-rpc-provider': 1.0.1 + '@metamask/safe-event-emitter': 3.0.0 + '@metamask/utils': 5.0.2 + json-rpc-random-id: 1.0.1 + pify: 3.0.0 + transitivePeerDependencies: + - supports-color + + eth-json-rpc-filters@6.0.1: + dependencies: + '@metamask/safe-event-emitter': 3.0.0 + async-mutex: 0.2.6 + eth-query: 2.1.2 + json-rpc-engine: 6.1.0 + pify: 5.0.0 + + eth-query@2.1.2: + dependencies: + json-rpc-random-id: 1.0.1 + xtend: 4.0.2 + + eth-rpc-errors@4.0.3: + dependencies: + fast-safe-stringify: 2.1.1 + + ethereum-cryptography@0.1.3: + dependencies: + '@types/pbkdf2': 3.1.2 + '@types/secp256k1': 4.0.3 + blakejs: 1.2.1 + browserify-aes: 1.2.0 + bs58check: 2.1.2 + create-hash: 1.2.0 + create-hmac: 1.1.7 + hash.js: 1.1.7 + keccak: 3.0.3 + pbkdf2: 3.1.2 + randombytes: 2.1.0 + safe-buffer: 5.2.1 + scrypt-js: 3.0.1 + secp256k1: 4.0.3 + setimmediate: 1.0.5 + + ethereum-cryptography@1.2.0: + dependencies: + '@noble/hashes': 1.2.0 + '@noble/secp256k1': 1.7.1 + '@scure/bip32': 1.1.5 + '@scure/bip39': 1.1.1 + + ethereum-cryptography@2.2.1: + dependencies: + '@noble/curves': 1.4.2 + '@noble/hashes': 1.4.0 + '@scure/bip32': 1.4.0 + '@scure/bip39': 1.3.0 + + ethereumjs-abi@0.6.8: + dependencies: + bn.js: 4.12.0 + ethereumjs-util: 6.2.1 + + ethereumjs-util@6.2.1: + dependencies: + '@types/bn.js': 4.11.6 + bn.js: 4.12.0 + create-hash: 1.2.0 + elliptic: 6.6.0 + ethereum-cryptography: 0.1.3 + ethjs-util: 0.1.6 + rlp: 2.2.7 + + ethjs-util@0.1.6: + dependencies: + is-hex-prefixed: 1.0.0 + strip-hex-prefix: 1.0.0 + + event-target-shim@5.0.1: {} + + eventemitter2@6.4.9: {} + + eventemitter3@4.0.7: {} + + eventemitter3@5.0.1: {} + + events@3.3.0: {} + + evp_bytestokey@1.0.3: + dependencies: + md5.js: 1.3.5 + safe-buffer: 5.2.1 + + execa@5.1.1: + dependencies: + cross-spawn: 7.0.6 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + + execa@7.2.0: + dependencies: + cross-spawn: 7.0.6 + get-stream: 6.0.1 + human-signals: 4.3.1 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 3.0.7 + strip-final-newline: 3.0.0 + + execa@8.0.1: + dependencies: + cross-spawn: 7.0.6 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + + execa@9.1.0: + dependencies: + '@sindresorhus/merge-streams': 4.0.0 + cross-spawn: 7.0.6 + figures: 6.1.0 + get-stream: 9.0.1 + human-signals: 7.0.0 + is-plain-obj: 4.1.0 + is-stream: 4.0.1 + npm-run-path: 5.3.0 + pretty-ms: 9.0.0 + signal-exit: 4.1.0 + strip-final-newline: 4.0.0 + yoctocolors: 2.0.2 + + expect-type@1.2.1: {} + + exsolve@1.0.5: {} + + extendable-error@0.1.7: {} + + extension-port-stream@3.0.0: + dependencies: + readable-stream: 3.6.2 + webextension-polyfill: 0.10.0 + + external-editor@3.1.0: + dependencies: + chardet: 0.7.0 + iconv-lite: 0.4.24 + tmp: 0.0.33 + + externality@1.0.2: + dependencies: + enhanced-resolve: 5.18.1 + mlly: 1.7.4 + pathe: 1.1.2 + ufo: 1.6.1 + + extract-zip@2.0.1: + dependencies: + debug: 4.4.1 + get-stream: 5.2.0 + yauzl: 2.10.0 + optionalDependencies: + '@types/yauzl': 2.10.3 + transitivePeerDependencies: + - supports-color + + fast-copy@3.0.2: {} + + fast-deep-equal@3.1.3: {} + + fast-fifo@1.3.2: {} + + fast-glob@3.3.2: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.5 + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-npm-meta@0.4.3: {} + + fast-redact@3.1.2: {} + + fast-safe-stringify@2.1.1: {} + + fastq@1.15.0: + dependencies: + reusify: 1.0.4 + + fd-slicer@1.1.0: + dependencies: + pend: 1.2.0 + + fdir@6.1.1(picomatch@4.0.2): + optionalDependencies: + picomatch: 4.0.2 + + fdir@6.4.4(picomatch@4.0.2): + optionalDependencies: + picomatch: 4.0.2 + + fecha@4.2.3: {} + + fetch-blob@3.2.0: + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 3.3.3 + + fflate@0.8.2: {} + + figures@6.1.0: + dependencies: + is-unicode-supported: 2.0.0 + + file-uri-to-path@1.0.0: {} + + fill-range@7.0.1: + dependencies: + to-regex-range: 5.0.1 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + filter-obj@1.1.0: {} + + filter-obj@5.1.0: {} + + find-up-simple@1.0.1: {} + + find-up@2.1.0: + dependencies: + locate-path: 2.0.0 + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + find-up@6.3.0: + dependencies: + locate-path: 7.2.0 + path-exists: 5.0.0 + + find-up@7.0.0: + dependencies: + locate-path: 7.2.0 + path-exists: 5.0.0 + unicorn-magic: 0.1.0 + + fixturez@1.1.0: + dependencies: + fs-extra: 5.0.0 + globby: 7.1.1 + signal-exit: 3.0.7 + tempy: 0.2.1 + + flat@5.0.2: {} + + floating-vue@5.2.2(@nuxt/kit@3.17.4(magicast@0.3.5))(vue@3.5.12(typescript@5.8.3)): + dependencies: + '@floating-ui/dom': 1.1.1 + vue: 3.5.12(typescript@5.8.3) + vue-resize: 2.0.0-alpha.1(vue@3.5.12(typescript@5.8.3)) + optionalDependencies: + '@nuxt/kit': 3.17.4(magicast@0.3.5) + + fn.name@1.1.0: {} + + focus-trap@7.6.0: + dependencies: + tabbable: 6.2.0 + + follow-redirects@1.15.2(debug@4.3.4): + optionalDependencies: + debug: 4.3.4(supports-color@8.1.1) + + for-each@0.3.5: + dependencies: + is-callable: 1.2.7 + + foreground-child@3.1.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + formdata-polyfill@4.0.10: + dependencies: + fetch-blob: 3.2.0 + + fp-ts@1.19.3: {} + + fraction.js@4.3.7: {} + + fresh@2.0.0: {} + + fs-constants@1.0.0: {} + + fs-extra@0.30.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 2.4.0 + klaw: 1.3.1 + path-is-absolute: 1.0.1 + rimraf: 2.7.1 + + fs-extra@5.0.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fs-extra@7.0.1: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fs-extra@8.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fs-minipass@2.1.0: + dependencies: + minipass: 3.3.6 + + fs.realpath@1.0.0: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + fuse.js@7.1.0: {} + + gauge@3.0.2: + dependencies: + aproba: 2.0.0 + color-support: 1.1.3 + console-control-strings: 1.1.0 + has-unicode: 2.0.1 + object-assign: 4.1.1 + signal-exit: 3.0.7 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wide-align: 1.1.5 + + gensync@1.0.0-beta.2: {} + + get-amd-module-type@5.0.1: + dependencies: + ast-module-types: 5.0.0 + node-source-walk: 6.0.2 + + get-caller-file@2.0.5: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-port-please@3.1.2: {} + + get-port@7.1.0: {} + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-stream@5.2.0: + dependencies: + pump: 3.0.2 + + get-stream@6.0.1: {} + + get-stream@8.0.1: {} + + get-stream@9.0.1: + dependencies: + '@sec-ant/readable-stream': 0.4.1 + is-stream: 4.0.1 + + giget@2.0.0: + dependencies: + citty: 0.1.6 + consola: 3.4.2 + defu: 6.1.4 + node-fetch-native: 1.6.6 + nypm: 0.6.0 + pathe: 2.0.3 + + git-up@8.1.1: + dependencies: + is-ssh: 1.4.1 + parse-url: 9.2.0 + + git-url-parse@16.1.0: + dependencies: + git-up: 8.1.1 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob@10.4.5: + dependencies: + foreground-child: 3.1.1 + jackspeak: 3.4.3 + minimatch: 9.0.4 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + + glob@7.2.0: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + glob@8.1.0: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 5.1.6 + once: 1.4.0 + + global-directory@4.0.1: + dependencies: + ini: 4.1.1 + + globals@11.12.0: {} + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + + globby@14.1.0: + dependencies: + '@sindresorhus/merge-streams': 2.3.0 + fast-glob: 3.3.3 + ignore: 7.0.4 + path-type: 6.0.0 + slash: 5.1.0 + unicorn-magic: 0.3.0 + + globby@7.1.1: + dependencies: + array-union: 1.0.2 + dir-glob: 2.2.2 + glob: 7.2.3 + ignore: 3.3.10 + pify: 3.0.0 + slash: 1.0.0 + + gonzales-pe@4.3.0: + dependencies: + minimist: 1.2.8 + + gopd@1.2.0: {} + + graceful-fs@4.2.11: {} + + graphql@16.8.1: {} + + gzip-size@6.0.0: + dependencies: + duplexer: 0.1.2 + + gzip-size@7.0.0: + dependencies: + duplexer: 0.1.2 + + h3@1.15.3: + dependencies: + cookie-es: 1.2.2 + crossws: 0.3.5 + defu: 6.1.4 + destr: 2.0.5 + iron-webcrypto: 1.2.1 + node-mock-http: 1.0.0 + radix3: 1.1.2 + ufo: 1.6.1 + uncrypto: 0.1.3 + + happy-dom@15.10.2: + dependencies: + entities: 4.5.0 + webidl-conversions: 7.0.0 + whatwg-mimetype: 3.0.0 + + hardhat@2.22.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10): + dependencies: + '@ethersproject/abi': 5.7.0 + '@metamask/eth-sig-util': 4.0.1 + '@nomicfoundation/edr': 0.3.7 + '@nomicfoundation/ethereumjs-common': 4.0.4 + '@nomicfoundation/ethereumjs-tx': 5.0.4 + '@nomicfoundation/ethereumjs-util': 9.0.4 + '@nomicfoundation/solidity-analyzer': 0.1.1 + '@sentry/node': 5.30.0 + '@types/bn.js': 5.1.5 + '@types/lru-cache': 5.1.1 + adm-zip: 0.4.16 + aggregate-error: 3.1.0 + ansi-escapes: 4.3.2 + boxen: 5.1.2 + chalk: 2.4.2 + chokidar: 3.6.0 + ci-info: 2.0.0 + debug: 4.3.4(supports-color@8.1.1) + enquirer: 2.3.6 + env-paths: 2.2.1 + ethereum-cryptography: 1.2.0 + ethereumjs-abi: 0.6.8 + find-up: 2.1.0 + fp-ts: 1.19.3 + fs-extra: 7.0.1 + glob: 7.2.0 + immutable: 4.3.5 + io-ts: 1.10.4 + keccak: 3.0.3 + lodash: 4.17.21 + mnemonist: 0.38.5 + mocha: 10.2.0 + p-map: 4.0.0 + raw-body: 2.5.1 + resolve: 1.17.0 + semver: 6.3.1 + solc: 0.7.3(debug@4.3.4) + source-map-support: 0.5.21 + stacktrace-parser: 0.1.10 + tsort: 0.0.1 + undici: 5.28.3 + uuid: 8.3.2 + ws: 7.5.9(bufferutil@4.0.9)(utf-8-validate@5.0.10) + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - bufferutil + - c-kzg + - supports-color + - utf-8-validate + + has-flag@3.0.0: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + has-unicode@2.0.1: {} + + hash-base@3.1.0: + dependencies: + inherits: 2.0.4 + readable-stream: 3.6.2 + safe-buffer: 5.2.1 + + hash.js@1.1.7: + dependencies: + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + hast-util-to-html@9.0.3: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.2 + ccount: 2.0.1 + comma-separated-tokens: 2.0.3 + hast-util-whitespace: 3.0.0 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.1.0 + property-information: 6.5.0 + space-separated-tokens: 2.0.2 + stringify-entities: 4.0.4 + zwitch: 2.0.4 + + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + he@1.2.0: {} + + headers-polyfill@4.0.2: {} + + help-me@5.0.0: {} + + highlight.js@10.7.3: {} + + hmac-drbg@1.0.1: + dependencies: + hash.js: 1.1.7 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + + hookable@5.5.3: {} + + hosted-git-info@7.0.2: + dependencies: + lru-cache: 10.4.3 + + html-escaper@2.0.2: {} + + html-void-elements@3.0.0: {} + + http-errors@2.0.0: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + + http-proxy@1.18.1: + dependencies: + eventemitter3: 4.0.7 + follow-redirects: 1.15.2(debug@4.3.4) + requires-port: 1.0.0 + transitivePeerDependencies: + - debug + + http-shutdown@1.2.2: {} + + https-proxy-agent@5.0.1: + dependencies: + agent-base: 6.0.2 + debug: 4.3.4(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + https-proxy-agent@7.0.6: + dependencies: + agent-base: 7.1.3 + debug: 4.4.1 + transitivePeerDependencies: + - supports-color + + httpxy@0.1.7: {} + + human-id@1.0.2: {} + + human-signals@2.1.0: {} + + human-signals@4.3.1: {} + + human-signals@5.0.0: {} + + human-signals@7.0.0: {} + + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + + idb-keyval@6.2.1: {} + + ieee754@1.2.1: {} + + ignore@3.3.10: {} + + ignore@5.3.2: {} + + ignore@7.0.4: {} + + image-meta@0.2.1: {} + + immutable@4.3.5: {} + + impound@0.2.2(rollup@4.41.0): + dependencies: + '@rollup/pluginutils': 5.1.4(rollup@4.41.0) + mlly: 1.7.4 + mocked-exports: 0.1.1 + pathe: 2.0.3 + unplugin: 2.3.4 + transitivePeerDependencies: + - rollup + + imurmurhash@0.1.4: {} + + indent-string@4.0.0: {} + + index-to-position@1.1.0: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + ini@1.3.8: {} + + ini@4.1.1: {} + + io-ts@1.10.4: + dependencies: + fp-ts: 1.19.3 + + ioredis@5.6.1: + dependencies: + '@ioredis/commands': 1.2.0 + cluster-key-slot: 1.1.2 + debug: 4.4.1 + denque: 2.1.0 + lodash.defaults: 4.2.0 + lodash.isarguments: 3.1.0 + redis-errors: 1.2.0 + redis-parser: 3.0.0 + standard-as-callback: 2.1.0 + transitivePeerDependencies: + - supports-color + + iron-webcrypto@1.2.1: {} + + is-arguments@1.2.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-arrayish@0.3.2: {} + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.2.0 + + is-builtin-module@3.2.1: + dependencies: + builtin-modules: 3.3.0 + + is-callable@1.2.7: {} + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + + is-docker@2.2.1: {} + + is-docker@3.0.0: {} + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-generator-function@1.1.0: + dependencies: + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-hex-prefixed@1.0.0: {} + + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + + is-installed-globally@1.0.0: + dependencies: + global-directory: 4.0.1 + is-path-inside: 4.0.0 + + is-module@1.0.0: {} + + is-node-process@1.2.0: {} + + is-number@7.0.0: {} + + is-path-inside@4.0.0: {} + + is-plain-obj@2.1.0: {} + + is-plain-obj@4.1.0: {} + + is-plain-object@5.0.0: {} + + is-reference@1.2.1: + dependencies: + '@types/estree': 1.0.7 + + is-regex@1.2.1: + dependencies: + call-bound: 1.0.4 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + is-ssh@1.4.1: + dependencies: + protocols: 2.0.2 + + is-stream@2.0.1: {} + + is-stream@3.0.0: {} + + is-stream@4.0.1: {} + + is-subdir@1.2.0: + dependencies: + better-path-resolve: 1.0.0 + + is-typed-array@1.1.15: + dependencies: + which-typed-array: 1.1.19 + + is-unicode-supported@0.1.0: {} + + is-unicode-supported@2.0.0: {} + + is-url-superb@4.0.0: {} + + is-url@1.2.4: {} + + is-what@4.1.16: {} + + is-windows@1.0.2: {} + + is-wsl@2.2.0: + dependencies: + is-docker: 2.2.1 + + is-wsl@3.1.0: + dependencies: + is-inside-container: 1.0.0 + + is64bit@2.0.0: + dependencies: + system-architecture: 0.1.0 + + isarray@1.0.0: {} + + isexe@2.0.0: {} + + isexe@3.1.1: {} + + isows@1.0.4(ws@8.13.0(bufferutil@4.0.8)(utf-8-validate@6.0.5)): + dependencies: + ws: 8.13.0(bufferutil@4.0.8)(utf-8-validate@6.0.5) + + isows@1.0.4(ws@8.13.0(bufferutil@4.0.9)(utf-8-validate@6.0.5)): + dependencies: + ws: 8.13.0(bufferutil@4.0.9)(utf-8-validate@6.0.5) + + isows@1.0.4(ws@8.17.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)): + dependencies: + ws: 8.17.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + + isows@1.0.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)): + dependencies: + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + + isows@1.0.6(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)): + dependencies: + ws: 8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + + isows@1.0.6(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@6.0.5)): + dependencies: + ws: 8.18.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) + + istanbul-lib-coverage@3.2.2: {} + + istanbul-lib-report@3.0.1: + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + + istanbul-lib-source-maps@5.0.6: + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + debug: 4.3.7 + istanbul-lib-coverage: 3.2.2 + transitivePeerDependencies: + - supports-color + + istanbul-reports@3.1.7: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + jiti@1.21.0: {} + + jiti@1.21.6: {} + + jiti@1.21.7: {} + + jiti@2.4.2: {} + + joycon@3.1.1: {} + + js-beautify@1.15.1: + dependencies: + config-chain: 1.1.13 + editorconfig: 1.0.4 + glob: 10.4.5 + js-cookie: 3.0.5 + nopt: 7.2.1 + + js-cookie@3.0.5: {} + + js-sha3@0.8.0: {} + + js-tokens@4.0.0: {} + + js-tokens@9.0.1: {} + + js-yaml@3.14.1: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + jsesc@2.5.2: {} + + jsesc@3.1.0: {} + + json-rpc-engine@6.1.0: + dependencies: + '@metamask/safe-event-emitter': 2.0.0 + eth-rpc-errors: 4.0.3 + + json-rpc-random-id@1.0.1: {} + + json5@2.2.3: {} + + jsonfile@2.4.0: + optionalDependencies: + graceful-fs: 4.2.11 + + jsonfile@4.0.0: + optionalDependencies: + graceful-fs: 4.2.11 + + junk@4.0.1: {} + + jwt-decode@4.0.0: {} + + keccak@3.0.3: + dependencies: + node-addon-api: 2.0.2 + node-gyp-build: 4.6.0 + readable-stream: 3.6.2 + + keyvaluestorage-interface@1.0.0: {} + + klaw@1.3.1: + optionalDependencies: + graceful-fs: 4.2.11 + + kleur@3.0.3: {} + + kleur@4.1.5: {} + + klona@2.0.6: {} + + knip@5.30.6(@types/node@24.0.1)(typescript@5.8.3): + dependencies: + '@nodelib/fs.walk': 1.2.8 + '@snyk/github-codeowners': 1.1.0 + '@types/node': 24.0.1 + easy-table: 1.2.0 + enhanced-resolve: 5.17.1 + fast-glob: 3.3.2 + jiti: 1.21.6 + js-yaml: 4.1.0 + minimist: 1.2.8 + picocolors: 1.1.0 + picomatch: 4.0.2 + pretty-ms: 9.0.0 + smol-toml: 1.3.0 + strip-json-comments: 5.0.1 + summary: 2.1.0 + typescript: 5.8.3 + zod: 3.25.20 + zod-validation-error: 3.2.0(zod@3.25.20) + + knitwork@1.2.0: {} + + kolorist@1.8.0: {} + + kuler@2.0.0: {} + + lambda-local@2.2.0: + dependencies: + commander: 10.0.1 + dotenv: 16.5.0 + winston: 3.17.0 + + launch-editor@2.10.0: + dependencies: + picocolors: 1.1.1 + shell-quote: 1.8.2 + + lazystream@1.0.1: + dependencies: + readable-stream: 2.3.8 + + lilconfig@3.1.3: {} + + listhen@1.7.2: + dependencies: + '@parcel/watcher': 2.4.1 + '@parcel/watcher-wasm': 2.4.1 + citty: 0.1.6 + clipboardy: 4.0.0 + consola: 3.4.2 + crossws: 0.2.4 + defu: 6.1.4 + get-port-please: 3.1.2 + h3: 1.15.3 + http-shutdown: 1.2.2 + jiti: 1.21.7 + mlly: 1.7.4 + node-forge: 1.3.1 + pathe: 1.1.2 + std-env: 3.9.0 + ufo: 1.6.1 + untun: 0.1.3 + uqr: 0.1.2 + transitivePeerDependencies: + - uWebSockets.js + + listhen@1.9.0: + dependencies: + '@parcel/watcher': 2.5.1 + '@parcel/watcher-wasm': 2.5.1 + citty: 0.1.6 + clipboardy: 4.0.0 + consola: 3.4.2 + crossws: 0.3.5 + defu: 6.1.4 + get-port-please: 3.1.2 + h3: 1.15.3 + http-shutdown: 1.2.2 + jiti: 2.4.2 + mlly: 1.7.4 + node-forge: 1.3.1 + pathe: 1.1.2 + std-env: 3.9.0 + ufo: 1.6.1 + untun: 0.1.3 + uqr: 0.1.2 + + lit-element@4.2.0: + dependencies: + '@lit-labs/ssr-dom-shim': 1.3.0 + '@lit/reactive-element': 2.1.0 + lit-html: 3.3.0 + + lit-html@3.3.0: + dependencies: + '@types/trusted-types': 2.0.3 + + lit@3.1.0: + dependencies: + '@lit/reactive-element': 2.1.0 + lit-element: 4.2.0 + lit-html: 3.3.0 + + load-tsconfig@0.2.5: {} + + local-pkg@0.5.0: + dependencies: + mlly: 1.7.4 + pkg-types: 1.3.1 + + local-pkg@0.5.1: + dependencies: + mlly: 1.7.4 + pkg-types: 1.3.1 + + local-pkg@1.1.1: + dependencies: + mlly: 1.7.4 + pkg-types: 2.1.0 + quansync: 0.2.10 + + locate-path@2.0.0: + dependencies: + p-locate: 2.0.0 + path-exists: 3.0.0 + + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + locate-path@7.2.0: + dependencies: + p-locate: 6.0.0 + + lodash-es@4.17.21: {} + + lodash.debounce@4.0.8: {} + + lodash.defaults@4.2.0: {} + + lodash.difference@4.5.0: {} + + lodash.flatten@4.4.0: {} + + lodash.isarguments@3.1.0: {} + + lodash.isplainobject@4.0.6: {} + + lodash.memoize@4.1.2: {} + + lodash.startcase@4.4.0: {} + + lodash.union@4.6.0: {} + + lodash.uniq@4.5.0: {} + + lodash@4.17.21: {} + + log-symbols@4.1.0: + dependencies: + chalk: 4.1.2 + is-unicode-supported: 0.1.0 + + logform@2.7.0: + dependencies: + '@colors/colors': 1.6.0 + '@types/triple-beam': 1.3.5 + fecha: 4.2.3 + ms: 2.1.3 + safe-stable-stringify: 2.5.0 + triple-beam: 1.4.1 + + lokijs@1.5.12: {} + + longest-streak@3.1.0: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + loupe@3.1.3: {} + + lru-cache@10.2.2: {} + + lru-cache@10.4.3: {} + + lru-cache@4.1.5: + dependencies: + pseudomap: 1.0.2 + yallist: 2.1.2 + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + lru-cache@6.0.0: + dependencies: + yallist: 4.0.0 + + lru_map@0.3.3: {} + + luxon@3.6.1: {} + + lz-string@1.5.0: {} + + magic-string-ast@0.7.1: + dependencies: + magic-string: 0.30.17 + + magic-string@0.30.10: + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + + magic-string@0.30.11: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + magic-string@0.30.12: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + magic-string@0.30.17: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + magicast@0.3.4: + dependencies: + '@babel/parser': 7.24.5 + '@babel/types': 7.24.5 + source-map-js: 1.2.0 + + magicast@0.3.5: + dependencies: + '@babel/parser': 7.27.2 + '@babel/types': 7.27.1 + source-map-js: 1.2.1 + + make-dir@3.1.0: + dependencies: + semver: 6.3.1 + + make-dir@4.0.0: + dependencies: + semver: 7.7.2 + + mark.js@8.11.1: {} + + markdown-table@3.0.3: {} + + marked-terminal@7.1.0(marked@9.1.6): + dependencies: + ansi-escapes: 7.0.0 + chalk: 5.3.0 + cli-highlight: 2.1.11 + cli-table3: 0.6.5 + marked: 9.1.6 + node-emoji: 2.1.3 + supports-hyperlinks: 3.0.0 + + marked@9.1.6: {} + + math-intrinsics@1.1.0: {} + + md5.js@1.3.5: + dependencies: + hash-base: 3.1.0 + inherits: 2.0.4 + safe-buffer: 5.2.1 + + mdast-util-find-and-replace@3.0.1: + dependencies: + '@types/mdast': 4.0.3 + escape-string-regexp: 5.0.0 + unist-util-is: 6.0.0 + unist-util-visit-parents: 6.0.1 + + mdast-util-from-markdown@2.0.2: + dependencies: + '@types/mdast': 4.0.3 + '@types/unist': 3.0.2 + decode-named-character-reference: 1.0.2 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.0 + micromark-util-decode-numeric-character-reference: 2.0.1 + micromark-util-decode-string: 2.0.0 + micromark-util-normalize-identifier: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-autolink-literal@2.0.0: + dependencies: + '@types/mdast': 4.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-find-and-replace: 3.0.1 + micromark-util-character: 2.1.0 + + mdast-util-gfm-footnote@2.0.0: + dependencies: + '@types/mdast': 4.0.3 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.0 + micromark-util-normalize-identifier: 2.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-strikethrough@2.0.0: + dependencies: + '@types/mdast': 4.0.3 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-table@2.0.0: + dependencies: + '@types/mdast': 4.0.3 + devlop: 1.1.0 + markdown-table: 3.0.3 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-task-list-item@2.0.0: + dependencies: + '@types/mdast': 4.0.3 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm@3.0.0: + dependencies: + mdast-util-from-markdown: 2.0.2 + mdast-util-gfm-autolink-literal: 2.0.0 + mdast-util-gfm-footnote: 2.0.0 + mdast-util-gfm-strikethrough: 2.0.0 + mdast-util-gfm-table: 2.0.0 + mdast-util-gfm-task-list-item: 2.0.0 + mdast-util-to-markdown: 2.1.0 + transitivePeerDependencies: + - supports-color + + mdast-util-phrasing@4.1.0: + dependencies: + '@types/mdast': 4.0.3 + unist-util-is: 6.0.0 + + mdast-util-to-hast@13.1.0: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.3 + '@ungap/structured-clone': 1.2.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.0 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.1 + + mdast-util-to-hast@13.2.0: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.3 + '@ungap/structured-clone': 1.2.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.0 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.1 + + mdast-util-to-markdown@2.1.0: + dependencies: + '@types/mdast': 4.0.3 + '@types/unist': 3.0.2 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-string: 4.0.0 + micromark-util-decode-string: 2.0.0 + unist-util-visit: 5.0.0 + zwitch: 2.0.4 + + mdast-util-to-string@4.0.0: + dependencies: + '@types/mdast': 4.0.3 + + mdn-data@2.0.28: {} + + mdn-data@2.0.30: {} + + memorystream@0.3.1: {} + + merge-options@3.0.4: + dependencies: + is-plain-obj: 2.1.0 + + merge-stream@2.0.0: {} + + merge2@1.4.1: {} + + micro-api-client@3.3.0: {} + + micro-ftch@0.3.1: {} + + micromark-core-commonmark@2.0.1: + dependencies: + decode-named-character-reference: 1.0.2 + devlop: 1.1.0 + micromark-factory-destination: 2.0.0 + micromark-factory-label: 2.0.0 + micromark-factory-space: 2.0.0 + micromark-factory-title: 2.0.0 + micromark-factory-whitespace: 2.0.0 + micromark-util-character: 2.1.0 + micromark-util-chunked: 2.0.0 + micromark-util-classify-character: 2.0.0 + micromark-util-html-tag-name: 2.0.0 + micromark-util-normalize-identifier: 2.0.0 + micromark-util-resolve-all: 2.0.0 + micromark-util-subtokenize: 2.0.1 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + + micromark-factory-destination@2.0.0: + dependencies: + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + + micromark-factory-label@2.0.0: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + + micromark-factory-space@2.0.0: + dependencies: + micromark-util-character: 2.1.0 + micromark-util-types: 2.0.0 + + micromark-factory-title@2.0.0: + dependencies: + micromark-factory-space: 2.0.0 + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + + micromark-factory-whitespace@2.0.0: + dependencies: + micromark-factory-space: 2.0.0 + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + + micromark-util-character@2.1.0: + dependencies: + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + + micromark-util-chunked@2.0.0: + dependencies: + micromark-util-symbol: 2.0.0 + + micromark-util-classify-character@2.0.0: + dependencies: + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + + micromark-util-combine-extensions@2.0.0: + dependencies: + micromark-util-chunked: 2.0.0 + micromark-util-types: 2.0.0 + + micromark-util-decode-numeric-character-reference@2.0.1: + dependencies: + micromark-util-symbol: 2.0.0 + + micromark-util-decode-string@2.0.0: + dependencies: + decode-named-character-reference: 1.0.2 + micromark-util-character: 2.1.0 + micromark-util-decode-numeric-character-reference: 2.0.1 + micromark-util-symbol: 2.0.0 + + micromark-util-encode@2.0.0: {} + + micromark-util-html-tag-name@2.0.0: {} + + micromark-util-normalize-identifier@2.0.0: + dependencies: + micromark-util-symbol: 2.0.0 + + micromark-util-resolve-all@2.0.0: + dependencies: + micromark-util-types: 2.0.0 + + micromark-util-sanitize-uri@2.0.0: + dependencies: + micromark-util-character: 2.1.0 + micromark-util-encode: 2.0.0 + micromark-util-symbol: 2.0.0 + + micromark-util-subtokenize@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + + micromark-util-symbol@2.0.0: {} + + micromark-util-types@2.0.0: {} + + micromark@4.0.0: + dependencies: + '@types/debug': 4.1.7 + debug: 4.4.1 + decode-named-character-reference: 1.0.2 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.1 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.1.0 + micromark-util-chunked: 2.0.0 + micromark-util-combine-extensions: 2.0.0 + micromark-util-decode-numeric-character-reference: 2.0.1 + micromark-util-encode: 2.0.0 + micromark-util-normalize-identifier: 2.0.0 + micromark-util-resolve-all: 2.0.0 + micromark-util-sanitize-uri: 2.0.0 + micromark-util-subtokenize: 2.0.1 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + transitivePeerDependencies: + - supports-color + + micromatch@4.0.5: + dependencies: + braces: 3.0.2 + picomatch: 2.3.1 + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime-db@1.54.0: {} + + mime-types@3.0.1: + dependencies: + mime-db: 1.54.0 + + mime@3.0.0: {} + + mime@4.0.7: {} + + mimic-fn@2.1.0: {} + + mimic-fn@4.0.0: {} + + minimalistic-assert@1.0.1: {} + + minimalistic-crypto-utils@1.0.1: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@5.0.1: + dependencies: + brace-expansion: 2.0.1 + + minimatch@5.1.6: + dependencies: + brace-expansion: 2.0.1 + + minimatch@9.0.1: + dependencies: + brace-expansion: 2.0.1 + + minimatch@9.0.4: + dependencies: + brace-expansion: 2.0.1 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + minimist@1.2.8: {} + + minipass@3.3.6: + dependencies: + yallist: 4.0.0 + + minipass@5.0.0: {} + + minipass@7.1.2: {} + + minisearch@7.1.0: {} + + minizlib@2.1.2: + dependencies: + minipass: 3.3.6 + yallist: 4.0.0 + + minizlib@3.0.1: + dependencies: + minipass: 7.1.2 + rimraf: 5.0.10 + + minizlib@3.0.2: + dependencies: + minipass: 7.1.2 + + mipd@0.0.7(typescript@5.8.3): + optionalDependencies: + typescript: 5.8.3 + + mitt@3.0.1: {} + + mkdirp@1.0.4: {} + + mkdirp@3.0.1: {} + + mlly@1.7.0: + dependencies: + acorn: 8.11.3 + pathe: 1.1.2 + pkg-types: 1.3.1 + ufo: 1.6.1 + + mlly@1.7.4: + dependencies: + acorn: 8.14.1 + pathe: 2.0.3 + pkg-types: 1.3.1 + ufo: 1.6.1 + + mnemonist@0.38.5: + dependencies: + obliterator: 2.0.4 + + mocha@10.2.0: + dependencies: + ansi-colors: 4.1.1 + browser-stdout: 1.3.1 + chokidar: 3.5.3 + debug: 4.3.4(supports-color@8.1.1) + diff: 5.0.0 + escape-string-regexp: 4.0.0 + find-up: 5.0.0 + glob: 7.2.0 + he: 1.2.0 + js-yaml: 4.1.0 + log-symbols: 4.1.0 + minimatch: 5.0.1 + ms: 2.1.3 + nanoid: 3.3.3 + serialize-javascript: 6.0.0 + strip-json-comments: 3.1.1 + supports-color: 8.1.1 + workerpool: 6.2.1 + yargs: 16.2.0 + yargs-parser: 20.2.4 + yargs-unparser: 2.0.0 + + mocked-exports@0.1.1: {} + + module-definition@5.0.1: + dependencies: + ast-module-types: 5.0.0 + node-source-walk: 6.0.2 + + mri@1.2.0: {} + + mrmime@2.0.1: {} + + ms@2.1.2: {} + + ms@2.1.3: {} + + msw@2.4.9(typescript@5.8.3): + dependencies: + '@bundled-es-modules/cookie': 2.0.0 + '@bundled-es-modules/statuses': 1.0.1 + '@bundled-es-modules/tough-cookie': 0.1.6 + '@inquirer/confirm': 3.1.6 + '@mswjs/interceptors': 0.35.9 + '@open-draft/until': 2.1.0 + '@types/cookie': 0.6.0 + '@types/statuses': 2.0.4 + chalk: 4.1.2 + graphql: 16.8.1 + headers-polyfill: 4.0.2 + is-node-process: 1.2.0 + outvariant: 1.4.2 + path-to-regexp: 6.3.0 + strict-event-emitter: 0.5.1 + type-fest: 4.18.2 + yargs: 17.7.2 + optionalDependencies: + typescript: 5.8.3 + + muggle-string@0.4.1: {} + + multiformats@9.9.0: {} + + mute-stream@1.0.0: {} + + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + + nanoid@3.3.11: {} + + nanoid@3.3.3: {} + + nanoid@3.3.7: {} + + nanoid@5.1.5: {} + + nanospinner@1.2.2: + dependencies: + picocolors: 1.1.1 + + nanotar@0.2.0: {} + + nested-error-stacks@2.1.1: {} + + netlify@13.3.5: + dependencies: + '@netlify/open-api': 2.37.0 + lodash-es: 4.17.21 + micro-api-client: 3.3.0 + node-fetch: 3.3.2 + p-wait-for: 5.0.2 + qs: 6.14.0 + + next@15.3.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@next/env': 15.3.3 + '@swc/counter': 0.1.3 + '@swc/helpers': 0.5.15 + busboy: 1.6.0 + caniuse-lite: 1.0.30001723 + postcss: 8.4.31 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + styled-jsx: 5.1.6(react@18.3.1) + optionalDependencies: + '@next/swc-darwin-arm64': 15.3.3 + '@next/swc-darwin-x64': 15.3.3 + '@next/swc-linux-arm64-gnu': 15.3.3 + '@next/swc-linux-arm64-musl': 15.3.3 + '@next/swc-linux-x64-gnu': 15.3.3 + '@next/swc-linux-x64-musl': 15.3.3 + '@next/swc-win32-arm64-msvc': 15.3.3 + '@next/swc-win32-x64-msvc': 15.3.3 + sharp: 0.34.2 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + + nitropack@2.11.12(encoding@0.1.13)(idb-keyval@6.2.1): + dependencies: + '@cloudflare/kv-asset-handler': 0.4.0 + '@netlify/functions': 3.1.8(encoding@0.1.13)(rollup@4.41.0) + '@rollup/plugin-alias': 5.1.1(rollup@4.41.0) + '@rollup/plugin-commonjs': 28.0.3(rollup@4.41.0) + '@rollup/plugin-inject': 5.0.5(rollup@4.41.0) + '@rollup/plugin-json': 6.1.0(rollup@4.41.0) + '@rollup/plugin-node-resolve': 16.0.1(rollup@4.41.0) + '@rollup/plugin-replace': 6.0.2(rollup@4.41.0) + '@rollup/plugin-terser': 0.4.4(rollup@4.41.0) + '@vercel/nft': 0.29.3(encoding@0.1.13)(rollup@4.41.0) + archiver: 7.0.1 + c12: 3.0.4(magicast@0.3.5) + chokidar: 4.0.3 + citty: 0.1.6 + compatx: 0.2.0 + confbox: 0.2.2 + consola: 3.4.2 + cookie-es: 2.0.0 + croner: 9.0.0 + crossws: 0.3.5 + db0: 0.3.2 + defu: 6.1.4 + destr: 2.0.5 + dot-prop: 9.0.0 + esbuild: 0.25.5 + escape-string-regexp: 5.0.0 + etag: 1.8.1 + exsolve: 1.0.5 + globby: 14.1.0 + gzip-size: 7.0.0 + h3: 1.15.3 + hookable: 5.5.3 + httpxy: 0.1.7 + ioredis: 5.6.1 + jiti: 2.4.2 + klona: 2.0.6 + knitwork: 1.2.0 + listhen: 1.9.0 + magic-string: 0.30.17 + magicast: 0.3.5 + mime: 4.0.7 + mlly: 1.7.4 + node-fetch-native: 1.6.6 + node-mock-http: 1.0.0 + ofetch: 1.4.1 + ohash: 2.0.11 + pathe: 2.0.3 + perfect-debounce: 1.0.0 + pkg-types: 2.1.0 + pretty-bytes: 6.1.1 + radix3: 1.1.2 + rollup: 4.41.0 + rollup-plugin-visualizer: 5.14.0(rollup@4.41.0) + scule: 1.3.0 + semver: 7.7.2 + serve-placeholder: 2.0.2 + serve-static: 2.2.0 + source-map: 0.7.4 + std-env: 3.9.0 + ufo: 1.6.1 + ultrahtml: 1.6.0 + uncrypto: 0.1.3 + unctx: 2.4.1 + unenv: 2.0.0-rc.17 + unimport: 5.0.1 + unplugin-utils: 0.2.4 + unstorage: 1.16.0(db0@0.3.2)(idb-keyval@6.2.1)(ioredis@5.6.1) + untyped: 2.0.0 + unwasm: 0.3.9 + youch: 4.1.0-beta.7 + youch-core: 0.3.2 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@electric-sql/pglite' + - '@libsql/client' + - '@netlify/blobs' + - '@planetscale/database' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/kv' + - aws4fetch + - better-sqlite3 + - drizzle-orm + - encoding + - idb-keyval + - mysql2 + - rolldown + - sqlite3 + - supports-color + - uploadthing + + node-addon-api@2.0.2: {} + + node-addon-api@7.0.0: {} + + node-addon-api@7.1.1: {} + + node-domexception@1.0.0: {} + + node-emoji@2.1.3: + dependencies: + '@sindresorhus/is': 4.6.0 + char-regex: 1.0.2 + emojilib: 2.4.0 + skin-tone: 2.0.0 + + node-fetch-native@1.6.4: {} + + node-fetch-native@1.6.6: {} + + node-fetch@2.6.7(encoding@0.1.13): + dependencies: + whatwg-url: 5.0.0 + optionalDependencies: + encoding: 0.1.13 + + node-fetch@2.6.9(encoding@0.1.13): + dependencies: + whatwg-url: 5.0.0 + optionalDependencies: + encoding: 0.1.13 + + node-fetch@2.7.0(encoding@0.1.13): + dependencies: + whatwg-url: 5.0.0 + optionalDependencies: + encoding: 0.1.13 + + node-fetch@3.3.2: + dependencies: + data-uri-to-buffer: 4.0.1 + fetch-blob: 3.2.0 + formdata-polyfill: 4.0.10 + + node-forge@1.3.1: {} + + node-gyp-build@4.6.0: {} + + node-gyp-build@4.8.4: {} + + node-mock-http@1.0.0: {} + + node-releases@2.0.14: {} + + node-releases@2.0.19: {} + + node-source-walk@6.0.2: + dependencies: + '@babel/parser': 7.27.2 + + nopt@5.0.0: + dependencies: + abbrev: 1.1.1 + + nopt@7.2.1: + dependencies: + abbrev: 2.0.0 + + nopt@8.1.0: + dependencies: + abbrev: 3.0.1 + + normalize-package-data@6.0.2: + dependencies: + hosted-git-info: 7.0.2 + semver: 7.7.2 + validate-npm-package-license: 3.0.4 + + normalize-path@2.1.1: + dependencies: + remove-trailing-separator: 1.1.0 + + normalize-path@3.0.0: {} + + normalize-range@0.1.2: {} + + npm-run-path@4.0.1: + dependencies: + path-key: 3.1.1 + + npm-run-path@5.3.0: + dependencies: + path-key: 4.0.0 + + npm-run-path@6.0.0: + dependencies: + path-key: 4.0.0 + unicorn-magic: 0.3.0 + + npmlog@5.0.1: + dependencies: + are-we-there-yet: 2.0.0 + console-control-strings: 1.1.0 + gauge: 3.0.2 + set-blocking: 2.0.0 + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + nuxt@3.16.0(@biomejs/biome@1.9.4)(@parcel/watcher@2.5.1)(@types/node@24.0.1)(bufferutil@4.0.9)(db0@0.3.2)(encoding@0.1.13)(idb-keyval@6.2.1)(ioredis@5.6.1)(magicast@0.3.5)(rollup@4.41.0)(terser@5.39.2)(typescript@5.8.3)(utf-8-validate@6.0.5)(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0))(yaml@2.8.0): + dependencies: + '@nuxt/cli': 3.25.1(magicast@0.3.5) + '@nuxt/devalue': 2.0.2 + '@nuxt/devtools': 2.4.1(bufferutil@4.0.9)(utf-8-validate@6.0.5)(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.8.3)) + '@nuxt/kit': 3.16.0(magicast@0.3.5) + '@nuxt/schema': 3.16.0 + '@nuxt/telemetry': 2.6.6(magicast@0.3.5) + '@nuxt/vite-builder': 3.16.0(@biomejs/biome@1.9.4)(@types/node@24.0.1)(magicast@0.3.5)(rollup@4.41.0)(terser@5.39.2)(typescript@5.8.3)(vue@3.5.14(typescript@5.8.3))(yaml@2.8.0) + '@oxc-parser/wasm': 0.56.5 + '@unhead/vue': 2.0.9(vue@3.5.14(typescript@5.8.3)) + '@vue/shared': 3.5.14 + c12: 3.0.4(magicast@0.3.5) + chokidar: 4.0.3 + compatx: 0.1.8 + consola: 3.4.2 + cookie-es: 2.0.0 + defu: 6.1.4 + destr: 2.0.5 + devalue: 5.1.1 + errx: 0.1.0 + esbuild: 0.25.5 + escape-string-regexp: 5.0.0 + estree-walker: 3.0.3 + exsolve: 1.0.5 + globby: 14.1.0 + h3: 1.15.3 + hookable: 5.5.3 + ignore: 7.0.4 + impound: 0.2.2(rollup@4.41.0) + jiti: 2.4.2 + klona: 2.0.6 + knitwork: 1.2.0 + magic-string: 0.30.17 + mlly: 1.7.4 + nanotar: 0.2.0 + nitropack: 2.11.12(encoding@0.1.13)(idb-keyval@6.2.1) + nypm: 0.6.0 + ofetch: 1.4.1 + ohash: 2.0.11 + on-change: 5.0.1 + oxc-parser: 0.56.5 + pathe: 2.0.3 + perfect-debounce: 1.0.0 + pkg-types: 2.1.0 + radix3: 1.1.2 + scule: 1.3.0 + semver: 7.7.2 + std-env: 3.9.0 + strip-literal: 3.0.0 + tinyglobby: 0.2.12 + ufo: 1.6.1 + ultrahtml: 1.6.0 + uncrypto: 0.1.3 + unctx: 2.4.1 + unenv: 2.0.0-rc.17 + unimport: 4.2.0 + unplugin: 2.3.4 + unplugin-vue-router: 0.12.0(vue-router@4.5.1(vue@3.5.14(typescript@5.8.3)))(vue@3.5.14(typescript@5.8.3)) + unstorage: 1.16.0(db0@0.3.2)(idb-keyval@6.2.1)(ioredis@5.6.1) + untyped: 2.0.0 + vue: 3.5.14(typescript@5.8.3) + vue-bundle-renderer: 2.1.1 + vue-devtools-stub: 0.1.0 + vue-router: 4.5.1(vue@3.5.14(typescript@5.8.3)) + optionalDependencies: + '@parcel/watcher': 2.5.1 + '@types/node': 24.0.1 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@biomejs/biome' + - '@capacitor/preferences' + - '@deno/kv' + - '@electric-sql/pglite' + - '@libsql/client' + - '@netlify/blobs' + - '@planetscale/database' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/kv' + - aws4fetch + - better-sqlite3 + - bufferutil + - db0 + - drizzle-orm + - encoding + - eslint + - idb-keyval + - ioredis + - less + - lightningcss + - magicast + - meow + - mysql2 + - optionator + - rolldown + - rollup + - sass + - sass-embedded + - sqlite3 + - stylelint + - stylus + - sugarss + - supports-color + - terser + - tsx + - typescript + - uploadthing + - utf-8-validate + - vite + - vls + - vti + - vue-tsc + - xml2js + - yaml + + nypm@0.6.0: + dependencies: + citty: 0.1.6 + consola: 3.4.2 + pathe: 2.0.3 + pkg-types: 2.1.0 + tinyexec: 0.3.2 + + obj-multiplex@1.0.0: + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + readable-stream: 2.3.8 + + object-assign@4.1.1: {} + + object-inspect@1.13.4: {} + + obliterator@2.0.4: {} + + ofetch@1.4.1: + dependencies: + destr: 2.0.5 + node-fetch-native: 1.6.6 + ufo: 1.6.1 + + ohash@2.0.11: {} + + on-change@5.0.1: {} + + on-exit-leak-free@0.2.0: {} + + on-exit-leak-free@2.1.2: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + one-time@1.0.0: + dependencies: + fn.name: 1.1.0 + + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + + onetime@6.0.0: + dependencies: + mimic-fn: 4.0.0 + + oniguruma-to-js@0.4.3: + dependencies: + regex: 4.4.0 + + open@10.1.2: + dependencies: + default-browser: 5.2.1 + define-lazy-prop: 3.0.0 + is-inside-container: 1.0.0 + is-wsl: 3.1.0 + + open@8.4.2: + dependencies: + define-lazy-prop: 2.0.0 + is-docker: 2.2.1 + is-wsl: 2.2.0 + + opener@1.5.2: {} + + os-tmpdir@1.0.2: {} + + outdent@0.5.0: {} + + outvariant@1.4.2: {} + + outvariant@1.4.3: {} + + ox@0.6.7(typescript@5.8.3)(zod@3.25.20): + dependencies: + '@adraffy/ens-normalize': 1.11.0 + '@noble/curves': 1.8.1 + '@noble/hashes': 1.7.1 + '@scure/bip32': 1.6.2 + '@scure/bip39': 1.5.4 + abitype: 1.0.8(typescript@5.8.3)(zod@3.25.20) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - zod + + ox@0.6.9(typescript@5.8.3)(zod@3.22.4): + dependencies: + '@adraffy/ens-normalize': 1.11.0 + '@noble/curves': 1.8.2 + '@noble/hashes': 1.7.2 + '@scure/bip32': 1.6.2 + '@scure/bip39': 1.5.4 + abitype: 1.0.8(typescript@5.8.3)(zod@3.22.4) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - zod + + ox@0.6.9(typescript@5.8.3)(zod@3.25.20): + dependencies: + '@adraffy/ens-normalize': 1.11.0 + '@noble/curves': 1.8.2 + '@noble/hashes': 1.7.2 + '@scure/bip32': 1.6.2 + '@scure/bip39': 1.5.4 + abitype: 1.0.8(typescript@5.8.3)(zod@3.25.20) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - zod + + oxc-parser@0.56.5: + dependencies: + '@oxc-project/types': 0.56.5 + optionalDependencies: + '@oxc-parser/binding-darwin-arm64': 0.56.5 + '@oxc-parser/binding-darwin-x64': 0.56.5 + '@oxc-parser/binding-linux-arm-gnueabihf': 0.56.5 + '@oxc-parser/binding-linux-arm64-gnu': 0.56.5 + '@oxc-parser/binding-linux-arm64-musl': 0.56.5 + '@oxc-parser/binding-linux-x64-gnu': 0.56.5 + '@oxc-parser/binding-linux-x64-musl': 0.56.5 + '@oxc-parser/binding-wasm32-wasi': 0.56.5 + '@oxc-parser/binding-win32-arm64-msvc': 0.56.5 + '@oxc-parser/binding-win32-x64-msvc': 0.56.5 + + p-event@5.0.1: + dependencies: + p-timeout: 5.1.0 + + p-filter@2.1.0: + dependencies: + p-map: 2.1.0 + + p-limit@1.3.0: + dependencies: + p-try: 1.0.0 + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-limit@4.0.0: + dependencies: + yocto-queue: 1.2.1 + + p-locate@2.0.0: + dependencies: + p-limit: 1.3.0 + + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + p-locate@6.0.0: + dependencies: + p-limit: 4.0.0 + + p-map@2.1.0: {} + + p-map@4.0.0: + dependencies: + aggregate-error: 3.1.0 + + p-map@7.0.3: {} + + p-timeout@5.1.0: {} + + p-timeout@6.1.4: {} + + p-try@1.0.0: {} + + p-try@2.2.0: {} + + p-wait-for@5.0.2: + dependencies: + p-timeout: 6.1.4 + + package-json-from-dist@1.0.1: {} + + package-manager-detector@0.2.0: {} + + package-manager-detector@1.3.0: {} + + parse-gitignore@2.0.0: {} + + parse-json@8.3.0: + dependencies: + '@babel/code-frame': 7.27.1 + index-to-position: 1.1.0 + type-fest: 4.41.0 + + parse-ms@4.0.0: {} + + parse-path@7.1.0: + dependencies: + protocols: 2.0.2 + + parse-url@9.2.0: + dependencies: + '@types/parse-path': 7.1.0 + parse-path: 7.1.0 + + parse5-htmlparser2-tree-adapter@6.0.1: + dependencies: + parse5: 6.0.1 + + parse5@5.1.1: {} + + parse5@6.0.1: {} + + parseurl@1.3.3: {} + + path-browserify@1.0.1: {} + + path-exists@3.0.0: {} + + path-exists@4.0.0: {} + + path-exists@5.0.0: {} + + path-is-absolute@1.0.1: {} + + path-key@3.1.1: {} + + path-key@4.0.0: {} + + path-parse@1.0.7: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + + path-to-regexp@6.3.0: {} + + path-type@3.0.0: + dependencies: + pify: 3.0.0 + + path-type@4.0.0: {} + + path-type@6.0.0: {} + + pathe@1.1.2: {} + + pathe@2.0.3: {} + + pathval@2.0.0: {} + + pbkdf2@3.1.2: + dependencies: + create-hash: 1.2.0 + create-hmac: 1.1.7 + ripemd160: 2.0.2 + safe-buffer: 5.2.1 + sha.js: 2.4.11 + + pend@1.2.0: {} + + perfect-debounce@1.0.0: {} + + picocolors@1.0.0: {} + + picocolors@1.1.0: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + picomatch@4.0.2: {} + + pify@3.0.0: {} + + pify@4.0.1: {} + + pify@5.0.0: {} + + pino-abstract-transport@0.5.0: + dependencies: + duplexify: 4.1.2 + split2: 4.2.0 + + pino-abstract-transport@2.0.0: + dependencies: + split2: 4.2.0 + + pino-pretty@13.0.0: + dependencies: + colorette: 2.0.20 + dateformat: 4.6.3 + fast-copy: 3.0.2 + fast-safe-stringify: 2.1.1 + help-me: 5.0.0 + joycon: 3.1.1 + minimist: 1.2.8 + on-exit-leak-free: 2.1.2 + pino-abstract-transport: 2.0.0 + pump: 3.0.2 + secure-json-parse: 2.7.0 + sonic-boom: 4.2.0 + strip-json-comments: 3.1.1 + + pino-std-serializers@4.0.0: {} + + pino@7.11.0: + dependencies: + atomic-sleep: 1.0.0 + fast-redact: 3.1.2 + on-exit-leak-free: 0.2.0 + pino-abstract-transport: 0.5.0 + pino-std-serializers: 4.0.0 + process-warning: 1.0.0 + quick-format-unescaped: 4.0.4 + real-require: 0.1.0 + safe-stable-stringify: 2.4.3 + sonic-boom: 2.8.0 + thread-stream: 0.15.2 + + pkg-types@1.1.0: + dependencies: + confbox: 0.1.7 + mlly: 1.7.4 + pathe: 1.1.2 + + pkg-types@1.1.1: + dependencies: + confbox: 0.1.7 + mlly: 1.7.0 + pathe: 1.1.2 + + pkg-types@1.3.1: + dependencies: + confbox: 0.1.8 + mlly: 1.7.4 + pathe: 2.0.3 + + pkg-types@2.1.0: + dependencies: + confbox: 0.2.2 + exsolve: 1.0.5 + pathe: 2.0.3 + + pngjs@5.0.0: {} + + pony-cause@2.1.11: {} + + possible-typed-array-names@1.1.0: {} + + postcss-calc@10.1.1(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + postcss-selector-parser: 7.1.0 + postcss-value-parser: 4.2.0 + + postcss-colormin@7.0.3(postcss@8.5.3): + dependencies: + browserslist: 4.24.5 + caniuse-api: 3.0.0 + colord: 2.9.3 + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + + postcss-convert-values@7.0.5(postcss@8.5.3): + dependencies: + browserslist: 4.24.5 + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + + postcss-discard-comments@7.0.4(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + postcss-selector-parser: 7.1.0 + + postcss-discard-duplicates@7.0.2(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + + postcss-discard-empty@7.0.1(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + + postcss-discard-overridden@7.0.1(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + + postcss-merge-longhand@7.0.5(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + stylehacks: 7.0.5(postcss@8.5.3) + + postcss-merge-rules@7.0.5(postcss@8.5.3): + dependencies: + browserslist: 4.24.5 + caniuse-api: 3.0.0 + cssnano-utils: 5.0.1(postcss@8.5.3) + postcss: 8.5.3 + postcss-selector-parser: 7.1.0 + + postcss-minify-font-values@7.0.1(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + + postcss-minify-gradients@7.0.1(postcss@8.5.3): + dependencies: + colord: 2.9.3 + cssnano-utils: 5.0.1(postcss@8.5.3) + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + + postcss-minify-params@7.0.3(postcss@8.5.3): + dependencies: + browserslist: 4.24.5 + cssnano-utils: 5.0.1(postcss@8.5.3) + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + + postcss-minify-selectors@7.0.5(postcss@8.5.3): + dependencies: + cssesc: 3.0.0 + postcss: 8.5.3 + postcss-selector-parser: 7.1.0 + + postcss-normalize-charset@7.0.1(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + + postcss-normalize-display-values@7.0.1(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + + postcss-normalize-positions@7.0.1(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + + postcss-normalize-repeat-style@7.0.1(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + + postcss-normalize-string@7.0.1(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + + postcss-normalize-timing-functions@7.0.1(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + + postcss-normalize-unicode@7.0.3(postcss@8.5.3): + dependencies: + browserslist: 4.24.5 + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + + postcss-normalize-url@7.0.1(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + + postcss-normalize-whitespace@7.0.1(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + + postcss-ordered-values@7.0.2(postcss@8.5.3): + dependencies: + cssnano-utils: 5.0.1(postcss@8.5.3) + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + + postcss-reduce-initial@7.0.3(postcss@8.5.3): + dependencies: + browserslist: 4.24.5 + caniuse-api: 3.0.0 + postcss: 8.5.3 + + postcss-reduce-transforms@7.0.1(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + + postcss-selector-parser@7.1.0: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-svgo@7.0.2(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + svgo: 3.3.2 + + postcss-unique-selectors@7.0.4(postcss@8.5.3): + dependencies: + postcss: 8.5.3 + postcss-selector-parser: 7.1.0 + + postcss-value-parser@4.2.0: {} + + postcss-values-parser@6.0.2(postcss@8.5.5): + dependencies: + color-name: 1.1.4 + is-url-superb: 4.0.0 + postcss: 8.5.5 + quote-unquote: 1.0.0 + + postcss@8.4.31: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + postcss@8.4.47: + dependencies: + nanoid: 3.3.7 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + postcss@8.5.3: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + postcss@8.5.5: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + preact@10.17.1: {} + + preact@10.24.3: {} + + precinct@11.0.5: + dependencies: + '@dependents/detective-less': 4.1.0 + commander: 10.0.1 + detective-amd: 5.0.2 + detective-cjs: 5.0.1 + detective-es6: 4.0.1 + detective-postcss: 6.1.3 + detective-sass: 5.0.3 + detective-scss: 4.0.3 + detective-stylus: 4.0.0 + detective-typescript: 11.2.0 + module-definition: 5.0.1 + node-source-walk: 6.0.2 + transitivePeerDependencies: + - supports-color + + prettier@2.8.8: {} + + prettier@3.0.3: {} + + pretty-bytes@6.1.1: {} + + pretty-format@27.5.1: + dependencies: + ansi-regex: 5.0.1 + ansi-styles: 5.2.0 + react-is: 17.0.2 + + pretty-ms@9.0.0: + dependencies: + parse-ms: 4.0.0 + + process-nextick-args@2.0.1: {} + + process-warning@1.0.0: {} + + process@0.11.10: {} + + prompts@2.4.2: + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + + prool@0.0.23: + dependencies: + change-case: 5.4.4 + eventemitter3: 5.0.1 + execa: 9.1.0 + get-port: 7.1.0 + http-proxy: 1.18.1 + tar: 7.2.0 + transitivePeerDependencies: + - debug + + property-information@6.5.0: {} + + proto-list@1.2.4: {} + + protocols@2.0.2: {} + + proxy-compare@2.6.0: {} + + pseudomap@1.0.2: {} + + psl@1.9.0: {} + + publint@0.3.12: + dependencies: + '@publint/pack': 0.1.2 + package-manager-detector: 1.3.0 + picocolors: 1.1.1 + sade: 1.8.1 + + pump@3.0.2: + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + + punycode@2.3.1: {} + + qrcode@1.5.3: + dependencies: + dijkstrajs: 1.0.2 + encode-utf8: 1.0.3 + pngjs: 5.0.0 + yargs: 15.4.1 + + qs@6.14.0: + dependencies: + side-channel: 1.1.0 + + quansync@0.2.10: {} + + query-string@7.1.3: + dependencies: + decode-uri-component: 0.2.2 + filter-obj: 1.1.0 + split-on-first: 1.1.0 + strict-uri-encode: 2.0.0 + + querystringify@2.2.0: {} + + queue-microtask@1.2.3: {} + + quick-format-unescaped@4.0.4: {} + + quote-unquote@1.0.0: {} + + radix3@1.1.2: {} + + randombytes@2.1.0: + dependencies: + safe-buffer: 5.2.1 + + range-parser@1.2.1: {} + + raw-body@2.5.1: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + + rc9@2.1.2: + dependencies: + defu: 6.1.4 + destr: 2.0.5 + + react-dom@18.3.1(react@18.3.1): + dependencies: + loose-envify: 1.4.0 + react: 18.3.1 + scheduler: 0.23.2 + + react-is@17.0.2: {} + + react-refresh@0.14.0: {} + + react@18.3.1: + dependencies: + loose-envify: 1.4.0 + + read-package-up@11.0.0: + dependencies: + find-up-simple: 1.0.1 + read-pkg: 9.0.1 + type-fest: 4.41.0 + + read-pkg@9.0.1: + dependencies: + '@types/normalize-package-data': 2.4.4 + normalize-package-data: 6.0.2 + parse-json: 8.3.0 + type-fest: 4.41.0 + unicorn-magic: 0.1.0 + + read-yaml-file@1.1.0: + dependencies: + graceful-fs: 4.2.11 + js-yaml: 3.14.1 + pify: 4.0.1 + strip-bom: 3.0.0 + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + readable-stream@4.7.0: + dependencies: + abort-controller: 3.0.0 + buffer: 6.0.3 + events: 3.3.0 + process: 0.11.10 + string_decoder: 1.3.0 + + readdir-glob@1.1.3: + dependencies: + minimatch: 5.1.6 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + readdirp@4.1.2: {} + + real-require@0.1.0: {} + + redis-errors@1.2.0: {} + + redis-parser@3.0.0: + dependencies: + redis-errors: 1.2.0 + + regenerator-runtime@0.14.0: {} + + regex@4.4.0: {} + + remove-accents@0.5.0: {} + + remove-trailing-separator@1.1.0: {} + + require-directory@2.1.1: {} + + require-from-string@2.0.2: {} + + require-main-filename@2.0.0: {} + + require-package-name@2.0.1: {} + + requires-port@1.0.0: {} + + resolve-from@5.0.0: {} + + resolve@1.17.0: + dependencies: + path-parse: 1.0.7 + + resolve@1.22.10: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + resolve@2.0.0-next.5: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + reusify@1.0.4: {} + + rfdc@1.4.1: {} + + rimraf@2.7.1: + dependencies: + glob: 7.2.3 + + rimraf@3.0.2: + dependencies: + glob: 7.2.3 + + rimraf@5.0.10: + dependencies: + glob: 10.4.5 + + ripemd160@2.0.2: + dependencies: + hash-base: 3.1.0 + inherits: 2.0.4 + + rlp@2.2.7: + dependencies: + bn.js: 5.2.1 + + rollup-plugin-visualizer@5.14.0(rollup@4.41.0): + dependencies: + open: 8.4.2 + picomatch: 4.0.2 + source-map: 0.7.4 + yargs: 17.7.2 + optionalDependencies: + rollup: 4.41.0 + + rollup@4.41.0: + dependencies: + '@types/estree': 1.0.7 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.41.0 + '@rollup/rollup-android-arm64': 4.41.0 + '@rollup/rollup-darwin-arm64': 4.41.0 + '@rollup/rollup-darwin-x64': 4.41.0 + '@rollup/rollup-freebsd-arm64': 4.41.0 + '@rollup/rollup-freebsd-x64': 4.41.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.41.0 + '@rollup/rollup-linux-arm-musleabihf': 4.41.0 + '@rollup/rollup-linux-arm64-gnu': 4.41.0 + '@rollup/rollup-linux-arm64-musl': 4.41.0 + '@rollup/rollup-linux-loongarch64-gnu': 4.41.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.41.0 + '@rollup/rollup-linux-riscv64-gnu': 4.41.0 + '@rollup/rollup-linux-riscv64-musl': 4.41.0 + '@rollup/rollup-linux-s390x-gnu': 4.41.0 + '@rollup/rollup-linux-x64-gnu': 4.41.0 + '@rollup/rollup-linux-x64-musl': 4.41.0 + '@rollup/rollup-win32-arm64-msvc': 4.41.0 + '@rollup/rollup-win32-ia32-msvc': 4.41.0 + '@rollup/rollup-win32-x64-msvc': 4.41.0 + fsevents: 2.3.3 + + run-applescript@7.0.0: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + sade@1.8.1: + dependencies: + mri: 1.2.0 + + safe-buffer@5.1.2: {} + + safe-buffer@5.2.1: {} + + safe-regex-test@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-regex: 1.2.1 + + safe-stable-stringify@2.4.3: {} + + safe-stable-stringify@2.5.0: {} + + safer-buffer@2.1.2: {} + + scheduler@0.23.2: + dependencies: + loose-envify: 1.4.0 + + scrypt-js@3.0.1: {} + + scule@1.3.0: {} + + secp256k1@4.0.3: + dependencies: + elliptic: 6.6.1 + node-addon-api: 2.0.2 + node-gyp-build: 4.8.4 + + secure-json-parse@2.7.0: {} + + semver@5.7.1: {} + + semver@6.3.1: {} + + semver@7.5.4: + dependencies: + lru-cache: 6.0.0 + + semver@7.6.2: {} + + semver@7.7.2: {} + + send@1.2.0: + dependencies: + debug: 4.4.1 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 2.0.0 + http-errors: 2.0.0 + mime-types: 3.0.1 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + + serialize-javascript@6.0.0: + dependencies: + randombytes: 2.1.0 + + serialize-javascript@6.0.2: + dependencies: + randombytes: 2.1.0 + + serve-placeholder@2.0.2: + dependencies: + defu: 6.1.4 + + serve-static@2.2.0: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 1.2.0 + transitivePeerDependencies: + - supports-color + + set-blocking@2.0.0: {} + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + setimmediate@1.0.5: {} + + setprototypeof@1.2.0: {} + + sha.js@2.4.11: + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + + sharp@0.34.2: + dependencies: + color: 4.2.3 + detect-libc: 2.0.4 + semver: 7.7.2 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.34.2 + '@img/sharp-darwin-x64': 0.34.2 + '@img/sharp-libvips-darwin-arm64': 1.1.0 + '@img/sharp-libvips-darwin-x64': 1.1.0 + '@img/sharp-libvips-linux-arm': 1.1.0 + '@img/sharp-libvips-linux-arm64': 1.1.0 + '@img/sharp-libvips-linux-ppc64': 1.1.0 + '@img/sharp-libvips-linux-s390x': 1.1.0 + '@img/sharp-libvips-linux-x64': 1.1.0 + '@img/sharp-libvips-linuxmusl-arm64': 1.1.0 + '@img/sharp-libvips-linuxmusl-x64': 1.1.0 + '@img/sharp-linux-arm': 0.34.2 + '@img/sharp-linux-arm64': 0.34.2 + '@img/sharp-linux-s390x': 0.34.2 + '@img/sharp-linux-x64': 0.34.2 + '@img/sharp-linuxmusl-arm64': 0.34.2 + '@img/sharp-linuxmusl-x64': 0.34.2 + '@img/sharp-wasm32': 0.34.2 + '@img/sharp-win32-arm64': 0.34.2 + '@img/sharp-win32-ia32': 0.34.2 + '@img/sharp-win32-x64': 0.34.2 + optional: true + + shebang-command@1.2.0: + dependencies: + shebang-regex: 1.0.0 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@1.0.0: {} + + shebang-regex@3.0.0: {} + + shell-quote@1.8.2: {} + + sherif-darwin-arm64@1.0.0: + optional: true + + sherif-darwin-x64@1.0.0: + optional: true + + sherif-linux-arm64@1.0.0: + optional: true + + sherif-linux-x64@1.0.0: + optional: true + + sherif-windows-arm64@1.0.0: + optional: true + + sherif-windows-x64@1.0.0: + optional: true + + sherif@1.0.0: + optionalDependencies: + sherif-darwin-arm64: 1.0.0 + sherif-darwin-x64: 1.0.0 + sherif-linux-arm64: 1.0.0 + sherif-linux-x64: 1.0.0 + sherif-windows-arm64: 1.0.0 + sherif-windows-x64: 1.0.0 + + shiki@1.22.2: + dependencies: + '@shikijs/core': 1.22.2 + '@shikijs/engine-javascript': 1.22.2 + '@shikijs/engine-oniguruma': 1.22.2 + '@shikijs/types': 1.22.2 + '@shikijs/vscode-textmate': 9.3.0 + '@types/hast': 3.0.4 + + side-channel-list@1.0.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + siginfo@2.0.0: {} + + signal-exit@3.0.7: {} + + signal-exit@4.1.0: {} + + simple-git-hooks@2.11.1: {} + + simple-git@3.27.0: + dependencies: + '@kwsites/file-exists': 1.1.1 + '@kwsites/promise-deferred': 1.1.1 + debug: 4.4.1 + transitivePeerDependencies: + - supports-color + + simple-swizzle@0.2.2: + dependencies: + is-arrayish: 0.3.2 + + sirv@2.0.4: + dependencies: + '@polka/url': 1.0.0-next.29 + mrmime: 2.0.1 + totalist: 3.0.1 + + sirv@3.0.1: + dependencies: + '@polka/url': 1.0.0-next.29 + mrmime: 2.0.1 + totalist: 3.0.1 + + sisteransi@1.0.5: {} + + skin-tone@2.0.0: + dependencies: + unicode-emoji-modifier-base: 1.0.0 + + slash@1.0.0: {} + + slash@3.0.0: {} + + slash@5.1.0: {} + + smob@1.5.0: {} + + smol-toml@1.3.0: {} + + socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10): + dependencies: + '@socket.io/component-emitter': 3.1.2 + debug: 4.3.7 + engine.io-client: 6.6.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + socket.io-parser: 4.2.4 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + socket.io-parser@4.2.4: + dependencies: + '@socket.io/component-emitter': 3.1.2 + debug: 4.3.7 + transitivePeerDependencies: + - supports-color + + solc@0.7.3(debug@4.3.4): + dependencies: + command-exists: 1.2.9 + commander: 3.0.2 + follow-redirects: 1.15.2(debug@4.3.4) + fs-extra: 0.30.0 + js-sha3: 0.8.0 + memorystream: 0.3.1 + require-from-string: 2.0.2 + semver: 5.7.1 + tmp: 0.0.33 + transitivePeerDependencies: + - debug + + sonic-boom@2.8.0: + dependencies: + atomic-sleep: 1.0.0 + + sonic-boom@4.2.0: + dependencies: + atomic-sleep: 1.0.0 + + source-map-js@1.2.0: {} + + source-map-js@1.2.1: {} + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.6.1: {} + + source-map@0.7.4: {} + + space-separated-tokens@2.0.2: {} + + spawndamnit@2.0.0: + dependencies: + cross-spawn: 5.1.0 + signal-exit: 3.0.7 + + spdx-correct@3.2.0: + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.21 + + spdx-exceptions@2.5.0: {} + + spdx-expression-parse@3.0.1: + dependencies: + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.21 + + spdx-license-ids@3.0.21: {} + + speakingurl@14.0.1: {} + + split-on-first@1.1.0: {} + + split2@4.2.0: {} + + sprintf-js@1.0.3: {} + + stack-trace@0.0.10: {} + + stackback@0.0.2: {} + + stacktrace-parser@0.1.10: + dependencies: + type-fest: 0.7.1 + + standard-as-callback@2.1.0: {} + + statuses@2.0.1: {} + + std-env@3.7.0: {} + + std-env@3.9.0: {} + + stream-shift@1.0.1: {} + + streamsearch@1.1.0: {} + + streamx@2.22.0: + dependencies: + fast-fifo: 1.3.2 + text-decoder: 1.2.3 + optionalDependencies: + bare-events: 2.5.4 + + strict-event-emitter@0.5.1: {} + + strict-uri-encode@2.0.0: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.1.0 + + strip-bom@3.0.0: {} + + strip-final-newline@2.0.0: {} + + strip-final-newline@3.0.0: {} + + strip-final-newline@4.0.0: {} + + strip-hex-prefix@1.0.0: + dependencies: + is-hex-prefixed: 1.0.0 + + strip-json-comments@3.1.1: {} + + strip-json-comments@5.0.1: {} + + strip-literal@1.3.0: + dependencies: + acorn: 8.11.3 + + strip-literal@3.0.0: + dependencies: + js-tokens: 9.0.1 + + structured-clone-es@1.0.0: {} + + styled-jsx@5.1.6(react@18.3.1): + dependencies: + client-only: 0.0.1 + react: 18.3.1 + + stylehacks@7.0.5(postcss@8.5.3): + dependencies: + browserslist: 4.24.5 + postcss: 8.5.3 + postcss-selector-parser: 7.1.0 + + summary@2.1.0: {} + + superjson@2.2.1: + dependencies: + copy-anything: 3.0.5 + + superjson@2.2.2: + dependencies: + copy-anything: 3.0.5 + + superstruct@1.0.3: {} + + supports-color@10.0.0: {} + + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + + supports-color@9.4.0: {} + + supports-hyperlinks@3.0.0: + dependencies: + has-flag: 4.0.0 + supports-color: 7.2.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + svgo@3.3.2: + dependencies: + '@trysound/sax': 0.2.0 + commander: 7.2.0 + css-select: 5.1.0 + css-tree: 2.3.1 + css-what: 6.1.0 + csso: 5.0.5 + picocolors: 1.1.1 + + system-architecture@0.1.0: {} + + tabbable@6.2.0: {} + + tapable@2.2.1: {} + + tapable@2.2.2: {} + + tar-stream@2.2.0: + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.4 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 + + tar-stream@3.1.7: + dependencies: + b4a: 1.6.7 + fast-fifo: 1.3.2 + streamx: 2.22.0 + + tar@6.2.1: + dependencies: + chownr: 2.0.0 + fs-minipass: 2.1.0 + minipass: 5.0.0 + minizlib: 2.1.2 + mkdirp: 1.0.4 + yallist: 4.0.0 + + tar@7.2.0: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.2 + minizlib: 3.0.1 + mkdirp: 3.0.1 + yallist: 5.0.0 + + tar@7.4.3: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.2 + minizlib: 3.0.2 + mkdirp: 3.0.1 + yallist: 5.0.0 + + temp-dir@1.0.0: {} + + tempy@0.2.1: + dependencies: + temp-dir: 1.0.0 + unique-string: 1.0.0 + + term-size@2.2.1: {} + + terser@5.39.2: + dependencies: + '@jridgewell/source-map': 0.3.6 + acorn: 8.15.0 + commander: 2.20.3 + source-map-support: 0.5.21 + + test-exclude@7.0.1: + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 10.4.5 + minimatch: 9.0.4 + + text-decoder@1.2.3: + dependencies: + b4a: 1.6.7 + + text-hex@1.0.0: {} + + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + + thread-stream@0.15.2: + dependencies: + real-require: 0.1.0 + + tiny-invariant@1.3.3: {} + + tinybench@2.9.0: {} + + tinyexec@0.3.2: {} + + tinyexec@1.0.1: {} + + tinyglobby@0.2.12: + dependencies: + fdir: 6.4.4(picomatch@4.0.2) + picomatch: 4.0.2 + + tinyglobby@0.2.13: + dependencies: + fdir: 6.4.4(picomatch@4.0.2) + picomatch: 4.0.2 + + tinypool@1.0.2: {} + + tinyrainbow@1.2.0: {} + + tinyspy@3.0.2: {} + + tmp-promise@3.0.3: + dependencies: + tmp: 0.2.3 + + tmp@0.0.33: + dependencies: + os-tmpdir: 1.0.2 + + tmp@0.2.3: {} + + to-fast-properties@2.0.0: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + toidentifier@1.0.1: {} + + toml@3.0.0: {} + + totalist@3.0.1: {} + + tough-cookie@4.1.4: + dependencies: + psl: 1.9.0 + punycode: 2.3.1 + universalify: 0.2.0 + url-parse: 1.5.10 + + tr46@0.0.3: {} + + trim-lines@3.0.1: {} + + triple-beam@1.4.1: {} + + tslib@1.14.1: {} + + tslib@2.8.1: {} + + tsort@0.0.1: {} + + tsutils@3.21.0(typescript@5.8.3): + dependencies: + tslib: 1.14.1 + typescript: 5.8.3 + + tweetnacl-util@0.15.1: {} + + tweetnacl@1.0.3: {} + + twoslash-protocol@0.2.12: {} + + twoslash-vue@0.2.12(typescript@5.8.3): + dependencies: + '@vue/language-core': 2.1.10(typescript@5.8.3) + twoslash: 0.2.12(typescript@5.8.3) + twoslash-protocol: 0.2.12 + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + twoslash@0.2.12(typescript@5.8.3): + dependencies: + '@typescript/vfs': 1.6.0(typescript@5.8.3) + twoslash-protocol: 0.2.12 + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + type-fest@0.20.2: {} + + type-fest@0.21.3: {} + + type-fest@0.7.1: {} + + type-fest@4.18.2: {} + + type-fest@4.41.0: {} + + typescript@5.6.1-rc: {} + + typescript@5.8.3: {} + + ufo@1.5.3: {} + + ufo@1.6.1: {} + + uint8arrays@3.1.0: + dependencies: + multiformats: 9.9.0 + + uint8arrays@3.1.1: + dependencies: + multiformats: 9.9.0 + + ultrahtml@1.6.0: {} + + unconfig@0.3.13: + dependencies: + '@antfu/utils': 0.7.7 + defu: 6.1.4 + jiti: 1.21.7 + + uncrypto@0.1.3: {} + + unctx@2.4.1: + dependencies: + acorn: 8.14.1 + estree-walker: 3.0.3 + magic-string: 0.30.17 + unplugin: 2.3.4 + + undici-types@5.26.5: {} + + undici-types@6.21.0: {} + + undici-types@7.8.0: {} + + undici@5.28.3: + dependencies: + '@fastify/busboy': 2.1.0 + + unenv@2.0.0-rc.17: + dependencies: + defu: 6.1.4 + exsolve: 1.0.5 + ohash: 2.0.11 + pathe: 2.0.3 + ufo: 1.6.1 + + unhead@2.0.9: + dependencies: + hookable: 5.5.3 + + unicode-emoji-modifier-base@1.0.0: {} + + unicorn-magic@0.1.0: {} + + unicorn-magic@0.3.0: {} + + unimport@3.7.1(rollup@4.41.0): + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@4.41.0) + acorn: 8.11.3 + escape-string-regexp: 5.0.0 + estree-walker: 3.0.3 + fast-glob: 3.3.2 + local-pkg: 0.5.0 + magic-string: 0.30.10 + mlly: 1.7.0 + pathe: 1.1.2 + pkg-types: 1.1.0 + scule: 1.3.0 + strip-literal: 1.3.0 + unplugin: 1.10.1 + transitivePeerDependencies: + - rollup + + unimport@4.2.0: + dependencies: + acorn: 8.14.1 + escape-string-regexp: 5.0.0 + estree-walker: 3.0.3 + local-pkg: 1.1.1 + magic-string: 0.30.17 + mlly: 1.7.4 + pathe: 2.0.3 + picomatch: 4.0.2 + pkg-types: 2.1.0 + scule: 1.3.0 + strip-literal: 3.0.0 + tinyglobby: 0.2.13 + unplugin: 2.3.4 + unplugin-utils: 0.2.4 + + unimport@5.0.1: + dependencies: + acorn: 8.14.1 + escape-string-regexp: 5.0.0 + estree-walker: 3.0.3 + local-pkg: 1.1.1 + magic-string: 0.30.17 + mlly: 1.7.4 + pathe: 2.0.3 + picomatch: 4.0.2 + pkg-types: 2.1.0 + scule: 1.3.0 + strip-literal: 3.0.0 + tinyglobby: 0.2.13 + unplugin: 2.3.4 + unplugin-utils: 0.2.4 + + unique-string@1.0.0: + dependencies: + crypto-random-string: 1.0.0 + + unist-util-is@6.0.0: + dependencies: + '@types/unist': 3.0.2 + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.2 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.2 + + unist-util-visit-parents@6.0.1: + dependencies: + '@types/unist': 3.0.2 + unist-util-is: 6.0.0 + + unist-util-visit@5.0.0: + dependencies: + '@types/unist': 3.0.2 + unist-util-is: 6.0.0 + unist-util-visit-parents: 6.0.1 + + universalify@0.1.2: {} + + universalify@0.2.0: {} + + unixify@1.0.0: + dependencies: + normalize-path: 2.1.1 + + unocss@0.59.4(rollup@4.41.0): + dependencies: + '@unocss/astro': 0.59.4(rollup@4.41.0) + '@unocss/cli': 0.59.4(rollup@4.41.0) + '@unocss/core': 0.59.4 + '@unocss/extractor-arbitrary-variants': 0.59.4 + '@unocss/postcss': 0.59.4 + '@unocss/preset-attributify': 0.59.4 + '@unocss/preset-icons': 0.59.4 + '@unocss/preset-mini': 0.59.4 + '@unocss/preset-tagify': 0.59.4 + '@unocss/preset-typography': 0.59.4 + '@unocss/preset-uno': 0.59.4 + '@unocss/preset-web-fonts': 0.59.4 + '@unocss/preset-wind': 0.59.4 + '@unocss/reset': 0.59.4 + '@unocss/transformer-attributify-jsx': 0.59.4 + '@unocss/transformer-attributify-jsx-babel': 0.59.4 + '@unocss/transformer-compile-class': 0.59.4 + '@unocss/transformer-directives': 0.59.4 + '@unocss/transformer-variant-group': 0.59.4 + '@unocss/vite': 0.59.4(rollup@4.41.0) + transitivePeerDependencies: + - rollup + - supports-color + + unpipe@1.0.0: {} + + unplugin-utils@0.2.4: + dependencies: + pathe: 2.0.3 + picomatch: 4.0.2 + + unplugin-vue-router@0.12.0(vue-router@4.5.1(vue@3.5.14(typescript@5.8.3)))(vue@3.5.14(typescript@5.8.3)): + dependencies: + '@babel/types': 7.27.1 + '@vue-macros/common': 1.16.1(vue@3.5.14(typescript@5.8.3)) + ast-walker-scope: 0.6.2 + chokidar: 4.0.3 + fast-glob: 3.3.3 + json5: 2.2.3 + local-pkg: 1.1.1 + magic-string: 0.30.17 + micromatch: 4.0.8 + mlly: 1.7.4 + pathe: 2.0.3 + scule: 1.3.0 + unplugin: 2.3.4 + unplugin-utils: 0.2.4 + yaml: 2.8.0 + optionalDependencies: + vue-router: 4.5.1(vue@3.5.14(typescript@5.8.3)) + transitivePeerDependencies: + - vue + + unplugin@1.10.1: + dependencies: + acorn: 8.11.3 + chokidar: 3.6.0 + webpack-sources: 3.2.3 + webpack-virtual-modules: 0.6.1 + + unplugin@1.16.1: + dependencies: + acorn: 8.15.0 + webpack-virtual-modules: 0.6.2 + + unplugin@2.3.4: + dependencies: + acorn: 8.14.1 + picomatch: 4.0.2 + webpack-virtual-modules: 0.6.2 + + unstorage@1.10.2(idb-keyval@6.2.1)(ioredis@5.6.1): + dependencies: + anymatch: 3.1.3 + chokidar: 3.6.0 + destr: 2.0.5 + h3: 1.15.3 + listhen: 1.7.2 + lru-cache: 10.2.2 + mri: 1.2.0 + node-fetch-native: 1.6.4 + ofetch: 1.4.1 + ufo: 1.6.1 + optionalDependencies: + idb-keyval: 6.2.1 + ioredis: 5.6.1 + transitivePeerDependencies: + - uWebSockets.js + + unstorage@1.16.0(db0@0.3.2)(idb-keyval@6.2.1)(ioredis@5.6.1): + dependencies: + anymatch: 3.1.3 + chokidar: 4.0.3 + destr: 2.0.5 + h3: 1.15.3 + lru-cache: 10.4.3 + node-fetch-native: 1.6.6 + ofetch: 1.4.1 + ufo: 1.6.1 + optionalDependencies: + db0: 0.3.2 + idb-keyval: 6.2.1 + ioredis: 5.6.1 + + untun@0.1.3: + dependencies: + citty: 0.1.6 + consola: 3.4.2 + pathe: 1.1.2 + + untyped@1.4.2: + dependencies: + '@babel/core': 7.24.5 + '@babel/standalone': 7.24.5 + '@babel/types': 7.24.5 + defu: 6.1.4 + jiti: 1.21.0 + mri: 1.2.0 + scule: 1.3.0 + transitivePeerDependencies: + - supports-color + + untyped@2.0.0: + dependencies: + citty: 0.1.6 + defu: 6.1.4 + jiti: 2.4.2 + knitwork: 1.2.0 + scule: 1.3.0 + + unwasm@0.3.9: + dependencies: + knitwork: 1.2.0 + magic-string: 0.30.17 + mlly: 1.7.4 + pathe: 1.1.2 + pkg-types: 1.3.1 + unplugin: 1.16.1 + + update-browserslist-db@1.0.15(browserslist@4.23.0): + dependencies: + browserslist: 4.23.0 + escalade: 3.2.0 + picocolors: 1.1.1 + + update-browserslist-db@1.1.3(browserslist@4.24.5): + dependencies: + browserslist: 4.24.5 + escalade: 3.2.0 + picocolors: 1.1.1 + + uqr@0.1.2: {} + + url-parse@1.5.10: + dependencies: + querystringify: 2.2.0 + requires-port: 1.0.0 + + urlpattern-polyfill@10.1.0: {} + + urlpattern-polyfill@8.0.2: {} + + use-sync-external-store@1.2.0(react@18.3.1): + dependencies: + react: 18.3.1 + + use-sync-external-store@1.4.0(react@18.3.1): + dependencies: + react: 18.3.1 + + utf-8-validate@5.0.10: + dependencies: + node-gyp-build: 4.8.4 + + utf-8-validate@6.0.5: + dependencies: + node-gyp-build: 4.8.4 + + util-deprecate@1.0.2: {} + + util@0.12.5: + dependencies: + inherits: 2.0.4 + is-arguments: 1.2.0 + is-generator-function: 1.1.0 + is-typed-array: 1.1.15 + which-typed-array: 1.1.19 + + uuid@11.1.0: {} + + uuid@8.3.2: {} + + uuid@9.0.1: {} + + validate-npm-package-license@3.0.4: + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + + validate-npm-package-name@5.0.1: {} + + valtio@1.13.2(@types/react@18.3.1)(react@18.3.1): + dependencies: + derive-valtio: 0.1.0(valtio@1.13.2(@types/react@18.3.1)(react@18.3.1)) + proxy-compare: 2.6.0 + use-sync-external-store: 1.2.0(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.1 + react: 18.3.1 + + vfile-message@4.0.2: + dependencies: + '@types/unist': 3.0.2 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.1: + dependencies: + '@types/unist': 3.0.2 + unist-util-stringify-position: 4.0.0 + vfile-message: 4.0.2 + + viem@2.10.8(bufferutil@4.0.8)(typescript@5.8.3)(utf-8-validate@6.0.5)(zod@3.25.20): + dependencies: + '@adraffy/ens-normalize': 1.10.0 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@scure/bip32': 1.3.2 + '@scure/bip39': 1.2.1 + abitype: 1.0.0(typescript@5.8.3)(zod@3.25.20) + isows: 1.0.4(ws@8.13.0(bufferutil@4.0.8)(utf-8-validate@6.0.5)) + ws: 8.13.0(bufferutil@4.0.8)(utf-8-validate@6.0.5) + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + viem@2.10.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@6.0.5)(zod@3.25.20): + dependencies: + '@adraffy/ens-normalize': 1.10.0 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@scure/bip32': 1.3.2 + '@scure/bip39': 1.2.1 + abitype: 1.0.0(typescript@5.8.3)(zod@3.25.20) + isows: 1.0.4(ws@8.13.0(bufferutil@4.0.9)(utf-8-validate@6.0.5)) + ws: 8.13.0(bufferutil@4.0.9)(utf-8-validate@6.0.5) + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + viem@2.17.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20): + dependencies: + '@adraffy/ens-normalize': 1.10.0 + '@noble/curves': 1.4.0 + '@noble/hashes': 1.4.0 + '@scure/bip32': 1.4.0 + '@scure/bip39': 1.3.0 + abitype: 1.0.5(typescript@5.8.3)(zod@3.25.20) + isows: 1.0.4(ws@8.17.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + ws: 8.17.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + viem@2.23.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20): + dependencies: + '@noble/curves': 1.8.1 + '@noble/hashes': 1.7.1 + '@scure/bip32': 1.6.2 + '@scure/bip39': 1.5.4 + abitype: 1.0.8(typescript@5.8.3)(zod@3.25.20) + isows: 1.0.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + ox: 0.6.7(typescript@5.8.3)(zod@3.25.20) + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + viem@2.29.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4): + dependencies: + '@noble/curves': 1.8.2 + '@noble/hashes': 1.7.2 + '@scure/bip32': 1.6.2 + '@scure/bip39': 1.5.4 + abitype: 1.0.8(typescript@5.8.3)(zod@3.22.4) + isows: 1.0.6(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + ox: 0.6.9(typescript@5.8.3)(zod@3.22.4) + ws: 8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + viem@2.29.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.20): + dependencies: + '@noble/curves': 1.8.2 + '@noble/hashes': 1.7.2 + '@scure/bip32': 1.6.2 + '@scure/bip39': 1.5.4 + abitype: 1.0.8(typescript@5.8.3)(zod@3.25.20) + isows: 1.0.6(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + ox: 0.6.9(typescript@5.8.3)(zod@3.25.20) + ws: 8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + viem@2.29.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@6.0.5)(zod@3.25.20): + dependencies: + '@noble/curves': 1.8.2 + '@noble/hashes': 1.7.2 + '@scure/bip32': 1.6.2 + '@scure/bip39': 1.5.4 + abitype: 1.0.8(typescript@5.8.3)(zod@3.25.20) + isows: 1.0.6(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@6.0.5)) + ox: 0.6.9(typescript@5.8.3)(zod@3.25.20) + ws: 8.18.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + vite-dev-rpc@1.0.7(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0)): + dependencies: + birpc: 2.3.0 + vite: 6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0) + vite-hot-client: 2.0.4(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0)) + + vite-hot-client@2.0.4(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0)): + dependencies: + vite: 6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0) + + vite-node@2.1.9(@types/node@24.0.1)(terser@5.39.2): + dependencies: + cac: 6.7.14 + debug: 4.4.1 + es-module-lexer: 1.7.0 + pathe: 1.1.2 + vite: 5.4.19(@types/node@24.0.1)(terser@5.39.2) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + vite-node@3.1.4(@types/node@24.0.1)(terser@5.39.2): + dependencies: + cac: 6.7.14 + debug: 4.4.1 + es-module-lexer: 1.7.0 + pathe: 2.0.3 + vite: 5.4.19(@types/node@24.0.1)(terser@5.39.2) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + vite-plugin-checker@0.9.3(@biomejs/biome@1.9.4)(typescript@5.8.3)(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0)): + dependencies: + '@babel/code-frame': 7.27.1 + chokidar: 4.0.3 + npm-run-path: 6.0.0 + picocolors: 1.1.1 + picomatch: 4.0.2 + strip-ansi: 7.1.0 + tiny-invariant: 1.3.3 + tinyglobby: 0.2.13 + vite: 6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0) + vscode-uri: 3.1.0 + optionalDependencies: + '@biomejs/biome': 1.9.4 + typescript: 5.8.3 + + vite-plugin-inspect@11.1.0(@nuxt/kit@3.17.4(magicast@0.3.5))(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0)): + dependencies: + ansis: 3.17.0 + debug: 4.4.1 + error-stack-parser-es: 1.0.5 + ohash: 2.0.11 + open: 10.1.2 + perfect-debounce: 1.0.0 + sirv: 3.0.1 + unplugin-utils: 0.2.4 + vite: 6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0) + vite-dev-rpc: 1.0.7(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0)) + optionalDependencies: + '@nuxt/kit': 3.17.4(magicast@0.3.5) + transitivePeerDependencies: + - supports-color + + vite-plugin-vue-tracer@0.1.3(vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.8.3)): + dependencies: + estree-walker: 3.0.3 + exsolve: 1.0.5 + magic-string: 0.30.17 + pathe: 2.0.3 + source-map-js: 1.2.1 + vite: 6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0) + vue: 3.5.14(typescript@5.8.3) + + vite@5.4.19(@types/node@24.0.1)(terser@5.39.2): + dependencies: + esbuild: 0.21.5 + postcss: 8.5.3 + rollup: 4.41.0 + optionalDependencies: + '@types/node': 24.0.1 + fsevents: 2.3.3 + terser: 5.39.2 + + vite@6.3.5(@types/node@24.0.1)(jiti@2.4.2)(terser@5.39.2)(yaml@2.8.0): + dependencies: + esbuild: 0.25.5 + fdir: 6.4.4(picomatch@4.0.2) + picomatch: 4.0.2 + postcss: 8.5.5 + rollup: 4.41.0 + tinyglobby: 0.2.13 + optionalDependencies: + '@types/node': 24.0.1 + fsevents: 2.3.3 + jiti: 2.4.2 + terser: 5.39.2 + yaml: 2.8.0 + + vitepress@1.5.0(@algolia/client-search@5.12.0)(@types/node@24.0.1)(@types/react@18.3.1)(change-case@5.4.4)(fuse.js@7.1.0)(idb-keyval@6.2.1)(jwt-decode@4.0.0)(postcss@8.5.5)(qrcode@1.5.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(terser@5.39.2)(typescript@5.8.3): + dependencies: + '@docsearch/css': 3.6.3 + '@docsearch/js': 3.6.3(@algolia/client-search@5.12.0)(@types/react@18.3.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@iconify-json/simple-icons': 1.2.10 + '@shikijs/core': 1.22.2 + '@shikijs/transformers': 1.22.2 + '@shikijs/types': 1.22.2 + '@types/markdown-it': 14.1.2 + '@vitejs/plugin-vue': 5.1.4(vite@5.4.19(@types/node@24.0.1)(terser@5.39.2))(vue@3.5.12(typescript@5.8.3)) + '@vue/devtools-api': 7.6.2 + '@vue/shared': 3.5.12 + '@vueuse/core': 11.2.0(vue@3.5.12(typescript@5.8.3)) + '@vueuse/integrations': 11.2.0(change-case@5.4.4)(focus-trap@7.6.0)(fuse.js@7.1.0)(idb-keyval@6.2.1)(jwt-decode@4.0.0)(qrcode@1.5.3)(vue@3.5.12(typescript@5.8.3)) + focus-trap: 7.6.0 + mark.js: 8.11.1 + minisearch: 7.1.0 + shiki: 1.22.2 + vite: 5.4.19(@types/node@24.0.1)(terser@5.39.2) + vue: 3.5.12(typescript@5.8.3) + optionalDependencies: + postcss: 8.5.5 + transitivePeerDependencies: + - '@algolia/client-search' + - '@types/node' + - '@types/react' + - '@vue/composition-api' + - async-validator + - axios + - change-case + - drauu + - fuse.js + - idb-keyval + - jwt-decode + - less + - lightningcss + - nprogress + - qrcode + - react + - react-dom + - sass + - sass-embedded + - search-insights + - sortablejs + - stylus + - sugarss + - terser + - typescript + - universal-cookie + + vitest@2.1.9(@types/node@24.0.1)(happy-dom@15.10.2)(msw@2.4.9(typescript@5.8.3))(terser@5.39.2): + dependencies: + '@vitest/expect': 2.1.9 + '@vitest/mocker': 2.1.9(msw@2.4.9(typescript@5.8.3))(vite@5.4.19(@types/node@24.0.1)(terser@5.39.2)) + '@vitest/pretty-format': 2.1.9 + '@vitest/runner': 2.1.9 + '@vitest/snapshot': 2.1.9 + '@vitest/spy': 2.1.9 + '@vitest/utils': 2.1.9 + chai: 5.2.0 + debug: 4.4.1 + expect-type: 1.2.1 + magic-string: 0.30.17 + pathe: 1.1.2 + std-env: 3.9.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinypool: 1.0.2 + tinyrainbow: 1.2.0 + vite: 5.4.19(@types/node@24.0.1)(terser@5.39.2) + vite-node: 2.1.9(@types/node@24.0.1)(terser@5.39.2) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 24.0.1 + happy-dom: 15.10.2 + transitivePeerDependencies: + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + vscode-uri@3.1.0: {} + + vue-bundle-renderer@2.1.1: + dependencies: + ufo: 1.6.1 + + vue-component-type-helpers@2.0.16: {} + + vue-demi@0.14.10(vue@3.4.27(typescript@5.8.3)): + dependencies: + vue: 3.4.27(typescript@5.8.3) + + vue-demi@0.14.10(vue@3.5.12(typescript@5.8.3)): + dependencies: + vue: 3.5.12(typescript@5.8.3) + + vue-devtools-stub@0.1.0: {} + + vue-resize@2.0.0-alpha.1(vue@3.5.12(typescript@5.8.3)): + dependencies: + vue: 3.5.12(typescript@5.8.3) + + vue-router@4.3.2(vue@3.4.27(typescript@5.8.3)): + dependencies: + '@vue/devtools-api': 6.6.1 + vue: 3.4.27(typescript@5.8.3) + + vue-router@4.5.1(vue@3.5.14(typescript@5.8.3)): + dependencies: + '@vue/devtools-api': 6.6.4 + vue: 3.5.14(typescript@5.8.3) + + vue-template-compiler@2.7.16: + dependencies: + de-indent: 1.0.2 + he: 1.2.0 + + vue-tsc@2.0.16(typescript@5.8.3): + dependencies: + '@volar/typescript': 2.2.1 + '@vue/language-core': 2.0.16(typescript@5.8.3) + semver: 7.5.4 + typescript: 5.8.3 + + vue@3.4.27(typescript@5.8.3): + dependencies: + '@vue/compiler-dom': 3.4.27 + '@vue/compiler-sfc': 3.4.27 + '@vue/runtime-dom': 3.4.27 + '@vue/server-renderer': 3.4.27(vue@3.4.27(typescript@5.8.3)) + '@vue/shared': 3.4.27 + optionalDependencies: + typescript: 5.8.3 + + vue@3.5.12(typescript@5.8.3): + dependencies: + '@vue/compiler-dom': 3.5.12 + '@vue/compiler-sfc': 3.5.12 + '@vue/runtime-dom': 3.5.12 + '@vue/server-renderer': 3.5.12(vue@3.5.12(typescript@5.8.3)) + '@vue/shared': 3.5.12 + optionalDependencies: + typescript: 5.8.3 + + vue@3.5.14(typescript@5.8.3): + dependencies: + '@vue/compiler-dom': 3.5.14 + '@vue/compiler-sfc': 3.5.14 + '@vue/runtime-dom': 3.5.14 + '@vue/server-renderer': 3.5.14(vue@3.5.14(typescript@5.8.3)) + '@vue/shared': 3.5.14 + optionalDependencies: + typescript: 5.8.3 + + wcwidth@1.0.1: + dependencies: + defaults: 1.0.4 + optional: true + + web-streams-polyfill@3.3.3: {} + + webextension-polyfill@0.10.0: {} + + webidl-conversions@3.0.1: {} + + webidl-conversions@7.0.0: {} + + webpack-bundle-analyzer@4.10.1(bufferutil@4.0.8)(utf-8-validate@6.0.5): + dependencies: + '@discoveryjs/json-ext': 0.5.7 + acorn: 8.15.0 + acorn-walk: 8.3.4 + commander: 7.2.0 + debounce: 1.2.1 + escape-string-regexp: 4.0.0 + gzip-size: 6.0.0 + html-escaper: 2.0.2 + is-plain-object: 5.0.0 + opener: 1.5.2 + picocolors: 1.1.1 + sirv: 2.0.4 + ws: 7.5.10(bufferutil@4.0.8)(utf-8-validate@6.0.5) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + webpack-sources@3.2.3: {} + + webpack-virtual-modules@0.6.1: {} + + webpack-virtual-modules@0.6.2: {} + + whatwg-mimetype@3.0.0: {} + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + which-module@2.0.0: {} + + which-typed-array@1.1.19: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + for-each: 0.3.5 + get-proto: 1.0.1 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + + which@1.3.1: + dependencies: + isexe: 2.0.0 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + which@5.0.0: + dependencies: + isexe: 3.1.1 + + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + + wide-align@1.1.5: + dependencies: + string-width: 4.2.3 + + widest-line@3.1.0: + dependencies: + string-width: 4.2.3 + + winston-transport@4.9.0: + dependencies: + logform: 2.7.0 + readable-stream: 3.6.2 + triple-beam: 1.4.1 + + winston@3.17.0: + dependencies: + '@colors/colors': 1.6.0 + '@dabh/diagnostics': 2.0.3 + async: 3.2.6 + is-stream: 2.0.1 + logform: 2.7.0 + one-time: 1.0.0 + readable-stream: 3.6.2 + safe-stable-stringify: 2.5.0 + stack-trace: 0.0.10 + triple-beam: 1.4.1 + winston-transport: 4.9.0 + + workerpool@6.2.1: {} + + wrap-ansi@6.2.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + + wrappy@1.0.2: {} + + write-file-atomic@6.0.0: + dependencies: + imurmurhash: 0.1.4 + signal-exit: 4.1.0 + + ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@6.0.5): + optionalDependencies: + bufferutil: 4.0.8 + utf-8-validate: 6.0.5 + + ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 5.0.10 + + ws@7.5.9(bufferutil@4.0.9)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 5.0.10 + + ws@8.13.0(bufferutil@4.0.8)(utf-8-validate@6.0.5): + optionalDependencies: + bufferutil: 4.0.8 + utf-8-validate: 6.0.5 + + ws@8.13.0(bufferutil@4.0.9)(utf-8-validate@6.0.5): + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 6.0.5 + + ws@8.17.1(bufferutil@4.0.9)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 5.0.10 + + ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 5.0.10 + + ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 5.0.10 + + ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@6.0.5): + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 6.0.5 + + ws@8.18.2(bufferutil@4.0.9)(utf-8-validate@6.0.5): + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 6.0.5 + + xmlhttprequest-ssl@2.1.2: {} + + xtend@4.0.2: {} + + y18n@4.0.3: {} + + y18n@5.0.8: {} + + yallist@2.1.2: {} + + yallist@3.1.1: {} + + yallist@4.0.0: {} + + yallist@5.0.0: {} + + yaml@2.8.0: {} + + yargs-parser@18.1.3: + dependencies: + camelcase: 5.3.1 + decamelize: 1.2.0 + + yargs-parser@20.2.4: {} + + yargs-parser@21.1.1: {} + + yargs-unparser@2.0.0: + dependencies: + camelcase: 6.3.0 + decamelize: 4.0.0 + flat: 5.0.2 + is-plain-obj: 2.1.0 + + yargs@15.4.1: + dependencies: + cliui: 6.0.0 + decamelize: 1.2.0 + find-up: 4.1.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + require-main-filename: 2.0.0 + set-blocking: 2.0.0 + string-width: 4.2.3 + which-module: 2.0.0 + y18n: 4.0.3 + yargs-parser: 18.1.3 + + yargs@16.2.0: + dependencies: + cliui: 7.0.4 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 20.2.4 + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + yauzl@2.10.0: + dependencies: + buffer-crc32: 0.2.13 + fd-slicer: 1.1.0 + + yocto-queue@0.1.0: {} + + yocto-queue@1.2.1: {} + + yoctocolors@2.0.2: {} + + youch-core@0.3.2: + dependencies: + '@poppinss/exception': 1.2.1 + error-stack-parser-es: 1.0.5 + + youch@4.1.0-beta.7: + dependencies: + '@poppinss/dumper': 0.6.3 + '@speed-highlight/core': 1.2.7 + cookie: 1.0.2 + youch-core: 0.3.2 + + zip-stream@4.1.1: + dependencies: + archiver-utils: 3.0.4 + compress-commons: 4.1.2 + readable-stream: 3.6.2 + + zip-stream@6.0.1: + dependencies: + archiver-utils: 5.0.2 + compress-commons: 6.0.2 + readable-stream: 4.7.0 + + zod-validation-error@3.2.0(zod@3.25.20): + dependencies: + zod: 3.25.20 + + zod@3.22.4: {} + + zod@3.25.20: {} + + zustand@5.0.0(@types/react@18.3.1)(react@18.3.1)(use-sync-external-store@1.4.0(react@18.3.1)): + optionalDependencies: + '@types/react': 18.3.1 + react: 18.3.1 + use-sync-external-store: 1.4.0(react@18.3.1) + + zwitch@2.0.4: {} diff --git a/wagmi-project/pnpm-workspace.yaml b/wagmi-project/pnpm-workspace.yaml new file mode 100644 index 0000000000..b1f32102e6 --- /dev/null +++ b/wagmi-project/pnpm-workspace.yaml @@ -0,0 +1,19 @@ +packages: + - packages/* + - "!packages/register-tests" + - packages/cli/src/plugins/__fixtures__/hardhat + - packages/register-tests/* + - playgrounds/* + - site + +catalog: + "@tanstack/query-core": "5.49.1" + "@tanstack/react-query": "5.49.2" + "@tanstack/vue-query": "5.49.1" + "@testing-library/dom": "10.4.0" + "@testing-library/react": "16.0.1" + "@types/react": "18.3.1" + "@types/react-dom": "18.3.0" + react-dom: "18.3.1" + react: "18.3.1" + vue: "3.4.27" diff --git a/wagmi-project/scripts/formatPackageJson.ts b/wagmi-project/scripts/formatPackageJson.ts new file mode 100644 index 0000000000..a4d5a13e39 --- /dev/null +++ b/wagmi-project/scripts/formatPackageJson.ts @@ -0,0 +1,36 @@ +import path from 'node:path' + +// Generates package.json files to be published to NPM with only the necessary fields. + +console.log('Formatting package.json files.') + +// Get all package.json files +const packagePaths = await Array.fromAsync( + new Bun.Glob('packages/**/package.json').scan(), +) + +let count = 0 +for (const packagePath of packagePaths) { + type Package = Record & { + name?: string | undefined + private?: boolean | undefined + } + const file = Bun.file(packagePath) + const packageJson = (await file.json()) as Package + + // Skip private packages + if (packageJson.private) continue + + count += 1 + console.log(`${packageJson.name} — ${path.dirname(packagePath)}`) + + await Bun.write( + `${packagePath}.tmp`, + `${JSON.stringify(packageJson, undefined, 2)}\n`, + ) + + const { devDependencies: _dD, scripts: _s, ...rest } = packageJson + await Bun.write(packagePath, `${JSON.stringify(rest, undefined, 2)}\n`) +} + +console.log(`Done. Formatted ${count} ${count === 1 ? 'file' : 'files'}.`) diff --git a/wagmi-project/scripts/generateProxyPackages.ts b/wagmi-project/scripts/generateProxyPackages.ts new file mode 100644 index 0000000000..a53a7167b3 --- /dev/null +++ b/wagmi-project/scripts/generateProxyPackages.ts @@ -0,0 +1,57 @@ +import fs from 'node:fs/promises' +import path from 'node:path' + +// Generates proxy packages for package.json#exports. + +console.log('Generating proxy packages.') + +// Get all package.json files +const packagePaths = await Array.fromAsync( + new Bun.Glob('packages/**/package.json').scan(), +) + +let count = 0 +for (const packagePath of packagePaths) { + type Package = Record & { + name?: string | undefined + private?: boolean | undefined + exports?: + | Record + | undefined + } + const file = Bun.file(packagePath) + const packageJson = (await file.json()) as Package + + // Skip private packages + if (packageJson.private) continue + if (!packageJson.exports) continue + + count += 1 + console.log(`${packageJson.name} — ${path.dirname(packagePath)}`) + + const dir = path.resolve(path.dirname(packagePath)) + + for (const [key, exports] of Object.entries(packageJson.exports)) { + // Skip `package.json` export + if (/package\.json$/.test(key)) continue + if (key === '.') continue + if (typeof exports === 'string') continue + if (!exports.default) continue + + const proxyDir = path.resolve(dir, key) + await fs.mkdir(proxyDir, { recursive: true }) + + const types = path.relative(key, exports.types) + const main = path.relative(key, exports.default) + await Bun.write( + `${proxyDir}/package.json`, + `${JSON.stringify({ type: 'module', types, main }, undefined, 2)}\n`, + ) + } +} + +console.log( + `Done. Generated proxy packages for ${count} ${ + count === 1 ? 'package' : 'packages' + }.`, +) diff --git a/wagmi-project/scripts/preconstruct.ts b/wagmi-project/scripts/preconstruct.ts new file mode 100644 index 0000000000..9580924f1f --- /dev/null +++ b/wagmi-project/scripts/preconstruct.ts @@ -0,0 +1,87 @@ +import fs from 'node:fs/promises' +import path from 'node:path' + +// Symlinks package sources to dist for local development + +console.log('Setting up packages for development.') + +// Get all package.json files +const packagePaths = await Array.fromAsync( + new Bun.Glob('**/package.json').scan(), +) + +let count = 0 +for (const packagePath of packagePaths) { + type Package = { + bin?: Record | undefined + exports?: + | Record + | undefined + name?: string | undefined + private?: boolean | undefined + } + const file = Bun.file(packagePath) + const packageJson = (await file.json()) as Package + + // Skip private packages + if (packageJson.private && packageJson.name !== '@wagmi/test') continue + if (!packageJson.exports) continue + if (packageJson.bin) continue + + count += 1 + console.log(`${packageJson.name} — ${path.dirname(packagePath)}`) + + const dir = path.resolve(path.dirname(packagePath)) + + // Empty dist directory + const dist = path.resolve(dir, 'dist') + let files: string[] = [] + try { + files = await fs.readdir(dist) + } catch { + await fs.mkdir(dist) + } + + const promises = [] + for (const file of files) { + promises.push( + fs.rm(path.join(dist, file), { recursive: true, force: true }), + ) + } + await Promise.all(promises) + + // Link exports to dist locations + for (const [key, exports] of Object.entries(packageJson.exports)) { + // Skip `package.json` exports + if (/package\.json$/.test(key)) continue + if (typeof exports === 'string') continue + + // Link exports to dist locations + for (const [type, value] of Object.entries(exports) as [ + type: 'types' | 'default', + value: string, + ][]) { + const srcDir = path.resolve( + dir, + path + .dirname(value) + .replace(`dist/${type === 'default' ? 'esm' : type}`, 'src'), + ) + let srcFileName: string + if (key === '.') srcFileName = 'index.ts' + else srcFileName = path.basename(`${key}.ts`) + const srcFilePath = path.resolve(srcDir, srcFileName) + + const distDir = path.resolve(dir, path.dirname(value)) + const distFileName = path.basename(value) + const distFilePath = path.resolve(distDir, distFileName) + + await fs.mkdir(distDir, { recursive: true }) + + // Symlink src to dist file + await fs.symlink(srcFilePath, distFilePath, 'file') + } + } +} + +console.log(`Done. Set up ${count} ${count === 1 ? 'package' : 'packages'}.`) diff --git a/wagmi-project/scripts/restorePackageJson.ts b/wagmi-project/scripts/restorePackageJson.ts new file mode 100644 index 0000000000..c0019a340f --- /dev/null +++ b/wagmi-project/scripts/restorePackageJson.ts @@ -0,0 +1,29 @@ +import fs from 'node:fs/promises' +import path from 'node:path' + +// Restores package.json files from package.json.tmp files. + +console.log('Restoring package.json files.') + +// Get all package.json files +const packagePaths = await Array.fromAsync( + new Bun.Glob('packages/**/package.json.tmp').scan(), +) + +let count = 0 +for (const packagePath of packagePaths) { + type Package = { name?: string | undefined } & Record + const file = Bun.file(packagePath) + const packageJson = (await file.json()) as Package + + count += 1 + console.log(`${packageJson.name} — ${path.dirname(packagePath)}`) + + await Bun.write( + packagePath.replace('.tmp', ''), + `${JSON.stringify(packageJson, undefined, 2)}\n`, + ) + await fs.rm(packagePath) +} + +console.log(`Done. Restored ${count} ${count === 1 ? 'file' : 'files'}.`) diff --git a/wagmi-project/scripts/updateBlockExplorerPluginChains.ts b/wagmi-project/scripts/updateBlockExplorerPluginChains.ts new file mode 100644 index 0000000000..d61790fd36 --- /dev/null +++ b/wagmi-project/scripts/updateBlockExplorerPluginChains.ts @@ -0,0 +1,53 @@ +// Fetches supported chains for Etherscan and Sourcify + +console.log('Updating block explorer plugins chains.') + +let count = 0 +{ + console.log('etherscan - https://api.etherscan.io/v2/chainlist') + const res = (await fetch('https://api.etherscan.io/v2/chainlist').then( + (res) => res.json(), + )) as { + totalcount: number + result: { + chainname: string + chainid: number + blockexplorer: string + apiurl: string + status: 0 | 1 + }[] + } + + let content = 'type ChainId =\n' + for (const chain of res.result) + content += ` | ${chain.chainid} // ${chain.chainname}\n` + + await writeContent('./packages/cli/src/plugins/etherscan.ts', content) + count += 1 +} + +{ + console.log('sourcify - https://sourcify.dev/server/chains') + const res = (await fetch('https://sourcify.dev/server/chains').then((res) => + res.json(), + )) as { + name: string + chainId: number + }[] + + let content = 'type ChainId =\n' + for (const chain of res) content += ` | ${chain.chainId} // ${chain.name}\n` + + await writeContent('./packages/cli/src/plugins/sourcify.ts', content) + count += 1 +} + +console.log(`Done. Updated chains for ${count} plugins.`) + +async function writeContent(pluginPath: string, content: string) { + const file = Bun.file(pluginPath) + const text = await file + .text() + .then((text) => text.replace(/type ChainId =[\s\S]*$/, content)) + await Bun.write(pluginPath, text) +} diff --git a/wagmi-project/scripts/updateVersion.ts b/wagmi-project/scripts/updateVersion.ts new file mode 100644 index 0000000000..4ec949cc10 --- /dev/null +++ b/wagmi-project/scripts/updateVersion.ts @@ -0,0 +1,43 @@ +import path from 'node:path' + +// Updates package version.ts files (so you can use the version in code without importing package.json). + +console.log('Updating version files.') + +// Get all package.json files +const packagePaths = await Array.fromAsync( + new Bun.Glob('**/package.json').scan(), +) + +let count = 0 +for (const packagePath of packagePaths) { + type Package = { + name?: string | undefined + private?: boolean | undefined + version?: string | undefined + } + const file = Bun.file(packagePath) + const packageJson = (await file.json()) as Package + + // Skip private packages + if (packageJson.private) continue + + count += 1 + console.log(`${packageJson.name} — ${packageJson.version}`) + + const versionFilePath = path.resolve( + path.dirname(packagePath), + 'src', + 'version.ts', + ) + await Bun.write( + versionFilePath, + `export const version = '${packageJson.version}'\n`, + ) +} + +console.log( + `Done. Updated version file for ${count} ${ + count === 1 ? 'package' : 'packages' + }.`, +) diff --git a/wagmi-project/scripts/updateViemVersion.ts b/wagmi-project/scripts/updateViemVersion.ts new file mode 100644 index 0000000000..5731394bad --- /dev/null +++ b/wagmi-project/scripts/updateViemVersion.ts @@ -0,0 +1,44 @@ +// Updates viem version in Vitest snapshots, etc. + +console.log('Updating Viem version.') + +const file = Bun.file('package.json') +const packageJson = await file.json() +const viemVersion = packageJson.devDependencies.viem + +// Update Vitest snapshots +// Get all *.test.ts files +const testPaths = await Array.fromAsync( + new Bun.Glob('packages/**/*.test.ts').scan(), +) + +let count = 0 +for (const testPath of testPaths) { + const file = Bun.file(testPath) + const testFile = await file.text() + + // Skip files that don't contain viem version + if (!testFile.includes('Version: viem@')) continue + // Skip files that contain current version + if (testFile.includes(`Version: viem@${viemVersion}`)) continue + + console.log(testPath) + const updatedTestFile = testFile.replace( + /Version: viem@[A-Za-z0-9\-\.]+/g, + `Version: viem@${viemVersion}`, + ) + await Bun.write(testPath, updatedTestFile) + + count += 1 +} + +// // Update package.json#pnpm.overrides.viem +// if (packageJson.pnpm?.overrides?.viem !== viemVersion) { +// const path = 'package.json' +// console.log(path) +// packageJson.pnpm.overrides.viem = viemVersion +// await Bun.write(path, `${JSON.stringify(packageJson, undefined, 2)}\n`) +// count += 1 +// } + +console.log(`Done. Updated ${count} ${count === 1 ? 'file' : 'files'}.`) diff --git a/wagmi-project/site/.vitepress/config.ts b/wagmi-project/site/.vitepress/config.ts new file mode 100644 index 0000000000..77f242cb09 --- /dev/null +++ b/wagmi-project/site/.vitepress/config.ts @@ -0,0 +1,151 @@ +import { + defaultHoverInfoProcessor, + transformerTwoslash, +} from '@shikijs/vitepress-twoslash' +import { presetAttributify, presetIcons, presetUno } from 'unocss' +import Unocss from 'unocss/vite' +import { defineConfig } from 'vitepress' + +import { farcasterIcon } from './constants' +import { getSidebar } from './sidebar' + +// https://vitepress.dev/reference/site-config +export default defineConfig({ + cleanUrls: true, + description: 'Reactivity for Ethereum apps', + head: [ + [ + 'meta', + { + name: 'keywords', + content: 'react, ethereum, typescript, react, react hooks, open source', + }, + ], + ['link', { rel: 'icon', href: '/favicon.svg' }], + ['meta', { name: 'theme-color', content: '#646cff' }], + // Open Graph + ['meta', { property: 'og:type', content: 'website' }], + ['meta', { property: 'og:image', content: 'https://wagmi.sh/og.png' }], + ['meta', { property: 'og:url', content: 'https://wagmi.sh' }], + // Twitter + ['meta', { name: 'twitter:card', content: 'summary_large_image' }], + ['meta', { name: 'twitter:creator', content: '@wevm_dev' }], + ['meta', { name: 'twitter:image', content: 'https://wagmi.sh/og.png' }], + ['meta', { name: 'twitter:site', content: 'wagmi.sh' }], + // Fathom + [ + 'script', + { + src: 'https://cdn.usefathom.com/script.js', + 'data-site': 'QWAXSUPT', + defer: '', + }, + ], + ], + ignoreDeadLinks: false, + lang: 'en-US', + lastUpdated: true, + markdown: { + codeTransformers: [ + transformerTwoslash({ + processHoverInfo(info) { + return ( + defaultHoverInfoProcessor(info) + // Remove shiki_core namespace + .replace(/_shikijs_core[\w_]*\./g, '') + ) + }, + }), + ], + theme: { + light: 'vitesse-light', + dark: 'vitesse-dark', + }, + }, + themeConfig: { + editLink: { + pattern: 'https://github.com/wevm/wagmi/edit/main/site/:path', + text: 'Suggest changes to this page', + }, + footer: { + message: + 'Released under the MIT License.', + copyright: 'Copyright Ā© 2022-present Weth, LLC', + }, + logo: { + light: '/logo-light.svg', + dark: '/logo-dark.svg', + alt: 'wagmi logo', + }, + nav: [ + { text: 'React', link: '/react/getting-started' }, + { text: 'Vue', link: '/vue/getting-started' }, + { text: 'Core', link: '/core/getting-started' }, + { text: 'CLI', link: '/cli/getting-started' }, + // { text: 'Examples', link: '/examples/connect-wallet' }, + { + text: 'More', + items: [ + { + text: 'Discussions ', + link: 'https://github.com/wevm/wagmi/discussions', + }, + { + text: 'Release Notes ', + link: 'https://github.com/wevm/wagmi/releases', + }, + { + text: 'Contributing ', + link: '/dev/contributing', + }, + ], + }, + ], + outline: [2, 3], + search: { + provider: 'local', + options: { + _render(src, env, md) { + const html = md.render(src, env) + if (env.frontmatter?.search === false) return '' + if (env.relativePath.startsWith('shared')) return '' + return html + }, + }, + }, + sidebar: getSidebar(), + siteTitle: false, + socialLinks: [ + { + icon: 'github', + link: 'https://github.com/wevm/wagmi', + }, + { icon: 'bluesky', link: 'https://bsky.app/profile/wevm.dev' }, + { icon: 'x', link: 'https://twitter.com/wevm_dev' }, + { icon: { svg: farcasterIcon }, link: 'https://warpcast.com/wevm' }, + { icon: 'discord', link: 'https://discord.gg/9zHPXuBpqy' }, + ], + }, + title: 'Wagmi', + vite: { + plugins: [ + Unocss({ + shortcuts: [ + [ + 'btn', + 'px-4 py-1 rounded inline-flex justify-center gap-2 text-white leading-30px children:mya !no-underline cursor-pointer disabled:cursor-default disabled:bg-gray-600 disabled:opacity-50', + ], + ], + presets: [ + presetUno({ + dark: 'media', + }), + presetAttributify(), + presetIcons({ + scale: 1.2, + }), + ], + }), + ], + }, +}) diff --git a/wagmi-project/site/.vitepress/constants.ts b/wagmi-project/site/.vitepress/constants.ts new file mode 100644 index 0000000000..981f8df3e1 --- /dev/null +++ b/wagmi-project/site/.vitepress/constants.ts @@ -0,0 +1,2 @@ +export const farcasterIcon = + '' diff --git a/wagmi-project/site/.vitepress/sidebar.ts b/wagmi-project/site/.vitepress/sidebar.ts new file mode 100644 index 0000000000..29ea14bc52 --- /dev/null +++ b/wagmi-project/site/.vitepress/sidebar.ts @@ -0,0 +1,1085 @@ +import type { DefaultTheme } from 'vitepress' + +export function getSidebar() { + return { + '/react': [ + { + text: 'Introduction', + items: [ + { text: 'Why Wagmi', link: '/react/why' }, + { text: 'Installation', link: '/react/installation' }, + { text: 'Getting Started', link: '/react/getting-started' }, + { text: 'TypeScript', link: '/react/typescript' }, + { text: 'Comparisons', link: '/react/comparisons' }, + ], + }, + { + text: 'Guides', + items: [ + { + text: 'TanStack Query', + link: '/react/guides/tanstack-query', + }, + { + text: 'Viem', + link: '/react/guides/viem', + }, + { + text: 'Error Handling', + link: '/react/guides/error-handling', + }, + { + text: 'Ethers.js Adapters', + link: '/react/guides/ethers', + }, + // { + // text: 'Testing', + // link: '/react/guides/testing', + // }, + { + text: 'Chain Properties', + link: '/react/guides/chain-properties', + }, + { + text: 'SSR', + link: '/react/guides/ssr', + }, + { + text: 'Connect Wallet', + link: '/react/guides/connect-wallet', + }, + { + text: 'Send Transaction', + link: '/react/guides/send-transaction', + }, + { + text: 'Read from Contract', + link: '/react/guides/read-from-contract', + }, + { + text: 'Write to Contract', + link: '/react/guides/write-to-contract', + }, + { + text: 'FAQ / Troubleshooting', + link: '/react/guides/faq', + }, + { + text: 'Migrate from v1 to v2', + link: '/react/guides/migrate-from-v1-to-v2', + }, + ], + }, + { + text: 'Configuration', + items: [ + { text: 'createConfig', link: '/react/api/createConfig' }, + { text: 'createStorage', link: '/react/api/createStorage' }, + { text: 'Chains', link: '/react/api/chains' }, + { + text: 'Connectors', + collapsed: true, + link: '/react/api/connectors', + items: [ + { + text: 'coinbaseWallet', + link: '/react/api/connectors/coinbaseWallet', + }, + { text: 'injected', link: '/react/api/connectors/injected' }, + { + text: 'metaMask', + link: '/react/api/connectors/metaMask', + }, + { + text: 'mock', + link: '/react/api/connectors/mock', + }, + { + text: 'safe', + link: '/react/api/connectors/safe', + }, + { + text: 'walletConnect', + link: '/react/api/connectors/walletConnect', + }, + ], + }, + { + text: 'Transports', + collapsed: true, + link: '/react/api/transports', + items: [ + { + text: 'custom (EIP-1193)', + link: '/react/api/transports/custom', + }, + { + text: 'fallback', + link: '/react/api/transports/fallback', + }, + { + text: 'http', + link: '/react/api/transports/http', + }, + { + text: 'unstable_connector', + link: '/react/api/transports/unstable_connector', + }, + { + text: 'webSocket', + link: '/react/api/transports/webSocket', + }, + ], + }, + { text: 'WagmiProvider', link: '/react/api/WagmiProvider' }, + ], + }, + { + text: 'Hooks', + link: '/react/api/hooks', + items: [ + { text: 'useAccount', link: '/react/api/hooks/useAccount' }, + { + text: 'useAccountEffect', + link: '/react/api/hooks/useAccountEffect', + }, + { text: 'useBalance', link: '/react/api/hooks/useBalance' }, + { + text: 'useBlockNumber', + link: '/react/api/hooks/useBlockNumber', + }, + { + text: 'useBlock', + link: '/react/api/hooks/useBlock', + }, + { + text: 'useBlockTransactionCount', + link: '/react/api/hooks/useBlockTransactionCount', + }, + { + text: 'useBytecode', + link: '/react/api/hooks/useBytecode', + }, + { text: 'useCall', link: '/react/api/hooks/useCall' }, + { + text: 'useCallsStatus', + link: '/react/api/hooks/useCallsStatus', + }, + { + text: 'useCapabilities', + link: '/react/api/hooks/useCapabilities', + }, + { text: 'useChainId', link: '/react/api/hooks/useChainId' }, + { text: 'useChains', link: '/react/api/hooks/useChains' }, + { text: 'useClient', link: '/react/api/hooks/useClient' }, + { text: 'useConfig', link: '/react/api/hooks/useConfig' }, + { text: 'useConnect', link: '/react/api/hooks/useConnect' }, + { + text: 'useConnections', + link: '/react/api/hooks/useConnections', + }, + { + text: 'useConnectorClient', + link: '/react/api/hooks/useConnectorClient', + }, + { + text: 'useConnectors', + link: '/react/api/hooks/useConnectors', + }, + { + text: 'useDeployContract', + link: '/react/api/hooks/useDeployContract', + }, + { text: 'useDisconnect', link: '/react/api/hooks/useDisconnect' }, + { text: 'useEnsAddress', link: '/react/api/hooks/useEnsAddress' }, + { text: 'useEnsAvatar', link: '/react/api/hooks/useEnsAvatar' }, + { text: 'useEnsName', link: '/react/api/hooks/useEnsName' }, + { + text: 'useEnsResolver', + link: '/react/api/hooks/useEnsResolver', + }, + { + text: 'useEnsText', + link: '/react/api/hooks/useEnsText', + }, + { + text: 'useFeeHistory', + link: '/react/api/hooks/useFeeHistory', + }, + { + text: 'useProof', + link: '/react/api/hooks/useProof', + }, + { + text: 'usePublicClient', + link: '/react/api/hooks/usePublicClient', + }, + { + text: 'useEstimateFeesPerGas', + link: '/react/api/hooks/useEstimateFeesPerGas', + }, + { + text: 'useEstimateGas', + link: '/react/api/hooks/useEstimateGas', + }, + { + text: 'useEstimateMaxPriorityFeePerGas', + link: '/react/api/hooks/useEstimateMaxPriorityFeePerGas', + }, + { + text: 'useGasPrice', + link: '/react/api/hooks/useGasPrice', + }, + { + text: 'useInfiniteReadContracts', + link: '/react/api/hooks/useInfiniteReadContracts', + }, + { + text: 'usePrepareTransactionRequest', + link: '/react/api/hooks/usePrepareTransactionRequest', + }, + { + text: 'useReadContract', + link: '/react/api/hooks/useReadContract', + }, + { + text: 'useReadContracts', + link: '/react/api/hooks/useReadContracts', + }, + { text: 'useReconnect', link: '/react/api/hooks/useReconnect' }, + { + text: 'useSendCalls', + link: '/react/api/hooks/useSendCalls', + }, + { + text: 'useSendTransaction', + link: '/react/api/hooks/useSendTransaction', + }, + { + text: 'useShowCallsStatus', + link: '/react/api/hooks/useShowCallsStatus', + }, + { + text: 'useSignMessage', + link: '/react/api/hooks/useSignMessage', + }, + { + text: 'useSignTypedData', + link: '/react/api/hooks/useSignTypedData', + }, + { + text: 'useSimulateContract', + link: '/react/api/hooks/useSimulateContract', + }, + { + text: 'useStorageAt', + link: '/react/api/hooks/useStorageAt', + }, + { + text: 'useSwitchAccount', + link: '/react/api/hooks/useSwitchAccount', + }, + { + text: 'useSwitchChain', + link: '/react/api/hooks/useSwitchChain', + }, + { + text: 'useTransaction', + link: '/react/api/hooks/useTransaction', + }, + { + text: 'useTransactionConfirmations', + link: '/react/api/hooks/useTransactionConfirmations', + }, + { + text: 'useTransactionCount', + link: '/react/api/hooks/useTransactionCount', + }, + { + text: 'useTransactionReceipt', + link: '/react/api/hooks/useTransactionReceipt', + }, + { + text: 'useToken', + link: '/react/api/hooks/useToken', + }, + { + text: 'useWaitForCallsStatus', + link: '/react/api/hooks/useWaitForCallsStatus', + }, + { + text: 'useWaitForTransactionReceipt', + link: '/react/api/hooks/useWaitForTransactionReceipt', + }, + { + text: 'useVerifyMessage', + link: '/react/api/hooks/useVerifyMessage', + }, + { + text: 'useVerifyTypedData', + link: '/react/api/hooks/useVerifyTypedData', + }, + { + text: 'useWalletClient', + link: '/react/api/hooks/useWalletClient', + }, + { + text: 'useWatchAsset', + link: '/react/api/hooks/useWatchAsset', + }, + { + text: 'useWatchBlocks', + link: '/react/api/hooks/useWatchBlocks', + }, + { + text: 'useWatchBlockNumber', + link: '/react/api/hooks/useWatchBlockNumber', + }, + { + text: 'useWatchContractEvent', + link: '/react/api/hooks/useWatchContractEvent', + }, + { + text: 'useWatchPendingTransactions', + link: '/react/api/hooks/useWatchPendingTransactions', + }, + { + text: 'useWriteContract', + link: '/react/api/hooks/useWriteContract', + }, + ], + }, + { + text: 'Miscellaneous', + items: [ + { text: 'Actions', link: '/react/api/actions' }, + { text: 'Errors', link: '/react/api/errors' }, + { + text: 'Utilities', + collapsed: true, + items: [ + { + text: 'cookieToInitialState', + link: '/react/api/utilities/cookieToInitialState', + }, + { text: 'deserialize', link: '/react/api/utilities/deserialize' }, + { + text: 'normalizeChainId', + link: '/react/api/utilities/normalizeChainId', + }, + { text: 'serialize', link: '/react/api/utilities/serialize' }, + ], + }, + ], + }, + ], + '/vue': [ + { + text: 'Introduction', + items: [ + { text: 'Why Wagmi', link: '/vue/why' }, + { text: 'Installation', link: '/vue/installation' }, + { text: 'Getting Started', link: '/vue/getting-started' }, + { text: 'TypeScript', link: '/vue/typescript' }, + ], + }, + { + text: 'Guides', + items: [ + { + text: 'TanStack Query', + link: '/vue/guides/tanstack-query', + }, + { + text: 'Viem', + link: '/vue/guides/viem', + }, + { + text: 'Error Handling', + link: '/vue/guides/error-handling', + }, + { + text: 'Chain Properties', + link: '/vue/guides/chain-properties', + }, + { + text: 'SSR', + link: '/vue/guides/ssr', + }, + { + text: 'Connect Wallet', + link: '/vue/guides/connect-wallet', + }, + { + text: 'Send Transaction', + link: '/vue/guides/send-transaction', + }, + { + text: 'Read from Contract', + link: '/vue/guides/read-from-contract', + }, + { + text: 'Write to Contract', + link: '/vue/guides/write-to-contract', + }, + { + text: 'FAQ / Troubleshooting', + link: '/vue/guides/faq', + }, + ], + }, + { + text: 'Configuration', + items: [ + { text: 'createConfig', link: '/vue/api/createConfig' }, + { text: 'createStorage', link: '/vue/api/createStorage' }, + { text: 'Chains', link: '/vue/api/chains' }, + { + text: 'Connectors', + collapsed: true, + link: '/vue/api/connectors', + items: [ + { + text: 'coinbaseWallet', + link: '/vue/api/connectors/coinbaseWallet', + }, + { text: 'injected', link: '/vue/api/connectors/injected' }, + { + text: 'metaMask', + link: '/vue/api/connectors/metaMask', + }, + { + text: 'mock', + link: '/vue/api/connectors/mock', + }, + { + text: 'safe', + link: '/vue/api/connectors/safe', + }, + { + text: 'walletConnect', + link: '/vue/api/connectors/walletConnect', + }, + ], + }, + { + text: 'Transports', + collapsed: true, + link: '/vue/api/transports', + items: [ + { + text: 'custom (EIP-1193)', + link: '/vue/api/transports/custom', + }, + { + text: 'fallback', + link: '/vue/api/transports/fallback', + }, + { + text: 'http', + link: '/vue/api/transports/http', + }, + { + text: 'unstable_connector', + link: '/vue/api/transports/unstable_connector', + }, + { + text: 'webSocket', + link: '/vue/api/transports/webSocket', + }, + ], + }, + { text: 'WagmiPlugin', link: '/vue/api/WagmiPlugin' }, + { text: 'Nuxt', link: '/vue/api/Nuxt' }, + ], + }, + { + text: 'Composables', + link: '/vue/api/composables', + items: [ + { text: 'useAccount', link: '/vue/api/composables/useAccount' }, + { + text: 'useAccountEffect', + link: '/vue/api/composables/useAccountEffect', + }, + { + text: 'useBalance', + link: '/vue/api/composables/useBalance', + }, + { + text: 'useBlockNumber', + link: '/vue/api/composables/useBlockNumber', + }, + { + text: 'useBytecode', + link: '/vue/api/composables/useBytecode', + }, + { text: 'useChainId', link: '/vue/api/composables/useChainId' }, + { text: 'useChains', link: '/vue/api/composables/useChains' }, + { text: 'useClient', link: '/vue/api/composables/useClient' }, + { text: 'useConfig', link: '/vue/api/composables/useConfig' }, + { text: 'useConnect', link: '/vue/api/composables/useConnect' }, + { + text: 'useConnections', + link: '/vue/api/composables/useConnections', + }, + { + text: 'useConnectorClient', + link: '/vue/api/composables/useConnectorClient', + }, + { + text: 'useConnectors', + link: '/vue/api/composables/useConnectors', + }, + { + text: 'useDisconnect', + link: '/vue/api/composables/useDisconnect', + }, + { + text: 'useEnsAddress', + link: '/vue/api/composables/useEnsAddress', + }, + { + text: 'useEnsAvatar', + link: '/vue/api/composables/useEnsAvatar', + }, + { + text: 'useEstimateGas', + link: '/vue/api/composables/useEstimateGas', + }, + { + text: 'useReadContract', + link: '/vue/api/composables/useReadContract', + }, + { + text: 'useReconnect', + link: '/vue/api/composables/useReconnect', + }, + { + text: 'useSendTransaction', + link: '/vue/api/composables/useSendTransaction', + }, + { + text: 'useSignMessage', + link: '/vue/api/composables/useSignMessage', + }, + { + text: 'useSignTypedData', + link: '/vue/api/composables/useSignTypedData', + }, + { + text: 'useSimulateContract', + link: '/vue/api/composables/useSimulateContract', + }, + { + text: 'useSwitchAccount', + link: '/vue/api/composables/useSwitchAccount', + }, + { + text: 'useSwitchChain', + link: '/vue/api/composables/useSwitchChain', + }, + { + text: 'useTransaction', + link: '/vue/api/composables/useTransaction', + }, + { + text: 'useTransactionReceipt', + link: '/vue/api/composables/useTransactionReceipt', + }, + { + text: 'useWaitForTransactionReceipt', + link: '/vue/api/composables/useWaitForTransactionReceipt', + }, + { + text: 'useWatchBlockNumber', + link: '/vue/api/composables/useWatchBlockNumber', + }, + { + text: 'useWatchContractEvent', + link: '/vue/api/composables/useWatchContractEvent', + }, + { + text: 'useWriteContract', + link: '/vue/api/composables/useWriteContract', + }, + ], + }, + { + text: 'Miscellaneous', + items: [ + { text: 'Actions', link: '/vue/api/actions' }, + { text: 'Errors', link: '/vue/api/errors' }, + { + text: 'Utilities', + collapsed: true, + items: [ + { + text: 'deserialize', + link: '/vue/api/utilities/deserialize', + }, + { text: 'serialize', link: '/vue/api/utilities/serialize' }, + ], + }, + ], + }, + ], + '/core': [ + { + text: 'Introduction', + items: [ + { text: 'Why Wagmi', link: '/core/why' }, + { text: 'Installation', link: '/core/installation' }, + { text: 'Getting Started', link: '/core/getting-started' }, + { text: 'TypeScript', link: '/core/typescript' }, + ], + }, + { + text: 'Guides', + items: [ + { + text: 'Viem', + link: '/core/guides/viem', + }, + { + text: 'Framework Adapters', + link: '/core/guides/framework-adapters', + }, + { + text: 'Error Handling', + link: '/core/guides/error-handling', + }, + { + text: 'Ethers.js Adapters', + link: '/core/guides/ethers', + }, + // { + // text: 'Testing', + // link: '/core/guides/testing', + // }, + { + text: 'Chain Properties', + link: '/core/guides/chain-properties', + }, + { + text: 'FAQ / Troubleshooting', + link: '/core/guides/faq', + }, + { + text: 'Migrate from v1 to v2', + link: '/core/guides/migrate-from-v1-to-v2', + }, + ], + }, + { + text: 'Configuration', + items: [ + { text: 'createConfig', link: '/core/api/createConfig' }, + { text: 'createConnector', link: '/core/api/createConnector' }, + { text: 'createStorage', link: '/core/api/createStorage' }, + { text: 'Chains', link: '/core/api/chains' }, + { + text: 'Connectors', + collapsed: true, + link: '/core/api/connectors', + items: [ + { + text: 'coinbaseWallet', + link: '/core/api/connectors/coinbaseWallet', + }, + { text: 'injected', link: '/core/api/connectors/injected' }, + { + text: 'metaMask', + link: '/core/api/connectors/metaMask', + }, + { + text: 'mock', + link: '/core/api/connectors/mock', + }, + { + text: 'safe', + link: '/core/api/connectors/safe', + }, + { + text: 'walletConnect', + link: '/core/api/connectors/walletConnect', + }, + ], + }, + { + text: 'Transports', + collapsed: true, + link: '/core/api/transports', + items: [ + { + text: 'custom (EIP-1193)', + link: '/core/api/transports/custom', + }, + { + text: 'fallback', + link: '/core/api/transports/fallback', + }, + { + text: 'http', + link: '/core/api/transports/http', + }, + { + text: 'unstable_connector', + link: '/core/api/transports/unstable_connector', + }, + { + text: 'webSocket', + link: '/core/api/transports/webSocket', + }, + ], + }, + ], + }, + { + text: 'Actions', + link: '/core/api/actions', + items: [ + { + text: 'call', + link: '/core/api/actions/call', + }, + { text: 'connect', link: '/core/api/actions/connect' }, + { text: 'deployContract', link: '/core/api/actions/deployContract' }, + { text: 'disconnect', link: '/core/api/actions/disconnect' }, + { + text: 'estimateFeesPerGas', + link: '/core/api/actions/estimateFeesPerGas', + }, + { text: 'estimateGas', link: '/core/api/actions/estimateGas' }, + { + text: 'estimateMaxPriorityFeePerGas', + link: '/core/api/actions/estimateMaxPriorityFeePerGas', + }, + { text: 'getAccount', link: '/core/api/actions/getAccount' }, + { text: 'getBalance', link: '/core/api/actions/getBalance' }, + { + text: 'getBlock', + link: '/core/api/actions/getBlock', + }, + { + text: 'getBlockNumber', + link: '/core/api/actions/getBlockNumber', + }, + { + text: 'getBlockTransactionCount', + link: '/core/api/actions/getBlockTransactionCount', + }, + { + text: 'getBytecode', + link: '/core/api/actions/getBytecode', + }, + { + text: 'getCallsStatus', + link: '/core/api/actions/getCallsStatus', + }, + { + text: 'getCapabilities', + link: '/core/api/actions/getCapabilities', + }, + { text: 'getChainId', link: '/core/api/actions/getChainId' }, + { text: 'getChains', link: '/core/api/actions/getChains' }, + { + text: 'getClient', + link: '/core/api/actions/getClient', + }, + { + text: 'getConnections', + link: '/core/api/actions/getConnections', + }, + { + text: 'getConnectorClient', + link: '/core/api/actions/getConnectorClient', + }, + { + text: 'getConnectors', + link: '/core/api/actions/getConnectors', + }, + { + text: 'getEnsAddress', + link: '/core/api/actions/getEnsAddress', + }, + { text: 'getEnsAvatar', link: '/core/api/actions/getEnsAvatar' }, + { text: 'getEnsName', link: '/core/api/actions/getEnsName' }, + { + text: 'getEnsResolver', + link: '/core/api/actions/getEnsResolver', + }, + { + text: 'getEnsText', + link: '/core/api/actions/getEnsText', + }, + { + text: 'getFeeHistory', + link: '/core/api/actions/getFeeHistory', + }, + { + text: 'getGasPrice', + link: '/core/api/actions/getGasPrice', + }, + { + text: 'getProof', + link: '/core/api/actions/getProof', + }, + { + text: 'getPublicClient', + link: '/core/api/actions/getPublicClient', + }, + { + text: 'getStorageAt', + link: '/core/api/actions/getStorageAt', + }, + { text: 'getToken', link: '/core/api/actions/getToken' }, + { + text: 'getTransaction', + link: '/core/api/actions/getTransaction', + }, + { + text: 'getTransactionConfirmations', + link: '/core/api/actions/getTransactionConfirmations', + }, + { + text: 'getTransactionCount', + link: '/core/api/actions/getTransactionCount', + }, + { + text: 'getTransactionReceipt', + link: '/core/api/actions/getTransactionReceipt', + }, + { + text: 'getWalletClient', + link: '/core/api/actions/getWalletClient', + }, + { + text: 'multicall', + link: '/core/api/actions/multicall', + }, + { + text: 'prepareTransactionRequest', + link: '/core/api/actions/prepareTransactionRequest', + }, + { text: 'reconnect', link: '/core/api/actions/reconnect' }, + { + text: 'readContract', + link: '/core/api/actions/readContract', + }, + { + text: 'readContracts', + link: '/core/api/actions/readContracts', + }, + { + text: 'sendCalls', + link: '/core/api/actions/sendCalls', + }, + { + text: 'sendTransaction', + link: '/core/api/actions/sendTransaction', + }, + { + text: 'showCallsStatus', + link: '/core/api/actions/showCallsStatus', + }, + { + text: 'signMessage', + link: '/core/api/actions/signMessage', + }, + { + text: 'signTypedData', + link: '/core/api/actions/signTypedData', + }, + { + text: 'simulateContract', + link: '/core/api/actions/simulateContract', + }, + { + text: 'switchAccount', + link: '/core/api/actions/switchAccount', + }, + { + text: 'switchChain', + link: '/core/api/actions/switchChain', + }, + { + text: 'verifyMessage', + link: '/core/api/actions/verifyMessage', + }, + { + text: 'verifyTypedData', + link: '/core/api/actions/verifyTypedData', + }, + { + text: 'waitForCallsStatus', + link: '/core/api/actions/waitForCallsStatus', + }, + { + text: 'waitForTransactionReceipt', + link: '/core/api/actions/waitForTransactionReceipt', + }, + { + text: 'watchAccount', + link: '/core/api/actions/watchAccount', + }, + { + text: 'watchAsset', + link: '/core/api/actions/watchAsset', + }, + { + text: 'watchBlocks', + link: '/core/api/actions/watchBlocks', + }, + { + text: 'watchBlockNumber', + link: '/core/api/actions/watchBlockNumber', + }, + { + text: 'watchChainId', + link: '/core/api/actions/watchChainId', + }, + { + text: 'watchClient', + link: '/core/api/actions/watchClient', + }, + { + text: 'watchConnections', + link: '/core/api/actions/watchConnections', + }, + { + text: 'watchConnectors', + link: '/core/api/actions/watchConnectors', + }, + { + text: 'watchContractEvent', + link: '/core/api/actions/watchContractEvent', + }, + { + text: 'watchPendingTransactions', + link: '/core/api/actions/watchPendingTransactions', + }, + { + text: 'watchPublicClient', + link: '/core/api/actions/watchPublicClient', + }, + { + text: 'writeContract', + link: '/core/api/actions/writeContract', + }, + ], + }, + { + text: 'Miscellaneous', + items: [ + { text: 'Errors', link: '/core/api/errors' }, + { + text: 'Utilities', + collapsed: true, + items: [ + { + text: 'cookieToInitialState', + link: '/core/api/utilities/cookieToInitialState', + }, + { text: 'deserialize', link: '/core/api/utilities/deserialize' }, + { + text: 'normalizeChainId', + link: '/core/api/utilities/normalizeChainId', + }, + { text: 'serialize', link: '/core/api/utilities/serialize' }, + ], + }, + ], + }, + ], + '/cli': [ + { + text: 'Introduction', + items: [ + { text: 'Why Wagmi CLI', link: '/cli/why' }, + { text: 'Installation', link: '/cli/installation' }, + { text: 'Getting Started', link: '/cli/getting-started' }, + ], + }, + { + text: 'Guides', + items: [ + { + text: 'Migrate from v1 to v2', + link: '/cli/guides/migrate-from-v1-to-v2', + }, + ], + }, + { + text: 'Config File', + items: [ + { + text: 'Configuring CLI', + link: '/cli/config/configuring-cli', + }, + { text: 'Config Options', link: '/cli/config/options' }, + ], + }, + { + text: 'Commands', + link: '/cli/api/commands', + items: [ + { + text: 'generate', + link: '/cli/api/commands/generate', + }, + { + text: 'init', + link: '/cli/api/commands/init', + }, + ], + }, + { + text: 'Plugins', + link: '/cli/api/plugins', + items: [ + { text: 'actions', link: '/cli/api/plugins/actions' }, + { text: 'blockExplorer', link: '/cli/api/plugins/blockExplorer' }, + { text: 'etherscan', link: '/cli/api/plugins/etherscan' }, + { text: 'fetch', link: '/cli/api/plugins/fetch' }, + { text: 'foundry', link: '/cli/api/plugins/foundry' }, + { text: 'hardhat', link: '/cli/api/plugins/hardhat' }, + { text: 'react', link: '/cli/api/plugins/react' }, + { text: 'sourcify', link: '/cli/api/plugins/sourcify' }, + ], + }, + { + text: 'create-wagmi', + link: '/cli/create-wagmi', + }, + ], + '/dev': [ + { + text: 'Dev', + items: [ + { text: 'Contributing', link: '/dev/contributing' }, + { text: 'Creating Connectors', link: '/dev/creating-connectors' }, + ], + }, + ], + '/examples': [ + { + text: 'React', + items: [ + { text: 'Connect Wallet', link: '/examples/connect-wallet' }, + { text: 'Send Transaction', link: '/examples/send-transaction' }, + { text: 'Write Contract', link: '/examples/contract-write' }, + { + text: 'Write Contract (Dynamic Args)', + link: '/examples/contract-write-dynamic', + }, + { text: 'Sign Message', link: '/examples/sign-message' }, + { + text: 'Sign In With Ethereum', + link: '/examples/sign-in-with-ethereum', + }, + ], + }, + ], + } satisfies DefaultTheme.Sidebar +} diff --git a/wagmi-project/site/.vitepress/theme/components/AsideSponsors.vue b/wagmi-project/site/.vitepress/theme/components/AsideSponsors.vue new file mode 100644 index 0000000000..09e1075abb --- /dev/null +++ b/wagmi-project/site/.vitepress/theme/components/AsideSponsors.vue @@ -0,0 +1,27 @@ + + + + diff --git a/wagmi-project/site/.vitepress/theme/components/Banner.vue b/wagmi-project/site/.vitepress/theme/components/Banner.vue new file mode 100644 index 0000000000..14ccf48b91 --- /dev/null +++ b/wagmi-project/site/.vitepress/theme/components/Banner.vue @@ -0,0 +1,16 @@ +// TODO: Dismissable, a11y, etc. +// https://github.com/faker-js/faker/pull/1487 + + + + diff --git a/wagmi-project/site/.vitepress/theme/components/HomeBanner.vue b/wagmi-project/site/.vitepress/theme/components/HomeBanner.vue new file mode 100644 index 0000000000..dbbf1c4f89 --- /dev/null +++ b/wagmi-project/site/.vitepress/theme/components/HomeBanner.vue @@ -0,0 +1,13 @@ + + + + diff --git a/wagmi-project/site/.vitepress/theme/components/HomePage.vue b/wagmi-project/site/.vitepress/theme/components/HomePage.vue new file mode 100644 index 0000000000..31e1e10574 --- /dev/null +++ b/wagmi-project/site/.vitepress/theme/components/HomePage.vue @@ -0,0 +1,118 @@ + + + + + diff --git a/wagmi-project/site/.vitepress/theme/composables/useSponsors.ts b/wagmi-project/site/.vitepress/theme/composables/useSponsors.ts new file mode 100644 index 0000000000..571a2b7df6 --- /dev/null +++ b/wagmi-project/site/.vitepress/theme/composables/useSponsors.ts @@ -0,0 +1,212 @@ +import { onMounted, ref } from 'vue' + +type Sponsor = { + name: string + img: string + url: string +} + +type Data = { + size: 'big' | 'medium' | 'small' + items: Sponsor[] + tier: string + type: 'platinum' | 'gold' | 'silver' +}[] + +// shared data across instances so we load only once. +const data = ref() + +// TODO: Data powered +// const dataHost = 'https://sponsors.vuejs.org' +// const dataUrl = `${dataHost}/vite.json` + +export function useSponsors() { + onMounted(async () => { + if (data.value) return + + // const result = await fetch(dataUrl) + // const json = await result.json() + // console.log(json) + const sponsors = { + platinum: [ + { + name: 'Paradigm', + url: 'https://paradigm.xyz', + img: 'paradigm-light.svg', + }, + { + name: 'Ithaca', + url: 'https://ithaca.xyz', + img: 'ithaca-light.svg', + }, + ], + gold: [ + { + name: 'Stripe', + url: 'https://www.stripe.com', + img: 'stripe-light.svg', + }, + { + name: 'zkSync', + url: 'https://zksync.io', + img: 'zksync-light.svg', + }, + { + name: 'Linea', + url: 'https://linea.build', + img: 'linea-light.svg', + }, + { + name: 'Routescan', + url: 'https://routescan.io', + img: 'routescan-light.svg', + }, + ], + silver: [ + { + name: 'Family', + url: 'https://twitter.com/family', + img: 'family-light.svg', + }, + { + name: 'Context', + url: 'https://twitter.com/context', + img: 'context-light.svg', + }, + { + name: 'WalletConnect', + url: 'https://walletconnect.com', + img: 'walletconnect-light.svg', + }, + { + name: 'PartyDAO', + url: 'https://twitter.com/prtyDAO', + img: 'partydao-light.svg', + }, + { + name: 'SushiSwap', + url: 'https://www.sushi.com', + img: 'sushi-light.svg', + }, + { + name: 'Dynamic', + url: 'https://www.dynamic.xyz', + img: 'dynamic-light.svg', + }, + { + name: 'Privy', + url: 'https://privy.io', + img: 'privy-light.svg', + }, + { + name: 'PancakeSwap', + url: 'https://pancakeswap.finance', + img: 'pancake-light.svg', + }, + { + name: 'Celo', + url: 'https://celo.org', + img: 'celo-light.svg', + }, + { + name: 'Rainbow', + url: 'https://rainbow.me', + img: 'rainbow-light.svg', + }, + { + name: 'Pimlico', + url: 'https://pimlico.io', + img: 'pimlico-light.svg', + }, + { + name: 'Zora', + url: 'https://zora.co', + img: 'zora-light.svg', + }, + { + name: 'Lattice', + url: 'https://lattice.xyz', + img: 'lattice-light.svg', + }, + { + name: 'Supa', + url: 'https://twitter.com/supafinance', + img: 'supa-light.svg', + }, + { + name: 'Syndicate', + url: 'https://syndicate.io', + img: 'syndicate-light.svg', + }, + { + name: 'Reservoir', + url: 'https://reservoir.tools', + img: 'reservoir-light.svg', + }, + { + name: 'Uniswap', + url: 'https://uniswap.org', + img: 'uniswap-light.svg', + }, + { + name: 'Biconomy', + url: 'https://biconomy.io', + img: 'biconomy-light.svg', + }, + { + name: 'Thirdweb', + url: 'https://thirdweb.com', + img: 'thirdweb-light.svg', + }, + { + name: 'Polymarket', + url: 'https://polymarket.com', + img: 'polymarket-light.svg', + }, + { + name: 'Sequence', + url: 'https://sequence.xyz', + img: 'sequence-light.svg', + }, + ], + } + + data.value = mapSponsors(sponsors) + }) + + return { data } +} + +function mapSponsors(sponsors: { + platinum: Sponsor[] + gold: Sponsor[] + silver: Sponsor[] +}) { + return [ + { + size: 'big', + items: mapImgPath(sponsors.platinum), + tier: 'Collaborators', + type: 'platinum', + }, + { + size: 'medium', + items: mapImgPath(sponsors.gold), + tier: 'Large Enterprises', + type: 'gold', + }, + { + size: 'small', + items: mapImgPath(sponsors.silver), + tier: 'Small Enterprises', + type: 'silver', + }, + ] satisfies Data +} + +function mapImgPath(sponsors: Sponsor[]) { + return sponsors.map((sponsor) => ({ + ...sponsor, + img: `https://raw.githubusercontent.com/wevm/.github/main/content/sponsors/${sponsor.img}`, + })) +} diff --git a/wagmi-project/site/.vitepress/theme/index.ts b/wagmi-project/site/.vitepress/theme/index.ts new file mode 100644 index 0000000000..abcc802176 --- /dev/null +++ b/wagmi-project/site/.vitepress/theme/index.ts @@ -0,0 +1,30 @@ +import TwoslashFloatingVue from '@shikijs/vitepress-twoslash/client' +import type { Theme } from 'vitepress' +import DefaultTheme from 'vitepress/theme' +// https://vitepress.dev/guide/custom-theme +import { h } from 'vue' + +import '@shikijs/vitepress-twoslash/style.css' +import 'uno.css' +import './style.css' + +import AsideSponsors from './components/AsideSponsors.vue' +// import Banner from './components/Banner.vue' +import HomeBanner from './components/HomeBanner.vue' +import HomePage from './components/HomePage.vue' + +export default { + extends: DefaultTheme, + Layout() { + return h(DefaultTheme.Layout, null, { + // https://vitepress.dev/guide/extending-default-theme#layout-slots + 'aside-ads-before': () => h(AsideSponsors), + // 'doc-before': () => h(Banner), + 'home-features-after': () => h(HomePage), + 'home-hero-before': () => h(HomeBanner), + }) + }, + enhanceApp({ app }) { + app.use(TwoslashFloatingVue) + }, +} satisfies Theme diff --git a/wagmi-project/site/.vitepress/theme/style.css b/wagmi-project/site/.vitepress/theme/style.css new file mode 100644 index 0000000000..4ec569cf05 --- /dev/null +++ b/wagmi-project/site/.vitepress/theme/style.css @@ -0,0 +1,148 @@ +/** + * Customize default theme styling by overriding CSS variables: + * https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css + */ + +/** + * Colors + * + * Each colors have exact same color scale system with 3 levels of solid + * colors with different brightness, and 1 soft color. + * + * - `XXX-1`: The most solid color used mainly for colored text. It must + * satisfy the contrast ratio against when used on top of `XXX-soft`. + * + * - `XXX-2`: The color used mainly for hover state of the button. + * + * - `XXX-3`: The color for solid background, such as bg color of the button. + * It must satisfy the contrast ratio with pure white (#ffffff) text on + * top of it. + * + * - `XXX-soft`: The color used for subtle background such as custom container + * or badges. It must satisfy the contrast ratio when putting `XXX-1` colors + * on top of it. + * + * The soft color must be semi transparent alpha channel. This is crucial + * because it allows adding multiple "soft" colors on top of each other + * to create a accent, such as when having inline code block inside + * custom containers. + * + * - `default`: The color used purely for subtle indication without any + * special meanings attached to it such as bg color for menu hover state. + * + * - `brand`: Used for primary brand colors, such as link text, button with + * brand theme, etc. + * + * - `tip`: Used to indicate useful information. The default theme uses the + * brand color for this by default. + * + * - `warning`: Used to indicate warning to the users. Used in custom + * container, badges, etc. + * + * - `danger`: Used to show error, or dangerous message to the users. Used + * in custom container, badges, etc. + * -------------------------------------------------------------------------- */ + +:root { + --vp-c-default-1: var(--vp-c-gray-1); + --vp-c-default-2: var(--vp-c-gray-2); + --vp-c-default-3: var(--vp-c-gray-3); + --vp-c-default-soft: var(--vp-c-gray-soft); + + --vp-c-brand-1: var(--vp-c-indigo-1); + --vp-c-brand-2: var(--vp-c-indigo-2); + --vp-c-brand-3: var(--vp-c-indigo-3); + --vp-c-brand-soft: var(--vp-c-indigo-soft); + + --vp-c-tip-1: var(--vp-c-brand-1); + --vp-c-tip-2: var(--vp-c-brand-2); + --vp-c-tip-3: var(--vp-c-brand-3); + --vp-c-tip-soft: var(--vp-c-brand-soft); + + --vp-c-warning-1: var(--vp-c-yellow-1); + --vp-c-warning-2: var(--vp-c-yellow-2); + --vp-c-warning-3: var(--vp-c-yellow-3); + --vp-c-warning-soft: var(--vp-c-yellow-soft); + + --vp-c-danger-1: var(--vp-c-red-1); + --vp-c-danger-2: var(--vp-c-red-2); + --vp-c-danger-3: var(--vp-c-red-3); + --vp-c-danger-soft: var(--vp-c-red-soft); +} + +/** + * Component: Button + * -------------------------------------------------------------------------- */ + +:root { + --vp-button-brand-border: transparent; + --vp-button-brand-text: var(--vp-c-white); + --vp-button-brand-bg: var(--vp-c-brand-3); + --vp-button-brand-hover-border: transparent; + --vp-button-brand-hover-text: var(--vp-c-white); + --vp-button-brand-hover-bg: var(--vp-c-brand-2); + --vp-button-brand-active-border: transparent; + --vp-button-brand-active-text: var(--vp-c-white); + --vp-button-brand-active-bg: var(--vp-c-brand-1); +} + +/** + * Component: Home + * -------------------------------------------------------------------------- */ + +:root { + --vp-home-hero-name-color: transparent; + --vp-home-hero-name-background: -webkit-linear-gradient( + 120deg, + #bd34fe 30%, + #41d1ff + ); + + --vp-home-hero-image-background-image: linear-gradient( + -45deg, + #bd34fe 50%, + #47caff 50% + ); + --vp-home-hero-image-filter: blur(44px); +} + +@media (min-width: 640px) { + :root { + --vp-home-hero-image-filter: blur(56px); + } +} + +@media (min-width: 960px) { + :root { + --vp-home-hero-image-filter: blur(68px); + } +} + +/** + * Component: Custom Block + * -------------------------------------------------------------------------- */ + +:root { + --vp-custom-block-tip-border: transparent; + --vp-custom-block-tip-text: var(--vp-c-text-1); + --vp-custom-block-tip-bg: var(--vp-c-brand-soft); + --vp-custom-block-tip-code-bg: var(--vp-c-brand-soft); +} + +/** + * Component: Algolia + * -------------------------------------------------------------------------- */ + +.DocSearch { + --docsearch-primary-color: var(--vp-c-brand-1) !important; +} + +.vp-doc [class*="language-"] .has-focused-lines .line:not(.has-focus) { + filter: unset; + opacity: 0.3; +} + +.twoslash-error-line { + max-width: min-content; + white-space: wrap; +} diff --git a/wagmi-project/site/cli/api/commands.md b/wagmi-project/site/cli/api/commands.md new file mode 100644 index 0000000000..643397560b --- /dev/null +++ b/wagmi-project/site/cli/api/commands.md @@ -0,0 +1,53 @@ +# Commands + +## Available Commands + +- [`init`](/cli/api/commands/init) Creates configuration file. +- [`generate`](/cli/api/commands/generate) Generates code based on configuration, using `contracts` and `plugins`. + +## Display Info + +### `-h`, `--help` + +Show help message when `-h`, `--help` flags appear. + +::: code-group +```bash [pnpm] +pnpm wagmi --help +``` + +```bash [npm] +npx wagmi --help +``` + +```bash [yarn] +yarn wagmi --help +``` + +```bash [bun] +bun wagmi --help +``` +::: + +### `-v`, `--version` + +Show version number when `-v`, `--version` flags appear. + +::: code-group +```bash [pnpm] +pnpm wagmi --version +``` + +```bash [npm] +npx wagmi --version +``` + +```bash [yarn] +yarn wagmi --version +``` + +```bash [bun] +bun wagmi --version +``` +::: + diff --git a/wagmi-project/site/cli/api/commands/generate.md b/wagmi-project/site/cli/api/commands/generate.md new file mode 100644 index 0000000000..d1f88e90a0 --- /dev/null +++ b/wagmi-project/site/cli/api/commands/generate.md @@ -0,0 +1,49 @@ +# generate + +Generates code based on configuration, using `contracts` and `plugins`. + +## Usage + +```bash +wagmi generate +``` + +## Options + +### -c, --config \ + +`string` + +Path to config file. + +```bash +wagmi generate --config wagmi.config.ts +``` + +### -r, --root \ + +`string` + +Root path to resolve config from. + +```bash +wagmi generate --root path/to/root +``` + +### -w, --watch + +`boolean` + +Watch for changes (for plugins that support watch mode). + +```bash +wagmi generate --watch +``` + +### -h, --help + +Displays help message. + +```bash +wagmi generate --help +``` \ No newline at end of file diff --git a/wagmi-project/site/cli/api/commands/init.md b/wagmi-project/site/cli/api/commands/init.md new file mode 100644 index 0000000000..440315e9c7 --- /dev/null +++ b/wagmi-project/site/cli/api/commands/init.md @@ -0,0 +1,40 @@ +# init + +Creates configuration file. If TypeScript is detected, the config file will use TypeScript and be named `wagmi.config.ts`. Otherwise, the config file will use JavaScript and be named `wagmi.config.js`. + +## Usage + +```bash +wagmi init +``` + +## Options + +### -c, --config \ + +`string` + +Path to config file. + +```bash +wagmi init --config wagmi.config.ts +``` + +### -r, --root \ + +`string` + +Root path to resolve config from. + +```bash +wagmi init --root path/to/root +``` + +### -h, --help + +Displays help message. + +```bash +wagmi init --help +``` + diff --git a/wagmi-project/site/cli/api/plugins.md b/wagmi-project/site/cli/api/plugins.md new file mode 100644 index 0000000000..54afdb19e1 --- /dev/null +++ b/wagmi-project/site/cli/api/plugins.md @@ -0,0 +1,42 @@ +# Plugins + +Plugins for managing ABIs, generating code, and more. + +## Import + +Import via the `'@wagmi/cli/plugins'` entrypoint. + +```ts +import { etherscan } from '@wagmi/cli/plugins' +``` + +## Available Plugins + +- [`actions`](/cli/api/plugins/actions) Generate type-safe VanillaJS actions from configuration `contracts`. +- [`blockExplorer`](/cli/api/plugins/blockExplorer) Fetch ABIs from Block Explorers that support `?module=contract&action=getabi`. +- [`etherscan`](/cli/api/plugins/etherscan) Fetch ABIs from Etherscan and add into configuration. +- [`fetch`](/cli/api/plugins/fetch) Fetch and parse ABIs from network resource with `fetch`. +- [`foundry`](/cli/api/plugins/foundry) Generate ABIs and watch for Foundry project changes. +- [`hardhat`](/cli/api/plugins/hardhat) Generate ABIs and watch for Hardhat projects changes. +- [`react`](/cli/api/plugins/react) Generate type-safe React Hooks from configuration `contracts`. +- [`sourcify`](/cli/api/plugins/sourcify) Fetch ABIs from Sourcify from configuration `contracts`. + +## Create Plugin + +Creating plugins to hook into the CLI is quite simple. Plugins most commonly inject contracts into `contracts` config, e.g. [`etherscan`](/cli/api/plugins/etherscan), and/or generate code using the `run` option, e.g. [`react`](/cli/api/plugins/react). All you need to do is write a function that returns the `Plugin` type. + +```ts{3-8} +import { type Plugin, defineConfig } from '@wagmi/cli' + +function myPlugin(): Plugin { + // `name` is the only required property. + name: 'MyPlugin', + // You likely want to at least include `contracts` or `run`. + // ... +} + +export default defineConfig({ + out: 'src/generated.ts', + plugins: [myPlugin()], +}) +``` diff --git a/wagmi-project/site/cli/api/plugins/actions.md b/wagmi-project/site/cli/api/plugins/actions.md new file mode 100644 index 0000000000..d62a29a6b7 --- /dev/null +++ b/wagmi-project/site/cli/api/plugins/actions.md @@ -0,0 +1,72 @@ +# actions + +Plugin for type-safe VanillaJS actions. + +## Import + +```ts +import { actions } from '@wagmi/cli/plugins' +``` + +## Usage + +```ts{2,6} +import { defineConfig } from '@wagmi/cli' +import { actions } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + actions(), + ], +}) +``` + +## Configuration + +```ts +import { type ActionsConfig } from '@wagmi/cli/plugins' +``` + +### getActionName + +`` 'legacy' | ((options: { contractName: string; type: 'read' | 'simulate' | 'watch' | 'write' }) => `use${string}`) `` + +- Function for setting custom hook names. +- Defaults to `` `${type}${contractName}` ``. For example, `readErc20`, `simulateErc20`, `watchErc20Event`, `writeErc20`. +- When `'legacy'` (deprecated), hook names are set to `@wagmi/cli@1` format. + +```ts +import { defineConfig } from '@wagmi/cli' +import { actions } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + actions({ + getActionName({ contractName, type }) { // [!code focus] + return `${contractName}__${type}` // [!code focus] + }, // [!code focus] + }), + ], +}) +``` + +### overridePackageName + +`'@wagmi/core' | 'wagmi'` + +- Override detected import source. +- Defaults to `'wagmi'` or `'@wagmi/core'` depending on which package is installed. + +```ts +import { defineConfig } from '@wagmi/cli' +import { actions } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + actions({ + overridePackageName: 'wagmi', // [!code focus] + }), + ], +}) +``` + diff --git a/wagmi-project/site/cli/api/plugins/blockExplorer.md b/wagmi-project/site/cli/api/plugins/blockExplorer.md new file mode 100644 index 0000000000..462e37bddd --- /dev/null +++ b/wagmi-project/site/cli/api/plugins/blockExplorer.md @@ -0,0 +1,223 @@ +# blockExplorer + +Plugin for fetching ABIs from block explorers that supports the `?module=contract&action=getabi` API format. + +## Import + +```ts +import { blockExplorer } from '@wagmi/cli/plugins' +``` + +## Usage + +```ts{2,6-14} +import { defineConfig } from '@wagmi/cli' +import { blockExplorer } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + blockExplorer({ + baseUrl: 'https://api.etherscan.io/v2/api', + contracts: [ + { + name: 'Wagmigotchi', + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + }, + ], + }), + ], +}) +``` + +## Configuration + +```ts +import { type BlockExplorerConfig } from '@wagmi/cli/plugins' +``` + +### apiKey + +`string | undefined` + +API key for block explorer. Appended to the request URL as query param `&apikey=${apiKey}`. + +```ts +import { defineConfig } from '@wagmi/cli' +import { blockExplorer } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + blockExplorer({ + apiKey: process.env.ETHERSCAN_API_KEY, // [!code focus] + baseUrl: 'https://api.etherscan.io/v2/api', + contracts: [ + { + name: 'Wagmigotchi', + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + }, + ], + }), + ], +}) +``` + +### baseUrl + +`string` + +Base URL for block explorer. + +```ts +import { defineConfig } from '@wagmi/cli' +import { blockExplorer } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + blockExplorer({ + baseUrl: 'https://api.etherscan.io/v2/api', // [!code focus] + contracts: [ + { + name: 'Wagmigotchi', + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + }, + ], + }), + ], +}) +``` + +### cacheDuration + +`number | undefined` + +Duration in milliseconds to cache ABIs. Defaults to `1_800_000` (30 minutes). + +```ts +import { defineConfig } from '@wagmi/cli' +import { blockExplorer } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + blockExplorer({ + baseUrl: 'https://api.etherscan.io/v2/api', + cacheDuration: 300_000, // [!code focus] + contracts: [ + { + name: 'Wagmigotchi', + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + }, + ], + }), + ], +}) +``` + +### chainId + +`number | undefined` + +Chain ID for block explorer. Appended to the request URL as query param `&chainId=${chainId}`. + +```ts +import { defineConfig } from '@wagmi/cli' +import { blockExplorer } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + blockExplorer({ + apiKey: process.env.ETHERSCAN_API_KEY, + baseUrl: 'https://api.etherscan.io/v2/api', + chainId: 1, // [!code focus] + contracts: [ + { + name: 'Wagmigotchi', + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + }, + ], + }), + ], +}) +``` + + +### contracts + +`{ name: string; address?: Address | Record | undefined }[]` + +Contracts to fetch ABIs for. + +```ts +import { defineConfig } from '@wagmi/cli' +import { blockExplorer } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + blockExplorer({ + baseUrl: 'https://api.etherscan.io/v2/api', + contracts: [ // [!code focus] + { // [!code focus] + name: 'Wagmigotchi', // [!code focus] + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', // [!code focus] + }, // [!code focus] + ], // [!code focus] + }), + ], +}) +``` + +### getAddress + +`((config: { address: Address | Record }) => Address) | undefined` + +- Function to get address from contract config. +- Defaults to `({ address }) => typeof address === 'string' ? address : Object.values(address)[0]`. + +```ts +import { defineConfig } from '@wagmi/cli' +import { blockExplorer } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + blockExplorer({ + baseUrl: 'https://api.etherscan.io/v2/api', + contracts: [ + { + name: 'Wagmigotchi', + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + }, + ], + getAddress({ address }) { // [!code focus] + if (typeof address === 'string') return address // [!code focus] + return Object.values(address)[0] // [!code focus] + }, // [!code focus] + }), + ], +}) +``` + +### name + +`string` + +- Name of source. +- Defaults to `'Block Explorer'`. + +```ts +import { defineConfig } from '@wagmi/cli' +import { blockExplorer } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + blockExplorer({ + baseUrl: 'https://api.etherscan.io/v2/api', + contracts: [ + { + name: 'Wagmigotchi', + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + }, + ], + name: 'Etherscan', // [!code focus] + }), + ], +}) +``` diff --git a/wagmi-project/site/cli/api/plugins/etherscan.md b/wagmi-project/site/cli/api/plugins/etherscan.md new file mode 100644 index 0000000000..ec52fd6796 --- /dev/null +++ b/wagmi-project/site/cli/api/plugins/etherscan.md @@ -0,0 +1,182 @@ +# etherscan + +Plugin for fetching ABIs from [Etherscan](https://etherscan.io) and adding into `contracts` config. + +## Import + +```ts +import { etherscan } from '@wagmi/cli/plugins' +``` + +## Usage + +```ts{2,6-14} +import { defineConfig } from '@wagmi/cli' +import { etherscan } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + etherscan({ + apiKey: process.env.ETHERSCAN_API_KEY, + chainId: 1, + contracts: [ + { + name: 'Wagmigotchi', + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + }, + ], + }), + ], +}) +``` + +## Configuration + +```ts +import { type EtherscanConfig } from '@wagmi/cli/plugins' +``` + +### apiKey + +`string` + +Etherscan API key. Etherscan API keys are specific per network and include testnets (e.g. Ethereum Mainnet and Sepolia share same API key). + +```ts +import { defineConfig } from '@wagmi/cli' +import { etherscan } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + etherscan({ + apiKey: process.env.ETHERSCAN_API_KEY, // [!code focus] + chainId: 1, + contracts: [ + { + name: 'Wagmigotchi', + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + }, + ], + }), + ], +}) +``` + +### cacheDuration + +`number | undefined` + +- Duration in milliseconds to cache ABIs. +- Defaults to `1_800_000` (30 minutes). + +```ts +import { defineConfig } from '@wagmi/cli' +import { etherscan } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + etherscan({ + apiKey: process.env.ETHERSCAN_API_KEY, + cacheDuration: 300_000, // [!code focus] + chainId: 1, + contracts: [ + { + name: 'Wagmigotchi', + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + }, + ], + }), + ], +}) +``` + +### chainId + +`number` + +Chain ID to use for fetching ABI. If [`address`](/cli/config/options#address) is an object, `chainId` is used to select the address. + +View supported chains on the [Etherscan docs](https://docs.etherscan.io/etherscan-v2/getting-started/supported-chains). + +```ts +import { defineConfig } from '@wagmi/cli' +import { blockExplorer } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + etherscan({ + apiKey: process.env.ETHERSCAN_API_KEY, + chainId: 1, // [!code focus] + contracts: [ + { + name: 'Wagmigotchi', + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + }, + { + name: 'EnsRegistry', + address: { + 1: '0x314159265dd8dbb310642f98f50c066173c1259b', + 5: '0x112234455c3a32fd11230c42e7bccd4a84e02010', + }, + }, + ], + }), + ], +}) +``` + +### contracts + +`{ name: string; address?: Address | Record | undefined }[]` + +Contracts to fetch ABIs for. + +```ts +import { defineConfig } from '@wagmi/cli' +import { etherscan } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + etherscan({ + apiKey: process.env.ETHERSCAN_API_KEY, + chainId: 1, + contracts: [ // [!code focus] + { // [!code focus] + name: 'Wagmigotchi', // [!code focus] + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', // [!code focus] + }, // [!code focus] + ], // [!code focus] + }), + ], +}) +``` + +### tryFetchProxyImplementation + +`boolean | undefined` + +- Whether to try fetching proxy implementation address of the contract. +- Defaults to `false`. + +```ts +import { defineConfig } from '@wagmi/cli' +import { blockExplorer } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + etherscan({ + apiKey: process.env.ETHERSCAN_API_KEY, + chainId: 1, + contracts: [ + { + name: 'FiatToken', + address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + }, + ], + tryFetchProxyImplementation: true, // [!code focus] + }), + ], +}) +``` + + diff --git a/wagmi-project/site/cli/api/plugins/fetch.md b/wagmi-project/site/cli/api/plugins/fetch.md new file mode 100644 index 0000000000..8d463a7ab6 --- /dev/null +++ b/wagmi-project/site/cli/api/plugins/fetch.md @@ -0,0 +1,269 @@ +# fetch + +Plugin for fetching and parsing ABIs from network resource with `fetch`. + +## Import + +```ts +import { fetch } from '@wagmi/cli/plugins' +``` + +## Usage + +```ts{2,6-23} +import { defineConfig } from '@wagmi/cli' +import { fetch } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + fetch({ + contracts: [ + { + name: 'Wagmigotchi', + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + }, + ], + request(contract) { + if (!contract.address) throw new Error('address is required') + const address = + typeof contract.address === 'string' + ? contract.address + : Object.values(contract.address)[0] + return { + url: `https://api.etherscan.io/api?module=contract&action=getabi&address=${address}`, + } + }, + }), + ], +}) +``` + + +## Configuration + +```ts +import { type FetchConfig } from '@wagmi/cli/plugins' +``` + +### cacheDuration + +`number | undefined` + +- Duration in milliseconds to cache ABIs. +- Defaults to `1_800_000` (30 minutes). + +```ts +import { defineConfig } from '@wagmi/cli' +import { fetch } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + fetch({ + cacheDuration: 300_000, // [!code focus] + contracts: [ + { + name: 'Wagmigotchi', + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + }, + ], + request(contract) { + if (!contract.address) throw new Error('address is required') + const address = + typeof contract.address === 'string' + ? contract.address + : Object.values(contract.address)[0] + return { + url: `https://api.etherscan.io/api?module=contract&action=getabi&address=${address}`, + } + }, + }), + ], +}) +``` + +### contracts + +`{ name: string; address?: Address | Record | undefined }[]` + +Contracts to fetch ABIs for. + +```ts +import { defineConfig } from '@wagmi/cli' +import { fetch } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + fetch({ + contracts: [ // [!code focus] + { // [!code focus] + name: 'Wagmigotchi', // [!code focus] + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', // [!code focus] + }, // [!code focus] + ], // [!code focus] + request(contract) { + if (!contract.address) throw new Error('address is required') + const address = + typeof contract.address === 'string' + ? contract.address + : Object.values(contract.address)[0] + return { + url: `https://api.etherscan.io/api?module=contract&action=getabi&address=${address}`, + } + }, + }), + ], +}) + +``` + +### getCacheKey + +`((config: { contract: { address: Address | Record | undefined; name: string } }) => string) | undefined` + +- Function for creating a cache key for contract. Contract data is cached at `~/.wagmi-cli/plugins/fetch/cache/`. +- Defaults to `({ contract }) => JSON.stringify(contract)`. + +```ts +import { defineConfig } from '@wagmi/cli' +import { fetch } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + fetch({ + contracts: [ + { + name: 'wagmigotchi', + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + }, + ], + getCacheKey({ contract }) { // [!code focus] + if (typeof contract.address === 'string') // [!code focus] + return `${name}:${contract.address}` // [!code focus] + return `${name}:${JSON.stringify(contract.address)}` // [!code focus] + }, // [!code focus] + request(contract) { + if (!contract.address) throw new Error('address is required') + const address = + typeof contract.address === 'string' + ? contract.address + : Object.values(contract.address)[0] + return { + url: `https://api.etherscan.io/api?module=contract&action=getabi&address=${address}`, + } + }, + }), + ], +}) + +``` + +### name + +`string` + +- Name of source. +- Defaults to `'Fetch'`. + +```ts +import { defineConfig } from '@wagmi/cli' +import { fetch } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + fetch({ + contracts: [ + { + name: 'Wagmigotchi', + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + }, + ], + name: 'Etherscan', // [!code focus] + request(contract) { + if (!contract.address) throw new Error('address is required') + const address = + typeof contract.address === 'string' + ? contract.address + : Object.values(contract.address)[0] + return { + url: `https://api.etherscan.io/api?module=contract&action=getabi&address=${address}`, + } + }, + }), + ], +}) +``` + +### parse + +`((config: { response: Response }) => Abi | Promise) | undefined` + +- Function for parsing ABI from fetch response. +- Defaults to `({ response }) => response.json()` + +```ts +import { defineConfig } from '@wagmi/cli' +import { fetch } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + fetch({ + contracts: [ + { + name: 'Wagmigotchi', + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + }, + ], + async parse({ response }) { // [!code focus] + const json = await response.json() // [!code focus] + if (json.status === '0') throw new Error(json.message) // [!code focus] + return json.result // [!code focus] + }, // [!code focus] + request(contract) { + if (!contract.address) throw new Error('address is required') + const address = + typeof contract.address === 'string' + ? contract.address + : Object.values(contract.address)[0] + return { + url: `https://api.etherscan.io/api?module=contract&action=getabi&address=${address}`, + } + }, + }), + ], +}) +``` + +### request + +`(config: { address?: Address | Record | undefined }) => { url: RequestInfo; init?: RequestInit | undefined } | Promise<{ url: RequestInfo; init?: RequestInit | undefined }>` + +Function for returning a request to fetch ABI from. + +```ts +import { defineConfig } from '@wagmi/cli' +import { fetch } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + fetch({ + contracts: [ + { + name: 'Wagmigotchi', + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + }, + ], + request(contract) { // [!code focus] + if (!contract.address) throw new Error('address is required') // [!code focus] + const address = // [!code focus] + typeof contract.address === 'string' // [!code focus] + ? contract.address // [!code focus] + : Object.values(contract.address)[0] // [!code focus] + return { // [!code focus] + url: `https://api.etherscan.io/api?module=contract&action=getabi&address=${address}`, // [!code focus] + } // [!code focus] + }, // [!code focus] + }), + ], +}) + +``` diff --git a/wagmi-project/site/cli/api/plugins/foundry.md b/wagmi-project/site/cli/api/plugins/foundry.md new file mode 100644 index 0000000000..d24677b5c0 --- /dev/null +++ b/wagmi-project/site/cli/api/plugins/foundry.md @@ -0,0 +1,217 @@ +# foundry + +Plugin for resolving ABIs from [Foundry](https://github.com/foundry-rs/foundry) projects. Supports [`watch`](/cli/api/commands/generate#w-watch) mode. + +## Import + +```ts +import { foundry } from '@wagmi/cli/plugins' +``` + +## Usage + +```ts{2,6-8} +import { defineConfig } from '@wagmi/cli' +import { foundry } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + foundry({ + project: '../hello_foundry', + }), + ], +}) +``` + +## Configuration + +```ts +import { type FoundryConfig } from '@wagmi/cli/plugins' +``` + +### artifacts + +`string | undefined` + +- Project's artifacts directory. Same as your `foundry.toml`/`forge`s `--out` (`-o`) option. +- Defaults to `'out/'`. + +```ts +import { defineConfig } from '@wagmi/cli' +import { foundry } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + foundry({ + artifacts: 'out/', // [!code focus] + }), + ], +}) +``` + +### deployments + +`{ [key: string]: address?: Address | Record | undefined } | undefined` + +Mapping of addresses to attach to artifacts. + +```ts +import { defineConfig } from '@wagmi/cli' +import { foundry } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + foundry({ + deployments: { // [!code focus] + Counter: { // [!code focus] + 1: '0x314159265dd8dbb310642f98f50c066173c1259b', // [!code focus] + 5: '0x112234455c3a32fd11230c42e7bccd4a84e02010', // [!code focus] + }, // [!code focus] + }, // [!code focus] + }), + ], +}) +``` + +### exclude + +`string[] | undefined` + +Artifact files to exclude relative to `artifacts`. Supports glob patterns. + +```ts +import { defineConfig } from '@wagmi/cli' +import { foundry } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + foundry({ + exclude: [ // [!code focus] + // the following patterns are excluded by default // [!code focus] + 'Common.sol/**', // [!code focus] + 'Components.sol/**', // [!code focus] + 'Script.sol/**', // [!code focus] + 'StdAssertions.sol/**', // [!code focus] + 'StdInvariant.sol/**', // [!code focus] + 'StdError.sol/**', // [!code focus] + 'StdCheats.sol/**', // [!code focus] + 'StdMath.sol/**', // [!code focus] + 'StdJson.sol/**', // [!code focus] + 'StdStorage.sol/**', // [!code focus] + 'StdUtils.sol/**', // [!code focus] + 'Vm.sol/**', // [!code focus] + 'console.sol/**', // [!code focus] + 'console2.sol/**', // [!code focus] + 'test.sol/**', // [!code focus] + '**.s.sol/*.json', // [!code focus] + '**.t.sol/*.json', // [!code focus] + ], // [!code focus] + }), + ], +}) +``` + +### forge + +`{ clean?: boolean | undefined; build?: boolean | undefined; path?: string | undefined; rebuild?: boolean | undefined } | undefined` + +Options for `forge`. + +```ts +import { defineConfig } from '@wagmi/cli' +import { foundry } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + foundry({ + forge: { // [!code focus] + clean: true, // [!code focus] + build: true, // [!code focus] + path: 'path/to/forge', // [!code focus] + rebuild: true, // [!code focus] + }, // [!code focus] + }), + ], +}) +``` + +#### clean + +- Remove build artifacts and cache directories on start up. +- Defaults to `false`. + +#### build + +- Build Foundry project before fetching artifacts. +- Defaults to `true`. + +#### path + +- Path to `forge` executable command. +- Defaults to `forge`. + +#### rebuild + +- Rebuild every time a watched file or directory is changed. Used for setting up [`watch`](/cli/api/commands/generate#w-watch) mode. +- Defaults to `true`. + +### include + +`string[] | undefined` + +Artifact files to include relative to `artifacts`. Supports glob patterns. + +```ts +import { defineConfig } from '@wagmi/cli' +import { foundry } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + foundry({ + include: [ // [!code focus] + // the following patterns are included by default // [!code focus] + '*.json', // [!code focus] + ], // [!code focus] + }), + ], +}) +``` + +### namePrefix + +`string | undefined` + +Prefix to prepend to artifact names. Useful for preventing name collisions between contracts from other sources. + +```ts +import { defineConfig } from '@wagmi/cli' +import { foundry } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + foundry({ // [!code focus] + namePrefix: 'HelloFoundry', // [!code focus] + }), // [!code focus] + ], +}) +``` + +### project + +`string | undefined` + +- Path to Foundry project. +- Defaults to Foundry configuration using `forge config --json` command. + +```ts +import { defineConfig } from '@wagmi/cli' +import { foundry } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + foundry({ // [!code focus] + project: '../hello_foundry', // [!code focus] + }), // [!code focus] + ], +}) +``` \ No newline at end of file diff --git a/wagmi-project/site/cli/api/plugins/hardhat.md b/wagmi-project/site/cli/api/plugins/hardhat.md new file mode 100644 index 0000000000..38cca9aebe --- /dev/null +++ b/wagmi-project/site/cli/api/plugins/hardhat.md @@ -0,0 +1,199 @@ +# hardhat + +Plugin for resolving ABIs from [Hardhat](https://hardhat.org) projects. Supports [`watch`](/cli/api/commands/generate#w-watch) mode. + +```ts +import { hardhat } from '@wagmi/cli/plugins' +``` + +## Usage + +```ts{2,6-8} +import { defineConfig } from '@wagmi/cli' +import { hardhat } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + hardhat({ + project: '../hello_hardhat', + }), + ], +}) +``` + +## Configuration + +```ts +import { type HardhatConfig } from '@wagmi/cli/plugins' +``` + +### artifacts + +`string | undefined` + +- Project's artifacts directory. Same as your project's `artifacts` [path configuration](https://hardhat.org/hardhat-runner/docs/config#path-configuration) option. +- Defaults to `'artifacts/'`. + +```ts +import { defineConfig } from '@wagmi/cli' +import { hardhat } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + hardhat({ + artifacts: 'out/', // [!code focus] + project: '../hello_hardhat', + }), + ], +}) +``` + +### deployments + +`{ [key: string]: address?: Address | Record | undefined } | undefined` + +Mapping of addresses to attach to artifacts. + +```ts +import { defineConfig } from '@wagmi/cli' +import { hardhat } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + hardhat({ + project: '../hello_hardhat', + deployments: { // [!code focus] + Counter: { // [!code focus] + 1: '0x314159265dd8dbb310642f98f50c066173c1259b', // [!code focus] + 5: '0x112234455c3a32fd11230c42e7bccd4a84e02010', // [!code focus] + }, // [!code focus] + }, // [!code focus] + }), + ], +}) +``` + +### exclude + +`string[] | undefined` + +Artifact files to exclude relative to `artifacts`. Supports glob patterns. + +```ts +import { defineConfig } from '@wagmi/cli' +import { hardhat } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + hardhat({ + exclude: [ // [!code focus] + // the following patterns are excluded by default // [!code focus] + 'build-info/**', // [!code focus] + '*.dbg.json', // [!code focus] + ], // [!code focus] + project: '../hello_hardhat', + }), + ], +}) +``` + +### commands + +`{ clean?: string | boolean | undefined; build?: string | boolean | undefined; rebuild?: string | boolean | undefined } | undefined` + +Hardhat command options. + +```ts +import { defineConfig } from '@wagmi/cli' +import { hardhat } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + hardhat({ + commands: { // [!code focus] + clean: 'pnpm hardhat clean', // [!code focus] + build: 'pnpm hardhat compile', // [!code focus] + rebuild: 'pnpm hardhat compile', // [!code focus] + }, // [!code focus] + project: '../hello_hardhat', + }), + ], +}) +``` + +#### clean + +- Remove build artifacts and cache directories on start up. +- Defaults to `'${packageManger} hardhat clean'`. + +#### build + +- Build Foundry project before fetching artifacts. +- Defaults to `'${packageManger} hardhat compile'`. + +#### rebuild + +- Command to run when watched file or directory is changed. Used for setting up [`watch`](/cli/api/commands/generate#w-watch) mode. +- Defaults to `'${packageManger} hardhat compile'`. + +### include + +`string[] | undefined` + +Artifact files to include relative to `artifacts`. Supports glob patterns. + +```ts +import { defineConfig } from '@wagmi/cli' +import { hardhat } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + hardhat({ + include: [ // [!code focus] + // the following patterns are included by default // [!code focus] + '*.json', // [!code focus] + ], // [!code focus] + project: '../hello_hardhat', + }), + ], +}) +``` + +### namePrefix + +`string | undefined` + +Prefix to prepend to artifact names. Useful for preventing name collisions between contracts from other sources. + +```ts +import { defineConfig } from '@wagmi/cli' +import { hardhat } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + hardhat({ + namePrefix: 'HelloHardhat', // [!code focus] + project: '../hello_hardhat', + }), + ], +}) +``` + +### project + +`string` + +Path to Hardhat project. + +```ts +import { defineConfig } from '@wagmi/cli' +import { hardhat } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + hardhat({ + project: '../hello_hardhat', // [!code focus] + }), + ], +}) +``` \ No newline at end of file diff --git a/wagmi-project/site/cli/api/plugins/react.md b/wagmi-project/site/cli/api/plugins/react.md new file mode 100644 index 0000000000..e78f782c6d --- /dev/null +++ b/wagmi-project/site/cli/api/plugins/react.md @@ -0,0 +1,52 @@ +# react + +Plugin for generating type-safe [Wagmi Hooks](/react/api/hooks). + +## Import + +```ts +import { react } from '@wagmi/cli/plugins' +``` + +## Usage + +```ts{2,6} +import { defineConfig } from '@wagmi/cli' +import { react } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + react(), + ], +}) +``` + +## Configuration + +```ts +import { type ReactConfig } from '@wagmi/cli/plugins' +``` + +### getHookName + +`` 'legacy' | ((options: { contractName: string; type: 'read' | 'simulate' | 'watch' | 'write' }) => `use${string}`) `` + +- Function for setting custom hook names. +- Defaults to `` `use${type}${contractName}` ``. For example, `useReadErc20`, `useSimulateErc20`, `useWatchErc20Event`, `useWriteErc20`. +- When `'legacy'` (deprecated), hook names are set to `@wagmi/cli@1` format. + +```ts +import { defineConfig } from '@wagmi/cli' +import { react } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + react({ + getHookName({ contractName, type }) { // [!code focus] + return `use${contractName}__${type}` // [!code focus] + }, // [!code focus] + }), + ], +}) +``` + diff --git a/wagmi-project/site/cli/api/plugins/sourcify.md b/wagmi-project/site/cli/api/plugins/sourcify.md new file mode 100644 index 0000000000..d965fdde02 --- /dev/null +++ b/wagmi-project/site/cli/api/plugins/sourcify.md @@ -0,0 +1,115 @@ +# sourcify + +Plugin for fetching ABIs from [Sourcify](https://sourcify.dev/). Sourcify is a decentralized, open-source, smart contract verification and metadata repository. + +## Import + +```ts +import { sourcify } from '@wagmi/cli/plugins' +``` + +## Usage + +```ts{2,6-13} +import { defineConfig } from '@wagmi/cli' +import { sourcify } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + sourcify({ + contracts: [ + { + name: 'deposit', + address: '0x00000000219ab540356cbb839cbe05303d7705fa', + }, + ], + }), + ], +}) +``` + +## Configuration + +```ts +import { type SourcifyConfig } from '@wagmi/cli/plugins' +``` + +### cacheDuration + +`number | undefined` + +- Duration in milliseconds to cache ABIs. +- Defaults to `1_800_000` (30 minutes). + +```ts +import { defineConfig } from '@wagmi/cli' +import { sourcify } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + sourcify({ + cacheDuration: 300_000, // [!code focus] + chainId: 100, + contracts: [ + { + name: 'Deposit', + address: '0x00000000219ab540356cbb839cbe05303d7705fa', + }, + ], + }), + ], +}) +``` + +### chainId + +`number` + +Chain ID to use for fetching ABI. If `address` is an object, `chainId` is used to select the address. See [Sourcify docs](https://docs.sourcify.dev/docs/chains) for supported chains. + +```ts +import { defineConfig } from '@wagmi/cli' +import { sourcify } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + sourcify({ + chainId: 100, // [!code focus] + contracts: [ + { + name: 'Community', + address: { + 100: '0xC4c622862a8F548997699bE24EA4bc504e5cA865', + 137: '0xC4c622862a8F548997699bE24EA4bc504e5cA865', + }, + }, + ], + }), + ], +}) +``` + +### contracts + +`{ name: string; address?: Address | Record | undefined }[]` + +Contracts to fetch ABIs for. + +```ts +import { defineConfig } from '@wagmi/cli' +import { sourcify } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + sourcify({ + chainId: 100, + contracts: [ // [!code focus] + { // [!code focus] + name: 'Deposit', // [!code focus] + address: '0x00000000219ab540356cbb839cbe05303d7705fa', // [!code focus] + }, // [!code focus] + ], // [!code focus] + }), + ], +}) +``` diff --git a/wagmi-project/site/cli/config/configuring-cli.md b/wagmi-project/site/cli/config/configuring-cli.md new file mode 100644 index 0000000000..9e8e11fae3 --- /dev/null +++ b/wagmi-project/site/cli/config/configuring-cli.md @@ -0,0 +1,124 @@ +# Configuring CLI + +When running `wagmi` from the command line, `@wagmi/cli` will automatically try to resolve a config file named `wagmi.config.js` or `wagmi.config.ts` inside the project root. The most basic config file looks like this: + +::: code-group +```js [wagmi.config.js] +export default { + // config options +} +``` +::: + +Note `@wagmi/cli` supports using ES modules syntax in the config file even if the project is not using native Node ESM, e.g. `"type": "module"` in package.json. In this case, the config file is auto pre-processed before load. + +You can also explicitly specify a config file to use with the `--config`/`-c` CLI option (resolved relative to the current directory): + +```bash +wagmi --config my-config.js +``` + +To scaffold a config file quickly, check out the [`init`](/cli/api/commands/init) command. + +## Config Intellisense + +Since Wagmi CLI ships with TypeScript typings, you can use your editor's intellisense with [JSDoc](https://jsdoc.app) type hints: + +::: code-group +```js [wagmi.config.js] +/** @type {import('@wagmi/cli').Config} */ +export default { + // ... +} +``` +::: + +Alternatively, you can use the `defineConfig` utility which should provide intellisense without the need for JSDoc annotations: + +::: code-group +```js [wagmi.config.js] +import { defineConfig } from '@wagmi/cli' + +export default defineConfig({ + // ... +}) +``` +::: + +Wagmi CLI also directly supports TypeScript config files. You can use `wagmi.config.ts` with the `defineConfig` helper as well. + +## Conditional Config + +If the config needs to conditionally determine options based on the environment, it can export a function instead: + +::: code-group +```js [wagmi.config.js] +export default defineConfig(() => { + if (process.env.NODE_ENV === 'dev') { + return { + // dev specific config + } + } else { + return { + // production specific config + } + } +}) +``` +::: + +## Async Config + +If the config needs to call async function, it can export a async function instead: + +::: code-group +```js [wagmi.config.js] +export default defineConfig(async () => { + const data = await asyncFunction() + return { + // ... + } +}) +``` +::: + +This can be useful for resolving external resources from the network or filesystem that are required for configuration ahead of running a command. + +## Array Config + +The config can also be represented either as a pre-defined array or returned as an array from a function: + +::: code-group +```js [wagmi.config.js] +export default defineConfig([ + { + // config 1 + }, + { + // config 2 + }, +]) +``` +::: + +## Environment Variables + +Environmental Variables can be obtained from `process.env` as usual. + +Note that Wagmi CLI doesn't load `.env` files by default as the files to load can only be determined after evaluating the config. However, you can use the exported `loadEnv` utility to load the specific `.env` files if needed. + +::: code-group +```js [wagmi.config.js] +import { defineConfig, loadEnv } from '@wagmi/cli' + +export default defineConfig(() => { + const env = loadEnv({ + mode: process.env.NODE_ENV, + envDir: process.cwd(), + }) + return { + // ... + } +}) +``` +::: \ No newline at end of file diff --git a/wagmi-project/site/cli/config/options.md b/wagmi-project/site/cli/config/options.md new file mode 100644 index 0000000000..04a2cd2d56 --- /dev/null +++ b/wagmi-project/site/cli/config/options.md @@ -0,0 +1,132 @@ +# Config Options + +Configuration options for Wagmi CLI. + +## contracts + +`ContractConfig[] | undefined` + +Array of contracts to use when running [commands](/cli/api/commands). `abi` and `name` are required, all other properties are optional. + +### address + +`Address | Record | undefined` + +Contract address or addresses. Accepts an object `{ [chainId]: address }` for targeting specific chains. + +::: code-group +```ts {6,11-14} [wagmi.config.ts] +export default { + out: 'src/generated.ts', + contracts: [ + { + abi: […], + address: '0x…', + name: 'MyCoolContract', + }, + { + abi: […], + address: { + 1: '0xfoo…', + 5: '0xbar…', + }, + name: 'MyCoolMultichainContract' + } + ], +} +``` +::: + +### abi + +`Abi` + +ABI for contract. Used by [plugins](/cli/api/plugins) to generate code base on properties. + +::: code-group +```ts {5} [wagmi.config.ts] +export default { + out: 'src/generated.ts', + contracts: [ + { + abi: […], + name: 'MyCoolContract' + }, + ], +} +``` +::: + +### name + +`string` + +Name of contract. Must be unique. Used by [plugins](/cli/api/plugins) to name generated code. + +::: code-group +```ts {6} [wagmi.config.ts] +export default { + out: 'src/generated.ts', + contracts: [ + { + abi: […], + name: 'MyCoolContract' + }, + ], +} +``` +::: + +## out + +`string` + +Path to output generated code. Must be unique per config. Use an [Array Config](/cli/config/configuring-cli#array-config) for multiple outputs. + +::: code-group +```ts {2} [wagmi.config.ts] +export default { + out: 'src/generated.ts', + contracts: [ + { + abi: […], + name: 'MyCoolContract' + }, + ], +} +``` +::: + +## plugins + +`Plugin[] | undefined` + +Plugins to use and their configuration. + +Wagmi CLI has multiple [built-in plugins](/cli/api/plugins) that are used to manage ABIs, generate code, etc. + +::: code-group +```ts {1,5-20} [wagmi.config.ts] +import { etherscan, react } from '@wagmi/cli/plugins' + +export default { + out: 'src/generated.js', + plugins: [ + etherscan({ + apiKey: process.env.ETHERSCAN_API_KEY, + chainId: 5, + contracts: [ + { + name: 'EnsRegistry', + address: { + 1: '0x314159265dd8dbb310642f98f50c066173c1259b', + 5: '0x112234455c3a32fd11230c42e7bccd4a84e02010', + }, + }, + ], + }), + react(), + ], +} +``` +::: diff --git a/wagmi-project/site/cli/create-wagmi.md b/wagmi-project/site/cli/create-wagmi.md new file mode 100644 index 0000000000..bdf8dda308 --- /dev/null +++ b/wagmi-project/site/cli/create-wagmi.md @@ -0,0 +1,75 @@ +# create-wagmi + +## Overview + +create-wagmi is a command line interface (CLI) for scaffolding new Wagmi projects. + +## Usage + +::: code-group +```bash [pnpm] +pnpm create wagmi +``` +```bash [npm] +npm create wagmi@latest +``` +```bash [yarn] +yarn create wagmi +``` +```bash [bun] +bun create wagmi +``` +::: + +## Options + +### `-t`, `--template` + +You can specify a custom [template](#templates) by passing the `--template`/`-t` flag: + +::: code-group +```bash [pnpm] +pnpm create wagmi --template next +``` +```bash [npm] +npm create wagmi@latest --template next +``` +```bash [yarn] +yarn create wagmi --template next +``` +```bash [bun] +bun create wagmi --template next +``` +::: + +### `--bun`/`--npm`/`--pnpm`/`--yarn` + +Use a specific package manager to install dependencies. By default, `create-wagmi` will use the package manager you used to run the command. + +### `-h`, `--help` + +Prints the help message. + +### `-v`, `--version` + +Prints the CLI version. + +## Templates + +`create-wagmi` currently comes with the following templates: + +- `next`: A Next.js Wagmi project. +- `nuxt`: A Nuxt Wagmi project. +- `vite-react`: A Vite (React) Wagmi project. +- `vite-vanilla`: A Vite Wagmi Core project. +- `vite-vue`: A Vite (Vue) Wagmi project. + +If you do not specify the template on the command line, you will be prompted to select a framework and variant. + +- **React** : A React project. + - **Vite** : A React + Vite Wagmi project (`vite-react`). + - **Next** : A React + Next Wagmi project (`next`). +- **Vue**: A Vue project. + - **Vite**: A Vue + Vite Wagmi project (`vite-vue`). + - **Nuxt**: A Vue + Nuxt Wagmi project (`nuxt`). +- **Vanilla**: A Vite Wagmi project without React (`vite-vanilla`). diff --git a/wagmi-project/site/cli/getting-started.md b/wagmi-project/site/cli/getting-started.md new file mode 100644 index 0000000000..ccf2d2b606 --- /dev/null +++ b/wagmi-project/site/cli/getting-started.md @@ -0,0 +1,167 @@ +# Getting Started + +## Overview + +Wagmi CLI is a command line interface for managing ABIs (from Etherscan/block explorers, Foundry/Hardhat projects, etc.), generating code (e.g. React Hooks), and much more. It makes working with Ethereum easier by automating manual work so you can build faster. You can learn more about the rationale behind the project in the [Why Wagmi CLI](/cli/why) section. + +## Manual Installation + +To manually add Wagmi CLI to your project, install the required packages. + +::: code-group +```bash [pnpm] +pnpm add -D @wagmi/cli +``` + +```bash [npm] +npm install --save-dev @wagmi/cli +``` + +```bash [yarn] +yarn add -D @wagmi/cli +``` + +```bash [bun] +bun add -D @wagmi/cli +``` +::: + +## Create Config File + +Run the `init` command to generate a configuration file: either `wagmi.config.ts` if TypeScript is detected, otherwise `wagmi.config.js`. You can also create the configuration file manually. See [Configuring CLI](/cli/config/configuring-cli) for more info. + +::: code-group +```bash [pnpm] +pnpm wagmi init +``` + +```bash [npm] +npx wagmi init +``` + +```bash [yarn] +yarn wagmi init +``` + +```bash [bun] +bun wagmi init +``` +::: + +The generated configuration file will look something like this: + +::: code-group +```ts [wagmi.config.ts] +import { defineConfig } from '@wagmi/cli' + +export default defineConfig({ + out: 'src/generated.ts', + contracts: [], + plugins: [], +}) +``` +::: + +## Add Contracts And Plugins + +Once the configuration file is set up, you can add contracts and plugins to it. These contracts and plugins are used to manage ABIs (fetch from block explorers, resolve from the file system, etc.), generate code (React hooks, etc.), and much more! + +For example, we can add the ERC-20 contract from Viem, and the [`etherscan`](/cli/api/plugins/etherscan) and [`react`](/cli/api/plugins/react) plugins. + +::: code-group +```ts{2,3,9-12,15-27,28} [wagmi.config.ts] +import { defineConfig } from '@wagmi/cli' +import { etherscan, react } from '@wagmi/cli/plugins' +import { erc20Abi } from 'viem' +import { mainnet, sepolia } from 'wagmi/chains' + +export default defineConfig({ + out: 'src/generated.ts', + contracts: [ + { + name: 'erc20', + abi: erc20Abi, + }, + ], + plugins: [ + etherscan({ + apiKey: process.env.ETHERSCAN_API_KEY!, + chainId: mainnet.id, + contracts: [ + { + name: 'EnsRegistry', + address: { + [mainnet.id]: '0x314159265dd8dbb310642f98f50c066173c1259b', + [sepolia.id]: '0x112234455c3a32fd11230c42e7bccd4a84e02010', + }, + }, + ], + }), + react(), + ], +}) +``` +::: + +## Run Code Generation + +Now that we added a few contracts and plugins to the configuration file, we can run the [`generate`](/cli/api/commands/generate) command to resolve ABIs and generate code to the `out` file. + +::: code-group +```bash [pnpm] +pnpm wagmi generate +``` + +```bash [npm] +npx wagmi generate +``` + +```bash [yarn] +yarn wagmi generate +``` + +```bash [bun] +bun wagmi generate +``` +::: + +In this example, the `generate` command will do the following: + +- Validate the `etherscan` and `react` plugins +- Fetch and cache the ENS Registry ABI from the Mainnet Etherscan API +- Pull in the `erc20Abi` using the name `'ERC20'` +- Generate React Hooks for both ABIs +- Save ABIs, ENS Registry deployment addresses, and React Hooks to the `out` file + +## Use Generated Code + +Once `out` is created, you can start using the generated code in your project. + +```ts +import { useReadErc20, useReadErc20BalanceOf } from './generated' + +// Use the generated ERC-20 read hook +const { data } = useReadErc20({ + address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + functionName: 'balanceOf', + args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e'], +}) + +// Use the generated ERC-20 "balanceOf" hook +const { data } = useReadErc20BalanceOf({ + address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e'], +}) +``` + +::: tip +Instead of committing the `out` file, you likely want to add `out` to your `.gitignore` and run `generate` during the build process or before you start your dev server in a `"predev"` script. +::: + +## Next Steps + +For more information on what to do next, check out the following topics. + +- [**Configuring CLI**](/cli/config/configuring-cli) Learn how to configure the CLI to work best for your project. +- [**Commands**](/cli/api/commands) Learn more about the CLI commands and how to use them. +- [**Plugins**](/cli/api/plugins) Browse the collection of plugins and set them up with your config. diff --git a/wagmi-project/site/cli/guides/migrate-from-v1-to-v2.md b/wagmi-project/site/cli/guides/migrate-from-v1-to-v2.md new file mode 100644 index 0000000000..2db0fef568 --- /dev/null +++ b/wagmi-project/site/cli/guides/migrate-from-v1-to-v2.md @@ -0,0 +1,51 @@ +--- +title: Migrate from v1 to v2 +titleTemplate: Wagmi CLI +description: Guide for migrating from Wagmi CLI v1 to v2. +--- + +# Migrate from v1 to v2 + +To get started, install the latest version of the Wagmi CLI. + +::: code-group +```bash-vue [pnpm] +pnpm add @wagmi/cli +``` + +```bash-vue [npm] +npm install @wagmi/cli +``` + +```bash-vue [yarn] +yarn add @wagmi/cli +``` + +```bash-vue [bun] +bun add @wagmi/cli +``` +::: + +::: info Not ready to migrate yet? +The Wagmi CLI v1 docs are still available at [1.x.wagmi.sh/cli](https://1.x.wagmi.sh/cli). +::: + +## Changed generated action and hook names + +Generated action and hook names now align with [Wagmi v2 naming conventions](/react/guides/migrate-from-v1-to-v2#renamed-hooks). If you want hooks to still follow Wagmi v1 naming conventions, set [`getActionName`](/cli/api/plugins/actions#getactionname) and [`getHookName`](/cli/api/plugins/react#gethookname) to `'legacy'`. + +```ts +import { defineConfig } from '@wagmi/cli' +import { actions, react } from '@wagmi/cli/plugins' + +export default defineConfig({ + plugins: [ + actions({ + getActionName: 'legacy', // [!code focus] + }), + react({ + getHookName: 'legacy', // [!code focus] + }), + ], +}) +``` diff --git a/wagmi-project/site/cli/installation.md b/wagmi-project/site/cli/installation.md new file mode 100644 index 0000000000..649565ca34 --- /dev/null +++ b/wagmi-project/site/cli/installation.md @@ -0,0 +1,60 @@ +# Installation + +Install Wagmi CLI via your package manager. + +## Package Manager + +Install the required package. + +::: code-group +```bash [pnpm] +pnpm add @wagmi/cli +``` + +```bash [npm] +npm install @wagmi/cli +``` + +```bash [yarn] +yarn add @wagmi/cli +``` + +```bash [bun] +bun add @wagmi/cli +``` +::: + +## Using Unreleased Commits + +If you can't wait for a new release to test the latest features, you can either install from the `canary` tag (tracks the [`main`](https://github.com/wevm/wagmi/tree/main) branch). + +::: code-group +```bash [pnpm] +pnpm add @wagmi/cli@canary +``` + +```bash [npm] +npm install @wagmi/cli@canary +``` + +```bash [yarn] +yarn add @wagmi/cli@canary +``` + +```bash [bun] +bun add @wagmi/cli@canary +``` +::: + +Or clone the [Wagmi repo](https://github.com/wevm/wagmi) to your local machine, build, and link it yourself. + +```bash +git clone https://github.com/wevm/wagmi.git +cd wagmi +pnpm install +pnpm build +cd packages/cli +pnpm link --global +``` + +Then go to the project where you are using the Wagmi CLI and run `pnpm link --global @wagmi/cli` (or the package manager that you used to link Wagmi CLI globally). \ No newline at end of file diff --git a/wagmi-project/site/cli/why.md b/wagmi-project/site/cli/why.md new file mode 100644 index 0000000000..a626c46006 --- /dev/null +++ b/wagmi-project/site/cli/why.md @@ -0,0 +1,92 @@ +# Why Wagmi CLI + +## The Problem + +The most common way to interact with smart contracts is through [Application Binary Interfaces](https://docs.soliditylang.org/en/latest/abi-spec.html). ABIs describe smart contracts' public functionality (e.g. functions, events, errors) as well as how to encode and decode related data (e.g. arguments and results). + +While ABIs are extremely powerful, there isn't a uniform way developers manage them in their apps. Developers do a bunch of different things, like: + +- Publish packages on npm containing ABIs +- Write custom scripts to fetch ABIs from external sources +- Compile contracts into application project +- Copy and paste ABIs from local projects or block explorers + +All these approaches take time that you could spend doing more important things, like interacting with your smart contracts! + +## The Solution + +The Wagmi CLI is an attempt to automate manual work so you can build faster. In short, the CLI manages ABIs and generates code. It takes ABIs as inputs and outputs ABIs and generated code. For example, the [Etherscan plugin](/cli/api/plugins/etherscan) allows you to fetch ABIs across multiple chains and deployments and immediately start importing them into your project. + +Code generation is another big advantage of the CLI. Using the [React plugin](/cli/api/plugins/react), you can generate [Wagmi Hooks](/react/api/hooks) for ABIs. When you combine this with the CLI's different ABI sources, like Etherscan, Foundry/Hardhat, and more, you reduce a lot of boilerplate code. + +::: code-group +```ts [Diff] +import { useReadContract, useWriteContract } from 'wagmi' // [!code --] +import { froggyFriendsAbi, froggyFriendsAddress } from './generated' // [!code --] +import { useReadFroggyFriends, useWriteFroggyFriends } from './generated' // [!code ++] + +function App() { + const { data } = useReadContract({ // [!code --] + const { data } = useReadFroggyFriends({ // [!code ++] + abi: froggyFriendsAbi, // [!code --] + address: froggyFriendsAddress, // [!code --] + functionName: 'tokenURI', + args: [123n], + }) + + const { write } = useWriteContract() // [!code --] + const { write } = useWriteFroggyFriends() // [!code ++] + const onClick = React.useCallback(() => { + write({ + abi: froggyFriendsAbi, // [!code --] + address: froggyFriendsAddress, // [!code --] + functionName: 'mint', + args: ['foo', 123n], + }) + }, [write]) +} +``` +```ts [Before] +import { useReadContract, useWriteContract } from 'wagmi' +import { froggyFriendsAbi, froggyFriendsAddress } from './generated' + +function App() { + const { data } = useReadContract({ + abi: froggyFriendsAbi, + address: froggyFriendsAddress, + functionName: 'tokenURI', + args: [123n], + }) + + const { write } = useWriteContract() + const onClick = React.useCallback(() => { + write({ + abi: froggyFriendsAbi, + address: froggyFriendsAddress, + functionName: 'mint', + args: ['foo', 123n], + }) + }, [write]) +} +``` +```ts [After] +import { useReadFroggyFriends, useWriteFroggyFriends } from './generated' + +function App() { + const { data } = useReadFroggyFriends({ + functionName: 'tokenURI', + args: [123n], + }) + + const { write } = useWriteFroggyFriends() + const onClick = React.useCallback(() => { + write({ + functionName: 'mint', + args: ['foo', 123n], + }) + }, [write]) +} +``` +::: + +Finally, the Wagmi CLI supports popular smart contract development tools, [Foundry](/cli/api/plugins/foundry) and [Hardhat](/cli/api/plugins/hardhat). You can run the CLI in [watch mode](/cli/api/commands/generate#w-watch), make changes to your contracts, and the CLI will automatically pick up ABI changes and run plugins over those changes. A major boon to working a monorepo and shortening the feedback loop across your stack. diff --git a/wagmi-project/site/components/Browsers.vue b/wagmi-project/site/components/Browsers.vue new file mode 100644 index 0000000000..4367018bc9 --- /dev/null +++ b/wagmi-project/site/components/Browsers.vue @@ -0,0 +1,9 @@ + + + diff --git a/wagmi-project/site/components/SearchChains.vue b/wagmi-project/site/components/SearchChains.vue new file mode 100644 index 0000000000..b649a6202e --- /dev/null +++ b/wagmi-project/site/components/SearchChains.vue @@ -0,0 +1,82 @@ + + + + + diff --git a/wagmi-project/site/core/api/actions.md b/wagmi-project/site/core/api/actions.md new file mode 100644 index 0000000000..664cd9a86a --- /dev/null +++ b/wagmi-project/site/core/api/actions.md @@ -0,0 +1,25 @@ + + +# Actions + +Actions for accounts, wallets, contracts, transactions, signing, ENS, and more. + +## Import + +```ts +import { getAccount } from '@wagmi/core' +``` + +## Available Actions + + diff --git a/wagmi-project/site/core/api/actions/call.md b/wagmi-project/site/core/api/actions/call.md new file mode 100644 index 0000000000..52f202a570 --- /dev/null +++ b/wagmi-project/site/core/api/actions/call.md @@ -0,0 +1,340 @@ + + +# call + +Action for executing a new message call immediately without submitting a transaction to the network. + +## Import + +```ts +import { call } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { call } from '@wagmi/core' +import { config } from './config' + +await call(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts twoslash +import { type CallParameters } from '@wagmi/core' +``` + +### account + +`Account | Address | undefined` + +The Account to call from. + +::: code-group +```ts [index.ts] +import { call } from '@wagmi/core' +import { config } from './config' + +await call(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', // [!code focus] + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### data + +`` `0x${string}` | undefined `` + +A contract hashed method call with encoded args. + +::: code-group +```ts [index.ts] +import { call } from '@wagmi/core' +import { config } from './config' + +await call(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### to + +`Address | undefined` + +The contract address or recipient. + +::: code-group +```ts [index.ts] +import { call } from '@wagmi/core' +import { config } from './config' + +await call(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### accessList + +`AccessList | undefined` + +The access list. + +::: code-group +```ts [index.ts] +import { call } from '@wagmi/core' +import { config } from './config' + +await call(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + accessList: [ // [!code focus:6] + { + address: '0x1', + storageKeys: ['0x1'], + }, + ], + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### gas + +`bigint | undefined` + +The gas provided for transaction execution. + +::: code-group +```ts [index.ts] +import { call } from '@wagmi/core' +import { config } from './config' + +await call(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + gas: 1_000_000n, // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### gasPrice + +`bigint | undefined` + +The price (in wei) to pay per gas. Only applies to [Legacy Transactions](https://viem.sh/docs/glossary/terms.html#legacy-transaction). + +::: code-group +```ts [index.ts] +import { call } from '@wagmi/core' +import { parseGwei } from 'viem' +import { config } from './config' + +await call(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + gasPrice: parseGwei('20'), // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### maxFeePerGas + +`bigint | undefined` + +Total fee per gas (in wei), inclusive of `maxPriorityFeePerGas`. Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```ts [index.ts] +import { call } from '@wagmi/core' +import { parseGwei } from 'viem' +import { config } from './config' + +await call(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + maxFeePerGas: parseGwei('20'), // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### maxPriorityFeePerGas + +`bigint | undefined` + +Max priority fee per gas (in wei). Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```ts [index.ts] +import { call } from '@wagmi/core' +import { parseGwei } from 'viem' +import { config } from './config' + +await call(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + maxFeePerGas: parseGwei('20'), + maxPriorityFeePerGas: parseGwei('2'), // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### nonce + +`number | undefined` + +Unique number identifying this transaction. + +::: code-group +```ts [index.ts] +import { call } from '@wagmi/core' +import { config } from './config' + +await call(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + nonce: 420, // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### value + +`bigint | undefined` + +Value (in wei) sent with this transaction. + +::: code-group +```ts [index.ts] +import { call } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +await call(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockNumber + +`number | undefined` + +The block number to perform the call against. + +::: code-group +```ts [index.ts] +import { call } from '@wagmi/core' +import { config } from './config' + +await call(config, { + blockNumber: 15121123n, // [!code focus] + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +The block tag to perform the call against. + +::: code-group +```ts [index.ts] +import { call } from '@wagmi/core' +import { config } from './config' + +await call(config, { + blockTag: 'safe', // [!code focus] + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +The block tag to perform the call against. + +::: code-group +```ts [index.ts] +import { call } from '@wagmi/core' +import { config } from './config' +import { mainnet } from '@wagmi/core/chains' + +await call(config, { + chainId: mainnet.id, // [!code focus] + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts twoslash +import { type CallReturnType } from '@wagmi/core' +``` + +`{ data: 0x${string} }` + +The call data. + +## Error + +```ts twoslash +import { type CallErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`call`](https://viem.sh/docs/actions/public/call.html) diff --git a/wagmi-project/site/core/api/actions/connect.md b/wagmi-project/site/core/api/actions/connect.md new file mode 100644 index 0000000000..30d04a85e3 --- /dev/null +++ b/wagmi-project/site/core/api/actions/connect.md @@ -0,0 +1,102 @@ + + +# connect + +Action for connecting accounts with [connectors](/core/api/connectors). + +## Import + +```ts +import { connect } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { connect } from '@wagmi/core' +import { injected } from '@wagmi/connectors' +import { config } from './config' + +const result = await connect(config, { connector: injected() }) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type ConnectParameters } from '@wagmi/core' +``` + +### chainId + +`number | undefined` + +Chain ID to connect to. + +Not all connectors support connecting directly to a `chainId` (e.g. they don't support programmatic chain switching). In those cases, the connector will connect to whatever chain the connector's provider is connected to. + +::: code-group +```ts [index.ts] +import { connect } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { injected } from '@wagmi/connectors' +import { config } from './config' + +const result = await connect(config, { + chainId: mainnet.id, // [!code focus] + connector: injected(), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### connector + +`CreateConnectorFn | Connector` + +[Connector](/core/api/connectors) to connect with. + +::: code-group +```ts [index.ts] +import { connect } from '@wagmi/core' +import { injected } from '@wagmi/connectors' // [!code focus] +import { config } from './config' + +const result = await connect(config, { + connector: injected(), // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type ConnectReturnType } from '@wagmi/core' +``` + +### accounts + +`readonly [Address, ...Address[]]` + +Connected accounts from connector. + +### chainId + +`number` + +Connected chain ID from connector. + +## Error + +```ts +import { type ConnectErrorType } from '@wagmi/core' +``` + + diff --git a/wagmi-project/site/core/api/actions/deployContract.md b/wagmi-project/site/core/api/actions/deployContract.md new file mode 100644 index 0000000000..3cdbfd130f --- /dev/null +++ b/wagmi-project/site/core/api/actions/deployContract.md @@ -0,0 +1,264 @@ + + +# deployContract + +Action for deploying a contract to the network, given bytecode, and constructor arguments. + +## Import + +```ts +import { deployContract } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { deployContract } from '@wagmi/core' +import { wagmiAbi } from './abi' +import { config } from './config' + +const result = await deployContract(config, { + abi: wagmiAbi, + bytecode: '0x608060405260405161083e38038061083e833981016040819052610...', +}) +``` +```ts [abi.ts] +export const wagmiAbi = [ + ... + { + inputs: [], + stateMutability: "nonpayable", + type: "constructor", + }, + ... +] as const +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Deploying with Constructor Args + +::: code-group +```ts [index.ts] +import { deployContract } from '@wagmi/core' +import { wagmiAbi } from './abi' +import { config } from './config' + +const result = await deployContract(config, { + abi: wagmiAbi, + args: [69420], + bytecode: '0x608060405260405161083e38038061083e833981016040819052610...', +}) +``` +```ts [abi.ts] +export const wagmiAbi = [ + ... + { + inputs: [{ name: "x", type: "uint32" }], + stateMutability: "nonpayable", + type: "constructor", + }, + ... +] as const; +``` +<<< @/snippets/core/config.ts[config.ts] +::: + + +## Parameters + +```ts +import { type DeployContractParameters } from '@wagmi/core' +``` + +### abi + +`Abi` + +The contract's ABI. + +::: code-group +```ts [index.ts] +import { deployContract } from '@wagmi/core' +import { wagmiAbi } from './abi' +import { config } from './config' + +const result = await deployContract(config, { + abi: wagmiAbi, // [!code focus] + args: [69420], + bytecode: '0x608060405260405161083e38038061083e833981016040819052610...', +}) +``` +```ts [abi.ts] +export const wagmiAbi = [ + ... + { + inputs: [{ name: "x", type: "uint32" }], + stateMutability: "nonpayable", + type: "constructor", + }, + ... +] as const; +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### account + +`Address | Account | undefined` + +Account to use when deploying a contract. Throws if account is not found on [`connector`](#connector). + +::: code-group +```ts [index.ts] +import { deployContract } from '@wagmi/core' +import { wagmiAbi } from './abi' +import { config } from './config' + +const result = await deployContract(config, { + abi: wagmiAbi, + account: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] + args: [69420], + bytecode: '0x608060405260405161083e38038061083e833981016040819052610...', +}) +``` +```ts [abi.ts] +export const wagmiAbi = [ + ... + { + inputs: [{ name: "x", type: "uint32" }], + stateMutability: "nonpayable", + type: "constructor", + }, + ... +] as const; +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### args + +`readonly unknown[] | undefined` + +- Arguments to pass when deploying the contract. +- Inferred from [`abi`](#abi). + +::: code-group +```ts [index.ts] +import { deployContract } from '@wagmi/core' +import { wagmiAbi } from './abi' +import { config } from './config' + +const result = await deployContract(config, { + abi: wagmiAbi, + args: [69420], // [!code focus] + bytecode: '0x608060405260405161083e38038061083e833981016040819052610...', +}) +``` +```ts [abi.ts] +export const wagmiAbi = [ + ... + { + inputs: [{ name: "x", type: "uint32" }], + stateMutability: "nonpayable", + type: "constructor", + }, + ... +] as const; +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### bytecode + +`Hex` + +The contract's bytecode. + +::: code-group +```ts [index.ts] +import { deployContract } from '@wagmi/core' +import { wagmiAbi } from './abi' +import { config } from './config' + +const result = await deployContract(config, { + abi: wagmiAbi, + args: [69420], + bytecode: '0x608060405260405161083e38038061083e833981016040819052610...', // [!code focus] +}) +``` +```ts [abi.ts] +export const wagmiAbi = [ + ... + { + inputs: [{ name: "x", type: "uint32" }], + stateMutability: "nonpayable", + type: "constructor", + }, + ... +] as const; +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +- Connector to use when deploying a contract. +- Defaults to current connector. + +::: code-group +```ts [index.ts] +import { getAccount, deployContract } from '@wagmi/core' +import { wagmiAbi } from './abi' +import { config } from './config' + +const { connector } = getAccount(config) +const result = await deployContract(config, { + abi: wagmiAbi, + args: [69420], + bytecode: '0x608060405260405161083e38038061083e833981016040819052610...', + connector, // [!code focus] +}) +``` +```ts [abi.ts] +export const wagmiAbi = [ + ... + { + inputs: [{ name: "x", type: "uint32" }], + stateMutability: "nonpayable", + type: "constructor", + }, + ... +] as const; +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type DeployContractReturnType } from '@wagmi/core' +``` + +[`Hash`](https://viem.sh/docs/glossary/types.html#hash) + +Transaction hash. + +## Error + +```ts +import { type DeployContractErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`deployContract`](https://viem.sh/docs/contract/deployContract) diff --git a/wagmi-project/site/core/api/actions/disconnect.md b/wagmi-project/site/core/api/actions/disconnect.md new file mode 100644 index 0000000000..6c77fb5c74 --- /dev/null +++ b/wagmi-project/site/core/api/actions/disconnect.md @@ -0,0 +1,60 @@ + + +# disconnect + +Action for disconnecting connections. + +## Import + +```ts +import { disconnect } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { disconnect } from '@wagmi/core' +import { config } from './config' + +await disconnect(config) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type DisconnectParameters } from '@wagmi/core' +``` + +### connector + +`Connector | undefined` + +[Connector](/core/api/connectors) to disconnect with. + +::: code-group +```ts [index.ts] +import { disconnect, getAccount } from '@wagmi/core' +import { config } from './config' + +const { connector } = getAccount(config) +const result = await disconnect(config, { + connector, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Error + +```ts +import { type DisconnectErrorType } from '@wagmi/core' +``` + + diff --git a/wagmi-project/site/core/api/actions/estimateFeesPerGas.md b/wagmi-project/site/core/api/actions/estimateFeesPerGas.md new file mode 100644 index 0000000000..ce804efeb9 --- /dev/null +++ b/wagmi-project/site/core/api/actions/estimateFeesPerGas.md @@ -0,0 +1,139 @@ + + +# estimateFeesPerGas + +Returns an estimate for the fees per gas (in wei) for a transaction to be likely included in the next block. + +## Import + +```ts +import { estimateFeesPerGas } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { estimateFeesPerGas } from '@wagmi/core' +import { config } from './config' + +const result = await estimateFeesPerGas(config) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type EstimateFeesPerGasParameters } from '@wagmi/core' +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { estimateFeesPerGas } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const result = await estimateFeesPerGas(config, { + chainId: mainnet.id, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### formatUnits + +`'ether' | 'gwei' | 'wei' | number | undefined` + +- Units to use when formatting result. +- Defaults to `'ether'`. + +::: code-group +```ts [index.ts] +import { estimateFeesPerGas } from '@wagmi/core' +import { config } from './config' + +const feesPerGas = estimateFeesPerGas(config, { + formatUnits: 'ether', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### type + +`'legacy' | 'eip1559'` + +- Fee value type. +- Defaults to `'eip1559'` + +::: code-group +```ts [index.ts] +import { estimateFeesPerGas } from '@wagmi/core' +import { config } from './config' + +const result = estimateFeesPerGas(config, { + type: 'legacy', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type EstimateFeesPerGasReturnType } from '@wagmi/core' +``` + +[`FeeValues`](https://viem.sh/docs/glossary/types.html#feevalues) + +An estimate (in wei) for the fees per gas. + +### formatted + +`{ gasPrice: string | undefined; maxFeePerGas: string | undefined; maxPriorityFeePerGas: string | undefined; }` + +Object of formatted values using [`formatUnits`](#formatunits). + +### gasPrice + +`bigint | undefined` + +- Gas price. +- When [`type`](#type) is `'eip1559'`, value is `undefined`. + +### maxFeePerGas + +`bigint | undefined` + +- Max fee per gas. +- When [`type`](#type) is `'legacy'`, value is `undefined`. + +### maxPriorityFeePerGas + +`bigint | undefined` + +- Max priority fee per gas. +- When [`type`](#type) is `'legacy'`, value is `undefined`. + +## Error + +```ts +import { type EstimateFeesPerGasErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`estimateFeesPerGas`](https://viem.sh/docs/actions/public/estimateFeesPerGas.html) diff --git a/wagmi-project/site/core/api/actions/estimateGas.md b/wagmi-project/site/core/api/actions/estimateGas.md new file mode 100644 index 0000000000..cbeb1ba40d --- /dev/null +++ b/wagmi-project/site/core/api/actions/estimateGas.md @@ -0,0 +1,340 @@ + + +# estimateGas + +Action for estimating the gas necessary to complete a transaction without submitting it to the network. + +## Import + +```ts +import { estimateGas } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { estimateGas } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +const result = await estimateGas(config, { + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type EstimateGasParameters } from '@wagmi/core' +``` + +### accessList + +`AccessList | undefined` + +The access list. + +::: code-group +```ts [index.ts] +import { estimateGas } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +const result = await estimateGas(config, { + accessList: [{ // [!code focus] + address: '0x1', // [!code focus] + storageKeys: ['0x1'], // [!code focus] + }], // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### account + +`Address | Account | undefined` + +Account to use when estimating gas. + +::: code-group +```ts [index.ts] +import { estimateGas } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +const result = await estimateGas(config, { + account: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +Chain ID to target when estimating gas. + +::: code-group +```ts [index.ts] +import { estimateGas } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { parseEther } from 'viem' +import { config } from './config' + +const result = await estimateGas(config, { + chainId: mainnet.id, // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +Connector to estimate with. If no [`account`](#account) is provided, will use default account from connector. + +::: code-group +```ts [index.ts] +import { getConnections, estimateGas } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +const connections = getConnections(config) +const result = await estimateGas(config, { + connector: connections[0]?.connector, // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### data + +`` `0x${string}` | undefined `` + +A contract hashed method call with encoded args. + +::: code-group +```ts [index.ts] +import { estimateGas } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +const result = await estimateGas(config, { + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### gas + +`bigint | undefined` + +Gas provided for transaction execution. + +::: code-group +```ts [index.ts] +import { estimateGas } from '@wagmi/core' +import { parseEther, parseGwei } from 'viem' +import { config } from './config' + +const result = await estimateGas(config, { + gas: parseGwei('20'), // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### gasPrice + +`bigint | undefined` + +The price in wei to pay per gas. Only applies to [Legacy Transactions](https://viem.sh/docs/glossary/terms.html#legacy-transaction). + +::: code-group +```ts [index.ts] +import { estimateGas } from '@wagmi/core' +import { parseEther, parseGwei } from 'viem' +import { config } from './config' + +const result = await estimateGas(config, { + gasPrice: parseGwei('20'), // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### maxFeePerGas + +`bigint | undefined` + +Total fee per gas in wei, inclusive of [`maxPriorityFeePerGas`](#maxPriorityFeePerGas). Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```ts [index.ts] +import { estimateGas } from '@wagmi/core' +import { parseEther, parseGwei } from 'viem' +import { config } from './config' + +const result = await estimateGas(config, { + maxFeePerGas: parseGwei('20'), // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### maxPriorityFeePerGas + +`bigint | undefined` + +Max priority fee per gas in wei. Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```ts [index.ts] +import { estimateGas } from '@wagmi/core' +import { parseEther, parseGwei } from 'viem' +import { config } from './config' + +const result = await estimateGas(config, { + maxFeePerGas: parseGwei('20'), + maxPriorityFeePerGas: parseGwei('2'), // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### nonce + +`number` + +Unique number identifying this transaction. + +::: code-group +```ts [index.ts] +import { estimateGas } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +const result = await estimateGas(config, { + nonce: 123, // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### to + +`Address | undefined` + +The transaction recipient or contract address. + +::: code-group +```ts [index.ts] +import { estimateGas } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +const result = await estimateGas(config, { + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### type + +`'legacy' | 'eip1559' | 'eip2930' | undefined` + +Optional transaction request type to narrow parameters. + +::: code-group +```ts [index.ts] +import { estimateGas } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +const result = await estimateGas(config, { + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + type: 'eip1559', // [!code focus] + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### value + +`bigint | undefined` + +Value in wei sent with this transaction. + +::: code-group +```ts [index.ts] +import { estimateGas } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +const result = await estimateGas(config, { + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type EstimateGasReturnType } from '@wagmi/core' +``` + +`bigint` + +The gas estimate in wei. + +## Error + +```ts +import { type EstimateGasErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`estimateGas`](https://viem.sh/docs/actions/public/estimateGas.html) diff --git a/wagmi-project/site/core/api/actions/estimateMaxPriorityFeePerGas.md b/wagmi-project/site/core/api/actions/estimateMaxPriorityFeePerGas.md new file mode 100644 index 0000000000..906e98b931 --- /dev/null +++ b/wagmi-project/site/core/api/actions/estimateMaxPriorityFeePerGas.md @@ -0,0 +1,74 @@ + + +# estimateMaxPriorityFeePerGas + +Returns an estimate for the max priority fee per gas (in wei) for a transaction to be likely included in the next block. + +## Import + +```ts +import { estimateMaxPriorityFeePerGas } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { estimateMaxPriorityFeePerGas } from '@wagmi/core' +import { config } from './config' + +const result = await estimateMaxPriorityFeePerGas(config) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type EstimateFeesPerGasParameters } from '@wagmi/core' +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { estimateMaxPriorityFeePerGas } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const result = await estimateMaxPriorityFeePerGas(config, { + chainId: mainnet.id, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type EstimateFeesPerGasReturnType } from '@wagmi/core' +``` + +`bigint` + +An estimate (in wei) for the max priority fee per gas. + +## Error + +```ts +import { type EstimateFeesPerGasErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`estimateMaxPriorityFeePerGas`](https://viem.sh/docs/actions/public/estimateMaxPriorityFeePerGas.html) diff --git a/wagmi-project/site/core/api/actions/getAccount.md b/wagmi-project/site/core/api/actions/getAccount.md new file mode 100644 index 0000000000..a8dde7602e --- /dev/null +++ b/wagmi-project/site/core/api/actions/getAccount.md @@ -0,0 +1,29 @@ +# getAccount + +Action for getting current account. + +## Import + +```ts +import { getAccount } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getAccount } from '@wagmi/core' +import { config } from './config' + +const account = getAccount(config) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetAccountReturnType } from '@wagmi/core' +``` + + diff --git a/wagmi-project/site/core/api/actions/getBalance.md b/wagmi-project/site/core/api/actions/getBalance.md new file mode 100644 index 0000000000..192d5a69ce --- /dev/null +++ b/wagmi-project/site/core/api/actions/getBalance.md @@ -0,0 +1,197 @@ + + +# getBalance + +Action for fetching native currency or token balance. + +## Import + +```ts +import { getBalance } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getBalance } from '@wagmi/core' +import { config } from './config' + +const balance = getBalance(config, { + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetBalanceParameters } from '@wagmi/core' +``` + +### address + +`Address` + +Address to get balance for. + +::: code-group +```ts [index.ts] +import { getBalance } from '@wagmi/core' +import { config } from './config' + +const balance = getBalance(config, { + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### blockNumber + +`bigint | undefined` + +Block number to get balance at. + +::: code-group +```ts [index.ts] +import { getBalance } from '@wagmi/core' +import { config } from './config' + +const balance = getBalance(config, { + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + blockNumber: 17829139n, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get balance at. + +::: code-group +```ts [index.ts] +import { getBalance } from '@wagmi/core' +import { config } from './config' + +const balance = getBalance(config, { + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + blockTag: 'latest', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { getBalance } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const balance = await getBalance(config, { + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + chainId: mainnet.id, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### token + +`Address | undefined` + +ERC-20 token address to get balance for. + +::: code-group +```ts [index.ts] +import { getBalance } from '@wagmi/core' +import { config } from './config' + +const balance = getBalance(config, { + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + token: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### unit + +`'ether' | 'gwei' | 'wei' | number | undefined` + +- Units to use when formatting result. +- Defaults to `'ether'`. + +::: code-group +```ts [index.ts] +import { getBalance } from '@wagmi/core' +import { config } from './config' + +const balance = getBalance(config, { + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + unit: 'ether', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetBalanceReturnType } from '@wagmi/core' +``` + +### decimals + +`number` + +Number of decimals for balance [`value`](#value). + +### formatted + +`string` + +Formatted value of balance using [`unit`](#unit). + +### symbol + +`string` + +Symbol of native currency or token. + +### value + +`bigint` + +Raw value of balance. + +## Error + +```ts +import { type GetBalanceErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`getBalance`](https://viem.sh/docs/actions/public/getBalance.html) for native currency balances +- [`multicall`](https://viem.sh/docs/actions/public/multicall.html) for token balances diff --git a/wagmi-project/site/core/api/actions/getBlock.md b/wagmi-project/site/core/api/actions/getBlock.md new file mode 100644 index 0000000000..980b026247 --- /dev/null +++ b/wagmi-project/site/core/api/actions/getBlock.md @@ -0,0 +1,146 @@ + + +# getBlock + +Action for fetching information about a block at a block number, hash or tag. + +## Import + +```ts +import { getBlock } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getBlock } from '@wagmi/core' +import { config } from './config' + +const blockNumber = await getBlock(config) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetBlockParameters } from '@wagmi/core' +``` + +### blockHash + +`` `0x${string}` `` + +Information at a given block hash. + +::: code-group +```ts [index.ts] +import { getBlock } from '@wagmi/core' +import { config } from './config' + +const blockNumber = await getBlock(config, { + blockHash: '0x89644bbd5c8d682a2e9611170e6c1f02573d866d286f006cbf517eec7254ec2d' // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockNumber + +`` bigint `` + +Information at a given block number. + +::: code-group +```ts [index.ts] +import { getBlock } from '@wagmi/core' +import { config } from './config' + +const blockNumber = await getBlock(config, { + blockNumber: 42069n // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockTag + +`` 'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' `` + +Information at a given block tag. Defaults to `'latest'`. + +::: code-group +```ts [index.ts] +import { getBlock } from '@wagmi/core' +import { config } from './config' + +const blockNumber = await getBlock(config, { + blockTag: 'pending' // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { getBlock } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const blockNumber = await getBlock(config, { + chainId: mainnet.id, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### includeTransactions + +`boolean` + +Whether or not to include transactions as objects. + +::: code-group +```ts [index.ts] +import { getBlock } from '@wagmi/core' +import { config } from './config' + +const blockNumber = await getBlock(config, { + includeTransactions: true // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetBlockReturnType } from '@wagmi/core' +``` + +[`Block`](https://viem.sh/docs/glossary/types.html#block) + +Information about the block. + +## Error + +```ts +import { type GetBlockErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`getBlock`](https://viem.sh/docs/actions/public/getBlock.html) diff --git a/wagmi-project/site/core/api/actions/getBlockNumber.md b/wagmi-project/site/core/api/actions/getBlockNumber.md new file mode 100644 index 0000000000..ce13cbb14e --- /dev/null +++ b/wagmi-project/site/core/api/actions/getBlockNumber.md @@ -0,0 +1,93 @@ + + +# getBlockNumber + +Action for fetching the number of the most recent block seen. + +## Import + +```ts +import { getBlockNumber } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getBlockNumber } from '@wagmi/core' +import { config } from './config' + +const blockNumber = await getBlockNumber(config) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetBlockNumberParameters } from '@wagmi/core' +``` + +### cacheTime + +`number | undefined` + +Time in milliseconds that cached block number will remain in memory. + +::: code-group +```ts [index.ts] +import { getBlockNumber } from '@wagmi/core' +import { config } from './config' + +const blockNumber = await getBlockNumber(config, { + cacheTime: 4_000, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { getBlockNumber } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const blockNumber = await getBlockNumber(config, { + chainId: mainnet.id, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetBlockNumberReturnType } from '@wagmi/core' +``` + +`bigint` + +Most recent block number seen. + +## Error + +```ts +import { type GetBlockNumberErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`getBlockNumber`](https://viem.sh/docs/actions/public/getBlockNumber.html) +- [`watchBlockNumber`](https://viem.sh/docs/actions/public/watchBlockNumber.html) diff --git a/wagmi-project/site/core/api/actions/getBlockTransactionCount.md b/wagmi-project/site/core/api/actions/getBlockTransactionCount.md new file mode 100644 index 0000000000..c351272209 --- /dev/null +++ b/wagmi-project/site/core/api/actions/getBlockTransactionCount.md @@ -0,0 +1,92 @@ + + +# getBlockTransactionCount + +Action for fetching the number of Transactions at a block number, hash or tag. + +## Import + +```ts +import { getBlockTransactionCount } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getBlockTransactionCount } from '@wagmi/core' +import { config } from './config' + +const blockTransactionCount = await getBlockTransactionCount(config) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetBlockTransactionCountParameters } from '@wagmi/core' +``` + +### cacheTime + +`number | undefined` + +Time in milliseconds that cached block transaction count will remain in memory. + +::: code-group +```ts [index.ts] +import { getBlockTransactionCount } from '@wagmi/core' +import { config } from './config' + +const blockTransactionCount = await getBlockTransactionCount(config, { + cacheTime: 4_000, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { getBlockTransactionCount } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const blockTransactionCount = await getBlockTransactionCount(config, { + chainId: mainnet.id, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetBlockTransactionCountReturnType } from '@wagmi/core' +``` + +`number` + +The number of Transactions at a block number + +## Error + +```ts +import { type GetBlockTransactionCountErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`getBlockTransactionCount`](https://viem.sh/docs/actions/public/getBlockTransactionCount.html) diff --git a/wagmi-project/site/core/api/actions/getBytecode.md b/wagmi-project/site/core/api/actions/getBytecode.md new file mode 100644 index 0000000000..3a926d6eea --- /dev/null +++ b/wagmi-project/site/core/api/actions/getBytecode.md @@ -0,0 +1,133 @@ + + +# getBytecode + +Action for retrieving the bytecode at an address. + +## Import + +```ts +import { getBytecode } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getBytecode } from '@wagmi/core' +import { config } from './config' + +await getBytecode(config, { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetBytecodeParameters } from '@wagmi/core' +``` + +### address + +`Address` + +The contract address. + +::: code-group +```ts [index.ts] +import { getBytecode } from '@wagmi/core' +import { config } from './config' + +await getBytecode(config, { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockNumber + +`bigint | undefined` + +The block number to check the bytecode at. + +::: code-group +```ts [index.ts] +import { getBytecode } from '@wagmi/core' +import { config } from './config' + +await getBytecode(config, { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + blockNumber: 16280770n, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +The block tag to check the bytecode at. + +::: code-group +```ts [index.ts] +import { getBytecode } from '@wagmi/core' +import { config } from './config' + +await getBytecode(config, { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + blockTag: 'safe', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +The chain ID to check the bytecode at. + +::: code-group +```ts [index.ts] +import { getBytecode } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +await getBytecode(config, { + chainId: mainnet.id, // [!code focus] + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetBytecodeReturnType } from '@wagmi/core' +``` + +`Hex` + +The contract's bytecode. + +## Error + +```ts +import { type GetBytecodeErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`getCode`](https://viem.sh/docs/contract/getCode) diff --git a/wagmi-project/site/core/api/actions/getCallsStatus.md b/wagmi-project/site/core/api/actions/getCallsStatus.md new file mode 100644 index 0000000000..dc03862b19 --- /dev/null +++ b/wagmi-project/site/core/api/actions/getCallsStatus.md @@ -0,0 +1,97 @@ + + +# getCallsStatus + +Action to fetch the status and receipts of a call batch that was sent via [`sendCalls`](/core/api/actions/sendCalls). + +[Read more.](https://github.com/ethereum/EIPs/blob/1663ea2e7a683285f977eda51c32cec86553f585/EIPS/eip-5792.md#wallet_getcallsstatus) + +## Import + +```ts +import { getCallsStatus } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getCallsStatus } from '@wagmi/core' +import { config } from './config' + +const status = await getCallsStatus(config, { + id: '0x1234567890abcdef', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetCallsStatusParameters } from '@wagmi/core' +``` + +### connector + +`Connector | undefined` + +Connector to get call statuses with. + +::: code-group +```ts [index.ts] +import { getConnections, getCallsStatus } from '@wagmi/core' +import { config } from './config' + +const connections = getConnections(config) +const status = await getCallsStatus(config, { + connector: connections[0]?.connector, // [!code focus] + id: '0x1234567890abcdef', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### id + +`string` + +Identifier of the call batch. + +::: code-group +```ts [index.ts] +import { getCallsStatus } from '@wagmi/core' +import { config } from './config' + +const status = await getCallsStatus(config, { + id: '0x1234567890abcdef', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetCallsStatusReturnType } from '@wagmi/core' +``` + +`{ status: 'PENDING' | 'CONFIRMED', receipts: TransactionReceipt[] }` + +The status and receipts of the call batch. + +## Error + +```ts +import { type GetCallsStatusErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`getCallsStatus`](https://viem.sh/experimental/eip5792/getCallsStatus) diff --git a/wagmi-project/site/core/api/actions/getCapabilities.md b/wagmi-project/site/core/api/actions/getCapabilities.md new file mode 100644 index 0000000000..36bad2bdda --- /dev/null +++ b/wagmi-project/site/core/api/actions/getCapabilities.md @@ -0,0 +1,96 @@ + + +# getCapabilities + +Action to extract capabilities (grouped by chain ID) that a connected wallet supports (e.g. paymasters, session keys, etc). + +[Read more.](https://github.com/ethereum/EIPs/blob/815028dc634463e1716fc5ce44c019a6040f0bef/EIPS/eip-5792.md#wallet_getcapabilities) + + + +## Import + +```ts +import { getCapabilities } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getCapabilities } from '@wagmi/core' +import { config } from './config' + +const capabilities = await getCapabilities(config) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetCapabilitiesParameters } from '@wagmi/core' +``` + +### account + +`Account | Address | undefined` + +Fetch capabilities for the provided account. + +::: code-group +```ts [index.ts] +import { getCapabilities } from '@wagmi/core' +import { config } from './config' + +const capabilities = await getCapabilities(config, { + account: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +Connector to get capabilities from. + +::: code-group +```ts [index.ts] +import { getConnections, getCapabilities } from '@wagmi/core' +import { config } from './config' + +const connections = getConnections(config) +const capabilities = await getCapabilities(config, { + connector: connections[0]?.connector, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetCapabilitiesReturnType } from '@wagmi/core' +``` + +`bigint` + +Most recent block number seen. + +## Error + +```ts +import { type GetCapabilitiesErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`getCapabilities`](https://viem.sh/experimental/eip5792/getCapabilities) diff --git a/wagmi-project/site/core/api/actions/getChainId.md b/wagmi-project/site/core/api/actions/getChainId.md new file mode 100644 index 0000000000..9d03f8468e --- /dev/null +++ b/wagmi-project/site/core/api/actions/getChainId.md @@ -0,0 +1,38 @@ +# getChainId + +Action for getting current chain ID. + + +## Import + +```ts +import { getChainId } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getChainId } from '@wagmi/core' +import { config } from './config' + +const chainId = getChainId(config) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetChainIdReturnType } from '@wagmi/core' +``` + +`number` + +Current chain ID from [`config.state.chainId`](/core/api/createConfig#chainid). + +::: info +Only returns chain IDs for chains configured via `createConfig`'s [`chains`](/core/api/createConfig#chains) parameter. + +If the active [connection](/core/api/createConfig#connection) [`chainId`](/core/api/createConfig#chainid-1) is not from a chain included in your Wagmi `Config`, `getChainId` will return the last configured chain ID. +::: diff --git a/wagmi-project/site/core/api/actions/getChains.md b/wagmi-project/site/core/api/actions/getChains.md new file mode 100644 index 0000000000..c70334e027 --- /dev/null +++ b/wagmi-project/site/core/api/actions/getChains.md @@ -0,0 +1,31 @@ +# getChains + +Action for getting configured chains. + +## Import + +```ts +import { getChains } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getChains } from '@wagmi/core' +import { config } from './config' + +const chains = getChains(config) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetChainsReturnType } from '@wagmi/core' +``` + +`readonly [Chain, ...Chain[]]` + +Chains from [`config.chains`](/core/api/createConfig#chains). diff --git a/wagmi-project/site/core/api/actions/getClient.md b/wagmi-project/site/core/api/actions/getClient.md new file mode 100644 index 0000000000..9f29f73236 --- /dev/null +++ b/wagmi-project/site/core/api/actions/getClient.md @@ -0,0 +1,56 @@ +# getClient + +Action for getting Viem [`Client`](https://viem.sh/docs/clients/custom.html) instance. + +## Import + +```ts +import { getClient } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getClient } from '@wagmi/core' +import { config } from './config' + +const client = getClient(config) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetClientParameters } from '@wagmi/core' +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when getting Viem Client. + +::: code-group +```ts [index.ts] +import { getClient } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const client = await getClient(config, { + chainId: mainnet.id, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetClientReturnType } from '@wagmi/core' +``` + +`Client` + +Viem [`Client`](https://viem.sh/docs/clients/custom.html) instance. diff --git a/wagmi-project/site/core/api/actions/getConnections.md b/wagmi-project/site/core/api/actions/getConnections.md new file mode 100644 index 0000000000..513d0d017d --- /dev/null +++ b/wagmi-project/site/core/api/actions/getConnections.md @@ -0,0 +1,31 @@ +# getConnections + +Action for getting active connections. + +## Import + +```ts +import { getConnections } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getConnections } from '@wagmi/core' +import { config } from './config' + +const connections = getConnections(config) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetConnectionsReturnType } from '@wagmi/core' +``` + +[`Connection[]`](/core/api/createConfig#connection) + +Active connections. diff --git a/wagmi-project/site/core/api/actions/getConnectorClient.md b/wagmi-project/site/core/api/actions/getConnectorClient.md new file mode 100644 index 0000000000..46d2795c7a --- /dev/null +++ b/wagmi-project/site/core/api/actions/getConnectorClient.md @@ -0,0 +1,108 @@ + + +# getConnectorClient + +Action for getting a Viem [`Client`](https://viem.sh/docs/clients/custom.html) object for the current or provided connector. + +## Import + +```ts +import { getConnectorClient } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getConnectorClient } from '@wagmi/core' +import { config } from './config' + +const client = await getConnectorClient(config) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetConnectorClientParameters } from '@wagmi/core' +``` + +### account + +`Address | Account | undefined` + +Account to use with client. Throws if account is not found on [`connector`](#connector). + +::: code-group +```ts [index.ts] +import { getConnectorClient } from '@wagmi/core' +import { config } from './config' + +const client = await getConnectorClient(config, { + account: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use with client. + +::: code-group +```ts [index.ts] +import { getConnectorClient } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const client = await getConnectorClient(config, { + chainId: mainnet.id, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +- Connector to get client for. +- Defaults to current connector. + +::: code-group +```ts [index.ts] +import { getConnections, getConnectorClient } from '@wagmi/core' +import { config } from './config' + +const connections = getConnections(config) +const client = await getConnectorClient(config, { + connector: connections[0]?.connector, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetChainIdReturnType } from '@wagmi/core' +``` + +`Client` + +Viem [`Client`](https://viem.sh/docs/clients/custom.html) object for the current or provided connector. + +## Error + +```ts +import { type GetConnectorClientErrorType } from '@wagmi/core' +``` + + diff --git a/wagmi-project/site/core/api/actions/getConnectors.md b/wagmi-project/site/core/api/actions/getConnectors.md new file mode 100644 index 0000000000..ddbb049be9 --- /dev/null +++ b/wagmi-project/site/core/api/actions/getConnectors.md @@ -0,0 +1,31 @@ +# getConnectors + +Action for getting configured connectors. + +## Import + +```ts +import { getConnectors } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getConnectors } from '@wagmi/core' +import { config } from './config' + +const connectors = getConnectors(config) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetConnectorsReturnType } from '@wagmi/core' +``` + +`readonly Connector[]` + +Connectors from [`config.connectors`](/core/api/createConfig#connectors-1). diff --git a/wagmi-project/site/core/api/actions/getEnsAddress.md b/wagmi-project/site/core/api/actions/getEnsAddress.md new file mode 100644 index 0000000000..dc44dbb732 --- /dev/null +++ b/wagmi-project/site/core/api/actions/getEnsAddress.md @@ -0,0 +1,187 @@ + + +# getEnsAddress + +Action for fetching ENS address for name. + +## Import + +```ts +import { getEnsAddress } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getEnsAddress } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensAddress = getEnsAddress(config, { + name: normalize('wevm.eth'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +::: warning +Since ENS names prohibit certain forbidden characters (e.g. underscore) and have other validation rules, you likely want to [normalize ENS names](https://docs.ens.domains/contract-api-reference/name-processing#normalising-names) with [UTS-46 normalization](https://unicode.org/reports/tr46) before passing them to `getEnsAddress`. You can use Viem's built-in [`normalize`](https://viem.sh/docs/ens/utilities/normalize) function for this. +::: + +## Parameters + +```ts +import { type GetEnsAddressParameters } from '@wagmi/core' +``` + +--- + +### blockNumber + +`bigint | undefined` + +Block number to get ENS address at. + +::: code-group +```ts [index.ts] +import { getEnsAddress } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensAddress = getEnsAddress(config, { + blockNumber: 17829139n, // [!code focus] + name: normalize('wevm.eth'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get ENS address at. + +::: code-group +```ts [index.ts] +import { getEnsAddress } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensAddress = getEnsAddress(config, { + blockTag: 'latest', // [!code focus] + name: normalize('wevm.eth'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { getEnsAddress } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensAddress = await getEnsAddress(config, { + chainId: mainnet.id, // [!code focus] + name: normalize('wevm.eth'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### coinType + +`number | undefined` + +The [ENSIP-9](https://docs.ens.domains/ens-improvement-proposals/ensip-9-multichain-address-resolution) coin type to fetch the address for. + +::: code-group +```ts [index.ts] +import { getEnsAddress } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensAddress = await getEnsAddress(config, { + coinType: 60, // [!code focus] + name: normalize('wevm.eth'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### name + +`string` + +Name to get the address for. + +::: code-group +```ts [index.ts] +import { getEnsAddress } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensAddress = await getEnsAddress(config, { + name: normalize('wevm.eth'), // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### universalResolverAddress + +`Address | undefined` + +- Address of ENS Universal Resolver Contract. +- Defaults to current chain's Universal Resolver Contract address. + +::: code-group +```ts [index.ts] +import { getEnsAddress } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensAddress = await getEnsAddress(config, { + name: normalize('wevm.eth'), + universalResolverAddress: '0x74E20Bd2A1fE0cdbe45b9A1d89cb7e0a45b36376', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetEnsAddressReturnType } from '@wagmi/core' +``` + +`string` + +ENS address. + +## Error + +```ts +import { type GetEnsAddressErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`getEnsAddress`](https://viem.sh/docs/ens/actions/getEnsAddress.html) diff --git a/wagmi-project/site/core/api/actions/getEnsAvatar.md b/wagmi-project/site/core/api/actions/getEnsAvatar.md new file mode 100644 index 0000000000..b7da4aa0f0 --- /dev/null +++ b/wagmi-project/site/core/api/actions/getEnsAvatar.md @@ -0,0 +1,210 @@ + + +# getEnsAvatar + +Action for fetching ENS address for avatar. + +## Import + +```ts +import { getEnsAvatar } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getEnsAvatar } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensAvatar = await getEnsAvatar(config, { + name: normalize('wevm.eth'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +::: warning +Since ENS names prohibit certain forbidden characters (e.g. underscore) and have other validation rules, you likely want to [normalize ENS names](https://docs.ens.domains/contract-api-reference/name-processing#normalising-names) with [UTS-46 normalization](https://unicode.org/reports/tr46) before passing them to `getEnsAvatar`. You can use Viem's built-in [`normalize`](https://viem.sh/docs/ens/utilities/normalize) function for this. +::: + +## Parameters + +```ts +import { type GetEnsAvatarParameters } from '@wagmi/core' +``` + +--- + +### assetGatewayUrls + +`{ ipfs?: string | undefined; arweave?: string | undefined } | undefined` + +Gateway urls to resolve IPFS and/or Arweave assets. + +::: code-group +```ts [index.ts] +import { getEnsAvatar } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensAvatar = await getEnsAvatar(config, { + assetGatewayUrls: { // [!code focus] + ipfs: 'https://cloudflare-ipfs.com', // [!code focus] + }, // [!code focus] + name: normalize('wevm.eth'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + + +### blockNumber + +`bigint | undefined` + +Block number to get avatar at. + +::: code-group +```ts [index.ts] +import { getEnsAvatar } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensAvatar = await getEnsAvatar(config, { + blockNumber: 17829139n, // [!code focus] + name: normalize('wevm.eth'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get avatar at. + +::: code-group +```ts [index.ts] +import { getEnsAvatar } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensAvatar = await getEnsAvatar(config, { + blockTag: 'latest', // [!code focus] + name: normalize('wevm.eth'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { getEnsAvatar } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensAvatar = await getEnsAvatar(config, { + chainId: mainnet.id, // [!code focus] + name: normalize('wevm.eth'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### gatewayUrls + +`string[] | undefined` + +A set of Universal Resolver gateways, used for resolving CCIP-Read requests made through the ENS Universal Resolver Contract. + +::: code-group +```ts [index.ts] +import { getEnsAvatar } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensAvatar = await getEnsAvatar(config, { + gatewayUrls: ['https://cloudflare-ipfs.com'] { // [!code focus] + name: normalize('wevm.eth'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### name + +`string` + +Name to get the avatar for. + +::: code-group +```ts [index.ts] +import { getEnsAvatar } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensAvatar = await getEnsAvatar(config, { + name: normalize('wevm.eth'), // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### universalResolverAddress + +`Address | undefined` + +- Address of ENS Universal Resolver Contract. +- Defaults to current chain's Universal Resolver Contract address. + +::: code-group +```ts [index.ts] +import { getEnsAvatar } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensAvatar = await getEnsAvatar(config, { + name: normalize('wevm.eth'), + universalResolverAddress: '0x74E20Bd2A1fE0cdbe45b9A1d89cb7e0a45b36376', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetEnsAvatarReturnType } from '@wagmi/core' +``` + +`string | null` + +The avatar URI for ENS name. + +## Error + +```ts +import { type getEnsAvatarError } from '@wagmi/core' +``` + + + +## Viem + +- [`getEnsAvatar`](https://viem.sh/docs/ens/actions/getEnsAvatar.html) diff --git a/wagmi-project/site/core/api/actions/getEnsName.md b/wagmi-project/site/core/api/actions/getEnsName.md new file mode 100644 index 0000000000..f663923f94 --- /dev/null +++ b/wagmi-project/site/core/api/actions/getEnsName.md @@ -0,0 +1,157 @@ + + +# getEnsName + +Action for fetching primary ENS name for address. + +## Import + +```ts +import { getEnsName } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getEnsName } from '@wagmi/core' +import { config } from './config' + +const ensName = getEnsName(config, { + address: '0xd2135CfB216b74109775236E36d4b433F1DF507B', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetEnsNameParameters } from '@wagmi/core' +``` + +### address + +`Address` + +Address to get the name for. + +::: code-group +```ts [index.ts] +import { getEnsName } from '@wagmi/core' +import { config } from './config' + +const ensName = await getEnsName(config, { + address: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### blockNumber + +`bigint | undefined` + +Block number to get name at. + +::: code-group +```ts [index.ts] +import { getEnsName } from '@wagmi/core' +import { config } from './config' + +const ensName = getEnsName(config, { + address: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + blockNumber: 17829139n, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get name at. + +::: code-group +```ts [index.ts] +import { getEnsName } from '@wagmi/core' +import { config } from './config' + +const ensName = getEnsName(config, { + address: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + blockTag: 'latest', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { getEnsName } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const ensName = await getEnsName(config, { + address: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + chainId: mainnet.id, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### universalResolverAddress + +`Address | undefined` + +- Address of ENS Universal Resolver Contract. +- Defaults to current chain's Universal Resolver Contract address. + +::: code-group +```ts [index.ts] +import { getEnsName } from '@wagmi/core' +import { config } from './config' + +const ensName = await getEnsName(config, { + address: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + universalResolverName: '0x74E20Bd2A1fE0cdbe45b9A1d89cb7e0a45b36376', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetEnsNameReturnType } from '@wagmi/core' +``` + +`string | null` + +The primary ENS name for the address. Returns `null` if address does not have primary name assigned. + +## Error + +```ts +import { type GetEnsNameErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`getEnsName`](https://viem.sh/docs/ens/actions/getEnsName.html) diff --git a/wagmi-project/site/core/api/actions/getEnsResolver.md b/wagmi-project/site/core/api/actions/getEnsResolver.md new file mode 100644 index 0000000000..c73301e071 --- /dev/null +++ b/wagmi-project/site/core/api/actions/getEnsResolver.md @@ -0,0 +1,167 @@ + + +# getEnsResolver + +Action for fetching ENS resolver for name. + +## Import + +```ts +import { getEnsResolver } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getEnsResolver } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensResolver = getEnsResolver(config, { + name: normalize('wevm.eth'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +::: warning +Since ENS names prohibit certain forbidden characters (e.g. underscore) and have other validation rules, you likely want to [normalize ENS names](https://docs.ens.domains/contract-api-reference/name-processing#normalising-names) with [UTS-46 normalization](https://unicode.org/reports/tr46) before passing them to `getEnsResolver`. You can use Viem's built-in [`normalize`](https://viem.sh/docs/ens/utilities/normalize) function for this. +::: + +## Parameters + +```ts +import { type GetEnsResolverParameters } from '@wagmi/core' +``` + +--- + +### blockNumber + +`bigint | undefined` + +Block number to get resolver at. + +::: code-group +```ts [index.ts] +import { getEnsResolver } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensResolver = getEnsResolver(config, { + blockNumber: 17829139n, // [!code focus] + name: normalize('wevm.eth'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get resolver at. + +::: code-group +```ts [index.ts] +import { getEnsResolver } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensResolver = getEnsResolver(config, { + blockTag: 'latest', // [!code focus] + name: normalize('wevm.eth'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { getEnsResolver } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensResolver = await getEnsResolver(config, { + chainId: mainnet.id, // [!code focus] + name: normalize('wevm.eth'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### name + +`string` + +Name to get the resolver for. + +::: code-group +```ts [index.ts] +import { getEnsResolver } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensResolver = await getEnsResolver(config, { + name: normalize('wevm.eth'), // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### universalResolverAddress + +`Address | undefined` + +- Address of ENS Universal Resolver Contract. +- Defaults to current chain's Universal Resolver Contract address. + +::: code-group +```ts [index.ts] +import { getEnsResolver } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensResolver = await getEnsResolver(config, { + name: normalize('wevm.eth'), + universalResolverAddress: '0x74E20Bd2A1fE0cdbe45b9A1d89cb7e0a45b36376', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetEnsResolverReturnType } from '@wagmi/core' +``` + +`Address` + +The address of the resolver. + +## Error + +```ts +import { type getEnsResolverError } from '@wagmi/core' +``` + + + +## Viem + +- [`getEnsResolver`](https://viem.sh/docs/ens/actions/getEnsResolver.html) diff --git a/wagmi-project/site/core/api/actions/getEnsText.md b/wagmi-project/site/core/api/actions/getEnsText.md new file mode 100644 index 0000000000..a5ffb8ed5a --- /dev/null +++ b/wagmi-project/site/core/api/actions/getEnsText.md @@ -0,0 +1,195 @@ + + +# getEnsText + +Action for fetching a text record for a specified ENS name and key. + +## Import + +```ts +import { getEnsText } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getEnsText } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensText = getEnsText(config, { + name: normalize('wevm.eth'), + key: 'com.twitter', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +::: warning +Since ENS names prohibit certain forbidden characters (e.g. underscore) and have other validation rules, you likely want to [normalize ENS names](https://docs.ens.domains/contract-api-reference/name-processing#normalising-names) with [UTS-46 normalization](https://unicode.org/reports/tr46) before passing them to `getEnsText`. You can use Viem's built-in [`normalize`](https://viem.sh/docs/ens/utilities/normalize) function for this. +::: + +## Parameters + +```ts +import { type GetEnsTextParameters } from '@wagmi/core' +``` + +--- + +### blockNumber + +`bigint | undefined` + +Block number to get the text at. + +::: code-group +```ts [index.ts] +import { getEnsText } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensText = getEnsText(config, { + blockNumber: 17829139n, // [!code focus] + name: normalize('wevm.eth'), + key: 'com.twitter', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get the text at. + +::: code-group +```ts [index.ts] +import { getEnsText } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensText = getEnsText(config, { + blockTag: 'latest', // [!code focus] + name: normalize('wevm.eth'), + key: 'com.twitter', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { getEnsText } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensText = await getEnsText(config, { + chainId: mainnet.id, // [!code focus] + name: normalize('wevm.eth'), + key: 'com.twitter', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### key + +`string` + +ENS key to get Text for. + +::: code-group +```ts [index.ts] +import { getEnsText } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensText = await getEnsText(config, { + name: normalize('wevm.eth'), + key: 'com.twitter', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### name + +`string` + +Name to get the text for. + +::: code-group +```ts [index.ts] +import { getEnsText } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensText = await getEnsText(config, { + name: normalize('wevm.eth'), // [!code focus] + key: 'com.twitter', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### universalResolverAddress + +`Address | undefined` + +- Address of ENS Universal Resolver Contract. +- Defaults to current chain's Universal Resolver Contract address. + +::: code-group +```ts [index.ts] +import { getEnsText } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +const ensText = await getEnsText(config, { + name: normalize('wevm.eth'), + key: 'com.twitter', + universalResolverAddress: '0x74E20Bd2A1fE0cdbe45b9A1d89cb7e0a45b36376', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetEnsTextReturnType } from '@wagmi/core' +``` + +`string | null` + +The text record for ENS name. + +Returns `null` if name does not have text assigned. + +## Error + +```ts +import { type getEnsTextError } from '@wagmi/core' +``` + + + +## Viem + +- [`getEnsText`](https://viem.sh/docs/ens/actions/getEnsText.html) diff --git a/wagmi-project/site/core/api/actions/getFeeHistory.md b/wagmi-project/site/core/api/actions/getFeeHistory.md new file mode 100644 index 0000000000..3787d8f66b --- /dev/null +++ b/wagmi-project/site/core/api/actions/getFeeHistory.md @@ -0,0 +1,157 @@ + + +# getFeeHistory + +Action for fetching a collection of historical gas information. + +## Import + +```ts +import { getFeeHistory } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getFeeHistory } from '@wagmi/core' +import { config } from './config' + +const feeHistory = await getFeeHistory(config, { + blockCount: 4, + rewardPercentiles: [25, 75] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetFeeHistoryParameters } from '@wagmi/core' +``` + +### blockCount + +`number` + +Number of blocks in the requested range. Between 1 and 1024 blocks can be requested in a single query. Less than requested may be returned if not all blocks are available. + +::: code-group +```ts [index.ts] +import { getFeeHistory } from '@wagmi/core' +import { config } from './config' + +const feeHistory = await getFeeHistory(config, { + blockCount: 4, // [!code focus] + rewardPercentiles: [25, 75] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### rewardPercentiles + +`number[]` + +A monotonically increasing list of percentile values to sample from each block's effective priority fees per gas in ascending order, weighted by gas used. + +::: code-group +```ts [index.ts] +import { getFeeHistory } from '@wagmi/core' +import { config } from './config' + +const feeHistory = await getFeeHistory(config, { + blockCount: 4, + rewardPercentiles: [25, 75] // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockNumber + +`bigint | undefined` + +Highest number block of the requested range. + +::: code-group +```ts [index.ts] +import { getFeeHistory } from '@wagmi/core' +import { config } from './config' + +const feeHistory = await getFeeHistory(config, { + blockCount: 4, + blockNumber: 1551231n, // [!code focus] + rewardPercentiles: [25, 75], +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag of the highest number block of the requested range. + +::: code-group +```ts [index.ts] +import { getFeeHistory } from '@wagmi/core' +import { config } from './config' + +const feeHistory = await getFeeHistory(config, { + blockCount: 4, + blockTag: 'safe', // [!code focus] + rewardPercentiles: [25, 75], +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { getFeeHistory } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const feeHistory = await getFeeHistory(config, { + blockCount: 4, + chainId: mainnet.id, // [!code focus] + rewardPercentiles: [25, 75], +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetFeeHistoryReturnType } from '@wagmi/core' +``` + +[`FeeHistory`](https://viem.sh/docs/glossary/types.html#feehistory) + +The fee history. + +## Error + +```ts +import { type GetFeeHistoryErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`getFeeHistory`](https://viem.sh/docs/actions/public/getFeeHistory.html) diff --git a/wagmi-project/site/core/api/actions/getGasPrice.md b/wagmi-project/site/core/api/actions/getGasPrice.md new file mode 100644 index 0000000000..106829fcfd --- /dev/null +++ b/wagmi-project/site/core/api/actions/getGasPrice.md @@ -0,0 +1,74 @@ + + +# getGasPrice + +Action for fetching the current price of gas (in wei). + +## Import + +```ts +import { getGasPrice } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getGasPrice } from '@wagmi/core' +import { config } from './config' + +const gasPrice = await getGasPrice(config) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetGasPriceParameters } from '@wagmi/core' +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { getGasPrice } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const gasPrice = await getGasPrice(config, { + chainId: mainnet.id, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetGasPriceReturnType } from '@wagmi/core' +``` + +`bigint` + +Current price of gas (in wei). + +## Error + +```ts +import { type GetGasPriceErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`getGasPrice`](https://viem.sh/docs/actions/public/getGasPrice.html) diff --git a/wagmi-project/site/core/api/actions/getProof.md b/wagmi-project/site/core/api/actions/getProof.md new file mode 100644 index 0000000000..60cd493260 --- /dev/null +++ b/wagmi-project/site/core/api/actions/getProof.md @@ -0,0 +1,169 @@ + + +# getProof + +Action for return the account and storage values of the specified account including the Merkle-proof. + +## Import + +```ts +import { getProof } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getProof } from '@wagmi/core' +import { config } from './config' + +await getProof(config, { + address: '0x4200000000000000000000000000000000000016', + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetProofParameters } from '@wagmi/core' +``` + +### address + +`Address` + +The account address to get the proof for. + +::: code-group +```ts [index.ts] +import { getProof } from '@wagmi/core' +import { config } from './config' + +await getProof(config, { + address: '0x4200000000000000000000000000000000000016', // [!code focus] + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### storageKeys + +`` `0x${string}`[] `` + +Array of storage-keys that should be proofed and included. + +::: code-group +```ts [index.ts] +import { getProof } from '@wagmi/core' +import { config } from './config' + +await getProof(config, { + address: '0x4200000000000000000000000000000000000016', + storageKeys: [ // [!code focus:3] + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockNumber + +`bigint | undefined` + +Proof at a given block number. + +::: code-group +```ts [index.ts] +import { getProof } from '@wagmi/core' +import { config } from './config' + +await getProof(config, { + address: '0x4200000000000000000000000000000000000016', + blockNumber: 42069n, // [!code focus] + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Proof at a given block tag. + +::: code-group +```ts [index.ts] +import { getProof } from '@wagmi/core' +import { config } from './config' + +await getProof(config, { + address: '0x4200000000000000000000000000000000000016', + blockTag: 'latest', // [!code focus] + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +The ID of chain to get the proof for. + +::: code-group +```ts [index.ts] +import { getProof } from '@wagmi/core' +import { config } from './config' +import { optimism } from '@wagmi/core/chains' + +await getProof(config, { + chainId: optimism.id, // [!code focus] + address: '0x4200000000000000000000000000000000000016', + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetProofReturnType } from '@wagmi/core' +``` + +`Proof` + +Proof data. + +## Error + +```ts +import { type GetProofErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`getProof`](https://viem.sh/docs/actions/public/getProof.html) diff --git a/wagmi-project/site/core/api/actions/getPublicClient.md b/wagmi-project/site/core/api/actions/getPublicClient.md new file mode 100644 index 0000000000..437104aa78 --- /dev/null +++ b/wagmi-project/site/core/api/actions/getPublicClient.md @@ -0,0 +1,60 @@ +# getPublicClient + +Action for getting Viem [`PublicClient`](https://viem.sh/docs/clients/public.html) instance. + +## Import + +```ts +import { getPublicClient } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getPublicClient } from '@wagmi/core' +import { config } from './config' + +const client = getPublicClient(config) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +::: warning +If you want to optimize bundle size, you should use [`getClient`](/core/api/actions/getClient) along with Viem's [tree-shakable actions](https://viem.sh/docs/clients/custom.html#tree-shaking) instead. Since Public Client has all public actions attached directly to it. +::: + +## Parameters + +```ts +import { type GetClientParameters } from '@wagmi/core' +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when getting Viem Public Client. + +::: code-group +```ts [index.ts] +import { getPublicClient } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const client = getPublicClient(config, { + chainId: mainnet.id, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetPublicClientReturnType } from '@wagmi/core' +``` + +`PublicClient | undefined` + +Viem [`PublicClient`](https://viem.sh/docs/clients/public.html) instance. diff --git a/wagmi-project/site/core/api/actions/getStorageAt.md b/wagmi-project/site/core/api/actions/getStorageAt.md new file mode 100644 index 0000000000..23a5dc1d2f --- /dev/null +++ b/wagmi-project/site/core/api/actions/getStorageAt.md @@ -0,0 +1,157 @@ + + +# getStorageAt + +Action for returning the value from a storage slot at a given address. + +## Import + +```ts +import { getStorageAt } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getStorageAt } from '@wagmi/core' +import { config } from './config' + +await getStorageAt(config, { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + slot: '0x0', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetStorageAtParameters } from '@wagmi/core' +``` + +### address + +`Address` + +The contract address. + +::: code-group +```ts [index.ts] +import { getStorageAt } from '@wagmi/core' +import { config } from './config' + +await getStorageAt(config, { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', // [!code focus] + slot: '0x0', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### slot + +`Hex` + +The storage position (as a hex encoded value). + +::: code-group +```ts [index.ts] +import { getStorageAt } from '@wagmi/core' +import { config } from './config' + +await getStorageAt(config, { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + slot: '0x0', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockNumber + +`bigint | undefined` + +The block number to check the storage at. + +::: code-group +```ts [index.ts] +import { getStorageAt } from '@wagmi/core' +import { config } from './config' + +await getStorageAt(config, { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + blockNumber: 16280770n, // [!code focus] + slot: '0x0', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +The block tag to check the storage at. + +::: code-group +```ts [index.ts] +import { getStorageAt } from '@wagmi/core' +import { config } from './config' + +await getStorageAt(config, { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + blockTag: 'safe', // [!code focus] + slot: '0x0', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +The chain ID to check the storage at. + +::: code-group +```ts [index.ts] +import { getStorageAt } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +await getStorageAt(config, { + chainId: mainnet.id, // [!code focus] + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + slot: '0x0', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetStorageAtReturnType } from '@wagmi/core' +``` + +`Hex` + +The value of the storage slot. + +## Error + +```ts +import { type GetStorageAtErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`getStorageAt`](https://viem.sh/docs/contract/getStorageAt) diff --git a/wagmi-project/site/core/api/actions/getToken.md b/wagmi-project/site/core/api/actions/getToken.md new file mode 100644 index 0000000000..b37805cff0 --- /dev/null +++ b/wagmi-project/site/core/api/actions/getToken.md @@ -0,0 +1,141 @@ + + +# getToken + +Action for fetching token info. + +## Import + +```ts +import { getToken } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getToken } from '@wagmi/core' +import { config } from './config' + +const token = getToken(config, { + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetTokenParameters } from '@wagmi/core' +``` + +### address + +`Address` + +Address to get token for. + +::: code-group +```ts [index.ts] +import { getToken } from '@wagmi/core' +import { config } from './config' + +const token = getToken(config, { + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { getToken } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const token = await getToken(config, { + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + chainId: mainnet.id, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### formatUnits + +`'ether' | 'gwei' | 'wei' | number | undefined` + +- Units to use when formatting result. +- Defaults to `'ether'`. + +::: code-group +```ts [index.ts] +import { getToken } from '@wagmi/core' +import { config } from './config' + +const token = getToken(config, { + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + formatUnits: 'ether', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetTokenReturnType } from '@wagmi/core' +``` + +### address + +`Address` + +Address of token. + +### decimals + +`number` + +Number of decimals for token. + +### name + +`string | undefined` + +Name of token. + +### symbol + +`string | undefined` + +Symbol of token. + +### totalSupply + +`{ formatted: string; value: bigint; }` + +Total supply of token. `formatted` is formatted using [`formatUnits`](#formatunits). + +## Error + +```ts +import { type GetTokenErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`multicall`](https://viem.sh/docs/contract/multicall) diff --git a/wagmi-project/site/core/api/actions/getTransaction.md b/wagmi-project/site/core/api/actions/getTransaction.md new file mode 100644 index 0000000000..8ebe770990 --- /dev/null +++ b/wagmi-project/site/core/api/actions/getTransaction.md @@ -0,0 +1,173 @@ + + +# getTransaction + +Action for fetching transactions given hashes or block identifiers. + +## Import + +```ts +import { getTransaction } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getTransaction } from '@wagmi/core' +import { config } from './config' + +const transaction = getTransaction(config, { + hash: '0x0fa64daeae54e207aa98613e308c2ba8abfe274f75507e741508cc4db82c8cb5', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetTransactionParameters } from '@wagmi/core' +``` + +--- + +### blockHash + +`bigint | undefined` + +Block hash to get transaction at (with [`index`](#index)). + +::: code-group +```ts [index.ts] +import { getTransaction } from '@wagmi/core' +import { config } from './config' + +const transaction = getTransaction(config, { + blockHash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', // [!code focus] + index: 0, +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockNumber + +`bigint | undefined` + +Block number to get transaction at (with [`index`](#index)). + +::: code-group +```ts [index.ts] +import { getTransaction } from '@wagmi/core' +import { config } from './config' + +const transaction = getTransaction(config, { + blockNumber: 17829139n, // [!code focus] + index: 0, +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get transaction at (with [`index`](#index)). + +::: code-group +```ts [index.ts] +import { getTransaction } from '@wagmi/core' +import { config } from './config' + +const transaction = getTransaction(config, { + blockTag: 'safe', // [!code focus] + index: 0, +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { getTransaction } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const transaction = await getTransaction(config, { + chainId: mainnet.id, // [!code focus] + hash: '0x0fa64daeae54e207aa98613e308c2ba8abfe274f75507e741508cc4db82c8cb5', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### hash + +`` `0x${string}` | undefined `` + +Hash to get transaction. + +::: code-group +```ts [index.ts] +import { getTransaction } from '@wagmi/core' +import { config } from './config' + +const transaction = getTransaction(config, { + hash: '0x0fa64daeae54e207aa98613e308c2ba8abfe274f75507e741508cc4db82c8cb5', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### index + +`number | undefined` + +An index to be used with a block identifier ([hash](#blockhash), [number](#blocknumber), or [tag](#blocktag)). + +::: code-group +```ts [index.ts] +import { getTransaction } from '@wagmi/core' +import { config } from './config' + +const transaction = getTransaction(config, { + blockTag: 'safe', + index: 0 // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetTransactionReturnType } from '@wagmi/core' +``` + +[`Transaction`](https://viem.sh/docs/glossary/types.html#transaction) + +## Error + +```ts +import { type GetTransactionErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`getTransaction`](https://viem.sh/docs/actions/public/getTransaction.html) diff --git a/wagmi-project/site/core/api/actions/getTransactionConfirmations.md b/wagmi-project/site/core/api/actions/getTransactionConfirmations.md new file mode 100644 index 0000000000..eb42df19ac --- /dev/null +++ b/wagmi-project/site/core/api/actions/getTransactionConfirmations.md @@ -0,0 +1,117 @@ + + +# getTransactionConfirmations + +Action for fetching the number of blocks passed (confirmations) since the transaction was processed on a block. If confirmations is 0, then the Transaction has not been confirmed & processed yet. + +## Import + +```ts +import { getTransactionConfirmations } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getTransactionConfirmations } from '@wagmi/core' +import { config } from './config' + +const transaction = getTransactionConfirmations(config, { + hash: '0x0fa64daeae54e207aa98613e308c2ba8abfe274f75507e741508cc4db82c8cb5', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetTransactionConfirmationsParameters } from '@wagmi/core' +``` + +--- + +### hash + +`` `0x${string}` | undefined `` + +The hash of the transaction. + +::: code-group +```ts [index.ts] +import { getTransactionConfirmations } from '@wagmi/core' +import { config } from './config' + +const transaction = getTransactionConfirmations(config, { + hash: '0x0fa64daeae54e207aa98613e308c2ba8abfe274f75507e741508cc4db82c8cb5', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### transactionReceipt + +`TransactionReceipt | undefined` + +The transaction receipt. + +::: code-group +```ts [index.ts] +import { getTransactionConfirmations } from '@wagmi/core' +import { config } from './config' + +const transaction = getTransactionConfirmations(config, { + transactionReceipt: { ... }, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { getTransactionConfirmations } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const transaction = await getTransactionConfirmations(config, { + chainId: mainnet.id, // [!code focus] + hash: '0x0fa64daeae54e207aa98613e308c2ba8abfe274f75507e741508cc4db82c8cb5', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetTransactionConfirmationsReturnType } from '@wagmi/core' +``` + +`bigint` + +The number of blocks passed since the transaction was processed. If confirmations is 0, then the Transaction has not been confirmed & processed yet. + +## Error + +```ts +import { type GetTransactionConfirmationsErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`getTransactionConfirmations`](https://viem.sh/docs/actions/public/getTransactionConfirmations.html) diff --git a/wagmi-project/site/core/api/actions/getTransactionCount.md b/wagmi-project/site/core/api/actions/getTransactionCount.md new file mode 100644 index 0000000000..d08987c84d --- /dev/null +++ b/wagmi-project/site/core/api/actions/getTransactionCount.md @@ -0,0 +1,139 @@ + + +# getTransactionCount + +Action for fetching the number of transactions an Account has sent. + +## Import + +```ts +import { getTransactionCount } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getTransactionCount } from '@wagmi/core' +import { config } from './config' + +const transactionCount = getTransactionCount(config, { + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetTransactionCountParameters } from '@wagmi/core' +``` + +--- + +### address + +`Address` + +The address of the account. + +::: code-group +```ts [index.ts] +import { getTransactionCount } from '@wagmi/core' +import { config } from './config' + +const transactionCount = getTransactionCount(config, { + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### blockNumber + +`bigint | undefined` + +Get the count at a block number. + +::: code-group +```ts [index.ts] +import { getTransactionCount } from '@wagmi/core' +import { config } from './config' + +const transactionCount = getTransactionCount(config, { + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + blockNumber: 17829139n, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Get the count at a block tag. + +::: code-group +```ts [index.ts] +import { getTransactionCount } from '@wagmi/core' +import { config } from './config' + +const transactionCount = getTransactionCount(config, { + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + blockTag: 'latest', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { getTransactionCount } from '@wagmi/core' +import { config } from './config' + +const transactionCount = getTransactionCount(config, { + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + chainId: mainnet.id, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + + +## Return Type + +```ts +import { type GetTransactionCountReturnType } from '@wagmi/core' +``` + +`number` + +The number of transactions an account has sent. + +## Error + +```ts +import { type GetTransactionCountErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`getTransactionCount`](https://viem.sh/docs/actions/public/getTransactionCount.html) diff --git a/wagmi-project/site/core/api/actions/getTransactionReceipt.md b/wagmi-project/site/core/api/actions/getTransactionReceipt.md new file mode 100644 index 0000000000..d0687ac63e --- /dev/null +++ b/wagmi-project/site/core/api/actions/getTransactionReceipt.md @@ -0,0 +1,95 @@ + + +# getTransactionReceipt + +Action for return the [Transaction Receipt](https://viem.sh/docs/glossary/terms.html#transaction-receipt) given a [Transaction](https://viem.sh/docs/glossary/terms.html#transaction) hash. + +## Import + +```ts +import { getTransactionReceipt } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getTransactionReceipt } from '@wagmi/core' +import { config } from './config' + +await getTransactionReceipt(config, { + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type GetTransactionReceiptParameters } from '@wagmi/core' +``` + +### hash + +`` `0x${string}` `` + +A transaction hash. + +::: code-group +```ts [index.ts] +import { getTransactionReceipt } from '@wagmi/core' +import { config } from './config' + +await getTransactionReceipt(config, { + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +The ID of chain to return the transaction receipt from. + +::: code-group +```ts [index.ts] +import { getTransactionReceipt } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +await getTransactionReceipt(config, { + chainId: mainnet.id, // [!code focus] + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetTransactionReceiptReturnType } from '@wagmi/core' +``` + +[`TransactionReceipt`](https://viem.sh/docs/glossary/types.html#transactionreceipt) + +The transaction receipt. + +## Error + +```ts +import { type GetTransactionReceiptErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`getTransactionReceipt`](https://viem.sh/docs/actions/public/getTransactionReceipt.html) diff --git a/wagmi-project/site/core/api/actions/getWalletClient.md b/wagmi-project/site/core/api/actions/getWalletClient.md new file mode 100644 index 0000000000..a321b3637c --- /dev/null +++ b/wagmi-project/site/core/api/actions/getWalletClient.md @@ -0,0 +1,112 @@ + + +# getWalletClient + +Action for getting a Viem [`WalletClient`](https://viem.sh/docs/clients/wallet.html) object for the current or provided connector. + +## Import + +```ts +import { getWalletClient } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getWalletClient } from '@wagmi/core' +import { config } from './config' + +const client = getWalletClient(config) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +::: warning +If you want to optimize bundle size, you should use [`getConnectorClient`](/core/api/actions/getConnectorClient) along with Viem's [tree-shakable actions](https://viem.sh/docs/clients/custom.html#tree-shaking) instead. Since Wallet Client has all wallet actions attached directly to it. +::: + +## Parameters + +```ts +import { type GetWalletClientParameters } from '@wagmi/core' +``` + +### account + +`Address | Account | undefined` + +Account to use with client. Throws if account is not found on [`connector`](#connector). + +::: code-group +```ts [index.ts] +import { getWalletClient } from '@wagmi/core' +import { config } from './config' + +const client = getWalletClient(config, { + account: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use with client. + +::: code-group +```ts [index.ts] +import { getWalletClient } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const client = getWalletClient(config, { + chainId: mainnet.id, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +- Connector to get client for. +- Defaults to current connector. + +::: code-group +```ts [index.ts] +import { getConnections, getWalletClient } from '@wagmi/core' +import { config } from './config' + +const connections = getConnections(config) +const client = getWalletClient(config, { + connector: connections[0]?.connector, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type GetChainIdReturnType } from '@wagmi/core' +``` + +`WalletClient` + +Viem [`WalletClient`](https://viem.sh/docs/clients/wallet.html) object for the current or provided connector. + +## Error + +```ts +import { type GetWalletClientErrorType } from '@wagmi/core' +``` + + \ No newline at end of file diff --git a/wagmi-project/site/core/api/actions/multicall.md b/wagmi-project/site/core/api/actions/multicall.md new file mode 100644 index 0000000000..ec46368d17 --- /dev/null +++ b/wagmi-project/site/core/api/actions/multicall.md @@ -0,0 +1,355 @@ +# multicall + +Action for batching up multiple functions on a contract in a single RPC call via the [Multicall3 contract](https://github.com/mds1/multicall). + +## Import + +```ts +import { multicall } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { multicall } from '@wagmi/core' +import { config } from './config' + +const wagmigotchiContract = { + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + abi: wagmigotchiABI, +} as const +const mlootContract = { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, +} as const + +const result = await multicall(config, { + contracts: [ + { + ...wagmigotchiContract, + functionName: 'getAlive', + }, + { + ...wagmigotchiContract, + functionName: 'getBoredom', + }, + { + ...mlootContract, + functionName: 'getChest', + args: [69], + }, + { + ...mlootContract, + functionName: 'getWaist', + args: [69], + }, + ], +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type MulticallParameters } from '@wagmi/core' +``` + +### contracts + +`readonly Contract[]` + +Set of contracts to call. + +#### abi + +`Abi | undefined` + +The contract's ABI. Check out the [TypeScript docs](/react/typescript#const-assert-abis-typed-data) for how to set up ABIs for maximum type inference and safety. + +::: code-group +```tsx [index.tsx] +import { multicall } from '@wagmi/core' +import { config } from './config' + +const result = await multicall(config, { + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, // [!code hl] + functionName: 'getChest', + args: [69], + }, + // ... + ], +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +#### address + +`Address | undefined` + +The contract's address. + +::: code-group +```tsx [index.tsx] +import { multicall } from '@wagmi/core' +import { config } from './config' + +const result = await multicall(config, { + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', // [!code hl] + abi: mlootABI, + functionName: 'getChest', + args: [69], + }, + // ... + ], +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +#### args + +`readonly unknown[] | undefined` + +- Arguments to pass when calling the contract. +- Inferred from [`abi`](#abi) and [`functionName`](#functionname). + +::: code-group +```tsx [index.tsx] +import { multicall } from '@wagmi/core' +import { config } from './config' + +const result = await multicall(config, { + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69], // [!code hl] + }, + // ... + ], +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +#### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { multicall } from '@wagmi/core' +import { config } from './config' + +const result = await multicall(config, { + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69], + chainId: 1, // [!code hl] + }, + // ... + ], +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + +#### functionName + +`string | undefined` + +- Function to call on the contract. +- Inferred from [`abi`](#abi). + +::: code-group +```tsx [index.tsx] +import { multicall } from '@wagmi/core' +import { config } from './config' + +const result = await multicall(config, { + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', // [!code hl] + args: [69], + }, + // ... + ], +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### allowFailure + +`boolean` + +Whether or not the Hook should throw if a call reverts. If set to `true` (default), and a call reverts, then `multicall` will fail silently and its error will be logged in the results array. Defaults to `true`. + +::: code-group +```tsx [index.tsx] +import { multicall } from '@wagmi/core' +import { config } from './config' + +const result = await multicall(config, { + allowFailure: false, // [!code hl] + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69], + }, + // ... + ], +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### batchSize + +`number` + +The maximum size (in bytes) for each calldata chunk. Set to `0` to disable the size limit. Defaults to `1024`. + +> Note: Some RPC Providers limit the amount of calldata (`data`) that can be sent in a single `eth_call` request. It is best to check with your RPC Provider to see if there are any calldata size limits to `eth_call` requests. + +::: code-group +```tsx [index.tsx] +import { multicall } from '@wagmi/core' +import { config } from './config' + +const result = await multicall(config, { + batchSize: 1_024, // [!code hl] + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69], + }, + // ... + ], +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockNumber + +`number` + +The block number to perform the read against. + +::: code-group +```tsx [index.tsx] +import { multicall } from '@wagmi/core' +import { config } from './config' + +const result = await multicall(config, { + blockNumber: 69420n, // [!code hl] + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69], + }, + // ... + ], +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to read against. + +::: code-group +```tsx [index.tsx] +import { multicall } from '@wagmi/core' +import { config } from './config' + +const result = await multicall(config, { + blockTag: 'safe', // [!code hl] + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69], + }, + // ... + ], +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### multicallAddress + +`Address` + +Address of multicall contract. + +::: code-group +```tsx [index.tsx] +import { multicall } from '@wagmi/core' +import { config } from './config' + +const result = await multicall(config, { + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69], + }, + // ... + ], + multicallAddress: '0xca11bde05977b3631167028862be2a173976ca11', // [!code hl] +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + +## Return Type + +```ts +import { type MulticallReturnType } from '@wagmi/core' +``` + +## Type Inference + +With [`contracts[number]['abi']`](#abi) setup correctly, TypeScript will infer the correct types for [`functionName`](#functionname), [`args`](#args), and the return type. See the Wagmi [TypeScript docs](/core/typescript) for more information. + +## Error + +```ts +import { type MulticallErrorType } from '@wagmi/core' +``` + +## Viem + +- [`multicall`](https://viem.sh/docs/actions/public/multicall.html) diff --git a/wagmi-project/site/core/api/actions/prepareTransactionRequest.md b/wagmi-project/site/core/api/actions/prepareTransactionRequest.md new file mode 100644 index 0000000000..1a1f1fc207 --- /dev/null +++ b/wagmi-project/site/core/api/actions/prepareTransactionRequest.md @@ -0,0 +1,307 @@ + + +# prepareTransactionRequest + +Action for preparing a transaction request for signing by populating a nonce, gas limit, fee values, and a transaction type. + +## Import + +```ts +import { prepareTransactionRequest } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { prepareTransactionRequest } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +await prepareTransactionRequest(config, { + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type PrepareTransactionRequestParameters } from '@wagmi/core' +``` + +### account + +`Account | Address | undefined` + +The Account to send the transaction from. + +::: code-group +```ts [index.ts] +import { prepareTransactionRequest } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +await prepareTransactionRequest(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### to + +`` `0x${string}` | undefined `` + +The transaction recipient or contract address. + +::: code-group +```ts [index.ts] +import { prepareTransactionRequest } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +await prepareTransactionRequest(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', // [!code focus] + value: parseEther('1'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### accessList + +`AccessList | undefined` + +The access list. + +::: code-group +```ts [index.ts] +import { prepareTransactionRequest } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +await prepareTransactionRequest(config, { + accessList: [ // [!code focus:6] + { + address: '0x1', + storageKeys: ['0x1'], + }, + ], + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +Chain ID to prepare the transaction request for. + +::: code-group +```ts [index.ts] +import { prepareTransactionRequest } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { parseEther } from 'viem' +import { config } from './config' + +await prepareTransactionRequest(config, { + chainId: mainnet.id, // [!code focus] + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### data + +`` `0x${string}` | undefined `` + +A contract hashed method call with encoded args. + +::: code-group +```ts [index.ts] +import { prepareTransactionRequest } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +await prepareTransactionRequest(config, { + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', // [!code focus] + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### gasPrice + +`bigint | undefined` + +The price (in wei) to pay per gas. Only applies to [Legacy Transactions](https://viem.sh/docs/glossary/terms.html#legacy-transaction). + +::: code-group +```ts [index.ts] +import { prepareTransactionRequest } from '@wagmi/core' +import { parseEther, parseGwei } from 'viem' +import { config } from './config' + +await prepareTransactionRequest(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + gasPrice: parseGwei('20'), // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### maxFeePerGas + +`bigint | undefined` + +Total fee per gas (in wei), inclusive of `maxPriorityFeePerGas`. Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```ts [index.ts] +import { prepareTransactionRequest } from '@wagmi/core' +import { parseEther, parseGwei } from 'viem' +import { config } from './config' + +await prepareTransactionRequest(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + maxFeePerGas: parseGwei('20'), // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### maxPriorityFeePerGas + +`bigint | undefined` + +Max priority fee per gas (in wei). Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```ts [index.ts] +import { prepareTransactionRequest } from '@wagmi/core' +import { parseEther, parseGwei } from 'viem' +import { config } from './config' + +await prepareTransactionRequest(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + maxFeePerGas: parseGwei('20'), + maxPriorityFeePerGas: parseGwei('2'), // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### nonce + +`number | undefined` + +Unique number identifying this transaction. + +::: code-group +```ts [index.ts] +import { prepareTransactionRequest } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +await prepareTransactionRequest(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), + nonce: 5, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### parameters + +`("fees" | "gas" | "nonce" | "type")[] | undefined` + +Parameters to prepare. + +For instance, if `["gas", "nonce"]` is provided, then only the `gas` and `nonce` parameters will be prepared. + +::: code-group +```ts [index.ts] +import { prepareTransactionRequest } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +await prepareTransactionRequest(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + parameters: ['gas', 'nonce'], // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### value + +`bigint | undefined` + +The transaction recipient or contract address. + +::: code-group +```ts [index.ts] +import { prepareTransactionRequest } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +await prepareTransactionRequest(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type PrepareTransactionRequestReturnType } from '@wagmi/core' +``` + +[`TransactionRequest`](https://viem.sh/docs/glossary/types.html#transactionrequest) + +The transaction request. + +## Error + +```ts +import { type PrepareTransactionRequestErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`prepareTransactionRequest`](https://viem.sh/docs/actions/wallet/prepareTransactionRequest.html) diff --git a/wagmi-project/site/core/api/actions/readContract.md b/wagmi-project/site/core/api/actions/readContract.md new file mode 100644 index 0000000000..80dfbb0b2e --- /dev/null +++ b/wagmi-project/site/core/api/actions/readContract.md @@ -0,0 +1,258 @@ + + +# readContract + +Action for calling a **read-only** function on a contract, and returning the response. + +A **read-only** function (constant function) on a Solidity contract is denoted by a pure or view keyword. They can only read the state of the contract, and cannot make any changes to it. Since read-only methods do not change the state of the contract, they do not require any gas to be executed, and can be called by any user without the need to pay for gas. + +## Import + +```ts +import { readContract } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { readContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await readContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'totalSupply', +}) +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type ReadContractParameters } from '@wagmi/core' +``` + +### abi + +`Abi` + +The contract's ABI. Check out the [TypeScript docs](/react/typescript#const-assert-abis-typed-data) for how to set up ABIs for maximum type inference and safety. + +::: code-group +```ts [index.ts] +import { readContract } from '@wagmi/core' +import { abi } from './abi' // [!code focus] +import { config } from './config' + +const result = await readContract(config, { + abi, // [!code focus] + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'totalSupply', +}) +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### account + +`Account | undefined` + +Account to use when calling the contract (`msg.sender`). + +::: code-group +```ts [index.ts] +import { readContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await readContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'balanceOf', + args: ['0xd2135CfB216b74109775236E36d4b433F1DF507B'], + account: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] +}) +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### address + +`Address` + +The contract's address. + +::: code-group +```ts [index.ts] +import { readContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await readContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', // [!code focus] + functionName: 'totalSupply', +}) +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### args + +`readonly unknown[] | undefined` + +- Arguments to pass when calling the contract. +- Inferred from [`abi`](#abi) and [`functionName`](#functionname). + +::: code-group +```ts [index.ts] +import { readContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await readContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'balanceOf', + args: ['0xd2135CfB216b74109775236E36d4b433F1DF507B'], // [!code focus] +}) +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### blockNumber + +`bigint | undefined` + +Block number to call contract at. + +::: code-group +```ts [index.ts] +import { readContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await readContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'totalSupply', + blockNumber: 17829139n, // [!code focus] +}) +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to call contract at. + +::: code-group +```ts [index.ts] +import { readContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await readContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'totalSupply', + blockTag: 'safe', // [!code focus] +}) +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { readContract } from '@wagmi/core' +import { mainnet } from 'wagmi/chains' // [!code focus] +import { abi } from './abi' +import { config } from './config' + +const result = await readContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'totalSupply', + chainId: mainnet.id, // [!code focus] +}) +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### functionName + +`string` + +- Function to call on the contract. +- Inferred from [`abi`](#abi). + +::: code-group +```ts [index.ts] +import { readContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await readContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'balanceOf', // [!code focus] + args: ['0xd2135CfB216b74109775236E36d4b433F1DF507B'], +}) +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type ReadContractReturnType } from '@wagmi/core' +``` + +`unknown` + +- Result of contract read-only function. +- Inferred from [`abi`](#abi), [`functionName`](#functionname), and [`args`](#args). + +## Type Inference + +With [`abi`](#abi) setup correctly, TypeScript will infer the correct types for [`functionName`](#functionname), [`args`](#args), and the return type. See the Wagmi [TypeScript docs](/core/typescript) for more information. + +## Error + +```ts +import { type ReadContractErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`readContract`](https://viem.sh/docs/contract/readContract.html) diff --git a/wagmi-project/site/core/api/actions/readContracts.md b/wagmi-project/site/core/api/actions/readContracts.md new file mode 100644 index 0000000000..67cbdf65af --- /dev/null +++ b/wagmi-project/site/core/api/actions/readContracts.md @@ -0,0 +1,363 @@ + + +# readContracts + +Action for calling multiple read methods on a contract. + +## Import + +```ts +import { readContracts } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { readContracts } from '@wagmi/core' +import { config } from './config' + +const wagmigotchiContract = { + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + abi: wagmigotchiABI, +} as const +const mlootContract = { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, +} as const + +const result = await readContracts(config, { + contracts: [ + { + ...wagmigotchiContract, + functionName: 'getAlive', + }, + { + ...wagmigotchiContract, + functionName: 'getBoredom', + }, + { + ...mlootContract, + functionName: 'getChest', + args: [69], + }, + { + ...mlootContract, + functionName: 'getWaist', + args: [69], + }, + ], +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type ReadContractsParameters } from '@wagmi/core' +``` + +### contracts + +`readonly Contract[]` + +Set of contracts to call. + +#### abi + +`Abi | undefined` + +The contract's ABI. Check out the [TypeScript docs](/react/typescript#const-assert-abis-typed-data) for how to set up ABIs for maximum type inference and safety. + +::: code-group +```tsx [index.tsx] +import { readContracts } from '@wagmi/core' +import { config } from './config' + +const result = await readContracts(config, { + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, // [!code hl] + functionName: 'getChest', + args: [69], + }, + // ... + ], +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +#### address + +`Address | undefined` + +The contract's address. + +::: code-group +```tsx [index.tsx] +import { readContracts } from '@wagmi/core' +import { config } from './config' + +const result = await readContracts(config, { + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', // [!code hl] + abi: mlootABI, + functionName: 'getChest', + args: [69], + }, + // ... + ], +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +#### args + +`readonly unknown[] | undefined` + +- Arguments to pass when calling the contract. +- Inferred from [`abi`](#abi) and [`functionName`](#functionname). + +::: code-group +```tsx [index.tsx] +import { readContracts } from '@wagmi/core' +import { config } from './config' + +const result = await readContracts(config, { + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69], // [!code hl] + }, + // ... + ], +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +#### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { readContracts } from '@wagmi/core' +import { config } from './config' + +const result = await readContracts(config, { + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69], + chainId: 1, // [!code hl] + }, + // ... + ], +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + +#### functionName + +`string | undefined` + +- Function to call on the contract. +- Inferred from [`abi`](#abi). + +::: code-group +```tsx [index.tsx] +import { readContracts } from '@wagmi/core' +import { config } from './config' + +const result = await readContracts(config, { + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', // [!code hl] + args: [69], + }, + // ... + ], +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### allowFailure + +`boolean` + +Whether or not the Hook should throw if a call reverts. If set to `true` (default), and a call reverts, then `readContracts` will fail silently and its error will be logged in the results array. Defaults to `true`. + +::: code-group +```tsx [index.tsx] +import { readContracts } from '@wagmi/core' +import { config } from './config' + +const result = await readContracts(config, { + allowFailure: false, // [!code hl] + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69], + }, + // ... + ], +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### batchSize + +`number` + +The maximum size (in bytes) for each calldata chunk. Set to `0` to disable the size limit. Defaults to `1024`. + +> Note: Some RPC Providers limit the amount of calldata (`data`) that can be sent in a single `eth_call` request. It is best to check with your RPC Provider to see if there are any calldata size limits to `eth_call` requests. + +::: code-group +```tsx [index.tsx] +import { readContracts } from '@wagmi/core' +import { config } from './config' + +const result = await readContracts(config, { + batchSize: 1_024, // [!code hl] + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69], + }, + // ... + ], +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockNumber + +`number` + +The block number to perform the read against. + +::: code-group +```tsx [index.tsx] +import { readContracts } from '@wagmi/core' +import { config } from './config' + +const result = await readContracts(config, { + blockNumber: 69420n, // [!code hl] + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69], + }, + // ... + ], +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to read against. + +::: code-group +```tsx [index.tsx] +import { readContracts } from '@wagmi/core' +import { config } from './config' + +const result = await readContracts(config, { + blockTag: 'safe', // [!code hl] + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69], + }, + // ... + ], +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### multicallAddress + +`Address` + +Address of multicall contract. + +::: code-group +```tsx [index.tsx] +import { readContracts } from '@wagmi/core' +import { config } from './config' + +const result = await readContracts(config, { + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69], + }, + // ... + ], + multicallAddress: '0xca11bde05977b3631167028862be2a173976ca11', // [!code hl] +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type ReadContractsReturnType } from '@wagmi/core' +``` + +## Type Inference + +With [`contracts[number]['abi']`](#abi) setup correctly, TypeScript will infer the correct types for [`functionName`](#functionname), [`args`](#args), and the return type. See the Wagmi [TypeScript docs](/core/typescript) for more information. + +## Error + +```ts +import { type ReadContractsErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`multicall`](https://viem.sh/docs/actions/public/multicall.html) when supported by current chain. +- [`readContract`](https://viem.sh/docs/contract/readContract.html) when multicall is not supported. diff --git a/wagmi-project/site/core/api/actions/reconnect.md b/wagmi-project/site/core/api/actions/reconnect.md new file mode 100644 index 0000000000..983be9aa76 --- /dev/null +++ b/wagmi-project/site/core/api/actions/reconnect.md @@ -0,0 +1,72 @@ + + +# reconnect + +Action for reconnecting [connectors](/core/api/connectors). + +## Import + +```ts +import { reconnect } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { reconnect } from '@wagmi/core' +import { injected } from '@wagmi/connectors' +import { config } from './config' + +const result = await reconnect(config, { connectors: [injected()] }) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type ReconnectParameters } from '@wagmi/core' +``` + +### connectors + +`(CreateConnectorFn | Connector)[] | undefined` + +- [Connectors](/core/api/connectors) to reconnect to. +- Defaults to [`Config['connectors']`](/core/api/createConfig#connectors). + +::: code-group +```ts [index.ts] +import { reconnect } from '@wagmi/core' +import { injected } from '@wagmi/connectors' +import { config } from './config' + +const result = await reconnect(config, { + connectors: [injected()], // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type ReconnectReturnType } from '@wagmi/core' +``` + +`Connection[]` + +[Connections](/core/api/createConfig#connection) that were successfully reconnected. + +## Error + +```ts +import { type ReconnectErrorType } from '@wagmi/core' +``` + + diff --git a/wagmi-project/site/core/api/actions/sendCalls.md b/wagmi-project/site/core/api/actions/sendCalls.md new file mode 100644 index 0000000000..8e65890e5e --- /dev/null +++ b/wagmi-project/site/core/api/actions/sendCalls.md @@ -0,0 +1,223 @@ + + +# sendCalls + +Action that requests for the wallet to sign and broadcast a batch of calls (transactions) to the network. + +[Read more.](https://github.com/ethereum/EIPs/blob/815028dc634463e1716fc5ce44c019a6040f0bef/EIPS/eip-5792.md#wallet_sendcalls) + + + +## Import + +```ts +import { sendCalls } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { parseEther } from 'viem' +import { sendCalls } from '@wagmi/core' +import { config } from './config' + +const id = await sendCalls(config, { + calls: [ + { + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1') + }, + { + data: '0xdeadbeef', + to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + }, + ] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type SendCallsParameters } from '@wagmi/core' +``` + +### account + +`Account | Address | null | undefined` + +Account to execute the calls. + +If set to `null`, it is assumed that the wallet will handle filling the sender of the calls. + +::: code-group +```ts [index.ts] +import { parseEther } from 'viem' +import { sendCalls } from '@wagmi/core' +import { config } from './config' + +const id = await sendCalls(config, { + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', // [!code focus] + calls: [ + { + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1') + }, + { + data: '0xdeadbeef', + to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + }, + ], +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### calls + +`{ to: Hex, data?: Hex, value?: bigint }[]` + +Calls to execute. + +::: code-group +```ts [index.ts] +import { parseEther } from 'viem' +import { sendCalls } from '@wagmi/core' +import { config } from './config' + +const id = await sendCalls(config, { + calls: [ // [!code focus] + { // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', // [!code focus] + value: parseEther('1') // [!code focus] + }, // [!code focus] + { // [!code focus] + data: '0xdeadbeef', // [!code focus] + to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', // [!code focus] + }, // [!code focus] + ], // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### capabilities + +`WalletCapabilities | undefined` + +Capability metadata for the calls (e.g. specifying a paymaster). + +::: code-group +```ts [index.ts] +import { parseEther } from 'viem' +import { sendCalls } from '@wagmi/core' +import { config } from './config' + +const id = await sendCalls(config, { + calls: [ + { + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1') + }, + { + data: '0xdeadbeef', + to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + }, + ], + capabilities: { // [!code focus] + paymasterService: { // [!code focus] + url: 'https://...' // [!code focus] + } // [!code focus] + } // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`number | undefined` + +The target chain ID to broadcast the calls. + +::: code-group +```ts [index.ts] +import { parseEther } from 'viem' +import { sendCalls } from '@wagmi/core' +import { config } from './config' + +const id = await sendCalls(config, { + calls: [ + { + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1') + }, + { + data: '0xdeadbeef', + to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + }, + ], + chainId: 10, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +Connector to get send the calls with. + +::: code-group +```ts [index.ts] +import { parseEther } from 'viem' +import { getConnections } from '@wagmi/core' +import { sendCalls } from '@wagmi/core' +import { config } from './config' + +const connections = getConnections(config) +const id = await sendCalls(config, { + calls: [ + { + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1') + }, + { + data: '0xdeadbeef', + to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + }, + ], + connector: connections[0]?.connector, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type SendCallsReturnType } from '@wagmi/core' +``` + +`bigint` + +Most recent block number seen. + +## Error + +```ts +import { type SendCallsErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`sendCalls`](https://viem.sh/experimental/eip5792/sendCalls) diff --git a/wagmi-project/site/core/api/actions/sendTransaction.md b/wagmi-project/site/core/api/actions/sendTransaction.md new file mode 100644 index 0000000000..e02e1908dc --- /dev/null +++ b/wagmi-project/site/core/api/actions/sendTransaction.md @@ -0,0 +1,341 @@ + + +# sendTransaction + +Action for creating, signing, and sending transactions to networks. + +## Import + +```ts +import { sendTransaction } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { sendTransaction } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +const result = await sendTransaction(config, { + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type SendTransactionParameters } from '@wagmi/core' +``` + +### accessList + +`AccessList | undefined` + +The access list. + +::: code-group +```ts [index.ts] +import { sendTransaction } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +const result = await sendTransaction(config, { + accessList: [{ // [!code focus] + address: '0x1', // [!code focus] + storageKeys: ['0x1'], // [!code focus] + }], // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### account + +`Address | Account | undefined` + +Account to use when sending transaction. Throws if account is not found on [`connector`](#connector). + +::: code-group +```ts [index.ts] +import { sendTransaction } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +const result = await sendTransaction(config, { + account: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +Chain ID to validate against before sending transaction. + +::: code-group +```ts [index.ts] +import { sendTransaction } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { parseEther } from 'viem' +import { config } from './config' + +const result = await sendTransaction(config, { + chainId: mainnet.id, // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +- Connector to send transaction with. +- Defaults to current connector. + +::: code-group +```ts [index.ts] +import { getConnections, sendTransaction } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +const connections = getConnections(config) +const result = await sendTransaction(config, { + connector: connections[0]?.connector, // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### data + +`` `0x${string}` | undefined `` + +A contract hashed method call with encoded args. + +::: code-group +```ts [index.ts] +import { sendTransaction } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +const result = await sendTransaction(config, { + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### gas + +`bigint | undefined | null` + +Gas provided for transaction execution. + +::: code-group +```ts [index.ts] +import { sendTransaction } from '@wagmi/core' +import { parseEther, parseGwei } from 'viem' +import { config } from './config' + +const result = await sendTransaction(config, { + gas: parseGwei('20'), // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### gasPrice + +`bigint | undefined` + +The price in wei to pay per gas. Only applies to [Legacy Transactions](https://viem.sh/docs/glossary/terms.html#legacy-transaction). + +::: code-group +```ts [index.ts] +import { sendTransaction } from '@wagmi/core' +import { parseEther, parseGwei } from 'viem' +import { config } from './config' + +const result = await sendTransaction(config, { + gasPrice: parseGwei('20'), // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### maxFeePerGas + +`bigint | undefined` + +Total fee per gas in wei, inclusive of [`maxPriorityFeePerGas`](#maxPriorityFeePerGas). Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```ts [index.ts] +import { sendTransaction } from '@wagmi/core' +import { parseEther, parseGwei } from 'viem' +import { config } from './config' + +const result = await sendTransaction(config, { + maxFeePerGas: parseGwei('20'), // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### maxPriorityFeePerGas + +`bigint | undefined` + +Max priority fee per gas in wei. Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```ts [index.ts] +import { sendTransaction } from '@wagmi/core' +import { parseEther, parseGwei } from 'viem' +import { config } from './config' + +const result = await sendTransaction(config, { + maxFeePerGas: parseGwei('20'), + maxPriorityFeePerGas: parseGwei('2'), // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### nonce + +`number` + +Unique number identifying this transaction. + +::: code-group +```ts [index.ts] +import { sendTransaction } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +const result = await sendTransaction(config, { + nonce: 123, // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### to + +`Address` + +The transaction recipient or contract address. + +::: code-group +```ts [index.ts] +import { sendTransaction } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +const result = await sendTransaction(config, { + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### type + +`'legacy' | 'eip1559' | 'eip2930' | undefined` + +Optional transaction request type to narrow parameters. + +::: code-group +```ts [index.ts] +import { sendTransaction } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +const result = await sendTransaction(config, { + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + type: 'eip1559', // [!code focus] + value: parseEther('0.01'), +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### value + +`bigint | undefined` + +Value in wei sent with this transaction. + +::: code-group +```ts [index.ts] +import { sendTransaction } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +const result = await sendTransaction(config, { + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type SendTransactionReturnType } from '@wagmi/core' +``` + +[`Hash`](https://viem.sh/docs/glossary/types.html#hash) + +Transaction hash. + +## Error + +```ts +import { type SendTransactionErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`sendTransaction`](https://viem.sh/docs/actions/wallet/sendTransaction.html) diff --git a/wagmi-project/site/core/api/actions/showCallsStatus.md b/wagmi-project/site/core/api/actions/showCallsStatus.md new file mode 100644 index 0000000000..c47d1fb88d --- /dev/null +++ b/wagmi-project/site/core/api/actions/showCallsStatus.md @@ -0,0 +1,99 @@ + + +# showCallsStatus + +Action to request for the wallet to show information about a call batch that was sent via `showCalls`. + +[Read more.](https://github.com/ethereum/EIPs/blob/1663ea2e7a683285f977eda51c32cec86553f585/EIPS/eip-5792.md#wallet_showcallsstatus) + + + +## Import + +```ts +import { showCallsStatus } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { showCallsStatus } from '@wagmi/core' +import { config } from './config' + +await showCallsStatus(config, { + id: '0x1234567890abcdef', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type ShowCallsStatusParameters } from '@wagmi/core' +``` + +### connector + +`Connector | undefined` + +Connector to show call statuses with. + +::: code-group +```ts [index.ts] +import { getConnections, showCallsStatus } from '@wagmi/core' +import { config } from './config' + +const connections = getConnections(config) +await showCallsStatus(config, { + connector: connections[0]?.connector, // [!code focus] + id: '0x1234567890abcdef', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### id + +`string` + +Identifier of the call batch. + +::: code-group +```ts [index.ts] +import { showCallsStatus } from '@wagmi/core' +import { config } from './config' + +await showCallsStatus(config, { + id: '0x1234567890abcdef', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type ShowCallsStatusReturnType } from '@wagmi/core' +``` + +`bigint` + +Most recent block number seen. + +## Error + +```ts +import { type ShowCallsStatusErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`showCallsStatus`](https://viem.sh/experimental/eip5792/showCallsStatus) diff --git a/wagmi-project/site/core/api/actions/signMessage.md b/wagmi-project/site/core/api/actions/signMessage.md new file mode 100644 index 0000000000..23569146ac --- /dev/null +++ b/wagmi-project/site/core/api/actions/signMessage.md @@ -0,0 +1,125 @@ + + +# signMessage + +Action for signing messages. + +## Import + +```ts +import { signMessage } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { signMessage } from '@wagmi/core' +import { config } from './config' + +await signMessage(config, { message: 'hello world' }) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type SignMessageParameters } from '@wagmi/core' +``` + +### account + +`Address | Account | undefined` + +Account to use when signing message. Throws if account is not found on [`connector`](#connector). + +::: code-group +```ts [index.ts] +import { signMessage } from '@wagmi/core' +import { config } from './config' + +const result = await signMessage(config, { + account: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] + message: 'hello world', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +[Connector](/core/api/connectors) to sign message with. + +::: code-group +```ts [index.ts] +import { getAccount, signMessage } from '@wagmi/core' +import { config } from './config' + +const { connector } = getAccount(config) +const result = await signMessage(config, { + connector, // [!code focus] + message: 'hello world', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### message + +`string | { raw: Hex | ByteArray }` + +Message to sign. + +::: code-group +```ts [index.ts] +import { signMessage } from '@wagmi/core' +import { config } from './config' + +const result = await signMessage(config, { + message: 'hello world', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +::: tip +By default, viem signs the UTF-8 representation of the message. To sign the data representation of the message, you can use the `raw` attribute. + +```ts +import { signMessage } from '@wagmi/core' +import { config } from './config' + +const result = await signMessage(config, { + message: { raw: '0x68656c6c6f20776f726c64' }, // [!code focus] +}) +``` +::: + +## Return Type + +```ts +import { type SignMessageReturnType } from '@wagmi/core' +``` + +[`Hex`](https://viem.sh/docs/glossary/types.html#hex) + +The signed message. + +## Error + +```ts +import { type SignMessageErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`signMessage`](https://viem.sh/docs/actions/wallet/signMessage.html) diff --git a/wagmi-project/site/core/api/actions/signTypedData.md b/wagmi-project/site/core/api/actions/signTypedData.md new file mode 100644 index 0000000000..757c87160f --- /dev/null +++ b/wagmi-project/site/core/api/actions/signTypedData.md @@ -0,0 +1,409 @@ + + +# signTypedData + +Action for signing typed data and calculating an Ethereum-specific [EIP-712](https://eips.ethereum.org/EIPS/eip-712) signature. + +## Import + +```ts +import { signTypedData } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { signTypedData } from '@wagmi/core' +import { config } from './config' + +const result = await signTypedData(config, { + types: { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + }, + primaryType: 'Mail', + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type SignTypedDataParameters } from '@wagmi/core' +``` + +### account + +`Address | Account | undefined` + +Account to use when signing data. Throws if account is not found on [`connector`](#connector). + +::: code-group +```ts [index.ts] +import { signTypedData } from '@wagmi/core' +import { config } from './config' +import { types } from './typedData' + +const result = await signTypedData(config, { + account: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] + types, + primaryType: 'Mail', + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, +}) +``` +<<< @/snippets/typedData.ts[typedData.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +[Connector](/core/api/connectors) to sign data with. + +::: code-group +```ts [index.ts] +import { getAccount, signTypedData } from '@wagmi/core' +import { config } from './config' +import { types } from './typedData' + +const { connector } = getAccount(config) +const result = await signTypedData(config, { + connector, // [!code focus] + types, + primaryType: 'Mail', + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, +}) +``` +<<< @/snippets/typedData.ts[typedData.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### domain + +`TypedDataDomain | undefined` + +- The typed data domain. +- If `EIP712Domain` key exists in [`types`](#types), `domain` schema is inferred from it. + +::: code-group +```ts [index.ts] +import { signTypedData } from '@wagmi/core' +import { config } from './config' +import { types } from './typedData' + +const result = await signTypedData(config, { + domain: { // [!code focus] + name: 'Ether Mail', // [!code focus] + chainId: 1, // [!code focus] + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', // [!code focus] + version: '1', // [!code focus] + }, // [!code focus] + types, + primaryType: 'Mail', + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, +}) +``` +<<< @/snippets/typedData.ts[typedData.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### message + +`Record` + +- Data to sign. +- Type inferred from [`types`](#types) and [`primaryType`](#primarytype). + +::: code-group +```ts [index.ts] +import { signTypedData } from '@wagmi/core' +import { config } from './config' +import { types } from './typedData' + +const result = await signTypedData(config, { + types, + primaryType: 'Mail', + message: { // [!code focus] + from: { // [!code focus] + name: 'Cow', // [!code focus] + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', // [!code focus] + }, // [!code focus] + to: { // [!code focus] + name: 'Bob', // [!code focus] + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', // [!code focus] + }, // [!code focus] + contents: 'Hello, Bob!', // [!code focus] + }, // [!code focus] +}) +``` +<<< @/snippets/typedData.ts[typedData.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### primaryType + +`string` + +- The primary type to extract from [`types`](#types) and use in [`message`](#message). +- Type inferred from [`types`](#types). + +::: code-group +```ts [index.ts] +import { signTypedData } from '@wagmi/core' +import { config } from './config' +import { types } from './typedData' + +const result = await signTypedData(config, { + types, + primaryType: 'Mail', // [!code focus] + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, +}) +``` +<<< @/snippets/typedData.ts[typedData.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### types + +`TypedData` + +- The type definitions for the typed data. +- By defining inline or adding a [const assertion](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions) to `types`, TypeScript will infer the correct types for [`message`](#message) and [`primaryType`](#primarytype). See the Wagmi [TypeScript docs](/core/typescript) for more information. + +::: code-group +```ts [index.ts] +import { signTypedData } from '@wagmi/core' +import { config } from './config' + +const result = await signTypedData(config, { + types: { // [!code focus] + Person: [ // [!code focus] + { name: 'name', type: 'string' }, // [!code focus] + { name: 'wallet', type: 'address' }, // [!code focus] + ], // [!code focus] + Mail: [ // [!code focus] + { name: 'from', type: 'Person' }, // [!code focus] + { name: 'to', type: 'Person' }, // [!code focus] + { name: 'contents', type: 'string' }, // [!code focus] + ], // [!code focus] + }, // [!code focus] + primaryType: 'Mail', + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type SignTypedDataReturnType } from '@wagmi/core' +``` + +[`Hex`](https://viem.sh/docs/glossary/types.html#hex) + +The signed data. + +## Type Inference + +With [`types`](#types) setup correctly, TypeScript will infer the correct types for [`domain`](#domain), [`message`](#message), and [`primaryType`](#primarytype). See the Wagmi [TypeScript docs](/core/typescript) for more information. + +::: code-group +```ts twoslash [Inline] +import { createConfig, http, signTypedData } from '@wagmi/core' +import { mainnet, sepolia } from '@wagmi/core/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +// ---cut--- +const result = await signTypedData(config, { + types: { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + }, + primaryType: 'Mail', + // ^? + + + message: { + // ^? + + + + + + + + + + + + + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, +}) +``` +```ts twoslash [Const-Asserted] +import { createConfig, http, signTypedData } from '@wagmi/core' +import { mainnet, sepolia } from '@wagmi/core/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +// ---cut--- +const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const + +const result = await signTypedData(config, { + types, + primaryType: 'Mail', + // ^? + + + message: { + // ^? + + + + + + + + + + + + + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, +}) +``` +::: + +## Error + +```ts +import { type SignTypedDataErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`signTypedData`](https://viem.sh/docs/actions/wallet/signTypedData.html) diff --git a/wagmi-project/site/core/api/actions/simulateContract.md b/wagmi-project/site/core/api/actions/simulateContract.md new file mode 100644 index 0000000000..b7884ef713 --- /dev/null +++ b/wagmi-project/site/core/api/actions/simulateContract.md @@ -0,0 +1,598 @@ + + +# simulateContract + +Action for simulating/validating a contract interaction. + +## Import + +```ts +import { simulateContract } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { simulateContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type SimulateContractParameters } from '@wagmi/core' +``` + +### abi + +`Abi` + +The contract's ABI. Check out the [TypeScript docs](/react/typescript#const-assert-abis-typed-data) for how to set up ABIs for maximum type inference and safety. + +::: code-group +```ts [index.ts] +import { simulateContract } from '@wagmi/core' +import { abi } from './abi' // [!code focus] +import { config } from './config' + +const result = await simulateContract(config, { + abi, // [!code focus] + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### accessList + +`AccessList | undefined` + +The access list. + +::: code-group +```ts [index.ts] +import { simulateContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + accessList: [{ // [!code focus] + address: '0x1', // [!code focus] + storageKeys: ['0x1'], // [!code focus] + }], // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### account + +`Address | Account | undefined` + +Account to use when signing data. Throws if account is not found on [`connector`](#connector). + +::: code-group +```ts [index.ts] +import { simulateContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + account: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### address + +`Address` + +The contract's address. + +::: code-group +```ts [index.ts] +import { simulateContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', // [!code focus] + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + + +### args + +`readonly unknown[] | undefined` + +- Arguments to pass when calling the contract. +- Inferred from [`abi`](#abi) and [`functionName`](#functionname). + +::: code-group +```ts [index.ts] +import { simulateContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ // [!code focus] + '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', // [!code focus] + 123n, // [!code focus] + ], // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### blockNumber + +`bigint | undefined` + +Block number to simulate against. + +::: code-group +```ts [index.ts] +import { simulateContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + blockNumber: 17829139n, // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to simulate against. + +::: code-group +```ts [index.ts] +import { simulateContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + blockTag: 'safe', // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +Chain ID to validate against before sending transaction. + +::: code-group +```ts [index.ts] +import { simulateContract } from '@wagmi/core' +import { mainnet } from 'wagmi/chains' // [!code focus] +import { abi } from './abi' +import { config } from './config' + +const result = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + chainId: mainnet.id, // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +[Connector](/core/api/connectors) to simulate transaction with. + +::: code-group +```ts [index.ts] +import { getAccount, simulateContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const { connector } = getAccount(config) +const result = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + connector, // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### dataSuffix + +`` `0x${string}` | undefined `` + +Data to append to the end of the calldata. Useful for adding a ["domain" tag](https://opensea.notion.site/opensea/Seaport-Order-Attributions-ec2d69bf455041a5baa490941aad307f). + +::: code-group +```ts [index.ts] +import { simulateContract } from '@wagmi/core' +import { parseGwei } from 'viem' +import { abi } from './abi' +import { config } from './config' + +const result = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + dataSuffix: '0xdeadbeef', // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### functionName + +`string` + +- Function to call on the contract. +- Inferred from [`abi`](#abi). + +::: code-group +```ts [index.ts] +import { simulateContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'approve', // [!code focus] + args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', 123n] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### gas + +`bigint | undefined` + +Gas provided for transaction execution. + +::: code-group +```ts [index.ts] +import { simulateContract } from '@wagmi/core' +import { parseGwei } from 'viem' +import { abi } from './abi' +import { config } from './config' + +const result = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + gas: parseGwei('20'), // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### gasPrice + +`bigint | undefined` + +The price in wei to pay per gas. Only applies to [Legacy Transactions](https://viem.sh/docs/glossary/terms.html#legacy-transaction). + +::: code-group +```ts [index.ts] +import { simulateContract } from '@wagmi/core' +import { parseGwei } from 'viem' +import { abi } from './abi' +import { config } from './config' + +const result = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + gasPrice: parseGwei('20'), // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### maxFeePerGas + +`bigint | undefined` + +Total fee per gas in wei, inclusive of [`maxPriorityFeePerGas`](#maxPriorityFeePerGas). Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```ts [index.ts] +import { simulateContract } from '@wagmi/core' +import { parseGwei } from 'viem' +import { abi } from './abi' +import { config } from './config' + +const result = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + maxFeePerGas: parseGwei('20'), // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### maxPriorityFeePerGas + +`bigint | undefined` + +Max priority fee per gas in wei. Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```ts [index.ts] +import { simulateContract } from '@wagmi/core' +import { parseGwei } from 'viem' +import { abi } from './abi' +import { config } from './config' + +const result = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + maxFeePerGas: parseGwei('20'), + maxPriorityFeePerGas: parseGwei('2'), // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### nonce + +`number` + +Unique number identifying this transaction. + +::: code-group +```ts [index.ts] +import { simulateContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + nonce: 123, // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### type + +`'legacy' | 'eip1559' | 'eip2930' | undefined` + +Optional transaction request type to narrow parameters. + +::: code-group +```ts [index.ts] +import { simulateContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + type: 'eip1559', // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### value + +`bigint | undefined` + +Value in wei sent with this transaction. + +::: code-group +```ts [index.ts] +import { simulateContract } from '@wagmi/core' +import { parseEther } from 'viem' +import { abi } from './abi' +import { config } from './config' + +const result = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + value: parseEther('0.01'), // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type SimulateContractReturnType } from '@wagmi/core' +``` + +The simulation result and write request. + +### request + +Write request that includes [parameters](#parameters). + +### response + +`unknown` + +- Result of contract simulation. +- Inferred from [`abi`](#abi), [`functionName`](#functionname), and [`args`](#args). + +## Type Inference + +With [`abi`](#abi) setup correctly, TypeScript will infer the correct types for [`functionName`](#functionname), [`args`](#args), and [`value`](#value). See the Wagmi [TypeScript docs](/core/typescript) for more information. + +## Error + +```ts +import { type SimulateContractErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`simulateContract`](https://viem.sh/docs/contract/simulateContract.html) diff --git a/wagmi-project/site/core/api/actions/switchAccount.md b/wagmi-project/site/core/api/actions/switchAccount.md new file mode 100644 index 0000000000..8d0f629c13 --- /dev/null +++ b/wagmi-project/site/core/api/actions/switchAccount.md @@ -0,0 +1,81 @@ + + +# switchAccount + +Action for switching the current account. + +## Import + +```ts +import { switchAccount } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { getConnections, switchAccount } from '@wagmi/core' +import { config } from './config' + +const connections = getConnections(config) +const result = await switchAccount(config, { + connector: connections[0]?.connector, +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type SwitchAccountParameters } from '@wagmi/core' +``` + +### connector + +`Connector` + +[Connector](/core/api/connectors) to switch to. + +::: code-group +```ts [index.ts] +import { getConnections, switchAccount } from '@wagmi/core' +import { config } from './config' + +const connections = getConnections(config) +const result = await switchAccount(config, { + connector: connections[0]?.connector, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type SwitchAccountReturnType } from '@wagmi/core' +``` + +### accounts + +`readonly [Address, ...Address[]]` + +Connected accounts from connector. + +### chainId + +`number` + +Connected chain ID from connector. + +## Error + +```ts +import { type SwitchAccountErrorType } from '@wagmi/core' +``` + + diff --git a/wagmi-project/site/core/api/actions/switchChain.md b/wagmi-project/site/core/api/actions/switchChain.md new file mode 100644 index 0000000000..c741e801c8 --- /dev/null +++ b/wagmi-project/site/core/api/actions/switchChain.md @@ -0,0 +1,122 @@ + + +# switchChain + +Action for switching the target chain for a connector or the Wagmi [`Config`](/core/api/createConfig#config). + +## Import + +```ts +import { switchChain } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { switchChain } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +await switchChain(config, { chainId: mainnet.id }) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +::: tip +When connected, `switchChain` will switch the target chain for the connector. When not connected, `switchChain` will switch the target chain for the Wagmi [`Config`](/core/api/createConfig#config). +::: + +## Parameters + +```ts +import { type SwitchChainParameters } from '@wagmi/core' +``` + +### addEthereumChainParameter + +`{ chainName: string; nativeCurrency?: { name: string; symbol: string; decimals: number } | undefined; rpcUrls: readonly string[]; blockExplorerUrls?: string[] | undefined; iconUrls?: string[] | undefined } | undefined` + +[EIP-3085 parameters](https://eips.ethereum.org/EIPS/eip-3085) to use when adding chain to connector (when supported). + +::: code-group +```ts [index.ts] +import { switchChain } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const result = await switchChain(config, { + addEthereumChainParameter: { // [!code focus] + iconUrls: ['https://example.com/icon.png'], // [!code focus] + }, // [!code focus] + chainId: mainnet.id, +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to switch to. + +::: code-group +```ts [index.ts] +import { switchChain } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const result = await switchChain(config, { + chainId: mainnet.id, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### connector + +`Connector` + +[Connector](/core/api/connectors) to switch chain with. + +::: code-group +```ts [index.ts] +import { getConnections, switchAccount } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const connections = getConnections(config) +const result = await switchChain(config, { + chainId: mainnet.id, + connector: connections[0]?.connector, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type SwitchChainReturnType } from '@wagmi/core' +``` + +`Chain` + +Chain that was switched to. + +## Error + +```ts +import { type SwitchChainErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`switchChain`](https://viem.sh/docs/actions/wallet/switchChain.html) when connected. diff --git a/wagmi-project/site/core/api/actions/verifyMessage.md b/wagmi-project/site/core/api/actions/verifyMessage.md new file mode 100644 index 0000000000..93d46992b9 --- /dev/null +++ b/wagmi-project/site/core/api/actions/verifyMessage.md @@ -0,0 +1,200 @@ + + +# verifyMessage + +Action for verify that a message was signed by the provided address. It supports verifying messages that were signed by either a Smart Contract Account or Externally Owned Account. + +## Import + +```ts +import { verifyMessage } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { verifyMessage } from '@wagmi/core' +import { config } from './config' + +await verifyMessage(config, { + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + message: 'hello world', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type VerifyMessageParameters } from '@wagmi/core' +``` + +### address + +`Address` + +The Ethereum address that signed the original message. + +::: code-group +```ts [index.ts] +import { verifyMessage } from '@wagmi/core' +import { config } from './config' + +await verifyMessage(config, { + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', // [!code focus] + message: 'hello world', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### message + +`string | { raw: Hex | ByteArray }` + +The message to be verified. + +By default, wagmi verifies the UTF-8 representation of the message. + +::: code-group +```ts [index.ts] +import { getAccount, verifyMessage } from '@wagmi/core' +import { config } from './config' + +await verifyMessage(config, { + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + message: 'hello world', // [!code focus] + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +::: tip +By default, viem signs the UTF-8 representation of the message. To sign the data representation of the message, you can use the `raw` attribute. + +```ts +import { verifyMessage } from '@wagmi/core' +import { config } from './config' + +await verifyMessage(config, { + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + message: { raw: '0x68656c6c6f20776f726c64' } // [!code focus] + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', +}) +``` +::: + +### signature + +`Hex | ByteArray ` + +The signature that was generated by signing the message with the address's signer. + +::: code-group +```ts [index.ts] +import { verifyMessage } from '@wagmi/core' +import { config } from './config' + +await verifyMessage(config, { + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + message: 'hello world', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +Only used when verifying a message that was signed by a Smart Contract Account. The ID of chain to check if the contract was already deployed. + +::: code-group +```ts [index.ts] +import { verifyMessage } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +await verifyMessage(config, { + chainId: mainnet.id, // [!code focus] + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + message: 'hello world', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockNumber + +`bigint | undefined` + +Only used when verifying a message that was signed by a Smart Contract Account. The block number to check if the contract was already deployed. + +::: code-group +```ts [index.ts] +import { verifyMessage } from '@wagmi/core' +import { config } from './config' + +await verifyMessage(config, { + blockNumber: 12345678n, // [!code focus] + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + message: 'hello world', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Only used when verifying a message that was signed by a Smart Contract Account. The block tag to check if the contract was already deployed. + +::: code-group +```ts [index.ts] +import { verifyMessage } from '@wagmi/core' +import { config } from './config' + +await verifyMessage(config, { + blockTag: 'latest', // [!code focus] + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + message: 'hello world', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type VerifyMessageReturnType } from '@wagmi/core' +``` + +`boolean` + +Whether the signed message is valid for the given address. + +## Error + +```ts +import { type VerifyMessageErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`verifyMessage`](https://viem.sh/docs/actions/public/verifyMessage.html) diff --git a/wagmi-project/site/core/api/actions/verifyTypedData.md b/wagmi-project/site/core/api/actions/verifyTypedData.md new file mode 100644 index 0000000000..e9afa17ad4 --- /dev/null +++ b/wagmi-project/site/core/api/actions/verifyTypedData.md @@ -0,0 +1,595 @@ + + +# verifyTypedData + +Action for verify that a typed data was signed by the provided address. It supports verifying typed data that were signed by either a Smart Contract Account or Externally Owned Account. + +## Import + +```ts +import { verifyTypedData } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { verifyTypedData } from '@wagmi/core' +import { domain, types } from './data' +import { config } from './config' + +const valid = await verifyTypedData(config, { + domain, + types, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', +}) +// true +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const + +// The named list of all type definitions +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type VerifyTypedDataParameters } from '@wagmi/core' +``` + +### address + +`Address` + +The Ethereum address that signed the original typed data. + +::: code-group +```ts [index.ts] +import { verifyTypedData } from '@wagmi/core' +import { domain, types } from './data' +import { config } from './config' + +const valid = await verifyTypedData(config, { + domain, + types, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', // [!code focus] + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', +}) +// true +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const + +// The named list of all type definitions +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### domain + +`TypedDataDomain` + +The typed data domain. + +::: code-group +```ts [index.ts] +import { verifyTypedData } from '@wagmi/core' +import { types } from './data' +import { config } from './config' + +const valid = await verifyTypedData(config, { + domain: { // [!code focus:6] + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', + }, + types, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', +}) +// true +``` +```ts [data.ts] +// The named list of all type definitions +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### types + +The type definitions for the typed data. + +::: code-group +```ts [index.ts] +import { verifyTypedData } from '@wagmi/core' +import { domain } from './data' +import { config } from './config' + +const valid = await verifyTypedData(config, { + domain, + types: { // [!code focus:11] + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', +}) +// true +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### primaryType + +`string` + +The primary `type` to extract from types and use in `value`. + +::: code-group +```ts [index.ts] +import { verifyTypedData } from '@wagmi/core' +import { domain } from './data' +import { config } from './config' + +const valid = await verifyTypedData(config, { + domain, + types: { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ // [!code focus:5] + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + }, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', // [!code focus] + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', +}) +// true +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### message + +Type inferred from `types` & `primaryType`. + +The message to be verified. + +::: code-group +```ts [index.ts] +import { verifyTypedData } from '@wagmi/core' +import { domain, types } from './data' +import { config } from './config' + +const valid = await verifyTypedData(config, { + domain, + types, + message: { // [!code focus:11] + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', +}) +// true +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const + +// The named list of all type definitions +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### signature + +`Hex | ByteArray` + +The signature that was generated by signing the typed data with the address's signer. + +::: code-group +```ts [index.ts] +import { verifyTypedData } from '@wagmi/core' +import { domain, types } from './data' +import { config } from './config' + +const valid = await verifyTypedData(config, { + domain, + types, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', // [!code focus] +}) +// true +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const + +// The named list of all type definitions +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +Only used when verifying a typed data that was signed by a Smart Contract Account. The ID of chain to check if the contract was already deployed. + +::: code-group +```ts [index.ts] +import { verifyTypedData } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { domain, types } from './data' +import { config } from './config' + +const valid = await verifyTypedData(config, { + chainId: mainnet.id, // [!code focus] + domain, + types, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', +}) +// true +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const + +// The named list of all type definitions +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockNumber + +`bigint | undefined` + +Only used when verifying a typed data that was signed by a Smart Contract Account. The block number to check if the contract was already deployed. + +::: code-group +```ts [index.ts] +import { verifyTypedData } from '@wagmi/core' +import { domain, types } from './data' +import { config } from './config' + +const valid = await verifyTypedData(config, { + blockNumber: 12345678n, // [!code focus] + domain, + types, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', +}) +// true +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const + +// The named list of all type definitions +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Only used when verifying a typed data that was signed by a Smart Contract Account. The block number to check if the contract was already deployed. + +::: code-group +```ts [index.ts] +import { verifyTypedData } from '@wagmi/core' +import { domain, types } from './data' +import { config } from './config' + +const valid = await verifyTypedData(config, { + blockTag: 'latest', // [!code focus] + domain, + types, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', +}) +// true +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const + +// The named list of all type definitions +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type VerifyTypedDataReturnType } from '@wagmi/core' +``` + +`boolean` + +Whether the signed message is valid for the given address. + +## Type Inference + +With [`types`](#types) setup correctly, TypeScript will infer the correct types for [`domain`](#domain), [`message`](#message), and [`primaryType`](#primarytype). See the Wagmi [TypeScript docs](/core/typescript) for more information. + +## Error + +```ts +import { type VerifyTypedDataErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`verifyTypedData`](https://viem.sh/docs/actions/public/verifyTypedData.html) diff --git a/wagmi-project/site/core/api/actions/waitForCallsStatus.md b/wagmi-project/site/core/api/actions/waitForCallsStatus.md new file mode 100644 index 0000000000..8261801046 --- /dev/null +++ b/wagmi-project/site/core/api/actions/waitForCallsStatus.md @@ -0,0 +1,143 @@ + + +# waitForCallsStatus + +Waits for a call bundle to be confirmed & included on a block before returning the status & receipts. + + + +## Import + +```ts +import { waitForCallsStatus } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { parseEther } from 'viem' +import { sendCalls, waitForCallsStatus } from '@wagmi/core' +import { config } from './config' + +const id = await sendCalls(config, { + calls: [{ + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1') + }] +}) + +const { status, receipts } = await waitForCallsStatus(config, { // [!code focus] + id, // [!code focus] +}) // [!code focus] +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type WaitForCallsStatusParameters } from '@wagmi/core' +``` + +### connector + +`Connector | undefined` + +Connector to get call statuses with. + +::: code-group +```ts [index.ts] +import { getConnections, waitForCallsStatus } from '@wagmi/core' +import { config } from './config' + +const connections = getConnections(config) +const status = await waitForCallsStatus(config, { + connector: connections[0]?.connector, // [!code focus] + id: '0x1234567890abcdef', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### id + +`string` + +Identifier of the call batch. + +::: code-group +```ts [index.ts] +import { waitForCallsStatus } from '@wagmi/core' +import { config } from './config' + +const status = await waitForCallsStatus(config, { + id: '0x1234567890abcdef', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### pollingInterval + +`number` + +Polling interval in milliseconds. + +::: code-group +```ts [index.ts] +import { waitForCallsStatus } from '@wagmi/core' +import { config } from './config' + +const status = await waitForCallsStatus(config, { + id: '0x1234567890abcdef', + pollingInterval: 1_000, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### timeout + +`number` + +Timeout in milliseconds before `waitForCallsStatus` stops polling. + +::: code-group +```ts [index.ts] +import { waitForCallsStatus } from '@wagmi/core' +import { config } from './config' + +const status = await waitForCallsStatus(config, { + id: '0x1234567890abcdef', + timeout: 10_000, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type WaitForCallsStatusReturnType } from '@wagmi/core' +``` + +`{ status: 'PENDING' | 'CONFIRMED', receipts: TransactionReceipt[] }` + +The status and receipts of the call batch. + +## Error + +```ts +import { type WaitForCallsStatusErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`waitForCallsStatus`](https://viem.sh/experimental/eip5792/waitForCallsStatus) diff --git a/wagmi-project/site/core/api/actions/waitForTransactionReceipt.md b/wagmi-project/site/core/api/actions/waitForTransactionReceipt.md new file mode 100644 index 0000000000..853189055d --- /dev/null +++ b/wagmi-project/site/core/api/actions/waitForTransactionReceipt.md @@ -0,0 +1,155 @@ + + +# waitForTransactionReceipt + +Action that waits for the transaction to be included on a block, and then returns the transaction receipt. If the transaction reverts, then the action will throw an error. Replacement detection (e.g. sped up transactions) is also supported. + +## Import + +```ts +import { waitForTransactionReceipt } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { waitForTransactionReceipt } from '@wagmi/core' +import { config } from './config' + +const transactionReceipt = waitForTransactionReceipt(config, { + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type WaitForTransactionReceiptParameters } from '@wagmi/core' +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { waitForTransactionReceipt } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const transactionReceipt = await waitForTransactionReceipt(config, { + chainId: mainnet.id, // [!code focus] + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### confirmations + +`number | undefined` + +The number of confirmations (blocks that have passed) to wait before resolving. + +::: code-group +```ts [index.ts] +import { waitForTransactionReceipt } from '@wagmi/core' +import { config } from './config' + +const transactionReceipt = await waitForTransactionReceipt(config, { + confirmations: 2, // [!code focus] + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### onReplaced + +` +(({ reason: 'replaced' | 'repriced' | 'cancelled'; replacedTransaction: Transaction; transaction: Transaction; transactionReceipt: TransactionReceipt }) => void) | undefined +` + +Optional callback to emit if the transaction has been replaced. + +::: code-group +```ts [index.ts] +import { waitForTransactionReceipt } from '@wagmi/core' +import { config } from './config' + +const transactionReceipt = await waitForTransactionReceipt(config, { + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', + onReplaced: replacement => console.log(replacement), // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### hash + +`` `0x${string}` `` + +The transaction hash to wait for. + +::: code-group +```ts [index.ts] +import { waitForTransactionReceipt } from '@wagmi/core' +import { config } from './config' + +const transactionReceipt = await waitForTransactionReceipt(config, { + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### pollingInterval + +`number | undefined` + +- Polling frequency (in milliseconds). +- Defaults to the [Config's `pollingInterval` config](/core/api/createConfig#pollinginterval). + +::: code-group +```ts [index.ts] +import { waitForTransactionReceipt } from '@wagmi/core' +import { config } from './config' + +const transactionReceipt = await waitForTransactionReceipt(config, { + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', + pollingInterval: 1_000, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type WaitForTransactionReceiptReturnType } from '@wagmi/core' +``` + +[`TransactionReceipt`](https://viem.sh/docs/glossary/types.html#transactionreceipt) + +The transaction receipt. + +## Error + +```ts +import { type WaitForTransactionReceiptErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`waitForTransactionReceipt`](https://viem.sh/docs/actions/public/waitForTransactionReceipt.html) diff --git a/wagmi-project/site/core/api/actions/watchAccount.md b/wagmi-project/site/core/api/actions/watchAccount.md new file mode 100644 index 0000000000..a71ca4d161 --- /dev/null +++ b/wagmi-project/site/core/api/actions/watchAccount.md @@ -0,0 +1,61 @@ +# watchAccount + +Subscribe to account changes. + +## Import + +```ts +import { watchAccount } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { watchAccount } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchAccount(config, { + onChange(data) { + console.log('Account changed!', data) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type WatchAccountParameters } from '@wagmi/core' +``` + +### onChange + +`onChange(account: GetAccountReturnType, prevAccount: GetAccountReturnType): void` + +Callback function called when account changes. + +::: code-group +```ts [index.ts] +import { watchAccount } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchAccount(config, { + onChange(account) { // [!code focus:3] + console.log('Account changed!', account) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type WatchAccountReturnType } from '@wagmi/core' +``` + +Function for cleaning up watcher. \ No newline at end of file diff --git a/wagmi-project/site/core/api/actions/watchAsset.md b/wagmi-project/site/core/api/actions/watchAsset.md new file mode 100644 index 0000000000..394dadd7ae --- /dev/null +++ b/wagmi-project/site/core/api/actions/watchAsset.md @@ -0,0 +1,134 @@ + + +# watchAsset + +Action for requesting user tracks the token in their wallet. Returns a boolean indicating if the token was successfully added. + +## Import + +```ts +import { watchAsset } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { watchAsset } from '@wagmi/core' +import { config } from './config' + +await watchAsset(config, { + type: 'ERC20', + options: { + address: '0x0000000000000000000000000000000000000000', + symbol: 'WAGMI', + decimals: 18, + }, +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type WatchAssetParameters } from '@wagmi/core' +``` + +### connector + +`Connector | undefined` + +[Connector](/core/api/connectors) to sign message with. + +::: code-group +```ts [index.ts] +import { getAccount, watchAsset } from '@wagmi/core' +import { config } from './config' + +const { connector } = getAccount(config) +const result = await watchAsset(config, { + connector, // [!code focus] + options: { + address: '0x0000000000000000000000000000000000000000', + symbol: 'WAGMI', + decimals: 18, + }, + type: 'ERC20', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### options + +`{ address: string; symbol: string; decimals: number; image?: string | undefined; }` + +Asset options. + +::: code-group +```ts [index.ts] +import { watchAsset } from '@wagmi/core' +import { config } from './config' + +const result = await watchAsset(config, { + options: { // [!code focus] + address: '0x0000000000000000000000000000000000000000', // [!code focus] + symbol: 'WAGMI', // [!code focus] + decimals: 18, // [!code focus] + }, // [!code focus] + type: 'ERC20', +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### type + +`'ERC20'` + +Type of asset. + +::: code-group +```ts [index.ts] +import { watchAsset } from '@wagmi/core' +import { config } from './config' + +const result = await watchAsset(config, { + options: { + address: '0x0000000000000000000000000000000000000000', + symbol: 'WAGMI', + decimals: 18, + }, + type: 'ERC20', // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type WatchAssetReturnType } from '@wagmi/core' +``` + +`boolean` + +Returns a boolean indicating if the token was successfully added. + +## Error + +```ts +import { type WatchAssetErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`watchAsset`](https://viem.sh/docs/actions/wallet/watchAsset.html) + diff --git a/wagmi-project/site/core/api/actions/watchBlockNumber.md b/wagmi-project/site/core/api/actions/watchBlockNumber.md new file mode 100644 index 0000000000..098fd6613e --- /dev/null +++ b/wagmi-project/site/core/api/actions/watchBlockNumber.md @@ -0,0 +1,226 @@ +# watchBlockNumber + +Action that watches for block number changes. + +## Import + +```ts +import { watchBlockNumber } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { watchBlockNumber } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchBlockNumber(config, { + onBlockNumber(blockNumber) { + console.log('Block number changed!', blockNumber) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type WatchBlockNumberParameters } from '@wagmi/core' +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { watchBlockNumber } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const unwatch = watchBlockNumber(config, { + chainId: mainnet.id, // [!code focus] + onBlockNumber(blockNumber) { + console.log('Block number changed!', blockNumber) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### emitOnBegin + +`boolean | undefined` + +Whether or not to emit the latest block number to the callback when the subscription opens. + +::: code-group +```ts [index.ts] +import { watchBlockNumber } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchBlockNumber(config, { + emitOnBegin: true, // [!code focus] + onBlockNumber(blockNumber) { + console.log('Block number changed!', blockNumber) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### emitMissed + +`boolean | undefined` + +Whether or not to emit the missed block numbers to the callback. + +::: code-group +```ts [index.ts] +import { watchBlockNumber } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchBlockNumber(config, { + emitMissed: true, // [!code focus] + onBlockNumber(blockNumber) { + console.log('Block number changed!', blockNumber) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + + +### onBlockNumber + +`(blockNumber: bigint, prevBlockNumber: bigint | undefined) => void` + +Callback for when block number changes. + +::: code-group +```ts [index.ts] +import { watchBlockNumber } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchBlockNumber(config, { + onBlockNumber(blockNumber) { // [!code focus] + console.log('Block number changed!', blockNumber) // [!code focus] + }, // [!code focus] +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### onError + +`((error: Error) => void) | undefined` + +Error thrown from getting the block number. + +::: code-group +```ts [index.ts] +import { watchBlockNumber } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchBlockNumber(config, { + onBlockNumber(blockNumber) { + console.log('Block number changed!', blockNumber) + }, + onError(error) { // [!code focus] + console.error('Block number error', error) // [!code focus] + }, // [!code focus] +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### poll + +`boolean | undefined` + +- Whether or not to use a polling mechanism to check for new blocks instead of a WebSocket subscription. +- Defaults to `false` for WebSocket Clients, and `true` for non-WebSocket Clients. + +::: code-group +```ts [index.ts] +import { watchBlockNumber } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchBlockNumber(config, { + onBlockNumber(blockNumber) { + console.log('Block number changed!', blockNumber) + }, + poll: true, // [!code focus] +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### pollingInterval + +`number | undefined` + +- Polling frequency (in milliseconds). +- Defaults to the [Config's `pollingInterval` config](/core/api/createConfig#pollinginterval). + +::: code-group +```ts [index.ts] +import { watchBlockNumber } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchBlockNumber(config, { + onBlockNumber(blockNumber) { + console.log('Block number changed!', blockNumber) + }, + pollingInterval: 1_000, // [!code focus] +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### syncConnectedChain + +`boolean | undefined` + +- Set up subscriber for connected chain changes. +- Defaults to [`Config['syncConnectedChain']`](/core/api/createConfig#syncconnectedchain). + +::: code-group +```ts [index.ts] +import { watchBlockNumber } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchBlockNumber(config, { + onBlockNumber(blockNumber) { + console.log('Block number changed!', blockNumber) + }, + syncConnectedChain: false, // [!code focus] +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type WatchBlockNumberReturnType } from '@wagmi/core' +``` + +Function for cleaning up watcher. + +## Viem + +- [`watchBlockNumber`](https://viem.sh/docs/actions/public/watchBlockNumber.html) diff --git a/wagmi-project/site/core/api/actions/watchBlocks.md b/wagmi-project/site/core/api/actions/watchBlocks.md new file mode 100644 index 0000000000..892ef0005f --- /dev/null +++ b/wagmi-project/site/core/api/actions/watchBlocks.md @@ -0,0 +1,249 @@ +# watchBlocks + +Action that watches for block changes. + +## Import + +```ts +import { watchBlocks } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { watchBlocks } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchBlocks(config, { + onBlock(block) { + console.log('Block changed!', block) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type WatchBlocksParameters } from '@wagmi/core' +``` + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized'` + +Watch for new blocks on a given tag. Defaults to `'latest'`. + +::: code-group +```ts [index.ts] +import { watchBlocks } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchBlocks(config, { + blockTag: 'pending', // [!code focus] + onBlock(block) { + console.log('Block changed!', block) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { watchBlocks } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const unwatch = watchBlocks(config, { + chainId: mainnet.id, // [!code focus] + onBlock(block) { + console.log('Block changed!', block) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### emitMissed + +`boolean` + +Whether or not to emit missed blocks to the callback. Defaults to `false`. + +Missed blocks may occur in instances where internet connection is lost, or the block time is lesser than the polling interval of the client. + +::: code-group +```ts [index.ts] +import { watchBlocks } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchBlocks(config, { + emitMissed: true, // [!code focus] + onBlock(block) { + console.log('Block changed!', block) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### emitOnBegin + +`boolean` + +Whether or not to emit the block to the callback when the subscription opens. Defaults to `false`. + +::: code-group +```ts [index.ts] +import { watchBlocks } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchBlocks(config, { + emitOnBegin: true, // [!code focus] + onBlock(block) { + console.log('Block changed!', block) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### onBlock + +`(block: Block, prevblock: Block | undefined) => void` + +Callback for when block changes. + +::: code-group +```ts [index.ts] +import { watchBlocks } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchBlocks(config, { + onBlock(block) { // [!code focus] + console.log('Block changed!', block) // [!code focus] + }, // [!code focus] +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### onError + +`((error: Error) => void) | undefined` + +Error thrown from getting the block. + +::: code-group +```ts [index.ts] +import { watchBlocks } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchBlocks(config, { + onBlock(block) { + console.log('Block changed!', block) + }, + onError(error) { // [!code focus] + console.error('Block error', error) // [!code focus] + }, // [!code focus] +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### poll + +`boolean | undefined` + +- Whether or not to use a polling mechanism to check for new blocks instead of a WebSocket subscription. +- Defaults to `false` for WebSocket Clients, and `true` for non-WebSocket Clients. + +::: code-group +```ts [index.ts] +import { watchBlocks } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchBlocks(config, { + poll: true, // [!code focus] + onBlock(block) { + console.log('Block changed!', block) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### pollingInterval + +`number | undefined` + +- Polling frequency (in milliseconds). +- Defaults to the [Config's `pollingInterval` config](/core/api/createConfig#pollinginterval). + +::: code-group +```ts [index.ts] +import { watchBlocks } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchBlocks(config, { + pollingInterval: 1_000, // [!code focus] + onBlock(block) { + console.log('Block changed!', block) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### syncConnectedChain + +`boolean | undefined` + +- Set up subscriber for connected chain changes. +- Defaults to [`Config['syncConnectedChain']`](/core/api/createConfig#syncconnectedchain). + +::: code-group +```ts [index.ts] +import { watchBlocks } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchBlocks(config, { + onBlock(block) { + console.log('Block changed!', block) + }, + syncConnectedChain: false, // [!code focus] +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type WatchBlocksReturnType } from '@wagmi/core' +``` + +Function for cleaning up watcher. + +## Viem + +- [`watchBlocks`](https://viem.sh/docs/actions/public/watchBlocks.html) diff --git a/wagmi-project/site/core/api/actions/watchChainId.md b/wagmi-project/site/core/api/actions/watchChainId.md new file mode 100644 index 0000000000..a003fd16dc --- /dev/null +++ b/wagmi-project/site/core/api/actions/watchChainId.md @@ -0,0 +1,61 @@ +# watchChainId + +Subscribe to chain ID changes. + +## Import + +```ts +import { watchChainId } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { watchChainId } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchChainId(config, { + onChange(chainId) { + console.log('Chain ID changed!', chainId) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type WatchChainIdParameters } from '@wagmi/core' +``` + +### onChange + +`onChange(chainId: GetChainIdReturnType, prevChainId: GetChainIdReturnType): void` + +Callback function called when chain ID changes. + +::: code-group +```ts [index.ts] +import { watchChainId } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchChainId(config, { + onChange(chainId) { // [!code focus:3] + console.log('Chain ID changed!', chainId) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type WatchChainIdReturnType } from '@wagmi/core' +``` + +Function for cleaning up watcher. \ No newline at end of file diff --git a/wagmi-project/site/core/api/actions/watchClient.md b/wagmi-project/site/core/api/actions/watchClient.md new file mode 100644 index 0000000000..aa3087c0d0 --- /dev/null +++ b/wagmi-project/site/core/api/actions/watchClient.md @@ -0,0 +1,61 @@ +# watchClient + +Subscribe to Client changes. + +## Import + +```ts +import { watchClient } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { watchClient } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchClient(config, { + onChange(client) { + console.log('Client changed!', client) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type WatchClientParameters } from '@wagmi/core' +``` + +### onChange + +`onChange(client: GetClientReturnType, prevClient: GetClientReturnType): void` + +Callback function called when Client changes. + +::: code-group +```ts [index.ts] +import { watchClient } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchClient(config, { + onChange(client) { // [!code focus:3] + console.log('Client changed!', client) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type WatchClientReturnType } from '@wagmi/core' +``` + +Function for cleaning up watcher. \ No newline at end of file diff --git a/wagmi-project/site/core/api/actions/watchConnections.md b/wagmi-project/site/core/api/actions/watchConnections.md new file mode 100644 index 0000000000..11cb0a617b --- /dev/null +++ b/wagmi-project/site/core/api/actions/watchConnections.md @@ -0,0 +1,61 @@ +# watchConnections + +Subscribe to connections changes. + +## Import + +```ts +import { watchConnections } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { watchConnections } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchConnections(config, { + onChange(data) { + console.log('Connections changed!', data) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type WatchConnectionsParameters } from '@wagmi/core' +``` + +### onChange + +`onChange(connections: GetConnectionsReturnType, prevConnections: GetConnectionsReturnType): void` + +Callback function called when connections changes. + +::: code-group +```ts [index.ts] +import { watchConnections } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchConnections(config, { + onChange(data) { // [!code focus:3] + console.log('Connections changed!', data) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type WatchConnectionsReturnType } from '@wagmi/core' +``` + +Function for cleaning up watcher. \ No newline at end of file diff --git a/wagmi-project/site/core/api/actions/watchConnectors.md b/wagmi-project/site/core/api/actions/watchConnectors.md new file mode 100644 index 0000000000..0b951a4584 --- /dev/null +++ b/wagmi-project/site/core/api/actions/watchConnectors.md @@ -0,0 +1,61 @@ +# watchConnectors + +Subscribe to connectors changes. + +## Import + +```ts +import { watchConnectors } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { watchConnectors } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchConnectors(config, { + onChange(connectors) { + console.log('Connectors changed!', connectors) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type WatchConnectorsParameters } from '@wagmi/core' +``` + +### onChange + +`onChange(connectors: GetConnectorsReturnType, prevConnectors: GetConnectorsReturnType): void` + +Callback function called when connectors changes. + +::: code-group +```ts [index.ts] +import { watchConnectors } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchConnectors(config, { + onChange(connectors) { // [!code focus:3] + console.log('Connectors changed!', connectors) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type WatchConnectorsReturnType } from '@wagmi/core' +``` + +Function for cleaning up watcher. \ No newline at end of file diff --git a/wagmi-project/site/core/api/actions/watchContractEvent.md b/wagmi-project/site/core/api/actions/watchContractEvent.md new file mode 100644 index 0000000000..91498f1784 --- /dev/null +++ b/wagmi-project/site/core/api/actions/watchContractEvent.md @@ -0,0 +1,376 @@ + + +# watchContractEvent + +Action that watches and returns emitted contract event logs. + +## Import + +```ts +import { watchContractEvent } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { watchContractEvent } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const unwatch = watchContractEvent(config, { + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + abi, + eventName: 'Transfer', + onLogs(logs) { + console.log('New logs!', logs) + }, +}) +unwatch() +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type WatchContractEventParameters } from '@wagmi/core' +``` + +### abi + +`Abi` + +The contract's ABI. Check out the [TypeScript docs](/react/typescript#const-assert-abis-typed-data) for how to set up ABIs for maximum type inference and safety. + +::: code-group +```ts [index.ts] +import { watchContractEvent } from '@wagmi/core' +import { abi } from './abi' // [!code focus] +import { config } from './config' + +const unwatch = watchContractEvent(config, { + abi, // [!code focus] + onLogs(logs) { + console.log('Logs changed!', logs) + }, +}) +unwatch() +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### address + +`Address | undefined` + +The contract's address. + +::: code-group +```ts [index.ts] +import { watchContractEvent } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const unwatch = watchContractEvent(config, { + address: '0x6b175474e89094c44da98b954eedeac495271d0f', // [!code focus] + abi, + onLogs(logs) { + console.log('Logs changed!', logs) + }, +}) +unwatch() +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### args + +`object | readonly unknown[] | undefined` + +- Arguments to pass when calling the contract. +- Inferred from [`abi`](#abi) and [`eventName`](#eventname). + +::: code-group +```ts [index.ts] +import { watchContractEvent } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const unwatch = watchContractEvent(config, { + abi, + args: { // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] + }, // [!code focus] + onLogs(logs) { + console.log('Logs changed!', logs) + }, +}) +unwatch() +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### batch + +`boolean | undefined` + +- Whether or not the events should be batched on each invocation. +- Defaults to `true`. + +::: code-group +```ts [index.ts] +import { watchContractEvent } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const unwatch = watchContractEvent(config, { + abi, + batch: false, // [!code focus] + onLogs(logs) { + console.log('Logs changed!', logs) + }, +}) +unwatch() +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { watchContractEvent } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { abi } from './abi' +import { config } from './config' + +const unwatch = watchContractEvent(config, { + abi, + chainId: mainnet.id, // [!code focus] + onLogs(logs) { + console.log('Logs changed!', logs) + }, +}) +unwatch() +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### eventName + +`string` + +- Event to listen for the contract. +- Inferred from [`abi`](#abi). + +::: code-group +```ts [index.ts] +import { watchContractEvent } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const unwatch = watchContractEvent(config, { + abi, + eventName: 'Approval', // [!code focus] + onLogs(logs) { + console.log('Logs changed!', logs) + }, +}) +unwatch() +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### onError + +`((error: Error) => void) | undefined` + +Error thrown from getting the block number. + +::: code-group +```ts [index.ts] +import { watchContractEvent } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const unwatch = watchContractEvent(config, { + abi, + onLogs(logs) { + console.log('Logs changed!', logs) + }, + onError(error) { // [!code focus] + console.error('Logs error', error) // [!code focus] + }, // [!code focus] +}) +unwatch() +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### onLogs + +`(logs: Log[], prevLogs: Log[] | undefined) => void` + +Callback for when logs changes. + +::: code-group +```ts [index.ts] +import { watchContractEvent } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const unwatch = watchContractEvent(config, { + abi, + onLogs(logs) { // [!code focus] + console.log('Logs changed!', logs) // [!code focus] + }, // [!code focus] +}) +unwatch() +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### poll + +`boolean | undefined` + +- Whether or not to use a polling mechanism to check for new blocks instead of a WebSocket subscription. +- Defaults to `false` for WebSocket Clients, and `true` for non-WebSocket Clients. + +::: code-group +```ts [index.ts] +import { watchContractEvent } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const unwatch = watchContractEvent(config, { + abi, + onLogs(logs) { + console.log('Logs changed!', logs) + }, + poll: true, // [!code focus] +}) +unwatch() +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### pollingInterval + +`number | undefined` + +- Polling frequency (in milliseconds). +- Defaults to the [Config's `pollingInterval` config](/core/api/createConfig#pollinginterval). + +::: code-group +```ts [index.ts] +import { watchContractEvent } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const unwatch = watchContractEvent(config, { + abi, + onLogs(logs) { + console.log('Logs changed!', logs) + }, + pollingInterval: 1_000, // [!code focus] +}) +unwatch() +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### strict + +`boolean | undefined` + +- Defaults to `false`. + +::: code-group +```ts [index.ts] +import { watchContractEvent } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const unwatch = watchContractEvent(config, { + abi, + onLogs(logs) { + console.log('Logs changed!', logs) + }, + strict: true, // [!code focus] +}) +unwatch() +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### syncConnectedChain + +`boolean | undefined` + +- Set up subscriber for connected chain changes. +- Defaults to [`Config['syncConnectedChain']`](/core/api/createConfig#syncconnectedchain). + +::: code-group +```ts [index.ts] +import { watchContractEvent } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const unwatch = watchContractEvent(config, { + abi, + onLogs(logs) { + console.log('Logs changed!', logs) + }, + syncConnectedChain: false, // [!code focus] +}) +unwatch() +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type WatchContractEventReturnType } from '@wagmi/core' +``` + +Function for cleaning up watcher. + +## Type Inference + +With [`abi`](#abi) setup correctly, TypeScript will infer the correct types for [`eventName`](#eventname), [`args`](#args), and [`onLogs`](#onlogs) parameters. See the Wagmi [TypeScript docs](/core/typescript) for more information. + +## Error + +```ts +import { type WatchContractEventError } from '@wagmi/core' +``` + + + +## Viem + +- [`watchContractEvent`](https://viem.sh/docs/contract/watchContractEvent.html) diff --git a/wagmi-project/site/core/api/actions/watchPendingTransactions.md b/wagmi-project/site/core/api/actions/watchPendingTransactions.md new file mode 100644 index 0000000000..fe0e5c3885 --- /dev/null +++ b/wagmi-project/site/core/api/actions/watchPendingTransactions.md @@ -0,0 +1,207 @@ + + +# watchPendingTransactions + +Action that watches and returns pending transaction hashes. + +## Import + +```ts +import { watchPendingTransactions } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { watchPendingTransactions } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchPendingTransactions(config, { + onTransactions(transactions) { + console.log('New transactions!', transactions) + }, +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type WatchPendingTransactionsParameters } from '@wagmi/core' +``` + +### batch + +`boolean | undefined` + +- Whether or not the transactions should be batched on each invocation. +- Defaults to `true`. + +::: code-group +```ts [index.ts] +import { watchPendingTransactions } from '@wagmi/core' + +const unwatch = watchPendingTransactions(config, { + batch: false, // [!code focus] + onTransactions(transactions) { + console.log('New transactions!', transactions) + }, +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```ts [index.ts] +import { watchPendingTransactions } from '@wagmi/core' +import { mainnet } from '@wagmi/core/chains' +import { config } from './config' + +const unwatch = watchPendingTransactions(config, { + chainId: mainnet.id, // [!code focus] + onTransactions(transactions) { + console.log('New transactions!', transactions) + }, +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### onError + +`((error: Error) => void) | undefined` + +Error thrown from watching pending transactions. + +::: code-group +```ts [index.ts] +import { watchPendingTransactions } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchPendingTransactions(config, { + onError(error) { // [!code focus] + console.log('Error', error) // [!code focus] + }, // [!code focus] + onTransactions(transactions) { + console.log('New transactions!', transactions) + }, +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### onTransactions + +`(transactions: Hash[], prevTransactions: Hash[] | undefined) => void` + +Callback when new incoming pending transactions are detected. + +::: code-group +```ts [index.ts] +import { watchPendingTransactions } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchPendingTransactions(config, { + onTransactions(transactions) { // [!code focus] + console.log('New transactions!', transactions) // [!code focus] + }, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### poll + +`boolean | undefined` + +- Whether or not to use a polling mechanism to check for new pending transactions instead of a WebSocket subscription. +- Defaults to `false` for WebSocket Clients, and `true` for non-WebSocket Clients. + +::: code-group +```ts [index.ts] +import { watchPendingTransactions } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchPendingTransactions(config, { + onTransactions(transactions) { + console.log('New transactions!', transactions) + }, + poll: false, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### pollingInterval + +`number | undefined` + +- Polling frequency (in milliseconds). +- Defaults to the [Config's `pollingInterval` config](/core/api/createConfig#pollinginterval). + +::: code-group +```ts [index.ts] +import { watchPendingTransactions } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchPendingTransactions(config, { + onTransactions(transactions) { + console.log('New transactions!', transactions) + }, + pollingInterval: 1_000, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### syncConnectedChain + +`boolean | undefined` + +- Set up subscriber for connected chain changes. +- Defaults to [`Config['syncConnectedChain']`](/core/api/createConfig#syncconnectedchain). + +::: code-group +```ts [index.ts] +import { watchPendingTransactions } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchPendingTransactions(config, { + onTransactions(transactions) { + console.log('New transactions!', transactions) + }, + syncConnectedChain: false, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type WatchPendingTransactionsReturnType } from '@wagmi/core' +``` + +Function to unsubscribe from pending transaction listener. + +## Error + +```ts +import { type WatchPendingTransactionsError } from '@wagmi/core' +``` + +## Viem + +- [`watchPendingTransactions`](https://viem.sh/docs/actions/public/watchPendingTransactions.html) diff --git a/wagmi-project/site/core/api/actions/watchPublicClient.md b/wagmi-project/site/core/api/actions/watchPublicClient.md new file mode 100644 index 0000000000..7363fc3deb --- /dev/null +++ b/wagmi-project/site/core/api/actions/watchPublicClient.md @@ -0,0 +1,61 @@ +# watchPublicClient + +Subscribe to Public Client changes. + +## Import + +```ts +import { watchPublicClient } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { watchPublicClient } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchPublicClient(config, { + onChange(client) { + console.log('Public Client changed!', client) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type WatchPublicClientParameters } from '@wagmi/core' +``` + +### onChange + +`onChange(client: GetPublicClientReturnType, prevClient: GetPublicClientReturnType): void` + +Callback function called when Public Client changes. + +::: code-group +```ts [index.ts] +import { watchPublicClient } from '@wagmi/core' +import { config } from './config' + +const unwatch = watchPublicClient(config, { + onChange(client) { // [!code focus:3] + console.log('Public Client changed!', client) + }, +}) +unwatch() +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type WatchPublicClientReturnType } from '@wagmi/core' +``` + +Function for cleaning up watcher. \ No newline at end of file diff --git a/wagmi-project/site/core/api/actions/writeContract.md b/wagmi-project/site/core/api/actions/writeContract.md new file mode 100644 index 0000000000..34000d9d32 --- /dev/null +++ b/wagmi-project/site/core/api/actions/writeContract.md @@ -0,0 +1,560 @@ + + +# writeContract + +Action for executing a write function on a contract. + +A "write" function on a Solidity contract modifies the state of the blockchain. These types of functions require gas to be executed, hence a transaction is broadcasted in order to change the state. + +## Import + +```ts +import { writeContract } from '@wagmi/core' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { writeContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await writeContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +::::tip Pairing with `simulateContract` + +Pairing [`simulateContract`](/core/api/actions/simulateContract) with `writeContract` allows you to validate if the transaction will succeed ahead of time. If the simulate succeeds, `writeContract` can execute the transaction. + +::: code-group +```ts [index.ts] +import { simulateContract, writeContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const { request } = await simulateContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], +}) +const hash = await writeContract(config, request) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: +:::: + + +## Parameters + +```ts +import { type WriteContractParameters } from '@wagmi/core' +``` + +### abi + +`Abi` + +The contract's ABI. Check out the [TypeScript docs](/react/typescript#const-assert-abis-typed-data) for how to set up ABIs for maximum type inference and safety. + +::: code-group +```ts [index.ts] +import { writeContract } from '@wagmi/core' +import { abi } from './abi' // [!code focus] +import { config } from './config' + +const result = await writeContract(config, { + abi, // [!code focus] + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### accessList + +`AccessList | undefined` + +The access list. + +::: code-group +```ts [index.ts] +import { writeContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await writeContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + accessList: [{ // [!code focus] + address: '0x1', // [!code focus] + storageKeys: ['0x1'], // [!code focus] + }], // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### account + +`Address | Account | undefined` + +Account to use when signing data. Throws if account is not found on [`connector`](#connector). + +::: code-group +```ts [index.ts] +import { writeContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await writeContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + account: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### address + +`Address` + +The contract's address. + +::: code-group +```ts [index.ts] +import { writeContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await writeContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', // [!code focus] + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + + +### args + +`readonly unknown[] | undefined` + +- Arguments to pass when calling the contract. +- Inferred from [`abi`](#abi) and [`functionName`](#functionname). + +::: code-group +```ts [index.ts] +import { writeContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await writeContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ // [!code focus] + '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', // [!code focus] + 123n, // [!code focus] + ] // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +Chain ID to validate against before sending transaction. + +::: code-group +```ts [index.ts] +import { writeContract } from '@wagmi/core' +import { mainnet } from 'wagmi/chains' // [!code focus] +import { abi } from './abi' +import { config } from './config' + +const result = await writeContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + chainId: mainnet.id, // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +[Connector](/core/api/connectors) to sign data with. + +::: code-group +```ts [index.ts] +import { getAccount, writeContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const { connector } = getAccount(config) +const result = await writeContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + connector, // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### dataSuffix + +`` `0x${string}` | undefined `` + +Data to append to the end of the calldata. Useful for adding a ["domain" tag](https://opensea.notion.site/opensea/Seaport-Order-Attributions-ec2d69bf455041a5baa490941aad307f). + +::: code-group +```ts [index.ts] +import { writeContract } from '@wagmi/core' +import { parseGwei } from 'viem' +import { abi } from './abi' +import { config } from './config' + +const result = await writeContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + dataSuffix: '0xdeadbeef', // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### functionName + +`string` + +- Function to call on the contract. +- Inferred from [`abi`](#abi). + +::: code-group +```ts [index.ts] +import { writeContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await writeContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'approve', // [!code focus] + args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', 123n] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + + +### gas + +`bigint | undefined` + +Gas provided for transaction execution. + +::: code-group +```ts [index.ts] +import { writeContract } from '@wagmi/core' +import { parseGwei } from 'viem' +import { abi } from './abi' +import { config } from './config' + +const result = await writeContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + gas: parseGwei('20'), // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### gasPrice + +`bigint | undefined` + +The price in wei to pay per gas. Only applies to [Legacy Transactions](https://viem.sh/docs/glossary/terms.html#legacy-transaction). + +::: code-group +```ts [index.ts] +import { writeContract } from '@wagmi/core' +import { parseGwei } from 'viem' +import { abi } from './abi' +import { config } from './config' + +const result = await writeContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + gasPrice: parseGwei('20'), // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### maxFeePerGas + +`bigint | undefined` + +Total fee per gas in wei, inclusive of [`maxPriorityFeePerGas`](#maxPriorityFeePerGas). Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```ts [index.ts] +import { writeContract } from '@wagmi/core' +import { parseGwei } from 'viem' +import { abi } from './abi' +import { config } from './config' + +const result = await writeContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + maxFeePerGas: parseGwei('20'), // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### maxPriorityFeePerGas + +`bigint | undefined` + +Max priority fee per gas in wei. Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```ts [index.ts] +import { writeContract } from '@wagmi/core' +import { parseGwei } from 'viem' +import { abi } from './abi' +import { config } from './config' + +const result = await writeContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + maxFeePerGas: parseGwei('20'), + maxPriorityFeePerGas: parseGwei('2'), // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +--- + +### nonce + +`number` + +Unique number identifying this transaction. + +::: code-group +```ts [index.ts] +import { writeContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await writeContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + nonce: 123, // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### type + +`'legacy' | 'eip1559' | 'eip2930' | undefined` + +Optional transaction request type to narrow parameters. + +::: code-group +```ts [index.ts] +import { writeContract } from '@wagmi/core' +import { abi } from './abi' +import { config } from './config' + +const result = await writeContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + type: 'eip1559', // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +### value + +`bigint | undefined` + +Value in wei sent with this transaction. + +::: code-group +```ts [index.ts] +import { writeContract } from '@wagmi/core' +import { parseEther } from 'viem' +import { abi } from './abi' +import { config } from './config' + +const result = await writeContract(config, { + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + value: parseEther('0.01'), // [!code focus] +}) +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type WriteContractReturnType } from '@wagmi/core' +``` + +[`Hash`](https://viem.sh/docs/glossary/types.html#hash) + +The transaction hash. + +## Type Inference + +With [`abi`](#abi) setup correctly, TypeScript will infer the correct types for [`functionName`](#functionname), [`args`](#args), and [`value`](#value). See the Wagmi [TypeScript docs](/core/typescript) for more information. + +## Error + +```ts +import { type WriteContractErrorType } from '@wagmi/core' +``` + + + +## Viem + +- [`writeContract`](https://viem.sh/docs/contract/writeContract.html) diff --git a/wagmi-project/site/core/api/actions/writeContracts.md b/wagmi-project/site/core/api/actions/writeContracts.md new file mode 100644 index 0000000000..a6afe42ff6 --- /dev/null +++ b/wagmi-project/site/core/api/actions/writeContracts.md @@ -0,0 +1,317 @@ + + +# writeContracts + +Action that requests for the wallet to sign and broadcast a batch of write contract calls (transactions) to the network. + +[Read more.](https://github.com/ethereum/EIPs/blob/815028dc634463e1716fc5ce44c019a6040f0bef/EIPS/eip-5792.md#wallet_sendcalls) + + + +## Import + +```ts +import { writeContracts } from '@wagmi/core/experimental' +``` + +## Usage + +::: code-group +```ts [index.ts] +import { parseAbi } from 'viem' +import { writeContracts } from '@wagmi/core/experimental' +import { config } from './config' + +const abi = parseAbi([ + 'function approve(address, uint256) returns (bool)', + 'function transferFrom(address, address, uint256) returns (bool)', +]) + +const id = await writeContracts(config, { + contracts: [ + { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi, + functionName: 'approve', + args: [ + '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + 100n + ], + }, + { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi, + functionName: 'transferFrom', + args: [ + '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + '0x0000000000000000000000000000000000000000', + 100n + ], + }, + ], +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type WriteContractsParameters } from '@wagmi/core/experimental' +``` + +### account + +`Account | Address | undefined` + +Account to execute the calls. + +::: code-group +```ts [index.ts] +import { parseAbi } from 'viem' +import { writeContracts } from '@wagmi/core/experimental' +import { config } from './config' + +const abi = parseAbi([ + 'function approve(address, uint256) returns (bool)', + 'function transferFrom(address, address, uint256) returns (bool)', +]) + +const id = await writeContracts(config, { + account: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', // [!code focus] + contracts: [ + { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi, + functionName: 'approve', + args: [ + '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + 100n + ], + }, + { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi, + functionName: 'transferFrom', + args: [ + '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + '0x0000000000000000000000000000000000000000', + 100n + ], + }, + ], +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### contracts + +`{ to: Hex, data?: Hex, value?: bigint }[]` + +Calls to execute. + +::: code-group +```ts [index.ts] +import { parseAbi } from 'viem' +import { writeContracts } from '@wagmi/core/experimental' +import { config } from './config' + +const abi = parseAbi([ + 'function approve(address, uint256) returns (bool)', + 'function transferFrom(address, address, uint256) returns (bool)', +]) + +const id = await writeContracts(config, { + contracts: [ // [!code focus] + { // [!code focus] + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', // [!code focus] + abi, // [!code focus] + functionName: 'approve', // [!code focus] + args: [ // [!code focus] + '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', // [!code focus] + 100n // [!code focus] + ], // [!code focus] + }, // [!code focus] + { // [!code focus] + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', // [!code focus] + abi, // [!code focus] + functionName: 'transferFrom', // [!code focus] + args: [ // [!code focus] + '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', // [!code focus] + '0x0000000000000000000000000000000000000000', // [!code focus] + 100n // [!code focus] + ], // [!code focus] + }, // [!code focus] + ], // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### capabilities + +`WalletCapabilities | undefined` + +Capability metadata for the calls (e.g. specifying a paymaster). + +::: code-group +```ts [index.ts] +import { parseAbi } from 'viem' +import { writeContracts } from '@wagmi/core/experimental' +import { config } from './config' + +const abi = parseAbi([ + 'function approve(address, uint256) returns (bool)', + 'function transferFrom(address, address, uint256) returns (bool)', +]) + +const id = await writeContracts(config, { + contracts: [ + { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi, + functionName: 'approve', + args: [ + '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + 100n + ], + }, + { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi, + functionName: 'transferFrom', + args: [ + '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + '0x0000000000000000000000000000000000000000', + 100n + ], + }, + ], + capabilities: { // [!code focus] + paymasterService: { // [!code focus] + url: 'https://...' // [!code focus] + } // [!code focus] + } // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`number | undefined` + +The target chain ID to broadcast the calls. + +::: code-group +```ts [index.ts] +import { parseAbi } from 'viem' +import { writeContracts } from '@wagmi/core/experimental' +import { config } from './config' + +const abi = parseAbi([ + 'function approve(address, uint256) returns (bool)', + 'function transferFrom(address, address, uint256) returns (bool)', +]) + +const id = await writeContracts(config, { + contracts: [ + { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi, + functionName: 'approve', + args: [ + '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + 100n + ], + }, + { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi, + functionName: 'transferFrom', + args: [ + '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + '0x0000000000000000000000000000000000000000', + 100n + ], + }, + ], + chainId: 10, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +Connector to get send the calls with. + +::: code-group +```ts [index.ts] +import { parseAbi } from 'viem' +import { getConnections } from '@wagmi/core' +import { writeContracts } from '@wagmi/core/experimental' +import { config } from './config' + +const abi = parseAbi([ + 'function approve(address, uint256) returns (bool)', + 'function transferFrom(address, address, uint256) returns (bool)', +]) + +const connections = getConnections(config) +const id = await writeContracts(config, { + contracts: [ + { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi, + functionName: 'approve', + args: [ + '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + 100n + ], + }, + { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi, + functionName: 'transferFrom', + args: [ + '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + '0x0000000000000000000000000000000000000000', + 100n + ], + }, + ], + connector: connections[0]?.connector, // [!code focus] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type WriteContractsReturnType } from '@wagmi/core/experimental' +``` + +`bigint` + +Most recent block number seen. + +## Error + +```ts +import { type WriteContractsErrorType } from '@wagmi/core/experimental' +``` + + + +## Viem + +- [`writeContracts`](https://viem.sh/experimental/eip5792/writeContracts) diff --git a/wagmi-project/site/core/api/chains.md b/wagmi-project/site/core/api/chains.md new file mode 100644 index 0000000000..6bdd81de6a --- /dev/null +++ b/wagmi-project/site/core/api/chains.md @@ -0,0 +1,24 @@ + + +# Chains + +## Import + +Import via the `'@wagmi/core/chains'` entrypoint (proxies all chains from `'viem/chains'`). + +```ts +import { mainnet } from '@wagmi/core/chains' +``` + +## Available Chains + +Chain definitions as of `viem@{{viemVersion}}`. For `viem@latest`, visit the [Viem repo](https://github.com/wevm/viem/blob/main/src/chains/index.ts). + + + + diff --git a/wagmi-project/site/core/api/connectors.md b/wagmi-project/site/core/api/connectors.md new file mode 100644 index 0000000000..d68718b25b --- /dev/null +++ b/wagmi-project/site/core/api/connectors.md @@ -0,0 +1,28 @@ + + +# Connectors + +Connectors for popular wallet providers and protocols. + +## Import + +```ts +import { injected } from 'wagmi/connectors' +``` + +## Built-In Connectors + +Available via the `'wagmi/connectors'` entrypoint. + + diff --git a/wagmi-project/site/core/api/connectors/coinbaseWallet.md b/wagmi-project/site/core/api/connectors/coinbaseWallet.md new file mode 100644 index 0000000000..d8968eac7d --- /dev/null +++ b/wagmi-project/site/core/api/connectors/coinbaseWallet.md @@ -0,0 +1,6 @@ + + + \ No newline at end of file diff --git a/wagmi-project/site/core/api/connectors/injected.md b/wagmi-project/site/core/api/connectors/injected.md new file mode 100644 index 0000000000..6e874baef3 --- /dev/null +++ b/wagmi-project/site/core/api/connectors/injected.md @@ -0,0 +1,7 @@ + + + diff --git a/wagmi-project/site/core/api/connectors/metaMask.md b/wagmi-project/site/core/api/connectors/metaMask.md new file mode 100644 index 0000000000..5553c2b34a --- /dev/null +++ b/wagmi-project/site/core/api/connectors/metaMask.md @@ -0,0 +1,7 @@ + + + diff --git a/wagmi-project/site/core/api/connectors/mock.md b/wagmi-project/site/core/api/connectors/mock.md new file mode 100644 index 0000000000..d085d93cb4 --- /dev/null +++ b/wagmi-project/site/core/api/connectors/mock.md @@ -0,0 +1,6 @@ + + + diff --git a/wagmi-project/site/core/api/connectors/safe.md b/wagmi-project/site/core/api/connectors/safe.md new file mode 100644 index 0000000000..cc800dcc90 --- /dev/null +++ b/wagmi-project/site/core/api/connectors/safe.md @@ -0,0 +1,6 @@ + + + diff --git a/wagmi-project/site/core/api/connectors/walletConnect.md b/wagmi-project/site/core/api/connectors/walletConnect.md new file mode 100644 index 0000000000..ba65cbda96 --- /dev/null +++ b/wagmi-project/site/core/api/connectors/walletConnect.md @@ -0,0 +1,6 @@ + + + diff --git a/wagmi-project/site/core/api/createConfig.md b/wagmi-project/site/core/api/createConfig.md new file mode 100644 index 0000000000..26df850162 --- /dev/null +++ b/wagmi-project/site/core/api/createConfig.md @@ -0,0 +1,7 @@ + + + diff --git a/wagmi-project/site/core/api/createConnector.md b/wagmi-project/site/core/api/createConnector.md new file mode 100644 index 0000000000..7cdbd00bdd --- /dev/null +++ b/wagmi-project/site/core/api/createConnector.md @@ -0,0 +1,31 @@ +# createConnector + +Creates new [`CreateConnectorFn`](#parameters). + +## Import + +```ts +import { createConnector } from '@wagmi/core' +``` + +## Usage + +```ts +import { createConnector } from '@wagmi/core' + +export type InjectedParameters = {} + +export function injected(parameters: InjectedParameters = {}) { + return createConnector((config) => ({ + // ... + })) +} +``` + +## Parameters + +```ts +import { type CreateConnectorFn } from '@wagmi/core' +``` + +Read [Creating Connectors](/dev/creating-connectors) for more info on the `CreateConnectorFn` type. \ No newline at end of file diff --git a/wagmi-project/site/core/api/createStorage.md b/wagmi-project/site/core/api/createStorage.md new file mode 100644 index 0000000000..f547a9a609 --- /dev/null +++ b/wagmi-project/site/core/api/createStorage.md @@ -0,0 +1,6 @@ + + + diff --git a/wagmi-project/site/core/api/errors.md b/wagmi-project/site/core/api/errors.md new file mode 100644 index 0000000000..4a29a1c30f --- /dev/null +++ b/wagmi-project/site/core/api/errors.md @@ -0,0 +1,11 @@ + + +# Errors + +Error classes used by Wagmi. + + + diff --git a/wagmi-project/site/core/api/transports.md b/wagmi-project/site/core/api/transports.md new file mode 100644 index 0000000000..cfaa9a6021 --- /dev/null +++ b/wagmi-project/site/core/api/transports.md @@ -0,0 +1,28 @@ + + +# Transports + +[`createConfig`](/core/api/createConfig) can be instantiated with a set of Transports for each chain. A Transport is the intermediary layer that is responsible for executing outgoing JSON-RPC requests to the RPC Provider (e.g. Alchemy, Infura, etc). + +## Import + +```ts +import { http } from '@wagmi/core' +``` + +## Built-In Transports + +Available via the `'@wagmi/core'` entrypoint. + + diff --git a/wagmi-project/site/core/api/transports/custom.md b/wagmi-project/site/core/api/transports/custom.md new file mode 100644 index 0000000000..487c3ae930 --- /dev/null +++ b/wagmi-project/site/core/api/transports/custom.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/core/api/transports/fallback.md b/wagmi-project/site/core/api/transports/fallback.md new file mode 100644 index 0000000000..cefffa734e --- /dev/null +++ b/wagmi-project/site/core/api/transports/fallback.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/core/api/transports/http.md b/wagmi-project/site/core/api/transports/http.md new file mode 100644 index 0000000000..7fed8c6d72 --- /dev/null +++ b/wagmi-project/site/core/api/transports/http.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/core/api/transports/unstable_connector.md b/wagmi-project/site/core/api/transports/unstable_connector.md new file mode 100644 index 0000000000..19a9b43575 --- /dev/null +++ b/wagmi-project/site/core/api/transports/unstable_connector.md @@ -0,0 +1,6 @@ + + + diff --git a/wagmi-project/site/core/api/transports/webSocket.md b/wagmi-project/site/core/api/transports/webSocket.md new file mode 100644 index 0000000000..4ed1ae3273 --- /dev/null +++ b/wagmi-project/site/core/api/transports/webSocket.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/core/api/utilities/cookieToInitialState.md b/wagmi-project/site/core/api/utilities/cookieToInitialState.md new file mode 100644 index 0000000000..c0470295c9 --- /dev/null +++ b/wagmi-project/site/core/api/utilities/cookieToInitialState.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/core/api/utilities/deserialize.md b/wagmi-project/site/core/api/utilities/deserialize.md new file mode 100644 index 0000000000..4f051cdc53 --- /dev/null +++ b/wagmi-project/site/core/api/utilities/deserialize.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/core/api/utilities/normalizeChainId.md b/wagmi-project/site/core/api/utilities/normalizeChainId.md new file mode 100644 index 0000000000..9dd43935bb --- /dev/null +++ b/wagmi-project/site/core/api/utilities/normalizeChainId.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/core/api/utilities/serialize.md b/wagmi-project/site/core/api/utilities/serialize.md new file mode 100644 index 0000000000..3672a67c17 --- /dev/null +++ b/wagmi-project/site/core/api/utilities/serialize.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/core/getting-started.md b/wagmi-project/site/core/getting-started.md new file mode 100644 index 0000000000..f5759957a5 --- /dev/null +++ b/wagmi-project/site/core/getting-started.md @@ -0,0 +1,71 @@ + + +# Getting Started + +## Overview + +Wagmi Core is a VanillaJS library for Ethereum. You can learn more about the rationale behind the project in the [Why Wagmi](/core/why) section. + +## Manual Installation + +To manually add Wagmi to your project, install the required packages. + +::: code-group +```bash-vue [pnpm] +pnpm add @wagmi/core @wagmi/connectors viem@{{viemVersion}} +``` + +```bash-vue [npm] +npm install @wagmi/core @wagmi/connectors viem@{{viemVersion}} +``` + +```bash-vue [yarn] +yarn add @wagmi/core @wagmi/connectors viem@{{viemVersion}} +``` + +```bash-vue [bun] +bun add @wagmi/core @wagmi/connectors viem@{{viemVersion}} +``` +::: + +- [Wagmi Connectors](/core/api/connectors) is a collection of interfaces for linking accounts/wallets to Wagmi. +- [Viem](https://viem.sh) is a TypeScript interface for Ethereum that performs blockchain operations. +- [TypeScript](/react/typescript) is optional, but highly recommended. Learn more about [TypeScript support](/core/typescript). + +### Create Config + +Create and export a new Wagmi config using `createConfig`. + +::: code-group +<<< @/snippets/core/config.ts[config.ts] +::: + +In this example, Wagmi is configured to use the Mainnet and Sepolia chains. Check out the [`createConfig` docs](/core/api/createConfig) for more configuration options. + +### Use Wagmi + +Now that everything is set up, you can pass the `config` to use actions. + +::: code-group +```tsx [index.ts] +import { getAccount, getEnsName } from '@wagmi/core' +import { config } from './config' + +const { address } = getAccount(config) +const ensName = await getEnsName(config, { address }) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Next Steps + +For more information on what to do next, check out the following topics. + +- [**TypeScript**](/core/typescript) Learn how to get the most out of Wagmi's type-safety and inference for an enlightened developer experience. +- [**Actions**](/core/api/actions) Browse the collection of actions and learn how to use them. +- [**Framework Adapters**](/core/guides/framework-adapters) Learn how to create a Wagmi-like adapter for your favorite framework. +- [**Viem docs**](https://viem.sh) Wagmi Core is a wrapper around Viem that manages account and client reactivity. Learn more about Viem and how to use it. diff --git a/wagmi-project/site/core/guides/chain-properties.md b/wagmi-project/site/core/guides/chain-properties.md new file mode 100644 index 0000000000..4f0b480fe0 --- /dev/null +++ b/wagmi-project/site/core/guides/chain-properties.md @@ -0,0 +1,91 @@ +# Chain Properties + +Some chains support additional properties related to blocks and transactions. This is powered by Viem's [formatters](https://viem.sh/docs/chains/formatters) and [serializers](https://viem.sh/docs/chains/serializers). For example, Celo, ZkSync, OP Stack chains support all additional properties. In order to use these properties in a type-safe way, there are a few things you should be aware of. + +## Narrowing Parameters + +When you pass your `config` to an action, you are ready to access chain-specific properties! For example, Celo's `feeCurrency` is available. + +::: code-group +```ts [index.ts] +import { parseEther } from 'viem' +import { simulateContract } from '@wagmi/core' +import { config } from './config' + +const result = await simulateContract(config, { + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + feeCurrency: '0x…', // [!code focus] +}) +``` +<<< @/snippets/core/config-chain-properties.ts[config.ts] +::: + +This is great, but if you have multiple chains that support additional properties, your autocomplete could be overwhelmed with all of them. By setting the `chainId` property to a specific value (e.g. `celo.id`), you can narrow parameters to a single chain. + +::: code-group +```ts [index.ts] +import { parseEther } from 'viem' +import { simulateContract } from '@wagmi/core' +import { celo } from 'wagmi/chains' + +const result = await simulateContract({ + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + chainId: celo.id, // [!code focus] + feeCurrency: '0x…', // [!code focus] + // ^? (property) feeCurrency?: `0x${string}` | undefined // [!code focus] +}) +``` +<<< @/snippets/core/config-chain-properties.ts[config.ts] +::: + +## Narrowing Return Types + +Return types can also have chain-specific properties attached to them. There are a couple approaches for extracting these properties. + +### `chainId` Parameter + +Not only can you use the `chainId` parameter to [narrow parameters](#narrowing-parameters), you can also use it to narrow the return type. + +::: code-group +```ts [index.tsx] +import { waitForTransactionReceipt } from '@wagmi/core' +import { zkSync } from '@wagmi/core/chains' + +const result = await waitForTransactionReceipt({ + chainId: zkSync.id, + hash: '0x16854fcdd0219cacf5aec5e4eb2154dac9e406578a1510a6fc48bd0b67e69ea9', +}) + +result.logs +// ^? (property) logs: ZkSyncLog[] | undefined +``` +<<< @/snippets/core/config-chain-properties.ts[config.ts] +::: + +### `chainId` Data Property + +Wagmi internally will set a `chainId` property on return types that you can use to narrow results. The `chainId` is determined from the `chainId` parameter or global state (e.g. connector). You can use this property to help TypeScript narrow the type. + +::: code-group +```ts [index.tsx] +import { waitForTransactionReceipt } from '@wagmi/core' +import { zkSync } from '@wagmi/core/chains' + +const result = await waitForTransactionReceipt({ + hash: '0x16854fcdd0219cacf5aec5e4eb2154dac9e406578a1510a6fc48bd0b67e69ea9', +}) + +if (result.chainId === zkSync.id) { + result.logs + // ^? (property) logs: ZkSyncLog[] | undefined +} +``` +<<< @/snippets/core/config-chain-properties.ts[config.ts] +::: + +## Troubleshooting + +If chain properties aren't working, make sure [TypeScript](/core/guides/faq#type-inference-doesn-t-work) is configured correctly. Not all chains have additional properties, to check which ones do, see the [Viem repo](https://github.com/wevm/viem/tree/main/src/chains) (chains that have a top-level directory under [`src/chains`](https://github.com/wevm/viem/tree/main/src/chains) support additional properties). + diff --git a/wagmi-project/site/core/guides/error-handling.md b/wagmi-project/site/core/guides/error-handling.md new file mode 100644 index 0000000000..bac34a1d2c --- /dev/null +++ b/wagmi-project/site/core/guides/error-handling.md @@ -0,0 +1,37 @@ +# Error Handling + +Every module in Wagmi Core exports an accompanying error type which you can use to strongly type your `catch` statements. + +These types come in the form of `ErrorType`. For example, the `getBlockNumber` action exports a `GetBlockNumberErrorType` type. + +Unfortunately, [TypeScript doesn't have an abstraction for typed exceptions](https://github.com/microsoft/TypeScript/issues/13219), so the most pragmatic & vanilla approach would be to explicitly cast error types in the `catch` statement. + +::: code-group +```tsx [index.tsx] +import { type GetBlockNumberErrorType, getBlockNumber } from '@wagmi/core' +import { config } from './config' + +try { + const blockNumber = await getBlockNumber(config) +} catch (e) { + const error = e as GetBlockNumberErrorType + error.name + // ^? (property) name: "Error" | "ChainDisconnectedError" | "HttpRequestError" | "InternalRpcError" | "InvalidInputRpcError" | "InvalidParamsRpcError" | "InvalidRequestRpcError" | "JsonRpcVersionUnsupportedError" | ... 16 more ... | "WebSocketRequestError" + + if (error.name === 'InternalRpcError') + error.code + // ^? (property) code: -32603 + + if (error.name === 'HttpRequestError') + error.headers + // ^? (property) headers: Headers + error.status + // ^? (property) status: number +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +::: tip +If you are using [Wagmi Hooks](/react/api/hooks), errors are [already strongly typed](/react/guides/error-handling) via the `error` property. +::: \ No newline at end of file diff --git a/wagmi-project/site/core/guides/ethers.md b/wagmi-project/site/core/guides/ethers.md new file mode 100644 index 0000000000..c99598a362 --- /dev/null +++ b/wagmi-project/site/core/guides/ethers.md @@ -0,0 +1,306 @@ +# Ethers.js Adapters + +It is recommended for projects to migrate to [Viem](https://viem.sh) when using Wagmi, but there are some cases where you might still need to use [Ethers.js](https://ethers.org) in your project: + +- You may want to **incrementally migrate** Ethers.js usage to Viem +- Some **third-party libraries & SDKs** may only support Ethers.js +- Personal preference + +We have provided reference implementations for Viem → Ethers.js adapters that you can copy + paste in your project. + +## Client → Provider + +### Reference Implementation + +Copy the following reference implementation into a file of your choice: + +::: code-group + +```ts [Ethers v5] +import { type Config, getClient } from '@wagmi/core' +import { providers } from 'ethers' +import type { Client, Chain, Transport } from 'viem' + +export function clientToProvider(client: Client) { + const { chain, transport } = client + const network = { + chainId: chain.id, + name: chain.name, + ensAddress: chain.contracts?.ensRegistry?.address, + } + if (transport.type === 'fallback') + return new providers.FallbackProvider( + (transport.transports as ReturnType[]).map( + ({ value }) => new providers.JsonRpcProvider(value?.url, network), + ), + ) + return new providers.JsonRpcProvider(transport.url, network) +} + +/** Action to convert a viem Public Client to an ethers.js Provider. */ +export function getEthersProvider( + config: Config, + { chainId }: { chainId?: number } = {}, +) { + const client = getClient(config, { chainId }) + if (!client) return + return clientToProvider(client) +} +``` + +```ts [Ethers v6] +import { type Config, getClient } from '@wagmi/core' +import { FallbackProvider, JsonRpcProvider } from 'ethers' +import type { Client, Chain, Transport } from 'viem' + +export function clientToProvider(client: Client) { + const { chain, transport } = client + const network = { + chainId: chain.id, + name: chain.name, + ensAddress: chain.contracts?.ensRegistry?.address, + } + if (transport.type === 'fallback') { + const providers = (transport.transports as ReturnType[]).map( + ({ value }) => new JsonRpcProvider(value?.url, network), + ) + if (providers.length === 1) return providers[0] + return new FallbackProvider(providers) + } + return new JsonRpcProvider(transport.url, network) +} + +/** Action to convert a viem Client to an ethers.js Provider. */ +export function getEthersProvider( + config: Config, + { chainId }: { chainId?: number } = {}, +) { + const client = getClient(config, { chainId }) + if (!client) return + return clientToProvider(client) +} +``` + +::: + +### Usage + +Now you can use the `getEthersProvider` function in your components: + +::: code-group + +```ts [example.ts] +import { getEthersProvider } from './ethers' +import { config } from './config' + +function example() { + const provider = getEthersProvider(config) + ... +} +``` + +```ts [ethers.ts (Ethers v5)] +import { type Config, getClient } from '@wagmi/core' +import { providers } from 'ethers' +import type { Client, Chain, Transport } from 'viem' + +export function clientToProvider(client: Client) { + const { chain, transport } = client + const network = { + chainId: chain.id, + name: chain.name, + ensAddress: chain.contracts?.ensRegistry?.address, + } + if (transport.type === 'fallback') + return new providers.FallbackProvider( + (transport.transports as ReturnType[]).map( + ({ value }) => new providers.JsonRpcProvider(value?.url, network), + ), + ) + return new providers.JsonRpcProvider(transport.url, network) +} + +/** Action to convert a viem Public Client to an ethers.js Provider. */ +export function getEthersProvider( + config: Config, + { chainId }: { chainId?: number } = {}, +) { + const client = getClient(config, { chainId }) + if (!client) return + return clientToProvider(client) +} + +``` + +```ts [ethers.ts (Ethers v6)] +import { type Config, getClient } from '@wagmi/core' +import { FallbackProvider, JsonRpcProvider } from 'ethers' +import type { Client, Chain, Transport } from 'viem' + +export function clientToProvider(client: Client) { + const { chain, transport } = client + const network = { + chainId: chain.id, + name: chain.name, + ensAddress: chain.contracts?.ensRegistry?.address, + } + if (transport.type === 'fallback') { + const providers = (transport.transports as ReturnType[]).map( + ({ value }) => new JsonRpcProvider(value?.url, network), + ) + if (providers.length === 1) return providers[0] + return new FallbackProvider(providers) + } + return new JsonRpcProvider(transport.url, network) +} + +/** Action to convert a viem Client to an ethers.js Provider. */ +export function getEthersProvider( + config: Config, + { chainId }: { chainId?: number } = {}, +) { + const client = getClient(config, { chainId }) + if (!client) return + return clientToProvider(client) +} +``` + +::: + +## Connector Client → Signer + +### Reference Implementation + +Copy the following reference implementation into a file of your choice: + +::: code-group + +```ts [Ethers v5] +import { Config, getConnectorClient } from '@wagmi/core' +import { providers } from 'ethers' +import type { Account, Chain, Client, Transport } from 'viem' + +export function clientToSigner(client: Client) { + const { account, chain, transport } = client + const network = { + chainId: chain.id, + name: chain.name, + ensAddress: chain.contracts?.ensRegistry?.address, + } + const provider = new providers.Web3Provider(transport, network) + const signer = provider.getSigner(account.address) + return signer +} + +/** Action to convert a Viem Client to an ethers.js Signer. */ +export async function getEthersSigner( + config: Config, + { chainId }: { chainId?: number } = {}, +) { + const client = await getConnectorClient(config, { chainId }) + return clientToSigner(client) +} +``` + +```ts [Ethers v6] +import { Config, getConnectorClient } from '@wagmi/core' +import { BrowserProvider, JsonRpcSigner } from 'ethers' +import type { Account, Chain, Client, Transport } from 'viem' + +export function clientToSigner(client: Client) { + const { account, chain, transport } = client + const network = { + chainId: chain.id, + name: chain.name, + ensAddress: chain.contracts?.ensRegistry?.address, + } + const provider = new BrowserProvider(transport, network) + const signer = new JsonRpcSigner(provider, account.address) + return signer +} + +/** Action to convert a viem Wallet Client to an ethers.js Signer. */ +export async function getEthersSigner( + config: Config, + { chainId }: { chainId?: number } = {}, +) { + const client = await getConnectorClient(config, { chainId }) + return clientToSigner(client) +} + +``` + +::: + +### Usage + +Now you can use the `getEthersSigner` function in your components: + +::: code-group + +```ts [example.ts] +import { getEthersSigner } from './ethers' +import { config } from './config' + +function example() { + const provider = getEthersSigner(config) + ... +} +``` + +```ts [ethers.ts (Ethers v5)] +import { Config, getConnectorClient } from '@wagmi/core' +import { providers } from 'ethers' +import type { Account, Chain, Client, Transport } from 'viem' + +export function clientToSigner(client: Client) { + const { account, chain, transport } = client + const network = { + chainId: chain.id, + name: chain.name, + ensAddress: chain.contracts?.ensRegistry?.address, + } + const provider = new providers.Web3Provider(transport, network) + const signer = provider.getSigner(account.address) + return signer +} + +/** Action to convert a Viem Client to an ethers.js Signer. */ +export async function getEthersSigner( + config: Config, + { chainId }: { chainId?: number } = {}, +) { + const client = await getConnectorClient(config, { chainId }) + return clientToSigner(client) +} +``` + +```ts [ethers.ts (Ethers v6)] +import { Config, getConnectorClient } from '@wagmi/core' +import { BrowserProvider, JsonRpcSigner } from 'ethers' +import type { Account, Chain, Client, Transport } from 'viem' + +export function clientToSigner(client: Client) { + const { account, chain, transport } = client + const network = { + chainId: chain.id, + name: chain.name, + ensAddress: chain.contracts?.ensRegistry?.address, + } + const provider = new BrowserProvider(transport, network) + const signer = new JsonRpcSigner(provider, account.address) + return signer +} + +/** Action to convert a viem Wallet Client to an ethers.js Signer. */ +export async function getEthersSigner( + config: Config, + { chainId }: { chainId?: number } = {}, +) { + const client = await getConnectorClient(config, { chainId }) + return clientToSigner(client) +} + +``` + +::: diff --git a/wagmi-project/site/core/guides/faq.md b/wagmi-project/site/core/guides/faq.md new file mode 100644 index 0000000000..7e3ca47e10 --- /dev/null +++ b/wagmi-project/site/core/guides/faq.md @@ -0,0 +1,9 @@ + + +# FAQ / Troubleshooting + +Collection of frequently asked questions with ideas on how to troubleshoot and resolve them. + + diff --git a/wagmi-project/site/core/guides/framework-adapters.md b/wagmi-project/site/core/guides/framework-adapters.md new file mode 100644 index 0000000000..1e45ba63ec --- /dev/null +++ b/wagmi-project/site/core/guides/framework-adapters.md @@ -0,0 +1,35 @@ +# Framework Adapters + +Folks often ask if they can use Wagmi with other frameworks, like Svelte, Solid.js, and more. + +The short answer is — you already can! Wagmi Core is pure VanillaJS that you can use with any framework. For some, this answer is (understandably) unsatisfying as they want a tight integration between Wagmi Core and their favorite framework's reactivity system, e.g. what Wagmi is for React and Vue. + +Someday, we would love to support additional frameworks, but unfortunately the core team doesn't have time to build and support them in a high-quality way at the moment. This could change in the future with additional [sponsors](https://github.com/sponsors/wevm), reshuffling of the roadmap, or if someone from the community wants to lead the effort. + +In the meantime, here are some tips on how to create tighter bonds between Wagmi Core and other frameworks. + +## Dependency Injection + +Once you create a Wagmi Config, you'll need to make sure your framework has access to it inside your higher-level functions (e.g. hooks for React, composables for Vue). For example, Wagmi uses [React Context](https://react.dev/learn/passing-data-deeply-with-context) to inject the Config into React Hooks and update it if it changes. This makes it so your users don't need to pass a Config object every time they use a hook. + +## Reactivity Layer + +All frameworks approach reactivity in a different way. To hook into your favorite frameworks, reactivity system, it's often helpful to see what other popular libraries for your framework are doing. + +The most important thing to hook up Wagmi Core with your framework is to make sure changes to the Wagmi Config are tracked. This enables behavior, like switching chains or connecting accounts, to propagate throughout your app and update state. Check out [`useAccount`](https://github.com/wevm/wagmi/blob/main/packages/react/src/hooks/useAccount.ts), [`useChainId`](https://github.com/wevm/wagmi/blob/main/packages/react/src/hooks/useChainId.ts), [`useClient`](https://github.com/wevm/wagmi/blob/main/packages/react/src/hooks/useClient.ts), and [`useConnectorClient`](https://github.com/wevm/wagmi/blob/main/packages/react/src/hooks/useConnectorClient.ts) — versions of these for your framework are important to get right as they power a lot of internals. + +## TanStack Query + +Wagmi uses [TanStack Query](https://tanstack.com/query) to enable caching, deduplication, persistence, and more in React and Vue applications. Normally, you would need to find a similar library for your framework, but the good news is TanStack Query supports other frameworks! (Svelte, Solid, and Angular at the time of writing.) + +To get started with your framework, install and set up the related TanStack Query adapter. Next, import query keys/functions and mutation functions from the `'@wagmi/core/query'` entrypoint. You can plug these directly into your framework's TanStack Query adapter functions. + +If you are building a library, you'll also want to make sure that you wire up generics correctly so type-inference and safety work correctly. The best way to make sure you are doing this correctly, is to see how we do this for React with Wagmi by checking out the [source code](https://github.com/wevm/wagmi/tree/main/packages/react/src/hooks). + +## Testing + +If you are building a library, you'll want to write tests. Wagmi uses [React Testing Library](https://testing-library.com/docs/react-testing-library/intro) to test hooks. [Testing Library](https://testing-library.com) also supports other frameworks, like Svelte, Solid, and more. You can take a look at how the React tests work and do something similar for your code. + +## Proxy Exports + +Wagmi proxies exports directly from Wagmi Core and [Viem](https://viem.sh) to make importing easier. You'll likely want to imitate this behavior for your framework. diff --git a/wagmi-project/site/core/guides/migrate-from-v1-to-v2.md b/wagmi-project/site/core/guides/migrate-from-v1-to-v2.md new file mode 100644 index 0000000000..6807ebafcd --- /dev/null +++ b/wagmi-project/site/core/guides/migrate-from-v1-to-v2.md @@ -0,0 +1,585 @@ +--- +title: Migrate from v1 to v2 +titleTemplate: Wagmi Core +description: Guide for migrating from Wagmi Core v1 to v2. +--- + + + +# Migrate from v1 to v2 + +Wagmi Core v2 redesigns the core APIs to mesh better with [Viem](https://viem.sh). This major version transforms Wagmi into a light wrapper around Viem, sprinkling in multichain support and account management. As such, there are some breaking changes and deprecations to be aware of outlined in this guide. + +To get started, install the latest version of Wagmi and it's required peer dependencies. + +::: code-group +```bash-vue [pnpm] +pnpm add @wagmi/core viem@{{viemVersion}} @wagmi/connectors +``` + +```bash-vue [npm] +npm install @wagmi/core viem@{{viemVersion}} @wagmi/connectors +``` + +```bash-vue [yarn] +yarn add @wagmi/core viem@{{viemVersion}} @wagmi/connectors +``` + +```bash-vue [bun] +bun add @wagmi/core viem@{{viemVersion}} @wagmi/connectors +``` +::: + +::: info Wagmi Core v2 should be the last major version that will have this many actionable breaking changes. +Moving forward, new functionality will be opt-in with old functionality being deprecated alongside the new features. This means upgrading to the latest major versions will not require immediate changes. +::: + +::: info Not ready to migrate yet? +The Wagmi Core v1 docs are still available at [1.x.wagmi.sh/core](https://1.x.wagmi.sh/core). +::: + +## Dependencies + +### Dropped CommonJS support + +Wagmi v2 no longer publishes a separate `cjs` tag since very few people use this tag and ESM is the future. See [Sindre Sorhus' guide](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c) for more info about switching to ESM. + +## Actions + +### Removed `config` singleton + +Before v2, when you called [`createConfig`](/core/api/createConfig), it set a global `config` singleton that was used internally by actions. For v2, `config` is now a required first parameter for actions. + +::: code-group +```ts [index.ts] +import { getAccount, readContract } from '@wagmi/core' +import { parseAbi } from 'viem' +import { config } from './config' // [!code ++] + +const account = getAccount() // [!code --] +const account = getAccount(config) // [!code ++] + +const balanceOf = readContract({ // [!code --] +const balanceOf = readContract(config, { // [!code ++] + address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + abi: parseAbi(['function balanceOf(address) view returns (uint256)']), + functionName: 'balanceOf', + args: ['0xd2135CfB216b74109775236E36d4b433F1DF507B'], +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +The previous global `config` singleton made it so you couldn't use multiple `Config` objects in the same project. In addition, we think passing `config` is more explicit and makes it easier to understand what's going on. Finally, types can be inferred directly from the `config`, like [chain properties](/core/guides/chain-properties) and more. + +### Removed `getContract` + +Removed `getContract` export. Use Viem's [`getContract`](https://viem.sh/docs/contract/getContract.html) instead. + +```ts +import { getContract } from '@wagmi/core' // [!code --] +import { getContract } from 'viem' // [!code ++] + +const contract = getContract() // [!code --] +const contract = getContract() // [!code ++] +``` + +### Removed `getNetwork` and `watchNetwork` + +The `getNetwork` and `watchNetwork` actions were removed since the connected chain is typically based on the connected account. + +- Use [`config.chains`](/core/api/createConfig#chains-1) instead to get `chains`. + + ::: code-group + ```ts [index.ts] + import { getNetwork } from '@wagmi/core' // [!code --] + + const { chains } = getNetwork() // [!code --] + const chains = config.chains // [!code ++] + ``` + <<< @/snippets/core/config.ts[config.ts] + ::: + +- Use [`getAccount`](/core/api/actions/getAccount) and `config.chains` instead to get `chain`. + + ::: code-group + ```ts [index.ts] + import { getNetwork } from '@wagmi/core' // [!code --] + import { getAccount } from '@wagmi/core' // [!code ++] + import { config } from './config' // [!code ++] + + const { chain } = getNetwork() // [!code --] + const { chainId } = getAccount(config) // [!code ++] + const chain = chains.find(chain => chain.id === chainId) // [!code ++] + ``` + <<< @/snippets/core/config.ts[config.ts] + ::: + + Before v2, `getNetwork().chain` could result in an invalid chain if the active connector's `chainId` was not configured in the list of `config.chains`. Using `getAccount` and `config.chains` is more work, but ensures that chain is either valid or not defined. You can also use `getAccount(config).chain` if you don't care about the chain being `undefined` when not configured. + +- Use `watchAccount` instead of `watchNetwork`. + + ::: code-group + ```ts [index.ts] + import { watchNetwork } from '@wagmi/core' // [!code --] + import { watchAccount } from '@wagmi/core' // [!code ++] + import { config } from './config' // [!code ++] + + const unwatch = watchNetwork((data) => console.log('Changed!', data)) // [!code --] + const unwatch = watchAccount(config, { // [!code ++] + onChange(data) { // [!code ++] + const chains = config.chains // [!code ++] + const chain = chains.find(chain => chain.id === data.chainId) // [!code ++] + }, // [!code ++] + }) // [!code ++] + ``` + <<< @/snippets/core/config.ts[config.ts] + ::: + +### Removed `getWebSocketPublicClient` and `watchWebSocketPublicClient` + +Viem [Transports](https://viem.sh/docs/clients/intro.html#transports) now determine the type of client that is returned. You can use [`getPublicClient`](/core/api/actions/getPublicClient) and [`watchPublicClient`](/core/api/actions/watchPublicClient) to retrieve Viem [`PublicClient`](https://viem.sh/docs/clients/public.html) instances. + +Alternatively, you can use [`getClient`](/core/api/actions/getClient) and [`watchClient`](/core/api/actions/watchClient) to retrieve plain Viem [`Client`](https://viem.sh/docs/clients/custom.html) instances. This is a better option for users that care about optimizing bundle size to be as small as possible. + +### Removed `watchReadContract`, `watchReadContracts`, and `watchReadMulticall` + +Use [`watchBlockNumber`](/core/api/actions/watchBlockNumber) along with [`readContract`](/core/api/actions/readContract), [`readContracts`](/core/api/actions/readContracts), and [`multicall`](/core/api/actions/multicall) actions instead. Before v2, `watchReadContract`, `watchReadContracts`, and `watchReadMulticall` were all wrappers around `watchBlockNumber` and this simplifies the API. + +::: code-group +```ts [index.ts] +import { watchReadContract } from '@wagmi/core' // [!code --] +import { watchBlockNumber, readContract } from '@wagmi/core' // [!code ++] +import { config } from './config' // [!code ++] + +const unwatch = watchReadContract( // [!code --] + { // [!code --] + address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', // [!code --] + abi: parseAbi(['function balanceOf(address) view returns (uint256)']), // [!code --] + functionName: 'balanceOf', // [!code --] + args: ['0xd2135CfB216b74109775236E36d4b433F1DF507B'], // [!code --] + }, // [!code --] + (result) => console.log('Changed!', result), // [!code --] +) // [!code --] +const unwatch = watchBlockNumber(config, { // [!code ++] + onBlockNumber() { // [!code ++] + const balanceOf = readContract(config, { // [!code ++] + address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', // [!code ++] + abi: parseAbi(['function balanceOf(address) view returns (uint256)']), // [!code ++] + functionName: 'balanceOf', // [!code ++] + args: ['0xd2135CfB216b74109775236E36d4b433F1DF507B'], // [!code ++] + }) // [!code ++] + console.log('Changed!', balanceOf)// [!code ++] + }, // [!code ++] +}) // [!code ++] +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### Removed `fetchFeeData` + +Removed `fetchFeeData`. Use [`estimateFeesPerGas`](/core/api/actions/estimateFeesPerGas) instead. + +::: code-group +```ts [index.ts] +import { fetchFeeData } from '@wagmi/core' // [!code --] +import { estimateFeesPerGas } from '@wagmi/core' // [!code ++] +import { config } from './config' // [!code ++] + +const result = await fetchFeeData() // [!code --] +const result = await estimateFeesPerGas(config) // [!code ++] +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### Removed `prepareWriteContract` + +Removed `prepareWriteContract`. Use [`simulateContract`](/core/api/actions/simulateContract) instead. + +::: code-group +```ts [index.ts] +import { prepareWriteContract } from '@wagmi/core' // [!code --] +import { simulateContract } from '@wagmi/core' // [!code ++] +import { config } from './config' // [!code ++] + +const result = await prepareWriteContract({ ... }) // [!code --] +const result = await simulateContract(config, { ... }) // [!code ++] +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### Removed `prepareSendTransaction` + +Removed `prepareSendTransaction`. Use [`estimateGas`](/core/api/actions/estimateGas) instead. + +::: code-group +```ts [index.ts] +import { prepareSendTransaction } from '@wagmi/core' // [!code --] +import { estimateGas } from '@wagmi/core' // [!code ++] +import { config } from './config' // [!code ++] + +const result = await prepareSendTransaction({ ... }) // [!code --] +const result = await estimateGas(config, { ... }) // [!code ++] +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### Updated `sendTransaction` and `writeContract` return type + +Updated [`sendTransaction`](/core/api/actions/sendTransaction) and [`writeContract`](/core/api/actions/writeContract) return type from `` { hash: `0x${string}` } `` to `` `0x${string}` ``. + +```ts +const result = await sendTransaction({ hash: '0x...' }) +result.hash // [!code --] +result // [!code ++] +``` + +### Updated `connect` return type + +Updated [`connect`](/core/api/actions/connect) return type from `` { account: Address; chain: { id: number; unsupported?: boolean }; connector: Connector } `` to `` { accounts: readonly Address[]; chainId: number } ``. This better reflects the ability to have multiple accounts per connector. + +### Renamed parameters and return types + +All hook parameters and return types follow the naming pattern of `[PascalCaseActionName]Parameters` and `[PascalCaseActionName]ReturnType`. For example, `GetAccountParameters` and `GetAccountReturnType`. + +```ts +import { GetAccountConfig, GetAccountResult } from '@wagmi/core' // [!code --] +import { GetAccountParameters, GetAccountReturnType } from '@wagmi/core' // [!code ++] +``` + +## Connectors + +### Moved Wagmi Connectors to peer dependencies + +Wagmi Core v2 no longer exports connectors via the `'@wagmi/core/connectors/*'` entrypoints. Instead, you should install the `@wagmi/connectors` package. + +::: code-group +```bash-vue [pnpm] +pnpm add @wagmi/connectors +``` + +```bash-vue [npm] +npm install @wagmi/connectors +``` + +```bash-vue [yarn] +yarn add @wagmi/connectors +``` + +```bash-vue [bun] +bun add @wagmi/connectors +``` +::: + +And import connectors from there. + +```ts +import { injected } from '@wagmi/connectors' +``` + +See the [connectors documentation](/core/api/connectors) for more information. + +### Updated connector API + +In order to maximize type-safety and ease of creating connectors, the connector API changed. Follow the [Creating Connectors guide](/dev/creating-connectors) for more info on creating new connectors and converting Wagmi v1 connectors. + +### Removed individual entrypoints + +Previously, each connector had its own entrypoint to optimize tree-shaking. Since all connectors now have [`package.json#sideEffects`](https://webpack.js.org/guides/tree-shaking/#mark-the-file-as-side-effect-free) enabled, this is no longer necessary and the entrypoint is unified. Use the `'@wagmi/connectors'` package instead. + +```ts +import { InjectedConnector } from '@wagmi/core/connectors/injected' // [!code --] +import { CoinbaseWalletConnector } from '@wagmi/core/connectors/coinbaseWallet' // [!code --] +import { coinbaseWallet, injected } from '@wagmi/connectors' // [!code ++] +``` + +### Removed `MetaMaskConnector` + +The `MetaMaskConnector` was removed since it was nearly the same thing as the `InjectedConnector`. Use the [`injected`](/core/api/connectors/injected) connector instead, along with the [`target`](/core/api/connectors/injected#target) parameter set to `'metaMask'`, for the same behavior. + +```ts +import { MetaMaskConnector } from '@wagmi/core/connectors/metaMask' // [!code --] +import { injected } from '@wagmi/connectors' // [!code ++] + +const connector = new MetaMaskConnector() // [!code --] +const connector = injected({ target: 'metaMask' }) // [!code ++] +``` + +### Renamed connectors + +In Wagmi v1, connectors were classes you needed to instantiate. In Wagmi v2, connectors are functions. As a result, the API has changed. Connectors have the following new names: + +- `CoinbaseWalletConnector` is now [`coinbaseWallet`](/core/api/connectors/coinbaseWallet). +- `InjectedConnector` is now [`injected`](/core/api/connectors/injected). +- `SafeConnector` is now [`safe`](/core/api/connectors/safe). +- `WalletConnectConnector` is now [`walletConnect`](/core/api/connectors/walletConnect). + +To create a connector, you now call the connector function with parameters. + +```ts +import { WalletConnectConnector } from '@wagmi/core/connectors/walletConnect' // [!code --] +import { walletConnect } from '@wagmi/connectors' // [!code ++] + +const connector = new WalletConnectConnector({ // [!code --] +const connector = walletConnect({ // [!code ++] + projectId: '3fcc6bba6f1de962d911bb5b5c3dba68', +}) +``` + +### Removed `WalletConnectLegacyConnector` + +WalletConnect v1 was sunset June 28, 2023. Use the [`walletConnect`](/core/api/connectors/walletConnect) connector instead. + +```ts +import { WalletConnectLegacyConnector } from '@wagmi/core/connectors/walletConnectLegacy' // [!code --] +import { walletConnect } from '@wagmi/connectors' // [!code ++] + +const connector = new WalletConnectLegacyConnector({ // [!code --] +const connector = walletConnect({ // [!code ++] + projectId: '3fcc6bba6f1de962d911bb5b5c3dba68', +}) +``` + +## Chains + +### Updated `'@wagmi/core/chains'` entrypoint + +Chains now live in the [Viem repository](https://github.com/wevm/viem). As a result, the `'@wagmi/core/chains'` entrypoint now proxies all chains from `'viem/chains'` directly. + +### Removed `mainnet` and `sepolia` from main entrypoint + +Since the `'@wagmi/core/chains'` entrypoint now proxies `'viem/chains'`, `mainnet` and `sepolia` were removed from the main entrypoint. Use the `'@wagmi/core/chains'` entrypoint instead. + +```ts +import { mainnet, sepolia } from '@wagmi/core' // [!code --] +import { mainnet, sepolia } from '@wagmi/core/chains' // [!code ++] +``` + +## Errors + +A number of errors were renamed to better reflect their functionality or replaced by Viem errors. + +## Miscellaneous + +### Removed internal ENS normalization + +Before v2, Wagmi handled ENS name normalization internally for `getEnsAddress`, `getEnsAvatar`, and `getEnsResolver`, using Viem's [`normalize`](https://viem.sh/docs/ens/utilities/normalize.html) function. This added extra bundle size as full normalization is quite heavy. For v2, you must normalize ENS names yourself before passing them to these actions. You can use Viem's `normalize` function or any other function that performs [UTS-46 normalization](https://unicode.org/reports/tr46). + + +::: code-group +```ts [index.ts] +import { getEnsAddress } from '@wagmi/core' +import { normalize } from 'viem' // [!code ++] +import { config } from './config' + +const result = await getEnsAddress(config, { + name: 'wevm.eth', // [!code --] + name: normalize('wevm.eth'), // [!code ++] +}) +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +By inverting control, Wagmi lets you choose how much normalization to do. For example, maybe your project only allows ENS names that are numeric so no normalization is not needed. Check out the [ENS documentation](https://docs.ens.domains/contract-api-reference/name-processing#normalising-names) for more information on normalizing names. + +### Removed `configureChains` + +The Wagmi v2 `Config` now has native multichain support using the [`chains`](/core/api/createConfig) parameter so the `configureChains` function is no longer required. + +```ts +import { configureChains, createConfig } from '@wagmi/core' // [!code --] +import { http, createConfig } from '@wagmi/core' // [!code ++] +import { mainnet, sepolia } from '@wagmi/core/chains' + +const { chains, publicClient } = configureChains( // [!code --] + [mainnet, sepolia], // [!code --] + [publicProvider(), publicProvider()], // [!code --] +) // [!code --] + +export const config = createConfig({ + publicClient, // [!code --] + chains: [mainnet, sepolia], // [!code ++] + transports: { // [!code ++] + [mainnet.id]: http(), // [!code ++] + [sepolia.id]: http(), // [!code ++] + }, // [!code ++] +}) +``` + +### Removed ABI exports + +Import from Viem instead. + +```ts +import { erc20ABI } from '@wagmi/core' // [!code --] +import { erc20Abi } from 'viem' // [!code ++] +``` + +### Removed `'@wagmi/core/providers/*` entrypoints + +It never made sense that we would have provider URLs hardcoded in the Wagmi codebase. Use [Viem transports](https://viem.sh/docs/clients/intro.html#transports) along with RPC provider URLs instead. + +```ts +import { alchemyProvider } from '@wagmi/core/providers/alchemy' // [!code --] +import { http } from 'viem' // [!code ++] + +const transport = http('https://mainnet.example.com') +``` + +### Updated `createConfig` parameters + +- Removed `autoConnect`. The reconnecting behavior must be managed manually and is not related to the Wagmi `Config`. Use the [`reconnect`](/core/api/actions/reconnect) action instead. +- Removed `publicClient` and `webSocketPublicClient`. Use [`transports`](/core/api/createConfig#transports) or [`client`](/core/api/createConfig#client) instead. +- Removed `logger`. Wagmi no longer logs debug information to console. + +### Updated `Config` object + +- Removed `config.connector`. Use `config.state.connections.get(config.state.current)?.connector` instead. +- Removed `config.data`. Use `config.state.connections.get(config.state.current)` instead. +- Removed `config.error`. Was unused and not needed. +- Removed `config.lastUsedChainId`. Use `config.state.connections.get(config.state.current)?.chainId` instead. +- Removed `config.publicClient`. Use [`config.getClient()`](/core/api/createConfig#getclient) or [`getPublicClient`](/core/api/actions/getPublicClient) instead. +- Removed `config.status`. Use [`config.state.status`](/core/api/createConfig#status) instead. +- Removed `config.webSocketClient`. Use [`config.getClient()`](/core/api/createConfig#getclient) or [`getPublicClient`](/core/api/actions/getPublicClient) instead. +- Removed `config.clearState`. Was unused and not needed. +- Removed `config.autoConnect()`. Use [`reconnect`](/core/api/actions/reconnect) action instead. +- Renamed `config.setConnectors`. Use `config._internal.setConnectors` instead. +- Removed `config.setLastUsedConnector`. Use `config.storage?.setItem('recentConnectorId', connectorId)` instead. +- Removed `getConfig`. `config` should be passed explicitly to actions instead of using global `config`. + +## Deprecations + +### Deprecated `getBalance` `token` parameter + +Moving forward, `getBalance` will only work for native currencies, thus the `token` parameter is no longer supported. Use [`readContracts`](/core/api/actions/readContracts) instead. + +```ts +import { getBalance } from '@wagmi/core' // [!code --] +import { readContracts } from '@wagmi/core' // [!code ++] +import { erc20Abi } from 'viem' // [!code ++] +import { config } from './config' // [!code ++] + +const result = await getBalance(config, { // [!code --] + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', // [!code --] + token: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code --] +}) // [!code --] +const result = await readContracts(config, { // [!code ++] + allowFailure: false, // [!code ++] + contracts: [ // [!code ++] + { // [!code ++] + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code ++] + abi: erc20Abi, // [!code ++] + functionName: 'balanceOf', // [!code ++] + args: ['0x4557B18E779944BFE9d78A672452331C186a9f48'], // [!code ++] + }, // [!code ++] + { // [!code ++] + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code ++] + abi: erc20Abi, // [!code ++] + functionName: 'decimals', // [!code ++] + }, // [!code ++] + { // [!code ++] + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code ++] + abi: erc20Abi, // [!code ++] + functionName: 'symbol', // [!code ++] + }, // [!code ++] + ] // [!code ++] +}) // [!code ++] +``` + +### Deprecated `getBalance` `unit` parameter and `formatted` return value + +Moving forward, `getBalance` will not accept the `unit` parameter or return a `formatted` value. Instead you can call `formatUnits` from Viem directly or use another number formatting library, like [dnum](https://github.com/bpierre/dnum) instead. + +```ts +import { formatUnits } from 'viem' // [!code ++] +import { getBalance } from '@wagmi/core' + +const result = await getBalance({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + unit: 'ether', // [!code --] +}) +result.formatted // [!code --] +formatUnits(result.value, result.decimals) // [!code ++] +``` + +### Deprecated `getToken` + +Moving forward, `getToken` is no longer supported. Use [`readContracts`](/core/api/actions/readContracts) instead. + +```ts +import { getToken } from '@wagmi/core' // [!code --] +import { readContracts } from '@wagmi/core' // [!code ++] +import { erc20Abi } from 'viem' // [!code ++] +import { config } from './config' // [!code ++] + +const result = await getToken(config, { // [!code --] + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code --] +}) // [!code --] +const result = await readContracts(config, { // [!code ++] + allowFailure: false, // [!code ++] + contracts: [ // [!code ++] + { // [!code ++] + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code ++] + abi: erc20Abi, // [!code ++] + functionName: 'decimals', // [!code ++] + }, // [!code ++] + { // [!code ++] + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code ++] + abi: erc20Abi, // [!code ++] + functionName: 'name', // [!code ++] + }, // [!code ++] + { // [!code ++] + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code ++] + abi: erc20Abi, // [!code ++] + functionName: 'symbol', // [!code ++] + }, // [!code ++] + { // [!code ++] + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code ++] + abi: erc20Abi, // [!code ++] + functionName: 'totalSupply', // [!code ++] + }, // [!code ++] + ] // [!code ++] +}) // [!code ++] +``` + +### Deprecated `formatUnits` parameters and return values + +The `formatUnits` parameter and related return values (e.g. `result.formatted`) are deprecated for the following actions: + +- [`estimateFeesPerGas`](/core/api/actions/estimateFeesPerGas) +- [`getToken`](/core/api/actions/getToken) + +Instead you can call `formatUnits` from Viem directly or use another number formatting library, like [dnum](https://github.com/bpierre/dnum) instead. + +```ts +import { formatUnits } from 'viem' // [!code ++] +import { getToken } from '@wagmi/core' + +const result = await getToken({ + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + formatUnits: 'ether', +}) +result.totalSupply.formatted // [!code --] +formatUnits(result.totalSupply.value, 18) // [!code ++] +``` + +This allows us to invert control to users so they can handle number formatting however they want, taking into account precision, localization, and more. + +### Renamed actions + +The following actions were renamed to better reflect their functionality and underlying [Viem](https://viem.sh) actions: + +- `fetchBalance` is now [`getBalance`](/core/api/actions/getBalance) +- `fetchBlockNumber` is now [`getBlockNumber`](/core/api/actions/getBlockNumber) +- `fetchEnsAddress` is now [`getEnsAddress`](/core/api/actions/getEnsAddress) +- `fetchEnsAvatar` is now [`getEnsAvatar`](/core/api/actions/getEnsAvatar) +- `fetchEnsName` is now [`getEnsName`](/core/api/actions/getEnsName) +- `fetchEnsResolver` is now [`getEnsResolver`](/core/api/actions/getEnsResolver) +- `fetchToken` is now [`getToken`](/core/api/actions/getToken) +- `fetchTransaction` is now [`getTransaction`](/core/api/actions/getTransaction) +- `switchNetwork` is now [`switchChain`](/core/api/actions/switchChain) +- `waitForTransaction` is now [`waitForTransactionReceipt`](/core/api/actions/waitForTransactionReceipt) diff --git a/wagmi-project/site/core/guides/testing.md b/wagmi-project/site/core/guides/testing.md new file mode 100644 index 0000000000..383062dbea --- /dev/null +++ b/wagmi-project/site/core/guides/testing.md @@ -0,0 +1,3 @@ +# Testing + + diff --git a/wagmi-project/site/core/guides/viem.md b/wagmi-project/site/core/guides/viem.md new file mode 100644 index 0000000000..275ed86949 --- /dev/null +++ b/wagmi-project/site/core/guides/viem.md @@ -0,0 +1,197 @@ +# Viem + +[Viem](https://viem.sh) is a low-level TypeScript Interface for Ethereum that enables developers to interact with the Ethereum blockchain, including: JSON-RPC API abstractions, Smart Contract interaction, wallet & signing implementations, coding/parsing utilities and more. + +**Wagmi Core** is essentially a wrapper over **Viem** that provides multi-chain functionality via [Wagmi Config](/core/api/createConfig) and automatic account management via [Connectors](/core/api/connectors). + +## Leveraging Viem Actions + +All of the core [Wagmi Actions](/core/api/actions) are friendly wrappers around [Viem Actions](https://viem.sh/docs/actions/public/introduction.html) that inject a multi-chain and connector aware [Wagmi Config](/core/api/createConfig). + +There may be cases where you might want to dig deeper and utilize Viem Actions directly (maybe an Action doesn't exist in Wagmi yet). In these cases, you can import Viem Actions directly via `viem/actions` and plug in a Viem Client returned by the [`getClient` Action](/core/api/actions/getClient). + +The example below demonstrates two different ways to utilize Viem Actions: + +1. **Tree-shakable Actions (recommended):** Uses `getClient` (for public actions) and `getConnectorClient` (for wallet actions). +2. **Client Actions:** Uses `getPublicClient` (for public actions) and `getWalletClient` (for wallet actions). + +::: tip + +It is highly recommended to use the **tree-shakable** method to ensure that you are only pulling modules you use, and keep your bundle size low. + +::: + +::: code-group + +```tsx [Tree-shakable Actions] +// 1. Import modules. +import { http, createConfig, getClient, getConnectorClient } from '@wagmi/core' +import { base, mainnet, optimism, zora } from '@wagmi/core/chains' +import { getLogs, watchAsset } from 'viem/actions' // [!code hl] + +// 2. Set up a Wagmi Config +export const config = createConfig({ + chains: [base, mainnet, optimism, zora], + transports: { + [base.id]: http(), + [mainnet.id]: http(), + [optimism.id]: http(), + [zora.id]: http(), + }, +}) + +// 3. Extract a Viem Client for the current active chain. +const publicClient = getClient(config) +const logs = await getLogs(publicClient, /* ... */) // [!code hl] + +// 4. Extract a Viem Client for the current active chain & account. +const walletClient = getConnectorClient(config) +const success = await watchAsset(walletClient, /* ... */) // [!code hl] +``` + +```tsx [Client Actions] +// 1. Import modules. +import { http, createConfig, getPublicClient, getWalletClient } from '@wagmi/core' +import { base, mainnet, optimism, zora } from '@wagmi/core/chains' + +// 2. Set up a Wagmi Config +export const config = createConfig({ + chains: [base, mainnet, optimism, zora], + transports: { + [base.id]: http(), + [mainnet.id]: http(), + [optimism.id]: http(), + [zora.id]: http(), + }, +}) + +// 3. Extract a Viem Public Client for the current active chain. +const publicClient = getPublicClient(config) +const logs = await publicClient.getLogs(publicClient, /* ... */) // [!code hl] + +// 4. Extract a Viem Wallet Client for the current active chain & account. +const walletClient = getWalletClient(config) +const success = await walletClient.watchAsset(walletClient, /* ... */) // [!code hl] +``` + +::: + +## Multi-chain Viem Client + +The [Viem Client](https://viem.sh/docs/client) provides an interface to interact with an JSON-RPC Provider. By nature, JSON-RPC Providers are single-chain, so the Viem Client is designed to be instantiated with a single `chain`. As a result, setting up Viem to be multi-chain aware can get a bit verbose. + +The good news is that you can create a **"multi-chain Viem Client"** with **Wagmi** by utilizing [`createConfig`](/core/api/createConfig) and [`getClient`](/core/api/actions/getClient). + +::: code-group + +```tsx [Wagmi Usage] +// 1. Import modules. +import { http, createConfig, getClient, getConnectorClient } from '@wagmi/core' +import { base, mainnet, optimism, zora } from '@wagmi/core/chains' +import { getBlockNumber, sendTransaction } from 'viem/actions' // [!code hl] + +// 2. Set up a Wagmi Config +export const config = createConfig({ + chains: [base, mainnet, optimism, zora], + transports: { + [base.id]: http(), + [mainnet.id]: http(), + [optimism.id]: http(), + [zora.id]: http(), + }, +}) + +// 3. Extract a Viem Client for the current active chain. +const publicClient = getClient(config) +const blockNumber = await getBlockNumber(publicClient) // [!code hl] + +// 4. Extract a Viem Client for the current active chain & account. +const walletClient = getConnectorClient(config) +const hash = await sendTransaction(walletClient, /* ... */) // [!code hl] +``` + +```tsx [Viem Usage] +// Manually set up Viem Clients without wagmi. Don't do this, it's only here +// to demonstrate the amount of boilerplate required. + +import { createPublicClient, createWalletClient, http } from 'viem' +import { base, mainnet, optimism, zora } from 'viem/chains' + +const publicClient = { + base: createPublicClient({ + chain: base, + transport: http() + }), + mainnet: createPublicClient({ + chain: mainnet, + transport: http() + }), + optimism: createPublicClient({ + chain: optimism, + transport: http() + }), + zora: createPublicClient({ + chain: zora, + transport: http() + }) +} as const + +const walletClient = { + base: createWalletClient({ + chain: base, + transport: custom(window.ethereum) + }), + mainnet: createWalletClient({ + chain: mainnet, + transport: custom(window.ethereum) + }), + optimism: createWalletClient({ + chain: optimism, + transport: custom(window.ethereum) + }), + zora: createWalletClient({ + chain: zora, + transport: custom(window.ethereum) + }) +} as const + +const blockNumber = await publicClient.mainnet.getBlockNumber() +const hash = await walletClient.mainnet.sendTransaction(/* ... */) +``` + +::: + +## Private Key & Mnemonic Accounts + +It is possible to utilize Viem's [Private Key & Mnemonic Accounts](https://viem.sh/docs/accounts/local.html) with Wagmi by explicitly passing through the account via the `account` argument on Wagmi Actions. + +```tsx +import { http, createConfig, sendTransaction } from '@wagmi/core' +import { base, mainnet, optimism, zora } from '@wagmi/core/chains' +import { parseEther } from 'viem' +import { privateKeyToAccount } from 'viem/accounts' + +export const config = createConfig({ + chains: [base, mainnet, optimism, zora], + transports: { + [base.id]: http(), + [mainnet.id]: http(), + [optimism.id]: http(), + [zora.id]: http(), + }, +}) + +const account = privateKeyToAccount('0x...') // [!code hl] + +const hash = await sendTransaction({ + account, // [!code hl] + to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + value: parseEther('0.001') +}) +``` + +::: info + +Wagmi currently does not support hoisting Private Key & Mnemonic Accounts to the top-level Wagmi Config – meaning you have to explicitly pass through the account to every Action. If you feel like this is a feature that should be added, please [open a discussion](https://github.com/wevm/wagmi/discussions/new?category=ideas). + +::: diff --git a/wagmi-project/site/core/installation.md b/wagmi-project/site/core/installation.md new file mode 100644 index 0000000000..858ebc6879 --- /dev/null +++ b/wagmi-project/site/core/installation.md @@ -0,0 +1,52 @@ + + +# Installation + +Install Wagmi Core via your package manager, a ` +``` + + diff --git a/wagmi-project/site/core/typescript.md b/wagmi-project/site/core/typescript.md new file mode 100644 index 0000000000..e41d942828 --- /dev/null +++ b/wagmi-project/site/core/typescript.md @@ -0,0 +1,241 @@ + + +# TypeScript + +## Requirements + +Wagmi Core is designed to be as type-safe as possible! Things to keep in mind: + +- Types currently require using TypeScript {{typescriptVersion}}. +- [TypeScript doesn't follow semver](https://www.learningtypescript.com/articles/why-typescript-doesnt-follow-strict-semantic-versioning) and often introduces breaking changes in minor releases. +- Changes to types in this repository are considered non-breaking and are usually released as patch changes (otherwise every type enhancement would be a major version!). +- It is highly recommended that you lock your `@wagmi/core` and `typescript` versions to specific patch releases and upgrade with the expectation that types may be fixed or upgraded between any release. +- The non-type-related public API of Wagmi Core still follows semver very strictly. + +To ensure everything works correctly, make sure your `tsconfig.json` has [`strict`](https://www.typescriptlang.org/tsconfig#strict) mode set to `true`. + +::: code-group +```json [tsconfig.json] +{ + "compilerOptions": { + "strict": true + } +} +``` +::: + +## Const-Assert ABIs & Typed Data + +Wagmi Core can infer types based on [ABIs](https://docs.soliditylang.org/en/latest/abi-spec.html#json) and [EIP-712](https://eips.ethereum.org/EIPS/eip-712) Typed Data definitions, powered by [Viem](https://viem.sh) and [ABIType](https://github.com/wevm/abitype). This achieves full end-to-end type-safety from your contracts to your frontend and enlightened developer experience by autocompleting ABI item names, catching misspellings, inferring argument and return types (including overloads), and more. + +For this to work, you must either [const-assert](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions) ABIs and Typed Data (more info below) or define them inline. For example, `useReadContract`'s `abi` configuration parameter: + +```ts +const result = await readContract({ + abi: […], // <--- defined inline // [!code focus] +}) +``` + +```ts +const abi = […] as const // <--- const assertion // [!code focus] +const result = readContract({ abi }) +``` + +If type inference isn't working, it's likely you forgot to add a `const` assertion or define the configuration parameter inline. Also, make sure your ABIs, Typed Data definitions, and [TypeScript configuration](#requirements) are valid and set up correctly. + +::: tip +Unfortunately [TypeScript doesn't support importing JSON `as const` yet](https://github.com/microsoft/TypeScript/issues/32063). Check out the [Wagmi CLI](/cli/getting-started) to help with this! It can automatically fetch ABIs from Etherscan and other block explorers, resolve ABIs from your Foundry/Hardhat projects, and more. +::: + +Anywhere you see the `abi` or `types` configuration property, you can likely use const-asserted or inline ABIs and Typed Data to get type-safety and inference. These properties are also called out in the docs. + +Here's what [`readContract`](/core/api/actions/readContract) looks like with and without a const-asserted `abi` property. + +::: code-group +```ts twoslash [Const-Asserted] +import { createConfig, http } from '@wagmi/core' +import { mainnet, sepolia } from '@wagmi/core/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) + +const erc721Abi = [ + { + name: 'balanceOf', + type: 'function', + stateMutability: 'view', + inputs: [{ type: 'address', name: 'owner' }], + outputs: [{ type: 'uint256' }], + }, + { + name: 'isApprovedForAll', + type: 'function', + stateMutability: 'view', + inputs: [ + { type: 'address', name: 'owner' }, + { type: 'address', name: 'operator' }, + ], + outputs: [{ type: 'bool' }], + }, + { + name: 'getApproved', + type: 'function', + stateMutability: 'view', + inputs: [{ type: 'uint256', name: 'tokenId' }], + outputs: [{ type: 'address' }], + }, + { + name: 'ownerOf', + type: 'function', + stateMutability: 'view', + inputs: [{ type: 'uint256', name: 'tokenId' }], + outputs: [{ type: 'address' }], + }, + { + name: 'tokenURI', + type: 'function', + stateMutability: 'pure', + inputs: [{ type: 'uint256', name: 'tokenId' }], + outputs: [{ type: 'string' }], + }, +] as const +// ---cut--- +import { readContract } from '@wagmi/core' + +const result = await readContract(config, { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi: erc721Abi, + functionName: 'balanceOf', + // ^? + + + + args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e'], + // ^? +}) + +result +// ^? +``` +```ts twoslash [Not Const-Asserted] +import { createConfig, http } from '@wagmi/core' +import { mainnet, sepolia } from '@wagmi/core/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) + +declare const erc721Abi: { + name: string; + type: string; + stateMutability: string; + inputs: { + type: string; + name: string; + }[]; + outputs: { + type: string; + }[]; +}[] +// ---cut--- +import { readContract } from '@wagmi/core' + +const result = await readContract(config, { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi: erc721Abi, + functionName: 'balanceOf', + // ^? + + + + args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e'], + // ^? +}) + +result +// ^? +``` +::: + +You can prevent runtime errors and be more productive by making sure your ABIs and Typed Data definitions are set up appropriately. šŸŽ‰ + +```ts twoslash +// @errors: 2820 +import { createConfig, http } from '@wagmi/core' +import { mainnet, sepolia } from '@wagmi/core/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) + +const erc721Abi = [ + { + name: 'balanceOf', + type: 'function', + stateMutability: 'view', + inputs: [{ type: 'address', name: 'owner' }], + outputs: [{ type: 'uint256' }], + }, + { + name: 'isApprovedForAll', + type: 'function', + stateMutability: 'view', + inputs: [ + { type: 'address', name: 'owner' }, + { type: 'address', name: 'operator' }, + ], + outputs: [{ type: 'bool' }], + }, + { + name: 'getApproved', + type: 'function', + stateMutability: 'view', + inputs: [{ type: 'uint256', name: 'tokenId' }], + outputs: [{ type: 'address' }], + }, + { + name: 'ownerOf', + type: 'function', + stateMutability: 'view', + inputs: [{ type: 'uint256', name: 'tokenId' }], + outputs: [{ type: 'address' }], + }, + { + name: 'tokenURI', + type: 'function', + stateMutability: 'pure', + inputs: [{ type: 'uint256', name: 'tokenId' }], + outputs: [{ type: 'string' }], + }, +] as const +// ---cut--- +import { readContract } from '@wagmi/core' + +readContract(config, { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi: erc721Abi, + functionName: 'balanecOf', + args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e'], +}) +``` + +## Configure Internal Types + +For advanced use-cases, you may want to configure wagmi's internal types. Most of wagmi's types relating to ABIs and EIP-712 Typed Data are powered by [ABIType](https://github.com/wevm/abitype). See the [ABIType docs](https://abitype.dev) for more info on how to configure types. diff --git a/wagmi-project/site/core/why.md b/wagmi-project/site/core/why.md new file mode 100644 index 0000000000..d7ed951f02 --- /dev/null +++ b/wagmi-project/site/core/why.md @@ -0,0 +1,46 @@ +# Why Wagmi Core + +## The Problems + +Building Ethereum applications is hard. Apps need to support connecting wallets, multiple chains, signing messages and data, sending transactions, listening for events and state changes, refreshing stale blockchain data, and much more. This is all on top of solving for app-specific use-cases and providing polished user experiences. + +The ecosystem is also continuously evolving, meaning you need to adapt to new improvements or get left behind. App developers should not need to worry about connecting tens of different wallets, the intricacies of multi-chain support, typos accidentally sending an order of magnitude more ETH or calling a misspelled contract function, or accidentally spamming their RPC provider, costing thousands in compute units. + +Wagmi Core solves all these problems and more — allowing app developers to focus on building high-quality and performant experiences for Ethereum — by focusing on **developer experience**, **performance**, **feature coverage**, and **stability.** + +## Developer Experience + +Wagmi Core delivers a great developer experience through modular and composable APIs, automatic type safety and inference, and comprehensive documentation. + +It provides developers with intuitive building blocks to build their Ethereum apps. While Wagmi Core's APIs might seem more verbose at first, it makes Wagmi Core's modular building blocks extremely flexible. Easy to move around, change, and remove. It also allows developers to better understand Ethereum concepts as well as understand _what_ and _why_ certain properties are being passed through. Learning how to use Wagmi Core is a great way to learn how to interact with Ethereum in general. + +Wagmi Core also provides [strongly typed APIs](/core/typescript), allowing consumers to get the best possible experience through [autocomplete](https://twitter.com/awkweb/status/1555678944770367493), [type inference](https://twitter.com/jakemoxey/status/1570244174502588417?s=20), as well as static validation. You often just need to provide an ABI and Wagmi Core can help you autocomplete your way to success, identify type errors before your users do, drill into blockchain errors [at compile and runtimes](/core/guides/error-handling) with surgical precision, and much more. + +The API documentation is comprehensive and contains usage info for _every_ module in Wagmi Core. The core team uses a [documentation](https://gist.github.com/zsup/9434452) and [test driven](https://en.wikipedia.org/wiki/Test-driven_development#:~:text=Test%2Ddriven%20development%20(TDD),software%20against%20all%20test%20cases.) development approach to building modules, which leads to predictable and stable APIs. + +## Performance + +Performance is critical for applications on all sizes. Slow page load and interactions can cause users to stop using applications. Wagmi Core uses and is built by the same team behind [Viem](https://viem.sh), the most performant production-ready Ethereum library. + +End users should not be required to download a module of over 100kB in order to interact with Ethereum. Wagmi Core is optimized for tree-shaking and dead-code elimination, allowing apps to minimize bundle size for fast page load times. + +Data layer performance is also critical. Slow, unnecessary, and manual data fetching can make apps unusable and cost thousands in RPC compute units. Wagmi Core supports caching, deduplication, persistence, and much more through [TanStack Query](/react/guides/tanstack-query) via the `'@wagmi/core/query'` entrypoint so you can [plug it into your framework](/core/guides/framework-adapters) of choice, like Vue, Svelte, and more. + +## Feature Coverage + +Wagmi Core supports the most popular and commonly-used Ethereum features out of the box with 40+ VanillaJS Actions for accounts, wallets, contracts, transactions, signing, ENS, and more. Wagmi Core also supports just about any wallet out there through its official [connectors](/core/api/connectors), [EIP-6963 support](/core/api/createConfig#multiinjectedproviderdiscovery), and [extensible API](/dev/creating-connectors). + +If you need lower-level control, you can always drop down to [Viem](https://viem.sh), which Wagmi Core uses internally to perform blockchain operations. Wagmi Core also manages multi-chain support automatically so developers can focus on their applications instead of adding custom code. + +Finally, Wagmi Core has a [CLI](/cli/getting-started) to manage ABIs as well as a robust ecosystem of third-party libraries, like [ConnectKit](https://docs.family.co/connectkit), [RainbowKit](https://www.rainbowkit.com), [AppKit](https://walletconnect.com/appkit), [Dynamic](https://www.dynamic.xyz), [Privy](https://privy.io), and many more, so you can get started quickly without needing to build everything from scratch. + +## Stability + +Stability is a fundamental principle for Wagmi Core. Many organizations, large and small, rely heavily on Wagmi Core and expect it to be entirely stable for their users and applications. + +Wagmi Core's test suite runs against forked Ethereum nodes to make sure functions work across chains. The test suite also runs type tests against many different versions of peer dependencies, like TypeScript, to ensure compatibility with the latest releases of other popular software. + +Wagmi Core follows semver so developers can upgrade between versions with confidence. Starting with Wagmi Core v2, new functionality will be opt-in with old functionality being deprecated alongside the new features. This means upgrading to the latest major versions will not require immediate changes. + +Lastly, the core team works full-time on Wagmi Core and [related projects](https://github.com/wevm), and is constantly improving Wagmi Core and keeping it up-to-date with industry trends and changes. + diff --git a/wagmi-project/site/dev/contributing.md b/wagmi-project/site/dev/contributing.md new file mode 100644 index 0000000000..f5c0d8335a --- /dev/null +++ b/wagmi-project/site/dev/contributing.md @@ -0,0 +1,171 @@ + + +# Contributing + +Thanks for your interest in contributing to Wagmi! Please take a moment to review this document **before submitting a pull request.** + +## Overview + +This guide is intended to help you get started with contributing. By following these steps, you will understand the development process and workflow. If you want to contribute, but aren't sure where to start, you can create a [new discussion](https://github.com/wevm/wagmi/discussions/new/choose). + +:::warning +**Please ask first before starting work on any significant new features. This includes things like adding new hooks, actions, connectors, etc.** + +It's never a fun experience to have your pull request declined after investing time and effort into a new feature. To avoid this from happening, we request that contributors first create a [feature request](https://github.com/wevm/wagmi/discussions/new?category=ideas) to discuss any API changes or significant new ideas. +::: + +## 1. Cloning the repository + +To start contributing to the project, clone it to your local machine using git: + +```bash +git clone https://github.com/wevm/wagmi.git +``` + +Or the [GitHub CLI](https://cli.github.com): + +```bash +gh repo clone wevm/wagmi +``` + +## 2. Installing Node.js and pnpm + +Wagmi uses Node.js with [pnpm workspaces](https://pnpm.io/workspaces) to manage multiple projects. You can run the following command in your terminal to check your local Node.js version. + +```bash +node -v +``` + +If **`node@{{nodeVersion}}`** is not installed, you can install via [fnm](https://github.com/Schniz/fnm) or from the [official website](https://nodejs.org). + +Once Node.js is installed, run the following to install [Corepack](https://nodejs.org/api/corepack.html). Corepack automatically installs and manages **`{{packageManager}}`**. + +```bash +corepack enable +``` + +## 3. Installing dependencies + +Once in the project's root directory, run the following command to install pnpm (via Corepack) and the project's dependencies: + +```bash +pnpm install +``` + +After the install completes, pnpm links packages across the project for development and [git hooks](https://github.com/toplenboren/simple-git-hooks) are set up. + +## 4. Adding the env variables + +The [dev playgrounds](#_5-running-the-dev-playgrounds) and [test suite](#_6-running-the-test-suite) require environment variables to be set. Copy over the following environment variables to `.env`, and fill them out. + +```bash +VITE_MAINNET_FORK_URL=https://eth.merkle.io +VITE_OPTIMISM_FORK_URL=https://mainnet.optimism.io + +NEXT_PUBLIC_WC_PROJECT_ID=3fbb6bba6f1de962d911bb5b5c9dba88 +NUXT_PUBLIC_WC_PROJECT_ID=3fbb6bba6f1de962d911bb5b5c9dba88 +VITE_WC_PROJECT_ID=3fbb6bba6f1de962d911bb5b5c9dba88 + +NEXT_TELEMETRY_DISABLED=1 +NUXT_TELEMETRY_DISABLED=1 +``` + +You might want to change `*_FORK_URL` to a paid RPC provider for better performance. + +## 5. Running the dev playgrounds + +To start the local development playgrounds, run one of the following commands. These commands run playground apps, located at `./playgrounds`, that are set up for trying out code while making changes. + +```bash +pnpm dev # `wagmi` playground +pnpm dev:core # `@wagmi/core` playground +pnpm dev:create-wagmi # `create-wagmi` cli tool +pnpm dev:cli # `@wagmi/cli` tool +pnpm dev:next # `wagmi` playground with Next.js +pnpm dev:nuxt # `@wagmi/vue` playground with Nuxt.js +pnpm dev:react # `wagmi` playground (same as `pnpm dev`) +pnpm dev:vue # `@wagmi/vue` playground +``` + +Once a playground dev server is running, you can make changes to any of the package source files (e.g. `packages/react`) and it will automatically update the playground. + +## 6. Running the test suite + +Wagmi uses [Vitest](https://vitest.dev) to run tests and [Prool](https://github.com/wevm/prool) to execute tests against locally running chain forks. First, install [Anvil](https://github.com/foundry-rs/foundry/tree/master/crates/anvil) via [Foundryup](https://book.getfoundry.sh/getting-started/installation). + +```bash +curl -L https://foundry.paradigm.xyz | bash +foundryup +``` + +Next, make sure you have set up your [env variables](#_4-adding-the-env-variables). Now you are ready to run the tests! You have the following options for running tests: + +- `pnpm test [package?]` — runs tests in watch mode +- `pnpm test:cov` — runs tests and reports coverage +- `pnpm test:core` — runs `@wagmi/core` tests +- `pnpm test:react` — runs `wagmi` tests +- `pnpm test:vue` — runs `@wagmi/vue` tests + +When adding new features or fixing bugs, it's important to add test cases to cover the new or updated behavior. If snapshot tests fail, you can run the `test:update` command to update the snapshots. + +## 7. Writing documentation + +Documentation is crucial to helping developers of all experience levels use Wagmi. Wagmi uses [VitePress](https://vitepress.dev) for the documentation site (located at `./site`). To start the site in dev mode, run: + +```bash +pnpm docs:dev +``` + +Try to keep documentation brief and use plain language so folks of all experience levels can understand. If you think something is unclear or could be explained better, you are welcome to open a pull request. + +## 8. Submitting a pull request + +When you're ready to submit a pull request, you can follow these naming conventions: + +- Pull request titles use the [Imperative Mood](https://en.wikipedia.org/wiki/Imperative_mood) (e.g., `Add something`, `Fix something`). +- [Changesets](#versioning) use past tense verbs (e.g., `Added something`, `Fixed something`). + +When you submit a pull request, GitHub will automatically lint, build, and test your changes. If you see an āŒ, it's most likely a bug in your code. Please, inspect the logs through the GitHub UI to find the cause. + +**Please make sure that "Allow edits from maintainers" is enabled so the core team can make updates to your pull request if necessary.** + +## 9. Versioning + +When adding new features or fixing bugs, we'll need to bump the package versions. We use [Changesets](https://github.com/changesets/changesets) to do this. + +::: tip +Only changes to the codebase that affect the public API or existing behavior (e.g. bugs) need changesets. +::: + +Each changeset defines which packages should be published and whether the change should be a major/minor/patch release, as well as providing release notes that will be added to the changelog upon release. + +To create a new changeset, run `pnpm changeset`. This will run the Changesets CLI, prompting you for details about the change. You’ll be able to edit the file after it’s created — don’t worry about getting everything perfect up front. + +Even though you can technically use any markdown formatting you like, headings should be avoided since each changeset will ultimately be nested within a bullet list. Instead, bold text should be used as section headings. + +If your PR is making changes to an area that already has a changeset (e.g. there’s an existing changeset covering theme API changes but you’re making further changes to the same API), you should update the existing changeset in your PR rather than creating a new one. + +### Releasing to npm + +The first time a PR with a changeset is merged after a release, a new PR will automatically be created called `chore: version packages`. Any subsequent PRs with changesets will automatically update this existing version packages PR. Merging this PR triggers the release process by publishing to npm and cleaning up the changeset files. + +### Creating a snapshot release + +If a PR has changesets, you can create a [snapshot release](https://github.com/changesets/changesets/blob/main/docs/snapshot-releases.md) by [manually dispatching](https://github.com/wevm/wagmi/actions/workflows/canary.yml) the Canary workflow. This publishes a tagged version to npm with the PR branch name and timestamp. + +## 10. Updating dependencies + +Use [Taze](https://github.com/antfu/taze) by running: + +```bash +pnpm deps # prints outdated deps +pnpm deps patch # print outdated deps with new patch versions +pnpm deps -w # updates deps (best done with clean working tree) +``` + +[Socket](https://socket.dev) checks pull requests for vulnerabilities when new dependencies and versions are added, but you should also be vigilant! When updating dependencies, you should check release notes and source code as well as lock versions when possible. diff --git a/wagmi-project/site/dev/creating-connectors.md b/wagmi-project/site/dev/creating-connectors.md new file mode 100644 index 0000000000..c9e82b04b1 --- /dev/null +++ b/wagmi-project/site/dev/creating-connectors.md @@ -0,0 +1,155 @@ +# Creating Connectors + +Thanks for your interest in adding a new connector to Wagmi! Please take a moment to review this document **before starting work on a new connector.** + +## Overview + +This guide details how to create new connectors and upstream them back into Wagmi. By following these steps, you will understand the development process, workflow, and requirements for new connectors. **Not all connectors will be accepted into Wagmi** for a variety of reasons outlined in this document. + +In addition, for connector requests to be accepted, the team creating the connector must [sponsor Wagmi](https://github.com/sponsors/wevm). It takes time and effort to maintain third-party connectors. Wagmi is an OSS project that depends on sponsors and grants to continue our work. Please get in touch via [dev@wevm.dev](mailto:dev@wevm.dev) if you have questions about sponsoring. + +::: warning **Please ask first before starting work on a new connector.** +To avoid having your pull request declined after investing time and effort into a new connector, we ask that contributors create a [Connector Request](https://github.com/wevm/wagmi/discussions/new?category=connector-request) before starting work. This ensures the connector solves for an important or general use-case of interest to Wagmi users and is well supported by the Wagmi and connector teams. +::: + +## 1. Follow the contributing guide + +Check out the [Contributing Guide](/dev/contributing) to get your local development environment set up and learn more about the contributing workflow. + +## 2. Create a new file for the connector + +Create a new file in `packages/connector/src` named after the connector you want to add. + +For example, if you want to add Foo, you would create a file named `foo.ts`. File names should be camel-cased and as short as possible. + +## 3. Create the connector object. + +Import `createConnector` from `@wagmi/core` and export a new function that accepts a parameters object and returns the `createConnector` result. This is the base of all connectors. The name of the connector name should be the same as the file name. + +```ts +import { createConnector } from '@wagmi/core' + +export type FooBarBazParameters = {} + +export function fooBarBaz(parameters: FooBarBazParameters = {}) { + return createConnector((config) => ({})) +} +``` + +## 4. Add the missing properties to the object + +Now that the base of the connector is set up, you should see a type error that looks something like this: + +```ts twoslash +// @errors: 2740 +import { createConnector } from '@wagmi/core' +// ---cut--- +createConnector((config) => ({})) +``` + +The type error tells you what properties are missing from `createConnector`'s return type. Add them all in! + +#### Properties + +- `icon`: Optional icon URL for the connector. +- `id`: The ID for the connector. This should be camel-cased and as short as possible. Example: `fooBarBaz`. +- `name`: Human-readable name for the connector. Example: `'Foo Bar Baz'`. +- `rdns`: Optional reverse DNS for the connector. This is used to filter out duplicate [EIP-6963](https://eips.ethereum.org/EIPS/eip-6963) injected providers when `createConfig#multiInjectedProviderDiscovery` is enabled. + +#### Methods + +- `connect`: Function for connecting the connector. +- `disconnect`: Function for disconnecting the connector. +- `getAccounts`: Function that returns the connected accounts for the connector. +- `getChainId`: Function that returns the connected chain ID for the connector. +- `getProvider`: Function that returns the underlying provider interface for internal use throughout the connector. +- `isAuthorized`: Function that returns whether the connector has connected previously and is still authorized. +- `setup`: Optional function for running when the connector is first created. +- `switchChain`: Optional function for switching the connector's active chain. + +#### Events + +- `onAccountsChanged`: Function for subscribing to account changes internally in the connector. +- `onChainChanged`: Function for subscribing to chain changes internally in the connector. +- `onConnect`: Function for subscribing to connection events internally in the connector. +- `onDisconnect`: Function for subscribing to disconnection events internally in the connector. +- `onMessage`: Optional function for subscribing to messages internally in the connector. + +#### Parameters + +`createConnector` also has the following config properties you can use within the connector: + +- `chains`: List of chains configured by the user. +- `emitter`: Emitter for emitting events. Used to sync connector state with Wagmi `Config`. The following events are available: + - `change`: Emitted when the connected accounts or chain changes. + - `connect`: Emitted when the connector connects. + - `disconnect`: Emitted when the connector disconnects. + - `error`: Emitted when the connector receives an error. + - `message`: Emitted when the connector receives a message. +- `storage`: Optional storage configured by the user. Defaults to wrapper around localStorage. + +::: tip +If you plan to use a third-party SDK, it should have minimal dependencies (limit bundle size, supply chain attacks, etc.) and use the most permissive license possible (ideally MIT). Any third-party packages, should also have [`"sideEffects": false`](https://webpack.js.org/guides/tree-shaking/#mark-the-file-as-side-effect-free) in their `package.json` file for maximum tree-shakability support. +::: + +::: tip +All address values returned and emitted by the connector should be checksummed using Viem's [`getAddress`](https://viem.sh/docs/utilities/getAddress). +::: + +## 5. Export the connector + +Export the connector from `packages/connector/src/exports/index.ts` in alphabetic order. + +```ts +export { fooBarBaz } from './fooBarBaz.js' +``` + +## 6. Try out the connector and add tests + +While building a connector, it can be useful to try it out with Wagmi. You can use the [development playgrounds](/dev/contributing#_5-running-the-dev-playgrounds) for testing your changes. + +Ideally, you should also be able to add tests for the connector in a `connectorName.test.ts` file. This isn't always easy so at a minimum please create a test file with instructions for how to test the connector manually. The test file should include actual tests or "instruction tests" for the following: + +- How to connect the connector. +- How to disconnect the connector. +- How to switch the connector's active chain (if applicable). + +Remember to include all info required to test the connector, like software to install (browser extension, mobile app, etc.), smart contracts to interact with/deploy, etc. + +Finally, you should also update the test file in `packages/connectors/src/exports/index.test.ts` to include the new connector. You can do this manually or by running: + +```bash +pnpm test:update packages/connectors/src/exports/index.test.ts +``` + +## 7. Add your team to CODEOWNERS + +It is critical that connectors are updated in a timely manner and actively maintained so that users of Wagmi can rely on them in production settings. + +The Wagmi core team will provide as much assistance as possible to keep connectors up-to-date with breaking changes from Wagmi, but it is your responsibility to ensure that any dependencies and issues/discussions related to the connector are handled in a timely manner. If issues are not resolved in a timely manner, the connector may be removed from Wagmi. + +In support of this goal, add at least one member of your team to the [CODEOWNERS](https://github.com/wevm/wagmi/blob/main/.github/CODEOWNERS) file so that you get notified of pull requests, issues, etc. related to the connector. You can add your team like this: + +``` +/packages/connectors/src/fooBarBaz @tmm @jxom +``` + +For more info about GitHub code owners, check out the [GitHub Documentation](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners). + +## 8. Document the connector + +The connector should be documented. Follow the step on [writing documentation](/dev/contributing#_7-writing-documentation) to get set up with running the docs site locally and add the required pages. + +## 9. Create a changeset + +Now that the connector works and has tests, it's time to create a changeset to prepare for release. Run the following to create a changeset: + +```bash +pnpm changeset +``` + +The changeset should be a `patch` applied to the `@wagmi/connectors` repository with the description `Added [ConnectorName]`, For example, `Added Foo Bar Baz`. + +## 10. Create a pull request + +The connector is ready to go! Create a [pull request](/dev/contributing#_8-submitting-a-pull-request) and the connector should make it into a future release of Wagmi after some review. diff --git a/wagmi-project/site/index.md b/wagmi-project/site/index.md new file mode 100644 index 0000000000..23b40a7f13 --- /dev/null +++ b/wagmi-project/site/index.md @@ -0,0 +1,58 @@ +--- +# https://vitepress.dev/reference/default-theme-home-page +layout: home + +description: Type Safe, Extensible, and Modular by design. Build high-performance blockchain frontends. +title: 'Wagmi | Reactivity for Ethereum apps' +titleTemplate: false + +hero: + name: Wagmi + text: Reactivity for Ethereum apps + tagline: Type Safe, Extensible, and Modular by design. Build high-performance blockchain frontends. + actions: + - theme: brand + text: Get Started + link: /react/getting-started + - theme: alt + text: Why Wagmi + link: /react/why + - theme: alt + text: View on GitHub + link: https://github.com/wevm/wagmi + image: + src: /logo-dark.svg + alt: Wagmi Logo + +features: + - icon: šŸš€ + title: 20+ React Hooks + details: React Hooks for accounts, wallets, contracts, transactions, signing, ENS, and more. + link: /react/api/hooks + linkText: See all hooks + - icon: šŸ¦„ + title: TypeScript Ready + details: Infer types from ABIs and EIP-712 Typed Data and autocomplete your way to productivity. + link: /react/typescript + linkText: Learn about TypeScript support + - icon: šŸ’¼ + title: Connect Wallet + details: Official connectors for MetaMask, EIP-6963, WalletConnect, Coinbase Wallet, and more. + link: /react/api/connectors + linkText: See all connectors + - icon: šŸ‘Ÿ + title: Caching. Deduplication. Persistence. + details: Built-in caching, deduplication, persistence powered by TanStack Query. + link: /react/guides/tanstack-query + linkText: How to use TanStack Query + - icon: 🌳 + title: Modular By Design + details: Don't use React or Vue? Use VanillaJS or build an adapter for your favorite framework. + link: /core/getting-started + linkText: Learn about Wagmi Core + - icon: āœŒļø + title: Built on Viem + details: The modern, low-level TypeScript interface for Ethereum that performs blockchain operations. + link: https://viem.sh + linkText: Check out Viem +--- diff --git a/wagmi-project/site/package.json b/wagmi-project/site/package.json new file mode 100644 index 0000000000..3bdbb9ba86 --- /dev/null +++ b/wagmi-project/site/package.json @@ -0,0 +1,28 @@ +{ + "name": "site", + "private": true, + "type": "module", + "scripts": { + "dev": "vitepress dev", + "build": "vitepress build", + "preview": "vitepress preview" + }, + "devDependencies": { + "@shikijs/vitepress-twoslash": "1.22.2", + "@tanstack/query-core": "catalog:", + "@tanstack/react-query": "catalog:", + "@tanstack/vue-query": "catalog:", + "@types/react": "catalog:", + "@wagmi/connectors": "workspace:*", + "@wagmi/core": "workspace:*", + "@wagmi/vue": "workspace:*", + "abitype": "*", + "nuxt": "^3.16.0", + "react": "catalog:", + "unocss": "^0.59.4", + "viem": "2.*", + "vitepress": "1.5.0", + "vue": "catalog:", + "wagmi": "workspace:*" + } +} diff --git a/wagmi-project/site/public/browsers/chrome.png b/wagmi-project/site/public/browsers/chrome.png new file mode 100644 index 0000000000..3024356395 Binary files /dev/null and b/wagmi-project/site/public/browsers/chrome.png differ diff --git a/wagmi-project/site/public/browsers/edge.png b/wagmi-project/site/public/browsers/edge.png new file mode 100644 index 0000000000..931cb1c1bf Binary files /dev/null and b/wagmi-project/site/public/browsers/edge.png differ diff --git a/wagmi-project/site/public/browsers/firefox.png b/wagmi-project/site/public/browsers/firefox.png new file mode 100644 index 0000000000..fc7123205a Binary files /dev/null and b/wagmi-project/site/public/browsers/firefox.png differ diff --git a/wagmi-project/site/public/browsers/opera.png b/wagmi-project/site/public/browsers/opera.png new file mode 100644 index 0000000000..472a152348 Binary files /dev/null and b/wagmi-project/site/public/browsers/opera.png differ diff --git a/wagmi-project/site/public/browsers/safari.png b/wagmi-project/site/public/browsers/safari.png new file mode 100644 index 0000000000..aba5f86d1f Binary files /dev/null and b/wagmi-project/site/public/browsers/safari.png differ diff --git a/wagmi-project/site/public/favicon.svg b/wagmi-project/site/public/favicon.svg new file mode 100644 index 0000000000..48c440d660 --- /dev/null +++ b/wagmi-project/site/public/favicon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/wagmi-project/site/public/logo-dark.svg b/wagmi-project/site/public/logo-dark.svg new file mode 100644 index 0000000000..df0c2945ce --- /dev/null +++ b/wagmi-project/site/public/logo-dark.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/wagmi-project/site/public/logo-light.svg b/wagmi-project/site/public/logo-light.svg new file mode 100644 index 0000000000..cc571bc094 --- /dev/null +++ b/wagmi-project/site/public/logo-light.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/wagmi-project/site/public/og.png b/wagmi-project/site/public/og.png new file mode 100644 index 0000000000..8b3a05f556 Binary files /dev/null and b/wagmi-project/site/public/og.png differ diff --git a/wagmi-project/site/react/api/WagmiProvider.md b/wagmi-project/site/react/api/WagmiProvider.md new file mode 100644 index 0000000000..7330f4569b --- /dev/null +++ b/wagmi-project/site/react/api/WagmiProvider.md @@ -0,0 +1,112 @@ +# WagmiProvider + +React Context Provider for Wagmi. + +## Import + +```ts +import { WagmiProvider } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [app.tsx] +import { WagmiProvider } from 'wagmi' +import { config } from './config' + +function App() { + return ( + + {/** ... */} + + ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type WagmiProviderProps } from 'wagmi' +``` + +### config + +[`Config`](/react/api/createConfig#config) object to inject with context. + +::: code-group +```tsx [app.tsx] +import { WagmiProvider } from 'wagmi' +import { config } from './config' + +function App() { + return ( + + {/** ... */} + + ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### initialState + +`State | undefined` + +- Initial state to hydrate into the [Wagmi Config](/react/api/createConfig). Useful for SSR. + +::: code-group +```tsx [app.tsx] +import { WagmiProvider } from 'wagmi' +import { config } from './config' + +function App() { + return ( + + {/** ... */} + + ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### reconnectOnMount + +`boolean | undefined` + +- Whether or not to reconnect previously connected [connectors](/react/api/createConfig#connectors) on mount. +- Defaults to `true`. + +::: code-group +```tsx [app.tsx] +import { WagmiProvider } from 'wagmi' +import { config } from './config' + +function App() { + return ( + + {/** ... */} + + ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Context + +```ts +import { type WagmiContext } from 'wagmi' +``` diff --git a/wagmi-project/site/react/api/actions.md b/wagmi-project/site/react/api/actions.md new file mode 100644 index 0000000000..af367bb025 --- /dev/null +++ b/wagmi-project/site/react/api/actions.md @@ -0,0 +1,28 @@ +# Actions + +Sometimes the declarative nature of React Hooks doesn't work for parts of your app. For those cases, you can use Wagmi Core Actions directly! + +All the Wagmi Core Actions are importable using the `wagmi/actions` entrypoint. For example, you can use the `watchBlockNumber` action to watch for block number changes. + +::: code-group +```ts [index.tsx] +import { useConfig } from 'wagmi' +import { watchBlockNumber } from 'wagmi/actions' +import { useEffect } from 'react' + +function App() { + const config = useConfig() + + useEffect(() => { + return watchBlockNumber(config, { + onBlockNumber(blockNumber) { + console.log('Block number changed!', blockNumber) + }, + }) + }, []) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +See the [Wagmi Core docs](/core/api/actions) for more info on what actions are available. diff --git a/wagmi-project/site/react/api/chains.md b/wagmi-project/site/react/api/chains.md new file mode 100644 index 0000000000..4a7e600447 --- /dev/null +++ b/wagmi-project/site/react/api/chains.md @@ -0,0 +1,26 @@ + + +# Chains + +Viem `Chain` objects. More info at the [Viem docs](https://viem.sh/docs/chains/introduction). + +## Import + +Import via the `'wagmi/chains'` entrypoint (proxies all chains from `'viem/chains'`). + +```ts +import { mainnet } from 'wagmi/chains' +``` + +## Available Chains + +Chain definitions as of `viem@{{viemVersion}}`. For `viem@latest`, visit the [Viem repo](https://github.com/wevm/viem/blob/main/src/chains/index.ts). + + + + diff --git a/wagmi-project/site/react/api/connectors.md b/wagmi-project/site/react/api/connectors.md new file mode 100644 index 0000000000..49096a1641 --- /dev/null +++ b/wagmi-project/site/react/api/connectors.md @@ -0,0 +1,28 @@ + + +# Connectors + +Connectors for popular wallet providers and protocols. + +## Import + +Import via the `'wagmi/connectors'` entrypoint. + +```ts +import { injected } from 'wagmi/connectors' +``` + +## Available Connectors + + diff --git a/wagmi-project/site/react/api/connectors/coinbaseWallet.md b/wagmi-project/site/react/api/connectors/coinbaseWallet.md new file mode 100644 index 0000000000..b8597b11ae --- /dev/null +++ b/wagmi-project/site/react/api/connectors/coinbaseWallet.md @@ -0,0 +1,6 @@ + + + \ No newline at end of file diff --git a/wagmi-project/site/react/api/connectors/injected.md b/wagmi-project/site/react/api/connectors/injected.md new file mode 100644 index 0000000000..56573881f4 --- /dev/null +++ b/wagmi-project/site/react/api/connectors/injected.md @@ -0,0 +1,7 @@ + + + diff --git a/wagmi-project/site/react/api/connectors/metaMask.md b/wagmi-project/site/react/api/connectors/metaMask.md new file mode 100644 index 0000000000..e16d849037 --- /dev/null +++ b/wagmi-project/site/react/api/connectors/metaMask.md @@ -0,0 +1,7 @@ + + + diff --git a/wagmi-project/site/react/api/connectors/mock.md b/wagmi-project/site/react/api/connectors/mock.md new file mode 100644 index 0000000000..3a111297a1 --- /dev/null +++ b/wagmi-project/site/react/api/connectors/mock.md @@ -0,0 +1,6 @@ + + + diff --git a/wagmi-project/site/react/api/connectors/safe.md b/wagmi-project/site/react/api/connectors/safe.md new file mode 100644 index 0000000000..375ddb7b2d --- /dev/null +++ b/wagmi-project/site/react/api/connectors/safe.md @@ -0,0 +1,6 @@ + + + diff --git a/wagmi-project/site/react/api/connectors/walletConnect.md b/wagmi-project/site/react/api/connectors/walletConnect.md new file mode 100644 index 0000000000..3e1a4a5c24 --- /dev/null +++ b/wagmi-project/site/react/api/connectors/walletConnect.md @@ -0,0 +1,6 @@ + + + diff --git a/wagmi-project/site/react/api/createConfig.md b/wagmi-project/site/react/api/createConfig.md new file mode 100644 index 0000000000..f42bec2539 --- /dev/null +++ b/wagmi-project/site/react/api/createConfig.md @@ -0,0 +1,7 @@ + + + diff --git a/wagmi-project/site/react/api/createStorage.md b/wagmi-project/site/react/api/createStorage.md new file mode 100644 index 0000000000..738e998f0b --- /dev/null +++ b/wagmi-project/site/react/api/createStorage.md @@ -0,0 +1,6 @@ + + + diff --git a/wagmi-project/site/react/api/errors.md b/wagmi-project/site/react/api/errors.md new file mode 100644 index 0000000000..d431a6c4fe --- /dev/null +++ b/wagmi-project/site/react/api/errors.md @@ -0,0 +1,20 @@ + + +# Errors + +Error classes used by Wagmi. + + + +## React + +### WagmiProviderNotFoundError + +When a Wagmi hook is used outside of a [`WagmiProvider`](/react/api/WagmiProvider). + +```ts +import { WagmiProviderNotFoundError } from 'wagmi' +``` \ No newline at end of file diff --git a/wagmi-project/site/react/api/hooks.md b/wagmi-project/site/react/api/hooks.md new file mode 100644 index 0000000000..9d8a65c718 --- /dev/null +++ b/wagmi-project/site/react/api/hooks.md @@ -0,0 +1,25 @@ + + +# Hooks + +React Hooks for accounts, wallets, contracts, transactions, signing, ENS, and more. + +## Import + +```ts +import { useAccount } from 'wagmi' +``` + +## Available Hooks + + diff --git a/wagmi-project/site/react/api/hooks/useAccount.md b/wagmi-project/site/react/api/hooks/useAccount.md new file mode 100644 index 0000000000..d5b9e2964c --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useAccount.md @@ -0,0 +1,65 @@ +--- +title: useAccount +description: Hook for getting current account. +--- + +# useAccount + +Hook for getting current account. + +## Import + +```ts +import { useAccount } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useAccount } from 'wagmi' + +function App() { + const account = useAccount() +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseAccountParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useAccount } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const account = useAccount({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type UseAccountReturnType } from 'wagmi' +``` + + + +## Action + +- [`getAccount`](/core/api/actions/getAccount) diff --git a/wagmi-project/site/react/api/hooks/useAccountEffect.md b/wagmi-project/site/react/api/hooks/useAccountEffect.md new file mode 100644 index 0000000000..6636f4bbaa --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useAccountEffect.md @@ -0,0 +1,113 @@ +--- +title: useAccountEffect +description: Hook for listening to account lifecycle events. +--- + +# useAccountEffect + +Hook for listening to account lifecycle events. + +## Import + +```ts +import { useAccountEffect } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useAccountEffect } from 'wagmi' + +function App() { + useAccountEffect({ + onConnect(data) { + console.log('Connected!', data) + }, + onDisconnect() { + console.log('Disconnected!') + }, + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseAccountEffectParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useAccountEffect } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + useAccountEffect({ + config, // [!code focus] + onConnect(data) { + console.log('Connected!', data) + }, + onDisconnect() { + console.log('Disconnected!') + }, + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### onConnect + +`` ((data: { address: `0x${string}`; addresses: readonly [`0x${string}`, ...`0x${string}`[]]; chain: Chain | undefined chainId: number; connector: Connector; isReconnected: boolean }) => void) | undefined `` + +Callback that is called when accounts are connected. + +::: code-group +```tsx [index.tsx] +import { useAccountEffect } from 'wagmi' + +function App() { + useAccountEffect({ + onConnect(data) { // [!code focus] + console.log('Connected!', data) // [!code focus] + }, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### onDisconnect + +`(() => void) | undefined` + +Callback that is called when no more accounts are connected. + +::: code-group +```tsx [index.tsx] +import { useAccountEffect } from 'wagmi' + +function App() { + useAccountEffect({ + onDisconnect() { // [!code focus] + console.log('Disconnected!') // [!code focus] + }, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Action + +- [`getAccount`](/core/api/actions/getAccount) +- [`watchAccount`](/core/api/actions/watchAccount) diff --git a/wagmi-project/site/react/api/hooks/useBalance.md b/wagmi-project/site/react/api/hooks/useBalance.md new file mode 100644 index 0000000000..deddbb720d --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useBalance.md @@ -0,0 +1,226 @@ +--- +title: useBalance +description: Hook for fetching native currency or token balance. +--- + + + +# useBalance + +Hook for fetching native currency or token balance. + +## Import + +```ts +import { useBalance } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useBalance } from 'wagmi' + +function App() { + const result = useBalance({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseBalanceParameters } from 'wagmi' +``` + +### address + +`Address | undefined` + +Address to get balance for. [`enabled`](#enabled) set to `false` if `address` is `undefined`. + +::: code-group +```tsx [index.tsx] +import { useBalance } from 'wagmi' +import { mainnet } from 'wagmi/chains' + +function App() { + const result = useBalance({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +--- + +### blockNumber + +`bigint | undefined` + +Block number to get balance at. + +::: code-group +```ts [index.ts] +import { useBalance } from 'wagmi' + +function App() { + const result = useBalance({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + blockNumber: 17829139n, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get balance at. + +::: code-group +```ts [index.ts] +import { useBalance } from 'wagmi' + +function App() { + const result = useBalance({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + blockTag: 'latest', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useBalance } from 'wagmi' +import { mainnet } from 'wagmi/chains' // [!code focus] + +function App() { + const result = useBalance({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + chainId: mainnet.id, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useBalance } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useBalance({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { useBalance } from 'wagmi' + +function App() { + const result = useBalance({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + scopeKey: 'foo', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### token [deprecated](/react/guides/migrate-from-v1-to-v2#deprecated-usebalance-token-parameter) + +`Address | undefined` + +ERC-20 token address to get balance for. + +::: code-group +```ts [index.ts] +import { useBalance } from 'wagmi' + +function App() { + const result = useBalance({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + token: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### unit [deprecated](/react/guides/migrate-from-v1-to-v2#deprecated-usebalance-unit-parameter-and-formatted-return-value) + +`'ether' | 'gwei' | 'wei' | number | undefined` + +- Units to use when formatting result. +- Defaults to `'ether'`. + +::: code-group +```ts [index.ts] +import { useBalance } from 'wagmi' + +function App() { + const result = useBalance({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + unit: 'ether', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseBalanceReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getBalance`](/core/api/actions/getBalance) diff --git a/wagmi-project/site/react/api/hooks/useBlock.md b/wagmi-project/site/react/api/hooks/useBlock.md new file mode 100644 index 0000000000..f0962ee4c1 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useBlock.md @@ -0,0 +1,227 @@ +--- +title: useBlock +description: Hook for fetching information about a block at a block number, hash or tag. +--- + + + +# useBlock + +Hook for fetching information about a block at a block number, hash or tag. + +## Import + +```ts +import { useBlock } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useBlock } from 'wagmi' + +function App() { + const result = useBlock() +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseBlockParameters } from 'wagmi' +``` + +### blockHash + +`` `0x${string}` `` + +Information at a given block hash. + +::: code-group +```tsx [index.tsx] +import { useBlock } from 'wagmi' + +function App() { + const result = useBlock({ + blockHash: '0x89644bbd5c8d682a2e9611170e6c1f02573d866d286f006cbf517eec7254ec2d' // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockNumber + +`` bigint `` + +Information at a given block number. + +::: code-group +```tsx [index.tsx] +import { useBlock } from 'wagmi' + +function App() { + const result = useBlock({ + blockNumber: 42069n // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`` 'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' `` + +Information at a given block tag. Defaults to `'latest'`. + +::: code-group +```tsx [index.tsx] +import { useBlock } from 'wagmi' + +function App() { + const result = useBlock({ + blockTag: 'pending' // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useBlock } from 'wagmi' +import { mainnet } from 'wagmi/chains' // [!code focus] + +function App() { + const result = useBlock({ + chainId: mainnet.id, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useBlock } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useBlock({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### includeTransactions + +`boolean` + +Whether or not to include transactions as objects. + +::: code-group +```tsx [index.tsx] +import { useBlock } from 'wagmi' +import { config } from './config' + +function App() { + const result = useBlock({ + includeTransactions: true // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { useBlock } from 'wagmi' +import { config } from './config' + +function App() { + const result = useBlock({ + scopeKey: 'foo' // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### watch + +`boolean | UseWatchBlockParameters | undefined` + +- Enables/disables listening for block changes. +- Can pass a subset of [`UseWatchBlocksParameters`](/react/api/hooks/useWatchBlocks#parameters) directly to [`useWatchBlocks`](/react/api/hooks/useWatchBlocks). + +::: code-group +```tsx [index.tsx] +import { useBlock } from 'wagmi' + +function App() { + const result = useBlock({ + watch: true, // [!code focus] + }) +} +``` + +```tsx [index-2.tsx] +import { useBlock } from 'wagmi' + +function App() { + const result = useBlock({ + watch: { // [!code focus] + pollingInterval: 4_000, // [!code focus] + }, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseBlockReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getBlock`](/core/api/actions/getBlock) +- [`watchBlockNumber`](/core/api/actions/watchBlockNumber) diff --git a/wagmi-project/site/react/api/hooks/useBlockNumber.md b/wagmi-project/site/react/api/hooks/useBlockNumber.md new file mode 100644 index 0000000000..e0c6ff7242 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useBlockNumber.md @@ -0,0 +1,169 @@ +--- +title: useBlockNumber +description: Hook for fetching the number of the most recent block seen. +--- + + + +# useBlockNumber + +Hook for fetching the number of the most recent block seen. + +## Import + +```ts +import { useBlockNumber } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useBlockNumber } from 'wagmi' + +function App() { + const result = useBlockNumber() +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseBlockNumberParameters } from 'wagmi' +``` + +### cacheTime + +`number | undefined` + +Time in milliseconds that cached block number will remain in memory. + +::: code-group +```tsx [index.tsx] +import { useBlockNumber } from 'wagmi' + +function App() { + const result = useBlockNumber({ + cacheTime: 4_000, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useBlockNumber } from 'wagmi' +import { mainnet } from 'wagmi/chains' // [!code focus] + +function App() { + const result = useBlockNumber({ + chainId: mainnet.id, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useBlockNumber } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useBlockNumber({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { useBlockNumber } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useBlockNumber({ + scopeKey: 'foo', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### watch + +`boolean | UseWatchBlockNumberParameters | undefined` + +- Enables/disables listening for block number changes. +- Can pass a subset of [`UseWatchBlockNumberParameters`](/react/api/hooks/useWatchBlockNumber#parameters)directly to [`useWatchBlockNumber`](/react/api/hooks/useWatchBlockNumber). + +::: code-group +```tsx [index.tsx] +import { useBlockNumber } from 'wagmi' + +function App() { + const result = useBlockNumber({ + watch: true, // [!code focus] + }) +} +``` + +```tsx [index-2.tsx] +import { useBlockNumber } from 'wagmi' + +function App() { + const result = useBlockNumber({ + watch: { // [!code focus] + pollingInterval: 4_000, // [!code focus] + }, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseBlockNumberReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getBlockNumber`](/core/api/actions/getBlockNumber) +- [`watchBlockNumber`](/core/api/actions/watchBlockNumber) diff --git a/wagmi-project/site/react/api/hooks/useBlockTransactionCount.md b/wagmi-project/site/react/api/hooks/useBlockTransactionCount.md new file mode 100644 index 0000000000..80cb99de32 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useBlockTransactionCount.md @@ -0,0 +1,175 @@ +--- +title: useBlockTransactionCount +description: Hook for fetching the number of Transactions at a block number, hash or tag. +--- + + + +# useBlockTransactionCount + +Hook for fetching the number of Transactions at a block number, hash or tag. + +## Import + +```ts +import { useBlockTransactionCount } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useBlockTransactionCount } from 'wagmi' + +function App() { + const result = useBlockTransactionCount() +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseBlockTransactionCountParameters } from 'wagmi' +``` + +### blockHash + +`` `0x${string}` `` + +Transaction count at a given block hash. + +::: code-group +```tsx [index.tsx] +import { useBlock } from 'wagmi' + +function App() { + const result = useBlock({ + blockHash: '0x89644bbd5c8d682a2e9611170e6c1f02573d866d286f006cbf517eec7254ec2d' // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockNumber + +`` bigint `` + +Transaction count at a given block number. + +::: code-group +```tsx [index.tsx] +import { useBlock } from 'wagmi' + +function App() { + const result = useBlock({ + blockNumber: 42069n // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`` 'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' `` + +Transaction count at a given block tag. Defaults to `'latest'`. + +::: code-group +```tsx [index.tsx] +import { useBlock } from 'wagmi' + +function App() { + const result = useBlock({ + blockTag: 'pending' // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useBlock } from 'wagmi' +import { mainnet } from 'wagmi/chains' // [!code focus] + +function App() { + const result = useBlock({ + chainId: mainnet.id, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useBlockTransactionCount } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useBlockTransactionCount({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { useBlockTransactionCount } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useBlockTransactionCount({ + scopeKey: 'foo', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + + +## Return Type + +```ts +import { type UseBlockTransactionCountReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getBlockTransactionCount`](/core/api/actions/getBlockTransactionCount) diff --git a/wagmi-project/site/react/api/hooks/useBytecode.md b/wagmi-project/site/react/api/hooks/useBytecode.md new file mode 100644 index 0000000000..573cee32c0 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useBytecode.md @@ -0,0 +1,181 @@ +--- +title: useBytecode +description: Hook for retrieving the bytecode at an address. +--- + + + +# useBytecode + +Hook for retrieving the bytecode at an address. + +## Import + +```ts +import { useBytecode } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useBytecode } from 'wagmi' + +function App() { + const result = useBytecode({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseBytecodeParameters } from 'wagmi' +``` + +### address + +`Address | undefined` + +The contract address. + +::: code-group +```tsx [index.tsx] +import { useBytecode } from 'wagmi' + +function App() { + const result = useBytecode({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockNumber + +`bigint | undefined` + +The block number to check the bytecode at. + +::: code-group +```tsx [index.tsx] +import { useBytecode } from 'wagmi' + +function App() { + const result = useBytecode({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + blockNumber: 16280770n, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +The block tag to check the bytecode at. + +::: code-group +```tsx [index.tsx] +import { useBytecode } from 'wagmi' + +function App() { + const result = useBytecode({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + blockTag: 'safe', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +The chain ID to check the bytecode at. + +::: code-group +```tsx [index.tsx] +import { useBytecode } from 'wagmi' +import { mainnet } from 'wagmi/chains' + +function App() { + const result = useBytecode({ + chainId: mainnet.id, // [!code focus] + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useBytecode } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useBytecode({ + config, // [!code focus] + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { useBytecode } from 'wagmi' +import { config } from './config' + +function App() { + const result = useBytecode({ + scopeKey: 'foo' // [!code focus] + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseBytecodeReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getBytecode`](/core/api/actions/getBytecode) diff --git a/wagmi-project/site/react/api/hooks/useCall.md b/wagmi-project/site/react/api/hooks/useCall.md new file mode 100644 index 0000000000..9bc2250cf2 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useCall.md @@ -0,0 +1,397 @@ +--- +title: useCall +description: Hook for executing a new message call immediately without submitting a transaction to the network. +--- + + + +# useCall + +Hook for executing a new message call immediately without submitting a transaction to the network. + +## Import + +```ts +import { useCall } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useCall } from 'wagmi' + +function App() { + const result = useCall({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseCallParameters } from 'wagmi' +``` + +### account + +`Account | Address | undefined` + +The Account to call from. + +::: code-group +```tsx [index.tsx] +import { useCall } from 'wagmi' + +function App() { + const result = useCall({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', // [!code focus] + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### data + +`0x${string} | undefined` + +A contract hashed method call with encoded args. + +::: code-group +```tsx [index.tsx] +import { useCall } from 'wagmi' + +function App() { + const result = useCall({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### to + +`Address | undefined` + +The contract address or recipient. + +::: code-group +```tsx [index.tsx] +import { useCall } from 'wagmi' + +function App() { + const result = useCall({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### accessList + +`AccessList | undefined` + +The access list. + +::: code-group +```tsx [index.tsx] +import { useCall } from 'wagmi' + +function App() { + const result = useCall({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + accessList: [ // [!code focus:6] + { + address: '0x1', + storageKeys: ['0x1'], + }, + ], + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### gas + +`bigint | undefined` + +The gas provided for transaction execution. + +::: code-group +```tsx [index.tsx] +import { useCall } from 'wagmi' + +function App() { + const result = useCall({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + gas: 1_000_000n, // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### gasPrice + +`bigint | undefined` + +The price (in wei) to pay per gas. Only applies to [Legacy Transactions](https://viem.sh/docs/glossary/terms.html#legacy-transaction). + +::: code-group +```tsx [index.tsx] +import { useCall } from 'wagmi' + +function App() { + const result = useCall({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + gasPrice: parseGwei('20'), // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### maxFeePerGas + +`bigint | undefined` + +Total fee per gas (in wei), inclusive of `maxPriorityFeePerGas`. Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```tsx [index.tsx] +import { useCall } from 'wagmi' + +function App() { + const result = useCall({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + maxFeePerGas: parseGwei('20'), // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### maxPriorityFeePerGas + +`bigint | undefined` + +Max priority fee per gas (in wei). Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```tsx [index.tsx] +import { useCall } from 'wagmi' + +function App() { + const result = useCall({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + maxFeePerGas: parseGwei('20'), + maxPriorityFeePerGas: parseGwei('2'), // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### nonce + +`number | undefined` + +Unique number identifying this transaction. + +::: code-group +```tsx [index.tsx] +import { useCall } from 'wagmi' + +function App() { + const result = useCall({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + nonce: 420, // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### value + +`bigint | undefined` + +Value (in wei) sent with this transaction. + +::: code-group +```tsx [index.tsx] +import { useCall } from 'wagmi' + +function App() { + const result = useCall({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockNumber + +`number | undefined` + +The block number to perform the call against. + +::: code-group +```tsx [index.tsx] +import { useCall } from 'wagmi' + +function App() { + const result = useCall({ + blockNumber: 15121123n, // [!code focus] + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +The block tag to perform the call against. + +::: code-group +```tsx [index.tsx] +import { useCall } from 'wagmi' + +function App() { + const result = useCall({ + blockTag: 'safe', // [!code focus] + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +The block tag to perform the call against. + +::: code-group +```tsx [index.tsx] +import { useCall } from 'wagmi' +import { mainnet } from '@wagmi/core/chains' + +function App() { + const result = useCall({ + chainId: mainnet.id, // [!code focus] + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useCall } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useCall({ + config, // [!code focus] + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { useCall } from 'wagmi' +import { config } from './config' + +function App() { + const result = useCall({ + scopeKey: 'foo' // [!code focus] + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseCallReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`call`](/core/api/actions/call) diff --git a/wagmi-project/site/react/api/hooks/useCallsStatus.md b/wagmi-project/site/react/api/hooks/useCallsStatus.md new file mode 100644 index 0000000000..48135c53eb --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useCallsStatus.md @@ -0,0 +1,143 @@ +--- +title: useCallsStatus +description: Hook for fetching the number of the most recent block seen. +--- + + + +# useCallsStatus + +Hook to fetch the status and receipts of a call batch that was sent via [`useSendCalls`](/react/api/hooks/useSendCalls). + + + +## Import + +```ts +import { useCallsStatus } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useCallsStatus } from 'wagmi' + +function App() { + const result = useCallsStatus({ + id: '0x...', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseCallsStatusParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useCallsStatus } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useCallsStatus({ + config, // [!code focus] + id: '0x...', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +Connector to get call statuses with. + +::: code-group +```tsx [index.tsx] +import { useCallsStatus, useConnections } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const connections = useConnections() + const result = useCallsStatus({ + connector: connections[0]?.connector, // [!code focus] + id: '0x...', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### id + +`string` + +Identifier of the call batch. + +::: code-group +```ts [index.ts] +import { useCallsStatus } from '@wagmi/core' +import { config } from './config' + +const status = await useCallsStatus({ + id: '0x1234567890abcdef', // [!code focus] +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { useCallsStatus } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useCallsStatus({ + id: '0x...', + scopeKey: 'foo', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseCallsStatusReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getCallsStatus`](https://viem.sh/experimental/eip5792/getCallsStatus) \ No newline at end of file diff --git a/wagmi-project/site/react/api/hooks/useCapabilities.md b/wagmi-project/site/react/api/hooks/useCapabilities.md new file mode 100644 index 0000000000..d9d6fc74a7 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useCapabilities.md @@ -0,0 +1,138 @@ +--- +title: useCapabilities +description: Hook for fetching the number of the most recent block seen. +--- + + + +# useCapabilities + +Hook to extract capabilities (grouped by chain ID) that a connected wallet supports (e.g. paymasters, session keys, etc). + +[Read more.](https://github.com/ethereum/EIPs/blob/815028dc634463e1716fc5ce44c019a6040f0bef/EIPS/eip-5792.md#wallet_getcapabilities) + +## Import + +```ts +import { useCapabilities } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useCapabilities } from 'wagmi' + +function App() { + const result = useCapabilities() +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseCapabilitiesParameters } from 'wagmi' +``` + +### account + +`Account | Address | undefined` + +Fetch capabilities for the provided account. + +::: code-group +```ts [index.ts] +import { useCapabilities } from '@wagmi/core' +import { config } from './config' + +const status = await useCapabilities({ + account: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', // [!code focus] +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useCapabilities } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useCapabilities({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +Connector to get call statuses with. + +::: code-group +```tsx [index.tsx] +import { useCapabilities, useConnections } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const connections = useConnections() + const result = useCapabilities({ + connector: connections[0]?.connector, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { useCapabilities } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useCapabilities({ + scopeKey: 'foo', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseCapabilitiesReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getCapabilities`](https://viem.sh/experimental/eip5792/getCapabilities) \ No newline at end of file diff --git a/wagmi-project/site/react/api/hooks/useChainId.md b/wagmi-project/site/react/api/hooks/useChainId.md new file mode 100644 index 0000000000..509f5a1e4c --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useChainId.md @@ -0,0 +1,74 @@ +--- +title: useChainId +description: Hook for getting current chain ID. +--- + +# useChainId + +Hook for getting current chain ID. + +## Import + +```ts +import { useChainId } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useChainId } from 'wagmi' + +function App() { + const chainId = useChainId() +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseChainIdParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useChainId } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const chainId = useChainId({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type UseChainIdReturnType } from 'wagmi' +``` + +`number` + +Current chain ID from [`config.state.chainId`](/react/api/createConfig#chainid). + +::: info +Only returns chain IDs for chains configured via `createConfig`'s [`chains`](/react/api/createConfig#chains) parameter. + +If the active [connection](/react/api/createConfig#connection) [`chainId`](/react/api/createConfig#chainid-1) is not from a chain included in your Wagmi `Config`, `useChainId` will return the last configured chain ID. +::: + +## Action + +- [`getChainId`](/core/api/actions/getChainId) +- [`watchChainId`](/core/api/actions/watchChainId) diff --git a/wagmi-project/site/react/api/hooks/useChains.md b/wagmi-project/site/react/api/hooks/useChains.md new file mode 100644 index 0000000000..286f794276 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useChains.md @@ -0,0 +1,67 @@ +--- +title: useChains +description: Hook for getting configured chains +--- + +# useChains + +Hook for getting configured chains + +## Import + +```ts +import { useChains } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useChains } from 'wagmi' + +function App() { + const chains = useChains() +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseChainsParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useChains } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const chains = useChains({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type UseChainsReturnType } from 'wagmi' +``` + +`readonly [Chain, ...Chain[]]` + +Chains from [`config.chains`](/react/api/createConfig#chains). + +## Action + +- [`getChains`](/core/api/actions/getChains) diff --git a/wagmi-project/site/react/api/hooks/useClient.md b/wagmi-project/site/react/api/hooks/useClient.md new file mode 100644 index 0000000000..fc87a15e47 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useClient.md @@ -0,0 +1,89 @@ +--- +title: useClient +description: Hook for getting Viem `Client` instance. +--- + +# useClient + +Hook for getting Viem [`Client`](https://viem.sh/docs/clients/custom.html) instance. + +## Import + +```ts +import { useClient } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useClient } from 'wagmi' + +function App() { + const client = useClient() +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseClientParameters } from 'wagmi' +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when getting Viem Client. + +::: code-group +```ts [index.ts] +import { useClient } from 'wagmi' +import { mainnet } from 'wagmi/chains' // [!code focus] +import { config } from './config' + +function App() { + const client = useClient({ + chainId: mainnet.id, // [!code focus] + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useClient } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const client = useClient({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type UseClientReturnType } from 'wagmi' +``` + +`Client | undefined` + +Viem [`Client`](https://viem.sh/docs/clients/custom.html) instance. + +## Action + +- [`getClient`](/core/api/actions/getClient) +- [`watchClient`](/core/api/actions/watchClient) diff --git a/wagmi-project/site/react/api/hooks/useConfig.md b/wagmi-project/site/react/api/hooks/useConfig.md new file mode 100644 index 0000000000..6f70b6e821 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useConfig.md @@ -0,0 +1,75 @@ +--- +title: useConfig +description: Hook for getting `Config` from nearest `WagmiProvider`. +--- + +# useConfig + +Hook for getting [`Config`](/react/api/createConfig#config) from nearest [`WagmiProvider`](/react/api/WagmiProvider). + +## Import + +```ts +import { useConfig } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useConfig } from 'wagmi' + +function App() { + const config = useConfig() +} +``` + +::: + +## Return Type + +```ts +import { type UseConfigReturnType } from 'wagmi' +``` + +If you use TypeScript and [register your `Config`](/react/typescript#register-config), the return type will be inferred. + +::: code-group +```ts twoslash [index.tsx] +import { type Config } from 'wagmi' +import { mainnet, sepolia } from 'wagmi/chains' + +declare module 'wagmi' { + interface Register { + config: Config + } +} +// ---cut--- +import { useConfig } from 'wagmi' + +function App() { + const config = useConfig() + // ^? +} +``` + +```ts [config.ts] +import { createConfig, http } from 'wagmi' +import { mainnet, sepolia } from 'wagmi/chains' + +declare module 'wagmi' { + interface Register { + config: typeof config + } +} + +export const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +``` + +::: diff --git a/wagmi-project/site/react/api/hooks/useConnect.md b/wagmi-project/site/react/api/hooks/useConnect.md new file mode 100644 index 0000000000..ba52ee2aaf --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useConnect.md @@ -0,0 +1,117 @@ +--- +title: useConnect +description: Hook for connecting accounts with connectors. +--- + + + +# useConnect + +Hook for connecting accounts with [connectors](/react/api/connectors). + +## Import + +```ts +import { useConnect } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useConnect } from 'wagmi' +import { injected } from 'wagmi/connectors' + +function App() { + const { connect } = useConnect() + + return ( + + ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseConnectParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useConnect } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useConnect({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseConnectReturnType } from 'wagmi' +``` + +### connectors + +`readonly Connector[]` + +Globally configured connectors via [`createConfig`](/react/api/createConfig#connectors). Useful for rendering a list of available connectors. + +::: code-group +```tsx [index.tsx] +import { useConnect } from 'wagmi' + +function App() { + const { connect, connectors } = useConnect() + + return ( +
+ {connectors.map((connector) => ( + + ))} +
+ ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +::: tip +Not all connectors support connecting directly to a `chainId` (e.g. they don't support programmatic chain switching). In those cases, the connector will connect to whatever chain the connector's provider (e.g. wallet) is connected to. +::: + + + +## Action + +- [`connect`](/core/api/actions/connect) diff --git a/wagmi-project/site/react/api/hooks/useConnections.md b/wagmi-project/site/react/api/hooks/useConnections.md new file mode 100644 index 0000000000..f6f18b14fa --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useConnections.md @@ -0,0 +1,64 @@ +--- +title: useConnections +description: Hook for getting active connections. +--- + +# useConnections + +Hook for getting active connections. + +## Import + +```ts +import { useConnections } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useConnections } from 'wagmi' + +function App() { + const connections = useConnections() +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseConnectionsParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useConnections } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const connections = useConnections({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type UseConnectionsReturnType } from 'wagmi' +``` + +## Action + +- [`getConnections`](/core/api/actions/getConnections) +- [`watchConnections`](/core/api/actions/watchConnections) diff --git a/wagmi-project/site/react/api/hooks/useConnectorClient.md b/wagmi-project/site/react/api/hooks/useConnectorClient.md new file mode 100644 index 0000000000..60aa74b77d --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useConnectorClient.md @@ -0,0 +1,128 @@ +--- +title: useConnectorClient +description: Hook for getting a Viem `Client` object for the current or provided connector. +--- + + + +# useConnectorClient + +Hook for getting a Viem [`Client`](https://viem.sh/docs/clients/custom.html) object for the current or provided connector. + +## Import + +```ts +import { useConnectorClient } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useConnectorClient } from 'wagmi' + +function App() { + const result = useConnectorClient() +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseConnectorClientParameters } from 'wagmi' +``` + +### account + +`Address | Account | undefined` + +Account to use with client. Throws if account is not found on [`connector`](#connector). + +```ts +import { useConnectorClient } from 'wagmi' + +function App() { + const result = useConnectorClient({ + account: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] + }) +} +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use with client. + +```ts +import { useConnectorClient } from 'wagmi' + +function App() { + const result = useConnectorClient({ + chainId: mainnet.id, // [!code focus] + }) +} +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useConnectorClient } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useConnectorClient({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +- Connector to get client for. +- Defaults to current connector. + +```ts +import { useConnections, useConnectorClient } from 'wagmi' + +function App() { + const connections = useConnections(config) + const result = useConnectorClient({ + connector: connections[0]?.connector, // [!code focus] + }) +} +``` + + + +## Return Type + +```ts +import { type UseConnectorClientReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getConnectorClient`](/core/api/actions/getConnectorClient) diff --git a/wagmi-project/site/react/api/hooks/useConnectors.md b/wagmi-project/site/react/api/hooks/useConnectors.md new file mode 100644 index 0000000000..f02e2dfd2f --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useConnectors.md @@ -0,0 +1,41 @@ +--- +title: useConnectors +description: Hook for getting configured connectors. +--- + +# useConnectors + +Hook for getting configured connectors. + +## Import + +```ts +import { useConnectors } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useConnectors } from 'wagmi' + +function App() { + const connectors = useConnectors() +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type UseConnectorsReturnType } from 'wagmi' +``` + +`readonly Connector[]` + +Connectors from [`config.connectors`](/react/api/createConfig#connectors-1). + +## Action + +- [`getConnectors`](/core/api/actions/getConnectors) diff --git a/wagmi-project/site/react/api/hooks/useDeployContract.md b/wagmi-project/site/react/api/hooks/useDeployContract.md new file mode 100644 index 0000000000..42b2e9ffe3 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useDeployContract.md @@ -0,0 +1,145 @@ +--- +title: useDeployContract +description: Hook for deploying a contract to the network, given bytecode & constructor arguments. +--- + + + +# useDeployContract + +Hook for deploying a contract to the network, given bytecode, and constructor arguments. + +## Import + +```ts +import { useDeployContract } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useDeployContract } from 'wagmi' +import { parseEther } from 'viem' +import { wagmiAbi } from './abi' + +function App() { + const { deployContract } = useDeployContract() + + return ( + + ) +} +``` +```ts [abi.ts] +export const wagmiAbi = [ + ... + { + inputs: [], + stateMutability: "nonpayable", + type: "constructor", + }, + ... +] as const +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Deploying with Constructor Args + +::: code-group +```tsx [index.tsx] +import { useDeployContract } from 'wagmi' +import { parseEther } from 'viem' +import { wagmiAbi } from './abi' + +function App() { + const { deployContract } = useDeployContract() + + return ( + + ) +} +``` +```ts [abi.ts] +export const wagmiAbi = [ + ... + { + inputs: [{ name: "x", type: "uint32" }], + stateMutability: "nonpayable", + type: "constructor", + }, + ... +] as const; +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type useDeployContractParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useDeployContract } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useDeployContract({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type useDeployContractReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`deployContract`](/core/api/actions/deployContract) diff --git a/wagmi-project/site/react/api/hooks/useDisconnect.md b/wagmi-project/site/react/api/hooks/useDisconnect.md new file mode 100644 index 0000000000..5e537a846d --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useDisconnect.md @@ -0,0 +1,113 @@ +--- +title: useDisconnect +description: Hook for disconnecting connections. +--- + + + +# useDisconnect + +Hook for disconnecting connections. + +## Import + +```ts +import { useDisconnect } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useDisconnect } from 'wagmi' + +function App() { + const { disconnect } = useDisconnect() + + return ( + + ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseDisconnectParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useDisconnect } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useDisconnect({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseDisconnectReturnType } from 'wagmi' +``` + +### connectors + +`readonly Connector[]` + +Connectors that are currently connected. Useful for rendering a list of connectors to disconnect. + +::: code-group +```tsx [index.tsx] +import { useDisconnect } from 'wagmi' +import { mainnet } from 'wagmi/chains' + +function App() { + const { connectors, disconnect } = useDisconnect() + + return ( +
+ {connectors.map((connector) => ( + + ))} +
+ ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + + + +## Action + +- [`disconnect`](/core/api/actions/disconnect) diff --git a/wagmi-project/site/react/api/hooks/useEnsAddress.md b/wagmi-project/site/react/api/hooks/useEnsAddress.md new file mode 100644 index 0000000000..b4807384f1 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useEnsAddress.md @@ -0,0 +1,238 @@ +--- +title: useEnsAddress +description: Hook for fetching ENS address for name. +--- + + + +# useEnsAddress + +Hook for fetching ENS address for name. + +## Import + +```ts +import { useEnsAddress } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useEnsAddress } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsAddress({ + name: normalize('wevm.eth'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +::: warning +Since ENS names prohibit certain forbidden characters (e.g. underscore) and have other validation rules, you likely want to [normalize ENS names](https://docs.ens.domains/contract-api-reference/name-processing#normalising-names) with [UTS-46 normalization](https://unicode.org/reports/tr46) before passing them to `useEnsAddress`. You can use Viem's built-in [`normalize`](https://viem.sh/docs/ens/utilities/normalize) function for this. +::: + +## Parameters + +```ts +import { type UseEnsAddressParameters } from 'wagmi' +``` + +--- + +### blockNumber + +`bigint | undefined` + +Block number to get ENS address at. + +::: code-group +```ts [index.ts] +import { useEnsAddress } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsAddress({ + blockNumber: 17829139n, // [!code focus] + name: normalize('wevm.eth'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get ENS address at. + +::: code-group +```ts [index.ts] +import { useEnsAddress } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsAddress({ + name: normalize('wevm.eth'), + blockTag: 'latest', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useEnsAddress } from 'wagmi' +import { mainnet } from 'wagmi/chains' // [!code focus] +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsAddress({ + chainId: mainnet.id, // [!code focus] + name: normalize('wevm.eth'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### coinType + +`number | undefined` + +The [ENSIP-9](https://docs.ens.domains/ens-improvement-proposals/ensip-9-multichain-address-resolution) coin type to fetch the address for. + +::: code-group +```ts [index.ts] +import { useEnsAddress } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsAddress({ + coinType: 60, // [!code focus] + name: normalize('wevm.eth'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useEnsAddress } from 'wagmi' +import { normalize } from 'viem/ens' +import { config } from './config' // [!code focus] + +function App() { + const result = useEnsAddress({ + config, // [!code focus] + name: normalize('wevm.eth'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### name + +`string | undefined` + +Name to get the address for. [`enabled`](#enabled) set to `false` if `name` is `undefined`. + +::: code-group +```ts [index.ts] +import { useEnsAddress } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsAddress({ + name: normalize('wevm.eth'), // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```ts [index.ts] +import { useEnsAddress } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsAddress({ + name: normalize('wevm.eth'), + scopeKey: 'foo', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### universalResolverAddress + +`Address | undefined` + +- Address of ENS Universal Resolver Contract. +- Defaults to current chain's Universal Resolver Contract address. + +::: code-group +```ts [index.ts] +import { useEnsAddress } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsAddress({ + name: normalize('wevm.eth'), + universalResolverAddress: '0x74E20Bd2A1fE0cdbe45b9A1d89cb7e0a45b36376', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseEnsAddressReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getEnsAddress`](/core/api/actions/getEnsAddress) diff --git a/wagmi-project/site/react/api/hooks/useEnsAvatar.md b/wagmi-project/site/react/api/hooks/useEnsAvatar.md new file mode 100644 index 0000000000..ec09af5e31 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useEnsAvatar.md @@ -0,0 +1,262 @@ +--- +title: useEnsAvatar +description: Hook for fetching ENS avatar for name. +--- + + + +# useEnsAvatar + +Hook for fetching ENS avatar for name. + +## Import + +```ts +import { useEnsAvatar } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useEnsAvatar } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsAvatar({ + name: normalize('wevm.eth'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +::: warning +Since ENS names prohibit certain forbidden characters (e.g. underscore) and have other validation rules, you likely want to [normalize ENS names](https://docs.ens.domains/contract-api-reference/name-processing#normalising-names) with [UTS-46 normalization](https://unicode.org/reports/tr46) before passing them to `useEnsAvatar`. You can use Viem's built-in [`normalize`](https://viem.sh/docs/ens/utilities/normalize) function for this. +::: + +## Parameters + +```ts +import { type UseEnsAvatarParameters } from 'wagmi' +``` + +--- + +### assetGatewayUrls + +`{ ipfs?: string | undefined; arweave?: string | undefined } | undefined` + +Gateway urls to resolve IPFS and/or Arweave assets. + +::: code-group +```ts [index.ts] +import { getEnsAvatar } from '@wagmi/core' +import { normalize } from 'viem/ens' +import { config } from './config' + +function App() { + const result = useEnsAvatar({ + assetGatewayUrls: { // [!code focus] + ipfs: 'https://cloudflare-ipfs.com', // [!code focus] + }, // [!code focus] + name: normalize('wevm.eth'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockNumber + +`bigint | undefined` + +Block number to get ENS avatar at. + +::: code-group +```ts [index.ts] +import { useEnsAvatar } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsAvatar({ + blockNumber: 17829139n, // [!code focus] + name: normalize('wevm.eth'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get ENS avatar at. + +::: code-group +```ts [index.ts] +import { useEnsAvatar } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsAvatar({ + name: normalize('wevm.eth'), + blockTag: 'latest', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useEnsAvatar } from 'wagmi' +import { mainnet } from 'wagmi/chains' // [!code focus] +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsAvatar({ + chainId: mainnet.id, // [!code focus], + name: normalize('wevm.eth'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useEnsAvatar } from 'wagmi' +import { normalize } from 'viem/ens' +import { config } from './config' // [!code focus] + +function App() { + const result = useEnsAvatar({ + config, // [!code focus] + name: normalize('wevm.eth'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### gatewayUrls + +`string[] | undefined` + +A set of Universal Resolver gateways, used for resolving CCIP-Read requests made through the ENS Universal Resolver Contract. + +::: code-group +```ts [index.ts] +import { useEnsAvatar } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsAvatar({ + gatewayUrls: ['https://cloudflare-ipfs.com'] { // [!code focus] + name: normalize('wevm.eth'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### name + +`string | undefined` + +Name to get the avatar for. [`enabled`](#enabled) set to `false` if `name` is `undefined`. + +::: code-group +```ts [index.ts] +import { useEnsAvatar } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsAvatar({ + name: normalize('wevm.eth'), // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```ts [index.ts] +import { useEnsAvatar } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsAvatar({ + name: normalize('wevm.eth'), + scopeKey: 'foo', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### universalResolverAddress + +`Address | undefined` + +- Address of ENS Universal Resolver Contract. +- Defaults to current chain's Universal Resolver Contract address. + +::: code-group +```ts [index.ts] +import { useEnsAvatar } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsAvatar({ + name: normalize('wevm.eth'), + universalResolverAddress: '0x74E20Bd2A1fE0cdbe45b9A1d89cb7e0a45b36376', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseEnsAvatarReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getEnsAvatar`](/core/api/actions/getEnsAvatar) diff --git a/wagmi-project/site/react/api/hooks/useEnsName.md b/wagmi-project/site/react/api/hooks/useEnsName.md new file mode 100644 index 0000000000..71d128b1bf --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useEnsName.md @@ -0,0 +1,206 @@ +--- +title: useEnsName +description: Hook for fetching primary ENS name for address. +--- + + + +# useEnsName + +Hook for fetching primary ENS name for address. + +## Import + +```ts +import { useEnsName } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useEnsName } from 'wagmi' + +function App() { + const result = useEnsName({ + address: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseEnsNameParameters } from 'wagmi' +``` + +### address + +`Address | undefined` + +Name to get the resolver for. [`enabled`](#enabled) set to `false` if `address` is `undefined`. + +::: code-group +```ts [index.ts] +import { useEnsName } from 'wagmi' + +function App() { + const result = useEnsName({ + address: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +--- + +### blockNumber + +`bigint | undefined` + +Block number to get ENS name at. + +::: code-group +```ts [index.ts] +import { useEnsName } from 'wagmi' + +function App() { + const result = useEnsName({ + address: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + blockNumber: 17829139n, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get ENS name at. + +::: code-group +```ts [index.ts] +import { useEnsName } from 'wagmi' + +function App() { + const result = useEnsName({ + address: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + blockTag: 'latest', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useEnsName } from 'wagmi' +import { mainnet } from 'wagmi/chains' // [!code focus] + +function App() { + const result = useEnsName({ + address: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + chainId: mainnet.id, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useEnsName } from 'wagmi' +import { normalize } from 'viem/ens' +import { config } from './config' // [!code focus] + +function App() { + const result = useEnsName({ + address: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```ts [index.ts] +import { useEnsName } from 'wagmi' + +function App() { + const result = useEnsName({ + address: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + scopeKey: 'foo', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### universalResolverAddress + +`Address | undefined` + +- Address of ENS Universal Resolver Contract. +- Defaults to current chain's Universal Resolver Contract address. + +::: code-group +```ts [index.ts] +import { useEnsName } from 'wagmi' + +function App() { + const result = useEnsName({ + address: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + universalResolverAddress: '0x74E20Bd2A1fE0cdbe45b9A1d89cb7e0a45b36376', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseEnsNameReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getEnsName`](/core/api/actions/getEnsName) diff --git a/wagmi-project/site/react/api/hooks/useEnsResolver.md b/wagmi-project/site/react/api/hooks/useEnsResolver.md new file mode 100644 index 0000000000..b66e17fa03 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useEnsResolver.md @@ -0,0 +1,217 @@ +--- +title: useEnsResolver +description: Hook for fetching ENS resolver for name. +--- + + + +# useEnsResolver + +Hook for fetching ENS resolver for name. + +## Import + +```ts +import { useEnsResolver } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useEnsResolver } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsResolver({ + name: normalize('wevm.eth'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +::: warning +Since ENS names prohibit certain forbidden characters (e.g. underscore) and have other validation rules, you likely want to [normalize ENS names](https://docs.ens.domains/contract-api-reference/name-processing#normalising-names) with [UTS-46 normalization](https://unicode.org/reports/tr46) before passing them to `useEnsResolver`. You can use Viem's built-in [`normalize`](https://viem.sh/docs/ens/utilities/normalize) function for this. +::: + +## Parameters + +```ts +import { type UseEnsResolverParameters } from 'wagmi' +``` + +--- + +### blockNumber + +`bigint | undefined` + +Block number to get ENS resolver at. + +::: code-group +```ts [index.ts] +import { useEnsResolver } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsResolver({ + blockNumber: 17829139n, // [!code focus] + name: normalize('wevm.eth'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get ENS resolver at. + +::: code-group +```ts [index.ts] +import { useEnsResolver } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsResolver({ + name: normalize('wevm.eth'), + blockTag: 'latest', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useEnsResolver } from 'wagmi' +import { mainnet } from 'wagmi/chains' // [!code focus] +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsResolver({ + chainId: mainnet.id, // [!code focus] + name: normalize('wevm.eth'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useEnsResolver } from 'wagmi' +import { normalize } from 'viem/ens' +import { config } from './config' // [!code focus] + +function App() { + const result = useEnsResolver({ + config, // [!code focus] + name: normalize('wevm.eth'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### name + +`string | undefined` + +Name to get the resolver for. [`enabled`](#enabled) set to `false` if `name` is `undefined`. + +::: code-group +```ts [index.ts] +import { useEnsResolver } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsResolver({ + name: normalize('wevm.eth'), // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```ts [index.ts] +import { useEnsResolver } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsResolver({ + name: normalize('wevm.eth'), + scopeKey: 'foo', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### universalResolverAddress + +`Address | undefined` + +- Resolver of ENS Universal Resolver Contract. +- Defaults to current chain's Universal Resolver Contract address. + +::: code-group +```ts [index.ts] +import { useEnsResolver } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsResolver({ + name: normalize('wevm.eth'), + universalResolverAddress: '0x74E20Bd2A1fE0cdbe45b9A1d89cb7e0a45b36376', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseEnsResolverReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getEnsResolver`](/core/api/actions/getEnsResolver) diff --git a/wagmi-project/site/react/api/hooks/useEnsText.md b/wagmi-project/site/react/api/hooks/useEnsText.md new file mode 100644 index 0000000000..769bae66ce --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useEnsText.md @@ -0,0 +1,247 @@ +--- +title: useEnsText +description: Hook for fetching a text record for a specified ENS name and key. +--- + + + +# useEnsText + +Hook for fetching a text record for a specified ENS name and key. + +## Import + +```ts +import { useEnsText } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useEnsText } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsText({ + name: normalize('wevm.eth'), + key: 'com.twitter', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +::: warning +Since ENS names prohibit certain forbidden characters (e.g. underscore) and have other validation rules, you likely want to [normalize ENS names](https://docs.ens.domains/contract-api-reference/name-processing#normalising-names) with [UTS-46 normalization](https://unicode.org/reports/tr46) before passing them to `useEnsText`. You can use Viem's built-in [`normalize`](https://viem.sh/docs/ens/utilities/normalize) function for this. +::: + +## Parameters + +```ts +import { type UseEnsTextParameters } from 'wagmi' +``` + +--- + +### blockNumber + +`bigint | undefined` + +Block number to get the text at. + +::: code-group +```ts [index.ts] +import { useEnsText } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsText({ + blockNumber: 17829139n, // [!code focus] + name: normalize('wevm.eth'), + key: 'com.twitter', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get the text at. + +::: code-group +```ts [index.ts] +import { useEnsText } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsText({ + blockTag: 'latest', // [!code focus] + name: normalize('wevm.eth'), + key: 'com.twitter', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useEnsText } from 'wagmi' +import { mainnet } from 'wagmi/chains' // [!code focus] +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsText({ + chainId: mainnet.id, // [!code focus] + name: normalize('wevm.eth'), + key: 'com.twitter', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### key + +`string | undefined` + +ENS key to get Text for. + +::: code-group +```ts [index.ts] +import { useEnsText } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsText({ + name: normalize('wevm.eth'), + key: 'com.twitter', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + +### name + +`string | undefined` + +Name to get the text for. [`enabled`](#enabled) set to `false` if `name` is `undefined`. + +::: code-group +```ts [index.ts] +import { useEnsText } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsText({ + name: normalize('wevm.eth'), // [!code focus] + key: 'com.twitter', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useEnsText } from 'wagmi' +import { normalize } from 'viem/ens' +import { config } from './config' // [!code focus] + +function App() { + const result = useEnsText({ + config, // [!code focus] + name: normalize('wevm.eth'), + key: 'com.twitter', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```ts [index.ts] +import { useEnsText } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsText({ + scopeKey: 'foo', // [!code focus] + name: normalize('wevm.eth'), + key: 'com.twitter', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### universalResolverAddress + +`Address | undefined` + +- Resolver of ENS Universal Resolver Contract. +- Defaults to current chain's Universal Resolver Contract address. + +::: code-group +```ts [index.ts] +import { useEnsText } from 'wagmi' +import { normalize } from 'viem/ens' + +function App() { + const result = useEnsText({ + name: normalize('wevm.eth'), + key: 'com.twitter', + universalResolverAddress: '0x74E20Bd2A1fE0cdbe45b9A1d89cb7e0a45b36376', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseEnsTextReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getEnsText`](/core/api/actions/getEnsText) diff --git a/wagmi-project/site/react/api/hooks/useEstimateFeesPerGas.md b/wagmi-project/site/react/api/hooks/useEstimateFeesPerGas.md new file mode 100644 index 0000000000..29b8711673 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useEstimateFeesPerGas.md @@ -0,0 +1,155 @@ +--- +title: useEstimateFeesPerGas +description: Hook for fetching an estimate for the fees per gas (in wei) for a transaction to be likely included in the next block. +--- + + + +# useEstimateFeesPerGas + +Hook for fetching an estimate for the fees per gas (in wei) for a transaction to be likely included in the next block. + +## Import + +```ts +import { useEstimateFeesPerGas } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useEstimateFeesPerGas } from 'wagmi' + +function App() { + const result = useEstimateFeesPerGas() +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseEstimateFeesPerGas } from 'wagmi' +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useEstimateFeesPerGas } from 'wagmi' +import { mainnet } from 'wagmi/chains' // [!code focus] + +function App() { + const result = useEstimateFeesPerGas({ + chainId: mainnet.id, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useEstimateFeesPerGas } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useEstimateFeesPerGas({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### formatUnits + +`'ether' | 'gwei' | 'wei' | number | undefined` + +- Units to use when formatting result. +- Defaults to `'ether'`. + +::: code-group +```ts [index.ts] +import { useEstimateFeesPerGas } from 'wagmi' + +function App() { + const result = useEstimateFeesPerGas({ + formatUnits: 'ether', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```ts [index.ts] +import { useEstimateFeesPerGas } from 'wagmi' + +function App() { + const result = useEstimateFeesPerGas({ + scopeKey: 'foo', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### type + +`'legacy' | 'eip1559'` + +- Defaults to `'eip1559'` + +::: code-group +```ts [index.ts] +import { useEstimateFeesPerGas } from 'wagmi' + +function App() { + const result = useEstimateFeesPerGas({ + type: 'legacy', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseEstimateFeesPerGasReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`estimateFeesPerGas`](/core/api/actions/estimateFeesPerGas) diff --git a/wagmi-project/site/react/api/hooks/useEstimateGas.md b/wagmi-project/site/react/api/hooks/useEstimateGas.md new file mode 100644 index 0000000000..db0707ca1a --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useEstimateGas.md @@ -0,0 +1,387 @@ +--- +title: useEstimateGas +description: Hook for estimating the gas necessary to complete a transaction without submitting it to the network. +--- + + + +# useEstimateGas + +Hook for estimating the gas necessary to complete a transaction without submitting it to the network. + +## Import + +```ts +import { useEstimateGas } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useEstimateGas } from 'wagmi' + +function App() { + const result = useEstimateGas() +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseEstimateGasParameters } from 'wagmi' +``` + +### accessList + +`AccessList | undefined` + +The access list. + +::: code-group +```ts [index.ts] +import { useEstimateGas } from 'wagmi' +import { parseEther } from 'viem' +import { config } from './config' + +function App() { + const result = useEstimateGas({ + accessList: [{ // [!code focus] + address: '0x1', // [!code focus] + storageKeys: ['0x1'], // [!code focus] + }], // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### account + +`Address | Account | undefined` + +Account to use when estimating gas. + +::: code-group +```ts [index.ts] +import { useEstimateGas } from 'wagmi' +import { parseEther } from 'viem' +import { config } from './config' + +function App() { + const result = useEstimateGas({ + account: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +Chain ID to target when estimating gas. + +::: code-group +```ts [index.ts] +import { useEstimateGas } from 'wagmi' +import { mainnet } from '@wagmi/core/chains' +import { parseEther } from 'viem' +import { config } from './config' + +function App() { + const result = useEstimateGas({ + chainId: mainnet.id, // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +Connector to estimate with. If no [`account`](#account) is provided, will use default account from connector. + +::: code-group +```ts [index.ts] +import { getConnections, estimateGas } from '@wagmi/core' +import { parseEther } from 'viem' +import { config } from './config' + +function App() { + const connections = getConnections(config) + const result = useEstimateGas({ + connector: connections[0]?.connector, // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### data + +`` `0x${string}` | undefined `` + +A contract hashed method call with encoded function data. + +::: code-group +```ts [index.ts] +import { useEstimateGas } from 'wagmi' +import { parseEther } from 'viem' +import { config } from './config' + +function App() { + const result = useEstimateGas({ + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### gas + +`bigint | undefined` + +Gas provided for transaction execution. + +::: code-group +```ts [index.ts] +import { useEstimateGas } from 'wagmi' +import { parseEther, parseGwei } from 'viem' +import { config } from './config' + +function App() { + const result = useEstimateGas({ + gas: parseGwei('20'), // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +--- + +### gasPrice + +`bigint | undefined` + +The price in wei to pay per gas. Only applies to [Legacy Transactions](https://viem.sh/docs/glossary/terms.html#legacy-transaction). + +::: code-group +```ts [index.ts] +import { useEstimateGas } from 'wagmi' +import { parseEther, parseGwei } from 'viem' +import { config } from './config' + +function App() { + const result = useEstimateGas({ + gasPrice: parseGwei('20'), // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### maxFeePerGas + +`bigint | undefined` + +Total fee per gas in wei, inclusive of [`maxPriorityFeePerGas`](#maxPriorityFeePerGas). Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```ts [index.ts] +import { useEstimateGas } from 'wagmi' +import { parseEther, parseGwei } from 'viem' +import { config } from './config' + +function App() { + const result = useEstimateGas({ + maxFeePerGas: parseGwei('20'), // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### maxPriorityFeePerGas + +`bigint | undefined` + +Max priority fee per gas in wei. Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```ts [index.ts] +import { useEstimateGas } from 'wagmi' +import { parseEther, parseGwei } from 'viem' +import { config } from './config' + +function App() { + const result = useEstimateGas({ + maxFeePerGas: parseGwei('20'), + maxPriorityFeePerGas: parseGwei('2'), // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +--- + +### nonce + +`number` + +Unique number identifying this transaction. + +::: code-group +```ts [index.ts] +import { useEstimateGas } from 'wagmi' +import { parseEther } from 'viem' +import { config } from './config' + +function App() { + const result = useEstimateGas({ + nonce: 123, // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```ts [index.ts] +import { useEstimateGas } from 'wagmi' +import { parseEther } from 'viem' +import { config } from './config' + +function App() { + const result = useEstimateGas({ + scopeKey: 'foo', // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### to + +`Address | undefined` + +The transaction recipient or contract address. + +::: code-group +```ts [index.ts] +import { useEstimateGas } from 'wagmi' +import { parseEther } from 'viem' +import { config } from './config' + +function App() { + const result = useEstimateGas({ + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] + value: parseEther('0.01'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### type + +`'legacy' | 'eip1559' | 'eip2930' | undefined` + +Optional transaction request type to narrow parameters. + +::: code-group +```ts [index.ts] +import { useEstimateGas } from 'wagmi' +import { parseEther } from 'viem' +import { config } from './config' + +function App() { + const result = useEstimateGas({ + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + type: 'eip1559', // [!code focus] + value: parseEther('0.01'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### value + +`bigint | undefined` + +Value in wei sent with this transaction. + +::: code-group +```ts [index.ts] +import { useEstimateGas } from 'wagmi' +import { parseEther } from 'viem' +import { config } from './config' + +function App() { + const result = useEstimateGas({ + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseEstimateGasReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`estimateGas`](/core/api/actions/estimateGas) diff --git a/wagmi-project/site/react/api/hooks/useEstimateMaxPriorityFeePerGas.md b/wagmi-project/site/react/api/hooks/useEstimateMaxPriorityFeePerGas.md new file mode 100644 index 0000000000..affb165711 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useEstimateMaxPriorityFeePerGas.md @@ -0,0 +1,116 @@ +--- +title: useEstimateMaxPriorityFeePerGas +description: Hook for fetching an estimate for the max priority fee per gas (in wei) for a transaction to be likely included in the next block. +--- + + + +# useEstimateMaxPriorityFeePerGas + +Hook for fetching an estimate for the fees per gas (in wei) for a transaction to be likely included in the next block. + +## Import + +```ts +import { useEstimateMaxPriorityFeePerGas } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useEstimateMaxPriorityFeePerGas } from 'wagmi' + +function App() { + const result = useEstimateMaxPriorityFeePerGas() +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseEstimateMaxPriorityFeePerGas } from 'wagmi' +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useEstimateMaxPriorityFeePerGas } from 'wagmi' +import { mainnet } from 'wagmi/chains' // [!code focus] + +function App() { + const result = useEstimateMaxPriorityFeePerGas({ + chainId: mainnet.id, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useEstimateMaxPriorityFeePerGas } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useEstimateMaxPriorityFeePerGas({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```ts [index.ts] +import { useEstimateMaxPriorityFeePerGas } from 'wagmi' + +function App() { + const result = useEstimateMaxPriorityFeePerGas({ + scopeKey: 'foo', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseEstimateMaxPriorityFeePerGasReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`estimateMaxPriorityFeePerGas`](/core/api/actions/estimateMaxPriorityFeePerGas) diff --git a/wagmi-project/site/react/api/hooks/useFeeHistory.md b/wagmi-project/site/react/api/hooks/useFeeHistory.md new file mode 100644 index 0000000000..42bf60d89f --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useFeeHistory.md @@ -0,0 +1,210 @@ +--- +title: useFeeHistory +description: Hook for fetching a collection of historical gas information. +--- + + + +# useFeeHistory + +Hook for fetching a collection of historical gas information. + +## Import + +```ts +import { useFeeHistory } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useFeeHistory } from 'wagmi' + +function App() { + const result = useFeeHistory({ + blockCount: 4, + rewardPercentiles: [25, 75] +}) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseFeeHistoryParameters } from 'wagmi' +``` + +### blockCount + +`number | undefined` + +Number of blocks in the requested range. Between 1 and 1024 blocks can be requested in a single query. Less than requested may be returned if not all blocks are available. + +::: code-group +```tsx [index.tsx] +import { useFeeHistory } from 'wagmi' + +function App() { + const result = useFeeHistory({ + blockCount: 4, // [!code focus] + rewardPercentiles: [25, 75] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### rewardPercentiles + +`number[] | undefined` + +A monotonically increasing list of percentile values to sample from each block's effective priority fees per gas in ascending order, weighted by gas used. + +::: code-group +```tsx [index.tsx] +import { useFeeHistory } from 'wagmi' + +function App() { + const result = useFeeHistory({ + blockCount: 4, + rewardPercentiles: [25, 75] // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockNumber + +`bigint | undefined` + +Highest number block of the requested range. + + +::: code-group +```tsx [index.tsx] +import { useFeeHistory } from 'wagmi' + +function App() { + const result = useFeeHistory({ + blockCount: 4, + blockNumber: 1551231n, // [!code focus] + rewardPercentiles: [25, 75] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag of the highest number block of the requested range. + +::: code-group +```tsx [index.tsx] +import { useFeeHistory } from 'wagmi' + +function App() { + const result = useFeeHistory({ + blockCount: 4, + blockTag: 'safe', // [!code focus] + rewardPercentiles: [25, 75] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + + +::: code-group +```tsx [index.tsx] +import { useFeeHistory } from 'wagmi' +import { mainnet } from '@wagmi/core/chains' + +function App() { + const result = useFeeHistory({ + blockCount: 4, + chainId: mainnet.id, // [!code focus] + rewardPercentiles: [25, 75] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useFeeHistory } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useFeeHistory({ + blockCount: 4, + rewardPercentiles: [25, 75] + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { useFeeHistory } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useFeeHistory({ + blockCount: 4, + rewardPercentiles: [25, 75] + scopeKey: 'foo', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseFeeHistoryReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getFeeHistory`](/core/api/actions/getFeeHistory) diff --git a/wagmi-project/site/react/api/hooks/useGasPrice.md b/wagmi-project/site/react/api/hooks/useGasPrice.md new file mode 100644 index 0000000000..2dfa13aa19 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useGasPrice.md @@ -0,0 +1,117 @@ +--- +title: useGasPrice +description: Hook for fetching the current price of gas (in wei). +--- + + + +# useGasPrice + +Hook for fetching the current price of gas (in wei). + +## Import + +```ts +import { useGasPrice } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useGasPrice } from 'wagmi' + +function App() { + const result = useGasPrice() +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseGasPriceParameters } from 'wagmi' +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useGasPrice } from 'wagmi' +import { mainnet } from 'wagmi/chains' // [!code focus] + +function App() { + const result = useGasPrice({ + chainId: mainnet.id, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useGasPrice } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useGasPrice({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { useGasPrice } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useGasPrice({ + scopeKey: 'foo', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseGasPriceReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getGasPrice`](/core/api/actions/getGasPrice) diff --git a/wagmi-project/site/react/api/hooks/useInfiniteReadContracts.md b/wagmi-project/site/react/api/hooks/useInfiniteReadContracts.md new file mode 100644 index 0000000000..bc25df59f8 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useInfiniteReadContracts.md @@ -0,0 +1,358 @@ +--- +title: useInfiniteReadContracts +description: Hook for calling multiple read methods on a contract with "infinite scroll"/"fetch more" support. +--- + + + +# useInfiniteReadContracts + +Hook for calling multiple contract read-only methods with "infinite scrolling"/"fetch more" support. + +## Import + +```ts +import { useInfiniteReadContracts } from 'wagmi' +``` + +## Usage + +The example below shows how to demonstrate how to fetch a set of [mloot](https://etherscan.io/address/0x1dfe7ca09e99d10835bf73044a23b73fc20623df) attributes (chestwear, footwear, and handwear) with "fetch more" support. + +::: code-group +```tsx [index.tsx] +import { useInfiniteReadContracts } from 'wagmi' +import { abi } from './abi' + +const mlootContractConfig = { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi, +} as const + +function App() { + const result = useInfiniteReadContracts({ + cacheKey: 'mlootAttributes', + contracts(pageParam) { + const args = [pageParam] as const + return [ + { ...mlootContractConfig, functionName: 'getChest', args }, + { ...mlootContractConfig, functionName: 'getFoot', args }, + { ...mlootContractConfig, functionName: 'getHand', args }, + ] + } + query: { + initialPageParam: 0, + getNextPageParam: (_lastPage, _allPages, lastPageParam) => { + return lastPageParam + 1 + } + } + }) +} +``` +<<< @/snippets/abi-infinite-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +In the above example, we are setting a few things: + +- [`cacheKey`](#cachekey): A unique key to store the data in the cache. +- [`query.initialPageParam`](#initialpageparam): An initial page parameter to use when fetching the first set of contracts. +- [`query.getNextPageParam`](#getnextpageparam): A function that returns the next page parameter to use when fetching the next set of contracts. +- [`contracts`](#contracts): A function that provides `pageParam` (derived from the above) as an argument and expects to return an array of contracts. + +### Paginated Parameters + +We can also leverage properties like `getNextPageParam` with a custom `limit` variable to achieve "pagination" of parameters. For example, we can fetch the first 10 contract functions, then fetch the next 10 contract functions, and so on. + +::: code-group +```tsx [index.tsx] +import { useInfiniteReadContracts } from 'wagmi' +import { abi } from './abi' + +function Example({ limit = 10 }: { limit?: number } = {}) { + const result = useInfiniteReadContracts({ + cacheKey: 'mlootAttributes', + contracts(pageParam) { + return [...new Array(limit)].map( + (_, i) => + ({ + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi, + functionName: 'getHand', + args: [BigInt(pageParam + i)], + }) as const, + ) + }, + query: { + initialPageParam: 1, + getNextPageParam(_lastPage, _allPages, lastPageParam) { + return lastPageParam + limit + }, + } + }) +} +``` +<<< @/snippets/abi-infinite-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + + +## Parameters + +```ts +import { type UseInfiniteReadContractsParameters } from 'wagmi' +``` + +### cacheKey + +`string` + +A unique key to store the data in the cache. + +::: code-group +```tsx [index.tsx] +import { useInfiniteReadContracts } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useInfiniteReadContracts({ + cacheKey: 'mlootAttributes', // [!code hl] + contracts(pageParam) { + // ... + } + query: { + initialPageParam: 0, + getNextPageParam: (_lastPage, _allPages, lastPageParam) => { + return lastPageParam + 1 + } + } + }) +} +``` +<<< @/snippets/abi-infinite-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### contracts + +`(pageParam: {{TPageParam}}) => Contract[]` + +A function that provides `pageParam` (derived from the above) as an argument and expects to return an array of contracts. + +#### abi + +`Abi | undefined` + +The contract's ABI. Check out the [TypeScript docs](/react/typescript#const-assert-abis-typed-data) for how to set up ABIs for maximum type inference and safety. + +::: code-group +```tsx [index.tsx] +import { useInfiniteReadContracts } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useInfiniteReadContracts({ + cacheKey: 'mlootAttributes', + contracts(pageParam) { + const args = [pageParam] as const + return [ + // ... + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi, // [!code hl] + functionName: 'getChest', + args + }, + // ... + ] + } + query: { + initialPageParam: 0, + getNextPageParam: (_lastPage, _allPages, lastPageParam) => { + return lastPageParam + 1 + } + } + }) +} +``` +<<< @/snippets/abi-infinite-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +#### address + +`Address | undefined` + +The contract's address. + +::: code-group +```tsx [index.tsx] +import { useInfiniteReadContracts } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useInfiniteReadContracts({ + cacheKey: 'mlootAttributes', + contracts(pageParam) { + const args = [pageParam] as const + return [ + // ... + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', // [!code hl] + abi, + functionName: 'getChest', + args + }, + // ... + ] + } + query: { + initialPageParam: 0, + getNextPageParam: (_lastPage, _allPages, lastPageParam) => { + return lastPageParam + 1 + } + } + }) +} +``` +<<< @/snippets/abi-infinite-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +#### functionName + +`string | undefined` + +- Function to call on the contract. +- Inferred from [`abi`](#abi). + +::: code-group +```tsx [index.tsx] +import { useInfiniteReadContracts } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useInfiniteReadContracts({ + cacheKey: 'mlootAttributes', + contracts(pageParam) { + const args = [pageParam] as const + return [ + // ... + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi, + functionName: 'getChest', // [!code hl] + args + }, + // ... + ] + } + query: { + initialPageParam: 0, + getNextPageParam: (_lastPage, _allPages, lastPageParam) => { + return lastPageParam + 1 + } + } + }) +} +``` +<<< @/snippets/abi-infinite-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +#### args + +`readonly unknown[] | undefined` + +- Arguments to pass when calling the contract. +- Inferred from [`abi`](#abi) and [`functionName`](#functionname). + +::: code-group +```tsx [index.tsx] +import { useInfiniteReadContracts } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useInfiniteReadContracts({ + cacheKey: 'mlootAttributes', + contracts(pageParam) { + return [ + // ... + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi, + functionName: 'getChest', + args: [pageParam] // [!code hl] + }, + // ... + ] + } + query: { + initialPageParam: 0, + getNextPageParam: (_lastPage, _allPages, lastPageParam) => { + return lastPageParam + 1 + } + } + }) +} +``` +<<< @/snippets/abi-infinite-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +#### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useInfiniteReadContracts } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useInfiniteReadContracts({ + cacheKey: 'mlootAttributes', + contracts(pageParam) { + const args = [pageParam] as const + return [ + // ... + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi, + functionName: 'getChest', + args, + chainId: 1 // [!code hl] + }, + // ... + ] + } + query: { + initialPageParam: 0, + getNextPageParam: (_lastPage, _allPages, lastPageParam) => { + return lastPageParam + 1 + } + } + }) +} +``` +<<< @/snippets/abi-infinite-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseInfiniteReadContractsReturnType } from 'wagmi' +``` + + \ No newline at end of file diff --git a/wagmi-project/site/react/api/hooks/usePrepareTransactionRequest.md b/wagmi-project/site/react/api/hooks/usePrepareTransactionRequest.md new file mode 100644 index 0000000000..431fdda482 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/usePrepareTransactionRequest.md @@ -0,0 +1,368 @@ +--- +title: usePrepareTransactionRequest +description: Hook for preparing a transaction request for signing by populating a nonce, gas limit, fee values, and a transaction type. +--- + + + +# usePrepareTransactionRequest + +Hook for preparing a transaction request for signing by populating a nonce, gas limit, fee values, and a transaction type. + +## Import + +```ts +import { usePrepareTransactionRequest } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { usePrepareTransactionRequest } from 'wagmi' +import { parseEther } from 'viem' + +function App() { + const result = usePrepareTransactionRequest({ + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UsePrepareTransactionRequestParameters } from 'wagmi' +``` + +### account + +`Account | Address | undefined` + +The Account to send the transaction from. + +::: code-group +```tsx [index.tsx] +import { usePrepareTransactionRequest } from 'wagmi' +import { parseEther } from 'viem' + +function App() { + const result = usePrepareTransactionRequest({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### to + +`` `0x${string}` | undefined `` + +The transaction recipient or contract address. + +::: code-group +```tsx [index.tsx] +import { usePrepareTransactionRequest } from 'wagmi' +import { parseEther } from 'viem' + +function App() { + const result = usePrepareTransactionRequest({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', // [!code focus] + value: parseEther('1'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### accessList + +`AccessList | undefined` + +The access list. + +::: code-group +```tsx [index.tsx] +import { usePrepareTransactionRequest } from 'wagmi' +import { parseEther } from 'viem' + +function App() { + const result = usePrepareTransactionRequest({ + accessList: [ // [!code focus:6] + { + address: '0x1', + storageKeys: ['0x1'], + }, + ], + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +Chain ID to prepare the transaction request for. + +::: code-group +```tsx [index.tsx] +import { usePrepareTransactionRequest } from 'wagmi' +import { parseEther } from 'viem' + +function App() { + const result = usePrepareTransactionRequest({ + chainId: mainnet.id, // [!code focus] + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### data + +`` `0x${string}` | undefined `` + +A contract hashed method call with encoded args. + +::: code-group +```tsx [index.tsx] +import { usePrepareTransactionRequest } from 'wagmi' +import { parseEther } from 'viem' + +function App() { + const result = usePrepareTransactionRequest({ + data: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', // [!code focus] + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### gasPrice + +`bigint | undefined` + +The price (in wei) to pay per gas. Only applies to [Legacy Transactions](https://viem.sh/docs/glossary/terms.html#legacy-transaction). + +::: code-group +```tsx [index.tsx] +import { usePrepareTransactionRequest } from 'wagmi' +import { parseEther, parseGwei } from 'viem' + +function App() { + const result = usePrepareTransactionRequest({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + gasPrice: parseGwei('20'), // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### maxFeePerGas + +`bigint | undefined` + +Total fee per gas (in wei), inclusive of `maxPriorityFeePerGas`. Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```tsx [index.tsx] +import { usePrepareTransactionRequest } from 'wagmi' +import { parseEther, parseGwei } from 'viem' + +function App() { + const result = usePrepareTransactionRequest({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + maxFeePerGas: parseGwei('20'), // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### maxPriorityFeePerGas + +`bigint | undefined` + +Max priority fee per gas (in wei). Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```tsx [index.tsx] +import { usePrepareTransactionRequest } from 'wagmi' +import { parseEther, parseGwei } from 'viem' + +function App() { + const result = usePrepareTransactionRequest({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + maxFeePerGas: parseGwei('20'), + maxPriorityFeePerGas: parseGwei('2'), // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### nonce + +`number | undefined` + +Unique number identifying this transaction. + +::: code-group +```tsx [index.tsx] +import { usePrepareTransactionRequest } from 'wagmi' +import { parseEther } from 'viem' + +function App() { + const result = usePrepareTransactionRequest({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), + nonce: 5, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### parameters + +`("fees" | "gas" | "nonce" | "type")[] | undefined` + +Parameters to prepare. + +For instance, if `["gas", "nonce"]` is provided, then only the `gas` and `nonce` parameters will be prepared. + +::: code-group +```tsx [index.tsx] +import { usePrepareTransactionRequest } from 'wagmi' +import { parseEther } from 'viem' + +function App() { + const result = usePrepareTransactionRequest({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + parameters: ['gas', 'nonce'], // [!code focus] + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### value + +`bigint | undefined` + +Value in wei sent with this transaction. + +::: code-group +```tsx [index.tsx] +import { usePrepareTransactionRequest } from 'wagmi' +import { parseEther } from 'viem' + +function App() { + const result = usePrepareTransactionRequest({ + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { usePrepareTransactionRequest } from 'wagmi' +import { parseEther } from 'viem' +import { config } from './config' // [!code focus] + +function App() { + const result = usePrepareTransactionRequest({ + config, // [!code focus] + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { usePrepareTransactionRequest } from 'wagmi' +import { parseEther } from 'viem' +import { config } from './config' + +function App() { + const result = usePrepareTransactionRequest({ + scopeKey: 'foo' // [!code focus] + account: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + value: parseEther('1'), + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UsePrepareTransactionRequestReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`prepareTransactionRequest`](/core/api/actions/prepareTransactionRequest) diff --git a/wagmi-project/site/react/api/hooks/useProof.md b/wagmi-project/site/react/api/hooks/useProof.md new file mode 100644 index 0000000000..76adcdca4d --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useProof.md @@ -0,0 +1,224 @@ +--- +title: useProof +description: Hook for return the account and storage values of the specified account including the Merkle-proof. +--- + + + +# useProof + +Hook for return the account and storage values of the specified account including the Merkle-proof. + +## Import + +```ts +import { useProof } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useProof } from 'wagmi' + +function App() { + const result = useProof({ + address: '0x4200000000000000000000000000000000000016', + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseProofParameters } from 'wagmi' +``` + +### address + +`Address | undefined` + +The account address to get the proof for. + +::: code-group +```tsx [index.tsx] +import { useProof } from 'wagmi' + +function App() { + const result = useProof({ + address: '0x4200000000000000000000000000000000000016', // [!code focus] + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### storageKeys + +`` `0x${string}`[] | undefined `` + +Array of storage-keys that should be proofed and included. + +::: code-group +```tsx [index.tsx] +import { useProof } from 'wagmi' + +function App() { + const result = useProof({ + address: '0x4200000000000000000000000000000000000016', + storageKeys: [ // [!code focus:3] + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockNumber + +`bigint | undefined` + +Proof at a given block number. + +::: code-group +```tsx [index.tsx] +import { useProof } from 'wagmi' + +function App() { + const result = useProof({ + address: '0x4200000000000000000000000000000000000016', + blockNumber: 42069n, // [!code focus] + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Proof at a given block tag. + +::: code-group +```tsx [index.tsx] +import { useProof } from 'wagmi' + +function App() { + const result = useProof({ + address: '0x4200000000000000000000000000000000000016', + blockTag: 'latest', // [!code focus] + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +The ID of chain to get the proof for. + +::: code-group +```tsx [index.tsx] +import { useProof } from 'wagmi' +import { optimism } from 'wagmi/chains' + +function App() { + const result = useProof({ + chainId: optimism.id, // [!code focus] + address: '0x4200000000000000000000000000000000000016', + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useProof } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useProof({ + config, // [!code focus] + address: '0x4200000000000000000000000000000000000016', + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { useProof } from 'wagmi' +import { config } from './config' + +function App() { + const result = useProof({ + scopeKey: 'foo' // [!code focus] + address: '0x4200000000000000000000000000000000000016', + storageKeys: [ + '0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99', + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseProofReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getProof`](/core/api/actions/getProof) diff --git a/wagmi-project/site/react/api/hooks/usePublicClient.md b/wagmi-project/site/react/api/hooks/usePublicClient.md new file mode 100644 index 0000000000..9f0411055b --- /dev/null +++ b/wagmi-project/site/react/api/hooks/usePublicClient.md @@ -0,0 +1,93 @@ +--- +title: usePublicClient +description: Hook for getting Viem `PublicClient` instance. +--- + +# usePublicClient + +Hook for getting Viem [`PublicClient`](https://viem.sh/docs/clients/public.html) instance. + +## Import + +```ts +import { usePublicClient } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { usePublicClient } from 'wagmi' + +function App() { + const client = usePublicClient() +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +::: warning +If you want to optimize bundle size, you should use [`useClient`](/react/api/hooks/useClient) along with Viem's [tree-shakable actions](https://viem.sh/docs/clients/custom.html#tree-shaking) instead. Since Public Client has all public actions attached directly to it. +::: + +## Parameters + +```ts +import { type UsePublicClientParameters } from 'wagmi' +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when getting Viem Public Client. + +::: code-group +```ts [index.ts] +import { usePublicClient } from 'wagmi' +import { mainnet } from 'wagmi/chains' // [!code focus] +import { config } from './config' + +function App() { + const client = usePublicClient({ + chainId: mainnet.id, // [!code focus] + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { usePublicClient } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const client = usePublicClient({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type UsePublicClientReturnType } from 'wagmi' +``` + +`PublicClient | undefined` + +Viem [`PublicClient`](https://viem.sh/docs/clients/public.html) instance. + +## Action + +- [`getPublicClient`](/core/api/actions/getPublicClient) +- [`watchPublicClient`](/core/api/actions/watchPublicClient) diff --git a/wagmi-project/site/react/api/hooks/useReadContract.md b/wagmi-project/site/react/api/hooks/useReadContract.md new file mode 100644 index 0000000000..07be91e010 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useReadContract.md @@ -0,0 +1,406 @@ +--- +title: useReadContract +description: Hook for calling a read-only function on a contract, and returning the response. +--- + + + +# useReadContract + +Hook for calling a **read-only** function on a contract, and returning the response. + +A **read-only** function (constant function) on a Solidity contract is denoted by a pure or view keyword. They can only read the state of the contract, and cannot make any changes to it. Since read-only methods do not change the state of the contract, they do not require any gas to be executed, and can be called by any user without the need to pay for gas. + +## Import + +```ts +import { useReadContract } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useReadContract } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useReadContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'totalSupply', + }) +} +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseReadContractParameters } from 'wagmi' +``` + +### abi + +`Abi | undefined` + +The contract's ABI. Check out the [TypeScript docs](/react/typescript#const-assert-abis-typed-data) for how to set up ABIs for maximum type inference and safety. + +::: code-group +```tsx [index.tsx] +import { useReadContract } from 'wagmi' +import { abi } from './abi' // [!code focus] + +function App() { + const result = useReadContract({ + abi, // [!code focus] + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'totalSupply', + }) +} +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### account + +`Account | undefined` + +Account to use when calling the contract (`msg.sender`). + +::: code-group +```tsx [index.tsx] +import { useReadContract } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useReadContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'balanceOf', + args: ['0x6b175474e89094c44da98b954eedeac495271d0f'], + account: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] + }) +} +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### address + +`Address | undefined` + +The contract's address. + +::: code-group +```tsx [index.tsx] +import { useReadContract } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useReadContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', // [!code focus] + functionName: 'totalSupply', + }) +} +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### args + +`readonly unknown[] | undefined` + +- Arguments to pass when calling the contract. +- Inferred from [`abi`](#abi) and [`functionName`](#functionname). + +::: code-group +```tsx [index.tsx] +import { useReadContract } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useReadContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'balanceOf', + args: ['0x6b175474e89094c44da98b954eedeac495271d0f'], // [!code focus] + }) +} +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +--- + +### blockNumber + +`bigint | undefined` + +Block number to call contract at. + +::: code-group +```tsx [index.tsx] +import { useReadContract } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useReadContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'totalSupply', + blockNumber: 17829139n, // [!code focus] + }) +} +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to call contract at. + +::: code-group +```tsx [index.tsx] +import { useReadContract } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useReadContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'totalSupply', + blockTag: 'safe', // [!code focus] + }) +} +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useReadContract } from 'wagmi' +import { mainnet } from 'wagmi/chains' // [!code focus] +import { abi } from './abi' + +function App() { + const result = useReadContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'totalSupply', + chainId: mainnet.id, // [!code focus] + }) +} +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useReadContract } from 'wagmi' +import { abi } from './abi' +import { config } from './config' // [!code focus] + +function App() { + const result = useReadContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'totalSupply', + config, // [!code focus] + }) +} +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### functionName + +`string | undefined` + +- Function to call on the contract. +- Inferred from [`abi`](#abi). + +::: code-group +```tsx [index.tsx] +import { useReadContract } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useReadContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'balanceOf', // [!code focus] + args: ['0x6b175474e89094c44da98b954eedeac495271d0f'], + }) +} +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { useReadContract } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useReadContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'balanceOf', + args: ['0x6b175474e89094c44da98b954eedeac495271d0f'], + scopeKey: 'foo', // [!code focus] + }) +} +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseReadContractReturnType } from 'wagmi' +``` + +The return type's [`data`](#data) property is inferrable via the combination of [`abi`](#abi), [`functionName`](#functionname), and [`args`](#args). Check out the [TypeScript docs](/react/typescript#const-assert-abis-typed-data) for more info. + + + +## Type Inference + +With [`abi`](#abi) setup correctly, TypeScript will infer the correct types for [`functionName`](#functionname), [`args`](#args), and the return type. See the Wagmi [TypeScript docs](/react/typescript) for more information. + +::: code-group +```ts twoslash [Inline] +import { createConfig, http, useReadContract } from 'wagmi' +import { mainnet, sepolia } from 'wagmi/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +// ---cut--- +const result = useReadContract({ + abi: [ + { + type: 'function', + name: 'balanceOf', + stateMutability: 'view', + inputs: [{ name: 'account', type: 'address' }], + outputs: [{ type: 'uint256' }], + }, + { + type: 'function', + name: 'totalSupply', + stateMutability: 'view', + inputs: [], + outputs: [{ name: 'supply', type: 'uint256' }], + }, + ], + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'balanceOf', + // ^? + + + args: ['0x6b175474e89094c44da98b954eedeac495271d0f'], + // ^? +}) + +result.data +// ^? +``` +```ts twoslash [Const-Asserted] +import { createConfig, http, useReadContract } from 'wagmi' +import { mainnet, sepolia } from 'wagmi/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +// ---cut--- +const abi = [ + { + type: 'function', + name: 'balanceOf', + stateMutability: 'view', + inputs: [{ name: 'account', type: 'address' }], + outputs: [{ type: 'uint256' }], + }, + { + type: 'function', + name: 'totalSupply', + stateMutability: 'view', + inputs: [], + outputs: [{ name: 'supply', type: 'uint256' }], + }, +] as const + +const result = useReadContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'balanceOf', + // ^? + + + args: ['0x6b175474e89094c44da98b954eedeac495271d0f'], + // ^? +}) + +result.data +// ^? +``` +::: + + + +## Action + +- [`readContract`](/core/api/actions/readContract) diff --git a/wagmi-project/site/react/api/hooks/useReadContracts.md b/wagmi-project/site/react/api/hooks/useReadContracts.md new file mode 100644 index 0000000000..48436c9362 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useReadContracts.md @@ -0,0 +1,394 @@ +--- +title: useReadContracts +description: Hook for calling multiple read methods on a contract. +--- + +# useReadContracts + +Hook for calling multiple read methods on a contract. + +## Import + +```ts +import { useReadContracts } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useReadContracts } from 'wagmi' + +const wagmigotchiContract = { + address: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1', + abi: wagmigotchiABI, +} as const +const mlootContract = { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, +} as const + +function App() { + const result = useReadContracts({ + contracts: [ + { + ...wagmigotchiContract, + functionName: 'getAlive', + }, + { + ...wagmigotchiContract, + functionName: 'getBoredom', + }, + { + ...mlootContract, + functionName: 'getChest', + args: [69], + }, + { + ...mlootContract, + functionName: 'getWaist', + args: [69], + }, + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseReadContractsParameters } from 'wagmi' +``` + +### contracts + +`readonly Contract[]` + +Set of contracts to call. + +#### abi + +`Abi | undefined` + +The contract's ABI. Check out the [TypeScript docs](/react/typescript#const-assert-abis-typed-data) for how to set up ABIs for maximum type inference and safety. + +::: code-group +```tsx [index.tsx] +import { useReadContracts } from 'wagmi' + +function App() { + const result = useReadContracts({ + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, // [!code hl] + functionName: 'getChest', + args: [69], + }, + // ... + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +#### address + +`Address | undefined` + +The contract's address. + +::: code-group +```tsx [index.tsx] +import { useReadContracts } from 'wagmi' + +function App() { + const result = useReadContracts({ + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', // [!code hl] + abi: mlootABI, + functionName: 'getChest', + args: [69], + }, + // ... + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +#### functionName + +`string | undefined` + +- Function to call on the contract. +- Inferred from [`abi`](#abi). + +::: code-group +```tsx [index.tsx] +import { useReadContracts } from 'wagmi' + +function App() { + const result = useReadContracts({ + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', // [!code hl] + args: [69], + }, + // ... + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +#### args + +`readonly unknown[] | undefined` + +- Arguments to pass when calling the contract. +- Inferred from [`abi`](#abi) and [`functionName`](#functionname). + +::: code-group +```tsx [index.tsx] +import { useReadContracts } from 'wagmi' + +function App() { + const result = useReadContracts({ + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69], // [!code hl] + }, + // ... + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +#### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useReadContracts } from 'wagmi' + +function App() { + const result = useReadContracts({ + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69], + chainId: 1 // [!code hl] + }, + // ... + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + +### allowFailure + +`boolean` + +Whether or not the Hook should throw if a call reverts. If set to `true` (default), and a call reverts, then `useReadContracts` will fail silently and its error will be logged in the results array. Defaults to `true`. + +::: code-group +```tsx [index.tsx] +import { useReadContracts } from 'wagmi' + +function App() { + const result = useReadContracts({ + allowFailure: false, // [!code hl] + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69] + }, + // ... + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + +### batchSize + +`number` + +The maximum size (in bytes) for each calldata chunk. Set to `0` to disable the size limit. Defaults to `1024`. + +> Note: Some RPC Providers limit the amount of calldata (`data`) that can be sent in a single `eth_call` request. It is best to check with your RPC Provider to see if there are any calldata size limits to `eth_call` requests. + +::: code-group +```tsx [index.tsx] +import { useReadContracts } from 'wagmi' + +function App() { + const result = useReadContracts({ + batchSize: 1024, // [!code hl] + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69] + }, + // ... + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockNumber + +`number` + +The block number to perform the read against. + +::: code-group +```tsx [index.tsx] +import { useReadContracts } from 'wagmi' + +function App() { + const result = useReadContracts({ + blockNumber: 69420n, // [!code hl] + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69] + }, + // ... + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to read against. + +::: code-group +```tsx [index.tsx] +import { useReadContracts } from 'wagmi' + +function App() { + const result = useReadContracts({ + blockTag: 'safe', // [!code hl] + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69] + }, + // ... + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useReadContracts } from 'wagmi' +import { config } from './config' + +function App() { + const result = useReadContracts({ + config, // [!code hl] + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69] + }, + // ... + ], + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### multicallAddress + +`Address` + +Address of multicall contract. + +::: code-group +```tsx [index.tsx] +import { useReadContracts } from 'wagmi' + +function App() { + const result = useReadContracts({ + contracts: [ + { + address: '0x1dfe7ca09e99d10835bf73044a23b73fc20623df', + abi: mlootABI, + functionName: 'getChest', + args: [69] + }, + // ... + ], + multicallAddress: '0xca11bde05977b3631167028862be2a173976ca11', // [!code hl] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseReadContractsReturnType } from 'wagmi' +``` + + + +## Action + +- [`readContracts`](/core/api/actions/readContracts) diff --git a/wagmi-project/site/react/api/hooks/useReconnect.md b/wagmi-project/site/react/api/hooks/useReconnect.md new file mode 100644 index 0000000000..7aff4945c9 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useReconnect.md @@ -0,0 +1,111 @@ +--- +title: useReconnect +description: Hook for reconnecting connectors. +--- + + + +# useReconnect + +Hook for reconnecting [connectors](/core/api/connectors). + +## Import + +```ts +import { useReconnect } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useReconnect } from 'wagmi' +import { useEffect } from 'react' + +function App() { + const { reconnect } = useReconnect() + + useEffect(() => { + reconnect() + }, []) +} +``` + +::: + +::: tip +When [`WagmiProvider['reconnectOnMount']`](/react/api/WagmiProvider#reconnectonmount) is `true`, `reconnect` is called automatically on mount. +::: + +## Parameters + +```ts +import { type UseReconnectParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useReconnect } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useReconnect({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseReconnectReturnType } from 'wagmi' +``` + +### connectors + +`readonly Connector[]` + +Globally configured connectors via [`createConfig`](/react/api/createConfig#connectors). + +::: code-group +```tsx [index.tsx] +import { useReconnect } from 'wagmi' +import { mainnet } from 'wagmi/chains' +import { useEffect } from 'react' + +function App() { + const { reconnect, connectors } = useReconnect() + + useEffect(() => { + reconnect({ connectors }) + }, []) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + + + +## Action + +- [`reconnect`](/core/api/actions/reconnect) diff --git a/wagmi-project/site/react/api/hooks/useSendCalls.md b/wagmi-project/site/react/api/hooks/useSendCalls.md new file mode 100644 index 0000000000..d7020fd8bf --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useSendCalls.md @@ -0,0 +1,103 @@ +--- +title: useSendCalls +description: Hook that requests for the wallet to sign and broadcast a batch of calls (transactions) to the network. +--- + + + +# useSendCalls + +Hook that requests for the wallet to sign and broadcast a batch of calls (transactions) to the network. + +[Read more.](https://github.com/ethereum/EIPs/blob/815028dc634463e1716fc5ce44c019a6040f0bef/EIPS/eip-5792.md#wallet_sendcalls) + +## Import + +```ts +import { useSendCalls } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useSendCalls } from 'wagmi' +import { parseEther } from 'viem' + +function App() { + const { sendCalls } = useSendCalls() + + return ( + + ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseSendCallsParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useSendCalls } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useSendCalls({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseSendCallsReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`sendCalls`](/core/api/actions/sendCalls) diff --git a/wagmi-project/site/react/api/hooks/useSendTransaction.md b/wagmi-project/site/react/api/hooks/useSendTransaction.md new file mode 100644 index 0000000000..c9d4bf441b --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useSendTransaction.md @@ -0,0 +1,93 @@ +--- +title: useSendTransaction +description: Hook for creating, signing, and sending transactions to networks. +--- + + + +# useSendTransaction + +Hook for creating, signing, and sending transactions to networks. + +## Import + +```ts +import { useSendTransaction } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useSendTransaction } from 'wagmi' +import { parseEther } from 'viem' + +function App() { + const { sendTransaction } = useSendTransaction() + + return ( + + ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseSendTransactionParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useSendTransaction } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useSendTransaction({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseSendTransactionReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`sendTransaction`](/core/api/actions/sendTransaction) diff --git a/wagmi-project/site/react/api/hooks/useShowCallsStatus.md b/wagmi-project/site/react/api/hooks/useShowCallsStatus.md new file mode 100644 index 0000000000..6fb26e9f05 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useShowCallsStatus.md @@ -0,0 +1,96 @@ +--- +title: useShowCallsStatus +description: Action to request for the wallet to show information about a call batch +--- + + + +# useShowCallsStatus + +Action to request for the wallet to show information about a call batch that was sent via `useShowCalls`. + +[Read more.](https://github.com/ethereum/EIPs/blob/1663ea2e7a683285f977eda51c32cec86553f585/EIPS/eip-5792.md#wallet_showcallsstatus) + + + +## Import + +```ts +import { useShowCallsStatus } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useShowCallsStatus } from 'wagmi' +import { parseEther } from 'viem' + +function App() { + const { showCallsStatus } = useShowCallsStatus() + + return ( + + ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseShowCallsStatusParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useShowCallsStatus } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useShowCallsStatus({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseShowCallsStatusReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`showCallsStatus`](/core/api/actions/showCallsStatus) diff --git a/wagmi-project/site/react/api/hooks/useSignMessage.md b/wagmi-project/site/react/api/hooks/useSignMessage.md new file mode 100644 index 0000000000..7b0ffb3a4a --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useSignMessage.md @@ -0,0 +1,85 @@ +--- +title: useSignMessage +description: Hook for signing messages. +--- + + + +# useSignMessage + +Hook for signing messages. + +## Import + +```ts +import { useSignMessage } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useSignMessage } from 'wagmi' + +function App() { + const { signMessage } = useSignMessage() + + return ( + + ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseSignMessageParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useSignMessage } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useSignMessage({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseSignMessageReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`signMessage`](/core/api/actions/signMessage) diff --git a/wagmi-project/site/react/api/hooks/useSignTypedData.md b/wagmi-project/site/react/api/hooks/useSignTypedData.md new file mode 100644 index 0000000000..140b0e86a3 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useSignTypedData.md @@ -0,0 +1,217 @@ +--- +title: useSignTypedData +description: Hook for signing typed data and calculating an Ethereum-specific EIP-712 signature. +--- + + + +# useSignTypedData + +Hook for signing typed data and calculating an Ethereum-specific [EIP-712](https://eips.ethereum.org/EIPS/eip-712) signature. + +## Import + +```ts +import { useSignTypedData } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useSignTypedData } from 'wagmi' + + +function App() { + const { signTypedData } = useSignTypedData() + + return ( + + ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseSignTypedDataParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useSignTypedData } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useSignTypedData({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseSignTypedDataReturnType } from 'wagmi' +``` + + + +## Type Inference + +With [`types`](/core/api/actions/signTypedData#types) setup correctly, TypeScript will infer the correct types for [`domain`](/core/api/actions/signTypedData#domain), [`message`](/core/api/actions/signTypedData#message), and [`primaryType`](/core/api/actions/signTypedData#primarytype). See the Wagmi [TypeScript docs](/react/typescript) for more information. + +::: code-group +```ts twoslash [Inline] +import { useSignTypedData } from 'wagmi' +// ---cut--- +const { signTypedData } = useSignTypedData() + +signTypedData({ + types: { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + }, + primaryType: 'Mail', + // ^? + + + message: { + // ^? + + + + + + + + + + + + + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, +}) +``` +```ts twoslash [Const-Asserted] +import { useSignTypedData } from 'wagmi' +// ---cut--- +const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const + +const { signTypedData } = useSignTypedData() + +signTypedData({ + types, + primaryType: 'Mail', + // ^? + + + message: { + // ^? + + + + + + + + + + + + + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, +}) +``` +::: + + + +## Action + +- [`signTypedData`](/core/api/actions/signTypedData) diff --git a/wagmi-project/site/react/api/hooks/useSimulateContract.md b/wagmi-project/site/react/api/hooks/useSimulateContract.md new file mode 100644 index 0000000000..03872f53e5 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useSimulateContract.md @@ -0,0 +1,686 @@ +--- +title: useSimulateContract +description: Hook for simulating/validating a contract interaction. +--- + + + +# useSimulateContract + +Hook for simulating/validating a contract interaction. + +## Import + +```ts +import { useSimulateContract } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useSimulateContract } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Parameters + +```ts +import { type UseSimulateContractParameters } from 'wagmi' +``` + +### abi + +`Abi | undefined` + +The contract's ABI. Check out the [TypeScript docs](/react/typescript#const-assert-abis-typed-data) for how to set up ABIs for maximum type inference and safety. + +::: code-group +```tsx [index.tsx] +import { useSimulateContract } from 'wagmi' +import { abi } from './abi' // [!code focus] + +function App() { + const result = useSimulateContract({ + abi, // [!code focus] + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### accessList + +`AccessList | undefined` + +The access list. + +::: code-group +```tsx [index.ts] +import { useSimulateContract } from 'wagmi' +import { abi } from './abi' +import { config } from './config' + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + accessList: [{ // [!code focus] + address: '0x1', // [!code focus] + storageKeys: ['0x1'], // [!code focus] + }], // [!code focus] + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### account + +`Account | undefined` + +Account to use when calling the contract (`msg.sender`). Throws if account is not found on [`connector`](#connector). + +::: code-group +```tsx [index.tsx] +import { useSimulateContract } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + account: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### address + +`Address | undefined` + +The contract's address. + +::: code-group +```tsx [index.tsx] +import { useSimulateContract } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', // [!code focus] + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### args + +`readonly unknown[] | undefined` + +- Arguments to pass when calling the contract. +- Inferred from [`abi`](#abi) and [`functionName`](#functionname). + +::: code-group +```tsx [index.tsx] +import { useSimulateContract } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ // [!code focus] + '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', // [!code focus] + 123n, // [!code focus] + ], // [!code focus] + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +--- + +### blockNumber + +`bigint | undefined` + +Block number to call contract at. + +::: code-group +```tsx [index.tsx] +import { useSimulateContract } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + blockNumber: 17829139n, // [!code focus] + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to call contract at. + +::: code-group +```tsx [index.tsx] +import { useSimulateContract } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + blockTag: 'safe', // [!code focus] + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useSimulateContract } from 'wagmi' +import { mainnet } from 'wagmi/chains' // [!code focus] +import { abi } from './abi' + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + chainId: mainnet.id, // [!code focus] + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useSimulateContract } from 'wagmi' +import { abi } from './abi' +import { config } from './config' // [!code focus] + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + config, // [!code focus] + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +[Connector](/react/api/connectors) to simulate transaction with. + +::: code-group +```tsx [index.ts] +import { useConnectorClient, useSimulateContract } from 'wagmi' +import { abi } from './abi' +import { config } from './config' + +function App() { + const { data: connector } = useConnectorClient() + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + connector, // [!code focus] + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### dataSuffix + +`` `0x${string}` | undefined `` + +Data to append to the end of the calldata. Useful for adding a ["domain" tag](https://opensea.notion.site/opensea/Seaport-Order-Attributions-ec2d69bf455041a5baa490941aad307f). + +::: code-group +```tsx [index.ts] +import { useSimulateContract } from 'wagmi' +import { parseGwei } from 'viem' +import { abi } from './abi' +import { config } from './config' + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + dataSuffix: '0xdeadbeef', // [!code focus] + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### functionName + +`string | undefined` + +- Function to call on the contract. +- Inferred from [`abi`](#abi). + +::: code-group +```tsx [index.tsx] +import { useSimulateContract } from 'wagmi' +import { abi } from './abi' + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', // [!code focus] + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### gas + +`bigint | undefined` + +Gas provided for transaction execution. + +::: code-group +```tsx [index.ts] +import { useSimulateContract } from 'wagmi' +import { parseGwei } from 'viem' +import { abi } from './abi' +import { config } from './config' + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + gas: parseGwei('20'), // [!code focus] + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +--- + +### gasPrice + +`bigint | undefined` + +The price in wei to pay per gas. Only applies to [Legacy Transactions](https://viem.sh/docs/glossary/terms.html#legacy-transaction). + +::: code-group +```tsx [index.ts] +import { useSimulateContract } from 'wagmi' +import { parseGwei } from 'viem' +import { abi } from './abi' +import { config } from './config' + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + gasPrice: parseGwei('20'), // [!code focus] + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### maxFeePerGas + +`bigint | undefined` + +Total fee per gas in wei, inclusive of [`maxPriorityFeePerGas`](#maxPriorityFeePerGas). Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```tsx [index.ts] +import { useSimulateContract } from 'wagmi' +import { parseGwei } from 'viem' +import { abi } from './abi' +import { config } from './config' + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + maxFeePerGas: parseGwei('20'), // [!code focus] + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### maxPriorityFeePerGas + +`bigint | undefined` + +Max priority fee per gas in wei. Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```tsx [index.ts] +import { useSimulateContract } from 'wagmi' +import { parseGwei } from 'viem' +import { abi } from './abi' +import { config } from './config' + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + maxFeePerGas: parseGwei('20'), + maxPriorityFeePerGas: parseGwei('2'), // [!code focus] + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +--- + +### nonce + +`number` + +Unique number identifying this transaction. + +::: code-group +```tsx [index.ts] +import { useSimulateContract } from 'wagmi' +import { abi } from './abi' +import { config } from './config' + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + nonce: 123, // [!code focus] + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### type + +`'legacy' | 'eip1559' | 'eip2930' | undefined` + +Optional transaction request type to narrow parameters. + +::: code-group +```tsx [index.ts] +import { useSimulateContract } from 'wagmi' +import { abi } from './abi' +import { config } from './config' + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + type: 'eip1559', // [!code focus] + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### value + +`bigint | undefined` + +Value in wei sent with this transaction. + +::: code-group +```tsx [index.ts] +import { useSimulateContract } from 'wagmi' +import { parseEther } from 'viem' +import { abi } from './abi' +import { config } from './config' + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + value: parseEther('0.01'), // [!code focus] + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.ts] +import { useSimulateContract } from 'wagmi' +import { abi } from './abi' +import { config } from './config' + +function App() { + const result = useSimulateContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'transferFrom', + args: [ + '0xd2135CfB216b74109775236E36d4b433F1DF507B', + '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', + 123n, + ], + scopeKey: 'foo', // [!code focus] + }) +} +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseSimulateContractReturnType } from 'wagmi' +``` + +The return type's [`data`](#data) property is inferrable via the combination of [`abi`](#abi), [`functionName`](#functionname), and [`args`](#args). Check out the [TypeScript docs](/react/typescript#const-assert-abis-typed-data) for more info. + + + +## Type Inference + +With [`abi`](#abi) setup correctly, TypeScript will infer the correct types for [`functionName`](#functionname), [`args`](#args), and [`value`](#value). See the Wagmi [TypeScript docs](/react/typescript) for more information. + + + +## Action + +- [`simulateContract`](/core/api/actions/simulateContract) diff --git a/wagmi-project/site/react/api/hooks/useStorageAt.md b/wagmi-project/site/react/api/hooks/useStorageAt.md new file mode 100644 index 0000000000..12c524ac1e --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useStorageAt.md @@ -0,0 +1,208 @@ +--- +title: useStorageAt +description: Hook for returning the value from a storage slot at a given address. +--- + + + +# useStorageAt + +Hook for for returning the value from a storage slot at a given address. + +## Import + +```ts +import { useStorageAt } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useStorageAt } from 'wagmi' + +function App() { + const result = useStorageAt({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + slot: '0x0', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseStorageAtParameters } from 'wagmi' +``` + +### address + +`Address | undefined` + +The contract address. + +::: code-group +```tsx [index.tsx] +import { useStorageAt } from 'wagmi' + +function App() { + const result = useStorageAt({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', // [!code focus] + slot: '0x0', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### slot + +`Hex | undefined` + +The storage position (as a hex encoded value). + +::: code-group +```tsx [index.tsx] +import { useStorageAt } from 'wagmi' + +function App() { + const result = useStorageAt({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + slot: '0x0', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## blockNumber + +`bigint | undefined` + +The block number to check the storage at. + +::: code-group +```tsx [index.tsx] +import { useStorageAt } from 'wagmi' + +function App() { + const result = useStorageAt({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + blockNumber: 16280770n, // [!code focus] + slot: '0x0', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +The block tag to check the storage at. + +::: code-group +```tsx [index.tsx] +import { useStorageAt } from 'wagmi' + +function App() { + const result = useStorageAt({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + blockTag: 'safe', // [!code focus] + slot: '0x0', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +The chain ID to check the storage at. + +::: code-group +```tsx [index.tsx] +import { useStorageAt } from 'wagmi' +import { mainnet } from '@wagmi/core/chains' + +function App() { + const result = useStorageAt({ + chainId: mainnet.id, // [!code focus] + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + slot: '0x0', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useStorageAt } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useStorageAt({ + config, // [!code focus] + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + slot: '0x0', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { useStorageAt } from 'wagmi' +import { config } from './config' + +function App() { + const result = useStorageAt({ + scopeKey: 'foo' // [!code focus] + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + slot: '0x0', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseStorageAtReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getStorageAt`](/core/api/actions/getStorageAt) diff --git a/wagmi-project/site/react/api/hooks/useSwitchAccount.md b/wagmi-project/site/react/api/hooks/useSwitchAccount.md new file mode 100644 index 0000000000..8dc3395a70 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useSwitchAccount.md @@ -0,0 +1,116 @@ +--- +title: useSwitchAccount +description: Hook for switching the current account. +--- + + + +# useSwitchAccount + +Hook for switching the current account. + +## Import + +```ts +import { useSwitchAccount } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useSwitchAccount } from 'wagmi' + +function App() { + const { connectors, switchAccount } = useSwitchAccount() + + return ( +
+ {connectors.map((connector) => ( + + ))} +
+ ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseSwitchAccountParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useSwitchAccount } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useSwitchAccount({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseSwitchAccountReturnType } from 'wagmi' +``` + +### connectors + +`readonly Connector[]` + +Globally configured and actively connected connectors. Useful for rendering a list of available connectors to switch to. + +::: code-group +```tsx [index.tsx] +import { useSwitchAccount } from 'wagmi' + +function App() { + const { connectors, switchAccount } = useSwitchAccount() + + return ( +
+ {connectors.map((connector) => ( + + ))} +
+ ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + + + +## Action + +- [`switchAccount`](/core/api/actions/switchAccount) diff --git a/wagmi-project/site/react/api/hooks/useSwitchChain.md b/wagmi-project/site/react/api/hooks/useSwitchChain.md new file mode 100644 index 0000000000..3b139bd701 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useSwitchChain.md @@ -0,0 +1,120 @@ +--- +title: useSwitchChain +description: Hook for switching the target chain for a connector or the Wagmi `Config`. +--- + + + +# useSwitchChain + +Hook for switching the target chain for a connector or the Wagmi [`Config`](/react/api/createConfig#config). + +## Import + +```ts +import { useSwitchChain } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useSwitchChain } from 'wagmi' + +function App() { + const { chains, switchChain } = useSwitchChain() + + return ( +
+ {chains.map((chain) => ( + + ))} +
+ ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +::: tip +When connected, `switchChain` will switch the target chain for the connector. When not connected, `switchChain` will switch the target chain for the Wagmi [`Config`](/react/api/createConfig#config). +::: + +## Parameters + +```ts +import { type UseSwitchChainParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useSwitchChain } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useSwitchChain({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseSwitchChainReturnType } from 'wagmi' +``` + +### chains + +`readonly [Chain, ...Chain[]]` + +Globally configured chains. Useful for rendering a list of available chains to switch to. + +::: code-group +```tsx [index.tsx] +import { useSwitchChain } from 'wagmi' + +function App() { + const { chains, switchChain } = useSwitchChain() + + return ( +
+ {chains.map((chain) => ( + + ))} +
+ ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + + + +## Action + +- [`switchChain`](/core/api/actions/switchChain) diff --git a/wagmi-project/site/react/api/hooks/useToken.md b/wagmi-project/site/react/api/hooks/useToken.md new file mode 100644 index 0000000000..cd4c6dbec2 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useToken.md @@ -0,0 +1,162 @@ +--- +title: useToken +description: Hook for fetching token info. +--- + + + +# useToken [deprecated](/react/guides/migrate-from-v1-to-v2#deprecated-usetoken) + +Hook for fetching token info. + +## Import + +```ts +import { useToken } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useToken } from 'wagmi' + +function App() { + const result = useToken({ + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseTokenParameters } from 'wagmi' +``` + +### address + +`Address | undefined` + +Address to get token for. [`enabled`](#enabled) set to `false` if `address` is `undefined`. + +::: code-group +```tsx [index.tsx] +import { useToken } from 'wagmi' +import { mainnet } from 'wagmi/chains' + +function App() { + const result = useToken({ + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useToken } from 'wagmi' +import { mainnet } from 'wagmi/chains' // [!code focus] + +function App() { + const result = useToken({ + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + chainId: mainnet.id, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useToken } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useToken({ + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### formatUnits + +`'ether' | 'gwei' | 'wei' | number | undefined` + +- Units to use when formatting result. +- Defaults to `'ether'`. + +::: code-group +```ts [index.ts] +import { useToken } from 'wagmi' + +function App() { + const result = useToken({ + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + formatUnits: 'ether', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```ts [index.ts] +import { useToken } from 'wagmi' + +function App() { + const result = useToken({ + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + scopeKey: 'foo', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseTokenReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getToken`](/core/api/actions/getToken) diff --git a/wagmi-project/site/react/api/hooks/useTransaction.md b/wagmi-project/site/react/api/hooks/useTransaction.md new file mode 100644 index 0000000000..391f5bf802 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useTransaction.md @@ -0,0 +1,184 @@ +--- +title: useTransaction +description: Hook for fetching transactions given hashes or block identifiers. +--- + + + +# useTransaction + +Hook for fetching transactions given hashes or block identifiers. + +## Import + +```ts +import { useTransaction } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useTransaction } from 'wagmi' + +function App() { + const result = useTransaction({ + hash: '0x0fa64daeae54e207aa98613e308c2ba8abfe274f75507e741508cc4db82c8cb5', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseTransactionParameters } from 'wagmi' +``` + +--- + +### blockHash + +`bigint | undefined` + +Block hash to get transaction at (with [`index`](#index)). + +```ts +import { useTransaction } from 'wagmi' + +function App() { + const result = useTransaction({ + blockHash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', // [!code focus] + index: 0, + }) +} +``` + +### blockNumber + +`bigint | undefined` + +Block number to get transaction at (with [`index`](#index)). + +```ts +import { useTransaction } from 'wagmi' + +function App() { + const result = useTransaction({ + blockNumber: 17829139n, // [!code focus] + index: 0, + }) +} +``` + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get transaction at (with [`index`](#index)). + +```ts +import { useTransaction } from 'wagmi' + +function App() { + const result = useTransaction({ + blockTag: 'safe', // [!code focus] + index: 0, + }) +} +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +```ts +import { useTransaction } from 'wagmi' +import { mainnet } from 'wagmi/chains' + +function App() { + const result = useTransaction({ + chainId: mainnet.id, // [!code focus] + hash: '0x0fa64daeae54e207aa98613e308c2ba8abfe274f75507e741508cc4db82c8cb5', + }) +} +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useTransaction } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useTransaction({ + hash: '0x0fa64daeae54e207aa98613e308c2ba8abfe274f75507e741508cc4db82c8cb5', + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### hash + +`` `0x${string}` | undefined `` + +Hash to get transaction. [`enabled`](#enabled) set to `false` if `hash` and [`index`](#index) are `undefined`. + +```ts +import { useTransaction } from 'wagmi' + +function App() { + const result = useTransaction({ + hash: '0x0fa64daeae54e207aa98613e308c2ba8abfe274f75507e741508cc4db82c8cb5', // [!code focus] + }) +} +``` + +### index + +`number | undefined` + +An index to be used with a block identifier ([hash](#blockhash), [number](#blocknumber), or [tag](#blocktag)). [`enabled`](#enabled) set to `false` if `index` and [`hash`](#hash) are `undefined`. + +```ts +import { useTransaction } from 'wagmi' + +function App() { + const result = useTransaction({ + blockTag: 'safe', + index: 0 // [!code focus] + }) +} +``` + + + +## Return Type + +```ts +import { type UseTransactionReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getTransaction`](/core/api/actions/getTransaction) diff --git a/wagmi-project/site/react/api/hooks/useTransactionConfirmations.md b/wagmi-project/site/react/api/hooks/useTransactionConfirmations.md new file mode 100644 index 0000000000..6dec7c1319 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useTransactionConfirmations.md @@ -0,0 +1,153 @@ +--- +title: useTransactionConfirmations +description: Hook for fetching the number of blocks passed (confirmations) since the transaction was processed on a block. +--- + + + +# useTransactionConfirmations + +Hook for fetching the number of blocks passed (confirmations) since the transaction was processed on a block. If confirmations is 0, then the Transaction has not been confirmed & processed yet. + +## Import + +```ts +import { useTransactionConfirmations } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useTransactionConfirmations } from 'wagmi' + +function App() { + const result = useTransactionConfirmations({ + hash: '0x0fa64daeae54e207aa98613e308c2ba8abfe274f75507e741508cc4db82c8cb5', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseTransactionConfirmationsParameters } from 'wagmi' +``` + +--- + +### hash + +`` `0x${string}` | undefined `` + +The hash of the transaction. + +```ts +import { useTransactionConfirmations } from 'wagmi' + +function App() { + const result = useTransactionConfirmations({ + hash: '0x0fa64daeae54e207aa98613e308c2ba8abfe274f75507e741508cc4db82c8cb5', // [!code focus] + }) +} +``` + +### transactionReceipt + +`TransactionReceipt | undefined` + +The transaction receipt. + +```ts +import { useTransactionConfirmations } from 'wagmi' + +function App() { + const result = useTransactionConfirmations({ + transactionReceipt: { ... }, // [!code focus] + }) +} +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +```ts +import { useTransactionConfirmations } from 'wagmi' +import { mainnet } from 'wagmi/chains' + +function App() { + const result = useTransactionConfirmations({ + chainId: mainnet.id, // [!code focus] + hash: '0x0fa64daeae54e207aa98613e308c2ba8abfe274f75507e741508cc4db82c8cb5', + }) +} +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useTransactionConfirmations } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useTransactionConfirmations({ + config, // [!code focus] + hash: '0x0fa64daeae54e207aa98613e308c2ba8abfe274f75507e741508cc4db82c8cb5', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { useBlock } from 'wagmi' +import { config } from './config' + +function App() { + const result = useTransactionConfirmations({ + scopeKey: 'foo' // [!code focus] + hash: '0x0fa64daeae54e207aa98613e308c2ba8abfe274f75507e741508cc4db82c8cb5', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseTransactionConfirmationsReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getTransactionConfirmations`](/core/api/actions/getTransactionConfirmations) diff --git a/wagmi-project/site/react/api/hooks/useTransactionCount.md b/wagmi-project/site/react/api/hooks/useTransactionCount.md new file mode 100644 index 0000000000..142453af4b --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useTransactionCount.md @@ -0,0 +1,185 @@ +--- +title: useTransactionCount +description: Hook for fetching the number of transactions an Account has broadcast / sent. +--- + + + +# useTransactionCount + +Hook for fetching the number of transactions an Account has sent. + +## Import + +```ts +import { useTransactionCount } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useTransactionCount } from 'wagmi' + +function App() { + const result = useTransactionCount({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseTransactionCountParameters } from 'wagmi' +``` + +### address + +`Address | undefined` + +Address to get the transaction count for. [`enabled`](#enabled) set to `false` if `address` is `undefined`. + +::: code-group +```tsx [index.tsx] +import { useTransactionCount } from 'wagmi' +import { mainnet } from 'wagmi/chains' + +function App() { + const result = useTransactionCount({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +--- + +### blockNumber + +`bigint | undefined` + +Block number to get the transaction count at. + +::: code-group +```ts [index.ts] +import { useTransactionCount } from 'wagmi' + +function App() { + const result = useTransactionCount({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + blockNumber: 17829139n, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get the transaction count at. + +::: code-group +```ts [index.ts] +import { useTransactionCount } from 'wagmi' + +function App() { + const result = useTransactionCount({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + blockTag: 'latest', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useTransactionCount } from 'wagmi' +import { mainnet } from 'wagmi/chains' // [!code focus] + +function App() { + const result = useTransactionCount({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + chainId: mainnet.id, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useTransactionCount } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useTransactionCount({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { useTransactionCount } from 'wagmi' + +function App() { + const result = useTransactionCount({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + scopeKey: 'foo', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseTransactionCountReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getTransactionCount`](/core/api/actions/getTransactionCount) diff --git a/wagmi-project/site/react/api/hooks/useTransactionReceipt.md b/wagmi-project/site/react/api/hooks/useTransactionReceipt.md new file mode 100644 index 0000000000..2f909ee891 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useTransactionReceipt.md @@ -0,0 +1,142 @@ +--- +title: useTransactionReceipt +description: Hook for return the Transaction Receipt given a Transaction hash. +--- + + + +# useTransactionReceipt + +Hook for return the [Transaction Receipt](https://viem.sh/docs/glossary/terms.html#transaction-receipt) given a [Transaction](https://viem.sh/docs/glossary/terms.html#transaction) hash. + +## Import + +```ts +import { useTransactionReceipt } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useTransactionReceipt } from 'wagmi' + +function App() { + const result = useTransactionReceipt({ + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseTransactionReceiptParameters } from 'wagmi' +``` + +### hash + +`` `0x${string}` | undefined `` + +A transaction hash. + +::: code-group +```tsx [index.tsx] +import { useTransactionReceipt } from 'wagmi' + +function App() { + const result = useTransactionReceipt({ + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +The ID of chain to return the transaction receipt from. + +::: code-group +```tsx [index.tsx] +import { useTransactionReceipt } from 'wagmi' +import { mainnet } from 'wagmi/chains' + + +function App() { + const result = useTransactionReceipt({ + chainId: mainnet.id, // [!code focus] + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useTransactionReceipt } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useTransactionReceipt({ + config, // [!code focus] + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { useTransactionReceipt } from 'wagmi' +import { config } from './config' + +function App() { + const result = useTransactionReceipt({ + scopeKey: 'foo' // [!code focus] + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseTransactionReceiptReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getTransactionReceipt`](/core/api/actions/getTransactionReceipt) diff --git a/wagmi-project/site/react/api/hooks/useVerifyMessage.md b/wagmi-project/site/react/api/hooks/useVerifyMessage.md new file mode 100644 index 0000000000..e7750d79f3 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useVerifyMessage.md @@ -0,0 +1,257 @@ +--- +title: useVerifyMessage +description: Hook for verify that a message was signed by the provided address. +--- + + + +# useVerifyMessage + +Hook for verify that a message was signed by the provided address. It supports verifying messages that were signed by either a Smart Contract Account or Externally Owned Account. + +## Import + +```ts +import { useVerifyMessage } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useVerifyMessage } from 'wagmi' + +function App() { + const result = useVerifyMessage({ + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + message: 'hello world', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseVerifyMessageParameters } from 'wagmi' +``` + +### address + +`Address | undefined` + +The Ethereum address that signed the original message. + +::: code-group +```tsx [index.tsx] +import { useVerifyMessage } from 'wagmi' + +function App() { + const result = useVerifyMessage({ + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', // [!code focus] + message: 'hello world', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### message + +`string | { raw: Hex | ByteArray } | undefined` + +The message to be verified. + +By default, wagmi verifies the UTF-8 representation of the message. + +::: code-group +```tsx [index.tsx] +import { useVerifyMessage } from 'wagmi' + +function App() { + const result = useVerifyMessage({ + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + message: 'hello world', // [!code focus] + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +::: tip +By default, viem signs the UTF-8 representation of the message. To sign the data representation of the message, you can use the `raw` attribute. + +```ts +import { useVerifyMessage } from 'wagmi' + +function App() { + const result = useVerifyMessage({ + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + message: { raw: '0x68656c6c6f20776f726c64' } // [!code focus] + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +::: + +### signature + +`Hex | ByteArray | undefined` + +The signature that was generated by signing the message with the address's signer. + +::: code-group +```tsx [index.tsx] +import { useVerifyMessage } from 'wagmi' + +function App() { + const result = useVerifyMessage({ + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + message: 'hello world', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +Only used when verifying a message that was signed by a Smart Contract Account. The ID of chain to check if the contract was already deployed. + +::: code-group +```tsx [index.tsx] +import { useVerifyMessage } from 'wagmi' +import { mainnet } from 'wagmi/chains' + +function App() { + const result = useVerifyMessage({ + chainId: mainnet.id, // [!code focus] + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + message: 'hello world', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockNumber + +`bigint | undefined` + +Only used when verifying a message that was signed by a Smart Contract Account. The block number to check if the contract was already deployed. + +::: code-group +```tsx [index.tsx] +import { useVerifyMessage } from 'wagmi' +import { mainnet } from 'wagmi/chains' + +function App() { + const result = useVerifyMessage({ + blockNumber: 12345678n, // [!code focus] + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + message: 'hello world', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Only used when verifying a message that was signed by a Smart Contract Account. The block tag to check if the contract was already deployed. + +::: code-group +```tsx [index.tsx] +import { useVerifyMessage } from 'wagmi' +import { mainnet } from 'wagmi/chains' + +function App() { + const result = useVerifyMessage({ + blockTag: 'pending', // [!code focus] + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + message: 'hello world', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useVerifyMessage } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useVerifyMessage({ + config, // [!code focus] + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + message: 'hello world', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { useVerifyMessage } from 'wagmi' +import { config } from './config' + +function App() { + const result = useVerifyMessage({ + scopeKey: 'foo' // [!code focus] + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + message: 'hello world', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseVerifyMessageReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`verifyMessage`](/core/api/actions/verifyMessage) diff --git a/wagmi-project/site/react/api/hooks/useVerifyTypedData.md b/wagmi-project/site/react/api/hooks/useVerifyTypedData.md new file mode 100644 index 0000000000..4d9f8bc24e --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useVerifyTypedData.md @@ -0,0 +1,724 @@ +--- +title: useVerifyTypedData +description: Hook for verify that a typed data was signed by the provided address. +--- + + + +# useVerifyTypedData + +Hook for verify that a typed data was signed by the provided address. It supports verifying typed data that were signed by either a Smart Contract Account or Externally Owned Account. + +## Import + +```ts +import { useVerifyTypedData } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { domain, types } from './data' +import { useVerifyTypedData } from 'wagmi' + +function App() { + const result = useVerifyTypedData({ + domain, + types, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const + +// The named list of all type definitions +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseVerifyTypedDataParameters } from 'wagmi' +``` + +### address + +`Address | undefined` + +The Ethereum address that signed the original typed data. + +::: code-group +```tsx [index.tsx] +import { domain, types } from './data' +import { useVerifyTypedData } from 'wagmi' + +function App() { + const result = useVerifyTypedData({ + domain, + types, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', // [!code focus] + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const + +// The named list of all type definitions +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### domain + +`TypedDataDomain | undefined` + +The typed data domain. + +::: code-group +```tsx [index.tsx] +import { types } from './data' +import { useVerifyTypedData } from 'wagmi' + +function App() { + const result = useVerifyTypedData({ + domain: { // [!code focus:6] + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', + }, + types, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +```ts [data.ts] +// The named list of all type definitions +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### types + +The type definitions for the typed data. + +::: code-group +```tsx [index.tsx] +import { domain } from './data' +import { useVerifyTypedData } from 'wagmi' + +function App() { + const result = useVerifyTypedData({ + domain, + types: { // [!code focus:11] + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + }, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### primaryType + +`string | undefined` + +The primary `type` to extract from types and use in `value`. + +::: code-group +```tsx [index.tsx] +import { domain } from './data' +import { useVerifyTypedData } from 'wagmi' + +function App() { + const result = useVerifyTypedData({ + domain, + types: { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ // [!code focus:5] + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + }, + primaryType: 'Mail', // [!code focus] + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### message + +Type inferred from `types` & `primaryType`. + +The message to be verified. + +::: code-group +```tsx [index.tsx] +import { domain, types } from './data' +import { useVerifyTypedData } from 'wagmi' + +function App() { + const result = useVerifyTypedData({ + domain, + types, + message: { // [!code focus:11] + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const + +// The named list of all type definitions +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### signature + +`Hex | ByteArray | undefined` + +The signature that was generated by signing the typed data with the address's signer. + +::: code-group +```tsx [index.tsx] +import { domain, types } from './data' +import { useVerifyTypedData } from 'wagmi' + +function App() { + const result = useVerifyTypedData({ + domain, + types, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', // [!code focus] + }) +} +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const + +// The named list of all type definitions +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +Only used when verifying a typed data that was signed by a Smart Contract Account. The ID of chain to check if the contract was already deployed. + +::: code-group +```tsx [index.tsx] +import { domain, types } from './data' +import { useVerifyTypedData } from 'wagmi' +import { mainnet } from 'wagmi/chains' + +function App() { + const result = useVerifyTypedData({ + chainId: mainnet.id, // [!code focus] + domain, + types, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const + +// The named list of all type definitions +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockNumber + +`bigint | undefined` + +Only used when verifying a typed data that was signed by a Smart Contract Account. The block number to check if the contract was already deployed. + +::: code-group +```tsx [index.tsx] +import { domain, types } from './data' +import { useVerifyTypedData } from 'wagmi' + +function App() { + const result = useVerifyTypedData({ + blockNumber: 12345678n, // [!code focus] + domain, + types, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const + +// The named list of all type definitions +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Only used when verifying a typed data that was signed by a Smart Contract Account. The block tag to check if the contract was already deployed. + +::: code-group +```tsx [index.tsx] +import { domain, types } from './data' +import { useVerifyTypedData } from 'wagmi' + +function App() { + const result = useVerifyTypedData({ + blockTag: 'latest', // [!code focus] + domain, + types, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const + +// The named list of all type definitions +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { domain, types } from './data' +import { useVerifyTypedData } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useVerifyTypedData({ + config, // [!code focus] + domain, + types, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const + +// The named list of all type definitions +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { domain, types } from './data' +import { useVerifyTypedData } from 'wagmi' + +function App() { + const result = useVerifyTypedData({ + scopeKey: 'foo' // [!code focus] + domain, + types, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, + primaryType: 'Mail', + address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', + signature: '0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c', + }) +} +``` +```ts [data.ts] +// All properties on a domain are optional +export const domain = { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', +} as const + +// The named list of all type definitions +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseVerifyTypedDataReturnType } from 'wagmi' +``` + + + +## Type Inference + +With [`types`](#types) setup correctly, TypeScript will infer the correct types for [`domain`](#domain), [`message`](#message), and [`primaryType`](#primarytype). See the Wagmi [TypeScript docs](/react/typescript) for more information. + + + +## Action + +- [`verifyTypedData`](/core/api/actions/verifyTypedData) diff --git a/wagmi-project/site/react/api/hooks/useWaitForCallsStatus.md b/wagmi-project/site/react/api/hooks/useWaitForCallsStatus.md new file mode 100644 index 0000000000..39e520de52 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useWaitForCallsStatus.md @@ -0,0 +1,181 @@ +--- +title: useWaitForCallsStatus +description: Waits for a call bundle to be confirmed & included on a block. +--- + + + +# useWaitForCallsStatus + +Waits for a call bundle to be confirmed & included on a block before returning the status & receipts. + + + +## Import + +```ts +import { useWaitForCallsStatus } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useWaitForCallsStatus } from 'wagmi' + +function App() { + const result = useWaitForCallsStatus({ + id: '0x...', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseWaitForCallsStatusParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useWaitForCallsStatus } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useWaitForCallsStatus({ + config, // [!code focus] + id: '0x...', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +Connector to get call statuses with. + +::: code-group +```tsx [index.tsx] +import { useWaitForCallsStatus, useConnections } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const connections = useConnections() + const result = useWaitForCallsStatus({ + connector: connections[0]?.connector, // [!code focus] + id: '0x...', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### id + +`string` + +Identifier of the call batch. + +::: code-group +```ts [index.ts] +import { useWaitForCallsStatus } from '@wagmi/core' +import { config } from './config' + +const status = await useWaitForCallsStatus({ + id: '0x1234567890abcdef', // [!code focus] +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### pollingInterval + +`number | undefined` + +Polling interval in milliseconds. + +::: code-group +```ts [index.ts] +import { useWaitForCallsStatus } from '@wagmi/core' +import { config } from './config' + +const status = await useWaitForCallsStatus({ + id: '0x1234567890abcdef', + pollingInterval: 1_000, // [!code focus] +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```tsx [index.tsx] +import { useWaitForCallsStatus } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useWaitForCallsStatus({ + id: '0x...', + scopeKey: 'foo', // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### timeout + +`number | undefined` + +Timeout in milliseconds. + +::: code-group +```ts [index.ts] +import { useWaitForCallsStatus } from '@wagmi/core' +import { config } from './config' + +const status = await useWaitForCallsStatus({ + id: '0x1234567890abcdef', + timeout: 10_000, // [!code focus] +}) +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseWaitForCallsStatusReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`waitForCallsStatus`](https://viem.sh/experimental/eip5792/waitForCallsStatus) \ No newline at end of file diff --git a/wagmi-project/site/react/api/hooks/useWaitForTransactionReceipt.md b/wagmi-project/site/react/api/hooks/useWaitForTransactionReceipt.md new file mode 100644 index 0000000000..78dbe7bc54 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useWaitForTransactionReceipt.md @@ -0,0 +1,168 @@ +--- +title: useWaitForTransactionReceipt +description: Hook that waits for the transaction to be included on a block, and then returns the transaction receipt. If the transaction reverts, then the action will throw an error. Replacement detection (e.g. sped up transactions) is also supported. +--- + + + +# useWaitForTransactionReceipt + +Hook that waits for the transaction to be included on a block, and then returns the transaction receipt. If the transaction reverts, then the action will throw an error. Replacement detection (e.g. sped up transactions) is also supported. + +## Import + +```ts +import { useWaitForTransactionReceipt } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useWaitForTransactionReceipt } from 'wagmi' + +function App() { + const result = useWaitForTransactionReceipt({ + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseWaitForTransactionReceiptParameters } from 'wagmi' +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +```ts [index.ts] +import { useWaitForTransactionReceipt } from 'wagmi' +import { mainnet } from 'wagmi/chains' + +function App() { + const result = useWaitForTransactionReceipt({ + chainId: mainnet.id, // [!code focus] + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', + }) +} +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useWaitForTransactionReceipt } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useWaitForTransactionReceipt({ + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### confirmations + +`number | undefined` + +The number of confirmations (blocks that have passed) to wait before resolving. + +```ts [index.ts] +import { useWaitForTransactionReceipt } from 'wagmi' + +function App() { + const result = useWaitForTransactionReceipt({ + confirmations: 2, // [!code focus] + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', + }) +} +``` + +### onReplaced + +` +(({ reason: 'replaced' | 'repriced' | 'cancelled'; replacedTransaction: Transaction; transaction: Transaction; transactionReceipt: TransactionReceipt }) => void) | undefined +` + +Optional callback to emit if the transaction has been replaced. + +```ts [index.ts] +import { useWaitForTransactionReceipt } from 'wagmi' + +function App() { + const result = useWaitForTransactionReceipt({ + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', + onReplaced: replacement => console.log(replacement), // [!code focus] + }) +} +``` + +### pollingInterval + +`number | undefined` + +- Polling frequency (in milliseconds). +- Defaults to the [Config's `pollingInterval` config](/react/api/createConfig#pollinginterval). + +```ts [index.ts] +import { useWaitForTransactionReceipt } from 'wagmi' + +function App() { + const result = useWaitForTransactionReceipt({ + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', + pollingInterval: 1_000, // [!code focus] + }) +} +``` + +### hash + +`` `0x${string}` | undefined `` + +The transaction hash to wait for. [`enabled`](#enabled) set to `false` if `hash` is `undefined`. + +```ts [index.ts] +import { useWaitForTransactionReceipt } from 'wagmi' + +function App() { + const result = useWaitForTransactionReceipt({ + hash: '0x4ca7ee652d57678f26e887c149ab0735f41de37bcad58c9f6d3ed5824f15b74d', // [!code focus] + }) +} +``` + + + +## Return Type + +```ts +import { type UseWaitForTransactionReceiptReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`waitForTransactionReceipt`](/core/api/actions/waitForTransactionReceipt) diff --git a/wagmi-project/site/react/api/hooks/useWalletClient.md b/wagmi-project/site/react/api/hooks/useWalletClient.md new file mode 100644 index 0000000000..e6ee792c25 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useWalletClient.md @@ -0,0 +1,132 @@ +--- +title: useWalletClient +description: Hook for getting a Viem `WalletClient` object for the current or provided connector. +--- + + + +# useWalletClient + +Hook for getting a Viem [`WalletClient`](https://viem.sh/docs/clients/wallet.html) object for the current or provided connector. + +## Import + +```ts +import { useWalletClient } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useWalletClient } from 'wagmi' + +function App() { + const result = useWalletClient() +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +::: warning +If you want to optimize bundle size, you should use [`useConnectorClient`](/react/api/hooks/useConnectorClient) along with Viem's [tree-shakable actions](https://viem.sh/docs/clients/custom.html#tree-shaking) instead. Since Wallet Client has all wallet actions attached directly to it. +::: + +## Parameters + +```ts +import { type UseWalletClientParameters } from 'wagmi' +``` + +### account + +`Address | Account | undefined` + +Account to use with client. Throws if account is not found on [`connector`](#connector). + +```ts +import { useWalletClient } from 'wagmi' + +function App() { + const result = useWalletClient({ + account: '0xd2135CfB216b74109775236E36d4b433F1DF507B', // [!code focus] + }) +} +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use with client. + +```ts +import { useWalletClient } from 'wagmi' + +function App() { + const result = useWalletClient({ + chainId: mainnet.id, // [!code focus] + }) +} +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useWalletClient } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useWalletClient({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +- Connector to get client for. +- Defaults to current connector. + +```ts +import { useConnections, useWalletClient } from 'wagmi' + +function App() { + const connections = useConnections(config) + const result = useWalletClient({ + connector: connections[0]?.connector, // [!code focus] + }) +} +``` + + + +## Return Type + +```ts +import { type UseWalletClientReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`getWalletClient`](/core/api/actions/getWalletClient) diff --git a/wagmi-project/site/react/api/hooks/useWatchAsset.md b/wagmi-project/site/react/api/hooks/useWatchAsset.md new file mode 100644 index 0000000000..03f756d569 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useWatchAsset.md @@ -0,0 +1,94 @@ +--- +title: useWatchAsset +description: Hook for requesting user tracks the token in their wallet. Returns a boolean indicating if the token was successfully added. +--- + + + +# useWatchAsset + +Hook for requesting user tracks the token in their wallet. Returns a boolean indicating if the token was successfully added. + +## Import + +```ts +import { useWatchAsset } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useWatchAsset } from 'wagmi' + +function App() { + const { watchAsset } = useWatchAsset() + + return ( + + ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseWatchAssetParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useWatchAsset } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useWatchAsset({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseWatchAssetReturnType } from 'wagmi' +``` + + + + + +## Action + +- [`watchAsset`](/core/api/actions/watchAsset) diff --git a/wagmi-project/site/react/api/hooks/useWatchBlockNumber.md b/wagmi-project/site/react/api/hooks/useWatchBlockNumber.md new file mode 100644 index 0000000000..925dddfc1a --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useWatchBlockNumber.md @@ -0,0 +1,276 @@ +--- +title: useWatchBlockNumber +description: Hook that watches for block number changes. +--- + +# useWatchBlockNumber + +Hook that watches for block number changes. + +## Import + +```ts +import { useWatchBlockNumber } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useWatchBlockNumber } from 'wagmi' + +function App() { + useWatchBlockNumber({ + onBlockNumber(blockNumber) { + console.log('Block number changed!', blockNumber) + }, + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseWatchBlockNumberParameters } from 'wagmi' +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to watch blocks at. + +::: code-group +```ts [index.ts] +import { useWatchBlockNumber } from 'wagmi' + +function App() { + useWatchBlockNumber({ + chainId: 1, // [!code focus] + onBlockNumber(blockNumber) { + console.log('New block number', blockNumber) + }, + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```ts [index.ts] +import { useWatchBlockNumber } from 'wagmi' +import { config } from './config' + +function App() { + useWatchBlockNumber({ + config, // [!code focus] + onBlockNumber(blockNumber) { + console.log('New block number', blockNumber) + }, + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### emitMissed + +`boolean` + +Whether or not to emit missed blocks to the callback. Defaults to `false`. + +Missed blocks may occur in instances where internet connection is lost, or the block time is lesser than the polling interval of the client. + +::: code-group +```ts [index.ts] +import { useWatchBlockNumber } from 'wagmi' + +function App() { + useWatchBlockNumber({ + emitMissed: true, // [!code focus] + onBlockNumber(blockNumber) { + console.log('New block number', blockNumber) + }, + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### emitOnBegin + +`boolean` + +Whether or not to emit the block to the callback when the subscription opens. Defaults to `false`. + +::: code-group +```ts [index.ts] +import { useWatchBlockNumber } from 'wagmi' + +function App() { + useWatchBlockNumber({ + emitOnBegin: true, // [!code focus] + onBlockNumber(blockNumber) { + console.log('New block number', blockNumber) + }, + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### enabled + +`boolean` + +Whether or not to watch for blocks. Defaults to `true`. + +::: code-group +```ts [index.ts] +import { useWatchBlockNumber } from 'wagmi' + +function App() { + useWatchBlockNumber({ + enabled: false, // [!code focus] + onBlockNumber(blockNumber) { + console.log('New block number', blockNumber) + }, + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### onBlockNumber + +`(block: Block, prevblock: Block | undefined) => void` + +Callback for when block changes. + +::: code-group +```ts [index.ts] +import { useWatchBlockNumber } from 'wagmi' + +function App() { + useWatchBlockNumber({ + onBlockNumber(blockNumber) { // [!code focus] + console.log('New block number', blockNumber) // [!code focus] + }, // [!code focus] + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### onError + +`((error: Error) => void) | undefined` + +Error thrown from getting the block. + +::: code-group +```ts [index.ts] +import { useWatchBlockNumber } from 'wagmi' + +function App() { + useWatchBlockNumber({ + onBlockNumber(blockNumber) { + console.log('New block number', blockNumber) + }, + onError(error) { // [!code focus] + console.error('Block error', error) // [!code focus] + }, // [!code focus] + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### poll + +`boolean | undefined` + +- Whether or not to use a polling mechanism to check for new blocks instead of a WebSocket subscription. +- Defaults to `false` for WebSocket Clients, and `true` for non-WebSocket Clients. + +::: code-group +```ts [index.ts] +import { useWatchBlockNumber } from 'wagmi' + +function App() { + useWatchBlockNumber({ + onBlockNumber(blockNumber) { + console.log('New block number', blockNumber) + } + poll: true, // [!code focus] + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### pollingInterval + +`number | undefined` + +- Polling frequency (in milliseconds). +- Defaults to the [Config's `pollingInterval` config](/core/api/createConfig#pollinginterval). + +::: code-group +```ts [index.ts] +import { useWatchBlockNumber } from 'wagmi' + +function App() { + useWatchBlockNumber({ + onBlockNumber(blockNumber) { + console.log('New block number', blockNumber) + } + pollingInterval: 1_000, // [!code focus] + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### syncConnectedChain + +`boolean | undefined` + +- Set up subscriber for connected chain changes. +- Defaults to [`Config['syncConnectedChain']`](/core/api/createConfig#syncconnectedchain). + +::: code-group +```ts [index.ts] +import { useWatchBlockNumber } from 'wagmi' + +function App() { + useWatchBlockNumber({ + onBlockNumber(blockNumber) { + console.log('New block number', blockNumber) + } + syncConnectedChain: false, // [!code focus] + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type UseWatchBlockNumberReturnType } from 'wagmi' +``` + +Function for cleaning up watcher. + +## Action + +- [`watchBlockNumber`](/core/api/actions/watchBlockNumber) diff --git a/wagmi-project/site/react/api/hooks/useWatchBlocks.md b/wagmi-project/site/react/api/hooks/useWatchBlocks.md new file mode 100644 index 0000000000..ec2b17326c --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useWatchBlocks.md @@ -0,0 +1,318 @@ +--- +title: useWatchBlocks +description: Hook that watches for block changes. +--- + +# useWatchBlocks + +Hook that watches for block changes. + +## Import + +```ts +import { useWatchBlocks } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useWatchBlocks } from 'wagmi' + +function App() { + useWatchBlocks({ + onBlock(block) { + console.log('New block', block.number) + }, + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseWatchBlocksParameters } from 'wagmi' +``` + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to watch blocks at. + +::: code-group +```ts [index.ts] +import { useWatchBlocks } from 'wagmi' + +function App() { + useWatchBlocks({ + blockTag: 'latest', // [!code focus] + onBlock(block) { + console.log('New block', block.number) + }, + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to watch blocks at. + +::: code-group +```ts [index.ts] +import { useWatchBlocks } from 'wagmi' + +function App() { + useWatchBlocks({ + chainId: 1, // [!code focus] + onBlock(block) { + console.log('New block', block.number) + }, + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```ts [index.ts] +import { useWatchBlocks } from 'wagmi' +import { config } from './config' + +function App() { + useWatchBlocks({ + config, // [!code focus] + onBlock(block) { + console.log('New block', block.number) + }, + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### emitMissed + +`boolean` + +Whether or not to emit missed blocks to the callback. Defaults to `false`. + +Missed blocks may occur in instances where internet connection is lost, or the block time is lesser than the polling interval of the client. + +::: code-group +```ts [index.ts] +import { useWatchBlocks } from 'wagmi' + +function App() { + useWatchBlocks({ + emitMissed: true, // [!code focus] + onBlock(block) { + console.log('New block', block.number) + }, + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### emitOnBegin + +`boolean` + +Whether or not to emit the block to the callback when the subscription opens. Defaults to `false`. + +::: code-group +```ts [index.ts] +import { useWatchBlocks } from 'wagmi' + +function App() { + useWatchBlocks({ + emitOnBegin: true, // [!code focus] + onBlock(block) { + console.log('New block', block.number) + }, + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### enabled + +`boolean` + +Whether or not to watch for blocks. Defaults to `true`. + +::: code-group +```ts [index.ts] +import { useWatchBlocks } from 'wagmi' + +function App() { + useWatchBlocks({ + enabled: false, // [!code focus] + onBlock(block) { + console.log('New block', block.number) + }, + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### includeTransactions + +`boolean` + +Whether or not to unwrap transactions as objects (instead of hashes) in blocks. Defaults to `false`. + +::: code-group +```ts [index.ts] +import { useWatchBlocks } from 'wagmi' + +function App() { + useWatchBlocks({ + includeTransactions: true, // [!code focus] + onBlock(block) { + console.log('New block', block.number) + }, + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### onBlock + +`(block: Block, prevblock: Block | undefined) => void` + +Callback for when block changes. + +::: code-group +```ts [index.ts] +import { useWatchBlocks } from 'wagmi' + +function App() { + useWatchBlocks({ + onBlock(block) { // [!code focus] + console.log('New block', block.number) // [!code focus] + }, // [!code focus] + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### onError + +`((error: Error) => void) | undefined` + +Error thrown from getting the block. + +::: code-group +```ts [index.ts] +import { useWatchBlocks } from 'wagmi' + +function App() { + useWatchBlocks({ + onBlock(block) { + console.log('New block', block.number) + }, + onError(error) { // [!code focus] + console.error('Block error', error) // [!code focus] + }, // [!code focus] + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### poll + +`boolean | undefined` + +- Whether or not to use a polling mechanism to check for new blocks instead of a WebSocket subscription. +- Defaults to `false` for WebSocket Clients, and `true` for non-WebSocket Clients. + +::: code-group +```ts [index.ts] +import { useWatchBlocks } from 'wagmi' + +function App() { + useWatchBlocks({ + onBlock(block) { + console.log('New block', block.number) + } + poll: true, // [!code focus] + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### pollingInterval + +`number | undefined` + +- Polling frequency (in milliseconds). +- Defaults to the [Config's `pollingInterval` config](/core/api/createConfig#pollinginterval). + +::: code-group +```ts [index.ts] +import { useWatchBlocks } from 'wagmi' + +function App() { + useWatchBlocks({ + onBlock(block) { + console.log('New block', block.number) + } + pollingInterval: 1_000, // [!code focus] + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +### syncConnectedChain + +`boolean | undefined` + +- Set up subscriber for connected chain changes. +- Defaults to [`Config['syncConnectedChain']`](/core/api/createConfig#syncconnectedchain). + +::: code-group +```ts [index.ts] +import { useWatchBlocks } from 'wagmi' + +function App() { + useWatchBlocks({ + onBlock(block) { + console.log('New block', block.number) + } + syncConnectedChain: false, // [!code focus] + }) +} +``` +<<< @/snippets/core/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type UseWatchBlocksReturnType } from 'wagmi' +``` + +## Action + +- [`watchBlocks`](/core/api/actions/watchBlocks) diff --git a/wagmi-project/site/react/api/hooks/useWatchContractEvent.md b/wagmi-project/site/react/api/hooks/useWatchContractEvent.md new file mode 100644 index 0000000000..1bdcfb2622 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useWatchContractEvent.md @@ -0,0 +1,413 @@ +--- +title: useWatchContractEvent +description: Hook that watches and returns emitted contract event logs. +--- + +# useWatchContractEvent + +Hook that watches and returns emitted contract event logs. + +## Import + +```ts +import { useWatchContractEvent } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useWatchContractEvent } from 'wagmi' +import { abi } from './abi' + +function App() { + useWatchContractEvent({ + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + abi, + eventName: 'Transfer', + onLogs(logs) { + console.log('New logs!', logs) + }, + }) +} +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseWatchContractEventParameters } from 'wagmi' +``` + +### abi + +`Abi` + +The contract's ABI. Check out the [TypeScript docs](/react/typescript#const-assert-abis-typed-data) for how to set up ABIs for maximum type inference and safety. + +::: code-group +```tsx [index.tsx] +import { useWatchContractEvent } from 'wagmi' +import { abi } from './abi' + +function App() { + useWatchContractEvent({ + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + abi, // [!code focus] + eventName: 'Transfer', + onLogs(logs) { + console.log('New logs!', logs) + }, + }) +} +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### address + +`Address | undefined` + +The contract's address. + +::: code-group +```tsx [index.tsx] +import { useWatchContractEvent } from 'wagmi' +import { abi } from './abi' + +function App() { + useWatchContractEvent({ + address: '0x6b175474e89094c44da98b954eedeac495271d0f', // [!code focus] + abi, + eventName: 'Transfer', + onLogs(logs) { + console.log('New logs!', logs) + }, + }) +} +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### args + +`object | readonly unknown[] | undefined` + +- Arguments to pass when calling the contract. +- Inferred from [`abi`](#abi) and [`eventName`](#eventname). + +::: code-group +```tsx [index.tsx] +import { useWatchContractEvent } from 'wagmi' +import { abi } from './abi' + +function App() { + useWatchContractEvent({ + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + abi, + args: { // [!code focus] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B' // [!code focus] + } // [!code focus] + eventName: 'Transfer', + onLogs(logs) { + console.log('New logs!', logs) + }, + }) +} +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### batch + +`boolean | undefined` + +- Whether or not the events should be batched on each invocation. +- Defaults to `true`. + +::: code-group +```tsx [index.tsx] +import { useWatchContractEvent } from 'wagmi' +import { abi } from './abi' + +function App() { + useWatchContractEvent({ + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + abi, + batch: false, // [!code focus] + eventName: 'Transfer', + onLogs(logs) { + console.log('New logs!', logs) + }, + }) +} +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useWatchContractEvent } from 'wagmi' +import { abi } from './abi' + +function App() { + useWatchContractEvent({ + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + abi, + chainId: 1, // [!code focus] + eventName: 'Transfer', + onLogs(logs) { + console.log('New logs!', logs) + }, + }) +} +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useWatchContractEvent } from 'wagmi' +import { abi } from './abi' +import { config } from './config' + +function App() { + useWatchContractEvent({ + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + abi, + config, // [!code focus] + eventName: 'Transfer', + onLogs(logs) { + console.log('New logs!', logs) + }, + }) +} +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### eventName + +`string` + +- Event to listen for the contract. +- Inferred from [`abi`](#abi). + +::: code-group +```tsx [index.tsx] +import { useWatchContractEvent } from 'wagmi' +import { abi } from './abi' +import { config } from './config' + +function App() { + useWatchContractEvent({ + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + abi, + eventName: 'Transfer', // [!code focus] + onLogs(logs) { + console.log('New logs!', logs) + }, + }) +} +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### onError + +`((error: Error) => void) | undefined` + +Error thrown from getting the block number. + +::: code-group +```tsx [index.tsx] +import { useWatchContractEvent } from 'wagmi' +import { abi } from './abi' + +function App() { + useWatchContractEvent({ + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + abi, + eventName: 'Transfer', + onLogs(logs) { + console.log('New logs!', logs) + }, + onError(error) { // [!code focus] + console.log('Error', error) // [!code focus] + } // [!code focus] + }) +} +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### onLogs + +`(logs: Log[], prevLogs: Log[] | undefined) => void` + +Callback for when logs changes. + +::: code-group +```tsx [index.tsx] +import { useWatchContractEvent } from 'wagmi' +import { abi } from './abi' + +function App() { + useWatchContractEvent({ + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + abi, + eventName: 'Transfer', + onLogs(logs) { // [!code focus] + console.log('New logs!', logs) // [!code focus] + } // [!code focus] + }) +} +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### poll + +`boolean | undefined` + +- Whether or not to use a polling mechanism to check for new blocks instead of a WebSocket subscription. +- Defaults to `false` for WebSocket Clients, and `true` for non-WebSocket Clients. + +::: code-group +```tsx [index.tsx] +import { useWatchContractEvent } from 'wagmi' +import { abi } from './abi' + +function App() { + useWatchContractEvent({ + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + abi, + eventName: 'Transfer', + onLogs(logs) { + console.log('New logs!', logs) + }, + poll: true // [!code focus] + }) +} +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### pollingInterval + +`number | undefined` + +- Polling frequency (in milliseconds). +- Defaults to the [Config's `pollingInterval` config](/core/api/createConfig#pollinginterval). + +::: code-group +```tsx [index.tsx] +import { useWatchContractEvent } from 'wagmi' +import { abi } from './abi' + +function App() { + useWatchContractEvent({ + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + abi, + eventName: 'Transfer', + onLogs(logs) { + console.log('New logs!', logs) + }, + pollingInterval: 1_000 // [!code focus] + }) +} +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### strict + +`boolean | undefined` + +- Defaults to `false`. + +::: code-group +```tsx [index.tsx] +import { useWatchContractEvent } from 'wagmi' +import { abi } from './abi' + +function App() { + useWatchContractEvent({ + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + abi, + eventName: 'Transfer', + onLogs(logs) { + console.log('New logs!', logs) + }, + strict: true // [!code focus] + }) +} +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +### syncConnectedChain + +`boolean | undefined` + +- Set up subscriber for connected chain changes. +- Defaults to [`Config['syncConnectedChain']`](/core/api/createConfig#syncconnectedchain). + +::: code-group +```tsx [index.tsx] +import { useWatchContractEvent } from 'wagmi' +import { abi } from './abi' + +function App() { + useWatchContractEvent({ + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + abi, + eventName: 'Transfer', + onLogs(logs) { + console.log('New logs!', logs) + }, + syncConnectedChain: true // [!code focus] + }) +} +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type UseWatchContractEventReturnType } from 'wagmi' +``` + +Hook returns `void` + +## Action + +- [`watchContractEvent`](/core/api/actions/watchContractEvent) diff --git a/wagmi-project/site/react/api/hooks/useWatchPendingTransactions.md b/wagmi-project/site/react/api/hooks/useWatchPendingTransactions.md new file mode 100644 index 0000000000..0bfbb8136d --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useWatchPendingTransactions.md @@ -0,0 +1,229 @@ +--- +title: useWatchPendingTransactions +description: Hook that watches and returns pending transaction hashes. +--- + +# useWatchPendingTransactions + +Hook that watches and returns pending transaction hashes. + +## Import + +```ts +import { useWatchPendingTransactions } from 'wagmi' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useWatchPendingTransactions } from 'wagmi' + +function App() { + useWatchPendingTransactions({ + onTransactions(transactions) { + console.log('New transactions!', transactions) + }, + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseWatchPendingTransactionsParameters } from 'wagmi' +``` + +### batch + +`boolean | undefined` + +- Whether or not the transactions should be batched on each invocation. +- Defaults to `true`. + +::: code-group +```tsx [index.tsx] +import { useWatchPendingTransactions } from 'wagmi' + +function App() { + useWatchPendingTransactions({ + batch: true // [!code focus] + onTransactions(transactions) { + console.log('New transactions!', transactions) + }, + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```tsx [index.tsx] +import { useWatchPendingTransactions } from 'wagmi' + +function App() { + useWatchPendingTransactions({ + chainId: 1 // [!code focus] + onTransactions(transactions) { + console.log('New transactions!', transactions) + }, + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useWatchPendingTransactions } from 'wagmi' +import { config } from './config' + +function App() { + useWatchPendingTransactions({ + config // [!code focus] + onTransactions(transactions) { + console.log('New transactions!', transactions) + }, + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### onError + +`((error: Error) => void) | undefined` + +Error thrown from watching pending transactions. + +::: code-group +```tsx [index.tsx] +import { useWatchPendingTransactions } from 'wagmi' + +function App() { + useWatchPendingTransactions({ + onError(error) { // [!code focus] + console.log('Error', error) // [!code focus] + }, // [!code focus] + onTransactions(transactions) { + console.log('New transactions!', transactions) + }, + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### onTransactions + +`(transactions: Hash[], prevTransactions: Hash[] | undefined) => void` + +Callback when new incoming pending transactions are detected. + +::: code-group +```tsx [index.tsx] +import { useWatchPendingTransactions } from 'wagmi' + +function App() { + useWatchPendingTransactions({ + onTransactions(transactions) { // [!code focus] + console.log('New transactions!', transactions) // [!code focus] + }, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### poll + +`boolean | undefined` + +- Whether or not to use a polling mechanism to check for new pending transactions instead of a WebSocket subscription. +- Defaults to `false` for WebSocket Clients, and `true` for non-WebSocket Clients. + +::: code-group +```tsx [index.tsx] +import { useWatchPendingTransactions } from 'wagmi' + +function App() { + useWatchPendingTransactions({ + onTransactions(transactions) { + console.log('New transactions!', transactions) + }, + poll: true, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### pollingInterval + +`number | undefined` + +- Polling frequency (in milliseconds). +- Defaults to the [Config's `pollingInterval` config](/core/api/createConfig#pollinginterval). + +::: code-group +```tsx [index.tsx] +import { useWatchPendingTransactions } from 'wagmi' + +function App() { + useWatchPendingTransactions({ + onTransactions(transactions) { + console.log('New transactions!', transactions) + }, + pollingInterval: 1_000, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### syncConnectedChain + +`boolean | undefined` + +- Set up subscriber for connected chain changes. +- Defaults to [`Config['syncConnectedChain']`](/core/api/createConfig#syncconnectedchain). + +::: code-group +```tsx [index.tsx] +import { useWatchPendingTransactions } from 'wagmi' + +function App() { + useWatchPendingTransactions({ + onTransactions(transactions) { + console.log('New transactions!', transactions) + }, + syncConnectedChain: false, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type UseWatchPendingTransactionsReturnType } from 'wagmi' +``` + +## Action + +- [`watchPendingTransactions`](/core/api/actions/watchPendingTransactions) diff --git a/wagmi-project/site/react/api/hooks/useWriteContract.md b/wagmi-project/site/react/api/hooks/useWriteContract.md new file mode 100644 index 0000000000..bc575ce88b --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useWriteContract.md @@ -0,0 +1,116 @@ +--- +title: useWriteContract +description: Action for executing a write function on a contract. +--- + + + +# useWriteContract + +Action for executing a write function on a contract. + +A "write" function on a Solidity contract modifies the state of the blockchain. These types of functions require gas to be executed, hence a transaction is broadcasted in order to change the state. + +## Import + +```ts +import { useWriteContract } from 'wagmi' +``` + +## Usage + +::: code-group + +```tsx [index.tsx] +import { useWriteContract } from 'wagmi' +import { abi } from './abi' + +function App() { + const { writeContract } = useWriteContract() + + return ( + + ) +} +``` + +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/react/config.ts[config.ts] +::: + + + + + +## Parameters + +```ts +import { type UseWriteContractParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group + +```tsx [index.tsx] +import { useWriteContract } from 'wagmi' +import { config } from './config' // [!code focus] + +function App() { + const result = useWriteContract({ + config, // [!code focus] + }) +} +``` + +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseWriteContractReturnType } from 'wagmi' +``` + +The return type's [`data`](#data) property is inferrable via the combination of [`abi`](#abi), [`functionName`](#functionname), and [`args`](#args). Check out the [TypeScript docs](/react/typescript#const-assert-abis-typed-data) for more info. + + + +## Type Inference + +With [`abi`](/core/api/actions/writeContract#abi) setup correctly, TypeScript will infer the correct types for [`functionName`](/core/api/actions/writeContract#functionname), [`args`](/core/api/actions/writeContract#args), and the [`value`](/core/api/actions/writeContract##value). See the Wagmi [TypeScript docs](/react/typescript) for more information. + + + +## Action + +- [`writeContract`](/core/api/actions/writeContract) diff --git a/wagmi-project/site/react/api/hooks/useWriteContracts.md b/wagmi-project/site/react/api/hooks/useWriteContracts.md new file mode 100644 index 0000000000..0e8e94aa79 --- /dev/null +++ b/wagmi-project/site/react/api/hooks/useWriteContracts.md @@ -0,0 +1,119 @@ +--- +title: useWriteContracts +description: Hook that requests for the wallet to sign and broadcast a batch of calls (transactions) to the network. +--- + + + +# useWriteContracts + +Hook that requests for the wallet to sign and broadcast a batch of write contract calls (transactions) to the network. + +[Read more.](https://github.com/ethereum/EIPs/blob/815028dc634463e1716fc5ce44c019a6040f0bef/EIPS/eip-5792.md#wallet_sendcalls) + +## Import + +```ts +import { useWriteContracts } from 'wagmi/experimental' +``` + +## Usage + +::: code-group +```tsx [index.tsx] +import { useWriteContracts } from 'wagmi/experimental' +import { parseAbi } from 'viem' + +const abi = parseAbi([ + 'function approve(address, uint256) returns (bool)', + 'function transferFrom(address, address, uint256) returns (bool)', +]) + +function App() { + const { writeContracts } = useWriteContracts() + + return ( + + ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseWriteContractsParameters } from 'wagmi/experimental' +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```tsx [index.tsx] +import { useWriteContracts } from 'wagmi/experimental' +import { config } from './config' // [!code focus] + +function App() { + const result = useWriteContracts({ + config, // [!code focus] + }) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseWriteContractsReturnType } from 'wagmi/experimental' +``` + + + + + +## Action + +- [`writeContracts`](/core/api/actions/writeContracts) diff --git a/wagmi-project/site/react/api/transports.md b/wagmi-project/site/react/api/transports.md new file mode 100644 index 0000000000..5620b3c115 --- /dev/null +++ b/wagmi-project/site/react/api/transports.md @@ -0,0 +1,28 @@ + + +# Transports + +[`createConfig`](/react/api/createConfig) can be instantiated with a set of Transports for each chain. A Transport is the intermediary layer that is responsible for executing outgoing JSON-RPC requests to the RPC Provider (e.g. Alchemy, Infura, etc). + +## Import + +```ts +import { http } from 'wagmi' +``` + +## Built-In Transports + +Available via the `'wagmi'` entrypoint. + + diff --git a/wagmi-project/site/react/api/transports/custom.md b/wagmi-project/site/react/api/transports/custom.md new file mode 100644 index 0000000000..d2ba5de554 --- /dev/null +++ b/wagmi-project/site/react/api/transports/custom.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/react/api/transports/fallback.md b/wagmi-project/site/react/api/transports/fallback.md new file mode 100644 index 0000000000..cffcd08f05 --- /dev/null +++ b/wagmi-project/site/react/api/transports/fallback.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/react/api/transports/http.md b/wagmi-project/site/react/api/transports/http.md new file mode 100644 index 0000000000..31d80d8a8d --- /dev/null +++ b/wagmi-project/site/react/api/transports/http.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/react/api/transports/unstable_connector.md b/wagmi-project/site/react/api/transports/unstable_connector.md new file mode 100644 index 0000000000..008b9aa3d4 --- /dev/null +++ b/wagmi-project/site/react/api/transports/unstable_connector.md @@ -0,0 +1,6 @@ + + + diff --git a/wagmi-project/site/react/api/transports/webSocket.md b/wagmi-project/site/react/api/transports/webSocket.md new file mode 100644 index 0000000000..6eacdaabed --- /dev/null +++ b/wagmi-project/site/react/api/transports/webSocket.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/react/api/utilities/cookieToInitialState.md b/wagmi-project/site/react/api/utilities/cookieToInitialState.md new file mode 100644 index 0000000000..98363c60e6 --- /dev/null +++ b/wagmi-project/site/react/api/utilities/cookieToInitialState.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/react/api/utilities/deserialize.md b/wagmi-project/site/react/api/utilities/deserialize.md new file mode 100644 index 0000000000..24e9aa22c4 --- /dev/null +++ b/wagmi-project/site/react/api/utilities/deserialize.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/react/api/utilities/normalizeChainId.md b/wagmi-project/site/react/api/utilities/normalizeChainId.md new file mode 100644 index 0000000000..deceae7a4e --- /dev/null +++ b/wagmi-project/site/react/api/utilities/normalizeChainId.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/react/api/utilities/serialize.md b/wagmi-project/site/react/api/utilities/serialize.md new file mode 100644 index 0000000000..9ff2ff3225 --- /dev/null +++ b/wagmi-project/site/react/api/utilities/serialize.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/react/comparisons.md b/wagmi-project/site/react/comparisons.md new file mode 100644 index 0000000000..8c614ed552 --- /dev/null +++ b/wagmi-project/site/react/comparisons.md @@ -0,0 +1,90 @@ +# Comparison + +There are multiple options when it comes to React libraries for Ethereum that help manage wallet connections, provide utility methods/hooks, etc. + +::: tip +Comparisons strive to be as accurate and as unbiased as possible. If you use any of these libraries and feel the information could be improved, feel free to suggest changes. +::: + +## Overview + +| | [wagmi](https://github.com/wagmi-dev/wagmi) | [web3-react](https://github.com/NoahZinsmeister/web3-react) | [useDApp](https://github.com/EthWorks/useDApp) | +| -------------------- | :---------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------ | :------------------------------------------------------------------------------------------------- | +| GitHub Stars | ![wagmi star count](https://img.shields.io/github/stars/wagmi-dev/wagmi?colorB=27292E&label=) | ![web3-react star count](https://img.shields.io/github/stars/Uniswap/web3-react?colorB=27292E&label=) | ![useDApp star count](https://img.shields.io/github/stars/EthWorks/useDApp?colorB=27292E&label=) | +| Open Issues | ![wagmi issue count](https://img.shields.io/github/issues/wagmi-dev/wagmi?colorB=27292E&label=) | ![web3-react issue count](https://img.shields.io/github/issues/Uniswap/web3-react?colorB=27292E&label=) | ![useDApp issue count](https://img.shields.io/github/issues/EthWorks/useDApp?colorB=27292E&label=) | +| Downloads | ![wagmi downloads](https://img.shields.io/npm/dw/wagmi?colorB=27292E&label=) | ![web3-react downloads](https://img.shields.io/npm/dw/@web3-react/core?colorB=27292E&label=) | ![useDApp downloads](https://img.shields.io/npm/dw/@usedapp/core?colorB=27292E&label=) | +| License | ![wagmi license](https://img.shields.io/github/license/wagmi-dev/wagmi?colorB=27292E&label=) | ![web3-react license](https://img.shields.io/github/license/Uniswap/web3-react?colorB=27292E&label=) | ![useDApp license](https://img.shields.io/github/license/EthWorks/useDApp?colorB=27292E&label=) | +| Their Comparison | – | none | none | +| Supported Frameworks | React, Vanilla JS | React | React | +| Documentation | āœ… | šŸ›‘ | āœ… | +| TypeScript | āœ… | šŸ”¶ | šŸ”¶ | +| EIP-6963 Support | āœ… | šŸ”“ | šŸ”“ | +| Test Suite | āœ… | šŸ”¶ | šŸ”¶ | +| Examples | āœ… | šŸ”¶ | āœ… | + +::: details Comparison Key + +1. Documentation + - Comprehensive documentation for all library features āœ… + - No documentation šŸ”“ +2. Typescript + - Infer types from ABIs, EIP-712 Typed Data, etc. āœ… + - Can add types with explicit generics, type annotations, etc. šŸ”¶ +3. Test Suite + - Runs against forked Ethereum network(s) āœ… + - Mocking functionality (i.e. RPC calls) is šŸ”¶ +4. EIP-6963 Support + - Fully compatible with EIP-6963 āœ… + - Not compatible with EIP-6963 šŸ”“ +5. Examples + - Has multiple examples āœ… + - Has single example šŸ”¶ +::: + +## [Wagmi](https://github.com/wagmi-dev/wagmi) + +### Pros + +- 20+ hooks for working with wallets, ENS, contracts, transactions, signing, etc. +- Built-in wallet connectors for injected providers (EIP-6963 support), WalletConnect, MetaMask, Coinbase Wallet +- Caching, request deduplication, and persistence powered by TanStack Query +- Auto-refresh data on wallet, block, and network changes +- Multicall support +- Test suite running against forked Ethereum networks +- TypeScript ready (infer types from ABIs and EIP-712 Typed Data) +- Extensive documentation and examples +- Used by Coinbase, Stripe, Shopify, Uniswap, Optimism, ENS, Sushi, and [many more](https://github.com/wagmi-dev/wagmi/discussions/201) +- MIT License + +### Cons + +- Not as many built-in connectors as `web3-react` + +## [web3-react](https://github.com/Uniswap/web3-react) + +### Pros + +- Supports many different connectors (conceptually similar to Wagmi's connectors) +- Basic hooks for managing account + +### Cons + +- Need to set up connectors and method for connecting wallet on your own +- Need to install connectors separately +- Almost no tests or documentation; infrequent updates +- GPL-3.0 License + +## [useDApp](https://github.com/EthWorks/useDApp) + +### Pros + +- Auto-refresh on new blocks and wallet changes +- Multicall support +- Transaction notifications +- Chrome extension and Firefox add-on +- MIT License + +### Cons + +- Non-standard hook API + diff --git a/wagmi-project/site/react/getting-started.md b/wagmi-project/site/react/getting-started.md new file mode 100644 index 0000000000..3e4111cb49 --- /dev/null +++ b/wagmi-project/site/react/getting-started.md @@ -0,0 +1,214 @@ + + +# Getting Started + +## Overview + +Wagmi is a React Hooks library for Ethereum. You can learn more about the rationale behind the project in the [Why Wagmi](/react/why) section. + +## Automatic Installation + +For new projects, it is recommended to set up your Wagmi app using the [`create-wagmi`](/cli/create-wagmi) command line interface (CLI). This will create a new Wagmi project using TypeScript and install the required dependencies. + +::: code-group +```bash [pnpm] +pnpm create wagmi +``` + +```bash [npm] +npm create wagmi@latest +``` + +```bash [yarn] +yarn create wagmi +``` + +```bash [bun] +bun create wagmi +``` +::: + +Once the command runs, you'll see some prompts to complete. + +```ansi +Project name: wagmi-project +Select a framework: React / Vanilla +... +``` + +After the prompts, `create-wagmi` will create a directory with your project name and install the required dependencies. Check out the `README.md` for further instructions (if required). + +## Manual Installation + +To manually add Wagmi to your project, install the required packages. + +::: code-group +```bash-vue [pnpm] +pnpm add wagmi viem@{{viemVersion}} @tanstack/react-query +``` + +```bash-vue [npm] +npm install wagmi viem@{{viemVersion}} @tanstack/react-query +``` + +```bash-vue [yarn] +yarn add wagmi viem@{{viemVersion}} @tanstack/react-query +``` + +```bash-vue [bun] +bun add wagmi viem@{{viemVersion}} @tanstack/react-query +``` +::: + +- [Viem](https://viem.sh) is a TypeScript interface for Ethereum that performs blockchain operations. +- [TanStack Query](https://tanstack.com/query/v5) is an async state manager that handles requests, caching, and more. +- [TypeScript](/react/typescript) is optional, but highly recommended. Learn more about [TypeScript support](/react/typescript). + +### Create Config + +Create and export a new Wagmi config using `createConfig`. + +::: code-group +<<< @/snippets/react/config.ts[config.ts] +::: + +In this example, Wagmi is configured to use the Mainnet and Sepolia chains, and `injected` connector. Check out the [`createConfig` docs](/react/api/createConfig) for more configuration options. + + +::: details TypeScript Tip +If you are using TypeScript, you can "register" the Wagmi config or use the hook `config` property to get strong type-safety across React Context in places that wouldn't normally have type info. + +::: code-group +```ts twoslash [register config] +// @errors: 2322 +import { type Config } from 'wagmi' +import { mainnet, sepolia } from 'wagmi/chains' + +declare const config: Config +// ---cut--- +import { useBlockNumber } from 'wagmi' + +useBlockNumber({ chainId: 123 }) + +declare module 'wagmi' { + interface Register { + config: typeof config + } +} +``` + +```ts twoslash [hook config property] +// @errors: 2322 +import { type Config } from 'wagmi' +import { mainnet, sepolia } from 'wagmi/chains' + +declare const config: Config +// ---cut--- +import { useBlockNumber } from 'wagmi' + +useBlockNumber({ chainId: 123, config }) +``` + +By registering or using the hook `config` property, `useBlockNumber`'s `chainId` is strongly typed to only allow Mainnet and Sepolia IDs. Learn more by reading the [TypeScript docs](/react/typescript#config-types). +::: + +### Wrap App in Context Provider + +Wrap your app in the `WagmiProvider` React Context Provider and pass the `config` you created earlier to the `config` property. + +::: code-group +```tsx [app.tsx] +import { WagmiProvider } from 'wagmi' // [!code focus] +import { config } from './config' // [!code focus] + +function App() { + return ( + // [!code focus] + {/** ... */} // [!code focus] + // [!code focus] + ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +Check out the [`WagmiProvider` docs](/react/api/WagmiProvider) to learn more about React Context in Wagmi. + +### Setup TanStack Query + +Inside the `WagmiProvider`, wrap your app in a TanStack Query React Context Provider, e.g. `QueryClientProvider`, and pass a new `QueryClient` instance to the `client` property. + +::: code-group +```tsx [app.tsx] +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' // [!code focus] +import { WagmiProvider } from 'wagmi' +import { config } from './config' + +const queryClient = new QueryClient() // [!code focus] + +function App() { + return ( + + // [!code focus] + {/** ... */} // [!code focus] + // [!code focus] + + ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +Check out the [TanStack Query docs](https://tanstack.com/query/latest/docs/framework/react) to learn about the library, APIs, and more. + +### Use Wagmi + +Now that everything is set up, every component inside the Wagmi and TanStack Query Providers can use Wagmi React Hooks. + +::: code-group +```tsx [profile.tsx] +import { useAccount, useEnsName } from 'wagmi' + +export function Profile() { + const { address } = useAccount() + const { data, error, status } = useEnsName({ address }) + if (status === 'pending') return
Loading ENS name
+ if (status === 'error') + return
Error fetching ENS name: {error.message}
+ return
ENS name: {data}
+} +``` + +```tsx [app.tsx] +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { WagmiProvider } from 'wagmi' +import { config } from './config' +import { Profile } from './profile' + +const queryClient = new QueryClient() + +function App() { + return ( + + + + + + ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Next Steps + +For more information on what to do next, check out the following topics. + +- [**TypeScript**](/react/typescript) Learn how to get the most out of Wagmi's type-safety and inference for an enlightened developer experience. +- [**Connect Wallet**](/react/guides/connect-wallet) Learn how to enable wallets to connect to and disconnect from your apps and display information about connected accounts. +- [**React Hooks**](/react/api/hooks) Browse the collection of React Hooks and learn how to use them. +- [**Viem**](/react/guides/viem) Learn about Viem and how it works with Wagmi. diff --git a/wagmi-project/site/react/guides/chain-properties.md b/wagmi-project/site/react/guides/chain-properties.md new file mode 100644 index 0000000000..9e4667a6e3 --- /dev/null +++ b/wagmi-project/site/react/guides/chain-properties.md @@ -0,0 +1,97 @@ +# Chain Properties + +Some chains support additional properties related to blocks and transactions. This is powered by Viem's [formatters](https://viem.sh/docs/chains/formatters) and [serializers](https://viem.sh/docs/chains/serializers). For example, Celo, ZkSync, OP Stack chains all support additional properties. In order to use these properties in a type-safe way, there are a few things you should be aware of. + +
+ +::: tip +Make sure you follow the TypeScript guide's [Config Types](/react/typescript#config-types) section before moving on. The easiest way to do this is to use [Declaration Merging](/react/typescript#declaration-merging) to "register" your `config` globally with TypeScript. + +<<< @/snippets/react/config-chain-properties.ts[config.ts] +::: + +## Narrowing Parameters + +Once your Config is registered with TypeScript, you are ready to access chain-specific properties! For example, Celo's `feeCurrency` is available. + +::: code-group +```ts [index.tsx] +import { parseEther } from 'viem' +import { useSimulateContract } from 'wagmi' + +const result = useSimulateContract({ + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + feeCurrency: '0x…', // [!code focus] +}) +``` +<<< @/snippets/react/config-chain-properties.ts[config.ts] +::: + +This is great, but if you have multiple chains that support additional properties, your autocomplete could be overwhelmed with all of them. By setting the `chainId` property to a specific value (e.g. `celo.id`), you can narrow parameters to a single chain. + +::: code-group +```ts [index.tsx] +import { parseEther } from 'viem' +import { useSimulateContract } from 'wagmi' +import { celo } from 'wagmi/chains' + +const result = useSimulateContract({ + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + chainId: celo.id, // [!code focus] + feeCurrency: '0x…', // [!code focus] + // ^? (property) feeCurrency?: `0x${string}` | undefined // [!code focus] +}) +``` +<<< @/snippets/react/config-chain-properties.ts[config.ts] +::: + +## Narrowing Return Types + +Return types can also have chain-specific properties attached to them. There are a couple approaches for extracting these properties. + +### `chainId` Parameter + +Not only can you use the `chainId` parameter to [narrow parameters](#narrowing-parameters), you can also use it to narrow the return type. + +::: code-group +```ts [index.tsx] +import { useWaitForTransactionReceipt } from 'wagmi' +import { zkSync } from 'wagmi/chains' + +const { data } = useWaitForTransactionReceipt({ + chainId: zkSync.id, + hash: '0x16854fcdd0219cacf5aec5e4eb2154dac9e406578a1510a6fc48bd0b67e69ea9', +}) + +data?.logs +// ^? (property) logs: ZkSyncLog[] | undefined +``` +<<< @/snippets/react/config-chain-properties.ts[config.ts] +::: + +### `chainId` Data Property + +Wagmi internally will set a `chainId` property on return types that you can use to narrow results. The `chainId` is determined from the `chainId` parameter or global state (e.g. connector). You can use this property to help TypeScript narrow the type. + +::: code-group +```ts [index.tsx] +import { useWaitForTransactionReceipt } from 'wagmi' +import { zkSync } from 'wagmi/chains' + +const { data } = useWaitForTransactionReceipt({ + hash: '0x16854fcdd0219cacf5aec5e4eb2154dac9e406578a1510a6fc48bd0b67e69ea9', +}) + +if (data?.chainId === zkSync.id) { + data?.logs + // ^? (property) logs: ZkSyncLog[] | undefined +} +``` +<<< @/snippets/react/config-chain-properties.ts[config.ts] +::: + +## Troubleshooting + +If chain properties aren't working, make sure [TypeScript](/react/guides/faq#type-inference-doesn-t-work) is configured correctly. Not all chains have additional properties, to check which ones do, see the [Viem repo](https://github.com/wevm/viem/tree/main/src/chains) (chains that have a top-level directory under [`src/chains`](https://github.com/wevm/viem/tree/main/src/chains) support additional properties). diff --git a/wagmi-project/site/react/guides/connect-wallet.md b/wagmi-project/site/react/guides/connect-wallet.md new file mode 100644 index 0000000000..34a7e7bea3 --- /dev/null +++ b/wagmi-project/site/react/guides/connect-wallet.md @@ -0,0 +1,421 @@ +# Connect Wallet + +The ability for a user to connect their wallet is a core function for any Dapp. It allows users to perform tasks such as: writing to contracts, signing messages, or sending transactions. + +Wagmi contains everything you need to get started with building a Connect Wallet module. To get started, you can either use a [third-party library](#third-party-libraries) or [build your own](#build-your-own). + +## Third-party Libraries + +You can use a pre-built Connect Wallet module from a third-party library such as: + +- [ConnectKit](https://docs.family.co/connectkit) - [Guide](https://docs.family.co/connectkit/getting-started) +- [AppKit](https://reown.com/appkit) - [Guide](https://docs.reown.com/appkit/next/core/installation) +- [RainbowKit](https://www.rainbowkit.com/) - [Guide](https://www.rainbowkit.com/docs/installation) +- [Dynamic](https://www.dynamic.xyz/) - [Guide](https://docs.dynamic.xyz/quickstart) +- [Privy](https://privy.io) - [Guide](https://docs.privy.io/guide/react/wallets/usage/wagmi) + +The above libraries are all built on top of Wagmi, handle all the edge cases around wallet connection, and provide a seamless Connect Wallet UX that you can use in your Dapp. + +## Build Your Own + +Wagmi provides you with the Hooks to get started building your own Connect Wallet module. + +It takes less than five minutes to get up and running with Browser Wallets, WalletConnect, and Coinbase Wallet. + +### 1. Configure Wagmi + +Before we get started with building the functionality of the Connect Wallet module, we will need to set up the Wagmi configuration. + +Let's create a `config.ts` file and export a `config` object. + +::: code-group + +```tsx [config.ts] +import { http, createConfig } from 'wagmi' +import { base, mainnet, optimism } from 'wagmi/chains' +import { injected, metaMask, safe, walletConnect } from 'wagmi/connectors' + +const projectId = '' + +export const config = createConfig({ + chains: [mainnet, base], + connectors: [ + injected(), + walletConnect({ projectId }), + metaMask(), + safe(), + ], + transports: { + [mainnet.id]: http(), + [base.id]: http(), + }, +}) +``` + +::: + +In the above configuration, we want to set up connectors for Injected (browser), WalletConnect (browser + mobile), MetaMask, and Safe wallets. This configuration uses the **Mainnet** and **Base** chains, but you can use whatever you want. + +::: warning + +Make sure to replace the `projectId` with your own WalletConnect Project ID, if you wish to use WalletConnect! + +[Get your Project ID](https://cloud.reown.com/) + +::: + +### 2. Wrap App in Context Provider + +Next, we will need to wrap our React App with Context so that our application is aware of Wagmi & React Query's reactive state and in-memory caching. + +::: code-group + +```tsx [app.tsx] + // 1. Import modules +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { WagmiProvider } from 'wagmi' +import { config } from './config' + +// 2. Set up a React Query client. +const queryClient = new QueryClient() + +function App() { + // 3. Wrap app with Wagmi and React Query context. + return ( + + + {/** ... */} + + + ) +} +``` + +```tsx [config.ts] +import { http, createConfig } from 'wagmi' +import { base, mainnet, optimism } from 'wagmi/chains' +import { injected, metaMask, safe, walletConnect } from 'wagmi/connectors' + +const projectId = '' + +export const config = createConfig({ + chains: [mainnet, base], + connectors: [ + injected(), + walletConnect({ projectId }), + metaMask(), + safe(), + ], + transports: { + [mainnet.id]: http(), + [base.id]: http(), + }, +}) +``` + +::: + +### 3. Display Wallet Options + +After that, we will create a `WalletOptions` component that will display our connectors. This will allow users to select a wallet and connect. + +Below, we are rendering a list of `connectors` retrieved from `useConnect`. When the user clicks on a connector, the `connect` function will connect the users' wallet. + +::: code-group + +```tsx [wallet-options.tsx] +import * as React from 'react' +import { Connector, useConnect } from 'wagmi' + +export function WalletOptions() { + const { connectors, connect } = useConnect() + + return connectors.map((connector) => ( + + )) +} +``` + +```tsx [app.tsx] + // 1. Import modules +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { WagmiProvider } from 'wagmi' +import { config } from './config' + +// 2. Set up a React Query client. +const queryClient = new QueryClient() + +function App() { + // 3. Wrap app with Wagmi and React Query context. + return ( + + + {/* ... */} + + + ) +} +``` + +```tsx [config.ts] +import { http, createConfig } from 'wagmi' +import { base, mainnet, optimism } from 'wagmi/chains' +import { injected, metaMask, safe, walletConnect } from 'wagmi/connectors' + +const projectId = '' + +export const config = createConfig({ + chains: [mainnet, base], + connectors: [ + injected(), + walletConnect({ projectId }), + metaMask(), + safe(), + ], + transports: { + [mainnet.id]: http(), + [base.id]: http(), + }, +}) +``` + +::: + +### 4. Display Connected Account + +Lastly, if an account is connected, we want to show some basic information, like the connected address and ENS name and avatar. + +Below, we are using hooks like `useAccount`, `useEnsAvatar` and `useEnsName` to extract this information. + +We are also utilizing `useDisconnect` to show a "Disconnect" button so a user can disconnect their wallet. + +::: code-group + +```tsx [account.tsx] +import { useAccount, useDisconnect, useEnsAvatar, useEnsName } from 'wagmi' + +export function Account() { + const { address } = useAccount() + const { disconnect } = useDisconnect() + const { data: ensName } = useEnsName({ address }) + const { data: ensAvatar } = useEnsAvatar({ name: ensName! }) + + return ( +
+ {ensAvatar && ENS Avatar} + {address &&
{ensName ? `${ensName} (${address})` : address}
} + +
+ ) +} +``` + +```tsx [wallet-options.tsx] +import * as React from 'react' +import { Connector, useConnect } from 'wagmi' + +export function WalletOptions() { + const { connectors, connect } = useConnect() + + return connectors.map((connector) => ( + connect({ connector })} + /> + )) +} + +function WalletOption({ + connector, + onClick, +}: { + connector: Connector + onClick: () => void +}) { + const [ready, setReady] = React.useState(false) + + React.useEffect(() => { + ;(async () => { + const provider = await connector.getProvider() + setReady(!!provider) + })() + }, [connector]) + + return ( + + ) +} +``` + +```tsx [app.tsx] + // 1. Import modules +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { WagmiProvider } from 'wagmi' +import { config } from './config' + +// 2. Set up a React Query client. +const queryClient = new QueryClient() + +function App() { + // 3. Wrap app with Wagmi and React Query context. + return ( + + + {/* ... */} + + + ) +} +``` + +```tsx [config.ts] +import { http, createConfig } from 'wagmi' +import { base, mainnet, optimism } from 'wagmi/chains' +import { injected, metaMask, safe, walletConnect } from 'wagmi/connectors' + +const projectId = '' + +export const config = createConfig({ + chains: [mainnet, base], + connectors: [ + injected(), + walletConnect({ projectId }), + metaMask(), + safe(), + ], + transports: { + [mainnet.id]: http(), + [base.id]: http(), + }, +}) +``` + +::: + +### 5. Wire it up! + +Finally, we can wire up our Wallet Options and Account components to our application's entrypoint. + +::: code-group + +```tsx [app.tsx] +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { WagmiProvider, useAccount } from 'wagmi' +import { config } from './config' +import { Account } from './account' // [!code ++] +import { WalletOptions } from './wallet-options' // [!code ++] + +const queryClient = new QueryClient() + +function ConnectWallet() { // [!code ++] + const { isConnected } = useAccount() // [!code ++] + if (isConnected) return // [!code ++] + return // [!code ++] +} // [!code ++] + +function App() { + return ( + + + // [!code ++] + + + ) +} +``` + +```tsx [account.tsx] +import { useAccount, useDisconnect, useEnsAvatar, useEnsName } from 'wagmi' + +export function Account() { + const { address } = useAccount() + const { disconnect } = useDisconnect() + const { data: ensName } = useEnsName({ address }) + const { data: ensAvatar } = useEnsAvatar({ name: ensName! }) + + return ( +
+ {ensAvatar && ENS Avatar} + {address &&
{ensName ? `${ensName} (${address})` : address}
} + +
+ ) +} +``` + +```tsx [wallet-options.tsx] +import * as React from 'react' +import { Connector, useConnect } from 'wagmi' + +export function WalletOptions() { + const { connectors, connect } = useConnect() + + return connectors.map((connector) => ( + connect({ connector })} + /> + )) +} + +function WalletOption({ + connector, + onClick, +}: { + connector: Connector + onClick: () => void +}) { + const [ready, setReady] = React.useState(false) + + React.useEffect(() => { + ;(async () => { + const provider = await connector.getProvider() + setReady(!!provider) + })() + }, [connector]) + + return ( + + ) +} +``` + +```tsx [config.ts] +import { http, createConfig } from 'wagmi' +import { base, mainnet, optimism } from 'wagmi/chains' +import { injected, metaMask, safe, walletConnect } from 'wagmi/connectors' + +const projectId = '' + +export const config = createConfig({ + chains: [mainnet, base], + connectors: [ + injected(), + walletConnect({ projectId }), + metaMask(), + safe(), + ], + transports: { + [mainnet.id]: http(), + [base.id]: http(), + }, +}) +``` + +::: + +### Playground + +Want to see the above steps all wired up together in an end-to-end example? Check out the below StackBlitz playground. + +
+ + diff --git a/wagmi-project/site/react/guides/error-handling.md b/wagmi-project/site/react/guides/error-handling.md new file mode 100644 index 0000000000..62dae72b52 --- /dev/null +++ b/wagmi-project/site/react/guides/error-handling.md @@ -0,0 +1,42 @@ +# Error Handling + +The `error` property in Wagmi Hooks is strongly typed with it's corresponding error type. This enables you to have granular precision with handling errors in your application. + +You can discriminate the error type by using the `name` property on the error object. + +::: code-group +```tsx twoslash [index.tsx] +// @noErrors +import { useBlockNumber } from 'wagmi' + +function App() { + const { data, error } = useBlockNumber() + // ^? + + error?.name + // ^? + + + + + + + if (error?.name === 'HttpRequestError') { + const { status } = error + // ^? + + + return
A HTTP error occurred. Status: {status}
+ } + if (error?.name === 'LimitExceededRpcError') { + const { code } = error + // ^? + + + return
Rate limit exceeded. Code: {code}
+ } + // ... +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: diff --git a/wagmi-project/site/react/guides/ethers.md b/wagmi-project/site/react/guides/ethers.md new file mode 100644 index 0000000000..fe1b2ad597 --- /dev/null +++ b/wagmi-project/site/react/guides/ethers.md @@ -0,0 +1,285 @@ +# Ethers.js Adapters + +It is recommended for projects to migrate to [Viem](https://viem.sh) when using Wagmi, but there are some cases where you might still need to use [Ethers.js](https://ethers.org) in your project: + +- You may want to **incrementally migrate** Ethers.js usage to Viem +- Some **third-party libraries & SDKs** may only support Ethers.js +- Personal preference + +We have provided reference implementations for Viem → Ethers.js adapters that you can copy + paste in your project. + +## Client → Provider + +### Reference Implementation + +Copy the following reference implementation into a file of your choice: + +::: code-group + +```ts [Ethers v5] +import { providers } from 'ethers' +import { useMemo } from 'react' +import type { Chain, Client, Transport } from 'viem' +import { Config, useClient } from 'wagmi' + +export function clientToProvider(client: Client) { + const { chain, transport } = client + const network = { + chainId: chain.id, + name: chain.name, + ensAddress: chain.contracts?.ensRegistry?.address, + } + if (transport.type === 'fallback') + return new providers.FallbackProvider( + (transport.transports as ReturnType[]).map( + ({ value }) => new providers.JsonRpcProvider(value?.url, network), + ), + ) + return new providers.JsonRpcProvider(transport.url, network) +} + +/** Hook to convert a viem Client to an ethers.js Provider. */ +export function useEthersProvider({ + chainId, +}: { chainId?: number | undefined } = {}) { + const client = useClient({ chainId }) + return useMemo(() => (client ? clientToProvider(client) : undefined), [client]) +} +``` + +```ts [Ethers v6] +import { FallbackProvider, JsonRpcProvider } from 'ethers' +import { useMemo } from 'react' +import type { Chain, Client, Transport } from 'viem' +import { type Config, useClient } from 'wagmi' + +export function clientToProvider(client: Client) { + const { chain, transport } = client + const network = { + chainId: chain.id, + name: chain.name, + ensAddress: chain.contracts?.ensRegistry?.address, + } + if (transport.type === 'fallback') { + const providers = (transport.transports as ReturnType[]).map( + ({ value }) => new JsonRpcProvider(value?.url, network), + ) + if (providers.length === 1) return providers[0] + return new FallbackProvider(providers) + } + return new JsonRpcProvider(transport.url, network) +} + +/** Action to convert a viem Client to an ethers.js Provider. */ +export function useEthersProvider({ chainId }: { chainId?: number } = {}) { + const client = useClient({ chainId }) + return useMemo(() => (client ? clientToProvider(client) : undefined), [client]) +} +``` + +::: + +### Usage + +Now you can use the `useEthersProvider` function in your components: + +::: code-group + +```ts [example.ts] +import { useEthersProvider } from './ethers' + +function Example() { + const provider = useEthersProvider() + ... +} +``` + +```ts [ethers.ts (Ethers v5)] +import { providers } from 'ethers' +import { useMemo } from 'react' +import type { Chain, Client, Transport } from 'viem' +import { Config, useClient } from 'wagmi' + +export function clientToProvider(client: Client) { + const { chain, transport } = client + const network = { + chainId: chain.id, + name: chain.name, + ensAddress: chain.contracts?.ensRegistry?.address, + } + if (transport.type === 'fallback') + return new providers.FallbackProvider( + (transport.transports as ReturnType[]).map( + ({ value }) => new providers.JsonRpcProvider(value?.url, network), + ), + ) + return new providers.JsonRpcProvider(transport.url, network) +} + +/** Hook to convert a viem Client to an ethers.js Provider. */ +export function useEthersProvider({ + chainId, +}: { chainId?: number | undefined } = {}) { + const client = useClient({ chainId }) + return useMemo(() => (client ? clientToProvider(client) : undefined), [client]) +} +``` + +```ts [ethers.ts (Ethers v6)] +import { FallbackProvider, JsonRpcProvider } from 'ethers' +import { useMemo } from 'react' +import type { Chain, Client, Transport } from 'viem' +import { type Config, useClient } from 'wagmi' + +export function clientToProvider(client: Client) { + const { chain, transport } = client + const network = { + chainId: chain.id, + name: chain.name, + ensAddress: chain.contracts?.ensRegistry?.address, + } + if (transport.type === 'fallback') { + const providers = (transport.transports as ReturnType[]).map( + ({ value }) => new JsonRpcProvider(value?.url, network), + ) + if (providers.length === 1) return providers[0] + return new FallbackProvider(providers) + } + return new JsonRpcProvider(transport.url, network) +} + +/** Action to convert a viem Client to an ethers.js Provider. */ +export function useEthersProvider({ chainId }: { chainId?: number } = {}) { + const client = useClient({ chainId }) + return useMemo(() => (client ? clientToProvider(client) : undefined), [client]) +} +``` + +::: + +## Connector Client → Signer + +### Reference Implementation + +Copy the following reference implementation into a file of your choice: + +::: code-group + +```ts [Ethers v5] +import { providers } from 'ethers' +import { useMemo } from 'react' +import type { Account, Chain, Client, Transport } from 'viem' +import { Config, useConnectorClient } from 'wagmi' + +export function clientToSigner(client: Client) { + const { account, chain, transport } = client + const network = { + chainId: chain.id, + name: chain.name, + ensAddress: chain.contracts?.ensRegistry?.address, + } + const provider = new providers.Web3Provider(transport, network) + const signer = provider.getSigner(account.address) + return signer +} + +/** Hook to convert a Viem Client to an ethers.js Signer. */ +export function useEthersSigner({ chainId }: { chainId?: number } = {}) { + const { data: client } = useConnectorClient({ chainId }) + return useMemo(() => (client ? clientToSigner(client) : undefined), [client]) +} +``` + +```ts [Ethers v6] +import { BrowserProvider, JsonRpcSigner } from 'ethers' +import { useMemo } from 'react' +import type { Account, Chain, Client, Transport } from 'viem' +import { type Config, useConnectorClient } from 'wagmi' + +export function clientToSigner(client: Client) { + const { account, chain, transport } = client + const network = { + chainId: chain.id, + name: chain.name, + ensAddress: chain.contracts?.ensRegistry?.address, + } + const provider = new BrowserProvider(transport, network) + const signer = new JsonRpcSigner(provider, account.address) + return signer +} + +/** Hook to convert a viem Wallet Client to an ethers.js Signer. */ +export function useEthersSigner({ chainId }: { chainId?: number } = {}) { + const { data: client } = useConnectorClient({ chainId }) + return useMemo(() => (client ? clientToSigner(client) : undefined), [client]) +} +``` + +::: + +### Usage + +Now you can use the `useEthersSigner` function in your components: + +::: code-group + +```ts [example.ts] +import { useEthersSigner } from './ethers' + +function example() { + const signer = useEthersSigner() + ... +} +``` + +```ts [ethers.ts (Ethers v5)] +import { providers } from 'ethers' +import { useMemo } from 'react' +import type { Account, Chain, Client, Transport } from 'viem' +import { Config, useConnectorClient } from 'wagmi' + +export function clientToSigner(client: Client) { + const { account, chain, transport } = client + const network = { + chainId: chain.id, + name: chain.name, + ensAddress: chain.contracts?.ensRegistry?.address, + } + const provider = new providers.Web3Provider(transport, network) + const signer = provider.getSigner(account.address) + return signer +} + +/** Action to convert a Viem Client to an ethers.js Signer. */ +export function useEthersSigner({ chainId }: { chainId?: number } = {}) { + const { data: client } = useConnectorClient({ chainId }) + return useMemo(() => (client ? clientToSigner(client) : undefined), [client]) +} +``` + +```ts [ethers.ts (Ethers v6)] +import { BrowserProvider, JsonRpcSigner } from 'ethers' +import { useMemo } from 'react' +import type { Account, Chain, Client, Transport } from 'viem' +import { type Config, useConnectorClient } from 'wagmi' + +export function clientToSigner(client: Client) { + const { account, chain, transport } = client + const network = { + chainId: chain.id, + name: chain.name, + ensAddress: chain.contracts?.ensRegistry?.address, + } + const provider = new BrowserProvider(transport, network) + const signer = new JsonRpcSigner(provider, account.address) + return signer +} + +/** Hook to convert a viem Wallet Client to an ethers.js Signer. */ +export function useEthersSigner({ chainId }: { chainId?: number } = {}) { + const { data: client } = useConnectorClient({ chainId }) + return useMemo(() => (client ? clientToSigner(client) : undefined), [client]) +} +``` + +::: diff --git a/wagmi-project/site/react/guides/faq.md b/wagmi-project/site/react/guides/faq.md new file mode 100644 index 0000000000..8628c5b1b3 --- /dev/null +++ b/wagmi-project/site/react/guides/faq.md @@ -0,0 +1,24 @@ + + +# FAQ / Troubleshooting + +Collection of frequently asked questions with ideas on how to troubleshoot and resolve them. + + + +## How does Wagmi work? + +Until there's a more in-depth write-up about Wagmi internals, here is the gist: + +- Wagmi is essentially a wrapper around [Viem](https://viem.sh) and TanStack Query that adds connector and multichain support. +- [Connectors](/react/api/connectors) allow Wagmi and Ethereum accounts to communicate with each other. +- The Wagmi [`Config`](/react/api/createConfig#config) manages connections established between Wagmi and Connectors, as well as some global state. [Connections](/react/api/createConfig#connection) come with one or more addresses and a chain ID. + - If there are connections, the Wagmi `Config` listens for connection changes and updates the [`chainId`](/react/api/createConfig#chainid) based on the ["current" connection](/react/api/createConfig#current). (The Wagmi `Config` can have [many connections established](/react/api/createConfig#connections) at once, but only one connection can be the "current" connection. Usually this is the connection from the last connector that is connected, but can change based on event emitted from other connectors or through the [`useSwitchAccount`](/react/api/hooks/useSwitchAccount) hook and [`switchAccount`](/core/api/actions/switchAccount) action.) + - If there are no connections, the Wagmi `Config` defaults the global state `chainId` to the first chain it was created with or last established connection. + - The global `chainId` can be changed directly using the [`useSwitchChain`](/react/api/hooks/useSwitchChain) hook and [`switchChain`](/core/api/actions/switchChain) action. This works when there are no connections as well as for most connectors (not all connectors support chain switching). +- Wagmi uses the global `chainId` (from the "current" connection or global state) to internally create Viem Client's, which are used by hooks and actions. +- Hooks are constructed by TanStack Query options helpers, exported by the `'@wagmi/core/query'` entrypoint, and some additional code to wire up type parameters, hook into React Context, etc. +- There are three types of hooks: query hooks, mutation hooks, and config hooks. Query hooks, like [`useCall`](/react/api/hooks/useCall), generally read blockchain state and mutation hooks, like [`useSendTransaction`](/react/api/hooks/useSendTransaction), usually change state through sending transactions via the "current" connection. Config hooks are for getting data from and managing the Wagmi `Config` instance, e.g. [`useChainId`](/react/api/hooks/useChainId) and `useSwitchAccount`. Query and mutation hooks usually have corresponding [Viem actions.](https://viem.sh) + diff --git a/wagmi-project/site/react/guides/migrate-from-v1-to-v2.md b/wagmi-project/site/react/guides/migrate-from-v1-to-v2.md new file mode 100644 index 0000000000..1374fd6eef --- /dev/null +++ b/wagmi-project/site/react/guides/migrate-from-v1-to-v2.md @@ -0,0 +1,658 @@ +--- +title: Migrate from v1 to v2 +description: Guide for migrating from Wagmi v1 to v2. +--- + + + +# Migrate from v1 to v2 + +## Overview + +Wagmi v2 redesigns the core APIs to mesh better with [Viem](https://viem.sh) and [TanStack Query](https://tanstack.com/query/v5/docs/react). This major version transforms Wagmi into a light wrapper around these libraries, sprinkling in multichain support and account management. As such, there are some breaking changes and deprecations to be aware of outlined in this guide. + +To get started, install the latest version of Wagmi and it's required peer dependencies. + +::: code-group +```bash-vue [pnpm] +pnpm add wagmi viem@{{viemVersion}} @tanstack/react-query +``` + +```bash-vue [npm] +npm install wagmi viem@{{viemVersion}} @tanstack/react-query +``` + +```bash-vue [yarn] +yarn add wagmi viem@{{viemVersion}} @tanstack/react-query +``` + +```bash-vue [bun] +bun add wagmi viem@{{viemVersion}} @tanstack/react-query +``` +::: + +::: info Wagmi v2 should be the last major version that will have this many actionable breaking changes. +Moving forward after Wagmi v2, new functionality will be opt-in with old functionality being deprecated alongside the new features. This means upgrading to the latest major versions will not require immediate changes. +::: + +::: info Not ready to migrate yet? +The Wagmi v1 docs are still available at [1.x.wagmi.sh/react](https://1.x.wagmi.sh/react). +::: + +## Dependencies + +### Moved TanStack Query to peer dependencies + +Wagmi uses [TanStack Query](https://tanstack.com/query/v5/docs/react) to manage async state, handling requests, caching, and more. With Wagmi v1, TanStack Query was an internal implementation detail. With Wagmi v2, TanStack Query is a peer dependency. A lot of Wagmi users also use TanStack Query in their apps so making it a peer dependency gives them more control and removes some custom Wagmi code internally. + +If you don't normally use TanStack Query, all you need to do is set it up and mostly forget about it (we'll provide guidance around version updates). + +::: code-group +```tsx [app.tsx] +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' // [!code ++] +import { WagmiProvider } from 'wagmi' +import { config } from './config' + +const queryClient = new QueryClient() // [!code ++] + +function App() { + return ( + + // [!code ++] + {/** ... */} + // [!code ++] + + ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +For more information on setting up TanStack Query for Wagmi, follow the [Getting Started docs](/react/getting-started#setup-tanstack-query). If you want to set up persistence for your query cache (default behavior before Wagmi v2), check out the [TanStack Query docs](https://tanstack.com/query/v5/docs/react/plugins/persistQueryClient#usage-with-react). + +### Dropped CommonJS support + +Wagmi v2 no longer publishes a separate `cjs` tag since very few people use this tag and ESM is the future. See [Sindre Sorhus' guide](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c) for more info about switching to ESM. + +## Hooks + +### Removed mutation setup arguments + +Mutation hooks are hooks that change network or application state, sign data, or perform write operations through mutation functions. With Wagmi v1, you could pass arguments directly to these hooks instead of using them with their mutation functions. For example: + +```ts{3} +// Wagmi v1 +const { signMessage } = useSignMessage({ + message: 'foo bar baz', +}) +``` + +With Wagmi v2, you must pass arguments to the mutation function instead. This follows the same behavior as [TanStack Query](https://tanstack.com/query/v5/docs/react/guides/mutations) mutations and improves type-safety. + +```tsx +import { useSignMessage } from 'wagmi' + +const { signMessage } = useSignMessage({ message: 'foo bar baz' }) // [!code --] +const { signMessage } = useSignMessage() // [!code ++] + + +``` + +### Moved TanStack Query parameters to `query` property + +Previously, you could pass TanStack Query parameters, like `enabled` and `staleTime`, directly to hooks. In Wagmi v2, TanStack Query parameters are now moved to the `query` property. This allows Wagmi to better support TanStack Query type inference, control for future breaking changes since [TanStack Query is now a peer dependency](#moved-tanstack-query-to-peer-dependencies), and expose Wagmi-related hook property at the top-level of editor features, like autocomplete. + +```tsx +useReadContract({ + enabled: false, // [!code --] + staleTime: 1_000, // [!code --] + query: { // [!code ++] + enabled: false, // [!code ++] + staleTime: 1_000, // [!code ++] + }, // [!code ++] +}) +``` + +### Removed watch property + +The `watch` property was removed from all hooks besides [`useBlock`](/react/api/hooks/useBlock) and [`useBlockNumber`](/react/api/hooks/useBlockNumber). This property allowed hooks to internally listen for block changes and automatically refresh their data. In Wagmi v2, you can compose `useBlock` or `useBlockNumber` along with [`React.useEffect`](https://react.dev/reference/react/useEffect) to achieve the same behavior. Two different approaches are outlined for `useBalance` below. + +::: code-group +```ts [invalidateQueries] +import { useQueryClient } from '@tanstack/react-query' // [!code ++] +import { useEffect } from 'react' // [!code ++] +import { useBlockNumber, useBalance } from 'wagmi' // [!code ++] + +const queryClient = useQueryClient() // [!code ++] +const { data: blockNumber } = useBlockNumber({ watch: true }) // [!code ++] +const { data: balance, queryKey } = useBalance({ // [!code ++] + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + watch: true, // [!code --] +}) + +useEffect(() => { // [!code ++] + queryClient.invalidateQueries({ queryKey }) // [!code ++] +}, [blockNumber, queryClient]) // [!code ++] +``` +```ts [refetch] +import { useEffect } from 'react' // [!code ++] +import { useBlockNumber, useBalance } from 'wagmi' // [!code ++] + +const { data: blockNumber } = useBlockNumber({ watch: true }) // [!code ++] +const { data: balance, refetch } = useBalance({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + watch: true, // [!code --] +}) + +useEffect(() => { // [!code ++] + refetch() // [!code ++] +}, [blockNumber]) // [!code ++] +``` +::: + +This is a bit more code, but removes a lot of internal code from hooks that can slow down your app when not used and gives you more control. For example, you can easily refresh data every five blocks instead of every block. + +```ts +const { data: blockNumber } = useBlockNumber({ watch: true }) +const { data: balance, queryKey } = useBalance({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', +}) + +useEffect(() => { + if (blockNumber % 5 === 0) // [!code focus] + queryClient.invalidateQueries({ queryKey }) // [!code focus] +}, [blockNumber, queryClient]) +``` + +### Removed suspense property + +Wagmi used to support an experimental `suspense` property via TanStack Query. Since TanStack Query [removed `suspense`](https://tanstack.com/query/v5/docs/react/guides/migrating-to-v5#new-hooks-for-suspense) from its `useQuery` hook, it is no longer supported by Wagmi Hooks. + +Instead, you can use `useSuspenseQuery` along with TanStack Query-related exports from the `'wagmi/query'` entrypoint. + +```ts +import { useSuspenseQuery } from '@tanstack/react-query' // [!code ++] +import { useConfig } from 'wagmi' // [!code ++] +import { getBalanceQueryOptions } from 'wagmi/query' // [!code ++] +import { useBalance } from 'wagmi' // [!code --] + +const config = useConfig() // [!code ++] +const options = getBalanceQueryOptions(config, { address: '0x…' }) // [!code ++] +const result = useSuspenseQuery(options) // [!code ++] +const result = useBalance({ // [!code --] + address: '0x…', // [!code --] + suspense: true, // [!code --] +}) // [!code --] +``` + +### Removed prepare hooks + +`usePrepareContractWrite` and `usePrepareSendTransaction` were removed and replaced with idiomatic Viem alternatives. For `usePrepareContractWrite`, use [`useSimulateContract`](/react/api/hooks/useSimulateContract). Similar to `usePrepareContractWrite`, `useSimulateContract` composes well with `useWriteContract` + +```tsx +import { usePrepareContractWrite, useWriteContract } from 'wagmi' // [!code --] +import { useSimulateContract, useWriteContract } from 'wagmi' // [!code ++] + +const { config } = usePrepareContractWrite({ // [!code --] +const { data } = useSimulateContract({ // [!code ++] + address: '0x', + abi: [{ + type: 'function', + name: 'transferFrom', + stateMutability: 'nonpayable', + inputs: [ + { name: 'sender', type: 'address' }, + { name: 'recipient', type: 'address' }, + { name: 'amount', type: 'uint256' }, + ], + outputs: [{ type: 'bool' }], + }], + functionName: 'transferFrom', + args: ['0x', '0x', 123n], +}) +const { write } = useWriteContract(config) // [!code --] +const { writeContract } = useWriteContract() // [!code ++] + + +``` + +Instead of `usePrepareSendTransaction`, use [`useEstimateGas`](/react/api/hooks/useEstimateGas). You can pass `useEstimateGas` `data` to `useSendTransaction` to compose the two hooks. + +```tsx +import { usePrepareSendTransaction, useSendTransaction } from 'wagmi' // [!code --] +import { useEstimateGas, useSendTransaction } from 'wagmi' // [!code ++] +import { parseEther } from 'viem' + +const { config } = usePrepareSendTransaction({ // [!code --] +const { data } = useEstimateGas({ // [!code ++] + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), +}) +const { sendTransaction } = useSendTransaction(config) // [!code --] +const { sendTransaction } = useSendTransaction() // [!code ++] + + +``` + +This might seem like more work, but it gives you more control and is more accurate representation of what is happening under the hood. + +### Removed `useNetwork` hook + +The `useNetwork` hook was removed since the connected chain is typically based on the connected account. Use [`useAccount`](/react/api/hooks/useAccount) to get the connected `chain`. + +```ts +import { useNetwork } from 'wagmi' // [!code --] +import { useAccount } from 'wagmi' // [!code ++] + +const { chain } = useNetwork() // [!code --] +const { chain } = useAccount() // [!code ++] +``` + +Use `useConfig` for the list of `chains` set up with the Wagmi [`Config`](/react/api/createConfig#chains). + +```ts +import { useNetwork } from 'wagmi' // [!code --] +import { useConfig } from 'wagmi' // [!code ++] + +const { chains } = useNetwork() // [!code --] +const { chains } = useConfig() // [!code ++] +``` + +### Removed `onConnect` and `onDisconnect` callbacks from `useAccount` + +The `onConnect` and `onDisconnect` callbacks were removed from the `useAccount` hook since it is frequently used without these callbacks so it made sense to extract these into a new API, [`useAccountEffect`](/react/api/hooks/useAccountEffect), rather than clutter the `useAccount` hook. + +```ts +import { useAccount } from 'wagmi' // [!code --] +import { useAccountEffect } from 'wagmi' // [!code ++] + +useAccount({ // [!code --] +useAccountEffect({ // [!code ++] + onConnect(data) { + console.log('connected', data) + }, + onDisconnect() { + console.log('disconnected') + }, +}) +``` + +### Removed `useWebSocketPublicClient` + +The Wagmi [`Config`](/react/api/createConfig) does not separate transport types anymore. Simply use Viem's [`webSocket`](https://viem.sh/docs/clients/transports/websocket.html) transport instead when setting up your Wagmi `Config`. You can get Viem `Client` instance with this transport attached by using [`useClient`](/react/api/hooks/useClient) or [`usePublicClient`](/react/api/hooks/usePublicClient). + +### Removed `useInfiniteReadContracts` `paginatedIndexesConfig` + +In the spirit of removing unnecessary abstractions, `paginatedIndexesConfig` was removed. Use `useInfiniteReadContracts`'s `initialPageParam` and `getNextPageParam` parameters along with `fetchNextPage`/`fetchPreviousPage` from the result instead or copy `paginatedIndexesConfig`'s implementation to your codebase. + +See the [TanStack Query docs](https://tanstack.com/query/v5/docs/react/guides/infinite-queries) for more information on infinite queries. + +### Updated `useSendTransaction` and `useWriteContract` return type + +Updated [`useSendTransaction`](/react/api/hooks/useSendTransaction) and [`useWriteContract`](/react/api/hooks/useWriteContract) return type from `` { hash: `0x${string}` } `` to `` `0x${string}` ``. + +```ts +const result = useSendTransaction() +result.data?.hash // [!code --] +result.data // [!code ++] +``` + +### Updated `useConnect` return type + +Updated [`useConnect`](/react/api/hooks/useConnect) return type from `` { account: Address; chain: { id: number; unsupported?: boolean }; connector: Connector } `` to `` { accounts: readonly Address[]; chainId: number } ``. This better reflects the ability to have multiple accounts per connector. + +### Renamed parameters and return types + +All hook parameters and return types follow the naming pattern of `[PascalCaseHookName]Parameters` and `[PascalCaseHookName]ReturnType`. For example, `UseAccountParameters` and `UseAccountReturnType`. + +```ts +import { UseAccountConfig, UseAccountResult } from 'wagmi' // [!code --] +import { UseAccountParameters, UseAccountReturnType } from 'wagmi' // [!code ++] +``` + +## Connectors + +### Updated connector API + +In order to maximize type-safety and ease of creating connectors, the connector API changed. Follow the [Creating Connectors guide](/dev/creating-connectors) for more info on creating new connectors and converting Wagmi v1 connectors. + +### Removed individual entrypoints + +Previously, each connector had it's own entrypoint to optimize tree-shaking. Since all connectors now have [`package.json#sideEffects`](https://webpack.js.org/guides/tree-shaking/#mark-the-file-as-side-effect-free) enabled, this is no longer necessary and the entrypoint is unified. Use the `'wagmi/connectors'` entrypoint instead. + +```ts +import { InjectedConnector } from 'wagmi/connectors/injected' // [!code --] +import { CoinbaseWalletConnector } from 'wagmi/connectors/coinbaseWallet' // [!code --] +import { coinbaseWallet, injected } from 'wagmi/connectors' // [!code ++] +``` + +### Removed `MetaMaskConnector` + +The `MetaMaskConnector` was removed since it was nearly the same thing as the `InjectedConnector`. Use the [`injected`](/react/api/connectors/injected) connector instead, along with the [`target`](/react/api/connectors/injected#target) parameter set to `'metaMask'`, for the same behavior. + +```ts +import { MetaMaskConnector } from 'wagmi/connectors/metaMask' // [!code --] +import { injected } from 'wagmi/connectors' // [!code ++] + +const connector = new MetaMaskConnector() // [!code --] +const connector = injected({ target: 'metaMask' }) // [!code ++] +``` +### Renamed connectors + +In Wagmi v1, connectors were classes you needed to instantiate. In Wagmi v2, connectors are functions. As a result, the API has changed. Connectors have the following new names: + +- `CoinbaseWalletConnector` is now [`coinbaseWallet`](/react/api/connectors/coinbaseWallet). +- `InjectedConnector` is now [`injected`](/react/api/connectors/injected). +- `SafeConnector` is now [`safe`](/react/api/connectors/safe). +- `WalletConnectConnector` is now [`walletConnect`](/react/api/connectors/walletConnect). + +To create a connector, you now call the connector function with parameters. + +```ts +import { WalletConnectConnector } from 'wagmi/connectors/walletConnect' // [!code --] +import { walletConnect } from 'wagmi/connectors' // [!code ++] + +const connector = new WalletConnectConnector({ // [!code --] +const connector = walletConnect({ // [!code ++] + projectId: '3fcc6bba6f1de962d911bb5b5c3dba68', +}) +``` + +### Removed `WalletConnectLegacyConnector` + +WalletConnect v1 was sunset June 28, 2023. Use the [`walletConnect`](/react/api/connectors/walletConnect) connector instead. + +```ts +import { WalletConnectLegacyConnector } from 'wagmi/connectors/walletConnectLegacy' // [!code --] +import { walletConnect } from 'wagmi/connectors' // [!code ++] + +const connector = new WalletConnectLegacyConnector({ // [!code --] +const connector = walletConnect({ // [!code ++] + projectId: '3fcc6bba6f1de962d911bb5b5c3dba68', +}) +``` + +## Chains + +### Updated `'wagmi/chains'` entrypoint + +Chains now live in the [Viem repository](https://github.com/wevm/viem). As a result, the `'wagmi/chains'` entrypoint now proxies all chains from `'viem/chains'` directly. + +### Removed `mainnet` and `sepolia` from main entrypoint + +Since the `'wagmi/chains'` entrypoint now proxies `'viem/chains'`, `mainnet` and `sepolia` were removed from the main entrypoint. Use the `'wagmi/chains'` entrypoint instead. + +```ts +import { mainnet, sepolia } from 'wagmi' // [!code --] +import { mainnet, sepolia } from 'wagmi/chains' // [!code ++] +``` + +## Errors + +A number of errors were renamed to better reflect their functionality or replaced by Viem errors. + +## Miscellaneous + +### Removed internal ENS name normalization + +Before v2, Wagmi handled ENS name normalization internally for `useEnsAddress`, `useEnsAvatar`, and `useEnsResolver`, using Viem's [`normalize`](https://viem.sh/docs/ens/utilities/normalize.html) function. This added extra bundle size as full normalization is quite heavy. For v2, you must normalize ENS names yourself before passing them to these hooks. You can use Viem's `normalize` function or any other function that performs [UTS-46 normalization](https://unicode.org/reports/tr46). + +```ts +import { useEnsAddress } from 'wagmi' +import { normalize } from 'viem/ens' // [!code ++] + +const result = useEnsAddress({ + name: 'wevm.eth', // [!code --] + name: normalize('wevm.eth'), // [!code ++] +}) +``` + +By inverting control, Wagmi let's you choose how much normalization to do. For example, maybe your project only allows ENS names that are numeric so no normalization is not needed. Check out the [ENS documentation](https://docs.ens.domains/contract-api-reference/name-processing#normalising-names) for more information on normalizing names. + +### Removed `configureChains` + +The Wagmi v2 `Config` now has native multichain support using the [`chains`](/react/api/createConfig) parameter so the `configureChains` function is no longer required. + +```ts +import { configureChains, createConfig } from 'wagmi' // [!code --] +import { http, createConfig } from 'wagmi' // [!code ++] +import { mainnet, sepolia } from 'wagmi/chains' + +const { chains, publicClient } = configureChains( // [!code --] + [mainnet, sepolia], // [!code --] + [publicProvider(), publicProvider()], // [!code --] +) // [!code --] + +export const config = createConfig({ + publicClient, // [!code --] + chains: [mainnet, sepolia], // [!code ++] + transports: { // [!code ++] + [mainnet.id]: http(), // [!code ++] + [sepolia.id]: http(), // [!code ++] + }, // [!code ++] +}) +``` + +### Removed ABI exports + +Import from Viem instead. + +```ts +import { erc20ABI } from 'wagmi' // [!code --] +import { erc20Abi } from 'viem' // [!code ++] +``` + +### Removed `'wagmi/providers/*` entrypoints + +It never made sense that we would have provider URLs hardcoded in the Wagmi codebase. Use [Viem transports](https://viem.sh/docs/clients/intro.html#transports) along with RPC provider URLs instead. + +```ts +import { alchemyProvider } from 'wagmi/providers/alchemy' // [!code --] +import { http } from 'viem' // [!code ++] + +const transport = http('https://mainnet.example.com') +``` + +### Updated `createConfig` parameters + +- Removed `autoConnect`. The reconnecting behavior is now managed by React and not related to the Wagmi `Config`. Use `WagmiProvider` [`reconnectOnMount`](/react/api/WagmiProvider#reconnectonmount) or [`useReconnect`](/react/api/hooks/useReconnect) hook instead. +- Removed `publicClient` and `webSocketPublicClient`. Use [`transports`](/react/api/createConfig#transports) or [`client`](/react/api/createConfig#client) instead. +- Removed `logger`. Wagmi no longer logs debug information to console. + +### Updated `Config` object + +- Removed `config.connector`. Use `config.state.connections.get(config.state.current)?.connector` instead. +- Removed `config.data`. Use `config.state.connections.get(config.state.current)` instead. +- Removed `config.error`. Was unused and not needed. +- Removed `config.lastUsedChainId`. Use `config.state.connections.get(config.state.current)?.chainId` instead. +- Removed `config.publicClient`. Use [`config.getClient()`](/react/api/createConfig#getclient) or [`getPublicClient`](/core/api/actions/getPublicClient) instead. +- Removed `config.status`. Use [`config.state.status`](/react/api/createConfig#status) instead. +- Removed `config.webSocketClient`. Use [`config.getClient()`](/react/api/createConfig#getclient) or [`getPublicClient`](/core/api/actions/getPublicClient) instead. +- Removed `config.clearState`. Was unused and not needed. +- Removed `config.autoConnect()`. Use [`reconnect`](/core/api/actions/reconnect) action instead. +- Renamed `config.setConnectors`. Use `config._internal.setConnectors` instead. +- Removed `config.setLastUsedConnector`. Use `config.storage?.setItem('recentConnectorId', connectorId)` instead. +- Removed `getConfig`. `config` should be passed explicitly to actions instead of using global `config`. + +## Deprecations + +### Renamed `WagmiConfig` + +`WagmiConfig` was renamed to [`WagmiProvider`](/react/api/WagmiProvider) to reduce confusion with the Wagmi [`Config`](/react/api/createConfig) type. React Context Providers usually follow the naming schema `*Provider` so this is a more idiomatic name. Now that Wagmi no longer uses Ethers.js (since Wagmi v1), the term "Provider" is less overloaded. + +::: code-group +```tsx [app.tsx] +import { WagmiConfig } from 'wagmi' // [!code --] +import { WagmiProvider } from 'wagmi' // [!code ++] +import { config } from './config' + +function App() { + return ( + // [!code --] + // [!code ++] + {/** ... */} + // [!code ++] + // [!code --] + ) +} +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### Deprecated `useBalance` `token` parameter + +Moving forward, `useBalance` will only work for native currencies, thus the `token` parameter is no longer supported. Use [`useReadContracts`](/react/api/hooks/useReadContracts) instead. + +```ts +import { useBalance } from 'wagmi' // [!code --] +import { useReadContracts } from 'wagmi' // [!code ++] +import { erc20Abi } from 'viem' // [!code ++] + +const result = useBalance({ // [!code --] + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', // [!code --] + token: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code --] +}) // [!code --] +const result = useReadContracts({ // [!code ++] + allowFailure: false, // [!code ++] + contracts: [ // [!code ++] + { // [!code ++] + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code ++] + abi: erc20Abi, // [!code ++] + functionName: 'balanceOf', // [!code ++] + args: ['0x4557B18E779944BFE9d78A672452331C186a9f48'], // [!code ++] + }, // [!code ++] + { // [!code ++] + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code ++] + abi: erc20Abi, // [!code ++] + functionName: 'decimals', // [!code ++] + }, // [!code ++] + { // [!code ++] + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code ++] + abi: erc20Abi, // [!code ++] + functionName: 'symbol', // [!code ++] + }, // [!code ++] + ] // [!code ++] +}) // [!code ++] +``` + +### Deprecated `useBalance` `unit` parameter and `formatted` return value + +Moving forward, `useBalance` will not accept the `unit` parameter or return a `formatted` value. Instead you can call `formatUnits` from Viem directly or use another number formatting library, like [dnum](https://github.com/bpierre/dnum) instead. + +```ts +import { formatUnits } from 'viem' // [!code ++] +import { useBalance } from 'wagmi' + +const result = useBalance({ + address: '0x4557B18E779944BFE9d78A672452331C186a9f48', + unit: 'ether', // [!code --] +}) +result.data!.formatted // [!code --] +formatUnits(result.data!.value, result.data!.decimals) // [!code ++] +``` + +### Deprecated `useToken` + +Moving forward, `useToken` is no longer supported. Use [`useReadContracts`](/react/api/hooks/useReadContracts) instead. + +```ts +import { useToken } from 'wagmi' // [!code --] +import { useReadContracts } from 'wagmi' // [!code ++] +import { erc20Abi } from 'viem' // [!code ++] + +const result = useToken({ // [!code --] + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code --] +}) // [!code --] +const result = useReadContracts({ // [!code ++] + allowFailure: false, // [!code ++] + contracts: [ // [!code ++] + { // [!code ++] + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code ++] + abi: erc20Abi, // [!code ++] + functionName: 'decimals', // [!code ++] + }, // [!code ++] + { // [!code ++] + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code ++] + abi: erc20Abi, // [!code ++] + functionName: 'name', // [!code ++] + }, // [!code ++] + { // [!code ++] + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code ++] + abi: erc20Abi, // [!code ++] + functionName: 'symbol', // [!code ++] + }, // [!code ++] + { // [!code ++] + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', // [!code ++] + abi: erc20Abi, // [!code ++] + functionName: 'totalSupply', // [!code ++] + }, // [!code ++] + ] // [!code ++] +}) // [!code ++] +``` + +### Deprecated `formatUnits` parameters and return values + +The `formatUnits` parameter and related return values (e.g. `result.formatted`) are deprecated for the following hooks: + +- [`useEstimateFeesPerGas`](/react/api/hooks/useEstimateFeesPerGas) +- [`useToken`](/react/api/hooks/useToken) + +Instead you can call `formatUnits` from Viem directly or use another number formatting library, like [dnum](https://github.com/bpierre/dnum) instead. + +```ts +import { formatUnits } from 'viem' // [!code ++] + +const result = useToken({ + address: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + formatUnits: 'ether', +}) +result.data!.totalSupply.formatted // [!code --] +formatUnits(result.data!.totalSupply.value, 18) // [!code ++] +``` + +This allows us to invert control to users so they can handle number formatting however they want, taking into account precision, localization, and more. + +### Renamed hooks + +The following hooks were renamed to better reflect their functionality and underlying [Viem](https://viem.sh) actions: + +- `useContractRead` is now [`useReadContract`](/react/api/hooks/useReadContract) +- `useContractReads` is now [`useReadContracts`](/react/api/hooks/useReadContracts) +- `useContractWrite` is now [`useWriteContract`](/react/api/hooks/useWriteContract) +- `useContractEvent` is now [`useWatchContractEvent`](/react/api/hooks/useWatchContractEvent) +- `useContractInfiniteReads` is now [`useInfiniteReadContracts`](/react/api/hooks/useInfiniteReadContracts) +- `useFeeData` is now [`useEstimateFeesPerGas`](/react/api/hooks/useEstimateFeesPerGas) +- `useSwitchNetwork` is now [`useSwitchChain`](/react/api/hooks/useSwitchChain) +- `useWaitForTransaction` is now [`useWaitForTransactionReceipt`](/react/api/hooks/useWaitForTransactionReceipt) + +### Miscellaneous + +- `WagmiConfigProps` renamed to [`WagmiProviderProps`](/react/api/WagmiProvider#parameters). +- `Context` renamed to [`WagmiContext`](/react/api/WagmiProvider#context). diff --git a/wagmi-project/site/react/guides/read-from-contract.md b/wagmi-project/site/react/guides/read-from-contract.md new file mode 100644 index 0000000000..b41f5c569d --- /dev/null +++ b/wagmi-project/site/react/guides/read-from-contract.md @@ -0,0 +1,202 @@ +# Read from Contract + +The [`useReadContract` Hook](/react/api/hooks/useReadContract) allows you to read data on a smart contract, from a `view` or `pure` (read-only) function. They can only read the state of the contract, and cannot make any changes to it. Since read-only methods do not change the state of the contract, they do not require any gas to be executed, and can be called by any user without the need to pay for gas. + +The component below shows how to retrieve the token balance of an address from the [Wagmi Example](https://etherscan.io/token/0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2) contract + +:::code-group +```tsx [read-contract.tsx] +import { useReadContract } from 'wagmi' +import { wagmiContractConfig } from './contracts' + +function ReadContract() { + const { data: balance } = useReadContract({ + ...wagmiContractConfig, + functionName: 'balanceOf', + args: ['0x03A71968491d55603FFe1b11A9e23eF013f75bCF'], + }) + + return ( +
Balance: {balance?.toString()}
+ ) +} +``` +```ts [contracts.ts] +export const wagmiContractConfig = { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi: [ + { + type: 'function', + name: 'balanceOf', + stateMutability: 'view', + inputs: [{ name: 'account', type: 'address' }], + outputs: [{ type: 'uint256' }], + }, + { + type: 'function', + name: 'totalSupply', + stateMutability: 'view', + inputs: [], + outputs: [{ name: 'supply', type: 'uint256' }], + }, + ], +} as const +``` +::: + +If `useReadContract` depends on another value (`address` in the example below), you can use the [`query.enabled`](/react/api/hooks/useReadContract#enabled) option to prevent the query from running until the dependency is ready. + +```tsx +const { data: balance } = useReadContract({ + ...wagmiContractConfig, + functionName: 'balanceOf', + args: [address], + query: { // [!code focus] + enabled: !!address, // [!code focus] + }, // [!code focus] +}) +``` + +## Loading & Error States + +The [`useReadContract` Hook](/react/api/hooks/useReadContract) also returns loading & error states, which can be used to display a loading indicator while the data is being fetched, or an error message if contract execution reverts. + +:::code-group + +```tsx [read-contract.tsx] +import { type BaseError, useReadContract } from 'wagmi' + +function ReadContract() { + const { + data: balance, + error, // [!code ++] + isPending // [!code ++] + } = useReadContract({ + ...wagmiContractConfig, + functionName: 'balanceOf', + args: ['0x03A71968491d55603FFe1b11A9e23eF013f75bCF'], + }) + + if (isPending) return
Loading...
// [!code ++] + + if (error) // [!code ++] + return ( // [!code ++] +
// [!code ++] + Error: {(error as BaseError).shortMessage || error.message} // [!code ++] +
// [!code ++] + ) // [!code ++] + + return ( +
Balance: {balance?.toString()}
+ ) +} +``` + +## Refetching On Blocks + +The [`useBlockNumber` Hook](/react/api/hooks/useBlockNumber) can be utilized to refetch or [invalidate](https://tanstack.com/query/latest/docs/framework/react/guides/query-invalidation) the contract data on a specific block interval. + +:::code-group +```tsx [read-contract.tsx (refetch)] +import { useEffect } from 'react' +import { useBlockNumber, useReadContract } from 'wagmi' + +function ReadContract() { + const { data: balance, refetch } = useReadContract({ + ...wagmiContractConfig, + functionName: 'balanceOf', + args: ['0x03A71968491d55603FFe1b11A9e23eF013f75bCF'], + }) + const { data: blockNumber } = useBlockNumber({ watch: true }) + + useEffect(() => { + // want to refetch every `n` block instead? use the modulo operator! + // if (blockNumber % 5 === 0) refetch() // refetch every 5 blocks + refetch() + }, [blockNumber]) + + return ( +
Balance: {balance?.toString()}
+ ) +} +``` +```tsx [read-contract.tsx (invalidate)] +import { useQueryClient } from '@tanstack/react-query' +import { useEffect } from 'react' +import { useBlockNumber, useReadContract } from 'wagmi' + +function ReadContract() { + const queryClient = useQueryClient() + const { data: balance, refetch } = useReadContract({ + ...wagmiContractConfig, + functionName: 'balanceOf', + args: ['0x03A71968491d55603FFe1b11A9e23eF013f75bCF'], + }) + const { data: blockNumber } = useBlockNumber({ watch: true }) + + useEffect(() => { + // if `useReadContract` is in a different hook/component, + // you can import `readContractQueryKey` from `'wagmi/query'` and + // construct a one-off query key to use for invalidation + queryClient.invalidateQueries({ queryKey }) + }, [blockNumber, queryClient]) + + return ( +
Balance: {balance?.toString()}
+ ) +} +``` +::: + +## Calling Multiple Functions + +We can use the [`useReadContract` Hook](/react/api/hooks/useReadContract) multiple times in a single component to call multiple functions on the same contract, but this ends up being hard to manage as the number of functions increases, especially when we also want to deal with loading & error states. + +Luckily, to make this easier, we can use the [`useReadContracts` Hook](/react/api/hooks/useReadContracts) to call multiple functions in a single call. + +:::code-group + +```tsx [read-contract.tsx] +import { type BaseError, useReadContracts } from 'wagmi' + +function ReadContract() { + const { + data, + error, + isPending + } = useReadContracts({ + contracts: [{ + ...wagmiContractConfig, + functionName: 'balanceOf', + args: ['0x03A71968491d55603FFe1b11A9e23eF013f75bCF'], + }, { + ...wagmiContractConfig, + functionName: 'ownerOf', + args: [69n], + }, { + ...wagmiContractConfig, + functionName: 'totalSupply', + }] + }) + const [balance, ownerOf, totalSupply] = data || [] + + if (isPending) return
Loading...
+ + if (error) + return ( +
+ Error: {(error as BaseError).shortMessage || error.message} +
+ ) + + return ( + <> +
Balance: {balance?.toString()}
+
Owner of Token 69: {ownerOf?.toString()}
+
Total Supply: {totalSupply?.toString()}
+ + ) +} +``` + +::: diff --git a/wagmi-project/site/react/guides/send-transaction.md b/wagmi-project/site/react/guides/send-transaction.md new file mode 100644 index 0000000000..a6c5c1887a --- /dev/null +++ b/wagmi-project/site/react/guides/send-transaction.md @@ -0,0 +1,362 @@ +# Send Transaction + +The following guide teaches you how to send transactions in Wagmi. The example below builds on the [Connect Wallet guide](/react/guides/connect-wallet) and uses the [useSendTransaction](/react/api/hooks/useSendTransaction) & [useWaitForTransaction](/react/api/hooks/useWaitForTransactionReceipt) hooks. + +## Example + +Feel free to check out the example before moving on: + + + +## Steps + +### 1. Connect Wallet + +Follow the [Connect Wallet guide](/react/guides/connect-wallet) guide to get this set up. + +### 2. Create a new component + +Create your `SendTransaction` component that will contain the send transaction logic. + +::: code-group + +```tsx [send-transaction.tsx] +import * as React from 'react' + +export function SendTransaction() { + return ( +
+ + + +
+ ) +} +``` + +::: + +### 3. Add a form handler + +Next, we will need to add a handler to the form that will send the transaction when the user hits "Send". This will be a basic handler in this step. + +::: code-group + +```tsx [send-transaction.tsx] +import * as React from 'react' + +export function SendTransaction() { + async function submit(e: React.FormEvent) { // [!code ++] + e.preventDefault() // [!code ++] + const formData = new FormData(e.target as HTMLFormElement) // [!code ++] + const to = formData.get('address') as `0x${string}` // [!code ++] + const value = formData.get('value') as string // [!code ++] + } // [!code ++] + + return ( +
// [!code --] + // [!code ++] + + + +
+ ) +} +``` + +::: + +### 4. Hook up the `useSendTransaction` Hook + +Now that we have the form handler, we can hook up the [`useSendTransaction` Hook](/react/api/hooks/useSendTransaction) to send the transaction. + +::: code-group + +```tsx [send-transaction.tsx] +import * as React from 'react' +import { useSendTransaction } from 'wagmi' // [!code ++] +import { parseEther } from 'viem' // [!code ++] + +export function SendTransaction() { + const { data: hash, sendTransaction } = useSendTransaction() // [!code ++] + + async function submit(e: React.FormEvent) { + e.preventDefault() + const formData = new FormData(e.target as HTMLFormElement) + const to = formData.get('address') as `0x${string}` + const value = formData.get('value') as string + sendTransaction({ to, value: parseEther(value) }) // [!code ++] + } + + return ( +
+ + + + {hash &&
Transaction Hash: {hash}
} // [!code ++] +
+ ) +} +``` + +::: + +### 5. Add loading state (optional) + +We can optionally add a loading state to the "Send" button while we are waiting confirmation from the user's wallet. + +::: code-group + +```tsx [send-transaction.tsx] +import * as React from 'react' +import { useSendTransaction } from 'wagmi' +import { parseEther } from 'viem' + +export function SendTransaction() { + const { + data: hash, + isPending, // [!code ++] + sendTransaction + } = useSendTransaction() + + async function submit(e: React.FormEvent) { + e.preventDefault() + const formData = new FormData(e.target as HTMLFormElement) + const to = formData.get('address') as `0x${string}` + const value = formData.get('value') as string + sendTransaction({ to, value: parseEther(value) }) + } + + return ( +
+ + + + {hash &&
Transaction Hash: {hash}
} +
+ ) +} +``` + +::: + +### 6. Wait for transaction receipt (optional) + +We can also display the transaction confirmation status to the user by using the [`useWaitForTransactionReceipt` Hook](/react/api/hooks/useWaitForTransactionReceipt). + +::: code-group + +```tsx [send-transaction.tsx] +import * as React from 'react' +import { + useSendTransaction, + useWaitForTransactionReceipt // [!code ++] +} from 'wagmi' +import { parseEther } from 'viem' + +export function SendTransaction() { + const { + data: hash, + isPending, + sendTransaction + } = useSendTransaction() + + async function submit(e: React.FormEvent) { + e.preventDefault() + const formData = new FormData(e.target as HTMLFormElement) + const to = formData.get('address') as `0x${string}` + const value = formData.get('value') as string + sendTransaction({ to, value: parseEther(value) }) + } + + const { isLoading: isConfirming, isSuccess: isConfirmed } = // [!code ++] + useWaitForTransactionReceipt({ // [!code ++] + hash, // [!code ++] + }) // [!code ++] + + return ( +
+ + + + {hash &&
Transaction Hash: {hash}
} + {isConfirming &&
Waiting for confirmation...
} // [!code ++] + {isConfirmed &&
Transaction confirmed.
} // [!code ++] +
+ ) +} +``` + +::: + +### 7. Handle errors (optional) + +If the user rejects the transaction, or the user does not have enough funds to cover the transaction, we can display an error message to the user. + +::: code-group + +```tsx [send-transaction.tsx] +import * as React from 'react' +import { + type BaseError, // [!code ++] + useSendTransaction, + useWaitForTransactionReceipt +} from 'wagmi' +import { parseEther } from 'viem' + +export function SendTransaction() { + const { + data: hash, + error, // [!code ++] + isPending, + sendTransaction + } = useSendTransaction() + + async function submit(e: React.FormEvent) { + e.preventDefault() + const formData = new FormData(e.target as HTMLFormElement) + const to = formData.get('address') as `0x${string}` + const value = formData.get('value') as string + sendTransaction({ to, value: parseEther(value) }) + } + + const { isLoading: isConfirming, isSuccess: isConfirmed } = + useWaitForTransactionReceipt({ + hash, + }) + + return ( +
+ + + + {hash &&
Transaction Hash: {hash}
} + {isConfirming &&
Waiting for confirmation...
} + {isConfirmed &&
Transaction confirmed.
} + {error && ( // [!code ++] +
Error: {(error as BaseError).shortMessage || error.message}
// [!code ++] + )} // [!code ++] +
+ ) +} +``` + +::: + +### 8. Wire it up! + +Finally, we can wire up our Send Transaction component to our application's entrypoint. + +::: code-group + +```tsx [app.tsx] +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { WagmiProvider, useAccount } from 'wagmi' +import { config } from './config' +import { SendTransaction } from './send-transaction' // [!code ++] + +const queryClient = new QueryClient() + +function App() { + return ( + + + // [!code ++] + + + ) +} +``` + +```tsx [send-transaction.tsx] +import * as React from 'react' +import { + type BaseError, + useSendTransaction, + useWaitForTransactionReceipt +} from 'wagmi' +import { parseEther } from 'viem' + +export function SendTransaction() { + const { + data: hash, + error, + isPending, + sendTransaction + } = useSendTransaction() + + async function submit(e: React.FormEvent) { + e.preventDefault() + const formData = new FormData(e.target as HTMLFormElement) + const to = formData.get('address') as `0x${string}` + const value = formData.get('value') as string + sendTransaction({ to, value: parseEther(value) }) + } + + const { isLoading: isConfirming, isSuccess: isConfirmed } = + useWaitForTransactionReceipt({ + hash, + }) + + return ( +
+ + + + {hash &&
Transaction Hash: {hash}
} + {isConfirming &&
Waiting for confirmation...
} + {isConfirmed &&
Transaction confirmed.
} + {error && ( +
Error: {(error as BaseError).shortMessage || error.message}
+ )} +
+ ) +} +``` + +```tsx [config.ts] +import { http, createConfig } from 'wagmi' +import { base, mainnet, optimism } from 'wagmi/chains' +import { injected, metaMask, safe, walletConnect } from 'wagmi/connectors' + +const projectId = '' + +export const config = createConfig({ + chains: [mainnet, base], + connectors: [ + injected(), + walletConnect({ projectId }), + metaMask(), + safe(), + ], + transports: { + [mainnet.id]: http(), + [base.id]: http(), + }, +}) +``` + +::: + +[See the Example.](#example) diff --git a/wagmi-project/site/react/guides/ssr.md b/wagmi-project/site/react/guides/ssr.md new file mode 100644 index 0000000000..131be1a2b7 --- /dev/null +++ b/wagmi-project/site/react/guides/ssr.md @@ -0,0 +1,168 @@ +--- +outline: deep +--- + +# SSR + +Wagmi uses client-only external stores (such as `localStorage` and `mipd`) to show the user the most relevant data as quickly as possible on first render. + +However, the caveat of using these external client stores is that frameworks which incorporate SSR (such as Next.js) will throw hydration warnings on the client when it identifies mismatches between the server-rendered HTML and the client-rendered HTML. + +To stop this from happening, you can toggle on the [`ssr`](/react/api/createConfig#ssr) property in the Wagmi Config. + +```tsx +import { createConfig, http } from 'wagmi' +import { mainnet, sepolia } from 'wagmi/chains' + +const config = createConfig({ // [!code focus:99] + chains: [mainnet, sepolia], + ssr: true, // [!code ++] + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +``` + +Turning on the `ssr` property means that content from the external stores will be hydrated on the client after the initial mount. + +## Persistence using Cookies + +As a result of turning on the `ssr` property, external persistent stores like `localStorage` will be hydrated on the client **after the initial mount**. + +This means that you will still see a flash of "empty" data on the client (e.g. a `"disconnected"` account instead of a `"reconnecting"` account, or an empty address instead of the last connected address) until after the first mount, when the store hydrates. + +In order to persist data between the server and the client, you can use cookies. + +### 1. Set up cookie storage + +First, we will set up cookie storage in the Wagmi Config. + +```tsx +import { + createConfig, + http, + cookieStorage, // [!code ++] + createStorage // [!code ++] +} from 'wagmi' +import { mainnet, sepolia } from 'wagmi/chains' + +export function getConfig() { + return createConfig({ + chains: [mainnet, sepolia], + ssr: true, + storage: createStorage({ // [!code ++] + storage: cookieStorage, // [!code ++] + }), // [!code ++] + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, + }) +} +``` + +### 2. Hydrate the cookie + +Next, we will need to add some mechanisms to hydrate the stored cookie in Wagmi. + +#### Next.js App Directory + +In our `app/layout.tsx` file (a [Server Component](https://nextjs.org/docs/app/building-your-application/rendering/server-components)), we will need to extract the cookie from the `headers` function and pass it to [`cookieToInitialState`](/react/api/utilities/cookieToInitialState). + +We will need to pass this result to the [`initialState` property](/react/api/WagmiProvider#initialstate) of the `WagmiProvider`. The `WagmiProvider` **must** be in a Client Component tagged with `"use client"` (see `app/providers.tsx` tab). + +::: code-group +```tsx [app/layout.tsx] +import { type ReactNode } from 'react' +import { headers } from 'next/headers' // [!code ++] +import { cookieToInitialState } from 'wagmi' // [!code ++] + +import { getConfig } from './config' +import { Providers } from './providers' + +export default async function Layout({ children }: { children: ReactNode }) { + const initialState = cookieToInitialState( // [!code ++] + getConfig(), // [!code ++] + (await headers()).get('cookie') // [!code ++] + ) // [!code ++] + return ( + + + // [!code --] + // [!code ++] + {children} + + + + ) +} + +``` + +```tsx [app/providers.tsx] +'use client' + +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { type ReactNode, useState } from 'react' +import { type State, WagmiProvider } from 'wagmi' + +import { getConfig } from './config' + +type Props = { + children: ReactNode, + initialState: State | undefined, // [!code ++] +} + +export function Providers({ children }: Props) { // [!code --] +export function Providers({ children, initialState }: Props) { // [!code ++] + const [config] = useState(() => getConfig()) + const [queryClient] = useState(() => new QueryClient()) + + return ( + // [!code --] + // [!code ++] + + {children} + + + ) +} + +``` + +```tsx [app/config.ts] +import { + createConfig, + http, + cookieStorage, + createStorage +} from 'wagmi' +import { mainnet, sepolia } from 'wagmi/chains' + +export function getConfig() { + return createConfig({ + chains: [mainnet, sepolia], + ssr: true, + storage: createStorage({ // [!code ++] + storage: cookieStorage, // [!code ++] + }), // [!code ++] + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, + }) +} +``` +::: + +#### Next.js Pages Directory + +Would you like to contribute this content? Feel free to [open a Pull Request](https://github.com/wevm/wagmi/pulls)! + + +#### Vanilla SSR + +Would you like to contribute this content? Feel free to [open a Pull Request](https://github.com/wevm/wagmi/pulls)! + + diff --git a/wagmi-project/site/react/guides/tanstack-query.md b/wagmi-project/site/react/guides/tanstack-query.md new file mode 100644 index 0000000000..e491695d71 --- /dev/null +++ b/wagmi-project/site/react/guides/tanstack-query.md @@ -0,0 +1,403 @@ +# TanStack Query + +Wagmi Hooks are not only a wrapper around the core [Wagmi Actions](/core/api/actions), but they also utilize [TanStack Query](https://tanstack.com/query/v5) to enable trivial and intuitive fetching, caching, synchronizing, and updating of asynchronous data in your React applications. + +Without an asynchronous data fetching abstraction, you would need to handle all the negative side-effects that comes as a result, such as: representing finite states (loading, error, success), handling race conditions, caching against a deterministic identifier, etc. + +## Queries & Mutations + +Wagmi Hooks represent either a **Query** or a **Mutation**. + +**Queries** are used for fetching data (e.g. fetching a block number, reading from a contract, etc), and are typically invoked on mount by default. All queries are coupled to a unique [Query Key](#query-keys), and can be used for further operations such as refetching, prefetching, or modifying the cached data. + +**Mutations** are used for mutating data (e.g. connecting/disconnecting accounts, writing to a contract, switching chains, etc), and are typically invoked in response to a user interaction. Unlike **Queries**, they are not coupled with a query key. + +## Terms + +- **Query**: An asynchronous data fetching (e.g. read data) operation that is tied against a unique Query Key. +- **Mutation**: An asynchronous mutating (e.g. create/update/delete data or side-effect) operation. +- **Query Key**: A unique identifier that is used to deterministically identify a query. It is typically a tuple of the query name and the query arguments. +- **Stale Data**: Data that is unused or inactive after a certain period of time. +- **Query Fetching**: The process of invoking an async query function. +- **Query Refetching**: The process of refetching **rendered** queries. +- **[Query Invalidation](https://tanstack.com/query/v5/docs/react/guides/query-invalidation)**: The process of marking query data as stale (e.g. inactive/unused), and refetching **rendered** queries. +- **[Query Prefetching](https://tanstack.com/query/v5/docs/react/guides/prefetching)**: The process of prefetching queries and seeding the cache. + +## Persistence via External Stores + +By default, TanStack Query persists all query data in-memory. This means that if you refresh the page, all in-memory query data will be lost. + +If you want to persist query data to an external storage, you can utilize TanStack Query's [`createSyncStoragePersister`](https://tanstack.com/query/v5/docs/react/plugins/createSyncStoragePersister) or [`createAsyncStoragePersister`](https://tanstack.com/query/v5/docs/react/plugins/createAsyncStoragePersister) to plug external storage like `localStorage`, `sessionStorage`, [IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API) or [`AsyncStorage`](https://reactnative.dev/docs/asyncstorage) (React Native). + +### Sync Storage + +Below is an example of how to set up Wagmi + TanStack Query with sync external storage like `localStorage` or `sessionStorage`. + +#### Install + +::: code-group +```bash [pnpm] +pnpm i @tanstack/query-sync-storage-persister @tanstack/react-query-persist-client +``` + +```bash [npm] +npm i @tanstack/query-sync-storage-persister @tanstack/react-query-persist-client +``` + +```bash [yarn] +yarn add @tanstack/query-sync-storage-persister @tanstack/react-query-persist-client +``` + +```bash [bun] +bun i @tanstack/query-sync-storage-persister @tanstack/react-query-persist-client +``` +::: + +#### Usage + +```tsx +// 1. Import modules. // [!code hl] +import { createSyncStoragePersister } from '@tanstack/query-sync-storage-persister' // [!code hl] +import { QueryClient } from '@tanstack/react-query' // [!code hl] +import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client' // [!code hl] +import { WagmiProvider, deserialize, serialize } from 'wagmi' // [!code hl] + +// 2. Create a new Query Client with a default `gcTime`. // [!code hl] +const queryClient = new QueryClient({ // [!code hl] + defaultOptions: { // [!code hl] + queries: { // [!code hl] + gcTime: 1_000 * 60 * 60 * 24, // 24 hours // [!code hl] + }, // [!code hl] + }, // [!code hl] +}) // [!code hl] + +// 3. Set up the persister. // [!code hl] +const persister = createSyncStoragePersister({ // [!code hl] + serialize, // [!code hl] + storage: window.localStorage, // [!code hl] + deserialize, // [!code hl] +}) // [!code hl] + +function App() { + return ( + + {/* 4. Wrap app in PersistQueryClientProvider */} // [!code hl] + // [!code hl] + {/* ... */} + // [!code hl] + + ) +} +``` + +Read more about [Sync Storage Persistence](https://tanstack.com/query/v5/docs/react/plugins/createSyncStoragePersister). + +### Async Storage + +Below is an example of how to set up Wagmi + TanStack Query with async external storage like [`IndexedDB`](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API) or [`AsyncStorage`](https://reactnative.dev/docs/asyncstorage). + +#### Install + +::: code-group +```bash [pnpm] +pnpm i @tanstack/query-async-storage-persister @tanstack/react-query-persist-client +``` + +```bash [npm] +npm i @tanstack/query-async-storage-persister @tanstack/react-query-persist-client +``` + +```bash [yarn] +yarn add @tanstack/query-async-storage-persister @tanstack/react-query-persist-client +``` + +```bash [bun] +bun i @tanstack/query-async-storage-persister @tanstack/react-query-persist-client +``` +::: + +#### Usage + +```tsx +// 1. Import modules. // [!code hl] +import AsyncStorage from '@react-native-async-storage/async-storage' // [!code hl] +import { createAsyncStoragePersister } from '@tanstack/query-async-storage-persister' // [!code hl] +import { QueryClient } from '@tanstack/react-query' // [!code hl] +import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client' // [!code hl] +import { WagmiProvider, deserialize, serialize } from 'wagmi' // [!code hl] + +// 2. Create a new Query Client with a default `gcTime`. // [!code hl] +const queryClient = new QueryClient({ // [!code hl] + defaultOptions: { // [!code hl] + queries: { // [!code hl] + gcTime: 1_000 * 60 * 60 * 24, // 24 hours // [!code hl] + }, // [!code hl] + }, // [!code hl] +}) // [!code hl] + +// 3. Set up the persister. // [!code hl] +const persister = createAsyncStoragePersister({ // [!code hl] + serialize, // [!code hl] + storage: AsyncStorage, // [!code hl] + deserialize, // [!code hl] +}) // [!code hl] + +function App() { + return ( + + {/* 4. Wrap app in PersistQueryClientProvider */} // [!code hl] + // [!code hl] + {/* ... */} + // [!code hl] + + ) +} +``` + +Read more about [Async Storage Persistence](https://tanstack.com/query/v5/docs/react/plugins/createAsyncStoragePersister). + +## Query Keys + +Query Keys are typically used to perform advanced operations on the query such as: invalidation, refetching, prefetching, etc. + +Wagmi exports Query Keys for every Hook, and they can be retrieved via the [Hook (React)](#hook-react) or via an [Import (Vanilla JS)](#import-vanilla-js). + +Read more about **Query Keys** on the [TanStack Query docs.](https://tanstack.com/query/v5/docs/react/guides/query-keys) + +### Hook (React) + +Each Hook returns a `queryKey` value. You would use this approach when you want to utilize the query key in a React component as it handles reactivity for you, unlike the [Import](#import-vanilla-js) method below. + +```ts +import { useBlock } from 'wagmi' // [!code hl] + +function App() { + const { queryKey } = useBlock() // [!code hl] +} +``` + +### Import (Vanilla JS) + +Each Hook has a corresponding `getQueryOptions` function that returns a query key. You would use this method when you want to utilize the query key outside of a React component in a Vanilla JS context, like in a utility function. + +```ts +import { getBlockQueryOptions } from 'wagmi/query' // [!code hl] +import { config } from './config' + +function perform() { + const { queryKey } = getBlockQueryOptions(config, { // [!code hl] + chainId: config.state.chainId // [!code hl] + }) // [!code hl] +} +``` + +::: warning + +The caveat of this method is that it does not handle reactivity for you (e.g. active account/chain changes, argument changes, etc). You would need to handle this yourself by explicitly passing through the arguments to `getQueryOptions`. + +::: + +## Invalidating Queries + +Invalidating a query is the process of marking the query data as stale (e.g. inactive/unused), and refetching the queries that are already rendered. + +Read more about **Invalidating Queries** on the [TanStack Query docs.](https://tanstack.com/query/v5/docs/react/guides/query-invalidation) + +#### Example: Watching a Users' Balance + +You may want to "watch" a users' balance, and invalidate the balance after each incoming block. We can invoke `invalidateQueries` inside a `useEffect` with the block number as it's only dependency – this will refetch all rendered balance queries when the `blockNumber` changes. + +```tsx +import { useQueryClient } from '@tanstack/react-query' +import { useEffect } from 'react' +import { useBlockNumber, useBalance } from 'wagmi' + +function App() { + const queryClient = useQueryClient() + const { data: blockNumber } = useBlockNumber({ watch: true }) // [!code hl] + const { data: balance, queryKey } = useBalance() // [!code hl] + + useEffect(() => { // [!code hl] + queryClient.invalidateQueries({ queryKey }) // [!code hl] + }, [blockNumber]) // [!code hl] + + return
{balance}
+} +``` + +#### Example: After User Interaction + +Maybe you want to invalidate a users' balance after some interaction. This would mark the balance as stale, and consequently refetch all rendered balance queries. + +```tsx +import { useBalance } from 'wagmi' + +function App() { + // 1. Extract `queryKey` from the useBalance Hook. // [!code hl] + const { queryKey } = useBalance() // [!code hl] + + return ( + + ) +} + +function Example() { + // 3. Other `useBalance` Hooks in your rendered React tree will be refetched! // [!code hl] + const { data: balance } = useBalance() // [!code hl] + + return
{balance}
+} +``` + +## Fetching Queries + +Fetching a query is the process of invoking the query function to retrieve data. If the query exists and the data is not invalidated or older than a given `staleTime`, then the data from the cache will be returned. Otherwise, the query will fetch for the latest data. + +::: code-group +```tsx [example.tsx] +import { getBlockQueryOptions } from 'wagmi' +import { queryClient } from './app' +import { config } from './config' + +export async function fetchBlockData() { + return queryClient.fetchQuery( // [!code hl] + getBlockQueryOptions(config, { // [!code hl] + chainId: config.state.chainId, // [!code hl] + } // [!code hl] + )) // [!code hl] +} +``` +<<< @/snippets/react/app.tsx[app.tsx] +<<< @/snippets/react/config.ts[config.ts] +::: + +## Retrieving & Updating Query Data + +You can retrieve and update query data imperatively with `getQueryData` and `setQueryData`. This is useful for scenarios where you want to retrieve or update a query outside of a React component. + +Note that these functions do not invalidate or refetch queries. + +::: code-group +```tsx [example.tsx] +import { getBlockQueryOptions } from 'wagmi' +import type { Block } from 'viem' +import { queryClient } from './app' +import { config } from './config' + +export function getPendingBlockData() { + return queryClient.getQueryData( // [!code hl] + getBlockQueryOptions(config, { // [!code hl] + chainId: config.state.chainId, // [!code hl] + tag: 'pending' // [!code hl] + } // [!code hl] + )) // [!code hl] +} + +export function setPendingBlockData(data: Block) { + return queryClient.setQueryData( // [!code hl] + getBlockQueryOptions(config, { // [!code hl] + chainId: config.state.chainId, // [!code hl] + tag: 'pending' // [!code hl] + }, // [!code hl] + data // [!code hl] + )) // [!code hl] +} +``` +<<< @/snippets/react/app.tsx[app.tsx] +<<< @/snippets/react/config.ts[config.ts] +::: + +## Prefetching Queries + +Prefetching a query is the process of fetching the data ahead of time and seeding the cache with the returned data. This is useful for scenarios where you want to fetch data before the user navigates to a page, or fetching data on the server to be reused on client hydration. + +Read more about **Prefetching Queries** on the [TanStack Query docs.](https://tanstack.com/query/v5/docs/react/guides/prefetching) + +#### Example: Prefetching in Event Handler + +```tsx +import { Link } from 'next/link' +import { getBlockQueryOptions } from 'wagmi' + +function App() { + const config = useConfig() + const chainId = useChainId() + + // 1. Set up a function to prefetch the block data. // [!code hl] + const prefetch = () => // [!code hl] + queryClient.prefetchQuery(getBlockQueryOptions(config, { chainId })) // [!code hl] + + + return ( + + Block details + + ) +} +``` + +## SSR + +It is possible to utilize TanStack Query's SSR strategies with Wagmi Hooks & Query Keys. Check out the [Server Rendering & Hydration](https://tanstack.com/query/v5/docs/react/guides/ssr) & [Advanced Server Rendering](https://tanstack.com/query/v5/docs/react/guides/advanced-ssr) guides. + +## Devtools + +TanStack Query includes dedicated [Devtools](https://tanstack.com/query/latest/docs/framework/react/devtools) that assist in visualizing and debugging your queries, their cache states, and much more. You will have to pass a custom `queryKeyFn` to your `QueryClient` for Devtools to correctly serialize BigInt values for display. Alternatively, You can use the `hashFn` from `@wagmi/core/query`, which already handles this serialization. + +#### Install + +::: code-group +```bash [pnpm] +pnpm i @tanstack/react-query-devtools +``` + +```bash [npm] +npm i @tanstack/react-query-devtools +``` + +```bash [yarn] +yarn add @tanstack/react-query-devtools +``` + +```bash [bun] +bun i @tanstack/react-query-devtools +``` +::: + +#### Usage + +```tsx +import { + QueryClient, + QueryClientProvider, +} from "@tanstack/react-query"; +import { ReactQueryDevtools } from "@tanstack/react-query-devtools"; // [!code hl] +import { hashFn } from "@wagmi/core/query"; // [!code hl] + +const queryClient = new QueryClient({ + defaultOptions: { // [!code hl] + queries: { // [!code hl] + queryKeyHashFn: hashFn, // [!code hl] + }, // [!code hl] + }, // [!code hl] +}); +``` diff --git a/wagmi-project/site/react/guides/testing.md b/wagmi-project/site/react/guides/testing.md new file mode 100644 index 0000000000..fd198fa058 --- /dev/null +++ b/wagmi-project/site/react/guides/testing.md @@ -0,0 +1,2 @@ +# Testing + diff --git a/wagmi-project/site/react/guides/viem.md b/wagmi-project/site/react/guides/viem.md new file mode 100644 index 0000000000..6539b3fe61 --- /dev/null +++ b/wagmi-project/site/react/guides/viem.md @@ -0,0 +1,150 @@ +# Viem + +[Viem](https://viem.sh) is a low-level TypeScript Interface for Ethereum that enables developers to interact with the Ethereum blockchain, including: JSON-RPC API abstractions, Smart Contract interaction, wallet & signing implementations, coding/parsing utilities and more. + +**Wagmi Core** is essentially a wrapper over **Viem** that provides multi-chain functionality via [Wagmi Config](/react/api/createConfig) and automatic account management via [Connectors](/react/api/connectors). + +## Leveraging Viem Actions + +All of the core [Wagmi Hooks](/react/api/actions) are friendly wrappers around [Viem Actions](https://viem.sh/docs/actions/public/introduction.html) that inject a multi-chain and connector aware [Wagmi Config](/react/api/createConfig). + +There may be cases where you might want to dig deeper and utilize Viem Actions directly (maybe a Hook doesn't exist in Wagmi yet). In these cases, you can create your own custom Wagmi Hook by importing Viem Actions directly via `viem/actions` and plugging in a Viem Client returned by the [`useClient` Hook](/react/api/hooks/useClient). + +The example below demonstrates two different ways to utilize Viem Actions: + +1. **Tree-shakable Actions (recommended):** Uses `useClient` (for public actions) and `useConnectorClient` (for wallet actions). +2. **Client Actions:** Uses `usePublicClient` (for public actions) and `useWalletClient` (for wallet actions). + +::: tip + +It is highly recommended to use the **tree-shakable** method to ensure that you are only pulling modules you use, and keep your bundle size low. + +::: + +::: code-group + +```tsx [Tree-shakable Actions] +// 1. Import modules. +import { useMutation, useQuery } from '@tanstack/react-query' +import { http, createConfig, useClient, useConnectorClient } from 'wagmi' +import { base, mainnet, optimism, zora } from 'wagmi/chains' +import { getLogs, watchAsset } from 'viem/actions' + +// 2. Set up a Wagmi Config +export const config = createConfig({ + chains: [base, mainnet, optimism, zora], + transports: { + [base.id]: http(), + [mainnet.id]: http(), + [optimism.id]: http(), + [zora.id]: http(), + }, +}) + +function Example() { + // 3. Extract a Viem Client for the current active chain. // [!code hl] + const publicClient = useClient({ config }) // [!code hl] + + // 4. Create a "custom" Query Hook that utilizes the Client. // [!code hl] + const { data: logs } = useQuery({ // [!code hl] + queryKey: ['logs', publicClient.uid], // [!code hl] + queryFn: () => getLogs(publicClient, /* ... */) // [!code hl] + }) // [!code hl] + + // 5. Extract a Viem Client for the current active chain & account. // [!code hl] + const { data: walletClient } = useConnectorClient({ config }) // [!code hl] + + // 6. Create a "custom" Mutation Hook that utilizes the Client. // [!code hl] + const { mutate } = useMutation({ // [!code hl] + mutationFn: (asset) => watchAsset(walletClient, asset) // [!code hl] + }) // [!code hl] + + return ( +
+ {/* ... */} +
+ ) +} +``` + +```tsx [Client Actions] +// 1. Import modules. +import { useMutation, useQuery } from '@tanstack/react-query' +import { http, createConfig, useClient, useConnectorClient } from 'wagmi' +import { base, mainnet, optimism, zora } from 'wagmi/chains' + +// 2. Set up a Wagmi Config +export const config = createConfig({ + chains: [base, mainnet, optimism, zora], + transports: { + [base.id]: http(), + [mainnet.id]: http(), + [optimism.id]: http(), + [zora.id]: http(), + }, +}) + +function Example() { + // 3. Extract a Viem Client for the current active chain. // [!code hl] + const publicClient = useClient({ config }) // [!code hl] + + // 4. Create a "custom" Query Hook that utilizes the Client. // [!code hl] + const { data: logs } = useQuery({ // [!code hl] + queryKey: ['logs', publicClient.uid], // [!code hl] + queryFn: () => publicClient.getLogs(/* ... */) // [!code hl] + }) // [!code hl] + + // 5. Extract a Viem Client for the current active chain & account. // [!code hl] + const { data: walletClient } = useConnectorClient({ config }) // [!code hl] + + // 6. Create a "custom" Mutation Hook that utilizes the Client. // [!code hl] + const { mutate } = useMutation({ // [!code hl] + mutationFn: (asset) => walletClient.watchAsset(asset) // [!code hl] + }) // [!code hl] + + return ( +
+ {/* ... */} +
+ ) +} +``` + +::: + +## Private Key & Mnemonic Accounts + +It is possible to utilize Viem's [Private Key & Mnemonic Accounts](https://viem.sh/docs/accounts/local.html) with Wagmi by explicitly passing through the account via the `account` argument on Wagmi Actions. + +```tsx +import { http, createConfig, useSendTransaction } from 'wagmi' +import { base, mainnet, optimism, zora } from 'wagmi/chains' +import { parseEther } from 'viem' +import { privateKeyToAccount } from 'viem/accounts' + +export const config = createConfig({ + chains: [base, mainnet, optimism, zora], + transports: { + [base.id]: http(), + [mainnet.id]: http(), + [optimism.id]: http(), + [zora.id]: http(), + }, +}) + +const account = privateKeyToAccount('0x...') // [!code hl] + +function Example() { + const { data: hash } = useSendTransaction({ + account, // [!code hl] + to: '0xa5cc3c03994DB5b0d9A5eEdD10CabaB0813678AC', + value: parseEther('0.001') + }) +} +``` + +::: info + +Wagmi currently does not support hoisting Private Key & Mnemonic Accounts to the top-level Wagmi Config – meaning you have to explicitly pass through the account to every Action. If you feel like this is a feature that should be added, please [open an discussion](https://github.com/wevm/wagmi/discussions/new?category=ideas). + +::: diff --git a/wagmi-project/site/react/guides/write-to-contract.md b/wagmi-project/site/react/guides/write-to-contract.md new file mode 100644 index 0000000000..65914ae981 --- /dev/null +++ b/wagmi-project/site/react/guides/write-to-contract.md @@ -0,0 +1,438 @@ +# Write to Contract + +The [`useWriteContract` Hook](/react/api/hooks/useWriteContract) allows you to mutate data on a smart contract, from a `payable` or `nonpayable` (write) function. These types of functions require gas to be executed, hence a transaction is broadcasted in order to change the state. + +In the guide below, we will teach you how to implement a "Mint NFT" form that takes in a dynamic argument (token ID) using Wagmi. The example below builds on the [Connect Wallet guide](/react/guides/connect-wallet) and uses the [useWriteContract](/react/api/hooks/useWriteContract) & [useWaitForTransaction](/react/api/hooks/useWaitForTransactionReceipt) hooks. + +If you have already completed the [Sending Transactions guide](/react/guides/send-transaction), this guide will look very similar! That's because writing to a contract internally broadcasts & sends a transaction. + +## Example + +Feel free to check out the example before moving on: + + + +## Steps + +### 1. Connect Wallet + +Follow the [Connect Wallet guide](/react/guides/connect-wallet) guide to get this set up. + +### 2. Create a new component + +Create your `MintNFT` component that will contain the Mint NFT logic. + +::: code-group + +```tsx [mint-nft.tsx] +import * as React from 'react' + +export function MintNFT() { + return ( +
+ + +
+ ) +} +``` + +::: + +### 3. Add a form handler + +Next, we will need to add a handler to the form that will send the transaction when the user hits "Mint". This will be a basic handler in this step. + +::: code-group + +```tsx [mint-nft.tsx] +import * as React from 'react' + +export function MintNFT() { + async function submit(e: React.FormEvent) { // [!code ++] + e.preventDefault() // [!code ++] + const formData = new FormData(e.target as HTMLFormElement) // [!code ++] + const tokenId = formData.get('tokenId') as string // [!code ++] + } // [!code ++] + + return ( +
// [!code --] + // [!code ++] + + +
+ ) +} +``` + +::: + +### 4. Hook up the `useWriteContract` Hook + +Now that we have the form handler, we can hook up the [`useWriteContract` Hook](/react/api/hooks/useWriteContract) to send the transaction. + +::: code-group + +```tsx [mint-nft.tsx] +import * as React from 'react' +import { useWriteContract } from 'wagmi' // [!code ++] +import { abi } from './abi' // [!code ++] + +export function MintNFT() { + const { data: hash, writeContract } = useWriteContract() // [!code ++] + + async function submit(e: React.FormEvent) { + e.preventDefault() + const formData = new FormData(e.target as HTMLFormElement) + const tokenId = formData.get('tokenId') as string + writeContract({ // [!code ++] + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', // [!code ++] + abi, // [!code ++] + functionName: 'mint', // [!code ++] + args: [BigInt(tokenId)], // [!code ++] + }) // [!code ++] + } + + return ( +
+ + + {hash &&
Transaction Hash: {hash}
} // [!code ++] +
+ ) +} +``` + +```ts [abi.ts] +export const abi = [ + { + name: 'mint', + type: 'function', + stateMutability: 'nonpayable', + inputs: [{ internalType: 'uint32', name: 'tokenId', type: 'uint32' }], + outputs: [], + }, +] as const +``` + +::: + +### 5. Add loading state (optional) + +We can optionally add a loading state to the "Mint" button while we are waiting confirmation from the user's wallet. + +::: code-group + +```tsx [mint-nft.tsx] +import * as React from 'react' +import { useWriteContract } from 'wagmi' +import { abi } from './abi' + +export function MintNFT() { + const { + data: hash, + isPending, // [!code ++] + writeContract + } = useWriteContract() + + async function submit(e: React.FormEvent) { + e.preventDefault() + const formData = new FormData(e.target as HTMLFormElement) + const tokenId = formData.get('tokenId') as string + writeContract({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi, + functionName: 'mint', + args: [BigInt(tokenId)], + }) + } + + return ( +
+ + + {hash &&
Transaction Hash: {hash}
} +
+ ) +} +``` + +```ts [abi.ts] +export const abi = [ + { + name: 'mint', + type: 'function', + stateMutability: 'nonpayable', + inputs: [{ internalType: 'uint32', name: 'tokenId', type: 'uint32' }], + outputs: [], + }, +] as const +``` + +::: + +### 6. Wait for transaction receipt (optional) + +We can also display the transaction confirmation status to the user by using the [`useWaitForTransactionReceipt` Hook](/react/api/hooks/useWaitForTransactionReceipt). + +::: code-group + +```tsx [mint-nft.tsx] +import * as React from 'react' +import { + useWaitForTransactionReceipt, // [!code ++] + useWriteContract +} from 'wagmi' +import { abi } from './abi' + +export function MintNFT() { + const { + data: hash, + isPending, + writeContract + } = useWriteContract() + + async function submit(e: React.FormEvent) { + e.preventDefault() + const formData = new FormData(e.target as HTMLFormElement) + const tokenId = formData.get('tokenId') as string + writeContract({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi, + functionName: 'mint', + args: [BigInt(tokenId)], + }) + } + + const { isLoading: isConfirming, isSuccess: isConfirmed } = // [!code ++] + useWaitForTransactionReceipt({ // [!code ++] + hash, // [!code ++] + }) // [!code ++] + + return ( +
+ + + {hash &&
Transaction Hash: {hash}
} + {isConfirming &&
Waiting for confirmation...
} // [!code ++] + {isConfirmed &&
Transaction confirmed.
} // [!code ++] +
+ ) +} +``` + +```ts [abi.ts] +export const abi = [ + { + name: 'mint', + type: 'function', + stateMutability: 'nonpayable', + inputs: [{ internalType: 'uint32', name: 'tokenId', type: 'uint32' }], + outputs: [], + }, +] as const +``` + +::: + +### 7. Handle errors (optional) + +If the user rejects the transaction, or the contract reverts, we can display an error message to the user. + +::: code-group + +```tsx [mint-nft.tsx] +import * as React from 'react' +import { + type BaseError, // [!code ++] + useWaitForTransactionReceipt, + useWriteContract +} from 'wagmi' +import { abi } from './abi' + +export function MintNFT() { + const { + data: hash, + error, // [!code ++] + isPending, + writeContract + } = useWriteContract() + + async function submit(e: React.FormEvent) { + e.preventDefault() + const formData = new FormData(e.target as HTMLFormElement) + const tokenId = formData.get('tokenId') as string + writeContract({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi, + functionName: 'mint', + args: [BigInt(tokenId)], + }) + } + + const { isLoading: isConfirming, isSuccess: isConfirmed } = + useWaitForTransactionReceipt({ + hash, + }) + + return ( +
+ + + {hash &&
Transaction Hash: {hash}
} + {isConfirming &&
Waiting for confirmation...
} + {isConfirmed &&
Transaction confirmed.
} + {error && ( // [!code ++] +
Error: {(error as BaseError).shortMessage || error.message}
// [!code ++] + )} // [!code ++] +
+ ) +} +``` + +```ts [abi.ts] +export const abi = [ + { + name: 'mint', + type: 'function', + stateMutability: 'nonpayable', + inputs: [{ internalType: 'uint32', name: 'tokenId', type: 'uint32' }], + outputs: [], + }, +] as const +``` + +::: + +### 8. Wire it up! + +Finally, we can wire up our Mint NFT component to our application's entrypoint. + +::: code-group + +```tsx [app.tsx] +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { WagmiProvider, useAccount } from 'wagmi' +import { config } from './config' +import { MintNft } from './mint-nft' // [!code ++] + +const queryClient = new QueryClient() + +function App() { + return ( + + + // [!code ++] + + + ) +} +``` + +```tsx [mint-nft.tsx] +import * as React from 'react' +import { + type BaseError, + useWaitForTransactionReceipt, + useWriteContract +} from 'wagmi' +import { abi } from './abi' + +export function MintNFT() { + const { + data: hash, + error, + isPending, + writeContract + } = useWriteContract() + + async function submit(e: React.FormEvent) { + e.preventDefault() + const formData = new FormData(e.target as HTMLFormElement) + const tokenId = formData.get('tokenId') as string + writeContract({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi, + functionName: 'mint', + args: [BigInt(tokenId)], + }) + } + + const { isLoading: isConfirming, isSuccess: isConfirmed } = + useWaitForTransactionReceipt({ + hash, + }) + + return ( +
+ + + {hash &&
Transaction Hash: {hash}
} + {isConfirming &&
Waiting for confirmation...
} + {isConfirmed &&
Transaction confirmed.
} + {error && ( +
Error: {(error as BaseError).shortMessage || error.message}
+ )} +
+ ) +} +``` + +```ts [abi.ts] +export const abi = [ + { + name: 'mint', + type: 'function', + stateMutability: 'nonpayable', + inputs: [{ internalType: 'uint32', name: 'tokenId', type: 'uint32' }], + outputs: [], + }, +] as const +``` + +```tsx [config.ts] +import { http, createConfig } from 'wagmi' +import { base, mainnet, optimism } from 'wagmi/chains' +import { injected, metaMask, safe, walletConnect } from 'wagmi/connectors' + +const projectId = '' + +export const config = createConfig({ + chains: [mainnet, base], + connectors: [ + injected(), + walletConnect({ projectId }), + metaMask(), + safe(), + ], + transports: { + [mainnet.id]: http(), + [base.id]: http(), + }, +}) +``` + +::: + +[See the Example.](#example) diff --git a/wagmi-project/site/react/installation.md b/wagmi-project/site/react/installation.md new file mode 100644 index 0000000000..7dd8306796 --- /dev/null +++ b/wagmi-project/site/react/installation.md @@ -0,0 +1,56 @@ + + +# Installation + +Install Wagmi via your package manager, a ` +``` + +Check out the React docs for info on how to use [React without JSX](https://react.dev/reference/react/createElement#creating-an-element-without-jsx). + + diff --git a/wagmi-project/site/react/typescript.md b/wagmi-project/site/react/typescript.md new file mode 100644 index 0000000000..1ed9d4246e --- /dev/null +++ b/wagmi-project/site/react/typescript.md @@ -0,0 +1,302 @@ + + +# TypeScript + +## Requirements + +Wagmi is designed to be as type-safe as possible! Things to keep in mind: + +- Types currently require using TypeScript {{typescriptVersion}}. +- [TypeScript doesn't follow semver](https://www.learningtypescript.com/articles/why-typescript-doesnt-follow-strict-semantic-versioning) and often introduces breaking changes in minor releases. +- Changes to types in this repository are considered non-breaking and are usually released as patch changes (otherwise every type enhancement would be a major version!). +- It is highly recommended that you lock your `wagmi` and `typescript` versions to specific patch releases and upgrade with the expectation that types may be fixed or upgraded between any release. +- The non-type-related public API of Wagmi still follows semver very strictly. + +To ensure everything works correctly, make sure your `tsconfig.json` has [`strict`](https://www.typescriptlang.org/tsconfig#strict) mode set to `true`. + +::: code-group +```json [tsconfig.json] +{ + "compilerOptions": { + "strict": true + } +} +``` +::: + +## Config Types + +By default React Context does not work well with type inference. To support strong type-safety across the React Context boundary, there are two options available: + +- Declaration merging to "register" your `config` globally with TypeScript. +- `config` property to pass your `config` directly to hooks. + +### Declaration Merging + +[Declaration merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html) allows you to "register" your `config` globally with TypeScript. The `Register` type enables Wagmi to infer types in places that wouldn't normally have access to type info via React Context alone. + +To set this up, add the following declaration to your project. Below, we co-locate the declaration merging and the `config` set up. + +```ts +import { createConfig, http } from 'wagmi' +import { mainnet, sepolia } from 'wagmi/chains' + +declare module 'wagmi' { // [!code focus] + interface Register { // [!code focus] + config: typeof config // [!code focus] + } // [!code focus] +} // [!code focus] + +export const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +``` + +Since the `Register` type is global, you only need to add it once in your project. Once set up, you will get strong type-safety across your entire project. For example, query hooks will type `chainId` based on your `config`'s `chains`. + +```ts twoslash +// @errors: 2322 +import { type Config } from 'wagmi' +import { mainnet, sepolia } from 'wagmi/chains' + +declare module 'wagmi' { + interface Register { + config: Config + } +} +// ---cut--- +import { useBlockNumber } from 'wagmi' + +useBlockNumber({ chainId: 123 }) +``` + +You just saved yourself a runtime error and you didn't even need to pass your `config`. šŸŽ‰ + +### Hook `config` Property + +For cases where you have more than one Wagmi `config` or don't want to use the declaration merging approach, you can pass a specific `config` directly to hooks via the `config` property. + +```ts +import { createConfig, http } from 'wagmi' +import { mainnet, optimism } from 'wagmi/chains' + +export const configA = createConfig({ // [!code focus] + chains: [mainnet], // [!code focus] + transports: { // [!code focus] + [mainnet.id]: http(), // [!code focus] + }, // [!code focus] +}) // [!code focus] + +export const configB = createConfig({ // [!code focus] + chains: [optimism], // [!code focus] + transports: { // [!code focus] + [optimism.id]: http(), // [!code focus] + }, // [!code focus] +}) // [!code focus] +``` + +As you expect, `chainId` is inferred correctly for each `config`. + +```ts twoslash +// @errors: 2322 +import { type Config } from 'wagmi' +import { mainnet, optimism } from 'wagmi/chains' + +declare const configA: Config +declare const configB: Config +// ---cut--- +import { useBlockNumber } from 'wagmi' + +useBlockNumber({ chainId: 123, config: configA }) +useBlockNumber({ chainId: 123, config: configB }) +``` + +This approach is more explicit, but works well for advanced use-cases, if you don't want to use React Context or declaration merging, etc. + +## Const-Assert ABIs & Typed Data + +Wagmi can infer types based on [ABIs](https://docs.soliditylang.org/en/latest/abi-spec.html#json) and [EIP-712](https://eips.ethereum.org/EIPS/eip-712) Typed Data definitions, powered by [Viem](https://viem.sh) and [ABIType](https://github.com/wevm/abitype). This achieves full end-to-end type-safety from your contracts to your frontend and enlightened developer experience by autocompleting ABI item names, catching misspellings, inferring argument and return types (including overloads), and more. + +For this to work, you must either [const-assert](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions) ABIs and Typed Data (more info below) or define them inline. For example, `useReadContract`'s `abi` configuration parameter: + +```ts +const { data } = useReadContract({ + abi: […], // <--- defined inline // [!code focus] +}) +``` + +```ts +const abi = […] as const // <--- const assertion // [!code focus] +const { data } = useReadContract({ abi }) +``` + +If type inference isn't working, it's likely you forgot to add a `const` assertion or define the configuration parameter inline. Also, make sure your ABIs, Typed Data definitions, and [TypeScript configuration](#requirements) are valid and set up correctly. + +::: tip +Unfortunately [TypeScript doesn't support importing JSON `as const` yet](https://github.com/microsoft/TypeScript/issues/32063). Check out the [Wagmi CLI](/cli/getting-started) to help with this! It can automatically fetch ABIs from Etherscan and other block explorers, resolve ABIs from your Foundry/Hardhat projects, generate React Hooks, and more. +::: + +Anywhere you see the `abi` or `types` configuration property, you can likely use const-asserted or inline ABIs and Typed Data to get type-safety and inference. These properties are also called out in the docs. + +Here's what [`useReadContract`](/react/api/hooks/useReadContract) looks like with and without a const-asserted `abi` property. + +::: code-group +```ts twoslash [Const-Asserted] +const erc721Abi = [ + { + name: 'balanceOf', + type: 'function', + stateMutability: 'view', + inputs: [{ type: 'address', name: 'owner' }], + outputs: [{ type: 'uint256' }], + }, + { + name: 'isApprovedForAll', + type: 'function', + stateMutability: 'view', + inputs: [ + { type: 'address', name: 'owner' }, + { type: 'address', name: 'operator' }, + ], + outputs: [{ type: 'bool' }], + }, + { + name: 'getApproved', + type: 'function', + stateMutability: 'view', + inputs: [{ type: 'uint256', name: 'tokenId' }], + outputs: [{ type: 'address' }], + }, + { + name: 'ownerOf', + type: 'function', + stateMutability: 'view', + inputs: [{ type: 'uint256', name: 'tokenId' }], + outputs: [{ type: 'address' }], + }, + { + name: 'tokenURI', + type: 'function', + stateMutability: 'pure', + inputs: [{ type: 'uint256', name: 'tokenId' }], + outputs: [{ type: 'string' }], + }, +] as const +// ---cut--- +import { useReadContract } from 'wagmi' + +const { data } = useReadContract({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi: erc721Abi, + functionName: 'balanceOf', + // ^? + + + + args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e'], + // ^? +}) + +data +// ^? +``` +```ts twoslash [Not Const-Asserted] +declare const erc721Abi: { + name: string; + type: string; + stateMutability: string; + inputs: { + type: string; + name: string; + }[]; + outputs: { + type: string; + }[]; +}[] +// ---cut--- +import { useReadContract } from 'wagmi' + +const { data } = useReadContract({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi: erc721Abi, + functionName: 'balanceOf', + // ^? + + + + args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e'], + // ^? +}) + +data +// ^? +``` +::: + +
+
+ +You can prevent runtime errors and be more productive by making sure your ABIs and Typed Data definitions are set up appropriately. šŸŽ‰ + +```ts twoslash +// @errors: 2820 +const erc721Abi = [ + { + name: 'balanceOf', + type: 'function', + stateMutability: 'view', + inputs: [{ type: 'address', name: 'owner' }], + outputs: [{ type: 'uint256' }], + }, + { + name: 'isApprovedForAll', + type: 'function', + stateMutability: 'view', + inputs: [ + { type: 'address', name: 'owner' }, + { type: 'address', name: 'operator' }, + ], + outputs: [{ type: 'bool' }], + }, + { + name: 'getApproved', + type: 'function', + stateMutability: 'view', + inputs: [{ type: 'uint256', name: 'tokenId' }], + outputs: [{ type: 'address' }], + }, + { + name: 'ownerOf', + type: 'function', + stateMutability: 'view', + inputs: [{ type: 'uint256', name: 'tokenId' }], + outputs: [{ type: 'address' }], + }, + { + name: 'tokenURI', + type: 'function', + stateMutability: 'pure', + inputs: [{ type: 'uint256', name: 'tokenId' }], + outputs: [{ type: 'string' }], + }, +] as const +// ---cut--- +import { useReadContract } from 'wagmi' + +useReadContract({ + abi: erc721Abi, + functionName: 'balanecOf', +}) +``` + +## Configure Internal Types + +For advanced use-cases, you may want to configure Wagmi's internal types. Most of Wagmi's types relating to ABIs and EIP-712 Typed Data are powered by [ABIType](https://github.com/wevm/abitype). See the [ABIType docs](https://abitype.dev) for more info on how to configure types. diff --git a/wagmi-project/site/react/why.md b/wagmi-project/site/react/why.md new file mode 100644 index 0000000000..3b4bf2b89b --- /dev/null +++ b/wagmi-project/site/react/why.md @@ -0,0 +1,46 @@ +# Why Wagmi + +## The Problems + +Building Ethereum applications is hard. Apps need to support connecting wallets, multiple chains, signing messages and data, sending transactions, listening for events and state changes, refreshing stale blockchain data, and much more. This is all on top of solving for app-specific use-cases and providing polished user experiences. + +The ecosystem is also continuously evolving, meaning you need to adapt to new improvements or get left behind. App developers should not need to worry about connecting tens of different wallets, the intricacies of multi-chain support, typos accidentally sending an order of magnitude more ETH or calling a misspelled contract function, or accidentally spamming their RPC provider, costing thousands in compute units. + +Wagmi solves all these problems and more — allowing app developers to focus on building high-quality and performant experiences for Ethereum — by focusing on **developer experience**, **performance**, **feature coverage**, and **stability.** + +## Developer Experience + +Wagmi delivers a great developer experience through modular and composable APIs, automatic type safety and inference, and comprehensive documentation. + +It provides developers with intuitive building blocks to build their Ethereum apps. While Wagmi's APIs might seem more verbose at first, it makes Wagmi's modular building blocks extremely flexible. Easy to move around, change, and remove. It also allows developers to better understand Ethereum concepts as well as understand _what_ and _why_ certain properties are being passed through. Learning how to use Wagmi is a great way to learn how to interact with Ethereum in general. + +Wagmi also provides [strongly typed APIs](/react/typescript), allowing consumers to get the best possible experience through [autocomplete](https://twitter.com/awkweb/status/1555678944770367493), [type inference](https://twitter.com/jakemoxey/status/1570244174502588417?s=20), as well as static validation. You often just need to provide an ABI and Wagmi can help you autocomplete your way to success, identify type errors before your users do, drill into blockchain errors [at compile and runtimes](/react/guides/error-handling) with surgical precision, and much more. + +The API documentation is comprehensive and contains usage info for _every_ module in Wagmi. The core team uses a [documentation](https://gist.github.com/zsup/9434452) and [test driven](https://en.wikipedia.org/wiki/Test-driven_development#:~:text=Test%2Ddriven%20development%20(TDD),software%20against%20all%20test%20cases.) development approach to building modules, which leads to predictable and stable APIs. + +## Performance + +Performance is critical for applications on all sizes. Slow page load and interactions can cause users to stop using applications. Wagmi uses and is built by the same team behind [Viem](https://viem.sh), the most performant production-ready Ethereum library. + +End users should not be required to download a module of over 100kB in order to interact with Ethereum. Wagmi is optimized for tree-shaking and dead-code elimination, allowing apps to minimize bundle size for fast page load times. + +Data layer performance is also critical. Slow, unnecessary, and manual data fetching can make apps unusable and cost thousands in RPC compute units. Wagmi supports caching, deduplication, persistence, and much more through [TanStack Query](/react/guides/tanstack-query). + +## Feature Coverage + +Wagmi supports the most popular and commonly-used Ethereum features out of the box with 40+ React Hooks for accounts, wallets, contracts, transactions, signing, ENS, and more. Wagmi also supports just about any wallet out there through official [connectors](/react/api/connectors), [EIP-6963 support](/react/api/createConfig#multiinjectedproviderdiscovery), and [extensible API](/dev/creating-connectors). + +If you need lower-level control, you can always drop down to [Wagmi Core](/core/getting-started) or [Viem](https://viem.sh), which Wagmi uses internally to perform blockchain operations. Wagmi also manages multi-chain support automatically so developers can focus on their applications instead of adding custom code. + +Finally, Wagmi has a [CLI](/cli/getting-started) to manage ABIs as well as a robust ecosystem of third-party libraries, like [ConnectKit](https://docs.family.co/connectkit), [RainbowKit](https://www.rainbowkit.com), [AppKit](https://walletconnect.com/appkit), [Dynamic](https://www.dynamic.xyz), [Privy](https://privy.io), and many more, so you can get started quickly without needing to build everything from scratch. + +## Stability + +Stability is a fundamental principle for Wagmi. Many organizations, large and small, rely heavily on Wagmi and expect it to be entirely stable for their users and applications. + +Wagmi's test suite runs against forked Ethereum nodes to make sure functions work across chains. The test suite also runs type tests against many different versions of peer dependencies, like TypeScript, to ensure compatibility with the latest releases of other popular software. + +Wagmi follows semver so developers can upgrade between versions with confidence. Starting with Wagmi v2, new functionality will be opt-in with old functionality being deprecated alongside the new features. This means upgrading to the latest major versions will not require immediate changes. + +Lastly, the core team works full-time on Wagmi and [related projects](https://github.com/wevm), and is constantly improving Wagmi and keeping it up-to-date with industry trends and changes. + diff --git a/wagmi-project/site/shared/connectors/coinbaseWallet.md b/wagmi-project/site/shared/connectors/coinbaseWallet.md new file mode 100644 index 0000000000..de70807aef --- /dev/null +++ b/wagmi-project/site/shared/connectors/coinbaseWallet.md @@ -0,0 +1,160 @@ + + +# coinbaseWallet + +Connector for the [Coinbase Wallet SDK](https://github.com/coinbase/coinbase-wallet-sdk). + +## Import + +```ts-vue +import { coinbaseWallet } from '{{connectorsPackageName}}' +``` + +## Usage + +```ts-vue +import { createConfig, http } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' +import { coinbaseWallet } from '{{connectorsPackageName}}' // [!code hl] + +export const config = createConfig({ + chains: [mainnet, sepolia], + connectors: [coinbaseWallet()], // [!code hl] + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +``` + +:::warning +Before going to production, it is highly recommended to set an [`appName`](#appname) and [`appLogoUrl`](#applogourl) for your application that can be displayed upon connection to the wallet. +::: + +## Parameters + +```ts-vue +import { type CoinbaseWalletParameters } from '{{connectorsPackageName}}' +``` + +Check out the [Coinbase Wallet SDK docs](https://github.com/coinbase/coinbase-wallet-sdk) for more info. + +### appName + +`string` + +Application name. + +```ts-vue +import { coinbaseWallet } from '{{connectorsPackageName}}' + +const connector = coinbaseWallet({ + appName: 'My Wagmi App', // [!code focus] +}) +``` + +### appLogoUrl + +`string | null | undefined` + +Application logo image URL; favicon is used if unspecified. + +```ts-vue +import { coinbaseWallet } from '{{connectorsPackageName}}' + +const connector = coinbaseWallet({ + appName: 'My Wagmi App', + appLogoUrl: 'https://example.com/myLogoUrl.png', // [!code focus] +}) +``` + +### headlessMode + +`boolean | undefined` + +- Whether or not onboarding overlay popup should be displayed. +- `headlessMode` will be removed in the next major version. Upgrade to [`version: '4'`](#version). + +```ts-vue +import { coinbaseWallet } from '{{connectorsPackageName}}' + +const connector = coinbaseWallet({ + appName: 'My Wagmi App', + headlessMode: false, // [!code focus] +}) +``` + +### preference + +`"all" | "eoaOnly" | "smartWalletOnly"` + +Preference for the type of wallet to display. + +- `'eoaOnly'`: Uses EOA Browser Extension or Mobile Coinbase Wallet. +- `'smartWalletOnly'`: Displays Smart Wallet popup. +- `'all'` (default): Supports both `'eoaOnly'` and `'smartWalletOnly'` based on context. + +```ts-vue +import { coinbaseWallet } from '{{connectorsPackageName}}' + +const connector = coinbaseWallet({ + appName: 'My Wagmi App', + preference: 'smartWalletOnly', // [!code focus] +}) +``` + +::: warning +Passing `preference` as a string is deprecated and will be removed in the next major version. Instead you should use [`preference#options`](#options). +::: + +```ts-vue +import { coinbaseWallet } from '{{connectorsPackageName}}' + +const connector = coinbaseWallet({ + appName: 'My Wagmi App', + preference: { // [!code focus] + options: 'smartWalletOnly' // [!code focus] + }, // [!code focus] +}) +``` + +#### attribution + +`` { auto?: boolean | undefined; dataSuffix?: `0x${string}` | undefined } `` + +This option only applies to Coinbase Smart Wallet. When a valid data suffix is supplied, it is appended to the `initCode` and `executeBatch` calldata. Coinbase Smart Wallet expects a 16 byte hex string. If the data suffix is not a 16 byte hex string, the Smart Wallet will ignore the property. If auto is true, the Smart Wallet will generate a 16 byte hex string from the apps origin. + +#### keysUrl + +`string` + +- The URL for the keys popup. +- By default, `https://keys.coinbase.com/connect` is used for production. Use `https://keys-dev.coinbase.com/connect` for development environments. + +#### options + +`"all" | "eoaOnly" | "smartWalletOnly"` + +Preference for the type of wallet to display. + +- `'eoaOnly'`: Uses EOA Browser Extension or Mobile Coinbase Wallet. +- `'smartWalletOnly'`: Displays Smart Wallet popup. +- `'all'` (default): Supports both `'eoaOnly'` and `'smartWalletOnly'` based on context. + +### version + +- Coinbase Wallet SDK version +- Defaults to `'4'`. If [`headlessMode: true`](#headlessmode), defaults to `'3'`. + +```ts-vue +import { coinbaseWallet } from '{{connectorsPackageName}}' + +const connector = coinbaseWallet({ + appName: 'My Wagmi App', + version: '4', // [!code focus] +}) +``` + diff --git a/wagmi-project/site/shared/connectors/injected.md b/wagmi-project/site/shared/connectors/injected.md new file mode 100644 index 0000000000..36583b4d83 --- /dev/null +++ b/wagmi-project/site/shared/connectors/injected.md @@ -0,0 +1,89 @@ + + +# injected + +Connector for [EIP-1193](https://eips.ethereum.org/EIPS/eip-1193) Ethereum Providers. + +## Import + +```ts-vue +import { injected } from '{{connectorsPackageName}}' +``` + +## Usage + +```ts-vue{3,7} +import { createConfig, http } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' +import { injected } from '{{connectorsPackageName}}' + +export const config = createConfig({ + chains: [mainnet, sepolia], + connectors: [injected()], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +``` + +## Parameters + +```ts-vue +import { type InjectedParameters } from '{{connectorsPackageName}}' +``` + +### shimDisconnect + +`boolean | undefined` + +- MetaMask and other injected providers do not support programmatic disconnect. +- This flag simulates the disconnect behavior by keeping track of connection status in storage. See [GitHub issue](https://github.com/MetaMask/metamask-extension/issues/10353) for more info. +- Defaults to `true`. + +```ts-vue +import { injected } from '{{connectorsPackageName}}' + +const connector = injected({ + shimDisconnect: false, // [!code focus] +}) +``` + +### target + +`TargetId | (TargetMap[TargetId] & { id: string }) | (() => (TargetMap[TargetId] & { id: string }) | undefined) | undefined` + +- [EIP-1193](https://eips.ethereum.org/EIPS/eip-1193) Ethereum Provider to target. +- [EIP-6963](https://eips.ethereum.org/EIPS/eip-6963) supported via `createConfig`'s `multiInjectedProviderDiscovery` property. + +```ts-vue +import { injected } from '{{connectorsPackageName}}' + +const connector = injected({ + target() { // [!code focus] + return { // [!code focus] + id: 'windowProvider', // [!code focus] + name: 'Window Provider', // [!code focus] + provider: window.ethereum, // [!code focus] + } // [!code focus] + }, // [!code focus] +}) +``` + +### unstable_shimAsyncInject + +`boolean | number | undefined` + +Watches for async provider injection via the `ethereum#initialized` event. When `true`, defaults to `1_000` milliseconds. Otherwise, uses a provided value of milliseconds. + +```ts-vue +import { injected } from '{{connectorsPackageName}}' + +const connector = injected({ + unstable_shimAsyncInject: 2_000, // [!code focus] +}) +``` diff --git a/wagmi-project/site/shared/connectors/metaMask.md b/wagmi-project/site/shared/connectors/metaMask.md new file mode 100644 index 0000000000..08a6f4f9cd --- /dev/null +++ b/wagmi-project/site/shared/connectors/metaMask.md @@ -0,0 +1,124 @@ + + +# metaMask + +Connector for [MetaMask SDK](https://github.com/MetaMask/metamask-sdk). + +Check out the [MetaMask SDK docs](https://docs.metamask.io/wallet/connect/metamask-sdk/javascript) for more information. + +## Import + +```ts-vue +import { metaMask } from '{{connectorsPackageName}}' +``` + +## Usage + +```ts-vue{3,7} +import { createConfig, http } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' +import { metaMask } from '{{connectorsPackageName}}' + +export const config = createConfig({ + chains: [mainnet, sepolia], + connectors: [metaMask()], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +``` + +## Parameters + +```ts-vue +import { type MetaMaskParameters } from '{{connectorsPackageName}}' +``` + +Check out the [MetaMask SDK docs](https://docs.metamask.io/wallet/connect/3rd-party-libraries/wagmi/) for more info. A few options are omitted that Wagmi manages internally. + +### dappMetadata + +`DappMetadata | undefined` + +Metadata is used to fill details for the UX on confirmation screens in MetaMask, including the following fields: + +- `name`: `string` - The name of the dapp. +- `url`: `string` - URL of the dapp (defaults to `window.location.origin`). +- `iconUrl`: `string` - URL to the dapp's favicon or icon. + +```ts-vue +import { metaMask } from '{{connectorsPackageName}}' + +const connector = metaMask({ + dappMetadata: { // [!code focus] + name: 'My Wagmi App', // [!code focus] + url: 'https://example.com', // [!code focus] + iconUrl: 'https://example.com/favicon.ico', // [!code focus] + } +}) +``` + +### logging + +`SDKLoggingOptions | undefined` + +Enables SDK-side logging to provide visibility into: + +- RPC methods being called. +- Events received for syncing the chain or active account. +- Raw RPC responses. + +In this context, this is especially useful to observe what calls are made through Wagmi hooks. + +Relevant options: + +```ts +{ + developerMode: boolean, // Enables developer mode logs + sdk: boolean // Enables SDK-specific logs +} +``` + +```ts +import { metaMask } from '{{connectorsPackageName}}' + +const connector = metaMask({ + logging: { developerMode: true, sdk: true } // [!code focus] +}) +``` + +### headless + +`boolean | undefined` + +- Enables headless mode, disabling MetaMask's built-in modal. +- Allows developers to create their own modal, such as for displaying a QR code. + +This is particularly relevant for web-only setups using Wagmi, where developers want complete control over the UI. + +To get the deeplink to display in the QR code, listen to the `display_uri` event. + +The default is `false`. + +```ts-vue +import { metaMask } from '{{connectorsPackageName}}' + +const connector = metaMask({ + headless: true // [!code focus] +}) +``` + +## Advanced + +By default, if the EIP-6963 MetaMask injected provider is detected, this connector will replace it. + +EIP-6963 defines a standard way for dapps to interact with multiple wallets simultaneously by injecting providers into the browser. Wallets that implement this standard can make their presence known to dapps in a consistent and predictable manner. + +When MetaMask SDK detects an EIP-6963-compliant provider (such as MetaMask itself), the connector will automatically replace the default injected provider (like `window.ethereum`) with the one provided by MetaMask SDK. + +See the [`rdns` property](https://wagmi.sh/dev/creating-connectors#properties) for more information. diff --git a/wagmi-project/site/shared/connectors/mock.md b/wagmi-project/site/shared/connectors/mock.md new file mode 100644 index 0000000000..90d87b0b3e --- /dev/null +++ b/wagmi-project/site/shared/connectors/mock.md @@ -0,0 +1,128 @@ + + +# mock + +Connector for mocking Wagmi functionality. + +## Import + +```ts-vue +import { mock } from '{{connectorsPackageName}}' +``` + +## Usage + +```ts-vue{3,8-14} +import { createConfig, http } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' +import { mock } from '{{connectorsPackageName}}' + +export const config = createConfig({ + chains: [mainnet, sepolia], + connectors: [ + mock({ + accounts: [ + '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + '0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC', + ], + }), + ], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +``` + +## Parameters + +```ts-vue +import { type MockParameters } from '{{connectorsPackageName}}' +``` + +### accounts + +`readonly [Address, ...Address[]]` + +Accounts to use with the connector. + +```ts-vue +import { mock } from '{{connectorsPackageName}}' + +const connector = mock({ + accounts: [ // [!code focus] + '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', // [!code focus] + '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', // [!code focus] + '0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC', // [!code focus] + '0x90F79bf6EB2c4f870365E785982E1f101E93b906', // [!code focus] + '0x15d34aaf54267db7d7c367839aaf71a00a2c6a65', // [!code focus] + '0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc', // [!code focus] + '0x976EA74026E726554dB657fA54763abd0C3a0aa9', // [!code focus] + '0x14dC79964da2C08b23698B3D3cc7Ca32193d9955', // [!code focus] + '0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f', // [!code focus] + '0xa0Ee7A142d267C1f36714E4a8F75612F20a79720', // [!code focus] + ], // [!code focus] +}) +``` + +### features + +`{ connectError?: boolean | Error | undefined; reconnect?: boolean | undefined; signMessageError?: boolean | Error | undefined; signTypedDataError?: boolean | Error | undefined; switchChainError?: boolean | Error | undefined; } | undefined` + +Feature flags that change behavior of Wagmi internals. + +```ts-vue +import { mock } from '{{connectorsPackageName}}' +import { UserRejectedRequestError } from 'viem' + +const connector = mock({ + accounts: [ + '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', + '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', + '0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC', + ], + features: { // [!code focus] + connectError: new UserRejectedRequestError(new Error('Failed to connect.')), // [!code focus] + reconnect: false, // [!code focus] + }, // [!code focus] +}) +``` +#### defaultConnected + +`boolean | undefined` + +Whether the connector is connected by default. + +#### connectError + +`boolean | Error | undefined` + +Whether to throw an error when `connector.connect` is called. + +#### reconnect + +`boolean | undefined` + +Enables reconnecting to connector. + +#### signMessageError + +`boolean | Error | undefined` + +Whether to throw an error when `'personal_sign'` is called. + +#### signTypedDataError + +`boolean | Error | undefined` + +Whether to throw an error when `'eth_signTypedData_v4'` is called. + +#### switchChainError + +`boolean | Error | undefined` + +Whether to throw an error when `connector.switchChain` is called. diff --git a/wagmi-project/site/shared/connectors/safe.md b/wagmi-project/site/shared/connectors/safe.md new file mode 100644 index 0000000000..171010214b --- /dev/null +++ b/wagmi-project/site/shared/connectors/safe.md @@ -0,0 +1,77 @@ + + +# safe + +Connector for [Safe Apps SDK](https://github.com/safe-global/safe-apps-sdk). + +## Import + +```ts-vue +import { safe } from '{{connectorsPackageName}}' +``` + +## Usage + +```ts-vue{3,7} +import { createConfig, http } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' +import { safe } from '{{connectorsPackageName}}' + +export const config = createConfig({ + chains: [mainnet, sepolia], + connectors: [safe()], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +``` + +## Parameters + +```ts-vue +import { type SafeParameters } from '{{connectorsPackageName}}' +``` + +Check out the [Safe docs](https://github.com/safe-global/safe-apps-sdk/tree/main/packages/safe-apps-sdk) for more info. +### allowedDomains + +`RegExp[] | undefined` + +```ts-vue +import { safe } from '{{connectorsPackageName}}' + +const connector = safe({ + allowedDomains: [/app.safe.global$/], // [!code focus] +}) +``` + +### debug + +`boolean | undefined` + +```ts-vue +import { safe } from '{{connectorsPackageName}}' + +const connector = safe({ + debug: true, // [!code focus] +}) +``` + +### shimDisconnect + +`boolean | undefined` + +- This flag simulates disconnect behavior by keeping track of connection status in storage. +- Defaults to `false`. + +```ts-vue +import { safe } from '{{connectorsPackageName}}' + +const connector = safe({ + shimDisconnect: true, // [!code focus] +}) +``` diff --git a/wagmi-project/site/shared/connectors/walletConnect.md b/wagmi-project/site/shared/connectors/walletConnect.md new file mode 100644 index 0000000000..48e7fcb950 --- /dev/null +++ b/wagmi-project/site/shared/connectors/walletConnect.md @@ -0,0 +1,215 @@ + + +# walletConnect + +Connector for [WalletConnect](https://walletconnect.com). + +## Import + +```ts-vue +import { walletConnect } from '{{connectorsPackageName}}' +``` + +## Usage + +```ts-vue{3,8-10} +import { createConfig, http } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' +import { walletConnect } from '{{connectorsPackageName}}' + +export const config = createConfig({ + chains: [mainnet, sepolia], + connectors: [ + walletConnect({ + projectId: '3fcc6bba6f1de962d911bb5b5c3dba68', + }), + ], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +``` + +## Parameters + +```ts-vue +import { type WalletConnectParameters } from '{{connectorsPackageName}}' +``` + +Check out the [WalletConnect docs](https://github.com/WalletConnect/walletconnect-monorepo/tree/v2.0/providers/ethereum-provider) for more info. A few options are omitted that Wagmi manages internally. + +### customStoragePrefix + +`string | undefined` + +Custom storage prefix for persisting provider state. + +```ts-vue +import { walletConnect } from '{{connectorsPackageName}}' + +const connector = walletConnect({ + customStoragePrefix: 'wagmi', // [!code focus] + projectId: '3fcc6bba6f1de962d911bb5b5c3dba68', +}) +``` + +### disableProviderPing + +`boolean | undefined` + +```ts-vue +import { walletConnect } from '{{connectorsPackageName}}' + +const connector = walletConnect({ + disableProviderPing: false, // [!code focus] + projectId: '3fcc6bba6f1de962d911bb5b5c3dba68', +}) +``` + +### isNewChainsStale + +`boolean | undefined` + +- If a new chain is added to a previously existing configured connector `chains`, this flag +will determine if that chain should be considered as stale. A stale chain is a chain that +WalletConnect has yet to establish a relationship with (e.g. the user has not approved or +rejected the chain). +- Defaults to `true`. + +```ts-vue +import { walletConnect } from '{{connectorsPackageName}}' + +const connector = walletConnect({ + isNewChainsStale: true, // [!code focus] + projectId: '3fcc6bba6f1de962d911bb5b5c3dba68', +}) +``` + +::: details More info +Preface: Whereas WalletConnect v1 supported dynamic chain switching, WalletConnect v2 requires +the user to pre-approve a set of chains up-front. This comes with consequent UX nuances (see below) when +a user tries to switch to a chain that they have not approved. + +This flag mainly affects the behavior when a wallet does not support dynamic chain authorization +with WalletConnect v2. + +If `true` (default), the new chain will be treated as a stale chain. If the user +has yet to establish a relationship (approved/rejected) with this chain in their WalletConnect +session, the connector will disconnect upon the dapp auto-connecting, and the user will have to +reconnect to the dapp (revalidate the chain) in order to approve the newly added chain. +This is the default behavior to avoid an unexpected error upon switching chains which may +be a confusing user experience (e.g. the user will not know they have to reconnect +unless the dapp handles these types of errors). + +If `false`, the new chain will be treated as a validated chain. This means that if the user +has yet to establish a relationship with the chain in their WalletConnect session, wagmi will successfully +auto-connect the user. This comes with the trade-off that the connector will throw an error +when attempting to switch to the unapproved chain. This may be useful in cases where a dapp constantly +modifies their configured chains, and they do not want to disconnect the user upon +auto-connecting. If the user decides to switch to the unapproved chain, it is important that the +dapp handles this error and prompts the user to reconnect to the dapp in order to approve +the newly added chain. +::: + +### metadata + +`CoreTypes.Metadata | undefined` + +Metadata related to the app requesting the connection. + +```ts-vue +import { walletConnect } from '{{connectorsPackageName}}' + +const connector = walletConnect({ + projectId: '3fcc6bba6f1de962d911bb5b5c3dba68', + metadata: { // [!code focus] + name: 'Example', // [!code focus] + description: 'Example website', // [!code focus] + url: 'https://example.com', // [!code focus] + }, // [!code focus] +}) +``` + +### projectId + +`string` + +WalletConnect Cloud project identifier. You can find your `projectId` on your [WalletConnect dashboard](https://cloud.reown.com/sign-in). + +```ts-vue +import { walletConnect } from '{{connectorsPackageName}}' + +const connector = walletConnect({ + projectId: '3fcc6bba6f1de962d911bb5b5c3dba68', // [!code focus] +}) +``` + +### qrModalOptions + +`QrModalOptions | undefined` + +Options for rendering QR modal. + +```ts-vue +import { walletConnect } from '{{connectorsPackageName}}' + +const connector = walletConnect({ + projectId: '3fcc6bba6f1de962d911bb5b5c3dba68', + qrModalOptions: { // [!code focus] + themeMode: 'dark', // [!code focus] + }, // [!code focus] +}) +``` + +### relayUrl + +`string | undefined` + +- WalletConnect relay URL to use. +- Defaults to `'wss://relay.walletconnect.com'`. + +```ts-vue +import { walletConnect } from '{{connectorsPackageName}}' + +const connector = walletConnect({ + projectId: '3fcc6bba6f1de962d911bb5b5c3dba68', + relayUrl: 'wss://relay.walletconnect.org', // [!code focus] +}) +``` + +### storageOptions + +`KeyValueStorageOptions | undefined` + +```ts-vue +import { walletConnect } from '{{connectorsPackageName}}' + +const connector = walletConnect({ + projectId: '3fcc6bba6f1de962d911bb5b5c3dba68', + storageOptions: {}, // [!code focus] +}) +``` + +### showQrModal + +`boolean | undefined` + +- Whether to show the QR code modal upon calling `connector.connect()`. +- Defaults to `true`. + +```ts-vue +import { walletConnect } from '{{connectorsPackageName}}' + +const connector = walletConnect({ + projectId: '3fcc6bba6f1de962d911bb5b5c3dba68', + showQrModal: true, // [!code focus] +}) +``` + +::: tip +This can be disabled and you can listen for a `'message'` event with payload `{ type: 'display_uri'; data: string }` if you want to render your own QR code. +::: diff --git a/wagmi-project/site/shared/create-chain.md b/wagmi-project/site/shared/create-chain.md new file mode 100644 index 0000000000..da2a7194cd --- /dev/null +++ b/wagmi-project/site/shared/create-chain.md @@ -0,0 +1,93 @@ +## Create Chain + +Import the `Chain` type from Viem and create a new object that is asserted `as const` and `satisfies` the type. You can also use the `defineChain` function from Viem. + +::: code-group +```ts twoslash [as const satisfies Chain] +// @errors: 1360 +import { type Chain } from 'viem' + +export const mainnet = {} as const satisfies Chain +``` +```ts twoslash [defineChain] +// @errors: 2345 +import { defineChain } from 'viem' + +export const mainnet = defineChain({}) +``` +::: + +Now, add the missing required properties to the object until the error goes away. + +::: code-group +```ts twoslash [as const satisfies Chain] +import { type Chain } from 'viem' + +export const mainnet = { + id: 1, + name: 'Ethereum', + nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 }, + rpcUrls: { + default: { http: ['https://eth.merkle.io'] }, + }, + blockExplorers: { + default: { name: 'Etherscan', url: 'https://etherscan.io' }, + }, + contracts: { + ensRegistry: { + address: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e', + }, + ensUniversalResolver: { + address: '0xE4Acdd618deED4e6d2f03b9bf62dc6118FC9A4da', + blockCreated: 16773775, + }, + multicall3: { + address: '0xca11bde05977b3631167028862be2a173976ca11', + blockCreated: 14353601, + }, + }, +} as const satisfies Chain +``` +```ts twoslash [defineChain] +import { defineChain } from 'viem' + +export const mainnet = defineChain({ + id: 1, + name: 'Ethereum', + nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 }, + rpcUrls: { + default: { http: ['https://eth.merkle.io'] }, + }, + blockExplorers: { + default: { name: 'Etherscan', url: 'https://etherscan.io' }, + }, + contracts: { + ensRegistry: { + address: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e', + }, + ensUniversalResolver: { + address: '0xE4Acdd618deED4e6d2f03b9bf62dc6118FC9A4da', + blockCreated: 16773775, + }, + multicall3: { + address: '0xca11bde05977b3631167028862be2a173976ca11', + blockCreated: 14353601, + }, + }, +}) +``` +::: + +The more properties you add, the better the chain will be to use with Wagmi. Most of these attributes exist within the [`ethereum-lists/chains` repository](https://github.com/ethereum-lists/chains/tree/3fbd4eeac7ce116579634bd042b84e2b1d89886a/_data/chains). + +- `id`: The chain ID for the network. This can be found by typing the network name into [ChainList](https://chainlist.org). Example: "Ethereum Mainnet" has a Chain ID of `1`. +- `name`: Human-readable name for the chain. Example: "Ethereum Mainnet" +- `nativeCurrency`: The native currency of the chain. Found from [`ethereum-lists/chains`](https://github.com/ethereum-lists/chains/blob/3fbd4eeac7ce116579634bd042b84e2b1d89886a/_data/chains/eip155-56.json#L20-L24). +- `rpcUrls`: At least one public, credible RPC URL. Found from [`ethereum-lists/chains`](https://github.com/ethereum-lists/chains/blob/3fbd4eeac7ce116579634bd042b84e2b1d89886a/_data/chains/eip155-56.json#L4-L18). +- `blockExplorers`: A set of block explorers for the chain. Found from [`ethereum-lists/chains`](https://github.com/ethereum-lists/chains/blob/3fbd4eeac7ce116579634bd042b84e2b1d89886a/_data/chains/eip155-56.json#L30-L36). +- `contracts`: A set of deployed contracts for the chain. If you are deploying one of the following contracts yourself, make sure it is verified. + - `multicall3` is optional, but it's address is most likely `0xca11bde05977b3631167028862be2a173976ca11` – you can find the deployed block number on the block explorer. Check out [`mds1/multicall`](https://github.com/mds1/multicall#multicall3-contract-addresses) for more info. + - `ensRegistry` is optional – not all Chains have a ENS Registry. See [ENS Deployments](https://docs.ens.domains/ens-deployments) for more info. + - `ensUniversalResolver` is optional – not all Chains have a ENS Universal Resolver. +- `sourceId`: Source Chain ID (e.g. the L1 chain). +- `testnet`: Whether or not the chain is a testnet. \ No newline at end of file diff --git a/wagmi-project/site/shared/createConfig.md b/wagmi-project/site/shared/createConfig.md new file mode 100644 index 0000000000..bde2601794 --- /dev/null +++ b/wagmi-project/site/shared/createConfig.md @@ -0,0 +1,485 @@ + + +# createConfig + +Creates new [`Config`](#config) object. + +## Import + +```ts-vue +import { createConfig } from '{{packageName}}' +``` + +## Usage + +```ts-vue +import { createConfig, http } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http('https://mainnet.example.com'), + [sepolia.id]: http('https://sepolia.example.com'), + }, +}) +``` + +::: tip Integrating a Viem Client + +Instead of using [`transports`](#transports), it's possible to provide a function that returns a Viem [`Client`](https://viem.sh/docs/clients/custom.html) via the [`client`](#client) property for more fine-grained control over Wagmi's internal `Client` creation. + +```ts-vue {3,7-9} +import { createConfig, http } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' +import { createClient } from 'viem' + +const config = createConfig({ + chains: [mainnet, sepolia], + client({ chain }) { + return createClient({ chain, transport: http() }) + }, +}) +``` +::: + +## Parameters + +```ts-vue +import { type CreateConfigParameters } from '{{packageName}}' +``` + +### chains + +`readonly [Chain, ...Chain[]]` + +- Chains used by the `Config`. +- See Chains for more details about built-in chains and the `Chain` type. + +```ts-vue +import { createConfig, http } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], // [!code focus] + transports: { + [mainnet.id]: http('https://mainnet.example.com'), + [sepolia.id]: http('https://sepolia.example.com'), + }, +}) +``` + +### connectors + +`CreateConnectorFn[] | undefined` + +Connectors used by the `Config`. + +```ts-vue +import { createConfig, http } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' +import { injected } from '{{connectorsPackageName}}' // [!code focus] + +const config = createConfig({ + chains: [mainnet, sepolia], + connectors: [injected()], // [!code focus] + transports: { + [mainnet.id]: http('https://mainnet.example.com'), + [sepolia.id]: http('https://sepolia.example.com'), + }, +}) +``` + +### multiInjectedProviderDiscovery + +`boolean | undefined` + +- Enables discovery of injected providers via [EIP-6963](https://eips.ethereum.org/EIPS/eip-6963) using the [`mipd`](https://github.com/wevm/mipd) library and converting to injected connectors. +- Defaults to `true`. + +```ts-vue +import { createConfig, http } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + multiInjectedProviderDiscovery: false, // [!code focus] + transports: { + [mainnet.id]: http('https://mainnet.example.com'), + [sepolia.id]: http('https://sepolia.example.com'), + }, +}) +``` + +### ssr + +`boolean | undefined` + +Flag to indicate if the config is being used in a server-side rendering environment. Defaults to `false`. + +```ts-vue +import { createConfig, http } from '{{packageName}}' // [!code focus] +import { mainnet, sepolia } from '{{packageName}}/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + ssr: true, // [!code focus] + transports: { + [mainnet.id]: http('https://mainnet.example.com'), + [sepolia.id]: http('https://sepolia.example.com'), + }, +}) +``` + +### storage + +`Storage | null | undefined` + +- `Storage` used by the config. Persists `Config`'s [`State`](#state-1) between sessions. +- Defaults to `createStorage({ storage: typeof window !== 'undefined' && window.localStorage ? window.localStorage : noopStorage })`. + +```ts-vue +import { createConfig, createStorage, http } from '{{packageName}}' // [!code focus] +import { mainnet, sepolia } from '{{packageName}}/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + storage: createStorage({ storage: window.localStorage }), // [!code focus] + transports: { + [mainnet.id]: http('https://mainnet.example.com'), + [sepolia.id]: http('https://sepolia.example.com'), + }, +}) +``` + +### syncConnectedChain + +`boolean | undefined` + +- Keep the [`State['chainId']`](#chainid) in sync with the current connection. +- Defaults to `true`. + +```ts-vue +import { createConfig, http } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + syncConnectedChain: false, // [!code focus] + transports: { + [mainnet.id]: http('https://mainnet.example.com'), + [sepolia.id]: http('https://sepolia.example.com'), + }, +}) +``` + +--- + +### batch + +`{ multicall?: boolean | { batchSize?: number | undefined; wait?: number | undefined } | undefined } | { [_ in chains[number]["id"]]?: { multicall?: boolean | { batchSize?: number | undefined; wait?: number | undefined } | undefined } | undefined } | undefined` + +- Batch settings. See [Viem docs](https://viem.sh/docs/clients/custom.html#batch-optional) for more info. +- Defaults to `{ multicall: true }`. + +```ts-vue +import { createConfig, http } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + batch: { multicall: true }, // [!code focus] + transports: { + [mainnet.id]: http('https://mainnet.example.com'), + [sepolia.id]: http('https://sepolia.example.com'), + }, +}) +``` + +### cacheTime + +`number | { [_ in chains[number]['id']]?: number | undefined } | undefined` + +- Frequency in milliseconds for polling enabled features. See [Viem docs](https://viem.sh/docs/clients/public.html#cachetime-optional) for more info. +- Defaults to [`pollingInterval`](#pollinginterval) or `4_000`. + +```ts-vue +import { createConfig, http } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + cacheTime: 4_000, // [!code focus] + transports: { + [mainnet.id]: http('https://mainnet.example.com'), + [sepolia.id]: http('https://sepolia.example.com'), + }, +}) +``` + +### pollingInterval + +`number | { [_ in chains[number]['id']]?: number | undefined } | undefined` + +- Frequency in milliseconds for polling enabled features. See [Viem docs](https://viem.sh/docs/clients/custom.html#pollinginterval-optional) for more info. +- Defaults to `4_000`. + +```ts-vue +import { createConfig, http } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + pollingInterval: 4_000, // [!code focus] + transports: { + [mainnet.id]: http('https://mainnet.example.com'), + [sepolia.id]: http('https://sepolia.example.com'), + }, +}) +``` + +### transports + +`Record` + +Mapping of [chain IDs](#chains) to `Transport`s. This mapping is used internally when creating chain-aware Viem [`Client`](https://viem.sh/docs/clients/custom.html) objects. See the Transport docs for more info. + +```ts-vue +import { createConfig, fallback, http } from '{{packageName}}' // [!code focus] +import { mainnet, sepolia } from '{{packageName}}/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + transports: { // [!code focus] + [mainnet.id]: fallback([ // [!code focus] + http('https://...'), // [!code focus] + http('https://...'), // [!code focus] + ]), // [!code focus] + [sepolia.id]: http('https://...'), // [!code focus] + }, // [!code focus] +}) +``` + +--- + +### client + +`(parameters: { chain: chains[number] }) => Client` + +Function for creating new Viem [`Client`](https://viem.sh/docs/clients/custom.html) to be used internally. Exposes more control over the internal `Client` creation logic versus using the [`transports`](#transports) property. + +```ts-vue +import { createClient, http } from 'viem' // [!code focus] +import { createConfig } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + client({ chain }) { // [!code focus] + return createClient({ chain, transport: http('https://...') }) // [!code focus] + }, // [!code focus] +}) +``` + +::: warning +When using this option, you likely want to pass `parameters.chain` straight through to [`createClient`](https://viem.sh/docs/clients/custom.html#createclient) to ensure the Viem `Client` is in sync with any active connections. +::: + +## Return Type + +```ts-vue +import { type Config } from '{{packageName}}' +``` + +## Config + +Object responsible for managing Wagmi state and internals. + +```ts-vue +import { type Config } from '{{packageName}}' +``` + +### chains + +`readonly [Chain, ...Chain[]]` + +[`chains`](#chains) passed to `createConfig`. + +### connectors + +`readonly Connector[]` + +Connectors set up from passing [`connectors`](#connectors) and [`multiInjectedProviderDiscovery`](#multiinjectedproviderdiscovery) to `createConfig`. + +### state + +`State` + +The `Config` object's internal state. See [`State`](#state-1) for more info. + +### storage + +`Storage | null` + +[`storage`](#storage) passed to `createConfig`. + +### getClient + +`(parameters?: { chainId?: chainId | chains[number]['id'] | undefined }): Client>` + +Creates new Viem [`Client`](https://viem.sh/docs/clients/custom.html) object. + +::: code-group +```ts-vue [index.ts] +import { config } from './config' + +const client = config.getClient({ chainId: 1 }) +``` + +```ts-vue [config.ts] +import { createConfig, http } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' + +export const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http('https://mainnet.example.com'), + [sepolia.id]: http('https://sepolia.example.com'), + }, +}) +``` + +::: + +### setState + +`(value: State | ((state: State) => State)) => void` + +Updates the `Config` object's internal state. See [`State`](#state-1) for more info. + +::: code-group +```ts-vue [index.ts] +import { mainnet } from '{{packageName}}/chains' +import { config } from './config' + +config.setState((x) => ({ + ...x, + chainId: x.current ? x.chainId : mainnet.id, +})) +``` + +```ts-vue [config.ts] +import { createConfig, http } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' + +export const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http('https://mainnet.example.com'), + [sepolia.id]: http('https://sepolia.example.com'), + }, +}) +``` + +::: + +::: warning +Exercise caution when using this method. It is intended for internal and advanced use-cases only. Manually setting state can cause unexpected behavior. +::: + +### subscribe + +`(selector: (state: State) => state, listener: (selectedState: state, previousSelectedState: state) => void, options?: { emitImmediately?: boolean | undefined; equalityFn?: ((a: state, b: state) => boolean) | undefined } | undefined) => (() => void)` + +Listens for state changes matching the `selector` function. Returns a function that can be called to unsubscribe the listener. + +::: code-group +```ts-vue [index.ts] +import { config } from './config' + +const unsubscribe = config.subscribe( + (state) => state.chainId, + (chainId) => console.log(`Chain ID changed to ${chainId}`), +) +unsubscribe() +``` + +```ts-vue [config.ts] +import { createConfig, http } from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' + +export const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http('https://mainnet.example.com'), + [sepolia.id]: http('https://sepolia.example.com'), + }, +}) +``` + +::: + +## State + +```ts-vue +import { type State } from '{{packageName}}' +``` + +### chainId + +`chains[number]['id']` + +Current chain ID. When `syncConnectedChain` is `true`, `chainId` is kept in sync with the current connection. Defaults to first chain in [`chains`](#chains). + +### connections + +`Map` + +Mapping of unique connector identifier to [`Connection`](#connection) object. + +### current + +`string | undefined` + +Unique identifier of the current connection. + +### status + +`'connected' | 'connecting' | 'disconnected' | 'reconnecting'` + +Current connection status. + +- `'connecting'` attempting to establish connection. +- `'reconnecting'` attempting to re-establish connection to one or more connectors. +- `'connected'` at least one connector is connected. +- `'disconnected'` no connection to any connector. + +## Connection + +```ts-vue +import { type Connection } from '{{packageName}}' +``` + +### accounts + +`readonly [Address, ...Address[]]` + +Array of addresses associated with the connection. + +### chainId + +`number` + +Chain ID associated with the connection. + +### connector + +`Connector` + +Connector associated with the connection. diff --git a/wagmi-project/site/shared/createStorage.md b/wagmi-project/site/shared/createStorage.md new file mode 100644 index 0000000000..fe758569d2 --- /dev/null +++ b/wagmi-project/site/shared/createStorage.md @@ -0,0 +1,161 @@ + + +# createStorage + +Creates new [`Storage`](#storage) object. + +## Import + +```ts-vue +import { createStorage } from '{{packageName}}' +``` + +## Usage + +```ts-vue +import { createStorage } from '{{packageName}}' + +const storage = createStorage({ storage: localStorage }) +``` + +## Parameters + +```ts-vue +import { type CreateStorageParameters } from '{{packageName}}' +``` + +### deserialize + +`((value: string) => T) | undefined` + +- Function to deserialize data from storage. +- Defaults to `deserialize`. + +```ts-vue +import { createStorage, deserialize } from '{{packageName}}' // [!code focus] + +const storage = createStorage({ + deserialize, // [!code focus] + storage: localStorage, +}) +``` + +::: warning +If you use a custom `deserialize` function, make sure it can handle `bigint` and `Map` values. +::: + +### key + +`string | undefined` + +- Key prefix to use when persisting data. +- Defaults to `'wagmi'`. + +```ts-vue +import { createStorage } from '{{packageName}}' + +const storage = createStorage({ + key: 'my-app', // [!code focus] + storage: localStorage, +}) +``` + +### serialize + +`((value: T) => string) | undefined` + +- Function to serialize data for storage. +- Defaults to `serialize`. + +```ts-vue +import { createStorage, serialize } from '{{packageName}}' // [!code focus] + +const storage = createStorage({ + serialize, // [!code focus] + storage: localStorage, +}) +``` + +::: warning +If you use a custom `serialize` function, make sure it can handle `bigint` and `Map` values. +::: + +### storage + +`{ getItem(key: string): string | null | undefined | Promise; setItem(key: string, value: string): void | Promise; removeItem(key: string): void | Promise; }` + +- Storage interface to use for persisting data. +- Defaults to `localStorage`. +- Supports synchronous and asynchronous storage methods. + +```ts-vue +import { createStorage } from '{{packageName}}' +// Using IndexedDB via https://github.com/jakearchibald/idb-keyval // [!code focus] +import { del, get, set } from 'idb-keyval' // [!code focus] + +const storage = createStorage({ + storage: { // [!code focus] + async getItem(name) { // [!code focus] + return get(name)// [!code focus] + }, // [!code focus] + async setItem(name, value) { // [!code focus] + await set(name, value) // [!code focus] + }, // [!code focus] + async removeItem(name) { // [!code focus] + await del(name) // [!code focus] + }, // [!code focus] + }, // [!code focus] +}) +``` + +## Return Type + +```ts-vue +import { type Storage } from '{{packageName}}' +``` + +## Storage + +Object responsible for persisting Wagmi `State` and other data. + +```ts-vue +import { type Storage } from '{{packageName}}' +``` + +### getItem + +`getItem(key: string, defaultValue?: value | null | undefined): value | null | Promise` + +```ts-vue +import { createStorage } from '{{packageName}}' + +const storage = createStorage({ storage: localStorage }) +const recentConnectorId = storage.getItem('recentConnectorId') // [!code focus] +``` + +### setItem + +`setItem(key: string, value: any): void | Promise` + +```ts-vue +import { createStorage } from '{{packageName}}' + +const storage = createStorage({ storage: localStorage }) +storage.setItem('recentConnectorId', 'foo') // [!code focus] +``` + +### removeItem + +`removeItem(key: string): void | Promise` + +```ts-vue +import { createStorage } from '{{packageName}}' + +const storage = createStorage({ storage: localStorage }) +storage.removeItem('recentConnectorId') // [!code focus] +``` \ No newline at end of file diff --git a/wagmi-project/site/shared/errors.md b/wagmi-project/site/shared/errors.md new file mode 100644 index 0000000000..c518172fc7 --- /dev/null +++ b/wagmi-project/site/shared/errors.md @@ -0,0 +1,90 @@ + + +## BaseError + +Error class extended by all errors. + +```ts-vue +import { BaseError } from '{{packageName}}' +``` + +## Config + +### ConnectorAccountNotFoundError + +When an account does not exist on the connector or is unable to be used. + +```ts-vue +import { ConnectorAccountNotFoundError } from '{{packageName}}' +``` + +### ConnectorAlreadyConnectedError + +When a connector is already connected. + +```ts-vue +import { ConnectorAlreadyConnectedError } from '{{packageName}}' +``` + +### ConnectorChainMismatchError + +When the Wagmi Config is out-of-sync with the connector's active chain ID. This is rare and likely an upstream wallet issue. + +```ts-vue +import { ConnectorChainMismatchError } from '{{packageName}}' +``` + +### ChainNotConfiguredError + +When a chain is not configured. You likely need to add the chain to `Config['chains']`. + +```ts-vue +import { ChainNotConfiguredError } from '{{packageName}}' +``` + +### ConnectorNotConnectedError + +When a connector is not connected. + +```ts-vue +import { ConnectorNotConnectedError } from '{{packageName}}' +``` + +### ConnectorNotFoundError + +When a connector is not found or able to be used. + +```ts-vue +import { ConnectorNotFoundError } from '{{packageName}}' +``` + +### ConnectorUnavailableReconnectingError + +During the reconnection step, the only connector methods guaranteed to be available are: `id`, `name`, `type`, `uuid`. All other methods are not guaranteed to be available until reconnection completes and connectors are fully restored. This error commonly occurs for connectors that asynchronously inject after reconnection has already started. + +```ts-vue +import { ConnectorUnavailableReconnectingError } from '{{packageName}}' +``` + +## Connector + +### ProviderNotFoundError + +When a connector's provider is not found or able to be used. + +```ts-vue +import { ProviderNotFoundError } from '{{packageName}}' +``` + +### SwitchChainNotSupportedError + +When switching chains is not supported by connectors. + +```ts-vue +import { SwitchChainNotSupportedError } from '{{packageName}}' +``` diff --git a/wagmi-project/site/shared/faq.md b/wagmi-project/site/shared/faq.md new file mode 100644 index 0000000000..03e17693ee --- /dev/null +++ b/wagmi-project/site/shared/faq.md @@ -0,0 +1,81 @@ + + +## Type inference doesn't work + +- Check that you set up TypeScript correctly with `"strict": true` in your `tsconfig.json` (TypeScript docs) +- Check that you const-asserted any ABIs or Typed Data you are using. +- Restart your language server or IDE, and check for type errors in your code. + +## My wallet doesn't work + +If you run into issues with a specific wallet, try another before opening up an issue. There are many different wallets and it's likely that the issue is with the wallet itself, not Wagmi. For example, if you are using Wallet X and sending a transaction doesn't work, try Wallet Y and see if it works. + +## `BigInt` Serialization + +Using native `BigInt` with `JSON.stringify` will raise a `TypeError` as +[`BigInt` values are not serializable](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#use_within_json). There are two techniques to mitigate this: + +#### Lossless serialization + +Lossless serialization means that `BigInt` will be converted to a format that can be deserialized later (e.g. `69420n` → `"#bigint.69420"`). The trade-off is that these values are not human-readable and are not intended to be displayed to the user. + +Lossless serialization can be achieved with wagmi's `serialize` and `deserialize` utilities. + +```tsx +import { serialize, deserialize } from 'wagmi' + +const serialized = serialize({ value: 69420n }) +// '{"value":"#bigint.69420"}' + +const deserialized = deserialize(serialized) +// { value: 69420n } +``` + +#### Lossy serialization + +Lossy serialization means that the `BigInt` will be converted to a normal display string (e.g. `69420n` → `'69420'`). +The trade-off is that you will not be able to deserialize the `BigInt` with `JSON.parse` as it can not distinguish between a normal string and a `BigInt`. + +This method can be achieved by modifying `JSON.stringify` to include a BigInt `replacer`: + +```tsx +const replacer = (key, value) => + typeof value === 'bigint' ? value.toString() : value + +JSON.stringify({ value: 69420n }, replacer) +// '{"value":"69420"}' +``` + +## How do I support the project? + +Wagmi is an open source software project and free to use. If you enjoy using Wagmi or would like to support Wagmi development, you can: + +- [Become a sponsor on GitHub](https://github.com/sponsors/wevm) +- Send us crypto + - Mainnet: 0x4557B18E779944BFE9d78A672452331C186a9f48 + - Multichain: 0xd2135CfB216b74109775236E36d4b433F1DF507B +- [Become a supporter on Drips](https://www.drips.network/app/projects/github/wevm/wagmi) + +If you use Wagmi at work, consider asking your company to sponsor Wagmi. This may not be easy, but **business sponsorships typically make a much larger impact on the sustainability of OSS projects** than individual donations, so you will help us much more if you succeed. + +## Is Wagmi production ready? + +Yes. Wagmi is very stable and is used in production by thousands of organizations, like [Stripe](https://stripe.com), [Shopify](https://shopify.com), [Coinbase](https://coinbase.com), [Uniswap](https://uniswap.org), [ENS](https://ens.domains), [Optimism](https://optimism.com). + +## Is Wagmi strict with semver? + +Yes, Wagmi is very strict with [semantic versioning](https://semver.org) and we will never introduce breaking changes to the runtime API in a minor version bump. + +For exported types, we try our best to not introduce breaking changes in non-major versions, however, [TypeScript doesn't follow semver](https://www.learningtypescript.com/articles/why-typescript-doesnt-follow-strict-semantic-versioning) and often introduces breaking changes in minor releases that can cause Wagmi type issues. See the TypeScript docs for more information. + +## How can I contribute to Wagmi? + +The Wagmi team accepts all sorts of contributions. Check out the [Contributing](/dev/contributing) guide to get started. If you are interested in adding a new connector to Wagmi, check out the [Creating Connectors](/dev/creating-connectors) guide. + +## Anything else you want to know? + +Please create a new [GitHub Discussion thread](https://github.com/wevm/wagmi). You're also free to suggest changes to this or any other page on the site using the "Suggest changes to this page" button at the bottom of the page. diff --git a/wagmi-project/site/shared/getAccount-return-type.md b/wagmi-project/site/shared/getAccount-return-type.md new file mode 100644 index 0000000000..315728261b --- /dev/null +++ b/wagmi-project/site/shared/getAccount-return-type.md @@ -0,0 +1,107 @@ + + +### address + +`Address | undefined` + +- Connected address from connector. +- Defaults to first address in [`addresses`](#addresses). + +### addresses + +`readonly Address[] | undefined` + +Connected addresses from connector. + +### chain + +`Chain | undefined` + +Connected chain from connector. If chain is not configured by config, it will be `undefined`. + +### chainId + +`number | undefined` + +Connected chain id from connector. + +### connector + +`Connector | undefined` + +Connected connector. + +### isConnecting / isReconnecting / isConnected / isDisconnected + +`boolean` + +Boolean variables derived from [`status`](#status). + +### status + +`'connecting' | 'reconnecting' | 'connected' | 'disconnected'` + +- `'connecting'` attempting to establish connection. +- `'reconnecting'` attempting to re-establish connection to one or more connectors. +- `'connected'` at least one connector is connected. +- `'disconnected'` no connection to any connector. + +::: info You can use `status` to narrow the return type. +For example, when `status` is `'connected'` properties like `address` are guaranteed to be defined. + +```ts twoslash +import { type GetAccountReturnType } from '@wagmi/core' +const account = {} as GetAccountReturnType +// ---cut--- +if (account.status === 'connected') { + account + // ^? + + + + + + + + + + + + + + + +} +``` + +Or when status is `'disconnected'` properties like `address` are guaranteed to be `undefined`: + +```ts twoslash +import { type GetAccountReturnType } from '@wagmi/core' +const account = {} as GetAccountReturnType +// ---cut--- +if (account.status === 'disconnected') { + account + // ^? + + + + + + + + + + + + + + + +} +``` +::: diff --git a/wagmi-project/site/shared/installation.md b/wagmi-project/site/shared/installation.md new file mode 100644 index 0000000000..c96c14def0 --- /dev/null +++ b/wagmi-project/site/shared/installation.md @@ -0,0 +1,62 @@ + + +## Requirements + +Wagmi is optimized for modern browsers. It is compatible with the latest versions of the following browsers. + + + +::: tip +Depending on your environment, you might need to add polyfills. See [Viem Platform Compatibility](https://viem.sh/docs/compatibility.html) for more info. +::: + +## Using Unreleased Commits + +If you can't wait for a new release to test the latest features, you can either install from the `canary` tag (tracks the [`main`](https://github.com/wevm/wagmi/tree/main) branch). + +::: code-group +```bash-vue [pnpm] +pnpm add {{packageName}}@canary +``` + +```bash-vue [npm] +npm install {{packageName}}@canary +``` + +```bash-vue [yarn] +yarn add {{packageName}}@canary +``` + +```bash-vue [bun] +bun add {{packageName}}@canary +``` +::: + +Or clone the [Wagmi repo](https://github.com/wevm/wagmi) to your local machine, build, and link it yourself. + +```bash-vue +gh repo clone wevm/wagmi +cd wagmi +pnpm install +pnpm build +cd packages/{{packageDir}} +pnpm link --global +``` + +Then go to the project where you are using Wagmi and run `pnpm link --global {{packageName}}` (or the package manager that you used to link Wagmi globally). Make sure you installed any [required peer dependencies](#package-manager) and their versions are correct. + +## Security + +Ethereum-related projects are often targeted in attacks to steal users' assets. Make sure you follow security best-practices for your project. Some quick things to get started. + +- Pin package versions, upgrade mindfully, and inspect lockfile changes to minimize the risk of [supply-chain attacks](https://nodejs.org/en/guides/security/#supply-chain-attacks). +- Install the [Socket Security](https://socket.dev) [GitHub App](https://github.com/apps/socket-security) to help detect and block supply-chain attacks. +- Add a [Content Security Policy](https://cheatsheetseries.owasp.org/cheatsheets/Content_Security_Policy_Cheat_Sheet.html) to defend against external scripts running in your app. +- Pin [GitHub Action](https://x.com/paulmillr/status/1900948425325031448) versions to commits instead of tags. diff --git a/wagmi-project/site/shared/mutation-imports.md b/wagmi-project/site/shared/mutation-imports.md new file mode 100644 index 0000000000..b538dcfab6 --- /dev/null +++ b/wagmi-project/site/shared/mutation-imports.md @@ -0,0 +1,19 @@ + + +## TanStack Query + +```ts-vue +import { + type {{typeName}}Data, + type {{typeName}}Variables, + type {{typeName}}Mutate, + type {{typeName}}MutateAsync, + {{actionName}}MutationOptions, +} from '{{packageName}}/query' +``` \ No newline at end of file diff --git a/wagmi-project/site/shared/mutation-options.md b/wagmi-project/site/shared/mutation-options.md new file mode 100644 index 0000000000..b1eae45250 --- /dev/null +++ b/wagmi-project/site/shared/mutation-options.md @@ -0,0 +1,89 @@ + + +
+ +--- + +### mutation + +TanStack Query parameters. See the [TanStack Query mutation docs](https://tanstack.com/query/v5/docs/react/reference/useMutation) for more info. + +::: info Wagmi does not support passing all TanStack Query parameters +TanStack Query parameters, like `mutationFn` and `mutationKey`, are used internally to make Wagmi work and you cannot override them. Check out the [source](https://github.com/wevm/wagmi/blob/main/packages/react/src/utils/query.ts#L30) to see what parameters are not supported. All parameters listed below are supported. +::: + +#### gcTime + +`number | Infinity | undefined` + +- The time in milliseconds that unused/inactive cache data remains in memory. When a mutation's cache becomes unused or inactive, that cache data will be garbage collected after this duration. When different cache times are specified, the longest one will be used. +- If set to `Infinity`, will disable garbage collection + +#### meta + +`Record | undefined` + +If set, stores additional information on the mutation cache entry that can be used as needed. It will be accessible wherever [`{{mutate}}`](#mutate) is available (e.g. [`onError`](#onerror), [`onSuccess`](#onsuccess) functions). + +#### networkMode + +`'online' | 'always' | 'offlineFirst' | undefined` + +- defaults to `'online'` +- see [Network Mode](https://tanstack.com/query/v5/docs/react/guides/network-mode) for more information. + +#### onError + +`((error: {{TError}}, variables: {{TVariables}}, context?: context | undefined) => Promise | unknown) | undefined` + +This function will fire if the mutation encounters an error and will be passed the error. + +#### onMutate + +`((variables: {{TVariables}}) => Promise | context | void) | undefined` + +- This function will fire before the mutation function is fired and is passed the same variables the mutation function would receive +- Useful to perform optimistic updates to a resource in hopes that the mutation succeeds +- The value returned from this function will be passed to both the `onError` and `onSettled` functions in the event of a mutation failure and can be useful for rolling back optimistic updates. + +#### onSuccess + +`((data: {{TData}}, variables: {{TVariables}}, context?: context | undefined) => Promise | unknown) | undefined` + +This function will fire when the mutation is successful and will be passed the mutation's result. + +#### onSettled + +`((data: {{TData}}, error: {{TError}}, variables: {{TVariables}}, context?: context | undefined) => Promise | unknown) | undefined` + +This function will fire when the mutation is either successfully fetched or encounters an error and be passed either the data or error + +#### queryClient + +`QueryClient` + +Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will be used. + +#### retry + +`boolean | number | ((failureCount: number, error: {{TError}}) => boolean) | undefined` + +- Defaults to `0`. +- If `false`, failed mutations will not retry. +- If `true`, failed mutations will retry infinitely. +- If set to an `number`, e.g. `3`, failed mutations will retry until the failed mutations count meets that number. + +#### retryDelay + +`number | ((retryAttempt: number, error: {{TError}}) => number) | undefined` + +- This function receives a `retryAttempt` integer and the actual Error and returns the delay to apply before the next attempt in milliseconds. +- A function like `attempt => Math.min(attempt > 1 ? 2 ** attempt * 1000 : 1000, 30 * 1000)` applies exponential backoff. +- A function like `attempt => attempt * 1000` applies linear backoff. diff --git a/wagmi-project/site/shared/mutation-result.md b/wagmi-project/site/shared/mutation-result.md new file mode 100644 index 0000000000..3dfaa2d709 --- /dev/null +++ b/wagmi-project/site/shared/mutation-result.md @@ -0,0 +1,122 @@ + + +
+ +--- + +[TanStack Query mutation docs](https://tanstack.com/query/v5/docs/react/reference/useMutation) + +### {{mutate}} + +`(variables: {{TVariables}}, { onSuccess, onSettled, onError }) => void` + +The mutation function you can call with variables to trigger the mutation and optionally hooks on additional callback options. + +- #### variables + + `{{TVariables}}` + + The variables object to pass to the `{{mutate}}` action. + +- #### onSuccess + + `(data: {{TData}}, variables: {{TVariables}}, context: TContext) => void` + + This function will fire when the mutation is successful and will be passed the mutation's result. + +- #### onError + + `(error: {{TError}}, variables: {{TVariables}}, context: TContext | undefined) => void` + + This function will fire if the mutation encounters an error and will be passed the error. + +- #### onSettled + + `(data: {{TData}} | undefined, error: {{TError}} | null, variables: {{TVariables}}, context: TContext | undefined) => void` + + - This function will fire when the mutation is either successfully fetched or encounters an error and be passed either the data or error + - If you make multiple requests, `onSuccess` will fire only after the latest call you've made. + +### {{mutate}}Async + +`(variables: {{TVariables}}, { onSuccess, onSettled, onError }) => Promise<{{TData}}>` + +Similar to [`{{mutate}}`](#mutate) but returns a promise which can be awaited. + +### data + +`{{TData}} | undefined` + +- `{{mutate}}` return type +- Defaults to `undefined` +- The last successfully resolved data for the mutation. + +### error + +`{{TError}} | null` + +The error object for the mutation, if an error was encountered. + +### failureCount + +`number` + +- The failure count for the mutation. +- Incremented every time the mutation fails. +- Reset to `0` when the mutation succeeds. + +### failureReason + +`{{TError}} | null` + +- The failure reason for the mutation retry. +- Reset to `null` when the mutation succeeds. + +### isError / isIdle / isPending / isSuccess + +`boolean` + +Boolean variables derived from [`status`](#status). + +### isPaused + +`boolean` + +- will be `true` if the mutation has been `paused`. +- see [Network Mode](https://tanstack.com/query/v5/docs/react/guides/network-mode) for more information. + +### reset + +`() => void` + +A function to clean the mutation internal state (e.g. it resets the mutation to its initial state). + +### status + +`'idle' | 'pending' | 'error' | 'success'` + +- `'idle'` initial status prior to the mutation function executing. +- `'pending'` if the mutation is currently executing. +- `'error'` if the last mutation attempt resulted in an error. +- `'success'` if the last mutation attempt was successful. + +### submittedAt + +`number` + +- The timestamp for when the mutation was submitted. +- Defaults to `0`. + +### variables + +`{{TVariables}} | undefined` + +- The variables object passed to [`{{mutate}}`](#mutate). +- Defaults to `undefined`. diff --git a/wagmi-project/site/shared/query-imports.md b/wagmi-project/site/shared/query-imports.md new file mode 100644 index 0000000000..20eed55a01 --- /dev/null +++ b/wagmi-project/site/shared/query-imports.md @@ -0,0 +1,20 @@ + + +## TanStack Query + +```ts-vue +import { + type {{typeName}}Data, + type {{typeName}}Options, + type {{typeName}}QueryFnData, + type {{typeName}}QueryKey, + {{actionName}}QueryKey, + {{actionName}}QueryOptions, +} from '{{packageName}}/query' +``` \ No newline at end of file diff --git a/wagmi-project/site/shared/query-options.md b/wagmi-project/site/shared/query-options.md new file mode 100644 index 0000000000..ac6f3f51f5 --- /dev/null +++ b/wagmi-project/site/shared/query-options.md @@ -0,0 +1,208 @@ + + +
+ +--- + +### query + +TanStack Query parameters. See the [TanStack Query query docs](https://tanstack.com/query/v5/docs/react/reference/useQuery) for more info. + +::: info Wagmi does not support passing all TanStack Query parameters +TanStack Query parameters, like `queryFn` and `queryKey`, are used internally to make Wagmi work and you cannot override them. Check out the [source](https://github.com/wevm/wagmi/blob/main/packages/react/src/types/properties.ts#L27) to see what parameters are not supported. All parameters listed below are supported. +::: + +#### enabled + +`boolean | undefined` + +- Set this to `false` to disable this query from automatically running. +- Can be used for [Dependent Queries](https://tanstack.com/query/v5/docs/react/guides/dependent-queries). + +
+ +#### gcTime + +`number | Infinity | undefined` + +- Defaults to `5 * 60 * 1000` (5 minutes) or `Infinity` during SSR +- The time in milliseconds that unused/inactive cache data remains in memory. When a query's cache becomes unused or inactive, that cache data will be garbage collected after this duration. When different garbage collection times are specified, the longest one will be used. +- If set to `Infinity`, will disable garbage collection + +
+ +#### initialData + +`{{TData}} | (() => {{TData}}) | undefined` + +- If set, this value will be used as the initial data for the query cache (as long as the query hasn't been created or cached yet) +- If set to a function, the function will be called **once** during the shared/root query initialization, and be expected to synchronously return the initialData +- Initial data is considered stale by default unless a `staleTime` has been set. +- `initialData` **is persisted** to the cache + +#### initialDataUpdatedAt + +`number | ((() => number | undefined)) | undefined` + +If set, this value will be used as the time (in milliseconds) of when the `initialData` itself was last updated. + +
+ +#### initialPageParam + +`{{TPageParam}}` + +The initial page parameter to be passed to the query function. + +#### getPreviousPageParam + +This function can be set to automatically get the previous cursor for infinite queries. +The result will also be used to determine the value of `hasPreviousPage`. + +`(firstPage: {{TData}}, allPages: {{TData}}[], firstPageParam: {{TPageParam}}, allPageParams: {{TPageParam}}[]) => {{TPageParam}} | undefined | null` + +#### getNextPageParam + +This function can be set to automatically get the previous cursor for infinite queries. +The result will also be used to determine the value of `hasPreviousPage`. + +`(lastPage: {{TData}}, allPages: {{TData}}[], lastPageParam: {{TPageParam}}, allPageParams: {{TPageParam}}[]) => {{TPageParam}} | undefined | null` + +
+ +#### meta + +`Record | undefined` + +If set, stores additional information on the query cache entry that can be used as needed. It will be accessible wherever the `query` is available, and is also part of the `QueryFunctionContext` provided to the `queryFn`. + +#### networkMode + +`online' | 'always' | 'offlineFirst' | undefined` + +- Defaults to `'online'` +- see [Network Mode](https://tanstack.com/query/v5/docs/react/guides/network-mode) for more information. + +#### notifyOnChangeProps + +`string[] | 'all' | (() => string[] | 'all') | undefined` + +- If set, the component will only re-render if any of the listed properties change. +- If set to `['data', 'error']` for example, the component will only re-render when the `data` or `error` properties change. +- If set to `'all'`, the component will opt-out of smart tracking and re-render whenever a query is updated. +- If set to a function, the function will be executed to compute the list of properties. +- By default, access to properties will be tracked, and the component will only re-render when one of the tracked properties change. + +#### placeholderData + +`{{TData}} | ((previousValue: {{TData}} | undefined; previousQuery: Query | undefined) => {{TData}}) | undefined` + +- If set, this value will be used as the placeholder data for this particular query observer while the query is still in the `pending` state. +- `placeholderData` is **not persisted** to the cache +- If you provide a function for `placeholderData`, as a first argument you will receive previously watched query data if available, and the second argument will be the complete previousQuery instance. + +#### queryClient + +`QueryClient | undefined` + +Use this to use a custom `QueryClient`. Otherwise, the one from the nearest context will be used. + +#### refetchInterval + +`number | false | ((data: {{TData}} | undefined, query: Query) => number | false | undefined) | undefined` + +- If set to a number, all queries will continuously refetch at this frequency in milliseconds +- If set to a function, the function will be executed with the latest data and query to compute a frequency + +#### refetchIntervalInBackground + +`boolean | undefined` + +If set to `true`, queries that are set to continuously refetch with a `refetchInterval` will continue to refetch while their tab/window is in the background + +#### refetchOnMount + +`boolean | 'always' | ((query: Query) => boolean | 'always') | undefined` + +- Defaults to `true` +- If set to `true`, the query will refetch on mount if the data is stale. +- If set to `false`, the query will not refetch on mount. +- If set to `'always'`, the query will always refetch on mount. +- If set to a function, the function will be executed with the query to compute the value + +#### refetchOnReconnect + +`boolean | 'always' | ((query: Query) => boolean | 'always') | undefined` + +- Defaults to `true` +- If set to `true`, the query will refetch on reconnect if the data is stale. +- If set to `false`, the query will not refetch on reconnect. +- If set to `'always'`, the query will always refetch on reconnect. +- If set to a function, the function will be executed with the query to compute the value + +#### refetchOnWindowFocus + +`boolean | 'always' | ((query: Query) => boolean | 'always') | undefined` + +- Defaults to `true` +- If set to `true`, the query will refetch on window focus if the data is stale. +- If set to `false`, the query will not refetch on window focus. +- If set to `'always'`, the query will always refetch on window focus. +- If set to a function, the function will be executed with the query to compute the value + +#### retry + +`boolean | number | ((failureCount: number, error: {{TError}}) => boolean) | undefined` + +- If `false`, failed queries will not retry by default. +- If `true`, failed queries will retry infinitely. +- If set to a `number`, e.g. `3`, failed queries will retry until the failed query count meets that number. +- Defaults to `3` on the client and `0` on the server + +#### retryDelay + +`number | ((retryAttempt: number, error: {{TError}}) => number) | undefined` + +- This function receives a `retryAttempt` integer and the actual Error and returns the delay to apply before the next attempt in milliseconds. +- A function like `attempt => Math.min(attempt > 1 ? 2 ** attempt * 1000 : 1000, 30 * 1000)` applies exponential backoff. +- A function like `attempt => attempt * 1000` applies linear backoff. + +#### retryOnMount + +`boolean | undefined` + +If set to `false`, the query will not be retried on mount if it contains an error. Defaults to `true`. + +#### select + +`((data: {{TData}}) => unknown) | undefined` + +This option can be used to transform or select a part of the data returned by the query function. It affects the returned `data` value, but does not affect what gets stored in the query cache. + +
+ +#### staleTime + +`number | Infinity | undefined` + +- Defaults to `0` +- The time in milliseconds after data is considered stale. This value only applies to the hook it is defined on. +- If set to `Infinity`, the data will never be considered stale + +
+ +#### structuralSharing + +`boolean | (((oldData: {{TData}} | undefined, newData: {{TData}}) => {{TData}})) | undefined` + +- Defaults to `true` +- If set to `false`, structural sharing between query results will be disabled. +- If set to a function, the old and new data values will be passed through this function, which should combine them into resolved data for the query. This way, you can retain references from the old data to improve performance even when that data contains non-serializable values. diff --git a/wagmi-project/site/shared/query-result.md b/wagmi-project/site/shared/query-result.md new file mode 100644 index 0000000000..34e4b8e733 --- /dev/null +++ b/wagmi-project/site/shared/query-result.md @@ -0,0 +1,193 @@ + + +
+ +--- + +[TanStack Query query docs](https://tanstack.com/query/v5/docs/react/reference/useQuery) + +### data + +`{{TData}}` + +- The last successfully resolved data for the query. +- Defaults to `undefined`. + +### dataUpdatedAt + +`number` + +The timestamp for when the query most recently returned the `status` as `'success'`. + +### error + +`null | {{TError}}` + +- The error object for the query, if an error was thrown. +- Defaults to `null` + +### errorUpdatedAt + +`number` + +The timestamp for when the query most recently returned the `status` as `'error'`. + +### errorUpdateCount + +`number` + +The sum of all errors. + +### failureCount + +`number` + +- The failure count for the query. +- Incremented every time the query fails. +- Reset to `0` when the query succeeds. + +### failureReason + +`null | {{TError}}` + +- The failure reason for the query retry. +- Reset to `null` when the query succeeds. + +
+ +### fetchNextPage + +`(options?: FetchNextPageOptions) => Promise>` + +This function allows you to fetch the next "page" of results. + +### fetchPreviousPage + +`(options?: FetchPreviousPageOptions) => Promise>` + +This function allows you to fetch the previous "page" of results. + +### hasNextPage + +`boolean` + +This will be `true` if there is a next page to be fetched (known via the `getNextPageParam` option). + +### hasPreviousPage + +`boolean` + +This will be `true` if there is a previous page to be fetched (known via the `getPreviousPageParam` option). + +### isFetchingNextPage + +`boolean` + +Will be `true` while fetching the next page with `fetchNextPage`. + +### isFetchingPreviousPage + +`boolean` + +Will be `true` while fetching the previous page with `fetchPreviousPage`. + +
+ +### fetchStatus + +`'fetching' | 'idle' | 'paused'` + +- `fetching` Is `true` whenever the queryFn is executing, which includes initial `pending` as well as background refetches. +- `paused` The query wanted to fetch, but has been `paused`. +- `idle` The query is not fetching. +- See [Network Mode](https://tanstack.com/query/v5/docs/react/guides/network-mode) for more information. + +### isError / isPending / isSuccess + +`boolean` + +Boolean variables derived from [`status`](#status). + +### isFetched + +`boolean` + +Will be `true` if the query has been fetched. + +### isFetchedAfterMount + +`boolean` + +- Will be `true` if the query has been fetched after the component mounted. +- This property can be used to not show any previously cached data. + +### isFetching / isPaused + +`boolean` + +Boolean variables derived from [`fetchStatus`](#fetchstatus). + +### isLoading + +`boolean` + +- Is `true` whenever the first fetch for a query is in-flight +- Is the same as `isFetching && isPending` + +### isLoadingError + +`boolean` + +Will be `true` if the query failed while fetching for the first time. + +### isPlaceholderData + +`boolean` + +Will be `true` if the data shown is the placeholder data. + +### isRefetchError + +`boolean` + +Will be `true` if the query failed while refetching. + +### isRefetching + +`boolean` + +- Is `true` whenever a background refetch is in-flight, which _does not_ include initial `'pending'`. +- Is the same as `isFetching && !isPending` + +### isStale + +`boolean` + +Will be `true` if the data in the cache is invalidated or if the data is older than the given `staleTime`. + +### refetch + +`(options: { cancelRefetch?: boolean | undefined; throwOnError?: boolean | undefined }) => Promise>` + +- A function to manually refetch the query. +- `throwOnError` + - When set to `true`, an error will be thrown if the query fails. + - When set to `false`, an error will be logged if the query fails. +- `cancelRefetch` + - When set to `true`, a currently running request will be cancelled before a new request is made. + - When set to `false`, no refetch will be made if there is already a request running. + - Defaults to `true` + +### status + +`'error' | 'pending' | 'success'` + +- `pending` if there's no cached data and no query attempt was finished yet. +- `error` if the query attempt resulted in an error. The corresponding `error` property has the error received from the attempted fetch +- `success` if the query has received a response with no errors and is ready to display its data. The corresponding `data` property on the query is the data received from the successful fetch or if the query's `enabled` property is set to `false` and has not been fetched yet `data` is the first `initialData` supplied to the query on initialization. diff --git a/wagmi-project/site/shared/transports/custom.md b/wagmi-project/site/shared/transports/custom.md new file mode 100644 index 0000000000..dee391608a --- /dev/null +++ b/wagmi-project/site/shared/transports/custom.md @@ -0,0 +1,110 @@ + + +# custom + +The `custom` Transport connects to a JSON-RPC API via custom. Wraps Viem's [`custom` Transport](https://viem.sh/docs/clients/transports/custom.html). + +## Import + +```ts-vue +import { custom } from '{{packageName}}' +``` + +## Usage + +```ts-vue +import { + createConfig, + custom // [!code hl] +} from '{{packageName}}' +import { mainnet } from '{{packageName}}/chains' +import { customRpc } from './rpc' + +export const config = createConfig({ + chains: [mainnet], + connectors: [injected()], + transports: { + [mainnet.id]: custom({ // [!code hl] + async request({ method, params }) { // [!code hl] + const response = await customRpc.request(method, params) // [!code hl] + return response // [!code hl] + } // [!code hl] + }) // [!code hl] + }, +}) +``` + +## Parameters + +### provider + +`{ request({ method: string, params: unknown[] }): Promise }` + +An [EIP-1193 `request` function](https://eips.ethereum.org/EIPS/eip-1193#request) function. + +```ts +import { customRpc } from './rpc' + +const transport = custom({ + async request({ method, params }) { // [!code focus:3] + const response = await customRpc.request(method, params) + return response + } +}) +``` + +### key (optional) + +`string` + +A key for the Transport. Defaults to `"custom"`. + +```ts +const transport = custom( + provider, + { + key: 'windowProvider', // [!code focus] + } +) +``` + +### name (optional) + +`string` + +A name for the Transport. Defaults to `"Ethereum Provider"`. + +```ts +const transport = custom( + provider, + { + name: 'Window Ethereum Provider', // [!code focus] + } +) +``` + +### retryCount (optional) + +`number` + +The max number of times to retry when a request fails. Defaults to `3`. + +```ts +const transport = custom(provider, { + retryCount: 5, // [!code focus] +}) +``` + +### retryDelay (optional) + +`number` + +The base delay (in ms) between retries. By default, the Transport will use [exponential backoff](https://en.wikipedia.org/wiki/Exponential_backoff) (`~~(1 << count) * retryDelay`), which means the time between retries is not constant. + +```ts +const transport = custom(provider, { + retryDelay: 100, // [!code focus] +}) +``` \ No newline at end of file diff --git a/wagmi-project/site/shared/transports/fallback.md b/wagmi-project/site/shared/transports/fallback.md new file mode 100644 index 0000000000..befe9395e3 --- /dev/null +++ b/wagmi-project/site/shared/transports/fallback.md @@ -0,0 +1,36 @@ + + +# fallback + +The `fallback` Transport consumes **multiple** Transports. If a Transport request fails, it will fall back to the next one in the list. Wraps Viem's [`fallback` Transport](https://viem.sh/docs/clients/transports/fallback.html). + +## Import + +```ts-vue +import { fallback } from '{{packageName}}' +``` + +## Usage + +```ts-vue +import { + createConfig, + fallback, // [!code hl] + http, +} from '{{packageName}}' +import { mainnet } from '{{packageName}}/chains' + +export const config = createConfig({ + chains: [mainnet], + connectors: [injected()], + transports: { + [mainnet.id]: fallback([ // [!code hl] + http('https://foo-bar-baz.quiknode.pro/...'), // [!code hl] + http('https://mainnet.infura.io/v3/...'), // [!code hl] + ]) // [!code hl] + }, +}) +``` + diff --git a/wagmi-project/site/shared/transports/http.md b/wagmi-project/site/shared/transports/http.md new file mode 100644 index 0000000000..1a1d864063 --- /dev/null +++ b/wagmi-project/site/shared/transports/http.md @@ -0,0 +1,178 @@ + + +# http + +The `http` Transport connects to a JSON-RPC API via HTTP. Wraps Viem's [`http` Transport](https://viem.sh/docs/clients/transports/http.html). + +## Import + +```ts-vue +import { http } from '{{packageName}}' +``` + +## Usage + +```ts-vue +import { + createConfig, + http // [!code hl] +} from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' + +export const config = createConfig({ + chains: [mainnet, sepolia], + connectors: [injected()], + transports: { + [mainnet.id]: http('https://foo-bar-baz.quiknode.pro/...'), // [!code hl] + [sepolia.id]: http('https://foo-bar-sep.quiknode.pro/...'), // [!code hl] + }, +}) +``` + +::: warning +If no URL is provided, then the transport will fall back to a public RPC URL on the chain. It is highly recommended to provide an authenticated RPC URL to prevent rate-limiting. +::: + +### Batch JSON-RPC + +The `http` Transport supports Batch JSON-RPC. This means that multiple JSON-RPC requests can be sent in a single HTTP request. + +The Transport will batch up Actions over a given period and execute them in a single Batch JSON-RPC HTTP request. By default, this period is a [zero delay](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Event_loop#zero_delays) meaning that the batch request will be executed at the end of the current [JavaScript message queue](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Event_loop#queue). Consumers can specify a custom time period `wait` (in ms). + +You can enable Batch JSON-RPC by setting the `batch` flag to `true`: + +```ts +const transport = http('https://foo-bar-baz.quiknode.pro/...', { + batch: true // [!code hl] +}) +``` + +## Parameters + +### url + +`string` + +URL of the JSON-RPC API. Defaults to `chain.rpcUrls.default.http[0]`. + +```ts +const transport = http('https://foo-bar-baz.quiknode.pro/...') +``` + +### batch + +`boolean | BatchOptions` + +Toggle to enable Batch JSON-RPC. Defaults to `false` + +```ts +const transport = http('https://foo-bar-baz.quiknode.pro/...', { + batch: true // [!code focus] +}) +``` + +### batch.batchSize + +`number` + +The maximum number of JSON-RPC requests to send in a batch. Defaults to `1_000`. + +```ts +const transport = http('https://foo-bar-baz.quiknode.pro/...', { + batch: { + batchSize: 2_000 // [!code focus] + } +}) +``` + +### batch.wait + +`number` + +The maximum number of milliseconds to wait before sending a batch. Defaults to `0` ([zero delay](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Event_loop#zero_delays)). + +```ts +const transport = http('https://foo-bar-baz.quiknode.pro/...', { + batch: { + wait: 16 // [!code focus] + } +}) +``` + +### fetchOptions + +[`RequestInit`](https://developer.mozilla.org/en-US/docs/Web/API/fetch) + +[Fetch options](https://developer.mozilla.org/en-US/docs/Web/API/fetch) to pass to the internal `fetch` function. Useful for passing auth headers or cache options. + +```ts +const transport = http('https://foo-bar-baz.quiknode.pro/...', { + fetchOptions: { // [!code focus:5] + headers: { + 'Authorization': 'Bearer ...' + } + } +}) +``` + +### key + +`string` + +A key for the Transport. Defaults to `"http"`. + +```ts +const transport = http('https://foo-bar-baz.quiknode.pro/...', { + key: 'alchemy', // [!code focus] +}) +``` + +### name + +`string` + +A name for the Transport. Defaults to `"HTTP JSON-RPC"`. + +```ts +const transport = http('https://foo-bar-baz.quiknode.pro/...', { + name: 'Alchemy HTTP Provider', // [!code focus] +}) +``` + +### retryCount + +`number` + +The max number of times to retry when a request fails. Defaults to `3`. + +```ts +const transport = http('https://foo-bar-baz.quiknode.pro/...', { + retryCount: 5, // [!code focus] +}) +``` + +### retryDelay + +`number` + +The base delay (in ms) between retries. By default, the Transport will use [exponential backoff](https://en.wikipedia.org/wiki/Exponential_backoff) (`~~(1 << count) * retryDelay`), which means the time between retries is not constant. + +```ts +const transport = http('https://foo-bar-baz.quiknode.pro/...', { + retryDelay: 100, // [!code focus] +}) +``` + +### timeout + +`number` + +The timeout for requests. Defaults to `10_000`. + +```ts +const transport = http('https://foo-bar-baz.quiknode.pro/...', { + timeout: 60_000, // [!code focus] +}) +``` diff --git a/wagmi-project/site/shared/transports/unstable_connector.md b/wagmi-project/site/shared/transports/unstable_connector.md new file mode 100644 index 0000000000..f858421c90 --- /dev/null +++ b/wagmi-project/site/shared/transports/unstable_connector.md @@ -0,0 +1,123 @@ + + +# unstable_connector + +The `unstable_connector` Transport connects to a JSON-RPC API via the provided Connector. + +For example, if the provided Connector is `injected` and the end-user uses MetaMask, then outgoing JSON-RPC requests will be sent via the MetaMask EIP-1193 Provider (`window.ethereum`). + +## Import + +```ts-vue +import { unstable_connector } from '{{packageName}}' +``` + +## Usage + +```ts-vue +import { + createConfig, + fallback, + unstable_connector, // [!code hl] +} from '{{packageName}}' +import { mainnet } from '{{packageName}}/chains' + +export const config = createConfig({ + chains: [mainnet], + connectors: [injected()], + transports: { + [mainnet.id]: fallback([ + unstable_connector(injected), // [!code hl] + http('https://foo-bar-baz.quiknode.pro/...') + ]) + }, +}) +``` + +::: warning +It is **highly recommended** to use the `unstable_connector` Transport inside of a `fallback` Transport. This ensures that if the Connector request fails, the Transport will fall back to a different Transport in the fallback set. + +Some common cases for a Connector request to fail are: + +- Chain ID mismatches, +- Connector RPC not supporting the requested method and/or only supporting a subset of methods for connected accounts, +- Rate-limiting of Connector RPC. +::: + +## Parameters + +### connector + +`Connector` + +The Connector to use for the Transport. + +```ts +import { unstable_connector } from 'wagmi' +import { safe } from 'wagmi/connectors' + +const transport = unstable_connector(safe) // [!code focus] +``` + +### key (optional) + +`string` + +A key for the Transport. Defaults to `"connector"`. + +```ts +import { unstable_connector } from 'wagmi' +import { injected } from 'wagmi/connectors' + +const transport = unstable_connector(injected, { + key: 'injected', // [!code focus] +}) +``` + +### name (optional) + +`string` + +A name for the Transport. Defaults to `"Connector"`. + +```ts +import { unstable_connector } from 'wagmi' +import { injected } from 'wagmi/connectors' + +const transport = unstable_connector(injected, { + name: 'Injected', // [!code focus] +}) +``` + +### retryCount (optional) + +`number` + +The max number of times to retry when a request fails. Defaults to `3`. + +```ts +import { unstable_connector } from 'wagmi' +import { injected } from 'wagmi/connectors' + +const transport = unstable_connector(injected, { + retryCount: 5, // [!code focus] +}) +``` + +### retryDelay (optional) + +`number` + +The base delay (in ms) between retries. By default, the Transport will use [exponential backoff](https://en.wikipedia.org/wiki/Exponential_backoff) (`~~(1 << count) * retryDelay`), which means the time between retries is not constant. + +```ts +import { unstable_connector } from 'wagmi' +import { injected } from 'wagmi/connectors' + +const transport = unstable_connector(injected, { + retryDelay: 100, // [!code focus] +}) +``` diff --git a/wagmi-project/site/shared/transports/webSocket.md b/wagmi-project/site/shared/transports/webSocket.md new file mode 100644 index 0000000000..0b79117400 --- /dev/null +++ b/wagmi-project/site/shared/transports/webSocket.md @@ -0,0 +1,108 @@ + + +# webSocket + +The `webSocket` Transport connects to a JSON-RPC API via a WebSocket. Wraps Viem's [`webSocket` Transport](https://viem.sh/docs/clients/transports/websocket). + +## Import + +```ts-vue +import { webSocket } from '{{packageName}}' +``` + +## Usage + +```ts-vue +import { + createConfig, + webSocket // [!code hl] +} from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' + +export const config = createConfig({ + chains: [mainnet, sepolia], + connectors: [injected()], + transports: { + [mainnet.id]: webSocket('wss://foo-bar-baz.quiknode.pro/...'), // [!code hl] + [sepolia.id]: webSocket('wss://foo-bar-sep.quiknode.pro/...'), // [!code hl] + }, +}) +``` + +::: warning +If no URL is provided, then the transport will fall back to a public RPC URL on the chain. It is highly recommended to provide an authenticated RPC URL to prevent rate-limiting. +::: + +## Parameters + +### url + +`string` + +URL of the JSON-RPC API. + +```ts +const transport = webSocket('wss://foo-bar-baz.quiknode.pro/...') +``` + +### key (optional) + +`string` + +A key for the Transport. Defaults to `"webSocket"`. + +```ts +const transport = webSocket('wss://foo-bar-baz.quiknode.pro/...', { + key: 'alchemy', // [!code focus] +}) +``` + +### name (optional) + +`string` + +A name for the Transport. Defaults to `"WebSocket JSON-RPC"`. + +```ts +const transport = webSocket('wss://foo-bar-baz.quiknode.pro/...', { + name: 'Alchemy WebSocket Provider', // [!code focus] +}) +``` + +### retryCount (optional) + +`number` + +The max number of times to retry when a request fails. Defaults to `3`. + +```ts +const transport = webSocket('wss://foo-bar-baz.quiknode.pro/...', { + retryCount: 5, // [!code focus] +}) +``` + +### retryDelay (optional) + +`number` + +The base delay (in ms) between retries. By default, the Transport will use [exponential backoff](https://en.wikipedia.org/wiki/Exponential_backoff) (`~~(1 << count) * retryDelay`), which means the time between retries is not constant. + +```ts +const transport = webSocket('wss://foo-bar-baz.quiknode.pro/...', { + retryDelay: 100, // [!code focus] +}) +``` + +### timeout (optional) + +`number` + +The timeout for async WebSocket requests. Defaults to `10_000`. + +```ts +const transport = webSocket('wss://foo-bar-baz.quiknode.pro/...', { + timeout: 60_000, // [!code focus] +}) +``` diff --git a/wagmi-project/site/shared/utilities/cookieToInitialState.md b/wagmi-project/site/shared/utilities/cookieToInitialState.md new file mode 100644 index 0000000000..0850b45020 --- /dev/null +++ b/wagmi-project/site/shared/utilities/cookieToInitialState.md @@ -0,0 +1,74 @@ + + +# cookieToInitialState + +Helper to convert a cookie string into [initial state](/react/api/WagmiProvider#initialstate). + +## Import + +```ts-vue +import { cookieToInitialState } from '{{packageName}}' +``` + +## Usage + +::: code-group + +```ts-vue [server.ts] +import { cookieToInitialState } from '{{packageName}}' +import config from './config' + +function handler(req: Request) { + const initialState = cookieToInitialState(config, req.headers.cookie) + // ... +} +``` + +```ts-vue [config.ts] +import { + createConfig, + http, + cookieStorage, + createStorage +} from '{{packageName}}' +import { mainnet, sepolia } from '{{packageName}}/chains' + +export const config = createConfig({ + chains: [mainnet, sepolia], + ssr: true, + storage: createStorage({ + storage: cookieStorage, + }), + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +``` + +::: + +## Parameters + +### config + +`Config` + +Wagmi Config + + +### cookie + +`string | null | undefined` + +The cookie string. + +## Return Type + +`State` + +Initial state. \ No newline at end of file diff --git a/wagmi-project/site/shared/utilities/deserialize.md b/wagmi-project/site/shared/utilities/deserialize.md new file mode 100644 index 0000000000..c355e5a15b --- /dev/null +++ b/wagmi-project/site/shared/utilities/deserialize.md @@ -0,0 +1,44 @@ + + +# deserialize + +Deserialize function that supports `bigint` and `Map`. + +## Import + +```ts-vue +import { deserialize } from '{{packageName}}' +``` + +## Usage + +```ts-vue +import { deserialize } from '{{packageName}}' + +const result = deserialize('{"foo":"wagmi","bar":{"__type":"bigint","value":"123"}}') +``` + +## Parameters + +### value + +`string` + +The string to deserialize. + + +### reviver + +`(key: string, value: any) => any` + +A custom reviver function for handling standard values. + +## Return Type + +`unknown` + +Parsed value. \ No newline at end of file diff --git a/wagmi-project/site/shared/utilities/normalizeChainId.md b/wagmi-project/site/shared/utilities/normalizeChainId.md new file mode 100644 index 0000000000..6cc1cad75d --- /dev/null +++ b/wagmi-project/site/shared/utilities/normalizeChainId.md @@ -0,0 +1,56 @@ + + +# normalizeChainId + +Normalizes a chain ID to a number. + +## Import + +```ts-vue +import { normalizeChainId } from '{{packageName}}' +``` + +## Usage + +:::warning Deprecated +Use `Number` instead. + +```ts-vue +import { normalizeChainId } from '{{packageName}}' // [!code --] +const chainId = normalizeChainId(123n) // [!code --] +const chainId = Number(123n) // [!code ++] +``` +::: + +```ts-vue +import { normalizeChainId } from '{{packageName}}' + +const result = normalizeChainId('0x1') +``` + +## Parameters + + +### chainId + +`bigint | number | string` + +The chain ID to normalize. + +```ts-vue +import { normalizeChainId } from '{{packageName}}' + +normalizeChainId(1n) +normalizeChainId(1) +normalizeChainId('0x1') +``` + +## Return Type + +`number` + +The normalized chain ID. diff --git a/wagmi-project/site/shared/utilities/serialize.md b/wagmi-project/site/shared/utilities/serialize.md new file mode 100644 index 0000000000..9ce6608e7b --- /dev/null +++ b/wagmi-project/site/shared/utilities/serialize.md @@ -0,0 +1,53 @@ + + +# serialize + +Serialize function that supports `bigint` and `Map`. + +## Import + +```ts-vue +import { serialize } from '{{packageName}}' +``` + +## Usage + +```ts-vue +import { serialize } from '{{packageName}}' + +const result = serialize({ foo: 'wagmi', bar: 123n }) +``` + +## Parameters + +### value + +`any` + +The value to stringify. + +### replacer + +`(key: string, value: any) => any` + +A custom replacer function for handling standard values. + +### indent + +`number | null | undefined` + +The number of spaces to indent the output by. + +### circularReplacer + +A custom replacer function for handling circular values. + +## Return Type + +`string` + +Stringified value. \ No newline at end of file diff --git a/wagmi-project/site/snippets/abi-event.ts b/wagmi-project/site/snippets/abi-event.ts new file mode 100644 index 0000000000..2d5b344ae9 --- /dev/null +++ b/wagmi-project/site/snippets/abi-event.ts @@ -0,0 +1,20 @@ +export const abi = [ + { + type: 'event', + name: 'Approval', + inputs: [ + { indexed: true, name: 'owner', type: 'address' }, + { indexed: true, name: 'spender', type: 'address' }, + { indexed: false, name: 'value', type: 'uint256' }, + ], + }, + { + type: 'event', + name: 'Transfer', + inputs: [ + { indexed: true, name: 'from', type: 'address' }, + { indexed: true, name: 'to', type: 'address' }, + { indexed: false, name: 'value', type: 'uint256' }, + ], + }, +] as const diff --git a/wagmi-project/site/snippets/abi-infinite-read.ts b/wagmi-project/site/snippets/abi-infinite-read.ts new file mode 100644 index 0000000000..7e0a2b28ed --- /dev/null +++ b/wagmi-project/site/snippets/abi-infinite-read.ts @@ -0,0 +1,23 @@ +export const abi = [ + { + inputs: [{ internalType: 'uint256', name: 'tokenId', type: 'uint256' }], + name: 'getChest', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'tokenId', type: 'uint256' }], + name: 'getFoot', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'uint256', name: 'tokenId', type: 'uint256' }], + name: 'getHand', + outputs: [{ internalType: 'string', name: '', type: 'string' }], + stateMutability: 'view', + type: 'function', + }, +] as const diff --git a/wagmi-project/site/snippets/abi-read.ts b/wagmi-project/site/snippets/abi-read.ts new file mode 100644 index 0000000000..f893ed2b20 --- /dev/null +++ b/wagmi-project/site/snippets/abi-read.ts @@ -0,0 +1,16 @@ +export const abi = [ + { + type: 'function', + name: 'balanceOf', + stateMutability: 'view', + inputs: [{ name: 'account', type: 'address' }], + outputs: [{ type: 'uint256' }], + }, + { + type: 'function', + name: 'totalSupply', + stateMutability: 'view', + inputs: [], + outputs: [{ name: 'supply', type: 'uint256' }], + }, +] as const diff --git a/wagmi-project/site/snippets/abi-write.ts b/wagmi-project/site/snippets/abi-write.ts new file mode 100644 index 0000000000..93c1b8bb8e --- /dev/null +++ b/wagmi-project/site/snippets/abi-write.ts @@ -0,0 +1,23 @@ +export const abi = [ + { + type: 'function', + name: 'approve', + stateMutability: 'nonpayable', + inputs: [ + { name: 'spender', type: 'address' }, + { name: 'amount', type: 'uint256' }, + ], + outputs: [{ type: 'bool' }], + }, + { + type: 'function', + name: 'transferFrom', + stateMutability: 'nonpayable', + inputs: [ + { name: 'sender', type: 'address' }, + { name: 'recipient', type: 'address' }, + { name: 'amount', type: 'uint256' }, + ], + outputs: [{ type: 'bool' }], + }, +] as const diff --git a/wagmi-project/site/snippets/core/config-chain-properties.ts b/wagmi-project/site/snippets/core/config-chain-properties.ts new file mode 100644 index 0000000000..d9d407cff1 --- /dev/null +++ b/wagmi-project/site/snippets/core/config-chain-properties.ts @@ -0,0 +1,11 @@ +import { http, createConfig } from '@wagmi/core' +import { base, celo, mainnet } from '@wagmi/core/chains' + +export const config = createConfig({ + chains: [base, celo, mainnet], + transports: { + [base.id]: http(), + [celo.id]: http(), + [mainnet.id]: http(), + }, +}) diff --git a/wagmi-project/site/snippets/core/config.ts b/wagmi-project/site/snippets/core/config.ts new file mode 100644 index 0000000000..956f6efa06 --- /dev/null +++ b/wagmi-project/site/snippets/core/config.ts @@ -0,0 +1,10 @@ +import { http, createConfig } from '@wagmi/core' +import { mainnet, sepolia } from '@wagmi/core/chains' + +export const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) diff --git a/wagmi-project/site/snippets/react/app.tsx b/wagmi-project/site/snippets/react/app.tsx new file mode 100644 index 0000000000..6fb247a541 --- /dev/null +++ b/wagmi-project/site/snippets/react/app.tsx @@ -0,0 +1,16 @@ +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import * as React from 'react' +import { WagmiProvider } from 'wagmi' +import { config } from './config' + +export const queryClient = new QueryClient() + +export function App() { + return ( + + + {/** ... */} + + + ) +} diff --git a/wagmi-project/site/snippets/react/config-chain-properties.ts b/wagmi-project/site/snippets/react/config-chain-properties.ts new file mode 100644 index 0000000000..9c71331028 --- /dev/null +++ b/wagmi-project/site/snippets/react/config-chain-properties.ts @@ -0,0 +1,17 @@ +import { http, createConfig } from 'wagmi' +import { base, celo, mainnet } from 'wagmi/chains' + +export const config = createConfig({ + chains: [base, celo, mainnet], + transports: { + [base.id]: http(), + [celo.id]: http(), + [mainnet.id]: http(), + }, +}) + +declare module 'wagmi' { + interface Register { + config: typeof config + } +} diff --git a/wagmi-project/site/snippets/react/config.ts b/wagmi-project/site/snippets/react/config.ts new file mode 100644 index 0000000000..9739c926ce --- /dev/null +++ b/wagmi-project/site/snippets/react/config.ts @@ -0,0 +1,10 @@ +import { http, createConfig } from 'wagmi' +import { mainnet, sepolia } from 'wagmi/chains' + +export const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) diff --git a/wagmi-project/site/snippets/typedData.ts b/wagmi-project/site/snippets/typedData.ts new file mode 100644 index 0000000000..90f01a4155 --- /dev/null +++ b/wagmi-project/site/snippets/typedData.ts @@ -0,0 +1,13 @@ +import type { TypedData } from 'viem' + +export const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const satisfies TypedData diff --git a/wagmi-project/site/snippets/vue/App.vue b/wagmi-project/site/snippets/vue/App.vue new file mode 100644 index 0000000000..ae2a44fd79 --- /dev/null +++ b/wagmi-project/site/snippets/vue/App.vue @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/wagmi-project/site/snippets/vue/config-chain-properties.ts b/wagmi-project/site/snippets/vue/config-chain-properties.ts new file mode 100644 index 0000000000..3c3a9bcaff --- /dev/null +++ b/wagmi-project/site/snippets/vue/config-chain-properties.ts @@ -0,0 +1,17 @@ +import { http, createConfig } from '@wagmi/vue' +import { base, celo, mainnet } from '@wagmi/vue/chains' + +export const config = createConfig({ + chains: [base, celo, mainnet], + transports: { + [base.id]: http(), + [celo.id]: http(), + [mainnet.id]: http(), + }, +}) + +declare module '@wagmi/vue' { + interface Register { + config: typeof config + } +} diff --git a/wagmi-project/site/snippets/vue/config.ts b/wagmi-project/site/snippets/vue/config.ts new file mode 100644 index 0000000000..558ae12e36 --- /dev/null +++ b/wagmi-project/site/snippets/vue/config.ts @@ -0,0 +1,10 @@ +import { http, createConfig } from '@wagmi/vue' +import { mainnet, sepolia } from '@wagmi/vue/chains' + +export const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) diff --git a/wagmi-project/site/snippets/vue/main.ts b/wagmi-project/site/snippets/vue/main.ts new file mode 100644 index 0000000000..27ca843af0 --- /dev/null +++ b/wagmi-project/site/snippets/vue/main.ts @@ -0,0 +1,13 @@ +import { QueryClient, VueQueryPlugin } from '@tanstack/vue-query' +import { WagmiPlugin } from '@wagmi/vue' +import { createApp } from 'vue' + +import App from './App.vue' +import { config } from './config' + +export const queryClient = new QueryClient() + +createApp(App) + .use(WagmiPlugin, { config }) + .use(VueQueryPlugin, { queryClient }) + .mount('#app') diff --git a/wagmi-project/site/tsconfig.json b/wagmi-project/site/tsconfig.json new file mode 100644 index 0000000000..053a800ac2 --- /dev/null +++ b/wagmi-project/site/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "jsx": "preserve", + "lib": ["DOM", "ESNext"], + "module": "ESNext", + "moduleResolution": "node", + "noUnusedLocals": true, + "paths": { + "~/*": ["src/*"] + }, + "resolveJsonModule": true, + "skipLibCheck": true, + "strict": true, + "strictNullChecks": true, + "target": "esnext", + "types": ["vite/client", "vitepress"] + }, + "include": ["./*.ts", "./.vitepress/**/*.ts", "./.vitepress/**/*.vue"], + "exclude": ["dist", "node_modules", "snippets"] +} diff --git a/wagmi-project/site/vercel.json b/wagmi-project/site/vercel.json new file mode 100644 index 0000000000..f7abbb9989 --- /dev/null +++ b/wagmi-project/site/vercel.json @@ -0,0 +1,148 @@ +{ + "cleanUrls": true, + "redirects": [ + { + "source": "/cli", + "destination": "/cli/getting-started", + "permanent": true + }, + + { + "source": "/core", + "destination": "/core/getting-started", + "permanent": true + }, + { + "source": "/core/migration-guide", + "destination": "/core/guides/migrate-from-v1-to-v2", + "permanent": true + }, + { + "source": "/core/:name(faq)", + "destination": "/core/guides/:name", + "permanent": true + }, + { + "source": "/core/ethers-adapters", + "destination": "/core/guides/ethers-web3", + "permanent": true + }, + { + "source": "/core/:section(chains)", + "destination": "/core/api/:section", + "permanent": true + }, + { + "source": "/core/:section(actions|connectors)/:name", + "destination": "/core/api/:section/:name", + "permanent": true + }, + { + "source": "/core/config", + "destination": "/core/api/createConfig", + "permanent": true + }, + + { + "source": "/react", + "destination": "/react/getting-started", + "permanent": true + }, + { + "source": "/react/comparison", + "destination": "/react/comparisons", + "permanent": true + }, + { + "source": "/react/migration-guide", + "destination": "/react/guides/migrate-from-v1-to-v2", + "permanent": true + }, + { + "source": "/react/:name(faq)", + "destination": "/react/guides/:name", + "permanent": true + }, + { + "source": "/react/ethers-adapters", + "destination": "/react/guides/ethers", + "permanent": true + }, + { + "source": "/react/:section(actions|chains)", + "destination": "/react/api/:section", + "permanent": true + }, + { + "source": "/react/:section(connectors|hooks)/:name", + "destination": "/react/api/:section/:name", + "permanent": true + }, + { + "source": "/react/config", + "destination": "/react/api/createConfig", + "permanent": true + }, + { + "source": "/react/WagmiConfig", + "destination": "/react/api/WagmiProvider", + "permanent": true + }, + { + "source": "/react/prepare-hooks/usePrepareContractWrite", + "destination": "/react/api/hooks/useSimulateContract", + "permanent": true + }, + { + "source": "/react/prepare-hooks/usePrepareSendTransaction", + "destination": "/react/api/hooks/useEstimateFeesPerGas", + "permanent": true + }, + + { + "source": "/examples/connect-wallet", + "destination": "/react/guides/connect-wallet", + "permanent": true + }, + { + "source": "/examples/send-transaction", + "destination": "/react/guides/send-transaction", + "permanent": true + }, + { + "source": "/react/guides/sending-transactions", + "destination": "/react/guides/send-transaction", + "permanent": true + }, + { + "source": "/react/guides/reading-contracts", + "destination": "/react/guides/read-from-contract", + "permanent": true + }, + { + "source": "/examples/contract-write(-dynamic)?", + "destination": "/react/guides/write-to-contract", + "permanent": true + }, + { + "source": "/react/guides/writing-to-contracts", + "destination": "/react/guides/write-to-contract", + "permanent": true + }, + { + "source": "/examples/custom-connector", + "destination": "/dev/creating-connectors", + "permanent": true + }, + { + "source": "/examples/sign-message", + "destination": "https://1.x.wagmi.sh/examples/sign-message", + "permanent": false + }, + { + "source": "/examples/sign-in-with-ethereum", + "destination": "https://1.x.wagmi.sh/examples/sign-in-with-ethereum", + "permanent": false + } + ] +} diff --git a/wagmi-project/site/vue/api/Nuxt.md b/wagmi-project/site/vue/api/Nuxt.md new file mode 100644 index 0000000000..e785cfd702 --- /dev/null +++ b/wagmi-project/site/vue/api/Nuxt.md @@ -0,0 +1,27 @@ +# Nuxt + +[Nuxt Module](https://nuxt.com/docs/guide/concepts/modules) for Wagmi. Adds all [Composables](/vue/api/composables) as [auto-imports](https://nuxt.com/docs/guide/concepts/auto-imports). + +## Usage + +::: code-group +```ts twoslash [nuxt.config.ts] +import { defineNuxtConfig } from 'nuxt/config' + +export default defineNuxtConfig({ + modules: ['@wagmi/vue/nuxt'], +}) +``` +```vue [index.vue] + + + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + diff --git a/wagmi-project/site/vue/api/WagmiPlugin.md b/wagmi-project/site/vue/api/WagmiPlugin.md new file mode 100644 index 0000000000..96d2dff971 --- /dev/null +++ b/wagmi-project/site/vue/api/WagmiPlugin.md @@ -0,0 +1,113 @@ +# WagmiPlugin + +[Vue Plugin](https://vuejs.org/guide/reusability/plugins.html#plugins) for Wagmi. + +## Import + +```ts +import { WagmiPlugin } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```ts [main.ts] +import { createApp } from 'vue' +import { WagmiPlugin } from '@wagmi/vue' + +import App from './App.vue' +import { config } from './config' + +createApp(App) + .use(WagmiPlugin, { config }) + .mount('#app') +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type WagmiPluginProps } from '@wagmi/vue' +``` + +### config + +[`Config`](/vue/api/createConfig#config) object to inject with context. + +::: code-group +```ts [main.ts] +import { createApp } from 'vue' +import { WagmiPlugin } from '@wagmi/vue' + +import App from './App.vue' +import { config } from './config' + +createApp(App) + .use(WagmiPlugin, { + config // [!code focus] + }) + .mount('#app') +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### initialState + +`State | undefined` + +- Initial state to hydrate into the [Wagmi Config](/vue/api/createConfig). Useful for SSR. + +::: code-group +```ts [main.ts] +import { createApp } from 'vue' +import { WagmiPlugin } from '@wagmi/vue' + +import App from './App.vue' +import { config } from './config' + +createApp(App) + .use(WagmiPlugin, { + config, + initialState: /* ... */ // [!code focus] + }) + .mount('#app') +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### reconnectOnMount + +`boolean | undefined` + +- Whether or not to reconnect previously connected [connectors](/vue/api/createConfig#connectors) on mount. +- Defaults to `true`. + +::: code-group +```ts [main.ts] +import { createApp } from 'vue' +import { WagmiPlugin } from '@wagmi/vue' + +import App from './App.vue' +import { config } from './config' + +createApp(App) + .use(WagmiPlugin, { + config, + reconnectOnMount: false // [!code focus] + }) + .mount('#app') +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## configKey + +Key to use to provide/inject `Config` via `WagmiPlugin`. + +```ts +import { configKey, type Config } from '@wagmi/vue' +import { inject } from 'vue' + +inject(configKey) +``` diff --git a/wagmi-project/site/vue/api/actions.md b/wagmi-project/site/vue/api/actions.md new file mode 100644 index 0000000000..fa47b78a44 --- /dev/null +++ b/wagmi-project/site/vue/api/actions.md @@ -0,0 +1,30 @@ +# Actions + +Sometimes the declarative nature of Vue Composables doesn't work for parts of your app. For those cases, you can use Wagmi Core Actions directly! + +All the Wagmi Core Actions are importable using the `@wagmi/vue/actions` entrypoint. For example, you can use the `watchBlockNumber` action to watch for block number changes. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +See the [Wagmi Core docs](/core/api/actions) for more info on what actions are available. diff --git a/wagmi-project/site/vue/api/chains.md b/wagmi-project/site/vue/api/chains.md new file mode 100644 index 0000000000..5693e95547 --- /dev/null +++ b/wagmi-project/site/vue/api/chains.md @@ -0,0 +1,26 @@ + + +# Chains + +Viem `Chain` objects. More info at the [Viem docs](https://viem.sh/docs/chains/introduction). + +## Import + +Import via the `'@wagmi/vue/chains'` entrypoint (proxies all chains from `'viem/chains'`). + +```ts +import { mainnet } from '@wagmi/vue/chains' +``` + +## Available Chains + +Chain definitions as of `viem@{{viemVersion}}`. For `viem@latest`, visit the [Viem repo](https://github.com/wevm/viem/blob/main/src/chains/index.ts). + + + + diff --git a/wagmi-project/site/vue/api/composables.md b/wagmi-project/site/vue/api/composables.md new file mode 100644 index 0000000000..8d1babb981 --- /dev/null +++ b/wagmi-project/site/vue/api/composables.md @@ -0,0 +1,25 @@ + + +# Composables + +Vue Composables for accounts, wallets, contracts, transactions, signing, ENS, and more. + +## Import + +```ts +import { useAccount } from '@wagmi/vue' +``` + +## Available Composables + + diff --git a/wagmi-project/site/vue/api/composables/useAccount.md b/wagmi-project/site/vue/api/composables/useAccount.md new file mode 100644 index 0000000000..41bf8727c3 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useAccount.md @@ -0,0 +1,80 @@ +--- +title: useAccount +description: Composable for getting current account. +--- + +# useAccount + +Composable for getting current account. + +## Import + +```ts +import { useAccount } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue twoslash [index.vue] + + + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts twoslash +import { type UseAccountParameters } from '@wagmi/vue' +``` + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Return Type + +```ts twoslash +import { type UseAccountReturnType } from '@wagmi/vue' +``` + + + +## Action + +- [`getAccount`](/core/api/actions/getAccount) diff --git a/wagmi-project/site/vue/api/composables/useAccountEffect.md b/wagmi-project/site/vue/api/composables/useAccountEffect.md new file mode 100644 index 0000000000..8f42d593d2 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useAccountEffect.md @@ -0,0 +1,113 @@ +--- +title: useAccountEffect +description: Composable for listening to account lifecycle events. +--- + +# useAccountEffect + +Composable for listening to account lifecycle events. + +## Import + +```ts +import { useAccountEffect } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type useAccountEffectParameters } from '@wagmi/vue' +``` + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### onConnect + +`` MaybeRef<((data: { address: `0x${string}`; addresses: readonly [`0x${string}`, ...`0x${string}`[]]; chain: Chain | undefined chainId: number; connector: Connector; isReconnected: boolean }) => void)> | undefined `` + +Callback that is called when accounts are connected. + +::: code-group +```tsx [index.tsx] +import { useAccountEffect } from '@wagmi/vue' + +function App() { + useAccountEffect({ + onConnect(data) { // [!code focus] + console.log('Connected!', data) // [!code focus] + }, // [!code focus] + }) +} +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### onDisconnect + +`MaybeRef<(() => void)> | undefined` + +Callback that is called when no more accounts are connected. + +::: code-group +```tsx [index.tsx] +import { useAccountEffect } from '@wagmi/vue' + +function App() { + useAccountEffect({ + onDisconnect() { // [!code focus] + console.log('Disconnected!') // [!code focus] + }, // [!code focus] + }) +} +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Action + +- [`getAccount`](/core/api/actions/getAccount) +- [`watchAccount`](/core/api/actions/watchAccount) diff --git a/wagmi-project/site/vue/api/composables/useBalance.md b/wagmi-project/site/vue/api/composables/useBalance.md new file mode 100644 index 0000000000..a84f6ba886 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useBalance.md @@ -0,0 +1,226 @@ +--- +title: useBalance +description: Composable for fetching native currency or token balance. +--- + + + +# useBalance + +Composable for fetching native currency or token balance. + +## Import + +```ts +import { useBalance } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseBalanceParameters } from '@wagmi/vue' +``` + +### address + +`Address | undefined` + +Address to get balance for. [`enabled`](#enabled) set to `false` if `address` is `undefined`. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +--- + +### blockNumber + +`bigint | undefined` + +Block number to get balance at. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get balance at. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### token + +`Address | undefined` + +ERC-20 token address to get balance for. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### unit + +`'ether' | 'gwei' | 'wei' | number | undefined` + +- Units to use when formatting result. +- Defaults to `'ether'`. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseBalanceReturnType } from '@wagmi/vue' +``` + + + + + +## Action + +- [`getBalance`](/core/api/actions/getBalance) diff --git a/wagmi-project/site/vue/api/composables/useBlockNumber.md b/wagmi-project/site/vue/api/composables/useBlockNumber.md new file mode 100644 index 0000000000..ae8d8956ee --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useBlockNumber.md @@ -0,0 +1,172 @@ +--- +title: useBlockNumber +description: Composable for fetching the number of the most recent block seen. +--- + + + +# useBlockNumber + +Composable for fetching the number of the most recent block seen. + +## Import + +```ts +import { useBlockNumber } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseBlockNumberParameters } from '@wagmi/vue' +``` + +### cacheTime + +`MaybeRef | undefined` + +Time in milliseconds that cached block number will remain in memory. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### chainId + +`MaybeRef | undefined` + +ID of chain to use when fetching data. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### scopeKey + +`MaybeRef | undefined` + +Scopes the cache to a given context. Composables that have identical context will share the same cache. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### watch + +`MaybeRef | undefined` + +- Enables/disables listening for block number changes. +- Can pass a subset of [`UseWatchBlockNumberParameters`](/vue/api/composables/useWatchBlockNumber#parameters) directly to [`useWatchBlockNumber`](/vue/api/composables/useWatchBlockNumber). + +::: code-group +```vue [index.vue] + +``` + +```vue [index-2.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseBlockNumberReturnType } from '@wagmi/vue' +``` + + + + + +## Action + +- [`getBlockNumber`](/core/api/actions/getBlockNumber) +- [`watchBlockNumber`](/core/api/actions/watchBlockNumber) diff --git a/wagmi-project/site/vue/api/composables/useBytecode.md b/wagmi-project/site/vue/api/composables/useBytecode.md new file mode 100644 index 0000000000..a6aa3cca6d --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useBytecode.md @@ -0,0 +1,209 @@ +--- +title: useBytecode +description: Composable for retrieving the bytecode at an address. +--- + + + +# useBytecode + +Composable for retrieving the bytecode at an address. + +## Import + +```ts +import { useBytecode } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseBytecodeParameters } from '@wagmi/vue' +``` + +### address + +`Address | undefined` + +The contract address. + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockNumber + +`bigint | undefined` + +The block number to check the bytecode at. + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +The block tag to check the bytecode at. + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +The chain ID to check the bytecode at. + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/react/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Hooks that have identical context will share the same cache. + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/react/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseBytecodeReturnType } from '@wagmi/vue' +``` + + + + + +## Action + +- [`getBytecode`](/core/api/actions/getBytecode) diff --git a/wagmi-project/site/vue/api/composables/useChainId.md b/wagmi-project/site/vue/api/composables/useChainId.md new file mode 100644 index 0000000000..1419148744 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useChainId.md @@ -0,0 +1,74 @@ +--- +title: useChainId +description: Composable for getting current chain ID. +--- + +# useChainId + +Composable for getting current chain ID. + +## Import + +```ts +import { useChainId } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseChainIdParameters } from '@wagmi/vue' +``` + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type UseChainIdReturnType } from '@wagmi/vue' +``` + +`number` + +Current chain ID from [`config.state.chainId`](/vue/api/createConfig#chainid). + +::: info +Only returns chain IDs for chains configured via `createConfig`'s [`chains`](/vue/api/createConfig#chains) parameter. + +If the active [connection](/vue/api/createConfig#connection) [`chainId`](/vue/api/createConfig#chainid-1) is not from a chain included in your Wagmi `Config`, `useChainId` will return the last configured chain ID. +::: + +## Action + +- [`getChainId`](/core/api/actions/getChainId) +- [`watchChainId`](/core/api/actions/watchChainId) diff --git a/wagmi-project/site/vue/api/composables/useChains.md b/wagmi-project/site/vue/api/composables/useChains.md new file mode 100644 index 0000000000..52daf66021 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useChains.md @@ -0,0 +1,67 @@ +--- +title: useChains +description: Composable for getting configured chains +--- + +# useChains + +Composable for getting configured chains + +## Import + +```ts +import { useChains } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseChainsParameters } from '@wagmi/vue' +``` + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type UseChainsReturnType } from '@wagmi/vue' +``` + +`readonly [Chain, ...Chain[]]` + +Chains from [`config.chains`](/vue/api/createConfig#chains). + +## Action + +- [`getChains`](/core/api/actions/getChains) diff --git a/wagmi-project/site/vue/api/composables/useClient.md b/wagmi-project/site/vue/api/composables/useClient.md new file mode 100644 index 0000000000..18b3ca91fc --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useClient.md @@ -0,0 +1,89 @@ +--- +title: useClient +description: Composable for getting Viem `Client` instance. +--- + +# useClient + +Composable for getting Viem [`Client`](https://viem.sh/docs/clients/custom.html) instance. + +## Import + +```ts +import { useClient } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseClientParameters } from '@wagmi/vue' +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when getting Viem Client. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type UseClientReturnType } from '@wagmi/vue' +``` + +`Client | undefined` + +Viem [`Client`](https://viem.sh/docs/clients/custom.html) instance. + +## Action + +- [`getClient`](/core/api/actions/getClient) +- [`watchClient`](/core/api/actions/watchClient) diff --git a/wagmi-project/site/vue/api/composables/useConfig.md b/wagmi-project/site/vue/api/composables/useConfig.md new file mode 100644 index 0000000000..7555043352 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useConfig.md @@ -0,0 +1,33 @@ +--- +title: useConfig +description: Composable for getting `Config` from the `WagmiPlugin`. +--- + +# useConfig + +Composable for getting [`Config`](/vue/api/createConfig#config) from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +## Import + +```ts +import { useConfig } from 'wagmi' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` + +::: + +## Return Type + +```ts +import { type UseConfigReturnType } from 'wagmi' +``` diff --git a/wagmi-project/site/vue/api/composables/useConnect.md b/wagmi-project/site/vue/api/composables/useConnect.md new file mode 100644 index 0000000000..d1d586c561 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useConnect.md @@ -0,0 +1,115 @@ +--- +title: useConnect +description: Composable for connecting accounts with connectors. +--- + + + +# useConnect + +Composable for connecting accounts with [connectors](/vue/api/connectors). + +## Import + +```ts +import { useConnect } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseConnectParameters } from '@wagmi/vue' +``` + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseConnectReturnType } from '@wagmi/vue' +``` + +### connectors + +`readonly Connector[]` + +Globally configured connectors via [`createConfig`](/vue/api/createConfig#connectors). Useful for rendering a list of available connectors. + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +::: tip +Not all connectors support connecting directly to a `chainId` (e.g. they don't support programmatic chain switching). In those cases, the connector will connect to whatever chain the connector's provider (e.g. wallet) is connected to. +::: + + + +## Action + +- [`connect`](/core/api/actions/connect) diff --git a/wagmi-project/site/vue/api/composables/useConnections.md b/wagmi-project/site/vue/api/composables/useConnections.md new file mode 100644 index 0000000000..c6fa350f90 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useConnections.md @@ -0,0 +1,64 @@ +--- +title: useConnections +description: Composable for getting active connections. +--- + +# useConnections + +Composable for getting active connections. + +## Import + +```ts +import { useConnections } from 'wagmi' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseConnectionsParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type UseConnectionsReturnType } from 'wagmi' +``` + +## Action + +- [`getConnections`](/core/api/actions/getConnections) +- [`watchConnections`](/core/api/actions/watchConnections) diff --git a/wagmi-project/site/vue/api/composables/useConnectorClient.md b/wagmi-project/site/vue/api/composables/useConnectorClient.md new file mode 100644 index 0000000000..61f56ca616 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useConnectorClient.md @@ -0,0 +1,128 @@ +--- +title: useConnectorClient +description: Composable for getting a Viem `Client` object for the current or provided connector. +--- + + + +# useConnectorClient + +Composable for getting a Viem [`Client`](https://viem.sh/docs/clients/custom.html) object for the current or provided connector. + +## Import + +```ts +import { useConnectorClient } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseConnectorClientParameters } from '@wagmi/vue' +``` + +### account + +`Address | Account | undefined` + +Account to use with client. Throws if account is not found on [`connector`](#connector). + +```vue + +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use with client. + +```vue + +``` + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +- Connector to get client for. +- Defaults to current connector. + +```vue + +``` + + + +## Return Type + +```ts +import { type UseConnectorClientReturnType } from '@wagmi/vue' +``` + + + + + +## Action + +- [`getConnectorClient`](/core/api/actions/getConnectorClient) diff --git a/wagmi-project/site/vue/api/composables/useConnectors.md b/wagmi-project/site/vue/api/composables/useConnectors.md new file mode 100644 index 0000000000..c05bc3d381 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useConnectors.md @@ -0,0 +1,41 @@ +--- +title: useConnectors +description: Composable for getting configured connectors. +--- + +# useConnectors + +Composable for getting configured connectors. + +## Import + +```ts +import { useConnectors } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Return Type + +```ts +import { type UseConnectorsReturnType } from '@wagmi/vue' +``` + +`readonly Connector[]` + +Connectors from [`config.connectors`](/vue/api/createConfig#connectors-1). + +## Action + +- [`getConnectors`](/core/api/actions/getConnectors) diff --git a/wagmi-project/site/vue/api/composables/useDisconnect.md b/wagmi-project/site/vue/api/composables/useDisconnect.md new file mode 100644 index 0000000000..66635c3c05 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useDisconnect.md @@ -0,0 +1,111 @@ +--- +title: useDisconnect +description: Composable for disconnecting connections. +--- + + + +# useDisconnect + +Composable for disconnecting connections. + +## Import + +```ts +import { useDisconnect } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseDisconnectParameters } from '@wagmi/vue' +``` + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseDisconnectReturnType } from '@wagmi/vue' +``` + +### connectors + +`readonly Connector[]` + +Connectors that are currently connected. Useful for rendering a list of connectors to disconnect. + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + + + +## Action + +- [`disconnect`](/core/api/actions/connect) diff --git a/wagmi-project/site/vue/api/composables/useEnsAddress.md b/wagmi-project/site/vue/api/composables/useEnsAddress.md new file mode 100644 index 0000000000..7aa72eed65 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useEnsAddress.md @@ -0,0 +1,238 @@ +--- +title: useEnsAddress +description: Composable for fetching ENS address for name. +--- + + + +# useEnsAddress + +Composable for fetching ENS address for name. + +## Import + +```ts +import { useEnsAddress } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +::: warning +Since ENS names prohibit certain forbidden characters (e.g. underscore) and have other validation rules, you likely want to [normalize ENS names](https://docs.ens.domains/contract-api-reference/name-processing#normalising-names) with [UTS-46 normalization](https://unicode.org/reports/tr46) before passing them to `useEnsAddress`. You can use Viem's built-in [`normalize`](https://viem.sh/docs/ens/utilities/normalize) function for this. +::: + +## Parameters + +```ts +import { type UseEnsAddressParameters } from '@wagmi/vue' +``` + +--- + +### blockNumber + +`bigint | undefined` + +Block number to get ENS address at. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get ENS address at. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### coinType + +`number | undefined` + +The [ENSIP-9](https://docs.ens.domains/ens-improvement-proposals/ensip-9-multichain-address-resolution) coin type to fetch the address for. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### name + +`string | undefined` + +Name to get the address for. [`enabled`](#enabled) set to `false` if `name` is `undefined`. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Composables that have identical context will share the same cache. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### universalResolverAddress + +`Address | undefined` + +- Address of ENS Universal Resolver Contract. +- Defaults to current chain's Universal Resolver Contract address. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseEnsAddressReturnType } from '@wagmi/vue' +``` + + + + + +## Action + +- [`getEnsAddress`](/core/api/actions/getEnsAddress) diff --git a/wagmi-project/site/vue/api/composables/useEnsAvatar.md b/wagmi-project/site/vue/api/composables/useEnsAvatar.md new file mode 100644 index 0000000000..5f352e2559 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useEnsAvatar.md @@ -0,0 +1,262 @@ +--- +title: useEnsAvatar +description: Composable for fetching ENS avatar for name. +--- + + + +# useEnsAvatar + +Composable for fetching ENS avatar for name. + +## Import + +```ts +import { useEnsAvatar } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +::: warning +Since ENS names prohibit certain forbidden characters (e.g. underscore) and have other validation rules, you likely want to [normalize ENS names](https://docs.ens.domains/contract-api-reference/name-processing#normalising-names) with [UTS-46 normalization](https://unicode.org/reports/tr46) before passing them to `useEnsAvatar`. You can use Viem's built-in [`normalize`](https://viem.sh/docs/ens/utilities/normalize) function for this. +::: + +## Parameters + +```ts +import { type UseEnsAvatarParameters } from '@wagmi/vue' +``` + +--- + +### assetGatewayUrls + +`{ ipfs?: string | undefined; arweave?: string | undefined } | undefined` + +Gateway urls to resolve IPFS and/or Arweave assets. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### blockNumber + +`bigint | undefined` + +Block number to get ENS avatar at. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get ENS avatar at. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### gatewayUrls + +`string[] | undefined` + +A set of Universal Resolver gateways, used for resolving CCIP-Read requests made through the ENS Universal Resolver Contract. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### name + +`string | undefined` + +Name to get the avatar for. [`enabled`](#enabled) set to `false` if `name` is `undefined`. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Composables that have identical context will share the same cache. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### universalResolverAddress + +`Address | undefined` + +- Address of ENS Universal Resolver Contract. +- Defaults to current chain's Universal Resolver Contract address. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseEnsAvatarReturnType } from '@wagmi/vue' +``` + + + + + +## Action + +- [`getEnsAvatar`](/core/api/actions/getEnsAvatar) diff --git a/wagmi-project/site/vue/api/composables/useEnsName.md b/wagmi-project/site/vue/api/composables/useEnsName.md new file mode 100644 index 0000000000..74461c9964 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useEnsName.md @@ -0,0 +1,206 @@ +--- +title: useEnsName +description: Composable for fetching primary ENS name for address. +--- + + + +# useEnsName + +Composable for fetching primary ENS name for address. + +## Import + +```ts +import { useEnsName } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseEnsNameParameters } from '@wagmi/vue' +``` + +### address + +`Address | undefined` + +Name to get the resolver for. [`enabled`](#enabled) set to `false` if `address` is `undefined`. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +--- + +### blockNumber + +`bigint | undefined` + +Block number to get ENS name at. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get ENS name at. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Composables that have identical context will share the same cache. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### universalResolverAddress + +`Address | undefined` + +- Address of ENS Universal Resolver Contract. +- Defaults to current chain's Universal Resolver Contract address. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseEnsNameReturnType } from '@wagmi/vue' +``` + + + + + +## Action + +- [`getEnsName`](/core/api/actions/getEnsName) diff --git a/wagmi-project/site/vue/api/composables/useEstimateGas.md b/wagmi-project/site/vue/api/composables/useEstimateGas.md new file mode 100644 index 0000000000..4c05fa7674 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useEstimateGas.md @@ -0,0 +1,387 @@ +--- +title: useEstimateGas +description: Composable for estimating the gas necessary to complete a transaction without submitting it to the network. +--- + + + +# useEstimateGas + +Composable for estimating the gas necessary to complete a transaction without submitting it to the network. + +## Import + +```ts +import { useEstimateGas } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseEstimateGasParameters } from '@wagmi/vue' +``` + +### accessList + +`AccessList | undefined` + +The access list. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### account + +`Address | Account | undefined` + +Account to use when estimating gas. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +Chain ID to target when estimating gas. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +Connector to estimate with. If no [`account`](#account) is provided, will use default account from connector. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### data + +`` `0x${string}` | undefined `` + +A contract hashed method call with encoded function data. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### gas + +`bigint | undefined` + +Gas provided for transaction execution. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +--- + +### gasPrice + +`bigint | undefined` + +The price in wei to pay per gas. Only applies to [Legacy Transactions](https://viem.sh/docs/glossary/terms.html#legacy-transaction). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### maxFeePerGas + +`bigint | undefined` + +Total fee per gas in wei, inclusive of [`maxPriorityFeePerGas`](#maxPriorityFeePerGas). Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### maxPriorityFeePerGas + +`bigint | undefined` + +Max priority fee per gas in wei. Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +--- + +### nonce + +`number` + +Unique number identifying this transaction. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Composables that have identical context will share the same cache. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### to + +`Address | undefined` + +The transaction recipient or contract address. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### type + +`'legacy' | 'eip1559' | 'eip2930' | undefined` + +Optional transaction request type to narrow parameters. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### value + +`bigint | undefined` + +Value in wei sent with this transaction. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseEstimateGasReturnType } from '@wagmi/vue' +``` + + + + + +## Action + +- [`estimateGas`](/core/api/actions/estimateGas) diff --git a/wagmi-project/site/vue/api/composables/useReadContract.md b/wagmi-project/site/vue/api/composables/useReadContract.md new file mode 100644 index 0000000000..98e44af8c1 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useReadContract.md @@ -0,0 +1,410 @@ +--- +title: useReadContract +description: Composable for calling a read-only function on a contract, and returning the response. +--- + + + +# useReadContract + +Composable for calling a **read-only** function on a contract, and returning the response. + +A **read-only** function (constant function) on a Solidity contract is denoted by a pure or view keyword. They can only read the state of the contract, and cannot make any changes to it. Since read-only methods do not change the state of the contract, they do not require any gas to be executed, and can be called by any user without the need to pay for gas. + +## Import + +```ts +import { useReadContract } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseReadContractParameters } from '@wagmi/vue' +``` + +### abi + +`Abi | undefined` + +The contract's ABI. Check out the [TypeScript docs](/vue/typescript#const-assert-abis-typed-data) for how to set up ABIs for maximum type inference and safety. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### account + +`Account | undefined` + +Account to use when calling the contract (`msg.sender`). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### address + +`Address | undefined` + +The contract's address. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### args + +`readonly unknown[] | undefined` + +- Arguments to pass when calling the contract. +- Inferred from [`abi`](#abi) and [`functionName`](#functionname). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +--- + +### blockNumber + +`bigint | undefined` + +Block number to call contract at. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to call contract at. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### functionName + +`string | undefined` + +- Function to call on the contract. +- Inferred from [`abi`](#abi). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Composables that have identical context will share the same cache. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-read.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseReadContractReturnType } from '@wagmi/vue' +``` + +The return type's [`data`](#data) property is inferrable via the combination of [`abi`](#abi), [`functionName`](#functionname), and [`args`](#args). Check out the [TypeScript docs](/vue/typescript#const-assert-abis-typed-data) for more info. + + + +## Type Inference + +With [`abi`](#abi) setup correctly, TypeScript will infer the correct types for [`functionName`](#functionname), [`args`](#args), and the return type. See the Wagmi [TypeScript docs](/vue/typescript) for more information. + +::: code-group +```ts twoslash [Inline] +import { createConfig, http, useReadContract } from '@wagmi/vue' +import { mainnet, sepolia } from 'wagmi/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +// ---cut--- +const result = useReadContract({ + abi: [ + { + type: 'function', + name: 'balanceOf', + stateMutability: 'view', + inputs: [{ name: 'account', type: 'address' }], + outputs: [{ type: 'uint256' }], + }, + { + type: 'function', + name: 'totalSupply', + stateMutability: 'view', + inputs: [], + outputs: [{ name: 'supply', type: 'uint256' }], + }, + ], + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'balanceOf', + // ^? + + + args: ['0x6b175474e89094c44da98b954eedeac495271d0f'], + // ^? + + + +}) + +result.data +// ^? +``` + +```ts twoslash [Const-Asserted] +import { createConfig, http, useReadContract } from '@wagmi/vue' +import { mainnet, sepolia } from 'wagmi/chains' + +const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +// ---cut--- +const abi = [ + { + type: 'function', + name: 'balanceOf', + stateMutability: 'view', + inputs: [{ name: 'account', type: 'address' }], + outputs: [{ type: 'uint256' }], + }, + { + type: 'function', + name: 'totalSupply', + stateMutability: 'view', + inputs: [], + outputs: [{ name: 'supply', type: 'uint256' }], + }, +] as const + +const result = useReadContract({ + abi, + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + functionName: 'balanceOf', + // ^? + + + args: ['0x6b175474e89094c44da98b954eedeac495271d0f'], + // ^? +}) + +result.data +// ^? +``` +::: + + + +## Action + +- [`readContract`](/core/api/actions/readContract) diff --git a/wagmi-project/site/vue/api/composables/useReconnect.md b/wagmi-project/site/vue/api/composables/useReconnect.md new file mode 100644 index 0000000000..56316fee5f --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useReconnect.md @@ -0,0 +1,106 @@ +--- +title: useReconnect +description: Composable for reconnecting connectors. +--- + + + +# useReconnect + +Composable for reconnecting [connectors](/core/api/connectors). + +## Import + +```ts +import { useReconnect } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` + +::: + +::: tip +When [`WagmiPlugin['reconnectOnMount']`](/vue/api/WagmiPlugin#reconnectonmount) is `true`, `reconnect` is called automatically on mount. +::: + +## Parameters + +```ts +import { type UseReconnectParameters } from '@wagmi/vue' +``` + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseReconnectReturnType } from '@wagmi/vue' +``` + +### connectors + +`readonly Connector[]` + +Globally configured connectors via [`createConfig`](/vue/api/createConfig#connectors). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + + + +## Action + +- [`reconnect`](/core/api/actions/reconnect) diff --git a/wagmi-project/site/vue/api/composables/useSendTransaction.md b/wagmi-project/site/vue/api/composables/useSendTransaction.md new file mode 100644 index 0000000000..62f581143a --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useSendTransaction.md @@ -0,0 +1,91 @@ +--- +title: useSendTransaction +description: Composable for creating, signing, and sending transactions to networks. +--- + + + +# useSendTransaction + +Composable for creating, signing, and sending transactions to networks. + +## Import + +```ts +import { useSendTransaction } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseSendTransactionParameters } from '@wagmi/vue' +``` + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseSendTransactionReturnType } from '@wagmi/vue' +``` + + + + + +## Action + +- [`sendTransaction`](/core/api/actions/sendTransaction) diff --git a/wagmi-project/site/vue/api/composables/useSignMessage.md b/wagmi-project/site/vue/api/composables/useSignMessage.md new file mode 100644 index 0000000000..dacbc6153c --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useSignMessage.md @@ -0,0 +1,85 @@ +--- +title: useSignMessage +description: Composable for signing messages. +--- + + + +# useSignMessage + +Composable for signing messages. + +## Import + +```ts +import { useSignMessage } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseSignMessageParameters } from '@wagmi/vue' +``` + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseSignMessageReturnType } from '@wagmi/vue' +``` + + + + + +## Action + +- [`signMessage`](/core/api/actions/signMessage) diff --git a/wagmi-project/site/vue/api/composables/useSignTypedData.md b/wagmi-project/site/vue/api/composables/useSignTypedData.md new file mode 100644 index 0000000000..6c21a09012 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useSignTypedData.md @@ -0,0 +1,214 @@ +--- +title: useSignTypedData +description: Composable for signing typed data and calculating an Ethereum-specific EIP-712 signature. +--- + + + +# useSignTypedData + +Composable for signing typed data and calculating an Ethereum-specific [EIP-712](https://eips.ethereum.org/EIPS/eip-712) signature. + +## Import + +```ts +import { useSignTypedData } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseSignTypedDataParameters } from '@wagmi/vue' +``` + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseSignTypedDataReturnType } from '@wagmi/vue' +``` + + + +## Type Inference + +With [`types`](/core/api/actions/signTypedData#types) setup correctly, TypeScript will infer the correct types for [`domain`](/core/api/actions/signTypedData#domain), [`message`](/core/api/actions/signTypedData#message), and [`primaryType`](/core/api/actions/signTypedData#primarytype). See the Wagmi [TypeScript docs](/vue/typescript) for more information. + +::: code-group +```ts twoslash [Inline] +import { useSignTypedData } from '@wagmi/vue' +// ---cut--- +const { signTypedData } = useSignTypedData() + +signTypedData({ + types: { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + }, + primaryType: 'Mail', + // ^? + + + message: { + // ^? + + + + + + + + + + + + + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, +}) +``` +```ts twoslash [Const-Asserted] +import { useSignTypedData } from '@wagmi/vue' +// ---cut--- +const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], +} as const + +const { signTypedData } = useSignTypedData() + +signTypedData({ + types, + primaryType: 'Mail', + // ^? + + + message: { + // ^? + + + + + + + + + + + + + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }, +}) +``` +::: + + + +## Action + +- [`signTypedData`](/core/api/actions/signTypedData) diff --git a/wagmi-project/site/vue/api/composables/useSimulateContract.md b/wagmi-project/site/vue/api/composables/useSimulateContract.md new file mode 100644 index 0000000000..7e10c486d6 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useSimulateContract.md @@ -0,0 +1,686 @@ +--- +title: useSimulateContract +description: Composable for simulating/validating a contract interaction. +--- + + + +# useSimulateContract + +Composable for simulating/validating a contract interaction. + +## Import + +```ts +import { useSimulateContract } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Parameters + +```ts +import { type UseSimulateContractParameters } from '@wagmi/vue' +``` + +### abi + +`Abi | undefined` + +The contract's ABI. Check out the [TypeScript docs](/vue/typescript#const-assert-abis-typed-data) for how to set up ABIs for maximum type inference and safety. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### accessList + +`AccessList | undefined` + +The access list. + +::: code-group +```vue [index.ts] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### account + +`Account | undefined` + +Account to use when calling the contract (`msg.sender`). Throws if account is not found on [`connector`](#connector). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### address + +`Address | undefined` + +The contract's address. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### args + +`readonly unknown[] | undefined` + +- Arguments to pass when calling the contract. +- Inferred from [`abi`](#abi) and [`functionName`](#functionname). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +--- + +### blockNumber + +`bigint | undefined` + +Block number to call contract at. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to call contract at. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +--- + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### connector + +`Connector | undefined` + +[Connector](/vue/api/connectors) to simulate transaction with. + +::: code-group +```vue [index.ts] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### dataSuffix + +`` `0x${string}` | undefined `` + +Data to append to the end of the calldata. Useful for adding a ["domain" tag](https://opensea.notion.site/opensea/Seaport-Order-Attributions-ec2d69bf455041a5baa490941aad307f). + +::: code-group +```vue [index.ts] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### functionName + +`string | undefined` + +- Function to call on the contract. +- Inferred from [`abi`](#abi). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### gas + +`bigint | undefined` + +Gas provided for transaction execution. + +::: code-group +```vue [index.ts] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +--- + +### gasPrice + +`bigint | undefined` + +The price in wei to pay per gas. Only applies to [Legacy Transactions](https://viem.sh/docs/glossary/terms.html#legacy-transaction). + +::: code-group +```vue [index.ts] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### maxFeePerGas + +`bigint | undefined` + +Total fee per gas in wei, inclusive of [`maxPriorityFeePerGas`](#maxPriorityFeePerGas). Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```vue [index.ts] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### maxPriorityFeePerGas + +`bigint | undefined` + +Max priority fee per gas in wei. Only applies to [EIP-1559 Transactions](https://viem.sh/docs/glossary/terms.html#eip-1559-transaction). + +::: code-group +```vue [index.ts] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +--- + +### nonce + +`number` + +Unique number identifying this transaction. + +::: code-group +```vue [index.ts] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### type + +`'legacy' | 'eip1559' | 'eip2930' | undefined` + +Optional transaction request type to narrow parameters. + +::: code-group +```vue [index.ts] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### value + +`bigint | undefined` + +Value in wei sent with this transaction. + +::: code-group +```vue [index.ts] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Composables that have identical context will share the same cache. + +::: code-group +```vue [index.ts] + +``` +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseSimulateContractReturnType } from '@wagmi/vue' +``` + +The return type's [`data`](#data) property is inferrable via the combination of [`abi`](#abi), [`functionName`](#functionname), and [`args`](#args). Check out the [TypeScript docs](/vue/typescript#const-assert-abis-typed-data) for more info. + + + +## Type Inference + +With [`abi`](#abi) setup correctly, TypeScript will infer the correct types for [`functionName`](#functionname), [`args`](#args), and [`value`](#value). See the Wagmi [TypeScript docs](/vue/typescript) for more information. + + + +## Action + +- [`simulateContract`](/core/api/actions/simulateContract) diff --git a/wagmi-project/site/vue/api/composables/useSwitchAccount.md b/wagmi-project/site/vue/api/composables/useSwitchAccount.md new file mode 100644 index 0000000000..bf965bbebb --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useSwitchAccount.md @@ -0,0 +1,120 @@ +--- +title: useSwitchAccount +description: Composable for switching the current account. +--- + + + +# useSwitchAccount + +Composable for switching the current account. + +## Import + +```ts +import { useSwitchAccount } from 'wagmi' +``` + +## Usage + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseSwitchAccountParameters } from 'wagmi' +``` + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseSwitchAccountReturnType } from 'wagmi' +``` + +### connectors + +`readonly Connector[]` + +Globally configured and actively connected connectors. Useful for rendering a list of available connectors to switch to. + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + + + +## Action + +- [`switchAccount`](/core/api/actions/switchAccount) diff --git a/wagmi-project/site/vue/api/composables/useSwitchChain.md b/wagmi-project/site/vue/api/composables/useSwitchChain.md new file mode 100644 index 0000000000..c7dace93ef --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useSwitchChain.md @@ -0,0 +1,124 @@ +--- +title: useSwitchChain +description: Composable for switching the target chain for a connector or the Wagmi `Config`. +--- + + + +# useSwitchChain + +Composable for switching the target chain for a connector or the Wagmi [`Config`](/vue/api/createConfig#config). + +## Import + +```ts +import { useSwitchChain } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +::: tip +When connected, `switchChain` will switch the target chain for the connector. When not connected, `switchChain` will switch the target chain for the Wagmi [`Config`](/vue/api/createConfig#config). +::: + +## Parameters + +```ts +import { type UseSwitchChainParameters } from '@wagmi/vue' +``` + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseSwitchChainReturnType } from '@wagmi/vue' +``` + +### chains + +`readonly [Chain, ...Chain[]]` + +Globally configured chains. Useful for rendering a list of available chains to switch to. + +::: code-group +```vue [index.vue] + + + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + + + +## Action + +- [`switchChain`](/core/api/actions/switchChain) diff --git a/wagmi-project/site/vue/api/composables/useTransaction.md b/wagmi-project/site/vue/api/composables/useTransaction.md new file mode 100644 index 0000000000..80fedc53d3 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useTransaction.md @@ -0,0 +1,184 @@ +--- +title: useTransaction +description: Composable for fetching transactions given hashes or block identifiers. +--- + + + +# useTransaction + +Composable for fetching transactions given hashes or block identifiers. + +## Import + +```ts +import { useTransaction } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseTransactionParameters } from '@wagmi/vue' +``` + +--- + +### blockHash + +`bigint | undefined` + +Block hash to get transaction at (with [`index`](#index)). + +```vue + +``` + +### blockNumber + +`bigint | undefined` + +Block number to get transaction at (with [`index`](#index)). + +```vue + +``` + +### blockTag + +`'latest' | 'earliest' | 'pending' | 'safe' | 'finalized' | undefined` + +Block tag to get transaction at (with [`index`](#index)). + +```vue + +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +```vue + +``` + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### hash + +`` `0x${string}` | undefined `` + +Hash to get transaction. [`enabled`](#enabled) set to `false` if `hash` and [`index`](#index) are `undefined`. + +```vue + +``` + +### index + +`number | undefined` + +An index to be used with a block identifier ([hash](#blockhash), [number](#blocknumber), or [tag](#blocktag)). [`enabled`](#enabled) set to `false` if `index` and [`hash`](#hash) are `undefined`. + +```vue + +``` + + + +## Return Type + +```ts +import { type UseTransactionReturnType } from '@wagmi/vue' +``` + + + + + +## Action + +- [`getTransaction`](/core/api/actions/getTransaction) diff --git a/wagmi-project/site/vue/api/composables/useTransactionReceipt.md b/wagmi-project/site/vue/api/composables/useTransactionReceipt.md new file mode 100644 index 0000000000..e610c23840 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useTransactionReceipt.md @@ -0,0 +1,141 @@ +--- +title: useTransactionReceipt +description: Composable for return the Transaction Receipt given a Transaction hash. +--- + + + +# useTransactionReceipt + +Composable for return the [Transaction Receipt](https://viem.sh/docs/glossary/terms.html#transaction-receipt) given a [Transaction](https://viem.sh/docs/glossary/terms.html#transaction) hash. + +## Import + +```ts +import { useTransactionReceipt } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseTransactionReceiptParameters } from '@wagmi/vue' +``` + +### hash + +`` `0x${string}` | undefined `` + +A transaction hash. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### chainId + +`config['chains'][number]['id'] | undefined` + +The ID of chain to return the transaction receipt from. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### scopeKey + +`string | undefined` + +Scopes the cache to a given context. Composables that have identical context will share the same cache. + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseTransactionReceiptReturnType } from '@wagmi/vue' +``` + + + + + +## Action + +- [`getTransactionReceipt`](/core/api/actions/getTransactionReceipt) diff --git a/wagmi-project/site/vue/api/composables/useWaitForTransactionReceipt.md b/wagmi-project/site/vue/api/composables/useWaitForTransactionReceipt.md new file mode 100644 index 0000000000..80c887a8f7 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useWaitForTransactionReceipt.md @@ -0,0 +1,168 @@ +--- +title: useWaitForTransactionReceipt +description: Composable that waits for the transaction to be included on a block, and then returns the transaction receipt. If the transaction reverts, then the action will throw an error. Replacement detection (e.g. sped up transactions) is also supported. +--- + + + +# useWaitForTransactionReceipt + +Composable that waits for the transaction to be included on a block, and then returns the transaction receipt. If the transaction reverts, then the action will throw an error. Replacement detection (e.g. sped up transactions) is also supported. + +## Import + +```ts +import { useWaitForTransactionReceipt } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type WaitForTransactionReceiptParameters } from '@wagmi/core' +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +```vue [index.vue] + +``` + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group +```vue [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +### confirmations + +`number | undefined` + +The number of confirmations (blocks that have passed) to wait before resolving. + +```vue [index.vue] + +``` + +### onReplaced + +` +(({ reason: 'replaced' | 'repriced' | 'cancelled'; replacedTransaction: Transaction; transaction: Transaction; transactionReceipt: TransactionReceipt }) => void) | undefined +` + +Optional callback to emit if the transaction has been replaced. + +```vue [index.vue] + +``` + +### pollingInterval + +`number | undefined` + +- Polling frequency (in milliseconds). +- Defaults to the [Config's `pollingInterval` config](/vue/api/createConfig#pollinginterval). + +```vue [index.vue] + +``` + +### hash + +`` `0x${string}` | undefined `` + +The transaction hash to wait for. [`enabled`](#enabled) set to `false` if `hash` is `undefined`. + +```vue [index.vue] + +``` + + + +## Return Type + +```ts +import { type UseWaitForTransactionReceiptReturnType } from '@wagmi/vue' +``` + + + + + +## Action + +- [`waitForTransactionReceipt`](/core/api/actions/waitForTransactionReceipt) diff --git a/wagmi-project/site/vue/api/composables/useWatchBlockNumber.md b/wagmi-project/site/vue/api/composables/useWatchBlockNumber.md new file mode 100644 index 0000000000..5d0a561cd1 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useWatchBlockNumber.md @@ -0,0 +1,109 @@ +# useWatchBlockNumber + +Composable that watches for block number changes. + +## Import + +```ts +import { useWatchBlockNumber } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```ts [index.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseWatchBlockNumberParameters } from '@wagmi/vue' +``` + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to watch blocks at. + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +### emitMissed + +`boolean` + +Whether or not to emit missed blocks to the callback. Defaults to `false`. + +Missed blocks may occur in instances where internet connection is lost, or the block time is lesser than the polling interval of the client. + +### emitOnBegin + +`boolean` + +Whether or not to emit the block to the callback when the subscription opens. Defaults to `false`. + +### enabled + +`boolean` + +Whether or not to watch for blocks. Defaults to `true`. + +### onBlockNumber + +`(block: Block, prevblock: Block | undefined) => void` + +Callback for when block changes. + +### onError + +`((error: Error) => void) | undefined` + +Error thrown from getting the block. + +### poll + +`boolean | undefined` + +- Whether or not to use a polling mechanism to check for new blocks instead of a WebSocket subscription. +- Defaults to `false` for WebSocket Clients, and `true` for non-WebSocket Clients. + +### pollingInterval + +`number | undefined` + +- Polling frequency (in milliseconds). +- Defaults to the [Config's `pollingInterval` config](/core/api/createConfig#pollinginterval). + +### syncConnectedChain + +`boolean | undefined` + +- Set up subscriber for connected chain changes. +- Defaults to [`Config['syncConnectedChain']`](/core/api/createConfig#syncconnectedchain). + +## Return Type + +```ts +import { type UseWatchBlockNumberReturnType } from '@wagmi/vue' +``` + +Function for cleaning up watcher. + +## Action + +- [`watchBlockNumber`](/core/api/actions/watchBlockNumber) diff --git a/wagmi-project/site/vue/api/composables/useWatchContractEvent.md b/wagmi-project/site/vue/api/composables/useWatchContractEvent.md new file mode 100644 index 0000000000..5467c49a50 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useWatchContractEvent.md @@ -0,0 +1,134 @@ +# useWatchContractEvent + +Composable that watches and returns emitted contract event logs. + +## Import + +```ts +import { useWatchContractEvent } from '@wagmi/vue' +``` + +## Usage + +::: code-group +```ts [index.vue] + +``` +<<< @/snippets/abi-event.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Parameters + +```ts +import { type UseWatchContractEventParameters } from '@wagmi/vue' +``` + +### abi + +`Abi` + +The contract's ABI. Check out the [TypeScript docs](/vue/typescript#const-assert-abis-typed-data) for how to set up ABIs for maximum type inference and safety. + +### address + +`Address | undefined` + +The contract's address. + +### args + +`object | readonly unknown[] | undefined` + +- Arguments to pass when calling the contract. +- Inferred from [`abi`](#abi) and [`eventName`](#eventname). + +### batch + +`boolean | undefined` + +- Whether or not the events should be batched on each invocation. +- Defaults to `true`. + +### chainId + +`config['chains'][number]['id'] | undefined` + +ID of chain to use when fetching data. + +### config + +`Config | undefined` + +[`Config`](/react/api/createConfig#config) to use instead of retrieving from the nearest [`WagmiProvider`](/react/api/WagmiProvider). + +### eventName + +`string` + +- Event to listen for the contract. +- Inferred from [`abi`](#abi). + +### onError + +`((error: Error) => void) | undefined` + +Error thrown from getting the block number. + +### onLogs + +`(logs: Log[], prevLogs: Log[] | undefined) => void` + +Callback for when logs changes. + +### poll + +`boolean | undefined` + +- Whether or not to use a polling mechanism to check for new blocks instead of a WebSocket subscription. +- Defaults to `false` for WebSocket Clients, and `true` for non-WebSocket Clients. + +### pollingInterval + +`number | undefined` + +- Polling frequency (in milliseconds). +- Defaults to the [Config's `pollingInterval` config](/core/api/createConfig#pollinginterval). + +### strict + +`boolean | undefined` + +- Defaults to `false`. + +### syncConnectedChain + +`boolean | undefined` + +- Set up subscriber for connected chain changes. +- Defaults to [`Config['syncConnectedChain']`](/core/api/createConfig#syncconnectedchain). + +## Return Type + +```ts +import { type UseWatchContractEventReturnType } from '@wagmi/vue' +``` + +Hook returns `void` + +## Action + +- [`watchContractEvent`](/core/api/actions/watchContractEvent) + diff --git a/wagmi-project/site/vue/api/composables/useWriteContract.md b/wagmi-project/site/vue/api/composables/useWriteContract.md new file mode 100644 index 0000000000..1221345851 --- /dev/null +++ b/wagmi-project/site/vue/api/composables/useWriteContract.md @@ -0,0 +1,112 @@ +--- +title: useWriteContract +description: Composable for executing a write function on a contract. +--- + + + +# useWriteContract + +Composable for executing a write function on a contract. + +A "write" function on a Solidity contract modifies the state of the blockchain. These types of functions require gas to be executed, hence a transaction is broadcasted in order to change the state. + +## Import + +```ts +import { useWriteContract } from '@wagmi/vue' +``` + +## Usage + +::: code-group + +```vue [index.vue] + + + +``` + +<<< @/snippets/abi-write.ts[abi.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + + + + + +## Parameters + +```ts +import { type UseWriteContractParameters } from '@wagmi/vue' +``` + +### config + +`Config | undefined` + +[`Config`](/vue/api/createConfig#config) to use instead of retrieving from the [`WagmiPlugin`](/vue/api/WagmiPlugin). + +::: code-group + +```vue [index.vue] + +``` + +<<< @/snippets/vue/config.ts[config.ts] +::: + + + +## Return Type + +```ts +import { type UseWriteContractReturnType } from '@wagmi/vue' +``` + +The return type's [`data`](#data) property is inferrable via the combination of [`abi`](#abi), [`functionName`](#functionname), and [`args`](#args). Check out the [TypeScript docs](/vue/typescript#const-assert-abis-typed-data) for more info. + + + +## Type Inference + +With [`abi`](/core/api/actions/writeContract#abi) setup correctly, TypeScript will infer the correct types for [`functionName`](/core/api/actions/writeContract#functionname), [`args`](/core/api/actions/writeContract#args), and the [`value`](/core/api/actions/writeContract##value). See the Wagmi [TypeScript docs](/vue/typescript) for more information. + + + +## Action + +- [`writeContract`](/core/api/actions/writeContract) diff --git a/wagmi-project/site/vue/api/connectors.md b/wagmi-project/site/vue/api/connectors.md new file mode 100644 index 0000000000..6d3a189936 --- /dev/null +++ b/wagmi-project/site/vue/api/connectors.md @@ -0,0 +1,28 @@ + + +# Connectors + +Connectors for popular wallet providers and protocols. + +## Import + +Import via the `'@wagmi/vue/connectors'` entrypoint. + +```ts +import { injected } from '@wagmi/vue/connectors' +``` + +## Available Connectors + + diff --git a/wagmi-project/site/vue/api/connectors/coinbaseWallet.md b/wagmi-project/site/vue/api/connectors/coinbaseWallet.md new file mode 100644 index 0000000000..839a80f567 --- /dev/null +++ b/wagmi-project/site/vue/api/connectors/coinbaseWallet.md @@ -0,0 +1,6 @@ + + + \ No newline at end of file diff --git a/wagmi-project/site/vue/api/connectors/injected.md b/wagmi-project/site/vue/api/connectors/injected.md new file mode 100644 index 0000000000..45c5e158e0 --- /dev/null +++ b/wagmi-project/site/vue/api/connectors/injected.md @@ -0,0 +1,7 @@ + + + diff --git a/wagmi-project/site/vue/api/connectors/metaMask.md b/wagmi-project/site/vue/api/connectors/metaMask.md new file mode 100644 index 0000000000..30d15d7794 --- /dev/null +++ b/wagmi-project/site/vue/api/connectors/metaMask.md @@ -0,0 +1,7 @@ + + + diff --git a/wagmi-project/site/vue/api/connectors/mock.md b/wagmi-project/site/vue/api/connectors/mock.md new file mode 100644 index 0000000000..532cc19fbf --- /dev/null +++ b/wagmi-project/site/vue/api/connectors/mock.md @@ -0,0 +1,6 @@ + + + diff --git a/wagmi-project/site/vue/api/connectors/safe.md b/wagmi-project/site/vue/api/connectors/safe.md new file mode 100644 index 0000000000..85fb516ca7 --- /dev/null +++ b/wagmi-project/site/vue/api/connectors/safe.md @@ -0,0 +1,6 @@ + + + diff --git a/wagmi-project/site/vue/api/connectors/walletConnect.md b/wagmi-project/site/vue/api/connectors/walletConnect.md new file mode 100644 index 0000000000..c3840c3979 --- /dev/null +++ b/wagmi-project/site/vue/api/connectors/walletConnect.md @@ -0,0 +1,6 @@ + + + diff --git a/wagmi-project/site/vue/api/createConfig.md b/wagmi-project/site/vue/api/createConfig.md new file mode 100644 index 0000000000..8210634c08 --- /dev/null +++ b/wagmi-project/site/vue/api/createConfig.md @@ -0,0 +1,7 @@ + + + diff --git a/wagmi-project/site/vue/api/createStorage.md b/wagmi-project/site/vue/api/createStorage.md new file mode 100644 index 0000000000..f4901773c1 --- /dev/null +++ b/wagmi-project/site/vue/api/createStorage.md @@ -0,0 +1,6 @@ + + + diff --git a/wagmi-project/site/vue/api/errors.md b/wagmi-project/site/vue/api/errors.md new file mode 100644 index 0000000000..d914152150 --- /dev/null +++ b/wagmi-project/site/vue/api/errors.md @@ -0,0 +1,10 @@ + + +# Errors + +Error classes used by Wagmi. + + \ No newline at end of file diff --git a/wagmi-project/site/vue/api/transports.md b/wagmi-project/site/vue/api/transports.md new file mode 100644 index 0000000000..c35d06b631 --- /dev/null +++ b/wagmi-project/site/vue/api/transports.md @@ -0,0 +1,28 @@ + + +# Transports + +[`createConfig`](/vue/api/createConfig) can be instantiated with a set of Transports for each chain. A Transport is the intermediary layer that is responsible for executing outgoing JSON-RPC requests to the RPC Provider (e.g. Alchemy, Infura, etc). + +## Import + +```ts +import { http } from '@wagmi/vue' +``` + +## Built-In Transports + +Available via the `'@wagmi/vue'` entrypoint. + + diff --git a/wagmi-project/site/vue/api/transports/custom.md b/wagmi-project/site/vue/api/transports/custom.md new file mode 100644 index 0000000000..4ece9d2d46 --- /dev/null +++ b/wagmi-project/site/vue/api/transports/custom.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/vue/api/transports/fallback.md b/wagmi-project/site/vue/api/transports/fallback.md new file mode 100644 index 0000000000..084762db3b --- /dev/null +++ b/wagmi-project/site/vue/api/transports/fallback.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/vue/api/transports/http.md b/wagmi-project/site/vue/api/transports/http.md new file mode 100644 index 0000000000..93e1fc3c93 --- /dev/null +++ b/wagmi-project/site/vue/api/transports/http.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/vue/api/transports/unstable_connector.md b/wagmi-project/site/vue/api/transports/unstable_connector.md new file mode 100644 index 0000000000..8bb1bfc52f --- /dev/null +++ b/wagmi-project/site/vue/api/transports/unstable_connector.md @@ -0,0 +1,6 @@ + + + diff --git a/wagmi-project/site/vue/api/transports/webSocket.md b/wagmi-project/site/vue/api/transports/webSocket.md new file mode 100644 index 0000000000..3559e6ff89 --- /dev/null +++ b/wagmi-project/site/vue/api/transports/webSocket.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/vue/api/utilities/deserialize.md b/wagmi-project/site/vue/api/utilities/deserialize.md new file mode 100644 index 0000000000..871aabe907 --- /dev/null +++ b/wagmi-project/site/vue/api/utilities/deserialize.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/vue/api/utilities/serialize.md b/wagmi-project/site/vue/api/utilities/serialize.md new file mode 100644 index 0000000000..63abbda162 --- /dev/null +++ b/wagmi-project/site/vue/api/utilities/serialize.md @@ -0,0 +1,5 @@ + + + diff --git a/wagmi-project/site/vue/getting-started.md b/wagmi-project/site/vue/getting-started.md new file mode 100644 index 0000000000..c36bceab02 --- /dev/null +++ b/wagmi-project/site/vue/getting-started.md @@ -0,0 +1,217 @@ + + +# Getting Started + +## Overview + +Wagmi is a collection of Vue composition utilities for Ethereum. You can learn more about the rationale behind the project in the [Why Wagmi](/vue/why) section. + +## Automatic Installation + +For new projects, it is recommended to set up your Wagmi app using the [`create-wagmi`](/cli/create-wagmi) command line interface (CLI). This will create a new Wagmi project using TypeScript and install the required dependencies. + +::: code-group +```bash [pnpm] +pnpm create wagmi +``` + +```bash [npm] +npm create wagmi@latest +``` + +```bash [yarn] +yarn create wagmi +``` + +```bash [bun] +bun create wagmi +``` +::: + +Once the command runs, you'll see some prompts to complete. + +```ansi +Project name: wagmi-project +Select a framework: Vue / Vanilla +... +``` + +After the prompts, `create-wagmi` will create a directory with your project name and install the required dependencies. Check out the `README.md` for further instructions (if required). + +## Manual Installation + +To manually add Wagmi to your project, install the required packages. + +::: code-group +```bash-vue [pnpm] +pnpm add @wagmi/vue viem@{{viemVersion}} @tanstack/vue-query +``` + +```bash-vue [npm] +npm install @wagmi/vue viem@{{viemVersion}} @tanstack/vue-query +``` + +```bash-vue [yarn] +yarn add @wagmi/vue viem@{{viemVersion}} @tanstack/vue-query +``` + +```bash-vue [bun] +bun add @wagmi/vue viem@{{viemVersion}} @tanstack/vue-query +``` +::: + +- [Viem](https://viem.sh) is a TypeScript interface for Ethereum that performs blockchain operations. +- [TanStack Query](https://tanstack.com/query/v5) is an async state manager that handles requests, caching, and more. +- [TypeScript](/vue/typescript) is optional, but highly recommended. Learn more about [TypeScript support](/vue/typescript). + +### Create Config + +Create and export a new Wagmi config using `createConfig`. + +::: code-group +<<< @/snippets/vue/config.ts[config.ts] +::: + +In this example, Wagmi is configured to use the Mainnet and Sepolia chains, and `injected` connector. Check out the [`createConfig` docs](/vue/api/createConfig) for more configuration options. + +::: details TypeScript Tip +If you are using TypeScript, you can "register" the Wagmi config or use the hook `config` property to get strong type-safety in places that wouldn't normally have type info. + +::: code-group +```ts twoslash [register config] +// @errors: 2322 +import { type Config } from '@wagmi/vue' +import { mainnet, sepolia } from '@wagmi/vue/chains' + +declare const config: Config +// ---cut--- +import { useBlockNumber } from '@wagmi/vue' + +useBlockNumber({ chainId: 123 }) + +declare module '@wagmi/vue' { + interface Register { + config: typeof config + } +} +``` + +```ts twoslash [hook config property] +// @errors: 2322 +import { type Config } from '@wagmi/vue' +import { mainnet, sepolia } from '@wagmi/vue/chains' + +declare const config: Config +// ---cut--- +import { useBlockNumber } from '@wagmi/vue' + +useBlockNumber({ chainId: 123, config }) +``` + +By registering or using the hook `config` property, `useBlockNumber`'s `chainId` is strongly typed to only allow Mainnet and Sepolia IDs. Learn more by reading the [TypeScript docs](/vue/typescript#config-types). +::: + +### Add Plugin to App + +Add the `WagmiPlugin` to your app instance and pass the `config` you created earlier to the plugin options. + +::: code-group +```tsx [main.ts] +import { WagmiPlugin } from '@wagmi/vue' // [!code focus] +import { createApp } from 'vue' +import { config } from './config' // [!code focus] +import App from './App.vue' + +createApp(App) + .use(WagmiPlugin, { config }) // [!code focus] + .mount('#app') +``` +```vue [App.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +Check out the [`WagmiPlugin` docs](/vue/api/WagmiPlugin) to learn more about the plugin API. + +### Setup TanStack Query + +After the `WagmiPlugin`, attach the `VueQueryPlugin` to your app, and pass a new `QueryClient` instance to the `queryClient` property. + +::: code-group +```tsx [main.ts] +import { QueryClient, VueQueryPlugin } from '@tanstack/vue-query' // [!code focus] +import { WagmiPlugin } from '@wagmi/vue' +import { createApp } from 'vue' +import { config } from './config' +import App from './App.vue' + +const queryClient = new QueryClient() // [!code focus] + +createApp(App) + .use(WagmiPlugin, { config }) + .use(VueQueryPlugin, { queryClient }) // [!code focus] + .mount('#app') +``` +```vue [App.vue] + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + +Check out the [TanStack Query docs](https://tanstack.com/query/latest/docs/framework/vue) to learn about the library, APIs, and more. + +### Use Wagmi + +Now that everything is set up, every component inside your app can use Wagmi Vue Composables. + +::: code-group +```vue [App.vue] + + + +``` +```tsx [main.ts] +import { QueryClient, VueQueryPlugin } from '@tanstack/vue-query' +import { WagmiPlugin } from '@wagmi/vue' +import { createApp } from 'vue' +import { config } from './config' +import App from './App.vue' + +const queryClient = new QueryClient() + +createApp(App) + .use(WagmiPlugin, { config }) + .use(VueQueryPlugin, { queryClient }) + .mount('#app') +``` +<<< @/snippets/vue/config.ts[config.ts] +::: + + +## Next Steps + +For more information on what to do next, check out the following topics. + +- [**TypeScript**](/vue/typescript) Learn how to get the most out of Wagmi's type-safety and inference for an enlightened developer experience. +- [**Connect Wallet**](/vue/guides/connect-wallet) Learn how to enable wallets to connect to and disconnect from your apps and display information about connected accounts. +- [**Vue Composables**](/vue/api/composables) Browse the collection of Vue Composables and learn how to use them. +- [**Viem**](/vue/guides/viem) Learn about Viem and how it works with Wagmi. + diff --git a/wagmi-project/site/vue/guides/chain-properties.md b/wagmi-project/site/vue/guides/chain-properties.md new file mode 100644 index 0000000000..0f41ef41c9 --- /dev/null +++ b/wagmi-project/site/vue/guides/chain-properties.md @@ -0,0 +1,97 @@ +# Chain Properties + +Some chains support additional properties related to blocks and transactions. This is powered by Viem's [formatters](https://viem.sh/docs/chains/formatters) and [serializers](https://viem.sh/docs/chains/serializers). For example, Celo, ZkSync, OP Stack chains support all support additional properties. In order to use these properties in a type-safe way, there are a few things you should be aware of. + +
+ +::: tip +Make sure you follow the TypeScript guide's [Config Types](/vue/typescript#config-types) section before moving on. The easiest way to do this is to use [Declaration Merging](/vue/typescript#declaration-merging) to "register" your `config` globally with TypeScript. + +<<< @/snippets/vue/config-chain-properties.ts[config.ts] +::: + +## Narrowing Parameters + +Once your Config is registered with TypeScript, you are ready to access chain-specific properties! For example, Celo's `feeCurrency` is available. + +::: code-group +```ts [index.tsx] +import { parseEther } from 'viem' +import { useSimulateContract } from '@wagmi/vue' + +const result = useSimulateContract({ + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + feeCurrency: '0x…', // [!code focus] +}) +``` +<<< @/snippets/vue/config-chain-properties.ts[config.ts] +::: + +This is great, but if you have multiple chains that support additional properties, your autocomplete could be overwhelmed with all of them. By setting the `chainId` property to a specific value (e.g. `celo.id`), you can narrow parameters to a single chain. + +::: code-group +```ts [index.tsx] +import { parseEther } from 'viem' +import { useSimulateContract } from '@wagmi/vue' +import { celo } from '@wagmi/vue/chains' + +const result = useSimulateContract({ + to: '0xd2135CfB216b74109775236E36d4b433F1DF507B', + value: parseEther('0.01'), + chainId: celo.id, // [!code focus] + feeCurrency: '0x…', // [!code focus] + // ^? (property) feeCurrency?: `0x${string}` | undefined // [!code focus] +}) +``` +<<< @/snippets/vue/config-chain-properties.ts[config.ts] +::: + +## Narrowing Return Types + +Return types can also have chain-specific properties attached to them. There are a couple approaches for extracting these properties. + +### `chainId` Parameter + +Not only can you use the `chainId` parameter to [narrow parameters](#narrowing-parameters), you can also use it to narrow the return type. + +::: code-group +```ts [index.tsx] +import { useWaitForTransactionReceipt } from '@wagmi/vue' +import { zkSync } from '@wagmi/vue/chains' + +const { data } = useWaitForTransactionReceipt({ + chainId: zkSync.id, + hash: '0x16854fcdd0219cacf5aec5e4eb2154dac9e406578a1510a6fc48bd0b67e69ea9', +}) + +data?.logs +// ^? (property) logs: ZkSyncLog[] | undefined +``` +<<< @/snippets/vue/config-chain-properties.ts[config.ts] +::: + +### `chainId` Data Property + +Wagmi internally will set a `chainId` property on return types that you can use to narrow results. The `chainId` is determined from the `chainId` parameter or global state (e.g. connector). You can use this property to help TypeScript narrow the type. + +::: code-group +```ts [index.tsx] +import { useWaitForTransactionReceipt } from '@wagmi/vue' +import { zkSync } from '@wagmi/vue/chains' + +const { data } = useWaitForTransactionReceipt({ + hash: '0x16854fcdd0219cacf5aec5e4eb2154dac9e406578a1510a6fc48bd0b67e69ea9', +}) + +if (data?.chainId === zkSync.id) { + data?.logs + // ^? (property) logs: ZkSyncLog[] | undefined +} +``` +<<< @/snippets/vue/config-chain-properties.ts[config.ts] +::: + +## Troubleshooting + +If chain properties aren't working, make sure [TypeScript](/vue/guides/faq#type-inference-doesn-t-work) is configured correctly. Not all chains have additional properties, to check which ones do, see the [Viem repo](https://github.com/wevm/viem/tree/main/src/chains) (chains that have a top-level directory under [`src/chains`](https://github.com/wevm/viem/tree/main/src/chains) support additional properties). diff --git a/wagmi-project/site/vue/guides/connect-wallet.md b/wagmi-project/site/vue/guides/connect-wallet.md new file mode 100644 index 0000000000..89e795ac72 --- /dev/null +++ b/wagmi-project/site/vue/guides/connect-wallet.md @@ -0,0 +1,387 @@ +# Connect Wallet + +The ability for a user to connect their wallet is a core function for any Dapp. It allows users to perform tasks such as: writing to contracts, signing messages, or sending transactions. + +Wagmi contains everything you need to get started with building a Connect Wallet module. To get started, you can either use a [third-party library](#third-party-libraries) or [build your own](#build-your-own). + +## Third-party Libraries + +You can use a pre-built Connect Wallet module from a third-party library such as: + +- [AppKit](https://walletconnect.com/appkit) - [Guide](https://docs.walletconnect.com/appkit/vue/core/installation) + +The above libraries are all built on top of Wagmi, handle all the edge cases around wallet connection, and provide a seamless Connect Wallet UX that you can use in your Dapp. + +## Build Your Own + +Wagmi provides you with the Composables to get started building your own Connect Wallet module. + +It takes less than five minutes to get up and running with Browser Wallets, WalletConnect, and Coinbase Wallet. + +### 1. Configure Wagmi + +Before we get started with building the functionality of the Connect Wallet module, we will need to set up the Wagmi configuration. + +Let's create a `config.ts` file and export a `config` object. + +::: code-group + +```tsx [config.ts] +import { http, createConfig } from '@wagmi/vue' +import { base, mainnet, optimism } from '@wagmi/vue/chains' +import { injected, metaMask, safe, walletConnect } from '@wagmi/vue/connectors' + +const projectId = '' + +export const config = createConfig({ + chains: [mainnet, base], + connectors: [ + injected(), + walletConnect({ projectId }), + metaMask(), + safe(), + ], + transports: { + [mainnet.id]: http(), + [base.id]: http(), + }, +}) +``` + +::: + +In the above configuration, we want to set up connectors for Injected (browser), WalletConnect (browser + mobile), MetaMask, and Safe wallets. This configuration uses the **Mainnet** and **Base** chains, but you can use whatever you want. + +::: warning + +Make sure to replace the `projectId` with your own WalletConnect Project ID, if you wish to use WalletConnect! + +[Get your Project ID](https://cloud.walletconnect.com/) + +::: + +### 2. Inject the WagmiPlugin onto your App + +Next, we will need to inject our App with plugins so that our application is aware of Wagmi & Vue Query's reactive state and in-memory caching. + +::: code-group + +```ts [main.ts] +// 1. Import modules. +import { VueQueryPlugin } from '@tanstack/vue-query'; +import { WagmiPlugin } from '@wagmi/vue'; +import { createApp } from 'vue'; + +import App from './App.vue'; +import { config } from './wagmi'; + +createApp(App) + // 2. Inject the Wagmi plugin. + .use(WagmiPlugin, { config }) + // 3. Inject the Vue Query plugin. + .use(VueQueryPlugin, {}) + .mount('#app'); +``` + +```vue [App.vue] + + + +``` + +```ts [config.ts] +import { http, createConfig } from '@wagmi/vue' +import { base, mainnet, optimism } from '@wagmi/vue/chains' +import { injected, metaMask, safe, walletConnect } from '@wagmi/vue/connectors' + +const projectId = '' + +export const config = createConfig({ + chains: [mainnet, base], + connectors: [ + injected(), + walletConnect({ projectId }), + metaMask(), + safe(), + ], + transports: { + [mainnet.id]: http(), + [base.id]: http(), + }, +}) +``` + +::: + +### 3. Display Wallet Options + +After that, we will create a `Connect` component that will display our connectors. This will allow users to select a wallet and connect. + +Below, we are rendering a list of `connectors` retrieved from `useConnect`. When the user clicks on a connector, the `connect` function will connect the users' wallet. + +::: code-group + +```vue [Connect.vue] + + + +``` + +```vue [App.vue] + + + +``` + +```ts [main.ts] +// 1. Import modules. +import { VueQueryPlugin } from '@tanstack/vue-query'; +import { WagmiPlugin } from '@wagmi/vue'; +import { createApp } from 'vue'; + +import App from './App.vue'; +import { config } from './wagmi'; + +createApp(App) + // 2. Inject the Wagmi plugin. + .use(WagmiPlugin, { config }) + // 3. Inject the Vue Query plugin. + .use(VueQueryPlugin, {}) + .mount('#app'); +``` + +```ts [config.ts] +import { http, createConfig } from '@wagmi/vue' +import { base, mainnet, optimism } from '@wagmi/vue/chains' +import { injected, metaMask, safe, walletConnect } from '@wagmi/vue/connectors' + +const projectId = '' + +export const config = createConfig({ + chains: [mainnet, base], + connectors: [ + injected(), + walletConnect({ projectId }), + metaMask(), + safe(), + ], + transports: { + [mainnet.id]: http(), + [base.id]: http(), + }, +}) +``` + +::: + +### 4. Display Connected Account + +Lastly, if an account is connected, we want to show some basic information, like the connected address and ENS name and avatar. + +Below, we are using hooks like `useAccount`, `useEnsAvatar` and `useEnsName` to extract this information. + +We are also utilizing `useDisconnect` to show a "Disconnect" button so a user can disconnect their wallet. + +::: code-group + +```vue [Account.vue] + + + +``` + +```vue [Connect.vue] + + + +``` + +```vue [App.vue] + + + +``` + +```ts [main.ts] +// 1. Import modules. +import { VueQueryPlugin } from '@tanstack/vue-query'; +import { WagmiPlugin } from '@wagmi/vue'; +import { createApp } from 'vue'; + +import App from './App.vue'; +import { config } from './wagmi'; + +createApp(App) + // 2. Inject the Wagmi plugin. + .use(WagmiPlugin, { config }) + // 3. Inject the Vue Query plugin. + .use(VueQueryPlugin, {}) + .mount('#app'); +``` + +```ts [config.ts] +import { http, createConfig } from '@wagmi/vue' +import { base, mainnet, optimism } from '@wagmi/vue/chains' +import { injected, metaMask, safe, walletConnect } from '@wagmi/vue/connectors' + +const projectId = '' + +export const config = createConfig({ + chains: [mainnet, base], + connectors: [ + injected(), + walletConnect({ projectId }), + metaMask(), + safe(), + ], + transports: { + [mainnet.id]: http(), + [base.id]: http(), + }, +}) +``` + +::: + +### 5. Wire it up! + +Finally, we can wire up our Connect and Account components to our application's entrypoint. + +::: code-group + +```vue [App.vue] + + + + +``` + +```vue [Account.vue] + + + +``` + +```vue [Connect.vue] + + + +``` + +```ts [main.ts] +// 1. Import modules. +import { VueQueryPlugin } from '@tanstack/vue-query'; +import { WagmiPlugin } from '@wagmi/vue'; +import { createApp } from 'vue'; + +import App from './App.vue'; +import { config } from './wagmi'; + +createApp(App) + // 2. Inject the Wagmi plugin. + .use(WagmiPlugin, { config }) + // 3. Inject the Vue Query plugin. + .use(VueQueryPlugin, {}) + .mount('#app'); +``` + +```ts [config.ts] +import { http, createConfig } from '@wagmi/vue' +import { base, mainnet, optimism } from '@wagmi/vue/chains' +import { injected, metaMask, safe, walletConnect } from '@wagmi/vue/connectors' + +const projectId = '' + +export const config = createConfig({ + chains: [mainnet, base], + connectors: [ + injected(), + walletConnect({ projectId }), + metaMask(), + safe(), + ], + transports: { + [mainnet.id]: http(), + [base.id]: http(), + }, +}) +``` + +::: + +### Playground + +Want to see the above steps all wired up together in an end-to-end example? Check out the below StackBlitz playground. + +
+ + diff --git a/wagmi-project/site/vue/guides/error-handling.md b/wagmi-project/site/vue/guides/error-handling.md new file mode 100644 index 0000000000..8cb7e9b507 --- /dev/null +++ b/wagmi-project/site/vue/guides/error-handling.md @@ -0,0 +1,39 @@ +# Error Handling + +The `error` property in Wagmi Composables is strongly typed with it's corresponding error type. This enables you to have granular precision with handling errors in your application. + +You can discriminate the error type by using the `name` property on the error object. + +::: code-group +```vue twoslash [index.vue] + + + +``` +<<< @/snippets/vue/config.ts[config.ts] +::: diff --git a/wagmi-project/site/vue/guides/faq.md b/wagmi-project/site/vue/guides/faq.md new file mode 100644 index 0000000000..61def1c79d --- /dev/null +++ b/wagmi-project/site/vue/guides/faq.md @@ -0,0 +1,9 @@ + + +# FAQ / Troubleshooting + +Collection of frequently asked questions with ideas on how to troubleshoot and resolve them. + + diff --git a/wagmi-project/site/vue/guides/read-from-contract.md b/wagmi-project/site/vue/guides/read-from-contract.md new file mode 100644 index 0000000000..8bf78acc91 --- /dev/null +++ b/wagmi-project/site/vue/guides/read-from-contract.md @@ -0,0 +1,206 @@ +# Read from Contract + +## Overview + +The [`useReadContract` Composable](/vue/api/composables/useReadContract) allows you to read data on a smart contract, from a `view` or `pure` (read-only) function. They can only read the state of the contract, and cannot make any changes to it. Since read-only methods do not change the state of the contract, they do not require any gas to be executed, and can be called by any user without the need to pay for gas. + +The component below shows how to retrieve the token balance of an address from the [Wagmi Example](https://etherscan.io/token/0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2) contract + +:::code-group + +```vue [ReadContract.vue] + + + +``` +```ts [contracts.ts] +export const wagmiContractConfig = { + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi: [ + { + type: 'function', + name: 'balanceOf', + stateMutability: 'view', + inputs: [{ name: 'account', type: 'address' }], + outputs: [{ type: 'uint256' }], + }, + { + type: 'function', + name: 'totalSupply', + stateMutability: 'view', + inputs: [], + outputs: [{ name: 'supply', type: 'uint256' }], + }, + ], +} as const +``` +::: + + +If `useReadContract` depends on another value (`address` in the example below), you can use the [`query.enabled`](/vue/api/composables/useReadContract#enabled) option to prevent the query from running until the dependency is ready. + +```tsx +const { data: balance } = useReadContract({ + ...wagmiContractConfig, + functionName: 'balanceOf', + args: [address], + query: { // [!code focus] + enabled: !!address, // [!code focus] + }, // [!code focus] +}) +``` + + +## Loading & Error States + +The [`useReadContract` Composable](/vue/api/composables/useReadContract) also returns loading & error states, which can be used to display a loading indicator while the data is being fetched, or an error message if contract execution reverts. + +:::code-group + +```vue [ReadContract.vue] + + + +``` + +::: + + + + diff --git a/wagmi-project/site/vue/guides/send-transaction.md b/wagmi-project/site/vue/guides/send-transaction.md new file mode 100644 index 0000000000..6686e720be --- /dev/null +++ b/wagmi-project/site/vue/guides/send-transaction.md @@ -0,0 +1,311 @@ +# Send Transaction + +The following guide teaches you how to send transactions in Wagmi. The example below builds on the [Connect Wallet guide](/vue/guides/connect-wallet) and uses the [useSendTransaction](/vue/api/composables/useSendTransaction) & [useWaitForTransaction](/vue/api/composables/useWaitForTransactionReceipt) composables. + +## Example + +Feel free to check out the example before moving on: + + + +## Steps + +### 1. Connect Wallet + +Follow the [Connect Wallet guide](/vue/guides/connect-wallet) guide to get this set up. + +### 2. Create a new component + +Create your `SendTransaction` component that will contain the send transaction logic. + +::: code-group + +```tsx [SendTransaction.vue] + + + +``` + +::: + +### 3. Add a form handler + +Next, we will need to add a handler to the form that will send the transaction when the user hits "Send". This will be a basic handler in this step. + +::: code-group + +```vue [SendTransaction.vue] + + + +``` + +::: + +### 4. Hook up the `useSendTransaction` Composable + +Now that we have the form handler, we can hook up the [`useSendTransaction` Composable](/vue/api/composables/useSendTransaction) to send the transaction. + +::: code-group + +```vue [SendTransaction.vue] + + + +``` + +::: + +### 5. Add loading state (optional) + +We can optionally add a loading state to the "Send" button while we are waiting confirmation from the user's wallet. + +::: code-group + +```vue [SendTransaction.vue] + + + +``` + +::: + +### 6. Wait for transaction receipt (optional) + +We can also display the transaction confirmation status to the user by using the [`useWaitForTransactionReceipt` Composable](/vue/api/composables/useWaitForTransactionReceipt). + +::: code-group + +```vue [SendTransaction.vue] + + + +``` + +::: + +### 7. Handle errors (optional) + +If the user rejects the transaction, or the user does not have enough funds to cover the transaction, we can display an error message to the user. + +::: code-group + +```vue [SendTransaction.vue] + + + +``` + +::: + +### 8. Wire it up! + +Finally, we can wire up our Send Transaction component to our application's entrypoint. + +:::code-group +```vue [App.vue] + + + +``` +```vue [SendTransaction.vue] + + + +``` +::: + +[See the Example.](#example) diff --git a/wagmi-project/site/vue/guides/ssr.md b/wagmi-project/site/vue/guides/ssr.md new file mode 100644 index 0000000000..bf6fc4e2e9 --- /dev/null +++ b/wagmi-project/site/vue/guides/ssr.md @@ -0,0 +1,77 @@ +--- +outline: deep +--- + +# SSR + +Wagmi uses client-only external stores (such as `localStorage` and `mipd`) to show the user the most relevant data as quickly as possible on first render. + +However, the caveat of using these external client stores is that frameworks which incorporate SSR (such as Next.js) will throw hydration warnings on the client when it identifies mismatches between the server-rendered HTML and the client-rendered HTML. + +To stop this from happening, you can toggle on the [`ssr`](/vue/api/createConfig#ssr) property in the Wagmi Config. + +```tsx +import { createConfig, http } from '@wagmi/vue' +import { mainnet, sepolia } from '@wagmi/vue/chains' + +const config = createConfig({ // [!code focus:99] + chains: [mainnet, sepolia], + ssr: true, // [!code ++] + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +``` + +Turning on the `ssr` property means that content from the external stores will be hydrated on the client after the initial mount. + +## Persistence using Cookies + +As a result of turning on the `ssr` property, external persistent stores like `localStorage` will be hydrated on the client **after the initial mount**. + +This means that you will still see a flash of "empty" data on the client (e.g. a `"disconnected"` account instead of a `"reconnecting"` account, or an empty address instead of the last connected address) until after the first mount, when the store hydrates. + +In order to persist data between the server and the client, you can use cookies. + +### 1. Set up cookie storage + +First, we will set up cookie storage in the Wagmi Config. + +```tsx +import { + createConfig, + http, + cookieStorage, // [!code ++] + createStorage // [!code ++] +} from '@wagmi/vue' +import { mainnet, sepolia } from '@wagmi/vue/chains' + +export const config = createConfig({ + chains: [mainnet, sepolia], + ssr: true, + storage: createStorage({ // [!code ++] + storage: cookieStorage, // [!code ++] + }), // [!code ++] + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +``` + +### 2. Hydrate the cookie + +Next, we will need to add some mechanisms to hydrate the stored cookie in Wagmi. + +#### Nuxt.js + +Would you like to contribute this content? Feel free to [open a Pull Request](https://github.com/wevm/wagmi/pulls)! + + +#### Vanilla SSR + +Would you like to contribute this content? Feel free to [open a Pull Request](https://github.com/wevm/wagmi/pulls)! + + + diff --git a/wagmi-project/site/vue/guides/tanstack-query.md b/wagmi-project/site/vue/guides/tanstack-query.md new file mode 100644 index 0000000000..9d5efb4d7a --- /dev/null +++ b/wagmi-project/site/vue/guides/tanstack-query.md @@ -0,0 +1,287 @@ +# TanStack Query + +Wagmi Composables are not only a wrapper around the core [Wagmi Actions](/core/api/actions), but they also utilize [TanStack Query](https://tanstack.com/query/v5) to enable trivial and intuitive fetching, caching, synchronizing, and updating of asynchronous data in your Vue applications. + +Without an asynchronous data fetching abstraction, you would need to handle all the negative side-effects that comes as a result, such as: representing finite states (loading, error, success), handling race conditions, caching against a deterministic identifier, etc. + +## Queries & Mutations + +Wagmi Composables represent either a **Query** or a **Mutation**. + +**Queries** are used for fetching data (e.g. fetching a block number, reading from a contract, etc), and are typically invoked on mount by default. All queries are coupled to a unique [Query Key](#query-keys), and can be used for further operations such as refetching, prefetching, or modifying the cached data. + +**Mutations** are used for mutating data (e.g. connecting/disconnecting accounts, writing to a contract, switching chains, etc), and are typically invoked in response to a user interaction. Unlike **Queries**, they are not coupled with a query key. + +## Terms + +- **Query**: An asynchronous data fetching (e.g. read data) operation that is tied against a unique Query Key. +- **Mutation**: An asynchronous mutating (e.g. create/update/delete data or side-effect) operation. +- **Query Key**: A unique identifier that is used to deterministically identify a query. It is typically a tuple of the query name and the query arguments. +- **Stale Data**: Data that is unused or inactive after a certain period of time. +- **Query Fetching**: The process of invoking an async query function. +- **Query Refetching**: The process of refetching **rendered** queries. +- **[Query Invalidation](https://tanstack.com/query/v5/docs/vue/guides/query-invalidation)**: The process of marking query data as stale (e.g. inactive/unused), and refetching **rendered** queries. +- **[Query Prefetching](https://tanstack.com/query/v5/docs/vue/guides/prefetching)**: The process of prefetching queries and seeding the cache. + + + +## Query Keys + +Query Keys are typically used to perform advanced operations on the query such as: invalidation, refetching, prefetching, etc. + +Wagmi exports Query Keys for every Composable, and they can be retrieved via the [Composable (Vue)](#composable-vue) or via an [Import (Vanilla JS)](#import-vanilla-js). + +Read more about **Query Keys** on the [TanStack Query docs.](https://tanstack.com/query/v5/docs/vue/guides/query-keys) + +### Composable (Vue) + +Each Composable returns a `queryKey` value. You would use this approach when you want to utilize the query key in a Vue component as it handles reactivity for you, unlike the [Import](#import-vanilla-js) method below. + +```vue [index.vue] + + + +``` + +### Import (Vanilla JS) + +Each Hook has a corresponding `getQueryOptions` function that returns a query key. You would use this method when you want to utilize the query key outside of a Vue component in a Vanilla JS context, like in a utility function. + +```ts +import { getBalanceQueryOptions } from '@wagmi/vue/query' // [!code hl] +import { config } from './config' + +function perform() { + const { queryKey } = getBalanceQueryOptions(config, { // [!code hl] + chainId: config.state.chainId // [!code hl] + }) // [!code hl] +} +``` + +::: warning + +The caveat of this method is that it does not handle reactivity for you (e.g. active account/chain changes, argument changes, etc). You would need to handle this yourself by explicitly passing through the arguments to `getQueryOptions`. + +::: + +## Invalidating Queries + +Invalidating a query is the process of marking the query data as stale (e.g. inactive/unused), and refetching the queries that are already rendered. + +Read more about **Invalidating Queries** on the [TanStack Query docs.](https://tanstack.com/query/v5/docs/vue/guides/query-invalidation) + +#### Example: Watching a Users' Balance + +You may want to "watch" a users' balance, and invalidate the balance after each incoming block. We can invoke `invalidateQueries` inside a `watchEffect` – this will refetch all rendered balance queries when the `blockNumber` changes. + +```vue + + + +``` + +#### Example: After User Interaction + +Maybe you want to invalidate a users' balance after some interaction. This would mark the balance as stale, and consequently refetch all rendered balance queries. + +```vue + + + +``` + +```vue + + + +``` + +## Fetching Queries + +Fetching a query is the process of invoking the query function to retrieve data. If the query exists and the data is not invalidated or older than a given `staleTime`, then the data from the cache will be returned. Otherwise, the query will fetch for the latest data. + +::: code-group +```tsx [example.tsx] +import { getBlockQueryOptions } from '@wagmi/vue/query' +import { queryClient } from './main' +import { config } from './config' + +export async function fetchBlockData() { + return queryClient.fetchQuery( // [!code hl] + getBlockQueryOptions(config, { // [!code hl] + chainId: config.state.chainId, // [!code hl] + } // [!code hl] + )) // [!code hl] +} +``` +<<< @/snippets/vue/main.ts[main.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Retrieving & Updating Query Data + +You can retrieve and update query data imperatively with `getQueryData` and `setQueryData`. This is useful for scenarios where you want to retrieve or update a query outside of a Vue component. + +Note that these functions do not invalidate or refetch queries. + +::: code-group +```tsx [example.tsx] +import type { GetBalanceReturnType } from '@wagmi/vue/actions' +import { getBalanceQueryOptions } from '@wagmi/vue/query' +import { queryClient } from './app' +import { config } from './config' + +export function getBalanceData() { + return queryClient.getQueryData( // [!code hl] + getBalanceQueryOptions(config, { // [!code hl] + chainId: config.state.chainId, // [!code hl] + } // [!code hl] + )) // [!code hl] +} + +export function setBalanceData(parameters: Partial) { + return queryClient.setQueryData( // [!code hl] + getBalanceQueryOptions(config, { // [!code hl] + chainId: config.state.chainId, // [!code hl] + }, // [!code hl] + data => ({ ...data, ...parameters }) // [!code hl] + )) // [!code hl] +} +``` +<<< @/snippets/vue/main.ts[main.ts] +<<< @/snippets/vue/config.ts[config.ts] +::: + +## Prefetching Queries + +Prefetching a query is the process of fetching the data ahead of time and seeding the cache with the returned data. This is useful for scenarios where you want to fetch data before the user navigates to a page, or fetching data on the server to be reused on client hydration. + +Read more about **Prefetching Queries** on the [TanStack Query docs.](https://tanstack.com/query/v5/docs/vue/guides/prefetching) + +#### Example: Prefetching in Event Handler + +```vue + + + +``` + +## SSR + +It is possible to utilize TanStack Query's SSR strategies with Wagmi Composables & Query Keys. Check out the [SSR guide](https://tanstack.com/query/latest/docs/framework/vue/guides/ssr). + +## Devtools + +TanStack Query includes dedicated [Devtools](https://tanstack.com/query/latest/docs/framework/vue/devtools) that assist in visualizing and debugging your queries, their cache states, and much more. You will have to pass a custom `queryKeyFn` to your `QueryClient` for Devtools to correctly serialize BigInt values for display. Alternatively, You can use the `hashFn` from `@wagmi/core/query`, which already handles this serialization. + +#### Install + +::: code-group +```bash [pnpm] +pnpm i @tanstack/vue-query-devtools +``` + +```bash [npm] +npm i @tanstack/vue-query-devtools +``` + +```bash [yarn] +yarn add @tanstack/vue-query-devtools +``` + +```bash [bun] +bun i @tanstack/vue-query-devtools +``` +::: + +#### Usage + +::: code-group +```vue [App.vue] + + + +``` + +```vue [main.vue] + +``` +::: \ No newline at end of file diff --git a/wagmi-project/site/vue/guides/viem.md b/wagmi-project/site/vue/guides/viem.md new file mode 100644 index 0000000000..a4b7da32d0 --- /dev/null +++ b/wagmi-project/site/vue/guides/viem.md @@ -0,0 +1,94 @@ +# Viem + +[Viem](https://viem.sh) is a low-level TypeScript Interface for Ethereum that enables developers to interact with the Ethereum blockchain, including: JSON-RPC API abstractions, Smart Contract interaction, wallet & signing implementations, coding/parsing utilities and more. + +**Wagmi Core** is essentially a wrapper over **Viem** that provides multi-chain functionality via [Wagmi Config](/react/api/createConfig) and automatic account management via [Connectors](/react/api/connectors). + +## Leveraging Viem Actions + +All of the core [Wagmi Composables](/vue/api/composables) are friendly wrappers around [Viem Actions](https://viem.sh/docs/actions/public/introduction.html) that inject a multi-chain and connector aware [Wagmi Config](/vue/api/createConfig). + +There may be cases where you might want to dig deeper and utilize Viem Actions directly (maybe a Composable doesn't exist in Wagmi yet). In these cases, you can create your own custom Wagmi Composable by importing Viem Actions directly via `viem/actions` and plugging in a Viem Client returned by the [`useClient` Composable](/vue/api/composables/useClient). + +There are two categories of Viem Actions: + +- **[Public Actions](https://viem.sh/docs/actions/public/introduction):** Actions that are "read-only" and do not require a wallet connection. +- **[Wallet Actions](https://viem.sh/docs/actions/wallet/introduction):** Actions that interface with a Wallet and require a wallet connection. + +While it is not mandatory, it is also recommended to pair Actions with either `useQuery` or `useMutation` to effectively leverage the reactivity and caching capabilities of [Tanstack Query](/vue/guides/tanstack-query). + +### Public Actions + +The example below demonstrates how to utilize Viem's `getLogs` Action with a `useQuery` Composable to create your own abstraction akin to a `useLogs` Composable. + +```vue + +``` + +### Wallet Actions + +The example below demonstrates how to utilize Viem's `watchAsset` Action with a `useMutation` Composable to create your own abstraction akin to a `useWatchAsset` Composable. + +```vue + +``` + +## Private Key & Mnemonic Accounts + +It is possible to utilize Viem's [Private Key & Mnemonic Accounts](https://viem.sh/docs/accounts/local.html) with Wagmi by explicitly passing through the account via the `account` argument on Wagmi Actions. + +```vue + +``` + +::: info + +Wagmi currently does not support hoisting Private Key & Mnemonic Accounts to the top-level Wagmi Config – meaning you have to explicitly pass through the account to every Action. If you feel like this is a feature that should be added, please [open an discussion](https://github.com/wevm/wagmi/discussions/new?category=ideas). + +::: diff --git a/wagmi-project/site/vue/guides/write-to-contract.md b/wagmi-project/site/vue/guides/write-to-contract.md new file mode 100644 index 0000000000..9bdc788428 --- /dev/null +++ b/wagmi-project/site/vue/guides/write-to-contract.md @@ -0,0 +1,387 @@ +# Write to Contract + +The [`useWriteContract` Composable](/vue/api/composables/useWriteContract) allows you to mutate data on a smart contract, from a `payable` or `nonpayable` (write) function. These types of functions require gas to be executed, hence a transaction is broadcasted in order to change the state. + +In the guide below, we will teach you how to implement a "Mint NFT" form that takes in a dynamic argument (token ID) using Wagmi. The example below builds on the [Connect Wallet guide](/vue/guides/connect-wallet) and uses the [useWriteContract](/vue/api/composables/useWriteContract) & [useWaitForTransaction](/vue/api/composables/useWaitForTransactionReceipt) composables. + +If you have already completed the [Sending Transactions guide](/vue/guides/send-transaction), this guide will look very similar! That's because writing to a contract internally broadcasts & sends a transaction. + +## Example + +Feel free to check out the example before moving on: + + + +## Steps + +### 1. Connect Wallet + +Follow the [Connect Wallet guide](/vue/guides/connect-wallet) guide to get this set up. + +### 2. Create a new component + +Create your `MintNft` component that will contain the Mint NFT logic. + +::: code-group + +```vue [MintNft.vue] + + + +``` + +::: + +### 3. Add a form handler + +Next, we will need to add a handler to the form that will send the transaction when the user hits "Mint". This will be a basic handler in this step. + +::: code-group + +```vue [MintNft.vue] + + + +``` + +::: + +### 4. Hook up the `useWriteContract` Composable + +Now that we have the form handler, we can hook up the [`useWriteContract` Composable](/vue/api/composables/useWriteContract) to send the transaction. + +::: code-group + +```vue [MintNft.vue] + + + +``` + +```ts [abi.ts] +export const abi = [ + { + name: 'mint', + type: 'function', + stateMutability: 'nonpayable', + inputs: [{ internalType: 'uint32', name: 'tokenId', type: 'uint32' }], + outputs: [], + }, +] as const +``` + +::: + +### 5. Add loading state (optional) + +We can optionally add a loading state to the "Mint" button while we are waiting confirmation from the user's wallet. + +::: code-group + +```vue [MintNft.vue] + + + +``` + +```ts [abi.ts] +export const abi = [ + { + name: 'mint', + type: 'function', + stateMutability: 'nonpayable', + inputs: [{ internalType: 'uint32', name: 'tokenId', type: 'uint32' }], + outputs: [], + }, +] as const +``` + +::: + +### 6. Wait for transaction receipt (optional) + +We can also display the transaction confirmation status to the user by using the [`useWaitForTransactionReceipt` Composable](/vue/api/composables/useWaitForTransactionReceipt). + +::: code-group + +```vue [MintNft.vue] + + + +``` + +```ts [abi.ts] +export const abi = [ + { + name: 'mint', + type: 'function', + stateMutability: 'nonpayable', + inputs: [{ internalType: 'uint32', name: 'tokenId', type: 'uint32' }], + outputs: [], + }, +] as const +``` + +::: + +### 7. Handle errors (optional) + +If the user rejects the transaction, or the user does not have enough funds to cover the transaction, we can display an error message to the user. + +::: code-group + +```vue [MintNft.vue] + + + +``` + +```ts [abi.ts] +export const abi = [ + { + name: 'mint', + type: 'function', + stateMutability: 'nonpayable', + inputs: [{ internalType: 'uint32', name: 'tokenId', type: 'uint32' }], + outputs: [], + }, +] as const +``` + +::: + +### 8. Wire it up! + +Finally, we can wire up our Send Transaction component to our application's entrypoint. + +:::code-group +```vue [App.vue] + + + +``` + +```vue [MintNft.vue] + + + +``` + +```ts [abi.ts] +export const abi = [ + { + name: 'mint', + type: 'function', + stateMutability: 'nonpayable', + inputs: [{ internalType: 'uint32', name: 'tokenId', type: 'uint32' }], + outputs: [], + }, +] as const +``` +::: + +[See the Example.](#example) \ No newline at end of file diff --git a/wagmi-project/site/vue/installation.md b/wagmi-project/site/vue/installation.md new file mode 100644 index 0000000000..82676c43fa --- /dev/null +++ b/wagmi-project/site/vue/installation.md @@ -0,0 +1,41 @@ + + +# Installation + +Install Wagmi via your package manager, a ` + +# TypeScript + +## Requirements + +Wagmi is designed to be as type-safe as possible! Things to keep in mind: + +- Types currently require using TypeScript {{typescriptVersion}}. +- [TypeScript doesn't follow semver](https://www.learningtypescript.com/articles/why-typescript-doesnt-follow-strict-semantic-versioning) and often introduces breaking changes in minor releases. +- Changes to types in this repository are considered non-breaking and are usually released as patch changes (otherwise every type enhancement would be a major version!). +- It is highly recommended that you lock your `wagmi` and `typescript` versions to specific patch releases and upgrade with the expectation that types may be fixed or upgraded between any release. +- The non-type-related public API of Wagmi still follows semver very strictly. + +To ensure everything works correctly, make sure your `tsconfig.json` has [`strict`](https://www.typescriptlang.org/tsconfig#strict) mode set to `true`. + +::: code-group +```json [tsconfig.json] +{ + "compilerOptions": { + "strict": true + } +} +``` +::: + +## Config Types + +By default Vue Plugins does not work well with type inference. To support strong type-safety across the Vue Plugins boundary, there are two options available: + +- Declaration merging to "register" your `config` globally with TypeScript. +- `config` property to pass your `config` directly to composables. + +### Declaration Merging + +[Declaration merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html) allows you to "register" your `config` globally with TypeScript. The `Register` type enables Wagmi to infer types in places that wouldn't normally have access to type info via a Vue Plugin alone. + +To set this up, add the following declaration to your project. Below, we co-locate the declaration merging and the `config` set up. + +```ts +import { createConfig, http } from '@wagmi/vue' +import { mainnet, sepolia } from 'wagmi/chains' + +declare module '@wagmi/vue' { // [!code focus] + interface Register { // [!code focus] + config: typeof config // [!code focus] + } // [!code focus] +} // [!code focus] + +export const config = createConfig({ + chains: [mainnet, sepolia], + transports: { + [mainnet.id]: http(), + [sepolia.id]: http(), + }, +}) +``` + +Since the `Register` type is global, you only need to add it once in your project. Once set up, you will get strong type-safety across your entire project. For example, query composables will type `chainId` based on your `config`'s `chains`. + +```ts twoslash +// @errors: 2322 +import { type Config } from '@wagmi/vue' +import { mainnet, sepolia } from 'wagmi/chains' + +declare module '@wagmi/vue' { + interface Register { + config: Config + } +} +// ---cut--- +import { useBlockNumber } from '@wagmi/vue' + +useBlockNumber({ chainId: 123 }) +``` + +You just saved yourself a runtime error and you didn't even need to pass your `config`. šŸŽ‰ + +### Hook `config` Property + +For cases where you have more than one Wagmi `config` or don't want to use the declaration merging approach, you can pass a specific `config` directly to composables via the `config` property. + +```ts +import { createConfig, http } from '@wagmi/vue' +import { mainnet, optimism } from '@wagmi/vue/chains' + +export const configA = createConfig({ // [!code focus] + chains: [mainnet], // [!code focus] + transports: { // [!code focus] + [mainnet.id]: http(), // [!code focus] + }, // [!code focus] +}) // [!code focus] + +export const configB = createConfig({ // [!code focus] + chains: [optimism], // [!code focus] + transports: { // [!code focus] + [optimism.id]: http(), // [!code focus] + }, // [!code focus] +}) // [!code focus] +``` + +As you expect, `chainId` is inferred correctly for each `config`. + +```ts twoslash +// @errors: 2322 +import { type Config } from '@wagmi/vue' +import { mainnet, optimism } from '@wagmi/vue/chains' + +declare const configA: Config +declare const configB: Config +// ---cut--- +import { useBlockNumber } from '@wagmi/vue' + +useBlockNumber({ chainId: 123, config: configA }) +useBlockNumber({ chainId: 123, config: configB }) +``` + +This approach is more explicit, but works well for advanced use-cases, if you don't want to use a Vue Plugin or declaration merging, etc. + +## Const-Assert ABIs & Typed Data + +Wagmi can infer types based on [ABIs](https://docs.soliditylang.org/en/latest/abi-spec.html#json) and [EIP-712](https://eips.ethereum.org/EIPS/eip-712) Typed Data definitions, powered by [Viem](https://viem.sh) and [ABIType](https://github.com/wevm/abitype). This achieves full end-to-end type-safety from your contracts to your frontend and enlightened developer experience by autocompleting ABI item names, catching misspellings, inferring argument and return types (including overloads), and more. + +For this to work, you must either [const-assert](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions) ABIs and Typed Data (more info below) or define them inline. For example, `useReadContract`'s `abi` configuration parameter: + +```ts +const { data } = useReadContract({ + abi: […], // <--- defined inline // [!code focus] +}) +``` + +```ts +const abi = […] as const // <--- const assertion // [!code focus] +const { data } = useReadContract({ abi }) +``` + +If type inference isn't working, it's likely you forgot to add a `const` assertion or define the configuration parameter inline. Also, make sure your ABIs, Typed Data definitions, and [TypeScript configuration](#requirements) are valid and set up correctly. + +::: tip +Unfortunately [TypeScript doesn't support importing JSON `as const` yet](https://github.com/microsoft/TypeScript/issues/32063). Check out the [Wagmi CLI](/cli/getting-started) to help with this! It can automatically fetch ABIs from Etherscan and other block explorers, resolve ABIs from your Foundry/Hardhat projects, generate Vue Composables, and more. +::: + +Anywhere you see the `abi` or `types` configuration property, you can likely use const-asserted or inline ABIs and Typed Data to get type-safety and inference. These properties are also called out in the docs. + +Here's what [`useReadContract`](/vue/api/composables/useReadContract) looks like with and without a const-asserted `abi` property. + +::: code-group +```ts twoslash [Const-Asserted] +const erc721Abi = [ + { + name: 'balanceOf', + type: 'function', + stateMutability: 'view', + inputs: [{ type: 'address', name: 'owner' }], + outputs: [{ type: 'uint256' }], + }, + { + name: 'isApprovedForAll', + type: 'function', + stateMutability: 'view', + inputs: [ + { type: 'address', name: 'owner' }, + { type: 'address', name: 'operator' }, + ], + outputs: [{ type: 'bool' }], + }, + { + name: 'getApproved', + type: 'function', + stateMutability: 'view', + inputs: [{ type: 'uint256', name: 'tokenId' }], + outputs: [{ type: 'address' }], + }, + { + name: 'ownerOf', + type: 'function', + stateMutability: 'view', + inputs: [{ type: 'uint256', name: 'tokenId' }], + outputs: [{ type: 'address' }], + }, + { + name: 'tokenURI', + type: 'function', + stateMutability: 'pure', + inputs: [{ type: 'uint256', name: 'tokenId' }], + outputs: [{ type: 'string' }], + }, +] as const +// ---cut--- +import { useReadContract } from '@wagmi/vue' + +const { data } = useReadContract({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi: erc721Abi, + functionName: 'balanceOf', + // ^? + + + + args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e'], + // ^? +}) + +data +// ^? +``` +```ts twoslash [Not Const-Asserted] +declare const erc721Abi: { + name: string; + type: string; + stateMutability: string; + inputs: { + type: string; + name: string; + }[]; + outputs: { + type: string; + }[]; +}[] +// ---cut--- +import { useReadContract } from '@wagmi/vue' + +const { data } = useReadContract({ + address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', + abi: erc721Abi, + functionName: 'balanceOf', + // ^? + + + + args: ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e'], + // ^? +}) + +data +// ^? +``` +::: + +
+
+ +You can prevent runtime errors and be more productive by making sure your ABIs and Typed Data definitions are set up appropriately. šŸŽ‰ + +```ts twoslash +// @errors: 2820 +const erc721Abi = [ + { + name: 'balanceOf', + type: 'function', + stateMutability: 'view', + inputs: [{ type: 'address', name: 'owner' }], + outputs: [{ type: 'uint256' }], + }, + { + name: 'isApprovedForAll', + type: 'function', + stateMutability: 'view', + inputs: [ + { type: 'address', name: 'owner' }, + { type: 'address', name: 'operator' }, + ], + outputs: [{ type: 'bool' }], + }, + { + name: 'getApproved', + type: 'function', + stateMutability: 'view', + inputs: [{ type: 'uint256', name: 'tokenId' }], + outputs: [{ type: 'address' }], + }, + { + name: 'ownerOf', + type: 'function', + stateMutability: 'view', + inputs: [{ type: 'uint256', name: 'tokenId' }], + outputs: [{ type: 'address' }], + }, + { + name: 'tokenURI', + type: 'function', + stateMutability: 'pure', + inputs: [{ type: 'uint256', name: 'tokenId' }], + outputs: [{ type: 'string' }], + }, +] as const +// ---cut--- +import { useReadContract } from '@wagmi/vue' + +useReadContract({ + abi: erc721Abi, + functionName: 'balanecOf', +}) +``` + +## Configure Internal Types + +For advanced use-cases, you may want to configure Wagmi's internal types. Most of Wagmi's types relating to ABIs and EIP-712 Typed Data are powered by [ABIType](https://github.com/wevm/abitype). See the [ABIType docs](https://abitype.dev) for more info on how to configure types. diff --git a/wagmi-project/site/vue/why.md b/wagmi-project/site/vue/why.md new file mode 100644 index 0000000000..4a3560c13f --- /dev/null +++ b/wagmi-project/site/vue/why.md @@ -0,0 +1,46 @@ +# Why Wagmi + +## The Problems + +Building Ethereum applications is hard. Apps need to support connecting wallets, multiple chains, signing messages and data, sending transactions, listening for events and state changes, refreshing stale blockchain data, and much more. This is all on top of solving for app-specific use-cases and providing polished user experiences. + +The ecosystem is also continuously evolving, meaning you need to adapt to new improvements or get left behind. App developers should not need to worry about connecting tens of different wallets, the intricacies of multi-chain support, typos accidentally sending an order of magnitude more ETH or calling a misspelled contract function, or accidentally spamming their RPC provider, costing thousands in compute units. + +Wagmi solves all these problems and more — allowing app developers to focus on building high-quality and performant experiences for Ethereum — by focusing on **developer experience**, **performance**, **feature coverage**, and **stability.** + +## Developer Experience + +Wagmi delivers a great developer experience through modular and composable APIs, automatic type safety and inference, and comprehensive documentation. + +It provides developers with intuitive building blocks to build their Ethereum apps. While Wagmi's APIs might seem more verbose at first, it makes Wagmi's modular building blocks extremely flexible. Easy to move around, change, and remove. It also allows developers to better understand Ethereum concepts as well as understand _what_ and _why_ certain properties are being passed through. Learning how to use Wagmi is a great way to learn how to interact with Ethereum in general. + +Wagmi also provides [strongly typed APIs](/vue/typescript), allowing consumers to get the best possible experience through [autocomplete](https://twitter.com/awkweb/status/1555678944770367493), [type inference](https://twitter.com/jakemoxey/status/1570244174502588417?s=20), as well as static validation. You often just need to provide an ABI and Wagmi can help you autocomplete your way to success, identify type errors before your users do, drill into blockchain errors [at compile and runtimes](/vue/guides/error-handling) with surgical precision, and much more. + +The API documentation is comprehensive and contains usage info for _every_ module in Wagmi. The core team uses a [documentation](https://gist.github.com/zsup/9434452) and [test driven](https://en.wikipedia.org/wiki/Test-driven_development#:~:text=Test%2Ddriven%20development%20(TDD),software%20against%20all%20test%20cases.) development approach to building modules, which leads to predictable and stable APIs. + +## Performance + +Performance is critical for applications on all sizes. Slow page load and interactions can cause users to stop using applications. Wagmi uses and is built by the same team behind [Viem](https://viem.sh), the most performant production-ready Ethereum library. + +End users should not be required to download a module of over 100kB in order to interact with Ethereum. Wagmi is optimized for tree-shaking and dead-code elimination, allowing apps to minimize bundle size for fast page load times. + +Data layer performance is also critical. Slow, unnecessary, and manual data fetching can make apps unusable and cost thousands in RPC compute units. Wagmi supports caching, deduplication, persistence, and much more through [TanStack Query](/vue/guides/tanstack-query). + +## Feature Coverage + +Wagmi supports the most popular and commonly-used Ethereum features out of the box with 40+ Vue Composables for accounts, wallets, contracts, transactions, signing, ENS, and more. Wagmi also supports just about any wallet out there through it's official [connectors](/vue/api/connectors), [EIP-6963 support](/vue/api/createConfig#multiinjectedproviderdiscovery), and [extensible API](/dev/creating-connectors). + +If you need lower-level control, you can always drop down to [Wagmi Core](/core/getting-started) or [Viem](https://viem.sh), which Wagmi uses internally to perform blockchain operations. Wagmi also manages multi-chain support automatically so developers can focus on their applications instead of adding custom code. + +Finally, Wagmi has a [CLI](/cli/getting-started) to manage ABIs as well as a robust ecosystem of third-party libraries, like [ConnectKit](https://docs.family.co/connectkit), [RainbowKit](https://www.rainbowkit.com), [AppKit](https://walletconnect.com/appkit), [Dynamic](https://www.dynamic.xyz), [Privy](https://privy.io), and many more, so you can get started quickly without needing to build everything from scratch. + +## Stability + +Stability is a fundamental principle for Wagmi. Many organizations, large and small, rely heavily on Wagmi and expect it to be entirely stable for their users and applications. + +Wagmi's test suite runs against forked Ethereum nodes to make sure functions work across chains. The test suite also runs type tests against many different versions of peer dependencies, like TypeScript, to ensure compatibility with the latest releases of other popular software. + +Wagmi follows semver so developers can upgrade between versions with confidence. Starting with Wagmi v2, new functionality will be opt-in with old functionality being deprecated alongside the new features. This means upgrading to the latest major versions will not require immediate changes. + +Lastly, the core team works full-time on Wagmi and [related projects](https://github.com/wevm), and is constantly improving Wagmi and keeping it up-to-date with industry trends and changes. + diff --git a/wagmi-project/src/App.tsx b/wagmi-project/src/App.tsx new file mode 100644 index 0000000000..9f245fc45f --- /dev/null +++ b/wagmi-project/src/App.tsx @@ -0,0 +1,1362 @@ +import { AnimatePresence } from 'framer-motion' +import React, { useState, useEffect, useMemo, SetStateAction } from 'react' +import { ethers } from 'ethers' +import { sequence } from '0xsequence' +import { walletContracts } from '@0xsequence/abi' +import { + Box, + Image, + Text, + Button, + ExternalLinkIcon, + Divider, + Card, + TransactionIcon, + Select, + TokenImage, + TextInput, + Modal +} from '@0xsequence/design-system' +import { ETHAuth } from '@0xsequence/ethauth' +import { configureLogger } from '@0xsequence/utils' +import { ConnectOptions, OpenWalletIntent, Settings } from '@0xsequence/provider' +import { ChainId, NetworkType } from '@0xsequence/network' + +import { ERC_20_ABI } from './constants/abi' +import { Console } from './components/Console' +import { Group } from './components/Group' +import { getDefaultChainId, toHexString } from './helpers' +import logoUrl from './images/logo.svg' +import skyweaverBannerUrl from './images/skyweaver-banner.png' +import skyweaverBannerLargeUrl from './images/skyweaver-banner-large.png' + +configureLogger({ logLevel: 'DEBUG' }) + +interface Environment { + name: string + walletUrl: string + projectAccessKey: string +} + +const environments: Environment[] = [ + { + name: 'production', + walletUrl: 'https://sequence.app', + projectAccessKey: 'AQAAAAAAAAbvrgpWEC2Aefg5qYStQmwjBpA' + }, + { + name: 'development', + walletUrl: 'https://dev.sequence.app', + //projectAccessKey: 'AQAAAAAAAAVBNfoB30kz7Ph4I_Qs5mkYuDc', + projectAccessKey: 'AQAAAAAAAAVCXiQ9f_57R44MjorZ4SmGdhA' + }, + { + name: 'local', + walletUrl: 'http://localhost:3333', + projectAccessKey: 'AQAAAAAAAAVCXiQ9f_57R44MjorZ4SmGdhA' + }, + { + name: 'custom', + walletUrl: '', + projectAccessKey: '' + } +] + +const DEFAULT_API_URL = 'https://api.sequence.app' + +// Specify your desired default chain id. NOTE: you can communicate to multiple +// chains at the same time without even having to switch the network, but a default +// chain is required. +const defaultChainId = getDefaultChainId() || ChainId.MAINNET +// const defaultChainId = ChainId.POLYGON +// const defaultChainId = ChainId.GOERLI +// const defaultChainId = ChainId.ARBITRUM +// const defaultChainId = ChainId.AVALANCHE +// etc.. see the full list here: https://docs.sequence.xyz/multi-chain-support + +// For Sequence core dev team -- app developers can ignore +// a custom wallet app url can specified in the query string +const urlParams = new URLSearchParams(window.location.search) + +const env = urlParams.get('env') ?? 'production' +const envConfig = environments.find(x => x.name === env) ?? environments.find(x => x.name === 'production') +if (!envConfig) { + throw new Error('Invalid environment configuration.') +} +const walletAppURL = urlParams.get('walletAppURL') ?? envConfig.walletUrl +const projectAccessKey = urlParams.get('projectAccessKey') ?? envConfig.projectAccessKey +const showProhibitedActions = urlParams.has('showProhibitedActions') + +const isCustom = walletAppURL !== envConfig.walletUrl || projectAccessKey !== envConfig.projectAccessKey + +if (walletAppURL && walletAppURL.length > 0) { + // Wallet can point to a custom wallet app url + // NOTICE: this is not needed, unless testing an alpha version of the wallet + sequence.initWallet(projectAccessKey, { defaultNetwork: defaultChainId, transports: { walletAppURL } }) +} else { + // Init the sequence wallet library at the top-level of your project with + // your designed default chain id + sequence.initWallet(projectAccessKey, { defaultNetwork: defaultChainId, transports: { walletAppURL } }) +} + +// App component +const App = () => { + const [consoleMsg, setConsoleMsg] = useState(null) + const [email, setEmail] = useState(null) + const [consoleLoading, setConsoleLoading] = useState(false) + const [isWalletConnected, setIsWalletConnected] = useState(false) + + const wallet = sequence.getWallet().getProvider() + + const [showChainId, setShowChainId] = useState(wallet.getChainId()) + const [isOpen, toggleModal] = useState(false) + const [warning, setWarning] = useState(false) + + useEffect(() => { + const handleChainChanged = (chainId: string) => { + setShowChainId(Number(BigInt(chainId))) + } + wallet.on('chainChanged', handleChainChanged) + return () => { + wallet.off('chainChanged', handleChainChanged) + } + }, [wallet]) + + useEffect(() => { + setIsWalletConnected(wallet.isConnected()) + }, [wallet]) + + useEffect(() => { + consoleWelcomeMessage() + // eslint-disable-next-line + }, [isWalletConnected]) + + useEffect(() => { + // Wallet events + const onOpen = () => { + console.log('wallet window opened') + } + wallet.client.on('open', onOpen) + + const onClose = () => { + console.log('wallet window closed') + } + wallet.client.on('close', onClose) + + return () => { + wallet.client.off('open', onOpen) + wallet.client.off('close', onClose) + } + }, [wallet]) + + const defaultConnectOptions: ConnectOptions = { + app: 'Demo Dapp', + askForEmail: true + // keepWalletOpened: true, + } + + // Methods + const connect = async (connectOptions: ConnectOptions = { app: 'Demo dapp' }) => { + if (isWalletConnected) { + resetConsole() + appendConsoleLine('Wallet already connected!') + setConsoleLoading(false) + return + } + + connectOptions = { + ...defaultConnectOptions, + ...connectOptions, + settings: { + ...defaultConnectOptions.settings, + ...connectOptions.settings + } + } + + try { + resetConsole() + appendConsoleLine('Connecting') + const wallet = sequence.getWallet() + + const connectDetails = await wallet.connect(connectOptions) + + // Example of how to verify using ETHAuth via Sequence API + if (connectOptions.authorize && connectDetails.connected && connectDetails.proof) { + let apiUrl = urlParams.get('apiUrl') + + if (!apiUrl || apiUrl.length === 0) { + apiUrl = DEFAULT_API_URL + } + + const api = new sequence.api.SequenceAPIClient(apiUrl) + // or just + // const api = new sequence.api.SequenceAPIClient('https://api.sequence.app') + + const { isValid } = await api.isValidETHAuthProof({ + chainId: connectDetails.chainId, + walletAddress: connectDetails.session.accountAddress, + ethAuthProofString: connectDetails.proof.proofString + }) + + appendConsoleLine(`isValid (API)?: ${isValid}`) + } + + // Example of how to verify using ETHAuth directl on the client + if (connectOptions.authorize) { + const ethAuth = new ETHAuth() + + if (connectDetails.proof) { + const decodedProof = await ethAuth.decodeProof(connectDetails.proof.proofString, true) + + const isValid = await wallet.utils.isValidTypedDataSignature( + wallet.getAddress(), + connectDetails.proof.typedData, + decodedProof.signature, + Number(BigInt(connectDetails.chainId)) + ) + + appendConsoleLine(`connected using chainId: ${BigInt(connectDetails.chainId).toString()}`) + appendConsoleLine(`isValid (client)?: ${isValid}`) + } + } + + setConsoleLoading(false) + if (connectDetails.connected) { + appendConsoleLine('Wallet connected!') + appendConsoleLine(`shared email: ${connectDetails.email}`) + setIsWalletConnected(true) + } else { + appendConsoleLine('Failed to connect wallet - ' + connectDetails.error) + } + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const disconnect = () => { + const wallet = sequence.getWallet() + wallet.disconnect() + consoleWelcomeMessage() + setIsWalletConnected(false) + } + + const openWallet = () => { + const wallet = sequence.getWallet() + wallet.openWallet() + } + + const openWalletWithSettings = () => { + const wallet = sequence.getWallet() + + const settings: Settings = { + theme: 'light', + includedPaymentProviders: ['moonpay', 'ramp'], + defaultFundingCurrency: 'eth', + defaultPurchaseAmount: 400, + lockFundingCurrencyToDefault: false + } + + const intent: OpenWalletIntent = { + type: 'openWithOptions', + options: { + app: 'Demo Dapp', + settings + } + } + + const path = 'wallet/add-funds' + wallet.openWallet(path, intent) + } + + const closeWallet = () => { + const wallet = sequence.getWallet() + wallet.closeWallet() + } + + const isConnected = async () => { + resetConsole() + const wallet = sequence.getWallet() + appendConsoleLine(`isConnected?: ${wallet.isConnected()}`) + setConsoleLoading(false) + } + + const isOpened = async () => { + resetConsole() + const wallet = sequence.getWallet() + appendConsoleLine(`isOpened?: ${wallet.isOpened()}`) + setConsoleLoading(false) + } + + const getChainID = async () => { + try { + resetConsole() + + const topChainId = wallet.getChainId() + appendConsoleLine(`top chainId: ${topChainId}`) + + const provider = wallet.getProvider() + const providerChainId = provider!.getChainId() + appendConsoleLine(`provider.getChainId(): ${providerChainId}`) + + const signer = wallet.getSigner() + const signerChainId = await signer.getChainId() + appendConsoleLine(`signer.getChainId(): ${signerChainId}`) + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const getAccounts = async () => { + try { + resetConsole() + + const wallet = sequence.getWallet() + const address = wallet.getAddress() + appendConsoleLine(`getAddress(): ${address}`) + + const provider = wallet.getProvider() + const accountList = provider.listAccounts() + appendConsoleLine(`accounts: ${JSON.stringify(accountList)}`) + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const getBalance = async () => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + const provider = wallet.getProvider() + const account = wallet.getAddress() + const balanceChk1 = await provider!.getBalance(account) + appendConsoleLine(`balance check 1: ${balanceChk1.toString()}`) + + const signer = wallet.getSigner() + const balanceChk2 = await signer.getBalance() + appendConsoleLine(`balance check 2: ${balanceChk2.toString()}`) + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const getNetworks = async () => { + try { + resetConsole() + + const wallet = sequence.getWallet() + const networks = await wallet.getNetworks() + + appendConsoleLine(`networks: ${JSON.stringify(networks, null, 2)}`) + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const signMessageString = async () => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + appendConsoleLine('signing message...') + const signer = wallet.getSigner() + + const message = `1915 Robert Frost +The Road Not Taken + +Two roads diverged in a yellow wood, +And sorry I could not travel both +And be one traveler, long I stood +And looked down one as far as I could +To where it bent in the undergrowth + +Then took the other, as just as fair, +And having perhaps the better claim, +Because it was grassy and wanted wear +Though as for that the passing there +Had worn them really about the same, + +And both that morning equally lay +In leaves no step had trodden black. +Oh, I kept the first for another day! +Yet knowing how way leads on to way, +I doubted if I should ever come back. + +I shall be telling this with a sigh +Somewhere ages and ages hence: +Two roads diverged in a wood, and I— +I took the one less traveled by, +And that has made all the difference. + +\u2601 \u2600 \u2602` + + // sign + const sig = await signer.signMessage(message) + appendConsoleLine(`signature: ${sig}`) + + const isValid = await wallet.utils.isValidMessageSignature(wallet.getAddress(), message, sig, await signer.getChainId()) + appendConsoleLine(`isValid?: ${isValid}`) + if (!isValid) throw new Error('sig invalid') + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const signMessageHex = async () => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + appendConsoleLine('signing message...') + const signer = wallet.getSigner() + + // Message in hex + const message = ethers.hexlify(ethers.toUtf8Bytes('Hello, world!')) + + // sign + const sig = await signer.signMessage(message) + appendConsoleLine(`signature: ${sig}`) + + const isValid = await wallet.utils.isValidMessageSignature(wallet.getAddress(), message, sig, await signer.getChainId()) + appendConsoleLine(`isValid?: ${isValid}`) + if (!isValid) throw new Error('sig invalid') + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const signMessageBytes = async () => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + appendConsoleLine('signing message...') + const signer = wallet.getSigner() + + // Message in hex + const message = ethers.toUtf8Bytes('Hello, world!') + + // sign + const sig = await signer.signMessage(message) + appendConsoleLine(`signature: ${sig}`) + + const isValid = await wallet.utils.isValidMessageSignature(wallet.getAddress(), message, sig, await signer.getChainId()) + appendConsoleLine(`isValid?: ${isValid}`) + if (!isValid) throw new Error('sig invalid') + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const signTypedData = async () => { + try { + resetConsole() + const wallet = sequence.getWallet() + + appendConsoleLine('signing typedData...') + + const typedData: sequence.utils.TypedData = { + types: { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' } + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'cc', type: 'Person[]' }, + { name: 'contents', type: 'string' }, + { name: 'attachements', type: 'string[]' } + ] + }, + primaryType: 'Mail', + domain: { + name: 'Ether Mail', + version: '1', + chainId: 1, + verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC' + }, + message: { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826' + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB' + }, + cc: [ + { name: 'Dev Team', wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB' }, + { name: 'Accounting', wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB' } + ], + contents: 'Hello, Bob!', + attachements: ['cat.png', 'dog.png'] + } + } + + const signer = wallet.getSigner() + + const sig = await signer.signTypedData(typedData.domain, typedData.types, typedData.message) + appendConsoleLine(`signature: ${sig}`) + + // validate + const isValid = await wallet.utils.isValidTypedDataSignature(wallet.getAddress(), typedData, sig, await signer.getChainId()) + appendConsoleLine(`isValid?: ${isValid}`) + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const estimateUnwrapGas = async () => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + const wmaticContractAddress = '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270' + const wmaticInterface = new ethers.Interface(['function withdraw(uint256 amount)']) + + const tx: sequence.transactions.Transaction = { + to: wmaticContractAddress, + data: wmaticInterface.encodeFunctionData('withdraw', ['1000000000000000000']) + } + + const provider = wallet.getProvider() + const estimate = await provider.estimateGas(tx) + + appendConsoleLine(`estimated gas needed for wmatic withdrawal : ${estimate.toString()}`) + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const sendETH = async (signer?: sequence.provider.SequenceSigner) => { + try { + resetConsole() + const wallet = sequence.getWallet() + + signer = signer || wallet.getSigner() + + appendConsoleLine(`Transfer txn on ${signer.getChainId()} chainId`) + + // NOTE: on mainnet, the balance will be of ETH value + // and on matic, the balance will be of MATIC value + + // Sending the funds to the wallet itself + // so we don't lose any funds ;-) + // (of course, you can send anywhere) + const toAddress = await signer.getAddress() + + const tx1: sequence.transactions.Transaction = { + delegateCall: false, + revertOnError: false, + gasLimit: '0x55555', + to: toAddress, + value: ethers.parseEther('1.234'), + data: '0x' + } + + const tx2: sequence.transactions.Transaction = { + delegateCall: false, + revertOnError: false, + gasLimit: '0x55555', + to: toAddress, + value: ethers.parseEther('0.4242'), + data: '0x' + } + + const provider = signer.provider + + const balance1 = await provider.getBalance(toAddress) + appendConsoleLine(`balance of ${toAddress}, before: ${balance1}`) + + const txnResp = await signer.sendTransaction([tx1, tx2]) + appendConsoleLine(`txnResponse: ${JSON.stringify(txnResp)}`) + + const balance2 = await provider.getBalance(toAddress) + appendConsoleLine(`balance of ${toAddress}, after: ${balance2}`) + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const sendSepoliaUSDC = async (signer?: sequence.provider.SequenceSigner) => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + signer = signer || wallet.getSigner() // select DefaultChain signer by default + + // Sending the funds to the wallet itself + // so we don't lose any funds ;-) + // (of course, you can send anywhere) + const toAddress = await signer.getAddress() + + const amount = ethers.parseUnits('1', 1) + + // (USDC address on Sepolia) + const usdcAddress = '0x07865c6e87b9f70255377e024ace6630c1eaa37f' + + const tx: sequence.transactions.Transaction = { + delegateCall: false, + revertOnError: false, + gasLimit: '0x55555', + to: usdcAddress, + value: 0, + data: new ethers.Interface(ERC_20_ABI).encodeFunctionData('transfer', [toAddress, toHexString(amount)]) + } + + const txnResp = await signer.sendTransaction([tx], { chainId: ChainId.SEPOLIA }) + appendConsoleLine(`txnResponse: ${JSON.stringify(txnResp)}`) + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const sendDAI = async (signer?: sequence.provider.SequenceSigner) => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + signer = signer || wallet.getSigner() // select DefaultChain signer by default + + // Sending the funds to the wallet itself + // so we don't lose any funds ;-) + // (of course, you can send anywhere) + const toAddress = await signer.getAddress() + + const amount = ethers.parseUnits('0.05', 18) + const daiContractAddress = '0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063' // (DAI address on Polygon) + + const tx: sequence.transactions.Transaction = { + delegateCall: false, + revertOnError: false, + gasLimit: '0x55555', + to: daiContractAddress, + value: 0, + data: new ethers.Interface(ERC_20_ABI).encodeFunctionData('transfer', [toAddress, toHexString(amount)]) + } + + const txnResp = await signer.sendTransaction([tx]) + appendConsoleLine(`txnResponse: ${JSON.stringify(txnResp)}`) + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const sendETHSidechain = async () => { + try { + const wallet = sequence.getWallet() + + // Send either to Arbitrum or Optimism + // just pick one that is not the current chainId + const pick = wallet.getChainId() === ChainId.ARBITRUM ? ChainId.OPTIMISM : ChainId.ARBITRUM + sendETH(wallet.getSigner(pick)) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const send1155Tokens = async () => { + try { + resetConsole() + appendConsoleLine('TODO') + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const contractExample = async (signer?: sequence.provider.SequenceSigner) => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + signer = signer || wallet.getSigner() + + const abi = [ + 'function balanceOf(address owner) view returns (uint256)', + 'function decimals() view returns (uint8)', + 'function symbol() view returns (string)', + 'function transfer(address to, uint amount) returns (bool)', + 'event Transfer(address indexed from, address indexed to, uint amount)' + ] + + // USD Coin (PoS) on Polygon + const address = '0x2791bca1f2de4661ed88a30c99a7a9449aa84174' + + const usdc = new ethers.Contract(address, abi) + + const usdSymbol = await usdc.symbol() + appendConsoleLine(`Token symbol: ${usdSymbol}`) + + const balance = await usdc.balanceOf(await signer.getAddress()) + appendConsoleLine(`Token Balance: ${balance.toString()}`) + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const fetchTokenBalances = async () => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + const signer = wallet.getSigner() + const accountAddress = await signer.getAddress() + const networks = await wallet.getNetworks() + const network = networks.find(network => network.chainId === ChainId.POLYGON) + + if (!network) { + throw new Error(`Could not find Polygon network in networks list`) + } + + const indexer = new sequence.indexer.SequenceIndexer(network.indexerUrl) + + const tokenBalances = await indexer.getTokenBalances({ + accountAddress: accountAddress, + includeMetadata: true + }) + + appendConsoleLine(`tokens in your account: ${JSON.stringify(tokenBalances)}`) + + // NOTE: you can put any NFT/collectible address in the `contractAddress` field and it will return all of the balances + metadata. + // We use the Skyweaver production contract address here for demo purposes, but try another one :) + const skyweaverCollectibles = await indexer.getTokenBalances({ + accountAddress: accountAddress, + includeMetadata: true, + contractAddress: '0x631998e91476DA5B870D741192fc5Cbc55F5a52E' + }) + appendConsoleLine(`skyweaver collectibles in your account: ${JSON.stringify(skyweaverCollectibles)}`) + + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const updateImplementation = async (signer?: sequence.provider.SequenceSigner) => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + signer = signer || wallet.getSigner() // select DefaultChain signer by default + + const transaction: sequence.transactions.Transaction = { + to: wallet.getAddress(), + data: new ethers.Interface(walletContracts.mainModule.abi).encodeFunctionData('updateImplementation', [ + ethers.ZeroAddress + ]) + } + + const response = await signer.sendTransaction(transaction) + appendConsoleLine(`response: ${JSON.stringify(response)}`) + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const updateImageHash = async (signer?: sequence.provider.SequenceSigner) => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + signer = signer || wallet.getSigner() // select DefaultChain signer by default + + const transaction: sequence.transactions.Transaction = { + to: wallet.getAddress(), + data: new ethers.Interface(walletContracts.mainModuleUpgradable.abi).encodeFunctionData('updateImageHash', [ + ethers.ZeroHash + ]) + } + + const response = await signer.sendTransaction(transaction) + appendConsoleLine(`response: ${JSON.stringify(response)}`) + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const delegateCall = async (signer?: sequence.provider.SequenceSigner) => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + signer = signer || wallet.getSigner() // select DefaultChain signer by default + + const transaction: sequence.transactions.Transaction = { + to: wallet.getAddress(), + delegateCall: true + } + + const response = await signer.sendTransaction(transaction) + appendConsoleLine(`response: ${JSON.stringify(response)}`) + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const addHook = async (signer?: sequence.provider.SequenceSigner) => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + signer = signer || wallet.getSigner() // select DefaultChain signer by default + + const transaction: sequence.transactions.Transaction = { + to: wallet.getAddress(), + data: new ethers.Interface(['function addHook(bytes4 _signature, address _implementation)']).encodeFunctionData( + 'addHook', + ['0x01234567', ethers.ZeroAddress] + ) + } + + const response = await signer.sendTransaction(transaction) + appendConsoleLine(`response: ${JSON.stringify(response)}`) + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const setExtraImageHash = async (signer?: sequence.provider.SequenceSigner) => { + try { + resetConsole() + + const wallet = sequence.getWallet() + + signer = signer || wallet.getSigner() // select DefaultChain signer by default + + const transaction: sequence.transactions.Transaction = { + to: wallet.getAddress(), + data: new ethers.Interface(['function setExtraImageHash(bytes32 _imageHash, uint256 _expiration)']).encodeFunctionData( + 'setExtraImageHash', + [ethers.ZeroHash, ethers.MaxUint256] + ) + } + + const response = await signer.sendTransaction(transaction) + appendConsoleLine(`response: ${JSON.stringify(response)}`) + setConsoleLoading(false) + } catch (e) { + console.error(e) + consoleErrorMessage() + } + } + + const appendConsoleLine = (message: string, clear = false) => { + console.log(message) + + if (clear) { + return setConsoleMsg(message) + } + + return setConsoleMsg(prevState => { + return `${prevState}\n\n${message}` + }) + } + + const resetConsole = () => { + setConsoleLoading(true) + } + + const consoleWelcomeMessage = () => { + setConsoleLoading(false) + + if (isWalletConnected) { + setConsoleMsg('Status: Wallet is connected :)') + } else { + setConsoleMsg('Status: Wallet not connected. Please connect wallet first.') + } + } + + const consoleErrorMessage = () => { + setConsoleLoading(false) + setConsoleMsg('An error occurred') + } + + // networks list, filtered and sorted + const omitNetworks = [ + ChainId.RINKEBY, + ChainId.HARDHAT, + ChainId.HARDHAT_2, + ChainId.KOVAN, + ChainId.ROPSTEN, + ChainId.HOMEVERSE_TESTNET, + ChainId.BASE_GOERLI + ] + + const mainnets = Object.values(sequence.network.networks) + .filter(network => network.type === NetworkType.MAINNET) + .sort((a, b) => a.chainId - b.chainId) + const testnets = Object.values(sequence.network.networks) + .filter(network => network.type === NetworkType.TESTNET) + .sort((a, b) => a.chainId - b.chainId) + const networks = [...mainnets, ...testnets].filter(network => !network.deprecated && !omitNetworks.includes(network.chainId)) + + useEffect(() => { + if (email && !isOpen) { + console.log(email) + connect({ + app: 'Demo Dapp', + authorize: true, + settings: { + // Specify signInWithEmail with an email address to allow user automatically sign in with the email option. + signInWithEmail: email, + theme: 'dark', + bannerUrl: `${window.location.origin}${skyweaverBannerUrl}` + } + }) + setEmail(null) + } + }, [email, isOpen]) + + const sanitizeEmail = (email: string) => { + // Trim unnecessary spaces + email = email.trim() + + // Check if the email matches the pattern of a typical email + const emailRegex = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/ + if (emailRegex.test(email)) { + return true + } + + return false + } + + return ( + + + + logo + + + + + + Demo Dapp + + + + + + A dapp example on how to use the Sequence Wallet. This covers how to connect, sign messages and send transctions. + + + + + + + Please open your browser dev inspector to view output of functions below. + + + + + + {!isCustom && ( + + wallet.setDefaultChainId(Number(value))} + value={String(showChainId)} + options={[ + ...Object.values(networks).map(network => ({ + label: ( + + + {network.title!} + + ), + value: String(network.chainId) + })) + ]} + /> + + + +